summaryrefslogtreecommitdiff
path: root/win32/rm.bat
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2022-02-08 08:51:55 -0800
committerJeremy Evans <code@jeremyevans.net>2022-03-29 18:14:33 -0700
commitd8dfabbfe6522c495d280e6a12201c3fa88988b5 (patch)
treed473fa4c9eaa403544618d06c3eee2f665c66c63 /win32/rm.bat
parent750e18594b138465506aba9a1225b9897026a06a (diff)
Fix spec description
Co-authored-by: Benoit Daloze <eregontp@gmail.com>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5359
Diffstat (limited to 'win32/rm.bat')
0 files changed, 0 insertions, 0 deletions
setup/directories/action.yml137
-rw-r--r--.github/actions/setup/macos/action.yml24
-rw-r--r--.github/actions/setup/ubuntu/action.yml53
-rw-r--r--.github/actions/slack/action.yml39
-rw-r--r--.github/auto_request_review.yml13
-rw-r--r--.github/codeql/codeql-config.yml3
-rw-r--r--.github/dependabot.yml4
-rw-r--r--.github/workflows/annocheck.yml127
-rw-r--r--.github/workflows/auto_request_review.yml19
-rw-r--r--.github/workflows/baseruby.yml60
-rw-r--r--.github/workflows/bundled_gems.yml137
-rw-r--r--.github/workflows/check_dependencies.yml60
-rw-r--r--.github/workflows/check_misc.yml117
-rw-r--r--.github/workflows/codeql-analysis.yml136
-rw-r--r--.github/workflows/compilers.yml128
-rw-r--r--.github/workflows/dependabot_automerge.yml30
-rw-r--r--.github/workflows/macos.yml116
-rw-r--r--.github/workflows/mingw.yml135
-rw-r--r--.github/workflows/mjit-bindgen.yml104
-rw-r--r--.github/workflows/mjit.yml113
-rw-r--r--.github/workflows/publish.yml18
-rw-r--r--.github/workflows/rjit-bindgen.yml91
-rw-r--r--.github/workflows/rjit.yml120
-rw-r--r--.github/workflows/scorecards.yml28
-rw-r--r--.github/workflows/spec_guards.yml29
-rw-r--r--.github/workflows/ubuntu.yml144
-rw-r--r--.github/workflows/wasm.yml106
-rw-r--r--.github/workflows/windows.yml152
-rw-r--r--.github/workflows/yjit-macos.yml151
-rw-r--r--.github/workflows/yjit-ubuntu.yml190
-rw-r--r--.gitignore45
-rw-r--r--.travis.yml152
-rw-r--r--LEGAL28
-rw-r--r--NEWS.md1171
-rw-r--r--README.ja.md28
-rw-r--r--README.md19
-rw-r--r--addr2line.c817
-rw-r--r--addr2line.h4
-rw-r--r--array.c764
-rw-r--r--array.rb88
-rw-r--r--ast.c284
-rw-r--r--ast.rb20
-rw-r--r--benchmark/enum_sort_by.yml53
-rw-r--r--benchmark/lib/benchmark_driver/runner/mjit.rb34
-rw-r--r--benchmark/loop_generator.rb2
-rw-r--r--benchmark/mjit_exivar.yml18
-rw-r--r--benchmark/mjit_integer.yml32
-rw-r--r--benchmark/mjit_kernel.yml20
-rw-r--r--benchmark/mjit_leave.yml8
-rw-r--r--benchmark/mjit_opt_cc_insns.yml27
-rw-r--r--benchmark/mjit_struct_aref.yml10
-rw-r--r--benchmark/range_bsearch_bignum.yml10
-rw-r--r--benchmark/range_bsearch_endpointless.yml21
-rw-r--r--benchmark/range_bsearch_fixnum.yml10
-rw-r--r--benchmark/range_count.yml11
-rw-r--r--benchmark/range_overlap.yml19
-rw-r--r--benchmark/range_reverse_each.yml16
-rw-r--r--benchmark/regexp_dup.yml6
-rw-r--r--benchmark/regexp_new.yml7
-rw-r--r--benchmark/so_count_words.yml33
-rw-r--r--benchmark/so_meteor_contest.rb2
-rw-r--r--benchmark/string_concat.yml6
-rw-r--r--benchmark/string_dup.yml7
-rw-r--r--benchmark/string_rpartition.yml18
-rw-r--r--benchmark/struct_accessor.yml25
-rw-r--r--benchmark/vm_call_bmethod.yml37
-rw-r--r--benchmark/vm_call_method_missing.yml62
-rw-r--r--benchmark/vm_call_send_iseq.yml77
-rw-r--r--benchmark/vm_call_symproc.yml83
-rw-r--r--benchmark/vm_ivar_ic_miss.yml20
-rw-r--r--benchmark/vm_ivar_memoize.yml85
-rw-r--r--benchmark/vm_method_splat_calls.yml13
-rw-r--r--benchmark/vm_send_cfunc.yml15
-rw-r--r--bignum.c21
-rwxr-xr-xbin/gem2
-rwxr-xr-xbootstraptest/runner.rb18
-rw-r--r--bootstraptest/test_eval.rb10
-rw-r--r--bootstraptest/test_gc.rb2
-rw-r--r--bootstraptest/test_insns.rb14
-rw-r--r--bootstraptest/test_load.rb2
-rw-r--r--bootstraptest/test_method.rb9
-rw-r--r--bootstraptest/test_ractor.rb197
-rw-r--r--bootstraptest/test_rjit.rb58
-rw-r--r--bootstraptest/test_syntax.rb4
-rw-r--r--bootstraptest/test_thread.rb18
-rw-r--r--bootstraptest/test_yjit.rb1002
-rw-r--r--builtin.c15
-rw-r--r--builtin.h6
-rw-r--r--ccan/list/list.h6
-rw-r--r--class.c127
-rw-r--r--common.mk4182
-rw-r--r--compar.c27
-rw-r--r--compile.c2263
-rw-r--r--complex.c836
-rw-r--r--configure.ac350
-rw-r--r--constant.h2
-rw-r--r--cont.c251
-rw-r--r--coroutine/amd64/Context.S42
-rw-r--r--coroutine/arm64/Context.S67
-rw-r--r--coroutine/arm64/Context.h24
-rw-r--r--coroutine/asyncify/Context.h8
-rw-r--r--coroutine/loongarch64/Context.S73
-rw-r--r--coroutine/loongarch64/Context.h46
-rw-r--r--coroutine/ppc/Context.S2
-rw-r--r--coroutine/ppc/Context.h2
-rw-r--r--coroutine/ppc64/Context.h2
-rw-r--r--cygwin/GNUmakefile.in17
-rw-r--r--darray.h183
-rw-r--r--debug.c140
-rw-r--r--debug_counter.c2
-rw-r--r--debug_counter.h59
-rw-r--r--defs/gmake.mk177
-rw-r--r--defs/id.def2
-rw-r--r--defs/tags.mk18
-rw-r--r--defs/universal.mk5
-rw-r--r--dir.c853
-rw-r--r--dir.rb377
-rw-r--r--dln.c80
-rw-r--r--dln.h1
-rw-r--r--dln_find.c2
-rw-r--r--dmydln.c9
-rw-r--r--doc/.document4
-rw-r--r--doc/ChangeLog-0.06_to_0.52 (renamed from doc/ChangeLog/ChangeLog-0.06_to_0.52)0
-rw-r--r--doc/ChangeLog-0.50_to_0.60 (renamed from doc/ChangeLog/ChangeLog-0.50_to_0.60)0
-rw-r--r--doc/ChangeLog-0.60_to_1.1 (renamed from doc/ChangeLog/ChangeLog-0.60_to_1.1)0
-rw-r--r--doc/ChangeLog-1.8.0 (renamed from doc/ChangeLog/ChangeLog-1.8.0)0
-rw-r--r--doc/ChangeLog-1.9.3 (renamed from doc/ChangeLog/ChangeLog-1.9.3)0
-rw-r--r--doc/ChangeLog-2.0.0 (renamed from doc/ChangeLog/ChangeLog-2.0.0)0
-rw-r--r--doc/ChangeLog-2.1.0 (renamed from doc/ChangeLog/ChangeLog-2.1.0)0
-rw-r--r--doc/ChangeLog-2.2.0 (renamed from doc/ChangeLog/ChangeLog-2.2.0)0
-rw-r--r--doc/ChangeLog-2.3.0 (renamed from doc/ChangeLog/ChangeLog-2.3.0)0
-rw-r--r--doc/ChangeLog-2.4.0 (renamed from doc/ChangeLog/ChangeLog-2.4.0)0
-rw-r--r--doc/ChangeLog-YARV (renamed from doc/ChangeLog/ChangeLog-YARV)0
-rw-r--r--doc/NEWS/NEWS-3.2.0.md820
-rw-r--r--doc/_regexp.rdoc1276
-rw-r--r--doc/_timezones.rdoc156
-rw-r--r--doc/bsearch.rdoc2
-rw-r--r--doc/case_mapping.rdoc6
-rw-r--r--doc/character_selectors.rdoc6
-rw-r--r--doc/command_injection.rdoc4
-rw-r--r--doc/contributing/building_ruby.md122
-rw-r--r--doc/contributing/documentation_guide.md144
-rw-r--r--doc/contributing/glossary.md41
-rw-r--r--doc/contributing/making_changes_to_stdlibs.md2
-rw-r--r--doc/contributing/testing_ruby.md36
-rw-r--r--doc/csv/options/common/col_sep.rdoc6
-rw-r--r--doc/csv/options/common/row_sep.rdoc9
-rw-r--r--doc/csv/options/generating/write_converters.rdoc8
-rw-r--r--doc/csv/options/generating/write_headers.rdoc2
-rw-r--r--doc/csv/options/parsing/liberal_parsing.rdoc23
-rw-r--r--doc/csv/recipes/filtering.rdoc2
-rw-r--r--doc/csv/recipes/generating.rdoc4
-rw-r--r--doc/csv/recipes/parsing.rdoc4
-rw-r--r--doc/csv/recipes/recipes.rdoc2
-rw-r--r--doc/distribution.md47
-rw-r--r--doc/encodings.rdoc48
-rw-r--r--doc/extension.ja.rdoc10
-rw-r--r--doc/extension.rdoc163
-rw-r--r--doc/format_specifications.rdoc58
-rw-r--r--doc/globals.rdoc491
-rw-r--r--doc/implicit_conversion.rdoc10
-rw-r--r--doc/irb/indexes.md189
-rw-r--r--doc/irb/irb.rd.ja4
-rw-r--r--doc/keywords.rdoc2
-rw-r--r--doc/maintainers.md520
-rw-r--r--doc/maintainers.rdoc424
-rw-r--r--doc/mjit/mjit.md39
-rw-r--r--doc/optparse/argument_converters.rdoc70
-rw-r--r--doc/optparse/option_params.rdoc4
-rw-r--r--doc/optparse/tutorial.rdoc70
-rw-r--r--doc/packed_data.rdoc87
-rw-r--r--doc/ractor.md8
-rw-r--r--doc/rdoc/markup_reference.rb47
-rw-r--r--doc/regexp.rdoc801
-rw-r--r--doc/regexp/methods.rdoc41
-rw-r--r--doc/regexp/unicode_properties.rdoc678
-rw-r--r--doc/reline/face.md111
-rw-r--r--doc/rjit/rjit.md45
-rw-r--r--doc/standard_library.rdoc18
-rw-r--r--doc/strftime_formatting.rdoc48
-rw-r--r--doc/string/encode.rdoc47
-rw-r--r--doc/string/length.rdoc1
-rw-r--r--doc/syntax.rdoc3
-rw-r--r--doc/syntax/assignment.rdoc6
-rw-r--r--doc/syntax/calling_methods.rdoc12
-rw-r--r--doc/syntax/comments.rdoc2
-rw-r--r--doc/syntax/control_expressions.rdoc68
-rw-r--r--doc/syntax/literals.rdoc12
-rw-r--r--doc/syntax/modules_and_classes.rdoc28
-rw-r--r--doc/syntax/operators.rdoc75
-rw-r--r--doc/syntax/pattern_matching.rdoc28
-rw-r--r--doc/syntax/refinements.rdoc2
-rw-r--r--doc/timezones.rdoc108
-rw-r--r--doc/transcode.rdoc52
-rw-r--r--doc/windows.md233
-rw-r--r--doc/yjit/yjit.md170
-rw-r--r--enc/depend207
-rw-r--r--enc/trans/big5-uao-tbl.rb2
-rw-r--r--enc/trans/cp850-tbl.rb2
-rw-r--r--enc/trans/cp852-tbl.rb2
-rw-r--r--enc/trans/cp855-tbl.rb2
-rw-r--r--enc/trans/gbk-tbl.rb2
-rw-r--r--enc/trans/ibm437-tbl.rb2
-rw-r--r--enc/trans/ibm775-tbl.rb2
-rw-r--r--enc/trans/ibm852-tbl.rb2
-rw-r--r--enc/trans/ibm855-tbl.rb2
-rw-r--r--enc/trans/ibm857-tbl.rb2
-rw-r--r--enc/trans/ibm860-tbl.rb2
-rw-r--r--enc/trans/ibm861-tbl.rb2
-rw-r--r--enc/trans/ibm862-tbl.rb2
-rw-r--r--enc/trans/ibm863-tbl.rb2
-rw-r--r--enc/trans/ibm865-tbl.rb2
-rw-r--r--enc/trans/ibm866-tbl.rb2
-rw-r--r--enc/trans/ibm869-tbl.rb2
-rw-r--r--enc/trans/koi8-r-tbl.rb2
-rw-r--r--enc/trans/koi8-u-tbl.rb2
-rw-r--r--enc/trans/maccroatian-tbl.rb2
-rw-r--r--enc/trans/maccyrillic-tbl.rb2
-rw-r--r--enc/trans/macgreek-tbl.rb2
-rw-r--r--enc/trans/maciceland-tbl.rb2
-rw-r--r--enc/trans/macroman-tbl.rb2
-rw-r--r--enc/trans/macromania-tbl.rb2
-rw-r--r--enc/trans/macturkish-tbl.rb2
-rw-r--r--enc/trans/macukraine-tbl.rb2
-rw-r--r--enc/trans/windows-1250-tbl.rb2
-rw-r--r--enc/trans/windows-1251-tbl.rb2
-rw-r--r--enc/trans/windows-1252-tbl.rb2
-rw-r--r--enc/trans/windows-1253-tbl.rb2
-rw-r--r--enc/trans/windows-1254-tbl.rb2
-rw-r--r--enc/trans/windows-1256-tbl.rb2
-rw-r--r--enc/trans/windows-1257-tbl.rb2
-rw-r--r--enc/trans/windows-874-tbl.rb2
-rw-r--r--enc/unicode/15.0.0/name2ctype.h2
-rw-r--r--encoding.c52
-rw-r--r--enum.c265
-rw-r--r--enumerator.c220
-rw-r--r--error.c521
-rw-r--r--eval.c57
-rw-r--r--eval_error.c26
-rw-r--r--eval_intern.h8
-rw-r--r--ext/-test-/RUBY_ALIGNOF/depend3
-rw-r--r--ext/-test-/arith_seq/beg_len_step/depend3
-rw-r--r--ext/-test-/arith_seq/extract/depend3
-rw-r--r--ext/-test-/array/concat/depend3
-rw-r--r--ext/-test-/array/resize/depend3
-rw-r--r--ext/-test-/bignum/depend21
-rw-r--r--ext/-test-/bug-14834/depend3
-rw-r--r--ext/-test-/bug-3571/depend3
-rw-r--r--ext/-test-/bug-5832/depend3
-rw-r--r--ext/-test-/bug_reporter/depend3
-rw-r--r--ext/-test-/class/depend6
-rw-r--r--ext/-test-/debug/depend9
-rw-r--r--ext/-test-/debug/profile_frames.c21
-rw-r--r--ext/-test-/dln/empty/depend3
-rw-r--r--ext/-test-/enumerator_kw/depend3
-rw-r--r--ext/-test-/exception/depend12
-rw-r--r--ext/-test-/fatal/depend3
-rw-r--r--ext/-test-/file/depend9
-rw-r--r--ext/-test-/float/depend6
-rw-r--r--ext/-test-/funcall/depend3
-rw-r--r--ext/-test-/gvl/call_without_gvl/depend3
-rw-r--r--ext/-test-/hash/depend6
-rw-r--r--ext/-test-/integer/depend9
-rw-r--r--ext/-test-/iseq_load/depend3
-rw-r--r--ext/-test-/iter/depend9
-rw-r--r--ext/-test-/load/dot.dot/depend3
-rw-r--r--ext/-test-/load/protect/depend3
-rw-r--r--ext/-test-/load/resolve_symbol_resolver/extconf.rb1
-rw-r--r--ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c55
-rw-r--r--ext/-test-/load/resolve_symbol_target/extconf.rb1
-rw-r--r--ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c15
-rw-r--r--ext/-test-/load/resolve_symbol_target/resolve_symbol_target.def4
-rw-r--r--ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h4
-rw-r--r--ext/-test-/load/stringify_symbols/extconf.rb1
-rw-r--r--ext/-test-/load/stringify_symbols/stringify_symbols.c29
-rw-r--r--ext/-test-/load/stringify_target/extconf.rb1
-rw-r--r--ext/-test-/load/stringify_target/stringify_target.c15
-rw-r--r--ext/-test-/load/stringify_target/stringify_target.def4
-rw-r--r--ext/-test-/load/stringify_target/stringify_target.h4
-rw-r--r--ext/-test-/marshal/compat/depend3
-rw-r--r--ext/-test-/marshal/internal_ivar/depend3
-rw-r--r--ext/-test-/marshal/usr/depend3
-rw-r--r--ext/-test-/memory_status/depend3
-rw-r--r--ext/-test-/memory_view/depend3
-rw-r--r--ext/-test-/method/depend6
-rw-r--r--ext/-test-/notimplement/depend3
-rw-r--r--ext/-test-/num2int/depend3
-rw-r--r--ext/-test-/path_to_class/depend3
-rw-r--r--ext/-test-/popen_deadlock/depend3
-rw-r--r--ext/-test-/postponed_job/depend3
-rw-r--r--ext/-test-/postponed_job/postponed_job.c131
-rw-r--r--ext/-test-/printf/depend3
-rw-r--r--ext/-test-/proc/depend9
-rw-r--r--ext/-test-/random/depend9
-rw-r--r--ext/-test-/rational/depend3
-rw-r--r--ext/-test-/rb_call_super_kw/depend3
-rw-r--r--ext/-test-/recursion/depend3
-rw-r--r--ext/-test-/regexp/depend6
-rw-r--r--ext/-test-/scan_args/depend3
-rw-r--r--ext/-test-/st/foreach/depend3
-rw-r--r--ext/-test-/st/foreach/foreach.c30
-rw-r--r--ext/-test-/st/numhash/depend3
-rw-r--r--ext/-test-/st/update/depend3
-rw-r--r--ext/-test-/string/cstr.c14
-rw-r--r--ext/-test-/string/depend222
-rw-r--r--ext/-test-/string/enc_dummy.c15
-rw-r--r--ext/-test-/string/fstring.c10
-rw-r--r--ext/-test-/struct/data.c13
-rw-r--r--ext/-test-/struct/depend171
-rw-r--r--ext/-test-/symbol/depend6
-rw-r--r--ext/-test-/thread/instrumentation/depend3
-rw-r--r--ext/-test-/thread/instrumentation/instrumentation.c215
-rw-r--r--ext/-test-/thread_fd/depend3
-rw-r--r--ext/-test-/time/depend9
-rw-r--r--ext/-test-/tracepoint/depend6
-rw-r--r--ext/-test-/tracepoint/gc_hook.c4
-rw-r--r--ext/-test-/typeddata/depend3
-rw-r--r--ext/-test-/vm/depend3
-rw-r--r--ext/-test-/wait/depend3
-rw-r--r--ext/.document6
-rw-r--r--ext/Setup3
-rw-r--r--ext/Setup.atheos6
-rw-r--r--ext/Setup.nt6
-rw-r--r--ext/bigdecimal/bigdecimal.c174
-rw-r--r--ext/bigdecimal/bigdecimal.gemspec40
-rw-r--r--ext/bigdecimal/depend7
-rw-r--r--ext/bigdecimal/extconf.rb25
-rw-r--r--ext/bigdecimal/lib/bigdecimal.rb6
-rw-r--r--ext/bigdecimal/lib/bigdecimal/util.rb10
-rw-r--r--ext/cgi/escape/depend3
-rw-r--r--ext/cgi/escape/escape.c35
-rw-r--r--ext/cgi/escape/extconf.rb6
-rw-r--r--ext/continuation/depend3
-rw-r--r--ext/coverage/coverage.c5
-rw-r--r--ext/coverage/depend17
-rw-r--r--ext/date/date_core.c23
-rw-r--r--ext/date/depend12
-rw-r--r--ext/date/lib/date.rb2
-rw-r--r--ext/digest/bubblebabble/depend3
-rw-r--r--ext/digest/depend3
-rw-r--r--ext/digest/digest.h3
-rw-r--r--ext/digest/md5/depend6
-rw-r--r--ext/digest/rmd160/depend6
-rw-r--r--ext/digest/sha1/depend6
-rw-r--r--ext/digest/sha2/depend6
-rw-r--r--ext/etc/depend3
-rw-r--r--ext/etc/etc.c20
-rw-r--r--ext/etc/extconf.rb14
-rwxr-xr-xext/extmk.rb29
-rw-r--r--ext/fcntl/depend3
-rw-r--r--ext/fcntl/fcntl.c6
-rw-r--r--ext/fcntl/fcntl.gemspec12
-rw-r--r--ext/fiddle/closure.c33
-rw-r--r--ext/fiddle/conversions.c55
-rw-r--r--ext/fiddle/conversions.h2
-rw-r--r--ext/fiddle/depend24
-rw-r--r--ext/fiddle/extconf.rb5
-rw-r--r--ext/fiddle/fiddle.c53
-rw-r--r--ext/fiddle/fiddle.h18
-rw-r--r--ext/fiddle/function.c9
-rw-r--r--ext/fiddle/handle.c9
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb28
-rw-r--r--ext/fiddle/lib/fiddle/import.rb2
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb12
-rw-r--r--ext/fiddle/lib/fiddle/value.rb28
-rw-r--r--ext/fiddle/lib/fiddle/version.rb2
-rw-r--r--ext/fiddle/pointer.c50
-rwxr-xr-xext/fiddle/win32/libffi-config.rb10
-rw-r--r--ext/io/console/.document2
-rw-r--r--ext/io/console/console.c655
-rw-r--r--ext/io/console/depend5
-rw-r--r--ext/io/console/extconf.rb13
-rw-r--r--ext/io/console/io-console.gemspec20
-rw-r--r--ext/io/console/win32_vk.inc327
-rw-r--r--ext/io/console/win32_vk.list2
-rw-r--r--ext/io/nonblock/depend3
-rw-r--r--ext/io/nonblock/extconf.rb7
-rw-r--r--ext/io/nonblock/io-nonblock.gemspec2
-rw-r--r--ext/io/nonblock/nonblock.c71
-rw-r--r--ext/io/wait/depend3
-rw-r--r--ext/io/wait/extconf.rb3
-rw-r--r--ext/io/wait/io-wait.gemspec2
-rw-r--r--ext/io/wait/wait.c11
-rw-r--r--ext/json/VERSION1
-rw-r--r--ext/json/generator/depend3
-rw-r--r--ext/json/generator/generator.c103
-rw-r--r--ext/json/generator/generator.h13
-rw-r--r--ext/json/json.gemspec13
-rw-r--r--ext/json/lib/json.rb9
-rw-r--r--ext/json/lib/json/add/bigdecimal.rb45
-rw-r--r--ext/json/lib/json/add/complex.rb33
-rw-r--r--ext/json/lib/json/add/date.rb32
-rw-r--r--ext/json/lib/json/add/date_time.rb33
-rw-r--r--ext/json/lib/json/add/exception.rb30
-rw-r--r--ext/json/lib/json/add/ostruct.rb32
-rw-r--r--ext/json/lib/json/add/range.rb39
-rw-r--r--ext/json/lib/json/add/rational.rb32
-rw-r--r--ext/json/lib/json/add/regexp.rb32
-rw-r--r--ext/json/lib/json/add/set.rb31
-rw-r--r--ext/json/lib/json/add/struct.rb34
-rw-r--r--ext/json/lib/json/add/symbol.rb31
-rw-r--r--ext/json/lib/json/add/time.rb31
-rw-r--r--ext/json/lib/json/common.rb60
-rw-r--r--ext/json/lib/json/version.rb2
-rw-r--r--ext/json/parser/depend3
-rw-r--r--ext/json/parser/extconf.rb4
-rw-r--r--ext/json/parser/parser.c4792
-rw-r--r--ext/json/parser/parser.rl173
-rw-r--r--ext/monitor/depend3
-rw-r--r--ext/monitor/lib/monitor.rb13
-rw-r--r--ext/monitor/monitor.c2
-rw-r--r--ext/nkf/depend3
-rw-r--r--ext/nkf/nkf.c3
-rw-r--r--ext/nkf/nkf.gemspec13
-rw-r--r--ext/objspace/depend61
-rw-r--r--ext/objspace/lib/objspace.rb35
-rw-r--r--ext/objspace/object_tracing.c2
-rw-r--r--ext/objspace/objspace.c146
-rw-r--r--ext/objspace/objspace_dump.c63
-rw-r--r--ext/openssl/History.md42
-rw-r--r--ext/openssl/depend322
-rw-r--r--ext/openssl/extconf.rb43
-rw-r--r--ext/openssl/lib/openssl/buffering.rb7
-rw-r--r--ext/openssl/lib/openssl/digest.rb6
-rw-r--r--ext/openssl/lib/openssl/ssl.rb20
-rw-r--r--ext/openssl/lib/openssl/version.rb2
-rw-r--r--ext/openssl/openssl.gemspec20
-rw-r--r--ext/openssl/ossl.c268
-rw-r--r--ext/openssl/ossl.h11
-rw-r--r--ext/openssl/ossl_bn.c2
-rw-r--r--ext/openssl/ossl_cipher.c2
-rw-r--r--ext/openssl/ossl_config.c2
-rw-r--r--ext/openssl/ossl_digest.c2
-rw-r--r--ext/openssl/ossl_engine.c2
-rw-r--r--ext/openssl/ossl_hmac.c2
-rw-r--r--ext/openssl/ossl_kdf.c2
-rw-r--r--ext/openssl/ossl_ns_spki.c2
-rw-r--r--ext/openssl/ossl_ocsp.c12
-rw-r--r--ext/openssl/ossl_pkcs12.c2
-rw-r--r--ext/openssl/ossl_pkcs7.c6
-rw-r--r--ext/openssl/ossl_pkey.c261
-rw-r--r--ext/openssl/ossl_pkey_dh.c29
-rw-r--r--ext/openssl/ossl_pkey_dsa.c65
-rw-r--r--ext/openssl/ossl_pkey_ec.c74
-rw-r--r--ext/openssl/ossl_pkey_rsa.c81
-rw-r--r--ext/openssl/ossl_provider.c211
-rw-r--r--ext/openssl/ossl_provider.h5
-rw-r--r--ext/openssl/ossl_ssl.c148
-rw-r--r--ext/openssl/ossl_ssl_session.c2
-rw-r--r--ext/openssl/ossl_ts.c6
-rw-r--r--ext/openssl/ossl_x509attr.c2
-rw-r--r--ext/openssl/ossl_x509cert.c2
-rw-r--r--ext/openssl/ossl_x509crl.c2
-rw-r--r--ext/openssl/ossl_x509ext.c20
-rw-r--r--ext/openssl/ossl_x509name.c2
-rw-r--r--ext/openssl/ossl_x509req.c2
-rw-r--r--ext/openssl/ossl_x509revoked.c2
-rw-r--r--ext/openssl/ossl_x509store.c17
-rw-r--r--ext/pathname/depend3
-rw-r--r--ext/pathname/lib/pathname.rb2
-rw-r--r--ext/pathname/pathname.c28
-rw-r--r--ext/pathname/pathname.gemspec11
-rw-r--r--ext/psych/depend15
-rw-r--r--ext/psych/extconf.rb2
-rw-r--r--ext/psych/lib/psych.rb42
-rw-r--r--ext/psych/lib/psych/class_loader.rb2
-rw-r--r--ext/psych/lib/psych/tree_builder.rb4
-rw-r--r--ext/psych/lib/psych/versions.rb4
-rw-r--r--ext/psych/lib/psych/visitors/to_ruby.rb2
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb17
-rw-r--r--ext/psych/psych.gemspec50
-rw-r--r--ext/pty/depend3
-rw-r--r--ext/pty/pty.c63
-rw-r--r--ext/racc/cparse/README11
-rw-r--r--ext/racc/cparse/cparse.c861
-rw-r--r--ext/racc/cparse/depend162
-rw-r--r--ext/racc/cparse/extconf.rb9
-rw-r--r--ext/rbconfig/sizeof/depend6
-rw-r--r--ext/readline/.gitignore1
-rw-r--r--ext/readline/README10
-rw-r--r--ext/readline/README.ja386
-rw-r--r--ext/readline/depend175
-rw-r--r--ext/readline/depend-gem4
-rw-r--r--ext/readline/extconf.rb112
-rw-r--r--ext/readline/readline-ext.gemspec22
-rw-r--r--ext/readline/readline.c2144
-rw-r--r--ext/ripper/README1
-rw-r--r--ext/ripper/depend564
-rw-r--r--ext/ripper/eventids2.c12
-rw-r--r--ext/ripper/eventids2.h8
-rw-r--r--ext/ripper/extconf.rb15
-rw-r--r--ext/ripper/lib/ripper/lexer.rb7
-rw-r--r--ext/ripper/ripper_init.c.tmpl618
-rw-r--r--ext/ripper/ripper_init.h8
-rw-r--r--ext/ripper/tools/dsl.rb21
-rw-r--r--ext/ripper/tools/generate.rb39
-rw-r--r--ext/ripper/tools/preproc.rb70
-rw-r--r--ext/socket/ancdata.c4
-rw-r--r--ext/socket/depend315
-rw-r--r--ext/socket/extconf.rb25
-rw-r--r--ext/socket/getaddrinfo.c3
-rw-r--r--ext/socket/init.c79
-rw-r--r--ext/socket/lib/socket.rb21
-rw-r--r--ext/socket/mkconstants.rb13
-rw-r--r--ext/socket/raddrinfo.c530
-rw-r--r--ext/socket/rubysocket.h5
-rw-r--r--ext/socket/socket.c5
-rw-r--r--ext/socket/unixsocket.c2
-rw-r--r--ext/stringio/depend3
-rw-r--r--ext/stringio/extconf.rb7
-rw-r--r--ext/stringio/stringio.c227
-rw-r--r--ext/stringio/stringio.gemspec8
-rw-r--r--ext/strscan/depend3
-rw-r--r--ext/strscan/extconf.rb4
-rw-r--r--ext/strscan/strscan.c20
-rw-r--r--ext/syslog/depend3
-rw-r--r--ext/syslog/syslog.c4
-rw-r--r--ext/syslog/syslog.gemspec9
-rw-r--r--ext/win32/lib/win32/registry.rb6
-rw-r--r--ext/win32ole/win32ole.c2
-rw-r--r--ext/win32ole/win32ole.gemspec12
-rw-r--r--ext/zlib/depend3
-rw-r--r--ext/zlib/extconf.rb17
-rw-r--r--ext/zlib/zlib.c11
-rw-r--r--ext/zlib/zlib.gemspec2
-rw-r--r--file.c736
-rw-r--r--gc.c3159
-rw-r--r--gc.h147
-rw-r--r--gc.rb104
-rw-r--r--gem_prelude.rb2
-rw-r--r--gems/bundled_gems31
-rw-r--r--gems/lib/envutil.rb1
-rw-r--r--gems/lib/rake/extensiontask.rb2
-rw-r--r--hash.c891
-rw-r--r--id_table.c6
-rw-r--r--include/ruby/atomic.h51
-rw-r--r--include/ruby/backward/2/attributes.h24
-rw-r--r--include/ruby/debug.h171
-rw-r--r--include/ruby/fiber/scheduler.h80
-rw-r--r--include/ruby/intern.h1
-rw-r--r--include/ruby/internal/abi.h2
-rw-r--r--include/ruby/internal/anyargs.h22
-rw-r--r--include/ruby/internal/attr/noexcept.h2
-rw-r--r--include/ruby/internal/attr/nonstring.h32
-rw-r--r--include/ruby/internal/attr/packed_struct.h43
-rw-r--r--include/ruby/internal/config.h4
-rw-r--r--include/ruby/internal/core/rarray.h198
-rw-r--r--include/ruby/internal/core/rfile.h4
-rw-r--r--include/ruby/internal/core/rhash.h13
-rw-r--r--include/ruby/internal/core/rmatch.h14
-rw-r--r--include/ruby/internal/core/robject.h26
-rw-r--r--include/ruby/internal/core/rstring.h118
-rw-r--r--include/ruby/internal/core/rtypeddata.h57
-rw-r--r--include/ruby/internal/dllexport.h34
-rw-r--r--include/ruby/internal/encoding/encoding.h17
-rw-r--r--include/ruby/internal/encoding/string.h2
-rw-r--r--include/ruby/internal/error.h36
-rw-r--r--include/ruby/internal/event.h5
-rw-r--r--include/ruby/internal/fl_type.h93
-rw-r--r--include/ruby/internal/gc.h780
-rw-r--r--include/ruby/internal/globals.h2
-rw-r--r--include/ruby/internal/has/c_attribute.h12
-rw-r--r--include/ruby/internal/intern/array.h2
-rw-r--r--include/ruby/internal/intern/bignum.h4
-rw-r--r--include/ruby/internal/intern/error.h2
-rw-r--r--include/ruby/internal/intern/gc.h392
-rw-r--r--include/ruby/internal/intern/load.h37
-rw-r--r--include/ruby/internal/intern/process.h11
-rw-r--r--include/ruby/internal/intern/re.h5
-rw-r--r--include/ruby/internal/intern/select.h2
-rw-r--r--include/ruby/internal/intern/signal.h6
-rw-r--r--include/ruby/internal/intern/struct.h30
-rw-r--r--include/ruby/internal/memory.h2
-rw-r--r--include/ruby/internal/newobj.h4
-rw-r--r--include/ruby/internal/rgengc.h443
-rw-r--r--include/ruby/io.h102
-rw-r--r--include/ruby/io/buffer.h22
-rw-r--r--include/ruby/memory_view.h4
-rw-r--r--include/ruby/onigmo.h4
-rw-r--r--include/ruby/random.h2
-rw-r--r--include/ruby/re.h25
-rw-r--r--include/ruby/ruby.h125
-rw-r--r--include/ruby/st.h4
-rw-r--r--include/ruby/thread.h87
-rw-r--r--include/ruby/thread_native.h5
-rw-r--r--include/ruby/util.h13
-rw-r--r--include/ruby/version.h2
-rw-r--r--include/ruby/win32.h15
-rw-r--r--inits.c15
-rw-r--r--insns.def105
-rw-r--r--internal.h1
-rw-r--r--internal/array.h32
-rw-r--r--internal/basic_operators.h3
-rw-r--r--internal/bignum.h2
-rw-r--r--internal/bits.h31
-rw-r--r--internal/class.h134
-rw-r--r--internal/cmdlineopt.h12
-rw-r--r--internal/compile.h3
-rw-r--r--internal/cont.h3
-rw-r--r--internal/encoding.h3
-rw-r--r--internal/error.h29
-rw-r--r--internal/gc.h232
-rw-r--r--internal/hash.h93
-rw-r--r--internal/imemo.h4
-rw-r--r--internal/io.h99
-rw-r--r--internal/numeric.h2
-rw-r--r--internal/object.h5
-rw-r--r--internal/parse.h97
-rw-r--r--internal/proc.h2
-rw-r--r--internal/process.h15
-rw-r--r--internal/random.h1
-rw-r--r--internal/range.h4
-rw-r--r--internal/rational.h1
-rw-r--r--internal/re.h4
-rw-r--r--internal/ruby_parser.h69
-rw-r--r--internal/sanitizers.h4
-rw-r--r--internal/signal.h4
-rw-r--r--internal/string.h19
-rw-r--r--internal/struct.h44
-rw-r--r--internal/symbol.h3
-rw-r--r--internal/thread.h26
-rw-r--r--internal/time.h5
-rw-r--r--internal/transcode.h3
-rw-r--r--internal/variable.h60
-rw-r--r--internal/vm.h28
-rw-r--r--io.c797
-rw-r--r--io.rb13
-rw-r--r--io_buffer.c809
-rw-r--r--iseq.c552
-rw-r--r--iseq.h24
-rw-r--r--kernel.rb160
-rw-r--r--lib/English.gemspec4
-rw-r--r--lib/English.rb60
-rw-r--r--lib/abbrev.gemspec11
-rw-r--r--lib/abbrev.rb1
-rw-r--r--lib/base64.gemspec13
-rw-r--r--lib/base64.rb373
-rw-r--r--lib/benchmark.gemspec30
-rw-r--r--lib/benchmark.rb2
-rw-r--r--lib/benchmark/benchmark.gemspec29
-rw-r--r--lib/benchmark/version.rb4
-rw-r--r--lib/bundled_gems.rb195
-rw-r--r--lib/bundler.rb106
-rw-r--r--lib/bundler/build_metadata.rb2
-rw-r--r--lib/bundler/bundler.gemspec8
-rw-r--r--lib/bundler/capistrano.rb2
-rw-r--r--lib/bundler/checksum.rb254
-rw-r--r--lib/bundler/ci_detector.rb75
-rw-r--r--lib/bundler/cli.rb503
-rw-r--r--lib/bundler/cli/add.rb6
-rw-r--r--lib/bundler/cli/binstubs.rb8
-rw-r--r--lib/bundler/cli/cache.rb2
-rw-r--r--lib/bundler/cli/check.rb4
-rw-r--r--lib/bundler/cli/common.rb10
-rw-r--r--lib/bundler/cli/config.rb15
-rw-r--r--lib/bundler/cli/console.rb5
-rw-r--r--lib/bundler/cli/doctor.rb4
-rw-r--r--lib/bundler/cli/exec.rb2
-rw-r--r--lib/bundler/cli/gem.rb58
-rw-r--r--lib/bundler/cli/info.rb15
-rw-r--r--lib/bundler/cli/install.rb15
-rw-r--r--lib/bundler/cli/issue.rb2
-rw-r--r--lib/bundler/cli/lock.rb56
-rw-r--r--lib/bundler/cli/open.rb12
-rw-r--r--lib/bundler/cli/outdated.rb12
-rw-r--r--lib/bundler/cli/plugin.rb24
-rw-r--r--lib/bundler/cli/pristine.rb68
-rw-r--r--lib/bundler/cli/show.rb4
-rw-r--r--lib/bundler/cli/update.rb11
-rw-r--r--lib/bundler/compact_index_client.rb21
-rw-r--r--lib/bundler/compact_index_client/cache.rb61
-rw-r--r--lib/bundler/compact_index_client/cache_file.rb153
-rw-r--r--lib/bundler/compact_index_client/gem_parser.rb10
-rw-r--r--lib/bundler/compact_index_client/updater.rb160
-rw-r--r--lib/bundler/constants.rb9
-rw-r--r--lib/bundler/current_ruby.rb26
-rw-r--r--lib/bundler/definition.rb322
-rw-r--r--lib/bundler/dependency.rb35
-rw-r--r--lib/bundler/digest.rb4
-rw-r--r--lib/bundler/dsl.rb98
-rw-r--r--lib/bundler/endpoint_specification.rb8
-rw-r--r--lib/bundler/env.rb8
-rw-r--r--lib/bundler/environment_preserver.rb28
-rw-r--r--lib/bundler/errors.rb72
-rw-r--r--lib/bundler/fetcher.rb116
-rw-r--r--lib/bundler/fetcher/base.rb8
-rw-r--r--lib/bundler/fetcher/compact_index.rb14
-rw-r--r--lib/bundler/fetcher/dependency.rb2
-rw-r--r--lib/bundler/fetcher/downloader.rb26
-rw-r--r--lib/bundler/fetcher/gem_remote_fetcher.rb16
-rw-r--r--lib/bundler/fetcher/index.rb2
-rw-r--r--lib/bundler/friendly_errors.rb10
-rw-r--r--lib/bundler/gem_helper.rb4
-rw-r--r--lib/bundler/gem_helpers.rb14
-rw-r--r--lib/bundler/gem_version_promoter.rb82
-rw-r--r--lib/bundler/graph.rb18
-rw-r--r--lib/bundler/index.rb96
-rw-r--r--lib/bundler/injector.rb9
-rw-r--r--lib/bundler/inline.rb6
-rw-r--r--lib/bundler/installer.rb38
-rw-r--r--lib/bundler/installer/gem_installer.rb20
-rw-r--r--lib/bundler/installer/parallel_installer.rb50
-rw-r--r--lib/bundler/installer/standalone.rb19
-rw-r--r--lib/bundler/lazy_specification.rb47
-rw-r--r--lib/bundler/lockfile_generator.rb9
-rw-r--r--lib/bundler/lockfile_parser.rb152
-rw-r--r--lib/bundler/man/bundle-add.129
-rw-r--r--lib/bundler/man/bundle-binstubs.120
-rw-r--r--lib/bundler/man/bundle-cache.127
-rw-r--r--lib/bundler/man/bundle-check.117
-rw-r--r--lib/bundler/man/bundle-check.1.ronn3
-rw-r--r--lib/bundler/man/bundle-clean.113
-rw-r--r--lib/bundler/man/bundle-config.1235
-rw-r--r--lib/bundler/man/bundle-config.1.ronn13
-rw-r--r--lib/bundler/man/bundle-console.126
-rw-r--r--lib/bundler/man/bundle-doctor.122
-rw-r--r--lib/bundler/man/bundle-exec.187
-rw-r--r--lib/bundler/man/bundle-exec.1.ronn5
-rw-r--r--lib/bundler/man/bundle-gem.162
-rw-r--r--lib/bundler/man/bundle-help.110
-rw-r--r--lib/bundler/man/bundle-info.112
-rw-r--r--lib/bundler/man/bundle-init.115
-rw-r--r--lib/bundler/man/bundle-inject.125
-rw-r--r--lib/bundler/man/bundle-install.1156
-rw-r--r--lib/bundler/man/bundle-install.1.ronn5
-rw-r--r--lib/bundler/man/bundle-list.123
-rw-r--r--lib/bundler/man/bundle-lock.134
-rw-r--r--lib/bundler/man/bundle-open.134
-rw-r--r--lib/bundler/man/bundle-outdated.158
-rw-r--r--lib/bundler/man/bundle-outdated.1.ronn1
-rw-r--r--lib/bundler/man/bundle-platform.132
-rw-r--r--lib/bundler/man/bundle-plugin.171
-rw-r--r--lib/bundler/man/bundle-plugin.1.ronn20
-rw-r--r--lib/bundler/man/bundle-pristine.121
-rw-r--r--lib/bundler/man/bundle-remove.118
-rw-r--r--lib/bundler/man/bundle-show.113
-rw-r--r--lib/bundler/man/bundle-update.1155
-rw-r--r--lib/bundler/man/bundle-version.119
-rw-r--r--lib/bundler/man/bundle-viz.120
-rw-r--r--lib/bundler/man/bundle.149
-rw-r--r--lib/bundler/man/gemfile.5332
-rw-r--r--lib/bundler/man/gemfile.5.ronn13
-rw-r--r--lib/bundler/match_metadata.rb4
-rw-r--r--lib/bundler/match_platform.rb2
-rw-r--r--lib/bundler/mirror.rb6
-rw-r--r--lib/bundler/plugin.rb19
-rw-r--r--lib/bundler/plugin/api/source.rb9
-rw-r--r--lib/bundler/plugin/index.rb8
-rw-r--r--lib/bundler/plugin/installer.rb54
-rw-r--r--lib/bundler/plugin/installer/path.rb18
-rw-r--r--lib/bundler/plugin/source_list.rb8
-rw-r--r--lib/bundler/remote_specification.rb4
-rw-r--r--lib/bundler/resolver.rb165
-rw-r--r--lib/bundler/resolver/base.rb2
-rw-r--r--lib/bundler/resolver/candidate.rb2
-rw-r--r--lib/bundler/resolver/incompatibility.rb2
-rw-r--r--lib/bundler/resolver/package.rb5
-rw-r--r--lib/bundler/resolver/spec_group.rb5
-rw-r--r--lib/bundler/retry.rb2
-rw-r--r--lib/bundler/ruby_dsl.rb49
-rw-r--r--lib/bundler/ruby_version.rb11
-rw-r--r--lib/bundler/rubygems_ext.rb115
-rw-r--r--lib/bundler/rubygems_gem_installer.rb81
-rw-r--r--lib/bundler/rubygems_integration.rb119
-rw-r--r--lib/bundler/runtime.rb6
-rw-r--r--lib/bundler/self_manager.rb34
-rw-r--r--lib/bundler/settings.rb163
-rw-r--r--lib/bundler/setup.rb8
-rw-r--r--lib/bundler/shared_helpers.rb73
-rw-r--r--lib/bundler/source.rb2
-rw-r--r--lib/bundler/source/git.rb9
-rw-r--r--lib/bundler/source/git/git_proxy.rb88
-rw-r--r--lib/bundler/source/metadata.rb32
-rw-r--r--lib/bundler/source/path.rb13
-rw-r--r--lib/bundler/source/rubygems.rb108
-rw-r--r--lib/bundler/source/rubygems/remote.rb2
-rw-r--r--lib/bundler/source_list.rb28
-rw-r--r--lib/bundler/spec_set.rb132
-rw-r--r--lib/bundler/stub_specification.rb7
-rw-r--r--lib/bundler/templates/Executable.bundler2
-rw-r--r--lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt106
-rw-r--r--lib/bundler/templates/newgem/README.md.tt6
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt16
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt2
-rw-r--r--lib/bundler/templates/newgem/github/workflows/main.yml.tt2
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt9
-rw-r--r--lib/bundler/templates/newgem/rubocop.yml.tt5
-rw-r--r--lib/bundler/templates/newgem/standard.yml.tt2
-rw-r--r--lib/bundler/ui/shell.rb4
-rw-r--r--lib/bundler/uri_credentials_filter.rb4
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool.rb59
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb2
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils.rb28
-rw-r--r--lib/bundler/vendor/net-http-persistent/.document1
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb114
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb7
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb34
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb2
-rw-r--r--lib/bundler/vendor/pub_grub/.document1
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb1
-rw-r--r--lib/bundler/vendor/thor/.document1
-rw-r--r--lib/bundler/vendor/thor/lib/thor.rb163
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions.rb30
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/create_file.rb5
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/directory.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb18
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb19
-rw-r--r--lib/bundler/vendor/thor/lib/thor/base.rb154
-rw-r--r--lib/bundler/vendor/thor/lib/thor/command.rb17
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/error.rb41
-rw-r--r--lib/bundler/vendor/thor/lib/thor/group.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/invocation.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/nested_context.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/argument.rb21
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/arguments.rb50
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/option.rb35
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/options.rb50
-rw-r--r--lib/bundler/vendor/thor/lib/thor/rake_compat.rb4
-rw-r--r--lib/bundler/vendor/thor/lib/thor/runner.rb70
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/basic.rb176
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/color.rb47
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb29
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/html.rb45
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb134
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/terminal.rb42
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb38
-rw-r--r--lib/bundler/vendor/thor/lib/thor/util.rb15
-rw-r--r--lib/bundler/vendor/thor/lib/thor/version.rb2
-rw-r--r--lib/bundler/vendor/tsort/.document1
-rw-r--r--lib/bundler/vendor/tsort/lib/tsort.rb3
-rw-r--r--lib/bundler/vendor/uri/.document1
-rw-r--r--lib/bundler/vendor/uri/lib/uri/common.rb388
-rw-r--r--lib/bundler/vendor/uri/lib/uri/generic.rb1
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb126
-rw-r--r--lib/bundler/vendor/uri/lib/uri/version.rb2
-rw-r--r--lib/bundler/vendored_net_http.rb12
-rw-r--r--lib/bundler/vendored_persistent.rb4
-rw-r--r--lib/bundler/vendored_timeout.rb12
-rw-r--r--lib/bundler/vendored_uri.rb19
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/bundler/vlad.rb2
-rw-r--r--lib/bundler/yaml_serializer.rb38
-rw-r--r--lib/cgi.rb2
-rw-r--r--lib/cgi/cookie.rb5
-rw-r--r--lib/cgi/session.rb2
-rw-r--r--lib/cgi/util.rb20
-rw-r--r--lib/csv.rb27
-rw-r--r--lib/csv/delete_suffix.rb18
-rw-r--r--lib/csv/match_p.rb20
-rw-r--r--lib/csv/parser.rb13
-rw-r--r--lib/csv/version.rb2
-rw-r--r--lib/delegate.gemspec29
-rw-r--r--lib/delegate.rb2
-rw-r--r--lib/delegate/delegate.gemspec29
-rw-r--r--lib/did_you_mean.rb4
-rw-r--r--lib/drb/drb.rb3
-rw-r--r--lib/drb/ssl.rb10
-rw-r--r--lib/drb/version.rb2
-rw-r--r--lib/erb.gemspec2
-rw-r--r--lib/erb.rb4
-rw-r--r--lib/erb/compiler.rb1
-rw-r--r--lib/erb/def_method.rb1
-rw-r--r--lib/erb/util.rb1
-rw-r--r--lib/erb/version.rb2
-rw-r--r--lib/error_highlight/base.rb31
-rw-r--r--lib/error_highlight/version.rb2
-rw-r--r--lib/fileutils.rb30
-rw-r--r--lib/find.gemspec11
-rw-r--r--lib/find.rb2
-rw-r--r--lib/getoptlong.gemspec30
-rw-r--r--lib/getoptlong.rb4
-rw-r--r--lib/getoptlong/getoptlong.gemspec30
-rw-r--r--lib/ipaddr.rb42
-rw-r--r--lib/irb.rb1865
-rw-r--r--lib/irb/cmd/backtrace.rb21
-rw-r--r--lib/irb/cmd/break.rb21
-rw-r--r--lib/irb/cmd/catch.rb21
-rw-r--r--lib/irb/cmd/chws.rb42
-rw-r--r--lib/irb/cmd/continue.rb17
-rw-r--r--lib/irb/cmd/debug.rb136
-rw-r--r--lib/irb/cmd/delete.rb17
-rw-r--r--lib/irb/cmd/edit.rb61
-rw-r--r--lib/irb/cmd/finish.rb17
-rw-r--r--lib/irb/cmd/fork.rb40
-rw-r--r--lib/irb/cmd/help.rb63
-rw-r--r--lib/irb/cmd/info.rb21
-rw-r--r--lib/irb/cmd/irb_info.rb37
-rw-r--r--lib/irb/cmd/load.rb82
-rw-r--r--lib/irb/cmd/ls.rb116
-rw-r--r--lib/irb/cmd/measure.rb48
-rw-r--r--lib/irb/cmd/next.rb17
-rw-r--r--lib/irb/cmd/nop.rb73
-rw-r--r--lib/irb/cmd/pushws.rb51
-rw-r--r--lib/irb/cmd/show_cmds.rb39
-rw-r--r--lib/irb/cmd/show_source.rb112
-rw-r--r--lib/irb/cmd/step.rb17
-rw-r--r--lib/irb/cmd/subirb.rb71
-rw-r--r--lib/irb/cmd/whereami.rb25
-rw-r--r--lib/irb/color.rb20
-rw-r--r--lib/irb/color_printer.rb7
-rw-r--r--lib/irb/command.rb23
-rw-r--r--lib/irb/command/backtrace.rb17
-rw-r--r--lib/irb/command/base.rb62
-rw-r--r--lib/irb/command/break.rb17
-rw-r--r--lib/irb/command/catch.rb17
-rw-r--r--lib/irb/command/chws.rb40
-rw-r--r--lib/irb/command/context.rb16
-rw-r--r--lib/irb/command/continue.rb17
-rw-r--r--lib/irb/command/debug.rb71
-rw-r--r--lib/irb/command/delete.rb17
-rw-r--r--lib/irb/command/disable_irb.rb19
-rw-r--r--lib/irb/command/edit.rb63
-rw-r--r--lib/irb/command/exit.rb18
-rw-r--r--lib/irb/command/finish.rb17
-rw-r--r--lib/irb/command/force_exit.rb18
-rw-r--r--lib/irb/command/help.rb83
-rw-r--r--lib/irb/command/history.rb45
-rw-r--r--lib/irb/command/info.rb17
-rw-r--r--lib/irb/command/internal_helpers.rb27
-rw-r--r--lib/irb/command/irb_info.rb33
-rw-r--r--lib/irb/command/load.rb91
-rw-r--r--lib/irb/command/ls.rb155
-rw-r--r--lib/irb/command/measure.rb49
-rw-r--r--lib/irb/command/next.rb17
-rw-r--r--lib/irb/command/pushws.rb65
-rw-r--r--lib/irb/command/show_doc.rb51
-rw-r--r--lib/irb/command/show_source.rb74
-rw-r--r--lib/irb/command/step.rb17
-rw-r--r--lib/irb/command/subirb.rb123
-rw-r--r--lib/irb/command/whereami.rb23
-rw-r--r--lib/irb/completion.rb282
-rw-r--r--lib/irb/context.rb267
-rw-r--r--lib/irb/debug.rb130
-rw-r--r--lib/irb/debug/ui.rb103
-rw-r--r--lib/irb/default_commands.rb260
-rw-r--r--lib/irb/easter-egg.rb22
-rw-r--r--lib/irb/ext/change-ws.rb20
-rw-r--r--lib/irb/ext/eval_history.rb149
-rw-r--r--lib/irb/ext/history.rb155
-rw-r--r--lib/irb/ext/loader.rb42
-rw-r--r--lib/irb/ext/multi-irb.rb16
-rw-r--r--lib/irb/ext/save-history.rb130
-rw-r--r--lib/irb/ext/tracer.rb73
-rw-r--r--lib/irb/ext/use-loader.rb20
-rw-r--r--lib/irb/ext/workspaces.rb50
-rw-r--r--lib/irb/extend-command.rb433
-rw-r--r--lib/irb/frame.rb8
-rw-r--r--lib/irb/help.rb16
-rw-r--r--lib/irb/helper_method.rb29
-rw-r--r--lib/irb/helper_method/base.rb16
-rw-r--r--lib/irb/helper_method/conf.rb11
-rw-r--r--lib/irb/history.rb87
-rw-r--r--lib/irb/init.rb193
-rw-r--r--lib/irb/input-method.rb448
-rw-r--r--lib/irb/inspector.rb28
-rw-r--r--lib/irb/irb.gemspec10
-rw-r--r--lib/irb/lc/error.rb18
-rw-r--r--lib/irb/lc/help-message8
-rw-r--r--lib/irb/lc/ja/encoding_aliases.rb13
-rw-r--r--lib/irb/lc/ja/error.rb20
-rw-r--r--lib/irb/lc/ja/help-message13
-rw-r--r--lib/irb/locale.rb64
-rw-r--r--lib/irb/magic-file.rb38
-rw-r--r--lib/irb/nesting_parser.rb237
-rw-r--r--lib/irb/notifier.rb8
-rw-r--r--lib/irb/output-method.rb16
-rw-r--r--lib/irb/pager.rb91
-rw-r--r--lib/irb/ruby-lex.rb1150
-rw-r--r--lib/irb/ruby_logo.aa43
-rw-r--r--lib/irb/source_finder.rb139
-rw-r--r--lib/irb/src_encoding.rb7
-rw-r--r--lib/irb/statement.rb80
-rw-r--r--lib/irb/version.rb12
-rw-r--r--lib/irb/workspace.rb43
-rw-r--r--lib/irb/ws-for-case-2.rb8
-rw-r--r--lib/irb/xmp.rb12
-rw-r--r--lib/logger.rb42
-rw-r--r--lib/logger/logger.gemspec6
-rw-r--r--lib/logger/severity.rb19
-rw-r--r--lib/logger/version.rb2
-rw-r--r--lib/mkmf.rb160
-rw-r--r--lib/mutex_m.gemspec1
-rw-r--r--lib/mutex_m.rb14
-rw-r--r--lib/net/net-protocol.gemspec2
-rw-r--r--lib/net/protocol.rb2
-rw-r--r--lib/observer.gemspec32
-rw-r--r--lib/observer.rb2
-rw-r--r--lib/observer/observer.gemspec32
-rw-r--r--lib/open-uri.gemspec11
-rw-r--r--lib/open-uri.rb10
-rw-r--r--lib/open3.rb1268
-rw-r--r--lib/open3/open3.gemspec2
-rw-r--r--lib/open3/version.rb2
-rw-r--r--lib/optparse.rb37
-rw-r--r--lib/ostruct.gemspec24
-rw-r--r--lib/ostruct.rb14
-rw-r--r--lib/ostruct/ostruct.gemspec27
-rw-r--r--lib/pp.gemspec11
-rw-r--r--lib/pp.rb8
-rw-r--r--lib/prettyprint.gemspec11
-rw-r--r--lib/prettyprint.rb6
-rw-r--r--lib/prism.rb99
-rw-r--r--lib/prism/debug.rb200
-rw-r--r--lib/prism/desugar_compiler.rb207
-rw-r--r--lib/prism/ffi.rb341
-rw-r--r--lib/prism/lex_compat.rb892
-rw-r--r--lib/prism/node_ext.rb189
-rw-r--r--lib/prism/node_inspector.rb68
-rw-r--r--lib/prism/pack.rb224
-rw-r--r--lib/prism/parse_result.rb460
-rw-r--r--lib/prism/parse_result/comments.rb177
-rw-r--r--lib/prism/parse_result/newlines.rb64
-rw-r--r--lib/prism/pattern.rb250
-rw-r--r--lib/prism/prism.gemspec119
-rw-r--r--lib/prism/ripper_compat.rb207
-rw-r--r--lib/pstore.gemspec32
-rw-r--r--lib/pstore.rb14
-rw-r--r--lib/pstore/pstore.gemspec32
-rw-r--r--lib/racc.rb6
-rw-r--r--lib/racc/compat.rb33
-rw-r--r--lib/racc/debugflags.rb60
-rw-r--r--lib/racc/exception.rb16
-rw-r--r--lib/racc/grammar.rb1118
-rw-r--r--lib/racc/grammarfileparser.rb561
-rw-r--r--lib/racc/info.rb17
-rw-r--r--lib/racc/iset.rb92
-rw-r--r--lib/racc/logfilegenerator.rb212
-rw-r--r--lib/racc/parser-text.rb637
-rw-r--r--lib/racc/parser.rb632
-rw-r--r--lib/racc/parserfilegenerator.rb468
-rw-r--r--lib/racc/racc.gemspec58
-rw-r--r--lib/racc/sourcetext.rb35
-rw-r--r--lib/racc/state.rb972
-rw-r--r--lib/racc/statetransitiontable.rb311
-rw-r--r--lib/racc/static.rb5
-rw-r--r--lib/random/formatter.rb134
-rw-r--r--lib/rdoc.rb12
-rw-r--r--lib/rdoc/alias.rb1
-rw-r--r--lib/rdoc/anon_class.rb1
-rw-r--r--lib/rdoc/any_method.rb15
-rw-r--r--lib/rdoc/attr.rb1
-rw-r--r--lib/rdoc/class_module.rb1
-rw-r--r--lib/rdoc/comment.rb61
-rw-r--r--lib/rdoc/constant.rb1
-rw-r--r--lib/rdoc/context/section.rb1
-rw-r--r--lib/rdoc/cross_reference.rb4
-rw-r--r--lib/rdoc/encoding.rb18
-rw-r--r--lib/rdoc/erb_partial.rb1
-rw-r--r--lib/rdoc/erbio.rb9
-rw-r--r--lib/rdoc/extend.rb1
-rw-r--r--lib/rdoc/generator/darkfish.rb8
-rw-r--r--lib/rdoc/generator/json_index.rb4
-rw-r--r--lib/rdoc/generator/markup.rb1
-rw-r--r--lib/rdoc/generator/pot.rb1
-rw-r--r--lib/rdoc/generator/ri.rb1
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml2
-rw-r--r--lib/rdoc/generator/template/darkfish/class.rhtml6
-rw-r--r--lib/rdoc/generator/template/darkfish/css/rdoc.css51
-rw-r--r--lib/rdoc/generator/template/darkfish/js/darkfish.js13
-rw-r--r--lib/rdoc/generator/template/darkfish/js/search.js6
-rw-r--r--lib/rdoc/generator/template/darkfish/table_of_contents.rhtml9
-rw-r--r--lib/rdoc/generator/template/json_index/js/navigation.js16
-rw-r--r--lib/rdoc/ghost_method.rb1
-rw-r--r--lib/rdoc/include.rb1
-rw-r--r--lib/rdoc/markdown.rb2
-rw-r--r--lib/rdoc/markdown/entities.rb1
-rw-r--r--lib/rdoc/markdown/literals.rb1
-rw-r--r--lib/rdoc/markup/attr_changer.rb1
-rw-r--r--lib/rdoc/markup/attr_span.rb1
-rw-r--r--lib/rdoc/markup/attribute_manager.rb26
-rw-r--r--lib/rdoc/markup/attributes.rb1
-rw-r--r--lib/rdoc/markup/blank_line.rb1
-rw-r--r--lib/rdoc/markup/block_quote.rb1
-rw-r--r--lib/rdoc/markup/document.rb1
-rw-r--r--lib/rdoc/markup/formatter.rb3
-rw-r--r--lib/rdoc/markup/hard_break.rb1
-rw-r--r--lib/rdoc/markup/heading.rb1
-rw-r--r--lib/rdoc/markup/include.rb1
-rw-r--r--lib/rdoc/markup/indented_paragraph.rb1
-rw-r--r--lib/rdoc/markup/list.rb1
-rw-r--r--lib/rdoc/markup/list_item.rb1
-rw-r--r--lib/rdoc/markup/paragraph.rb1
-rw-r--r--lib/rdoc/markup/parser.rb6
-rw-r--r--lib/rdoc/markup/raw.rb1
-rw-r--r--lib/rdoc/markup/regexp_handling.rb1
-rw-r--r--lib/rdoc/markup/rule.rb1
-rw-r--r--lib/rdoc/markup/table.rb13
-rw-r--r--lib/rdoc/markup/to_ansi.rb1
-rw-r--r--lib/rdoc/markup/to_html.rb10
-rw-r--r--lib/rdoc/markup/to_html_crossref.rb2
-rw-r--r--lib/rdoc/markup/to_html_snippet.rb4
-rw-r--r--lib/rdoc/markup/to_joined_paragraph.rb5
-rw-r--r--lib/rdoc/markup/to_label.rb1
-rw-r--r--lib/rdoc/markup/to_markdown.rb1
-rw-r--r--lib/rdoc/markup/to_rdoc.rb1
-rw-r--r--lib/rdoc/markup/to_table_of_contents.rb1
-rw-r--r--lib/rdoc/markup/to_test.rb1
-rw-r--r--lib/rdoc/markup/to_tt_only.rb1
-rw-r--r--lib/rdoc/markup/verbatim.rb1
-rw-r--r--lib/rdoc/meta_method.rb1
-rw-r--r--lib/rdoc/method_attr.rb1
-rw-r--r--lib/rdoc/mixin.rb1
-rw-r--r--lib/rdoc/normal_class.rb1
-rw-r--r--lib/rdoc/normal_module.rb1
-rw-r--r--lib/rdoc/options.rb5
-rw-r--r--lib/rdoc/parser/c.rb29
-rw-r--r--lib/rdoc/parser/changelog.rb16
-rw-r--r--lib/rdoc/parser/markdown.rb2
-rw-r--r--lib/rdoc/parser/rd.rb1
-rw-r--r--lib/rdoc/parser/ripper_state_lex.rb12
-rw-r--r--lib/rdoc/parser/ruby.rb11
-rw-r--r--lib/rdoc/parser/ruby_tools.rb2
-rw-r--r--lib/rdoc/parser/text.rb1
-rw-r--r--lib/rdoc/rd/block_parser.rb658
-rw-r--r--lib/rdoc/rd/inline.rb1
-rw-r--r--lib/rdoc/rd/inline_parser.rb656
-rw-r--r--lib/rdoc/rdoc.gemspec6
-rw-r--r--lib/rdoc/rdoc.rb6
-rw-r--r--lib/rdoc/require.rb1
-rw-r--r--lib/rdoc/ri/driver.rb17
-rw-r--r--lib/rdoc/ri/store.rb1
-rw-r--r--lib/rdoc/single_class.rb1
-rw-r--r--lib/rdoc/stats/quiet.rb1
-rw-r--r--lib/rdoc/stats/verbose.rb2
-rw-r--r--lib/rdoc/store.rb3
-rw-r--r--lib/rdoc/task.rb30
-rw-r--r--lib/rdoc/text.rb10
-rw-r--r--lib/rdoc/token_stream.rb3
-rw-r--r--lib/rdoc/top_level.rb4
-rw-r--r--lib/rdoc/version.rb2
-rw-r--r--lib/readline.gemspec2
-rw-r--r--lib/readline.rb2
-rw-r--r--lib/reline.rb298
-rw-r--r--lib/reline/ansi.rb172
-rw-r--r--lib/reline/config.rb78
-rw-r--r--lib/reline/face.rb199
-rw-r--r--lib/reline/general_io.rb26
-rw-r--r--lib/reline/history.rb2
-rw-r--r--lib/reline/key_actor/base.rb4
-rw-r--r--lib/reline/key_actor/emacs.rb26
-rw-r--r--lib/reline/key_actor/vi_command.rb46
-rw-r--r--lib/reline/key_actor/vi_insert.rb10
-rw-r--r--lib/reline/key_stroke.rb57
-rw-r--r--lib/reline/kill_ring.rb4
-rw-r--r--lib/reline/line_editor.rb2954
-rw-r--r--lib/reline/reline.gemspec5
-rw-r--r--lib/reline/terminfo.rb37
-rw-r--r--lib/reline/unicode.rb159
-rw-r--r--lib/reline/unicode/east_asian_width.rb150
-rw-r--r--lib/reline/version.rb2
-rw-r--r--lib/reline/windows.rb12
-rw-r--r--lib/resolv.gemspec11
-rw-r--r--lib/resolv.rb517
-rw-r--r--lib/rinda/rinda.gemspec11
-rw-r--r--lib/rinda/rinda.rb2
-rw-r--r--lib/ruby_vm/mjit/c_pointer.rb329
-rw-r--r--lib/ruby_vm/mjit/c_type.rb91
-rw-r--r--lib/ruby_vm/mjit/compiler.rb952
-rw-r--r--lib/ruby_vm/mjit/hooks.rb32
-rw-r--r--lib/ruby_vm/rjit/.document1
-rw-r--r--lib/ruby_vm/rjit/assembler.rb1140
-rw-r--r--lib/ruby_vm/rjit/block.rb11
-rw-r--r--lib/ruby_vm/rjit/branch_stub.rb24
-rw-r--r--lib/ruby_vm/rjit/c_pointer.rb394
-rw-r--r--lib/ruby_vm/rjit/c_type.rb99
-rw-r--r--lib/ruby_vm/rjit/code_block.rb91
-rw-r--r--lib/ruby_vm/rjit/compiler.rb518
-rw-r--r--lib/ruby_vm/rjit/context.rb377
-rw-r--r--lib/ruby_vm/rjit/entry_stub.rb7
-rw-r--r--lib/ruby_vm/rjit/exit_compiler.rb164
-rw-r--r--lib/ruby_vm/rjit/hooks.rb36
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb5972
-rw-r--r--lib/ruby_vm/rjit/invariants.rb155
-rw-r--r--lib/ruby_vm/rjit/jit_state.rb65
-rw-r--r--lib/ruby_vm/rjit/stats.rb191
-rw-r--r--lib/ruby_vm/rjit/type.rb221
-rw-r--r--lib/rubygems.rb121
-rw-r--r--lib/rubygems/available_set.rb10
-rw-r--r--lib/rubygems/basic_specification.rb80
-rw-r--r--lib/rubygems/bundler_version_finder.rb8
-rw-r--r--lib/rubygems/ci_detector.rb75
-rw-r--r--lib/rubygems/command.rb67
-rw-r--r--lib/rubygems/command_manager.rb12
-rw-r--r--lib/rubygems/commands/build_command.rb17
-rw-r--r--lib/rubygems/commands/cert_command.rb11
-rw-r--r--lib/rubygems/commands/check_command.rb14
-rw-r--r--lib/rubygems/commands/cleanup_command.rb28
-rw-r--r--lib/rubygems/commands/contents_command.rb12
-rw-r--r--lib/rubygems/commands/dependency_command.rb14
-rw-r--r--lib/rubygems/commands/environment_command.rb8
-rw-r--r--lib/rubygems/commands/exec_command.rb2
-rw-r--r--lib/rubygems/commands/fetch_command.rb4
-rw-r--r--lib/rubygems/commands/generate_index_command.rb113
-rw-r--r--lib/rubygems/commands/help_command.rb16
-rw-r--r--lib/rubygems/commands/info_command.rb4
-rw-r--r--lib/rubygems/commands/install_command.rb24
-rw-r--r--lib/rubygems/commands/list_command.rb4
-rw-r--r--lib/rubygems/commands/lock_command.rb2
-rw-r--r--lib/rubygems/commands/open_command.rb4
-rw-r--r--lib/rubygems/commands/owner_command.rb22
-rw-r--r--lib/rubygems/commands/pristine_command.rb41
-rw-r--r--lib/rubygems/commands/push_command.rb4
-rw-r--r--lib/rubygems/commands/query_command.rb9
-rw-r--r--lib/rubygems/commands/rdoc_command.rb13
-rw-r--r--lib/rubygems/commands/rebuild_command.rb264
-rw-r--r--lib/rubygems/commands/search_command.rb4
-rw-r--r--lib/rubygems/commands/setup_command.rb75
-rw-r--r--lib/rubygems/commands/sources_command.rb28
-rw-r--r--lib/rubygems/commands/specification_command.rb26
-rw-r--r--lib/rubygems/commands/stale_command.rb4
-rw-r--r--lib/rubygems/commands/uninstall_command.rb34
-rw-r--r--lib/rubygems/commands/unpack_command.rb24
-rw-r--r--lib/rubygems/commands/update_command.rb55
-rw-r--r--lib/rubygems/commands/which_command.rb2
-rw-r--r--lib/rubygems/commands/yank_command.rb4
-rw-r--r--lib/rubygems/compatibility.rb11
-rw-r--r--lib/rubygems/config_file.rb115
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb6
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb80
-rw-r--r--lib/rubygems/core_ext/kernel_warn.rb9
-rw-r--r--lib/rubygems/core_ext/tcpsocket_init.rb2
-rw-r--r--lib/rubygems/defaults.rb36
-rw-r--r--lib/rubygems/dependency.rb44
-rw-r--r--lib/rubygems/dependency_installer.rb81
-rw-r--r--lib/rubygems/dependency_list.rb4
-rw-r--r--lib/rubygems/deprecate.rb162
-rw-r--r--lib/rubygems/doctor.rb14
-rw-r--r--lib/rubygems/errors.rb10
-rw-r--r--lib/rubygems/exceptions.rb5
-rw-r--r--lib/rubygems/ext/builder.rb34
-rw-r--r--lib/rubygems/ext/cargo_builder.rb31
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb6
-rw-r--r--lib/rubygems/ext/rake_builder.rb2
-rw-r--r--lib/rubygems/gem_runner.rb14
-rw-r--r--lib/rubygems/gemcutter_utilities.rb92
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_listener.rb2
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb6
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_poller.rb10
-rw-r--r--lib/rubygems/gemspec_helpers.rb19
-rw-r--r--lib/rubygems/indexer.rb428
-rw-r--r--lib/rubygems/install_update_options.rb39
-rw-r--r--lib/rubygems/installer.rb143
-rw-r--r--lib/rubygems/installer_uninstaller_utils.rb2
-rw-r--r--lib/rubygems/local_remote_options.rb31
-rw-r--r--lib/rubygems/mock_gem_ui.rb86
-rw-r--r--lib/rubygems/name_tuple.rb16
-rw-r--r--lib/rubygems/optparse.rb3
-rw-r--r--lib/rubygems/optparse/.document (renamed from lib/bundler/vendor/connection_pool/.document)0
-rw-r--r--lib/rubygems/optparse/lib/optionparser.rb (renamed from lib/rubygems/vendor/optparse/lib/optionparser.rb)0
-rw-r--r--lib/rubygems/optparse/lib/optparse.rb2308
-rw-r--r--lib/rubygems/optparse/lib/optparse/ac.rb (renamed from lib/rubygems/vendor/optparse/lib/optparse/ac.rb)0
-rw-r--r--lib/rubygems/optparse/lib/optparse/date.rb (renamed from lib/rubygems/vendor/optparse/lib/optparse/date.rb)0
-rw-r--r--lib/rubygems/optparse/lib/optparse/kwargs.rb (renamed from lib/rubygems/vendor/optparse/lib/optparse/kwargs.rb)0
-rw-r--r--lib/rubygems/optparse/lib/optparse/shellwords.rb (renamed from lib/rubygems/vendor/optparse/lib/optparse/shellwords.rb)0
-rw-r--r--lib/rubygems/optparse/lib/optparse/time.rb (renamed from lib/rubygems/vendor/optparse/lib/optparse/time.rb)0
-rw-r--r--lib/rubygems/optparse/lib/optparse/uri.rb7
-rw-r--r--lib/rubygems/optparse/lib/optparse/version.rb (renamed from lib/rubygems/vendor/optparse/lib/optparse/version.rb)0
-rw-r--r--lib/rubygems/package.rb112
-rw-r--r--lib/rubygems/package/digest_io.rb2
-rw-r--r--lib/rubygems/package/old.rb4
-rw-r--r--lib/rubygems/package/tar_header.rb104
-rw-r--r--lib/rubygems/package/tar_reader.rb24
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb47
-rw-r--r--lib/rubygems/package/tar_writer.rb40
-rw-r--r--lib/rubygems/package_task.rb4
-rw-r--r--lib/rubygems/path_support.rb21
-rw-r--r--lib/rubygems/platform.rb118
-rw-r--r--lib/rubygems/query_utils.rb26
-rw-r--r--lib/rubygems/remote_fetcher.rb50
-rw-r--r--lib/rubygems/request.rb53
-rw-r--r--lib/rubygems/request/connection_pools.rb6
-rw-r--r--lib/rubygems/request_set.rb15
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb245
-rw-r--r--lib/rubygems/request_set/lockfile.rb17
-rw-r--r--lib/rubygems/request_set/lockfile/parser.rb18
-rw-r--r--lib/rubygems/request_set/lockfile/tokenizer.rb32
-rw-r--r--lib/rubygems/requirement.rb21
-rw-r--r--lib/rubygems/resolver.rb27
-rw-r--r--lib/rubygems/resolver/activation_request.rb10
-rw-r--r--lib/rubygems/resolver/api_set.rb5
-rw-r--r--lib/rubygems/resolver/api_set/gem_parser.rb10
-rw-r--r--lib/rubygems/resolver/api_specification.rb2
-rw-r--r--lib/rubygems/resolver/best_set.rb4
-rw-r--r--lib/rubygems/resolver/composed_set.rb2
-rw-r--r--lib/rubygems/resolver/conflict.rb16
-rw-r--r--lib/rubygems/resolver/index_set.rb8
-rw-r--r--lib/rubygems/resolver/index_specification.rb4
-rw-r--r--lib/rubygems/resolver/installed_specification.rb2
-rw-r--r--lib/rubygems/resolver/installer_set.rb11
-rw-r--r--lib/rubygems/resolver/local_specification.rb2
-rw-r--r--lib/rubygems/resolver/lock_set.rb2
-rw-r--r--lib/rubygems/resolver/molinillo.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo.rb11
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb57
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb88
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb255
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb36
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb66
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb62
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb63
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb61
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb126
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb46
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb36
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb164
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb149
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb6
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb112
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb67
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb839
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb46
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/state.rb58
-rw-r--r--lib/rubygems/resolver/spec_specification.rb7
-rw-r--r--lib/rubygems/s3_uri_signer.rb18
-rw-r--r--lib/rubygems/safe_marshal.rb74
-rw-r--r--lib/rubygems/safe_marshal/elements.rb146
-rw-r--r--lib/rubygems/safe_marshal/reader.rb308
-rw-r--r--lib/rubygems/safe_marshal/visitors/stream_printer.rb31
-rw-r--r--lib/rubygems/safe_marshal/visitors/to_ruby.rb415
-rw-r--r--lib/rubygems/safe_marshal/visitors/visitor.rb74
-rw-r--r--lib/rubygems/safe_yaml.rb38
-rw-r--r--lib/rubygems/security.rb36
-rw-r--r--lib/rubygems/security/policies.rb74
-rw-r--r--lib/rubygems/security/policy.rb18
-rw-r--r--lib/rubygems/security/signer.rb14
-rw-r--r--lib/rubygems/security/trust_dir.rb20
-rw-r--r--lib/rubygems/security_option.rb2
-rw-r--r--lib/rubygems/source.rb32
-rw-r--r--lib/rubygems/source/git.rb8
-rw-r--r--lib/rubygems/source/installed.rb2
-rw-r--r--lib/rubygems/source/local.rb83
-rw-r--r--lib/rubygems/source/lock.rb4
-rw-r--r--lib/rubygems/source/specific_file.rb1
-rw-r--r--lib/rubygems/source/vendor.rb2
-rw-r--r--lib/rubygems/source_list.rb16
-rw-r--r--lib/rubygems/spec_fetcher.rb86
-rw-r--r--lib/rubygems/specification.rb518
-rw-r--r--lib/rubygems/specification_policy.rb165
-rw-r--r--lib/rubygems/specification_record.rb213
-rw-r--r--lib/rubygems/stub_specification.rb32
-rw-r--r--lib/rubygems/text.rb3
-rw-r--r--lib/rubygems/tsort.rb3
-rw-r--r--lib/rubygems/tsort/.document (renamed from lib/bundler/vendor/fileutils/.document)0
-rw-r--r--lib/rubygems/tsort/lib/tsort.rb452
-rw-r--r--lib/rubygems/uninstaller.rb46
-rw-r--r--lib/rubygems/update_suggestion.rb25
-rw-r--r--lib/rubygems/uri.rb12
-rw-r--r--lib/rubygems/uri_formatter.rb2
-rw-r--r--lib/rubygems/user_interaction.rb44
-rw-r--r--lib/rubygems/util.rb14
-rw-r--r--lib/rubygems/util/licenses.rb331
-rw-r--r--lib/rubygems/util/list.rb4
-rw-r--r--lib/rubygems/validator.rb20
-rw-r--r--lib/rubygems/vendor/molinillo/.document1
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo.rb11
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb57
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb88
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph.rb255
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/action.rb36
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb66
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb62
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb63
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb61
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/log.rb126
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb46
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb36
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb164
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/errors.rb149
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb6
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/modules/specification_provider.rb112
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/modules/ui.rb67
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/resolution.rb839
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/resolver.rb46
-rw-r--r--lib/rubygems/vendor/molinillo/lib/molinillo/state.rb58
-rw-r--r--lib/rubygems/vendor/net-http/.document1
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http.rb2496
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/backward.rb40
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb34
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb414
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/header.rb981
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb17
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/request.rb88
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/requests.rb425
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/response.rb738
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/responses.rb1174
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/status.rb84
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/https.rb23
-rw-r--r--lib/rubygems/vendor/net-protocol/.document1
-rw-r--r--lib/rubygems/vendor/net-protocol/lib/net/protocol.rb544
-rw-r--r--lib/rubygems/vendor/optparse/.document1
-rw-r--r--lib/rubygems/vendor/optparse/lib/optparse.rb2330
-rw-r--r--lib/rubygems/vendor/optparse/lib/optparse/uri.rb7
-rw-r--r--lib/rubygems/vendor/resolv/.document1
-rw-r--r--lib/rubygems/vendor/resolv/lib/resolv.rb3387
-rw-r--r--lib/rubygems/vendor/timeout/.document1
-rw-r--r--lib/rubygems/vendor/timeout/lib/timeout.rb199
-rw-r--r--lib/rubygems/vendor/tsort/.document1
-rw-r--r--lib/rubygems/vendor/tsort/lib/tsort.rb455
-rw-r--r--lib/rubygems/vendor/uri/.document1
-rw-r--r--lib/rubygems/vendor/uri/lib/uri.rb104
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/common.rb853
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/file.rb100
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/ftp.rb267
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/generic.rb1588
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/http.rb125
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/https.rb23
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/ldap.rb261
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/ldaps.rb22
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/mailto.rb293
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb539
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb183
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/version.rb6
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/ws.rb83
-rw-r--r--lib/rubygems/vendor/uri/lib/uri/wss.rb23
-rw-r--r--lib/rubygems/vendored_molinillo.rb3
-rw-r--r--lib/rubygems/vendored_net_http.rb5
-rw-r--r--lib/rubygems/vendored_optparse.rb3
-rw-r--r--lib/rubygems/vendored_timeout.rb5
-rw-r--r--lib/rubygems/vendored_tsort.rb3
-rw-r--r--lib/rubygems/version.rb69
-rw-r--r--lib/rubygems/version_option.rb7
-rw-r--r--lib/rubygems/yaml_serializer.rb105
-rw-r--r--lib/securerandom.gemspec11
-rw-r--r--lib/securerandom.rb25
-rw-r--r--lib/set.rb66
-rw-r--r--lib/set/set.gemspec13
-rw-r--r--lib/shellwords.gemspec12
-rw-r--r--lib/shellwords.rb2
-rw-r--r--lib/singleton.gemspec30
-rw-r--r--lib/singleton.rb9
-rw-r--r--lib/singleton/singleton.gemspec30
-rw-r--r--lib/syntax_suggest/api.rb47
-rw-r--r--lib/syntax_suggest/clean_document.rb12
-rw-r--r--lib/syntax_suggest/code_block.rb2
-rw-r--r--lib/syntax_suggest/code_frontier.rb2
-rw-r--r--lib/syntax_suggest/code_line.rb17
-rw-r--r--lib/syntax_suggest/code_search.rb4
-rw-r--r--lib/syntax_suggest/core_ext.rb2
-rw-r--r--lib/syntax_suggest/display_invalid_blocks.rb2
-rw-r--r--lib/syntax_suggest/explain_syntax.rb22
-rw-r--r--lib/syntax_suggest/lex_all.rb39
-rw-r--r--lib/syntax_suggest/pathname_from_message.rb2
-rw-r--r--lib/syntax_suggest/ripper_errors.rb5
-rw-r--r--lib/syntax_suggest/scan_history.rb2
-rw-r--r--lib/syntax_suggest/syntax_suggest.gemspec2
-rw-r--r--lib/syntax_suggest/version.rb2
-rw-r--r--lib/tempfile.gemspec13
-rw-r--r--lib/tempfile.rb78
-rw-r--r--lib/time.gemspec13
-rw-r--r--lib/time.rb3
-rw-r--r--lib/timeout.gemspec32
-rw-r--r--lib/timeout.rb38
-rw-r--r--lib/timeout/timeout.gemspec30
-rw-r--r--lib/tmpdir.gemspec4
-rw-r--r--lib/tmpdir.rb16
-rw-r--r--lib/tsort.gemspec11
-rw-r--r--lib/tsort.rb3
-rw-r--r--lib/un.gemspec11
-rw-r--r--lib/un.rb4
-rw-r--r--lib/uri/common.rb390
-rw-r--r--lib/uri/generic.rb16
-rw-r--r--lib/uri/rfc3986_parser.rb126
-rw-r--r--lib/uri/uri.gemspec18
-rw-r--r--lib/uri/version.rb2
-rw-r--r--lib/weakref.gemspec34
-rw-r--r--lib/weakref.rb2
-rw-r--r--lib/weakref/weakref.gemspec34
-rw-r--r--lib/yaml.rb1
-rw-r--r--lib/yaml/store.rb2
-rw-r--r--lib/yaml/yaml.gemspec13
-rwxr-xr-xlibexec/bundle11
-rwxr-xr-xlibexec/irb2
-rwxr-xr-xlibexec/racc320
-rw-r--r--load.c184
-rw-r--r--main.c9
-rw-r--r--man/irb.17
-rw-r--r--man/ruby.178
-rw-r--r--marshal.c86
-rw-r--r--math.c82
-rw-r--r--method.h5
-rw-r--r--mini_builtin.c23
-rw-r--r--miniinit.c7
-rw-r--r--misc/.vscode/launch.json13
-rw-r--r--misc/.vscode/settings.json8
-rw-r--r--misc/.vscode/tasks.json14
-rw-r--r--misc/README1
-rw-r--r--misc/call_fuzzer.rb372
-rwxr-xr-xmisc/call_fuzzer.sh13
-rw-r--r--misc/gdb.py181
-rwxr-xr-xmisc/lldb_cruby.py63
-rw-r--r--misc/lldb_rb/commands/heap_page_command.py4
-rw-r--r--misc/lldb_rb/commands/print_flags_command.py31
-rw-r--r--misc/lldb_rb/commands/rb_id2str_command.py49
-rw-r--r--misc/lldb_rb/commands/rp_command.py15
-rw-r--r--misc/lldb_rb/constants.py2
-rw-r--r--misc/lldb_rb/lldb_interface.py7
-rw-r--r--misc/lldb_rb/rb_base_command.py24
-rw-r--r--misc/lldb_rb/rb_heap_structs.py143
-rw-r--r--misc/lldb_rb/utils.py490
-rw-r--r--missing/dtoa.c11
-rw-r--r--missing/explicit_bzero.c5
-rw-r--r--missing/procstat_vm.c34
-rw-r--r--missing/setproctitle.c1
-rw-r--r--mjit.c1999
-rw-r--r--mjit.h145
-rw-r--r--mjit.rb37
-rw-r--r--mjit_c.c43
-rw-r--r--mjit_c.h97
-rw-r--r--mjit_c.rb807
-rw-r--r--node.c1412
-rw-r--r--node.h544
-rw-r--r--node_dump.c1123
-rw-r--r--numeric.c268
-rw-r--r--numeric.rb359
-rw-r--r--object.c492
-rw-r--r--pack.c8
-rw-r--r--parse.y18608
-rw-r--r--parser_bits.h564
-rw-r--r--parser_node.h32
-rw-r--r--parser_st.c164
-rw-r--r--parser_st.h162
-rw-r--r--parser_value.h106
-rw-r--r--prelude.rb2
-rw-r--r--prism/api_pack.c267
-rw-r--r--prism/config.yml2704
-rw-r--r--prism/defines.h94
-rw-r--r--prism/diagnostic.c355
-rw-r--r--prism/diagnostic.h297
-rw-r--r--prism/encoding.c5137
-rw-r--r--prism/encoding.h248
-rw-r--r--prism/extension.c1055
-rw-r--r--prism/extension.h18
-rw-r--r--prism/node.h57
-rw-r--r--prism/options.c189
-rw-r--r--prism/options.h204
-rw-r--r--prism/pack.c493
-rw-r--r--prism/pack.h152
-rw-r--r--prism/parser.h716
-rw-r--r--prism/prettyprint.h26
-rw-r--r--prism/prism.c17486
-rw-r--r--prism/prism.h272
-rw-r--r--prism/regexp.c638
-rw-r--r--prism/regexp.h33
-rw-r--r--prism/templates/ext/prism/api_node.c.erb221
-rw-r--r--prism/templates/include/prism/ast.h.erb206
-rw-r--r--prism/templates/lib/prism/compiler.rb.erb41
-rw-r--r--prism/templates/lib/prism/dispatcher.rb.erb89
-rw-r--r--prism/templates/lib/prism/dot_visitor.rb.erb186
-rw-r--r--prism/templates/lib/prism/dsl.rb.erb45
-rw-r--r--prism/templates/lib/prism/mutation_compiler.rb.erb19
-rw-r--r--prism/templates/lib/prism/node.rb.erb254
-rw-r--r--prism/templates/lib/prism/serialize.rb.erb310
-rw-r--r--prism/templates/lib/prism/visitor.rb.erb50
-rw-r--r--prism/templates/src/node.c.erb162
-rw-r--r--prism/templates/src/prettyprint.c.erb189
-rw-r--r--prism/templates/src/serialize.c.erb380
-rw-r--r--prism/templates/src/token_type.c.erb20
-rwxr-xr-xprism/templates/template.rb472
-rw-r--r--prism/util/pm_buffer.c179
-rw-r--r--prism/util/pm_buffer.h146
-rw-r--r--prism/util/pm_char.c318
-rw-r--r--prism/util/pm_char.h205
-rw-r--r--prism/util/pm_constant_pool.c296
-rw-r--r--prism/util/pm_constant_pool.h191
-rw-r--r--prism/util/pm_list.c49
-rw-r--r--prism/util/pm_list.h97
-rw-r--r--prism/util/pm_memchr.c35
-rw-r--r--prism/util/pm_memchr.h29
-rw-r--r--prism/util/pm_newline_list.c96
-rw-r--r--prism/util/pm_newline_list.h104
-rw-r--r--prism/util/pm_state_stack.c25
-rw-r--r--prism/util/pm_state_stack.h42
-rw-r--r--prism/util/pm_string.c210
-rw-r--r--prism/util/pm_string.h150
-rw-r--r--prism/util/pm_string_list.c28
-rw-r--r--prism/util/pm_string_list.h44
-rw-r--r--prism/util/pm_strncasecmp.c24
-rw-r--r--prism/util/pm_strncasecmp.h32
-rw-r--r--prism/util/pm_strpbrk.c72
-rw-r--r--prism/util/pm_strpbrk.h43
-rw-r--r--prism/version.h29
-rw-r--r--prism_compile.c6532
-rw-r--r--prism_compile.h29
-rw-r--r--prism_init.c9
-rw-r--r--probes_helper.h2
-rw-r--r--proc.c341
-rw-r--r--process.c3066
-rw-r--r--ractor.c2021
-rw-r--r--ractor.rb255
-rw-r--r--ractor_core.h95
-rw-r--r--random.c6
-rw-r--r--range.c430
-rw-r--r--rational.c21
-rw-r--r--re.c608
-rw-r--r--regcomp.c118
-rw-r--r--regenc.c2
-rw-r--r--regenc.h5
-rw-r--r--regexec.c1044
-rw-r--r--regint.h69
-rw-r--r--regparse.c178
-rw-r--r--regparse.h3
-rw-r--r--rjit.c501
-rw-r--r--rjit.h101
-rw-r--r--rjit.rb41
-rw-r--r--rjit_c.c542
-rw-r--r--rjit_c.h164
-rw-r--r--rjit_c.rb1695
-rw-r--r--ruby-runner.c35
-rw-r--r--ruby.c1078
-rw-r--r--ruby_parser.c913
-rw-r--r--rubyparser.h1405
-rw-r--r--sample/all-ruby-quine.rb24
-rw-r--r--sample/dir.rb11
-rw-r--r--scheduler.c86
-rw-r--r--shape.c947
-rw-r--r--shape.h141
-rw-r--r--signal.c181
-rw-r--r--siphash.c3
-rw-r--r--spec/README.md8
-rw-r--r--spec/bundler/bundler/bundler_spec.rb32
-rw-r--r--spec/bundler/bundler/ci_detector_spec.rb21
-rw-r--r--spec/bundler/bundler/cli_spec.rb32
-rw-r--r--spec/bundler/bundler/compact_index_client/updater_spec.rb205
-rw-r--r--spec/bundler/bundler/definition_spec.rb79
-rw-r--r--spec/bundler/bundler/dependency_spec.rb226
-rw-r--r--spec/bundler/bundler/digest_spec.rb6
-rw-r--r--spec/bundler/bundler/dsl_spec.rb108
-rw-r--r--spec/bundler/bundler/endpoint_specification_spec.rb6
-rw-r--r--spec/bundler/bundler/env_spec.rb16
-rw-r--r--spec/bundler/bundler/environment_preserver_spec.rb16
-rw-r--r--spec/bundler/bundler/fetcher/base_spec.rb11
-rw-r--r--spec/bundler/bundler/fetcher/compact_index_spec.rb9
-rw-r--r--spec/bundler/bundler/fetcher/dependency_spec.rb25
-rw-r--r--spec/bundler/bundler/fetcher/downloader_spec.rb66
-rw-r--r--spec/bundler/bundler/fetcher/index_spec.rb7
-rw-r--r--spec/bundler/bundler/fetcher_spec.rb98
-rw-r--r--spec/bundler/bundler/friendly_errors_spec.rb6
-rw-r--r--spec/bundler/bundler/gem_helper_spec.rb40
-rw-r--r--spec/bundler/bundler/gem_version_promoter_spec.rb56
-rw-r--r--spec/bundler/bundler/installer/gem_installer_spec.rb12
-rw-r--r--spec/bundler/bundler/installer/parallel_installer_spec.rb46
-rw-r--r--spec/bundler/bundler/installer/spec_installation_spec.rb18
-rw-r--r--spec/bundler/bundler/lockfile_parser_spec.rb78
-rw-r--r--spec/bundler/bundler/mirror_spec.rb16
-rw-r--r--spec/bundler/bundler/plugin/api/source_spec.rb4
-rw-r--r--spec/bundler/bundler/plugin/dsl_spec.rb6
-rw-r--r--spec/bundler/bundler/plugin/installer_spec.rb21
-rw-r--r--spec/bundler/bundler/plugin_spec.rb10
-rw-r--r--spec/bundler/bundler/remote_specification_spec.rb12
-rw-r--r--spec/bundler/bundler/resolver/candidate_spec.rb6
-rw-r--r--spec/bundler/bundler/ruby_dsl_spec.rb108
-rw-r--r--spec/bundler/bundler/rubygems_integration_spec.rb29
-rw-r--r--spec/bundler/bundler/settings/validator_spec.rb6
-rw-r--r--spec/bundler/bundler/settings_spec.rb25
-rw-r--r--spec/bundler/bundler/shared_helpers_spec.rb77
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb122
-rw-r--r--spec/bundler/bundler/source/git_spec.rb4
-rw-r--r--spec/bundler/bundler/source/rubygems/remote_spec.rb20
-rw-r--r--spec/bundler/bundler/source_list_spec.rb6
-rw-r--r--spec/bundler/bundler/source_spec.rb20
-rw-r--r--spec/bundler/bundler/spec_set_spec.rb18
-rw-r--r--spec/bundler/bundler/specifications/foo.gemspec13
-rw-r--r--spec/bundler/bundler/stub_specification_spec.rb11
-rw-r--r--spec/bundler/bundler/uri_credentials_filter_spec.rb10
-rw-r--r--spec/bundler/bundler/yaml_serializer_spec.rb57
-rw-r--r--spec/bundler/cache/gems_spec.rb77
-rw-r--r--spec/bundler/cache/git_spec.rb12
-rw-r--r--spec/bundler/cache/path_spec.rb10
-rw-r--r--spec/bundler/cache/platform_spec.rb2
-rw-r--r--spec/bundler/commands/add_spec.rb95
-rw-r--r--spec/bundler/commands/binstubs_spec.rb50
-rw-r--r--spec/bundler/commands/cache_spec.rb80
-rw-r--r--spec/bundler/commands/check_spec.rb62
-rw-r--r--spec/bundler/commands/clean_spec.rb46
-rw-r--r--spec/bundler/commands/config_spec.rb34
-rw-r--r--spec/bundler/commands/console_spec.rb2
-rw-r--r--spec/bundler/commands/doctor_spec.rb7
-rw-r--r--spec/bundler/commands/exec_spec.rb96
-rw-r--r--spec/bundler/commands/help_spec.rb9
-rw-r--r--spec/bundler/commands/info_spec.rb22
-rw-r--r--spec/bundler/commands/init_spec.rb26
-rw-r--r--spec/bundler/commands/inject_spec.rb8
-rw-r--r--spec/bundler/commands/install_spec.rb445
-rw-r--r--spec/bundler/commands/list_spec.rb12
-rw-r--r--spec/bundler/commands/lock_spec.rb572
-rw-r--r--spec/bundler/commands/newgem_spec.rb235
-rw-r--r--spec/bundler/commands/open_spec.rb54
-rw-r--r--spec/bundler/commands/outdated_spec.rb176
-rw-r--r--spec/bundler/commands/platform_spec.rb132
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb14
-rw-r--r--spec/bundler/commands/pristine_spec.rb20
-rw-r--r--spec/bundler/commands/remove_spec.rb22
-rw-r--r--spec/bundler/commands/show_spec.rb20
-rw-r--r--spec/bundler/commands/update_spec.rb439
-rw-r--r--spec/bundler/commands/version_spec.rb16
-rw-r--r--spec/bundler/commands/viz_spec.rb16
-rw-r--r--spec/bundler/install/allow_offline_install_spec.rb18
-rw-r--r--spec/bundler/install/bundler_spec.rb20
-rw-r--r--spec/bundler/install/deploy_spec.rb136
-rw-r--r--spec/bundler/install/failure_spec.rb4
-rw-r--r--spec/bundler/install/gemfile/eval_gemfile_spec.rb8
-rw-r--r--spec/bundler/install/gemfile/force_ruby_platform_spec.rb32
-rw-r--r--spec/bundler/install/gemfile/gemspec_spec.rb165
-rw-r--r--spec/bundler/install/gemfile/git_spec.rb183
-rw-r--r--spec/bundler/install/gemfile/groups_spec.rb42
-rw-r--r--spec/bundler/install/gemfile/install_if_spec.rb9
-rw-r--r--spec/bundler/install/gemfile/lockfile_spec.rb5
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb202
-rw-r--r--spec/bundler/install/gemfile/platform_spec.rb41
-rw-r--r--spec/bundler/install/gemfile/ruby_spec.rb36
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb522
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb548
-rw-r--r--spec/bundler/install/gemfile_spec.rb10
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb372
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb136
-rw-r--r--spec/bundler/install/gems/flex_spec.rb27
-rw-r--r--spec/bundler/install/gems/native_extensions_spec.rb8
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb130
-rw-r--r--spec/bundler/install/gems/standalone_spec.rb77
-rw-r--r--spec/bundler/install/gemspecs_spec.rb30
-rw-r--r--spec/bundler/install/git_spec.rb71
-rw-r--r--spec/bundler/install/global_cache_spec.rb40
-rw-r--r--spec/bundler/install/path_spec.rb36
-rw-r--r--spec/bundler/install/redownload_spec.rb2
-rw-r--r--spec/bundler/install/security_policy_spec.rb12
-rw-r--r--spec/bundler/install/yanked_spec.rb14
-rw-r--r--spec/bundler/lock/git_spec.rb6
-rw-r--r--spec/bundler/lock/lockfile_spec.rb334
-rw-r--r--spec/bundler/other/cli_dispatch_spec.rb6
-rw-r--r--spec/bundler/other/ext_spec.rb24
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb200
-rw-r--r--spec/bundler/plugins/command_spec.rb2
-rw-r--r--spec/bundler/plugins/install_spec.rb91
-rw-r--r--spec/bundler/plugins/source/example_spec.rb14
-rw-r--r--spec/bundler/plugins/uninstall_spec.rb25
-rw-r--r--spec/bundler/quality_spec.rb17
-rw-r--r--spec/bundler/realworld/dependency_api_spec.rb16
-rw-r--r--spec/bundler/realworld/double_check_spec.rb6
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb155
-rw-r--r--spec/bundler/realworld/ffi_spec.rb2
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile2
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile.lock2
-rw-r--r--spec/bundler/realworld/gemfile_source_header_spec.rb18
-rw-r--r--spec/bundler/realworld/git_spec.rb2
-rw-r--r--spec/bundler/realworld/mirror_probe_spec.rb22
-rw-r--r--spec/bundler/realworld/parallel_spec.rb8
-rw-r--r--spec/bundler/realworld/slow_perf_spec.rb117
-rw-r--r--spec/bundler/resolver/basic_spec.rb34
-rw-r--r--spec/bundler/resolver/platform_spec.rb2
-rw-r--r--spec/bundler/runtime/executable_spec.rb22
-rw-r--r--spec/bundler/runtime/gem_tasks_spec.rb10
-rw-r--r--spec/bundler/runtime/inline_spec.rb99
-rw-r--r--spec/bundler/runtime/load_spec.rb2
-rw-r--r--spec/bundler/runtime/platform_spec.rb33
-rw-r--r--spec/bundler/runtime/require_spec.rb36
-rw-r--r--spec/bundler/runtime/requiring_spec.rb15
-rw-r--r--spec/bundler/runtime/self_management_spec.rb51
-rw-r--r--spec/bundler/runtime/setup_spec.rb206
-rw-r--r--spec/bundler/runtime/with_unbundled_env_spec.rb22
-rw-r--r--spec/bundler/spec_helper.rb10
-rw-r--r--spec/bundler/support/activate.rb9
-rw-r--r--spec/bundler/support/artifice/compact_index_checksum_mismatch.rb4
-rw-r--r--spec/bundler/support/artifice/compact_index_concurrent_download.rb7
-rw-r--r--spec/bundler/support/artifice/compact_index_etag_match.rb16
-rw-r--r--spec/bundler/support/artifice/compact_index_host_redirect.rb2
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update.rb2
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update_bad_digest.rb40
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update_no_digest_not_incremental.rb42
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb40
-rw-r--r--spec/bundler/support/artifice/compact_index_range_ignored.rb40
-rw-r--r--spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb3
-rw-r--r--spec/bundler/support/artifice/endpoint_500.rb2
-rw-r--r--spec/bundler/support/artifice/endpoint_host_redirect.rb2
-rw-r--r--spec/bundler/support/artifice/endpoint_mirror_source.rb2
-rw-r--r--spec/bundler/support/artifice/fail.rb14
-rw-r--r--spec/bundler/support/artifice/helpers/artifice.rb6
-rw-r--r--spec/bundler/support/artifice/helpers/compact_index.rb27
-rw-r--r--spec/bundler/support/artifice/helpers/endpoint.rb10
-rw-r--r--spec/bundler/support/artifice/helpers/rack_request.rb24
-rw-r--r--spec/bundler/support/artifice/used_cassettes.txt20908
-rw-r--r--spec/bundler/support/artifice/vcr.rb14
-rw-r--r--spec/bundler/support/artifice/windows.rb2
-rw-r--r--spec/bundler/support/build_metadata.rb14
-rw-r--r--spec/bundler/support/builders.rb105
-rw-r--r--spec/bundler/support/bundle.rb7
-rw-r--r--spec/bundler/support/checksums.rb114
-rw-r--r--spec/bundler/support/command_execution.rb15
-rw-r--r--spec/bundler/support/filters.rb22
-rw-r--r--spec/bundler/support/helpers.rb130
-rw-r--r--spec/bundler/support/indexes.rb16
-rw-r--r--spec/bundler/support/matchers.rb12
-rw-r--r--spec/bundler/support/path.rb26
-rw-r--r--spec/bundler/support/platforms.rb11
-rw-r--r--spec/bundler/support/rubygems_ext.rb11
-rw-r--r--spec/bundler/support/rubygems_version_manager.rb9
-rw-r--r--spec/bundler/update/gemfile_spec.rb10
-rw-r--r--spec/bundler/update/gems/fund_spec.rb2
-rw-r--r--spec/bundler/update/gems/post_install_spec.rb4
-rw-r--r--spec/bundler/update/git_spec.rb71
-rw-r--r--spec/bundler/update/path_spec.rb4
-rw-r--r--spec/bundler/update/redownload_spec.rb14
-rw-r--r--spec/default.mspec74
-rw-r--r--spec/lib/formatter_overrides.rb6
-rw-r--r--spec/lib/spec_coverage.rb1
-rwxr-xr-xspec/mspec/lib/mspec/commands/mspec.rb5
-rw-r--r--spec/mspec/lib/mspec/helpers/io.rb4
-rw-r--r--spec/mspec/lib/mspec/helpers/ruby_exe.rb54
-rw-r--r--spec/mspec/lib/mspec/matchers/complain.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/actions/timeout.rb78
-rw-r--r--spec/mspec/lib/mspec/runner/mspec.rb5
-rw-r--r--spec/mspec/lib/mspec/utils/options.rb2
-rw-r--r--spec/mspec/lib/mspec/utils/warnings.rb43
-rw-r--r--spec/mspec/spec/commands/mspec_spec.rb27
-rw-r--r--spec/mspec/spec/helpers/ruby_exe_spec.rb10
-rw-r--r--spec/mspec/spec/runner/context_spec.rb2
-rwxr-xr-xspec/mspec/tool/check_require_spec_helper.rb34
-rw-r--r--spec/mspec/tool/remove_old_guards.rb51
-rwxr-xr-xspec/mspec/tool/tag_from_output.rb10
-rw-r--r--spec/ruby/.mspec.constants1
-rw-r--r--spec/ruby/.rubocop.yml6
-rw-r--r--spec/ruby/.rubocop_todo.yml1
-rw-r--r--spec/ruby/CONTRIBUTING.md15
-rw-r--r--spec/ruby/README.md11
-rw-r--r--spec/ruby/command_line/backtrace_limit_spec.rb44
-rw-r--r--spec/ruby/command_line/dash_a_spec.rb4
-rw-r--r--spec/ruby/command_line/dash_l_spec.rb8
-rw-r--r--spec/ruby/command_line/dash_n_spec.rb8
-rw-r--r--spec/ruby/command_line/dash_p_spec.rb4
-rw-r--r--spec/ruby/command_line/dash_upper_f_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_u_spec.rb7
-rw-r--r--spec/ruby/command_line/dash_v_spec.rb3
-rw-r--r--spec/ruby/command_line/fixtures/bin/embedded_ruby.txt2
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_required_diff_enc.rbbin90 -> 121 bytes-rw-r--r--spec/ruby/command_line/rubyopt_spec.rb14
-rw-r--r--spec/ruby/core/argf/bytes_spec.rb16
-rw-r--r--spec/ruby/core/argf/chars_spec.rb16
-rw-r--r--spec/ruby/core/argf/codepoints_spec.rb16
-rw-r--r--spec/ruby/core/argf/lines_spec.rb16
-rw-r--r--spec/ruby/core/argf/readpartial_spec.rb2
-rw-r--r--spec/ruby/core/array/all_spec.rb13
-rw-r--r--spec/ruby/core/array/any_spec.rb12
-rw-r--r--spec/ruby/core/array/assoc_spec.rb14
-rw-r--r--spec/ruby/core/array/bsearch_index_spec.rb4
-rw-r--r--spec/ruby/core/array/count_spec.rb11
-rw-r--r--spec/ruby/core/array/delete_if_spec.rb30
-rw-r--r--spec/ruby/core/array/drop_spec.rb12
-rw-r--r--spec/ruby/core/array/drop_while_spec.rb16
-rw-r--r--spec/ruby/core/array/each_index_spec.rb18
-rw-r--r--spec/ruby/core/array/each_spec.rb5
-rw-r--r--spec/ruby/core/array/fill_spec.rb82
-rw-r--r--spec/ruby/core/array/fixtures/classes.rb10
-rw-r--r--spec/ruby/core/array/flatten_spec.rb24
-rw-r--r--spec/ruby/core/array/initialize_spec.rb4
-rw-r--r--spec/ruby/core/array/intersect_spec.rb53
-rw-r--r--spec/ruby/core/array/multiply_spec.rb18
-rw-r--r--spec/ruby/core/array/new_spec.rb4
-rw-r--r--spec/ruby/core/array/none_spec.rb13
-rw-r--r--spec/ruby/core/array/one_spec.rb13
-rw-r--r--spec/ruby/core/array/pack/c_spec.rb4
-rw-r--r--spec/ruby/core/array/pack/shared/basic.rb2
-rw-r--r--spec/ruby/core/array/pack/shared/float.rb16
-rw-r--r--spec/ruby/core/array/pack/shared/integer.rb36
-rw-r--r--spec/ruby/core/array/pack/shared/unicode.rb4
-rw-r--r--spec/ruby/core/array/pack/w_spec.rb4
-rw-r--r--spec/ruby/core/array/plus_spec.rb21
-rw-r--r--spec/ruby/core/array/product_spec.rb5
-rw-r--r--spec/ruby/core/array/rassoc_spec.rb14
-rw-r--r--spec/ruby/core/array/reject_spec.rb15
-rw-r--r--spec/ruby/core/array/reverse_each_spec.rb16
-rw-r--r--spec/ruby/core/array/rindex_spec.rb17
-rw-r--r--spec/ruby/core/array/sample_spec.rb4
-rw-r--r--spec/ruby/core/array/shared/collect.rb32
-rw-r--r--spec/ruby/core/array/shared/index.rb4
-rw-r--r--spec/ruby/core/array/shared/intersection.rb3
-rw-r--r--spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb25
-rw-r--r--spec/ruby/core/array/shared/keep_if.rb35
-rw-r--r--spec/ruby/core/array/shared/select.rb3
-rw-r--r--spec/ruby/core/array/shared/slice.rb400
-rw-r--r--spec/ruby/core/array/shuffle_spec.rb14
-rw-r--r--spec/ruby/core/array/slice_spec.rb60
-rw-r--r--spec/ruby/core/array/sort_by_spec.rb33
-rw-r--r--spec/ruby/core/array/sum_spec.rb21
-rw-r--r--spec/ruby/core/array/take_spec.rb12
-rw-r--r--spec/ruby/core/array/take_while_spec.rb16
-rw-r--r--spec/ruby/core/array/to_h_spec.rb6
-rw-r--r--spec/ruby/core/array/try_convert_spec.rb2
-rw-r--r--spec/ruby/core/array/uniq_spec.rb46
-rw-r--r--spec/ruby/core/basicobject/fixtures/classes.rb228
-rw-r--r--spec/ruby/core/basicobject/instance_eval_spec.rb124
-rw-r--r--spec/ruby/core/basicobject/method_missing_spec.rb1
-rw-r--r--spec/ruby/core/binding/clone_spec.rb6
-rw-r--r--spec/ruby/core/binding/dup_spec.rb6
-rw-r--r--spec/ruby/core/binding/eval_spec.rb99
-rw-r--r--spec/ruby/core/binding/shared/clone.rb22
-rw-r--r--spec/ruby/core/binding/source_location_spec.rb5
-rw-r--r--spec/ruby/core/class/dup_spec.rb3
-rw-r--r--spec/ruby/core/complex/inspect_spec.rb19
-rw-r--r--spec/ruby/core/complex/to_s_spec.rb10
-rw-r--r--spec/ruby/core/data/constants_spec.rb16
-rw-r--r--spec/ruby/core/data/define_spec.rb36
-rw-r--r--spec/ruby/core/data/fixtures/classes.rb5
-rw-r--r--spec/ruby/core/data/initialize_spec.rb58
-rw-r--r--spec/ruby/core/dir/exist_spec.rb8
-rw-r--r--spec/ruby/core/dir/fchdir_spec.rb68
-rw-r--r--spec/ruby/core/dir/glob_spec.rb138
-rw-r--r--spec/ruby/core/dir/home_spec.rb33
-rw-r--r--spec/ruby/core/dir/shared/chroot.rb4
-rw-r--r--spec/ruby/core/dir/shared/exist.rb8
-rw-r--r--spec/ruby/core/dir/shared/glob.rb26
-rw-r--r--spec/ruby/core/encoding/converter/primitive_convert_spec.rb4
-rw-r--r--spec/ruby/core/encoding/default_external_spec.rb8
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb1
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb1
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb1
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb1
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb1
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb1
-rw-r--r--spec/ruby/core/encoding/name_spec.rb1
-rw-r--r--spec/ruby/core/encoding/replicate_spec.rb8
-rw-r--r--spec/ruby/core/encoding/to_s_spec.rb1
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb1
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb1
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb1
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb1
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb1
-rw-r--r--spec/ruby/core/enumerable/all_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/any_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/chunk_spec.rb5
-rw-r--r--spec/ruby/core/enumerable/grep_spec.rb49
-rw-r--r--spec/ruby/core/enumerable/grep_v_spec.rb49
-rw-r--r--spec/ruby/core/enumerable/none_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/one_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/shared/inject.rb44
-rw-r--r--spec/ruby/core/enumerable/sum_spec.rb2
-rw-r--r--spec/ruby/core/enumerable/tally_spec.rb13
-rw-r--r--spec/ruby/core/enumerator/chain/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/chain/inspect_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/each_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/generator/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/initialize_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/inspect_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/compact_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/new_spec.rb47
-rw-r--r--spec/ruby/core/enumerator/product/each_spec.rb73
-rw-r--r--spec/ruby/core/enumerator/product/initialize_copy_spec.rb54
-rw-r--r--spec/ruby/core/enumerator/product/initialize_spec.rb33
-rw-r--r--spec/ruby/core/enumerator/product/inspect_spec.rb22
-rw-r--r--spec/ruby/core/enumerator/product/rewind_spec.rb64
-rw-r--r--spec/ruby/core/enumerator/product/size_spec.rb64
-rw-r--r--spec/ruby/core/enumerator/product_spec.rb93
-rw-r--r--spec/ruby/core/enumerator/rewind_spec.rb4
-rw-r--r--spec/ruby/core/env/clone_spec.rb23
-rw-r--r--spec/ruby/core/env/delete_spec.rb16
-rw-r--r--spec/ruby/core/env/dup_spec.rb11
-rw-r--r--spec/ruby/core/env/except_spec.rb44
-rw-r--r--spec/ruby/core/env/index_spec.rb14
-rw-r--r--spec/ruby/core/env/indexes_spec.rb1
-rw-r--r--spec/ruby/core/env/indices_spec.rb1
-rw-r--r--spec/ruby/core/env/key_spec.rb32
-rw-r--r--spec/ruby/core/env/shared/include.rb7
-rw-r--r--spec/ruby/core/env/shared/key.rb31
-rw-r--r--spec/ruby/core/env/shared/value.rb7
-rw-r--r--spec/ruby/core/env/slice_spec.rb10
-rw-r--r--spec/ruby/core/env/to_a_spec.rb5
-rw-r--r--spec/ruby/core/exception/case_compare_spec.rb2
-rw-r--r--spec/ruby/core/exception/detailed_message_spec.rb43
-rw-r--r--spec/ruby/core/exception/equal_value_spec.rb14
-rw-r--r--spec/ruby/core/exception/fixtures/common.rb4
-rw-r--r--spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb22
-rw-r--r--spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb25
-rw-r--r--spec/ruby/core/exception/full_message_spec.rb92
-rw-r--r--spec/ruby/core/exception/no_method_error_spec.rb79
-rw-r--r--spec/ruby/core/exception/top_level_spec.rb12
-rw-r--r--spec/ruby/core/false/singleton_method_spec.rb15
-rw-r--r--spec/ruby/core/fiber/blocking_spec.rb68
-rw-r--r--spec/ruby/core/fiber/inspect_spec.rb36
-rw-r--r--spec/ruby/core/fiber/kill_spec.rb90
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb56
-rw-r--r--spec/ruby/core/fiber/resume_spec.rb15
-rw-r--r--spec/ruby/core/fiber/storage_spec.rb103
-rw-r--r--spec/ruby/core/file/absolute_path_spec.rb2
-rw-r--r--spec/ruby/core/file/atime_spec.rb2
-rw-r--r--spec/ruby/core/file/ctime_spec.rb2
-rw-r--r--spec/ruby/core/file/dirname_spec.rb39
-rw-r--r--spec/ruby/core/file/exist_spec.rb8
-rw-r--r--spec/ruby/core/file/flock_spec.rb4
-rw-r--r--spec/ruby/core/file/mtime_spec.rb2
-rw-r--r--spec/ruby/core/file/new_spec.rb65
-rw-r--r--spec/ruby/core/file/open_spec.rb17
-rw-r--r--spec/ruby/core/file/realpath_spec.rb4
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb47
-rw-r--r--spec/ruby/core/file/utime_spec.rb26
-rw-r--r--spec/ruby/core/float/magnitude_spec.rb1
-rw-r--r--spec/ruby/core/float/round_spec.rb2
-rw-r--r--spec/ruby/core/gc/auto_compact_spec.rb36
-rw-r--r--spec/ruby/core/hash/compact_spec.rb24
-rw-r--r--spec/ruby/core/hash/constructor_spec.rb18
-rw-r--r--spec/ruby/core/hash/except_spec.rb50
-rw-r--r--spec/ruby/core/hash/fetch_spec.rb2
-rw-r--r--spec/ruby/core/hash/fetch_values_spec.rb2
-rw-r--r--spec/ruby/core/hash/hash_spec.rb2
-rw-r--r--spec/ruby/core/hash/index_spec.rb9
-rw-r--r--spec/ruby/core/hash/new_spec.rb13
-rw-r--r--spec/ruby/core/hash/ruby2_keywords_hash_spec.rb24
-rw-r--r--spec/ruby/core/hash/shared/each.rb37
-rw-r--r--spec/ruby/core/hash/shared/equal.rb90
-rw-r--r--spec/ruby/core/hash/to_a_spec.rb10
-rw-r--r--spec/ruby/core/hash/to_proc_spec.rb16
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb32
-rw-r--r--spec/ruby/core/hash/try_convert_spec.rb2
-rw-r--r--spec/ruby/core/integer/bit_and_spec.rb2
-rw-r--r--spec/ruby/core/integer/bit_or_spec.rb6
-rw-r--r--spec/ruby/core/integer/bit_xor_spec.rb4
-rw-r--r--spec/ruby/core/integer/ceildiv_spec.rb22
-rw-r--r--spec/ruby/core/integer/left_shift_spec.rb32
-rw-r--r--spec/ruby/core/integer/right_shift_spec.rb32
-rw-r--r--spec/ruby/core/integer/shared/arithmetic_coerce.rb20
-rw-r--r--spec/ruby/core/integer/try_convert_spec.rb12
-rw-r--r--spec/ruby/core/integer/zero_spec.rb12
-rw-r--r--spec/ruby/core/io/binread_spec.rb10
-rw-r--r--spec/ruby/core/io/bytes_spec.rb47
-rw-r--r--spec/ruby/core/io/chars_spec.rb30
-rw-r--r--spec/ruby/core/io/codepoints_spec.rb38
-rw-r--r--spec/ruby/core/io/copy_stream_spec.rb33
-rw-r--r--spec/ruby/core/io/eof_spec.rb2
-rw-r--r--spec/ruby/core/io/flush_spec.rb10
-rw-r--r--spec/ruby/core/io/foreach_spec.rb19
-rw-r--r--spec/ruby/core/io/getbyte_spec.rb16
-rw-r--r--spec/ruby/core/io/gets_spec.rb71
-rw-r--r--spec/ruby/core/io/initialize_spec.rb11
-rw-r--r--spec/ruby/core/io/lines_spec.rb46
-rw-r--r--spec/ruby/core/io/new_spec.rb8
-rw-r--r--spec/ruby/core/io/nonblock_spec.rb46
-rw-r--r--spec/ruby/core/io/open_spec.rb13
-rw-r--r--spec/ruby/core/io/pread_spec.rb79
-rw-r--r--spec/ruby/core/io/pwrite_spec.rb32
-rw-r--r--spec/ruby/core/io/read_spec.rb129
-rw-r--r--spec/ruby/core/io/readline_spec.rb12
-rw-r--r--spec/ruby/core/io/readlines_spec.rb39
-rw-r--r--spec/ruby/core/io/select_spec.rb15
-rw-r--r--spec/ruby/core/io/shared/binwrite.rb13
-rw-r--r--spec/ruby/core/io/shared/each.rb20
-rw-r--r--spec/ruby/core/io/shared/new.rb50
-rw-r--r--spec/ruby/core/io/shared/readlines.rb20
-rw-r--r--spec/ruby/core/io/shared/write.rb65
-rw-r--r--spec/ruby/core/io/syswrite_spec.rb1
-rw-r--r--spec/ruby/core/io/try_convert_spec.rb2
-rw-r--r--spec/ruby/core/io/ungetc_spec.rb16
-rw-r--r--spec/ruby/core/io/write_nonblock_spec.rb1
-rw-r--r--spec/ruby/core/io/write_spec.rb159
-rw-r--r--spec/ruby/core/kernel/Complex_spec.rb4
-rw-r--r--spec/ruby/core/kernel/Integer_spec.rb38
-rw-r--r--spec/ruby/core/kernel/__dir___spec.rb16
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb61
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb86
-rw-r--r--spec/ruby/core/kernel/define_singleton_method_spec.rb6
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb48
-rw-r--r--spec/ruby/core/kernel/exec_spec.rb4
-rw-r--r--spec/ruby/core/kernel/exit_spec.rb10
-rw-r--r--spec/ruby/core/kernel/fixtures/at_exit.rb3
-rw-r--r--spec/ruby/core/kernel/initialize_clone_spec.rb10
-rw-r--r--spec/ruby/core/kernel/initialize_copy_spec.rb9
-rw-r--r--spec/ruby/core/kernel/iterator_spec.rb14
-rw-r--r--spec/ruby/core/kernel/lambda_spec.rb74
-rw-r--r--spec/ruby/core/kernel/method_spec.rb21
-rw-r--r--spec/ruby/core/kernel/open_spec.rb87
-rw-r--r--spec/ruby/core/kernel/printf_spec.rb7
-rw-r--r--spec/ruby/core/kernel/proc_spec.rb18
-rw-r--r--spec/ruby/core/kernel/require_relative_spec.rb8
-rw-r--r--spec/ruby/core/kernel/require_spec.rb20
-rw-r--r--spec/ruby/core/kernel/shared/load.rb38
-rw-r--r--spec/ruby/core/kernel/shared/require.rb82
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb4
-rw-r--r--spec/ruby/core/kernel/singleton_class_spec.rb49
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb28
-rw-r--r--spec/ruby/core/kernel/sprintf_spec.rb16
-rw-r--r--spec/ruby/core/kernel/taint_spec.rb16
-rw-r--r--spec/ruby/core/kernel/tainted_spec.rb20
-rw-r--r--spec/ruby/core/kernel/test_spec.rb4
-rw-r--r--spec/ruby/core/kernel/trust_spec.rb18
-rw-r--r--spec/ruby/core/kernel/untaint_spec.rb18
-rw-r--r--spec/ruby/core/kernel/untrust_spec.rb16
-rw-r--r--spec/ruby/core/kernel/untrusted_spec.rb18
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb141
-rw-r--r--spec/ruby/core/main/private_spec.rb12
-rw-r--r--spec/ruby/core/main/public_spec.rb12
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb222
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_data.rb96
-rw-r--r--spec/ruby/core/marshal/shared/load.rb289
-rw-r--r--spec/ruby/core/matchdata/byteoffset_spec.rb95
-rw-r--r--spec/ruby/core/matchdata/captures_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/deconstruct_keys_spec.rb65
-rw-r--r--spec/ruby/core/matchdata/deconstruct_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/element_reference_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/named_captures_spec.rb12
-rw-r--r--spec/ruby/core/matchdata/post_match_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/pre_match_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/shared/captures.rb13
-rw-r--r--spec/ruby/core/matchdata/to_a_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/to_s_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb4
-rw-r--r--spec/ruby/core/math/cos_spec.rb26
-rw-r--r--spec/ruby/core/method/clone_spec.rb15
-rw-r--r--spec/ruby/core/method/compose_spec.rb3
-rw-r--r--spec/ruby/core/method/dup_spec.rb15
-rw-r--r--spec/ruby/core/method/parameters_spec.rb47
-rw-r--r--spec/ruby/core/method/private_spec.rb11
-rw-r--r--spec/ruby/core/method/protected_spec.rb11
-rw-r--r--spec/ruby/core/method/public_spec.rb11
-rw-r--r--spec/ruby/core/method/shared/dup.rb32
-rw-r--r--spec/ruby/core/method/shared/to_s.rb30
-rw-r--r--spec/ruby/core/method/source_location_spec.rb9
-rw-r--r--spec/ruby/core/method/super_method_spec.rb10
-rw-r--r--spec/ruby/core/module/alias_method_spec.rb20
-rw-r--r--spec/ruby/core/module/attr_accessor_spec.rb16
-rw-r--r--spec/ruby/core/module/attr_reader_spec.rb16
-rw-r--r--spec/ruby/core/module/attr_spec.rb22
-rw-r--r--spec/ruby/core/module/attr_writer_spec.rb16
-rw-r--r--spec/ruby/core/module/const_added_spec.rb35
-rw-r--r--spec/ruby/core/module/const_defined_spec.rb21
-rw-r--r--spec/ruby/core/module/const_get_spec.rb2
-rw-r--r--spec/ruby/core/module/const_set_spec.rb18
-rw-r--r--spec/ruby/core/module/const_source_location_spec.rb14
-rw-r--r--spec/ruby/core/module/define_method_spec.rb46
-rw-r--r--spec/ruby/core/module/fixtures/classes.rb26
-rw-r--r--spec/ruby/core/module/fixtures/module.rb4
-rw-r--r--spec/ruby/core/module/method_added_spec.rb73
-rw-r--r--spec/ruby/core/module/module_function_spec.rb136
-rw-r--r--spec/ruby/core/module/name_spec.rb54
-rw-r--r--spec/ruby/core/module/prepend_spec.rb39
-rw-r--r--spec/ruby/core/module/private_class_method_spec.rb14
-rw-r--r--spec/ruby/core/module/public_class_method_spec.rb20
-rw-r--r--spec/ruby/core/module/refine_spec.rb2
-rw-r--r--spec/ruby/core/module/refinements_spec.rb45
-rw-r--r--spec/ruby/core/module/ruby2_keywords_spec.rb22
-rw-r--r--spec/ruby/core/module/set_temporary_name_spec.rb68
-rw-r--r--spec/ruby/core/module/shared/class_eval.rb6
-rw-r--r--spec/ruby/core/module/shared/set_visibility.rb28
-rw-r--r--spec/ruby/core/module/undefined_instance_methods_spec.rb26
-rw-r--r--spec/ruby/core/module/used_refinements_spec.rb87
-rw-r--r--spec/ruby/core/mutex/lock_spec.rb4
-rw-r--r--spec/ruby/core/mutex/owned_spec.rb18
-rw-r--r--spec/ruby/core/nil/singleton_method_spec.rb15
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb10
-rw-r--r--spec/ruby/core/numeric/fdiv_spec.rb1
-rw-r--r--spec/ruby/core/numeric/magnitude_spec.rb1
-rw-r--r--spec/ruby/core/numeric/quo_spec.rb1
-rw-r--r--spec/ruby/core/numeric/remainder_spec.rb3
-rw-r--r--spec/ruby/core/numeric/shared/quo.rb7
-rw-r--r--spec/ruby/core/numeric/shared/step.rb8
-rw-r--r--spec/ruby/core/numeric/step_spec.rb85
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb78
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/delete_spec.rb40
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb26
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb71
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb14
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb17
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/key_spec.rb33
-rw-r--r--spec/ruby/core/objectspace/weakmap/delete_spec.rb30
-rw-r--r--spec/ruby/core/proc/clone_spec.rb9
-rw-r--r--spec/ruby/core/proc/compose_spec.rb46
-rw-r--r--spec/ruby/core/proc/dup_spec.rb7
-rw-r--r--spec/ruby/core/proc/eql_spec.rb8
-rw-r--r--spec/ruby/core/proc/equal_value_spec.rb8
-rw-r--r--spec/ruby/core/proc/lambda_spec.rb8
-rw-r--r--spec/ruby/core/proc/new_spec.rb35
-rw-r--r--spec/ruby/core/proc/parameters_spec.rb50
-rw-r--r--spec/ruby/core/proc/ruby2_keywords_spec.rb22
-rw-r--r--spec/ruby/core/proc/shared/dup.rb31
-rw-r--r--spec/ruby/core/proc/shared/equal.rb17
-rw-r--r--spec/ruby/core/proc/source_location_spec.rb13
-rw-r--r--spec/ruby/core/process/argv0_spec.rb25
-rw-r--r--spec/ruby/core/process/constants_spec.rb8
-rw-r--r--spec/ruby/core/process/daemon_spec.rb3
-rw-r--r--spec/ruby/core/process/detach_spec.rb14
-rw-r--r--spec/ruby/core/process/exec_spec.rb44
-rw-r--r--spec/ruby/core/process/exit_spec.rb2
-rw-r--r--spec/ruby/core/process/fixtures/argv0.rb6
-rw-r--r--spec/ruby/core/process/spawn_spec.rb2
-rw-r--r--spec/ruby/core/process/status/wait_spec.rb158
-rw-r--r--spec/ruby/core/process/times_spec.rb20
-rw-r--r--spec/ruby/core/process/wait2_spec.rb4
-rw-r--r--spec/ruby/core/process/wait_spec.rb2
-rw-r--r--spec/ruby/core/process/warmup_spec.rb11
-rw-r--r--spec/ruby/core/queue/deq_spec.rb7
-rw-r--r--spec/ruby/core/queue/initialize_spec.rb33
-rw-r--r--spec/ruby/core/queue/pop_spec.rb7
-rw-r--r--spec/ruby/core/queue/shift_spec.rb7
-rw-r--r--spec/ruby/core/random/bytes_spec.rb1
-rw-r--r--spec/ruby/core/random/default_spec.rb24
-rw-r--r--spec/ruby/core/random/new_spec.rb1
-rw-r--r--spec/ruby/core/range/cover_spec.rb4
-rw-r--r--spec/ruby/core/range/frozen_spec.rb34
-rw-r--r--spec/ruby/core/range/include_spec.rb4
-rw-r--r--spec/ruby/core/range/initialize_spec.rb15
-rw-r--r--spec/ruby/core/range/max_spec.rb18
-rw-r--r--spec/ruby/core/range/minmax_spec.rb24
-rw-r--r--spec/ruby/core/range/new_spec.rb14
-rw-r--r--spec/ruby/core/range/shared/cover_and_include.rb1
-rw-r--r--spec/ruby/core/range/size_spec.rb4
-rw-r--r--spec/ruby/core/range/step_spec.rb52
-rw-r--r--spec/ruby/core/rational/abs_spec.rb1
-rw-r--r--spec/ruby/core/rational/ceil_spec.rb1
-rw-r--r--spec/ruby/core/rational/coerce_spec.rb1
-rw-r--r--spec/ruby/core/rational/comparison_spec.rb1
-rw-r--r--spec/ruby/core/rational/denominator_spec.rb1
-rw-r--r--spec/ruby/core/rational/div_spec.rb1
-rw-r--r--spec/ruby/core/rational/divide_spec.rb1
-rw-r--r--spec/ruby/core/rational/divmod_spec.rb1
-rw-r--r--spec/ruby/core/rational/equal_value_spec.rb1
-rw-r--r--spec/ruby/core/rational/exponent_spec.rb1
-rw-r--r--spec/ruby/core/rational/fdiv_spec.rb1
-rw-r--r--spec/ruby/core/rational/floor_spec.rb1
-rw-r--r--spec/ruby/core/rational/hash_spec.rb1
-rw-r--r--spec/ruby/core/rational/inspect_spec.rb1
-rw-r--r--spec/ruby/core/rational/integer_spec.rb1
-rw-r--r--spec/ruby/core/rational/magnitude_spec.rb1
-rw-r--r--spec/ruby/core/rational/modulo_spec.rb1
-rw-r--r--spec/ruby/core/rational/multiply_spec.rb1
-rw-r--r--spec/ruby/core/rational/numerator_spec.rb1
-rw-r--r--spec/ruby/core/rational/plus_spec.rb1
-rw-r--r--spec/ruby/core/rational/quo_spec.rb1
-rw-r--r--spec/ruby/core/rational/remainder_spec.rb1
-rw-r--r--spec/ruby/core/rational/to_f_spec.rb1
-rw-r--r--spec/ruby/core/rational/to_i_spec.rb1
-rw-r--r--spec/ruby/core/rational/to_r_spec.rb1
-rw-r--r--spec/ruby/core/rational/to_s_spec.rb1
-rw-r--r--spec/ruby/core/rational/truncate_spec.rb1
-rw-r--r--spec/ruby/core/rational/zero_spec.rb1
-rw-r--r--spec/ruby/core/refinement/extend_object_spec.rb6
-rw-r--r--spec/ruby/core/refinement/fixtures/classes.rb10
-rw-r--r--spec/ruby/core/refinement/import_methods_spec.rb235
-rw-r--r--spec/ruby/core/refinement/refined_class_spec.rb17
-rw-r--r--spec/ruby/core/regexp/initialize_spec.rb12
-rw-r--r--spec/ruby/core/regexp/linear_time_spec.rb25
-rw-r--r--spec/ruby/core/regexp/shared/new.rb4
-rw-r--r--spec/ruby/core/regexp/try_convert_spec.rb6
-rw-r--r--spec/ruby/core/regexp/union_spec.rb51
-rw-r--r--spec/ruby/core/signal/signame_spec.rb12
-rw-r--r--spec/ruby/core/signal/trap_spec.rb19
-rw-r--r--spec/ruby/core/sizedqueue/append_spec.rb7
-rw-r--r--spec/ruby/core/sizedqueue/deq_spec.rb7
-rw-r--r--spec/ruby/core/sizedqueue/enq_spec.rb7
-rw-r--r--spec/ruby/core/sizedqueue/pop_spec.rb7
-rw-r--r--spec/ruby/core/sizedqueue/push_spec.rb7
-rw-r--r--spec/ruby/core/sizedqueue/shift_spec.rb7
-rw-r--r--spec/ruby/core/string/append_spec.rb1
-rw-r--r--spec/ruby/core/string/byteindex_spec.rb300
-rw-r--r--spec/ruby/core/string/byterindex_spec.rb359
-rw-r--r--spec/ruby/core/string/bytesplice_spec.rb133
-rw-r--r--spec/ruby/core/string/capitalize_spec.rb15
-rw-r--r--spec/ruby/core/string/casecmp_spec.rb10
-rw-r--r--spec/ruby/core/string/center_spec.rb25
-rw-r--r--spec/ruby/core/string/chars_spec.rb1
-rw-r--r--spec/ruby/core/string/chomp_spec.rb15
-rw-r--r--spec/ruby/core/string/chop_spec.rb12
-rw-r--r--spec/ruby/core/string/concat_spec.rb1
-rw-r--r--spec/ruby/core/string/dedup_spec.rb2
-rw-r--r--spec/ruby/core/string/delete_prefix_spec.rb15
-rw-r--r--spec/ruby/core/string/delete_spec.rb12
-rw-r--r--spec/ruby/core/string/delete_suffix_spec.rb15
-rw-r--r--spec/ruby/core/string/downcase_spec.rb12
-rw-r--r--spec/ruby/core/string/dump_spec.rb12
-rw-r--r--spec/ruby/core/string/each_char_spec.rb1
-rw-r--r--spec/ruby/core/string/each_grapheme_cluster_spec.rb11
-rw-r--r--spec/ruby/core/string/encode_spec.rb4
-rw-r--r--spec/ruby/core/string/grapheme_clusters_spec.rb1
-rw-r--r--spec/ruby/core/string/gsub_spec.rb21
-rw-r--r--spec/ruby/core/string/index_spec.rb18
-rw-r--r--spec/ruby/core/string/ljust_spec.rb25
-rw-r--r--spec/ruby/core/string/lstrip_spec.rb18
-rw-r--r--spec/ruby/core/string/plus_spec.rb5
-rw-r--r--spec/ruby/core/string/reverse_spec.rb18
-rw-r--r--spec/ruby/core/string/rindex_spec.rb18
-rw-r--r--spec/ruby/core/string/rjust_spec.rb25
-rw-r--r--spec/ruby/core/string/rstrip_spec.rb10
-rw-r--r--spec/ruby/core/string/scan_spec.rb10
-rw-r--r--spec/ruby/core/string/scrub_spec.rb36
-rw-r--r--spec/ruby/core/string/shared/byte_index_common.rb63
-rw-r--r--spec/ruby/core/string/shared/concat.rb32
-rw-r--r--spec/ruby/core/string/shared/dedup.rb8
-rw-r--r--spec/ruby/core/string/shared/each_line.rb18
-rw-r--r--spec/ruby/core/string/shared/partition.rb34
-rw-r--r--spec/ruby/core/string/shared/slice.rb114
-rw-r--r--spec/ruby/core/string/shared/strip.rb18
-rw-r--r--spec/ruby/core/string/shared/succ.rb18
-rw-r--r--spec/ruby/core/string/shared/to_a.rb9
-rw-r--r--spec/ruby/core/string/shared/to_sym.rb2
-rw-r--r--spec/ruby/core/string/slice_spec.rb93
-rw-r--r--spec/ruby/core/string/split_spec.rb112
-rw-r--r--spec/ruby/core/string/squeeze_spec.rb12
-rw-r--r--spec/ruby/core/string/start_with_spec.rb17
-rw-r--r--spec/ruby/core/string/strip_spec.rb16
-rw-r--r--spec/ruby/core/string/sub_spec.rb21
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb15
-rw-r--r--spec/ruby/core/string/to_c_spec.rb12
-rw-r--r--spec/ruby/core/string/tr_s_spec.rb21
-rw-r--r--spec/ruby/core/string/tr_spec.rb21
-rw-r--r--spec/ruby/core/string/try_convert_spec.rb2
-rw-r--r--spec/ruby/core/string/unpack/b_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/c_spec.rb4
-rw-r--r--spec/ruby/core/string/unpack/h_spec.rb8
-rw-r--r--spec/ruby/core/string/unpack/shared/float.rb20
-rw-r--r--spec/ruby/core/string/unpack/shared/integer.rb28
-rw-r--r--spec/ruby/core/string/unpack/shared/unicode.rb4
-rw-r--r--spec/ruby/core/string/unpack/w_spec.rb4
-rw-r--r--spec/ruby/core/string/unpack_spec.rb2
-rw-r--r--spec/ruby/core/string/upcase_spec.rb12
-rw-r--r--spec/ruby/core/string/uplus_spec.rb3
-rw-r--r--spec/ruby/core/string/upto_spec.rb6
-rw-r--r--spec/ruby/core/string/valid_encoding_spec.rb10
-rw-r--r--spec/ruby/core/struct/constants_spec.rb15
-rw-r--r--spec/ruby/core/struct/deconstruct_keys_spec.rb2
-rw-r--r--spec/ruby/core/struct/fixtures/classes.rb6
-rw-r--r--spec/ruby/core/struct/initialize_spec.rb10
-rw-r--r--spec/ruby/core/struct/inspect_spec.rb5
-rw-r--r--spec/ruby/core/struct/keyword_init_spec.rb19
-rw-r--r--spec/ruby/core/struct/new_spec.rb19
-rw-r--r--spec/ruby/core/struct/shared/inspect.rb35
-rw-r--r--spec/ruby/core/symbol/casecmp_spec.rb8
-rw-r--r--spec/ruby/core/symbol/inspect_spec.rb2
-rw-r--r--spec/ruby/core/symbol/name_spec.rb24
-rw-r--r--spec/ruby/core/symbol/to_proc_spec.rb39
-rw-r--r--spec/ruby/core/thread/backtrace/location/path_spec.rb2
-rw-r--r--spec/ruby/core/thread/each_caller_location_spec.rb49
-rw-r--r--spec/ruby/core/thread/exclusive_spec.rb49
-rw-r--r--spec/ruby/core/thread/ignore_deadlock_spec.rb26
-rw-r--r--spec/ruby/core/thread/kill_spec.rb4
-rw-r--r--spec/ruby/core/thread/native_thread_id_spec.rb40
-rw-r--r--spec/ruby/core/thread/report_on_exception_spec.rb44
-rw-r--r--spec/ruby/core/thread/shared/exit.rb19
-rw-r--r--spec/ruby/core/time/deconstruct_keys_spec.rb44
-rw-r--r--spec/ruby/core/time/new_spec.rb200
-rw-r--r--spec/ruby/core/time/now_spec.rb66
-rw-r--r--spec/ruby/core/time/succ_spec.rb39
-rw-r--r--spec/ruby/core/time/utc_spec.rb10
-rw-r--r--spec/ruby/core/time/zone_spec.rb11
-rw-r--r--spec/ruby/core/tracepoint/enable_spec.rb8
-rw-r--r--spec/ruby/core/tracepoint/inspect_spec.rb8
-rw-r--r--spec/ruby/core/tracepoint/path_spec.rb31
-rw-r--r--spec/ruby/core/true/singleton_method_spec.rb15
-rw-r--r--spec/ruby/core/unboundmethod/bind_call_spec.rb8
-rw-r--r--spec/ruby/core/unboundmethod/bind_spec.rb8
-rw-r--r--spec/ruby/core/unboundmethod/clone_spec.rb13
-rw-r--r--spec/ruby/core/unboundmethod/dup_spec.rb15
-rw-r--r--spec/ruby/core/unboundmethod/fixtures/classes.rb4
-rw-r--r--spec/ruby/core/unboundmethod/private_spec.rb11
-rw-r--r--spec/ruby/core/unboundmethod/protected_spec.rb11
-rw-r--r--spec/ruby/core/unboundmethod/public_spec.rb11
-rw-r--r--spec/ruby/core/unboundmethod/shared/dup.rb32
-rw-r--r--spec/ruby/core/unboundmethod/source_location_spec.rb9
-rw-r--r--spec/ruby/core/unboundmethod/super_method_spec.rb10
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb13
-rw-r--r--spec/ruby/core/warning/element_set_spec.rb20
-rw-r--r--spec/ruby/core/warning/warn_spec.rb103
-rw-r--r--spec/ruby/fixtures/code/d/load_fixture.rb.rb1
-rw-r--r--spec/ruby/fixtures/constants.rb3
-rw-r--r--spec/ruby/language/END_spec.rb26
-rw-r--r--spec/ruby/language/alias_spec.rb20
-rw-r--r--spec/ruby/language/block_spec.rb172
-rw-r--r--spec/ruby/language/case_spec.rb104
-rw-r--r--spec/ruby/language/class_spec.rb18
-rw-r--r--spec/ruby/language/class_variable_spec.rb56
-rw-r--r--spec/ruby/language/constants_spec.rb38
-rw-r--r--spec/ruby/language/defined_spec.rb26
-rw-r--r--spec/ruby/language/delegation_spec.rb38
-rw-r--r--spec/ruby/language/file_spec.rb12
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rbbin120 -> 181 bytes-rw-r--r--spec/ruby/language/fixtures/super.rb14
-rw-r--r--spec/ruby/language/fixtures/variables.rb72
-rw-r--r--spec/ruby/language/hash_spec.rb50
-rw-r--r--spec/ruby/language/if_spec.rb43
-rw-r--r--spec/ruby/language/keyword_arguments_spec.rb555
-rw-r--r--spec/ruby/language/lambda_spec.rb68
-rw-r--r--spec/ruby/language/method_spec.rb731
-rw-r--r--spec/ruby/language/module_spec.rb18
-rw-r--r--spec/ruby/language/numbered_parameters_spec.rb66
-rw-r--r--spec/ruby/language/pattern_matching_spec.rb276
-rw-r--r--spec/ruby/language/predefined_spec.rb47
-rw-r--r--spec/ruby/language/proc_spec.rb26
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb10
-rw-r--r--spec/ruby/language/regexp/repetition_spec.rb8
-rw-r--r--spec/ruby/language/regexp_spec.rb8
-rw-r--r--spec/ruby/language/safe_spec.rb28
-rw-r--r--spec/ruby/language/send_spec.rb36
-rw-r--r--spec/ruby/language/singleton_class_spec.rb24
-rw-r--r--spec/ruby/language/source_encoding_spec.rb2
-rw-r--r--spec/ruby/language/string_spec.rb24
-rw-r--r--spec/ruby/language/super_spec.rb23
-rw-r--r--spec/ruby/language/symbol_spec.rb14
-rw-r--r--spec/ruby/language/undef_spec.rb9
-rw-r--r--spec/ruby/language/variables_spec.rb99
-rw-r--r--spec/ruby/language/yield_spec.rb31
-rw-r--r--spec/ruby/library/English/English_spec.rb16
-rw-r--r--spec/ruby/library/bigdecimal/add_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/remainder_spec.rb28
-rw-r--r--spec/ruby/library/bigdecimal/round_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/shared/to_int.rb2
-rw-r--r--spec/ruby/library/bigdecimal/to_s_spec.rb27
-rw-r--r--spec/ruby/library/cgi/escapeURIComponent_spec.rb57
-rw-r--r--spec/ruby/library/cgi/initialize_spec.rb2
-rw-r--r--spec/ruby/library/coverage/running_spec.rb2
-rw-r--r--spec/ruby/library/coverage/supported_spec.rb32
-rw-r--r--spec/ruby/library/date/deconstruct_keys_spec.rb44
-rw-r--r--spec/ruby/library/date/iso8601_spec.rb21
-rw-r--r--spec/ruby/library/date/new_spec.rb1
-rw-r--r--spec/ruby/library/date/parse_spec.rb10
-rw-r--r--spec/ruby/library/date/shared/new_bang.rb14
-rw-r--r--spec/ruby/library/date/shared/parse.rb4
-rw-r--r--spec/ruby/library/date/shared/parse_eu.rb8
-rw-r--r--spec/ruby/library/date/shared/parse_us.rb8
-rw-r--r--spec/ruby/library/date/strftime_spec.rb6
-rw-r--r--spec/ruby/library/datetime/deconstruct_keys_spec.rb46
-rw-r--r--spec/ruby/library/datetime/rfc2822_spec.rb4
-rw-r--r--spec/ruby/library/datetime/strftime_spec.rb5
-rw-r--r--spec/ruby/library/datetime/to_time_spec.rb4
-rw-r--r--spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb1
-rw-r--r--spec/ruby/library/digest/instance/shared/update.rb2
-rw-r--r--spec/ruby/library/digest/md5/shared/sample.rb17
-rw-r--r--spec/ruby/library/erb/new_spec.rb2
-rw-r--r--spec/ruby/library/etc/confstr_spec.rb2
-rw-r--r--spec/ruby/library/etc/passwd_spec.rb2
-rw-r--r--spec/ruby/library/etc/sysconf_spec.rb2
-rw-r--r--spec/ruby/library/etc/sysconfdir_spec.rb2
-rw-r--r--spec/ruby/library/etc/systmpdir_spec.rb2
-rw-r--r--spec/ruby/library/etc/uname_spec.rb14
-rw-r--r--spec/ruby/library/expect/expect_spec.rb3
-rw-r--r--spec/ruby/library/fiber/current_spec.rb21
-rw-r--r--spec/ruby/library/fiber/resume_spec.rb35
-rw-r--r--spec/ruby/library/fiber/transfer_spec.rb56
-rw-r--r--spec/ruby/library/io-wait/fixtures/classes.rb12
-rw-r--r--spec/ruby/library/io-wait/wait_spec.rb144
-rw-r--r--spec/ruby/library/ipaddr/new_spec.rb10
-rw-r--r--spec/ruby/library/logger/device/close_spec.rb15
-rw-r--r--spec/ruby/library/logger/device/write_spec.rb15
-rw-r--r--spec/ruby/library/matrix/unitary_spec.rb6
-rw-r--r--spec/ruby/library/monitor/exit_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/shared/getbinaryfile.rb4
-rw-r--r--spec/ruby/library/net/ftp/shared/gettextfile.rb2
-rw-r--r--spec/ruby/library/net/ftp/shared/putbinaryfile.rb4
-rw-r--r--spec/ruby/library/net/ftp/shared/puttextfile.rb2
-rw-r--r--spec/ruby/library/net/ftp/storbinary_spec.rb2
-rw-r--r--spec/ruby/library/net/ftp/storlines_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/get_spec.rb16
-rw-r--r--spec/ruby/library/objectspace/dump_all_spec.rb112
-rw-r--r--spec/ruby/library/objectspace/dump_spec.rb70
-rw-r--r--spec/ruby/library/openssl/config/freeze_spec.rb22
-rw-r--r--spec/ruby/library/openssl/digest/append_spec.rb6
-rw-r--r--spec/ruby/library/openssl/digest/block_length_spec.rb44
-rw-r--r--spec/ruby/library/openssl/digest/digest_length_spec.rb44
-rw-r--r--spec/ruby/library/openssl/digest/digest_spec.rb62
-rw-r--r--spec/ruby/library/openssl/digest/initialize_spec.rb141
-rw-r--r--spec/ruby/library/openssl/digest/name_spec.rb16
-rw-r--r--spec/ruby/library/openssl/digest/reset_spec.rb36
-rw-r--r--spec/ruby/library/openssl/digest/shared/update.rb123
-rw-r--r--spec/ruby/library/openssl/digest/update_spec.rb6
-rw-r--r--spec/ruby/library/openssl/digest_spec.rb63
-rw-r--r--spec/ruby/library/openssl/fixed_length_secure_compare_spec.rb42
-rw-r--r--spec/ruby/library/openssl/kdf/pbkdf2_hmac_spec.rb168
-rw-r--r--spec/ruby/library/openssl/kdf/scrypt_spec.rb209
-rw-r--r--spec/ruby/library/openssl/random/shared/random_bytes.rb2
-rw-r--r--spec/ruby/library/openssl/secure_compare_spec.rb38
-rw-r--r--spec/ruby/library/openssl/x509/name/verify_spec.rb78
-rw-r--r--spec/ruby/library/openssl/x509/store/verify_spec.rb78
-rw-r--r--spec/ruby/library/pathname/relative_path_from_spec.rb4
-rw-r--r--spec/ruby/library/rexml/attribute/clone_spec.rb14
-rw-r--r--spec/ruby/library/rexml/attribute/element_spec.rb26
-rw-r--r--spec/ruby/library/rexml/attribute/equal_value_spec.rb21
-rw-r--r--spec/ruby/library/rexml/attribute/hash_spec.rb16
-rw-r--r--spec/ruby/library/rexml/attribute/initialize_spec.rb32
-rw-r--r--spec/ruby/library/rexml/attribute/inspect_spec.rb22
-rw-r--r--spec/ruby/library/rexml/attribute/namespace_spec.rb27
-rw-r--r--spec/ruby/library/rexml/attribute/node_type_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attribute/prefix_spec.rb21
-rw-r--r--spec/ruby/library/rexml/attribute/remove_spec.rb23
-rw-r--r--spec/ruby/library/rexml/attribute/to_s_spec.rb17
-rw-r--r--spec/ruby/library/rexml/attribute/to_string_spec.rb17
-rw-r--r--spec/ruby/library/rexml/attribute/value_spec.rb17
-rw-r--r--spec/ruby/library/rexml/attribute/write_spec.rb26
-rw-r--r--spec/ruby/library/rexml/attribute/xpath_spec.rb22
-rw-r--r--spec/ruby/library/rexml/attributes/add_spec.rb10
-rw-r--r--spec/ruby/library/rexml/attributes/append_spec.rb10
-rw-r--r--spec/ruby/library/rexml/attributes/delete_all_spec.rb34
-rw-r--r--spec/ruby/library/rexml/attributes/delete_spec.rb30
-rw-r--r--spec/ruby/library/rexml/attributes/each_attribute_spec.rb25
-rw-r--r--spec/ruby/library/rexml/attributes/each_spec.rb26
-rw-r--r--spec/ruby/library/rexml/attributes/element_reference_spec.rb21
-rw-r--r--spec/ruby/library/rexml/attributes/element_set_spec.rb28
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb17
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_spec.rb32
-rw-r--r--spec/ruby/library/rexml/attributes/initialize_spec.rb21
-rw-r--r--spec/ruby/library/rexml/attributes/length_spec.rb10
-rw-r--r--spec/ruby/library/rexml/attributes/namespaces_spec.rb9
-rw-r--r--spec/ruby/library/rexml/attributes/prefixes_spec.rb27
-rw-r--r--spec/ruby/library/rexml/attributes/shared/add.rb17
-rw-r--r--spec/ruby/library/rexml/attributes/shared/length.rb13
-rw-r--r--spec/ruby/library/rexml/attributes/size_spec.rb10
-rw-r--r--spec/ruby/library/rexml/attributes/to_a_spec.rb22
-rw-r--r--spec/ruby/library/rexml/cdata/clone_spec.rb13
-rw-r--r--spec/ruby/library/rexml/cdata/initialize_spec.rb27
-rw-r--r--spec/ruby/library/rexml/cdata/shared/to_s.rb11
-rw-r--r--spec/ruby/library/rexml/cdata/to_s_spec.rb10
-rw-r--r--spec/ruby/library/rexml/cdata/value_spec.rb10
-rw-r--r--spec/ruby/library/rexml/document/add_element_spec.rb34
-rw-r--r--spec/ruby/library/rexml/document/add_spec.rb60
-rw-r--r--spec/ruby/library/rexml/document/clone_spec.rb23
-rw-r--r--spec/ruby/library/rexml/document/doctype_spec.rb18
-rw-r--r--spec/ruby/library/rexml/document/encoding_spec.rb25
-rw-r--r--spec/ruby/library/rexml/document/expanded_name_spec.rb19
-rw-r--r--spec/ruby/library/rexml/document/new_spec.rb39
-rw-r--r--spec/ruby/library/rexml/document/node_type_spec.rb11
-rw-r--r--spec/ruby/library/rexml/document/root_spec.rb15
-rw-r--r--spec/ruby/library/rexml/document/stand_alone_spec.rb22
-rw-r--r--spec/ruby/library/rexml/document/version_spec.rb17
-rw-r--r--spec/ruby/library/rexml/document/write_spec.rb38
-rw-r--r--spec/ruby/library/rexml/document/xml_decl_spec.rb18
-rw-r--r--spec/ruby/library/rexml/element/add_attribute_spec.rb44
-rw-r--r--spec/ruby/library/rexml/element/add_attributes_spec.rb25
-rw-r--r--spec/ruby/library/rexml/element/add_element_spec.rb41
-rw-r--r--spec/ruby/library/rexml/element/add_namespace_spec.rb26
-rw-r--r--spec/ruby/library/rexml/element/add_text_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/attribute_spec.rb20
-rw-r--r--spec/ruby/library/rexml/element/attributes_spec.rb22
-rw-r--r--spec/ruby/library/rexml/element/cdatas_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/clone_spec.rb32
-rw-r--r--spec/ruby/library/rexml/element/comments_spec.rb23
-rw-r--r--spec/ruby/library/rexml/element/delete_attribute_spec.rb42
-rw-r--r--spec/ruby/library/rexml/element/delete_element_spec.rb52
-rw-r--r--spec/ruby/library/rexml/element/delete_namespace_spec.rb28
-rw-r--r--spec/ruby/library/rexml/element/document_spec.rb19
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb38
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_text_spec.rb34
-rw-r--r--spec/ruby/library/rexml/element/element_reference_spec.rb23
-rw-r--r--spec/ruby/library/rexml/element/get_text_spec.rb21
-rw-r--r--spec/ruby/library/rexml/element/has_attributes_spec.rb20
-rw-r--r--spec/ruby/library/rexml/element/has_elements_spec.rb21
-rw-r--r--spec/ruby/library/rexml/element/has_text_spec.rb19
-rw-r--r--spec/ruby/library/rexml/element/inspect_spec.rb30
-rw-r--r--spec/ruby/library/rexml/element/instructions_spec.rb24
-rw-r--r--spec/ruby/library/rexml/element/namespace_spec.rb30
-rw-r--r--spec/ruby/library/rexml/element/namespaces_spec.rb35
-rw-r--r--spec/ruby/library/rexml/element/new_spec.rb38
-rw-r--r--spec/ruby/library/rexml/element/next_element_spec.rb22
-rw-r--r--spec/ruby/library/rexml/element/node_type_spec.rb11
-rw-r--r--spec/ruby/library/rexml/element/prefixes_spec.rb26
-rw-r--r--spec/ruby/library/rexml/element/previous_element_spec.rb23
-rw-r--r--spec/ruby/library/rexml/element/raw_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/root_spec.rb31
-rw-r--r--spec/ruby/library/rexml/element/text_spec.rb49
-rw-r--r--spec/ruby/library/rexml/element/texts_spec.rb19
-rw-r--r--spec/ruby/library/rexml/element/whitespace_spec.rb26
-rw-r--r--spec/ruby/library/rexml/node/each_recursive_spec.rb24
-rw-r--r--spec/ruby/library/rexml/node/find_first_recursive_spec.rb28
-rw-r--r--spec/ruby/library/rexml/node/index_in_parent_spec.rb18
-rw-r--r--spec/ruby/library/rexml/node/next_sibling_node_spec.rb24
-rw-r--r--spec/ruby/library/rexml/node/parent_spec.rb23
-rw-r--r--spec/ruby/library/rexml/node/previous_sibling_node_spec.rb24
-rw-r--r--spec/ruby/library/rexml/shared/each_element.rb36
-rw-r--r--spec/ruby/library/rexml/shared/elements_to_a.rb34
-rw-r--r--spec/ruby/library/rexml/text/append_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/clone_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/comparison_spec.rb28
-rw-r--r--spec/ruby/library/rexml/text/empty_spec.rb15
-rw-r--r--spec/ruby/library/rexml/text/indent_text_spec.rb26
-rw-r--r--spec/ruby/library/rexml/text/inspect_spec.rb11
-rw-r--r--spec/ruby/library/rexml/text/new_spec.rb51
-rw-r--r--spec/ruby/library/rexml/text/node_type_spec.rb11
-rw-r--r--spec/ruby/library/rexml/text/normalize_spec.rb11
-rw-r--r--spec/ruby/library/rexml/text/read_with_substitution_spec.rb15
-rw-r--r--spec/ruby/library/rexml/text/to_s_spec.rb20
-rw-r--r--spec/ruby/library/rexml/text/unnormalize_spec.rb11
-rw-r--r--spec/ruby/library/rexml/text/value_spec.rb40
-rw-r--r--spec/ruby/library/rexml/text/wrap_spec.rb23
-rw-r--r--spec/ruby/library/rexml/text/write_with_substitution_spec.rb36
-rw-r--r--spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb2
-rw-r--r--spec/ruby/library/set/comparison_spec.rb56
-rw-r--r--spec/ruby/library/set/divide_spec.rb35
-rw-r--r--spec/ruby/library/set/each_spec.rb1
-rw-r--r--spec/ruby/library/set/enumerable/to_set_spec.rb8
-rw-r--r--spec/ruby/library/set/flatten_spec.rb9
-rw-r--r--spec/ruby/library/set/initialize_clone_spec.rb22
-rw-r--r--spec/ruby/library/set/join_spec.rb42
-rw-r--r--spec/ruby/library/set/proper_subset_spec.rb9
-rw-r--r--spec/ruby/library/set/shared/inspect.rb20
-rw-r--r--spec/ruby/library/set/sortedset/add_spec.rb42
-rw-r--r--spec/ruby/library/set/sortedset/append_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/case_equality_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/classify_spec.rb30
-rw-r--r--spec/ruby/library/set/sortedset/clear_spec.rb20
-rw-r--r--spec/ruby/library/set/sortedset/collect_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/constructor_spec.rb18
-rw-r--r--spec/ruby/library/set/sortedset/delete_if_spec.rb41
-rw-r--r--spec/ruby/library/set/sortedset/delete_spec.rb40
-rw-r--r--spec/ruby/library/set/sortedset/difference_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/divide_spec.rb37
-rw-r--r--spec/ruby/library/set/sortedset/each_spec.rb29
-rw-r--r--spec/ruby/library/set/sortedset/empty_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/eql_spec.rb19
-rw-r--r--spec/ruby/library/set/sortedset/equal_value_spec.rb16
-rw-r--r--spec/ruby/library/set/sortedset/exclusion_spec.rb21
-rw-r--r--spec/ruby/library/set/sortedset/filter_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/flatten_merge_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/flatten_spec.rb47
-rw-r--r--spec/ruby/library/set/sortedset/hash_spec.rb16
-rw-r--r--spec/ruby/library/set/sortedset/include_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/initialize_spec.rb33
-rw-r--r--spec/ruby/library/set/sortedset/inspect_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/intersection_spec.rb14
-rw-r--r--spec/ruby/library/set/sortedset/keep_if_spec.rb34
-rw-r--r--spec/ruby/library/set/sortedset/length_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/map_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/member_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/merge_spec.rb22
-rw-r--r--spec/ruby/library/set/sortedset/minus_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/plus_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_spec.rb20
-rw-r--r--spec/ruby/library/set/sortedset/proper_subset_spec.rb36
-rw-r--r--spec/ruby/library/set/sortedset/proper_superset_spec.rb36
-rw-r--r--spec/ruby/library/set/sortedset/reject_spec.rb45
-rw-r--r--spec/ruby/library/set/sortedset/replace_spec.rb20
-rw-r--r--spec/ruby/library/set/sortedset/select_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/shared/add.rb14
-rw-r--r--spec/ruby/library/set/sortedset/shared/collect.rb20
-rw-r--r--spec/ruby/library/set/sortedset/shared/difference.rb15
-rw-r--r--spec/ruby/library/set/sortedset/shared/include.rb7
-rw-r--r--spec/ruby/library/set/sortedset/shared/intersection.rb15
-rw-r--r--spec/ruby/library/set/sortedset/shared/length.rb6
-rw-r--r--spec/ruby/library/set/sortedset/shared/select.rb35
-rw-r--r--spec/ruby/library/set/sortedset/shared/union.rb15
-rw-r--r--spec/ruby/library/set/sortedset/size_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/sortedset_spec.rb24
-rw-r--r--spec/ruby/library/set/sortedset/subset_spec.rb36
-rw-r--r--spec/ruby/library/set/sortedset/subtract_spec.rb20
-rw-r--r--spec/ruby/library/set/sortedset/superset_spec.rb36
-rw-r--r--spec/ruby/library/set/sortedset/to_a_spec.rb20
-rw-r--r--spec/ruby/library/set/sortedset/union_spec.rb14
-rw-r--r--spec/ruby/library/set/subset_spec.rb9
-rw-r--r--spec/ruby/library/set/to_s_spec.rb1
-rw-r--r--spec/ruby/library/shellwords/shellwords_spec.rb15
-rw-r--r--spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb4
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_spec.rb19
-rw-r--r--spec/ruby/library/socket/basicsocket/send_spec.rb4
-rw-r--r--spec/ruby/library/socket/basicsocket/shutdown_spec.rb20
-rw-r--r--spec/ruby/library/socket/fixtures/classes.rb6
-rw-r--r--spec/ruby/library/socket/ipsocket/getaddress_spec.rb2
-rw-r--r--spec/ruby/library/socket/shared/partially_closable_sockets.rb2
-rw-r--r--spec/ruby/library/socket/socket/getnameinfo_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/new_spec.rb2
-rw-r--r--spec/ruby/library/socket/tcpserver/new_spec.rb6
-rw-r--r--spec/ruby/library/socket/tcpsocket/initialize_spec.rb21
-rw-r--r--spec/ruby/library/socket/tcpsocket/open_spec.rb1
-rw-r--r--spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb2
-rw-r--r--spec/ruby/library/socket/tcpsocket/shared/new.rb16
-rw-r--r--spec/ruby/library/socket/udpsocket/new_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb7
-rw-r--r--spec/ruby/library/socket/unixserver/accept_spec.rb2
-rw-r--r--spec/ruby/library/socket/unixserver/for_fd_spec.rb2
-rw-r--r--spec/ruby/library/socket/unixserver/new_spec.rb12
-rw-r--r--spec/ruby/library/socket/unixserver/open_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixserver/shared/new.rb26
-rw-r--r--spec/ruby/library/socket/unixsocket/addr_spec.rb5
-rw-r--r--spec/ruby/library/socket/unixsocket/inspect_spec.rb4
-rw-r--r--spec/ruby/library/socket/unixsocket/local_address_spec.rb2
-rw-r--r--spec/ruby/library/socket/unixsocket/new_spec.rb12
-rw-r--r--spec/ruby/library/socket/unixsocket/open_spec.rb10
-rw-r--r--spec/ruby/library/socket/unixsocket/pair_spec.rb7
-rw-r--r--spec/ruby/library/socket/unixsocket/partially_closable_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/path_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/peeraddr_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/recv_io_spec.rb7
-rw-r--r--spec/ruby/library/socket/unixsocket/recvfrom_spec.rb7
-rw-r--r--spec/ruby/library/socket/unixsocket/send_io_spec.rb7
-rw-r--r--spec/ruby/library/socket/unixsocket/shared/new.rb28
-rw-r--r--spec/ruby/library/stringio/append_spec.rb7
-rw-r--r--spec/ruby/library/stringio/bytes_spec.rb29
-rw-r--r--spec/ruby/library/stringio/chars_spec.rb29
-rw-r--r--spec/ruby/library/stringio/codepoints_spec.rb19
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb13
-rw-r--r--spec/ruby/library/stringio/lines_spec.rb53
-rw-r--r--spec/ruby/library/stringio/new_spec.rb8
-rw-r--r--spec/ruby/library/stringio/reopen_spec.rb30
-rw-r--r--spec/ruby/library/stringio/set_encoding_spec.rb8
-rw-r--r--spec/ruby/library/stringio/shared/each.rb4
-rw-r--r--spec/ruby/library/stringio/shared/sysread.rb2
-rw-r--r--spec/ruby/library/stringio/shared/write.rb28
-rw-r--r--spec/ruby/library/time/to_datetime_spec.rb5
-rw-r--r--spec/ruby/library/uri/generic/host_spec.rb7
-rw-r--r--spec/ruby/library/uri/generic/to_s_spec.rb7
-rw-r--r--spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/_invoke_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/codepage_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/connect_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/const_load_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/constants_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/create_guid_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/invoke_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/locale_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/new_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_method_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole/setproperty_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_event/new_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/event_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/name_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/new_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/params_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/visible_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/default_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/input_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/name_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/optional_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/retval_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/guid_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/name_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/new_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/progid_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/progids_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/variables_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/visible_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/name_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/value_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb1
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb1
-rw-r--r--spec/ruby/library/yaml/dump_spec.rb14
-rw-r--r--spec/ruby/library/yaml/dump_stream_spec.rb3
-rw-r--r--spec/ruby/library/yaml/fixtures/common.rb4
-rw-r--r--spec/ruby/library/yaml/load_file_spec.rb13
-rw-r--r--spec/ruby/library/yaml/load_stream_spec.rb3
-rw-r--r--spec/ruby/library/yaml/parse_file_spec.rb8
-rw-r--r--spec/ruby/library/yaml/parse_spec.rb7
-rw-r--r--spec/ruby/library/yaml/shared/each_document.rb3
-rw-r--r--spec/ruby/library/yaml/shared/load.rb10
-rw-r--r--spec/ruby/library/yaml/to_yaml_spec.rb20
-rw-r--r--spec/ruby/library/zlib/deflate/new_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_line_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/mtime_spec.rb11
-rw-r--r--spec/ruby/library/zlib/gzipreader/new_spec.rb1
-rw-r--r--spec/ruby/library/zlib/inflate/finish_spec.rb1
-rw-r--r--spec/ruby/library/zlib/inflate/new_spec.rb1
-rw-r--r--spec/ruby/optional/capi/array_spec.rb34
-rw-r--r--spec/ruby/optional/capi/class_spec.rb32
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb30
-rw-r--r--spec/ruby/optional/capi/exception_spec.rb34
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c28
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/debug_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c23
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/hash_spec.c9
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c73
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c54
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c15
-rw-r--r--spec/ruby/optional/capi/ext/range_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/rbasic_spec.c54
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h34
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c49
-rw-r--r--spec/ruby/optional/capi/ext/struct_spec.c13
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c9
-rw-r--r--spec/ruby/optional/capi/ext/tracepoint_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c12
-rw-r--r--spec/ruby/optional/capi/fixtures/kernel.rb19
-rw-r--r--spec/ruby/optional/capi/hash_spec.rb16
-rw-r--r--spec/ruby/optional/capi/io_spec.rb98
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb135
-rw-r--r--spec/ruby/optional/capi/object_spec.rb12
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb53
-rw-r--r--spec/ruby/optional/capi/rbasic_spec.rb2
-rw-r--r--spec/ruby/optional/capi/shared/rbasic.rb1
-rw-r--r--spec/ruby/optional/capi/string_spec.rb63
-rw-r--r--spec/ruby/optional/capi/thread_spec.rb28
-rw-r--r--spec/ruby/optional/capi/time_spec.rb5
-rw-r--r--spec/ruby/optional/capi/typed_data_spec.rb12
-rw-r--r--spec/ruby/optional/capi/util_spec.rb93
-rw-r--r--spec/ruby/security/cve_2014_8080_spec.rb34
-rw-r--r--spec/ruby/security/cve_2017_17742_spec.rb37
-rw-r--r--spec/ruby/security/cve_2019_8323_spec.rb14
-rw-r--r--spec/ruby/shared/file/exist.rb5
-rw-r--r--spec/ruby/shared/kernel/at_exit.rb67
-rw-r--r--spec/ruby/shared/kernel/fixtures/END.rb3
-rw-r--r--spec/ruby/shared/kernel/fixtures/at_exit.rb3
-rw-r--r--spec/ruby/shared/process/exit.rb6
-rw-r--r--spec/ruby/shared/queue/deque.rb23
-rw-r--r--spec/ruby/shared/rational/Rational.rb9
-rw-r--r--spec/ruby/shared/rational/marshal_dump.rb5
-rw-r--r--spec/ruby/shared/rational/marshal_load.rb5
-rw-r--r--spec/ruby/shared/rational/quo.rb5
-rw-r--r--spec/ruby/shared/rational/truncate.rb26
-rw-r--r--spec/ruby/shared/sizedqueue/enque.rb26
-rw-r--r--spec/ruby/shared/string/start_with.rb12
-rw-r--r--spec/ruby/shared/string/times.rb18
-rw-r--r--spec/ruby/shared/types/rb_num2dbl_fails.rb17
-rw-r--r--spec/ruby/spec_helper.rb2
-rw-r--r--spec/syntax_suggest/integration/ruby_command_line_spec.rb8
-rw-r--r--spec/syntax_suggest/integration/syntax_suggest_spec.rb16
-rw-r--r--spec/syntax_suggest/unit/api_spec.rb6
-rw-r--r--spec/syntax_suggest/unit/around_block_scan_spec.rb2
-rw-r--r--spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb4
-rw-r--r--spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb4
-rw-r--r--spec/syntax_suggest/unit/capture_code_context_spec.rb32
-rw-r--r--spec/syntax_suggest/unit/clean_document_spec.rb8
-rw-r--r--spec/syntax_suggest/unit/code_line_spec.rb12
-rw-r--r--spec/syntax_suggest/unit/code_search_spec.rb82
-rw-r--r--spec/syntax_suggest/unit/core_ext_spec.rb2
-rw-r--r--spec/syntax_suggest/unit/explain_syntax_spec.rb4
-rw-r--r--spec/syntax_suggest/unit/lex_all_spec.rb3
-rw-r--r--spec/syntax_suggest/unit/pathname_from_message_spec.rb9
-rw-r--r--spec/syntax_suggest/unit/scan_history_spec.rb6
-rw-r--r--sprintf.c5
-rw-r--r--st.c155
-rw-r--r--string.c1002
-rw-r--r--string.rb10
-rw-r--r--struct.c143
-rw-r--r--symbol.c39
-rw-r--r--symbol.h5
-rw-r--r--symbol.rb2
-rw-r--r--template/Doxyfile.tmpl363
-rw-r--r--template/GNUmakefile.in9
-rw-r--r--template/Makefile.in135
-rw-r--r--template/builtin_binary.inc.tmpl10
-rw-r--r--template/configure-ext.mk.tmpl2
-rw-r--r--template/exts.mk.tmpl2
-rw-r--r--template/fake.rb.in6
-rw-r--r--template/id.c.tmpl3
-rw-r--r--template/id.h.tmpl9
-rw-r--r--template/prelude.c.tmpl35
-rw-r--r--template/ruby.pc.in2
-rwxr-xr-xtemplate/unicode_properties.rdoc.tmpl59
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb17
-rw-r--r--test/-ext-/debug/test_profile_frames.rb63
-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-/postponed_job/test_postponed_job.rb72
-rw-r--r--test/-ext-/string/test_capacity.rb8
-rw-r--r--test/-ext-/string/test_fstring.rb4
-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-/thread/helper.rb51
-rw-r--r--test/-ext-/thread/test_instrumentation_api.rb274
-rw-r--r--test/.excludes/TestArraySubclass.rb1
-rw-r--r--test/.excludes/TestThread.rb18
-rw-r--r--test/bigdecimal/test_bigdecimal.rb33
-rw-r--r--test/cgi/test_cgi_util.rb49
-rw-r--r--test/coverage/test_coverage.rb64
-rw-r--r--test/csv/helper.rb2
-rw-r--r--test/csv/interface/test_read.rb6
-rw-r--r--test/csv/parse/test_general.rb27
-rw-r--r--test/csv/parse/test_inputs_scanner.rb2
-rw-r--r--test/csv/parse/test_row_separator.rb2
-rw-r--r--test/csv/parse/test_skip_lines.rb10
-rw-r--r--test/csv/test_encodings.rb8
-rw-r--r--test/csv/write/test_general.rb2
-rw-r--r--test/did_you_mean/core_ext/test_name_error_extension.rb4
-rw-r--r--test/drb/drbtest.rb2
-rw-r--r--test/drb/test_drbssl.rb4
-rw-r--r--test/drb/ut_array_drbssl.rb4
-rw-r--r--test/error_highlight/test_error_highlight.rb180
-rw-r--r--test/excludes/TestArray.rb (renamed from test/.excludes/TestArray.rb)0
-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.rb14
-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/fiber/scheduler.rb130
-rw-r--r--test/fiber/test_address_resolve.rb2
-rw-r--r--test/fiber/test_io.rb15
-rw-r--r--test/fiber/test_io_buffer.rb41
-rw-r--r--test/fiber/test_scheduler.rb43
-rw-r--r--test/fiber/test_thread.rb2
-rw-r--r--test/fiddle/test_c_struct_entry.rb8
-rw-r--r--test/fiddle/test_closure.rb12
-rw-r--r--test/fiddle/test_cparser.rb40
-rw-r--r--test/fiddle/test_func.rb17
-rw-r--r--test/fiddle/test_pointer.rb16
-rw-r--r--test/fileutils/test_fileutils.rb8
-rw-r--r--test/fixtures/fake_sorted_set_gem/sorted_set.rb (renamed from test/set/fixtures/fake_sorted_set_gem/sorted_set.rb)0
-rw-r--r--test/io/console/test_io_console.rb10
-rw-r--r--test/io/wait/test_io_wait.rb1
-rw-r--r--test/irb/command/test_custom_command.rb149
-rw-r--r--test/irb/command/test_force_exit.rb51
-rw-r--r--test/irb/command/test_help.rb75
-rw-r--r--test/irb/command/test_multi_irb_commands.rb50
-rw-r--r--test/irb/command/test_show_source.rb397
-rw-r--r--test/irb/helper.rb159
-rw-r--r--test/irb/test_cmd.rb692
-rw-r--r--test/irb/test_color.rb65
-rw-r--r--test/irb/test_color_printer.rb20
-rw-r--r--test/irb/test_command.rb971
-rw-r--r--test/irb/test_completion.rb290
-rw-r--r--test/irb/test_context.rb444
-rw-r--r--test/irb/test_debug_cmd.rb303
-rw-r--r--test/irb/test_debugger_integration.rb496
-rw-r--r--test/irb/test_eval_history.rb69
-rw-r--r--test/irb/test_evaluation.rb44
-rw-r--r--test/irb/test_helper_method.rb134
-rw-r--r--test/irb/test_history.rb410
-rw-r--r--test/irb/test_init.rb183
-rw-r--r--test/irb/test_input_method.rb116
-rw-r--r--test/irb/test_irb.rb917
-rw-r--r--test/irb/test_locale.rb118
-rw-r--r--test/irb/test_nesting_parser.rb341
-rw-r--r--test/irb/test_option.rb2
-rw-r--r--test/irb/test_raise_exception.rb74
-rw-r--r--test/irb/test_raise_no_backtrace_exception.rb56
-rw-r--r--test/irb/test_ruby_lex.rb817
-rw-r--r--test/irb/test_tracer.rb90
-rw-r--r--test/irb/test_type_completor.rb88
-rw-r--r--test/irb/test_workspace.rb6
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb716
-rw-r--r--test/json/json_addition_test.rb4
-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
-rw-r--r--[-rwxr-xr-x]test/json/json_generator_test.rb67
-rw-r--r--test/json/json_generic_object_test.rb2
-rw-r--r--test/json/json_parser_test.rb12
-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.rb93
-rw-r--r--test/logger/test_severity.rb32
-rw-r--r--test/mkmf/base.rb7
-rw-r--r--test/mkmf/test_config.rb29
-rw-r--r--test/mkmf/test_configuration.rb39
-rw-r--r--test/mkmf/test_flags.rb6
-rw-r--r--test/monitor/test_monitor.rb2
-rw-r--r--test/net/http/test_http.rb12
-rw-r--r--test/net/http/test_https.rb10
-rw-r--r--test/objspace/test_objspace.rb92
-rw-r--r--test/open-uri/test_open-uri.rb32
-rw-r--r--test/openssl/fixtures/pkey/dh1024.pem5
-rw-r--r--test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem8
-rw-r--r--test/openssl/test_bn.rb4
-rw-r--r--test/openssl/test_cipher.rb2
-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_ns_spki.rb6
-rw-r--r--test/openssl/test_ossl.rb13
-rw-r--r--test/openssl/test_pkcs12.rb4
-rw-r--r--test/openssl/test_pkey.rb84
-rw-r--r--test/openssl/test_pkey_dh.rb64
-rw-r--r--test/openssl/test_pkey_dsa.rb2
-rw-r--r--test/openssl/test_pkey_ec.rb29
-rw-r--r--test/openssl/test_pkey_rsa.rb2
-rw-r--r--test/openssl/test_provider.rb69
-rw-r--r--test/openssl/test_ssl.rb38
-rw-r--r--test/openssl/test_ssl_session.rb2
-rw-r--r--test/openssl/test_x509ext.rb37
-rw-r--r--test/openssl/test_x509req.rb7
-rw-r--r--test/openssl/utils.rb57
-rw-r--r--test/optparse/test_getopts.rb16
-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/comments_test.rb138
-rw-r--r--test/prism/compiler_test.rb30
-rw-r--r--test/prism/constant_path_node_test.rb56
-rw-r--r--test/prism/desugar_compiler_test.rb86
-rw-r--r--test/prism/dispatcher_test.rb46
-rw-r--r--test/prism/encoding_test.rb349
-rw-r--r--test/prism/errors_test.rb2062
-rw-r--r--test/prism/fixtures/alias.txt23
-rw-r--r--test/prism/fixtures/arithmetic.txt13
-rw-r--r--test/prism/fixtures/arrays.txt142
-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.txt44
-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/embdoc_no_newline_at_end.txt2
-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.txt26
-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.txt19
-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.txt149
-rw-r--r--test/prism/fixtures/methods.txt186
-rw-r--r--test/prism/fixtures/modules.txt18
-rw-r--r--test/prism/fixtures/newline_terminated.txtbin212 -> 0 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.txt202
-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.txt40
-rw-r--r--test/prism/fixtures/rescue.txt31
-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_break.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_next.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/dasgn_icky2.txt8
-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/seattlerb/yield_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/yield_call_assocs.txt11
-rw-r--r--test/prism/fixtures/seattlerb/yield_empty_parens.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/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/control.txt15
-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.txt6
-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.txt7
-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/literal/yield.txt3
-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/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.txt11
-rw-r--r--test/prism/fixtures/whitequark/args_assocs_comma.txt1
-rw-r--r--test/prism/fixtures/whitequark/args_assocs_legacy.txt11
-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/break.txt7
-rw-r--r--test/prism/fixtures/whitequark/break_block.txt1
-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_definition_in_while_cond.txt7
-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_iflipflop.txt3
-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/if_while_after_class__since_32.txt7
-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/method_definition_in_while_cond.txt7
-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/next.txt7
-rw-r--r--test/prism/fixtures/whitequark/next_block.txt1
-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/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_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/redo.txt1
-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/retry.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/yield.txt7
-rw-r--r--test/prism/fixtures/whitequark/zsuper.txt1
-rw-r--r--test/prism/fixtures/xstring.txt7
-rw-r--r--test/prism/fixtures/yield.txt7
-rw-r--r--test/prism/fuzzer_test.rb64
-rw-r--r--test/prism/heredoc_dedent_test.rb27
-rw-r--r--test/prism/library_symbols_test.rb103
-rw-r--r--test/prism/locals_test.rb116
-rw-r--r--test/prism/location_test.rb915
-rw-r--r--test/prism/magic_comment_test.rb37
-rw-r--r--test/prism/memsize_test.rb17
-rw-r--r--test/prism/newline_test.rb93
-rw-r--r--test/prism/parameters_signature_test.rb91
-rw-r--r--test/prism/parse_comments_test.rb21
-rw-r--r--test/prism/parse_test.rb283
-rw-r--r--test/prism/pattern_test.rb132
-rw-r--r--test/prism/regexp_test.rb263
-rw-r--r--test/prism/ripper_compat_test.rb19
-rw-r--r--test/prism/ruby_api_test.rb156
-rw-r--r--test/prism/snapshots/alias.txt193
-rw-r--r--test/prism/snapshots/arithmetic.txt252
-rw-r--r--test/prism/snapshots/arrays.txt2268
-rw-r--r--test/prism/snapshots/begin_ensure.txt253
-rw-r--r--test/prism/snapshots/begin_rescue.txt699
-rw-r--r--test/prism/snapshots/blocks.txt777
-rw-r--r--test/prism/snapshots/boolean_operators.txt54
-rw-r--r--test/prism/snapshots/booleans.txt7
-rw-r--r--test/prism/snapshots/break.txt221
-rw-r--r--test/prism/snapshots/case.txt358
-rw-r--r--test/prism/snapshots/classes.txt358
-rw-r--r--test/prism/snapshots/command_method_call.txt718
-rw-r--r--test/prism/snapshots/comments.txt145
-rw-r--r--test/prism/snapshots/constants.txt1237
-rw-r--r--test/prism/snapshots/dash_heredocs.txt254
-rw-r--r--test/prism/snapshots/defined.txt84
-rw-r--r--test/prism/snapshots/dos_endings.txt108
-rw-r--r--test/prism/snapshots/embdoc_no_newline_at_end.txt5
-rw-r--r--test/prism/snapshots/endless_methods.txt106
-rw-r--r--test/prism/snapshots/endless_range_in_conditional.txt49
-rw-r--r--test/prism/snapshots/for.txt176
-rw-r--r--test/prism/snapshots/global_variables.txt191
-rw-r--r--test/prism/snapshots/hashes.txt366
-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.txt49
-rw-r--r--test/prism/snapshots/heredocs_nested.txt89
-rw-r--r--test/prism/snapshots/heredocs_with_ignored_newlines.txt63
-rw-r--r--test/prism/snapshots/heredocs_with_ignored_newlines_and_non_empty.txt11
-rw-r--r--test/prism/snapshots/if.txt454
-rw-r--r--test/prism/snapshots/indented_file_end.txt19
-rw-r--r--test/prism/snapshots/integer_operations.txt569
-rw-r--r--test/prism/snapshots/keyword_method_names.txt180
-rw-r--r--test/prism/snapshots/keywords.txt12
-rw-r--r--test/prism/snapshots/lambda.txt200
-rw-r--r--test/prism/snapshots/method_calls.txt2345
-rw-r--r--test/prism/snapshots/methods.txt2072
-rw-r--r--test/prism/snapshots/modules.txt180
-rw-r--r--test/prism/snapshots/newline_terminated.txt107
-rw-r--r--test/prism/snapshots/next.txt132
-rw-r--r--test/prism/snapshots/nils.txt32
-rw-r--r--test/prism/snapshots/non_alphanumeric_methods.txt536
-rw-r--r--test/prism/snapshots/not.txt351
-rw-r--r--test/prism/snapshots/numbers.txt108
-rw-r--r--test/prism/snapshots/patterns.txt4761
-rw-r--r--test/prism/snapshots/procs.txt383
-rw-r--r--test/prism/snapshots/range_begin_open_exclusive.txt12
-rw-r--r--test/prism/snapshots/range_begin_open_inclusive.txt12
-rw-r--r--test/prism/snapshots/range_end_open_exclusive.txt12
-rw-r--r--test/prism/snapshots/range_end_open_inclusive.txt12
-rw-r--r--test/prism/snapshots/ranges.txt492
-rw-r--r--test/prism/snapshots/regex.txt371
-rw-r--r--test/prism/snapshots/rescue.txt390
-rw-r--r--test/prism/snapshots/return.txt138
-rw-r--r--test/prism/snapshots/seattlerb/BEGIN.txt14
-rw-r--r--test/prism/snapshots/seattlerb/TestRubyParserShared.txt357
-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.txt21
-rw-r--r--test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt23
-rw-r--r--test/prism/snapshots/seattlerb/args_kw_block.txt37
-rw-r--r--test/prism/snapshots/seattlerb/array_line_breaks.txt24
-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.txt33
-rw-r--r--test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt22
-rw-r--r--test/prism/snapshots/seattlerb/attrasgn_array_arg.txt39
-rw-r--r--test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt79
-rw-r--r--test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt30
-rw-r--r--test/prism/snapshots/seattlerb/backticks_interpolation_line.txt38
-rw-r--r--test/prism/snapshots/seattlerb/bang_eq.txt22
-rw-r--r--test/prism/snapshots/seattlerb/bdot2.txt37
-rw-r--r--test/prism/snapshots/seattlerb/bdot3.txt37
-rw-r--r--test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt16
-rw-r--r--test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt43
-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.txt50
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_opt_splat.txt48
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt54
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_optional.txt42
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_scope.txt39
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_scope2.txt41
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_splat_arg.txt43
-rw-r--r--test/prism/snapshots/seattlerb/block_args_kwargs.txt44
-rw-r--r--test/prism/snapshots/seattlerb/block_args_no_kwargs.txt38
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt1.txt57
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt2.txt49
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt2_2.txt67
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt3.txt74
-rw-r--r--test/prism/snapshots/seattlerb/block_break.txt56
-rw-r--r--test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt81
-rw-r--r--test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt101
-rw-r--r--test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt114
-rw-r--r--test/prism/snapshots/seattlerb/block_call_operation_colon.txt55
-rw-r--r--test/prism/snapshots/seattlerb/block_call_operation_dot.txt55
-rw-r--r--test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt61
-rw-r--r--test/prism/snapshots/seattlerb/block_command_operation_colon.txt50
-rw-r--r--test/prism/snapshots/seattlerb/block_command_operation_dot.txt50
-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.txt50
-rw-r--r--test/prism/snapshots/seattlerb/block_decomp_splat.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_kw.txt41
-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.txt60
-rw-r--r--test/prism/snapshots/seattlerb/block_next.txt56
-rw-r--r--test/prism/snapshots/seattlerb/block_opt_arg.txt44
-rw-r--r--test/prism/snapshots/seattlerb/block_opt_splat.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt52
-rw-r--r--test/prism/snapshots/seattlerb/block_optarg.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_paren_splat.txt48
-rw-r--r--test/prism/snapshots/seattlerb/block_reg_optarg.txt48
-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.txt41
-rw-r--r--test/prism/snapshots/seattlerb/bug169.txt29
-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.txt20
-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.txt61
-rw-r--r--test/prism/snapshots/seattlerb/bug_215.txt14
-rw-r--r--test/prism/snapshots/seattlerb/bug_249.txt88
-rw-r--r--test/prism/snapshots/seattlerb/bug_and.txt21
-rw-r--r--test/prism/snapshots/seattlerb/bug_args__19.txt57
-rw-r--r--test/prism/snapshots/seattlerb/bug_args_masgn.txt47
-rw-r--r--test/prism/snapshots/seattlerb/bug_args_masgn2.txt55
-rw-r--r--test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt53
-rw-r--r--test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt106
-rw-r--r--test/prism/snapshots/seattlerb/bug_case_when_regexp.txt27
-rw-r--r--test/prism/snapshots/seattlerb/bug_comma.txt41
-rw-r--r--test/prism/snapshots/seattlerb/bug_cond_pct.txt21
-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.txt47
-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.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_assoc.txt31
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt40
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_kwsplat.txt36
-rw-r--r--test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt103
-rw-r--r--test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt31
-rw-r--r--test/prism/snapshots/seattlerb/call_args_command.txt53
-rw-r--r--test/prism/snapshots/seattlerb/call_array_arg.txt37
-rw-r--r--test/prism/snapshots/seattlerb/call_array_block_call.txt41
-rw-r--r--test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt43
-rw-r--r--test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt44
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc.txt29
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_new.txt33
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt56
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt29
-rw-r--r--test/prism/snapshots/seattlerb/call_bang_command_call.txt40
-rw-r--r--test/prism/snapshots/seattlerb/call_bang_squiggle.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_begin_call_block_call.txt54
-rw-r--r--test/prism/snapshots/seattlerb/call_block_arg_named.txt28
-rw-r--r--test/prism/snapshots/seattlerb/call_carat.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_colon2.txt17
-rw-r--r--test/prism/snapshots/seattlerb/call_colon_parens.txt17
-rw-r--r--test/prism/snapshots/seattlerb/call_div.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_dot_parens.txt17
-rw-r--r--test/prism/snapshots/seattlerb/call_env.txt25
-rw-r--r--test/prism/snapshots/seattlerb/call_eq3.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_gt.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_kwsplat.txt26
-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.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_lte.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_not.txt17
-rw-r--r--test/prism/snapshots/seattlerb/call_pipe.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_rshift.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_self_brackets.txt21
-rw-r--r--test/prism/snapshots/seattlerb/call_spaceship.txt22
-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.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_star2.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_trailing_comma.txt20
-rw-r--r--test/prism/snapshots/seattlerb/call_trailing_dots.txt35
-rw-r--r--test/prism/snapshots/seattlerb/call_unary_bang.txt17
-rw-r--r--test/prism/snapshots/seattlerb/case_in.txt940
-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.txt32
-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.txt81
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt50
-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.txt32
-rw-r--r--test/prism/snapshots/seattlerb/cond_unary_minus.txt14
-rw-r--r--test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt23
-rw-r--r--test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt17
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_and1.txt18
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_and2.txt17
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_or.txt19
-rw-r--r--test/prism/snapshots/seattlerb/dasgn_icky2.txt62
-rw-r--r--test/prism/snapshots/seattlerb/defined_eh_parens.txt12
-rw-r--r--test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt35
-rw-r--r--test/prism/snapshots/seattlerb/defn_arg_forward_args.txt49
-rw-r--r--test/prism/snapshots/seattlerb/defn_args_forward_args.txt59
-rw-r--r--test/prism/snapshots/seattlerb/defn_comments.txt19
-rw-r--r--test/prism/snapshots/seattlerb/defn_endless_command.txt36
-rw-r--r--test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt42
-rw-r--r--test/prism/snapshots/seattlerb/defn_forward_args.txt44
-rw-r--r--test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt44
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_env.txt55
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt41
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt37
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt37
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt42
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt33
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_val.txt35
-rw-r--r--test/prism/snapshots/seattlerb/defn_no_kwargs.txt30
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner.txt47
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt46
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt31
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt31
-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.txt35
-rw-r--r--test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt40
-rw-r--r--test/prism/snapshots/seattlerb/defn_powarg.txt31
-rw-r--r--test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt42
-rw-r--r--test/prism/snapshots/seattlerb/defn_splat_arg.txt33
-rw-r--r--test/prism/snapshots/seattlerb/defn_unary_not.txt22
-rw-r--r--test/prism/snapshots/seattlerb/defns_reserved.txt20
-rw-r--r--test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt62
-rw-r--r--test/prism/snapshots/seattlerb/defs_comments.txt20
-rw-r--r--test/prism/snapshots/seattlerb/defs_endless_command.txt46
-rw-r--r--test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt52
-rw-r--r--test/prism/snapshots/seattlerb/defs_kwarg.txt34
-rw-r--r--test/prism/snapshots/seattlerb/defs_oneliner.txt48
-rw-r--r--test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt47
-rw-r--r--test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt161
-rw-r--r--test/prism/snapshots/seattlerb/difficult0_.txt72
-rw-r--r--test/prism/snapshots/seattlerb/difficult1_line_numbers.txt253
-rw-r--r--test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt76
-rw-r--r--test/prism/snapshots/seattlerb/difficult2_.txt71
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_.txt50
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_2.txt41
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_3.txt45
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_4.txt38
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_5.txt50
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__10.txt50
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__11.txt46
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__12.txt48
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__6.txt52
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__7.txt48
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__8.txt50
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__9.txt48
-rw-r--r--test/prism/snapshots/seattlerb/difficult4__leading_dots.txt25
-rw-r--r--test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt14
-rw-r--r--test/prism/snapshots/seattlerb/difficult6_.txt60
-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_.txt94
-rw-r--r--test/prism/snapshots/seattlerb/do_bug.txt62
-rw-r--r--test/prism/snapshots/seattlerb/do_lambda.txt18
-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.txt37
-rw-r--r--test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt25
-rw-r--r--test/prism/snapshots/seattlerb/dstr_lex_state.txt34
-rw-r--r--test/prism/snapshots/seattlerb/dstr_str.txt27
-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.txt9
-rw-r--r--test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt49
-rw-r--r--test/prism/snapshots/seattlerb/evstr_evstr.txt41
-rw-r--r--test/prism/snapshots/seattlerb/evstr_str.txt31
-rw-r--r--test/prism/snapshots/seattlerb/expr_not_bang.txt38
-rw-r--r--test/prism/snapshots/seattlerb/f_kw.txt33
-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.txt16
-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.txt25
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_nested.txt40
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly.txt33
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt66
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt33
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_empty.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_interp.txt47
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_no_indent.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_tabs.txt27
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt27
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt33
-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.txt26
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt26
-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.txt23
-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.txt17
-rw-r--r--test/prism/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt24
-rw-r--r--test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt24
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_1.txt39
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_10_1.txt48
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_10_2.txt52
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_11_1.txt50
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_11_2.txt54
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_2__19.txt45
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_3.txt49
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_4.txt43
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_5.txt41
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_6.txt46
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_7_1.txt46
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_7_2.txt50
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_8_1.txt48
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_8_2.txt52
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_9_1.txt44
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_9_2.txt48
-rw-r--r--test/prism/snapshots/seattlerb/iter_kwarg.txt41
-rw-r--r--test/prism/snapshots/seattlerb/iter_kwarg_kwsplat.txt45
-rw-r--r--test/prism/snapshots/seattlerb/label_vs_string.txt34
-rw-r--r--test/prism/snapshots/seattlerb/lambda_do_vs_brace.txt99
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_arg_rescue_arg.txt19
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt32
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt32
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_command.txt36
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_env.txt13
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_ivar_env.txt12
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_lasgn_command_call.txt32
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_middle_splat.txt49
-rw-r--r--test/prism/snapshots/seattlerb/magic_encoding_comment.txt47
-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.txt41
-rw-r--r--test/prism/snapshots/seattlerb/masgn_colon3.txt34
-rw-r--r--test/prism/snapshots/seattlerb/masgn_command_call.txt42
-rw-r--r--test/prism/snapshots/seattlerb/masgn_double_paren.txt35
-rw-r--r--test/prism/snapshots/seattlerb/masgn_lhs_splat.txt30
-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.txt18
-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.txt39
-rw-r--r--test/prism/snapshots/seattlerb/method_call_trailing_comma.txt30
-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.txt35
-rw-r--r--test/prism/snapshots/seattlerb/module_comments.txt30
-rw-r--r--test/prism/snapshots/seattlerb/multiline_hash_declaration.txt95
-rw-r--r--test/prism/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt24
-rw-r--r--test/prism/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt24
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_command_call.txt36
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt31
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_index_command_call.txt51
-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.txt19
-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.txt39
-rw-r--r--test/prism/snapshots/seattlerb/parse_def_special_name.txt19
-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.txt29
-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.txt60
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_complex.txt65
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_no_parens.txt33
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_no_parens_args.txt29
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot2.txt49
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot2_open.txt37
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot3.txt49
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot3_open.txt37
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt20
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dstr_soft_newline.txt20
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_evstr_after_break.txt35
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_hash_lit.txt21
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_heredoc.txt43
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_heredoc_evstr.txt37
-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.txt73
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_iter_call_parens.txt73
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_multiline_str.txt13
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt13
-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.txt31
-rw-r--r--test/prism/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt22
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_019.txt30
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_044.txt38
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_051.txt42
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_058.txt67
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_058_2.txt61
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_069.txt46
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_076.txt56
-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.txt50
-rw-r--r--test/prism/snapshots/seattlerb/pipe_semicolon.txt39
-rw-r--r--test/prism/snapshots/seattlerb/pipe_space.txt37
-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.txt55
-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.txt33
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_ensure_result.txt59
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_no_raise.txt76
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_raised.txt53
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_rescued.txt80
-rw-r--r--test/prism/snapshots/seattlerb/rescue_in_block.txt48
-rw-r--r--test/prism/snapshots/seattlerb/rescue_parens.txt48
-rw-r--r--test/prism/snapshots/seattlerb/return_call_assocs.txt203
-rw-r--r--test/prism/snapshots/seattlerb/rhs_asgn.txt14
-rw-r--r--test/prism/snapshots/seattlerb/ruby21_numbers.txt24
-rw-r--r--test/prism/snapshots/seattlerb/safe_attrasgn.txt30
-rw-r--r--test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt30
-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.txt30
-rw-r--r--test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt31
-rw-r--r--test/prism/snapshots/seattlerb/safe_calls.txt40
-rw-r--r--test/prism/snapshots/seattlerb/safe_op_asgn.txt40
-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.txt45
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_iter_call.txt60
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt55
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_kw.txt32
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_kw__required.txt29
-rw-r--r--test/prism/snapshots/seattlerb/stabby_proc_scope.txt30
-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.txt31
-rw-r--r--test/prism/snapshots/seattlerb/str_evstr_escape.txt37
-rw-r--r--test/prism/snapshots/seattlerb/str_heredoc_interp.txt31
-rw-r--r--test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt104
-rw-r--r--test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt21
-rw-r--r--test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt13
-rw-r--r--test/prism/snapshots/seattlerb/str_pct_Q_nested.txt37
-rw-r--r--test/prism/snapshots/seattlerb/str_pct_nested_nested.txt39
-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.txt27
-rw-r--r--test/prism/snapshots/seattlerb/str_str_str.txt33
-rw-r--r--test/prism/snapshots/seattlerb/super_arg.txt16
-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.txt55
-rw-r--r--test/prism/snapshots/seattlerb/uminus_float.txt6
-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.txt20
-rw-r--r--test/prism/snapshots/seattlerb/when_splat.txt38
-rw-r--r--test/prism/snapshots/seattlerb/words_interp.txt28
-rw-r--r--test/prism/snapshots/seattlerb/yield_arg.txt15
-rw-r--r--test/prism/snapshots/seattlerb/yield_call_assocs.txt215
-rw-r--r--test/prism/snapshots/seattlerb/yield_empty_parens.txt10
-rw-r--r--test/prism/snapshots/single_quote_heredocs.txt11
-rw-r--r--test/prism/snapshots/spanning_heredoc.txt409
-rw-r--r--test/prism/snapshots/strings.txt527
-rw-r--r--test/prism/snapshots/super.txt124
-rw-r--r--test/prism/snapshots/symbols.txt456
-rw-r--r--test/prism/snapshots/ternary_operator.txt293
-rw-r--r--test/prism/snapshots/tilde_heredocs.txt381
-rw-r--r--test/prism/snapshots/undef.txt116
-rw-r--r--test/prism/snapshots/unescaping.txt34
-rw-r--r--test/prism/snapshots/unless.txt132
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/alias.txt29
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/assignment.txt1035
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/block.txt1408
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/case.txt434
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/class.txt234
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/control.txt139
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/def.txt1201
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/defined.txt53
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/defs.txt369
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/dstr.txt340
-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.txt189
-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.txt280
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/kwbegin.txt491
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/lambda.txt149
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/literal.txt1144
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/module.txt108
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/opasgn.txt489
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/pattern.txt424
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/pragma.txt19
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/range.txt49
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/rescue.txt101
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/send.txt2183
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/27.txt49
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/30.txt83
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/31.txt89
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/32.txt106
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/singletons.txt9
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/super.txt282
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/unary.txt245
-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.txt705
-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.txt195
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/def.txt92
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/dstr.txt570
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/kwbegin.txt259
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/literal.txt94
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/send.txt162
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/undef.txt29
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/while.txt281
-rw-r--r--test/prism/snapshots/until.txt141
-rw-r--r--test/prism/snapshots/variables.txt379
-rw-r--r--test/prism/snapshots/while.txt365
-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.txt55
-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.txt55
-rw-r--r--test/prism/snapshots/whitequark/arg_duplicate_ignored.txt57
-rw-r--r--test/prism/snapshots/whitequark/arg_label.txt118
-rw-r--r--test/prism/snapshots/whitequark/arg_scope.txt34
-rw-r--r--test/prism/snapshots/whitequark/args.txt1024
-rw-r--r--test/prism/snapshots/whitequark/args_args_assocs.txt94
-rw-r--r--test/prism/snapshots/whitequark/args_args_assocs_comma.txt53
-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.txt189
-rw-r--r--test/prism/snapshots/whitequark/args_assocs_comma.txt43
-rw-r--r--test/prism/snapshots/whitequark/args_assocs_legacy.txt189
-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.txt39
-rw-r--r--test/prism/snapshots/whitequark/array_plain.txt14
-rw-r--r--test/prism/snapshots/whitequark/array_splat.txt65
-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.txt78
-rw-r--r--test/prism/snapshots/whitequark/asgn_cmd.txt55
-rw-r--r--test/prism/snapshots/whitequark/asgn_mrhs.txt86
-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.txt50
-rw-r--r--test/prism/snapshots/whitequark/beginless_erange_after_newline.txt22
-rw-r--r--test/prism/snapshots/whitequark/beginless_irange_after_newline.txt22
-rw-r--r--test/prism/snapshots/whitequark/beginless_range.txt19
-rw-r--r--test/prism/snapshots/whitequark/blockarg.txt31
-rw-r--r--test/prism/snapshots/whitequark/blockargs.txt1288
-rw-r--r--test/prism/snapshots/whitequark/break.txt56
-rw-r--r--test/prism/snapshots/whitequark/break_block.txt41
-rw-r--r--test/prism/snapshots/whitequark/bug_435.txt38
-rw-r--r--test/prism/snapshots/whitequark/bug_447.txt57
-rw-r--r--test/prism/snapshots/whitequark/bug_452.txt63
-rw-r--r--test/prism/snapshots/whitequark/bug_466.txt68
-rw-r--r--test/prism/snapshots/whitequark/bug_473.txt33
-rw-r--r--test/prism/snapshots/whitequark/bug_480.txt36
-rw-r--r--test/prism/snapshots/whitequark/bug_481.txt51
-rw-r--r--test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt11
-rw-r--r--test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt31
-rw-r--r--test/prism/snapshots/whitequark/bug_cmdarg.txt108
-rw-r--r--test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt19
-rw-r--r--test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt52
-rw-r--r--test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt41
-rw-r--r--test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt394
-rw-r--r--test/prism/snapshots/whitequark/bug_heredoc_do.txt31
-rw-r--r--test/prism/snapshots/whitequark/bug_interp_single.txt34
-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.txt33
-rw-r--r--test/prism/snapshots/whitequark/case_cond_else.txt45
-rw-r--r--test/prism/snapshots/whitequark/case_expr.txt43
-rw-r--r--test/prism/snapshots/whitequark/case_expr_else.txt59
-rw-r--r--test/prism/snapshots/whitequark/casgn_scoped.txt19
-rw-r--r--test/prism/snapshots/whitequark/casgn_toplevel.txt17
-rw-r--r--test/prism/snapshots/whitequark/casgn_unscoped.txt12
-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_definition_in_while_cond.txt175
-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.txt23
-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_iflipflop.txt78
-rw-r--r--test/prism/snapshots/whitequark/cond_match_current_line.txt34
-rw-r--r--test/prism/snapshots/whitequark/const_op_asgn.txt98
-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.txt12
-rw-r--r--test/prism/snapshots/whitequark/dedenting_heredoc.txt485
-rw-r--r--test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt21
-rw-r--r--test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt21
-rw-r--r--test/prism/snapshots/whitequark/def.txt89
-rw-r--r--test/prism/snapshots/whitequark/defined.txt42
-rw-r--r--test/prism/snapshots/whitequark/defs.txt95
-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.txt149
-rw-r--r--test/prism/snapshots/whitequark/endless_method_command_syntax.txt396
-rw-r--r--test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt44
-rw-r--r--test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt54
-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.txt7
-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.txt44
-rw-r--r--test/prism/snapshots/whitequark/forward_arg_with_open_args.txt404
-rw-r--r--test/prism/snapshots/whitequark/forward_args_legacy.txt102
-rw-r--r--test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt57
-rw-r--r--test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt54
-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.txt12
-rw-r--r--test/prism/snapshots/whitequark/hash_empty.txt9
-rw-r--r--test/prism/snapshots/whitequark/hash_hashrocket.txt45
-rw-r--r--test/prism/snapshots/whitequark/hash_kwsplat.txt34
-rw-r--r--test/prism/snapshots/whitequark/hash_label.txt21
-rw-r--r--test/prism/snapshots/whitequark/hash_label_end.txt97
-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.txt63
-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/if_while_after_class__since_32.txt119
-rw-r--r--test/prism/snapshots/whitequark/int.txt11
-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.txt12
-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.txt87
-rw-r--r--test/prism/snapshots/whitequark/kwoptarg.txt33
-rw-r--r--test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt57
-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.txt56
-rw-r--r--test/prism/snapshots/whitequark/lparenarg_after_lvar__since_25.txt65
-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.txt16
-rw-r--r--test/prism/snapshots/whitequark/masgn.txt77
-rw-r--r--test/prism/snapshots/whitequark/masgn_attr.txt80
-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/method_definition_in_while_cond.txt205
-rw-r--r--test/prism/snapshots/whitequark/module.txt14
-rw-r--r--test/prism/snapshots/whitequark/multiple_pattern_matches.txt149
-rw-r--r--test/prism/snapshots/whitequark/newline_in_hash_argument.txt149
-rw-r--r--test/prism/snapshots/whitequark/next.txt56
-rw-r--r--test/prism/snapshots/whitequark/next_block.txt41
-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.txt43
-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.txt147
-rw-r--r--test/prism/snapshots/whitequark/numparam_outside_block.txt115
-rw-r--r--test/prism/snapshots/whitequark/op_asgn.txt71
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_cmd.txt178
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_index.txt35
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_index_cmd.txt56
-rw-r--r--test/prism/snapshots/whitequark/optarg.txt70
-rw-r--r--test/prism/snapshots/whitequark/or.txt53
-rw-r--r--test/prism/snapshots/whitequark/or_asgn.txt55
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_272.txt42
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_490.txt109
-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.txt67
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_604.txt58
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_640.txt11
-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_drops_truncated_parts_of_squiggly_heredoc.txt19
-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.txt51
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_blank_else.txt28
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_else.txt32
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_single_line.txt43
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt233
-rw-r--r--test/prism/snapshots/whitequark/postexe.txt14
-rw-r--r--test/prism/snapshots/whitequark/preexe.txt14
-rw-r--r--test/prism/snapshots/whitequark/procarg0.txt77
-rw-r--r--test/prism/snapshots/whitequark/range_exclusive.txt14
-rw-r--r--test/prism/snapshots/whitequark/range_inclusive.txt14
-rw-r--r--test/prism/snapshots/whitequark/rational.txt12
-rw-r--r--test/prism/snapshots/whitequark/redo.txt6
-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.txt27
-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.txt42
-rw-r--r--test/prism/snapshots/whitequark/rescue_mod_op_assign.txt36
-rw-r--r--test/prism/snapshots/whitequark/rescue_without_begin_end.txt60
-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/retry.txt6
-rw-r--r--test/prism/snapshots/whitequark/return.txt56
-rw-r--r--test/prism/snapshots/whitequark/return_block.txt41
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_10279.txt31
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_10653.txt175
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11107.txt50
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11380.txt56
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873.txt785
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873_a.txt1245
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873_b.txt100
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11989.txt24
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11990.txt34
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12073.txt94
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12402.txt565
-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.txt32
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_14690.txt61
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_15789.txt122
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_9669.txt57
-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.txt102
-rw-r--r--test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt30
-rw-r--r--test/prism/snapshots/whitequark/send_binary_op.txt530
-rw-r--r--test/prism/snapshots/whitequark/send_block_chain_cmd.txt328
-rw-r--r--test/prism/snapshots/whitequark/send_block_conditional.txt32
-rw-r--r--test/prism/snapshots/whitequark/send_call.txt55
-rw-r--r--test/prism/snapshots/whitequark/send_conditional.txt25
-rw-r--r--test/prism/snapshots/whitequark/send_index.txt32
-rw-r--r--test/prism/snapshots/whitequark/send_index_asgn.txt34
-rw-r--r--test/prism/snapshots/whitequark/send_index_asgn_legacy.txt34
-rw-r--r--test/prism/snapshots/whitequark/send_index_cmd.txt51
-rw-r--r--test/prism/snapshots/whitequark/send_index_legacy.txt32
-rw-r--r--test/prism/snapshots/whitequark/send_lambda.txt46
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_args.txt51
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_args_noparen.txt56
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_args_shadow.txt32
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_legacy.txt13
-rw-r--r--test/prism/snapshots/whitequark/send_op_asgn_conditional.txt26
-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.txt40
-rw-r--r--test/prism/snapshots/whitequark/send_self_block.txt78
-rw-r--r--test/prism/snapshots/whitequark/send_unary_op.txt65
-rw-r--r--test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt27
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg.txt26
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg_block.txt109
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg_call.txt36
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg_newline.txt26
-rw-r--r--test/prism/snapshots/whitequark/space_args_block.txt29
-rw-r--r--test/prism/snapshots/whitequark/space_args_cmd.txt47
-rw-r--r--test/prism/snapshots/whitequark/string___FILE__.txt7
-rw-r--r--test/prism/snapshots/whitequark/string_concat.txt30
-rw-r--r--test/prism/snapshots/whitequark/string_dvar.txt36
-rw-r--r--test/prism/snapshots/whitequark/string_interp.txt37
-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.txt50
-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.txt34
-rw-r--r--test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt49
-rw-r--r--test/prism/snapshots/whitequark/trailing_forward_arg.txt53
-rw-r--r--test/prism/snapshots/whitequark/true.txt6
-rw-r--r--test/prism/snapshots/whitequark/unary_num_pow_precedence.txt74
-rw-r--r--test/prism/snapshots/whitequark/undef.txt38
-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.txt13
-rw-r--r--test/prism/snapshots/whitequark/var_op_asgn.txt54
-rw-r--r--test/prism/snapshots/whitequark/var_op_asgn_cmd.txt28
-rw-r--r--test/prism/snapshots/whitequark/var_or_asgn.txt13
-rw-r--r--test/prism/snapshots/whitequark/when_multi.txt49
-rw-r--r--test/prism/snapshots/whitequark/when_splat.txt69
-rw-r--r--test/prism/snapshots/whitequark/when_then.txt43
-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.txt55
-rw-r--r--test/prism/snapshots/yield.txt39
-rw-r--r--test/prism/test_helper.rb91
-rw-r--r--test/prism/unescape_test.rb235
-rw-r--r--test/prism/version_test.rb11
-rw-r--r--test/psych/test_encoding.rb4
-rw-r--r--test/psych/test_numeric.rb9
-rw-r--r--test/psych/test_object_references.rb8
-rw-r--r--test/psych/test_parser.rb23
-rw-r--r--test/psych/test_psych.rb7
-rw-r--r--test/psych/test_yaml.rb32
-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.rb111
-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/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_section.rb1
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb35
-rw-r--r--test/rdoc/test_rdoc_generator_markup.rb1
-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.rb41
-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.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_rdoc.rb1
-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.rb20
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb39
-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.rb15
-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_inline.rb1
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb14
-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.rb8
-rw-r--r--test/rdoc/test_rdoc_task.rb9
-rw-r--r--test/rdoc/test_rdoc_token_stream.rb17
-rw-r--r--test/rdoc/xref_data.rb1
-rw-r--r--test/rdoc/xref_test_case.rb1
-rw-r--r--test/readline/helper.rb29
-rw-r--r--test/readline/test_readline.rb955
-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.rb137
-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.rb1918
-rw-r--r--test/reline/test_key_actor_vi.rb1294
-rw-r--r--test/reline/test_key_stroke.rb26
-rw-r--r--test/reline/test_line_editor.rb185
-rw-r--r--test/reline/test_macro.rb3
-rw-r--r--test/reline/test_reline.rb34
-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.rb67
-rw-r--r--test/reline/test_within_pipe.rb9
-rwxr-xr-xtest/reline/yamatanooroti/multiline_repl64
-rw-r--r--test/reline/yamatanooroti/termination_checker.rb38
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb627
-rw-r--r--test/resolv/test_dns.rb208
-rw-r--r--test/resolv/test_resource.rb8
-rw-r--r--test/resolv/test_svcb_https.rb231
-rw-r--r--test/rinda/test_rinda.rb4
-rw-r--r--test/ripper/assert_parse_files.rb25
-rw-r--r--test/ripper/dummyparser.rb53
-rw-r--r--test/ripper/test_lexer.rb68
-rw-r--r--test/ripper/test_parser_events.rb5
-rw-r--r--test/ripper/test_ripper.rb7
-rw-r--r--test/ripper/test_scanner_events.rb28
-rw-r--r--test/ripper/test_sexp.rb26
-rw-r--r--test/ruby/enc/test_case_comprehensive.rb2
-rw-r--r--test/ruby/enc/test_emoji_breaks.rb2
-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_argf.rb1
-rw-r--r--test/ruby/test_arity.rb1
-rw-r--r--test/ruby/test_array.rb31
-rw-r--r--test/ruby/test_assignment.rb10
-rw-r--r--test/ruby/test_ast.rb175
-rw-r--r--test/ruby/test_autoload.rb5
-rw-r--r--test/ruby/test_backtrace.rb6
-rw-r--r--test/ruby/test_beginendblock.rb9
-rw-r--r--test/ruby/test_bignum.rb6
-rw-r--r--test/ruby/test_call.rb1212
-rw-r--r--test/ruby/test_class.rb11
-rw-r--r--test/ruby/test_comparable.rb10
-rw-r--r--test/ruby/test_compile_prism.rb2110
-rw-r--r--test/ruby/test_complex.rb65
-rw-r--r--test/ruby/test_data.rb34
-rw-r--r--test/ruby/test_default_gems.rb19
-rw-r--r--test/ruby/test_defined.rb14
-rw-r--r--test/ruby/test_dir.rb96
-rw-r--r--test/ruby/test_econv.rb2
-rw-r--r--test/ruby/test_encoding.rb50
-rw-r--r--test/ruby/test_enum.rb12
-rw-r--r--test/ruby/test_enumerator.rb47
-rw-r--r--test/ruby/test_env.rb16
-rw-r--r--test/ruby/test_eval.rb7
-rw-r--r--test/ruby/test_exception.rb21
-rw-r--r--test/ruby/test_fiber.rb2
-rw-r--r--test/ruby/test_file_exhaustive.rb9
-rw-r--r--test/ruby/test_float.rb31
-rw-r--r--test/ruby/test_gc.rb386
-rw-r--r--test/ruby/test_gc_compact.rb52
-rw-r--r--test/ruby/test_hash.rb783
-rw-r--r--test/ruby/test_integer.rb83
-rw-r--r--test/ruby/test_integer_comb.rb23
-rw-r--r--test/ruby/test_io.rb188
-rw-r--r--test/ruby/test_io_buffer.rb151
-rw-r--r--test/ruby/test_io_m17n.rb104
-rw-r--r--test/ruby/test_iseq.rb65
-rw-r--r--test/ruby/test_keyword.rb36
-rw-r--r--test/ruby/test_lambda.rb26
-rw-r--r--test/ruby/test_lazy_enumerator.rb5
-rw-r--r--test/ruby/test_m17n.rb18
-rw-r--r--test/ruby/test_marshal.rb10
-rw-r--r--test/ruby/test_math.rb10
-rw-r--r--test/ruby/test_method.rb91
-rw-r--r--test/ruby/test_mjit.rb1327
-rw-r--r--test/ruby/test_mjit_debug.rb17
-rw-r--r--test/ruby/test_module.rb19
-rw-r--r--test/ruby/test_nomethod_error.rb2
-rw-r--r--test/ruby/test_object.rb47
-rw-r--r--test/ruby/test_optimization.rb13
-rw-r--r--test/ruby/test_pack.rb54
-rw-r--r--test/ruby/test_parse.rb227
-rw-r--r--test/ruby/test_pattern_matching.rb18
-rw-r--r--test/ruby/test_proc.rb74
-rw-r--r--test/ruby/test_process.rb244
-rw-r--r--test/ruby/test_random_formatter.rb55
-rw-r--r--test/ruby/test_range.rb236
-rw-r--r--test/ruby/test_refinement.rb69
-rw-r--r--test/ruby/test_regexp.rb370
-rw-r--r--test/ruby/test_require.rb11
-rw-r--r--test/ruby/test_require_lib.rb31
-rw-r--r--test/ruby/test_rubyoptions.rb285
-rw-r--r--test/ruby/test_rubyvm_mjit.rb105
-rw-r--r--test/ruby/test_settracefunc.rb186
-rw-r--r--test/ruby/test_shapes.rb612
-rw-r--r--test/ruby/test_signal.rb43
-rw-r--r--test/ruby/test_sprintf.rb12
-rw-r--r--test/ruby/test_stack.rb1
-rw-r--r--test/ruby/test_string.rb572
-rw-r--r--test/ruby/test_string_memory.rb55
-rw-r--r--test/ruby/test_struct.rb8
-rw-r--r--test/ruby/test_super.rb41
-rw-r--r--test/ruby/test_symbol.rb7
-rw-r--r--test/ruby/test_syntax.rb273
-rw-r--r--test/ruby/test_system.rb13
-rw-r--r--test/ruby/test_thread.rb41
-rw-r--r--test/ruby/test_thread_cv.rb6
-rw-r--r--test/ruby/test_thread_queue.rb34
-rw-r--r--test/ruby/test_time.rb10
-rw-r--r--test/ruby/test_transcode.rb498
-rw-r--r--test/ruby/test_variable.rb105
-rw-r--r--test/ruby/test_vm_dump.rb2
-rw-r--r--test/ruby/test_weakkeymap.rb145
-rw-r--r--test/ruby/test_weakmap.rb49
-rw-r--r--test/ruby/test_whileuntil.rb18
-rw-r--r--test/ruby/test_yjit.rb438
-rw-r--r--test/ruby/test_yjit_exit_locations.rb20
-rw-r--r--test/rubygems/bundler_test_gem.rb51
-rw-r--r--test/rubygems/helper.rb363
-rw-r--r--test/rubygems/installer_test_case.rb16
-rw-r--r--test/rubygems/mock_gem_ui.rb86
-rw-r--r--test/rubygems/package/tar_test_case.rb6
-rw-r--r--test/rubygems/plugin/exception/rubygems_plugin.rb4
-rw-r--r--test/rubygems/plugin/scripterror/rubygems_plugin.rb4
-rw-r--r--test/rubygems/specifications/rubyforge-0.0.1.gemspec21
-rw-r--r--test/rubygems/test_bundled_ca.rb6
-rw-r--r--test/rubygems/test_config.rb4
-rw-r--r--test/rubygems/test_deprecate.rb8
-rw-r--r--test/rubygems/test_gem.rb191
-rw-r--r--test/rubygems/test_gem_available_set.rb6
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb2
-rw-r--r--test/rubygems/test_gem_ci_detector.rb32
-rw-r--r--test/rubygems/test_gem_command.rb47
-rw-r--r--test/rubygems/test_gem_command_manager.rb70
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb17
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb67
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb18
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb14
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb49
-rw-r--r--test/rubygems/test_gem_commands_exec_command.rb88
-rw-r--r--test/rubygems/test_gem_commands_generate_index_command.rb81
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb4
-rw-r--r--test/rubygems/test_gem_commands_info_command.rb12
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb118
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb2
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb13
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb32
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb19
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb33
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb64
-rw-r--r--test/rubygems/test_gem_commands_rebuild_command.rb145
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb51
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb99
-rw-r--r--test/rubygems/test_gem_commands_signout_command.rb6
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb30
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb4
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb32
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb8
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb52
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb12
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb8
-rw-r--r--test/rubygems/test_gem_config_file.rb92
-rw-r--r--test/rubygems/test_gem_console_ui.rb19
-rw-r--r--test/rubygems/test_gem_dependency.rb19
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb183
-rw-r--r--test/rubygems/test_gem_dependency_list.rb12
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb14
-rw-r--r--test/rubygems/test_gem_ext_builder.rb148
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder.rb14
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock44
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock34
-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_unit.rb2
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb14
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb2
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb17
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb22
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb39
-rw-r--r--test/rubygems/test_gem_indexer.rb381
-rw-r--r--test/rubygems/test_gem_install_update_options.rb25
-rw-r--r--test/rubygems/test_gem_installer.rb249
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb12
-rw-r--r--test/rubygems/test_gem_name_tuple.rb33
-rw-r--r--test/rubygems/test_gem_package.rb279
-rw-r--r--test/rubygems/test_gem_package_old.rb6
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb90
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb25
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb72
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb88
-rw-r--r--test/rubygems/test_gem_package_task.rb4
-rw-r--r--test/rubygems/test_gem_platform.rb25
-rw-r--r--test/rubygems/test_gem_rdoc.rb4
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb242
-rw-r--r--test/rubygems/test_gem_request.rb113
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb24
-rw-r--r--test/rubygems/test_gem_request_set.rb58
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb160
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb16
-rw-r--r--test/rubygems/test_gem_requirement.rb18
-rw-r--r--test/rubygems/test_gem_resolver.rb80
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb14
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb111
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb68
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb40
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb10
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb24
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb3
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb28
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb9
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb22
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb6
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb14
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb2
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb3
-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.rb60
-rw-r--r--test/rubygems/test_gem_security_policy.rb60
-rw-r--r--test/rubygems/test_gem_security_signer.rb18
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb18
-rw-r--r--test/rubygems/test_gem_silent_ui.rb3
-rw-r--r--test/rubygems/test_gem_source.rb38
-rw-r--r--test/rubygems/test_gem_source_git.rb8
-rw-r--r--test/rubygems/test_gem_source_installed.rb2
-rw-r--r--test/rubygems/test_gem_source_list.rb4
-rw-r--r--test/rubygems/test_gem_source_local.rb4
-rw-r--r--test/rubygems/test_gem_source_lock.rb4
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb4
-rw-r--r--test/rubygems/test_gem_source_subpath_problem.rb6
-rw-r--r--test/rubygems/test_gem_source_vendor.rb2
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb14
-rw-r--r--test/rubygems/test_gem_specification.rb417
-rw-r--r--test/rubygems/test_gem_stream_ui.rb18
-rw-r--r--test/rubygems/test_gem_stub_specification.rb2
-rw-r--r--test/rubygems/test_gem_uninstaller.rb187
-rw-r--r--test/rubygems/test_gem_update_suggestion.rb152
-rw-r--r--test/rubygems/test_gem_util.rb14
-rw-r--r--test/rubygems/test_gem_version.rb6
-rw-r--r--test/rubygems/test_gem_version_option.rb48
-rw-r--r--test/rubygems/test_kernel.rb20
-rw-r--r--test/rubygems/test_remote_fetch_error.rb2
-rw-r--r--test/rubygems/test_require.rb98
-rw-r--r--test/rubygems/test_rubygems.rb10
-rw-r--r--test/rubygems/test_webauthn_listener.rb32
-rw-r--r--test/rubygems/test_webauthn_poller.rb20
-rw-r--r--test/rubygems/utilities.rb39
-rw-r--r--test/runner.rb13
-rw-r--r--test/set/test_set.rb892
-rw-r--r--test/socket/test_addrinfo.rb4
-rw-r--r--test/socket/test_socket.rb36
-rw-r--r--test/socket/test_tcp.rb2
-rw-r--r--test/socket/test_unix.rb68
-rw-r--r--test/stringio/test_stringio.rb38
-rw-r--r--test/strscan/test_stringscanner.rb4
-rw-r--r--test/test_extlibs.rb2
-rw-r--r--test/test_ipaddr.rb20
-rw-r--r--test/test_mutex_m.rb21
-rw-r--r--test/test_open3.rb10
-rw-r--r--test/test_pp.rb13
-rw-r--r--test/test_set.rb879
-rw-r--r--test/test_singleton.rb21
-rw-r--r--test/test_sorted_set.rb (renamed from test/set/test_sorted_set.rb)0
-rw-r--r--test/test_tempfile.rb27
-rw-r--r--test/test_timeout.rb110
-rw-r--r--test/test_tmpdir.rb16
-rw-r--r--test/test_trick.rb59
-rw-r--r--test/test_unicode_normalize.rb2
-rw-r--r--test/uri/test_common.rb10
-rw-r--r--test/uri/test_ftp.rb10
-rw-r--r--test/uri/test_generic.rb22
-rw-r--r--test/uri/test_http.rb8
-rw-r--r--test/uri/test_ldap.rb8
-rw-r--r--test/uri/test_parser.rb8
-rw-r--r--test/uri/test_ws.rb8
-rw-r--r--test/uri/test_wss.rb8
-rw-r--r--test/win32ole/test_win32ole.rb2
-rw-r--r--test/zlib/test_zlib.rb55
-rw-r--r--thread.c820
-rw-r--r--thread_none.c58
-rw-r--r--thread_none.h1
-rw-r--r--thread_pthread.c3264
-rw-r--r--thread_pthread.h121
-rw-r--r--thread_pthread_mn.c1046
-rw-r--r--thread_sync.c265
-rw-r--r--thread_win32.c196
-rw-r--r--thread_win32.h7
-rw-r--r--time.c364
-rw-r--r--timev.rb65
-rw-r--r--tool/bundler/dev_gems.rb9
-rw-r--r--tool/bundler/dev_gems.rb.lock57
-rw-r--r--tool/bundler/rubocop_gems.rb2
-rw-r--r--tool/bundler/rubocop_gems.rb.lock73
-rw-r--r--tool/bundler/standard_gems.rb.lock81
-rw-r--r--tool/bundler/test_gems.rb10
-rw-r--r--tool/bundler/test_gems.rb.lock45
-rw-r--r--tool/bundler/vendor_gems.rb15
-rw-r--r--tool/bundler/vendor_gems.rb.lock71
-rw-r--r--tool/ci_functions.sh29
-rwxr-xr-xtool/darwin-ar6
-rwxr-xr-xtool/darwin-cc3
-rw-r--r--tool/downloader.rb1
-rwxr-xr-xtool/enc-case-folding.rb6
-rwxr-xr-xtool/enc-unicode.rb101
-rwxr-xr-xtool/extlibs.rb2
-rwxr-xr-xtool/fetch-bundled_gems.rb10
-rwxr-xr-xtool/format-release4
-rwxr-xr-xtool/gen-github-release.rb59
-rwxr-xr-xtool/leaked-globals44
-rw-r--r--tool/lib/bundled_gem.rb53
-rw-r--r--tool/lib/colorize.rb32
-rw-r--r--tool/lib/core_assertions.rb41
-rw-r--r--tool/lib/envutil.rb49
-rw-r--r--tool/lib/iseq_loader_checker.rb9
-rw-r--r--tool/lib/memory_status.rb2
-rw-r--r--tool/lib/output.rb12
-rw-r--r--tool/lib/test/unit.rb112
-rw-r--r--tool/lib/test/unit/parallel.rb12
-rw-r--r--tool/lib/test/unit/testcase.rb22
-rw-r--r--tool/lib/vcs.rb59
-rwxr-xr-xtool/ln_sr.rb2
-rw-r--r--tool/lrama/LEGAL.md12
-rw-r--r--tool/lrama/MIT21
-rw-r--r--tool/lrama/NEWS.md167
-rwxr-xr-xtool/lrama/exe/lrama6
-rw-r--r--tool/lrama/lib/lrama.rb17
-rw-r--r--tool/lrama/lib/lrama/bitmap.rb29
-rw-r--r--tool/lrama/lib/lrama/command.rb46
-rw-r--r--tool/lrama/lib/lrama/context.rb517
-rw-r--r--tool/lrama/lib/lrama/counterexamples.rb286
-rw-r--r--tool/lrama/lib/lrama/counterexamples/derivation.rb63
-rw-r--r--tool/lrama/lib/lrama/counterexamples/example.rb124
-rw-r--r--tool/lrama/lib/lrama/counterexamples/path.rb23
-rw-r--r--tool/lrama/lib/lrama/counterexamples/production_path.rb17
-rw-r--r--tool/lrama/lib/lrama/counterexamples/start_path.rb21
-rw-r--r--tool/lrama/lib/lrama/counterexamples/state_item.rb6
-rw-r--r--tool/lrama/lib/lrama/counterexamples/transition_path.rb17
-rw-r--r--tool/lrama/lib/lrama/counterexamples/triple.rb21
-rw-r--r--tool/lrama/lib/lrama/digraph.rb51
-rw-r--r--tool/lrama/lib/lrama/grammar.rb612
-rw-r--r--tool/lrama/lib/lrama/grammar/auxiliary.rb7
-rw-r--r--tool/lrama/lib/lrama/grammar/code.rb38
-rw-r--r--tool/lrama/lib/lrama/grammar/code/initial_action_code.rb28
-rw-r--r--tool/lrama/lib/lrama/grammar/code/no_reference_code.rb24
-rw-r--r--tool/lrama/lib/lrama/grammar/code/printer_code.rb34
-rw-r--r--tool/lrama/lib/lrama/grammar/code/rule_action.rb78
-rw-r--r--tool/lrama/lib/lrama/grammar/counter.rb15
-rw-r--r--tool/lrama/lib/lrama/grammar/error_token.rb9
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb60
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb36
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb28
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb28
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb28
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb39
-rw-r--r--tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb34
-rw-r--r--tool/lrama/lib/lrama/grammar/percent_code.rb12
-rw-r--r--tool/lrama/lib/lrama/grammar/precedence.rb11
-rw-r--r--tool/lrama/lib/lrama/grammar/printer.rb9
-rw-r--r--tool/lrama/lib/lrama/grammar/reference.rb13
-rw-r--r--tool/lrama/lib/lrama/grammar/rule.rb56
-rw-r--r--tool/lrama/lib/lrama/grammar/rule_builder.rb177
-rw-r--r--tool/lrama/lib/lrama/grammar/symbol.rb101
-rw-r--r--tool/lrama/lib/lrama/grammar/type.rb6
-rw-r--r--tool/lrama/lib/lrama/grammar/union.rb10
-rw-r--r--tool/lrama/lib/lrama/lexer.rb174
-rw-r--r--tool/lrama/lib/lrama/lexer/location.rb22
-rw-r--r--tool/lrama/lib/lrama/lexer/token.rb51
-rw-r--r--tool/lrama/lib/lrama/lexer/token/char.rb8
-rw-r--r--tool/lrama/lib/lrama/lexer/token/ident.rb8
-rw-r--r--tool/lrama/lib/lrama/lexer/token/parameterizing.rb34
-rw-r--r--tool/lrama/lib/lrama/lexer/token/tag.rb12
-rw-r--r--tool/lrama/lib/lrama/lexer/token/user_code.rb64
-rw-r--r--tool/lrama/lib/lrama/option_parser.rb128
-rw-r--r--tool/lrama/lib/lrama/options.rb23
-rw-r--r--tool/lrama/lib/lrama/output.rb417
-rw-r--r--tool/lrama/lib/lrama/parser.rb1934
-rw-r--r--tool/lrama/lib/lrama/report.rb2
-rw-r--r--tool/lrama/lib/lrama/report/duration.rb25
-rw-r--r--tool/lrama/lib/lrama/report/profile.rb14
-rw-r--r--tool/lrama/lib/lrama/state.rb166
-rw-r--r--tool/lrama/lib/lrama/state/reduce.rb35
-rw-r--r--tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb9
-rw-r--r--tool/lrama/lib/lrama/state/resolved_conflict.rb29
-rw-r--r--tool/lrama/lib/lrama/state/shift.rb13
-rw-r--r--tool/lrama/lib/lrama/state/shift_reduce_conflict.rb9
-rw-r--r--tool/lrama/lib/lrama/states.rb556
-rw-r--r--tool/lrama/lib/lrama/states/item.rb79
-rw-r--r--tool/lrama/lib/lrama/states_reporter.rb323
-rw-r--r--tool/lrama/lib/lrama/version.rb3
-rw-r--r--tool/lrama/lib/lrama/warning.rb25
-rw-r--r--tool/lrama/template/bison/_yacc.h71
-rw-r--r--tool/lrama/template/bison/yacc.c2052
-rw-r--r--tool/lrama/template/bison/yacc.h40
-rw-r--r--tool/m4/ruby_check_header.m48
-rw-r--r--tool/m4/ruby_default_arch.m421
-rw-r--r--tool/m4/ruby_stack_grow_direction.m42
-rw-r--r--tool/m4/ruby_universal_arch.m44
-rwxr-xr-xtool/make-snapshot44
-rwxr-xr-xtool/merger.rb3
-rwxr-xr-xtool/missing-baseruby.bat5
-rwxr-xr-xtool/mjit/bindgen.rb435
-rw-r--r--tool/mjit_archflag.sh40
-rw-r--r--tool/mjit_tabs.rb67
-rw-r--r--tool/mk_builtin_loader.rb79
-rwxr-xr-xtool/mkconfig.rb18
-rwxr-xr-xtool/rbinstall.rb111
-rw-r--r--tool/rbs_skip_tests24
-rwxr-xr-xtool/redmine-backporter.rb33
-rwxr-xr-xtool/rjit/bindgen.rb663
-rw-r--r--tool/ruby_vm/helpers/c_escape.rb5
-rw-r--r--tool/ruby_vm/models/attribute.rb2
-rwxr-xr-xtool/ruby_vm/models/bare_instructions.rb16
-rw-r--r--tool/ruby_vm/models/c_expr.rb6
-rw-r--r--tool/ruby_vm/models/operands_unifications.rb8
-rw-r--r--tool/ruby_vm/views/_comptime_insn_stack_increase.erb2
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb9
-rw-r--r--tool/ruby_vm/views/_leaf_helpers.erb2
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb40
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb14
-rw-r--r--tool/ruby_vm/views/mjit_sp_inc.inc.erb17
-rw-r--r--tool/ruby_vm/views/opt_sc.inc.erb40
-rw-r--r--tool/ruby_vm/views/optinsn.inc.erb4
-rw-r--r--tool/rubyspec_temp.rb13
-rwxr-xr-xtool/runruby.rb9
-rwxr-xr-xtool/sync_default_gems.rb499
-rw-r--r--tool/test-bundled-gems.rb10
-rw-r--r--tool/test-coverage.rb21
-rw-r--r--tool/test/init.rb18
-rw-r--r--tool/test/runner.rb13
-rwxr-xr-xtool/test/test_sync_default_gems.rb221
-rw-r--r--tool/test/testunit/test4test_load_failure.rb1
-rw-r--r--tool/test/testunit/test4test_timeout.rb15
-rw-r--r--tool/test/testunit/test_hideskip.rb4
-rw-r--r--tool/test/testunit/test_load_failure.rb23
-rw-r--r--tool/test/testunit/test_parallel.rb27
-rw-r--r--tool/test/testunit/test_sorting.rb2
-rw-r--r--tool/test/testunit/test_timeout.rb10
-rw-r--r--tool/test/testunit/tests_for_parallel/slow_helper.rb7
-rw-r--r--tool/test/testunit/tests_for_parallel/test4test_slow_0.rb5
-rw-r--r--tool/test/testunit/tests_for_parallel/test4test_slow_1.rb5
-rw-r--r--tool/test/webrick/test_httpserver.rb2
-rw-r--r--tool/test/webrick/test_server.rb2
-rw-r--r--tool/test_for_warn_bundled_gems/.gitignore1
-rw-r--r--tool/test_for_warn_bundled_gems/Gemfile0
-rw-r--r--tool/test_for_warn_bundled_gems/Gemfile.lock11
-rw-r--r--tool/test_for_warn_bundled_gems/README.md3
-rwxr-xr-xtool/test_for_warn_bundled_gems/test.sh53
-rw-r--r--tool/test_for_warn_bundled_gems/test_no_warn_dash_gem.rb8
-rw-r--r--tool/test_for_warn_bundled_gems/test_no_warn_dependency.rb10
-rw-r--r--tool/test_for_warn_bundled_gems/test_no_warn_sub_feature.rb8
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_bootsnap.rb11
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_bootsnap_rubyarchdir_gem.rb11
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_bundle_exec.rb1
-rwxr-xr-xtool/test_for_warn_bundled_gems/test_warn_bundle_exec_shebang.rb3
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_bundled_gems.rb8
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_dash_gem.rb7
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_dependency.rb8
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_sub_feature.rb7
-rw-r--r--tool/test_for_warn_bundled_gems/test_warn_zeitwerk.rb12
-rw-r--r--tool/transform_mjit_header.rb319
-rwxr-xr-xtool/update-NEWS-gemlist.rb41
-rwxr-xr-xtool/update-bundled_gems.rb39
-rwxr-xr-xtool/update-deps51
-rwxr-xr-xtool/ytab.sed80
-rw-r--r--trace_point.rb14
-rw-r--r--transcode.c41
-rw-r--r--transient_heap.c991
-rw-r--r--transient_heap.h65
-rw-r--r--universal_parser.c377
-rw-r--r--util.c15
-rw-r--r--variable.c1261
-rw-r--r--variable.h16
-rw-r--r--version.c96
-rw-r--r--version.h14
-rw-r--r--vm.c791
-rw-r--r--vm_args.c170
-rw-r--r--vm_backtrace.c155
-rw-r--r--vm_callinfo.h126
-rw-r--r--vm_core.h303
-rw-r--r--vm_dump.c428
-rw-r--r--vm_eval.c228
-rw-r--r--vm_exec.c59
-rw-r--r--vm_exec.h36
-rw-r--r--vm_insnhelper.c1478
-rw-r--r--vm_insnhelper.h31
-rw-r--r--vm_method.c260
-rw-r--r--vm_opts.h6
-rw-r--r--vm_sync.c123
-rw-r--r--vm_trace.c452
-rw-r--r--vsnprintf.c4
-rw-r--r--warning.rb4
-rw-r--r--wasm/runtime.c7
-rw-r--r--wasm/setjmp.c69
-rw-r--r--wasm/setjmp.h2
-rw-r--r--weakmap.c1113
-rw-r--r--win32/.document1
-rw-r--r--win32/Makefile.sub81
-rw-r--r--win32/README.win32149
-rw-r--r--win32/file.c27
-rw-r--r--win32/file.h3
-rwxr-xr-xwin32/mkexports.rb5
-rw-r--r--win32/setup.mak11
-rw-r--r--win32/win32.c275
-rw-r--r--win32/winmain.c4
-rw-r--r--yjit.c224
-rw-r--r--yjit.h24
-rw-r--r--yjit.rb383
-rw-r--r--yjit/Cargo.lock7
-rw-r--r--yjit/Cargo.toml11
-rw-r--r--yjit/bindgen/Cargo.lock159
-rw-r--r--yjit/bindgen/Cargo.toml2
-rw-r--r--yjit/bindgen/src/main.rs66
-rw-r--r--yjit/not_gmake.mk6
-rw-r--r--yjit/src/asm/arm64/arg/bitmask_imm.rs4
-rw-r--r--yjit/src/asm/arm64/arg/condition.rs2
-rw-r--r--yjit/src/asm/arm64/arg/truncate.rs4
-rw-r--r--yjit/src/asm/arm64/inst/madd.rs73
-rw-r--r--yjit/src/asm/arm64/inst/mod.rs4
-rw-r--r--yjit/src/asm/arm64/inst/smulh.rs60
-rw-r--r--yjit/src/asm/arm64/mod.rs40
-rw-r--r--yjit/src/asm/mod.rs184
-rw-r--r--yjit/src/asm/x86_64/mod.rs80
-rw-r--r--yjit/src/asm/x86_64/tests.rs20
-rw-r--r--yjit/src/backend/arm64/mod.rs573
-rw-r--r--yjit/src/backend/ir.rs659
-rw-r--r--yjit/src/backend/mod.rs6
-rw-r--r--yjit/src/backend/tests.rs47
-rw-r--r--yjit/src/backend/x86_64/mod.rs596
-rw-r--r--yjit/src/codegen.rs6974
-rw-r--r--yjit/src/core.rs2946
-rw-r--r--yjit/src/cruby.rs107
-rw-r--r--yjit/src/cruby_bindings.inc.rs778
-rw-r--r--yjit/src/disasm.rs138
-rw-r--r--yjit/src/invariants.rs229
-rw-r--r--yjit/src/lib.rs3
-rw-r--r--yjit/src/options.rs187
-rw-r--r--yjit/src/stats.rs497
-rw-r--r--yjit/src/utils.rs41
-rw-r--r--yjit/src/virtualmem.rs90
-rw-r--r--yjit/src/yjit.rs134
-rw-r--r--yjit/yjit.mk46
5559 files changed, 214892 insertions, 332361 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000000..05ff204541
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,134 @@
+---
+version: '{build}'
+init:
+ - git config --global user.name git
+ - git config --global user.email svn-admin@ruby-lang.org
+ - git config --global core.autocrlf false
+ - git config --global core.eol lf
+ - git config --global advice.detachedHead 0
+shallow_clone: true
+clone_depth: 10
+platform:
+ - x64
+skip_commits:
+ message: /\[DOC\]/
+ files:
+ - doc/*
+ - '**/*.md'
+ - '**/*.rdoc'
+ - '**/.document'
+ - '**/*.[1-8]'
+ - '**/*.ronn'
+environment:
+ ruby_version: "24-%Platform%"
+ matrix:
+ # Test only the oldest supported version because AppVeyor is unstable, its concurrency
+ # is limited, and compatibility issues that happen only in newer versions are rare.
+ # You may test some other stuff on GitHub Actions instead.
+ - build: vs
+ vs: 120 # Visual Studio 2013
+ ssl: OpenSSL-v111
+ # The worker image name. This is NOT the Visual Studio version we're using here.
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ GEMS_FOR_TEST: ""
+ RELINE_TEST_ENCODING: "UTF-8"
+cache:
+ - c:\Tools\vcpkg\installed\
+for:
+-
+ matrix:
+ only:
+ - build: vs
+ install:
+ - ver
+ - chcp
+ - SET BITS=%Platform:x86=32%
+ - SET BITS=%BITS:x=%
+ - SET OPENSSL_DIR=C:\%ssl%-Win%BITS%
+ - cd C:\Tools\vcpkg
+ - git pull -q
+ - .\bootstrap-vcpkg.bat
+ - ps: Start-FileDownload 'https://github.com/microsoft/vcpkg-tool/releases/download/2023-08-09/vcpkg.exe' -FileName 'C:\Tools\vcpkg\vcpkg.exe'
+ - cd %APPVEYOR_BUILD_FOLDER%
+ - vcpkg --triplet %Platform%-windows install --x-use-aria2 libffi libyaml readline zlib
+ - CALL SET vcvars=%%^VS%VS%COMNTOOLS^%%..\..\VC\vcvarsall.bat
+ - SET vcvars
+ - '"%vcvars%" %Platform:x64=amd64%'
+ - SET ruby_path=C:\Ruby%ruby_version:-x86=%
+ - SET PATH=\usr\local\bin;%ruby_path%\bin;%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin
+ - ruby --version
+ - 'cl'
+ - echo> Makefile srcdir=.
+ - echo>> Makefile MSC_VER=0
+ - echo>> Makefile RT=none
+ - echo>> Makefile RT_VER=0
+ - echo>> Makefile BUILTIN_ENCOBJS=nul
+ - type win32\Makefile.sub >> Makefile
+ - nmake %mflags% up VCSUP="echo Update OK"
+ - nmake %mflags% extract-extlibs
+ - del Makefile
+ - mkdir \usr\local\bin
+ - mkdir \usr\local\include
+ - mkdir \usr\local\lib
+ - for %%I in (%OPENSSL_DIR%\*.dll) do mklink /h \usr\local\bin\%%~nxI %%I
+ - for %%I in (c:\Tools\vcpkg\installed\%Platform%-windows\bin\*.dll) do (
+ if not %%~nI == readline mklink \usr\local\bin\%%~nxI %%I
+ )
+ - attrib +r /s /d
+ - mkdir %Platform%-mswin_%vs%
+ build_script:
+ - set HAVE_GIT=no
+ - cd %APPVEYOR_BUILD_FOLDER%
+ - cd %Platform%-mswin_%vs%
+ - >-
+ ..\win32\configure.bat
+ --with-opt-dir="/usr/local;c:/Tools/vcpkg/installed/%Platform%-windows"
+ --with-openssl-dir=%OPENSSL_DIR:\=/%
+ - nmake -l
+ - nmake install-nodoc
+ - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')"
+ - if not "%GEMS_FOR_TEST%" == "" \usr\bin\gem install --no-document %GEMS_FOR_TEST%
+ - \usr\bin\ruby -ropenssl -e "puts 'Build ' + OpenSSL::OPENSSL_VERSION, 'Runtime ' + OpenSSL::OPENSSL_LIBRARY_VERSION"
+ test_script:
+ - set /a JOBS=%NUMBER_OF_PROCESSORS%
+ - nmake -l "TESTOPTS=-v -q" btest
+ - nmake -l "TESTOPTS=-v -q" test-basic
+ - >-
+ nmake -l "TESTOPTS=--timeout-scale=3.0
+ --excludes=../test/excludes/_appveyor -j%JOBS%
+ --exclude win32ole
+ --exclude test_bignum
+ --exclude test_syntax
+ --exclude test_open-uri
+ --exclude test_bundled_ca
+ " test-all
+ # separately execute tests without -j which may crash worker with -j.
+ - >-
+ nmake -l
+ "TESTOPTS=--timeout-scale=3.0 --excludes=../test/excludes/_appveyor"
+ TESTS="
+ ../test/win32ole
+ ../test/ruby/test_bignum.rb
+ ../test/ruby/test_syntax.rb
+ ../test/open-uri/test_open-uri.rb
+ ../test/rubygems/test_bundled_ca.rb
+ " test-all
+ - nmake -l test-spec MSPECOPT=-fs # not using `-j` because sometimes `mspec -j` silently dies on Windows
+notifications:
+ - provider: Webhook
+ method: POST
+ url:
+ secure: CcFlJNDJ/a6to7u3Z4Fnz6dScEPNx7hTha2GkSRlV+1U6dqmxY/7uBcLXYb9gR3jfQk6w+2o/HrjNAyXMNGU/JOka3s2WRI4VKitzM+lQ08owvJIh0R7LxrGH0J2e81U # ruby-lang slack: ruby/simpler-alerts-bot
+ body: >-
+ {{^isPullRequest}}
+ {
+ "ci": "AppVeyor CI",
+ "env": "Visual Studio 2013",
+ "url": "{{buildUrl}}",
+ "commit": "{{commitId}}",
+ "branch": "{{branch}}"
+ }
+ {{/isPullRequest}}
+ on_build_success: false
+ on_build_failure: true
+ on_build_status_changed: false
diff --git a/.document b/.document
index e875e42546..3a6b0c238c 100644
--- a/.document
+++ b/.document
@@ -18,7 +18,7 @@ gc.rb
io.rb
kernel.rb
marshal.rb
-rjit.rb
+mjit.rb
numeric.rb
nilclass.rb
pack.rb
@@ -48,4 +48,7 @@ COPYING.ja
LEGAL
+# win32/README.win32 linked from README.md
+win32
+
doc
diff --git a/.gdbinit b/.gdbinit
index 7dd3336e28..34d044caf6 100644
--- a/.gdbinit
+++ b/.gdbinit
@@ -67,7 +67,7 @@ define rp
printf "%sT_OBJECT%s: ", $color_type, $color_end
print ((struct RObject *)($arg0))->basic
if ($flags & ROBJECT_EMBED)
- print/x *((VALUE*)((struct RObject*)($arg0))->as.ary) @ (rb_shape_get_shape($arg0)->capacity)
+ print/x *((VALUE*)((struct RObject*)($arg0))->as.ary) @ (ROBJECT_EMBED_LEN_MAX+0)
else
print (((struct RObject *)($arg0))->as.heap)
if (((struct RObject*)($arg0))->as.heap.numiv) > 0
@@ -104,8 +104,8 @@ define rp
(($rsflags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
set print address off
output *(char *)(($rsflags & RUBY_FL_USER1) ? \
- ((struct RString*)$regsrc)->as.heap.ptr : \
- ((struct RString*)$regsrc)->as.ary) @ $len
+ ((struct RString*)$regsrc)->as.heap.ptr : \
+ ((struct RString*)$regsrc)->as.ary) @ $len
set print address on
printf " len:%ld ", $len
if $flags & RUBY_FL_USER6
@@ -126,26 +126,26 @@ define rp
printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
printf "(embed) "
if ($len == 0)
- printf "{(empty)} "
+ printf "{(empty)} "
else
- print/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len
- printf " "
+ print/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len
+ printf " "
end
else
set $len = ((struct RArray*)($arg0))->as.heap.len
printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
if ($flags & RUBY_FL_USER2)
- printf "(shared) shared="
- output/x ((struct RArray*)($arg0))->as.heap.aux.shared_root
- printf " "
+ printf "(shared) shared="
+ output/x ((struct RArray*)($arg0))->as.heap.aux.shared_root
+ printf " "
else
- printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
+ printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
end
if ($len == 0)
- printf "{(empty)} "
+ printf "{(empty)} "
else
- print/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len
- printf " "
+ print/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len
+ printf " "
end
end
print (struct RArray *)($arg0)
@@ -445,8 +445,8 @@ define output_string
(($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
if $len > 0
output *(char *)(($flags & RUBY_FL_USER1) ? \
- ((struct RString*)($arg0))->as.heap.ptr : \
- ((struct RString*)($arg0))->as.ary) @ $len
+ ((struct RString*)($arg0))->as.heap.ptr : \
+ ((struct RString*)($arg0))->as.ary) @ $len
else
output ""
end
@@ -459,8 +459,8 @@ define print_string
(($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
if $len > 0
printf "%s", *(char *)(($flags & RUBY_FL_USER1) ? \
- ((struct RString*)($arg0))->as.heap.ptr : \
- ((struct RString*)($arg0))->as.ary) @ $len
+ ((struct RString*)($arg0))->as.heap.ptr : \
+ ((struct RString*)($arg0))->as.ary) @ $len
end
end
@@ -689,6 +689,11 @@ define nd_stts
end
+define nd_entry
+ printf "%su3.entry%s: ", $color_highlite, $color_end
+ p ($arg0).u3.entry
+end
+
define nd_vid
printf "%su1.id%s: ", $color_highlite, $color_end
p ($arg0).u1.id
@@ -863,22 +868,22 @@ define rb_numtable_entry
set $rb_numtable_p = $rb_numtable_tbl->as.packed.bins
while $rb_numtable_p && $rb_numtable_p < $rb_numtable_tbl->as.packed.bins+$rb_numtable_tbl->num_entries
if $rb_numtable_p.k == $rb_numtable_id
- set $rb_numtable_key = $rb_numtable_p.k
- set $rb_numtable_rec = $rb_numtable_p.v
- set $rb_numtable_p = 0
+ set $rb_numtable_key = $rb_numtable_p.k
+ set $rb_numtable_rec = $rb_numtable_p.v
+ set $rb_numtable_p = 0
else
- set $rb_numtable_p = $rb_numtable_p + 1
+ set $rb_numtable_p = $rb_numtable_p + 1
end
end
else
set $rb_numtable_p = $rb_numtable_tbl->as.big.bins[st_numhash($rb_numtable_id) % $rb_numtable_tbl->num_bins]
while $rb_numtable_p
if $rb_numtable_p->key == $rb_numtable_id
- set $rb_numtable_key = $rb_numtable_p->key
- set $rb_numtable_rec = $rb_numtable_p->record
- set $rb_numtable_p = 0
+ set $rb_numtable_key = $rb_numtable_p->key
+ set $rb_numtable_rec = $rb_numtable_p->record
+ set $rb_numtable_p = 0
else
- set $rb_numtable_p = $rb_numtable_p->next
+ set $rb_numtable_p = $rb_numtable_p->next
end
end
end
@@ -956,7 +961,7 @@ define iseq
set $operand_size = ((INSN*)($arg0))->operand_size
set $operands = ((INSN*)($arg0))->operands
while $i < $operand_size
- rp $operands[$i++]
+ rp $operands[$i++]
end
end
end
@@ -1274,9 +1279,9 @@ document rb_count_objects
Counts all objects grouped by type.
end
-# Details: https://github.com/ruby/ruby/wiki/Machine-Instructions-Trace-with-GDB
+# Details: https://bugs.ruby-lang.org/projects/ruby-master/wiki/MachineInstructionsTraceWithGDB
define trace_machine_instructions
- set logging enabled
+ set logging on
set height 0
set width 0
display/i $pc
@@ -1343,5 +1348,3 @@ define print_flags
printf "RUBY_FL_USER17 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER17 ? "1" : "0"
printf "RUBY_FL_USER18 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER18 ? "1" : "0"
end
-
-source misc/gdb.py
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 1bf7db40ad..6c5eac5a0f 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -5,7 +5,6 @@
# Expand tabs
5b21e94bebed90180d8ff63dad03b8b948361089
-c5e9af9c9d890578182a21e7b71b50334cd5579e
# Enable Style/StringLiterals cop for RubyGems/Bundler
d7ffd3fea402239b16833cc434404a7af82d44f3
@@ -22,7 +21,3 @@ f28287d34c03f472ffe90ea262bdde9affd4b965
# Make benchmark indentation consistent
fc4acf8cae82e5196186d3278d831f2438479d91
-
-# Make prism_compile.c indentation consistent
-40b2c8e5e7e6e5f83cee9276dc9c1922a69292d6
-d2c5867357ed88eccc28c2b3bd4a46e206e7ff85
diff --git a/.github/actions/setup/directories/action.yml b/.github/actions/setup/directories/action.yml
deleted file mode 100644
index 359e5c0d37..0000000000
--- a/.github/actions/setup/directories/action.yml
+++ /dev/null
@@ -1,137 +0,0 @@
-name: Setup directories etc.
-description: >-
- Set up the source code and build directories (plus some
- environmental tweaks)
-
-inputs:
- srcdir:
- required: false
- default: ${{ github.workspace }}
- description: >-
- Directory to (re-)checkout source codes. This will be created
- if absent. If there is no `configure` file that is also
- generated inside.
-
- builddir:
- required: false
- default: ${{ github.workspace }}
- description: >-
- Where binaries and other generated contents go. This will be
- created if absent.
-
- makeup:
- required: false
- type: boolean
- # Note that `default: false` evaluates to a string constant
- # `'false'`, which is a truthy value :sigh:
- # https://github.com/actions/runner/issues/2238
- default: ''
- description: >-
- If set to true, additionally runs `make up`.
-
- checkout:
- required: false
- type: boolean
- default: true
- description: >-
- If set to '' (false), skip running actions/checkout. This is useful when
- you don't want to overwrite a GitHub token that is already set up.
-
- dummy-files:
- required: false
- type: boolean
- default: ''
- description: >-
- If set to true, creates dummy files in build dir.
-
-outputs: {} # nothing?
-
-runs:
- using: composite
-
- steps:
- # Note that `shell: bash` works on both Windows and Linux, but not
- # `shell: sh`. This is because GitHub hosted Windows runners have
- # their bash manually installed.
- - shell: bash
- run: |
- mkdir -p ${{ inputs.srcdir }}
- mkdir -p ${{ inputs.builddir }}
-
- # Did you know that actions/checkout works without git(1)? We are
- # checking that here.
- - id: which
- shell: bash
- run: |
- echo "git=`command -v git`" >> "$GITHUB_OUTPUT"
- echo "sudo=`command -v sudo`" >> "$GITHUB_OUTPUT"
- echo "autoreconf=`command -v autoreconf`" >> "$GITHUB_OUTPUT"
-
- - if: steps.which.outputs.git
- shell: bash
- run: |
- git config --global core.autocrlf false
- git config --global core.eol lf
- git config --global advice.detachedHead 0
- git config --global init.defaultBranch garbage
-
- - if: inputs.checkout
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- path: ${{ inputs.srcdir }}
-
- - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
- with:
- path: ${{ inputs.srcdir }}/.downloaded-cache
- key: downloaded-cache
-
- - if: steps.which.outputs.autoreconf
- shell: bash
- working-directory: ${{ inputs.srcdir }}
- run: ./autogen.sh
-
- # This is for MinGW.
- - if: runner.os == 'Windows'
- shell: bash
- run: echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV
-
- - if: runner.os == 'Linux'
- shell: bash
- run: echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> "$GITHUB_ENV"
-
- # macOS' GNU make is so old that they doesn't understand `GNUMAKEFLAGS`.
- - if: runner.os == 'macOS'
- shell: bash
- run: echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> "$GITHUB_ENV"
-
- - if: inputs.makeup
- shell: bash
- working-directory: ${{ inputs.srcdir }}
- run: |
- touch config.status
- touch .rbconfig.time
- sed -f tool/prereq.status template/Makefile.in > Makefile
- sed -f tool/prereq.status template/GNUmakefile.in > GNUmakefile
- make up
-
- # Cleanup, runs even on failure
- - if: always() && inputs.makeup
- shell: bash
- working-directory: ${{ inputs.srcdir }}
- run: rm -f config.status Makefile rbconfig.rb .rbconfig.time
-
- - if: steps.which.outputs.sudo
- shell: bash
- run: |
- sudo chmod -R go-w /usr/share
- chmod -v go-w $HOME $HOME/.config || :
- sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
-
- - if: inputs.dummy-files == 'true'
- shell: bash
- working-directory: ${{ inputs.builddir }}
- run: |
- : Create dummy files in build dir
- for basename in {a..z} {A..Z} {0..9} foo bar test zzz; do
- echo > ${basename}.rb "raise %(do not load ${basename}.rb)"
- done
diff --git a/.github/actions/setup/macos/action.yml b/.github/actions/setup/macos/action.yml
deleted file mode 100644
index 3649a64876..0000000000
--- a/.github/actions/setup/macos/action.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Setup macOS environment
-description: >-
- Installs necessary packages via Homebrew.
-
-inputs: {} # nothing?
-
-outputs: {} # nothing?
-
-runs:
- using: composite
-
- steps:
- - name: brew
- shell: bash
- run: |
- brew install --quiet gmp libffi openssl@1.1 zlib autoconf automake libtool readline
-
- - name: Set ENV
- shell: bash
- run: |
- for lib in openssl@1.1 readline; do
- CONFIGURE_ARGS="${CONFIGURE_ARGS:+$CONFIGURE_ARGS }--with-${lib%@*}-dir=$(brew --prefix $lib)"
- done
- echo CONFIGURE_ARGS="${CONFIGURE_ARGS}" >> $GITHUB_ENV
diff --git a/.github/actions/setup/ubuntu/action.yml b/.github/actions/setup/ubuntu/action.yml
deleted file mode 100644
index a9e5b41951..0000000000
--- a/.github/actions/setup/ubuntu/action.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: Setup ubuntu environment
-description: >-
- At the beginning there was no way but to copy & paste `apt-get`
- everywhere. But now that we have composite actions, it seems better
- merge them into one.
-
-inputs:
- arch:
- required: false
- default: ''
- description: >-
- Architecture. Because we run this on a GitHub-hosted runner
- acceptable value for this input is very limited.
-
-outputs:
- arch:
- value: ${{ steps.uname.outputs.uname }}
- description: >-
- Actual architecture. This could be different from the one
- passed to the `inputs.arch`. For instance giving `i386` to this
- action yields `i686`.
-
-runs:
- using: composite
-
- steps:
- - name: set SETARCH
- shell: bash
- run: echo "SETARCH=${setarch}" >> "$GITHUB_ENV"
- env:
- setarch: ${{ inputs.arch && format('setarch {0} --', inputs.arch) }}
-
- - id: uname
- name: uname
- shell: bash
- run: |
- echo uname=`${SETARCH} uname -m` >> "$GITHUB_OUTPUT"
- echo dpkg=`${SETARCH} uname -m | sed s/686/386/` >> "$GITHUB_OUTPUT"
-
- - name: apt-get
- shell: bash
- env:
- arch: ${{ inputs.arch && format(':{0}', steps.uname.outputs.dpkg) || '' }}
- run: |
- set -x
- ${arch:+sudo dpkg --add-architecture ${arch#:}}
- sudo apt-get update -qq || :
- sudo apt-get install --no-install-recommends -qq -y -o=Dpkg::Use-Pty=0 \
- ${arch:+cross}build-essential${arch/:/-} \
- libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \
- zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \
- autoconf ruby
- sudo apt-get install -qq -y pkg-config${arch} || :
diff --git a/.github/actions/slack/action.yml b/.github/actions/slack/action.yml
deleted file mode 100644
index c98be085a8..0000000000
--- a/.github/actions/slack/action.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-name: Post a message to slack
-description: >-
- We have our ruby/action-slack webhook. However its arguments are
- bit verbose to be listed in every workflow files. Better merge them
- into one.
-
-inputs:
- SLACK_WEBHOOK_URL:
- required: true
- description: >-
- The URL to post the payload. This is an input because it tends
- to be stored in a secrets valut and a composite action cannot
- look into one.
-
- label:
- required: false
- description: >-
- Human-readable description of the run, something like "DEBUG=1".
- This need not be unique among runs.
-
-outputs: {} # Nothing?
-
-runs:
- using: composite
-
- steps:
- - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
- with:
- payload: |
- {
- "ci": "GitHub Actions",
- "env": "${{ github.workflow }}${{ inputs.label && format(' / {0}', inputs.label) }}",
- "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
- "commit": "${{ github.sha }}",
- "branch": "${{ github.ref_name }}"
- }
- env:
- SLACK_WEBHOOK_URL: ${{ inputs.SLACK_WEBHOOK_URL }}
- if: ${{github.event_name == 'push' && startsWith(github.repository, 'ruby/')}}
diff --git a/.github/auto_request_review.yml b/.github/auto_request_review.yml
deleted file mode 100644
index 8726df577d..0000000000
--- a/.github/auto_request_review.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-files:
- 'yjit*': [team:yjit]
- 'yjit/**/*': [team:yjit]
- 'yjit/src/cruby_bindings.inc.rs': []
- 'doc/yjit/*': [team:yjit]
- 'bootstraptest/test_yjit*': [team:yjit]
- 'test/ruby/test_yjit*': [team:yjit]
-options:
- ignore_draft: true
- # This currently doesn't work as intended. We want to skip reviews when only
- # cruby_bingings.inc.rs is modified, but this skips reviews even when other
- # yjit files are modified as well. To be enabled after fixing the behavior.
- #last_files_match_only: true
diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml
new file mode 100644
index 0000000000..91f82b842b
--- /dev/null
+++ b/.github/codeql/codeql-config.yml
@@ -0,0 +1,3 @@
+name: "CodeQL config for the Ruby language"
+
+languages: cpp
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 70a73430d7..bc63aca35b 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,6 +1,6 @@
version: 2
updates:
- package-ecosystem: 'github-actions'
- directory: '/.github'
+ directory: '/'
schedule:
- interval: 'daily'
+ interval: 'monthly'
diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml
deleted file mode 100644
index 25454f6abe..0000000000
--- a/.github/workflows/annocheck.yml
+++ /dev/null
@@ -1,127 +0,0 @@
-name: Annocheck
-
-on:
- push:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
- pull_request:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
- merge_group:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
-
-concurrency:
- group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
- cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-
-permissions:
- contents: read
-
-jobs:
- compile:
- name: gcc-11 annocheck
-
- runs-on: ubuntu-latest
-
- container:
- image: ghcr.io/ruby/ruby-ci-image:gcc-11
- options: --user root
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
- env:
- CONFIGURE_TTY: never
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
- RUBY_DEBUG: ci rgengc
- RUBY_TESTOPTS: >-
- -q
- --color=always
- --tty=no
- # FIXME: Drop skipping options
- # https://bugs.ruby-lang.org/issues/18061
- # https://sourceware.org/annobin/annobin.html/Test-pie.html
- TEST_ANNOCHECK_OPTS: '--skip-pie --skip-gaps'
-
- steps:
- - run: id
- working-directory:
-
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/directories
- with:
- srcdir: src
- builddir: build
- makeup: true
-
- # Minimal flags to pass the check.
- # -g0 disables backtraces when SEGV. Do not set that.
- - name: Run configure
- run: >
- ../src/configure -C
- --enable-debug-env
- --disable-install-doc
- --with-ext=-test-/cxxanyargs,+
- --without-valgrind
- --without-jemalloc
- --without-gmp
- --with-gcc="gcc-11 -fcf-protection -Wa,--generate-missing-build-notes=yes"
- --enable-shared
- debugflags=-ggdb3
- optflags=-O2
- LDFLAGS=-Wl,-z,now
-
- - run: make showflags
-
- - run: make
-
- - run: make test
-
- - run: make install
-
- - run: make test-tool
-
- ### test-all doesn't work: https://github.com/ruby/ruby/actions/runs/4340112185/jobs/7578344307
- # - run: make test-all TESTS='-- ruby -ext-'
-
- ### test-spec doesn't work: https://github.com/ruby/ruby/actions/runs/4340193212/jobs/7578505652
- # - run: make test-spec
- # env:
- # CHECK_LEAKS: true
-
- - run: make test-annocheck
- continue-on-error: true # toomanyrequests: You have reached your pull rate limit.
-
- - uses: ./.github/actions/slack
- with:
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
-defaults:
- run:
- working-directory: build
diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml
deleted file mode 100644
index 998a6ea58a..0000000000
--- a/.github/workflows/auto_request_review.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Auto Request Review
-on:
- pull_request_target:
- types: [opened, ready_for_review, reopened]
-
-permissions:
- contents: read
-
-jobs:
- auto-request-review:
- name: Auto Request Review
- runs-on: ubuntu-latest
- if: ${{ github.repository == 'ruby/ruby' && github.base_ref == 'master' }}
- steps:
- - name: Request review based on files changes and/or groups the author belongs to
- uses: necojackarc/auto-request-review@6a51cebffe2c084705d9a7b394abd802e0119633 # v0.12.0
- with:
- # scope: public_repo
- token: ${{ secrets.MATZBOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml
index 860d74aa1a..ebaafe3bf0 100644
--- a/.github/workflows/baseruby.yml
+++ b/.github/workflows/baseruby.yml
@@ -8,7 +8,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
paths-ignore:
- 'doc/**'
@@ -16,7 +15,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
merge_group:
paths-ignore:
- 'doc/**'
@@ -24,7 +22,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -36,49 +33,48 @@ permissions:
jobs:
baseruby:
name: BASERUBY
-
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
strategy:
matrix:
ruby:
- - ruby-2.5
+ - ruby-2.2
+# - ruby-2.3
+# - ruby-2.4
+# - ruby-2.5
# - ruby-2.6
# - ruby-2.7
- ruby-3.0
- ruby-3.1
- - ruby-3.2
steps:
- - uses: ruby/setup-ruby@036ef458ddccddb148a2b9fb67e95a22fdbf728b # v1.160.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
-
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
- - uses: ./.github/actions/setup/ubuntu
-
- - uses: ./.github/actions/setup/directories
- with:
- makeup: true
-
+ - run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: sudo apt-get install build-essential autoconf bison libyaml-dev
+ - run: ./autogen.sh
- run: ./configure --disable-install-doc
-
+ - run: make common-srcs
+ - run: make incs
- run: make all
-
- run: make test
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.ruby }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / BASERUBY @ ${{ matrix.ruby }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml
index 943140e9ef..070c0fa1dd 100644
--- a/.github/workflows/bundled_gems.yml
+++ b/.github/workflows/bundled_gems.yml
@@ -2,17 +2,17 @@ name: bundled_gems
on:
push:
- branches: ['master']
+ branches: [ "master" ]
paths:
- '.github/workflows/bundled_gems.yml'
- 'gems/bundled_gems'
pull_request:
- branches: ['master']
+ branches: [ "master" ]
paths:
- '.github/workflows/bundled_gems.yml'
- 'gems/bundled_gems'
merge_group:
- branches: ['master']
+ branches: [ "master" ]
paths:
- '.github/workflows/bundled_gems.yml'
- 'gems/bundled_gems'
@@ -20,34 +20,36 @@ on:
- cron: '45 6 * * *'
workflow_dispatch:
-permissions: # added using https://github.com/step-security/secure-workflows
+permissions: # added using https://github.com/step-security/secure-workflows
contents: read
jobs:
update:
permissions:
- contents: write # for Git to git push
-
+ contents: write # for Git to git push
if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby' }}
-
name: update ${{ github.workflow }}
-
runs-on: ubuntu-latest
-
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
-
- - uses: ./.github/actions/setup/directories
- with:
- # Skip overwriting MATZBOT_GITHUB_TOKEN
- checkout: '' # false (ref: https://github.com/actions/runner/issues/2238)
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
- name: Set ENV
run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
echo "TODAY=$(date +%F)" >> $GITHUB_ENV
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache-${{ github.sha }}
+ restore-keys: |
+ downloaded-cache
+
- name: Download previous gems list
run: |
data=bundled_gems.json
@@ -56,76 +58,109 @@ jobs:
curl -O -R -z ./$data https://stdgems.org/$data
- name: Update bundled gems list
- id: bundled_gems
run: |
- ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems >> $GITHUB_OUTPUT
+ ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems
- name: Maintain updated gems list in NEWS
run: |
- ruby tool/update-NEWS-gemlist.rb bundled
+ #!ruby
+ require 'json'
+ news = File.read("NEWS.md")
+ prev = news[/since the \*+(\d+\.\d+\.\d+)\*+/, 1]
+ prevs = [prev, prev.sub(/\.\d+\z/, '')]
+ %W[bundled].each do |type|
+ last = JSON.parse(File.read("#{type}_gems.json"))['gems'].filter_map do |g|
+ v = g['versions'].values_at(*prevs).compact.first
+ g = g['gem']
+ g = 'RubyGems' if g == 'rubygems'
+ [g, v] if v
+ end.to_h
+ changed = File.foreach("gems/#{type}_gems").filter_map do |l|
+ next if l.start_with?("#")
+ g, v = l.split(" ", 3)
+ [g, v] unless last[g] == v
+ end
+ changed, added = changed.partition {|g, _| last[g]}
+ news.sub!(/^\*( +)The following #{type} gems? are updated\.\n+\K(?: \1\*( +).*\n)*/) do
+ mark = "#{$1} *#{$2}"
+ changed.map {|g, v|"#{mark}#{g} #{v}\n"}.join("")
+ end or next
+ news.sub!(/^\*( +)The following default gems are now bundled gems\.\n+\K(?: \1\*( +).*\n)*/) do
+ mark = "#{$1} *#{$2}"
+ added.map {|g, v|"#{mark}#{g} #{v}\n"}.join("")
+ end or next unless added.empty?
+ File.write("NEWS.md", news)
+ end
+ shell: ruby {0}
- name: Check diffs
id: diff
run: |
- news= gems=
- git diff --color --no-ext-diff --ignore-submodules --exit-code -- NEWS.md ||
- news=true
- git diff --color --no-ext-diff --ignore-submodules --exit-code -- gems/bundled_gems ||
- gems=true
- git add -- NEWS.md gems/bundled_gems
- echo news=$news >> $GITHUB_OUTPUT
- echo gems=$gems >> $GITHUB_OUTPUT
- echo update=${news:-$gems} >> $GITHUB_OUTPUT
+ git add -- NEWS.md
+ git diff --no-ext-diff --ignore-submodules --quiet -- gems/bundled_gems
+ continue-on-error: true
- name: Install libraries
- uses: ./.github/actions/setup/ubuntu
- if: ${{ steps.diff.outputs.gems }}
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
+ if: ${{ steps.diff.outcome == 'failure' }}
- name: Build
run: |
./autogen.sh
./configure -C --disable-install-doc
make
- if: ${{ steps.diff.outputs.gems }}
+ if: ${{ steps.diff.outcome == 'failure' }}
- name: Prepare bundled gems
run: |
make -s prepare-gems
- if: ${{ steps.diff.outputs.gems }}
+ if: ${{ steps.diff.outcome == 'failure' }}
- name: Test bundled gems
run: |
make -s test-bundled-gems
+ git add -- gems/bundled_gems
timeout-minutes: 30
env:
- RUBY_TESTOPTS: '-q --tty=no'
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: ''
- if: ${{ steps.diff.outputs.gems }}
+ RUBY_TESTOPTS: "-q --tty=no"
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ if: ${{ steps.diff.outcome == 'failure' }}
+
+ - name: Show diffs
+ id: show
+ run: |
+ git diff --cached --color --no-ext-diff --ignore-submodules --exit-code --
+ continue-on-error: true
- name: Commit
run: |
git pull --ff-only origin ${GITHUB_REF#refs/heads/}
- message="Update bundled gems list"
- if [ -z "${gems}" ]; then
- git commit --message="${message} at ${GITHUB_SHA:0:30} [ci skip]"
+ message="Update bundled gems list at "
+ if [ ${{ steps.diff.outcome }} = success ]; then
+ git commit --message="${message}${GITHUB_SHA:0:30} [ci skip]"
else
- git commit --message="${message} as of ${TODAY}"
+ git commit --message="${message}${TODAY}"
fi
git push origin ${GITHUB_REF#refs/heads/}
env:
- TODAY: ${{ steps.bundled_gems.outputs.latest_date || env.TODAY }}
EMAIL: svn-admin@ruby-lang.org
GIT_AUTHOR_NAME: git
GIT_COMMITTER_NAME: git
- gems: ${{ steps.diff.outputs.gems }}
- if: >-
- ${{
- github.repository == 'ruby/ruby' &&
- !startsWith(github.event_name, 'pull') &&
- steps.diff.outputs.update
- }}
-
- - uses: ./.github/actions/slack
+ if: ${{ github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull') && steps.show.outcome == 'failure' }}
+
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / update",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml
index 10c202c3c1..79b2916feb 100644
--- a/.github/workflows/check_dependencies.yml
+++ b/.github/workflows/check_dependencies.yml
@@ -7,7 +7,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
paths-ignore:
- 'doc/**'
@@ -15,7 +14,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
merge_group:
paths-ignore:
- 'doc/**'
@@ -23,7 +21,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -36,41 +33,46 @@ jobs:
update-deps:
strategy:
matrix:
- os: [ubuntu-20.04]
+ os: [ubuntu-22.04]
fail-fast: true
-
runs-on: ${{ matrix.os }}
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
- - uses: ./.github/actions/setup/ubuntu
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
if: ${{ contains(matrix.os, 'ubuntu') }}
-
- - uses: ./.github/actions/setup/macos
+ - name: Install libraries
+ run: |
+ brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline
if: ${{ contains(matrix.os, 'macos') }}
-
- - uses: ./.github/actions/setup/directories
-
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache
+ - run: ./autogen.sh
- name: Run configure
run: ./configure -C --disable-install-doc --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g'
-
- run: make all golf
-
- run: ruby tool/update-deps --fix
-
- run: git diff --no-ext-diff --ignore-submodules --exit-code
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.os }} / Dependencies need to update
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / Dependencies need to update",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml
deleted file mode 100644
index ce4397b35a..0000000000
--- a/.github/workflows/check_misc.yml
+++ /dev/null
@@ -1,117 +0,0 @@
-name: Misc
-on: [push, pull_request, merge_group]
-
-concurrency:
- group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
- cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-
-permissions:
- contents: read
-
-jobs:
- checks:
- name: Miscellaneous checks
-
- permissions:
- contents: write # for Git to git push
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
-
- - uses: ./.github/actions/setup/directories
- with:
- makeup: true
- # Skip overwriting MATZBOT_GITHUB_TOKEN
- checkout: '' # false (ref: https://github.com/actions/runner/issues/2238)
-
- - name: Check if C-sources are US-ASCII
- run: |
- grep -r -n --include='*.[chyS]' --include='*.asm' $'[^\t-~]' -- . && exit 1 || :
-
- - name: Check for trailing spaces
- run: |
- git grep -I -n $'[\t ]$' -- '*.rb' '*.[chy]' '*.rs' '*.yml' && exit 1 || :
- git grep -n $'^[\t ][\t ]*$' -- '*.md' && exit 1 || :
-
- - name: Check for bash specific substitution in configure.ac
- run: |
- git grep -n '\${[A-Za-z_0-9]*/' -- configure.ac && exit 1 || :
-
- - name: Check for header macros
- run: |
- fail=
- for header in ruby/*.h; do
- git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null && continue
- fail=1
- echo $header
- done
- exit $fail
- working-directory: include
-
- - id: gems
- run: true
- if: ${{ github.ref == 'refs/heads/master' }}
-
- - name: Download previous gems list
- run: |
- data=default_gems.json
- mkdir -p .downloaded-cache
- ln -s .downloaded-cache/$data .
- curl -O -R -z ./$data https://stdgems.org/$data
- if: ${{ steps.gems.outcome == 'success' }}
-
- - name: Make default gems list
- run: |
- #!ruby
- require 'rubygems'
- $:.unshift "lib"
- rgver = File.foreach("lib/rubygems.rb") do |line|
- break $1 if /^\s*VERSION\s*=\s*"([^"]+)"/ =~ line
- end
- gems = Dir.glob("{ext,lib}/**/*.gemspec").map do |f|
- spec = Gem::Specification.load(f)
- "#{spec.name} #{spec.version}"
- end.sort
- File.open("gems/default_gems", "w") do |f|
- f.puts "RubyGems #{rgver}"
- f.puts gems
- end
- shell: ruby --disable=gems {0}
- if: ${{ steps.gems.outcome == 'success' }}
-
- - name: Maintain updated gems list in NEWS
- run: |
- ruby tool/update-NEWS-gemlist.rb default
- if: ${{ steps.gems.outcome == 'success' }}
-
- - name: Check diffs
- id: diff
- run: |
- git diff --color --no-ext-diff --ignore-submodules --exit-code NEWS.md ||
- echo update=true >> $GITHUB_OUTPUT
- if: ${{ steps.gems.outcome == 'success' }}
-
- - name: Commit
- run: |
- git pull --ff-only origin ${GITHUB_REF#refs/heads/}
- git commit --message="Update default gems list at ${GITHUB_SHA:0:30} [ci skip]" NEWS.md
- git push origin ${GITHUB_REF#refs/heads/}
- env:
- EMAIL: svn-admin@ruby-lang.org
- GIT_AUTHOR_NAME: git
- GIT_COMMITTER_NAME: git
- if: >-
- ${{
- github.repository == 'ruby/ruby' &&
- !startsWith(github.event_name, 'pull') &&
- steps.diff.outputs.update
- }}
-
- - uses: ./.github/actions/slack
- with:
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 47104672fe..8dba76fbe2 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,23 +1,20 @@
-name: 'CodeQL'
+name: "Code scanning - action"
on:
- push:
- branches: ['master']
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
- pull_request:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
+ # push:
+ # paths-ignore:
+ # - 'doc/**'
+ # - '**/man'
+ # - '**.md'
+ # - '**.rdoc'
+ # - '**/.document'
+ # pull_request:
+ # paths-ignore:
+ # - 'doc/**'
+ # - '**/man'
+ # - '**.md'
+ # - '**.rdoc'
+ # - '**/.document'
schedule:
- cron: '0 12 * * *'
workflow_dispatch:
@@ -26,90 +23,53 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-permissions: # added using https://github.com/step-security/secure-workflows
+permissions: # added using https://github.com/step-security/secure-workflows
contents: read
jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
+ CodeQL-Build:
+
+ # CodeQL runs on ubuntu-latest and windows-latest
permissions:
- actions: read # for github/codeql-action/init to get workflow details
- contents: read # for actions/checkout to fetch code
- security-events: write # for github/codeql-action/autobuild to send a status report
+ actions: read # for github/codeql-action/init to get workflow details
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/autobuild to send a status report
+ runs-on: ubuntu-latest
# CodeQL fails to run pull requests from dependabot due to missing write access to upload results.
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') && github.event.head_commit.pusher.name != 'dependabot[bot]' }}
env:
enable_install_doc: no
- strategy:
- fail-fast: false
- matrix:
- language: ['cpp', 'ruby']
-
steps:
- - name: Checkout repository
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
- - name: Install libraries
- uses: ./.github/actions/setup/ubuntu
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
- - uses: ./.github/actions/setup/directories
+ - name: Checkout repository
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- - name: Remove an obsolete rubygems vendored file
- run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache
- - name: Initialize CodeQL
- uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
- with:
- languages: ${{ matrix.language }}
+ - name: Remove an obsolete rubygems vendored file
+ run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
- - name: Autobuild
- uses: github/codeql-action/autobuild@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
+ with:
+ config-file: ./.github/codeql/codeql-config.yml
+ trap-caching: false
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
- with:
- category: '/language:${{ matrix.language }}'
- upload: False
- output: sarif-results
- ram: 8192
- # CodeQL randomly hits `OutOfMemoryError "Java heap space"`.
- # GitHub recommends running a larger runner to fix it, but we don't pay for it.
- continue-on-error: true
+ - name: Set ENV
+ run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
- - name: filter-sarif
- uses: advanced-security/filter-sarif@f3b8118a9349d88f7b1c0c488476411145b6270d # v1.0
- with:
- patterns: |
- +**/*.rb
- -lib/uri/mailto.rb:rb/overly-large-range
- -lib/uri/rfc3986_parser.rb:rb/overly-large-range
- -lib/bundler/vendor/uri/lib/uri/mailto.rb:rb/overly-large-range
- -lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb:rb/overly-large-range
- -test/ruby/test_io.rb:rb/non-constant-kernel-open
- -test/open-uri/test_open-uri.rb:rb/non-constant-kernel-open
- -test/open-uri/test_ssl.rb:rb/non-constant-kernel-open
- -spec/ruby/core/io/binread_spec.rb:rb/non-constant-kernel-open
- -spec/ruby/core/io/readlines_spec.rb:rb/non-constant-kernel-open
- -spec/ruby/core/io/foreach_spec.rb:rb/non-constant-kernel-open
- -spec/ruby/core/io/write_spec.rb:rb/non-constant-kernel-open
- -spec/ruby/core/io/read_spec.rb:rb/non-constant-kernel-open
- -spec/ruby/core/kernel/open_spec.rb:rb/non-constant-kernel-open
- input: sarif-results/${{ matrix.language }}.sarif
- output: sarif-results/${{ matrix.language }}.sarif
- if: ${{ matrix.language == 'ruby' }}
- continue-on-error: true
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
- - name: Upload SARIF
- uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
- with:
- sarif_file: sarif-results/${{ matrix.language }}.sarif
- continue-on-error: true
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml
index fbe6d5da88..caf12cc0f4 100644
--- a/.github/workflows/compilers.yml
+++ b/.github/workflows/compilers.yml
@@ -1,4 +1,3 @@
-# Some tests depending on this name 'Compilations' via $GITHUB_WORKFLOW. Make sure to update such tests when renaming this workflow.
name: Compilations
on:
@@ -9,23 +8,18 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
paths-ignore:
- 'doc/**'
- '**/man'
- - '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
merge_group:
paths-ignore:
- 'doc/**'
- '**/man'
- - '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -35,7 +29,7 @@ concurrency:
# environment variables (plus the "echo $GITHUB_ENV" hack) is to reroute that
# restriction.
env:
- default_cc: clang-17
+ default_cc: clang-15
append_cc: ''
# -O1 is faster than -O3 in our tests... Majority of time are consumed trying
@@ -56,8 +50,13 @@ env:
--without-jemalloc
--without-gmp
+ UPDATE_UNICODE: >-
+ UNICODE_FILES=.
+ UNICODE_PROPERTY_FILES=.
+ UNICODE_AUXILIARY_FILES=.
+ UNICODE_EMOJI_FILES=.
CONFIGURE_TTY: never
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
RUBY_DEBUG: ci rgengc
RUBY_TESTOPTS: >-
-q
@@ -75,7 +74,6 @@ jobs:
env:
- {}
entry:
- - { name: gcc-13, env: { default_cc: gcc-13 } }
- { name: gcc-12, env: { default_cc: gcc-12 } }
- { name: gcc-11, env: { default_cc: gcc-11 } }
- { name: gcc-10, env: { default_cc: gcc-10 } }
@@ -89,8 +87,6 @@ jobs:
optflags: '-O2'
shared: disable
# check: true
- - { name: clang-18, env: { default_cc: clang-18 } }
- - { name: clang-17, env: { default_cc: clang-17 } }
- { name: clang-16, env: { default_cc: clang-16 } }
- { name: clang-15, env: { default_cc: clang-15 } }
- { name: clang-14, env: { default_cc: clang-14 } }
@@ -111,8 +107,6 @@ jobs:
shared: disable
# check: true
- - { name: ext/Setup }
-
# - { name: aarch64-linux-gnu, crosshost: aarch64-linux-gnu, container: crossbuild-essential-arm64 }
# - { name: arm-linux-gnueabi, crosshost: arm-linux-gnueabi }
# - { name: arm-linux-gnueabihf, crosshost: arm-linux-gnueabihf }
@@ -128,27 +122,25 @@ jobs:
# warning generates a lot of noise from use of ANYARGS in
# rb_define_method() and friends.
# See: https://github.com/llvm/llvm-project/commit/11da1b53d8cd3507959022cd790d5a7ad4573d94
- - { name: c99, env: { CFLAGS: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
-# - { name: c11, env: { CFLAGS: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
-# - { name: c17, env: { CFLAGS: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
- - { name: c23, env: { CFLAGS: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+ - { name: c99, env: { append_cc: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+# - { name: c11, env: { append_cc: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+# - { name: c17, env: { append_cc: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+ - { name: c2x, env: { append_cc: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
- { name: c++98, env: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
# - { name: c++11, env: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
# - { name: c++14, env: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
# - { name: c++17, env: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
-# - { name: c++20, env: { CXXFLAGS: '-std=c++20 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
-# - { name: c++23, env: { CXXFLAGS: '-std=c++23 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
- - { name: c++26, env: { CXXFLAGS: '-std=c++26 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
+ - { name: c++2a, env: { CXXFLAGS: '-std=c++2a -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
- { name: '-O0', env: { optflags: '-O0 -march=x86-64 -mtune=generic' } }
# - { name: '-O3', env: { optflags: '-O3 -march=x86-64 -mtune=generic' }, check: true }
- - { name: gmp, env: { append_configure: '--with-gmp' }, check: true }
+ - { name: gmp, env: { append_configure: '--with-gmp' } }
- { name: jemalloc, env: { append_configure: '--with-jemalloc' } }
- { name: valgrind, env: { append_configure: '--with-valgrind' } }
- { name: 'coroutine=ucontext', env: { append_configure: '--with-coroutine=ucontext' } }
- { name: 'coroutine=pthread', env: { append_configure: '--with-coroutine=pthread' } }
- - { name: disable-jit, env: { append_configure: '--disable-yjit --disable-rjit' } }
+ - { name: disable-jit-support, env: { append_configure: '--disable-jit-support' } }
- { name: disable-dln, env: { append_configure: '--disable-dln' } }
- { name: enable-mkmf-verbose, env: { append_configure: '--enable-mkmf-verbose' } }
- { name: disable-rubygems, env: { append_configure: '--disable-rubygems' } }
@@ -172,27 +164,31 @@ jobs:
# - { name: SYMBOL_DEBUG, env: { cppflags: '-DSYMBOL_DEBUG' } }
# - { name: RGENGC_CHECK_MODE, env: { cppflags: '-DRGENGC_CHECK_MODE' } }
+# - { name: TRANSIENT_HEAP_CHECK_MODE, env: { cppflags: '-DTRANSIENT_HEAP_CHECK_MODE' } }
# - { name: VM_CHECK_MODE, env: { cppflags: '-DVM_CHECK_MODE' } }
-# - { name: USE_EMBED_CI=0, env: { cppflags: '-DUSE_EMBED_CI=0' } }
- - name: USE_FLONUM=0
+ - { name: USE_EMBED_CI=0, env: { cppflags: '-DUSE_EMBED_CI=0' } }
+ - name: USE_FLONUM=0,
env:
cppflags: '-DUSE_FLONUM=0'
# yjit requires FLONUM for the pointer tagging scheme
append_configure: '--disable-yjit'
# - { name: USE_GC_MALLOC_OBJ_INFO_DETAILS, env: { cppflags: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' } }
-# - { name: USE_LAZY_LOAD, env: { cppflags: '-DUSE_LAZY_LOAD' } }
+ - { name: USE_LAZY_LOAD, env: { cppflags: '-DUSE_LAZY_LOAD' } }
+# - { name: USE_RINCGC=0, env: { cppflags: '-DUSE_RINCGC=0' } }
# - { name: USE_SYMBOL_GC=0, env: { cppflags: '-DUSE_SYMBOL_GC=0' } }
# - { name: USE_THREAD_CACHE=0, env: { cppflags: '-DUSE_THREAD_CACHE=0' } }
- - { name: USE_RUBY_DEBUG_LOG=1, env: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } }
+# - { name: USE_TRANSIENT_HEAP=0, env: { cppflags: '-DUSE_TRANSIENT_HEAP=0' } }
+# - { name: USE_RUBY_DEBUG_LOG=1, env: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } }
+ - { name: USE_RVARGC=0, env: { cppflags: '-DUSE_RVARGC=0' } }
+# - { name: USE_RVARGC=1, env: { cppflags: '-DUSE_RVARGC=1' } }
# - { name: USE_DEBUG_COUNTER, env: { cppflags: '-DUSE_DEBUG_COUNTER=1', RUBY_DEBUG_COUNTER_DISABLE: '1' } }
- - { name: SHARABLE_MIDDLE_SUBSTRING, env: { cppflags: '-DSHARABLE_MIDDLE_SUBSTRING=1' } }
-# - { name: DEBUG_FIND_TIME_NUMGUESS, env: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } }
-# - { name: DEBUG_INTEGER_PACK, env: { cppflags: '-DDEBUG_INTEGER_PACK' } }
+ - { name: DEBUG_FIND_TIME_NUMGUESS, env: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } }
+ - { name: DEBUG_INTEGER_PACK, env: { cppflags: '-DDEBUG_INTEGER_PACK' } }
# - { name: ENABLE_PATH_CHECK, env: { cppflags: '-DENABLE_PATH_CHECK' } }
-# - { name: GC_DEBUG_STRESS_TO_CLASS, env: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } }
+ - { name: GC_DEBUG_STRESS_TO_CLASS, env: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } }
# - { name: GC_ENABLE_LAZY_SWEEP=0, env: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' } }
# - { name: GC_PROFILE_DETAIL_MEMOTY, env: { cppflags: '-DGC_PROFILE_DETAIL_MEMOTY' } }
# - { name: GC_PROFILE_MORE_DETAIL, env: { cppflags: '-DGC_PROFILE_MORE_DETAIL' } }
@@ -205,50 +201,39 @@ jobs:
# - { name: RGENGC_ESTIMATE_OLDMALLOC, env: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' } }
# - { name: RGENGC_FORCE_MAJOR_GC, env: { cppflags: '-DRGENGC_FORCE_MAJOR_GC' } }
# - { name: RGENGC_OBJ_INFO, env: { cppflags: '-DRGENGC_OBJ_INFO' } }
+# - { name: RGENGC_OLD_NEWOBJ_CHECK, env: { cppflags: '-DRGENGC_OLD_NEWOBJ_CHECK' } }
# - { name: RGENGC_PROFILE, env: { cppflags: '-DRGENGC_PROFILE' } }
# - { name: VM_DEBUG_BP_CHECK, env: { cppflags: '-DVM_DEBUG_BP_CHECK' } }
# - { name: VM_DEBUG_VERIFY_METHOD_CACHE, env: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } }
- - { name: enable-yjit, env: { append_configure: '--enable-yjit --disable-rjit' } }
- - { name: enable-rjit, env: { append_configure: '--enable-rjit --disable-yjit' } }
+ - { name: MJIT_FORCE_ENABLE, env: { cppflags: '-DMJIT_FORCE_ENABLE' } }
- { name: YJIT_FORCE_ENABLE, env: { cppflags: '-DYJIT_FORCE_ENABLE' } }
-# - { name: RJIT_FORCE_ENABLE, env: { cppflags: '-DRJIT_FORCE_ENABLE' } }
- - { name: UNIVERSAL_PARSER, env: { cppflags: '-DUNIVERSAL_PARSER' } }
name: ${{ matrix.entry.name }}
-
runs-on: ubuntu-latest
-
container:
- image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || matrix.entry.env.default_cc || 'clang-17' }}
+ image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || matrix.entry.env.default_cc || 'clang-15' }}
options: --user root
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
env: ${{ matrix.entry.env || matrix.env }}
-
steps:
- run: id
working-directory:
-
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ - run: mkdir build
+ working-directory:
+ - name: setenv
+ run: |
+ echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/directories
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
- srcdir: src
- builddir: build
- makeup: true
-
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - run: ./autogen.sh
+ working-directory: src
- name: Run configure
run: >
../src/configure -C ${default_configure} ${append_configure}
@@ -258,39 +243,38 @@ jobs:
matrix.entry.crosshost || '"${default_cc}${append_cc:+ $append_cc}"'
}}
--${{ matrix.entry.shared || 'enable' }}-shared
-
- - name: Add to ext/Setup # statically link just the etc extension
- run: mkdir ext && echo etc >> ext/Setup
- if: ${{ matrix.entry.name == 'ext/Setup' }}
-
+ - run: make extract-extlibs
+ - run: make incs
- run: make showflags
-
- run: make
-
+ - run: make leaked-globals
- run: make test
-
- run: make install
if: ${{ matrix.entry.check }}
-
- run: make test-tool
if: ${{ matrix.entry.check }}
-
- run: make test-all TESTS='-- ruby -ext-'
if: ${{ matrix.entry.check }}
-
- run: make test-spec
env:
CHECK_LEAKS: true
if: ${{ matrix.entry.check }}
-
- run: make test-annocheck
if: ${{ matrix.entry.check && endsWith(matrix.entry.name, 'annocheck') }}
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.entry.name }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.entry.name }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml
deleted file mode 100644
index 6259199b11..0000000000
--- a/.github/workflows/dependabot_automerge.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-# from https://github.com/gofiber/swagger/blob/main/.github/workflows/dependabot_automerge.yml
-name: Dependabot auto-merge
-on:
- pull_request_target:
-
-jobs:
- automerge:
- runs-on: ubuntu-latest
-
- if: ${{ github.actor == 'dependabot[bot]' }}
-
- steps:
- - name: Dependabot metadata
- uses: dependabot/fetch-metadata@c9c4182bf1b97f5224aee3906fd373f6b61b4526 # v1.6.0
- id: metadata
-
- - name: Wait for status checks
- uses: lewagon/wait-on-check-action@e106e5c43e8ca1edea6383a39a01c5ca495fd812 # v1.3.1
- with:
- repo-token: ${{ secrets.MATZBOT_GITHUB_TOKEN }}
- ref: ${{ github.event.pull_request.head.sha || github.sha }}
- check-regexp: 'make \(check, .*\)'
- wait-interval: 30
-
- - name: Auto-merge for Dependabot PRs
- if: ${{ steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch' }}
- run: gh pr merge --auto --rebase "$PR_URL"
- env:
- PR_URL: ${{ github.event.pull_request.html_url }}
- GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 6411a02d2b..d8dc58b119 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -7,10 +7,13 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
- # Do not use paths-ignore for required status checks
- # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
merge_group:
paths-ignore:
- 'doc/**'
@@ -18,7 +21,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -31,86 +33,80 @@ jobs:
make:
strategy:
matrix:
- test_task: ['check']
- configure: ['']
- os: ${{ fromJSON(format('["macos-11","macos-12"{0}]', (github.repository == 'ruby/ruby' && ',"macos-arm-oss"' || ''))) }}
- include:
- - test_task: test-all TESTS=--repeat-count=2
- os: ${{ github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-12' }}
+ test_task: ["check"] # "test-bundler-parallel", "test-bundled-gems"
+ os:
+ - macos-13
+ - macos-14
+ - macos-15
fail-fast: false
-
env:
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
-
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
runs-on: ${{ matrix.os }}
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ - run: mkdir build
+ working-directory:
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - name: Install libraries
- uses: ./.github/actions/setup/macos
-
- - uses: ./.github/actions/setup/directories
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
- srcdir: src
- builddir: build
- makeup: true
- dummy-files: ${{ matrix.test_task == 'check' }}
-
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Install libraries
+ run: |
+ brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline bison
+ working-directory: src
+ - name: Set ENV
+ run: |
+ echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
+ echo "PATH="/usr/local/opt/bison/bin:/opt/homebrew/opt/bison/bin:$PATH"" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
- name: Run configure
- run: ../src/configure -C --disable-install-doc ${{ matrix.configure }}
-
+ run: ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline)
+ - run: make incs
- run: make prepare-gems
if: ${{ matrix.test_task == 'test-bundled-gems' }}
-
- run: make
-
+ - run: make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
- name: make ${{ matrix.test_task }}
run: |
make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`}
- timeout-minutes: 60
+ timeout-minutes: 40
env:
- RUBY_TESTOPTS: '-q --tty=no'
+ RUBY_TESTOPTS: "-q --tty=no"
TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }}
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: ''
- PRECHECK_BUNDLED_GEMS: 'no'
-
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ PRECHECK_BUNDLED_GEMS: "no"
- name: make skipped tests
run: |
make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'`
env:
- GNUMAKEFLAGS: ''
- RUBY_TESTOPTS: '-v --tty=no'
+ GNUMAKEFLAGS: ""
+ RUBY_TESTOPTS: "-v --tty=no"
TESTS: ${{ matrix.skipped_tests }}
- PRECHECK_BUNDLED_GEMS: 'no'
+ PRECHECK_BUNDLED_GEMS: "no"
if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.os }} / ${{ matrix.test_task }} ${{ matrix.configure }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
- result:
- if: ${{ always() }}
- name: ${{ github.workflow }} result
- runs-on: macos-latest
- needs: [make]
- steps:
- - run: exit 1
- if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml
index df879f56b6..0df917d3d8 100644
--- a/.github/workflows/mingw.yml
+++ b/.github/workflows/mingw.yml
@@ -7,8 +7,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
- - '.*.yml'
pull_request:
paths-ignore:
- 'doc/**'
@@ -16,8 +14,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
- - '.*.yml'
merge_group:
paths-ignore:
- 'doc/**'
@@ -25,8 +21,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -41,42 +35,50 @@ permissions:
jobs:
make:
runs-on: windows-2022
-
name: ${{ github.workflow }} (${{ matrix.msystem }})
-
env:
MSYSTEM: ${{ matrix.msystem }}
MSYS2_ARCH: x86_64
- CHOST: 'x86_64-w64-mingw32'
- CFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe'
- CXXFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe'
- CPPFLAGS: '-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048'
- LDFLAGS: '-pipe'
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
-
+ CHOST: "x86_64-w64-mingw32"
+ CFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe"
+ CXXFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe"
+ CPPFLAGS: "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048"
+ LDFLAGS: "-pipe"
+ UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
strategy:
matrix:
include:
# To mitigate flakiness of MinGW CI, we test only one runtime that newer MSYS2 uses.
- - msystem: 'UCRT64'
+ - msystem: "UCRT64"
base_ruby: head
- test_task: 'check'
- test-all-opts: '--name=!/TestObjSpace#test_reachable_objects_during_iteration/'
+ test_task: "check"
+ test-all-opts: "--name=!/TestObjSpace#test_reachable_objects_during_iteration/"
fail-fast: false
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
+ - run: mkdir build
+ working-directory:
+ - name: git config
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
- name: Set up Ruby & MSYS2
- uses: ruby/setup-ruby@036ef458ddccddb148a2b9fb67e95a22fdbf728b # v1.160.0
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.base_ruby }}
+ - name: set env
+ run: |
+ echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV
- name: where check
run: |
@@ -84,83 +86,92 @@ jobs:
mv /c/Windows/System32/libcrypto-1_1-x64.dll /c/Windows/System32/libcrypto-1_1-x64.dll_
mv /c/Windows/System32/libssl-1_1-x64.dll /c/Windows/System32/libssl-1_1-x64.dll_
result=true
- for e in gcc.exe ragel.exe make.exe libcrypto-1_1-x64.dll libssl-1_1-x64.dll; do
- echo ::group::$'\033[93m'$e$'\033[m'
+ for e in gcc.exe ragel.exe make.exe bison.exe libcrypto-1_1-x64.dll libssl-1_1-x64.dll; do
+ echo '##['group']'$'\033[93m'$e$'\033[m'
where $e || result=false
- echo ::endgroup::
+ echo '##['endgroup']'
done
$result
- working-directory:
- name: version check
run: |
# show version
result=true
- for e in gcc ragel make "openssl version"; do
+ for e in gcc ragel make bison "openssl version"; do
case "$e" in *" "*) ;; *) e="$e --version";; esac
- echo ::group::$'\033[93m'$e$'\033[m'
+ echo '##['group']'$'\033[93m'$e$'\033[m'
$e || result=false
- echo ::endgroup::
+ echo '##['endgroup']'
done
$result
- working-directory:
-
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
- - uses: ./.github/actions/setup/directories
- with:
- srcdir: src
- builddir: build
- makeup: true
+ - name: autogen
+ run: |
+ ./autogen.sh
+ working-directory: src
- name: configure
run: >
../src/configure --disable-install-doc --prefix=/.
--build=$CHOST --host=$CHOST --target=$CHOST
+ - name: update
+ run: |
+ make incs
+
+ - name: download gems
+ run: |
+ make update-gems
+
- name: make all
timeout-minutes: 30
- run: make
+ run: |
+ make
+
+ - run: make leaked-globals
- name: make install
- run: make DESTDIR=../install install-nodoc
+ run: |
+ make DESTDIR=../install install-nodoc
- name: test
- timeout-minutes: 30
- run: make test
- shell: cmd
- env:
- GNUMAKEFLAGS: ''
- RUBY_TESTOPTS: '-v --tty=no'
- if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test' }}
+ timeout-minutes: 5
+ run: |
+ make test
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test'}}
- name: test-all
timeout-minutes: 45
- shell: cmd
run: |
+ # Actions uses UTF8, causes test failures, similar to normal OS setup
+ chcp.com 437
make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }}
env:
RUBY_TESTOPTS: >-
--retry --job-status=normal --show-skip --timeout-scale=1.5
${{ matrix.test-all-opts }}
BUNDLER_VERSION:
- if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test-all' || StartsWith(matrix.test_task, 'test/') }}
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-all' || StartsWith(matrix.test_task, 'test/')}}
- name: test-spec
timeout-minutes: 10
run: |
make ${{ StartsWith(matrix.test_task, 'spec/') && matrix.test_task || 'test-spec' }}
- shell: cmd
- if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/') }}
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/')}}
- - uses: ./src/.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.msystem }} / ${{ matrix.test_task }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} ${{ matrix.msystem }} / ${{ matrix.test_task }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/mjit-bindgen.yml b/.github/workflows/mjit-bindgen.yml
new file mode 100644
index 0000000000..26f8a1b2aa
--- /dev/null
+++ b/.github/workflows/mjit-bindgen.yml
@@ -0,0 +1,104 @@
+name: MJIT bindgen
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
+jobs:
+ make:
+ strategy:
+ matrix:
+ include:
+ - task: mjit-bindgen
+ fail-fast: false
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y \
+ build-essential \
+ libssl-dev libyaml-dev libreadline6-dev \
+ zlib1g-dev libncurses5-dev libffi-dev \
+ libclang1-14 \
+ bison autoconf
+ sudo apt-get install -q -y pkg-config || :
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
+ with:
+ ruby-version: '3.1'
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install --enable-yjit=dev_nodebug
+ - run: make incs
+ - run: make
+ - run: make install
+ - run: make ${{ matrix.task }}
+ - run: git diff --exit-code
+ working-directory: src
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml
new file mode 100644
index 0000000000..6f7181489a
--- /dev/null
+++ b/.github/workflows/mjit.yml
@@ -0,0 +1,113 @@
+name: MJIT
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ - '**.[1-8]'
+ - '**.ronn'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ - '**.[1-8]'
+ - '**.ronn'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
+jobs:
+ make:
+ strategy:
+ matrix:
+ test_task: [check] # to make job names consistent
+ mjit_opts: [--mjit-wait]
+ fail-fast: false
+ runs-on: ubuntu-latest
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ env:
+ TESTOPTS: '-q --tty=no'
+ RUN_OPTS: '--disable-gems ${{ matrix.mjit_opts }} --mjit-debug=-ggdb3'
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc cppflags=-DVM_CHECK_MODE
+ - run: make incs
+ - run: make
+ - run: sudo make -s install
+ - name: Run test
+ run: |
+ unset GNUMAKEFLAGS
+ make -s test RUN_OPTS="$RUN_OPTS"
+ timeout-minutes: 60
+ # - name: Run test-all
+ # run: |
+ # ulimit -c unlimited
+ # make -s test-all RUN_OPTS="$RUN_OPTS"
+ # timeout-minutes: 60
+ - name: Run test-spec
+ run: |
+ unset GNUMAKEFLAGS
+ make -s test-spec RUN_OPTS="$RUN_OPTS"
+ timeout-minutes: 60
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.mjit_opts }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000000..5d4474d978
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,18 @@
+name: Start release workflow
+on:
+ push:
+ tags:
+ - '*'
+
+jobs:
+ notify:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Build release package
+ run: |
+ curl -L -X POST \
+ -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/ruby/actions/dispatches \
+ -d '{"event_type": "${{ github.ref }}"}'
diff --git a/.github/workflows/rjit-bindgen.yml b/.github/workflows/rjit-bindgen.yml
deleted file mode 100644
index bf3c752e7b..0000000000
--- a/.github/workflows/rjit-bindgen.yml
+++ /dev/null
@@ -1,91 +0,0 @@
-name: RJIT bindgen
-on:
- push:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
- pull_request:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
- merge_group:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
-
-concurrency:
- group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
- cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-
-permissions:
- contents: read
-
-jobs:
- make:
- strategy:
- matrix:
- include:
- - task: rjit-bindgen
- fail-fast: false
-
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
- steps:
- - name: Set up Ruby
- uses: ruby/setup-ruby@036ef458ddccddb148a2b9fb67e95a22fdbf728b # v1.160.0
- with:
- ruby-version: '3.1'
-
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/ubuntu
-
- - uses: ./.github/actions/setup/directories
- with:
- srcdir: src
- builddir: build
- makeup: true
-
- - name: Run configure
- run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install --enable-yjit=dev_nodebug
-
- - run: make
-
- - run: make install
-
- - run: make ${{ matrix.task }}
-
- - run: git diff --exit-code
- working-directory: src
-
- - uses: ./.github/actions/slack
- with:
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
-defaults:
- run:
- working-directory: build
diff --git a/.github/workflows/rjit.yml b/.github/workflows/rjit.yml
deleted file mode 100644
index bf9122f581..0000000000
--- a/.github/workflows/rjit.yml
+++ /dev/null
@@ -1,120 +0,0 @@
-name: RJIT
-on:
- push:
- paths-ignore:
- - 'doc/**'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '**.[1-8]'
- - '**.ronn'
- - '.*.yml'
- pull_request:
- paths-ignore:
- - 'doc/**'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '**.[1-8]'
- - '**.ronn'
- - '.*.yml'
- merge_group:
- paths-ignore:
- - 'doc/**'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '**.[1-8]'
- - '**.ronn'
- - '.*.yml'
-
-concurrency:
- group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
- cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-
-permissions:
- contents: read
-
-jobs:
- make:
- strategy:
- matrix:
- # main variables included in the job name
- test_task: [check]
- run_opts: ['--rjit-call-threshold=1']
- arch: ['']
- fail-fast: false
-
- env:
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
- RUBY_DEBUG: ci
- SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }}
-
- runs-on: ubuntu-22.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
- steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/ubuntu
-
- - uses: ./.github/actions/setup/directories
- with:
- srcdir: src
- builddir: build
- makeup: true
-
- - name: Run configure
- env:
- arch: ${{ matrix.arch }}
- run: >-
- $SETARCH ../src/configure -C --disable-install-doc cppflags=-DRUBY_DEBUG
- ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE}
-
- - run: $SETARCH make
-
- - name: make test
- run: |
- $SETARCH make -s test RUN_OPTS="$RUN_OPTS"
- timeout-minutes: 30
- env:
- GNUMAKEFLAGS: ''
- RUBY_TESTOPTS: '-v --tty=no'
- RUN_OPTS: ${{ matrix.run_opts }}
-
- - name: make test-all
- run: |
- $SETARCH make -s test-all RUN_OPTS="$RUN_OPTS"
- timeout-minutes: 40
- env:
- GNUMAKEFLAGS: ''
- RUBY_TESTOPTS: '-q --tty=no'
- RUN_OPTS: ${{ matrix.run_opts }}
-
- - name: make test-spec
- run: |
- $SETARCH make -s test-spec RUN_OPTS="$RUN_OPTS"
- timeout-minutes: 10
- env:
- GNUMAKEFLAGS: ''
- RUN_OPTS: ${{ matrix.run_opts }}
-
- - uses: ./.github/actions/slack
- with:
- label: ${{ matrix.run_opts }}
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
-defaults:
- run:
- working-directory: build
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 51ce54a518..c12a95362d 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -11,8 +11,8 @@ on:
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '22 4 * * 2'
- # push:
- # branches: [ "master" ]
+ push:
+ branches: [ "master" ]
# Declare default permissions as read only.
permissions: read-all
@@ -31,13 +31,13 @@ jobs:
# actions: read
steps:
- - name: 'Checkout code'
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ - name: "Checkout code"
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: 'Run analysis'
- uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@ea651e62978af7915d09fe2e282747c798bf2dab # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@@ -58,15 +58,15 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- # - name: "Upload artifact"
- # uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
- # with:
- # name: SARIF file
- # path: results.sarif
- # retention-days: 5
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- - name: 'Upload to code-scanning'
- uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.1.27
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.27
with:
sarif_file: results.sarif
diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml
index e14e7818a6..4521195a2b 100644
--- a/.github/workflows/spec_guards.yml
+++ b/.github/workflows/spec_guards.yml
@@ -6,13 +6,10 @@ on:
- 'spec/**'
- '!spec/*.md'
pull_request:
- paths-ignore:
+ paths:
- 'spec/**'
- '!spec/*.md'
merge_group:
- paths-ignore:
- - 'spec/**'
- - '!spec/*.md'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -25,13 +22,15 @@ jobs:
rubyspec:
name: Rubyspec
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
if: >-
${{!(false
|| contains(github.event.head_commit.message, '[DOC]')
+ || contains(github.event.head_commit.message, 'Document')
|| contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
+ || contains(github.event.pull_request.title, 'Document')
+ || contains(github.event.pull_request.labels.*.name, 'Document')
|| (github.event_name == 'push' && github.actor == 'dependabot[bot]')
)}}
@@ -40,14 +39,13 @@ jobs:
# Specs from ruby/spec should still run on all supported Ruby versions.
# This also ensures the needed ruby_version_is guards are there, see spec/README.md.
ruby:
- - ruby-3.0
- ruby-3.1
- ruby-3.2
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- - uses: ruby/setup-ruby@036ef458ddccddb148a2b9fb67e95a22fdbf728b # v1.160.0
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
@@ -58,9 +56,16 @@ jobs:
working-directory: spec/ruby
env:
CHECK_LEAKS: true
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.ruby }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / rubyspec @ ${{ matrix.ruby }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
if: ${{ failure() }}
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index 93ced0d1d2..4fbca1170e 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -7,10 +7,13 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
- # Do not use paths-ignore for required status checks
- # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
merge_group:
paths-ignore:
- 'doc/**'
@@ -18,7 +21,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -31,101 +33,113 @@ jobs:
make:
strategy:
matrix:
+ # main variables included in the job name
test_task: [check]
+ configure: [cppflags=-DRUBY_DEBUG] # default to use more assertions
arch: ['']
- configure: ['cppflags=-DVM_CHECK_MODE']
- # specifying other jobs with `include` to avoid redundant tests
+ # specify all jobs with `include` to avoid testing duplicated things
include:
- test_task: check
- arch: i686
- test_task: check
- configure: '--disable-yjit'
+ arch: i686
+ configure: '' # test without -DRUBY_DEBUG as well
- test_task: check
- configure: '--enable-shared --enable-load-relative'
+ configure: "--enable-shared --enable-load-relative"
+ - test_task: test-all TESTS=--repeat-count=2
- test_task: test-bundler-parallel
- test_task: test-bundled-gems
fail-fast: false
-
env:
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
RUBY_DEBUG: ci
-
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }}
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/ubuntu
+ - run: mkdir build
+ working-directory:
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - name: Install libraries
+ env:
+ arch: ${{matrix.arch}}
+ run: |
+ set -x
+ arch=${arch:+:${arch/i[3-6]86/i386}}
+ ${arch:+sudo dpkg --add-architecture ${arch#:}}
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y \
+ ${arch:+cross}build-essential${arch/:/-} \
+ libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \
+ zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \
+ bison autoconf ruby
+ sudo apt-get install -q -y pkg-config${arch} || :
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
- arch: ${{ matrix.arch }}
-
- - uses: ./.github/actions/setup/directories
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
- srcdir: src
- builddir: build
- makeup: true
- dummy-files: ${{ matrix.test_task == 'check' }}
-
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - run: ./autogen.sh
+ working-directory: src
- name: Run configure
env:
- arch: ${{ matrix.arch }}
- configure: ${{ matrix.configure }}
+ arch: ${{matrix.arch}}
run: >-
- $SETARCH ../src/configure -C --disable-install-doc ${configure:-cppflags=-DRUBY_DEBUG}
+ $SETARCH ../src/configure -C --disable-install-doc ${{ matrix.configure }}
${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE}
-
+ - run: $SETARCH make incs
- run: $SETARCH make prepare-gems
if: ${{ matrix.test_task == 'test-bundled-gems' }}
-
- run: $SETARCH make
-
+ - run: $SETARCH make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
+ - name: Create dummy files in build dir
+ run: |
+ $SETARCH ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}'
+ if: ${{ matrix.test_task == 'check' }}
- name: make ${{ matrix.test_task }}
- run: >-
- $SETARCH make -s ${{ matrix.test_task }}
- ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`}
- ${{ !contains(matrix.test_task, 'bundle') && 'RUBYOPT=-w' || '' }}
+ run: |
+ $SETARCH make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`}
timeout-minutes: 40
env:
- RUBY_TESTOPTS: '-q --tty=no'
+ RUBY_TESTOPTS: "-q --tty=no"
TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }}
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: ''
- PRECHECK_BUNDLED_GEMS: 'no'
-
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ PRECHECK_BUNDLED_GEMS: "no"
- name: make skipped tests
run: |
$SETARCH make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'`
env:
- GNUMAKEFLAGS: ''
- RUBY_TESTOPTS: '-v --tty=no'
+ GNUMAKEFLAGS: ""
+ RUBY_TESTOPTS: "-v --tty=no"
TESTS: ${{ matrix.skipped_tests }}
if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
- result:
- if: ${{ always() }}
- name: ${{ github.workflow }} result
- runs-on: ubuntu-latest
- needs: [make]
- steps:
- - run: exit 1
- if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml
index f69df0f58d..27920b5821 100644
--- a/.github/workflows/wasm.yml
+++ b/.github/workflows/wasm.yml
@@ -7,7 +7,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
paths-ignore:
- 'doc/**'
@@ -15,7 +14,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
merge_group:
paths-ignore:
- 'doc/**'
@@ -23,13 +21,12 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-permissions: # added using https://github.com/step-security/secure-workflows
+permissions: # added using https://github.com/step-security/secure-workflows
contents: read
jobs:
@@ -38,50 +35,38 @@ jobs:
matrix:
entry:
# # wasmtime can't compile non-optimized Asyncified binary due to locals explosion
-# - { name: O0-debuginfo, optflags: '-O0', debugflags: '-g', wasmoptflags: '-O1' }
-# - { name: O1, optflags: '-O1', debugflags: '' , wasmoptflags: '-O1' }
- - { name: O2, optflags: '-O2', debugflags: '', wasmoptflags: '-O2' }
-# - { name: O3, optflags: '-O3', debugflags: '' , wasmoptflags: '-O3' }
+# - { name: O0-debuginfo, optflags: "-O0", debugflags: "-g", wasmoptflags: "-O1" }
+# - { name: O1, optflags: "-O1", debugflags: "" , wasmoptflags: "-O1" }
+ - { name: O2, optflags: "-O2", debugflags: "" , wasmoptflags: "-O2" }
+# - { name: O3, optflags: "-O3", debugflags: "" , wasmoptflags: "-O3" }
# # -O4 is equivalent to -O3 in clang, but it's different in wasm-opt
-# - { name: O4, optflags: '-O3', debugflags: '' , wasmoptflags: '-O4' }
-# - { name: Oz, optflags: '-Oz', debugflags: '' , wasmoptflags: '-Oz' }
+# - { name: O4, optflags: "-O3", debugflags: "" , wasmoptflags: "-O4" }
+# - { name: Oz, optflags: "-Oz", debugflags: "" , wasmoptflags: "-Oz" }
fail-fast: false
-
env:
RUBY_TESTOPTS: '-q --tty=no'
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
- WASI_SDK_VERSION_MAJOR: 20
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ WASI_SDK_VERSION_MAJOR: 14
WASI_SDK_VERSION_MINOR: 0
- BINARYEN_VERSION: 113
- WASMTIME_VERSION: v15.0.0
-
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ BINARYEN_VERSION: 109
+ WASMTIME_VERSION: v0.33.0
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/directories
+ - run: mkdir build
+ working-directory:
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
- srcdir: src
- builddir: build
- makeup: true
-
+ path: src
- name: Install libraries
run: |
set -ex
sudo apt-get update -q || :
- sudo apt-get install --no-install-recommends -q -y ruby make autoconf git wget
+ sudo apt-get install --no-install-recommends -q -y ruby bison make autoconf git wget
wasi_sdk_deb="wasi-sdk_${WASI_SDK_VERSION_MAJOR}.${WASI_SDK_VERSION_MINOR}_amd64.deb"
wget "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION_MAJOR}/${wasi_sdk_deb}"
@@ -100,27 +85,29 @@ jobs:
wget -O - "$binaryen_url" | tar xfz -
sudo ln -fs "$PWD/binaryen-version_${BINARYEN_VERSION}/bin/wasm-opt" /usr/local/bin/wasm-opt
working-directory: src
-
- name: Set ENV
run: |
+ echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
- - name: Build baseruby
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
+ with:
+ ruby-version: '3.0'
+ bundler: none
+
+ - name: Download config.guess with wasi version
run: |
- set -ex
- mkdir ../baseruby
- pushd ../baseruby
- ../src/configure --prefix=$PWD/install
- make
- make install
+ rm tool/config.guess tool/config.sub
+ ruby tool/downloader.rb -d tool -e gnu config.guess config.sub
+ working-directory: src
- name: Run configure
run: |
../src/configure \
--host wasm32-unknown-wasi \
- --with-baseruby=$PWD/../baseruby/install/bin/ruby \
--with-static-linked-ext \
- --with-ext=bigdecimal,cgi/escape,continuation,coverage,date,dbm,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,fiber,gdbm,json,json/generator,json/parser,nkf,objspace,pathname,racc/cparse,rbconfig/sizeof,ripper,stringio,strscan,monitor \
LDFLAGS=" \
-Xlinker --stack-first \
-Xlinker -z -Xlinker stack-size=16777216 \
@@ -131,31 +118,28 @@ jobs:
# miniruby may not be built when cross-compling
- run: make mini ruby
-
- - run: make install DESTDIR=$PWD/../install
- - run: tar cfz ../install.tar.gz -C ../install .
-
- - name: Upload artifacts
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
- with:
- name: ruby-wasm-install
- path: ${{ github.workspace }}/install.tar.gz
-
- name: Run basictest
run: wasmtime run ./../build/miniruby --mapdir /::./ -- basictest/test.rb
working-directory: src
-
- name: Run bootstraptest (no thread)
run: |
NO_THREAD_TESTS="$(grep -L Thread -R ./bootstraptest | awk -F/ '{ print $NF }' | uniq | sed -n 's/test_\(.*\).rb/\1/p' | paste -s -d, -)"
ruby ./bootstraptest/runner.rb --ruby="$(which wasmtime) run $PWD/../build/ruby --mapdir /::./ -- " --verbose "--sets=$NO_THREAD_TESTS"
working-directory: src
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.entry.name }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.name }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 8b34f962fe..c2bd4881c2 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -7,7 +7,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
paths-ignore:
- 'doc/**'
@@ -15,7 +14,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
merge_group:
paths-ignore:
- 'doc/**'
@@ -23,7 +21,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -37,163 +34,114 @@ jobs:
strategy:
matrix:
include:
- - vs: 2019
- vs: 2022
+ vcvers: -vcvars_ver=14.2
fail-fast: false
-
- runs-on: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }}
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ runs-on: windows-${{ matrix.vs }}
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
name: VisualStudio ${{ matrix.vs }}
-
env:
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
- OS_VER: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }}
- # FIXME: This is a workaround for the vcpkg's issue present as of openssl 3.1.1
- # where OpenSSL's default modules directory is incorrectly set to C:\vcpkg\packages\openssl_x64-windows\bin
- # cf. https://github.com/ruby/openssl/pull/635#issuecomment-1596833720
- OPENSSL_MODULES: C:\vcpkg\installed\x64-windows\bin
-
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ PATCH: C:\msys64\usr\bin\patch.exe
+ OS_VER: windows-${{ matrix.vs }}
steps:
- run: md build
working-directory:
-
- - name: find tools
- id: find-tools
- run: |
- ::- find needed tools
- set NEEDS=
- for %%I in (%NEEDED_TOOLS%) do if "%%~$PATH:I" == "" (
- call set NEEDS=%%NEEDS%% %%~nI
- ) else (
- echo %%I: %%~$PATH:I
- )
- echo.needs=%NEEDS%>>%GITHUB_OUTPUT%
- if "%NEEDS%" == "" (
- echo [debug] All needed tools found
- ) else (
- echo [warning^]Needs%NEEDS%
- )
- env:
- NEEDED_TOOLS: >-
- patch.exe
-
- - uses: msys2/setup-msys2@d40200dc2db4c351366b048a9565ad82919e1c24 # v2
+ - uses: msys2/setup-msys2@61f9e5e925871ba6c9e3e8da24ede83ea27fa91f # v2.27.0
id: setup-msys2
with:
update: true
- install: >-
- ${{ steps.find-tools.outputs.needs }}
- if: ${{ steps.find-tools.outputs.needs != '' }}
-
- - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
- with:
- path: C:\vcpkg\downloads
- key: ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}-
- ${{ runner.os }}-vcpkg-download-
-
- - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
+ install: bison patch
+ - name: patch path
+ shell: msys2 {0}
+ run: echo PATCH=$(cygpath -wa $(command -v patch)) >> $GITHUB_ENV
+ if: ${{ steps.setup-msys2.outcome == 'success' }}
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: C:\vcpkg\installed
- key: ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}-${{ github.sha }}
+ key: ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-${{ github.sha }}
restore-keys: |
- ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}-
- ${{ runner.os }}-vcpkg-installed-
-
+ ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-
+ ${{ runner.os }}-vcpkg-installed-windows-
- name: Install libraries with vcpkg
run: |
- vcpkg --triplet x64-windows install libffi libyaml openssl readline zlib
-
- - name: Install libraries with scoop
- run: |
iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
- shell: pwsh
-
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ scoop install cmake@3.31.6
+ vcpkg --triplet x64-windows install libffi libyaml openssl readline zlib
+ shell:
+ pwsh
+ - name: git config
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/directories
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
- srcdir: src
- builddir: build
-
+ path: src/.downloaded-cache
+ key: downloaded-cache
- name: setup env
# %TEMP% is inconsistent with %TMP% and test-all expects they are consistent.
# https://github.com/actions/virtual-environments/issues/712#issuecomment-613004302
+ # msys2/setup-msys2 installs MSYS2 to D:/a/_temp/msys64/usr/bin
run: |
- set VS=${{ matrix.vs }}
- set VCVARS=${{ matrix.vcvars || '' }}
+ set Path=D:/a/_temp/msys64/usr/bin;%Path%
if not "%VCVARS%" == "" goto :vcset
- set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
:vcset
set | C:\msys64\usr\bin\sort > old.env
- call %VCVARS%
- nmake -f nul
+ call %VCVARS% ${{ matrix.vcvers || ''}}
set TMP=%USERPROFILE%\AppData\Local\Temp
set TEMP=%USERPROFILE%\AppData\Local\Temp
- set MAKEFLAGS=l
set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul
set | C:\msys64\usr\bin\sort > new.env
C:\msys64\usr\bin\comm -13 old.env new.env >> %GITHUB_ENV%
del *.env
-
- name: compiler version
run: cl
-
- name: link libraries
run: |
for %%I in (C:\vcpkg\installed\x64-windows\bin\*.dll) do (
if not %%~nI == readline mklink %%~nxI %%I
)
- # We use OpenSSL instealled by vcpkg instead
- - name: disable system OpenSSL
- run: |
for %%I in (libcrypto-1_1-x64 libssl-1_1-x64) do (
ren c:\Windows\System32\%%I.dll %%I.dll_
)
- # windows-2019 image doesn't have OpenSSL as of 2023/9/14
- if: ${{ matrix.vs != 2019 }}
-
- name: Configure
run: >-
../src/win32/configure.bat --disable-install-doc
--with-opt-dir=C:/vcpkg/installed/x64-windows
-
- run: nmake incs
-
- run: nmake extract-extlibs
-
- run: nmake
-
+ env:
+ YACC: bison.exe
- run: nmake test
timeout-minutes: 5
-
- run: nmake test-spec
timeout-minutes: 10
-
- run: nmake test-all
env:
- RUBY_TESTOPTS: -j${{ env.TEST_JOBS || 4 }} --job-status=normal
+ RUBY_TESTOPTS: -j${{env.TEST_JOBS}} --job-status=normal
timeout-minutes: 60
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: VS${{ matrix.vs }} / ${{ matrix.test_task || 'check' }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "VS${{ matrix.vs }} / ${{ matrix.test_task || 'check' }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/yjit-macos.yml b/.github/workflows/yjit-macos.yml
deleted file mode 100644
index 11e200a619..0000000000
--- a/.github/workflows/yjit-macos.yml
+++ /dev/null
@@ -1,151 +0,0 @@
-name: YJIT macOS Arm64
-on:
- push:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
- pull_request:
- # Do not use paths-ignore for required status checks
- # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
- merge_group:
- paths-ignore:
- - 'doc/**'
- - '**/man'
- - '**.md'
- - '**.rdoc'
- - '**/.document'
- - '.*.yml'
-
-concurrency:
- group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
- cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-
-permissions:
- contents: read
-
-jobs:
- cargo:
- name: cargo test
-
- runs-on: macos-arm-oss
-
- if: >-
- ${{github.repository == 'ruby/ruby' &&
- !(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
- steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
- - run: RUST_BACKTRACE=1 cargo test
- working-directory: yjit
-
- # Also compile and test with all features enabled
- - run: RUST_BACKTRACE=1 cargo test --all-features
- working-directory: yjit
-
- # Check that we can build in release mode too
- - run: cargo build --release
- working-directory: yjit
-
- make:
- strategy:
- matrix:
- include:
- - test_task: 'check'
- configure: '--enable-yjit'
- yjit_opts: '--yjit'
- - test_task: 'check'
- configure: '--enable-yjit=dev'
- yjit_opts: '--yjit-call-threshold=1 --yjit-verify-ctx --yjit-code-gc'
- fail-fast: false
-
- env:
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
- RUN_OPTS: ${{ matrix.yjit_opts }}
-
- runs-on: macos-arm-oss
-
- if: >-
- ${{github.repository == 'ruby/ruby' &&
- !(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
- steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - name: Install libraries
- uses: ./.github/actions/setup/macos
-
- - uses: ./.github/actions/setup/directories
- with:
- srcdir: src
- builddir: build
- makeup: true
- dummy-files: ${{ matrix.test_task == 'check' }}
-
- - name: Run configure
- run: ../src/configure -C --disable-install-doc ${{ matrix.configure }}
-
- - run: make prepare-gems
- if: ${{ matrix.test_task == 'test-bundled-gems' }}
-
- - run: make
-
- - name: Enable YJIT through ENV
- run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
-
- - name: make ${{ matrix.test_task }}
- run: |
- make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`}
- timeout-minutes: 60
- env:
- RUBY_TESTOPTS: '-q --tty=no'
- TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }}
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: ''
- PRECHECK_BUNDLED_GEMS: 'no'
-
- - name: make skipped tests
- run: |
- make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'`
- env:
- GNUMAKEFLAGS: ''
- RUBY_TESTOPTS: '-v --tty=no'
- TESTS: ${{ matrix.skipped_tests }}
- PRECHECK_BUNDLED_GEMS: 'no'
- if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
- continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
-
- - uses: ./.github/actions/slack
- with:
- label: ${{ matrix.test_task }} ${{ matrix.configure }} ${{ matrix.yjit_opts }}
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
- result:
- if: ${{ always() && github.repository == 'ruby/ruby' }}
- name: ${{ github.workflow }} result
- runs-on: macos-arm-oss
- needs: [make]
- steps:
- - run: exit 1
- if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
-
-defaults:
- run:
- working-directory: build
diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml
index ec8483b7d1..0b7b9046e9 100644
--- a/.github/workflows/yjit-ubuntu.yml
+++ b/.github/workflows/yjit-ubuntu.yml
@@ -7,10 +7,13 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
pull_request:
- # Do not use paths-ignore for required status checks
- # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
merge_group:
paths-ignore:
- 'doc/**'
@@ -18,7 +21,6 @@ on:
- '**.md'
- '**.rdoc'
- '**/.document'
- - '.*.yml'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -29,58 +31,22 @@ permissions:
jobs:
cargo:
- name: cargo test
-
+ name: Rust cargo test
# GitHub Action's image seems to already contain a Rust 1.58.0.
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# For now we can't run cargo test --offline because it complains about the
# capstone dependency, even though the dependency is optional
#- run: cargo test --offline
-
- run: RUST_BACKTRACE=1 cargo test
working-directory: yjit
-
# Also compile and test with all features enabled
- run: RUST_BACKTRACE=1 cargo test --all-features
working-directory: yjit
-
# Check that we can build in release mode too
- run: cargo build --release
working-directory: yjit
-
- lint:
- name: cargo clippy
-
- # GitHub Action's image seems to already contain a Rust 1.58.0.
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
- steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
- # Check that we don't have linting errors in release mode, too
- - run: cargo clippy --all-targets --all-features
- working-directory: yjit
-
make:
strategy:
fail-fast: false
@@ -88,114 +54,116 @@ jobs:
include:
- test_task: 'yjit-bindgen'
hint: 'To fix: use patch in logs'
- configure: '--with-gcc=clang-12 --enable-yjit=dev'
+ configure: '--with-gcc=clang-14 --enable-yjit=dev'
+ libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1'
- - test_task: 'check'
+ - test_task: "check"
# YJIT should be automatically built in release mode on x86-64 Linux with rustc present
#configure: "--enable-yjit RUSTC='rustc +1.58.0'"
configure: "RUSTC='rustc +1.58.0'"
- rust_version: '1.58.0'
+ rust_version: "1.58.0"
- - test_task: 'check'
- configure: '--enable-yjit=dev'
+ - test_task: "check"
+ configure: "--enable-yjit=dev"
- - test_task: 'check'
- configure: '--enable-yjit=dev'
- yjit_opts: '--yjit-call-threshold=1 --yjit-verify-ctx --yjit-code-gc'
+ - test_task: "check"
+ configure: "--enable-yjit=dev"
+ yjit_opts: "--yjit-call-threshold=1 --yjit-verify-ctx"
- - test_task: 'test-bundled-gems'
- configure: '--enable-yjit=dev'
+ - test_task: "test-all TESTS=--repeat-count=2"
+ configure: "--enable-yjit=dev"
- - test_task: 'yjit-bench'
- configure: '--enable-yjit=dev'
- yjit_bench_opts: '--yjit-stats'
+ - test_task: "test-bundled-gems"
+ configure: "--enable-yjit=dev"
+ - test_task: "yjit-bench"
+ configure: "--enable-yjit=dev"
+ yjit_bench_opts: "--yjit-stats"
env:
- GITPULLOPTIONS: --no-tags origin ${{ github.ref }}
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
RUN_OPTS: ${{ matrix.yjit_opts }}
YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }}
RUBY_DEBUG: ci
BUNDLE_JOBS: 8 # for yjit-bench
- RUST_BACKTRACE: 1
-
- runs-on: ubuntu-20.04
-
- if: >-
- ${{!(false
- || contains(github.event.head_commit.message, '[DOC]')
- || contains(github.event.pull_request.title, '[DOC]')
- || contains(github.event.pull_request.labels.*.name, 'Documentation')
- || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
- )}}
-
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- with:
- sparse-checkout-cone-mode: false
- sparse-checkout: /.github
-
- - uses: ./.github/actions/setup/ubuntu
-
- - uses: ./.github/actions/setup/directories
- with:
- srcdir: src
- builddir: build
- makeup: true
- dummy-files: ${{ matrix.test_task == 'check' }}
-
+ - run: mkdir build
+ working-directory:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
- name: Install Rust
if: ${{ matrix.rust_version }}
run: rustup install ${{ matrix.rust_version }} --profile minimal
-
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
- name: Run configure
run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install ${{ matrix.configure }}
-
- run: make incs
-
- run: make prepare-gems
if: ${{ matrix.test_task == 'test-bundled-gems' }}
-
- - run: make
-
+ - run: make -j
+ - run: make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
+ - name: Create dummy files in build dir
+ run: |
+ ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}'
+ if: ${{ matrix.test_task == 'check' }}
- name: Enable YJIT through ENV
run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
-
# Check that the binary was built with YJIT
- name: Check YJIT enabled
run: ./miniruby --yjit -v | grep "+YJIT"
-
- name: make ${{ matrix.test_task }}
- run: make -s -j ${{ matrix.test_task }} RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS" YJIT_BINDGEN_DIFF_OPTS="$YJIT_BINDGEN_DIFF_OPTS"
+ run: make -s -j ${{ matrix.test_task }} RUN_OPTS="$RUN_OPTS" YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS"
timeout-minutes: 60
env:
- RUBY_TESTOPTS: '-q --tty=no'
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'rbs'
- PRECHECK_BUNDLED_GEMS: 'no'
- SYNTAX_SUGGEST_TIMEOUT: '5'
- YJIT_BINDGEN_DIFF_OPTS: '--exit-code'
+ RUBY_TESTOPTS: "-q --tty=no"
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ PRECHECK_BUNDLED_GEMS: "no"
+ LIBCLANG_PATH: ${{ matrix.libclang_path }}
continue-on-error: ${{ matrix.test_task == 'yjit-bench' }}
-
- name: Show ${{ github.event.pull_request.base.ref }} GitHub URL for yjit-bench comparison
run: echo "https://github.com/${BASE_REPO}/commit/${BASE_SHA}"
env:
BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
if: ${{ matrix.test_task == 'yjit-bench' && startsWith(github.event_name, 'pull') }}
-
- - uses: ./.github/actions/slack
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
- label: ${{ matrix.test_task }} ${{ matrix.configure }}
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.configure }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() }}
-
- result:
- if: ${{ always() }}
- name: ${{ github.workflow }} result
- runs-on: ubuntu-latest
- needs: [make]
- steps:
- - run: exit 1
- if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.gitignore b/.gitignore
index b6beba3b3e..99d32a1825 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,7 +50,6 @@ y.tab.c
*.gcno
*.gcov
*.vscode
-!misc/.vscode
lcov*.info
# /
@@ -124,7 +123,6 @@ lcov*.info
/repack
/revision.h
/revision.tmp
-/ripper.tmp.y
/riscos
/rubicon
/ruby
@@ -138,7 +136,6 @@ lcov*.info
/test.rb
/test-coverage.dat
/tmp
-/vcpkg_installed
/transdb.h
/uncommon.mk
/verconf.h
@@ -167,7 +164,6 @@ lcov*.info
# /coroutine/
!/coroutine/**/*.s
-!/coroutine/**/*.S
# /enc/trans/
/enc/trans/*.c
@@ -207,10 +203,8 @@ lcov*.info
# /ext/ripper/
/ext/ripper/eventids1.c
-/ext/ripper/eventids1.h
/ext/ripper/.eventids2-check
/ext/ripper/eventids2table.c
-/ext/ripper/ripper_init.c
/ext/ripper/ripper.*
/ext/ripper/ids1
/ext/ripper/ids2
@@ -232,9 +226,8 @@ lcov*.info
# /misc/
/misc/**/__pycache__
-# for `make test-bundler`
+# /spec/bundler
/.rspec_status
-/tool/bundler/*.lock
# /tool/
/tool/config.guess
@@ -243,12 +236,11 @@ lcov*.info
# /win32/
/win32/*.ico
-# RJIT
-/include/ruby-*/*/rb_rjit_min_header-*.h
-/lib/ruby_vm/rjit/instruction.rb
-/lib/ruby_vm/rjit/instruction.rb
-/rjit_config.h
-/rb_rjit_header.h*
+# MJIT
+/include/ruby-*/*/rb_mjit_min_header-*.h
+/lib/ruby_vm/mjit/instruction.rb
+/mjit_config.h
+/rb_mjit_header.h
# YJIT
/yjit-bench
@@ -256,28 +248,3 @@ lcov*.info
# /wasm/
/wasm/tests/*.wasm
-
-# prism
-/lib/prism/compiler.rb
-/lib/prism/dispatcher.rb
-/lib/prism/dot_visitor.rb
-/lib/prism/dsl.rb
-/lib/prism/inspect_visitor.rb
-/lib/prism/mutation_compiler.rb
-/lib/prism/node.rb
-/lib/prism/reflection.rb
-/lib/prism/serialize.rb
-/lib/prism/visitor.rb
-/prism/api_node.c
-/prism/ast.h
-/prism/diagnostic.c
-/prism/diagnostic.h
-/prism/node.c
-/prism/prettyprint.c
-/prism/serialize.c
-/prism/token_type.c
-
-# tool/update-NEWS-gemlist.rb
-/bundled_gems.json
-/default_gems.json
-/gems/default_gems
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 741c0a32ef..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,152 +0,0 @@
-# -*- YAML -*-
-# Copyright (C) 2011 Urabe, Shyouhei. All rights reserved.
-#
-# This file is a part of the programming language Ruby. Permission is hereby
-# granted, to either redistribute or modify this file, provided that the
-# conditions mentioned in the file COPYING are met. Consult the file for
-# details.
-
-# When you see Travis CI issues, or you are interested in understanding how to
-# manage, please check the link below.
-# https://github.com/ruby/ruby/wiki/CI-Servers#travis-ci
-
-# We enable Travis on the specific branches or forked repositories here.
-if: >-
- (repo != ruby/ruby OR branch = master OR branch =~ /^ruby_\d_\d$/)
- AND (commit_message !~ /\[DOC\]/)
-
-language: c
-
-os: linux
-
-dist: jammy
-
-git:
- quiet: true
-
-env:
- global:
- - NPROC="$(nproc)"
- - JOBS="-j${NPROC}"
- # SETARCH are overridden when necessary. See below.
- - SETARCH=
- # https://github.com/travis-ci/travis-build/blob/e411371dda21430a60f61b8f3f57943d2fe4d344/lib/travis/build/bash/travis_apt_get_options.bash#L7
- - travis_apt_get_options='--allow-downgrades --allow-remove-essential --allow-change-held-packages'
- - travis_apt_get_options="-yq --no-install-suggests --no-install-recommends $travis_apt_get_options"
- # -g0 disables backtraces when SEGV. Do not set that.
- - debugflags=-ggdb3
- - RUBY_TESTOPTS="$JOBS -q --tty=no"
-
-.org.ruby-lang.ci.matrix-definitions:
- - &gcc-11
- compiler: gcc-11
- before_install:
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- gcc-11
- g++-11
- libffi-dev
- libncurses-dev
- libncursesw5-dev
- libreadline-dev
- libssl-dev
- libyaml-dev
- openssl
- zlib1g-dev
- - gcc-11 --version
- - &arm64-linux
- name: arm64-linux
- arch: arm64
- <<: *gcc-11
- - &ppc64le-linux
- name: ppc64le-linux
- arch: ppc64le
- <<: *gcc-11
- - &s390x-linux
- name: s390x-linux
- arch: s390x
- <<: *gcc-11
- env:
- # Avoid possible test failures with the zlib applying the following patch
- # on s390x CPU architecture.
- # https://github.com/madler/zlib/pull/410
- - DFLTCC=0
- - &arm32-linux
- name: arm32-linux
- arch: arm64
- # https://packages.ubuntu.com/jammy/crossbuild-essential-armhf
- compiler: arm-linux-gnueabihf-gcc
- env:
- - SETARCH='setarch linux32 --verbose --32bit'
- # Still keep the -O1 for only arm32, while we want to test with the
- # default optflags -O3.
- # Because bootstraptest/test_ractor.rb fails with segfualt with the
- # default -O3.
- # https://bugs.ruby-lang.org/issues/19981
- - optflags=-O1
- before_install:
- - sudo dpkg --add-architecture armhf
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- crossbuild-essential-armhf
- libc6:armhf
- libstdc++-10-dev:armhf
- libffi-dev:armhf
- libncurses-dev:armhf
- libncursesw5-dev:armhf
- libreadline-dev:armhf
- libssl-dev:armhf
- libyaml-dev:armhf
- linux-libc-dev:armhf
- zlib1g-dev:armhf
-
-matrix:
- include:
- - <<: *arm64-linux
- - <<: *ppc64le-linux
- - <<: *s390x-linux
- # FIXME: lib/rubygems/util.rb:104 glob_files_in_dir -
- # <internal:dir>:411:in glob: File name too long - (Errno::ENAMETOOLONG)
- # https://github.com/rubygems/rubygems/issues/7132
- - <<: *arm32-linux
- allow_failures:
- # Allow failures for the unstable jobs.
- # - name: arm64-linux
- # - name: ppc64le-linux
- # - name: s390x-linux
- # The 2nd arm64 pipeline may be unstable.
- # - name: arm32-linux
- fast_finish: true
-
-before_script:
- - ./autogen.sh
- - mkdir build
- - cd build
- - $SETARCH ../configure -C --disable-install-doc --prefix=$(pwd)/install
- - $SETARCH make -s $JOBS
- - make -s $JOBS install
- # Useful info to report issues to the Ruby.
- - $SETARCH $(pwd)/install/bin/ruby -v
- # Useful info To report issues to the RubyGems.
- - $SETARCH $(pwd)/install/bin/gem env
-
-script:
- - $SETARCH make -s test
- - ../tool/travis_wait.sh $SETARCH make -s test-all RUBYOPT="-w"
- - $SETARCH make -s test-spec
-
-# We want to be notified when something happens.
-notifications:
- webhooks:
- urls:
- # ruby-lang slack: ruby/simpler-alerts-bot (travis)
- - secure: mRsoS/UbqDkKkW5p3AEqM27d4SZnV6Gsylo3bm8T/deltQzTsGzZwrm7OIBXZv0UFZdE68XmPlyHfZFLSP2V9QZ7apXMf9/vw0GtcSe1gchtnjpAPF6lYBn7nMCbVPPx9cS0dwL927fjdRM1vj7IKZ2bk4F0lAJ25R25S6teqdk=
- on_success: never
- on_failure: always
- email:
- recipients:
- - jaruga@ruby-lang.org
- on_success: never
- on_failure: always
diff --git a/LEGAL b/LEGAL
index e352c55ee5..0423d57ac9 100644
--- a/LEGAL
+++ b/LEGAL
@@ -748,7 +748,8 @@ mentioned below.
[ext/psych]
[test/psych]
- The files under these directories are under the following license.
+ The files under these directories are under the following license, except for
+ ext/psych/yaml.
>>>
Copyright 2009:: Aaron Patterson, et al.
@@ -771,6 +772,31 @@ mentioned below.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+[ext/psych/yaml]
+
+ The files under this directory are under the following license.
+
+ >>>
+ Copyright (c) 2006:: Kirill Simonov
+
+ 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.
+
[ext/pty/pty.c]
>>>
diff --git a/NEWS.md b/NEWS.md
index 364786d754..f6c3c6fc97 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,529 +1,820 @@
-# NEWS for Ruby 3.3.0
+# NEWS for Ruby 3.2.0
This document is a list of user-visible feature changes
-since the **3.2.0** release, except for bug fixes.
+since the **3.1.0** release, except for bug fixes.
Note that each entry is kept to a minimum, see links for details.
-## Command line options
+## Language changes
-* A new `performance` warning category was introduced.
- They are not displayed by default even in verbose mode.
- Turn them on with `-W:performance` or `Warning[:performance] = true`. [[Feature #19538]]
+* Anonymous rest and keyword rest arguments can now be passed as
+ arguments, instead of just used in method parameters.
+ [[Feature #18351]]
-* A new `RUBY_CRASH_REPORT` environment variable was introduced to allow
- redirecting Ruby crash reports to a file or sub command. See the `BUG REPORT ENVIRONMENT`
- section of the ruby manpage for further details. [[Feature #19790]]
+ ```ruby
+ def foo(*)
+ bar(*)
+ end
+ def baz(**)
+ quux(**)
+ end
+ ```
-## Core classes updates
+* A proc that accepts a single positional argument and keywords will
+ no longer autosplat. [[Bug #18633]]
-Note: We're only listing outstanding class updates.
+ ```ruby
+ proc{|a, **k| a}.call([1, 2])
+ # Ruby 3.1 and before
+ # => 1
+ # Ruby 3.2 and after
+ # => [1, 2]
+ ```
+
+* Constant assignment evaluation order for constants set on explicit
+ objects has been made consistent with single attribute assignment
+ evaluation order. With this code:
+
+ ```ruby
+ foo::BAR = baz
+ ```
+
+ `foo` is now called before `baz`. Similarly, for multiple assignments
+ to constants, left-to-right evaluation order is used. With this
+ code:
+
+ ```ruby
+ foo1::BAR1, foo2::BAR2 = baz1, baz2
+ ```
-* Array
+ The following evaluation order is now used:
- * Array#pack now raises ArgumentError for unknown directives. [[Bug #19150]]
+ 1. `foo1`
+ 2. `foo2`
+ 3. `baz1`
+ 4. `baz2`
-* Dir
+ [[Bug #15928]]
- * Dir.for_fd added for returning a Dir object for the directory specified
- by the provided directory file descriptor. [[Feature #19347]]
- * Dir.fchdir added for changing the directory to the directory specified
- by the provided directory file descriptor. [[Feature #19347]]
- * Dir#chdir added for changing the directory to the directory specified by
- the provided `Dir` object. [[Feature #19347]]
+* "Find pattern" is no longer experimental.
+ [[Feature #18585]]
-* Encoding
+* Methods taking a rest parameter (like `*args`) and wishing to delegate keyword
+ arguments through `foo(*args)` must now be marked with `ruby2_keywords`
+ (if not already the case). In other words, all methods wishing to delegate
+ keyword arguments through `*args` must now be marked with `ruby2_keywords`,
+ with no exception. This will make it easier to transition to other ways of
+ delegation once a library can require Ruby 3+. Previously, the `ruby2_keywords`
+ flag was kept if the receiving method took `*args`, but this was a bug and an
+ inconsistency. A good technique to find the potentially-missing `ruby2_keywords`
+ is to run the test suite, for where it fails find the last method which must
+ receive keyword arguments, use `puts nil, caller, nil` there, and check each
+ method/block on the call chain which must delegate keywords is correctly marked
+ as `ruby2_keywords`. [[Bug #18625]] [[Bug #16466]]
+
+ ```ruby
+ def target(**kw)
+ end
+
+ # Accidentally worked without ruby2_keywords in Ruby 2.7-3.1, ruby2_keywords
+ # needed in 3.2+. Just like (*args, **kwargs) or (...) would be needed on
+ # both #foo and #bar when migrating away from ruby2_keywords.
+ ruby2_keywords def bar(*args)
+ target(*args)
+ end
+
+ ruby2_keywords def foo(*args)
+ bar(*args)
+ end
+
+ foo(k: 1)
+ ```
+
+## Core classes updates
- * `Encoding#replicate` has been removed, it was already deprecated. [[Feature #18949]]
+Note: We're only listing outstanding class updates.
* Fiber
- * Introduce Fiber#kill. [[Bug #595]]
+ * Introduce Fiber.[] and Fiber.[]= for inheritable fiber storage.
+ Introduce Fiber#storage and Fiber#storage= (experimental) for
+ getting and resetting the current storage. Introduce
+ `Fiber.new(storage:)` for setting the storage when creating a
+ fiber. [[Feature #19078]]
+
+ Existing Thread and Fiber local variables can be tricky to use.
+ Thread-local variables are shared between all fibers, making it
+ hard to isolate, while Fiber-local variables can be hard to
+ share. It is often desirable to define unit of execution
+ ("execution context") such that some state is shared between all
+ fibers and threads created in that context. This is what Fiber
+ storage provides.
```ruby
- fiber = Fiber.new do
- while true
- puts "Yielding..."
- Fiber.yield
+ def log(message)
+ puts "#{Fiber[:request_id]}: #{message}"
+ end
+
+ def handle_requests
+ while request = read_request
+ Fiber.schedule do
+ Fiber[:request_id] = SecureRandom.uuid
+
+ request.messages.each do |message|
+ Fiber.schedule do
+ log("Handling #{message}") # Log includes inherited request_id.
+ end
+ end
+ end
end
- ensure
- puts "Exiting..."
end
+ ```
+
+ You should generally consider Fiber storage for any state which
+ you want to be shared implicitly between all fibers and threads
+ created in a given context, e.g. a connection pool, a request
+ id, a logger level, environment variables, configuration, etc.
+
+* Fiber::Scheduler
+
+ * Introduce `Fiber::Scheduler#io_select` for non-blocking IO.select.
+ [[Feature #19060]]
+
+* IO
- fiber.resume
- # Yielding...
- fiber.kill
- # Exiting...
+ * Introduce IO#timeout= and IO#timeout which can cause
+ IO::TimeoutError to be raised if a blocking operation exceeds the
+ specified timeout. [[Feature #18630]]
+
+ ```ruby
+ STDIN.timeout = 1
+ STDIN.read # => Blocking operation timed out! (IO::TimeoutError)
```
-* MatchData
+ * Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`.
+ [[Feature #19036]]
- * MatchData#named_captures now accepts optional `symbolize_names`
- keyword. [[Feature #19591]]
+* Class
-* Module
+ * Class#attached_object, which returns the object for which
+ the receiver is the singleton class. Raises TypeError if the
+ receiver is not a singleton class.
+ [[Feature #12084]]
+
+ ```ruby
+ class Foo; end
+
+ Foo.singleton_class.attached_object #=> Foo
+ Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370>
+ Foo.attached_object #=> TypeError: `Foo' is not a singleton class
+ nil.singleton_class.attached_object #=> TypeError: `NilClass' is not a singleton class
+ ```
+
+* Data
+
+ * New core class to represent simple immutable value object. The class is
+ similar to Struct and partially shares an implementation, but has more
+ lean and strict API. [[Feature #16122]]
+
+ ```ruby
+ Measure = Data.define(:amount, :unit)
+ distance = Measure.new(100, 'km') #=> #<data Measure amount=100, unit="km">
+ weight = Measure.new(amount: 50, unit: 'kg') #=> #<data Measure amount=50, unit="kg">
+ weight.with(amount: 40) #=> #<data Measure amount=40, unit="kg">
+ weight.amount #=> 50
+ weight.amount = 40 #=> NoMethodError: undefined method `amount='
+ ```
+
+* Encoding
+
+ * Encoding#replicate has been deprecated and will be removed in 3.3. [[Feature #18949]]
+ * The dummy `Encoding::UTF_16` and `Encoding::UTF_32` encodings no longer
+ try to dynamically guess the endian based on a byte order mark.
+ Use `Encoding::UTF_16BE`/`UTF_16LE` and `Encoding::UTF_32BE`/`UTF_32LE` instead.
+ This change speeds up getting the encoding of a String. [[Feature #18949]]
+ * Limit maximum encoding set size by 256.
+ If exceeding maximum size, `EncodingError` will be raised. [[Feature #18949]]
- * Module#set_temporary_name added for setting a temporary name for a
- module. [[Feature #19521]]
+* Enumerator
-* ObjectSpace::WeakKeyMap
+ * Enumerator.product has been added. Enumerator::Product is the implementation. [[Feature #18685]]
- * New core class to build collections with weak references.
- The class use equality semantic to lookup keys like a regular hash,
- but it doesn't hold strong references on the keys. [[Feature #18498]]
+* Exception
-* ObjectSpace::WeakMap
+ * Exception#detailed_message has been added.
+ The default error printer calls this method on the Exception object
+ instead of #message. [[Feature #18564]]
- * ObjectSpace::WeakMap#delete was added to eagerly clear weak map
- entries. [[Feature #19561]]
+* Hash
+
+ * Hash#shift now always returns nil if the hash is
+ empty, instead of returning the default value or
+ calling the default proc. [[Bug #16908]]
+
+* Integer
+
+ * Integer#ceildiv has been added. [[Feature #18809]]
+
+* Kernel
+
+ * Kernel#binding raises RuntimeError if called from a non-Ruby frame
+ (such as a method defined in C). [[Bug #18487]]
+
+* MatchData
+
+ * MatchData#byteoffset has been added. [[Feature #13110]]
+ * MatchData#deconstruct has been added. [[Feature #18821]]
+ * MatchData#deconstruct_keys has been added. [[Feature #18821]]
+
+* Module
+
+ * Module.used_refinements has been added. [[Feature #14332]]
+ * Module#refinements has been added. [[Feature #12737]]
+ * Module#const_added has been added. [[Feature #17881]]
+ * Module#undefined_instance_methods has been added. [[Feature #12655]]
* Proc
- * Now Proc#dup and Proc#clone call `#initialize_dup` and `#initialize_clone`
- hooks respectively. [[Feature #19362]]
+
+ * Proc#dup returns an instance of subclass. [[Bug #17545]]
+ * Proc#parameters now accepts lambda keyword. [[Feature #15357]]
* Process
+ * Added `RLIMIT_NPTS` constant to FreeBSD platform
- * New Process.warmup method that notify the Ruby virtual machine that the boot sequence is finished,
- and that now is a good time to optimize the application. This is useful
- for long-running applications. The actual optimizations performed are entirely
- implementation-specific and may change in the future without notice. [[Feature #18885]]
+* Regexp
-* Process::Status
+ * The cache-based optimization is introduced.
+ Many (but not all) Regexp matching is now in linear time, which
+ will prevent regular expression denial of service (ReDoS)
+ vulnerability. [[Feature #19104]]
- * Process::Status#& and Process::Status#>> are deprecated. [[Bug #19868]]
+ * Regexp.linear_time? is introduced. [[Feature #19194]]
-* Range
+ * Regexp.new now supports passing the regexp flags not only as an Integer,
+ but also as a String. Unknown flags raise ArgumentError.
+ Otherwise, anything other than `true`, `false`, `nil` or Integer will be warned.
+ [[Feature #18788]]
- * Range#reverse_each can now process beginless ranges with an Integer endpoint. [[Feature #18515]]
- * Range#reverse_each now raises TypeError for endless ranges. [[Feature #18551]]
- * Range#overlap? added for checking if two ranges overlap. [[Feature #19839]]
+ * Regexp.timeout= has been added. Also, Regexp.new new supports timeout keyword.
+ See [[Feature #17837]]
* Refinement
- * Add Refinement#target as an alternative of Refinement#refined_class.
- Refinement#refined_class is deprecated and will be removed in Ruby
- 3.4. [[Feature #19714]]
+ * Refinement#refined_class has been added. [[Feature #12737]]
-* Regexp
+* RubyVM::AbstractSyntaxTree
+
+ * Add `error_tolerant` option for `parse`, `parse_file` and `of`. [[Feature #19013]]
+ With this option
+
+ 1. SyntaxError is suppressed
+ 2. AST is returned for invalid input
+ 3. `end` is complemented when a parser reaches to the end of input but `end` is insufficient
+ 4. `end` is treated as keyword based on indent
- * The cache-based optimization now supports lookarounds and atomic groupings. That is, match
- for Regexp containing these extensions can now also be performed in linear time to the length
- of the input string. However, these cannot contain captures and cannot be nested. [[Feature #19725]]
+ ```ruby
+ # Without error_tolerant option
+ root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY)
+ def m
+ a = 10
+ if
+ end
+ RUBY
+ # => <internal:ast>:33:in `parse': syntax error, unexpected `end' (SyntaxError)
+
+ # With error_tolerant option
+ root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true)
+ def m
+ a = 10
+ if
+ end
+ RUBY
+ p root # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-4:3>
+
+ # `end` is treated as keyword based on indent
+ root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true)
+ module Z
+ class Foo
+ foo.
+ end
+
+ def bar
+ end
+ end
+ RUBY
+ p root.children[-1].children[-1].children[-1].children[-2..-1]
+ # => [#<RubyVM::AbstractSyntaxTree::Node:CLASS@2:2-4:5>, #<RubyVM::AbstractSyntaxTree::Node:DEFN@6:2-7:5>]
+ ```
+
+ * Add `keep_tokens` option for `parse`, `parse_file` and `of`. Add `#tokens` and `#all_tokens`
+ for RubyVM::AbstractSyntaxTree::Node [[Feature #19070]]
+
+ ```ruby
+ root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true)
+ root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...]
+ root.tokens.map{_1[2]}.join # => "x = 1 + 2"
+ ```
+
+* Set
+
+ * Set is now available as a built-in class without the need for `require "set"`. [[Feature #16989]]
+ It is currently autoloaded via the Set constant or a call to Enumerable#to_set.
* String
- * String#unpack now raises ArgumentError for unknown directives. [[Bug #19150]]
- * String#bytesplice now accepts new arguments index/length or range of the
- source string to be copied. [[Feature #19314]]
+ * String#byteindex and String#byterindex have been added. [[Feature #13110]]
+ * Update Unicode to Version 15.0.0 and Emoji Version 15.0. [[Feature #18639]]
+ (also applies to Regexp)
+ * String#bytesplice has been added. [[Feature #18598]]
+ * String#dedup has been added as an alias to String#-@. [[Feature #18595]]
+
+* Struct
+
+ * A Struct class can also be initialized with keyword arguments
+ without `keyword_init: true` on Struct.new [[Feature #16806]]
+
+ ```ruby
+ Post = Struct.new(:id, :name)
+ Post.new(1, "hello") #=> #<struct Post id=1, name="hello">
+ # From Ruby 3.2, the following code also works without keyword_init: true.
+ Post.new(id: 1, name: "hello") #=> #<struct Post id=1, name="hello">
+ ```
+
+* Thread
+
+ * Thread.each_caller_location is added. [[Feature #16663]]
* Thread::Queue
- * Thread::Queue#freeze now raises TypeError. [[Bug #17146]]
+ * Thread::Queue#pop(timeout: sec) is added. [[Feature #18774]]
* Thread::SizedQueue
- * Thread::SizedQueue#freeze now raises TypeError. [[Bug #17146]]
+ * Thread::SizedQueue#pop(timeout: sec) is added. [[Feature #18774]]
+ * Thread::SizedQueue#push(timeout: sec) is added. [[Feature #18944]]
* Time
- * Time.new with a string argument became stricter. [[Bug #19293]]
+ * Time#deconstruct_keys is added, allowing to use Time instances
+ in pattern-matching expressions [[Feature #19071]]
- ```ruby
- Time.new('2023-12-20')
- # no time information (ArgumentError)
- ```
+ * Time.new now can parse a string like generated by Time#inspect
+ and return a Time instance based on the given argument.
+ [[Feature #18033]]
+
+* SyntaxError
+ * SyntaxError#path has been added. [[Feature #19138]]
* TracePoint
- * TracePoint supports `rescue` event. When the raised exception was rescued,
- the TracePoint will fire the hook. `rescue` event only supports Ruby-level
- `rescue`. [[Feature #19572]]
+ * TracePoint#binding now returns `nil` for `c_call`/`c_return` TracePoints.
+ [[Bug #18487]]
+ * TracePoint#enable `target_thread` keyword argument now defaults to the
+ current thread if a block is given and `target` and `target_line` keyword
+ arguments are not passed. [[Bug #16889]]
+
+* UnboundMethod
+
+ * `UnboundMethod#==` returns `true` if the actual method is same. For example,
+ `String.instance_method(:object_id) == Array.instance_method(:object_id)`
+ returns `true`. [[Feature #18798]]
+
+ * `UnboundMethod#inspect` does not show the receiver of `instance_method`.
+ For example `String.instance_method(:object_id).inspect` returns
+ `"#<UnboundMethod: Kernel#object_id()>"`
+ (was `"#<UnboundMethod: String(Kernel)#object_id()>"`).
+
+* GC
+
+ * Expose `need_major_gc` via `GC.latest_gc_info`. [GH-6791]
+
+* ObjectSpace
+
+ * `ObjectSpace.dump_all` dump shapes as well. [GH-6868]
## Stdlib updates
-* RubyGems and Bundler warn if users do `require` the following gems without adding them to Gemfile or gemspec.
- This is because they will become the bundled gems in the future version of Ruby. This warning is suppressed
- if you use bootsnap gem. We recommend to run your application with `DISABLE_BOOTSNAP=1` environmental variable
- at least once. This is limitation of this version.
- [[Feature #19351]] [[Feature #19776]] [[Feature #19843]]
- * abbrev
- * base64
- * bigdecimal
- * csv
- * drb
- * getoptlong
- * mutex_m
- * nkf
- * observer
- * racc
- * resolv-replace
- * rinda
- * syslog
-
-* Socket#recv and Socket#recv_nonblock returns `nil` instead of an empty string on closed
- connections. Socket#recvmsg and Socket#recvmsg_nonblock returns `nil` instead of an empty packet on closed
- connections. [[Bug #19012]]
-
-* Name resolution such as Socket.getaddrinfo, Socket.getnameinfo, Addrinfo.getaddrinfo, etc.
- can now be interrupted. [[Feature #19965]]
-
-* Random::Formatter#alphanumeric is extended to accept optional `chars`
- keyword argument. [[Feature #18183]]
-
-The following default gem is added.
-
-* prism 0.19.0
-
-The following default gems are updated.
-
-* RubyGems 3.5.3
-* abbrev 0.1.2
-* base64 0.2.0
-* benchmark 0.3.0
-* bigdecimal 3.1.5
-* bundler 2.5.3
-* cgi 0.4.1
-* csv 3.2.8
-* date 3.3.4
-* delegate 0.3.1
-* drb 2.2.0
-* english 0.8.0
-* erb 4.0.3
-* error_highlight 0.6.0
-* etc 1.4.3
-* fcntl 1.1.0
-* fiddle 1.1.2
-* fileutils 1.7.2
-* find 0.2.0
-* getoptlong 0.2.1
-* io-console 0.7.1
-* io-nonblock 0.3.0
-* io-wait 0.3.1
-* ipaddr 1.2.6
-* irb 1.11.0
-* json 2.7.1
-* logger 1.6.0
-* mutex_m 0.2.0
-* net-http 0.4.0
-* net-protocol 0.2.2
-* nkf 0.1.3
-* observer 0.1.2
-* open-uri 0.4.1
-* open3 0.2.1
-* openssl 3.2.0
-* optparse 0.4.0
-* ostruct 0.6.0
-* pathname 0.3.0
-* pp 0.5.0
-* prettyprint 0.2.0
-* pstore 0.1.3
-* psych 5.1.2
-* rdoc 6.6.2
-* readline 0.0.4
-* reline 0.4.1
-* resolv 0.3.0
-* rinda 0.2.0
-* securerandom 0.3.1
-* set 1.1.0
-* shellwords 0.2.0
-* singleton 0.2.0
-* stringio 3.1.0
-* strscan 3.0.7
-* syntax_suggest 2.0.0
-* syslog 0.1.2
-* tempfile 0.2.1
-* time 0.3.0
-* timeout 0.4.1
-* tmpdir 0.2.0
-* tsort 0.2.0
-* un 0.3.0
-* uri 0.13.0
-* weakref 0.1.3
-* win32ole 1.8.10
-* yaml 0.3.0
-* zlib 3.1.0
-
-The following bundled gem is promoted from default gems.
-
-* racc 1.7.3
-
-The following bundled gems are updated.
-
-* minitest 5.20.0
-* rake 13.1.0
-* test-unit 3.6.1
-* rexml 3.2.6
-* rss 0.3.0
-* net-ftp 0.3.3
-* net-imap 0.4.9
-* net-smtp 0.4.0
-* rbs 3.4.0
-* typeprof 0.21.9
-* debug 1.9.1
-
-See GitHub releases like [Logger](https://github.com/ruby/logger/releases) or
-changelog for details of the default gems or bundled gems.
-
-### Prism
-
-* Introduced [the Prism parser](https://github.com/ruby/prism) as a default gem
- * Prism is a portable, error tolerant, and maintainable recursive descent parser for the Ruby language
-* Prism is production ready and actively maintained, you can use it in place of Ripper
- * There is [extensive documentation](https://ruby.github.io/prism/) on how to use Prism
- * Prism is both a C library that will be used internally by CRuby and a Ruby gem that can be used by any tooling which needs to parse Ruby code
- * Notable methods in the Prism API are:
- * `Prism.parse(source)` which returns the AST as part of a parse result object
- * `Prism.parse_comments(source)` which returns the comments
- * `Prism.parse_success?(source)` which returns true if there are no errors
-* You can make pull requests or issues directly on [the Prism repository](https://github.com/ruby/prism) if you are interested in contributing
-* You can now use `ruby --parser=prism` or `RUBYOPT="--parser=prism"` to experiment with the Prism compiler. Please note that this flag is for debugging only.
+* Bundler
+
+ * Bundler now uses [PubGrub] resolver instead of [Molinillo] for performance improvement.
+ * Add --ext=rust support to bundle gem for creating simple gems with Rust extensions.
+ [[GH-rubygems-6149]]
+ * Make cloning git repos faster [[GH-rubygems-4475]]
+
+* RubyGems
+
+ * Add mswin support for cargo builder. [[GH-rubygems-6167]]
+
+* CGI
+
+ * `CGI.escapeURIComponent` and `CGI.unescapeURIComponent` are added.
+ [[Feature #18822]]
+
+* Coverage
+
+ * `Coverage.setup` now accepts `eval: true`. By this, `eval` and related methods are
+ able to generate code coverage. [[Feature #19008]]
+
+ * `Coverage.supported?(mode)` enables detection of what coverage modes are
+ supported. [[Feature #19026]]
+
+* Date
+
+ * Added `Date#deconstruct_keys` and `DateTime#deconstruct_keys` same as [[Feature #19071]]
+
+* ERB
+
+ * `ERB::Util.html_escape` is made faster than `CGI.escapeHTML`.
+ * It no longer allocates a String object when no character needs to be escaped.
+ * It skips calling `#to_s` method when an argument is already a String.
+ * `ERB::Escape.html_escape` is added as an alias to `ERB::Util.html_escape`,
+ which has not been monkey-patched by Rails.
+ * `ERB::Util.url_encode` is made faster using `CGI.escapeURIComponent`.
+ * `-S` option is removed from `erb` command.
+
+* FileUtils
+
+ * Add FileUtils.ln_sr method and `relative:` option to FileUtils.ln_s.
+ [[Feature #18925]]
+
+* IRB
+
+ * debug.gem integration commands have been added: `debug`, `break`, `catch`,
+ `next`, `delete`, `step`, `continue`, `finish`, `backtrace`, `info`
+ * They work even if you don't have `gem "debug"` in your Gemfile.
+ * See also: [What's new in Ruby 3.2's IRB?](https://st0012.dev/whats-new-in-ruby-3-2-irb)
+ * More Pry-like commands and features have been added.
+ * `edit` and `show_cmds` (like Pry's `help`) are added.
+ * `ls` takes `-g` or `-G` option to filter out outputs.
+ * `show_source` is aliased from `$` and accepts unquoted inputs.
+ * `whereami` is aliased from `@`.
+
+* Net::Protocol
+
+ * Improve `Net::BufferedIO` performance. [[GH-net-protocol-14]]
+
+* Pathname
+
+ * Added `Pathname#lutime`. [[GH-pathname-20]]
+
+* Socket
+
+ * Added the following constants for supported platforms.
+ * `SO_INCOMING_CPU`
+ * `SO_INCOMING_NAPI_ID`
+ * `SO_RTABLE`
+ * `SO_SETFIB`
+ * `SO_USER_COOKIE`
+ * `TCP_KEEPALIVE`
+ * `TCP_CONNECTION_INFO`
+
+* SyntaxSuggest
+
+ * The feature of `syntax_suggest` formerly `dead_end` is integrated in Ruby.
+ [[Feature #18159]]
+
+* UNIXSocket
+
+ * Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
+ support for File.socket? and File::Stat#socket? where possible.
+ [[Feature #19135]]
+
+* The following default gems are updated.
+
+ * RubyGems 3.4.1
+ * abbrev 0.1.1
+ * benchmark 0.2.1
+ * bigdecimal 3.1.3
+ * bundler 2.4.1
+ * cgi 0.3.6
+ * csv 3.2.6
+ * date 3.3.3
+ * delegate 0.3.0
+ * did_you_mean 1.6.3
+ * digest 3.1.1
+ * drb 2.1.1
+ * english 0.7.2
+ * erb 4.0.2
+ * error_highlight 0.5.1
+ * etc 1.4.2
+ * fcntl 1.0.2
+ * fiddle 1.1.1
+ * fileutils 1.7.0
+ * forwardable 1.3.3
+ * getoptlong 0.2.0
+ * io-console 0.6.0
+ * io-nonblock 0.2.0
+ * io-wait 0.3.0
+ * ipaddr 1.2.5
+ * irb 1.6.2
+ * json 2.6.3
+ * logger 1.5.3
+ * mutex_m 0.1.2
+ * net-http 0.4.0
+ * net-protocol 0.2.1
+ * nkf 0.1.2
+ * open-uri 0.3.0
+ * open3 0.1.2
+ * openssl 3.1.0
+ * optparse 0.3.1
+ * ostruct 0.5.5
+ * pathname 0.2.1
+ * pp 0.4.0
+ * pstore 0.1.2
+ * psych 5.0.1
+ * racc 1.6.2
+ * rdoc 6.5.0
+ * readline-ext 0.1.5
+ * reline 0.3.2
+ * resolv 0.2.2
+ * resolv-replace 0.1.1
+ * securerandom 0.2.2
+ * set 1.0.3
+ * stringio 3.0.4
+ * strscan 3.0.5
+ * syntax_suggest 1.0.2
+ * syslog 0.1.1
+ * tempfile 0.1.3
+ * time 0.2.1
+ * timeout 0.3.1
+ * tmpdir 0.1.3
+ * tsort 0.1.1
+ * un 0.2.1
+ * uri 0.12.0
+ * weakref 0.1.2
+ * win32ole 1.8.9
+ * yaml 0.2.1
+ * zlib 3.0.0
+
+* The following bundled gems are updated.
+
+ * minitest 5.16.3
+ * power_assert 2.0.3
+ * test-unit 3.5.7
+ * net-ftp 0.2.0
+ * net-imap 0.3.4
+ * net-pop 0.1.2
+ * net-smtp 0.3.3
+ * rbs 2.8.2
+ * typeprof 0.21.3
+ * debug 1.7.1
+
+See GitHub releases like [GitHub Releases of Logger](https://github.com/ruby/logger/releases) or changelog for details of the default gems or bundled gems.
+
+## Supported platforms
+
+* WebAssembly/WASI is added. See [wasm/README.md] and [ruby.wasm] for more details. [[Feature #18462]]
## Compatibility issues
-* Subprocess creation/forking via the following file open methods is deprecated. [[Feature #19630]]
- * Kernel#open
- * URI.open
- * IO.binread
- * IO.foreach
- * IO.readlines
- * IO.read
- * IO.write
+* `String#to_c` currently treat a sequence of underscores as an end of Complex
+ string. [[Bug #19087]]
-* When given a non-lambda, non-literal block, Kernel#lambda with now raises
- ArgumentError instead of returning it unmodified. These usages have been
- issuing warnings under the `Warning[:deprecated]` category since Ruby 3.0.0.
- [[Feature #19777]]
+* Now `ENV.clone` raises `TypeError` as well as `ENV.dup` [[Bug #17767]]
-* The `RUBY_GC_HEAP_INIT_SLOTS` environment variable has been deprecated and
- removed. Environment variables `RUBY_GC_HEAP_%d_INIT_SLOTS` should be
- used instead. [[Feature #19785]]
+### Removed constants
-* `it` calls without arguments in a block with no ordinary parameters are
- deprecated. `it` will be a reference to the first block parameter in Ruby 3.4.
- [[Feature #18980]]
+The following deprecated constants are removed.
-* Error message for NoMethodError have changed to not use the target object's `#inspect`
- for efficiency, and says "instance of ClassName" instead. [[Feature #18285]]
+* `Fixnum` and `Bignum` [[Feature #12005]]
+* `Random::DEFAULT` [[Feature #17351]]
+* `Struct::Group`
+* `Struct::Passwd`
- ```ruby
- ([1] * 100).nonexisting
- # undefined method `nonexisting' for an instance of Array (NoMethodError)
- ```
+### Removed methods
-* Now anonymous parameters forwarding is disallowed inside a block
- that uses anonymous parameters. [[Feature #19370]]
+The following deprecated methods are removed.
+
+* `Dir.exists?` [[Feature #17391]]
+* `File.exists?` [[Feature #17391]]
+* `Kernel#=~` [[Feature #15231]]
+* `Kernel#taint`, `Kernel#untaint`, `Kernel#tainted?`
+ [[Feature #16131]]
+* `Kernel#trust`, `Kernel#untrust`, `Kernel#untrusted?`
+ [[Feature #16131]]
+* `Method#public?`, `Method#private?`, `Method#protected?`,
+ `UnboundMethod#public?`, `UnboundMethod#private?`, `UnboundMethod#protected?`
+ [[Bug #18729]] [[Bug #18751]] [[Bug #18435]]
+
+### Source code incompatibility of extension libraries
+
+* Extension libraries provide PRNG, subclasses of Random, need updates.
+ See [PRNG update] below for more information. [[Bug #19100]]
+
+### Error printer
+
+* Ruby no longer escapes control characters and backslashes in an
+ error message. [[Feature #18367]]
+
+### Constant lookup when defining a class/module
+
+* When defining a class/module directly under the Object class by class/module
+ statement, if there is already a class/module defined by `Module#include`
+ with the same name, the statement was handled as "open class" in Ruby 3.1 or before.
+ Since Ruby 3.2, a new class is defined instead. [[Feature #18832]]
## Stdlib compatibility issues
-* `racc` is promoted to bundled gems.
- * You need to add `racc` to your `Gemfile` if you use `racc` under bundler environment.
-* `ext/readline` is retired
- * We have `reline` that is pure Ruby implementation compatible with `ext/readline` API.
- We rely on `reline` in the future. If you need to use `ext/readline`, you can install
- `ext/readline` via rubygems.org with `gem install readline-ext`.
- * We no longer need to install libraries like `libreadline` or `libedit`.
+* Psych no longer bundles libyaml sources.
+ And also Fiddle no longer bundles libffi sources.
+ Users need to install the libyaml/libffi library themselves via the package
+ manager like apt, yum, brew, etc.
+
+ Psych and fiddle supported the static build with specific version of libyaml
+ and libffi sources. You can build psych with libyaml-0.2.5 like this.
+
+ ```bash
+ $ ./configure --with-libyaml-source-dir=/path/to/libyaml-0.2.5
+ ```
+
+ And you can build fiddle with libffi-3.4.4 like this.
+
+ ```bash
+ $ ./configure --with-libffi-source-dir=/path/to/libffi-3.4.4
+ ```
+
+ [[Feature #18571]]
+
+* Check cookie name/path/domain characters in `CGI::Cookie`. [[CVE-2021-33621]]
+
+* `URI.parse` return empty string in host instead of nil. [[sec-156615]]
## C API updates
-* `rb_postponed_job` updates
- * New APIs and deprecated APIs (see comments for details)
- * added: `rb_postponed_job_preregister()`
- * added: `rb_postponed_job_trigger()`
- * deprecated: `rb_postponed_job_register()` (and semantic change. see below)
- * deprecated: `rb_postponed_job_register_one()`
- * The postponed job APIs have been changed to address some rare crashes.
- To solve the issue, we introduced new two APIs and deprecated current APIs.
- The semantics of these functions have also changed slightly; `rb_postponed_job_register`
- now behaves like the `once` variant in that multiple calls with the same
- `func` might be coalesced into a single execution of the `func`
- [[Feature #20057]]
-
-* Some updates for internal thread event hook APIs
- * `rb_internal_thread_event_data_t` with a target Ruby thread (VALUE)
- and callback functions (`rb_internal_thread_event_callback`) receive it.
- https://github.com/ruby/ruby/pull/8885
- * The following functions are introduced to manipulate Ruby thread local data
- from internal thread event hook APIs (they are introduced since Ruby 3.2).
- https://github.com/ruby/ruby/pull/8936
- * `rb_internal_thread_specific_key_create()`
- * `rb_internal_thread_specific_get()`
- * `rb_internal_thread_specific_set()`
-
-* `rb_profile_thread_frames()` is introduced to get a frames from
- a specific thread.
- [[Feature #10602]]
-
-* `rb_data_define()` is introduced to define `Data`. [[Feature #19757]]
-
-* `rb_ext_resolve_symbol()` is introduced to search a function from
- extension libraries. [[Feature #20005]]
-
-* IO related updates:
- * The details of `rb_io_t` will be hidden and deprecated attributes
- are added for each members. [[Feature #19057]]
- * `rb_io_path(VALUE io)` is introduced to get a path of `io`.
- * `rb_io_closed_p(VALUE io)` to get opening or closing of `io`.
- * `rb_io_mode(VALUE io)` to get the mode of `io`.
- * `rb_io_open_descriptor()` is introduced to make an IO object from a file
- descriptor.
+### Updated C APIs
+
+The following APIs are updated.
+
+* PRNG update
+
+ `rb_random_interface_t` in ruby/random.h updated and versioned.
+ Extension libraries which use this interface and built for older
+ versions need to rebuild with adding `init_int32` function.
+
+### Added C APIs
+
+* `VALUE rb_hash_new_capa(long capa)` was added to created hashes with the desired capacity.
+* `rb_internal_thread_add_event_hook` and `rb_internal_thread_add_event_hook` were added to instrument threads scheduling.
+ The following events are available:
+ * `RUBY_INTERNAL_THREAD_EVENT_STARTED`
+ * `RUBY_INTERNAL_THREAD_EVENT_READY`
+ * `RUBY_INTERNAL_THREAD_EVENT_RESUMED`
+ * `RUBY_INTERNAL_THREAD_EVENT_SUSPENDED`
+ * `RUBY_INTERNAL_THREAD_EVENT_EXITED`
+* `rb_debug_inspector_current_depth` and `rb_debug_inspector_frame_depth` are added for debuggers.
+
+### Removed C APIs
+
+The following deprecated APIs are removed.
+
+* `rb_cData` variable.
+* "taintedness" and "trustedness" functions. [[Feature #16131]]
## Implementation improvements
-### Parser
-
-* Replace Bison with [Lrama LALR parser generator](https://github.com/ruby/lrama).
- No need to install Bison to build Ruby from source code anymore.
- We will no longer suffer bison compatibility issues and we can use new features by just implementing it to Lrama. [[Feature #19637]]
- * See [The future vision of Ruby Parser](https://rubykaigi.org/2023/presentations/spikeolaf.html) for detail.
- * Lrama internal parser is a LR parser generated by Racc for maintainability.
- * Parameterizing Rules `(?, *, +)` are supported, it will be used in Ruby parse.y.
-
-### GC / Memory management
-
-* Major performance improvements over Ruby 3.2
- * Young objects referenced by old objects are no longer immediately
- promoted to the old generation. This significantly reduces the frequency of
- major GC collections. [[Feature #19678]]
- * A new `REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO` tuning variable was
- introduced to control the number of unprotected objects cause a major GC
- collection to trigger. The default is set to `0.01` (1%). This significantly
- reduces the frequency of major GC collection. [[Feature #19571]]
- * Write Barriers were implemented for many core types that were missing them,
- notably `Time`, `Enumerator`, `MatchData`, `Method`, `File::Stat`, `BigDecimal`
- and several others. This significantly reduces minor GC collection time and major
- GC collection frequency.
- * Most core classes are now using Variable Width Allocation, notably `Hash`, `Time`,
- `Thread::Backtrace`, `Thread::Backtrace::Location`, `File::Stat`, `Method`.
- This makes these classes faster to allocate and free, use less memory and reduce
- heap fragmentation.
-* `defined?(@ivar)` is optimized with Object Shapes.
+* Fixed several race conditions in Kernel#autoload. [[Bug #18782]]
+* Cache invalidation for expressions referencing constants is now
+ more fine-grained. `RubyVM.stat(:global_constant_state)` was
+ removed because it was closely tied to the previous caching scheme
+ where setting any constant invalidates all caches in the system.
+ New keys, `:constant_cache_invalidations` and `:constant_cache_misses`,
+ were introduced to help with use cases for `:global_constant_state`.
+ [[Feature #18589]]
+* The cache-based optimization for Regexp matching is introduced.
+ [[Feature #19104]]
+* [Variable Width Allocation](https://shopify.engineering/ruby-variable-width-allocation)
+ is now enabled by default. [[Feature #18239]]
+* Added a new instance variable caching mechanism, called object shapes, which
+ improves inline cache hits for most objects and allows us to generate very
+ efficient JIT code. Objects whose instance variables are defined in a
+ consistent order will see the most performance benefits.
+ [[Feature #18776]]
+* Speed up marking instruction sequences by using a bitmap to find "markable"
+ objects. This change results in faster major collections.
+ [[Feature #18875]]
+
+## JIT
### YJIT
-* Major performance improvements over Ruby 3.2
- * Support for splat and rest arguments has been improved.
- * Registers are allocated for stack operations of the virtual machine.
- * More calls with optional arguments are compiled. Exception handlers are also compiled.
- * Unsupported call types and megamorphic call sites no longer exit to the interpreter.
- * Basic methods like Rails `#blank?` and
- [specialized `#present?`](https://github.com/rails/rails/pull/49909) are inlined.
- * `Integer#*`, `Integer#!=`, `String#!=`, `String#getbyte`,
- `Kernel#block_given?`, `Kernel#is_a?`, `Kernel#instance_of?`, and `Module#===`
- are specially optimized.
- * Compilation speed is now slightly faster than Ruby 3.2.
- * Now more than 3x faster than the interpreter on Optcarrot!
-* Significantly improved memory usage over Ruby 3.2
- * Metadata for compiled code uses a lot less memory.
- * `--yjit-call-threshold` is automatically raised from 30 to 120
- when the application has more than 40,000 ISEQs.
- * `--yjit-cold-threshold` is added to skip compiling cold ISEQs.
- * More compact code is generated on Arm64.
-* Code GC is now disabled by default
- * `--yjit-exec-mem-size` is treated as a hard limit where compilation of new code stops.
- * No sudden drops in performance due to code GC.
- Better copy-on-write behavior on servers reforking with
- [Pitchfork](https://github.com/shopify/pitchfork).
- * You can still enable code GC if desired with `--yjit-code-gc`
-* Add `RubyVM::YJIT.enable` that can enable YJIT at run-time
- * You can start YJIT without modifying command-line arguments or environment variables.
- Rails 7.2 will [enable YJIT by default](https://github.com/rails/rails/pull/49947)
- using this method.
- * This can also be used to enable YJIT only once your application is
- done booting. `--yjit-disable` can be used if you want to use other
- YJIT options while disabling YJIT at boot.
-* More YJIT stats are available by default
- * `yjit_alloc_size` and several more metadata-related stats are now available by default.
- * `ratio_in_yjit` stat produced by `--yjit-stats` is now available in release builds,
- a special stats or dev build is no longer required to access most stats.
-* Add more profiling capabilities
- * `--yjit-perf` is added to facilitate profiling with Linux perf.
- * `--yjit-trace-exits` now supports sampling with `--yjit-trace-exits-sample-rate=N`
-* More thorough testing and multiple bug fixes
-* `--yjit-stats=quiet` is added to avoid printing stats on exit.
+* YJIT is no longer experimental
+ * Has been tested on production workloads for over a year and proven to be quite stable.
+* YJIT now supports both x86-64 and arm64/aarch64 CPUs on Linux, MacOS, BSD and other UNIX platforms.
+ * This release brings support for Mac M1/M2, AWS Graviton and Raspberry Pi 4.
+* Building YJIT now requires Rust 1.58.0+. [[Feature #18481]]
+ * In order to ensure that CRuby is built with YJIT, please install `rustc` >= 1.58.0
+ before running `./configure`
+ * Please reach out to the YJIT team should you run into any issues.
+* Physical memory for JIT code is lazily allocated. Unlike Ruby 3.1,
+ the RSS of a Ruby process is minimized because virtual memory pages
+ allocated by `--yjit-exec-mem-size` will not be mapped to physical
+ memory pages until actually utilized by JIT code.
+* Introduce Code GC that frees all code pages when the memory consumption
+ by JIT code reaches `--yjit-exec-mem-size`.
+ * `RubyVM::YJIT.runtime_stats` returns Code GC metrics in addition to
+ existing `inline_code_size` and `outlined_code_size` keys:
+ `code_gc_count`, `live_page_count`, `freed_page_count`, and `freed_code_size`.
+* Most of the statistics produced by `RubyVM::YJIT.runtime_stats` are now available in release builds.
+ * Simply run ruby with `--yjit-stats` to compute and dump stats (incurs some run-time overhead).
+* YJIT is now optimized to take advantage of object shapes. [[Feature #18776]]
+* Take advantage of finer-grained constant invalidation to invalidate less code when defining new constants. [[Feature #18589]]
+* The default `--yjit-exec-mem-size` is changed to 64 (MiB).
+* The default `--yjit-call-threshold` is changed to 30.
### MJIT
-* MJIT is removed.
- * `--disable-jit-support` is removed. Consider using `--disable-yjit --disable-rjit` instead.
-
-### RJIT
-
-* Introduced a pure-Ruby JIT compiler RJIT.
- * RJIT supports only x86\_64 architecture on Unix platforms.
- * Unlike MJIT, it doesn't require a C compiler at runtime.
-* RJIT exists only for experimental purposes.
- * You should keep using YJIT in production.
-
-### M:N Thread scheduler
-
-* M:N Thread scheduler is introduced. [[Feature #19842]]
- * Background: Ruby 1.8 and before, M:1 thread scheduler (M Ruby threads
- with 1 native thread. Called as User level threads or Green threads)
- is used. Ruby 1.9 and later, 1:1 thread scheduler (1 Ruby thread with
- 1 native thread). M:1 threads takes lower resources compare with 1:1
- threads because it needs only 1 native threads. However it is difficult
- to support context switching for all of blocking operation so 1:1
- threads are employed from Ruby 1.9. M:N thread scheduler uses N native
- threads for M Ruby threads (N is small number in general). It doesn't
- need same number of native threads as Ruby threads (similar to the M:1
- thread scheduler). Also our M:N threads supports blocking operations
- well same as 1:1 threads. See the ticket for more details.
- Our M:N thread scheduler refers on the goroutine scheduler in the
- Go language.
- * In a ractor, only 1 thread can run in a same time because of
- implementation. Therefore, applications that use only one Ractor
- (most applications) M:N thread scheduler works as M:1 thread scheduler
- with further extension from Ruby 1.8.
- * M:N thread scheduler can introduce incompatibility for C-extensions,
- so it is disabled by default on the main Ractors.
- `RUBY_MN_THREADS=1` environment variable will enable it.
- On non-main Ractors, M:N thread scheduler is enabled (and can not
- disable it now).
- * `N` (the number of native threads) can be specified with `RUBY_MAX_CPU`
- environment variable. The default is 8.
- Note that more than `N` native threads are used to support many kind of
- blocking operations.
-
-[Bug #595]: https://bugs.ruby-lang.org/issues/595
-[Feature #10602]: https://bugs.ruby-lang.org/issues/10602
-[Bug #17146]: https://bugs.ruby-lang.org/issues/17146
-[Feature #18183]: https://bugs.ruby-lang.org/issues/18183
-[Feature #18285]: https://bugs.ruby-lang.org/issues/18285
-[Feature #18498]: https://bugs.ruby-lang.org/issues/18498
-[Feature #18515]: https://bugs.ruby-lang.org/issues/18515
-[Feature #18551]: https://bugs.ruby-lang.org/issues/18551
-[Feature #18885]: https://bugs.ruby-lang.org/issues/18885
-[Feature #18949]: https://bugs.ruby-lang.org/issues/18949
-[Feature #18980]: https://bugs.ruby-lang.org/issues/18980
-[Bug #19012]: https://bugs.ruby-lang.org/issues/19012
-[Feature #19057]: https://bugs.ruby-lang.org/issues/19057
-[Bug #19150]: https://bugs.ruby-lang.org/issues/19150
-[Bug #19293]: https://bugs.ruby-lang.org/issues/19293
-[Feature #19314]: https://bugs.ruby-lang.org/issues/19314
-[Feature #19347]: https://bugs.ruby-lang.org/issues/19347
-[Feature #19351]: https://bugs.ruby-lang.org/issues/19351
-[Feature #19362]: https://bugs.ruby-lang.org/issues/19362
-[Feature #19370]: https://bugs.ruby-lang.org/issues/19370
-[Feature #19521]: https://bugs.ruby-lang.org/issues/19521
-[Feature #19538]: https://bugs.ruby-lang.org/issues/19538
-[Feature #19561]: https://bugs.ruby-lang.org/issues/19561
-[Feature #19571]: https://bugs.ruby-lang.org/issues/19571
-[Feature #19572]: https://bugs.ruby-lang.org/issues/19572
-[Feature #19591]: https://bugs.ruby-lang.org/issues/19591
-[Feature #19630]: https://bugs.ruby-lang.org/issues/19630
-[Feature #19637]: https://bugs.ruby-lang.org/issues/19637
-[Feature #19678]: https://bugs.ruby-lang.org/issues/19678
-[Feature #19714]: https://bugs.ruby-lang.org/issues/19714
-[Feature #19725]: https://bugs.ruby-lang.org/issues/19725
-[Feature #19757]: https://bugs.ruby-lang.org/issues/19757
-[Feature #19776]: https://bugs.ruby-lang.org/issues/19776
-[Feature #19777]: https://bugs.ruby-lang.org/issues/19777
-[Feature #19785]: https://bugs.ruby-lang.org/issues/19785
-[Feature #19790]: https://bugs.ruby-lang.org/issues/19790
-[Feature #19839]: https://bugs.ruby-lang.org/issues/19839
-[Feature #19842]: https://bugs.ruby-lang.org/issues/19842
-[Feature #19843]: https://bugs.ruby-lang.org/issues/19843
-[Bug #19868]: https://bugs.ruby-lang.org/issues/19868
-[Feature #19965]: https://bugs.ruby-lang.org/issues/19965
-[Feature #20005]: https://bugs.ruby-lang.org/issues/20005
-[Feature #20057]: https://bugs.ruby-lang.org/issues/20057
+* The MJIT compiler is re-implemented in Ruby as `ruby_vm/mjit/compiler`.
+* MJIT compiler is executed under a forked Ruby process instead of
+ doing it in a native thread called MJIT worker. [[Feature #18968]]
+ * As a result, Microsoft Visual Studio (MSWIN) is no longer supported.
+* MinGW is no longer supported. [[Feature #18824]]
+* Rename `--mjit-min-calls` to `--mjit-call-threshold`.
+* Change default `--mjit-max-cache` back from 10000 to 100.
+
+[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
+[Feature #12084]: https://bugs.ruby-lang.org/issues/12084
+[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
+[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
+[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
+[Feature #14332]: https://bugs.ruby-lang.org/issues/14332
+[Feature #15231]: https://bugs.ruby-lang.org/issues/15231
+[Feature #15357]: https://bugs.ruby-lang.org/issues/15357
+[Bug #15928]: https://bugs.ruby-lang.org/issues/15928
+[Feature #16122]: https://bugs.ruby-lang.org/issues/16122
+[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
+[Bug #16466]: https://bugs.ruby-lang.org/issues/16466
+[Feature #16663]: https://bugs.ruby-lang.org/issues/16663
+[Feature #16806]: https://bugs.ruby-lang.org/issues/16806
+[Bug #16889]: https://bugs.ruby-lang.org/issues/16889
+[Bug #16908]: https://bugs.ruby-lang.org/issues/16908
+[Feature #16989]: https://bugs.ruby-lang.org/issues/16989
+[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
+[Feature #17391]: https://bugs.ruby-lang.org/issues/17391
+[Bug #17545]: https://bugs.ruby-lang.org/issues/17545
+[Bug #17767]: https://bugs.ruby-lang.org/issues/17767
+[Feature #17837]: https://bugs.ruby-lang.org/issues/17837
+[Feature #17881]: https://bugs.ruby-lang.org/issues/17881
+[Feature #18033]: https://bugs.ruby-lang.org/issues/18033
+[Feature #18159]: https://bugs.ruby-lang.org/issues/18159
+[Feature #18239]: https://bugs.ruby-lang.org/issues/18239#note-17
+[Feature #18351]: https://bugs.ruby-lang.org/issues/18351
+[Feature #18367]: https://bugs.ruby-lang.org/issues/18367
+[Bug #18435]: https://bugs.ruby-lang.org/issues/18435
+[Feature #18462]: https://bugs.ruby-lang.org/issues/18462
+[Feature #18481]: https://bugs.ruby-lang.org/issues/18481
+[Bug #18487]: https://bugs.ruby-lang.org/issues/18487
+[Feature #18564]: https://bugs.ruby-lang.org/issues/18564
+[Feature #18571]: https://bugs.ruby-lang.org/issues/18571
+[Feature #18585]: https://bugs.ruby-lang.org/issues/18585
+[Feature #18589]: https://bugs.ruby-lang.org/issues/18589
+[Feature #18595]: https://bugs.ruby-lang.org/issues/18595
+[Feature #18598]: https://bugs.ruby-lang.org/issues/18598
+[Bug #18625]: https://bugs.ruby-lang.org/issues/18625
+[Feature #18630]: https://bugs.ruby-lang.org/issues/18630
+[Bug #18633]: https://bugs.ruby-lang.org/issues/18633
+[Feature #18639]: https://bugs.ruby-lang.org/issues/18639
+[Feature #18685]: https://bugs.ruby-lang.org/issues/18685
+[Bug #18729]: https://bugs.ruby-lang.org/issues/18729
+[Bug #18751]: https://bugs.ruby-lang.org/issues/18751
+[Feature #18774]: https://bugs.ruby-lang.org/issues/18774
+[Feature #18776]: https://bugs.ruby-lang.org/issues/18776
+[Bug #18782]: https://bugs.ruby-lang.org/issues/18782
+[Feature #18788]: https://bugs.ruby-lang.org/issues/18788
+[Feature #18798]: https://bugs.ruby-lang.org/issues/18798
+[Feature #18809]: https://bugs.ruby-lang.org/issues/18809
+[Feature #18821]: https://bugs.ruby-lang.org/issues/18821
+[Feature #18822]: https://bugs.ruby-lang.org/issues/18822
+[Feature #18824]: https://bugs.ruby-lang.org/issues/18824
+[Feature #18832]: https://bugs.ruby-lang.org/issues/18832
+[Feature #18875]: https://bugs.ruby-lang.org/issues/18875
+[Feature #18925]: https://bugs.ruby-lang.org/issues/18925
+[Feature #18944]: https://bugs.ruby-lang.org/issues/18944
+[Feature #18949]: https://bugs.ruby-lang.org/issues/18949
+[Feature #18968]: https://bugs.ruby-lang.org/issues/18968
+[Feature #19008]: https://bugs.ruby-lang.org/issues/19008
+[Feature #19013]: https://bugs.ruby-lang.org/issues/19013
+[Feature #19026]: https://bugs.ruby-lang.org/issues/19026
+[Feature #19036]: https://bugs.ruby-lang.org/issues/19036
+[Feature #19060]: https://bugs.ruby-lang.org/issues/19060
+[Feature #19070]: https://bugs.ruby-lang.org/issues/19070
+[Feature #19071]: https://bugs.ruby-lang.org/issues/19071
+[Feature #19078]: https://bugs.ruby-lang.org/issues/19078
+[Bug #19087]: https://bugs.ruby-lang.org/issues/19087
+[Bug #19100]: https://bugs.ruby-lang.org/issues/19100
+[Feature #19104]: https://bugs.ruby-lang.org/issues/19104
+[Feature #19135]: https://bugs.ruby-lang.org/issues/19135
+[Feature #19138]: https://bugs.ruby-lang.org/issues/19138
+[Feature #19194]: https://bugs.ruby-lang.org/issues/19194
+[Molinillo]: https://github.com/CocoaPods/Molinillo
+[PubGrub]: https://github.com/jhawthorn/pub_grub
+[GH-net-protocol-14]: https://github.com/ruby/net-protocol/pull/14
+[GH-pathname-20]: https://github.com/ruby/pathname/pull/20
+[GH-6791]: https://github.com/ruby/ruby/pull/6791
+[GH-6868]: https://github.com/ruby/ruby/pull/6868
+[GH-rubygems-4475]: https://github.com/rubygems/rubygems/pull/4475
+[GH-rubygems-6149]: https://github.com/rubygems/rubygems/pull/6149
+[GH-rubygems-6167]: https://github.com/rubygems/rubygems/pull/6167
+[sec-156615]: https://hackerone.com/reports/156615
+[CVE-2021-33621]: https://www.ruby-lang.org/en/news/2022/11/22/http-response-splitting-in-cgi-cve-2021-33621/
+[wasm/README.md]: https://github.com/ruby/ruby/blob/master/wasm/README.md
+[ruby.wasm]: https://github.com/ruby/ruby.wasm
diff --git a/README.ja.md b/README.ja.md
index 0d2d309fb8..93c0131690 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -1,10 +1,9 @@
[![Actions Status: MinGW](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
-[![Actions Status: RJIT](https://github.com/ruby/ruby/workflows/RJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"RJIT")
+[![Actions Status: MJIT](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
[![Actions Status: Ubuntu](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
[![Actions Status: Windows](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
[![AppVeyor status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
[![Travis Status](https://app.travis-ci.com/ruby/ruby.svg?branch=master)](https://app.travis-ci.com/ruby/ruby)
-[![Cirrus Status](https://api.cirrus-ci.com/github/ruby/ruby.svg)](https://cirrus-ci.com/github/ruby/ruby/master)
# Rubyã¨ã¯
@@ -26,7 +25,7 @@ Rubyã¯ãƒ†ã‚­ã‚¹ãƒˆå‡¦ç†é–¢ä¿‚ã®èƒ½åŠ›ãªã©ã«å„ªã‚Œï¼ŒPerlã¨åŒã˜ãらã„
* ダイナミックローディング (アーキテクãƒãƒ£ã«ã‚ˆã‚‹)
* ç§»æ¤æ€§ãŒé«˜ã„.多ãã®Unix-like/POSIX互æ›ãƒ—ラットフォーム上ã§å‹•ãã ã‘ã§ãªã,Windows, macOS,
Haikuãªã©ã®ä¸Šã§ã‚‚å‹•ã cf.
- https://docs.ruby-lang.org/en/master/maintainers_md.html#label-Platform+Maintainers
+ https://github.com/ruby/ruby/blob/master/doc/contributing.rdoc#platform-maintainers
## 入手法
@@ -50,6 +49,17 @@ https://www.ruby-lang.org/ja/downloads/
Rubyリãƒã‚¸ãƒˆãƒªã®æœ¬æ¥ã®master㯠https://git.ruby-lang.org/ruby.git ã«ã‚りã¾ã™ï¼Ž
コミッタã¯ã“ã¡ã‚‰ã‚’使ã„ã¾ã™ï¼Ž
+### Subversion
+
+å¤ã„Rubyã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§ã‚‚å–å¾—ã§ãã¾ã™ï¼Ž
+
+ $ svn co https://svn.ruby-lang.org/repos/ruby/branches/ruby_2_6/ ruby
+
+ä»–ã®ãƒ–ランãƒã®ä¸€è¦§ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§è¦‹ã‚‰ã‚Œã¾ã™ï¼Ž
+
+ $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
+
+
## ホームページ
Rubyã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã®URLã¯
@@ -60,20 +70,20 @@ https://www.ruby-lang.org/
## メーリングリスト
-Rubyã®ãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆãŒã‚りã¾ã™ï¼Žå‚åŠ å¸Œæœ›ã®æ–¹ã¯ [ruby-list-request@ml.ruby-lang.org] ã¾ã§ä»¶åã«
+Rubyã®ãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆãŒã‚りã¾ã™ï¼Žå‚åŠ å¸Œæœ›ã®æ–¹ã¯ [ruby-list-request@ruby-lang.org] ã¾ã§æœ¬æ–‡ã«
- join
+ subscribe
ã¨æ›¸ã„ã¦é€ã£ã¦ä¸‹ã•ã„.
Ruby開発者å‘ã‘メーリングリストもã‚りã¾ã™ï¼Žã“ã¡ã‚‰ã§ã¯rubyã®ãƒã‚°ï¼Œå°†æ¥ã®ä»•様拡張ãªã©å®Ÿè£…上ã®å•題ã«ã¤ã„ã¦è­°è«–ã•れã¦ã„ã¾ã™ï¼Ž
-å‚åŠ å¸Œæœ›ã®æ–¹ã¯ [ruby-dev-request@ml.ruby-lang.org] ã¾ã§ruby-listã¨åŒæ§˜ã®æ–¹æ³•ã§ãƒ¡ãƒ¼ãƒ«ã—ã¦ãã ã•ã„.
+å‚åŠ å¸Œæœ›ã®æ–¹ã¯ [ruby-dev-request@ruby-lang.org] ã¾ã§ruby-listã¨åŒæ§˜ã®æ–¹æ³•ã§ãƒ¡ãƒ¼ãƒ«ã—ã¦ãã ã•ã„.
Ruby拡張モジュールã«ã¤ã„ã¦è©±ã—åˆã†ruby-extãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆã¨æ•°å­¦é–¢ä¿‚ã®è©±é¡Œã«ã¤ã„ã¦è©±ã—åˆã†ruby-mathメーリングリストã¨
英語ã§rubyã«ã¤ã„ã¦è©±ã—åˆã†ruby-talkメーリングリストもã‚りã¾ã™ï¼Žå‚加方法ã¯ã©ã‚Œã‚‚åŒã˜ã§ã™ï¼Ž
-[ruby-list-request@ml.ruby-lang.org]: mailto:ruby-list-request@ml.ruby-lang.org?subject=join
-[ruby-dev-request@ml.ruby-lang.org]: mailto:ruby-dev-request@ml.ruby-lang.org?subject=join
+[ruby-list-request@ruby-lang.org]: mailto:ruby-list-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
+[ruby-dev-request@ruby-lang.org]: mailto:ruby-dev-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
## コンパイル・インストール
@@ -152,7 +162,7 @@ UNIXã§ã‚れ㰠`configure` ãŒã»ã¨ã‚“ã©ã®å·®ç•°ã‚’å¸åŽã—ã¦ãれるã¯
## é…布æ¡ä»¶
-[COPYING.ja](https://docs.ruby-lang.org/en/master/COPYING_ja.html) ファイルをå‚ç…§ã—ã¦ãã ã•ã„.
+[COPYING.ja](COPYING.ja) ファイルをå‚ç…§ã—ã¦ãã ã•ã„.
## フィードãƒãƒƒã‚¯
diff --git a/README.md b/README.md
index 8fb3786691..c445448c71 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
[![Actions Status: MinGW](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
-[![Actions Status: RJIT](https://github.com/ruby/ruby/workflows/RJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"RJIT")
+[![Actions Status: MJIT](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
[![Actions Status: Ubuntu](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
[![Actions Status: Windows](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
[![AppVeyor status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
@@ -24,20 +24,15 @@ It is simple, straightforward, and extensible.
* Dynamic Loading of Object Files (on some architectures)
* Highly Portable (works on many Unix-like/POSIX compatible platforms as
well as Windows, macOS, etc.) cf.
- https://docs.ruby-lang.org/en/master/maintainers_md.html#label-Platform+Maintainers
+ https://github.com/ruby/ruby/blob/master/doc/maintainers.rdoc#label-Platform+Maintainers
-## How to get Ruby
+## How to get Ruby with Git
For a complete list of ways to install Ruby, including using third-party tools
like rvm, see:
https://www.ruby-lang.org/en/downloads/
-You can download release packages and the snapshot of the repository. If you want to
-download whole versions of Ruby, please visit https://www.ruby-lang.org/en/downloads/releases/.
-
-### Download with Git
-
The mirror of the Ruby source tree can be checked out with the following command:
$ git clone https://github.com/ruby/ruby.git
@@ -52,7 +47,7 @@ if you are a committer.
## How to build
-See [Building Ruby](https://docs.ruby-lang.org/en/master/contributing/building_ruby_md.html)
+see [Building Ruby](doc/contributing/building_ruby.md)
## Ruby home page
@@ -68,11 +63,11 @@ https://www.ruby-lang.org/
There is a mailing list to discuss Ruby. To subscribe to this list, please
send the following phrase:
- join
+ subscribe
-in the mail subject (not body) to the address [ruby-talk-request@ml.ruby-lang.org].
+in the mail body (not subject) to the address [ruby-talk-request@ruby-lang.org].
-[ruby-talk-request@ml.ruby-lang.org]: mailto:ruby-talk-request@ml.ruby-lang.org?subject=join
+[ruby-talk-request@ruby-lang.org]: mailto:ruby-talk-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
## Copying
diff --git a/addr2line.c b/addr2line.c
index 2a69dd0966..e5f25293e2 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -8,14 +8,10 @@
**********************************************************************/
-#if defined(__clang__) && defined(__has_warning)
-#if __has_warning("-Wgnu-empty-initializer")
+#if defined(__clang__)
#pragma clang diagnostic ignored "-Wgnu-empty-initializer"
-#endif
-#if __has_warning("-Wgcc-compat")
#pragma clang diagnostic ignored "-Wgcc-compat"
#endif
-#endif
#include "ruby/internal/config.h"
#include "ruby/defines.h"
@@ -61,21 +57,8 @@ void *alloca();
# endif
# endif /* AIX */
# endif /* HAVE_ALLOCA_H */
-# ifndef UNREACHABLE
-# define UNREACHABLE __builtin_unreachable()
-# endif
-# ifndef UNREACHABLE_RETURN
-# define UNREACHABLE_RETURN(_) __builtin_unreachable()
-# endif
#endif /* __GNUC__ */
-#ifndef UNREACHABLE
-# define UNREACHABLE abort()
-#endif
-#ifndef UNREACHABLE_RETURN
-# define UNREACHABLE_RETURN(_) return (abort(), (_))
-#endif
-
#ifdef HAVE_DLADDR
# include <dlfcn.h>
#endif
@@ -144,7 +127,7 @@ void *alloca();
#define DW_LNE_define_file 0x03
#define DW_LNE_set_discriminator 0x04 /* DWARF4 */
-#define kprintf(...) fprintf(errout, "" __VA_ARGS__)
+PRINTF_ARGS(static int kprintf(const char *fmt, ...), 1, 2);
typedef struct line_info {
const char *dirname;
@@ -201,7 +184,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
&obj->debug_line_str
};
if (n < 0 || DWARF_SECTION_COUNT <= n) {
- UNREACHABLE_RETURN(0);
+ abort();
}
return ary[n];
}
@@ -254,7 +237,7 @@ sleb128(const char **p)
}
static const char *
-get_nth_dirname(unsigned long dir, const char *p, FILE *errout)
+get_nth_dirname(unsigned long dir, const char *p)
{
if (!dir--) {
return "";
@@ -271,14 +254,10 @@ get_nth_dirname(unsigned long dir, const char *p, FILE *errout)
return p;
}
-static const char *parse_ver5_debug_line_header(
- const char *p, int idx, uint8_t format,
- obj_info_t *obj, const char **out_path,
- uint64_t *out_directory_index, FILE *errout);
+static const char *parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t *obj, const char **out_path, uint64_t *out_directory_index);
static void
-fill_filename(int file, uint8_t format, uint16_t version, const char *include_directories,
- const char *filenames, line_info_t *line, obj_info_t *obj, FILE *errout)
+fill_filename(int file, uint8_t format, uint16_t version, const char *include_directories, const char *filenames, line_info_t *line, obj_info_t *obj)
{
int i;
const char *p = filenames;
@@ -287,9 +266,9 @@ fill_filename(int file, uint8_t format, uint16_t version, const char *include_di
if (version >= 5) {
const char *path;
uint64_t directory_index = -1;
- parse_ver5_debug_line_header(filenames, file, format, obj, &path, &directory_index, errout);
+ parse_ver5_debug_line_header(filenames, file, format, obj, &path, &directory_index);
line->filename = path;
- parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL, errout);
+ parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL);
line->dirname = path;
}
else {
@@ -311,7 +290,7 @@ fill_filename(int file, uint8_t format, uint16_t version, const char *include_di
if (i == file) {
line->filename = filename;
- line->dirname = get_nth_dirname(dir, include_directories, errout);
+ line->dirname = get_nth_dirname(dir, include_directories);
}
}
}
@@ -320,7 +299,7 @@ fill_filename(int file, uint8_t format, uint16_t version, const char *include_di
static void
fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
uint8_t format, uint16_t version, const char *include_directories, const char *filenames,
- obj_info_t *obj, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t *obj, line_info_t *lines, int offset)
{
int i;
addr += obj->base_addr - obj->vmaddr;
@@ -329,7 +308,7 @@ fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
/* We assume one line code doesn't result >100 bytes of native code.
We may want more reliable way eventually... */
if (addr < a && a < addr + 100) {
- fill_filename(file, format, version, include_directories, filenames, &lines[i], obj, errout);
+ fill_filename(file, format, version, include_directories, filenames, &lines[i], obj);
lines[i].line = line;
}
}
@@ -354,7 +333,7 @@ struct LineNumberProgramHeader {
};
static int
-parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header, FILE *errout)
+parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header)
{
const char *p = *pp;
header->unit_length = *(uint32_t *)p;
@@ -400,7 +379,7 @@ parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgr
if (header->version >= 5) {
header->include_directories = p;
- p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL, errout);
+ p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL);
header->filenames = p;
}
else {
@@ -427,7 +406,7 @@ parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgr
static int
parse_debug_line_cu(int num_traces, void **traces, const char **debug_line,
- obj_info_t *obj, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t *obj, line_info_t *lines, int offset)
{
const char *p = (const char *)*debug_line;
struct LineNumberProgramHeader header;
@@ -444,7 +423,7 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line,
/* int epilogue_begin = 0; */
/* unsigned int isa = 0; */
- if (parse_debug_line_header(obj, &p, &header, errout))
+ if (parse_debug_line_header(obj, &p, &header))
return -1;
is_stmt = header.default_is_stmt;
@@ -455,7 +434,7 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line,
header.version, \
header.include_directories, \
header.filenames, \
- obj, lines, offset, errout); \
+ obj, lines, offset); \
/*basic_block = prologue_end = epilogue_begin = 0;*/ \
} while (0)
@@ -555,11 +534,11 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line,
static int
parse_debug_line(int num_traces, void **traces,
const char *debug_line, unsigned long size,
- obj_info_t *obj, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t *obj, line_info_t *lines, int offset)
{
const char *debug_line_end = debug_line + size;
while (debug_line < debug_line_end) {
- if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset, errout))
+ if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset))
return -1;
}
if (debug_line != debug_line_end) {
@@ -572,7 +551,7 @@ parse_debug_line(int num_traces, void **traces,
/* read file and fill lines */
static uintptr_t
fill_lines(int num_traces, void **traces, int check_debuglink,
- obj_info_t **objp, line_info_t *lines, int offset, FILE *errout);
+ obj_info_t **objp, line_info_t *lines, int offset);
static void
append_obj(obj_info_t **objp)
@@ -600,7 +579,7 @@ append_obj(obj_info_t **objp)
// check the path pattern of "/usr/lib/debug/usr/bin/ruby.debug"
static void
follow_debuglink(const char *debuglink, int num_traces, void **traces,
- obj_info_t **objp, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t **objp, line_info_t *lines, int offset)
{
static const char global_debug_dir[] = "/usr/lib/debug";
const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
@@ -626,13 +605,13 @@ follow_debuglink(const char *debuglink, int num_traces, void **traces,
o2 = *objp;
o2->base_addr = o1->base_addr;
o2->path = o1->path;
- fill_lines(num_traces, traces, 0, objp, lines, offset, errout);
+ fill_lines(num_traces, traces, 0, objp, lines, offset);
}
// check the path pattern of "/usr/lib/debug/.build-id/ab/cdef1234.debug"
static void
follow_debuglink_build_id(const char *build_id, size_t build_id_size, int num_traces, void **traces,
- obj_info_t **objp, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t **objp, line_info_t *lines, int offset)
{
static const char global_debug_dir[] = "/usr/lib/debug/.build-id/";
const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
@@ -657,7 +636,7 @@ follow_debuglink_build_id(const char *build_id, size_t build_id_size, int num_tr
o2 = *objp;
o2->base_addr = o1->base_addr;
o2->path = o1->path;
- fill_lines(num_traces, traces, 0, objp, lines, offset, errout);
+ fill_lines(num_traces, traces, 0, objp, lines, offset);
}
#endif
@@ -861,11 +840,7 @@ enum
DW_FORM_addrx1 = 0x29,
DW_FORM_addrx2 = 0x2a,
DW_FORM_addrx3 = 0x2b,
- DW_FORM_addrx4 = 0x2c,
-
- /* GNU extensions for referring to .gnu_debugaltlink dwz-compressed info */
- DW_FORM_GNU_ref_alt = 0x1f20,
- DW_FORM_GNU_strp_alt = 0x1f21
+ DW_FORM_addrx4 = 0x2c
};
/* Range list entry encodings */
@@ -1083,13 +1058,13 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader)
}
static int
-di_read_debug_line_cu(DebugInfoReader *reader, FILE *errout)
+di_read_debug_line_cu(DebugInfoReader *reader)
{
const char *p;
struct LineNumberProgramHeader header;
p = (const char *)reader->debug_line_cu_end;
- if (parse_debug_line_header(reader->obj, &p, &header, errout))
+ if (parse_debug_line_header(reader->obj, &p, &header))
return -1;
reader->debug_line_cu_end = (char *)header.cu_end;
@@ -1169,32 +1144,25 @@ resolve_strx(DebugInfoReader *reader, uint64_t idx)
return reader->obj->debug_str.ptr + off;
}
-static bool
-debug_info_reader_read_addr_value_member(DebugInfoReader *reader, DebugInfoValue *v, int size)
+static void
+debug_info_reader_read_addr_value(DebugInfoReader *reader, DebugInfoValue *v)
{
- if (size == 4) {
+ if (reader->address_size == 4) {
set_uint_value(v, read_uint32(&reader->p));
- } else if (size == 8) {
+ } else if (reader->address_size == 8) {
set_uint_value(v, read_uint64(&reader->p));
} else {
- return false;
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
}
- return true;
}
-#define debug_info_reader_read_addr_value(reader, v, mem) \
- if (!debug_info_reader_read_addr_value_member((reader), (v), (reader)->mem)) { \
- kprintf("unknown " #mem ":%d", (reader)->mem); \
- return false; \
- }
-
-
-static bool
-debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v, FILE *errout)
+static void
+debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
{
switch (form) {
case DW_FORM_addr:
- debug_info_reader_read_addr_value(reader, v, address_size);
+ debug_info_reader_read_addr_value(reader, v);
break;
case DW_FORM_block2:
v->size = read_uint16(&reader->p);
@@ -1249,9 +1217,16 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
if (reader->current_version <= 2) {
// DWARF Version 2 specifies that references have
// the same size as an address on the target system
- debug_info_reader_read_addr_value(reader, v, address_size);
+ debug_info_reader_read_addr_value(reader, v);
} else {
- debug_info_reader_read_addr_value(reader, v, format);
+ if (reader->format == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->format == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown format:%d", reader->format);
+ abort();
+ }
}
break;
case DW_FORM_ref1:
@@ -1352,28 +1327,20 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
case DW_FORM_addrx4:
set_addr_idx_value(v, read_uint32(&reader->p));
break;
- /* we have no support for actually reading the real values of these refs out
- * of the .gnu_debugaltlink dwz-compressed debuginfo at the moment, but "read"
- * them anyway so that we advance the reader by the right amount. */
- case DW_FORM_GNU_ref_alt:
- case DW_FORM_GNU_strp_alt:
- read_uint(reader);
- set_uint_value(v, 0);
- break;
case 0:
goto fail;
break;
}
- return true;
+ return;
fail:
- kprintf("%d: unsupported form: %#"PRIx64"\n", __LINE__, form);
- return false;
+ fprintf(stderr, "%d: unsupported form: %#"PRIx64"\n", __LINE__, form);
+ exit(1);
}
/* find abbrev in current compilation unit */
static const char *
-di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout)
+di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
{
const char *p;
if (abbrev_number < ABBREV_TABLE_SIZE) {
@@ -1386,8 +1353,8 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout)
di_skip_die_attributes(&p);
for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
if (n == 0) {
- kprintf("%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
- return NULL;
+ fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
+ exit(1);
}
uleb128(&p); /* tag */
p++; /* has_children */
@@ -1398,52 +1365,52 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout)
#if 0
static void
-hexdump0(const unsigned char *p, size_t n, FILE *errout)
+hexdump0(const unsigned char *p, size_t n)
{
size_t i;
- kprintf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
+ fprintf(stderr, " 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (i=0; i < n; i++){
switch (i & 15) {
case 0:
- kprintf("%02" PRIdSIZE ": %02X ", i/16, p[i]);
+ fprintf(stderr, "%02" PRIdSIZE ": %02X ", i/16, p[i]);
break;
case 15:
- kprintf("%02X\n", p[i]);
+ fprintf(stderr, "%02X\n", p[i]);
break;
default:
- kprintf("%02X ", p[i]);
+ fprintf(stderr, "%02X ", p[i]);
break;
}
}
if ((i & 15) != 15) {
- kprintf("\n");
+ fprintf(stderr, "\n");
}
}
-#define hexdump(p,n,e) hexdump0((const unsigned char *)p, n, e)
+#define hexdump(p,n) hexdump0((const unsigned char *)p, n)
static void
-div_inspect(DebugInfoValue *v, FILE *errout)
+div_inspect(DebugInfoValue *v)
{
switch (v->type) {
case VAL_uint:
- kprintf("%d: type:%d size:%" PRIxSIZE " v:%"PRIx64"\n",__LINE__,v->type,v->size,v->as.uint64);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:%"PRIx64"\n",__LINE__,v->type,v->size,v->as.uint64);
break;
case VAL_int:
- kprintf("%d: type:%d size:%" PRIxSIZE " v:%"PRId64"\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:%"PRId64"\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64);
break;
case VAL_cstr:
- kprintf("%d: type:%d size:%" PRIxSIZE " v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr);
break;
case VAL_data:
- kprintf("%d: type:%d size:%" PRIxSIZE " v:\n",__LINE__,v->type,v->size);
- hexdump(v->as.ptr, 16, errout);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:\n",__LINE__,v->type,v->size);
+ hexdump(v->as.ptr, 16);
break;
}
}
#endif
static DIE *
-di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout)
+di_read_die(DebugInfoReader *reader, DIE *die)
{
uint64_t abbrev_number = uleb128(&reader->p);
if (abbrev_number == 0) {
@@ -1451,7 +1418,7 @@ di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout)
return NULL;
}
- if (!(reader->q = di_find_abbrev(reader, abbrev_number, errout))) return NULL;
+ reader->q = di_find_abbrev(reader, abbrev_number);
die->pos = reader->p - reader->obj->debug_info.ptr - 1;
die->tag = (int)uleb128(&reader->q); /* tag */
@@ -1463,26 +1430,26 @@ di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout)
}
static DebugInfoValue *
-di_read_record(DebugInfoReader *reader, DebugInfoValue *vp, FILE *errout)
+di_read_record(DebugInfoReader *reader, DebugInfoValue *vp)
{
uint64_t at = uleb128(&reader->q);
uint64_t form = uleb128(&reader->q);
if (!at || !form) return NULL;
vp->at = at;
vp->form = form;
- if (!debug_info_reader_read_value(reader, form, vp, errout)) return NULL;
+ debug_info_reader_read_value(reader, form, vp);
return vp;
}
-static bool
-di_skip_records(DebugInfoReader *reader, FILE *errout)
+static void
+di_skip_records(DebugInfoReader *reader)
{
for (;;) {
- DebugInfoValue v = {{0}};
+ DebugInfoValue v = {{}};
uint64_t at = uleb128(&reader->q);
uint64_t form = uleb128(&reader->q);
- if (!at || !form) return true;
- if (!debug_info_reader_read_value(reader, form, &v, errout)) return false;
+ if (!at || !form) return;
+ debug_info_reader_read_value(reader, form, &v);
}
}
@@ -1494,14 +1461,13 @@ typedef struct addr_header {
/* uint8_t segment_selector_size; */
} addr_header_t;
-static bool
-addr_header_init(obj_info_t *obj, addr_header_t *header, FILE *errout)
-{
+static void
+addr_header_init(obj_info_t *obj, addr_header_t *header) {
const char *p = obj->debug_addr.ptr;
header->ptr = p;
- if (!p) return true;
+ if (!p) return;
header->unit_length = *(uint32_t *)p;
p += sizeof(uint32_t);
@@ -1515,12 +1481,7 @@ addr_header_init(obj_info_t *obj, addr_header_t *header, FILE *errout)
p += 2; /* version */
header->address_size = *p++;
- if (header->address_size != 4 && header->address_size != 8) {
- kprintf("unknown address_size:%d", header->address_size);
- return false;
- }
p++; /* segment_selector_size */
- return true;
}
static uint64_t
@@ -1540,12 +1501,11 @@ typedef struct rnglists_header {
uint32_t offset_entry_count;
} rnglists_header_t;
-static bool
-rnglists_header_init(obj_info_t *obj, rnglists_header_t *header, FILE *errout)
-{
+static void
+rnglists_header_init(obj_info_t *obj, rnglists_header_t *header) {
const char *p = obj->debug_rnglists.ptr;
- if (!p) return true;
+ if (!p) return;
header->unit_length = *(uint32_t *)p;
p += sizeof(uint32_t);
@@ -1559,13 +1519,8 @@ rnglists_header_init(obj_info_t *obj, rnglists_header_t *header, FILE *errout)
p += 2; /* version */
header->address_size = *p++;
- if (header->address_size != 4 && header->address_size != 8) {
- kprintf("unknown address_size:%d", header->address_size);
- return false;
- }
p++; /* segment_selector_size */
header->offset_entry_count = *(uint32_t *)p;
- return true;
}
typedef struct {
@@ -1609,23 +1564,26 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v, addr_header_t *addr_header, uint64_
}
static uint64_t
-read_dw_form_addr(DebugInfoReader *reader, const char **ptr, FILE *errout)
+read_dw_form_addr(DebugInfoReader *reader, const char **ptr)
{
const char *p = *ptr;
*ptr = p + reader->address_size;
if (reader->address_size == 4) {
return read_uint32(&p);
- } else {
+ } else if (reader->address_size == 8) {
return read_uint64(&p);
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
}
}
static uintptr_t
-ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header, FILE *errout)
+ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header)
{
if (ptr->high_pc_set) {
if (ptr->ranges_set || !ptr->low_pc_set) {
- return UINTPTR_MAX;
+ exit(1);
}
if (ptr->low_pc <= addr && addr <= ptr->high_pc) {
return (uintptr_t)ptr->low_pc;
@@ -1674,15 +1632,15 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h
to = (uintptr_t)base + uleb128(&p);
break;
case DW_RLE_base_address:
- base = read_dw_form_addr(reader, &p, errout);
+ base = read_dw_form_addr(reader, &p);
base_valid = true;
break;
case DW_RLE_start_end:
- from = (uintptr_t)read_dw_form_addr(reader, &p, errout);
- to = (uintptr_t)read_dw_form_addr(reader, &p, errout);
+ from = (uintptr_t)read_dw_form_addr(reader, &p);
+ to = (uintptr_t)read_dw_form_addr(reader, &p);
break;
case DW_RLE_start_length:
- from = (uintptr_t)read_dw_form_addr(reader, &p, errout);
+ from = (uintptr_t)read_dw_form_addr(reader, &p);
to = from + uleb128(&p);
break;
}
@@ -1690,7 +1648,7 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h
return from;
}
}
- return 0;
+ return false;
}
p = reader->obj->debug_ranges.ptr + ptr->ranges;
for (;;) {
@@ -1711,42 +1669,42 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h
return (uintptr_t)ptr->low_pc;
}
}
- return 0;
+ return false;
}
#if 0
static void
-ranges_inspect(DebugInfoReader *reader, ranges_t *ptr, FILE *errout)
+ranges_inspect(DebugInfoReader *reader, ranges_t *ptr)
{
if (ptr->high_pc_set) {
if (ptr->ranges_set || !ptr->low_pc_set) {
- kprintf("low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set);
- return;
+ fprintf(stderr,"low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set);
+ exit(1);
}
- kprintf("low_pc:%"PRIx64" high_pc:%"PRIx64"\n",ptr->low_pc,ptr->high_pc);
+ fprintf(stderr,"low_pc:%"PRIx64" high_pc:%"PRIx64"\n",ptr->low_pc,ptr->high_pc);
}
else if (ptr->ranges_set) {
char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
- kprintf("low_pc:%"PRIx64" ranges:%"PRIx64" %lx ",ptr->low_pc,ptr->ranges, p-reader->obj->mapped);
+ fprintf(stderr,"low_pc:%"PRIx64" ranges:%"PRIx64" %lx ",ptr->low_pc,ptr->ranges, p-reader->obj->mapped);
for (;;) {
uintptr_t from = read_uintptr(&p);
uintptr_t to = read_uintptr(&p);
if (!from && !to) break;
- kprintf("%"PRIx64"-%"PRIx64" ",ptr->low_pc+from,ptr->low_pc+to);
+ fprintf(stderr,"%"PRIx64"-%"PRIx64" ",ptr->low_pc+from,ptr->low_pc+to);
}
- kprintf("\n");
+ fprintf(stderr,"\n");
}
else if (ptr->low_pc_set) {
- kprintf("low_pc:%"PRIx64"\n",ptr->low_pc);
+ fprintf(stderr,"low_pc:%"PRIx64"\n",ptr->low_pc);
}
else {
- kprintf("empty\n");
+ fprintf(stderr,"empty\n");
}
}
#endif
static int
-di_read_cu(DebugInfoReader *reader, FILE *errout)
+di_read_cu(DebugInfoReader *reader)
{
uint64_t unit_length;
uint16_t version;
@@ -1773,23 +1731,23 @@ di_read_cu(DebugInfoReader *reader, FILE *errout)
debug_abbrev_offset = read_uint(reader);
reader->address_size = read_uint8(&reader->p);
}
- if (reader->address_size != 4 && reader->address_size != 8) {
- kprintf("unknown address_size:%d", reader->address_size);
- return -1;
- }
reader->q0 = reader->obj->debug_abbrev.ptr + debug_abbrev_offset;
reader->level = 0;
di_read_debug_abbrev_cu(reader);
- if (di_read_debug_line_cu(reader, errout)) return -1;
+ if (di_read_debug_line_cu(reader)) return -1;
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER_BUILD_DATE)
+ /* Though DWARF specifies "the applicable base address defaults to the base
+ address of the compilation unit", but GCC seems to use zero as default */
+#else
do {
DIE die;
- if (!di_read_die(reader, &die, errout)) continue;
+ if (!di_read_die(reader, &die)) continue;
if (die.tag != DW_TAG_compile_unit) {
- if (!di_skip_records(reader, errout)) return -1;
+ di_skip_records(reader);
break;
}
@@ -1797,11 +1755,11 @@ di_read_cu(DebugInfoReader *reader, FILE *errout)
reader->current_addr_base = 0;
reader->current_rnglists_base = 0;
- DebugInfoValue low_pc = {{0}};
+ DebugInfoValue low_pc = {{}};
/* enumerate abbrev */
for (;;) {
- DebugInfoValue v = {{0}};
- if (!di_read_record(reader, &v, errout)) break;
+ DebugInfoValue v = {{}};
+ if (!di_read_record(reader, &v)) break;
switch (v.at) {
case DW_AT_low_pc:
// clang may output DW_AT_addr_base after DW_AT_low_pc.
@@ -1826,19 +1784,19 @@ di_read_cu(DebugInfoReader *reader, FILE *errout)
break;
case VAL_addr:
{
- addr_header_t header = {0};
- if (!addr_header_init(reader->obj, &header, errout)) return -1;
+ addr_header_t header;
+ addr_header_init(reader->obj, &header);
reader->current_low_pc = read_addr(&header, reader->current_addr_base, low_pc.as.addr_idx);
}
break;
}
} while (0);
-
+#endif
return 0;
}
static void
-read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line, FILE *errout)
+read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line)
{
const char *p = reader->p;
const char *q = reader->q;
@@ -1863,12 +1821,12 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o
default:
goto finish;
}
- if (!di_read_die(reader, &die, errout)) goto finish;
+ if (!di_read_die(reader, &die)) goto finish;
/* enumerate abbrev */
for (;;) {
- DebugInfoValue v = {{0}};
- if (!di_read_record(reader, &v, errout)) break;
+ DebugInfoValue v = {{}};
+ if (!di_read_record(reader, &v)) break;
switch (v.at) {
case DW_AT_name:
line->sname = get_cstr_value(&v);
@@ -1882,44 +1840,43 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o
reader->level = level;
}
-static bool
+static void
debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
- line_info_t *lines, int offset, FILE *errout)
-{
+ line_info_t *lines, int offset) {
- addr_header_t addr_header = {0};
- if (!addr_header_init(reader->obj, &addr_header, errout)) return false;
+ addr_header_t addr_header = {};
+ addr_header_init(reader->obj, &addr_header);
- rnglists_header_t rnglists_header = {0};
- if (!rnglists_header_init(reader->obj, &rnglists_header, errout)) return false;
+ rnglists_header_t rnglists_header = {};
+ rnglists_header_init(reader->obj, &rnglists_header);
while (reader->p < reader->cu_end) {
DIE die;
- ranges_t ranges = {0};
- line_info_t line = {0};
+ ranges_t ranges = {};
+ line_info_t line = {};
- if (!di_read_die(reader, &die, errout)) continue;
- /* kprintf("%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */
+ if (!di_read_die(reader, &die)) continue;
+ /* fprintf(stderr,"%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */
if (die.tag != DW_TAG_subprogram && die.tag != DW_TAG_inlined_subroutine) {
skip_die:
- if (!di_skip_records(reader, errout)) return false;
+ di_skip_records(reader);
continue;
}
/* enumerate abbrev */
for (;;) {
- DebugInfoValue v = {{0}};
+ DebugInfoValue v = {{}};
/* ptrdiff_t pos = reader->p - reader->p0; */
- if (!di_read_record(reader, &v, errout)) break;
- /* kprintf("\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */
- /* div_inspect(&v, errout); */
+ if (!di_read_record(reader, &v)) break;
+ /* fprintf(stderr,"\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */
+ /* div_inspect(&v); */
switch (v.at) {
case DW_AT_name:
line.sname = get_cstr_value(&v);
break;
case DW_AT_call_file:
- fill_filename((int)v.as.uint64, reader->debug_line_format, reader->debug_line_version, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj, errout);
+ fill_filename((int)v.as.uint64, reader->debug_line_format, reader->debug_line_version, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
break;
case DW_AT_call_line:
line.line = (int)v.as.uint64;
@@ -1935,19 +1892,18 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
/* 1 or 3 */
break; /* goto skip_die; */
case DW_AT_abstract_origin:
- read_abstract_origin(reader, v.form, v.as.uint64, &line, errout);
+ read_abstract_origin(reader, v.form, v.as.uint64, &line);
break; /* goto skip_die; */
}
}
- /* ranges_inspect(reader, &ranges, errout); */
- /* kprintf("%d:%tx: %x ",__LINE__,diepos,die.tag); */
+ /* ranges_inspect(reader, &ranges); */
+ /* fprintf(stderr,"%d:%tx: %x ",__LINE__,diepos,die.tag); */
for (int i=offset; i < num_traces; i++) {
uintptr_t addr = (uintptr_t)traces[i];
uintptr_t offset = addr - reader->obj->base_addr + reader->obj->vmaddr;
- uintptr_t saddr = ranges_include(reader, &ranges, offset, &rnglists_header, errout);
- if (saddr == UINTPTR_MAX) return false;
+ uintptr_t saddr = ranges_include(reader, &ranges, offset, &rnglists_header);
if (saddr) {
- /* kprintf("%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
+ /* fprintf(stdout, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
if (lines[i].sname) {
line_info_t *lp = malloc(sizeof(line_info_t));
memcpy(lp, &lines[i], sizeof(line_info_t));
@@ -1964,7 +1920,6 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
}
}
}
- return true;
}
// This function parses the following attributes of Line Number Program Header in DWARF 5:
@@ -1983,10 +1938,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
//
// It records DW_LNCT_path and DW_LNCT_directory_index at the index "idx".
static const char *
-parse_ver5_debug_line_header(const char *p, int idx, uint8_t format,
- obj_info_t *obj, const char **out_path,
- uint64_t *out_directory_index, FILE *errout)
-{
+parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t *obj, const char **out_path, uint64_t *out_directory_index) {
int i, j;
int entry_format_count = *(uint8_t *)p++;
const char *entry_format = p;
@@ -1996,17 +1948,17 @@ parse_ver5_debug_line_header(const char *p, int idx, uint8_t format,
int entry_count = (int)uleb128(&p);
- DebugInfoReader reader = {0};
+ DebugInfoReader reader;
debug_info_reader_init(&reader, obj);
reader.format = format;
reader.p = p;
for (j = 0; j < entry_count; j++) {
const char *format = entry_format;
for (i = 0; i < entry_format_count; i++) {
- DebugInfoValue v = {{0}};
+ DebugInfoValue v = {{}};
unsigned long dw_lnct = uleb128(&format);
unsigned long dw_form = uleb128(&format);
- if (!debug_info_reader_read_value(&reader, dw_form, &v, errout)) return 0;
+ debug_info_reader_read_value(&reader, dw_form, &v);
if (dw_lnct == 1 /* DW_LNCT_path */ && v.type == VAL_cstr && out_path)
*out_path = v.as.ptr + v.off;
if (dw_lnct == 2 /* DW_LNCT_directory_index */ && v.type == VAL_uint && out_directory_index)
@@ -2051,7 +2003,7 @@ fail:
/* read file and fill lines */
static uintptr_t
fill_lines(int num_traces, void **traces, int check_debuglink,
- obj_info_t **objp, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t **objp, line_info_t *lines, int offset)
{
int i, j;
char *shstr;
@@ -2211,10 +2163,9 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
debug_info_reader_init(&reader, obj);
i = 0;
while (reader.p < reader.pend) {
- /* kprintf("%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */
- if (di_read_cu(&reader, errout)) goto use_symtab;
- if (!debug_info_read(&reader, num_traces, traces, lines, offset, errout))
- goto use_symtab;
+ /* fprintf(stderr, "%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */
+ if (di_read_cu(&reader)) goto use_symtab;
+ debug_info_read(&reader, num_traces, traces, lines, offset);
}
}
else {
@@ -2254,14 +2205,14 @@ use_symtab:
if (gnu_debuglink_shdr && check_debuglink) {
follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
num_traces, traces,
- objp, lines, offset, errout);
+ objp, lines, offset);
}
if (note_gnu_build_id && check_debuglink) {
ElfW(Nhdr) *nhdr = (ElfW(Nhdr)*) (file + note_gnu_build_id->sh_offset);
const char *build_id = (char *)(nhdr + 1) + nhdr->n_namesz;
follow_debuglink_build_id(build_id, nhdr->n_descsz,
num_traces, traces,
- objp, lines, offset, errout);
+ objp, lines, offset);
}
goto finish;
}
@@ -2269,7 +2220,7 @@ use_symtab:
if (parse_debug_line(num_traces, traces,
obj->debug_line.ptr,
obj->debug_line.size,
- obj, lines, offset, errout) == -1)
+ obj, lines, offset) == -1)
goto fail;
finish:
@@ -2281,7 +2232,7 @@ fail:
/* read file and fill lines */
static uintptr_t
fill_lines(int num_traces, void **traces, int check_debuglink,
- obj_info_t **objp, line_info_t *lines, int offset, FILE *errout)
+ obj_info_t **objp, line_info_t *lines, int offset)
{
# ifdef __LP64__
# define LP(x) x##_64
@@ -2360,13 +2311,13 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
struct fat_header *fat = (struct fat_header *)file;
char *q = file + sizeof(*fat);
uint32_t nfat_arch = __builtin_bswap32(fat->nfat_arch);
- /* kprintf("%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */
+ /* fprintf(stderr,"%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */
for (uint32_t i = 0; i < nfat_arch; i++) {
struct fat_arch *arch = (struct fat_arch *)q;
cpu_type_t cputype = __builtin_bswap32(arch->cputype);
cpu_subtype_t cpusubtype = __builtin_bswap32(arch->cpusubtype);
uint32_t offset = __builtin_bswap32(arch->offset);
- /* kprintf("%d: fat %d %x/%x %x/%x\n",__LINE__, i, mhp->cputype,mhp->cpusubtype, cputype,cpusubtype); */
+ /* fprintf(stderr,"%d: fat %d %x/%x %x/%x\n",__LINE__, i, mhp->cputype,mhp->cpusubtype, cputype,cpusubtype); */
if (mhp->cputype == cputype &&
(cpu_subtype_t)(mhp->cpusubtype & ~CPU_SUBTYPE_MASK) == cpusubtype) {
p = file + offset;
@@ -2482,16 +2433,15 @@ found_mach_header:
DebugInfoReader reader;
debug_info_reader_init(&reader, obj);
while (reader.p < reader.pend) {
- if (di_read_cu(&reader, errout)) goto fail;
- if (!debug_info_read(&reader, num_traces, traces, lines, offset, errout))
- goto fail;
+ if (di_read_cu(&reader)) goto fail;
+ debug_info_read(&reader, num_traces, traces, lines, offset);
}
}
if (parse_debug_line(num_traces, traces,
obj->debug_line.ptr,
obj->debug_line.size,
- obj, lines, offset, errout) == -1)
+ obj, lines, offset) == -1)
goto fail;
return dladdr_fbase;
@@ -2504,7 +2454,7 @@ fail:
#if defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/sysctl.h>
#endif
-/* ssize_t main_exe_path(FILE *errout)
+/* ssize_t main_exe_path(void)
*
* store the path of the main executable to `binary_filename`,
* and returns strlen(binary_filename).
@@ -2512,7 +2462,7 @@ fail:
*/
#if defined(__linux__) || defined(__NetBSD__)
static ssize_t
-main_exe_path(FILE *errout)
+main_exe_path(void)
{
# if defined(__linux__)
# define PROC_SELF_EXE "/proc/self/exe"
@@ -2526,7 +2476,7 @@ main_exe_path(FILE *errout)
}
#elif defined(__FreeBSD__) || defined(__DragonFly__)
static ssize_t
-main_exe_path(FILE *errout)
+main_exe_path(void)
{
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
size_t len = PATH_MAX;
@@ -2540,7 +2490,7 @@ main_exe_path(FILE *errout)
}
#elif defined(HAVE_LIBPROC_H)
static ssize_t
-main_exe_path(FILE *errout)
+main_exe_path(void)
{
int len = proc_pidpath(getpid(), binary_filename, PATH_MAX);
if (len == 0) return 0;
@@ -2552,7 +2502,7 @@ main_exe_path(FILE *errout)
#endif
static void
-print_line0(line_info_t *line, void *address, FILE *errout)
+print_line0(line_info_t *line, void *address)
{
uintptr_t addr = (uintptr_t)address;
uintptr_t d = addr - line->saddr;
@@ -2593,16 +2543,16 @@ print_line0(line_info_t *line, void *address, FILE *errout)
}
static void
-print_line(line_info_t *line, void *address, FILE *errout)
+print_line(line_info_t *line, void *address)
{
- print_line0(line, address, errout);
+ print_line0(line, address);
if (line->next) {
- print_line(line->next, NULL, errout);
+ print_line(line->next, NULL);
}
}
void
-rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout)
+rb_dump_backtrace_with_lines(int num_traces, void **traces)
{
int i;
/* async-signal unsafe */
@@ -2614,14 +2564,14 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout)
#ifdef HAVE_MAIN_EXE_PATH
char *main_path = NULL; /* used on printing backtrace */
ssize_t len;
- if ((len = main_exe_path(errout)) > 0) {
+ if ((len = main_exe_path()) > 0) {
main_path = (char *)alloca(len + 1);
if (main_path) {
uintptr_t addr;
memcpy(main_path, binary_filename, len+1);
append_obj(&obj);
obj->path = main_path;
- addr = fill_lines(num_traces, traces, 1, &obj, lines, -1, errout);
+ addr = fill_lines(num_traces, traces, 1, &obj, lines, -1);
if (addr != (uintptr_t)-1) {
dladdr_fbases[0] = (void *)addr;
}
@@ -2658,7 +2608,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout)
lines[i].saddr = (uintptr_t)info.dli_saddr;
}
strlcpy(binary_filename, path, PATH_MAX);
- if (fill_lines(num_traces, traces, 1, &obj, lines, i, errout) == (uintptr_t)-1)
+ if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
break;
}
next_line:
@@ -2667,7 +2617,7 @@ next_line:
/* output */
for (i = 0; i < num_traces; i++) {
- print_line(&lines[i], traces[i], errout);
+ print_line(&lines[i], traces[i]);
/* FreeBSD's backtrace may show _start and so on */
if (lines[i].sname && strcmp("main", lines[i].sname) == 0)
@@ -2701,8 +2651,435 @@ next_line:
free(dladdr_fbases);
}
-#undef kprintf
+/* From FreeBSD's lib/libstand/printf.c */
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include <stdarg.h>
+#define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
+static inline int toupper(int c) { return ('A' <= c && c <= 'Z') ? (c&0x5f) : c; }
+#define hex2ascii(hex) (hex2ascii_data[hex])
+static const char hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+static inline int imax(int a, int b) { return (a > b ? a : b); }
+static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
+
+static void putce(int c)
+{
+ char s[1];
+ ssize_t ret;
+
+ s[0] = (char)c;
+ ret = write(2, s, 1);
+ (void)ret;
+}
+
+static int
+kprintf(const char *fmt, ...)
+{
+ va_list ap;
+ int retval;
+ va_start(ap, fmt);
+ retval = kvprintf(fmt, putce, NULL, 10, ap);
+ va_end(ap);
+ return retval;
+}
+
+/*
+ * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
+ * order; return an optional length and a pointer to the last character
+ * written in the buffer (i.e., the first character of the string).
+ * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
+ */
+static char *
+ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
+{
+ char *p, c;
+
+ p = nbuf;
+ *p = '\0';
+ do {
+ c = hex2ascii(num % base);
+ *++p = upper ? toupper(c) : c;
+ } while (num /= base);
+ if (lenp)
+ *lenp = (int)(p - nbuf);
+ return (p);
+}
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * Two additional formats:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register. Thus:
+ *
+ * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ *
+ * would produce output:
+ *
+ * reg=3<BITTWO,BITONE>
+ *
+ * XXX: %D -- Hexdump, takes pointer and separator string:
+ * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
+ * ("%*D", len, ptr, " " -> XX XX XX XX ...
+ */
+static int
+kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
+{
+#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
+ char nbuf[MAXNBUF];
+ char *d;
+ const char *p, *percent, *q;
+ unsigned char *up;
+ int ch, n;
+ uintmax_t num;
+ int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+ int cflag, hflag, jflag, tflag, zflag;
+ int dwidth, upper;
+ char padc;
+ int stop = 0, retval = 0;
+
+ num = 0;
+ if (!func)
+ d = (char *) arg;
+ else
+ d = NULL;
+
+ if (fmt == NULL)
+ fmt = "(fmt null)\n";
+
+ if (radix < 2 || radix > 36)
+ radix = 10;
+
+ for (;;) {
+ padc = ' ';
+ width = 0;
+ while ((ch = (unsigned char)*fmt++) != '%' || stop) {
+ if (ch == '\0')
+ return (retval);
+ PCHAR(ch);
+ }
+ percent = fmt - 1;
+ qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+ sign = 0; dot = 0; dwidth = 0; upper = 0;
+ cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
+reswitch: switch (ch = (unsigned char)*fmt++) {
+ case '.':
+ dot = 1;
+ goto reswitch;
+ case '#':
+ sharpflag = 1;
+ goto reswitch;
+ case '+':
+ sign = 1;
+ goto reswitch;
+ case '-':
+ ladjust = 1;
+ goto reswitch;
+ case '%':
+ PCHAR(ch);
+ break;
+ case '*':
+ if (!dot) {
+ width = va_arg(ap, int);
+ if (width < 0) {
+ ladjust = !ladjust;
+ width = -width;
+ }
+ } else {
+ dwidth = va_arg(ap, int);
+ }
+ goto reswitch;
+ case '0':
+ if (!dot) {
+ padc = '0';
+ goto reswitch;
+ }
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ for (n = 0;; ++fmt) {
+ n = n * 10 + ch - '0';
+ ch = *fmt;
+ if (ch < '0' || ch > '9')
+ break;
+ }
+ if (dot)
+ dwidth = n;
+ else
+ width = n;
+ goto reswitch;
+ case 'b':
+ num = (unsigned int)va_arg(ap, int);
+ p = va_arg(ap, char *);
+ for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
+ PCHAR(*q--);
+
+ if (num == 0)
+ break;
+
+ for (tmp = 0; *p;) {
+ n = *p++;
+ if (num & (1 << (n - 1))) {
+ PCHAR(tmp ? ',' : '<');
+ for (; (n = *p) > ' '; ++p)
+ PCHAR(n);
+ tmp = 1;
+ } else
+ for (; *p > ' '; ++p)
+ continue;
+ }
+ if (tmp)
+ PCHAR('>');
+ break;
+ case 'c':
+ PCHAR(va_arg(ap, int));
+ break;
+ case 'D':
+ up = va_arg(ap, unsigned char *);
+ p = va_arg(ap, char *);
+ if (!width)
+ width = 16;
+ while(width--) {
+ PCHAR(hex2ascii(*up >> 4));
+ PCHAR(hex2ascii(*up & 0x0f));
+ up++;
+ if (width)
+ for (q=p;*q;q++)
+ PCHAR(*q);
+ }
+ break;
+ case 'd':
+ case 'i':
+ base = 10;
+ sign = 1;
+ goto handle_sign;
+ case 'h':
+ if (hflag) {
+ hflag = 0;
+ cflag = 1;
+ } else
+ hflag = 1;
+ goto reswitch;
+ case 'j':
+ jflag = 1;
+ goto reswitch;
+ case 'l':
+ if (lflag) {
+ lflag = 0;
+ qflag = 1;
+ } else
+ lflag = 1;
+ goto reswitch;
+ case 'n':
+ if (jflag)
+ *(va_arg(ap, intmax_t *)) = retval;
+ else if (qflag)
+ *(va_arg(ap, int64_t *)) = retval;
+ else if (lflag)
+ *(va_arg(ap, long *)) = retval;
+ else if (zflag)
+ *(va_arg(ap, size_t *)) = retval;
+ else if (hflag)
+ *(va_arg(ap, short *)) = retval;
+ else if (cflag)
+ *(va_arg(ap, char *)) = retval;
+ else
+ *(va_arg(ap, int *)) = retval;
+ break;
+ case 'o':
+ base = 8;
+ goto handle_nosign;
+ case 'p':
+ base = 16;
+ sharpflag = (width == 0);
+ sign = 0;
+ num = (uintptr_t)va_arg(ap, void *);
+ goto number;
+ case 'q':
+ qflag = 1;
+ goto reswitch;
+ case 'r':
+ base = radix;
+ if (sign)
+ goto handle_sign;
+ goto handle_nosign;
+ case 's':
+ p = va_arg(ap, char *);
+ if (p == NULL)
+ p = "(null)";
+ if (!dot)
+ n = (int)strlen (p);
+ else
+ for (n = 0; n < dwidth && p[n]; n++)
+ continue;
+
+ width -= n;
+
+ if (!ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ while (n--)
+ PCHAR(*p++);
+ if (ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ break;
+ case 't':
+ tflag = 1;
+ goto reswitch;
+ case 'u':
+ base = 10;
+ goto handle_nosign;
+ case 'X':
+ upper = 1;
+ case 'x':
+ base = 16;
+ goto handle_nosign;
+ case 'y':
+ base = 16;
+ sign = 1;
+ goto handle_sign;
+ case 'z':
+ zflag = 1;
+ goto reswitch;
+handle_nosign:
+ sign = 0;
+ if (jflag)
+ num = va_arg(ap, uintmax_t);
+ else if (qflag)
+ num = va_arg(ap, uint64_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, unsigned long);
+ else if (zflag)
+ num = va_arg(ap, size_t);
+ else if (hflag)
+ num = (unsigned short)va_arg(ap, int);
+ else if (cflag)
+ num = (unsigned char)va_arg(ap, int);
+ else
+ num = va_arg(ap, unsigned int);
+ goto number;
+handle_sign:
+ if (jflag)
+ num = va_arg(ap, intmax_t);
+ else if (qflag)
+ num = va_arg(ap, int64_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, long);
+ else if (zflag)
+ num = va_arg(ap, ssize_t);
+ else if (hflag)
+ num = (short)va_arg(ap, int);
+ else if (cflag)
+ num = (char)va_arg(ap, int);
+ else
+ num = va_arg(ap, int);
+number:
+ if (sign && (intmax_t)num < 0) {
+ neg = 1;
+ num = -(intmax_t)num;
+ }
+ p = ksprintn(nbuf, num, base, &n, upper);
+ tmp = 0;
+ if (sharpflag && num != 0) {
+ if (base == 8)
+ tmp++;
+ else if (base == 16)
+ tmp += 2;
+ }
+ if (neg)
+ tmp++;
+
+ if (!ladjust && padc == '0')
+ dwidth = width - tmp;
+ width -= tmp + imax(dwidth, n);
+ dwidth -= n;
+ if (!ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+ if (neg)
+ PCHAR('-');
+ if (sharpflag && num != 0) {
+ if (base == 8) {
+ PCHAR('0');
+ } else if (base == 16) {
+ PCHAR('0');
+ PCHAR('x');
+ }
+ }
+ while (dwidth-- > 0)
+ PCHAR('0');
+
+ while (*p)
+ PCHAR(*p--);
+
+ if (ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+
+ break;
+ default:
+ while (percent < fmt)
+ PCHAR(*percent++);
+ /*
+ * Since we ignore an formatting argument it is no
+ * longer safe to obey the remaining formatting
+ * arguments as the arguments will no longer match
+ * the format specs.
+ */
+ stop = 1;
+ break;
+ }
+ }
+#undef PCHAR
+}
#else /* defined(USE_ELF) */
#error not supported
#endif
diff --git a/addr2line.h b/addr2line.h
index ff8e476b92..f09b665800 100644
--- a/addr2line.h
+++ b/addr2line.h
@@ -12,10 +12,8 @@
#if (defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H))
-#include <stdio.h>
-
void
-rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout);
+rb_dump_backtrace_with_lines(int num_traces, void **traces);
#endif /* USE_ELF */
diff --git a/array.c b/array.c
index e1b8553568..b76e9a64a3 100644
--- a/array.c
+++ b/array.c
@@ -28,6 +28,7 @@
#include "ruby/encoding.h"
#include "ruby/st.h"
#include "ruby/util.h"
+#include "transient_heap.h"
#include "builtin.h"
#if !ARRAY_DEBUG
@@ -46,8 +47,13 @@ VALUE rb_cArray;
* 2: RARRAY_SHARED_FLAG (equal to ELTS_SHARED)
* The array is shared. The buffer this array points to is owned by
* another array (the shared root).
+ * if USE_RVARGC
* 3-9: RARRAY_EMBED_LEN
* The length of the array when RARRAY_EMBED_FLAG is set.
+ * else
+ * 3-4: RARRAY_EMBED_LEN
+ * The length of the array when RARRAY_EMBED_FLAG is set.
+ * endif
* 12: RARRAY_SHARED_ROOT_FLAG
* The array is a shared root that does reference counting. The buffer
* this array points to is owned by this array but may be pointed to
@@ -57,6 +63,8 @@ VALUE rb_cArray;
* they cannot be modified. Not updating the reference count
* improves copy-on-write performance. Their reference count is
* assumed to be infinity.
+ * 13: RARRAY_TRANSIENT_FLAG
+ * The buffer of the array is allocated on the transient heap.
* 14: RARRAY_PTR_IN_USE_FLAG
* The buffer of the array is in use. This is only used during
* debugging.
@@ -94,6 +102,7 @@ should_be_T_ARRAY(VALUE ary)
#define FL_SET_EMBED(a) do { \
assert(!ARY_SHARED_P(a)); \
FL_SET((a), RARRAY_EMBED_FLAG); \
+ RARY_TRANSIENT_UNSET(a); \
ary_verify(a); \
} while (0)
@@ -152,6 +161,16 @@ should_be_T_ARRAY(VALUE ary)
RARRAY(ary)->as.heap.aux.capa = (n); \
} while (0)
+#define ARY_SET_SHARED(ary, value) do { \
+ const VALUE _ary_ = (ary); \
+ const VALUE _value_ = (value); \
+ assert(!ARY_EMBED_P(_ary_)); \
+ assert(ARY_SHARED_P(_ary_)); \
+ assert(!OBJ_FROZEN(_ary_)); \
+ assert(ARY_SHARED_ROOT_P(_value_) || OBJ_FROZEN(_value_)); \
+ RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \
+} while (0)
+
#define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
assert(ARY_SHARED_ROOT_P(ary)); \
@@ -162,6 +181,7 @@ should_be_T_ARRAY(VALUE ary)
#define FL_SET_SHARED_ROOT(ary) do { \
assert(!OBJ_FROZEN(ary)); \
assert(!ARY_EMBED_P(ary)); \
+ assert(!RARRAY_TRANSIENT_P(ary)); \
FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
} while (0)
@@ -178,9 +198,13 @@ ARY_SET(VALUE a, long i, VALUE v)
static long
ary_embed_capa(VALUE ary)
{
+#if USE_RVARGC
size_t size = rb_gc_obj_slot_size(ary) - offsetof(struct RArray, as.ary);
assert(size % sizeof(VALUE) == 0);
return size / sizeof(VALUE);
+#else
+ return RARRAY_EMBED_LEN_MAX;
+#endif
}
static size_t
@@ -192,7 +216,11 @@ ary_embed_size(long capa)
static bool
ary_embeddable_p(long capa)
{
+#if USE_RVARGC
return rb_gc_size_allocatable_p(ary_embed_size(capa));
+#else
+ return capa <= RARRAY_EMBED_LEN_MAX;
+#endif
}
bool
@@ -238,18 +266,20 @@ ary_verify_(VALUE ary, const char *file, int line)
if (ARY_SHARED_P(ary)) {
VALUE root = ARY_SHARED_ROOT(ary);
const VALUE *ptr = ARY_HEAP_PTR(ary);
- const VALUE *root_ptr = RARRAY_CONST_PTR(root);
+ const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root);
long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root);
assert(ARY_SHARED_ROOT_P(root) || OBJ_FROZEN(root));
assert(root_ptr <= ptr && ptr + len <= root_ptr + root_len);
ary_verify(root);
}
else if (ARY_EMBED_P(ary)) {
+ assert(!RARRAY_TRANSIENT_P(ary));
assert(!ARY_SHARED_P(ary));
assert(RARRAY_LEN(ary) <= ary_embed_capa(ary));
}
else {
- const VALUE *ptr = RARRAY_CONST_PTR(ary);
+#if 1
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
long i, len = RARRAY_LEN(ary);
volatile VALUE v;
if (len > 1) len = 1; /* check only HEAD */
@@ -257,7 +287,16 @@ ary_verify_(VALUE ary, const char *file, int line)
v = ptr[i]; /* access check */
}
v = v;
+#endif
+ }
+
+#if USE_TRANSIENT_HEAP
+ if (RARRAY_TRANSIENT_P(ary)) {
+ assert(rb_transient_heap_managed_ptr_p(RARRAY_CONST_PTR_TRANSIENT(ary)));
}
+#endif
+
+ rb_transient_heap_verify();
return ary;
}
@@ -277,7 +316,7 @@ rb_ary_ptr_use_start(VALUE ary)
#if ARRAY_DEBUG
FL_SET_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
#endif
- return (VALUE *)RARRAY_CONST_PTR(ary);
+ return (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary);
}
void
@@ -299,7 +338,7 @@ rb_mem_clear(VALUE *mem, long size)
static void
ary_mem_clear(VALUE ary, long beg, long size)
{
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
rb_mem_clear(ptr + beg, size);
});
}
@@ -315,7 +354,7 @@ memfill(register VALUE *mem, register long size, register VALUE val)
static void
ary_memfill(VALUE ary, long beg, long size, VALUE val)
{
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
memfill(ptr + beg, size, val);
RB_OBJ_WRITTEN(ary, Qundef, val);
});
@@ -328,13 +367,13 @@ ary_memcpy0(VALUE ary, long beg, long argc, const VALUE *argv, VALUE buff_owner_
if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
rb_gc_writebarrier_remember(buff_owner_ary);
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMCPY(ptr+beg, argv, VALUE, argc);
});
}
else {
int i;
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
for (i=0; i<argc; i++) {
RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
}
@@ -349,46 +388,143 @@ ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv)
}
static VALUE *
-ary_heap_alloc(size_t capa)
+ary_heap_alloc(VALUE ary, size_t capa)
{
- return ALLOC_N(VALUE, capa);
+ VALUE *ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * capa);
+
+ if (ptr != NULL) {
+ RARY_TRANSIENT_SET(ary);
+ }
+ else {
+ RARY_TRANSIENT_UNSET(ary);
+ ptr = ALLOC_N(VALUE, capa);
+ }
+
+ return ptr;
}
static void
ary_heap_free_ptr(VALUE ary, const VALUE *ptr, long size)
{
- ruby_sized_xfree((void *)ptr, size);
+ if (RARRAY_TRANSIENT_P(ary)) {
+ /* ignore it */
+ }
+ else {
+ ruby_sized_xfree((void *)ptr, size);
+ }
}
static void
ary_heap_free(VALUE ary)
{
- ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
+ if (RARRAY_TRANSIENT_P(ary)) {
+ RARY_TRANSIENT_UNSET(ary);
+ }
+ else {
+ ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
+ }
}
static size_t
ary_heap_realloc(VALUE ary, size_t new_capa)
{
- SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, ARY_HEAP_CAPA(ary));
+ size_t alloc_capa = new_capa;
+ size_t old_capa = ARY_HEAP_CAPA(ary);
+
+ if (RARRAY_TRANSIENT_P(ary)) {
+ if (new_capa <= old_capa) {
+ /* do nothing */
+ alloc_capa = old_capa;
+ }
+ else {
+ VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa);
+
+ if (new_ptr == NULL) {
+ new_ptr = ALLOC_N(VALUE, new_capa);
+ RARY_TRANSIENT_UNSET(ary);
+ }
+
+ MEMCPY(new_ptr, ARY_HEAP_PTR(ary), VALUE, old_capa);
+ ARY_SET_PTR(ary, new_ptr);
+ }
+ }
+ else {
+ SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa);
+ }
+ ary_verify(ary);
+
+ return alloc_capa;
+}
+
+#if USE_TRANSIENT_HEAP
+static inline void
+rb_ary_transient_heap_evacuate_(VALUE ary, int transient, int promote)
+{
+ if (transient) {
+ assert(!ARY_SHARED_ROOT_P(ary));
+
+ VALUE *new_ptr;
+ const VALUE *old_ptr = ARY_HEAP_PTR(ary);
+ long capa = ARY_HEAP_CAPA(ary);
+
+ assert(ARY_OWNS_HEAP_P(ary));
+ assert(RARRAY_TRANSIENT_P(ary));
+ assert(!ARY_PTR_USING_P(ary));
+
+ if (promote) {
+ new_ptr = ALLOC_N(VALUE, capa);
+ RARY_TRANSIENT_UNSET(ary);
+ }
+ else {
+ new_ptr = ary_heap_alloc(ary, capa);
+ }
+
+ MEMCPY(new_ptr, old_ptr, VALUE, capa);
+ /* do not use ARY_SET_PTR() because they assert !frozen */
+ RARRAY(ary)->as.heap.ptr = new_ptr;
+ }
+
ary_verify(ary);
+}
- return new_capa;
+void
+rb_ary_transient_heap_evacuate(VALUE ary, int promote)
+{
+ rb_ary_transient_heap_evacuate_(ary, RARRAY_TRANSIENT_P(ary), promote);
}
void
+rb_ary_detransient(VALUE ary)
+{
+ assert(RARRAY_TRANSIENT_P(ary));
+ rb_ary_transient_heap_evacuate_(ary, TRUE, TRUE);
+}
+#else
+void
+rb_ary_detransient(VALUE ary)
+{
+ /* do nothing */
+}
+#endif
+
+void
rb_ary_make_embedded(VALUE ary)
{
assert(rb_ary_embeddable_p(ary));
if (!ARY_EMBED_P(ary)) {
const VALUE *buf = ARY_HEAP_PTR(ary);
long len = ARY_HEAP_LEN(ary);
+ bool was_transient = RARRAY_TRANSIENT_P(ary);
+ // FL_SET_EMBED also unsets the transient flag
FL_SET_EMBED(ary);
ARY_SET_EMBED_LEN(ary, len);
MEMCPY((void *)ARY_EMBED_PTR(ary), (void *)buf, VALUE, len);
- ary_heap_free_ptr(ary, buf, len * sizeof(VALUE));
+ if (!was_transient) {
+ ary_heap_free_ptr(ary, buf, len * sizeof(VALUE));
+ }
}
}
@@ -403,7 +539,7 @@ ary_resize_capa(VALUE ary, long capacity)
size_t new_capa = capacity;
if (ARY_EMBED_P(ary)) {
long len = ARY_EMBED_LEN(ary);
- VALUE *ptr = ary_heap_alloc(capacity);
+ VALUE *ptr = ary_heap_alloc(ary, capacity);
MEMCPY(ptr, ARY_EMBED_PTR(ary), VALUE, len);
FL_UNSET_EMBED(ary);
@@ -507,15 +643,10 @@ rb_ary_increment_share(VALUE shared_root)
static void
rb_ary_set_shared(VALUE ary, VALUE shared_root)
{
- assert(!ARY_EMBED_P(ary));
- assert(!OBJ_FROZEN(ary));
- assert(ARY_SHARED_ROOT_P(shared_root) || OBJ_FROZEN(shared_root));
-
rb_ary_increment_share(shared_root);
FL_SET_SHARED(ary);
- RB_OBJ_WRITE(ary, &RARRAY(ary)->as.heap.aux.shared_root, shared_root);
-
RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
+ ARY_SET_SHARED(ary, shared_root);
}
static inline void
@@ -543,18 +674,18 @@ rb_ary_cancel_sharing(VALUE ary)
ARY_SET_EMBED_LEN(ary, len);
}
else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) {
- long shift = RARRAY_CONST_PTR(ary) - RARRAY_CONST_PTR(shared_root);
+ long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root);
FL_UNSET_SHARED(ary);
- ARY_SET_PTR(ary, RARRAY_CONST_PTR(shared_root));
+ ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared_root));
ARY_SET_CAPA(ary, shared_len);
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr, ptr+shift, VALUE, len);
});
FL_SET_EMBED(shared_root);
rb_ary_decrement_share(shared_root);
}
else {
- VALUE *ptr = ary_heap_alloc(len);
+ VALUE *ptr = ary_heap_alloc(ary, len);
MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
rb_ary_unshare(ary);
ARY_SET_CAPA(ary, len);
@@ -587,7 +718,7 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
if (new_len > ary_embed_capa(ary)) {
VALUE shared_root = ARY_SHARED_ROOT(ary);
if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
- if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
+ if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
rb_ary_modify_check(ary);
ary_verify(ary);
@@ -665,9 +796,12 @@ ary_alloc_embed(VALUE klass, long capa)
{
size_t size = ary_embed_size(capa);
assert(rb_gc_size_allocatable_p(size));
- NEWOBJ_OF(ary, struct RArray, klass,
+#if !USE_RVARGC
+ assert(size <= sizeof(struct RArray));
+#endif
+ RVARGC_NEWOBJ_OF(ary, struct RArray, klass,
T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
- size, 0);
+ size);
/* Created array is:
* FL_SET_EMBED((VALUE)ary);
* ARY_SET_EMBED_LEN((VALUE)ary, 0);
@@ -678,9 +812,9 @@ ary_alloc_embed(VALUE klass, long capa)
static VALUE
ary_alloc_heap(VALUE klass)
{
- NEWOBJ_OF(ary, struct RArray, klass,
+ RVARGC_NEWOBJ_OF(ary, struct RArray, klass,
T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
- sizeof(struct RArray), 0);
+ sizeof(struct RArray));
return (VALUE)ary;
}
@@ -694,7 +828,7 @@ empty_ary_alloc(VALUE klass)
static VALUE
ary_new(VALUE klass, long capa)
{
- VALUE ary;
+ VALUE ary,*ptr;
if (capa < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
@@ -713,7 +847,8 @@ ary_new(VALUE klass, long capa)
ARY_SET_CAPA(ary, capa);
assert(!ARY_EMBED_P(ary));
- ARY_SET_PTR(ary, ary_heap_alloc(capa));
+ ptr = ary_heap_alloc(ary, capa);
+ ARY_SET_PTR(ary, ptr);
ARY_SET_HEAP_LEN(ary, 0);
}
@@ -751,7 +886,7 @@ VALUE
return ary;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
{
VALUE ary;
@@ -776,9 +911,12 @@ ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa)
{
size_t size = ary_embed_size(capa);
assert(rb_gc_size_allocatable_p(size));
- NEWOBJ_OF(ary, struct RArray, klass,
- T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
- size, ec);
+#if !USE_RVARGC
+ assert(size <= sizeof(struct RArray));
+#endif
+ RB_RVARGC_EC_NEWOBJ_OF(ec, ary, struct RArray, klass,
+ T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
+ size);
/* Created array is:
* FL_SET_EMBED((VALUE)ary);
* ARY_SET_EMBED_LEN((VALUE)ary, 0);
@@ -789,16 +927,16 @@ ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa)
static VALUE
ec_ary_alloc_heap(rb_execution_context_t *ec, VALUE klass)
{
- NEWOBJ_OF(ary, struct RArray, klass,
- T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
- sizeof(struct RArray), ec);
+ RB_RVARGC_EC_NEWOBJ_OF(ec, ary, struct RArray, klass,
+ T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
+ sizeof(struct RArray));
return (VALUE)ary;
}
static VALUE
ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa)
{
- VALUE ary;
+ VALUE ary,*ptr;
if (capa < 0) {
rb_raise(rb_eArgError, "negative array size (or size too big)");
@@ -817,7 +955,8 @@ ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa)
ARY_SET_CAPA(ary, capa);
assert(!ARY_EMBED_P(ary));
- ARY_SET_PTR(ary, ary_heap_alloc(capa));
+ ptr = ary_heap_alloc(ary, capa);
+ ARY_SET_PTR(ary, ptr);
ARY_SET_HEAP_LEN(ary, 0);
}
@@ -842,6 +981,7 @@ VALUE
rb_ary_hidden_new(long capa)
{
VALUE ary = ary_new(0, capa);
+ rb_ary_transient_heap_evacuate(ary, TRUE);
return ary;
}
@@ -864,8 +1004,13 @@ rb_ary_free(VALUE ary)
RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
}
- RB_DEBUG_COUNTER_INC(obj_ary_ptr);
- ary_heap_free(ary);
+ if (RARRAY_TRANSIENT_P(ary)) {
+ RB_DEBUG_COUNTER_INC(obj_ary_transient);
+ }
+ else {
+ RB_DEBUG_COUNTER_INC(obj_ary_ptr);
+ ary_heap_free(ary);
+ }
}
else {
RB_DEBUG_COUNTER_INC(obj_ary_embed);
@@ -893,6 +1038,7 @@ rb_ary_memsize(VALUE ary)
static VALUE
ary_make_shared(VALUE ary)
{
+ assert(USE_RVARGC || !ARY_EMBED_P(ary));
ary_verify(ary);
if (ARY_SHARED_P(ary)) {
@@ -903,11 +1049,14 @@ ary_make_shared(VALUE ary)
}
else if (OBJ_FROZEN(ary)) {
if (!ARY_EMBED_P(ary)) {
+ rb_ary_transient_heap_evacuate(ary, TRUE);
ary_shrink_capa(ary);
}
return ary;
}
else {
+ rb_ary_transient_heap_evacuate(ary, TRUE);
+
long capa = ARY_CAPA(ary);
long len = RARRAY_LEN(ary);
@@ -917,21 +1066,26 @@ ary_make_shared(VALUE ary)
FL_SET_SHARED_ROOT(shared);
if (ARY_EMBED_P(ary)) {
- VALUE *ptr = ary_heap_alloc(capa);
+ /* Cannot use ary_heap_alloc because we don't want to allocate
+ * on the transient heap. */
+ VALUE *ptr = ALLOC_N(VALUE, capa);
ARY_SET_PTR(shared, ptr);
- ary_memcpy(shared, 0, len, RARRAY_CONST_PTR(ary));
+ ary_memcpy(shared, 0, len, RARRAY_PTR(ary));
FL_UNSET_EMBED(ary);
ARY_SET_HEAP_LEN(ary, len);
ARY_SET_PTR(ary, ptr);
}
else {
- ARY_SET_PTR(shared, RARRAY_CONST_PTR(ary));
+ ARY_SET_PTR(shared, RARRAY_PTR(ary));
}
ARY_SET_LEN(shared, capa);
ary_mem_clear(shared, len, capa - len);
- rb_ary_set_shared(ary, shared);
+ ARY_SET_SHARED_ROOT_REFCNT(shared, 1);
+ FL_SET_SHARED(ary);
+ RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
+ ARY_SET_SHARED(ary, shared);
ary_verify(shared);
ary_verify(ary);
@@ -949,7 +1103,7 @@ ary_make_substitution(VALUE ary)
VALUE subst = rb_ary_new_capa(len);
assert(ARY_EMBED_P(subst));
- ary_memcpy(subst, 0, len, RARRAY_CONST_PTR(ary));
+ ary_memcpy(subst, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_EMBED_LEN(subst, len);
return subst;
}
@@ -977,7 +1131,7 @@ rb_check_array_type(VALUE ary)
return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_check_to_array(VALUE ary)
{
return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
@@ -1052,7 +1206,7 @@ rb_ary_s_new(int argc, VALUE *argv, VALUE klass)
* a.class # => Array
* a # => [:foo, "bar", 2]
*
- * With no block and a single Integer argument +size+,
+ * With no block and a single \Integer argument +size+,
* returns a new \Array of the given size
* whose elements are all +nil+:
*
@@ -1192,22 +1346,21 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
assert(len >= 0);
assert(offset+len <= RARRAY_LEN(ary));
- VALUE result = ary_alloc_heap(klass);
- size_t embed_capa = ary_embed_capa(result);
- if ((size_t)len <= embed_capa) {
- FL_SET_EMBED(result);
- ary_memcpy(result, 0, len, RARRAY_CONST_PTR(ary) + offset);
+ const size_t rarray_embed_capa_max = (sizeof(struct RArray) - offsetof(struct RArray, as.ary)) / sizeof(VALUE);
+
+ if ((size_t)len <= rarray_embed_capa_max && ary_embeddable_p(len)) {
+ VALUE result = ary_alloc_embed(klass, len);
+ ary_memcpy(result, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary) + offset);
ARY_SET_EMBED_LEN(result, len);
+ return result;
}
else {
VALUE shared = ary_make_shared(ary);
- /* The ary_make_shared call may allocate, which can trigger a GC
- * compaction. This can cause the array to be embedded because it has
- * a length of 0. */
- FL_UNSET_EMBED(result);
+ VALUE result = ary_alloc_heap(klass);
+ assert(!ARY_EMBED_P(result));
- ARY_SET_PTR(result, RARRAY_CONST_PTR(ary));
+ ARY_SET_PTR(result, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_LEN(result, RARRAY_LEN(ary));
rb_ary_set_shared(result, shared);
@@ -1215,10 +1368,9 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
ARY_SET_LEN(result, len);
ary_verify(shared);
+ ary_verify(result);
+ return result;
}
-
- ary_verify(result);
- return result;
}
static VALUE
@@ -1229,13 +1381,12 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
assert(offset+len <= RARRAY_LEN(ary));
assert(step != 0);
+ const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary);
const long orig_len = len;
if (step > 0 && step >= len) {
VALUE result = ary_new(klass, 1);
VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
- const VALUE *values = RARRAY_CONST_PTR(ary);
-
RB_OBJ_WRITE(result, ptr, values[offset]);
ARY_SET_EMBED_LEN(result, 1);
return result;
@@ -1253,8 +1404,6 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
VALUE result = ary_new(klass, len);
if (ARY_EMBED_P(result)) {
VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
- const VALUE *values = RARRAY_CONST_PTR(ary);
-
for (i = 0; i < len; ++i) {
RB_OBJ_WRITE(result, ptr+i, values[j]);
j += step;
@@ -1262,9 +1411,7 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
ARY_SET_EMBED_LEN(result, len);
}
else {
- const VALUE *values = RARRAY_CONST_PTR(ary);
-
- RARRAY_PTR_USE(result, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(result, ptr, {
for (i = 0; i < len; ++i) {
RB_OBJ_WRITE(result, ptr+i, values[j]);
j += step;
@@ -1289,11 +1436,20 @@ enum ary_take_pos_flags
};
static VALUE
-ary_take_first_or_last_n(VALUE ary, long n, enum ary_take_pos_flags last)
+ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
{
- long len = RARRAY_LEN(ary);
+ long n;
+ long len;
long offset = 0;
+ argc = rb_check_arity(argc, 0, 1);
+ /* the case optional argument is omitted should be handled in
+ * callers of this function. if another arity case is added,
+ * this arity check needs to rewrite. */
+ RUBY_ASSERT_ALWAYS(argc == 1);
+
+ n = NUM2LONG(argv[0]);
+ len = RARRAY_LEN(ary);
if (n > len) {
n = len;
}
@@ -1306,17 +1462,6 @@ ary_take_first_or_last_n(VALUE ary, long n, enum ary_take_pos_flags last)
return ary_make_partial(ary, rb_cArray, offset, n);
}
-static VALUE
-ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
-{
- argc = rb_check_arity(argc, 0, 1);
- /* the case optional argument is omitted should be handled in
- * callers of this function. if another arity case is added,
- * this arity check needs to rewrite. */
- RUBY_ASSERT_ALWAYS(argc == 1);
- return ary_take_first_or_last_n(ary, NUM2LONG(argv[0]), last);
-}
-
/*
* call-seq:
* array << object -> self
@@ -1339,7 +1484,7 @@ rb_ary_push(VALUE ary, VALUE item)
{
long idx = RARRAY_LEN((ary_verify(ary), ary));
VALUE target_ary = ary_ensure_room_for_push(ary, 1);
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
RB_OBJ_WRITE(target_ary, &ptr[idx], item);
});
ARY_SET_LEN(ary, idx + 1);
@@ -1374,6 +1519,8 @@ rb_ary_cat(VALUE ary, const VALUE *argv, long len)
* a1 = a.push([:baz, :bat], [:bam, :bad])
* a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]
*
+ * Array#append is an alias for Array#push.
+ *
* Related: #pop, #shift, #unshift.
*/
@@ -1418,7 +1565,7 @@ rb_ary_pop(VALUE ary)
*
* Returns +nil+ if the array is empty.
*
- * When a non-negative Integer argument +n+ is given and is in range,
+ * When a non-negative \Integer argument +n+ is given and is in range,
*
* removes and returns the last +n+ elements in a new \Array:
* a = [:foo, 'bar', 2]
@@ -1482,7 +1629,7 @@ rb_ary_shift(VALUE ary)
*
* Returns +nil+ if +self+ is empty.
*
- * When positive Integer argument +n+ is given, removes the first +n+ elements;
+ * When positive \Integer argument +n+ is given, removes the first +n+ elements;
* returns those elements in a new \Array:
*
* a = [:foo, 'bar', 2]
@@ -1518,7 +1665,7 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
return result;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_ary_behead(VALUE ary, long n)
{
if (n <= 0) {
@@ -1529,7 +1676,7 @@ rb_ary_behead(VALUE ary, long n)
if (!ARY_SHARED_P(ary)) {
if (ARY_EMBED_P(ary) || RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr, ptr + n, VALUE, RARRAY_LEN(ary) - n);
}); /* WB: no new reference */
ARY_INCREASE_LEN(ary, -n);
@@ -1590,12 +1737,12 @@ ary_modify_for_unshift(VALUE ary, int argc)
capa = ARY_CAPA(ary);
ary_make_shared(ary);
- head = sharedp = RARRAY_CONST_PTR(ary);
+ head = sharedp = RARRAY_CONST_PTR_TRANSIENT(ary);
return make_room_for_unshift(ary, head, (void *)sharedp, argc, capa, len);
}
else {
/* sliding items */
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr + argc, ptr, VALUE, len);
});
@@ -1627,8 +1774,8 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
return ary_modify_for_unshift(ary, argc);
}
else {
- const VALUE * head = RARRAY_CONST_PTR(ary);
- void *sharedp = (void *)RARRAY_CONST_PTR(shared_root);
+ const VALUE * head = RARRAY_CONST_PTR_TRANSIENT(ary);
+ void *sharedp = (void *)RARRAY_CONST_PTR_TRANSIENT(shared_root);
rb_ary_modify_check(ary);
return make_room_for_unshift(ary, head, sharedp, argc, capa, len);
@@ -1645,10 +1792,12 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
* a = [:foo, 'bar', 2]
* a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]
*
+ * Array#prepend is an alias for Array#unshift.
+ *
* Related: #push, #pop, #shift.
*/
-VALUE
+static VALUE
rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
{
long len = RARRAY_LEN(ary);
@@ -1668,7 +1817,7 @@ rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
VALUE
rb_ary_unshift(VALUE ary, VALUE item)
{
- return rb_ary_unshift_m(1, &item, ary);
+ return rb_ary_unshift_m(1,&item,ary);
}
/* faster version - use this if you don't need to treat negative offset */
@@ -1732,7 +1881,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* Returns elements from +self+; does not modify +self+.
*
- * When a single Integer argument +index+ is given, returns the element at offset +index+:
+ * When a single \Integer argument +index+ is given, returns the element at offset +index+:
*
* a = [:foo, 'bar', 2]
* a[0] # => :foo
@@ -1747,7 +1896,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* If +index+ is out of range, returns +nil+.
*
- * When two Integer arguments +start+ and +length+ are given,
+ * When two \Integer arguments +start+ and +length+ are given,
* returns a new \Array of size +length+ containing successive elements beginning at offset +start+:
*
* a = [:foo, 'bar', 2]
@@ -1767,7 +1916,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* If +length+ is negative, returns +nil+.
*
- * When a single Range argument +range+ is given,
+ * When a single \Range argument +range+ is given,
* treats <tt>range.min</tt> as +start+ above
* and <tt>range.size</tt> as +length+ above:
*
@@ -1821,6 +1970,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
* # Raises TypeError (no implicit conversion of Symbol into Integer):
* a[:foo]
*
+ * Array#slice is an alias for Array#[].
*/
VALUE
@@ -1844,7 +1994,7 @@ rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
return rb_ary_subseq(ary, beg, len);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_ary_aref1(VALUE ary, VALUE arg)
{
long beg, len, step;
@@ -1870,7 +2020,7 @@ rb_ary_aref1(VALUE ary, VALUE arg)
* call-seq:
* array.at(index) -> object
*
- * Returns the element at Integer offset +index+; does not modify +self+.
+ * Returns the element at \Integer offset +index+; does not modify +self+.
* a = [:foo, 'bar', 2]
* a.at(0) # => :foo
* a.at(2) # => 2
@@ -1883,7 +2033,39 @@ rb_ary_at(VALUE ary, VALUE pos)
return rb_ary_entry(ary, NUM2LONG(pos));
}
-#if 0
+/*
+ * call-seq:
+ * array.first -> object or nil
+ * array.first(n) -> new_array
+ *
+ * Returns elements from +self+; does not modify +self+.
+ *
+ * When no argument is given, returns the first element:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.first # => :foo
+ * a # => [:foo, "bar", 2]
+ *
+ * If +self+ is empty, returns +nil+.
+ *
+ * When non-negative \Integer argument +n+ is given,
+ * returns the first +n+ elements in a new \Array:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.first(2) # => [:foo, "bar"]
+ *
+ * If <tt>n >= array.size</tt>, returns all elements:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.first(50) # => [:foo, "bar", 2]
+ *
+ * If <tt>n == 0</tt> returns an new empty \Array:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.first(0) # []
+ *
+ * Related: #last.
+ */
static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
@@ -1895,26 +2077,48 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary)
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
}
}
-#endif
-
-static VALUE
-ary_first(VALUE self)
-{
- return (RARRAY_LEN(self) == 0) ? Qnil : RARRAY_AREF(self, 0);
-}
-static VALUE
-ary_last(VALUE self)
-{
- long len = RARRAY_LEN(self);
- return (len == 0) ? Qnil : RARRAY_AREF(self, len-1);
-}
+/*
+ * call-seq:
+ * array.last -> object or nil
+ * array.last(n) -> new_array
+ *
+ * Returns elements from +self+; +self+ is not modified.
+ *
+ * When no argument is given, returns the last element:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.last # => 2
+ * a # => [:foo, "bar", 2]
+ *
+ * If +self+ is empty, returns +nil+.
+ *
+ * When non-negative \Integer argument +n+ is given,
+ * returns the last +n+ elements in a new \Array:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.last(2) # => ["bar", 2]
+ *
+ * If <tt>n >= array.size</tt>, returns all elements:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.last(50) # => [:foo, "bar", 2]
+ *
+ * If <tt>n == 0</tt>, returns an new empty \Array:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.last(0) # []
+ *
+ * Related: #first.
+ */
VALUE
-rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y
+rb_ary_last(int argc, const VALUE *argv, VALUE ary)
{
if (argc == 0) {
- return ary_last(ary);
+ long len = RARRAY_LEN(ary);
+ if (len == 0) return Qnil;
+ return RARRAY_AREF(ary, len-1);
}
else {
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
@@ -1929,7 +2133,7 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y
*
* Returns the element at offset +index+.
*
- * With the single Integer argument +index+,
+ * With the single \Integer argument +index+,
* returns the element at offset +index+:
*
* a = [:foo, 'bar', 2]
@@ -2019,6 +2223,8 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
* e # => #<Enumerator: [:foo, "bar", 2]:index>
* e.each {|element| element == 'bar' } # => 1
*
+ * Array#find_index is an alias for Array#index.
+ *
* Related: #rindex.
*/
@@ -2073,7 +2279,7 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
*
* Returns +nil+ if the block never returns a truthy value.
*
- * When neither an argument nor a block is given, returns a new Enumerator:
+ * When neither an argument nor a block is given, returns a new \Enumerator:
*
* a = [:foo, 'bar', 2, 'bar']
* e = a.rindex
@@ -2145,7 +2351,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
}
{
- const VALUE *optr = RARRAY_CONST_PTR(ary);
+ const VALUE *optr = RARRAY_CONST_PTR_TRANSIENT(ary);
rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
}
@@ -2158,7 +2364,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
len = beg + rlen;
ary_mem_clear(ary, olen, beg - olen);
if (rlen > 0) {
- if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs;
+ if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
ary_memcpy0(ary, beg, rlen, rptr, target_ary);
}
ARY_SET_LEN(ary, len);
@@ -2176,25 +2382,20 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
}
if (len != rlen) {
- RARRAY_PTR_USE(ary, ptr,
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
MEMMOVE(ptr + beg + rlen, ptr + beg + len,
VALUE, olen - (beg + len)));
ARY_SET_LEN(ary, alen);
}
if (rlen > 0) {
- if (rofs == -1) {
- rb_gc_writebarrier_remember(ary);
- }
- else {
- /* In this case, we're copying from a region in this array, so
- * we don't need to fire the write barrier. */
- rptr = RARRAY_CONST_PTR(ary) + rofs;
- }
+ if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
+ /* give up wb-protected ary */
+ RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
/* do not use RARRAY_PTR() because it can causes GC.
* ary can contain T_NONE object because it is not cleared.
*/
- RARRAY_PTR_USE(ary, ptr,
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
MEMMOVE(ptr + beg, rptr, VALUE, rlen));
}
}
@@ -2239,8 +2440,9 @@ rb_ary_resize(VALUE ary, long len)
else if (len <= ary_embed_capa(ary)) {
const VALUE *ptr = ARY_HEAP_PTR(ary);
long ptr_capa = ARY_HEAP_SIZE(ary);
- bool is_malloc_ptr = !ARY_SHARED_P(ary);
+ bool is_malloc_ptr = !ARY_SHARED_P(ary) && !RARRAY_TRANSIENT_P(ary);
+ FL_UNSET(ary, RARRAY_TRANSIENT_FLAG);
FL_SET_EMBED(ary);
MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len); /* WB: no new reference */
@@ -2270,7 +2472,7 @@ static VALUE
ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
{
VALUE rpl = rb_ary_to_ary(val);
- rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR(rpl), RARRAY_LEN(rpl));
+ rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR_TRANSIENT(rpl), RARRAY_LEN(rpl));
RB_GC_GUARD(rpl);
return val;
}
@@ -2283,7 +2485,7 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
*
* Assigns elements in +self+; returns the given +object+.
*
- * When Integer argument +index+ is given, assigns +object+ to an element in +self+.
+ * When \Integer argument +index+ is given, assigns +object+ to an element in +self+.
*
* If +index+ is non-negative, assigns +object+ the element at offset +index+:
*
@@ -2303,7 +2505,7 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
* a[-1] = 'two' # => "two"
* a # => [:foo, "bar", "two"]
*
- * When Integer arguments +start+ and +length+ are given and +object+ is not an \Array,
+ * When \Integer arguments +start+ and +length+ are given and +object+ is not an \Array,
* removes <tt>length - 1</tt> elements beginning at offset +start+,
* and assigns +object+ at offset +start+:
*
@@ -2338,7 +2540,7 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
* a[1, 5] = 'foo' # => "foo"
* a # => [:foo, "foo"]
*
- * When Range argument +range+ is given and +object+ is an \Array,
+ * When \Range argument +range+ is given and +object+ is an \Array,
* removes <tt>length - 1</tt> elements beginning at offset +start+,
* and assigns +object+ at offset +start+:
*
@@ -2418,7 +2620,7 @@ rb_ary_aset(int argc, VALUE *argv, VALUE ary)
* call-seq:
* array.insert(index, *objects) -> self
*
- * Inserts given +objects+ before or after the element at Integer index +offset+;
+ * Inserts given +objects+ before or after the element at \Integer index +offset+;
* returns +self+.
*
* When +index+ is non-negative, inserts all given +objects+
@@ -2512,7 +2714,7 @@ ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
* foo
* bar
*
- * When no block given, returns a new Enumerator:
+ * When no block given, returns a new \Enumerator:
* a = [:foo, 'bar', 2]
*
* e = a.each
@@ -2569,7 +2771,7 @@ rb_ary_each(VALUE ary)
* 0
* 1
*
- * When no block given, returns a new Enumerator:
+ * When no block given, returns a new \Enumerator:
*
* a = [:foo, 'bar', 2]
* e = a.each_index
@@ -2626,7 +2828,7 @@ rb_ary_each_index(VALUE ary)
* 2
* bar
*
- * When no block given, returns a new Enumerator:
+ * When no block given, returns a new \Enumerator:
*
* a = [:foo, 'bar', 2]
* e = a.reverse_each
@@ -2693,7 +2895,7 @@ rb_ary_dup(VALUE ary)
{
long len = RARRAY_LEN(ary);
VALUE dup = rb_ary_new2(len);
- ary_memcpy(dup, 0, len, RARRAY_CONST_PTR(ary));
+ ary_memcpy(dup, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_LEN(dup, len);
ary_verify(ary);
@@ -2846,7 +3048,7 @@ rb_ary_join(VALUE ary, VALUE sep)
* array.join ->new_string
* array.join(separator = $,) -> new_string
*
- * Returns the new String formed by joining the array elements after conversion.
+ * Returns the new \String formed by joining the array elements after conversion.
* For each element +element+:
*
* - Uses <tt>element.to_s</tt> if +element+ is not a <tt>kind_of?(Array)</tt>.
@@ -2906,12 +3108,13 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
* call-seq:
* array.inspect -> new_string
*
- * Returns the new String formed by calling method <tt>#inspect</tt>
+ * Returns the new \String formed by calling method <tt>#inspect</tt>
* on each array element:
*
* a = [:foo, 'bar', 2]
* a.inspect # => "[:foo, \"bar\", 2]"
*
+ * Array#to_s is an alias for Array#inspect.
*/
static VALUE
@@ -2964,18 +3167,18 @@ rb_ary_to_a(VALUE ary)
* array.to_h -> new_hash
* array.to_h {|item| ... } -> new_hash
*
- * Returns a new Hash formed from +self+.
+ * Returns a new \Hash formed from +self+.
*
* When a block is given, calls the block with each array element;
* the block must return a 2-element \Array whose two elements
- * form a key-value pair in the returned Hash:
+ * form a key-value pair in the returned \Hash:
*
* a = ['foo', :bar, 1, [2, 3], {baz: 4}]
* h = a.to_h {|item| [item, item] }
* h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}}
*
* When no block is given, +self+ must be an \Array of 2-element sub-arrays,
- * each sub-array is formed into a key-value pair in the new Hash:
+ * each sub-array is formed into a key-value pair in the new \Hash:
*
* [].to_h # => {}
* a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
@@ -3039,7 +3242,7 @@ rb_ary_reverse(VALUE ary)
rb_ary_modify(ary);
if (len > 1) {
- RARRAY_PTR_USE(ary, p1, {
+ RARRAY_PTR_USE_TRANSIENT(ary, p1, {
p2 = p1 + len - 1; /* points last item */
ary_reverse(p1, p2);
}); /* WB: no new reference */
@@ -3083,8 +3286,8 @@ rb_ary_reverse_m(VALUE ary)
VALUE dup = rb_ary_new2(len);
if (len > 0) {
- const VALUE *p1 = RARRAY_CONST_PTR(ary);
- VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
+ const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
+ VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
@@ -3126,7 +3329,7 @@ rb_ary_rotate(VALUE ary, long cnt)
if (cnt != 0) {
long len = RARRAY_LEN(ary);
if (len > 1 && (cnt = rotate_count(cnt, len)) > 0) {
- RARRAY_PTR_USE(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
return ary;
}
}
@@ -3145,7 +3348,7 @@ rb_ary_rotate(VALUE ary, long cnt)
* a = [:foo, 'bar', 2, 'bar']
* a.rotate! # => ["bar", 2, "bar", :foo]
*
- * When given a non-negative Integer +count+,
+ * When given a non-negative \Integer +count+,
* rotates +count+ elements from the beginning to the end:
*
* a = [:foo, 'bar', 2]
@@ -3202,7 +3405,7 @@ rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
* a1 = a.rotate
* a1 # => ["bar", 2, "bar", :foo]
*
- * When given a non-negative Integer +count+,
+ * When given a non-negative \Integer +count+,
* returns a new \Array with +count+ elements rotated from the beginning to the end:
*
* a = [:foo, 'bar', 2]
@@ -3221,7 +3424,7 @@ rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
* a1 = a.rotate(0)
* a1 # => [:foo, "bar", 2]
*
- * When given a negative Integer +count+, rotates in the opposite direction,
+ * When given a negative \Integer +count+, rotates in the opposite direction,
* from end to beginning:
*
* a = [:foo, 'bar', 2]
@@ -3248,7 +3451,7 @@ rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
rotated = rb_ary_new2(len);
if (len > 0) {
cnt = rotate_count(cnt, len);
- ptr = RARRAY_CONST_PTR(ary);
+ ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
len -= cnt;
ary_memcpy(rotated, 0, len, ptr + cnt);
ary_memcpy(rotated, len, cnt, ptr);
@@ -3387,9 +3590,6 @@ rb_ary_sort_bang(VALUE ary)
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
}
- if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
- ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
- }
ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
}
@@ -3582,7 +3782,7 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
* a.sort_by! {|element| element.size }
* a # => ["d", "cc", "bbb", "aaaa"]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = ['aaaa', 'bbb', 'cc', 'd']
* a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!>
@@ -3614,11 +3814,12 @@ rb_ary_sort_by_bang(VALUE ary)
* a1 = a.map {|element| element.class }
* a1 # => [Symbol, String, Integer]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* a = [:foo, 'bar', 2]
* a1 = a.map
* a1 # => #<Enumerator: [:foo, "bar", 2]:map>
*
+ * Array#collect is an alias for Array#map.
*/
static VALUE
@@ -3647,12 +3848,13 @@ rb_ary_collect(VALUE ary)
* a = [:foo, 'bar', 2]
* a.map! { |element| element.class } # => [Symbol, String, Integer]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2]
* a1 = a.map!
* a1 # => #<Enumerator: [:foo, "bar", 2]:map!>
*
+ * Array#collect! is an alias for Array#map!.
*/
static VALUE
@@ -3704,7 +3906,7 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
/* check if idx is Range */
else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) {
if (len > 0) {
- const VALUE *const src = RARRAY_CONST_PTR(ary);
+ const VALUE *const src = RARRAY_CONST_PTR_TRANSIENT(ary);
const long end = beg + len;
const long prevlen = RARRAY_LEN(result);
if (beg < olen) {
@@ -3727,7 +3929,7 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
* array.values_at(*indexes) -> new_array
*
* Returns a new \Array whose elements are the elements
- * of +self+ at the given Integer or Range +indexes+.
+ * of +self+ at the given \Integer or \Range +indexes+.
*
* For each positive +index+, returns the element at offset +index+:
*
@@ -3791,11 +3993,12 @@ rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
* a1 = a.select {|element| element.to_s.start_with?('b') }
* a1 # => ["bar", :bam]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2, :bam]
* a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>
*
+ * Array#filter is an alias for Array#select.
*/
static VALUE
@@ -3850,7 +4053,7 @@ select_bang_ensure(VALUE a)
rb_ary_modify(ary);
if (i1 < len) {
tail = len - i1;
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
});
}
@@ -3874,11 +4077,12 @@ select_bang_ensure(VALUE a)
*
* Returns +nil+ if no elements were removed.
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2, :bam]
* a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>
*
+ * Array#filter! is an alias for Array#select!.
*/
static VALUE
@@ -3905,7 +4109,7 @@ rb_ary_select_bang(VALUE ary)
* a = [:foo, 'bar', 2, :bam]
* a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2, :bam]
* a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if>
@@ -4037,7 +4241,7 @@ rb_ary_delete_at(VALUE ary, long pos)
rb_ary_modify(ary);
del = RARRAY_AREF(ary, pos);
- RARRAY_PTR_USE(ary, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
});
ARY_INCREASE_LEN(ary, -1);
@@ -4049,7 +4253,7 @@ rb_ary_delete_at(VALUE ary, long pos)
* call-seq:
* array.delete_at(index) -> deleted_object or nil
*
- * Deletes an element from +self+, per the given Integer +index+.
+ * Deletes an element from +self+, per the given \Integer +index+.
*
* When +index+ is non-negative, deletes the element at offset +index+:
*
@@ -4098,7 +4302,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
return rb_ary_new2(0);
}
else {
- VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR(ary)+pos);
+ VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
rb_ary_splice(ary, pos, len, 0, 0);
return arg2;
}
@@ -4112,7 +4316,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
*
* Removes and returns elements from +self+.
*
- * When the only argument is an Integer +n+,
+ * When the only argument is an \Integer +n+,
* removes and returns the _nth_ element in +self+:
*
* a = [:foo, 'bar', 2]
@@ -4147,7 +4351,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
*
* If +length+ is negative, returns +nil+.
*
- * When the only argument is a Range object +range+,
+ * When the only argument is a \Range object +range+,
* treats <tt>range.min</tt> as +start+ above and <tt>range.size</tt> as +length+ above:
*
* a = [:foo, 'bar', 2]
@@ -4263,7 +4467,7 @@ ary_reject_bang(VALUE ary)
*
* Returns +nil+ if no elements removed.
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2]
* a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
@@ -4290,7 +4494,7 @@ rb_ary_reject_bang(VALUE ary)
* a1 = a.reject {|element| element.to_s.start_with?('b') }
* a1 # => [:foo, 2]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2]
* a.reject # => #<Enumerator: [:foo, "bar", 2]:reject>
@@ -4319,12 +4523,12 @@ rb_ary_reject(VALUE ary)
* a = [:foo, 'bar', 2, 'bat']
* a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [:foo, 'bar', 2]
* a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if>
*
- */
+3 */
static VALUE
rb_ary_delete_if(VALUE ary)
@@ -4539,14 +4743,15 @@ rb_ary_replace(VALUE copy, VALUE orig)
/* orig has enough space to embed the contents of orig. */
if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
assert(ARY_EMBED_P(copy));
- ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
+ ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
}
+#if USE_RVARGC
/* orig is embedded but copy does not have enough space to embed the
* contents of orig. */
else if (ARY_EMBED_P(orig)) {
long len = ARY_EMBED_LEN(orig);
- VALUE *ptr = ary_heap_alloc(len);
+ VALUE *ptr = ary_heap_alloc(copy, len);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ptr);
@@ -4555,8 +4760,9 @@ rb_ary_replace(VALUE copy, VALUE orig)
// No allocation and exception expected that could leave `copy` in a
// bad state from the edits above.
- ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));
+ ary_memcpy(copy, 0, len, RARRAY_CONST_PTR_TRANSIENT(orig));
}
+#endif
/* Otherwise, orig is on heap and copy does not have enough space to embed
* the contents of orig. */
else {
@@ -4621,7 +4827,7 @@ rb_ary_clear(VALUE ary)
* a # => ["a", "b", "c", "d"]
* a.fill(:X) # => [:X, :X, :X, :X]
*
- * With arguments +obj+ and Integer +start+, and no block given,
+ * With arguments +obj+ and \Integer +start+, and no block given,
* replaces elements based on the given start.
*
* If +start+ is in range (<tt>0 <= start < array.size</tt>),
@@ -4649,7 +4855,7 @@ rb_ary_clear(VALUE ary)
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, -50) # => [:X, :X, :X, :X]
*
- * With arguments +obj+, Integer +start+, and Integer +length+, and no block given,
+ * With arguments +obj+, \Integer +start+, and \Integer +length+, and no block given,
* replaces elements based on the given +start+ and +length+.
*
* If +start+ is in range, replaces +length+ elements beginning at offset +start+:
@@ -4675,7 +4881,7 @@ rb_ary_clear(VALUE ary)
* a.fill(:X, 1, 0) # => ["a", "b", "c", "d"]
* a.fill(:X, 1, -1) # => ["a", "b", "c", "d"]
*
- * With arguments +obj+ and Range +range+, and no block given,
+ * With arguments +obj+ and \Range +range+, and no block given,
* replaces elements based on the given range.
*
* If the range is positive and ascending (<tt>0 < range.begin <= range.end</tt>),
@@ -4887,8 +5093,8 @@ rb_ary_plus(VALUE x, VALUE y)
len = xlen + ylen;
z = rb_ary_new2(len);
- ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
- ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
+ ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x));
+ ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
ARY_SET_LEN(z, len);
return z;
}
@@ -4898,7 +5104,7 @@ ary_append(VALUE x, VALUE y)
{
long n = RARRAY_LEN(y);
if (n > 0) {
- rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR(y), n);
+ rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR_TRANSIENT(y), n);
}
RB_GC_GUARD(y);
return x;
@@ -4946,13 +5152,13 @@ rb_ary_concat(VALUE x, VALUE y)
* array * n -> new_array
* array * string_separator -> new_string
*
- * When non-negative argument Integer +n+ is given,
+ * When non-negative argument \Integer +n+ is given,
* returns a new \Array built by concatenating the +n+ copies of +self+:
*
* a = ['x', 'y']
* a * 3 # => ["x", "y", "x", "y", "x", "y"]
*
- * When String argument +string_separator+ is given,
+ * When \String argument +string_separator+ is given,
* equivalent to <tt>array.join(string_separator)</tt>:
*
* [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
@@ -4987,16 +5193,16 @@ rb_ary_times(VALUE ary, VALUE times)
ary2 = ary_new(rb_cArray, len);
ARY_SET_LEN(ary2, len);
- ptr = RARRAY_CONST_PTR(ary);
+ ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
t = RARRAY_LEN(ary);
if (0 < t) {
ary_memcpy(ary2, 0, t, ptr);
while (t <= len/2) {
- ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
+ ary_memcpy(ary2, t, t, RARRAY_CONST_PTR_TRANSIENT(ary2));
t *= 2;
}
if (t < len) {
- ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
+ ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR_TRANSIENT(ary2));
}
}
out:
@@ -5055,7 +5261,7 @@ rb_ary_rassoc(VALUE ary, VALUE value)
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
- v = rb_check_array_type(RARRAY_AREF(ary, i));
+ v = RARRAY_AREF(ary, i);
if (RB_TYPE_P(v, T_ARRAY) &&
RARRAY_LEN(v) > 1 &&
rb_equal(RARRAY_AREF(v, 1), value))
@@ -5127,7 +5333,7 @@ rb_ary_equal(VALUE ary1, VALUE ary2)
return rb_equal(ary2, ary1);
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
- if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
+ if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
}
@@ -5167,27 +5373,10 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
if (ary1 == ary2) return Qtrue;
if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
- if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
+ if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
}
-VALUE
-rb_ary_hash_values(long len, const VALUE *elements)
-{
- long i;
- st_index_t h;
- VALUE n;
-
- h = rb_hash_start(len);
- h = rb_hash_uint(h, (st_index_t)rb_ary_hash_values);
- for (i=0; i<len; i++) {
- n = rb_hash(elements[i]);
- h = rb_hash_uint(h, NUM2LONG(n));
- }
- h = rb_hash_end(h);
- return ST2FIX(h);
-}
-
/*
* call-seq:
* array.hash -> integer
@@ -5204,7 +5393,18 @@ rb_ary_hash_values(long len, const VALUE *elements)
static VALUE
rb_ary_hash(VALUE ary)
{
- return rb_ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
+ long i;
+ st_index_t h;
+ VALUE n;
+
+ h = rb_hash_start(RARRAY_LEN(ary));
+ h = rb_hash_uint(h, (st_index_t)rb_ary_hash);
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ n = rb_hash(RARRAY_AREF(ary, i));
+ h = rb_hash_uint(h, NUM2LONG(n));
+ }
+ h = rb_hash_end(h);
+ return ST2FIX(h);
}
/*
@@ -5364,6 +5564,17 @@ ary_make_hash_by(VALUE ary)
return ary_add_hash_by(hash, ary);
}
+static inline void
+ary_recycle_hash(VALUE hash)
+{
+ assert(RBASIC_CLASS(hash) == 0);
+ if (RHASH_ST_TABLE_P(hash)) {
+ st_table *tbl = RHASH_ST_TABLE(hash);
+ st_free_table(tbl);
+ RHASH_ST_CLEAR(hash);
+ }
+}
+
/*
* call-seq:
* array - other_array -> new_array
@@ -5405,7 +5616,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
rb_ary_push(ary3, rb_ary_elt(ary1, i));
}
-
+ ary_recycle_hash(hash);
return ary3;
}
@@ -5468,8 +5679,7 @@ rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
* array & other_array -> new_array
*
* Returns a new \Array containing each element found in both +array+ and \Array +other_array+;
- * duplicates are omitted; items are compared using <tt>eql?</tt>
- * (items must also implement +hash+ correctly):
+ * duplicates are omitted; items are compared using <tt>eql?</tt>:
*
* [0, 1, 2, 3] & [1, 2] # => [1, 2]
* [0, 1, 0, 1] & [0, 1] # => [0, 1]
@@ -5512,6 +5722,7 @@ rb_ary_and(VALUE ary1, VALUE ary2)
rb_ary_push(ary3, v);
}
}
+ ary_recycle_hash(hash);
return ary3;
}
@@ -5522,8 +5733,7 @@ rb_ary_and(VALUE ary1, VALUE ary2)
*
* Returns a new \Array containing each element found both in +self+
* and in all of the given Arrays +other_arrays+;
- * duplicates are omitted; items are compared using <tt>eql?</tt>
- * (items must also implement +hash+ correctly):
+ * duplicates are omitted; items are compared using <tt>eql?</tt>:
*
* [0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
* [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
@@ -5599,11 +5809,11 @@ rb_ary_union_hash(VALUE hash, VALUE ary2)
static VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
- VALUE hash;
+ VALUE hash, ary3;
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
- VALUE ary3 = rb_ary_new();
+ ary3 = rb_ary_new();
rb_ary_union(ary3, ary1);
rb_ary_union(ary3, ary2);
return ary3;
@@ -5612,7 +5822,9 @@ rb_ary_or(VALUE ary1, VALUE ary2)
hash = ary_make_hash(ary1);
rb_ary_union_hash(hash, ary2);
- return rb_hash_values(hash);
+ ary3 = rb_hash_values(hash);
+ ary_recycle_hash(hash);
+ return ary3;
}
/*
@@ -5636,7 +5848,7 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
{
int i;
long sum;
- VALUE hash;
+ VALUE hash, ary_union;
sum = RARRAY_LEN(ary);
for (i = 0; i < argc; i++) {
@@ -5645,7 +5857,7 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
}
if (sum <= SMALL_ARRAY_LEN) {
- VALUE ary_union = rb_ary_new();
+ ary_union = rb_ary_new();
rb_ary_union(ary_union, ary);
for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
@@ -5656,7 +5868,9 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
hash = ary_make_hash(ary);
for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
- return rb_hash_values(hash);
+ ary_union = rb_hash_values(hash);
+ ary_recycle_hash(hash);
+ return ary_union;
}
/*
@@ -5672,8 +5886,6 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
* a.intersect?(b) #=> true
* a.intersect?(c) #=> false
*
- * Array elements are compared using <tt>eql?</tt>
- * (items must also implement +hash+ correctly).
*/
static VALUE
@@ -5712,6 +5924,7 @@ rb_ary_intersect_p(VALUE ary1, VALUE ary2)
break;
}
}
+ ary_recycle_hash(hash);
return result;
}
@@ -5818,20 +6031,20 @@ ary_max_opt_string(VALUE ary, long i, VALUE vmax)
* - A new \Array of maximum-valued elements selected from +self+.
*
* When no block is given, each element in +self+ must respond to method <tt><=></tt>
- * with an Integer.
+ * with an \Integer.
*
* With no argument and no block, returns the element in +self+
* having the maximum value per method <tt><=></tt>:
*
* [0, 1, 2].max # => 2
*
- * With an argument Integer +n+ and no block, returns a new \Array with at most +n+ elements,
+ * With an argument \Integer +n+ and no block, returns a new \Array with at most +n+ elements,
* in descending order per method <tt><=></tt>:
*
* [0, 1, 2, 3].max(3) # => [3, 2, 1]
* [0, 1, 2, 3].max(6) # => [3, 2, 1, 0]
*
- * When a block is given, the block must return an Integer.
+ * When a block is given, the block must return an \Integer.
*
* With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements;
* returns the element having the maximum value per the block:
@@ -5986,14 +6199,14 @@ ary_min_opt_string(VALUE ary, long i, VALUE vmin)
* - A new \Array of minimum-valued elements selected from +self+.
*
* When no block is given, each element in +self+ must respond to method <tt><=></tt>
- * with an Integer.
+ * with an \Integer.
*
* With no argument and no block, returns the element in +self+
* having the minimum value per method <tt><=></tt>:
*
* [0, 1, 2].min # => 0
*
- * With Integer argument +n+ and no block, returns a new \Array with at most +n+ elements,
+ * With \Integer argument +n+ and no block, returns a new \Array with at most +n+ elements,
* in ascending order per method <tt><=></tt>:
*
* [0, 1, 2, 3].min(3) # => [0, 1, 2]
@@ -6061,13 +6274,13 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
* from +self+, either per method <tt><=></tt> or per a given block:.
*
* When no block is given, each element in +self+ must respond to method <tt><=></tt>
- * with an Integer;
+ * with an \Integer;
* returns a new 2-element \Array containing the minimum and maximum values
* from +self+, per method <tt><=></tt>:
*
* [0, 1, 2].minmax # => [0, 2]
*
- * When a block is given, the block must return an Integer;
+ * When a block is given, the block must return an \Integer;
* the block is called <tt>self.size-1</tt> times to compare elements;
* returns a new 2-element \Array containing the minimum and maximum values
* from +self+, per the block:
@@ -6146,6 +6359,7 @@ rb_ary_uniq_bang(VALUE ary)
}
ary_resize_capa(ary, hash_size);
rb_hash_foreach(hash, push_value, ary);
+ ary_recycle_hash(hash);
return ary;
}
@@ -6190,6 +6404,9 @@ rb_ary_uniq(VALUE ary)
hash = ary_make_hash(ary);
uniq = rb_hash_values(hash);
}
+ if (hash) {
+ ary_recycle_hash(hash);
+ }
return uniq;
}
@@ -6210,14 +6427,14 @@ rb_ary_compact_bang(VALUE ary)
long n;
rb_ary_modify(ary);
- p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
+ p = t = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary); /* WB: no new reference */
end = p + RARRAY_LEN(ary);
while (t < end) {
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
- n = p - RARRAY_CONST_PTR(ary);
+ n = p - RARRAY_CONST_PTR_TRANSIENT(ary);
if (RARRAY_LEN(ary) == n) {
return Qnil;
}
@@ -6305,8 +6522,9 @@ static VALUE
flatten(VALUE ary, int level)
{
long i;
- VALUE stack, result, tmp = 0, elt;
- VALUE memo = Qfalse;
+ VALUE stack, result, tmp = 0, elt, vmemo;
+ st_table *memo = 0;
+ st_data_t id;
for (i = 0; i < RARRAY_LEN(ary); i++) {
elt = RARRAY_AREF(ary, i);
@@ -6320,7 +6538,7 @@ flatten(VALUE ary, int level)
}
result = ary_new(0, RARRAY_LEN(ary));
- ary_memcpy(result, 0, i, RARRAY_CONST_PTR(ary));
+ ary_memcpy(result, 0, i, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_LEN(result, i);
stack = ary_new(0, ARY_DEFAULT_SIZE);
@@ -6328,9 +6546,12 @@ flatten(VALUE ary, int level)
rb_ary_push(stack, LONG2NUM(i + 1));
if (level < 0) {
- memo = rb_obj_hide(rb_ident_hash_new());
- rb_hash_aset(memo, ary, Qtrue);
- rb_hash_aset(memo, tmp, Qtrue);
+ vmemo = rb_hash_new();
+ RBASIC_CLEAR_CLASS(vmemo);
+ memo = st_init_numtable();
+ rb_hash_st_table_set(vmemo, memo);
+ st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
+ st_insert(memo, (st_data_t)tmp, (st_data_t)Qtrue);
}
ary = tmp;
@@ -6345,8 +6566,9 @@ flatten(VALUE ary, int level)
}
tmp = rb_check_array_type(elt);
if (RBASIC(result)->klass) {
- if (RTEST(memo)) {
- rb_hash_clear(memo);
+ if (memo) {
+ RB_GC_GUARD(vmemo);
+ st_clear(memo);
}
rb_raise(rb_eRuntimeError, "flatten reentered");
}
@@ -6355,11 +6577,12 @@ flatten(VALUE ary, int level)
}
else {
if (memo) {
- if (rb_hash_aref(memo, tmp) == Qtrue) {
- rb_hash_clear(memo);
+ id = (st_data_t)tmp;
+ if (st_is_member(memo, id)) {
+ st_clear(memo);
rb_raise(rb_eArgError, "tried to flatten recursive array");
}
- rb_hash_aset(memo, tmp, Qtrue);
+ st_insert(memo, id, (st_data_t)Qtrue);
}
rb_ary_push(stack, ary);
rb_ary_push(stack, LONG2NUM(i));
@@ -6371,7 +6594,8 @@ flatten(VALUE ary, int level)
break;
}
if (memo) {
- rb_hash_delete(memo, ary);
+ id = (st_data_t)ary;
+ st_delete(memo, &id, 0);
}
tmp = rb_ary_pop(stack);
i = NUM2LONG(tmp);
@@ -6379,7 +6603,7 @@ flatten(VALUE ary, int level)
}
if (memo) {
- rb_hash_clear(memo);
+ st_clear(memo);
}
RBASIC_SET_CLASS(result, rb_cArray);
@@ -6394,7 +6618,7 @@ flatten(VALUE ary, int level)
* Replaces each nested \Array in +self+ with the elements from that \Array;
* returns +self+ if any changes, +nil+ otherwise.
*
- * With non-negative Integer argument +level+, flattens recursively through +level+ levels:
+ * With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
*
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten!(1) # => [0, 1, [2, 3], 4, 5]
@@ -6448,7 +6672,7 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
* - Each non-Array element is unchanged.
* - Each \Array is replaced by its individual elements.
*
- * With non-negative Integer argument +level+, flattens recursively through +level+ levels:
+ * With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
*
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten(0) # => [0, [1, [2, 3], 4], 5]
@@ -6504,7 +6728,7 @@ rb_ary_shuffle_bang(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
while (i) {
long j = RAND_UPTO(i);
VALUE tmp;
- if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR(ary)) {
+ if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR_TRANSIENT(ary)) {
rb_raise(rb_eRuntimeError, "modified during shuffle");
}
tmp = ptr[--i];
@@ -6596,7 +6820,7 @@ ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE
sorted[j] = idx[i] = k;
}
result = rb_ary_new_capa(n);
- RARRAY_PTR_USE(result, ptr_result, {
+ RARRAY_PTR_USE_TRANSIENT(result, ptr_result, {
for (i=0; i<n; i++) {
ptr_result[i] = RARRAY_AREF(ary, idx[i]);
}
@@ -6619,7 +6843,7 @@ ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE
len = RARRAY_LEN(ary);
if (len <= max_idx) n = 0;
else if (n > len) n = len;
- RARRAY_PTR_USE(ary, ptr_ary, {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr_ary, {
for (i=0; i<n; i++) {
long j2 = j = ptr_result[i];
long i2 = i;
@@ -6682,7 +6906,7 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
* array.cycle -> new_enumerator
* array.cycle(count) -> new_enumerator
*
- * When called with positive Integer argument +count+ and a block,
+ * When called with positive \Integer argument +count+ and a block,
* calls the block with each element, then does so again,
* until it has done so +count+ times; returns +nil+:
*
@@ -6701,7 +6925,7 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
* [0, 1].cycle {|element| puts element }
* [0, 1].cycle(nil) {|element| puts element }
*
- * When no block is given, returns a new Enumerator:
+ * When no block is given, returns a new \Enumerator:
*
* [0, 1].cycle(2) # => #<Enumerator: [0, 1]:cycle(2)>
* [0, 1].cycle # => # => #<Enumerator: [0, 1]:cycle>
@@ -6858,7 +7082,7 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* When invoked with a block, yield all permutations of elements of +self+; returns +self+.
* The order of permutations is indeterminate.
*
- * When a block and an in-range positive Integer argument +n+ (<tt>0 < n <= self.size</tt>)
+ * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>)
* are given, calls the block with all +n+-tuple permutations of +self+.
*
* Example:
@@ -6920,7 +7144,7 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* [2, 0, 1]
* [2, 1, 0]
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [0, 1, 2]
* a.permutation # => #<Enumerator: [0, 1, 2]:permutation>
@@ -7004,7 +7228,7 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
* Calls the block, if given, with combinations of elements of +self+;
* returns +self+. The order of combinations is indeterminate.
*
- * When a block and an in-range positive Integer argument +n+ (<tt>0 < n <= self.size</tt>)
+ * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>)
* are given, calls the block with all +n+-tuple combinations of +self+.
*
* Example:
@@ -7043,7 +7267,7 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
* a.combination(-1) {|combination| fail 'Cannot happen' }
* a.combination(4) {|combination| fail 'Cannot happen' }
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [0, 1, 2]
* a.combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
@@ -7141,7 +7365,7 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* each permutation is an \Array;
* returns +self+. The order of the permutations is indeterminate.
*
- * When a block and a positive Integer argument +n+ are given, calls the block with each
+ * When a block and a positive \Integer argument +n+ are given, calls the block with each
* +n+-tuple repeated permutation of the elements of +self+.
* The number of permutations is <tt>self.size**n</tt>.
*
@@ -7178,7 +7402,7 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
*
* a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [0, 1, 2]
* a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
@@ -7273,7 +7497,7 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
* each combination is an \Array;
* returns +self+. The order of the combinations is indeterminate.
*
- * When a block and a positive Integer argument +n+ are given, calls the block with each
+ * When a block and a positive \Integer argument +n+ are given, calls the block with each
* +n+-tuple repeated combination of the elements of +self+.
* The number of combinations is <tt>(n+1)(n+2)/2</tt>.
*
@@ -7307,7 +7531,7 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
*
* a.repeated_combination(-1) {|combination| fail 'Cannot happen' }
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
*
* a = [0, 1, 2]
* a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
@@ -7515,7 +7739,7 @@ done:
* array.take(n) -> new_array
*
* Returns a new \Array containing the first +n+ element of +self+,
- * where +n+ is a non-negative Integer;
+ * where +n+ is a non-negative \Integer;
* does not modify +self+.
*
* Examples:
@@ -7555,7 +7779,7 @@ rb_ary_take(VALUE obj, VALUE n)
* a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5]
* a # => [0, 1, 2, 3, 4, 5]
*
- * With no block given, returns a new Enumerator:
+ * With no block given, returns a new \Enumerator:
*
* [0, 1].take_while # => #<Enumerator: [0, 1]:take_while>
*
@@ -7578,7 +7802,7 @@ rb_ary_take_while(VALUE ary)
* array.drop(n) -> new_array
*
* Returns a new \Array containing all but the first +n+ element of +self+,
- * where +n+ is a non-negative Integer;
+ * where +n+ is a non-negative \Integer;
* does not modify +self+.
*
* Examples:
@@ -7619,7 +7843,7 @@ rb_ary_drop(VALUE ary, VALUE n)
* a = [0, 1, 2, 3, 4, 5]
* a.drop_while {|element| element < 3 } # => [3, 4, 5]
*
- * With no block given, returns a new Enumerator:
+ * With no block given, returns a new \Enumerator:
*
* [0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while>
*
@@ -7645,9 +7869,6 @@ rb_ary_drop_while(VALUE ary)
*
* Returns +true+ if any element of +self+ meets a given criterion.
*
- * If +self+ has no element, returns +false+ and argument or block
- * are not used.
- *
* With no block given and no argument, returns +true+ if +self+ has any truthy element,
* +false+ otherwise:
*
@@ -7709,9 +7930,6 @@ rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
*
* Returns +true+ if all elements of +self+ meet a given criterion.
*
- * If +self+ has no element, returns +true+ and argument or block
- * are not used.
- *
* With no block given and no argument, returns +true+ if +self+ contains only truthy elements,
* +false+ otherwise:
*
@@ -7997,12 +8215,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
n = 0;
r = Qundef;
-
- if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {
- i = 0;
- goto init_is_a_value;
- }
-
for (i = 0; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
@@ -8087,7 +8299,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
}
goto has_some_value;
- init_is_a_value:
for (; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
@@ -8098,7 +8309,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
return v;
}
-/* :nodoc: */
static VALUE
rb_ary_deconstruct(VALUE ary)
{
@@ -8626,6 +8836,8 @@ Init_Array(void)
rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
rb_define_method(rb_cArray, "at", rb_ary_at, 1);
rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
+ rb_define_method(rb_cArray, "first", rb_ary_first, -1);
+ rb_define_method(rb_cArray, "last", rb_ary_last, -1);
rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1);
rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);
diff --git a/array.rb b/array.rb
index d17f374235..b9fa9844e6 100644
--- a/array.rb
+++ b/array.rb
@@ -66,92 +66,4 @@ class Array
Primitive.ary_sample(random, n, ary)
end
end
-
- # call-seq:
- # array.first -> object or nil
- # array.first(n) -> new_array
- #
- # Returns elements from +self+; does not modify +self+.
- #
- # When no argument is given, returns the first element:
- #
- # a = [:foo, 'bar', 2]
- # a.first # => :foo
- # a # => [:foo, "bar", 2]
- #
- # If +self+ is empty, returns +nil+.
- #
- # When non-negative Integer argument +n+ is given,
- # returns the first +n+ elements in a new \Array:
- #
- # a = [:foo, 'bar', 2]
- # a.first(2) # => [:foo, "bar"]
- #
- # If <tt>n >= array.size</tt>, returns all elements:
- #
- # a = [:foo, 'bar', 2]
- # a.first(50) # => [:foo, "bar", 2]
- #
- # If <tt>n == 0</tt> returns an new empty \Array:
- #
- # a = [:foo, 'bar', 2]
- # a.first(0) # []
- #
- # Related: #last.
- def first n = unspecified = true
- if Primitive.mandatory_only?
- Primitive.attr! :leaf
- Primitive.cexpr! %q{ ary_first(self) }
- else
- if unspecified
- Primitive.cexpr! %q{ ary_first(self) }
- else
- Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_FIRST) }
- end
- end
- end
-
- # call-seq:
- # array.last -> object or nil
- # array.last(n) -> new_array
- #
- # Returns elements from +self+; +self+ is not modified.
- #
- # When no argument is given, returns the last element:
- #
- # a = [:foo, 'bar', 2]
- # a.last # => 2
- # a # => [:foo, "bar", 2]
- #
- # If +self+ is empty, returns +nil+.
- #
- # When non-negative Integer argument +n+ is given,
- # returns the last +n+ elements in a new \Array:
- #
- # a = [:foo, 'bar', 2]
- # a.last(2) # => ["bar", 2]
- #
- # If <tt>n >= array.size</tt>, returns all elements:
- #
- # a = [:foo, 'bar', 2]
- # a.last(50) # => [:foo, "bar", 2]
- #
- # If <tt>n == 0</tt>, returns an new empty \Array:
- #
- # a = [:foo, 'bar', 2]
- # a.last(0) # []
- #
- # Related: #first.
- def last n = unspecified = true
- if Primitive.mandatory_only?
- Primitive.attr! :leaf
- Primitive.cexpr! %q{ ary_last(self) }
- else
- if unspecified
- Primitive.cexpr! %q{ ary_last(self) }
- else
- Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_LAST) }
- end
- end
- end
end
diff --git a/ast.c b/ast.c
index 50a54a9f4b..adb7287ed3 100644
--- a/ast.c
+++ b/ast.c
@@ -1,6 +1,6 @@
/* indent-tabs-mode: nil */
#include "internal.h"
-#include "internal/ruby_parser.h"
+#include "internal/parse.h"
#include "internal/symbol.h"
#include "internal/warnings.h"
#include "iseq.h"
@@ -97,7 +97,7 @@ rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant, VALUE
StringValue(str);
VALUE vparser = ast_parse_new();
- if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser, Qtrue);
+ if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
ast = rb_parser_compile_string_path(vparser, Qnil, str, 1);
@@ -117,10 +117,11 @@ rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VAL
rb_ast_t *ast = 0;
rb_encoding *enc = rb_utf8_encoding();
+ FilePathValue(path);
f = rb_file_open_str(path, "r");
rb_funcall(f, rb_intern("set_encoding"), 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
VALUE vparser = ast_parse_new();
- if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser, Qtrue);
+ if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
ast = rb_parser_compile_file_path(vparser, Qnil, f, 1);
@@ -148,7 +149,7 @@ rb_ast_parse_array(VALUE array, VALUE keep_script_lines, VALUE error_tolerant, V
array = rb_check_array_type(array);
VALUE vparser = ast_parse_new();
- if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser, Qtrue);
+ if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
ast = rb_parser_compile_generic(vparser, lex_array, Qnil, array, 1);
@@ -183,8 +184,8 @@ node_find(VALUE self, const int node_id)
extern VALUE rb_e_script;
-VALUE
-rb_script_lines_for(VALUE path, bool add)
+static VALUE
+script_lines(VALUE path)
{
VALUE hash, lines;
ID script_lines;
@@ -192,19 +193,10 @@ rb_script_lines_for(VALUE path, bool add)
if (!rb_const_defined_at(rb_cObject, script_lines)) return Qnil;
hash = rb_const_get_at(rb_cObject, script_lines);
if (!RB_TYPE_P(hash, T_HASH)) return Qnil;
- if (add) {
- rb_hash_aset(hash, path, lines = rb_ary_new());
- }
- else if (!RB_TYPE_P((lines = rb_hash_lookup(hash, path)), T_ARRAY)) {
- return Qnil;
- }
+ lines = rb_hash_lookup(hash, path);
+ if (!RB_TYPE_P(lines, T_ARRAY)) return Qnil;
return lines;
}
-static VALUE
-script_lines(VALUE path)
-{
- return rb_script_lines_for(path, false);
-}
static VALUE
node_id_for_backtrace_location(rb_execution_context_t *ec, VALUE module, VALUE location)
@@ -330,14 +322,14 @@ rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...)
}
static VALUE
-dump_block(rb_ast_t *ast, const struct RNode_BLOCK *node)
+dump_block(rb_ast_t *ast, const NODE *node)
{
VALUE ary = rb_ary_new();
do {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
} while (node->nd_next &&
nd_type_p(node->nd_next, NODE_BLOCK) &&
- (node = RNODE_BLOCK(node->nd_next), 1));
+ (node = node->nd_next, 1));
if (node->nd_next) {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
}
@@ -346,13 +338,13 @@ dump_block(rb_ast_t *ast, const struct RNode_BLOCK *node)
}
static VALUE
-dump_array(rb_ast_t *ast, const struct RNode_LIST *node)
+dump_array(rb_ast_t *ast, const NODE *node)
{
VALUE ary = rb_ary_new();
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
while (node->nd_next && nd_type_p(node->nd_next, NODE_LIST)) {
- node = RNODE_LIST(node->nd_next);
+ node = node->nd_next;
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
}
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
@@ -385,229 +377,211 @@ rest_arg(rb_ast_t *ast, const NODE *rest_arg)
static VALUE
node_children(rb_ast_t *ast, const NODE *node)
{
- char name[sizeof("$") + DECIMAL_SIZE_OF(long)];
+ char name[DECIMAL_SIZE_OF_BITS(sizeof(long) * CHAR_BIT) + 2]; /* including '$' */
enum node_type type = nd_type(node);
switch (type) {
case NODE_BLOCK:
- return dump_block(ast, RNODE_BLOCK(node));
+ return dump_block(ast, node);
case NODE_IF:
- return rb_ary_new_from_node_args(ast, 3, RNODE_IF(node)->nd_cond, RNODE_IF(node)->nd_body, RNODE_IF(node)->nd_else);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else);
case NODE_UNLESS:
- return rb_ary_new_from_node_args(ast, 3, RNODE_UNLESS(node)->nd_cond, RNODE_UNLESS(node)->nd_body, RNODE_UNLESS(node)->nd_else);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else);
case NODE_CASE:
- return rb_ary_new_from_node_args(ast, 2, RNODE_CASE(node)->nd_head, RNODE_CASE(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
case NODE_CASE2:
- return rb_ary_new_from_node_args(ast, 2, RNODE_CASE2(node)->nd_head, RNODE_CASE2(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
case NODE_CASE3:
- return rb_ary_new_from_node_args(ast, 2, RNODE_CASE3(node)->nd_head, RNODE_CASE3(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
case NODE_WHEN:
- return rb_ary_new_from_node_args(ast, 3, RNODE_WHEN(node)->nd_head, RNODE_WHEN(node)->nd_body, RNODE_WHEN(node)->nd_next);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
case NODE_IN:
- return rb_ary_new_from_node_args(ast, 3, RNODE_IN(node)->nd_head, RNODE_IN(node)->nd_body, RNODE_IN(node)->nd_next);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
case NODE_WHILE:
case NODE_UNTIL:
- return rb_ary_push(rb_ary_new_from_node_args(ast, 2, RNODE_WHILE(node)->nd_cond, RNODE_WHILE(node)->nd_body),
- RBOOL(RNODE_WHILE(node)->nd_state));
+ return rb_ary_push(rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body),
+ RBOOL(node->nd_state));
case NODE_ITER:
case NODE_FOR:
- return rb_ary_new_from_node_args(ast, 2, RNODE_ITER(node)->nd_iter, RNODE_ITER(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body);
case NODE_FOR_MASGN:
- return rb_ary_new_from_node_args(ast, 1, RNODE_FOR_MASGN(node)->nd_var);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_var);
case NODE_BREAK:
- return rb_ary_new_from_node_args(ast, 1, RNODE_BREAK(node)->nd_stts);
case NODE_NEXT:
- return rb_ary_new_from_node_args(ast, 1, RNODE_NEXT(node)->nd_stts);
case NODE_RETURN:
- return rb_ary_new_from_node_args(ast, 1, RNODE_RETURN(node)->nd_stts);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_stts);
case NODE_REDO:
return rb_ary_new_from_node_args(ast, 0);
case NODE_RETRY:
return rb_ary_new_from_node_args(ast, 0);
case NODE_BEGIN:
- return rb_ary_new_from_node_args(ast, 1, RNODE_BEGIN(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_RESCUE:
- return rb_ary_new_from_node_args(ast, 3, RNODE_RESCUE(node)->nd_head, RNODE_RESCUE(node)->nd_resq, RNODE_RESCUE(node)->nd_else);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_resq, node->nd_else);
case NODE_RESBODY:
- return rb_ary_new_from_node_args(ast, 3, RNODE_RESBODY(node)->nd_args, RNODE_RESBODY(node)->nd_body, RNODE_RESBODY(node)->nd_head);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_args, node->nd_body, node->nd_head);
case NODE_ENSURE:
- return rb_ary_new_from_node_args(ast, 2, RNODE_ENSURE(node)->nd_head, RNODE_ENSURE(node)->nd_ensr);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_ensr);
case NODE_AND:
case NODE_OR:
{
VALUE ary = rb_ary_new();
while (1) {
- rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_1st));
- if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type))
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_1st));
+ if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type))
break;
- node = RNODE_AND(node)->nd_2nd;
+ node = node->nd_2nd;
}
- rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_2nd));
+ rb_ary_push(ary, NEW_CHILD(ast, node->nd_2nd));
return ary;
}
case NODE_MASGN:
- if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) {
- return rb_ary_new_from_node_args(ast, 3, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head, RNODE_MASGN(node)->nd_args);
+ if (NODE_NAMED_REST_P(node->nd_args)) {
+ return rb_ary_new_from_node_args(ast, 3, node->nd_value, node->nd_head, node->nd_args);
}
else {
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_MASGN(node)->nd_value),
- NEW_CHILD(ast, RNODE_MASGN(node)->nd_head),
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_value),
+ NEW_CHILD(ast, node->nd_head),
no_name_rest());
}
case NODE_LASGN:
- if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node)->nd_value)) {
- return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
- }
- return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_LASGN(node)->nd_value));
case NODE_DASGN:
- if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node)->nd_value)) {
- return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
- }
- return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_DASGN(node)->nd_value));
case NODE_IASGN:
- return rb_ary_new_from_args(2, var_name(RNODE_IASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_IASGN(node)->nd_value));
case NODE_CVASGN:
- return rb_ary_new_from_args(2, var_name(RNODE_CVASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_CVASGN(node)->nd_value));
case NODE_GASGN:
- return rb_ary_new_from_args(2, var_name(RNODE_GASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_GASGN(node)->nd_value));
+ if (NODE_REQUIRED_KEYWORD_P(node)) {
+ return rb_ary_new_from_args(2, var_name(node->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
+ }
+ return rb_ary_new_from_args(2, var_name(node->nd_vid), NEW_CHILD(ast, node->nd_value));
case NODE_CDECL:
- if (RNODE_CDECL(node)->nd_vid) {
- return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node)->nd_vid), NEW_CHILD(ast, RNODE_CDECL(node)->nd_value));
+ if (node->nd_vid) {
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_vid), NEW_CHILD(ast, node->nd_value));
}
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_CDECL(node)->nd_else), ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid), NEW_CHILD(ast, RNODE_CDECL(node)->nd_value));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_else), ID2SYM(node->nd_else->nd_mid), NEW_CHILD(ast, node->nd_value));
case NODE_OP_ASGN1:
- return rb_ary_new_from_args(4, NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_recv),
- ID2SYM(RNODE_OP_ASGN1(node)->nd_mid),
- NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_index),
- NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_rvalue));
+ return rb_ary_new_from_args(4, NEW_CHILD(ast, node->nd_recv),
+ ID2SYM(node->nd_mid),
+ NEW_CHILD(ast, node->nd_args->nd_head),
+ NEW_CHILD(ast, node->nd_args->nd_body));
case NODE_OP_ASGN2:
- return rb_ary_new_from_args(5, NEW_CHILD(ast, RNODE_OP_ASGN2(node)->nd_recv),
- RBOOL(RNODE_OP_ASGN2(node)->nd_aid),
- ID2SYM(RNODE_OP_ASGN2(node)->nd_vid),
- ID2SYM(RNODE_OP_ASGN2(node)->nd_mid),
- NEW_CHILD(ast, RNODE_OP_ASGN2(node)->nd_value));
+ return rb_ary_new_from_args(5, NEW_CHILD(ast, node->nd_recv),
+ RBOOL(node->nd_next->nd_aid),
+ ID2SYM(node->nd_next->nd_vid),
+ ID2SYM(node->nd_next->nd_mid),
+ NEW_CHILD(ast, node->nd_value));
case NODE_OP_ASGN_AND:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_ASGN_AND(node)->nd_head), ID2SYM(idANDOP),
- NEW_CHILD(ast, RNODE_OP_ASGN_AND(node)->nd_value));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idANDOP),
+ NEW_CHILD(ast, node->nd_value));
case NODE_OP_ASGN_OR:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_ASGN_OR(node)->nd_head), ID2SYM(idOROP),
- NEW_CHILD(ast, RNODE_OP_ASGN_OR(node)->nd_value));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idOROP),
+ NEW_CHILD(ast, node->nd_value));
case NODE_OP_CDECL:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_CDECL(node)->nd_head),
- ID2SYM(RNODE_OP_CDECL(node)->nd_aid),
- NEW_CHILD(ast, RNODE_OP_CDECL(node)->nd_value));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head),
+ ID2SYM(node->nd_aid),
+ NEW_CHILD(ast, node->nd_value));
case NODE_CALL:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_CALL(node)->nd_recv),
- ID2SYM(RNODE_CALL(node)->nd_mid),
- NEW_CHILD(ast, RNODE_CALL(node)->nd_args));
case NODE_OPCALL:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OPCALL(node)->nd_recv),
- ID2SYM(RNODE_OPCALL(node)->nd_mid),
- NEW_CHILD(ast, RNODE_OPCALL(node)->nd_args));
case NODE_QCALL:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_QCALL(node)->nd_recv),
- ID2SYM(RNODE_QCALL(node)->nd_mid),
- NEW_CHILD(ast, RNODE_QCALL(node)->nd_args));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv),
+ ID2SYM(node->nd_mid),
+ NEW_CHILD(ast, node->nd_args));
case NODE_FCALL:
- return rb_ary_new_from_args(2, ID2SYM(RNODE_FCALL(node)->nd_mid),
- NEW_CHILD(ast, RNODE_FCALL(node)->nd_args));
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_mid),
+ NEW_CHILD(ast, node->nd_args));
case NODE_VCALL:
- return rb_ary_new_from_args(1, ID2SYM(RNODE_VCALL(node)->nd_mid));
+ return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
case NODE_SUPER:
- return rb_ary_new_from_node_args(ast, 1, RNODE_SUPER(node)->nd_args);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_args);
case NODE_ZSUPER:
return rb_ary_new_from_node_args(ast, 0);
case NODE_LIST:
- return dump_array(ast, RNODE_LIST(node));
+ case NODE_VALUES:
+ return dump_array(ast, node);
case NODE_ZLIST:
return rb_ary_new_from_node_args(ast, 0);
case NODE_HASH:
- return rb_ary_new_from_node_args(ast, 1, RNODE_HASH(node)->nd_head);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
case NODE_YIELD:
- return rb_ary_new_from_node_args(ast, 1, RNODE_YIELD(node)->nd_head);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
case NODE_LVAR:
- return rb_ary_new_from_args(1, var_name(RNODE_LVAR(node)->nd_vid));
case NODE_DVAR:
- return rb_ary_new_from_args(1, var_name(RNODE_DVAR(node)->nd_vid));
+ return rb_ary_new_from_args(1, var_name(node->nd_vid));
case NODE_IVAR:
- return rb_ary_new_from_args(1, ID2SYM(RNODE_IVAR(node)->nd_vid));
case NODE_CONST:
- return rb_ary_new_from_args(1, ID2SYM(RNODE_CONST(node)->nd_vid));
case NODE_CVAR:
- return rb_ary_new_from_args(1, ID2SYM(RNODE_CVAR(node)->nd_vid));
case NODE_GVAR:
- return rb_ary_new_from_args(1, ID2SYM(RNODE_GVAR(node)->nd_vid));
+ return rb_ary_new_from_args(1, ID2SYM(node->nd_vid));
case NODE_NTH_REF:
- snprintf(name, sizeof(name), "$%ld", RNODE_NTH_REF(node)->nd_nth);
+ snprintf(name, sizeof(name), "$%ld", node->nd_nth);
return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
case NODE_BACK_REF:
name[0] = '$';
- name[1] = (char)RNODE_BACK_REF(node)->nd_nth;
+ name[1] = (char)node->nd_nth;
name[2] = '\0';
return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
case NODE_MATCH2:
- if (RNODE_MATCH2(node)->nd_args) {
- return rb_ary_new_from_node_args(ast, 3, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value, RNODE_MATCH2(node)->nd_args);
+ if (node->nd_args) {
+ return rb_ary_new_from_node_args(ast, 3, node->nd_recv, node->nd_value, node->nd_args);
}
- return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
case NODE_MATCH3:
- return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH3(node)->nd_recv, RNODE_MATCH3(node)->nd_value);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
case NODE_MATCH:
case NODE_LIT:
case NODE_STR:
case NODE_XSTR:
- return rb_ary_new_from_args(1, RNODE_LIT(node)->nd_lit);
+ return rb_ary_new_from_args(1, node->nd_lit);
case NODE_ONCE:
- return rb_ary_new_from_node_args(ast, 1, RNODE_ONCE(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_DSTR:
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
{
- struct RNode_LIST *n = RNODE_DSTR(node)->nd_next;
+ NODE *n = node->nd_next;
VALUE head = Qnil, next = Qnil;
if (n) {
head = NEW_CHILD(ast, n->nd_head);
next = NEW_CHILD(ast, n->nd_next);
}
- return rb_ary_new_from_args(3, RNODE_DSTR(node)->nd_lit, head, next);
+ return rb_ary_new_from_args(3, node->nd_lit, head, next);
}
case NODE_EVSTR:
- return rb_ary_new_from_node_args(ast, 1, RNODE_EVSTR(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_ARGSCAT:
- return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSCAT(node)->nd_head, RNODE_ARGSCAT(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
case NODE_ARGSPUSH:
- return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSPUSH(node)->nd_head, RNODE_ARGSPUSH(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
case NODE_SPLAT:
- return rb_ary_new_from_node_args(ast, 1, RNODE_SPLAT(node)->nd_head);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
case NODE_BLOCK_PASS:
- return rb_ary_new_from_node_args(ast, 2, RNODE_BLOCK_PASS(node)->nd_head, RNODE_BLOCK_PASS(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
case NODE_DEFN:
- return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFN(node)->nd_defn));
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn));
case NODE_DEFS:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_DEFS(node)->nd_recv), ID2SYM(RNODE_DEFS(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFS(node)->nd_defn));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn));
case NODE_ALIAS:
- return rb_ary_new_from_node_args(ast, 2, RNODE_ALIAS(node)->nd_1st, RNODE_ALIAS(node)->nd_2nd);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
case NODE_VALIAS:
- return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig));
+ return rb_ary_new_from_args(2, ID2SYM(node->nd_alias), ID2SYM(node->nd_orig));
case NODE_UNDEF:
- return rb_ary_new_from_node_args(ast, 1, RNODE_UNDEF(node)->nd_undef);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_undef);
case NODE_CLASS:
- return rb_ary_new_from_node_args(ast, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 3, node->nd_cpath, node->nd_super, node->nd_body);
case NODE_MODULE:
- return rb_ary_new_from_node_args(ast, 2, RNODE_MODULE(node)->nd_cpath, RNODE_MODULE(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_cpath, node->nd_body);
case NODE_SCLASS:
- return rb_ary_new_from_node_args(ast, 2, RNODE_SCLASS(node)->nd_recv, RNODE_SCLASS(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_body);
case NODE_COLON2:
- return rb_ary_new_from_args(2, NEW_CHILD(ast, RNODE_COLON2(node)->nd_head), ID2SYM(RNODE_COLON2(node)->nd_mid));
+ return rb_ary_new_from_args(2, NEW_CHILD(ast, node->nd_head), ID2SYM(node->nd_mid));
case NODE_COLON3:
- return rb_ary_new_from_args(1, ID2SYM(RNODE_COLON3(node)->nd_mid));
+ return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
case NODE_DOT2:
case NODE_DOT3:
case NODE_FLIP2:
case NODE_FLIP3:
- return rb_ary_new_from_node_args(ast, 2, RNODE_DOT2(node)->nd_beg, RNODE_DOT2(node)->nd_end);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_beg, node->nd_end);
case NODE_SELF:
return rb_ary_new_from_node_args(ast, 0);
case NODE_NIL:
@@ -619,84 +593,84 @@ node_children(rb_ast_t *ast, const NODE *node)
case NODE_ERRINFO:
return rb_ary_new_from_node_args(ast, 0);
case NODE_DEFINED:
- return rb_ary_new_from_node_args(ast, 1, RNODE_DEFINED(node)->nd_head);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_head);
case NODE_POSTEXE:
- return rb_ary_new_from_node_args(ast, 1, RNODE_POSTEXE(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_ATTRASGN:
- return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_ATTRASGN(node)->nd_recv), ID2SYM(RNODE_ATTRASGN(node)->nd_mid), NEW_CHILD(ast, RNODE_ATTRASGN(node)->nd_args));
+ return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_args));
case NODE_LAMBDA:
- return rb_ary_new_from_node_args(ast, 1, RNODE_LAMBDA(node)->nd_body);
+ return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_OPT_ARG:
- return rb_ary_new_from_node_args(ast, 2, RNODE_OPT_ARG(node)->nd_body, RNODE_OPT_ARG(node)->nd_next);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next);
case NODE_KW_ARG:
- return rb_ary_new_from_node_args(ast, 2, RNODE_KW_ARG(node)->nd_body, RNODE_KW_ARG(node)->nd_next);
+ return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next);
case NODE_POSTARG:
- if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) {
- return rb_ary_new_from_node_args(ast, 2, RNODE_POSTARG(node)->nd_1st, RNODE_POSTARG(node)->nd_2nd);
+ if (NODE_NAMED_REST_P(node->nd_1st)) {
+ return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
}
return rb_ary_new_from_args(2, no_name_rest(),
- NEW_CHILD(ast, RNODE_POSTARG(node)->nd_2nd));
+ NEW_CHILD(ast, node->nd_2nd));
case NODE_ARGS:
{
- struct rb_args_info *ainfo = &RNODE_ARGS(node)->nd_ainfo;
+ struct rb_args_info *ainfo = node->nd_ainfo;
return rb_ary_new_from_args(10,
INT2NUM(ainfo->pre_args_num),
NEW_CHILD(ast, ainfo->pre_init),
- NEW_CHILD(ast, (NODE *)ainfo->opt_args),
+ NEW_CHILD(ast, ainfo->opt_args),
var_name(ainfo->first_post_arg),
INT2NUM(ainfo->post_args_num),
NEW_CHILD(ast, ainfo->post_init),
(ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA
? ID2SYM(rb_intern("NODE_SPECIAL_EXCESSIVE_COMMA"))
: var_name(ainfo->rest_arg)),
- (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, (NODE *)ainfo->kw_args)),
+ (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_args)),
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_rest_arg)),
var_name(ainfo->block_arg));
}
case NODE_SCOPE:
{
- rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl;
+ rb_ast_id_table_t *tbl = node->nd_tbl;
int i, size = tbl ? tbl->size : 0;
VALUE locals = rb_ary_new_capa(size);
for (i = 0; i < size; i++) {
rb_ary_push(locals, var_name(tbl->ids[i]));
}
- return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, (NODE *)RNODE_SCOPE(node)->nd_args), NEW_CHILD(ast, RNODE_SCOPE(node)->nd_body));
+ return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, node->nd_args), NEW_CHILD(ast, node->nd_body));
}
case NODE_ARYPTN:
{
- VALUE rest = rest_arg(ast, RNODE_ARYPTN(node)->rest_arg);
+ struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
+ VALUE rest = rest_arg(ast, apinfo->rest_arg);
return rb_ary_new_from_args(4,
- NEW_CHILD(ast, RNODE_ARYPTN(node)->nd_pconst),
- NEW_CHILD(ast, RNODE_ARYPTN(node)->pre_args),
+ NEW_CHILD(ast, node->nd_pconst),
+ NEW_CHILD(ast, apinfo->pre_args),
rest,
- NEW_CHILD(ast, RNODE_ARYPTN(node)->post_args));
+ NEW_CHILD(ast, apinfo->post_args));
}
case NODE_FNDPTN:
{
- VALUE pre_rest = rest_arg(ast, RNODE_FNDPTN(node)->pre_rest_arg);
- VALUE post_rest = rest_arg(ast, RNODE_FNDPTN(node)->post_rest_arg);
+ struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo;
+ VALUE pre_rest = rest_arg(ast, fpinfo->pre_rest_arg);
+ VALUE post_rest = rest_arg(ast, fpinfo->post_rest_arg);
return rb_ary_new_from_args(4,
- NEW_CHILD(ast, RNODE_FNDPTN(node)->nd_pconst),
+ NEW_CHILD(ast, node->nd_pconst),
pre_rest,
- NEW_CHILD(ast, RNODE_FNDPTN(node)->args),
+ NEW_CHILD(ast, fpinfo->args),
post_rest);
}
case NODE_HSHPTN:
{
- VALUE kwrest = RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
- NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwrestarg);
+ VALUE kwrest = node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
+ NEW_CHILD(ast, node->nd_pkwrestarg);
return rb_ary_new_from_args(3,
- NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pconst),
- NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwargs),
+ NEW_CHILD(ast, node->nd_pconst),
+ NEW_CHILD(ast, node->nd_pkwargs),
kwrest);
}
case NODE_ERROR:
return rb_ary_new_from_node_args(ast, 0);
case NODE_ARGS_AUX:
- case NODE_RIPPER:
- case NODE_RIPPER_VALUES:
case NODE_LAST:
break;
}
diff --git a/ast.rb b/ast.rb
index 51ee5b3d59..f3f72c747f 100644
--- a/ast.rb
+++ b/ast.rb
@@ -20,7 +20,7 @@
module RubyVM::AbstractSyntaxTree
# call-seq:
- # RubyVM::AbstractSyntaxTree.parse(string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.parse(string, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
# Parses the given _string_ into an abstract syntax tree,
# returning the root node of that tree.
@@ -53,14 +53,14 @@ module RubyVM::AbstractSyntaxTree
# # (ERROR@1:7-1:11),
# # (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))]
#
- # Note that parsing continues even after the errored expression.
+ # Note that parsing continues even after the errored expresion.
#
- def self.parse string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false
+ def self.parse string, keep_script_lines: false, error_tolerant: false, keep_tokens: false
Primitive.ast_s_parse string, keep_script_lines, error_tolerant, keep_tokens
end
# call-seq:
- # RubyVM::AbstractSyntaxTree.parse_file(pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.parse_file(pathname, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
# Reads the file from _pathname_, then parses it like ::parse,
# returning the root node of the abstract syntax tree.
@@ -72,13 +72,13 @@ module RubyVM::AbstractSyntaxTree
# # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
#
# See ::parse for explanation of keyword argument meaning and usage.
- def self.parse_file pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false
+ def self.parse_file pathname, keep_script_lines: false, error_tolerant: false, keep_tokens: false
Primitive.ast_s_parse_file pathname, keep_script_lines, error_tolerant, keep_tokens
end
# call-seq:
- # RubyVM::AbstractSyntaxTree.of(proc, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
- # RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.of(proc, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
# Returns AST nodes of the given _proc_ or _method_.
#
@@ -93,7 +93,7 @@ module RubyVM::AbstractSyntaxTree
# # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
#
# See ::parse for explanation of keyword argument meaning and usage.
- def self.of body, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false
+ def self.of body, keep_script_lines: false, error_tolerant: false, keep_tokens: false
Primitive.ast_s_of body, keep_script_lines, error_tolerant, keep_tokens
end
@@ -265,8 +265,8 @@ module RubyVM::AbstractSyntaxTree
lines = script_lines
if lines
lines = lines[first_lineno - 1 .. last_lineno - 1]
- lines[-1] = lines[-1].byteslice(0...last_column)
- lines[0] = lines[0].byteslice(first_column..-1)
+ lines[-1] = lines[-1][0...last_column]
+ lines[0] = lines[0][first_column..-1]
lines.join
else
nil
diff --git a/benchmark/enum_sort_by.yml b/benchmark/enum_sort_by.yml
deleted file mode 100644
index d386353888..0000000000
--- a/benchmark/enum_sort_by.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-prelude: |
- array_length = 2
- fixnum_array2 = array_length.times.to_a.map {rand(10000)}
- float_array2 = array_length.times.to_a.map {rand(10000.0).to_f}
- string_array2 = array_length.times.to_a.map {"r" * rand(1..10000)}
- mix_array2 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end}
- all_zero_array2 =array_length.times.to_a.map {0}
-
- array_length = 10
- fixnum_array10 = array_length.times.to_a.map {rand(10000)}
- float_array10 = array_length.times.to_a.map {rand(10000.0).to_f}
- string_array10 = array_length.times.to_a.map {"r" * rand(1..10000)}
- mix_array10 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end}
- all_zero_array10 =array_length.times.to_a.map {0}
-
- array_length = 1000
- fixnum_array1000 = array_length.times.to_a.map {rand(10000)}
- float_array1000 = array_length.times.to_a.map {rand(10000.0).to_f}
- string_array1000 = array_length.times.to_a.map {"r" * rand(1..10000)}
- mix_array1000 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end}
- all_zero_array1000 =array_length.times.to_a.map {0}
-
- array_length = 100000
- fixnum_array100000 = array_length.times.to_a.map {rand(10000)}
- float_array100000 = array_length.times.to_a.map {rand(10000.0).to_f}
- string_array100000 = array_length.times.to_a.map {"r" * rand(1..10000)}
- mix_array100000 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end}
- all_zero_array100000 =array_length.times.to_a.map {0}
-
-benchmark:
- fixnum_array2.sort_by: fixnum_array2.sort_by {|a| a}
- float_array2.sort_by: float_array2.sort_by {|a| a}
- string_length2.sort_by: string_array2.sort_by {|a| a.length}
- mix_array2.sort_by: mix_array2.sort_by {|a| a}
- all_zero2.sort_by: all_zero_array2.sort_by{|a| a}
-
- fixnum_array10.sort_by: fixnum_array10.sort_by {|a| a}
- float_array10.sort_by: float_array10.sort_by {|a| a}
- string_length10.sort_by: string_array10.sort_by {|a| a.length}
- mix_array10.sort_by: mix_array10.sort_by {|a| a}
- all_zero10.sort_by: all_zero_array10.sort_by{|a| a}
-
- fixnum_array1000.sort_by: fixnum_array1000.sort_by {|a| a}
- float_array1000.sort_by: float_array1000.sort_by {|a| a}
- string_length1000.sort_by: string_array1000.sort_by {|a| a.length}
- mix_array1000.sort_by: mix_array1000.sort_by {|a| a}
- all_zero1000.sort_by: all_zero_array1000.sort_by{|a| a}
-
- fixnum_array100000.sort_by: fixnum_array100000.sort_by {|a| a}
- float_array100000.sort_by: float_array100000.sort_by {|a| a}
- string_length100000.sort_by: string_array100000.sort_by {|a| a.length}
- mix_array100000.sort_by: mix_array100000.sort_by {|a| a}
- all_zero100000.sort_by: all_zero_array100000.sort_by{|a| a}
diff --git a/benchmark/lib/benchmark_driver/runner/mjit.rb b/benchmark/lib/benchmark_driver/runner/mjit.rb
new file mode 100644
index 0000000000..3a58a620de
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/mjit.rb
@@ -0,0 +1,34 @@
+require 'benchmark_driver/struct'
+require 'benchmark_driver/metric'
+require 'erb'
+
+# A runner to measure after-JIT performance easily
+class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]).extend(Module.new{
+ def parse(**)
+ jobs = super
+ jobs.map do |job|
+ job = job.dup
+ job.prelude = "#{job.prelude}\n#{<<~EOS}"
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ __bmdv_ruby_i = 0
+ while __bmdv_ruby_i < 10000 # MJIT call threshold
+ #{job.script}
+ __bmdv_ruby_i += 1
+ end
+ RubyVM::MJIT.pause # compile
+ #{job.script}
+ RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile
+ #{job.script}
+ RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile 2
+ end
+ EOS
+ job
+ end
+ end
+ })
+end
diff --git a/benchmark/loop_generator.rb b/benchmark/loop_generator.rb
index 6a3194b670..d3375c744c 100644
--- a/benchmark/loop_generator.rb
+++ b/benchmark/loop_generator.rb
@@ -1,4 +1,4 @@
-max = 6000000
+max = 600000
if defined? Fiber
gen = (1..max).each
diff --git a/benchmark/mjit_exivar.yml b/benchmark/mjit_exivar.yml
new file mode 100644
index 0000000000..2584fa6410
--- /dev/null
+++ b/benchmark/mjit_exivar.yml
@@ -0,0 +1,18 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ class Bench < Hash
+ def initialize
+ @exivar = nil
+ end
+
+ def exivar
+ @exivar
+ end
+ end
+
+ bench = Bench.new
+
+benchmark:
+ mjit_exivar: bench.exivar
+
+loop_count: 200000000
diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml
new file mode 100644
index 0000000000..a6b5c9ee16
--- /dev/null
+++ b/benchmark/mjit_integer.yml
@@ -0,0 +1,32 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_abs(int) int.abs end
+ def mjit_bit_length(int) int.bit_length end
+ def mjit_comp(int) ~int end
+ def mjit_even?(int) int.even? end
+ def mjit_integer?(int) int.integer? end
+ def mjit_magnitude(int) int.magnitude end
+ def mjit_odd?(int) int.odd? end
+ def mjit_ord(int) int.ord end
+ def mjit_size(int) int.size end
+ def mjit_to_i(int) int.to_i end
+ def mjit_to_int(int) int.to_int end
+ def mjit_uminus(int) -int end
+ def mjit_zero?(int) int.zero? end
+
+benchmark:
+ - mjit_abs(-1)
+ - mjit_bit_length(100)
+ - mjit_comp(1)
+ - mjit_even?(2)
+ - mjit_integer?(0)
+ - mjit_magnitude(-1)
+ - mjit_odd?(1)
+ - mjit_ord(1)
+ - mjit_size(1)
+ - mjit_to_i(1)
+ - mjit_to_int(1)
+ - mjit_uminus(1)
+ - mjit_zero?(0)
+
+loop_count: 40000000
diff --git a/benchmark/mjit_kernel.yml b/benchmark/mjit_kernel.yml
new file mode 100644
index 0000000000..7720e65c2c
--- /dev/null
+++ b/benchmark/mjit_kernel.yml
@@ -0,0 +1,20 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_class(obj)
+ obj.class
+ end
+
+ def mjit_frozen?(obj)
+ obj.frozen?
+ end
+
+ str = ""
+ fstr = "".freeze
+
+benchmark:
+ - mjit_class(self)
+ - mjit_class(1)
+ - mjit_frozen?(str)
+ - mjit_frozen?(fstr)
+
+loop_count: 40000000
diff --git a/benchmark/mjit_leave.yml b/benchmark/mjit_leave.yml
new file mode 100644
index 0000000000..9ac68b164b
--- /dev/null
+++ b/benchmark/mjit_leave.yml
@@ -0,0 +1,8 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def leave
+ nil
+ end
+benchmark:
+ mjit_leave: leave
+loop_count: 200000000
diff --git a/benchmark/mjit_opt_cc_insns.yml b/benchmark/mjit_opt_cc_insns.yml
new file mode 100644
index 0000000000..fed6d34bd5
--- /dev/null
+++ b/benchmark/mjit_opt_cc_insns.yml
@@ -0,0 +1,27 @@
+# opt_* insns using vm_method_cfunc_is with send-compatible operands:
+# * opt_nil_p
+# * opt_not
+# * opt_eq
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_nil?(obj)
+ obj.nil?
+ end
+
+ def mjit_not(obj)
+ !obj
+ end
+
+ def mjit_eq(a, b)
+ a == b
+ end
+
+benchmark:
+ - script: mjit_nil?(1)
+ loop_count: 40000000
+ - script: mjit_not(1)
+ loop_count: 40000000
+ - script: mjit_eq(1, nil)
+ loop_count: 8000000
+ - script: mjit_eq(nil, 1)
+ loop_count: 8000000
diff --git a/benchmark/mjit_struct_aref.yml b/benchmark/mjit_struct_aref.yml
new file mode 100644
index 0000000000..bfba1323f2
--- /dev/null
+++ b/benchmark/mjit_struct_aref.yml
@@ -0,0 +1,10 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_struct_aref(struct)
+ struct.aa
+ end
+ struct = Struct.new(:a0, :a1, :a2, :a3, :a4, :a5, :a6, :a7, :a8, :a9, :aa).new
+
+benchmark: mjit_struct_aref(struct)
+
+loop_count: 40000000
diff --git a/benchmark/range_bsearch_bignum.yml b/benchmark/range_bsearch_bignum.yml
deleted file mode 100644
index 5730c93fcf..0000000000
--- a/benchmark/range_bsearch_bignum.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-prelude: |
- first = 2**100
- last = 2**1000
- mid = (first + last) / 2
- r = first..last
-
-benchmark:
- first: r.bsearch { |x| x >= first }
- mid: r.bsearch { |x| x >= mid }
- last: r.bsearch { |x| x >= last }
diff --git a/benchmark/range_bsearch_endpointless.yml b/benchmark/range_bsearch_endpointless.yml
deleted file mode 100644
index 8d7bedb662..0000000000
--- a/benchmark/range_bsearch_endpointless.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-prelude: |
- re = (1..)
- rb = (..0)
-
-benchmark:
- 'endless 10**0': re.bsearch { |x| x >= 1 }
- 'endless 10**1': re.bsearch { |x| x >= 10 }
- 'endless 10**2': re.bsearch { |x| x >= 100 }
- 'endless 10**3': re.bsearch { |x| x >= 1000 }
- 'endless 10**4': re.bsearch { |x| x >= 10000 }
- 'endless 10**5': re.bsearch { |x| x >= 100000 }
- 'endless 10**10': re.bsearch { |x| x >= 10000000000 }
- 'endless 10**100': re.bsearch { |x| x >= 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 }
- 'beginless -10**0': rb.bsearch { |x| x >= -1 }
- 'beginless -10**1': rb.bsearch { |x| x >= -10 }
- 'beginless -10**2': rb.bsearch { |x| x >= -100 }
- 'beginless -10**3': rb.bsearch { |x| x >= -1000 }
- 'beginless -10**4': rb.bsearch { |x| x >= -10000 }
- 'beginless -10**5': rb.bsearch { |x| x >= -100000 }
- 'beginless -10**10': rb.bsearch { |x| x >= -10000000000 }
- 'beginless -10**100': rb.bsearch { |x| x >= -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 }
diff --git a/benchmark/range_bsearch_fixnum.yml b/benchmark/range_bsearch_fixnum.yml
deleted file mode 100644
index 59416531b9..0000000000
--- a/benchmark/range_bsearch_fixnum.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-prelude: |
- first = 1
- last = 10000
- mid = (first + last) / 2
- r = first..last
-
-benchmark:
- first: r.bsearch { |x| x >= first }
- mid: r.bsearch { |x| x >= mid }
- last: r.bsearch { |x| x >= last }
diff --git a/benchmark/range_count.yml b/benchmark/range_count.yml
deleted file mode 100644
index 58f53a0236..0000000000
--- a/benchmark/range_count.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-prelude: |
- r_1 = 1..1
- r_1k = 1..1000
- r_1m = 1..1000000
- r_str = 'a'..'z'
-
-benchmark:
- 'int 1': r_1.count
- 'int 1K': r_1k.count
- 'int 1M': r_1m.count
- string: r_str.count
diff --git a/benchmark/range_overlap.yml b/benchmark/range_overlap.yml
deleted file mode 100644
index 700a00053c..0000000000
--- a/benchmark/range_overlap.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-prelude: |
- class Range
- unless method_defined?(:overlap?)
- def overlap?(other)
- other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin)
- end
- end
- end
-
-benchmark:
- - (2..3).overlap?(1..1)
- - (2..3).overlap?(2..4)
- - (2..3).overlap?(4..5)
- - (2..3).overlap?(2..1)
- - (2..3).overlap?(0..1)
- - (2..3).overlap?(...1)
- - (2...3).overlap?(..2)
- - (2...3).overlap?(3...)
- - (2..3).overlap?('a'..'d')
diff --git a/benchmark/range_reverse_each.yml b/benchmark/range_reverse_each.yml
deleted file mode 100644
index a32efeccc6..0000000000
--- a/benchmark/range_reverse_each.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-prelude: |
- rf_1 = 0..1
- rf_1k = 0..1000
- rf_1m = 0..1000000
- big = 2**1000
- rb_1 = big..big+1
- rb_1k = big..big+1000
- rb_1m = big..big+1000000
-
-benchmark:
- "Fixnum 1": rf_1.reverse_each { _1 }
- "Fixnum 1K": rf_1k.reverse_each { _1 }
- "Fixnum 1M": rf_1m.reverse_each { _1 }
- "Bignum 1": rb_1.reverse_each { _1 }
- "Bignum 1K": rb_1k.reverse_each { _1 }
- "Bignum 1M": rb_1m.reverse_each { _1 }
diff --git a/benchmark/regexp_dup.yml b/benchmark/regexp_dup.yml
deleted file mode 100644
index 52f89991cd..0000000000
--- a/benchmark/regexp_dup.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-prelude: |
- str = "a" * 1000
- re = Regexp.new(str)
-
-benchmark:
- dup: re.dup
diff --git a/benchmark/regexp_new.yml b/benchmark/regexp_new.yml
deleted file mode 100644
index bc9ab3ca21..0000000000
--- a/benchmark/regexp_new.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- str = "a" * 1000
- re = Regexp.new(str)
-
-benchmark:
- string: Regexp.new(str)
- regexp: Regexp.new(re)
diff --git a/benchmark/so_count_words.yml b/benchmark/so_count_words.yml
index f7322a8541..99683505f9 100644
--- a/benchmark/so_count_words.yml
+++ b/benchmark/so_count_words.yml
@@ -15,13 +15,13 @@ prelude: |
Newsgroups: rec.games.roguelike.nethack
X-Mailer: Mozilla 1.1N (Macintosh; I; 68K)
- Hello there, Izchak Miller was my father. When I was younger I spent
- many a night, hunched over the keyboard with a cup of tea, playing
- nethack with him and my brother. my dad was a philosopher with a strong
- weakness for fantasy/sci fi. I remember when he started to get involved
- with the Nethack team- my brother's Dungeons and Dragons monster book
- found a regular place beside my dad's desk. it's nice to see him living
- on in the game he loved so much :-).
+ Hello there, Izchak Miller was my father. When I was younger I spent
+ many a night, hunched over the keyboard with a cup of tea, playing
+ nethack with him and my brother. my dad was a philosopher with a strong
+ weakness for fantasy/sci fi. I remember when he started to get involved
+ with the Nethack team- my brother's Dungeons and Dragons monster book
+ found a regular place beside my dad's desk. it's nice to see him living
+ on in the game he loved so much :-).
Tamar Miller
The following is a really long word of 5000 characters:
@@ -38,9 +38,8 @@ prelude: |
13.times{
data << data
}
- File.write(wcinput, data)
+ open(wcinput, 'w'){|f| f.write data}
end
- at_exit {File.unlink(wcinput) rescue nil}
end
prepare_wc_input(wc_input_base)
@@ -50,16 +49,16 @@ benchmark:
# $Id: wc-ruby.code,v 1.4 2004/11/13 07:43:32 bfulgham Exp $
# http://www.bagley.org/~doug/shootout/
# with help from Paul Brannan
+ input = open(File.join(File.dirname($0), 'wc.input'), 'rb')
nl = nw = nc = 0
- File.open(File.join(File.dirname($0), 'wc.input'), 'rb') do |input|
- while tmp = input.read(4096)
- data = tmp << (input.gets || "")
- nc += data.length
- nl += data.count("\n")
- ((data.strip! || data).tr!("\n", " ") || data).squeeze!
- nw += data.count(" ") + 1
- end
+ while true
+ tmp = input.read(4096) or break
+ data = tmp << (input.gets || "")
+ nc += data.length
+ nl += data.count("\n")
+ ((data.strip! || data).tr!("\n", " ") || data).squeeze!
+ nw += data.count(" ") + 1
end
# STDERR.puts "#{nl} #{nw} #{nc}"
diff --git a/benchmark/so_meteor_contest.rb b/benchmark/so_meteor_contest.rb
index d8c8e3ab9c..8c136baa6c 100644
--- a/benchmark/so_meteor_contest.rb
+++ b/benchmark/so_meteor_contest.rb
@@ -447,7 +447,7 @@ end
# as an inverse. The inverse will ALWAYS be 3 one of the piece configurations that is exactly 3 rotations away
# (an odd number). Checking even vs odd then produces a higher probability of finding more pieces earlier
# in the cycle. We still need to keep checking all the permutations, but our probability of finding one will
-# diminish over time. Since we are TOLD how many to search for this lets us exit before checking all pieces
+# diminsh over time. Since we are TOLD how many to search for this lets us exit before checking all pieces
# this bennifit is very great when seeking small numbers of solutions and is 0 when looking for more than the
# maximum number
def find_top( rotation_skip)
diff --git a/benchmark/string_concat.yml b/benchmark/string_concat.yml
index da14692f5e..e65c00cca9 100644
--- a/benchmark/string_concat.yml
+++ b/benchmark/string_concat.yml
@@ -1,8 +1,6 @@
prelude: |
CHUNK = "a" * 64
UCHUNK = "é" * 32
- SHORT = "a" * (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] / 2)
- LONG = "a" * (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 2)
GC.disable # GC causes a lot of variance
benchmark:
binary_concat_7bit: |
@@ -45,7 +43,3 @@ benchmark:
"#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
"#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
"#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}"
- interpolation_same_size_pool: |
- buffer = "#{SHORT}#{SHORT}"
- interpolation_switching_size_pools: |
- buffer = "#{SHORT}#{LONG}"
diff --git a/benchmark/string_dup.yml b/benchmark/string_dup.yml
deleted file mode 100644
index 90793f9f2a..0000000000
--- a/benchmark/string_dup.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- # frozen_string_literal: true
-benchmark:
- uplus: |
- +"A"
- dup: |
- "A".dup
diff --git a/benchmark/string_rpartition.yml b/benchmark/string_rpartition.yml
deleted file mode 100644
index 37e9d1b071..0000000000
--- a/benchmark/string_rpartition.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-prelude: |
- str1 = [*"a".."z",*"0".."9"].join("")
- str10 = str1 * 10 + ":"
- str100 = str1 * 100 + ":"
- str1000 = str1 * 1000 + ":"
- nonascii1 = [*"\u{e0}".."\u{ff}"].join("")
- nonascii10 = nonascii1 * 10 + ":"
- nonascii100 = nonascii1 * 100 + ":"
- nonascii1000 = nonascii1 * 1000 + ":"
-benchmark:
- rpartition-1: str1.rpartition(":")
- rpartition-10: str10.rpartition(":")
- rpartition-100: str100.rpartition(":")
- rpartition-1000: str1000.rpartition(":")
- rpartition-nonascii1: nonascii1.rpartition(":")
- rpartition-nonascii10: nonascii10.rpartition(":")
- rpartition-nonascii100: nonascii100.rpartition(":")
- rpartition-nonascii1000: nonascii1000.rpartition(":")
diff --git a/benchmark/struct_accessor.yml b/benchmark/struct_accessor.yml
deleted file mode 100644
index 61176cfdd4..0000000000
--- a/benchmark/struct_accessor.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-prelude: |
- C = Struct.new(:x) do
- class_eval <<-END
- def r
- #{'x;'*256}
- end
- def w
- #{'self.x = nil;'*256}
- end
- def rm
- m = method(:x)
- #{'m.call;'*256}
- end
- def wm
- m = method(:x=)
- #{'m.call(nil);'*256}
- end
- END
- end
- obj = C.new(nil)
-benchmark:
- member_reader: "obj.r"
- member_writer: "obj.w"
- member_reader_method: "obj.rm"
- member_writer_method: "obj.wm"
diff --git a/benchmark/vm_call_bmethod.yml b/benchmark/vm_call_bmethod.yml
deleted file mode 100644
index 40136e5aa4..0000000000
--- a/benchmark/vm_call_bmethod.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-prelude: |
- define_method(:a0){}
- define_method(:a1){|a| a}
- define_method(:s){|*a| a}
- define_method(:b){|kw: 1| kw}
-
- t0 = 0.times.to_a
- t1 = 1.times.to_a
- t10 = 10.times.to_a
- t100 = 100.times.to_a
- kw = {kw: 2}
-benchmark:
- bmethod_simple_0: |
- a0
- bmethod_simple_1: |
- a1(1)
- bmethod_simple_0_splat: |
- a0(*t0)
- bmethod_simple_1_splat: |
- a1(*t1)
- bmethod_no_splat: |
- s
- bmethod_0_splat: |
- s(*t0)
- bmethod_1_splat: |
- s(*t1)
- bmethod_10_splat: |
- s(*t10)
- bmethod_100_splat: |
- s(*t100)
- bmethod_kw: |
- b(kw: 1)
- bmethod_no_kw: |
- b
- bmethod_kw_splat: |
- b(**kw)
-loop_count: 6000000
diff --git a/benchmark/vm_call_method_missing.yml b/benchmark/vm_call_method_missing.yml
deleted file mode 100644
index f890796f11..0000000000
--- a/benchmark/vm_call_method_missing.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-prelude: |
- class A0
- def method_missing(m); m end
- end
- class A1
- def method_missing(m, a) a; end
- end
- class S
- def method_missing(m, *a) a; end
- end
- class B
- def method_missing(m, kw: 1) kw end
- end
- class SB
- def method_missing(m, *a, kw: 1) kw end
- end
-
- t0 = 0.times.to_a
- t1 = 1.times.to_a
- t10 = 10.times.to_a
- t200 = 200.times.to_a
- kw = {kw: 2}
-
- a0 = A0.new
- a1 = A1.new
- s = S.new
- b = B.new
- sb = SB.new
-benchmark:
- method_missing_simple_0: |
- a0.()
- method_missing_simple_1: |
- a1.x(1)
- method_missing_simple_0_splat: |
- a0.(*t0)
- method_missing_simple_1_splat: |
- a1.(*t1)
- method_missing_no_splat: |
- s.()
- method_missing_0_splat: |
- s.(*t0)
- method_missing_1_splat: |
- s.(*t1)
- method_missing_10_splat: |
- s.(*t10)
- method_missing_200_splat: |
- s.(*t200)
- method_missing_kw: |
- b.(kw: 1)
- method_missing_no_kw: |
- b.()
- method_missing_kw_splat: |
- b.(**kw)
- method_missing_0_splat_kw: |
- sb.(*t0, **kw)
- method_missing_1_splat_kw: |
- sb.(*t1, **kw)
- method_missing_10_splat_kw: |
- sb.(*t10, **kw)
- method_missing_200_splat_kw: |
- sb.(*t200, **kw)
-loop_count: 1000000
diff --git a/benchmark/vm_call_send_iseq.yml b/benchmark/vm_call_send_iseq.yml
deleted file mode 100644
index 60ff23c475..0000000000
--- a/benchmark/vm_call_send_iseq.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-prelude: |
- def a0; end
- def a1(a) a; end
- def s(*a) a; end
- def b(kw: 1) kw end
- def sb(*a, kw: 1) kw end
-
- t0 = 0.times.to_a
- t1 = 1.times.to_a
- t10 = 10.times.to_a
- t200 = 200.times.to_a
-
- a0_t0 = [:a0, *t0]
- a1_t1 = [:a1, *t1]
- s_t0 = [:s, *t0]
- s_t1 = [:s, *t1]
- s_t10 = [:s, *t10]
- s_t200 = [:s, *t200]
- sb_t0 = [:sb, *t0]
- sb_t1 = [:sb, *t1]
- sb_t10 = [:sb, *t10]
- sb_t200 = [:sb, *t200]
- kw = {kw: 2}
-benchmark:
- send_simple_0: |
- send(:a0)
- send_simple_1: |
- send(:a1, 1)
- send_simple_0_splat: |
- send(:a0, *t0)
- send_simple_1_splat: |
- send(:a1, *t1)
- send_simple_0_splat_comb: |
- send(*a0_t0)
- send_simple_1_splat_comb: |
- send(*a1_t1)
- send_no_splat: |
- send(:s)
- send_0_splat: |
- send(:s, *t0)
- send_1_splat: |
- send(:s, *t1)
- send_10_splat: |
- send(:s, *t10)
- send_200_splat: |
- send(:s, *t200)
- send_0_splat_comb: |
- send(*s_t0)
- send_1_splat_comb: |
- send(*s_t1)
- send_10_splat_comb: |
- send(*s_t10)
- send_200_splat_comb: |
- send(*s_t200)
- send_kw: |
- send(:b, kw: 1)
- send_no_kw: |
- send(:b)
- send_kw_splat: |
- send(:b, **kw)
- send_0_splat_kw: |
- send(:sb, *t0, **kw)
- send_1_splat_kw: |
- send(:sb, *t1, **kw)
- send_10_splat_kw: |
- send(:sb, *t10, **kw)
- send_200_splat_kw: |
- send(:sb, *t200, **kw)
- send_0_splat_comb_kw: |
- send(*sb_t0, **kw)
- send_1_splat_comb_kw: |
- send(*sb_t1, **kw)
- send_10_splat_comb_kw: |
- send(*sb_t10, **kw)
- send_200_splat_comb_kw: |
- send(*sb_t200, **kw)
-loop_count: 3000000
diff --git a/benchmark/vm_call_symproc.yml b/benchmark/vm_call_symproc.yml
deleted file mode 100644
index 16e0ac579e..0000000000
--- a/benchmark/vm_call_symproc.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-prelude: |
- def self.a0; end
- def self.a1(a) a; end
- def self.s(*a) a; end
- def self.b(kw: 1) kw end
- def self.sb(*a, kw: 1) kw end
-
- t0 = 0.times.to_a
- t1 = 1.times.to_a
- t10 = 10.times.to_a
- t200 = 200.times.to_a
-
- a0_t0 = [self, *t0]
- a1_t1 = [self, *t1]
- s_t0 = [self, *t0]
- s_t1 = [self, *t1]
- s_t10 = [self, *t10]
- s_t200 = [self, *t200]
- sb_t0 = [self, *t0]
- sb_t1 = [self, *t1]
- sb_t10 = [self, *t10]
- sb_t200 = [self, *t200]
- kw = {kw: 2}
-
- a0 = :a0.to_proc
- a1 = :a1.to_proc
- s = :s.to_proc
- b = :b.to_proc
- sb = :sb.to_proc
-benchmark:
- symproc_simple_0: |
- a0.(self)
- symproc_simple_1: |
- a1.(self, 1)
- symproc_simple_0_splat: |
- a0.(self, *t0)
- symproc_simple_1_splat: |
- a1.(self, *t1)
- symproc_simple_0_splat_comb: |
- a0.(*a0_t0)
- symproc_simple_1_splat_comb: |
- a1.(*a1_t1)
- symproc_no_splat: |
- s.(self)
- symproc_0_splat: |
- s.(self, *t0)
- symproc_1_splat: |
- s.(self, *t1)
- symproc_10_splat: |
- s.(self, *t10)
- symproc_200_splat: |
- s.(self, *t200)
- symproc_0_splat_comb: |
- s.(*s_t0)
- symproc_1_splat_comb: |
- s.(*s_t1)
- symproc_10_splat_comb: |
- s.(*s_t10)
- symproc_200_splat_comb: |
- s.(*s_t200)
- symproc_kw: |
- b.(self, kw: 1)
- symproc_no_kw: |
- b.(self)
- symproc_kw_splat: |
- b.(self, **kw)
- symproc_0_splat_kw: |
- sb.(self, *t0, **kw)
- symproc_1_splat_kw: |
- sb.(self, *t1, **kw)
- symproc_10_splat_kw: |
- sb.(self, *t10, **kw)
- symproc_200_splat_kw: |
- sb.(self, *t200, **kw)
- symproc_0_splat_comb_kw: |
- sb.(*sb_t0, **kw)
- symproc_1_splat_comb_kw: |
- sb.(*sb_t1, **kw)
- symproc_10_splat_comb_kw: |
- sb.(*sb_t10, **kw)
- symproc_200_splat_comb_kw: |
- sb.(*sb_t200, **kw)
-loop_count: 1000000
diff --git a/benchmark/vm_ivar_ic_miss.yml b/benchmark/vm_ivar_ic_miss.yml
deleted file mode 100644
index 944fb1a9e6..0000000000
--- a/benchmark/vm_ivar_ic_miss.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-prelude: |
- class Foo
- def initialize diverge
- if diverge
- @a = 1
- end
-
- @a0 = @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 = @a31 = @a32 = @a33 = @a34 = @a35 = @a36 = @a37 = @a38 = @a39 = @a40 = @a41 = @a42 = @a43 = @a44 = @a45 = @a46 = @a47 = @a48 = @a49 = @a50 = @a51 = @a52 = @a53 = @a54 = @a55 = @a56 = @a57 = @a58 = @a59 = @a60 = @a61 = @a62 = @a63 = @a64 = @a65 = @a66 = @a67 = @a68 = @a69 = @a70 = @a71 = @a72 = @a73 = @a74 = @b = 1
- end
-
- def b; @b; end
- end
-
- a = Foo.new false
- b = Foo.new true
-benchmark:
- vm_ivar_ic_miss: |
- a.b
- b.b
-loop_count: 30000000
diff --git a/benchmark/vm_ivar_memoize.yml b/benchmark/vm_ivar_memoize.yml
deleted file mode 100644
index 90f6b07f05..0000000000
--- a/benchmark/vm_ivar_memoize.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-prelude: |
- IVARS = 60
- class Record
- def initialize(offset = false)
- @offset = 1 if offset
- @first = 0
- IVARS.times do |i|
- instance_variable_set("@ivar_#{i}", i)
- end
- end
-
- def first
- @first
- end
-
- def lazy_set
- @lazy_set ||= 123
- end
-
- def undef
- @undef
- end
- end
-
- Record.new # Need one alloc to right size
-
- BASE = Record.new
- LAZY = Record.new
- LAZY.lazy_set
-
- class Miss < Record
- @first = 0
- IVARS.times do |i|
- instance_variable_set("@i_#{i}", i)
- end
- end
-
- Miss.new # Need one alloc to right size
- MISS = Miss.new
-
- DIVERGENT = Record.new(true)
-
-benchmark:
- vm_ivar_stable_shape: |
- BASE.first
- BASE.first
- BASE.first
- BASE.first
- BASE.first
- BASE.first
- vm_ivar_memoize_unstable_shape: |
- BASE.first
- LAZY.first
- BASE.first
- LAZY.first
- BASE.first
- LAZY.first
- vm_ivar_memoize_unstable_shape_miss: |
- BASE.first
- MISS.first
- BASE.first
- MISS.first
- BASE.first
- MISS.first
- vm_ivar_unstable_undef: |
- BASE.undef
- LAZY.undef
- BASE.undef
- LAZY.undef
- BASE.undef
- LAZY.undef
- vm_ivar_divergent_shape: |
- BASE.first
- DIVERGENT.first
- BASE.first
- DIVERGENT.first
- BASE.first
- DIVERGENT.first
- vm_ivar_divergent_shape_imbalanced: |
- BASE.first
- DIVERGENT.first
- DIVERGENT.first
- DIVERGENT.first
- DIVERGENT.first
- DIVERGENT.first
diff --git a/benchmark/vm_method_splat_calls.yml b/benchmark/vm_method_splat_calls.yml
deleted file mode 100644
index f2f366e99c..0000000000
--- a/benchmark/vm_method_splat_calls.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-prelude: |
- def f(x=0, y: 0) end
- a = [1]
- ea = []
- kw = {y: 1}
- b = lambda{}
-benchmark:
- arg_splat: "f(1, *ea)"
- arg_splat_block: "f(1, *ea, &b)"
- splat_kw_splat: "f(*a, **kw)"
- splat_kw_splat_block: "f(*a, **kw, &b)"
- splat_kw: "f(*a, y: 1)"
- splat_kw_block: "f(*a, y: 1, &b)"
diff --git a/benchmark/vm_send_cfunc.yml b/benchmark/vm_send_cfunc.yml
index 6f12b65176..b114ac317d 100644
--- a/benchmark/vm_send_cfunc.yml
+++ b/benchmark/vm_send_cfunc.yml
@@ -1,14 +1,3 @@
-prelude: |
- ary = []
- kw = {a: 1}
- empty_kw = {}
- kw_ary = [Hash.ruby2_keywords_hash(a: 1)]
- empty_kw_ary = [Hash.ruby2_keywords_hash({})]
benchmark:
- vm_send_cfunc: itself
- vm_send_cfunc_splat: itself(*ary)
- vm_send_cfunc_splat_kw_hash: equal?(*kw_ary)
- vm_send_cfunc_splat_empty_kw_hash: itself(*empty_kw_ary)
- vm_send_cfunc_splat_kw: equal?(*ary, **kw)
- vm_send_cfunc_splat_empty_kw: itself(*ary, **empty_kw)
-loop_count: 20000000
+ vm_send_cfunc: self.class
+loop_count: 100000000
diff --git a/bignum.c b/bignum.c
index e9bf37d206..cb2c3b6f07 100644
--- a/bignum.c
+++ b/bignum.c
@@ -48,14 +48,6 @@
#include "ruby/util.h"
#include "ruby_assert.h"
-static const bool debug_integer_pack = (
-#ifdef DEBUG_INTEGER_PACK
- DEBUG_INTEGER_PACK+0
-#else
- RUBY_DEBUG
-#endif
- ) != 0;
-
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
#ifndef SIZEOF_BDIGIT_DBL
@@ -1057,13 +1049,15 @@ integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int *
if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
- if (debug_integer_pack) {
+#ifdef DEBUG_INTEGER_PACK
+ {
int nlp_bits1;
size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
assert(num_bdigits == num_bdigits1);
assert(*nlp_bits_ret == nlp_bits1);
(void)num_bdigits1;
}
+#endif
}
else {
num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
@@ -3029,8 +3023,7 @@ rb_big_resize(VALUE big, size_t len)
static VALUE
bignew_1(VALUE klass, size_t len, int sign)
{
- NEWOBJ_OF(big, struct RBignum, klass,
- T_BIGNUM | (RGENGC_WB_PROTECTED_BIGNUM ? FL_WB_PROTECTED : 0), sizeof(struct RBignum), 0);
+ NEWOBJ_OF(big, struct RBignum, klass, T_BIGNUM | (RGENGC_WB_PROTECTED_BIGNUM ? FL_WB_PROTECTED : 0));
VALUE bigv = (VALUE)big;
BIGNUM_SET_SIGN(bigv, sign);
if (len <= BIGNUM_EMBED_LEN_MAX) {
@@ -3429,13 +3422,15 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
if (numbytes <= SIZE_MAX / CHAR_BIT) {
numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
- if (debug_integer_pack) {
+#ifdef DEBUG_INTEGER_PACK
+ {
size_t numwords0, nlz_bits0;
numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
assert(numwords0 == numwords);
assert(nlz_bits0 == nlz_bits);
(void)numwords0;
}
+#endif
}
else {
numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
@@ -4546,7 +4541,7 @@ rb_uint128t2big(uint128_t n)
return big;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_int128t2big(int128_t n)
{
int neg = 0;
diff --git a/bin/gem b/bin/gem
index 3ac1d9e623..1c16ea7ddd 100755
--- a/bin/gem
+++ b/bin/gem
@@ -1,6 +1,4 @@
#!/usr/bin/env ruby
-# frozen_string_literal: true
-
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb
index a34527d2fa..f9b3e919b8 100755
--- a/bootstraptest/runner.rb
+++ b/bootstraptest/runner.rb
@@ -118,7 +118,7 @@ BT = Class.new(bt) do
r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
end
- rescue
+ rescue => e
r.close if r
else
r.close_on_exec = true
@@ -552,13 +552,8 @@ class Assertion < Struct.new(:src, :path, :lineno, :proc)
filename = "bootstraptest.#{self.path}_#{self.lineno}_#{self.id}.rb"
File.open(filename, 'w') {|f|
f.puts "#frozen_string_literal:true" if frozen_string_literal
- if $stress
- f.puts "GC.stress = true" if $stress
- else
- f.puts ""
- end
- f.puts "class BT_Skip < Exception; end; def skip(msg) = raise(BT_Skip, msg.to_s)"
- f.puts "print(begin; #{self.src}; rescue BT_Skip; $!.message; end)"
+ f.puts "GC.stress = true" if $stress
+ f.puts "print(begin; #{self.src}; end)"
}
filename
end
@@ -674,7 +669,7 @@ end
def assert_finish(timeout_seconds, testsrc, message = '')
add_assertion testsrc, -> as do
- if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # for --jit-wait
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
timeout_seconds *= 3
end
@@ -789,9 +784,4 @@ def check_coredump
end
end
-def rjit_enabled?
- # Don't check `RubyVM::RJIT.enabled?`. On btest-bruby, target Ruby != runner Ruby.
- ENV.fetch('RUN_OPTS', '').include?('rjit')
-end
-
exit main
diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb
index 47e2924846..a9f389c673 100644
--- a/bootstraptest/test_eval.rb
+++ b/bootstraptest/test_eval.rb
@@ -227,16 +227,6 @@ assert_equal %q{[10, main]}, %q{
}, '[ruby-dev:31372]'
end
-assert_normal_exit %{
- $stderr = STDOUT
- 5000.times do
- begin
- eval "0 rescue break"
- rescue SyntaxError
- end
- end
-}
-
assert_normal_exit %q{
$stderr = STDOUT
class Foo
diff --git a/bootstraptest/test_gc.rb b/bootstraptest/test_gc.rb
index 17bc497822..eb68c9845e 100644
--- a/bootstraptest/test_gc.rb
+++ b/bootstraptest/test_gc.rb
@@ -14,7 +14,7 @@ ms = "a".."k"
o.send(meth)
end
end
-}, '[ruby-dev:39453]' unless rjit_enabled? # speed up RJIT CI
+}, '[ruby-dev:39453]'
assert_normal_exit %q{
a = []
diff --git a/bootstraptest/test_insns.rb b/bootstraptest/test_insns.rb
index d2e799f855..91fba9b011 100644
--- a/bootstraptest/test_insns.rb
+++ b/bootstraptest/test_insns.rb
@@ -214,11 +214,9 @@ tests = [
'true'.freeze
},
- [ 'opt_newarray_send', %q{ ![ ].hash.nil? }, ],
-
- [ 'opt_newarray_send', %q{ [ ].max.nil? }, ],
- [ 'opt_newarray_send', %q{ [1, x = 2, 3].max == 3 }, ],
- [ 'opt_newarray_send', <<-'},', ], # {
+ [ 'opt_newarray_max', %q{ [ ].max.nil? }, ],
+ [ 'opt_newarray_max', %q{ [1, x = 2, 3].max == 3 }, ],
+ [ 'opt_newarray_max', <<-'},', ], # {
class Array
def max
true
@@ -226,9 +224,9 @@ tests = [
end
[1, x = 2, 3].max
},
- [ 'opt_newarray_send', %q{ [ ].min.nil? }, ],
- [ 'opt_newarray_send', %q{ [3, x = 2, 1].min == 1 }, ],
- [ 'opt_newarray_send', <<-'},', ], # {
+ [ 'opt_newarray_min', %q{ [ ].min.nil? }, ],
+ [ 'opt_newarray_min', %q{ [3, x = 2, 1].min == 1 }, ],
+ [ 'opt_newarray_min', <<-'},', ], # {
class Array
def min
true
diff --git a/bootstraptest/test_load.rb b/bootstraptest/test_load.rb
index 3253582a32..e63c93a8f4 100644
--- a/bootstraptest/test_load.rb
+++ b/bootstraptest/test_load.rb
@@ -12,7 +12,7 @@ assert_equal 'ok', %q{
}
}.map {|t| t.value }
vs[0] == M && vs[1] == M ? :ok : :ng
-}, '[ruby-dev:32048]' unless ENV.fetch('RUN_OPTS', '').include?('rjit') # Thread seems to be switching during JIT. To be fixed later.
+}, '[ruby-dev:32048]'
assert_equal 'ok', %q{
%w[a a/foo b].each {|d| Dir.mkdir(d)}
diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb
index 964bf39d98..04c9eb2d11 100644
--- a/bootstraptest/test_method.rb
+++ b/bootstraptest/test_method.rb
@@ -1190,12 +1190,3 @@ assert_equal 'DC', %q{
test2 o1, [], block
$result.join
}
-
-assert_equal 'ok', %q{
- def foo
- binding
- ["ok"].first
- end
- foo
- foo
-}, '[Bug #20178]'
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index ea7c2c197d..67e66b03ee 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -283,7 +283,9 @@ assert_equal 30.times.map { 'ok' }.to_s, %q{
30.times.map{|i|
test i
}
-} unless (ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') # https://bugs.ruby-lang.org/issues/17878
+} unless ENV['RUN_OPTS'] =~ /--mjit-call-threshold=5/ || # This always fails with --mjit-wait --mjit-call-threshold=5
+ (ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') || # https://bugs.ruby-lang.org/issues/17878
+ true # too flaky everywhere http://ci.rvm.jp/results/trunk@ruby-sp1/4321096
# Exception for empty select
assert_match /specify at least one ractor/, %q{
@@ -514,9 +516,9 @@ assert_equal '[true, true, true]', %q{
end
}
received = []
- taken = []
+ take = []
yielded = []
- until received.size == RN && taken.size == RN && yielded.size == RN
+ until rs.empty?
r, v = Ractor.select(CR, *rs, yield_value: 'yield')
case r
when :receive
@@ -524,17 +526,11 @@ assert_equal '[true, true, true]', %q{
when :yield
yielded << v
else
- taken << v
+ take << v
rs.delete r
end
end
- r = [received == ['sendyield'] * RN,
- yielded == [nil] * RN,
- taken == ['take'] * RN,
- ]
-
- STDERR.puts [received, yielded, taken].inspect
- r
+ [received.all?('sendyield'), yielded.all?(nil), take.all?('take')]
}
# multiple Ractors can send to one Ractor
@@ -1401,7 +1397,7 @@ assert_equal '[false, false, true, true]', %q{
}
# TracePoint with normal Proc should be Ractor local
-assert_equal '[6, 10]', %q{
+assert_equal '[4, 8]', %q{
rs = []
TracePoint.new(:line){|tp| rs << tp.lineno if tp.path == __FILE__}.enable do
Ractor.new{ # line 4
@@ -1476,6 +1472,21 @@ assert_equal "#{N}#{N}", %Q{
}.map{|r| r.take}.join
}
+# enc_table
+assert_equal "100", %Q{
+ Ractor.new do
+ loop do
+ Encoding.find("test-enc-#{rand(5_000)}").inspect
+ rescue ArgumentError => e
+ end
+ end
+
+ src = Encoding.find("UTF-8")
+ 100.times{|i|
+ src.replicate("test-enc-\#{i}")
+ }
+}
+
# Generic ivtbl
n = N/2
assert_equal "#{n}#{n}", %Q{
@@ -1494,9 +1505,8 @@ assert_equal "#{n}#{n}", %Q{
# NameError
assert_equal "ok", %q{
- obj = "".freeze # NameError refers the receiver indirectly
begin
- obj.bar
+ bar
rescue => err
end
begin
@@ -1532,7 +1542,7 @@ assert_equal "ok", %q{
1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
"ok"
-} unless ENV['RUN_OPTS'] =~ /rjit/ || ENV.key?('CI') # flaky
+}
assert_equal "ok", %q{
def foo(*); ->{ super }; end
@@ -1570,7 +1580,6 @@ assert_equal "ok", %q{
end
}
-# check method cache invalidation
assert_equal "ok", %q{
module M
def foo
@@ -1610,166 +1619,10 @@ assert_equal "ok", %q{
"ok"
}
-# check method cache invalidation
-assert_equal 'true', %q{
- class C1; def self.foo = 1; end
- class C2; def self.foo = 2; end
- class C3; def self.foo = 3; end
- class C4; def self.foo = 5; end
- class C5; def self.foo = 7; end
- class C6; def self.foo = 11; end
- class C7; def self.foo = 13; end
- class C8; def self.foo = 17; end
-
- LN = 10_000
- RN = 10
- CS = [C1, C2, C3, C4, C5, C6, C7, C8]
- rs = RN.times.map{|i|
- Ractor.new(CS.shuffle){|cs|
- LN.times.sum{
- cs.inject(1){|r, c| r * c.foo} # c.foo invalidates method cache entry
- }
- }
- }
-
- n = CS.inject(1){|r, c| r * c.foo} * LN
- rs.map{|r| r.take} == Array.new(RN){n}
-}
-
-# check experimental warning
assert_match /\Atest_ractor\.rb:1:\s+warning:\s+Ractor is experimental/, %q{
Warning[:experimental] = $VERBOSE = true
STDERR.reopen(STDOUT)
eval("Ractor.new{}.take", nil, "test_ractor.rb", 1)
}
-# check moved object
-assert_equal 'ok', %q{
- r = Ractor.new do
- Ractor.receive
- GC.start
- :ok
- end
-
- obj = begin
- raise
- rescue => e
- e = Marshal.load(Marshal.dump(e))
- end
-
- r.send obj, move: true
- r.take
-}
-
-## Ractor::Selector
-
-# Selector#empty? returns true
-assert_equal 'true', %q{
- skip true unless defined? Ractor::Selector
-
- s = Ractor::Selector.new
- s.empty?
-}
-
-# Selector#empty? returns false if there is target ractors
-assert_equal 'false', %q{
- skip false unless defined? Ractor::Selector
-
- s = Ractor::Selector.new
- s.add Ractor.new{}
- s.empty?
-}
-
-# Selector#clear removes all ractors from the waiting list
-assert_equal 'true', %q{
- skip true unless defined? Ractor::Selector
-
- s = Ractor::Selector.new
- s.add Ractor.new{10}
- s.add Ractor.new{20}
- s.clear
- s.empty?
-}
-
-# Selector#wait can wait multiple ractors
-assert_equal '[10, 20, true]', %q{
- skip [10, 20, true] unless defined? Ractor::Selector
-
- s = Ractor::Selector.new
- s.add Ractor.new{10}
- s.add Ractor.new{20}
- r, v = s.wait
- vs = []
- vs << v
- r, v = s.wait
- vs << v
- [*vs.sort, s.empty?]
-} if defined? Ractor::Selector
-
-# Selector#wait can wait multiple ractors with receiving.
-assert_equal '30', %q{
- skip 30 unless defined? Ractor::Selector
-
- RN = 30
- rs = RN.times.map{
- Ractor.new{ :v }
- }
- s = Ractor::Selector.new(*rs)
-
- results = []
- until s.empty?
- results << s.wait
-
- # Note that s.wait can raise an exception because other Ractors/Threads
- # can take from the same ractors in the waiting set.
- # In this case there is no other takers so `s.wait` doesn't raise an error.
- end
-
- results.size
-} if defined? Ractor::Selector
-
-# Selector#wait can support dynamic addition
-yjit_enabled = ENV.key?('RUBY_YJIT_ENABLE') || ENV.fetch('RUN_OPTS', '').include?('yjit') || BT.ruby.include?('yjit')
-assert_equal '600', %q{
- skip 600 unless defined? Ractor::Selector
-
- RN = 100
- s = Ractor::Selector.new
- rs = RN.times.map{
- Ractor.new{
- Ractor.main << Ractor.new{ Ractor.yield :v3; :v4 }
- Ractor.main << Ractor.new{ Ractor.yield :v5; :v6 }
- Ractor.yield :v1
- :v2
- }
- }
-
- rs.each{|r| s.add(r)}
- h = {v1: 0, v2: 0, v3: 0, v4: 0, v5: 0, v6: 0}
-
- loop do
- case s.wait receive: true
- in :receive, r
- s.add r
- in r, v
- h[v] += 1
- break if h.all?{|k, v| v == RN}
- end
- end
-
- h.sum{|k, v| v}
-} unless yjit_enabled # http://ci.rvm.jp/results/trunk-yjit@ruby-sp2-docker/4466770
-
-# Selector should be GCed (free'ed) without trouble
-assert_equal 'ok', %q{
- skip :ok unless defined? Ractor::Selector
-
- RN = 30
- rs = RN.times.map{
- Ractor.new{ :v }
- }
- s = Ractor::Selector.new(*rs)
- :ok
-}
-
end # if !ENV['GITHUB_WORKFLOW']
diff --git a/bootstraptest/test_rjit.rb b/bootstraptest/test_rjit.rb
deleted file mode 100644
index e123f35160..0000000000
--- a/bootstraptest/test_rjit.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# VM_CALL_OPT_SEND + VM_METHOD_TYPE_ATTRSET
-assert_equal '1', %q{
- class Foo
- attr_writer :foo
-
- def bar
- send(:foo=, 1)
- end
- end
-
- Foo.new.bar
-}
-
-# VM_CALL_OPT_SEND + OPTIMIZED_METHOD_TYPE_CALL
-assert_equal 'foo', %q{
- def bar(&foo)
- foo.send(:call)
- end
-
- bar { :foo }
-}
-
-# VM_CALL_OPT_SEND + OPTIMIZED_METHOD_TYPE_STRUCT_AREF
-assert_equal 'bar', %q{
- def bar(foo)
- foo.send(:bar)
- end
-
- bar(Struct.new(:bar).new(:bar))
-}
-
-# kwargs default w/ checkkeyword + locals (which shouldn't overwrite unspecified_bits)
-assert_equal '1', %q{
- def foo(bar: 1.to_s)
- _ = 1
- bar
- end
-
- def entry
- foo
- end
-
- entry
-}
-
-# Updating local type in Context
-assert_normal_exit %q{
- def foo(flag, object)
- klass = if flag
- object
- end
- klass ||= object
- return klass.new
- end
-
- foo(false, Object)
- foo(true, Object)
-}
diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb
index 59fdae651f..948e2d7809 100644
--- a/bootstraptest/test_syntax.rb
+++ b/bootstraptest/test_syntax.rb
@@ -535,8 +535,8 @@ assert_syntax_error "unterminated string meets end of file", '().."', '[ruby-dev
assert_equal %q{[]}, %q{$&;[]}, '[ruby-dev:31068]'
assert_syntax_error "syntax error, unexpected *, expecting '}'", %q{{*0}}, '[ruby-dev:31072]'
assert_syntax_error "`@0' is not allowed as an instance variable name", %q{@0..0}, '[ruby-dev:31095]'
-assert_syntax_error "`$00' is not allowed as a global variable name", %q{$00..0}, '[ruby-dev:31100]'
-assert_syntax_error "`$00' is not allowed as a global variable name", %q{0..$00=1}
+assert_syntax_error "identifier $00 is not valid to get", %q{$00..0}, '[ruby-dev:31100]'
+assert_syntax_error "identifier $00 is not valid to set", %q{0..$00=1}
assert_equal %q{0}, %q{[*0];0}, '[ruby-dev:31102]'
assert_syntax_error "syntax error, unexpected ')'", %q{v0,(*,v1,) = 0}, '[ruby-dev:31104]'
assert_equal %q{1}, %q{
diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb
index a4d46e2f10..5361828403 100644
--- a/bootstraptest/test_thread.rb
+++ b/bootstraptest/test_thread.rb
@@ -242,20 +242,6 @@ assert_equal 'true', %{
end
}
-assert_equal 'true', %{
- Thread.new{}.join
- begin
- Process.waitpid2 fork{
- Thread.new{
- sleep 0.1
- }.join
- }
- true
- rescue NotImplementedError
- true
- end
-}
-
assert_equal 'ok', %{
open("zzz_t1.rb", "w") do |f|
f.puts <<-END
@@ -303,7 +289,7 @@ assert_normal_exit %q{
}.each {|t|
t.join
}
-} unless rjit_enabled? # flaky
+}
assert_equal 'ok', %q{
def m
@@ -497,7 +483,7 @@ assert_equal 'foo', %q{
[th1, th2].each {|t| t.join }
GC.start
f.call.source
-} unless rjit_enabled? # flaky
+}
assert_normal_exit %q{
class C
def inspect
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 7266587707..5c655b8f25 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1,267 +1,3 @@
-# regression test for popping before side exit
-assert_equal "ok", %q{
- def foo(a, *) = a
-
- def call(args, &)
- foo(1) # spill at where the block arg will be
- foo(*args, &)
- end
-
- call([1, 2])
-
- begin
- call([])
- rescue ArgumentError
- :ok
- end
-}
-
-# regression test for send processing before side exit
-assert_equal "ok", %q{
- def foo(a, *) = :foo
-
- def call(args)
- send(:foo, *args)
- end
-
- call([1, 2])
-
- begin
- call([])
- rescue ArgumentError
- :ok
- end
-}
-
-# test discarding extra yield arguments
-assert_equal "2210150001501015", %q{
- def splat_kw(ary) = yield *ary, a: 1
-
- def splat(ary) = yield *ary
-
- def kw = yield 1, 2, a: 0
-
- def simple = yield 0, 1
-
- def calls
- [
- splat([1, 1, 2]) { |x, y| x + y },
- splat([1, 1, 2]) { |y, opt = raise| opt + y},
- splat_kw([0, 1]) { |a:| a },
- kw { |a:| a },
- kw { |a| a },
- simple { 5.itself },
- simple { |a| a },
- simple { |opt = raise| opt },
- simple { |*rest| rest },
- simple { |opt_kw: 5| opt_kw },
- # autosplat ineractions
- [0, 1, 2].yield_self { |a, b| [a, b] },
- [0, 1, 2].yield_self { |a, opt = raise| [a, opt] },
- [1].yield_self { |a, opt = 4| a + opt },
- ]
- end
-
- calls.join
-}
-
-# test autosplat with empty splat
-assert_equal "ok", %q{
- def m(pos, splat) = yield pos, *splat
-
- m([:ok], []) {|v0,| v0 }
-}
-
-# regression test for send stack shifting
-assert_normal_exit %q{
- def foo(a, b)
- a.singleton_methods(b)
- end
-
- def call_foo
- [1, 1, 1, 1, 1, 1, send(:foo, 1, 1)]
- end
-
- call_foo
-}
-
-# regression test for keyword splat with yield
-assert_equal 'nil', %q{
- def splat_kw(kwargs) = yield(**kwargs)
-
- splat_kw({}) { _1 }.inspect
-} unless rjit_enabled? # Not yet working on RJIT
-
-# regression test for arity check with splat
-assert_equal '[:ae, :ae]', %q{
- def req_one(a_, b_ = 1) = raise
-
- def test(args)
- req_one *args
- rescue ArgumentError
- :ae
- end
-
- [test(Array.new 5), test([])]
-} unless rjit_enabled? # Not yet working on RJIT
-
-# regression test for arity check with splat and send
-assert_equal '[:ae, :ae]', %q{
- def two_reqs(a, b_, _ = 1) = a.gsub(a, a)
-
- def test(name, args)
- send(name, *args)
- rescue ArgumentError
- :ae
- end
-
- [test(:two_reqs, ["g", nil, nil, nil]), test(:two_reqs, ["g"])]
-}
-
-# regression test for GC marking stubs in invalidated code
-assert_normal_exit %q{
- garbage = Array.new(10_000) { [] } # create garbage to cause iseq movement
- eval(<<~RUBY)
- def foo(n, garbage)
- if n == 2
- # 1.times.each to create a cfunc frame to preserve the JIT frame
- # which will return to a stub housed in an invalidated block
- return 1.times.each do
- Object.define_method(:foo) {}
- garbage.clear
- GC.verify_compaction_references(toward: :empty, expand_heap: true)
- end
- end
-
- foo(n + 1, garbage)
- end
- RUBY
-
- foo(1, garbage)
-}
-
-# regression test for callee block handler overlapping with arguments
-assert_equal '3', %q{
- def foo(_req, *args) = args.last
-
- def call_foo = foo(0, 1, 2, 3, &->{})
-
- call_foo
-}
-
-# call leaf builtin with a block argument
-assert_equal '0', "0.abs(&nil)"
-
-# regression test for invokeblock iseq guard
-assert_equal 'ok', %q{
- return :ok unless defined?(GC.compact)
- def foo = yield
- 10.times do |i|
- ret = eval("foo { #{i} }")
- raise "failed at #{i}" unless ret == i
- GC.compact
- end
- :ok
-} unless rjit_enabled? # Not yet working on RJIT
-
-# regression test for overly generous guard elision
-assert_equal '[0, :sum, 0, :sum]', %q{
- # In faulty versions, the following happens:
- # 1. YJIT puts object on the temp stack with type knowledge
- # (CArray or CString) about RBASIC_CLASS(object).
- # 2. In iter=0, due to the type knowledge, YJIT generates
- # a call to sum() without any guard on RBASIC_CLASS(object).
- # 3. In iter=1, a singleton class is added to the object,
- # changing RBASIC_CLASS(object), falsifying the type knowledge.
- # 4. Because the code from (1) has no class guard, it is incorrectly
- # reused and the wrong method is invoked.
- # Putting a literal is important for gaining type knowledge.
- def carray(iter)
- array = []
- array.sum(iter.times { def array.sum(_) = :sum })
- end
-
- def cstring(iter)
- string = ""
- string.sum(iter.times { def string.sum(_) = :sum })
- end
-
- [carray(0), carray(1), cstring(0), cstring(1)]
-}
-
-# regression test for return type of Integer#/
-# It can return a T_BIGNUM when inputs are T_FIXNUM.
-assert_equal 0x3fffffffffffffff.to_s, %q{
- def call(fixnum_min)
- (fixnum_min / -1) - 1
- end
-
- call(-(2**62))
-}
-
-# regression test for return type of String#<<
-assert_equal 'Sub', %q{
- def call(sub) = (sub << sub).itself
-
- class Sub < String; end
-
- call(Sub.new('o')).class
-}
-
-# test splat filling required and feeding rest
-assert_equal '[0, 1, 2, [3, 4]]', %q{
- public def lead_rest(a, b, *rest)
- [self, a, b, rest]
- end
-
- def call(args) = 0.lead_rest(*args)
-
- call([1, 2, 3, 4])
-}
-
-# test missing opts are nil initialized
-assert_equal '[[0, 1, nil, 3], [0, 1, nil, 3], [0, 1, nil, 3, []], [0, 1, nil, 3, []]]', %q{
- public def lead_opts(a, b=binding.local_variable_get(:c), c=3)
- [self, a, b, c]
- end
-
- public def opts_rest(a=raise, b=binding.local_variable_get(:c), c=3, *rest)
- [self, a, b, c, rest]
- end
-
- def call(args)
- [
- 0.lead_opts(1),
- 0.lead_opts(*args),
-
- 0.opts_rest(1),
- 0.opts_rest(*args),
- ]
- end
-
- call([1])
-}
-
-# test filled optionals with unspecified keyword param
-assert_equal 'ok', %q{
- def opt_rest_opt_kw(_=1, *, k: :ok) = k
-
- def call = opt_rest_opt_kw(0)
-
- call
-}
-
-# test splat empty array with rest param
-assert_equal '[0, 1, 2, []]', %q{
- public def foo(a=1, b=2, *rest)
- [self, a, b, rest]
- end
-
- def call(args) = 0.foo(*args)
-
- call([])
-}
-
# Regression test for yielding with autosplat to block with
# optional parameters. https://github.com/Shopify/yjit/issues/313
assert_equal '[:a, :b, :a, :b]', %q{
@@ -290,7 +26,7 @@ assert_equal '[:ok]', %q{
# Used to crash due to GC run in rb_ensure_iv_list_size()
# not marking the newly allocated [:ok].
RegressionTest.new.extender.itself
-} unless rjit_enabled? # Skip on RJIT since this uncovers a crash
+}
assert_equal 'true', %q{
# regression test for tracking type of locals for too long
@@ -340,7 +76,7 @@ assert_normal_exit %q{
}
assert_normal_exit %q{
- # Test to ensure send on overridden c functions
+ # Test to ensure send on overriden c functions
# doesn't corrupt the stack
class Bar
def bar(x)
@@ -373,80 +109,6 @@ assert_equal '[nil, nil, nil, nil, nil, nil]', %q{
end
}
-assert_equal '[nil, nil, nil, nil, nil, nil]', %q{
- # Tests defined? on non-heap objects
- [NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass|
- klass.class_eval("def foo = defined?(@foo)")
- end
-
- [nil, true, false, 0xFABCAFE, 0.42, :cake].map do |instance|
- instance.foo
- instance.foo
- end
-}
-
-assert_equal '[nil, "instance-variable", nil, "instance-variable"]', %q{
- # defined? on object that changes shape between calls
- class Foo
- def foo
- defined?(@foo)
- end
-
- def add
- @foo = 1
- end
-
- def remove
- self.remove_instance_variable(:@foo)
- end
- end
-
- obj = Foo.new
- [obj.foo, (obj.add; obj.foo), (obj.remove; obj.foo), (obj.add; obj.foo)]
-}
-
-assert_equal '["instance-variable", 5]', %q{
- # defined? on object too complex for shape information
- class Foo
- def initialize
- 100.times { |i| instance_variable_set("@foo#{i}", i) }
- end
-
- def foo
- [defined?(@foo5), @foo5]
- end
- end
-
- Foo.new.foo
-}
-
-# getinstancevariable with shape too complex
-assert_normal_exit %q{
- class Foo
- def initialize
- @a = 1
- end
-
- def getter
- @foobar
- end
- end
-
- # Initialize ivars in changing order, making the Foo
- # class have shape too complex
- 100.times do |x|
- foo = Foo.new
- foo.instance_variable_set(:"@a#{x}", 1)
- foo.instance_variable_set(:"@foobar", 777)
-
- # The getter method eventually sees shape too complex
- r = foo.getter
- if r != 777
- raise "error"
- end
- end
-}
-
assert_equal '0', %q{
# This is a regression test for incomplete invalidation from
# opt_setinlinecache. This test might be brittle, so
@@ -589,6 +251,8 @@ assert_equal 'string', %q{
# Check that exceptions work when getting global variable
assert_equal 'rescued', %q{
+ Warning[:deprecated] = true
+
module Warning
def warn(message)
raise
@@ -742,45 +406,6 @@ assert_equal 'false', %q{
less_than 2
}
-# BOP redefinition works on Integer#<=
-assert_equal 'false', %q{
- def le(x, y) = x <= y
-
- le(2, 2)
-
- class Integer
- def <=(_) = false
- end
-
- le(2, 2)
-}
-
-# BOP redefinition works on Integer#>
-assert_equal 'false', %q{
- def gt(x, y) = x > y
-
- gt(3, 2)
-
- class Integer
- def >(_) = false
- end
-
- gt(3, 2)
-}
-
-# BOP redefinition works on Integer#>=
-assert_equal 'false', %q{
- def ge(x, y) = x >= y
-
- ge(2, 2)
-
- class Integer
- def >=(_) = false
- end
-
- ge(2, 2)
-}
-
# Putobject, less-than operator, fixnums
assert_equal '2', %q{
def check_index(index)
@@ -1391,18 +1016,6 @@ assert_equal '[42, :default]', %q{
]
}
-# Test default value block for Hash with opt_aref_with
-assert_equal "false", %q{
- def index_with_string(h)
- h["foo"]
- end
-
- h = Hash.new { |h, k| k.frozen? }
-
- index_with_string(h)
- index_with_string(h)
-}
-
# A regression test for making sure cfp->sp is proper when
# hitting stubs. See :stub-sp-flush:
assert_equal 'ok', %q{
@@ -2025,24 +1638,6 @@ assert_equal 'true', %q{
jittable_method
}
-# test getbyte on string class
-assert_equal '[97, :nil, 97, :nil, :raised]', %q{
- def getbyte(s, i)
- byte = begin
- s.getbyte(i)
- rescue TypeError
- :raised
- end
-
- byte || :nil
- end
-
- getbyte("a", 0)
- getbyte("a", 0)
-
- [getbyte("a", 0), getbyte("a", 1), getbyte("a", -1), getbyte("a", -2), getbyte("a", "a")]
-} unless rjit_enabled? # Not yet working on RJIT
-
# Test << operator on string subclass
assert_equal 'abab', %q{
class MyString < String; end
@@ -2409,38 +2004,6 @@ assert_equal '[:A, :Btwo]', %q{
ins.foo
}
-# invokesuper with a block
-assert_equal 'true', %q{
- class A
- def foo = block_given?
- end
-
- class B < A
- def foo = super()
- end
-
- B.new.foo { }
- B.new.foo { }
-}
-
-# invokesuper in a block
-assert_equal '[0, 2]', %q{
- class A
- def foo(x) = x * 2
- end
-
- class B < A
- def foo
- 2.times.map do |x|
- super(x)
- end
- end
- end
-
- B.new.foo
- B.new.foo
-}
-
# Call to fixnum
assert_equal '[true, false]', %q{
def is_odd(obj)
@@ -2521,18 +2084,6 @@ assert_equal '[1, 2, 3, 4, 5]', %q{
splatarray
}
-# splatkw
-assert_equal '[1, 2]', %q{
- def foo(a:) = [a, yield]
-
- def entry(&block)
- a = { a: 1 }
- foo(**a, &block)
- end
-
- entry { 2 }
-}
-
assert_equal '[1, 1, 2, 1, 2, 3]', %q{
def expandarray
arr = [1, 2, 3]
@@ -2597,17 +2148,6 @@ assert_equal '[1, 2, nil]', %q{
expandarray_rhs_too_small
}
-assert_equal '[nil, 2, nil]', %q{
- def foo(arr)
- a, b, c = arr
- end
-
- a, b, c1 = foo([0, 1])
- a, b, c2 = foo([0, 1, 2])
- a, b, c3 = foo([0, 1])
- [c1, c2, c3]
-}
-
assert_equal '[1, [2]]', %q{
def expandarray_splat
a, *b = [1, 2]
@@ -2697,7 +2237,7 @@ assert_equal '[[:c_return, :String, :string_alias, "events_to_str"]]', %q{
events.compiled(events)
events
-} unless rjit_enabled? # RJIT calls extra Ruby methods
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
# test enabling a TracePoint that targets a particular line in a C method call
assert_equal '[true]', %q{
@@ -2779,7 +2319,7 @@ assert_equal '[[:c_call, :itself]]', %q{
tp.enable { shouldnt_compile }
events
-} unless rjit_enabled? # RJIT calls extra Ruby methods
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
# test enabling c_return tracing before compiling
assert_equal '[[:c_return, :itself, main]]', %q{
@@ -2794,7 +2334,7 @@ assert_equal '[[:c_return, :itself, main]]', %q{
tp.enable { shouldnt_compile }
events
-} unless rjit_enabled? # RJIT calls extra Ruby methods
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
# test c_call invalidation
assert_equal '[[:c_call, :itself]]', %q{
@@ -3981,530 +3521,10 @@ assert_equal 'ok', %q{
cw(4)
}
-assert_equal 'threw', %q{
- def foo(args)
- wrap(*args)
- rescue ArgumentError
- 'threw'
- end
-
- def wrap(a)
- [a]
- end
-
- foo([Hash.ruby2_keywords_hash({})])
-}
-
-assert_equal 'threw', %q{
- # C call
- def bar(args)
- Array(*args)
- rescue ArgumentError
- 'threw'
- end
-
- bar([Hash.ruby2_keywords_hash({})])
-}
-
-# Test instance_of? and is_a?
-assert_equal 'true', %q{
- 1.instance_of?(Integer) && 1.is_a?(Integer)
-}
-
-# Test instance_of? and is_a? for singleton classes
-assert_equal 'true', %q{
- a = []
- def a.test = :test
- a.instance_of?(Array) && a.is_a?(Array)
-}
-
-# Test instance_of? for singleton_class
-# Yes this does really return false
-assert_equal 'false', %q{
- a = []
- def a.test = :test
- a.instance_of?(a.singleton_class)
-}
-
-# Test is_a? for singleton_class
-assert_equal 'true', %q{
- a = []
- def a.test = :test
- a.is_a?(a.singleton_class)
-}
-
-# Test send with splat to a cfunc
-assert_equal 'true', %q{
- 1.send(:==, 1, *[])
-}
-
-# Test empty splat with cfunc
-assert_equal '2', %q{
- def foo
- Integer.sqrt(4, *[])
- end
- # call twice to deal with constant exiting
- foo
- foo
-}
-
-# Test non-empty splat with cfunc
-assert_equal 'Hello World', %q{
- def bar
- args = ["Hello "]
- greeting = "World"
- greeting.insert(0, *args)
- greeting
- end
- bar
-}
-
-# Regression: this creates a temp stack with > 127 elements
-assert_normal_exit %q{
- def foo(a)
- [
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a, a, a,
- a, a, a, a, a, a, a, a,
- ]
- end
-
- def entry
- foo(1)
- end
-
- entry
-}
-
-# Test that splat and rest combined
-# properly dupe the array
-assert_equal "[]", %q{
- def foo(*rest)
- rest << 1
- end
-
- def test(splat)
- foo(*splat)
- end
-
- EMPTY = []
- custom = Object.new
- def custom.to_a
- EMPTY
- end
-
- test(custom)
- test(custom)
- EMPTY
-}
-
-# Rest with send
-assert_equal '[1, 2, 3]', %q{
- def bar(x, *rest)
- rest.insert(0, x)
- end
- send(:bar, 1, 2, 3)
-}
-
-# Fix splat block arg bad compilation
-assert_equal "foo", %q{
- def literal(*args, &block)
- s = ''.dup
- literal_append(s, *args, &block)
- s
- end
-
- def literal_append(sql, v)
- sql << v
- end
-
- literal("foo")
-}
-
-# regression test for accidentally having a parameter truncated
-# due to Rust/C signature mismatch. Used to crash with
-# > [BUG] rb_vm_insn_addr2insn: invalid insn address ...
-# or
-# > ... `Err` value: TryFromIntError(())'
-assert_normal_exit %q{
- n = 16384
- eval(
- "def foo(arg); " + "_=arg;" * n + '_=1;' + "Object; end"
- )
- foo 1
-}
-
-# Regression test for CantCompile not using starting_ctx
-assert_normal_exit %q{
- class Integer
- def ===(other)
- false
- end
- end
-
- def my_func(x)
- case x
- when 1
- 1
- when 2
- 2
- else
- 3
- end
- end
-
- my_func(1)
-}
-
-# Regression test for CantCompile not using starting_ctx
-assert_equal "ArgumentError", %q{
- def literal(*args, &block)
- s = ''.dup
- args = [1, 2, 3]
- literal_append(s, *args, &block)
- s
- end
-
- def literal_append(sql, v)
- [sql.inspect, v.inspect]
- end
-
- begin
- literal("foo")
- rescue ArgumentError
- "ArgumentError"
- end
-}
-
-# Rest with block
-# Simplified code from railsbench
-assert_equal '[{"/a"=>"b", :as=>:c, :via=>:post}, [], nil]', %q{
- def match(path, *rest, &block)
- [path, rest, block]
- end
-
- def map_method(method, args, &block)
- options = args.last
- args.pop
- options[:via] = method
- match(*args, options, &block)
- end
-
- def post(*args, &block)
- map_method(:post, args, &block)
- end
-
- post "/a" => "b", as: :c
-}
-
-# Test rest and kw_args
-assert_equal '[true, true, true, true]', %q{
- def my_func(*args, base: nil, sort: true)
- [args, base, sort]
- end
-
- def calling_my_func
- results = []
- results << (my_func("test") == [["test"], nil, true])
- results << (my_func("test", base: :base) == [["test"], :base, true])
- results << (my_func("test", sort: false) == [["test"], nil, false])
- results << (my_func("test", "other", base: :base) == [["test", "other"], :base, true])
- results
- end
- calling_my_func
-}
-
-# Test Integer#[] with 2 args
-assert_equal '0', %q{
- 3[0, 0]
-}
-
-# unspecified_bits + checkkeyword
-assert_equal '2', %q{
- def callee = 1
-
- # checkkeyword should see unspecified_bits=0 (use bar), not Integer 1 (set bar = foo).
- def foo(foo, bar: foo) = bar
-
- def entry(&block)
- # write 1 at stack[3]. Calling #callee spills stack[3].
- 1 + (1 + (1 + (1 + callee)))
- # &block is written to a register instead of stack[3]. When &block is popped and
- # unspecified_bits is pushed, it must be written to stack[3], not to a register.
- foo(1, bar: 2, &block)
- end
-
- entry # call branch_stub_hit (spill temps)
- entry # doesn't call branch_stub_hit (not spill temps)
-}
-
-# Test rest and optional_params
-assert_equal '[true, true, true, true]', %q{
- def my_func(stuff, base=nil, sort=true, *args)
- [stuff, base, sort, args]
- end
-
- def calling_my_func
- results = []
- results << (my_func("test") == ["test", nil, true, []])
- results << (my_func("test", :base) == ["test", :base, true, []])
- results << (my_func("test", :base, false) == ["test", :base, false, []])
- results << (my_func("test", :base, false, "other", "other") == ["test", :base, false, ["other", "other"]])
- results
- end
- calling_my_func
-}
-
-# Test rest and optional_params and splat
-assert_equal '[true, true, true, true, true]', %q{
- def my_func(stuff, base=nil, sort=true, *args)
- [stuff, base, sort, args]
- end
-
- def calling_my_func
- results = []
- splat = ["test"]
- results << (my_func(*splat) == ["test", nil, true, []])
- splat = [:base]
- results << (my_func("test", *splat) == ["test", :base, true, []])
- splat = [:base, false]
- results << (my_func("test", *splat) == ["test", :base, false, []])
- splat = [:base, false, "other", "other"]
- results << (my_func("test", *splat) == ["test", :base, false, ["other", "other"]])
- splat = ["test", :base, false, "other", "other"]
- results << (my_func(*splat) == ["test", :base, false, ["other", "other"]])
- results
- end
- calling_my_func
-}
+assert_normal_exit %{
+ class Bug20997
+ def foo(&) = self.class.name(&)
-# Regression test: rest and optional and splat
-assert_equal 'true', %q{
- def my_func(base=nil, *args)
- [base, args]
- end
-
- def calling_my_func
- array = []
- my_func(:base, :rest1, *array) == [:base, [:rest1]]
- end
-
- calling_my_func
-}
-
-# Fix failed case for large splat
-assert_equal 'true', %q{
- def d(a, b=:b)
- end
-
- def calling_func
- ary = 1380888.times;
- d(*ary)
- end
- begin
- calling_func
- rescue ArgumentError
- true
- end
-} unless rjit_enabled? # Not yet working on RJIT
-
-# Regression test: register allocator on expandarray
-assert_equal '[]', %q{
- func = proc { [] }
- proc do
- _x, _y = func.call
- end.call
-}
-
-# Catch TAG_BREAK in a non-FINISH frame with JIT code
-assert_equal '1', %q{
- def entry
- catch_break
- end
-
- def catch_break
- while_true do
- break
- end
- 1
- end
-
- def while_true
- while true
- yield
- end
- end
-
- entry
-}
-
-assert_equal '6', %q{
- class Base
- def number = 1 + yield
- end
-
- class Sub < Base
- def number = super + 2
- end
-
- Sub.new.number { 3 }
-}
-
-# Integer multiplication and overflow
-assert_equal '[6, -6, 9671406556917033397649408, -9671406556917033397649408, 21267647932558653966460912964485513216]', %q{
- def foo(a, b)
- a * b
- end
-
- r1 = foo(2, 3)
- r2 = foo(2, -3)
- r3 = foo(2 << 40, 2 << 41)
- r4 = foo(2 << 40, -2 << 41)
- r5 = foo(1 << 62, 1 << 62)
-
- [r1, r2, r3, r4, r5]
-}
-
-# Integer multiplication and overflow (minimized regression test from test-basic)
-assert_equal '8515157028618240000', %q{2128789257154560000 * 4}
-
-# Inlined method calls
-assert_equal 'nil', %q{
- def putnil = nil
- def entry = putnil
- entry.inspect
-}
-assert_equal '1', %q{
- def putobject_1 = 1
- def entry = putobject_1
- entry
-}
-assert_equal 'false', %q{
- def putobject(_unused_arg1) = false
- def entry = putobject(nil)
- entry
-}
-assert_equal 'true', %q{
- def entry = yield
- entry { true }
-}
-
-assert_normal_exit %q{
- ivars = 1024.times.map { |i| "@iv_#{i} = #{i}\n" }.join
- Foo = Class.new
- Foo.class_eval "def initialize() #{ivars} end"
- Foo.new
-}
-
-assert_equal '0', %q{
- def spill
- 1.to_i # not inlined
- end
-
- def inline(_stack1, _stack2, _stack3, _stack4, _stack5)
- 0 # inlined
- end
-
- def entry
- # RegTemps is 00111110 prior to the #inline call.
- # Its return value goes to stack_idx=0, which conflicts with stack_idx=5.
- inline(spill, 2, 3, 4, 5)
- end
-
- entry
-}
-
-# Integer succ and overflow
-assert_equal '[2, 4611686018427387904]', %q{
- [1.succ, 4611686018427387903.succ]
-}
-
-# Integer right shift
-assert_equal '[0, 1, -4]', %q{
- [0 >> 1, 2 >> 1, -7 >> 1]
-}
-
-assert_equal '[nil, "yield"]', %q{
- def defined_yield = defined?(yield)
- [defined_yield, defined_yield {}]
-}
-
-# splat with ruby2_keywords into rest parameter
-assert_equal '[[{:a=>1}], {}]', %q{
- ruby2_keywords def foo(*args) = args
-
- def bar(*args, **kw) = [args, kw]
-
- def pass_bar(*args) = bar(*args)
-
- def body
- args = foo(a: 1)
- pass_bar(*args)
- end
-
- body
-}
-
-# regression test for splatting empty array to cfunc
-assert_normal_exit %q{
- def test_body(args) = Array(1, *args)
- test_body([])
- 0x100.times do
- array = Array.new(100)
- array.clear
- test_body(array)
+ new.foo
end
}
-
-# compiling code shouldn't emit warnings as it may call into more Ruby code
-assert_equal 'ok', <<~'RUBY'
- # [Bug #20522]
- $VERBOSE = true
- Warning[:performance] = true
-
- module StrictWarnings
- def warn(msg, **)
- raise msg
- end
- end
- Warning.singleton_class.prepend(StrictWarnings)
-
- class A
- def compiled_method(is_private)
- @some_ivar = is_private
- end
- end
-
- shape_max_variations = 8
- if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS) && RubyVM::Shape::SHAPE_MAX_VARIATIONS != shape_max_variations
- raise "Expected SHAPE_MAX_VARIATIONS to be #{shape_max_variations}, got: #{RubyVM::Shape::SHAPE_MAX_VARIATIONS}"
- end
-
- 100.times do |i|
- klass = Class.new(A)
- (shape_max_variations - 1).times do |j|
- obj = klass.new
- obj.instance_variable_set("@base_#{i}", 42)
- obj.instance_variable_set("@ivar_#{j}", 42)
- end
- obj = klass.new
- obj.instance_variable_set("@base_#{i}", 42)
- begin
- obj.compiled_method(true)
- rescue
- # expected
- end
- end
-
- :ok
-RUBY
diff --git a/builtin.c b/builtin.c
index 4fc2ab43d1..21fff95650 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3,15 +3,15 @@
#include "iseq.h"
#include "builtin.h"
-#include "builtin_binary.inc"
-
-#ifndef BUILTIN_BINARY_SIZE
+#ifdef CROSS_COMPILING
#define INCLUDED_BY_BUILTIN_C 1
#include "mini_builtin.c"
#else
+#include "builtin_binary.inc"
+
static const unsigned char *
bin4feature(const struct builtin_binary *bb, const char *feature, size_t *psize)
{
@@ -39,7 +39,7 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin
size_t size;
const unsigned char *bin = builtin_lookup(feature_name, &size);
if (! bin) {
- rb_bug("builtin_lookup: can not find %s", feature_name);
+ rb_bug("builtin_lookup: can not find %s\n", feature_name);
}
// load binary
@@ -48,7 +48,6 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin
vm->builtin_function_table = table;
vm->builtin_inline_index = 0;
const rb_iseq_t *iseq = rb_iseq_ibf_load_bytes((const char *)bin, size);
- ASSUME(iseq); // otherwise an exception should have raised
vm->builtin_function_table = NULL;
// exec
@@ -58,12 +57,6 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin
#endif
void
-rb_free_loaded_builtin_table(void)
-{
- // do nothing
-}
-
-void
Init_builtin(void)
{
// nothing
diff --git a/builtin.h b/builtin.h
index 85fd1a009a..38ad5a1629 100644
--- a/builtin.h
+++ b/builtin.h
@@ -11,13 +11,17 @@ struct rb_builtin_function {
// for load
const int index;
const char * const name;
+
+ // for jit
+ void (*compiler)(VALUE, long, unsigned, bool);
};
-#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity) {\
+#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity, _compiler) {\
.name = _i < 0 ? NULL : #_name, \
.func_ptr = (void *)_fname, \
.argc = _arity, \
.index = _i, \
+ .compiler = _compiler, \
}
void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table);
diff --git a/ccan/list/list.h b/ccan/list/list.h
index bf692a6937..30b2af04e9 100644
--- a/ccan/list/list.h
+++ b/ccan/list/list.h
@@ -635,16 +635,14 @@ static inline void ccan_list_prepend_list_(struct ccan_list_head *to,
/* internal macros, do not use directly */
#define ccan_list_for_each_off_dir_(h, i, off, dir) \
- for (i = 0, \
- i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \
+ for (i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \
(off)); \
ccan_list_node_from_off_((void *)i, (off)) != &(h)->n; \
i = ccan_list_node_to_off_(ccan_list_node_from_off_((void *)i, (off))->dir, \
(off)))
#define ccan_list_for_each_safe_off_dir_(h, i, nxt, off, dir) \
- for (i = 0, \
- i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \
+ for (i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \
(off)), \
nxt = ccan_list_node_to_off_(ccan_list_node_from_off_(i, (off))->dir, \
(off)); \
diff --git a/class.c b/class.c
index f8cf4b832a..cf0b7b821f 100644
--- a/class.c
+++ b/class.c
@@ -30,41 +30,7 @@
#include "ruby/st.h"
#include "vm_core.h"
-/* Flags of T_CLASS
- *
- * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF
- * The RCLASS_SUPERCLASSES contains the class as the last element.
- * This means that this class owns the RCLASS_SUPERCLASSES list.
- * if !SHAPE_IN_BASIC_FLAGS
- * 4-19: SHAPE_FLAG_MASK
- * Shape ID for the class.
- * endif
- */
-
-/* Flags of T_ICLASS
- *
- * 0: RICLASS_IS_ORIGIN
- * 3: RICLASS_ORIGIN_SHARED_MTBL
- * The T_ICLASS does not own the method table.
- * if !SHAPE_IN_BASIC_FLAGS
- * 4-19: SHAPE_FLAG_MASK
- * Shape ID. This is set but not used.
- * endif
- */
-
-/* Flags of T_MODULE
- *
- * 1: RMODULE_ALLOCATED_BUT_NOT_INITIALIZED
- * Module has not been initialized.
- * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF
- * See RCLASS_SUPERCLASSES_INCLUDE_SELF in T_CLASS.
- * 3: RMODULE_IS_REFINEMENT
- * Module is used for refinements.
- * if !SHAPE_IN_BASIC_FLAGS
- * 4-19: SHAPE_FLAG_MASK
- * Shape ID for the module.
- * endif
- */
+#define id_attached id__attached__
#define METACLASS_OF(k) RBASIC(k)->klass
#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
@@ -229,13 +195,22 @@ rb_class_detach_module_subclasses(VALUE klass)
static VALUE
class_alloc(VALUE flags, VALUE klass)
{
- size_t alloc_size = sizeof(struct RClass) + sizeof(rb_classext_t);
+ size_t alloc_size = sizeof(struct RClass);
+
+#if RCLASS_EXT_EMBEDDED
+ alloc_size += sizeof(rb_classext_t);
+#endif
flags &= T_MASK;
+ flags |= FL_PROMOTED1 /* start from age == 2 */;
if (RGENGC_WB_PROTECTED_CLASS) flags |= FL_WB_PROTECTED;
- NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size, 0);
+ RVARGC_NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size);
+#if RCLASS_EXT_EMBEDDED
memset(RCLASS_EXT(obj), 0, sizeof(rb_classext_t));
+#else
+ obj->ptr = ZALLOC(rb_classext_t);
+#endif
/* ZALLOC
RCLASS_CONST_TBL(obj) = 0;
@@ -248,7 +223,7 @@ class_alloc(VALUE flags, VALUE klass)
*/
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
RB_OBJ_WRITE(obj, &RCLASS_REFINED_CLASS(obj), Qnil);
- RCLASS_SET_ALLOCATOR((VALUE)obj, 0);
+ RCLASS_ALLOCATOR(obj) = 0;
return (VALUE)obj;
}
@@ -435,8 +410,7 @@ struct cvc_table_copy_ctx {
};
static enum rb_id_table_iterator_result
-cvc_table_copy(ID id, VALUE val, void *data)
-{
+cvc_table_copy(ID id, VALUE val, void *data) {
struct cvc_table_copy_ctx *ctx = (struct cvc_table_copy_ctx *)data;
struct rb_cvar_class_tbl_entry * orig_entry;
orig_entry = (struct rb_cvar_class_tbl_entry *)val;
@@ -496,7 +470,7 @@ static bool ensure_origin(VALUE klass);
/**
* If this flag is set, that module is allocated but not initialized yet.
*/
-enum {RMODULE_ALLOCATED_BUT_NOT_INITIALIZED = RUBY_FL_USER1};
+enum {RMODULE_ALLOCATED_BUT_NOT_INITIALIZED = RUBY_FL_USER5};
static inline bool
RMODULE_UNINITIALIZED(VALUE module)
@@ -539,14 +513,14 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
/* cloned flag is refer at constant inline cache
* see vm_get_const_key_cref() in vm_insnhelper.c
*/
- RCLASS_EXT(clone)->cloned = true;
- RCLASS_EXT(orig)->cloned = true;
+ FL_SET(clone, RCLASS_CLONED);
+ FL_SET(orig , RCLASS_CLONED);
if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
rb_singleton_class_attached(METACLASS_OF(clone), (VALUE)clone);
}
- RCLASS_SET_ALLOCATOR(clone, RCLASS_ALLOCATOR(orig));
+ RCLASS_ALLOCATOR(clone) = RCLASS_ALLOCATOR(orig);
copy_tables(clone, orig);
if (RCLASS_M_TBL(orig)) {
struct clone_method_arg arg;
@@ -578,14 +552,11 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
rb_bug("non iclass between module/class and origin");
}
clone_p = class_alloc(RBASIC(p)->flags, METACLASS_OF(p));
- /* We should set the m_tbl right after allocation before anything
- * that can trigger GC to avoid clone_p from becoming old and
- * needing to fire write barriers. */
- RCLASS_SET_M_TBL(clone_p, RCLASS_M_TBL(p));
RCLASS_SET_SUPER(prev_clone_p, clone_p);
prev_clone_p = clone_p;
+ RCLASS_M_TBL(clone_p) = RCLASS_M_TBL(p);
RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p);
- RCLASS_SET_ALLOCATOR(clone_p, RCLASS_ALLOCATOR(p));
+ RCLASS_ALLOCATOR(clone_p) = RCLASS_ALLOCATOR(p);
if (RB_TYPE_P(clone, T_CLASS)) {
RCLASS_SET_INCLUDER(clone_p, clone);
}
@@ -648,7 +619,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
// attached to an object other than `obj`. In which case `obj` does not have
// a material singleton class attached yet and there is no singleton class
// to clone.
- if (!(FL_TEST(klass, FL_SINGLETON) && RCLASS_ATTACHED_OBJECT(klass) == obj)) {
+ if (!(FL_TEST(klass, FL_SINGLETON) && rb_attr_get(klass, id_attached) == obj)) {
// nothing to clone
return klass;
}
@@ -670,6 +641,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
}
RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
+ RCLASS_ALLOCATOR(clone) = RCLASS_ALLOCATOR(klass);
rb_iv_tbl_copy(clone, klass);
if (RCLASS_CONST_TBL(klass)) {
struct clone_const_arg arg;
@@ -700,7 +672,7 @@ void
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
if (FL_TEST(klass, FL_SINGLETON)) {
- RCLASS_SET_ATTACHED_OBJECT(klass, obj);
+ rb_class_ivar_set(klass, id_attached, obj);
}
}
@@ -714,13 +686,13 @@ rb_singleton_class_attached(VALUE klass, VALUE obj)
static int
rb_singleton_class_has_metaclass_p(VALUE sklass)
{
- return RCLASS_ATTACHED_OBJECT(METACLASS_OF(sklass)) == sklass;
+ return rb_attr_get(METACLASS_OF(sklass), id_attached) == sklass;
}
int
rb_singleton_class_internal_p(VALUE sklass)
{
- return (RB_TYPE_P(RCLASS_ATTACHED_OBJECT(sklass), T_CLASS) &&
+ return (RB_TYPE_P(rb_attr_get(sklass, id_attached), T_CLASS) &&
!rb_singleton_class_has_metaclass_p(sklass));
}
@@ -866,27 +838,6 @@ refinement_import_methods(int argc, VALUE *argv, VALUE refinement)
}
# endif
-/*!
- *--
- * \private
- * Initializes the world of objects and classes.
- *
- * At first, the function bootstraps the class hierarchy.
- * It initializes the most fundamental classes and their metaclasses.
- * - \c BasicObject
- * - \c Object
- * - \c Module
- * - \c Class
- * After the bootstrap step, the class hierarchy becomes as the following
- * diagram.
- *
- * \image html boottime-classes.png
- *
- * Then, the function defines classes, modules and methods as usual.
- * \ingroup class
- *++
- */
-
void
Init_class_hierarchy(void)
{
@@ -959,7 +910,7 @@ rb_define_class_id(ID id, VALUE super)
* \return the value \c Class#inherited's returns
* \pre Each of \a super and \a klass must be a \c Class object.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_class_inherited(VALUE super, VALUE klass)
{
ID inherited;
@@ -1142,7 +1093,7 @@ rb_include_class_new(VALUE module, VALUE super)
{
VALUE klass = class_alloc(T_ICLASS, rb_cClass);
- RCLASS_SET_M_TBL(klass, RCLASS_M_TBL(module));
+ RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
RCLASS_SET_ORIGIN(klass, klass);
if (BUILTIN_TYPE(module) == T_ICLASS) {
@@ -1194,8 +1145,8 @@ rb_include_module(VALUE klass, VALUE module)
iclass = iclass->next;
}
- int do_include = 1;
while (iclass) {
+ int do_include = 1;
VALUE check_class = iclass->klass;
/* During lazy sweeping, iclass->klass could be a dead object that
* has not yet been swept. */
@@ -1262,7 +1213,7 @@ static int
do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super, bool check_cyclic)
{
VALUE p, iclass, origin_stack = 0;
- int method_changed = 0, add_subclass;
+ int method_changed = 0;
long origin_len;
VALUE klass_origin = RCLASS_ORIGIN(klass);
VALUE original_klass = klass;
@@ -1326,7 +1277,6 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
iclass = rb_include_class_new(module, super_class);
c = RCLASS_SET_SUPER(c, iclass);
RCLASS_SET_INCLUDER(iclass, klass);
- add_subclass = TRUE;
if (module != RCLASS_ORIGIN(module)) {
if (!origin_stack) origin_stack = rb_ary_hidden_new(2);
VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
@@ -1337,14 +1287,11 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
rb_ary_resize(origin_stack, origin_len);
- add_subclass = FALSE;
}
- if (add_subclass) {
- VALUE m = module;
- if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
- rb_module_add_to_subclasses_list(m, iclass);
- }
+ VALUE m = module;
+ if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
+ rb_module_add_to_subclasses_list(m, iclass);
if (BUILTIN_TYPE(klass) == T_MODULE && FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
VALUE refined_class =
@@ -1418,10 +1365,10 @@ ensure_origin(VALUE klass)
VALUE origin = RCLASS_ORIGIN(klass);
if (origin == klass) {
origin = class_alloc(T_ICLASS, klass);
- RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass));
RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass));
RCLASS_SET_SUPER(klass, origin);
RCLASS_SET_ORIGIN(klass, origin);
+ RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
RCLASS_M_TBL_INIT(klass);
rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass);
rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
@@ -1714,7 +1661,7 @@ rb_class_attached_object(VALUE klass)
rb_raise(rb_eTypeError, "`%"PRIsVALUE"' is not a singleton class", klass);
}
- return RCLASS_ATTACHED_OBJECT(klass);
+ return rb_attr_get(klass, id_attached);
}
static void
@@ -2243,7 +2190,7 @@ singleton_class_of(VALUE obj)
klass = METACLASS_OF(obj);
if (!(FL_TEST(klass, FL_SINGLETON) &&
- RCLASS_ATTACHED_OBJECT(klass) == obj)) {
+ rb_attr_get(klass, id_attached) == obj)) {
klass = rb_make_metaclass(obj, klass);
}
@@ -2282,7 +2229,7 @@ rb_singleton_class_get(VALUE obj)
}
klass = METACLASS_OF(obj);
if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
- if (RCLASS_ATTACHED_OBJECT(klass) != obj) return Qnil;
+ if (rb_attr_get(klass, id_attached) != obj) return Qnil;
return klass;
}
@@ -2346,7 +2293,7 @@ rb_define_attr(VALUE klass, const char *name, int read, int write)
rb_attr(klass, rb_intern(name), read, write, FALSE);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_keyword_error_new(const char *error, VALUE keys)
{
long i = 0, len = RARRAY_LEN(keys);
diff --git a/common.mk b/common.mk
index 83f10f7a58..126053c9c8 100644
--- a/common.mk
+++ b/common.mk
@@ -1,6 +1,4 @@
# -*- mode: makefile-gmake; indent-tabs-mode: t -*-
-# This fragment can be used with nmake.exe and with bsdmake.
-# Avoid features specific to GNU Make.
bin: $(PROGRAM) $(WPROGRAM)
lib: $(LIBRUBY)
@@ -45,15 +43,20 @@ RUN_OPTS = --disable-gems
# GITPULLOPTIONS = --no-tags
-PRISM_SRCDIR = $(srcdir)/prism
-INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(PRISM_SRCDIR) -I$(UNICODE_HDR_DIR) $(incflags)
+INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(UNICODE_HDR_DIR) $(incflags)
GEM_HOME =
GEM_PATH =
GEM_VENDOR =
BENCHMARK_DRIVER_GIT_URL = https://github.com/benchmark-driver/benchmark-driver
-BENCHMARK_DRIVER_GIT_REF = v0.16.3
+BENCHMARK_DRIVER_GIT_REF = v0.16.0
+SIMPLECOV_GIT_URL = https://github.com/colszowka/simplecov.git
+SIMPLECOV_GIT_REF = v0.17.0
+SIMPLECOV_HTML_GIT_URL = https://github.com/colszowka/simplecov-html.git
+SIMPLECOV_HTML_GIT_REF = v0.10.2
+DOCLIE_GIT_URL = https://github.com/ms-ati/docile.git
+DOCLIE_GIT_REF = v1.3.2
STATIC_RUBY = static-ruby
@@ -83,34 +86,6 @@ ENC_MK = enc.mk
MAKE_ENC = -f $(ENC_MK) V="$(V)" UNICODE_HDR_DIR="$(UNICODE_HDR_DIR)" \
RUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BOOTSTRAPRUBY)" $(mflags)
-PRISM_BUILD_DIR = prism
-
-PRISM_FILES = prism/api_node.$(OBJEXT) \
- prism/api_pack.$(OBJEXT) \
- prism/diagnostic.$(OBJEXT) \
- prism/encoding.$(OBJEXT) \
- prism/extension.$(OBJEXT) \
- prism/node.$(OBJEXT) \
- prism/options.$(OBJEXT) \
- prism/pack.$(OBJEXT) \
- prism/prettyprint.$(OBJEXT) \
- prism/regexp.$(OBJEXT) \
- prism/serialize.$(OBJEXT) \
- prism/token_type.$(OBJEXT) \
- prism/util/pm_buffer.$(OBJEXT) \
- prism/util/pm_char.$(OBJEXT) \
- prism/util/pm_constant_pool.$(OBJEXT) \
- prism/util/pm_list.$(OBJEXT) \
- prism/util/pm_memchr.$(OBJEXT) \
- prism/util/pm_newline_list.$(OBJEXT) \
- prism/util/pm_state_stack.$(OBJEXT) \
- prism/util/pm_string.$(OBJEXT) \
- prism/util/pm_string_list.$(OBJEXT) \
- prism/util/pm_strncasecmp.$(OBJEXT) \
- prism/util/pm_strpbrk.$(OBJEXT) \
- prism/prism.$(OBJEXT) \
- prism_init.$(OBJEXT)
-
COMMONOBJS = array.$(OBJEXT) \
ast.$(OBJEXT) \
bignum.$(OBJEXT) \
@@ -139,15 +114,13 @@ COMMONOBJS = array.$(OBJEXT) \
marshal.$(OBJEXT) \
math.$(OBJEXT) \
memory_view.$(OBJEXT) \
- rjit.$(OBJEXT) \
- rjit_c.$(OBJEXT) \
+ mjit.$(OBJEXT) \
+ mjit_c.$(OBJEXT) \
node.$(OBJEXT) \
- node_dump.$(OBJEXT) \
numeric.$(OBJEXT) \
object.$(OBJEXT) \
pack.$(OBJEXT) \
parse.$(OBJEXT) \
- parser_st.$(OBJEXT) \
proc.$(OBJEXT) \
process.$(OBJEXT) \
ractor.$(OBJEXT) \
@@ -162,7 +135,6 @@ COMMONOBJS = array.$(OBJEXT) \
regparse.$(OBJEXT) \
regsyntax.$(OBJEXT) \
ruby.$(OBJEXT) \
- ruby_parser.$(OBJEXT) \
scheduler.$(OBJEXT) \
shape.$(OBJEXT) \
signal.$(OBJEXT) \
@@ -175,6 +147,7 @@ COMMONOBJS = array.$(OBJEXT) \
thread.$(OBJEXT) \
time.$(OBJEXT) \
transcode.$(OBJEXT) \
+ transient_heap.$(OBJEXT) \
util.$(OBJEXT) \
variable.$(OBJEXT) \
version.$(OBJEXT) \
@@ -183,81 +156,13 @@ COMMONOBJS = array.$(OBJEXT) \
vm_dump.$(OBJEXT) \
vm_sync.$(OBJEXT) \
vm_trace.$(OBJEXT) \
- weakmap.$(OBJEXT) \
- $(PRISM_FILES) \
$(YJIT_OBJ) \
- $(YJIT_LIBOBJ) \
$(COROUTINE_OBJ) \
$(DTRACE_OBJ) \
$(BUILTIN_ENCOBJS) \
$(BUILTIN_TRANSOBJS) \
$(MISSING)
-$(PRISM_FILES): $(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/util/.time
-
-$(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/util/.time:
- $(Q) $(MAKEDIRS) $(@D)
- @$(NULLCMD) > $@
-
-main: $(srcdir)/lib/prism/compiler.rb
-srcs: $(srcdir)/lib/prism/compiler.rb
-$(srcdir)/lib/prism/compiler.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/compiler.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/compiler.rb $(srcdir)/lib/prism/compiler.rb
-
-main: $(srcdir)/lib/prism/dispatcher.rb
-srcs: $(srcdir)/lib/prism/dispatcher.rb
-$(srcdir)/lib/prism/dispatcher.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/dispatcher.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/dispatcher.rb $(srcdir)/lib/prism/dispatcher.rb
-
-main: $(srcdir)/lib/prism/dsl.rb
-srcs: $(srcdir)/lib/prism/dsl.rb
-$(srcdir)/lib/prism/dsl.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/dsl.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/dsl.rb $(srcdir)/lib/prism/dsl.rb
-
-main: $(srcdir)/lib/prism/mutation_compiler.rb
-srcs: $(srcdir)/lib/prism/mutation_compiler.rb
-$(srcdir)/lib/prism/mutation_compiler.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/mutation_compiler.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/mutation_compiler.rb $(srcdir)/lib/prism/mutation_compiler.rb
-
-main: $(srcdir)/lib/prism/node.rb
-srcs: $(srcdir)/lib/prism/node.rb
-$(srcdir)/lib/prism/node.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/node.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/node.rb $(srcdir)/lib/prism/node.rb
-
-main: $(srcdir)/lib/prism/serialize.rb
-srcs: $(srcdir)/lib/prism/serialize.rb
-$(srcdir)/lib/prism/serialize.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/serialize.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/serialize.rb $(srcdir)/lib/prism/serialize.rb
-
-main: $(srcdir)/lib/prism/visitor.rb
-srcs: $(srcdir)/lib/prism/visitor.rb
-$(srcdir)/lib/prism/visitor.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/visitor.rb.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/visitor.rb $(srcdir)/lib/prism/visitor.rb
-
-srcs: prism/api_node.c
-prism/api_node.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/ext/prism/api_node.c.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb ext/prism/api_node.c $@
-
-srcs: prism/ast.h
-prism/ast.h: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/include/prism/ast.h.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb include/prism/ast.h $@
-
-srcs: prism/node.c
-prism/node.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/node.c.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/node.c $@
-
-srcs: prism/prettyprint.c
-prism/prettyprint.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/prettyprint.c.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/prettyprint.c $@
-
-srcs: prism/serialize.c
-prism/serialize.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/serialize.c.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/serialize.c $@
-
-srcs: prism/token_type.c
-prism/token_type.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/token_type.c.erb
- $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/token_type.c $@
-
EXPORTOBJS = $(DLNOBJ) \
localeinit.$(OBJEXT) \
loadpath.$(OBJEXT) \
@@ -296,7 +201,7 @@ INSTALL_DATA_MODE = 0644
BOOTSTRAPRUBY_COMMAND = $(BOOTSTRAPRUBY) $(BOOTSTRAPRUBY_OPT)
TESTSDIR = $(srcdir)/test
TOOL_TESTSDIR = $(tooldir)/test
-TEST_EXCLUDES = --excludes-dir=$(TESTSDIR)/.excludes --name=!/memory_leak/
+TEST_EXCLUDES = --excludes-dir=$(TESTSDIR)/excludes --name=!/memory_leak/
TESTWORKDIR = testwork
TESTOPTS = $(RUBY_TESTOPTS)
@@ -320,7 +225,6 @@ YJIT_RUSTC_ARGS = --crate-name=yjit \
--crate-type=staticlib \
--edition=2021 \
-g \
- -C lto=thin \
-C opt-level=3 \
-C overflow-checks=on \
'--out-dir=$(CARGO_TARGET_DIR)/release/' \
@@ -331,15 +235,45 @@ all: $(SHOWFLAGS) main docs
main: $(SHOWFLAGS) exts $(ENCSTATIC:static=lib)encs
@$(NULLCMD)
-main: $(srcdir)/lib/ruby_vm/rjit/instruction.rb
-srcs: $(srcdir)/lib/ruby_vm/rjit/instruction.rb
-$(srcdir)/lib/ruby_vm/rjit/instruction.rb: $(tooldir)/insns2vm.rb $(tooldir)/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb $(srcdir)/insns.def
+main: $(srcdir)/lib/ruby_vm/mjit/instruction.rb
+srcs: $(srcdir)/lib/ruby_vm/mjit/instruction.rb
+$(srcdir)/lib/ruby_vm/mjit/instruction.rb: $(tooldir)/insns2vm.rb $(tooldir)/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb $(srcdir)/insns.def
$(ECHO) generating $@
$(Q) $(BASERUBY) -Ku $(tooldir)/insns2vm.rb --basedir="$(srcdir)" $(INSNS2VMOPT) $@
-.PHONY: rjit-bindgen
-rjit-bindgen:
- $(Q) $(BASERUBY) -rrubygems -C $(srcdir)/tool/rjit bindgen.rb $(CURDIR)
+mjit-headers: $(MJIT_SUPPORT)-mjit-headers
+no-mjit-headers: PHONY
+yes-mjit-headers: mjit_config.h PHONY
+
+mjit.$(OBJEXT): mjit_config.h
+mjit_config.h: Makefile
+
+.PHONY: mjit-bindgen
+mjit-bindgen:
+ $(Q) $(BASERUBY) -rrubygems -C $(srcdir)/tool/mjit bindgen.rb $(CURDIR)
+
+# These rules using MJIT_HEADER_SUFFIX must be in common.mk, not
+# Makefile.in, in order to override the macro in defs/universal.mk.
+
+# Other `-Dxxx`s preceding `-DMJIT_HEADER` will be removed in transform_mjit_header.rb.
+# So `-DMJIT_HEADER` should be passed first when rb_mjit_header.h is generated.
+$(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time: probes.h vm.$(OBJEXT) \
+ $(TIMESTAMPDIR)/$(arch)/.time $(tooldir)/mjit_tabs.rb $(PREP) $(RBCONFIG)
+ $(ECHO) building $(@F:.time=.h)
+ $(Q)$(MINIRUBY) $(tooldir)/mjit_tabs.rb "$(MJIT_TABS)" \
+ $(CPP) -DMJIT_HEADER $(MJIT_HEADER_FLAGS) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/vm.c $(CPPOUTFLAG)$(@F:.time=.h).new
+ $(Q) $(IFCHANGE) "--timestamp=$@" $(@F:.time=.h) $(@F:.time=.h).new
+
+$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time
+
+$(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: \
+ $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time \
+ $(tooldir)/transform_mjit_header.rb $(PREP) \
+ $(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h
+ $(ECHO) building $@
+ $(Q)$(MINIRUBY) $(tooldir)/transform_mjit_header.rb "$(CC) $(CFLAGS) -w" $(MJIT_HEADER:.h=)$(MJIT_HEADER_ARCH).h $@
+ $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR)
+ $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F)
.PHONY: showflags
exts enc trans: $(SHOWFLAGS)
@@ -395,8 +329,7 @@ configure-ext: $(EXTS_MK)
build-ext: $(EXTS_MK)
$(Q)$(MAKE) -f $(EXTS_MK) $(mflags) libdir="$(libdir)" LIBRUBY_EXTS=$(LIBRUBY_EXTS) \
- EXTENCS="$(ENCOBJS)" BASERUBY="$(BASERUBY)" MINIRUBY="$(MINIRUBY)" \
- UPDATE_LIBRARIES=no $(EXTSTATIC)
+ EXTENCS="$(ENCOBJS)" MINIRUBY="$(MINIRUBY)" UPDATE_LIBRARIES=no $(EXTSTATIC)
$(Q)$(MAKE) $(EXTS_NOTE)
exts-note: $(EXTS_MK)
@@ -439,8 +372,8 @@ Doxyfile: $(srcdir)/template/Doxyfile.tmpl $(PREP) $(tooldir)/generic_erb.rb $(R
$(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ $(srcdir)/template/Doxyfile.tmpl \
--srcdir="$(srcdir)" --miniruby="$(MINIRUBY)"
-program: $(SHOWFLAGS) $(DOT_WAIT) $(PROGRAM)
-wprogram: $(SHOWFLAGS) $(DOT_WAIT) $(WPROGRAM)
+program: $(SHOWFLAGS) $(PROGRAM)
+wprogram: $(SHOWFLAGS) $(WPROGRAM)
mini: PHONY miniruby$(EXEEXT)
$(PROGRAM) $(WPROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
@@ -461,12 +394,12 @@ ruby.imp: $(COMMONOBJS)
$(NM) -Pgp $(COMMONOBJS) | \
awk 'BEGIN{print "#!"}; $$2~/^[A-TV-Z]$$/&&$$1!~/^$(SYMBOL_PREFIX)(Init_|InitVM_|ruby_static_id_|.*_threadptr_|rb_ec_)|^\./{print $$1}'; \
($(CHDIR) $(srcdir) && \
- exec sed -n '/^RJIT_FUNC_EXPORTED/!d;N;s/.*\n\(rb_[a-zA-Z_0-9]*\).*/$(SYMBOL_PREFIX)\1/p' cont.c gc.c thread*c vm*.c) \
+ exec sed -n '/^MJIT_FUNC_EXPORTED/!d;N;s/.*\n\(rb_[a-zA-Z_0-9]*\).*/$(SYMBOL_PREFIX)\1/p' cont.c gc.c thread*c vm*.c) \
} | \
sort -u -o $@
install: install-$(INSTALLDOC)
-docs: srcs-doc $(DOCTARGETS)
+docs: $(DOCTARGETS)
pkgconfig-data: $(ruby_pc)
$(ruby_pc): $(srcdir)/template/ruby.pc.in config.status
@@ -660,24 +593,18 @@ do-install-dbg: $(PROGRAM) pre-install-dbg
post-install-dbg::
@$(NULLCMD)
-rdoc: PHONY main srcs-doc
+rdoc: PHONY main
@echo Generating RDoc documentation
$(Q) $(RDOC) --ri --op "$(RDOCOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) "$(srcdir)"
-html: PHONY main srcs-doc
+html: PHONY main
@echo Generating RDoc HTML files
$(Q) $(RDOC) --op "$(HTMLOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) "$(srcdir)"
-rdoc-coverage: PHONY main srcs-doc
+rdoc-coverage: PHONY main
@echo Generating RDoc coverage report
$(Q) $(RDOC) --quiet -C $(RDOCFLAGS) "$(srcdir)"
-undocumented: PHONY main srcs-doc
- $(Q) $(RDOC) --quiet -C $(RDOCFLAGS) "$(srcdir)" | \
- sed -n \
- -e '/^ *# in file /{' -e 's///;N;s/\n/: /p' -e '}' \
- -e 's/^ *\(.*[^ ]\) *# in file \(.*\)/\2: \1/p'
-
RDOCBENCHOUT=/tmp/rdocbench
GCBENCH_ITEM=null
@@ -712,11 +639,8 @@ clean-local:: clean-runnable
$(Q)$(RM) y.tab.c y.output encdb.h transdb.h config.log rbconfig.rb $(ruby_pc) $(COROUTINE_H:/Context.h=/.time)
$(Q)$(RM) probes.h probes.$(OBJEXT) probes.stamp ruby-glommed.$(OBJEXT) ruby.imp ChangeLog $(STATIC_RUBY)$(EXEEXT)
$(Q)$(RM) GNUmakefile.old Makefile.old $(arch)-fake.rb bisect.sh $(ENC_TRANS_D) builtin_binary.inc
- $(Q)$(RM) $(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/*/.time
-$(Q)$(RMALL) yjit/target
- -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine yjit \
- $(PRISM_BUILD_DIR)/*/ $(PRISM_BUILD_DIR) tmp \
- 2> $(NULL) || $(NULLCMD)
+ -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine yjit 2> $(NULL) || $(NULLCMD)
bin/clean-runnable:: PHONY
$(Q)$(CHDIR) bin 2>$(NULL) && $(RM) $(PROGRAM) $(WPROGRAM) $(GORUBY)$(EXEEXT) bin/*.$(DLEXT) 2>$(NULL) || $(NULLCMD)
@@ -764,6 +688,8 @@ clean-srcs-local::
$(Q)$(RM) parse.c parse.h lex.c enc/trans/newline.c revision.h
$(Q)$(RM) id.c id.h probes.dmyh probes.h
$(Q)$(RM) encdb.h transdb.h verconf.h ruby-runner.h
+ $(Q)$(RM) mjit_config.h rb_mjit_header.h
+ $(Q)$(RM) $(MJIT_MIN_HEADER) $(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h
realclean-srcs-local:: clean-srcs-local
$(Q)$(CHDIR) $(srcdir) && $(RM) \
@@ -858,7 +784,7 @@ $(HAVE_BASERUBY:no=)$(arch)-fake.rb: miniruby$(EXEEXT)
# actually depending on other headers more.
$(arch:noarch=ignore)-fake.rb: $(top_srcdir)/revision.h $(top_srcdir)/version.h $(srcdir)/version.c
-$(arch:noarch=ignore)-fake.rb: {$(VPATH)}id.h {$(VPATH)}vm_opts.h $(REVISION_H)
+$(arch:noarch=ignore)-fake.rb: {$(VPATH)}id.h {$(VPATH)}vm_opts.h
$(arch:noarch=ignore)-fake.rb: $(srcdir)/template/fake.rb.in $(tooldir)/generic_erb.rb
$(ECHO) generating $@
@@ -870,7 +796,6 @@ $(arch:noarch=ignore)-fake.rb: $(srcdir)/template/fake.rb.in $(tooldir)/generic_
noarch-fake.rb: # prerequisite of yes-fake
$(Q) exit > $@
-# runner: BASERUBY, target: miniruby
btest: $(TEST_RUNNABLE)-btest
no-btest: PHONY
yes-btest: yes-fake miniruby$(EXEEXT) PHONY
@@ -878,7 +803,6 @@ yes-btest: yes-fake miniruby$(EXEEXT) PHONY
$(Q)$(gnumake_recursive)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS)
$(ACTIONS_ENDGROUP)
-# runner: ruby, target: ruby
btest-ruby: $(TEST_RUNNABLE)-btest-ruby
no-btest-ruby: PHONY
yes-btest-ruby: prog PHONY
@@ -886,12 +810,6 @@ yes-btest-ruby: prog PHONY
$(Q)$(gnumake_recursive)$(exec) $(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS)
$(ACTIONS_ENDGROUP)
-# runner: BASERUBY, target: ruby
-btest-bruby: prog PHONY
- $(ACTIONS_GROUP)
- $(Q)$(gnumake_recursive)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS)
- $(ACTIONS_ENDGROUP)
-
rtest: yes-fake miniruby$(EXEEXT) PHONY
$(ACTIONS_GROUP)
$(Q)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" --sets=ractor -v
@@ -930,17 +848,10 @@ test-sample: test-basic # backward compatibility for mswin-build
test-short: btest-ruby $(DOT_WAIT) test-knownbug $(DOT_WAIT) test-basic
test: test-short
-# Separate to skip updating encs and exts by `make -o test-precheck`
-# for GNU make.
-test-precheck: encs exts PHONY $(DOT_WAIT)
-yes-test-all-precheck: programs $(DOT_WAIT) test-precheck
-
-PRECHECK_TEST_ALL = yes-test-all-precheck
-
# $ make test-all TESTOPTS="--help" displays more detail
# for example, make test-all TESTOPTS="-j2 -v -n test-name -- test-file-name"
test-all: $(TEST_RUNNABLE)-test-all
-yes-test-all: $(PRECHECK_TEST_ALL)
+yes-test-all: programs PHONY
$(ACTIONS_GROUP)
$(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) $(TESTS)
$(ACTIONS_ENDGROUP)
@@ -982,14 +893,13 @@ $(RBCONFIG): $(tooldir)/mkconfig.rb config.status $(srcdir)/version.h $(srcdir)/
test-rubyspec: test-spec
yes-test-rubyspec: yes-test-spec
-yes-test-spec-precheck: yes-test-all-precheck yes-fake
+test-spec-precheck: programs yes-fake
test-spec: $(TEST_RUNNABLE)-test-spec
-yes-test-spec: yes-test-spec-precheck
+yes-test-spec: test-spec-precheck
$(ACTIONS_GROUP)
$(gnumake_recursive)$(Q) \
- $(RUNRUBY) -r./$(arch)-fake -r$(tooldir)/rubyspec_temp \
- $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/default.mspec $(MSPECOPT) $(SPECOPTS)
+ $(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/default.mspec $(MSPECOPT) $(SPECOPTS)
$(ACTIONS_ENDGROUP)
no-test-spec:
@@ -1033,19 +943,23 @@ $(ENC_MK): $(srcdir)/enc/make_encmake.rb $(srcdir)/enc/Makefile.in $(srcdir)/enc
PHONY:
-{$(VPATH)}parse.c: {$(VPATH)}parse.y {$(VPATH)}id.h
+{$(VPATH)}parse.c: {$(VPATH)}parse.y $(tooldir)/ytab.sed {$(VPATH)}id.h
{$(VPATH)}parse.h: {$(VPATH)}parse.c
{$(srcdir)}.y.c:
$(ECHO) generating $@
- $(Q)$(BASERUBY) $(tooldir)/id2token.rb $(SRC_FILE) | \
- $(YACC) $(YFLAGS) -o$@ -H$*.h - parse.y
+ $(Q)$(BASERUBY) $(tooldir)/id2token.rb $(SRC_FILE) > parse.tmp.y
+ $(Q)$(YACC) -d $(YFLAGS) -o y.tab.c parse.tmp.y
+ $(Q)$(RM) parse.tmp.y
+ $(Q)sed -f $(tooldir)/ytab.sed -e "/^#/s|parse\.tmp\.[iy]|$(SRC_FILE)|" -e "/^#/s!y\.tab\.c!$@!" y.tab.c > $@.new
+ $(Q)$(MV) $@.new $@
+ $(Q)sed -e "/^#line.*y\.tab\.h/d;/^#line.*parse.*\.y/d" y.tab.h > $(@:.c=.h)
+ $(Q)$(RM) y.tab.c y.tab.h
$(PLATFORM_D):
$(Q) $(MAKEDIRS) $(PLATFORM_DIR) $(@D)
@$(NULLCMD) > $@
-exe/$(PROGRAM): $(TIMESTAMPDIR)/$(arch)/.time
exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time $(PREP) {$(VPATH)}config.h
$(Q) $(CC) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) -DRUBY_INSTALL_NAME=$(@F) $(COUTFLAG)ruby-runner.$(OBJEXT) -c $(CSRCFLAG)$(srcdir)/ruby-runner.c
$(Q) $(PURIFY) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTFLAG)$@ ruby-runner.$(OBJEXT) $(LIBS)
@@ -1058,8 +972,6 @@ exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time $(PREP) {$(VPATH)}config.h
-e ' File.symlink(prog, dest)' \
-e 'end' \
$(@F) $(@D) $(RUBY_INSTALL_NAME)$(EXEEXT)
- $(Q) $(BOOTSTRAPRUBY) -r$(srcdir)/lib/fileutils \
- -e 'FileUtils::Verbose.ln_sr(*ARGV, force: true)' rbconfig.rb $(EXTOUT)/$(arch)
exe/.time:
$(Q) $(MAKEDIRS) $(@D)
@@ -1127,7 +1039,7 @@ parse.$(OBJEXT): {$(VPATH)}parse.c
miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c
# dependencies for optional sources.
-compile.$(OBJEXT): {$(VPATH)}optunifs.inc
+compile.$(OBJEXT): {$(VPATH)}opt_sc.inc {$(VPATH)}optunifs.inc
win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c {$(VPATH)}win32/file.h \
{$(VPATH)}dln.h {$(VPATH)}dln_find.c {$(VPATH)}encindex.h \
@@ -1154,6 +1066,7 @@ INSNS2VMOPT = --srcdir="$(srcdir)"
srcs_vpath = {$(VPATH)}
inc_common_headers = $(tooldir)/ruby_vm/views/_copyright.erb $(tooldir)/ruby_vm/views/_notice.erb
+$(srcs_vpath)opt_sc.inc: $(tooldir)/ruby_vm/views/opt_sc.inc.erb $(inc_common_headers)
$(srcs_vpath)optinsn.inc: $(tooldir)/ruby_vm/views/optinsn.inc.erb $(inc_common_headers)
$(srcs_vpath)optunifs.inc: $(tooldir)/ruby_vm/views/optunifs.inc.erb $(inc_common_headers)
$(srcs_vpath)insns.inc: $(tooldir)/ruby_vm/views/insns.inc.erb $(inc_common_headers)
@@ -1165,6 +1078,7 @@ $(srcs_vpath)insns_info.inc: $(tooldir)/ruby_vm/views/insns_info.inc.erb $(inc_c
$(srcs_vpath)vmtc.inc: $(tooldir)/ruby_vm/views/vmtc.inc.erb $(inc_common_headers)
$(srcs_vpath)vm.inc: $(tooldir)/ruby_vm/views/vm.inc.erb $(inc_common_headers) \
$(tooldir)/ruby_vm/views/_insn_entry.erb $(tooldir)/ruby_vm/views/_trace_instruction.erb
+$(srcs_vpath)mjit_sp_inc.inc: $(tooldir)/ruby_vm/views/mjit_sp_inc.inc.erb
BUILTIN_RB_SRCS = \
$(srcdir)/ast.rb \
@@ -1173,8 +1087,8 @@ BUILTIN_RB_SRCS = \
$(srcdir)/numeric.rb \
$(srcdir)/io.rb \
$(srcdir)/marshal.rb \
- $(srcdir)/rjit.rb \
- $(srcdir)/rjit_c.rb \
+ $(srcdir)/mjit.rb \
+ $(srcdir)/mjit_c.rb \
$(srcdir)/pack.rb \
$(srcdir)/trace_point.rb \
$(srcdir)/warning.rb \
@@ -1197,16 +1111,9 @@ common-srcs: $(srcs_vpath)parse.c $(srcs_vpath)lex.c $(srcs_vpath)enc/trans/newl
missing-srcs: $(srcdir)/missing/des_tables.c
-srcs: common-srcs missing-srcs srcs-enc srcs-doc
+srcs: common-srcs missing-srcs srcs-enc
-RIPPER_SRCS = $(srcdir)/ext/ripper/ripper.c \
- $(srcdir)/ext/ripper/ripper_init.c \
- $(srcdir)/ext/ripper/eventids1.h \
- $(srcdir)/ext/ripper/eventids1.c \
- $(srcdir)/ext/ripper/eventids2table.c \
- # RIPPER_SRCS
-
-EXT_SRCS = ripper_srcs \
+EXT_SRCS = $(srcdir)/ext/ripper/ripper.c \
$(srcdir)/ext/rbconfig/sizeof/sizes.c \
$(srcdir)/ext/rbconfig/sizeof/limits.c \
$(srcdir)/ext/socket/constdefs.c \
@@ -1252,9 +1159,9 @@ id.c: $(tooldir)/generic_erb.rb $(srcdir)/template/id.c.tmpl $(srcdir)/defs/id.d
$(Q) $(BASERUBY) $(tooldir)/generic_erb.rb --output=$@ \
$(srcdir)/template/id.c.tmpl
-node_name.inc: $(tooldir)/node_name.rb $(srcdir)/rubyparser.h
+node_name.inc: $(tooldir)/node_name.rb $(srcdir)/node.h
$(ECHO) generating $@
- $(Q) $(BASERUBY) -n $(tooldir)/node_name.rb < $(srcdir)/rubyparser.h > $@
+ $(Q) $(BASERUBY) -n $(tooldir)/node_name.rb < $(srcdir)/node.h > $@
encdb.h: $(RBCONFIG) $(tooldir)/generic_erb.rb $(srcdir)/template/encdb.h.tmpl
$(ECHO) generating $@
@@ -1306,13 +1213,9 @@ preludes: {$(srcdir)}golf_prelude.c
$(ECHO) making $@
$(Q) $(BASERUBY) $(tooldir)/mk_builtin_loader.rb $<
-$(BUILTIN_BINARY:yes=built)in_binary.inc: $(PREP) $(BUILTIN_RB_SRCS) $(srcdir)/template/builtin_binary.inc.tmpl
+builtin_binary.inc: $(PREP) $(BUILTIN_RB_SRCS) $(srcdir)/template/builtin_binary.inc.tmpl
$(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ \
- $(srcdir)/template/builtin_binary.inc.tmpl
- -$(Q) sha256sum $@ 2> $(NULL) || $(NULLCMD)
-
-$(BUILTIN_BINARY:no=builtin)_binary.inc:
- $(Q) echo> $@ // empty $(@F)
+ $(srcdir)/template/builtin_binary.inc.tmpl -- --cross=$(CROSS_COMPILING)
$(BUILTIN_RB_INCS): $(top_srcdir)/tool/mk_builtin_loader.rb
@@ -1323,20 +1226,13 @@ $(REVISION_H)$(no_baseruby:no=~disabled~):
$(REVISION_H)$(yes_baseruby:yes=~disabled~):
$(Q) exit > $@
-# uncommon.mk: $(REVISION_H)
-# $(MKFILES): $(REVISION_H)
-
-ripper_srcs: $(RIPPER_SRCS)
-
-$(RIPPER_SRCS): $(srcdir)/parse.y $(srcdir)/defs/id.def
-$(RIPPER_SRCS): $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/ext/ripper/tools/dsl.rb
-$(RIPPER_SRCS): $(srcdir)/ext/ripper/ripper_init.c.tmpl $(srcdir)/ext/ripper/eventids2.c
+$(srcdir)/ext/ripper/ripper.c: $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/parse.y $(srcdir)/defs/id.def $(srcdir)/ext/ripper/depend
$(ECHO) generating $@
$(Q) $(CHDIR) $(@D) && \
$(CAT_DEPEND) depend | \
$(exec) $(MAKE) -f - $(mflags) \
- Q=$(Q) ECHO=$(ECHO) RM="$(RM1)" top_srcdir=../.. srcdir=. VPATH=../.. \
- RUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)" LANG=C
+ Q=$(Q) ECHO=$(ECHO) RM="$(RM1)" BISON="$(YACC)" top_srcdir=../.. srcdir=. VPATH=../.. \
+ RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)" LANG=C
$(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl $(srcdir)/ext/json/parser/prereq.mk
$(ECHO) generating $@
@@ -1364,7 +1260,7 @@ $(srcdir)/ext/rbconfig/sizeof/limits.c: $(srcdir)/ext/rbconfig/sizeof/depend \
$(exec) $(MAKE) -f - $(mflags) \
Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. RUBY="$(BASERUBY)" $(@F)
-$(srcdir)/ext/socket/constdefs.c: $(srcdir)/ext/socket/depend $(srcdir)/ext/socket/mkconstants.rb
+$(srcdir)/ext/socket/constdefs.c: $(srcdir)/ext/socket/depend
$(Q) $(CHDIR) $(@D) && \
$(CAT_DEPEND) depend | \
$(exec) $(MAKE) -f - $(mflags) \
@@ -1426,10 +1322,9 @@ run.gdb:
echo ' quit' >> run.gdb
echo end >> run.gdb
-GDB = gdb
gdb: miniruby$(EXEEXT) run.gdb PHONY
- $(GDB) -x run.gdb --quiet --args $(MINIRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
+ gdb -x run.gdb --quiet --args $(MINIRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
gdb-ruby: $(PROGRAM) run.gdb PHONY
$(Q) $(RUNRUBY_COMMAND) $(RUNRUBY_DEBUGGER) -- $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT)
@@ -1452,7 +1347,7 @@ dist:
up:: update-remote
-up$(DOT_WAIT)::
+up::
-$(Q)$(MAKE) $(mflags) Q=$(Q) REVISION_FORCE=PHONY ALWAYS_UPDATE_UNICODE= after-update
yes::
@@ -1479,10 +1374,6 @@ update-config_files: PHONY
$(Q) $(BASERUBY) -C "$(srcdir)" tool/downloader.rb -d tool --cache-dir=$(CACHE_DIR) -e gnu \
config.guess config.sub
-update-coverage: main PHONY
- $(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
- --install-dir .bundle --conservative "simplecov"
-
refresh-gems: update-bundled_gems prepare-gems
prepare-gems: $(HAVE_BASERUBY:yes=update-gems) $(HAVE_BASERUBY:yes=extract-gems)
extract-gems: $(HAVE_BASERUBY:yes=update-gems)
@@ -1509,28 +1400,14 @@ extract-gems$(gnumake:yes=-sequential): PHONY
-e 'gem, ver, _, rev = *$$F' \
-e 'next if !ver or /^#/=~gem' \
-e 'g = "#{gem}-#{ver}"' \
- -e 'unless File.directory?("#{d}/#{g}")' \
- -e 'if rev and File.exist?(gs = "gems/src/#{gem}/#{gem}.gemspec")' \
- -e 'BundledGem.build(gs, ver, "gems")' \
- -e 'end' \
+ -e 'if File.directory?("#{d}/#{g}")' \
+ -e 'elsif rev and File.exist?(gs = "gems/src/#{gem}/#{gem}.gemspec")' \
+ -e 'BundledGem.copy(gs, ".bundle")' \
+ -e 'else' \
-e 'BundledGem.unpack("gems/#{g}.gem", ".bundle")' \
-e 'end' \
gems/bundled_gems
-extract-gems$(gnumake:yes=-sequential): $(HAVE_GIT:yes=clone-bundled-gems-src)
-
-clone-bundled-gems-src: PHONY
- $(Q) $(BASERUBY) -C "$(srcdir)" \
- -Itool/lib -rbundled_gem -answ \
- -e 'BEGIN {git = $$git}' \
- -e 'gem, _, repo, rev = *$$F' \
- -e 'next if !rev or /^#/=~gem' \
- -e 'gemdir = "gems/src/#{gem}"' \
- -e 'BundledGem.checkout(gemdir, repo, rev, git: git)' \
- -e 'BundledGem.dummy_gemspec("#{gemdir}/#{gem}.gemspec")' \
- -- -git="$(GIT)" \
- gems/bundled_gems
-
outdate-bundled-gems: PHONY
$(Q) $(BASERUBY) $(tooldir)/$@.rb --make="$(MAKE)" --mflags="$(MFLAGS)" "$(srcdir)"
@@ -1560,7 +1437,7 @@ no-test-bundled-gems-prepare: no-test-bundled-gems-precheck
yes-test-bundled-gems-prepare: yes-test-bundled-gems-precheck
$(ACTIONS_GROUP)
$(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
- --install-dir .bundle --conservative "hoe" "json-schema" "test-unit-rr"
+ --install-dir .bundle --conservative "bundler" "minitest:~> 5" "test-unit" "rake" "hoe" "rexml" "json-schema:5.1.0" "test-unit-rr"
$(ACTIONS_ENDGROUP)
PREPARE_BUNDLED_GEMS = test-bundled-gems-prepare
@@ -1584,30 +1461,24 @@ no-test-syntax-suggest-prepare: no-test-syntax-suggest-precheck
yes-test-syntax-suggest-prepare: yes-test-syntax-suggest-precheck
$(ACTIONS_GROUP)
$(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
- --install-dir .bundle --conservative "rspec:~> 3"
+ --install-dir .bundle --conservative "bundler" "rake" "rspec:~> 3" #"ruby-prof"
$(ACTIONS_ENDGROUP)
RSPECOPTS =
SYNTAX_SUGGEST_SPECS =
-PREPARE_SYNTAX_SUGGEST = $(TEST_RUNNABLE)-test-syntax-suggest-prepare
+PREPARE_SYNTAX_SUGGEST = test-syntax-suggest-prepare
test-syntax-suggest: $(TEST_RUNNABLE)-test-syntax-suggest
-yes-test-syntax-suggest: $(PREPARE_SYNTAX_SUGGEST)
- $(ACTIONS_GROUP)
- $(XRUBY) -C $(srcdir) -Ispec/syntax_suggest:spec/lib .bundle/bin/rspec \
- --require rspec/expectations \
- --require spec_helper --require formatter_overrides --require spec_coverage \
- $(RSPECOPTS) spec/syntax_suggest/$(SYNTAX_SUGGEST_SPECS)
- $(ACTIONS_ENDGROUP)
+yes-test-syntax-suggest: yes-$(PREPARE_SYNTAX_SUGGEST)
+ $(XRUBY) -C $(srcdir) -Ispec/syntax_suggest .bundle/bin/rspec \
+ --require spec_helper $(RSPECOPTS) spec/syntax_suggest/$(SYNTAX_SUGGEST_SPECS)
no-test-syntax-suggest:
-check: $(DOT_WAIT) $(PREPARE_SYNTAX_SUGGEST) test-syntax-suggest
+check: $(DOT_WAIT) $(TEST_RUNNABLE)-$(PREPARE_SYNTAX_SUGGEST) test-syntax-suggest
test-bundler-precheck: $(TEST_RUNNABLE)-test-bundler-precheck
no-test-bundler-precheck:
yes-test-bundler-precheck: main $(arch)-fake.rb
-yes-test-bundler-parallel-precheck: yes-test-bundler-precheck
-test-bundler-prepare: $(TEST_RUNNABLE)-test-bundler-prepare
no-test-bundler-prepare: no-test-bundler-precheck
yes-test-bundler-prepare: yes-test-bundler-precheck
$(ACTIONS_GROUP)
@@ -1616,24 +1487,23 @@ yes-test-bundler-prepare: yes-test-bundler-precheck
-e 'ENV["BUNDLE_APP_CONFIG"] = File.expand_path(".bundle")' \
-e 'ENV["BUNDLE_PATH__SYSTEM"] = "true"' \
-e 'ENV["BUNDLE_WITHOUT"] = "lint doc"' \
- -e 'load "spec/bundler/support/bundle.rb"' -- install --quiet --gemfile=tool/bundler/dev_gems.rb
+ -e 'load "spec/bundler/support/bundle.rb"' -- install --gemfile=tool/bundler/dev_gems.rb
$(ACTIONS_ENDGROUP)
RSPECOPTS =
BUNDLER_SPECS =
-PREPARE_BUNDLER = $(TEST_RUNNABLE)-test-bundler-prepare
test-bundler: $(TEST_RUNNABLE)-test-bundler
-yes-test-bundler: $(PREPARE_BUNDLER)
+yes-test-bundler: yes-test-bundler-prepare
$(gnumake_recursive)$(XRUBY) \
-r./$(arch)-fake \
-e "exec(*ARGV)" -- \
- $(XRUBY) -C $(srcdir) -Ispec/bundler:spec/lib .bundle/bin/rspec \
- --require spec_helper --require formatter_overrides $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS)
+ $(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec \
+ --require spec_helper $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS)
no-test-bundler:
PARALLELRSPECOPTS = --runtime-log $(srcdir)/tmp/parallel_runtime_rspec.log
test-bundler-parallel: $(TEST_RUNNABLE)-test-bundler-parallel
-yes-test-bundler-parallel: $(PREPARE_BUNDLER)
+yes-test-bundler-parallel: yes-test-bundler-prepare
$(gnumake_recursive)$(XRUBY) \
-r./$(arch)-fake \
-e "ARGV[-1] = File.expand_path(ARGV[-1])" \
@@ -1641,9 +1511,9 @@ yes-test-bundler-parallel: $(PREPARE_BUNDLER)
$(XRUBY) -I$(srcdir)/spec/bundler \
-e "ENV['PARALLEL_TESTS_EXECUTABLE'] = ARGV.shift" \
-e "load ARGV.shift" \
- "$(XRUBY) -C $(srcdir) -Ispec/bundler:spec/lib .bundle/bin/rspec" \
+ "$(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec" \
$(srcdir)/.bundle/bin/parallel_rspec \
- -o "--require spec_helper --require formatter_overrides" \
+ -o "--require spec_helper" \
$(PARALLELRSPECOPTS) $(srcdir)/spec/bundler/$(BUNDLER_SPECS)
no-test-bundler-parallel:
@@ -1793,16 +1663,6 @@ $(UNICODE_HDR_DIR)/name2ctype.h:
$(UNICODE_SRC_DATA_DIR) $(UNICODE_SRC_EMOJI_DATA_DIR) > $@.new
$(MV) $@.new $@
-srcs-doc: $(srcdir)/doc/regexp/unicode_properties.rdoc
-$(srcdir)/doc/regexp/$(ALWAYS_UPDATE_UNICODE:yes=unicode_properties.rdoc): \
- $(UNICODE_HDR_DIR)/name2ctype.h $(UNICODE_PROPERTY_FILES)
-
-$(srcdir)/doc/regexp/unicode_properties.rdoc:
- $(Q) $(BOOTSTRAPRUBY) $(tooldir)/generic_erb.rb -c -o $@ \
- $(srcdir)/template/unicode_properties.rdoc.tmpl \
- $(UNICODE_SRC_DATA_DIR) $(UNICODE_HDR_DIR)/name2ctype.h || \
- $(TOUCH) $@
-
# the next non-comment line was:
# $(UNICODE_HDR_DIR)/casefold.h: $(tooldir)/enc-case-folding.rb \
# but was changed to make sure CI works on systems that don't have gperf
@@ -1845,8 +1705,6 @@ info-arch: PHONY
@echo arch=$(arch)
exam: check
-exam: $(DOT_WAIT) test-bundler-parallel
-exam: $(DOT_WAIT) test-bundled-gems
love: sudo-precheck up all test exam install
@echo love is all you need
@@ -1868,7 +1726,7 @@ update-man-date: PHONY
ChangeLog:
$(ECHO) Generating $@
-$(Q) $(BASERUBY) -I"$(tooldir)/lib" -rvcs \
- -e 'VCS.detect(ARGV[0]).export_changelog(path: ARGV[1])' \
+ -e 'VCS.detect(ARGV[0]).export_changelog("@", nil, nil, ARGV[1])' \
"$(srcdir)" $@
HELP_EXTRA_TASKS = ""
@@ -1889,16 +1747,13 @@ help: PHONY
" runruby: runs test.rb by ruby you just built" \
" gdb: runs test.rb by miniruby under gdb" \
" gdb-ruby: runs test.rb by ruby under gdb" \
- " runirb: starts irb on built ruby (not installed ruby)" \
- " exam: equals make check test-bundler-parallel test-bundled-gems" \
- " check: equals make test test-tool test-all test-spec test-syntax-suggest" \
+ " check: equals make test test-tool test-all test-spec" \
" test: ruby core tests [BTESTS=<bootstraptest files>]" \
" test-all: all ruby tests [TESTOPTS=-j4 TESTS=<test files>]" \
" test-spec: run the Ruby spec suite [SPECOPTS=<specs, opts>]" \
" test-bundler: run the Bundler spec" \
" test-bundler-parallel: run the Bundler spec with parallel" \
- " test-syntax-suggest: run the SyntaxSuggest spec" \
- " test-bundled-gems: run the test suite of bundled gems [BUNDLED_GEMS=<gems>]" \
+ " test-bundled-gems: run the test suite of bundled gems" \
" test-tool: tests under the tool/test" \
" update-gems: download files of the bundled gems" \
" update-bundled_gems: update the latest version of bundled gems" \
@@ -1909,12 +1764,12 @@ help: PHONY
" install: install all ruby distributions" \
" install-nodoc: install without rdoc" \
" install-cross: install cross compiling stuff" \
- " clean: clean up to the state before build" \
- " distclean: clean up to the state before configure" \
+ " clean: clean for tarball" \
+ " distclean: clean for repository" \
" golf: build goruby for golfers" \
$(HELP_EXTRA_TASKS) \
"see DeveloperHowto for more detail: " \
- " https://github.com/ruby/ruby/wiki/Developer-How-To" \
+ " https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto" \
$(MESSAGE_END)
$(CROSS_COMPILING:yes=)builtin.$(OBJEXT): {$(VPATH)}mini_builtin.c
@@ -1946,7 +1801,6 @@ addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
addr2line.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-addr2line.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
addr2line.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
addr2line.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
addr2line.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -1976,10 +1830,6 @@ addr2line.$(OBJEXT): {$(VPATH)}internal/stdbool.h
addr2line.$(OBJEXT): {$(VPATH)}internal/warning_push.h
addr2line.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
addr2line.$(OBJEXT): {$(VPATH)}missing.h
-array.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-array.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-array.$(OBJEXT): $(CCAN_DIR)/list/list.h
-array.$(OBJEXT): $(CCAN_DIR)/str/str.h
array.$(OBJEXT): $(hdrdir)/ruby/ruby.h
array.$(OBJEXT): $(top_srcdir)/internal/array.h
array.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
@@ -1992,7 +1842,6 @@ array.$(OBJEXT): $(top_srcdir)/internal/enum.h
array.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
array.$(OBJEXT): $(top_srcdir)/internal/gc.h
array.$(OBJEXT): $(top_srcdir)/internal/hash.h
-array.$(OBJEXT): $(top_srcdir)/internal/imemo.h
array.$(OBJEXT): $(top_srcdir)/internal/numeric.h
array.$(OBJEXT): $(top_srcdir)/internal/object.h
array.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -2005,7 +1854,6 @@ array.$(OBJEXT): $(top_srcdir)/internal/warnings.h
array.$(OBJEXT): {$(VPATH)}array.c
array.$(OBJEXT): {$(VPATH)}array.rbinc
array.$(OBJEXT): {$(VPATH)}assert.h
-array.$(OBJEXT): {$(VPATH)}atomic.h
array.$(OBJEXT): {$(VPATH)}backward/2/assume.h
array.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
array.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -2063,7 +1911,6 @@ array.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
array.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
array.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
array.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-array.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
array.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
array.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
array.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -2132,6 +1979,7 @@ array.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
array.$(OBJEXT): {$(VPATH)}internal/intern/error.h
array.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
array.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+array.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
array.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
array.$(OBJEXT): {$(VPATH)}internal/intern/io.h
array.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -2162,6 +2010,7 @@ array.$(OBJEXT): {$(VPATH)}internal/memory.h
array.$(OBJEXT): {$(VPATH)}internal/method.h
array.$(OBJEXT): {$(VPATH)}internal/module.h
array.$(OBJEXT): {$(VPATH)}internal/newobj.h
+array.$(OBJEXT): {$(VPATH)}internal/rgengc.h
array.$(OBJEXT): {$(VPATH)}internal/scan_args.h
array.$(OBJEXT): {$(VPATH)}internal/special_consts.h
array.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -2173,24 +2022,17 @@ array.$(OBJEXT): {$(VPATH)}internal/value_type.h
array.$(OBJEXT): {$(VPATH)}internal/variable.h
array.$(OBJEXT): {$(VPATH)}internal/warning_push.h
array.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-array.$(OBJEXT): {$(VPATH)}method.h
array.$(OBJEXT): {$(VPATH)}missing.h
-array.$(OBJEXT): {$(VPATH)}node.h
array.$(OBJEXT): {$(VPATH)}onigmo.h
array.$(OBJEXT): {$(VPATH)}oniguruma.h
array.$(OBJEXT): {$(VPATH)}probes.dmyh
array.$(OBJEXT): {$(VPATH)}probes.h
array.$(OBJEXT): {$(VPATH)}ruby_assert.h
-array.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-array.$(OBJEXT): {$(VPATH)}rubyparser.h
array.$(OBJEXT): {$(VPATH)}shape.h
array.$(OBJEXT): {$(VPATH)}st.h
array.$(OBJEXT): {$(VPATH)}subst.h
-array.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-array.$(OBJEXT): {$(VPATH)}thread_native.h
+array.$(OBJEXT): {$(VPATH)}transient_heap.h
array.$(OBJEXT): {$(VPATH)}util.h
-array.$(OBJEXT): {$(VPATH)}vm_core.h
-array.$(OBJEXT): {$(VPATH)}vm_opts.h
ast.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
ast.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
ast.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -2203,34 +2045,12 @@ ast.$(OBJEXT): $(top_srcdir)/internal/compilers.h
ast.$(OBJEXT): $(top_srcdir)/internal/gc.h
ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h
ast.$(OBJEXT): $(top_srcdir)/internal/parse.h
-ast.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
ast.$(OBJEXT): $(top_srcdir)/internal/serial.h
ast.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
ast.$(OBJEXT): $(top_srcdir)/internal/symbol.h
ast.$(OBJEXT): $(top_srcdir)/internal/variable.h
ast.$(OBJEXT): $(top_srcdir)/internal/vm.h
ast.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-ast.$(OBJEXT): $(top_srcdir)/prism/defines.h
-ast.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-ast.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-ast.$(OBJEXT): $(top_srcdir)/prism/node.h
-ast.$(OBJEXT): $(top_srcdir)/prism/options.h
-ast.$(OBJEXT): $(top_srcdir)/prism/pack.h
-ast.$(OBJEXT): $(top_srcdir)/prism/parser.h
-ast.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-ast.$(OBJEXT): $(top_srcdir)/prism/prism.h
-ast.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
ast.$(OBJEXT): {$(VPATH)}assert.h
ast.$(OBJEXT): {$(VPATH)}ast.c
ast.$(OBJEXT): {$(VPATH)}ast.rbinc
@@ -2291,7 +2111,6 @@ ast.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
ast.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
ast.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
ast.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-ast.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
ast.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
ast.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
ast.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -2360,6 +2179,7 @@ ast.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
ast.$(OBJEXT): {$(VPATH)}internal/intern/error.h
ast.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
ast.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+ast.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
ast.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
ast.$(OBJEXT): {$(VPATH)}internal/intern/io.h
ast.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -2390,6 +2210,7 @@ ast.$(OBJEXT): {$(VPATH)}internal/memory.h
ast.$(OBJEXT): {$(VPATH)}internal/method.h
ast.$(OBJEXT): {$(VPATH)}internal/module.h
ast.$(OBJEXT): {$(VPATH)}internal/newobj.h
+ast.$(OBJEXT): {$(VPATH)}internal/rgengc.h
ast.$(OBJEXT): {$(VPATH)}internal/scan_args.h
ast.$(OBJEXT): {$(VPATH)}internal/special_consts.h
ast.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -2407,12 +2228,8 @@ ast.$(OBJEXT): {$(VPATH)}missing.h
ast.$(OBJEXT): {$(VPATH)}node.h
ast.$(OBJEXT): {$(VPATH)}onigmo.h
ast.$(OBJEXT): {$(VPATH)}oniguruma.h
-ast.$(OBJEXT): {$(VPATH)}prism/ast.h
-ast.$(OBJEXT): {$(VPATH)}prism/version.h
-ast.$(OBJEXT): {$(VPATH)}prism_compile.h
ast.$(OBJEXT): {$(VPATH)}ruby_assert.h
ast.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-ast.$(OBJEXT): {$(VPATH)}rubyparser.h
ast.$(OBJEXT): {$(VPATH)}shape.h
ast.$(OBJEXT): {$(VPATH)}st.h
ast.$(OBJEXT): {$(VPATH)}subst.h
@@ -2421,13 +2238,7 @@ ast.$(OBJEXT): {$(VPATH)}thread_native.h
ast.$(OBJEXT): {$(VPATH)}util.h
ast.$(OBJEXT): {$(VPATH)}vm_core.h
ast.$(OBJEXT): {$(VPATH)}vm_opts.h
-bignum.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-bignum.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-bignum.$(OBJEXT): $(CCAN_DIR)/list/list.h
-bignum.$(OBJEXT): $(CCAN_DIR)/str/str.h
bignum.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-bignum.$(OBJEXT): $(top_srcdir)/internal/array.h
-bignum.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
bignum.$(OBJEXT): $(top_srcdir)/internal/bignum.h
bignum.$(OBJEXT): $(top_srcdir)/internal/bits.h
bignum.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -2435,7 +2246,6 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/compilers.h
bignum.$(OBJEXT): $(top_srcdir)/internal/complex.h
bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h
-bignum.$(OBJEXT): $(top_srcdir)/internal/imemo.h
bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h
bignum.$(OBJEXT): $(top_srcdir)/internal/object.h
bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -2445,7 +2255,6 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/variable.h
bignum.$(OBJEXT): $(top_srcdir)/internal/vm.h
bignum.$(OBJEXT): $(top_srcdir)/internal/warnings.h
bignum.$(OBJEXT): {$(VPATH)}assert.h
-bignum.$(OBJEXT): {$(VPATH)}atomic.h
bignum.$(OBJEXT): {$(VPATH)}backward/2/assume.h
bignum.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
bignum.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -2459,7 +2268,6 @@ bignum.$(OBJEXT): {$(VPATH)}bignum.c
bignum.$(OBJEXT): {$(VPATH)}config.h
bignum.$(OBJEXT): {$(VPATH)}constant.h
bignum.$(OBJEXT): {$(VPATH)}defines.h
-bignum.$(OBJEXT): {$(VPATH)}encoding.h
bignum.$(OBJEXT): {$(VPATH)}id.h
bignum.$(OBJEXT): {$(VPATH)}id_table.h
bignum.$(OBJEXT): {$(VPATH)}intern.h
@@ -2502,7 +2310,6 @@ bignum.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
bignum.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
bignum.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
bignum.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-bignum.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
bignum.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
bignum.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
bignum.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -2535,15 +2342,6 @@ bignum.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
bignum.$(OBJEXT): {$(VPATH)}internal/ctype.h
bignum.$(OBJEXT): {$(VPATH)}internal/dllexport.h
bignum.$(OBJEXT): {$(VPATH)}internal/dosish.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-bignum.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
bignum.$(OBJEXT): {$(VPATH)}internal/error.h
bignum.$(OBJEXT): {$(VPATH)}internal/eval.h
bignum.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -2571,6 +2369,7 @@ bignum.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
bignum.$(OBJEXT): {$(VPATH)}internal/intern/error.h
bignum.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
bignum.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+bignum.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
bignum.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
bignum.$(OBJEXT): {$(VPATH)}internal/intern/io.h
bignum.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -2601,6 +2400,7 @@ bignum.$(OBJEXT): {$(VPATH)}internal/memory.h
bignum.$(OBJEXT): {$(VPATH)}internal/method.h
bignum.$(OBJEXT): {$(VPATH)}internal/module.h
bignum.$(OBJEXT): {$(VPATH)}internal/newobj.h
+bignum.$(OBJEXT): {$(VPATH)}internal/rgengc.h
bignum.$(OBJEXT): {$(VPATH)}internal/scan_args.h
bignum.$(OBJEXT): {$(VPATH)}internal/special_consts.h
bignum.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -2612,23 +2412,13 @@ bignum.$(OBJEXT): {$(VPATH)}internal/value_type.h
bignum.$(OBJEXT): {$(VPATH)}internal/variable.h
bignum.$(OBJEXT): {$(VPATH)}internal/warning_push.h
bignum.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-bignum.$(OBJEXT): {$(VPATH)}method.h
bignum.$(OBJEXT): {$(VPATH)}missing.h
-bignum.$(OBJEXT): {$(VPATH)}node.h
-bignum.$(OBJEXT): {$(VPATH)}onigmo.h
-bignum.$(OBJEXT): {$(VPATH)}oniguruma.h
bignum.$(OBJEXT): {$(VPATH)}ruby_assert.h
-bignum.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-bignum.$(OBJEXT): {$(VPATH)}rubyparser.h
bignum.$(OBJEXT): {$(VPATH)}shape.h
bignum.$(OBJEXT): {$(VPATH)}st.h
bignum.$(OBJEXT): {$(VPATH)}subst.h
bignum.$(OBJEXT): {$(VPATH)}thread.h
-bignum.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-bignum.$(OBJEXT): {$(VPATH)}thread_native.h
bignum.$(OBJEXT): {$(VPATH)}util.h
-bignum.$(OBJEXT): {$(VPATH)}vm_core.h
-bignum.$(OBJEXT): {$(VPATH)}vm_opts.h
builtin.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
builtin.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
builtin.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -2644,27 +2434,6 @@ builtin.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
builtin.$(OBJEXT): $(top_srcdir)/internal/variable.h
builtin.$(OBJEXT): $(top_srcdir)/internal/vm.h
builtin.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/defines.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/node.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/options.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/pack.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/parser.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/prism.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
builtin.$(OBJEXT): {$(VPATH)}assert.h
builtin.$(OBJEXT): {$(VPATH)}atomic.h
builtin.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -2682,7 +2451,6 @@ builtin.$(OBJEXT): {$(VPATH)}builtin_binary.inc
builtin.$(OBJEXT): {$(VPATH)}config.h
builtin.$(OBJEXT): {$(VPATH)}constant.h
builtin.$(OBJEXT): {$(VPATH)}defines.h
-builtin.$(OBJEXT): {$(VPATH)}encoding.h
builtin.$(OBJEXT): {$(VPATH)}id.h
builtin.$(OBJEXT): {$(VPATH)}id_table.h
builtin.$(OBJEXT): {$(VPATH)}intern.h
@@ -2725,7 +2493,6 @@ builtin.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
builtin.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
builtin.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
builtin.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-builtin.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
builtin.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
builtin.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
builtin.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -2758,15 +2525,6 @@ builtin.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
builtin.$(OBJEXT): {$(VPATH)}internal/ctype.h
builtin.$(OBJEXT): {$(VPATH)}internal/dllexport.h
builtin.$(OBJEXT): {$(VPATH)}internal/dosish.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-builtin.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
builtin.$(OBJEXT): {$(VPATH)}internal/error.h
builtin.$(OBJEXT): {$(VPATH)}internal/eval.h
builtin.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -2794,6 +2552,7 @@ builtin.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
builtin.$(OBJEXT): {$(VPATH)}internal/intern/error.h
builtin.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
builtin.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+builtin.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
builtin.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
builtin.$(OBJEXT): {$(VPATH)}internal/intern/io.h
builtin.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -2824,6 +2583,7 @@ builtin.$(OBJEXT): {$(VPATH)}internal/memory.h
builtin.$(OBJEXT): {$(VPATH)}internal/method.h
builtin.$(OBJEXT): {$(VPATH)}internal/module.h
builtin.$(OBJEXT): {$(VPATH)}internal/newobj.h
+builtin.$(OBJEXT): {$(VPATH)}internal/rgengc.h
builtin.$(OBJEXT): {$(VPATH)}internal/scan_args.h
builtin.$(OBJEXT): {$(VPATH)}internal/special_consts.h
builtin.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -2839,14 +2599,8 @@ builtin.$(OBJEXT): {$(VPATH)}iseq.h
builtin.$(OBJEXT): {$(VPATH)}method.h
builtin.$(OBJEXT): {$(VPATH)}missing.h
builtin.$(OBJEXT): {$(VPATH)}node.h
-builtin.$(OBJEXT): {$(VPATH)}onigmo.h
-builtin.$(OBJEXT): {$(VPATH)}oniguruma.h
-builtin.$(OBJEXT): {$(VPATH)}prism/ast.h
-builtin.$(OBJEXT): {$(VPATH)}prism/version.h
-builtin.$(OBJEXT): {$(VPATH)}prism_compile.h
builtin.$(OBJEXT): {$(VPATH)}ruby_assert.h
builtin.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-builtin.$(OBJEXT): {$(VPATH)}rubyparser.h
builtin.$(OBJEXT): {$(VPATH)}shape.h
builtin.$(OBJEXT): {$(VPATH)}st.h
builtin.$(OBJEXT): {$(VPATH)}subst.h
@@ -2933,7 +2687,6 @@ class.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
class.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
class.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
class.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-class.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
class.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
class.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
class.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -3002,6 +2755,7 @@ class.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
class.$(OBJEXT): {$(VPATH)}internal/intern/error.h
class.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
class.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+class.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
class.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
class.$(OBJEXT): {$(VPATH)}internal/intern/io.h
class.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -3032,6 +2786,7 @@ class.$(OBJEXT): {$(VPATH)}internal/memory.h
class.$(OBJEXT): {$(VPATH)}internal/method.h
class.$(OBJEXT): {$(VPATH)}internal/module.h
class.$(OBJEXT): {$(VPATH)}internal/newobj.h
+class.$(OBJEXT): {$(VPATH)}internal/rgengc.h
class.$(OBJEXT): {$(VPATH)}internal/scan_args.h
class.$(OBJEXT): {$(VPATH)}internal/special_consts.h
class.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -3050,18 +2805,14 @@ class.$(OBJEXT): {$(VPATH)}onigmo.h
class.$(OBJEXT): {$(VPATH)}oniguruma.h
class.$(OBJEXT): {$(VPATH)}ruby_assert.h
class.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-class.$(OBJEXT): {$(VPATH)}rubyparser.h
class.$(OBJEXT): {$(VPATH)}shape.h
class.$(OBJEXT): {$(VPATH)}st.h
class.$(OBJEXT): {$(VPATH)}subst.h
class.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
class.$(OBJEXT): {$(VPATH)}thread_native.h
class.$(OBJEXT): {$(VPATH)}vm_core.h
-class.$(OBJEXT): {$(VPATH)}vm_debug.h
class.$(OBJEXT): {$(VPATH)}vm_opts.h
-class.$(OBJEXT): {$(VPATH)}vm_sync.h
compar.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-compar.$(OBJEXT): $(hdrdir)/ruby/version.h
compar.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
compar.$(OBJEXT): $(top_srcdir)/internal/compar.h
compar.$(OBJEXT): $(top_srcdir)/internal/compilers.h
@@ -3125,7 +2876,6 @@ compar.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
compar.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
compar.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
compar.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-compar.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
compar.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
compar.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
compar.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -3194,6 +2944,7 @@ compar.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
compar.$(OBJEXT): {$(VPATH)}internal/intern/error.h
compar.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
compar.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+compar.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
compar.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
compar.$(OBJEXT): {$(VPATH)}internal/intern/io.h
compar.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -3224,6 +2975,7 @@ compar.$(OBJEXT): {$(VPATH)}internal/memory.h
compar.$(OBJEXT): {$(VPATH)}internal/method.h
compar.$(OBJEXT): {$(VPATH)}internal/module.h
compar.$(OBJEXT): {$(VPATH)}internal/newobj.h
+compar.$(OBJEXT): {$(VPATH)}internal/rgengc.h
compar.$(OBJEXT): {$(VPATH)}internal/scan_args.h
compar.$(OBJEXT): {$(VPATH)}internal/special_consts.h
compar.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -3245,7 +2997,6 @@ compile.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
compile.$(OBJEXT): $(CCAN_DIR)/list/list.h
compile.$(OBJEXT): $(CCAN_DIR)/str/str.h
compile.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-compile.$(OBJEXT): $(hdrdir)/ruby/version.h
compile.$(OBJEXT): $(top_srcdir)/internal/array.h
compile.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
compile.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -3272,28 +3023,6 @@ compile.$(OBJEXT): $(top_srcdir)/internal/thread.h
compile.$(OBJEXT): $(top_srcdir)/internal/variable.h
compile.$(OBJEXT): $(top_srcdir)/internal/vm.h
compile.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-compile.$(OBJEXT): $(top_srcdir)/prism/defines.h
-compile.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-compile.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-compile.$(OBJEXT): $(top_srcdir)/prism/node.h
-compile.$(OBJEXT): $(top_srcdir)/prism/options.h
-compile.$(OBJEXT): $(top_srcdir)/prism/pack.h
-compile.$(OBJEXT): $(top_srcdir)/prism/parser.h
-compile.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-compile.$(OBJEXT): $(top_srcdir)/prism/prism.h
-compile.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-compile.$(OBJEXT): $(top_srcdir)/prism_compile.c
compile.$(OBJEXT): {$(VPATH)}assert.h
compile.$(OBJEXT): {$(VPATH)}atomic.h
compile.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -3313,6 +3042,7 @@ compile.$(OBJEXT): {$(VPATH)}debug_counter.h
compile.$(OBJEXT): {$(VPATH)}defines.h
compile.$(OBJEXT): {$(VPATH)}encindex.h
compile.$(OBJEXT): {$(VPATH)}encoding.h
+compile.$(OBJEXT): {$(VPATH)}gc.h
compile.$(OBJEXT): {$(VPATH)}id.h
compile.$(OBJEXT): {$(VPATH)}id_table.h
compile.$(OBJEXT): {$(VPATH)}insns.def
@@ -3358,7 +3088,6 @@ compile.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
compile.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
compile.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
compile.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-compile.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
compile.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
compile.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
compile.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -3428,6 +3157,7 @@ compile.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
compile.$(OBJEXT): {$(VPATH)}internal/intern/error.h
compile.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
compile.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+compile.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
compile.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
compile.$(OBJEXT): {$(VPATH)}internal/intern/io.h
compile.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -3458,6 +3188,7 @@ compile.$(OBJEXT): {$(VPATH)}internal/memory.h
compile.$(OBJEXT): {$(VPATH)}internal/method.h
compile.$(OBJEXT): {$(VPATH)}internal/module.h
compile.$(OBJEXT): {$(VPATH)}internal/newobj.h
+compile.$(OBJEXT): {$(VPATH)}internal/rgengc.h
compile.$(OBJEXT): {$(VPATH)}internal/scan_args.h
compile.$(OBJEXT): {$(VPATH)}internal/special_consts.h
compile.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -3476,16 +3207,10 @@ compile.$(OBJEXT): {$(VPATH)}node.h
compile.$(OBJEXT): {$(VPATH)}onigmo.h
compile.$(OBJEXT): {$(VPATH)}oniguruma.h
compile.$(OBJEXT): {$(VPATH)}optinsn.inc
-compile.$(OBJEXT): {$(VPATH)}prism/ast.h
-compile.$(OBJEXT): {$(VPATH)}prism/prism.h
-compile.$(OBJEXT): {$(VPATH)}prism/version.h
-compile.$(OBJEXT): {$(VPATH)}prism_compile.c
-compile.$(OBJEXT): {$(VPATH)}prism_compile.h
compile.$(OBJEXT): {$(VPATH)}re.h
compile.$(OBJEXT): {$(VPATH)}regex.h
compile.$(OBJEXT): {$(VPATH)}ruby_assert.h
compile.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-compile.$(OBJEXT): {$(VPATH)}rubyparser.h
compile.$(OBJEXT): {$(VPATH)}shape.h
compile.$(OBJEXT): {$(VPATH)}st.h
compile.$(OBJEXT): {$(VPATH)}subst.h
@@ -3496,8 +3221,6 @@ compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h
compile.$(OBJEXT): {$(VPATH)}vm_core.h
compile.$(OBJEXT): {$(VPATH)}vm_debug.h
compile.$(OBJEXT): {$(VPATH)}vm_opts.h
-compile.$(OBJEXT): {$(VPATH)}vm_sync.h
-compile.$(OBJEXT): {$(VPATH)}yjit.h
complex.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
complex.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
complex.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -3519,7 +3242,6 @@ complex.$(OBJEXT): $(top_srcdir)/internal/object.h
complex.$(OBJEXT): $(top_srcdir)/internal/rational.h
complex.$(OBJEXT): $(top_srcdir)/internal/serial.h
complex.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-complex.$(OBJEXT): $(top_srcdir)/internal/string.h
complex.$(OBJEXT): $(top_srcdir)/internal/variable.h
complex.$(OBJEXT): $(top_srcdir)/internal/vm.h
complex.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@@ -3537,9 +3259,7 @@ complex.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
complex.$(OBJEXT): {$(VPATH)}complex.c
complex.$(OBJEXT): {$(VPATH)}config.h
complex.$(OBJEXT): {$(VPATH)}constant.h
-complex.$(OBJEXT): {$(VPATH)}debug_counter.h
complex.$(OBJEXT): {$(VPATH)}defines.h
-complex.$(OBJEXT): {$(VPATH)}encoding.h
complex.$(OBJEXT): {$(VPATH)}id.h
complex.$(OBJEXT): {$(VPATH)}id_table.h
complex.$(OBJEXT): {$(VPATH)}intern.h
@@ -3582,7 +3302,6 @@ complex.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
complex.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
complex.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
complex.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-complex.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
complex.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
complex.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
complex.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -3615,15 +3334,6 @@ complex.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
complex.$(OBJEXT): {$(VPATH)}internal/ctype.h
complex.$(OBJEXT): {$(VPATH)}internal/dllexport.h
complex.$(OBJEXT): {$(VPATH)}internal/dosish.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-complex.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
complex.$(OBJEXT): {$(VPATH)}internal/error.h
complex.$(OBJEXT): {$(VPATH)}internal/eval.h
complex.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -3651,6 +3361,7 @@ complex.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
complex.$(OBJEXT): {$(VPATH)}internal/intern/error.h
complex.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
complex.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+complex.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
complex.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
complex.$(OBJEXT): {$(VPATH)}internal/intern/io.h
complex.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -3681,6 +3392,7 @@ complex.$(OBJEXT): {$(VPATH)}internal/memory.h
complex.$(OBJEXT): {$(VPATH)}internal/method.h
complex.$(OBJEXT): {$(VPATH)}internal/module.h
complex.$(OBJEXT): {$(VPATH)}internal/newobj.h
+complex.$(OBJEXT): {$(VPATH)}internal/rgengc.h
complex.$(OBJEXT): {$(VPATH)}internal/scan_args.h
complex.$(OBJEXT): {$(VPATH)}internal/special_consts.h
complex.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -3695,27 +3407,21 @@ complex.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
complex.$(OBJEXT): {$(VPATH)}method.h
complex.$(OBJEXT): {$(VPATH)}missing.h
complex.$(OBJEXT): {$(VPATH)}node.h
-complex.$(OBJEXT): {$(VPATH)}onigmo.h
-complex.$(OBJEXT): {$(VPATH)}oniguruma.h
complex.$(OBJEXT): {$(VPATH)}ruby_assert.h
complex.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-complex.$(OBJEXT): {$(VPATH)}rubyparser.h
complex.$(OBJEXT): {$(VPATH)}shape.h
complex.$(OBJEXT): {$(VPATH)}st.h
complex.$(OBJEXT): {$(VPATH)}subst.h
complex.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
complex.$(OBJEXT): {$(VPATH)}thread_native.h
complex.$(OBJEXT): {$(VPATH)}vm_core.h
-complex.$(OBJEXT): {$(VPATH)}vm_debug.h
complex.$(OBJEXT): {$(VPATH)}vm_opts.h
-complex.$(OBJEXT): {$(VPATH)}vm_sync.h
cont.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
cont.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
cont.$(OBJEXT): $(CCAN_DIR)/list/list.h
cont.$(OBJEXT): $(CCAN_DIR)/str/str.h
cont.$(OBJEXT): $(hdrdir)/ruby.h
cont.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-cont.$(OBJEXT): $(hdrdir)/ruby/version.h
cont.$(OBJEXT): $(top_srcdir)/internal/array.h
cont.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h
@@ -3728,31 +3434,9 @@ cont.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
cont.$(OBJEXT): $(top_srcdir)/internal/string.h
-cont.$(OBJEXT): $(top_srcdir)/internal/thread.h
cont.$(OBJEXT): $(top_srcdir)/internal/variable.h
cont.$(OBJEXT): $(top_srcdir)/internal/vm.h
cont.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-cont.$(OBJEXT): $(top_srcdir)/prism/defines.h
-cont.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-cont.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-cont.$(OBJEXT): $(top_srcdir)/prism/node.h
-cont.$(OBJEXT): $(top_srcdir)/prism/options.h
-cont.$(OBJEXT): $(top_srcdir)/prism/pack.h
-cont.$(OBJEXT): $(top_srcdir)/prism/parser.h
-cont.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-cont.$(OBJEXT): $(top_srcdir)/prism/prism.h
-cont.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
cont.$(OBJEXT): {$(VPATH)}$(COROUTINE_H)
cont.$(OBJEXT): {$(VPATH)}assert.h
cont.$(OBJEXT): {$(VPATH)}atomic.h
@@ -3773,6 +3457,7 @@ cont.$(OBJEXT): {$(VPATH)}defines.h
cont.$(OBJEXT): {$(VPATH)}encoding.h
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
cont.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
+cont.$(OBJEXT): {$(VPATH)}gc.h
cont.$(OBJEXT): {$(VPATH)}id.h
cont.$(OBJEXT): {$(VPATH)}id_table.h
cont.$(OBJEXT): {$(VPATH)}intern.h
@@ -3815,7 +3500,6 @@ cont.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
cont.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
cont.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
cont.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-cont.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
cont.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
cont.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
cont.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -3884,6 +3568,7 @@ cont.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
cont.$(OBJEXT): {$(VPATH)}internal/intern/error.h
cont.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
cont.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+cont.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
cont.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
cont.$(OBJEXT): {$(VPATH)}internal/intern/io.h
cont.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -3914,6 +3599,7 @@ cont.$(OBJEXT): {$(VPATH)}internal/memory.h
cont.$(OBJEXT): {$(VPATH)}internal/method.h
cont.$(OBJEXT): {$(VPATH)}internal/module.h
cont.$(OBJEXT): {$(VPATH)}internal/newobj.h
+cont.$(OBJEXT): {$(VPATH)}internal/rgengc.h
cont.$(OBJEXT): {$(VPATH)}internal/scan_args.h
cont.$(OBJEXT): {$(VPATH)}internal/special_consts.h
cont.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -3928,18 +3614,14 @@ cont.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
cont.$(OBJEXT): {$(VPATH)}iseq.h
cont.$(OBJEXT): {$(VPATH)}method.h
cont.$(OBJEXT): {$(VPATH)}missing.h
+cont.$(OBJEXT): {$(VPATH)}mjit.h
cont.$(OBJEXT): {$(VPATH)}node.h
cont.$(OBJEXT): {$(VPATH)}onigmo.h
cont.$(OBJEXT): {$(VPATH)}oniguruma.h
-cont.$(OBJEXT): {$(VPATH)}prism/ast.h
-cont.$(OBJEXT): {$(VPATH)}prism/version.h
-cont.$(OBJEXT): {$(VPATH)}prism_compile.h
cont.$(OBJEXT): {$(VPATH)}ractor.h
cont.$(OBJEXT): {$(VPATH)}ractor_core.h
-cont.$(OBJEXT): {$(VPATH)}rjit.h
cont.$(OBJEXT): {$(VPATH)}ruby_assert.h
cont.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-cont.$(OBJEXT): {$(VPATH)}rubyparser.h
cont.$(OBJEXT): {$(VPATH)}shape.h
cont.$(OBJEXT): {$(VPATH)}st.h
cont.$(OBJEXT): {$(VPATH)}subst.h
@@ -3986,6 +3668,7 @@ debug.$(OBJEXT): {$(VPATH)}defines.h
debug.$(OBJEXT): {$(VPATH)}encindex.h
debug.$(OBJEXT): {$(VPATH)}encoding.h
debug.$(OBJEXT): {$(VPATH)}eval_intern.h
+debug.$(OBJEXT): {$(VPATH)}gc.h
debug.$(OBJEXT): {$(VPATH)}id.h
debug.$(OBJEXT): {$(VPATH)}id_table.h
debug.$(OBJEXT): {$(VPATH)}intern.h
@@ -4028,7 +3711,6 @@ debug.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
debug.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
debug.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
debug.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-debug.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
debug.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
debug.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
debug.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -4097,6 +3779,7 @@ debug.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
debug.$(OBJEXT): {$(VPATH)}internal/intern/error.h
debug.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
debug.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+debug.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
debug.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
debug.$(OBJEXT): {$(VPATH)}internal/intern/io.h
debug.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -4127,6 +3810,7 @@ debug.$(OBJEXT): {$(VPATH)}internal/memory.h
debug.$(OBJEXT): {$(VPATH)}internal/method.h
debug.$(OBJEXT): {$(VPATH)}internal/module.h
debug.$(OBJEXT): {$(VPATH)}internal/newobj.h
+debug.$(OBJEXT): {$(VPATH)}internal/rgengc.h
debug.$(OBJEXT): {$(VPATH)}internal/scan_args.h
debug.$(OBJEXT): {$(VPATH)}internal/special_consts.h
debug.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -4148,7 +3832,6 @@ debug.$(OBJEXT): {$(VPATH)}ractor.h
debug.$(OBJEXT): {$(VPATH)}ractor_core.h
debug.$(OBJEXT): {$(VPATH)}ruby_assert.h
debug.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-debug.$(OBJEXT): {$(VPATH)}rubyparser.h
debug.$(OBJEXT): {$(VPATH)}shape.h
debug.$(OBJEXT): {$(VPATH)}st.h
debug.$(OBJEXT): {$(VPATH)}subst.h
@@ -4160,7 +3843,6 @@ debug.$(OBJEXT): {$(VPATH)}vm_callinfo.h
debug.$(OBJEXT): {$(VPATH)}vm_core.h
debug.$(OBJEXT): {$(VPATH)}vm_debug.h
debug.$(OBJEXT): {$(VPATH)}vm_opts.h
-debug.$(OBJEXT): {$(VPATH)}vm_sync.h
debug_counter.$(OBJEXT): $(hdrdir)/ruby/ruby.h
debug_counter.$(OBJEXT): {$(VPATH)}assert.h
debug_counter.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -4215,7 +3897,6 @@ debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -4275,6 +3956,7 @@ debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/error.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/io.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -4305,6 +3987,7 @@ debug_counter.$(OBJEXT): {$(VPATH)}internal/memory.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/method.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/module.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/newobj.h
+debug_counter.$(OBJEXT): {$(VPATH)}internal/rgengc.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/scan_args.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/special_consts.h
debug_counter.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -4320,14 +4003,8 @@ debug_counter.$(OBJEXT): {$(VPATH)}missing.h
debug_counter.$(OBJEXT): {$(VPATH)}st.h
debug_counter.$(OBJEXT): {$(VPATH)}subst.h
debug_counter.$(OBJEXT): {$(VPATH)}thread_native.h
-dir.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-dir.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-dir.$(OBJEXT): $(CCAN_DIR)/list/list.h
-dir.$(OBJEXT): $(CCAN_DIR)/str/str.h
dir.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-dir.$(OBJEXT): $(hdrdir)/ruby/version.h
dir.$(OBJEXT): $(top_srcdir)/internal/array.h
-dir.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
dir.$(OBJEXT): $(top_srcdir)/internal/class.h
dir.$(OBJEXT): $(top_srcdir)/internal/compilers.h
dir.$(OBJEXT): $(top_srcdir)/internal/dir.h
@@ -4335,7 +4012,6 @@ dir.$(OBJEXT): $(top_srcdir)/internal/encoding.h
dir.$(OBJEXT): $(top_srcdir)/internal/error.h
dir.$(OBJEXT): $(top_srcdir)/internal/file.h
dir.$(OBJEXT): $(top_srcdir)/internal/gc.h
-dir.$(OBJEXT): $(top_srcdir)/internal/imemo.h
dir.$(OBJEXT): $(top_srcdir)/internal/io.h
dir.$(OBJEXT): $(top_srcdir)/internal/object.h
dir.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -4345,7 +4021,6 @@ dir.$(OBJEXT): $(top_srcdir)/internal/variable.h
dir.$(OBJEXT): $(top_srcdir)/internal/vm.h
dir.$(OBJEXT): $(top_srcdir)/internal/warnings.h
dir.$(OBJEXT): {$(VPATH)}assert.h
-dir.$(OBJEXT): {$(VPATH)}atomic.h
dir.$(OBJEXT): {$(VPATH)}backward/2/assume.h
dir.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
dir.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -4405,7 +4080,6 @@ dir.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
dir.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
dir.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
dir.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-dir.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
dir.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
dir.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
dir.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -4474,6 +4148,7 @@ dir.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
dir.$(OBJEXT): {$(VPATH)}internal/intern/error.h
dir.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
dir.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dir.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
dir.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
dir.$(OBJEXT): {$(VPATH)}internal/intern/io.h
dir.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -4504,6 +4179,7 @@ dir.$(OBJEXT): {$(VPATH)}internal/memory.h
dir.$(OBJEXT): {$(VPATH)}internal/method.h
dir.$(OBJEXT): {$(VPATH)}internal/module.h
dir.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dir.$(OBJEXT): {$(VPATH)}internal/rgengc.h
dir.$(OBJEXT): {$(VPATH)}internal/scan_args.h
dir.$(OBJEXT): {$(VPATH)}internal/special_consts.h
dir.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -4516,23 +4192,14 @@ dir.$(OBJEXT): {$(VPATH)}internal/variable.h
dir.$(OBJEXT): {$(VPATH)}internal/warning_push.h
dir.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
dir.$(OBJEXT): {$(VPATH)}io.h
-dir.$(OBJEXT): {$(VPATH)}method.h
dir.$(OBJEXT): {$(VPATH)}missing.h
-dir.$(OBJEXT): {$(VPATH)}node.h
dir.$(OBJEXT): {$(VPATH)}onigmo.h
dir.$(OBJEXT): {$(VPATH)}oniguruma.h
-dir.$(OBJEXT): {$(VPATH)}ruby_assert.h
-dir.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-dir.$(OBJEXT): {$(VPATH)}rubyparser.h
dir.$(OBJEXT): {$(VPATH)}shape.h
dir.$(OBJEXT): {$(VPATH)}st.h
dir.$(OBJEXT): {$(VPATH)}subst.h
dir.$(OBJEXT): {$(VPATH)}thread.h
-dir.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-dir.$(OBJEXT): {$(VPATH)}thread_native.h
dir.$(OBJEXT): {$(VPATH)}util.h
-dir.$(OBJEXT): {$(VPATH)}vm_core.h
-dir.$(OBJEXT): {$(VPATH)}vm_opts.h
dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h
dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@@ -4590,7 +4257,6 @@ dln.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
dln.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
dln.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
dln.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-dln.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
dln.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
dln.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
dln.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -4650,6 +4316,7 @@ dln.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
dln.$(OBJEXT): {$(VPATH)}internal/intern/error.h
dln.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
dln.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dln.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
dln.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
dln.$(OBJEXT): {$(VPATH)}internal/intern/io.h
dln.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -4680,6 +4347,7 @@ dln.$(OBJEXT): {$(VPATH)}internal/memory.h
dln.$(OBJEXT): {$(VPATH)}internal/method.h
dln.$(OBJEXT): {$(VPATH)}internal/module.h
dln.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dln.$(OBJEXT): {$(VPATH)}internal/rgengc.h
dln.$(OBJEXT): {$(VPATH)}internal/scan_args.h
dln.$(OBJEXT): {$(VPATH)}internal/special_consts.h
dln.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -4747,7 +4415,6 @@ dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
dln_find.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-dln_find.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
dln_find.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
dln_find.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
dln_find.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -4807,6 +4474,7 @@ dln_find.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
dln_find.$(OBJEXT): {$(VPATH)}internal/intern/error.h
dln_find.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
dln_find.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
dln_find.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
dln_find.$(OBJEXT): {$(VPATH)}internal/intern/io.h
dln_find.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -4837,6 +4505,7 @@ dln_find.$(OBJEXT): {$(VPATH)}internal/memory.h
dln_find.$(OBJEXT): {$(VPATH)}internal/method.h
dln_find.$(OBJEXT): {$(VPATH)}internal/module.h
dln_find.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dln_find.$(OBJEXT): {$(VPATH)}internal/rgengc.h
dln_find.$(OBJEXT): {$(VPATH)}internal/scan_args.h
dln_find.$(OBJEXT): {$(VPATH)}internal/special_consts.h
dln_find.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -4903,7 +4572,6 @@ dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
dmydln.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-dmydln.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
dmydln.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
dmydln.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
dmydln.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -4963,6 +4631,7 @@ dmydln.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
dmydln.$(OBJEXT): {$(VPATH)}internal/intern/error.h
dmydln.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
dmydln.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
dmydln.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
dmydln.$(OBJEXT): {$(VPATH)}internal/intern/io.h
dmydln.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -4993,6 +4662,7 @@ dmydln.$(OBJEXT): {$(VPATH)}internal/memory.h
dmydln.$(OBJEXT): {$(VPATH)}internal/method.h
dmydln.$(OBJEXT): {$(VPATH)}internal/module.h
dmydln.$(OBJEXT): {$(VPATH)}internal/newobj.h
+dmydln.$(OBJEXT): {$(VPATH)}internal/rgengc.h
dmydln.$(OBJEXT): {$(VPATH)}internal/scan_args.h
dmydln.$(OBJEXT): {$(VPATH)}internal/special_consts.h
dmydln.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -5130,6 +4800,7 @@ enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -5160,6 +4831,7 @@ enc/ascii.$(OBJEXT): {$(VPATH)}internal/memory.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/method.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/module.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enc/ascii.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enc/ascii.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -5287,6 +4959,7 @@ enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -5317,6 +4990,7 @@ enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/memory.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/method.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/module.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -5444,6 +5118,7 @@ enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -5474,6 +5149,7 @@ enc/unicode.$(OBJEXT): {$(VPATH)}internal/memory.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/method.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/module.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enc/unicode.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enc/unicode.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -5612,6 +5288,7 @@ enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -5642,6 +5319,7 @@ enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/memory.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/method.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/module.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -5780,6 +5458,7 @@ enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -5810,6 +5489,7 @@ enc/utf_8.$(OBJEXT): {$(VPATH)}internal/memory.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/method.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/module.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enc/utf_8.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enc/utf_8.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -5827,22 +5507,14 @@ enc/utf_8.$(OBJEXT): {$(VPATH)}oniguruma.h
enc/utf_8.$(OBJEXT): {$(VPATH)}regenc.h
enc/utf_8.$(OBJEXT): {$(VPATH)}st.h
enc/utf_8.$(OBJEXT): {$(VPATH)}subst.h
-encoding.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-encoding.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-encoding.$(OBJEXT): $(CCAN_DIR)/list/list.h
-encoding.$(OBJEXT): $(CCAN_DIR)/str/str.h
encoding.$(OBJEXT): $(hdrdir)/ruby.h
encoding.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-encoding.$(OBJEXT): $(hdrdir)/ruby/version.h
-encoding.$(OBJEXT): $(top_srcdir)/internal/array.h
-encoding.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
encoding.$(OBJEXT): $(top_srcdir)/internal/class.h
encoding.$(OBJEXT): $(top_srcdir)/internal/compilers.h
encoding.$(OBJEXT): $(top_srcdir)/internal/enc.h
encoding.$(OBJEXT): $(top_srcdir)/internal/encoding.h
encoding.$(OBJEXT): $(top_srcdir)/internal/error.h
encoding.$(OBJEXT): $(top_srcdir)/internal/gc.h
-encoding.$(OBJEXT): $(top_srcdir)/internal/imemo.h
encoding.$(OBJEXT): $(top_srcdir)/internal/inits.h
encoding.$(OBJEXT): $(top_srcdir)/internal/load.h
encoding.$(OBJEXT): $(top_srcdir)/internal/object.h
@@ -5853,7 +5525,6 @@ encoding.$(OBJEXT): $(top_srcdir)/internal/variable.h
encoding.$(OBJEXT): $(top_srcdir)/internal/vm.h
encoding.$(OBJEXT): $(top_srcdir)/internal/warnings.h
encoding.$(OBJEXT): {$(VPATH)}assert.h
-encoding.$(OBJEXT): {$(VPATH)}atomic.h
encoding.$(OBJEXT): {$(VPATH)}backward/2/assume.h
encoding.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
encoding.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -5870,7 +5541,6 @@ encoding.$(OBJEXT): {$(VPATH)}defines.h
encoding.$(OBJEXT): {$(VPATH)}encindex.h
encoding.$(OBJEXT): {$(VPATH)}encoding.c
encoding.$(OBJEXT): {$(VPATH)}encoding.h
-encoding.$(OBJEXT): {$(VPATH)}id.h
encoding.$(OBJEXT): {$(VPATH)}id_table.h
encoding.$(OBJEXT): {$(VPATH)}intern.h
encoding.$(OBJEXT): {$(VPATH)}internal.h
@@ -5912,7 +5582,6 @@ encoding.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
encoding.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
encoding.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
encoding.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-encoding.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
encoding.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
encoding.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
encoding.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -5981,6 +5650,7 @@ encoding.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
encoding.$(OBJEXT): {$(VPATH)}internal/intern/error.h
encoding.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
encoding.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+encoding.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
encoding.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
encoding.$(OBJEXT): {$(VPATH)}internal/intern/io.h
encoding.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -6011,6 +5681,7 @@ encoding.$(OBJEXT): {$(VPATH)}internal/memory.h
encoding.$(OBJEXT): {$(VPATH)}internal/method.h
encoding.$(OBJEXT): {$(VPATH)}internal/module.h
encoding.$(OBJEXT): {$(VPATH)}internal/newobj.h
+encoding.$(OBJEXT): {$(VPATH)}internal/rgengc.h
encoding.$(OBJEXT): {$(VPATH)}internal/scan_args.h
encoding.$(OBJEXT): {$(VPATH)}internal/special_consts.h
encoding.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -6022,24 +5693,16 @@ encoding.$(OBJEXT): {$(VPATH)}internal/value_type.h
encoding.$(OBJEXT): {$(VPATH)}internal/variable.h
encoding.$(OBJEXT): {$(VPATH)}internal/warning_push.h
encoding.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-encoding.$(OBJEXT): {$(VPATH)}method.h
encoding.$(OBJEXT): {$(VPATH)}missing.h
-encoding.$(OBJEXT): {$(VPATH)}node.h
encoding.$(OBJEXT): {$(VPATH)}onigmo.h
encoding.$(OBJEXT): {$(VPATH)}oniguruma.h
encoding.$(OBJEXT): {$(VPATH)}regenc.h
encoding.$(OBJEXT): {$(VPATH)}ruby_assert.h
-encoding.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-encoding.$(OBJEXT): {$(VPATH)}rubyparser.h
encoding.$(OBJEXT): {$(VPATH)}shape.h
encoding.$(OBJEXT): {$(VPATH)}st.h
encoding.$(OBJEXT): {$(VPATH)}subst.h
-encoding.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-encoding.$(OBJEXT): {$(VPATH)}thread_native.h
encoding.$(OBJEXT): {$(VPATH)}util.h
-encoding.$(OBJEXT): {$(VPATH)}vm_core.h
encoding.$(OBJEXT): {$(VPATH)}vm_debug.h
-encoding.$(OBJEXT): {$(VPATH)}vm_opts.h
encoding.$(OBJEXT): {$(VPATH)}vm_sync.h
enum.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enum.$(OBJEXT): $(top_srcdir)/internal/array.h
@@ -6121,7 +5784,6 @@ enum.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
enum.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
enum.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
enum.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-enum.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
enum.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
enum.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
enum.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -6190,6 +5852,7 @@ enum.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enum.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enum.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enum.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enum.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enum.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enum.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enum.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -6220,6 +5883,7 @@ enum.$(OBJEXT): {$(VPATH)}internal/memory.h
enum.$(OBJEXT): {$(VPATH)}internal/method.h
enum.$(OBJEXT): {$(VPATH)}internal/module.h
enum.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enum.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enum.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enum.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enum.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -6245,7 +5909,6 @@ enumerator.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
enumerator.$(OBJEXT): $(CCAN_DIR)/list/list.h
enumerator.$(OBJEXT): $(CCAN_DIR)/str/str.h
enumerator.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-enumerator.$(OBJEXT): $(hdrdir)/ruby/version.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/array.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -6265,7 +5928,6 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/serial.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/string.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/struct.h
-enumerator.$(OBJEXT): $(top_srcdir)/internal/variable.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/vm.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/warnings.h
enumerator.$(OBJEXT): {$(VPATH)}assert.h
@@ -6280,8 +5942,6 @@ enumerator.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
enumerator.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
enumerator.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
enumerator.$(OBJEXT): {$(VPATH)}config.h
-enumerator.$(OBJEXT): {$(VPATH)}constant.h
-enumerator.$(OBJEXT): {$(VPATH)}debug_counter.h
enumerator.$(OBJEXT): {$(VPATH)}defines.h
enumerator.$(OBJEXT): {$(VPATH)}encoding.h
enumerator.$(OBJEXT): {$(VPATH)}enumerator.c
@@ -6327,7 +5987,6 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
enumerator.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-enumerator.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
enumerator.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
enumerator.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
enumerator.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -6396,6 +6055,7 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
enumerator.$(OBJEXT): {$(VPATH)}internal/intern/error.h
enumerator.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
enumerator.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
enumerator.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
enumerator.$(OBJEXT): {$(VPATH)}internal/intern/io.h
enumerator.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -6426,6 +6086,7 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/memory.h
enumerator.$(OBJEXT): {$(VPATH)}internal/method.h
enumerator.$(OBJEXT): {$(VPATH)}internal/module.h
enumerator.$(OBJEXT): {$(VPATH)}internal/newobj.h
+enumerator.$(OBJEXT): {$(VPATH)}internal/rgengc.h
enumerator.$(OBJEXT): {$(VPATH)}internal/scan_args.h
enumerator.$(OBJEXT): {$(VPATH)}internal/special_consts.h
enumerator.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -6444,22 +6105,18 @@ enumerator.$(OBJEXT): {$(VPATH)}onigmo.h
enumerator.$(OBJEXT): {$(VPATH)}oniguruma.h
enumerator.$(OBJEXT): {$(VPATH)}ruby_assert.h
enumerator.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-enumerator.$(OBJEXT): {$(VPATH)}rubyparser.h
enumerator.$(OBJEXT): {$(VPATH)}shape.h
enumerator.$(OBJEXT): {$(VPATH)}st.h
enumerator.$(OBJEXT): {$(VPATH)}subst.h
enumerator.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
enumerator.$(OBJEXT): {$(VPATH)}thread_native.h
enumerator.$(OBJEXT): {$(VPATH)}vm_core.h
-enumerator.$(OBJEXT): {$(VPATH)}vm_debug.h
enumerator.$(OBJEXT): {$(VPATH)}vm_opts.h
-enumerator.$(OBJEXT): {$(VPATH)}vm_sync.h
error.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
error.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
error.$(OBJEXT): $(CCAN_DIR)/list/list.h
error.$(OBJEXT): $(CCAN_DIR)/str/str.h
error.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-error.$(OBJEXT): $(hdrdir)/ruby/version.h
error.$(OBJEXT): $(top_srcdir)/internal/array.h
error.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
error.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -6472,7 +6129,6 @@ error.$(OBJEXT): $(top_srcdir)/internal/imemo.h
error.$(OBJEXT): $(top_srcdir)/internal/io.h
error.$(OBJEXT): $(top_srcdir)/internal/load.h
error.$(OBJEXT): $(top_srcdir)/internal/object.h
-error.$(OBJEXT): $(top_srcdir)/internal/process.h
error.$(OBJEXT): $(top_srcdir)/internal/serial.h
error.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
error.$(OBJEXT): $(top_srcdir)/internal/string.h
@@ -6540,7 +6196,6 @@ error.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
error.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
error.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
error.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-error.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
error.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
error.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
error.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -6609,6 +6264,7 @@ error.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
error.$(OBJEXT): {$(VPATH)}internal/intern/error.h
error.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
error.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+error.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
error.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
error.$(OBJEXT): {$(VPATH)}internal/intern/io.h
error.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -6639,6 +6295,7 @@ error.$(OBJEXT): {$(VPATH)}internal/memory.h
error.$(OBJEXT): {$(VPATH)}internal/method.h
error.$(OBJEXT): {$(VPATH)}internal/module.h
error.$(OBJEXT): {$(VPATH)}internal/newobj.h
+error.$(OBJEXT): {$(VPATH)}internal/rgengc.h
error.$(OBJEXT): {$(VPATH)}internal/scan_args.h
error.$(OBJEXT): {$(VPATH)}internal/special_consts.h
error.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -6659,13 +6316,11 @@ error.$(OBJEXT): {$(VPATH)}onigmo.h
error.$(OBJEXT): {$(VPATH)}oniguruma.h
error.$(OBJEXT): {$(VPATH)}ruby_assert.h
error.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-error.$(OBJEXT): {$(VPATH)}rubyparser.h
error.$(OBJEXT): {$(VPATH)}shape.h
error.$(OBJEXT): {$(VPATH)}st.h
error.$(OBJEXT): {$(VPATH)}subst.h
error.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
error.$(OBJEXT): {$(VPATH)}thread_native.h
-error.$(OBJEXT): {$(VPATH)}util.h
error.$(OBJEXT): {$(VPATH)}vm_core.h
error.$(OBJEXT): {$(VPATH)}vm_opts.h
error.$(OBJEXT): {$(VPATH)}warning.rbinc
@@ -6675,7 +6330,6 @@ eval.$(OBJEXT): $(CCAN_DIR)/list/list.h
eval.$(OBJEXT): $(CCAN_DIR)/str/str.h
eval.$(OBJEXT): $(hdrdir)/ruby.h
eval.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-eval.$(OBJEXT): $(hdrdir)/ruby/version.h
eval.$(OBJEXT): $(top_srcdir)/internal/array.h
eval.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
eval.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -6696,27 +6350,6 @@ eval.$(OBJEXT): $(top_srcdir)/internal/thread.h
eval.$(OBJEXT): $(top_srcdir)/internal/variable.h
eval.$(OBJEXT): $(top_srcdir)/internal/vm.h
eval.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-eval.$(OBJEXT): $(top_srcdir)/prism/defines.h
-eval.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-eval.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-eval.$(OBJEXT): $(top_srcdir)/prism/node.h
-eval.$(OBJEXT): $(top_srcdir)/prism/options.h
-eval.$(OBJEXT): $(top_srcdir)/prism/pack.h
-eval.$(OBJEXT): $(top_srcdir)/prism/parser.h
-eval.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-eval.$(OBJEXT): $(top_srcdir)/prism/prism.h
-eval.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
eval.$(OBJEXT): {$(VPATH)}assert.h
eval.$(OBJEXT): {$(VPATH)}atomic.h
eval.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -6738,6 +6371,7 @@ eval.$(OBJEXT): {$(VPATH)}eval_error.c
eval.$(OBJEXT): {$(VPATH)}eval_intern.h
eval.$(OBJEXT): {$(VPATH)}eval_jump.c
eval.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
+eval.$(OBJEXT): {$(VPATH)}gc.h
eval.$(OBJEXT): {$(VPATH)}id.h
eval.$(OBJEXT): {$(VPATH)}id_table.h
eval.$(OBJEXT): {$(VPATH)}intern.h
@@ -6780,7 +6414,6 @@ eval.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
eval.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
eval.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
eval.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-eval.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
eval.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
eval.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
eval.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -6849,6 +6482,7 @@ eval.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
eval.$(OBJEXT): {$(VPATH)}internal/intern/error.h
eval.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
eval.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+eval.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
eval.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
eval.$(OBJEXT): {$(VPATH)}internal/intern/io.h
eval.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -6879,6 +6513,7 @@ eval.$(OBJEXT): {$(VPATH)}internal/memory.h
eval.$(OBJEXT): {$(VPATH)}internal/method.h
eval.$(OBJEXT): {$(VPATH)}internal/module.h
eval.$(OBJEXT): {$(VPATH)}internal/newobj.h
+eval.$(OBJEXT): {$(VPATH)}internal/rgengc.h
eval.$(OBJEXT): {$(VPATH)}internal/scan_args.h
eval.$(OBJEXT): {$(VPATH)}internal/special_consts.h
eval.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -6894,21 +6529,17 @@ eval.$(OBJEXT): {$(VPATH)}io.h
eval.$(OBJEXT): {$(VPATH)}iseq.h
eval.$(OBJEXT): {$(VPATH)}method.h
eval.$(OBJEXT): {$(VPATH)}missing.h
+eval.$(OBJEXT): {$(VPATH)}mjit.h
eval.$(OBJEXT): {$(VPATH)}node.h
eval.$(OBJEXT): {$(VPATH)}onigmo.h
eval.$(OBJEXT): {$(VPATH)}oniguruma.h
-eval.$(OBJEXT): {$(VPATH)}prism/ast.h
-eval.$(OBJEXT): {$(VPATH)}prism/version.h
-eval.$(OBJEXT): {$(VPATH)}prism_compile.h
eval.$(OBJEXT): {$(VPATH)}probes.dmyh
eval.$(OBJEXT): {$(VPATH)}probes.h
eval.$(OBJEXT): {$(VPATH)}probes_helper.h
eval.$(OBJEXT): {$(VPATH)}ractor.h
eval.$(OBJEXT): {$(VPATH)}ractor_core.h
-eval.$(OBJEXT): {$(VPATH)}rjit.h
eval.$(OBJEXT): {$(VPATH)}ruby_assert.h
eval.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-eval.$(OBJEXT): {$(VPATH)}rubyparser.h
eval.$(OBJEXT): {$(VPATH)}shape.h
eval.$(OBJEXT): {$(VPATH)}st.h
eval.$(OBJEXT): {$(VPATH)}subst.h
@@ -6918,7 +6549,6 @@ eval.$(OBJEXT): {$(VPATH)}vm.h
eval.$(OBJEXT): {$(VPATH)}vm_core.h
eval.$(OBJEXT): {$(VPATH)}vm_debug.h
eval.$(OBJEXT): {$(VPATH)}vm_opts.h
-eval.$(OBJEXT): {$(VPATH)}vm_sync.h
explicit_bzero.$(OBJEXT): {$(VPATH)}config.h
explicit_bzero.$(OBJEXT): {$(VPATH)}explicit_bzero.c
explicit_bzero.$(OBJEXT): {$(VPATH)}internal/attr/format.h
@@ -6934,12 +6564,7 @@ explicit_bzero.$(OBJEXT): {$(VPATH)}internal/config.h
explicit_bzero.$(OBJEXT): {$(VPATH)}internal/dllexport.h
explicit_bzero.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
explicit_bzero.$(OBJEXT): {$(VPATH)}missing.h
-file.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-file.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-file.$(OBJEXT): $(CCAN_DIR)/list/list.h
-file.$(OBJEXT): $(CCAN_DIR)/str/str.h
file.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-file.$(OBJEXT): $(hdrdir)/ruby/version.h
file.$(OBJEXT): $(top_srcdir)/internal/array.h
file.$(OBJEXT): $(top_srcdir)/internal/class.h
file.$(OBJEXT): $(top_srcdir)/internal/compilers.h
@@ -7018,7 +6643,6 @@ file.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
file.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
file.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
file.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-file.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
file.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
file.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
file.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -7087,6 +6711,7 @@ file.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
file.$(OBJEXT): {$(VPATH)}internal/intern/error.h
file.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
file.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+file.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
file.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
file.$(OBJEXT): {$(VPATH)}internal/intern/io.h
file.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -7117,6 +6742,7 @@ file.$(OBJEXT): {$(VPATH)}internal/memory.h
file.$(OBJEXT): {$(VPATH)}internal/method.h
file.$(OBJEXT): {$(VPATH)}internal/module.h
file.$(OBJEXT): {$(VPATH)}internal/newobj.h
+file.$(OBJEXT): {$(VPATH)}internal/rgengc.h
file.$(OBJEXT): {$(VPATH)}internal/scan_args.h
file.$(OBJEXT): {$(VPATH)}internal/special_consts.h
file.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -7136,7 +6762,6 @@ file.$(OBJEXT): {$(VPATH)}shape.h
file.$(OBJEXT): {$(VPATH)}st.h
file.$(OBJEXT): {$(VPATH)}subst.h
file.$(OBJEXT): {$(VPATH)}thread.h
-file.$(OBJEXT): {$(VPATH)}thread_native.h
file.$(OBJEXT): {$(VPATH)}util.h
gc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
gc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
@@ -7144,13 +6769,11 @@ gc.$(OBJEXT): $(CCAN_DIR)/list/list.h
gc.$(OBJEXT): $(CCAN_DIR)/str/str.h
gc.$(OBJEXT): $(hdrdir)/ruby.h
gc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-gc.$(OBJEXT): $(hdrdir)/ruby/version.h
gc.$(OBJEXT): $(top_srcdir)/internal/array.h
gc.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
gc.$(OBJEXT): $(top_srcdir)/internal/bignum.h
gc.$(OBJEXT): $(top_srcdir)/internal/bits.h
gc.$(OBJEXT): $(top_srcdir)/internal/class.h
-gc.$(OBJEXT): $(top_srcdir)/internal/compile.h
gc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
gc.$(OBJEXT): $(top_srcdir)/internal/complex.h
gc.$(OBJEXT): $(top_srcdir)/internal/cont.h
@@ -7175,27 +6798,6 @@ gc.$(OBJEXT): $(top_srcdir)/internal/thread.h
gc.$(OBJEXT): $(top_srcdir)/internal/variable.h
gc.$(OBJEXT): $(top_srcdir)/internal/vm.h
gc.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-gc.$(OBJEXT): $(top_srcdir)/prism/defines.h
-gc.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-gc.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-gc.$(OBJEXT): $(top_srcdir)/prism/node.h
-gc.$(OBJEXT): $(top_srcdir)/prism/options.h
-gc.$(OBJEXT): $(top_srcdir)/prism/pack.h
-gc.$(OBJEXT): $(top_srcdir)/prism/parser.h
-gc.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-gc.$(OBJEXT): $(top_srcdir)/prism/prism.h
-gc.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
gc.$(OBJEXT): {$(VPATH)}assert.h
gc.$(OBJEXT): {$(VPATH)}atomic.h
gc.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -7210,13 +6812,13 @@ gc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
gc.$(OBJEXT): {$(VPATH)}builtin.h
gc.$(OBJEXT): {$(VPATH)}config.h
gc.$(OBJEXT): {$(VPATH)}constant.h
-gc.$(OBJEXT): {$(VPATH)}darray.h
gc.$(OBJEXT): {$(VPATH)}debug.h
gc.$(OBJEXT): {$(VPATH)}debug_counter.h
gc.$(OBJEXT): {$(VPATH)}defines.h
gc.$(OBJEXT): {$(VPATH)}encoding.h
gc.$(OBJEXT): {$(VPATH)}eval_intern.h
gc.$(OBJEXT): {$(VPATH)}gc.c
+gc.$(OBJEXT): {$(VPATH)}gc.h
gc.$(OBJEXT): {$(VPATH)}gc.rbinc
gc.$(OBJEXT): {$(VPATH)}id.h
gc.$(OBJEXT): {$(VPATH)}id_table.h
@@ -7260,7 +6862,6 @@ gc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
gc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
gc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
gc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-gc.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
gc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
gc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
gc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -7330,6 +6931,7 @@ gc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
gc.$(OBJEXT): {$(VPATH)}internal/intern/error.h
gc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
gc.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+gc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
gc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
gc.$(OBJEXT): {$(VPATH)}internal/intern/io.h
gc.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -7360,6 +6962,7 @@ gc.$(OBJEXT): {$(VPATH)}internal/memory.h
gc.$(OBJEXT): {$(VPATH)}internal/method.h
gc.$(OBJEXT): {$(VPATH)}internal/module.h
gc.$(OBJEXT): {$(VPATH)}internal/newobj.h
+gc.$(OBJEXT): {$(VPATH)}internal/rgengc.h
gc.$(OBJEXT): {$(VPATH)}internal/scan_args.h
gc.$(OBJEXT): {$(VPATH)}internal/special_consts.h
gc.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -7375,12 +6978,10 @@ gc.$(OBJEXT): {$(VPATH)}io.h
gc.$(OBJEXT): {$(VPATH)}iseq.h
gc.$(OBJEXT): {$(VPATH)}method.h
gc.$(OBJEXT): {$(VPATH)}missing.h
+gc.$(OBJEXT): {$(VPATH)}mjit.h
gc.$(OBJEXT): {$(VPATH)}node.h
gc.$(OBJEXT): {$(VPATH)}onigmo.h
gc.$(OBJEXT): {$(VPATH)}oniguruma.h
-gc.$(OBJEXT): {$(VPATH)}prism/ast.h
-gc.$(OBJEXT): {$(VPATH)}prism/version.h
-gc.$(OBJEXT): {$(VPATH)}prism_compile.h
gc.$(OBJEXT): {$(VPATH)}probes.dmyh
gc.$(OBJEXT): {$(VPATH)}probes.h
gc.$(OBJEXT): {$(VPATH)}ractor.h
@@ -7389,10 +6990,8 @@ gc.$(OBJEXT): {$(VPATH)}re.h
gc.$(OBJEXT): {$(VPATH)}regenc.h
gc.$(OBJEXT): {$(VPATH)}regex.h
gc.$(OBJEXT): {$(VPATH)}regint.h
-gc.$(OBJEXT): {$(VPATH)}rjit.h
gc.$(OBJEXT): {$(VPATH)}ruby_assert.h
gc.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-gc.$(OBJEXT): {$(VPATH)}rubyparser.h
gc.$(OBJEXT): {$(VPATH)}shape.h
gc.$(OBJEXT): {$(VPATH)}st.h
gc.$(OBJEXT): {$(VPATH)}subst.h
@@ -7400,6 +6999,7 @@ gc.$(OBJEXT): {$(VPATH)}symbol.h
gc.$(OBJEXT): {$(VPATH)}thread.h
gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
gc.$(OBJEXT): {$(VPATH)}thread_native.h
+gc.$(OBJEXT): {$(VPATH)}transient_heap.h
gc.$(OBJEXT): {$(VPATH)}util.h
gc.$(OBJEXT): {$(VPATH)}vm_callinfo.h
gc.$(OBJEXT): {$(VPATH)}vm_core.h
@@ -7417,33 +7017,11 @@ goruby.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
goruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h
goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-goruby.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
goruby.$(OBJEXT): $(top_srcdir)/internal/serial.h
goruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
goruby.$(OBJEXT): $(top_srcdir)/internal/variable.h
goruby.$(OBJEXT): $(top_srcdir)/internal/vm.h
goruby.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/defines.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/node.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/options.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/pack.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/parser.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/prism.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
goruby.$(OBJEXT): {$(VPATH)}assert.h
goruby.$(OBJEXT): {$(VPATH)}atomic.h
goruby.$(OBJEXT): {$(VPATH)}backward.h
@@ -7459,7 +7037,6 @@ goruby.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
goruby.$(OBJEXT): {$(VPATH)}config.h
goruby.$(OBJEXT): {$(VPATH)}constant.h
goruby.$(OBJEXT): {$(VPATH)}defines.h
-goruby.$(OBJEXT): {$(VPATH)}encoding.h
goruby.$(OBJEXT): {$(VPATH)}golf_prelude.c
goruby.$(OBJEXT): {$(VPATH)}goruby.c
goruby.$(OBJEXT): {$(VPATH)}id.h
@@ -7503,8 +7080,8 @@ goruby.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-goruby.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -7537,15 +7114,6 @@ goruby.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
goruby.$(OBJEXT): {$(VPATH)}internal/ctype.h
goruby.$(OBJEXT): {$(VPATH)}internal/dllexport.h
goruby.$(OBJEXT): {$(VPATH)}internal/dosish.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-goruby.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
goruby.$(OBJEXT): {$(VPATH)}internal/error.h
goruby.$(OBJEXT): {$(VPATH)}internal/eval.h
goruby.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -7573,6 +7141,7 @@ goruby.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
goruby.$(OBJEXT): {$(VPATH)}internal/intern/error.h
goruby.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
goruby.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+goruby.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
goruby.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
goruby.$(OBJEXT): {$(VPATH)}internal/intern/io.h
goruby.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -7603,6 +7172,7 @@ goruby.$(OBJEXT): {$(VPATH)}internal/memory.h
goruby.$(OBJEXT): {$(VPATH)}internal/method.h
goruby.$(OBJEXT): {$(VPATH)}internal/module.h
goruby.$(OBJEXT): {$(VPATH)}internal/newobj.h
+goruby.$(OBJEXT): {$(VPATH)}internal/rgengc.h
goruby.$(OBJEXT): {$(VPATH)}internal/scan_args.h
goruby.$(OBJEXT): {$(VPATH)}internal/special_consts.h
goruby.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -7619,14 +7189,8 @@ goruby.$(OBJEXT): {$(VPATH)}main.c
goruby.$(OBJEXT): {$(VPATH)}method.h
goruby.$(OBJEXT): {$(VPATH)}missing.h
goruby.$(OBJEXT): {$(VPATH)}node.h
-goruby.$(OBJEXT): {$(VPATH)}onigmo.h
-goruby.$(OBJEXT): {$(VPATH)}oniguruma.h
-goruby.$(OBJEXT): {$(VPATH)}prism/ast.h
-goruby.$(OBJEXT): {$(VPATH)}prism/version.h
-goruby.$(OBJEXT): {$(VPATH)}prism_compile.h
goruby.$(OBJEXT): {$(VPATH)}ruby_assert.h
goruby.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-goruby.$(OBJEXT): {$(VPATH)}rubyparser.h
goruby.$(OBJEXT): {$(VPATH)}shape.h
goruby.$(OBJEXT): {$(VPATH)}st.h
goruby.$(OBJEXT): {$(VPATH)}subst.h
@@ -7640,7 +7204,6 @@ hash.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
hash.$(OBJEXT): $(CCAN_DIR)/list/list.h
hash.$(OBJEXT): $(CCAN_DIR)/str/str.h
hash.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-hash.$(OBJEXT): $(hdrdir)/ruby/version.h
hash.$(OBJEXT): $(top_srcdir)/internal/array.h
hash.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
hash.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -7663,27 +7226,6 @@ hash.$(OBJEXT): $(top_srcdir)/internal/time.h
hash.$(OBJEXT): $(top_srcdir)/internal/variable.h
hash.$(OBJEXT): $(top_srcdir)/internal/vm.h
hash.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-hash.$(OBJEXT): $(top_srcdir)/prism/defines.h
-hash.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-hash.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-hash.$(OBJEXT): $(top_srcdir)/prism/node.h
-hash.$(OBJEXT): $(top_srcdir)/prism/options.h
-hash.$(OBJEXT): $(top_srcdir)/prism/pack.h
-hash.$(OBJEXT): $(top_srcdir)/prism/parser.h
-hash.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-hash.$(OBJEXT): $(top_srcdir)/prism/prism.h
-hash.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
hash.$(OBJEXT): {$(VPATH)}assert.h
hash.$(OBJEXT): {$(VPATH)}atomic.h
hash.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -7743,7 +7285,6 @@ hash.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
hash.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
hash.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
hash.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-hash.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
hash.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
hash.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
hash.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -7812,6 +7353,7 @@ hash.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
hash.$(OBJEXT): {$(VPATH)}internal/intern/error.h
hash.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
hash.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+hash.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
hash.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
hash.$(OBJEXT): {$(VPATH)}internal/intern/io.h
hash.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -7842,6 +7384,7 @@ hash.$(OBJEXT): {$(VPATH)}internal/memory.h
hash.$(OBJEXT): {$(VPATH)}internal/method.h
hash.$(OBJEXT): {$(VPATH)}internal/module.h
hash.$(OBJEXT): {$(VPATH)}internal/newobj.h
+hash.$(OBJEXT): {$(VPATH)}internal/rgengc.h
hash.$(OBJEXT): {$(VPATH)}internal/scan_args.h
hash.$(OBJEXT): {$(VPATH)}internal/special_consts.h
hash.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -7859,21 +7402,18 @@ hash.$(OBJEXT): {$(VPATH)}missing.h
hash.$(OBJEXT): {$(VPATH)}node.h
hash.$(OBJEXT): {$(VPATH)}onigmo.h
hash.$(OBJEXT): {$(VPATH)}oniguruma.h
-hash.$(OBJEXT): {$(VPATH)}prism/ast.h
-hash.$(OBJEXT): {$(VPATH)}prism/version.h
-hash.$(OBJEXT): {$(VPATH)}prism_compile.h
hash.$(OBJEXT): {$(VPATH)}probes.dmyh
hash.$(OBJEXT): {$(VPATH)}probes.h
hash.$(OBJEXT): {$(VPATH)}ractor.h
hash.$(OBJEXT): {$(VPATH)}ruby_assert.h
hash.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-hash.$(OBJEXT): {$(VPATH)}rubyparser.h
hash.$(OBJEXT): {$(VPATH)}shape.h
hash.$(OBJEXT): {$(VPATH)}st.h
hash.$(OBJEXT): {$(VPATH)}subst.h
hash.$(OBJEXT): {$(VPATH)}symbol.h
hash.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
hash.$(OBJEXT): {$(VPATH)}thread_native.h
+hash.$(OBJEXT): {$(VPATH)}transient_heap.h
hash.$(OBJEXT): {$(VPATH)}util.h
hash.$(OBJEXT): {$(VPATH)}vm_core.h
hash.$(OBJEXT): {$(VPATH)}vm_debug.h
@@ -7937,7 +7477,6 @@ inits.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
inits.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
inits.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
inits.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-inits.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
inits.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
inits.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
inits.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -7997,6 +7536,7 @@ inits.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
inits.$(OBJEXT): {$(VPATH)}internal/intern/error.h
inits.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
inits.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+inits.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
inits.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
inits.$(OBJEXT): {$(VPATH)}internal/intern/io.h
inits.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -8027,6 +7567,7 @@ inits.$(OBJEXT): {$(VPATH)}internal/memory.h
inits.$(OBJEXT): {$(VPATH)}internal/method.h
inits.$(OBJEXT): {$(VPATH)}internal/module.h
inits.$(OBJEXT): {$(VPATH)}internal/newobj.h
+inits.$(OBJEXT): {$(VPATH)}internal/rgengc.h
inits.$(OBJEXT): {$(VPATH)}internal/scan_args.h
inits.$(OBJEXT): {$(VPATH)}internal/special_consts.h
inits.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -8047,7 +7588,6 @@ io.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
io.$(OBJEXT): $(CCAN_DIR)/list/list.h
io.$(OBJEXT): $(CCAN_DIR)/str/str.h
io.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-io.$(OBJEXT): $(hdrdir)/ruby/version.h
io.$(OBJEXT): $(top_srcdir)/internal/array.h
io.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
io.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -8133,7 +7673,6 @@ io.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
io.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
io.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
io.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-io.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
io.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
io.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
io.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -8202,6 +7741,7 @@ io.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
io.$(OBJEXT): {$(VPATH)}internal/intern/error.h
io.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
io.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+io.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
io.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
io.$(OBJEXT): {$(VPATH)}internal/intern/io.h
io.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -8232,6 +7772,7 @@ io.$(OBJEXT): {$(VPATH)}internal/memory.h
io.$(OBJEXT): {$(VPATH)}internal/method.h
io.$(OBJEXT): {$(VPATH)}internal/module.h
io.$(OBJEXT): {$(VPATH)}internal/newobj.h
+io.$(OBJEXT): {$(VPATH)}internal/rgengc.h
io.$(OBJEXT): {$(VPATH)}internal/scan_args.h
io.$(OBJEXT): {$(VPATH)}internal/special_consts.h
io.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -8255,7 +7796,6 @@ io.$(OBJEXT): {$(VPATH)}oniguruma.h
io.$(OBJEXT): {$(VPATH)}ractor.h
io.$(OBJEXT): {$(VPATH)}ruby_assert.h
io.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-io.$(OBJEXT): {$(VPATH)}rubyparser.h
io.$(OBJEXT): {$(VPATH)}shape.h
io.$(OBJEXT): {$(VPATH)}st.h
io.$(OBJEXT): {$(VPATH)}subst.h
@@ -8265,12 +7805,7 @@ io.$(OBJEXT): {$(VPATH)}thread_native.h
io.$(OBJEXT): {$(VPATH)}util.h
io.$(OBJEXT): {$(VPATH)}vm_core.h
io.$(OBJEXT): {$(VPATH)}vm_opts.h
-io_buffer.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-io_buffer.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-io_buffer.$(OBJEXT): $(CCAN_DIR)/list/list.h
-io_buffer.$(OBJEXT): $(CCAN_DIR)/str/str.h
io_buffer.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-io_buffer.$(OBJEXT): $(hdrdir)/ruby/version.h
io_buffer.$(OBJEXT): $(top_srcdir)/internal/array.h
io_buffer.$(OBJEXT): $(top_srcdir)/internal/bignum.h
io_buffer.$(OBJEXT): $(top_srcdir)/internal/bits.h
@@ -8337,7 +7872,6 @@ io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -8406,6 +7940,7 @@ io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/error.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/io.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -8436,6 +7971,7 @@ io_buffer.$(OBJEXT): {$(VPATH)}internal/memory.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/method.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/module.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/newobj.h
+io_buffer.$(OBJEXT): {$(VPATH)}internal/rgengc.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/scan_args.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/special_consts.h
io_buffer.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -8455,14 +7991,12 @@ io_buffer.$(OBJEXT): {$(VPATH)}onigmo.h
io_buffer.$(OBJEXT): {$(VPATH)}oniguruma.h
io_buffer.$(OBJEXT): {$(VPATH)}st.h
io_buffer.$(OBJEXT): {$(VPATH)}subst.h
-io_buffer.$(OBJEXT): {$(VPATH)}thread_native.h
iseq.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
iseq.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
iseq.$(OBJEXT): $(CCAN_DIR)/list/list.h
iseq.$(OBJEXT): $(CCAN_DIR)/str/str.h
iseq.$(OBJEXT): $(hdrdir)/ruby.h
iseq.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-iseq.$(OBJEXT): $(hdrdir)/ruby/version.h
iseq.$(OBJEXT): $(top_srcdir)/internal/array.h
iseq.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
iseq.$(OBJEXT): $(top_srcdir)/internal/bits.h
@@ -8475,7 +8009,6 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h
iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h
iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h
iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h
-iseq.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
iseq.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
iseq.$(OBJEXT): $(top_srcdir)/internal/serial.h
iseq.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@@ -8485,27 +8018,6 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/thread.h
iseq.$(OBJEXT): $(top_srcdir)/internal/variable.h
iseq.$(OBJEXT): $(top_srcdir)/internal/vm.h
iseq.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/defines.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/node.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/options.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/pack.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/parser.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
iseq.$(OBJEXT): {$(VPATH)}assert.h
iseq.$(OBJEXT): {$(VPATH)}atomic.h
iseq.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -8524,6 +8036,7 @@ iseq.$(OBJEXT): {$(VPATH)}debug_counter.h
iseq.$(OBJEXT): {$(VPATH)}defines.h
iseq.$(OBJEXT): {$(VPATH)}encoding.h
iseq.$(OBJEXT): {$(VPATH)}eval_intern.h
+iseq.$(OBJEXT): {$(VPATH)}gc.h
iseq.$(OBJEXT): {$(VPATH)}id.h
iseq.$(OBJEXT): {$(VPATH)}id_table.h
iseq.$(OBJEXT): {$(VPATH)}insns.def
@@ -8569,7 +8082,6 @@ iseq.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
iseq.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
iseq.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
iseq.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-iseq.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
iseq.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
iseq.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
iseq.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -8638,6 +8150,7 @@ iseq.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
iseq.$(OBJEXT): {$(VPATH)}internal/intern/error.h
iseq.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
iseq.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+iseq.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
iseq.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
iseq.$(OBJEXT): {$(VPATH)}internal/intern/io.h
iseq.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -8668,6 +8181,7 @@ iseq.$(OBJEXT): {$(VPATH)}internal/memory.h
iseq.$(OBJEXT): {$(VPATH)}internal/method.h
iseq.$(OBJEXT): {$(VPATH)}internal/module.h
iseq.$(OBJEXT): {$(VPATH)}internal/newobj.h
+iseq.$(OBJEXT): {$(VPATH)}internal/rgengc.h
iseq.$(OBJEXT): {$(VPATH)}internal/scan_args.h
iseq.$(OBJEXT): {$(VPATH)}internal/special_consts.h
iseq.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -8683,18 +8197,14 @@ iseq.$(OBJEXT): {$(VPATH)}iseq.c
iseq.$(OBJEXT): {$(VPATH)}iseq.h
iseq.$(OBJEXT): {$(VPATH)}method.h
iseq.$(OBJEXT): {$(VPATH)}missing.h
+iseq.$(OBJEXT): {$(VPATH)}mjit.h
iseq.$(OBJEXT): {$(VPATH)}node.h
+iseq.$(OBJEXT): {$(VPATH)}node_name.inc
iseq.$(OBJEXT): {$(VPATH)}onigmo.h
iseq.$(OBJEXT): {$(VPATH)}oniguruma.h
-iseq.$(OBJEXT): {$(VPATH)}prism/ast.h
-iseq.$(OBJEXT): {$(VPATH)}prism/prism.h
-iseq.$(OBJEXT): {$(VPATH)}prism/version.h
-iseq.$(OBJEXT): {$(VPATH)}prism_compile.h
iseq.$(OBJEXT): {$(VPATH)}ractor.h
-iseq.$(OBJEXT): {$(VPATH)}rjit.h
iseq.$(OBJEXT): {$(VPATH)}ruby_assert.h
iseq.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-iseq.$(OBJEXT): {$(VPATH)}rubyparser.h
iseq.$(OBJEXT): {$(VPATH)}shape.h
iseq.$(OBJEXT): {$(VPATH)}st.h
iseq.$(OBJEXT): {$(VPATH)}subst.h
@@ -8703,29 +8213,23 @@ iseq.$(OBJEXT): {$(VPATH)}thread_native.h
iseq.$(OBJEXT): {$(VPATH)}util.h
iseq.$(OBJEXT): {$(VPATH)}vm_callinfo.h
iseq.$(OBJEXT): {$(VPATH)}vm_core.h
-iseq.$(OBJEXT): {$(VPATH)}vm_debug.h
iseq.$(OBJEXT): {$(VPATH)}vm_opts.h
-iseq.$(OBJEXT): {$(VPATH)}vm_sync.h
iseq.$(OBJEXT): {$(VPATH)}yjit.h
load.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
load.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
load.$(OBJEXT): $(CCAN_DIR)/list/list.h
load.$(OBJEXT): $(CCAN_DIR)/str/str.h
load.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-load.$(OBJEXT): $(hdrdir)/ruby/version.h
load.$(OBJEXT): $(top_srcdir)/internal/array.h
load.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-load.$(OBJEXT): $(top_srcdir)/internal/bits.h
load.$(OBJEXT): $(top_srcdir)/internal/compilers.h
load.$(OBJEXT): $(top_srcdir)/internal/dir.h
load.$(OBJEXT): $(top_srcdir)/internal/error.h
load.$(OBJEXT): $(top_srcdir)/internal/file.h
load.$(OBJEXT): $(top_srcdir)/internal/gc.h
-load.$(OBJEXT): $(top_srcdir)/internal/hash.h
load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
load.$(OBJEXT): $(top_srcdir)/internal/load.h
load.$(OBJEXT): $(top_srcdir)/internal/parse.h
-load.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
load.$(OBJEXT): $(top_srcdir)/internal/serial.h
load.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
load.$(OBJEXT): $(top_srcdir)/internal/string.h
@@ -8733,27 +8237,6 @@ load.$(OBJEXT): $(top_srcdir)/internal/thread.h
load.$(OBJEXT): $(top_srcdir)/internal/variable.h
load.$(OBJEXT): $(top_srcdir)/internal/vm.h
load.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-load.$(OBJEXT): $(top_srcdir)/prism/defines.h
-load.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-load.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-load.$(OBJEXT): $(top_srcdir)/prism/node.h
-load.$(OBJEXT): $(top_srcdir)/prism/options.h
-load.$(OBJEXT): $(top_srcdir)/prism/pack.h
-load.$(OBJEXT): $(top_srcdir)/prism/parser.h
-load.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-load.$(OBJEXT): $(top_srcdir)/prism/prism.h
-load.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-load.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
load.$(OBJEXT): {$(VPATH)}assert.h
load.$(OBJEXT): {$(VPATH)}atomic.h
load.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -8814,7 +8297,6 @@ load.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
load.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
load.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
load.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-load.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
load.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
load.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
load.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -8883,6 +8365,7 @@ load.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
load.$(OBJEXT): {$(VPATH)}internal/intern/error.h
load.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
load.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+load.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
load.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
load.$(OBJEXT): {$(VPATH)}internal/intern/io.h
load.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -8913,6 +8396,7 @@ load.$(OBJEXT): {$(VPATH)}internal/memory.h
load.$(OBJEXT): {$(VPATH)}internal/method.h
load.$(OBJEXT): {$(VPATH)}internal/module.h
load.$(OBJEXT): {$(VPATH)}internal/newobj.h
+load.$(OBJEXT): {$(VPATH)}internal/rgengc.h
load.$(OBJEXT): {$(VPATH)}internal/scan_args.h
load.$(OBJEXT): {$(VPATH)}internal/special_consts.h
load.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -8931,14 +8415,10 @@ load.$(OBJEXT): {$(VPATH)}missing.h
load.$(OBJEXT): {$(VPATH)}node.h
load.$(OBJEXT): {$(VPATH)}onigmo.h
load.$(OBJEXT): {$(VPATH)}oniguruma.h
-load.$(OBJEXT): {$(VPATH)}prism/ast.h
-load.$(OBJEXT): {$(VPATH)}prism/version.h
-load.$(OBJEXT): {$(VPATH)}prism_compile.h
load.$(OBJEXT): {$(VPATH)}probes.dmyh
load.$(OBJEXT): {$(VPATH)}probes.h
load.$(OBJEXT): {$(VPATH)}ruby_assert.h
load.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-load.$(OBJEXT): {$(VPATH)}rubyparser.h
load.$(OBJEXT): {$(VPATH)}shape.h
load.$(OBJEXT): {$(VPATH)}st.h
load.$(OBJEXT): {$(VPATH)}subst.h
@@ -9000,7 +8480,6 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
loadpath.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-loadpath.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
loadpath.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
loadpath.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
loadpath.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -9060,6 +8539,7 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
loadpath.$(OBJEXT): {$(VPATH)}internal/intern/error.h
loadpath.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
loadpath.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
loadpath.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
loadpath.$(OBJEXT): {$(VPATH)}internal/intern/io.h
loadpath.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -9090,6 +8570,7 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/memory.h
loadpath.$(OBJEXT): {$(VPATH)}internal/method.h
loadpath.$(OBJEXT): {$(VPATH)}internal/module.h
loadpath.$(OBJEXT): {$(VPATH)}internal/newobj.h
+loadpath.$(OBJEXT): {$(VPATH)}internal/rgengc.h
loadpath.$(OBJEXT): {$(VPATH)}internal/scan_args.h
loadpath.$(OBJEXT): {$(VPATH)}internal/special_consts.h
loadpath.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -9160,7 +8641,6 @@ localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
localeinit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-localeinit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
localeinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
localeinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
localeinit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -9229,6 +8709,7 @@ localeinit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
localeinit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
localeinit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
localeinit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
localeinit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
localeinit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
localeinit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -9259,6 +8740,7 @@ localeinit.$(OBJEXT): {$(VPATH)}internal/memory.h
localeinit.$(OBJEXT): {$(VPATH)}internal/method.h
localeinit.$(OBJEXT): {$(VPATH)}internal/module.h
localeinit.$(OBJEXT): {$(VPATH)}internal/newobj.h
+localeinit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
localeinit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
localeinit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
localeinit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -9329,7 +8811,6 @@ main.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
main.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
main.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
main.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-main.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
main.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
main.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
main.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -9389,6 +8870,7 @@ main.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
main.$(OBJEXT): {$(VPATH)}internal/intern/error.h
main.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
main.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+main.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
main.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
main.$(OBJEXT): {$(VPATH)}internal/intern/io.h
main.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -9419,6 +8901,7 @@ main.$(OBJEXT): {$(VPATH)}internal/memory.h
main.$(OBJEXT): {$(VPATH)}internal/method.h
main.$(OBJEXT): {$(VPATH)}internal/module.h
main.$(OBJEXT): {$(VPATH)}internal/newobj.h
+main.$(OBJEXT): {$(VPATH)}internal/rgengc.h
main.$(OBJEXT): {$(VPATH)}internal/scan_args.h
main.$(OBJEXT): {$(VPATH)}internal/special_consts.h
main.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -9440,7 +8923,6 @@ marshal.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
marshal.$(OBJEXT): $(CCAN_DIR)/list/list.h
marshal.$(OBJEXT): $(CCAN_DIR)/str/str.h
marshal.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-marshal.$(OBJEXT): $(hdrdir)/ruby/version.h
marshal.$(OBJEXT): $(top_srcdir)/internal/array.h
marshal.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
marshal.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -9478,7 +8960,6 @@ marshal.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
marshal.$(OBJEXT): {$(VPATH)}builtin.h
marshal.$(OBJEXT): {$(VPATH)}config.h
marshal.$(OBJEXT): {$(VPATH)}constant.h
-marshal.$(OBJEXT): {$(VPATH)}debug_counter.h
marshal.$(OBJEXT): {$(VPATH)}defines.h
marshal.$(OBJEXT): {$(VPATH)}encindex.h
marshal.$(OBJEXT): {$(VPATH)}encoding.h
@@ -9523,8 +9004,8 @@ marshal.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-marshal.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -9593,6 +9074,7 @@ marshal.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
marshal.$(OBJEXT): {$(VPATH)}internal/intern/error.h
marshal.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
marshal.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+marshal.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
marshal.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
marshal.$(OBJEXT): {$(VPATH)}internal/intern/io.h
marshal.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -9623,6 +9105,7 @@ marshal.$(OBJEXT): {$(VPATH)}internal/memory.h
marshal.$(OBJEXT): {$(VPATH)}internal/method.h
marshal.$(OBJEXT): {$(VPATH)}internal/module.h
marshal.$(OBJEXT): {$(VPATH)}internal/newobj.h
+marshal.$(OBJEXT): {$(VPATH)}internal/rgengc.h
marshal.$(OBJEXT): {$(VPATH)}internal/scan_args.h
marshal.$(OBJEXT): {$(VPATH)}internal/special_consts.h
marshal.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -9644,7 +9127,6 @@ marshal.$(OBJEXT): {$(VPATH)}onigmo.h
marshal.$(OBJEXT): {$(VPATH)}oniguruma.h
marshal.$(OBJEXT): {$(VPATH)}ruby_assert.h
marshal.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-marshal.$(OBJEXT): {$(VPATH)}rubyparser.h
marshal.$(OBJEXT): {$(VPATH)}shape.h
marshal.$(OBJEXT): {$(VPATH)}st.h
marshal.$(OBJEXT): {$(VPATH)}subst.h
@@ -9652,9 +9134,7 @@ marshal.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
marshal.$(OBJEXT): {$(VPATH)}thread_native.h
marshal.$(OBJEXT): {$(VPATH)}util.h
marshal.$(OBJEXT): {$(VPATH)}vm_core.h
-marshal.$(OBJEXT): {$(VPATH)}vm_debug.h
marshal.$(OBJEXT): {$(VPATH)}vm_opts.h
-marshal.$(OBJEXT): {$(VPATH)}vm_sync.h
math.$(OBJEXT): $(hdrdir)/ruby/ruby.h
math.$(OBJEXT): $(top_srcdir)/internal/bignum.h
math.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -9722,7 +9202,6 @@ math.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
math.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
math.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
math.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-math.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
math.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
math.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
math.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -9782,6 +9261,7 @@ math.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
math.$(OBJEXT): {$(VPATH)}internal/intern/error.h
math.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
math.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+math.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
math.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
math.$(OBJEXT): {$(VPATH)}internal/intern/io.h
math.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -9812,6 +9292,7 @@ math.$(OBJEXT): {$(VPATH)}internal/memory.h
math.$(OBJEXT): {$(VPATH)}internal/method.h
math.$(OBJEXT): {$(VPATH)}internal/module.h
math.$(OBJEXT): {$(VPATH)}internal/newobj.h
+math.$(OBJEXT): {$(VPATH)}internal/rgengc.h
math.$(OBJEXT): {$(VPATH)}internal/scan_args.h
math.$(OBJEXT): {$(VPATH)}internal/special_consts.h
math.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -9828,24 +9309,13 @@ math.$(OBJEXT): {$(VPATH)}missing.h
math.$(OBJEXT): {$(VPATH)}shape.h
math.$(OBJEXT): {$(VPATH)}st.h
math.$(OBJEXT): {$(VPATH)}subst.h
-memory_view.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-memory_view.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-memory_view.$(OBJEXT): $(CCAN_DIR)/list/list.h
-memory_view.$(OBJEXT): $(CCAN_DIR)/str/str.h
memory_view.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-memory_view.$(OBJEXT): $(top_srcdir)/internal/array.h
-memory_view.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/gc.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h
-memory_view.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h
-memory_view.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/variable.h
-memory_view.$(OBJEXT): $(top_srcdir)/internal/vm.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/warnings.h
memory_view.$(OBJEXT): {$(VPATH)}assert.h
-memory_view.$(OBJEXT): {$(VPATH)}atomic.h
memory_view.$(OBJEXT): {$(VPATH)}backward/2/assume.h
memory_view.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
memory_view.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -9859,8 +9329,6 @@ memory_view.$(OBJEXT): {$(VPATH)}config.h
memory_view.$(OBJEXT): {$(VPATH)}constant.h
memory_view.$(OBJEXT): {$(VPATH)}debug_counter.h
memory_view.$(OBJEXT): {$(VPATH)}defines.h
-memory_view.$(OBJEXT): {$(VPATH)}encoding.h
-memory_view.$(OBJEXT): {$(VPATH)}id.h
memory_view.$(OBJEXT): {$(VPATH)}id_table.h
memory_view.$(OBJEXT): {$(VPATH)}intern.h
memory_view.$(OBJEXT): {$(VPATH)}internal.h
@@ -9902,7 +9370,6 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
memory_view.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
memory_view.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
memory_view.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
memory_view.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -9935,15 +9402,6 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
memory_view.$(OBJEXT): {$(VPATH)}internal/ctype.h
memory_view.$(OBJEXT): {$(VPATH)}internal/dllexport.h
memory_view.$(OBJEXT): {$(VPATH)}internal/dosish.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
memory_view.$(OBJEXT): {$(VPATH)}internal/error.h
memory_view.$(OBJEXT): {$(VPATH)}internal/eval.h
memory_view.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -9971,6 +9429,7 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
memory_view.$(OBJEXT): {$(VPATH)}internal/intern/error.h
memory_view.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
memory_view.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
memory_view.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
memory_view.$(OBJEXT): {$(VPATH)}internal/intern/io.h
memory_view.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -10001,6 +9460,7 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/memory.h
memory_view.$(OBJEXT): {$(VPATH)}internal/method.h
memory_view.$(OBJEXT): {$(VPATH)}internal/module.h
memory_view.$(OBJEXT): {$(VPATH)}internal/newobj.h
+memory_view.$(OBJEXT): {$(VPATH)}internal/rgengc.h
memory_view.$(OBJEXT): {$(VPATH)}internal/scan_args.h
memory_view.$(OBJEXT): {$(VPATH)}internal/special_consts.h
memory_view.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -10014,62 +9474,29 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/warning_push.h
memory_view.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
memory_view.$(OBJEXT): {$(VPATH)}memory_view.c
memory_view.$(OBJEXT): {$(VPATH)}memory_view.h
-memory_view.$(OBJEXT): {$(VPATH)}method.h
memory_view.$(OBJEXT): {$(VPATH)}missing.h
-memory_view.$(OBJEXT): {$(VPATH)}node.h
-memory_view.$(OBJEXT): {$(VPATH)}onigmo.h
-memory_view.$(OBJEXT): {$(VPATH)}oniguruma.h
-memory_view.$(OBJEXT): {$(VPATH)}ruby_assert.h
-memory_view.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-memory_view.$(OBJEXT): {$(VPATH)}rubyparser.h
memory_view.$(OBJEXT): {$(VPATH)}shape.h
memory_view.$(OBJEXT): {$(VPATH)}st.h
memory_view.$(OBJEXT): {$(VPATH)}subst.h
-memory_view.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-memory_view.$(OBJEXT): {$(VPATH)}thread_native.h
memory_view.$(OBJEXT): {$(VPATH)}util.h
-memory_view.$(OBJEXT): {$(VPATH)}vm_core.h
memory_view.$(OBJEXT): {$(VPATH)}vm_debug.h
-memory_view.$(OBJEXT): {$(VPATH)}vm_opts.h
memory_view.$(OBJEXT): {$(VPATH)}vm_sync.h
miniinit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
miniinit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
miniinit.$(OBJEXT): $(CCAN_DIR)/list/list.h
miniinit.$(OBJEXT): $(CCAN_DIR)/str/str.h
miniinit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-miniinit.$(OBJEXT): $(srcdir)/rjit_c.rb
+miniinit.$(OBJEXT): $(srcdir)/mjit_c.rb
miniinit.$(OBJEXT): $(top_srcdir)/internal/array.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-miniinit.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/serial.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/variable.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/vm.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/defines.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/node.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/options.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/pack.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/parser.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/prism.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
miniinit.$(OBJEXT): {$(VPATH)}array.rb
miniinit.$(OBJEXT): {$(VPATH)}assert.h
miniinit.$(OBJEXT): {$(VPATH)}ast.rb
@@ -10132,8 +9559,8 @@ miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-miniinit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -10202,6 +9629,7 @@ miniinit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
miniinit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
miniinit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
miniinit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
miniinit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
miniinit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
miniinit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -10232,6 +9660,7 @@ miniinit.$(OBJEXT): {$(VPATH)}internal/memory.h
miniinit.$(OBJEXT): {$(VPATH)}internal/method.h
miniinit.$(OBJEXT): {$(VPATH)}internal/module.h
miniinit.$(OBJEXT): {$(VPATH)}internal/newobj.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
miniinit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
miniinit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
miniinit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -10252,6 +9681,8 @@ miniinit.$(OBJEXT): {$(VPATH)}mini_builtin.c
miniinit.$(OBJEXT): {$(VPATH)}miniinit.c
miniinit.$(OBJEXT): {$(VPATH)}miniprelude.c
miniinit.$(OBJEXT): {$(VPATH)}missing.h
+miniinit.$(OBJEXT): {$(VPATH)}mjit.rb
+miniinit.$(OBJEXT): {$(VPATH)}mjit_c.rb
miniinit.$(OBJEXT): {$(VPATH)}nilclass.rb
miniinit.$(OBJEXT): {$(VPATH)}node.h
miniinit.$(OBJEXT): {$(VPATH)}numeric.rb
@@ -10259,15 +9690,9 @@ miniinit.$(OBJEXT): {$(VPATH)}onigmo.h
miniinit.$(OBJEXT): {$(VPATH)}oniguruma.h
miniinit.$(OBJEXT): {$(VPATH)}pack.rb
miniinit.$(OBJEXT): {$(VPATH)}prelude.rb
-miniinit.$(OBJEXT): {$(VPATH)}prism/ast.h
-miniinit.$(OBJEXT): {$(VPATH)}prism/version.h
-miniinit.$(OBJEXT): {$(VPATH)}prism_compile.h
miniinit.$(OBJEXT): {$(VPATH)}ractor.rb
-miniinit.$(OBJEXT): {$(VPATH)}rjit.rb
-miniinit.$(OBJEXT): {$(VPATH)}rjit_c.rb
miniinit.$(OBJEXT): {$(VPATH)}ruby_assert.h
miniinit.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-miniinit.$(OBJEXT): {$(VPATH)}rubyparser.h
miniinit.$(OBJEXT): {$(VPATH)}shape.h
miniinit.$(OBJEXT): {$(VPATH)}st.h
miniinit.$(OBJEXT): {$(VPATH)}subst.h
@@ -10281,6 +9706,441 @@ miniinit.$(OBJEXT): {$(VPATH)}vm_core.h
miniinit.$(OBJEXT): {$(VPATH)}vm_opts.h
miniinit.$(OBJEXT): {$(VPATH)}warning.rb
miniinit.$(OBJEXT): {$(VPATH)}yjit.rb
+mjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+mjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+mjit.$(OBJEXT): $(CCAN_DIR)/list/list.h
+mjit.$(OBJEXT): $(CCAN_DIR)/str/str.h
+mjit.$(OBJEXT): $(hdrdir)/ruby.h
+mjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+mjit.$(OBJEXT): $(hdrdir)/ruby/version.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/array.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/class.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/compile.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/cont.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/file.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/process.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/variable.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/vm.h
+mjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+mjit.$(OBJEXT): {$(VPATH)}assert.h
+mjit.$(OBJEXT): {$(VPATH)}atomic.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+mjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+mjit.$(OBJEXT): {$(VPATH)}builtin.h
+mjit.$(OBJEXT): {$(VPATH)}config.h
+mjit.$(OBJEXT): {$(VPATH)}constant.h
+mjit.$(OBJEXT): {$(VPATH)}debug.h
+mjit.$(OBJEXT): {$(VPATH)}debug_counter.h
+mjit.$(OBJEXT): {$(VPATH)}defines.h
+mjit.$(OBJEXT): {$(VPATH)}dln.h
+mjit.$(OBJEXT): {$(VPATH)}encoding.h
+mjit.$(OBJEXT): {$(VPATH)}gc.h
+mjit.$(OBJEXT): {$(VPATH)}id.h
+mjit.$(OBJEXT): {$(VPATH)}id_table.h
+mjit.$(OBJEXT): {$(VPATH)}insns.def
+mjit.$(OBJEXT): {$(VPATH)}insns.inc
+mjit.$(OBJEXT): {$(VPATH)}insns_info.inc
+mjit.$(OBJEXT): {$(VPATH)}intern.h
+mjit.$(OBJEXT): {$(VPATH)}internal.h
+mjit.$(OBJEXT): {$(VPATH)}internal/abi.h
+mjit.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+mjit.$(OBJEXT): {$(VPATH)}internal/assume.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+mjit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+mjit.$(OBJEXT): {$(VPATH)}internal/cast.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+mjit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+mjit.$(OBJEXT): {$(VPATH)}internal/config.h
+mjit.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+mjit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+mjit.$(OBJEXT): {$(VPATH)}internal/ctype.h
+mjit.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+mjit.$(OBJEXT): {$(VPATH)}internal/dosish.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
+mjit.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
+mjit.$(OBJEXT): {$(VPATH)}internal/error.h
+mjit.$(OBJEXT): {$(VPATH)}internal/eval.h
+mjit.$(OBJEXT): {$(VPATH)}internal/event.h
+mjit.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+mjit.$(OBJEXT): {$(VPATH)}internal/gc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/glob.h
+mjit.$(OBJEXT): {$(VPATH)}internal/globals.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+mjit.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+mjit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+mjit.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+mjit.$(OBJEXT): {$(VPATH)}internal/iterator.h
+mjit.$(OBJEXT): {$(VPATH)}internal/memory.h
+mjit.$(OBJEXT): {$(VPATH)}internal/method.h
+mjit.$(OBJEXT): {$(VPATH)}internal/module.h
+mjit.$(OBJEXT): {$(VPATH)}internal/newobj.h
+mjit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+mjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+mjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+mjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+mjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+mjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+mjit.$(OBJEXT): {$(VPATH)}internal/symbol.h
+mjit.$(OBJEXT): {$(VPATH)}internal/value.h
+mjit.$(OBJEXT): {$(VPATH)}internal/value_type.h
+mjit.$(OBJEXT): {$(VPATH)}internal/variable.h
+mjit.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+mjit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+mjit.$(OBJEXT): {$(VPATH)}iseq.h
+mjit.$(OBJEXT): {$(VPATH)}method.h
+mjit.$(OBJEXT): {$(VPATH)}missing.h
+mjit.$(OBJEXT): {$(VPATH)}mjit.c
+mjit.$(OBJEXT): {$(VPATH)}mjit.h
+mjit.$(OBJEXT): {$(VPATH)}mjit.rbinc
+mjit.$(OBJEXT): {$(VPATH)}mjit_c.h
+mjit.$(OBJEXT): {$(VPATH)}mjit_config.h
+mjit.$(OBJEXT): {$(VPATH)}node.h
+mjit.$(OBJEXT): {$(VPATH)}onigmo.h
+mjit.$(OBJEXT): {$(VPATH)}oniguruma.h
+mjit.$(OBJEXT): {$(VPATH)}ractor.h
+mjit.$(OBJEXT): {$(VPATH)}ractor_core.h
+mjit.$(OBJEXT): {$(VPATH)}ruby_assert.h
+mjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+mjit.$(OBJEXT): {$(VPATH)}shape.h
+mjit.$(OBJEXT): {$(VPATH)}st.h
+mjit.$(OBJEXT): {$(VPATH)}subst.h
+mjit.$(OBJEXT): {$(VPATH)}thread.h
+mjit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+mjit.$(OBJEXT): {$(VPATH)}thread_native.h
+mjit.$(OBJEXT): {$(VPATH)}util.h
+mjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h
+mjit.$(OBJEXT): {$(VPATH)}vm_core.h
+mjit.$(OBJEXT): {$(VPATH)}vm_debug.h
+mjit.$(OBJEXT): {$(VPATH)}vm_opts.h
+mjit.$(OBJEXT): {$(VPATH)}vm_sync.h
+mjit.$(OBJEXT): {$(VPATH)}yjit.h
+mjit_c.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+mjit_c.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+mjit_c.$(OBJEXT): $(CCAN_DIR)/list/list.h
+mjit_c.$(OBJEXT): $(CCAN_DIR)/str/str.h
+mjit_c.$(OBJEXT): $(hdrdir)/ruby.h
+mjit_c.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+mjit_c.$(OBJEXT): $(srcdir)/mjit_c.rb
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/array.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/class.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/compile.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/gc.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/hash.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/imemo.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/object.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/serial.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/variable.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/vm.h
+mjit_c.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+mjit_c.$(OBJEXT): {$(VPATH)}assert.h
+mjit_c.$(OBJEXT): {$(VPATH)}atomic.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+mjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+mjit_c.$(OBJEXT): {$(VPATH)}builtin.h
+mjit_c.$(OBJEXT): {$(VPATH)}config.h
+mjit_c.$(OBJEXT): {$(VPATH)}constant.h
+mjit_c.$(OBJEXT): {$(VPATH)}debug_counter.h
+mjit_c.$(OBJEXT): {$(VPATH)}defines.h
+mjit_c.$(OBJEXT): {$(VPATH)}id.h
+mjit_c.$(OBJEXT): {$(VPATH)}id_table.h
+mjit_c.$(OBJEXT): {$(VPATH)}insns.def
+mjit_c.$(OBJEXT): {$(VPATH)}insns.inc
+mjit_c.$(OBJEXT): {$(VPATH)}insns_info.inc
+mjit_c.$(OBJEXT): {$(VPATH)}intern.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/abi.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/assume.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/cast.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/config.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/ctype.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/dosish.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/error.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/eval.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/event.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/gc.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/glob.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/globals.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/iterator.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/memory.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/method.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/module.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/newobj.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/symbol.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/value.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/value_type.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/variable.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+mjit_c.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+mjit_c.$(OBJEXT): {$(VPATH)}iseq.h
+mjit_c.$(OBJEXT): {$(VPATH)}method.h
+mjit_c.$(OBJEXT): {$(VPATH)}missing.h
+mjit_c.$(OBJEXT): {$(VPATH)}mjit.h
+mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.c
+mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.h
+mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.rb
+mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.rbinc
+mjit_c.$(OBJEXT): {$(VPATH)}mjit_sp_inc.inc
+mjit_c.$(OBJEXT): {$(VPATH)}node.h
+mjit_c.$(OBJEXT): {$(VPATH)}ruby_assert.h
+mjit_c.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+mjit_c.$(OBJEXT): {$(VPATH)}shape.h
+mjit_c.$(OBJEXT): {$(VPATH)}st.h
+mjit_c.$(OBJEXT): {$(VPATH)}subst.h
+mjit_c.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+mjit_c.$(OBJEXT): {$(VPATH)}thread_native.h
+mjit_c.$(OBJEXT): {$(VPATH)}vm_callinfo.h
+mjit_c.$(OBJEXT): {$(VPATH)}vm_core.h
+mjit_c.$(OBJEXT): {$(VPATH)}vm_exec.h
+mjit_c.$(OBJEXT): {$(VPATH)}vm_insnhelper.h
+mjit_c.$(OBJEXT): {$(VPATH)}vm_opts.h
+mjit_c.$(OBJEXT): {$(VPATH)}yjit.h
node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
node.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -10311,7 +10171,6 @@ node.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
node.$(OBJEXT): {$(VPATH)}config.h
node.$(OBJEXT): {$(VPATH)}constant.h
node.$(OBJEXT): {$(VPATH)}defines.h
-node.$(OBJEXT): {$(VPATH)}encoding.h
node.$(OBJEXT): {$(VPATH)}id.h
node.$(OBJEXT): {$(VPATH)}id_table.h
node.$(OBJEXT): {$(VPATH)}intern.h
@@ -10354,7 +10213,6 @@ node.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
node.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
node.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
node.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-node.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
node.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
node.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
node.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -10387,15 +10245,6 @@ node.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
node.$(OBJEXT): {$(VPATH)}internal/ctype.h
node.$(OBJEXT): {$(VPATH)}internal/dllexport.h
node.$(OBJEXT): {$(VPATH)}internal/dosish.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-node.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
node.$(OBJEXT): {$(VPATH)}internal/error.h
node.$(OBJEXT): {$(VPATH)}internal/eval.h
node.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -10423,6 +10272,7 @@ node.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
node.$(OBJEXT): {$(VPATH)}internal/intern/error.h
node.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
node.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+node.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
node.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
node.$(OBJEXT): {$(VPATH)}internal/intern/io.h
node.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -10453,6 +10303,7 @@ node.$(OBJEXT): {$(VPATH)}internal/memory.h
node.$(OBJEXT): {$(VPATH)}internal/method.h
node.$(OBJEXT): {$(VPATH)}internal/module.h
node.$(OBJEXT): {$(VPATH)}internal/newobj.h
+node.$(OBJEXT): {$(VPATH)}internal/rgengc.h
node.$(OBJEXT): {$(VPATH)}internal/scan_args.h
node.$(OBJEXT): {$(VPATH)}internal/special_consts.h
node.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -10468,12 +10319,8 @@ node.$(OBJEXT): {$(VPATH)}method.h
node.$(OBJEXT): {$(VPATH)}missing.h
node.$(OBJEXT): {$(VPATH)}node.c
node.$(OBJEXT): {$(VPATH)}node.h
-node.$(OBJEXT): {$(VPATH)}node_name.inc
-node.$(OBJEXT): {$(VPATH)}onigmo.h
-node.$(OBJEXT): {$(VPATH)}oniguruma.h
node.$(OBJEXT): {$(VPATH)}ruby_assert.h
node.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-node.$(OBJEXT): {$(VPATH)}rubyparser.h
node.$(OBJEXT): {$(VPATH)}shape.h
node.$(OBJEXT): {$(VPATH)}st.h
node.$(OBJEXT): {$(VPATH)}subst.h
@@ -10481,212 +10328,8 @@ node.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
node.$(OBJEXT): {$(VPATH)}thread_native.h
node.$(OBJEXT): {$(VPATH)}vm_core.h
node.$(OBJEXT): {$(VPATH)}vm_opts.h
-node_dump.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-node_dump.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-node_dump.$(OBJEXT): $(CCAN_DIR)/list/list.h
-node_dump.$(OBJEXT): $(CCAN_DIR)/str/str.h
-node_dump.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/array.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h
-node_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-node_dump.$(OBJEXT): {$(VPATH)}assert.h
-node_dump.$(OBJEXT): {$(VPATH)}atomic.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-node_dump.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-node_dump.$(OBJEXT): {$(VPATH)}config.h
-node_dump.$(OBJEXT): {$(VPATH)}constant.h
-node_dump.$(OBJEXT): {$(VPATH)}defines.h
-node_dump.$(OBJEXT): {$(VPATH)}encoding.h
-node_dump.$(OBJEXT): {$(VPATH)}id.h
-node_dump.$(OBJEXT): {$(VPATH)}id_table.h
-node_dump.$(OBJEXT): {$(VPATH)}intern.h
-node_dump.$(OBJEXT): {$(VPATH)}internal.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/abi.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/assume.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/cast.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/config.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/ctype.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/dosish.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/error.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/eval.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/event.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/gc.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/glob.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/globals.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/iterator.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/memory.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/method.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/module.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/newobj.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/symbol.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/value.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/value_type.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/variable.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-node_dump.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-node_dump.$(OBJEXT): {$(VPATH)}method.h
-node_dump.$(OBJEXT): {$(VPATH)}missing.h
-node_dump.$(OBJEXT): {$(VPATH)}node.h
-node_dump.$(OBJEXT): {$(VPATH)}node_dump.c
-node_dump.$(OBJEXT): {$(VPATH)}onigmo.h
-node_dump.$(OBJEXT): {$(VPATH)}oniguruma.h
-node_dump.$(OBJEXT): {$(VPATH)}ruby_assert.h
-node_dump.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-node_dump.$(OBJEXT): {$(VPATH)}rubyparser.h
-node_dump.$(OBJEXT): {$(VPATH)}shape.h
-node_dump.$(OBJEXT): {$(VPATH)}st.h
-node_dump.$(OBJEXT): {$(VPATH)}subst.h
-node_dump.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-node_dump.$(OBJEXT): {$(VPATH)}thread_native.h
-node_dump.$(OBJEXT): {$(VPATH)}vm_core.h
-node_dump.$(OBJEXT): {$(VPATH)}vm_opts.h
-numeric.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-numeric.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-numeric.$(OBJEXT): $(CCAN_DIR)/list/list.h
-numeric.$(OBJEXT): $(CCAN_DIR)/str/str.h
numeric.$(OBJEXT): $(hdrdir)/ruby/ruby.h
numeric.$(OBJEXT): $(top_srcdir)/internal/array.h
-numeric.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
numeric.$(OBJEXT): $(top_srcdir)/internal/bignum.h
numeric.$(OBJEXT): $(top_srcdir)/internal/bits.h
numeric.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -10696,7 +10339,6 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/enumerator.h
numeric.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h
numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h
-numeric.$(OBJEXT): $(top_srcdir)/internal/imemo.h
numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h
numeric.$(OBJEXT): $(top_srcdir)/internal/object.h
numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -10708,7 +10350,6 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/variable.h
numeric.$(OBJEXT): $(top_srcdir)/internal/vm.h
numeric.$(OBJEXT): $(top_srcdir)/internal/warnings.h
numeric.$(OBJEXT): {$(VPATH)}assert.h
-numeric.$(OBJEXT): {$(VPATH)}atomic.h
numeric.$(OBJEXT): {$(VPATH)}backward/2/assume.h
numeric.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
numeric.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -10765,7 +10406,6 @@ numeric.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
numeric.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
numeric.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
numeric.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-numeric.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
numeric.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
numeric.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
numeric.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -10834,6 +10474,7 @@ numeric.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
numeric.$(OBJEXT): {$(VPATH)}internal/intern/error.h
numeric.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
numeric.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+numeric.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
numeric.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
numeric.$(OBJEXT): {$(VPATH)}internal/intern/io.h
numeric.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -10864,6 +10505,7 @@ numeric.$(OBJEXT): {$(VPATH)}internal/memory.h
numeric.$(OBJEXT): {$(VPATH)}internal/method.h
numeric.$(OBJEXT): {$(VPATH)}internal/module.h
numeric.$(OBJEXT): {$(VPATH)}internal/newobj.h
+numeric.$(OBJEXT): {$(VPATH)}internal/rgengc.h
numeric.$(OBJEXT): {$(VPATH)}internal/scan_args.h
numeric.$(OBJEXT): {$(VPATH)}internal/special_consts.h
numeric.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -10875,30 +10517,21 @@ numeric.$(OBJEXT): {$(VPATH)}internal/value_type.h
numeric.$(OBJEXT): {$(VPATH)}internal/variable.h
numeric.$(OBJEXT): {$(VPATH)}internal/warning_push.h
numeric.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-numeric.$(OBJEXT): {$(VPATH)}method.h
numeric.$(OBJEXT): {$(VPATH)}missing.h
-numeric.$(OBJEXT): {$(VPATH)}node.h
numeric.$(OBJEXT): {$(VPATH)}numeric.c
numeric.$(OBJEXT): {$(VPATH)}numeric.rbinc
numeric.$(OBJEXT): {$(VPATH)}onigmo.h
numeric.$(OBJEXT): {$(VPATH)}oniguruma.h
numeric.$(OBJEXT): {$(VPATH)}ruby_assert.h
-numeric.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-numeric.$(OBJEXT): {$(VPATH)}rubyparser.h
numeric.$(OBJEXT): {$(VPATH)}shape.h
numeric.$(OBJEXT): {$(VPATH)}st.h
numeric.$(OBJEXT): {$(VPATH)}subst.h
-numeric.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-numeric.$(OBJEXT): {$(VPATH)}thread_native.h
numeric.$(OBJEXT): {$(VPATH)}util.h
-numeric.$(OBJEXT): {$(VPATH)}vm_core.h
-numeric.$(OBJEXT): {$(VPATH)}vm_opts.h
object.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
object.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
object.$(OBJEXT): $(CCAN_DIR)/list/list.h
object.$(OBJEXT): $(CCAN_DIR)/str/str.h
object.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-object.$(OBJEXT): $(hdrdir)/ruby/version.h
object.$(OBJEXT): $(top_srcdir)/internal/array.h
object.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
object.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -10935,7 +10568,6 @@ object.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
object.$(OBJEXT): {$(VPATH)}builtin.h
object.$(OBJEXT): {$(VPATH)}config.h
object.$(OBJEXT): {$(VPATH)}constant.h
-object.$(OBJEXT): {$(VPATH)}debug_counter.h
object.$(OBJEXT): {$(VPATH)}defines.h
object.$(OBJEXT): {$(VPATH)}encoding.h
object.$(OBJEXT): {$(VPATH)}id.h
@@ -10980,7 +10612,6 @@ object.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
object.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
object.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
object.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-object.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
object.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
object.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
object.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -11049,6 +10680,7 @@ object.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
object.$(OBJEXT): {$(VPATH)}internal/intern/error.h
object.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
object.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+object.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
object.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
object.$(OBJEXT): {$(VPATH)}internal/intern/io.h
object.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -11079,6 +10711,7 @@ object.$(OBJEXT): {$(VPATH)}internal/memory.h
object.$(OBJEXT): {$(VPATH)}internal/method.h
object.$(OBJEXT): {$(VPATH)}internal/module.h
object.$(OBJEXT): {$(VPATH)}internal/newobj.h
+object.$(OBJEXT): {$(VPATH)}internal/rgengc.h
object.$(OBJEXT): {$(VPATH)}internal/scan_args.h
object.$(OBJEXT): {$(VPATH)}internal/special_consts.h
object.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -11102,7 +10735,6 @@ object.$(OBJEXT): {$(VPATH)}probes.dmyh
object.$(OBJEXT): {$(VPATH)}probes.h
object.$(OBJEXT): {$(VPATH)}ruby_assert.h
object.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-object.$(OBJEXT): {$(VPATH)}rubyparser.h
object.$(OBJEXT): {$(VPATH)}shape.h
object.$(OBJEXT): {$(VPATH)}st.h
object.$(OBJEXT): {$(VPATH)}subst.h
@@ -11111,29 +10743,18 @@ object.$(OBJEXT): {$(VPATH)}thread_native.h
object.$(OBJEXT): {$(VPATH)}util.h
object.$(OBJEXT): {$(VPATH)}variable.h
object.$(OBJEXT): {$(VPATH)}vm_core.h
-object.$(OBJEXT): {$(VPATH)}vm_debug.h
object.$(OBJEXT): {$(VPATH)}vm_opts.h
-object.$(OBJEXT): {$(VPATH)}vm_sync.h
-pack.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-pack.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-pack.$(OBJEXT): $(CCAN_DIR)/list/list.h
-pack.$(OBJEXT): $(CCAN_DIR)/str/str.h
pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h
pack.$(OBJEXT): $(top_srcdir)/internal/array.h
-pack.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
pack.$(OBJEXT): $(top_srcdir)/internal/bits.h
pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h
pack.$(OBJEXT): $(top_srcdir)/internal/gc.h
-pack.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-pack.$(OBJEXT): $(top_srcdir)/internal/serial.h
pack.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
pack.$(OBJEXT): $(top_srcdir)/internal/string.h
pack.$(OBJEXT): $(top_srcdir)/internal/symbol.h
pack.$(OBJEXT): $(top_srcdir)/internal/variable.h
-pack.$(OBJEXT): $(top_srcdir)/internal/vm.h
pack.$(OBJEXT): $(top_srcdir)/internal/warnings.h
pack.$(OBJEXT): {$(VPATH)}assert.h
-pack.$(OBJEXT): {$(VPATH)}atomic.h
pack.$(OBJEXT): {$(VPATH)}backward/2/assume.h
pack.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
pack.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -11148,7 +10769,6 @@ pack.$(OBJEXT): {$(VPATH)}config.h
pack.$(OBJEXT): {$(VPATH)}constant.h
pack.$(OBJEXT): {$(VPATH)}defines.h
pack.$(OBJEXT): {$(VPATH)}encoding.h
-pack.$(OBJEXT): {$(VPATH)}id.h
pack.$(OBJEXT): {$(VPATH)}id_table.h
pack.$(OBJEXT): {$(VPATH)}intern.h
pack.$(OBJEXT): {$(VPATH)}internal.h
@@ -11190,7 +10810,6 @@ pack.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
pack.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
pack.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
pack.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-pack.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
pack.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
pack.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
pack.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -11259,6 +10878,7 @@ pack.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
pack.$(OBJEXT): {$(VPATH)}internal/intern/error.h
pack.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
pack.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+pack.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
pack.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
pack.$(OBJEXT): {$(VPATH)}internal/intern/io.h
pack.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -11289,6 +10909,7 @@ pack.$(OBJEXT): {$(VPATH)}internal/memory.h
pack.$(OBJEXT): {$(VPATH)}internal/method.h
pack.$(OBJEXT): {$(VPATH)}internal/module.h
pack.$(OBJEXT): {$(VPATH)}internal/newobj.h
+pack.$(OBJEXT): {$(VPATH)}internal/rgengc.h
pack.$(OBJEXT): {$(VPATH)}internal/scan_args.h
pack.$(OBJEXT): {$(VPATH)}internal/special_consts.h
pack.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -11300,33 +10921,18 @@ pack.$(OBJEXT): {$(VPATH)}internal/value_type.h
pack.$(OBJEXT): {$(VPATH)}internal/variable.h
pack.$(OBJEXT): {$(VPATH)}internal/warning_push.h
pack.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-pack.$(OBJEXT): {$(VPATH)}method.h
pack.$(OBJEXT): {$(VPATH)}missing.h
-pack.$(OBJEXT): {$(VPATH)}node.h
pack.$(OBJEXT): {$(VPATH)}onigmo.h
pack.$(OBJEXT): {$(VPATH)}oniguruma.h
pack.$(OBJEXT): {$(VPATH)}pack.c
pack.$(OBJEXT): {$(VPATH)}pack.rbinc
-pack.$(OBJEXT): {$(VPATH)}ruby_assert.h
-pack.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-pack.$(OBJEXT): {$(VPATH)}rubyparser.h
pack.$(OBJEXT): {$(VPATH)}shape.h
pack.$(OBJEXT): {$(VPATH)}st.h
pack.$(OBJEXT): {$(VPATH)}subst.h
-pack.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-pack.$(OBJEXT): {$(VPATH)}thread_native.h
pack.$(OBJEXT): {$(VPATH)}util.h
-pack.$(OBJEXT): {$(VPATH)}vm_core.h
-pack.$(OBJEXT): {$(VPATH)}vm_opts.h
-parse.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-parse.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-parse.$(OBJEXT): $(CCAN_DIR)/list/list.h
-parse.$(OBJEXT): $(CCAN_DIR)/str/str.h
parse.$(OBJEXT): $(hdrdir)/ruby.h
parse.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-parse.$(OBJEXT): $(hdrdir)/ruby/version.h
parse.$(OBJEXT): $(top_srcdir)/internal/array.h
-parse.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
parse.$(OBJEXT): $(top_srcdir)/internal/bignum.h
parse.$(OBJEXT): $(top_srcdir)/internal/bits.h
parse.$(OBJEXT): $(top_srcdir)/internal/compile.h
@@ -11343,7 +10949,6 @@ parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h
parse.$(OBJEXT): $(top_srcdir)/internal/parse.h
parse.$(OBJEXT): $(top_srcdir)/internal/rational.h
parse.$(OBJEXT): $(top_srcdir)/internal/re.h
-parse.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
parse.$(OBJEXT): $(top_srcdir)/internal/serial.h
parse.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
parse.$(OBJEXT): $(top_srcdir)/internal/string.h
@@ -11353,7 +10958,6 @@ parse.$(OBJEXT): $(top_srcdir)/internal/variable.h
parse.$(OBJEXT): $(top_srcdir)/internal/vm.h
parse.$(OBJEXT): $(top_srcdir)/internal/warnings.h
parse.$(OBJEXT): {$(VPATH)}assert.h
-parse.$(OBJEXT): {$(VPATH)}atomic.h
parse.$(OBJEXT): {$(VPATH)}backward/2/assume.h
parse.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
parse.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -11410,7 +11014,6 @@ parse.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
parse.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
parse.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
parse.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-parse.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
parse.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
parse.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
parse.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -11479,6 +11082,7 @@ parse.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
parse.$(OBJEXT): {$(VPATH)}internal/intern/error.h
parse.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
parse.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+parse.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
parse.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
parse.$(OBJEXT): {$(VPATH)}internal/intern/io.h
parse.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -11509,6 +11113,7 @@ parse.$(OBJEXT): {$(VPATH)}internal/memory.h
parse.$(OBJEXT): {$(VPATH)}internal/method.h
parse.$(OBJEXT): {$(VPATH)}internal/module.h
parse.$(OBJEXT): {$(VPATH)}internal/newobj.h
+parse.$(OBJEXT): {$(VPATH)}internal/rgengc.h
parse.$(OBJEXT): {$(VPATH)}internal/scan_args.h
parse.$(OBJEXT): {$(VPATH)}internal/special_consts.h
parse.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -11522,7 +11127,6 @@ parse.$(OBJEXT): {$(VPATH)}internal/warning_push.h
parse.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
parse.$(OBJEXT): {$(VPATH)}io.h
parse.$(OBJEXT): {$(VPATH)}lex.c
-parse.$(OBJEXT): {$(VPATH)}method.h
parse.$(OBJEXT): {$(VPATH)}missing.h
parse.$(OBJEXT): {$(VPATH)}node.h
parse.$(OBJEXT): {$(VPATH)}onigmo.h
@@ -11530,1059 +11134,22 @@ parse.$(OBJEXT): {$(VPATH)}oniguruma.h
parse.$(OBJEXT): {$(VPATH)}parse.c
parse.$(OBJEXT): {$(VPATH)}parse.h
parse.$(OBJEXT): {$(VPATH)}parse.y
-parse.$(OBJEXT): {$(VPATH)}parser_node.h
-parse.$(OBJEXT): {$(VPATH)}parser_st.h
parse.$(OBJEXT): {$(VPATH)}probes.dmyh
parse.$(OBJEXT): {$(VPATH)}probes.h
parse.$(OBJEXT): {$(VPATH)}ractor.h
parse.$(OBJEXT): {$(VPATH)}regenc.h
parse.$(OBJEXT): {$(VPATH)}regex.h
parse.$(OBJEXT): {$(VPATH)}ruby_assert.h
-parse.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-parse.$(OBJEXT): {$(VPATH)}rubyparser.h
parse.$(OBJEXT): {$(VPATH)}shape.h
parse.$(OBJEXT): {$(VPATH)}st.h
parse.$(OBJEXT): {$(VPATH)}subst.h
parse.$(OBJEXT): {$(VPATH)}symbol.h
-parse.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-parse.$(OBJEXT): {$(VPATH)}thread_native.h
parse.$(OBJEXT): {$(VPATH)}util.h
-parse.$(OBJEXT): {$(VPATH)}vm_core.h
-parse.$(OBJEXT): {$(VPATH)}vm_opts.h
-parser_st.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-parser_st.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-parser_st.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-parser_st.$(OBJEXT): {$(VPATH)}assert.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-parser_st.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-parser_st.$(OBJEXT): {$(VPATH)}config.h
-parser_st.$(OBJEXT): {$(VPATH)}defines.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/assume.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/cast.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/config.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/dosish.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-parser_st.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-parser_st.$(OBJEXT): {$(VPATH)}missing.h
-parser_st.$(OBJEXT): {$(VPATH)}parser_bits.h
-parser_st.$(OBJEXT): {$(VPATH)}parser_st.c
-parser_st.$(OBJEXT): {$(VPATH)}parser_st.h
-parser_st.$(OBJEXT): {$(VPATH)}parser_value.h
-parser_st.$(OBJEXT): {$(VPATH)}st.c
-prism/api_node.$(OBJEXT): $(hdrdir)/ruby.h
-prism/api_node.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/extension.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/api_node.$(OBJEXT): {$(VPATH)}assert.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-prism/api_node.$(OBJEXT): {$(VPATH)}config.h
-prism/api_node.$(OBJEXT): {$(VPATH)}defines.h
-prism/api_node.$(OBJEXT): {$(VPATH)}encoding.h
-prism/api_node.$(OBJEXT): {$(VPATH)}intern.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/abi.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/assume.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/cast.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/config.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/ctype.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/dosish.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/error.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/eval.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/event.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/gc.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/glob.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/globals.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/iterator.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/memory.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/method.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/module.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/newobj.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/symbol.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/value.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/value_type.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/variable.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-prism/api_node.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-prism/api_node.$(OBJEXT): {$(VPATH)}missing.h
-prism/api_node.$(OBJEXT): {$(VPATH)}onigmo.h
-prism/api_node.$(OBJEXT): {$(VPATH)}oniguruma.h
-prism/api_node.$(OBJEXT): {$(VPATH)}prism/api_node.c
-prism/api_node.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/api_node.$(OBJEXT): {$(VPATH)}prism/version.h
-prism/api_node.$(OBJEXT): {$(VPATH)}st.h
-prism/api_node.$(OBJEXT): {$(VPATH)}subst.h
-prism/api_pack.$(OBJEXT): $(hdrdir)/ruby.h
-prism/api_pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/api_pack.c
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/extension.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}assert.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}config.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}defines.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}encoding.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}intern.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/abi.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/assume.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/cast.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/config.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/ctype.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/dosish.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/error.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/eval.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/event.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/gc.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/glob.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/globals.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/iterator.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/memory.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/method.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/module.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/newobj.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/symbol.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/value.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/value_type.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/variable.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}missing.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}onigmo.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}oniguruma.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}prism/version.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}st.h
-prism/api_pack.$(OBJEXT): {$(VPATH)}subst.h
-prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/diagnostic.c
-prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/diagnostic.$(OBJEXT): {$(VPATH)}config.h
-prism/diagnostic.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/encoding.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/encoding.$(OBJEXT): $(top_srcdir)/prism/encoding.c
-prism/encoding.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/encoding.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/encoding.$(OBJEXT): {$(VPATH)}config.h
-prism/extension.$(OBJEXT): $(hdrdir)/ruby.h
-prism/extension.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/extension.c
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/extension.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/extension.$(OBJEXT): {$(VPATH)}assert.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-prism/extension.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-prism/extension.$(OBJEXT): {$(VPATH)}config.h
-prism/extension.$(OBJEXT): {$(VPATH)}defines.h
-prism/extension.$(OBJEXT): {$(VPATH)}encoding.h
-prism/extension.$(OBJEXT): {$(VPATH)}intern.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/abi.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/assume.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/cast.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/config.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/ctype.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/dosish.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/error.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/eval.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/event.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/gc.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/glob.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/globals.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/iterator.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/memory.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/method.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/module.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/newobj.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/symbol.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/value.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/value_type.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/variable.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-prism/extension.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-prism/extension.$(OBJEXT): {$(VPATH)}missing.h
-prism/extension.$(OBJEXT): {$(VPATH)}onigmo.h
-prism/extension.$(OBJEXT): {$(VPATH)}oniguruma.h
-prism/extension.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/extension.$(OBJEXT): {$(VPATH)}prism/version.h
-prism/extension.$(OBJEXT): {$(VPATH)}st.h
-prism/extension.$(OBJEXT): {$(VPATH)}subst.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/node.$(OBJEXT): {$(VPATH)}config.h
-prism/node.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/node.$(OBJEXT): {$(VPATH)}prism/node.c
-prism/options.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/options.$(OBJEXT): $(top_srcdir)/prism/options.c
-prism/options.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/options.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/pack.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/pack.$(OBJEXT): $(top_srcdir)/prism/pack.c
-prism/pack.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/pack.$(OBJEXT): {$(VPATH)}config.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/prettyprint.$(OBJEXT): {$(VPATH)}config.h
-prism/prettyprint.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/prettyprint.$(OBJEXT): {$(VPATH)}prism/prettyprint.c
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/prism.c
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/prism.$(OBJEXT): $(top_srcdir)/prism/version.h
-prism/prism.$(OBJEXT): {$(VPATH)}config.h
-prism/prism.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/prism.$(OBJEXT): {$(VPATH)}prism/version.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/regexp.c
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/regexp.$(OBJEXT): {$(VPATH)}config.h
-prism/regexp.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/serialize.$(OBJEXT): {$(VPATH)}config.h
-prism/serialize.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/serialize.$(OBJEXT): {$(VPATH)}prism/serialize.c
-prism/serialize.$(OBJEXT): {$(VPATH)}prism/version.h
-prism/token_type.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/token_type.$(OBJEXT): {$(VPATH)}config.h
-prism/token_type.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/token_type.$(OBJEXT): {$(VPATH)}prism/token_type.c
-prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.c
-prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism/util/pm_buffer.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.c
-prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/util/pm_char.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_constant_pool.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_constant_pool.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.c
-prism/util/pm_constant_pool.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/util/pm_constant_pool.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_list.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.c
-prism/util/pm_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/util/pm_list.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.c
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/util/pm_memchr.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_memchr.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism/util/pm_newline_list.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_newline_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.c
-prism/util/pm_newline_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/util/pm_newline_list.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_state_stack.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_state_stack.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.c
-prism/util/pm_state_stack.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/util/pm_state_stack.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_string.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_string.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.c
-prism/util/pm_string.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/util/pm_string.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_string_list.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_string_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/util/pm_string_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.c
-prism/util/pm_string_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism/util/pm_string_list.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_strncasecmp.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_strncasecmp.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.c
-prism/util/pm_strncasecmp.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.c
-prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism/util/pm_strpbrk.$(OBJEXT): {$(VPATH)}config.h
-prism/util/pm_strpbrk.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism_init.$(OBJEXT): $(hdrdir)/ruby.h
-prism_init.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/defines.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/extension.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/node.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/options.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/pack.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/parser.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/prism.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-prism_init.$(OBJEXT): $(top_srcdir)/prism_init.c
-prism_init.$(OBJEXT): {$(VPATH)}assert.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-prism_init.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-prism_init.$(OBJEXT): {$(VPATH)}config.h
-prism_init.$(OBJEXT): {$(VPATH)}defines.h
-prism_init.$(OBJEXT): {$(VPATH)}encoding.h
-prism_init.$(OBJEXT): {$(VPATH)}intern.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/abi.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/assume.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/cast.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/config.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/ctype.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/dosish.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/error.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/eval.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/event.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/gc.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/glob.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/globals.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/iterator.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/memory.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/method.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/module.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/newobj.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/symbol.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/value.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/value_type.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/variable.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-prism_init.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-prism_init.$(OBJEXT): {$(VPATH)}missing.h
-prism_init.$(OBJEXT): {$(VPATH)}onigmo.h
-prism_init.$(OBJEXT): {$(VPATH)}oniguruma.h
-prism_init.$(OBJEXT): {$(VPATH)}prism/ast.h
-prism_init.$(OBJEXT): {$(VPATH)}prism/version.h
-prism_init.$(OBJEXT): {$(VPATH)}prism_init.c
-prism_init.$(OBJEXT): {$(VPATH)}st.h
-prism_init.$(OBJEXT): {$(VPATH)}subst.h
proc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
proc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
proc.$(OBJEXT): $(CCAN_DIR)/list/list.h
proc.$(OBJEXT): $(CCAN_DIR)/str/str.h
proc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-proc.$(OBJEXT): $(hdrdir)/ruby/version.h
proc.$(OBJEXT): $(top_srcdir)/internal/array.h
proc.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
proc.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -12590,6 +11157,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
proc.$(OBJEXT): $(top_srcdir)/internal/error.h
proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
+proc.$(OBJEXT): $(top_srcdir)/internal/hash.h
proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
proc.$(OBJEXT): $(top_srcdir)/internal/object.h
proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -12600,27 +11168,6 @@ proc.$(OBJEXT): $(top_srcdir)/internal/symbol.h
proc.$(OBJEXT): $(top_srcdir)/internal/variable.h
proc.$(OBJEXT): $(top_srcdir)/internal/vm.h
proc.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-proc.$(OBJEXT): $(top_srcdir)/prism/defines.h
-proc.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-proc.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-proc.$(OBJEXT): $(top_srcdir)/prism/node.h
-proc.$(OBJEXT): $(top_srcdir)/prism/options.h
-proc.$(OBJEXT): $(top_srcdir)/prism/pack.h
-proc.$(OBJEXT): $(top_srcdir)/prism/parser.h
-proc.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-proc.$(OBJEXT): $(top_srcdir)/prism/prism.h
-proc.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
proc.$(OBJEXT): {$(VPATH)}assert.h
proc.$(OBJEXT): {$(VPATH)}atomic.h
proc.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -12634,10 +11181,10 @@ proc.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
proc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
proc.$(OBJEXT): {$(VPATH)}config.h
proc.$(OBJEXT): {$(VPATH)}constant.h
-proc.$(OBJEXT): {$(VPATH)}debug_counter.h
proc.$(OBJEXT): {$(VPATH)}defines.h
proc.$(OBJEXT): {$(VPATH)}encoding.h
proc.$(OBJEXT): {$(VPATH)}eval_intern.h
+proc.$(OBJEXT): {$(VPATH)}gc.h
proc.$(OBJEXT): {$(VPATH)}id.h
proc.$(OBJEXT): {$(VPATH)}id_table.h
proc.$(OBJEXT): {$(VPATH)}intern.h
@@ -12680,7 +11227,6 @@ proc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
proc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
proc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
proc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-proc.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
proc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
proc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
proc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -12749,6 +11295,7 @@ proc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
proc.$(OBJEXT): {$(VPATH)}internal/intern/error.h
proc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
proc.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+proc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
proc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
proc.$(OBJEXT): {$(VPATH)}internal/intern/io.h
proc.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -12779,6 +11326,7 @@ proc.$(OBJEXT): {$(VPATH)}internal/memory.h
proc.$(OBJEXT): {$(VPATH)}internal/method.h
proc.$(OBJEXT): {$(VPATH)}internal/module.h
proc.$(OBJEXT): {$(VPATH)}internal/newobj.h
+proc.$(OBJEXT): {$(VPATH)}internal/rgengc.h
proc.$(OBJEXT): {$(VPATH)}internal/scan_args.h
proc.$(OBJEXT): {$(VPATH)}internal/special_consts.h
proc.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -12796,22 +11344,16 @@ proc.$(OBJEXT): {$(VPATH)}missing.h
proc.$(OBJEXT): {$(VPATH)}node.h
proc.$(OBJEXT): {$(VPATH)}onigmo.h
proc.$(OBJEXT): {$(VPATH)}oniguruma.h
-proc.$(OBJEXT): {$(VPATH)}prism/ast.h
-proc.$(OBJEXT): {$(VPATH)}prism/version.h
-proc.$(OBJEXT): {$(VPATH)}prism_compile.h
proc.$(OBJEXT): {$(VPATH)}proc.c
proc.$(OBJEXT): {$(VPATH)}ruby_assert.h
proc.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-proc.$(OBJEXT): {$(VPATH)}rubyparser.h
proc.$(OBJEXT): {$(VPATH)}shape.h
proc.$(OBJEXT): {$(VPATH)}st.h
proc.$(OBJEXT): {$(VPATH)}subst.h
proc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
proc.$(OBJEXT): {$(VPATH)}thread_native.h
proc.$(OBJEXT): {$(VPATH)}vm_core.h
-proc.$(OBJEXT): {$(VPATH)}vm_debug.h
proc.$(OBJEXT): {$(VPATH)}vm_opts.h
-proc.$(OBJEXT): {$(VPATH)}vm_sync.h
proc.$(OBJEXT): {$(VPATH)}yjit.h
process.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
process.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
@@ -12819,7 +11361,6 @@ process.$(OBJEXT): $(CCAN_DIR)/list/list.h
process.$(OBJEXT): $(CCAN_DIR)/str/str.h
process.$(OBJEXT): $(hdrdir)/ruby.h
process.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-process.$(OBJEXT): $(hdrdir)/ruby/version.h
process.$(OBJEXT): $(top_srcdir)/internal/array.h
process.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
process.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -12833,7 +11374,6 @@ process.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
process.$(OBJEXT): $(top_srcdir)/internal/gc.h
process.$(OBJEXT): $(top_srcdir)/internal/hash.h
process.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-process.$(OBJEXT): $(top_srcdir)/internal/io.h
process.$(OBJEXT): $(top_srcdir)/internal/numeric.h
process.$(OBJEXT): $(top_srcdir)/internal/object.h
process.$(OBJEXT): $(top_srcdir)/internal/process.h
@@ -12906,7 +11446,6 @@ process.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
process.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
process.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
process.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-process.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
process.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
process.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
process.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -12975,6 +11514,7 @@ process.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
process.$(OBJEXT): {$(VPATH)}internal/intern/error.h
process.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
process.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+process.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
process.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
process.$(OBJEXT): {$(VPATH)}internal/intern/io.h
process.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -13005,6 +11545,7 @@ process.$(OBJEXT): {$(VPATH)}internal/memory.h
process.$(OBJEXT): {$(VPATH)}internal/method.h
process.$(OBJEXT): {$(VPATH)}internal/module.h
process.$(OBJEXT): {$(VPATH)}internal/newobj.h
+process.$(OBJEXT): {$(VPATH)}internal/rgengc.h
process.$(OBJEXT): {$(VPATH)}internal/scan_args.h
process.$(OBJEXT): {$(VPATH)}internal/special_consts.h
process.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -13019,15 +11560,14 @@ process.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
process.$(OBJEXT): {$(VPATH)}io.h
process.$(OBJEXT): {$(VPATH)}method.h
process.$(OBJEXT): {$(VPATH)}missing.h
+process.$(OBJEXT): {$(VPATH)}mjit.h
process.$(OBJEXT): {$(VPATH)}node.h
process.$(OBJEXT): {$(VPATH)}onigmo.h
process.$(OBJEXT): {$(VPATH)}oniguruma.h
process.$(OBJEXT): {$(VPATH)}process.c
process.$(OBJEXT): {$(VPATH)}ractor.h
-process.$(OBJEXT): {$(VPATH)}rjit.h
process.$(OBJEXT): {$(VPATH)}ruby_assert.h
process.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-process.$(OBJEXT): {$(VPATH)}rubyparser.h
process.$(OBJEXT): {$(VPATH)}shape.h
process.$(OBJEXT): {$(VPATH)}st.h
process.$(OBJEXT): {$(VPATH)}subst.h
@@ -13036,16 +11576,13 @@ process.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
process.$(OBJEXT): {$(VPATH)}thread_native.h
process.$(OBJEXT): {$(VPATH)}util.h
process.$(OBJEXT): {$(VPATH)}vm_core.h
-process.$(OBJEXT): {$(VPATH)}vm_debug.h
process.$(OBJEXT): {$(VPATH)}vm_opts.h
-process.$(OBJEXT): {$(VPATH)}vm_sync.h
ractor.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
ractor.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
ractor.$(OBJEXT): $(CCAN_DIR)/list/list.h
ractor.$(OBJEXT): $(CCAN_DIR)/str/str.h
ractor.$(OBJEXT): $(hdrdir)/ruby.h
ractor.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-ractor.$(OBJEXT): $(hdrdir)/ruby/version.h
ractor.$(OBJEXT): $(top_srcdir)/internal/array.h
ractor.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
ractor.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -13084,7 +11621,7 @@ ractor.$(OBJEXT): {$(VPATH)}constant.h
ractor.$(OBJEXT): {$(VPATH)}debug_counter.h
ractor.$(OBJEXT): {$(VPATH)}defines.h
ractor.$(OBJEXT): {$(VPATH)}encoding.h
-ractor.$(OBJEXT): {$(VPATH)}eval_intern.h
+ractor.$(OBJEXT): {$(VPATH)}gc.h
ractor.$(OBJEXT): {$(VPATH)}id.h
ractor.$(OBJEXT): {$(VPATH)}id_table.h
ractor.$(OBJEXT): {$(VPATH)}intern.h
@@ -13127,7 +11664,6 @@ ractor.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
ractor.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
ractor.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
ractor.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-ractor.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
ractor.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
ractor.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
ractor.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -13196,6 +11732,7 @@ ractor.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
ractor.$(OBJEXT): {$(VPATH)}internal/intern/error.h
ractor.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
ractor.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+ractor.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
ractor.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
ractor.$(OBJEXT): {$(VPATH)}internal/intern/io.h
ractor.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -13226,6 +11763,7 @@ ractor.$(OBJEXT): {$(VPATH)}internal/memory.h
ractor.$(OBJEXT): {$(VPATH)}internal/method.h
ractor.$(OBJEXT): {$(VPATH)}internal/module.h
ractor.$(OBJEXT): {$(VPATH)}internal/newobj.h
+ractor.$(OBJEXT): {$(VPATH)}internal/rgengc.h
ractor.$(OBJEXT): {$(VPATH)}internal/scan_args.h
ractor.$(OBJEXT): {$(VPATH)}internal/special_consts.h
ractor.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -13239,6 +11777,7 @@ ractor.$(OBJEXT): {$(VPATH)}internal/warning_push.h
ractor.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
ractor.$(OBJEXT): {$(VPATH)}method.h
ractor.$(OBJEXT): {$(VPATH)}missing.h
+ractor.$(OBJEXT): {$(VPATH)}mjit.h
ractor.$(OBJEXT): {$(VPATH)}node.h
ractor.$(OBJEXT): {$(VPATH)}onigmo.h
ractor.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -13246,35 +11785,28 @@ ractor.$(OBJEXT): {$(VPATH)}ractor.c
ractor.$(OBJEXT): {$(VPATH)}ractor.h
ractor.$(OBJEXT): {$(VPATH)}ractor.rbinc
ractor.$(OBJEXT): {$(VPATH)}ractor_core.h
-ractor.$(OBJEXT): {$(VPATH)}rjit.h
ractor.$(OBJEXT): {$(VPATH)}ruby_assert.h
ractor.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-ractor.$(OBJEXT): {$(VPATH)}rubyparser.h
ractor.$(OBJEXT): {$(VPATH)}shape.h
ractor.$(OBJEXT): {$(VPATH)}st.h
ractor.$(OBJEXT): {$(VPATH)}subst.h
ractor.$(OBJEXT): {$(VPATH)}thread.h
ractor.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
ractor.$(OBJEXT): {$(VPATH)}thread_native.h
+ractor.$(OBJEXT): {$(VPATH)}transient_heap.h
ractor.$(OBJEXT): {$(VPATH)}variable.h
ractor.$(OBJEXT): {$(VPATH)}vm_core.h
ractor.$(OBJEXT): {$(VPATH)}vm_debug.h
ractor.$(OBJEXT): {$(VPATH)}vm_opts.h
ractor.$(OBJEXT): {$(VPATH)}vm_sync.h
ractor.$(OBJEXT): {$(VPATH)}yjit.h
-random.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-random.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-random.$(OBJEXT): $(CCAN_DIR)/list/list.h
-random.$(OBJEXT): $(CCAN_DIR)/str/str.h
random.$(OBJEXT): $(hdrdir)/ruby/ruby.h
random.$(OBJEXT): $(top_srcdir)/internal/array.h
-random.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
random.$(OBJEXT): $(top_srcdir)/internal/bignum.h
random.$(OBJEXT): $(top_srcdir)/internal/bits.h
random.$(OBJEXT): $(top_srcdir)/internal/compilers.h
random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
random.$(OBJEXT): $(top_srcdir)/internal/gc.h
-random.$(OBJEXT): $(top_srcdir)/internal/imemo.h
random.$(OBJEXT): $(top_srcdir)/internal/numeric.h
random.$(OBJEXT): $(top_srcdir)/internal/random.h
random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -13297,8 +11829,6 @@ random.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
random.$(OBJEXT): {$(VPATH)}config.h
random.$(OBJEXT): {$(VPATH)}constant.h
random.$(OBJEXT): {$(VPATH)}defines.h
-random.$(OBJEXT): {$(VPATH)}encoding.h
-random.$(OBJEXT): {$(VPATH)}id.h
random.$(OBJEXT): {$(VPATH)}id_table.h
random.$(OBJEXT): {$(VPATH)}intern.h
random.$(OBJEXT): {$(VPATH)}internal.h
@@ -13340,7 +11870,6 @@ random.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
random.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
random.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
random.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-random.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
random.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
random.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
random.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -13373,15 +11902,6 @@ random.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
random.$(OBJEXT): {$(VPATH)}internal/ctype.h
random.$(OBJEXT): {$(VPATH)}internal/dllexport.h
random.$(OBJEXT): {$(VPATH)}internal/dosish.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-random.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
random.$(OBJEXT): {$(VPATH)}internal/error.h
random.$(OBJEXT): {$(VPATH)}internal/eval.h
random.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -13409,6 +11929,7 @@ random.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
random.$(OBJEXT): {$(VPATH)}internal/intern/error.h
random.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
random.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+random.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
random.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
random.$(OBJEXT): {$(VPATH)}internal/intern/io.h
random.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -13439,6 +11960,7 @@ random.$(OBJEXT): {$(VPATH)}internal/memory.h
random.$(OBJEXT): {$(VPATH)}internal/method.h
random.$(OBJEXT): {$(VPATH)}internal/module.h
random.$(OBJEXT): {$(VPATH)}internal/newobj.h
+random.$(OBJEXT): {$(VPATH)}internal/rgengc.h
random.$(OBJEXT): {$(VPATH)}internal/scan_args.h
random.$(OBJEXT): {$(VPATH)}internal/special_consts.h
random.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -13450,29 +11972,18 @@ random.$(OBJEXT): {$(VPATH)}internal/value_type.h
random.$(OBJEXT): {$(VPATH)}internal/variable.h
random.$(OBJEXT): {$(VPATH)}internal/warning_push.h
random.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-random.$(OBJEXT): {$(VPATH)}method.h
random.$(OBJEXT): {$(VPATH)}missing.h
random.$(OBJEXT): {$(VPATH)}mt19937.c
-random.$(OBJEXT): {$(VPATH)}node.h
-random.$(OBJEXT): {$(VPATH)}onigmo.h
-random.$(OBJEXT): {$(VPATH)}oniguruma.h
random.$(OBJEXT): {$(VPATH)}ractor.h
random.$(OBJEXT): {$(VPATH)}random.c
random.$(OBJEXT): {$(VPATH)}random.h
-random.$(OBJEXT): {$(VPATH)}ruby_assert.h
random.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-random.$(OBJEXT): {$(VPATH)}rubyparser.h
random.$(OBJEXT): {$(VPATH)}shape.h
random.$(OBJEXT): {$(VPATH)}siphash.c
random.$(OBJEXT): {$(VPATH)}siphash.h
random.$(OBJEXT): {$(VPATH)}st.h
random.$(OBJEXT): {$(VPATH)}subst.h
-random.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-random.$(OBJEXT): {$(VPATH)}thread_native.h
-random.$(OBJEXT): {$(VPATH)}vm_core.h
-random.$(OBJEXT): {$(VPATH)}vm_opts.h
range.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-range.$(OBJEXT): $(hdrdir)/ruby/version.h
range.$(OBJEXT): $(top_srcdir)/internal/array.h
range.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
range.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -13546,7 +12057,6 @@ range.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
range.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
range.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
range.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-range.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
range.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
range.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
range.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -13615,6 +12125,7 @@ range.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
range.$(OBJEXT): {$(VPATH)}internal/intern/error.h
range.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
range.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+range.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
range.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
range.$(OBJEXT): {$(VPATH)}internal/intern/io.h
range.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -13645,6 +12156,7 @@ range.$(OBJEXT): {$(VPATH)}internal/memory.h
range.$(OBJEXT): {$(VPATH)}internal/method.h
range.$(OBJEXT): {$(VPATH)}internal/module.h
range.$(OBJEXT): {$(VPATH)}internal/newobj.h
+range.$(OBJEXT): {$(VPATH)}internal/rgengc.h
range.$(OBJEXT): {$(VPATH)}internal/scan_args.h
range.$(OBJEXT): {$(VPATH)}internal/special_consts.h
range.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -13663,13 +12175,8 @@ range.$(OBJEXT): {$(VPATH)}range.c
range.$(OBJEXT): {$(VPATH)}shape.h
range.$(OBJEXT): {$(VPATH)}st.h
range.$(OBJEXT): {$(VPATH)}subst.h
-rational.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-rational.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-rational.$(OBJEXT): $(CCAN_DIR)/list/list.h
-rational.$(OBJEXT): $(CCAN_DIR)/str/str.h
rational.$(OBJEXT): $(hdrdir)/ruby/ruby.h
rational.$(OBJEXT): $(top_srcdir)/internal/array.h
-rational.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
rational.$(OBJEXT): $(top_srcdir)/internal/bignum.h
rational.$(OBJEXT): $(top_srcdir)/internal/bits.h
rational.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -13677,7 +12184,6 @@ rational.$(OBJEXT): $(top_srcdir)/internal/compilers.h
rational.$(OBJEXT): $(top_srcdir)/internal/complex.h
rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
rational.$(OBJEXT): $(top_srcdir)/internal/gc.h
-rational.$(OBJEXT): $(top_srcdir)/internal/imemo.h
rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h
rational.$(OBJEXT): $(top_srcdir)/internal/object.h
rational.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -13687,7 +12193,6 @@ rational.$(OBJEXT): $(top_srcdir)/internal/variable.h
rational.$(OBJEXT): $(top_srcdir)/internal/vm.h
rational.$(OBJEXT): $(top_srcdir)/internal/warnings.h
rational.$(OBJEXT): {$(VPATH)}assert.h
-rational.$(OBJEXT): {$(VPATH)}atomic.h
rational.$(OBJEXT): {$(VPATH)}backward/2/assume.h
rational.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
rational.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -13700,7 +12205,6 @@ rational.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
rational.$(OBJEXT): {$(VPATH)}config.h
rational.$(OBJEXT): {$(VPATH)}constant.h
rational.$(OBJEXT): {$(VPATH)}defines.h
-rational.$(OBJEXT): {$(VPATH)}encoding.h
rational.$(OBJEXT): {$(VPATH)}id.h
rational.$(OBJEXT): {$(VPATH)}id_table.h
rational.$(OBJEXT): {$(VPATH)}intern.h
@@ -13743,7 +12247,6 @@ rational.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
rational.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
rational.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
rational.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-rational.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
rational.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
rational.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
rational.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -13776,15 +12279,6 @@ rational.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
rational.$(OBJEXT): {$(VPATH)}internal/ctype.h
rational.$(OBJEXT): {$(VPATH)}internal/dllexport.h
rational.$(OBJEXT): {$(VPATH)}internal/dosish.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-rational.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
rational.$(OBJEXT): {$(VPATH)}internal/error.h
rational.$(OBJEXT): {$(VPATH)}internal/eval.h
rational.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -13812,6 +12306,7 @@ rational.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
rational.$(OBJEXT): {$(VPATH)}internal/intern/error.h
rational.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
rational.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+rational.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
rational.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
rational.$(OBJEXT): {$(VPATH)}internal/intern/io.h
rational.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -13842,6 +12337,7 @@ rational.$(OBJEXT): {$(VPATH)}internal/memory.h
rational.$(OBJEXT): {$(VPATH)}internal/method.h
rational.$(OBJEXT): {$(VPATH)}internal/module.h
rational.$(OBJEXT): {$(VPATH)}internal/newobj.h
+rational.$(OBJEXT): {$(VPATH)}internal/rgengc.h
rational.$(OBJEXT): {$(VPATH)}internal/scan_args.h
rational.$(OBJEXT): {$(VPATH)}internal/special_consts.h
rational.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -13853,30 +12349,15 @@ rational.$(OBJEXT): {$(VPATH)}internal/value_type.h
rational.$(OBJEXT): {$(VPATH)}internal/variable.h
rational.$(OBJEXT): {$(VPATH)}internal/warning_push.h
rational.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-rational.$(OBJEXT): {$(VPATH)}method.h
rational.$(OBJEXT): {$(VPATH)}missing.h
-rational.$(OBJEXT): {$(VPATH)}node.h
-rational.$(OBJEXT): {$(VPATH)}onigmo.h
-rational.$(OBJEXT): {$(VPATH)}oniguruma.h
rational.$(OBJEXT): {$(VPATH)}rational.c
rational.$(OBJEXT): {$(VPATH)}ruby_assert.h
-rational.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-rational.$(OBJEXT): {$(VPATH)}rubyparser.h
rational.$(OBJEXT): {$(VPATH)}shape.h
rational.$(OBJEXT): {$(VPATH)}st.h
rational.$(OBJEXT): {$(VPATH)}subst.h
-rational.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-rational.$(OBJEXT): {$(VPATH)}thread_native.h
-rational.$(OBJEXT): {$(VPATH)}vm_core.h
-rational.$(OBJEXT): {$(VPATH)}vm_opts.h
-re.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-re.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-re.$(OBJEXT): $(CCAN_DIR)/list/list.h
-re.$(OBJEXT): $(CCAN_DIR)/str/str.h
re.$(OBJEXT): $(hdrdir)/ruby.h
re.$(OBJEXT): $(hdrdir)/ruby/ruby.h
re.$(OBJEXT): $(top_srcdir)/internal/array.h
-re.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
re.$(OBJEXT): $(top_srcdir)/internal/bits.h
re.$(OBJEXT): $(top_srcdir)/internal/class.h
re.$(OBJEXT): $(top_srcdir)/internal/compilers.h
@@ -13892,10 +12373,8 @@ re.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
re.$(OBJEXT): $(top_srcdir)/internal/string.h
re.$(OBJEXT): $(top_srcdir)/internal/time.h
re.$(OBJEXT): $(top_srcdir)/internal/variable.h
-re.$(OBJEXT): $(top_srcdir)/internal/vm.h
re.$(OBJEXT): $(top_srcdir)/internal/warnings.h
re.$(OBJEXT): {$(VPATH)}assert.h
-re.$(OBJEXT): {$(VPATH)}atomic.h
re.$(OBJEXT): {$(VPATH)}backward/2/assume.h
re.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
re.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -13911,7 +12390,6 @@ re.$(OBJEXT): {$(VPATH)}defines.h
re.$(OBJEXT): {$(VPATH)}encindex.h
re.$(OBJEXT): {$(VPATH)}encoding.h
re.$(OBJEXT): {$(VPATH)}hrtime.h
-re.$(OBJEXT): {$(VPATH)}id.h
re.$(OBJEXT): {$(VPATH)}id_table.h
re.$(OBJEXT): {$(VPATH)}intern.h
re.$(OBJEXT): {$(VPATH)}internal.h
@@ -13953,7 +12431,6 @@ re.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
re.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
re.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
re.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-re.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
re.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
re.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
re.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -14023,6 +12500,7 @@ re.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
re.$(OBJEXT): {$(VPATH)}internal/intern/error.h
re.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
re.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+re.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
re.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
re.$(OBJEXT): {$(VPATH)}internal/intern/io.h
re.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -14053,6 +12531,7 @@ re.$(OBJEXT): {$(VPATH)}internal/memory.h
re.$(OBJEXT): {$(VPATH)}internal/method.h
re.$(OBJEXT): {$(VPATH)}internal/module.h
re.$(OBJEXT): {$(VPATH)}internal/newobj.h
+re.$(OBJEXT): {$(VPATH)}internal/rgengc.h
re.$(OBJEXT): {$(VPATH)}internal/scan_args.h
re.$(OBJEXT): {$(VPATH)}internal/special_consts.h
re.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -14064,9 +12543,7 @@ re.$(OBJEXT): {$(VPATH)}internal/value_type.h
re.$(OBJEXT): {$(VPATH)}internal/variable.h
re.$(OBJEXT): {$(VPATH)}internal/warning_push.h
re.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-re.$(OBJEXT): {$(VPATH)}method.h
re.$(OBJEXT): {$(VPATH)}missing.h
-re.$(OBJEXT): {$(VPATH)}node.h
re.$(OBJEXT): {$(VPATH)}onigmo.h
re.$(OBJEXT): {$(VPATH)}oniguruma.h
re.$(OBJEXT): {$(VPATH)}re.c
@@ -14074,17 +12551,10 @@ re.$(OBJEXT): {$(VPATH)}re.h
re.$(OBJEXT): {$(VPATH)}regenc.h
re.$(OBJEXT): {$(VPATH)}regex.h
re.$(OBJEXT): {$(VPATH)}regint.h
-re.$(OBJEXT): {$(VPATH)}ruby_assert.h
-re.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-re.$(OBJEXT): {$(VPATH)}rubyparser.h
re.$(OBJEXT): {$(VPATH)}shape.h
re.$(OBJEXT): {$(VPATH)}st.h
re.$(OBJEXT): {$(VPATH)}subst.h
-re.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-re.$(OBJEXT): {$(VPATH)}thread_native.h
re.$(OBJEXT): {$(VPATH)}util.h
-re.$(OBJEXT): {$(VPATH)}vm_core.h
-re.$(OBJEXT): {$(VPATH)}vm_opts.h
regcomp.$(OBJEXT): $(hdrdir)/ruby.h
regcomp.$(OBJEXT): $(hdrdir)/ruby/ruby.h
regcomp.$(OBJEXT): {$(VPATH)}assert.h
@@ -14137,7 +12607,6 @@ regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
regcomp.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-regcomp.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
regcomp.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
regcomp.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
regcomp.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -14197,6 +12666,7 @@ regcomp.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
regcomp.$(OBJEXT): {$(VPATH)}internal/intern/error.h
regcomp.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
regcomp.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
regcomp.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
regcomp.$(OBJEXT): {$(VPATH)}internal/intern/io.h
regcomp.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -14227,6 +12697,7 @@ regcomp.$(OBJEXT): {$(VPATH)}internal/memory.h
regcomp.$(OBJEXT): {$(VPATH)}internal/method.h
regcomp.$(OBJEXT): {$(VPATH)}internal/module.h
regcomp.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regcomp.$(OBJEXT): {$(VPATH)}internal/rgengc.h
regcomp.$(OBJEXT): {$(VPATH)}internal/scan_args.h
regcomp.$(OBJEXT): {$(VPATH)}internal/special_consts.h
regcomp.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -14298,7 +12769,6 @@ regenc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
regenc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
regenc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
regenc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-regenc.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
regenc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
regenc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
regenc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -14358,6 +12828,7 @@ regenc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
regenc.$(OBJEXT): {$(VPATH)}internal/intern/error.h
regenc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
regenc.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regenc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
regenc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
regenc.$(OBJEXT): {$(VPATH)}internal/intern/io.h
regenc.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -14388,6 +12859,7 @@ regenc.$(OBJEXT): {$(VPATH)}internal/memory.h
regenc.$(OBJEXT): {$(VPATH)}internal/method.h
regenc.$(OBJEXT): {$(VPATH)}internal/module.h
regenc.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regenc.$(OBJEXT): {$(VPATH)}internal/rgengc.h
regenc.$(OBJEXT): {$(VPATH)}internal/scan_args.h
regenc.$(OBJEXT): {$(VPATH)}internal/special_consts.h
regenc.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -14458,7 +12930,6 @@ regerror.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
regerror.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
regerror.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
regerror.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-regerror.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
regerror.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
regerror.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
regerror.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -14518,6 +12989,7 @@ regerror.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
regerror.$(OBJEXT): {$(VPATH)}internal/intern/error.h
regerror.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
regerror.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regerror.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
regerror.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
regerror.$(OBJEXT): {$(VPATH)}internal/intern/io.h
regerror.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -14548,6 +13020,7 @@ regerror.$(OBJEXT): {$(VPATH)}internal/memory.h
regerror.$(OBJEXT): {$(VPATH)}internal/method.h
regerror.$(OBJEXT): {$(VPATH)}internal/module.h
regerror.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regerror.$(OBJEXT): {$(VPATH)}internal/rgengc.h
regerror.$(OBJEXT): {$(VPATH)}internal/scan_args.h
regerror.$(OBJEXT): {$(VPATH)}internal/special_consts.h
regerror.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -14618,7 +13091,6 @@ regexec.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
regexec.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
regexec.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
regexec.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-regexec.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
regexec.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
regexec.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
regexec.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -14678,6 +13150,7 @@ regexec.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
regexec.$(OBJEXT): {$(VPATH)}internal/intern/error.h
regexec.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
regexec.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regexec.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
regexec.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
regexec.$(OBJEXT): {$(VPATH)}internal/intern/io.h
regexec.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -14708,6 +13181,7 @@ regexec.$(OBJEXT): {$(VPATH)}internal/memory.h
regexec.$(OBJEXT): {$(VPATH)}internal/method.h
regexec.$(OBJEXT): {$(VPATH)}internal/module.h
regexec.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regexec.$(OBJEXT): {$(VPATH)}internal/rgengc.h
regexec.$(OBJEXT): {$(VPATH)}internal/scan_args.h
regexec.$(OBJEXT): {$(VPATH)}internal/special_consts.h
regexec.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -14782,7 +13256,6 @@ regparse.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
regparse.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
regparse.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
regparse.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-regparse.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
regparse.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
regparse.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
regparse.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -14842,6 +13315,7 @@ regparse.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
regparse.$(OBJEXT): {$(VPATH)}internal/intern/error.h
regparse.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
regparse.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regparse.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
regparse.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
regparse.$(OBJEXT): {$(VPATH)}internal/intern/io.h
regparse.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -14872,6 +13346,7 @@ regparse.$(OBJEXT): {$(VPATH)}internal/memory.h
regparse.$(OBJEXT): {$(VPATH)}internal/method.h
regparse.$(OBJEXT): {$(VPATH)}internal/module.h
regparse.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regparse.$(OBJEXT): {$(VPATH)}internal/rgengc.h
regparse.$(OBJEXT): {$(VPATH)}internal/scan_args.h
regparse.$(OBJEXT): {$(VPATH)}internal/special_consts.h
regparse.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -14943,7 +13418,6 @@ regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -15003,6 +13477,7 @@ regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/error.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/io.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -15033,6 +13508,7 @@ regsyntax.$(OBJEXT): {$(VPATH)}internal/memory.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/method.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/module.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/newobj.h
+regsyntax.$(OBJEXT): {$(VPATH)}internal/rgengc.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/scan_args.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/special_consts.h
regsyntax.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -15051,511 +13527,6 @@ regsyntax.$(OBJEXT): {$(VPATH)}regint.h
regsyntax.$(OBJEXT): {$(VPATH)}regsyntax.c
regsyntax.$(OBJEXT): {$(VPATH)}st.h
regsyntax.$(OBJEXT): {$(VPATH)}subst.h
-rjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-rjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-rjit.$(OBJEXT): $(CCAN_DIR)/list/list.h
-rjit.$(OBJEXT): $(CCAN_DIR)/str/str.h
-rjit.$(OBJEXT): $(hdrdir)/ruby.h
-rjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-rjit.$(OBJEXT): $(hdrdir)/ruby/version.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/array.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/class.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/compile.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/cont.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/file.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/process.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/string.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/struct.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/variable.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/vm.h
-rjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/defines.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/node.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/options.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/pack.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/parser.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/prism.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-rjit.$(OBJEXT): {$(VPATH)}assert.h
-rjit.$(OBJEXT): {$(VPATH)}atomic.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-rjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-rjit.$(OBJEXT): {$(VPATH)}builtin.h
-rjit.$(OBJEXT): {$(VPATH)}config.h
-rjit.$(OBJEXT): {$(VPATH)}constant.h
-rjit.$(OBJEXT): {$(VPATH)}debug.h
-rjit.$(OBJEXT): {$(VPATH)}debug_counter.h
-rjit.$(OBJEXT): {$(VPATH)}defines.h
-rjit.$(OBJEXT): {$(VPATH)}dln.h
-rjit.$(OBJEXT): {$(VPATH)}encoding.h
-rjit.$(OBJEXT): {$(VPATH)}id.h
-rjit.$(OBJEXT): {$(VPATH)}id_table.h
-rjit.$(OBJEXT): {$(VPATH)}insns.def
-rjit.$(OBJEXT): {$(VPATH)}insns.inc
-rjit.$(OBJEXT): {$(VPATH)}insns_info.inc
-rjit.$(OBJEXT): {$(VPATH)}intern.h
-rjit.$(OBJEXT): {$(VPATH)}internal.h
-rjit.$(OBJEXT): {$(VPATH)}internal/abi.h
-rjit.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-rjit.$(OBJEXT): {$(VPATH)}internal/assume.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-rjit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-rjit.$(OBJEXT): {$(VPATH)}internal/cast.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-rjit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-rjit.$(OBJEXT): {$(VPATH)}internal/config.h
-rjit.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-rjit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-rjit.$(OBJEXT): {$(VPATH)}internal/ctype.h
-rjit.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-rjit.$(OBJEXT): {$(VPATH)}internal/dosish.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-rjit.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-rjit.$(OBJEXT): {$(VPATH)}internal/error.h
-rjit.$(OBJEXT): {$(VPATH)}internal/eval.h
-rjit.$(OBJEXT): {$(VPATH)}internal/event.h
-rjit.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-rjit.$(OBJEXT): {$(VPATH)}internal/gc.h
-rjit.$(OBJEXT): {$(VPATH)}internal/glob.h
-rjit.$(OBJEXT): {$(VPATH)}internal/globals.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-rjit.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-rjit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-rjit.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-rjit.$(OBJEXT): {$(VPATH)}internal/iterator.h
-rjit.$(OBJEXT): {$(VPATH)}internal/memory.h
-rjit.$(OBJEXT): {$(VPATH)}internal/method.h
-rjit.$(OBJEXT): {$(VPATH)}internal/module.h
-rjit.$(OBJEXT): {$(VPATH)}internal/newobj.h
-rjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-rjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-rjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-rjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-rjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-rjit.$(OBJEXT): {$(VPATH)}internal/symbol.h
-rjit.$(OBJEXT): {$(VPATH)}internal/value.h
-rjit.$(OBJEXT): {$(VPATH)}internal/value_type.h
-rjit.$(OBJEXT): {$(VPATH)}internal/variable.h
-rjit.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-rjit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-rjit.$(OBJEXT): {$(VPATH)}iseq.h
-rjit.$(OBJEXT): {$(VPATH)}method.h
-rjit.$(OBJEXT): {$(VPATH)}missing.h
-rjit.$(OBJEXT): {$(VPATH)}node.h
-rjit.$(OBJEXT): {$(VPATH)}onigmo.h
-rjit.$(OBJEXT): {$(VPATH)}oniguruma.h
-rjit.$(OBJEXT): {$(VPATH)}prism/ast.h
-rjit.$(OBJEXT): {$(VPATH)}prism/version.h
-rjit.$(OBJEXT): {$(VPATH)}prism_compile.h
-rjit.$(OBJEXT): {$(VPATH)}ractor.h
-rjit.$(OBJEXT): {$(VPATH)}ractor_core.h
-rjit.$(OBJEXT): {$(VPATH)}rjit.c
-rjit.$(OBJEXT): {$(VPATH)}rjit.h
-rjit.$(OBJEXT): {$(VPATH)}rjit.rbinc
-rjit.$(OBJEXT): {$(VPATH)}rjit_c.h
-rjit.$(OBJEXT): {$(VPATH)}ruby_assert.h
-rjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-rjit.$(OBJEXT): {$(VPATH)}rubyparser.h
-rjit.$(OBJEXT): {$(VPATH)}shape.h
-rjit.$(OBJEXT): {$(VPATH)}st.h
-rjit.$(OBJEXT): {$(VPATH)}subst.h
-rjit.$(OBJEXT): {$(VPATH)}thread.h
-rjit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-rjit.$(OBJEXT): {$(VPATH)}thread_native.h
-rjit.$(OBJEXT): {$(VPATH)}util.h
-rjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h
-rjit.$(OBJEXT): {$(VPATH)}vm_core.h
-rjit.$(OBJEXT): {$(VPATH)}vm_debug.h
-rjit.$(OBJEXT): {$(VPATH)}vm_opts.h
-rjit.$(OBJEXT): {$(VPATH)}vm_sync.h
-rjit.$(OBJEXT): {$(VPATH)}yjit.h
-rjit_c.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-rjit_c.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-rjit_c.$(OBJEXT): $(CCAN_DIR)/list/list.h
-rjit_c.$(OBJEXT): $(CCAN_DIR)/str/str.h
-rjit_c.$(OBJEXT): $(hdrdir)/ruby.h
-rjit_c.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-rjit_c.$(OBJEXT): $(srcdir)/rjit_c.rb
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/array.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/class.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/compile.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/gc.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/hash.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/object.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/proc.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/serial.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/string.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/struct.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/variable.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/vm.h
-rjit_c.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/defines.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/node.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/options.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/pack.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/parser.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/prism.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-rjit_c.$(OBJEXT): {$(VPATH)}assert.h
-rjit_c.$(OBJEXT): {$(VPATH)}atomic.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-rjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-rjit_c.$(OBJEXT): {$(VPATH)}builtin.h
-rjit_c.$(OBJEXT): {$(VPATH)}config.h
-rjit_c.$(OBJEXT): {$(VPATH)}constant.h
-rjit_c.$(OBJEXT): {$(VPATH)}debug.h
-rjit_c.$(OBJEXT): {$(VPATH)}debug_counter.h
-rjit_c.$(OBJEXT): {$(VPATH)}defines.h
-rjit_c.$(OBJEXT): {$(VPATH)}encoding.h
-rjit_c.$(OBJEXT): {$(VPATH)}id.h
-rjit_c.$(OBJEXT): {$(VPATH)}id_table.h
-rjit_c.$(OBJEXT): {$(VPATH)}insns.def
-rjit_c.$(OBJEXT): {$(VPATH)}insns.inc
-rjit_c.$(OBJEXT): {$(VPATH)}insns_info.inc
-rjit_c.$(OBJEXT): {$(VPATH)}intern.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/abi.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/assume.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/cast.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/config.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/ctype.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/dosish.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/error.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/eval.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/event.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/gc.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/glob.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/globals.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/iterator.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/memory.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/method.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/module.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/newobj.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/symbol.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/value.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/value_type.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/variable.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-rjit_c.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-rjit_c.$(OBJEXT): {$(VPATH)}iseq.h
-rjit_c.$(OBJEXT): {$(VPATH)}method.h
-rjit_c.$(OBJEXT): {$(VPATH)}missing.h
-rjit_c.$(OBJEXT): {$(VPATH)}node.h
-rjit_c.$(OBJEXT): {$(VPATH)}onigmo.h
-rjit_c.$(OBJEXT): {$(VPATH)}oniguruma.h
-rjit_c.$(OBJEXT): {$(VPATH)}prism/ast.h
-rjit_c.$(OBJEXT): {$(VPATH)}prism/version.h
-rjit_c.$(OBJEXT): {$(VPATH)}prism_compile.h
-rjit_c.$(OBJEXT): {$(VPATH)}probes.dmyh
-rjit_c.$(OBJEXT): {$(VPATH)}probes.h
-rjit_c.$(OBJEXT): {$(VPATH)}probes_helper.h
-rjit_c.$(OBJEXT): {$(VPATH)}rjit.h
-rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.c
-rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.h
-rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.rb
-rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.rbinc
-rjit_c.$(OBJEXT): {$(VPATH)}ruby_assert.h
-rjit_c.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-rjit_c.$(OBJEXT): {$(VPATH)}rubyparser.h
-rjit_c.$(OBJEXT): {$(VPATH)}shape.h
-rjit_c.$(OBJEXT): {$(VPATH)}st.h
-rjit_c.$(OBJEXT): {$(VPATH)}subst.h
-rjit_c.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-rjit_c.$(OBJEXT): {$(VPATH)}thread_native.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_callinfo.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_core.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_debug.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_exec.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_insnhelper.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_opts.h
-rjit_c.$(OBJEXT): {$(VPATH)}vm_sync.h
-rjit_c.$(OBJEXT): {$(VPATH)}yjit.h
ruby-runner.$(OBJEXT): {$(VPATH)}config.h
ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
@@ -15592,35 +13563,13 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h
ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h
ruby.$(OBJEXT): $(top_srcdir)/internal/object.h
ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
-ruby.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
+ruby.$(OBJEXT): $(top_srcdir)/internal/process.h
ruby.$(OBJEXT): $(top_srcdir)/internal/serial.h
ruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
ruby.$(OBJEXT): $(top_srcdir)/internal/string.h
-ruby.$(OBJEXT): $(top_srcdir)/internal/thread.h
ruby.$(OBJEXT): $(top_srcdir)/internal/variable.h
ruby.$(OBJEXT): $(top_srcdir)/internal/vm.h
ruby.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/defines.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/node.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/options.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/pack.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/parser.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/prism.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
ruby.$(OBJEXT): {$(VPATH)}assert.h
ruby.$(OBJEXT): {$(VPATH)}atomic.h
ruby.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -15681,7 +13630,6 @@ ruby.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
ruby.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
ruby.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
ruby.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-ruby.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
ruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
ruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
ruby.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -15750,6 +13698,7 @@ ruby.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
ruby.$(OBJEXT): {$(VPATH)}internal/intern/error.h
ruby.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
ruby.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+ruby.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
ruby.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
ruby.$(OBJEXT): {$(VPATH)}internal/intern/io.h
ruby.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -15780,6 +13729,7 @@ ruby.$(OBJEXT): {$(VPATH)}internal/memory.h
ruby.$(OBJEXT): {$(VPATH)}internal/method.h
ruby.$(OBJEXT): {$(VPATH)}internal/module.h
ruby.$(OBJEXT): {$(VPATH)}internal/newobj.h
+ruby.$(OBJEXT): {$(VPATH)}internal/rgengc.h
ruby.$(OBJEXT): {$(VPATH)}internal/scan_args.h
ruby.$(OBJEXT): {$(VPATH)}internal/special_consts.h
ruby.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -15795,17 +13745,13 @@ ruby.$(OBJEXT): {$(VPATH)}io.h
ruby.$(OBJEXT): {$(VPATH)}iseq.h
ruby.$(OBJEXT): {$(VPATH)}method.h
ruby.$(OBJEXT): {$(VPATH)}missing.h
+ruby.$(OBJEXT): {$(VPATH)}mjit.h
ruby.$(OBJEXT): {$(VPATH)}node.h
ruby.$(OBJEXT): {$(VPATH)}onigmo.h
ruby.$(OBJEXT): {$(VPATH)}oniguruma.h
-ruby.$(OBJEXT): {$(VPATH)}prism/ast.h
-ruby.$(OBJEXT): {$(VPATH)}prism/version.h
-ruby.$(OBJEXT): {$(VPATH)}prism_compile.h
-ruby.$(OBJEXT): {$(VPATH)}rjit.h
ruby.$(OBJEXT): {$(VPATH)}ruby.c
ruby.$(OBJEXT): {$(VPATH)}ruby_assert.h
ruby.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-ruby.$(OBJEXT): {$(VPATH)}rubyparser.h
ruby.$(OBJEXT): {$(VPATH)}shape.h
ruby.$(OBJEXT): {$(VPATH)}st.h
ruby.$(OBJEXT): {$(VPATH)}subst.h
@@ -15816,7 +13762,6 @@ ruby.$(OBJEXT): {$(VPATH)}util.h
ruby.$(OBJEXT): {$(VPATH)}vm_core.h
ruby.$(OBJEXT): {$(VPATH)}vm_opts.h
ruby.$(OBJEXT): {$(VPATH)}yjit.h
-ruby_parser.$(OBJEXT): {$(VPATH)}ruby_parser.c
scheduler.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
scheduler.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
scheduler.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -15891,7 +13836,6 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
scheduler.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-scheduler.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
scheduler.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
scheduler.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
scheduler.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -15960,6 +13904,7 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
scheduler.$(OBJEXT): {$(VPATH)}internal/intern/error.h
scheduler.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
scheduler.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
scheduler.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
scheduler.$(OBJEXT): {$(VPATH)}internal/intern/io.h
scheduler.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -15990,6 +13935,7 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/memory.h
scheduler.$(OBJEXT): {$(VPATH)}internal/method.h
scheduler.$(OBJEXT): {$(VPATH)}internal/module.h
scheduler.$(OBJEXT): {$(VPATH)}internal/newobj.h
+scheduler.$(OBJEXT): {$(VPATH)}internal/rgengc.h
scheduler.$(OBJEXT): {$(VPATH)}internal/scan_args.h
scheduler.$(OBJEXT): {$(VPATH)}internal/special_consts.h
scheduler.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -16010,7 +13956,6 @@ scheduler.$(OBJEXT): {$(VPATH)}onigmo.h
scheduler.$(OBJEXT): {$(VPATH)}oniguruma.h
scheduler.$(OBJEXT): {$(VPATH)}ruby_assert.h
scheduler.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-scheduler.$(OBJEXT): {$(VPATH)}rubyparser.h
scheduler.$(OBJEXT): {$(VPATH)}scheduler.c
scheduler.$(OBJEXT): {$(VPATH)}shape.h
scheduler.$(OBJEXT): {$(VPATH)}st.h
@@ -16071,7 +14016,6 @@ setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -16131,6 +14075,7 @@ setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/error.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/io.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -16161,6 +14106,7 @@ setproctitle.$(OBJEXT): {$(VPATH)}internal/memory.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/method.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/module.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/newobj.h
+setproctitle.$(OBJEXT): {$(VPATH)}internal/rgengc.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/scan_args.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/special_consts.h
setproctitle.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -16182,18 +14128,14 @@ shape.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
shape.$(OBJEXT): $(CCAN_DIR)/list/list.h
shape.$(OBJEXT): $(CCAN_DIR)/str/str.h
shape.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-shape.$(OBJEXT): $(hdrdir)/ruby/version.h
shape.$(OBJEXT): $(top_srcdir)/internal/array.h
shape.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
shape.$(OBJEXT): $(top_srcdir)/internal/class.h
shape.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-shape.$(OBJEXT): $(top_srcdir)/internal/error.h
shape.$(OBJEXT): $(top_srcdir)/internal/gc.h
shape.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-shape.$(OBJEXT): $(top_srcdir)/internal/object.h
shape.$(OBJEXT): $(top_srcdir)/internal/serial.h
shape.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-shape.$(OBJEXT): $(top_srcdir)/internal/string.h
shape.$(OBJEXT): $(top_srcdir)/internal/symbol.h
shape.$(OBJEXT): $(top_srcdir)/internal/variable.h
shape.$(OBJEXT): $(top_srcdir)/internal/vm.h
@@ -16214,6 +14156,7 @@ shape.$(OBJEXT): {$(VPATH)}constant.h
shape.$(OBJEXT): {$(VPATH)}debug_counter.h
shape.$(OBJEXT): {$(VPATH)}defines.h
shape.$(OBJEXT): {$(VPATH)}encoding.h
+shape.$(OBJEXT): {$(VPATH)}gc.h
shape.$(OBJEXT): {$(VPATH)}id.h
shape.$(OBJEXT): {$(VPATH)}id_table.h
shape.$(OBJEXT): {$(VPATH)}intern.h
@@ -16256,7 +14199,6 @@ shape.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
shape.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
shape.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
shape.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-shape.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
shape.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
shape.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
shape.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -16325,6 +14267,7 @@ shape.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
shape.$(OBJEXT): {$(VPATH)}internal/intern/error.h
shape.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
shape.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+shape.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
shape.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
shape.$(OBJEXT): {$(VPATH)}internal/intern/io.h
shape.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -16355,6 +14298,7 @@ shape.$(OBJEXT): {$(VPATH)}internal/memory.h
shape.$(OBJEXT): {$(VPATH)}internal/method.h
shape.$(OBJEXT): {$(VPATH)}internal/module.h
shape.$(OBJEXT): {$(VPATH)}internal/newobj.h
+shape.$(OBJEXT): {$(VPATH)}internal/rgengc.h
shape.$(OBJEXT): {$(VPATH)}internal/scan_args.h
shape.$(OBJEXT): {$(VPATH)}internal/special_consts.h
shape.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -16373,7 +14317,6 @@ shape.$(OBJEXT): {$(VPATH)}onigmo.h
shape.$(OBJEXT): {$(VPATH)}oniguruma.h
shape.$(OBJEXT): {$(VPATH)}ruby_assert.h
shape.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-shape.$(OBJEXT): {$(VPATH)}rubyparser.h
shape.$(OBJEXT): {$(VPATH)}shape.c
shape.$(OBJEXT): {$(VPATH)}shape.h
shape.$(OBJEXT): {$(VPATH)}st.h
@@ -16391,11 +14334,9 @@ signal.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
signal.$(OBJEXT): $(CCAN_DIR)/list/list.h
signal.$(OBJEXT): $(CCAN_DIR)/str/str.h
signal.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-signal.$(OBJEXT): $(hdrdir)/ruby/version.h
signal.$(OBJEXT): $(top_srcdir)/internal/array.h
signal.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
signal.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-signal.$(OBJEXT): $(top_srcdir)/internal/error.h
signal.$(OBJEXT): $(top_srcdir)/internal/eval.h
signal.$(OBJEXT): $(top_srcdir)/internal/gc.h
signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
@@ -16466,8 +14407,8 @@ signal.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-signal.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -16536,6 +14477,7 @@ signal.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
signal.$(OBJEXT): {$(VPATH)}internal/intern/error.h
signal.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
signal.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+signal.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
signal.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
signal.$(OBJEXT): {$(VPATH)}internal/intern/io.h
signal.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -16566,6 +14508,7 @@ signal.$(OBJEXT): {$(VPATH)}internal/memory.h
signal.$(OBJEXT): {$(VPATH)}internal/method.h
signal.$(OBJEXT): {$(VPATH)}internal/module.h
signal.$(OBJEXT): {$(VPATH)}internal/newobj.h
+signal.$(OBJEXT): {$(VPATH)}internal/rgengc.h
signal.$(OBJEXT): {$(VPATH)}internal/scan_args.h
signal.$(OBJEXT): {$(VPATH)}internal/special_consts.h
signal.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -16586,7 +14529,6 @@ signal.$(OBJEXT): {$(VPATH)}ractor.h
signal.$(OBJEXT): {$(VPATH)}ractor_core.h
signal.$(OBJEXT): {$(VPATH)}ruby_assert.h
signal.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-signal.$(OBJEXT): {$(VPATH)}rubyparser.h
signal.$(OBJEXT): {$(VPATH)}shape.h
signal.$(OBJEXT): {$(VPATH)}signal.c
signal.$(OBJEXT): {$(VPATH)}st.h
@@ -16597,7 +14539,6 @@ signal.$(OBJEXT): {$(VPATH)}vm_core.h
signal.$(OBJEXT): {$(VPATH)}vm_debug.h
signal.$(OBJEXT): {$(VPATH)}vm_opts.h
sprintf.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-sprintf.$(OBJEXT): $(hdrdir)/ruby/version.h
sprintf.$(OBJEXT): $(top_srcdir)/internal/bignum.h
sprintf.$(OBJEXT): $(top_srcdir)/internal/bits.h
sprintf.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -16672,7 +14613,6 @@ sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
sprintf.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-sprintf.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
sprintf.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
sprintf.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
sprintf.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -16742,6 +14682,7 @@ sprintf.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
sprintf.$(OBJEXT): {$(VPATH)}internal/intern/error.h
sprintf.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
sprintf.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
sprintf.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
sprintf.$(OBJEXT): {$(VPATH)}internal/intern/io.h
sprintf.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -16772,6 +14713,7 @@ sprintf.$(OBJEXT): {$(VPATH)}internal/memory.h
sprintf.$(OBJEXT): {$(VPATH)}internal/method.h
sprintf.$(OBJEXT): {$(VPATH)}internal/module.h
sprintf.$(OBJEXT): {$(VPATH)}internal/newobj.h
+sprintf.$(OBJEXT): {$(VPATH)}internal/rgengc.h
sprintf.$(OBJEXT): {$(VPATH)}internal/scan_args.h
sprintf.$(OBJEXT): {$(VPATH)}internal/special_consts.h
sprintf.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -16853,7 +14795,6 @@ st.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
st.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
st.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
st.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-st.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
st.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
st.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
st.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -16913,6 +14854,7 @@ st.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
st.$(OBJEXT): {$(VPATH)}internal/intern/error.h
st.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
st.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+st.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
st.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
st.$(OBJEXT): {$(VPATH)}internal/intern/io.h
st.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -16943,6 +14885,7 @@ st.$(OBJEXT): {$(VPATH)}internal/memory.h
st.$(OBJEXT): {$(VPATH)}internal/method.h
st.$(OBJEXT): {$(VPATH)}internal/module.h
st.$(OBJEXT): {$(VPATH)}internal/newobj.h
+st.$(OBJEXT): {$(VPATH)}internal/rgengc.h
st.$(OBJEXT): {$(VPATH)}internal/scan_args.h
st.$(OBJEXT): {$(VPATH)}internal/special_consts.h
st.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -16955,6 +14898,7 @@ st.$(OBJEXT): {$(VPATH)}internal/variable.h
st.$(OBJEXT): {$(VPATH)}internal/warning_push.h
st.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
st.$(OBJEXT): {$(VPATH)}missing.h
+st.$(OBJEXT): {$(VPATH)}ruby_assert.h
st.$(OBJEXT): {$(VPATH)}st.c
st.$(OBJEXT): {$(VPATH)}st.h
st.$(OBJEXT): {$(VPATH)}subst.h
@@ -17018,7 +14962,6 @@ strftime.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
strftime.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
strftime.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
strftime.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-strftime.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
strftime.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
strftime.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
strftime.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -17087,6 +15030,7 @@ strftime.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
strftime.$(OBJEXT): {$(VPATH)}internal/intern/error.h
strftime.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
strftime.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+strftime.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
strftime.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
strftime.$(OBJEXT): {$(VPATH)}internal/intern/io.h
strftime.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -17117,6 +15061,7 @@ strftime.$(OBJEXT): {$(VPATH)}internal/memory.h
strftime.$(OBJEXT): {$(VPATH)}internal/method.h
strftime.$(OBJEXT): {$(VPATH)}internal/module.h
strftime.$(OBJEXT): {$(VPATH)}internal/newobj.h
+strftime.$(OBJEXT): {$(VPATH)}internal/rgengc.h
strftime.$(OBJEXT): {$(VPATH)}internal/scan_args.h
strftime.$(OBJEXT): {$(VPATH)}internal/special_consts.h
strftime.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -17136,12 +15081,7 @@ strftime.$(OBJEXT): {$(VPATH)}strftime.c
strftime.$(OBJEXT): {$(VPATH)}subst.h
strftime.$(OBJEXT): {$(VPATH)}timev.h
strftime.$(OBJEXT): {$(VPATH)}util.h
-string.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-string.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-string.$(OBJEXT): $(CCAN_DIR)/list/list.h
-string.$(OBJEXT): $(CCAN_DIR)/str/str.h
string.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-string.$(OBJEXT): $(hdrdir)/ruby/version.h
string.$(OBJEXT): $(top_srcdir)/internal/array.h
string.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
string.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -17153,7 +15093,6 @@ string.$(OBJEXT): $(top_srcdir)/internal/encoding.h
string.$(OBJEXT): $(top_srcdir)/internal/error.h
string.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
string.$(OBJEXT): $(top_srcdir)/internal/gc.h
-string.$(OBJEXT): $(top_srcdir)/internal/imemo.h
string.$(OBJEXT): $(top_srcdir)/internal/numeric.h
string.$(OBJEXT): $(top_srcdir)/internal/object.h
string.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -17183,6 +15122,7 @@ string.$(OBJEXT): {$(VPATH)}debug_counter.h
string.$(OBJEXT): {$(VPATH)}defines.h
string.$(OBJEXT): {$(VPATH)}encindex.h
string.$(OBJEXT): {$(VPATH)}encoding.h
+string.$(OBJEXT): {$(VPATH)}gc.h
string.$(OBJEXT): {$(VPATH)}id.h
string.$(OBJEXT): {$(VPATH)}id_table.h
string.$(OBJEXT): {$(VPATH)}intern.h
@@ -17224,8 +15164,8 @@ string.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
string.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
string.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
string.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
string.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-string.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
string.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
string.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
string.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -17295,6 +15235,7 @@ string.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
string.$(OBJEXT): {$(VPATH)}internal/intern/error.h
string.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
string.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+string.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
string.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
string.$(OBJEXT): {$(VPATH)}internal/intern/io.h
string.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -17325,6 +15266,7 @@ string.$(OBJEXT): {$(VPATH)}internal/memory.h
string.$(OBJEXT): {$(VPATH)}internal/method.h
string.$(OBJEXT): {$(VPATH)}internal/module.h
string.$(OBJEXT): {$(VPATH)}internal/newobj.h
+string.$(OBJEXT): {$(VPATH)}internal/rgengc.h
string.$(OBJEXT): {$(VPATH)}internal/scan_args.h
string.$(OBJEXT): {$(VPATH)}internal/special_consts.h
string.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -17336,9 +15278,7 @@ string.$(OBJEXT): {$(VPATH)}internal/value_type.h
string.$(OBJEXT): {$(VPATH)}internal/variable.h
string.$(OBJEXT): {$(VPATH)}internal/warning_push.h
string.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-string.$(OBJEXT): {$(VPATH)}method.h
string.$(OBJEXT): {$(VPATH)}missing.h
-string.$(OBJEXT): {$(VPATH)}node.h
string.$(OBJEXT): {$(VPATH)}onigmo.h
string.$(OBJEXT): {$(VPATH)}oniguruma.h
string.$(OBJEXT): {$(VPATH)}probes.dmyh
@@ -17346,18 +15286,13 @@ string.$(OBJEXT): {$(VPATH)}probes.h
string.$(OBJEXT): {$(VPATH)}re.h
string.$(OBJEXT): {$(VPATH)}regex.h
string.$(OBJEXT): {$(VPATH)}ruby_assert.h
-string.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-string.$(OBJEXT): {$(VPATH)}rubyparser.h
string.$(OBJEXT): {$(VPATH)}shape.h
string.$(OBJEXT): {$(VPATH)}st.h
string.$(OBJEXT): {$(VPATH)}string.c
string.$(OBJEXT): {$(VPATH)}subst.h
-string.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
string.$(OBJEXT): {$(VPATH)}thread_native.h
string.$(OBJEXT): {$(VPATH)}util.h
-string.$(OBJEXT): {$(VPATH)}vm_core.h
string.$(OBJEXT): {$(VPATH)}vm_debug.h
-string.$(OBJEXT): {$(VPATH)}vm_opts.h
string.$(OBJEXT): {$(VPATH)}vm_sync.h
strlcat.$(OBJEXT): {$(VPATH)}config.h
strlcat.$(OBJEXT): {$(VPATH)}internal/attr/format.h
@@ -17394,7 +15329,6 @@ struct.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
struct.$(OBJEXT): $(CCAN_DIR)/list/list.h
struct.$(OBJEXT): $(CCAN_DIR)/str/str.h
struct.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-struct.$(OBJEXT): $(hdrdir)/ruby/version.h
struct.$(OBJEXT): $(top_srcdir)/internal/array.h
struct.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
struct.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -17427,7 +15361,6 @@ struct.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
struct.$(OBJEXT): {$(VPATH)}builtin.h
struct.$(OBJEXT): {$(VPATH)}config.h
struct.$(OBJEXT): {$(VPATH)}constant.h
-struct.$(OBJEXT): {$(VPATH)}debug_counter.h
struct.$(OBJEXT): {$(VPATH)}defines.h
struct.$(OBJEXT): {$(VPATH)}encoding.h
struct.$(OBJEXT): {$(VPATH)}id.h
@@ -17472,7 +15405,6 @@ struct.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
struct.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
struct.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
struct.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-struct.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
struct.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
struct.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
struct.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -17541,6 +15473,7 @@ struct.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
struct.$(OBJEXT): {$(VPATH)}internal/intern/error.h
struct.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
struct.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+struct.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
struct.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
struct.$(OBJEXT): {$(VPATH)}internal/intern/io.h
struct.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -17571,6 +15504,7 @@ struct.$(OBJEXT): {$(VPATH)}internal/memory.h
struct.$(OBJEXT): {$(VPATH)}internal/method.h
struct.$(OBJEXT): {$(VPATH)}internal/module.h
struct.$(OBJEXT): {$(VPATH)}internal/newobj.h
+struct.$(OBJEXT): {$(VPATH)}internal/rgengc.h
struct.$(OBJEXT): {$(VPATH)}internal/scan_args.h
struct.$(OBJEXT): {$(VPATH)}internal/special_consts.h
struct.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -17589,31 +15523,21 @@ struct.$(OBJEXT): {$(VPATH)}onigmo.h
struct.$(OBJEXT): {$(VPATH)}oniguruma.h
struct.$(OBJEXT): {$(VPATH)}ruby_assert.h
struct.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-struct.$(OBJEXT): {$(VPATH)}rubyparser.h
struct.$(OBJEXT): {$(VPATH)}shape.h
struct.$(OBJEXT): {$(VPATH)}st.h
struct.$(OBJEXT): {$(VPATH)}struct.c
struct.$(OBJEXT): {$(VPATH)}subst.h
struct.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
struct.$(OBJEXT): {$(VPATH)}thread_native.h
+struct.$(OBJEXT): {$(VPATH)}transient_heap.h
struct.$(OBJEXT): {$(VPATH)}vm_core.h
-struct.$(OBJEXT): {$(VPATH)}vm_debug.h
struct.$(OBJEXT): {$(VPATH)}vm_opts.h
-struct.$(OBJEXT): {$(VPATH)}vm_sync.h
-symbol.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-symbol.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-symbol.$(OBJEXT): $(CCAN_DIR)/list/list.h
-symbol.$(OBJEXT): $(CCAN_DIR)/str/str.h
symbol.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-symbol.$(OBJEXT): $(hdrdir)/ruby/version.h
-symbol.$(OBJEXT): $(top_srcdir)/internal/array.h
-symbol.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
symbol.$(OBJEXT): $(top_srcdir)/internal/class.h
symbol.$(OBJEXT): $(top_srcdir)/internal/compilers.h
symbol.$(OBJEXT): $(top_srcdir)/internal/error.h
symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h
symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h
-symbol.$(OBJEXT): $(top_srcdir)/internal/imemo.h
symbol.$(OBJEXT): $(top_srcdir)/internal/object.h
symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h
symbol.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@@ -17623,7 +15547,6 @@ symbol.$(OBJEXT): $(top_srcdir)/internal/variable.h
symbol.$(OBJEXT): $(top_srcdir)/internal/vm.h
symbol.$(OBJEXT): $(top_srcdir)/internal/warnings.h
symbol.$(OBJEXT): {$(VPATH)}assert.h
-symbol.$(OBJEXT): {$(VPATH)}atomic.h
symbol.$(OBJEXT): {$(VPATH)}backward/2/assume.h
symbol.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
symbol.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -17639,6 +15562,7 @@ symbol.$(OBJEXT): {$(VPATH)}constant.h
symbol.$(OBJEXT): {$(VPATH)}debug_counter.h
symbol.$(OBJEXT): {$(VPATH)}defines.h
symbol.$(OBJEXT): {$(VPATH)}encoding.h
+symbol.$(OBJEXT): {$(VPATH)}gc.h
symbol.$(OBJEXT): {$(VPATH)}id.c
symbol.$(OBJEXT): {$(VPATH)}id.h
symbol.$(OBJEXT): {$(VPATH)}id_table.c
@@ -17682,8 +15606,8 @@ symbol.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-symbol.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -17752,6 +15676,7 @@ symbol.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
symbol.$(OBJEXT): {$(VPATH)}internal/intern/error.h
symbol.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
symbol.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+symbol.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
symbol.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
symbol.$(OBJEXT): {$(VPATH)}internal/intern/io.h
symbol.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -17782,6 +15707,7 @@ symbol.$(OBJEXT): {$(VPATH)}internal/memory.h
symbol.$(OBJEXT): {$(VPATH)}internal/method.h
symbol.$(OBJEXT): {$(VPATH)}internal/module.h
symbol.$(OBJEXT): {$(VPATH)}internal/newobj.h
+symbol.$(OBJEXT): {$(VPATH)}internal/rgengc.h
symbol.$(OBJEXT): {$(VPATH)}internal/scan_args.h
symbol.$(OBJEXT): {$(VPATH)}internal/special_consts.h
symbol.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -17793,16 +15719,12 @@ symbol.$(OBJEXT): {$(VPATH)}internal/value_type.h
symbol.$(OBJEXT): {$(VPATH)}internal/variable.h
symbol.$(OBJEXT): {$(VPATH)}internal/warning_push.h
symbol.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-symbol.$(OBJEXT): {$(VPATH)}method.h
symbol.$(OBJEXT): {$(VPATH)}missing.h
-symbol.$(OBJEXT): {$(VPATH)}node.h
symbol.$(OBJEXT): {$(VPATH)}onigmo.h
symbol.$(OBJEXT): {$(VPATH)}oniguruma.h
symbol.$(OBJEXT): {$(VPATH)}probes.dmyh
symbol.$(OBJEXT): {$(VPATH)}probes.h
symbol.$(OBJEXT): {$(VPATH)}ruby_assert.h
-symbol.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-symbol.$(OBJEXT): {$(VPATH)}rubyparser.h
symbol.$(OBJEXT): {$(VPATH)}shape.h
symbol.$(OBJEXT): {$(VPATH)}st.h
symbol.$(OBJEXT): {$(VPATH)}subst.h
@@ -17810,11 +15732,7 @@ symbol.$(OBJEXT): {$(VPATH)}symbol.c
symbol.$(OBJEXT): {$(VPATH)}symbol.h
symbol.$(OBJEXT): {$(VPATH)}symbol.rb
symbol.$(OBJEXT): {$(VPATH)}symbol.rbinc
-symbol.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-symbol.$(OBJEXT): {$(VPATH)}thread_native.h
-symbol.$(OBJEXT): {$(VPATH)}vm_core.h
symbol.$(OBJEXT): {$(VPATH)}vm_debug.h
-symbol.$(OBJEXT): {$(VPATH)}vm_opts.h
symbol.$(OBJEXT): {$(VPATH)}vm_sync.h
thread.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
thread.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
@@ -17822,7 +15740,6 @@ thread.$(OBJEXT): $(CCAN_DIR)/list/list.h
thread.$(OBJEXT): $(CCAN_DIR)/str/str.h
thread.$(OBJEXT): $(hdrdir)/ruby.h
thread.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-thread.$(OBJEXT): $(hdrdir)/ruby/version.h
thread.$(OBJEXT): $(top_srcdir)/internal/array.h
thread.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
thread.$(OBJEXT): $(top_srcdir)/internal/bits.h
@@ -17845,28 +15762,6 @@ thread.$(OBJEXT): $(top_srcdir)/internal/time.h
thread.$(OBJEXT): $(top_srcdir)/internal/variable.h
thread.$(OBJEXT): $(top_srcdir)/internal/vm.h
thread.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-thread.$(OBJEXT): $(top_srcdir)/prism/defines.h
-thread.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-thread.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-thread.$(OBJEXT): $(top_srcdir)/prism/node.h
-thread.$(OBJEXT): $(top_srcdir)/prism/options.h
-thread.$(OBJEXT): $(top_srcdir)/prism/pack.h
-thread.$(OBJEXT): $(top_srcdir)/prism/parser.h
-thread.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-thread.$(OBJEXT): $(top_srcdir)/prism/prism.h
-thread.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
-thread.$(OBJEXT): {$(VPATH)}$(COROUTINE_H)
thread.$(OBJEXT): {$(VPATH)}assert.h
thread.$(OBJEXT): {$(VPATH)}atomic.h
thread.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -17887,6 +15782,7 @@ thread.$(OBJEXT): {$(VPATH)}defines.h
thread.$(OBJEXT): {$(VPATH)}encoding.h
thread.$(OBJEXT): {$(VPATH)}eval_intern.h
thread.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
+thread.$(OBJEXT): {$(VPATH)}gc.h
thread.$(OBJEXT): {$(VPATH)}hrtime.h
thread.$(OBJEXT): {$(VPATH)}id.h
thread.$(OBJEXT): {$(VPATH)}id_table.h
@@ -17930,7 +15826,6 @@ thread.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
thread.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
thread.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
thread.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-thread.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
thread.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
thread.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
thread.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -17999,6 +15894,7 @@ thread.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
thread.$(OBJEXT): {$(VPATH)}internal/intern/error.h
thread.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
thread.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+thread.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
thread.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
thread.$(OBJEXT): {$(VPATH)}internal/intern/io.h
thread.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -18029,6 +15925,7 @@ thread.$(OBJEXT): {$(VPATH)}internal/memory.h
thread.$(OBJEXT): {$(VPATH)}internal/method.h
thread.$(OBJEXT): {$(VPATH)}internal/module.h
thread.$(OBJEXT): {$(VPATH)}internal/newobj.h
+thread.$(OBJEXT): {$(VPATH)}internal/rgengc.h
thread.$(OBJEXT): {$(VPATH)}internal/scan_args.h
thread.$(OBJEXT): {$(VPATH)}internal/special_consts.h
thread.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -18044,18 +15941,14 @@ thread.$(OBJEXT): {$(VPATH)}io.h
thread.$(OBJEXT): {$(VPATH)}iseq.h
thread.$(OBJEXT): {$(VPATH)}method.h
thread.$(OBJEXT): {$(VPATH)}missing.h
+thread.$(OBJEXT): {$(VPATH)}mjit.h
thread.$(OBJEXT): {$(VPATH)}node.h
thread.$(OBJEXT): {$(VPATH)}onigmo.h
thread.$(OBJEXT): {$(VPATH)}oniguruma.h
-thread.$(OBJEXT): {$(VPATH)}prism/ast.h
-thread.$(OBJEXT): {$(VPATH)}prism/version.h
-thread.$(OBJEXT): {$(VPATH)}prism_compile.h
thread.$(OBJEXT): {$(VPATH)}ractor.h
thread.$(OBJEXT): {$(VPATH)}ractor_core.h
-thread.$(OBJEXT): {$(VPATH)}rjit.h
thread.$(OBJEXT): {$(VPATH)}ruby_assert.h
thread.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-thread.$(OBJEXT): {$(VPATH)}rubyparser.h
thread.$(OBJEXT): {$(VPATH)}shape.h
thread.$(OBJEXT): {$(VPATH)}st.h
thread.$(OBJEXT): {$(VPATH)}subst.h
@@ -18064,7 +15957,6 @@ thread.$(OBJEXT): {$(VPATH)}thread.h
thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).c
thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
thread.$(OBJEXT): {$(VPATH)}thread_native.h
-thread.$(OBJEXT): {$(VPATH)}thread_pthread_mn.c
thread.$(OBJEXT): {$(VPATH)}thread_sync.c
thread.$(OBJEXT): {$(VPATH)}thread_sync.rbinc
thread.$(OBJEXT): {$(VPATH)}timev.h
@@ -18072,10 +15964,6 @@ thread.$(OBJEXT): {$(VPATH)}vm_core.h
thread.$(OBJEXT): {$(VPATH)}vm_debug.h
thread.$(OBJEXT): {$(VPATH)}vm_opts.h
thread.$(OBJEXT): {$(VPATH)}vm_sync.h
-time.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-time.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-time.$(OBJEXT): $(CCAN_DIR)/list/list.h
-time.$(OBJEXT): $(CCAN_DIR)/str/str.h
time.$(OBJEXT): $(hdrdir)/ruby/ruby.h
time.$(OBJEXT): $(top_srcdir)/internal/array.h
time.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
@@ -18086,7 +15974,6 @@ time.$(OBJEXT): $(top_srcdir)/internal/compilers.h
time.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
time.$(OBJEXT): $(top_srcdir)/internal/gc.h
time.$(OBJEXT): $(top_srcdir)/internal/hash.h
-time.$(OBJEXT): $(top_srcdir)/internal/imemo.h
time.$(OBJEXT): $(top_srcdir)/internal/numeric.h
time.$(OBJEXT): $(top_srcdir)/internal/rational.h
time.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -18097,7 +15984,6 @@ time.$(OBJEXT): $(top_srcdir)/internal/variable.h
time.$(OBJEXT): $(top_srcdir)/internal/vm.h
time.$(OBJEXT): $(top_srcdir)/internal/warnings.h
time.$(OBJEXT): {$(VPATH)}assert.h
-time.$(OBJEXT): {$(VPATH)}atomic.h
time.$(OBJEXT): {$(VPATH)}backward/2/assume.h
time.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
time.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -18154,7 +16040,6 @@ time.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
time.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
time.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
time.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-time.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
time.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
time.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
time.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -18223,6 +16108,7 @@ time.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
time.$(OBJEXT): {$(VPATH)}internal/intern/error.h
time.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
time.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+time.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
time.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
time.$(OBJEXT): {$(VPATH)}internal/intern/io.h
time.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -18253,6 +16139,7 @@ time.$(OBJEXT): {$(VPATH)}internal/memory.h
time.$(OBJEXT): {$(VPATH)}internal/method.h
time.$(OBJEXT): {$(VPATH)}internal/module.h
time.$(OBJEXT): {$(VPATH)}internal/newobj.h
+time.$(OBJEXT): {$(VPATH)}internal/rgengc.h
time.$(OBJEXT): {$(VPATH)}internal/scan_args.h
time.$(OBJEXT): {$(VPATH)}internal/special_consts.h
time.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -18264,24 +16151,16 @@ time.$(OBJEXT): {$(VPATH)}internal/value_type.h
time.$(OBJEXT): {$(VPATH)}internal/variable.h
time.$(OBJEXT): {$(VPATH)}internal/warning_push.h
time.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-time.$(OBJEXT): {$(VPATH)}method.h
time.$(OBJEXT): {$(VPATH)}missing.h
-time.$(OBJEXT): {$(VPATH)}node.h
time.$(OBJEXT): {$(VPATH)}onigmo.h
time.$(OBJEXT): {$(VPATH)}oniguruma.h
time.$(OBJEXT): {$(VPATH)}ruby_assert.h
-time.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-time.$(OBJEXT): {$(VPATH)}rubyparser.h
time.$(OBJEXT): {$(VPATH)}shape.h
time.$(OBJEXT): {$(VPATH)}st.h
time.$(OBJEXT): {$(VPATH)}subst.h
-time.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-time.$(OBJEXT): {$(VPATH)}thread_native.h
time.$(OBJEXT): {$(VPATH)}time.c
time.$(OBJEXT): {$(VPATH)}timev.h
time.$(OBJEXT): {$(VPATH)}timev.rbinc
-time.$(OBJEXT): {$(VPATH)}vm_core.h
-time.$(OBJEXT): {$(VPATH)}vm_opts.h
transcode.$(OBJEXT): $(hdrdir)/ruby/ruby.h
transcode.$(OBJEXT): $(top_srcdir)/internal/array.h
transcode.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -18351,7 +16230,6 @@ transcode.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
transcode.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
transcode.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
transcode.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-transcode.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
transcode.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
transcode.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
transcode.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -18420,6 +16298,7 @@ transcode.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
transcode.$(OBJEXT): {$(VPATH)}internal/intern/error.h
transcode.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
transcode.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+transcode.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
transcode.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
transcode.$(OBJEXT): {$(VPATH)}internal/intern/io.h
transcode.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -18450,6 +16329,7 @@ transcode.$(OBJEXT): {$(VPATH)}internal/memory.h
transcode.$(OBJEXT): {$(VPATH)}internal/method.h
transcode.$(OBJEXT): {$(VPATH)}internal/module.h
transcode.$(OBJEXT): {$(VPATH)}internal/newobj.h
+transcode.$(OBJEXT): {$(VPATH)}internal/rgengc.h
transcode.$(OBJEXT): {$(VPATH)}internal/scan_args.h
transcode.$(OBJEXT): {$(VPATH)}internal/special_consts.h
transcode.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -18469,6 +16349,184 @@ transcode.$(OBJEXT): {$(VPATH)}st.h
transcode.$(OBJEXT): {$(VPATH)}subst.h
transcode.$(OBJEXT): {$(VPATH)}transcode.c
transcode.$(OBJEXT): {$(VPATH)}transcode_data.h
+transient_heap.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/array.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/compilers.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/gc.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/hash.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/struct.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/variable.h
+transient_heap.$(OBJEXT): $(top_srcdir)/internal/warnings.h
+transient_heap.$(OBJEXT): {$(VPATH)}assert.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/assume.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/bool.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/limits.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
+transient_heap.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
+transient_heap.$(OBJEXT): {$(VPATH)}config.h
+transient_heap.$(OBJEXT): {$(VPATH)}constant.h
+transient_heap.$(OBJEXT): {$(VPATH)}debug.h
+transient_heap.$(OBJEXT): {$(VPATH)}debug_counter.h
+transient_heap.$(OBJEXT): {$(VPATH)}defines.h
+transient_heap.$(OBJEXT): {$(VPATH)}gc.h
+transient_heap.$(OBJEXT): {$(VPATH)}id_table.h
+transient_heap.$(OBJEXT): {$(VPATH)}intern.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/abi.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/anyargs.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/assume.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/const.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/error.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/format.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/cast.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/config.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/constant_p.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/robject.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/ctype.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/dllexport.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/dosish.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/error.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/eval.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/event.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/fl_type.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/gc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/glob.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/globals.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/extension.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/feature.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/has/warning.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/array.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/class.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/error.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/io.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/load.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/object.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/process.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/random.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/range.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/re.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/select.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/string.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/time.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/interpreter.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/iterator.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/memory.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/method.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/module.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/newobj.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/rgengc.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/scan_args.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/special_consts.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/static_assert.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/stdalign.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/stdbool.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/symbol.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/value.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/value_type.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/variable.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/warning_push.h
+transient_heap.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+transient_heap.$(OBJEXT): {$(VPATH)}missing.h
+transient_heap.$(OBJEXT): {$(VPATH)}ruby_assert.h
+transient_heap.$(OBJEXT): {$(VPATH)}shape.h
+transient_heap.$(OBJEXT): {$(VPATH)}st.h
+transient_heap.$(OBJEXT): {$(VPATH)}subst.h
+transient_heap.$(OBJEXT): {$(VPATH)}transient_heap.c
+transient_heap.$(OBJEXT): {$(VPATH)}transient_heap.h
+transient_heap.$(OBJEXT): {$(VPATH)}vm_debug.h
+transient_heap.$(OBJEXT): {$(VPATH)}vm_sync.h
util.$(OBJEXT): $(hdrdir)/ruby/ruby.h
util.$(OBJEXT): $(top_srcdir)/internal/compilers.h
util.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -18528,7 +16586,6 @@ util.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
util.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
util.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
util.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-util.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
util.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
util.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
util.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -18588,6 +16645,7 @@ util.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
util.$(OBJEXT): {$(VPATH)}internal/intern/error.h
util.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
util.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+util.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
util.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
util.$(OBJEXT): {$(VPATH)}internal/intern/io.h
util.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -18618,6 +16676,7 @@ util.$(OBJEXT): {$(VPATH)}internal/memory.h
util.$(OBJEXT): {$(VPATH)}internal/method.h
util.$(OBJEXT): {$(VPATH)}internal/module.h
util.$(OBJEXT): {$(VPATH)}internal/newobj.h
+util.$(OBJEXT): {$(VPATH)}internal/rgengc.h
util.$(OBJEXT): {$(VPATH)}internal/scan_args.h
util.$(OBJEXT): {$(VPATH)}internal/special_consts.h
util.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -18640,7 +16699,6 @@ variable.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
variable.$(OBJEXT): $(CCAN_DIR)/list/list.h
variable.$(OBJEXT): $(CCAN_DIR)/str/str.h
variable.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-variable.$(OBJEXT): $(hdrdir)/ruby/version.h
variable.$(OBJEXT): $(top_srcdir)/internal/array.h
variable.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
variable.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -18718,7 +16776,6 @@ variable.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
variable.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
variable.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
variable.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-variable.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
variable.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
variable.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
variable.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -18787,6 +16844,7 @@ variable.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
variable.$(OBJEXT): {$(VPATH)}internal/intern/error.h
variable.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
variable.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+variable.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
variable.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
variable.$(OBJEXT): {$(VPATH)}internal/intern/io.h
variable.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -18817,6 +16875,7 @@ variable.$(OBJEXT): {$(VPATH)}internal/memory.h
variable.$(OBJEXT): {$(VPATH)}internal/method.h
variable.$(OBJEXT): {$(VPATH)}internal/module.h
variable.$(OBJEXT): {$(VPATH)}internal/newobj.h
+variable.$(OBJEXT): {$(VPATH)}internal/rgengc.h
variable.$(OBJEXT): {$(VPATH)}internal/scan_args.h
variable.$(OBJEXT): {$(VPATH)}internal/special_consts.h
variable.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -18837,13 +16896,12 @@ variable.$(OBJEXT): {$(VPATH)}ractor.h
variable.$(OBJEXT): {$(VPATH)}ractor_core.h
variable.$(OBJEXT): {$(VPATH)}ruby_assert.h
variable.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-variable.$(OBJEXT): {$(VPATH)}rubyparser.h
variable.$(OBJEXT): {$(VPATH)}shape.h
variable.$(OBJEXT): {$(VPATH)}st.h
variable.$(OBJEXT): {$(VPATH)}subst.h
-variable.$(OBJEXT): {$(VPATH)}symbol.h
variable.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
variable.$(OBJEXT): {$(VPATH)}thread_native.h
+variable.$(OBJEXT): {$(VPATH)}transient_heap.h
variable.$(OBJEXT): {$(VPATH)}util.h
variable.$(OBJEXT): {$(VPATH)}variable.c
variable.$(OBJEXT): {$(VPATH)}variable.h
@@ -18885,7 +16943,6 @@ version.$(OBJEXT): {$(VPATH)}config.h
version.$(OBJEXT): {$(VPATH)}constant.h
version.$(OBJEXT): {$(VPATH)}debug_counter.h
version.$(OBJEXT): {$(VPATH)}defines.h
-version.$(OBJEXT): {$(VPATH)}encoding.h
version.$(OBJEXT): {$(VPATH)}id.h
version.$(OBJEXT): {$(VPATH)}id_table.h
version.$(OBJEXT): {$(VPATH)}intern.h
@@ -18928,7 +16985,6 @@ version.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
version.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
version.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
version.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-version.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
version.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
version.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
version.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -18961,15 +17017,6 @@ version.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
version.$(OBJEXT): {$(VPATH)}internal/ctype.h
version.$(OBJEXT): {$(VPATH)}internal/dllexport.h
version.$(OBJEXT): {$(VPATH)}internal/dosish.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-version.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
version.$(OBJEXT): {$(VPATH)}internal/error.h
version.$(OBJEXT): {$(VPATH)}internal/eval.h
version.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -18997,6 +17044,7 @@ version.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
version.$(OBJEXT): {$(VPATH)}internal/intern/error.h
version.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
version.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+version.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
version.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
version.$(OBJEXT): {$(VPATH)}internal/intern/io.h
version.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -19027,6 +17075,7 @@ version.$(OBJEXT): {$(VPATH)}internal/memory.h
version.$(OBJEXT): {$(VPATH)}internal/method.h
version.$(OBJEXT): {$(VPATH)}internal/module.h
version.$(OBJEXT): {$(VPATH)}internal/newobj.h
+version.$(OBJEXT): {$(VPATH)}internal/rgengc.h
version.$(OBJEXT): {$(VPATH)}internal/scan_args.h
version.$(OBJEXT): {$(VPATH)}internal/special_consts.h
version.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -19040,14 +17089,11 @@ version.$(OBJEXT): {$(VPATH)}internal/warning_push.h
version.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
version.$(OBJEXT): {$(VPATH)}method.h
version.$(OBJEXT): {$(VPATH)}missing.h
+version.$(OBJEXT): {$(VPATH)}mjit.h
version.$(OBJEXT): {$(VPATH)}node.h
-version.$(OBJEXT): {$(VPATH)}onigmo.h
-version.$(OBJEXT): {$(VPATH)}oniguruma.h
version.$(OBJEXT): {$(VPATH)}revision.h
-version.$(OBJEXT): {$(VPATH)}rjit.h
version.$(OBJEXT): {$(VPATH)}ruby_assert.h
version.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-version.$(OBJEXT): {$(VPATH)}rubyparser.h
version.$(OBJEXT): {$(VPATH)}shape.h
version.$(OBJEXT): {$(VPATH)}st.h
version.$(OBJEXT): {$(VPATH)}subst.h
@@ -19063,7 +17109,6 @@ vm.$(OBJEXT): $(CCAN_DIR)/list/list.h
vm.$(OBJEXT): $(CCAN_DIR)/str/str.h
vm.$(OBJEXT): $(hdrdir)/ruby.h
vm.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-vm.$(OBJEXT): $(hdrdir)/ruby/version.h
vm.$(OBJEXT): $(top_srcdir)/internal/array.h
vm.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
vm.$(OBJEXT): $(top_srcdir)/internal/bignum.h
@@ -19073,7 +17118,6 @@ vm.$(OBJEXT): $(top_srcdir)/internal/compar.h
vm.$(OBJEXT): $(top_srcdir)/internal/compile.h
vm.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm.$(OBJEXT): $(top_srcdir)/internal/cont.h
-vm.$(OBJEXT): $(top_srcdir)/internal/encoding.h
vm.$(OBJEXT): $(top_srcdir)/internal/error.h
vm.$(OBJEXT): $(top_srcdir)/internal/eval.h
vm.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
@@ -19087,7 +17131,6 @@ vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
vm.$(OBJEXT): $(top_srcdir)/internal/proc.h
vm.$(OBJEXT): $(top_srcdir)/internal/random.h
vm.$(OBJEXT): $(top_srcdir)/internal/re.h
-vm.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
vm.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@@ -19095,31 +17138,9 @@ vm.$(OBJEXT): $(top_srcdir)/internal/string.h
vm.$(OBJEXT): $(top_srcdir)/internal/struct.h
vm.$(OBJEXT): $(top_srcdir)/internal/symbol.h
vm.$(OBJEXT): $(top_srcdir)/internal/thread.h
-vm.$(OBJEXT): $(top_srcdir)/internal/transcode.h
vm.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-vm.$(OBJEXT): $(top_srcdir)/prism/defines.h
-vm.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-vm.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-vm.$(OBJEXT): $(top_srcdir)/prism/node.h
-vm.$(OBJEXT): $(top_srcdir)/prism/options.h
-vm.$(OBJEXT): $(top_srcdir)/prism/pack.h
-vm.$(OBJEXT): $(top_srcdir)/prism/parser.h
-vm.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-vm.$(OBJEXT): $(top_srcdir)/prism/prism.h
-vm.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
vm.$(OBJEXT): {$(VPATH)}assert.h
vm.$(OBJEXT): {$(VPATH)}atomic.h
vm.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -19139,6 +17160,7 @@ vm.$(OBJEXT): {$(VPATH)}defines.h
vm.$(OBJEXT): {$(VPATH)}defs/opt_operand.def
vm.$(OBJEXT): {$(VPATH)}encoding.h
vm.$(OBJEXT): {$(VPATH)}eval_intern.h
+vm.$(OBJEXT): {$(VPATH)}gc.h
vm.$(OBJEXT): {$(VPATH)}id.h
vm.$(OBJEXT): {$(VPATH)}id_table.h
vm.$(OBJEXT): {$(VPATH)}insns.def
@@ -19184,7 +17206,6 @@ vm.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
vm.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
vm.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
vm.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-vm.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
vm.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
vm.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
vm.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -19253,6 +17274,7 @@ vm.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
vm.$(OBJEXT): {$(VPATH)}internal/intern/error.h
vm.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
vm.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
vm.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
vm.$(OBJEXT): {$(VPATH)}internal/intern/io.h
vm.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -19283,6 +17305,7 @@ vm.$(OBJEXT): {$(VPATH)}internal/memory.h
vm.$(OBJEXT): {$(VPATH)}internal/method.h
vm.$(OBJEXT): {$(VPATH)}internal/module.h
vm.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm.$(OBJEXT): {$(VPATH)}internal/rgengc.h
vm.$(OBJEXT): {$(VPATH)}internal/scan_args.h
vm.$(OBJEXT): {$(VPATH)}internal/special_consts.h
vm.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -19297,21 +17320,17 @@ vm.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
vm.$(OBJEXT): {$(VPATH)}iseq.h
vm.$(OBJEXT): {$(VPATH)}method.h
vm.$(OBJEXT): {$(VPATH)}missing.h
+vm.$(OBJEXT): {$(VPATH)}mjit.h
vm.$(OBJEXT): {$(VPATH)}node.h
vm.$(OBJEXT): {$(VPATH)}onigmo.h
vm.$(OBJEXT): {$(VPATH)}oniguruma.h
-vm.$(OBJEXT): {$(VPATH)}prism/ast.h
-vm.$(OBJEXT): {$(VPATH)}prism/version.h
-vm.$(OBJEXT): {$(VPATH)}prism_compile.h
vm.$(OBJEXT): {$(VPATH)}probes.dmyh
vm.$(OBJEXT): {$(VPATH)}probes.h
vm.$(OBJEXT): {$(VPATH)}probes_helper.h
vm.$(OBJEXT): {$(VPATH)}ractor.h
vm.$(OBJEXT): {$(VPATH)}ractor_core.h
-vm.$(OBJEXT): {$(VPATH)}rjit.h
vm.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-vm.$(OBJEXT): {$(VPATH)}rubyparser.h
vm.$(OBJEXT): {$(VPATH)}shape.h
vm.$(OBJEXT): {$(VPATH)}st.h
vm.$(OBJEXT): {$(VPATH)}subst.h
@@ -19341,10 +17360,8 @@ vm_backtrace.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/list/list.h
vm_backtrace.$(OBJEXT): $(CCAN_DIR)/str/str.h
vm_backtrace.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-vm_backtrace.$(OBJEXT): $(hdrdir)/ruby/version.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/array.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/class.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h
@@ -19355,27 +17372,6 @@ vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/string.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/defines.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/node.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/options.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/pack.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/parser.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/prism.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
vm_backtrace.$(OBJEXT): {$(VPATH)}assert.h
vm_backtrace.$(OBJEXT): {$(VPATH)}atomic.h
vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -19390,7 +17386,6 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
vm_backtrace.$(OBJEXT): {$(VPATH)}config.h
vm_backtrace.$(OBJEXT): {$(VPATH)}constant.h
vm_backtrace.$(OBJEXT): {$(VPATH)}debug.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}debug_counter.h
vm_backtrace.$(OBJEXT): {$(VPATH)}defines.h
vm_backtrace.$(OBJEXT): {$(VPATH)}encoding.h
vm_backtrace.$(OBJEXT): {$(VPATH)}eval_intern.h
@@ -19436,7 +17431,6 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -19505,6 +17499,7 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/error.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/io.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -19535,6 +17530,7 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}internal/memory.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/method.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/module.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}internal/rgengc.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/scan_args.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/special_consts.h
vm_backtrace.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -19552,12 +17548,8 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}missing.h
vm_backtrace.$(OBJEXT): {$(VPATH)}node.h
vm_backtrace.$(OBJEXT): {$(VPATH)}onigmo.h
vm_backtrace.$(OBJEXT): {$(VPATH)}oniguruma.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}prism/ast.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}prism/version.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}prism_compile.h
vm_backtrace.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm_backtrace.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}rubyparser.h
vm_backtrace.$(OBJEXT): {$(VPATH)}shape.h
vm_backtrace.$(OBJEXT): {$(VPATH)}st.h
vm_backtrace.$(OBJEXT): {$(VPATH)}subst.h
@@ -19565,9 +17557,7 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
vm_backtrace.$(OBJEXT): {$(VPATH)}thread_native.h
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_backtrace.c
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_core.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}vm_debug.h
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_opts.h
-vm_backtrace.$(OBJEXT): {$(VPATH)}vm_sync.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
vm_dump.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -19583,27 +17573,6 @@ vm_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/defines.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/node.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/options.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/pack.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/parser.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/prism.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
vm_dump.$(OBJEXT): {$(VPATH)}addr2line.h
vm_dump.$(OBJEXT): {$(VPATH)}assert.h
vm_dump.$(OBJEXT): {$(VPATH)}atomic.h
@@ -19619,7 +17588,7 @@ vm_dump.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
vm_dump.$(OBJEXT): {$(VPATH)}config.h
vm_dump.$(OBJEXT): {$(VPATH)}constant.h
vm_dump.$(OBJEXT): {$(VPATH)}defines.h
-vm_dump.$(OBJEXT): {$(VPATH)}encoding.h
+vm_dump.$(OBJEXT): {$(VPATH)}gc.h
vm_dump.$(OBJEXT): {$(VPATH)}id.h
vm_dump.$(OBJEXT): {$(VPATH)}id_table.h
vm_dump.$(OBJEXT): {$(VPATH)}intern.h
@@ -19662,7 +17631,6 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -19695,15 +17663,6 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/ctype.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/dllexport.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/dosish.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/error.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/eval.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -19731,6 +17690,7 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/error.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/io.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -19761,6 +17721,7 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/memory.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/method.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/module.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal/rgengc.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/scan_args.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/special_consts.h
vm_dump.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -19776,17 +17737,11 @@ vm_dump.$(OBJEXT): {$(VPATH)}iseq.h
vm_dump.$(OBJEXT): {$(VPATH)}method.h
vm_dump.$(OBJEXT): {$(VPATH)}missing.h
vm_dump.$(OBJEXT): {$(VPATH)}node.h
-vm_dump.$(OBJEXT): {$(VPATH)}onigmo.h
-vm_dump.$(OBJEXT): {$(VPATH)}oniguruma.h
-vm_dump.$(OBJEXT): {$(VPATH)}prism/ast.h
-vm_dump.$(OBJEXT): {$(VPATH)}prism/version.h
-vm_dump.$(OBJEXT): {$(VPATH)}prism_compile.h
vm_dump.$(OBJEXT): {$(VPATH)}procstat_vm.c
vm_dump.$(OBJEXT): {$(VPATH)}ractor.h
vm_dump.$(OBJEXT): {$(VPATH)}ractor_core.h
vm_dump.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm_dump.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-vm_dump.$(OBJEXT): {$(VPATH)}rubyparser.h
vm_dump.$(OBJEXT): {$(VPATH)}shape.h
vm_dump.$(OBJEXT): {$(VPATH)}st.h
vm_dump.$(OBJEXT): {$(VPATH)}subst.h
@@ -19808,7 +17763,6 @@ vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-vm_sync.$(OBJEXT): $(top_srcdir)/internal/thread.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@@ -19827,7 +17781,7 @@ vm_sync.$(OBJEXT): {$(VPATH)}config.h
vm_sync.$(OBJEXT): {$(VPATH)}constant.h
vm_sync.$(OBJEXT): {$(VPATH)}debug_counter.h
vm_sync.$(OBJEXT): {$(VPATH)}defines.h
-vm_sync.$(OBJEXT): {$(VPATH)}encoding.h
+vm_sync.$(OBJEXT): {$(VPATH)}gc.h
vm_sync.$(OBJEXT): {$(VPATH)}id.h
vm_sync.$(OBJEXT): {$(VPATH)}id_table.h
vm_sync.$(OBJEXT): {$(VPATH)}intern.h
@@ -19870,7 +17824,6 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -19903,15 +17856,6 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/ctype.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/dllexport.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/dosish.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/error.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/eval.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -19939,6 +17883,7 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/error.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/io.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -19969,6 +17914,7 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/memory.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/method.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/module.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_sync.$(OBJEXT): {$(VPATH)}internal/rgengc.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/scan_args.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/special_consts.h
vm_sync.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -19983,13 +17929,10 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
vm_sync.$(OBJEXT): {$(VPATH)}method.h
vm_sync.$(OBJEXT): {$(VPATH)}missing.h
vm_sync.$(OBJEXT): {$(VPATH)}node.h
-vm_sync.$(OBJEXT): {$(VPATH)}onigmo.h
-vm_sync.$(OBJEXT): {$(VPATH)}oniguruma.h
vm_sync.$(OBJEXT): {$(VPATH)}ractor.h
vm_sync.$(OBJEXT): {$(VPATH)}ractor_core.h
vm_sync.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm_sync.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-vm_sync.$(OBJEXT): {$(VPATH)}rubyparser.h
vm_sync.$(OBJEXT): {$(VPATH)}shape.h
vm_sync.$(OBJEXT): {$(VPATH)}st.h
vm_sync.$(OBJEXT): {$(VPATH)}subst.h
@@ -20008,8 +17951,6 @@ vm_trace.$(OBJEXT): $(hdrdir)/ruby.h
vm_trace.$(OBJEXT): $(hdrdir)/ruby/ruby.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/array.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-vm_trace.$(OBJEXT): $(top_srcdir)/internal/bits.h
-vm_trace.$(OBJEXT): $(top_srcdir)/internal/class.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h
@@ -20017,31 +17958,9 @@ vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/symbol.h
-vm_trace.$(OBJEXT): $(top_srcdir)/internal/thread.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/defines.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/node.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/options.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/pack.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/parser.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/prism.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
vm_trace.$(OBJEXT): {$(VPATH)}assert.h
vm_trace.$(OBJEXT): {$(VPATH)}atomic.h
vm_trace.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -20103,7 +18022,6 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -20172,6 +18090,7 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/error.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/io.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -20202,6 +18121,7 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/memory.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/method.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/module.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/newobj.h
+vm_trace.$(OBJEXT): {$(VPATH)}internal/rgengc.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/scan_args.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/special_consts.h
vm_trace.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -20216,17 +18136,13 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
vm_trace.$(OBJEXT): {$(VPATH)}iseq.h
vm_trace.$(OBJEXT): {$(VPATH)}method.h
vm_trace.$(OBJEXT): {$(VPATH)}missing.h
+vm_trace.$(OBJEXT): {$(VPATH)}mjit.h
vm_trace.$(OBJEXT): {$(VPATH)}node.h
vm_trace.$(OBJEXT): {$(VPATH)}onigmo.h
vm_trace.$(OBJEXT): {$(VPATH)}oniguruma.h
-vm_trace.$(OBJEXT): {$(VPATH)}prism/ast.h
-vm_trace.$(OBJEXT): {$(VPATH)}prism/version.h
-vm_trace.$(OBJEXT): {$(VPATH)}prism_compile.h
vm_trace.$(OBJEXT): {$(VPATH)}ractor.h
-vm_trace.$(OBJEXT): {$(VPATH)}rjit.h
vm_trace.$(OBJEXT): {$(VPATH)}ruby_assert.h
vm_trace.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-vm_trace.$(OBJEXT): {$(VPATH)}rubyparser.h
vm_trace.$(OBJEXT): {$(VPATH)}shape.h
vm_trace.$(OBJEXT): {$(VPATH)}st.h
vm_trace.$(OBJEXT): {$(VPATH)}subst.h
@@ -20234,208 +18150,9 @@ vm_trace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
vm_trace.$(OBJEXT): {$(VPATH)}thread_native.h
vm_trace.$(OBJEXT): {$(VPATH)}trace_point.rbinc
vm_trace.$(OBJEXT): {$(VPATH)}vm_core.h
-vm_trace.$(OBJEXT): {$(VPATH)}vm_debug.h
vm_trace.$(OBJEXT): {$(VPATH)}vm_opts.h
-vm_trace.$(OBJEXT): {$(VPATH)}vm_sync.h
vm_trace.$(OBJEXT): {$(VPATH)}vm_trace.c
vm_trace.$(OBJEXT): {$(VPATH)}yjit.h
-weakmap.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
-weakmap.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
-weakmap.$(OBJEXT): $(CCAN_DIR)/list/list.h
-weakmap.$(OBJEXT): $(CCAN_DIR)/str/str.h
-weakmap.$(OBJEXT): $(hdrdir)/ruby/ruby.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/array.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/compilers.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/gc.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/hash.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/proc.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/serial.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/vm.h
-weakmap.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-weakmap.$(OBJEXT): {$(VPATH)}assert.h
-weakmap.$(OBJEXT): {$(VPATH)}atomic.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/assume.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/bool.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/limits.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
-weakmap.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
-weakmap.$(OBJEXT): {$(VPATH)}config.h
-weakmap.$(OBJEXT): {$(VPATH)}defines.h
-weakmap.$(OBJEXT): {$(VPATH)}encoding.h
-weakmap.$(OBJEXT): {$(VPATH)}id.h
-weakmap.$(OBJEXT): {$(VPATH)}intern.h
-weakmap.$(OBJEXT): {$(VPATH)}internal.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/abi.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/anyargs.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/assume.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/const.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/error.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/format.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/cast.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/config.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/constant_p.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/robject.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/ctype.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/dllexport.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/dosish.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/error.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/eval.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/event.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/fl_type.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/gc.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/glob.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/globals.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/extension.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/feature.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/has/warning.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/array.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/class.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/error.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/file.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/io.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/load.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/object.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/process.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/random.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/range.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/re.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/select.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/string.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/time.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/interpreter.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/iterator.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/memory.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/method.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/module.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/newobj.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/scan_args.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/special_consts.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/static_assert.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/stdalign.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/stdbool.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/symbol.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/value.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/value_type.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/variable.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/warning_push.h
-weakmap.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
-weakmap.$(OBJEXT): {$(VPATH)}method.h
-weakmap.$(OBJEXT): {$(VPATH)}missing.h
-weakmap.$(OBJEXT): {$(VPATH)}node.h
-weakmap.$(OBJEXT): {$(VPATH)}onigmo.h
-weakmap.$(OBJEXT): {$(VPATH)}oniguruma.h
-weakmap.$(OBJEXT): {$(VPATH)}ruby_assert.h
-weakmap.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-weakmap.$(OBJEXT): {$(VPATH)}rubyparser.h
-weakmap.$(OBJEXT): {$(VPATH)}st.h
-weakmap.$(OBJEXT): {$(VPATH)}subst.h
-weakmap.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
-weakmap.$(OBJEXT): {$(VPATH)}thread_native.h
-weakmap.$(OBJEXT): {$(VPATH)}vm_core.h
-weakmap.$(OBJEXT): {$(VPATH)}vm_opts.h
-weakmap.$(OBJEXT): {$(VPATH)}weakmap.c
yjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
yjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
yjit.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -20443,8 +18160,6 @@ yjit.$(OBJEXT): $(CCAN_DIR)/str/str.h
yjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
yjit.$(OBJEXT): $(top_srcdir)/internal/array.h
yjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
-yjit.$(OBJEXT): $(top_srcdir)/internal/bignum.h
-yjit.$(OBJEXT): $(top_srcdir)/internal/bits.h
yjit.$(OBJEXT): $(top_srcdir)/internal/class.h
yjit.$(OBJEXT): $(top_srcdir)/internal/compile.h
yjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
@@ -20453,7 +18168,6 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
-yjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
yjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@@ -20461,27 +18175,6 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/string.h
yjit.$(OBJEXT): $(top_srcdir)/internal/variable.h
yjit.$(OBJEXT): $(top_srcdir)/internal/vm.h
yjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/defines.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/encoding.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/node.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/options.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/pack.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/parser.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/prism.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/regexp.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
-yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
yjit.$(OBJEXT): {$(VPATH)}assert.h
yjit.$(OBJEXT): {$(VPATH)}atomic.h
yjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -20500,6 +18193,7 @@ yjit.$(OBJEXT): {$(VPATH)}debug.h
yjit.$(OBJEXT): {$(VPATH)}debug_counter.h
yjit.$(OBJEXT): {$(VPATH)}defines.h
yjit.$(OBJEXT): {$(VPATH)}encoding.h
+yjit.$(OBJEXT): {$(VPATH)}gc.h
yjit.$(OBJEXT): {$(VPATH)}id.h
yjit.$(OBJEXT): {$(VPATH)}id_table.h
yjit.$(OBJEXT): {$(VPATH)}insns.def
@@ -20545,7 +18239,6 @@ yjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
yjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
yjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
yjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
-yjit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
yjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
yjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
yjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
@@ -20614,6 +18307,7 @@ yjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
yjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h
yjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
yjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h
+yjit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h
yjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
yjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h
yjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h
@@ -20644,7 +18338,7 @@ yjit.$(OBJEXT): {$(VPATH)}internal/memory.h
yjit.$(OBJEXT): {$(VPATH)}internal/method.h
yjit.$(OBJEXT): {$(VPATH)}internal/module.h
yjit.$(OBJEXT): {$(VPATH)}internal/newobj.h
-yjit.$(OBJEXT): {$(VPATH)}internal/numeric.h
+yjit.$(OBJEXT): {$(VPATH)}internal/rgengc.h
yjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h
yjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h
yjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h
@@ -20662,15 +18356,11 @@ yjit.$(OBJEXT): {$(VPATH)}missing.h
yjit.$(OBJEXT): {$(VPATH)}node.h
yjit.$(OBJEXT): {$(VPATH)}onigmo.h
yjit.$(OBJEXT): {$(VPATH)}oniguruma.h
-yjit.$(OBJEXT): {$(VPATH)}prism/ast.h
-yjit.$(OBJEXT): {$(VPATH)}prism/version.h
-yjit.$(OBJEXT): {$(VPATH)}prism_compile.h
yjit.$(OBJEXT): {$(VPATH)}probes.dmyh
yjit.$(OBJEXT): {$(VPATH)}probes.h
yjit.$(OBJEXT): {$(VPATH)}probes_helper.h
yjit.$(OBJEXT): {$(VPATH)}ruby_assert.h
yjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h
-yjit.$(OBJEXT): {$(VPATH)}rubyparser.h
yjit.$(OBJEXT): {$(VPATH)}shape.h
yjit.$(OBJEXT): {$(VPATH)}st.h
yjit.$(OBJEXT): {$(VPATH)}subst.h
diff --git a/compar.c b/compar.c
index 081b4e2dea..040f77975e 100644
--- a/compar.c
+++ b/compar.c
@@ -187,12 +187,6 @@ cmp_between(VALUE x, VALUE min, VALUE max)
* 'd'.clamp('a', 'f') #=> 'd'
* 'z'.clamp('a', 'f') #=> 'f'
*
- * If _min_ is +nil+, it is considered smaller than _obj_,
- * and if _max_ is +nil+, it is considered greater than _obj_.
- *
- * -20.clamp(0, nil) #=> 0
- * 523.clamp(nil, 100) #=> 100
- *
* In <code>(range)</code> form, returns _range.begin_ if _obj_
* <code><=></code> _range.begin_ is less than zero, _range.end_
* if _obj_ <code><=></code> _range.end_ is greater than zero, and
@@ -235,7 +229,7 @@ cmp_clamp(int argc, VALUE *argv, VALUE x)
}
}
if (!NIL_P(min) && !NIL_P(max) && cmpint(min, max) > 0) {
- rb_raise(rb_eArgError, "min argument must be less than or equal to max argument");
+ rb_raise(rb_eArgError, "min argument must be smaller than max argument");
}
if (!NIL_P(min)) {
@@ -263,28 +257,25 @@ cmp_clamp(int argc, VALUE *argv, VALUE x)
* <code>==</code>, <code>>=</code>, and <code>></code>) and the
* method <code>between?</code>.
*
- * class StringSorter
+ * class SizeMatters
* include Comparable
- *
* attr :str
* def <=>(other)
* str.size <=> other.str.size
* end
- *
* def initialize(str)
* @str = str
* end
- *
* def inspect
* @str
* end
* end
*
- * s1 = StringSorter.new("Z")
- * s2 = StringSorter.new("YY")
- * s3 = StringSorter.new("XXX")
- * s4 = StringSorter.new("WWWW")
- * s5 = StringSorter.new("VVVVV")
+ * s1 = SizeMatters.new("Z")
+ * s2 = SizeMatters.new("YY")
+ * s3 = SizeMatters.new("XXX")
+ * s4 = SizeMatters.new("WWWW")
+ * s5 = SizeMatters.new("VVVVV")
*
* s1 < s2 #=> true
* s4.between?(s1, s3) #=> false
@@ -298,8 +289,8 @@ cmp_clamp(int argc, VALUE *argv, VALUE x)
* - #<: Returns whether +self+ is less than the given object.
* - #<=: Returns whether +self+ is less than or equal to the given object.
* - #==: Returns whether +self+ is equal to the given object.
- * - #>: Returns whether +self+ is greater than the given object.
- * - #>=: Returns whether +self+ is greater than or equal to the given object.
+ * - #>: Returns whether +self+ is greater than or equal to the given object.
+ * - #>=: Returns whether +self+ is greater than the given object.
* - #between?: Returns +true+ if +self+ is between two given objects.
* - #clamp: For given objects +min+ and +max+, or range <tt>(min..max)</tt>, returns:
*
diff --git a/compile.c b/compile.c
index a938d58abb..0452305923 100644
--- a/compile.c
+++ b/compile.c
@@ -17,6 +17,7 @@
#endif
#include "encindex.h"
+#include "gc.h"
#include "id_table.h"
#include "internal.h"
#include "internal/array.h"
@@ -24,7 +25,6 @@
#include "internal/complex.h"
#include "internal/encoding.h"
#include "internal/error.h"
-#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/numeric.h"
#include "internal/object.h"
@@ -39,7 +39,6 @@
#include "vm_core.h"
#include "vm_callinfo.h"
#include "vm_debug.h"
-#include "yjit.h"
#include "builtin.h"
#include "insns.inc"
@@ -119,7 +118,7 @@ struct ensure_range {
};
struct iseq_compile_data_ensure_node_stack {
- const void *ensure_node;
+ const NODE *ensure_node;
struct iseq_compile_data_ensure_node_stack *prev;
struct ensure_range *erange;
};
@@ -333,10 +332,10 @@ static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NOD
(debug_compile("== " desc "\n", \
iseq_compile_each(iseq, (anchor), (node), (popped))))
-#define COMPILE_RECV(anchor, desc, node, recv) \
+#define COMPILE_RECV(anchor, desc, node) \
(private_recv_p(node) ? \
(ADD_INSN(anchor, node, putself), VM_CALL_FCALL) : \
- COMPILE(anchor, desc, recv) ? 0 : -1)
+ COMPILE(anchor, desc, node->nd_recv) ? 0 : -1)
#define OPERAND_AT(insn, idx) \
(((INSN*)(insn))->operands[(idx)])
@@ -487,6 +486,7 @@ static int iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl);
static int iseq_set_exception_local_table(rb_iseq_t *iseq);
static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, const NODE *const node);
+static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
static int iseq_set_exception_table(rb_iseq_t *iseq);
static int iseq_set_optargs_table(rb_iseq_t *iseq);
@@ -721,117 +721,6 @@ validate_labels(rb_iseq_t *iseq, st_table *labels_table)
st_free_table(labels_table);
}
-static NODE *
-get_nd_recv(const NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_CALL:
- return RNODE_CALL(node)->nd_recv;
- case NODE_OPCALL:
- return RNODE_OPCALL(node)->nd_recv;
- case NODE_FCALL:
- return 0;
- case NODE_QCALL:
- return RNODE_QCALL(node)->nd_recv;
- case NODE_VCALL:
- return 0;
- case NODE_ATTRASGN:
- return RNODE_ATTRASGN(node)->nd_recv;
- case NODE_OP_ASGN1:
- return RNODE_OP_ASGN1(node)->nd_recv;
- case NODE_OP_ASGN2:
- return RNODE_OP_ASGN2(node)->nd_recv;
- default:
- rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
- }
-}
-
-static ID
-get_node_call_nd_mid(const NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_CALL:
- return RNODE_CALL(node)->nd_mid;
- case NODE_OPCALL:
- return RNODE_OPCALL(node)->nd_mid;
- case NODE_FCALL:
- return RNODE_FCALL(node)->nd_mid;
- case NODE_QCALL:
- return RNODE_QCALL(node)->nd_mid;
- case NODE_VCALL:
- return RNODE_VCALL(node)->nd_mid;
- case NODE_ATTRASGN:
- return RNODE_ATTRASGN(node)->nd_mid;
- default:
- rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
- }
-}
-
-static NODE *
-get_nd_args(const NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_CALL:
- return RNODE_CALL(node)->nd_args;
- case NODE_OPCALL:
- return RNODE_OPCALL(node)->nd_args;
- case NODE_FCALL:
- return RNODE_FCALL(node)->nd_args;
- case NODE_QCALL:
- return RNODE_QCALL(node)->nd_args;
- case NODE_VCALL:
- return 0;
- case NODE_ATTRASGN:
- return RNODE_ATTRASGN(node)->nd_args;
- default:
- rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
- }
-}
-
-static ID
-get_node_colon_nd_mid(const NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_COLON2:
- return RNODE_COLON2(node)->nd_mid;
- case NODE_COLON3:
- return RNODE_COLON3(node)->nd_mid;
- default:
- rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
- }
-}
-
-static ID
-get_nd_vid(const NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_LASGN:
- return RNODE_LASGN(node)->nd_vid;
- case NODE_DASGN:
- return RNODE_DASGN(node)->nd_vid;
- case NODE_IASGN:
- return RNODE_IASGN(node)->nd_vid;
- case NODE_CVASGN:
- return RNODE_CVASGN(node)->nd_vid;
- default:
- rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
- }
-}
-
-
-static NODE *
-get_nd_value(const NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_LASGN:
- return RNODE_LASGN(node)->nd_value;
- case NODE_DASGN:
- return RNODE_DASGN(node)->nd_value;
- default:
- rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
- }
-}
-
VALUE
rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
{
@@ -864,8 +753,8 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
/* assume node is T_NODE */
else if (nd_type_p(node, NODE_SCOPE)) {
/* iseq type of top, method, class, block */
- iseq_set_local_table(iseq, RNODE_SCOPE(node)->nd_tbl);
- iseq_set_arguments(iseq, ret, (NODE *)RNODE_SCOPE(node)->nd_args);
+ iseq_set_local_table(iseq, node->nd_tbl);
+ iseq_set_arguments(iseq, ret, node->nd_args);
switch (ISEQ_BODY(iseq)->type) {
case ISEQ_TYPE_BLOCK:
@@ -880,7 +769,7 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
NODE dummy_line_node = generate_dummy_line_node(ISEQ_BODY(iseq)->location.first_lineno, -1);
ADD_INSN (ret, &dummy_line_node, nop);
ADD_LABEL(ret, start);
- CHECK(COMPILE(ret, "block body", RNODE_SCOPE(node)->nd_body));
+ CHECK(COMPILE(ret, "block body", node->nd_body));
ADD_LABEL(ret, end);
ADD_TRACE(ret, RUBY_EVENT_B_RETURN);
ISEQ_COMPILE_DATA(iseq)->last_line = ISEQ_BODY(iseq)->location.code_location.end_pos.lineno;
@@ -893,23 +782,23 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
case ISEQ_TYPE_CLASS:
{
ADD_TRACE(ret, RUBY_EVENT_CLASS);
- CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body));
+ CHECK(COMPILE(ret, "scoped node", node->nd_body));
ADD_TRACE(ret, RUBY_EVENT_END);
ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node);
break;
}
case ISEQ_TYPE_METHOD:
{
- ISEQ_COMPILE_DATA(iseq)->root_node = RNODE_SCOPE(node)->nd_body;
+ ISEQ_COMPILE_DATA(iseq)->root_node = node->nd_body;
ADD_TRACE(ret, RUBY_EVENT_CALL);
- CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body));
- ISEQ_COMPILE_DATA(iseq)->root_node = RNODE_SCOPE(node)->nd_body;
+ CHECK(COMPILE(ret, "scoped node", node->nd_body));
+ ISEQ_COMPILE_DATA(iseq)->root_node = node->nd_body;
ADD_TRACE(ret, RUBY_EVENT_RETURN);
ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node);
break;
}
default: {
- CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body));
+ CHECK(COMPILE(ret, "scoped node", node->nd_body));
break;
}
}
@@ -967,20 +856,6 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
return iseq_setup(iseq, ret);
}
-static VALUE rb_translate_prism(pm_parser_t *parser, rb_iseq_t *iseq, pm_scope_node_t *scope_node, LINK_ANCHOR *const ret);
-
-VALUE
-rb_iseq_compile_prism_node(rb_iseq_t * iseq, pm_scope_node_t *scope_node, pm_parser_t *parser)
-{
- DECL_ANCHOR(ret);
- INIT_ANCHOR(ret);
-
- CHECK(rb_translate_prism(parser, iseq, scope_node, ret));
-
- CHECK(iseq_setup_insn(iseq, ret));
- return iseq_setup(iseq, ret);
-}
-
static int
rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
{
@@ -997,11 +872,6 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
}
FL_SET((VALUE)iseq, ISEQ_TRANSLATED);
#endif
-
-#if USE_YJIT
- rb_yjit_live_iseq_count++;
-#endif
-
return COMPILE_OK;
}
@@ -1374,7 +1244,7 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line)
}
static void
-iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE data)
+iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE data)
{
const char *types = insn_op_types(insn->insn_id);
for (int j = 0; types[j]; j++) {
@@ -1385,7 +1255,7 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE dat
case TS_VALUE:
case TS_IC: // constant path array
case TS_CALLDATA: // ci is stored.
- func(OPERAND_AT(insn, j), data);
+ func(&OPERAND_AT(insn, j), data);
break;
default:
break;
@@ -1394,9 +1264,9 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE dat
}
static void
-iseq_insn_each_object_write_barrier(VALUE obj, VALUE iseq)
+iseq_insn_each_object_write_barrier(VALUE *obj_ptr, VALUE iseq)
{
- RB_OBJ_WRITTEN(iseq, Qundef, obj);
+ RB_OBJ_WRITTEN(iseq, Qundef, *obj_ptr);
}
static INSN *
@@ -1485,8 +1355,7 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
rb_ast_body_t ast;
ast.root = node;
- ast.frozen_string_literal = -1;
- ast.coverage_enabled = -1;
+ ast.compile_option = 0;
ast.script_lines = ISEQ_BODY(iseq)->variable.script_lines;
debugs("[new_child_iseq]> ---------------------------------------\n");
@@ -1515,14 +1384,11 @@ new_child_iseq_with_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_call
}
static void
-set_catch_except_p(rb_iseq_t *iseq)
+set_catch_except_p(struct rb_iseq_constant_body *body)
{
- RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq));
- ISEQ_COMPILE_DATA(iseq)->catch_except_p = true;
- if (ISEQ_BODY(iseq)->parent_iseq != NULL) {
- if (ISEQ_COMPILE_DATA(ISEQ_BODY(iseq)->parent_iseq)) {
- set_catch_except_p((rb_iseq_t *) ISEQ_BODY(iseq)->parent_iseq);
- }
+ body->catch_except_p = true;
+ if (body->parent_iseq != NULL) {
+ set_catch_except_p(ISEQ_BODY(body->parent_iseq));
}
}
@@ -1534,7 +1400,7 @@ set_catch_except_p(rb_iseq_t *iseq)
So this function sets true for limited ISeqs with break/next/redo catch table entries
whose child ISeq would really raise an exception. */
static void
-update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body)
+update_catch_except_flags(struct rb_iseq_constant_body *body)
{
unsigned int pos;
size_t i;
@@ -1547,7 +1413,7 @@ update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body)
while (pos < body->iseq_size) {
insn = rb_vm_insn_decode(body->iseq_encoded[pos]);
if (insn == BIN(throw)) {
- set_catch_except_p(iseq);
+ set_catch_except_p(body);
break;
}
pos += insn_len(insn);
@@ -1562,8 +1428,7 @@ update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body)
if (entry->type != CATCH_TYPE_BREAK
&& entry->type != CATCH_TYPE_NEXT
&& entry->type != CATCH_TYPE_REDO) {
- RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq));
- ISEQ_COMPILE_DATA(iseq)->catch_except_p = true;
+ body->catch_except_p = true;
break;
}
}
@@ -1575,9 +1440,9 @@ iseq_insert_nop_between_end_and_cont(rb_iseq_t *iseq)
VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
if (NIL_P(catch_table_ary)) return;
unsigned int i, tlen = (unsigned int)RARRAY_LEN(catch_table_ary);
- const VALUE *tptr = RARRAY_CONST_PTR(catch_table_ary);
+ const VALUE *tptr = RARRAY_CONST_PTR_TRANSIENT(catch_table_ary);
for (i = 0; i < tlen; i++) {
- const VALUE *ptr = RARRAY_CONST_PTR(tptr[i]);
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(tptr[i]);
LINK_ELEMENT *end = (LINK_ELEMENT *)(ptr[2] & ~1);
LINK_ELEMENT *cont = (LINK_ELEMENT *)(ptr[4] & ~1);
LINK_ELEMENT *e;
@@ -1624,6 +1489,13 @@ iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
dump_disasm_list(FIRST_ELEMENT(anchor));
}
+ if (ISEQ_COMPILE_DATA(iseq)->option->stack_caching) {
+ debugs("[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
+ iseq_set_sequence_stackcaching(iseq, anchor);
+ if (compile_debug > 5)
+ dump_disasm_list(FIRST_ELEMENT(anchor));
+ }
+
debugs("[compile step 3.4 (iseq_insert_nop_between_end_and_cont)]\n");
iseq_insert_nop_between_end_and_cont(iseq);
if (compile_debug > 5)
@@ -1653,12 +1525,10 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
if (!rb_iseq_translate_threaded_code(iseq)) return COMPILE_NG;
debugs("[compile step 6 (update_catch_except_flags)] \n");
- RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq));
- update_catch_except_flags(iseq, ISEQ_BODY(iseq));
+ update_catch_except_flags(ISEQ_BODY(iseq));
debugs("[compile step 6.1 (remove unused catch tables)] \n");
- RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq));
- if (!ISEQ_COMPILE_DATA(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) {
+ if (!ISEQ_BODY(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) {
xfree(ISEQ_BODY(iseq)->catch_table);
ISEQ_BODY(iseq)->catch_table = NULL;
}
@@ -1899,7 +1769,7 @@ static int
iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
const struct rb_args_info *args, int arg_size)
{
- const rb_node_kw_arg_t *node = args->kw_args;
+ const NODE *node = args->kw_args;
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
struct rb_iseq_param_keyword *keyword;
const VALUE default_values = rb_ary_hidden_new(1);
@@ -1918,7 +1788,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
node = args->kw_args;
while (node) {
- const NODE *val_node = get_nd_value(node->nd_body);
+ const NODE *val_node = node->nd_body->nd_value;
VALUE dv;
if (val_node == NODE_SPECIAL_REQUIRED_KEYWORD) {
@@ -1927,7 +1797,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
else {
switch (nd_type(val_node)) {
case NODE_LIT:
- dv = RNODE_LIT(val_node)->nd_lit;
+ dv = val_node->nd_lit;
break;
case NODE_NIL:
dv = Qnil;
@@ -1939,7 +1809,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
dv = Qfalse;
break;
default:
- NO_CHECK(COMPILE_POPPED(optargs, "kwarg", RNODE(node))); /* nd_type_p(node, NODE_KW_ARG) */
+ NO_CHECK(COMPILE_POPPED(optargs, "kwarg", node)); /* nd_type_p(node, NODE_KW_ARG) */
dv = complex_mark;
}
@@ -1952,7 +1822,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
keyword->num = kw;
- if (RNODE_DVAR(args->kw_rest_arg)->nd_vid != 0) {
+ if (args->kw_rest_arg->nd_vid != 0) {
keyword->rest_start = arg_size++;
body->param.flags.has_kwrest = TRUE;
}
@@ -1983,7 +1853,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
if (node_args) {
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
- struct rb_args_info *args = &RNODE_ARGS(node_args)->nd_ainfo;
+ struct rb_args_info *args = node_args->nd_ainfo;
ID rest_id = 0;
int last_comma = 0;
ID block_id = 0;
@@ -2004,14 +1874,14 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
block_id = args->block_arg;
if (args->opt_args) {
- const rb_node_opt_arg_t *node = args->opt_args;
+ const NODE *node = args->opt_args;
LABEL *label;
VALUE labels = rb_ary_hidden_new(1);
VALUE *opt_table;
int i = 0, j;
while (node) {
- label = NEW_LABEL(nd_line(RNODE(node)));
+ label = NEW_LABEL(nd_line(node));
rb_ary_push(labels, (VALUE)label | 1);
ADD_LABEL(optargs, label);
NO_CHECK(COMPILE_POPPED(optargs, "optarg", node->nd_body));
@@ -2026,7 +1896,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
opt_table = ALLOC_N(VALUE, i+1);
- MEMCPY(opt_table, RARRAY_CONST_PTR(labels), VALUE, i+1);
+ MEMCPY(opt_table, RARRAY_CONST_PTR_TRANSIENT(labels), VALUE, i+1);
for (j = 0; j < i+1; j++) {
opt_table[j] &= ~1;
}
@@ -2512,12 +2382,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
generated_iseq = ALLOC_N(VALUE, code_index);
insns_info = ALLOC_N(struct iseq_insn_info_entry, insn_num);
positions = ALLOC_N(unsigned int, insn_num);
- if (ISEQ_IS_SIZE(body)) {
- body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(body));
- }
- else {
- body->is_entries = NULL;
- }
+ body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(body));
body->call_data = ZALLOC_N(struct rb_call_data, body->ci_size);
ISEQ_COMPILE_DATA(iseq)->ci_index = 0;
@@ -2656,8 +2521,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
case TS_CALLDATA:
{
const struct rb_callinfo *source_ci = (const struct rb_callinfo *)operands[j];
- assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size);
struct rb_call_data *cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++];
+ assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size);
cd->ci = source_ci;
cd->cc = vm_cc_empty();
generated_iseq[code_index + 1 + j] = (VALUE)cd;
@@ -2799,14 +2664,14 @@ iseq_set_exception_table(rb_iseq_t *iseq)
VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
if (NIL_P(catch_table_ary)) return COMPILE_OK;
tlen = (int)RARRAY_LEN(catch_table_ary);
- tptr = RARRAY_CONST_PTR(catch_table_ary);
+ tptr = RARRAY_CONST_PTR_TRANSIENT(catch_table_ary);
if (tlen > 0) {
struct iseq_catch_table *table = xmalloc(iseq_catch_table_bytes(tlen));
table->size = tlen;
for (i = 0; i < table->size; i++) {
- ptr = RARRAY_CONST_PTR(tptr[i]);
+ ptr = RARRAY_CONST_PTR_TRANSIENT(tptr[i]);
entry = UNALIGNED_MEMBER_PTR(table, entries[i]);
entry->type = (enum rb_catch_type)(ptr[0] & 0xffff);
entry->start = label_get_position((LABEL *)(ptr[1] & ~1));
@@ -2975,7 +2840,6 @@ remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
break;
}
else if ((lab = find_destination((INSN *)i)) != 0) {
- if (lab->unremovable) break;
unref_counts[lab->label_no]++;
}
}
@@ -2992,8 +2856,7 @@ remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
/* do nothing */
}
else if (IS_ADJUST(i)) {
- LABEL *dest = ((ADJUST *)i)->label;
- if (dest && dest->unremovable) return 0;
+ return 0;
}
end = i;
} while ((i = i->next) != 0);
@@ -3487,7 +3350,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
previ == BIN(getlocal) ||
previ == BIN(getblockparam) ||
previ == BIN(getblockparamproxy) ||
- previ == BIN(getinstancevariable) ||
+ /* getinstancevariable may issue a warning */
previ == BIN(duparray)) {
/* just push operand or static value and pop soon, no
* side effects */
@@ -3814,10 +3677,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
if (IS_TRACE(iobj->link.next)) {
if (IS_NEXT_INSN_ID(iobj->link.next, leave)) {
iobj->insn_id = BIN(opt_invokebuiltin_delegate_leave);
- const struct rb_builtin_function *bf = (const struct rb_builtin_function *)iobj->operands[0];
- if (iobj == (INSN *)list && bf->argc == 0 && (iseq->body->builtin_attrs & BUILTIN_ATTR_LEAF)) {
- iseq->body->builtin_attrs |= BUILTIN_ATTR_SINGLE_NOARG_INLINE;
- }
}
}
}
@@ -3835,166 +3694,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
}
- if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
- LINK_ELEMENT *niobj = &iobj->link;
-
- /*
- * Eliminate array allocation for f(1, *a)
- *
- * splatarray true
- * send ARGS_SPLAT and not KW_SPLAT|ARGS_BLOCKARG
- * =>
- * splatarray false
- * send
- */
- if (IS_NEXT_INSN_ID(niobj, send)) {
- niobj = niobj->next;
- unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
- if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
- } else if (IS_NEXT_INSN_ID(niobj, getlocal) || IS_NEXT_INSN_ID(niobj, getinstancevariable)) {
- niobj = niobj->next;
-
- if (IS_NEXT_INSN_ID(niobj, send)) {
- niobj = niobj->next;
- unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
-
- if ((flag & VM_CALL_ARGS_SPLAT)) {
- /*
- * Eliminate array allocation for f(1, *a, &lvar) and f(1, *a, &@iv)
- *
- * splatarray true
- * getlocal / getinstancevariable
- * send ARGS_SPLAT|ARGS_BLOCKARG and not KW_SPLAT
- * =>
- * splatarray false
- * getlocal / getinstancevariable
- * send
- */
- if ((flag & VM_CALL_ARGS_BLOCKARG) && !(flag & VM_CALL_KW_SPLAT)) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
-
- /*
- * Eliminate array allocation for f(*a, **lvar) and f(*a, **@iv)
- *
- * splatarray true
- * getlocal / getinstancevariable
- * send ARGS_SPLAT|KW_SPLAT and not ARGS_BLOCKARG
- * =>
- * splatarray false
- * getlocal / getinstancevariable
- * send
- */
- else if (!(flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT)) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
- }
- }
- else if (IS_NEXT_INSN_ID(niobj, getlocal) || IS_NEXT_INSN_ID(niobj, getinstancevariable) ||
- IS_NEXT_INSN_ID(niobj, getblockparamproxy)) {
- niobj = niobj->next;
-
- /*
- * Eliminate array allocation for f(*a, **lvar, &lvar) and f(*a, **@iv, &@iv)
- *
- * splatarray true
- * getlocal / getinstancevariable
- * getlocal / getinstancevariable / getblockparamproxy
- * send ARGS_SPLAT|KW_SPLAT|ARGS_BLOCKARG
- * =>
- * splatarray false
- * getlocal / getinstancevariable
- * getlocal / getinstancevariable / getblockparamproxy
- * send
- */
- if (IS_NEXT_INSN_ID(niobj, send)) {
- niobj = niobj->next;
- unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
-
- if ((flag & VM_CALL_ARGS_SPLAT) && (flag & VM_CALL_KW_SPLAT) && (flag & VM_CALL_ARGS_BLOCKARG)) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
- }
- }
- }
- else if (IS_NEXT_INSN_ID(niobj, getblockparamproxy)) {
- niobj = niobj->next;
-
- if (IS_NEXT_INSN_ID(niobj, send)) {
- niobj = niobj->next;
- unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
-
- /*
- * Eliminate array allocation for f(1, *a, &arg)
- *
- * splatarray true
- * getblockparamproxy
- * send ARGS_SPLAT|ARGS_BLOCKARG and not KW_SPLAT
- * =>
- * splatarray false
- * getblockparamproxy
- * send
- */
- if ((flag & VM_CALL_ARGS_BLOCKARG) & (flag & VM_CALL_ARGS_SPLAT) && !(flag & VM_CALL_KW_SPLAT)) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
- }
- }
- else if (IS_NEXT_INSN_ID(niobj, duphash)) {
- niobj = niobj->next;
-
- /*
- * Eliminate array allocation for f(*a, kw: 1)
- *
- * splatarray true
- * duphash
- * send ARGS_SPLAT|KW_SPLAT|KW_SPLAT_MUT and not ARGS_BLOCKARG
- * =>
- * splatarray false
- * duphash
- * send
- */
- if (IS_NEXT_INSN_ID(niobj, send)) {
- niobj = niobj->next;
- unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
-
- if ((flag & VM_CALL_ARGS_SPLAT) && (flag & VM_CALL_KW_SPLAT) &&
- (flag & VM_CALL_KW_SPLAT_MUT) && !(flag & VM_CALL_ARGS_BLOCKARG)) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
- }
- else if (IS_NEXT_INSN_ID(niobj, getlocal) || IS_NEXT_INSN_ID(niobj, getinstancevariable) ||
- IS_NEXT_INSN_ID(niobj, getblockparamproxy)) {
- niobj = niobj->next;
-
- /*
- * Eliminate array allocation for f(*a, kw: 1, &lvar) and f(*a, kw: 1, &@iv)
- *
- * splatarray true
- * duphash
- * getlocal / getinstancevariable / getblockparamproxy
- * send ARGS_SPLAT|KW_SPLAT|KW_SPLAT_MUT|ARGS_BLOCKARG
- * =>
- * splatarray false
- * duphash
- * getlocal / getinstancevariable / getblockparamproxy
- * send
- */
- if (IS_NEXT_INSN_ID(niobj, send)) {
- niobj = niobj->next;
- unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
-
- if ((flag & VM_CALL_ARGS_SPLAT) && (flag & VM_CALL_KW_SPLAT) &&
- (flag & VM_CALL_KW_SPLAT_MUT) && (flag & VM_CALL_ARGS_BLOCKARG)) {
- OPERAND_AT(iobj, 0) = Qfalse;
- }
- }
- }
- }
- }
-
return COMPILE_OK;
}
@@ -4030,18 +3729,13 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
if ((vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) && vm_ci_argc(ci) == 0) {
switch (vm_ci_mid(ci)) {
case idMax:
+ iobj->insn_id = BIN(opt_newarray_max);
+ ELEM_REMOVE(&niobj->link);
+ return COMPILE_OK;
case idMin:
- case idHash:
- {
- VALUE num = iobj->operands[0];
- iobj->insn_id = BIN(opt_newarray_send);
- iobj->operands = compile_data_calloc2(iseq, insn_len(iobj->insn_id) - 1, sizeof(VALUE));
- iobj->operands[0] = num;
- iobj->operands[1] = rb_id2sym(vm_ci_mid(ci));
- iobj->operand_size = insn_len(iobj->insn_id) - 1;
- ELEM_REMOVE(&niobj->link);
- return COMPILE_OK;
- }
+ iobj->insn_id = BIN(opt_newarray_min);
+ ELEM_REMOVE(&niobj->link);
+ return COMPILE_OK;
}
}
}
@@ -4135,7 +3829,7 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
int do_block_optimization = 0;
- if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_BLOCK && !ISEQ_COMPILE_DATA(iseq)->catch_except_p) {
+ if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_BLOCK && !ISEQ_BODY(iseq)->catch_except_p) {
do_block_optimization = 1;
}
@@ -4273,6 +3967,167 @@ iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
return COMPILE_OK;
}
+#if OPT_STACK_CACHING
+
+#define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)]
+#define SC_NEXT(insn) sc_insn_next[(insn)]
+
+#include "opt_sc.inc"
+
+static int
+insn_set_sc_state(rb_iseq_t *iseq, const LINK_ELEMENT *anchor, INSN *iobj, int state)
+{
+ int nstate;
+ int insn_id;
+
+ insn_id = iobj->insn_id;
+ iobj->insn_id = SC_INSN(insn_id, state);
+ nstate = SC_NEXT(iobj->insn_id);
+
+ if (insn_id == BIN(jump) ||
+ insn_id == BIN(branchif) || insn_id == BIN(branchunless)) {
+ LABEL *lobj = (LABEL *)OPERAND_AT(iobj, 0);
+
+ if (lobj->sc_state != 0) {
+ if (lobj->sc_state != nstate) {
+ BADINSN_DUMP(anchor, iobj, lobj);
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
+ "insn_set_sc_state error: %d at "LABEL_FORMAT
+ ", %d expected\n",
+ lobj->sc_state, lobj->label_no, nstate);
+ return COMPILE_NG;
+ }
+ }
+ else {
+ lobj->sc_state = nstate;
+ }
+ if (insn_id == BIN(jump)) {
+ nstate = SCS_XX;
+ }
+ }
+ else if (insn_id == BIN(leave)) {
+ nstate = SCS_XX;
+ }
+
+ return nstate;
+}
+
+static int
+label_set_sc_state(LABEL *lobj, int state)
+{
+ if (lobj->sc_state != 0) {
+ if (lobj->sc_state != state) {
+ state = lobj->sc_state;
+ }
+ }
+ else {
+ lobj->sc_state = state;
+ }
+
+ return state;
+}
+
+
+#endif
+
+static int
+iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+#if OPT_STACK_CACHING
+ LINK_ELEMENT *list;
+ int state, insn_id;
+
+ /* initialize */
+ state = SCS_XX;
+ list = FIRST_ELEMENT(anchor);
+ /* dump_disasm_list(list); */
+
+ /* for each list element */
+ while (list) {
+ redo_point:
+ switch (list->type) {
+ case ISEQ_ELEMENT_INSN:
+ {
+ INSN *iobj = (INSN *)list;
+ insn_id = iobj->insn_id;
+
+ /* dump_disasm_list(list); */
+
+ switch (insn_id) {
+ case BIN(nop):
+ {
+ /* exception merge point */
+ if (state != SCS_AX) {
+ NODE dummy_line_node = generate_dummy_line_node(0, -1);
+ INSN *rpobj =
+ new_insn_body(iseq, &dummy_line_node, BIN(reput), 0);
+
+ /* replace this insn */
+ ELEM_REPLACE(list, (LINK_ELEMENT *)rpobj);
+ list = (LINK_ELEMENT *)rpobj;
+ goto redo_point;
+ }
+ break;
+ }
+ case BIN(swap):
+ {
+ if (state == SCS_AB || state == SCS_BA) {
+ state = (state == SCS_AB ? SCS_BA : SCS_AB);
+
+ ELEM_REMOVE(list);
+ list = list->next;
+ goto redo_point;
+ }
+ break;
+ }
+ case BIN(pop):
+ {
+ switch (state) {
+ case SCS_AX:
+ case SCS_BX:
+ state = SCS_XX;
+ break;
+ case SCS_AB:
+ state = SCS_AX;
+ break;
+ case SCS_BA:
+ state = SCS_BX;
+ break;
+ case SCS_XX:
+ goto normal_insn;
+ default:
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
+ "unreachable");
+ return COMPILE_NG;
+ }
+ /* remove useless pop */
+ ELEM_REMOVE(list);
+ list = list->next;
+ goto redo_point;
+ }
+ default:;
+ /* none */
+ } /* end of switch */
+ normal_insn:
+ state = insn_set_sc_state(iseq, anchor, iobj, state);
+ break;
+ }
+ case ISEQ_ELEMENT_LABEL:
+ {
+ LABEL *lobj;
+ lobj = (LABEL *)list;
+
+ state = label_set_sc_state(lobj, state);
+ }
+ default:
+ break;
+ }
+ list = list->next;
+ }
+#endif
+ return COMPILE_OK;
+}
+
static int
all_string_result_p(const NODE *node)
{
@@ -4281,16 +4136,16 @@ all_string_result_p(const NODE *node)
case NODE_STR: case NODE_DSTR:
return TRUE;
case NODE_IF: case NODE_UNLESS:
- if (!RNODE_IF(node)->nd_body || !RNODE_IF(node)->nd_else) return FALSE;
- if (all_string_result_p(RNODE_IF(node)->nd_body))
- return all_string_result_p(RNODE_IF(node)->nd_else);
+ if (!node->nd_body || !node->nd_else) return FALSE;
+ if (all_string_result_p(node->nd_body))
+ return all_string_result_p(node->nd_else);
return FALSE;
case NODE_AND: case NODE_OR:
- if (!RNODE_AND(node)->nd_2nd)
- return all_string_result_p(RNODE_AND(node)->nd_1st);
- if (!all_string_result_p(RNODE_AND(node)->nd_1st))
+ if (!node->nd_2nd)
+ return all_string_result_p(node->nd_1st);
+ if (!all_string_result_p(node->nd_1st))
return FALSE;
- return all_string_result_p(RNODE_AND(node)->nd_2nd);
+ return all_string_result_p(node->nd_2nd);
default:
return FALSE;
}
@@ -4299,8 +4154,8 @@ all_string_result_p(const NODE *node)
static int
compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int *cntp)
{
- const struct RNode_LIST *list = RNODE_DSTR(node)->nd_next;
- VALUE lit = RNODE_DSTR(node)->nd_lit;
+ const NODE *list = node->nd_next;
+ VALUE lit = node->nd_lit;
LINK_ELEMENT *first_lit = 0;
int cnt = 0;
@@ -4321,7 +4176,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cons
while (list) {
const NODE *const head = list->nd_head;
if (nd_type_p(head, NODE_STR)) {
- lit = rb_fstring(RNODE_STR(head)->nd_lit);
+ lit = rb_fstring(head->nd_lit);
ADD_INSN1(ret, head, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
lit = Qnil;
@@ -4330,7 +4185,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cons
CHECK(COMPILE(ret, "each string", head));
}
cnt++;
- list = (struct RNode_LIST *)list->nd_next;
+ list = list->nd_next;
}
if (NIL_P(lit) && first_lit) {
ELEM_REMOVE(first_lit);
@@ -4345,12 +4200,12 @@ static int
compile_block(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped)
{
while (node && nd_type_p(node, NODE_BLOCK)) {
- CHECK(COMPILE_(ret, "BLOCK body", RNODE_BLOCK(node)->nd_head,
- (RNODE_BLOCK(node)->nd_next ? 1 : popped)));
- node = RNODE_BLOCK(node)->nd_next;
+ CHECK(COMPILE_(ret, "BLOCK body", node->nd_head,
+ (node->nd_next ? 1 : popped)));
+ node = node->nd_next;
}
if (node) {
- CHECK(COMPILE_(ret, "BLOCK next", RNODE_BLOCK(node)->nd_next, popped));
+ CHECK(COMPILE_(ret, "BLOCK next", node->nd_next, popped));
}
return COMPILE_OK;
}
@@ -4359,8 +4214,8 @@ static int
compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
int cnt;
- if (!RNODE_DSTR(node)->nd_next) {
- VALUE lit = rb_fstring(RNODE_DSTR(node)->nd_lit);
+ if (!node->nd_next) {
+ VALUE lit = rb_fstring(node->nd_lit);
ADD_INSN1(ret, node, putstring, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
@@ -4372,28 +4227,11 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
}
static int
-compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
int cnt;
-
- if (!RNODE_DREGX(node)->nd_next) {
- VALUE match = RNODE_DREGX(node)->nd_lit;
- if (RB_TYPE_P(match, T_REGEXP)) {
- if (!popped) {
- ADD_INSN1(ret, node, putobject, match);
- RB_OBJ_WRITTEN(iseq, Qundef, match);
- }
- return COMPILE_OK;
- }
- }
-
CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
- ADD_INSN2(ret, node, toregexp, INT2FIX(RNODE_DREGX(node)->nd_cflag), INT2FIX(cnt));
-
- if (popped) {
- ADD_INSN(ret, node, pop);
- }
-
+ ADD_INSN2(ret, node, toregexp, INT2FIX(node->nd_cflag), INT2FIX(cnt));
return COMPILE_OK;
}
@@ -4411,7 +4249,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod
ADD_INSNL(ret, node, branchif, lend);
/* *flip == 0 */
- CHECK(COMPILE(ret, "flip2 beg", RNODE_FLIP2(node)->nd_beg));
+ CHECK(COMPILE(ret, "flip2 beg", node->nd_beg));
ADD_INSNL(ret, node, branchunless, else_label);
ADD_INSN1(ret, node, putobject, Qtrue);
ADD_INSN1(ret, node, setspecial, key);
@@ -4421,7 +4259,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod
/* *flip == 1 */
ADD_LABEL(ret, lend);
- CHECK(COMPILE(ret, "flip2 end", RNODE_FLIP2(node)->nd_end));
+ CHECK(COMPILE(ret, "flip2 end", node->nd_end));
ADD_INSNL(ret, node, branchunless, then_label);
ADD_INSN1(ret, node, putobject, Qfalse);
ADD_INSN1(ret, node, setspecial, key);
@@ -4431,62 +4269,37 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod
}
static int
-compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
- LABEL *then_label, LABEL *else_label);
-
-#define COMPILE_SINGLE 2
-static int
-compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
- LABEL *then_label, LABEL *else_label)
-{
- DECL_ANCHOR(seq);
- INIT_ANCHOR(seq);
- LABEL *label = NEW_LABEL(nd_line(cond));
- if (!then_label) then_label = label;
- else if (!else_label) else_label = label;
-
- CHECK(compile_branch_condition(iseq, seq, cond, then_label, else_label));
-
- if (LIST_INSN_SIZE_ONE(seq)) {
- INSN *insn = (INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(seq));
- if (insn->insn_id == BIN(jump) && (LABEL *)(insn->operands[0]) == label)
- return COMPILE_OK;
- }
- if (!label->refcnt) {
- return COMPILE_SINGLE;
- }
- ADD_LABEL(seq, label);
- ADD_SEQ(ret, seq);
- return COMPILE_OK;
-}
-
-static int
-compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
+compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
LABEL *then_label, LABEL *else_label)
{
- int ok;
- DECL_ANCHOR(ignore);
-
again:
switch (nd_type(cond)) {
case NODE_AND:
- CHECK(ok = compile_logical(iseq, ret, RNODE_AND(cond)->nd_1st, NULL, else_label));
- cond = RNODE_AND(cond)->nd_2nd;
- if (ok == COMPILE_SINGLE) {
- INIT_ANCHOR(ignore);
- ret = ignore;
- then_label = NEW_LABEL(nd_line(cond));
- }
- goto again;
+ {
+ LABEL *label = NEW_LABEL(nd_line(cond));
+ CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, label,
+ else_label));
+ if (!label->refcnt) {
+ ADD_INSN(ret, cond, putnil);
+ break;
+ }
+ ADD_LABEL(ret, label);
+ cond = cond->nd_2nd;
+ goto again;
+ }
case NODE_OR:
- CHECK(ok = compile_logical(iseq, ret, RNODE_OR(cond)->nd_1st, then_label, NULL));
- cond = RNODE_OR(cond)->nd_2nd;
- if (ok == COMPILE_SINGLE) {
- INIT_ANCHOR(ignore);
- ret = ignore;
- else_label = NEW_LABEL(nd_line(cond));
- }
- goto again;
+ {
+ LABEL *label = NEW_LABEL(nd_line(cond));
+ CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, then_label,
+ label));
+ if (!label->refcnt) {
+ ADD_INSN(ret, cond, putnil);
+ break;
+ }
+ ADD_LABEL(ret, label);
+ cond = cond->nd_2nd;
+ goto again;
+ }
case NODE_LIT: /* NODE_LIT is always true */
case NODE_TRUE:
case NODE_STR:
@@ -4517,28 +4330,7 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
CHECK(compile_defined_expr(iseq, ret, cond, Qfalse));
break;
default:
- {
- DECL_ANCHOR(cond_seq);
- INIT_ANCHOR(cond_seq);
-
- CHECK(COMPILE(cond_seq, "branch condition", cond));
-
- if (LIST_INSN_SIZE_ONE(cond_seq)) {
- INSN *insn = (INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(cond_seq));
- if (insn->insn_id == BIN(putobject)) {
- if (RTEST(insn->operands[0])) {
- ADD_INSNL(ret, cond, jump, then_label);
- // maybe unreachable
- return COMPILE_OK;
- }
- else {
- ADD_INSNL(ret, cond, jump, else_label);
- return COMPILE_OK;
- }
- }
- }
- ADD_SEQ(ret, cond_seq);
- }
+ CHECK(COMPILE(ret, "branch condition", cond));
break;
}
@@ -4552,35 +4344,33 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
static int
keyword_node_p(const NODE *const node)
{
- return nd_type_p(node, NODE_HASH) && (RNODE_HASH(node)->nd_brace & HASH_BRACE) != HASH_BRACE;
+ return nd_type_p(node, NODE_HASH) && (node->nd_brace & HASH_BRACE) != HASH_BRACE;
}
static int
compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
- const NODE *const root_node,
- struct rb_callinfo_kwarg **const kw_arg_ptr,
- unsigned int *flag)
+ const NODE *const root_node,
+ struct rb_callinfo_kwarg **const kw_arg_ptr,
+ unsigned int *flag)
{
- RUBY_ASSERT(nd_type_p(root_node, NODE_HASH));
- RUBY_ASSERT(kw_arg_ptr != NULL);
- RUBY_ASSERT(flag != NULL);
+ if (kw_arg_ptr == NULL) return FALSE;
- if (RNODE_HASH(root_node)->nd_head && nd_type_p(RNODE_HASH(root_node)->nd_head, NODE_LIST)) {
- const NODE *node = RNODE_HASH(root_node)->nd_head;
+ if (root_node->nd_head && nd_type_p(root_node->nd_head, NODE_LIST)) {
+ const NODE *node = root_node->nd_head;
int seen_nodes = 0;
while (node) {
- const NODE *key_node = RNODE_LIST(node)->nd_head;
+ const NODE *key_node = node->nd_head;
seen_nodes++;
assert(nd_type_p(node, NODE_LIST));
- if (key_node && nd_type_p(key_node, NODE_LIT) && SYMBOL_P(RNODE_LIT(key_node)->nd_lit)) {
+ if (key_node && nd_type_p(key_node, NODE_LIT) && SYMBOL_P(key_node->nd_lit)) {
/* can be keywords */
}
else {
if (flag) {
*flag |= VM_CALL_KW_SPLAT;
- if (seen_nodes > 1 || RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) {
+ if (seen_nodes > 1 || node->nd_next->nd_next) {
/* A new hash will be created for the keyword arguments
* in this case, so mark the method as passing mutable
* keyword splat.
@@ -4590,27 +4380,26 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
}
return FALSE;
}
- node = RNODE_LIST(node)->nd_next; /* skip value node */
- node = RNODE_LIST(node)->nd_next;
+ node = node->nd_next; /* skip value node */
+ node = node->nd_next;
}
/* may be keywords */
- node = RNODE_HASH(root_node)->nd_head;
+ node = root_node->nd_head;
{
- int len = (int)RNODE_LIST(node)->as.nd_alen / 2;
+ int len = (int)node->nd_alen / 2;
struct rb_callinfo_kwarg *kw_arg =
rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
VALUE *keywords = kw_arg->keywords;
int i = 0;
- kw_arg->references = 0;
kw_arg->keyword_len = len;
*kw_arg_ptr = kw_arg;
- for (i=0; node != NULL; i++, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) {
- const NODE *key_node = RNODE_LIST(node)->nd_head;
- const NODE *val_node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head;
- keywords[i] = RNODE_LIT(key_node)->nd_lit;
+ for (i=0; node != NULL; i++, node = node->nd_next->nd_next) {
+ const NODE *key_node = node->nd_head;
+ const NODE *val_node = node->nd_next->nd_head;
+ keywords[i] = key_node->nd_lit;
NO_CHECK(COMPILE(ret, "keyword values", val_node));
}
assert(i == len);
@@ -4621,21 +4410,26 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
}
static int
-compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, NODE **kwnode_ptr)
+compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node,
+ struct rb_callinfo_kwarg **keywords_ptr, unsigned int *flag)
{
int len = 0;
- for (; node; len++, node = RNODE_LIST(node)->nd_next) {
+ for (; node; len++, node = node->nd_next) {
if (CPDEBUG > 0) {
EXPECT_NODE("compile_args", node, NODE_LIST, -1);
}
- if (RNODE_LIST(node)->nd_next == NULL && keyword_node_p(RNODE_LIST(node)->nd_head)) { /* last node is kwnode */
- *kwnode_ptr = RNODE_LIST(node)->nd_head;
+ if (node->nd_next == NULL && keyword_node_p(node->nd_head)) { /* last node */
+ if (compile_keyword_arg(iseq, ret, node->nd_head, keywords_ptr, flag)) {
+ len--;
+ }
+ else {
+ compile_hash(iseq, ret, node->nd_head, TRUE, FALSE);
+ }
}
else {
- RUBY_ASSERT(!keyword_node_p(RNODE_LIST(node)->nd_head));
- NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, FALSE));
+ NO_CHECK(COMPILE_(ret, "array element", node->nd_head, FALSE));
}
}
@@ -4672,15 +4466,15 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq)
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
VALUE lit;
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node)));
- lit = rb_str_dup(RNODE_STR(node)->nd_lit);
+ lit = rb_str_dup(node->nd_lit);
rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
return rb_str_freeze(lit);
}
else {
- return rb_fstring(RNODE_STR(node)->nd_lit);
+ return rb_fstring(node->nd_lit);
}
default:
- return RNODE_LIT(node)->nd_lit;
+ return node->nd_lit;
}
}
@@ -4699,8 +4493,8 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop
EXPECT_NODE("compile_array", node, NODE_LIST, -1);
if (popped) {
- for (; node; node = RNODE_LIST(node)->nd_next) {
- NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, popped));
+ for (; node; node = node->nd_next) {
+ NO_CHECK(COMPILE_(ret, "array element", node->nd_head, popped));
}
return 1;
}
@@ -4759,10 +4553,10 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop
int count = 1;
/* pre-allocation check (this branch can be omittable) */
- if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq)) {
+ if (static_literal_node_p(node->nd_head, iseq)) {
/* count the elements that are optimizable */
- const NODE *node_tmp = RNODE_LIST(node)->nd_next;
- for (; node_tmp && static_literal_node_p(RNODE_LIST(node_tmp)->nd_head, iseq); node_tmp = RNODE_LIST(node_tmp)->nd_next)
+ const NODE *node_tmp = node->nd_next;
+ for (; node_tmp && static_literal_node_p(node_tmp->nd_head, iseq); node_tmp = node_tmp->nd_next)
count++;
if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) {
@@ -4770,8 +4564,8 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop
VALUE ary = rb_ary_hidden_new(count);
/* Create a hidden array */
- for (; count; count--, node = RNODE_LIST(node)->nd_next)
- rb_ary_push(ary, static_literal_value(RNODE_LIST(node)->nd_head, iseq));
+ for (; count; count--, node = node->nd_next)
+ rb_ary_push(ary, static_literal_value(node->nd_head, iseq));
OBJ_FREEZE(ary);
/* Emit optimized code */
@@ -4789,15 +4583,15 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop
}
/* Base case: Compile "count" elements */
- for (; count; count--, node = RNODE_LIST(node)->nd_next) {
+ for (; count; count--, node = node->nd_next) {
if (CPDEBUG > 0) {
EXPECT_NODE("compile_array", node, NODE_LIST, -1);
}
- NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, 0));
+ NO_CHECK(COMPILE_(ret, "array element", node->nd_head, 0));
stack_len++;
- if (!RNODE_LIST(node)->nd_next && keyword_node_p(RNODE_LIST(node)->nd_head)) {
+ if (!node->nd_next && keyword_node_p(node->nd_head)) {
/* Reached the end, and the last element is a keyword */
FLUSH_CHUNK(newarraykwsplat);
return 1;
@@ -4840,7 +4634,7 @@ compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node)
static inline int
static_literal_node_pair_p(const NODE *node, const rb_iseq_t *iseq)
{
- return RNODE_LIST(node)->nd_head && static_literal_node_p(RNODE_LIST(node)->nd_head, iseq) && static_literal_node_p(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq);
+ return node->nd_head && static_literal_node_p(node->nd_head, iseq) && static_literal_node_p(node->nd_next->nd_head, iseq);
}
static int
@@ -4848,7 +4642,7 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
{
const NODE *line_node = node;
- node = RNODE_HASH(node)->nd_head;
+ node = node->nd_head;
if (!node || nd_type_p(node, NODE_ZLIST)) {
if (!popped) {
@@ -4860,8 +4654,8 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
EXPECT_NODE("compile_hash", node, NODE_LIST, -1);
if (popped) {
- for (; node; node = RNODE_LIST(node)->nd_next) {
- NO_CHECK(COMPILE_(ret, "hash element", RNODE_LIST(node)->nd_head, popped));
+ for (; node; node = node->nd_next) {
+ NO_CHECK(COMPILE_(ret, "hash element", node->nd_head, popped));
}
return 1;
}
@@ -4914,8 +4708,8 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
/* pre-allocation check (this branch can be omittable) */
if (static_literal_node_pair_p(node, iseq)) {
/* count the elements that are optimizable */
- const NODE *node_tmp = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next;
- for (; node_tmp && static_literal_node_pair_p(node_tmp, iseq); node_tmp = RNODE_LIST(RNODE_LIST(node_tmp)->nd_next)->nd_next)
+ const NODE *node_tmp = node->nd_next->nd_next;
+ for (; node_tmp && static_literal_node_pair_p(node_tmp, iseq); node_tmp = node_tmp->nd_next->nd_next)
count++;
if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_hash_len) {
@@ -4923,14 +4717,14 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
VALUE ary = rb_ary_hidden_new(count);
/* Create a hidden hash */
- for (; count; count--, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) {
+ for (; count; count--, node = node->nd_next->nd_next) {
VALUE elem[2];
- elem[0] = static_literal_value(RNODE_LIST(node)->nd_head, iseq);
- elem[1] = static_literal_value(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq);
+ elem[0] = static_literal_value(node->nd_head, iseq);
+ elem[1] = static_literal_value(node->nd_next->nd_head, iseq);
rb_ary_cat(ary, elem, 2);
}
VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
- rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary), hash);
+ rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash);
hash = rb_obj_hide(hash);
OBJ_FREEZE(hash);
@@ -4953,16 +4747,16 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
}
/* Base case: Compile "count" elements */
- for (; count; count--, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) {
+ for (; count; count--, node = node->nd_next->nd_next) {
if (CPDEBUG > 0) {
EXPECT_NODE("compile_hash", node, NODE_LIST, -1);
}
- if (RNODE_LIST(node)->nd_head) {
+ if (node->nd_head) {
/* Normal key-value pair */
- NO_CHECK(COMPILE_(anchor, "hash key element", RNODE_LIST(node)->nd_head, 0));
- NO_CHECK(COMPILE_(anchor, "hash value element", RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, 0));
+ NO_CHECK(COMPILE_(anchor, "hash key element", node->nd_head, 0));
+ NO_CHECK(COMPILE_(anchor, "hash value element", node->nd_next->nd_head, 0));
stack_len += 2;
/* If there are many pushed elements, flush them to avoid stack overflow */
@@ -4972,10 +4766,10 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
/* kwsplat case: foo(..., **kw, ...) */
FLUSH_CHUNK();
- const NODE *kw = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head;
- int empty_kw = nd_type_p(kw, NODE_LIT) && RB_TYPE_P(RNODE_LIT(kw)->nd_lit, T_HASH); /* foo( ..., **{}, ...) */
+ const NODE *kw = node->nd_next->nd_head;
+ int empty_kw = nd_type_p(kw, NODE_LIT) && RB_TYPE_P(kw->nd_lit, T_HASH); /* foo( ..., **{}, ...) */
int first_kw = first_chunk && stack_len == 0; /* foo(1,2,3, **kw, ...) */
- int last_kw = !RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next; /* foo( ..., **kw) */
+ int last_kw = !node->nd_next->nd_next; /* foo( ..., **kw) */
int only_kw = last_kw && first_kw; /* foo(1,2,3, **kw) */
if (empty_kw) {
@@ -5038,7 +4832,7 @@ rb_node_case_when_optimizable_literal(const NODE *const node)
{
switch (nd_type(node)) {
case NODE_LIT: {
- VALUE v = RNODE_LIT(node)->nd_lit;
+ VALUE v = node->nd_lit;
double ival;
if (RB_FLOAT_TYPE_P(v) &&
modf(RFLOAT_VALUE(v), &ival) == 0.0) {
@@ -5059,7 +4853,7 @@ rb_node_case_when_optimizable_literal(const NODE *const node)
case NODE_FALSE:
return Qfalse;
case NODE_STR:
- return rb_fstring(RNODE_STR(node)->nd_lit);
+ return rb_fstring(node->nd_lit);
}
return Qundef;
}
@@ -5069,7 +4863,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
LABEL *l1, int only_special_literals, VALUE literals)
{
while (vals) {
- const NODE *val = RNODE_LIST(vals)->nd_head;
+ const NODE *val = vals->nd_head;
VALUE lit = rb_node_case_when_optimizable_literal(val);
if (UNDEF_P(lit)) {
@@ -5080,8 +4874,8 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
}
if (nd_type_p(val, NODE_STR)) {
- debugp_param("nd_lit", RNODE_STR(val)->nd_lit);
- lit = rb_fstring(RNODE_STR(val)->nd_lit);
+ debugp_param("nd_lit", val->nd_lit);
+ lit = rb_fstring(val->nd_lit);
ADD_INSN1(cond_seq, val, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
@@ -5089,11 +4883,11 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
if (!COMPILE(cond_seq, "when cond", val)) return -1;
}
- // Emit pattern === target
+ // Emit patern === target
ADD_INSN1(cond_seq, vals, topn, INT2FIX(1));
ADD_CALL(cond_seq, vals, idEqq, INT2FIX(1));
ADD_INSNL(cond_seq, val, branchif, l1);
- vals = RNODE_LIST(vals)->nd_next;
+ vals = vals->nd_next;
}
return only_special_literals;
}
@@ -5111,19 +4905,19 @@ when_splat_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
break;
case NODE_SPLAT:
ADD_INSN (cond_seq, line_node, dup);
- CHECK(COMPILE(cond_seq, "when splat", RNODE_SPLAT(vals)->nd_head));
+ CHECK(COMPILE(cond_seq, "when splat", vals->nd_head));
ADD_INSN1(cond_seq, line_node, splatarray, Qfalse);
ADD_INSN1(cond_seq, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
ADD_INSNL(cond_seq, line_node, branchif, l1);
break;
case NODE_ARGSCAT:
- CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSCAT(vals)->nd_head, l1, only_special_literals, literals));
- CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSCAT(vals)->nd_body, l1, only_special_literals, literals));
+ CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
+ CHECK(when_splat_vals(iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals));
break;
case NODE_ARGSPUSH:
- CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSPUSH(vals)->nd_head, l1, only_special_literals, literals));
+ CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
ADD_INSN (cond_seq, line_node, dup);
- CHECK(COMPILE(cond_seq, "when argspush body", RNODE_ARGSPUSH(vals)->nd_body));
+ CHECK(COMPILE(cond_seq, "when argspush body", vals->nd_body));
ADD_INSN1(cond_seq, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
ADD_INSNL(cond_seq, line_node, branchif, l1);
break;
@@ -5282,12 +5076,17 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
CHECK(COMPILE_POPPED(pre, "masgn lhs (NODE_ATTRASGN)", node));
+ bool safenav_call = false;
LINK_ELEMENT *insn_element = LAST_ELEMENT(pre);
iobj = (INSN *)get_prev_insn((INSN *)insn_element); /* send insn */
ASSUME(iobj);
- ELEM_REMOVE(LAST_ELEMENT(pre));
- ELEM_REMOVE((LINK_ELEMENT *)iobj);
- pre->last = iobj->link.prev;
+ ELEM_REMOVE(insn_element);
+ if (!IS_INSN_ID(iobj, send)) {
+ safenav_call = true;
+ iobj = (INSN *)get_prev_insn(iobj);
+ ELEM_INSERT_NEXT(&iobj->link, insn_element);
+ }
+ (pre->last = iobj->link.prev)->next = 0;
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(iobj, 0);
int argc = vm_ci_argc(ci) + 1;
@@ -5306,7 +5105,9 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
return COMPILE_NG;
}
- ADD_ELEM(lhs, (LINK_ELEMENT *)iobj);
+ iobj->link.prev = lhs->last;
+ lhs->last->next = &iobj->link;
+ for (lhs->last = &iobj->link; lhs->last->next; lhs->last = lhs->last->next);
if (vm_ci_flag(ci) & VM_CALL_ARGS_SPLAT) {
int argc = vm_ci_argc(ci);
ci = ci_argc_set(iseq, ci, argc - 1);
@@ -5315,9 +5116,11 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
INSERT_BEFORE_INSN1(iobj, line_node, newarray, INT2FIX(1));
INSERT_BEFORE_INSN(iobj, line_node, concatarray);
}
- ADD_INSN(lhs, line_node, pop);
- if (argc != 1) {
+ if (!safenav_call) {
ADD_INSN(lhs, line_node, pop);
+ if (argc != 1) {
+ ADD_INSN(lhs, line_node, pop);
+ }
}
for (int i=0; i < argc; i++) {
ADD_INSN(post, line_node, pop);
@@ -5343,7 +5146,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
break;
}
case NODE_CDECL:
- if (!RNODE_CDECL(node)->nd_vid) {
+ if (!node->nd_vid) {
/* Special handling only needed for expr::C, not for C */
INSN *iobj;
@@ -5381,8 +5184,8 @@ static int
compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *lhsn)
{
if (lhsn) {
- CHECK(compile_massign_opt_lhs(iseq, ret, RNODE_LIST(lhsn)->nd_next));
- CHECK(compile_massign_lhs(iseq, ret, ret, ret, ret, RNODE_LIST(lhsn)->nd_head, NULL, 0));
+ CHECK(compile_massign_opt_lhs(iseq, ret, lhsn->nd_next));
+ CHECK(compile_massign_lhs(iseq, ret, ret, ret, ret, lhsn->nd_head, NULL, 0));
}
return COMPILE_OK;
}
@@ -5412,29 +5215,31 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
}
while (lhsn) {
- const NODE *ln = RNODE_LIST(lhsn)->nd_head;
+ const NODE *ln = lhsn->nd_head;
switch (nd_type(ln)) {
case NODE_LASGN:
+ MEMORY(ln->nd_vid);
+ break;
case NODE_DASGN:
case NODE_IASGN:
case NODE_CVASGN:
- MEMORY(get_nd_vid(ln));
+ MEMORY(ln->nd_vid);
break;
default:
return 0;
}
- lhsn = RNODE_LIST(lhsn)->nd_next;
+ lhsn = lhsn->nd_next;
llen++;
}
while (rhsn) {
if (llen <= rlen) {
- NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", RNODE_LIST(rhsn)->nd_head));
+ NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", rhsn->nd_head));
}
else {
- NO_CHECK(COMPILE(ret, "masgn val", RNODE_LIST(rhsn)->nd_head));
+ NO_CHECK(COMPILE(ret, "masgn val", rhsn->nd_head));
}
- rhsn = RNODE_LIST(rhsn)->nd_next;
+ rhsn = rhsn->nd_next;
rlen++;
}
@@ -5451,31 +5256,32 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
static int
compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs, LINK_ANCHOR *const lhs, LINK_ANCHOR *const post, const NODE *const node, struct masgn_state *state, int popped)
{
- const NODE *rhsn = RNODE_MASGN(node)->nd_value;
- const NODE *splatn = RNODE_MASGN(node)->nd_args;
- const NODE *lhsn = RNODE_MASGN(node)->nd_head;
+ const NODE *rhsn = node->nd_value;
+ const NODE *splatn = node->nd_args;
+ const NODE *lhsn = node->nd_head;
const NODE *lhsn_count = lhsn;
int lhs_splat = (splatn && NODE_NAMED_REST_P(splatn)) ? 1 : 0;
int llen = 0;
int lpos = 0;
+ int expand = 1;
while (lhsn_count) {
llen++;
- lhsn_count = RNODE_LIST(lhsn_count)->nd_next;
+ lhsn_count = lhsn_count->nd_next;
}
while (lhsn) {
- CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, RNODE_LIST(lhsn)->nd_head, state, (llen - lpos) + lhs_splat + state->lhs_level));
+ CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, lhsn->nd_head, state, (llen - lpos) + lhs_splat + state->lhs_level));
lpos++;
- lhsn = RNODE_LIST(lhsn)->nd_next;
+ lhsn = lhsn->nd_next;
}
if (lhs_splat) {
if (nd_type_p(splatn, NODE_POSTARG)) {
/*a, b, *r, p1, p2 */
- const NODE *postn = RNODE_POSTARG(splatn)->nd_2nd;
- const NODE *restn = RNODE_POSTARG(splatn)->nd_1st;
- int plen = (int)RNODE_LIST(postn)->as.nd_alen;
+ const NODE *postn = splatn->nd_2nd;
+ const NODE *restn = splatn->nd_1st;
+ int plen = (int)postn->nd_alen;
int ppos = 0;
int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00);
@@ -5485,9 +5291,9 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs
CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, restn, state, 1 + plen + state->lhs_level));
}
while (postn) {
- CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, RNODE_LIST(postn)->nd_head, state, (plen - ppos) + state->lhs_level));
+ CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, postn->nd_head, state, (plen - ppos) + state->lhs_level));
ppos++;
- postn = RNODE_LIST(postn)->nd_next;
+ postn = postn->nd_next;
}
}
else {
@@ -5496,6 +5302,7 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs
}
}
+
if (!state->nested) {
NO_CHECK(COMPILE(rhs, "normal masgn rhs", rhsn));
}
@@ -5503,14 +5310,16 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs
if (!popped) {
ADD_INSN(rhs, node, dup);
}
- ADD_INSN2(rhs, node, expandarray, INT2FIX(llen), INT2FIX(lhs_splat));
+ if (expand) {
+ ADD_INSN2(rhs, node, expandarray, INT2FIX(llen), INT2FIX(lhs_splat));
+ }
return COMPILE_OK;
}
static int
compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
- if (!popped || RNODE_MASGN(node)->nd_args || !compile_massign_opt(iseq, ret, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head)) {
+ if (!popped || node->nd_args || !compile_massign_opt(iseq, ret, node->nd_value, node->nd_head)) {
struct masgn_state state;
state.lhs_level = popped ? 0 : 1;
state.nested = 0;
@@ -5559,15 +5368,15 @@ collect_const_segments(rb_iseq_t *iseq, const NODE *node)
for (;;) {
switch (nd_type(node)) {
case NODE_CONST:
- rb_ary_unshift(arr, ID2SYM(RNODE_CONST(node)->nd_vid));
+ rb_ary_unshift(arr, ID2SYM(node->nd_vid));
return arr;
case NODE_COLON3:
- rb_ary_unshift(arr, ID2SYM(RNODE_COLON3(node)->nd_mid));
+ rb_ary_unshift(arr, ID2SYM(node->nd_mid));
rb_ary_unshift(arr, ID2SYM(idNULL));
return arr;
case NODE_COLON2:
- rb_ary_unshift(arr, ID2SYM(RNODE_COLON2(node)->nd_mid));
- node = RNODE_COLON2(node)->nd_head;
+ rb_ary_unshift(arr, ID2SYM(node->nd_mid));
+ node = node->nd_head;
break;
default:
return Qfalse;
@@ -5581,22 +5390,22 @@ compile_const_prefix(rb_iseq_t *iseq, const NODE *const node,
{
switch (nd_type(node)) {
case NODE_CONST:
- debugi("compile_const_prefix - colon", RNODE_CONST(node)->nd_vid);
+ debugi("compile_const_prefix - colon", node->nd_vid);
ADD_INSN1(body, node, putobject, Qtrue);
- ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_CONST(node)->nd_vid));
+ ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_vid));
break;
case NODE_COLON3:
- debugi("compile_const_prefix - colon3", RNODE_COLON3(node)->nd_mid);
+ debugi("compile_const_prefix - colon3", node->nd_mid);
ADD_INSN(body, node, pop);
ADD_INSN1(body, node, putobject, rb_cObject);
ADD_INSN1(body, node, putobject, Qtrue);
- ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_COLON3(node)->nd_mid));
+ ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_mid));
break;
case NODE_COLON2:
- CHECK(compile_const_prefix(iseq, RNODE_COLON2(node)->nd_head, pref, body));
- debugi("compile_const_prefix - colon2", RNODE_COLON2(node)->nd_mid);
+ CHECK(compile_const_prefix(iseq, node->nd_head, pref, body));
+ debugi("compile_const_prefix - colon2", node->nd_mid);
ADD_INSN1(body, node, putobject, Qfalse);
- ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_COLON2(node)->nd_mid));
+ ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_mid));
break;
default:
CHECK(COMPILE(pref, "const colon2 prefix", node));
@@ -5613,9 +5422,9 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath)
ADD_INSN1(ret, cpath, putobject, rb_cObject);
return VM_DEFINECLASS_FLAG_SCOPED;
}
- else if (nd_type_p(cpath, NODE_COLON2) && RNODE_COLON2(cpath)->nd_head) {
+ else if (cpath->nd_head) {
/* Bar::Foo */
- NO_CHECK(COMPILE(ret, "nd_else->nd_head", RNODE_COLON2(cpath)->nd_head));
+ NO_CHECK(COMPILE(ret, "nd_else->nd_head", cpath->nd_head));
return VM_DEFINECLASS_FLAG_SCOPED;
}
else {
@@ -5629,9 +5438,9 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath)
static inline int
private_recv_p(const NODE *node)
{
- NODE *recv = get_nd_recv(node);
- if (recv && nd_type_p(recv, NODE_SELF)) {
- return RNODE_SELF(recv)->nd_state != 0;
+ if (nd_type_p(node->nd_recv, NODE_SELF)) {
+ NODE *self = node->nd_recv;
+ return self->nd_state != 0;
}
return 0;
}
@@ -5673,13 +5482,13 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
const NODE *vals = node;
do {
- defined_expr0(iseq, ret, RNODE_LIST(vals)->nd_head, lfinish, Qfalse, false);
+ defined_expr0(iseq, ret, vals->nd_head, lfinish, Qfalse, false);
if (!lfinish[1]) {
lfinish[1] = NEW_LABEL(line);
}
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
- } while ((vals = RNODE_LIST(vals)->nd_next) != NULL);
+ } while ((vals = vals->nd_next) != NULL);
}
/* fall through */
case NODE_STR:
@@ -5699,48 +5508,49 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
#define PUSH_VAL(type) (needstr == Qfalse ? Qtrue : rb_iseq_defined_string(type))
case NODE_IVAR:
- ADD_INSN3(ret, line_node, definedivar,
- ID2SYM(RNODE_IVAR(node)->nd_vid), get_ivar_ic_value(iseq,RNODE_IVAR(node)->nd_vid), PUSH_VAL(DEFINED_IVAR));
+ ADD_INSN(ret, line_node, putnil);
+ ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_IVAR),
+ ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_IVAR));
return;
case NODE_GVAR:
ADD_INSN(ret, line_node, putnil);
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_GVAR),
- ID2SYM(RNODE_GVAR(node)->nd_vid), PUSH_VAL(DEFINED_GVAR));
+ ID2SYM(node->nd_entry), PUSH_VAL(DEFINED_GVAR));
return;
case NODE_CVAR:
ADD_INSN(ret, line_node, putnil);
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CVAR),
- ID2SYM(RNODE_CVAR(node)->nd_vid), PUSH_VAL(DEFINED_CVAR));
+ ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_CVAR));
return;
case NODE_CONST:
ADD_INSN(ret, line_node, putnil);
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CONST),
- ID2SYM(RNODE_CONST(node)->nd_vid), PUSH_VAL(DEFINED_CONST));
+ ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_CONST));
return;
case NODE_COLON2:
if (!lfinish[1]) {
lfinish[1] = NEW_LABEL(line);
}
- defined_expr0(iseq, ret, RNODE_COLON2(node)->nd_head, lfinish, Qfalse, false);
+ defined_expr0(iseq, ret, node->nd_head, lfinish, Qfalse, false);
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
- NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", RNODE_COLON2(node)->nd_head));
+ NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", node->nd_head));
- if (rb_is_const_id(RNODE_COLON2(node)->nd_mid)) {
+ if (rb_is_const_id(node->nd_mid)) {
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CONST_FROM),
- ID2SYM(RNODE_COLON2(node)->nd_mid), PUSH_VAL(DEFINED_CONST));
+ ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_CONST));
}
else {
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD),
- ID2SYM(RNODE_COLON2(node)->nd_mid), PUSH_VAL(DEFINED_METHOD));
+ ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD));
}
return;
case NODE_COLON3:
ADD_INSN1(ret, line_node, putobject, rb_cObject);
ADD_INSN3(ret, line_node, defined,
- INT2FIX(DEFINED_CONST_FROM), ID2SYM(RNODE_COLON3(node)->nd_mid), PUSH_VAL(DEFINED_CONST));
+ INT2FIX(DEFINED_CONST_FROM), ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_CONST));
return;
/* method dispatch */
@@ -5753,7 +5563,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
(type == NODE_CALL || type == NODE_OPCALL ||
(type == NODE_ATTRASGN && !private_recv_p(node)));
- if (get_nd_args(node) || explicit_receiver) {
+ if (node->nd_args || explicit_receiver) {
if (!lfinish[1]) {
lfinish[1] = NEW_LABEL(line);
}
@@ -5761,31 +5571,31 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
lfinish[2] = NEW_LABEL(line);
}
}
- if (get_nd_args(node)) {
- defined_expr0(iseq, ret, get_nd_args(node), lfinish, Qfalse, false);
+ if (node->nd_args) {
+ defined_expr0(iseq, ret, node->nd_args, lfinish, Qfalse, false);
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
}
if (explicit_receiver) {
- defined_expr0(iseq, ret, get_nd_recv(node), lfinish, Qfalse, true);
- switch (nd_type(get_nd_recv(node))) {
+ defined_expr0(iseq, ret, node->nd_recv, lfinish, Qfalse, true);
+ switch (nd_type(node->nd_recv)) {
case NODE_CALL:
case NODE_OPCALL:
case NODE_VCALL:
case NODE_FCALL:
case NODE_ATTRASGN:
ADD_INSNL(ret, line_node, branchunless, lfinish[2]);
- compile_call(iseq, ret, get_nd_recv(node), nd_type(get_nd_recv(node)), line_node, 0, true);
+ compile_call(iseq, ret, node->nd_recv, nd_type(node->nd_recv), line_node, 0, true);
break;
default:
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
- NO_CHECK(COMPILE(ret, "defined/recv", get_nd_recv(node)));
+ NO_CHECK(COMPILE(ret, "defined/recv", node->nd_recv));
break;
}
if (keep_result) {
ADD_INSN(ret, line_node, dup);
}
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD),
- ID2SYM(get_node_call_nd_mid(node)), PUSH_VAL(DEFINED_METHOD));
+ ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD));
}
else {
ADD_INSN(ret, line_node, putself);
@@ -5793,7 +5603,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
ADD_INSN(ret, line_node, dup);
}
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_FUNC),
- ID2SYM(get_node_call_nd_mid(node)), PUSH_VAL(DEFINED_METHOD));
+ ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD));
}
return;
}
@@ -5808,7 +5618,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
case NODE_NTH_REF:
ADD_INSN(ret, line_node, putnil);
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_REF),
- INT2FIX((RNODE_BACK_REF(node)->nd_nth << 1) | (type == NODE_BACK_REF)),
+ INT2FIX((node->nd_nth << 1) | (type == NODE_BACK_REF)),
PUSH_VAL(DEFINED_GVAR));
return;
@@ -5884,7 +5694,7 @@ compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const
{
const int line = nd_line(node);
const NODE *line_node = node;
- if (!RNODE_DEFINED(node)->nd_head) {
+ if (!node->nd_head) {
VALUE str = rb_iseq_defined_string(DEFINED_NIL);
ADD_INSN1(ret, line_node, putobject, str);
}
@@ -5894,7 +5704,7 @@ compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const
lfinish[0] = NEW_LABEL(line);
lfinish[1] = 0;
lfinish[2] = 0;
- defined_expr(iseq, ret, RNODE_DEFINED(node)->nd_head, lfinish, needstr);
+ defined_expr(iseq, ret, node->nd_head, lfinish, needstr);
if (lfinish[1]) {
ELEM_INSERT_NEXT(last, &new_insn_body(iseq, line_node, BIN(putnil), 0)->link);
ADD_INSN(ret, line_node, swap);
@@ -5935,7 +5745,7 @@ make_name_for_block(const rb_iseq_t *orig_iseq)
static void
push_ensure_entry(rb_iseq_t *iseq,
struct iseq_compile_data_ensure_node_stack *enl,
- struct ensure_range *er, const void *const node)
+ struct ensure_range *er, const NODE *const node)
{
enl->ensure_node = node;
enl->prev = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack; /* prev */
@@ -6011,138 +5821,79 @@ add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return)
ADD_SEQ(ret, ensure);
}
-#if RUBY_DEBUG
static int
check_keyword(const NODE *node)
{
/* This check is essentially a code clone of compile_keyword_arg. */
if (nd_type_p(node, NODE_LIST)) {
- while (RNODE_LIST(node)->nd_next) {
- node = RNODE_LIST(node)->nd_next;
+ while (node->nd_next) {
+ node = node->nd_next;
}
- node = RNODE_LIST(node)->nd_head;
+ node = node->nd_head;
}
return keyword_node_p(node);
}
-#endif
-
-static bool
-keyword_node_single_splat_p(NODE *kwnode)
-{
- RUBY_ASSERT(keyword_node_p(kwnode));
- NODE *node = RNODE_HASH(kwnode)->nd_head;
- return RNODE_LIST(node)->nd_head == NULL &&
- RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next == NULL;
-}
-
-static int
+static VALUE
setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
- int dup_rest, unsigned int *flag_ptr, struct rb_callinfo_kwarg **kwarg_ptr)
-{
- if (!argn) return 0;
-
- NODE *kwnode = NULL;
-
- switch (nd_type(argn)) {
- case NODE_LIST: {
- // f(x, y, z)
- int len = compile_args(iseq, args, argn, &kwnode);
- RUBY_ASSERT(flag_ptr == NULL || (*flag_ptr & VM_CALL_ARGS_SPLAT) == 0);
-
- if (kwnode) {
- if (compile_keyword_arg(iseq, args, kwnode, kwarg_ptr, flag_ptr)) {
- len -= 1;
+ int dup_rest, unsigned int *flag, struct rb_callinfo_kwarg **keywords)
+{
+ if (argn) {
+ switch (nd_type(argn)) {
+ case NODE_SPLAT: {
+ NO_CHECK(COMPILE(args, "args (splat)", argn->nd_head));
+ ADD_INSN1(args, argn, splatarray, RBOOL(dup_rest));
+ if (flag) *flag |= VM_CALL_ARGS_SPLAT;
+ return INT2FIX(1);
+ }
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH: {
+ int next_is_list = (nd_type_p(argn->nd_head, NODE_LIST));
+ VALUE argc = setup_args_core(iseq, args, argn->nd_head, 1, NULL, NULL);
+ if (nd_type_p(argn->nd_body, NODE_LIST)) {
+ /* This branch is needed to avoid "newarraykwsplat" [Bug #16442] */
+ int rest_len = compile_args(iseq, args, argn->nd_body, NULL, NULL);
+ ADD_INSN1(args, argn, newarray, INT2FIX(rest_len));
}
else {
- compile_hash(iseq, args, kwnode, TRUE, FALSE);
+ NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body));
}
- }
-
- return len;
- }
- case NODE_SPLAT: {
- // f(*a)
- NO_CHECK(COMPILE(args, "args (splat)", RNODE_SPLAT(argn)->nd_head));
- ADD_INSN1(args, argn, splatarray, RBOOL(dup_rest));
- if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT;
- RUBY_ASSERT(flag_ptr == NULL || (*flag_ptr & VM_CALL_KW_SPLAT) == 0);
- return 1;
- }
- case NODE_ARGSCAT: {
- if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT;
- int argc = setup_args_core(iseq, args, RNODE_ARGSCAT(argn)->nd_head, 1, NULL, NULL);
-
- if (nd_type_p(RNODE_ARGSCAT(argn)->nd_body, NODE_LIST)) {
- int rest_len = compile_args(iseq, args, RNODE_ARGSCAT(argn)->nd_body, &kwnode);
- if (kwnode) rest_len--;
- ADD_INSN1(args, argn, newarray, INT2FIX(rest_len));
- }
- else {
- RUBY_ASSERT(!check_keyword(RNODE_ARGSCAT(argn)->nd_body));
- NO_CHECK(COMPILE(args, "args (cat: splat)", RNODE_ARGSCAT(argn)->nd_body));
- }
-
- if (nd_type_p(RNODE_ARGSCAT(argn)->nd_head, NODE_LIST)) {
- ADD_INSN1(args, argn, splatarray, Qtrue);
- argc += 1;
- }
- else {
- ADD_INSN1(args, argn, splatarray, Qfalse);
- ADD_INSN(args, argn, concatarray);
- }
-
- // f(..., *a, ..., k1:1, ...) #=> f(..., *[*a, ...], **{k1:1, ...})
- if (kwnode) {
- // kwsplat
- *flag_ptr |= VM_CALL_KW_SPLAT;
- *flag_ptr |= VM_CALL_KW_SPLAT_MUT;
- compile_hash(iseq, args, kwnode, TRUE, FALSE);
- argc += 1;
- }
-
- return argc;
- }
- case NODE_ARGSPUSH: {
- if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT;
- int argc = setup_args_core(iseq, args, RNODE_ARGSPUSH(argn)->nd_head, 1, NULL, NULL);
-
- if (nd_type_p(RNODE_ARGSPUSH(argn)->nd_body, NODE_LIST)) {
- int rest_len = compile_args(iseq, args, RNODE_ARGSPUSH(argn)->nd_body, &kwnode);
- if (kwnode) rest_len--;
- ADD_INSN1(args, argn, newarray, INT2FIX(rest_len));
- ADD_INSN1(args, argn, newarray, INT2FIX(1));
- ADD_INSN(args, argn, concatarray);
- }
- else {
- if (keyword_node_p(RNODE_ARGSPUSH(argn)->nd_body)) {
- kwnode = RNODE_ARGSPUSH(argn)->nd_body;
+ if (flag) {
+ *flag |= VM_CALL_ARGS_SPLAT;
+ /* This is a dirty hack. It traverses the AST twice.
+ * In a long term, it should be fixed by a redesign of keyword arguments */
+ if (check_keyword(argn->nd_body))
+ *flag |= VM_CALL_KW_SPLAT;
+ }
+ if (nd_type_p(argn, NODE_ARGSCAT)) {
+ if (next_is_list) {
+ ADD_INSN1(args, argn, splatarray, Qtrue);
+ return INT2FIX(FIX2INT(argc) + 1);
+ }
+ else {
+ ADD_INSN1(args, argn, splatarray, Qfalse);
+ ADD_INSN(args, argn, concatarray);
+ return argc;
+ }
}
else {
- NO_CHECK(COMPILE(args, "args (cat: splat)", RNODE_ARGSPUSH(argn)->nd_body));
ADD_INSN1(args, argn, newarray, INT2FIX(1));
ADD_INSN(args, argn, concatarray);
+ return argc;
}
+ }
+ case NODE_LIST: {
+ int len = compile_args(iseq, args, argn, keywords, flag);
+ return INT2FIX(len);
+ }
+ default: {
+ UNKNOWN_NODE("setup_arg", argn, Qnil);
+ }
}
-
- if (kwnode) {
- // f(*a, k:1)
- *flag_ptr |= VM_CALL_KW_SPLAT;
- if (!keyword_node_single_splat_p(kwnode)) {
- *flag_ptr |= VM_CALL_KW_SPLAT_MUT;
- }
- compile_hash(iseq, args, kwnode, TRUE, FALSE);
- argc += 1;
- }
-
- return argc;
- }
- default: {
- UNKNOWN_NODE("setup_arg", argn, Qnil);
- }
}
+ return INT2FIX(0);
}
static VALUE
@@ -6154,7 +5905,7 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
unsigned int dup_rest = 1;
DECL_ANCHOR(arg_block);
INIT_ANCHOR(arg_block);
- NO_CHECK(COMPILE(arg_block, "block", RNODE_BLOCK_PASS(argn)->nd_body));
+ NO_CHECK(COMPILE(arg_block, "block", argn->nd_body));
*flag |= VM_CALL_ARGS_BLOCKARG;
@@ -6168,11 +5919,11 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
dup_rest = 0;
}
}
- ret = INT2FIX(setup_args_core(iseq, args, RNODE_BLOCK_PASS(argn)->nd_head, dup_rest, flag, keywords));
+ ret = setup_args_core(iseq, args, argn->nd_head, dup_rest, flag, keywords);
ADD_SEQ(args, arg_block);
}
else {
- ret = INT2FIX(setup_args_core(iseq, args, argn, 0, flag, keywords));
+ ret = setup_args_core(iseq, args, argn, 0, flag, keywords);
}
return ret;
}
@@ -6208,19 +5959,19 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
ADD_INSN(ret, line_node, dup);
ADD_INSNL(ret, line_node, branchunless, fail_label);
- for (vars = node; vars; vars = RNODE_BLOCK(vars)->nd_next) {
+ for (vars = node; vars; vars = vars->nd_next) {
INSN *cap;
- if (RNODE_BLOCK(vars)->nd_next) {
+ if (vars->nd_next) {
ADD_INSN(ret, line_node, dup);
}
last = ret->last;
- NO_CHECK(COMPILE_POPPED(ret, "capture", RNODE_BLOCK(vars)->nd_head));
+ NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head));
last = last->next; /* putobject :var */
cap = new_insn_send(iseq, line_node, idAREF, INT2FIX(1),
NULL, INT2FIX(0), NULL);
ELEM_INSERT_PREV(last->next, (LINK_ELEMENT *)cap);
#if !defined(NAMED_CAPTURE_SINGLE_OPT) || NAMED_CAPTURE_SINGLE_OPT-0
- if (!RNODE_BLOCK(vars)->nd_next && vars == node) {
+ if (!vars->nd_next && vars == node) {
/* only one name */
DECL_ANCHOR(nom);
@@ -6241,9 +5992,9 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
ADD_INSNL(ret, line_node, jump, end_label);
ADD_LABEL(ret, fail_label);
ADD_INSN(ret, line_node, pop);
- for (vars = node; vars; vars = RNODE_BLOCK(vars)->nd_next) {
+ for (vars = node; vars; vars = vars->nd_next) {
last = ret->last;
- NO_CHECK(COMPILE_POPPED(ret, "capture", RNODE_BLOCK(vars)->nd_head));
+ NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head));
last = last->next; /* putobject :var */
((INSN*)last)->insn_id = BIN(putnil);
((INSN*)last)->operand_size = 0;
@@ -6257,7 +6008,7 @@ optimizable_range_item_p(const NODE *n)
if (!n) return FALSE;
switch (nd_type(n)) {
case NODE_LIT:
- return RB_INTEGER_TYPE_P(RNODE_LIT(n)->nd_lit);
+ return RB_INTEGER_TYPE_P(n->nd_lit);
case NODE_NIL:
return TRUE;
default:
@@ -6268,21 +6019,53 @@ optimizable_range_item_p(const NODE *n)
static int
compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type)
{
- const NODE *const node_body = type == NODE_IF ? RNODE_IF(node)->nd_body : RNODE_UNLESS(node)->nd_else;
- const NODE *const node_else = type == NODE_IF ? RNODE_IF(node)->nd_else : RNODE_UNLESS(node)->nd_body;
+ struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
+ const NODE *const node_body = type == NODE_IF ? node->nd_body : node->nd_else;
+ const NODE *const node_else = type == NODE_IF ? node->nd_else : node->nd_body;
const int line = nd_line(node);
const NODE *line_node = node;
DECL_ANCHOR(cond_seq);
+ DECL_ANCHOR(then_seq);
+ DECL_ANCHOR(else_seq);
LABEL *then_label, *else_label, *end_label;
VALUE branches = Qfalse;
+ int ci_size;
+ VALUE catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ long catch_table_size = NIL_P(catch_table) ? 0 : RARRAY_LEN(catch_table);
INIT_ANCHOR(cond_seq);
+ INIT_ANCHOR(then_seq);
+ INIT_ANCHOR(else_seq);
then_label = NEW_LABEL(line);
else_label = NEW_LABEL(line);
end_label = 0;
- compile_branch_condition(iseq, cond_seq, RNODE_IF(node)->nd_cond, then_label, else_label);
+ compile_branch_condition(iseq, cond_seq, node->nd_cond,
+ then_label, else_label);
+
+ ci_size = body->ci_size;
+ CHECK(COMPILE_(then_seq, "then", node_body, popped));
+ catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ if (!then_label->refcnt) {
+ body->ci_size = ci_size;
+ if (!NIL_P(catch_table)) rb_ary_set_len(catch_table, catch_table_size);
+ }
+ else {
+ if (!NIL_P(catch_table)) catch_table_size = RARRAY_LEN(catch_table);
+ }
+
+ ci_size = body->ci_size;
+ CHECK(COMPILE_(else_seq, "else", node_else, popped));
+ catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ if (!else_label->refcnt) {
+ body->ci_size = ci_size;
+ if (!NIL_P(catch_table)) rb_ary_set_len(catch_table, catch_table_size);
+ }
+ else {
+ if (!NIL_P(catch_table)) catch_table_size = RARRAY_LEN(catch_table);
+ }
+
ADD_SEQ(ret, cond_seq);
if (then_label->refcnt && else_label->refcnt) {
@@ -6291,11 +6074,6 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int
if (then_label->refcnt) {
ADD_LABEL(ret, then_label);
-
- DECL_ANCHOR(then_seq);
- INIT_ANCHOR(then_seq);
- CHECK(COMPILE_(then_seq, "then", node_body, popped));
-
if (else_label->refcnt) {
add_trace_branch_coverage(
iseq,
@@ -6315,11 +6093,6 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int
if (else_label->refcnt) {
ADD_LABEL(ret, else_label);
-
- DECL_ANCHOR(else_seq);
- INIT_ANCHOR(else_seq);
- CHECK(COMPILE_(else_seq, "else", node_else, popped));
-
if (then_label->refcnt) {
add_trace_branch_coverage(
iseq,
@@ -6362,11 +6135,11 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
RHASH_TBL_RAW(literals)->type = &cdhash_type;
- CHECK(COMPILE(head, "case base", RNODE_CASE(node)->nd_head));
+ CHECK(COMPILE(head, "case base", node->nd_head));
branches = decl_branch_base(iseq, node, "case");
- node = RNODE_CASE(node)->nd_body;
+ node = node->nd_body;
EXPECT_NODE("NODE_CASE", node, NODE_WHEN, COMPILE_NG);
type = nd_type(node);
line = nd_line(node);
@@ -6386,14 +6159,14 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
add_trace_branch_coverage(
iseq,
body_seq,
- RNODE_WHEN(node)->nd_body ? RNODE_WHEN(node)->nd_body : node,
+ node->nd_body ? node->nd_body : node,
branch_id++,
"when",
branches);
- CHECK(COMPILE_(body_seq, "when body", RNODE_WHEN(node)->nd_body, popped));
+ CHECK(COMPILE_(body_seq, "when body", node->nd_body, popped));
ADD_INSNL(body_seq, line_node, jump, endlabel);
- vals = RNODE_WHEN(node)->nd_head;
+ vals = node->nd_head;
if (vals) {
switch (nd_type(vals)) {
case NODE_LIST:
@@ -6414,7 +6187,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
EXPECT_NODE_NONULL("NODE_CASE", node, NODE_LIST, COMPILE_NG);
}
- node = RNODE_WHEN(node)->nd_next;
+ node = node->nd_next;
if (!node) {
break;
}
@@ -6459,7 +6232,7 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
{
const NODE *vals;
const NODE *val;
- const NODE *node = RNODE_CASE2(orig_node)->nd_body;
+ const NODE *node = orig_node->nd_body;
LABEL *endlabel;
DECL_ANCHOR(body_seq);
VALUE branches = Qfalse;
@@ -6477,14 +6250,14 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
add_trace_branch_coverage(
iseq,
body_seq,
- RNODE_WHEN(node)->nd_body ? RNODE_WHEN(node)->nd_body : node,
+ node->nd_body ? node->nd_body : node,
branch_id++,
"when",
branches);
- CHECK(COMPILE_(body_seq, "when", RNODE_WHEN(node)->nd_body, popped));
+ CHECK(COMPILE_(body_seq, "when", node->nd_body, popped));
ADD_INSNL(body_seq, node, jump, endlabel);
- vals = RNODE_WHEN(node)->nd_head;
+ vals = node->nd_head;
if (!vals) {
EXPECT_NODE_NONULL("NODE_WHEN", node, NODE_LIST, COMPILE_NG);
}
@@ -6492,12 +6265,12 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
case NODE_LIST:
while (vals) {
LABEL *lnext;
- val = RNODE_LIST(vals)->nd_head;
+ val = vals->nd_head;
lnext = NEW_LABEL(nd_line(val));
debug_compile("== when2\n", (void)0);
CHECK(compile_branch_condition(iseq, ret, val, l1, lnext));
ADD_LABEL(ret, lnext);
- vals = RNODE_LIST(vals)->nd_next;
+ vals = vals->nd_next;
}
break;
case NODE_SPLAT:
@@ -6511,7 +6284,7 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
default:
UNKNOWN_NODE("NODE_WHEN", vals, COMPILE_NG);
}
- node = RNODE_WHEN(node)->nd_next;
+ node = node->nd_next;
}
/* else */
add_trace_branch_coverage(
@@ -6603,13 +6376,14 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
* match_failed:
* goto unmatched
*/
- const NODE *args = RNODE_ARYPTN(node)->pre_args;
- const int pre_args_num = RNODE_ARYPTN(node)->pre_args ? rb_long2int(RNODE_LIST(RNODE_ARYPTN(node)->pre_args)->as.nd_alen) : 0;
- const int post_args_num = RNODE_ARYPTN(node)->post_args ? rb_long2int(RNODE_LIST(RNODE_ARYPTN(node)->post_args)->as.nd_alen) : 0;
+ struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
+ const NODE *args = apinfo->pre_args;
+ const int pre_args_num = apinfo->pre_args ? rb_long2int(apinfo->pre_args->nd_alen) : 0;
+ const int post_args_num = apinfo->post_args ? rb_long2int(apinfo->post_args->nd_alen) : 0;
const int min_argc = pre_args_num + post_args_num;
- const int use_rest_num = RNODE_ARYPTN(node)->rest_arg && (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg) ||
- (!NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg) && post_args_num > 0));
+ const int use_rest_num = apinfo->rest_arg && (NODE_NAMED_REST_P(apinfo->rest_arg) ||
+ (!NODE_NAMED_REST_P(apinfo->rest_arg) && post_args_num > 0));
LABEL *match_failed, *type_error, *deconstruct, *deconstructed;
int i;
@@ -6633,10 +6407,10 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_INSN(ret, line_node, dup);
ADD_SEND(ret, line_node, idLength, INT2FIX(0));
ADD_INSN1(ret, line_node, putobject, INT2FIX(min_argc));
- ADD_SEND(ret, line_node, RNODE_ARYPTN(node)->rest_arg ? idGE : idEq, INT2FIX(1)); // (1)
+ ADD_SEND(ret, line_node, apinfo->rest_arg ? idGE : idEq, INT2FIX(1)); // (1)
if (in_single_pattern) {
CHECK(iseq_compile_pattern_set_length_errmsg(iseq, ret, node,
- RNODE_ARYPTN(node)->rest_arg ? rb_fstring_lit("%p length mismatch (given %p, expected %p+)") :
+ apinfo->rest_arg ? rb_fstring_lit("%p length mismatch (given %p, expected %p+)") :
rb_fstring_lit("%p length mismatch (given %p, expected %p)"),
INT2FIX(min_argc), base_index + 1 /* (1) */));
}
@@ -6646,12 +6420,12 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_INSN(ret, line_node, dup);
ADD_INSN1(ret, line_node, putobject, INT2FIX(i));
ADD_SEND(ret, line_node, idAREF, INT2FIX(1)); // (2)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(args)->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (2) */, false));
- args = RNODE_LIST(args)->nd_next;
+ CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (2) */, false));
+ args = args->nd_next;
}
- if (RNODE_ARYPTN(node)->rest_arg) {
- if (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg)) {
+ if (apinfo->rest_arg) {
+ if (NODE_NAMED_REST_P(apinfo->rest_arg)) {
ADD_INSN(ret, line_node, dup);
ADD_INSN1(ret, line_node, putobject, INT2FIX(pre_args_num));
ADD_INSN1(ret, line_node, topn, INT2FIX(1));
@@ -6661,7 +6435,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_INSN1(ret, line_node, setn, INT2FIX(4));
ADD_SEND(ret, line_node, idAREF, INT2FIX(2)); // (3)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_ARYPTN(node)->rest_arg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (3) */, false));
+ CHECK(iseq_compile_pattern_match(iseq, ret, apinfo->rest_arg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (3) */, false));
}
else {
if (post_args_num > 0) {
@@ -6675,7 +6449,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
}
}
- args = RNODE_ARYPTN(node)->post_args;
+ args = apinfo->post_args;
for (i = 0; i < post_args_num; i++) {
ADD_INSN(ret, line_node, dup);
@@ -6684,8 +6458,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_SEND(ret, line_node, idPLUS, INT2FIX(1));
ADD_SEND(ret, line_node, idAREF, INT2FIX(1)); // (4)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(args)->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (4) */, false));
- args = RNODE_LIST(args)->nd_next;
+ CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (4) */, false));
+ args = args->nd_next;
}
ADD_INSN(ret, line_node, pop);
@@ -6763,8 +6537,9 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
* match_failed:
* goto unmatched
*/
- const NODE *args = RNODE_FNDPTN(node)->args;
- const int args_num = RNODE_FNDPTN(node)->args ? rb_long2int(RNODE_LIST(RNODE_FNDPTN(node)->args)->as.nd_alen) : 0;
+ struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo;
+ const NODE *args = fpinfo->args;
+ const int args_num = fpinfo->args ? rb_long2int(fpinfo->args->nd_alen) : 0;
LABEL *match_failed, *type_error, *deconstruct, *deconstructed;
match_failed = NEW_LABEL(line);
@@ -6817,25 +6592,25 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
}
ADD_SEND(ret, line_node, idAREF, INT2FIX(1)); // (5)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(args)->nd_head, next_loop, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (5) */, false));
- args = RNODE_LIST(args)->nd_next;
+ CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, next_loop, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (5) */, false));
+ args = args->nd_next;
}
- if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->pre_rest_arg)) {
+ if (NODE_NAMED_REST_P(fpinfo->pre_rest_arg)) {
ADD_INSN1(ret, line_node, topn, INT2FIX(3));
ADD_INSN1(ret, line_node, putobject, INT2FIX(0));
ADD_INSN1(ret, line_node, topn, INT2FIX(2));
ADD_SEND(ret, line_node, idAREF, INT2FIX(2)); // (6)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_FNDPTN(node)->pre_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (6) */, false));
+ CHECK(iseq_compile_pattern_match(iseq, ret, fpinfo->pre_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (6) */, false));
}
- if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->post_rest_arg)) {
+ if (NODE_NAMED_REST_P(fpinfo->post_rest_arg)) {
ADD_INSN1(ret, line_node, topn, INT2FIX(3));
ADD_INSN1(ret, line_node, topn, INT2FIX(1));
ADD_INSN1(ret, line_node, putobject, INT2FIX(args_num));
ADD_SEND(ret, line_node, idPLUS, INT2FIX(1));
ADD_INSN1(ret, line_node, topn, INT2FIX(3));
ADD_SEND(ret, line_node, idAREF, INT2FIX(2)); // (7)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_FNDPTN(node)->post_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3),(4), (7) */, false));
+ CHECK(iseq_compile_pattern_match(iseq, ret, fpinfo->post_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3),(4), (7) */, false));
}
ADD_INSNL(ret, line_node, jump, find_succeeded);
@@ -6949,12 +6724,12 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
match_failed = NEW_LABEL(line);
type_error = NEW_LABEL(line);
- if (RNODE_HSHPTN(node)->nd_pkwargs && !RNODE_HSHPTN(node)->nd_pkwrestarg) {
- const NODE *kw_args = RNODE_HASH(RNODE_HSHPTN(node)->nd_pkwargs)->nd_head;
- keys = rb_ary_new_capa(kw_args ? RNODE_LIST(kw_args)->as.nd_alen/2 : 0);
+ if (node->nd_pkwargs && !node->nd_pkwrestarg) {
+ const NODE *kw_args = node->nd_pkwargs->nd_head;
+ keys = rb_ary_new_capa(kw_args ? kw_args->nd_alen/2 : 0);
while (kw_args) {
- rb_ary_push(keys, RNODE_LIT(RNODE_LIST(kw_args)->nd_head)->nd_lit);
- kw_args = RNODE_LIST(RNODE_LIST(kw_args)->nd_next)->nd_next;
+ rb_ary_push(keys, kw_args->nd_head->nd_lit);
+ kw_args = kw_args->nd_next->nd_next;
}
}
@@ -6981,28 +6756,28 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_INSN1(ret, line_node, checktype, INT2FIX(T_HASH));
ADD_INSNL(ret, line_node, branchunless, type_error);
- if (RNODE_HSHPTN(node)->nd_pkwrestarg) {
+ if (node->nd_pkwrestarg) {
ADD_SEND(ret, line_node, rb_intern("dup"), INT2FIX(0));
}
- if (RNODE_HSHPTN(node)->nd_pkwargs) {
+ if (node->nd_pkwargs) {
int i;
int keys_num;
const NODE *args;
- args = RNODE_HASH(RNODE_HSHPTN(node)->nd_pkwargs)->nd_head;
+ args = node->nd_pkwargs->nd_head;
if (args) {
DECL_ANCHOR(match_values);
INIT_ANCHOR(match_values);
- keys_num = rb_long2int(RNODE_LIST(args)->as.nd_alen) / 2;
+ keys_num = rb_long2int(args->nd_alen) / 2;
for (i = 0; i < keys_num; i++) {
- NODE *key_node = RNODE_LIST(args)->nd_head;
- NODE *value_node = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_head;
+ NODE *key_node = args->nd_head;
+ NODE *value_node = args->nd_next->nd_head;
VALUE key;
if (!nd_type_p(key_node, NODE_LIT)) {
UNKNOWN_NODE("NODE_IN", key_node, COMPILE_NG);
}
- key = RNODE_LIT(key_node)->nd_lit;
+ key = key_node->nd_lit;
ADD_INSN(ret, line_node, dup);
ADD_INSN1(ret, line_node, putobject, key);
@@ -7031,9 +6806,9 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_INSN(match_values, line_node, dup);
ADD_INSN1(match_values, line_node, putobject, key);
- ADD_SEND(match_values, line_node, RNODE_HSHPTN(node)->nd_pkwrestarg ? rb_intern("delete") : idAREF, INT2FIX(1)); // (8)
+ ADD_SEND(match_values, line_node, node->nd_pkwrestarg ? rb_intern("delete") : idAREF, INT2FIX(1)); // (8)
CHECK(iseq_compile_pattern_match(iseq, match_values, value_node, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (8) */, false));
- args = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_next;
+ args = args->nd_next->nd_next;
}
ADD_SEQ(ret, match_values);
}
@@ -7047,8 +6822,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
ADD_INSNL(ret, line_node, branchunless, match_failed);
}
- if (RNODE_HSHPTN(node)->nd_pkwrestarg) {
- if (RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
+ if (node->nd_pkwrestarg) {
+ if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
ADD_INSN(ret, line_node, dup);
ADD_SEND(ret, line_node, idEmptyP, INT2FIX(0)); // (10)
if (in_single_pattern) {
@@ -7058,7 +6833,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
}
else {
ADD_INSN(ret, line_node, dup); // (11)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_HSHPTN(node)->nd_pkwrestarg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (11) */, false));
+ CHECK(iseq_compile_pattern_match(iseq, ret, node->nd_pkwrestarg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (11) */, false));
}
}
@@ -7102,7 +6877,6 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
case NODE_COLON2:
case NODE_COLON3:
case NODE_BEGIN:
- case NODE_BLOCK:
CHECK(COMPILE(ret, "case in literal", node)); // (1)
if (in_single_pattern) {
ADD_INSN1(ret, line_node, dupn, INT2FIX(2));
@@ -7116,7 +6890,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
break;
case NODE_LASGN: {
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
- ID id = RNODE_LASGN(node)->nd_vid;
+ ID id = node->nd_vid;
int idx = ISEQ_BODY(body->local_iseq)->local_table_size - get_local_var_idx(iseq, id);
if (in_alt_pattern) {
@@ -7134,7 +6908,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
}
case NODE_DASGN: {
int idx, lv, ls;
- ID id = RNODE_DASGN(node)->nd_vid;
+ ID id = node->nd_vid;
idx = get_dyna_var_idx(iseq, id, &lv, &ls);
@@ -7160,8 +6934,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
case NODE_UNLESS: {
LABEL *match_failed;
match_failed = unmatched;
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_IF(node)->nd_body, unmatched, in_single_pattern, in_alt_pattern, base_index, use_deconstructed_cache));
- CHECK(COMPILE(ret, "case in if", RNODE_IF(node)->nd_cond));
+ CHECK(iseq_compile_pattern_match(iseq, ret, node->nd_body, unmatched, in_single_pattern, in_alt_pattern, base_index, use_deconstructed_cache));
+ CHECK(COMPILE(ret, "case in if", node->nd_cond));
if (in_single_pattern) {
LABEL *match_succeeded;
match_succeeded = NEW_LABEL(line);
@@ -7198,15 +6972,15 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
LABEL *match_failed;
match_failed = NEW_LABEL(line);
- n = RNODE_HASH(node)->nd_head;
- if (! (nd_type_p(n, NODE_LIST) && RNODE_LIST(n)->as.nd_alen == 2)) {
+ n = node->nd_head;
+ if (! (nd_type_p(n, NODE_LIST) && n->nd_alen == 2)) {
COMPILE_ERROR(ERROR_ARGS "unexpected node");
return COMPILE_NG;
}
ADD_INSN(ret, line_node, dup); // (1)
- CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(n)->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (1) */, use_deconstructed_cache));
- CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_head, matched, match_failed, in_single_pattern, in_alt_pattern, base_index, false));
+ CHECK(iseq_compile_pattern_match(iseq, ret, n->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (1) */, use_deconstructed_cache));
+ CHECK(iseq_compile_pattern_each(iseq, ret, n->nd_next->nd_head, matched, match_failed, in_single_pattern, in_alt_pattern, base_index, false));
ADD_INSN(ret, line_node, putnil);
ADD_LABEL(ret, match_failed);
@@ -7220,13 +6994,13 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
fin = NEW_LABEL(line);
ADD_INSN(ret, line_node, dup); // (1)
- CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_OR(node)->nd_1st, match_succeeded, fin, in_single_pattern, true, base_index + 1 /* (1) */, use_deconstructed_cache));
+ CHECK(iseq_compile_pattern_each(iseq, ret, node->nd_1st, match_succeeded, fin, in_single_pattern, true, base_index + 1 /* (1) */, use_deconstructed_cache));
ADD_LABEL(ret, match_succeeded);
ADD_INSN(ret, line_node, pop);
ADD_INSNL(ret, line_node, jump, matched);
ADD_INSN(ret, line_node, putnil);
ADD_LABEL(ret, fin);
- CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_OR(node)->nd_2nd, matched, unmatched, in_single_pattern, true, base_index, use_deconstructed_cache));
+ CHECK(iseq_compile_pattern_each(iseq, ret, node->nd_2nd, matched, unmatched, in_single_pattern, true, base_index, use_deconstructed_cache));
break;
}
default:
@@ -7249,9 +7023,9 @@ iseq_compile_pattern_constant(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD
{
const NODE *line_node = node;
- if (RNODE_ARYPTN(node)->nd_pconst) {
+ if (node->nd_pconst) {
ADD_INSN(ret, line_node, dup); // (1)
- CHECK(COMPILE(ret, "constant", RNODE_ARYPTN(node)->nd_pconst)); // (2)
+ CHECK(COMPILE(ret, "constant", node->nd_pconst)); // (2)
if (in_single_pattern) {
ADD_INSN1(ret, line_node, dupn, INT2FIX(2));
}
@@ -7454,12 +7228,12 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
branches = decl_branch_base(iseq, node, "case");
- node = RNODE_CASE3(node)->nd_body;
+ node = node->nd_body;
EXPECT_NODE("NODE_CASE3", node, NODE_IN, COMPILE_NG);
type = nd_type(node);
line = nd_line(node);
line_node = node;
- single_pattern = !RNODE_IN(node)->nd_next;
+ single_pattern = !node->nd_next;
endlabel = NEW_LABEL(line);
elselabel = NEW_LABEL(line);
@@ -7473,7 +7247,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
}
ADD_INSN(head, line_node, putnil); /* allocate stack for cached #deconstruct value */
- CHECK(COMPILE(head, "case base", RNODE_CASE3(orig_node)->nd_head));
+ CHECK(COMPILE(head, "case base", orig_node->nd_head));
ADD_SEQ(ret, head); /* case VAL */
@@ -7489,14 +7263,14 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
add_trace_branch_coverage(
iseq,
body_seq,
- RNODE_IN(node)->nd_body ? RNODE_IN(node)->nd_body : node,
+ node->nd_body ? node->nd_body : node,
branch_id++,
"in",
branches);
- CHECK(COMPILE_(body_seq, "in body", RNODE_IN(node)->nd_body, popped));
+ CHECK(COMPILE_(body_seq, "in body", node->nd_body, popped));
ADD_INSNL(body_seq, line_node, jump, endlabel);
- pattern = RNODE_IN(node)->nd_head;
+ pattern = node->nd_head;
if (pattern) {
int pat_line = nd_line(pattern);
LABEL *next_pat = NEW_LABEL(pat_line);
@@ -7511,7 +7285,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
return COMPILE_NG;
}
- node = RNODE_IN(node)->nd_next;
+ node = node->nd_next;
if (!node) {
break;
}
@@ -7553,7 +7327,6 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no
fin = NEW_LABEL(line);
kw_arg = rb_xmalloc_mul_add(2, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
- kw_arg->references = 0;
kw_arg->keyword_len = 2;
kw_arg->keywords[0] = ID2SYM(rb_intern("matchee"));
kw_arg->keywords[1] = ID2SYM(rb_intern("key"));
@@ -7637,7 +7410,7 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
ISEQ_COMPILE_DATA(iseq)->loopval_popped = 0;
push_ensure_entry(iseq, &enl, NULL, NULL);
- if (RNODE_WHILE(node)->nd_state == 1) {
+ if (node->nd_state == 1) {
ADD_INSNL(ret, line_node, jump, next_label);
}
else {
@@ -7656,27 +7429,27 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
add_trace_branch_coverage(
iseq,
ret,
- RNODE_WHILE(node)->nd_body ? RNODE_WHILE(node)->nd_body : node,
+ node->nd_body ? node->nd_body : node,
0,
"body",
branches);
- CHECK(COMPILE_POPPED(ret, "while body", RNODE_WHILE(node)->nd_body));
+ CHECK(COMPILE_POPPED(ret, "while body", node->nd_body));
ADD_LABEL(ret, next_label); /* next */
if (type == NODE_WHILE) {
- compile_branch_condition(iseq, ret, RNODE_WHILE(node)->nd_cond,
+ compile_branch_condition(iseq, ret, node->nd_cond,
redo_label, end_label);
}
else {
/* until */
- compile_branch_condition(iseq, ret, RNODE_WHILE(node)->nd_cond,
+ compile_branch_condition(iseq, ret, node->nd_cond,
end_label, redo_label);
}
ADD_LABEL(ret, end_label);
ADD_ADJUST_RESTORE(ret, adjust_label);
- if (UNDEF_P(RNODE_WHILE(node)->nd_state)) {
+ if (UNDEF_P(node->nd_state)) {
/* ADD_INSN(ret, line_node, putundef); */
COMPILE_ERROR(ERROR_ARGS "unsupported: putundef");
return COMPILE_NG;
@@ -7718,18 +7491,18 @@ compile_iter(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
ADD_LABEL(ret, retry_label);
if (nd_type_p(node, NODE_FOR)) {
- CHECK(COMPILE(ret, "iter caller (for)", RNODE_FOR(node)->nd_iter));
+ CHECK(COMPILE(ret, "iter caller (for)", node->nd_iter));
ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq =
- NEW_CHILD_ISEQ(RNODE_FOR(node)->nd_body, make_name_for_block(iseq),
+ NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
ISEQ_TYPE_BLOCK, line);
ADD_SEND_WITH_BLOCK(ret, line_node, idEach, INT2FIX(0), child_iseq);
}
else {
ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq =
- NEW_CHILD_ISEQ(RNODE_ITER(node)->nd_body, make_name_for_block(iseq),
+ NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq),
ISEQ_TYPE_BLOCK, line);
- CHECK(COMPILE(ret, "iter caller", RNODE_ITER(node)->nd_iter));
+ CHECK(COMPILE(ret, "iter caller", node->nd_iter));
}
{
@@ -7773,7 +7546,7 @@ compile_for_masgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod
* (args.length == 1 && Array.try_convert(args[0])) || args
*/
const NODE *line_node = node;
- const NODE *var = RNODE_FOR_MASGN(node)->nd_var;
+ const NODE *var = node->nd_var;
LABEL *not_single = NEW_LABEL(nd_line(var));
LABEL *not_ary = NEW_LABEL(nd_line(var));
CHECK(COMPILE(ret, "for var", var));
@@ -7808,7 +7581,7 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
LABEL *splabel = NEW_LABEL(0);
ADD_LABEL(ret, splabel);
ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
- CHECK(COMPILE_(ret, "break val (while/until)", RNODE_BREAK(node)->nd_stts,
+ CHECK(COMPILE_(ret, "break val (while/until)", node->nd_stts,
ISEQ_COMPILE_DATA(iseq)->loopval_popped));
add_ensure_iseq(ret, iseq, 0);
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
@@ -7843,7 +7616,7 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
}
/* escape from block */
- CHECK(COMPILE(ret, "break val (block)", RNODE_BREAK(node)->nd_stts));
+ CHECK(COMPILE(ret, "break val (block)", node->nd_stts));
ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_BREAK));
if (popped) {
ADD_INSN(ret, line_node, pop);
@@ -7866,7 +7639,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
LABEL *splabel = NEW_LABEL(0);
debugs("next in while loop\n");
ADD_LABEL(ret, splabel);
- CHECK(COMPILE(ret, "next val/valid syntax?", RNODE_NEXT(node)->nd_stts));
+ CHECK(COMPILE(ret, "next val/valid syntax?", node->nd_stts));
add_ensure_iseq(ret, iseq, 0);
ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
@@ -7880,11 +7653,10 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
debugs("next in block\n");
ADD_LABEL(ret, splabel);
ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->start_label);
- CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts));
+ CHECK(COMPILE(ret, "next val", node->nd_stts));
add_ensure_iseq(ret, iseq, 0);
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
ADD_ADJUST_RESTORE(ret, splabel);
- splabel->unremovable = FALSE;
if (!popped) {
ADD_INSN(ret, line_node, putnil);
@@ -7915,7 +7687,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
ip = ISEQ_BODY(ip)->parent_iseq;
}
if (ip != 0) {
- CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts));
+ CHECK(COMPILE(ret, "next val", node->nd_stts));
ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_NEXT));
if (popped) {
@@ -8027,7 +7799,7 @@ compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
LABEL *lstart = NEW_LABEL(line);
LABEL *lend = NEW_LABEL(line);
LABEL *lcont = NEW_LABEL(line);
- const rb_iseq_t *rescue = NEW_CHILD_ISEQ(RNODE_RESCUE(node)->nd_resq,
+ const rb_iseq_t *rescue = NEW_CHILD_ISEQ(node->nd_resq,
rb_str_concat(rb_str_new2("rescue in "),
ISEQ_BODY(iseq)->location.label),
ISEQ_TYPE_RESCUE, line);
@@ -8039,14 +7811,14 @@ compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
bool prev_in_rescue = ISEQ_COMPILE_DATA(iseq)->in_rescue;
ISEQ_COMPILE_DATA(iseq)->in_rescue = true;
{
- CHECK(COMPILE(ret, "rescue head", RNODE_RESCUE(node)->nd_head));
+ CHECK(COMPILE(ret, "rescue head", node->nd_head));
}
ISEQ_COMPILE_DATA(iseq)->in_rescue = prev_in_rescue;
ADD_LABEL(ret, lend);
- if (RNODE_RESCUE(node)->nd_else) {
+ if (node->nd_else) {
ADD_INSN(ret, line_node, pop);
- CHECK(COMPILE(ret, "rescue else", RNODE_RESCUE(node)->nd_else));
+ CHECK(COMPILE(ret, "rescue else", node->nd_else));
}
ADD_INSN(ret, line_node, nop);
ADD_LABEL(ret, lcont);
@@ -8074,16 +7846,16 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
label_miss = NEW_LABEL(line);
label_hit = NEW_LABEL(line);
- narg = RNODE_RESBODY(resq)->nd_args;
+ narg = resq->nd_args;
if (narg) {
switch (nd_type(narg)) {
case NODE_LIST:
while (narg) {
ADD_GETLOCAL(ret, line_node, LVAR_ERRINFO, 0);
- CHECK(COMPILE(ret, "rescue arg", RNODE_LIST(narg)->nd_head));
+ CHECK(COMPILE(ret, "rescue arg", narg->nd_head));
ADD_INSN1(ret, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
ADD_INSNL(ret, line_node, branchif, label_hit);
- narg = RNODE_LIST(narg)->nd_next;
+ narg = narg->nd_next;
}
break;
case NODE_SPLAT:
@@ -8106,24 +7878,13 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
}
ADD_INSNL(ret, line_node, jump, label_miss);
ADD_LABEL(ret, label_hit);
- ADD_TRACE(ret, RUBY_EVENT_RESCUE);
-
- if (nd_type(RNODE_RESBODY(resq)->nd_body) == NODE_BEGIN && RNODE_BEGIN(RNODE_RESBODY(resq)->nd_body)->nd_body == NULL) {
- // empty body
- int lineno = nd_line(RNODE_RESBODY(resq)->nd_body);
- NODE dummy_line_node = generate_dummy_line_node(lineno, -1);
- ADD_INSN(ret, &dummy_line_node, putnil);
- }
- else {
- CHECK(COMPILE(ret, "resbody body", RNODE_RESBODY(resq)->nd_body));
- }
-
+ CHECK(COMPILE(ret, "resbody body", resq->nd_body));
if (ISEQ_COMPILE_DATA(iseq)->option->tailcall_optimization) {
ADD_INSN(ret, line_node, nop);
}
ADD_INSN(ret, line_node, leave);
ADD_LABEL(ret, label_miss);
- resq = RNODE_RESBODY(resq)->nd_head;
+ resq = resq->nd_head;
}
return COMPILE_OK;
}
@@ -8134,7 +7895,7 @@ compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
const int line = nd_line(node);
const NODE *line_node = node;
DECL_ANCHOR(ensr);
- const rb_iseq_t *ensure = NEW_CHILD_ISEQ(RNODE_ENSURE(node)->nd_ensr,
+ const rb_iseq_t *ensure = NEW_CHILD_ISEQ(node->nd_ensr,
rb_str_concat(rb_str_new2 ("ensure in "), ISEQ_BODY(iseq)->location.label),
ISEQ_TYPE_ENSURE, line);
LABEL *lstart = NEW_LABEL(line);
@@ -8147,17 +7908,17 @@ compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
struct ensure_range *erange;
INIT_ANCHOR(ensr);
- CHECK(COMPILE_POPPED(ensr, "ensure ensr", RNODE_ENSURE(node)->nd_ensr));
+ CHECK(COMPILE_POPPED(ensr, "ensure ensr", node->nd_ensr));
last = ensr->last;
last_leave = last && IS_INSN(last) && IS_INSN_ID(last, leave);
er.begin = lstart;
er.end = lend;
er.next = 0;
- push_ensure_entry(iseq, &enl, &er, RNODE_ENSURE(node)->nd_ensr);
+ push_ensure_entry(iseq, &enl, &er, node->nd_ensr);
ADD_LABEL(ret, lstart);
- CHECK(COMPILE_(ret, "ensure head", RNODE_ENSURE(node)->nd_head, (popped | last_leave)));
+ CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave)));
ADD_LABEL(ret, lend);
ADD_SEQ(ret, ensr);
if (!popped && last_leave) ADD_INSN(ret, line_node, putnil);
@@ -8186,7 +7947,7 @@ compile_return(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
enum rb_iseq_type type = ISEQ_BODY(iseq)->type;
const rb_iseq_t *is = iseq;
enum rb_iseq_type t = type;
- const NODE *retval = RNODE_RETURN(node)->nd_stts;
+ const NODE *retval = node->nd_stts;
LABEL *splabel = 0;
while (t == ISEQ_TYPE_RESCUE || t == ISEQ_TYPE_ENSURE) {
@@ -8295,13 +8056,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
/* optimization shortcut
* "literal".freeze -> opt_str_freeze("literal")
*/
- if (get_nd_recv(node) && nd_type_p(get_nd_recv(node), NODE_STR) &&
- (get_node_call_nd_mid(node) == idFreeze || get_node_call_nd_mid(node) == idUMinus) &&
- get_nd_args(node) == NULL &&
+ if (node->nd_recv && nd_type_p(node->nd_recv, NODE_STR) &&
+ (node->nd_mid == idFreeze || node->nd_mid == idUMinus) &&
+ node->nd_args == NULL &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- VALUE str = rb_fstring(RNODE_STR(get_nd_recv(node))->nd_lit);
- if (get_node_call_nd_mid(node) == idUMinus) {
+ VALUE str = rb_fstring(node->nd_recv->nd_lit);
+ if (node->nd_mid == idUMinus) {
ADD_INSN2(ret, line_node, opt_str_uminus, str,
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
}
@@ -8318,14 +8079,14 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
/* optimization shortcut
* obj["literal"] -> opt_aref_with(obj, "literal")
*/
- if (get_node_call_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) &&
- nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 &&
- nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) &&
+ if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args &&
+ nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 1 &&
+ nd_type_p(node->nd_args->nd_head, NODE_STR) &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(get_nd_args(node))->nd_head)->nd_lit);
- CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
+ VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
+ CHECK(COMPILE(ret, "recv", node->nd_recv));
ADD_INSN2(ret, line_node, opt_aref_with, str,
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
RB_OBJ_WRITTEN(iseq, Qundef, str);
@@ -8368,12 +8129,12 @@ iseq_builtin_function_name(const enum node_type type, const NODE *recv, ID mid)
if (recv) {
switch (nd_type(recv)) {
case NODE_VCALL:
- if (RNODE_VCALL(recv)->nd_mid == rb_intern("__builtin")) {
+ if (recv->nd_mid == rb_intern("__builtin")) {
return name;
}
break;
case NODE_CONST:
- if (RNODE_CONST(recv)->nd_vid == rb_intern("Primitive")) {
+ if (recv->nd_vid == rb_intern("Primitive")) {
return name;
}
break;
@@ -8454,60 +8215,16 @@ delegate_call_p(const rb_iseq_t *iseq, unsigned int argc, const LINK_ANCHOR *arg
}
}
-// Compile Primitive.attr! :leaf, ...
-static int
-compile_builtin_attr(rb_iseq_t *iseq, const NODE *node)
-{
- VALUE symbol;
- VALUE string;
- if (!node) goto no_arg;
- while (node) {
- if (!nd_type_p(node, NODE_LIST)) goto bad_arg;
- const NODE *next = RNODE_LIST(node)->nd_next;
-
- node = RNODE_LIST(node)->nd_head;
- if (!node) goto no_arg;
- if (!nd_type_p(node, NODE_LIT)) goto bad_arg;
-
- symbol = RNODE_LIT(node)->nd_lit;
- if (!SYMBOL_P(symbol)) goto non_symbol_arg;
-
- string = rb_sym_to_s(symbol);
- if (strcmp(RSTRING_PTR(string), "leaf") == 0) {
- ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_LEAF;
- }
- else if (strcmp(RSTRING_PTR(string), "no_gc") == 0) {
- ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_NO_GC;
- }
- else {
- goto unknown_arg;
- }
- node = next;
- }
- return COMPILE_OK;
- no_arg:
- COMPILE_ERROR(ERROR_ARGS "attr!: no argument");
- return COMPILE_NG;
- non_symbol_arg:
- COMPILE_ERROR(ERROR_ARGS "non symbol argument to attr!: %s", rb_builtin_class_name(symbol));
- return COMPILE_NG;
- unknown_arg:
- COMPILE_ERROR(ERROR_ARGS "unknown argument to attr!: %s", RSTRING_PTR(string));
- return COMPILE_NG;
- bad_arg:
- UNKNOWN_NODE("attr!", node, COMPILE_NG);
-}
-
static int
compile_builtin_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, const NODE *line_node, int popped)
{
if (!node) goto no_arg;
if (!nd_type_p(node, NODE_LIST)) goto bad_arg;
- if (RNODE_LIST(node)->nd_next) goto too_many_arg;
- node = RNODE_LIST(node)->nd_head;
+ if (node->nd_next) goto too_many_arg;
+ node = node->nd_head;
if (!node) goto no_arg;
if (!nd_type_p(node, NODE_LIT)) goto bad_arg;
- VALUE name = RNODE_LIT(node)->nd_lit;
+ VALUE name = node->nd_lit;
if (!SYMBOL_P(name)) goto non_symbol_arg;
if (!popped) {
compile_lvar(iseq, ret, line_node, SYM2ID(name));
@@ -8531,8 +8248,8 @@ static NODE *
mandatory_node(const rb_iseq_t *iseq, const NODE *cond_node)
{
const NODE *node = ISEQ_COMPILE_DATA(iseq)->root_node;
- if (nd_type(node) == NODE_IF && RNODE_IF(node)->nd_cond == cond_node) {
- return RNODE_IF(node)->nd_body;
+ if (nd_type(node) == NODE_IF && node->nd_cond == cond_node) {
+ return node->nd_body;
}
else {
rb_bug("mandatory_node: can't find mandatory node");
@@ -8546,9 +8263,8 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
struct rb_args_info args = {
.pre_args_num = ISEQ_BODY(iseq)->param.lead_num,
};
- rb_node_args_t args_node;
- rb_node_init(RNODE(&args_node), NODE_ARGS);
- args_node.nd_ainfo = args;
+ NODE args_node;
+ rb_node_init(&args_node, NODE_ARGS, 0, 0, (VALUE)&args);
// local table without non-mandatory parameters
const int skip_local_size = ISEQ_BODY(iseq)->param.size - ISEQ_BODY(iseq)->param.lead_num;
@@ -8569,25 +8285,24 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
tbl->ids[i] = ISEQ_BODY(iseq)->local_table[i + skip_local_size];
}
- rb_node_scope_t scope_node;
- rb_node_init(RNODE(&scope_node), NODE_SCOPE);
- scope_node.nd_tbl = tbl;
- scope_node.nd_body = mandatory_node(iseq, node);
- scope_node.nd_args = &args_node;
+ NODE scope_node;
+ rb_node_init(&scope_node, NODE_SCOPE, (VALUE)tbl, (VALUE)mandatory_node(iseq, node), (VALUE)&args_node);
rb_ast_body_t ast = {
- .root = RNODE(&scope_node),
- .frozen_string_literal = -1,
- .coverage_enabled = -1,
+ .root = &scope_node,
+ .compile_option = 0,
.script_lines = ISEQ_BODY(iseq)->variable.script_lines,
};
+ int prev_inline_index = GET_VM()->builtin_inline_index;
+
ISEQ_BODY(iseq)->mandatory_only_iseq =
rb_iseq_new_with_opt(&ast, rb_iseq_base_label(iseq),
rb_iseq_path(iseq), rb_iseq_realpath(iseq),
nd_line(line_node), NULL, 0,
ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option);
+ GET_VM()->builtin_inline_index = prev_inline_index;
ALLOCV_END(idtmp);
return COMPILE_OK;
}
@@ -8596,15 +8311,15 @@ static int
compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, const NODE *line_node, int popped,
const rb_iseq_t *parent_block, LINK_ANCHOR *args, const char *builtin_func)
{
- NODE *args_node = get_nd_args(node);
+ NODE *args_node = node->nd_args;
if (parent_block != NULL) {
- COMPILE_ERROR(ERROR_ARGS_AT(line_node) "should not call builtins here.");
+ COMPILE_ERROR(iseq, nd_line(line_node), "should not call builtins here.");
return COMPILE_NG;
}
else {
# define BUILTIN_INLINE_PREFIX "_bi"
- char inline_func[sizeof(BUILTIN_INLINE_PREFIX) + DECIMAL_SIZE_OF(int)];
+ char inline_func[DECIMAL_SIZE_OF_BITS(sizeof(int) * CHAR_BIT) + sizeof(BUILTIN_INLINE_PREFIX)];
bool cconst = false;
retry:;
const struct rb_builtin_function *bf = iseq_builtin_function_lookup(iseq, builtin_func);
@@ -8623,7 +8338,9 @@ compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD
return COMPILE_OK;
}
else if (strcmp("attr!", builtin_func) == 0) {
- return compile_builtin_attr(iseq, args_node);
+ // There's only "inline" attribute for now
+ ISEQ_BODY(iseq)->builtin_inline_p = true;
+ return COMPILE_OK;
}
else if (strcmp("arg!", builtin_func) == 0) {
return compile_builtin_arg(iseq, ret, args_node, line_node, popped);
@@ -8699,7 +8416,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
*/
DECL_ANCHOR(recv);
DECL_ANCHOR(args);
- ID mid = get_node_call_nd_mid(node);
+ ID mid = node->nd_mid;
VALUE argc;
unsigned int flag = 0;
struct rb_callinfo_kwarg *keywords = NULL;
@@ -8778,7 +8495,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
const char *builtin_func;
if (UNLIKELY(iseq_has_builtin_function_table(iseq)) &&
- (builtin_func = iseq_builtin_function_name(type, get_nd_recv(node), mid)) != NULL) {
+ (builtin_func = iseq_builtin_function_name(type, node->nd_recv, mid)) != NULL) {
return compile_builtin_function_call(iseq, ret, node, line_node, popped, parent_block, args, builtin_func);
}
@@ -8788,16 +8505,16 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
int idx, level;
if (mid == idCall &&
- nd_type_p(get_nd_recv(node), NODE_LVAR) &&
- iseq_block_param_id_p(iseq, RNODE_LVAR(get_nd_recv(node))->nd_vid, &idx, &level)) {
- ADD_INSN2(recv, get_nd_recv(node), getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ nd_type_p(node->nd_recv, NODE_LVAR) &&
+ iseq_block_param_id_p(iseq, node->nd_recv->nd_vid, &idx, &level)) {
+ ADD_INSN2(recv, node->nd_recv, getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
}
else if (private_recv_p(node)) {
ADD_INSN(recv, node, putself);
flag |= VM_CALL_FCALL;
}
else {
- CHECK(COMPILE(recv, "recv", get_nd_recv(node)));
+ CHECK(COMPILE(recv, "recv", node->nd_recv));
}
if (type == NODE_QCALL) {
@@ -8811,7 +8528,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
/* args */
if (type != NODE_VCALL) {
- argc = setup_args(iseq, args, get_nd_args(node), &flag, &keywords);
+ argc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
CHECK(!NIL_P(argc));
}
else {
@@ -8832,9 +8549,6 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
flag |= VM_CALL_FCALL;
}
- if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) {
- ADD_INSN(ret, line_node, splatkw);
- }
ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords);
qcall_branch_end(iseq, ret, else_label, branches, node, line_node);
@@ -8851,10 +8565,8 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
VALUE argc;
unsigned int flag = 0;
int asgnflag = 0;
- ID id = RNODE_OP_ASGN1(node)->nd_mid;
+ ID id = node->nd_mid;
int boff = 0;
- int keyword_len = 0;
- struct rb_callinfo_kwarg *keywords = NULL;
/*
* a[x] (op)= y
@@ -8882,9 +8594,9 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
if (!popped) {
ADD_INSN(ret, node, putnil);
}
- asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node, RNODE_OP_ASGN1(node)->nd_recv);
+ asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node);
CHECK(asgnflag != -1);
- switch (nd_type(RNODE_OP_ASGN1(node)->nd_index)) {
+ switch (nd_type(node->nd_args->nd_head)) {
case NODE_ZLIST:
argc = INT2FIX(0);
break;
@@ -8892,28 +8604,12 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
boff = 1;
/* fall through */
default:
- argc = setup_args(iseq, ret, RNODE_OP_ASGN1(node)->nd_index, &flag, &keywords);
- if (flag & VM_CALL_KW_SPLAT) {
- if (boff) {
- ADD_INSN(ret, node, splatkw);
- }
- else {
- /* Make sure to_hash is only called once and not twice */
- ADD_INSN(ret, node, dup);
- ADD_INSN(ret, node, splatkw);
- ADD_INSN(ret, node, pop);
- }
- }
+ argc = setup_args(iseq, ret, node->nd_args->nd_head, &flag, NULL);
CHECK(!NIL_P(argc));
}
- int dup_argn = FIX2INT(argc) + 1 + boff;
- if (keywords) {
- keyword_len = keywords->keyword_len;
- dup_argn += keyword_len;
- }
- ADD_INSN1(ret, node, dupn, INT2FIX(dup_argn));
+ ADD_INSN1(ret, node, dupn, FIXNUM_INC(argc, 1 + boff));
flag |= asgnflag;
- ADD_SEND_R(ret, node, idAREF, argc, NULL, INT2FIX(flag & ~VM_CALL_KW_SPLAT_MUT), keywords);
+ ADD_SEND_WITH_FLAG(ret, node, idAREF, argc, INT2FIX(flag));
if (id == idOROP || id == idANDOP) {
/* a[x] ||= y or a[x] &&= y
@@ -8936,116 +8632,64 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
}
ADD_INSN(ret, node, pop);
- CHECK(COMPILE(ret, "NODE_OP_ASGN1 nd_rvalue: ", RNODE_OP_ASGN1(node)->nd_rvalue));
+ CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
if (!popped) {
- ADD_INSN1(ret, node, setn, INT2FIX(dup_argn+1));
+ ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff));
}
if (flag & VM_CALL_ARGS_SPLAT) {
- if (flag & VM_CALL_KW_SPLAT) {
- ADD_INSN1(ret, node, topn, INT2FIX(2 + boff));
+ ADD_INSN1(ret, node, newarray, INT2FIX(1));
+ if (boff > 0) {
+ ADD_INSN1(ret, node, dupn, INT2FIX(3));
ADD_INSN(ret, node, swap);
- ADD_INSN1(ret, node, newarray, INT2FIX(1));
- ADD_INSN(ret, node, concatarray);
- ADD_INSN1(ret, node, setn, INT2FIX(2 + boff));
ADD_INSN(ret, node, pop);
}
- else {
- ADD_INSN1(ret, node, newarray, INT2FIX(1));
- if (boff > 0) {
- ADD_INSN1(ret, node, dupn, INT2FIX(3));
- ADD_INSN(ret, node, swap);
- ADD_INSN(ret, node, pop);
- }
- ADD_INSN(ret, node, concatarray);
- if (boff > 0) {
- ADD_INSN1(ret, node, setn, INT2FIX(3));
- ADD_INSN(ret, node, pop);
- ADD_INSN(ret, node, pop);
- }
- }
- ADD_SEND_R(ret, node, idASET, argc, NULL, INT2FIX(flag), keywords);
- }
- else if (flag & VM_CALL_KW_SPLAT) {
+ ADD_INSN(ret, node, concatarray);
if (boff > 0) {
- ADD_INSN1(ret, node, topn, INT2FIX(2));
- ADD_INSN(ret, node, swap);
ADD_INSN1(ret, node, setn, INT2FIX(3));
ADD_INSN(ret, node, pop);
+ ADD_INSN(ret, node, pop);
}
- ADD_INSN(ret, node, swap);
- ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
- }
- else if (keyword_len) {
- ADD_INSN1(ret, node, opt_reverse, INT2FIX(keyword_len+boff+1));
- ADD_INSN1(ret, node, opt_reverse, INT2FIX(keyword_len+boff+0));
- ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
+ ADD_SEND_WITH_FLAG(ret, node, idASET, argc, INT2FIX(flag));
}
else {
if (boff > 0)
ADD_INSN(ret, node, swap);
- ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
+ ADD_SEND_WITH_FLAG(ret, node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
}
ADD_INSN(ret, node, pop);
ADD_INSNL(ret, node, jump, lfin);
ADD_LABEL(ret, label);
if (!popped) {
- ADD_INSN1(ret, node, setn, INT2FIX(dup_argn+1));
+ ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff));
}
- ADD_INSN1(ret, node, adjuststack, INT2FIX(dup_argn+1));
+ ADD_INSN1(ret, node, adjuststack, FIXNUM_INC(argc, 2+boff));
ADD_LABEL(ret, lfin);
}
else {
- CHECK(COMPILE(ret, "NODE_OP_ASGN1 nd_rvalue: ", RNODE_OP_ASGN1(node)->nd_rvalue));
+ CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
ADD_SEND(ret, node, id, INT2FIX(1));
if (!popped) {
- ADD_INSN1(ret, node, setn, INT2FIX(dup_argn+1));
+ ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff));
}
if (flag & VM_CALL_ARGS_SPLAT) {
- if (flag & VM_CALL_KW_SPLAT) {
- ADD_INSN1(ret, node, topn, INT2FIX(2 + boff));
+ ADD_INSN1(ret, node, newarray, INT2FIX(1));
+ if (boff > 0) {
+ ADD_INSN1(ret, node, dupn, INT2FIX(3));
ADD_INSN(ret, node, swap);
- ADD_INSN1(ret, node, newarray, INT2FIX(1));
- ADD_INSN(ret, node, concatarray);
- ADD_INSN1(ret, node, setn, INT2FIX(2 + boff));
ADD_INSN(ret, node, pop);
}
- else {
- ADD_INSN1(ret, node, newarray, INT2FIX(1));
- if (boff > 0) {
- ADD_INSN1(ret, node, dupn, INT2FIX(3));
- ADD_INSN(ret, node, swap);
- ADD_INSN(ret, node, pop);
- }
- ADD_INSN(ret, node, concatarray);
- if (boff > 0) {
- ADD_INSN1(ret, node, setn, INT2FIX(3));
- ADD_INSN(ret, node, pop);
- ADD_INSN(ret, node, pop);
- }
- }
- ADD_SEND_R(ret, node, idASET, argc, NULL, INT2FIX(flag), keywords);
- }
- else if (flag & VM_CALL_KW_SPLAT) {
+ ADD_INSN(ret, node, concatarray);
if (boff > 0) {
- ADD_INSN1(ret, node, topn, INT2FIX(2));
- ADD_INSN(ret, node, swap);
ADD_INSN1(ret, node, setn, INT2FIX(3));
ADD_INSN(ret, node, pop);
+ ADD_INSN(ret, node, pop);
}
- ADD_INSN(ret, node, swap);
- ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
- }
- else if (keyword_len) {
- ADD_INSN(ret, node, dup);
- ADD_INSN1(ret, node, opt_reverse, INT2FIX(keyword_len+boff+2));
- ADD_INSN1(ret, node, opt_reverse, INT2FIX(keyword_len+boff+1));
- ADD_INSN(ret, node, pop);
- ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
+ ADD_SEND_WITH_FLAG(ret, node, idASET, argc, INT2FIX(flag));
}
else {
if (boff > 0)
ADD_INSN(ret, node, swap);
- ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
+ ADD_SEND_WITH_FLAG(ret, node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
}
ADD_INSN(ret, node, pop);
}
@@ -9056,8 +8700,8 @@ static int
compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
const int line = nd_line(node);
- ID atype = RNODE_OP_ASGN2(node)->nd_mid;
- ID vid = RNODE_OP_ASGN2(node)->nd_vid, aid = rb_id_attrset(vid);
+ ID atype = node->nd_next->nd_mid;
+ ID vid = node->nd_next->nd_vid, aid = rb_id_attrset(vid);
int asgnflag;
LABEL *lfin = NEW_LABEL(line);
LABEL *lcfin = NEW_LABEL(line);
@@ -9115,9 +8759,9 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
*/
- asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node, RNODE_OP_ASGN2(node)->nd_recv);
+ asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node);
CHECK(asgnflag != -1);
- if (RNODE_OP_ASGN2(node)->nd_aid) {
+ if (node->nd_next->nd_aid) {
lskip = NEW_LABEL(line);
ADD_INSN(ret, node, dup);
ADD_INSNL(ret, node, branchnil, lskip);
@@ -9138,7 +8782,7 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
if (!popped) {
ADD_INSN(ret, node, pop);
}
- CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", RNODE_OP_ASGN2(node)->nd_value));
+ CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value));
if (!popped) {
ADD_INSN(ret, node, swap);
ADD_INSN1(ret, node, topn, INT2FIX(1));
@@ -9154,7 +8798,7 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
ADD_LABEL(ret, lfin);
}
else {
- CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", RNODE_OP_ASGN2(node)->nd_value));
+ CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value));
ADD_SEND(ret, node, atype, INT2FIX(1));
if (!popped) {
ADD_INSN(ret, node, swap);
@@ -9180,21 +8824,21 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
LABEL *lassign = 0;
ID mid;
- switch (nd_type(RNODE_OP_CDECL(node)->nd_head)) {
+ switch (nd_type(node->nd_head)) {
case NODE_COLON3:
ADD_INSN1(ret, node, putobject, rb_cObject);
break;
case NODE_COLON2:
- CHECK(COMPILE(ret, "NODE_OP_CDECL/colon2#nd_head", RNODE_COLON2(RNODE_OP_CDECL(node)->nd_head)->nd_head));
+ CHECK(COMPILE(ret, "NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head));
break;
default:
COMPILE_ERROR(ERROR_ARGS "%s: invalid node in NODE_OP_CDECL",
- ruby_node_name(nd_type(RNODE_OP_CDECL(node)->nd_head)));
+ ruby_node_name(nd_type(node->nd_head)));
return COMPILE_NG;
}
- mid = get_node_colon_nd_mid(RNODE_OP_CDECL(node)->nd_head);
+ mid = node->nd_head->nd_mid;
/* cref */
- if (RNODE_OP_CDECL(node)->nd_aid == idOROP) {
+ if (node->nd_aid == idOROP) {
lassign = NEW_LABEL(line);
ADD_INSN(ret, node, dup); /* cref cref */
ADD_INSN3(ret, node, defined, INT2FIX(DEFINED_CONST_FROM),
@@ -9205,17 +8849,17 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
ADD_INSN1(ret, node, putobject, Qtrue);
ADD_INSN1(ret, node, getconstant, ID2SYM(mid)); /* cref obj */
- if (RNODE_OP_CDECL(node)->nd_aid == idOROP || RNODE_OP_CDECL(node)->nd_aid == idANDOP) {
+ if (node->nd_aid == idOROP || node->nd_aid == idANDOP) {
lfin = NEW_LABEL(line);
if (!popped) ADD_INSN(ret, node, dup); /* cref [obj] obj */
- if (RNODE_OP_CDECL(node)->nd_aid == idOROP)
+ if (node->nd_aid == idOROP)
ADD_INSNL(ret, node, branchif, lfin);
else /* idANDOP */
ADD_INSNL(ret, node, branchunless, lfin);
/* cref [obj] */
if (!popped) ADD_INSN(ret, node, pop); /* cref */
if (lassign) ADD_LABEL(ret, lassign);
- CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", RNODE_OP_CDECL(node)->nd_value));
+ CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", node->nd_value));
/* cref value */
if (popped)
ADD_INSN1(ret, node, topn, INT2FIX(1)); /* cref value cref */
@@ -9229,9 +8873,9 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
ADD_INSN(ret, node, pop); /* [value] */
}
else {
- CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", RNODE_OP_CDECL(node)->nd_value));
+ CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", node->nd_value));
/* cref obj value */
- ADD_CALL(ret, node, RNODE_OP_CDECL(node)->nd_aid, INT2FIX(1));
+ ADD_CALL(ret, node, node->nd_aid, INT2FIX(1));
/* cref value */
ADD_INSN(ret, node, swap); /* value cref */
if (!popped) {
@@ -9250,11 +8894,11 @@ compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
LABEL *lfin = NEW_LABEL(line);
LABEL *lassign;
- if (type == NODE_OP_ASGN_OR && !nd_type_p(RNODE_OP_ASGN_OR(node)->nd_head, NODE_IVAR)) {
+ if (type == NODE_OP_ASGN_OR && !nd_type_p(node->nd_head, NODE_IVAR)) {
LABEL *lfinish[2];
lfinish[0] = lfin;
lfinish[1] = 0;
- defined_expr(iseq, ret, RNODE_OP_ASGN_OR(node)->nd_head, lfinish, Qfalse);
+ defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
lassign = lfinish[1];
if (!lassign) {
lassign = NEW_LABEL(line);
@@ -9265,7 +8909,7 @@ compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
lassign = NEW_LABEL(line);
}
- CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", RNODE_OP_ASGN_OR(node)->nd_head));
+ CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head));
if (!popped) {
ADD_INSN(ret, node, dup);
@@ -9283,7 +8927,7 @@ compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
}
ADD_LABEL(ret, lassign);
- CHECK(COMPILE_(ret, "NODE_OP_ASGN_AND/OR#nd_value", RNODE_OP_ASGN_OR(node)->nd_value, popped));
+ CHECK(COMPILE_(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value, popped));
ADD_LABEL(ret, lfin);
return COMPILE_OK;
}
@@ -9301,12 +8945,9 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
INIT_ANCHOR(args);
ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
if (type == NODE_SUPER) {
- VALUE vargc = setup_args(iseq, args, RNODE_SUPER(node)->nd_args, &flag, &keywords);
+ VALUE vargc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
CHECK(!NIL_P(vargc));
argc = FIX2INT(vargc);
- if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) {
- ADD_INSN(args, node, splatkw);
- }
}
else {
/* NODE_ZSUPER */
@@ -9377,11 +9018,14 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
if (local_body->param.flags.has_kwrest) {
int idx = local_body->local_table_size - local_kwd->rest_start;
ADD_GETLOCAL(args, node, idx, lvar_level);
- assert(local_kwd->num > 0);
- ADD_SEND (args, node, rb_intern("dup"), INT2FIX(0));
+ if (local_kwd->num > 0) {
+ ADD_SEND (args, node, rb_intern("dup"), INT2FIX(0));
+ flag |= VM_CALL_KW_SPLAT_MUT;
+ }
}
else {
ADD_INSN1(args, node, newhash, INT2FIX(0));
+ flag |= VM_CALL_KW_SPLAT_MUT;
}
for (i = 0; i < local_kwd->num; ++i) {
ID id = local_kwd->table[i];
@@ -9390,12 +9034,24 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
ADD_GETLOCAL(args, node, idx, lvar_level);
}
ADD_SEND(args, node, id_core_hash_merge_ptr, INT2FIX(i * 2 + 1));
- flag |= VM_CALL_KW_SPLAT| VM_CALL_KW_SPLAT_MUT;
+ if (local_body->param.flags.has_rest) {
+ ADD_INSN1(args, node, newarray, INT2FIX(1));
+ ADD_INSN (args, node, concatarray);
+ --argc;
+ }
+ flag |= VM_CALL_KW_SPLAT;
}
else if (local_body->param.flags.has_kwrest) {
int idx = local_body->local_table_size - local_kwd->rest_start;
ADD_GETLOCAL(args, node, idx, lvar_level);
- argc++;
+
+ if (local_body->param.flags.has_rest) {
+ ADD_INSN1(args, node, newarray, INT2FIX(1));
+ ADD_INSN (args, node, concatarray);
+ }
+ else {
+ argc++;
+ }
flag |= VM_CALL_KW_SPLAT;
}
}
@@ -9433,8 +9089,8 @@ compile_yield(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
default: /* valid */;
}
- if (RNODE_YIELD(node)->nd_head) {
- argc = setup_args(iseq, args, RNODE_YIELD(node)->nd_head, &flag, &keywords);
+ if (node->nd_head) {
+ argc = setup_args(iseq, args, node->nd_head, &flag, &keywords);
CHECK(!NIL_P(argc));
}
else {
@@ -9468,17 +9124,17 @@ compile_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
INIT_ANCHOR(val);
switch ((int)type) {
case NODE_MATCH:
- ADD_INSN1(recv, node, putobject, RNODE_MATCH(node)->nd_lit);
+ ADD_INSN1(recv, node, putobject, node->nd_lit);
ADD_INSN2(val, node, getspecial, INT2FIX(0),
INT2FIX(0));
break;
case NODE_MATCH2:
- CHECK(COMPILE(recv, "receiver", RNODE_MATCH2(node)->nd_recv));
- CHECK(COMPILE(val, "value", RNODE_MATCH2(node)->nd_value));
+ CHECK(COMPILE(recv, "receiver", node->nd_recv));
+ CHECK(COMPILE(val, "value", node->nd_value));
break;
case NODE_MATCH3:
- CHECK(COMPILE(recv, "receiver", RNODE_MATCH3(node)->nd_value));
- CHECK(COMPILE(val, "value", RNODE_MATCH3(node)->nd_recv));
+ CHECK(COMPILE(recv, "receiver", node->nd_value));
+ CHECK(COMPILE(val, "value", node->nd_recv));
break;
}
@@ -9486,8 +9142,8 @@ compile_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
ADD_SEQ(ret, val);
ADD_SEND(ret, node, idEqTilde, INT2FIX(1));
- if (nd_type_p(node, NODE_MATCH2) && RNODE_MATCH2(node)->nd_args) {
- compile_named_capture_assign(iseq, ret, RNODE_MATCH2(node)->nd_args);
+ if (node->nd_args) {
+ compile_named_capture_assign(iseq, ret, node->nd_args);
}
if (popped) {
@@ -9499,7 +9155,7 @@ compile_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
static int
compile_colon2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
- if (rb_is_const_id(RNODE_COLON2(node)->nd_mid)) {
+ if (rb_is_const_id(node->nd_mid)) {
/* constant */
VALUE segments;
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache &&
@@ -9529,8 +9185,8 @@ compile_colon2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
else {
/* function call */
ADD_CALL_RECEIVER(ret, node);
- CHECK(COMPILE(ret, "colon2#nd_head", RNODE_COLON2(node)->nd_head));
- ADD_CALL(ret, node, RNODE_COLON2(node)->nd_mid, INT2FIX(1));
+ CHECK(COMPILE(ret, "colon2#nd_head", node->nd_head));
+ ADD_CALL(ret, node, node->nd_mid, INT2FIX(1));
}
if (popped) {
ADD_INSN(ret, node, pop);
@@ -9541,19 +9197,19 @@ compile_colon2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
static int
compile_colon3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
- debugi("colon3#nd_mid", RNODE_COLON3(node)->nd_mid);
+ debugi("colon3#nd_mid", node->nd_mid);
/* add cache insn */
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
ISEQ_BODY(iseq)->ic_size++;
- VALUE segments = rb_ary_new_from_args(2, ID2SYM(idNULL), ID2SYM(RNODE_COLON3(node)->nd_mid));
+ VALUE segments = rb_ary_new_from_args(2, ID2SYM(idNULL), ID2SYM(node->nd_mid));
ADD_INSN1(ret, node, opt_getconstant_path, segments);
RB_OBJ_WRITTEN(iseq, Qundef, segments);
}
else {
ADD_INSN1(ret, node, putobject, rb_cObject);
ADD_INSN1(ret, node, putobject, Qtrue);
- ADD_INSN1(ret, node, getconstant, ID2SYM(RNODE_COLON3(node)->nd_mid));
+ ADD_INSN1(ret, node, getconstant, ID2SYM(node->nd_mid));
}
if (popped) {
@@ -9566,13 +9222,13 @@ static int
compile_dots(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const int excl)
{
VALUE flag = INT2FIX(excl);
- const NODE *b = RNODE_DOT2(node)->nd_beg;
- const NODE *e = RNODE_DOT2(node)->nd_end;
+ const NODE *b = node->nd_beg;
+ const NODE *e = node->nd_end;
if (optimizable_range_item_p(b) && optimizable_range_item_p(e)) {
if (!popped) {
- VALUE bv = nd_type_p(b, NODE_LIT) ? RNODE_LIT(b)->nd_lit : Qnil;
- VALUE ev = nd_type_p(e, NODE_LIT) ? RNODE_LIT(e)->nd_lit : Qnil;
+ VALUE bv = nd_type_p(b, NODE_LIT) ? b->nd_lit : Qnil;
+ VALUE ev = nd_type_p(e, NODE_LIT) ? e->nd_lit : Qnil;
VALUE val = rb_range_new(bv, ev, excl);
ADD_INSN1(ret, node, putobject, val);
RB_OBJ_WRITTEN(iseq, Qundef, val);
@@ -9621,7 +9277,7 @@ compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
{
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
LABEL *end_label = NEW_LABEL(nd_line(node));
- const NODE *default_value = get_nd_value(RNODE_KW_ARG(node)->nd_body);
+ const NODE *default_value = node->nd_body->nd_value;
if (default_value == NODE_SPECIAL_REQUIRED_KEYWORD) {
/* required argument. do nothing */
@@ -9645,7 +9301,7 @@ compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
ADD_INSN2(ret, node, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(keyword_idx));
ADD_INSNL(ret, node, branchif, end_label);
- CHECK(COMPILE_POPPED(ret, "keyword default argument", RNODE_KW_ARG(node)->nd_body));
+ CHECK(COMPILE_POPPED(ret, "keyword default argument", node->nd_body));
ADD_LABEL(ret, end_label);
}
return COMPILE_OK;
@@ -9657,7 +9313,7 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
DECL_ANCHOR(recv);
DECL_ANCHOR(args);
unsigned int flag = 0;
- ID mid = RNODE_ATTRASGN(node)->nd_mid;
+ ID mid = node->nd_mid;
VALUE argc;
LABEL *else_label = NULL;
VALUE branches = Qfalse;
@@ -9665,16 +9321,17 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
/* optimization shortcut
* obj["literal"] = value -> opt_aset_with(obj, "literal", value)
*/
- if (mid == idASET && !private_recv_p(node) && RNODE_ATTRASGN(node)->nd_args &&
- nd_type_p(RNODE_ATTRASGN(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->as.nd_alen == 2 &&
- nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) &&
+ if (!ISEQ_COMPILE_DATA(iseq)->in_masgn &&
+ mid == idASET && !private_recv_p(node) && node->nd_args &&
+ nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 2 &&
+ nd_type_p(node->nd_args->nd_head, NODE_STR) &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction)
{
- VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head)->nd_lit);
- CHECK(COMPILE(ret, "recv", RNODE_ATTRASGN(node)->nd_recv));
- CHECK(COMPILE(ret, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head));
+ VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
+ CHECK(COMPILE(ret, "recv", node->nd_recv));
+ CHECK(COMPILE(ret, "value", node->nd_args->nd_next->nd_head));
if (!popped) {
ADD_INSN(ret, node, swap);
ADD_INSN1(ret, node, topn, INT2FIX(1));
@@ -9688,10 +9345,10 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
INIT_ANCHOR(recv);
INIT_ANCHOR(args);
- argc = setup_args(iseq, args, RNODE_ATTRASGN(node)->nd_args, &flag, NULL);
+ argc = setup_args(iseq, args, node->nd_args, &flag, NULL);
CHECK(!NIL_P(argc));
- int asgnflag = COMPILE_RECV(recv, "recv", node, RNODE_ATTRASGN(node)->nd_recv);
+ int asgnflag = COMPILE_RECV(recv, "recv", node);
CHECK(asgnflag != -1);
flag |= (unsigned int)asgnflag;
@@ -9773,7 +9430,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
/* ignore */
}
else {
- if (nd_fl_newline(node)) {
+ if (node->flags & NODE_FL_NEWLINE) {
int event = RUBY_EVENT_LINE;
ISEQ_COMPILE_DATA(iseq)->last_line = line;
if (ISEQ_COVERAGE(iseq) && ISEQ_LINE_COVERAGE(iseq)) {
@@ -9828,7 +9485,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
CHECK(compile_retry(iseq, ret, node, popped));
break;
case NODE_BEGIN:{
- CHECK(COMPILE_(ret, "NODE_BEGIN", RNODE_BEGIN(node)->nd_body, popped));
+ CHECK(COMPILE_(ret, "NODE_BEGIN", node->nd_body, popped));
break;
}
case NODE_RESCUE:
@@ -9844,7 +9501,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
case NODE_AND:
case NODE_OR:{
LABEL *end_label = NEW_LABEL(line);
- CHECK(COMPILE(ret, "nd_1st", RNODE_OR(node)->nd_1st));
+ CHECK(COMPILE(ret, "nd_1st", node->nd_1st));
if (!popped) {
ADD_INSN(ret, node, dup);
}
@@ -9857,22 +9514,25 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
if (!popped) {
ADD_INSN(ret, node, pop);
}
- CHECK(COMPILE_(ret, "nd_2nd", RNODE_OR(node)->nd_2nd, popped));
+ CHECK(COMPILE_(ret, "nd_2nd", node->nd_2nd, popped));
ADD_LABEL(ret, end_label);
break;
}
case NODE_MASGN:{
+ bool prev_in_masgn = ISEQ_COMPILE_DATA(iseq)->in_masgn;
+ ISEQ_COMPILE_DATA(iseq)->in_masgn = true;
compile_massign(iseq, ret, node, popped);
+ ISEQ_COMPILE_DATA(iseq)->in_masgn = prev_in_masgn;
break;
}
case NODE_LASGN:{
- ID id = RNODE_LASGN(node)->nd_vid;
+ ID id = node->nd_vid;
int idx = ISEQ_BODY(body->local_iseq)->local_table_size - get_local_var_idx(iseq, id);
debugs("lvar: %s idx: %d\n", rb_id2name(id), idx);
- CHECK(COMPILE(ret, "rvalue", RNODE_LASGN(node)->nd_value));
+ CHECK(COMPILE(ret, "rvalue", node->nd_value));
if (!popped) {
ADD_INSN(ret, node, dup);
@@ -9882,8 +9542,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_DASGN: {
int idx, lv, ls;
- ID id = RNODE_DASGN(node)->nd_vid;
- CHECK(COMPILE(ret, "dvalue", RNODE_DASGN(node)->nd_value));
+ ID id = node->nd_vid;
+ CHECK(COMPILE(ret, "dvalue", node->nd_value));
debugi("dassn id", rb_id2str(id) ? id : '*');
if (!popped) {
@@ -9901,27 +9561,27 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_GASGN:{
- CHECK(COMPILE(ret, "lvalue", RNODE_GASGN(node)->nd_value));
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
if (!popped) {
ADD_INSN(ret, node, dup);
}
- ADD_INSN1(ret, node, setglobal, ID2SYM(RNODE_GASGN(node)->nd_vid));
+ ADD_INSN1(ret, node, setglobal, ID2SYM(node->nd_entry));
break;
}
case NODE_IASGN:{
- CHECK(COMPILE(ret, "lvalue", RNODE_IASGN(node)->nd_value));
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
if (!popped) {
ADD_INSN(ret, node, dup);
}
ADD_INSN2(ret, node, setinstancevariable,
- ID2SYM(RNODE_IASGN(node)->nd_vid),
- get_ivar_ic_value(iseq,RNODE_IASGN(node)->nd_vid));
+ ID2SYM(node->nd_vid),
+ get_ivar_ic_value(iseq,node->nd_vid));
break;
}
case NODE_CDECL:{
- if (RNODE_CDECL(node)->nd_vid) {
- CHECK(COMPILE(ret, "lvalue", RNODE_CDECL(node)->nd_value));
+ if (node->nd_vid) {
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
if (!popped) {
ADD_INSN(ret, node, dup);
@@ -9929,11 +9589,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
ADD_INSN1(ret, node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, node, setconstant, ID2SYM(RNODE_CDECL(node)->nd_vid));
+ ADD_INSN1(ret, node, setconstant, ID2SYM(node->nd_vid));
}
else {
- compile_cpath(ret, iseq, RNODE_CDECL(node)->nd_else);
- CHECK(COMPILE(ret, "lvalue", RNODE_CDECL(node)->nd_value));
+ compile_cpath(ret, iseq, node->nd_else);
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
ADD_INSN(ret, node, swap);
if (!popped) {
@@ -9941,18 +9601,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
ADD_INSN(ret, node, swap);
}
- ADD_INSN1(ret, node, setconstant, ID2SYM(get_node_colon_nd_mid(RNODE_CDECL(node)->nd_else)));
+ ADD_INSN1(ret, node, setconstant, ID2SYM(node->nd_else->nd_mid));
}
break;
}
case NODE_CVASGN:{
- CHECK(COMPILE(ret, "cvasgn val", RNODE_CVASGN(node)->nd_value));
+ CHECK(COMPILE(ret, "cvasgn val", node->nd_value));
if (!popped) {
ADD_INSN(ret, node, dup);
}
ADD_INSN2(ret, node, setclassvariable,
- ID2SYM(RNODE_CVASGN(node)->nd_vid),
- get_cvar_ic_value(iseq, RNODE_CVASGN(node)->nd_vid));
+ ID2SYM(node->nd_vid),
+ get_cvar_ic_value(iseq,node->nd_vid));
break;
}
case NODE_OP_ASGN1:
@@ -9994,6 +9654,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
break;
}
+ case NODE_VALUES:{
+ const NODE *n = node;
+ if (popped) {
+ COMPILE_ERROR(ERROR_ARGS "NODE_VALUES: must not be popped");
+ }
+ while (n) {
+ CHECK(COMPILE(ret, "values item", n->nd_head));
+ n = n->nd_next;
+ }
+ ADD_INSN1(ret, node, newarray, INT2FIX(node->nd_alen));
+ break;
+ }
case NODE_HASH:
CHECK(compile_hash(iseq, ret, node, FALSE, popped) >= 0);
break;
@@ -10005,18 +9677,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
case NODE_LVAR:{
if (!popped) {
- compile_lvar(iseq, ret, node, RNODE_LVAR(node)->nd_vid);
+ compile_lvar(iseq, ret, node, node->nd_vid);
}
break;
}
case NODE_DVAR:{
int lv, idx, ls;
- debugi("nd_vid", RNODE_DVAR(node)->nd_vid);
+ debugi("nd_vid", node->nd_vid);
if (!popped) {
- idx = get_dyna_var_idx(iseq, RNODE_DVAR(node)->nd_vid, &lv, &ls);
+ idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
if (idx < 0) {
COMPILE_ERROR(ERROR_ARGS "unknown dvar (%"PRIsVALUE")",
- rb_id2str(RNODE_DVAR(node)->nd_vid));
+ rb_id2str(node->nd_vid));
goto ng;
}
ADD_GETLOCAL(ret, node, ls - idx, lv);
@@ -10024,34 +9696,34 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_GVAR:{
- ADD_INSN1(ret, node, getglobal, ID2SYM(RNODE_GVAR(node)->nd_vid));
+ ADD_INSN1(ret, node, getglobal, ID2SYM(node->nd_entry));
if (popped) {
ADD_INSN(ret, node, pop);
}
break;
}
case NODE_IVAR:{
- debugi("nd_vid", RNODE_IVAR(node)->nd_vid);
+ debugi("nd_vid", node->nd_vid);
if (!popped) {
ADD_INSN2(ret, node, getinstancevariable,
- ID2SYM(RNODE_IVAR(node)->nd_vid),
- get_ivar_ic_value(iseq, RNODE_IVAR(node)->nd_vid));
+ ID2SYM(node->nd_vid),
+ get_ivar_ic_value(iseq,node->nd_vid));
}
break;
}
case NODE_CONST:{
- debugi("nd_vid", RNODE_CONST(node)->nd_vid);
+ debugi("nd_vid", node->nd_vid);
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
body->ic_size++;
- VALUE segments = rb_ary_new_from_args(1, ID2SYM(RNODE_CONST(node)->nd_vid));
+ VALUE segments = rb_ary_new_from_args(1, ID2SYM(node->nd_vid));
ADD_INSN1(ret, node, opt_getconstant_path, segments);
RB_OBJ_WRITTEN(iseq, Qundef, segments);
}
else {
ADD_INSN(ret, node, putnil);
ADD_INSN1(ret, node, putobject, Qtrue);
- ADD_INSN1(ret, node, getconstant, ID2SYM(RNODE_CONST(node)->nd_vid));
+ ADD_INSN1(ret, node, getconstant, ID2SYM(node->nd_vid));
}
if (popped) {
@@ -10062,26 +9734,26 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
case NODE_CVAR:{
if (!popped) {
ADD_INSN2(ret, node, getclassvariable,
- ID2SYM(RNODE_CVAR(node)->nd_vid),
- get_cvar_ic_value(iseq, RNODE_CVAR(node)->nd_vid));
+ ID2SYM(node->nd_vid),
+ get_cvar_ic_value(iseq,node->nd_vid));
}
break;
}
case NODE_NTH_REF:{
if (!popped) {
- if (!RNODE_NTH_REF(node)->nd_nth) {
+ if (!node->nd_nth) {
ADD_INSN(ret, node, putnil);
break;
}
ADD_INSN2(ret, node, getspecial, INT2FIX(1) /* '~' */,
- INT2FIX(RNODE_NTH_REF(node)->nd_nth << 1));
+ INT2FIX(node->nd_nth << 1));
}
break;
}
case NODE_BACK_REF:{
if (!popped) {
ADD_INSN2(ret, node, getspecial, INT2FIX(1) /* '~' */,
- INT2FIX(0x01 | (RNODE_BACK_REF(node)->nd_nth << 1)));
+ INT2FIX(0x01 | (node->nd_nth << 1)));
}
break;
}
@@ -10091,17 +9763,22 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
CHECK(compile_match(iseq, ret, node, popped, type));
break;
case NODE_LIT:{
- debugp_param("lit", RNODE_LIT(node)->nd_lit);
+ debugp_param("lit", node->nd_lit);
if (!popped) {
- ADD_INSN1(ret, node, putobject, RNODE_LIT(node)->nd_lit);
- RB_OBJ_WRITTEN(iseq, Qundef, RNODE_LIT(node)->nd_lit);
+ if (UNLIKELY(node->nd_lit == rb_mRubyVMFrozenCore)) {
+ ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); // [Bug #20569]
+ }
+ else {
+ ADD_INSN1(ret, node, putobject, node->nd_lit);
+ }
+ RB_OBJ_WRITTEN(iseq, Qundef, node->nd_lit);
}
break;
}
case NODE_STR:{
- debugp_param("nd_lit", RNODE_STR(node)->nd_lit);
+ debugp_param("nd_lit", node->nd_lit);
if (!popped) {
- VALUE lit = RNODE_STR(node)->nd_lit;
+ VALUE lit = node->nd_lit;
if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
lit = rb_fstring(lit);
ADD_INSN1(ret, node, putstring, lit);
@@ -10133,7 +9810,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_XSTR:{
ADD_CALL_RECEIVER(ret, node);
- VALUE str = rb_fstring(RNODE_XSTR(node)->nd_lit);
+ VALUE str = rb_fstring(node->nd_lit);
ADD_INSN1(ret, node, putobject, str);
RB_OBJ_WRITTEN(iseq, Qundef, str);
ADD_CALL(ret, node, idBackquote, INT2FIX(1));
@@ -10154,15 +9831,20 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_EVSTR:
- CHECK(compile_evstr(iseq, ret, RNODE_EVSTR(node)->nd_body, popped));
+ CHECK(compile_evstr(iseq, ret, node->nd_body, popped));
break;
- case NODE_DREGX:
- compile_dregx(iseq, ret, node, popped);
+ case NODE_DREGX:{
+ compile_dregx(iseq, ret, node);
+
+ if (popped) {
+ ADD_INSN(ret, node, pop);
+ }
break;
+ }
case NODE_ONCE:{
int ic_index = body->ise_size++;
const rb_iseq_t *block_iseq;
- block_iseq = NEW_CHILD_ISEQ(RNODE_ONCE(node)->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line);
+ block_iseq = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line);
ADD_INSN2(ret, node, once, block_iseq, INT2FIX(ic_index));
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block_iseq);
@@ -10174,36 +9856,36 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_ARGSCAT:{
if (popped) {
- CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head));
+ CHECK(COMPILE(ret, "argscat head", node->nd_head));
ADD_INSN1(ret, node, splatarray, Qfalse);
ADD_INSN(ret, node, pop);
- CHECK(COMPILE(ret, "argscat body", RNODE_ARGSCAT(node)->nd_body));
+ CHECK(COMPILE(ret, "argscat body", node->nd_body));
ADD_INSN1(ret, node, splatarray, Qfalse);
ADD_INSN(ret, node, pop);
}
else {
- CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head));
- CHECK(COMPILE(ret, "argscat body", RNODE_ARGSCAT(node)->nd_body));
+ CHECK(COMPILE(ret, "argscat head", node->nd_head));
+ CHECK(COMPILE(ret, "argscat body", node->nd_body));
ADD_INSN(ret, node, concatarray);
}
break;
}
case NODE_ARGSPUSH:{
if (popped) {
- CHECK(COMPILE(ret, "argspush head", RNODE_ARGSPUSH(node)->nd_head));
+ CHECK(COMPILE(ret, "argspush head", node->nd_head));
ADD_INSN1(ret, node, splatarray, Qfalse);
ADD_INSN(ret, node, pop);
- CHECK(COMPILE_(ret, "argspush body", RNODE_ARGSPUSH(node)->nd_body, popped));
+ CHECK(COMPILE_(ret, "argspush body", node->nd_body, popped));
}
else {
- CHECK(COMPILE(ret, "argspush head", RNODE_ARGSPUSH(node)->nd_head));
- CHECK(compile_array_1(iseq, ret, RNODE_ARGSPUSH(node)->nd_body));
+ CHECK(COMPILE(ret, "argspush head", node->nd_head));
+ CHECK(compile_array_1(iseq, ret, node->nd_body));
ADD_INSN(ret, node, concatarray);
}
break;
}
case NODE_SPLAT:{
- CHECK(COMPILE(ret, "splat", RNODE_SPLAT(node)->nd_head));
+ CHECK(COMPILE(ret, "splat", node->nd_head));
ADD_INSN1(ret, node, splatarray, Qtrue);
if (popped) {
@@ -10212,8 +9894,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_DEFN:{
- ID mid = RNODE_DEFN(node)->nd_mid;
- const rb_iseq_t *method_iseq = NEW_ISEQ(RNODE_DEFN(node)->nd_defn,
+ ID mid = node->nd_mid;
+ const rb_iseq_t *method_iseq = NEW_ISEQ(node->nd_defn,
rb_id2str(mid),
ISEQ_TYPE_METHOD, line);
@@ -10228,13 +9910,13 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_DEFS:{
- ID mid = RNODE_DEFS(node)->nd_mid;
- const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(RNODE_DEFS(node)->nd_defn,
+ ID mid = node->nd_mid;
+ const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(node->nd_defn,
rb_id2str(mid),
ISEQ_TYPE_METHOD, line);
debugp_param("defs/iseq", rb_iseqw_new(singleton_method_iseq));
- CHECK(COMPILE(ret, "defs: recv", RNODE_DEFS(node)->nd_recv));
+ CHECK(COMPILE(ret, "defs: recv", node->nd_recv));
ADD_INSN2(ret, node, definesmethod, ID2SYM(mid), singleton_method_iseq);
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_method_iseq);
@@ -10246,8 +9928,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
case NODE_ALIAS:{
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
- CHECK(COMPILE(ret, "alias arg1", RNODE_ALIAS(node)->nd_1st));
- CHECK(COMPILE(ret, "alias arg2", RNODE_ALIAS(node)->nd_2nd));
+ CHECK(COMPILE(ret, "alias arg1", node->nd_1st));
+ CHECK(COMPILE(ret, "alias arg2", node->nd_2nd));
ADD_SEND(ret, node, id_core_set_method_alias, INT2FIX(3));
if (popped) {
@@ -10257,8 +9939,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_VALIAS:{
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, node, putobject, ID2SYM(RNODE_VALIAS(node)->nd_alias));
- ADD_INSN1(ret, node, putobject, ID2SYM(RNODE_VALIAS(node)->nd_orig));
+ ADD_INSN1(ret, node, putobject, ID2SYM(node->nd_alias));
+ ADD_INSN1(ret, node, putobject, ID2SYM(node->nd_orig));
ADD_SEND(ret, node, id_core_set_variable_alias, INT2FIX(2));
if (popped) {
@@ -10269,7 +9951,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
case NODE_UNDEF:{
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
- CHECK(COMPILE(ret, "undef arg", RNODE_UNDEF(node)->nd_undef));
+ CHECK(COMPILE(ret, "undef arg", node->nd_undef));
ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2));
if (popped) {
@@ -10278,15 +9960,15 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_CLASS:{
- const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(RNODE_CLASS(node)->nd_body,
- rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(get_node_colon_nd_mid(RNODE_CLASS(node)->nd_cpath)))),
+ const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(node->nd_body,
+ rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid))),
ISEQ_TYPE_CLASS, line);
const int flags = VM_DEFINECLASS_TYPE_CLASS |
- (RNODE_CLASS(node)->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
- compile_cpath(ret, iseq, RNODE_CLASS(node)->nd_cpath);
+ (node->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
+ compile_cpath(ret, iseq, node->nd_cpath);
- CHECK(COMPILE(ret, "super", RNODE_CLASS(node)->nd_super));
- ADD_INSN3(ret, node, defineclass, ID2SYM(get_node_colon_nd_mid(RNODE_CLASS(node)->nd_cpath)), class_iseq, INT2FIX(flags));
+ CHECK(COMPILE(ret, "super", node->nd_super));
+ ADD_INSN3(ret, node, defineclass, ID2SYM(node->nd_cpath->nd_mid), class_iseq, INT2FIX(flags));
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq);
if (popped) {
@@ -10295,14 +9977,14 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_MODULE:{
- const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(RNODE_MODULE(node)->nd_body,
- rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(get_node_colon_nd_mid(RNODE_MODULE(node)->nd_cpath)))),
+ const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(node->nd_body,
+ rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid))),
ISEQ_TYPE_CLASS, line);
const int flags = VM_DEFINECLASS_TYPE_MODULE |
- compile_cpath(ret, iseq, RNODE_MODULE(node)->nd_cpath);
+ compile_cpath(ret, iseq, node->nd_cpath);
ADD_INSN (ret, node, putnil); /* dummy */
- ADD_INSN3(ret, node, defineclass, ID2SYM(get_node_colon_nd_mid(RNODE_MODULE(node)->nd_cpath)), module_iseq, INT2FIX(flags));
+ ADD_INSN3(ret, node, defineclass, ID2SYM(node->nd_cpath->nd_mid), module_iseq, INT2FIX(flags));
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq);
if (popped) {
@@ -10312,10 +9994,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_SCLASS:{
ID singletonclass;
- const rb_iseq_t *singleton_class = NEW_ISEQ(RNODE_SCLASS(node)->nd_body, rb_fstring_lit("singleton class"),
+ const rb_iseq_t *singleton_class = NEW_ISEQ(node->nd_body, rb_fstring_lit("singleton class"),
ISEQ_TYPE_CLASS, line);
- CHECK(COMPILE(ret, "sclass#recv", RNODE_SCLASS(node)->nd_recv));
+ CHECK(COMPILE(ret, "sclass#recv", node->nd_recv));
ADD_INSN (ret, node, putnil);
CONST_ID(singletonclass, "singletonclass");
ADD_INSN3(ret, node, defineclass,
@@ -10393,7 +10075,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
*/
int is_index = body->ise_size++;
struct rb_iseq_new_with_callback_callback_func *ifunc =
- rb_iseq_new_with_callback_new_callback(build_postexe_iseq, RNODE_POSTEXE(node)->nd_body);
+ rb_iseq_new_with_callback_new_callback(build_postexe_iseq, node->nd_body);
const rb_iseq_t *once_iseq =
new_child_iseq_with_callback(iseq, ifunc,
rb_fstring(make_name_for_block(iseq)), iseq, ISEQ_TYPE_BLOCK, line);
@@ -10424,7 +10106,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
case NODE_LAMBDA:{
/* compile same as lambda{...} */
- const rb_iseq_t *block = NEW_CHILD_ISEQ(RNODE_LAMBDA(node)->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+ const rb_iseq_t *block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
VALUE argc = INT2FIX(0);
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
@@ -10635,12 +10317,6 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr,
fflush(stdout);
}
-int
-rb_insn_len(VALUE insn)
-{
- return insn_len(insn);
-}
-
const char *
rb_insns_name(int i)
{
@@ -10804,7 +10480,6 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op)
size_t n = rb_callinfo_kwarg_bytes(len);
kw_arg = xmalloc(n);
- kw_arg->references = 0;
kw_arg->keyword_len = len;
for (i = 0; i < len; i++) {
VALUE kw = RARRAY_AREF(vkw_arg, i);
@@ -10830,7 +10505,6 @@ event_name_to_flag(VALUE sym)
CHECK_EVENT(RUBY_EVENT_RETURN);
CHECK_EVENT(RUBY_EVENT_B_CALL);
CHECK_EVENT(RUBY_EVENT_B_RETURN);
- CHECK_EVENT(RUBY_EVENT_RESCUE);
#undef CHECK_EVENT
return RUBY_EVENT_NONE;
}
@@ -11115,13 +10789,13 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
}
static void
-iseq_insn_each_object_mark_and_pin(VALUE obj, VALUE _)
+iseq_insn_each_object_mark(VALUE *obj_ptr, VALUE _)
{
- rb_gc_mark(obj);
+ rb_gc_mark(*obj_ptr);
}
void
-rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *storage)
+rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
{
INSN *iobj = 0;
size_t size = sizeof(INSN);
@@ -11146,7 +10820,7 @@ rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *storage)
iobj = (INSN *)&storage->buff[pos];
if (iobj->operands) {
- iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark_and_pin, (VALUE)0);
+ iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark, (VALUE)0);
}
pos += (int)size;
}
@@ -11319,7 +10993,7 @@ rb_local_defined(ID id, const rb_iseq_t *iseq)
#define IBF_ISEQ_ENABLE_LOCAL_BUFFER 0
#endif
-typedef uint32_t ibf_offset_t;
+typedef unsigned int ibf_offset_t;
#define IBF_OFFSET(ptr) ((ibf_offset_t)(VALUE)(ptr))
#define IBF_MAJOR_VERSION ISEQ_MAJOR_VERSION
@@ -11330,27 +11004,17 @@ typedef uint32_t ibf_offset_t;
#define IBF_MINOR_VERSION ISEQ_MINOR_VERSION
#endif
-static const char IBF_ENDIAN_MARK =
-#ifdef WORDS_BIGENDIAN
- 'b'
-#else
- 'l'
-#endif
- ;
-
struct ibf_header {
char magic[4]; /* YARB */
- uint32_t major_version;
- uint32_t minor_version;
- uint32_t size;
- uint32_t extra_size;
+ unsigned int major_version;
+ unsigned int minor_version;
+ unsigned int size;
+ unsigned int extra_size;
- uint32_t iseq_list_size;
- uint32_t global_object_list_size;
+ unsigned int iseq_list_size;
+ unsigned int global_object_list_size;
ibf_offset_t iseq_list_offset;
ibf_offset_t global_object_list_offset;
- uint8_t endian;
- uint8_t wordsize; /* assume no 2048-bit CPU */
};
struct ibf_dump_buffer {
@@ -11385,7 +11049,7 @@ struct ibf_load {
struct pinned_list {
long size;
- VALUE buffer[1];
+ VALUE * buffer;
};
static void
@@ -11400,14 +11064,25 @@ pinned_list_mark(void *ptr)
}
}
+static void
+pinned_list_free(void *ptr)
+{
+ struct pinned_list *list = (struct pinned_list *)ptr;
+ xfree(list->buffer);
+ xfree(ptr);
+}
+
+static size_t
+pinned_list_memsize(const void *ptr)
+{
+ struct pinned_list *list = (struct pinned_list *)ptr;
+ return sizeof(struct pinned_list) + (list->size * sizeof(VALUE *));
+}
+
static const rb_data_type_t pinned_list_type = {
"pinned_list",
- {
- pinned_list_mark,
- RUBY_DEFAULT_FREE,
- NULL, // No external memory to report,
- },
- 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE
+ {pinned_list_mark, pinned_list_free, pinned_list_memsize,},
+ 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
@@ -11441,10 +11116,13 @@ pinned_list_store(VALUE list, long offset, VALUE object)
static VALUE
pinned_list_new(long size)
{
- size_t memsize = offsetof(struct pinned_list, buffer) + size * sizeof(VALUE);
- VALUE obj_list = rb_data_typed_object_zalloc(0, memsize, &pinned_list_type);
- struct pinned_list * ptr = RTYPEDDATA_GET_DATA(obj_list);
+ struct pinned_list * ptr;
+ VALUE obj_list =
+ TypedData_Make_Struct(0, struct pinned_list, &pinned_list_type, ptr);
+
+ ptr->buffer = xcalloc(size, sizeof(VALUE));
ptr->size = size;
+
return obj_list;
}
@@ -12237,34 +11915,13 @@ ibf_dump_ci_entries(struct ibf_dump *dump, const rb_iseq_t *iseq)
return offset;
}
-struct outer_variable_pair {
- ID id;
- VALUE name;
- VALUE val;
-};
-
-struct outer_variable_list {
- size_t num;
- struct outer_variable_pair pairs[1];
-};
-
static enum rb_id_table_iterator_result
-store_outer_variable(ID id, VALUE val, void *dump)
+dump_outer_variable(ID id, VALUE val, void *dump)
{
- struct outer_variable_list *ovlist = dump;
- struct outer_variable_pair *pair = &ovlist->pairs[ovlist->num++];
- pair->id = id;
- pair->name = rb_id2str(id);
- pair->val = val;
- return ID_TABLE_CONTINUE;
-}
+ ibf_dump_write_small_value(dump, ibf_dump_id(dump, id));
+ ibf_dump_write_small_value(dump, val);
-static int
-outer_variable_cmp(const void *a, const void *b, void *arg)
-{
- const struct outer_variable_pair *ap = (const struct outer_variable_pair *)a;
- const struct outer_variable_pair *bp = (const struct outer_variable_pair *)b;
- return rb_str_cmp(ap->name, bp->name);
+ return ID_TABLE_CONTINUE;
}
static ibf_offset_t
@@ -12274,24 +11931,12 @@ ibf_dump_outer_variables(struct ibf_dump *dump, const rb_iseq_t *iseq)
ibf_offset_t offset = ibf_dump_pos(dump);
- size_t size = ovs ? rb_id_table_size(ovs) : 0;
- ibf_dump_write_small_value(dump, (VALUE)size);
- if (size > 0) {
- VALUE buff;
- size_t buffsize =
- rb_size_mul_add_or_raise(sizeof(struct outer_variable_pair), size,
- offsetof(struct outer_variable_list, pairs),
- rb_eArgError);
- struct outer_variable_list *ovlist = RB_ALLOCV(buff, buffsize);
- ovlist->num = 0;
- rb_id_table_foreach(ovs, store_outer_variable, ovlist);
- ruby_qsort(ovlist->pairs, size, sizeof(struct outer_variable_pair), outer_variable_cmp, NULL);
- for (size_t i = 0; i < size; ++i) {
- ID id = ovlist->pairs[i].id;
- ID val = ovlist->pairs[i].val;
- ibf_dump_write_small_value(dump, ibf_dump_id(dump, id));
- ibf_dump_write_small_value(dump, val);
- }
+ if (ovs) {
+ ibf_dump_write_small_value(dump, (VALUE)rb_id_table_size(ovs));
+ rb_id_table_foreach(ovs, dump_outer_variable, (void *)dump);
+ }
+ else {
+ ibf_dump_write_small_value(dump, (VALUE)0);
}
return offset;
@@ -12322,7 +11967,6 @@ ibf_load_ci_entries(const struct ibf_load *load,
int kwlen = (int)ibf_load_small_value(load, &reading_pos);
if (kwlen > 0) {
kwarg = rb_xmalloc_mul_add(kwlen, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
- kwarg->references = 0;
kwarg->keyword_len = kwlen;
for (int j=0; j<kwlen; j++) {
VALUE keyword = ibf_load_small_value(load, &reading_pos);
@@ -12477,7 +12121,8 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq)
ibf_dump_write_small_value(dump, body->ic_size);
ibf_dump_write_small_value(dump, body->ci_size);
ibf_dump_write_small_value(dump, body->stack_max);
- ibf_dump_write_small_value(dump, body->builtin_attrs);
+ ibf_dump_write_small_value(dump, body->catch_except_p);
+ ibf_dump_write_small_value(dump, body->builtin_inline_p);
#undef IBF_BODY_OFFSET
@@ -12589,7 +12234,8 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
const unsigned int ci_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
const unsigned int stack_max = (unsigned int)ibf_load_small_value(load, &reading_pos);
- const unsigned int builtin_attrs = (unsigned int)ibf_load_small_value(load, &reading_pos);
+ const char catch_except_p = (char)ibf_load_small_value(load, &reading_pos);
+ const bool builtin_inline_p = (bool)ibf_load_small_value(load, &reading_pos);
// setup fname and dummy frame
VALUE path = ibf_load_object(load, location_pathobj_index);
@@ -12661,19 +12307,14 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
load_body->location.code_location.beg_pos.column = location_code_location_beg_pos_column;
load_body->location.code_location.end_pos.lineno = location_code_location_end_pos_lineno;
load_body->location.code_location.end_pos.column = location_code_location_end_pos_column;
- load_body->builtin_attrs = builtin_attrs;
+ load_body->catch_except_p = catch_except_p;
+ load_body->builtin_inline_p = builtin_inline_p;
load_body->ivc_size = ivc_size;
load_body->icvarc_size = icvarc_size;
load_body->ise_size = ise_size;
load_body->ic_size = ic_size;
-
- if (ISEQ_IS_SIZE(load_body)) {
- load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body));
- }
- else {
- load_body->is_entries = NULL;
- }
+ load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body));
ibf_load_ci_entries(load, ci_entries_offset, ci_size, &load_body->call_data);
load_body->outer_variables = ibf_load_outer_variables(load, outer_variables_offset);
load_body->param.opt_table = ibf_load_param_opt_table(load, param_opt_table_offset, param_opt_num);
@@ -13113,12 +12754,8 @@ ibf_load_object_bignum(const struct ibf_load *load, const struct ibf_object_head
const struct ibf_object_bignum *bignum = IBF_OBJBODY(struct ibf_object_bignum, offset);
int sign = bignum->slen > 0;
ssize_t len = sign > 0 ? bignum->slen : -1 * bignum->slen;
- const int big_unpack_flags = /* c.f. rb_big_unpack() */
- INTEGER_PACK_LSWORD_FIRST |
- INTEGER_PACK_NATIVE_BYTE_ORDER;
- VALUE obj = rb_integer_unpack(bignum->digits, len, sizeof(BDIGIT), 0,
- big_unpack_flags |
- (sign == 0 ? INTEGER_PACK_NEGATIVE : 0));
+ VALUE obj = rb_integer_unpack(bignum->digits, len * 2, 2, 0,
+ INTEGER_PACK_LITTLE_ENDIAN | (sign == 0 ? INTEGER_PACK_NEGATIVE : 0));
if (header->internal) rb_obj_hide(obj);
if (header->frozen) rb_obj_freeze(obj);
return obj;
@@ -13210,7 +12847,7 @@ ibf_load_object_symbol(const struct ibf_load *load, const struct ibf_object_head
}
typedef void (*ibf_dump_object_function)(struct ibf_dump *dump, VALUE obj);
-static const ibf_dump_object_function dump_object_functions[RUBY_T_MASK+1] = {
+static ibf_dump_object_function dump_object_functions[RUBY_T_MASK+1] = {
ibf_dump_object_unsupported, /* T_NONE */
ibf_dump_object_unsupported, /* T_OBJECT */
ibf_dump_object_class, /* T_CLASS */
@@ -13303,7 +12940,7 @@ ibf_dump_object_object(struct ibf_dump *dump, VALUE obj)
}
typedef VALUE (*ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset);
-static const ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = {
+static ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = {
ibf_load_object_unsupported, /* T_NONE */
ibf_load_object_unsupported, /* T_OBJECT */
ibf_load_object_class, /* T_CLASS */
@@ -13446,13 +13083,14 @@ ibf_dump_free(void *ptr)
st_free_table(dump->iseq_table);
dump->iseq_table = 0;
}
+ ruby_xfree(dump);
}
static size_t
ibf_dump_memsize(const void *ptr)
{
struct ibf_dump *dump = (struct ibf_dump *)ptr;
- size_t size = 0;
+ size_t size = sizeof(*dump);
if (dump->iseq_table) size += st_memsize(dump->iseq_table);
if (dump->global_buffer.obj_table) size += st_memsize(dump->global_buffer.obj_table);
return size;
@@ -13461,7 +13099,7 @@ ibf_dump_memsize(const void *ptr)
static const rb_data_type_t ibf_dump_type = {
"ibf_dump",
{ibf_dump_mark, ibf_dump_free, ibf_dump_memsize,},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
@@ -13497,6 +13135,7 @@ rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
ibf_dump_setup(dump, dump_obj);
ibf_dump_write(dump, &header, sizeof(header));
+ ibf_dump_write(dump, RUBY_PLATFORM, strlen(RUBY_PLATFORM) + 1);
ibf_dump_iseq(dump, iseq);
header.magic[0] = 'Y'; /* YARB */
@@ -13505,8 +13144,6 @@ rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
header.magic[3] = 'B';
header.major_version = IBF_MAJOR_VERSION;
header.minor_version = IBF_MINOR_VERSION;
- header.endian = IBF_ENDIAN_MARK;
- header.wordsize = (uint8_t)SIZEOF_VALUE;
ibf_dump_iseq_list(dump, &header);
ibf_dump_object_list(dump, &header.global_object_list_offset, &header.global_object_list_size);
header.size = ibf_dump_pos(dump);
@@ -13524,6 +13161,8 @@ rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
ibf_dump_overwrite(dump, &header, sizeof(header), 0);
str = dump->global_buffer.str;
+ ibf_dump_free(dump);
+ DATA_PTR(dump_obj) = NULL;
RB_GC_GUARD(dump_obj);
return str;
}
@@ -13554,7 +13193,7 @@ rb_ibf_load_iseq_complete(rb_iseq_t *iseq)
}
#if USE_LAZY_LOAD
-const rb_iseq_t *
+MJIT_FUNC_EXPORTED const rb_iseq_t *
rb_iseq_complete(const rb_iseq_t *iseq)
{
rb_ibf_load_iseq_complete((rb_iseq_t *)iseq);
@@ -13597,12 +13236,16 @@ ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq)
#endif
pinned_list_store(load->iseq_list, iseq_index, (VALUE)iseq);
- if (!USE_LAZY_LOAD || GET_VM()->builtin_function_table) {
+#if !USE_LAZY_LOAD
#if IBF_ISEQ_DEBUG
- fprintf(stderr, "ibf_load_iseq: loading iseq=%p\n", (void *)iseq);
+ fprintf(stderr, "ibf_load_iseq: loading iseq=%p\n", (void *)iseq);
#endif
+ rb_ibf_load_iseq_complete(iseq);
+#else
+ if (GET_VM()->builtin_function_table) {
rb_ibf_load_iseq_complete(iseq);
}
+#endif /* !USE_LAZY_LOAD */
#if IBF_ISEQ_DEBUG
fprintf(stderr, "ibf_load_iseq: iseq=%p loaded %p\n",
@@ -13616,39 +13259,35 @@ ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq)
static void
ibf_load_setup_bytes(struct ibf_load *load, VALUE loader_obj, const char *bytes, size_t size)
{
- struct ibf_header *header = (struct ibf_header *)bytes;
load->loader_obj = loader_obj;
load->global_buffer.buff = bytes;
- load->header = header;
- load->global_buffer.size = header->size;
- load->global_buffer.obj_list_offset = header->global_object_list_offset;
- load->global_buffer.obj_list_size = header->global_object_list_size;
- RB_OBJ_WRITE(loader_obj, &load->iseq_list, pinned_list_new(header->iseq_list_size));
+ load->header = (struct ibf_header *)load->global_buffer.buff;
+ load->global_buffer.size = load->header->size;
+ load->global_buffer.obj_list_offset = load->header->global_object_list_offset;
+ load->global_buffer.obj_list_size = load->header->global_object_list_size;
+ RB_OBJ_WRITE(loader_obj, &load->iseq_list, pinned_list_new(load->header->iseq_list_size));
RB_OBJ_WRITE(loader_obj, &load->global_buffer.obj_list, pinned_list_new(load->global_buffer.obj_list_size));
load->iseq = NULL;
load->current_buffer = &load->global_buffer;
- if (size < header->size) {
+ if (size < load->header->size) {
rb_raise(rb_eRuntimeError, "broken binary format");
}
- if (strncmp(header->magic, "YARB", 4) != 0) {
+ if (strncmp(load->header->magic, "YARB", 4) != 0) {
rb_raise(rb_eRuntimeError, "unknown binary format");
}
- if (header->major_version != IBF_MAJOR_VERSION ||
- header->minor_version != IBF_MINOR_VERSION) {
+ if (load->header->major_version != IBF_MAJOR_VERSION ||
+ load->header->minor_version != IBF_MINOR_VERSION) {
rb_raise(rb_eRuntimeError, "unmatched version file (%u.%u for %u.%u)",
- header->major_version, header->minor_version, IBF_MAJOR_VERSION, IBF_MINOR_VERSION);
+ load->header->major_version, load->header->minor_version, IBF_MAJOR_VERSION, IBF_MINOR_VERSION);
}
- if (header->endian != IBF_ENDIAN_MARK) {
- rb_raise(rb_eRuntimeError, "unmatched endian: %c", header->endian);
+ if (strcmp(load->global_buffer.buff + sizeof(struct ibf_header), RUBY_PLATFORM) != 0) {
+ rb_raise(rb_eRuntimeError, "unmatched platform");
}
- if (header->wordsize != SIZEOF_VALUE) {
- rb_raise(rb_eRuntimeError, "unmatched word size: %d", header->wordsize);
- }
- if (header->iseq_list_offset % RUBY_ALIGNOF(ibf_offset_t)) {
+ if (load->header->iseq_list_offset % RUBY_ALIGNOF(ibf_offset_t)) {
rb_raise(rb_eArgError, "unaligned iseq list offset: %u",
- header->iseq_list_offset);
+ load->header->iseq_list_offset);
}
if (load->global_buffer.obj_list_offset % RUBY_ALIGNOF(ibf_offset_t)) {
rb_raise(rb_eArgError, "unaligned object list offset: %u",
@@ -13663,9 +13302,9 @@ ibf_load_setup(struct ibf_load *load, VALUE loader_obj, VALUE str)
rb_raise(rb_eRuntimeError, "broken binary format");
}
- if (USE_LAZY_LOAD) {
- str = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
- }
+#if USE_LAZY_LOAD
+ str = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
+#endif
ibf_load_setup_bytes(load, loader_obj, StringValuePtr(str), RSTRING_LEN(str));
RB_OBJ_WRITE(loader_obj, &load->str, str);
@@ -13739,5 +13378,3 @@ rb_iseq_ibf_load_extra_data(VALUE str)
RB_GC_GUARD(loader_obj);
return extra_str;
}
-
-#include "prism_compile.c"
diff --git a/complex.c b/complex.c
index b6fbc856f1..a227cb0a58 100644
--- a/complex.c
+++ b/complex.c
@@ -24,7 +24,6 @@
#include "internal/numeric.h"
#include "internal/object.h"
#include "internal/rational.h"
-#include "internal/string.h"
#include "ruby_assert.h"
#define ZERO INT2FIX(0)
@@ -392,8 +391,7 @@ k_numeric_p(VALUE x)
inline static VALUE
nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag)
{
- NEWOBJ_OF(obj, struct RComplex, klass,
- T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0), sizeof(struct RComplex), 0);
+ NEWOBJ_OF(obj, struct RComplex, klass, T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0));
RCOMPLEX_SET_REAL(obj, real);
RCOMPLEX_SET_IMAG(obj, imag);
@@ -475,19 +473,12 @@ nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
/*
* call-seq:
- * Complex.rect(real, imag = 0) -> complex
+ * Complex.rect(real[, imag]) -> complex
+ * Complex.rectangular(real[, imag]) -> complex
*
- * Returns a new \Complex object formed from the arguments,
- * each of which must be an instance of Numeric,
- * or an instance of one of its subclasses:
- * \Complex, Float, Integer, Rational;
- * see {Rectangular Coordinates}[rdoc-ref:Complex@Rectangular+Coordinates]:
+ * Returns a complex object which denotes the given rectangular form.
*
- * Complex.rect(3) # => (3+0i)
- * Complex.rect(3, Math::PI) # => (3+3.141592653589793i)
- * Complex.rect(-3, -Math::PI) # => (-3-3.141592653589793i)
- *
- * \Complex.rectangular is an alias for \Complex.rect.
+ * Complex.rectangular(1, 2) #=> (1+2i)
*/
static VALUE
nucomp_s_new(int argc, VALUE *argv, VALUE klass)
@@ -524,54 +515,39 @@ static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass);
/*
* call-seq:
- * Complex(real, imag = 0, exception: true) -> complex or nil
- * Complex(s, exception: true) -> complex or nil
- *
- * Returns a new \Complex object if the arguments are valid;
- * otherwise raises an exception if +exception+ is +true+;
- * otherwise returns +nil+.
- *
- * With Numeric arguments +real+ and +imag+,
- * returns <tt>Complex.rect(real, imag)</tt> if the arguments are valid.
- *
- * With string argument +s+, returns a new \Complex object if the argument is valid;
- * the string may have:
- *
- * - One or two numeric substrings,
- * each of which specifies a Complex, Float, Integer, Numeric, or Rational value,
- * specifying {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates]:
- *
- * - Sign-separated real and imaginary numeric substrings
- * (with trailing character <tt>'i'</tt>):
- *
- * Complex('1+2i') # => (1+2i)
- * Complex('+1+2i') # => (1+2i)
- * Complex('+1-2i') # => (1-2i)
- * Complex('-1+2i') # => (-1+2i)
- * Complex('-1-2i') # => (-1-2i)
- *
- * - Real-only numeric string (without trailing character <tt>'i'</tt>):
- *
- * Complex('1') # => (1+0i)
- * Complex('+1') # => (1+0i)
- * Complex('-1') # => (-1+0i)
- *
- * - Imaginary-only numeric string (with trailing character <tt>'i'</tt>):
- *
- * Complex('1i') # => (0+1i)
- * Complex('+1i') # => (0+1i)
- * Complex('-1i') # => (0-1i)
- *
- * - At-sign separated real and imaginary rational substrings,
- * each of which specifies a Rational value,
- * specifying {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]:
- *
- * Complex('1/2@3/4') # => (0.36584443443691045+0.34081938001166706i)
- * Complex('+1/2@+3/4') # => (0.36584443443691045+0.34081938001166706i)
- * Complex('+1/2@-3/4') # => (0.36584443443691045-0.34081938001166706i)
- * Complex('-1/2@+3/4') # => (-0.36584443443691045-0.34081938001166706i)
- * Complex('-1/2@-3/4') # => (-0.36584443443691045+0.34081938001166706i)
- *
+ * Complex(x[, y], exception: true) -> numeric or nil
+ *
+ * Returns x+i*y;
+ *
+ * Complex(1, 2) #=> (1+2i)
+ * Complex('1+2i') #=> (1+2i)
+ * Complex(nil) #=> TypeError
+ * Complex(1, nil) #=> TypeError
+ *
+ * Complex(1, nil, exception: false) #=> nil
+ * Complex('1+2', exception: false) #=> nil
+ *
+ * Syntax of string form:
+ *
+ * string form = extra spaces , complex , extra spaces ;
+ * complex = real part | [ sign ] , imaginary part
+ * | real part , sign , imaginary part
+ * | rational , "@" , rational ;
+ * real part = rational ;
+ * imaginary part = imaginary unit | unsigned rational , imaginary unit ;
+ * rational = [ sign ] , unsigned rational ;
+ * unsigned rational = numerator | numerator , "/" , denominator ;
+ * numerator = integer part | fractional part | integer part , fractional part ;
+ * denominator = digits ;
+ * integer part = digits ;
+ * fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
+ * imaginary unit = "i" | "I" | "j" | "J" ;
+ * sign = "-" | "+" ;
+ * digits = digit , { digit | "_" , digit };
+ * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
+ * extra spaces = ? \s* ? ;
+ *
+ * See String#to_c.
*/
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
@@ -721,19 +697,14 @@ rb_dbl_complex_new_polar_pi(double abs, double ang)
/*
* call-seq:
- * Complex.polar(abs, arg = 0) -> complex
+ * Complex.polar(abs[, arg]) -> complex
*
- * Returns a new \Complex object formed from the arguments,
- * each of which must be an instance of Numeric,
- * or an instance of one of its subclasses:
- * \Complex, Float, Integer, Rational.
- * Argument +arg+ is given in radians;
- * see {Polar Coordinates}[rdoc-ref:Complex@Polar+Coordinates]:
- *
- * Complex.polar(3) # => (3+0i)
- * Complex.polar(3, 2.0) # => (-1.2484405096414273+2.727892280477045i)
- * Complex.polar(-3, -2.0) # => (1.2484405096414273+2.727892280477045i)
+ * Returns a complex object which denotes the given polar form.
*
+ * Complex.polar(3, 0) #=> (3.0+0.0i)
+ * Complex.polar(3, Math::PI/2) #=> (1.836909530733566e-16+3.0i)
+ * Complex.polar(3, Math::PI) #=> (-3.0+3.673819061467132e-16i)
+ * Complex.polar(3, -Math::PI/2) #=> (1.836909530733566e-16-3.0i)
*/
static VALUE
nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
@@ -753,19 +724,12 @@ nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * real -> numeric
- *
- * Returns the real value for +self+:
+ * cmp.real -> real
*
- * Complex(7).real #=> 7
- * Complex(9, -4).real #=> 9
- *
- * If +self+ was created with
- * {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates], the returned value
- * is computed, and may be inexact:
- *
- * Complex.polar(1, Math::PI/4).real # => 0.7071067811865476 # Square root of 2.
+ * Returns the real part.
*
+ * Complex(7).real #=> 7
+ * Complex(9, -4).real #=> 9
*/
VALUE
rb_complex_real(VALUE self)
@@ -776,19 +740,13 @@ rb_complex_real(VALUE self)
/*
* call-seq:
- * imag -> numeric
+ * cmp.imag -> real
+ * cmp.imaginary -> real
*
- * Returns the imaginary value for +self+:
+ * Returns the imaginary part.
*
* Complex(7).imaginary #=> 0
* Complex(9, -4).imaginary #=> -4
- *
- * If +self+ was created with
- * {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates], the returned value
- * is computed, and may be inexact:
- *
- * Complex.polar(1, Math::PI/4).imag # => 0.7071067811865476 # Square root of 2.
- *
*/
VALUE
rb_complex_imag(VALUE self)
@@ -799,13 +757,11 @@ rb_complex_imag(VALUE self)
/*
* call-seq:
- * -complex -> new_complex
- *
- * Returns the negation of +self+, which is the negation of each of its parts:
+ * -cmp -> complex
*
- * -Complex(1, 2) # => (-1-2i)
- * -Complex(-1, -2) # => (1+2i)
+ * Returns negation of the value.
*
+ * -Complex(1, 2) #=> (-1-2i)
*/
VALUE
rb_complex_uminus(VALUE self)
@@ -817,16 +773,15 @@ rb_complex_uminus(VALUE self)
/*
* call-seq:
- * complex + numeric -> new_complex
+ * cmp + numeric -> complex
*
- * Returns the sum of +self+ and +numeric+:
- *
- * Complex(2, 3) + Complex(2, 3) # => (4+6i)
- * Complex(900) + Complex(1) # => (901+0i)
- * Complex(-2, 9) + Complex(-9, 2) # => (-11+11i)
- * Complex(9, 8) + 4 # => (13+8i)
- * Complex(20, 9) + 9.8 # => (29.8+9i)
+ * Performs addition.
*
+ * Complex(2, 3) + Complex(2, 3) #=> (4+6i)
+ * Complex(900) + Complex(1) #=> (901+0i)
+ * Complex(-2, 9) + Complex(-9, 2) #=> (-11+11i)
+ * Complex(9, 8) + 4 #=> (13+8i)
+ * Complex(20, 9) + 9.8 #=> (29.8+9i)
*/
VALUE
rb_complex_plus(VALUE self, VALUE other)
@@ -852,16 +807,15 @@ rb_complex_plus(VALUE self, VALUE other)
/*
* call-seq:
- * complex - numeric -> new_complex
- *
- * Returns the difference of +self+ and +numeric+:
+ * cmp - numeric -> complex
*
- * Complex(2, 3) - Complex(2, 3) # => (0+0i)
- * Complex(900) - Complex(1) # => (899+0i)
- * Complex(-2, 9) - Complex(-9, 2) # => (7+7i)
- * Complex(9, 8) - 4 # => (5+8i)
- * Complex(20, 9) - 9.8 # => (10.2+9i)
+ * Performs subtraction.
*
+ * Complex(2, 3) - Complex(2, 3) #=> (0+0i)
+ * Complex(900) - Complex(1) #=> (899+0i)
+ * Complex(-2, 9) - Complex(-9, 2) #=> (7+7i)
+ * Complex(9, 8) - 4 #=> (5+8i)
+ * Complex(20, 9) - 9.8 #=> (10.2+9i)
*/
VALUE
rb_complex_minus(VALUE self, VALUE other)
@@ -913,16 +867,15 @@ comp_mul(VALUE areal, VALUE aimag, VALUE breal, VALUE bimag, VALUE *real, VALUE
/*
* call-seq:
- * complex * numeric -> new_complex
+ * cmp * numeric -> complex
*
- * Returns the product of +self+ and +numeric+:
- *
- * Complex(2, 3) * Complex(2, 3) # => (-5+12i)
- * Complex(900) * Complex(1) # => (900+0i)
- * Complex(-2, 9) * Complex(-9, 2) # => (0-85i)
- * Complex(9, 8) * 4 # => (36+32i)
- * Complex(20, 9) * 9.8 # => (196.0+88.2i)
+ * Performs multiplication.
*
+ * Complex(2, 3) * Complex(2, 3) #=> (-5+12i)
+ * Complex(900) * Complex(1) #=> (900+0i)
+ * Complex(-2, 9) * Complex(-9, 2) #=> (0-85i)
+ * Complex(9, 8) * 4 #=> (36+32i)
+ * Complex(20, 9) * 9.8 #=> (196.0+88.2i)
*/
VALUE
rb_complex_mul(VALUE self, VALUE other)
@@ -989,16 +942,16 @@ f_divide(VALUE self, VALUE other,
/*
* call-seq:
- * complex / numeric -> new_complex
- *
- * Returns the quotient of +self+ and +numeric+:
+ * cmp / numeric -> complex
+ * cmp.quo(numeric) -> complex
*
- * Complex(2, 3) / Complex(2, 3) # => ((1/1)+(0/1)*i)
- * Complex(900) / Complex(1) # => ((900/1)+(0/1)*i)
- * Complex(-2, 9) / Complex(-9, 2) # => ((36/85)-(77/85)*i)
- * Complex(9, 8) / 4 # => ((9/4)+(2/1)*i)
- * Complex(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i)
+ * Performs division.
*
+ * Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i)
+ * Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i)
+ * Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i)
+ * Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i)
+ * Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i)
*/
VALUE
rb_complex_div(VALUE self, VALUE other)
@@ -1010,12 +963,11 @@ rb_complex_div(VALUE self, VALUE other)
/*
* call-seq:
- * fdiv(numeric) -> new_complex
+ * cmp.fdiv(numeric) -> complex
*
- * Returns <tt>Complex(self.real/numeric, self.imag/numeric)</tt>:
- *
- * Complex(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i)
+ * Performs division as each part is a float, never returns a float.
*
+ * Complex(11, 22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i)
*/
static VALUE
nucomp_fdiv(VALUE self, VALUE other)
@@ -1029,93 +981,14 @@ f_reciprocal(VALUE x)
return f_quo(ONE, x);
}
-static VALUE
-zero_for(VALUE x)
-{
- if (RB_FLOAT_TYPE_P(x))
- return DBL2NUM(0);
- if (RB_TYPE_P(x, T_RATIONAL))
- return rb_rational_new(INT2FIX(0), INT2FIX(1));
-
- return INT2FIX(0);
-}
-
-static VALUE
-complex_pow_for_special_angle(VALUE self, VALUE other)
-{
- if (!rb_integer_type_p(other)) {
- return Qundef;
- }
-
- get_dat1(self);
- VALUE x = Qundef;
- int dir;
- if (f_zero_p(dat->imag)) {
- x = dat->real;
- dir = 0;
- }
- else if (f_zero_p(dat->real)) {
- x = dat->imag;
- dir = 2;
- }
- else if (f_eqeq_p(dat->real, dat->imag)) {
- x = dat->real;
- dir = 1;
- }
- else if (f_eqeq_p(dat->real, f_negate(dat->imag))) {
- x = dat->imag;
- dir = 3;
- }
-
- if (x == Qundef) return x;
-
- if (f_negative_p(x)) {
- x = f_negate(x);
- dir += 4;
- }
-
- VALUE zx;
- if (dir % 2 == 0) {
- zx = rb_num_pow(x, other);
- }
- else {
- zx = rb_num_pow(
- rb_funcall(rb_int_mul(TWO, x), '*', 1, x),
- rb_int_div(other, TWO)
- );
- if (rb_int_odd_p(other)) {
- zx = rb_funcall(zx, '*', 1, x);
- }
- }
- static const int dirs[][2] = {
- {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}
- };
- int z_dir = FIX2INT(rb_int_modulo(rb_int_mul(INT2FIX(dir), other), INT2FIX(8)));
-
- VALUE zr = Qfalse, zi = Qfalse;
- switch (dirs[z_dir][0]) {
- case 0: zr = zero_for(zx); break;
- case 1: zr = zx; break;
- case -1: zr = f_negate(zx); break;
- }
- switch (dirs[z_dir][1]) {
- case 0: zi = zero_for(zx); break;
- case 1: zi = zx; break;
- case -1: zi = f_negate(zx); break;
- }
- return nucomp_s_new_internal(CLASS_OF(self), zr, zi);
-}
-
-
/*
* call-seq:
- * complex ** numeric -> new_complex
- *
- * Returns +self+ raised to power +numeric+:
+ * cmp ** numeric -> complex
*
- * Complex('i') ** 2 # => (-1+0i)
- * Complex(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i)
+ * Performs exponentiation.
*
+ * Complex('i') ** 2 #=> (-1+0i)
+ * Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i)
*/
VALUE
rb_complex_pow(VALUE self, VALUE other)
@@ -1133,14 +1006,6 @@ rb_complex_pow(VALUE self, VALUE other)
other = dat->real; /* c14n */
}
- if (other == ONE) {
- get_dat1(self);
- return nucomp_s_new_internal(CLASS_OF(self), dat->real, dat->imag);
- }
-
- VALUE result = complex_pow_for_special_angle(self, other);
- if (result != Qundef) return result;
-
if (RB_TYPE_P(other, T_COMPLEX)) {
VALUE r, theta, nr, ntheta;
@@ -1213,13 +1078,15 @@ rb_complex_pow(VALUE self, VALUE other)
/*
* call-seq:
- * complex == object -> true or false
+ * cmp == object -> true or false
*
- * Returns +true+ if <tt>self.real == object.real</tt>
- * and <tt>self.imag == object.imag</tt>:
- *
- * Complex(2, 3) == Complex(2.0, 3.0) # => true
+ * Returns true if cmp equals object numerically.
*
+ * Complex(2, 3) == Complex(2, 3) #=> true
+ * Complex(5) == 5 #=> true
+ * Complex(0) == 0.0 #=> true
+ * Complex('1/3') == 0.33 #=> false
+ * Complex('1/2') == '1/2' #=> false
*/
static VALUE
nucomp_eqeq_p(VALUE self, VALUE other)
@@ -1247,26 +1114,17 @@ nucomp_real_p(VALUE self)
/*
* call-seq:
- * complex <=> object -> -1, 0, 1, or nil
- *
- * Returns:
- *
- * - <tt>self.real <=> object.real</tt> if both of the following are true:
- *
- * - <tt>self.imag == 0</tt>.
- * - <tt>object.imag == 0</tt>. # Always true if object is numeric but not complex.
- *
- * - +nil+ otherwise.
+ * cmp <=> object -> 0, 1, -1, or nil
*
- * Examples:
- *
- * Complex(2) <=> 3 # => -1
- * Complex(2) <=> 2 # => 0
- * Complex(2) <=> 1 # => 1
- * Complex(2, 1) <=> 1 # => nil # self.imag not zero.
- * Complex(1) <=> Complex(1, 1) # => nil # object.imag not zero.
- * Complex(1) <=> 'Foo' # => nil # object.imag not defined.
+ * If +cmp+'s imaginary part is zero, and +object+ is also a
+ * real number (or a Complex number where the imaginary part is zero),
+ * compare the real part of +cmp+ to object. Otherwise, return nil.
*
+ * Complex(2, 3) <=> Complex(2, 3) #=> nil
+ * Complex(2, 3) <=> 1 #=> nil
+ * Complex(2) <=> 1 #=> 1
+ * Complex(2) <=> 2 #=> 0
+ * Complex(2) <=> 3 #=> -1
*/
static VALUE
nucomp_cmp(VALUE self, VALUE other)
@@ -1311,19 +1169,13 @@ nucomp_coerce(VALUE self, VALUE other)
/*
* call-seq:
- * abs -> float
- *
- * Returns the absolute value (magnitude) for +self+;
- * see {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]:
- *
- * Complex.polar(-1, 0).abs # => 1.0
- *
- * If +self+ was created with
- * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value
- * is computed, and may be inexact:
+ * cmp.abs -> real
+ * cmp.magnitude -> real
*
- * Complex.rectangular(1, 1).abs # => 1.4142135623730951 # The square root of 2.
+ * Returns the absolute part of its polar form.
*
+ * Complex(-1).abs #=> 1
+ * Complex(3.0, -4.0).abs #=> 5.0
*/
VALUE
rb_complex_abs(VALUE self)
@@ -1347,19 +1199,12 @@ rb_complex_abs(VALUE self)
/*
* call-seq:
- * abs2 -> float
+ * cmp.abs2 -> real
*
- * Returns square of the absolute value (magnitude) for +self+;
- * see {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]:
- *
- * Complex.polar(2, 2).abs2 # => 4.0
- *
- * If +self+ was created with
- * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value
- * is computed, and may be inexact:
- *
- * Complex.rectangular(1.0/3, 1.0/3).abs2 # => 0.2222222222222222
+ * Returns square of the absolute value.
*
+ * Complex(-1).abs2 #=> 1
+ * Complex(3.0, -4.0).abs2 #=> 25.0
*/
static VALUE
nucomp_abs2(VALUE self)
@@ -1371,19 +1216,13 @@ nucomp_abs2(VALUE self)
/*
* call-seq:
- * arg -> float
- *
- * Returns the argument (angle) for +self+ in radians;
- * see {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]:
+ * cmp.arg -> float
+ * cmp.angle -> float
+ * cmp.phase -> float
*
- * Complex.polar(3, Math::PI/2).arg # => 1.57079632679489660
- *
- * If +self+ was created with
- * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value
- * is computed, and may be inexact:
- *
- * Complex.polar(1, 1.0/3).arg # => 0.33333333333333326
+ * Returns the angle part of its polar form.
*
+ * Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
*/
VALUE
rb_complex_arg(VALUE self)
@@ -1394,22 +1233,12 @@ rb_complex_arg(VALUE self)
/*
* call-seq:
- * rect -> array
- *
- * Returns the array <tt>[self.real, self.imag]</tt>:
- *
- * Complex.rect(1, 2).rect # => [1, 2]
+ * cmp.rect -> array
+ * cmp.rectangular -> array
*
- * See {Rectangular Coordinates}[rdoc-ref:Complex@Rectangular+Coordinates].
+ * Returns an array; [cmp.real, cmp.imag].
*
- * If +self+ was created with
- * {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates], the returned value
- * is computed, and may be inexact:
- *
- * Complex.polar(1.0, 1.0).rect # => [0.5403023058681398, 0.8414709848078965]
- *
- *
- * Complex#rectangular is an alias for Complex#rect.
+ * Complex(1, 2).rectangular #=> [1, 2]
*/
static VALUE
nucomp_rect(VALUE self)
@@ -1420,20 +1249,11 @@ nucomp_rect(VALUE self)
/*
* call-seq:
- * polar -> array
- *
- * Returns the array <tt>[self.abs, self.arg]</tt>:
+ * cmp.polar -> array
*
- * Complex.polar(1, 2).polar # => [1.0, 2.0]
- *
- * See {Polar Coordinates}[rdoc-ref:Complex@Polar+Coordinates].
- *
- * If +self+ was created with
- * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value
- * is computed, and may be inexact:
- *
- * Complex.rect(1, 1).polar # => [1.4142135623730951, 0.7853981633974483]
+ * Returns an array; [cmp.abs, cmp.arg].
*
+ * Complex(1, 2).polar #=> [2.23606797749979, 1.1071487177940904]
*/
static VALUE
nucomp_polar(VALUE self)
@@ -1443,12 +1263,12 @@ nucomp_polar(VALUE self)
/*
* call-seq:
- * conj -> complex
- *
- * Returns the conjugate of +self+, <tt>Complex.rect(self.imag, self.real)</tt>:
+ * cmp.conj -> complex
+ * cmp.conjugate -> complex
*
- * Complex.rect(1, 2).conj # => (1-2i)
+ * Returns the complex conjugate.
*
+ * Complex(1, 2).conjugate #=> (1-2i)
*/
VALUE
rb_complex_conjugate(VALUE self)
@@ -1459,9 +1279,10 @@ rb_complex_conjugate(VALUE self)
/*
* call-seq:
- * real? -> false
+ * Complex(1).real? -> false
+ * Complex(1, 2).real? -> false
*
- * Returns +false+; for compatibility with Numeric#real?.
+ * Returns false, even if the complex number has no imaginary part.
*/
static VALUE
nucomp_real_p_m(VALUE self)
@@ -1471,17 +1292,11 @@ nucomp_real_p_m(VALUE self)
/*
* call-seq:
- * denominator -> integer
+ * cmp.denominator -> integer
*
- * Returns the denominator of +self+, which is
- * the {least common multiple}[https://en.wikipedia.org/wiki/Least_common_multiple]
- * of <tt>self.real.denominator</tt> and <tt>self.imag.denominator</tt>:
+ * Returns the denominator (lcm of both denominator - real and imag).
*
- * Complex.rect(Rational(1, 2), Rational(2, 3)).denominator # => 6
- *
- * Note that <tt>n.denominator</tt> of a non-rational numeric is +1+.
- *
- * Related: Complex#numerator.
+ * See numerator.
*/
static VALUE
nucomp_denominator(VALUE self)
@@ -1492,23 +1307,21 @@ nucomp_denominator(VALUE self)
/*
* call-seq:
- * numerator -> new_complex
+ * cmp.numerator -> numeric
*
- * Returns the \Complex object created from the numerators
- * of the real and imaginary parts of +self+,
- * after converting each part to the
- * {lowest common denominator}[https://en.wikipedia.org/wiki/Lowest_common_denominator]
- * of the two:
+ * Returns the numerator.
*
- * c = Complex(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i)
- * c.numerator # => (8+9i)
+ * 1 2 3+4i <- numerator
+ * - + -i -> ----
+ * 2 3 6 <- denominator
*
- * In this example, the lowest common denominator of the two parts is 12;
- * the two converted parts may be thought of as \Rational(8, 12) and \Rational(9, 12),
- * whose numerators, respectively, are 8 and 9;
- * so the returned value of <tt>c.numerator</tt> is <tt>Complex(8, 9)</tt>.
- *
- * Related: Complex#denominator.
+ * c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i)
+ * n = c.numerator #=> (3+4i)
+ * d = c.denominator #=> 6
+ * n / d #=> ((1/2)+(2/3)*i)
+ * Complex(Rational(n.real, d), Rational(n.imag, d))
+ * #=> ((1/2)+(2/3)*i)
+ * See denominator.
*/
static VALUE
nucomp_numerator(VALUE self)
@@ -1541,18 +1354,6 @@ rb_complex_hash(VALUE self)
return v;
}
-/*
- * :call-seq:
- * hash -> integer
- *
- * Returns the integer hash value for +self+.
- *
- * Two \Complex objects created from the same values will have the same hash value
- * (and will compare using #eql?):
- *
- * Complex(1, 2).hash == Complex(1, 2).hash # => true
- *
- */
static VALUE
nucomp_hash(VALUE self)
{
@@ -1613,16 +1414,15 @@ f_format(VALUE self, VALUE (*func)(VALUE))
/*
* call-seq:
- * to_s -> string
- *
- * Returns a string representation of +self+:
+ * cmp.to_s -> string
*
- * Complex(2).to_s # => "2+0i"
- * Complex('-8/6').to_s # => "-4/3+0i"
- * Complex('1/2i').to_s # => "0+1/2i"
- * Complex(0, Float::INFINITY).to_s # => "0+Infinity*i"
- * Complex(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i"
+ * Returns the value as a string.
*
+ * Complex(2).to_s #=> "2+0i"
+ * Complex('-8/6').to_s #=> "-4/3+0i"
+ * Complex('1/2i').to_s #=> "0+1/2i"
+ * Complex(0, Float::INFINITY).to_s #=> "0+Infinity*i"
+ * Complex(Float::NAN, Float::NAN).to_s #=> "NaN+NaN*i"
*/
static VALUE
nucomp_to_s(VALUE self)
@@ -1632,16 +1432,15 @@ nucomp_to_s(VALUE self)
/*
* call-seq:
- * inspect -> string
+ * cmp.inspect -> string
*
- * Returns a string representation of +self+:
- *
- * Complex(2).inspect # => "(2+0i)"
- * Complex('-8/6').inspect # => "((-4/3)+0i)"
- * Complex('1/2i').inspect # => "(0+(1/2)*i)"
- * Complex(0, Float::INFINITY).inspect # => "(0+Infinity*i)"
- * Complex(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)"
+ * Returns the value as a string for inspection.
*
+ * Complex(2).inspect #=> "(2+0i)"
+ * Complex('-8/6').inspect #=> "((-4/3)+0i)"
+ * Complex('1/2i').inspect #=> "(0+(1/2)*i)"
+ * Complex(0, Float::INFINITY).inspect #=> "(0+Infinity*i)"
+ * Complex(Float::NAN, Float::NAN).inspect #=> "(NaN+NaN*i)"
*/
static VALUE
nucomp_inspect(VALUE self)
@@ -1659,15 +1458,10 @@ nucomp_inspect(VALUE self)
/*
* call-seq:
- * finite? -> true or false
- *
- * Returns +true+ if both <tt>self.real.finite?</tt> and <tt>self.imag.finite?</tt>
- * are true, +false+ otherwise:
+ * cmp.finite? -> true or false
*
- * Complex(1, 1).finite? # => true
- * Complex(Float::INFINITY, 0).finite? # => false
- *
- * Related: Numeric#finite?, Float#finite?.
+ * Returns +true+ if +cmp+'s real and imaginary parts are both finite numbers,
+ * otherwise returns +false+.
*/
static VALUE
rb_complex_finite_p(VALUE self)
@@ -1679,15 +1473,15 @@ rb_complex_finite_p(VALUE self)
/*
* call-seq:
- * infinite? -> 1 or nil
+ * cmp.infinite? -> nil or 1
*
- * Returns +1+ if either <tt>self.real.infinite?</tt> or <tt>self.imag.infinite?</tt>
- * is true, +nil+ otherwise:
+ * Returns +1+ if +cmp+'s real or imaginary part is an infinite number,
+ * otherwise returns +nil+.
*
- * Complex(Float::INFINITY, 0).infinite? # => 1
- * Complex(1, 1).infinite? # => nil
+ * For example:
*
- * Related: Numeric#infinite?, Float#infinite?.
+ * (1+1i).infinite? #=> nil
+ * (Float::INFINITY + 1i).infinite? #=> 1
*/
static VALUE
rb_complex_infinite_p(VALUE self)
@@ -1785,15 +1579,14 @@ rb_dbl_complex_new(double real, double imag)
/*
* call-seq:
- * to_i -> integer
+ * cmp.to_i -> integer
*
- * Returns the value of <tt>self.real</tt> as an Integer, if possible:
+ * Returns the value as an integer if possible (the imaginary part
+ * should be exactly zero).
*
- * Complex(1, 0).to_i # => 1
- * Complex(1, Rational(0, 1)).to_i # => 1
- *
- * Raises RangeError if <tt>self.imag</tt> is not exactly zero
- * (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>).
+ * Complex(1, 0).to_i #=> 1
+ * Complex(1, 0.0).to_i # RangeError
+ * Complex(1, 2).to_i # RangeError
*/
static VALUE
nucomp_to_i(VALUE self)
@@ -1809,15 +1602,14 @@ nucomp_to_i(VALUE self)
/*
* call-seq:
- * to_f -> float
- *
- * Returns the value of <tt>self.real</tt> as a Float, if possible:
+ * cmp.to_f -> float
*
- * Complex(1, 0).to_f # => 1.0
- * Complex(1, Rational(0, 1)).to_f # => 1.0
+ * Returns the value as a float if possible (the imaginary part should
+ * be exactly zero).
*
- * Raises RangeError if <tt>self.imag</tt> is not exactly zero
- * (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>).
+ * Complex(1, 0).to_f #=> 1.0
+ * Complex(1, 0.0).to_f # RangeError
+ * Complex(1, 2).to_f # RangeError
*/
static VALUE
nucomp_to_f(VALUE self)
@@ -1833,17 +1625,16 @@ nucomp_to_f(VALUE self)
/*
* call-seq:
- * to_r -> rational
+ * cmp.to_r -> rational
*
- * Returns the value of <tt>self.real</tt> as a Rational, if possible:
+ * Returns the value as a rational if possible (the imaginary part
+ * should be exactly zero).
*
- * Complex(1, 0).to_r # => (1/1)
- * Complex(1, Rational(0, 1)).to_r # => (1/1)
+ * Complex(1, 0).to_r #=> (1/1)
+ * Complex(1, 0.0).to_r # RangeError
+ * Complex(1, 2).to_r # RangeError
*
- * Raises RangeError if <tt>self.imag</tt> is not exactly zero
- * (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>).
- *
- * Related: Complex#rationalize.
+ * See rationalize.
*/
static VALUE
nucomp_to_r(VALUE self)
@@ -1859,35 +1650,16 @@ nucomp_to_r(VALUE self)
/*
* call-seq:
- * rationalize(epsilon = nil) -> rational
- *
- * Returns a Rational object whose value is exactly or approximately
- * equivalent to that of <tt>self.real</tt>.
- *
- * With no argument +epsilon+ given, returns a \Rational object
- * whose value is exactly equal to that of <tt>self.real.rationalize</tt>:
- *
- * Complex(1, 0).rationalize # => (1/1)
- * Complex(1, Rational(0, 1)).rationalize # => (1/1)
- * Complex(3.14159, 0).rationalize # => (314159/100000)
- *
- * With argument +epsilon+ given, returns a \Rational object
- * whose value is exactly or approximately equal to that of <tt>self.real</tt>
- * to the given precision:
- *
- * Complex(3.14159, 0).rationalize(0.1) # => (16/5)
- * Complex(3.14159, 0).rationalize(0.01) # => (22/7)
- * Complex(3.14159, 0).rationalize(0.001) # => (201/64)
- * Complex(3.14159, 0).rationalize(0.0001) # => (333/106)
- * Complex(3.14159, 0).rationalize(0.00001) # => (355/113)
- * Complex(3.14159, 0).rationalize(0.000001) # => (7433/2366)
- * Complex(3.14159, 0).rationalize(0.0000001) # => (9208/2931)
- * Complex(3.14159, 0).rationalize(0.00000001) # => (47460/15107)
- * Complex(3.14159, 0).rationalize(0.000000001) # => (76149/24239)
- * Complex(3.14159, 0).rationalize(0.0000000001) # => (314159/100000)
- * Complex(3.14159, 0).rationalize(0.0) # => (3537115888337719/1125899906842624)
- *
- * Related: Complex#to_r.
+ * cmp.rationalize([eps]) -> rational
+ *
+ * Returns the value as a rational if possible (the imaginary part
+ * should be exactly zero).
+ *
+ * Complex(1.0/3, 0).rationalize #=> (1/3)
+ * Complex(1, 0.0).rationalize # RangeError
+ * Complex(1, 2).rationalize # RangeError
+ *
+ * See to_r.
*/
static VALUE
nucomp_rationalize(int argc, VALUE *argv, VALUE self)
@@ -1905,9 +1677,12 @@ nucomp_rationalize(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
- * to_c -> self
+ * complex.to_c -> self
*
- * Returns +self+.
+ * Returns self.
+ *
+ * Complex(2).to_c #=> (2+0i)
+ * Complex(-8, 6).to_c #=> (-8+6i)
*/
static VALUE
nucomp_to_c(VALUE self)
@@ -1917,12 +1692,9 @@ nucomp_to_c(VALUE self)
/*
* call-seq:
- * to_c -> (0+0i)
- *
- * Returns zero as a Complex:
- *
- * nil.to_c # => (0+0i)
+ * nil.to_c -> (0+0i)
*
+ * Returns zero as a complex.
*/
static VALUE
nilclass_to_c(VALUE self)
@@ -1932,9 +1704,9 @@ nilclass_to_c(VALUE self)
/*
* call-seq:
- * to_c -> complex
+ * num.to_c -> complex
*
- * Returns +self+ as a Complex object.
+ * Returns the value as a complex.
*/
static VALUE
numeric_to_c(VALUE self)
@@ -2214,14 +1986,23 @@ string_to_c_strict(VALUE self, int raise)
rb_must_asciicompat(self);
- if (raise) {
- s = StringValueCStr(self);
+ s = RSTRING_PTR(self);
+
+ if (!s || memchr(s, '\0', RSTRING_LEN(self))) {
+ if (!raise) return Qnil;
+ rb_raise(rb_eArgError, "string contains null byte");
}
- else if (!(s = rb_str_to_cstr(self))) {
- return Qnil;
+
+ if (s && s[RSTRING_LEN(self)]) {
+ rb_str_modify(self);
+ s = RSTRING_PTR(self);
+ s[RSTRING_LEN(self)] = '\0';
}
- if (!parse_comp(s, TRUE, &num)) {
+ if (!s)
+ s = (char *)"";
+
+ if (!parse_comp(s, 1, &num)) {
if (!raise) return Qnil;
rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE,
self);
@@ -2232,39 +2013,53 @@ string_to_c_strict(VALUE self, int raise)
/*
* call-seq:
- * to_c -> complex
- *
- * Returns +self+ interpreted as a Complex object;
- * leading whitespace and trailing garbage are ignored:
- *
- * '9'.to_c # => (9+0i)
- * '2.5'.to_c # => (2.5+0i)
- * '2.5/1'.to_c # => ((5/2)+0i)
- * '-3/2'.to_c # => ((-3/2)+0i)
- * '-i'.to_c # => (0-1i)
- * '45i'.to_c # => (0+45i)
- * '3-4i'.to_c # => (3-4i)
- * '-4e2-4e-2i'.to_c # => (-400.0-0.04i)
- * '-0.0-0.0i'.to_c # => (-0.0-0.0i)
- * '1/2+3/4i'.to_c # => ((1/2)+(3/4)*i)
- * '1.0@0'.to_c # => (1+0.0i)
- * "1.0@#{Math::PI/2}".to_c # => (0.0+1i)
- * "1.0@#{Math::PI}".to_c # => (-1+0.0i)
- *
- * Returns \Complex zero if the string cannot be converted:
- *
- * 'ruby'.to_c # => (0+0i)
- *
- * See Kernel#Complex.
+ * str.to_c -> complex
+ *
+ * Returns a complex which denotes the string form. The parser
+ * ignores leading whitespaces and trailing garbage. Any digit
+ * sequences can be separated by an underscore. Returns zero for null
+ * or garbage string.
+ *
+ * '9'.to_c #=> (9+0i)
+ * '2.5'.to_c #=> (2.5+0i)
+ * '2.5/1'.to_c #=> ((5/2)+0i)
+ * '-3/2'.to_c #=> ((-3/2)+0i)
+ * '-i'.to_c #=> (0-1i)
+ * '45i'.to_c #=> (0+45i)
+ * '3-4i'.to_c #=> (3-4i)
+ * '-4e2-4e-2i'.to_c #=> (-400.0-0.04i)
+ * '-0.0-0.0i'.to_c #=> (-0.0-0.0i)
+ * '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i)
+ * 'ruby'.to_c #=> (0+0i)
+ *
+ * Polar form:
+ * include Math
+ * "1.0@0".to_c #=> (1+0.0i)
+ * "1.0@#{PI/2}".to_c #=> (0.0+1i)
+ * "1.0@#{PI}".to_c #=> (-1+0.0i)
+ *
+ * See Kernel.Complex.
*/
static VALUE
string_to_c(VALUE self)
{
+ char *s;
VALUE num;
rb_must_asciicompat(self);
- (void)parse_comp(rb_str_fill_terminator(self, 1), FALSE, &num);
+ s = RSTRING_PTR(self);
+
+ if (s && s[RSTRING_LEN(self)]) {
+ rb_str_modify(self);
+ s = RSTRING_PTR(self);
+ s[RSTRING_LEN(self)] = '\0';
+ }
+
+ if (!s)
+ s = (char *)"";
+
+ (void)parse_comp(s, 0, &num);
return num;
}
@@ -2369,9 +2164,9 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * abs2 -> real
+ * num.abs2 -> real
*
- * Returns the square of +self+.
+ * Returns square of self.
*/
static VALUE
numeric_abs2(VALUE self)
@@ -2381,9 +2176,11 @@ numeric_abs2(VALUE self)
/*
* call-seq:
- * arg -> 0 or Math::PI
+ * num.arg -> 0 or float
+ * num.angle -> 0 or float
+ * num.phase -> 0 or float
*
- * Returns zero if +self+ is positive, Math::PI otherwise.
+ * Returns 0 if the value is positive, pi otherwise.
*/
static VALUE
numeric_arg(VALUE self)
@@ -2395,9 +2192,10 @@ numeric_arg(VALUE self)
/*
* call-seq:
- * rect -> array
+ * num.rect -> array
+ * num.rectangular -> array
*
- * Returns array <tt>[self, 0]</tt>.
+ * Returns an array; [num, 0].
*/
static VALUE
numeric_rect(VALUE self)
@@ -2407,9 +2205,9 @@ numeric_rect(VALUE self)
/*
* call-seq:
- * polar -> array
+ * num.polar -> array
*
- * Returns array <tt>[self.abs, self.arg]</tt>.
+ * Returns an array; [num.abs, num.arg].
*/
static VALUE
numeric_polar(VALUE self)
@@ -2437,9 +2235,11 @@ numeric_polar(VALUE self)
/*
* call-seq:
- * arg -> 0 or Math::PI
+ * flo.arg -> 0 or float
+ * flo.angle -> 0 or float
+ * flo.phase -> 0 or float
*
- * Returns 0 if +self+ is positive, Math::PI otherwise.
+ * Returns 0 if the value is positive, pi otherwise.
*/
static VALUE
float_arg(VALUE self)
@@ -2452,63 +2252,45 @@ float_arg(VALUE self)
}
/*
- * A \Complex object houses a pair of values,
- * given when the object is created as either <i>rectangular coordinates</i>
- * or <i>polar coordinates</i>.
- *
- * == Rectangular Coordinates
- *
- * The rectangular coordinates of a complex number
- * are called the _real_ and _imaginary_ parts;
- * see {Complex number definition}[https://en.wikipedia.org/wiki/Complex_number#Definition].
- *
- * You can create a \Complex object from rectangular coordinates with:
- *
- * - A {complex literal}[rdoc-ref:doc/syntax/literals.rdoc@Complex+Literals].
- * - \Method Complex.rect.
- * - \Method Kernel#Complex, either with numeric arguments or with certain string arguments.
- * - \Method String#to_c, for certain strings.
- *
- * Note that each of the stored parts may be a an instance one of the classes
- * Complex, Float, Integer, or Rational;
- * they may be retrieved:
- *
- * - Separately, with methods Complex#real and Complex#imaginary.
- * - Together, with method Complex#rect.
- *
- * The corresponding (computed) polar values may be retrieved:
+ * A complex number can be represented as a paired real number with
+ * imaginary unit; a+bi. Where a is real part, b is imaginary part
+ * and i is imaginary unit. Real a equals complex a+0i
+ * mathematically.
*
- * - Separately, with methods Complex#abs and Complex#arg.
- * - Together, with method Complex#polar.
+ * You can create a \Complex object explicitly with:
*
- * == Polar Coordinates
+ * - A {complex literal}[rdoc-ref:syntax/literals.rdoc@Complex+Literals].
*
- * The polar coordinates of a complex number
- * are called the _absolute_ and _argument_ parts;
- * see {Complex polar plane}[https://en.wikipedia.org/wiki/Complex_number#Polar_complex_plane].
+ * You can convert certain objects to \Complex objects with:
*
- * In this class, the argument part
- * in expressed {radians}[https://en.wikipedia.org/wiki/Radian]
- * (not {degrees}[https://en.wikipedia.org/wiki/Degree_(angle)]).
+ * - \Method #Complex.
*
- * You can create a \Complex object from polar coordinates with:
+ * Complex object can be created as literal, and also by using
+ * Kernel#Complex, Complex::rect, Complex::polar or to_c method.
*
- * - \Method Complex.polar.
- * - \Method Kernel#Complex, with certain string arguments.
- * - \Method String#to_c, for certain strings.
+ * 2+1i #=> (2+1i)
+ * Complex(1) #=> (1+0i)
+ * Complex(2, 3) #=> (2+3i)
+ * Complex.polar(2, 3) #=> (-1.9799849932008908+0.2822400161197344i)
+ * 3.to_c #=> (3+0i)
*
- * Note that each of the stored parts may be a an instance one of the classes
- * Complex, Float, Integer, or Rational;
- * they may be retrieved:
+ * You can also create complex object from floating-point numbers or
+ * strings.
*
- * - Separately, with methods Complex#abs and Complex#arg.
- * - Together, with method Complex#polar.
+ * Complex(0.3) #=> (0.3+0i)
+ * Complex('0.3-0.5i') #=> (0.3-0.5i)
+ * Complex('2/3+3/4i') #=> ((2/3)+(3/4)*i)
+ * Complex('1@2') #=> (-0.4161468365471424+0.9092974268256817i)
*
- * The corresponding (computed) rectangular values may be retrieved:
+ * 0.3.to_c #=> (0.3+0i)
+ * '0.3-0.5i'.to_c #=> (0.3-0.5i)
+ * '2/3+3/4i'.to_c #=> ((2/3)+(3/4)*i)
+ * '1@2'.to_c #=> (-0.4161468365471424+0.9092974268256817i)
*
- * - Separately, with methods Complex#real and Complex#imag.
- * - Together, with method Complex#rect.
+ * A complex object is either an exact or an inexact number.
*
+ * Complex(1, 1) / 2 #=> ((1/2)+(1/2)*i)
+ * Complex(1, 1) / 2.0 #=> (0.5+0.5i)
*/
void
Init_Complex(void)
@@ -2629,11 +2411,7 @@ Init_Complex(void)
rb_define_method(rb_cFloat, "phase", float_arg, 0);
/*
- * Equivalent
- * to <tt>Complex(0, 1)</tt>:
- *
- * Complex::I # => (0+1i)
- *
+ * The imaginary unit.
*/
rb_define_const(rb_cComplex, "I",
f_complex_new_bang2(rb_cComplex, ZERO, ONE));
diff --git a/configure.ac b/configure.ac
index 5165735443..220392d120 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,7 +16,6 @@ m4_include([tool/m4/ruby_append_option.m4])dnl
m4_include([tool/m4/ruby_append_options.m4])dnl
m4_include([tool/m4/ruby_check_builtin_func.m4])dnl
m4_include([tool/m4/ruby_check_builtin_setjmp.m4])dnl
-m4_include([tool/m4/ruby_check_header.m4])dnl
m4_include([tool/m4/ruby_check_printf_prefix.m4])dnl
m4_include([tool/m4/ruby_check_setjmp.m4])dnl
m4_include([tool/m4/ruby_check_signedness.m4])dnl
@@ -48,22 +47,11 @@ m4_include([tool/m4/ruby_universal_arch.m4])dnl
m4_include([tool/m4/ruby_wasm_tools.m4])dnl
m4_include([tool/m4/ruby_werror_flag.m4])dnl
-AS_IF([test "x${GITHUB_ACTIONS}" = xtrue],
-[AC_REQUIRE([_COLORIZE_RESULT_PREPARE])dnl
-dnl 93(bright yellow) is copied from .github/workflows/mingw.yml
- begin_group() { AS_ECHO(["::group::@<:@93m$[]1@<:@m"]);}
- end_group() { AS_ECHO(["::endgroup::"]);}
-],
-[dnl
- begin_group() { :;}
- end_group() { :;}
-])
-
AC_ARG_VAR([cflags], [additional CFLAGS (ignored when CFLAGS is given)])dnl
AC_ARG_VAR([cppflags], [additional CPPFLAGS (ignored when CPPFLAGS is given)])dnl
AC_ARG_VAR([cxxflags], [additional CXXFLAGS (ignored when CXXFLAGS is given)])dnl
-[begin]_group "environment section" && {
+: "environment section" && {
HAVE_BASERUBY=yes
BASERUBY_VERSION=
AC_ARG_WITH(baseruby,
@@ -76,13 +64,13 @@ AC_ARG_WITH(baseruby,
[
AC_PATH_PROG([BASERUBY], [ruby], [false])
])
-# BASERUBY must be >= 2.5.0. Note that `"2.5.0" > "2.5"` is true.
-AS_IF([test "$HAVE_BASERUBY" != no -a "`RUBYOPT=- $BASERUBY --disable=gems -e 'print 42 if RUBY_VERSION > "2.5"' 2>/dev/null`" = 42], [
+# BASERUBY must be >= 2.2.0. Note that `"2.2.0" > "2.2"` is true.
+AS_IF([test "$HAVE_BASERUBY" != no -a "`RUBYOPT=- $BASERUBY --disable=gems -e 'print 42 if RUBY_VERSION > "2.2"' 2>/dev/null`" = 42], [
AS_CASE(["$build_os"], [mingw*], [
# Can MSys shell run a command with a drive letter?
RUBYOPT=- `cygpath -ma "$BASERUBY"` --disable=gems -e exit 2>/dev/null || HAVE_BASERUBY=no
])
- RUBY_APPEND_OPTION(BASERUBY, "--disable=gems")
+ BASERUBY="$BASERUBY --disable=gems"
BASERUBY_VERSION=`$BASERUBY -v`
$BASERUBY -C "$srcdir" tool/downloader.rb -d tool -e gnu config.guess config.sub >&AS_MESSAGE_FD
], [
@@ -90,7 +78,7 @@ AS_IF([test "$HAVE_BASERUBY" != no -a "`RUBYOPT=- $BASERUBY --disable=gems -e 'p
])
AS_IF([test "$HAVE_BASERUBY" = no], [
AS_IF([test "$cross_compiling" = yes], [AC_MSG_ERROR([executable host ruby is required for cross-compiling])])
- BASERUBY=$srcdir/tool/missing-baseruby.bat
+ BASERUBY="echo executable host ruby is required. use --with-baseruby option.; false"
])
AC_SUBST(BASERUBY)
AC_SUBST(HAVE_BASERUBY)
@@ -226,15 +214,23 @@ AS_CASE(["/${rb_CC} "],
[*clang*], [
# Ditto for LLVM. Note however that llvm-as is a LLVM-IR to LLVM bitcode
# assembler that does not target your machine native binary.
+
+ # Xcode has its own version tools that may be incompatible with
+ # genuine LLVM tools, use the tools in the same directory.
+
+ AS_IF([$rb_CC -E -dM -xc - < /dev/null | grep -F __apple_build_version__ > /dev/null],
+ [llvm_prefix=], [llvm_prefix=llvm-])
+ # AC_PREPROC_IFELSE cannot be used before AC_USE_SYSTEM_EXTENSIONS
+
RUBY_CHECK_PROG_FOR_CC([LD], [s/clang/ld/]) # ... maybe try lld ?
- RUBY_CHECK_PROG_FOR_CC([AR], [s/clang/llvm-ar/])
-# RUBY_CHECK_PROG_FOR_CC([AS], [s/clang/llvm-as/])
+ RUBY_CHECK_PROG_FOR_CC([AR], [s/clang/${llvm_prefix}ar/])
+# RUBY_CHECK_PROG_FOR_CC([AS], [s/clang/${llvm_prefix}as/])
RUBY_CHECK_PROG_FOR_CC([CXX], [s/clang/clang++/])
- RUBY_CHECK_PROG_FOR_CC([NM], [s/clang/llvm-nm/])
- RUBY_CHECK_PROG_FOR_CC([OBJCOPY], [s/clang/llvm-objcopy/])
- RUBY_CHECK_PROG_FOR_CC([OBJDUMP], [s/clang/llvm-objdump/])
- RUBY_CHECK_PROG_FOR_CC([RANLIB], [s/clang/llvm-ranlib/])
- RUBY_CHECK_PROG_FOR_CC([STRIP], [s/clang/llvm-strip/])
+ RUBY_CHECK_PROG_FOR_CC([NM], [s/clang/${llvm_prefix}nm/])
+ RUBY_CHECK_PROG_FOR_CC([OBJCOPY], [s/clang/${llvm_prefix}objcopy/])
+ RUBY_CHECK_PROG_FOR_CC([OBJDUMP], [s/clang/${llvm_prefix}objdump/])
+ RUBY_CHECK_PROG_FOR_CC([RANLIB], [s/clang/${llvm_prefix}ranlib/])
+ RUBY_CHECK_PROG_FOR_CC([STRIP], [s/clang/${llvm_prefix}strip/])
])
AS_UNSET(rb_CC)
AS_UNSET(rb_dummy)
@@ -245,15 +241,9 @@ AS_CASE(["${build_os}"],
],
[aix*], [
AC_PATH_TOOL([NM], [nm], [/usr/ccs/bin/nm], [/usr/ccs/bin:$PATH])
-],
-[darwin*], [
- # For Apple clang version 14.0.3 (clang-1403.0.22.14.1)
- ac_cv_prog_ac_ct_AR=`$CC -print-prog-name=ar`
- ac_cv_prog_ac_ct_LD=`$CC -print-prog-name=ld`
- ac_cv_prog_ac_ct_NM=`$CC -print-prog-name=nm`
])
AS_CASE(["${target_os}"],
-[cygwin*|msys*|mingw*|darwin*], [
+[cygwin*|msys*|mingw*], [
ac_cv_prog_ac_ct_OBJCOPY=":"
])
@@ -272,14 +262,10 @@ AC_CHECK_TOOLS([AR], [gar ar])
AC_CHECK_TOOLS([AS], [gas as])
AC_CHECK_TOOLS([LD], [gld ld]) # ... try gold ?
AC_CHECK_TOOLS([NM], [gnm nm])
-AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy], [:])
+AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy])
AC_CHECK_TOOLS([OBJDUMP], [gobjdump objdump])
AC_CHECK_TOOLS([STRIP], [gstrip strip], [:])
-# nm errors with Rust's LLVM bitcode when Rust uses a newer LLVM version than nm.
-# In case we're working with llvm-nm, tell it to not worry about the bitcode.
-AS_IF([${NM} --help | grep -q 'llvm-bc'], [NM="$NM --no-llvm-bc"])
-
AS_IF([test ! $rb_test_CFLAGS], [AS_UNSET(CFLAGS)]); AS_UNSET(rb_test_CFLAGS)
AS_IF([test ! $rb_test_CXXFLAGS], [AS_UNSET(CXXFLAGS)]); AS_UNSET(rb_save_CXXFLAGS)
@@ -407,6 +393,13 @@ AS_IF([test "$GCC" = yes], [
AS_IF([test "$gcc_major" -lt 4], [
AC_MSG_ERROR([too old GCC: $gcc_major.$gcc_minor])
])
+
+ AC_CACHE_CHECK([if thread-local storage is supported], [rb_cv_tls_supported],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[int __thread conftest;]])],
+ [rb_cv_tls_supported=yes],
+ [rb_cv_tls_supported=no])])
+ AS_IF([test x"$rb_cv_tls_supported" != xyes],
+ [AC_DEFINE(RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED)])
], [
linker_flag=
])
@@ -421,17 +414,29 @@ AC_SUBST(OUTFLAG)
AC_SUBST(COUTFLAG)
AC_SUBST(CSRCFLAG)
+: ${MJIT_CC=$CC}
+AS_IF([test "x$cross_compiling" = xno], [
+ AC_PATH_PROG([MJIT_CC], ${MJIT_CC})
+
+ # if $CC is in /usr/lib/ccache/$CC, search original $CC (disable ccache)
+ AS_IF([echo $RUBY_DEBUG | grep ci > /dev/null &&
+ echo $MJIT_CC | grep ^/usr/lib/ccache > /dev/null], [
+ PATH=`echo $PATH | sed "s/\/usr\/lib\/ccache://"` MJIT_CC=`which $CC`])
+
+ AS_CASE([$target_os],
+ [*mingw*], [command -v cygpath > /dev/null && MJIT_CC=`cygpath -ma $MJIT_CC`])
+ shift 2
+ MJIT_CC="$MJIT_CC${1+ }$*"
+])
+
AS_CASE(["$build_os"],
- [darwin*], [
- # gcc 13 warns duplicate -l options, which are added by the
- # default spec.
+ [darwin1*.*], [
# Xcode linker warns for deprecated architecture and wrongly
# installed TBD files.
- CC_WRAPPER="" CC_NO_WRAPPER="$CC"
+ CC_WRAPPER=""
echo 'int main(void) {return 0;}' > conftest.c
AS_IF([$CC -framework Foundation -o conftest conftest.c 2>&1 |
- grep -e '^ld: warning: ignoring duplicate libraries:' \
- -e '^ld: warning: text-based stub file' >/dev/null], [
+ grep '^ld: warning: text-based stub file' >/dev/null], [
CC_WRAPPER=`cd -P "${tooldir}" && pwd`/darwin-cc
CC="$CC_WRAPPER $CC"
])
@@ -462,7 +467,7 @@ AC_SUBST(CC_VERSION_MESSAGE, $cc_version_message)
: ${DLDFLAGS="$LDFLAGS"}
RUBY_UNIVERSAL_ARCH
-AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "${universal_binary:-no}" = no], [
+AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "$cross_compiling" = no -a "${universal_binary:-no}" = no], [
RUBY_DEFAULT_ARCH("$target_cpu")
])
host_os=$target_os
@@ -507,7 +512,6 @@ AS_CASE(["$target_os"],
])
rb_cv_binary_elf=no
: ${enable_shared=yes}
- AS_IF([$WINDRES --version | grep LLVM > /dev/null], [USE_LLVM_WINDRES=yes], [USE_LLVM_WINDRES=no])
],
[hiuxmpp*], [AC_DEFINE(__HIUX_MPP__)]) # by TOYODA Eizi <toyoda@npd.kishou.go.jp>
@@ -591,7 +595,7 @@ AC_MSG_RESULT([$CHDIR])
AC_SUBST(CHDIR)
}
-[begin]_group "compiler section" && {
+: "compiler section" && {
RUBY_WERROR_FLAG([
AC_MSG_CHECKING([whether CFLAGS is valid])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
@@ -686,10 +690,6 @@ AS_CASE(["$GCC:${warnflags+set}:${extra_warnflags:+set}:"],
AS_IF([test $gcc_major -le 6], [
extra_warnflags="$extra_warnflags -Wno-maybe-uninitialized"
])
- AS_CASE([ $CFLAGS ], [*" -save-temps="*|*" -save-temps "*], [], [
- extra_warnflags="$extra_warnflags -Werror=misleading-indentation"
- ])
-
# ICC doesn't support -Werror=
AS_IF([test $icc_version -gt 0], [
particular_werror_flags=no
@@ -701,6 +701,7 @@ AS_CASE(["$GCC:${warnflags+set}:${extra_warnflags:+set}:"],
-Werror=duplicated-cond \
-Werror=implicit-function-declaration \
-Werror=implicit-int \
+ -Werror=misleading-indentation \
-Werror=pointer-arith \
-Werror=shorten-64-to-32 \
-Werror=write-strings \
@@ -804,6 +805,8 @@ AS_IF([test "$GCC" = yes], [
[@%:@include <stdio.h>])
])
+ : ${MJIT_HEADER_FLAGS='-P -dD'}
+
# -fstack-protector
AS_CASE(["$target_os"],
[emscripten*|wasi*], [
@@ -831,10 +834,7 @@ AS_IF([test "$GCC" = yes], [
AS_FOR(option, opt, [-mbranch-protection=pac-ret -msign-return-address=all], [
RUBY_TRY_CFLAGS(option, [branch_protection=yes], [branch_protection=no])
AS_IF([test "x$branch_protection" = xyes], [
- # C compiler and assembler must be consistent for -mbranch-protection
- # since they both check `__ARM_FEATURE_PAC_DEFAULT` definition.
RUBY_APPEND_OPTION(XCFLAGS, option)
- RUBY_APPEND_OPTION(ASFLAGS, option)
break
])
])
@@ -910,6 +910,7 @@ AS_IF([test "$GCC" = yes], [
], [
RUBY_TRY_LDFLAGS([-Wl,-unexported_symbol,_Init_*], [visibility_option=ld], [visibility_option=no])
])
+ test "$visibility_option" = no || OBJCOPY=:
])
AS_IF([test "$GCC" = yes], [
@@ -992,7 +993,7 @@ AS_IF([test "$rb_cv_have_stmt_and_decl_in_expr" = yes], [
AC_DEFINE(HAVE_STMT_AND_DECL_IN_EXPR)
])
-[begin]_group "header and library section" && {
+: "header and library section" && {
AC_ARG_WITH(winnt-ver,
AS_HELP_STRING([--with-winnt-ver=0xXXXX], [target Windows NT version (default to 0x0600)]),
[with_winnt_ver="$withval"], [with_winnt_ver="0x0600"])
@@ -1095,18 +1096,12 @@ main()
])
POSTLINK=""
AC_CHECK_PROGS(codesign, codesign)
- dsymutils=
- AS_CASE("$CC_NO_WRAPPER", [gcc*-1[[3-9]]], [
- dsymutils=${CC_NO_WRAPPER@%:@gcc}
- dsymutils=dsymutil${dsymutils%-1*}
- dsymutils="$dsymutils-19 $dsymutils-18 $dsymutils-17"
- ])
- AC_CHECK_PROGS(dsymutil, $dsymutils dsymutil)
+ AC_CHECK_PROGS(dsymutil, dsymutil)
AS_IF([test -n "$codesign"], [
POSTLINK="{ test -z '\$(RUBY_CODESIGN)' || $codesign -s '\$(RUBY_CODESIGN)' -f \$@; }${POSTLINK:+; $POSTLINK}"
])
AS_IF([test -n "$dsymutil"], [
- POSTLINK="$dsymutil \$@ 2>/dev/null${POSTLINK:+; $POSTLINK}"
+ POSTLINK="$dsymutil \$@${POSTLINK:+; $POSTLINK}"
])
AS_IF([test -n "${POSTLINK}"], [
LINK_SO="$LINK_SO
@@ -1208,8 +1203,6 @@ main()
ac_cv_func_gmtime_r=yes
rb_cv_large_fd_select=yes
ac_cv_type_struct_timeval=yes
- ac_cv_func_clock_gettime=yes
- ac_cv_func_clock_getres=yes
ac_cv_func_malloc_usable_size=no
ac_cv_type_off_t=yes
ac_cv_sizeof_off_t=8
@@ -1253,7 +1246,7 @@ main()
AS_CASE(["$target_cpu"], [powerpc64*], [
ac_cv_func___builtin_setjmp=no
])
- # With gcc-8's -fcf-protection, RJIT's __builtin_longjmp fails.
+ # With gcc-8's -fcf-protection, MJIT's __builtin_longjmp fails.
AS_CASE(["$CC $CFLAGS "], [*" -fcf-protection "*], [cf_protection=yes], [cf_protection=no])
AS_IF([test "$cf_protection" = yes], [
ac_cv_func___builtin_setjmp=no
@@ -1355,8 +1348,7 @@ AC_CHECK_HEADERS(syscall.h)
AC_CHECK_HEADERS(time.h)
AC_CHECK_HEADERS(ucontext.h)
AC_CHECK_HEADERS(utime.h)
-AC_CHECK_HEADERS(sys/epoll.h)
-AC_CHECK_HEADERS(sys/event.h)
+AC_CHECK_HEADERS(stdatomic.h)
AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [
AC_CHECK_HEADERS(x86intrin.h)
@@ -1364,7 +1356,7 @@ AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [
RUBY_UNIVERSAL_CHECK_HEADER([x86_64, i386], x86intrin.h)
AS_IF([test "x$with_gmp" != xno],
- [RUBY_CHECK_HEADER(gmp.h)
+ [AC_CHECK_HEADERS(gmp.h)
AS_IF([test "x$ac_cv_header_gmp_h" != xno],
AC_SEARCH_LIBS([__gmpz_init], [gmp],
[AC_DEFINE(HAVE_LIBGMP, 1)]))])
@@ -1495,25 +1487,6 @@ RUBY_CHECK_SIZEOF(float)
RUBY_CHECK_SIZEOF(double)
RUBY_CHECK_SIZEOF(time_t, [long "long long"], [], [@%:@include <time.h>])
RUBY_CHECK_SIZEOF(clock_t, [], [], [@%:@include <time.h>])
-AC_SUBST(X_BUILTIN_BINARY, yes)
-AS_IF([test "$cross_compiling" = yes],
-[dnl miniruby cannot run if cross compiling
- X_BUILTIN_BINARY=no
-],
-[
- AS_CASE([ac_cv_sizeof_voidp],
- [[1-9]*], [dnl fixed value
- ],
- [
- AC_CACHE_CHECK([word size], [rb_cv_word_size],
- [for w in 4 8; do
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@if SIZEOF_VOIDP != ${w}
- @%:@error SIZEOF_VOIDP
- @%:@endif]])], [rb_cv_word_size=${w}; break])
- done])
- AS_IF([test -z $rb_cv_word_size], [X_BUILTIN_BINARY=no])
- ])
-])
AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct,
[rb_cv_packed_struct=no
@@ -1526,9 +1499,10 @@ AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct,
[rb_cv_packed_struct=$mac; break])
done])
AS_IF([test "$rb_cv_packed_struct" != no], [
- AC_DEFINE_UNQUOTED([RBIMPL_ATTR_PACKED_STRUCT_BEGIN()], [`echo " $rb_cv_packed_struct " | sed 's/ x .*//;s/^ *//'`])
- AC_DEFINE_UNQUOTED([RBIMPL_ATTR_PACKED_STRUCT_END()], [`echo " $rb_cv_packed_struct " | sed 's/.* x //;s/ *$//'`])
+ AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], [$rb_cv_packed_struct])
RUBY_TRY_CFLAGS(-Wno-address-of-packed-member, [AC_DEFINE(USE_UNALIGNED_MEMBER_ACCESS)])
+], [
+ AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], x)
])
AS_IF([test "x$ac_cv_type_long_long" = xyes], [
@@ -2037,6 +2011,7 @@ AC_CHECK_FUNCS(_longjmp) # used for AC_ARG_WITH(setjmp-type)
test x$ac_cv_func__longjmp = xno && ac_cv_func__setjmp=no
AC_CHECK_FUNCS(arc4random_buf)
AC_CHECK_FUNCS(atan2l atan2f)
+AC_CHECK_DECLS(atomic_signal_fence, [], [], [#include <stdatomic.h>])
AC_CHECK_FUNCS(chmod)
AC_CHECK_FUNCS(chown)
AC_CHECK_FUNCS(chroot)
@@ -2060,7 +2035,6 @@ AC_CHECK_FUNCS(execv)
AC_CHECK_FUNCS(execve)
AC_CHECK_FUNCS(explicit_memset)
AC_CHECK_FUNCS(fcopyfile)
-AC_CHECK_FUNCS(fchdir)
AC_CHECK_FUNCS(fchmod)
AC_CHECK_FUNCS(fchown)
AC_CHECK_FUNCS(fcntl)
@@ -2118,7 +2092,6 @@ AC_CHECK_FUNCS(lstat)
AC_CHECK_FUNCS(lutimes)
AC_CHECK_FUNCS(malloc_usable_size)
AC_CHECK_FUNCS(malloc_size)
-AC_CHECK_FUNCS(malloc_trim)
AC_CHECK_FUNCS(mblen)
AC_CHECK_FUNCS(memalign)
AC_CHECK_FUNCS(memset_s)
@@ -2172,7 +2145,6 @@ AC_CHECK_FUNCS(sigaction)
AC_CHECK_FUNCS(sigaltstack)
AC_CHECK_FUNCS(sigprocmask)
AC_CHECK_FUNCS(sinh)
-AC_CHECK_FUNCS(snprintf)
AC_CHECK_FUNCS(spawnv)
AC_CHECK_FUNCS(symlink)
AC_CHECK_FUNCS(syscall)
@@ -2197,6 +2169,9 @@ AC_CHECK_FUNCS(__sinpi)
AS_IF([test "x$ac_cv_member_struct_statx_stx_btime" = xyes],
[AC_CHECK_FUNCS(statx)])
+AS_CASE(["$ac_cv_func_memset_s:$ac_cv_func_qsort_s"], [*yes*],
+ [RUBY_DEFINE_IF([!defined __STDC_WANT_LIB_EXT1__], [__STDC_WANT_LIB_EXT1__], 1)])
+
AS_IF([test "$ac_cv_func_getcwd" = yes], [
AC_CACHE_CHECK(if getcwd allocates buffer if NULL is given, [rb_cv_getcwd_malloc],
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
@@ -2265,27 +2240,6 @@ RUBY_CHECK_BUILTIN_FUNC(__builtin_types_compatible_p, [__builtin_types_compatibl
RUBY_CHECK_BUILTIN_FUNC(__builtin_trap, [__builtin_trap()])
RUBY_CHECK_BUILTIN_FUNC(__builtin_expect, [__builtin_expect(0, 0)])
-AS_IF([test "$rb_cv_builtin___builtin_mul_overflow" != no], [
- AC_CACHE_CHECK(for __builtin_mul_overflow with long long arguments, rb_cv_use___builtin_mul_overflow_long_long, [
- AC_LINK_IFELSE([AC_LANG_SOURCE([[
-#pragma clang optimize off
-
-int
-main(void)
-{
- long long x = 0, y;
- __builtin_mul_overflow(x, x, &y);
-
- return 0;
-}
-]])],
- rb_cv_use___builtin_mul_overflow_long_long=yes,
- rb_cv_use___builtin_mul_overflow_long_long=no)])
-])
-AS_IF([test "$rb_cv_use___builtin_mul_overflow_long_long" = yes], [
- AC_DEFINE(USE___BUILTIN_MUL_OVERFLOW_LONG_LONG, 1)
-])
-
AS_IF([test "$ac_cv_func_qsort_r" != no], [
AC_CACHE_CHECK(whether qsort_r is GNU version, rb_cv_gnu_qsort_r,
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -2673,9 +2627,6 @@ AS_CASE([$coroutine_type], [yes|''], [
[*86-mingw*], [
coroutine_type=win32
],
- [aarch64-mingw*], [
- coroutine_type=arm64
- ],
[arm*-linux*], [
coroutine_type=arm32
],
@@ -2688,9 +2639,6 @@ AS_CASE([$coroutine_type], [yes|''], [
[riscv64-linux*], [
coroutine_type=riscv64
],
- [loongarch64-linux*], [
- coroutine_type=loongarch64
- ],
[x86_64-freebsd*], [
coroutine_type=amd64
],
@@ -2715,9 +2663,6 @@ AS_CASE([$coroutine_type], [yes|''], [
[i386-openbsd*], [
coroutine_type=x86
],
- [aarch64-openbsd*], [
- coroutine_type=arm64
- ],
[*-openbsd*], [
coroutine_type=pthread
],
@@ -2815,22 +2760,6 @@ AS_IF([test "$THREAD_MODEL" = pthread], [
AC_DEFINE_UNQUOTED(SET_ANOTHER_THREAD_NAME(thid,name), $set_another_thread_name)
])
])
-
- AC_CACHE_CHECK([for thread-local storage sepcifier], [rb_cv_tls_specifier],
- rb_cv_tls_specifier=none
- RUBY_WERROR_FLAG([
- for attr in \
- _Thread_local \
- __thread \
- ; do
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[$attr int conftest;]])],
- [rb_cv_tls_specifier=$attr; break])
- done
- ])
- )
- AS_IF([test x"${rb_cv_tls_specifier}" != xnone],
- [AC_DEFINE_UNQUOTED(RB_THREAD_LOCAL_SPECIFIER, ${rb_cv_tls_specifier})]
- )
])
AS_IF([test x"$ac_cv_header_ucontext_h" = xno], [
@@ -2974,7 +2903,7 @@ AS_IF([test "x$ac_cv_func_ioctl" = xyes], [
}
-[begin]_group "runtime section" && {
+: "runtime section" && {
dnl wheather use dln_a_out or not
AC_ARG_WITH(dln-a-out,
AS_HELP_STRING([--with-dln-a-out], [dln_a_out is deprecated]),
@@ -3008,8 +2937,22 @@ AS_CASE(["$target_os"],
])])
LIBEXT=a
+AC_ARG_WITH(mjit-tabs,
+ AS_HELP_STRING([--without-mjit-tabs], [expand tabs in mjit header]),
+ [AS_IF([test $withval = no], [MJIT_TABS=false])])
+AC_SUBST(MJIT_TABS)dnl
AC_SUBST(DLDFLAGS)dnl
AC_SUBST(ARCH_FLAG)dnl
+AC_SUBST(MJIT_HEADER_FLAGS)dnl
+AC_SUBST(MJIT_HEADER_INSTALL_DIR)dnl
+AC_SUBST(MJIT_CC)dnl
+AS_CASE(["$GCC:$target_os"],
+ [yes:aix*], [mjit_std_cflag="-std=gnu99"],
+ [mjit_std_cflag=])
+AC_SUBST(MJIT_CFLAGS, [${MJIT_CFLAGS-"-w ${mjit_std_cflag} ${orig_cflags}"}])dnl
+AC_SUBST(MJIT_OPTFLAGS, [${MJIT_OPTFLAGS-'$(optflags)'}])dnl
+AC_SUBST(MJIT_DEBUGFLAGS, [${MJIT_DEBUGFLAGS-'$(debugflags)'}])dnl
+AC_SUBST(MJIT_LDSHARED)dnl
AC_SUBST(STATIC)dnl
AC_SUBST(CCDLFLAGS)dnl
@@ -3126,7 +3069,8 @@ AC_SUBST(EXTOBJS)
: ${LIBPATHENV=DYLD_LIBRARY_PATH}
: ${PRELOADENV=DYLD_INSERT_LIBRARIES}
AS_IF([test x"$enable_shared" = xyes], [
- # Resolve symbols from libruby.dylib in $(LIBS) when --enable-shared
+ # Resolve symbols from libruby.dylib when --enable-shared
+ EXTDLDFLAGS='$(LIBRUBYARG_SHARED)'
], [test "x$EXTSTATIC" = x], [
# When building exts as bundles, a mach-o bundle needs to know its loader
# program to bind symbols from the ruby executable
@@ -3475,6 +3419,9 @@ AC_ARG_ENABLE(multiarch,
[multiarch=], [unset multiarch])
AS_IF([test ${multiarch+set}], [
AC_DEFINE(ENABLE_MULTIARCH)
+ MJIT_HEADER_INSTALL_DIR=include/'${arch}/${RUBY_VERSION_NAME}'
+], [
+ MJIT_HEADER_INSTALL_DIR=include/'${RUBY_VERSION_NAME}/${arch}'
])
archlibdir='${libdir}/${arch}'
@@ -3754,7 +3701,7 @@ AS_IF([test x"$gcov" = xyes], [
RUBY_SETJMP_TYPE
}
-[begin]_group "installation section" && {
+: "build section" && {
dnl build rdoc index if requested
RDOCTARGET=""
CAPITARGET=""
@@ -3802,19 +3749,20 @@ AC_SUBST(CAPITARGET)
AS_CASE(["$RDOCTARGET:$CAPITARGET"],[nodoc:nodoc],[INSTALLDOC=nodoc],[INSTALLDOC=all])
AC_SUBST(INSTALLDOC)
-AC_ARG_ENABLE(install-static-library,
- AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]),
- [INSTALL_STATIC_LIBRARY=$enableval
- AS_IF([test x"$enable_shared" = xno -a x"$INSTALL_STATIC_LIBRARY" = xno],
- [AC_MSG_ERROR([must install either static or shared library])],
- [])],
- AS_IF([test x"$enable_shared" = xyes],
- [INSTALL_STATIC_LIBRARY=no],
- [INSTALL_STATIC_LIBRARY=yes]))
-AC_SUBST(INSTALL_STATIC_LIBRARY)
-}
+AC_ARG_ENABLE(jit-support,
+ AS_HELP_STRING([--disable-jit-support], [disable JIT features]),
+ [MJIT_SUPPORT=$enableval],
+ [AS_CASE(["$target_os"],
+ [wasi | mingw* | solaris*], [MJIT_SUPPORT=no],
+ [MJIT_SUPPORT=yes]
+ )])
+
+AS_IF([test x"$MJIT_SUPPORT" = "xyes"],
+ [AC_DEFINE(USE_MJIT, 1)],
+ [AC_DEFINE(USE_MJIT, 0)])
+
+AC_SUBST(MJIT_SUPPORT)
-[begin]_group "JIT section" && {
AC_CHECK_PROG(RUSTC, [rustc], [rustc], [no]) dnl no ac_tool_prefix
dnl check if rustc is recent enough to build YJIT (rustc >= 1.58.0)
@@ -3860,8 +3808,8 @@ AC_ARG_ENABLE(yjit,
AS_HELP_STRING([--enable-yjit],
[enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]),
[YJIT_SUPPORT=$enableval],
- [AS_CASE(["$YJIT_TARGET_OK:$YJIT_RUSTC_OK"],
- [yes:yes], [
+ [AS_CASE(["$enable_jit_support:$YJIT_TARGET_OK:$YJIT_RUSTC_OK"],
+ [yes:yes:yes|:yes:yes], [
YJIT_SUPPORT=yes
],
[YJIT_SUPPORT=no]
@@ -3873,6 +3821,9 @@ CARGO_BUILD_ARGS=
YJIT_LIBS=
AS_CASE(["${YJIT_SUPPORT}"],
[yes|dev|stats|dev_nodebug], [
+ AS_IF([test x"$enable_jit_support" = "xno"],
+ AC_MSG_ERROR([--disable-jit-support but --enable-yjit. YJIT requires JIT support])
+ )
AS_IF([test x"$RUSTC" = "xno"],
AC_MSG_ERROR([rustc is required. Installation instructions available at https://www.rust-lang.org/tools/install])
)
@@ -3889,7 +3840,6 @@ AS_CASE(["${YJIT_SUPPORT}"],
[dev_nodebug], [
rb_rust_target_subdir=dev_nodebug
CARGO_BUILD_ARGS='--profile dev_nodebug --features stats,disasm'
- AC_DEFINE(YJIT_STATS, 1)
],
[stats], [
rb_rust_target_subdir=stats
@@ -3913,9 +3863,7 @@ AS_CASE(["${YJIT_SUPPORT}"],
AC_DEFINE_UNQUOTED(YJIT_SUPPORT, [$YJIT_SUPPORT])
])
AC_DEFINE(USE_YJIT, 1)
-], [
- AC_DEFINE(USE_YJIT, 0)
-])
+], [AC_DEFINE(USE_YJIT, 0)])
dnl These variables end up in ::RbConfig::CONFIG
AC_SUBST(YJIT_SUPPORT)dnl what flavor of YJIT the Ruby build includes
@@ -3925,53 +3873,17 @@ AC_SUBST(CARGO_BUILD_ARGS)dnl for selecting Rust build profiles
AC_SUBST(YJIT_LIBS)dnl for optionally building the Rust parts of YJIT
AC_SUBST(YJIT_OBJ)dnl for optionally building the C parts of YJIT
-dnl RJIT supports only x86_64 platforms, but allows arm64/aarch64 for custom JITs.
-RJIT_TARGET_OK=no
-AS_IF([test "$cross_compiling" = no],
- AS_CASE(["$target_cpu-$target_os"],
- [*android*], [
- RJIT_TARGET_OK=no
- ],
- [arm64-darwin*|aarch64-darwin*|x86_64-darwin*], [
- RJIT_TARGET_OK=yes
- ],
- [arm64-*linux*|aarch64-*linux*|x86_64-*linux*], [
- RJIT_TARGET_OK=yes
- ],
- [arm64-*bsd*|aarch64-*bsd*|x86_64-*bsd*], [
- RJIT_TARGET_OK=yes
- ]
- )
-)
-
-dnl Build RJIT on supported platforms or if --enable-rjit is specified.
-AC_ARG_ENABLE(rjit,
- AS_HELP_STRING([--enable-rjit],
- [enable pure-Ruby JIT compiler. enabled by default on Unix x86_64 platforms]),
- [RJIT_SUPPORT=$enableval],
- [AS_CASE(["$RJIT_TARGET_OK"],
- [yes], [RJIT_SUPPORT=yes],
- [RJIT_SUPPORT=no]
- )]
-)
-
-AS_CASE(["$RJIT_SUPPORT"],
-[yes|dev], [
- AS_CASE(["$RJIT_SUPPORT"],
- [dev], [
- # Link libcapstone for --rjit-dump-disasm
- AC_CHECK_LIB([capstone], [cs_disasm])
- ])
-
- AC_DEFINE(USE_RJIT, 1)
-], [
- AC_DEFINE(USE_RJIT, 0)
-])
-
-AC_SUBST(RJIT_SUPPORT)
-}
+AC_ARG_ENABLE(install-static-library,
+ AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]),
+ [INSTALL_STATIC_LIBRARY=$enableval
+ AS_IF([test x"$enable_shared" = xno -a x"$INSTALL_STATIC_LIBRARY" = xno],
+ [AC_MSG_ERROR([must install either static or shared library])],
+ [])],
+ AS_IF([test x"$enable_shared" = xyes],
+ [INSTALL_STATIC_LIBRARY=no],
+ [INSTALL_STATIC_LIBRARY=yes]))
+AC_SUBST(INSTALL_STATIC_LIBRARY)
-[begin]_group "build section" && {
AC_CACHE_CHECK([for prefix of external symbols], rb_cv_symbol_prefix, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[extern void conftest_external(void) {}]], [[]])],[
rb_cv_symbol_prefix=`$NM conftest.$ac_objext |
@@ -3982,23 +3894,6 @@ AC_CACHE_CHECK([for prefix of external symbols], rb_cv_symbol_prefix, [
])
SYMBOL_PREFIX="$rb_cv_symbol_prefix"
test "x$SYMBOL_PREFIX" = xNONE && SYMBOL_PREFIX=''
-
-AS_IF([test x"$enable_shared" = xyes], [
- AC_CACHE_CHECK([for default symbols in empty shared library], rb_cv_symbols_in_emptylib, [
- save_CC="$CC"
- eval CC=\"`printf "%s" "${DLDSHARED}" | sed ['s/\$(CC)/${CC}/']`\"
- AC_LINK_IFELSE([AC_LANG_PROGRAM()],[
- rb_cv_symbols_in_emptylib=`$NM -Pgp conftest$ac_exeext |
- sed ["/ [A-TV-Z] .*/!d;s///;s/^${SYMBOL_PREFIX}//;/^main$/d"]`
- ])
- set dummy ${rb_cv_symbols_in_emptylib}
- shift
- rb_cv_symbols_in_emptylib="$*"
- CC="$save_CC"
- ])
-])
-AC_SUBST(XSYMBOLS_IN_EMPTYLIB, "${rb_cv_symbols_in_emptylib}")
-
DLNOBJ=dln.o
AC_ARG_ENABLE(dln,
AS_HELP_STRING([--disable-dln], [disable dynamic link feature]),
@@ -4176,9 +4071,8 @@ AS_IF([test "${universal_binary-no}" = yes ], [
const char arch[[]] = __ARCHITECTURE__;]], [[puts(arch);]])],
[rb_cv_architecture_available=yes], [rb_cv_architecture_available=no]))
])
-}
-[end]_group
+: ${MJIT_LDSHARED=`echo "$LDSHARED" | sed ['s|\$(LD)|'"${LD}"'|g;s|\$(CC)|$(MJIT_CC)|g']`}
MAINLIBS="$LIBS"
LIBS=$ORIG_LIBS
@@ -4244,7 +4138,6 @@ AC_SUBST(MINIOBJS)
AC_SUBST(THREAD_MODEL)
AC_SUBST(COROUTINE_TYPE, ${coroutine_type})
AC_SUBST(PLATFORM_DIR)
-AC_SUBST(USE_LLVM_WINDRES)
firstmf=`echo $FIRSTMAKEFILE | sed 's/:.*//'`
firsttmpl=`echo $FIRSTMAKEFILE | sed 's/.*://'`
@@ -4396,10 +4289,6 @@ AS_IF([test "${universal_binary-no}" = yes ], [
arch="${target_cpu}-${target_os}"
])
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "$arch")
-
- AS_IF([test "$arch" = "s390x-linux"], [
- AC_DEFINE_UNQUOTED(USE_MN_THREADS, 0)
- ])
])
unset sitearch
@@ -4504,7 +4393,7 @@ guard=INCLUDE_RUBY_CONFIG_H
{
echo "#ifndef $guard"
echo "#define $guard 1"
- sed "/^@%:@define PACKAGE_/d;s/ *$//" confdefs.h
+ grep -v "^#define PACKAGE_" confdefs.h
echo "#endif /* $guard */"
} | tr -d '\015' |
(
@@ -4622,6 +4511,7 @@ AC_SUBST(DESTDIR)
AC_OUTPUT
}
+}
AS_IF([test "$silent" = yes], [], [
AS_IF([${FOLD+:} false], [], [
@@ -4669,8 +4559,8 @@ config_summary "debugflags" "$debugflags"
config_summary "warnflags" "$warnflags"
config_summary "strip command" "$STRIP"
config_summary "install doc" "$DOCTARGETS"
+config_summary "MJIT support" "$MJIT_SUPPORT"
config_summary "YJIT support" "$YJIT_SUPPORT"
-config_summary "RJIT support" "$RJIT_SUPPORT"
config_summary "man page type" "$MANTYPE"
config_summary "search path" "$search_path"
config_summary "static-linked-ext" ${EXTSTATIC:+"yes"}
diff --git a/constant.h b/constant.h
index 90a68d447a..e0d36909e1 100644
--- a/constant.h
+++ b/constant.h
@@ -43,11 +43,13 @@ VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj);
void rb_free_const_table(struct rb_id_table *tbl);
VALUE rb_const_source_location(VALUE, ID);
+MJIT_SYMBOL_EXPORT_BEGIN
int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag);
rb_const_entry_t *rb_const_lookup(VALUE klass, ID id);
VALUE rb_public_const_get_at(VALUE klass, ID id);
VALUE rb_public_const_get_from(VALUE klass, ID id);
int rb_public_const_defined_from(VALUE klass, ID id);
VALUE rb_const_source_location_at(VALUE, ID);
+MJIT_SYMBOL_EXPORT_END
#endif /* CONSTANT_H */
diff --git a/cont.c b/cont.c
index 55040d3d38..5375d1945b 100644
--- a/cont.c
+++ b/cont.c
@@ -26,16 +26,15 @@ extern int madvise(caddr_t, size_t, int);
#include COROUTINE_H
#include "eval_intern.h"
+#include "gc.h"
#include "internal.h"
#include "internal/cont.h"
-#include "internal/thread.h"
#include "internal/error.h"
-#include "internal/gc.h"
#include "internal/proc.h"
#include "internal/sanitizers.h"
#include "internal/warnings.h"
#include "ruby/fiber/scheduler.h"
-#include "rjit.h"
+#include "mjit.h"
#include "yjit.h"
#include "vm_core.h"
#include "vm_sync.h"
@@ -71,6 +70,8 @@ static VALUE rb_cFiberPool;
#define FIBER_POOL_ALLOCATION_FREE
#endif
+#define jit_cont_enabled (mjit_enabled || rb_yjit_enabled_p())
+
enum context_type {
CONTINUATION_CONTEXT = 0,
FIBER_CONTEXT = 1
@@ -177,7 +178,7 @@ struct fiber_pool {
// A singly-linked list of allocations which contain 1 or more stacks each.
struct fiber_pool_allocation * allocations;
- // Free list that provides O(1) stack "allocation".
+ // Provides O(1) stack "allocation":
struct fiber_pool_vacancy * vacancies;
// The size of the stack allocations (excluding any guard page).
@@ -189,15 +190,13 @@ struct fiber_pool {
// The initial number of stacks to allocate.
size_t initial_count;
- // Whether to madvise(free) the stack or not.
- // If this value is set to 1, the stack will be madvise(free)ed
- // (or equivalent), where possible, when it is returned to the pool.
+ // Whether to madvise(free) the stack or not:
int free_stacks;
// The number of stacks that have been used in this pool.
size_t used;
- // The amount to allocate for the vm_stack.
+ // The amount to allocate for the vm_stack:
size_t vm_stack_size;
};
@@ -230,18 +229,18 @@ typedef struct rb_context_struct {
struct rb_jit_cont *jit_cont; // Continuation contexts for JITs
} rb_context_t;
+
/*
* Fiber status:
- * [Fiber.new] ------> FIBER_CREATED ----> [Fiber#kill] --> |
- * | [Fiber#resume] |
- * v |
- * +--> FIBER_RESUMED ----> [return] ------> |
- * [Fiber#resume] | | [Fiber.yield/transfer] |
- * [Fiber#transfer] | v |
- * +--- FIBER_SUSPENDED --> [Fiber#kill] --> |
- * |
- * |
- * FIBER_TERMINATED <-------------------+
+ * [Fiber.new] ------> FIBER_CREATED
+ * | [Fiber#resume]
+ * v
+ * +--> FIBER_RESUMED ----+
+ * [Fiber#resume] | | [Fiber.yield] |
+ * | v |
+ * +-- FIBER_SUSPENDED | [Terminate]
+ * |
+ * FIBER_TERMINATED <-+
*/
enum fiber_status {
FIBER_CREATED,
@@ -267,20 +266,12 @@ struct rb_fiber_struct {
unsigned int yielding : 1;
unsigned int blocking : 1;
- unsigned int killed : 1;
-
struct coroutine_context context;
struct fiber_pool_stack stack;
};
static struct fiber_pool shared_fiber_pool = {NULL, NULL, 0, 0, 0, 0};
-void
-rb_free_shared_fiber_pool(void)
-{
- xfree(shared_fiber_pool.allocations);
-}
-
static ID fiber_initialize_keywords[3] = {0};
/*
@@ -701,9 +692,7 @@ fiber_pool_stack_free(struct fiber_pool_stack * stack)
// If this is not true, the vacancy information will almost certainly be destroyed:
VM_ASSERT(size <= (stack->size - RB_PAGE_SIZE));
- int advice = stack->pool->free_stacks >> 1;
-
- if (DEBUG) fprintf(stderr, "fiber_pool_stack_free: %p+%"PRIuSIZE" [base=%p, size=%"PRIuSIZE"] advice=%d\n", base, size, stack->base, stack->size, advice);
+ if (DEBUG) fprintf(stderr, "fiber_pool_stack_free: %p+%"PRIuSIZE" [base=%p, size=%"PRIuSIZE"]\n", base, size, stack->base, stack->size);
// The pages being used by the stack can be returned back to the system.
// That doesn't change the page mapping, but it does allow the system to
@@ -717,29 +706,24 @@ fiber_pool_stack_free(struct fiber_pool_stack * stack)
#ifdef __wasi__
// WebAssembly doesn't support madvise, so we just don't do anything.
#elif VM_CHECK_MODE > 0 && defined(MADV_DONTNEED)
- if (!advice) advice = MADV_DONTNEED;
// This immediately discards the pages and the memory is reset to zero.
- madvise(base, size, advice);
+ madvise(base, size, MADV_DONTNEED);
#elif defined(MADV_FREE_REUSABLE)
- if (!advice) advice = MADV_FREE_REUSABLE;
// Darwin / macOS / iOS.
// Acknowledge the kernel down to the task info api we make this
// page reusable for future use.
- // As for MADV_FREE_REUSABLE below we ensure in the rare occasions the task was not
+ // As for MADV_FREE_REUSE below we ensure in the rare occasions the task was not
// completed at the time of the call to re-iterate.
- while (madvise(base, size, advice) == -1 && errno == EAGAIN);
+ while (madvise(base, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN);
#elif defined(MADV_FREE)
- if (!advice) advice = MADV_FREE;
// Recent Linux.
- madvise(base, size, advice);
+ madvise(base, size, MADV_FREE);
#elif defined(MADV_DONTNEED)
- if (!advice) advice = MADV_DONTNEED;
// Old Linux.
- madvise(base, size, advice);
+ madvise(base, size, MADV_DONTNEED);
#elif defined(POSIX_MADV_DONTNEED)
- if (!advice) advice = POSIX_MADV_DONTNEED;
// Solaris?
- posix_madvise(base, size, advice);
+ posix_madvise(base, size, POSIX_MADV_DONTNEED);
#elif defined(_WIN32)
VirtualAlloc(base, size, MEM_RESET, PAGE_READWRITE);
// Not available in all versions of Windows.
@@ -1066,8 +1050,10 @@ cont_free(void *ptr)
RUBY_FREE_UNLESS_NULL(cont->saved_vm_stack.ptr);
- VM_ASSERT(cont->jit_cont != NULL);
- jit_cont_free(cont->jit_cont);
+ if (jit_cont_enabled) {
+ VM_ASSERT(cont->jit_cont != NULL);
+ jit_cont_free(cont->jit_cont);
+ }
/* free rb_cont_t or rb_fiber_t */
ruby_xfree(ptr);
RUBY_FREE_LEAVE("cont");
@@ -1296,42 +1282,26 @@ rb_jit_cont_each_iseq(rb_iseq_callback callback, void *data)
if (cont->ec->vm_stack == NULL)
continue;
- const rb_control_frame_t *cfp = cont->ec->cfp;
- while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) {
- if (cfp->pc && cfp->iseq && imemo_type((VALUE)cfp->iseq) == imemo_iseq) {
- callback(cfp->iseq, data);
+ const rb_control_frame_t *cfp;
+ for (cfp = RUBY_VM_END_CONTROL_FRAME(cont->ec) - 1; ; cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp)) {
+ const rb_iseq_t *iseq;
+ if (cfp->pc && (iseq = cfp->iseq) != NULL && imemo_type((VALUE)iseq) == imemo_iseq) {
+ callback(iseq, data);
}
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- }
- }
-}
-
-#if USE_YJIT
-// Update the jit_return of all CFPs to leave_exit unless it's leave_exception or not set.
-// This prevents jit_exec_exception from jumping to the caller after invalidation.
-void
-rb_yjit_cancel_jit_return(void *leave_exit, void *leave_exception)
-{
- struct rb_jit_cont *cont;
- for (cont = first_jit_cont; cont != NULL; cont = cont->next) {
- if (cont->ec->vm_stack == NULL)
- continue;
- const rb_control_frame_t *cfp = cont->ec->cfp;
- while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) {
- if (cfp->jit_return && cfp->jit_return != leave_exception) {
- ((rb_control_frame_t *)cfp)->jit_return = leave_exit;
- }
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+ if (cfp == cont->ec->cfp)
+ break; // reached the most recent cfp
}
}
}
-#endif
// Finish working with jit_cont.
void
rb_jit_cont_finish(void)
{
+ if (!jit_cont_enabled)
+ return;
+
struct rb_jit_cont *cont, *next;
for (cont = first_jit_cont; cont != NULL; cont = next) {
next = cont->next;
@@ -1344,8 +1314,9 @@ static void
cont_init_jit_cont(rb_context_t *cont)
{
VM_ASSERT(cont->jit_cont == NULL);
- // We always allocate this since YJIT may be enabled later
- cont->jit_cont = jit_cont_new(&(cont->saved_ec));
+ if (jit_cont_enabled) {
+ cont->jit_cont = jit_cont_new(&(cont->saved_ec));
+ }
}
struct rb_execution_context_struct *
@@ -1392,11 +1363,15 @@ rb_fiberptr_blocking(struct rb_fiber_struct *fiber)
return fiber->blocking;
}
-// Initialize the jit_cont_lock
+// Start working with jit_cont.
void
rb_jit_cont_init(void)
{
+ if (!jit_cont_enabled)
+ return;
+
rb_native_mutex_initialize(&jit_cont_lock);
+ cont_init_jit_cont(&GET_EC()->fiber_ptr->cont);
}
#if 0
@@ -2021,7 +1996,6 @@ fiber_t_alloc(VALUE fiber_value, unsigned int blocking)
fiber->cont.self = fiber_value;
fiber->cont.type = FIBER_CONTEXT;
fiber->blocking = blocking;
- fiber->killed = 0;
cont_init(&fiber->cont, th);
fiber->cont.saved_ec.fiber_ptr = fiber;
@@ -2087,10 +2061,10 @@ fiber_storage_set(struct rb_fiber_struct *fiber, VALUE storage)
}
static inline VALUE
-fiber_storage_get(rb_fiber_t *fiber, int allocate)
+fiber_storage_get(rb_fiber_t *fiber)
{
VALUE storage = fiber->cont.saved_ec.storage;
- if (storage == Qnil && allocate) {
+ if (storage == Qnil) {
storage = rb_hash_new();
fiber_storage_set(fiber, storage);
}
@@ -2117,15 +2091,7 @@ static VALUE
rb_fiber_storage_get(VALUE self)
{
storage_access_must_be_from_same_fiber(self);
-
- VALUE storage = fiber_storage_get(fiber_ptr(self), FALSE);
-
- if (storage == Qnil) {
- return Qnil;
- }
- else {
- return rb_obj_dup(storage);
- }
+ return rb_obj_dup(fiber_storage_get(fiber_ptr(self)));
}
static int
@@ -2205,7 +2171,8 @@ rb_fiber_storage_aref(VALUE class, VALUE key)
{
Check_Type(key, T_SYMBOL);
- VALUE storage = fiber_storage_get(fiber_current(), FALSE);
+ VALUE storage = fiber_storage_get(fiber_current());
+
if (storage == Qnil) return Qnil;
return rb_hash_aref(storage, key);
@@ -2226,15 +2193,9 @@ rb_fiber_storage_aset(VALUE class, VALUE key, VALUE value)
{
Check_Type(key, T_SYMBOL);
- VALUE storage = fiber_storage_get(fiber_current(), value != Qnil);
- if (storage == Qnil) return Qnil;
+ VALUE storage = fiber_storage_get(fiber_current());
- if (value == Qnil) {
- return rb_hash_delete(storage, key);
- }
- else {
- return rb_hash_aset(storage, key, value);
- }
+ return rb_hash_aset(storage, key, value);
}
static VALUE
@@ -2512,6 +2473,7 @@ rb_fiber_start(rb_fiber_t *fiber)
rb_proc_t *proc;
enum ruby_tag_type state;
+ int need_interrupt = TRUE;
VM_ASSERT(th->ec == GET_EC());
VM_ASSERT(FIBER_RESUMED_P(fiber));
@@ -2537,7 +2499,6 @@ rb_fiber_start(rb_fiber_t *fiber)
}
EC_POP_TAG();
- int need_interrupt = TRUE;
VALUE err = Qfalse;
if (state) {
err = th->ec->errinfo;
@@ -2546,16 +2507,13 @@ rb_fiber_start(rb_fiber_t *fiber)
if (state == TAG_RAISE) {
// noop...
}
- else if (state == TAG_FATAL && err == RUBY_FATAL_FIBER_KILLED) {
- need_interrupt = FALSE;
- err = Qfalse;
- }
else if (state == TAG_FATAL) {
rb_threadptr_pending_interrupt_enque(th, err);
}
else {
err = rb_vm_make_jump_tag_but_local_jump(state, err);
}
+ need_interrupt = TRUE;
}
rb_fiber_terminate(fiber, need_interrupt, err);
@@ -2574,9 +2532,12 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th)
fiber->cont.saved_ec.fiber_ptr = fiber;
fiber->cont.saved_ec.thread_ptr = th;
fiber->blocking = 1;
- fiber->killed = 0;
fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */
th->ec = &fiber->cont.saved_ec;
+ // When rb_threadptr_root_fiber_setup is called for the first time, mjit_enabled and
+ // rb_yjit_enabled_p() are still false. So this does nothing and rb_jit_cont_init() that is
+ // called later will take care of it. However, you still have to call cont_init_jit_cont()
+ // here for other Ractors, which are not initialized by rb_jit_cont_init().
cont_init_jit_cont(&fiber->cont);
}
@@ -2587,12 +2548,12 @@ rb_threadptr_root_fiber_release(rb_thread_t *th)
/* ignore. A root fiber object will free th->ec */
}
else {
- rb_execution_context_t *ec = rb_current_execution_context(false);
+ rb_execution_context_t *ec = GET_EC();
VM_ASSERT(th->ec->fiber_ptr->cont.type == FIBER_CONTEXT);
VM_ASSERT(th->ec->fiber_ptr->cont.self == 0);
- if (ec && th->ec == ec) {
+ if (th->ec == ec) {
rb_ractor_set_current_ec(th->ractor, NULL);
}
fiber_free(th->ec->fiber_ptr);
@@ -2673,19 +2634,6 @@ fiber_store(rb_fiber_t *next_fiber, rb_thread_t *th)
fiber_setcontext(next_fiber, fiber);
}
-static void
-fiber_check_killed(rb_fiber_t *fiber)
-{
- VM_ASSERT(fiber == fiber_current());
-
- if (fiber->killed) {
- rb_thread_t *thread = fiber->cont.saved_ec.thread_ptr;
-
- thread->ec->errinfo = RUBY_FATAL_FIBER_KILLED;
- EC_JUMP_TAG(thread->ec, RUBY_TAG_FATAL);
- }
-}
-
static inline VALUE
fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fiber_t *resuming_fiber, bool yielding)
{
@@ -2774,14 +2722,7 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fi
current_fiber = th->ec->fiber_ptr;
value = current_fiber->cont.value;
-
- fiber_check_killed(current_fiber);
-
- if (current_fiber->cont.argc == -1) {
- // Fiber#raise will trigger this path.
- rb_exc_raise(value);
- }
-
+ if (current_fiber->cont.argc == -1) rb_exc_raise(value);
return value;
}
@@ -2817,8 +2758,6 @@ fiber_blocking_yield(VALUE fiber_value)
rb_fiber_t *fiber = fiber_ptr(fiber_value);
rb_thread_t * volatile th = fiber->cont.saved_ec.thread_ptr;
- VM_ASSERT(fiber->blocking == 0);
-
// fiber->blocking is `unsigned int : 1`, so we use it as a boolean:
fiber->blocking = 1;
@@ -3221,13 +3160,12 @@ rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass)
}
static VALUE
-fiber_raise(rb_fiber_t *fiber, VALUE exception)
+fiber_raise(rb_fiber_t *fiber, int argc, const VALUE *argv)
{
- if (fiber == fiber_current()) {
- rb_exc_raise(exception);
- }
- else if (fiber->resuming_fiber) {
- return fiber_raise(fiber->resuming_fiber, exception);
+ VALUE exception = rb_make_exception(argc, argv);
+
+ if (fiber->resuming_fiber) {
+ rb_raise(rb_eFiberError, "attempt to raise a resuming fiber");
}
else if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) {
return fiber_transfer_kw(fiber, -1, &exception, RB_NO_KEYWORDS);
@@ -3240,9 +3178,7 @@ fiber_raise(rb_fiber_t *fiber, VALUE exception)
VALUE
rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv)
{
- VALUE exception = rb_make_exception(argc, argv);
-
- return fiber_raise(fiber_ptr(fiber), exception);
+ return fiber_raise(fiber_ptr(fiber), argc, argv);
}
/*
@@ -3265,8 +3201,6 @@ rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv)
* the exception, and the third parameter is an array of callback information.
* Exceptions are caught by the +rescue+ clause of <code>begin...end</code>
* blocks.
- *
- * Raises +FiberError+ if called on a Fiber belonging to another +Thread+.
*/
static VALUE
rb_fiber_m_raise(int argc, VALUE *argv, VALUE self)
@@ -3276,45 +3210,6 @@ rb_fiber_m_raise(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
- * fiber.kill -> nil
- *
- * Terminates the fiber by raising an uncatchable exception.
- * It only terminates the given fiber and no other fiber, returning +nil+ to
- * another fiber if that fiber was calling #resume or #transfer.
- *
- * <tt>Fiber#kill</tt> only interrupts another fiber when it is in Fiber.yield.
- * If called on the current fiber then it raises that exception at the <tt>Fiber#kill</tt> call site.
- *
- * If the fiber has not been started, transition directly to the terminated state.
- *
- * If the fiber is already terminated, does nothing.
- *
- * Raises FiberError if called on a fiber belonging to another thread.
- */
-static VALUE
-rb_fiber_m_kill(VALUE self)
-{
- rb_fiber_t *fiber = fiber_ptr(self);
-
- if (fiber->killed) return Qfalse;
- fiber->killed = 1;
-
- if (fiber->status == FIBER_CREATED) {
- fiber->status = FIBER_TERMINATED;
- }
- else if (fiber->status != FIBER_TERMINATED) {
- if (fiber_current() == fiber) {
- fiber_check_killed(fiber);
- } else {
- fiber_raise(fiber_ptr(self), Qnil);
- }
- }
-
- return self;
-}
-
-/*
- * call-seq:
* Fiber.current -> fiber
*
* Returns the current fiber. If you are not running in the context of
@@ -3471,15 +3366,6 @@ Init_Cont(void)
const char *fiber_shared_fiber_pool_free_stacks = getenv("RUBY_SHARED_FIBER_POOL_FREE_STACKS");
if (fiber_shared_fiber_pool_free_stacks) {
shared_fiber_pool.free_stacks = atoi(fiber_shared_fiber_pool_free_stacks);
-
- if (shared_fiber_pool.free_stacks < 0) {
- rb_warn("Setting RUBY_SHARED_FIBER_POOL_FREE_STACKS to a negative value is not allowed.");
- shared_fiber_pool.free_stacks = 0;
- }
-
- if (shared_fiber_pool.free_stacks > 1) {
- rb_warn("Setting RUBY_SHARED_FIBER_POOL_FREE_STACKS to a value greater than 1 is operating system specific, and may cause crashes.");
- }
}
rb_cFiber = rb_define_class("Fiber", rb_cObject);
@@ -3497,7 +3383,6 @@ Init_Cont(void)
rb_define_method(rb_cFiber, "storage=", rb_fiber_storage_set, 1);
rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
rb_define_method(rb_cFiber, "raise", rb_fiber_m_raise, -1);
- rb_define_method(rb_cFiber, "kill", rb_fiber_m_kill, 0);
rb_define_method(rb_cFiber, "backtrace", rb_fiber_backtrace, -1);
rb_define_method(rb_cFiber, "backtrace_locations", rb_fiber_backtrace_locations, -1);
rb_define_method(rb_cFiber, "to_s", fiber_to_s, 0);
diff --git a/coroutine/amd64/Context.S b/coroutine/amd64/Context.S
index 056c276a31..d50732adbc 100644
--- a/coroutine/amd64/Context.S
+++ b/coroutine/amd64/Context.S
@@ -13,35 +13,29 @@
.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
- # Make space on the stack for 6 registers:
- subq $48, %rsp
-
- # Save caller state:
- movq %rbp, 40(%rsp)
- movq %rbx, 32(%rsp)
- movq %r12, 24(%rsp)
- movq %r13, 16(%rsp)
- movq %r14, 8(%rsp)
- movq %r15, (%rsp)
-
- # Save caller stack pointer:
+ # Save caller state
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ # Save caller stack pointer
movq %rsp, (%rdi)
- # Restore callee stack pointer:
+ # Restore callee stack pointer
movq (%rsi), %rsp
# Restore callee state
- movq 40(%rsp), %rbp
- movq 32(%rsp), %rbx
- movq 24(%rsp), %r12
- movq 16(%rsp), %r13
- movq 8(%rsp), %r14
- movq (%rsp), %r15
-
- # Adjust stack pointer back:
- addq $48, %rsp
-
- # Put the first argument into the return value:
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+
+ # Put the first argument into the return value
movq %rdi, %rax
# We pop the return address and jump to it
diff --git a/coroutine/arm64/Context.S b/coroutine/arm64/Context.S
index eeb0f774a3..07d50d30df 100644
--- a/coroutine/arm64/Context.S
+++ b/coroutine/arm64/Context.S
@@ -18,25 +18,11 @@
.align 2
#endif
-## NOTE(PAC): Use we HINT mnemonics instead of PAC mnemonics to
-## keep compatibility with those assemblers that don't support PAC.
-##
-## See "Providing protection for complex software" for more details about PAC/BTI
-## https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software
-
.global PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
-#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0)
- # paciasp (it also acts as BTI landing pad, so no need to insert BTI also)
- hint #25
-#elif defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT != 0)
- # For the the case PAC is not enabled but BTI is.
- # bti c
- hint #34
-#endif
# Make space on the stack for caller registers
- sub sp, sp, 0xa0
+ sub sp, sp, 0xb0
# Save caller registers
stp d8, d9, [sp, 0x00]
@@ -50,6 +36,9 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
stp x27, x28, [sp, 0x80]
stp x29, x30, [sp, 0x90]
+ # Save return address
+ str x30, [sp, 0xa0]
+
# Save stack pointer to x0 (first argument)
mov x2, sp
str x2, [x0, 0]
@@ -70,51 +59,15 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
ldp x27, x28, [sp, 0x80]
ldp x29, x30, [sp, 0x90]
- # Pop stack frame
- add sp, sp, 0xa0
+ # Load return address into x4
+ ldr x4, [sp, 0xa0]
-#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0)
- # autiasp: Authenticate x30 (LR) with SP and key A
- hint #29
-#endif
+ # Pop stack frame
+ add sp, sp, 0xb0
- # Jump to return address (in x30)
- ret
+ # Jump to return address (in x4)
+ ret x4
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
-
-#if __ARM_FEATURE_BTI_DEFAULT != 0 || __ARM_FEATURE_PAC_DEFAULT != 0
-/* See "ELF for the Arm 64-bit Architecture (AArch64)"
- https://github.com/ARM-software/abi-aa/blob/2023Q3/aaelf64/aaelf64.rst#program-property */
-# define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1<<0)
-# define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1<<1)
-
-# if __ARM_FEATURE_BTI_DEFAULT != 0
-# define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI
-# else
-# define BTI_FLAG 0
-# endif
-# if __ARM_FEATURE_PAC_DEFAULT != 0
-# define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC
-# else
-# define PAC_FLAG 0
-# endif
-
- # The note section format is described by Note Section in Chapter 5
- # of "System V Application Binary Interface, Edition 4.1".
- .pushsection .note.gnu.property, "a"
- .p2align 3
- .long 0x4 /* Name size ("GNU\0") */
- .long 0x10 /* Descriptor size */
- .long 0x5 /* Type: NT_GNU_PROPERTY_TYPE_0 */
- .asciz "GNU" /* Name */
- # Begin descriptor
- .long 0xc0000000 /* Property type: GNU_PROPERTY_AARCH64_FEATURE_1_AND */
- .long 0x4 /* Property size */
- .long (BTI_FLAG|PAC_FLAG)
- .long 0x0 /* 8-byte alignment padding */
- # End descriptor
- .popsection
-#endif
diff --git a/coroutine/arm64/Context.h b/coroutine/arm64/Context.h
index 1819fa5be9..1472621f48 100644
--- a/coroutine/arm64/Context.h
+++ b/coroutine/arm64/Context.h
@@ -17,7 +17,7 @@
#define COROUTINE __attribute__((noreturn)) void
-enum {COROUTINE_REGISTERS = 0xa0 / 8};
+enum {COROUTINE_REGISTERS = 0xb0 / 8};
#if defined(__SANITIZE_ADDRESS__)
#define COROUTINE_SANITIZE_ADDRESS
@@ -50,23 +50,6 @@ static inline void coroutine_initialize_main(struct coroutine_context * context)
context->stack_pointer = NULL;
}
-#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT != 0
-// Sign the given instruction address with the given modifier and key A
-static inline void *ptrauth_sign_instruction_addr(void *addr, void *modifier) {
- register void *r17 __asm("r17") = addr;
- register void *r16 __asm("r16") = modifier;
- // Use HINT mnemonic instead of PACIA1716 for compatibility with older assemblers.
- asm ("hint #8;" : "+r"(r17) : "r"(r16));
- addr = r17;
- return addr;
-}
-#else
-// No-op if PAC is not enabled
-static inline void *ptrauth_sign_instruction_addr(void *addr, void *modifier) {
- return addr;
-}
-#endif
-
static inline void coroutine_initialize(
struct coroutine_context *context,
coroutine_start start,
@@ -83,13 +66,12 @@ static inline void coroutine_initialize(
// Stack grows down. Force 16-byte alignment.
char * top = (char*)stack + size;
- top = (char *)((uintptr_t)top & ~0xF);
- context->stack_pointer = (void**)top;
+ context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
context->stack_pointer -= COROUTINE_REGISTERS;
memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
- context->stack_pointer[0x98 / 8] = ptrauth_sign_instruction_addr((void*)start, (void*)top);
+ context->stack_pointer[0xa0 / 8] = (void*)start;
}
struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
diff --git a/coroutine/asyncify/Context.h b/coroutine/asyncify/Context.h
index 7dba829a1d..71791a4004 100644
--- a/coroutine/asyncify/Context.h
+++ b/coroutine/asyncify/Context.h
@@ -13,6 +13,7 @@
#include <stddef.h>
#include <stdio.h>
+#include <stdint.h>
#include "wasm/asyncify.h"
#include "wasm/machine.h"
#include "wasm/fiber.h"
@@ -47,10 +48,13 @@ static inline void coroutine_initialize_main(struct coroutine_context * context)
static inline void coroutine_initialize(struct coroutine_context *context, coroutine_start start, void *stack, size_t size)
{
- if (ASYNCIFY_CORO_DEBUG) fprintf(stderr, "[%s] entry (context = %p, stack = %p ... %p)\n", __func__, context, stack, (char *)stack + size);
+ // Linear stack pointer must be always aligned down to 16 bytes.
+ // https://github.com/WebAssembly/tool-conventions/blob/c74267a5897c1bdc9aa60adeaf41816387d3cd12/BasicCABI.md#the-linear-stack
+ uintptr_t sp = ((uintptr_t)stack + size) & ~0xF;
+ if (ASYNCIFY_CORO_DEBUG) fprintf(stderr, "[%s] entry (context = %p, stack = %p ... %p)\n", __func__, context, stack, (char *)sp);
rb_wasm_init_context(&context->fc, coroutine_trampoline, start, context);
// record the initial stack pointer position to restore it after resumption
- context->current_sp = (char *)stack + size;
+ context->current_sp = (char *)sp;
context->stack_base = stack;
context->size = size;
}
diff --git a/coroutine/loongarch64/Context.S b/coroutine/loongarch64/Context.S
deleted file mode 100644
index 662f5dfb6c..0000000000
--- a/coroutine/loongarch64/Context.S
+++ /dev/null
@@ -1,73 +0,0 @@
-#define TOKEN_PASTE(x,y) x##y
-#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
-
-.text
-.align 2
-
-.global PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
-PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
-
- # Make space on the stack for caller registers
- addi.d $sp, $sp, -0xa0
-
- # Save caller registers
- st.d $s0, $sp, 0x00
- st.d $s1, $sp, 0x08
- st.d $s2, $sp, 0x10
- st.d $s3, $sp, 0x18
- st.d $s4, $sp, 0x20
- st.d $s5, $sp, 0x28
- st.d $s6, $sp, 0x30
- st.d $s7, $sp, 0x38
- st.d $s8, $sp, 0x40
- st.d $fp, $sp, 0x48
- fst.d $fs0, $sp, 0x50
- fst.d $fs1, $sp, 0x58
- fst.d $fs2, $sp, 0x60
- fst.d $fs3, $sp, 0x68
- fst.d $fs4, $sp, 0x70
- fst.d $fs5, $sp, 0x78
- fst.d $fs6, $sp, 0x80
- fst.d $fs7, $sp, 0x88
-
- # Save return address
- st.d $ra, $sp, 0x90
-
- # Save stack pointer to a0 (first argument)
- st.d $sp, $a0, 0x00
-
- # Load stack pointer from a1 (second argument)
- ld.d $sp, $a1, 0x00
-
- # Restore caller registers
- ld.d $s0, $sp, 0x00
- ld.d $s1, $sp, 0x08
- ld.d $s2, $sp, 0x10
- ld.d $s3, $sp, 0x18
- ld.d $s4, $sp, 0x20
- ld.d $s5, $sp, 0x28
- ld.d $s6, $sp, 0x30
- ld.d $s7, $sp, 0x38
- ld.d $s8, $sp, 0x40
- ld.d $fp, $sp, 0x48
- fld.d $fs0, $sp, 0x50
- fld.d $fs1, $sp, 0x58
- fld.d $fs2, $sp, 0x60
- fld.d $fs3, $sp, 0x68
- fld.d $fs4, $sp, 0x70
- fld.d $fs5, $sp, 0x78
- fld.d $fs6, $sp, 0x80
- fld.d $fs7, $sp, 0x88
-
- # Load return address
- ld.d $ra, $sp, 0x90
-
- # Pop stack frame
- addi.d $sp, $sp, 0xa0
-
- # Jump to return address
- jr $ra
-
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
diff --git a/coroutine/loongarch64/Context.h b/coroutine/loongarch64/Context.h
deleted file mode 100644
index 668c9a965e..0000000000
--- a/coroutine/loongarch64/Context.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#define COROUTINE __attribute__((noreturn)) void
-
-enum {COROUTINE_REGISTERS = 0xa0 / 8};
-
-struct coroutine_context
-{
- void **stack_pointer;
- void *argument;
-};
-
-typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
-
-static inline void coroutine_initialize_main(struct coroutine_context * context) {
- context->stack_pointer = NULL;
-}
-
-static inline void coroutine_initialize(
- struct coroutine_context *context,
- coroutine_start start,
- void *stack,
- size_t size
-) {
- assert(start && stack && size >= 1024);
-
- // Stack grows down. Force 16-byte alignment.
- char * top = (char*)stack + size;
- context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
-
- context->stack_pointer -= COROUTINE_REGISTERS;
- memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
-
- context->stack_pointer[0x90 / 8] = (void*)start;
-}
-
-struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
-
-static inline void coroutine_destroy(struct coroutine_context * context)
-{
-}
diff --git a/coroutine/ppc/Context.S b/coroutine/ppc/Context.S
index e2431a9250..cdda93e179 100644
--- a/coroutine/ppc/Context.S
+++ b/coroutine/ppc/Context.S
@@ -3,7 +3,7 @@
; Some relevant examples: https://github.com/gcc-mirror/gcc/blob/master/libphobos/libdruntime/config/powerpc/switchcontext.S
; https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/rs6000/darwin-gpsave.S
; https://www.ibm.com/docs/en/aix/7.2?topic=epilogs-saving-gprs-only
-; ppc32 version may be re-written compactly with stmw/lwm, but the code won't be faster, see: https://github.com/ruby/ruby/pull/5927#issuecomment-1139730541
+; ppc32 version may be re-written compactly with stmw/lwm, but the code wonʼt be faster, see: https://github.com/ruby/ruby/pull/5927#issuecomment-1139730541
; Notice that this code is only for Darwin (macOS). Darwin ABI differs from AIX and ELF.
; To add support for AIX, *BSD or *Linux, please make separate implementations.
diff --git a/coroutine/ppc/Context.h b/coroutine/ppc/Context.h
index 8035d08556..1fce112579 100644
--- a/coroutine/ppc/Context.h
+++ b/coroutine/ppc/Context.h
@@ -13,7 +13,7 @@
enum {
COROUTINE_REGISTERS =
- 20 /* 19 general purpose registers (r13-r31) and 1 return address */
+ 20 /* 19 general purpose registers (r13–r31) and 1 return address */
+ 4 /* space for fiber_entry() to store the link register */
};
diff --git a/coroutine/ppc64/Context.h b/coroutine/ppc64/Context.h
index 085b475ed5..3e6f77f55a 100644
--- a/coroutine/ppc64/Context.h
+++ b/coroutine/ppc64/Context.h
@@ -12,7 +12,7 @@
enum {
COROUTINE_REGISTERS =
- 20 /* 19 general purpose registers (r13-r31) and 1 return address */
+ 20 /* 19 general purpose registers (r13–r31) and 1 return address */
+ 4 /* space for fiber_entry() to store the link register */
};
diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in
index 192a8cc711..f342d2fcf7 100644
--- a/cygwin/GNUmakefile.in
+++ b/cygwin/GNUmakefile.in
@@ -2,15 +2,13 @@ gnumake = yes
include Makefile
+MUNICODE_FLAG := $(if $(filter mingw%,$(target_os)),-municode)
+override EXE_LDFLAGS += $(MUNICODE_FLAG)
+
DLLWRAP = @DLLWRAP@ --target=$(target_os) --driver-name="$(CC)"
-ifeq (@USE_LLVM_WINDRES@,yes) # USE_LLVM_WINDRES
- # llvm-windres fails when preprocessor options are added
- windres-cpp :=
-else
- windres-cpp := $(CPP) -xc
- windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \
- $(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp)))
-endif
+windres-cpp := $(CPP) -xc
+windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \
+ $(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp)))
WINDRES = @WINDRES@ $(windres-cpp) -DRC_INVOKED
STRIP = @STRIP@
@@ -46,7 +44,6 @@ SOLIBS := $(DLL_BASE_NAME).res.$(OBJEXT) $(SOLIBS)
override EXTOBJS += $(if $(filter-out $(RUBYW_INSTALL_NAME),$(@:$(EXEEXT)=)),$(RUBY_INSTALL_NAME),$(@:$(EXEEXT)=)).res.$(OBJEXT)
RCFILES = $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(DLL_BASE_NAME).rc
RUBYDEF = $(DLL_BASE_NAME).def
-override LIBRUBY_FOR_LEAKED_GLOBALS := # DLL shows symbols from import library
ruby: $(PROGRAM)
rubyw: $(WPROGRAM)
@@ -69,7 +66,7 @@ $(PROGRAM): $(RUBY_INSTALL_NAME).res.$(OBJEXT)
$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.$(OBJEXT)
@rm -f $@
$(ECHO) linking $@
- $(Q) $(PURIFY) $(CC) -mwindows -e $(SYMBOL_PREFIX)mainCRTStartup $(LDFLAGS) $(XLDFLAGS) \
+ $(Q) $(PURIFY) $(CC) $(MUNICODE_FLAG) -mwindows -e $(SYMBOL_PREFIX)mainCRTStartup $(LDFLAGS) $(XLDFLAGS) \
$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@
$(STUBPROGRAM): $(RUBY_INSTALL_NAME).res.$(OBJEXT)
diff --git a/darray.h b/darray.h
index 8e1e576355..c9a53f1e01 100644
--- a/darray.h
+++ b/darray.h
@@ -5,9 +5,6 @@
#include <stddef.h>
#include <stdlib.h>
-#include "internal/bits.h"
-#include "internal/gc.h"
-
// Type for a dynamic array. Use to declare a dynamic array.
// It is a pointer so it fits in st_table nicely. Designed
// to be fairly type-safe.
@@ -40,79 +37,66 @@
//
#define rb_darray_ref(ary, idx) (&((ary)->data[(idx)]))
-/* Copy a new element into the array. ptr_to_ary is evaluated multiple times.
- *
- * void rb_darray_append(rb_darray(T) *ptr_to_ary, T element);
- */
-#define rb_darray_append(ptr_to_ary, element) \
- rb_darray_append_impl(ptr_to_ary, element, rb_xrealloc_mul_add)
-
-#define rb_darray_append_without_gc(ptr_to_ary, element) \
- rb_darray_append_impl(ptr_to_ary, element, rb_darray_realloc_mul_add_without_gc)
-
-#define rb_darray_append_impl(ptr_to_ary, element, realloc_func) do { \
- rb_darray_ensure_space((ptr_to_ary), \
- sizeof(**(ptr_to_ary)), \
- sizeof((*(ptr_to_ary))->data[0]), \
- realloc_func); \
+// Copy a new element into the array. ptr_to_ary is evaluated multiple times.
+//
+// void rb_darray_append(rb_darray(T) *ptr_to_ary, T element);
+//
+#define rb_darray_append(ptr_to_ary, element) do { \
+ rb_darray_ensure_space((ptr_to_ary), sizeof(**(ptr_to_ary)), \
+ sizeof((*(ptr_to_ary))->data[0])); \
rb_darray_set(*(ptr_to_ary), \
(*(ptr_to_ary))->meta.size, \
(element)); \
(*(ptr_to_ary))->meta.size++; \
} while (0)
+
+// Last element of the array
+//
+#define rb_darray_back(ary) ((ary)->data[(ary)->meta.size - 1])
+
+// Remove the last element of the array.
+//
+#define rb_darray_pop_back(ary) ((ary)->meta.size--)
+
+// Remove element at idx and replace it by the last element
+#define rb_darray_remove_unordered(ary, idx) do { \
+ rb_darray_set(ary, idx, rb_darray_back(ary)); \
+ rb_darray_pop_back(ary); \
+} while (0);
+
// Iterate over items of the array in a for loop
//
#define rb_darray_foreach(ary, idx_name, elem_ptr_var) \
for (size_t idx_name = 0; idx_name < rb_darray_size(ary) && ((elem_ptr_var) = rb_darray_ref(ary, idx_name)); ++idx_name)
-// Iterate over valid indices in the array in a for loop
+// Iterate over valid indicies in the array in a for loop
//
#define rb_darray_for(ary, idx_name) \
for (size_t idx_name = 0; idx_name < rb_darray_size(ary); ++idx_name)
-/* Make a dynamic array of a certain size. All bytes backing the elements are set to zero.
- * Return 1 on success and 0 on failure.
- *
- * Note that NULL is a valid empty dynamic array.
- *
- * void rb_darray_make(rb_darray(T) *ptr_to_ary, size_t size);
- */
+// Make a dynamic array of a certain size. All bytes backing the elements are set to zero.
+//
+// Note that NULL is a valid empty dynamic array.
+//
+// void rb_darray_make(rb_darray(T) *ptr_to_ary, size_t size);
+//
#define rb_darray_make(ptr_to_ary, size) \
rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), \
- sizeof((*(ptr_to_ary))->data[0]), rb_xcalloc_mul_add)
-
-#define rb_darray_make_without_gc(ptr_to_ary, size) \
- rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), \
- sizeof((*(ptr_to_ary))->data[0]), rb_darray_calloc_mul_add_without_gc)
-
-/* Resize the darray to a new capacity. The new capacity must be greater than
- * or equal to the size of the darray.
- *
- * void rb_darray_resize_capa(rb_darray(T) *ptr_to_ary, size_t capa);
- */
-#define rb_darray_resize_capa_without_gc(ptr_to_ary, capa) \
- rb_darray_resize_capa_impl((ptr_to_ary), rb_darray_next_power_of_two(capa), sizeof(**(ptr_to_ary)), \
- sizeof((*(ptr_to_ary))->data[0]), rb_darray_realloc_mul_add_without_gc)
+ sizeof((*(ptr_to_ary))->data[0]))
#define rb_darray_data_ptr(ary) ((ary)->data)
+// Set the size of the array to zero without freeing the backing memory.
+// Allows reusing the same array.
+//
+#define rb_darray_clear(ary) (ary->meta.size = 0)
+
typedef struct rb_darray_meta {
size_t size;
size_t capa;
} rb_darray_meta_t;
-/* Set the size of the array to zero without freeing the backing memory.
- * Allows reusing the same array. */
-static inline void
-rb_darray_clear(void *ary)
-{
- rb_darray_meta_t *meta = ary;
- if (meta) {
- meta->size = 0;
- }
-}
-
// Get the size of the dynamic array.
//
static inline size_t
@@ -131,86 +115,20 @@ rb_darray_capa(const void *ary)
return meta ? meta->capa : 0;
}
-/* Free the dynamic array. */
+// Free the dynamic array.
+//
static inline void
rb_darray_free(void *ary)
{
rb_darray_meta_t *meta = ary;
- if (meta) ruby_sized_xfree(ary, meta->capa);
-}
-
-static inline void
-rb_darray_free_without_gc(void *ary)
-{
- free(ary);
-}
-
-/* Internal function. Like rb_xcalloc_mul_add but does not trigger GC and does
- * not check for overflow in arithmetic. */
-static inline void *
-rb_darray_calloc_mul_add_without_gc(size_t x, size_t y, size_t z)
-{
- size_t size = (x * y) + z;
-
- void *ptr = calloc(1, size);
- if (ptr == NULL) rb_bug("rb_darray_calloc_mul_add_without_gc: failed");
-
- return ptr;
-}
-
-/* Internal function. Like rb_xrealloc_mul_add but does not trigger GC and does
- * not check for overflow in arithmetic. */
-static inline void *
-rb_darray_realloc_mul_add_without_gc(const void *orig_ptr, size_t x, size_t y, size_t z)
-{
- size_t size = (x * y) + z;
-
- void *ptr = realloc((void *)orig_ptr, size);
- if (ptr == NULL) rb_bug("rb_darray_realloc_mul_add_without_gc: failed");
-
- return ptr;
-}
-
-/* Internal function. Returns the next power of two that is greater than or
- * equal to n. */
-static inline size_t
-rb_darray_next_power_of_two(size_t n)
-{
- return (size_t)(1 << (64 - nlz_int64(n)));
-}
-
-/* Internal function. Resizes the capacity of a darray. The new capacity must
- * be greater than or equal to the size of the darray. */
-static inline void
-rb_darray_resize_capa_impl(void *ptr_to_ary, size_t new_capa, size_t header_size, size_t element_size,
- void *(*realloc_mul_add_impl)(const void *, size_t, size_t, size_t))
-{
- rb_darray_meta_t **ptr_to_ptr_to_meta = ptr_to_ary;
- rb_darray_meta_t *meta = *ptr_to_ptr_to_meta;
-
- rb_darray_meta_t *new_ary = realloc_mul_add_impl(meta, new_capa, element_size, header_size);
-
- if (meta == NULL) {
- /* First allocation. Initialize size. On subsequence allocations
- * realloc takes care of carrying over the size. */
- new_ary->size = 0;
- }
-
- assert(new_ary->size <= new_capa);
-
- new_ary->capa = new_capa;
-
- // We don't have access to the type of the dynamic array in function context.
- // Write out result with memcpy to avoid strict aliasing issue.
- memcpy(ptr_to_ary, &new_ary, sizeof(new_ary));
+ ruby_sized_xfree(ary, meta->capa);
}
// Internal function
// Ensure there is space for one more element.
// Note: header_size can be bigger than sizeof(rb_darray_meta_t) when T is __int128_t, for example.
static inline void
-rb_darray_ensure_space(void *ptr_to_ary, size_t header_size, size_t element_size,
- void *(*realloc_mul_add_impl)(const void *, size_t, size_t, size_t))
+rb_darray_ensure_space(void *ptr_to_ary, size_t header_size, size_t element_size)
{
rb_darray_meta_t **ptr_to_ptr_to_meta = ptr_to_ary;
rb_darray_meta_t *meta = *ptr_to_ptr_to_meta;
@@ -220,12 +138,25 @@ rb_darray_ensure_space(void *ptr_to_ary, size_t header_size, size_t element_size
// Double the capacity
size_t new_capa = current_capa == 0 ? 1 : current_capa * 2;
- rb_darray_resize_capa_impl(ptr_to_ary, new_capa, header_size, element_size, realloc_mul_add_impl);
+ rb_darray_meta_t *doubled_ary = rb_xrealloc_mul_add(meta, new_capa, element_size, header_size);
+ // rb_xrealloc functions guarantee that NULL is not returned
+ assert(doubled_ary != NULL);
+
+ if (meta == NULL) {
+ // First allocation. Initialize size. On subsequence allocations
+ // realloc takes care of carrying over the size.
+ doubled_ary->size = 0;
+ }
+
+ doubled_ary->capa = new_capa;
+
+ // We don't have access to the type of the dynamic array in function context.
+ // Write out result with memcpy to avoid strict aliasing issue.
+ memcpy(ptr_to_ary, &doubled_ary, sizeof(doubled_ary));
}
static inline void
-rb_darray_make_impl(void *ptr_to_ary, size_t array_size, size_t header_size, size_t element_size,
- void *(*calloc_mul_add_impl)(size_t, size_t, size_t))
+rb_darray_make_impl(void *ptr_to_ary, size_t array_size, size_t header_size, size_t element_size)
{
rb_darray_meta_t **ptr_to_ptr_to_meta = ptr_to_ary;
if (array_size == 0) {
@@ -233,7 +164,9 @@ rb_darray_make_impl(void *ptr_to_ary, size_t array_size, size_t header_size, siz
return;
}
- rb_darray_meta_t *meta = calloc_mul_add_impl(array_size, element_size, header_size);
+ rb_darray_meta_t *meta = rb_xcalloc_mul_add(array_size, element_size, header_size);
+ // rb_xcalloc functions guarantee that NULL is not returned
+ assert(meta != NULL);
meta->size = array_size;
meta->capa = array_size;
diff --git a/debug.c b/debug.c
index e84e3d602a..3dd0f71906 100644
--- a/debug.c
+++ b/debug.c
@@ -53,8 +53,14 @@ const union {
rb_econv_result_t econv_result;
enum ruby_preserved_encindex encoding_index;
enum ruby_robject_flags robject_flags;
+#if !USE_RVARGC
+ enum ruby_robject_consts robject_consts;
+#endif
enum ruby_rmodule_flags rmodule_flags;
enum ruby_rstring_flags rstring_flags;
+#if !USE_RVARGC
+ enum ruby_rstring_consts rstring_consts;
+#endif
enum ruby_rarray_flags rarray_flags;
enum ruby_rarray_consts rarray_consts;
enum {
@@ -70,7 +76,7 @@ const union {
RUBY_FMODE_NOREVLOOKUP = 0x00000100,
RUBY_FMODE_TRUNC = FMODE_TRUNC,
RUBY_FMODE_TEXTMODE = FMODE_TEXTMODE,
- RUBY_FMODE_EXTERNAL = 0x00010000,
+ RUBY_FMODE_PREP = 0x00010000,
RUBY_FMODE_SETENC_BY_BOM = FMODE_SETENC_BY_BOM,
RUBY_FMODE_UNIX = 0x00200000,
RUBY_FMODE_INET = 0x00400000,
@@ -112,7 +118,7 @@ ruby_debug_printf(const char *format, ...)
va_end(ap);
}
-#include "internal/gc.h"
+#include "gc.h"
VALUE
ruby_debug_print_value(int level, int debug_level, const char *header, VALUE obj)
@@ -285,20 +291,12 @@ static const char *dlf_type_names[] = {
"func",
};
-#ifdef MAX_PATH
-#define DEBUG_LOG_MAX_PATH (MAX_PATH-1)
-#else
-#define DEBUG_LOG_MAX_PATH 255
-#endif
-
static struct {
char *mem;
unsigned int cnt;
struct debug_log_filter filters[MAX_DEBUG_LOG_FILTER_NUM];
unsigned int filters_num;
- bool show_pid;
rb_nativethread_lock_t lock;
- char output_file[DEBUG_LOG_MAX_PATH+1];
FILE *output;
} debug_log;
@@ -400,39 +398,7 @@ setup_debug_log(void)
}
else {
ruby_debug_log_mode |= ruby_debug_log_file;
-
- // pid extension with %p
- unsigned long len = strlen(log_config);
-
- for (unsigned long i=0, j=0; i<len; i++) {
- const char c = log_config[i];
-
- if (c == '%') {
- i++;
- switch (log_config[i]) {
- case '%':
- debug_log.output_file[j++] = '%';
- break;
- case 'p':
- snprintf(debug_log.output_file + j, DEBUG_LOG_MAX_PATH - j, "%d", getpid());
- j = strlen(debug_log.output_file);
- break;
- default:
- fprintf(stderr, "can not parse RUBY_DEBUG_LOG filename: %s\n", log_config);
- exit(1);
- }
- }
- else {
- debug_log.output_file[j++] = c;
- }
-
- if (j >= DEBUG_LOG_MAX_PATH) {
- fprintf(stderr, "RUBY_DEBUG_LOG=%s is too long\n", log_config);
- exit(1);
- }
- }
-
- if ((debug_log.output = fopen(debug_log.output_file, "w")) == NULL) {
+ if ((debug_log.output = fopen(log_config, "w")) == NULL) {
fprintf(stderr, "can not open %s for RUBY_DEBUG_LOG\n", log_config);
exit(1);
}
@@ -443,17 +409,9 @@ setup_debug_log(void)
(ruby_debug_log_mode & ruby_debug_log_memory) ? "[mem]" : "",
(ruby_debug_log_mode & ruby_debug_log_stderr) ? "[stderr]" : "",
(ruby_debug_log_mode & ruby_debug_log_file) ? "[file]" : "");
- if (debug_log.output_file[0]) {
- fprintf(stderr, "RUBY_DEBUG_LOG filename=%s\n", debug_log.output_file);
- }
-
rb_nativethread_lock_initialize(&debug_log.lock);
setup_debug_log_filter();
-
- if (getenv("RUBY_DEBUG_LOG_PID")) {
- debug_log.show_pid = true;
- }
}
}
@@ -492,7 +450,7 @@ check_filter(const char *str, const struct debug_log_filter *filter, bool *state
// (func_name or file_name) contains baz or boo
//
// RUBY_DEBUG_LOG_FILTER=foo,bar,-baz,-boo
-// returns true if
+// retunrs true if
// (func_name or file_name) contains foo or bar
// or
// (func_name or file_name) doesn't contain baz and
@@ -549,16 +507,10 @@ ruby_debug_log(const char *file, int line, const char *func_name, const char *fm
int len = 0;
int r = 0;
- if (debug_log.show_pid) {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "pid:%d\t", getpid());
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
- len += r;
- }
-
// message title
if (func_name && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "%s\t", func_name);
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
len += r;
}
@@ -577,67 +529,41 @@ ruby_debug_log(const char *file, int line, const char *func_name, const char *fm
// C location
if (file && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "\t%s:%d", pretty_filename(file), line);
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
len += r;
}
- rb_execution_context_t *ec = rb_current_execution_context(false);
-
- // Ruby location
- int ruby_line;
- const char *ruby_file = ec ? rb_source_location_cstr(&ruby_line) : NULL;
-
- if (len < MAX_DEBUG_LOG_MESSAGE_LEN) {
- if (ruby_file) {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t%s:%d", pretty_filename(ruby_file), ruby_line);
- }
- else {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t");
+ if (rb_current_execution_context(false)) {
+ // Ruby location
+ int ruby_line;
+ const char *ruby_file = rb_source_location_cstr(&ruby_line);
+ if (len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ if (ruby_file) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t%s:%d", pretty_filename(ruby_file), ruby_line);
+ }
+ else {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t");
+ }
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
+ len += r;
}
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
- len += r;
- }
-
-#ifdef RUBY_NT_SERIAL
- // native thread information
- if (len < MAX_DEBUG_LOG_MESSAGE_LEN) {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tnt:%d", ruby_nt_serial);
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
- len += r;
- }
-#endif
-
- if (ec) {
- rb_thread_t *th = ec ? rb_ec_thread_ptr(ec) : NULL;
// ractor information
if (ruby_single_main_ractor == NULL) {
- rb_ractor_t *cr = th ? th->ractor : NULL;
- rb_vm_t *vm = GET_VM();
-
+ rb_ractor_t *cr = GET_RACTOR();
if (r && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tr:#%d/%u (%u)",
- cr ? (int)rb_ractor_id(cr) : -1, vm->ractor.cnt, vm->ractor.sched.running_cnt);
-
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tr:#%u/%u",
+ (unsigned int)rb_ractor_id(cr), GET_VM()->ractor.cnt);
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
len += r;
}
}
// thread information
- if (th && r && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
- rb_execution_context_t *rec = th->ractor ? th->ractor->threads.running_ec : NULL;
- const rb_thread_t *rth = rec ? rec->thread_ptr : NULL;
- const rb_thread_t *sth = th->ractor ? th->ractor->threads.sched.running : NULL;
-
- if (rth != th || sth != th) {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%u (rth:%d,sth:%d)",
- rb_th_serial(th), rth ? (int)rb_th_serial(rth) : -1, sth ? (int)rb_th_serial(sth) : -1);
- }
- else {
- r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%u", rb_th_serial(th));
- }
- if (r < 0) rb_bug("ruby_debug_log returns %d", r);
+ const rb_thread_t *th = GET_THREAD();
+ if (r && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
+ r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%u", rb_th_serial(th));
+ if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
len += r;
}
}
diff --git a/debug_counter.c b/debug_counter.c
index 3dcc4c6a3a..463bebf849 100644
--- a/debug_counter.c
+++ b/debug_counter.c
@@ -25,8 +25,10 @@ const char *const rb_debug_counter_names[] = {
#undef RB_DEBUG_COUNTER
};
+MJIT_SYMBOL_EXPORT_BEGIN
size_t rb_debug_counter[numberof(rb_debug_counter_names)];
void rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add);
+MJIT_SYMBOL_EXPORT_END
static rb_nativethread_lock_t debug_counter_lock;
diff --git a/debug_counter.h b/debug_counter.h
index a8b95edded..6e0b8dee60 100644
--- a/debug_counter.h
+++ b/debug_counter.h
@@ -100,13 +100,6 @@ RB_DEBUG_COUNTER(ccf_opt_block_call)
RB_DEBUG_COUNTER(ccf_opt_struct_aref)
RB_DEBUG_COUNTER(ccf_opt_struct_aset)
RB_DEBUG_COUNTER(ccf_super_method)
-RB_DEBUG_COUNTER(ccf_cfunc_other)
-RB_DEBUG_COUNTER(ccf_cfunc_only_splat)
-RB_DEBUG_COUNTER(ccf_cfunc_only_splat_kw)
-RB_DEBUG_COUNTER(ccf_iseq_bmethod)
-RB_DEBUG_COUNTER(ccf_noniseq_bmethod)
-RB_DEBUG_COUNTER(ccf_opt_send_complex)
-RB_DEBUG_COUNTER(ccf_opt_send_simple)
/*
* control frame push counts.
@@ -134,22 +127,29 @@ RB_DEBUG_COUNTER(frame_R2C)
RB_DEBUG_COUNTER(frame_C2C)
RB_DEBUG_COUNTER(frame_C2R)
-/* instance variable counts */
-RB_DEBUG_COUNTER(ivar_get_obj_hit) // Only T_OBJECT hits
-RB_DEBUG_COUNTER(ivar_get_obj_miss) // Only T_OBJECT misses
-RB_DEBUG_COUNTER(ivar_get_ic_hit) // All hits
-RB_DEBUG_COUNTER(ivar_get_ic_miss) // All misses
-RB_DEBUG_COUNTER(ivar_set_ic_hit) // All hits
-RB_DEBUG_COUNTER(ivar_set_obj_hit) // Only T_OBJECT hits
-RB_DEBUG_COUNTER(ivar_set_obj_miss) // Only T_OBJECT misses
-RB_DEBUG_COUNTER(ivar_set_ic_miss) // All misses
-RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject) // Miss because non T_OBJECT
-RB_DEBUG_COUNTER(ivar_get_base) // Calls to `rb_ivar_get` (very slow path)
-RB_DEBUG_COUNTER(ivar_set_base) // Calls to `ivar_set` (very slow path)
-RB_DEBUG_COUNTER(ivar_get_ic_miss_set) // Misses on IV reads where the cache was wrong
-RB_DEBUG_COUNTER(ivar_get_cc_miss_set) // Misses on attr_reader where the cache was wrong
-RB_DEBUG_COUNTER(ivar_get_ic_miss_unset) // Misses on IV read where the cache wasn't set
-RB_DEBUG_COUNTER(ivar_get_cc_miss_unset) // Misses on attr_reader where the cache wasn't set
+/* instance variable counts
+ *
+ * * ivar_get_ic_hit/miss: ivar_get inline cache (ic) hit/miss counts (VM insn)
+ * * ivar_get_ic_miss_unset: ... by unset (VM insn)
+ * * ivar_get_ic_miss_noobject: ... by "not T_OBJECT" (VM insn)
+ * * ivar_set_...: same counts with ivar_set (VM insn)
+ * * ivar_get/set_base: call counts of "rb_ivar_get/set()".
+ * because of (1) ic miss.
+ * (2) direct call by C extensions.
+ */
+RB_DEBUG_COUNTER(ivar_get_ic_hit)
+RB_DEBUG_COUNTER(ivar_get_ic_miss)
+RB_DEBUG_COUNTER(ivar_get_ic_miss_noobject)
+RB_DEBUG_COUNTER(ivar_set_ic_hit)
+RB_DEBUG_COUNTER(ivar_set_ic_miss)
+RB_DEBUG_COUNTER(ivar_set_ic_miss_iv_hit)
+RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject)
+RB_DEBUG_COUNTER(ivar_get_base)
+RB_DEBUG_COUNTER(ivar_set_base)
+RB_DEBUG_COUNTER(ivar_get_ic_miss_set)
+RB_DEBUG_COUNTER(ivar_get_cc_miss_set)
+RB_DEBUG_COUNTER(ivar_get_ic_miss_unset)
+RB_DEBUG_COUNTER(ivar_get_cc_miss_unset)
/* local variable counts
*
@@ -185,7 +185,8 @@ RB_DEBUG_COUNTER(gc_major_force)
RB_DEBUG_COUNTER(gc_major_oldmalloc)
RB_DEBUG_COUNTER(gc_enter_start)
-RB_DEBUG_COUNTER(gc_enter_continue)
+RB_DEBUG_COUNTER(gc_enter_mark_continue)
+RB_DEBUG_COUNTER(gc_enter_sweep_continue)
RB_DEBUG_COUNTER(gc_enter_rest)
RB_DEBUG_COUNTER(gc_enter_finalizer)
@@ -214,6 +215,7 @@ RB_DEBUG_COUNTER(gc_isptr_maybe)
* * [attr]
* * _ptr: R?? is not embed.
* * _embed: R?? is embed.
+ * * _transient: R?? uses transient heap.
* * type specific attr.
* * str_shared: str is shared.
* * str_nofree: nofree
@@ -239,6 +241,7 @@ RB_DEBUG_COUNTER(obj_promote)
RB_DEBUG_COUNTER(obj_wb_unprotect)
RB_DEBUG_COUNTER(obj_obj_embed)
+RB_DEBUG_COUNTER(obj_obj_transient)
RB_DEBUG_COUNTER(obj_obj_ptr)
RB_DEBUG_COUNTER(obj_obj_too_complex)
@@ -249,6 +252,7 @@ RB_DEBUG_COUNTER(obj_str_nofree)
RB_DEBUG_COUNTER(obj_str_fstr)
RB_DEBUG_COUNTER(obj_ary_embed)
+RB_DEBUG_COUNTER(obj_ary_transient)
RB_DEBUG_COUNTER(obj_ary_ptr)
RB_DEBUG_COUNTER(obj_ary_extracapa)
/*
@@ -272,9 +276,11 @@ RB_DEBUG_COUNTER(obj_hash_g8)
RB_DEBUG_COUNTER(obj_hash_null)
RB_DEBUG_COUNTER(obj_hash_ar)
RB_DEBUG_COUNTER(obj_hash_st)
+RB_DEBUG_COUNTER(obj_hash_transient)
RB_DEBUG_COUNTER(obj_hash_force_convert)
RB_DEBUG_COUNTER(obj_struct_embed)
+RB_DEBUG_COUNTER(obj_struct_transient)
RB_DEBUG_COUNTER(obj_struct_ptr)
RB_DEBUG_COUNTER(obj_data_empty)
@@ -329,6 +335,11 @@ RB_DEBUG_COUNTER(heap_xmalloc)
RB_DEBUG_COUNTER(heap_xrealloc)
RB_DEBUG_COUNTER(heap_xfree)
+/* transient_heap */
+RB_DEBUG_COUNTER(theap_alloc)
+RB_DEBUG_COUNTER(theap_alloc_fail)
+RB_DEBUG_COUNTER(theap_evacuate)
+
// VM sync
RB_DEBUG_COUNTER(vm_sync_lock)
RB_DEBUG_COUNTER(vm_sync_lock_enter)
diff --git a/defs/gmake.mk b/defs/gmake.mk
index 5489b017b3..54fef6685f 100644
--- a/defs/gmake.mk
+++ b/defs/gmake.mk
@@ -1,19 +1,20 @@
# -*- mode: makefile-gmake; indent-tabs-mode: t -*-
reconfig config.status: export MAKE:=$(MAKE)
-export BASERUBY:=$(BASERUBY)
override gnumake_recursive := $(if $(findstring n,$(firstword $(MFLAGS))),,+)
override mflags := $(filter-out -j%,$(MFLAGS))
MSPECOPT += $(if $(filter -j%,$(MFLAGS)),-j)
nproc = $(subst -j,,$(filter -j%,$(MFLAGS)))
ifeq ($(GITHUB_ACTIONS),true)
-# 93(bright yellow) is copied from .github/workflows/mingw.yml
-override ACTIONS_GROUP = @echo "::group::$(@:yes-%=%)"
-override ACTIONS_ENDGROUP = @echo "::endgroup::"
+override ACTIONS_GROUP = @echo "\#\#[group]$(patsubst yes-%,%,$@)"
+override ACTIONS_ENDGROUP = @echo "\#\#[endgroup]"
endif
ifneq ($(filter darwin%,$(target_os)),)
+# Remove debug option not to generate thousands of .dSYM
+MJIT_DEBUGFLAGS := $(filter-out -g%,$(MJIT_DEBUGFLAGS))
+
INSTRUBY_ENV += SDKROOT=
endif
INSTRUBY_ARGS += --gnumake
@@ -25,7 +26,7 @@ TEST_TARGETS := $(filter $(CHECK_TARGETS),$(MAKECMDGOALS))
TEST_DEPENDS := $(filter-out commit $(TEST_TARGETS),$(MAKECMDGOALS))
TEST_TARGETS := $(patsubst great,exam,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out great $(TEST_TARGETS),$(TEST_DEPENDS))
-TEST_TARGETS := $(patsubst exam,test-bundled-gems test-bundler-parallel check,$(TEST_TARGETS))
+TEST_TARGETS := $(patsubst exam,check,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst check,test-syntax-suggest test-spec test-all test-tool test-short,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-rubyspec,test-spec,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out exam check test-spec $(TEST_TARGETS),$(TEST_DEPENDS))
@@ -36,15 +37,12 @@ TEST_DEPENDS := $(filter-out test-all $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_TARGETS := $(patsubst test,test-short,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out test $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_TARGETS := $(patsubst test-short,btest-ruby test-knownbug test-basic,$(TEST_TARGETS))
-TEST_TARGETS := $(patsubst test-basic,test-basic test-leaked-globals,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-bundled-gems,test-bundled-gems-run,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-bundled-gems-run,test-bundled-gems-run $(PREPARE_BUNDLED_GEMS),$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-bundled-gems-prepare,test-bundled-gems-prepare $(PRECHECK_BUNDLED_GEMS) test-bundled-gems-fetch,$(TEST_TARGETS))
-TEST_TARGETS := $(patsubst test-bundler-parallel,test-bundler-parallel $(PREPARE_BUNDLER),$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-syntax-suggest,test-syntax-suggest $(PREPARE_SYNTAX_SUGGEST),$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out test-short $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_DEPENDS += $(if $(filter great exam love check,$(MAKECMDGOALS)),all exts)
-TEST_TARGETS := $(patsubst yes-%,%,$(filter-out no-%,$(TEST_TARGETS)))
endif
in-srcdir := $(if $(filter-out .,$(srcdir)),$(CHDIR) $(srcdir) &&)
@@ -57,13 +55,6 @@ ifeq ($(if $(filter all main exts enc trans libencs libenc libtrans \
-include $(SHOWFLAGS)
endif
-ifeq ($(HAVE_BASERUBY):$(HAVE_GIT),yes:yes)
-override modified := $(shell $(BASERUBY) -C $(srcdir) tool/file2lastrev.rb --modified='%Y %m %d')
-override RUBY_RELEASE_YEAR := $(word 1,$(modified))
-override RUBY_RELEASE_MONTH := $(word 2,$(modified))
-override RUBY_RELEASE_DAY := $(word 3,$(modified))
-endif
-
ifneq ($(filter universal-%,$(arch)),)
define archcmd
%.$(1).S: %.c
@@ -79,7 +70,7 @@ define archcmd
%.i: %.$(1).i
endef
-$(foreach arch,$(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG))),\
+$(foreach arch,$(arch_flags),\
$(eval $(call archcmd,$(patsubst -arch=%,%,$(value arch)),$(patsubst -arch=%,-arch %,$(value arch)))))
endif
@@ -91,31 +82,16 @@ $(addprefix yes-,$(TEST_TARGETS)): $(TEST_DEPENDS)
endif
ORDERED_TEST_TARGETS := $(filter $(TEST_TARGETS), \
- btest-ruby test-knownbug test-leaked-globals test-basic \
+ btest-ruby test-knownbug test-basic \
test-testframework test-tool test-ruby test-all \
test-spec test-syntax-suggest-prepare test-syntax-suggest \
test-bundler-prepare test-bundler test-bundler-parallel \
test-bundled-gems-precheck test-bundled-gems-fetch \
test-bundled-gems-prepare test-bundled-gems-run \
)
-
-# grep ^yes-test-.*-precheck: template/Makefile.in defs/gmake.mk common.mk
-test_prechecks := $(filter $(ORDERED_TEST_TARGETS),\
- test-leaked-globals \
- test-all \
- test-spec \
- test-syntax-suggest \
- test-bundler \
- test-bundler-parallel \
- test-bundled-gems\
- )
-prev_test := $(subst test-bundler-parallel,test-bundler,$(test_prechecks))
-prev_test := $(addsuffix -precheck,$(prev_test))
-first_test_prechecks := $(prev_test)
-
+prev_test := $(if $(filter test-spec,$(ORDERED_TEST_TARGETS)),test-spec-precheck)
$(foreach test,$(ORDERED_TEST_TARGETS), \
- $(eval yes-$(value test): $(addprefix yes-,$(value prev_test))); \
- $(eval no-$(value test): $(addprefix no-,$(value prev_test))); \
+ $(eval yes-$(value test) no-$(value test): $(value prev_test)); \
$(eval prev_test := $(value test)))
endif
@@ -193,22 +169,15 @@ $(SCRIPTBINDIR):
$(Q) mkdir $@
.PHONY: commit
-COMMIT_PREPARE := $(filter-out commit do-commit,$(MAKECMDGOALS)) up
-
-commit: pre-commit $(DOT_WAIT) do-commit $(DOT_WAIT) post_commit
-pre-commit: $(COMMIT_PREPARE)
-do-commit: $(if $(DOT_WAIT),,pre-commit)
+commit: $(if $(filter commit,$(MAKECMDGOALS)),$(filter-out commit,$(MAKECMDGOALS))) up
@$(BASERUBY) -C "$(srcdir)" -I./tool/lib -rvcs -e 'VCS.detect(".").commit'
-post-commit: $(if $(DOT_WAIT),,do-commit)
+$(Q) \
{ \
$(in-srcdir) \
exec sed -f tool/prereq.status defs/gmake.mk template/Makefile.in common.mk; \
} | \
- $(MAKE) $(mflags) Q=$(Q) ECHO=$(ECHO) \
- top_srcdir="$(top_srcdir)" srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \
- BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" BOOTSTRAPRUBY_OPT="$(BOOTSTRAPRUBY_OPT)" \
- MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" HAVE_BASERUBY="$(HAVE_BASERUBY)" \
+ $(MAKE) $(mflags) Q=$(Q) ECHO=$(ECHO) srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \
+ BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" \
VCSUP="" ENC_MK=.top-enc.mk REVISION_FORCE=PHONY CONFIGURE="$(CONFIGURE)" -f - \
update-src srcs all-incs
@@ -299,7 +268,6 @@ HELP_EXTRA_TASKS = \
" checkout-github: checkout GitHub Pull Request [PR=1234]" \
" pull-github: rebase GitHub Pull Request to new worktree [PR=1234]" \
" update-github: merge master branch and push it to Pull Request [PR=1234]" \
- " tags: generate TAGS file" \
""
# 1. squeeze spaces
@@ -324,13 +292,12 @@ foreach-bundled-gems-rev = \
foreach-bundled-gems-rev-0 = \
$(call $(1),$(word 1,$(2)),$(word 2,$(2)),$(word 3,$(2)),$(word 4,$(2)))
bundled-gem-gemfile = $(srcdir)/gems/$(1)-$(2).gem
-bundled-gem-gemspec = $(srcdir)/gems/src/$(1)/$(1).gemspec
+bundled-gem-srcdir = $(srcdir)/gems/src/$(1)
bundled-gem-extracted = $(srcdir)/.bundle/gems/$(1)-$(2)
-bundled-gem-revision = $(srcdir)/.bundle/.timestamp/$(1).revision
update-gems: | $(patsubst %,$(srcdir)/gems/%.gem,$(bundled-gems))
update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-gemfile)
-update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-gemspec)
+update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-srcdir)
test-bundler-precheck: | $(srcdir)/.bundle/cache
@@ -358,44 +325,27 @@ $(srcdir)/.bundle/gems/%: $(srcdir)/gems/%.gem | .bundle/gems
-Itool/lib -rbundled_gem \
-e 'BundledGem.unpack("gems/$(@F).gem", ".bundle")'
-$(srcdir)/.bundle/.timestamp:
- $(MAKEDIRS) $@
-
-define build-gem
-$(srcdir)/gems/src/$(1)/.git: | $(srcdir)/gems/src
+define copy-gem
+$(srcdir)/gems/src/$(1): | $(srcdir)/gems/src
$(ECHO) Cloning $(4)
- $(Q) $(GIT) clone $(4) $$(@D)
+ $(Q) $(GIT) clone $(4) $$(@)
-$(bundled-gem-revision): \
- $(if $(if $(wildcard $$(@)),$(filter $(3),$(shell cat $$(@)))),,PHONY) \
- | $(srcdir)/.bundle/.timestamp $(srcdir)/gems/src/$(1)/.git
- $(ECHO) Update $(1) to $(3)
+$(srcdir)/.bundle/gems/$(1)-$(2): | $(srcdir)/gems/src/$(1) .bundle/gems
+ $(ECHO) Copying $(1)@$(3) to $$(@F)
$(Q) $(CHDIR) "$(srcdir)/gems/src/$(1)" && \
- if [ `$(GIT) rev-parse HEAD` != $(3) ]; then \
- $(GIT) fetch origin $(3) && \
- $(GIT) checkout --detach $(3) && \
- :; \
- fi
- echo $(3) | $(IFCHANGE) $$(@) -
-
-# The repository of minitest does not include minitest.gemspec because it uses hoe.
-# This creates a dummy gemspec.
-$(bundled-gem-gemspec): $(bundled-gem-revision) \
- | $(srcdir)/gems/src/$(1)/.git
- $(Q) $(BASERUBY) -I$(tooldir)/lib -rbundled_gem -e 'BundledGem.dummy_gemspec(*ARGV)' $$(@)
-
-$(bundled-gem-gemfile): $(bundled-gem-gemspec) $(bundled-gem-revision)
- $(ECHO) Building $(1)@$(3) to $$(@)
+ $(GIT) fetch origin $(3) && \
+ $(GIT) checkout --detach $(3) && \
+ :
$(Q) $(BASERUBY) -C "$(srcdir)" \
-Itool/lib -rbundled_gem \
- -e 'BundledGem.build("gems/src/$(1)/$(1).gemspec", "$(2)", "gems", validation: false)'
+ -e 'BundledGem.copy("gems/src/$(1)/$(1).gemspec", ".bundle")'
endef
-define build-gem-0
-$(eval $(call build-gem,$(1),$(2),$(3),$(4)))
+define copy-gem-0
+$(eval $(call copy-gem,$(1),$(2),$(3),$(4)))
endef
-$(call foreach-bundled-gems-rev,build-gem-0)
+$(call foreach-bundled-gems-rev,copy-gem-0)
$(srcdir)/gems/src:
$(MAKEDIRS) $@
@@ -403,36 +353,49 @@ $(srcdir)/gems/src:
$(srcdir)/.bundle/gems:
$(MAKEDIRS) $@
-ifneq ($(DOT_WAIT),)
-up:: $(DOT_WAIT) after-update
-endif
-
ifneq ($(filter update-bundled_gems refresh-gems,$(MAKECMDGOALS)),)
update-gems: update-bundled_gems
endif
+ifeq ($(filter 0 1,$(words $(arch_flags))),)
+$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \
+ $(eval $$(MJIT_HEADER:.h=)-$(value x).h \
+ $$(MJIT_MIN_HEADER:.h=)-$(value x).h \
+ $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time \
+ : ARCH_FLAG := -arch $(value x)))
+
+$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \
+ $(eval $$(MJIT_HEADER:.h=)-$(value x).h: \
+ $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time))
+
+mjit_min_headers := $(patsubst -arch=%,$(MJIT_MIN_HEADER:.h=-%.h),$(arch_flags))
+$(MJIT_MIN_HEADER): $(mjit_min_headers) $(PREP)
+ @ set -e; set $(patsubst -arch=%,%,$(arch_flags)); \
+ cd $(@D); h=$(@F:.h=); \
+ exec > $(@F).new; \
+ echo '#if 0'; \
+ for arch; do\
+ echo "#elif defined __$${arch}__"; \
+ echo "# include \"$$h-$$arch.h\""; \
+ done; \
+ echo "#else"; echo "# error unsupported platform"; echo "#endif"
+ $(IFCHANGE) $@ $@.new
+ $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR)
+ $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F)
+
+endif
+
.SECONDARY: update-unicode-files
.SECONDARY: update-unicode-auxiliary-files
.SECONDARY: update-unicode-ucd-emoji-files
.SECONDARY: update-unicode-emoji-files
-ifneq ($(DOT_WAIT),)
-.NOTPARALLEL: update-unicode
-.NOTPARALLEL: update-unicode-files
-.NOTPARALLEL: update-unicode-auxiliary-files
-.NOTPARALLEL: update-unicode-ucd-emoji-files
-.NOTPARALLEL: update-unicode-emoji-files
-.NOTPARALLEL: $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES)
-.NOTPARALLEL: $(UNICODE_AUXILIARY_FILES)
-.NOTPARALLEL: $(UNICODE_UCD_EMOJI_FILES) $(UNICODE_EMOJI_FILES)
-endif
-
ifeq ($(HAVE_GIT),yes)
REVISION_LATEST := $(shell $(CHDIR) $(srcdir) && $(GIT) log -1 --format=%H 2>/dev/null)
else
REVISION_LATEST := update
endif
-REVISION_IN_HEADER := $(shell sed '/^\#define RUBY_FULL_REVISION "\(.*\)"/!d;s//\1/;q' $(wildcard $(srcdir)/revision.h revision.h) /dev/null 2>/dev/null)
+REVISION_IN_HEADER := $(shell sed -n 's/^\#define RUBY_FULL_REVISION "\(.*\)"/\1/p' $(wildcard $(srcdir)/revision.h revision.h) /dev/null 2>/dev/null)
ifeq ($(REVISION_IN_HEADER),)
REVISION_IN_HEADER := none
endif
@@ -503,7 +466,7 @@ update-deps:
$(RUBYSPEC_CAPIEXT)/%.$(DLEXT): $(srcdir)/$(RUBYSPEC_CAPIEXT)/%.c $(srcdir)/$(RUBYSPEC_CAPIEXT)/rubyspec.h $(RUBY_H_INCLUDES) $(LIBRUBY)
$(ECHO) building $@
$(Q) $(MAKEDIRS) $(@D)
- $(Q) $(DLDSHARED) -L. $(XDLDFLAGS) $(XLDFLAGS) $(LDFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBYARG)
+ $(Q) $(DLDSHARED) $(XDLDFLAGS) $(XLDFLAGS) $(LDFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBYARG)
$(Q) $(RMALL) $@.*
rubyspec-capiext: $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c)))
@@ -517,29 +480,3 @@ spec/%/ spec/%_spec.rb: programs exts PHONY
+$(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec-run -B $(srcdir)/spec/default.mspec $(SPECOPTS) $(patsubst %,$(srcdir)/%,$@)
ruby.pc: $(filter-out ruby.pc,$(ruby_pc))
-
-matz: up
- $(eval MINOR := $(shell expr $(MINOR) + 1))
- $(eval message := Development of $(MAJOR).$(MINOR).0 started.)
- $(eval files := include/ruby/version.h include/ruby/internal/abi.h)
- sed -i~ \
- -e "s/^\(#define RUBY_API_VERSION_MINOR\) .*/\1 $(MINOR)/" \
- -e "s/^\(#define RUBY_ABI_VERSION\) .*/\1 0/" \
- $(files:%=$(srcdir)/%)
- $(GIT) -C $(srcdir) commit -m "$(message)" $(files)
-
-tags:
- $(MAKE) GIT="$(GIT)" -C "$(srcdir)" -f defs/tags.mk
-
-
-# ripper_srcs makes all sources at once. invoking this target multiple
-# times in parallel means all sources will be built for the number of
-# sources times respectively.
-ifneq ($(DOT_WAIT),)
-.NOTPARALLEL: ripper_srcs
-else
-ripper_src =
-$(foreach r,$(RIPPER_SRCS),$(eval $(value r): | $(value ripper_src))\
- $(eval ripper_src := $(value r)))
-ripper_srcs: $(ripper_src)
-endif
diff --git a/defs/id.def b/defs/id.def
index 2ddde7be70..ebf00506ea 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -2,7 +2,6 @@
firstline, predefined = __LINE__+1, %[\
max
min
- hash
freeze
nil?
inspect
@@ -26,6 +25,7 @@ firstline, predefined = __LINE__+1, %[\
lambda
send
__send__
+ __attached__
__recursive_key__
initialize
initialize_copy
diff --git a/defs/tags.mk b/defs/tags.mk
deleted file mode 100644
index d29260c294..0000000000
--- a/defs/tags.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- mode: makefile-gmake; indent-tabs-mode: t -*-
-
-SRCS := $(shell $(GIT) ls-files \
- *.[chy] *.def *.inc *.rb \
- ccan/ coroutine/ include/ internal/ missing/ \
- 'enc/**/*.[ch]' 'win32/**/*.[ch]' \
- )
-
-TAGS: $(SRCS)
- @echo updating $@
- @tmp=$$(mktemp); \
- trap 'rm -f "$$tmp"' 0; \
- { \
- $(GIT) grep -h --no-line-number -o '^ *# *define *RBIMPL_ATTR_[A-Z_]*(*' -- include | \
- sed 's/^ *# *define *//;/_H$$/d;y/(/+/' | sort -u && \
- echo 'NORETURN+'; \
- } > "$$tmp" && \
- ctags -e -I@"$$tmp" -h .def.inc --langmap=c:+.y.def.inc $(^)
diff --git a/defs/universal.mk b/defs/universal.mk
new file mode 100644
index 0000000000..c34a31b356
--- /dev/null
+++ b/defs/universal.mk
@@ -0,0 +1,5 @@
+arch_flags := $(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG)))
+ifeq ($(filter 0 1,$(words $(arch_flags))),)
+override MJIT_HEADER_SUFFIX = -%
+override MJIT_HEADER_ARCH = -$(word 2,$(ARCH_FLAG))
+endif
diff --git a/dir.c b/dir.c
index 96c1a455b3..3f73f83fc5 100644
--- a/dir.c
+++ b/dir.c
@@ -466,26 +466,31 @@ struct dir_data {
};
static void
+dir_mark(void *ptr)
+{
+ struct dir_data *dir = ptr;
+ rb_gc_mark(dir->path);
+}
+
+static void
dir_free(void *ptr)
{
struct dir_data *dir = ptr;
if (dir->dir) closedir(dir->dir);
+ xfree(dir);
}
-RUBY_REFERENCES(dir_refs) = {
- RUBY_REF_EDGE(struct dir_data, path),
- RUBY_REF_END
-};
+static size_t
+dir_memsize(const void *ptr)
+{
+ return sizeof(struct dir_data);
+}
static const rb_data_type_t dir_data_type = {
"dir",
- {
- RUBY_REFS_LIST_PTR(dir_refs),
- dir_free,
- NULL, // Nothing allocated externally, so don't need a memsize function
- },
- 0, NULL, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE
+ {dir_mark, dir_free, dir_memsize,},
+ 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE dir_close(VALUE);
@@ -586,45 +591,6 @@ dir_s_close(rb_execution_context_t *ec, VALUE klass, VALUE dir)
return dir_close(dir);
}
-# if defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD)
-/*
- * call-seq:
- * Dir.for_fd(fd) -> dir
- *
- * Returns a new \Dir object representing the directory specified by the given
- * integer directory file descriptor +fd+:
- *
- * d0 = Dir.new('..')
- * d1 = Dir.for_fd(d0.fileno)
- *
- * Note that the returned +d1+ does not have an associated path:
- *
- * d0.path # => '..'
- * d1.path # => nil
- *
- * This method uses the
- * {fdopendir()}[https://www.man7.org/linux/man-pages/man3/fdopendir.3p.html]
- * function defined by POSIX 2008;
- * the method is not implemented on non-POSIX platforms (raises NotImplementedError).
- */
-static VALUE
-dir_s_for_fd(VALUE klass, VALUE fd)
-{
- struct dir_data *dp;
- VALUE dir = TypedData_Make_Struct(klass, struct dir_data, &dir_data_type, dp);
-
- if (!(dp->dir = fdopendir(NUM2INT(fd)))) {
- rb_sys_fail("fdopendir");
- UNREACHABLE_RETURN(Qnil);
- }
-
- RB_OBJ_WRITE(dir, &dp->path, Qnil);
- return dir;
-}
-#else
-#define dir_s_for_fd rb_f_notimplement
-#endif
-
NORETURN(static void dir_closed(void));
static void
@@ -652,13 +618,10 @@ dir_check(VALUE dir)
/*
- * call-seq:
- * inspect -> string
- *
- * Returns a string description of +self+:
- *
- * Dir.new('example').inspect # => "#<Dir:example>"
+ * call-seq:
+ * dir.inspect -> string
*
+ * Return a string describing this Dir object.
*/
static VALUE
dir_inspect(VALUE dir)
@@ -692,18 +655,18 @@ dir_inspect(VALUE dir)
#ifdef HAVE_DIRFD
/*
- * call-seq:
- * fileno -> integer
+ * call-seq:
+ * dir.fileno -> integer
+ *
+ * Returns the file descriptor used in <em>dir</em>.
*
- * Returns the file descriptor used in <em>dir</em>.
+ * d = Dir.new("..")
+ * d.fileno #=> 8
*
- * d = Dir.new('..')
- * d.fileno # => 8
+ * This method uses dirfd() function defined by POSIX 2008.
+ * NotImplementedError is raised on other platforms, such as Windows,
+ * which doesn't provide the function.
*
- * This method uses the
- * {dirfd()}[https://www.man7.org/linux/man-pages/man3/dirfd.3.html]
- * function defined by POSIX 2008;
- * the method is not implemented on non-POSIX platforms (raises NotImplementedError).
*/
static VALUE
dir_fileno(VALUE dir)
@@ -722,14 +685,14 @@ dir_fileno(VALUE dir)
#endif
/*
- * call-seq:
- * path -> string or nil
+ * call-seq:
+ * dir.path -> string or nil
+ * dir.to_path -> string or nil
*
- * Returns the +dirpath+ string that was used to create +self+
- * (or +nil+ if created by method Dir.for_fd):
- *
- * Dir.new('example').path # => "example"
+ * Returns the path parameter passed to <em>dir</em>'s constructor.
*
+ * d = Dir.new("..")
+ * d.path #=> ".."
*/
static VALUE
dir_path(VALUE dir)
@@ -783,18 +746,16 @@ to_be_skipped(const struct dirent *dp)
}
/*
- * call-seq:
- * read -> string or nil
- *
- * Reads and returns the next entry name from +self+;
- * returns +nil+ if at end-of-stream;
- * see {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]:
+ * call-seq:
+ * dir.read -> string or nil
*
- * dir = Dir.new('example')
- * dir.read # => "."
- * dir.read # => ".."
- * dir.read # => "config.h"
+ * Reads the next entry from <em>dir</em> and returns it as a string.
+ * Returns <code>nil</code> at the end of the stream.
*
+ * d = Dir.new("testdir")
+ * d.read #=> "."
+ * d.read #=> ".."
+ * d.read #=> "config.h"
*/
static VALUE
dir_read(VALUE dir)
@@ -803,7 +764,7 @@ dir_read(VALUE dir)
struct dirent *dp;
GetDIR(dir, dirp);
- rb_errno_set(0);
+ errno = 0;
if ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
}
@@ -823,23 +784,24 @@ dir_yield(VALUE arg, VALUE path)
}
/*
- * call-seq:
- * each {|entry_name| ... } -> self
+ * call-seq:
+ * dir.each { |filename| block } -> dir
+ * dir.each -> an_enumerator
*
- * Calls the block with each entry name in +self+:
+ * Calls the block once for each entry in this directory, passing the
+ * filename of each entry as a parameter to the block.
*
- * Dir.new('example').each {|entry_name| p entry_name }
+ * If no block is given, an enumerator is returned instead.
*
- * Output:
-
- * "."
- * ".."
- * "config.h"
- * "lib"
- * "main.rb"
+ * d = Dir.new("testdir")
+ * d.each {|x| puts "Got #{x}" }
*
- * With no block given, returns an Enumerator.
+ * <em>produces:</em>
*
+ * Got .
+ * Got ..
+ * Got config.h
+ * Got main.rb
*/
static VALUE
dir_each(VALUE dir)
@@ -882,17 +844,16 @@ dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE), VALUE arg, int children_o
#ifdef HAVE_TELLDIR
/*
- * call-seq:
- * tell -> integer
+ * call-seq:
+ * dir.pos -> integer
+ * dir.tell -> integer
*
- * Returns the current position of +self+;
- * see {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]:
- *
- * dir = Dir.new('example')
- * dir.tell # => 0
- * dir.read # => "."
- * dir.tell # => 1
+ * Returns the current position in <em>dir</em>. See also Dir#seek.
*
+ * d = Dir.new("testdir")
+ * d.tell #=> 0
+ * d.read #=> "."
+ * d.tell #=> 12
*/
static VALUE
dir_tell(VALUE dir)
@@ -910,24 +871,18 @@ dir_tell(VALUE dir)
#ifdef HAVE_SEEKDIR
/*
- * call-seq:
- * seek(position) -> self
- *
- * Sets the position in +self+ and returns +self+.
- * The value of +position+ should have been returned from an earlier call to #tell;
- * if not, the return values from subsequent calls to #read are unspecified.
- *
- * See {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like].
- *
- * Examples:
- *
- * dir = Dir.new('example')
- * dir.pos # => 0
- * dir.seek(3) # => #<Dir:example>
- * dir.pos # => 3
- * dir.seek(30) # => #<Dir:example>
- * dir.pos # => 5
- *
+ * call-seq:
+ * dir.seek( integer ) -> dir
+ *
+ * Seeks to a particular location in <em>dir</em>. <i>integer</i>
+ * must be a value returned by Dir#tell.
+ *
+ * d = Dir.new("testdir") #=> #<Dir:0x401b3c40>
+ * d.read #=> "."
+ * i = d.tell #=> 12
+ * d.read #=> ".."
+ * d.seek(i) #=> #<Dir:0x401b3c40>
+ * d.read #=> ".."
*/
static VALUE
dir_seek(VALUE dir, VALUE pos)
@@ -945,24 +900,17 @@ dir_seek(VALUE dir, VALUE pos)
#ifdef HAVE_SEEKDIR
/*
- * call-seq:
- * pos = position -> integer
- *
- * Sets the position in +self+ and returns +position+.
- * The value of +position+ should have been returned from an earlier call to #tell;
- * if not, the return values from subsequent calls to #read are unspecified.
+ * call-seq:
+ * dir.pos = integer -> integer
*
- * See {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like].
- *
- * Examples:
- *
- * dir = Dir.new('example')
- * dir.pos # => 0
- * dir.pos = 3 # => 3
- * dir.pos # => 3
- * dir.pos = 30 # => 30
- * dir.pos # => 5
+ * Synonym for Dir#seek, but returns the position parameter.
*
+ * d = Dir.new("testdir") #=> #<Dir:0x401b3c40>
+ * d.read #=> "."
+ * i = d.pos #=> 12
+ * d.read #=> ".."
+ * d.pos = i #=> 12
+ * d.read #=> ".."
*/
static VALUE
dir_set_pos(VALUE dir, VALUE pos)
@@ -975,19 +923,15 @@ dir_set_pos(VALUE dir, VALUE pos)
#endif
/*
- * call-seq:
- * rewind -> self
- *
- * Sets the position in +self+ to zero;
- * see {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]:
+ * call-seq:
+ * dir.rewind -> dir
*
- * dir = Dir.new('example')
- * dir.read # => "."
- * dir.read # => ".."
- * dir.pos # => 2
- * dir.rewind # => #<Dir:example>
- * dir.pos # => 0
+ * Repositions <em>dir</em> to the first entry.
*
+ * d = Dir.new("testdir")
+ * d.read #=> "."
+ * d.rewind #=> #<Dir:0x401b3fb0>
+ * d.read #=> "."
*/
static VALUE
dir_rewind(VALUE dir)
@@ -1000,18 +944,14 @@ dir_rewind(VALUE dir)
}
/*
- * call-seq:
- * close -> nil
- *
- * Closes the stream in +self+, if it is open, and returns +nil+;
- * ignored if +self+ is already closed:
+ * call-seq:
+ * dir.close -> nil
*
- * dir = Dir.new('example')
- * dir.read # => "."
- * dir.close # => nil
- * dir.close # => nil
- * dir.read # Raises IOError.
+ * Closes the directory stream.
+ * Calling this method on closed Dir object is ignored since Ruby 2.3.
*
+ * d = Dir.new("testdir")
+ * d.close #=> nil
*/
static VALUE
dir_close(VALUE dir)
@@ -1035,7 +975,7 @@ nogvl_chdir(void *ptr)
}
static void
-dir_chdir0(VALUE path)
+dir_chdir(VALUE path)
{
if (chdir(RSTRING_PTR(path)) < 0)
rb_sys_fail_path(path);
@@ -1047,19 +987,18 @@ static VALUE chdir_thread = Qnil;
struct chdir_data {
VALUE old_path, new_path;
int done;
- bool yield_path;
};
static VALUE
chdir_yield(VALUE v)
{
struct chdir_data *args = (void *)v;
- dir_chdir0(args->new_path);
+ dir_chdir(args->new_path);
args->done = TRUE;
chdir_blocking++;
if (NIL_P(chdir_thread))
chdir_thread = rb_thread_current();
- return args->yield_path ? rb_yield(args->new_path) : rb_yield_values2(0, NULL);
+ return rb_yield(args->new_path);
}
static VALUE
@@ -1070,103 +1009,50 @@ chdir_restore(VALUE v)
chdir_blocking--;
if (chdir_blocking == 0)
chdir_thread = Qnil;
- dir_chdir0(args->old_path);
+ dir_chdir(args->old_path);
}
return Qnil;
}
-static VALUE
-chdir_path(VALUE path, bool yield_path)
-{
- if (chdir_blocking > 0) {
- if (rb_thread_current() != chdir_thread)
- rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block");
- if (!rb_block_given_p())
- rb_warn("conflicting chdir during another chdir block");
- }
-
- if (rb_block_given_p()) {
- struct chdir_data args;
-
- args.old_path = rb_str_encode_ospath(rb_dir_getwd());
- args.new_path = path;
- args.done = FALSE;
- args.yield_path = yield_path;
- return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
- }
- else {
- char *p = RSTRING_PTR(path);
- int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p,
- RUBY_UBF_IO, 0);
- if (r < 0)
- rb_sys_fail_path(path);
- }
-
- return INT2FIX(0);
-}
-
/*
- * call-seq:
- * Dir.chdir(new_dirpath) -> 0
- * Dir.chdir -> 0
- * Dir.chdir(new_dirpath) {|new_dirpath| ... } -> object
- * Dir.chdir {|cur_dirpath| ... } -> object
- *
- * Changes the current working directory.
- *
- * With argument +new_dirpath+ and no block,
- * changes to the given +dirpath+:
- *
- * Dir.pwd # => "/example"
- * Dir.chdir('..') # => 0
- * Dir.pwd # => "/"
- *
- * With no argument and no block:
- *
- * - Changes to the value of environment variable +HOME+ if defined.
- * - Otherwise changes to the value of environment variable +LOGDIR+ if defined.
- * - Otherwise makes no change.
- *
- * With argument +new_dirpath+ and a block, temporarily changes the working directory:
- *
- * - Calls the block with the argument.
- * - Changes to the given directory.
- * - Executes the block (yielding the new path).
- * - Restores the previous working directory.
- * - Returns the block's return value.
- *
- * Example:
- *
- * Dir.chdir('/var/spool/mail')
- * Dir.pwd # => "/var/spool/mail"
- * Dir.chdir('/tmp') do
- * Dir.pwd # => "/tmp"
- * end
- * Dir.pwd # => "/var/spool/mail"
- *
- * With no argument and a block,
- * calls the block with the current working directory (string)
- * and returns the block's return value.
- *
- * Calls to \Dir.chdir with blocks may be nested:
- *
- * Dir.chdir('/var/spool/mail')
- * Dir.pwd # => "/var/spool/mail"
- * Dir.chdir('/tmp') do
- * Dir.pwd # => "/tmp"
- * Dir.chdir('/usr') do
- * Dir.pwd # => "/usr"
+ * call-seq:
+ * Dir.chdir( [ string] ) -> 0
+ * Dir.chdir( [ string] ) {| path | block } -> anObject
+ *
+ * Changes the current working directory of the process to the given
+ * string. When called without an argument, changes the directory to
+ * the value of the environment variable <code>HOME</code>, or
+ * <code>LOGDIR</code>. SystemCallError (probably Errno::ENOENT) if
+ * the target directory does not exist.
+ *
+ * If a block is given, it is passed the name of the new current
+ * directory, and the block is executed with that as the current
+ * directory. The original working directory is restored when the block
+ * exits. The return value of <code>chdir</code> is the value of the
+ * block. <code>chdir</code> blocks can be nested, but in a
+ * multi-threaded program an error will be raised if a thread attempts
+ * to open a <code>chdir</code> block while another thread has one
+ * open or a call to <code>chdir</code> without a block occurs inside
+ * a block passed to <code>chdir</code> (even in the same thread).
+ *
+ * Dir.chdir("/var/spool/mail")
+ * puts Dir.pwd
+ * Dir.chdir("/tmp") do
+ * puts Dir.pwd
+ * Dir.chdir("/usr") do
+ * puts Dir.pwd
+ * end
+ * puts Dir.pwd
* end
- * Dir.pwd # => "/tmp"
- * end
- * Dir.pwd # => "/var/spool/mail"
+ * puts Dir.pwd
*
- * In a multi-threaded program an error is raised if a thread attempts
- * to open a +chdir+ block while another thread has one open,
- * or a call to +chdir+ without a block occurs inside
- * a block passed to +chdir+ (even in the same thread).
+ * <em>produces:</em>
*
- * Raises an exception if the target directory does not exist.
+ * /var/spool/mail
+ * /tmp
+ * /usr
+ * /tmp
+ * /var/spool/mail
*/
static VALUE
dir_s_chdir(int argc, VALUE *argv, VALUE obj)
@@ -1185,114 +1071,6 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj)
path = rb_str_new2(dist);
}
- return chdir_path(path, true);
-}
-
-#if defined(HAVE_FCHDIR) && defined(HAVE_DIRFD) && HAVE_FCHDIR && HAVE_DIRFD
-static void *
-nogvl_fchdir(void *ptr)
-{
- const int *fd = ptr;
-
- return (void *)(VALUE)fchdir(*fd);
-}
-
-static void
-dir_fchdir(int fd)
-{
- if (fchdir(fd) < 0)
- rb_sys_fail("fchdir");
-}
-
-struct fchdir_data {
- VALUE old_dir;
- int fd;
- int done;
-};
-
-static VALUE
-fchdir_yield(VALUE v)
-{
- struct fchdir_data *args = (void *)v;
- dir_fchdir(args->fd);
- args->done = TRUE;
- chdir_blocking++;
- if (NIL_P(chdir_thread))
- chdir_thread = rb_thread_current();
- return rb_yield_values(0);
-}
-
-static VALUE
-fchdir_restore(VALUE v)
-{
- struct fchdir_data *args = (void *)v;
- if (args->done) {
- chdir_blocking--;
- if (chdir_blocking == 0)
- chdir_thread = Qnil;
- dir_fchdir(RB_NUM2INT(dir_fileno(args->old_dir)));
- }
- dir_close(args->old_dir);
- return Qnil;
-}
-
-/*
- * call-seq:
- * Dir.fchdir(fd) -> 0
- * Dir.fchdir(fd) { ... } -> object
- *
- * Changes the current working directory to the directory
- * specified by the integer file descriptor +fd+.
- *
- * When passing a file descriptor over a UNIX socket or to a child process,
- * using +fchdir+ instead of +chdir+ avoids the
- * {time-of-check to time-of-use vulnerability}[https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use]
- *
- * With no block, changes to the directory given by +fd+:
- *
- * Dir.chdir('/var/spool/mail')
- * Dir.pwd # => "/var/spool/mail"
- * dir = Dir.new('/usr')
- * fd = dir.fileno
- * Dir.fchdir(fd)
- * Dir.pwd # => "/usr"
- *
- * With a block, temporarily changes the working directory:
- *
- * - Calls the block with the argument.
- * - Changes to the given directory.
- * - Executes the block (yields no args).
- * - Restores the previous working directory.
- * - Returns the block's return value.
- *
- * Example:
- *
- * Dir.chdir('/var/spool/mail')
- * Dir.pwd # => "/var/spool/mail"
- * dir = Dir.new('/tmp')
- * fd = dir.fileno
- * Dir.fchdir(fd) do
- * Dir.pwd # => "/tmp"
- * end
- * Dir.pwd # => "/var/spool/mail"
- *
- * This method uses the
- * {fchdir()}[https://www.man7.org/linux/man-pages/man3/fchdir.3p.html]
- * function defined by POSIX 2008;
- * the method is not implemented on non-POSIX platforms (raises NotImplementedError).
- *
- * Raises an exception if the file descriptor is not valid.
- *
- * In a multi-threaded program an error is raised if a thread attempts
- * to open a +chdir+ block while another thread has one open,
- * or a call to +chdir+ without a block occurs inside
- * a block passed to +chdir+ (even in the same thread).
- */
-static VALUE
-dir_s_fchdir(VALUE klass, VALUE fd_value)
-{
- int fd = RB_NUM2INT(fd_value);
-
if (chdir_blocking > 0) {
if (rb_thread_current() != chdir_thread)
rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block");
@@ -1301,58 +1079,23 @@ dir_s_fchdir(VALUE klass, VALUE fd_value)
}
if (rb_block_given_p()) {
- struct fchdir_data args;
- args.old_dir = dir_s_alloc(klass);
- dir_initialize(NULL, args.old_dir, rb_fstring_cstr("."), Qnil);
- args.fd = fd;
+ struct chdir_data args;
+
+ args.old_path = rb_str_encode_ospath(rb_dir_getwd());
+ args.new_path = path;
args.done = FALSE;
- return rb_ensure(fchdir_yield, (VALUE)&args, fchdir_restore, (VALUE)&args);
+ return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
}
else {
- int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_fchdir, &fd,
- RUBY_UBF_IO, 0);
+ char *p = RSTRING_PTR(path);
+ int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p,
+ RUBY_UBF_IO, 0);
if (r < 0)
- rb_sys_fail("fchdir");
+ rb_sys_fail_path(path);
}
return INT2FIX(0);
}
-#else
-#define dir_s_fchdir rb_f_notimplement
-#endif
-
-/*
- * call-seq:
- * chdir -> 0
- * chdir { ... } -> object
- *
- * Changes the current working directory to +self+:
- *
- * Dir.pwd # => "/"
- * dir = Dir.new('example')
- * dir.chdir
- * Dir.pwd # => "/example"
- *
- * With a block, temporarily changes the working directory:
- *
- * - Calls the block.
- * - Changes to the given directory.
- * - Executes the block (yields no args).
- * - Restores the previous working directory.
- * - Returns the block's return value.
- *
- * Uses Dir.fchdir if available, and Dir.chdir if not, see those
- * methods for caveats.
- */
-static VALUE
-dir_chdir(VALUE dir)
-{
-#if defined(HAVE_FCHDIR) && defined(HAVE_DIRFD) && HAVE_FCHDIR && HAVE_DIRFD
- return dir_s_fchdir(rb_cDir, dir_fileno(dir));
-#else
- return chdir_path(dir_get(dir)->path, false);
-#endif
-}
#ifndef _WIN32
VALUE
@@ -1400,14 +1143,16 @@ rb_dir_getwd(void)
}
/*
- * call-seq:
- * Dir.pwd -> string
- *
- * Returns the path to the current working directory:
+ * call-seq:
+ * Dir.getwd -> string
+ * Dir.pwd -> string
*
- * Dir.chdir("/tmp") # => 0
- * Dir.pwd # => "/tmp"
+ * Returns the path to the current working directory of this process as
+ * a string.
*
+ * Dir.chdir("/tmp") #=> 0
+ * Dir.getwd #=> "/tmp"
+ * Dir.pwd #=> "/tmp"
*/
static VALUE
dir_s_getwd(VALUE dir)
@@ -1437,16 +1182,13 @@ check_dirname(VALUE dir)
#if defined(HAVE_CHROOT)
/*
- * call-seq:
- * Dir.chroot(dirpath) -> 0
- *
- * Changes the root directory of the calling process to that specified in +dirpath+.
- * The new root directory is used for pathnames beginning with <tt>'/'</tt>.
- * The root directory is inherited by all children of the calling process.
- *
- * Only a privileged process may call +chroot+.
+ * call-seq:
+ * Dir.chroot( string ) -> 0
*
- * See {Linux chroot}[https://man7.org/linux/man-pages/man2/chroot.2.html].
+ * Changes this process's idea of the file system root. Only a
+ * privileged process may make this call. Not available on all
+ * platforms. On Unix systems, see <code>chroot(2)</code> for more
+ * information.
*/
static VALUE
dir_s_chroot(VALUE dir, VALUE path)
@@ -1475,20 +1217,18 @@ nogvl_mkdir(void *ptr)
}
/*
- * call-seq:
- * Dir.mkdir(dirpath, permissions = 0775) -> 0
+ * call-seq:
+ * Dir.mkdir( string [, integer] ) -> 0
*
- * Creates a directory in the underlying file system
- * at +dirpath+ with the given +permissions+;
- * returns zero:
+ * Makes a new directory named by <i>string</i>, with permissions
+ * specified by the optional parameter <i>anInteger</i>. The
+ * permissions may be modified by the value of File::umask, and are
+ * ignored on NT. Raises a SystemCallError if the directory cannot be
+ * created. See also the discussion of permissions in the class
+ * documentation for File.
*
- * Dir.mkdir('foo')
- * File.stat(Dir.new('foo')).mode.to_s(8)[1..4] # => "0755"
- * Dir.mkdir('bar', 0644)
- * File.stat(Dir.new('bar')).mode.to_s(8)[1..4] # => "0644"
+ * Dir.mkdir(File.join(Dir.home, ".foo"), 0700) #=> 0
*
- * See {File Permissions}[rdoc-ref:File@File+Permissions].
- * Note that argument +permissions+ is ignored on Windows.
*/
static VALUE
dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
@@ -1522,14 +1262,13 @@ nogvl_rmdir(void *ptr)
}
/*
- * call-seq:
- * Dir.rmdir(dirpath) -> 0
- *
- * Removes the directory at +dirpath+ from the underlying file system:
+ * call-seq:
+ * Dir.delete( string ) -> 0
+ * Dir.rmdir( string ) -> 0
+ * Dir.unlink( string ) -> 0
*
- * Dir.rmdir('foo') # => 0
- *
- * Raises an exception if the directory is not empty.
+ * Deletes the named directory. Raises a subclass of SystemCallError
+ * if the directory isn't empty.
*/
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
@@ -1737,7 +1476,7 @@ nogvl_opendir_at(void *ptr)
/* fallthrough*/
case 0:
if (fd >= 0) close(fd);
- rb_errno_set(e);
+ errno = e;
}
}
#else /* !USE_OPENDIR_AT */
@@ -3130,7 +2869,7 @@ push_glob(VALUE ary, VALUE str, VALUE base, int flags)
fd = AT_FDCWD;
if (!NIL_P(base)) {
if (!RB_TYPE_P(base, T_STRING) || !rb_enc_check(str, base)) {
- struct dir_data *dirp = RTYPEDDATA_GET_DATA(base);
+ struct dir_data *dirp = DATA_PTR(base);
if (!dirp->dir) dir_closed();
#ifdef HAVE_DIRFD
if ((fd = dirfd(dirp->dir)) == -1)
@@ -3254,35 +2993,26 @@ dir_open_dir(int argc, VALUE *argv)
/*
- * call-seq:
- * Dir.foreach(dirpath, encoding: 'UTF-8') {|entry_name| ... } -> nil
- *
- * Calls the block with each entry name in the directory at +dirpath+;
- * sets the given encoding onto each passed +entry_name+:
- *
- * Dir.foreach('/example') {|entry_name| p entry_name }
- *
- * Output:
+ * call-seq:
+ * Dir.foreach( dirname ) {| filename | block } -> nil
+ * Dir.foreach( dirname, encoding: enc ) {| filename | block } -> nil
+ * Dir.foreach( dirname ) -> an_enumerator
+ * Dir.foreach( dirname, encoding: enc ) -> an_enumerator
*
- * "config.h"
- * "lib"
- * "main.rb"
- * ".."
- * "."
+ * Calls the block once for each entry in the named directory, passing
+ * the filename of each entry as a parameter to the block.
*
- * Encoding:
+ * If no block is given, an enumerator is returned instead.
*
- * Dir.foreach('/example') {|entry_name| p entry_name.encoding; break }
- * Dir.foreach('/example', encoding: 'US-ASCII') {|entry_name| p entry_name.encoding; break }
+ * Dir.foreach("testdir") {|x| puts "Got #{x}" }
*
- * Output:
+ * <em>produces:</em>
*
- * #<Encoding:UTF-8>
- * #<Encoding:US-ASCII>
+ * Got .
+ * Got ..
+ * Got config.h
+ * Got main.rb
*
- * See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding].
- *
- * Returns an enumerator if no block is given.
*/
static VALUE
dir_foreach(int argc, VALUE *argv, VALUE io)
@@ -3304,21 +3034,19 @@ dir_collect(VALUE dir)
}
/*
- * call-seq:
- * Dir.entries(dirname, encoding: 'UTF-8') -> array
+ * call-seq:
+ * Dir.entries( dirname ) -> array
+ * Dir.entries( dirname, encoding: enc ) -> array
*
- * Returns an array of the entry names in the directory at +dirpath+;
- * sets the given encoding onto each returned entry name:
+ * Returns an array containing all of the filenames in the given
+ * directory. Will raise a SystemCallError if the named directory
+ * doesn't exist.
*
- * Dir.entries('/example') # => ["config.h", "lib", "main.rb", "..", "."]
- * Dir.entries('/example').first.encoding
- * # => #<Encoding:UTF-8>
- * Dir.entries('/example', encoding: 'US-ASCII').first.encoding
- * # => #<Encoding:US-ASCII>
+ * The optional <i>encoding</i> keyword argument specifies the encoding of the
+ * directory. If not specified, the filesystem encoding is used.
*
- * See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding].
+ * Dir.entries("testdir") #=> [".", "..", "config.h", "main.rb"]
*
- * Raises an exception if the directory does not exist.
*/
static VALUE
dir_entries(int argc, VALUE *argv, VALUE io)
@@ -3336,12 +3064,25 @@ dir_each_child(VALUE dir)
}
/*
- * call-seq:
- * Dir.each_child(dirpath) {|entry_name| ... } -> nil
- * Dir.each_child(dirpath, encoding: 'UTF-8') {|entry_name| ... } -> nil
+ * call-seq:
+ * Dir.each_child( dirname ) {| filename | block } -> nil
+ * Dir.each_child( dirname, encoding: enc ) {| filename | block } -> nil
+ * Dir.each_child( dirname ) -> an_enumerator
+ * Dir.each_child( dirname, encoding: enc ) -> an_enumerator
+ *
+ * Calls the block once for each entry except for "." and ".." in the
+ * named directory, passing the filename of each entry as a parameter
+ * to the block.
+ *
+ * If no block is given, an enumerator is returned instead.
+ *
+ * Dir.each_child("testdir") {|x| puts "Got #{x}" }
+ *
+ * <em>produces:</em>
+ *
+ * Got config.h
+ * Got main.rb
*
- * Like Dir.foreach, except that entries <tt>'.'</tt> and <tt>'..'</tt>
- * are not included.
*/
static VALUE
dir_s_each_child(int argc, VALUE *argv, VALUE io)
@@ -3355,22 +3096,24 @@ dir_s_each_child(int argc, VALUE *argv, VALUE io)
}
/*
- * call-seq:
- * each_child {|entry_name| ... } -> self
+ * call-seq:
+ * dir.each_child {| filename | block } -> dir
+ * dir.each_child -> an_enumerator
+ *
+ * Calls the block once for each entry except for "." and ".." in
+ * this directory, passing the filename of each entry as a parameter
+ * to the block.
*
- * Calls the block with each entry name in +self+
- * except <tt>'.'</tt> and <tt>'..'</tt>:
+ * If no block is given, an enumerator is returned instead.
*
- * dir = Dir.new('/example')
- * dir.each_child {|entry_name| p entry_name }
+ * d = Dir.new("testdir")
+ * d.each_child {|x| puts "Got #{x}" }
*
- * Output:
+ * <em>produces:</em>
*
- * "config.h"
- * "lib"
- * "main.rb"
+ * Got config.h
+ * Got main.rb
*
- * If no block is given, returns an enumerator.
*/
static VALUE
dir_each_child_m(VALUE dir)
@@ -3380,14 +3123,14 @@ dir_each_child_m(VALUE dir)
}
/*
- * call-seq:
- * children -> array
+ * call-seq:
+ * dir.children -> array
*
- * Returns an array of the entry names in +self+
- * except for <tt>'.'</tt> and <tt>'..'</tt>:
+ * Returns an array containing all of the filenames except for "."
+ * and ".." in this directory.
*
- * dir = Dir.new('/example')
- * dir.children # => ["config.h", "lib", "main.rb"]
+ * d = Dir.new("testdir")
+ * d.children #=> ["config.h", "main.rb"]
*
*/
static VALUE
@@ -3399,23 +3142,19 @@ dir_collect_children(VALUE dir)
}
/*
- * call-seq:
- * Dir.children(dirpath) -> array
- * Dir.children(dirpath, encoding: 'UTF-8') -> array
+ * call-seq:
+ * Dir.children( dirname ) -> array
+ * Dir.children( dirname, encoding: enc ) -> array
*
- * Returns an array of the entry names in the directory at +dirpath+
- * except for <tt>'.'</tt> and <tt>'..'</tt>;
- * sets the given encoding onto each returned entry name:
+ * Returns an array containing all of the filenames except for "."
+ * and ".." in the given directory. Will raise a SystemCallError if
+ * the named directory doesn't exist.
*
- * Dir.children('/example') # => ["config.h", "lib", "main.rb"]
- * Dir.children('/example').first.encoding
- * # => #<Encoding:UTF-8>
- * Dir.children('/example', encoding: 'US-ASCII').first.encoding
- * # => #<Encoding:US-ASCII>
+ * The optional <i>encoding</i> keyword argument specifies the encoding of the
+ * directory. If not specified, the filesystem encoding is used.
*
- * See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding].
+ * Dir.children("testdir") #=> ["config.h", "main.rb"]
*
- * Raises an exception if the directory does not exist.
*/
static VALUE
dir_s_children(int argc, VALUE *argv, VALUE io)
@@ -3489,16 +3228,12 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
}
/*
- * call-seq:
- * Dir.home(user_name = nil) -> dirpath
+ * call-seq:
+ * Dir.home() -> "/home/me"
+ * Dir.home("root") -> "/root"
*
- * Retruns the home directory path of the user specified with +user_name+
- * if it is not +nil+, or the current login user:
- *
- * Dir.home # => "/home/me"
- * Dir.home('root') # => "/root"
- *
- * Raises ArgumentError if +user_name+ is not a user name.
+ * Returns the home directory of the current user or the named user
+ * if given.
*/
static VALUE
dir_s_home(int argc, VALUE *argv, VALUE obj)
@@ -3523,15 +3258,10 @@ dir_s_home(int argc, VALUE *argv, VALUE obj)
#if 0
/*
* call-seq:
- * Dir.exist?(dirpath) -> true or false
- *
- * Returns whether +dirpath+ is a directory in the underlying file system:
+ * Dir.exist?(file_name) -> true or false
*
- * Dir.exist?('/example') # => true
- * Dir.exist?('/nosuch') # => false
- * Dir.exist?('/example/main.rb') # => false
- *
- * Same as File.directory?.
+ * Returns <code>true</code> if the named file is a directory,
+ * <code>false</code> otherwise.
*
*/
VALUE
@@ -3558,7 +3288,8 @@ nogvl_dir_empty_p(void *ptr)
/* fall through */
case 0:
if (e == ENOTDIR) return (void *)Qfalse;
- return (void *)INT2FIX(e);
+ errno = e; /* for rb_sys_fail_path */
+ return (void *)Qundef;
}
}
while ((dp = READDIR(dir, NULL)) != NULL) {
@@ -3573,18 +3304,10 @@ nogvl_dir_empty_p(void *ptr)
/*
* call-seq:
- * Dir.empty?(dirpath) -> true or false
- *
- * Returns whether +dirpath+ specifies an empty directory:
- *
- * dirpath = '/tmp/foo'
- * Dir.mkdir(dirpath)
- * Dir.empty?(dirpath) # => true
- * Dir.empty?('/example') # => false
- * Dir.empty?('/example/main.rb') # => false
+ * Dir.empty?(path_name) -> true or false
*
- * Raises an exception if +dirpath+ does not specify a directory or file
- * in the underlying file system.
+ * Returns <code>true</code> if the named file is an empty directory,
+ * <code>false</code> if it is not a directory or non-empty.
*/
static VALUE
rb_dir_s_empty_p(VALUE obj, VALUE dirname)
@@ -3620,8 +3343,8 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname)
result = (VALUE)rb_thread_call_without_gvl(nogvl_dir_empty_p, (void *)path,
RUBY_UBF_IO, 0);
- if (FIXNUM_P(result)) {
- rb_syserr_fail_path((int)FIX2LONG(result), orig);
+ if (UNDEF_P(result)) {
+ rb_sys_fail_path(orig);
}
return result;
}
@@ -3634,7 +3357,6 @@ Init_Dir(void)
rb_include_module(rb_cDir, rb_mEnumerable);
rb_define_alloc_func(rb_cDir, dir_s_alloc);
- rb_define_singleton_method(rb_cDir,"for_fd", dir_s_for_fd, 1);
rb_define_singleton_method(rb_cDir, "foreach", dir_foreach, -1);
rb_define_singleton_method(rb_cDir, "entries", dir_entries, -1);
rb_define_singleton_method(rb_cDir, "each_child", dir_s_each_child, -1);
@@ -3654,9 +3376,7 @@ Init_Dir(void)
rb_define_method(rb_cDir,"pos", dir_tell, 0);
rb_define_method(rb_cDir,"pos=", dir_set_pos, 1);
rb_define_method(rb_cDir,"close", dir_close, 0);
- rb_define_method(rb_cDir,"chdir", dir_chdir, 0);
- rb_define_singleton_method(rb_cDir,"fchdir", dir_s_fchdir, 1);
rb_define_singleton_method(rb_cDir,"chdir", dir_s_chdir, -1);
rb_define_singleton_method(rb_cDir,"getwd", dir_s_getwd, 0);
rb_define_singleton_method(rb_cDir,"pwd", dir_s_getwd, 0);
@@ -3673,26 +3393,51 @@ Init_Dir(void)
rb_define_singleton_method(rb_cFile,"fnmatch", file_s_fnmatch, -1);
rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1);
- /* Document-const: FNM_NOESCAPE
- * {File::FNM_NOESCAPE}[rdoc-ref:File::Constants@File-3A-3AFNM_NOESCAPE] */
+ /* Document-const: File::Constants::FNM_NOESCAPE
+ *
+ * Disables escapes in File.fnmatch and Dir.glob patterns
+ */
rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE));
- /* Document-const: FNM_PATHNAME
- * {File::FNM_PATHNAME}[rdoc-ref:File::Constants@File-3A-3AFNM_PATHNAME] */
+
+ /* Document-const: File::Constants::FNM_PATHNAME
+ *
+ * Wildcards in File.fnmatch and Dir.glob patterns do not match directory
+ * separators
+ */
rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
- /* Document-const: FNM_DOTMATCH
- * {File::FNM_DOTMATCH}[rdoc-ref:File::Constants@File-3A-3AFNM_DOTMATCH] */
+
+ /* Document-const: File::Constants::FNM_DOTMATCH
+ *
+ * The '*' wildcard matches filenames starting with "." in File.fnmatch
+ * and Dir.glob patterns
+ */
rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH));
- /* Document-const: FNM_CASEFOLD
- * {File::FNM_CASEFOLD}[rdoc-ref:File::Constants@File-3A-3AFNM_CASEFOLD] */
+
+ /* Document-const: File::Constants::FNM_CASEFOLD
+ *
+ * Makes File.fnmatch patterns case insensitive (but not Dir.glob
+ * patterns).
+ */
rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
- /* Document-const: FNM_EXTGLOB
- * {File::FNM_EXTGLOB}[rdoc-ref:File::Constants@File-3A-3AFNM_EXTGLOB] */
+
+ /* Document-const: File::Constants::FNM_EXTGLOB
+ *
+ * Allows file globbing through "{a,b}" in File.fnmatch patterns.
+ */
rb_file_const("FNM_EXTGLOB", INT2FIX(FNM_EXTGLOB));
- /* Document-const: FNM_SYSCASE
- * {File::FNM_SYSCASE}[rdoc-ref:File::Constants@File-3A-3AFNM_SYSCASE] */
+
+ /* Document-const: File::Constants::FNM_SYSCASE
+ *
+ * System default case insensitiveness, equals to FNM_CASEFOLD or
+ * 0.
+ */
rb_file_const("FNM_SYSCASE", INT2FIX(FNM_SYSCASE));
- /* Document-const: FNM_SHORTNAME
- * {File::FNM_SHORTNAME}[rdoc-ref:File::Constants@File-3A-3AFNM_SHORTNAME] */
+
+ /* Document-const: File::Constants::FNM_SHORTNAME
+ *
+ * Makes patterns to match short names if existing. Valid only
+ * on Microsoft Windows.
+ */
rb_file_const("FNM_SHORTNAME", INT2FIX(FNM_SHORTNAME));
}
diff --git a/dir.rb b/dir.rb
index 632c49eee9..2e426b0881 100644
--- a/dir.rb
+++ b/dir.rb
@@ -1,85 +1,11 @@
-# An object of class \Dir represents a directory in the underlying file system.
+# Objects of class Dir are directory streams representing
+# directories in the underlying file system. They provide a variety
+# of ways to list directories and their contents. See also File.
#
-# It consists mainly of:
-#
-# - A string _path_, given when the object is created,
-# that specifies a directory in the underlying file system;
-# method #path returns the path.
-# - A collection of string <i>entry names</i>,
-# each of which is the name of a directory or file in the underlying file system;
-# the entry names may be retrieved
-# in an {array-like fashion}[rdoc-ref:Dir@Dir+As+Array-Like]
-# or in a {stream-like fashion}[rdoc-ref:Dir@Dir+As+Stream-Like].
-#
-# == About the Examples
-#
-# Some examples on this page use this simple file tree:
-#
-# example/
-# ├── config.h
-# ├── lib/
-# │ ├── song/
-# │ │ └── karaoke.rb
-# │ └── song.rb
-# └── main.rb
-#
-# Others use the file tree for the
-# {Ruby project itself}[https://github.com/ruby/ruby].
-#
-# == \Dir As \Array-Like
-#
-# A \Dir object is in some ways array-like:
-#
-# - It has instance methods #children, #each, and #each_child.
-# - It includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here].
-#
-# == \Dir As Stream-Like
-#
-# A \Dir object is in some ways stream-like.
-#
-# The stream is initially open for reading,
-# but may be closed manually (using method #close),
-# and will be closed on block exit if created by Dir.open called with a block.
-# The closed stream may not be further manipulated,
-# and may not be reopened.
-#
-# The stream has a _position_, which is the index of an entry in the directory:
-#
-# - The initial position is zero (before the first entry).
-# - \Method #tell (aliased as #pos) returns the position.
-# - \Method #pos= sets the position (but ignores a value outside the stream),
-# and returns the position.
-# - \Method #seek is like #pos=, but returns +self+ (convenient for chaining).
-# - \Method #read, if not at end-of-stream, reads the next entry and increments
-# the position;
-# if at end-of-stream, does not increment the position.
-# - \Method #rewind sets the position to zero.
-#
-# Examples (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]):
-#
-# dir = Dir.new('example') # => #<Dir:example>
-# dir.pos # => 0
-#
-# dir.read # => "."
-# dir.read # => ".."
-# dir.read # => "config.h"
-# dir.read # => "lib"
-# dir.read # => "main.rb"
-# dir.pos # => 5
-# dir.read # => nil
-# dir.pos # => 5
-#
-# dir.rewind # => #<Dir:example>
-# dir.pos # => 0
-#
-# dir.pos = 3 # => 3
-# dir.pos # => 3
-#
-# dir.seek(4) # => #<Dir:example>
-# dir.pos # => 4
-#
-# dir.close # => nil
-# dir.read # Raises IOError.
+# The directory used in these examples contains the two regular files
+# (<code>config.h</code> and <code>main.rb</code>), the parent
+# directory (<code>..</code>), and the directory itself
+# (<code>.</code>).
#
# == What's Here
#
@@ -154,32 +80,20 @@
# closing it upon block exit.
# - ::unlink (aliased as ::delete and ::rmdir): Removes the given directory.
# - #inspect: Returns a string description of +self+.
-#
class Dir
# call-seq:
- # Dir.open(dirpath) -> dir
- # Dir.open(dirpath, encoding: nil) -> dir
- # Dir.open(dirpath) {|dir| ... } -> object
- # Dir.open(dirpath, encoding: nil) {|dir| ... } -> object
- #
- # Creates a new \Dir object _dir_ for the directory at +dirpath+.
- #
- # With no block, the method equivalent to Dir.new(dirpath, encoding):
- #
- # Dir.open('.') # => #<Dir:.>
- #
- # With a block given, the block is called with the created _dir_;
- # on block exit _dir_ is closed and the block's value is returned:
- #
- # Dir.open('.') {|dir| dir.inspect } # => "#<Dir:.>"
- #
- # The value given with optional keyword argument +encoding+
- # specifies the encoding for the directory entry names;
- # if +nil+ (the default), the file system's encoding is used:
- #
- # Dir.open('.').read.encoding # => #<Encoding:UTF-8>
- # Dir.open('.', encoding: 'US-ASCII').read.encoding # => #<Encoding:US-ASCII>
- #
+ # Dir.open( string ) -> aDir
+ # Dir.open( string, encoding: enc ) -> aDir
+ # Dir.open( string ) {| aDir | block } -> anObject
+ # Dir.open( string, encoding: enc ) {| aDir | block } -> anObject
+ #
+ # The optional <i>encoding</i> keyword argument specifies the encoding of the directory.
+ # If not specified, the filesystem encoding is used.
+ #
+ # With no block, <code>open</code> is a synonym for Dir::new. If a
+ # block is present, it is passed <i>aDir</i> as a parameter. The
+ # directory is closed at the end of the block, and Dir::open returns
+ # the value of the block.
def self.open(name, encoding: nil, &block)
dir = Primitive.dir_s_open(name, encoding)
if block
@@ -194,219 +108,114 @@ class Dir
end
# call-seq:
- # Dir.new(dirpath) -> dir
- # Dir.new(dirpath, encoding: nil) -> dir
- #
- # Returns a new \Dir object for the directory at +dirpath+:
- #
- # Dir.new('.') # => #<Dir:.>
+ # Dir.new( string ) -> aDir
+ # Dir.new( string, encoding: enc ) -> aDir
#
- # The value given with optional keyword argument +encoding+
- # specifies the encoding for the directory entry names;
- # if +nil+ (the default), the file system's encoding is used:
- #
- # Dir.new('.').read.encoding # => #<Encoding:UTF-8>
- # Dir.new('.', encoding: 'US-ASCII').read.encoding # => #<Encoding:US-ASCII>
+ # Returns a new directory object for the named directory.
#
+ # The optional <i>encoding</i> keyword argument specifies the encoding of the directory.
+ # If not specified, the filesystem encoding is used.
def initialize(name, encoding: nil)
Primitive.dir_initialize(name, encoding)
end
# call-seq:
- # Dir[*patterns, base: nil, sort: true] -> array
- #
- # Calls Dir.glob with argument +patterns+
- # and the values of keyword arguments +base+ and +sort+;
- # returns the array of selected entry names.
+ # Dir[ string [, string ...] [, base: path] [, sort: true] ] -> array
#
+ # Equivalent to calling
+ # <code>Dir.glob([</code><i>string,...</i><code>], 0)</code>.
def self.[](*args, base: nil, sort: true)
Primitive.dir_s_aref(args, base, sort)
end
# call-seq:
- # Dir.glob(*patterns, flags: 0, base: nil, sort: true) -> array
- # Dir.glob(*patterns, flags: 0, base: nil, sort: true) {|entry_name| ... } -> nil
- #
- # Forms an array _entry_names_ of the entry names selected by the arguments.
- #
- # Argument +patterns+ is a string pattern or an array of string patterns;
- # note that these are not regexps; see below.
- #
- # Notes for the following examples:
- #
- # - <tt>'*'</tt> is the pattern that matches any entry name
- # except those that begin with <tt>'.'</tt>.
- # - We use method Array#take to shorten returned arrays
- # that otherwise would be very large.
- #
- # With no block, returns array _entry_names_;
- # example (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]):
- #
- # Dir.glob('*') # => ["config.h", "lib", "main.rb"]
- #
- # With a block, calls the block with each of the _entry_names_
- # and returns +nil+:
- #
- # Dir.glob('*') {|entry_name| puts entry_name } # => nil
+ # Dir.glob( pattern, [flags], [base: path] [, sort: true] ) -> array
+ # Dir.glob( pattern, [flags], [base: path] [, sort: true] ) { |filename| block } -> nil
#
- # Output:
+ # Expands +pattern+, which is a pattern string or an Array of pattern
+ # strings, and returns an array containing the matching filenames.
+ # If a block is given, calls the block once for each matching filename,
+ # passing the filename as a parameter to the block.
#
- # config.h
- # lib
- # main.rb
+ # The optional +base+ keyword argument specifies the base directory for
+ # interpreting relative pathnames instead of the current working directory.
+ # As the results are not prefixed with the base directory name in this
+ # case, you will need to prepend the base directory name if you want real
+ # paths.
#
- # If optional keyword argument +flags+ is given,
- # the value modifies the matching; see below.
+ # The results which matched single wildcard or character set are sorted in
+ # binary ascending order, unless +false+ is given as the optional +sort+
+ # keyword argument. The order of an Array of pattern strings and braces
+ # are preserved.
#
- # If optional keyword argument +base+ is given,
- # its value specifies the base directory.
- # Each pattern string specifies entries relative to the base directory;
- # the default is <tt>'.'</tt>.
- # The base directory is not prepended to the entry names in the result:
+ # Note that the pattern is not a regexp, it's closer to a shell glob.
+ # See File::fnmatch for the meaning of the +flags+ parameter.
+ # Case sensitivity depends on your system (+File::FNM_CASEFOLD+ is ignored).
#
- # Dir.glob(pattern, base: 'lib').take(5)
- # # => ["abbrev.gemspec", "abbrev.rb", "base64.gemspec", "base64.rb", "benchmark.gemspec"]
- # Dir.glob(pattern, base: 'lib/irb').take(5)
- # # => ["cmd", "color.rb", "color_printer.rb", "completion.rb", "context.rb"]
- #
- # If optional keyword +sort+ is given, its value specifies whether
- # the array is to be sorted; the default is +true+.
- # Passing value +false+ with that keyword disables sorting
- # (though the underlying file system may already have sorted the array).
- #
- # <b>Patterns</b>
- #
- # Each pattern string is expanded
- # according to certain metacharacters;
- # examples below use the {Ruby file tree}[rdoc-ref:Dir@About+the+Examples]:
- #
- # - <tt>'*'</tt>: Matches any substring in an entry name,
- # similar in meaning to regexp <tt>/.*/mx</tt>;
- # may be restricted by other values in the pattern strings:
- #
- # - <tt>'*'</tt> matches all entry names:
- #
- # Dir.glob('*').take(3) # => ["BSDL", "CONTRIBUTING.md", "COPYING"]
- #
- # - <tt>'c*'</tt> matches entry names beginning with <tt>'c'</tt>:
- #
- # Dir.glob('c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"]
- #
- # - <tt>'*c'</tt> matches entry names ending with <tt>'c'</tt>:
- #
- # Dir.glob('*c').take(3) # => ["addr2line.c", "array.c", "ast.c"]
- #
- # - <tt>'\*c\*'</tt> matches entry names that contain <tt>'c'</tt>,
- # even at the beginning or end:
- #
- # Dir.glob('*c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"]
- #
- # Does not match Unix-like hidden entry names ("dot files").
- # To include those in the matched entry names,
- # use flag IO::FNM_DOTMATCH or something like <tt>'{*,.*}'</tt>.
- #
- # - <tt>'**'</tt>: Matches entry names recursively
- # if followed by the slash character <tt>'/'</tt>:
- #
- # Dir.glob('**/').take(3) # => ["basictest/", "benchmark/", "benchmark/gc/"]
- #
- # If the string pattern contains other characters
- # or is not followed by a slash character,
- # it is equivalent to <tt>'*'</tt>.
- #
- # - <tt>'?'</tt> Matches any single character;
- # similar in meaning to regexp <tt>/./</tt>:
- #
- # Dir.glob('io.?') # => ["io.c"]
- #
- # - <tt>'[_set_]'</tt>: Matches any one character in the string _set_;
- # behaves like a {Regexp character class}[rdoc-ref:Regexp@Character+Classes],
- # including set negation (<tt>'[^a-z]'</tt>):
- #
- # Dir.glob('*.[a-z][a-z]').take(3)
- # # => ["CONTRIBUTING.md", "COPYING.ja", "KNOWNBUGS.rb"]
- #
- # - <tt>'{_abc_,_xyz_}'</tt>:
- # Matches either string _abc_ or string _xyz_;
- # behaves like {Regexp alternation}[rdoc-ref:Regexp@Alternation]:
- #
- # Dir.glob('{LEGAL,BSDL}') # => ["LEGAL", "BSDL"]
- #
- # More than two alternatives may be given.
- #
- # - <tt>\\</tt>: Escapes the following metacharacter.
- #
- # Note that on Windows, the backslash character may not be used
- # in a string pattern:
- # <tt>Dir['c:\\foo*']</tt> will not work, use <tt>Dir['c:/foo*']</tt> instead.
- #
- # More examples (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]):
- #
- # # We're in the example directory.
- # File.basename(Dir.pwd) # => "example"
- # Dir.glob('config.?') # => ["config.h"]
- # Dir.glob('*.[a-z][a-z]') # => ["main.rb"]
- # Dir.glob('*.[^r]*') # => ["config.h"]
- # Dir.glob('*.{rb,h}') # => ["main.rb", "config.h"]
- # Dir.glob('*') # => ["config.h", "lib", "main.rb"]
- # Dir.glob('*', File::FNM_DOTMATCH) # => [".", "config.h", "lib", "main.rb"]
- # Dir.glob(["*.rb", "*.h"]) # => ["main.rb", "config.h"]
- #
- # Dir.glob('**/*.rb')
- # => ["lib/song/karaoke.rb", "lib/song.rb", "main.rb"]
- #
- # Dir.glob('**/*.rb', base: 'lib') # => ["song/karaoke.rb", "song.rb"]
- #
- # Dir.glob('**/lib') # => ["lib"]
+ # <code>*</code>::
+ # Matches any file. Can be restricted by other values in the glob.
+ # Equivalent to <code>/.*/mx</code> in regexp.
#
- # Dir.glob('**/lib/**/*.rb') # => ["lib/song/karaoke.rb", "lib/song.rb"]
+ # <code>*</code>:: Matches all files
+ # <code>c*</code>:: Matches all files beginning with <code>c</code>
+ # <code>*c</code>:: Matches all files ending with <code>c</code>
+ # <code>\*c\*</code>:: Match all files that have <code>c</code> in them
+ # (including at the beginning or end).
#
- # Dir.glob('**/lib/*.rb') # => ["lib/song.rb"]
+ # Note, this will not match Unix-like hidden files (dotfiles). In order
+ # to include those in the match results, you must use the
+ # File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>.
#
- # <b>Flags</b>
+ # <code>**</code>::
+ # Matches directories recursively if followed by <code>/</code>. If
+ # this path segment contains any other characters, it is the same as the
+ # usual <code>*</code>.
#
- # If optional keyword argument +flags+ is given (the default is zero -- no flags),
- # its value should be the bitwise OR of one or more of the constants
- # defined in module File::Constants.
+ # <code>?</code>::
+ # Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
#
- # Example:
+ # <code>[set]</code>::
+ # Matches any one character in +set+. Behaves exactly like character sets
+ # in Regexp, including set negation (<code>[^a-z]</code>).
#
- # flags = File::FNM_EXTGLOB | File::FNM_DOTMATCH
+ # <code>{p,q}</code>::
+ # Matches either literal <code>p</code> or literal <code>q</code>.
+ # Equivalent to pattern alternation in regexp.
#
- # Specifying flags can extend, restrict, or otherwise modify the matching.
+ # Matching literals may be more than one character in length. More than
+ # two literals may be specified.
#
- # The flags for this method (other constants in File::Constants do not apply):
+ # <code>\\</code>::
+ # Escapes the next metacharacter.
#
- # - File::FNM_DOTMATCH:
- # specifies that entry names beginning with <tt>'.'</tt>
- # should be considered for matching:
+ # Note that this means you cannot use backslash on windows as part of a
+ # glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use
+ # <code>Dir["c:/foo*"]</code> instead.
#
- # Dir.glob('*').take(5)
- # # => ["BSDL", "CONTRIBUTING.md", "COPYING", "COPYING.ja", "GPL"]
- # Dir.glob('*', flags: File::FNM_DOTMATCH).take(5)
- # # => [".", ".appveyor.yml", ".cirrus.yml", ".dir-locals.el", ".document"]
+ # Examples:
#
- # - File::FNM_EXTGLOB:
- # enables the pattern extension
- # <tt>'{_a_,_b_}'</tt>, which matches pattern _a_ and pattern _b_;
- # behaves like a
- # {regexp union}[rdoc-ref:Regexp.union]
- # (e.g., <tt>'(?:_a_|_b_)'</tt>):
+ # Dir["config.?"] #=> ["config.h"]
+ # Dir.glob("config.?") #=> ["config.h"]
+ # Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
+ # Dir.glob("*.[^r]*") #=> ["config.h"]
+ # Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
+ # Dir.glob("*") #=> ["config.h", "main.rb"]
+ # Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "config.h", "main.rb"]
+ # Dir.glob(["*.rb", "*.h"]) #=> ["main.rb", "config.h"]
#
- # pattern = '{LEGAL,BSDL}'
- # Dir.glob(pattern) # => ["LEGAL", "BSDL"]
+ # Dir.glob("**/*.rb") #=> ["main.rb",
+ # # "lib/song.rb",
+ # # "lib/song/karaoke.rb"]
#
- # - File::FNM_NOESCAPE:
- # specifies that escaping with the backslash character <tt>'\'</tt>
- # is disabled; the character is not an escape character.
+ # Dir.glob("**/*.rb", base: "lib") #=> ["song.rb",
+ # # "song/karaoke.rb"]
#
- # - File::FNM_PATHNAME:
- # specifies that metacharacters <tt>'*'</tt> and <tt>'?'</tt>
- # do not match directory separators.
+ # Dir.glob("**/lib") #=> ["lib"]
#
- # - File::FNM_SHORTNAME:
- # specifies that patterns may match short names if they exist; Windows only.
+ # Dir.glob("**/lib/**/*.rb") #=> ["lib/song.rb",
+ # # "lib/song/karaoke.rb"]
#
+ # Dir.glob("**/lib/*.rb") #=> ["lib/song.rb"]
def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true)
Primitive.dir_s_glob(pattern, flags, base, sort)
end
diff --git a/dln.c b/dln.c
index b4c2fb9423..0edd709bbe 100644
--- a/dln.c
+++ b/dln.c
@@ -272,15 +272,13 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine)
static bool
dln_incompatible_func(void *handle, const char *funcname, void *const fp, const char **libname)
{
+ Dl_info dli;
void *ex = dlsym(handle, funcname);
if (!ex) return false;
if (ex == fp) return false;
-# if defined(HAVE_DLADDR)
- Dl_info dli;
if (dladdr(ex, &dli)) {
*libname = dli.dli_fname;
}
-# endif
return true;
}
@@ -394,12 +392,6 @@ dln_open(const char *file)
dln_fatalerror("%s - %s", incompatible, file);
}
else {
- if (libruby_name) {
- const size_t len = strlen(libruby_name);
- char *const tmp = ALLOCA_N(char, len + 1);
- if (tmp) memcpy(tmp, libruby_name, len + 1);
- libruby_name = tmp;
- }
dlclose(handle);
if (libruby_name) {
dln_loaderror("linked to incompatible %s - %s", libruby_name, file);
@@ -421,63 +413,33 @@ dln_open(const char *file)
static void *
dln_sym(void *handle, const char *symbol)
{
-#if defined(_WIN32)
- return GetProcAddress(handle, symbol);
-#elif defined(USE_DLN_DLOPEN)
- return dlsym(handle, symbol);
-#endif
-}
+ void *func;
+ const char *error;
-static void *
-dln_sym_func(void *handle, const char *symbol)
-{
- void *func = dln_sym(handle, symbol);
+#if defined(_WIN32)
+ char message[1024];
+ func = GetProcAddress(handle, symbol);
if (func == NULL) {
- const char *error;
-#if defined(_WIN32)
- char message[1024];
error = dln_strerror();
+ goto failed;
+ }
+
#elif defined(USE_DLN_DLOPEN)
+ func = dlsym(handle, symbol);
+ if (func == NULL) {
const size_t errlen = strlen(error = dln_strerror()) + 1;
error = memcpy(ALLOCA_N(char, errlen), error, errlen);
-#endif
- dln_loaderror("%s - %s", error, symbol);
+ goto failed;
}
- return func;
-}
-
-#define dln_sym_callable(rettype, argtype, handle, symbol) \
- (*(rettype (*)argtype)dln_sym_func(handle, symbol))
#endif
-void *
-dln_symbol(void *handle, const char *symbol)
-{
-#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
- if (EXTERNAL_PREFIX[0]) {
- const size_t symlen = strlen(symbol);
- char *const tmp = ALLOCA_N(char, symlen + sizeof(EXTERNAL_PREFIX));
- if (!tmp) dln_memerror();
- memcpy(tmp, EXTERNAL_PREFIX, sizeof(EXTERNAL_PREFIX) - 1);
- memcpy(tmp + sizeof(EXTERNAL_PREFIX) - 1, symbol, symlen + 1);
- symbol = tmp;
- }
- if (handle == NULL) {
-# if defined(USE_DLN_DLOPEN)
- handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
-# elif defined(_WIN32)
- handle = rb_libruby_handle();
-# else
- return NULL;
-# endif
- }
- return dln_sym(handle, symbol);
-#else
- return NULL;
-#endif
-}
+ return func;
+ failed:
+ dln_loaderror("%s - %s", error, symbol);
+}
+#endif
#if defined(RUBY_DLN_CHECK_ABI) && defined(USE_DLN_DLOPEN)
static bool
@@ -495,9 +457,8 @@ dln_load(const char *file)
void *handle = dln_open(file);
#ifdef RUBY_DLN_CHECK_ABI
- typedef unsigned long long abi_version_number;
- abi_version_number binary_abi_version =
- dln_sym_callable(abi_version_number, (void), handle, EXTERNAL_PREFIX "ruby_abi_version")();
+ unsigned long long (*abi_version_fct)(void) = (unsigned long long(*)(void))dln_sym(handle, "ruby_abi_version");
+ unsigned long long binary_abi_version = (*abi_version_fct)();
if (binary_abi_version != ruby_abi_version() && abi_check_enabled_p()) {
dln_loaderror("incompatible ABI version of binary - %s", file);
}
@@ -505,9 +466,10 @@ dln_load(const char *file)
char *init_fct_name;
init_funcname(&init_fct_name, file);
+ void (*init_fct)(void) = (void(*)(void))dln_sym(handle, init_fct_name);
/* Call the init code */
- dln_sym_callable(void, (void), handle, init_fct_name)();
+ (*init_fct)();
return handle;
diff --git a/dln.h b/dln.h
index d624bb6611..902f753450 100644
--- a/dln.h
+++ b/dln.h
@@ -25,7 +25,6 @@ RUBY_SYMBOL_EXPORT_BEGIN
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
void *dln_load(const char*);
-void *dln_symbol(void*,const char*);
RUBY_SYMBOL_EXPORT_END
diff --git a/dln_find.c b/dln_find.c
index 91c51394a9..5d380f5d39 100644
--- a/dln_find.c
+++ b/dln_find.c
@@ -75,7 +75,7 @@ dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size
".";
}
buf = dln_find_1(fname, path, buf, size, 1 DLN_FIND_EXTRA_ARG);
- free(envpath);
+ if (envpath) free(envpath);
return buf;
}
diff --git a/dmydln.c b/dmydln.c
index b1516937d3..d05cda0b8e 100644
--- a/dmydln.c
+++ b/dmydln.c
@@ -8,12 +8,3 @@ dln_load(const char *file)
UNREACHABLE_RETURN(NULL);
}
-
-NORETURN(void *dln_symbol(void*,const char*));
-void*
-dln_symbol(void *handle, const char *symbol)
-{
- rb_loaderror("this executable file can't load extension libraries");
-
- UNREACHABLE_RETURN(NULL);
-}
diff --git a/doc/.document b/doc/.document
index 5a58e6e3ad..f589dda07c 100644
--- a/doc/.document
+++ b/doc/.document
@@ -1,11 +1,9 @@
*.md
*.rb
-[^_]*.rdoc
+*.rdoc
contributing
NEWS
syntax
optparse
rdoc
-regexp
-rjit
yjit
diff --git a/doc/ChangeLog/ChangeLog-0.06_to_0.52 b/doc/ChangeLog-0.06_to_0.52
index 63826081b3..63826081b3 100644
--- a/doc/ChangeLog/ChangeLog-0.06_to_0.52
+++ b/doc/ChangeLog-0.06_to_0.52
diff --git a/doc/ChangeLog/ChangeLog-0.50_to_0.60 b/doc/ChangeLog-0.50_to_0.60
index 5f5b03ff40..5f5b03ff40 100644
--- a/doc/ChangeLog/ChangeLog-0.50_to_0.60
+++ b/doc/ChangeLog-0.50_to_0.60
diff --git a/doc/ChangeLog/ChangeLog-0.60_to_1.1 b/doc/ChangeLog-0.60_to_1.1
index 59d195e780..59d195e780 100644
--- a/doc/ChangeLog/ChangeLog-0.60_to_1.1
+++ b/doc/ChangeLog-0.60_to_1.1
diff --git a/doc/ChangeLog/ChangeLog-1.8.0 b/doc/ChangeLog-1.8.0
index 6d9453d011..6d9453d011 100644
--- a/doc/ChangeLog/ChangeLog-1.8.0
+++ b/doc/ChangeLog-1.8.0
diff --git a/doc/ChangeLog/ChangeLog-1.9.3 b/doc/ChangeLog-1.9.3
index 0f80eed2d5..0f80eed2d5 100644
--- a/doc/ChangeLog/ChangeLog-1.9.3
+++ b/doc/ChangeLog-1.9.3
diff --git a/doc/ChangeLog/ChangeLog-2.0.0 b/doc/ChangeLog-2.0.0
index 9e654db189..9e654db189 100644
--- a/doc/ChangeLog/ChangeLog-2.0.0
+++ b/doc/ChangeLog-2.0.0
diff --git a/doc/ChangeLog/ChangeLog-2.1.0 b/doc/ChangeLog-2.1.0
index 5b670b31c9..5b670b31c9 100644
--- a/doc/ChangeLog/ChangeLog-2.1.0
+++ b/doc/ChangeLog-2.1.0
diff --git a/doc/ChangeLog/ChangeLog-2.2.0 b/doc/ChangeLog-2.2.0
index 5a7dbf826d..5a7dbf826d 100644
--- a/doc/ChangeLog/ChangeLog-2.2.0
+++ b/doc/ChangeLog-2.2.0
diff --git a/doc/ChangeLog/ChangeLog-2.3.0 b/doc/ChangeLog-2.3.0
index 94996cffd0..94996cffd0 100644
--- a/doc/ChangeLog/ChangeLog-2.3.0
+++ b/doc/ChangeLog-2.3.0
diff --git a/doc/ChangeLog/ChangeLog-2.4.0 b/doc/ChangeLog-2.4.0
index a297a579d1..a297a579d1 100644
--- a/doc/ChangeLog/ChangeLog-2.4.0
+++ b/doc/ChangeLog-2.4.0
diff --git a/doc/ChangeLog/ChangeLog-YARV b/doc/ChangeLog-YARV
index 83df05c52c..83df05c52c 100644
--- a/doc/ChangeLog/ChangeLog-YARV
+++ b/doc/ChangeLog-YARV
diff --git a/doc/NEWS/NEWS-3.2.0.md b/doc/NEWS/NEWS-3.2.0.md
deleted file mode 100644
index 33a7b85c47..0000000000
--- a/doc/NEWS/NEWS-3.2.0.md
+++ /dev/null
@@ -1,820 +0,0 @@
-# NEWS for Ruby 3.2.0
-
-This document is a list of user-visible feature changes
-since the **3.1.0** release, except for bug fixes.
-
-Note that each entry is kept to a minimum, see links for details.
-
-## Language changes
-
-* Anonymous rest and keyword rest arguments can now be passed as
- arguments, instead of just used in method parameters.
- [[Feature #18351]]
-
- ```ruby
- def foo(*)
- bar(*)
- end
- def baz(**)
- quux(**)
- end
- ```
-
-* A proc that accepts a single positional argument and keywords will
- no longer autosplat. [[Bug #18633]]
-
- ```ruby
- proc{|a, **k| a}.call([1, 2])
- # Ruby 3.1 and before
- # => 1
- # Ruby 3.2 and after
- # => [1, 2]
- ```
-
-* Constant assignment evaluation order for constants set on explicit
- objects has been made consistent with single attribute assignment
- evaluation order. With this code:
-
- ```ruby
- foo::BAR = baz
- ```
-
- `foo` is now called before `baz`. Similarly, for multiple assignments
- to constants, left-to-right evaluation order is used. With this
- code:
-
- ```ruby
- foo1::BAR1, foo2::BAR2 = baz1, baz2
- ```
-
- The following evaluation order is now used:
-
- 1. `foo1`
- 2. `foo2`
- 3. `baz1`
- 4. `baz2`
-
- [[Bug #15928]]
-
-* "Find pattern" is no longer experimental.
- [[Feature #18585]]
-
-* Methods taking a rest parameter (like `*args`) and wishing to delegate keyword
- arguments through `foo(*args)` must now be marked with `ruby2_keywords`
- (if not already the case). In other words, all methods wishing to delegate
- keyword arguments through `*args` must now be marked with `ruby2_keywords`,
- with no exception. This will make it easier to transition to other ways of
- delegation once a library can require Ruby 3+. Previously, the `ruby2_keywords`
- flag was kept if the receiving method took `*args`, but this was a bug and an
- inconsistency. A good technique to find the potentially-missing `ruby2_keywords`
- is to run the test suite, for where it fails find the last method which must
- receive keyword arguments, use `puts nil, caller, nil` there, and check each
- method/block on the call chain which must delegate keywords is correctly marked
- as `ruby2_keywords`. [[Bug #18625]] [[Bug #16466]]
-
- ```ruby
- def target(**kw)
- end
-
- # Accidentally worked without ruby2_keywords in Ruby 2.7-3.1, ruby2_keywords
- # needed in 3.2+. Just like (*args, **kwargs) or (...) would be needed on
- # both #foo and #bar when migrating away from ruby2_keywords.
- ruby2_keywords def bar(*args)
- target(*args)
- end
-
- ruby2_keywords def foo(*args)
- bar(*args)
- end
-
- foo(k: 1)
- ```
-
-## Core classes updates
-
-Note: We're only listing outstanding class updates.
-
-* Fiber
-
- * Introduce Fiber.[] and Fiber.[]= for inheritable fiber storage.
- Introduce Fiber#storage and Fiber#storage= (experimental) for
- getting and resetting the current storage. Introduce
- `Fiber.new(storage:)` for setting the storage when creating a
- fiber. [[Feature #19078]]
-
- Existing Thread and Fiber local variables can be tricky to use.
- Thread-local variables are shared between all fibers, making it
- hard to isolate, while Fiber-local variables can be hard to
- share. It is often desirable to define unit of execution
- ("execution context") such that some state is shared between all
- fibers and threads created in that context. This is what Fiber
- storage provides.
-
- ```ruby
- def log(message)
- puts "#{Fiber[:request_id]}: #{message}"
- end
-
- def handle_requests
- while request = read_request
- Fiber.schedule do
- Fiber[:request_id] = SecureRandom.uuid
-
- request.messages.each do |message|
- Fiber.schedule do
- log("Handling #{message}") # Log includes inherited request_id.
- end
- end
- end
- end
- end
- ```
-
- You should generally consider Fiber storage for any state which
- you want to be shared implicitly between all fibers and threads
- created in a given context, e.g. a connection pool, a request
- id, a logger level, environment variables, configuration, etc.
-
-* Fiber::Scheduler
-
- * Introduce `Fiber::Scheduler#io_select` for non-blocking IO.select.
- [[Feature #19060]]
-
-* IO
-
- * Introduce IO#timeout= and IO#timeout which can cause
- IO::TimeoutError to be raised if a blocking operation exceeds the
- specified timeout. [[Feature #18630]]
-
- ```ruby
- STDIN.timeout = 1
- STDIN.read # => Blocking operation timed out! (IO::TimeoutError)
- ```
-
- * Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`.
- [[Feature #19036]]
-
-* Class
-
- * Class#attached_object, which returns the object for which
- the receiver is the singleton class. Raises TypeError if the
- receiver is not a singleton class.
- [[Feature #12084]]
-
- ```ruby
- class Foo; end
-
- Foo.singleton_class.attached_object #=> Foo
- Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370>
- Foo.attached_object #=> TypeError: `Foo' is not a singleton class
- nil.singleton_class.attached_object #=> TypeError: `NilClass' is not a singleton class
- ```
-
-* Data
-
- * New core class to represent simple immutable value object. The class is
- similar to Struct and partially shares an implementation, but has more
- lean and strict API. [[Feature #16122]]
-
- ```ruby
- Measure = Data.define(:amount, :unit)
- distance = Measure.new(100, 'km') #=> #<data Measure amount=100, unit="km">
- weight = Measure.new(amount: 50, unit: 'kg') #=> #<data Measure amount=50, unit="kg">
- weight.with(amount: 40) #=> #<data Measure amount=40, unit="kg">
- weight.amount #=> 50
- weight.amount = 40 #=> NoMethodError: undefined method `amount='
- ```
-
-* Encoding
-
- * Encoding#replicate has been deprecated and will be removed in 3.3. [[Feature #18949]]
- * The dummy `Encoding::UTF_16` and `Encoding::UTF_32` encodings no longer
- try to dynamically guess the endian based on a byte order mark.
- Use `Encoding::UTF_16BE`/`UTF_16LE` and `Encoding::UTF_32BE`/`UTF_32LE` instead.
- This change speeds up getting the encoding of a String. [[Feature #18949]]
- * Limit maximum encoding set size by 256.
- If exceeding maximum size, `EncodingError` will be raised. [[Feature #18949]]
-
-* Enumerator
-
- * Enumerator.product has been added. Enumerator::Product is the implementation. [[Feature #18685]]
-
-* Exception
-
- * Exception#detailed_message has been added.
- The default error printer calls this method on the Exception object
- instead of #message. [[Feature #18564]]
-
-* Hash
-
- * Hash#shift now always returns nil if the hash is
- empty, instead of returning the default value or
- calling the default proc. [[Bug #16908]]
-
-* Integer
-
- * Integer#ceildiv has been added. [[Feature #18809]]
-
-* Kernel
-
- * Kernel#binding raises RuntimeError if called from a non-Ruby frame
- (such as a method defined in C). [[Bug #18487]]
-
-* MatchData
-
- * MatchData#byteoffset has been added. [[Feature #13110]]
- * MatchData#deconstruct has been added. [[Feature #18821]]
- * MatchData#deconstruct_keys has been added. [[Feature #18821]]
-
-* Module
-
- * Module.used_refinements has been added. [[Feature #14332]]
- * Module#refinements has been added. [[Feature #12737]]
- * Module#const_added has been added. [[Feature #17881]]
- * Module#undefined_instance_methods has been added. [[Feature #12655]]
-
-* Proc
-
- * Proc#dup returns an instance of subclass. [[Bug #17545]]
- * Proc#parameters now accepts lambda keyword. [[Feature #15357]]
-
-* Process
- * Added `RLIMIT_NPTS` constant to FreeBSD platform
-
-* Regexp
-
- * The cache-based optimization is introduced.
- Many (but not all) Regexp matching is now in linear time, which
- will prevent regular expression denial of service (ReDoS)
- vulnerability. [[Feature #19104]]
-
- * Regexp.linear_time? is introduced. [[Feature #19194]]
-
- * Regexp.new now supports passing the regexp flags not only as an Integer,
- but also as a String. Unknown flags raise ArgumentError.
- Otherwise, anything other than `true`, `false`, `nil` or Integer will be warned.
- [[Feature #18788]]
-
- * Regexp.timeout= has been added. Also, Regexp.new new supports timeout keyword.
- See [[Feature #17837]]
-
-* Refinement
-
- * Refinement#refined_class has been added. [[Feature #12737]]
-
-* RubyVM::AbstractSyntaxTree
-
- * Add `error_tolerant` option for `parse`, `parse_file` and `of`. [[Feature #19013]]
- With this option
-
- 1. SyntaxError is suppressed
- 2. AST is returned for invalid input
- 3. `end` is complemented when a parser reaches to the end of input but `end` is insufficient
- 4. `end` is treated as keyword based on indent
-
- ```ruby
- # Without error_tolerant option
- root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY)
- def m
- a = 10
- if
- end
- RUBY
- # => <internal:ast>:33:in `parse': syntax error, unexpected `end' (SyntaxError)
-
- # With error_tolerant option
- root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true)
- def m
- a = 10
- if
- end
- RUBY
- p root # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-4:3>
-
- # `end` is treated as keyword based on indent
- root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true)
- module Z
- class Foo
- foo.
- end
-
- def bar
- end
- end
- RUBY
- p root.children[-1].children[-1].children[-1].children[-2..-1]
- # => [#<RubyVM::AbstractSyntaxTree::Node:CLASS@2:2-4:5>, #<RubyVM::AbstractSyntaxTree::Node:DEFN@6:2-7:5>]
- ```
-
- * Add `keep_tokens` option for `parse`, `parse_file` and `of`. Add `#tokens` and `#all_tokens`
- for RubyVM::AbstractSyntaxTree::Node [[Feature #19070]]
-
- ```ruby
- root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true)
- root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...]
- root.tokens.map{_1[2]}.join # => "x = 1 + 2"
- ```
-
-* Set
-
- * Set is now available as a built-in class without the need for `require "set"`. [[Feature #16989]]
- It is currently autoloaded via the Set constant or a call to Enumerable#to_set.
-
-* String
-
- * String#byteindex and String#byterindex have been added. [[Feature #13110]]
- * Update Unicode to Version 15.0.0 and Emoji Version 15.0. [[Feature #18639]]
- (also applies to Regexp)
- * String#bytesplice has been added. [[Feature #18598]]
- * String#dedup has been added as an alias to String#-@. [[Feature #18595]]
-
-* Struct
-
- * A Struct class can also be initialized with keyword arguments
- without `keyword_init: true` on Struct.new [[Feature #16806]]
-
- ```ruby
- Post = Struct.new(:id, :name)
- Post.new(1, "hello") #=> #<struct Post id=1, name="hello">
- # From Ruby 3.2, the following code also works without keyword_init: true.
- Post.new(id: 1, name: "hello") #=> #<struct Post id=1, name="hello">
- ```
-
-* Thread
-
- * Thread.each_caller_location is added. [[Feature #16663]]
-
-* Thread::Queue
-
- * Thread::Queue#pop(timeout: sec) is added. [[Feature #18774]]
-
-* Thread::SizedQueue
-
- * Thread::SizedQueue#pop(timeout: sec) is added. [[Feature #18774]]
- * Thread::SizedQueue#push(timeout: sec) is added. [[Feature #18944]]
-
-* Time
-
- * Time#deconstruct_keys is added, allowing to use Time instances
- in pattern-matching expressions [[Feature #19071]]
-
- * Time.new now can parse a string like generated by Time#inspect
- and return a Time instance based on the given argument.
- [[Feature #18033]]
-
-* SyntaxError
- * SyntaxError#path has been added. [[Feature #19138]]
-
-* TracePoint
-
- * TracePoint#binding now returns `nil` for `c_call`/`c_return` TracePoints.
- [[Bug #18487]]
- * TracePoint#enable `target_thread` keyword argument now defaults to the
- current thread if a block is given and `target` and `target_line` keyword
- arguments are not passed. [[Bug #16889]]
-
-* UnboundMethod
-
- * `UnboundMethod#==` returns `true` if the actual method is same. For example,
- `String.instance_method(:object_id) == Array.instance_method(:object_id)`
- returns `true`. [[Feature #18798]]
-
- * `UnboundMethod#inspect` does not show the receiver of `instance_method`.
- For example `String.instance_method(:object_id).inspect` returns
- `"#<UnboundMethod: Kernel#object_id()>"`
- (was `"#<UnboundMethod: String(Kernel)#object_id()>"`).
-
-* GC
-
- * Expose `need_major_gc` via `GC.latest_gc_info`. [GH-6791]
-
-* ObjectSpace
-
- * `ObjectSpace.dump_all` dump shapes as well. [GH-6868]
-
-## Stdlib updates
-
-* Bundler
-
- * Bundler now uses [PubGrub] resolver instead of [Molinillo] for performance improvement.
- * Add --ext=rust support to bundle gem for creating simple gems with Rust extensions.
- [[GH-rubygems-6149]]
- * Make cloning git repos faster [[GH-rubygems-4475]]
-
-* RubyGems
-
- * Add mswin support for cargo builder. [[GH-rubygems-6167]]
-
-* CGI
-
- * `CGI.escapeURIComponent` and `CGI.unescapeURIComponent` are added.
- [[Feature #18822]]
-
-* Coverage
-
- * `Coverage.setup` now accepts `eval: true`. By this, `eval` and related methods are
- able to generate code coverage. [[Feature #19008]]
-
- * `Coverage.supported?(mode)` enables detection of what coverage modes are
- supported. [[Feature #19026]]
-
-* Date
-
- * Added `Date#deconstruct_keys` and `DateTime#deconstruct_keys` same as [[Feature #19071]]
-
-* ERB
-
- * `ERB::Util.html_escape` is made faster than `CGI.escapeHTML`.
- * It no longer allocates a String object when no character needs to be escaped.
- * It skips calling `#to_s` method when an argument is already a String.
- * `ERB::Escape.html_escape` is added as an alias to `ERB::Util.html_escape`,
- which has not been monkey-patched by Rails.
- * `ERB::Util.url_encode` is made faster using `CGI.escapeURIComponent`.
- * `-S` option is removed from `erb` command.
-
-* FileUtils
-
- * Add FileUtils.ln_sr method and `relative:` option to FileUtils.ln_s.
- [[Feature #18925]]
-
-* IRB
-
- * debug.gem integration commands have been added: `debug`, `break`, `catch`,
- `next`, `delete`, `step`, `continue`, `finish`, `backtrace`, `info`
- * They work even if you don't have `gem "debug"` in your Gemfile.
- * See also: [What's new in Ruby 3.2's IRB?](https://st0012.dev/whats-new-in-ruby-3-2-irb)
- * More Pry-like commands and features have been added.
- * `edit` and `show_cmds` (like Pry's `help`) are added.
- * `ls` takes `-g` or `-G` option to filter out outputs.
- * `show_source` is aliased from `$` and accepts unquoted inputs.
- * `whereami` is aliased from `@`.
-
-* Net::Protocol
-
- * Improve `Net::BufferedIO` performance. [[GH-net-protocol-14]]
-
-* Pathname
-
- * Added `Pathname#lutime`. [[GH-pathname-20]]
-
-* Socket
-
- * Added the following constants for supported platforms.
- * `SO_INCOMING_CPU`
- * `SO_INCOMING_NAPI_ID`
- * `SO_RTABLE`
- * `SO_SETFIB`
- * `SO_USER_COOKIE`
- * `TCP_KEEPALIVE`
- * `TCP_CONNECTION_INFO`
-
-* SyntaxSuggest
-
- * The feature of `syntax_suggest` formerly `dead_end` is integrated in Ruby.
- [[Feature #18159]]
-
-* UNIXSocket
-
- * Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
- support for File.socket? and File::Stat#socket? where possible.
- [[Feature #19135]]
-
-* The following default gems are updated.
-
- * RubyGems 3.4.1
- * abbrev 0.1.1
- * benchmark 0.2.1
- * bigdecimal 3.1.3
- * bundler 2.4.1
- * cgi 0.3.6
- * csv 3.2.6
- * date 3.3.3
- * delegate 0.3.0
- * did_you_mean 1.6.3
- * digest 3.1.1
- * drb 2.1.1
- * english 0.7.2
- * erb 4.0.2
- * error_highlight 0.5.1
- * etc 1.4.2
- * fcntl 1.0.2
- * fiddle 1.1.1
- * fileutils 1.7.0
- * forwardable 1.3.3
- * getoptlong 0.2.0
- * io-console 0.6.0
- * io-nonblock 0.2.0
- * io-wait 0.3.0
- * ipaddr 1.2.5
- * irb 1.6.2
- * json 2.6.3
- * logger 1.5.3
- * mutex_m 0.1.2
- * net-http 0.3.2
- * net-protocol 0.2.1
- * nkf 0.1.2
- * open-uri 0.3.0
- * open3 0.1.2
- * openssl 3.1.0
- * optparse 0.3.1
- * ostruct 0.5.5
- * pathname 0.2.1
- * pp 0.4.0
- * pstore 0.1.2
- * psych 5.0.1
- * racc 1.6.2
- * rdoc 6.5.0
- * readline-ext 0.1.5
- * reline 0.3.2
- * resolv 0.2.2
- * resolv-replace 0.1.1
- * securerandom 0.2.2
- * set 1.0.3
- * stringio 3.0.4
- * strscan 3.0.5
- * syntax_suggest 1.0.2
- * syslog 0.1.1
- * tempfile 0.1.3
- * time 0.2.1
- * timeout 0.3.1
- * tmpdir 0.1.3
- * tsort 0.1.1
- * un 0.2.1
- * uri 0.12.0
- * weakref 0.1.2
- * win32ole 1.8.9
- * yaml 0.2.1
- * zlib 3.0.0
-
-* The following bundled gems are updated.
-
- * minitest 5.16.3
- * power_assert 2.0.3
- * test-unit 3.5.7
- * net-ftp 0.2.0
- * net-imap 0.3.4
- * net-pop 0.1.2
- * net-smtp 0.3.3
- * rbs 2.8.2
- * typeprof 0.21.3
- * debug 1.7.1
-
-See GitHub releases like [GitHub Releases of Logger](https://github.com/ruby/logger/releases) or changelog for details of the default gems or bundled gems.
-
-## Supported platforms
-
-* WebAssembly/WASI is added. See [wasm/README.md] and [ruby.wasm] for more details. [[Feature #18462]]
-
-## Compatibility issues
-
-* `String#to_c` currently treat a sequence of underscores as an end of Complex
- string. [[Bug #19087]]
-
-* Now `ENV.clone` raises `TypeError` as well as `ENV.dup` [[Bug #17767]]
-
-### Removed constants
-
-The following deprecated constants are removed.
-
-* `Fixnum` and `Bignum` [[Feature #12005]]
-* `Random::DEFAULT` [[Feature #17351]]
-* `Struct::Group`
-* `Struct::Passwd`
-
-### Removed methods
-
-The following deprecated methods are removed.
-
-* `Dir.exists?` [[Feature #17391]]
-* `File.exists?` [[Feature #17391]]
-* `Kernel#=~` [[Feature #15231]]
-* `Kernel#taint`, `Kernel#untaint`, `Kernel#tainted?`
- [[Feature #16131]]
-* `Kernel#trust`, `Kernel#untrust`, `Kernel#untrusted?`
- [[Feature #16131]]
-* `Method#public?`, `Method#private?`, `Method#protected?`,
- `UnboundMethod#public?`, `UnboundMethod#private?`, `UnboundMethod#protected?`
- [[Bug #18729]] [[Bug #18751]] [[Bug #18435]]
-
-### Source code incompatibility of extension libraries
-
-* Extension libraries provide PRNG, subclasses of Random, need updates.
- See [PRNG update] below for more information. [[Bug #19100]]
-
-### Error printer
-
-* Ruby no longer escapes control characters and backslashes in an
- error message. [[Feature #18367]]
-
-### Constant lookup when defining a class/module
-
-* When defining a class/module directly under the Object class by class/module
- statement, if there is already a class/module defined by `Module#include`
- with the same name, the statement was handled as "open class" in Ruby 3.1 or before.
- Since Ruby 3.2, a new class is defined instead. [[Feature #18832]]
-
-## Stdlib compatibility issues
-
-* Psych no longer bundles libyaml sources.
- And also Fiddle no longer bundles libffi sources.
- Users need to install the libyaml/libffi library themselves via the package
- manager like apt, yum, brew, etc.
-
- Psych and fiddle supported the static build with specific version of libyaml
- and libffi sources. You can build psych with libyaml-0.2.5 like this.
-
- ```bash
- $ ./configure --with-libyaml-source-dir=/path/to/libyaml-0.2.5
- ```
-
- And you can build fiddle with libffi-3.4.4 like this.
-
- ```bash
- $ ./configure --with-libffi-source-dir=/path/to/libffi-3.4.4
- ```
-
- [[Feature #18571]]
-
-* Check cookie name/path/domain characters in `CGI::Cookie`. [[CVE-2021-33621]]
-
-* `URI.parse` return empty string in host instead of nil. [[sec-156615]]
-
-## C API updates
-
-### Updated C APIs
-
-The following APIs are updated.
-
-* PRNG update
-
- `rb_random_interface_t` in ruby/random.h updated and versioned.
- Extension libraries which use this interface and built for older
- versions need to rebuild with adding `init_int32` function.
-
-### Added C APIs
-
-* `VALUE rb_hash_new_capa(long capa)` was added to created hashes with the desired capacity.
-* `rb_internal_thread_add_event_hook` and `rb_internal_thread_add_event_hook` were added to instrument threads scheduling.
- The following events are available:
- * `RUBY_INTERNAL_THREAD_EVENT_STARTED`
- * `RUBY_INTERNAL_THREAD_EVENT_READY`
- * `RUBY_INTERNAL_THREAD_EVENT_RESUMED`
- * `RUBY_INTERNAL_THREAD_EVENT_SUSPENDED`
- * `RUBY_INTERNAL_THREAD_EVENT_EXITED`
-* `rb_debug_inspector_current_depth` and `rb_debug_inspector_frame_depth` are added for debuggers.
-
-### Removed C APIs
-
-The following deprecated APIs are removed.
-
-* `rb_cData` variable.
-* "taintedness" and "trustedness" functions. [[Feature #16131]]
-
-## Implementation improvements
-
-* Fixed several race conditions in Kernel#autoload. [[Bug #18782]]
-* Cache invalidation for expressions referencing constants is now
- more fine-grained. `RubyVM.stat(:global_constant_state)` was
- removed because it was closely tied to the previous caching scheme
- where setting any constant invalidates all caches in the system.
- New keys, `:constant_cache_invalidations` and `:constant_cache_misses`,
- were introduced to help with use cases for `:global_constant_state`.
- [[Feature #18589]]
-* The cache-based optimization for Regexp matching is introduced.
- [[Feature #19104]]
-* [Variable Width Allocation](https://shopify.engineering/ruby-variable-width-allocation)
- is now enabled by default. [[Feature #18239]]
-* Added a new instance variable caching mechanism, called object shapes, which
- improves inline cache hits for most objects and allows us to generate very
- efficient JIT code. Objects whose instance variables are defined in a
- consistent order will see the most performance benefits.
- [[Feature #18776]]
-* Speed up marking instruction sequences by using a bitmap to find "markable"
- objects. This change results in faster major collections.
- [[Feature #18875]]
-
-## JIT
-
-### YJIT
-
-* YJIT is no longer experimental
- * Has been tested on production workloads for over a year and proven to be quite stable.
-* YJIT now supports both x86-64 and arm64/aarch64 CPUs on Linux, MacOS, BSD and other UNIX platforms.
- * This release brings support for Mac M1/M2, AWS Graviton and Raspberry Pi 4.
-* Building YJIT now requires Rust 1.58.0+. [[Feature #18481]]
- * In order to ensure that CRuby is built with YJIT, please install `rustc` >= 1.58.0
- before running `./configure`
- * Please reach out to the YJIT team should you run into any issues.
-* Physical memory for JIT code is lazily allocated. Unlike Ruby 3.1,
- the RSS of a Ruby process is minimized because virtual memory pages
- allocated by `--yjit-exec-mem-size` will not be mapped to physical
- memory pages until actually utilized by JIT code.
-* Introduce Code GC that frees all code pages when the memory consumption
- by JIT code reaches `--yjit-exec-mem-size`.
- * `RubyVM::YJIT.runtime_stats` returns Code GC metrics in addition to
- existing `inline_code_size` and `outlined_code_size` keys:
- `code_gc_count`, `live_page_count`, `freed_page_count`, and `freed_code_size`.
-* Most of the statistics produced by `RubyVM::YJIT.runtime_stats` are now available in release builds.
- * Simply run ruby with `--yjit-stats` to compute and dump stats (incurs some run-time overhead).
-* YJIT is now optimized to take advantage of object shapes. [[Feature #18776]]
-* Take advantage of finer-grained constant invalidation to invalidate less code when defining new constants. [[Feature #18589]]
-* The default `--yjit-exec-mem-size` is changed to 64 (MiB).
-* The default `--yjit-call-threshold` is changed to 30.
-
-### MJIT
-
-* The MJIT compiler is re-implemented in Ruby as `ruby_vm/mjit/compiler`.
-* MJIT compiler is executed under a forked Ruby process instead of
- doing it in a native thread called MJIT worker. [[Feature #18968]]
- * As a result, Microsoft Visual Studio (MSWIN) is no longer supported.
-* MinGW is no longer supported. [[Feature #18824]]
-* Rename `--mjit-min-calls` to `--mjit-call-threshold`.
-* Change default `--mjit-max-cache` back from 10000 to 100.
-
-[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
-[Feature #12084]: https://bugs.ruby-lang.org/issues/12084
-[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
-[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
-[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
-[Feature #14332]: https://bugs.ruby-lang.org/issues/14332
-[Feature #15231]: https://bugs.ruby-lang.org/issues/15231
-[Feature #15357]: https://bugs.ruby-lang.org/issues/15357
-[Bug #15928]: https://bugs.ruby-lang.org/issues/15928
-[Feature #16122]: https://bugs.ruby-lang.org/issues/16122
-[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
-[Bug #16466]: https://bugs.ruby-lang.org/issues/16466
-[Feature #16663]: https://bugs.ruby-lang.org/issues/16663
-[Feature #16806]: https://bugs.ruby-lang.org/issues/16806
-[Bug #16889]: https://bugs.ruby-lang.org/issues/16889
-[Bug #16908]: https://bugs.ruby-lang.org/issues/16908
-[Feature #16989]: https://bugs.ruby-lang.org/issues/16989
-[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
-[Feature #17391]: https://bugs.ruby-lang.org/issues/17391
-[Bug #17545]: https://bugs.ruby-lang.org/issues/17545
-[Bug #17767]: https://bugs.ruby-lang.org/issues/17767
-[Feature #17837]: https://bugs.ruby-lang.org/issues/17837
-[Feature #17881]: https://bugs.ruby-lang.org/issues/17881
-[Feature #18033]: https://bugs.ruby-lang.org/issues/18033
-[Feature #18159]: https://bugs.ruby-lang.org/issues/18159
-[Feature #18239]: https://bugs.ruby-lang.org/issues/18239#note-17
-[Feature #18351]: https://bugs.ruby-lang.org/issues/18351
-[Feature #18367]: https://bugs.ruby-lang.org/issues/18367
-[Bug #18435]: https://bugs.ruby-lang.org/issues/18435
-[Feature #18462]: https://bugs.ruby-lang.org/issues/18462
-[Feature #18481]: https://bugs.ruby-lang.org/issues/18481
-[Bug #18487]: https://bugs.ruby-lang.org/issues/18487
-[Feature #18564]: https://bugs.ruby-lang.org/issues/18564
-[Feature #18571]: https://bugs.ruby-lang.org/issues/18571
-[Feature #18585]: https://bugs.ruby-lang.org/issues/18585
-[Feature #18589]: https://bugs.ruby-lang.org/issues/18589
-[Feature #18595]: https://bugs.ruby-lang.org/issues/18595
-[Feature #18598]: https://bugs.ruby-lang.org/issues/18598
-[Bug #18625]: https://bugs.ruby-lang.org/issues/18625
-[Feature #18630]: https://bugs.ruby-lang.org/issues/18630
-[Bug #18633]: https://bugs.ruby-lang.org/issues/18633
-[Feature #18639]: https://bugs.ruby-lang.org/issues/18639
-[Feature #18685]: https://bugs.ruby-lang.org/issues/18685
-[Bug #18729]: https://bugs.ruby-lang.org/issues/18729
-[Bug #18751]: https://bugs.ruby-lang.org/issues/18751
-[Feature #18774]: https://bugs.ruby-lang.org/issues/18774
-[Feature #18776]: https://bugs.ruby-lang.org/issues/18776
-[Bug #18782]: https://bugs.ruby-lang.org/issues/18782
-[Feature #18788]: https://bugs.ruby-lang.org/issues/18788
-[Feature #18798]: https://bugs.ruby-lang.org/issues/18798
-[Feature #18809]: https://bugs.ruby-lang.org/issues/18809
-[Feature #18821]: https://bugs.ruby-lang.org/issues/18821
-[Feature #18822]: https://bugs.ruby-lang.org/issues/18822
-[Feature #18824]: https://bugs.ruby-lang.org/issues/18824
-[Feature #18832]: https://bugs.ruby-lang.org/issues/18832
-[Feature #18875]: https://bugs.ruby-lang.org/issues/18875
-[Feature #18925]: https://bugs.ruby-lang.org/issues/18925
-[Feature #18944]: https://bugs.ruby-lang.org/issues/18944
-[Feature #18949]: https://bugs.ruby-lang.org/issues/18949
-[Feature #18968]: https://bugs.ruby-lang.org/issues/18968
-[Feature #19008]: https://bugs.ruby-lang.org/issues/19008
-[Feature #19013]: https://bugs.ruby-lang.org/issues/19013
-[Feature #19026]: https://bugs.ruby-lang.org/issues/19026
-[Feature #19036]: https://bugs.ruby-lang.org/issues/19036
-[Feature #19060]: https://bugs.ruby-lang.org/issues/19060
-[Feature #19070]: https://bugs.ruby-lang.org/issues/19070
-[Feature #19071]: https://bugs.ruby-lang.org/issues/19071
-[Feature #19078]: https://bugs.ruby-lang.org/issues/19078
-[Bug #19087]: https://bugs.ruby-lang.org/issues/19087
-[Bug #19100]: https://bugs.ruby-lang.org/issues/19100
-[Feature #19104]: https://bugs.ruby-lang.org/issues/19104
-[Feature #19135]: https://bugs.ruby-lang.org/issues/19135
-[Feature #19138]: https://bugs.ruby-lang.org/issues/19138
-[Feature #19194]: https://bugs.ruby-lang.org/issues/19194
-[Molinillo]: https://github.com/CocoaPods/Molinillo
-[PubGrub]: https://github.com/jhawthorn/pub_grub
-[GH-net-protocol-14]: https://github.com/ruby/net-protocol/pull/14
-[GH-pathname-20]: https://github.com/ruby/pathname/pull/20
-[GH-6791]: https://github.com/ruby/ruby/pull/6791
-[GH-6868]: https://github.com/ruby/ruby/pull/6868
-[GH-rubygems-4475]: https://github.com/rubygems/rubygems/pull/4475
-[GH-rubygems-6149]: https://github.com/rubygems/rubygems/pull/6149
-[GH-rubygems-6167]: https://github.com/rubygems/rubygems/pull/6167
-[sec-156615]: https://hackerone.com/reports/156615
-[CVE-2021-33621]: https://www.ruby-lang.org/en/news/2022/11/22/http-response-splitting-in-cgi-cve-2021-33621/
-[wasm/README.md]: https://github.com/ruby/ruby/blob/master/wasm/README.md
-[ruby.wasm]: https://github.com/ruby/ruby.wasm
diff --git a/doc/_regexp.rdoc b/doc/_regexp.rdoc
deleted file mode 100644
index 7b71eee984..0000000000
--- a/doc/_regexp.rdoc
+++ /dev/null
@@ -1,1276 +0,0 @@
-A {regular expression}[https://en.wikipedia.org/wiki/Regular_expression]
-(also called a _regexp_) is a <i>match pattern</i> (also simply called a _pattern_).
-
-A common notation for a regexp uses enclosing slash characters:
-
- /foo/
-
-A regexp may be applied to a <i>target string</i>;
-The part of the string (if any) that matches the pattern is called a _match_,
-and may be said <i>to match</i>:
-
- re = /red/
- re.match?('redirect') # => true # Match at beginning of target.
- re.match?('bored') # => true # Match at end of target.
- re.match?('credit') # => true # Match within target.
- re.match?('foo') # => false # No match.
-
-== \Regexp Uses
-
-A regexp may be used:
-
-- To extract substrings based on a given pattern:
-
- re = /foo/ # => /foo/
- re.match('food') # => #<MatchData "foo">
- re.match('good') # => nil
-
- See sections {Method match}[rdoc-ref:Regexp@Method+match]
- and {Operator =~}[rdoc-ref:Regexp@Operator+-3D~].
-
-- To determine whether a string matches a given pattern:
-
- re.match?('food') # => true
- re.match?('good') # => false
-
- See section {Method match?}[rdoc-ref:Regexp@Method+match-3F].
-
-- As an argument for calls to certain methods in other classes and modules;
- most such methods accept an argument that may be either a string
- or the (much more powerful) regexp.
-
- See {Regexp Methods}[rdoc-ref:regexp/methods.rdoc].
-
-== \Regexp Objects
-
-A regexp object has:
-
-- A source; see {Sources}[rdoc-ref:Regexp@Sources].
-
-- Several modes; see {Modes}[rdoc-ref:Regexp@Modes].
-
-- A timeout; see {Timeouts}[rdoc-ref:Regexp@Timeouts].
-
-- An encoding; see {Encodings}[rdoc-ref:Regexp@Encodings].
-
-== Creating a \Regexp
-
-A regular expression may be created with:
-
-- A regexp literal using slash characters
- (see {Regexp Literals}[rdoc-ref:syntax/literals.rdoc@Regexp+Literals]):
-
- # This is a very common usage.
- /foo/ # => /foo/
-
-- A <tt>%r</tt> regexp literal
- (see {%r: Regexp Literals}[rdoc-ref:syntax/literals.rdoc@25r-3A+Regexp+Literals]):
-
- # Same delimiter character at beginning and end;
- # useful for avoiding escaping characters
- %r/name\/value pair/ # => /name\/value pair/
- %r:name/value pair: # => /name\/value pair/
- %r|name/value pair| # => /name\/value pair/
-
- # Certain "paired" characters can be delimiters.
- %r[foo] # => /foo/
- %r{foo} # => /foo/
- %r(foo) # => /foo/
- %r<foo> # => /foo/
-
-- \Method Regexp.new.
-
-== \Method <tt>match</tt>
-
-Each of the methods Regexp#match, String#match, and Symbol#match
-returns a MatchData object if a match was found, +nil+ otherwise;
-each also sets {global variables}[rdoc-ref:Regexp@Global+Variables]:
-
- 'food'.match(/foo/) # => #<MatchData "foo">
- 'food'.match(/bar/) # => nil
-
-== Operator <tt>=~</tt>
-
-Each of the operators Regexp#=~, String#=~, and Symbol#=~
-returns an integer offset if a match was found, +nil+ otherwise;
-each also sets {global variables}[rdoc-ref:Regexp@Global+Variables]:
-
- /bar/ =~ 'foo bar' # => 4
- 'foo bar' =~ /bar/ # => 4
- /baz/ =~ 'foo bar' # => nil
-
-== \Method <tt>match?</tt>
-
-Each of the methods Regexp#match?, String#match?, and Symbol#match?
-returns +true+ if a match was found, +false+ otherwise;
-none sets {global variables}[rdoc-ref:Regexp@Global+Variables]:
-
- 'food'.match?(/foo/) # => true
- 'food'.match?(/bar/) # => false
-
-== Global Variables
-
-Certain regexp-oriented methods assign values to global variables:
-
-- <tt>#match</tt>: see {Method match}[rdoc-ref:Regexp@Method+match].
-- <tt>#=~</tt>: see {Operator =~}[rdoc-ref:Regexp@Operator+-3D~].
-
-The affected global variables are:
-
-- <tt>$~</tt>: Returns a MatchData object, or +nil+.
-- <tt>$&</tt>: Returns the matched part of the string, or +nil+.
-- <tt>$`</tt>: Returns the part of the string to the left of the match, or +nil+.
-- <tt>$'</tt>: Returns the part of the string to the right of the match, or +nil+.
-- <tt>$+</tt>: Returns the last group matched, or +nil+.
-- <tt>$1</tt>, <tt>$2</tt>, etc.: Returns the first, second, etc.,
- matched group, or +nil+.
- Note that <tt>$0</tt> is quite different;
- it returns the name of the currently executing program.
-
-Examples:
-
- # Matched string, but no matched groups.
- 'foo bar bar baz'.match('bar')
- $~ # => #<MatchData "bar">
- $& # => "bar"
- $` # => "foo "
- $' # => " bar baz"
- $+ # => nil
- $1 # => nil
-
- # Matched groups.
- /s(\w{2}).*(c)/.match('haystack')
- $~ # => #<MatchData "stac" 1:"ta" 2:"c">
- $& # => "stac"
- $` # => "hay"
- $' # => "k"
- $+ # => "c"
- $1 # => "ta"
- $2 # => "c"
- $3 # => nil
-
- # No match.
- 'foo'.match('bar')
- $~ # => nil
- $& # => nil
- $` # => nil
- $' # => nil
- $+ # => nil
- $1 # => nil
-
-Note that Regexp#match?, String#match?, and Symbol#match?
-do not set global variables.
-
-== Sources
-
-As seen above, the simplest regexp uses a literal expression as its source:
-
- re = /foo/ # => /foo/
- re.match('food') # => #<MatchData "foo">
- re.match('good') # => nil
-
-A rich collection of available _subexpressions_
-gives the regexp great power and flexibility:
-
-- {Special characters}[rdoc-ref:Regexp@Special+Characters]
-- {Source literals}[rdoc-ref:Regexp@Source+Literals]
-- {Character classes}[rdoc-ref:Regexp@Character+Classes]
-- {Shorthand character classes}[rdoc-ref:Regexp@Shorthand+Character+Classes]
-- {Anchors}[rdoc-ref:Regexp@Anchors]
-- {Alternation}[rdoc-ref:Regexp@Alternation]
-- {Quantifiers}[rdoc-ref:Regexp@Quantifiers]
-- {Groups and captures}[rdoc-ref:Regexp@Groups+and+Captures]
-- {Unicode}[rdoc-ref:Regexp@Unicode]
-- {POSIX Bracket Expressions}[rdoc-ref:Regexp@POSIX+Bracket+Expressions]
-- {Comments}[rdoc-ref:Regexp@Comments]
-
-=== Special Characters
-
-\Regexp special characters, called _metacharacters_,
-have special meanings in certain contexts;
-depending on the context, these are sometimes metacharacters:
-
- . ? - + * ^ \ | $ ( ) [ ] { }
-
-To match a metacharacter literally, backslash-escape it:
-
- # Matches one or more 'o' characters.
- /o+/.match('foo') # => #<MatchData "oo">
- # Would match 'o+'.
- /o\+/.match('foo') # => nil
-
-To match a backslash literally, backslash-escape it:
-
- /\./.match('\.') # => #<MatchData ".">
- /\\./.match('\.') # => #<MatchData "\\.">
-
-Method Regexp.escape returns an escaped string:
-
- Regexp.escape('.?-+*^\|$()[]{}')
- # => "\\.\\?\\-\\+\\*\\^\\\\\\|\\$\\(\\)\\[\\]\\{\\}"
-
-=== Source Literals
-
-The source literal largely behaves like a double-quoted string;
-see {String Literals}[rdoc-ref:syntax/literals.rdoc@String+Literals].
-
-In particular, a source literal may contain interpolated expressions:
-
- s = 'foo' # => "foo"
- /#{s}/ # => /foo/
- /#{s.capitalize}/ # => /Foo/
- /#{2 + 2}/ # => /4/
-
-There are differences between an ordinary string literal and a source literal;
-see {Shorthand Character Classes}[rdoc-ref:Regexp@Shorthand+Character+Classes].
-
-- <tt>\s</tt> in an ordinary string literal is equivalent to a space character;
- in a source literal, it's shorthand for matching a whitespace character.
-- In an ordinary string literal, these are (needlessly) escaped characters;
- in a source literal, they are shorthands for various matching characters:
-
- \w \W \d \D \h \H \S \R
-
-=== Character Classes
-
-A <i>character class</i> is delimited by square brackets;
-it specifies that certain characters match at a given point in the target string:
-
- # This character class will match any vowel.
- re = /B[aeiou]rd/
- re.match('Bird') # => #<MatchData "Bird">
- re.match('Bard') # => #<MatchData "Bard">
- re.match('Byrd') # => nil
-
-A character class may contain hyphen characters to specify ranges of characters:
-
- # These regexps have the same effect.
- /[abcdef]/.match('foo') # => #<MatchData "f">
- /[a-f]/.match('foo') # => #<MatchData "f">
- /[a-cd-f]/.match('foo') # => #<MatchData "f">
-
-When the first character of a character class is a caret (<tt>^</tt>),
-the sense of the class is inverted: it matches any character _except_ those specified.
-
- /[^a-eg-z]/.match('f') # => #<MatchData "f">
-
-A character class may contain another character class.
-By itself this isn't useful because <tt>[a-z[0-9]]</tt>
-describes the same set as <tt>[a-z0-9]</tt>.
-
-However, character classes also support the <tt>&&</tt> operator,
-which performs set intersection on its arguments.
-The two can be combined as follows:
-
- /[a-w&&[^c-g]z]/ # ([a-w] AND ([^c-g] OR z))
-
-This is equivalent to:
-
- /[abh-w]/
-
-=== Shorthand Character Classes
-
-Each of the following metacharacters serves as a shorthand
-for a character class:
-
-- <tt>/./</tt>: Matches any character except a newline:
-
- /./.match('foo') # => #<MatchData "f">
- /./.match("\n") # => nil
-
-- <tt>/./m</tt>: Matches any character, including a newline;
- see {Multiline Mode}[rdoc-ref:Regexp@Multiline+Mode]:
-
- /./m.match("\n") # => #<MatchData "\n">
-
-- <tt>/\w/</tt>: Matches a word character: equivalent to <tt>[a-zA-Z0-9_]</tt>:
-
- /\w/.match(' foo') # => #<MatchData "f">
- /\w/.match(' _') # => #<MatchData "_">
- /\w/.match(' ') # => nil
-
-- <tt>/\W/</tt>: Matches a non-word character: equivalent to <tt>[^a-zA-Z0-9_]</tt>:
-
- /\W/.match(' ') # => #<MatchData " ">
- /\W/.match('_') # => nil
-
-- <tt>/\d/</tt>: Matches a digit character: equivalent to <tt>[0-9]</tt>:
-
- /\d/.match('THX1138') # => #<MatchData "1">
- /\d/.match('foo') # => nil
-
-- <tt>/\D/</tt>: Matches a non-digit character: equivalent to <tt>[^0-9]</tt>:
-
- /\D/.match('123Jump!') # => #<MatchData "J">
- /\D/.match('123') # => nil
-
-- <tt>/\h/</tt>: Matches a hexdigit character: equivalent to <tt>[0-9a-fA-F]</tt>:
-
- /\h/.match('xyz fedcba9876543210') # => #<MatchData "f">
- /\h/.match('xyz') # => nil
-
-- <tt>/\H/</tt>: Matches a non-hexdigit character: equivalent to <tt>[^0-9a-fA-F]</tt>:
-
- /\H/.match('fedcba9876543210xyz') # => #<MatchData "x">
- /\H/.match('fedcba9876543210') # => nil
-
-- <tt>/\s/</tt>: Matches a whitespace character: equivalent to <tt>/[ \t\r\n\f\v]/</tt>:
-
- /\s/.match('foo bar') # => #<MatchData " ">
- /\s/.match('foo') # => nil
-
-- <tt>/\S/</tt>: Matches a non-whitespace character: equivalent to <tt>/[^ \t\r\n\f\v]/</tt>:
-
- /\S/.match(" \t\r\n\f\v foo") # => #<MatchData "f">
- /\S/.match(" \t\r\n\f\v") # => nil
-
-- <tt>/\R/</tt>: Matches a linebreak, platform-independently:
-
- /\R/.match("\r") # => #<MatchData "\r"> # Carriage return (CR)
- /\R/.match("\n") # => #<MatchData "\n"> # Newline (LF)
- /\R/.match("\f") # => #<MatchData "\f"> # Formfeed (FF)
- /\R/.match("\v") # => #<MatchData "\v"> # Vertical tab (VT)
- /\R/.match("\r\n") # => #<MatchData "\r\n"> # CRLF
- /\R/.match("\u0085") # => #<MatchData "\u0085"> # Next line (NEL)
- /\R/.match("\u2028") # => #<MatchData "\u2028"> # Line separator (LSEP)
- /\R/.match("\u2029") # => #<MatchData "\u2029"> # Paragraph separator (PSEP)
-
-=== Anchors
-
-An anchor is a metasequence that matches a zero-width position between
-characters in the target string.
-
-For a subexpression with no anchor,
-matching may begin anywhere in the target string:
-
- /real/.match('surrealist') # => #<MatchData "real">
-
-For a subexpression with an anchor,
-matching must begin at the matched anchor.
-
-==== Boundary Anchors
-
-Each of these anchors matches a boundary:
-
-- <tt>^</tt>: Matches the beginning of a line:
-
- /^bar/.match("foo\nbar") # => #<MatchData "bar">
- /^ar/.match("foo\nbar") # => nil
-
-- <tt>$</tt>: Matches the end of a line:
-
- /bar$/.match("foo\nbar") # => #<MatchData "bar">
- /ba$/.match("foo\nbar") # => nil
-
-- <tt>\A</tt>: Matches the beginning of the string:
-
- /\Afoo/.match('foo bar') # => #<MatchData "foo">
- /\Afoo/.match(' foo bar') # => nil
-
-- <tt>\Z</tt>: Matches the end of the string;
- if string ends with a single newline,
- it matches just before the ending newline:
-
- /foo\Z/.match('bar foo') # => #<MatchData "foo">
- /foo\Z/.match('foo bar') # => nil
- /foo\Z/.match("bar foo\n") # => #<MatchData "foo">
- /foo\Z/.match("bar foo\n\n") # => nil
-
-- <tt>\z</tt>: Matches the end of the string:
-
- /foo\z/.match('bar foo') # => #<MatchData "foo">
- /foo\z/.match('foo bar') # => nil
- /foo\z/.match("bar foo\n") # => nil
-
-- <tt>\b</tt>: Matches word boundary when not inside brackets;
- matches backspace (<tt>"0x08"</tt>) when inside brackets:
-
- /foo\b/.match('foo bar') # => #<MatchData "foo">
- /foo\b/.match('foobar') # => nil
-
-- <tt>\B</tt>: Matches non-word boundary:
-
- /foo\B/.match('foobar') # => #<MatchData "foo">
- /foo\B/.match('foo bar') # => nil
-
-- <tt>\G</tt>: Matches first matching position:
-
- In methods like String#gsub and String#scan, it changes on each iteration.
- It initially matches the beginning of subject, and in each following iteration it matches where the last match finished.
-
- " a b c".gsub(/ /, '_') # => "____a_b_c"
- " a b c".gsub(/\G /, '_') # => "____a b c"
-
- In methods like Regexp#match and String#match
- that take an optional offset, it matches where the search begins.
-
- "hello, world".match(/,/, 3) # => #<MatchData ",">
- "hello, world".match(/\G,/, 3) # => nil
-
-==== Lookaround Anchors
-
-Lookahead anchors:
-
-- <tt>(?=_pat_)</tt>: Positive lookahead assertion:
- ensures that the following characters match _pat_,
- but doesn't include those characters in the matched substring.
-
-- <tt>(?!_pat_)</tt>: Negative lookahead assertion:
- ensures that the following characters <i>do not</i> match _pat_,
- but doesn't include those characters in the matched substring.
-
-Lookbehind anchors:
-
-- <tt>(?<=_pat_)</tt>: Positive lookbehind assertion:
- ensures that the preceding characters match _pat_, but
- doesn't include those characters in the matched substring.
-
-- <tt>(?<!_pat_)</tt>: Negative lookbehind assertion:
- ensures that the preceding characters do not match
- _pat_, but doesn't include those characters in the matched substring.
-
-The pattern below uses positive lookahead and positive lookbehind to match
-text appearing in <tt><b></tt>...<tt></b></tt> tags
-without including the tags in the match:
-
- /(?<=<b>)\w+(?=<\/b>)/.match("Fortune favors the <b>bold</b>.")
- # => #<MatchData "bold">
-
-==== Match-Reset Anchor
-
-- <tt>\K</tt>: Match reset:
- the matched content preceding <tt>\K</tt> in the regexp is excluded from the result.
- For example, the following two regexps are almost equivalent:
-
- /ab\Kc/.match('abc') # => #<MatchData "c">
- /(?<=ab)c/.match('abc') # => #<MatchData "c">
-
- These match same string and <tt>$&</tt> equals <tt>'c'</tt>,
- while the matched position is different.
-
- As are the following two regexps:
-
- /(a)\K(b)\Kc/
- /(?<=(?<=(a))(b))c/
-
-=== Alternation
-
-The vertical bar metacharacter (<tt>|</tt>) may be used within parentheses
-to express alternation:
-two or more subexpressions any of which may match the target string.
-
-Two alternatives:
-
- re = /(a|b)/
- re.match('foo') # => nil
- re.match('bar') # => #<MatchData "b" 1:"b">
-
-Four alternatives:
-
- re = /(a|b|c|d)/
- re.match('shazam') # => #<MatchData "a" 1:"a">
- re.match('cold') # => #<MatchData "c" 1:"c">
-
-Each alternative is a subexpression, and may be composed of other subexpressions:
-
- re = /([a-c]|[x-z])/
- re.match('bar') # => #<MatchData "b" 1:"b">
- re.match('ooz') # => #<MatchData "z" 1:"z">
-
-\Method Regexp.union provides a convenient way to construct
-a regexp with alternatives.
-
-=== Quantifiers
-
-A simple regexp matches one character:
-
- /\w/.match('Hello') # => #<MatchData "H">
-
-An added _quantifier_ specifies how many matches are required or allowed:
-
-- <tt>*</tt> - Matches zero or more times:
-
- /\w*/.match('')
- # => #<MatchData "">
- /\w*/.match('x')
- # => #<MatchData "x">
- /\w*/.match('xyz')
- # => #<MatchData "yz">
-
-- <tt>+</tt> - Matches one or more times:
-
- /\w+/.match('') # => nil
- /\w+/.match('x') # => #<MatchData "x">
- /\w+/.match('xyz') # => #<MatchData "xyz">
-
-- <tt>?</tt> - Matches zero or one times:
-
- /\w?/.match('') # => #<MatchData "">
- /\w?/.match('x') # => #<MatchData "x">
- /\w?/.match('xyz') # => #<MatchData "x">
-
-- <tt>{</tt>_n_<tt>}</tt> - Matches exactly _n_ times:
-
- /\w{2}/.match('') # => nil
- /\w{2}/.match('x') # => nil
- /\w{2}/.match('xyz') # => #<MatchData "xy">
-
-- <tt>{</tt>_min_<tt>,}</tt> - Matches _min_ or more times:
-
- /\w{2,}/.match('') # => nil
- /\w{2,}/.match('x') # => nil
- /\w{2,}/.match('xy') # => #<MatchData "xy">
- /\w{2,}/.match('xyz') # => #<MatchData "xyz">
-
-- <tt>{,</tt>_max_<tt>}</tt> - Matches _max_ or fewer times:
-
- /\w{,2}/.match('') # => #<MatchData "">
- /\w{,2}/.match('x') # => #<MatchData "x">
- /\w{,2}/.match('xyz') # => #<MatchData "xy">
-
-- <tt>{</tt>_min_<tt>,</tt>_max_<tt>}</tt> -
- Matches at least _min_ times and at most _max_ times:
-
- /\w{1,2}/.match('') # => nil
- /\w{1,2}/.match('x') # => #<MatchData "x">
- /\w{1,2}/.match('xyz') # => #<MatchData "xy">
-
-==== Greedy, Lazy, or Possessive Matching
-
-Quantifier matching may be greedy, lazy, or possessive:
-
-- In _greedy_ matching, as many occurrences as possible are matched
- while still allowing the overall match to succeed.
- Greedy quantifiers: <tt>*</tt>, <tt>+</tt>, <tt>?</tt>,
- <tt>{min, max}</tt> and its variants.
-- In _lazy_ matching, the minimum number of occurrences are matched.
- Lazy quantifiers: <tt>*?</tt>, <tt>+?</tt>, <tt>??</tt>,
- <tt>{min, max}?</tt> and its variants.
-- In _possessive_ matching, once a match is found, there is no backtracking;
- that match is retained, even if it jeopardises the overall match.
- Possessive quantifiers: <tt>*+</tt>, <tt>++</tt>, <tt>?+</tt>.
- Note that <tt>{min, max}</tt> and its variants do _not_ support possessive matching.
-
-More:
-
-- About greedy and lazy matching, see
- {Choosing Minimal or Maximal Repetition}[https://doc.lagout.org/programmation/Regular%20Expressions/Regular%20Expressions%20Cookbook_%20Detailed%20Solutions%20in%20Eight%20Programming%20Languages%20%282nd%20ed.%29%20%5BGoyvaerts%20%26%20Levithan%202012-09-06%5D.pdf#tutorial-backtrack].
-- About possessive matching, see
- {Eliminate Needless Backtracking}[https://doc.lagout.org/programmation/Regular%20Expressions/Regular%20Expressions%20Cookbook_%20Detailed%20Solutions%20in%20Eight%20Programming%20Languages%20%282nd%20ed.%29%20%5BGoyvaerts%20%26%20Levithan%202012-09-06%5D.pdf#tutorial-backtrack].
-
-=== Groups and Captures
-
-A simple regexp has (at most) one match:
-
- re = /\d\d\d\d-\d\d-\d\d/
- re.match('1943-02-04') # => #<MatchData "1943-02-04">
- re.match('1943-02-04').size # => 1
- re.match('foo') # => nil
-
-Adding one or more pairs of parentheses, <tt>(_subexpression_)</tt>,
-defines _groups_, which may result in multiple matched substrings,
-called _captures_:
-
- re = /(\d\d\d\d)-(\d\d)-(\d\d)/
- re.match('1943-02-04') # => #<MatchData "1943-02-04" 1:"1943" 2:"02" 3:"04">
- re.match('1943-02-04').size # => 4
-
-The first capture is the entire matched string;
-the other captures are the matched substrings from the groups.
-
-A group may have a {quantifier}[rdoc-ref:Regexp@Quantifiers]:
-
- re = /July 4(th)?/
- re.match('July 4') # => #<MatchData "July 4" 1:nil>
- re.match('July 4th') # => #<MatchData "July 4th" 1:"th">
-
- re = /(foo)*/
- re.match('') # => #<MatchData "" 1:nil>
- re.match('foo') # => #<MatchData "foo" 1:"foo">
- re.match('foofoo') # => #<MatchData "foofoo" 1:"foo">
-
- re = /(foo)+/
- re.match('') # => nil
- re.match('foo') # => #<MatchData "foo" 1:"foo">
- re.match('foofoo') # => #<MatchData "foofoo" 1:"foo">
-
-The returned \MatchData object gives access to the matched substrings:
-
- re = /(\d\d\d\d)-(\d\d)-(\d\d)/
- md = re.match('1943-02-04')
- # => #<MatchData "1943-02-04" 1:"1943" 2:"02" 3:"04">
- md[0] # => "1943-02-04"
- md[1] # => "1943"
- md[2] # => "02"
- md[3] # => "04"
-
-==== Non-Capturing Groups
-
-A group may be made non-capturing;
-it is still a group (and, for example, can have a quantifier),
-but its matching substring is not included among the captures.
-
-A non-capturing group begins with <tt>?:</tt> (inside the parentheses):
-
- # Don't capture the year.
- re = /(?:\d\d\d\d)-(\d\d)-(\d\d)/
- md = re.match('1943-02-04') # => #<MatchData "1943-02-04" 1:"02" 2:"04">
-
-==== Backreferences
-
-A group match may also be referenced within the regexp itself;
-such a reference is called a +backreference+:
-
- /[csh](..) [csh]\1 in/.match('The cat sat in the hat')
- # => #<MatchData "cat sat in" 1:"at">
-
-This table shows how each subexpression in the regexp above
-matches a substring in the target string:
-
- | Subexpression in Regexp | Matching Substring in Target String |
- |---------------------------|-------------------------------------|
- | First '[csh]' | Character 'c' |
- | '(..)' | First substring 'at' |
- | First space ' ' | First space character ' ' |
- | Second '[csh]' | Character 's' |
- | '\1' (backreference 'at') | Second substring 'at' |
- | ' in' | Substring ' in' |
-
-A regexp may contain any number of groups:
-
-- For a large number of groups:
-
- - The ordinary <tt>\\_n_</tt> notation applies only for _n_ in range (1..9).
- - The <tt>MatchData[_n_]</tt> notation applies for any non-negative _n_.
-
-- <tt>\0</tt> is a special backreference, referring to the entire matched string;
- it may not be used within the regexp itself,
- but may be used outside it (for example, in a substitution method call):
-
- 'The cat sat in the hat'.gsub(/[csh]at/, '\0s')
- # => "The cats sats in the hats"
-
-==== Named Captures
-
-As seen above, a capture can be referred to by its number.
-A capture can also have a name,
-prefixed as <tt>?<_name_></tt> or <tt>?'_name_'</tt>,
-and the name (symbolized) may be used as an index in <tt>MatchData[]</tt>:
-
- md = /\$(?<dollars>\d+)\.(?'cents'\d+)/.match("$3.67")
- # => #<MatchData "$3.67" dollars:"3" cents:"67">
- md[:dollars] # => "3"
- md[:cents] # => "67"
- # The capture numbers are still valid.
- md[2] # => "67"
-
-When a regexp contains a named capture, there are no unnamed captures:
-
- /\$(?<dollars>\d+)\.(\d+)/.match("$3.67")
- # => #<MatchData "$3.67" dollars:"3">
-
-A named group may be backreferenced as <tt>\k<_name_></tt>:
-
- /(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
- # => #<MatchData "ototo" vowel:"o">
-
-When (and only when) a regexp contains named capture groups
-and appears before the <tt>=~</tt> operator,
-the captured substrings are assigned to local variables with corresponding names:
-
- /\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ '$3.67'
- dollars # => "3"
- cents # => "67"
-
-\Method Regexp#named_captures returns a hash of the capture names and substrings;
-method Regexp#names returns an array of the capture names.
-
-==== Atomic Grouping
-
-A group may be made _atomic_ with <tt>(?></tt>_subexpression_<tt>)</tt>.
-
-This causes the subexpression to be matched
-independently of the rest of the expression,
-so that the matched substring becomes fixed for the remainder of the match,
-unless the entire subexpression must be abandoned and subsequently revisited.
-
-In this way _subexpression_ is treated as a non-divisible whole.
-Atomic grouping is typically used to optimise patterns
-to prevent needless backtracking .
-
-Example (without atomic grouping):
-
- /".*"/.match('"Quote"') # => #<MatchData "\"Quote\"">
-
-Analysis:
-
-1. The leading subexpression <tt>"</tt> in the pattern matches the first character
- <tt>"</tt> in the target string.
-2. The next subexpression <tt>.*</tt> matches the next substring <tt>Quote“</tt>
- (including the trailing double-quote).
-3. Now there is nothing left in the target string to match
- the trailing subexpression <tt>"</tt> in the pattern;
- this would cause the overall match to fail.
-4. The matched substring is backtracked by one position: <tt>Quote</tt>.
-5. The final subexpression <tt>"</tt> now matches the final substring <tt>"</tt>,
- and the overall match succeeds.
-
-If subexpression <tt>.*</tt> is grouped atomically,
-the backtracking is disabled, and the overall match fails:
-
- /"(?>.*)"/.match('"Quote"') # => nil
-
-Atomic grouping can affect performance;
-see {Atomic Group}[https://www.regular-expressions.info/atomic.html].
-
-==== Subexpression Calls
-
-As seen above, a backreference number (<tt>\\_n_</tt>) or name (<tt>\k<_name_></tt>)
-gives access to a captured _substring_;
-the corresponding regexp _subexpression_ may also be accessed,
-via the number (<tt>\\g<i>n</i></tt>) or name (<tt>\g<_name_></tt>):
-
- /\A(?<paren>\(\g<paren>*\))*\z/.match('(())')
- # ^1
- # ^2
- # ^3
- # ^4
- # ^5
- # ^6
- # ^7
- # ^8
- # ^9
- # ^10
-
-The pattern:
-
-1. Matches at the beginning of the string, i.e. before the first character.
-2. Enters a named group +paren+.
-3. Matches the first character in the string, <tt>'('</tt>.
-4. Calls the +paren+ group again, i.e. recurses back to the second step.
-5. Re-enters the +paren+ group.
-6. Matches the second character in the string, <tt>'('</tt>.
-7. Attempts to call +paren+ a third time,
- but fails because doing so would prevent an overall successful match.
-8. Matches the third character in the string, <tt>')'</tt>;
- marks the end of the second recursive call
-9. Matches the fourth character in the string, <tt>')'</tt>.
-10. Matches the end of the string.
-
-See {Subexpression calls}[https://learnbyexample.github.io/Ruby_Regexp/groupings-and-backreferences.html?highlight=subexpression#subexpression-calls].
-
-==== Conditionals
-
-The conditional construct takes the form <tt>(?(_cond_)_yes_|_no_)</tt>, where:
-
-- _cond_ may be a capture number or name.
-- The match to be applied is _yes_ if _cond_ is captured;
- otherwise the match to be applied is _no_.
-- If not needed, <tt>|_no_</tt> may be omitted.
-
-Examples:
-
- re = /\A(foo)?(?(1)(T)|(F))\z/
- re.match('fooT') # => #<MatchData "fooT" 1:"foo" 2:"T" 3:nil>
- re.match('F') # => #<MatchData "F" 1:nil 2:nil 3:"F">
- re.match('fooF') # => nil
- re.match('T') # => nil
-
- re = /\A(?<xyzzy>foo)?(?(<xyzzy>)(T)|(F))\z/
- re.match('fooT') # => #<MatchData "fooT" xyzzy:"foo">
- re.match('F') # => #<MatchData "F" xyzzy:nil>
- re.match('fooF') # => nil
- re.match('T') # => nil
-
-
-==== Absence Operator
-
-The absence operator is a special group that matches anything which does _not_ match the contained subexpressions.
-
- /(?~real)/.match('surrealist') # => #<MatchData "surrea">
- /(?~real)ist/.match('surrealist') # => #<MatchData "ealist">
- /sur(?~real)ist/.match('surrealist') # => nil
-
-=== Unicode
-
-==== Unicode Properties
-
-The <tt>/\p{_property_name_}/</tt> construct (with lowercase +p+)
-matches characters using a Unicode property name,
-much like a character class;
-property +Alpha+ specifies alphabetic characters:
-
- /\p{Alpha}/.match('a') # => #<MatchData "a">
- /\p{Alpha}/.match('1') # => nil
-
-A property can be inverted
-by prefixing the name with a caret character (<tt>^</tt>):
-
- /\p{^Alpha}/.match('1') # => #<MatchData "1">
- /\p{^Alpha}/.match('a') # => nil
-
-Or by using <tt>\P</tt> (uppercase +P+):
-
- /\P{Alpha}/.match('1') # => #<MatchData "1">
- /\P{Alpha}/.match('a') # => nil
-
-See {Unicode Properties}[rdoc-ref:regexp/unicode_properties.rdoc]
-for regexps based on the numerous properties.
-
-Some commonly-used properties correspond to POSIX bracket expressions:
-
-- <tt>/\p{Alnum}/</tt>: Alphabetic and numeric character
-- <tt>/\p{Alpha}/</tt>: Alphabetic character
-- <tt>/\p{Blank}/</tt>: Space or tab
-- <tt>/\p{Cntrl}/</tt>: Control character
-- <tt>/\p{Digit}/</tt>: Digit
- characters, and similar)
-- <tt>/\p{Lower}/</tt>: Lowercase alphabetical character
-- <tt>/\p{Print}/</tt>: Like <tt>\p{Graph}</tt>, but includes the space character
-- <tt>/\p{Punct}/</tt>: Punctuation character
-- <tt>/\p{Space}/</tt>: Whitespace character (<tt>[:blank:]</tt>, newline,
- carriage return, etc.)
-- <tt>/\p{Upper}/</tt>: Uppercase alphabetical
-- <tt>/\p{XDigit}/</tt>: Digit allowed in a hexadecimal number (i.e., 0-9a-fA-F)
-
-These are also commonly used:
-
-- <tt>/\p{Emoji}/</tt>: Unicode emoji.
-- <tt>/\p{Graph}/</tt>: Non-blank character
- (excludes spaces, control characters, and similar).
-- <tt>/\p{Word}/</tt>: A member in one of these Unicode character
- categories (see below) or having one of these Unicode properties:
-
- - Unicode categories:
- - +Mark+ (+M+).
- - <tt>Decimal Number</tt> (+Nd+)
- - <tt>Connector Punctuation</tt> (+Pc+).
-
- - Unicode properties:
- - +Alpha+
- - <tt>Join_Control</tt>
-
-- <tt>/\p{ASCII}/</tt>: A character in the ASCII character set.
-- <tt>/\p{Any}/</tt>: Any Unicode character (including unassigned characters).
-- <tt>/\p{Assigned}/</tt>: An assigned character.
-
-==== Unicode Character Categories
-
-A Unicode character category name:
-
-- May be either its full name or its abbreviated name.
-- Is case-insensitive.
-- Treats a space, a hyphen, and an underscore as equivalent.
-
-Examples:
-
- /\p{lu}/ # => /\p{lu}/
- /\p{LU}/ # => /\p{LU}/
- /\p{Uppercase Letter}/ # => /\p{Uppercase Letter}/
- /\p{Uppercase_Letter}/ # => /\p{Uppercase_Letter}/
- /\p{UPPERCASE-LETTER}/ # => /\p{UPPERCASE-LETTER}/
-
-Below are the Unicode character category abbreviations and names.
-Enumerations of characters in each category are at the links.
-
-Letters:
-
-- +L+, +Letter+: +LC+, +Lm+, or +Lo+.
-- +LC+, +Cased_Letter+: +Ll+, +Lt+, or +Lu+.
-- {Lu, Lowercase_Letter}[https://www.compart.com/en/unicode/category/Ll].
-- {Lu, Modifier_Letter}[https://www.compart.com/en/unicode/category/Lm].
-- {Lu, Other_Letter}[https://www.compart.com/en/unicode/category/Lo].
-- {Lu, Titlecase_Letter}[https://www.compart.com/en/unicode/category/Lt].
-- {Lu, Uppercase_Letter}[https://www.compart.com/en/unicode/category/Lu].
-
-Marks:
-
-- +M+, +Mark+: +Mc+, +Me+, or +Mn+.
-- {Mc, Spacing_Mark}[https://www.compart.com/en/unicode/category/Mc].
-- {Me, Enclosing_Mark}[https://www.compart.com/en/unicode/category/Me].
-- {Mn, Nonapacing_Mark}[https://www.compart.com/en/unicode/category/Mn].
-
-Numbers:
-
-- +N+, +Number+: +Nd+, +Nl+, or +No+.
-- {Nd, Decimal_Number}[https://www.compart.com/en/unicode/category/Nd].
-- {Nl, Letter_Number}[https://www.compart.com/en/unicode/category/Nl].
-- {No, Other_Number}[https://www.compart.com/en/unicode/category/No].
-
-Punctation:
-
-- +P+, +Punctuation+: +Pc+, +Pd+, +Pe+, +Pf+, +Pi+, +Po+, or +Ps+.
-- {Pc, Connector_Punctuation}[https://www.compart.com/en/unicode/category/Pc].
-- {Pd, Dash_Punctuation}[https://www.compart.com/en/unicode/category/Pd].
-- {Pe, Close_Punctuation}[https://www.compart.com/en/unicode/category/Pe].
-- {Pf, Final_Punctuation}[https://www.compart.com/en/unicode/category/Pf].
-- {Pi, Initial_Punctuation}[https://www.compart.com/en/unicode/category/Pi].
-- {Po, Other_Punctuation}[https://www.compart.com/en/unicode/category/Po].
-- {Ps, Open_Punctuation}[https://www.compart.com/en/unicode/category/Ps].
-
-- +S+, +Symbol+: +Sc+, +Sk+, +Sm+, or +So+.
-- {Sc, Currency_Symbol}[https://www.compart.com/en/unicode/category/Sc].
-- {Sk, Modifier_Symbol}[https://www.compart.com/en/unicode/category/Sk].
-- {Sm, Math_Symbol}[https://www.compart.com/en/unicode/category/Sm].
-- {So, Other_Symbol}[https://www.compart.com/en/unicode/category/So].
-
-- +Z+, +Separator+: +Zl+, +Zp+, or +Zs+.
-- {Zl, Line_Separator}[https://www.compart.com/en/unicode/category/Zl].
-- {Zp, Paragraph_Separator}[https://www.compart.com/en/unicode/category/Zp].
-- {Zs, Space_Separator}[https://www.compart.com/en/unicode/category/Zs].
-
-- +C+, +Other+: +Cc+, +Cf+, +Cn+, +Co+, or +Cs+.
-- {Cc, Control}[https://www.compart.com/en/unicode/category/Cc].
-- {Cf, Format}[https://www.compart.com/en/unicode/category/Cf].
-- {Cn, Unassigned}[https://www.compart.com/en/unicode/category/Cn].
-- {Co, Private_Use}[https://www.compart.com/en/unicode/category/Co].
-- {Cs, Surrogate}[https://www.compart.com/en/unicode/category/Cs].
-
-==== Unicode Scripts and Blocks
-
-Among the Unicode properties are:
-
-- {Unicode scripts}[https://en.wikipedia.org/wiki/Script_(Unicode)];
- see {supported scripts}[https://www.unicode.org/standard/supported.html].
-- {Unicode blocks}[https://en.wikipedia.org/wiki/Unicode_block];
- see {supported blocks}[http://www.unicode.org/Public/UNIDATA/Blocks.txt].
-
-=== POSIX Bracket Expressions
-
-A POSIX <i>bracket expression</i> is also similar to a character class.
-These expressions provide a portable alternative to the above,
-with the added benefit of encompassing non-ASCII characters:
-
-- <tt>/\d/</tt> matches only ASCII decimal digits +0+ through +9+.
-- <tt>/[[:digit:]]/</tt> matches any character in the Unicode
- <tt>Decimal Number</tt> (+Nd+) category;
- see below.
-
-The POSIX bracket expressions:
-
-- <tt>/[[:digit:]]/</tt>: Matches a {Unicode digit}[https://www.compart.com/en/unicode/category/Nd]:
-
- /[[:digit:]]/.match('9') # => #<MatchData "9">
- /[[:digit:]]/.match("\u1fbf9") # => #<MatchData "9">
-
-- <tt>/[[:xdigit:]]/</tt>: Matches a digit allowed in a hexadecimal number;
- equivalent to <tt>[0-9a-fA-F]</tt>.
-
-- <tt>/[[:upper:]]/</tt>: Matches a {Unicode uppercase letter}[https://www.compart.com/en/unicode/category/Lu]:
-
- /[[:upper:]]/.match('A') # => #<MatchData "A">
- /[[:upper:]]/.match("\u00c6") # => #<MatchData "Æ">
-
-- <tt>/[[:lower:]]/</tt>: Matches a {Unicode lowercase letter}[https://www.compart.com/en/unicode/category/Ll]:
-
- /[[:lower:]]/.match('a') # => #<MatchData "a">
- /[[:lower:]]/.match("\u01fd") # => #<MatchData "ǽ">
-
-- <tt>/[[:alpha:]]/</tt>: Matches <tt>/[[:upper:]]/</tt> or <tt>/[[:lower:]]/</tt>.
-
-- <tt>/[[:alnum:]]/</tt>: Matches <tt>/[[:alpha:]]/</tt> or <tt>/[[:digit:]]/</tt>.
-
-- <tt>/[[:space:]]/</tt>: Matches {Unicode space character}[https://www.compart.com/en/unicode/category/Zs]:
-
- /[[:space:]]/.match(' ') # => #<MatchData " ">
- /[[:space:]]/.match("\u2005") # => #<MatchData " ">
-
-- <tt>/[[:blank:]]/</tt>: Matches <tt>/[[:space:]]/</tt> or tab character:
-
- /[[:blank:]]/.match(' ') # => #<MatchData " ">
- /[[:blank:]]/.match("\u2005") # => #<MatchData " ">
- /[[:blank:]]/.match("\t") # => #<MatchData "\t">
-
-- <tt>/[[:cntrl:]]/</tt>: Matches {Unicode control character}[https://www.compart.com/en/unicode/category/Cc]:
-
- /[[:cntrl:]]/.match("\u0000") # => #<MatchData "\u0000">
- /[[:cntrl:]]/.match("\u009f") # => #<MatchData "\u009F">
-
-- <tt>/[[:graph:]]/</tt>: Matches any character
- except <tt>/[[:space:]]/</tt> or <tt>/[[:cntrl:]]/</tt>.
-
-- <tt>/[[:print:]]/</tt>: Matches <tt>/[[:graph:]]/</tt> or space character.
-
-- <tt>/[[:punct:]]/</tt>: Matches any (Unicode punctuation character}[https://www.compart.com/en/unicode/category/Po]:
-
-Ruby also supports these (non-POSIX) bracket expressions:
-
-- <tt>/[[:ascii:]]/</tt>: Matches a character in the ASCII character set.
-- <tt>/[[:word:]]/</tt>: Matches a character in one of these Unicode character
- categories or having one of these Unicode properties:
-
- - Unicode categories:
- - +Mark+ (+M+).
- - <tt>Decimal Number</tt> (+Nd+)
- - <tt>Connector Punctuation</tt> (+Pc+).
-
- - Unicode properties:
- - +Alpha+
- - <tt>Join_Control</tt>
-
-=== Comments
-
-A comment may be included in a regexp pattern
-using the <tt>(?#</tt>_comment_<tt>)</tt> construct,
-where _comment_ is a substring that is to be ignored.
-arbitrary text ignored by the regexp engine:
-
- /foo(?#Ignore me)bar/.match('foobar') # => #<MatchData "foobar">
-
-The comment may not include an unescaped terminator character.
-
-See also {Extended Mode}[rdoc-ref:Regexp@Extended+Mode].
-
-== Modes
-
-Each of these modifiers sets a mode for the regexp:
-
-- +i+: <tt>/_pattern_/i</tt> sets
- {Case-Insensitive Mode}[rdoc-ref:Regexp@Case-Insensitive+Mode].
-- +m+: <tt>/_pattern_/m</tt> sets
- {Multiline Mode}[rdoc-ref:Regexp@Multiline+Mode].
-- +x+: <tt>/_pattern_/x</tt> sets
- {Extended Mode}[rdoc-ref:Regexp@Extended+Mode].
-- +o+: <tt>/_pattern_/o</tt> sets
- {Interpolation Mode}[rdoc-ref:Regexp@Interpolation+Mode].
-
-Any, all, or none of these may be applied.
-
-Modifiers +i+, +m+, and +x+ may be applied to subexpressions:
-
-- <tt>(?_modifier_)</tt> turns the mode "on" for ensuing subexpressions
-- <tt>(?-_modifier_)</tt> turns the mode "off" for ensuing subexpressions
-- <tt>(?_modifier_:_subexp_)</tt> turns the mode "on" for _subexp_ within the group
-- <tt>(?-_modifier_:_subexp_)</tt> turns the mode "off" for _subexp_ within the group
-
-Example:
-
- re = /(?i)te(?-i)st/
- re.match('test') # => #<MatchData "test">
- re.match('TEst') # => #<MatchData "TEst">
- re.match('TEST') # => nil
- re.match('teST') # => nil
-
- re = /t(?i:e)st/
- re.match('test') # => #<MatchData "test">
- re.match('tEst') # => #<MatchData "tEst">
- re.match('tEST') # => nil
-
-\Method Regexp#options returns an integer whose value showing
-the settings for case-insensitivity mode, multiline mode, and extended mode.
-
-=== Case-Insensitive Mode
-
-By default, a regexp is case-sensitive:
-
- /foo/.match('FOO') # => nil
-
-Modifier +i+ enables case-insensitive mode:
-
- /foo/i.match('FOO')
- # => #<MatchData "FOO">
-
-\Method Regexp#casefold? returns whether the mode is case-insensitive.
-
-=== Multiline Mode
-
-The multiline-mode in Ruby is what is commonly called a "dot-all mode":
-
-- Without the +m+ modifier, the subexpression <tt>.</tt> does not match newlines:
-
- /a.c/.match("a\nc") # => nil
-
-- With the modifier, it does match:
-
- /a.c/m.match("a\nc") # => #<MatchData "a\nc">
-
-Unlike other languages, the modifier +m+ does not affect the anchors <tt>^</tt> and <tt>$</tt>.
-These anchors always match at line-boundaries in Ruby.
-
-=== Extended Mode
-
-Modifier +x+ enables extended mode, which means that:
-
-- Literal white space in the pattern is to be ignored.
-- Character <tt>#</tt> marks the remainder of its containing line as a comment,
- which is also to be ignored for matching purposes.
-
-In extended mode, whitespace and comments may be used
-to form a self-documented regexp.
-
-Regexp not in extended mode (matches some Roman numerals):
-
- pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
- re = /#{pattern}/
- re.match('MCMXLIII') # => #<MatchData "MCMXLIII" 1:"CM" 2:"XL" 3:"III">
-
-Regexp in extended mode:
-
- pattern = <<-EOT
- ^ # beginning of string
- M{0,3} # thousands - 0 to 3 Ms
- (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs),
- # or 500-800 (D, followed by 0 to 3 Cs)
- (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs),
- # or 50-80 (L, followed by 0 to 3 Xs)
- (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is),
- # or 5-8 (V, followed by 0 to 3 Is)
- $ # end of string
- EOT
- re = /#{pattern}/x
- re.match('MCMXLIII') # => #<MatchData "MCMXLIII" 1:"CM" 2:"XL" 3:"III">
-
-=== Interpolation Mode
-
-Modifier +o+ means that the first time a literal regexp with interpolations
-is encountered,
-the generated Regexp object is saved and used for all future evaluations
-of that literal regexp.
-Without modifier +o+, the generated Regexp is not saved,
-so each evaluation of the literal regexp generates a new Regexp object.
-
-Without modifier +o+:
-
- def letters; sleep 5; /[A-Z][a-z]/; end
- words = %w[abc def xyz]
- start = Time.now
- words.each {|word| word.match(/\A[#{letters}]+\z/) }
- Time.now - start # => 15.0174892
-
-With modifier +o+:
-
- start = Time.now
- words.each {|word| word.match(/\A[#{letters}]+\z/o) }
- Time.now - start # => 5.0010866
-
-Note that if the literal regexp does not have interpolations,
-the +o+ behavior is the default.
-
-== Encodings
-
-By default, a regexp with only US-ASCII characters has US-ASCII encoding:
-
- re = /foo/
- re.source.encoding # => #<Encoding:US-ASCII>
- re.encoding # => #<Encoding:US-ASCII>
-
-A regular expression containing non-US-ASCII characters
-is assumed to use the source encoding.
-This can be overridden with one of the following modifiers.
-
-- <tt>/_pat_/n</tt>: US-ASCII if only containing US-ASCII characters,
- otherwise ASCII-8BIT:
-
- /foo/n.encoding # => #<Encoding:US-ASCII>
- /foo\xff/n.encoding # => #<Encoding:ASCII-8BIT>
- /foo\x7f/n.encoding # => #<Encoding:US-ASCII>
-
-- <tt>/_pat_/u</tt>: UTF-8
-
- /foo/u.encoding # => #<Encoding:UTF-8>
-
-- <tt>/_pat_/e</tt>: EUC-JP
-
- /foo/e.encoding # => #<Encoding:EUC-JP>
-
-- <tt>/_pat_/s</tt>: Windows-31J
-
- /foo/s.encoding # => #<Encoding:Windows-31J>
-
-A regexp can be matched against a target string when either:
-
-- They have the same encoding.
-- The regexp's encoding is a fixed encoding and the string
- contains only ASCII characters.
- Method Regexp#fixed_encoding? returns whether the regexp
- has a <i>fixed</i> encoding.
-
-If a match between incompatible encodings is attempted an
-<tt>Encoding::CompatibilityError</tt> exception is raised.
-
-Example:
-
- re = eval("# encoding: ISO-8859-1\n/foo\\xff?/")
- re.encoding # => #<Encoding:ISO-8859-1>
- re =~ "foo".encode("UTF-8") # => 0
- re =~ "foo\u0100" # Raises Encoding::CompatibilityError
-
-The encoding may be explicitly fixed by including Regexp::FIXEDENCODING
-in the second argument for Regexp.new:
-
- # Regexp with encoding ISO-8859-1.
- re = Regexp.new("a".force_encoding('iso-8859-1'), Regexp::FIXEDENCODING)
- re.encoding # => #<Encoding:ISO-8859-1>
- # Target string with encoding UTF-8.
- s = "a\u3042"
- s.encoding # => #<Encoding:UTF-8>
- re.match(s) # Raises Encoding::CompatibilityError.
-
-== Timeouts
-
-When either a regexp source or a target string comes from untrusted input,
-malicious values could become a denial-of-service attack;
-to prevent such an attack, it is wise to set a timeout.
-
-\Regexp has two timeout values:
-
-- A class default timeout, used for a regexp whose instance timeout is +nil+;
- this default is initially +nil+, and may be set by method Regexp.timeout=:
-
- Regexp.timeout # => nil
- Regexp.timeout = 3.0
- Regexp.timeout # => 3.0
-
-- An instance timeout, which defaults to +nil+ and may be set in Regexp.new:
-
- re = Regexp.new('foo', timeout: 5.0)
- re.timeout # => 5.0
-
-When regexp.timeout is +nil+, the timeout "falls through" to Regexp.timeout;
-when regexp.timeout is non-+nil+, that value controls timing out:
-
- | regexp.timeout Value | Regexp.timeout Value | Result |
- |----------------------|----------------------|-----------------------------|
- | nil | nil | Never times out. |
- | nil | Float | Times out in Float seconds. |
- | Float | Any | Times out in Float seconds. |
-
-== Optimization
-
-For certain values of the pattern and target string,
-matching time can grow polynomially or exponentially in relation to the input size;
-the potential vulnerability arising from this is the {regular expression denial-of-service}[https://en.wikipedia.org/wiki/ReDoS] (ReDoS) attack.
-
-\Regexp matching can apply an optimization to prevent ReDoS attacks.
-When the optimization is applied, matching time increases linearly (not polynomially or exponentially)
-in relation to the input size, and a ReDoS attach is not possible.
-
-This optimization is applied if the pattern meets these criteria:
-
-- No backreferences.
-- No subexpression calls.
-- No nested lookaround anchors or atomic groups.
-- No nested quantifiers with counting (i.e. no nested <tt>{n}</tt>,
- <tt>{min,}</tt>, <tt>{,max}</tt>, or <tt>{min,max}</tt> style quantifiers)
-
-You can use method Regexp.linear_time? to determine whether a pattern meets these criteria:
-
- Regexp.linear_time?(/a*/) # => true
- Regexp.linear_time?('a*') # => true
- Regexp.linear_time?(/(a*)\1/) # => false
-
-However, an untrusted source may not be safe even if the method returns +true+,
-because the optimization uses memoization (which may invoke large memory consumption).
-
-== References
-
-Read (online PDF books):
-
-- {Mastering Regular Expressions}[https://ia902508.us.archive.org/10/items/allitebooks-02/Mastering%20Regular%20Expressions%2C%203rd%20Edition.pdf]
- by Jeffrey E.F. Friedl.
-- {Regular Expressions Cookbook}[https://doc.lagout.org/programmation/Regular%20Expressions/Regular%20Expressions%20Cookbook_%20Detailed%20Solutions%20in%20Eight%20Programming%20Languages%20%282nd%20ed.%29%20%5BGoyvaerts%20%26%20Levithan%202012-09-06%5D.pdf]
- by Jan Goyvaerts & Steven Levithan.
-
-Explore, test (interactive online editor):
-
-- {Rubular}[https://rubular.com/].
diff --git a/doc/_timezones.rdoc b/doc/_timezones.rdoc
deleted file mode 100644
index c5230ea67d..0000000000
--- a/doc/_timezones.rdoc
+++ /dev/null
@@ -1,156 +0,0 @@
-== Timezone Specifiers
-
-Certain +Time+ methods accept arguments that specify timezones:
-
-- Time.at: keyword argument +in:+.
-- Time.new: positional argument +zone+ or keyword argument +in:+.
-- Time.now: keyword argument +in:+.
-- Time#getlocal: positional argument +zone+.
-- Time#localtime: positional argument +zone+.
-
-The value given with any of these must be one of the following
-(each detailed below):
-
-- {Hours/minutes offset}[rdoc-ref:Time@Hours-2FMinutes+Offsets].
-- {Single-letter offset}[rdoc-ref:Time@Single-Letter+Offsets].
-- {Integer offset}[rdoc-ref:Time@Integer+Offsets].
-- {Timezone object}[rdoc-ref:Time@Timezone+Objects].
-- {Timezone name}[rdoc-ref:Time@Timezone+Names].
-
-=== Hours/Minutes Offsets
-
-The zone value may be a string offset from UTC
-in the form <tt>'+HH:MM'</tt> or <tt>'-HH:MM'</tt>,
-where:
-
-- +HH+ is the 2-digit hour in the range <tt>0..23</tt>.
-- +MM+ is the 2-digit minute in the range <tt>0..59</tt>.
-
-Examples:
-
- t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
- Time.at(t, in: '-23:59') # => 1999-12-31 20:16:01 -2359
- Time.at(t, in: '+23:59') # => 2000-01-02 20:14:01 +2359
-
-=== Single-Letter Offsets
-
-The zone value may be a letter in the range <tt>'A'..'I'</tt>
-or <tt>'K'..'Z'</tt>;
-see {List of military time zones}[https://en.wikipedia.org/wiki/List_of_military_time_zones]:
-
- t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
- Time.at(t, in: 'A') # => 2000-01-01 21:15:01 +0100
- Time.at(t, in: 'I') # => 2000-01-02 05:15:01 +0900
- Time.at(t, in: 'K') # => 2000-01-02 06:15:01 +1000
- Time.at(t, in: 'Y') # => 2000-01-01 08:15:01 -1200
- Time.at(t, in: 'Z') # => 2000-01-01 20:15:01 UTC
-
-=== \Integer Offsets
-
-The zone value may be an integer number of seconds
-in the range <tt>-86399..86399</tt>:
-
- t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
- Time.at(t, in: -86399) # => 1999-12-31 20:15:02 -235959
- Time.at(t, in: 86399) # => 2000-01-02 20:15:00 +235959
-
-=== Timezone Objects
-
-The zone value may be an object responding to certain timezone methods, an
-instance of {Timezone}[https://github.com/panthomakos/timezone] and
-{TZInfo}[https://tzinfo.github.io] for example.
-
-The timezone methods are:
-
-- +local_to_utc+:
-
- - Called when Time.new is invoked with +tz+
- as the value of positional argument +zone+ or keyword argument +in:+.
- - Argument: a {Time-like object}[rdoc-ref:Time@Time-Like+Objects].
- - Returns: a {Time-like object}[rdoc-ref:Time@Time-Like+Objects] in the UTC timezone.
-
-- +utc_to_local+:
-
- - Called when Time.at or Time.now is invoked with +tz+
- as the value for keyword argument +in:+,
- and when Time#getlocal or Time#localtime is called with +tz+
- as the value for positional argument +zone+.
- - Argument: a {Time-like object}[rdoc-ref:Time@Time-Like+Objects].
- - Returns: a {Time-like object}[rdoc-ref:Time@Time-Like+Objects] in the local timezone.
-
-A custom timezone class may have these instance methods,
-which will be called if defined:
-
-- +abbr+:
-
- - Called when Time#strftime is invoked with a format involving <tt>%Z</tt>.
- - Argument: a {Time-like object}[rdoc-ref:Time@Time-Like+Objects].
- - Returns: a string abbreviation for the timezone name.
-
-- +dst?+:
-
- - Called when Time.at or Time.now is invoked with +tz+
- as the value for keyword argument +in:+,
- and when Time#getlocal or Time#localtime is called with +tz+
- as the value for positional argument +zone+.
- - Argument: a {Time-like object}[rdoc-ref:Time@Time-Like+Objects].
- - Returns: whether the time is daylight saving time.
-
-- +name+:
-
- - Called when <tt>Marshal.dump(t)</tt> is invoked
- - Argument: none.
- - Returns: the string name of the timezone.
-
-==== +Time+-Like Objects
-
-A +Time+-like object is a container object capable of interfacing with
-timezone libraries for timezone conversion.
-
-The argument to the timezone conversion methods above will have attributes
-similar to Time, except that timezone related attributes are meaningless.
-
-The objects returned by +local_to_utc+ and +utc_to_local+ methods of the
-timezone object may be of the same class as their arguments, of arbitrary
-object classes, or of class Integer.
-
-For a returned class other than +Integer+, the class must have the
-following methods:
-
-- +year+
-- +mon+
-- +mday+
-- +hour+
-- +min+
-- +sec+
-- +isdst+
-- +to_i+
-
-For a returned +Integer+, its components, decomposed in UTC, are
-interpreted as times in the specified timezone.
-
-=== Timezone Names
-
-If the class (the receiver of class methods, or the class of the receiver
-of instance methods) has +find_timezone+ singleton method, this method is
-called to achieve the corresponding timezone object from a timezone name.
-
-For example, using {Timezone}[https://github.com/panthomakos/timezone]:
- class TimeWithTimezone < Time
- require 'timezone'
- def self.find_timezone(z) = Timezone[z]
- end
-
- TimeWithTimezone.now(in: "America/New_York") #=> 2023-12-25 00:00:00 -0500
- TimeWithTimezone.new("2023-12-25 America/New_York") #=> 2023-12-25 00:00:00 -0500
-
-Or, using {TZInfo}[https://tzinfo.github.io]:
- class TimeWithTZInfo < Time
- require 'tzinfo'
- def self.find_timezone(z) = TZInfo::Timezone.get(z)
- end
-
- TimeWithTZInfo.now(in: "America/New_York") #=> 2023-12-25 00:00:00 -0500
- TimeWithTZInfo.new("2023-12-25 America/New_York") #=> 2023-12-25 00:00:00 -0500
-
-You can define this method per subclasses, or on the toplevel Time class.
diff --git a/doc/bsearch.rdoc b/doc/bsearch.rdoc
index 90705853d7..ca8091fc0d 100644
--- a/doc/bsearch.rdoc
+++ b/doc/bsearch.rdoc
@@ -1,4 +1,4 @@
-= Binary Searching
+== Binary Searching
A few Ruby methods support binary searching in a collection:
diff --git a/doc/case_mapping.rdoc b/doc/case_mapping.rdoc
index 57c037b9d8..3c42154973 100644
--- a/doc/case_mapping.rdoc
+++ b/doc/case_mapping.rdoc
@@ -1,4 +1,4 @@
-= Case Mapping
+== Case Mapping
Some string-oriented methods use case mapping.
@@ -24,7 +24,7 @@ In Symbol:
- Symbol#swapcase
- Symbol#upcase
-== Default Case Mapping
+=== Default Case Mapping
By default, all of these methods use full Unicode case mapping,
which is suitable for most languages.
@@ -60,7 +60,7 @@ Case changes may not be reversible:
Case changing methods may not maintain Unicode normalization.
See String#unicode_normalize).
-== Options for Case Mapping
+=== Options for Case Mapping
Except for +casecmp+ and +casecmp?+,
each of the case-mapping methods listed above
diff --git a/doc/character_selectors.rdoc b/doc/character_selectors.rdoc
index 47cf242be7..e01b0e6a25 100644
--- a/doc/character_selectors.rdoc
+++ b/doc/character_selectors.rdoc
@@ -1,6 +1,6 @@
-= Character Selectors
+== Character Selectors
-== Character Selector
+=== Character Selector
A _character_ _selector_ is a string argument accepted by certain Ruby methods.
Each of these instance methods accepts one or more character selectors:
@@ -70,7 +70,7 @@ In a character selector, these three characters get special treatment:
"hello\r\nworld".delete("\\r") # => "hello\r\nwold"
"hello\r\nworld".delete("\\\r") # => "hello\nworld"
-== Multiple Character Selectors
+=== Multiple Character Selectors
These instance methods accept multiple character selectors:
diff --git a/doc/command_injection.rdoc b/doc/command_injection.rdoc
index 246b2e6afe..af09be23f0 100644
--- a/doc/command_injection.rdoc
+++ b/doc/command_injection.rdoc
@@ -1,4 +1,4 @@
-= Command Injection
+== Command Injection
Some Ruby core methods accept string data
that includes text to be executed as a system command.
@@ -8,7 +8,6 @@ They should not be called with unknown or unsanitized commands.
These methods include:
- Kernel.system
-- Kernel.open
- {\`command` (backtick method)}[rdoc-ref:Kernel#`]
(also called by the expression <tt>%x[command]</tt>).
- IO.popen(command).
@@ -18,7 +17,6 @@ These methods include:
- IO.binwrite(command).
- IO.readlines(command).
- IO.foreach(command).
-- URI.open(command).
Note that some of these methods do not execute commands when called
from subclass \File:
diff --git a/doc/contributing/building_ruby.md b/doc/contributing/building_ruby.md
index b2a7b007eb..469c9d8361 100644
--- a/doc/contributing/building_ruby.md
+++ b/doc/contributing/building_ruby.md
@@ -1,113 +1,83 @@
# Building Ruby
-## Dependencies
+## Quick start guide
1. Install the prerequisite dependencies for building the CRuby interpreter:
* C compiler
-
- For RubyGems, you will also need:
-
- * OpenSSL 1.1.x or 3.0.x / LibreSSL
- * libyaml 0.1.7 or later
- * zlib
-
- If you want to build from the git repository, you will also need:
-
* autoconf - 2.67 or later
- * gperf - 3.1 or later
- * Usually unneeded; only if you edit some source files using gperf
- * ruby - 2.5 or later
- * We can upgrade this version to system ruby version of the latest Ubuntu LTS.
+ * bison - 3.0 or later
+ * gperf - 3.0.3 or later
+ * ruby - 2.7 or later
2. Install optional, recommended dependencies:
- * libffi (to build fiddle)
- * gmp (if you with to accelerate Bignum operations)
+ * OpenSSL/LibreSSL
+ * readline/editline (libedit)
+ * zlib
+ * libffi
+ * libyaml
* libexecinfo (FreeBSD)
- * rustc - 1.58.0 or later, if you wish to build
- [YJIT](https://docs.ruby-lang.org/en/master/RubyVM/YJIT.html).
+ * rustc - 1.58.0 or later (if you wish to build [YJIT](/doc/yjit/yjit.md))
- If you installed the libraries needed for extensions (openssl, readline, libyaml, zlib) into other than the OS default place,
- typically using Homebrew on macOS, add `--with-EXTLIB-dir` options to `CONFIGURE_ARGS` environment variable.
+3. Checkout the CRuby source code:
- ``` shell
- export CONFIGURE_ARGS=""
- for ext in openssl readline libyaml zlib; do
- CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-$ext-dir=$(brew --prefix $ext)"
- done
+ ```
+ git clone https://github.com/ruby/ruby.git
```
-## Quick start guide
-
-1. Download ruby source code:
-
- Select one of the bellow.
-
- 1. Build from the tarball:
-
- Download the latest tarball from [ruby-lang.org](https://www.ruby-lang.org/en/downloads/) and
- extract it. Example for Ruby 3.0.2:
-
- ``` shell
- tar -xzf ruby-3.0.2.tar.gz
- cd ruby-3.0.2
- ```
-
- 2. Build from the git repository:
-
- Checkout the CRuby source code:
-
- ``` shell
- git clone https://github.com/ruby/ruby.git
- cd ruby
- ```
-
- Generate the configure file:
+4. Generate the configure file:
- ``` shell
- ./autogen.sh
- ```
+ ```
+ ./autogen.sh
+ ```
-2. Create a `build` directory separate from the source directory:
+5. Create a `build` directory outside of the source directory:
- ``` shell
+ ```
mkdir build && cd build
```
While it's not necessary to build in a separate directory, it's good practice to do so.
-3. We'll install Ruby in `~/.rubies/ruby-master`, so create the directory:
+6. We'll install Ruby in `~/.rubies/ruby-master`, so create the directory:
- ``` shell
+ ```
mkdir ~/.rubies
```
-4. Run configure:
+7. Run configure:
- ``` shell
+ ```
../configure --prefix="${HOME}/.rubies/ruby-master"
```
- If you are frequently building Ruby, add the `--disable-install-doc` flag to not build documentation which will speed up the build process.
- - Also `-C` (or `--config-cache`) would reduce time to configure from the next time.
-
-5. Build Ruby:
+8. Build Ruby:
- ``` shell
+ ```
make install
```
-6. [Run tests](testing_ruby.md) to confirm your build succeeded.
+ - If you're on macOS and installed \OpenSSL through Homebrew, you may encounter failure to build \OpenSSL that look like this:
-### Unexplainable Build Errors
+ ```
+ openssl:
+ Could not be configured. It will not be installed.
+ ruby/ext/openssl/extconf.rb: OpenSSL library could not be found. You might want to use --with-openssl-dir=<dir> option to specify the prefix where OpenSSL is installed.
+ Check ext/openssl/mkmf.log for more details.
+ ```
-If you are having unexplainable build errors, after saving all your work, try running `git clean -xfd` in the source root to remove all git ignored local files. If you are working from a source directory that's been updated several times, you may have temporary build artifacts from previous releases which can cause build failures.
+ Adding `--with-openssl-dir=$(brew --prefix openssl)` to the list of options passed to configure may solve the issue.
+
+ Remember to delete your `build` directory and start again from the configure step.
-## Building on Windows
+9. [Run tests](testing_ruby.md) to confirm your build succeeded.
-The documentation for building on Windows can be found [here](../windows.md).
+### Unexplainable Build Errors
+
+If you are having unexplainable build errors, after saving all your work, try running `git clean -xfd` in the source root to remove all git ignored local files. If you are working from a source directory that's been updated several times, you may have temporary build artifacts from previous releases which can cause build failures.
## More details
@@ -119,7 +89,7 @@ about Ruby's build to help out.
In GNU make and BSD make implementations, to run a specific make script in parallel, pass the flag `-j<number of processes>`. For instance,
to run tests on 8 processes, use:
-``` shell
+```
make test-all -j8
```
@@ -147,7 +117,7 @@ Miniruby is a version of Ruby which has no external dependencies and lacks certa
It can be useful in Ruby development because it allows for faster build times. Miniruby is
built before Ruby. A functional Miniruby is required to build Ruby. To build Miniruby:
-``` shell
+```
make miniruby
```
@@ -163,14 +133,6 @@ with the Ruby script you'd like to run. You can use the following make targets:
* `make lldb-ruby`: Runs `test.rb` using Ruby in lldb
* `make gdb-ruby`: Runs `test.rb` using Ruby in gdb
-### Compiling for Debugging
-
-You should configure Ruby without optimization and other flags that may interfere with debugging:
-
-``` shell
-./configure --enable-debug-env optflags="-O0 -fno-omit-frame-pointer"
-```
-
### Building with Address Sanitizer
Using the address sanitizer is a great way to detect memory issues.
@@ -189,7 +151,7 @@ On Linux it is important to specify `-O0` when debugging. This is especially tru
You need to be able to use gcc (gcov) and lcov visualizer.
-``` shell
+```
./autogen.sh
./configure --enable-gcov
make
diff --git a/doc/contributing/documentation_guide.md b/doc/contributing/documentation_guide.md
index 027be34775..9cfd59d629 100644
--- a/doc/contributing/documentation_guide.md
+++ b/doc/contributing/documentation_guide.md
@@ -20,16 +20,14 @@ build directory:
make html
```
-If you don't have a build directory, follow the [quick start
-guide](building_ruby.md#label-Quick+start+guide) up to step 4.
-
Then you can preview your changes by opening
`{build folder}/.ext/html/index.html` file in your browser.
+
## Goal
The goal of Ruby documentation is to impart the most important
-and relevant information in the shortest time.
+and relevant in the shortest time.
The reader should be able to quickly understand the usefulness
of the subject code and how to use it.
@@ -43,17 +41,16 @@ Use your judgment about what the user needs to know.
- Write short declarative or imperative sentences.
- Group sentences into (ideally short) paragraphs,
each covering a single topic.
-- Organize material with
- [headings](rdoc-ref:RDoc::MarkupReference@Headings).
+- Organize material with [headers](rdoc-ref:RDoc::Markup@Headers).
- Refer to authoritative and relevant sources using
- [links](rdoc-ref:RDoc::MarkupReference@Links).
+ [links](rdoc-ref:RDoc::Markup@Links).
- Use simple verb tenses: simple present, simple past, simple future.
- Use simple sentence structure, not compound or complex structure.
- Avoid:
- Excessive comma-separated phrases;
- consider a [list](rdoc-ref:RDoc::MarkupReference@Lists).
+ consider a [list](rdoc-ref:RDoc::Markup@Simple+Lists).
- Idioms and culture-specific references.
- - Overuse of headings.
+ - Overuse of headers.
- Using US-ASCII-incompatible characters in C source files;
see [Characters](#label-Characters) below.
@@ -127,23 +124,16 @@ a.shuffle! #=> [2, 3, 1]
a #=> [2, 3, 1]
```
-### Headings
-
-Organize a long discussion for a class or module with [headings](rdoc-ref:RDoc::MarkupReference@Headings).
+### Headers
-Do not use formal headings in the documentation for a method or constant.
-
-In the rare case where heading-like structures are needed
-within the documentation for a method or constant, use
-[bold text](rdoc-ref:RDoc::MarkupReference@Bold)
-as pseudo-headings.
+Organize a long discussion with [headers](rdoc-ref:RDoc::Markup@Headers).
### Blank Lines
A blank line begins a new paragraph.
-A [code block](rdoc-ref:RDoc::MarkupReference@Code+Blocks)
-or [list](rdoc-ref:RDoc::MarkupReference@Lists)
+A [code block](rdoc-ref:RDoc::Markup@Paragraphs+and+Verbatim)
+or [list](rdoc-ref:RDoc::Markup@Simple+Lists)
should be preceded by and followed by a blank line.
This is unnecessary for the HTML output, but helps in the `ri` output.
@@ -160,14 +150,6 @@ For a method name in text:
or a hash mark for an instance method:
<tt>Foo.bar</tt>, <tt>Foo#baz</tt>.
-### Embedded Code and Commands
-
-Code or commands embedded in running text (i.e., not in a code block)
-should marked up as
-[monofont](rdoc-ref:RDoc::MarkupReference@Monofont).
-
-Code that is a simple string should include the quote marks.
-
### Auto-Linking
In general, \RDoc's auto-linking should not be suppressed.
@@ -181,61 +163,6 @@ We might consider whether to suppress when:
(e.g., _Array_ in the documentation for class `Array`).
- The same reference is repeated many times
(e.g., _RDoc_ on this page).
-- The reference is to a class or module that users
- usually don't deal with, including these:
-
- - \Class.
- - \Method.
- - \Module.
-
-Most often, the name of a class, module, or method
-will be autolinked:
-
-- Array.
-- Enumerable.
-- File.new
-- File#read.
-
-If not, or if you suppress autolinking, consider forcing
-[monofont](rdoc-ref:RDoc::MarkupReference@Monofont).
-
-### Explicit Links
-
-When writing an explicit link, follow these guidelines.
-
-#### +rdoc-ref+ Scheme
-
-Use the +rdoc-ref+ scheme for:
-
-- A link in core documentation to other core documentation.
-- A link in core documentation to documentation in a standard library package.
-- A link in a standard library package to other documentation in that same
- standard library package.
-
-See section "+rdoc-ref+ Scheme" in {Links}[rdoc-ref:RDoc::MarkupReference@Links].
-
-#### URL-Based Link
-
-Use a full URL-based link for:
-
-- A link in standard library documentation to documentation in the core.
-- A link in standard library documentation to documentation in a different
- standard library package.
-
-Doing so ensures that the link will valid even when the package documentation
-is built independently (separately from the core documentation).
-
-The link should lead to a target in https://docs.ruby-lang.org/en/master/.
-
-Also use a full URL-based link for a link to an off-site document.
-
-### Variable Names
-
-The name of a variable (as specified in its call-seq) should be marked up as
-[monofont](rdoc-ref:RDoc::MarkupReference@Monofont).
-
-Also, use monofont text for the name of a transient variable
-(i.e., one defined and used only in the discussion, such as +n+).
### HTML Tags
@@ -248,21 +175,16 @@ may not render them properly.
In particular, avoid building tables with HTML tags
(<tt><table></tt>, etc.).
-Alternatives:
+Alternatives are:
-- A {verbatim text block}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks],
- using spaces and punctuation to format the text;
- note that {text markup}[rdoc-ref:RDoc::MarkupReference@Text+Markup]
- will not be honored:
+- The GFM (GitHub Flavored Markdown) table extension,
+ which is enabled by default. See
+ {GFM tables extension}[https://github.github.com/gfm/#tables-extension-].
- - Example {source}[https://github.com/ruby/ruby/blob/34d802f32f00df1ac0220b62f72605827c16bad8/file.c#L6570-L6596].
- - Corresponding {output}[rdoc-ref:File@Read-2FWrite+Mode].
-
-- (Markdown format only): A {Github Flavored Markdown (GFM) table}[https://github.github.com/gfm/#tables-extension-],
- using special formatting for the text:
-
- - Example {source}[https://github.com/ruby/ruby/blob/34d802f32f00df1ac0220b62f72605827c16bad8/doc/contributing/glossary.md?plain=1].
- - Corresponding {output}[https://docs.ruby-lang.org/en/master/contributing/glossary_md.html].
+- A {verbatim text block}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks],
+ using spaces and punctuation to format the text.
+ Note that {text markup}[rdoc-ref:RDoc::MarkupReference@Text+Markup]
+ will not be honored.
## Documenting Classes and Modules
@@ -292,12 +214,9 @@ Guidelines:
- The section title is `What's Here`.
- Consider listing the parent class and any included modules; consider
- [links](rdoc-ref:RDoc::MarkupReference@Links)
+ [links](rdoc-ref:RDoc::Markup@Links)
to their "What's Here" sections if those exist.
-- All methods mentioned in the left-pane table of contents
- should be listed (including any methods extended from another class).
-- Attributes (which are not included in the TOC) may also be listed.
-- Display methods as items in one or more bullet lists:
+- List methods as a bullet list:
- Begin each item with the method name, followed by a colon
and a short description.
@@ -305,9 +224,9 @@ Guidelines:
(and do not list the aliases separately).
- Check the rendered documentation to determine whether \RDoc has recognized
the method and linked to it; if not, manually insert a
- [link](rdoc-ref:RDoc::MarkupReference@Links).
+ [link](rdoc-ref:RDoc::Markup@Links).
-- If there are numerous entries, consider grouping them into subsections with headings.
+- If there are numerous entries, consider grouping them into subsections with headers.
- If there are more than a few such subsections,
consider adding a table of contents just below the main section title.
@@ -322,6 +241,7 @@ The general structure of the method documentation should be:
- Details and examples.
- Argument description (if necessary).
- Corner cases and exceptions.
+- Aliases.
- Related methods (optional).
### Calling Sequence (for methods written in C)
@@ -330,7 +250,7 @@ For methods written in Ruby, \RDoc documents the calling sequence automatically.
For methods written in C, \RDoc cannot determine what arguments
the method accepts, so those need to be documented using \RDoc directive
-[`call-seq:`](rdoc-ref:RDoc::MarkupReference@Directives+for+Method+Documentation).
+[`call-seq:`](rdoc-ref:RDoc::Markup@Method+arguments).
For a singleton method, use the form:
@@ -408,11 +328,7 @@ Return types:
Aliases:
-- Omit aliases from the `call-seq`, unless the alias is an
- operator method. If listing both a regular method and an
- operator method in the `call-seq`, explain in the details and
- examples section when it is recommended to use the regular method
- and when it is recommended to use the operator method.
+- Omit aliases from the `call-seq`, but mention them near the end (see below).
### Synopsis
@@ -469,7 +385,7 @@ argument passed if it is not obvious, not explicitly mentioned in the
details, and not implicitly shown in the examples.
If there is more than one argument or block argument, use a
-[labeled list](rdoc-ref:RDoc::MarkupReference@Labeled+Lists).
+[labeled list](rdoc-ref:RDoc::Markup@Labeled+Lists).
### Corner Cases and Exceptions
@@ -482,6 +398,14 @@ you do not need to document that a `TypeError` is raised if a non-integer
is passed. Do not provide examples of exceptions being raised unless
that is a common case, such as `Hash#fetch` raising a `KeyError`.
+### Aliases
+
+Mention aliases in the form
+
+```
+// Array#find_index is an alias for Array#index.
+```
+
### Related Methods (optional)
In some cases, it is useful to document which methods are related to
diff --git a/doc/contributing/glossary.md b/doc/contributing/glossary.md
deleted file mode 100644
index 86c6671fbd..0000000000
--- a/doc/contributing/glossary.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Ruby Internals Glossary
-
-Just a list of acronyms I've run across in the Ruby source code and their meanings.
-
-| Term | Definition |
-| --- | -----------|
-| `BIN` | Basic Instruction Name. Used as a macro to reference the YARV instruction. Converts pop into YARVINSN_pop. |
-| `bop` | Basic Operator. Relates to methods like `Integer` plus and minus which can be optimized as long as they haven't been redefined. |
-| `cc` | Call Cache. An inline cache structure for the call site. Stored in the `cd` |
-| `cd` | Call Data. A data structure that points at the `ci` and the `cc`. `iseq` objects points at the `cd`, and access call information and call caches via this structure |
-| `cfp`| Control Frame Pointer. Represents a Ruby stack frame. Calling a method pushes a new frame (cfp), returning pops a frame. Points at the `pc`, `sp`, `ep`, and the corresponding `iseq`|
-| `ci` | Call Information. Refers to an `rb_callinfo` struct. Contains call information about the call site, including number of parameters to be passed, whether it they are keyword arguments or not, etc. Used in conjunction with the `cc` and `cd`. |
-| `cref` | Class reference. A structure pointing to the class reference where `klass_or_self`, visibility scope, and refinements are stored. It also stores a pointer to the next class in the hierarchy referenced by `rb_cref_struct * next`. The Class reference is lexically scoped. |
-| CRuby | Implementation of Ruby written in C |
-| `cvar` | Class Variable. Refers to a Ruby class variable like `@@foo` |
-| `dvar` | Dynamic Variable. Used by the parser to refer to local variables that are defined outside of the current lexical scope. For example `def foo; bar = 1; -> { p bar }; end` the "bar" inside the block is a `dvar` |
-| `ec` | Execution Context. The top level VM context, points at the current `cfp` |
-| `ep` | Environment Pointer. Local variables, including method parameters are stored in the `ep` array. The `ep` is pointed to by the `cfp` |
-| GC | Garbage Collector |
-| `gvar` | Global Variable. Refers to a Ruby global variable like `$$`, etc |
-| `ICLASS` | Internal Class. When a module is included, the target class gets a new superclass which is an instance of an `ICLASS`. The `ICLASS` represents the module in the inheritance chain. |
-| `ifunc` | Internal FUNCtion. A block implemented in C. |
-| `iseq` | Instruction Sequence. Usually "iseq" in the C code will refer to an `rb_iseq_t` object that holds a reference to the actual instruction sequences which are executed by the VM. The object also holds information about the code, like the method name associated with the code. |
-| `insn` | Instruction. Refers to a YARV instruction. |
-| `insns` | Instructions. Usually an array of YARV instructions. |
-| `ivar` | Instance Variable. Refers to a Ruby instance variable like `@foo` |
-| `imemo` | Internal Memo. A tagged struct whose memory is managed by Ruby's GC, but contains internal information and isn't meant to be exposed to Ruby programs. Contains various information depending on the type. See the `imemo_type` enum for different types. |
-| JIT | Just In Time compiler |
-| `lep` | Local Environment Pointer. An `ep` which is tagged `VM_ENV_FLAG_LOCAL`. Usually this is the `ep` of a method (rather than a block, whose `ep` isn't "local") |
-| `local` | Local. Refers to a local variable. |
-| `me` | Method Entry. Refers to an `rb_method_entry_t` struct, the internal representation of a Ruby method.
-| MRI | Matz's Ruby Implementation |
-| `pc` | Program Counter. Usually the instruction that will be executed _next_ by the VM. Pointed to by the `cfp` and incremented by the VM |
-| `sp` | Stack Pointer. The top of the stack. The VM executes instructions in the `iseq` and instructions will push and pop values on the stack. The VM updates the `sp` on the `cfp` to point at the top of the stack|
-| `svar` | Special Variable. Refers to special local variables like `$~` and `$_`. See the `getspecial` instruction in `insns.def` |
-| `VALUE` | VALUE is a pointer to a ruby object from the Ruby C code. |
-| VM | Virtual Machine. In MRI's case YARV (Yet Another Ruby VM)
-| WB | Write Barrier. To do with GC write barriers |
-| WC | Wild Card. As seen in instructions like `getlocal_WC_0`. It means this instruction takes a "wild card" for the parameter (in this case an index for a local) |
-| YARV | Yet Another Ruby VM. The virtual machine that CRuby uses |
-| ZOMBIE | A zombie object. An object that has a finalizer which hasn't been executed yet. The object has been collected, so is "dead", but the finalizer hasn't run yet so it's still somewhat alive. |
diff --git a/doc/contributing/making_changes_to_stdlibs.md b/doc/contributing/making_changes_to_stdlibs.md
index 3b33092fea..ef3811ea12 100644
--- a/doc/contributing/making_changes_to_stdlibs.md
+++ b/doc/contributing/making_changes_to_stdlibs.md
@@ -8,7 +8,7 @@ For example, CSV lives in [a separate repository](https://github.com/ruby/csv) a
## Maintainers
-You can find the list of maintainers [here](https://docs.ruby-lang.org/en/master/maintainers_md.html#label-Maintainers).
+You can find the list of maintainers [here](https://docs.ruby-lang.org/en/master/maintainers_rdoc.html#label-Maintainers).
## Build
diff --git a/doc/contributing/testing_ruby.md b/doc/contributing/testing_ruby.md
index dfb7fb3a65..6247686efc 100644
--- a/doc/contributing/testing_ruby.md
+++ b/doc/contributing/testing_ruby.md
@@ -70,7 +70,7 @@ We can run any of the make scripts [in parallel](building_ruby.md#label-Running+
first the file name, and then the test name, prefixed with `--name`. For example:
```
- make test-all TESTS="../test/ruby/test_alias.rb --name=TestAlias#test_alias_with_zsuper_method"
+ make test-all TESTS="../test/ruby/test_alias.rb --name=/test_alias_with_zsuper_method/"
```
To run these specs with logs, we can use:
@@ -79,13 +79,7 @@ We can run any of the make scripts [in parallel](building_ruby.md#label-Running+
make test-all TESTS=-v
```
- We can display the help of the `TESTS` option:
-
- ```
- make test-all TESTS=--help
- ```
-
- If we would like to run the `test/`, `bootstraptest/` and `spec/` test suites (the `spec/` is explained in a later section), we can run
+ If we would like to run both the `test/` and `bootstraptest/` test suites, we can run
```
make check
@@ -99,28 +93,28 @@ We can run any of the make scripts [in parallel](building_ruby.md#label-Running+
make test-spec
```
- To run a specific directory, we can use `SPECOPTS` to specify the directory:
+ To run a specific directory, we can use `MSPECOPT` to specify the directory:
```
- make test-spec SPECOPTS=spec/ruby/core/array
+ make test-spec MSPECOPT=spec/ruby/core/array
```
- To run a specific file, we can also use `SPECOPTS` to specify the file:
+ To run a specific file, we can also use `MSPECOPT` to specify the file:
```
- make test-spec SPECOPTS=spec/ruby/core/array/any_spec.rb
+ make test-spec MSPECOPT=spec/ruby/core/array/any_spec.rb
```
To run a specific test, we can use the `--example` flag to match against the test name:
```
- make test-spec SPECOPTS="../spec/ruby/core/array/any_spec.rb --example='is false if the array is empty'"
+ make test-spec MSPECOPT="../spec/ruby/core/array/any_spec.rb --example='is false if the array is empty'"
```
To run these specs with logs, we can use:
```
- make test-spec SPECOPTS=-Vfs
+ make test-spec MSPECOPT=-Vfs
```
To run a ruby-spec file or directory with GNU make, we can use
@@ -140,17 +134,5 @@ We can run any of the make scripts [in parallel](building_ruby.md#label-Running+
To run a specific bundler spec file, we can use `BUNDLER_SPECS` as follows:
```
- make test-bundler BUNDLER_SPECS=commands/exec_spec.rb
+ $ make test-bundler BUNDLER_SPECS=commands/exec_spec.rb
```
-
-## Troubleshooting
-
-### Running test suites on s390x CPU Architecture
-
-If we see failing tests related to the zlib library on s390x CPU architecture, we can run the test suites with `DFLTCC=0` to pass:
-
-```
-DFLTCC=0 make check
-```
-
-The failures can happen with the zlib library applying the patch [madler/zlib#410](https://github.com/madler/zlib/pull/410) to enable the deflate algorithm producing a different compressed byte stream. We manage this issue at [[ruby-core:114942][Bug #19909]](https://bugs.ruby-lang.org/issues/19909).
diff --git a/doc/csv/options/common/col_sep.rdoc b/doc/csv/options/common/col_sep.rdoc
index 3f23c6d2d3..05769b5773 100644
--- a/doc/csv/options/common/col_sep.rdoc
+++ b/doc/csv/options/common/col_sep.rdoc
@@ -55,3 +55,9 @@ Raises an exception if parsing with the empty \String:
# Raises ArgumentError (:col_sep must be 1 or more characters: "")
CSV.parse("foo0\nbar1\nbaz2\n", col_sep: col_sep)
+Raises an exception if the given value is not String-convertible:
+ col_sep = BasicObject.new
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.generate(line, col_sep: col_sep)
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.parse(str, col_sep: col_sep)
diff --git a/doc/csv/options/common/row_sep.rdoc b/doc/csv/options/common/row_sep.rdoc
index eae15b4a84..872d9d1f3f 100644
--- a/doc/csv/options/common/row_sep.rdoc
+++ b/doc/csv/options/common/row_sep.rdoc
@@ -89,3 +89,12 @@ if any of the following is true:
* The stream is only available for output.
Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead.
+
+---
+
+Raises an exception if the given value is not String-convertible:
+ row_sep = BasicObject.new
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.generate(ary, row_sep: row_sep)
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
+ CSV.parse(str, row_sep: row_sep)
diff --git a/doc/csv/options/generating/write_converters.rdoc b/doc/csv/options/generating/write_converters.rdoc
index d1a9cc748f..6e5fae5fda 100644
--- a/doc/csv/options/generating/write_converters.rdoc
+++ b/doc/csv/options/generating/write_converters.rdoc
@@ -23,3 +23,11 @@ With two write converters (called in order):
str # => "a,b,c\n"
See also {Write Converters}[#class-CSV-label-Write+Converters]
+
+---
+
+Raises an exception if the converter returns a value that is neither +nil+
+nor \String-convertible:
+ bad_converter = proc {|field| BasicObject.new }
+ # Raises NoMethodError (undefined method `is_a?' for #<BasicObject:>)
+ CSV.generate_line(['a', 'b', 'c'], write_converters: bad_converter) \ No newline at end of file
diff --git a/doc/csv/options/generating/write_headers.rdoc b/doc/csv/options/generating/write_headers.rdoc
index c56aa48adb..f9faa9d438 100644
--- a/doc/csv/options/generating/write_headers.rdoc
+++ b/doc/csv/options/generating/write_headers.rdoc
@@ -19,7 +19,7 @@ Without +write_headers+:
With +write_headers+":
CSV.open(file_path,'w',
- :write_headers => true,
+ :write_headers=> true,
:headers => ['Name','Value']
) do |csv|
csv << ['foo', '0']
diff --git a/doc/csv/options/parsing/liberal_parsing.rdoc b/doc/csv/options/parsing/liberal_parsing.rdoc
index 603de28613..b8b9b00c98 100644
--- a/doc/csv/options/parsing/liberal_parsing.rdoc
+++ b/doc/csv/options/parsing/liberal_parsing.rdoc
@@ -1,13 +1,13 @@
====== Option +liberal_parsing+
-Specifies the boolean or hash value that determines whether
+Specifies the boolean value that determines whether
CSV will attempt to parse input not conformant with RFC 4180,
such as double quotes in unquoted fields.
Default value:
CSV::DEFAULT_OPTIONS.fetch(:liberal_parsing) # => false
-For the next two examples:
+For examples in this section:
str = 'is,this "three, or four",fields'
Without +liberal_parsing+:
@@ -17,22 +17,3 @@ Without +liberal_parsing+:
With +liberal_parsing+:
ary = CSV.parse_line(str, liberal_parsing: true)
ary # => ["is", "this \"three", " or four\"", "fields"]
-
-Use the +backslash_quote+ sub-option to parse values that use
-a backslash to escape a double-quote character. This
-causes the parser to treat <code>\"</code> as if it were
-<code>""</code>.
-
-For the next two examples:
- str = 'Show,"Harry \"Handcuff\" Houdini, the one and only","Tampa Theater"'
-
-With +liberal_parsing+, but without the +backslash_quote+ sub-option:
- # Incorrect interpretation of backslash; incorrectly interprets the quoted comma as a field separator.
- ary = CSV.parse_line(str, liberal_parsing: true)
- ary # => ["Show", "\"Harry \\\"Handcuff\\\" Houdini", " the one and only\"", "Tampa Theater"]
- puts ary[1] # => "Harry \"Handcuff\" Houdini
-
-With +liberal_parsing+ and its +backslash_quote+ sub-option:
- ary = CSV.parse_line(str, liberal_parsing: { backslash_quote: true })
- ary # => ["Show", "Harry \"Handcuff\" Houdini, the one and only", "Tampa Theater"]
- puts ary[1] # => Harry "Handcuff" Houdini, the one and only
diff --git a/doc/csv/recipes/filtering.rdoc b/doc/csv/recipes/filtering.rdoc
index 1552bf0fb8..470649d09a 100644
--- a/doc/csv/recipes/filtering.rdoc
+++ b/doc/csv/recipes/filtering.rdoc
@@ -1,7 +1,5 @@
== Recipes for Filtering \CSV
-These recipes are specific code examples for specific \CSV filtering tasks.
-
For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].
All code snippets on this page assume that the following has been executed:
diff --git a/doc/csv/recipes/generating.rdoc b/doc/csv/recipes/generating.rdoc
index a6bd88a714..3ef6df99b4 100644
--- a/doc/csv/recipes/generating.rdoc
+++ b/doc/csv/recipes/generating.rdoc
@@ -1,7 +1,5 @@
== Recipes for Generating \CSV
-These recipes are specific code examples for specific \CSV generating tasks.
-
For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].
All code snippets on this page assume that the following has been executed:
@@ -146,7 +144,7 @@ This example defines and uses a custom write converter to strip whitespace from
==== Recipe: Specify Multiple Write Converters
-Use option <tt>:write_converters</tt> and multiple custom converters
+Use option <tt>:write_converters</tt> and multiple custom coverters
to convert field values when generating \CSV.
This example defines and uses two custom write converters to strip and upcase generated fields:
diff --git a/doc/csv/recipes/parsing.rdoc b/doc/csv/recipes/parsing.rdoc
index f3528fbdf1..7ac96a934b 100644
--- a/doc/csv/recipes/parsing.rdoc
+++ b/doc/csv/recipes/parsing.rdoc
@@ -1,7 +1,5 @@
== Recipes for Parsing \CSV
-These recipes are specific code examples for specific \CSV parsing tasks.
-
For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].
All code snippets on this page assume that the following has been executed:
@@ -520,7 +518,7 @@ Apply multiple header converters by defining and registering a custom header con
To capture unconverted field values, use option +:unconverted_fields+:
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
parsed = CSV.parse(source, converters: :integer, unconverted_fields: true)
- parsed # => [["Name", "Value"], ["foo", 0], ["bar", 1], ["baz", 2]]
+ parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
parsed.each {|row| p row.unconverted_fields }
Output:
["Name", "Value"]
diff --git a/doc/csv/recipes/recipes.rdoc b/doc/csv/recipes/recipes.rdoc
index 9bf7885b1e..9e4eaa1da4 100644
--- a/doc/csv/recipes/recipes.rdoc
+++ b/doc/csv/recipes/recipes.rdoc
@@ -1,6 +1,6 @@
== Recipes for \CSV
-The recipes are specific code examples for specific tasks. See:
+See:
- {Recipes for Parsing CSV}[./parsing_rdoc.html]
- {Recipes for Generating CSV}[./generating_rdoc.html]
- {Recipes for Filtering CSV}[./filtering_rdoc.html]
diff --git a/doc/distribution.md b/doc/distribution.md
deleted file mode 100644
index bc89a7500a..0000000000
--- a/doc/distribution.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# Distribution
-
-This document outlines the expected way to distribute Ruby, with a specific focus on building Ruby packages.
-
-## Getting the Ruby Tarball
-
-### Official Releases
-
-The tarball for official releases is created by the release manager. The release manager uploads the tarball to the [Ruby website](https://www.ruby-lang.org/en/downloads/).
-
-Downstream distributors should use the official release tarballs as part of their build process. This ensures that the tarball is created in a consistent way, and that the tarball is crytographically verified.
-
-### Using the nightly tarball for testing
-
-See the Snapshots section of the [Ruby website](https://www.ruby-lang.org/en/downloads/).
-
-### Building a manual snapshot tarball for testing
-
-This can be useful if the nightly tarball does not have all changes yet.
-
-At Ruby source tree cloned using git:
-```sh-session
-$ ./autogen.sh
-$ ./configure -C
-$ make
-$ make dist
-```
-
-This will create several tarball in the `tmp` directory. The tarball will be named e.g. `ruby-<version>.tar.gz` (several different compression formats will be generated).
-
-## Building the Tarball
-
-See [Building Ruby](contributing/building_ruby.md).
-
-## Updating the Ruby Standard Library
-
-The Ruby standard library is a collection of Ruby files that are included with Ruby. These files are used to provide the basic functionality of Ruby. The standard library is located in the `lib` directory and is distributed as part of the Ruby tarball.
-
-Occasionally, the standard library needs to be updated, for example a security issue might be found in a default gem or standard gem. There are two main ways that Ruby would update this code.
-
-### Releasing an Updated Ruby Gem
-
-Normally, the Ruby gem maintainer will release an updated gem. This gem can be installed alongside the default gem. This allows the user to update the gem without having to update Ruby.
-
-### Releasing a New Ruby Version
-
-If the update is critical, then the Ruby maintainers may decide to release a new version of Ruby. This new version will include the updated standard library.
diff --git a/doc/encodings.rdoc b/doc/encodings.rdoc
index 97c0d22616..1f3c54d740 100644
--- a/doc/encodings.rdoc
+++ b/doc/encodings.rdoc
@@ -1,6 +1,6 @@
-= Encodings
+== Encodings
-== The Basics
+=== The Basics
A {character encoding}[https://en.wikipedia.org/wiki/Character_encoding],
often shortened to _encoding_, is a mapping between:
@@ -30,9 +30,9 @@ Other characters, such as the Euro symbol, are multi-byte:
s = "\u20ac" # => "€"
s.bytes # => [226, 130, 172]
-== The \Encoding \Class
+=== The \Encoding \Class
-=== \Encoding Objects
+==== \Encoding Objects
Ruby encodings are defined by constants in class \Encoding.
There can be only one instance of \Encoding for each of these constants.
@@ -43,7 +43,7 @@ There can be only one instance of \Encoding for each of these constants.
Encoding.list.take(3)
# => [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>, #<Encoding:US-ASCII>]
-=== Names and Aliases
+==== Names and Aliases
\Method Encoding#name returns the name of an \Encoding:
@@ -78,7 +78,7 @@ because it includes both the names and their aliases.
Encoding.find("US-ASCII") # => #<Encoding:US-ASCII>
Encoding.find("US-ASCII").class # => Encoding
-=== Default Encodings
+==== Default Encodings
\Method Encoding.find, above, also returns a default \Encoding
for each of these special names:
@@ -118,7 +118,7 @@ for each of these special names:
Encoding.default_internal = 'US-ASCII' # => "US-ASCII"
Encoding.default_internal # => #<Encoding:US-ASCII>
-=== Compatible Encodings
+==== Compatible Encodings
\Method Encoding.compatible? returns whether two given objects are encoding-compatible
(that is, whether they can be concatenated);
@@ -132,21 +132,20 @@ returns the \Encoding of the concatenated string, or +nil+ if incompatible:
s1 = "\xa1\xa1".force_encoding('euc-jp') # => "\x{A1A1}"
Encoding.compatible?(s0, s1) # => nil
-== \String \Encoding
+=== \String \Encoding
A Ruby String object has an encoding that is an instance of class \Encoding.
The encoding may be retrieved by method String#encoding.
-The default encoding for a string literal is the script encoding;
-see {Script Encoding}[rdoc-ref:encodings.rdoc@Script+Encoding].
+The default encoding for a string literal is the script encoding
+(see Encoding@Script+encoding):
's'.encoding # => #<Encoding:UTF-8>
The default encoding for a string created with method String.new is:
- For a \String object argument, the encoding of that string.
-- For a string literal, the script encoding;
- see {Script Encoding}[rdoc-ref:encodings.rdoc@Script+Encoding].
+- For a string literal, the script encoding (see Encoding@Script+encoding).
In either case, any encoding may be specified:
@@ -183,7 +182,7 @@ Here are a couple of useful query methods:
s = "\xc2".force_encoding("UTF-8") # => "\xC2"
s.valid_encoding? # => false
-== \Symbol and \Regexp Encodings
+=== \Symbol and \Regexp Encodings
The string stored in a Symbol or Regexp object also has an encoding;
the encoding may be retrieved by method Symbol#encoding or Regexp#encoding.
@@ -191,23 +190,22 @@ the encoding may be retrieved by method Symbol#encoding or Regexp#encoding.
The default encoding for these, however, is:
- US-ASCII, if all characters are US-ASCII.
-- The script encoding, otherwise;
- see (Script Encoding)[rdoc-ref:encodings.rdoc@Script+Encoding].
+- The script encoding, otherwise (see Encoding@Script+encoding).
-== Filesystem \Encoding
+=== Filesystem \Encoding
The filesystem encoding is the default \Encoding for a string from the filesystem:
Encoding.find("filesystem") # => #<Encoding:UTF-8>
-== Locale \Encoding
+=== Locale \Encoding
The locale encoding is the default encoding for a string from the environment,
other than from the filesystem:
Encoding.find('locale') # => #<Encoding:IBM437>
-== Stream Encodings
+=== Stream Encodings
Certain stream objects can have two encodings; these objects include instances of:
@@ -222,7 +220,7 @@ The two encodings are:
- An _internal_ _encoding_, which (if not +nil+) specifies the encoding
to be used for the string constructed from the stream.
-=== External \Encoding
+==== External \Encoding
The external encoding, which is an \Encoding object, specifies how bytes read
from the stream are to be interpreted as characters.
@@ -250,7 +248,7 @@ For an \IO, \File, \ARGF, or \StringIO object, the external encoding may be set
- \Methods +set_encoding+ or (except for \ARGF) +set_encoding_by_bom+.
-=== Internal \Encoding
+==== Internal \Encoding
The internal encoding, which is an \Encoding object or +nil+,
specifies how characters read from the stream
@@ -276,7 +274,7 @@ For an \IO, \File, \ARGF, or \StringIO object, the internal encoding may be set
- \Method +set_encoding+.
-== Script \Encoding
+=== Script \Encoding
A Ruby script has a script encoding, which may be retrieved by:
@@ -291,7 +289,7 @@ followed by a colon, space and the Encoding name or alias:
# encoding: ISO-8859-1
__ENCODING__ #=> #<Encoding:ISO-8859-1>
-== Transcoding
+=== Transcoding
_Transcoding_ is the process of changing a sequence of characters
from one encoding to another.
@@ -302,7 +300,7 @@ but the bytes that represent them may change.
The handling for characters that cannot be represented in the destination encoding
may be specified by @Encoding+Options.
-=== Transcoding a \String
+==== Transcoding a \String
Each of these methods transcodes a string:
@@ -317,7 +315,7 @@ Each of these methods transcodes a string:
- String#unicode_normalize!: Like String#unicode_normalize,
but transcodes +self+ in place.
-== Transcoding a Stream
+=== Transcoding a Stream
Each of these methods may transcode a stream;
whether it does so depends on the external and internal encodings:
@@ -352,7 +350,7 @@ Output:
"R\xE9sum\xE9"
"Résumé"
-== \Encoding Options
+=== \Encoding Options
A number of methods in the Ruby core accept keyword arguments as encoding options.
diff --git a/doc/extension.ja.rdoc b/doc/extension.ja.rdoc
index bde907c916..93f5753cd1 100644
--- a/doc/extension.ja.rdoc
+++ b/doc/extension.ja.rdoc
@@ -888,12 +888,12 @@ dbm.cã§ã¯TypedData_Make_Structを以下ã®ã‚ˆã†ã«ä½¿ã£ã¦ã„ã¾ã™ï¼Ž
obj = TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp);
-ã“ã“ã§ã¯dbmdata構造体ã¸ã®ãƒã‚¤ãƒ³ã‚¿ã‚’Rubyオブジェクトã«ã‚«ãƒ—ã‚»
-ル化ã—ã¦ã„ã¾ã™ï¼ŽDBM*を直接カプセル化ã—ãªã„ã®ã¯close()ã—ãŸæ™‚
-ã®å‡¦ç†ã‚’考ãˆã¦ã®ã“ã¨ã§ã™ï¼Ž
+ã“ã“ã§ã¯dbmdata構造体ã¸ã®ãƒã‚¤ãƒ³ã‚¿ã‚’Dataã«ã‚«ãƒ—セル化ã—ã¦ã„
+ã¾ã™ï¼ŽDBM*を直接カプセル化ã—ãªã„ã®ã¯close()ã—ãŸæ™‚ã®å‡¦ç†ã‚’考
+ãˆã¦ã®ã“ã¨ã§ã™ï¼Ž
-Rubyオブジェクトã‹ã‚‰dbmdata構造体ã®ãƒã‚¤ãƒ³ã‚¿ã‚’å–り出ã™ãŸã‚ã«
-以下ã®ãƒžã‚¯ãƒ­ã‚’使ã£ã¦ã„ã¾ã™ï¼Ž
+Dataオブジェクトã‹ã‚‰dbmstruct構造体ã®ãƒã‚¤ãƒ³ã‚¿ã‚’å–り出ã™ãŸã‚
+ã«ä»¥ä¸‹ã®ãƒžã‚¯ãƒ­ã‚’使ã£ã¦ã„ã¾ã™ï¼Ž
#define GetDBM(obj, dbmp) do {\
TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
diff --git a/doc/extension.rdoc b/doc/extension.rdoc
index f0e12f27f2..ad9ae641d2 100644
--- a/doc/extension.rdoc
+++ b/doc/extension.rdoc
@@ -1,6 +1,6 @@
# extension.rdoc - -*- RDoc -*- created at: Mon Aug 7 16:45:54 JST 1995
-= Creating extension libraries for Ruby
+= Creating Extension Libraries for Ruby
This document explains how to make extension libraries for Ruby.
@@ -10,8 +10,8 @@ In C, variables have types and data do not have types. In contrast,
Ruby variables do not have a static type, and data themselves have
types, so data will need to be converted between the languages.
-Objects in Ruby are represented by the C type `VALUE'. Each VALUE
-data has its data type.
+Data in Ruby are represented by the C type `VALUE'. Each VALUE data
+has its data type.
To retrieve C data from a VALUE, you need to:
@@ -20,7 +20,7 @@ To retrieve C data from a VALUE, you need to:
Converting to the wrong data type may cause serious problems.
-=== Ruby data types
+=== Data Types
The Ruby interpreter has the following data types:
@@ -54,7 +54,7 @@ T_ZOMBIE :: object awaiting finalization
Most of the types are represented by C structures.
-=== Check type of the VALUE data
+=== Check Data Type of the VALUE
The macro TYPE() defined in ruby.h shows the data type of the VALUE.
TYPE() returns the constant number T_XXXX described above. To handle
@@ -88,7 +88,7 @@ There are also faster check macros for fixnums and nil.
FIXNUM_P(obj)
NIL_P(obj)
-=== Convert VALUE into C data
+=== Convert VALUE into C Data
The data for type T_NIL, T_FALSE, T_TRUE are nil, false, true
respectively. They are singletons for the data type.
@@ -143,7 +143,7 @@ Notice: Do not change the value of the structure directly, unless you
are responsible for the result. This ends up being the cause of
interesting bugs.
-=== Convert C data into VALUE
+=== Convert C Data into VALUE
To convert C data to Ruby values:
@@ -169,14 +169,14 @@ INT2NUM() :: for arbitrary sized integers.
INT2NUM() converts an integer into a Bignum if it is out of the FIXNUM
range, but is a bit slower.
-=== Manipulating Ruby object
+=== Manipulating Ruby Data
As I already mentioned, it is not recommended to modify an object's
internal structure. To manipulate objects, use the functions supplied
by the Ruby interpreter. Some (not all) of the useful functions are
listed below:
-==== String functions
+==== String Functions
rb_str_new(const char *ptr, long len) ::
@@ -279,7 +279,7 @@ rb_str_modify(VALUE str) ::
you MUST call this function before modifying the contents using
RSTRING_PTR and/or rb_str_set_len.
-==== Array functions
+==== Array Functions
rb_ary_new() ::
@@ -338,13 +338,13 @@ rb_ary_cat(VALUE ary, const VALUE *ptr, long len) ::
== Extending Ruby with C
-=== Adding new features to Ruby
+=== Adding New Features to Ruby
You can add new features (classes, methods, etc.) to the Ruby
interpreter. Ruby provides APIs for defining the following things:
- Classes, Modules
-- Methods, singleton methods
+- Methods, Singleton Methods
- Constants
==== Class and Module Definition
@@ -362,7 +362,7 @@ To define nested classes or modules, use the functions below:
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
VALUE rb_define_module_under(VALUE outer, const char *name)
-==== Method and singleton method definition
+==== Method and Singleton Method Definition
To define methods or singleton methods, use these functions:
@@ -467,7 +467,7 @@ available), you can use:
VALUE rb_current_receiver(void)
-==== Constant definition
+==== Constant Definition
We have 2 functions to define constants:
@@ -477,11 +477,11 @@ We have 2 functions to define constants:
The former is to define a constant under specified class/module. The
latter is to define a global constant.
-=== Use Ruby features from C
+=== Use Ruby Features from C
There are several ways to invoke Ruby's features from C code.
-==== Evaluate Ruby programs in a string
+==== Evaluate Ruby Programs in a String
The easiest way to use Ruby's functionality from a C program is to
evaluate the string as Ruby program. This function will do the job:
@@ -550,7 +550,7 @@ and to convert Ruby Symbol object to ID, use
ID SYM2ID(VALUE symbol)
-==== Invoke Ruby method from C
+==== Invoke Ruby Method from C
To invoke methods directly, you can use the function below
@@ -559,7 +559,7 @@ To invoke methods directly, you can use the function below
This function invokes a method on the recv, with the method name
specified by the symbol mid.
-==== Accessing the variables and constants
+==== Accessing the Variables and Constants
You can access class variables and instance variables using access
functions. Also, global variables can be shared between both
@@ -578,9 +578,9 @@ To access the constants of the class/module:
See also Constant Definition above.
-== Information sharing between Ruby and C
+== Information Sharing Between Ruby and C
-=== Ruby constants that can be accessed from C
+=== Ruby Constants That Can Be Accessed From C
As stated in section 1.3,
the following Ruby constants can be referred from C.
@@ -594,7 +594,7 @@ Qnil ::
Ruby nil in C scope.
-=== Global variables shared between C and Ruby
+=== Global Variables Shared Between C and Ruby
Information can be shared between the two environments using shared global
variables. To define them, you can use functions listed below:
@@ -636,7 +636,7 @@ The prototypes of the getter and setter functions are as follows:
VALUE (*getter)(ID id);
void (*setter)(VALUE val, ID id);
-=== Encapsulate C data into a Ruby object
+=== Encapsulate C Data into a Ruby Object
Sometimes you need to expose your struct in the C world as a Ruby
object.
@@ -762,7 +762,7 @@ You can allocate and wrap the structure in one step.
TypedData_Make_Struct(klass, type, data_type, sval)
-This macro returns an allocated T_DATA object, wrapping the pointer to
+This macro returns an allocated Data object, wrapping the pointer to
the structure, which is also allocated. This macro works like:
(sval = ZALLOC(type), TypedData_Wrap_Struct(klass, data_type, sval))
@@ -771,66 +771,9 @@ Arguments klass and data_type work like their counterparts in
TypedData_Wrap_Struct(). A pointer to the allocated structure will
be assigned to sval, which should be a pointer of the type specified.
-==== Declaratively marking/compacting struct references
-
-In the case where your struct refers to Ruby objects that are simple values,
-not wrapped in conditional logic or complex data structures an alternative
-approach to marking and reference updating is provided, by declaring offset
-references to the VALUES in your struct.
-
-Doing this allows the Ruby GC to support marking these references and GC
-compaction without the need to define the +dmark+ and +dcompact+ callbacks.
-
-You must define a static list of VALUE pointers to the offsets within your
-struct where the references are located, and set the "data" member to point to
-this reference list. The reference list must end with +RUBY_END_REFS+.
-
-Some Macros have been provided to make edge referencing easier:
-
-* <code>RUBY_TYPED_DECL_MARKING</code> =A flag that can be set on the +ruby_data_type_t+ to indicate that references are being declared as edges.
-
-* <code>RUBY_REFERENCES(ref_list_name)</code> - Define _ref_list_name_ as a list of references
-
-* <code>RUBY_REF_END</code> - The end mark of the references list.
-
-* <code>RUBY_REF_EDGE(struct, member)</code> - Declare _member_ as a VALUE edge from _struct_. Use this after +RUBY_REFERENCES_START+
-
-* +RUBY_REFS_LIST_PTR+ - Coerce the reference list into a format that can be
- accepted by the existing +dmark+ interface.
-
-The example below is from Dir (defined in +dir.c+)
-
- // The struct being wrapped. Notice this contains 3 members of which the second
- // is a VALUE reference to another ruby object.
- struct dir_data {
- DIR *dir;
- const VALUE path;
- rb_encoding *enc;
- }
-
- // Define a reference list `dir_refs` containing a single entry to `path`.
- // Needs terminating with RUBY_REF_END
- RUBY_REFERENCES(dir_refs) = {
- RUBY_REF_EDGE(dir_data, path),
- RUBY_REF_END
- };
-
- // Override the "dmark" field with the defined reference list now that we
- // no longer need a marking callback and add RUBY_TYPED_DECL_MARKING to the
- // flags field
- static const rb_data_type_t dir_data_type = {
- "dir",
- {RUBY_REFS_LIST_PTR(dir_refs), dir_free, dir_memsize,},
- 0, NULL, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_DECL_MARKING
- };
-
-Declaring simple references declaratively in this manner allows the GC to both
-mark, and move the underlying object, and automatically update the reference to
-it during compaction.
-
==== Ruby object to C struct
-To retrieve the C pointer from the T_DATA object, use the macro
+To retrieve the C pointer from the Data object, use the macro
TypedData_Get_Struct().
TypedData_Get_Struct(obj, type, &data_type, sval)
@@ -845,7 +788,7 @@ OK, here's the example of making an extension library. This is the
extension to access DBMs. The full source is included in the ext/
directory in the Ruby's source tree.
-=== Make the directory
+=== Make the Directory
% mkdir ext/dbm
@@ -1056,7 +999,7 @@ If a compilation condition is not fulfilled, you should not call
``create_makefile''. The Makefile will not be generated, compilation will
not be done.
-=== Prepare depend (Optional)
+=== Prepare Depend (Optional)
If the file named depend exists, Makefile will include that file to
check dependencies. You can make this file by invoking
@@ -1095,15 +1038,15 @@ You may need to rb_debug the extension. Extensions can be linked
statically by adding the directory name in the ext/Setup file so that
you can inspect the extension with the debugger.
-=== Done! Now you have the extension library
+=== Done! Now You Have the Extension Library
You can do anything you want with your library. The author of Ruby
will not claim any restrictions on your code depending on the Ruby API.
Feel free to use, modify, distribute or sell your program.
-== Appendix A. Ruby header and source files overview
+== Appendix A. Ruby Header and Source Files Overview
-=== Ruby header files
+=== Ruby Header Files
Everything under <tt>$repo_root/include/ruby</tt> is installed with
<tt>make install</tt>.
@@ -1120,7 +1063,7 @@ Header files under <tt>$repo_root/internal/</tt> or directly under the
root <tt>$repo_root/*.h</tt> are not make-installed.
They are internal headers with only internal APIs.
-=== Ruby language core
+=== Ruby Language Core
class.c :: classes and modules
error.c :: exception classes and exception mechanism
@@ -1129,14 +1072,14 @@ load.c :: library loading
object.c :: objects
variable.c :: variables and constants
-=== Ruby syntax parser
+=== Ruby Syntax Parser
parse.y :: grammar definition
parse.c :: automatically generated from parse.y
defs/keywords :: reserved keywords
lex.c :: automatically generated from keywords
-=== Ruby evaluator (a.k.a. YARV)
+=== Ruby Evaluator (a.k.a. YARV)
compile.c
eval.c
@@ -1162,7 +1105,7 @@ lex.c :: automatically generated from keywords
-> opt*.inc : automatically generated
-> vm.inc : automatically generated
-=== Regular expression engine (Onigumo)
+=== Regular Expression Engine (Onigumo)
regcomp.c
regenc.c
@@ -1171,7 +1114,7 @@ lex.c :: automatically generated from keywords
regparse.c
regsyntax.c
-=== Utility functions
+=== Utility Functions
debug.c :: debug symbols for C debugger
dln.c :: dynamic loading
@@ -1179,7 +1122,7 @@ st.c :: general purpose hash table
strftime.c :: formatting times
util.c :: misc utilities
-=== Ruby interpreter implementation
+=== Ruby Interpreter Implementation
dmyext.c
dmydln.c
@@ -1193,7 +1136,7 @@ util.c :: misc utilities
gem_prelude.rb
prelude.rb
-=== Class library
+=== Class Library
array.c :: Array
bignum.c :: Bignum
@@ -1232,13 +1175,13 @@ transcode.c :: Encoding::Converter
enc/*.c :: encoding classes
enc/trans/* :: codepoint mapping tables
-=== goruby interpreter implementation
+=== goruby Interpreter Implementation
goruby.c
golf_prelude.rb : goruby specific libraries.
-> golf_prelude.c : automatically generated
-== Appendix B. Ruby extension API reference
+== Appendix B. Ruby Extension API Reference
=== Types
@@ -1248,7 +1191,7 @@ VALUE ::
such as struct RString, etc. To refer the values in structures, use
casting macros like RSTRING(obj).
-=== Variables and constants
+=== Variables and Constants
Qnil ::
@@ -1262,7 +1205,7 @@ Qfalse ::
false object
-=== C pointer wrapping
+=== C Pointer Wrapping
Data_Wrap_Struct(VALUE klass, void (*mark)(), void (*free)(), void *sval) ::
@@ -1282,7 +1225,7 @@ Data_Get_Struct(data, type, sval) ::
This macro retrieves the pointer value from DATA, and assigns it to
the variable sval.
-=== Checking VALUE types
+=== Checking Data Types
RB_TYPE_P(value, type) ::
@@ -1312,7 +1255,7 @@ void Check_Type(VALUE value, int type) ::
Ensures +value+ is of the given internal +type+ or raises a TypeError
-=== VALUE type conversion
+=== Data Type Conversion
FIX2INT(value), INT2FIX(i) ::
@@ -1396,7 +1339,7 @@ rb_str_new2(s) ::
char * -> String
-=== Defining classes and modules
+=== Defining Classes and Modules
VALUE rb_define_class(const char *name, VALUE super) ::
@@ -1423,7 +1366,7 @@ void rb_extend_object(VALUE object, VALUE module) ::
Extend the object with the module's attributes.
-=== Defining global variables
+=== Defining Global Variables
void rb_define_variable(const char *name, VALUE *var) ::
@@ -1467,7 +1410,7 @@ void rb_gc_register_mark_object(VALUE object) ::
Tells GC to protect the +object+, which may not be referenced anywhere.
-=== Constant definition
+=== Constant Definition
void rb_define_const(VALUE klass, const char *name, VALUE val) ::
@@ -1479,7 +1422,7 @@ void rb_define_global_const(const char *name, VALUE val) ::
rb_define_const(rb_cObject, name, val)
-=== Method definition
+=== Method Definition
rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) ::
@@ -1655,7 +1598,7 @@ int rb_respond_to(VALUE obj, ID id) ::
Returns true if the object responds to the message specified by id.
-=== Instance variables
+=== Instance Variables
VALUE rb_iv_get(VALUE obj, const char *name) ::
@@ -1666,7 +1609,7 @@ VALUE rb_iv_set(VALUE obj, const char *name, VALUE val) ::
Sets the value of the instance variable.
-=== Control structure
+=== Control Structure
VALUE rb_block_call(VALUE recv, ID mid, int argc, VALUE * argv, VALUE (*func) (ANYARGS), VALUE data2) ::
@@ -1762,7 +1705,7 @@ void rb_iter_break_value(VALUE value) ::
return the given argument value. This function never return to the
caller.
-=== Exceptions and errors
+=== Exceptions and Errors
void rb_warn(const char *fmt, ...) ::
@@ -1835,7 +1778,7 @@ int rb_wait_for_single_fd(int fd, int events, struct timeval *timeout) ::
Use a NULL +timeout+ to wait indefinitely.
-=== I/O multiplexing
+=== I/O Multiplexing
Ruby supports I/O multiplexing based on the select(2) system call.
The Linux select_tut(2) manpage
@@ -1887,7 +1830,7 @@ int rb_thread_fd_select(int nfds, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_
rb_io_wait_writable, or rb_wait_for_single_fd functions since
they can be optimized for specific platforms (currently, only Linux).
-=== Initialize and start the interpreter
+=== Initialize and Start the Interpreter
The embedding API functions are below (not needed for extension libraries):
@@ -1912,7 +1855,7 @@ void ruby_script(char *name) ::
Specifies the name of the script ($0).
-=== Hooks for the interpreter events
+=== Hooks for the Interpreter Events
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data) ::
@@ -1954,7 +1897,7 @@ void rb_gc_adjust_memory_usage(ssize_t diff) ::
is decreased; a memory block is freed or a block is reallocated as
smaller size. This function may trigger the GC.
-=== Macros for compatibility
+=== Macros for Compatibility
Some macros to check API compatibilities are available by default.
diff --git a/doc/format_specifications.rdoc b/doc/format_specifications.rdoc
index 1111575e74..e589524f27 100644
--- a/doc/format_specifications.rdoc
+++ b/doc/format_specifications.rdoc
@@ -1,4 +1,4 @@
-= Format Specifications
+== Format Specifications
Several Ruby core classes have instance method +printf+ or +sprintf+:
@@ -37,12 +37,12 @@ It consists of:
Except for the leading percent character,
the only required part is the type specifier, so we begin with that.
-== Type Specifiers
+=== Type Specifiers
This section provides a brief explanation of each type specifier.
The links lead to the details and examples.
-=== \Integer Type Specifiers
+==== \Integer Type Specifiers
- +b+ or +B+: Format +argument+ as a binary integer.
See {Specifiers b and B}[rdoc-ref:format_specifications.rdoc@Specifiers+b+and+B].
@@ -54,7 +54,7 @@ The links lead to the details and examples.
- +x+ or +X+: Format +argument+ as a hexadecimal integer.
See {Specifiers x and X}[rdoc-ref:format_specifications.rdoc@Specifiers+x+and+X].
-=== Floating-Point Type Specifiers
+==== Floating-Point Type Specifiers
- +a+ or +A+: Format +argument+ as hexadecimal floating-point number.
See {Specifiers a and A}[rdoc-ref:format_specifications.rdoc@Specifiers+a+and+A].
@@ -65,7 +65,7 @@ The links lead to the details and examples.
- +g+ or +G+: Format +argument+ in a "general" format.
See {Specifiers g and G}[rdoc-ref:format_specifications.rdoc@Specifiers+g+and+G].
-=== Other Type Specifiers
+==== Other Type Specifiers
- +c+: Format +argument+ as a character.
See {Specifier c}[rdoc-ref:format_specifications.rdoc@Specifier+c].
@@ -76,7 +76,7 @@ The links lead to the details and examples.
- <tt>%</tt>: Format +argument+ (<tt>'%'</tt>) as a single percent character.
See {Specifier %}[rdoc-ref:format_specifications.rdoc@Specifier+-25].
-== Flags
+=== Flags
The effect of a flag may vary greatly among type specifiers.
These remarks are general in nature.
@@ -85,7 +85,7 @@ See {type-specific details}[rdoc-ref:format_specifications.rdoc@Type+Specifier+D
Multiple flags may be given with single type specifier;
order does not matter.
-=== <tt>' '</tt> Flag
+==== <tt>' '</tt> Flag
Insert a space before a non-negative number:
@@ -97,49 +97,49 @@ Insert a minus sign for negative value:
sprintf('%d', -10) # => "-10"
sprintf('% d', -10) # => "-10"
-=== <tt>'#'</tt> Flag
+==== <tt>'#'</tt> Flag
Use an alternate format; varies among types:
sprintf('%x', 100) # => "64"
sprintf('%#x', 100) # => "0x64"
-=== <tt>'+'</tt> Flag
+==== <tt>'+'</tt> Flag
Add a leading plus sign for a non-negative number:
sprintf('%x', 100) # => "64"
sprintf('%+x', 100) # => "+64"
-=== <tt>'-'</tt> Flag
+==== <tt>'-'</tt> Flag
Left justify the value in its field:
sprintf('%6d', 100) # => " 100"
sprintf('%-6d', 100) # => "100 "
-=== <tt>'0'</tt> Flag
+==== <tt>'0'</tt> Flag
Left-pad with zeros instead of spaces:
sprintf('%6d', 100) # => " 100"
sprintf('%06d', 100) # => "000100"
-=== <tt>'*'</tt> Flag
+==== <tt>'*'</tt> Flag
Use the next argument as the field width:
sprintf('%d', 20, 14) # => "20"
sprintf('%*d', 20, 14) # => " 14"
-=== <tt>'n$'</tt> Flag
+==== <tt>'n$'</tt> Flag
Format the (1-based) <tt>n</tt>th argument into this field:
sprintf("%s %s", 'world', 'hello') # => "world hello"
sprintf("%2$s %1$s", 'world', 'hello') # => "hello world"
-== Width Specifier
+=== Width Specifier
In general, a width specifier determines the minimum width (in characters)
of the formatted field:
@@ -152,7 +152,7 @@ of the formatted field:
# Ignore if too small.
sprintf('%1d', 100) # => "100"
-== Precision Specifier
+=== Precision Specifier
A precision specifier is a decimal point followed by zero or more
decimal digits.
@@ -194,9 +194,9 @@ the number of characters to write:
sprintf('%s', Time.now) # => "2022-05-04 11:59:16 -0400"
sprintf('%.10s', Time.now) # => "2022-05-04"
-== Type Specifier Details and Examples
+=== Type Specifier Details and Examples
-=== Specifiers +a+ and +A+
+==== Specifiers +a+ and +A+
Format +argument+ as hexadecimal floating-point number:
@@ -209,7 +209,7 @@ Format +argument+ as hexadecimal floating-point number:
sprintf('%A', 4096) # => "0X1P+12"
sprintf('%A', -4096) # => "-0X1P+12"
-=== Specifiers +b+ and +B+
+==== Specifiers +b+ and +B+
The two specifiers +b+ and +B+ behave identically
except when flag <tt>'#'</tt>+ is used.
@@ -226,14 +226,14 @@ Format +argument+ as a binary integer:
sprintf('%#b', 4) # => "0b100"
sprintf('%#B', 4) # => "0B100"
-=== Specifier +c+
+==== Specifier +c+
Format +argument+ as a single character:
sprintf('%c', 'A') # => "A"
sprintf('%c', 65) # => "A"
-=== Specifier +d+
+==== Specifier +d+
Format +argument+ as a decimal integer:
@@ -242,7 +242,7 @@ Format +argument+ as a decimal integer:
Flag <tt>'#'</tt> does not apply.
-=== Specifiers +e+ and +E+
+==== Specifiers +e+ and +E+
Format +argument+ in
{scientific notation}[https://en.wikipedia.org/wiki/Scientific_notation]:
@@ -250,7 +250,7 @@ Format +argument+ in
sprintf('%e', 3.14159) # => "3.141590e+00"
sprintf('%E', -3.14159) # => "-3.141590E+00"
-=== Specifier +f+
+==== Specifier +f+
Format +argument+ as a floating-point number:
@@ -259,7 +259,7 @@ Format +argument+ as a floating-point number:
Flag <tt>'#'</tt> does not apply.
-=== Specifiers +g+ and +G+
+==== Specifiers +g+ and +G+
Format +argument+ using exponential form (+e+/+E+ specifier)
if the exponent is less than -4 or greater than or equal to the precision.
@@ -281,7 +281,7 @@ Otherwise format +argument+ using floating-point form (+f+ specifier):
sprintf('%#G', 100000000000) # => "1.00000E+11"
sprintf('%#G', 0.000000000001) # => "1.00000E-12"
-=== Specifier +o+
+==== Specifier +o+
Format +argument+ as an octal integer.
If +argument+ is negative, it will be formatted as a two's complement
@@ -296,14 +296,14 @@ prefixed with +..7+:
sprintf('%#o', 16) # => "020"
sprintf('%#o', -16) # => "..760"
-=== Specifier +p+
+==== Specifier +p+
Format +argument+ as a string via <tt>argument.inspect</tt>:
t = Time.now
sprintf('%p', t) # => "2022-05-01 13:42:07.1645683 -0500"
-=== Specifier +s+
+==== Specifier +s+
Format +argument+ as a string via <tt>argument.to_s</tt>:
@@ -312,7 +312,7 @@ Format +argument+ as a string via <tt>argument.to_s</tt>:
Flag <tt>'#'</tt> does not apply.
-=== Specifiers +x+ and +X+
+==== Specifiers +x+ and +X+
Format +argument+ as a hexadecimal integer.
If +argument+ is negative, it will be formatted as a two's complement
@@ -329,7 +329,7 @@ prefixed with +..f+:
# Alternate format for negative value.
sprintf('%#x', -100) # => "0x..f9c"
-=== Specifier <tt>%</tt>
+==== Specifier <tt>%</tt>
Format +argument+ (<tt>'%'</tt>) as a single percent character:
@@ -337,7 +337,7 @@ Format +argument+ (<tt>'%'</tt>) as a single percent character:
Flags do not apply.
-== Reference by Name
+=== Reference by Name
For more complex formatting, Ruby supports a reference by name.
%<name>s style uses format style, but %{name} style doesn't.
diff --git a/doc/globals.rdoc b/doc/globals.rdoc
index 1bf78a60ab..1d7cda69f9 100644
--- a/doc/globals.rdoc
+++ b/doc/globals.rdoc
@@ -1,422 +1,69 @@
-= Pre-Defined Global Variables
-
-Some of the pre-defined global variables have synonyms
-that are available via module Engish.
-For each of those, the \English synonym is given.
-
-To use the module:
-
- require 'English'
-
-== Exceptions
-
-=== <tt>$!</tt> (\Exception)
-
-Contains the Exception object set by Kernel#raise:
-
- begin
- raise RuntimeError.new('Boo!')
- rescue RuntimeError
- p $!
- end
-
-Output:
-
- #<RuntimeError: Boo!>
-
-English - <tt>$ERROR_INFO</tt>
-
-=== <tt>$@</tt> (Backtrace)
-
-Same as <tt>$!.backtrace</tt>;
-returns an array of backtrace positions:
-
- begin
- raise RuntimeError.new('Boo!')
- rescue RuntimeError
- pp $@.take(4)
- end
-
-Output:
-
- ["(irb):338:in `<top (required)>'",
- "/snap/ruby/317/lib/ruby/3.2.0/irb/workspace.rb:119:in `eval'",
- "/snap/ruby/317/lib/ruby/3.2.0/irb/workspace.rb:119:in `evaluate'",
- "/snap/ruby/317/lib/ruby/3.2.0/irb/context.rb:502:in `evaluate'"]
-
-English - <tt>$ERROR_POSITION</tt>.
-
-== Pattern Matching
-
-These global variables store information about the most recent
-successful match in the current scope.
-
-For details and examples,
-see {Regexp Global Variables}[rdoc-ref:Regexp@Global+Variables].
-
-=== <tt>$~</tt> (\MatchData)
-
-MatchData object created from the match;
-thread-local and frame-local.
-
-English - <tt>$LAST_MATCH_INFO</tt>.
-
-=== <tt>$&</tt> (Matched Substring)
-
-The matched string.
-
-English - <tt>$MATCH</tt>.
-
-=== <tt>$`</tt> (Pre-Match Substring)
-
-The string to the left of the match.
-
-English - <tt>$PREMATCH</tt>.
-
-=== <tt>$'</tt> (Post-Match Substring)
-
-The string to the right of the match.
-
-English - <tt>$POSTMATCH</tt>.
-
-=== <tt>$+</tt> (Last Matched Group)
-
-The last group matched.
-
-English - <tt>$LAST_PAREN_MATCH</tt>.
-
-=== <tt>$1</tt>, <tt>$2</tt>, \Etc. (Matched Group)
-
-For <tt>$_n_</tt> the _nth_ group of the match.
-
-No \English.
-
-== Separators
-
-=== <tt>$/</tt> (Input Record Separator)
-
-An input record separator, initially newline.
-
-English - <tt>$INPUT_RECORD_SEPARATOR</tt>, <tt>$RS</tt>.
-
-Aliased as <tt>$-0</tt>.
-
-=== <tt>$;</tt> (Input Field Separator)
-
-An input field separator, initially +nil+.
-
-English - <tt>$FIELD_SEPARATOR</tt>, <tt>$FS</tt>.
-
-Aliased as <tt>$-F</tt>.
-
-=== <tt>$\\</tt> (Output Record Separator)
-
-An output record separator, initially +nil+.
-
-English - <tt>$OUTPUT_RECORD_SEPARATOR</tt>, <tt>$ORS</tt>.
-
-== Streams
-
-=== <tt>$stdin</tt> (Standard Input)
-
-The current standard input stream; initially:
-
- $stdin # => #<IO:<STDIN>>
-
-=== <tt>$stdout</tt> (Standard Output)
-
-The current standard output stream; initially:
-
- $stdout # => #<IO:<STDOUT>>
-
-=== <tt>$stderr</tt> (Standard Error)
-
-The current standard error stream; initially:
-
- $stderr # => #<IO:<STDERR>>
-
-=== <tt>$<</tt> (\ARGF or $stdin)
-
-Points to stream ARGF if not empty, else to stream $stdin; read-only.
-
-English - <tt>$DEFAULT_INPUT</tt>.
-
-=== <tt>$></tt> (Default Standard Output)
-
-An output stream, initially <tt>$stdout</tt>.
-
-English - <tt>$DEFAULT_OUTPUT
-
-=== <tt>$.</tt> (Input Position)
-
-The input position (line number) in the most recently read stream.
-
-English - <tt>$INPUT_LINE_NUMBER</tt>, <tt>$NR</tt>
-
-=== <tt>$_</tt> (Last Read Line)
-
-The line (string) from the most recently read stream.
-
-English - <tt>$LAST_READ_LINE</tt>.
-
-== Processes
-
-=== <tt>$0</tt>
-
-Initially, contains the name of the script being executed;
-may be reassigned.
-
-=== <tt>$*</tt> (\ARGV)
-
-Points to ARGV.
-
-English - <tt>$ARGV</tt>.
-
-=== <tt>$$</tt> (Process ID)
-
-The process ID of the current process. Same as Process.pid.
-
-English - <tt>$PROCESS_ID</tt>, <tt>$PID</tt>.
-
-=== <tt>$?</tt> (Child Status)
-
-Initially +nil+, otherwise the Process::Status object
-created for the most-recently exited child process;
-thread-local.
-
-English - <tt>$CHILD_STATUS</tt>.
-
-=== <tt>$LOAD_PATH</tt> (Load Path)
-
-Contains the array of paths to be searched
-by Kernel#load and Kernel#require.
-
-Singleton method <tt>$LOAD_PATH.resolve_feature_path(feature)</tt>
-returns:
-
-- <tt>[:rb, _path_]</tt>, where +path+ is the path to the Ruby file
- to be loaded for the given +feature+.
-- <tt>[:so+ _path_]</tt>, where +path+ is the path to the shared object file
- to be loaded for the given +feature+.
-- +nil+ if there is no such +feature+ and +path+.
-
-Examples:
-
- $LOAD_PATH.resolve_feature_path('timeout')
- # => [:rb, "/snap/ruby/317/lib/ruby/3.2.0/timeout.rb"]
- $LOAD_PATH.resolve_feature_path('date_core')
- # => [:so, "/snap/ruby/317/lib/ruby/3.2.0/x86_64-linux/date_core.so"]
- $LOAD_PATH.resolve_feature_path('foo')
- # => nil
-
-Aliased as <tt>$:</tt> and <tt>$-I</tt>.
-
-=== <tt>$LOADED_FEATURES</tt>
-
-Contains an array of the paths to the loaded files:
-
- $LOADED_FEATURES.take(10)
- # =>
- ["enumerator.so",
- "thread.rb",
- "fiber.so",
- "rational.so",
- "complex.so",
- "ruby2_keywords.rb",
- "/snap/ruby/317/lib/ruby/3.2.0/x86_64-linux/enc/encdb.so",
- "/snap/ruby/317/lib/ruby/3.2.0/x86_64-linux/enc/trans/transdb.so",
- "/snap/ruby/317/lib/ruby/3.2.0/x86_64-linux/rbconfig.rb",
- "/snap/ruby/317/lib/ruby/3.2.0/rubygems/compatibility.rb"]
-
-Aliased as <tt>$"</tt>.
-
-== Debugging
-
-=== <tt>$FILENAME</tt>
-
-The value returned by method ARGF.filename.
-
-=== <tt>$DEBUG</tt>
-
-Initially +true+ if command-line option <tt>-d</tt> or <tt>--debug</tt> is given,
-otherwise initially +false+;
-may be set to either value in the running program.
-
-When +true+, prints each raised exception to <tt>$stderr</tt>.
-
-Aliased as <tt>$-d</tt>.
-
-=== <tt>$VERBOSE</tt>
-
-Initially +true+ if command-line option <tt>-v</tt> or <tt>-w</tt> is given,
-otherwise initially +false+;
-may be set to either value, or to +nil+, in the running program.
-
-When +true+, enables Ruby warnings.
-
-When +nil+, disables warnings, including those from Kernel#warn.
-
-Aliased as <tt>$-v</tt> and <tt>$-w</tt>.
-
-== Other Variables
-
-=== <tt>$-a</tt>
-
-Whether command-line option <tt>-a</tt> was given; read-only.
-
-=== <tt>$-i</tt>
-
-Contains the extension given with command-line option <tt>-i</tt>,
-or +nil+ if none.
-
-An alias of ARGF.inplace_mode.
-
-=== <tt>$-l</tt>
-
-Whether command-line option <tt>-l</tt> was set; read-only.
-
-=== <tt>$-p</tt>
-
-Whether command-line option <tt>-p</tt> was given; read-only.
-
-== Deprecated
-
-=== <tt>$=</tt>
-
-=== <tt>$,</tt>
-
-= Pre-Defined Global Constants
-
-= Streams
-
-=== <tt>STDIN</tt>
-
-The standard input stream (the default value for <tt>$stdin</tt>):
-
- STDIN # => #<IO:<STDIN>>
-
-=== <tt>STDOUT</tt>
-
-The standard output stream (the default value for <tt>$stdout</tt>):
-
- STDOUT # => #<IO:<STDOUT>>
-
-=== <tt>STDERR</tt>
-
-The standard error stream (the default value for <tt>$stderr</tt>):
-
- STDERR # => #<IO:<STDERR>>
-
-== Environment
-
-=== ENV
-
-A hash of the contains current environment variables names and values:
-
- ENV.take(5)
- # =>
- [["COLORTERM", "truecolor"],
- ["DBUS_SESSION_BUS_ADDRESS", "unix:path=/run/user/1000/bus"],
- ["DESKTOP_SESSION", "ubuntu"],
- ["DISPLAY", ":0"],
- ["GDMSESSION", "ubuntu"]]
-
-=== ARGF
-
-The virtual concatenation of the files given on the command line, or from
-<tt>$stdin</tt> if no files were given, <tt>"-"</tt> is given, or after
-all files have been read.
-
-=== <tt>ARGV</tt>
-
-An array of the given command-line arguments.
-
-=== <tt>TOPLEVEL_BINDING</tt>
-
-The Binding of the top level scope:
-
- TOPLEVEL_BINDING # => #<Binding:0x00007f58da0da7c0>
-
-=== <tt>RUBY_VERSION</tt>
-
-The Ruby version:
-
- RUBY_VERSION # => "3.2.2"
-
-=== <tt>RUBY_RELEASE_DATE</tt>
-
-The release date string:
-
- RUBY_RELEASE_DATE # => "2023-03-30"
-
-=== <tt>RUBY_PLATFORM</tt>
-
-The platform identifier:
-
- RUBY_PLATFORM # => "x86_64-linux"
-
-=== <tt>RUBY_PATCHLEVEL</tt>
-
-The integer patch level for this Ruby:
-
- RUBY_PATCHLEVEL # => 53
-
-For a development build the patch level will be -1.
-
-=== <tt>RUBY_REVISION</tt>
-
-The git commit hash for this Ruby:
-
- RUBY_REVISION # => "e51014f9c05aa65cbf203442d37fef7c12390015"
-
-=== <tt>RUBY_COPYRIGHT</tt>
-
-The copyright string:
-
- RUBY_COPYRIGHT
- # => "ruby - Copyright (C) 1993-2023 Yukihiro Matsumoto"
-
-=== <tt>RUBY_ENGINE</tt>
-
-The name of the Ruby implementation:
-
- RUBY_ENGINE # => "ruby"
-
-=== <tt>RUBY_ENGINE_VERSION</tt>
-
-The version of the Ruby implementation:
-
- RUBY_ENGINE_VERSION # => "3.2.2"
-
-=== <tt>RUBY_DESCRIPTION</tt>
-
-The description of the Ruby implementation:
-
- RUBY_DESCRIPTION
- # => "ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]"
-
-== Embedded \Data
-
-=== <tt>DATA</tt>
-
-Defined if and only if the program has this line:
-
- __END__
-
-When defined, <tt>DATA</tt> is a File object
-containing the lines following the <tt>__END__</tt>,
-positioned at the first of those lines:
-
- p DATA
- DATA.each_line { |line| p line }
- __END__
- Foo
- Bar
- Baz
-
-Output:
-
- #<File:t.rb>
- "Foo\n"
- "Bar\n"
- "Baz\n"
+# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*-
+
+== Pre-defined global variables
+
+$!:: The Exception object set by Kernel#raise.
+$@:: The same as <code>$!.backtrace</code>.
+$~:: The information about the last match in the current scope (thread-local and frame-local).
+$&:: The string matched by the last successful match.
+$`:: The string to the left of the last successful match.
+$':: The string to the right of the last successful match.
+$+:: The highest group matched by the last successful match.
+$1:: The Nth group of the last successful match. May be > 1.
+$=:: This variable is no longer effective. Deprecated.
+$/:: The input record separator, newline by default. Aliased to $-0.
+$\:: The output record separator for Kernel#print and IO#write. Default is +nil+.
+$,:: The output field separator for Kernel#print and Array#join. Non-nil $, will be deprecated.
+$;:: The default separator for String#split. Non-nil $; will be deprecated. Aliased to $-F.
+$.:: The current input line number of the last file that was read.
+$<:: The same as ARGF.
+$>:: The default output stream for Kernel#print and Kernel#printf. $stdout by default.
+$_:: The last input line of string by gets or readline.
+$0:: Contains the name of the script being executed. May be assignable.
+$*:: The same as ARGV.
+$$:: The process number of the Ruby running this script. Same as Process.pid.
+$?:: The status of the last executed child process (thread-local).
+$LOAD_PATH:: Load path for searching Ruby scripts and extension libraries used
+ by Kernel#load and Kernel#require. Aliased to $: and $-I.
+ Has a singleton method <code>$LOAD_PATH.resolve_feature_path(feature)</code>
+ that returns [+:rb+ or +:so+, path], which resolves the feature to
+ the path the original Kernel#require method would load.
+$LOADED_FEATURES:: The array contains the module names loaded by require.
+ Aliased to $".
+$DEBUG:: The debug flag, which is set by the <tt>-d</tt> switch. Enabling debug
+ output prints each exception raised to $stderr (but not its
+ backtrace). Setting this to a true value enables debug output as
+ if <tt>-d</tt> were given on the command line. Setting this to a false
+ value disables debug output. Aliased to $-d.
+$FILENAME:: Current input filename from ARGF. Same as ARGF.filename.
+$stderr:: The current standard error output.
+$stdin:: The current standard input.
+$stdout:: The current standard output.
+$VERBOSE:: The verbose flag, which is set by the <tt>-w</tt> or <tt>-v</tt> switch.
+ Setting this to a true value enables warnings as if <tt>-w</tt> or <tt>-v</tt> were given
+ on the command line. Setting this to +nil+ disables warnings,
+ including from Kernel#warn. Aliased to $-v and $-w.
+$-a:: True if option <tt>-a</tt> is set. Read-only variable.
+$-i:: In in-place-edit mode, this variable holds the extension, otherwise +nil+.
+$-l:: True if option <tt>-l</tt> is set. Read-only variable.
+$-p:: True if option <tt>-p</tt> is set. Read-only variable.
+
+== Pre-defined global constants
+
+STDIN:: The standard input. The default value for $stdin.
+STDOUT:: The standard output. The default value for $stdout.
+STDERR:: The standard error output. The default value for $stderr.
+ENV:: The hash contains current environment variables.
+ARGF:: The virtual concatenation of the files given on command line (or from $stdin if no files were given).
+ARGV:: An Array of command line arguments given for the script.
+DATA:: The file object of the script, pointing just after <code>__END__</code>.
+TOPLEVEL_BINDING:: The Binding of the top level scope.
+RUBY_VERSION:: The Ruby language version.
+RUBY_RELEASE_DATE:: The release date string.
+RUBY_PLATFORM:: The platform identifier.
+RUBY_PATCHLEVEL:: The patchlevel for this Ruby. If this is a development build of Ruby the patchlevel will be -1.
+RUBY_REVISION:: The GIT commit hash for this Ruby.
+RUBY_COPYRIGHT:: The copyright string for Ruby.
+RUBY_ENGINE:: The name of the Ruby implementation.
+RUBY_ENGINE_VERSION:: The version of the Ruby implementation.
+RUBY_DESCRIPTION:: The same as <tt>ruby --version</tt>, a String describing various aspects of the Ruby implementation.
diff --git a/doc/implicit_conversion.rdoc b/doc/implicit_conversion.rdoc
index e244096125..ba15fa4bf4 100644
--- a/doc/implicit_conversion.rdoc
+++ b/doc/implicit_conversion.rdoc
@@ -1,4 +1,4 @@
-= Implicit Conversions
+== Implicit Conversions
Some Ruby methods accept one or more objects
that can be either:
@@ -15,7 +15,7 @@ a specific conversion method:
* Integer: +to_int+
* String: +to_str+
-== Array-Convertible Objects
+=== Array-Convertible Objects
An <i>Array-convertible object</i> is an object that:
@@ -69,7 +69,7 @@ This class is not Array-convertible (method +to_ary+ returns non-Array):
# Raises TypeError (can't convert NotArrayConvertible to Array (NotArrayConvertible#to_ary gives Symbol))
a.replace(NotArrayConvertible.new)
-== Hash-Convertible Objects
+=== Hash-Convertible Objects
A <i>Hash-convertible object</i> is an object that:
@@ -123,7 +123,7 @@ This class is not Hash-convertible (method +to_hash+ returns non-Hash):
# Raises TypeError (can't convert NotHashConvertible to Hash (ToHashReturnsNonHash#to_hash gives Symbol))
h.merge(NotHashConvertible.new)
-== Integer-Convertible Objects
+=== Integer-Convertible Objects
An <i>Integer-convertible object</i> is an object that:
@@ -171,7 +171,7 @@ This class is not Integer-convertible (method +to_int+ returns non-Integer):
# Raises TypeError (can't convert NotIntegerConvertible to Integer (NotIntegerConvertible#to_int gives Symbol))
Array.new(NotIntegerConvertible.new)
-== String-Convertible Objects
+=== String-Convertible Objects
A <i>String-convertible object</i> is an object that:
* Has instance method +to_str+.
diff --git a/doc/irb/indexes.md b/doc/irb/indexes.md
deleted file mode 100644
index 24a67b9698..0000000000
--- a/doc/irb/indexes.md
+++ /dev/null
@@ -1,189 +0,0 @@
-## Indexes
-
-### Index of Command-Line Options
-
-These are the \IRB command-line options, with links to explanatory text:
-
-- `-d`: Set `$DEBUG` and {$VERBOSE}[rdoc-ref:IRB@Verbosity]
- to `true`.
-- `-E _ex_[:_in_]`: Set initial external (ex) and internal (in)
- {encodings}[rdoc-ref:IRB@Encodings] (same as `ruby -E>`).
-- `-f`: Don't initialize from {configuration file}[rdoc-ref:IRB@Configuration+File].
-- `-I _dirpath_`: Specify {$LOAD_PATH directory}[rdoc-ref:IRB@Load+Modules]
- (same as `ruby -I`).
-- `-r _load-module_`: Require {load-module}[rdoc-ref:IRB@Load+Modules]
- (same as `ruby -r`).
-- `-U`: Set external and internal {encodings}[rdoc-ref:IRB@Encodings] to UTF-8.
-- `-w`: Suppress {warnings}[rdoc-ref:IRB@Warnings] (same as `ruby -w`).
-- `-W[_level_]`: Set {warning level}[rdoc-ref:IRB@Warnings];
- 0=silence, 1=medium, 2=verbose (same as `ruby -W`).
-- `--autocomplete`: Use {auto-completion}[rdoc-ref:IRB@Automatic+Completion].
-- `--back-trace-limit _n_`: Set a {backtrace limit}[rdoc-ref:IRB@Tracer];
- display at most the top `n` and bottom `n` entries.
-- `--colorize`: Use {color-highlighting}[rdoc-ref:IRB@Color+Highlighting]
- for input and output.
-- `--context-mode _n_`: Select method to create Binding object
- for new {workspace}[rdoc-ref:IRB@Commands]; `n` in range `0..4`.
-- `--echo`: Print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- return values.
-- `--extra-doc-dir _dirpath_`:
- Add a {documentation directory}[rdoc-ref:IRB@RI+Documentation+Directories]
- for the documentation dialog.
-- `--inf-ruby-mode`: Set prompt mode to {:INF_RUBY}[rdoc-ref:IRB@Pre-Defined+Prompts]
- (appropriate for `inf-ruby-mode` on Emacs);
- suppresses --multiline and --singleline.
-- `--inspect`: Use method `inspect` for printing ({echoing}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- return values.
-- `--multiline`: Use the multiline editor as the {input method}[rdoc-ref:IRB@Input+Method].
-- `--noautocomplete`: Don't use {auto-completion}[rdoc-ref:IRB@Automatic+Completion].
-- `--nocolorize`: Don't use {color-highlighting}[rdoc-ref:IRB@Color+Highlighting]
- for input and output.
-- `--noecho`: Don't print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- return values.
-- `--noecho-on-assignment`: Don't print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- result on assignment.
-- `--noinspect`: Don't se method `inspect` for printing ({echoing}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- return values.
-- `--nomultiline`: Don't use the multiline editor as the {input method}[rdoc-ref:IRB@Input+Method].
-- `--noprompt`: Don't print {prompts}[rdoc-ref:IRB@Prompt+and+Return+Formats].
-- `--noscript`: Treat the first command-line argument as a normal
- {command-line argument}[rdoc-ref:IRB@Initialization+Script],
- and include it in `ARGV`.
-- `--nosingleline`: Don't use the singleline editor as the {input method}[rdoc-ref:IRB@Input+Method].
-- `--noverbose`Don't print {verbose}[rdoc-ref:IRB@Verbosity] details.
-- `--prompt _mode_`, `--prompt-mode _mode_`:
- Set {prompt and return formats}[rdoc-ref:IRB@Prompt+and+Return+Formats];
- `mode` may be a {pre-defined prompt}[rdoc-ref:IRB@Pre-Defined+Prompts]
- or the name of a {custom prompt}[rdoc-ref:IRB@Custom+Prompts].
-- `--script`: Treat the first command-line argument as the path to an
- {initialization script}[rdoc-ref:IRB@Initialization+Script],
- and omit it from `ARGV`.
-- `--simple-prompt`, `--sample-book-mode`:
- Set prompt mode to {:SIMPLE}[rdoc-ref:IRB@Pre-Defined+Prompts].
-- `--singleline`: Use the singleline editor as the {input method}[rdoc-ref:IRB@Input+Method].
-- `--tracer`: Use {Tracer}[rdoc-ref:IRB@Tracer] to print a stack trace for each input command.
-- `--truncate-echo-on-assignment`: Print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- truncated result on assignment.
-- `--verbose`Print {verbose}[rdoc-ref:IRB@Verbosity] details.
-- `-v`, `--version`: Print the {IRB version}[rdoc-ref:IRB@Version].
-- `-h`, `--help`: Print the {IRB help text}[rdoc-ref:IRB@Help].
-- `--`: Separate options from {arguments}[rdoc-ref:IRB@Command-Line+Arguments]
- on the command-line.
-
-### Index of \IRB.conf Entries
-
-These are the keys for hash \IRB.conf entries, with links to explanatory text;
-for each entry that is pre-defined, the initial value is given:
-
-- `:AP_NAME`: \IRB {application name}[rdoc-ref:IRB@Application+Name];
- initial value: `'irb'`.
-- `:AT_EXIT`: Array of hooks to call
- {at exit}[rdoc-ref:IRB@IRB];
- initial value: `[]`.
-- `:AUTO_INDENT`: Whether {automatic indentation}[rdoc-ref:IRB@Automatic+Indentation]
- is enabled; initial value: `true`.
-- `:BACK_TRACE_LIMIT`: Sets the {back trace limit}[rdoc-ref:IRB@Tracer];
- initial value: `16`.
-- `:COMMAND_ALIASES`: Defines input {command aliases}[rdoc-ref:IRB@Command+Aliases];
- initial value:
-
- {
- "$": :show_source,
- "@": :whereami,
- }
-
-- `:CONTEXT_MODE`: Sets the {context mode}[rdoc-ref:IRB@Context+Mode],
- the type of binding to be used when evaluating statements;
- initial value: `4`.
-- `:ECHO`: Whether to print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- return values;
- initial value: `nil`, which would set `conf.echo` to `true`.
-- `:ECHO_ON_ASSIGNMENT`: Whether to print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29])
- return values on assignment;
- initial value: `nil`, which would set `conf.echo_on_assignment` to `:truncate`.
-- `:EVAL_HISTORY`: How much {evaluation history}[rdoc-ref:IRB@Evaluation+History]
- is to be stored; initial value: `nil`.
-- `:EXTRA_DOC_DIRS`: \Array of
- {RI documentation directories}[rdoc-ref:IRB@RI+Documentation+Directories]
- to be parsed for the documentation dialog;
- initial value: `[]`.
-- `:IGNORE_EOF`: Whether to ignore {end-of-file}[rdoc-ref:IRB@End-of-File];
- initial value: `false`.
-- `:IGNORE_SIGINT`: Whether to ignore {SIGINT}[rdoc-ref:IRB@SIGINT];
- initial value: `true`.
-- `:INSPECT_MODE`: Whether to use method `inspect` for printing
- ({echoing}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29]) return values;
- initial value: `true`.
-- `:IRB_LIB_PATH`: The path to the {IRB library directory}[rdoc-ref:IRB@IRB+Library+Directory]; initial value:
-
- - `"<i>RUBY_DIR</i>/lib/ruby/gems/<i>RUBY_VER_NUM</i>/gems/irb-<i>IRB_VER_NUM</i>/lib/irb"`,
-
- where:
-
- - <i>RUBY_DIR</i> is the Ruby installation dirpath.
- - <i>RUBY_VER_NUM</i> is the Ruby version number.
- - <i>IRB_VER_NUM</i> is the \IRB version number.
-
-- `:IRB_NAME`: {IRB name}[rdoc-ref:IRB@IRB+Name];
- initial value: `'irb'`.
-- `:IRB_RC`: {Configuration monitor}[rdoc-ref:IRB@Configuration+Monitor];
- initial value: `nil`.
-- `:LC_MESSAGES`: {Locale}[rdoc-ref:IRB@Locale];
- initial value: IRB::Locale object.
-- `:LOAD_MODULES`: deprecated.
-- `:MAIN_CONTEXT`: The {context}[rdoc-ref:IRB@Session+Context] for the main \IRB session;
- initial value: IRB::Context object.
-- `:MEASURE`: Whether to
- {measure performance}[rdoc-ref:IRB@Performance+Measurement];
- initial value: `false`.
-- `:MEASURE_CALLBACKS`: Callback methods for
- {performance measurement}[rdoc-ref:IRB@Performance+Measurement];
- initial value: `[]`.
-- `:MEASURE_PROC`: Procs for
- {performance measurement}[rdoc-ref:IRB@Performance+Measurement];
- initial value:
-
- {
- :TIME=>#<Proc:0x0000556e271c6598 /var/lib/gems/3.0.0/gems/irb-1.8.3/lib/irb/init.rb:106>,
- :STACKPROF=>#<Proc:0x0000556e271c6548 /var/lib/gems/3.0.0/gems/irb-1.8.3/lib/irb/init.rb:116>
- }
-
-- `:PROMPT`: \Hash of {defined prompts}[rdoc-ref:IRB@Prompt+and+Return+Formats];
- initial value:
-
- {
- :NULL=>{:PROMPT_I=>nil, :PROMPT_S=>nil, :PROMPT_C=>nil, :RETURN=>"%s\n"},
- :DEFAULT=>{:PROMPT_I=>"%N(%m):%03n> ", :PROMPT_S=>"%N(%m):%03n%l ", :PROMPT_C=>"%N(%m):%03n* ", :RETURN=>"=> %s\n"},
- :CLASSIC=>{:PROMPT_I=>"%N(%m):%03n:%i> ", :PROMPT_S=>"%N(%m):%03n:%i%l ", :PROMPT_C=>"%N(%m):%03n:%i* ", :RETURN=>"%s\n"},
- :SIMPLE=>{:PROMPT_I=>">> ", :PROMPT_S=>"%l> ", :PROMPT_C=>"?> ", :RETURN=>"=> %s\n"},
- :INF_RUBY=>{:PROMPT_I=>"%N(%m):%03n> ", :PROMPT_S=>nil, :PROMPT_C=>nil, :RETURN=>"%s\n", :AUTO_INDENT=>true},
- :XMP=>{:PROMPT_I=>nil, :PROMPT_S=>nil, :PROMPT_C=>nil, :RETURN=>" ==>%s\n"}
- }
-
-- `:PROMPT_MODE`: Name of {current prompt}[rdoc-ref:IRB@Prompt+and+Return+Formats];
- initial value: `:DEFAULT`.
-- `:RC`: Whether a {configuration file}[rdoc-ref:IRB@Configuration+File]
- was found and interpreted;
- initial value: `true` if a configuration file was found, `false` otherwise.
-- `:SAVE_HISTORY`: Number of commands to save in
- {input command history}[rdoc-ref:IRB@Input+Command+History];
- initial value: `1000`.
-- `:SINGLE_IRB`: Whether command-line option `--single-irb` was given;
- initial value: `true` if the option was given, `false` otherwise.
- See {Single-IRB Mode}[rdoc-ref:IRB@Single-IRB+Mode].
-- `:USE_AUTOCOMPLETE`: Whether to use
- {automatic completion}[rdoc-ref:IRB@Automatic+Completion];
- initial value: `true`.
-- `:USE_COLORIZE`: Whether to use
- {color highlighting}[rdoc-ref:IRB@Color+Highlighting];
- initial value: `true`.
-- `:USE_LOADER`: Whether to use the
- {IRB loader}[rdoc-ref:IRB@IRB+Loader] for `require` and `load`;
- initial value: `false`.
-- `:USE_TRACER`: Whether to use the
- {IRB tracer}[rdoc-ref:IRB@Tracer];
- initial value: `false`.
-- `:VERBOSE`: Whether to print {verbose output}[rdoc-ref:IRB@Verbosity];
- initial value: `nil`.
-- `:__MAIN__`: The main \IRB object;
- initial value: `main`.
diff --git a/doc/irb/irb.rd.ja b/doc/irb/irb.rd.ja
index c51e0bd60d..633c08cbd4 100644
--- a/doc/irb/irb.rd.ja
+++ b/doc/irb/irb.rd.ja
@@ -125,6 +125,7 @@ irb起動時ã«``~/.irbrc''を読ã¿è¾¼ã¿ã¾ã™. ã‚‚ã—存在ã—ãªã„å ´åˆã¯
IRB.conf[:PROMPT][:MY_PROMPT] = { # プロンプトモードã®åå‰
:PROMPT_I => nil, # 通常ã®ãƒ—ロンプト
+ :PROMPT_N => nil, # 継続行ã®ãƒ—ロンプト
:PROMPT_S => nil, # 文字列ãªã©ã®ç¶™ç¶šè¡Œã®ãƒ—ロンプト
:PROMPT_C => nil, # å¼ãŒç¶™ç¶šã—ã¦ã„る時ã®ãƒ—ロンプト
:RETURN => " ==>%s\n" # リターン時ã®ãƒ—ロンプト
@@ -139,7 +140,7 @@ OKã§ã™.
IRB.conf[:PROMPT_MODE] = :MY_PROMPT
-PROMPT_I, PROMPT_S, PROMPT_Cã¯, フォーマットを指定ã—ã¾ã™.
+PROMPT_I, PROMPT_N, PROMPT_S, PROMPT_Cã¯, フォーマットを指定ã—ã¾ã™.
%N èµ·å‹•ã—ã¦ã„るコマンドåãŒå‡ºåŠ›ã•れる.
%m mainオブジェクト(self)ãŒto_sã§å‡ºåŠ›ã•れる.
@@ -154,6 +155,7 @@ PROMPT_I, PROMPT_S, PROMPT_Cã¯, フォーマットを指定ã—ã¾ã™.
IRB.conf[:PROMPT][:DEFAULT] = {
:PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => "%N(%m):%03n:%i> ",
:PROMPT_S => "%N(%m):%03n:%i%l ",
:PROMPT_C => "%N(%m):%03n:%i* ",
:RETURN => "=> %s\n"
diff --git a/doc/keywords.rdoc b/doc/keywords.rdoc
index 7c368205ef..cb1cff33f0 100644
--- a/doc/keywords.rdoc
+++ b/doc/keywords.rdoc
@@ -1,4 +1,4 @@
-= Keywords
+== Keywords
The following keywords are used by Ruby.
diff --git a/doc/maintainers.md b/doc/maintainers.md
deleted file mode 100644
index 631371e178..0000000000
--- a/doc/maintainers.md
+++ /dev/null
@@ -1,520 +0,0 @@
-# Maintainers
-This page describes the current module, library, and extension maintainers of Ruby.
-
-## Module Maintainers
-A module maintainer is responsible for a certain part of Ruby.
-
-* The maintainer fixes bugs of the part. Particularly, they should fix
- security vulnerabilities as soon as possible.
-* They handle issues related the module on the Redmine or ML.
-* They may be discharged by the 3 months rule [[ruby-core:25764]](https://blade.ruby-lang.org/ruby-core/25764).
-* They have commit right to Ruby's repository to modify their part in the
- repository.
-* They have "developer" role on the Redmine to modify issues.
-* They have authority to decide the feature of their part. But they should
- always respect discussions on ruby-core/ruby-dev.
-
-A submaintainer of a module is like a maintainer. But the submaintainer does
-not have authority to change/add a feature on his/her part. They need
-consensus on ruby-core/ruby-dev before changing/adding. Some of submaintainers
-have commit right, others don't.
-
-### Language core features including security
-* Yukihiro Matsumoto (matz)
-
-### Evaluator
-* Koichi Sasada (ko1)
-
-### Core classes
-* Yukihiro Matsumoto (matz)
-
-## Standard Library Maintainers
-### Libraries
-#### lib/mkmf.rb
-* *unmaintained*
-
-#### lib/rubygems.rb, lib/rubygems/*
-* Eric Hodel (drbrain)
-* Hiroshi SHIBATA (hsbt)
-* https://github.com/rubygems/rubygems
-
-#### lib/unicode_normalize.rb, lib/unicode_normalize/*
-* Martin J. Dürst
-
-### Extensions
-#### ext/continuation
-* Koichi Sasada (ko1)
-
-#### ext/coverage
-* Yusuke Endoh (mame)
-
-#### ext/fiber
-* Koichi Sasada (ko1)
-
-#### ext/monitor
-* Koichi Sasada (ko1)
-
-#### ext/objspace
-* *unmaintained*
-
-#### ext/pty
-* *unmaintained*
-
-#### ext/ripper
-* *unmaintained*
-
-#### ext/socket
-* Tanaka Akira (akr)
-* API change needs matz's approval
-
-#### ext/win32
-* NAKAMURA Usaku (usa)
-
-## Default gems Maintainers
-### Libraries
-#### lib/abbrev.rb
-* Akinori MUSHA (knu)
-* https://github.com/ruby/abbrev
-* https://rubygems.org/gems/abbrev
-
-#### lib/base64.rb
-* Yusuke Endoh (mame)
-* https://github.com/ruby/base64
-* https://rubygems.org/gems/base64
-
-#### lib/benchmark.rb
-* *unmaintained*
-* https://github.com/ruby/benchmark
-* https://rubygems.org/gems/benchmark
-
-#### lib/bundler.rb, lib/bundler/*
-* Hiroshi SHIBATA (hsbt)
-* https://github.com/rubygems/rubygems
-* https://rubygems.org/gems/bundler
-
-#### lib/cgi.rb, lib/cgi/*
-* *unmaintained*
-* https://github.com/ruby/cgi
-* https://rubygems.org/gems/cgi
-
-#### lib/csv.rb
-* Kenta Murata (mrkn)
-* Kouhei Sutou (kou)
-* https://github.com/ruby/csv
-* https://rubygems.org/gems/csv
-
-#### lib/English.rb
-* *unmaintained*
-* https://github.com/ruby/English
-* https://rubygems.org/gems/English
-
-#### lib/delegate.rb
-* *unmaintained*
-* https://github.com/ruby/delegate
-* https://rubygems.org/gems/delegate
-
-#### lib/did_you_mean.rb
-* Yuki Nishijima (yuki24)
-* https://github.com/ruby/did_you_mean
-* https://rubygems.org/gems/did_you_mean
-
-#### ext/digest, ext/digest/*
-* Akinori MUSHA (knu)
-* https://github.com/ruby/digest
-* https://rubygems.org/gems/digest
-
-#### lib/drb.rb, lib/drb/*
-* Masatoshi SEKI (seki)
-* https://github.com/ruby/drb
-* https://rubygems.org/gems/drb
-
-#### lib/erb.rb
-* Masatoshi SEKI (seki)
-* Takashi Kokubun (k0kubun)
-* https://github.com/ruby/erb
-* https://rubygems.org/gems/erb
-
-#### lib/error_highlight.rb, lib/error_highlight/*
-* Yusuke Endoh (mame)
-* https://github.com/ruby/error_highlight
-* https://rubygems.org/gems/error_highlight
-
-#### lib/fileutils.rb
-* *unmaintained*
-* https://github.com/ruby/fileutils
-* https://rubygems.org/gems/fileutils
-
-#### lib/find.rb
-* Kazuki Tsujimoto (ktsj)
-* https://github.com/ruby/find
-* https://rubygems.org/gems/find
-
-#### lib/forwardable.rb
-* Keiju ISHITSUKA (keiju)
-* https://github.com/ruby/forwardable
-* https://rubygems.org/gems/forwardable
-
-#### lib/getoptlong.rb
-* *unmaintained*
-* https://github.com/ruby/getoptlong
-* https://rubygems.org/gems/getoptlong
-
-#### lib/ipaddr.rb
-* Akinori MUSHA (knu)
-* https://github.com/ruby/ipaddr
-* https://rubygems.org/gems/ipaddr
-
-#### lib/irb.rb, lib/irb/*
-* Stan Lo (st0012)
-* Tomoya Ishida (tompng)
-* Mari Imaizumi (ima1zumi)
-* Hitoshi Hasumi (hasumikin)
-* https://github.com/ruby/irb
-* https://rubygems.org/gems/irb
-
-#### lib/optparse.rb, lib/optparse/*
-* Nobuyuki Nakada (nobu)
-* https://github.com/ruby/optparse
-
-#### lib/logger.rb
-* Naotoshi Seo (sonots)
-* https://github.com/ruby/logger
-* https://rubygems.org/gems/logger
-
-#### lib/mutex_m.rb
-* Keiju ISHITSUKA (keiju)
-* https://github.com/ruby/mutex_m
-* https://rubygems.org/gems/mutex_m
-
-#### lib/net/http.rb, lib/net/https.rb
-* NARUSE, Yui (naruse)
-* https://github.com/ruby/net-http
-* https://rubygems.org/gems/net-http
-
-#### lib/net/protocol.rb
-* *unmaintained*
-* https://github.com/ruby/net-protocol
-* https://rubygems.org/gems/net-protocol
-
-#### lib/observer.rb
-* *unmaintained*
-* https://github.com/ruby/observer
-* https://rubygems.org/gems/observer
-
-#### lib/open3.rb
-* *unmaintained*
-* https://github.com/ruby/open3
-* https://rubygems.org/gems/open3
-
-#### lib/open-uri.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/open-uri
-
-#### lib/ostruct.rb
-* Marc-André Lafortune (marcandre)
-* https://github.com/ruby/ostruct
-* https://rubygems.org/gems/ostruct
-
-#### lib/pp.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/pp
-* https://rubygems.org/gems/pp
-
-#### lib/prettyprint.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/prettyprint
-* https://rubygems.org/gems/prettyprint
-
-#### lib/prism.rb
-* Kevin Newton (kddnewton)
-* Jemma Issroff (jemmaissroff)
-* https://github.com/ruby/prism
-* https://rubygems.org/gems/prism
-
-#### lib/pstore.rb
-* *unmaintained*
-* https://github.com/ruby/pstore
-* https://rubygems.org/gems/pstore
-
-#### lib/readline.rb
-* aycabta
-* https://github.com/ruby/readline
-* https://rubygems.org/gems/readline
-
-#### lib/resolv.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/resolv
-* https://rubygems.org/gems/resolv
-
-#### lib/resolv-replace.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/resolv-replace
-* https://rubygems.org/gems/resolv-replace
-
-#### lib/rdoc.rb, lib/rdoc/*
-* Eric Hodel (drbrain)
-* Hiroshi SHIBATA (hsbt)
-* https://github.com/ruby/rdoc
-* https://rubygems.org/gems/rdoc
-
-#### lib/reline.rb, lib/reline/*
-* Tomoya Ishida (tompng)
-* Mari Imaizumi (ima1zumi)
-* Stan Lo (st0012)
-* Hitoshi Hasumi (hasumikin)
-* https://github.com/ruby/reline
-* https://rubygems.org/gems/reline
-
-#### lib/rinda/*
-* Masatoshi SEKI (seki)
-* https://github.com/ruby/rinda
-* https://rubygems.org/gems/rinda
-
-#### lib/securerandom.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/securerandom
-* https://rubygems.org/gems/securerandom
-
-#### lib/set.rb
-* Akinori MUSHA (knu)
-* https://github.com/ruby/set
-* https://rubygems.org/gems/set
-
-#### lib/shellwords.rb
-* Akinori MUSHA (knu)
-* https://github.com/ruby/shellwords
-* https://rubygems.org/gems/shellwords
-
-#### lib/singleton.rb
-* Yukihiro Matsumoto (matz)
-* https://github.com/ruby/singleton
-* https://rubygems.org/gems/singleton
-
-#### lib/tempfile.rb
-* *unmaintained*
-* https://github.com/ruby/tempfile
-* https://rubygems.org/gems/tempfile
-
-#### lib/time.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/time
-* https://rubygems.org/gems/time
-
-#### lib/timeout.rb
-* Yukihiro Matsumoto (matz)
-* https://github.com/ruby/timeout
-* https://rubygems.org/gems/timeout
-
-#### lib/thwait.rb
-* Keiju ISHITSUKA (keiju)
-* https://github.com/ruby/thwait
-* https://rubygems.org/gems/thwait
-
-#### lib/tmpdir.rb
-* *unmaintained*
-* https://github.com/ruby/tmpdir
-* https://rubygems.org/gems/tmpdir
-
-#### lib/tsort.rb
-* Tanaka Akira (akr)
-* https://github.com/ruby/tsort
-* https://rubygems.org/gems/tsort
-
-#### lib/un.rb
-* WATANABE Hirofumi (eban)
-* https://github.com/ruby/un
-* https://rubygems.org/gems/un
-
-#### lib/uri.rb, lib/uri/*
-* NARUSE, Yui (naruse)
-* https://github.com/ruby/uri
-* https://rubygems.org/gems/uri
-
-#### lib/yaml.rb, lib/yaml/*
-* Aaron Patterson (tenderlove)
-* Hiroshi SHIBATA (hsbt)
-* https://github.com/ruby/yaml
-* https://rubygems.org/gems/yaml
-
-#### lib/weakref.rb
-* *unmaintained*
-* https://github.com/ruby/weakref
-* https://rubygems.org/gems/weakref
-
-### Extensions
-#### ext/bigdecimal
-* Kenta Murata (mrkn) https://github.com/ruby/bigdecimal
-* https://rubygems.org/gems/bigdecimal
-
-#### ext/cgi
-* Nobuyoshi Nakada (nobu)
-* https://github.com/ruby/cgi
-* https://rubygems.org/gems/cgi
-
-#### ext/date
-* *unmaintained*
-* https://github.com/ruby/date
-* https://rubygems.org/gems/date
-
-#### ext/etc
-* *unmaintained*
-* https://github.com/ruby/etc
-* https://rubygems.org/gems/etc
-
-#### ext/fcntl
-* *unmaintained*
-* https://github.com/ruby/fcntl
-* https://rubygems.org/gems/fcntl
-
-#### ext/fiddle
-* Aaron Patterson (tenderlove)
-* https://github.com/ruby/fiddle
-* https://rubygems.org/gems/fiddle
-
-#### ext/io/console
-* Nobuyuki Nakada (nobu)
-* https://github.com/ruby/io-console
-* https://rubygems.org/gems/io-console
-
-#### ext/io/nonblock
-* Nobuyuki Nakada (nobu)
-* https://github.com/ruby/io-nonblock
-* https://rubygems.org/gems/io-nonblock
-
-#### ext/io/wait
-* Nobuyuki Nakada (nobu)
-* https://github.com/ruby/io-wait
-* https://rubygems.org/gems/io-wait
-
-#### ext/json
-* NARUSE, Yui (naruse)
-* Hiroshi SHIBATA (hsbt)
-* https://github.com/flori/json
-* https://rubygems.org/gems/json
-
-#### ext/nkf
-* NARUSE, Yui (naruse)
-* https://github.com/ruby/nkf
-* https://rubygems.org/gems/nkf
-
-#### ext/openssl
-* Kazuki Yamaguchi (rhe)
-* https://github.com/ruby/openssl
-* https://rubygems.org/gems/openssl
-
-#### ext/pathname
-* Tanaka Akira (akr)
-* https://github.com/ruby/pathname
-* https://rubygems.org/gems/pathname
-
-#### ext/psych
-* Aaron Patterson (tenderlove)
-* Hiroshi SHIBATA (hsbt)
-* https://github.com/ruby/psych
-* https://rubygems.org/gems/psych
-
-#### ext/stringio
-* Nobuyuki Nakada (nobu)
-* https://github.com/ruby/stringio
-* https://rubygems.org/gems/stringio
-
-#### ext/strscan
-* Kouhei Sutou (kou)
-* https://github.com/ruby/strscan
-* https://rubygems.org/gems/strscan
-
-#### ext/syslog
-* Akinori MUSHA (knu)
-* https://github.com/ruby/syslog
-* https://rubygems.org/gems/syslog
-
-#### ext/win32ole
-* Masaki Suketa (suke)
-* https://github.com/ruby/win32ole
-* https://rubygems.org/gems/win32ole
-
-#### ext/zlib
-* NARUSE, Yui (naruse)
-* https://github.com/ruby/zlib
-* https://rubygems.org/gems/zlib
-
-## Bundled gems upstream repositories
-### minitest
-* https://github.com/seattlerb/minitest
-
-### power_assert
-* https://github.com/ruby/power_assert
-
-### rake
-* https://github.com/ruby/rake
-
-### test-unit
-* https://github.com/test-unit/test-unit
-
-### rexml
-* https://github.com/ruby/rexml
-
-### rss
-* https://github.com/ruby/rss
-
-### net-ftp
-* https://github.com/ruby/net-ftp
-
-### net-imap
-* https://github.com/ruby/net-imap
-
-### net-pop
-* https://github.com/ruby/net-pop
-
-### net-smtp
-* https://github.com/ruby/net-smtp
-
-### matrix
-* https://github.com/ruby/matrix
-
-### prime
-* https://github.com/ruby/prime
-
-### rbs
-* https://github.com/ruby/rbs
-
-### typeprof
-* https://github.com/ruby/typeprof
-
-### debug
-* https://github.com/ruby/debug
-
-### racc
-* https://github.com/ruby/racc
-
-
-## Platform Maintainers
-### mswin64 (Microsoft Windows)
-* NAKAMURA Usaku (usa)
-
-### mingw32 (Minimalist GNU for Windows)
-* Nobuyoshi Nakada (nobu)
-
-### AIX
-* Yutaka Kanemoto (kanemoto)
-
-### FreeBSD
-* Akinori MUSHA (knu)
-
-### Solaris
-* Naohisa Goto (ngoto)
-
-### RHEL, CentOS
-* KOSAKI Motohiro (kosaki)
-
-### macOS
-* Kenta Murata (mrkn)
-
-### OpenBSD
-* Jeremy Evans (jeremyevans0)
-
-### cygwin, ...
-* none. (Maintainer WANTED)
-
-### WebAssembly/WASI
-* Yuta Saito (katei)
diff --git a/doc/maintainers.rdoc b/doc/maintainers.rdoc
new file mode 100644
index 0000000000..7e0c35194f
--- /dev/null
+++ b/doc/maintainers.rdoc
@@ -0,0 +1,424 @@
+= Maintainers
+
+This page describes the current module, library, and extension maintainers of Ruby.
+
+== Module Maintainers
+
+A module maintainer is responsible for a certain part of Ruby.
+
+* The maintainer fixes bugs of the part. Particularly, they should fix security vulnerabilities as soon as possible.
+* They handle issues related the module on the Redmine or ML.
+* They may be discharged by the 3 months rule [ruby-core:25764].
+* They have commit right to Ruby's repository to modify their part in the repository.
+* They have "developer" role on the Redmine to modify issues.
+* They have authority to decide the feature of their part. But they should always respect discussions on ruby-core/ruby-dev.
+
+A submaintainer of a module is like a maintainer. But the submaintainer does
+not have authority to change/add a feature on his/her part. They need consensus
+on ruby-core/ruby-dev before changing/adding. Some of submaintainers have
+commit right, others don't.
+
+=== Language core features including security
+
+Yukihiro Matsumoto (matz)
+
+=== Evaluator
+
+Koichi Sasada (ko1)
+
+=== Core classes
+
+Yukihiro Matsumoto (matz)
+
+== Standard Library Maintainers
+
+=== Libraries
+
+[lib/mkmf.rb]
+ _unmaintained_
+[lib/rubygems.rb, lib/rubygems/*]
+ Eric Hodel (drbrain), Hiroshi SHIBATA (hsbt)
+ https://github.com/rubygems/rubygems
+[lib/unicode_normalize.rb, lib/unicode_normalize/*]
+ Martin J. Dürst
+
+=== Extensions
+
+[ext/continuation]
+ Koichi Sasada (ko1)
+[ext/coverage]
+ Yusuke Endoh (mame)
+[ext/fiber]
+ Koichi Sasada (ko1)
+[ext/monitor]
+ Koichi Sasada (ko1)
+[ext/objspace]
+ _unmaintained_
+[ext/pty]
+ _unmaintained_
+[ext/ripper]
+ _unmaintained_
+[ext/socket]
+ * Tanaka Akira (akr)
+ * API change needs matz's approval
+[ext/win32]
+ NAKAMURA Usaku (usa)
+
+== Default gems Maintainers
+
+=== Libraries
+
+[lib/abbrev.rb]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/abbrev
+ https://rubygems.org/gems/abbrev
+[lib/base64.rb]
+ Yusuke Endoh (mame)
+ https://github.com/ruby/base64
+ https://rubygems.org/gems/base64
+[lib/benchmark.rb]
+ _unmaintained_
+ https://github.com/ruby/benchmark
+ https://rubygems.org/gems/benchmark
+[lib/bundler.rb, lib/bundler/*]
+ Hiroshi SHIBATA (hsbt)
+ https://github.com/rubygems/rubygems
+ https://rubygems.org/gems/bundler
+[lib/cgi.rb, lib/cgi/*]
+ _unmaintained_
+ https://github.com/ruby/cgi
+ https://rubygems.org/gems/cgi
+[lib/csv.rb]
+ Kenta Murata (mrkn), Kouhei Sutou (kou)
+ https://github.com/ruby/csv
+ https://rubygems.org/gems/csv
+[lib/English.rb]
+ _unmaintained_
+ https://github.com/ruby/English
+ https://rubygems.org/gems/English
+[lib/debug.rb]
+ _unmaintained_
+ https://github.com/ruby/debug
+[lib/delegate.rb]
+ _unmaintained_
+ https://github.com/ruby/delegate
+ https://rubygems.org/gems/delegate
+[lib/did_you_mean.rb]
+ Yuki Nishijima (yuki24)
+ https://github.com/ruby/did_you_mean
+ https://rubygems.org/gems/did_you_mean
+[ext/digest, ext/digest/*]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/digest
+ https://rubygems.org/gems/digest
+[lib/drb.rb, lib/drb/*]
+ Masatoshi SEKI (seki)
+ https://github.com/ruby/drb
+ https://rubygems.org/gems/drb
+[lib/erb.rb]
+ Masatoshi SEKI (seki), Takashi Kokubun (k0kubun)
+ https://github.com/ruby/erb
+ https://rubygems.org/gems/erb
+[lib/error_highlight.rb, lib/error_highlight/*]
+ Yusuke Endoh (mame)
+ https://github.com/ruby/error_highlight
+ https://rubygems.org/gems/error_highlight
+[lib/fileutils.rb]
+ _unmaintained_
+ https://github.com/ruby/fileutils
+ https://rubygems.org/gems/fileutils
+[lib/find.rb]
+ Kazuki Tsujimoto (ktsj)
+ https://github.com/ruby/find
+ https://rubygems.org/gems/find
+[lib/forwardable.rb]
+ Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/forwardable
+ https://rubygems.org/gems/forwardable
+[lib/getoptlong.rb]
+ _unmaintained_
+ https://github.com/ruby/getoptlong
+ https://rubygems.org/gems/getoptlong
+[lib/ipaddr.rb]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/ipaddr
+ https://rubygems.org/gems/ipaddr
+[lib/irb.rb, lib/irb/*]
+ aycabta
+ https://github.com/ruby/irb
+ https://rubygems.org/gems/irb
+[lib/optparse.rb, lib/optparse/*]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/optparse
+[lib/logger.rb]
+ Naotoshi Seo (sonots)
+ https://github.com/ruby/logger
+ https://rubygems.org/gems/logger
+[lib/mutex_m.rb]
+ Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/mutex_m
+ https://rubygems.org/gems/mutex_m
+[lib/net/http.rb, lib/net/https.rb]
+ NARUSE, Yui (naruse)
+ https://github.com/ruby/net-http
+ https://rubygems.org/gems/net-http
+[lib/net/protocol.rb]
+ _unmaintained_
+ https://github.com/ruby/net-protocol
+ https://rubygems.org/gems/net-protocol
+[lib/observer.rb]
+ _unmaintained_
+ https://github.com/ruby/observer
+ https://rubygems.org/gems/observer
+[lib/open3.rb]
+ _unmaintained_
+ https://github.com/ruby/open3
+ https://rubygems.org/gems/open3
+[lib/open-uri.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/open-uri
+[lib/ostruct.rb]
+ Marc-André Lafortune (marcandre)
+ https://github.com/ruby/ostruct
+ https://rubygems.org/gems/ostruct
+[lib/pp.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/pp
+ https://rubygems.org/gems/pp
+[lib/prettyprint.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/prettyprint
+ https://rubygems.org/gems/prettyprint
+[lib/pstore.rb]
+ _unmaintained_
+ https://github.com/ruby/pstore
+ https://rubygems.org/gems/pstore
+[lib/racc.rb, lib/racc/*]
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/racc
+ https://rubygems.org/gems/racc
+[lib/readline.rb]
+ aycabta
+ https://github.com/ruby/readline
+ https://rubygems.org/gems/readline
+[lib/resolv.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/resolv
+ https://rubygems.org/gems/resolv
+[lib/resolv-replace.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/resolv-replace
+ https://rubygems.org/gems/resolv-replace
+[lib/rdoc.rb, lib/rdoc/*]
+ Eric Hodel (drbrain), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/rdoc
+ https://rubygems.org/gems/rdoc
+[lib/readline.rb]
+ aycabta
+ https://github.com/ruby/readline
+ https://rubygems.org/gems/readline
+[lib/reline.rb, lib/reline/*]
+ aycabta
+ https://github.com/ruby/reline
+ https://rubygems.org/gems/reline
+[lib/rinda/*]
+ Masatoshi SEKI (seki)
+ https://github.com/ruby/rinda
+ https://rubygems.org/gems/rinda
+[lib/securerandom.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/securerandom
+ https://rubygems.org/gems/securerandom
+[lib/set.rb]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/set
+ https://rubygems.org/gems/set
+[lib/shellwords.rb]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/shellwords
+ https://rubygems.org/gems/shellwords
+[lib/singleton.rb]
+ Yukihiro Matsumoto (matz)
+ https://github.com/ruby/singleton
+ https://rubygems.org/gems/singleton
+[lib/tempfile.rb]
+ _unmaintained_
+ https://github.com/ruby/tempfile
+ https://rubygems.org/gems/tempfile
+[lib/time.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/time
+ https://rubygems.org/gems/time
+[lib/timeout.rb]
+ Yukihiro Matsumoto (matz)
+ https://github.com/ruby/timeout
+ https://rubygems.org/gems/timeout
+[lib/thwait.rb]
+ Keiju ISHITSUKA (keiju)
+ https://github.com/ruby/thwait
+ https://rubygems.org/gems/thwait
+[lib/tmpdir.rb]
+ _unmaintained_
+ https://github.com/ruby/tmpdir
+ https://rubygems.org/gems/tmpdir
+[lib/tsort.rb]
+ Tanaka Akira (akr)
+ https://github.com/ruby/tsort
+ https://rubygems.org/gems/tsort
+[lib/un.rb]
+ WATANABE Hirofumi (eban)
+ https://github.com/ruby/un
+ https://rubygems.org/gems/un
+[lib/uri.rb, lib/uri/*]
+ YAMADA, Akira (akira)
+ https://github.com/ruby/uri
+ https://rubygems.org/gems/uri
+[lib/yaml.rb, lib/yaml/*]
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/yaml
+ https://rubygems.org/gems/yaml
+[lib/weakref.rb]
+ _unmaintained_
+ https://github.com/ruby/weakref
+ https://rubygems.org/gems/weakref
+
+=== Extensions
+
+[ext/bigdecimal]
+ Kenta Murata (mrkn)
+ https://github.com/ruby/bigdecimal
+ https://rubygems.org/gems/bigdecimal
+[ext/cgi]
+ Nobuyoshi Nakada (nobu)
+ https://github.com/ruby/cgi
+ https://rubygems.org/gems/cgi
+[ext/date]
+ _unmaintained_
+ https://github.com/ruby/date
+ https://rubygems.org/gems/date
+[ext/etc]
+ Ruby core team
+ https://github.com/ruby/etc
+ https://rubygems.org/gems/etc
+[ext/fcntl]
+ Ruby core team
+ https://github.com/ruby/fcntl
+ https://rubygems.org/gems/fcntl
+[ext/fiddle]
+ Aaron Patterson (tenderlove)
+ https://github.com/ruby/fiddle
+ https://rubygems.org/gems/fiddle
+[ext/io/console]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/io-console
+ https://rubygems.org/gems/io-console
+[ext/io/nonblock]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/io-nonblock
+ https://rubygems.org/gems/io-nonblock
+[ext/io/wait]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/io-wait
+ https://rubygems.org/gems/io-wait
+[ext/json]
+ NARUSE, Yui (naruse), Hiroshi SHIBATA (hsbt)
+ https://github.com/flori/json
+ https://rubygems.org/gems/json
+[ext/nkf]
+ NARUSE, Yui (naruse)
+ https://github.com/ruby/nkf
+ https://rubygems.org/gems/nkf
+[ext/openssl]
+ Kazuki Yamaguchi (rhe)
+ https://github.com/ruby/openssl
+ https://rubygems.org/gems/openssl
+[ext/pathname]
+ Tanaka Akira (akr)
+ https://github.com/ruby/pathname
+ https://rubygems.org/gems/pathname
+[ext/psych]
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/psych
+ https://rubygems.org/gems/psych
+[ext/racc]
+ Aaron Patterson (tenderlove), Hiroshi SHIBATA (hsbt)
+ https://github.com/ruby/racc
+ https://rubygems.org/gems/racc
+[ext/readline]
+ TAKAO Kouji (kouji)
+ https://github.com/ruby/readline-ext
+ https://rubygems.org/gems/readline-ext
+[ext/stringio]
+ Nobuyuki Nakada (nobu)
+ https://github.com/ruby/stringio
+ https://rubygems.org/gems/stringio
+[ext/strscan]
+ Kouhei Sutou (kou)
+ https://github.com/ruby/strscan
+ https://rubygems.org/gems/strscan
+[ext/syslog]
+ Akinori MUSHA (knu)
+ https://github.com/ruby/syslog
+ https://rubygems.org/gems/syslog
+[ext/win32ole]
+ Masaki Suketa (suke)
+ https://github.com/ruby/win32ole
+ https://rubygems.org/gems/win32ole
+[ext/zlib]
+ NARUSE, Yui (naruse)
+ https://github.com/ruby/zlib
+ https://rubygems.org/gems/zlib
+
+== Bundled gems upstream repositories
+
+[minitest]
+ https://github.com/seattlerb/minitest
+[power_assert]
+ https://github.com/ruby/power_assert
+[rake]
+ https://github.com/ruby/rake
+[test-unit]
+ https://github.com/test-unit/test-unit
+[rexml]
+ https://github.com/ruby/rexml
+[rss]
+ https://github.com/ruby/rss
+[net-ftp]
+ https://github.com/ruby/net-ftp
+[net-imap]
+ https://github.com/ruby/net-imap
+[net-pop]
+ https://github.com/ruby/net-pop
+[net-smtp]
+ https://github.com/ruby/net-smtp
+[matrix]
+ https://github.com/ruby/matrix
+[prime]
+ https://github.com/ruby/prime
+[rbs]
+ https://github.com/ruby/rbs
+[typeprof]
+ https://github.com/ruby/typeprof
+
+=== Platform Maintainers
+
+[mswin64 (Microsoft Windows)]
+ NAKAMURA Usaku (usa)
+[mingw32 (Minimalist GNU for Windows)]
+ Nobuyoshi Nakada (nobu)
+[AIX]
+ Yutaka Kanemoto (kanemoto)
+[FreeBSD]
+ Akinori MUSHA (knu)
+[Solaris]
+ Naohisa Goto (ngoto)
+[RHEL, CentOS]
+ KOSAKI Motohiro (kosaki)
+[macOS]
+ Kenta Murata (mrkn)
+[OpenBSD]
+ Jeremy Evans (jeremyevans0)
+[cygwin, ...]
+ none. (Maintainer WANTED)
+[WebAssembly/WASI]
+ Yuta Saito (katei)
diff --git a/doc/mjit/mjit.md b/doc/mjit/mjit.md
new file mode 100644
index 0000000000..6f19ab3ea7
--- /dev/null
+++ b/doc/mjit/mjit.md
@@ -0,0 +1,39 @@
+# MJIT
+
+This document has some tips that might be useful when you work on MJIT.
+
+## Supported platforms
+
+The following platforms are either tested on CI or assumed to work.
+
+* OS: Linux, macOS
+* Arch: x86\_64, aarch64, arm64, i686, i386
+
+### Not supported
+
+The MJIT support for the following platforms is no longer maintained.
+
+* OS: Windows (mswin, MinGW), Solaris
+* Arch: SPARC, s390x
+
+## Developing MJIT
+
+### Bindgen
+
+If you see an "MJIT bindgen" GitHub Actions failure, please commit the `git diff` shown on the failed job.
+
+For doing the same thing locally, run `make mjit-bindgen` after installing libclang.
+macOS seems to have libclang by default. On Ubuntu, you can install it with `apt install libclang1`.
+
+### Always run make install
+
+Always run `make install` before running MJIT. It could easily cause a SEGV if you don't.
+MJIT looks for the installed header for security reasons.
+
+### --mjit-debug vs --mjit-debug=-ggdb3
+
+`--mjit-debug=[flags]` allows you to specify arbitrary flags while keeping other compiler flags like `-O3`,
+which is useful for profiling benchmarks.
+
+`--mjit-debug` alone, on the other hand, disables `-O3` and adds debug flags.
+If you're debugging MJIT, what you need to use is not `--mjit-debug=-ggdb3` but `--mjit-debug`.
diff --git a/doc/optparse/argument_converters.rdoc b/doc/optparse/argument_converters.rdoc
index 4b4b30e8de..ac659da8c5 100644
--- a/doc/optparse/argument_converters.rdoc
+++ b/doc/optparse/argument_converters.rdoc
@@ -1,7 +1,7 @@
== Argument Converters
An option can specify that its argument is to be converted
-from the default +String+ to an instance of another class.
+from the default \String to an instance of another class.
=== Contents
@@ -27,13 +27,13 @@ from the default +String+ to an instance of another class.
=== Built-In Argument Converters
-+OptionParser+ has a number of built-in argument converters,
+\OptionParser has a number of built-in argument converters,
which are demonstrated below.
-==== +Date+
+==== \Date
File +date.rb+
-defines an option whose argument is to be converted to a +Date+ object.
+defines an option whose argument is to be converted to a \Date object.
The argument is converted by method Date#parse.
:include: ruby/date.rb
@@ -47,10 +47,10 @@ Executions:
$ ruby date.rb --date "3rd Feb 2001"
[#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>, Date]
-==== +DateTime+
+==== \DateTime
File +datetime.rb+
-defines an option whose argument is to be converted to a +DateTime+ object.
+defines an option whose argument is to be converted to a \DateTime object.
The argument is converted by method DateTime#parse.
:include: ruby/datetime.rb
@@ -64,10 +64,10 @@ Executions:
$ ruby datetime.rb --datetime "3rd Feb 2001 04:05:06 PM"
[#<DateTime: 2001-02-03T16:05:06+00:00 ((2451944j,57906s,0n),+0s,2299161j)>, DateTime]
-==== +Time+
+==== \Time
File +time.rb+
-defines an option whose argument is to be converted to a +Time+ object.
+defines an option whose argument is to be converted to a \Time object.
The argument is converted by method Time#httpdate or Time#parse.
:include: ruby/time.rb
@@ -79,10 +79,10 @@ Executions:
$ ruby time.rb --time 2010-10-31
[2010-10-31 00:00:00 -0500, Time]
-==== +URI+
+==== \URI
File +uri.rb+
-defines an option whose argument is to be converted to a +URI+ object.
+defines an option whose argument is to be converted to a \URI object.
The argument is converted by method URI#parse.
:include: ruby/uri.rb
@@ -96,10 +96,10 @@ Executions:
$ ruby uri.rb --uri file://~/var
[#<URI::File file://~/var>, URI::File]
-==== +Shellwords+
+==== \Shellwords
File +shellwords.rb+
-defines an option whose argument is to be converted to an +Array+ object by method
+defines an option whose argument is to be converted to an \Array object by method
Shellwords#shellwords.
:include: ruby/shellwords.rb
@@ -111,10 +111,10 @@ Executions:
$ ruby shellwords.rb --shellwords "here are 'two words'"
[["here", "are", "two words"], Array]
-==== +Integer+
+==== \Integer
File +integer.rb+
-defines an option whose argument is to be converted to an +Integer+ object.
+defines an option whose argument is to be converted to an \Integer object.
The argument is converted by method Kernel#Integer.
:include: ruby/integer.rb
@@ -132,10 +132,10 @@ Executions:
$ ruby integer.rb --integer 0b100
[4, Integer]
-==== +Float+
+==== \Float
File +float.rb+
-defines an option whose argument is to be converted to a +Float+ object.
+defines an option whose argument is to be converted to a \Float object.
The argument is converted by method Kernel#Float.
:include: ruby/float.rb
@@ -151,11 +151,11 @@ Executions:
$ ruby float.rb --float 1.234E-2
[0.01234, Float]
-==== +Numeric+
+==== \Numeric
File +numeric.rb+
defines an option whose argument is to be converted to an instance
-of +Rational+, +Float+, or +Integer+.
+of \Rational, \Float, or \Integer.
The argument is converted by method Kernel#Rational,
Kernel#Float, or Kernel#Integer.
@@ -170,10 +170,10 @@ Executions:
$ ruby numeric.rb --numeric 3
[3, Integer]
-==== +DecimalInteger+
+==== \DecimalInteger
File +decimal_integer.rb+
-defines an option whose argument is to be converted to an +Integer+ object.
+defines an option whose argument is to be converted to an \Integer object.
The argument is converted by method Kernel#Integer.
:include: ruby/decimal_integer.rb
@@ -192,10 +192,10 @@ Executions:
$ ruby decimal_integer.rb --decimal_integer -0100
[-100, Integer]
-==== +OctalInteger+
+==== \OctalInteger
File +octal_integer.rb+
-defines an option whose argument is to be converted to an +Integer+ object.
+defines an option whose argument is to be converted to an \Integer object.
The argument is converted by method Kernel#Integer.
:include: ruby/octal_integer.rb
@@ -212,10 +212,10 @@ Executions:
$ ruby octal_integer.rb --octal_integer 0100
[64, Integer]
-==== +DecimalNumeric+
+==== \DecimalNumeric
File +decimal_numeric.rb+
-defines an option whose argument is to be converted to an +Integer+ object.
+defines an option whose argument is to be converted to an \Integer object.
The argument is converted by method Kernel#Integer
:include: ruby/decimal_numeric.rb
@@ -232,7 +232,7 @@ Executions:
$ ruby decimal_numeric.rb --decimal_numeric 0100
[64, Integer]
-==== +TrueClass+
+==== \TrueClass
File +true_class.rb+
defines an option whose argument is to be converted to +true+ or +false+.
@@ -259,7 +259,7 @@ Executions:
$ ruby true_class.rb --true_class nil
[false, FalseClass]
-==== +FalseClass+
+==== \FalseClass
File +false_class.rb+
defines an option whose argument is to be converted to +true+ or +false+.
@@ -286,10 +286,10 @@ Executions:
$ ruby false_class.rb --false_class +
[true, TrueClass]
-==== +Object+
+==== \Object
File +object.rb+
-defines an option whose argument is not to be converted from +String+.
+defines an option whose argument is not to be converted from \String.
:include: ruby/object.rb
@@ -300,10 +300,10 @@ Executions:
$ ruby object.rb --object nil
["nil", String]
-==== +String+
+==== \String
File +string.rb+
-defines an option whose argument is not to be converted from +String+.
+defines an option whose argument is not to be converted from \String.
:include: ruby/string.rb
@@ -314,10 +314,10 @@ Executions:
$ ruby string.rb --string nil
["nil", String]
-==== +Array+
+==== \Array
File +array.rb+
-defines an option whose argument is to be converted from +String+
+defines an option whose argument is to be converted from \String
to an array of strings, based on comma-separated substrings.
:include: ruby/array.rb
@@ -331,10 +331,10 @@ Executions:
$ ruby array.rb --array "foo, bar, baz"
[["foo", " bar", " baz"], Array]
-==== +Regexp+
+==== \Regexp
File +regexp.rb+
-defines an option whose argument is to be converted to a +Regexp+ object.
+defines an option whose argument is to be converted to a \Regexp object.
:include: ruby/regexp.rb
@@ -352,7 +352,7 @@ To create a custom converter, call OptionParser#accept with:
- A block that accepts the argument and returns the converted value.
This custom converter accepts any argument and converts it,
-if possible, to a +Complex+ object.
+if possible, to a \Complex object.
:include: ruby/custom_converter.rb
diff --git a/doc/optparse/option_params.rdoc b/doc/optparse/option_params.rdoc
index 55f9b53dff..ace2c4283f 100644
--- a/doc/optparse/option_params.rdoc
+++ b/doc/optparse/option_params.rdoc
@@ -1,6 +1,6 @@
== Parameters for New Options
-Option-creating methods in +OptionParser+
+Option-creating methods in \OptionParser
accept arguments that determine the behavior of a new option:
- OptionParser#on
@@ -405,7 +405,7 @@ Executions:
=== Argument Converters
An option can specify that its argument is to be converted
-from the default +String+ to an instance of another class.
+from the default \String to an instance of another class.
There are a number of built-in converters.
You can also define custom converters.
diff --git a/doc/optparse/tutorial.rdoc b/doc/optparse/tutorial.rdoc
index b104379cf7..b95089826d 100644
--- a/doc/optparse/tutorial.rdoc
+++ b/doc/optparse/tutorial.rdoc
@@ -1,10 +1,10 @@
== Tutorial
-=== Why +OptionParser+?
+=== Why \OptionParser?
When a Ruby program executes, it captures its command-line arguments
and options into variable ARGV.
-This simple program just prints its +ARGV+:
+This simple program just prints its \ARGV:
:include: ruby/argv.rb
@@ -18,7 +18,7 @@ the command-line options.
OptionParser offers methods for parsing and handling those options.
-With +OptionParser+, you can define options so that for each option:
+With \OptionParser, you can define options so that for each option:
- The code that defines the option and code that handles that option
are in the same place.
@@ -55,7 +55,7 @@ The class also has method #help, which displays automatically-generated help tex
- {Argument Converters}[#label-Argument+Converters]
- {Help}[#label-Help]
- {Top List and Base List}[#label-Top+List+and+Base+List]
-- {Methods for Defining Options}[#label-Methods+for+Defining+Options]
+- {Defining Options}[#label-Defining+Options]
- {Parsing}[#label-Parsing]
- {Method parse!}[#label-Method+parse-21]
- {Method parse}[#label-Method+parse]
@@ -66,10 +66,10 @@ The class also has method #help, which displays automatically-generated help tex
=== To Begin With
-To use +OptionParser+:
+To use \OptionParser:
-1. Require the +OptionParser+ code.
-2. Create an +OptionParser+ object.
+1. Require the \OptionParser code.
+2. Create an \OptionParser object.
3. Define one or more options.
4. Parse the command line.
@@ -92,9 +92,9 @@ the block defined for the option is called with the argument value.
An invalid option raises an exception.
Method #parse!, which is used most often in this tutorial,
-removes from +ARGV+ the options and arguments it finds,
+removes from \ARGV the options and arguments it finds,
leaving other non-option arguments for the program to handle on its own.
-The method returns the possibly-reduced +ARGV+ array.
+The method returns the possibly-reduced \ARGV array.
Executions:
@@ -115,7 +115,7 @@ Executions:
=== Defining Options
-A common way to define an option in +OptionParser+
+A common way to define an option in \OptionParser
is with instance method OptionParser#on.
The method may be called with any number of arguments
@@ -522,11 +522,11 @@ Executions:
=== Argument Converters
An option can specify that its argument is to be converted
-from the default +String+ to an instance of another class.
+from the default \String to an instance of another class.
There are a number of built-in converters.
Example: File +date.rb+
-defines an option whose argument is to be converted to a +Date+ object.
+defines an option whose argument is to be converted to a \Date object.
The argument is converted by method Date#parse.
:include: ruby/date.rb
@@ -546,7 +546,7 @@ for both built-in and custom converters.
=== Help
-+OptionParser+ makes automatically generated help text available.
+\OptionParser makes automatically generated help text available.
The help text consists of:
@@ -614,49 +614,49 @@ Execution:
=== Top List and Base List
-An +OptionParser+ object maintains a stack of OptionParser::List objects,
+An \OptionParser object maintains a stack of \OptionParser::List objects,
each of which has a collection of zero or more options.
It is unlikely that you'll need to add or take away from that stack.
The stack includes:
-- The <em>top list</em>, given by OptionParser#top.
-- The <em>base list</em>, given by OptionParser#base.
+- The <em>top list</em>, given by \OptionParser#top.
+- The <em>base list</em>, given by \OptionParser#base.
-When +OptionParser+ builds its help text, the options in the top list
+When \OptionParser builds its help text, the options in the top list
precede those in the base list.
-=== Methods for Defining Options
+=== Defining Options
Option-defining methods allow you to create an option, and also append/prepend it
to the top list or append it to the base list.
Each of these next three methods accepts a sequence of parameter arguments and a block,
-creates an option object using method OptionParser#make_switch (see below),
+creates an option object using method \Option#make_switch (see below),
and returns the created option:
-- \Method OptionParser#define appends the created option to the top list.
+- \Method \OptionParser#define appends the created option to the top list.
-- \Method OptionParser#define_head prepends the created option to the top list.
+- \Method \OptionParser#define_head prepends the created option to the top list.
-- \Method OptionParser#define_tail appends the created option to the base list.
+- \Method \OptionParser#define_tail appends the created option to the base list.
These next three methods are identical to the three above,
except for their return values:
-- \Method OptionParser#on is identical to method OptionParser#define,
+- \Method \OptionParser#on is identical to method \OptionParser#define,
except that it returns the parser object +self+.
-- \Method OptionParser#on_head is identical to method OptionParser#define_head,
+- \Method \OptionParser#on_head is identical to method \OptionParser#define_head,
except that it returns the parser object +self+.
-- \Method OptionParser#on_tail is identical to method OptionParser#define_tail,
+- \Method \OptionParser#on_tail is identical to method \OptionParser#define_tail,
except that it returns the parser object +self+.
Though you may never need to call it directly,
here's the core method for defining an option:
-- \Method OptionParser#make_switch accepts an array of parameters and a block.
+- \Method \OptionParser#make_switch accepts an array of parameters and a block.
See {Parameters for New Options}[optparse/option_params.rdoc].
This method is unlike others here in that it:
- Accepts an <em>array of parameters</em>;
@@ -668,7 +668,7 @@ here's the core method for defining an option:
=== Parsing
-+OptionParser+ has six instance methods for parsing.
+\OptionParser has six instance methods for parsing.
Three have names ending with a "bang" (<tt>!</tt>):
@@ -699,9 +699,9 @@ Each of these methods:
(see {Keyword Argument into}[#label-Keyword+Argument+into]).
- Returns +argv+, possibly with some elements removed.
-==== \Method +parse!+
+==== \Method parse!
-\Method +parse!+:
+\Method parse!:
- Accepts an optional array of string arguments +argv+;
if not given, +argv+ defaults to the value of OptionParser#default_argv,
@@ -756,9 +756,9 @@ Processing ended by non-option found when +POSIXLY_CORRECT+ is defined:
["--xxx", true]
Returned: ["input_file.txt", "output_file.txt", "-yyy", "FOO"] (Array)
-==== \Method +parse+
+==== \Method parse
-\Method +parse+:
+\Method parse:
- Accepts an array of string arguments
_or_ zero or more string arguments.
@@ -810,25 +810,25 @@ Processing ended by non-option found when +POSIXLY_CORRECT+ is defined:
["--xxx", true]
Returned: ["input_file.txt", "output_file.txt", "-yyy", "FOO"] (Array)
-==== \Method +order!+
+==== \Method order!
Calling method OptionParser#order! gives exactly the same result as
calling method OptionParser#parse! with environment variable
+POSIXLY_CORRECT+ defined.
-==== \Method +order+
+==== \Method order
Calling method OptionParser#order gives exactly the same result as
calling method OptionParser#parse with environment variable
+POSIXLY_CORRECT+ defined.
-==== \Method +permute!+
+==== \Method permute!
Calling method OptionParser#permute! gives exactly the same result as
calling method OptionParser#parse! with environment variable
+POSIXLY_CORRECT+ _not_ defined.
-==== \Method +permute+
+==== \Method permute
Calling method OptionParser#permute gives exactly the same result as
calling method OptionParser#parse with environment variable
diff --git a/doc/packed_data.rdoc b/doc/packed_data.rdoc
index 59d8c99a3a..ec13b24c69 100644
--- a/doc/packed_data.rdoc
+++ b/doc/packed_data.rdoc
@@ -1,4 +1,4 @@
-= Packed \Data
+== Packed \Data
Certain Ruby core methods deal with packing and unpacking data:
@@ -64,7 +64,7 @@ If elements don't fit the provided directive, only least significant bits are en
[257].pack("C").unpack("C") # => [1]
-== Packing \Method
+=== Packing \Method
\Method Array#pack accepts optional keyword argument
+buffer+ that specifies the target string (instead of a new string):
@@ -76,7 +76,7 @@ The method can accept a block:
# Packed string is passed to the block.
[65, 66].pack('C*') {|s| p s } # => "AB"
-== Unpacking Methods
+=== Unpacking Methods
Methods String#unpack and String#unpack1 each accept
an optional keyword argument +offset+ that specifies an offset
@@ -95,12 +95,12 @@ Both methods can accept a block:
# The single unpacked object is passed to the block.
'AB'.unpack1('C*') {|ele| p ele } # => 65
-== \Integer Directives
+=== \Integer Directives
Each integer directive specifies the packing or unpacking
for one element in the input or output array.
-=== 8-Bit \Integer Directives
+==== 8-Bit \Integer Directives
- <tt>'c'</tt> - 8-bit signed integer
(like C <tt>signed char</tt>):
@@ -109,14 +109,14 @@ for one element in the input or output array.
s = [0, 1, -1].pack('c*') # => "\x00\x01\xFF"
s.unpack('c*') # => [0, 1, -1]
-- <tt>'C'</tt> - 8-bit unsigned integer
+- <tt>'C'</tt> - 8-bit signed integer
(like C <tt>unsigned char</tt>):
[0, 1, 255].pack('C*') # => "\x00\x01\xFF"
s = [0, 1, -1].pack('C*') # => "\x00\x01\xFF"
s.unpack('C*') # => [0, 1, 255]
-=== 16-Bit \Integer Directives
+==== 16-Bit \Integer Directives
- <tt>'s'</tt> - 16-bit signed integer, native-endian
(like C <tt>int16_t</tt>):
@@ -146,7 +146,7 @@ for one element in the input or output array.
s.unpack('v*')
# => [0, 1, 65535, 32767, 32768, 65535]
-=== 32-Bit \Integer Directives
+==== 32-Bit \Integer Directives
- <tt>'l'</tt> - 32-bit signed integer, native-endian
(like C <tt>int32_t</tt>):
@@ -178,7 +178,7 @@ for one element in the input or output array.
s.unpack('v*')
# => [0, 0, 1, 0, 65535, 65535]
-=== 64-Bit \Integer Directives
+==== 64-Bit \Integer Directives
- <tt>'q'</tt> - 64-bit signed integer, native-endian
(like C <tt>int64_t</tt>):
@@ -196,7 +196,7 @@ for one element in the input or output array.
s.unpack('Q*')
# => [578437695752307201, 17940646550795321087]
-=== Platform-Dependent \Integer Directives
+==== Platform-Dependent \Integer Directives
- <tt>'i'</tt> - Platform-dependent width signed integer,
native-endian (like C <tt>int</tt>):
@@ -214,24 +214,26 @@ for one element in the input or output array.
s.unpack('I*')
# => [67305985, 4244504319]
-- <tt>'j'</tt> - Pointer-width signed integer, native-endian
- (like C <tt>intptr_t</tt>):
+==== Pointer Directives
+
+- <tt>'j'</tt> - 64-bit pointer-width signed integer,
+ native-endian (like C <tt>intptr_t</tt>):
s = [67305985, -50462977].pack('j*')
# => "\x01\x02\x03\x04\x00\x00\x00\x00\xFF\xFE\xFD\xFC\xFF\xFF\xFF\xFF"
s.unpack('j*')
# => [67305985, -50462977]
-- <tt>'J'</tt> - Pointer-width unsigned integer, native-endian
- (like C <tt>uintptr_t</tt>):
+- <tt>'j'</tt> - 64-bit pointer-width unsigned integer,
+ native-endian (like C <tt>uintptr_t</tt>):
s = [67305985, 4244504319].pack('J*')
# => "\x01\x02\x03\x04\x00\x00\x00\x00\xFF\xFE\xFD\xFC\x00\x00\x00\x00"
s.unpack('J*')
# => [67305985, 4244504319]
-=== Other \Integer Directives
-
+==== Other \Integer Directives
+:
- <tt>'U'</tt> - UTF-8 character:
s = [4194304].pack('U*')
@@ -247,30 +249,31 @@ for one element in the input or output array.
s.unpack('w*')
# => [1073741823]
-=== Modifiers for \Integer Directives
-
-For the following directives, <tt>'!'</tt> or <tt>'_'</tt> modifiers may be
-suffixed as underlying platform’s native size.
-
-- <tt>'i'</tt>, <tt>'I'</tt> - C <tt>int</tt>, always native size.
-- <tt>'s'</tt>, <tt>'S'</tt> - C <tt>short</tt>.
-- <tt>'l'</tt>, <tt>'L'</tt> - C <tt>long</tt>.
-- <tt>'q'</tt>, <tt>'Q'</tt> - C <tt>long long</tt>, if available.
-- <tt>'j'</tt>, <tt>'J'</tt> - C <tt>intptr_t</tt>, always native size.
-
-Native size modifiers are silently ignored for always native size directives.
-
-The endian modifiers also may be suffixed in the directives above:
-
+==== Modifiers for \Integer Directives
+
+For directives in
+<tt>'i'</tt>,
+<tt>'I'</tt>,
+<tt>'s'</tt>,
+<tt>'S'</tt>,
+<tt>'l'</tt>,
+<tt>'L'</tt>,
+<tt>'q'</tt>,
+<tt>'Q'</tt>,
+<tt>'j'</tt>, and
+<tt>'J'</tt>,
+these modifiers may be suffixed:
+
+- <tt>'!'</tt> or <tt>'_'</tt> - Underlying platform’s native size.
- <tt>'>'</tt> - Big-endian.
- <tt>'<'</tt> - Little-endian.
-== \Float Directives
+=== \Float Directives
Each float directive specifies the packing or unpacking
for one element in the input or output array.
-=== Single-Precision \Float Directives
+==== Single-Precision \Float Directives
- <tt>'F'</tt> or <tt>'f'</tt> - Native format:
@@ -287,7 +290,7 @@ for one element in the input or output array.
s = [3.0].pack('g') # => "@@\x00\x00"
s.unpack('g') # => [3.0]
-=== Double-Precision \Float Directives
+==== Double-Precision \Float Directives
- <tt>'D'</tt> or <tt>'d'</tt> - Native format:
@@ -314,12 +317,12 @@ A float directive may be infinity or not-a-number:
[nan].pack('f') # => "\x00\x00\xC0\x7F"
"\x00\x00\xC0\x7F".unpack('f') # => [NaN]
-== \String Directives
+=== \String Directives
Each string directive specifies the packing or unpacking
for one byte in the input or output string.
-=== Binary \String Directives
+==== Binary \String Directives
- <tt>'A'</tt> - Arbitrary binary string (space padded; count is width);
+nil+ is treated as the empty string:
@@ -377,7 +380,7 @@ for one byte in the input or output string.
"foo".unpack('Z*') # => ["foo"]
"foo\0bar".unpack('Z*') # => ["foo"] # Does not read past "\0".
-=== Bit \String Directives
+==== Bit \String Directives
- <tt>'B'</tt> - Bit string (high byte first):
@@ -421,7 +424,7 @@ for one byte in the input or output string.
"\x01".unpack("b2") # => ["10"]
"\x01".unpack("b3") # => ["100"]
-=== Hex \String Directives
+==== Hex \String Directives
- <tt>'H'</tt> - Hex string (high nibble first):
@@ -467,7 +470,7 @@ for one byte in the input or output string.
"\x01\xfe".unpack('h4') # => ["10ef"]
"\x01\xfe".unpack('h5') # => ["10ef"]
-=== Pointer \String Directives
+==== Pointer \String Directives
- <tt>'P'</tt> - Pointer to a structure (fixed-length string):
@@ -485,7 +488,7 @@ for one byte in the input or output string.
("\0" * 8).unpack("p") # => [nil]
[nil].pack("p") # => "\x00\x00\x00\x00\x00\x00\x00\x00"
-=== Other \String Directives
+==== Other \String Directives
- <tt>'M'</tt> - Quoted printable, MIME encoding;
text mode, but input must use LF and output LF;
@@ -559,7 +562,7 @@ for one byte in the input or output string.
[0x40000000].pack("U") # => "\xFD\x80\x80\x80\x80\x80"
[0x7fffffff].pack("U") # => "\xFD\xBF\xBF\xBF\xBF\xBF"
-== Offset Directives
+=== Offset Directives
- <tt>'@'</tt> - Begin packing at the given byte offset;
for packing, null fill if necessary:
@@ -577,7 +580,7 @@ for one byte in the input or output string.
[0, 1, 2].pack("CCX2C") # => "\x02"
"\x00\x02".unpack("CCXC") # => [0, 2, 2]
-== Null Byte Direcive
+=== Null Byte Direcive
- <tt>'x'</tt> - Null byte:
diff --git a/doc/ractor.md b/doc/ractor.md
index 3ead510501..843754c263 100644
--- a/doc/ractor.md
+++ b/doc/ractor.md
@@ -393,7 +393,7 @@ TODO: `select` syntax of go-language uses round-robin technique to make fair sch
* `Ractor#close_incoming/outgoing` close incoming/outgoing ports (similar to `Queue#close`).
* `Ractor#close_incoming`
- * `r.send(obj)` where `r`'s incoming port is closed, will raise an exception.
+ * `r.send(obj) ` where `r`'s incoming port is closed, will raise an exception.
* When the incoming queue is empty and incoming port is closed, `Ractor.receive` raises an exception. If the incoming queue is not empty, it dequeues an object without exceptions.
* `Ractor#close_outgoing`
* `Ractor.yield` on a Ractor which closed the outgoing port, it will raise an exception.
@@ -536,7 +536,7 @@ The following objects are shareable.
Implementation: Now shareable objects (`RVALUE`) have `FL_SHAREABLE` flag. This flag can be added lazily.
-To make shareable objects, `Ractor.make_shareable(obj)` method is provided. In this case, try to make sharaeble by freezing `obj` and recursively traversable objects. This method accepts `copy:` keyword (default value is false).`Ractor.make_shareable(obj, copy: true)` tries to make a deep copy of `obj` and make the copied object shareable.
+To make shareable objects, `Ractor.make_shareable(obj)` method is provided. In this case, try to make sharaeble by freezing `obj` and recursively travasible objects. This method accepts `copy:` keyword (default value is false).`Ractor.make_shareable(obj, copy: true)` tries to make a deep copy of `obj` and make the copied object shareable.
## Language changes to isolate unshareable objects between Ractors
@@ -705,8 +705,8 @@ TABLE = {a: 'ko1', b: 'ko2', c: 'ko3'}
* none: Do nothing. Same as: `CONST = expr`
* literal:
- * if `expr` consists of literals, replaced to `CONST = Ractor.make_shareable(expr)`.
- * otherwise: replaced to `CONST = expr.tap{|o| raise unless Ractor.shareable?(o)}`.
+ * if `expr` is consites of literals, replaced to `CONST = Ractor.make_shareable(expr)`.
+ * otherwise: replaced to `CONST = expr.tap{|o| raise unless Ractor.shareable?}`.
* experimental_everything: replaced to `CONST = Ractor.make_shareable(expr)`.
* experimental_copy: replaced to `CONST = Ractor.make_shareable(expr, copy: true)`.
diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb
index a1bbe13e2d..66ec6786c0 100644
--- a/doc/rdoc/markup_reference.rb
+++ b/doc/rdoc/markup_reference.rb
@@ -26,7 +26,7 @@ require 'rdoc'
# - Single-line or multi-line comments that precede certain definitions;
# see {Markup in Comments}[rdoc-ref:RDoc::MarkupReference@Markup+in+Comments].
# - \RDoc directives in trailing comments (on the same line as code);
-# see <tt>:nodoc:</tt>, <tt>:doc:</tt>, and <tt>:notnew:</tt>.
+# see <tt>:nodoc:</tt>, <tt>:doc:</tt>, and <tt>:notnew</tt>.
# - \RDoc directives in single-line comments;
# see other {Directives}[rdoc-ref:RDoc::MarkupReference@Directives].
# - The Ruby code itself (but not from C code);
@@ -66,7 +66,7 @@ require 'rdoc'
# In a multi-line comment,
# \RDoc looks for the comment's natural left margin,
# which becomes the <em>base margin</em> for the comment
-# and is the initial <em>current margin</em> for the comment.
+# and is the initial <em>current margin</em> for for the comment.
#
# The current margin can change, and does so, for example in a list.
#
@@ -346,7 +346,7 @@ require 'rdoc'
#
# ===== Lettered Lists
#
-# A lettered list item begins with letters and a period.
+# A numbered list item begins with a letters and a period.
#
# The items are automatically "re-lettered."
#
@@ -467,32 +467,8 @@ require 'rdoc'
#
# - Appended to a line of code
# that defines a class, module, method, alias, constant, or attribute.
-#
# - Specifies that the defined object should not be documented.
#
-# - For method definitions in C code, it must be placed before the
-# implementation:
-#
-# /* :nodoc: */
-# static VALUE
-# some_method(VALUE self)
-# {
-# return self;
-# }
-#
-# Note that this directive has <em>no effect at all</em> at method
-# definition places. E.g.,
-#
-# /* :nodoc: */
-# rb_define_method(cMyClass, "do_something", something_func, 0);
-#
-# The above comment is just a comment and has nothing to do with \RDoc.
-# Therefore, +do_something+ method will be reported as "undocumented"
-# unless that method or function is documented elsewhere.
-#
-# - For constant definitions in C code, this directive <em>can not work</em>
-# because there is no "implementation" place for constants.
-#
# - <tt># :nodoc: all</tt>:
#
# - Appended to a line of code
@@ -526,8 +502,8 @@ require 'rdoc'
# #++
# # Documented.
#
-# For C code, any of directives <tt>:startdoc:</tt>, <tt>:stopdoc:</tt>,
-# and <tt>:enddoc:</tt> may appear in a stand-alone comment:
+# For C code, any of directives <tt>:startdoc:</tt>, <tt>:enddoc:</tt>,
+# and <tt>:nodoc:</tt> may appear in a stand-alone comment:
#
# /* :startdoc: */
# /* :stopdoc: */
@@ -1216,26 +1192,13 @@ require 'rdoc'
#
class RDoc::MarkupReference
- # example class
class DummyClass; end
-
- # example module
module DummyModule; end
-
- # example singleton method
def self.dummy_singleton_method(foo, bar); end
-
- # example instance method
def dummy_instance_method(foo, bar); end;
-
alias dummy_instance_alias dummy_instance_method
-
- # example attribute
attr_accessor :dummy_attribute
-
alias dummy_attribute_alias dummy_attribute
-
- # example constant
DUMMY_CONSTANT = ''
# :call-seq:
diff --git a/doc/regexp.rdoc b/doc/regexp.rdoc
new file mode 100644
index 0000000000..92c7ecf66e
--- /dev/null
+++ b/doc/regexp.rdoc
@@ -0,0 +1,801 @@
+# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*-
+
+Regular expressions (<i>regexp</i>s) are patterns which describe the
+contents of a string. They're used for testing whether a string contains a
+given pattern, or extracting the portions that match. They are created
+with the <tt>/</tt><i>pat</i><tt>/</tt> and
+<tt>%r{</tt><i>pat</i><tt>}</tt> literals or the <tt>Regexp.new</tt>
+constructor.
+
+A regexp is usually delimited with forward slashes (<tt>/</tt>). For
+example:
+
+ /hay/ =~ 'haystack' #=> 0
+ /y/.match('haystack') #=> #<MatchData "y">
+
+If a string contains the pattern it is said to <i>match</i>. A literal
+string matches itself.
+
+Here 'haystack' does not contain the pattern 'needle', so it doesn't match:
+
+ /needle/.match('haystack') #=> nil
+
+Here 'haystack' contains the pattern 'hay', so it matches:
+
+ /hay/.match('haystack') #=> #<MatchData "hay">
+
+Specifically, <tt>/st/</tt> requires that the string contains the letter
+_s_ followed by the letter _t_, so it matches _haystack_, also.
+
+Note that any Regexp matching will raise a RuntimeError if timeout is set and
+exceeded. See {"Timeout"}[#label-Timeout] section in detail.
+
+== \Regexp Interpolation
+
+A regexp may contain interpolated strings; trivially:
+
+ foo = 'bar'
+ /#{foo}/ # => /bar/
+
+== <tt>=~</tt> and Regexp#match
+
+Pattern matching may be achieved by using <tt>=~</tt> operator or Regexp#match
+method.
+
+=== <tt>=~</tt> Operator
+
+<tt>=~</tt> is Ruby's basic pattern-matching operator. When one operand is a
+regular expression and the other is a string then the regular expression is
+used as a pattern to match against the string. (This operator is equivalently
+defined by Regexp and String so the order of String and Regexp do not matter.
+Other classes may have different implementations of <tt>=~</tt>.) If a match
+is found, the operator returns index of first match in string, otherwise it
+returns +nil+.
+
+ /hay/ =~ 'haystack' #=> 0
+ 'haystack' =~ /hay/ #=> 0
+ /a/ =~ 'haystack' #=> 1
+ /u/ =~ 'haystack' #=> nil
+
+Using <tt>=~</tt> operator with a String and Regexp the <tt>$~</tt> global
+variable is set after a successful match. <tt>$~</tt> holds a MatchData
+object. Regexp.last_match is equivalent to <tt>$~</tt>.
+
+=== Regexp#match Method
+
+The #match method returns a MatchData object:
+
+ /st/.match('haystack') #=> #<MatchData "st">
+
+== Metacharacters and Escapes
+
+The following are <i>metacharacters</i> <tt>(</tt>, <tt>)</tt>,
+<tt>[</tt>, <tt>]</tt>, <tt>{</tt>, <tt>}</tt>, <tt>.</tt>, <tt>?</tt>,
+<tt>+</tt>, <tt>*</tt>. They have a specific meaning when appearing in a
+pattern. To match them literally they must be backslash-escaped. To match
+a backslash literally, backslash-escape it: <tt>\\\\</tt>.
+
+ /1 \+ 2 = 3\?/.match('Does 1 + 2 = 3?') #=> #<MatchData "1 + 2 = 3?">
+ /a\\\\b/.match('a\\\\b') #=> #<MatchData "a\\b">
+
+Patterns behave like double-quoted strings and can contain the same
+backslash escapes (the meaning of <tt>\s</tt> is different, however,
+see below[#label-Character+Classes]).
+
+ /\s\u{6771 4eac 90fd}/.match("Go to æ±äº¬éƒ½")
+ #=> #<MatchData " æ±äº¬éƒ½">
+
+Arbitrary Ruby expressions can be embedded into patterns with the
+<tt>#{...}</tt> construct.
+
+ place = "æ±äº¬éƒ½"
+ /#{place}/.match("Go to æ±äº¬éƒ½")
+ #=> #<MatchData "æ±äº¬éƒ½">
+
+== Character Classes
+
+A <i>character class</i> is delimited with square brackets (<tt>[</tt>,
+<tt>]</tt>) and lists characters that may appear at that point in the
+match. <tt>/[ab]/</tt> means _a_ or _b_, as opposed to <tt>/ab/</tt> which
+means _a_ followed by _b_.
+
+ /W[aeiou]rd/.match("Word") #=> #<MatchData "Word">
+
+Within a character class the hyphen (<tt>-</tt>) is a metacharacter
+denoting an inclusive range of characters. <tt>[abcd]</tt> is equivalent
+to <tt>[a-d]</tt>. A range can be followed by another range, so
+<tt>[abcdwxyz]</tt> is equivalent to <tt>[a-dw-z]</tt>. The order in which
+ranges or individual characters appear inside a character class is
+irrelevant.
+
+ /[0-9a-f]/.match('9f') #=> #<MatchData "9">
+ /[9f]/.match('9f') #=> #<MatchData "9">
+
+If the first character of a character class is a caret (<tt>^</tt>) the
+class is inverted: it matches any character _except_ those named.
+
+ /[^a-eg-z]/.match('f') #=> #<MatchData "f">
+
+A character class may contain another character class. By itself this
+isn't useful because <tt>[a-z[0-9]]</tt> describes the same set as
+<tt>[a-z0-9]</tt>. However, character classes also support the <tt>&&</tt>
+operator which performs set intersection on its arguments. The two can be
+combined as follows:
+
+ /[a-w&&[^c-g]z]/ # ([a-w] AND ([^c-g] OR z))
+
+This is equivalent to:
+
+ /[abh-w]/
+
+The following metacharacters also behave like character classes:
+
+* <tt>/./</tt> - Any character except a newline.
+* <tt>/./m</tt> - Any character (the +m+ modifier enables multiline mode)
+* <tt>/\w/</tt> - A word character (<tt>[a-zA-Z0-9_]</tt>)
+* <tt>/\W/</tt> - A non-word character (<tt>[^a-zA-Z0-9_]</tt>).
+ Please take a look at {Bug #4044}[https://bugs.ruby-lang.org/issues/4044] if
+ using <tt>/\W/</tt> with the <tt>/i</tt> modifier.
+* <tt>/\d/</tt> - A digit character (<tt>[0-9]</tt>)
+* <tt>/\D/</tt> - A non-digit character (<tt>[^0-9]</tt>)
+* <tt>/\h/</tt> - A hexdigit character (<tt>[0-9a-fA-F]</tt>)
+* <tt>/\H/</tt> - A non-hexdigit character (<tt>[^0-9a-fA-F]</tt>)
+* <tt>/\s/</tt> - A whitespace character: <tt>/[ \t\r\n\f\v]/</tt>
+* <tt>/\S/</tt> - A non-whitespace character: <tt>/[^ \t\r\n\f\v]/</tt>
+* <tt>/\R/</tt> - A linebreak: <tt>\n</tt>, <tt>\v</tt>, <tt>\f</tt>, <tt>\r</tt>
+ <tt>\u0085</tt> (NEXT LINE), <tt>\u2028</tt> (LINE SEPARATOR), <tt>\u2029</tt> (PARAGRAPH SEPARATOR)
+ or <tt>\r\n</tt>.
+
+POSIX <i>bracket expressions</i> are also similar to character classes.
+They provide a portable alternative to the above, with the added benefit
+that they encompass non-ASCII characters. For instance, <tt>/\d/</tt>
+matches only the ASCII decimal digits (0-9); whereas <tt>/[[:digit:]]/</tt>
+matches any character in the Unicode _Nd_ category.
+
+* <tt>/[[:alnum:]]/</tt> - Alphabetic and numeric character
+* <tt>/[[:alpha:]]/</tt> - Alphabetic character
+* <tt>/[[:blank:]]/</tt> - Space or tab
+* <tt>/[[:cntrl:]]/</tt> - Control character
+* <tt>/[[:digit:]]/</tt> - Digit
+* <tt>/[[:graph:]]/</tt> - Non-blank character (excludes spaces, control
+ characters, and similar)
+* <tt>/[[:lower:]]/</tt> - Lowercase alphabetical character
+* <tt>/[[:print:]]/</tt> - Like [:graph:], but includes the space character
+* <tt>/[[:punct:]]/</tt> - Punctuation character
+* <tt>/[[:space:]]/</tt> - Whitespace character (<tt>[:blank:]</tt>, newline,
+ carriage return, etc.)
+* <tt>/[[:upper:]]/</tt> - Uppercase alphabetical
+* <tt>/[[:xdigit:]]/</tt> - Digit allowed in a hexadecimal number (i.e.,
+ 0-9a-fA-F)
+
+Ruby also supports the following non-POSIX character classes:
+
+* <tt>/[[:word:]]/</tt> - A character in one of the following Unicode
+ general categories _Letter_, _Mark_, _Number_,
+ <i>Connector_Punctuation</i>
+* <tt>/[[:ascii:]]/</tt> - A character in the ASCII character set
+
+ # U+06F2 is "EXTENDED ARABIC-INDIC DIGIT TWO"
+ /[[:digit:]]/.match("\u06F2") #=> #<MatchData "\u{06F2}">
+ /[[:upper:]][[:lower:]]/.match("Hello") #=> #<MatchData "He">
+ /[[:xdigit:]][[:xdigit:]]/.match("A6") #=> #<MatchData "A6">
+
+== Repetition
+
+The constructs described so far match a single character. They can be
+followed by a repetition metacharacter to specify how many times they need
+to occur. Such metacharacters are called <i>quantifiers</i>.
+
+* <tt>*</tt> - Zero or more times
+* <tt>+</tt> - One or more times
+* <tt>?</tt> - Zero or one times (optional)
+* <tt>{</tt><i>n</i><tt>}</tt> - Exactly <i>n</i> times
+* <tt>{</tt><i>n</i><tt>,}</tt> - <i>n</i> or more times
+* <tt>{,</tt><i>m</i><tt>}</tt> - <i>m</i> or less times
+* <tt>{</tt><i>n</i><tt>,</tt><i>m</i><tt>}</tt> - At least <i>n</i> and
+ at most <i>m</i> times
+
+At least one uppercase character ('H'), at least one lowercase character
+('e'), two 'l' characters, then one 'o':
+
+ "Hello".match(/[[:upper:]]+[[:lower:]]+l{2}o/) #=> #<MatchData "Hello">
+
+=== Greedy Match
+
+Repetition is <i>greedy</i> by default: as many occurrences as possible
+are matched while still allowing the overall match to succeed. By
+contrast, <i>lazy</i> matching makes the minimal amount of matches
+necessary for overall success. Most greedy metacharacters can be made lazy
+by following them with <tt>?</tt>. For the <tt>{n}</tt> pattern, because
+it specifies an exact number of characters to match and not a variable
+number of characters, the <tt>?</tt> metacharacter instead makes the
+repeated pattern optional.
+
+Both patterns below match the string. The first uses a greedy quantifier so
+'.+' matches '<a><b>'; the second uses a lazy quantifier so '.+?' matches
+'<a>':
+
+ /<.+>/.match("<a><b>") #=> #<MatchData "<a><b>">
+ /<.+?>/.match("<a><b>") #=> #<MatchData "<a>">
+
+=== Possessive Match
+
+A quantifier followed by <tt>+</tt> matches <i>possessively</i>: once it
+has matched it does not backtrack. They behave like greedy quantifiers,
+but having matched they refuse to "give up" their match even if this
+jeopardises the overall match.
+
+ /<.*><.+>/.match("<a><b>") #=> #<MatchData "<a><b>">
+ /<.*+><.+>/.match("<a><b>") #=> nil
+ /<.*><.++>/.match("<a><b>") #=> nil
+
+== Capturing
+
+Parentheses can be used for <i>capturing</i>. The text enclosed by the
+<i>n</i>th group of parentheses can be subsequently referred to
+with <i>n</i>. Within a pattern use the <i>backreference</i>
+<tt>\n</tt> (e.g. <tt>\1</tt>); outside of the pattern use
+<tt>MatchData[n]</tt> (e.g. <tt>MatchData[1]</tt>).
+
+In this example, <tt>'at'</tt> is captured by the first group of
+parentheses, then referred to later with <tt>\1</tt>:
+
+ /[csh](..) [csh]\1 in/.match("The cat sat in the hat")
+ #=> #<MatchData "cat sat in" 1:"at">
+
+Regexp#match returns a MatchData object which makes the captured text
+available with its #[] method:
+
+ /[csh](..) [csh]\1 in/.match("The cat sat in the hat")[1] #=> 'at'
+
+While Ruby supports an arbitrary number of numbered captured groups,
+only groups 1-9 are supported using the <tt>\n</tt> backreference
+syntax.
+
+Ruby also supports <tt>\0</tt> as a special backreference, which
+references the entire matched string. This is also available at
+<tt>MatchData[0]</tt>. Note that the <tt>\0</tt> backreference cannot
+be used inside the regexp, as backreferences can only be used after the
+end of the capture group, and the <tt>\0</tt> backreference uses the
+implicit capture group of the entire match. However, you can use
+this backreference when doing substitution:
+
+ "The cat sat in the hat".gsub(/[csh]at/, '\0s')
+ # => "The cats sats in the hats"
+
+=== Named Captures
+
+Capture groups can be referred to by name when defined with the
+<tt>(?<</tt><i>name</i><tt>>)</tt> or <tt>(?'</tt><i>name</i><tt>')</tt>
+constructs.
+
+ /\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")
+ #=> #<MatchData "$3.67" dollars:"3" cents:"67">
+ /\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")[:dollars] #=> "3"
+
+Named groups can be backreferenced with <tt>\k<</tt><i>name</i><tt>></tt>,
+where _name_ is the group name.
+
+ /(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
+ #=> #<MatchData "ototo" vowel:"o">
+
+*Note*: A regexp can't use named backreferences and numbered
+backreferences simultaneously. Also, if a named capture is used in a
+regexp, then parentheses used for grouping which would otherwise result
+in a unnamed capture are treated as non-capturing.
+
+ /(\w)(\w)/.match("ab").captures # => ["a", "b"]
+ /(\w)(\w)/.match("ab").named_captures # => {}
+
+ /(?<c>\w)(\w)/.match("ab").captures # => ["a"]
+ /(?<c>\w)(\w)/.match("ab").named_captures # => {"c"=>"a"}
+
+When named capture groups are used with a literal regexp on the left-hand
+side of an expression and the <tt>=~</tt> operator, the captured text is
+also assigned to local variables with corresponding names.
+
+ /\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
+ dollars #=> "3"
+
+== Grouping
+
+Parentheses also <i>group</i> the terms they enclose, allowing them to be
+quantified as one <i>atomic</i> whole.
+
+The pattern below matches a vowel followed by 2 word characters:
+
+ /[aeiou]\w{2}/.match("Caenorhabditis elegans") #=> #<MatchData "aen">
+
+Whereas the following pattern matches a vowel followed by a word character,
+twice, i.e. <tt>[aeiou]\w[aeiou]\w</tt>: 'enor'.
+
+ /([aeiou]\w){2}/.match("Caenorhabditis elegans")
+ #=> #<MatchData "enor" 1:"or">
+
+The <tt>(?:</tt>...<tt>)</tt> construct provides grouping without
+capturing. That is, it combines the terms it contains into an atomic whole
+without creating a backreference. This benefits performance at the slight
+expense of readability.
+
+The first group of parentheses captures 'n' and the second 'ti'. The second
+group is referred to later with the backreference <tt>\2</tt>:
+
+ /I(n)ves(ti)ga\2ons/.match("Investigations")
+ #=> #<MatchData "Investigations" 1:"n" 2:"ti">
+
+The first group of parentheses is now made non-capturing with '?:', so it
+still matches 'n', but doesn't create the backreference. Thus, the
+backreference <tt>\1</tt> now refers to 'ti'.
+
+ /I(?:n)ves(ti)ga\1ons/.match("Investigations")
+ #=> #<MatchData "Investigations" 1:"ti">
+
+=== Atomic Grouping
+
+Grouping can be made <i>atomic</i> with
+<tt>(?></tt><i>pat</i><tt>)</tt>. This causes the subexpression <i>pat</i>
+to be matched independently of the rest of the expression such that what
+it matches becomes fixed for the remainder of the match, unless the entire
+subexpression must be abandoned and subsequently revisited. In this
+way <i>pat</i> is treated as a non-divisible whole. Atomic grouping is
+typically used to optimise patterns so as to prevent the regular
+expression engine from backtracking needlessly.
+
+The <tt>"</tt> in the pattern below matches the first character of the string,
+then <tt>.*</tt> matches <i>Quote"</i>. This causes the overall match to fail,
+so the text matched by <tt>.*</tt> is backtracked by one position, which
+leaves the final character of the string available to match <tt>"</tt>
+
+ /".*"/.match('"Quote"') #=> #<MatchData "\"Quote\"">
+
+If <tt>.*</tt> is grouped atomically, it refuses to backtrack <i>Quote"</i>,
+even though this means that the overall match fails
+
+ /"(?>.*)"/.match('"Quote"') #=> nil
+
+== Subexpression Calls
+
+The <tt>\g<</tt><i>name</i><tt>></tt> syntax matches the previous
+subexpression named _name_, which can be a group name or number, again.
+This differs from backreferences in that it re-executes the group rather
+than simply trying to re-match the same text.
+
+This pattern matches a <i>(</i> character and assigns it to the <tt>paren</tt>
+group, tries to call that the <tt>paren</tt> sub-expression again but fails,
+then matches a literal <i>)</i>:
+
+ /\A(?<paren>\(\g<paren>*\))*\z/ =~ '()'
+
+
+ /\A(?<paren>\(\g<paren>*\))*\z/ =~ '(())' #=> 0
+ # ^1
+ # ^2
+ # ^3
+ # ^4
+ # ^5
+ # ^6
+ # ^7
+ # ^8
+ # ^9
+ # ^10
+
+1. Matches at the beginning of the string, i.e. before the first
+ character.
+2. Enters a named capture group called <tt>paren</tt>
+3. Matches a literal <i>(</i>, the first character in the string
+4. Calls the <tt>paren</tt> group again, i.e. recurses back to the
+ second step
+5. Re-enters the <tt>paren</tt> group
+6. Matches a literal <i>(</i>, the second character in the
+ string
+7. Try to call <tt>paren</tt> a third time, but fail because
+ doing so would prevent an overall successful match
+8. Match a literal <i>)</i>, the third character in the string.
+ Marks the end of the second recursive call
+9. Match a literal <i>)</i>, the fourth character in the string
+10. Match the end of the string
+
+== Alternation
+
+The vertical bar metacharacter (<tt>|</tt>) combines several expressions into
+a single one that matches any of the expressions. Each expression is an
+<i>alternative</i>.
+
+ /\w(and|or)\w/.match("Feliformia") #=> #<MatchData "form" 1:"or">
+ /\w(and|or)\w/.match("furandi") #=> #<MatchData "randi" 1:"and">
+ /\w(and|or)\w/.match("dissemblance") #=> nil
+
+== Character Properties
+
+The <tt>\p{}</tt> construct matches characters with the named property,
+much like POSIX bracket classes.
+
+* <tt>/\p{Alnum}/</tt> - Alphabetic and numeric character
+* <tt>/\p{Alpha}/</tt> - Alphabetic character
+* <tt>/\p{Blank}/</tt> - Space or tab
+* <tt>/\p{Cntrl}/</tt> - Control character
+* <tt>/\p{Digit}/</tt> - Digit
+* <tt>/\p{Emoji}/</tt> - Unicode emoji
+* <tt>/\p{Graph}/</tt> - Non-blank character (excludes spaces, control
+ characters, and similar)
+* <tt>/\p{Lower}/</tt> - Lowercase alphabetical character
+* <tt>/\p{Print}/</tt> - Like <tt>\p{Graph}</tt>, but includes the space character
+* <tt>/\p{Punct}/</tt> - Punctuation character
+* <tt>/\p{Space}/</tt> - Whitespace character (<tt>[:blank:]</tt>, newline,
+ carriage return, etc.)
+* <tt>/\p{Upper}/</tt> - Uppercase alphabetical
+* <tt>/\p{XDigit}/</tt> - Digit allowed in a hexadecimal number (i.e., 0-9a-fA-F)
+* <tt>/\p{Word}/</tt> - A member of one of the following Unicode general
+ category <i>Letter</i>, <i>Mark</i>, <i>Number</i>,
+ <i>Connector\_Punctuation</i>
+* <tt>/\p{ASCII}/</tt> - A character in the ASCII character set
+* <tt>/\p{Any}/</tt> - Any Unicode character (including unassigned
+ characters)
+* <tt>/\p{Assigned}/</tt> - An assigned character
+
+A Unicode character's <i>General Category</i> value can also be matched
+with <tt>\p{</tt><i>Ab</i><tt>}</tt> where <i>Ab</i> is the category's
+abbreviation as described below:
+
+* <tt>/\p{L}/</tt> - 'Letter'
+* <tt>/\p{Ll}/</tt> - 'Letter: Lowercase'
+* <tt>/\p{Lm}/</tt> - 'Letter: Mark'
+* <tt>/\p{Lo}/</tt> - 'Letter: Other'
+* <tt>/\p{Lt}/</tt> - 'Letter: Titlecase'
+* <tt>/\p{Lu}/</tt> - 'Letter: Uppercase
+* <tt>/\p{Lo}/</tt> - 'Letter: Other'
+* <tt>/\p{M}/</tt> - 'Mark'
+* <tt>/\p{Mn}/</tt> - 'Mark: Nonspacing'
+* <tt>/\p{Mc}/</tt> - 'Mark: Spacing Combining'
+* <tt>/\p{Me}/</tt> - 'Mark: Enclosing'
+* <tt>/\p{N}/</tt> - 'Number'
+* <tt>/\p{Nd}/</tt> - 'Number: Decimal Digit'
+* <tt>/\p{Nl}/</tt> - 'Number: Letter'
+* <tt>/\p{No}/</tt> - 'Number: Other'
+* <tt>/\p{P}/</tt> - 'Punctuation'
+* <tt>/\p{Pc}/</tt> - 'Punctuation: Connector'
+* <tt>/\p{Pd}/</tt> - 'Punctuation: Dash'
+* <tt>/\p{Ps}/</tt> - 'Punctuation: Open'
+* <tt>/\p{Pe}/</tt> - 'Punctuation: Close'
+* <tt>/\p{Pi}/</tt> - 'Punctuation: Initial Quote'
+* <tt>/\p{Pf}/</tt> - 'Punctuation: Final Quote'
+* <tt>/\p{Po}/</tt> - 'Punctuation: Other'
+* <tt>/\p{S}/</tt> - 'Symbol'
+* <tt>/\p{Sm}/</tt> - 'Symbol: Math'
+* <tt>/\p{Sc}/</tt> - 'Symbol: Currency'
+* <tt>/\p{Sc}/</tt> - 'Symbol: Currency'
+* <tt>/\p{Sk}/</tt> - 'Symbol: Modifier'
+* <tt>/\p{So}/</tt> - 'Symbol: Other'
+* <tt>/\p{Z}/</tt> - 'Separator'
+* <tt>/\p{Zs}/</tt> - 'Separator: Space'
+* <tt>/\p{Zl}/</tt> - 'Separator: Line'
+* <tt>/\p{Zp}/</tt> - 'Separator: Paragraph'
+* <tt>/\p{C}/</tt> - 'Other'
+* <tt>/\p{Cc}/</tt> - 'Other: Control'
+* <tt>/\p{Cf}/</tt> - 'Other: Format'
+* <tt>/\p{Cn}/</tt> - 'Other: Not Assigned'
+* <tt>/\p{Co}/</tt> - 'Other: Private Use'
+* <tt>/\p{Cs}/</tt> - 'Other: Surrogate'
+
+Lastly, <tt>\p{}</tt> matches a character's Unicode <i>script</i>. The
+following scripts are supported: <i>Arabic</i>, <i>Armenian</i>,
+<i>Balinese</i>, <i>Bengali</i>, <i>Bopomofo</i>, <i>Braille</i>,
+<i>Buginese</i>, <i>Buhid</i>, <i>Canadian_Aboriginal</i>, <i>Carian</i>,
+<i>Cham</i>, <i>Cherokee</i>, <i>Common</i>, <i>Coptic</i>,
+<i>Cuneiform</i>, <i>Cypriot</i>, <i>Cyrillic</i>, <i>Deseret</i>,
+<i>Devanagari</i>, <i>Ethiopic</i>, <i>Georgian</i>, <i>Glagolitic</i>,
+<i>Gothic</i>, <i>Greek</i>, <i>Gujarati</i>, <i>Gurmukhi</i>, <i>Han</i>,
+<i>Hangul</i>, <i>Hanunoo</i>, <i>Hebrew</i>, <i>Hiragana</i>,
+<i>Inherited</i>, <i>Kannada</i>, <i>Katakana</i>, <i>Kayah_Li</i>,
+<i>Kharoshthi</i>, <i>Khmer</i>, <i>Lao</i>, <i>Latin</i>, <i>Lepcha</i>,
+<i>Limbu</i>, <i>Linear_B</i>, <i>Lycian</i>, <i>Lydian</i>,
+<i>Malayalam</i>, <i>Mongolian</i>, <i>Myanmar</i>, <i>New_Tai_Lue</i>,
+<i>Nko</i>, <i>Ogham</i>, <i>Ol_Chiki</i>, <i>Old_Italic</i>,
+<i>Old_Persian</i>, <i>Oriya</i>, <i>Osmanya</i>, <i>Phags_Pa</i>,
+<i>Phoenician</i>, <i>Rejang</i>, <i>Runic</i>, <i>Saurashtra</i>,
+<i>Shavian</i>, <i>Sinhala</i>, <i>Sundanese</i>, <i>Syloti_Nagri</i>,
+<i>Syriac</i>, <i>Tagalog</i>, <i>Tagbanwa</i>, <i>Tai_Le</i>,
+<i>Tamil</i>, <i>Telugu</i>, <i>Thaana</i>, <i>Thai</i>, <i>Tibetan</i>,
+<i>Tifinagh</i>, <i>Ugaritic</i>, <i>Vai</i>, and <i>Yi</i>.
+
+Unicode codepoint U+06E9 is named "ARABIC PLACE OF SAJDAH" and belongs to the
+Arabic script:
+
+ /\p{Arabic}/.match("\u06E9") #=> #<MatchData "\u06E9">
+
+All character properties can be inverted by prefixing their name with a
+caret (<tt>^</tt>).
+
+Letter 'A' is not in the Unicode Ll (Letter; Lowercase) category, so this
+match succeeds:
+
+ /\p{^Ll}/.match("A") #=> #<MatchData "A">
+
+== Anchors
+
+Anchors are metacharacter that match the zero-width positions between
+characters, <i>anchoring</i> the match to a specific position.
+
+* <tt>^</tt> - Matches beginning of line
+* <tt>$</tt> - Matches end of line
+* <tt>\A</tt> - Matches beginning of string.
+* <tt>\Z</tt> - Matches end of string. If string ends with a newline,
+ it matches just before newline
+* <tt>\z</tt> - Matches end of string
+* <tt>\G</tt> - Matches first matching position:
+
+ In methods like <tt>String#gsub</tt> and <tt>String#scan</tt>, it changes on each iteration.
+ It initially matches the beginning of subject, and in each following iteration it matches where the last match finished.
+
+ " a b c".gsub(/ /, '_') #=> "____a_b_c"
+ " a b c".gsub(/\G /, '_') #=> "____a b c"
+
+ In methods like <tt>Regexp#match</tt> and <tt>String#match</tt> that take an (optional) offset, it matches where the search begins.
+
+ "hello, world".match(/,/, 3) #=> #<MatchData ",">
+ "hello, world".match(/\G,/, 3) #=> nil
+
+* <tt>\b</tt> - Matches word boundaries when outside brackets;
+ backspace (0x08) when inside brackets
+* <tt>\B</tt> - Matches non-word boundaries
+* <tt>(?=</tt><i>pat</i><tt>)</tt> - <i>Positive lookahead</i> assertion:
+ ensures that the following characters match <i>pat</i>, but doesn't
+ include those characters in the matched text
+* <tt>(?!</tt><i>pat</i><tt>)</tt> - <i>Negative lookahead</i> assertion:
+ ensures that the following characters do not match <i>pat</i>, but
+ doesn't include those characters in the matched text
+* <tt>(?<=</tt><i>pat</i><tt>)</tt> - <i>Positive lookbehind</i>
+ assertion: ensures that the preceding characters match <i>pat</i>, but
+ doesn't include those characters in the matched text
+* <tt>(?<!</tt><i>pat</i><tt>)</tt> - <i>Negative lookbehind</i>
+ assertion: ensures that the preceding characters do not match
+ <i>pat</i>, but doesn't include those characters in the matched text
+
+* <tt>\K</tt> - <i>Match reset</i>: the matched content preceding
+ <tt>\K</tt> in the regexp is excluded from the result. For example,
+ the following two regexps are almost equivalent:
+
+ /ab\Kc/ =~ "abc" #=> 0
+ /(?<=ab)c/ =~ "abc" #=> 2
+
+ These match same string and <i>$&</i> equals <tt>"c"</tt>, while the
+ matched position is different.
+
+ As are the following two regexps:
+
+ /(a)\K(b)\Kc/
+ /(?<=(?<=(a))(b))c/
+
+If a pattern isn't anchored it can begin at any point in the string:
+
+ /real/.match("surrealist") #=> #<MatchData "real">
+
+Anchoring the pattern to the beginning of the string forces the match to start
+there. 'real' doesn't occur at the beginning of the string, so now the match
+fails:
+
+ /\Areal/.match("surrealist") #=> nil
+
+The match below fails because although 'Demand' contains 'and', the pattern
+does not occur at a word boundary.
+
+ /\band/.match("Demand")
+
+Whereas in the following example 'and' has been anchored to a non-word
+boundary so instead of matching the first 'and' it matches from the fourth
+letter of 'demand' instead:
+
+ /\Band.+/.match("Supply and demand curve") #=> #<MatchData "and curve">
+
+The pattern below uses positive lookahead and positive lookbehind to match
+text appearing in <b></b> tags without including the tags in the match:
+
+ /(?<=<b>)\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>")
+ #=> #<MatchData "bold">
+
+== Options
+
+The end delimiter for a regexp can be followed by one or more single-letter
+options which control how the pattern can match.
+
+* <tt>/pat/i</tt> - Ignore case
+* <tt>/pat/m</tt> - Treat a newline as a character matched by <tt>.</tt>
+* <tt>/pat/x</tt> - Ignore whitespace and comments in the pattern
+* <tt>/pat/o</tt> - Perform <tt>#{}</tt> interpolation only once
+
+<tt>i</tt>, <tt>m</tt>, and <tt>x</tt> can also be applied on the
+subexpression level with the
+<tt>(?</tt><i>on</i><tt>-</tt><i>off</i><tt>)</tt> construct, which
+enables options <i>on</i>, and disables options <i>off</i> for the
+expression enclosed by the parentheses:
+
+ /a(?i:b)c/.match('aBc') #=> #<MatchData "aBc">
+ /a(?-i:b)c/i.match('ABC') #=> nil
+
+Additionally, these options can also be toggled for the remainder of the
+pattern:
+
+ /a(?i)bc/.match('abC') #=> #<MatchData "abC">
+
+Options may also be used with <tt>Regexp.new</tt>:
+
+ Regexp.new("abc", Regexp::IGNORECASE) #=> /abc/i
+ Regexp.new("abc", Regexp::MULTILINE) #=> /abc/m
+ Regexp.new("abc # Comment", Regexp::EXTENDED) #=> /abc # Comment/x
+ Regexp.new("abc", Regexp::IGNORECASE | Regexp::MULTILINE) #=> /abc/mi
+
+ Regexp.new("abc", "i") #=> /abc/i
+ Regexp.new("abc", "m") #=> /abc/m
+ Regexp.new("abc # Comment", "x") #=> /abc # Comment/x
+ Regexp.new("abc", "im") #=> /abc/mi
+
+== Free-Spacing Mode and Comments
+
+As mentioned above, the <tt>x</tt> option enables <i>free-spacing</i>
+mode. Literal white space inside the pattern is ignored, and the
+octothorpe (<tt>#</tt>) character introduces a comment until the end of
+the line. This allows the components of the pattern to be organized in a
+potentially more readable fashion.
+
+A contrived pattern to match a number with optional decimal places:
+
+ float_pat = /\A
+ [[:digit:]]+ # 1 or more digits before the decimal point
+ (\. # Decimal point
+ [[:digit:]]+ # 1 or more digits after the decimal point
+ )? # The decimal point and following digits are optional
+ \Z/x
+ float_pat.match('3.14') #=> #<MatchData "3.14" 1:".14">
+
+There are a number of strategies for matching whitespace:
+
+* Use a pattern such as <tt>\s</tt> or <tt>\p{Space}</tt>.
+* Use escaped whitespace such as <tt>\ </tt>, i.e. a space preceded by a backslash.
+* Use a character class such as <tt>[ ]</tt>.
+
+Comments can be included in a non-<tt>x</tt> pattern with the
+<tt>(?#</tt><i>comment</i><tt>)</tt> construct, where <i>comment</i> is
+arbitrary text ignored by the regexp engine.
+
+Comments in regexp literals cannot include unescaped terminator
+characters.
+
+== Encoding
+
+Regular expressions are assumed to use the source encoding. This can be
+overridden with one of the following modifiers.
+
+* <tt>/</tt><i>pat</i><tt>/u</tt> - UTF-8
+* <tt>/</tt><i>pat</i><tt>/e</tt> - EUC-JP
+* <tt>/</tt><i>pat</i><tt>/s</tt> - Windows-31J
+* <tt>/</tt><i>pat</i><tt>/n</tt> - ASCII-8BIT
+
+A regexp can be matched against a string when they either share an
+encoding, or the regexp's encoding is _US-ASCII_ and the string's encoding
+is ASCII-compatible.
+
+If a match between incompatible encodings is attempted an
+<tt>Encoding::CompatibilityError</tt> exception is raised.
+
+The <tt>Regexp#fixed_encoding?</tt> predicate indicates whether the regexp
+has a <i>fixed</i> encoding, that is one incompatible with ASCII. A
+regexp's encoding can be explicitly fixed by supplying
+<tt>Regexp::FIXEDENCODING</tt> as the second argument of
+<tt>Regexp.new</tt>:
+
+ r = Regexp.new("a".force_encoding("iso-8859-1"),Regexp::FIXEDENCODING)
+ r =~ "a\u3042"
+ # raises Encoding::CompatibilityError: incompatible encoding regexp match
+ # (ISO-8859-1 regexp with UTF-8 string)
+
+== \Regexp Global Variables
+
+Pattern matching sets some global variables :
+
+* <tt>$~</tt> is equivalent to Regexp.last_match;
+* <tt>$&</tt> contains the complete matched text;
+* <tt>$`</tt> contains string before match;
+* <tt>$'</tt> contains string after match;
+* <tt>$1</tt>, <tt>$2</tt> and so on contain text matching first, second, etc
+ capture group;
+* <tt>$+</tt> contains last capture group.
+
+Example:
+
+ m = /s(\w{2}).*(c)/.match('haystack') #=> #<MatchData "stac" 1:"ta" 2:"c">
+ $~ #=> #<MatchData "stac" 1:"ta" 2:"c">
+ Regexp.last_match #=> #<MatchData "stac" 1:"ta" 2:"c">
+
+ $& #=> "stac"
+ # same as m[0]
+ $` #=> "hay"
+ # same as m.pre_match
+ $' #=> "k"
+ # same as m.post_match
+ $1 #=> "ta"
+ # same as m[1]
+ $2 #=> "c"
+ # same as m[2]
+ $3 #=> nil
+ # no third group in pattern
+ $+ #=> "c"
+ # same as m[-1]
+
+These global variables are thread-local and method-local variables.
+
+== Performance
+
+Certain pathological combinations of constructs can lead to abysmally bad
+performance.
+
+Consider a string of 25 <i>a</i>s, a <i>d</i>, 4 <i>a</i>s, and a
+<i>c</i>.
+
+ s = 'a' * 25 + 'd' + 'a' * 4 + 'c'
+ #=> "aaaaaaaaaaaaaaaaaaaaaaaaadaaaac"
+
+The following patterns match instantly as you would expect:
+
+ /(b|a)/ =~ s #=> 0
+ /(b|a+)/ =~ s #=> 0
+ /(b|a+)*/ =~ s #=> 0
+
+However, the following pattern takes appreciably longer:
+
+ /(b|a+)*c/ =~ s #=> 26
+
+This happens because an atom in the regexp is quantified by both an
+immediate <tt>+</tt> and an enclosing <tt>*</tt> with nothing to
+differentiate which is in control of any particular character. The
+nondeterminism that results produces super-linear performance. (Consult
+<i>Mastering Regular Expressions</i> (3rd ed.), pp 222, by
+<i>Jeffery Friedl</i>, for an in-depth analysis). This particular case
+can be fixed by use of atomic grouping, which prevents the unnecessary
+backtracking:
+
+ (start = Time.now) && /(b|a+)*c/ =~ s && (Time.now - start)
+ #=> 24.702736882
+ (start = Time.now) && /(?>b|a+)*c/ =~ s && (Time.now - start)
+ #=> 0.000166571
+
+A similar case is typified by the following example, which takes
+approximately 60 seconds to execute for me:
+
+Match a string of 29 <i>a</i>s against a pattern of 29 optional <i>a</i>s
+followed by 29 mandatory <i>a</i>s:
+
+ Regexp.new('a?' * 29 + 'a' * 29) =~ 'a' * 29
+
+The 29 optional <i>a</i>s match the string, but this prevents the 29
+mandatory <i>a</i>s that follow from matching. Ruby must then backtrack
+repeatedly so as to satisfy as many of the optional matches as it can
+while still matching the mandatory 29. It is plain to us that none of the
+optional matches can succeed, but this fact unfortunately eludes Ruby.
+
+The best way to improve performance is to significantly reduce the amount of
+backtracking needed. For this case, instead of individually matching 29
+optional <i>a</i>s, a range of optional <i>a</i>s can be matched all at once
+with <i>a{0,29}</i>:
+
+ Regexp.new('a{0,29}' + 'a' * 29) =~ 'a' * 29
+
+== Timeout
+
+There are two APIs to set timeout. One is Regexp.timeout=, which is
+process-global configuration of timeout for Regexp matching.
+
+ Regexp.timeout = 3
+ s = 'a' * 25 + 'd' + 'a' * 4 + 'c'
+ /(b|a+)*c/ =~ s #=> This raises an exception in three seconds
+
+The other is timeout keyword of Regexp.new.
+
+ re = Regexp.new("(b|a+)*c", timeout: 3)
+ s = 'a' * 25 + 'd' + 'a' * 4 + 'c'
+ /(b|a+)*c/ =~ s #=> This raises an exception in three seconds
+
+When using Regexps to process untrusted input, you should use the timeout
+feature to avoid excessive backtracking. Otherwise, a malicious user can
+provide input to Regexp causing Denial-of-Service attack.
+Note that the timeout is not set by default because an appropriate limit
+highly depends on an application requirement and context.
diff --git a/doc/regexp/methods.rdoc b/doc/regexp/methods.rdoc
deleted file mode 100644
index 356156ac9a..0000000000
--- a/doc/regexp/methods.rdoc
+++ /dev/null
@@ -1,41 +0,0 @@
-== \Regexp Methods
-
-Each of these Ruby core methods can accept a regexp as an argument:
-
-- Enumerable#all?
-- Enumerable#any?
-- Enumerable#grep
-- Enumerable#grep_v
-- Enumerable#none?
-- Enumerable#one?
-- Enumerable#slice_after
-- Enumerable#slice_before
-- Regexp#=~
-- Regexp#match
-- Regexp#match?
-- Regexp.new
-- Regexp.union
-- String#=~
-- String#[]=
-- String#byteindex
-- String#byterindex
-- String#gsub
-- String#gsub!
-- String#index
-- String#match
-- String#match?
-- String#partition
-- String#rindex
-- String#rpartition
-- String#scan
-- String#slice
-- String#slice!
-- String#split
-- String#start_with?
-- String#sub
-- String#sub!
-- Symbol#=~
-- Symbol#match
-- Symbol#match?
-- Symbol#slice
-- Symbol#start_with?
diff --git a/doc/regexp/unicode_properties.rdoc b/doc/regexp/unicode_properties.rdoc
deleted file mode 100644
index a1d7ecc380..0000000000
--- a/doc/regexp/unicode_properties.rdoc
+++ /dev/null
@@ -1,678 +0,0 @@
-== \Regexps Based on Unicode Properties
-
-The properties shown here are those currently supported in Ruby.
-Older versions may not support all of these.
-
-=== POSIX brackets
-
-- <tt>\p{ASCII}</tt>
-- <tt>\p{Alnum}</tt>
-- <tt>\p{Alphabetic}</tt>, <tt>\p{Alpha}</tt>
-- <tt>\p{Blank}</tt>
-- <tt>\p{Cntrl}</tt>
-- <tt>\p{Digit}</tt>
-- <tt>\p{Graph}</tt>
-- <tt>\p{Lowercase}</tt>, <tt>\p{Lower}</tt>
-- <tt>\p{Print}</tt>
-- <tt>\p{Punct}</tt>
-- <tt>\p{Space}</tt>
-- <tt>\p{Uppercase}</tt>, <tt>\p{Upper}</tt>
-- <tt>\p{Word}</tt>
-- <tt>\p{XDigit}</tt>
-- <tt>\p{XPosixPunct}</tt>
-
-=== Special
-
-- <tt>\p{Any}</tt>
-- <tt>\p{Assigned}</tt>
-
-=== Major and General Categories
-
-- <tt>\p{Cased_Letter}</tt>, <tt>\p{LC}</tt>
-- <tt>\p{Close_Punctuation}</tt>, <tt>\p{Pe}</tt>
-- <tt>\p{Connector_Punctuation}</tt>, <tt>\p{Pc}</tt>
-- <tt>\p{Control}</tt>, <tt>\p{Cc}</tt>
-- <tt>\p{Currency_Symbol}</tt>, <tt>\p{Sc}</tt>
-- <tt>\p{Dash_Punctuation}</tt>, <tt>\p{Pd}</tt>
-- <tt>\p{Decimal_Number}</tt>, <tt>\p{Nd}</tt>
-- <tt>\p{Enclosing_Mark}</tt>, <tt>\p{Me}</tt>
-- <tt>\p{Final_Punctuation}</tt>, <tt>\p{Pf}</tt>
-- <tt>\p{Format}</tt>, <tt>\p{Cf}</tt>
-- <tt>\p{Initial_Punctuation}</tt>, <tt>\p{Pi}</tt>
-- <tt>\p{Letter}</tt>, <tt>\p{L}</tt>
-- <tt>\p{Letter_Number}</tt>, <tt>\p{Nl}</tt>
-- <tt>\p{Line_Separator}</tt>, <tt>\p{Zl}</tt>
-- <tt>\p{Lowercase_Letter}</tt>, <tt>\p{Ll}</tt>
-- <tt>\p{Mark}</tt>, <tt>\p{M}</tt>
-- <tt>\p{Math_Symbol}</tt>, <tt>\p{Sm}</tt>
-- <tt>\p{Modifier_Letter}</tt>, <tt>\p{Lm}</tt>
-- <tt>\p{Modifier_Symbol}</tt>, <tt>\p{Sk}</tt>
-- <tt>\p{Nonspacing_Mark}</tt>, <tt>\p{Mn}</tt>
-- <tt>\p{Number}</tt>, <tt>\p{N}</tt>
-- <tt>\p{Open_Punctuation}</tt>, <tt>\p{Ps}</tt>
-- <tt>\p{Other}</tt>, <tt>\p{C}</tt>
-- <tt>\p{Other_Letter}</tt>, <tt>\p{Lo}</tt>
-- <tt>\p{Other_Number}</tt>, <tt>\p{No}</tt>
-- <tt>\p{Other_Punctuation}</tt>, <tt>\p{Po}</tt>
-- <tt>\p{Other_Symbol}</tt>, <tt>\p{So}</tt>
-- <tt>\p{Paragraph_Separator}</tt>, <tt>\p{Zp}</tt>
-- <tt>\p{Private_Use}</tt>, <tt>\p{Co}</tt>
-- <tt>\p{Punctuation}</tt>, <tt>\p{P}</tt>
-- <tt>\p{Separator}</tt>, <tt>\p{Z}</tt>
-- <tt>\p{Space_Separator}</tt>, <tt>\p{Zs}</tt>
-- <tt>\p{Spacing_Mark}</tt>, <tt>\p{Mc}</tt>
-- <tt>\p{Surrogate}</tt>, <tt>\p{Cs}</tt>
-- <tt>\p{Symbol}</tt>, <tt>\p{S}</tt>
-- <tt>\p{Titlecase_Letter}</tt>, <tt>\p{Lt}</tt>
-- <tt>\p{Unassigned}</tt>, <tt>\p{Cn}</tt>
-- <tt>\p{Uppercase_Letter}</tt>, <tt>\p{Lu}</tt>
-
-=== Prop List
-
-- <tt>\p{ASCII_Hex_Digit}</tt>, <tt>\p{AHex}</tt>
-- <tt>\p{Bidi_Control}</tt>, <tt>\p{Bidi_C}</tt>
-- <tt>\p{Dash}</tt>
-- <tt>\p{Deprecated}</tt>, <tt>\p{Dep}</tt>
-- <tt>\p{Diacritic}</tt>, <tt>\p{Dia}</tt>
-- <tt>\p{Extender}</tt>, <tt>\p{Ext}</tt>
-- <tt>\p{Hex_Digit}</tt>, <tt>\p{Hex}</tt>
-- <tt>\p{Hyphen}</tt>
-- <tt>\p{IDS_Binary_Operator}</tt>, <tt>\p{IDSB}</tt>
-- <tt>\p{IDS_Trinary_Operator}</tt>, <tt>\p{IDST}</tt>
-- <tt>\p{Ideographic}</tt>, <tt>\p{Ideo}</tt>
-- <tt>\p{Join_Control}</tt>, <tt>\p{Join_C}</tt>
-- <tt>\p{Logical_Order_Exception}</tt>, <tt>\p{LOE}</tt>
-- <tt>\p{Noncharacter_Code_Point}</tt>, <tt>\p{NChar}</tt>
-- <tt>\p{Other_Alphabetic}</tt>, <tt>\p{OAlpha}</tt>
-- <tt>\p{Other_Default_Ignorable_Code_Point}</tt>, <tt>\p{ODI}</tt>
-- <tt>\p{Other_Grapheme_Extend}</tt>, <tt>\p{OGr_Ext}</tt>
-- <tt>\p{Other_ID_Continue}</tt>, <tt>\p{OIDC}</tt>
-- <tt>\p{Other_ID_Start}</tt>, <tt>\p{OIDS}</tt>
-- <tt>\p{Other_Lowercase}</tt>, <tt>\p{OLower}</tt>
-- <tt>\p{Other_Math}</tt>, <tt>\p{OMath}</tt>
-- <tt>\p{Other_Uppercase}</tt>, <tt>\p{OUpper}</tt>
-- <tt>\p{Pattern_Syntax}</tt>, <tt>\p{Pat_Syn}</tt>
-- <tt>\p{Pattern_White_Space}</tt>, <tt>\p{Pat_WS}</tt>
-- <tt>\p{Prepended_Concatenation_Mark}</tt>, <tt>\p{PCM}</tt>
-- <tt>\p{Quotation_Mark}</tt>, <tt>\p{QMark}</tt>
-- <tt>\p{Radical}</tt>
-- <tt>\p{Regional_Indicator}</tt>, <tt>\p{RI}</tt>
-- <tt>\p{Sentence_Terminal}</tt>, <tt>\p{STerm}</tt>
-- <tt>\p{Soft_Dotted}</tt>, <tt>\p{SD}</tt>
-- <tt>\p{Terminal_Punctuation}</tt>, <tt>\p{Term}</tt>
-- <tt>\p{Unified_Ideograph}</tt>, <tt>\p{UIdeo}</tt>
-- <tt>\p{Variation_Selector}</tt>, <tt>\p{VS}</tt>
-- <tt>\p{White_Space}</tt>, <tt>\p{WSpace}</tt>
-
-=== Derived Core Properties
-
-- <tt>\p{Alphabetic}</tt>, <tt>\p{Alpha}</tt>
-- <tt>\p{Case_Ignorable}</tt>, <tt>\p{CI}</tt>
-- <tt>\p{Cased}</tt>
-- <tt>\p{Changes_When_Casefolded}</tt>, <tt>\p{CWCF}</tt>
-- <tt>\p{Changes_When_Casemapped}</tt>, <tt>\p{CWCM}</tt>
-- <tt>\p{Changes_When_Lowercased}</tt>, <tt>\p{CWL}</tt>
-- <tt>\p{Changes_When_Titlecased}</tt>, <tt>\p{CWT}</tt>
-- <tt>\p{Changes_When_Uppercased}</tt>, <tt>\p{CWU}</tt>
-- <tt>\p{Default_Ignorable_Code_Point}</tt>, <tt>\p{DI}</tt>
-- <tt>\p{Grapheme_Base}</tt>, <tt>\p{Gr_Base}</tt>
-- <tt>\p{Grapheme_Extend}</tt>, <tt>\p{Gr_Ext}</tt>
-- <tt>\p{Grapheme_Link}</tt>, <tt>\p{Gr_Link}</tt>
-- <tt>\p{ID_Continue}</tt>, <tt>\p{IDC}</tt>
-- <tt>\p{ID_Start}</tt>, <tt>\p{IDS}</tt>
-- <tt>\p{Lowercase}</tt>, <tt>\p{Lower}</tt>
-- <tt>\p{Math}</tt>
-- <tt>\p{Uppercase}</tt>, <tt>\p{Upper}</tt>
-- <tt>\p{XID_Continue}</tt>, <tt>\p{XIDC}</tt>
-- <tt>\p{XID_Start}</tt>, <tt>\p{XIDS}</tt>
-
-=== Scripts
-
-- <tt>\p{Adlam}</tt>, <tt>\p{Adlm}</tt>
-- <tt>\p{Ahom}</tt>
-- <tt>\p{Anatolian_Hieroglyphs}</tt>, <tt>\p{Hluw}</tt>
-- <tt>\p{Arabic}</tt>, <tt>\p{Arab}</tt>
-- <tt>\p{Armenian}</tt>, <tt>\p{Armn}</tt>
-- <tt>\p{Avestan}</tt>, <tt>\p{Avst}</tt>
-- <tt>\p{Balinese}</tt>, <tt>\p{Bali}</tt>
-- <tt>\p{Bamum}</tt>, <tt>\p{Bamu}</tt>
-- <tt>\p{Bassa_Vah}</tt>, <tt>\p{Bass}</tt>
-- <tt>\p{Batak}</tt>, <tt>\p{Batk}</tt>
-- <tt>\p{Bengali}</tt>, <tt>\p{Beng}</tt>
-- <tt>\p{Bhaiksuki}</tt>, <tt>\p{Bhks}</tt>
-- <tt>\p{Bopomofo}</tt>, <tt>\p{Bopo}</tt>
-- <tt>\p{Brahmi}</tt>, <tt>\p{Brah}</tt>
-- <tt>\p{Braille}</tt>, <tt>\p{Brai}</tt>
-- <tt>\p{Buginese}</tt>, <tt>\p{Bugi}</tt>
-- <tt>\p{Buhid}</tt>, <tt>\p{Buhd}</tt>
-- <tt>\p{Canadian_Aboriginal}</tt>, <tt>\p{Cans}</tt>
-- <tt>\p{Carian}</tt>, <tt>\p{Cari}</tt>
-- <tt>\p{Caucasian_Albanian}</tt>, <tt>\p{Aghb}</tt>
-- <tt>\p{Chakma}</tt>, <tt>\p{Cakm}</tt>
-- <tt>\p{Cham}</tt>
-- <tt>\p{Cherokee}</tt>, <tt>\p{Cher}</tt>
-- <tt>\p{Chorasmian}</tt>, <tt>\p{Chrs}</tt>
-- <tt>\p{Common}</tt>, <tt>\p{Zyyy}</tt>
-- <tt>\p{Coptic}</tt>, <tt>\p{Copt}</tt>
-- <tt>\p{Cuneiform}</tt>, <tt>\p{Xsux}</tt>
-- <tt>\p{Cypriot}</tt>, <tt>\p{Cprt}</tt>
-- <tt>\p{Cypro_Minoan}</tt>, <tt>\p{Cpmn}</tt>
-- <tt>\p{Cyrillic}</tt>, <tt>\p{Cyrl}</tt>
-- <tt>\p{Deseret}</tt>, <tt>\p{Dsrt}</tt>
-- <tt>\p{Devanagari}</tt>, <tt>\p{Deva}</tt>
-- <tt>\p{Dives_Akuru}</tt>, <tt>\p{Diak}</tt>
-- <tt>\p{Dogra}</tt>, <tt>\p{Dogr}</tt>
-- <tt>\p{Duployan}</tt>, <tt>\p{Dupl}</tt>
-- <tt>\p{Egyptian_Hieroglyphs}</tt>, <tt>\p{Egyp}</tt>
-- <tt>\p{Elbasan}</tt>, <tt>\p{Elba}</tt>
-- <tt>\p{Elymaic}</tt>, <tt>\p{Elym}</tt>
-- <tt>\p{Ethiopic}</tt>, <tt>\p{Ethi}</tt>
-- <tt>\p{Georgian}</tt>, <tt>\p{Geor}</tt>
-- <tt>\p{Glagolitic}</tt>, <tt>\p{Glag}</tt>
-- <tt>\p{Gothic}</tt>, <tt>\p{Goth}</tt>
-- <tt>\p{Grantha}</tt>, <tt>\p{Gran}</tt>
-- <tt>\p{Greek}</tt>, <tt>\p{Grek}</tt>
-- <tt>\p{Gujarati}</tt>, <tt>\p{Gujr}</tt>
-- <tt>\p{Gunjala_Gondi}</tt>, <tt>\p{Gong}</tt>
-- <tt>\p{Gurmukhi}</tt>, <tt>\p{Guru}</tt>
-- <tt>\p{Han}</tt>, <tt>\p{Hani}</tt>
-- <tt>\p{Hangul}</tt>, <tt>\p{Hang}</tt>
-- <tt>\p{Hanifi_Rohingya}</tt>, <tt>\p{Rohg}</tt>
-- <tt>\p{Hanunoo}</tt>, <tt>\p{Hano}</tt>
-- <tt>\p{Hatran}</tt>, <tt>\p{Hatr}</tt>
-- <tt>\p{Hebrew}</tt>, <tt>\p{Hebr}</tt>
-- <tt>\p{Hiragana}</tt>, <tt>\p{Hira}</tt>
-- <tt>\p{Imperial_Aramaic}</tt>, <tt>\p{Armi}</tt>
-- <tt>\p{Inherited}</tt>, <tt>\p{Zinh}</tt>
-- <tt>\p{Inscriptional_Pahlavi}</tt>, <tt>\p{Phli}</tt>
-- <tt>\p{Inscriptional_Parthian}</tt>, <tt>\p{Prti}</tt>
-- <tt>\p{Javanese}</tt>, <tt>\p{Java}</tt>
-- <tt>\p{Kaithi}</tt>, <tt>\p{Kthi}</tt>
-- <tt>\p{Kannada}</tt>, <tt>\p{Knda}</tt>
-- <tt>\p{Katakana}</tt>, <tt>\p{Kana}</tt>
-- <tt>\p{Kawi}</tt>
-- <tt>\p{Kayah_Li}</tt>, <tt>\p{Kali}</tt>
-- <tt>\p{Kharoshthi}</tt>, <tt>\p{Khar}</tt>
-- <tt>\p{Khitan_Small_Script}</tt>, <tt>\p{Kits}</tt>
-- <tt>\p{Khmer}</tt>, <tt>\p{Khmr}</tt>
-- <tt>\p{Khojki}</tt>, <tt>\p{Khoj}</tt>
-- <tt>\p{Khudawadi}</tt>, <tt>\p{Sind}</tt>
-- <tt>\p{Lao}</tt>, <tt>\p{Laoo}</tt>
-- <tt>\p{Latin}</tt>, <tt>\p{Latn}</tt>
-- <tt>\p{Lepcha}</tt>, <tt>\p{Lepc}</tt>
-- <tt>\p{Limbu}</tt>, <tt>\p{Limb}</tt>
-- <tt>\p{Linear_A}</tt>, <tt>\p{Lina}</tt>
-- <tt>\p{Linear_B}</tt>, <tt>\p{Linb}</tt>
-- <tt>\p{Lisu}</tt>
-- <tt>\p{Lycian}</tt>, <tt>\p{Lyci}</tt>
-- <tt>\p{Lydian}</tt>, <tt>\p{Lydi}</tt>
-- <tt>\p{Mahajani}</tt>, <tt>\p{Mahj}</tt>
-- <tt>\p{Makasar}</tt>, <tt>\p{Maka}</tt>
-- <tt>\p{Malayalam}</tt>, <tt>\p{Mlym}</tt>
-- <tt>\p{Mandaic}</tt>, <tt>\p{Mand}</tt>
-- <tt>\p{Manichaean}</tt>, <tt>\p{Mani}</tt>
-- <tt>\p{Marchen}</tt>, <tt>\p{Marc}</tt>
-- <tt>\p{Masaram_Gondi}</tt>, <tt>\p{Gonm}</tt>
-- <tt>\p{Medefaidrin}</tt>, <tt>\p{Medf}</tt>
-- <tt>\p{Meetei_Mayek}</tt>, <tt>\p{Mtei}</tt>
-- <tt>\p{Mende_Kikakui}</tt>, <tt>\p{Mend}</tt>
-- <tt>\p{Meroitic_Cursive}</tt>, <tt>\p{Merc}</tt>
-- <tt>\p{Meroitic_Hieroglyphs}</tt>, <tt>\p{Mero}</tt>
-- <tt>\p{Miao}</tt>, <tt>\p{Plrd}</tt>
-- <tt>\p{Modi}</tt>
-- <tt>\p{Mongolian}</tt>, <tt>\p{Mong}</tt>
-- <tt>\p{Mro}</tt>, <tt>\p{Mroo}</tt>
-- <tt>\p{Multani}</tt>, <tt>\p{Mult}</tt>
-- <tt>\p{Myanmar}</tt>, <tt>\p{Mymr}</tt>
-- <tt>\p{Nabataean}</tt>, <tt>\p{Nbat}</tt>
-- <tt>\p{Nag_Mundari}</tt>, <tt>\p{Nagm}</tt>
-- <tt>\p{Nandinagari}</tt>, <tt>\p{Nand}</tt>
-- <tt>\p{New_Tai_Lue}</tt>, <tt>\p{Talu}</tt>
-- <tt>\p{Newa}</tt>
-- <tt>\p{Nko}</tt>, <tt>\p{Nkoo}</tt>
-- <tt>\p{Nushu}</tt>, <tt>\p{Nshu}</tt>
-- <tt>\p{Nyiakeng_Puachue_Hmong}</tt>, <tt>\p{Hmnp}</tt>
-- <tt>\p{Ogham}</tt>, <tt>\p{Ogam}</tt>
-- <tt>\p{Ol_Chiki}</tt>, <tt>\p{Olck}</tt>
-- <tt>\p{Old_Hungarian}</tt>, <tt>\p{Hung}</tt>
-- <tt>\p{Old_Italic}</tt>, <tt>\p{Ital}</tt>
-- <tt>\p{Old_North_Arabian}</tt>, <tt>\p{Narb}</tt>
-- <tt>\p{Old_Permic}</tt>, <tt>\p{Perm}</tt>
-- <tt>\p{Old_Persian}</tt>, <tt>\p{Xpeo}</tt>
-- <tt>\p{Old_Sogdian}</tt>, <tt>\p{Sogo}</tt>
-- <tt>\p{Old_South_Arabian}</tt>, <tt>\p{Sarb}</tt>
-- <tt>\p{Old_Turkic}</tt>, <tt>\p{Orkh}</tt>
-- <tt>\p{Old_Uyghur}</tt>, <tt>\p{Ougr}</tt>
-- <tt>\p{Oriya}</tt>, <tt>\p{Orya}</tt>
-- <tt>\p{Osage}</tt>, <tt>\p{Osge}</tt>
-- <tt>\p{Osmanya}</tt>, <tt>\p{Osma}</tt>
-- <tt>\p{Pahawh_Hmong}</tt>, <tt>\p{Hmng}</tt>
-- <tt>\p{Palmyrene}</tt>, <tt>\p{Palm}</tt>
-- <tt>\p{Pau_Cin_Hau}</tt>, <tt>\p{Pauc}</tt>
-- <tt>\p{Phags_Pa}</tt>, <tt>\p{Phag}</tt>
-- <tt>\p{Phoenician}</tt>, <tt>\p{Phnx}</tt>
-- <tt>\p{Psalter_Pahlavi}</tt>, <tt>\p{Phlp}</tt>
-- <tt>\p{Rejang}</tt>, <tt>\p{Rjng}</tt>
-- <tt>\p{Runic}</tt>, <tt>\p{Runr}</tt>
-- <tt>\p{Samaritan}</tt>, <tt>\p{Samr}</tt>
-- <tt>\p{Saurashtra}</tt>, <tt>\p{Saur}</tt>
-- <tt>\p{Sharada}</tt>, <tt>\p{Shrd}</tt>
-- <tt>\p{Shavian}</tt>, <tt>\p{Shaw}</tt>
-- <tt>\p{Siddham}</tt>, <tt>\p{Sidd}</tt>
-- <tt>\p{SignWriting}</tt>, <tt>\p{Sgnw}</tt>
-- <tt>\p{Sinhala}</tt>, <tt>\p{Sinh}</tt>
-- <tt>\p{Sogdian}</tt>, <tt>\p{Sogd}</tt>
-- <tt>\p{Sora_Sompeng}</tt>, <tt>\p{Sora}</tt>
-- <tt>\p{Soyombo}</tt>, <tt>\p{Soyo}</tt>
-- <tt>\p{Sundanese}</tt>, <tt>\p{Sund}</tt>
-- <tt>\p{Syloti_Nagri}</tt>, <tt>\p{Sylo}</tt>
-- <tt>\p{Syriac}</tt>, <tt>\p{Syrc}</tt>
-- <tt>\p{Tagalog}</tt>, <tt>\p{Tglg}</tt>
-- <tt>\p{Tagbanwa}</tt>, <tt>\p{Tagb}</tt>
-- <tt>\p{Tai_Le}</tt>, <tt>\p{Tale}</tt>
-- <tt>\p{Tai_Tham}</tt>, <tt>\p{Lana}</tt>
-- <tt>\p{Tai_Viet}</tt>, <tt>\p{Tavt}</tt>
-- <tt>\p{Takri}</tt>, <tt>\p{Takr}</tt>
-- <tt>\p{Tamil}</tt>, <tt>\p{Taml}</tt>
-- <tt>\p{Tangsa}</tt>, <tt>\p{Tnsa}</tt>
-- <tt>\p{Tangut}</tt>, <tt>\p{Tang}</tt>
-- <tt>\p{Telugu}</tt>, <tt>\p{Telu}</tt>
-- <tt>\p{Thaana}</tt>, <tt>\p{Thaa}</tt>
-- <tt>\p{Thai}</tt>
-- <tt>\p{Tibetan}</tt>, <tt>\p{Tibt}</tt>
-- <tt>\p{Tifinagh}</tt>, <tt>\p{Tfng}</tt>
-- <tt>\p{Tirhuta}</tt>, <tt>\p{Tirh}</tt>
-- <tt>\p{Toto}</tt>
-- <tt>\p{Ugaritic}</tt>, <tt>\p{Ugar}</tt>
-- <tt>\p{Unknown}</tt>, <tt>\p{Zzzz}</tt>
-- <tt>\p{Vai}</tt>, <tt>\p{Vaii}</tt>
-- <tt>\p{Vithkuqi}</tt>, <tt>\p{Vith}</tt>
-- <tt>\p{Wancho}</tt>, <tt>\p{Wcho}</tt>
-- <tt>\p{Warang_Citi}</tt>, <tt>\p{Wara}</tt>
-- <tt>\p{Yezidi}</tt>, <tt>\p{Yezi}</tt>
-- <tt>\p{Yi}</tt>, <tt>\p{Yiii}</tt>
-- <tt>\p{Zanabazar_Square}</tt>, <tt>\p{Zanb}</tt>
-
-=== Blocks
-
-- <tt>\p{In_Adlam}</tt>
-- <tt>\p{In_Aegean_Numbers}</tt>
-- <tt>\p{In_Ahom}</tt>
-- <tt>\p{In_Alchemical_Symbols}</tt>
-- <tt>\p{In_Alphabetic_Presentation_Forms}</tt>
-- <tt>\p{In_Anatolian_Hieroglyphs}</tt>
-- <tt>\p{In_Ancient_Greek_Musical_Notation}</tt>
-- <tt>\p{In_Ancient_Greek_Numbers}</tt>
-- <tt>\p{In_Ancient_Symbols}</tt>
-- <tt>\p{In_Arabic}</tt>
-- <tt>\p{In_Arabic_Extended_A}</tt>
-- <tt>\p{In_Arabic_Extended_B}</tt>
-- <tt>\p{In_Arabic_Extended_C}</tt>
-- <tt>\p{In_Arabic_Mathematical_Alphabetic_Symbols}</tt>
-- <tt>\p{In_Arabic_Presentation_Forms_A}</tt>
-- <tt>\p{In_Arabic_Presentation_Forms_B}</tt>
-- <tt>\p{In_Arabic_Supplement}</tt>
-- <tt>\p{In_Armenian}</tt>
-- <tt>\p{In_Arrows}</tt>
-- <tt>\p{In_Avestan}</tt>
-- <tt>\p{In_Balinese}</tt>
-- <tt>\p{In_Bamum}</tt>
-- <tt>\p{In_Bamum_Supplement}</tt>
-- <tt>\p{In_Basic_Latin}</tt>
-- <tt>\p{In_Bassa_Vah}</tt>
-- <tt>\p{In_Batak}</tt>
-- <tt>\p{In_Bengali}</tt>
-- <tt>\p{In_Bhaiksuki}</tt>
-- <tt>\p{In_Block_Elements}</tt>
-- <tt>\p{In_Bopomofo}</tt>
-- <tt>\p{In_Bopomofo_Extended}</tt>
-- <tt>\p{In_Box_Drawing}</tt>
-- <tt>\p{In_Brahmi}</tt>
-- <tt>\p{In_Braille_Patterns}</tt>
-- <tt>\p{In_Buginese}</tt>
-- <tt>\p{In_Buhid}</tt>
-- <tt>\p{In_Byzantine_Musical_Symbols}</tt>
-- <tt>\p{In_CJK_Compatibility}</tt>
-- <tt>\p{In_CJK_Compatibility_Forms}</tt>
-- <tt>\p{In_CJK_Compatibility_Ideographs}</tt>
-- <tt>\p{In_CJK_Compatibility_Ideographs_Supplement}</tt>
-- <tt>\p{In_CJK_Radicals_Supplement}</tt>
-- <tt>\p{In_CJK_Strokes}</tt>
-- <tt>\p{In_CJK_Symbols_and_Punctuation}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_A}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_B}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_C}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_D}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_E}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_F}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_G}</tt>
-- <tt>\p{In_CJK_Unified_Ideographs_Extension_H}</tt>
-- <tt>\p{In_Carian}</tt>
-- <tt>\p{In_Caucasian_Albanian}</tt>
-- <tt>\p{In_Chakma}</tt>
-- <tt>\p{In_Cham}</tt>
-- <tt>\p{In_Cherokee}</tt>
-- <tt>\p{In_Cherokee_Supplement}</tt>
-- <tt>\p{In_Chess_Symbols}</tt>
-- <tt>\p{In_Chorasmian}</tt>
-- <tt>\p{In_Combining_Diacritical_Marks}</tt>
-- <tt>\p{In_Combining_Diacritical_Marks_Extended}</tt>
-- <tt>\p{In_Combining_Diacritical_Marks_Supplement}</tt>
-- <tt>\p{In_Combining_Diacritical_Marks_for_Symbols}</tt>
-- <tt>\p{In_Combining_Half_Marks}</tt>
-- <tt>\p{In_Common_Indic_Number_Forms}</tt>
-- <tt>\p{In_Control_Pictures}</tt>
-- <tt>\p{In_Coptic}</tt>
-- <tt>\p{In_Coptic_Epact_Numbers}</tt>
-- <tt>\p{In_Counting_Rod_Numerals}</tt>
-- <tt>\p{In_Cuneiform}</tt>
-- <tt>\p{In_Cuneiform_Numbers_and_Punctuation}</tt>
-- <tt>\p{In_Currency_Symbols}</tt>
-- <tt>\p{In_Cypriot_Syllabary}</tt>
-- <tt>\p{In_Cypro_Minoan}</tt>
-- <tt>\p{In_Cyrillic}</tt>
-- <tt>\p{In_Cyrillic_Extended_A}</tt>
-- <tt>\p{In_Cyrillic_Extended_B}</tt>
-- <tt>\p{In_Cyrillic_Extended_C}</tt>
-- <tt>\p{In_Cyrillic_Extended_D}</tt>
-- <tt>\p{In_Cyrillic_Supplement}</tt>
-- <tt>\p{In_Deseret}</tt>
-- <tt>\p{In_Devanagari}</tt>
-- <tt>\p{In_Devanagari_Extended}</tt>
-- <tt>\p{In_Devanagari_Extended_A}</tt>
-- <tt>\p{In_Dingbats}</tt>
-- <tt>\p{In_Dives_Akuru}</tt>
-- <tt>\p{In_Dogra}</tt>
-- <tt>\p{In_Domino_Tiles}</tt>
-- <tt>\p{In_Duployan}</tt>
-- <tt>\p{In_Early_Dynastic_Cuneiform}</tt>
-- <tt>\p{In_Egyptian_Hieroglyph_Format_Controls}</tt>
-- <tt>\p{In_Egyptian_Hieroglyphs}</tt>
-- <tt>\p{In_Elbasan}</tt>
-- <tt>\p{In_Elymaic}</tt>
-- <tt>\p{In_Emoticons}</tt>
-- <tt>\p{In_Enclosed_Alphanumeric_Supplement}</tt>
-- <tt>\p{In_Enclosed_Alphanumerics}</tt>
-- <tt>\p{In_Enclosed_CJK_Letters_and_Months}</tt>
-- <tt>\p{In_Enclosed_Ideographic_Supplement}</tt>
-- <tt>\p{In_Ethiopic}</tt>
-- <tt>\p{In_Ethiopic_Extended}</tt>
-- <tt>\p{In_Ethiopic_Extended_A}</tt>
-- <tt>\p{In_Ethiopic_Extended_B}</tt>
-- <tt>\p{In_Ethiopic_Supplement}</tt>
-- <tt>\p{In_General_Punctuation}</tt>
-- <tt>\p{In_Geometric_Shapes}</tt>
-- <tt>\p{In_Geometric_Shapes_Extended}</tt>
-- <tt>\p{In_Georgian}</tt>
-- <tt>\p{In_Georgian_Extended}</tt>
-- <tt>\p{In_Georgian_Supplement}</tt>
-- <tt>\p{In_Glagolitic}</tt>
-- <tt>\p{In_Glagolitic_Supplement}</tt>
-- <tt>\p{In_Gothic}</tt>
-- <tt>\p{In_Grantha}</tt>
-- <tt>\p{In_Greek_Extended}</tt>
-- <tt>\p{In_Greek_and_Coptic}</tt>
-- <tt>\p{In_Gujarati}</tt>
-- <tt>\p{In_Gunjala_Gondi}</tt>
-- <tt>\p{In_Gurmukhi}</tt>
-- <tt>\p{In_Halfwidth_and_Fullwidth_Forms}</tt>
-- <tt>\p{In_Hangul_Compatibility_Jamo}</tt>
-- <tt>\p{In_Hangul_Jamo}</tt>
-- <tt>\p{In_Hangul_Jamo_Extended_A}</tt>
-- <tt>\p{In_Hangul_Jamo_Extended_B}</tt>
-- <tt>\p{In_Hangul_Syllables}</tt>
-- <tt>\p{In_Hanifi_Rohingya}</tt>
-- <tt>\p{In_Hanunoo}</tt>
-- <tt>\p{In_Hatran}</tt>
-- <tt>\p{In_Hebrew}</tt>
-- <tt>\p{In_High_Private_Use_Surrogates}</tt>
-- <tt>\p{In_High_Surrogates}</tt>
-- <tt>\p{In_Hiragana}</tt>
-- <tt>\p{In_IPA_Extensions}</tt>
-- <tt>\p{In_Ideographic_Description_Characters}</tt>
-- <tt>\p{In_Ideographic_Symbols_and_Punctuation}</tt>
-- <tt>\p{In_Imperial_Aramaic}</tt>
-- <tt>\p{In_Indic_Siyaq_Numbers}</tt>
-- <tt>\p{In_Inscriptional_Pahlavi}</tt>
-- <tt>\p{In_Inscriptional_Parthian}</tt>
-- <tt>\p{In_Javanese}</tt>
-- <tt>\p{In_Kaithi}</tt>
-- <tt>\p{In_Kaktovik_Numerals}</tt>
-- <tt>\p{In_Kana_Extended_A}</tt>
-- <tt>\p{In_Kana_Extended_B}</tt>
-- <tt>\p{In_Kana_Supplement}</tt>
-- <tt>\p{In_Kanbun}</tt>
-- <tt>\p{In_Kangxi_Radicals}</tt>
-- <tt>\p{In_Kannada}</tt>
-- <tt>\p{In_Katakana}</tt>
-- <tt>\p{In_Katakana_Phonetic_Extensions}</tt>
-- <tt>\p{In_Kawi}</tt>
-- <tt>\p{In_Kayah_Li}</tt>
-- <tt>\p{In_Kharoshthi}</tt>
-- <tt>\p{In_Khitan_Small_Script}</tt>
-- <tt>\p{In_Khmer}</tt>
-- <tt>\p{In_Khmer_Symbols}</tt>
-- <tt>\p{In_Khojki}</tt>
-- <tt>\p{In_Khudawadi}</tt>
-- <tt>\p{In_Lao}</tt>
-- <tt>\p{In_Latin_1_Supplement}</tt>
-- <tt>\p{In_Latin_Extended_A}</tt>
-- <tt>\p{In_Latin_Extended_Additional}</tt>
-- <tt>\p{In_Latin_Extended_B}</tt>
-- <tt>\p{In_Latin_Extended_C}</tt>
-- <tt>\p{In_Latin_Extended_D}</tt>
-- <tt>\p{In_Latin_Extended_E}</tt>
-- <tt>\p{In_Latin_Extended_F}</tt>
-- <tt>\p{In_Latin_Extended_G}</tt>
-- <tt>\p{In_Lepcha}</tt>
-- <tt>\p{In_Letterlike_Symbols}</tt>
-- <tt>\p{In_Limbu}</tt>
-- <tt>\p{In_Linear_A}</tt>
-- <tt>\p{In_Linear_B_Ideograms}</tt>
-- <tt>\p{In_Linear_B_Syllabary}</tt>
-- <tt>\p{In_Lisu}</tt>
-- <tt>\p{In_Lisu_Supplement}</tt>
-- <tt>\p{In_Low_Surrogates}</tt>
-- <tt>\p{In_Lycian}</tt>
-- <tt>\p{In_Lydian}</tt>
-- <tt>\p{In_Mahajani}</tt>
-- <tt>\p{In_Mahjong_Tiles}</tt>
-- <tt>\p{In_Makasar}</tt>
-- <tt>\p{In_Malayalam}</tt>
-- <tt>\p{In_Mandaic}</tt>
-- <tt>\p{In_Manichaean}</tt>
-- <tt>\p{In_Marchen}</tt>
-- <tt>\p{In_Masaram_Gondi}</tt>
-- <tt>\p{In_Mathematical_Alphanumeric_Symbols}</tt>
-- <tt>\p{In_Mathematical_Operators}</tt>
-- <tt>\p{In_Mayan_Numerals}</tt>
-- <tt>\p{In_Medefaidrin}</tt>
-- <tt>\p{In_Meetei_Mayek}</tt>
-- <tt>\p{In_Meetei_Mayek_Extensions}</tt>
-- <tt>\p{In_Mende_Kikakui}</tt>
-- <tt>\p{In_Meroitic_Cursive}</tt>
-- <tt>\p{In_Meroitic_Hieroglyphs}</tt>
-- <tt>\p{In_Miao}</tt>
-- <tt>\p{In_Miscellaneous_Mathematical_Symbols_A}</tt>
-- <tt>\p{In_Miscellaneous_Mathematical_Symbols_B}</tt>
-- <tt>\p{In_Miscellaneous_Symbols}</tt>
-- <tt>\p{In_Miscellaneous_Symbols_and_Arrows}</tt>
-- <tt>\p{In_Miscellaneous_Symbols_and_Pictographs}</tt>
-- <tt>\p{In_Miscellaneous_Technical}</tt>
-- <tt>\p{In_Modi}</tt>
-- <tt>\p{In_Modifier_Tone_Letters}</tt>
-- <tt>\p{In_Mongolian}</tt>
-- <tt>\p{In_Mongolian_Supplement}</tt>
-- <tt>\p{In_Mro}</tt>
-- <tt>\p{In_Multani}</tt>
-- <tt>\p{In_Musical_Symbols}</tt>
-- <tt>\p{In_Myanmar}</tt>
-- <tt>\p{In_Myanmar_Extended_A}</tt>
-- <tt>\p{In_Myanmar_Extended_B}</tt>
-- <tt>\p{In_NKo}</tt>
-- <tt>\p{In_Nabataean}</tt>
-- <tt>\p{In_Nag_Mundari}</tt>
-- <tt>\p{In_Nandinagari}</tt>
-- <tt>\p{In_New_Tai_Lue}</tt>
-- <tt>\p{In_Newa}</tt>
-- <tt>\p{In_No_Block}</tt>
-- <tt>\p{In_Number_Forms}</tt>
-- <tt>\p{In_Nushu}</tt>
-- <tt>\p{In_Nyiakeng_Puachue_Hmong}</tt>
-- <tt>\p{In_Ogham}</tt>
-- <tt>\p{In_Ol_Chiki}</tt>
-- <tt>\p{In_Old_Hungarian}</tt>
-- <tt>\p{In_Old_Italic}</tt>
-- <tt>\p{In_Old_North_Arabian}</tt>
-- <tt>\p{In_Old_Permic}</tt>
-- <tt>\p{In_Old_Persian}</tt>
-- <tt>\p{In_Old_Sogdian}</tt>
-- <tt>\p{In_Old_South_Arabian}</tt>
-- <tt>\p{In_Old_Turkic}</tt>
-- <tt>\p{In_Old_Uyghur}</tt>
-- <tt>\p{In_Optical_Character_Recognition}</tt>
-- <tt>\p{In_Oriya}</tt>
-- <tt>\p{In_Ornamental_Dingbats}</tt>
-- <tt>\p{In_Osage}</tt>
-- <tt>\p{In_Osmanya}</tt>
-- <tt>\p{In_Ottoman_Siyaq_Numbers}</tt>
-- <tt>\p{In_Pahawh_Hmong}</tt>
-- <tt>\p{In_Palmyrene}</tt>
-- <tt>\p{In_Pau_Cin_Hau}</tt>
-- <tt>\p{In_Phags_pa}</tt>
-- <tt>\p{In_Phaistos_Disc}</tt>
-- <tt>\p{In_Phoenician}</tt>
-- <tt>\p{In_Phonetic_Extensions}</tt>
-- <tt>\p{In_Phonetic_Extensions_Supplement}</tt>
-- <tt>\p{In_Playing_Cards}</tt>
-- <tt>\p{In_Private_Use_Area}</tt>
-- <tt>\p{In_Psalter_Pahlavi}</tt>
-- <tt>\p{In_Rejang}</tt>
-- <tt>\p{In_Rumi_Numeral_Symbols}</tt>
-- <tt>\p{In_Runic}</tt>
-- <tt>\p{In_Samaritan}</tt>
-- <tt>\p{In_Saurashtra}</tt>
-- <tt>\p{In_Sharada}</tt>
-- <tt>\p{In_Shavian}</tt>
-- <tt>\p{In_Shorthand_Format_Controls}</tt>
-- <tt>\p{In_Siddham}</tt>
-- <tt>\p{In_Sinhala}</tt>
-- <tt>\p{In_Sinhala_Archaic_Numbers}</tt>
-- <tt>\p{In_Small_Form_Variants}</tt>
-- <tt>\p{In_Small_Kana_Extension}</tt>
-- <tt>\p{In_Sogdian}</tt>
-- <tt>\p{In_Sora_Sompeng}</tt>
-- <tt>\p{In_Soyombo}</tt>
-- <tt>\p{In_Spacing_Modifier_Letters}</tt>
-- <tt>\p{In_Specials}</tt>
-- <tt>\p{In_Sundanese}</tt>
-- <tt>\p{In_Sundanese_Supplement}</tt>
-- <tt>\p{In_Superscripts_and_Subscripts}</tt>
-- <tt>\p{In_Supplemental_Arrows_A}</tt>
-- <tt>\p{In_Supplemental_Arrows_B}</tt>
-- <tt>\p{In_Supplemental_Arrows_C}</tt>
-- <tt>\p{In_Supplemental_Mathematical_Operators}</tt>
-- <tt>\p{In_Supplemental_Punctuation}</tt>
-- <tt>\p{In_Supplemental_Symbols_and_Pictographs}</tt>
-- <tt>\p{In_Supplementary_Private_Use_Area_A}</tt>
-- <tt>\p{In_Supplementary_Private_Use_Area_B}</tt>
-- <tt>\p{In_Sutton_SignWriting}</tt>
-- <tt>\p{In_Syloti_Nagri}</tt>
-- <tt>\p{In_Symbols_and_Pictographs_Extended_A}</tt>
-- <tt>\p{In_Symbols_for_Legacy_Computing}</tt>
-- <tt>\p{In_Syriac}</tt>
-- <tt>\p{In_Syriac_Supplement}</tt>
-- <tt>\p{In_Tagalog}</tt>
-- <tt>\p{In_Tagbanwa}</tt>
-- <tt>\p{In_Tags}</tt>
-- <tt>\p{In_Tai_Le}</tt>
-- <tt>\p{In_Tai_Tham}</tt>
-- <tt>\p{In_Tai_Viet}</tt>
-- <tt>\p{In_Tai_Xuan_Jing_Symbols}</tt>
-- <tt>\p{In_Takri}</tt>
-- <tt>\p{In_Tamil}</tt>
-- <tt>\p{In_Tamil_Supplement}</tt>
-- <tt>\p{In_Tangsa}</tt>
-- <tt>\p{In_Tangut}</tt>
-- <tt>\p{In_Tangut_Components}</tt>
-- <tt>\p{In_Tangut_Supplement}</tt>
-- <tt>\p{In_Telugu}</tt>
-- <tt>\p{In_Thaana}</tt>
-- <tt>\p{In_Thai}</tt>
-- <tt>\p{In_Tibetan}</tt>
-- <tt>\p{In_Tifinagh}</tt>
-- <tt>\p{In_Tirhuta}</tt>
-- <tt>\p{In_Toto}</tt>
-- <tt>\p{In_Transport_and_Map_Symbols}</tt>
-- <tt>\p{In_Ugaritic}</tt>
-- <tt>\p{In_Unified_Canadian_Aboriginal_Syllabics}</tt>
-- <tt>\p{In_Unified_Canadian_Aboriginal_Syllabics_Extended}</tt>
-- <tt>\p{In_Unified_Canadian_Aboriginal_Syllabics_Extended_A}</tt>
-- <tt>\p{In_Vai}</tt>
-- <tt>\p{In_Variation_Selectors}</tt>
-- <tt>\p{In_Variation_Selectors_Supplement}</tt>
-- <tt>\p{In_Vedic_Extensions}</tt>
-- <tt>\p{In_Vertical_Forms}</tt>
-- <tt>\p{In_Vithkuqi}</tt>
-- <tt>\p{In_Wancho}</tt>
-- <tt>\p{In_Warang_Citi}</tt>
-- <tt>\p{In_Yezidi}</tt>
-- <tt>\p{In_Yi_Radicals}</tt>
-- <tt>\p{In_Yi_Syllables}</tt>
-- <tt>\p{In_Yijing_Hexagram_Symbols}</tt>
-- <tt>\p{In_Zanabazar_Square}</tt>
-- <tt>\p{In_Znamenny_Musical_Notation}</tt>
-
-=== Emoji
-
-- <tt>\p{Emoji}</tt>
-- <tt>\p{Emoji_Component}</tt>, <tt>\p{EComp}</tt>
-- <tt>\p{Emoji_Modifier}</tt>, <tt>\p{EMod}</tt>
-- <tt>\p{Emoji_Modifier_Base}</tt>, <tt>\p{EBase}</tt>
-- <tt>\p{Emoji_Presentation}</tt>, <tt>\p{EPres}</tt>
-- <tt>\p{Extended_Pictographic}</tt>, <tt>\p{ExtPict}</tt>
-
-=== Graphemes
-
-- <tt>\p{Grapheme_Cluster_Break_CR}</tt>
-- <tt>\p{Grapheme_Cluster_Break_Control}</tt>
-- <tt>\p{Grapheme_Cluster_Break_Extend}</tt>
-- <tt>\p{Grapheme_Cluster_Break_L}</tt>
-- <tt>\p{Grapheme_Cluster_Break_LF}</tt>
-- <tt>\p{Grapheme_Cluster_Break_LV}</tt>
-- <tt>\p{Grapheme_Cluster_Break_LVT}</tt>
-- <tt>\p{Grapheme_Cluster_Break_Prepend}</tt>
-- <tt>\p{Grapheme_Cluster_Break_Regional_Indicator}</tt>
-- <tt>\p{Grapheme_Cluster_Break_SpacingMark}</tt>
-- <tt>\p{Grapheme_Cluster_Break_T}</tt>
-- <tt>\p{Grapheme_Cluster_Break_V}</tt>
-- <tt>\p{Grapheme_Cluster_Break_ZWJ}</tt>
-
-=== Derived Ages
-
-- <tt>\p{Age_10_0}</tt>
-- <tt>\p{Age_11_0}</tt>
-- <tt>\p{Age_12_0}</tt>
-- <tt>\p{Age_12_1}</tt>
-- <tt>\p{Age_13_0}</tt>
-- <tt>\p{Age_14_0}</tt>
-- <tt>\p{Age_15_0}</tt>
-- <tt>\p{Age_1_1}</tt>
-- <tt>\p{Age_2_0}</tt>
-- <tt>\p{Age_2_1}</tt>
-- <tt>\p{Age_3_0}</tt>
-- <tt>\p{Age_3_1}</tt>
-- <tt>\p{Age_3_2}</tt>
-- <tt>\p{Age_4_0}</tt>
-- <tt>\p{Age_4_1}</tt>
-- <tt>\p{Age_5_0}</tt>
-- <tt>\p{Age_5_1}</tt>
-- <tt>\p{Age_5_2}</tt>
-- <tt>\p{Age_6_0}</tt>
-- <tt>\p{Age_6_1}</tt>
-- <tt>\p{Age_6_2}</tt>
-- <tt>\p{Age_6_3}</tt>
-- <tt>\p{Age_7_0}</tt>
-- <tt>\p{Age_8_0}</tt>
-- <tt>\p{Age_9_0}</tt>
diff --git a/doc/reline/face.md b/doc/reline/face.md
deleted file mode 100644
index 1fa916123b..0000000000
--- a/doc/reline/face.md
+++ /dev/null
@@ -1,111 +0,0 @@
-# Face
-
-With the `Reline::Face` class, you can modify the text color and text decorations in your terminal emulator.
-This is primarily used to customize the appearance of the method completion dialog in IRB.
-
-## Usage
-
-### ex: Change the background color of the completion dialog cyan to blue
-
-```ruby
-Reline::Face.config(:completion_dialog) do |conf|
- conf.define :default, foreground: :white, background: :blue
- # ^^^^^ `:cyan` by default
- conf.define :enhanced, foreground: :white, background: :magenta
- conf.define :scrollbar, foreground: :white, background: :blue
-end
-```
-
-If you provide the above code to an IRB session in some way, you can apply the configuration.
-It's generally done by writing it in `.irbrc`.
-
-Regarding `.irbrc`, please refer to the following link: [https://docs.ruby-lang.org/en/master/IRB.html](https://docs.ruby-lang.org/en/master/IRB.html)
-
-## Available parameters
-
-`Reline::Face` internally creates SGR (Select Graphic Rendition) code according to the block parameter of `Reline::Face.config` method.
-
-| Key | Value | SGR Code (numeric part following "\e[")|
-|:------------|:------------------|-----:|
-| :foreground | :black | 30 |
-| | :red | 31 |
-| | :green | 32 |
-| | :yellow | 33 |
-| | :blue | 34 |
-| | :magenta | 35 |
-| | :cyan | 36 |
-| | :white | 37 |
-| | :bright_black | 90 |
-| | :gray | 90 |
-| | :bright_red | 91 |
-| | :bright_green | 92 |
-| | :bright_yellow | 93 |
-| | :bright_blue | 94 |
-| | :bright_magenta | 95 |
-| | :bright_cyan | 96 |
-| | :bright_white | 97 |
-| :background | :black | 40 |
-| | :red | 41 |
-| | :green | 42 |
-| | :yellow | 43 |
-| | :blue | 44 |
-| | :magenta | 45 |
-| | :cyan | 46 |
-| | :white | 47 |
-| | :bright_black | 100 |
-| | :gray | 100 |
-| | :bright_red | 101 |
-| | :bright_green | 102 |
-| | :bright_yellow | 103 |
-| | :bright_blue | 104 |
-| | :bright_magenta | 105 |
-| | :bright_cyan | 106 |
-| | :bright_white | 107 |
-| :style | :reset | 0 |
-| | :bold | 1 |
-| | :faint | 2 |
-| | :italicized | 3 |
-| | :underlined | 4 |
-| | :slowly_blinking | 5 |
-| | :blinking | 5 |
-| | :rapidly_blinking | 6 |
-| | :negative | 7 |
-| | :concealed | 8 |
-| | :crossed_out | 9 |
-
-- The value for `:style` can be both a Symbol and an Array
- ```ruby
- # Single symbol
- conf.define :default, style: :bold
- # Array
- conf.define :default, style: [:bold, :negative]
- ```
-- The availability of specific SGR codes depends on your terminal emulator
-- You can specify a hex color code to `:foreground` and `:background` color like `foreground: "#FF1020"`. Its availability also depends on your terminal emulator
-
-## Debugging
-
-You can see the current Face configuration by `Reline::Face.configs` method
-
-Example:
-
-```ruby
-irb(main):001:0> Reline::Face.configs
-=>
-{:default=>
- {:default=>{:style=>:reset, :escape_sequence=>"\e[0m"},
- :enhanced=>{:style=>:reset, :escape_sequence=>"\e[0m"},
- :scrollbar=>{:style=>:reset, :escape_sequence=>"\e[0m"}},
- :completion_dialog=>
- {:default=>{:foreground=>:white, :background=>:cyan, :escape_sequence=>"\e[0m\e[37;46m"},
- :enhanced=>{:foreground=>:white, :background=>:magenta, :escape_sequence=>"\e[0m\e[37;45m"},
- :scrollbar=>{:foreground=>:white, :background=>:cyan, :escape_sequence=>"\e[0m\e[37;46m"}}}
-```
-
-## 256-Color and TrueColor
-
-Reline will automatically detect if your terminal emulator supports truecolor with `ENV['COLORTERM] in 'truecolor' | '24bit'`. When this env is not set, Reline will fallback to 256-color.
-If your terminal emulator supports truecolor but does not set COLORTERM env, add this line to `.irbrc`.
-```ruby
-Reline::Face.force_truecolor
-```
diff --git a/doc/rjit/rjit.md b/doc/rjit/rjit.md
deleted file mode 100644
index 9e60e43ce3..0000000000
--- a/doc/rjit/rjit.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# RJIT: Ruby JIT
-
-This document has some tips that might be useful when you work on RJIT.
-
-## Project purpose
-
-This project is for experimental purposes.
-For production deployment, consider using YJIT instead.
-
-## Supported platforms
-
-The following platforms are assumed to work. `linux-x86_64` is tested on CI.
-
-* OS: Linux, macOS, BSD
-* Arch: x86\_64
-
-## configure
-### --enable-rjit
-
-On supported platforms, `--enable-rjit` is set by default. You usually don't need to specify this.
-You may still manually pass `--enable-rjit` to try RJIT on unsupported platforms.
-
-### --enable-rjit=dev
-
-It enables `--rjit-dump-disasm` if libcapstone is available.
-
-## make
-### rjit-bindgen
-
-If you see an "RJIT bindgen" GitHub Actions failure, please commit the `git diff` shown on the failed job.
-
-For doing the same thing locally, run `make rjit-bindgen` after installing libclang.
-macOS seems to have libclang by default. On Ubuntu, you can install it with `apt install libclang1`.
-
-## ruby
-### --rjit-stats
-
-This prints RJIT stats at exit.
-
-### --rjit-dump-disasm
-
-This dumps all JIT code. You need to install libcapstone before configure and use `--enable-rjit=dev` on configure.
-
-* Ubuntu: `sudo apt-get install -y libcapstone-dev`
-* macOS: `brew install capstone`
diff --git a/doc/standard_library.rdoc b/doc/standard_library.rdoc
index 2282d7226b..7c9938c5b0 100644
--- a/doc/standard_library.rdoc
+++ b/doc/standard_library.rdoc
@@ -23,14 +23,6 @@ Socket:: Access underlying OS socket implementations
= Default gems
-* default gems are shipped with Ruby releases and also available as rubygems.
-* default gems are not uninstallable from Ruby installation.
-* default gems can be updated used by rubygems.
- * e.g. `gem update json`
-* default gems can be used with bundler environment like `unbundled_env`.
-* default gems can be used any version on Gemfile.
- * e.g. `gem "json", ">= 2.6"`
-
== Libraries
Abbrev:: Calculates a set of unique abbreviations for a given set of strings
@@ -61,7 +53,6 @@ OpenStruct:: Class to build custom data structures, similar to a Hash
OpenURI:: An easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP
PP:: Provides a PrettyPrinter for Ruby objects
PrettyPrinter:: Implements a pretty printing algorithm for readable structure
-Prism:: A portable, error-tolerant Ruby parser
PStore:: Implements a file based persistence mechanism based on a Hash
Readline:: Wrapper for Readline extencion and Reline
Reline:: GNU Readline and Editline by pure Ruby implementation.
@@ -98,6 +89,8 @@ NKF:: Ruby extension for Network Kanji Filter
OpenSSL:: Provides SSL, TLS and general purpose cryptography for Ruby
Pathname:: Representation of the name of a file or directory on the filesystem
Psych:: A YAML parser and emitter for Ruby
+Racc:: A LALR(1) parser generator written in Ruby.
+Readline:: Provides an interface for GNU Readline and Edit Line (libedit)
StringIO:: Pseudo I/O on String objects
StringScanner:: Provides lexical scanning operations on a String
Syslog:: Ruby interface for the POSIX system logging facility
@@ -106,12 +99,6 @@ Zlib:: Ruby interface for the zlib compression/decompression library
= Bundled gems
-* bundled gems are shipped with Ruby releases and also available as rubygems.
-* bundled gems are same as normal gems like `rails`, `rack`.
- * They are only bundled with Ruby releases.
- * They can be uninstallable from Ruby installation.
- * They are needed to declare in Gemfile when use with bundler.
-
== Libraries
MiniTest:: A test suite with TDD, BDD, mocking and benchmarking
@@ -129,4 +116,3 @@ Prime:: Prime numbers and factorization library
RBS:: RBS is a language to describe the structure of Ruby programs
TypeProf:: A type analysis tool for Ruby code based on abstract interpretation
DEBUGGER__:: Debugging functionality for Ruby
-Racc:: A LALR(1) parser generator written in Ruby.
diff --git a/doc/strftime_formatting.rdoc b/doc/strftime_formatting.rdoc
index 7694752a21..30a629bf68 100644
--- a/doc/strftime_formatting.rdoc
+++ b/doc/strftime_formatting.rdoc
@@ -1,4 +1,4 @@
-= Formats for Dates and Times
+== Formats for Dates and Times
Several Ruby time-related classes have instance method +strftime+,
which returns a formatted string representing all or part of a date or time:
@@ -32,9 +32,9 @@ It consists of:
Except for the leading percent character,
the only required part is the conversion specifier, so we begin with that.
-== Conversion Specifiers
+=== Conversion Specifiers
-=== \Date (Year, Month, Day)
+==== \Date (Year, Month, Day)
- <tt>%Y</tt> - Year including century, zero-padded:
@@ -87,7 +87,7 @@ the only required part is the conversion specifier, so we begin with that.
Time.new(2002, 1, 1).strftime('%j') # => "001"
Time.new(2002, 12, 31).strftime('%j') # => "365"
-=== \Time (Hour, Minute, Second, Subsecond)
+==== \Time (Hour, Minute, Second, Subsecond)
- <tt>%H</tt> - Hour of the day, in range (0..23), zero-padded:
@@ -152,7 +152,7 @@ the only required part is the conversion specifier, so we begin with that.
Time.now.strftime('%s') # => "1656505136"
-=== Timezone
+==== Timezone
- <tt>%z</tt> - Timezone as hour and minute offset from UTC:
@@ -162,7 +162,7 @@ the only required part is the conversion specifier, so we begin with that.
Time.now.strftime('%Z') # => "Central Daylight Time"
-=== Weekday
+==== Weekday
- <tt>%A</tt> - Full weekday name:
@@ -184,7 +184,7 @@ the only required part is the conversion specifier, so we begin with that.
t.strftime('%a') # => "Sun"
t.strftime('%w') # => "0"
-=== Week Number
+==== Week Number
- <tt>%U</tt> - Week number of the year, in range (0..53), zero-padded,
where each week begins on a Sunday:
@@ -200,7 +200,7 @@ the only required part is the conversion specifier, so we begin with that.
t.strftime('%a') # => "Sun"
t.strftime('%W') # => "25"
-=== Week Dates
+==== Week Dates
See {ISO 8601 week dates}[https://en.wikipedia.org/wiki/ISO_8601#Week_dates].
@@ -223,7 +223,7 @@ See {ISO 8601 week dates}[https://en.wikipedia.org/wiki/ISO_8601#Week_dates].
t0.strftime('%V') # => "52"
t1.strftime('%V') # => "01"
-=== Literals
+==== Literals
- <tt>%n</tt> - Newline character "\n":
@@ -237,7 +237,7 @@ See {ISO 8601 week dates}[https://en.wikipedia.org/wiki/ISO_8601#Week_dates].
Time.now.strftime('%%') # => "%"
-=== Shorthand Conversion Specifiers
+==== Shorthand Conversion Specifiers
Each shorthand specifier here is shown with its corresponding
longhand specifier.
@@ -294,14 +294,14 @@ longhand specifier.
DateTime.now.strftime('%a %b %e %H:%M:%S %Z %Y')
# => "Wed Jun 29 08:32:18 -05:00 2022"
-== Flags
+=== Flags
Flags may affect certain formatting specifications.
Multiple flags may be given with a single conversion specified;
order does not matter.
-=== Padding Flags
+==== Padding Flags
- <tt>0</tt> - Pad with zeroes:
@@ -315,7 +315,7 @@ order does not matter.
Time.new(10).strftime('%-Y') # => "10"
-=== Casing Flags
+==== Casing Flags
- <tt>^</tt> - Upcase result:
@@ -328,7 +328,7 @@ order does not matter.
Time.now.strftime('%^p') # => "AM"
Time.now.strftime('%#p') # => "am"
-=== Timezone Flags
+==== Timezone Flags
- <tt>:</tt> - Put timezone as colon-separated hours and minutes:
@@ -338,7 +338,7 @@ order does not matter.
Time.now.strftime('%::z') # => "-05:00:00"
-== Width Specifiers
+=== Width Specifiers
The integer width specifier gives a minimum width for the returned string:
@@ -348,12 +348,12 @@ The integer width specifier gives a minimum width for the returned string:
Time.new(2002, 12).strftime('%10B') # => " December"
Time.new(2002, 12).strftime('%3B') # => "December" # Ignored if too small.
-= Specialized Format Strings
+== Specialized Format Strings
Here are a few specialized format strings,
each based on an external standard.
-== HTTP Format
+=== HTTP Format
The HTTP date format is based on
{RFC 2616}[https://datatracker.ietf.org/doc/html/rfc2616],
@@ -368,7 +368,7 @@ and treats dates in the format <tt>'%a, %d %b %Y %T GMT'</tt>:
Date._httpdate(httpdate)
# => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0}
-== RFC 3339 Format
+=== RFC 3339 Format
The RFC 3339 date format is based on
{RFC 3339}[https://datatracker.ietf.org/doc/html/rfc3339]:
@@ -382,7 +382,7 @@ The RFC 3339 date format is based on
Date._rfc3339(rfc3339)
# => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0}
-== RFC 2822 Format
+=== RFC 2822 Format
The RFC 2822 date format is based on
{RFC 2822}[https://datatracker.ietf.org/doc/html/rfc2822],
@@ -397,7 +397,7 @@ and treats dates in the format <tt>'%a, %-d %b %Y %T %z'</tt>]:
Date._rfc2822(rfc2822)
# => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0}
-== JIS X 0301 Format
+=== JIS X 0301 Format
The JIS X 0301 format includes the
{Japanese era name}[https://en.wikipedia.org/wiki/Japanese_era_name],
@@ -412,7 +412,7 @@ with the first letter of the romanized era name prefixed:
# Return hash parsed from 0301-formatted string.
Date._jisx0301(jisx0301) # => {:year=>2001, :mon=>2, :mday=>3}
-== ISO 8601 Format Specifications
+=== ISO 8601 Format Specifications
This section shows format specifications that are compatible with
{ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601].
@@ -422,7 +422,7 @@ Examples in this section assume:
t = Time.now # => 2022-06-29 16:49:25.465246 -0500
-=== Dates
+==== Dates
See {ISO 8601 dates}[https://en.wikipedia.org/wiki/ISO_8601#Dates].
@@ -473,7 +473,7 @@ See {ISO 8601 dates}[https://en.wikipedia.org/wiki/ISO_8601#Dates].
t.strftime('%Y-%j') # => "2022-180"
-=== Times
+==== Times
See {ISO 8601 times}[https://en.wikipedia.org/wiki/ISO_8601#Times].
@@ -514,7 +514,7 @@ See {ISO 8601 times}[https://en.wikipedia.org/wiki/ISO_8601#Times].
- {Coordinated Universal Time (UTC)}[https://en.wikipedia.org/wiki/ISO_8601#Coordinated_Universal_Time_(UTC)].
- {Time offsets from UTC}[https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC].
-=== Combined \Date and \Time
+==== Combined \Date and \Time
See {ISO 8601 Combined date and time representations}[https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations].
diff --git a/doc/string/encode.rdoc b/doc/string/encode.rdoc
deleted file mode 100644
index 65872fdfd4..0000000000
--- a/doc/string/encode.rdoc
+++ /dev/null
@@ -1,47 +0,0 @@
-Returns a copy of +self+ transcoded as determined by +dst_encoding+.
-By default, raises an exception if +self+
-contains an invalid byte or a character not defined in +dst_encoding+;
-that behavior may be modified by encoding options; see below.
-
-With no arguments:
-
-- Uses the same encoding if <tt>Encoding.default_internal</tt> is +nil+
- (the default):
-
- Encoding.default_internal # => nil
- s = "Ruby\x99".force_encoding('Windows-1252')
- s.encoding # => #<Encoding:Windows-1252>
- s.bytes # => [82, 117, 98, 121, 153]
- t = s.encode # => "Ruby\x99"
- t.encoding # => #<Encoding:Windows-1252>
- t.bytes # => [82, 117, 98, 121, 226, 132, 162]
-
-- Otherwise, uses the encoding <tt>Encoding.default_internal</tt>:
-
- Encoding.default_internal = 'UTF-8'
- t = s.encode # => "Rubyâ„¢"
- t.encoding # => #<Encoding:UTF-8>
-
-With only argument +dst_encoding+ given, uses that encoding:
-
- s = "Ruby\x99".force_encoding('Windows-1252')
- s.encoding # => #<Encoding:Windows-1252>
- t = s.encode('UTF-8') # => "Rubyâ„¢"
- t.encoding # => #<Encoding:UTF-8>
-
-With arguments +dst_encoding+ and +src_encoding+ given,
-interprets +self+ using +src_encoding+, encodes the new string using +dst_encoding+:
-
- s = "Ruby\x99"
- t = s.encode('UTF-8', 'Windows-1252') # => "Rubyâ„¢"
- t.encoding # => #<Encoding:UTF-8>
-
-Optional keyword arguments +enc_opts+ specify encoding options;
-see {Encoding Options}[rdoc-ref:encodings.rdoc@Encoding+Options].
-
-Please note that, unless <code>invalid: :replace</code> option is
-given, conversion from an encoding +enc+ to the same encoding +enc+
-(independent of whether +enc+ is given explicitly or implicitly) is a
-no-op, i.e. the string is simply copied without any changes, and no
-exceptions are raised, even if there are invalid bytes.
-
diff --git a/doc/string/length.rdoc b/doc/string/length.rdoc
index 544bca269f..0a7e17f7dc 100644
--- a/doc/string/length.rdoc
+++ b/doc/string/length.rdoc
@@ -10,3 +10,4 @@ Contrast with String#bytesize:
'теÑÑ‚'.bytesize # => 8
'ã“ã‚“ã«ã¡ã¯'.bytesize # => 15
+String#size is an alias for String#length.
diff --git a/doc/syntax.rdoc b/doc/syntax.rdoc
index 6ca5843512..5895673f36 100644
--- a/doc/syntax.rdoc
+++ b/doc/syntax.rdoc
@@ -37,6 +37,3 @@ Miscellaneous[rdoc-ref:syntax/miscellaneous.rdoc] ::
Comments[rdoc-ref:syntax/comments.rdoc] ::
Line and block code comments
-
-Operators[rdoc-ref:syntax/operators.rdoc] ::
- Operator method behaviors
diff --git a/doc/syntax/assignment.rdoc b/doc/syntax/assignment.rdoc
index e30cb35adf..1321bbf3ac 100644
--- a/doc/syntax/assignment.rdoc
+++ b/doc/syntax/assignment.rdoc
@@ -107,7 +107,7 @@ Rather than printing "true" you receive a NameError, "undefined local variable
or method `a'". Since ruby parses the bare +a+ left of the +if+ first and has
not yet seen an assignment to +a+ it assumes you wish to call a method. Ruby
then sees the assignment to +a+ and will assume you are referencing a local
-variable.
+method.
The confusion comes from the out-of-order execution of the expression. First
the local variable is assigned-to then you attempt to call a nonexistent
@@ -403,10 +403,6 @@ assigning. This is similar to multiple assignment:
p a # prints [1, 2, 3]
- b = *1
-
- p b # prints [1]
-
You can splat anywhere in the right-hand side of the assignment:
a = 1, *[2, 3]
diff --git a/doc/syntax/calling_methods.rdoc b/doc/syntax/calling_methods.rdoc
index 6cc8678450..da061dbfdb 100644
--- a/doc/syntax/calling_methods.rdoc
+++ b/doc/syntax/calling_methods.rdoc
@@ -322,6 +322,18 @@ Both are equivalent to:
my_method(1, 2, 3)
+If the method accepts keyword arguments, the splat operator will convert a
+hash at the end of the array into keyword arguments:
+
+ def my_method(a, b, c: 3)
+ end
+
+ arguments = [1, 2, { c: 4 }]
+ my_method(*arguments)
+
+Note that this behavior is currently deprecated and will emit a warning.
+This behavior will be removed in Ruby 3.0.
+
You may also use the <code>**</code> (described next) to convert a Hash into
keyword arguments.
diff --git a/doc/syntax/comments.rdoc b/doc/syntax/comments.rdoc
index 00d19d588a..dbc7816984 100644
--- a/doc/syntax/comments.rdoc
+++ b/doc/syntax/comments.rdoc
@@ -196,7 +196,7 @@ The method Module#const_set is not affected.
In this mode, all values assigned to constants are deeply copied and
made shareable. It is safer mode than +experimental_everything+.
- # shareable_constant_value: experimental_copy
+ # shareable_constant_value: experimental_everything
var = [{foo: []}]
var.frozen? # => false (assignment was made to local variable)
X = var # => calls `Ractor.make_shareable(var, copy: true)`
diff --git a/doc/syntax/control_expressions.rdoc b/doc/syntax/control_expressions.rdoc
index 5350585f15..df3b5ced38 100644
--- a/doc/syntax/control_expressions.rdoc
+++ b/doc/syntax/control_expressions.rdoc
@@ -569,71 +569,3 @@ evaluated on the following iteration:
Here, the flip-flop turns on when +value+ equals 2, but doesn't turn off on the
same iteration. The `off' condition isn't evaluated until the following
iteration and +value+ will never be two again.
-
-== throw/catch
-
-+throw+ and +catch+ are used to implement non-local control flow in Ruby. They
-operate similarly to exceptions, allowing control to pass directly from the
-place where +throw+ is called to the place where the matching +catch+ is
-called. The main difference between +throw+/+catch+ and the use of exceptions
-is that +throw+/+catch+ are designed for expected non-local control flow,
-while exceptions are designed for exceptional control flow situations, such
-as handling unexpected errors.
-
-When using +throw+, you provide 1-2 arguments. The first argument is the
-value for the matching +catch+. The second argument is optional (defaults to
-+nil+), and will be the value that +catch+ returns if there is a matching
-+throw+ inside the +catch+ block. If no matching +throw+ method is called
-inside a +catch+ block, the +catch+ method returns the return value of the
-block passed to it.
-
- def a(n)
- throw :d, :a if n == 0
- b(n)
- end
-
- def b(n)
- throw :d, :b if n == 1
- c(n)
- end
-
- def c(n)
- throw :d if n == 2
- end
-
- 4.times.map do |i|
- catch(:d) do
- a(i)
- :default
- end
- end
- # => [:a, :b, nil, :default]
-
-If the first argument you pass to +throw+ is not handled by a matching
-+catch+, an UncaughtThrowError exception will be raised. This is because
-+throw+/+catch+ should only be used for expected control flow changes, so
-using a value that is not already expected is an error.
-
-+throw+/+catch+ are implemented as Kernel methods (Kernel#throw and
-Kernel#catch), not as keywords. So they are not usable directly if you are
-in a BasicObject context. You can use Kernel.throw and Kernel.catch in
-this case:
-
- BasicObject.new.instance_exec do
- def a
- b
- end
-
- def b
- c
- end
-
- def c
- ::Kernel.throw :d, :e
- end
-
- result = ::Kernel.catch(:d) do
- a
- end
- result # => :e
- end
diff --git a/doc/syntax/literals.rdoc b/doc/syntax/literals.rdoc
index 0c1e4a434b..b641433249 100644
--- a/doc/syntax/literals.rdoc
+++ b/doc/syntax/literals.rdoc
@@ -414,9 +414,9 @@ slash (<tt>'/'</tt>) characters:
re = /foo/ # => /foo/
re.class # => Regexp
-The trailing slash may be followed by one or more modifiers characters
-that set modes for the regexp.
-See {Regexp modes}[rdoc-ref:Regexp@Modes] for details.
+The trailing slash may be followed by one or more _flag_ characters
+that modify the behavior.
+See {Regexp options}[rdoc-ref:Regexp@Options] for details.
Interpolation may be used inside regular expressions along with escaped
characters. Note that a regular expression may require additional escaped
@@ -523,9 +523,9 @@ A few "symmetrical" character pairs may be used as delimiters:
%r(foo) # => /foo/
%r<foo> # => /foo/
-The trailing delimiter may be followed by one or more modifier characters
-that set modes for the regexp.
-See {Regexp modes}[rdoc-ref:Regexp@Modes] for details.
+The trailing delimiter may be followed by one or more _flag_ characters
+that modify the behavior.
+See {Regexp options}[rdoc-ref:Regexp@Options] for details.
=== <tt>%x</tt>: Backtick Literals
diff --git a/doc/syntax/modules_and_classes.rdoc b/doc/syntax/modules_and_classes.rdoc
index 9e05c5c774..024815a5a6 100644
--- a/doc/syntax/modules_and_classes.rdoc
+++ b/doc/syntax/modules_and_classes.rdoc
@@ -40,9 +40,9 @@ functionality:
remove_method :my_method
end
-Reopening modules (or classes) is a very powerful feature of Ruby, but it is
-best to only reopen modules you own. Reopening modules you do not own may lead
-to naming conflicts or difficult to diagnose bugs.
+Reopening classes is a very powerful feature of Ruby, but it is best to only
+reopen classes you own. Reopening classes you do not own may lead to naming
+conflicts or difficult to diagnose bugs.
== Nesting
@@ -259,28 +259,6 @@ includes a minimum of built-in methods. You can use BasicObject to create an
independent inheritance structure. See the BasicObject documentation for
further details.
-Just like modules, classes can also be reopened. You can omit its superclass
-when you reopen a class. Specifying a different superclass than the previous
-definition will raise an error.
-
- class C
- end
-
- class D < C
- end
-
- # OK
- class D < C
- end
-
- # OK
- class D
- end
-
- # TypeError: superclass mismatch for class D
- class D < String
- end
-
== Inheritance
Any method defined on a class is callable from its subclass:
diff --git a/doc/syntax/operators.rdoc b/doc/syntax/operators.rdoc
deleted file mode 100644
index 236b3413b5..0000000000
--- a/doc/syntax/operators.rdoc
+++ /dev/null
@@ -1,75 +0,0 @@
-= Operators
-
-In Ruby, operators such as <code>+</code>, are defined as methods on the class.
-Literals[rdoc-ref:syntax/literals.rdoc] define their methods within the lower
-level, C language. String class, for example.
-
-Ruby objects can define or overload their own implementation for most operators.
-
-Here is an example:
-
- class Foo < String
- def +(str)
- self.concat(str).concat("another string")
- end
- end
-
- foobar = Foo.new("test ")
- puts foobar + "baz "
-
-This prints:
-
- test baz another string
-
-What operators are available is dependent on the implementing class.
-
-== Operator Behavior
-
-How a class behaves to a given operator is specific to that class, since
-operators are method implementations.
-
-When using an operator, it's the expression on the left-hand side of the
-operation that specifies the behavior.
-
- 'a' * 3 #=> "aaa"
- 3 * 'a' # TypeError: String can't be coerced into Integer
-
-== Logical Operators
-
-Logical operators are not methods, and therefor cannot be
-redefined/overloaded. They are tokenized at a lower level.
-
-Short-circuit logical operators (<code>&&</code>, <code>||</code>,
-<code>and</code>, and <code>or</code>) do not always result in a boolean value.
-Similar to blocks, it's the last evaluated expression that defines the result
-of the operation.
-
-=== <code>&&</code>, <code>and</code>
-
-Both <code>&&</code>/<code>and</code> operators provide short-circuiting by executing each
-side of the operator, left to right, and stopping at the first occurrence of a
-falsey expression. The expression that defines the result is the last one
-executed, whether it be the final expression, or the first occurrence of a falsey
-expression.
-
-Some examples:
-
- true && 9 && "string" #=> "string"
- (1 + 2) && nil && "string" #=> nil
- (a = 1) && (b = false) && (c = "string") #=> false
-
- puts a #=> 1
- puts b #=> false
- puts c #=> nil
-
-In this last example, <code>c</code> was initialized, but not defined.
-
-=== <code>||</code>, <code>or</code>
-
-The means by which <code>||</code>/<code>or</code> short-circuits, is to return the result of
-the first expression that is truthy.
-
-Some examples:
-
- (1 + 2) || true || "string" #=> 3
- false || nil || "string" #=> "string"
diff --git a/doc/syntax/pattern_matching.rdoc b/doc/syntax/pattern_matching.rdoc
index e49c09a1f8..b7d614770c 100644
--- a/doc/syntax/pattern_matching.rdoc
+++ b/doc/syntax/pattern_matching.rdoc
@@ -415,11 +415,6 @@ Additionally, when matching custom classes, the expected class can be specified
end
#=> "matched: 1"
-These core and library classes implement deconstruction:
-
-* MatchData#deconstruct and MatchData#deconstruct_keys;
-* Time#deconstruct_keys, Date#deconstruct_keys, DateTime#deconstruct_keys.
-
== Guard clauses
+if+ can be used to attach an additional condition (guard clause) when the pattern matches. This condition may use bound variables:
@@ -450,6 +445,29 @@ These core and library classes implement deconstruction:
end
#=> "matched"
+== Current feature status
+
+As of Ruby 3.1, find patterns are considered _experimental_: its syntax can change in the future. Every time you use these features in code, a warning will be printed:
+
+ [0] => [*, 0, *]
+ # warning: Find pattern is experimental, and the behavior may change in future versions of Ruby!
+ # warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
+
+To suppress this warning, one may use the Warning::[]= method:
+
+ Warning[:experimental] = false
+ eval('[0] => [*, 0, *]')
+ # ...no warning printed...
+
+Note that pattern-matching warnings are raised at compile time, so this will not suppress the warning:
+
+ Warning[:experimental] = false # At the time this line is evaluated, the parsing happened and warning emitted
+ [0] => [*, 0, *]
+
+So, only subsequently loaded files or `eval`-ed code is affected by switching the flag.
+
+Alternatively, the command line option <code>-W:no-experimental</code> can be used to turn off "experimental" feature warnings.
+
== Appendix A. Pattern syntax
Approximate syntax is:
diff --git a/doc/syntax/refinements.rdoc b/doc/syntax/refinements.rdoc
index 17d5e67c21..c900ab1bdc 100644
--- a/doc/syntax/refinements.rdoc
+++ b/doc/syntax/refinements.rdoc
@@ -279,6 +279,6 @@ Refinements in descendants have higher precedence than those of ancestors.
== Further Reading
-See https://github.com/ruby/ruby/wiki/Refinements-Spec for the
+See https://bugs.ruby-lang.org/projects/ruby-master/wiki/RefinementsSpec for the
current specification for implementing refinements. The specification also
contains more details.
diff --git a/doc/timezones.rdoc b/doc/timezones.rdoc
new file mode 100644
index 0000000000..c3aae88fde
--- /dev/null
+++ b/doc/timezones.rdoc
@@ -0,0 +1,108 @@
+== Timezones
+
+=== Timezone Specifiers
+
+Certain \Time methods accept arguments that specify timezones:
+
+- Time.at: keyword argument +in:+.
+- Time.new: positional argument +zone+ or keyword argument +in:+.
+- Time.now: keyword argument +in:+.
+- Time#getlocal: positional argument +zone+.
+- Time#localtime: positional argument +zone+.
+
+The value given with any of these must be one of the following
+(each detailed below):
+
+- {Hours/minutes offset}[rdoc-ref:timezones.rdoc@Hours-2FMinutes+Offsets].
+- {Single-letter offset}[rdoc-ref:timezones.rdoc@Single-Letter+Offsets].
+- {Integer offset}[rdoc-ref:timezones.rdoc@Integer+Offsets].
+- {Timezone object}[rdoc-ref:timezones.rdoc@Timezone+Objects].
+
+==== Hours/Minutes Offsets
+
+The zone value may be a string offset from UTC
+in the form <tt>'+HH:MM'</tt> or <tt>'-HH:MM'</tt>,
+where:
+
+- +HH+ is the 2-digit hour in the range <tt>0..23</tt>.
+- +MM+ is the 2-digit minute in the range <tt>0..59</tt>.
+
+Examples:
+
+ t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
+ Time.at(t, in: '-23:59') # => 1999-12-31 20:16:01 -2359
+ Time.at(t, in: '+23:59') # => 2000-01-02 20:14:01 +2359
+
+==== Single-Letter Offsets
+
+The zone value may be a letter in the range <tt>'A'..'I'</tt>
+or <tt>'K'..'Z'</tt>;
+see {List of military time zones}[https://en.wikipedia.org/wiki/List_of_military_time_zones]:
+
+ t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
+ Time.at(t, in: 'A') # => 2000-01-01 21:15:01 +0100
+ Time.at(t, in: 'I') # => 2000-01-02 05:15:01 +0900
+ Time.at(t, in: 'K') # => 2000-01-02 06:15:01 +1000
+ Time.at(t, in: 'Y') # => 2000-01-01 08:15:01 -1200
+ Time.at(t, in: 'Z') # => 2000-01-01 20:15:01 UTC
+
+==== \Integer Offsets
+
+The zone value may be an integer number of seconds
+in the range <tt>-86399..86399</tt>:
+
+ t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
+ Time.at(t, in: -86399) # => 1999-12-31 20:15:02 -235959
+ Time.at(t, in: 86399) # => 2000-01-02 20:15:00 +235959
+
+==== Timezone Objects
+
+In most cases, the zone value may be an object
+responding to certain timezone methods.
+
+\Exceptions (timezone object not allowed):
+
+- Time.new with positional argument +zone+.
+- Time.now with keyword argument +in:+.
+
+The timezone methods are:
+
+- +local_to_utc+:
+
+ - Called when Time.new is invoked with +tz+
+ as the value of positional argument +zone+ or keyword argument +in:+.
+ - Argument: a <tt>Time::tm</tt> object.
+ - Returns: a \Time-like object in the UTC timezone.
+
+- +utc_to_local+:
+
+ - Called when Time.at or Time.now is invoked with +tz+
+ as the value for keyword argument +in:+,
+ and when Time#getlocal or Time#localtime is called with +tz+
+ as the value for positional argument +zone+.
+ - Argument: a <tt>Time::tm</tt> object.
+ - Returns: a \Time-like object in the local timezone.
+
+A custom timezone class may have these instance methods,
+which will be called if defined:
+
+- +abbr+:
+
+ - Called when Time#strftime is invoked with a format involving <tt>%Z</tt>.
+ - Argument: a <tt>Time::tm</tt> object.
+ - Returns: a string abbreviation for the timezone name.
+
+- +dst?+:
+
+ - Called when Time.at or Time.now is invoked with +tz+
+ as the value for keyword argument +in:+,
+ and when Time#getlocal or Time#localtime is called with +tz+
+ as the value for positional argument +zone+.
+ - Argument: a <tt>Time::tm</tt> object.
+ - Returns: whether the time is daylight saving time.
+
+- +name+:
+
+ - Called when <tt>Marshal.dump(t) is invoked
+ - Argument: none.
+ - Returns: the string name of the timezone.
diff --git a/doc/transcode.rdoc b/doc/transcode.rdoc
new file mode 100644
index 0000000000..4f15dff94a
--- /dev/null
+++ b/doc/transcode.rdoc
@@ -0,0 +1,52 @@
+# :markup: ruby
+
+class String
+ # call-seq:
+ # encode(dst_encoding = Encoding.default_internal, **enc_opts) -> string
+ # encode(dst_encoding, src_encoding, **enc_opts) -> string
+ #
+ # Returns a copy of +self+ transcoded as determined by +dst_encoding+.
+ # By default, raises an exception if +self+
+ # contains an invalid byte or a character not defined in +dst_encoding+;
+ # that behavior may be modified by encoding options; see below.
+ #
+ # With no arguments:
+ #
+ # - Uses the same encoding if <tt>Encoding.default_internal</tt> is +nil+
+ # (the default):
+ #
+ # Encoding.default_internal # => nil
+ # s = "Ruby\x99".force_encoding('Windows-1252')
+ # s.encoding # => #<Encoding:Windows-1252>
+ # s.bytes # => [82, 117, 98, 121, 153]
+ # t = s.encode # => "Ruby\x99"
+ # t.encoding # => #<Encoding:Windows-1252>
+ # t.bytes # => [82, 117, 98, 121, 226, 132, 162]
+ #
+ # - Otherwise, uses the encoding <tt>Encoding.default_internal</tt>:
+ #
+ # Encoding.default_internal = 'UTF-8'
+ # t = s.encode # => "Rubyâ„¢"
+ # t.encoding # => #<Encoding:UTF-8>
+ #
+ # With only argument +dst_encoding+ given, uses that encoding:
+ #
+ # s = "Ruby\x99".force_encoding('Windows-1252')
+ # s.encoding # => #<Encoding:Windows-1252>
+ # t = s.encode('UTF-8') # => "Rubyâ„¢"
+ # t.encoding # => #<Encoding:UTF-8>
+ #
+ # With arguments +dst_encoding+ and +src_encoding+ given,
+ # interprets +self+ using +src_encoding+, encodes the new string using +dst_encoding+:
+ #
+ # s = "Ruby\x99"
+ # t = s.encode('UTF-8', 'Windows-1252') # => "Rubyâ„¢"
+ # t.encoding # => #<Encoding:UTF-8>
+ #
+ # Optional keyword arguments +enc_opts+ specify encoding options;
+ # see {Encoding Options}[rdoc-ref:encodings.rdoc@Encoding+Options].
+ def encode(dst_encoding = Encoding.default_internal, **enc_opts)
+ # Pseudo code
+ Primitive.str_encode(...)
+ end
+end
diff --git a/doc/windows.md b/doc/windows.md
deleted file mode 100644
index 65c6b15c45..0000000000
--- a/doc/windows.md
+++ /dev/null
@@ -1,233 +0,0 @@
-# Windows
-
-Ruby supports a few native build platforms for Windows.
-
-* mswin: Build using Microsoft Visual C++ compiler with vcruntimeXXX.dll
-* mingw-msvcrt: Build using compiler for Mingw with msvcrtXX.dll
-* mingw-ucrt: Build using compiler for Mingw with Windows Universal CRT
-
-## Building Ruby using Mingw with UCRT
-
-The easiest build environment is just a standard [RubyInstaller-Devkit]
-installation and [git-for-windows]. You might like to use [VSCode] as an
-editor.
-
-### Build examples
-
-Ruby core development can be done either in Windows `cmd` like:
-
-```
-ridk enable ucrt64
-
-pacman -S --needed %MINGW_PACKAGE_PREFIX%-openssl %MINGW_PACKAGE_PREFIX%-libyaml %MINGW_PACKAGE_PREFIX%-libffi
-
-cd c:\
-mkdir work
-cd work
-git clone https://github.com/ruby/ruby
-
-cd c:\work\ruby
-sh autogen.sh
-sh configure -C --disable-install-doc
-make
-```
-
-or in MSYS2 `bash` like:
-
-```
-ridk enable ucrt64
-bash
-
-pacman -S --needed $MINGW_PACKAGE_PREFIX-openssl $MINGW_PACKAGE_PREFIX-libyaml $MINGW_PACKAGE_PREFIX-libffi
-
-cd /c/
-mkdir work
-cd work
-git clone https://github.com/ruby/ruby
-cd ruby
-
-./autogen.sh
-./configure -C --disable-install-doc
-make
-```
-
-[RubyInstaller-Devkit]: https://rubyinstaller.org/
-[git-for-windows]: https://gitforwindows.org/
-[VSCode]: https://code.visualstudio.com/
-
-## Building Ruby using Visual C++
-
-### Requirement
-
-1. Windows 7 or later.
-
-2. Visual C++ 12.0 (2013) or later.
-
- **Note** if you want to build x64 version, use native compiler for
- x64.
-
-3. Please set environment variable `INCLUDE`, `LIB`, `PATH`
- to run required commands properly from the command line.
-
- **Note** building ruby requires following commands.
-
- * nmake
- * cl
- * ml
- * lib
- * dumpbin
-
-4. If you want to build from GIT source, following commands are required.
- * patch
- * sed
- * ruby 2.0 or later
-
- You can use [scoop](https://scoop.sh/) to install them like:
-
- ```
- scoop install git ruby sed patch
- ```
-
-5. You need to install required libraries using [vcpkg](https://vcpkg.io/) like:
-
- ```
- vcpkg --triplet x64-windows install openssl libffi libyaml zlib
- ```
-
-6. Enable Command Extension of your command line. It's the default behavior
- of `cmd.exe`. If you want to enable it explicitly, run `cmd.exe` with
- `/E:ON` option.
-
-### How to compile and install
-
-1. Execute `win32\configure.bat` on your build directory.
- You can specify the target platform as an argument.
- For example, run `configure --target=i686-mswin32`
- You can also specify the install directory.
- For example, run `configure --prefix=<install_directory>`
- Default of the install directory is `/usr` .
- The default _PLATFORM_ is `i386-mswin32_`_MSRTVERSION_ on 32-bit
- platforms, or `x64-mswin64_`_MSRTVERSION_ on x64 platforms.
- _MSRTVERSION_ is the 2- or 3-digits version of the Microsoft
- Runtime Library.
-
-2. Change _RUBY_INSTALL_NAME_ and _RUBY_SO_NAME_ in `Makefile`
- if you want to change the name of the executable files.
- And add _RUBYW_INSTALL_NAME_ to change the name of the
- executable without console window if also you want.
-
-3. You need specify vcpkg directory to use `--with-opt-dir`
- option like `configure --with-opt-dir=C:\vcpkg\installed\x64-windows`
-
-4. Run `nmake up` if you are building from GIT source.
-
-5. Run `nmake`
-
-6. Run `nmake check`
-
-7. Run `nmake install`
-
-### Build examples
-
-* Build on the ruby source directory.
-
- ```
- ruby source directory: C:\ruby
- build directory: C:\ruby
- install directory: C:\usr\local
- ```
-
- ```
- C:
- cd \ruby
- win32\configure --prefix=/usr/local
- nmake
- nmake check
- nmake install
- ```
-
-* Build on the relative directory from the ruby source directory.
-
- ```
- ruby source directory: C:\ruby
- build directory: C:\ruby\mswin32
- install directory: C:\usr\local
- ```
-
- ```
- C:
- cd \ruby
- mkdir mswin32
- cd mswin32
- ..\win32\configure --prefix=/usr/local
- nmake
- nmake check
- nmake install
- ```
-
-* Build on the different drive.
-
- ```
- ruby source directory: C:\src\ruby
- build directory: D:\build\ruby
- install directory: C:\usr\local
- ```
-
- ```
- D:
- cd D:\build\ruby
- C:\src\ruby\win32\configure --prefix=/usr/local
- nmake
- nmake check
- nmake install DESTDIR=C:
- ```
-
-* Build x64 version (requires native x64 VC++ compiler)
-
- ```
- ruby source directory: C:\ruby
- build directory: C:\ruby
- install directory: C:\usr\local
- ```
-
- ```
- C:
- cd \ruby
- win32\configure --prefix=/usr/local --target=x64-mswin64
- nmake
- nmake check
- nmake install
- ```
-
-### Bugs
-
-You can **NOT** use a path name that contains any white space characters
-as the ruby source directory, this restriction comes from the behavior
-of `!INCLUDE` directives of `NMAKE`.
-
-You can build ruby in any directory including the source directory,
-except `win32` directory in the source directory.
-This is restriction originating in the path search method of `NMAKE`.
-
-## Icons
-
-Any icon files(`*.ico`) in the build directory, directories specified with
-_icondirs_ make variable and `win32` directory under the ruby
-source directory will be included in DLL or executable files, according
-to their base names.
- $(RUBY_INSTALL_NAME).ico or ruby.ico --> $(RUBY_INSTALL_NAME).exe
- $(RUBYW_INSTALL_NAME).ico or rubyw.ico --> $(RUBYW_INSTALL_NAME).exe
- the others --> $(RUBY_SO_NAME).dll
-
-Although no icons are distributed with the ruby source, you can use
-anything you like. You will be able to find many images by search engines.
-For example, followings are made from [Ruby logo kit]:
-
-* Small [favicon] in the official site
-
-* [vit-ruby.ico] or [icon itself]
-
-[Ruby logo kit]: https://cache.ruby-lang.org/pub/misc/logo/ruby-logo-kit.zip
-[favicon]: https://www.ruby-lang.org/favicon.ico
-[vit-ruby.ico]: http://ruby.morphball.net/vit-ruby-ico_en.html
-[icon itself]: http://ruby.morphball.net/icon/vit-ruby.ico
diff --git a/doc/yjit/yjit.md b/doc/yjit/yjit.md
index e6446e3ed1..67b2ffa5f0 100644
--- a/doc/yjit/yjit.md
+++ b/doc/yjit/yjit.md
@@ -4,27 +4,26 @@
</a>
</p>
+
YJIT - Yet Another Ruby JIT
===========================
YJIT is a lightweight, minimalistic Ruby JIT built inside CRuby.
It lazily compiles code using a Basic Block Versioning (BBV) architecture.
+The target use case is that of servers running Ruby on Rails.
YJIT is currently supported for macOS, Linux and BSD on x86-64 and arm64/aarch64 CPUs.
This project is open source and falls under the same license as CRuby.
<p align="center"><b>
If you're using YJIT in production, please
<a href="mailto:maxime.chevalierboisvert@shopify.com">share your success stories with us!</a>
-</b></p>
+ </b></p>
If you wish to learn more about the approach taken, here are some conference talks and publications:
-- RubyKaigi 2023 keynote: [Optimizing YJIT’s Performance, from Inception to Production](https://www.youtube.com/watch?v=X0JRhh8w_4I)
-- RubyKaigi 2023 keynote: [Fitting Rust YJIT into CRuby](https://www.youtube.com/watch?v=GI7vvAgP_Qs)
- RubyKaigi 2022 keynote: [Stories from developing YJIT](https://www.youtube.com/watch?v=EMchdR9C8XM)
- RubyKaigi 2022 talk: [Building a Lightweight IR and Backend for YJIT](https://www.youtube.com/watch?v=BbLGqTxTRp0)
- RubyKaigi 2021 talk: [YJIT: Building a New JIT Compiler Inside CRuby](https://www.youtube.com/watch?v=PBVLf3yfMs8)
- Blog post: [YJIT: Building a New JIT Compiler Inside CRuby](https://pointersgonewild.com/2021/06/02/yjit-building-a-new-jit-compiler-inside-cruby/)
-- MPLR 2023 paper: [Evaluating YJIT’s Performance in a Production Context: A Pragmatic Approach](https://dl.acm.org/doi/10.1145/3617651.3622982)
- VMIL 2021 paper: [YJIT: A Basic Block Versioning JIT Compiler for CRuby](https://dl.acm.org/doi/10.1145/3486606.3486781)
- MoreVMs 2021 talk: [YJIT: Building a New JIT Compiler Inside CRuby](https://www.youtube.com/watch?v=vucLAqv7qpc)
- ECOOP 2016 talk: [Interprocedural Type Specialization of JavaScript Programs Without Type Analysis](https://www.youtube.com/watch?v=sRNBY7Ss97A)
@@ -32,31 +31,31 @@ If you wish to learn more about the approach taken, here are some conference tal
- ECOOP 2015 talk: [Simple and Effective Type Check Removal through Lazy Basic Block Versioning](https://www.youtube.com/watch?v=S-aHBuoiYE0)
- ECOOP 2015 paper: [Simple and Effective Type Check Removal through Lazy Basic Block Versioning](https://arxiv.org/pdf/1411.0352.pdf)
-To cite YJIT in your publications, please cite the MPLR 2023 paper:
+To cite YJIT in your publications, please cite the VMIL 2021 paper:
```
-@inproceedings{yjit_mplr_2023,
-author = {Chevalier-Boisvert, Maxime and Kokubun, Takashi and Gibbs, Noah and Wu, Si Xing (Alan) and Patterson, Aaron and Issroff, Jemma},
-title = {Evaluating YJIT’s Performance in a Production Context: A Pragmatic Approach},
-year = {2023},
-isbn = {9798400703805},
+@inproceedings{yjit_vmil2021,
+author = {Chevalier-Boisvert, Maxime and Gibbs, Noah and Boussier, Jean and Wu, Si Xing (Alan) and Patterson, Aaron and Newton, Kevin and Hawthorn, John},
+title = {YJIT: A Basic Block Versioning JIT Compiler for CRuby},
+year = {2021},
+isbn = {9781450391092},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
-url = {https://doi.org/10.1145/3617651.3622982},
-doi = {10.1145/3617651.3622982},
-booktitle = {Proceedings of the 20th ACM SIGPLAN International Conference on Managed Programming Languages and Runtimes},
-pages = {20–33},
-numpages = {14},
-keywords = {dynamically typed, optimization, just-in-time, virtual machine, ruby, compiler, bytecode},
-location = {Cascais, Portugal},
-series = {MPLR 2023}
+url = {https://doi.org/10.1145/3486606.3486781},
+doi = {10.1145/3486606.3486781},
+booktitle = {Proceedings of the 13th ACM SIGPLAN International Workshop on Virtual Machines and Intermediate Languages},
+pages = {25–32},
+numpages = {8},
+keywords = {ruby, dynamically typed, compiler, optimization, just-in-time, bytecode},
+location = {Chicago, IL, USA},
+series = {VMIL 2021}
}
```
## Current Limitations
-YJIT may not be suitable for certain applications. It currently only supports macOS, Linux and BSD on x86-64 and arm64/aarch64 CPUs. YJIT will use more memory than the Ruby interpreter because the JIT compiler needs to generate machine code in memory and maintain additional state information.
-You can change how much executable memory is allocated using [YJIT's command-line options](#command-line-options).
+YJIT may not be suitable for certain applications. It currently only supports macOS and Linux on x86-64 and arm64/aarch64 CPUs. YJIT will use more memory than the Ruby interpreter because the JIT compiler needs to generate machine code in memory and maintain additional state information.
+You can change how much executable memory is allocated using [YJIT's command-line options](#command-line-options). There is a slight performance tradeoff because allocating less executable memory could result in the generated machine code being collected more often.
## Installation
@@ -113,7 +112,7 @@ On macOS, you may need to specify where to find some libraries:
```sh
# Install dependencies
-brew install openssl libyaml
+brew install openssl readline libyaml
# Configure in dev (debug) mode for development, build and install
./autogen.sh
@@ -165,61 +164,32 @@ The machine code generated for a given method can be printed by adding `puts Rub
YJIT supports all command-line options supported by upstream CRuby, but also adds a few YJIT-specific options:
- `--yjit`: enable YJIT (disabled by default)
-- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 48 MiB)
-- `--yjit-call-threshold=N`: number of calls after which YJIT begins to compile a function.
- It defaults to 30, and it's then increased to 120 when the number of ISEQs in the process reaches 40,000.
-- `--yjit-cold-threshold=N`: number of global calls after which an ISEQ is considered cold and not
- compiled, lower values mean less code is compiled (default 200K)
+- `--yjit-call-threshold=N`: number of calls after which YJIT begins to compile a function (default 30)
+- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 64 MiB)
- `--yjit-stats`: print statistics after the execution of a program (incurs a run-time cost)
-- `--yjit-stats=quiet`: gather statistics while running a program but don't print them. Stats are accessible through `RubyVM::YJIT.runtime_stats`. (incurs a run-time cost)
-- `--yjit-disable`: disable YJIT despite other `--yjit*` flags for lazily enabling it with `RubyVM::YJIT.enable`
-- `--yjit-code-gc`: enable code GC (disabled by default as of Ruby 3.3).
- It will cause all machine code to be discarded when the executable memory size limit is hit, meaning JIT compilation will then start over.
- This can allow you to use a lower executable memory size limit, but may cause a slight drop in performance when the limit is hit.
-- `--yjit-perf`: enable frame pointers and profiling with the `perf` tool
- `--yjit-trace-exits`: produce a Marshal dump of backtraces from specific exits. Automatically enables `--yjit-stats`
-- `--yjit-trace-exits-sample-rate=N`: trace exit locations only every Nth occurrence
Note that there is also an environment variable `RUBY_YJIT_ENABLE` which can be used to enable YJIT.
This can be useful for some deployment scripts where specifying an extra command-line option to Ruby is not practical.
-You can also enable YJIT at run-time using `RubyVM::YJIT.enable`. This can allow you to enable YJIT after your application is done
-booting, which makes it possible to avoid compiling any initialization code.
-
-You can verify that YJIT is enabled using `RubyVM::YJIT.enabled?` or by checking that `ruby --yjit -v` includes the string `+YJIT`:
-
-```sh
-ruby --yjit -v
-ruby 3.3.0dev (2023-01-31T15:11:10Z master 2a0bf269c9) +YJIT dev [x86_64-darwin22]
-
-ruby --yjit -e "p RubyVM::YJIT.enabled?"
-true
-
-ruby -e "RubyVM::YJIT.enable; p RubyVM::YJIT.enabled?"
-true
-```
-
### Benchmarking
-We have collected a set of benchmarks and implemented a simple benchmarking harness in the [yjit-bench](https://github.com/Shopify/yjit-bench) repository. This benchmarking harness is designed to disable CPU frequency scaling, set process affinity and disable address space randomization so that the variance between benchmarking runs will be as small as possible.
+We have collected a set of benchmarks and implemented a simple benchmarking harness in the [yjit-bench](https://github.com/Shopify/yjit-bench) repository. This benchmarking harness is designed to disable CPU frequency scaling, set process affinity and disable address space randomization so that the variance between benchmarking runs will be as small as possible. Please kindly note that we are at an early stage in this project.
## Performance Tips for Production Deployments
While YJIT options default to what we think would work well for most workloads,
they might not necessarily be the best configuration for your application.
+
This section covers tips on improving YJIT performance in case YJIT does not
speed up your application in production.
### Increasing --yjit-exec-mem-size
When JIT code size (`RubyVM::YJIT.runtime_stats[:code_region_size]`) reaches this value,
-YJIT stops compiling new code. Increasing the executable memory size means more code
-can be optimized by YJIT, at the cost of more memory usage.
-
-If you start Ruby with `--yjit-stats`, e.g. using an environment variable `RUBYOPT=--yjit-stats`,
-`RubyVM::YJIT.runtime_stats[:ratio_in_yjit]` shows the ratio of YJIT-executed instructions in %.
-Ideally, `ratio_in_yjit` should be as large as 99%, and increasing `--yjit-exec-mem-size` often
-helps improving `ratio_in_yjit`.
+YJIT triggers "code GC" that frees all JIT code and starts recompiling everything.
+Compiling code takes some time, so scheduling code GC too frequently slows down your application.
+Increasing `--yjit-exec-mem-size` may speed up your application if `RubyVM::YJIT.runtime_stats[:code_gc_count]` is not 0 or 1.
### Running workers as long as possible
@@ -231,29 +201,30 @@ You should monitor the number of requests each process has served.
If you're periodically killing worker processes, e.g. with `unicorn-worker-killer` or `puma_worker_killer`,
you may want to reduce the killing frequency or increase the limit.
-## Reducing YJIT Memory Usage
+## Saving YJIT Memory Usage
YJIT allocates memory for JIT code and metadata. Enabling YJIT generally results in more memory usage.
+
This section goes over tips on minimizing YJIT memory usage in case it uses more than your capacity.
+### Increasing --yjit-call-threshold
+
+As of Ruby 3.2, `--yjit-call-threshold` defaults to 30. With this default, some applications end up
+compiling methods that are used only during the application boot. Increasing this option may help
+you reduce the size of JIT code and metadata. It's worth trying different values like `--yjit-call-threshold=100`.
+
+Note that increasing the value too much may result in compiling code too late.
+You should monitor how many requests each worker processes before it's restarted. For example,
+if each process only handles 1000 requests, `--yjit-call-threshold=1000` might be too large for your application.
+
### Decreasing --yjit-exec-mem-size
-The `--yjit-exec-mem-size` option specifies the JIT code size, but YJIT also uses memory for its metadata,
+`--yjit-exec-mem-size` specifies the JIT code size, but YJIT also uses memory for its metadata,
which often consumes more memory than JIT code. Generally, YJIT adds memory overhead by roughly
-3-4x of `--yjit-exec-mem-size` in production as of Ruby 3.3. You should multiply that by the number
+3-4x of `--yjit-exec-mem-size` in production as of Ruby 3.2. You should multiply that by the number
of worker processes to estimate the worst case memory overhead.
-`--yjit-exec-mem-size=48` is the default since Ruby 3.3.1,
-but smaller values like 32 MiB might make sense for your application.
-While doing so, you may want to monitor `RubyVM::YJIT.runtime_stats[:ratio_in_yjit]` as explained above.
-
-### Enabling YJIT lazily
-
-If you enable YJIT by `--yjit` options or `RUBY_YJIT_ENABLE=1`, YJIT may compile code that is
-used only during the application boot. `RubyVM::YJIT.enable` allows you to enable YJIT from Ruby code,
-and you can call this after your application is initialized, e.g. on Unicorn's `after_fork` hook.
-If you use any YJIT options (`--yjit-*`), YJIT will start at boot by default, but `--yjit-disable`
-allows you to start Ruby with the YJIT-disabled mode while passing YJIT tuning options.
+Running code GC adds overhead, but it could be still faster than recovering from a whole process killed by OOM.
## Code Optimization Tips
@@ -265,7 +236,7 @@ This section contains tips on writing Ruby code that will run as fast as possibl
- Avoid allocating objects in the hot parts of your code
- Minimize layers of indirection
- Avoid classes that wrap objects if you can
- - Avoid methods that just call another method, trivial one-liner methods
+ - Avoid methods that just call another method, trivial one liner methods
- Try to write code so that the same variables always have the same type
- Use `while` loops if you can, instead of C methods like `Array#each`
- This is not idiomatic Ruby, but could help in hot methods
@@ -275,16 +246,16 @@ You can also use the `--yjit-stats` command-line option to see which bytecodes c
### Other Statistics
-If you run `ruby` with `--yjit-stats`, YJIT will track and return performance statistics in `RubyVM::YJIT.runtime_stats`.
+If you run `ruby` with `--yjit --yjit-stats`, YJIT will track and return performance statistics in `RubyVM::YJIT.runtime_stats`.
```rb
-$ RUBYOPT="--yjit-stats" irb
+$ RUBYOPT="--yjit --yjit-stats" irb
irb(main):001:0> RubyVM::YJIT.runtime_stats
=>
{:inline_code_size=>340745,
:outlined_code_size=>297664,
:all_stats=>true,
- :yjit_insns_count=>1547816,
+ :exec_instruction=>1547816,
:send_callsite_not_simple=>7267,
:send_kw_splat=>7,
:send_ivar_set_method=>72,
@@ -293,7 +264,7 @@ irb(main):001:0> RubyVM::YJIT.runtime_stats
Some of the counters include:
-* :yjit_insns_count - how many Ruby bytecode instructions have been executed
+* :exec_instruction - how many Ruby bytecode instructions have been executed
* :binding_allocations - number of bindings allocated
* :binding_set - number of variables set via a binding
* :code_gc_count - number of garbage collections of compiled code since process start
@@ -305,26 +276,25 @@ Some of the counters include:
* :total_exit_count - number of exits, including side exits, taken at runtime
* :avg_len_in_yjit - avg. number of instructions in compiled blocks before exiting to interpreter
-Counters starting with "exit_" show reasons for YJIT code taking a side exit (return to the interpreter.)
+Counters starting with "exit_" show reasons for YJIT code taking a side exit (return to the interpreter.) See yjit_hacking.md for more details.
-Performance counter names are not guaranteed to remain the same between Ruby versions. If you're curious what each counter means,
-it's usually best to search the source code for it &mdash; but it may change in a later Ruby version.
+Performance counter names are not guaranteed to remain the same between Ruby versions. If you're curious what one does, it's usually best to search the source code for it &mdash; but it may change in a later Ruby version.
-The printed text after a `--yjit-stats` run includes other information that may be named differently than the information in `RubyVM::YJIT.runtime_stats`.
+The printed text after a --yjit-stats run includes other information that may be named differently than the information in runtime_stats.
## Contributing
-We welcome open source contributions. You should feel free to open new issues to report bugs or just to ask questions.
+We welcome open source contributors. You should feel free to open new issues to report bugs or just to ask questions.
Suggestions on how to make this readme file more helpful for new contributors are most welcome.
Bug fixes and bug reports are very valuable to us. If you find a bug in YJIT, it's very possible be that nobody has reported it before,
or that we don't have a good reproduction for it, so please open an issue and provide as much information as you can about your configuration and a description of how you encountered the problem. List the commands you used to run YJIT so that we can easily reproduce the issue on our end and investigate it. If you are able to produce a small program reproducing the error to help us track it down, that is very much appreciated as well.
-If you would like to contribute a large patch to YJIT, we suggest opening an issue or a discussion on the [Shopify/ruby repository](https://github.com/Shopify/ruby/issues) so that
+If you would like to contribute a large patch to YJIT, we suggest opening an issue or a discussion on this repository so that
we can have an active discussion. A common problem is that sometimes people submit large pull requests to open source projects
without prior communication, and we have to reject them because the work they implemented does not fit within the design of the
-project. We want to save you time and frustration, so please reach out so we can have a productive discussion as to how
-you can contribute patches we will want to merge into YJIT.
+project. We want to save you time and frustration, so please reach out and we can have a productive discussion as to how
+you can contribute things we will want to merge into YJIT.
### Source Code Organization
@@ -337,8 +307,8 @@ The YJIT source code is divided between:
- `yjit/src/core.rb`: basic block versioning logic, core structure of YJIT
- `yjit/src/stats.rs`: gathering of run-time statistics
- `yjit/src/options.rs`: handling of command-line options
-- `yjit/src/cruby.rs`: C bindings manually exposed to the Rust codebase
- `yjit/bindgen/src/main.rs`: C bindings exposed to the Rust codebase through bindgen
+- `yjit/src/cruby.rs`: C bindings manually exposed to the Rust codebase
The core of CRuby's interpreter logic is found in:
- `insns.def`: defines Ruby's bytecode instructions (gets compiled into `vm.inc`)
@@ -361,12 +331,11 @@ add them to `yjit/cruby.rs` instead.
### Coding & Debugging Protips
-There are multiple test suites:
+There are 3 test suites:
- `make btest` (see `/bootstraptest`)
- `make test-all`
- `make test-spec`
- `make check` runs all of the above
-- `make yjit-smoke-test` runs quick checks to see that YJIT is working correctly
The tests can be run in parallel like this:
@@ -446,30 +415,3 @@ While in your i386 shell, install Cargo and Homebrew, then hack away!
2. Cargo will install in $HOME/.cargo by default, and I don't know a good way to change architectures after install
If you use Fish shell you can [read this link](https://tenderlovemaking.com/2022/01/07/homebrew-rosetta-and-ruby.html) for information on making the dev environment easier.
-
-## Profiling with Linux perf
-
-`--yjit-perf` allows you to profile JIT-ed methods along with other native functions using Linux perf.
-When you run Ruby with `perf record`, perf looks up `/tmp/perf-{pid}.map` to resolve symbols in JIT code,
-and this option lets YJIT write method symbols into that file as well as enabling frame pointers.
-
-Here's an example way to use this option with [Firefox Profiler](https://profiler.firefox.com)
-(See also: [Profiling with Linux perf](https://profiler.firefox.com/docs/#/./guide-perf-profiling)):
-
-```bash
-# Compile the interpreter with frame pointers enabled
-./configure --enable-yjit --prefix=$HOME/.rubies/ruby-yjit --disable-install-doc cflags=-fno-omit-frame-pointer
-make -j && make install
-
-# [Optional] Allow running perf without sudo
-echo 0 | sudo tee /proc/sys/kernel/kptr_restrict
-echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
-
-# Profile Ruby with --yjit-perf
-cd ../yjit-bench
-perf record --call-graph fp -- ruby --yjit-perf -Iharness-perf benchmarks/liquid-render/benchmark.rb
-
-# View results on Firefox Profiler https://profiler.firefox.com.
-# Create /tmp/test.perf as below and upload it using "Load a profile from file".
-perf script --fields +pid > /tmp/test.perf
-```
diff --git a/enc/depend b/enc/depend
index 12ddbc223a..973ad93010 100644
--- a/enc/depend
+++ b/enc/depend
@@ -58,8 +58,12 @@ TRANSCLEANOBJS = <%=cleanobjs.map {|clean|
LIBTRANS=enc/libtrans.$(LIBEXT)
UNICODE_HDR_DIR = --missing-unicode-header-dir--
-encs all: <%= MODULE_TYPE == :static ? "lib" : "mod" %>encs
-modencs: enc trans
+encs: all
+% if MODULE_TYPE == :static
+all: libenc libtrans
+% else
+all: enc trans
+%end
libencs: libenc libtrans
enc: $(ENCSOS)
libenc: $(LIBENC)
@@ -230,7 +234,6 @@ enc/ascii.$(OBJEXT): internal/attr/noexcept.h
enc/ascii.$(OBJEXT): internal/attr/noinline.h
enc/ascii.$(OBJEXT): internal/attr/nonnull.h
enc/ascii.$(OBJEXT): internal/attr/noreturn.h
-enc/ascii.$(OBJEXT): internal/attr/packed_struct.h
enc/ascii.$(OBJEXT): internal/attr/pure.h
enc/ascii.$(OBJEXT): internal/attr/restrict.h
enc/ascii.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -299,6 +302,7 @@ enc/ascii.$(OBJEXT): internal/intern/enumerator.h
enc/ascii.$(OBJEXT): internal/intern/error.h
enc/ascii.$(OBJEXT): internal/intern/eval.h
enc/ascii.$(OBJEXT): internal/intern/file.h
+enc/ascii.$(OBJEXT): internal/intern/gc.h
enc/ascii.$(OBJEXT): internal/intern/hash.h
enc/ascii.$(OBJEXT): internal/intern/io.h
enc/ascii.$(OBJEXT): internal/intern/load.h
@@ -329,6 +333,7 @@ enc/ascii.$(OBJEXT): internal/memory.h
enc/ascii.$(OBJEXT): internal/method.h
enc/ascii.$(OBJEXT): internal/module.h
enc/ascii.$(OBJEXT): internal/newobj.h
+enc/ascii.$(OBJEXT): internal/rgengc.h
enc/ascii.$(OBJEXT): internal/scan_args.h
enc/ascii.$(OBJEXT): internal/special_consts.h
enc/ascii.$(OBJEXT): internal/static_assert.h
@@ -400,7 +405,6 @@ enc/big5.$(OBJEXT): internal/attr/noexcept.h
enc/big5.$(OBJEXT): internal/attr/noinline.h
enc/big5.$(OBJEXT): internal/attr/nonnull.h
enc/big5.$(OBJEXT): internal/attr/noreturn.h
-enc/big5.$(OBJEXT): internal/attr/packed_struct.h
enc/big5.$(OBJEXT): internal/attr/pure.h
enc/big5.$(OBJEXT): internal/attr/restrict.h
enc/big5.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -460,6 +464,7 @@ enc/big5.$(OBJEXT): internal/intern/enumerator.h
enc/big5.$(OBJEXT): internal/intern/error.h
enc/big5.$(OBJEXT): internal/intern/eval.h
enc/big5.$(OBJEXT): internal/intern/file.h
+enc/big5.$(OBJEXT): internal/intern/gc.h
enc/big5.$(OBJEXT): internal/intern/hash.h
enc/big5.$(OBJEXT): internal/intern/io.h
enc/big5.$(OBJEXT): internal/intern/load.h
@@ -490,6 +495,7 @@ enc/big5.$(OBJEXT): internal/memory.h
enc/big5.$(OBJEXT): internal/method.h
enc/big5.$(OBJEXT): internal/module.h
enc/big5.$(OBJEXT): internal/newobj.h
+enc/big5.$(OBJEXT): internal/rgengc.h
enc/big5.$(OBJEXT): internal/scan_args.h
enc/big5.$(OBJEXT): internal/special_consts.h
enc/big5.$(OBJEXT): internal/static_assert.h
@@ -562,7 +568,6 @@ enc/cesu_8.$(OBJEXT): internal/attr/noexcept.h
enc/cesu_8.$(OBJEXT): internal/attr/noinline.h
enc/cesu_8.$(OBJEXT): internal/attr/nonnull.h
enc/cesu_8.$(OBJEXT): internal/attr/noreturn.h
-enc/cesu_8.$(OBJEXT): internal/attr/packed_struct.h
enc/cesu_8.$(OBJEXT): internal/attr/pure.h
enc/cesu_8.$(OBJEXT): internal/attr/restrict.h
enc/cesu_8.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -631,6 +636,7 @@ enc/cesu_8.$(OBJEXT): internal/intern/enumerator.h
enc/cesu_8.$(OBJEXT): internal/intern/error.h
enc/cesu_8.$(OBJEXT): internal/intern/eval.h
enc/cesu_8.$(OBJEXT): internal/intern/file.h
+enc/cesu_8.$(OBJEXT): internal/intern/gc.h
enc/cesu_8.$(OBJEXT): internal/intern/hash.h
enc/cesu_8.$(OBJEXT): internal/intern/io.h
enc/cesu_8.$(OBJEXT): internal/intern/load.h
@@ -661,6 +667,7 @@ enc/cesu_8.$(OBJEXT): internal/memory.h
enc/cesu_8.$(OBJEXT): internal/method.h
enc/cesu_8.$(OBJEXT): internal/module.h
enc/cesu_8.$(OBJEXT): internal/newobj.h
+enc/cesu_8.$(OBJEXT): internal/rgengc.h
enc/cesu_8.$(OBJEXT): internal/scan_args.h
enc/cesu_8.$(OBJEXT): internal/special_consts.h
enc/cesu_8.$(OBJEXT): internal/static_assert.h
@@ -732,7 +739,6 @@ enc/cp949.$(OBJEXT): internal/attr/noexcept.h
enc/cp949.$(OBJEXT): internal/attr/noinline.h
enc/cp949.$(OBJEXT): internal/attr/nonnull.h
enc/cp949.$(OBJEXT): internal/attr/noreturn.h
-enc/cp949.$(OBJEXT): internal/attr/packed_struct.h
enc/cp949.$(OBJEXT): internal/attr/pure.h
enc/cp949.$(OBJEXT): internal/attr/restrict.h
enc/cp949.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -792,6 +798,7 @@ enc/cp949.$(OBJEXT): internal/intern/enumerator.h
enc/cp949.$(OBJEXT): internal/intern/error.h
enc/cp949.$(OBJEXT): internal/intern/eval.h
enc/cp949.$(OBJEXT): internal/intern/file.h
+enc/cp949.$(OBJEXT): internal/intern/gc.h
enc/cp949.$(OBJEXT): internal/intern/hash.h
enc/cp949.$(OBJEXT): internal/intern/io.h
enc/cp949.$(OBJEXT): internal/intern/load.h
@@ -822,6 +829,7 @@ enc/cp949.$(OBJEXT): internal/memory.h
enc/cp949.$(OBJEXT): internal/method.h
enc/cp949.$(OBJEXT): internal/module.h
enc/cp949.$(OBJEXT): internal/newobj.h
+enc/cp949.$(OBJEXT): internal/rgengc.h
enc/cp949.$(OBJEXT): internal/scan_args.h
enc/cp949.$(OBJEXT): internal/special_consts.h
enc/cp949.$(OBJEXT): internal/static_assert.h
@@ -892,7 +900,6 @@ enc/emacs_mule.$(OBJEXT): internal/attr/noexcept.h
enc/emacs_mule.$(OBJEXT): internal/attr/noinline.h
enc/emacs_mule.$(OBJEXT): internal/attr/nonnull.h
enc/emacs_mule.$(OBJEXT): internal/attr/noreturn.h
-enc/emacs_mule.$(OBJEXT): internal/attr/packed_struct.h
enc/emacs_mule.$(OBJEXT): internal/attr/pure.h
enc/emacs_mule.$(OBJEXT): internal/attr/restrict.h
enc/emacs_mule.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -952,6 +959,7 @@ enc/emacs_mule.$(OBJEXT): internal/intern/enumerator.h
enc/emacs_mule.$(OBJEXT): internal/intern/error.h
enc/emacs_mule.$(OBJEXT): internal/intern/eval.h
enc/emacs_mule.$(OBJEXT): internal/intern/file.h
+enc/emacs_mule.$(OBJEXT): internal/intern/gc.h
enc/emacs_mule.$(OBJEXT): internal/intern/hash.h
enc/emacs_mule.$(OBJEXT): internal/intern/io.h
enc/emacs_mule.$(OBJEXT): internal/intern/load.h
@@ -982,6 +990,7 @@ enc/emacs_mule.$(OBJEXT): internal/memory.h
enc/emacs_mule.$(OBJEXT): internal/method.h
enc/emacs_mule.$(OBJEXT): internal/module.h
enc/emacs_mule.$(OBJEXT): internal/newobj.h
+enc/emacs_mule.$(OBJEXT): internal/rgengc.h
enc/emacs_mule.$(OBJEXT): internal/scan_args.h
enc/emacs_mule.$(OBJEXT): internal/special_consts.h
enc/emacs_mule.$(OBJEXT): internal/static_assert.h
@@ -1053,7 +1062,6 @@ enc/encdb.$(OBJEXT): internal/attr/noexcept.h
enc/encdb.$(OBJEXT): internal/attr/noinline.h
enc/encdb.$(OBJEXT): internal/attr/nonnull.h
enc/encdb.$(OBJEXT): internal/attr/noreturn.h
-enc/encdb.$(OBJEXT): internal/attr/packed_struct.h
enc/encdb.$(OBJEXT): internal/attr/pure.h
enc/encdb.$(OBJEXT): internal/attr/restrict.h
enc/encdb.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -1122,6 +1130,7 @@ enc/encdb.$(OBJEXT): internal/intern/enumerator.h
enc/encdb.$(OBJEXT): internal/intern/error.h
enc/encdb.$(OBJEXT): internal/intern/eval.h
enc/encdb.$(OBJEXT): internal/intern/file.h
+enc/encdb.$(OBJEXT): internal/intern/gc.h
enc/encdb.$(OBJEXT): internal/intern/hash.h
enc/encdb.$(OBJEXT): internal/intern/io.h
enc/encdb.$(OBJEXT): internal/intern/load.h
@@ -1152,6 +1161,7 @@ enc/encdb.$(OBJEXT): internal/memory.h
enc/encdb.$(OBJEXT): internal/method.h
enc/encdb.$(OBJEXT): internal/module.h
enc/encdb.$(OBJEXT): internal/newobj.h
+enc/encdb.$(OBJEXT): internal/rgengc.h
enc/encdb.$(OBJEXT): internal/scan_args.h
enc/encdb.$(OBJEXT): internal/special_consts.h
enc/encdb.$(OBJEXT): internal/static_assert.h
@@ -1225,7 +1235,6 @@ enc/euc_jp.$(OBJEXT): internal/attr/noexcept.h
enc/euc_jp.$(OBJEXT): internal/attr/noinline.h
enc/euc_jp.$(OBJEXT): internal/attr/nonnull.h
enc/euc_jp.$(OBJEXT): internal/attr/noreturn.h
-enc/euc_jp.$(OBJEXT): internal/attr/packed_struct.h
enc/euc_jp.$(OBJEXT): internal/attr/pure.h
enc/euc_jp.$(OBJEXT): internal/attr/restrict.h
enc/euc_jp.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -1285,6 +1294,7 @@ enc/euc_jp.$(OBJEXT): internal/intern/enumerator.h
enc/euc_jp.$(OBJEXT): internal/intern/error.h
enc/euc_jp.$(OBJEXT): internal/intern/eval.h
enc/euc_jp.$(OBJEXT): internal/intern/file.h
+enc/euc_jp.$(OBJEXT): internal/intern/gc.h
enc/euc_jp.$(OBJEXT): internal/intern/hash.h
enc/euc_jp.$(OBJEXT): internal/intern/io.h
enc/euc_jp.$(OBJEXT): internal/intern/load.h
@@ -1315,6 +1325,7 @@ enc/euc_jp.$(OBJEXT): internal/memory.h
enc/euc_jp.$(OBJEXT): internal/method.h
enc/euc_jp.$(OBJEXT): internal/module.h
enc/euc_jp.$(OBJEXT): internal/newobj.h
+enc/euc_jp.$(OBJEXT): internal/rgengc.h
enc/euc_jp.$(OBJEXT): internal/scan_args.h
enc/euc_jp.$(OBJEXT): internal/special_consts.h
enc/euc_jp.$(OBJEXT): internal/static_assert.h
@@ -1385,7 +1396,6 @@ enc/euc_kr.$(OBJEXT): internal/attr/noexcept.h
enc/euc_kr.$(OBJEXT): internal/attr/noinline.h
enc/euc_kr.$(OBJEXT): internal/attr/nonnull.h
enc/euc_kr.$(OBJEXT): internal/attr/noreturn.h
-enc/euc_kr.$(OBJEXT): internal/attr/packed_struct.h
enc/euc_kr.$(OBJEXT): internal/attr/pure.h
enc/euc_kr.$(OBJEXT): internal/attr/restrict.h
enc/euc_kr.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -1445,6 +1455,7 @@ enc/euc_kr.$(OBJEXT): internal/intern/enumerator.h
enc/euc_kr.$(OBJEXT): internal/intern/error.h
enc/euc_kr.$(OBJEXT): internal/intern/eval.h
enc/euc_kr.$(OBJEXT): internal/intern/file.h
+enc/euc_kr.$(OBJEXT): internal/intern/gc.h
enc/euc_kr.$(OBJEXT): internal/intern/hash.h
enc/euc_kr.$(OBJEXT): internal/intern/io.h
enc/euc_kr.$(OBJEXT): internal/intern/load.h
@@ -1475,6 +1486,7 @@ enc/euc_kr.$(OBJEXT): internal/memory.h
enc/euc_kr.$(OBJEXT): internal/method.h
enc/euc_kr.$(OBJEXT): internal/module.h
enc/euc_kr.$(OBJEXT): internal/newobj.h
+enc/euc_kr.$(OBJEXT): internal/rgengc.h
enc/euc_kr.$(OBJEXT): internal/scan_args.h
enc/euc_kr.$(OBJEXT): internal/special_consts.h
enc/euc_kr.$(OBJEXT): internal/static_assert.h
@@ -1545,7 +1557,6 @@ enc/euc_tw.$(OBJEXT): internal/attr/noexcept.h
enc/euc_tw.$(OBJEXT): internal/attr/noinline.h
enc/euc_tw.$(OBJEXT): internal/attr/nonnull.h
enc/euc_tw.$(OBJEXT): internal/attr/noreturn.h
-enc/euc_tw.$(OBJEXT): internal/attr/packed_struct.h
enc/euc_tw.$(OBJEXT): internal/attr/pure.h
enc/euc_tw.$(OBJEXT): internal/attr/restrict.h
enc/euc_tw.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -1605,6 +1616,7 @@ enc/euc_tw.$(OBJEXT): internal/intern/enumerator.h
enc/euc_tw.$(OBJEXT): internal/intern/error.h
enc/euc_tw.$(OBJEXT): internal/intern/eval.h
enc/euc_tw.$(OBJEXT): internal/intern/file.h
+enc/euc_tw.$(OBJEXT): internal/intern/gc.h
enc/euc_tw.$(OBJEXT): internal/intern/hash.h
enc/euc_tw.$(OBJEXT): internal/intern/io.h
enc/euc_tw.$(OBJEXT): internal/intern/load.h
@@ -1635,6 +1647,7 @@ enc/euc_tw.$(OBJEXT): internal/memory.h
enc/euc_tw.$(OBJEXT): internal/method.h
enc/euc_tw.$(OBJEXT): internal/module.h
enc/euc_tw.$(OBJEXT): internal/newobj.h
+enc/euc_tw.$(OBJEXT): internal/rgengc.h
enc/euc_tw.$(OBJEXT): internal/scan_args.h
enc/euc_tw.$(OBJEXT): internal/special_consts.h
enc/euc_tw.$(OBJEXT): internal/static_assert.h
@@ -1705,7 +1718,6 @@ enc/gb18030.$(OBJEXT): internal/attr/noexcept.h
enc/gb18030.$(OBJEXT): internal/attr/noinline.h
enc/gb18030.$(OBJEXT): internal/attr/nonnull.h
enc/gb18030.$(OBJEXT): internal/attr/noreturn.h
-enc/gb18030.$(OBJEXT): internal/attr/packed_struct.h
enc/gb18030.$(OBJEXT): internal/attr/pure.h
enc/gb18030.$(OBJEXT): internal/attr/restrict.h
enc/gb18030.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -1765,6 +1777,7 @@ enc/gb18030.$(OBJEXT): internal/intern/enumerator.h
enc/gb18030.$(OBJEXT): internal/intern/error.h
enc/gb18030.$(OBJEXT): internal/intern/eval.h
enc/gb18030.$(OBJEXT): internal/intern/file.h
+enc/gb18030.$(OBJEXT): internal/intern/gc.h
enc/gb18030.$(OBJEXT): internal/intern/hash.h
enc/gb18030.$(OBJEXT): internal/intern/io.h
enc/gb18030.$(OBJEXT): internal/intern/load.h
@@ -1795,6 +1808,7 @@ enc/gb18030.$(OBJEXT): internal/memory.h
enc/gb18030.$(OBJEXT): internal/method.h
enc/gb18030.$(OBJEXT): internal/module.h
enc/gb18030.$(OBJEXT): internal/newobj.h
+enc/gb18030.$(OBJEXT): internal/rgengc.h
enc/gb18030.$(OBJEXT): internal/scan_args.h
enc/gb18030.$(OBJEXT): internal/special_consts.h
enc/gb18030.$(OBJEXT): internal/static_assert.h
@@ -1865,7 +1879,6 @@ enc/gb2312.$(OBJEXT): internal/attr/noexcept.h
enc/gb2312.$(OBJEXT): internal/attr/noinline.h
enc/gb2312.$(OBJEXT): internal/attr/nonnull.h
enc/gb2312.$(OBJEXT): internal/attr/noreturn.h
-enc/gb2312.$(OBJEXT): internal/attr/packed_struct.h
enc/gb2312.$(OBJEXT): internal/attr/pure.h
enc/gb2312.$(OBJEXT): internal/attr/restrict.h
enc/gb2312.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -1925,6 +1938,7 @@ enc/gb2312.$(OBJEXT): internal/intern/enumerator.h
enc/gb2312.$(OBJEXT): internal/intern/error.h
enc/gb2312.$(OBJEXT): internal/intern/eval.h
enc/gb2312.$(OBJEXT): internal/intern/file.h
+enc/gb2312.$(OBJEXT): internal/intern/gc.h
enc/gb2312.$(OBJEXT): internal/intern/hash.h
enc/gb2312.$(OBJEXT): internal/intern/io.h
enc/gb2312.$(OBJEXT): internal/intern/load.h
@@ -1955,6 +1969,7 @@ enc/gb2312.$(OBJEXT): internal/memory.h
enc/gb2312.$(OBJEXT): internal/method.h
enc/gb2312.$(OBJEXT): internal/module.h
enc/gb2312.$(OBJEXT): internal/newobj.h
+enc/gb2312.$(OBJEXT): internal/rgengc.h
enc/gb2312.$(OBJEXT): internal/scan_args.h
enc/gb2312.$(OBJEXT): internal/special_consts.h
enc/gb2312.$(OBJEXT): internal/static_assert.h
@@ -2025,7 +2040,6 @@ enc/gbk.$(OBJEXT): internal/attr/noexcept.h
enc/gbk.$(OBJEXT): internal/attr/noinline.h
enc/gbk.$(OBJEXT): internal/attr/nonnull.h
enc/gbk.$(OBJEXT): internal/attr/noreturn.h
-enc/gbk.$(OBJEXT): internal/attr/packed_struct.h
enc/gbk.$(OBJEXT): internal/attr/pure.h
enc/gbk.$(OBJEXT): internal/attr/restrict.h
enc/gbk.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -2085,6 +2099,7 @@ enc/gbk.$(OBJEXT): internal/intern/enumerator.h
enc/gbk.$(OBJEXT): internal/intern/error.h
enc/gbk.$(OBJEXT): internal/intern/eval.h
enc/gbk.$(OBJEXT): internal/intern/file.h
+enc/gbk.$(OBJEXT): internal/intern/gc.h
enc/gbk.$(OBJEXT): internal/intern/hash.h
enc/gbk.$(OBJEXT): internal/intern/io.h
enc/gbk.$(OBJEXT): internal/intern/load.h
@@ -2115,6 +2130,7 @@ enc/gbk.$(OBJEXT): internal/memory.h
enc/gbk.$(OBJEXT): internal/method.h
enc/gbk.$(OBJEXT): internal/module.h
enc/gbk.$(OBJEXT): internal/newobj.h
+enc/gbk.$(OBJEXT): internal/rgengc.h
enc/gbk.$(OBJEXT): internal/scan_args.h
enc/gbk.$(OBJEXT): internal/special_consts.h
enc/gbk.$(OBJEXT): internal/static_assert.h
@@ -2186,7 +2202,6 @@ enc/iso_8859_1.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_1.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_1.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_1.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_1.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_1.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_1.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_1.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -2246,6 +2261,7 @@ enc/iso_8859_1.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_1.$(OBJEXT): internal/intern/error.h
enc/iso_8859_1.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_1.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_1.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_1.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_1.$(OBJEXT): internal/intern/io.h
enc/iso_8859_1.$(OBJEXT): internal/intern/load.h
@@ -2276,6 +2292,7 @@ enc/iso_8859_1.$(OBJEXT): internal/memory.h
enc/iso_8859_1.$(OBJEXT): internal/method.h
enc/iso_8859_1.$(OBJEXT): internal/module.h
enc/iso_8859_1.$(OBJEXT): internal/newobj.h
+enc/iso_8859_1.$(OBJEXT): internal/rgengc.h
enc/iso_8859_1.$(OBJEXT): internal/scan_args.h
enc/iso_8859_1.$(OBJEXT): internal/special_consts.h
enc/iso_8859_1.$(OBJEXT): internal/static_assert.h
@@ -2347,7 +2364,6 @@ enc/iso_8859_10.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_10.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_10.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_10.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_10.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_10.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_10.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_10.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -2407,6 +2423,7 @@ enc/iso_8859_10.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_10.$(OBJEXT): internal/intern/error.h
enc/iso_8859_10.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_10.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_10.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_10.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_10.$(OBJEXT): internal/intern/io.h
enc/iso_8859_10.$(OBJEXT): internal/intern/load.h
@@ -2437,6 +2454,7 @@ enc/iso_8859_10.$(OBJEXT): internal/memory.h
enc/iso_8859_10.$(OBJEXT): internal/method.h
enc/iso_8859_10.$(OBJEXT): internal/module.h
enc/iso_8859_10.$(OBJEXT): internal/newobj.h
+enc/iso_8859_10.$(OBJEXT): internal/rgengc.h
enc/iso_8859_10.$(OBJEXT): internal/scan_args.h
enc/iso_8859_10.$(OBJEXT): internal/special_consts.h
enc/iso_8859_10.$(OBJEXT): internal/static_assert.h
@@ -2507,7 +2525,6 @@ enc/iso_8859_11.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_11.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_11.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_11.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_11.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_11.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_11.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_11.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -2567,6 +2584,7 @@ enc/iso_8859_11.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_11.$(OBJEXT): internal/intern/error.h
enc/iso_8859_11.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_11.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_11.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_11.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_11.$(OBJEXT): internal/intern/io.h
enc/iso_8859_11.$(OBJEXT): internal/intern/load.h
@@ -2597,6 +2615,7 @@ enc/iso_8859_11.$(OBJEXT): internal/memory.h
enc/iso_8859_11.$(OBJEXT): internal/method.h
enc/iso_8859_11.$(OBJEXT): internal/module.h
enc/iso_8859_11.$(OBJEXT): internal/newobj.h
+enc/iso_8859_11.$(OBJEXT): internal/rgengc.h
enc/iso_8859_11.$(OBJEXT): internal/scan_args.h
enc/iso_8859_11.$(OBJEXT): internal/special_consts.h
enc/iso_8859_11.$(OBJEXT): internal/static_assert.h
@@ -2668,7 +2687,6 @@ enc/iso_8859_13.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_13.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_13.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_13.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_13.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_13.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_13.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_13.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -2728,6 +2746,7 @@ enc/iso_8859_13.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_13.$(OBJEXT): internal/intern/error.h
enc/iso_8859_13.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_13.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_13.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_13.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_13.$(OBJEXT): internal/intern/io.h
enc/iso_8859_13.$(OBJEXT): internal/intern/load.h
@@ -2758,6 +2777,7 @@ enc/iso_8859_13.$(OBJEXT): internal/memory.h
enc/iso_8859_13.$(OBJEXT): internal/method.h
enc/iso_8859_13.$(OBJEXT): internal/module.h
enc/iso_8859_13.$(OBJEXT): internal/newobj.h
+enc/iso_8859_13.$(OBJEXT): internal/rgengc.h
enc/iso_8859_13.$(OBJEXT): internal/scan_args.h
enc/iso_8859_13.$(OBJEXT): internal/special_consts.h
enc/iso_8859_13.$(OBJEXT): internal/static_assert.h
@@ -2829,7 +2849,6 @@ enc/iso_8859_14.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_14.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_14.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_14.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_14.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_14.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_14.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_14.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -2889,6 +2908,7 @@ enc/iso_8859_14.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_14.$(OBJEXT): internal/intern/error.h
enc/iso_8859_14.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_14.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_14.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_14.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_14.$(OBJEXT): internal/intern/io.h
enc/iso_8859_14.$(OBJEXT): internal/intern/load.h
@@ -2919,6 +2939,7 @@ enc/iso_8859_14.$(OBJEXT): internal/memory.h
enc/iso_8859_14.$(OBJEXT): internal/method.h
enc/iso_8859_14.$(OBJEXT): internal/module.h
enc/iso_8859_14.$(OBJEXT): internal/newobj.h
+enc/iso_8859_14.$(OBJEXT): internal/rgengc.h
enc/iso_8859_14.$(OBJEXT): internal/scan_args.h
enc/iso_8859_14.$(OBJEXT): internal/special_consts.h
enc/iso_8859_14.$(OBJEXT): internal/static_assert.h
@@ -2990,7 +3011,6 @@ enc/iso_8859_15.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_15.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_15.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_15.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_15.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_15.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_15.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_15.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -3050,6 +3070,7 @@ enc/iso_8859_15.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_15.$(OBJEXT): internal/intern/error.h
enc/iso_8859_15.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_15.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_15.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_15.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_15.$(OBJEXT): internal/intern/io.h
enc/iso_8859_15.$(OBJEXT): internal/intern/load.h
@@ -3080,6 +3101,7 @@ enc/iso_8859_15.$(OBJEXT): internal/memory.h
enc/iso_8859_15.$(OBJEXT): internal/method.h
enc/iso_8859_15.$(OBJEXT): internal/module.h
enc/iso_8859_15.$(OBJEXT): internal/newobj.h
+enc/iso_8859_15.$(OBJEXT): internal/rgengc.h
enc/iso_8859_15.$(OBJEXT): internal/scan_args.h
enc/iso_8859_15.$(OBJEXT): internal/special_consts.h
enc/iso_8859_15.$(OBJEXT): internal/static_assert.h
@@ -3151,7 +3173,6 @@ enc/iso_8859_16.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_16.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_16.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_16.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_16.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_16.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_16.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_16.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -3211,6 +3232,7 @@ enc/iso_8859_16.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_16.$(OBJEXT): internal/intern/error.h
enc/iso_8859_16.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_16.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_16.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_16.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_16.$(OBJEXT): internal/intern/io.h
enc/iso_8859_16.$(OBJEXT): internal/intern/load.h
@@ -3241,6 +3263,7 @@ enc/iso_8859_16.$(OBJEXT): internal/memory.h
enc/iso_8859_16.$(OBJEXT): internal/method.h
enc/iso_8859_16.$(OBJEXT): internal/module.h
enc/iso_8859_16.$(OBJEXT): internal/newobj.h
+enc/iso_8859_16.$(OBJEXT): internal/rgengc.h
enc/iso_8859_16.$(OBJEXT): internal/scan_args.h
enc/iso_8859_16.$(OBJEXT): internal/special_consts.h
enc/iso_8859_16.$(OBJEXT): internal/static_assert.h
@@ -3312,7 +3335,6 @@ enc/iso_8859_2.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_2.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_2.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_2.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_2.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_2.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_2.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_2.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -3372,6 +3394,7 @@ enc/iso_8859_2.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_2.$(OBJEXT): internal/intern/error.h
enc/iso_8859_2.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_2.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_2.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_2.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_2.$(OBJEXT): internal/intern/io.h
enc/iso_8859_2.$(OBJEXT): internal/intern/load.h
@@ -3402,6 +3425,7 @@ enc/iso_8859_2.$(OBJEXT): internal/memory.h
enc/iso_8859_2.$(OBJEXT): internal/method.h
enc/iso_8859_2.$(OBJEXT): internal/module.h
enc/iso_8859_2.$(OBJEXT): internal/newobj.h
+enc/iso_8859_2.$(OBJEXT): internal/rgengc.h
enc/iso_8859_2.$(OBJEXT): internal/scan_args.h
enc/iso_8859_2.$(OBJEXT): internal/special_consts.h
enc/iso_8859_2.$(OBJEXT): internal/static_assert.h
@@ -3473,7 +3497,6 @@ enc/iso_8859_3.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_3.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_3.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_3.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_3.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_3.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_3.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_3.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -3533,6 +3556,7 @@ enc/iso_8859_3.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_3.$(OBJEXT): internal/intern/error.h
enc/iso_8859_3.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_3.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_3.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_3.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_3.$(OBJEXT): internal/intern/io.h
enc/iso_8859_3.$(OBJEXT): internal/intern/load.h
@@ -3563,6 +3587,7 @@ enc/iso_8859_3.$(OBJEXT): internal/memory.h
enc/iso_8859_3.$(OBJEXT): internal/method.h
enc/iso_8859_3.$(OBJEXT): internal/module.h
enc/iso_8859_3.$(OBJEXT): internal/newobj.h
+enc/iso_8859_3.$(OBJEXT): internal/rgengc.h
enc/iso_8859_3.$(OBJEXT): internal/scan_args.h
enc/iso_8859_3.$(OBJEXT): internal/special_consts.h
enc/iso_8859_3.$(OBJEXT): internal/static_assert.h
@@ -3634,7 +3659,6 @@ enc/iso_8859_4.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_4.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_4.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_4.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_4.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_4.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_4.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_4.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -3694,6 +3718,7 @@ enc/iso_8859_4.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_4.$(OBJEXT): internal/intern/error.h
enc/iso_8859_4.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_4.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_4.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_4.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_4.$(OBJEXT): internal/intern/io.h
enc/iso_8859_4.$(OBJEXT): internal/intern/load.h
@@ -3724,6 +3749,7 @@ enc/iso_8859_4.$(OBJEXT): internal/memory.h
enc/iso_8859_4.$(OBJEXT): internal/method.h
enc/iso_8859_4.$(OBJEXT): internal/module.h
enc/iso_8859_4.$(OBJEXT): internal/newobj.h
+enc/iso_8859_4.$(OBJEXT): internal/rgengc.h
enc/iso_8859_4.$(OBJEXT): internal/scan_args.h
enc/iso_8859_4.$(OBJEXT): internal/special_consts.h
enc/iso_8859_4.$(OBJEXT): internal/static_assert.h
@@ -3794,7 +3820,6 @@ enc/iso_8859_5.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_5.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_5.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_5.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_5.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_5.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_5.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_5.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -3854,6 +3879,7 @@ enc/iso_8859_5.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_5.$(OBJEXT): internal/intern/error.h
enc/iso_8859_5.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_5.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_5.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_5.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_5.$(OBJEXT): internal/intern/io.h
enc/iso_8859_5.$(OBJEXT): internal/intern/load.h
@@ -3884,6 +3910,7 @@ enc/iso_8859_5.$(OBJEXT): internal/memory.h
enc/iso_8859_5.$(OBJEXT): internal/method.h
enc/iso_8859_5.$(OBJEXT): internal/module.h
enc/iso_8859_5.$(OBJEXT): internal/newobj.h
+enc/iso_8859_5.$(OBJEXT): internal/rgengc.h
enc/iso_8859_5.$(OBJEXT): internal/scan_args.h
enc/iso_8859_5.$(OBJEXT): internal/special_consts.h
enc/iso_8859_5.$(OBJEXT): internal/static_assert.h
@@ -3954,7 +3981,6 @@ enc/iso_8859_6.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_6.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_6.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_6.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_6.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_6.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_6.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_6.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4014,6 +4040,7 @@ enc/iso_8859_6.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_6.$(OBJEXT): internal/intern/error.h
enc/iso_8859_6.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_6.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_6.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_6.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_6.$(OBJEXT): internal/intern/io.h
enc/iso_8859_6.$(OBJEXT): internal/intern/load.h
@@ -4044,6 +4071,7 @@ enc/iso_8859_6.$(OBJEXT): internal/memory.h
enc/iso_8859_6.$(OBJEXT): internal/method.h
enc/iso_8859_6.$(OBJEXT): internal/module.h
enc/iso_8859_6.$(OBJEXT): internal/newobj.h
+enc/iso_8859_6.$(OBJEXT): internal/rgengc.h
enc/iso_8859_6.$(OBJEXT): internal/scan_args.h
enc/iso_8859_6.$(OBJEXT): internal/special_consts.h
enc/iso_8859_6.$(OBJEXT): internal/static_assert.h
@@ -4114,7 +4142,6 @@ enc/iso_8859_7.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_7.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_7.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_7.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_7.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_7.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_7.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_7.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4174,6 +4201,7 @@ enc/iso_8859_7.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_7.$(OBJEXT): internal/intern/error.h
enc/iso_8859_7.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_7.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_7.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_7.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_7.$(OBJEXT): internal/intern/io.h
enc/iso_8859_7.$(OBJEXT): internal/intern/load.h
@@ -4204,6 +4232,7 @@ enc/iso_8859_7.$(OBJEXT): internal/memory.h
enc/iso_8859_7.$(OBJEXT): internal/method.h
enc/iso_8859_7.$(OBJEXT): internal/module.h
enc/iso_8859_7.$(OBJEXT): internal/newobj.h
+enc/iso_8859_7.$(OBJEXT): internal/rgengc.h
enc/iso_8859_7.$(OBJEXT): internal/scan_args.h
enc/iso_8859_7.$(OBJEXT): internal/special_consts.h
enc/iso_8859_7.$(OBJEXT): internal/static_assert.h
@@ -4274,7 +4303,6 @@ enc/iso_8859_8.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_8.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_8.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_8.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_8.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_8.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_8.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_8.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4334,6 +4362,7 @@ enc/iso_8859_8.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_8.$(OBJEXT): internal/intern/error.h
enc/iso_8859_8.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_8.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_8.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_8.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_8.$(OBJEXT): internal/intern/io.h
enc/iso_8859_8.$(OBJEXT): internal/intern/load.h
@@ -4364,6 +4393,7 @@ enc/iso_8859_8.$(OBJEXT): internal/memory.h
enc/iso_8859_8.$(OBJEXT): internal/method.h
enc/iso_8859_8.$(OBJEXT): internal/module.h
enc/iso_8859_8.$(OBJEXT): internal/newobj.h
+enc/iso_8859_8.$(OBJEXT): internal/rgengc.h
enc/iso_8859_8.$(OBJEXT): internal/scan_args.h
enc/iso_8859_8.$(OBJEXT): internal/special_consts.h
enc/iso_8859_8.$(OBJEXT): internal/static_assert.h
@@ -4435,7 +4465,6 @@ enc/iso_8859_9.$(OBJEXT): internal/attr/noexcept.h
enc/iso_8859_9.$(OBJEXT): internal/attr/noinline.h
enc/iso_8859_9.$(OBJEXT): internal/attr/nonnull.h
enc/iso_8859_9.$(OBJEXT): internal/attr/noreturn.h
-enc/iso_8859_9.$(OBJEXT): internal/attr/packed_struct.h
enc/iso_8859_9.$(OBJEXT): internal/attr/pure.h
enc/iso_8859_9.$(OBJEXT): internal/attr/restrict.h
enc/iso_8859_9.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4495,6 +4524,7 @@ enc/iso_8859_9.$(OBJEXT): internal/intern/enumerator.h
enc/iso_8859_9.$(OBJEXT): internal/intern/error.h
enc/iso_8859_9.$(OBJEXT): internal/intern/eval.h
enc/iso_8859_9.$(OBJEXT): internal/intern/file.h
+enc/iso_8859_9.$(OBJEXT): internal/intern/gc.h
enc/iso_8859_9.$(OBJEXT): internal/intern/hash.h
enc/iso_8859_9.$(OBJEXT): internal/intern/io.h
enc/iso_8859_9.$(OBJEXT): internal/intern/load.h
@@ -4525,6 +4555,7 @@ enc/iso_8859_9.$(OBJEXT): internal/memory.h
enc/iso_8859_9.$(OBJEXT): internal/method.h
enc/iso_8859_9.$(OBJEXT): internal/module.h
enc/iso_8859_9.$(OBJEXT): internal/newobj.h
+enc/iso_8859_9.$(OBJEXT): internal/rgengc.h
enc/iso_8859_9.$(OBJEXT): internal/scan_args.h
enc/iso_8859_9.$(OBJEXT): internal/special_consts.h
enc/iso_8859_9.$(OBJEXT): internal/static_assert.h
@@ -4595,7 +4626,6 @@ enc/koi8_r.$(OBJEXT): internal/attr/noexcept.h
enc/koi8_r.$(OBJEXT): internal/attr/noinline.h
enc/koi8_r.$(OBJEXT): internal/attr/nonnull.h
enc/koi8_r.$(OBJEXT): internal/attr/noreturn.h
-enc/koi8_r.$(OBJEXT): internal/attr/packed_struct.h
enc/koi8_r.$(OBJEXT): internal/attr/pure.h
enc/koi8_r.$(OBJEXT): internal/attr/restrict.h
enc/koi8_r.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4655,6 +4685,7 @@ enc/koi8_r.$(OBJEXT): internal/intern/enumerator.h
enc/koi8_r.$(OBJEXT): internal/intern/error.h
enc/koi8_r.$(OBJEXT): internal/intern/eval.h
enc/koi8_r.$(OBJEXT): internal/intern/file.h
+enc/koi8_r.$(OBJEXT): internal/intern/gc.h
enc/koi8_r.$(OBJEXT): internal/intern/hash.h
enc/koi8_r.$(OBJEXT): internal/intern/io.h
enc/koi8_r.$(OBJEXT): internal/intern/load.h
@@ -4685,6 +4716,7 @@ enc/koi8_r.$(OBJEXT): internal/memory.h
enc/koi8_r.$(OBJEXT): internal/method.h
enc/koi8_r.$(OBJEXT): internal/module.h
enc/koi8_r.$(OBJEXT): internal/newobj.h
+enc/koi8_r.$(OBJEXT): internal/rgengc.h
enc/koi8_r.$(OBJEXT): internal/scan_args.h
enc/koi8_r.$(OBJEXT): internal/special_consts.h
enc/koi8_r.$(OBJEXT): internal/static_assert.h
@@ -4755,7 +4787,6 @@ enc/koi8_u.$(OBJEXT): internal/attr/noexcept.h
enc/koi8_u.$(OBJEXT): internal/attr/noinline.h
enc/koi8_u.$(OBJEXT): internal/attr/nonnull.h
enc/koi8_u.$(OBJEXT): internal/attr/noreturn.h
-enc/koi8_u.$(OBJEXT): internal/attr/packed_struct.h
enc/koi8_u.$(OBJEXT): internal/attr/pure.h
enc/koi8_u.$(OBJEXT): internal/attr/restrict.h
enc/koi8_u.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4815,6 +4846,7 @@ enc/koi8_u.$(OBJEXT): internal/intern/enumerator.h
enc/koi8_u.$(OBJEXT): internal/intern/error.h
enc/koi8_u.$(OBJEXT): internal/intern/eval.h
enc/koi8_u.$(OBJEXT): internal/intern/file.h
+enc/koi8_u.$(OBJEXT): internal/intern/gc.h
enc/koi8_u.$(OBJEXT): internal/intern/hash.h
enc/koi8_u.$(OBJEXT): internal/intern/io.h
enc/koi8_u.$(OBJEXT): internal/intern/load.h
@@ -4845,6 +4877,7 @@ enc/koi8_u.$(OBJEXT): internal/memory.h
enc/koi8_u.$(OBJEXT): internal/method.h
enc/koi8_u.$(OBJEXT): internal/module.h
enc/koi8_u.$(OBJEXT): internal/newobj.h
+enc/koi8_u.$(OBJEXT): internal/rgengc.h
enc/koi8_u.$(OBJEXT): internal/scan_args.h
enc/koi8_u.$(OBJEXT): internal/special_consts.h
enc/koi8_u.$(OBJEXT): internal/static_assert.h
@@ -4918,7 +4951,6 @@ enc/shift_jis.$(OBJEXT): internal/attr/noexcept.h
enc/shift_jis.$(OBJEXT): internal/attr/noinline.h
enc/shift_jis.$(OBJEXT): internal/attr/nonnull.h
enc/shift_jis.$(OBJEXT): internal/attr/noreturn.h
-enc/shift_jis.$(OBJEXT): internal/attr/packed_struct.h
enc/shift_jis.$(OBJEXT): internal/attr/pure.h
enc/shift_jis.$(OBJEXT): internal/attr/restrict.h
enc/shift_jis.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -4978,6 +5010,7 @@ enc/shift_jis.$(OBJEXT): internal/intern/enumerator.h
enc/shift_jis.$(OBJEXT): internal/intern/error.h
enc/shift_jis.$(OBJEXT): internal/intern/eval.h
enc/shift_jis.$(OBJEXT): internal/intern/file.h
+enc/shift_jis.$(OBJEXT): internal/intern/gc.h
enc/shift_jis.$(OBJEXT): internal/intern/hash.h
enc/shift_jis.$(OBJEXT): internal/intern/io.h
enc/shift_jis.$(OBJEXT): internal/intern/load.h
@@ -5008,6 +5041,7 @@ enc/shift_jis.$(OBJEXT): internal/memory.h
enc/shift_jis.$(OBJEXT): internal/method.h
enc/shift_jis.$(OBJEXT): internal/module.h
enc/shift_jis.$(OBJEXT): internal/newobj.h
+enc/shift_jis.$(OBJEXT): internal/rgengc.h
enc/shift_jis.$(OBJEXT): internal/scan_args.h
enc/shift_jis.$(OBJEXT): internal/special_consts.h
enc/shift_jis.$(OBJEXT): internal/static_assert.h
@@ -5077,7 +5111,6 @@ enc/trans/big5.$(OBJEXT): internal/attr/noexcept.h
enc/trans/big5.$(OBJEXT): internal/attr/noinline.h
enc/trans/big5.$(OBJEXT): internal/attr/nonnull.h
enc/trans/big5.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/big5.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/big5.$(OBJEXT): internal/attr/pure.h
enc/trans/big5.$(OBJEXT): internal/attr/restrict.h
enc/trans/big5.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -5137,6 +5170,7 @@ enc/trans/big5.$(OBJEXT): internal/intern/enumerator.h
enc/trans/big5.$(OBJEXT): internal/intern/error.h
enc/trans/big5.$(OBJEXT): internal/intern/eval.h
enc/trans/big5.$(OBJEXT): internal/intern/file.h
+enc/trans/big5.$(OBJEXT): internal/intern/gc.h
enc/trans/big5.$(OBJEXT): internal/intern/hash.h
enc/trans/big5.$(OBJEXT): internal/intern/io.h
enc/trans/big5.$(OBJEXT): internal/intern/load.h
@@ -5167,6 +5201,7 @@ enc/trans/big5.$(OBJEXT): internal/memory.h
enc/trans/big5.$(OBJEXT): internal/method.h
enc/trans/big5.$(OBJEXT): internal/module.h
enc/trans/big5.$(OBJEXT): internal/newobj.h
+enc/trans/big5.$(OBJEXT): internal/rgengc.h
enc/trans/big5.$(OBJEXT): internal/scan_args.h
enc/trans/big5.$(OBJEXT): internal/special_consts.h
enc/trans/big5.$(OBJEXT): internal/static_assert.h
@@ -5235,7 +5270,6 @@ enc/trans/cesu_8.$(OBJEXT): internal/attr/noexcept.h
enc/trans/cesu_8.$(OBJEXT): internal/attr/noinline.h
enc/trans/cesu_8.$(OBJEXT): internal/attr/nonnull.h
enc/trans/cesu_8.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/cesu_8.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/cesu_8.$(OBJEXT): internal/attr/pure.h
enc/trans/cesu_8.$(OBJEXT): internal/attr/restrict.h
enc/trans/cesu_8.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -5295,6 +5329,7 @@ enc/trans/cesu_8.$(OBJEXT): internal/intern/enumerator.h
enc/trans/cesu_8.$(OBJEXT): internal/intern/error.h
enc/trans/cesu_8.$(OBJEXT): internal/intern/eval.h
enc/trans/cesu_8.$(OBJEXT): internal/intern/file.h
+enc/trans/cesu_8.$(OBJEXT): internal/intern/gc.h
enc/trans/cesu_8.$(OBJEXT): internal/intern/hash.h
enc/trans/cesu_8.$(OBJEXT): internal/intern/io.h
enc/trans/cesu_8.$(OBJEXT): internal/intern/load.h
@@ -5325,6 +5360,7 @@ enc/trans/cesu_8.$(OBJEXT): internal/memory.h
enc/trans/cesu_8.$(OBJEXT): internal/method.h
enc/trans/cesu_8.$(OBJEXT): internal/module.h
enc/trans/cesu_8.$(OBJEXT): internal/newobj.h
+enc/trans/cesu_8.$(OBJEXT): internal/rgengc.h
enc/trans/cesu_8.$(OBJEXT): internal/scan_args.h
enc/trans/cesu_8.$(OBJEXT): internal/special_consts.h
enc/trans/cesu_8.$(OBJEXT): internal/static_assert.h
@@ -5393,7 +5429,6 @@ enc/trans/chinese.$(OBJEXT): internal/attr/noexcept.h
enc/trans/chinese.$(OBJEXT): internal/attr/noinline.h
enc/trans/chinese.$(OBJEXT): internal/attr/nonnull.h
enc/trans/chinese.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/chinese.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/chinese.$(OBJEXT): internal/attr/pure.h
enc/trans/chinese.$(OBJEXT): internal/attr/restrict.h
enc/trans/chinese.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -5453,6 +5488,7 @@ enc/trans/chinese.$(OBJEXT): internal/intern/enumerator.h
enc/trans/chinese.$(OBJEXT): internal/intern/error.h
enc/trans/chinese.$(OBJEXT): internal/intern/eval.h
enc/trans/chinese.$(OBJEXT): internal/intern/file.h
+enc/trans/chinese.$(OBJEXT): internal/intern/gc.h
enc/trans/chinese.$(OBJEXT): internal/intern/hash.h
enc/trans/chinese.$(OBJEXT): internal/intern/io.h
enc/trans/chinese.$(OBJEXT): internal/intern/load.h
@@ -5483,6 +5519,7 @@ enc/trans/chinese.$(OBJEXT): internal/memory.h
enc/trans/chinese.$(OBJEXT): internal/method.h
enc/trans/chinese.$(OBJEXT): internal/module.h
enc/trans/chinese.$(OBJEXT): internal/newobj.h
+enc/trans/chinese.$(OBJEXT): internal/rgengc.h
enc/trans/chinese.$(OBJEXT): internal/scan_args.h
enc/trans/chinese.$(OBJEXT): internal/special_consts.h
enc/trans/chinese.$(OBJEXT): internal/static_assert.h
@@ -5551,7 +5588,6 @@ enc/trans/ebcdic.$(OBJEXT): internal/attr/noexcept.h
enc/trans/ebcdic.$(OBJEXT): internal/attr/noinline.h
enc/trans/ebcdic.$(OBJEXT): internal/attr/nonnull.h
enc/trans/ebcdic.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/ebcdic.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/ebcdic.$(OBJEXT): internal/attr/pure.h
enc/trans/ebcdic.$(OBJEXT): internal/attr/restrict.h
enc/trans/ebcdic.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -5611,6 +5647,7 @@ enc/trans/ebcdic.$(OBJEXT): internal/intern/enumerator.h
enc/trans/ebcdic.$(OBJEXT): internal/intern/error.h
enc/trans/ebcdic.$(OBJEXT): internal/intern/eval.h
enc/trans/ebcdic.$(OBJEXT): internal/intern/file.h
+enc/trans/ebcdic.$(OBJEXT): internal/intern/gc.h
enc/trans/ebcdic.$(OBJEXT): internal/intern/hash.h
enc/trans/ebcdic.$(OBJEXT): internal/intern/io.h
enc/trans/ebcdic.$(OBJEXT): internal/intern/load.h
@@ -5641,6 +5678,7 @@ enc/trans/ebcdic.$(OBJEXT): internal/memory.h
enc/trans/ebcdic.$(OBJEXT): internal/method.h
enc/trans/ebcdic.$(OBJEXT): internal/module.h
enc/trans/ebcdic.$(OBJEXT): internal/newobj.h
+enc/trans/ebcdic.$(OBJEXT): internal/rgengc.h
enc/trans/ebcdic.$(OBJEXT): internal/scan_args.h
enc/trans/ebcdic.$(OBJEXT): internal/special_consts.h
enc/trans/ebcdic.$(OBJEXT): internal/static_assert.h
@@ -5709,7 +5747,6 @@ enc/trans/emoji.$(OBJEXT): internal/attr/noexcept.h
enc/trans/emoji.$(OBJEXT): internal/attr/noinline.h
enc/trans/emoji.$(OBJEXT): internal/attr/nonnull.h
enc/trans/emoji.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/emoji.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/emoji.$(OBJEXT): internal/attr/pure.h
enc/trans/emoji.$(OBJEXT): internal/attr/restrict.h
enc/trans/emoji.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -5769,6 +5806,7 @@ enc/trans/emoji.$(OBJEXT): internal/intern/enumerator.h
enc/trans/emoji.$(OBJEXT): internal/intern/error.h
enc/trans/emoji.$(OBJEXT): internal/intern/eval.h
enc/trans/emoji.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji.$(OBJEXT): internal/intern/gc.h
enc/trans/emoji.$(OBJEXT): internal/intern/hash.h
enc/trans/emoji.$(OBJEXT): internal/intern/io.h
enc/trans/emoji.$(OBJEXT): internal/intern/load.h
@@ -5799,6 +5837,7 @@ enc/trans/emoji.$(OBJEXT): internal/memory.h
enc/trans/emoji.$(OBJEXT): internal/method.h
enc/trans/emoji.$(OBJEXT): internal/module.h
enc/trans/emoji.$(OBJEXT): internal/newobj.h
+enc/trans/emoji.$(OBJEXT): internal/rgengc.h
enc/trans/emoji.$(OBJEXT): internal/scan_args.h
enc/trans/emoji.$(OBJEXT): internal/special_consts.h
enc/trans/emoji.$(OBJEXT): internal/static_assert.h
@@ -5867,7 +5906,6 @@ enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noexcept.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noinline.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/nonnull.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/pure.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/restrict.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -5927,6 +5965,7 @@ enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/enumerator.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/error.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/eval.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/gc.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/hash.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/io.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/intern/load.h
@@ -5957,6 +5996,7 @@ enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/memory.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/method.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/module.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/rgengc.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/scan_args.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/special_consts.h
enc/trans/emoji_iso2022_kddi.$(OBJEXT): internal/static_assert.h
@@ -6025,7 +6065,6 @@ enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noexcept.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noinline.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/nonnull.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/pure.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/restrict.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -6085,6 +6124,7 @@ enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/enumerator.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/error.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/eval.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/gc.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/hash.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/io.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/intern/load.h
@@ -6115,6 +6155,7 @@ enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/memory.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/method.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/module.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/rgengc.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/scan_args.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/special_consts.h
enc/trans/emoji_sjis_docomo.$(OBJEXT): internal/static_assert.h
@@ -6183,7 +6224,6 @@ enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noexcept.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noinline.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/nonnull.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/pure.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/restrict.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -6243,6 +6283,7 @@ enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/enumerator.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/error.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/eval.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/gc.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/hash.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/io.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/intern/load.h
@@ -6273,6 +6314,7 @@ enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/memory.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/method.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/module.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/rgengc.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/scan_args.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/special_consts.h
enc/trans/emoji_sjis_kddi.$(OBJEXT): internal/static_assert.h
@@ -6341,7 +6383,6 @@ enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noexcept.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noinline.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/nonnull.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/pure.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/restrict.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -6401,6 +6442,7 @@ enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/enumerator.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/error.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/eval.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/file.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/gc.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/hash.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/io.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/intern/load.h
@@ -6431,6 +6473,7 @@ enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/memory.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/method.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/module.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/newobj.h
+enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/rgengc.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/scan_args.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/special_consts.h
enc/trans/emoji_sjis_softbank.$(OBJEXT): internal/static_assert.h
@@ -6499,7 +6542,6 @@ enc/trans/escape.$(OBJEXT): internal/attr/noexcept.h
enc/trans/escape.$(OBJEXT): internal/attr/noinline.h
enc/trans/escape.$(OBJEXT): internal/attr/nonnull.h
enc/trans/escape.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/escape.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/escape.$(OBJEXT): internal/attr/pure.h
enc/trans/escape.$(OBJEXT): internal/attr/restrict.h
enc/trans/escape.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -6559,6 +6601,7 @@ enc/trans/escape.$(OBJEXT): internal/intern/enumerator.h
enc/trans/escape.$(OBJEXT): internal/intern/error.h
enc/trans/escape.$(OBJEXT): internal/intern/eval.h
enc/trans/escape.$(OBJEXT): internal/intern/file.h
+enc/trans/escape.$(OBJEXT): internal/intern/gc.h
enc/trans/escape.$(OBJEXT): internal/intern/hash.h
enc/trans/escape.$(OBJEXT): internal/intern/io.h
enc/trans/escape.$(OBJEXT): internal/intern/load.h
@@ -6589,6 +6632,7 @@ enc/trans/escape.$(OBJEXT): internal/memory.h
enc/trans/escape.$(OBJEXT): internal/method.h
enc/trans/escape.$(OBJEXT): internal/module.h
enc/trans/escape.$(OBJEXT): internal/newobj.h
+enc/trans/escape.$(OBJEXT): internal/rgengc.h
enc/trans/escape.$(OBJEXT): internal/scan_args.h
enc/trans/escape.$(OBJEXT): internal/special_consts.h
enc/trans/escape.$(OBJEXT): internal/static_assert.h
@@ -6657,7 +6701,6 @@ enc/trans/gb18030.$(OBJEXT): internal/attr/noexcept.h
enc/trans/gb18030.$(OBJEXT): internal/attr/noinline.h
enc/trans/gb18030.$(OBJEXT): internal/attr/nonnull.h
enc/trans/gb18030.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/gb18030.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/gb18030.$(OBJEXT): internal/attr/pure.h
enc/trans/gb18030.$(OBJEXT): internal/attr/restrict.h
enc/trans/gb18030.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -6717,6 +6760,7 @@ enc/trans/gb18030.$(OBJEXT): internal/intern/enumerator.h
enc/trans/gb18030.$(OBJEXT): internal/intern/error.h
enc/trans/gb18030.$(OBJEXT): internal/intern/eval.h
enc/trans/gb18030.$(OBJEXT): internal/intern/file.h
+enc/trans/gb18030.$(OBJEXT): internal/intern/gc.h
enc/trans/gb18030.$(OBJEXT): internal/intern/hash.h
enc/trans/gb18030.$(OBJEXT): internal/intern/io.h
enc/trans/gb18030.$(OBJEXT): internal/intern/load.h
@@ -6747,6 +6791,7 @@ enc/trans/gb18030.$(OBJEXT): internal/memory.h
enc/trans/gb18030.$(OBJEXT): internal/method.h
enc/trans/gb18030.$(OBJEXT): internal/module.h
enc/trans/gb18030.$(OBJEXT): internal/newobj.h
+enc/trans/gb18030.$(OBJEXT): internal/rgengc.h
enc/trans/gb18030.$(OBJEXT): internal/scan_args.h
enc/trans/gb18030.$(OBJEXT): internal/special_consts.h
enc/trans/gb18030.$(OBJEXT): internal/static_assert.h
@@ -6815,7 +6860,6 @@ enc/trans/gbk.$(OBJEXT): internal/attr/noexcept.h
enc/trans/gbk.$(OBJEXT): internal/attr/noinline.h
enc/trans/gbk.$(OBJEXT): internal/attr/nonnull.h
enc/trans/gbk.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/gbk.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/gbk.$(OBJEXT): internal/attr/pure.h
enc/trans/gbk.$(OBJEXT): internal/attr/restrict.h
enc/trans/gbk.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -6875,6 +6919,7 @@ enc/trans/gbk.$(OBJEXT): internal/intern/enumerator.h
enc/trans/gbk.$(OBJEXT): internal/intern/error.h
enc/trans/gbk.$(OBJEXT): internal/intern/eval.h
enc/trans/gbk.$(OBJEXT): internal/intern/file.h
+enc/trans/gbk.$(OBJEXT): internal/intern/gc.h
enc/trans/gbk.$(OBJEXT): internal/intern/hash.h
enc/trans/gbk.$(OBJEXT): internal/intern/io.h
enc/trans/gbk.$(OBJEXT): internal/intern/load.h
@@ -6905,6 +6950,7 @@ enc/trans/gbk.$(OBJEXT): internal/memory.h
enc/trans/gbk.$(OBJEXT): internal/method.h
enc/trans/gbk.$(OBJEXT): internal/module.h
enc/trans/gbk.$(OBJEXT): internal/newobj.h
+enc/trans/gbk.$(OBJEXT): internal/rgengc.h
enc/trans/gbk.$(OBJEXT): internal/scan_args.h
enc/trans/gbk.$(OBJEXT): internal/special_consts.h
enc/trans/gbk.$(OBJEXT): internal/static_assert.h
@@ -6972,8 +7018,8 @@ enc/trans/iso2022.$(OBJEXT): internal/attr/nodiscard.h
enc/trans/iso2022.$(OBJEXT): internal/attr/noexcept.h
enc/trans/iso2022.$(OBJEXT): internal/attr/noinline.h
enc/trans/iso2022.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/nonstring.h
enc/trans/iso2022.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/iso2022.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/iso2022.$(OBJEXT): internal/attr/pure.h
enc/trans/iso2022.$(OBJEXT): internal/attr/restrict.h
enc/trans/iso2022.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7033,6 +7079,7 @@ enc/trans/iso2022.$(OBJEXT): internal/intern/enumerator.h
enc/trans/iso2022.$(OBJEXT): internal/intern/error.h
enc/trans/iso2022.$(OBJEXT): internal/intern/eval.h
enc/trans/iso2022.$(OBJEXT): internal/intern/file.h
+enc/trans/iso2022.$(OBJEXT): internal/intern/gc.h
enc/trans/iso2022.$(OBJEXT): internal/intern/hash.h
enc/trans/iso2022.$(OBJEXT): internal/intern/io.h
enc/trans/iso2022.$(OBJEXT): internal/intern/load.h
@@ -7063,6 +7110,7 @@ enc/trans/iso2022.$(OBJEXT): internal/memory.h
enc/trans/iso2022.$(OBJEXT): internal/method.h
enc/trans/iso2022.$(OBJEXT): internal/module.h
enc/trans/iso2022.$(OBJEXT): internal/newobj.h
+enc/trans/iso2022.$(OBJEXT): internal/rgengc.h
enc/trans/iso2022.$(OBJEXT): internal/scan_args.h
enc/trans/iso2022.$(OBJEXT): internal/special_consts.h
enc/trans/iso2022.$(OBJEXT): internal/static_assert.h
@@ -7131,7 +7179,6 @@ enc/trans/japanese.$(OBJEXT): internal/attr/noexcept.h
enc/trans/japanese.$(OBJEXT): internal/attr/noinline.h
enc/trans/japanese.$(OBJEXT): internal/attr/nonnull.h
enc/trans/japanese.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/japanese.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/japanese.$(OBJEXT): internal/attr/pure.h
enc/trans/japanese.$(OBJEXT): internal/attr/restrict.h
enc/trans/japanese.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7191,6 +7238,7 @@ enc/trans/japanese.$(OBJEXT): internal/intern/enumerator.h
enc/trans/japanese.$(OBJEXT): internal/intern/error.h
enc/trans/japanese.$(OBJEXT): internal/intern/eval.h
enc/trans/japanese.$(OBJEXT): internal/intern/file.h
+enc/trans/japanese.$(OBJEXT): internal/intern/gc.h
enc/trans/japanese.$(OBJEXT): internal/intern/hash.h
enc/trans/japanese.$(OBJEXT): internal/intern/io.h
enc/trans/japanese.$(OBJEXT): internal/intern/load.h
@@ -7221,6 +7269,7 @@ enc/trans/japanese.$(OBJEXT): internal/memory.h
enc/trans/japanese.$(OBJEXT): internal/method.h
enc/trans/japanese.$(OBJEXT): internal/module.h
enc/trans/japanese.$(OBJEXT): internal/newobj.h
+enc/trans/japanese.$(OBJEXT): internal/rgengc.h
enc/trans/japanese.$(OBJEXT): internal/scan_args.h
enc/trans/japanese.$(OBJEXT): internal/special_consts.h
enc/trans/japanese.$(OBJEXT): internal/static_assert.h
@@ -7289,7 +7338,6 @@ enc/trans/japanese_euc.$(OBJEXT): internal/attr/noexcept.h
enc/trans/japanese_euc.$(OBJEXT): internal/attr/noinline.h
enc/trans/japanese_euc.$(OBJEXT): internal/attr/nonnull.h
enc/trans/japanese_euc.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/japanese_euc.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/japanese_euc.$(OBJEXT): internal/attr/pure.h
enc/trans/japanese_euc.$(OBJEXT): internal/attr/restrict.h
enc/trans/japanese_euc.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7349,6 +7397,7 @@ enc/trans/japanese_euc.$(OBJEXT): internal/intern/enumerator.h
enc/trans/japanese_euc.$(OBJEXT): internal/intern/error.h
enc/trans/japanese_euc.$(OBJEXT): internal/intern/eval.h
enc/trans/japanese_euc.$(OBJEXT): internal/intern/file.h
+enc/trans/japanese_euc.$(OBJEXT): internal/intern/gc.h
enc/trans/japanese_euc.$(OBJEXT): internal/intern/hash.h
enc/trans/japanese_euc.$(OBJEXT): internal/intern/io.h
enc/trans/japanese_euc.$(OBJEXT): internal/intern/load.h
@@ -7379,6 +7428,7 @@ enc/trans/japanese_euc.$(OBJEXT): internal/memory.h
enc/trans/japanese_euc.$(OBJEXT): internal/method.h
enc/trans/japanese_euc.$(OBJEXT): internal/module.h
enc/trans/japanese_euc.$(OBJEXT): internal/newobj.h
+enc/trans/japanese_euc.$(OBJEXT): internal/rgengc.h
enc/trans/japanese_euc.$(OBJEXT): internal/scan_args.h
enc/trans/japanese_euc.$(OBJEXT): internal/special_consts.h
enc/trans/japanese_euc.$(OBJEXT): internal/static_assert.h
@@ -7447,7 +7497,6 @@ enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noexcept.h
enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noinline.h
enc/trans/japanese_sjis.$(OBJEXT): internal/attr/nonnull.h
enc/trans/japanese_sjis.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/japanese_sjis.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/japanese_sjis.$(OBJEXT): internal/attr/pure.h
enc/trans/japanese_sjis.$(OBJEXT): internal/attr/restrict.h
enc/trans/japanese_sjis.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7507,6 +7556,7 @@ enc/trans/japanese_sjis.$(OBJEXT): internal/intern/enumerator.h
enc/trans/japanese_sjis.$(OBJEXT): internal/intern/error.h
enc/trans/japanese_sjis.$(OBJEXT): internal/intern/eval.h
enc/trans/japanese_sjis.$(OBJEXT): internal/intern/file.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/intern/gc.h
enc/trans/japanese_sjis.$(OBJEXT): internal/intern/hash.h
enc/trans/japanese_sjis.$(OBJEXT): internal/intern/io.h
enc/trans/japanese_sjis.$(OBJEXT): internal/intern/load.h
@@ -7537,6 +7587,7 @@ enc/trans/japanese_sjis.$(OBJEXT): internal/memory.h
enc/trans/japanese_sjis.$(OBJEXT): internal/method.h
enc/trans/japanese_sjis.$(OBJEXT): internal/module.h
enc/trans/japanese_sjis.$(OBJEXT): internal/newobj.h
+enc/trans/japanese_sjis.$(OBJEXT): internal/rgengc.h
enc/trans/japanese_sjis.$(OBJEXT): internal/scan_args.h
enc/trans/japanese_sjis.$(OBJEXT): internal/special_consts.h
enc/trans/japanese_sjis.$(OBJEXT): internal/static_assert.h
@@ -7605,7 +7656,6 @@ enc/trans/korean.$(OBJEXT): internal/attr/noexcept.h
enc/trans/korean.$(OBJEXT): internal/attr/noinline.h
enc/trans/korean.$(OBJEXT): internal/attr/nonnull.h
enc/trans/korean.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/korean.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/korean.$(OBJEXT): internal/attr/pure.h
enc/trans/korean.$(OBJEXT): internal/attr/restrict.h
enc/trans/korean.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7665,6 +7715,7 @@ enc/trans/korean.$(OBJEXT): internal/intern/enumerator.h
enc/trans/korean.$(OBJEXT): internal/intern/error.h
enc/trans/korean.$(OBJEXT): internal/intern/eval.h
enc/trans/korean.$(OBJEXT): internal/intern/file.h
+enc/trans/korean.$(OBJEXT): internal/intern/gc.h
enc/trans/korean.$(OBJEXT): internal/intern/hash.h
enc/trans/korean.$(OBJEXT): internal/intern/io.h
enc/trans/korean.$(OBJEXT): internal/intern/load.h
@@ -7695,6 +7746,7 @@ enc/trans/korean.$(OBJEXT): internal/memory.h
enc/trans/korean.$(OBJEXT): internal/method.h
enc/trans/korean.$(OBJEXT): internal/module.h
enc/trans/korean.$(OBJEXT): internal/newobj.h
+enc/trans/korean.$(OBJEXT): internal/rgengc.h
enc/trans/korean.$(OBJEXT): internal/scan_args.h
enc/trans/korean.$(OBJEXT): internal/special_consts.h
enc/trans/korean.$(OBJEXT): internal/static_assert.h
@@ -7762,7 +7814,6 @@ enc/trans/newline.$(OBJEXT): internal/attr/noexcept.h
enc/trans/newline.$(OBJEXT): internal/attr/noinline.h
enc/trans/newline.$(OBJEXT): internal/attr/nonnull.h
enc/trans/newline.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/newline.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/newline.$(OBJEXT): internal/attr/pure.h
enc/trans/newline.$(OBJEXT): internal/attr/restrict.h
enc/trans/newline.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7822,6 +7873,7 @@ enc/trans/newline.$(OBJEXT): internal/intern/enumerator.h
enc/trans/newline.$(OBJEXT): internal/intern/error.h
enc/trans/newline.$(OBJEXT): internal/intern/eval.h
enc/trans/newline.$(OBJEXT): internal/intern/file.h
+enc/trans/newline.$(OBJEXT): internal/intern/gc.h
enc/trans/newline.$(OBJEXT): internal/intern/hash.h
enc/trans/newline.$(OBJEXT): internal/intern/io.h
enc/trans/newline.$(OBJEXT): internal/intern/load.h
@@ -7852,6 +7904,7 @@ enc/trans/newline.$(OBJEXT): internal/memory.h
enc/trans/newline.$(OBJEXT): internal/method.h
enc/trans/newline.$(OBJEXT): internal/module.h
enc/trans/newline.$(OBJEXT): internal/newobj.h
+enc/trans/newline.$(OBJEXT): internal/rgengc.h
enc/trans/newline.$(OBJEXT): internal/scan_args.h
enc/trans/newline.$(OBJEXT): internal/special_consts.h
enc/trans/newline.$(OBJEXT): internal/static_assert.h
@@ -7920,7 +7973,6 @@ enc/trans/single_byte.$(OBJEXT): internal/attr/noexcept.h
enc/trans/single_byte.$(OBJEXT): internal/attr/noinline.h
enc/trans/single_byte.$(OBJEXT): internal/attr/nonnull.h
enc/trans/single_byte.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/single_byte.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/single_byte.$(OBJEXT): internal/attr/pure.h
enc/trans/single_byte.$(OBJEXT): internal/attr/restrict.h
enc/trans/single_byte.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -7980,6 +8032,7 @@ enc/trans/single_byte.$(OBJEXT): internal/intern/enumerator.h
enc/trans/single_byte.$(OBJEXT): internal/intern/error.h
enc/trans/single_byte.$(OBJEXT): internal/intern/eval.h
enc/trans/single_byte.$(OBJEXT): internal/intern/file.h
+enc/trans/single_byte.$(OBJEXT): internal/intern/gc.h
enc/trans/single_byte.$(OBJEXT): internal/intern/hash.h
enc/trans/single_byte.$(OBJEXT): internal/intern/io.h
enc/trans/single_byte.$(OBJEXT): internal/intern/load.h
@@ -8010,6 +8063,7 @@ enc/trans/single_byte.$(OBJEXT): internal/memory.h
enc/trans/single_byte.$(OBJEXT): internal/method.h
enc/trans/single_byte.$(OBJEXT): internal/module.h
enc/trans/single_byte.$(OBJEXT): internal/newobj.h
+enc/trans/single_byte.$(OBJEXT): internal/rgengc.h
enc/trans/single_byte.$(OBJEXT): internal/scan_args.h
enc/trans/single_byte.$(OBJEXT): internal/special_consts.h
enc/trans/single_byte.$(OBJEXT): internal/static_assert.h
@@ -8078,7 +8132,6 @@ enc/trans/transdb.$(OBJEXT): internal/attr/noexcept.h
enc/trans/transdb.$(OBJEXT): internal/attr/noinline.h
enc/trans/transdb.$(OBJEXT): internal/attr/nonnull.h
enc/trans/transdb.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/transdb.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/transdb.$(OBJEXT): internal/attr/pure.h
enc/trans/transdb.$(OBJEXT): internal/attr/restrict.h
enc/trans/transdb.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -8138,6 +8191,7 @@ enc/trans/transdb.$(OBJEXT): internal/intern/enumerator.h
enc/trans/transdb.$(OBJEXT): internal/intern/error.h
enc/trans/transdb.$(OBJEXT): internal/intern/eval.h
enc/trans/transdb.$(OBJEXT): internal/intern/file.h
+enc/trans/transdb.$(OBJEXT): internal/intern/gc.h
enc/trans/transdb.$(OBJEXT): internal/intern/hash.h
enc/trans/transdb.$(OBJEXT): internal/intern/io.h
enc/trans/transdb.$(OBJEXT): internal/intern/load.h
@@ -8168,6 +8222,7 @@ enc/trans/transdb.$(OBJEXT): internal/memory.h
enc/trans/transdb.$(OBJEXT): internal/method.h
enc/trans/transdb.$(OBJEXT): internal/module.h
enc/trans/transdb.$(OBJEXT): internal/newobj.h
+enc/trans/transdb.$(OBJEXT): internal/rgengc.h
enc/trans/transdb.$(OBJEXT): internal/scan_args.h
enc/trans/transdb.$(OBJEXT): internal/special_consts.h
enc/trans/transdb.$(OBJEXT): internal/static_assert.h
@@ -8237,7 +8292,6 @@ enc/trans/utf8_mac.$(OBJEXT): internal/attr/noexcept.h
enc/trans/utf8_mac.$(OBJEXT): internal/attr/noinline.h
enc/trans/utf8_mac.$(OBJEXT): internal/attr/nonnull.h
enc/trans/utf8_mac.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/utf8_mac.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/utf8_mac.$(OBJEXT): internal/attr/pure.h
enc/trans/utf8_mac.$(OBJEXT): internal/attr/restrict.h
enc/trans/utf8_mac.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -8297,6 +8351,7 @@ enc/trans/utf8_mac.$(OBJEXT): internal/intern/enumerator.h
enc/trans/utf8_mac.$(OBJEXT): internal/intern/error.h
enc/trans/utf8_mac.$(OBJEXT): internal/intern/eval.h
enc/trans/utf8_mac.$(OBJEXT): internal/intern/file.h
+enc/trans/utf8_mac.$(OBJEXT): internal/intern/gc.h
enc/trans/utf8_mac.$(OBJEXT): internal/intern/hash.h
enc/trans/utf8_mac.$(OBJEXT): internal/intern/io.h
enc/trans/utf8_mac.$(OBJEXT): internal/intern/load.h
@@ -8327,6 +8382,7 @@ enc/trans/utf8_mac.$(OBJEXT): internal/memory.h
enc/trans/utf8_mac.$(OBJEXT): internal/method.h
enc/trans/utf8_mac.$(OBJEXT): internal/module.h
enc/trans/utf8_mac.$(OBJEXT): internal/newobj.h
+enc/trans/utf8_mac.$(OBJEXT): internal/rgengc.h
enc/trans/utf8_mac.$(OBJEXT): internal/scan_args.h
enc/trans/utf8_mac.$(OBJEXT): internal/special_consts.h
enc/trans/utf8_mac.$(OBJEXT): internal/static_assert.h
@@ -8395,7 +8451,6 @@ enc/trans/utf_16_32.$(OBJEXT): internal/attr/noexcept.h
enc/trans/utf_16_32.$(OBJEXT): internal/attr/noinline.h
enc/trans/utf_16_32.$(OBJEXT): internal/attr/nonnull.h
enc/trans/utf_16_32.$(OBJEXT): internal/attr/noreturn.h
-enc/trans/utf_16_32.$(OBJEXT): internal/attr/packed_struct.h
enc/trans/utf_16_32.$(OBJEXT): internal/attr/pure.h
enc/trans/utf_16_32.$(OBJEXT): internal/attr/restrict.h
enc/trans/utf_16_32.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -8455,6 +8510,7 @@ enc/trans/utf_16_32.$(OBJEXT): internal/intern/enumerator.h
enc/trans/utf_16_32.$(OBJEXT): internal/intern/error.h
enc/trans/utf_16_32.$(OBJEXT): internal/intern/eval.h
enc/trans/utf_16_32.$(OBJEXT): internal/intern/file.h
+enc/trans/utf_16_32.$(OBJEXT): internal/intern/gc.h
enc/trans/utf_16_32.$(OBJEXT): internal/intern/hash.h
enc/trans/utf_16_32.$(OBJEXT): internal/intern/io.h
enc/trans/utf_16_32.$(OBJEXT): internal/intern/load.h
@@ -8485,6 +8541,7 @@ enc/trans/utf_16_32.$(OBJEXT): internal/memory.h
enc/trans/utf_16_32.$(OBJEXT): internal/method.h
enc/trans/utf_16_32.$(OBJEXT): internal/module.h
enc/trans/utf_16_32.$(OBJEXT): internal/newobj.h
+enc/trans/utf_16_32.$(OBJEXT): internal/rgengc.h
enc/trans/utf_16_32.$(OBJEXT): internal/scan_args.h
enc/trans/utf_16_32.$(OBJEXT): internal/special_consts.h
enc/trans/utf_16_32.$(OBJEXT): internal/static_assert.h
@@ -8556,7 +8613,6 @@ enc/unicode.$(OBJEXT): internal/attr/noexcept.h
enc/unicode.$(OBJEXT): internal/attr/noinline.h
enc/unicode.$(OBJEXT): internal/attr/nonnull.h
enc/unicode.$(OBJEXT): internal/attr/noreturn.h
-enc/unicode.$(OBJEXT): internal/attr/packed_struct.h
enc/unicode.$(OBJEXT): internal/attr/pure.h
enc/unicode.$(OBJEXT): internal/attr/restrict.h
enc/unicode.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -8616,6 +8672,7 @@ enc/unicode.$(OBJEXT): internal/intern/enumerator.h
enc/unicode.$(OBJEXT): internal/intern/error.h
enc/unicode.$(OBJEXT): internal/intern/eval.h
enc/unicode.$(OBJEXT): internal/intern/file.h
+enc/unicode.$(OBJEXT): internal/intern/gc.h
enc/unicode.$(OBJEXT): internal/intern/hash.h
enc/unicode.$(OBJEXT): internal/intern/io.h
enc/unicode.$(OBJEXT): internal/intern/load.h
@@ -8646,6 +8703,7 @@ enc/unicode.$(OBJEXT): internal/memory.h
enc/unicode.$(OBJEXT): internal/method.h
enc/unicode.$(OBJEXT): internal/module.h
enc/unicode.$(OBJEXT): internal/newobj.h
+enc/unicode.$(OBJEXT): internal/rgengc.h
enc/unicode.$(OBJEXT): internal/scan_args.h
enc/unicode.$(OBJEXT): internal/special_consts.h
enc/unicode.$(OBJEXT): internal/static_assert.h
@@ -8717,7 +8775,6 @@ enc/us_ascii.$(OBJEXT): internal/attr/noexcept.h
enc/us_ascii.$(OBJEXT): internal/attr/noinline.h
enc/us_ascii.$(OBJEXT): internal/attr/nonnull.h
enc/us_ascii.$(OBJEXT): internal/attr/noreturn.h
-enc/us_ascii.$(OBJEXT): internal/attr/packed_struct.h
enc/us_ascii.$(OBJEXT): internal/attr/pure.h
enc/us_ascii.$(OBJEXT): internal/attr/restrict.h
enc/us_ascii.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -8786,6 +8843,7 @@ enc/us_ascii.$(OBJEXT): internal/intern/enumerator.h
enc/us_ascii.$(OBJEXT): internal/intern/error.h
enc/us_ascii.$(OBJEXT): internal/intern/eval.h
enc/us_ascii.$(OBJEXT): internal/intern/file.h
+enc/us_ascii.$(OBJEXT): internal/intern/gc.h
enc/us_ascii.$(OBJEXT): internal/intern/hash.h
enc/us_ascii.$(OBJEXT): internal/intern/io.h
enc/us_ascii.$(OBJEXT): internal/intern/load.h
@@ -8816,6 +8874,7 @@ enc/us_ascii.$(OBJEXT): internal/memory.h
enc/us_ascii.$(OBJEXT): internal/method.h
enc/us_ascii.$(OBJEXT): internal/module.h
enc/us_ascii.$(OBJEXT): internal/newobj.h
+enc/us_ascii.$(OBJEXT): internal/rgengc.h
enc/us_ascii.$(OBJEXT): internal/scan_args.h
enc/us_ascii.$(OBJEXT): internal/special_consts.h
enc/us_ascii.$(OBJEXT): internal/static_assert.h
@@ -8888,7 +8947,6 @@ enc/utf_16be.$(OBJEXT): internal/attr/noexcept.h
enc/utf_16be.$(OBJEXT): internal/attr/noinline.h
enc/utf_16be.$(OBJEXT): internal/attr/nonnull.h
enc/utf_16be.$(OBJEXT): internal/attr/noreturn.h
-enc/utf_16be.$(OBJEXT): internal/attr/packed_struct.h
enc/utf_16be.$(OBJEXT): internal/attr/pure.h
enc/utf_16be.$(OBJEXT): internal/attr/restrict.h
enc/utf_16be.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -8948,6 +9006,7 @@ enc/utf_16be.$(OBJEXT): internal/intern/enumerator.h
enc/utf_16be.$(OBJEXT): internal/intern/error.h
enc/utf_16be.$(OBJEXT): internal/intern/eval.h
enc/utf_16be.$(OBJEXT): internal/intern/file.h
+enc/utf_16be.$(OBJEXT): internal/intern/gc.h
enc/utf_16be.$(OBJEXT): internal/intern/hash.h
enc/utf_16be.$(OBJEXT): internal/intern/io.h
enc/utf_16be.$(OBJEXT): internal/intern/load.h
@@ -8978,6 +9037,7 @@ enc/utf_16be.$(OBJEXT): internal/memory.h
enc/utf_16be.$(OBJEXT): internal/method.h
enc/utf_16be.$(OBJEXT): internal/module.h
enc/utf_16be.$(OBJEXT): internal/newobj.h
+enc/utf_16be.$(OBJEXT): internal/rgengc.h
enc/utf_16be.$(OBJEXT): internal/scan_args.h
enc/utf_16be.$(OBJEXT): internal/special_consts.h
enc/utf_16be.$(OBJEXT): internal/static_assert.h
@@ -9049,7 +9109,6 @@ enc/utf_16le.$(OBJEXT): internal/attr/noexcept.h
enc/utf_16le.$(OBJEXT): internal/attr/noinline.h
enc/utf_16le.$(OBJEXT): internal/attr/nonnull.h
enc/utf_16le.$(OBJEXT): internal/attr/noreturn.h
-enc/utf_16le.$(OBJEXT): internal/attr/packed_struct.h
enc/utf_16le.$(OBJEXT): internal/attr/pure.h
enc/utf_16le.$(OBJEXT): internal/attr/restrict.h
enc/utf_16le.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -9109,6 +9168,7 @@ enc/utf_16le.$(OBJEXT): internal/intern/enumerator.h
enc/utf_16le.$(OBJEXT): internal/intern/error.h
enc/utf_16le.$(OBJEXT): internal/intern/eval.h
enc/utf_16le.$(OBJEXT): internal/intern/file.h
+enc/utf_16le.$(OBJEXT): internal/intern/gc.h
enc/utf_16le.$(OBJEXT): internal/intern/hash.h
enc/utf_16le.$(OBJEXT): internal/intern/io.h
enc/utf_16le.$(OBJEXT): internal/intern/load.h
@@ -9139,6 +9199,7 @@ enc/utf_16le.$(OBJEXT): internal/memory.h
enc/utf_16le.$(OBJEXT): internal/method.h
enc/utf_16le.$(OBJEXT): internal/module.h
enc/utf_16le.$(OBJEXT): internal/newobj.h
+enc/utf_16le.$(OBJEXT): internal/rgengc.h
enc/utf_16le.$(OBJEXT): internal/scan_args.h
enc/utf_16le.$(OBJEXT): internal/special_consts.h
enc/utf_16le.$(OBJEXT): internal/static_assert.h
@@ -9210,7 +9271,6 @@ enc/utf_32be.$(OBJEXT): internal/attr/noexcept.h
enc/utf_32be.$(OBJEXT): internal/attr/noinline.h
enc/utf_32be.$(OBJEXT): internal/attr/nonnull.h
enc/utf_32be.$(OBJEXT): internal/attr/noreturn.h
-enc/utf_32be.$(OBJEXT): internal/attr/packed_struct.h
enc/utf_32be.$(OBJEXT): internal/attr/pure.h
enc/utf_32be.$(OBJEXT): internal/attr/restrict.h
enc/utf_32be.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -9270,6 +9330,7 @@ enc/utf_32be.$(OBJEXT): internal/intern/enumerator.h
enc/utf_32be.$(OBJEXT): internal/intern/error.h
enc/utf_32be.$(OBJEXT): internal/intern/eval.h
enc/utf_32be.$(OBJEXT): internal/intern/file.h
+enc/utf_32be.$(OBJEXT): internal/intern/gc.h
enc/utf_32be.$(OBJEXT): internal/intern/hash.h
enc/utf_32be.$(OBJEXT): internal/intern/io.h
enc/utf_32be.$(OBJEXT): internal/intern/load.h
@@ -9300,6 +9361,7 @@ enc/utf_32be.$(OBJEXT): internal/memory.h
enc/utf_32be.$(OBJEXT): internal/method.h
enc/utf_32be.$(OBJEXT): internal/module.h
enc/utf_32be.$(OBJEXT): internal/newobj.h
+enc/utf_32be.$(OBJEXT): internal/rgengc.h
enc/utf_32be.$(OBJEXT): internal/scan_args.h
enc/utf_32be.$(OBJEXT): internal/special_consts.h
enc/utf_32be.$(OBJEXT): internal/static_assert.h
@@ -9371,7 +9433,6 @@ enc/utf_32le.$(OBJEXT): internal/attr/noexcept.h
enc/utf_32le.$(OBJEXT): internal/attr/noinline.h
enc/utf_32le.$(OBJEXT): internal/attr/nonnull.h
enc/utf_32le.$(OBJEXT): internal/attr/noreturn.h
-enc/utf_32le.$(OBJEXT): internal/attr/packed_struct.h
enc/utf_32le.$(OBJEXT): internal/attr/pure.h
enc/utf_32le.$(OBJEXT): internal/attr/restrict.h
enc/utf_32le.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -9431,6 +9492,7 @@ enc/utf_32le.$(OBJEXT): internal/intern/enumerator.h
enc/utf_32le.$(OBJEXT): internal/intern/error.h
enc/utf_32le.$(OBJEXT): internal/intern/eval.h
enc/utf_32le.$(OBJEXT): internal/intern/file.h
+enc/utf_32le.$(OBJEXT): internal/intern/gc.h
enc/utf_32le.$(OBJEXT): internal/intern/hash.h
enc/utf_32le.$(OBJEXT): internal/intern/io.h
enc/utf_32le.$(OBJEXT): internal/intern/load.h
@@ -9461,6 +9523,7 @@ enc/utf_32le.$(OBJEXT): internal/memory.h
enc/utf_32le.$(OBJEXT): internal/method.h
enc/utf_32le.$(OBJEXT): internal/module.h
enc/utf_32le.$(OBJEXT): internal/newobj.h
+enc/utf_32le.$(OBJEXT): internal/rgengc.h
enc/utf_32le.$(OBJEXT): internal/scan_args.h
enc/utf_32le.$(OBJEXT): internal/special_consts.h
enc/utf_32le.$(OBJEXT): internal/static_assert.h
@@ -9532,7 +9595,6 @@ enc/utf_8.$(OBJEXT): internal/attr/noexcept.h
enc/utf_8.$(OBJEXT): internal/attr/noinline.h
enc/utf_8.$(OBJEXT): internal/attr/nonnull.h
enc/utf_8.$(OBJEXT): internal/attr/noreturn.h
-enc/utf_8.$(OBJEXT): internal/attr/packed_struct.h
enc/utf_8.$(OBJEXT): internal/attr/pure.h
enc/utf_8.$(OBJEXT): internal/attr/restrict.h
enc/utf_8.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -9601,6 +9663,7 @@ enc/utf_8.$(OBJEXT): internal/intern/enumerator.h
enc/utf_8.$(OBJEXT): internal/intern/error.h
enc/utf_8.$(OBJEXT): internal/intern/eval.h
enc/utf_8.$(OBJEXT): internal/intern/file.h
+enc/utf_8.$(OBJEXT): internal/intern/gc.h
enc/utf_8.$(OBJEXT): internal/intern/hash.h
enc/utf_8.$(OBJEXT): internal/intern/io.h
enc/utf_8.$(OBJEXT): internal/intern/load.h
@@ -9631,6 +9694,7 @@ enc/utf_8.$(OBJEXT): internal/memory.h
enc/utf_8.$(OBJEXT): internal/method.h
enc/utf_8.$(OBJEXT): internal/module.h
enc/utf_8.$(OBJEXT): internal/newobj.h
+enc/utf_8.$(OBJEXT): internal/rgengc.h
enc/utf_8.$(OBJEXT): internal/scan_args.h
enc/utf_8.$(OBJEXT): internal/special_consts.h
enc/utf_8.$(OBJEXT): internal/static_assert.h
@@ -9703,7 +9767,6 @@ enc/windows_1250.$(OBJEXT): internal/attr/noexcept.h
enc/windows_1250.$(OBJEXT): internal/attr/noinline.h
enc/windows_1250.$(OBJEXT): internal/attr/nonnull.h
enc/windows_1250.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_1250.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_1250.$(OBJEXT): internal/attr/pure.h
enc/windows_1250.$(OBJEXT): internal/attr/restrict.h
enc/windows_1250.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -9763,6 +9826,7 @@ enc/windows_1250.$(OBJEXT): internal/intern/enumerator.h
enc/windows_1250.$(OBJEXT): internal/intern/error.h
enc/windows_1250.$(OBJEXT): internal/intern/eval.h
enc/windows_1250.$(OBJEXT): internal/intern/file.h
+enc/windows_1250.$(OBJEXT): internal/intern/gc.h
enc/windows_1250.$(OBJEXT): internal/intern/hash.h
enc/windows_1250.$(OBJEXT): internal/intern/io.h
enc/windows_1250.$(OBJEXT): internal/intern/load.h
@@ -9793,6 +9857,7 @@ enc/windows_1250.$(OBJEXT): internal/memory.h
enc/windows_1250.$(OBJEXT): internal/method.h
enc/windows_1250.$(OBJEXT): internal/module.h
enc/windows_1250.$(OBJEXT): internal/newobj.h
+enc/windows_1250.$(OBJEXT): internal/rgengc.h
enc/windows_1250.$(OBJEXT): internal/scan_args.h
enc/windows_1250.$(OBJEXT): internal/special_consts.h
enc/windows_1250.$(OBJEXT): internal/static_assert.h
@@ -9863,7 +9928,6 @@ enc/windows_1251.$(OBJEXT): internal/attr/noexcept.h
enc/windows_1251.$(OBJEXT): internal/attr/noinline.h
enc/windows_1251.$(OBJEXT): internal/attr/nonnull.h
enc/windows_1251.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_1251.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_1251.$(OBJEXT): internal/attr/pure.h
enc/windows_1251.$(OBJEXT): internal/attr/restrict.h
enc/windows_1251.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -9923,6 +9987,7 @@ enc/windows_1251.$(OBJEXT): internal/intern/enumerator.h
enc/windows_1251.$(OBJEXT): internal/intern/error.h
enc/windows_1251.$(OBJEXT): internal/intern/eval.h
enc/windows_1251.$(OBJEXT): internal/intern/file.h
+enc/windows_1251.$(OBJEXT): internal/intern/gc.h
enc/windows_1251.$(OBJEXT): internal/intern/hash.h
enc/windows_1251.$(OBJEXT): internal/intern/io.h
enc/windows_1251.$(OBJEXT): internal/intern/load.h
@@ -9953,6 +10018,7 @@ enc/windows_1251.$(OBJEXT): internal/memory.h
enc/windows_1251.$(OBJEXT): internal/method.h
enc/windows_1251.$(OBJEXT): internal/module.h
enc/windows_1251.$(OBJEXT): internal/newobj.h
+enc/windows_1251.$(OBJEXT): internal/rgengc.h
enc/windows_1251.$(OBJEXT): internal/scan_args.h
enc/windows_1251.$(OBJEXT): internal/special_consts.h
enc/windows_1251.$(OBJEXT): internal/static_assert.h
@@ -10024,7 +10090,6 @@ enc/windows_1252.$(OBJEXT): internal/attr/noexcept.h
enc/windows_1252.$(OBJEXT): internal/attr/noinline.h
enc/windows_1252.$(OBJEXT): internal/attr/nonnull.h
enc/windows_1252.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_1252.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_1252.$(OBJEXT): internal/attr/pure.h
enc/windows_1252.$(OBJEXT): internal/attr/restrict.h
enc/windows_1252.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -10084,6 +10149,7 @@ enc/windows_1252.$(OBJEXT): internal/intern/enumerator.h
enc/windows_1252.$(OBJEXT): internal/intern/error.h
enc/windows_1252.$(OBJEXT): internal/intern/eval.h
enc/windows_1252.$(OBJEXT): internal/intern/file.h
+enc/windows_1252.$(OBJEXT): internal/intern/gc.h
enc/windows_1252.$(OBJEXT): internal/intern/hash.h
enc/windows_1252.$(OBJEXT): internal/intern/io.h
enc/windows_1252.$(OBJEXT): internal/intern/load.h
@@ -10114,6 +10180,7 @@ enc/windows_1252.$(OBJEXT): internal/memory.h
enc/windows_1252.$(OBJEXT): internal/method.h
enc/windows_1252.$(OBJEXT): internal/module.h
enc/windows_1252.$(OBJEXT): internal/newobj.h
+enc/windows_1252.$(OBJEXT): internal/rgengc.h
enc/windows_1252.$(OBJEXT): internal/scan_args.h
enc/windows_1252.$(OBJEXT): internal/special_consts.h
enc/windows_1252.$(OBJEXT): internal/static_assert.h
@@ -10184,7 +10251,6 @@ enc/windows_1253.$(OBJEXT): internal/attr/noexcept.h
enc/windows_1253.$(OBJEXT): internal/attr/noinline.h
enc/windows_1253.$(OBJEXT): internal/attr/nonnull.h
enc/windows_1253.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_1253.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_1253.$(OBJEXT): internal/attr/pure.h
enc/windows_1253.$(OBJEXT): internal/attr/restrict.h
enc/windows_1253.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -10244,6 +10310,7 @@ enc/windows_1253.$(OBJEXT): internal/intern/enumerator.h
enc/windows_1253.$(OBJEXT): internal/intern/error.h
enc/windows_1253.$(OBJEXT): internal/intern/eval.h
enc/windows_1253.$(OBJEXT): internal/intern/file.h
+enc/windows_1253.$(OBJEXT): internal/intern/gc.h
enc/windows_1253.$(OBJEXT): internal/intern/hash.h
enc/windows_1253.$(OBJEXT): internal/intern/io.h
enc/windows_1253.$(OBJEXT): internal/intern/load.h
@@ -10274,6 +10341,7 @@ enc/windows_1253.$(OBJEXT): internal/memory.h
enc/windows_1253.$(OBJEXT): internal/method.h
enc/windows_1253.$(OBJEXT): internal/module.h
enc/windows_1253.$(OBJEXT): internal/newobj.h
+enc/windows_1253.$(OBJEXT): internal/rgengc.h
enc/windows_1253.$(OBJEXT): internal/scan_args.h
enc/windows_1253.$(OBJEXT): internal/special_consts.h
enc/windows_1253.$(OBJEXT): internal/static_assert.h
@@ -10345,7 +10413,6 @@ enc/windows_1254.$(OBJEXT): internal/attr/noexcept.h
enc/windows_1254.$(OBJEXT): internal/attr/noinline.h
enc/windows_1254.$(OBJEXT): internal/attr/nonnull.h
enc/windows_1254.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_1254.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_1254.$(OBJEXT): internal/attr/pure.h
enc/windows_1254.$(OBJEXT): internal/attr/restrict.h
enc/windows_1254.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -10405,6 +10472,7 @@ enc/windows_1254.$(OBJEXT): internal/intern/enumerator.h
enc/windows_1254.$(OBJEXT): internal/intern/error.h
enc/windows_1254.$(OBJEXT): internal/intern/eval.h
enc/windows_1254.$(OBJEXT): internal/intern/file.h
+enc/windows_1254.$(OBJEXT): internal/intern/gc.h
enc/windows_1254.$(OBJEXT): internal/intern/hash.h
enc/windows_1254.$(OBJEXT): internal/intern/io.h
enc/windows_1254.$(OBJEXT): internal/intern/load.h
@@ -10435,6 +10503,7 @@ enc/windows_1254.$(OBJEXT): internal/memory.h
enc/windows_1254.$(OBJEXT): internal/method.h
enc/windows_1254.$(OBJEXT): internal/module.h
enc/windows_1254.$(OBJEXT): internal/newobj.h
+enc/windows_1254.$(OBJEXT): internal/rgengc.h
enc/windows_1254.$(OBJEXT): internal/scan_args.h
enc/windows_1254.$(OBJEXT): internal/special_consts.h
enc/windows_1254.$(OBJEXT): internal/static_assert.h
@@ -10506,7 +10575,6 @@ enc/windows_1257.$(OBJEXT): internal/attr/noexcept.h
enc/windows_1257.$(OBJEXT): internal/attr/noinline.h
enc/windows_1257.$(OBJEXT): internal/attr/nonnull.h
enc/windows_1257.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_1257.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_1257.$(OBJEXT): internal/attr/pure.h
enc/windows_1257.$(OBJEXT): internal/attr/restrict.h
enc/windows_1257.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -10566,6 +10634,7 @@ enc/windows_1257.$(OBJEXT): internal/intern/enumerator.h
enc/windows_1257.$(OBJEXT): internal/intern/error.h
enc/windows_1257.$(OBJEXT): internal/intern/eval.h
enc/windows_1257.$(OBJEXT): internal/intern/file.h
+enc/windows_1257.$(OBJEXT): internal/intern/gc.h
enc/windows_1257.$(OBJEXT): internal/intern/hash.h
enc/windows_1257.$(OBJEXT): internal/intern/io.h
enc/windows_1257.$(OBJEXT): internal/intern/load.h
@@ -10596,6 +10665,7 @@ enc/windows_1257.$(OBJEXT): internal/memory.h
enc/windows_1257.$(OBJEXT): internal/method.h
enc/windows_1257.$(OBJEXT): internal/module.h
enc/windows_1257.$(OBJEXT): internal/newobj.h
+enc/windows_1257.$(OBJEXT): internal/rgengc.h
enc/windows_1257.$(OBJEXT): internal/scan_args.h
enc/windows_1257.$(OBJEXT): internal/special_consts.h
enc/windows_1257.$(OBJEXT): internal/static_assert.h
@@ -10669,7 +10739,6 @@ enc/windows_31j.$(OBJEXT): internal/attr/noexcept.h
enc/windows_31j.$(OBJEXT): internal/attr/noinline.h
enc/windows_31j.$(OBJEXT): internal/attr/nonnull.h
enc/windows_31j.$(OBJEXT): internal/attr/noreturn.h
-enc/windows_31j.$(OBJEXT): internal/attr/packed_struct.h
enc/windows_31j.$(OBJEXT): internal/attr/pure.h
enc/windows_31j.$(OBJEXT): internal/attr/restrict.h
enc/windows_31j.$(OBJEXT): internal/attr/returns_nonnull.h
@@ -10729,6 +10798,7 @@ enc/windows_31j.$(OBJEXT): internal/intern/enumerator.h
enc/windows_31j.$(OBJEXT): internal/intern/error.h
enc/windows_31j.$(OBJEXT): internal/intern/eval.h
enc/windows_31j.$(OBJEXT): internal/intern/file.h
+enc/windows_31j.$(OBJEXT): internal/intern/gc.h
enc/windows_31j.$(OBJEXT): internal/intern/hash.h
enc/windows_31j.$(OBJEXT): internal/intern/io.h
enc/windows_31j.$(OBJEXT): internal/intern/load.h
@@ -10759,6 +10829,7 @@ enc/windows_31j.$(OBJEXT): internal/memory.h
enc/windows_31j.$(OBJEXT): internal/method.h
enc/windows_31j.$(OBJEXT): internal/module.h
enc/windows_31j.$(OBJEXT): internal/newobj.h
+enc/windows_31j.$(OBJEXT): internal/rgengc.h
enc/windows_31j.$(OBJEXT): internal/scan_args.h
enc/windows_31j.$(OBJEXT): internal/special_consts.h
enc/windows_31j.$(OBJEXT): internal/static_assert.h
diff --git a/enc/trans/big5-uao-tbl.rb b/enc/trans/big5-uao-tbl.rb
index a6f37cc7bd..295fbfdda5 100644
--- a/enc/trans/big5-uao-tbl.rb
+++ b/enc/trans/big5-uao-tbl.rb
@@ -19781,4 +19781,4 @@ BIG5_UAO_TO_UCS_TBL = [
["FEFC",0x8262],
["FEFD",0x826A],
["FEFE",0x8288],
-]
+] \ No newline at end of file
diff --git a/enc/trans/cp850-tbl.rb b/enc/trans/cp850-tbl.rb
index e0d120c803..615d3b2599 100644
--- a/enc/trans/cp850-tbl.rb
+++ b/enc/trans/cp850-tbl.rb
@@ -127,4 +127,4 @@ CP850_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/cp852-tbl.rb b/enc/trans/cp852-tbl.rb
index ad32cdc59d..6763bfa6e9 100644
--- a/enc/trans/cp852-tbl.rb
+++ b/enc/trans/cp852-tbl.rb
@@ -127,4 +127,4 @@ CP852_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/cp855-tbl.rb b/enc/trans/cp855-tbl.rb
index a2ca9daf97..72e548b9cb 100644
--- a/enc/trans/cp855-tbl.rb
+++ b/enc/trans/cp855-tbl.rb
@@ -127,4 +127,4 @@ CP855_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/gbk-tbl.rb b/enc/trans/gbk-tbl.rb
index 40929f992e..26f5078c45 100644
--- a/enc/trans/gbk-tbl.rb
+++ b/enc/trans/gbk-tbl.rb
@@ -21791,4 +21791,4 @@ GBK_TO_UCS_TBL= [
["A3FE",0xFFE3],
["A957",0xFFE4],
["A3A4",0xFFE5],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm437-tbl.rb b/enc/trans/ibm437-tbl.rb
index 6a823c293d..5ae64d621e 100644
--- a/enc/trans/ibm437-tbl.rb
+++ b/enc/trans/ibm437-tbl.rb
@@ -127,4 +127,4 @@ IBM437_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm775-tbl.rb b/enc/trans/ibm775-tbl.rb
index 2b79780813..f55679f409 100644
--- a/enc/trans/ibm775-tbl.rb
+++ b/enc/trans/ibm775-tbl.rb
@@ -127,4 +127,4 @@ IBM775_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm852-tbl.rb b/enc/trans/ibm852-tbl.rb
index 3e70daef2e..6cec51cf80 100644
--- a/enc/trans/ibm852-tbl.rb
+++ b/enc/trans/ibm852-tbl.rb
@@ -127,4 +127,4 @@ IBM852_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm855-tbl.rb b/enc/trans/ibm855-tbl.rb
index b4c0244728..7e0cc5014f 100644
--- a/enc/trans/ibm855-tbl.rb
+++ b/enc/trans/ibm855-tbl.rb
@@ -127,4 +127,4 @@ IBM855_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm857-tbl.rb b/enc/trans/ibm857-tbl.rb
index c1c76545ed..5b20d389d3 100644
--- a/enc/trans/ibm857-tbl.rb
+++ b/enc/trans/ibm857-tbl.rb
@@ -124,4 +124,4 @@ IBM857_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm860-tbl.rb b/enc/trans/ibm860-tbl.rb
index 77734cd194..ae218a129f 100644
--- a/enc/trans/ibm860-tbl.rb
+++ b/enc/trans/ibm860-tbl.rb
@@ -127,4 +127,4 @@ IBM860_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm861-tbl.rb b/enc/trans/ibm861-tbl.rb
index 69e0a45019..c24042a76c 100644
--- a/enc/trans/ibm861-tbl.rb
+++ b/enc/trans/ibm861-tbl.rb
@@ -127,4 +127,4 @@ IBM861_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm862-tbl.rb b/enc/trans/ibm862-tbl.rb
index f564051fd6..31d6fb0243 100644
--- a/enc/trans/ibm862-tbl.rb
+++ b/enc/trans/ibm862-tbl.rb
@@ -127,4 +127,4 @@ IBM862_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm863-tbl.rb b/enc/trans/ibm863-tbl.rb
index af1eb97566..db110cf38c 100644
--- a/enc/trans/ibm863-tbl.rb
+++ b/enc/trans/ibm863-tbl.rb
@@ -127,4 +127,4 @@ IBM863_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm865-tbl.rb b/enc/trans/ibm865-tbl.rb
index 4747509d66..22e322fb31 100644
--- a/enc/trans/ibm865-tbl.rb
+++ b/enc/trans/ibm865-tbl.rb
@@ -127,4 +127,4 @@ IBM865_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm866-tbl.rb b/enc/trans/ibm866-tbl.rb
index ed4b0d683e..95b9ee7534 100644
--- a/enc/trans/ibm866-tbl.rb
+++ b/enc/trans/ibm866-tbl.rb
@@ -127,4 +127,4 @@ IBM866_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/ibm869-tbl.rb b/enc/trans/ibm869-tbl.rb
index bee85b84ea..437e41ad98 100644
--- a/enc/trans/ibm869-tbl.rb
+++ b/enc/trans/ibm869-tbl.rb
@@ -118,4 +118,4 @@ IBM869_TO_UCS_TBL = [
["B1",0x2592],
["B2",0x2593],
["FE",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/koi8-r-tbl.rb b/enc/trans/koi8-r-tbl.rb
index 4cfe523334..a1f55ff2e3 100644
--- a/enc/trans/koi8-r-tbl.rb
+++ b/enc/trans/koi8-r-tbl.rb
@@ -127,4 +127,4 @@ KOI8_R_TO_UCS_TBL = [
["91",0x2592],
["92",0x2593],
["94",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/koi8-u-tbl.rb b/enc/trans/koi8-u-tbl.rb
index 225931ba5e..e87aa1aa3f 100644
--- a/enc/trans/koi8-u-tbl.rb
+++ b/enc/trans/koi8-u-tbl.rb
@@ -127,4 +127,4 @@ KOI8_U_TO_UCS_TBL = [
["91",0x2592],
["92",0x2593],
["94",0x25A0],
-]
+] \ No newline at end of file
diff --git a/enc/trans/maccroatian-tbl.rb b/enc/trans/maccroatian-tbl.rb
index e78f2f373f..359878ec1f 100644
--- a/enc/trans/maccroatian-tbl.rb
+++ b/enc/trans/maccroatian-tbl.rb
@@ -126,4 +126,4 @@ MACCROATIAN_TO_UCS_TBL = [
["B2",0x2264],
["B3",0x2265],
["D7",0x25CA],
-]
+] \ No newline at end of file
diff --git a/enc/trans/maccyrillic-tbl.rb b/enc/trans/maccyrillic-tbl.rb
index 2d5af7b466..378aa8c3bc 100644
--- a/enc/trans/maccyrillic-tbl.rb
+++ b/enc/trans/maccyrillic-tbl.rb
@@ -127,4 +127,4 @@ MACCYRILLIC_TO_UCS_TBL = [
["AD",0x2260],
["B2",0x2264],
["B3",0x2265],
-]
+] \ No newline at end of file
diff --git a/enc/trans/macgreek-tbl.rb b/enc/trans/macgreek-tbl.rb
index 645aefe5ff..7f75fde6d2 100644
--- a/enc/trans/macgreek-tbl.rb
+++ b/enc/trans/macgreek-tbl.rb
@@ -126,4 +126,4 @@ MACGREEK_TO_UCS_TBL = [
["AD",0x2260],
["B2",0x2264],
["B3",0x2265],
-]
+] \ No newline at end of file
diff --git a/enc/trans/maciceland-tbl.rb b/enc/trans/maciceland-tbl.rb
index ee9b5000d9..818d992274 100644
--- a/enc/trans/maciceland-tbl.rb
+++ b/enc/trans/maciceland-tbl.rb
@@ -126,4 +126,4 @@ MACICELAND_TO_UCS_TBL = [
["B2",0x2264],
["B3",0x2265],
["D7",0x25CA],
-]
+] \ No newline at end of file
diff --git a/enc/trans/macroman-tbl.rb b/enc/trans/macroman-tbl.rb
index 9a8172554a..8f74eea27f 100644
--- a/enc/trans/macroman-tbl.rb
+++ b/enc/trans/macroman-tbl.rb
@@ -126,4 +126,4 @@ MACROMAN_TO_UCS_TBL = [
["D7",0x25CA],
["DE",0xFB01],
["DF",0xFB02],
-]
+] \ No newline at end of file
diff --git a/enc/trans/macromania-tbl.rb b/enc/trans/macromania-tbl.rb
index 29a7942d9b..ff95c5e957 100644
--- a/enc/trans/macromania-tbl.rb
+++ b/enc/trans/macromania-tbl.rb
@@ -126,4 +126,4 @@ MACROMANIA_TO_UCS_TBL = [
["B2",0x2264],
["B3",0x2265],
["D7",0x25CA],
-]
+] \ No newline at end of file
diff --git a/enc/trans/macturkish-tbl.rb b/enc/trans/macturkish-tbl.rb
index 883f693e23..2358672ed6 100644
--- a/enc/trans/macturkish-tbl.rb
+++ b/enc/trans/macturkish-tbl.rb
@@ -125,4 +125,4 @@ MACTURKISH_TO_UCS_TBL = [
["B2",0x2264],
["B3",0x2265],
["D7",0x25CA],
-]
+] \ No newline at end of file
diff --git a/enc/trans/macukraine-tbl.rb b/enc/trans/macukraine-tbl.rb
index 09acf7c45a..6941af654d 100644
--- a/enc/trans/macukraine-tbl.rb
+++ b/enc/trans/macukraine-tbl.rb
@@ -127,4 +127,4 @@ MACUKRAINE_TO_UCS_TBL = [
["AD",0x2260],
["B2",0x2264],
["B3",0x2265],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1250-tbl.rb b/enc/trans/windows-1250-tbl.rb
index 9cdb432a03..52063e17b1 100644
--- a/enc/trans/windows-1250-tbl.rb
+++ b/enc/trans/windows-1250-tbl.rb
@@ -122,4 +122,4 @@ WINDOWS_1250_TO_UCS_TBL = [
["9B",0x203A],
["80",0x20AC],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1251-tbl.rb b/enc/trans/windows-1251-tbl.rb
index 3c6c4ca0bb..870c718b72 100644
--- a/enc/trans/windows-1251-tbl.rb
+++ b/enc/trans/windows-1251-tbl.rb
@@ -126,4 +126,4 @@ WINDOWS_1251_TO_UCS_TBL = [
["88",0x20AC],
["B9",0x2116],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1252-tbl.rb b/enc/trans/windows-1252-tbl.rb
index 86a7be41e7..cefc72dff2 100644
--- a/enc/trans/windows-1252-tbl.rb
+++ b/enc/trans/windows-1252-tbl.rb
@@ -122,4 +122,4 @@ WINDOWS_1252_TO_UCS_TBL = [
["9B",0x203A],
["80",0x20AC],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1253-tbl.rb b/enc/trans/windows-1253-tbl.rb
index b9d47be2e0..132edb60ba 100644
--- a/enc/trans/windows-1253-tbl.rb
+++ b/enc/trans/windows-1253-tbl.rb
@@ -110,4 +110,4 @@ WINDOWS_1253_TO_UCS_TBL = [
["9B",0x203A],
["80",0x20AC],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1254-tbl.rb b/enc/trans/windows-1254-tbl.rb
index 84063abf05..81a747afaa 100644
--- a/enc/trans/windows-1254-tbl.rb
+++ b/enc/trans/windows-1254-tbl.rb
@@ -120,4 +120,4 @@ WINDOWS_1254_TO_UCS_TBL = [
["9B",0x203A],
["80",0x20AC],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1256-tbl.rb b/enc/trans/windows-1256-tbl.rb
index 0b76c824d1..25c5874fb0 100644
--- a/enc/trans/windows-1256-tbl.rb
+++ b/enc/trans/windows-1256-tbl.rb
@@ -127,4 +127,4 @@ WINDOWS_1256_TO_UCS_TBL = [
["9B",0x203A],
["80",0x20AC],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-1257-tbl.rb b/enc/trans/windows-1257-tbl.rb
index 7f15cbbd50..9e89b2b0b5 100644
--- a/enc/trans/windows-1257-tbl.rb
+++ b/enc/trans/windows-1257-tbl.rb
@@ -115,4 +115,4 @@ WINDOWS_1257_TO_UCS_TBL = [
["9B",0x203A],
["80",0x20AC],
["99",0x2122],
-]
+] \ No newline at end of file
diff --git a/enc/trans/windows-874-tbl.rb b/enc/trans/windows-874-tbl.rb
index a569765bf0..0552df3d28 100644
--- a/enc/trans/windows-874-tbl.rb
+++ b/enc/trans/windows-874-tbl.rb
@@ -96,4 +96,4 @@ WINDOWS_874_TO_UCS_TBL = [
["95",0x2022],
["85",0x2026],
["80",0x20AC],
-]
+] \ No newline at end of file
diff --git a/enc/unicode/15.0.0/name2ctype.h b/enc/unicode/15.0.0/name2ctype.h
index 6bbbb3512f..a2c996423d 100644
--- a/enc/unicode/15.0.0/name2ctype.h
+++ b/enc/unicode/15.0.0/name2ctype.h
@@ -5402,7 +5402,7 @@ static const OnigCodePoint CR_ASCII[] = {
0x0000, 0x007f,
}; /* CR_ASCII */
-/* 'Punct': [[:Punct:]] */
+/* 'Punct' */
static const OnigCodePoint CR_Punct[] = {
191,
0x0021, 0x0023,
diff --git a/encoding.c b/encoding.c
index a0be931c97..2f4b47bdfa 100644
--- a/encoding.c
+++ b/encoding.c
@@ -71,24 +71,6 @@ static struct enc_table {
st_table *names;
} global_enc_table;
-static int
-enc_names_free_i(st_data_t name, st_data_t idx, st_data_t args)
-{
- ruby_xfree((void *)name);
- return ST_DELETE;
-}
-
-void
-rb_free_global_enc_table(void)
-{
- for (size_t i = 0; i < ENCODING_LIST_CAPA; i++) {
- xfree((void *)global_enc_table.list[i].enc);
- }
-
- st_foreach(global_enc_table.names, enc_names_free_i, (st_data_t)0);
- st_free_table(global_enc_table.names);
-}
-
static rb_encoding *global_enc_ascii,
*global_enc_utf_8,
*global_enc_us_ascii;
@@ -120,7 +102,7 @@ static rb_encoding *global_enc_ascii,
static const rb_data_type_t encoding_data_type = {
"encoding",
{0, 0, 0,},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
#define is_data_encoding(obj) (RTYPEDDATA_P(obj) && RTYPEDDATA_TYPE(obj) == &encoding_data_type)
@@ -523,6 +505,37 @@ enc_replicate(struct enc_table *enc_table, const char *name, rb_encoding *encodi
return idx;
}
+int
+rb_enc_replicate(const char *name, rb_encoding *encoding)
+{
+ int r;
+
+ GLOBAL_ENC_TABLE_EVAL(enc_table,
+ r = enc_replicate(enc_table, name, encoding));
+
+ return r;
+}
+
+/*
+ * call-seq:
+ * enc.replicate(name) -> encoding
+ *
+ * Returns a replicated encoding of _enc_ whose name is _name_.
+ * The new encoding should have the same byte structure of _enc_.
+ * If _name_ is used by another encoding, raise ArgumentError.
+ *
+ */
+static VALUE
+enc_replicate_m(VALUE encoding, VALUE name)
+{
+ int idx;
+ rb_warn_deprecated_to_remove("3.3", "Encoding#replicate", "the original encoding");
+
+ idx = rb_enc_replicate(name_for_encoding(&name), rb_to_encoding(encoding));
+ RB_GC_GUARD(name);
+ return rb_enc_from_encoding_index(idx);
+}
+
static int
enc_replicate_with_index(struct enc_table *enc_table, const char *name, rb_encoding *origenc, int idx)
{
@@ -1908,6 +1921,7 @@ Init_Encoding(void)
rb_define_method(rb_cEncoding, "names", enc_names, 0);
rb_define_method(rb_cEncoding, "dummy?", enc_dummy_p, 0);
rb_define_method(rb_cEncoding, "ascii_compatible?", enc_ascii_compatible_p, 0);
+ rb_define_method(rb_cEncoding, "replicate", enc_replicate_m, 1);
rb_define_singleton_method(rb_cEncoding, "list", enc_list, 0);
rb_define_singleton_method(rb_cEncoding, "name_list", rb_enc_name_list, 0);
rb_define_singleton_method(rb_cEncoding, "aliases", rb_enc_aliases, 0);
diff --git a/enum.c b/enum.c
index 7f15836ba8..b3c715e0a1 100644
--- a/enum.c
+++ b/enum.c
@@ -354,7 +354,7 @@ find_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
* {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1]
* {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => []
*
- * With no block given, returns an Enumerator.
+ * With no block given, returns an \Enumerator.
*
*/
static VALUE
@@ -424,7 +424,7 @@ find_index_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
* ['a', 'b', 'c', 'b'].find_index {|element| element.start_with?('b') } # => 1
* {foo: 0, bar: 1, baz: 2}.find_index {|key, value| value > 1 } # => 2
*
- * With no argument and no block given, returns an Enumerator.
+ * With no argument and no block given, returns an \Enumerator.
*
*/
@@ -501,7 +501,7 @@ enum_size_over_p(VALUE obj, long n)
* a = {foo: 0, bar: 1, baz: 2}.select {|key, value| key.start_with?('b') }
* a # => {:bar=>1, :baz=>2}
*
- * With no block given, returns an Enumerator.
+ * With no block given, returns an \Enumerator.
*
* Related: #reject.
*/
@@ -543,7 +543,7 @@ filter_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
* (0..9).filter_map {|i| i * 2 if i.even? } # => [0, 4, 8, 12, 16]
* {foo: 0, bar: 1, baz: 2}.filter_map {|key, value| key if value.even? } # => [:foo, :baz]
*
- * When no block given, returns an Enumerator.
+ * When no block given, returns an \Enumerator.
*
*/
static VALUE
@@ -584,7 +584,7 @@ reject_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
* (0..9).reject {|i| i * 2 if i.even? } # => [1, 3, 5, 7, 9]
* {foo: 0, bar: 1, baz: 2}.reject {|key, value| key if value.odd? } # => {:foo=>0, :baz=>2}
*
- * When no block given, returns an Enumerator.
+ * When no block given, returns an \Enumerator.
*
* Related: #select.
*/
@@ -631,7 +631,7 @@ collect_all(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
* (0..4).map {|i| i*i } # => [0, 1, 4, 9, 16]
* {foo: 0, bar: 1, baz: 2}.map {|key, value| value*2} # => [0, 2, 4]
*
- * With no block given, returns an Enumerator.
+ * With no block given, returns an \Enumerator.
*
*/
static VALUE
@@ -681,7 +681,7 @@ flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary))
* [[0, 1], [2, 3]].flat_map {|e| e + [100] } # => [0, 1, 100, 2, 3, 100]
* {foo: 0, bar: 1, baz: 2}.flat_map {|key, value| [key, value] } # => [:foo, 0, :bar, 1, :baz, 2]
*
- * With no block given, returns an Enumerator.
+ * With no block given, returns an \Enumerator.
*
* Alias: #collect_concat.
*/
@@ -700,12 +700,13 @@ enum_flat_map(VALUE obj)
/*
* call-seq:
- * to_a(*args) -> array
+ * to_a -> array
*
* Returns an array containing the items in +self+:
*
* (0..4).to_a # => [0, 1, 2, 3, 4]
*
+ * Enumerable#entries is an alias for Enumerable#to_a.
*/
static VALUE
enum_to_a(int argc, VALUE *argv, VALUE obj)
@@ -745,8 +746,8 @@ enum_to_h_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
/*
* call-seq:
- * to_h(*args) -> hash
- * to_h(*args) {|element| ... } -> hash
+ * to_h -> hash
+ * to_h {|element| ... } -> hash
*
* When +self+ consists of 2-element arrays,
* returns a hash each of whose entries is the key-value pair
@@ -999,6 +1000,7 @@ ary_inject_op(VALUE ary, VALUE init, VALUE op)
* "Memo: 3; element: 3"
* "Memo: 6; element: 4"
*
+ * Enumerable#reduce is an alias for Enumerable#inject.
*
*/
static VALUE
@@ -1334,12 +1336,10 @@ enum_sort(VALUE obj)
}
#define SORT_BY_BUFSIZE 16
-#define SORT_BY_UNIFORMED(num, flo, fix) (((num&1)<<2)|((flo&1)<<1)|fix)
struct sort_by_data {
const VALUE ary;
const VALUE buf;
- uint8_t n;
- uint8_t primitive_uniformed;
+ long n;
};
static VALUE
@@ -1360,11 +1360,6 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, _data))
rb_raise(rb_eRuntimeError, "sort_by reentered");
}
- if (data->primitive_uniformed) {
- data->primitive_uniformed &= SORT_BY_UNIFORMED((FIXNUM_P(v)) || (RB_FLOAT_TYPE_P(v)),
- RB_FLOAT_TYPE_P(v),
- FIXNUM_P(v));
- }
RARRAY_ASET(data->buf, data->n*2, v);
RARRAY_ASET(data->buf, data->n*2+1, i);
data->n++;
@@ -1392,179 +1387,6 @@ sort_by_cmp(const void *ap, const void *bp, void *data)
return OPTIMIZED_CMP(a, b);
}
-
-/*
- This is parts of uniform sort
-*/
-
-#define uless rb_uniform_is_less
-#define UNIFORM_SWAP(a,b)\
- do{struct rb_uniform_sort_data tmp = a; a = b; b = tmp;} while(0)
-
-struct rb_uniform_sort_data {
- VALUE v;
- VALUE i;
-};
-
-static inline bool
-rb_uniform_is_less(VALUE a, VALUE b)
-{
-
- if (FIXNUM_P(a) && FIXNUM_P(b)) {
- return (SIGNED_VALUE)a < (SIGNED_VALUE)b;
- }
- else if (FIXNUM_P(a)) {
- RUBY_ASSERT(RB_FLOAT_TYPE_P(b));
- return rb_float_cmp(b, a) > 0;
- }
- else {
- RUBY_ASSERT(RB_FLOAT_TYPE_P(a));
- return rb_float_cmp(a, b) < 0;
- }
-}
-
-static inline bool
-rb_uniform_is_larger(VALUE a, VALUE b)
-{
-
- if (FIXNUM_P(a) && FIXNUM_P(b)) {
- return (SIGNED_VALUE)a > (SIGNED_VALUE)b;
- }
- else if (FIXNUM_P(a)) {
- RUBY_ASSERT(RB_FLOAT_TYPE_P(b));
- return rb_float_cmp(b, a) < 0;
- }
- else {
- RUBY_ASSERT(RB_FLOAT_TYPE_P(a));
- return rb_float_cmp(a, b) > 0;
- }
-}
-
-#define med3_val(a,b,c) (uless(a,b)?(uless(b,c)?b:uless(c,a)?a:c):(uless(c,b)?b:uless(a,c)?a:c))
-
-static void
-rb_uniform_insertionsort_2(struct rb_uniform_sort_data* ptr_begin,
- struct rb_uniform_sort_data* ptr_end)
-{
- if ((ptr_end - ptr_begin) < 2) return;
- struct rb_uniform_sort_data tmp, *j, *k,
- *index = ptr_begin+1;
- for (; index < ptr_end; index++) {
- tmp = *index;
- j = k = index;
- if (uless(tmp.v, ptr_begin->v)) {
- while (ptr_begin < j) {
- *j = *(--k);
- j = k;
- }
- }
- else {
- while (uless(tmp.v, (--k)->v)) {
- *j = *k;
- j = k;
- }
- }
- *j = tmp;
- }
-}
-
-static inline void
-rb_uniform_heap_down_2(struct rb_uniform_sort_data* ptr_begin,
- size_t offset, size_t len)
-{
- size_t c;
- struct rb_uniform_sort_data tmp = ptr_begin[offset];
- while ((c = (offset<<1)+1) <= len) {
- if (c < len && uless(ptr_begin[c].v, ptr_begin[c+1].v)) {
- c++;
- }
- if (!uless(tmp.v, ptr_begin[c].v)) break;
- ptr_begin[offset] = ptr_begin[c];
- offset = c;
- }
- ptr_begin[offset] = tmp;
-}
-
-static void
-rb_uniform_heapsort_2(struct rb_uniform_sort_data* ptr_begin,
- struct rb_uniform_sort_data* ptr_end)
-{
- size_t n = ptr_end - ptr_begin;
- if (n < 2) return;
-
- for (size_t offset = n>>1; offset > 0;) {
- rb_uniform_heap_down_2(ptr_begin, --offset, n-1);
- }
- for (size_t offset = n-1; offset > 0;) {
- UNIFORM_SWAP(*ptr_begin, ptr_begin[offset]);
- rb_uniform_heap_down_2(ptr_begin, 0, --offset);
- }
-}
-
-
-static void
-rb_uniform_quicksort_intro_2(struct rb_uniform_sort_data* ptr_begin,
- struct rb_uniform_sort_data* ptr_end, size_t d)
-{
-
- if (ptr_end - ptr_begin <= 16) {
- rb_uniform_insertionsort_2(ptr_begin, ptr_end);
- return;
- }
- if (d == 0) {
- rb_uniform_heapsort_2(ptr_begin, ptr_end);
- return;
- }
-
- VALUE x = med3_val(ptr_begin->v,
- ptr_begin[(ptr_end - ptr_begin)>>1].v,
- ptr_end[-1].v);
- struct rb_uniform_sort_data *i = ptr_begin;
- struct rb_uniform_sort_data *j = ptr_end-1;
-
- do {
- while (uless(i->v, x)) i++;
- while (uless(x, j->v)) j--;
- if (i <= j) {
- UNIFORM_SWAP(*i, *j);
- i++;
- j--;
- }
- } while (i <= j);
- j++;
- if (ptr_end - j > 1) rb_uniform_quicksort_intro_2(j, ptr_end, d-1);
- if (i - ptr_begin > 1) rb_uniform_quicksort_intro_2(ptr_begin, i, d-1);
-}
-
-/**
- * Direct primitive data compare sort. Implement with intro sort.
- * @param[in] ptr_begin The begin address of target rb_ary's raw pointer.
- * @param[in] ptr_end The end address of target rb_ary's raw pointer.
-**/
-static void
-rb_uniform_intro_sort_2(struct rb_uniform_sort_data* ptr_begin,
- struct rb_uniform_sort_data* ptr_end)
-{
- size_t n = ptr_end - ptr_begin;
- size_t d = CHAR_BIT * sizeof(n) - nlz_intptr(n) - 1;
- bool sorted_flag = true;
-
- for (struct rb_uniform_sort_data* ptr = ptr_begin+1; ptr < ptr_end; ptr++) {
- if (rb_uniform_is_larger((ptr-1)->v, (ptr)->v)) {
- sorted_flag = false;
- break;
- }
- }
-
- if (sorted_flag) {
- return;
- }
- rb_uniform_quicksort_intro_2(ptr_begin, ptr_end, d<<1);
-}
-
-#undef uless
-
-
/*
* call-seq:
* sort_by {|element| ... } -> array
@@ -1671,9 +1493,6 @@ enum_sort_by(VALUE obj)
RB_OBJ_WRITE(memo, &data->ary, ary);
RB_OBJ_WRITE(memo, &data->buf, buf);
data->n = 0;
- data->primitive_uniformed = SORT_BY_UNIFORMED((CMP_OPTIMIZABLE(FLOAT) && CMP_OPTIMIZABLE(INTEGER)),
- CMP_OPTIMIZABLE(FLOAT),
- CMP_OPTIMIZABLE(INTEGER));
rb_block_call(obj, id_each, 0, 0, sort_by_i, (VALUE)memo);
ary = data->ary;
buf = data->buf;
@@ -1682,16 +1501,9 @@ enum_sort_by(VALUE obj)
rb_ary_concat(ary, buf);
}
if (RARRAY_LEN(ary) > 2) {
- if (data->primitive_uniformed) {
- RARRAY_PTR_USE(ary, ptr,
- rb_uniform_intro_sort_2((struct rb_uniform_sort_data*)ptr,
- (struct rb_uniform_sort_data*)(ptr + RARRAY_LEN(ary))));
- }
- else {
- RARRAY_PTR_USE(ary, ptr,
- ruby_qsort(ptr, RARRAY_LEN(ary)/2, 2*sizeof(VALUE),
- sort_by_cmp, (void *)ary));
- }
+ RARRAY_PTR_USE(ary, ptr,
+ ruby_qsort(ptr, RARRAY_LEN(ary)/2, 2*sizeof(VALUE),
+ sort_by_cmp, (void *)ary));
}
if (RBASIC(ary)->klass) {
rb_raise(rb_eRuntimeError, "sort_by reentered");
@@ -1757,9 +1569,6 @@ DEFINE_ENUMFUNCS(all)
*
* Returns whether every element meets a given criterion.
*
- * If +self+ has no element, returns +true+ and argument or block
- * are not used.
- *
* With no argument and no block,
* returns whether every element is truthy:
*
@@ -1821,9 +1630,6 @@ DEFINE_ENUMFUNCS(any)
*
* Returns whether any element meets a given criterion.
*
- * If +self+ has no element, returns +false+ and argument or block
- * are not used.
- *
* With no argument and no block,
* returns whether any element is truthy:
*
@@ -1854,6 +1660,7 @@ DEFINE_ENUMFUNCS(any)
* {foo: 0, bar: 1, baz: 2}.any? {|key, value| value < 1 } # => true
* {foo: 0, bar: 1, baz: 2}.any? {|key, value| value < 0 } # => false
*
+ *
* Related: #all?, #none?, #one?.
*/
@@ -2915,6 +2722,8 @@ member_i(RB_BLOCK_CALL_FUNC_ARGLIST(iter, args))
* {foo: 0, bar: 1, baz: 2}.include?('foo') # => false
* {foo: 0, bar: 1, baz: 2}.include?(0) # => false
*
+ * Enumerable#member? is an alias for Enumerable#include?.
+ *
*/
static VALUE
@@ -4650,7 +4459,7 @@ sum_iter(VALUE i, struct enum_sum_memo *memo)
}
else switch (TYPE(memo->v)) {
default: sum_iter_some_value(i, memo); return;
- case T_FLOAT: sum_iter_Kahan_Babuska(i, memo); return;
+ case T_FLOAT:
case T_FIXNUM:
case T_BIGNUM:
case T_RATIONAL:
@@ -4824,13 +4633,13 @@ uniq_iter(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
* %w[a b c c b a a b c].uniq # => ["a", "b", "c"]
* [0, 1, 2, 2, 1, 0, 0, 1, 2].uniq # => [0, 1, 2]
*
- * With a block, returns a new array containing elements only for which the block
+ * With a block, returns a new array containing only for which the block
* returns a unique value:
*
* a = [0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
* a.uniq {|i| i.even? ? i : 0 } # => [0, 2, 4]
* a = %w[a b c d e e d c b a a b c d e]
- * a.uniq {|c| c < 'c' } # => ["a", "c"]
+ a.uniq {|c| c < 'c' } # => ["a", "c"]
*
*/
@@ -4889,7 +4698,7 @@ enum_compact(VALUE obj)
*
* - {Querying}[rdoc-ref:Enumerable@Methods+for+Querying]
* - {Fetching}[rdoc-ref:Enumerable@Methods+for+Fetching]
- * - {Searching and Filtering}[rdoc-ref:Enumerable@Methods+for+Searching+and+Filtering]
+ * - {Searching}[rdoc-ref:Enumerable@Methods+for+Searching]
* - {Sorting}[rdoc-ref:Enumerable@Methods+for+Sorting]
* - {Iterating}[rdoc-ref:Enumerable@Methods+for+Iterating]
* - {And more....}[rdoc-ref:Enumerable@Other+Methods]
@@ -4905,7 +4714,7 @@ enum_compact(VALUE obj)
* - #one?: Returns +true+ if exactly one element meets a specified criterion; +false+ otherwise.
* - #count: Returns the count of elements,
* based on an argument or block criterion, if given.
- * - #tally: Returns a new Hash containing the counts of occurrences of each element.
+ * - #tally: Returns a new \Hash containing the counts of occurrences of each element.
*
* === Methods for Fetching
*
@@ -4926,21 +4735,21 @@ enum_compact(VALUE obj)
* as determined by <tt><=></tt> or a given block.
* - #max: Returns the elements whose values are largest among the elements,
* as determined by <tt><=></tt> or a given block.
- * - #minmax: Returns a 2-element Array containing the smallest and largest elements.
+ * - #minmax: Returns a 2-element \Array containing the smallest and largest elements.
* - #min_by: Returns the smallest element, as determined by the given block.
* - #max_by: Returns the largest element, as determined by the given block.
* - #minmax_by: Returns the smallest and largest elements, as determined by the given block.
*
* <i>Groups, slices, and partitions</i>:
*
- * - #group_by: Returns a Hash that partitions the elements into groups.
+ * - #group_by: Returns a \Hash that partitions the elements into groups.
* - #partition: Returns elements partitioned into two new Arrays, as determined by the given block.
- * - #slice_after: Returns a new Enumerator whose entries are a partition of +self+,
- * based either on a given +object+ or a given block.
- * - #slice_before: Returns a new Enumerator whose entries are a partition of +self+,
- * based either on a given +object+ or a given block.
- * - #slice_when: Returns a new Enumerator whose entries are a partition of +self+
- * based on the given block.
+ * - #slice_after: Returns a new \Enumerator whose entries are a partition of +self+,
+ based either on a given +object+ or a given block.
+ * - #slice_before: Returns a new \Enumerator whose entries are a partition of +self+,
+ based either on a given +object+ or a given block.
+ * - #slice_when: Returns a new \Enumerator whose entries are a partition of +self+
+ based on the given block.
* - #chunk: Returns elements organized into chunks as specified by the given block.
* - #chunk_while: Returns elements organized into chunks as specified by the given block.
*
@@ -5040,18 +4849,18 @@ enum_compact(VALUE obj)
*
* Virtually all methods in \Enumerable call method +#each+ in the including class:
*
- * - <tt>Hash#each</tt> yields the next key-value pair as a 2-element Array.
- * - <tt>Struct#each</tt> yields the next name-value pair as a 2-element Array.
+ * - <tt>Hash#each</tt> yields the next key-value pair as a 2-element \Array.
+ * - <tt>Struct#each</tt> yields the next name-value pair as a 2-element \Array.
* - For the other classes above, +#each+ yields the next object from the collection.
*
* == About the Examples
*
* The example code snippets for the \Enumerable methods:
*
- * - Always show the use of one or more Array-like classes (often Array itself).
- * - Sometimes show the use of a Hash-like class.
+ * - Always show the use of one or more \Array-like classes (often \Array itself).
+ * - Sometimes show the use of a \Hash-like class.
* For some methods, though, the usage would not make sense,
- * and so it is not shown. Example: #tally would find exactly one of each Hash entry.
+ * and so it is not shown. Example: #tally would find exactly one of each \Hash entry.
*
*/
diff --git a/enumerator.c b/enumerator.c
index d2819e4049..d587b63d32 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -73,7 +73,7 @@
* puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
* # => ["0:foo", "1:bar", "2:baz"]
*
- * == External Iteration
+ * == External Iteration
*
* An Enumerator can also be used as an external iterator.
* For example, Enumerator#next returns the next value of the iterator
@@ -85,31 +85,26 @@
* puts e.next # => 3
* puts e.next # raises StopIteration
*
- * +next+, +next_values+, +peek+, and +peek_values+ are the only methods
- * which use external iteration (and Array#zip(Enumerable-not-Array) which uses +next+ internally).
+ * +next+, +next_values+, +peek+ and +peek_values+ are the only methods
+ * which use external iteration (and Array#zip(Enumerable-not-Array) which uses +next+).
*
* These methods do not affect other internal enumeration methods,
* unless the underlying iteration method itself has side-effect, e.g. IO#each_line.
*
- * FrozenError will be raised if these methods are called against a frozen enumerator.
- * Since +rewind+ and +feed+ also change state for external iteration,
- * these methods may raise FrozenError too.
- *
* External iteration differs *significantly* from internal iteration
* due to using a Fiber:
- * - The Fiber adds some overhead compared to internal enumeration.
- * - The stacktrace will only include the stack from the Enumerator, not above.
- * - Fiber-local variables are *not* inherited inside the Enumerator Fiber,
- * which instead starts with no Fiber-local variables.
- * - Fiber storage variables *are* inherited and are designed
- * to handle Enumerator Fibers. Assigning to a Fiber storage variable
- * only affects the current Fiber, so if you want to change state
- * in the caller Fiber of the Enumerator Fiber, you need to use an
- * extra indirection (e.g., use some object in the Fiber storage
- * variable and mutate some ivar of it).
+ * - The Fiber adds some overhead compared to internal enumeration.
+ * - The stacktrace will only include the stack from the Enumerator, not above.
+ * - Fiber-local variables are *not* inherited inside the Enumerator Fiber,
+ * which instead starts with no Fiber-local variables.
+ * - Fiber storage variables *are* inherited and are designed
+ * to handle Enumerator Fibers. Assigning to a Fiber storage variable
+ * only affects the current Fiber, so if you want to change state
+ * in the caller Fiber of the Enumerator Fiber, you need to use an
+ * extra indirection (e.g., use some object in the Fiber storage
+ * variable and mutate some ivar of it).
*
* Concretely:
- *
* Thread.current[:fiber_local] = 1
* Fiber[:storage_var] = 1
* e = Enumerator.new do |y|
@@ -125,7 +120,7 @@
* e.each { p _1 }
* p Fiber[:storage_var] # => 2 (it ran in the same Fiber/"stack" as the current Fiber)
*
- * == Convert External Iteration to Internal Iteration
+ * == Convert External Iteration to Internal Iteration
*
* You can use an external iterator to implement an internal iterator as follows:
*
@@ -195,19 +190,6 @@ struct enumerator {
int kw_splat;
};
-RUBY_REFERENCES(enumerator_refs) = {
- RUBY_REF_EDGE(struct enumerator, obj),
- RUBY_REF_EDGE(struct enumerator, args),
- RUBY_REF_EDGE(struct enumerator, fib),
- RUBY_REF_EDGE(struct enumerator, dst),
- RUBY_REF_EDGE(struct enumerator, lookahead),
- RUBY_REF_EDGE(struct enumerator, feedvalue),
- RUBY_REF_EDGE(struct enumerator, stop_exc),
- RUBY_REF_EDGE(struct enumerator, size),
- RUBY_REF_EDGE(struct enumerator, procs),
- RUBY_REF_END
-};
-
static VALUE rb_cGenerator, rb_cYielder, rb_cEnumProducer;
struct generator {
@@ -257,15 +239,56 @@ struct enum_product {
VALUE rb_cArithSeq;
+/*
+ * Enumerator
+ */
+static void
+enumerator_mark(void *p)
+{
+ struct enumerator *ptr = p;
+ rb_gc_mark_movable(ptr->obj);
+ rb_gc_mark_movable(ptr->args);
+ rb_gc_mark_movable(ptr->fib);
+ rb_gc_mark_movable(ptr->dst);
+ rb_gc_mark_movable(ptr->lookahead);
+ rb_gc_mark_movable(ptr->feedvalue);
+ rb_gc_mark_movable(ptr->stop_exc);
+ rb_gc_mark_movable(ptr->size);
+ rb_gc_mark_movable(ptr->procs);
+}
+
+static void
+enumerator_compact(void *p)
+{
+ struct enumerator *ptr = p;
+ ptr->obj = rb_gc_location(ptr->obj);
+ ptr->args = rb_gc_location(ptr->args);
+ ptr->fib = rb_gc_location(ptr->fib);
+ ptr->dst = rb_gc_location(ptr->dst);
+ ptr->lookahead = rb_gc_location(ptr->lookahead);
+ ptr->feedvalue = rb_gc_location(ptr->feedvalue);
+ ptr->stop_exc = rb_gc_location(ptr->stop_exc);
+ ptr->size = rb_gc_location(ptr->size);
+ ptr->procs = rb_gc_location(ptr->procs);
+}
+
+#define enumerator_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+enumerator_memsize(const void *p)
+{
+ return sizeof(struct enumerator);
+}
+
static const rb_data_type_t enumerator_data_type = {
"enumerator",
{
- RUBY_REFS_LIST_PTR(enumerator_refs),
- RUBY_TYPED_DEFAULT_FREE,
- NULL, // Nothing allocated externally, so don't need a memsize function
- NULL,
+ enumerator_mark,
+ enumerator_free,
+ enumerator_memsize,
+ enumerator_compact,
},
- 0, NULL, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct enumerator *
@@ -296,15 +319,22 @@ proc_entry_compact(void *p)
ptr->memo = rb_gc_location(ptr->memo);
}
+#define proc_entry_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+proc_entry_memsize(const void *p)
+{
+ return p ? sizeof(struct proc_entry) : 0;
+}
+
static const rb_data_type_t proc_entry_data_type = {
"proc_entry",
{
proc_entry_mark,
- RUBY_TYPED_DEFAULT_FREE,
- NULL, // Nothing allocated externally, so don't need a memsize function
+ proc_entry_free,
+ proc_entry_memsize,
proc_entry_compact,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
};
static struct proc_entry *
@@ -389,7 +419,7 @@ obj_to_enum(int argc, VALUE *argv, VALUE obj)
}
enumerator = rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
if (rb_block_given_p()) {
- RB_OBJ_WRITE(enumerator, &enumerator_ptr(enumerator)->size, rb_block_proc());
+ enumerator_ptr(enumerator)->size = rb_block_proc();
}
return enumerator;
}
@@ -418,15 +448,15 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar
rb_raise(rb_eArgError, "unallocated enumerator");
}
- RB_OBJ_WRITE(enum_obj, &ptr->obj, obj);
+ ptr->obj = obj;
ptr->meth = rb_to_id(meth);
- if (argc) RB_OBJ_WRITE(enum_obj, &ptr->args, rb_ary_new4(argc, argv));
+ if (argc) ptr->args = rb_ary_new4(argc, argv);
ptr->fib = 0;
ptr->dst = Qnil;
ptr->lookahead = Qundef;
ptr->feedvalue = Qundef;
ptr->stop_exc = Qfalse;
- RB_OBJ_WRITE(enum_obj, &ptr->size, size);
+ ptr->size = size;
ptr->size_fn = size_fn;
ptr->kw_splat = kw_splat;
@@ -505,13 +535,13 @@ enumerator_init_copy(VALUE obj, VALUE orig)
rb_raise(rb_eArgError, "unallocated enumerator");
}
- RB_OBJ_WRITE(obj, &ptr1->obj, ptr0->obj);
- RB_OBJ_WRITE(obj, &ptr1->meth, ptr0->meth);
- RB_OBJ_WRITE(obj, &ptr1->args, ptr0->args);
+ ptr1->obj = ptr0->obj;
+ ptr1->meth = ptr0->meth;
+ ptr1->args = ptr0->args;
ptr1->fib = 0;
ptr1->lookahead = Qundef;
ptr1->feedvalue = Qundef;
- RB_OBJ_WRITE(obj, &ptr1->size, ptr0->size);
+ ptr1->size = ptr0->size;
ptr1->size_fn = ptr0->size_fn;
return obj;
@@ -559,17 +589,11 @@ enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
const struct enumerator *e = enumerator_ptr(obj);
ID meth = e->meth;
- VALUE args = e->args;
- if (args) {
- argc = RARRAY_LENINT(args);
- argv = RARRAY_CONST_PTR(args);
+ if (e->args) {
+ argc = RARRAY_LENINT(e->args);
+ argv = RARRAY_CONST_PTR(e->args);
}
-
- VALUE ret = rb_block_call_kw(e->obj, meth, argc, argv, func, arg, e->kw_splat);
-
- RB_GC_GUARD(args);
-
- return ret;
+ return rb_block_call_kw(e->obj, meth, argc, argv, func, arg, e->kw_splat);
}
/*
@@ -626,7 +650,7 @@ enumerator_each(int argc, VALUE *argv, VALUE obj)
else {
args = rb_ary_new4(argc, argv);
}
- RB_OBJ_WRITE(obj, &e->args, args);
+ e->args = args;
e->size = Qnil;
e->size_fn = 0;
}
@@ -767,7 +791,7 @@ next_i(RB_BLOCK_CALL_FUNC_ARGLIST(_, obj))
VALUE result;
result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
- RB_OBJ_WRITE(obj, &e->stop_exc, rb_exc_new2(rb_eStopIteration, "iteration reached an end"));
+ e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
rb_ivar_set(e->stop_exc, id_result, result);
return rb_fiber_yield(1, &nil);
}
@@ -776,8 +800,8 @@ static void
next_init(VALUE obj, struct enumerator *e)
{
VALUE curr = rb_fiber_current();
- RB_OBJ_WRITE(obj, &e->dst, curr);
- RB_OBJ_WRITE(obj, &e->fib, rb_fiber_new(next_i, obj));
+ e->dst = curr;
+ e->fib = rb_fiber_new(next_i, obj);
e->lookahead = Qundef;
}
@@ -865,8 +889,6 @@ enumerator_next_values(VALUE obj)
struct enumerator *e = enumerator_ptr(obj);
VALUE vs;
- rb_check_frozen(obj);
-
if (!UNDEF_P(e->lookahead)) {
vs = e->lookahead;
e->lookahead = Qundef;
@@ -928,12 +950,9 @@ enumerator_peek_values(VALUE obj)
{
struct enumerator *e = enumerator_ptr(obj);
- rb_check_frozen(obj);
-
if (UNDEF_P(e->lookahead)) {
- RB_OBJ_WRITE(obj, &e->lookahead, get_next_values(obj, e));
+ e->lookahead = get_next_values(obj, e);
}
-
return e->lookahead;
}
@@ -1055,12 +1074,10 @@ enumerator_feed(VALUE obj, VALUE v)
{
struct enumerator *e = enumerator_ptr(obj);
- rb_check_frozen(obj);
-
if (!UNDEF_P(e->feedvalue)) {
rb_raise(rb_eTypeError, "feed value already set");
}
- RB_OBJ_WRITE(obj, &e->feedvalue, v);
+ e->feedvalue = v;
return Qnil;
}
@@ -1079,8 +1096,6 @@ enumerator_rewind(VALUE obj)
{
struct enumerator *e = enumerator_ptr(obj);
- rb_check_frozen(obj);
-
rb_check_funcall(e->obj, id_rewind, 0, 0);
e->fib = 0;
@@ -1294,15 +1309,23 @@ yielder_compact(void *p)
ptr->proc = rb_gc_location(ptr->proc);
}
+#define yielder_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+yielder_memsize(const void *p)
+{
+ return sizeof(struct yielder);
+}
+
static const rb_data_type_t yielder_data_type = {
"yielder",
{
yielder_mark,
- RUBY_TYPED_DEFAULT_FREE,
- NULL,
+ yielder_free,
+ yielder_memsize,
yielder_compact,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct yielder *
@@ -1341,7 +1364,7 @@ yielder_init(VALUE obj, VALUE proc)
rb_raise(rb_eArgError, "unallocated yielder");
}
- RB_OBJ_WRITE(obj, &ptr->proc, proc);
+ ptr->proc = proc;
return obj;
}
@@ -1426,15 +1449,23 @@ generator_compact(void *p)
ptr->obj = rb_gc_location(ptr->obj);
}
+#define generator_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+generator_memsize(const void *p)
+{
+ return sizeof(struct generator);
+}
+
static const rb_data_type_t generator_data_type = {
"generator",
{
generator_mark,
- RUBY_TYPED_DEFAULT_FREE,
- NULL,
+ generator_free,
+ generator_memsize,
generator_compact,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct generator *
@@ -1474,7 +1505,7 @@ generator_init(VALUE obj, VALUE proc)
rb_raise(rb_eArgError, "unallocated generator");
}
- RB_OBJ_WRITE(obj, &ptr->proc, proc);
+ ptr->proc = proc;
return obj;
}
@@ -1522,7 +1553,7 @@ generator_init_copy(VALUE obj, VALUE orig)
rb_raise(rb_eArgError, "unallocated generator");
}
- RB_OBJ_WRITE(obj, &ptr1->proc, ptr0->proc);
+ ptr1->proc = ptr0->proc;
return obj;
}
@@ -1689,7 +1720,7 @@ lazy_generator_init(VALUE enumerator, VALUE procs)
lazy_init_block, rb_ary_new3(2, obj, procs));
gen_ptr = generator_ptr(generator);
- RB_OBJ_WRITE(generator, &gen_ptr->obj, obj);
+ gen_ptr->obj = obj;
return generator;
}
@@ -1874,10 +1905,10 @@ lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
VALUE entry_obj = TypedData_Make_Struct(rb_cObject, struct proc_entry,
&proc_entry_data_type, entry);
if (rb_block_given_p()) {
- RB_OBJ_WRITE(entry_obj, &entry->proc, rb_block_proc());
+ entry->proc = rb_block_proc();
}
entry->fn = fn;
- RB_OBJ_WRITE(entry_obj, &entry->memo, args);
+ entry->memo = args;
lazy_set_args(entry_obj, memo);
@@ -1886,9 +1917,9 @@ lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
rb_ary_push(new_procs, entry_obj);
new_obj = enumerator_init_copy(enumerator_allocate(rb_cLazy), obj);
- new_e = RTYPEDDATA_GET_DATA(new_obj);
- RB_OBJ_WRITE(new_obj, &new_e->obj, new_generator);
- RB_OBJ_WRITE(new_obj, &new_e->procs, new_procs);
+ new_e = DATA_PTR(new_obj);
+ new_e->obj = new_generator;
+ new_e->procs = new_procs;
if (argc > 0) {
new_e->meth = rb_to_id(*argv++);
@@ -1897,9 +1928,7 @@ lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
else {
new_e->meth = id_each;
}
-
- RB_OBJ_WRITE(new_obj, &new_e->args, rb_ary_new4(argc, argv));
-
+ new_e->args = rb_ary_new4(argc, argv);
return new_obj;
}
@@ -1985,7 +2014,7 @@ lazy_to_enum(int argc, VALUE *argv, VALUE self)
}
lazy = lazy_to_enum_i(self, meth, argc, argv, 0, rb_keyword_given_p());
if (rb_block_given_p()) {
- RB_OBJ_WRITE(lazy, &enumerator_ptr(lazy)->size, rb_block_proc());
+ enumerator_ptr(lazy)->size = rb_block_proc();
}
return lazy;
}
@@ -2371,6 +2400,7 @@ lazy_zip_arrays_func(VALUE proc_entry, struct MEMO *result, VALUE memos, long me
rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
}
LAZY_MEMO_SET_VALUE(result, ary);
+ LAZY_MEMO_SET_PACKED(result);
rb_ary_store(memos, memo_index, LONG2NUM(++count));
return result;
}
@@ -2945,7 +2975,7 @@ static const rb_data_type_t producer_data_type = {
producer_memsize,
producer_compact,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct producer *
@@ -2985,8 +3015,8 @@ producer_init(VALUE obj, VALUE init, VALUE proc)
rb_raise(rb_eArgError, "unallocated producer");
}
- RB_OBJ_WRITE(obj, &ptr->init, init);
- RB_OBJ_WRITE(obj, &ptr->proc, proc);
+ ptr->init = init;
+ ptr->proc = proc;
return obj;
}
diff --git a/error.c b/error.c
index 29f0f27ab9..726f57a4c0 100644
--- a/error.c
+++ b/error.c
@@ -23,10 +23,6 @@
# include <unistd.h>
#endif
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
#if defined __APPLE__
# include <AvailabilityMacros.h>
#endif
@@ -38,14 +34,12 @@
#include "internal/io.h"
#include "internal/load.h"
#include "internal/object.h"
-#include "internal/process.h"
#include "internal/string.h"
#include "internal/symbol.h"
#include "internal/thread.h"
#include "internal/variable.h"
#include "ruby/encoding.h"
#include "ruby/st.h"
-#include "ruby/util.h"
#include "ruby_assert.h"
#include "vm_core.h"
@@ -83,7 +77,6 @@ static ID id_warn;
static ID id_category;
static ID id_deprecated;
static ID id_experimental;
-static ID id_performance;
static VALUE sym_category;
static VALUE sym_highlight;
static struct {
@@ -155,8 +148,8 @@ rb_syntax_error_append(VALUE exc, VALUE file, int line, int column,
}
static unsigned int warning_disabled_categories = (
- (1U << RB_WARN_CATEGORY_DEPRECATED) |
- ~RB_WARN_CATEGORY_DEFAULT_BITS);
+ 1U << RB_WARN_CATEGORY_DEPRECATED |
+ 0);
static unsigned int
rb_warning_category_mask(VALUE category)
@@ -194,7 +187,7 @@ rb_warning_category_update(unsigned int mask, unsigned int bits)
warning_disabled_categories |= mask & ~bits;
}
-bool
+MJIT_FUNC_EXPORTED bool
rb_warning_category_enabled_p(rb_warning_category_t category)
{
return !(warning_disabled_categories & (1U << category));
@@ -207,19 +200,14 @@ rb_warning_category_enabled_p(rb_warning_category_t category)
* Returns the flag to show the warning messages for +category+.
* Supported categories are:
*
- * +:deprecated+ ::
- * deprecation warnings
- * * assignment of non-nil value to <code>$,</code> and <code>$;</code>
- * * keyword arguments
- * etc.
+ * +:deprecated+ :: deprecation warnings
+ * * assignment of non-nil value to <code>$,</code> and <code>$;</code>
+ * * keyword arguments
+ * * proc/lambda without block
+ * etc.
*
- * +:experimental+ ::
- * experimental features
- * * Pattern matching
- *
- * +:performance+ ::
- * performance hints
- * * Shape variation limit
+ * +:experimental+ :: experimental features
+ * * Pattern matching
*/
static VALUE
@@ -291,11 +279,11 @@ rb_warning_s_warn(int argc, VALUE *argv, VALUE mod)
*
* Changing the behavior of Warning.warn is useful to customize how warnings are
* handled by Ruby, for instance by filtering some warnings, and/or outputting
- * warnings somewhere other than <tt>$stderr</tt>.
+ * warnings somewhere other than $stderr.
*
* If you want to change the behavior of Warning.warn you should use
- * <tt>Warning.extend(MyNewModuleWithWarnMethod)</tt> and you can use +super+
- * to get the default behavior of printing the warning to <tt>$stderr</tt>.
+ * +Warning.extend(MyNewModuleWithWarnMethod)+ and you can use `super`
+ * to get the default behavior of printing the warning to $stderr.
*
* Example:
* module MyWarningFilter
@@ -312,7 +300,7 @@ rb_warning_s_warn(int argc, VALUE *argv, VALUE mod)
* You should never redefine Warning#warn (the instance method), as that will
* then no longer provide a way to use the default behavior.
*
- * The warning[https://rubygems.org/gems/warning] gem provides convenient ways to customize Warning.warn.
+ * The +warning+ gem provides convenient ways to customize Warning.warn.
*/
static VALUE
@@ -432,7 +420,7 @@ rb_warn(const char *fmt, ...)
void
rb_category_warn(rb_warning_category_t category, const char *fmt, ...)
{
- if (!NIL_P(ruby_verbose)) {
+ if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
with_warning_string(mesg, 0, fmt) {
rb_warn_category(mesg, rb_warning_category_to_name(category));
}
@@ -464,7 +452,7 @@ rb_warning(const char *fmt, ...)
void
rb_category_warning(rb_warning_category_t category, const char *fmt, ...)
{
- if (RTEST(ruby_verbose)) {
+ if (RTEST(ruby_verbose) && rb_warning_category_enabled_p(category)) {
with_warning_string(mesg, 0, fmt) {
rb_warn_category(mesg, rb_warning_category_to_name(category));
}
@@ -628,239 +616,18 @@ rb_bug_reporter_add(void (*func)(FILE *, void *), void *data)
return 1;
}
-/* returns true if x can not be used as file name */
-static bool
-path_sep_p(char x)
-{
-#if defined __CYGWIN__ || defined DOSISH
-# define PATH_SEP_ENCODING 1
- // Assume that "/" is only the first byte in any encoding.
- if (x == ':') return true; // drive letter or ADS
- if (x == '\\') return true;
-#endif
- return x == '/';
-}
-
-struct path_string {
- const char *ptr;
- size_t len;
-};
-
-static const char PATHSEP_REPLACE = '!';
-
-static char *
-append_pathname(char *p, const char *pe, VALUE str)
-{
-#ifdef PATH_SEP_ENCODING
- rb_encoding *enc = rb_enc_get(str);
-#endif
- const char *s = RSTRING_PTR(str);
- const char *const se = s + RSTRING_LEN(str);
- char c;
-
- --pe; // for terminator
-
- while (p < pe && s < se && (c = *s) != '\0') {
- if (c == '.') {
- if (s == se || !*s) break; // chomp "." basename
- if (path_sep_p(s[1])) goto skipsep; // skip "./"
- }
- else if (path_sep_p(c)) {
- // squeeze successive separators
- *p++ = PATHSEP_REPLACE;
- skipsep:
- while (++s < se && path_sep_p(*s));
- continue;
- }
- const char *const ss = s;
- while (p < pe && s < se && *s && !path_sep_p(*s)) {
-#ifdef PATH_SEP_ENCODING
- int n = rb_enc_mbclen(s, se, enc);
-#else
- const int n = 1;
-#endif
- p += n;
- s += n;
- }
- if (s > ss) memcpy(p - (s - ss), ss, s - ss);
- }
-
- return p;
-}
-
-static char *
-append_basename(char *p, const char *pe, struct path_string *path, VALUE str)
-{
- if (!path->ptr) {
-#ifdef PATH_SEP_ENCODING
- rb_encoding *enc = rb_enc_get(str);
-#endif
- const char *const b = RSTRING_PTR(str), *const e = RSTRING_END(str), *p = e;
-
- while (p > b) {
- if (path_sep_p(p[-1])) {
-#ifdef PATH_SEP_ENCODING
- const char *t = rb_enc_prev_char(b, p, e, enc);
- if (t == p-1) break;
- p = t;
-#else
- break;
-#endif
- }
- else {
- --p;
- }
- }
-
- path->ptr = p;
- path->len = e - p;
- }
- size_t n = path->len;
- if (p + n > pe) n = pe - p;
- memcpy(p, path->ptr, n);
- return p + n;
-}
-
-static void
-finish_report(FILE *out, rb_pid_t pid)
-{
- if (out != stdout && out != stderr) fclose(out);
-#ifdef HAVE_WORKING_FORK
- if (pid > 0) waitpid(pid, NULL, 0);
-#endif
-}
-
-struct report_expansion {
- struct path_string exe, script;
- rb_pid_t pid;
- time_t time;
-};
-
-/*
- * Open a bug report file to write. The `RUBY_CRASH_REPORT`
- * environment variable can be set to define a template that is used
- * to name bug report files. The template can contain % specifiers
- * which are substituted by the following values when a bug report
- * file is created:
- *
- * %% A single % character.
- * %e The base name of the executable filename.
- * %E Pathname of executable, with slashes ('/') replaced by
- * exclamation marks ('!').
- * %f Similar to %e with the main script filename.
- * %F Similar to %E with the main script filename.
- * %p PID of dumped process in decimal.
- * %t Time of dump, expressed as seconds since the Epoch,
- * 1970-01-01 00:00:00 +0000 (UTC).
- * %NNN Octal char code, upto 3 digits.
- */
-static char *
-expand_report_argument(const char **input_template, struct report_expansion *values,
- char *buf, size_t size, bool word)
-{
- char *p = buf;
- char *end = buf + size;
- const char *template = *input_template;
- bool store = true;
-
- if (p >= end-1 || !*template) return NULL;
- do {
- char c = *template++;
- if (word && ISSPACE(c)) break;
- if (!store) continue;
- if (c == '%') {
- size_t n;
- switch (c = *template++) {
- case 'e':
- p = append_basename(p, end, &values->exe, rb_argv0);
- continue;
- case 'E':
- p = append_pathname(p, end, rb_argv0);
- continue;
- case 'f':
- p = append_basename(p, end, &values->script, GET_VM()->orig_progname);
- continue;
- case 'F':
- p = append_pathname(p, end, GET_VM()->orig_progname);
- continue;
- case 'p':
- if (!values->pid) values->pid = getpid();
- snprintf(p, end-p, "%" PRI_PIDT_PREFIX "d", values->pid);
- p += strlen(p);
- continue;
- case 't':
- if (!values->time) values->time = time(NULL);
- snprintf(p, end-p, "%" PRI_TIMET_PREFIX "d", values->time);
- p += strlen(p);
- continue;
- default:
- if (c >= '0' && c <= '7') {
- c = (unsigned char)ruby_scan_oct(template-1, 3, &n);
- template += n - 1;
- if (!c) store = false;
- }
- break;
- }
- }
- if (p < end-1) *p++ = c;
- } while (*template);
- *input_template = template;
- *p = '\0';
- return ++p;
-}
-
-FILE *ruby_popen_writer(char *const *argv, rb_pid_t *pid);
-
-static FILE *
-open_report_path(const char *template, char *buf, size_t size, rb_pid_t *pid)
-{
- struct report_expansion values = {{0}};
-
- if (!template) return NULL;
- if (0) fprintf(stderr, "RUBY_CRASH_REPORT=%s\n", buf);
- if (*template == '|') {
- char *argv[16], *bufend = buf + size, *p;
- int argc;
- template++;
- for (argc = 0; argc < numberof(argv) - 1; ++argc) {
- while (*template && ISSPACE(*template)) template++;
- p = expand_report_argument(&template, &values, buf, bufend-buf, true);
- if (!p) break;
- argv[argc] = buf;
- buf = p;
- }
- argv[argc] = NULL;
- if (!p) return ruby_popen_writer(argv, pid);
- }
- else if (*template) {
- expand_report_argument(&template, &values, buf, size, false);
- return fopen(buf, "w");
- }
- return NULL;
-}
-
-static const char *crash_report;
-
/* SIGSEGV handler might have a very small stack. Thus we need to use it carefully. */
#define REPORT_BUG_BUFSIZ 256
static FILE *
-bug_report_file(const char *file, int line, rb_pid_t *pid)
+bug_report_file(const char *file, int line)
{
char buf[REPORT_BUG_BUFSIZ];
- const char *report = crash_report;
- if (!report) report = getenv("RUBY_CRASH_REPORT");
- FILE *out = open_report_path(report, buf, sizeof(buf), pid);
+ FILE *out = stderr;
int len = err_position_0(buf, sizeof(buf), file, line);
- if (out) {
- if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len) return out;
- fclose(out);
- }
- if ((ssize_t)fwrite(buf, 1, len, stderr) == (ssize_t)len) {
- return stderr;
- }
- if ((ssize_t)fwrite(buf, 1, len, stdout) == (ssize_t)len) {
- return stdout;
+ if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len ||
+ (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) {
+ return out;
}
return NULL;
@@ -967,7 +734,7 @@ bug_report_begin_valist(FILE *out, const char *fmt, va_list args)
} while (0)
static void
-bug_report_end(FILE *out, rb_pid_t pid)
+bug_report_end(FILE *out)
{
/* call additional bug reporters */
{
@@ -978,45 +745,26 @@ bug_report_end(FILE *out, rb_pid_t pid)
}
}
postscript_dump(out);
- finish_report(out, pid);
}
#define report_bug(file, line, fmt, ctx) do { \
- rb_pid_t pid = -1; \
- FILE *out = bug_report_file(file, line, &pid); \
+ FILE *out = bug_report_file(file, line); \
if (out) { \
bug_report_begin(out, fmt); \
- rb_vm_bugreport(ctx, out); \
- bug_report_end(out, pid); \
+ rb_vm_bugreport(ctx); \
+ bug_report_end(out); \
} \
} while (0) \
#define report_bug_valist(file, line, fmt, ctx, args) do { \
- rb_pid_t pid = -1; \
- FILE *out = bug_report_file(file, line, &pid); \
+ FILE *out = bug_report_file(file, line); \
if (out) { \
bug_report_begin_valist(out, fmt, args); \
- rb_vm_bugreport(ctx, out); \
- bug_report_end(out, pid); \
+ rb_vm_bugreport(ctx); \
+ bug_report_end(out); \
} \
} while (0) \
-void
-ruby_set_crash_report(const char *template)
-{
- crash_report = template;
-#if RUBY_DEBUG
- rb_pid_t pid = -1;
- char buf[REPORT_BUG_BUFSIZ];
- FILE *out = open_report_path(template, buf, sizeof(buf), &pid);
- if (out) {
- time_t t = time(NULL);
- fprintf(out, "ruby_test_bug_report: %s", ctime(&t));
- finish_report(out, pid);
- }
-#endif
-}
-
NORETURN(static void die(void));
static void
die(void)
@@ -1066,7 +814,6 @@ rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const voi
if (default_sighandler) default_sighandler(sig);
- ruby_default_signal(sig);
die();
}
@@ -1120,7 +867,7 @@ rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
report_bug_valist(RSTRING_PTR(file), line, fmt, NULL, args);
}
-void
+MJIT_FUNC_EXPORTED void
rb_assert_failure(const char *file, int line, const char *name, const char *expr)
{
FILE *out = stderr;
@@ -1128,8 +875,8 @@ rb_assert_failure(const char *file, int line, const char *name, const char *expr
if (name) fprintf(out, "%s:", name);
fprintf(out, "%s\n%s\n\n", expr, rb_dynamic_description);
preface_dump(out);
- rb_vm_bugreport(NULL, out);
- bug_report_end(out, -1);
+ rb_vm_bugreport(NULL);
+ bug_report_end(out);
die();
}
@@ -1323,7 +1070,7 @@ rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
actual = rb_str_new_cstr(name); /* or rb_fstring_cstr? not sure... */
}
else {
- return RTYPEDDATA_GET_DATA(obj);
+ return DATA_PTR(obj);
}
const char *expected = data_type->wrap_struct_name;
@@ -1835,7 +1582,7 @@ exc_set_backtrace(VALUE exc, VALUE bt)
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_exc_set_backtrace(VALUE exc, VALUE bt)
{
return exc_set_backtrace(exc, bt);
@@ -2203,50 +1950,50 @@ rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv)
return nometh_err_init_attr(exc, args, priv);
}
-typedef struct name_error_message_struct {
- VALUE mesg;
- VALUE recv;
- VALUE name;
-} name_error_message_t;
+/* :nodoc: */
+enum {
+ NAME_ERR_MESG__MESG,
+ NAME_ERR_MESG__RECV,
+ NAME_ERR_MESG__NAME,
+ NAME_ERR_MESG_COUNT
+};
static void
name_err_mesg_mark(void *p)
{
- name_error_message_t *ptr = (name_error_message_t *)p;
- rb_gc_mark_movable(ptr->mesg);
- rb_gc_mark_movable(ptr->recv);
- rb_gc_mark_movable(ptr->name);
+ VALUE *ptr = p;
+ rb_gc_mark_locations(ptr, ptr+NAME_ERR_MESG_COUNT);
}
-static void
-name_err_mesg_update(void *p)
+#define name_err_mesg_free RUBY_TYPED_DEFAULT_FREE
+
+static size_t
+name_err_mesg_memsize(const void *p)
{
- name_error_message_t *ptr = (name_error_message_t *)p;
- ptr->mesg = rb_gc_location(ptr->mesg);
- ptr->recv = rb_gc_location(ptr->recv);
- ptr->name = rb_gc_location(ptr->name);
+ return NAME_ERR_MESG_COUNT * sizeof(VALUE);
}
static const rb_data_type_t name_err_mesg_data_type = {
"name_err_mesg",
{
name_err_mesg_mark,
- RUBY_TYPED_DEFAULT_FREE,
- NULL, // No external memory to report,
- name_err_mesg_update,
+ name_err_mesg_free,
+ name_err_mesg_memsize,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
/* :nodoc: */
static VALUE
-rb_name_err_mesg_init(VALUE klass, VALUE mesg, VALUE recv, VALUE name)
+rb_name_err_mesg_init(VALUE klass, VALUE mesg, VALUE recv, VALUE method)
{
- name_error_message_t *message;
- VALUE result = TypedData_Make_Struct(klass, name_error_message_t, &name_err_mesg_data_type, message);
- RB_OBJ_WRITE(result, &message->mesg, mesg);
- RB_OBJ_WRITE(result, &message->recv, recv);
- RB_OBJ_WRITE(result, &message->name, name);
+ VALUE result = TypedData_Wrap_Struct(klass, &name_err_mesg_data_type, 0);
+ VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT);
+
+ ptr[NAME_ERR_MESG__MESG] = mesg;
+ ptr[NAME_ERR_MESG__RECV] = recv;
+ ptr[NAME_ERR_MESG__NAME] = method;
+ RTYPEDDATA_DATA(result) = ptr;
return result;
}
@@ -2268,16 +2015,14 @@ name_err_mesg_alloc(VALUE klass)
static VALUE
name_err_mesg_init_copy(VALUE obj1, VALUE obj2)
{
+ VALUE *ptr1, *ptr2;
+
if (obj1 == obj2) return obj1;
rb_obj_init_copy(obj1, obj2);
- name_error_message_t *ptr1, *ptr2;
- TypedData_Get_Struct(obj1, name_error_message_t, &name_err_mesg_data_type, ptr1);
- TypedData_Get_Struct(obj2, name_error_message_t, &name_err_mesg_data_type, ptr2);
-
- RB_OBJ_WRITE(obj1, &ptr1->mesg, ptr2->mesg);
- RB_OBJ_WRITE(obj1, &ptr1->recv, ptr2->recv);
- RB_OBJ_WRITE(obj1, &ptr1->name, ptr2->name);
+ TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
+ TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
+ MEMCPY(ptr1, ptr2, VALUE, NAME_ERR_MESG_COUNT);
return obj1;
}
@@ -2285,18 +2030,19 @@ name_err_mesg_init_copy(VALUE obj1, VALUE obj2)
static VALUE
name_err_mesg_equal(VALUE obj1, VALUE obj2)
{
- if (obj1 == obj2) return Qtrue;
+ VALUE *ptr1, *ptr2;
+ int i;
+ if (obj1 == obj2) return Qtrue;
if (rb_obj_class(obj2) != rb_cNameErrorMesg)
return Qfalse;
- name_error_message_t *ptr1, *ptr2;
- TypedData_Get_Struct(obj1, name_error_message_t, &name_err_mesg_data_type, ptr1);
- TypedData_Get_Struct(obj2, name_error_message_t, &name_err_mesg_data_type, ptr2);
-
- if (!rb_equal(ptr1->mesg, ptr2->mesg)) return Qfalse;
- if (!rb_equal(ptr1->recv, ptr2->recv)) return Qfalse;
- if (!rb_equal(ptr1->name, ptr2->name)) return Qfalse;
+ TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
+ TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
+ for (i=0; i<NAME_ERR_MESG_COUNT; i++) {
+ if (!rb_equal(ptr1[i], ptr2[i]))
+ return Qfalse;
+ }
return Qtrue;
}
@@ -2315,91 +2061,51 @@ name_err_mesg_receiver_name(VALUE obj)
static VALUE
name_err_mesg_to_str(VALUE obj)
{
- name_error_message_t *ptr;
- TypedData_Get_Struct(obj, name_error_message_t, &name_err_mesg_data_type, ptr);
+ VALUE *ptr, mesg;
+ TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr);
- VALUE mesg = ptr->mesg;
+ mesg = ptr[NAME_ERR_MESG__MESG];
if (NIL_P(mesg)) return Qnil;
else {
- struct RString s_str, c_str, d_str;
- VALUE c, s, d = 0, args[4], c2;
- int state = 0;
+ struct RString s_str, d_str;
+ VALUE c, s, d = 0, args[4];
+ int state = 0, singleton = 0;
rb_encoding *usascii = rb_usascii_encoding();
#define FAKE_CSTR(v, str) rb_setup_fake_str((v), (str), rb_strlen_lit(str), usascii)
- c = s = FAKE_CSTR(&s_str, "");
- obj = ptr->recv;
+ obj = ptr[NAME_ERR_MESG__RECV];
switch (obj) {
case Qnil:
- c = d = FAKE_CSTR(&d_str, "nil");
+ d = FAKE_CSTR(&d_str, "nil");
break;
case Qtrue:
- c = d = FAKE_CSTR(&d_str, "true");
+ d = FAKE_CSTR(&d_str, "true");
break;
case Qfalse:
- c = d = FAKE_CSTR(&d_str, "false");
+ d = FAKE_CSTR(&d_str, "false");
break;
default:
- if (strstr(RSTRING_PTR(mesg), "%2$s")) {
- d = rb_protect(name_err_mesg_receiver_name, obj, &state);
- if (state || NIL_OR_UNDEF_P(d))
- d = rb_protect(rb_inspect, obj, &state);
- if (state) {
- rb_set_errinfo(Qnil);
- }
- d = rb_check_string_type(d);
- if (NIL_P(d)) {
- d = rb_any_to_s(obj);
- }
- }
-
- if (!RB_SPECIAL_CONST_P(obj)) {
- switch (RB_BUILTIN_TYPE(obj)) {
- case T_MODULE:
- s = FAKE_CSTR(&s_str, "module ");
- c = obj;
- break;
- case T_CLASS:
- s = FAKE_CSTR(&s_str, "class ");
- c = obj;
- break;
- default:
- goto object;
- }
- }
- else {
- VALUE klass;
- object:
- klass = CLASS_OF(obj);
- if (RB_TYPE_P(klass, T_CLASS) && FL_TEST(klass, FL_SINGLETON)) {
- s = FAKE_CSTR(&s_str, "");
- if (obj == rb_vm_top_self()) {
- c = FAKE_CSTR(&c_str, "main");
- }
- else {
- c = rb_any_to_s(obj);
- }
- break;
- }
- else {
- s = FAKE_CSTR(&s_str, "an instance of ");
- c = rb_class_real(klass);
- }
- }
- c2 = rb_protect(name_err_mesg_receiver_name, c, &state);
- if (state || NIL_OR_UNDEF_P(c2))
- c2 = rb_protect(rb_inspect, c, &state);
+ d = rb_protect(name_err_mesg_receiver_name, obj, &state);
+ if (state || NIL_OR_UNDEF_P(d))
+ d = rb_protect(rb_inspect, obj, &state);
if (state) {
rb_set_errinfo(Qnil);
}
- c2 = rb_check_string_type(c2);
- if (NIL_P(c2)) {
- c2 = rb_any_to_s(c);
+ d = rb_check_string_type(d);
+ if (NIL_P(d)) {
+ d = rb_any_to_s(obj);
}
- c = c2;
+ singleton = (RSTRING_LEN(d) > 0 && RSTRING_PTR(d)[0] == '#');
break;
}
- args[0] = rb_obj_as_string(ptr->name);
+ if (!singleton) {
+ s = FAKE_CSTR(&s_str, ":");
+ c = rb_class_name(CLASS_OF(obj));
+ }
+ else {
+ c = s = FAKE_CSTR(&s_str, "");
+ }
+ args[0] = rb_obj_as_string(ptr[NAME_ERR_MESG__NAME]);
args[1] = d;
args[2] = s;
args[3] = c;
@@ -2432,17 +2138,17 @@ name_err_mesg_load(VALUE klass, VALUE str)
static VALUE
name_err_receiver(VALUE self)
{
- VALUE recv = rb_ivar_lookup(self, id_recv, Qundef);
+ VALUE *ptr, recv, mesg;
+
+ recv = rb_ivar_lookup(self, id_recv, Qundef);
if (!UNDEF_P(recv)) return recv;
- VALUE mesg = rb_attr_get(self, id_mesg);
+ mesg = rb_attr_get(self, id_mesg);
if (!rb_typeddata_is_kind_of(mesg, &name_err_mesg_data_type)) {
rb_raise(rb_eArgError, "no receiver is available");
}
-
- name_error_message_t *ptr;
- TypedData_Get_Struct(mesg, name_error_message_t, &name_err_mesg_data_type, ptr);
- return ptr->recv;
+ ptr = DATA_PTR(mesg);
+ return ptr[NAME_ERR_MESG__RECV];
}
/*
@@ -2694,14 +2400,6 @@ syntax_error_with_path(VALUE exc, VALUE path, VALUE *mesg, rb_encoding *enc)
static st_table *syserr_tbl;
-void
-rb_free_warning(void)
-{
- st_free_table(warning_categories.id2enum);
- st_free_table(warning_categories.enum2id);
- st_free_table(syserr_tbl);
-}
-
static VALUE
set_syserr(int n, const char *name)
{
@@ -3061,7 +2759,7 @@ syserr_eqq(VALUE self, VALUE exc)
*
* <em>raises the exception:</em>
*
- * NoMethodError: undefined method `to_ary' for an instance of String
+ * NoMethodError: undefined method `to_ary' for "hello":String
*/
/*
@@ -3257,9 +2955,9 @@ exception_dumper(VALUE exc)
}
static int
-ivar_copy_i(ID key, VALUE val, st_data_t exc)
+ivar_copy_i(st_data_t key, st_data_t val, st_data_t exc)
{
- rb_ivar_set((VALUE)exc, key, val);
+ rb_ivar_set((VALUE) exc, (ID) key, (VALUE) val);
return ST_CONTINUE;
}
@@ -3411,7 +3109,6 @@ Init_Exception(void)
id_category = rb_intern_const("category");
id_deprecated = rb_intern_const("deprecated");
id_experimental = rb_intern_const("experimental");
- id_performance = rb_intern_const("performance");
id_top = rb_intern_const("top");
id_bottom = rb_intern_const("bottom");
id_iseq = rb_make_internal_id();
@@ -3423,13 +3120,11 @@ Init_Exception(void)
warning_categories.id2enum = rb_init_identtable();
st_add_direct(warning_categories.id2enum, id_deprecated, RB_WARN_CATEGORY_DEPRECATED);
st_add_direct(warning_categories.id2enum, id_experimental, RB_WARN_CATEGORY_EXPERIMENTAL);
- st_add_direct(warning_categories.id2enum, id_performance, RB_WARN_CATEGORY_PERFORMANCE);
warning_categories.enum2id = rb_init_identtable();
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_NONE, 0);
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_DEPRECATED, id_deprecated);
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_EXPERIMENTAL, id_experimental);
- st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_PERFORMANCE, id_performance);
}
void
@@ -3512,7 +3207,7 @@ rb_fatal(const char *fmt, ...)
/* The thread has no GVL. Object allocation impossible (cant run GC),
* thus no message can be printed out. */
fprintf(stderr, "[FATAL] rb_fatal() outside of GVL\n");
- rb_print_backtrace(stderr);
+ rb_print_backtrace();
die();
}
@@ -3575,14 +3270,12 @@ rb_syserr_fail_str(int e, VALUE mesg)
rb_exc_raise(rb_syserr_new_str(e, mesg));
}
-#undef rb_sys_fail
void
rb_sys_fail(const char *mesg)
{
rb_exc_raise(make_errno_exc(mesg));
}
-#undef rb_sys_fail_str
void
rb_sys_fail_str(VALUE mesg)
{
diff --git a/eval.c b/eval.c
index a8fc48daf5..a61dfb1289 100644
--- a/eval.c
+++ b/eval.c
@@ -18,12 +18,12 @@
#endif
#include "eval_intern.h"
+#include "gc.h"
#include "internal.h"
#include "internal/class.h"
#include "internal/cont.h"
#include "internal/error.h"
#include "internal/eval.h"
-#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/inits.h"
#include "internal/io.h"
@@ -32,7 +32,7 @@
#include "internal/variable.h"
#include "ruby/fiber/scheduler.h"
#include "iseq.h"
-#include "rjit.h"
+#include "mjit.h"
#include "probes.h"
#include "probes_helper.h"
#include "ruby/vm.h"
@@ -257,6 +257,8 @@ rb_ec_cleanup(rb_execution_context_t *ec, enum ruby_tag_type ex)
}
}
+ mjit_finish(true); // We still need ISeqs here, so it's before rb_ec_finalize().
+
rb_ec_finalize(ec);
/* unlock again if finalizer took mutexes. */
@@ -439,7 +441,7 @@ rb_class_modify_check(VALUE klass)
if (FL_TEST(klass, FL_SINGLETON)) {
desc = "object";
- klass = RCLASS_ATTACHED_OBJECT(klass);
+ klass = rb_ivar_get(klass, id__attached__);
if (!SPECIAL_CONST_P(klass)) {
switch (BUILTIN_TYPE(klass)) {
case T_MODULE:
@@ -1341,21 +1343,14 @@ rb_using_module(const rb_cref_t *cref, VALUE module)
{
Check_Type(module, T_MODULE);
using_module_recursive(cref, module);
- rb_clear_all_refinement_method_cache();
+ rb_clear_method_cache_all();
}
/*
* call-seq:
- * target -> class_or_module
- *
- * Return the class or module refined by the receiver.
- *
- * module M
- * refine String do
- * end
- * end
+ * refined_class -> class
*
- * M.refinements[0].target # => String
+ * Return the class refined by the receiver.
*/
VALUE
rb_refinement_module_get_refined_class(VALUE module)
@@ -1366,21 +1361,6 @@ rb_refinement_module_get_refined_class(VALUE module)
return rb_attr_get(module, id_refined_class);
}
-/*
- * call-seq:
- * refined_class -> class
- *
- * Deprecated; prefer #target.
- *
- * Return the class refined by the receiver.
- */
-static VALUE
-rb_refinement_refined_class(VALUE module)
-{
- rb_warn_deprecated_to_remove("3.4", "Refinement#refined_class", "Refinement#target");
- return rb_refinement_module_get_refined_class(module);
-}
-
static void
add_activated_refinement(VALUE activated_refinements,
VALUE klass, VALUE refinement)
@@ -2093,8 +2073,7 @@ Init_eval(void)
rb_mod_s_used_refinements, 0);
rb_undef_method(rb_cClass, "refine");
rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
- rb_define_method(rb_cRefinement, "target", rb_refinement_module_get_refined_class, 0);
- rb_define_method(rb_cRefinement, "refined_class", rb_refinement_refined_class, 0);
+ rb_define_method(rb_cRefinement, "refined_class", rb_refinement_module_get_refined_class, 0);
rb_undef_method(rb_cRefinement, "append_features");
rb_undef_method(rb_cRefinement, "prepend_features");
rb_undef_method(rb_cRefinement, "extend_object");
@@ -2123,21 +2102,3 @@ Init_eval(void)
id_signo = rb_intern_const("signo");
id_status = rb_intern_const("status");
}
-
-int
-rb_errno(void)
-{
- return *rb_orig_errno_ptr();
-}
-
-void
-rb_errno_set(int e)
-{
- *rb_orig_errno_ptr() = e;
-}
-
-int *
-rb_errno_ptr(void)
-{
- return rb_orig_errno_ptr();
-}
diff --git a/eval_error.c b/eval_error.c
index bdce295f6e..9806683000 100644
--- a/eval_error.c
+++ b/eval_error.c
@@ -7,8 +7,6 @@
(NIL_P(str) ? warn_print(x) : (void)rb_str_cat_cstr(str, x))
#define write_warn2(str, x, l) \
(NIL_P(str) ? warn_print2(x, l) : (void)rb_str_cat(str, x, l))
-#define write_warn_enc(str, x, l, enc) \
- (NIL_P(str) ? warn_print2(x, l) : (void)rb_enc_str_buf_cat(str, x, l, enc))
#ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
#define warn_print(x) RB_GNUC_EXTENSION_BLOCK( \
(__builtin_constant_p(x)) ? \
@@ -105,7 +103,7 @@ print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, const VA
if (highlight) write_warn(str, underline);
write_warn(str, "unhandled exception");
if (highlight) write_warn(str, reset);
- write_warn(str, "\n");
+ write_warn2(str, "\n", 1);
}
else {
VALUE epath;
@@ -129,17 +127,13 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight)
{
const char *einfo = "";
long elen = 0;
- rb_encoding *eenc;
- VALUE str = rb_usascii_str_new_cstr("");
+ VALUE str = rb_str_new2("");
- if (!NIL_P(emesg) && rb_enc_asciicompat(eenc = rb_enc_get(emesg))) {
+ if (!NIL_P(emesg)) {
einfo = RSTRING_PTR(emesg);
elen = RSTRING_LEN(emesg);
}
- else {
- eenc = NULL;
- }
if (eclass == rb_eRuntimeError && elen == 0) {
if (highlight) write_warn(str, underline);
write_warn(str, "unhandled exception");
@@ -162,7 +156,7 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight)
if (RSTRING_PTR(epath)[0] == '#')
epath = 0;
if ((tail = memchr(einfo, '\n', elen)) != 0) {
- write_warn_enc(str, einfo, tail - einfo, eenc);
+ write_warn2(str, einfo, tail - einfo);
tail++; /* skip newline */
}
else {
@@ -176,23 +170,23 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight)
write_warn(str, reset);
write_warn(str, bold);
}
- write_warn(str, ")");
+ write_warn2(str, ")", 1);
if (highlight) write_warn(str, reset);
}
if (tail && einfo+elen > tail) {
if (!highlight) {
- write_warn(str, "\n");
- write_warn_enc(str, tail, einfo+elen-tail, eenc);
+ write_warn2(str, "\n", 1);
+ write_warn2(str, tail, einfo+elen-tail);
}
else {
elen -= tail - einfo;
einfo = tail;
- write_warn(str, "\n");
+ write_warn2(str, "\n", 1);
while (elen > 0) {
tail = memchr(einfo, '\n', elen);
if (!tail || tail > einfo) {
write_warn(str, bold);
- write_warn_enc(str, einfo, tail ? tail-einfo : elen, eenc);
+ write_warn2(str, einfo, tail ? tail-einfo : elen);
write_warn(str, reset);
if (!tail) {
break;
@@ -201,7 +195,7 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight)
elen -= tail - einfo;
einfo = tail;
do ++tail; while (tail < einfo+elen && *tail == '\n');
- write_warn_enc(str, einfo, tail-einfo, eenc);
+ write_warn2(str, einfo, tail-einfo);
elen -= tail - einfo;
einfo = tail;
}
diff --git a/eval_intern.h b/eval_intern.h
index d008b17ca1..6cbaa51361 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -110,11 +110,9 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval
_tag.tag = Qundef; \
_tag.prev = _ec->tag; \
_tag.lock_rec = rb_ec_vm_lock_rec(_ec); \
- rb_vm_tag_jmpbuf_init(&_tag.buf); \
#define EC_POP_TAG() \
_ec->tag = _tag.prev; \
- rb_vm_tag_jmpbuf_deinit(&_tag.buf); \
} while (0)
#define EC_TMPPOP_TAG() \
@@ -153,7 +151,6 @@ rb_ec_tag_state(const rb_execution_context_t *ec)
enum ruby_tag_type state = tag->state;
tag->state = TAG_NONE;
rb_ec_vm_lock_rec_check(ec, tag->lock_rec);
- RBIMPL_ASSUME(state != TAG_NONE);
return state;
}
@@ -161,9 +158,8 @@ NORETURN(static inline void rb_ec_tag_jump(const rb_execution_context_t *ec, enu
static inline void
rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st)
{
- RUBY_ASSERT(st != TAG_NONE);
ec->tag->state = st;
- ruby_longjmp(RB_VM_TAG_JMPBUF_GET(ec->tag->buf), 1);
+ ruby_longjmp(ec->tag->buf, 1);
}
/*
@@ -171,7 +167,7 @@ rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st)
[ISO/IEC 9899:1999] 7.13.1.1
*/
#define EC_EXEC_TAG() \
- (UNLIKELY(ruby_setjmp(RB_VM_TAG_JMPBUF_GET(_tag.buf))) ? rb_ec_tag_state(VAR_FROM_MEMORY(_ec)) : (EC_REPUSH_TAG(), 0))
+ (ruby_setjmp(_tag.buf) ? rb_ec_tag_state(VAR_FROM_MEMORY(_ec)) : (EC_REPUSH_TAG(), 0))
#define EC_JUMP_TAG(ec, st) rb_ec_tag_jump(ec, st)
diff --git a/ext/-test-/RUBY_ALIGNOF/depend b/ext/-test-/RUBY_ALIGNOF/depend
index 3011b637e5..21ef8c6dd0 100644
--- a/ext/-test-/RUBY_ALIGNOF/depend
+++ b/ext/-test-/RUBY_ALIGNOF/depend
@@ -52,7 +52,6 @@ c.o: $(hdrdir)/ruby/internal/attr/noexcept.h
c.o: $(hdrdir)/ruby/internal/attr/noinline.h
c.o: $(hdrdir)/ruby/internal/attr/nonnull.h
c.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-c.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
c.o: $(hdrdir)/ruby/internal/attr/pure.h
c.o: $(hdrdir)/ruby/internal/attr/restrict.h
c.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ c.o: $(hdrdir)/ruby/internal/intern/enumerator.h
c.o: $(hdrdir)/ruby/internal/intern/error.h
c.o: $(hdrdir)/ruby/internal/intern/eval.h
c.o: $(hdrdir)/ruby/internal/intern/file.h
+c.o: $(hdrdir)/ruby/internal/intern/gc.h
c.o: $(hdrdir)/ruby/internal/intern/hash.h
c.o: $(hdrdir)/ruby/internal/intern/io.h
c.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ c.o: $(hdrdir)/ruby/internal/memory.h
c.o: $(hdrdir)/ruby/internal/method.h
c.o: $(hdrdir)/ruby/internal/module.h
c.o: $(hdrdir)/ruby/internal/newobj.h
+c.o: $(hdrdir)/ruby/internal/rgengc.h
c.o: $(hdrdir)/ruby/internal/scan_args.h
c.o: $(hdrdir)/ruby/internal/special_consts.h
c.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/arith_seq/beg_len_step/depend b/ext/-test-/arith_seq/beg_len_step/depend
index dc807eaa99..36a2c4c71b 100644
--- a/ext/-test-/arith_seq/beg_len_step/depend
+++ b/ext/-test-/arith_seq/beg_len_step/depend
@@ -51,7 +51,6 @@ beg_len_step.o: $(hdrdir)/ruby/internal/attr/noexcept.h
beg_len_step.o: $(hdrdir)/ruby/internal/attr/noinline.h
beg_len_step.o: $(hdrdir)/ruby/internal/attr/nonnull.h
beg_len_step.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-beg_len_step.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
beg_len_step.o: $(hdrdir)/ruby/internal/attr/pure.h
beg_len_step.o: $(hdrdir)/ruby/internal/attr/restrict.h
beg_len_step.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ beg_len_step.o: $(hdrdir)/ruby/internal/intern/enumerator.h
beg_len_step.o: $(hdrdir)/ruby/internal/intern/error.h
beg_len_step.o: $(hdrdir)/ruby/internal/intern/eval.h
beg_len_step.o: $(hdrdir)/ruby/internal/intern/file.h
+beg_len_step.o: $(hdrdir)/ruby/internal/intern/gc.h
beg_len_step.o: $(hdrdir)/ruby/internal/intern/hash.h
beg_len_step.o: $(hdrdir)/ruby/internal/intern/io.h
beg_len_step.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ beg_len_step.o: $(hdrdir)/ruby/internal/memory.h
beg_len_step.o: $(hdrdir)/ruby/internal/method.h
beg_len_step.o: $(hdrdir)/ruby/internal/module.h
beg_len_step.o: $(hdrdir)/ruby/internal/newobj.h
+beg_len_step.o: $(hdrdir)/ruby/internal/rgengc.h
beg_len_step.o: $(hdrdir)/ruby/internal/scan_args.h
beg_len_step.o: $(hdrdir)/ruby/internal/special_consts.h
beg_len_step.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/arith_seq/extract/depend b/ext/-test-/arith_seq/extract/depend
index 231736b277..57cbaa9a0c 100644
--- a/ext/-test-/arith_seq/extract/depend
+++ b/ext/-test-/arith_seq/extract/depend
@@ -51,7 +51,6 @@ extract.o: $(hdrdir)/ruby/internal/attr/noexcept.h
extract.o: $(hdrdir)/ruby/internal/attr/noinline.h
extract.o: $(hdrdir)/ruby/internal/attr/nonnull.h
extract.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-extract.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
extract.o: $(hdrdir)/ruby/internal/attr/pure.h
extract.o: $(hdrdir)/ruby/internal/attr/restrict.h
extract.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ extract.o: $(hdrdir)/ruby/internal/intern/enumerator.h
extract.o: $(hdrdir)/ruby/internal/intern/error.h
extract.o: $(hdrdir)/ruby/internal/intern/eval.h
extract.o: $(hdrdir)/ruby/internal/intern/file.h
+extract.o: $(hdrdir)/ruby/internal/intern/gc.h
extract.o: $(hdrdir)/ruby/internal/intern/hash.h
extract.o: $(hdrdir)/ruby/internal/intern/io.h
extract.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ extract.o: $(hdrdir)/ruby/internal/memory.h
extract.o: $(hdrdir)/ruby/internal/method.h
extract.o: $(hdrdir)/ruby/internal/module.h
extract.o: $(hdrdir)/ruby/internal/newobj.h
+extract.o: $(hdrdir)/ruby/internal/rgengc.h
extract.o: $(hdrdir)/ruby/internal/scan_args.h
extract.o: $(hdrdir)/ruby/internal/special_consts.h
extract.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/array/concat/depend b/ext/-test-/array/concat/depend
index d66e7a540f..79c833738e 100644
--- a/ext/-test-/array/concat/depend
+++ b/ext/-test-/array/concat/depend
@@ -52,7 +52,6 @@ to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noinline.h
to_ary_concat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-to_ary_concat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
to_ary_concat.o: $(hdrdir)/ruby/internal/attr/pure.h
to_ary_concat.o: $(hdrdir)/ruby/internal/attr/restrict.h
to_ary_concat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ to_ary_concat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
to_ary_concat.o: $(hdrdir)/ruby/internal/intern/error.h
to_ary_concat.o: $(hdrdir)/ruby/internal/intern/eval.h
to_ary_concat.o: $(hdrdir)/ruby/internal/intern/file.h
+to_ary_concat.o: $(hdrdir)/ruby/internal/intern/gc.h
to_ary_concat.o: $(hdrdir)/ruby/internal/intern/hash.h
to_ary_concat.o: $(hdrdir)/ruby/internal/intern/io.h
to_ary_concat.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ to_ary_concat.o: $(hdrdir)/ruby/internal/memory.h
to_ary_concat.o: $(hdrdir)/ruby/internal/method.h
to_ary_concat.o: $(hdrdir)/ruby/internal/module.h
to_ary_concat.o: $(hdrdir)/ruby/internal/newobj.h
+to_ary_concat.o: $(hdrdir)/ruby/internal/rgengc.h
to_ary_concat.o: $(hdrdir)/ruby/internal/scan_args.h
to_ary_concat.o: $(hdrdir)/ruby/internal/special_consts.h
to_ary_concat.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/array/resize/depend b/ext/-test-/array/resize/depend
index a9c02b3db2..49e0f346d3 100644
--- a/ext/-test-/array/resize/depend
+++ b/ext/-test-/array/resize/depend
@@ -51,7 +51,6 @@ resize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
resize.o: $(hdrdir)/ruby/internal/attr/noinline.h
resize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
resize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-resize.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
resize.o: $(hdrdir)/ruby/internal/attr/pure.h
resize.o: $(hdrdir)/ruby/internal/attr/restrict.h
resize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ resize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
resize.o: $(hdrdir)/ruby/internal/intern/error.h
resize.o: $(hdrdir)/ruby/internal/intern/eval.h
resize.o: $(hdrdir)/ruby/internal/intern/file.h
+resize.o: $(hdrdir)/ruby/internal/intern/gc.h
resize.o: $(hdrdir)/ruby/internal/intern/hash.h
resize.o: $(hdrdir)/ruby/internal/intern/io.h
resize.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ resize.o: $(hdrdir)/ruby/internal/memory.h
resize.o: $(hdrdir)/ruby/internal/method.h
resize.o: $(hdrdir)/ruby/internal/module.h
resize.o: $(hdrdir)/ruby/internal/newobj.h
+resize.o: $(hdrdir)/ruby/internal/rgengc.h
resize.o: $(hdrdir)/ruby/internal/scan_args.h
resize.o: $(hdrdir)/ruby/internal/special_consts.h
resize.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/bignum/depend b/ext/-test-/bignum/depend
index d4392bb6a1..d4072fb35c 100644
--- a/ext/-test-/bignum/depend
+++ b/ext/-test-/bignum/depend
@@ -51,7 +51,6 @@ big2str.o: $(hdrdir)/ruby/internal/attr/noexcept.h
big2str.o: $(hdrdir)/ruby/internal/attr/noinline.h
big2str.o: $(hdrdir)/ruby/internal/attr/nonnull.h
big2str.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-big2str.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
big2str.o: $(hdrdir)/ruby/internal/attr/pure.h
big2str.o: $(hdrdir)/ruby/internal/attr/restrict.h
big2str.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ big2str.o: $(hdrdir)/ruby/internal/intern/enumerator.h
big2str.o: $(hdrdir)/ruby/internal/intern/error.h
big2str.o: $(hdrdir)/ruby/internal/intern/eval.h
big2str.o: $(hdrdir)/ruby/internal/intern/file.h
+big2str.o: $(hdrdir)/ruby/internal/intern/gc.h
big2str.o: $(hdrdir)/ruby/internal/intern/hash.h
big2str.o: $(hdrdir)/ruby/internal/intern/io.h
big2str.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ big2str.o: $(hdrdir)/ruby/internal/memory.h
big2str.o: $(hdrdir)/ruby/internal/method.h
big2str.o: $(hdrdir)/ruby/internal/module.h
big2str.o: $(hdrdir)/ruby/internal/newobj.h
+big2str.o: $(hdrdir)/ruby/internal/rgengc.h
big2str.o: $(hdrdir)/ruby/internal/scan_args.h
big2str.o: $(hdrdir)/ruby/internal/special_consts.h
big2str.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -210,7 +211,6 @@ bigzero.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bigzero.o: $(hdrdir)/ruby/internal/attr/noinline.h
bigzero.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bigzero.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bigzero.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bigzero.o: $(hdrdir)/ruby/internal/attr/pure.h
bigzero.o: $(hdrdir)/ruby/internal/attr/restrict.h
bigzero.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -270,6 +270,7 @@ bigzero.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bigzero.o: $(hdrdir)/ruby/internal/intern/error.h
bigzero.o: $(hdrdir)/ruby/internal/intern/eval.h
bigzero.o: $(hdrdir)/ruby/internal/intern/file.h
+bigzero.o: $(hdrdir)/ruby/internal/intern/gc.h
bigzero.o: $(hdrdir)/ruby/internal/intern/hash.h
bigzero.o: $(hdrdir)/ruby/internal/intern/io.h
bigzero.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -300,6 +301,7 @@ bigzero.o: $(hdrdir)/ruby/internal/memory.h
bigzero.o: $(hdrdir)/ruby/internal/method.h
bigzero.o: $(hdrdir)/ruby/internal/module.h
bigzero.o: $(hdrdir)/ruby/internal/newobj.h
+bigzero.o: $(hdrdir)/ruby/internal/rgengc.h
bigzero.o: $(hdrdir)/ruby/internal/scan_args.h
bigzero.o: $(hdrdir)/ruby/internal/special_consts.h
bigzero.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -369,7 +371,6 @@ div.o: $(hdrdir)/ruby/internal/attr/noexcept.h
div.o: $(hdrdir)/ruby/internal/attr/noinline.h
div.o: $(hdrdir)/ruby/internal/attr/nonnull.h
div.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-div.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
div.o: $(hdrdir)/ruby/internal/attr/pure.h
div.o: $(hdrdir)/ruby/internal/attr/restrict.h
div.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -429,6 +430,7 @@ div.o: $(hdrdir)/ruby/internal/intern/enumerator.h
div.o: $(hdrdir)/ruby/internal/intern/error.h
div.o: $(hdrdir)/ruby/internal/intern/eval.h
div.o: $(hdrdir)/ruby/internal/intern/file.h
+div.o: $(hdrdir)/ruby/internal/intern/gc.h
div.o: $(hdrdir)/ruby/internal/intern/hash.h
div.o: $(hdrdir)/ruby/internal/intern/io.h
div.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -459,6 +461,7 @@ div.o: $(hdrdir)/ruby/internal/memory.h
div.o: $(hdrdir)/ruby/internal/method.h
div.o: $(hdrdir)/ruby/internal/module.h
div.o: $(hdrdir)/ruby/internal/newobj.h
+div.o: $(hdrdir)/ruby/internal/rgengc.h
div.o: $(hdrdir)/ruby/internal/scan_args.h
div.o: $(hdrdir)/ruby/internal/special_consts.h
div.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -529,7 +532,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -589,6 +591,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -619,6 +622,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -687,7 +691,6 @@ intpack.o: $(hdrdir)/ruby/internal/attr/noexcept.h
intpack.o: $(hdrdir)/ruby/internal/attr/noinline.h
intpack.o: $(hdrdir)/ruby/internal/attr/nonnull.h
intpack.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-intpack.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
intpack.o: $(hdrdir)/ruby/internal/attr/pure.h
intpack.o: $(hdrdir)/ruby/internal/attr/restrict.h
intpack.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -747,6 +750,7 @@ intpack.o: $(hdrdir)/ruby/internal/intern/enumerator.h
intpack.o: $(hdrdir)/ruby/internal/intern/error.h
intpack.o: $(hdrdir)/ruby/internal/intern/eval.h
intpack.o: $(hdrdir)/ruby/internal/intern/file.h
+intpack.o: $(hdrdir)/ruby/internal/intern/gc.h
intpack.o: $(hdrdir)/ruby/internal/intern/hash.h
intpack.o: $(hdrdir)/ruby/internal/intern/io.h
intpack.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -777,6 +781,7 @@ intpack.o: $(hdrdir)/ruby/internal/memory.h
intpack.o: $(hdrdir)/ruby/internal/method.h
intpack.o: $(hdrdir)/ruby/internal/module.h
intpack.o: $(hdrdir)/ruby/internal/newobj.h
+intpack.o: $(hdrdir)/ruby/internal/rgengc.h
intpack.o: $(hdrdir)/ruby/internal/scan_args.h
intpack.o: $(hdrdir)/ruby/internal/special_consts.h
intpack.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -846,7 +851,6 @@ mul.o: $(hdrdir)/ruby/internal/attr/noexcept.h
mul.o: $(hdrdir)/ruby/internal/attr/noinline.h
mul.o: $(hdrdir)/ruby/internal/attr/nonnull.h
mul.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-mul.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
mul.o: $(hdrdir)/ruby/internal/attr/pure.h
mul.o: $(hdrdir)/ruby/internal/attr/restrict.h
mul.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -906,6 +910,7 @@ mul.o: $(hdrdir)/ruby/internal/intern/enumerator.h
mul.o: $(hdrdir)/ruby/internal/intern/error.h
mul.o: $(hdrdir)/ruby/internal/intern/eval.h
mul.o: $(hdrdir)/ruby/internal/intern/file.h
+mul.o: $(hdrdir)/ruby/internal/intern/gc.h
mul.o: $(hdrdir)/ruby/internal/intern/hash.h
mul.o: $(hdrdir)/ruby/internal/intern/io.h
mul.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -936,6 +941,7 @@ mul.o: $(hdrdir)/ruby/internal/memory.h
mul.o: $(hdrdir)/ruby/internal/method.h
mul.o: $(hdrdir)/ruby/internal/module.h
mul.o: $(hdrdir)/ruby/internal/newobj.h
+mul.o: $(hdrdir)/ruby/internal/rgengc.h
mul.o: $(hdrdir)/ruby/internal/scan_args.h
mul.o: $(hdrdir)/ruby/internal/special_consts.h
mul.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1005,7 +1011,6 @@ str2big.o: $(hdrdir)/ruby/internal/attr/noexcept.h
str2big.o: $(hdrdir)/ruby/internal/attr/noinline.h
str2big.o: $(hdrdir)/ruby/internal/attr/nonnull.h
str2big.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-str2big.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
str2big.o: $(hdrdir)/ruby/internal/attr/pure.h
str2big.o: $(hdrdir)/ruby/internal/attr/restrict.h
str2big.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1065,6 +1070,7 @@ str2big.o: $(hdrdir)/ruby/internal/intern/enumerator.h
str2big.o: $(hdrdir)/ruby/internal/intern/error.h
str2big.o: $(hdrdir)/ruby/internal/intern/eval.h
str2big.o: $(hdrdir)/ruby/internal/intern/file.h
+str2big.o: $(hdrdir)/ruby/internal/intern/gc.h
str2big.o: $(hdrdir)/ruby/internal/intern/hash.h
str2big.o: $(hdrdir)/ruby/internal/intern/io.h
str2big.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1095,6 +1101,7 @@ str2big.o: $(hdrdir)/ruby/internal/memory.h
str2big.o: $(hdrdir)/ruby/internal/method.h
str2big.o: $(hdrdir)/ruby/internal/module.h
str2big.o: $(hdrdir)/ruby/internal/newobj.h
+str2big.o: $(hdrdir)/ruby/internal/rgengc.h
str2big.o: $(hdrdir)/ruby/internal/scan_args.h
str2big.o: $(hdrdir)/ruby/internal/special_consts.h
str2big.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/bug-14834/depend b/ext/-test-/bug-14834/depend
index bf26a571aa..7bac8409e8 100644
--- a/ext/-test-/bug-14834/depend
+++ b/ext/-test-/bug-14834/depend
@@ -52,7 +52,6 @@ bug-14384.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bug-14384.o: $(hdrdir)/ruby/internal/attr/noinline.h
bug-14384.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bug-14384.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bug-14384.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bug-14384.o: $(hdrdir)/ruby/internal/attr/pure.h
bug-14384.o: $(hdrdir)/ruby/internal/attr/restrict.h
bug-14384.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ bug-14384.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bug-14384.o: $(hdrdir)/ruby/internal/intern/error.h
bug-14384.o: $(hdrdir)/ruby/internal/intern/eval.h
bug-14384.o: $(hdrdir)/ruby/internal/intern/file.h
+bug-14384.o: $(hdrdir)/ruby/internal/intern/gc.h
bug-14384.o: $(hdrdir)/ruby/internal/intern/hash.h
bug-14384.o: $(hdrdir)/ruby/internal/intern/io.h
bug-14384.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ bug-14384.o: $(hdrdir)/ruby/internal/memory.h
bug-14384.o: $(hdrdir)/ruby/internal/method.h
bug-14384.o: $(hdrdir)/ruby/internal/module.h
bug-14384.o: $(hdrdir)/ruby/internal/newobj.h
+bug-14384.o: $(hdrdir)/ruby/internal/rgengc.h
bug-14384.o: $(hdrdir)/ruby/internal/scan_args.h
bug-14384.o: $(hdrdir)/ruby/internal/special_consts.h
bug-14384.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/bug-3571/depend b/ext/-test-/bug-3571/depend
index 9105093b0d..2303f47594 100644
--- a/ext/-test-/bug-3571/depend
+++ b/ext/-test-/bug-3571/depend
@@ -52,7 +52,6 @@ bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bug.o: $(hdrdir)/ruby/internal/attr/noinline.h
bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bug.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bug.o: $(hdrdir)/ruby/internal/attr/pure.h
bug.o: $(hdrdir)/ruby/internal/attr/restrict.h
bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bug.o: $(hdrdir)/ruby/internal/intern/error.h
bug.o: $(hdrdir)/ruby/internal/intern/eval.h
bug.o: $(hdrdir)/ruby/internal/intern/file.h
+bug.o: $(hdrdir)/ruby/internal/intern/gc.h
bug.o: $(hdrdir)/ruby/internal/intern/hash.h
bug.o: $(hdrdir)/ruby/internal/intern/io.h
bug.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ bug.o: $(hdrdir)/ruby/internal/memory.h
bug.o: $(hdrdir)/ruby/internal/method.h
bug.o: $(hdrdir)/ruby/internal/module.h
bug.o: $(hdrdir)/ruby/internal/newobj.h
+bug.o: $(hdrdir)/ruby/internal/rgengc.h
bug.o: $(hdrdir)/ruby/internal/scan_args.h
bug.o: $(hdrdir)/ruby/internal/special_consts.h
bug.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/bug-5832/depend b/ext/-test-/bug-5832/depend
index 9105093b0d..2303f47594 100644
--- a/ext/-test-/bug-5832/depend
+++ b/ext/-test-/bug-5832/depend
@@ -52,7 +52,6 @@ bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bug.o: $(hdrdir)/ruby/internal/attr/noinline.h
bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bug.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bug.o: $(hdrdir)/ruby/internal/attr/pure.h
bug.o: $(hdrdir)/ruby/internal/attr/restrict.h
bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bug.o: $(hdrdir)/ruby/internal/intern/error.h
bug.o: $(hdrdir)/ruby/internal/intern/eval.h
bug.o: $(hdrdir)/ruby/internal/intern/file.h
+bug.o: $(hdrdir)/ruby/internal/intern/gc.h
bug.o: $(hdrdir)/ruby/internal/intern/hash.h
bug.o: $(hdrdir)/ruby/internal/intern/io.h
bug.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ bug.o: $(hdrdir)/ruby/internal/memory.h
bug.o: $(hdrdir)/ruby/internal/method.h
bug.o: $(hdrdir)/ruby/internal/module.h
bug.o: $(hdrdir)/ruby/internal/newobj.h
+bug.o: $(hdrdir)/ruby/internal/rgengc.h
bug.o: $(hdrdir)/ruby/internal/scan_args.h
bug.o: $(hdrdir)/ruby/internal/special_consts.h
bug.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/bug_reporter/depend b/ext/-test-/bug_reporter/depend
index 20882708d1..603dd53ebf 100644
--- a/ext/-test-/bug_reporter/depend
+++ b/ext/-test-/bug_reporter/depend
@@ -52,7 +52,6 @@ bug_reporter.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bug_reporter.o: $(hdrdir)/ruby/internal/attr/noinline.h
bug_reporter.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bug_reporter.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bug_reporter.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bug_reporter.o: $(hdrdir)/ruby/internal/attr/pure.h
bug_reporter.o: $(hdrdir)/ruby/internal/attr/restrict.h
bug_reporter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ bug_reporter.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bug_reporter.o: $(hdrdir)/ruby/internal/intern/error.h
bug_reporter.o: $(hdrdir)/ruby/internal/intern/eval.h
bug_reporter.o: $(hdrdir)/ruby/internal/intern/file.h
+bug_reporter.o: $(hdrdir)/ruby/internal/intern/gc.h
bug_reporter.o: $(hdrdir)/ruby/internal/intern/hash.h
bug_reporter.o: $(hdrdir)/ruby/internal/intern/io.h
bug_reporter.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ bug_reporter.o: $(hdrdir)/ruby/internal/memory.h
bug_reporter.o: $(hdrdir)/ruby/internal/method.h
bug_reporter.o: $(hdrdir)/ruby/internal/module.h
bug_reporter.o: $(hdrdir)/ruby/internal/newobj.h
+bug_reporter.o: $(hdrdir)/ruby/internal/rgengc.h
bug_reporter.o: $(hdrdir)/ruby/internal/scan_args.h
bug_reporter.o: $(hdrdir)/ruby/internal/special_consts.h
bug_reporter.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/class/depend b/ext/-test-/class/depend
index 0a805f815e..a615eacd74 100644
--- a/ext/-test-/class/depend
+++ b/ext/-test-/class/depend
@@ -51,7 +51,6 @@ class2name.o: $(hdrdir)/ruby/internal/attr/noexcept.h
class2name.o: $(hdrdir)/ruby/internal/attr/noinline.h
class2name.o: $(hdrdir)/ruby/internal/attr/nonnull.h
class2name.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-class2name.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
class2name.o: $(hdrdir)/ruby/internal/attr/pure.h
class2name.o: $(hdrdir)/ruby/internal/attr/restrict.h
class2name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ class2name.o: $(hdrdir)/ruby/internal/intern/enumerator.h
class2name.o: $(hdrdir)/ruby/internal/intern/error.h
class2name.o: $(hdrdir)/ruby/internal/intern/eval.h
class2name.o: $(hdrdir)/ruby/internal/intern/file.h
+class2name.o: $(hdrdir)/ruby/internal/intern/gc.h
class2name.o: $(hdrdir)/ruby/internal/intern/hash.h
class2name.o: $(hdrdir)/ruby/internal/intern/io.h
class2name.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ class2name.o: $(hdrdir)/ruby/internal/memory.h
class2name.o: $(hdrdir)/ruby/internal/method.h
class2name.o: $(hdrdir)/ruby/internal/module.h
class2name.o: $(hdrdir)/ruby/internal/newobj.h
+class2name.o: $(hdrdir)/ruby/internal/rgengc.h
class2name.o: $(hdrdir)/ruby/internal/scan_args.h
class2name.o: $(hdrdir)/ruby/internal/special_consts.h
class2name.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -210,7 +211,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -270,6 +270,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -300,6 +301,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/debug/depend b/ext/-test-/debug/depend
index 5feeea6d98..c3a0c278aa 100644
--- a/ext/-test-/debug/depend
+++ b/ext/-test-/debug/depend
@@ -52,7 +52,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ inspector.o: $(hdrdir)/ruby/internal/attr/noexcept.h
inspector.o: $(hdrdir)/ruby/internal/attr/noinline.h
inspector.o: $(hdrdir)/ruby/internal/attr/nonnull.h
inspector.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-inspector.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
inspector.o: $(hdrdir)/ruby/internal/attr/pure.h
inspector.o: $(hdrdir)/ruby/internal/attr/restrict.h
inspector.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ inspector.o: $(hdrdir)/ruby/internal/intern/enumerator.h
inspector.o: $(hdrdir)/ruby/internal/intern/error.h
inspector.o: $(hdrdir)/ruby/internal/intern/eval.h
inspector.o: $(hdrdir)/ruby/internal/intern/file.h
+inspector.o: $(hdrdir)/ruby/internal/intern/gc.h
inspector.o: $(hdrdir)/ruby/internal/intern/hash.h
inspector.o: $(hdrdir)/ruby/internal/intern/io.h
inspector.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ inspector.o: $(hdrdir)/ruby/internal/memory.h
inspector.o: $(hdrdir)/ruby/internal/method.h
inspector.o: $(hdrdir)/ruby/internal/module.h
inspector.o: $(hdrdir)/ruby/internal/newobj.h
+inspector.o: $(hdrdir)/ruby/internal/rgengc.h
inspector.o: $(hdrdir)/ruby/internal/scan_args.h
inspector.o: $(hdrdir)/ruby/internal/special_consts.h
inspector.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -370,7 +372,6 @@ profile_frames.o: $(hdrdir)/ruby/internal/attr/noexcept.h
profile_frames.o: $(hdrdir)/ruby/internal/attr/noinline.h
profile_frames.o: $(hdrdir)/ruby/internal/attr/nonnull.h
profile_frames.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-profile_frames.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
profile_frames.o: $(hdrdir)/ruby/internal/attr/pure.h
profile_frames.o: $(hdrdir)/ruby/internal/attr/restrict.h
profile_frames.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -430,6 +431,7 @@ profile_frames.o: $(hdrdir)/ruby/internal/intern/enumerator.h
profile_frames.o: $(hdrdir)/ruby/internal/intern/error.h
profile_frames.o: $(hdrdir)/ruby/internal/intern/eval.h
profile_frames.o: $(hdrdir)/ruby/internal/intern/file.h
+profile_frames.o: $(hdrdir)/ruby/internal/intern/gc.h
profile_frames.o: $(hdrdir)/ruby/internal/intern/hash.h
profile_frames.o: $(hdrdir)/ruby/internal/intern/io.h
profile_frames.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -460,6 +462,7 @@ profile_frames.o: $(hdrdir)/ruby/internal/memory.h
profile_frames.o: $(hdrdir)/ruby/internal/method.h
profile_frames.o: $(hdrdir)/ruby/internal/module.h
profile_frames.o: $(hdrdir)/ruby/internal/newobj.h
+profile_frames.o: $(hdrdir)/ruby/internal/rgengc.h
profile_frames.o: $(hdrdir)/ruby/internal/scan_args.h
profile_frames.o: $(hdrdir)/ruby/internal/special_consts.h
profile_frames.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/debug/profile_frames.c b/ext/-test-/debug/profile_frames.c
index f9a77a5a78..d2bba7d183 100644
--- a/ext/-test-/debug/profile_frames.c
+++ b/ext/-test-/debug/profile_frames.c
@@ -37,29 +37,8 @@ profile_frames(VALUE self, VALUE start_v, VALUE num_v)
return result;
}
-static VALUE
-profile_thread_frames(VALUE self, VALUE thread, VALUE start_v, VALUE num_v)
-{
- int i, collected_size;
- int start = NUM2INT(start_v);
- int buff_size = NUM2INT(num_v);
- VALUE buff[MAX_BUF_SIZE];
- int lines[MAX_BUF_SIZE];
- VALUE result = rb_ary_new();
-
- if (buff_size > MAX_BUF_SIZE) rb_raise(rb_eRuntimeError, "too long buff_size");
-
- collected_size = rb_profile_thread_frames(thread, start, buff_size, buff, lines);
- for (i=0; i<collected_size; i++) {
- rb_ary_push(result, rb_profile_frame_full_label(buff[i]));
- }
-
- return result;
-}
-
void
Init_profile_frames(VALUE klass)
{
rb_define_module_function(klass, "profile_frames", profile_frames, 2);
- rb_define_module_function(klass, "profile_thread_frames", profile_thread_frames, 3);
}
diff --git a/ext/-test-/dln/empty/depend b/ext/-test-/dln/empty/depend
index a460159087..e16082a7dc 100644
--- a/ext/-test-/dln/empty/depend
+++ b/ext/-test-/dln/empty/depend
@@ -52,7 +52,6 @@ empty.o: $(hdrdir)/ruby/internal/attr/noexcept.h
empty.o: $(hdrdir)/ruby/internal/attr/noinline.h
empty.o: $(hdrdir)/ruby/internal/attr/nonnull.h
empty.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-empty.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
empty.o: $(hdrdir)/ruby/internal/attr/pure.h
empty.o: $(hdrdir)/ruby/internal/attr/restrict.h
empty.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ empty.o: $(hdrdir)/ruby/internal/intern/enumerator.h
empty.o: $(hdrdir)/ruby/internal/intern/error.h
empty.o: $(hdrdir)/ruby/internal/intern/eval.h
empty.o: $(hdrdir)/ruby/internal/intern/file.h
+empty.o: $(hdrdir)/ruby/internal/intern/gc.h
empty.o: $(hdrdir)/ruby/internal/intern/hash.h
empty.o: $(hdrdir)/ruby/internal/intern/io.h
empty.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ empty.o: $(hdrdir)/ruby/internal/memory.h
empty.o: $(hdrdir)/ruby/internal/method.h
empty.o: $(hdrdir)/ruby/internal/module.h
empty.o: $(hdrdir)/ruby/internal/newobj.h
+empty.o: $(hdrdir)/ruby/internal/rgengc.h
empty.o: $(hdrdir)/ruby/internal/scan_args.h
empty.o: $(hdrdir)/ruby/internal/special_consts.h
empty.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/enumerator_kw/depend b/ext/-test-/enumerator_kw/depend
index 49ea495421..14a9557e41 100644
--- a/ext/-test-/enumerator_kw/depend
+++ b/ext/-test-/enumerator_kw/depend
@@ -52,7 +52,6 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noexcept.h
enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noinline.h
enumerator_kw.o: $(hdrdir)/ruby/internal/attr/nonnull.h
enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-enumerator_kw.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
enumerator_kw.o: $(hdrdir)/ruby/internal/attr/pure.h
enumerator_kw.o: $(hdrdir)/ruby/internal/attr/restrict.h
enumerator_kw.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/intern/enumerator.h
enumerator_kw.o: $(hdrdir)/ruby/internal/intern/error.h
enumerator_kw.o: $(hdrdir)/ruby/internal/intern/eval.h
enumerator_kw.o: $(hdrdir)/ruby/internal/intern/file.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/intern/gc.h
enumerator_kw.o: $(hdrdir)/ruby/internal/intern/hash.h
enumerator_kw.o: $(hdrdir)/ruby/internal/intern/io.h
enumerator_kw.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/memory.h
enumerator_kw.o: $(hdrdir)/ruby/internal/method.h
enumerator_kw.o: $(hdrdir)/ruby/internal/module.h
enumerator_kw.o: $(hdrdir)/ruby/internal/newobj.h
+enumerator_kw.o: $(hdrdir)/ruby/internal/rgengc.h
enumerator_kw.o: $(hdrdir)/ruby/internal/scan_args.h
enumerator_kw.o: $(hdrdir)/ruby/internal/special_consts.h
enumerator_kw.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/exception/depend b/ext/-test-/exception/depend
index 818b4c79df..e00f0b279d 100644
--- a/ext/-test-/exception/depend
+++ b/ext/-test-/exception/depend
@@ -51,7 +51,6 @@ dataerror.o: $(hdrdir)/ruby/internal/attr/noexcept.h
dataerror.o: $(hdrdir)/ruby/internal/attr/noinline.h
dataerror.o: $(hdrdir)/ruby/internal/attr/nonnull.h
dataerror.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-dataerror.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
dataerror.o: $(hdrdir)/ruby/internal/attr/pure.h
dataerror.o: $(hdrdir)/ruby/internal/attr/restrict.h
dataerror.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ dataerror.o: $(hdrdir)/ruby/internal/intern/enumerator.h
dataerror.o: $(hdrdir)/ruby/internal/intern/error.h
dataerror.o: $(hdrdir)/ruby/internal/intern/eval.h
dataerror.o: $(hdrdir)/ruby/internal/intern/file.h
+dataerror.o: $(hdrdir)/ruby/internal/intern/gc.h
dataerror.o: $(hdrdir)/ruby/internal/intern/hash.h
dataerror.o: $(hdrdir)/ruby/internal/intern/io.h
dataerror.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ dataerror.o: $(hdrdir)/ruby/internal/memory.h
dataerror.o: $(hdrdir)/ruby/internal/method.h
dataerror.o: $(hdrdir)/ruby/internal/module.h
dataerror.o: $(hdrdir)/ruby/internal/newobj.h
+dataerror.o: $(hdrdir)/ruby/internal/rgengc.h
dataerror.o: $(hdrdir)/ruby/internal/scan_args.h
dataerror.o: $(hdrdir)/ruby/internal/special_consts.h
dataerror.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ enc_raise.o: $(hdrdir)/ruby/internal/attr/noexcept.h
enc_raise.o: $(hdrdir)/ruby/internal/attr/noinline.h
enc_raise.o: $(hdrdir)/ruby/internal/attr/nonnull.h
enc_raise.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-enc_raise.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
enc_raise.o: $(hdrdir)/ruby/internal/attr/pure.h
enc_raise.o: $(hdrdir)/ruby/internal/attr/restrict.h
enc_raise.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -280,6 +280,7 @@ enc_raise.o: $(hdrdir)/ruby/internal/intern/enumerator.h
enc_raise.o: $(hdrdir)/ruby/internal/intern/error.h
enc_raise.o: $(hdrdir)/ruby/internal/intern/eval.h
enc_raise.o: $(hdrdir)/ruby/internal/intern/file.h
+enc_raise.o: $(hdrdir)/ruby/internal/intern/gc.h
enc_raise.o: $(hdrdir)/ruby/internal/intern/hash.h
enc_raise.o: $(hdrdir)/ruby/internal/intern/io.h
enc_raise.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -310,6 +311,7 @@ enc_raise.o: $(hdrdir)/ruby/internal/memory.h
enc_raise.o: $(hdrdir)/ruby/internal/method.h
enc_raise.o: $(hdrdir)/ruby/internal/module.h
enc_raise.o: $(hdrdir)/ruby/internal/newobj.h
+enc_raise.o: $(hdrdir)/ruby/internal/rgengc.h
enc_raise.o: $(hdrdir)/ruby/internal/scan_args.h
enc_raise.o: $(hdrdir)/ruby/internal/special_consts.h
enc_raise.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -381,7 +383,6 @@ ensured.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ensured.o: $(hdrdir)/ruby/internal/attr/noinline.h
ensured.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ensured.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ensured.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ensured.o: $(hdrdir)/ruby/internal/attr/pure.h
ensured.o: $(hdrdir)/ruby/internal/attr/restrict.h
ensured.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -441,6 +442,7 @@ ensured.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ensured.o: $(hdrdir)/ruby/internal/intern/error.h
ensured.o: $(hdrdir)/ruby/internal/intern/eval.h
ensured.o: $(hdrdir)/ruby/internal/intern/file.h
+ensured.o: $(hdrdir)/ruby/internal/intern/gc.h
ensured.o: $(hdrdir)/ruby/internal/intern/hash.h
ensured.o: $(hdrdir)/ruby/internal/intern/io.h
ensured.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -471,6 +473,7 @@ ensured.o: $(hdrdir)/ruby/internal/memory.h
ensured.o: $(hdrdir)/ruby/internal/method.h
ensured.o: $(hdrdir)/ruby/internal/module.h
ensured.o: $(hdrdir)/ruby/internal/newobj.h
+ensured.o: $(hdrdir)/ruby/internal/rgengc.h
ensured.o: $(hdrdir)/ruby/internal/scan_args.h
ensured.o: $(hdrdir)/ruby/internal/special_consts.h
ensured.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -540,7 +543,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -600,6 +602,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -630,6 +633,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/fatal/depend b/ext/-test-/fatal/depend
index 730a72e52a..5b1adb6607 100644
--- a/ext/-test-/fatal/depend
+++ b/ext/-test-/fatal/depend
@@ -52,7 +52,6 @@ rb_fatal.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rb_fatal.o: $(hdrdir)/ruby/internal/attr/noinline.h
rb_fatal.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rb_fatal.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rb_fatal.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rb_fatal.o: $(hdrdir)/ruby/internal/attr/pure.h
rb_fatal.o: $(hdrdir)/ruby/internal/attr/restrict.h
rb_fatal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ rb_fatal.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rb_fatal.o: $(hdrdir)/ruby/internal/intern/error.h
rb_fatal.o: $(hdrdir)/ruby/internal/intern/eval.h
rb_fatal.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_fatal.o: $(hdrdir)/ruby/internal/intern/gc.h
rb_fatal.o: $(hdrdir)/ruby/internal/intern/hash.h
rb_fatal.o: $(hdrdir)/ruby/internal/intern/io.h
rb_fatal.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ rb_fatal.o: $(hdrdir)/ruby/internal/memory.h
rb_fatal.o: $(hdrdir)/ruby/internal/method.h
rb_fatal.o: $(hdrdir)/ruby/internal/module.h
rb_fatal.o: $(hdrdir)/ruby/internal/newobj.h
+rb_fatal.o: $(hdrdir)/ruby/internal/rgengc.h
rb_fatal.o: $(hdrdir)/ruby/internal/scan_args.h
rb_fatal.o: $(hdrdir)/ruby/internal/special_consts.h
rb_fatal.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/file/depend b/ext/-test-/file/depend
index 662136f1ba..f0fffc2485 100644
--- a/ext/-test-/file/depend
+++ b/ext/-test-/file/depend
@@ -52,7 +52,6 @@ fs.o: $(hdrdir)/ruby/internal/attr/noexcept.h
fs.o: $(hdrdir)/ruby/internal/attr/noinline.h
fs.o: $(hdrdir)/ruby/internal/attr/nonnull.h
fs.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-fs.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
fs.o: $(hdrdir)/ruby/internal/attr/pure.h
fs.o: $(hdrdir)/ruby/internal/attr/restrict.h
fs.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -121,6 +120,7 @@ fs.o: $(hdrdir)/ruby/internal/intern/enumerator.h
fs.o: $(hdrdir)/ruby/internal/intern/error.h
fs.o: $(hdrdir)/ruby/internal/intern/eval.h
fs.o: $(hdrdir)/ruby/internal/intern/file.h
+fs.o: $(hdrdir)/ruby/internal/intern/gc.h
fs.o: $(hdrdir)/ruby/internal/intern/hash.h
fs.o: $(hdrdir)/ruby/internal/intern/io.h
fs.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -151,6 +151,7 @@ fs.o: $(hdrdir)/ruby/internal/memory.h
fs.o: $(hdrdir)/ruby/internal/method.h
fs.o: $(hdrdir)/ruby/internal/module.h
fs.o: $(hdrdir)/ruby/internal/newobj.h
+fs.o: $(hdrdir)/ruby/internal/rgengc.h
fs.o: $(hdrdir)/ruby/internal/scan_args.h
fs.o: $(hdrdir)/ruby/internal/special_consts.h
fs.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -223,7 +224,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -283,6 +283,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -313,6 +314,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -382,7 +384,6 @@ stat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
stat.o: $(hdrdir)/ruby/internal/attr/noinline.h
stat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
stat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-stat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
stat.o: $(hdrdir)/ruby/internal/attr/pure.h
stat.o: $(hdrdir)/ruby/internal/attr/restrict.h
stat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -451,6 +452,7 @@ stat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
stat.o: $(hdrdir)/ruby/internal/intern/error.h
stat.o: $(hdrdir)/ruby/internal/intern/eval.h
stat.o: $(hdrdir)/ruby/internal/intern/file.h
+stat.o: $(hdrdir)/ruby/internal/intern/gc.h
stat.o: $(hdrdir)/ruby/internal/intern/hash.h
stat.o: $(hdrdir)/ruby/internal/intern/io.h
stat.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -481,6 +483,7 @@ stat.o: $(hdrdir)/ruby/internal/memory.h
stat.o: $(hdrdir)/ruby/internal/method.h
stat.o: $(hdrdir)/ruby/internal/module.h
stat.o: $(hdrdir)/ruby/internal/newobj.h
+stat.o: $(hdrdir)/ruby/internal/rgengc.h
stat.o: $(hdrdir)/ruby/internal/scan_args.h
stat.o: $(hdrdir)/ruby/internal/special_consts.h
stat.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/float/depend b/ext/-test-/float/depend
index 9580a0416c..9391a445a3 100644
--- a/ext/-test-/float/depend
+++ b/ext/-test-/float/depend
@@ -55,7 +55,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -115,6 +114,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -145,6 +145,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -214,7 +215,6 @@ nextafter.o: $(hdrdir)/ruby/internal/attr/noexcept.h
nextafter.o: $(hdrdir)/ruby/internal/attr/noinline.h
nextafter.o: $(hdrdir)/ruby/internal/attr/nonnull.h
nextafter.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-nextafter.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
nextafter.o: $(hdrdir)/ruby/internal/attr/pure.h
nextafter.o: $(hdrdir)/ruby/internal/attr/restrict.h
nextafter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -274,6 +274,7 @@ nextafter.o: $(hdrdir)/ruby/internal/intern/enumerator.h
nextafter.o: $(hdrdir)/ruby/internal/intern/error.h
nextafter.o: $(hdrdir)/ruby/internal/intern/eval.h
nextafter.o: $(hdrdir)/ruby/internal/intern/file.h
+nextafter.o: $(hdrdir)/ruby/internal/intern/gc.h
nextafter.o: $(hdrdir)/ruby/internal/intern/hash.h
nextafter.o: $(hdrdir)/ruby/internal/intern/io.h
nextafter.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -304,6 +305,7 @@ nextafter.o: $(hdrdir)/ruby/internal/memory.h
nextafter.o: $(hdrdir)/ruby/internal/method.h
nextafter.o: $(hdrdir)/ruby/internal/module.h
nextafter.o: $(hdrdir)/ruby/internal/newobj.h
+nextafter.o: $(hdrdir)/ruby/internal/rgengc.h
nextafter.o: $(hdrdir)/ruby/internal/scan_args.h
nextafter.o: $(hdrdir)/ruby/internal/special_consts.h
nextafter.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/funcall/depend b/ext/-test-/funcall/depend
index 6719e4e676..24e8c54bd9 100644
--- a/ext/-test-/funcall/depend
+++ b/ext/-test-/funcall/depend
@@ -52,7 +52,6 @@ funcall.o: $(hdrdir)/ruby/internal/attr/noexcept.h
funcall.o: $(hdrdir)/ruby/internal/attr/noinline.h
funcall.o: $(hdrdir)/ruby/internal/attr/nonnull.h
funcall.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-funcall.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
funcall.o: $(hdrdir)/ruby/internal/attr/pure.h
funcall.o: $(hdrdir)/ruby/internal/attr/restrict.h
funcall.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ funcall.o: $(hdrdir)/ruby/internal/intern/enumerator.h
funcall.o: $(hdrdir)/ruby/internal/intern/error.h
funcall.o: $(hdrdir)/ruby/internal/intern/eval.h
funcall.o: $(hdrdir)/ruby/internal/intern/file.h
+funcall.o: $(hdrdir)/ruby/internal/intern/gc.h
funcall.o: $(hdrdir)/ruby/internal/intern/hash.h
funcall.o: $(hdrdir)/ruby/internal/intern/io.h
funcall.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ funcall.o: $(hdrdir)/ruby/internal/memory.h
funcall.o: $(hdrdir)/ruby/internal/method.h
funcall.o: $(hdrdir)/ruby/internal/module.h
funcall.o: $(hdrdir)/ruby/internal/newobj.h
+funcall.o: $(hdrdir)/ruby/internal/rgengc.h
funcall.o: $(hdrdir)/ruby/internal/scan_args.h
funcall.o: $(hdrdir)/ruby/internal/special_consts.h
funcall.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/gvl/call_without_gvl/depend b/ext/-test-/gvl/call_without_gvl/depend
index a4987a65ca..cd184aa01c 100644
--- a/ext/-test-/gvl/call_without_gvl/depend
+++ b/ext/-test-/gvl/call_without_gvl/depend
@@ -51,7 +51,6 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noinline.h
call_without_gvl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-call_without_gvl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
call_without_gvl.o: $(hdrdir)/ruby/internal/attr/pure.h
call_without_gvl.o: $(hdrdir)/ruby/internal/attr/restrict.h
call_without_gvl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
call_without_gvl.o: $(hdrdir)/ruby/internal/intern/error.h
call_without_gvl.o: $(hdrdir)/ruby/internal/intern/eval.h
call_without_gvl.o: $(hdrdir)/ruby/internal/intern/file.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/intern/gc.h
call_without_gvl.o: $(hdrdir)/ruby/internal/intern/hash.h
call_without_gvl.o: $(hdrdir)/ruby/internal/intern/io.h
call_without_gvl.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/memory.h
call_without_gvl.o: $(hdrdir)/ruby/internal/method.h
call_without_gvl.o: $(hdrdir)/ruby/internal/module.h
call_without_gvl.o: $(hdrdir)/ruby/internal/newobj.h
+call_without_gvl.o: $(hdrdir)/ruby/internal/rgengc.h
call_without_gvl.o: $(hdrdir)/ruby/internal/scan_args.h
call_without_gvl.o: $(hdrdir)/ruby/internal/special_consts.h
call_without_gvl.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/hash/depend b/ext/-test-/hash/depend
index 58d9a6247e..a8bc47e640 100644
--- a/ext/-test-/hash/depend
+++ b/ext/-test-/hash/depend
@@ -52,7 +52,6 @@ delete.o: $(hdrdir)/ruby/internal/attr/noexcept.h
delete.o: $(hdrdir)/ruby/internal/attr/noinline.h
delete.o: $(hdrdir)/ruby/internal/attr/nonnull.h
delete.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-delete.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
delete.o: $(hdrdir)/ruby/internal/attr/pure.h
delete.o: $(hdrdir)/ruby/internal/attr/restrict.h
delete.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ delete.o: $(hdrdir)/ruby/internal/intern/enumerator.h
delete.o: $(hdrdir)/ruby/internal/intern/error.h
delete.o: $(hdrdir)/ruby/internal/intern/eval.h
delete.o: $(hdrdir)/ruby/internal/intern/file.h
+delete.o: $(hdrdir)/ruby/internal/intern/gc.h
delete.o: $(hdrdir)/ruby/internal/intern/hash.h
delete.o: $(hdrdir)/ruby/internal/intern/io.h
delete.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ delete.o: $(hdrdir)/ruby/internal/memory.h
delete.o: $(hdrdir)/ruby/internal/method.h
delete.o: $(hdrdir)/ruby/internal/module.h
delete.o: $(hdrdir)/ruby/internal/newobj.h
+delete.o: $(hdrdir)/ruby/internal/rgengc.h
delete.o: $(hdrdir)/ruby/internal/scan_args.h
delete.o: $(hdrdir)/ruby/internal/special_consts.h
delete.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/integer/depend b/ext/-test-/integer/depend
index b68a68ce73..b12159f308 100644
--- a/ext/-test-/integer/depend
+++ b/ext/-test-/integer/depend
@@ -52,7 +52,6 @@ core_ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h
core_ext.o: $(hdrdir)/ruby/internal/attr/noinline.h
core_ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h
core_ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-core_ext.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
core_ext.o: $(hdrdir)/ruby/internal/attr/pure.h
core_ext.o: $(hdrdir)/ruby/internal/attr/restrict.h
core_ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ core_ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h
core_ext.o: $(hdrdir)/ruby/internal/intern/error.h
core_ext.o: $(hdrdir)/ruby/internal/intern/eval.h
core_ext.o: $(hdrdir)/ruby/internal/intern/file.h
+core_ext.o: $(hdrdir)/ruby/internal/intern/gc.h
core_ext.o: $(hdrdir)/ruby/internal/intern/hash.h
core_ext.o: $(hdrdir)/ruby/internal/intern/io.h
core_ext.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ core_ext.o: $(hdrdir)/ruby/internal/memory.h
core_ext.o: $(hdrdir)/ruby/internal/method.h
core_ext.o: $(hdrdir)/ruby/internal/module.h
core_ext.o: $(hdrdir)/ruby/internal/newobj.h
+core_ext.o: $(hdrdir)/ruby/internal/rgengc.h
core_ext.o: $(hdrdir)/ruby/internal/scan_args.h
core_ext.o: $(hdrdir)/ruby/internal/special_consts.h
core_ext.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -219,7 +220,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -279,6 +279,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -309,6 +310,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -378,7 +380,6 @@ my_integer.o: $(hdrdir)/ruby/internal/attr/noexcept.h
my_integer.o: $(hdrdir)/ruby/internal/attr/noinline.h
my_integer.o: $(hdrdir)/ruby/internal/attr/nonnull.h
my_integer.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-my_integer.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
my_integer.o: $(hdrdir)/ruby/internal/attr/pure.h
my_integer.o: $(hdrdir)/ruby/internal/attr/restrict.h
my_integer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -438,6 +439,7 @@ my_integer.o: $(hdrdir)/ruby/internal/intern/enumerator.h
my_integer.o: $(hdrdir)/ruby/internal/intern/error.h
my_integer.o: $(hdrdir)/ruby/internal/intern/eval.h
my_integer.o: $(hdrdir)/ruby/internal/intern/file.h
+my_integer.o: $(hdrdir)/ruby/internal/intern/gc.h
my_integer.o: $(hdrdir)/ruby/internal/intern/hash.h
my_integer.o: $(hdrdir)/ruby/internal/intern/io.h
my_integer.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -468,6 +470,7 @@ my_integer.o: $(hdrdir)/ruby/internal/memory.h
my_integer.o: $(hdrdir)/ruby/internal/method.h
my_integer.o: $(hdrdir)/ruby/internal/module.h
my_integer.o: $(hdrdir)/ruby/internal/newobj.h
+my_integer.o: $(hdrdir)/ruby/internal/rgengc.h
my_integer.o: $(hdrdir)/ruby/internal/scan_args.h
my_integer.o: $(hdrdir)/ruby/internal/special_consts.h
my_integer.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/iseq_load/depend b/ext/-test-/iseq_load/depend
index 30deb6e039..308956550c 100644
--- a/ext/-test-/iseq_load/depend
+++ b/ext/-test-/iseq_load/depend
@@ -52,7 +52,6 @@ iseq_load.o: $(hdrdir)/ruby/internal/attr/noexcept.h
iseq_load.o: $(hdrdir)/ruby/internal/attr/noinline.h
iseq_load.o: $(hdrdir)/ruby/internal/attr/nonnull.h
iseq_load.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-iseq_load.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
iseq_load.o: $(hdrdir)/ruby/internal/attr/pure.h
iseq_load.o: $(hdrdir)/ruby/internal/attr/restrict.h
iseq_load.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ iseq_load.o: $(hdrdir)/ruby/internal/intern/enumerator.h
iseq_load.o: $(hdrdir)/ruby/internal/intern/error.h
iseq_load.o: $(hdrdir)/ruby/internal/intern/eval.h
iseq_load.o: $(hdrdir)/ruby/internal/intern/file.h
+iseq_load.o: $(hdrdir)/ruby/internal/intern/gc.h
iseq_load.o: $(hdrdir)/ruby/internal/intern/hash.h
iseq_load.o: $(hdrdir)/ruby/internal/intern/io.h
iseq_load.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ iseq_load.o: $(hdrdir)/ruby/internal/memory.h
iseq_load.o: $(hdrdir)/ruby/internal/method.h
iseq_load.o: $(hdrdir)/ruby/internal/module.h
iseq_load.o: $(hdrdir)/ruby/internal/newobj.h
+iseq_load.o: $(hdrdir)/ruby/internal/rgengc.h
iseq_load.o: $(hdrdir)/ruby/internal/scan_args.h
iseq_load.o: $(hdrdir)/ruby/internal/special_consts.h
iseq_load.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/iter/depend b/ext/-test-/iter/depend
index 077a283532..d14c164cd4 100644
--- a/ext/-test-/iter/depend
+++ b/ext/-test-/iter/depend
@@ -52,7 +52,6 @@ break.o: $(hdrdir)/ruby/internal/attr/noexcept.h
break.o: $(hdrdir)/ruby/internal/attr/noinline.h
break.o: $(hdrdir)/ruby/internal/attr/nonnull.h
break.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-break.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
break.o: $(hdrdir)/ruby/internal/attr/pure.h
break.o: $(hdrdir)/ruby/internal/attr/restrict.h
break.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ break.o: $(hdrdir)/ruby/internal/intern/enumerator.h
break.o: $(hdrdir)/ruby/internal/intern/error.h
break.o: $(hdrdir)/ruby/internal/intern/eval.h
break.o: $(hdrdir)/ruby/internal/intern/file.h
+break.o: $(hdrdir)/ruby/internal/intern/gc.h
break.o: $(hdrdir)/ruby/internal/intern/hash.h
break.o: $(hdrdir)/ruby/internal/intern/io.h
break.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ break.o: $(hdrdir)/ruby/internal/memory.h
break.o: $(hdrdir)/ruby/internal/method.h
break.o: $(hdrdir)/ruby/internal/module.h
break.o: $(hdrdir)/ruby/internal/newobj.h
+break.o: $(hdrdir)/ruby/internal/rgengc.h
break.o: $(hdrdir)/ruby/internal/scan_args.h
break.o: $(hdrdir)/ruby/internal/special_consts.h
break.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -370,7 +372,6 @@ yield.o: $(hdrdir)/ruby/internal/attr/noexcept.h
yield.o: $(hdrdir)/ruby/internal/attr/noinline.h
yield.o: $(hdrdir)/ruby/internal/attr/nonnull.h
yield.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-yield.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
yield.o: $(hdrdir)/ruby/internal/attr/pure.h
yield.o: $(hdrdir)/ruby/internal/attr/restrict.h
yield.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -430,6 +431,7 @@ yield.o: $(hdrdir)/ruby/internal/intern/enumerator.h
yield.o: $(hdrdir)/ruby/internal/intern/error.h
yield.o: $(hdrdir)/ruby/internal/intern/eval.h
yield.o: $(hdrdir)/ruby/internal/intern/file.h
+yield.o: $(hdrdir)/ruby/internal/intern/gc.h
yield.o: $(hdrdir)/ruby/internal/intern/hash.h
yield.o: $(hdrdir)/ruby/internal/intern/io.h
yield.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -460,6 +462,7 @@ yield.o: $(hdrdir)/ruby/internal/memory.h
yield.o: $(hdrdir)/ruby/internal/method.h
yield.o: $(hdrdir)/ruby/internal/module.h
yield.o: $(hdrdir)/ruby/internal/newobj.h
+yield.o: $(hdrdir)/ruby/internal/rgengc.h
yield.o: $(hdrdir)/ruby/internal/scan_args.h
yield.o: $(hdrdir)/ruby/internal/special_consts.h
yield.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/load/dot.dot/depend b/ext/-test-/load/dot.dot/depend
index be835d3ea5..d8b8937c3c 100644
--- a/ext/-test-/load/dot.dot/depend
+++ b/ext/-test-/load/dot.dot/depend
@@ -52,7 +52,6 @@ dot.dot.o: $(hdrdir)/ruby/internal/attr/noexcept.h
dot.dot.o: $(hdrdir)/ruby/internal/attr/noinline.h
dot.dot.o: $(hdrdir)/ruby/internal/attr/nonnull.h
dot.dot.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-dot.dot.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
dot.dot.o: $(hdrdir)/ruby/internal/attr/pure.h
dot.dot.o: $(hdrdir)/ruby/internal/attr/restrict.h
dot.dot.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ dot.dot.o: $(hdrdir)/ruby/internal/intern/enumerator.h
dot.dot.o: $(hdrdir)/ruby/internal/intern/error.h
dot.dot.o: $(hdrdir)/ruby/internal/intern/eval.h
dot.dot.o: $(hdrdir)/ruby/internal/intern/file.h
+dot.dot.o: $(hdrdir)/ruby/internal/intern/gc.h
dot.dot.o: $(hdrdir)/ruby/internal/intern/hash.h
dot.dot.o: $(hdrdir)/ruby/internal/intern/io.h
dot.dot.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ dot.dot.o: $(hdrdir)/ruby/internal/memory.h
dot.dot.o: $(hdrdir)/ruby/internal/method.h
dot.dot.o: $(hdrdir)/ruby/internal/module.h
dot.dot.o: $(hdrdir)/ruby/internal/newobj.h
+dot.dot.o: $(hdrdir)/ruby/internal/rgengc.h
dot.dot.o: $(hdrdir)/ruby/internal/scan_args.h
dot.dot.o: $(hdrdir)/ruby/internal/special_consts.h
dot.dot.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/load/protect/depend b/ext/-test-/load/protect/depend
index 57cf029901..dd4ee71b62 100644
--- a/ext/-test-/load/protect/depend
+++ b/ext/-test-/load/protect/depend
@@ -52,7 +52,6 @@ protect.o: $(hdrdir)/ruby/internal/attr/noexcept.h
protect.o: $(hdrdir)/ruby/internal/attr/noinline.h
protect.o: $(hdrdir)/ruby/internal/attr/nonnull.h
protect.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-protect.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
protect.o: $(hdrdir)/ruby/internal/attr/pure.h
protect.o: $(hdrdir)/ruby/internal/attr/restrict.h
protect.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ protect.o: $(hdrdir)/ruby/internal/intern/enumerator.h
protect.o: $(hdrdir)/ruby/internal/intern/error.h
protect.o: $(hdrdir)/ruby/internal/intern/eval.h
protect.o: $(hdrdir)/ruby/internal/intern/file.h
+protect.o: $(hdrdir)/ruby/internal/intern/gc.h
protect.o: $(hdrdir)/ruby/internal/intern/hash.h
protect.o: $(hdrdir)/ruby/internal/intern/io.h
protect.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ protect.o: $(hdrdir)/ruby/internal/memory.h
protect.o: $(hdrdir)/ruby/internal/method.h
protect.o: $(hdrdir)/ruby/internal/module.h
protect.o: $(hdrdir)/ruby/internal/newobj.h
+protect.o: $(hdrdir)/ruby/internal/rgengc.h
protect.o: $(hdrdir)/ruby/internal/scan_args.h
protect.o: $(hdrdir)/ruby/internal/special_consts.h
protect.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/load/resolve_symbol_resolver/extconf.rb b/ext/-test-/load/resolve_symbol_resolver/extconf.rb
deleted file mode 100644
index 2299efcfd3..0000000000
--- a/ext/-test-/load/resolve_symbol_resolver/extconf.rb
+++ /dev/null
@@ -1 +0,0 @@
-create_makefile('-test-/load/resolve_symbol_resolver')
diff --git a/ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c b/ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c
deleted file mode 100644
index a856319cfb..0000000000
--- a/ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <ruby.h>
-#include "ruby/internal/intern/load.h"
-
-typedef VALUE(*target_func)(VALUE);
-
-static target_func rst_any_method;
-
-VALUE
-rsr_any_method(VALUE klass)
-{
- return rst_any_method((VALUE)NULL);
-}
-
-VALUE
-rsr_try_resolve_fname(VALUE klass)
-{
- target_func rst_something_missing =
- (target_func) rb_ext_resolve_symbol("-test-/load/resolve_symbol_missing", "rst_any_method");
- if (rst_something_missing == NULL) {
- // This should be done in Init_*, so the error is LoadError
- rb_raise(rb_eLoadError, "symbol not found: missing fname");
- }
- return Qtrue;
-}
-
-VALUE
-rsr_try_resolve_sname(VALUE klass)
-{
- target_func rst_something_missing =
- (target_func)rb_ext_resolve_symbol("-test-/load/resolve_symbol_target", "rst_something_missing");
- if (rst_something_missing == NULL) {
- // This should be done in Init_*, so the error is LoadError
- rb_raise(rb_eLoadError, "symbol not found: missing sname");
- }
- return Qtrue;
-}
-
-void
-Init_resolve_symbol_resolver(void)
-{
- /*
- * Resolving symbols at the head of Init_ because it raises LoadError (in cases).
- * If the module and methods are defined before raising LoadError, retrying `require "this.so"` will
- * cause re-defining those methods (and will be warned).
- */
- rst_any_method = (target_func)rb_ext_resolve_symbol("-test-/load/resolve_symbol_target", "rst_any_method");
- if (rst_any_method == NULL) {
- rb_raise(rb_eLoadError, "resolve_symbol_target is not loaded");
- }
-
- VALUE mod = rb_define_module("ResolveSymbolResolver");
- rb_define_singleton_method(mod, "any_method", rsr_any_method, 0);
- rb_define_singleton_method(mod, "try_resolve_fname", rsr_try_resolve_fname, 0);
- rb_define_singleton_method(mod, "try_resolve_sname", rsr_try_resolve_sname, 0);
-}
diff --git a/ext/-test-/load/resolve_symbol_target/extconf.rb b/ext/-test-/load/resolve_symbol_target/extconf.rb
deleted file mode 100644
index b5a99ca7f1..0000000000
--- a/ext/-test-/load/resolve_symbol_target/extconf.rb
+++ /dev/null
@@ -1 +0,0 @@
-create_makefile('-test-/load/resolve_symbol_target')
diff --git a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c
deleted file mode 100644
index b5bc9e8ee0..0000000000
--- a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <ruby.h>
-#include "resolve_symbol_target.h"
-
-VALUE
-rst_any_method(VALUE klass)
-{
- return rb_str_new_cstr("from target");
-}
-
-void
-Init_resolve_symbol_target(void)
-{
- VALUE mod = rb_define_module("ResolveSymbolTarget");
- rb_define_singleton_method(mod, "any_method", rst_any_method, 0);
-}
diff --git a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.def b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.def
deleted file mode 100644
index c2ed3610fe..0000000000
--- a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.def
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBRARY resolve_symbol_target
-EXPORTS
- Init_resolve_symbol_target
- rst_any_method
diff --git a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h
deleted file mode 100644
index 7d471bf360..0000000000
--- a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <ruby.h>
-#include "ruby/internal/dllexport.h"
-
-RUBY_EXTERN VALUE rst_any_method(VALUE);
diff --git a/ext/-test-/load/stringify_symbols/extconf.rb b/ext/-test-/load/stringify_symbols/extconf.rb
deleted file mode 100644
index ac39c15f09..0000000000
--- a/ext/-test-/load/stringify_symbols/extconf.rb
+++ /dev/null
@@ -1 +0,0 @@
-create_makefile('-test-/load/stringify_symbols')
diff --git a/ext/-test-/load/stringify_symbols/stringify_symbols.c b/ext/-test-/load/stringify_symbols/stringify_symbols.c
deleted file mode 100644
index 11a5ee3bc5..0000000000
--- a/ext/-test-/load/stringify_symbols/stringify_symbols.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <ruby.h>
-#include "ruby/internal/intern/load.h"
-#include "ruby/util.h"
-
-#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
-# define UINTPTR2NUM ULL2NUM
-#elif SIZEOF_INTPTR_T == SIZEOF_LONG
-# define UINTPTR2NUM ULONG2NUM
-#else
-# define UINTPTR2NUM UINT2NUM
-#endif
-
-static VALUE
-stringify_symbol(VALUE klass, VALUE fname, VALUE sname)
-{
- void *ptr = rb_ext_resolve_symbol(StringValueCStr(fname), StringValueCStr(sname));
- if (ptr == NULL) {
- return Qnil;
- }
- uintptr_t uintptr = (uintptr_t)ptr;
- return UINTPTR2NUM(uintptr);
-}
-
-void
-Init_stringify_symbols(void)
-{
- VALUE mod = rb_define_module("StringifySymbols");
- rb_define_singleton_method(mod, "stringify_symbol", stringify_symbol, 2);
-}
diff --git a/ext/-test-/load/stringify_target/extconf.rb b/ext/-test-/load/stringify_target/extconf.rb
deleted file mode 100644
index 4aa201cb09..0000000000
--- a/ext/-test-/load/stringify_target/extconf.rb
+++ /dev/null
@@ -1 +0,0 @@
-create_makefile('-test-/load/stringify_target')
diff --git a/ext/-test-/load/stringify_target/stringify_target.c b/ext/-test-/load/stringify_target/stringify_target.c
deleted file mode 100644
index ce09b8fd77..0000000000
--- a/ext/-test-/load/stringify_target/stringify_target.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <ruby.h>
-#include "stringify_target.h"
-
-VALUE
-stt_any_method(VALUE klass)
-{
- return rb_str_new_cstr("from target");
-}
-
-void
-Init_stringify_target(void)
-{
- VALUE mod = rb_define_module("StringifyTarget");
- rb_define_singleton_method(mod, "any_method", stt_any_method, 0);
-}
diff --git a/ext/-test-/load/stringify_target/stringify_target.def b/ext/-test-/load/stringify_target/stringify_target.def
deleted file mode 100644
index 89c2b762de..0000000000
--- a/ext/-test-/load/stringify_target/stringify_target.def
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBRARY stringify_target
-EXPORTS
- Init_stringify_target
- stt_any_method
diff --git a/ext/-test-/load/stringify_target/stringify_target.h b/ext/-test-/load/stringify_target/stringify_target.h
deleted file mode 100644
index 5081f8cbd6..0000000000
--- a/ext/-test-/load/stringify_target/stringify_target.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <ruby.h>
-#include "ruby/internal/dllexport.h"
-
-RUBY_EXTERN VALUE stt_any_method(VALUE);
diff --git a/ext/-test-/marshal/compat/depend b/ext/-test-/marshal/compat/depend
index ff675ccabb..2c3ecf1ab9 100644
--- a/ext/-test-/marshal/compat/depend
+++ b/ext/-test-/marshal/compat/depend
@@ -52,7 +52,6 @@ usrcompat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
usrcompat.o: $(hdrdir)/ruby/internal/attr/noinline.h
usrcompat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
usrcompat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-usrcompat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
usrcompat.o: $(hdrdir)/ruby/internal/attr/pure.h
usrcompat.o: $(hdrdir)/ruby/internal/attr/restrict.h
usrcompat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ usrcompat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
usrcompat.o: $(hdrdir)/ruby/internal/intern/error.h
usrcompat.o: $(hdrdir)/ruby/internal/intern/eval.h
usrcompat.o: $(hdrdir)/ruby/internal/intern/file.h
+usrcompat.o: $(hdrdir)/ruby/internal/intern/gc.h
usrcompat.o: $(hdrdir)/ruby/internal/intern/hash.h
usrcompat.o: $(hdrdir)/ruby/internal/intern/io.h
usrcompat.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ usrcompat.o: $(hdrdir)/ruby/internal/memory.h
usrcompat.o: $(hdrdir)/ruby/internal/method.h
usrcompat.o: $(hdrdir)/ruby/internal/module.h
usrcompat.o: $(hdrdir)/ruby/internal/newobj.h
+usrcompat.o: $(hdrdir)/ruby/internal/rgengc.h
usrcompat.o: $(hdrdir)/ruby/internal/scan_args.h
usrcompat.o: $(hdrdir)/ruby/internal/special_consts.h
usrcompat.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/marshal/internal_ivar/depend b/ext/-test-/marshal/internal_ivar/depend
index 4fe36834d8..cacb54a1a7 100644
--- a/ext/-test-/marshal/internal_ivar/depend
+++ b/ext/-test-/marshal/internal_ivar/depend
@@ -52,7 +52,6 @@ internal_ivar.o: $(hdrdir)/ruby/internal/attr/noexcept.h
internal_ivar.o: $(hdrdir)/ruby/internal/attr/noinline.h
internal_ivar.o: $(hdrdir)/ruby/internal/attr/nonnull.h
internal_ivar.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-internal_ivar.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
internal_ivar.o: $(hdrdir)/ruby/internal/attr/pure.h
internal_ivar.o: $(hdrdir)/ruby/internal/attr/restrict.h
internal_ivar.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ internal_ivar.o: $(hdrdir)/ruby/internal/intern/enumerator.h
internal_ivar.o: $(hdrdir)/ruby/internal/intern/error.h
internal_ivar.o: $(hdrdir)/ruby/internal/intern/eval.h
internal_ivar.o: $(hdrdir)/ruby/internal/intern/file.h
+internal_ivar.o: $(hdrdir)/ruby/internal/intern/gc.h
internal_ivar.o: $(hdrdir)/ruby/internal/intern/hash.h
internal_ivar.o: $(hdrdir)/ruby/internal/intern/io.h
internal_ivar.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ internal_ivar.o: $(hdrdir)/ruby/internal/memory.h
internal_ivar.o: $(hdrdir)/ruby/internal/method.h
internal_ivar.o: $(hdrdir)/ruby/internal/module.h
internal_ivar.o: $(hdrdir)/ruby/internal/newobj.h
+internal_ivar.o: $(hdrdir)/ruby/internal/rgengc.h
internal_ivar.o: $(hdrdir)/ruby/internal/scan_args.h
internal_ivar.o: $(hdrdir)/ruby/internal/special_consts.h
internal_ivar.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/marshal/usr/depend b/ext/-test-/marshal/usr/depend
index 1d56cc8202..717101cbcf 100644
--- a/ext/-test-/marshal/usr/depend
+++ b/ext/-test-/marshal/usr/depend
@@ -52,7 +52,6 @@ usrmarshal.o: $(hdrdir)/ruby/internal/attr/noexcept.h
usrmarshal.o: $(hdrdir)/ruby/internal/attr/noinline.h
usrmarshal.o: $(hdrdir)/ruby/internal/attr/nonnull.h
usrmarshal.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-usrmarshal.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
usrmarshal.o: $(hdrdir)/ruby/internal/attr/pure.h
usrmarshal.o: $(hdrdir)/ruby/internal/attr/restrict.h
usrmarshal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ usrmarshal.o: $(hdrdir)/ruby/internal/intern/enumerator.h
usrmarshal.o: $(hdrdir)/ruby/internal/intern/error.h
usrmarshal.o: $(hdrdir)/ruby/internal/intern/eval.h
usrmarshal.o: $(hdrdir)/ruby/internal/intern/file.h
+usrmarshal.o: $(hdrdir)/ruby/internal/intern/gc.h
usrmarshal.o: $(hdrdir)/ruby/internal/intern/hash.h
usrmarshal.o: $(hdrdir)/ruby/internal/intern/io.h
usrmarshal.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ usrmarshal.o: $(hdrdir)/ruby/internal/memory.h
usrmarshal.o: $(hdrdir)/ruby/internal/method.h
usrmarshal.o: $(hdrdir)/ruby/internal/module.h
usrmarshal.o: $(hdrdir)/ruby/internal/newobj.h
+usrmarshal.o: $(hdrdir)/ruby/internal/rgengc.h
usrmarshal.o: $(hdrdir)/ruby/internal/scan_args.h
usrmarshal.o: $(hdrdir)/ruby/internal/special_consts.h
usrmarshal.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/memory_status/depend b/ext/-test-/memory_status/depend
index 52e2fe8e1f..a65fe66ae3 100644
--- a/ext/-test-/memory_status/depend
+++ b/ext/-test-/memory_status/depend
@@ -52,7 +52,6 @@ memory_status.o: $(hdrdir)/ruby/internal/attr/noexcept.h
memory_status.o: $(hdrdir)/ruby/internal/attr/noinline.h
memory_status.o: $(hdrdir)/ruby/internal/attr/nonnull.h
memory_status.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-memory_status.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
memory_status.o: $(hdrdir)/ruby/internal/attr/pure.h
memory_status.o: $(hdrdir)/ruby/internal/attr/restrict.h
memory_status.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ memory_status.o: $(hdrdir)/ruby/internal/intern/enumerator.h
memory_status.o: $(hdrdir)/ruby/internal/intern/error.h
memory_status.o: $(hdrdir)/ruby/internal/intern/eval.h
memory_status.o: $(hdrdir)/ruby/internal/intern/file.h
+memory_status.o: $(hdrdir)/ruby/internal/intern/gc.h
memory_status.o: $(hdrdir)/ruby/internal/intern/hash.h
memory_status.o: $(hdrdir)/ruby/internal/intern/io.h
memory_status.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ memory_status.o: $(hdrdir)/ruby/internal/memory.h
memory_status.o: $(hdrdir)/ruby/internal/method.h
memory_status.o: $(hdrdir)/ruby/internal/module.h
memory_status.o: $(hdrdir)/ruby/internal/newobj.h
+memory_status.o: $(hdrdir)/ruby/internal/rgengc.h
memory_status.o: $(hdrdir)/ruby/internal/scan_args.h
memory_status.o: $(hdrdir)/ruby/internal/special_consts.h
memory_status.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/memory_view/depend b/ext/-test-/memory_view/depend
index c9ef06a15c..7ce2d0374c 100644
--- a/ext/-test-/memory_view/depend
+++ b/ext/-test-/memory_view/depend
@@ -52,7 +52,6 @@ memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h
memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h
memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h
memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h
memory_view.o: $(hdrdir)/ruby/internal/intern/error.h
memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h
memory_view.o: $(hdrdir)/ruby/internal/intern/file.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h
memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h
memory_view.o: $(hdrdir)/ruby/internal/intern/io.h
memory_view.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ memory_view.o: $(hdrdir)/ruby/internal/memory.h
memory_view.o: $(hdrdir)/ruby/internal/method.h
memory_view.o: $(hdrdir)/ruby/internal/module.h
memory_view.o: $(hdrdir)/ruby/internal/newobj.h
+memory_view.o: $(hdrdir)/ruby/internal/rgengc.h
memory_view.o: $(hdrdir)/ruby/internal/scan_args.h
memory_view.o: $(hdrdir)/ruby/internal/special_consts.h
memory_view.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/method/depend b/ext/-test-/method/depend
index dbf513f48f..85cf4d174a 100644
--- a/ext/-test-/method/depend
+++ b/ext/-test-/method/depend
@@ -52,7 +52,6 @@ arity.o: $(hdrdir)/ruby/internal/attr/noexcept.h
arity.o: $(hdrdir)/ruby/internal/attr/noinline.h
arity.o: $(hdrdir)/ruby/internal/attr/nonnull.h
arity.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-arity.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
arity.o: $(hdrdir)/ruby/internal/attr/pure.h
arity.o: $(hdrdir)/ruby/internal/attr/restrict.h
arity.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ arity.o: $(hdrdir)/ruby/internal/intern/enumerator.h
arity.o: $(hdrdir)/ruby/internal/intern/error.h
arity.o: $(hdrdir)/ruby/internal/intern/eval.h
arity.o: $(hdrdir)/ruby/internal/intern/file.h
+arity.o: $(hdrdir)/ruby/internal/intern/gc.h
arity.o: $(hdrdir)/ruby/internal/intern/hash.h
arity.o: $(hdrdir)/ruby/internal/intern/io.h
arity.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ arity.o: $(hdrdir)/ruby/internal/memory.h
arity.o: $(hdrdir)/ruby/internal/method.h
arity.o: $(hdrdir)/ruby/internal/module.h
arity.o: $(hdrdir)/ruby/internal/newobj.h
+arity.o: $(hdrdir)/ruby/internal/rgengc.h
arity.o: $(hdrdir)/ruby/internal/scan_args.h
arity.o: $(hdrdir)/ruby/internal/special_consts.h
arity.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/notimplement/depend b/ext/-test-/notimplement/depend
index 9105093b0d..2303f47594 100644
--- a/ext/-test-/notimplement/depend
+++ b/ext/-test-/notimplement/depend
@@ -52,7 +52,6 @@ bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bug.o: $(hdrdir)/ruby/internal/attr/noinline.h
bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bug.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bug.o: $(hdrdir)/ruby/internal/attr/pure.h
bug.o: $(hdrdir)/ruby/internal/attr/restrict.h
bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bug.o: $(hdrdir)/ruby/internal/intern/error.h
bug.o: $(hdrdir)/ruby/internal/intern/eval.h
bug.o: $(hdrdir)/ruby/internal/intern/file.h
+bug.o: $(hdrdir)/ruby/internal/intern/gc.h
bug.o: $(hdrdir)/ruby/internal/intern/hash.h
bug.o: $(hdrdir)/ruby/internal/intern/io.h
bug.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ bug.o: $(hdrdir)/ruby/internal/memory.h
bug.o: $(hdrdir)/ruby/internal/method.h
bug.o: $(hdrdir)/ruby/internal/module.h
bug.o: $(hdrdir)/ruby/internal/newobj.h
+bug.o: $(hdrdir)/ruby/internal/rgengc.h
bug.o: $(hdrdir)/ruby/internal/scan_args.h
bug.o: $(hdrdir)/ruby/internal/special_consts.h
bug.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/num2int/depend b/ext/-test-/num2int/depend
index 4e05d1e8c1..a3283838dd 100644
--- a/ext/-test-/num2int/depend
+++ b/ext/-test-/num2int/depend
@@ -52,7 +52,6 @@ num2int.o: $(hdrdir)/ruby/internal/attr/noexcept.h
num2int.o: $(hdrdir)/ruby/internal/attr/noinline.h
num2int.o: $(hdrdir)/ruby/internal/attr/nonnull.h
num2int.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-num2int.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
num2int.o: $(hdrdir)/ruby/internal/attr/pure.h
num2int.o: $(hdrdir)/ruby/internal/attr/restrict.h
num2int.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ num2int.o: $(hdrdir)/ruby/internal/intern/enumerator.h
num2int.o: $(hdrdir)/ruby/internal/intern/error.h
num2int.o: $(hdrdir)/ruby/internal/intern/eval.h
num2int.o: $(hdrdir)/ruby/internal/intern/file.h
+num2int.o: $(hdrdir)/ruby/internal/intern/gc.h
num2int.o: $(hdrdir)/ruby/internal/intern/hash.h
num2int.o: $(hdrdir)/ruby/internal/intern/io.h
num2int.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ num2int.o: $(hdrdir)/ruby/internal/memory.h
num2int.o: $(hdrdir)/ruby/internal/method.h
num2int.o: $(hdrdir)/ruby/internal/module.h
num2int.o: $(hdrdir)/ruby/internal/newobj.h
+num2int.o: $(hdrdir)/ruby/internal/rgengc.h
num2int.o: $(hdrdir)/ruby/internal/scan_args.h
num2int.o: $(hdrdir)/ruby/internal/special_consts.h
num2int.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/path_to_class/depend b/ext/-test-/path_to_class/depend
index 8fe6ee37c2..17f8e957c3 100644
--- a/ext/-test-/path_to_class/depend
+++ b/ext/-test-/path_to_class/depend
@@ -52,7 +52,6 @@ path_to_class.o: $(hdrdir)/ruby/internal/attr/noexcept.h
path_to_class.o: $(hdrdir)/ruby/internal/attr/noinline.h
path_to_class.o: $(hdrdir)/ruby/internal/attr/nonnull.h
path_to_class.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-path_to_class.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
path_to_class.o: $(hdrdir)/ruby/internal/attr/pure.h
path_to_class.o: $(hdrdir)/ruby/internal/attr/restrict.h
path_to_class.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ path_to_class.o: $(hdrdir)/ruby/internal/intern/enumerator.h
path_to_class.o: $(hdrdir)/ruby/internal/intern/error.h
path_to_class.o: $(hdrdir)/ruby/internal/intern/eval.h
path_to_class.o: $(hdrdir)/ruby/internal/intern/file.h
+path_to_class.o: $(hdrdir)/ruby/internal/intern/gc.h
path_to_class.o: $(hdrdir)/ruby/internal/intern/hash.h
path_to_class.o: $(hdrdir)/ruby/internal/intern/io.h
path_to_class.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ path_to_class.o: $(hdrdir)/ruby/internal/memory.h
path_to_class.o: $(hdrdir)/ruby/internal/method.h
path_to_class.o: $(hdrdir)/ruby/internal/module.h
path_to_class.o: $(hdrdir)/ruby/internal/newobj.h
+path_to_class.o: $(hdrdir)/ruby/internal/rgengc.h
path_to_class.o: $(hdrdir)/ruby/internal/scan_args.h
path_to_class.o: $(hdrdir)/ruby/internal/special_consts.h
path_to_class.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/popen_deadlock/depend b/ext/-test-/popen_deadlock/depend
index fb58ca30e9..22da87f2fe 100644
--- a/ext/-test-/popen_deadlock/depend
+++ b/ext/-test-/popen_deadlock/depend
@@ -52,7 +52,6 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noexcept.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noinline.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/nonnull.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/pure.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/restrict.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/enumerator.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/error.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/eval.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/file.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/gc.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/hash.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/io.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/memory.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/method.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/module.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/newobj.h
+infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/rgengc.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/scan_args.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/special_consts.h
infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/postponed_job/depend b/ext/-test-/postponed_job/depend
index e44d9d51b7..35aca7f2b0 100644
--- a/ext/-test-/postponed_job/depend
+++ b/ext/-test-/postponed_job/depend
@@ -53,7 +53,6 @@ postponed_job.o: $(hdrdir)/ruby/internal/attr/noexcept.h
postponed_job.o: $(hdrdir)/ruby/internal/attr/noinline.h
postponed_job.o: $(hdrdir)/ruby/internal/attr/nonnull.h
postponed_job.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-postponed_job.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
postponed_job.o: $(hdrdir)/ruby/internal/attr/pure.h
postponed_job.o: $(hdrdir)/ruby/internal/attr/restrict.h
postponed_job.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -113,6 +112,7 @@ postponed_job.o: $(hdrdir)/ruby/internal/intern/enumerator.h
postponed_job.o: $(hdrdir)/ruby/internal/intern/error.h
postponed_job.o: $(hdrdir)/ruby/internal/intern/eval.h
postponed_job.o: $(hdrdir)/ruby/internal/intern/file.h
+postponed_job.o: $(hdrdir)/ruby/internal/intern/gc.h
postponed_job.o: $(hdrdir)/ruby/internal/intern/hash.h
postponed_job.o: $(hdrdir)/ruby/internal/intern/io.h
postponed_job.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -143,6 +143,7 @@ postponed_job.o: $(hdrdir)/ruby/internal/memory.h
postponed_job.o: $(hdrdir)/ruby/internal/method.h
postponed_job.o: $(hdrdir)/ruby/internal/module.h
postponed_job.o: $(hdrdir)/ruby/internal/newobj.h
+postponed_job.o: $(hdrdir)/ruby/internal/rgengc.h
postponed_job.o: $(hdrdir)/ruby/internal/scan_args.h
postponed_job.o: $(hdrdir)/ruby/internal/special_consts.h
postponed_job.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/postponed_job/postponed_job.c b/ext/-test-/postponed_job/postponed_job.c
index 9ac866ae77..fa57bef6f5 100644
--- a/ext/-test-/postponed_job/postponed_job.c
+++ b/ext/-test-/postponed_job/postponed_job.c
@@ -1,29 +1,6 @@
#include "ruby.h"
#include "ruby/debug.h"
-// We're testing deprecated things, don't print the compiler warnings
-#if 0
-
-#elif defined(_MSC_VER)
-#pragma warning(disable : 4996)
-
-#elif defined(__INTEL_COMPILER)
-#pragma warning(disable : 1786)
-
-#elif defined(__clang__)
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-
-#elif defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
-#elif defined(__SUNPRO_CC)
-#pragma error_messages (off,symdeprecated)
-
-#else
-// :FIXME: improve here for your compiler.
-
-#endif
-
static int counter;
static void
@@ -81,22 +58,6 @@ pjob_call_direct(VALUE self, VALUE obj)
return self;
}
-static void pjob_noop_callback(void *data) { }
-
-static VALUE
-pjob_register_one_same(VALUE self)
-{
- rb_gc_start();
- int r1 = rb_postponed_job_register_one(0, pjob_noop_callback, NULL);
- int r2 = rb_postponed_job_register_one(0, pjob_noop_callback, NULL);
- int r3 = rb_postponed_job_register_one(0, pjob_noop_callback, NULL);
- VALUE ary = rb_ary_new();
- rb_ary_push(ary, INT2FIX(r1));
- rb_ary_push(ary, INT2FIX(r2));
- rb_ary_push(ary, INT2FIX(r3));
- return ary;
-}
-
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
@@ -125,93 +86,6 @@ pjob_register_in_c_thread(VALUE self, VALUE obj)
}
#endif
-static void
-pjob_preregistered_callback(void *data)
-{
- VALUE ary = (VALUE)data;
- Check_Type(ary, T_ARRAY);
- rb_ary_push(ary, INT2FIX(counter));
-}
-
-static VALUE
-pjob_preregister_and_call_with_sleep(VALUE self, VALUE obj)
-{
- counter = 0;
- rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, pjob_preregistered_callback, (void *)obj);
- counter++;
- rb_postponed_job_trigger(h);
- rb_thread_sleep(0);
- counter++;
- rb_postponed_job_trigger(h);
- rb_thread_sleep(0);
- counter++;
- rb_postponed_job_trigger(h);
- rb_thread_sleep(0);
- return self;
-}
-
-static VALUE
-pjob_preregister_and_call_without_sleep(VALUE self, VALUE obj)
-{
- counter = 0;
- rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, pjob_preregistered_callback, (void *)obj);
- counter = 3;
- rb_postponed_job_trigger(h);
- rb_postponed_job_trigger(h);
- rb_postponed_job_trigger(h);
- return self;
-}
-
-static VALUE
-pjob_preregister_multiple_times(VALUE self)
-{
- int r1 = rb_postponed_job_preregister(0, pjob_noop_callback, NULL);
- int r2 = rb_postponed_job_preregister(0, pjob_noop_callback, NULL);
- int r3 = rb_postponed_job_preregister(0, pjob_noop_callback, NULL);
- VALUE ary = rb_ary_new();
- rb_ary_push(ary, INT2FIX(r1));
- rb_ary_push(ary, INT2FIX(r2));
- rb_ary_push(ary, INT2FIX(r3));
- return ary;
-
-}
-
-struct pjob_append_data_args {
- VALUE ary;
- VALUE data;
-};
-
-static void
-pjob_append_data_callback(void *vctx) {
- struct pjob_append_data_args *ctx = (struct pjob_append_data_args *)vctx;
- Check_Type(ctx->ary, T_ARRAY);
- rb_ary_push(ctx->ary, ctx->data);
-}
-
-static VALUE
-pjob_preregister_calls_with_last_argument(VALUE self)
-{
- VALUE ary = rb_ary_new();
-
- struct pjob_append_data_args arg1 = { .ary = ary, .data = INT2FIX(1) };
- struct pjob_append_data_args arg2 = { .ary = ary, .data = INT2FIX(2) };
- struct pjob_append_data_args arg3 = { .ary = ary, .data = INT2FIX(3) };
- struct pjob_append_data_args arg4 = { .ary = ary, .data = INT2FIX(4) };
-
- rb_postponed_job_handle_t h;
- h = rb_postponed_job_preregister(0, pjob_append_data_callback, &arg1);
- rb_postponed_job_preregister(0, pjob_append_data_callback, &arg2);
- rb_postponed_job_trigger(h);
- rb_postponed_job_preregister(0, pjob_append_data_callback, &arg3);
- rb_thread_sleep(0); // should execute with arg3
-
- rb_postponed_job_preregister(0, pjob_append_data_callback, &arg4);
- rb_postponed_job_trigger(h);
- rb_thread_sleep(0); // should execute with arg4
-
- return ary;
-}
-
void
Init_postponed_job(VALUE self)
{
@@ -219,13 +93,8 @@ Init_postponed_job(VALUE self)
rb_define_module_function(mBug, "postponed_job_register", pjob_register, 1);
rb_define_module_function(mBug, "postponed_job_register_one", pjob_register_one, 1);
rb_define_module_function(mBug, "postponed_job_call_direct", pjob_call_direct, 1);
- rb_define_module_function(mBug, "postponed_job_register_one_same", pjob_register_one_same, 0);
#ifdef HAVE_PTHREAD_H
rb_define_module_function(mBug, "postponed_job_register_in_c_thread", pjob_register_in_c_thread, 1);
#endif
- rb_define_module_function(mBug, "postponed_job_preregister_and_call_with_sleep", pjob_preregister_and_call_with_sleep, 1);
- rb_define_module_function(mBug, "postponed_job_preregister_and_call_without_sleep", pjob_preregister_and_call_without_sleep, 1);
- rb_define_module_function(mBug, "postponed_job_preregister_multiple_times", pjob_preregister_multiple_times, 0);
- rb_define_module_function(mBug, "postponed_job_preregister_calls_with_last_argument", pjob_preregister_calls_with_last_argument, 0);
}
diff --git a/ext/-test-/printf/depend b/ext/-test-/printf/depend
index b397041103..6dfe1fe03d 100644
--- a/ext/-test-/printf/depend
+++ b/ext/-test-/printf/depend
@@ -53,7 +53,6 @@ printf.o: $(hdrdir)/ruby/internal/attr/noexcept.h
printf.o: $(hdrdir)/ruby/internal/attr/noinline.h
printf.o: $(hdrdir)/ruby/internal/attr/nonnull.h
printf.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-printf.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
printf.o: $(hdrdir)/ruby/internal/attr/pure.h
printf.o: $(hdrdir)/ruby/internal/attr/restrict.h
printf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ printf.o: $(hdrdir)/ruby/internal/intern/enumerator.h
printf.o: $(hdrdir)/ruby/internal/intern/error.h
printf.o: $(hdrdir)/ruby/internal/intern/eval.h
printf.o: $(hdrdir)/ruby/internal/intern/file.h
+printf.o: $(hdrdir)/ruby/internal/intern/gc.h
printf.o: $(hdrdir)/ruby/internal/intern/hash.h
printf.o: $(hdrdir)/ruby/internal/intern/io.h
printf.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ printf.o: $(hdrdir)/ruby/internal/memory.h
printf.o: $(hdrdir)/ruby/internal/method.h
printf.o: $(hdrdir)/ruby/internal/module.h
printf.o: $(hdrdir)/ruby/internal/newobj.h
+printf.o: $(hdrdir)/ruby/internal/rgengc.h
printf.o: $(hdrdir)/ruby/internal/scan_args.h
printf.o: $(hdrdir)/ruby/internal/special_consts.h
printf.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/proc/depend b/ext/-test-/proc/depend
index 7e78aa6f83..e3f1cf6ce9 100644
--- a/ext/-test-/proc/depend
+++ b/ext/-test-/proc/depend
@@ -52,7 +52,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ receiver.o: $(hdrdir)/ruby/internal/attr/noexcept.h
receiver.o: $(hdrdir)/ruby/internal/attr/noinline.h
receiver.o: $(hdrdir)/ruby/internal/attr/nonnull.h
receiver.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-receiver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
receiver.o: $(hdrdir)/ruby/internal/attr/pure.h
receiver.o: $(hdrdir)/ruby/internal/attr/restrict.h
receiver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ receiver.o: $(hdrdir)/ruby/internal/intern/enumerator.h
receiver.o: $(hdrdir)/ruby/internal/intern/error.h
receiver.o: $(hdrdir)/ruby/internal/intern/eval.h
receiver.o: $(hdrdir)/ruby/internal/intern/file.h
+receiver.o: $(hdrdir)/ruby/internal/intern/gc.h
receiver.o: $(hdrdir)/ruby/internal/intern/hash.h
receiver.o: $(hdrdir)/ruby/internal/intern/io.h
receiver.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ receiver.o: $(hdrdir)/ruby/internal/memory.h
receiver.o: $(hdrdir)/ruby/internal/method.h
receiver.o: $(hdrdir)/ruby/internal/module.h
receiver.o: $(hdrdir)/ruby/internal/newobj.h
+receiver.o: $(hdrdir)/ruby/internal/rgengc.h
receiver.o: $(hdrdir)/ruby/internal/scan_args.h
receiver.o: $(hdrdir)/ruby/internal/special_consts.h
receiver.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -370,7 +372,6 @@ super.o: $(hdrdir)/ruby/internal/attr/noexcept.h
super.o: $(hdrdir)/ruby/internal/attr/noinline.h
super.o: $(hdrdir)/ruby/internal/attr/nonnull.h
super.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-super.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
super.o: $(hdrdir)/ruby/internal/attr/pure.h
super.o: $(hdrdir)/ruby/internal/attr/restrict.h
super.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -430,6 +431,7 @@ super.o: $(hdrdir)/ruby/internal/intern/enumerator.h
super.o: $(hdrdir)/ruby/internal/intern/error.h
super.o: $(hdrdir)/ruby/internal/intern/eval.h
super.o: $(hdrdir)/ruby/internal/intern/file.h
+super.o: $(hdrdir)/ruby/internal/intern/gc.h
super.o: $(hdrdir)/ruby/internal/intern/hash.h
super.o: $(hdrdir)/ruby/internal/intern/io.h
super.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -460,6 +462,7 @@ super.o: $(hdrdir)/ruby/internal/memory.h
super.o: $(hdrdir)/ruby/internal/method.h
super.o: $(hdrdir)/ruby/internal/module.h
super.o: $(hdrdir)/ruby/internal/newobj.h
+super.o: $(hdrdir)/ruby/internal/rgengc.h
super.o: $(hdrdir)/ruby/internal/scan_args.h
super.o: $(hdrdir)/ruby/internal/special_consts.h
super.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/random/depend b/ext/-test-/random/depend
index 3f9a52be44..f2cbf7fc14 100644
--- a/ext/-test-/random/depend
+++ b/ext/-test-/random/depend
@@ -51,7 +51,6 @@ bad_version.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bad_version.o: $(hdrdir)/ruby/internal/attr/noinline.h
bad_version.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bad_version.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bad_version.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bad_version.o: $(hdrdir)/ruby/internal/attr/pure.h
bad_version.o: $(hdrdir)/ruby/internal/attr/restrict.h
bad_version.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ bad_version.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bad_version.o: $(hdrdir)/ruby/internal/intern/error.h
bad_version.o: $(hdrdir)/ruby/internal/intern/eval.h
bad_version.o: $(hdrdir)/ruby/internal/intern/file.h
+bad_version.o: $(hdrdir)/ruby/internal/intern/gc.h
bad_version.o: $(hdrdir)/ruby/internal/intern/hash.h
bad_version.o: $(hdrdir)/ruby/internal/intern/io.h
bad_version.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ bad_version.o: $(hdrdir)/ruby/internal/memory.h
bad_version.o: $(hdrdir)/ruby/internal/method.h
bad_version.o: $(hdrdir)/ruby/internal/module.h
bad_version.o: $(hdrdir)/ruby/internal/newobj.h
+bad_version.o: $(hdrdir)/ruby/internal/rgengc.h
bad_version.o: $(hdrdir)/ruby/internal/scan_args.h
bad_version.o: $(hdrdir)/ruby/internal/special_consts.h
bad_version.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -369,7 +371,6 @@ loop.o: $(hdrdir)/ruby/internal/attr/noexcept.h
loop.o: $(hdrdir)/ruby/internal/attr/noinline.h
loop.o: $(hdrdir)/ruby/internal/attr/nonnull.h
loop.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-loop.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
loop.o: $(hdrdir)/ruby/internal/attr/pure.h
loop.o: $(hdrdir)/ruby/internal/attr/restrict.h
loop.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -429,6 +430,7 @@ loop.o: $(hdrdir)/ruby/internal/intern/enumerator.h
loop.o: $(hdrdir)/ruby/internal/intern/error.h
loop.o: $(hdrdir)/ruby/internal/intern/eval.h
loop.o: $(hdrdir)/ruby/internal/intern/file.h
+loop.o: $(hdrdir)/ruby/internal/intern/gc.h
loop.o: $(hdrdir)/ruby/internal/intern/hash.h
loop.o: $(hdrdir)/ruby/internal/intern/io.h
loop.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -459,6 +461,7 @@ loop.o: $(hdrdir)/ruby/internal/memory.h
loop.o: $(hdrdir)/ruby/internal/method.h
loop.o: $(hdrdir)/ruby/internal/module.h
loop.o: $(hdrdir)/ruby/internal/newobj.h
+loop.o: $(hdrdir)/ruby/internal/rgengc.h
loop.o: $(hdrdir)/ruby/internal/scan_args.h
loop.o: $(hdrdir)/ruby/internal/special_consts.h
loop.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/rational/depend b/ext/-test-/rational/depend
index cff2eae38d..ce977821b8 100644
--- a/ext/-test-/rational/depend
+++ b/ext/-test-/rational/depend
@@ -56,7 +56,6 @@ rat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rat.o: $(hdrdir)/ruby/internal/attr/noinline.h
rat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rat.o: $(hdrdir)/ruby/internal/attr/pure.h
rat.o: $(hdrdir)/ruby/internal/attr/restrict.h
rat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -116,6 +115,7 @@ rat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rat.o: $(hdrdir)/ruby/internal/intern/error.h
rat.o: $(hdrdir)/ruby/internal/intern/eval.h
rat.o: $(hdrdir)/ruby/internal/intern/file.h
+rat.o: $(hdrdir)/ruby/internal/intern/gc.h
rat.o: $(hdrdir)/ruby/internal/intern/hash.h
rat.o: $(hdrdir)/ruby/internal/intern/io.h
rat.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -146,6 +146,7 @@ rat.o: $(hdrdir)/ruby/internal/memory.h
rat.o: $(hdrdir)/ruby/internal/method.h
rat.o: $(hdrdir)/ruby/internal/module.h
rat.o: $(hdrdir)/ruby/internal/newobj.h
+rat.o: $(hdrdir)/ruby/internal/rgengc.h
rat.o: $(hdrdir)/ruby/internal/scan_args.h
rat.o: $(hdrdir)/ruby/internal/special_consts.h
rat.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/rb_call_super_kw/depend b/ext/-test-/rb_call_super_kw/depend
index a42ddc85ac..3512a081c9 100644
--- a/ext/-test-/rb_call_super_kw/depend
+++ b/ext/-test-/rb_call_super_kw/depend
@@ -52,7 +52,6 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noinline.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/pure.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/restrict.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/error.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/eval.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/gc.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/hash.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/io.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/memory.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/method.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/module.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/newobj.h
+rb_call_super_kw.o: $(hdrdir)/ruby/internal/rgengc.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/scan_args.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/special_consts.h
rb_call_super_kw.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/recursion/depend b/ext/-test-/recursion/depend
index 49377250ef..e499f95e73 100644
--- a/ext/-test-/recursion/depend
+++ b/ext/-test-/recursion/depend
@@ -52,7 +52,6 @@ recursion.o: $(hdrdir)/ruby/internal/attr/noexcept.h
recursion.o: $(hdrdir)/ruby/internal/attr/noinline.h
recursion.o: $(hdrdir)/ruby/internal/attr/nonnull.h
recursion.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-recursion.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
recursion.o: $(hdrdir)/ruby/internal/attr/pure.h
recursion.o: $(hdrdir)/ruby/internal/attr/restrict.h
recursion.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ recursion.o: $(hdrdir)/ruby/internal/intern/enumerator.h
recursion.o: $(hdrdir)/ruby/internal/intern/error.h
recursion.o: $(hdrdir)/ruby/internal/intern/eval.h
recursion.o: $(hdrdir)/ruby/internal/intern/file.h
+recursion.o: $(hdrdir)/ruby/internal/intern/gc.h
recursion.o: $(hdrdir)/ruby/internal/intern/hash.h
recursion.o: $(hdrdir)/ruby/internal/intern/io.h
recursion.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ recursion.o: $(hdrdir)/ruby/internal/memory.h
recursion.o: $(hdrdir)/ruby/internal/method.h
recursion.o: $(hdrdir)/ruby/internal/module.h
recursion.o: $(hdrdir)/ruby/internal/newobj.h
+recursion.o: $(hdrdir)/ruby/internal/rgengc.h
recursion.o: $(hdrdir)/ruby/internal/scan_args.h
recursion.o: $(hdrdir)/ruby/internal/special_consts.h
recursion.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/regexp/depend b/ext/-test-/regexp/depend
index 484f0320dd..fa431e013a 100644
--- a/ext/-test-/regexp/depend
+++ b/ext/-test-/regexp/depend
@@ -52,7 +52,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noexcept.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noinline.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/nonnull.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/pure.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/restrict.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/enumerator.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/error.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/eval.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/file.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/gc.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/hash.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/io.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/memory.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/method.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/module.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/newobj.h
+parse_depth_limit.o: $(hdrdir)/ruby/internal/rgengc.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/scan_args.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/special_consts.h
parse_depth_limit.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/scan_args/depend b/ext/-test-/scan_args/depend
index 3bedc6a7cf..2194936b04 100644
--- a/ext/-test-/scan_args/depend
+++ b/ext/-test-/scan_args/depend
@@ -52,7 +52,6 @@ scan_args.o: $(hdrdir)/ruby/internal/attr/noexcept.h
scan_args.o: $(hdrdir)/ruby/internal/attr/noinline.h
scan_args.o: $(hdrdir)/ruby/internal/attr/nonnull.h
scan_args.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-scan_args.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
scan_args.o: $(hdrdir)/ruby/internal/attr/pure.h
scan_args.o: $(hdrdir)/ruby/internal/attr/restrict.h
scan_args.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ scan_args.o: $(hdrdir)/ruby/internal/intern/enumerator.h
scan_args.o: $(hdrdir)/ruby/internal/intern/error.h
scan_args.o: $(hdrdir)/ruby/internal/intern/eval.h
scan_args.o: $(hdrdir)/ruby/internal/intern/file.h
+scan_args.o: $(hdrdir)/ruby/internal/intern/gc.h
scan_args.o: $(hdrdir)/ruby/internal/intern/hash.h
scan_args.o: $(hdrdir)/ruby/internal/intern/io.h
scan_args.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ scan_args.o: $(hdrdir)/ruby/internal/memory.h
scan_args.o: $(hdrdir)/ruby/internal/method.h
scan_args.o: $(hdrdir)/ruby/internal/module.h
scan_args.o: $(hdrdir)/ruby/internal/newobj.h
+scan_args.o: $(hdrdir)/ruby/internal/rgengc.h
scan_args.o: $(hdrdir)/ruby/internal/scan_args.h
scan_args.o: $(hdrdir)/ruby/internal/special_consts.h
scan_args.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/st/foreach/depend b/ext/-test-/st/foreach/depend
index fdfe356805..0464ee3c53 100644
--- a/ext/-test-/st/foreach/depend
+++ b/ext/-test-/st/foreach/depend
@@ -52,7 +52,6 @@ foreach.o: $(hdrdir)/ruby/internal/attr/noexcept.h
foreach.o: $(hdrdir)/ruby/internal/attr/noinline.h
foreach.o: $(hdrdir)/ruby/internal/attr/nonnull.h
foreach.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-foreach.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
foreach.o: $(hdrdir)/ruby/internal/attr/pure.h
foreach.o: $(hdrdir)/ruby/internal/attr/restrict.h
foreach.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ foreach.o: $(hdrdir)/ruby/internal/intern/enumerator.h
foreach.o: $(hdrdir)/ruby/internal/intern/error.h
foreach.o: $(hdrdir)/ruby/internal/intern/eval.h
foreach.o: $(hdrdir)/ruby/internal/intern/file.h
+foreach.o: $(hdrdir)/ruby/internal/intern/gc.h
foreach.o: $(hdrdir)/ruby/internal/intern/hash.h
foreach.o: $(hdrdir)/ruby/internal/intern/io.h
foreach.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ foreach.o: $(hdrdir)/ruby/internal/memory.h
foreach.o: $(hdrdir)/ruby/internal/method.h
foreach.o: $(hdrdir)/ruby/internal/module.h
foreach.o: $(hdrdir)/ruby/internal/newobj.h
+foreach.o: $(hdrdir)/ruby/internal/rgengc.h
foreach.o: $(hdrdir)/ruby/internal/scan_args.h
foreach.o: $(hdrdir)/ruby/internal/special_consts.h
foreach.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/st/foreach/foreach.c b/ext/-test-/st/foreach/foreach.c
index 7fbf064694..cde49fb26d 100644
--- a/ext/-test-/st/foreach/foreach.c
+++ b/ext/-test-/st/foreach/foreach.c
@@ -14,20 +14,20 @@ force_unpack_check(struct checker *c, st_data_t key, st_data_t val)
if (c->nr == 0) {
st_data_t i;
- if (c->tbl->bins != NULL) rb_bug("should be packed");
+ if (c->tbl->bins != NULL) rb_bug("should be packed\n");
/* force unpacking during iteration: */
for (i = 1; i < expect_size; i++)
st_add_direct(c->tbl, i, i);
- if (c->tbl->bins == NULL) rb_bug("should be unpacked");
+ if (c->tbl->bins == NULL) rb_bug("should be unpacked\n");
}
if (key != c->nr) {
- rb_bug("unexpected key: %"PRIuVALUE" (expected %"PRIuVALUE")", (VALUE)key, (VALUE)c->nr);
+ rb_bug("unexpected key: %"PRIuVALUE" (expected %"PRIuVALUE")\n", (VALUE)key, (VALUE)c->nr);
}
if (val != c->nr) {
- rb_bug("unexpected val: %"PRIuVALUE" (expected %"PRIuVALUE")", (VALUE)val, (VALUE)c->nr);
+ rb_bug("unexpected val: %"PRIuVALUE" (expected %"PRIuVALUE")\n", (VALUE)val, (VALUE)c->nr);
}
c->nr++;
@@ -60,7 +60,7 @@ unp_fec_i(st_data_t key, st_data_t val, st_data_t args, int error)
st_data_t v;
if (!st_delete(c->tbl, &k, &v)) {
- rb_bug("failed to delete");
+ rb_bug("failed to delete\n");
}
if (v != 0) {
rb_bug("unexpected value deleted: %"PRIuVALUE" (expected 0)", (VALUE)v);
@@ -84,21 +84,21 @@ unp_fec(VALUE self, VALUE test)
st_add_direct(tbl, 0, 0);
- if (tbl->bins != NULL) rb_bug("should still be packed");
+ if (tbl->bins != NULL) rb_bug("should still be packed\n");
st_foreach_check(tbl, unp_fec_i, (st_data_t)&c, -1);
if (c.test == ID2SYM(rb_intern("delete2"))) {
if (c.nr != 1) {
- rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)", (VALUE)c.nr);
+ rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)\n", (VALUE)c.nr);
}
}
else if (c.nr != expect_size) {
- rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE")",
+ rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE")\n",
(VALUE)c.nr, (VALUE)expect_size);
}
- if (tbl->bins == NULL) rb_bug("should be unpacked");
+ if (tbl->bins == NULL) rb_bug("should be unpacked\n");
st_free_table(tbl);
@@ -120,14 +120,14 @@ unp_fe_i(st_data_t key, st_data_t val, st_data_t args)
st_data_t v;
if (!st_delete(c->tbl, &k, &v)) {
- rb_bug("failed to delete");
+ rb_bug("failed to delete\n");
}
if (v != 0) {
rb_bug("unexpected value deleted: %"PRIuVALUE" (expected 0)", (VALUE)v);
}
return ST_CONTINUE;
}
- rb_bug("should never get here");
+ rb_bug("should never get here\n");
}
rb_raise(rb_eArgError, "unexpected arg: %+"PRIsVALUE, c->test);
@@ -145,21 +145,21 @@ unp_fe(VALUE self, VALUE test)
st_add_direct(tbl, 0, 0);
- if (tbl->bins != NULL) rb_bug("should still be packed");
+ if (tbl->bins != NULL) rb_bug("should still be packed\n");
st_foreach(tbl, unp_fe_i, (st_data_t)&c);
if (c.test == ID2SYM(rb_intern("unpack_delete"))) {
if (c.nr != 1) {
- rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)", (VALUE)c.nr);
+ rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)\n", (VALUE)c.nr);
}
}
else if (c.nr != expect_size) {
- rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE"o)",
+ rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE"o)\n",
(VALUE)c.nr, (VALUE)expect_size);
}
- if (tbl->bins == NULL) rb_bug("should be unpacked");
+ if (tbl->bins == NULL) rb_bug("should be unpacked\n");
st_free_table(tbl);
diff --git a/ext/-test-/st/numhash/depend b/ext/-test-/st/numhash/depend
index ef28c892f3..9665ed6e39 100644
--- a/ext/-test-/st/numhash/depend
+++ b/ext/-test-/st/numhash/depend
@@ -52,7 +52,6 @@ numhash.o: $(hdrdir)/ruby/internal/attr/noexcept.h
numhash.o: $(hdrdir)/ruby/internal/attr/noinline.h
numhash.o: $(hdrdir)/ruby/internal/attr/nonnull.h
numhash.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-numhash.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
numhash.o: $(hdrdir)/ruby/internal/attr/pure.h
numhash.o: $(hdrdir)/ruby/internal/attr/restrict.h
numhash.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ numhash.o: $(hdrdir)/ruby/internal/intern/enumerator.h
numhash.o: $(hdrdir)/ruby/internal/intern/error.h
numhash.o: $(hdrdir)/ruby/internal/intern/eval.h
numhash.o: $(hdrdir)/ruby/internal/intern/file.h
+numhash.o: $(hdrdir)/ruby/internal/intern/gc.h
numhash.o: $(hdrdir)/ruby/internal/intern/hash.h
numhash.o: $(hdrdir)/ruby/internal/intern/io.h
numhash.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ numhash.o: $(hdrdir)/ruby/internal/memory.h
numhash.o: $(hdrdir)/ruby/internal/method.h
numhash.o: $(hdrdir)/ruby/internal/module.h
numhash.o: $(hdrdir)/ruby/internal/newobj.h
+numhash.o: $(hdrdir)/ruby/internal/rgengc.h
numhash.o: $(hdrdir)/ruby/internal/scan_args.h
numhash.o: $(hdrdir)/ruby/internal/special_consts.h
numhash.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/st/update/depend b/ext/-test-/st/update/depend
index 2d5ff224a2..01960df965 100644
--- a/ext/-test-/st/update/depend
+++ b/ext/-test-/st/update/depend
@@ -52,7 +52,6 @@ update.o: $(hdrdir)/ruby/internal/attr/noexcept.h
update.o: $(hdrdir)/ruby/internal/attr/noinline.h
update.o: $(hdrdir)/ruby/internal/attr/nonnull.h
update.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-update.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
update.o: $(hdrdir)/ruby/internal/attr/pure.h
update.o: $(hdrdir)/ruby/internal/attr/restrict.h
update.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ update.o: $(hdrdir)/ruby/internal/intern/enumerator.h
update.o: $(hdrdir)/ruby/internal/intern/error.h
update.o: $(hdrdir)/ruby/internal/intern/eval.h
update.o: $(hdrdir)/ruby/internal/intern/file.h
+update.o: $(hdrdir)/ruby/internal/intern/gc.h
update.o: $(hdrdir)/ruby/internal/intern/hash.h
update.o: $(hdrdir)/ruby/internal/intern/io.h
update.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ update.o: $(hdrdir)/ruby/internal/memory.h
update.o: $(hdrdir)/ruby/internal/method.h
update.o: $(hdrdir)/ruby/internal/module.h
update.o: $(hdrdir)/ruby/internal/newobj.h
+update.o: $(hdrdir)/ruby/internal/rgengc.h
update.o: $(hdrdir)/ruby/internal/scan_args.h
update.o: $(hdrdir)/ruby/internal/special_consts.h
update.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/string/cstr.c b/ext/-test-/string/cstr.c
index b0b1ef5374..468ee7a3b1 100644
--- a/ext/-test-/string/cstr.c
+++ b/ext/-test-/string/cstr.c
@@ -61,12 +61,18 @@ bug_str_unterminated_substring(VALUE str, VALUE vbeg, VALUE vlen)
if (RSTRING_LEN(str) < beg) rb_raise(rb_eIndexError, "beg: %ld", beg);
if (RSTRING_LEN(str) < beg + len) rb_raise(rb_eIndexError, "end: %ld", beg + len);
str = rb_str_new_shared(str);
- RSTRING(str)->len = len;
if (STR_EMBED_P(str)) {
+#if USE_RVARGC
+ RSTRING(str)->as.embed.len = (short)len;
+#else
+ RSTRING(str)->basic.flags &= ~RSTRING_EMBED_LEN_MASK;
+ RSTRING(str)->basic.flags |= len << RSTRING_EMBED_LEN_SHIFT;
+#endif
memmove(RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.ary + beg, len);
}
else {
RSTRING(str)->as.heap.ptr += beg;
+ RSTRING(str)->as.heap.len = len;
}
return str;
}
@@ -110,10 +116,14 @@ bug_str_s_cstr_noembed(VALUE self, VALUE str)
Check_Type(str, T_STRING);
FL_SET((str2), STR_NOEMBED);
memcpy(buf, RSTRING_PTR(str), capacity);
+#if USE_RVARGC
RBASIC(str2)->flags &= ~(STR_SHARED | FL_USER5 | FL_USER6);
+#else
+ RBASIC(str2)->flags &= ~RSTRING_EMBED_LEN_MASK;
+#endif
RSTRING(str2)->as.heap.aux.capa = capacity;
RSTRING(str2)->as.heap.ptr = buf;
- RSTRING(str2)->len = RSTRING_LEN(str);
+ RSTRING(str2)->as.heap.len = RSTRING_LEN(str);
TERM_FILL(RSTRING_END(str2), TERM_LEN(str));
return str2;
}
diff --git a/ext/-test-/string/depend b/ext/-test-/string/depend
index eeb4914346..773231047e 100644
--- a/ext/-test-/string/depend
+++ b/ext/-test-/string/depend
@@ -54,7 +54,6 @@ capacity.o: $(hdrdir)/ruby/internal/attr/noexcept.h
capacity.o: $(hdrdir)/ruby/internal/attr/noinline.h
capacity.o: $(hdrdir)/ruby/internal/attr/nonnull.h
capacity.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-capacity.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
capacity.o: $(hdrdir)/ruby/internal/attr/pure.h
capacity.o: $(hdrdir)/ruby/internal/attr/restrict.h
capacity.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -123,6 +122,7 @@ capacity.o: $(hdrdir)/ruby/internal/intern/enumerator.h
capacity.o: $(hdrdir)/ruby/internal/intern/error.h
capacity.o: $(hdrdir)/ruby/internal/intern/eval.h
capacity.o: $(hdrdir)/ruby/internal/intern/file.h
+capacity.o: $(hdrdir)/ruby/internal/intern/gc.h
capacity.o: $(hdrdir)/ruby/internal/intern/hash.h
capacity.o: $(hdrdir)/ruby/internal/intern/io.h
capacity.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -153,6 +153,7 @@ capacity.o: $(hdrdir)/ruby/internal/memory.h
capacity.o: $(hdrdir)/ruby/internal/method.h
capacity.o: $(hdrdir)/ruby/internal/module.h
capacity.o: $(hdrdir)/ruby/internal/newobj.h
+capacity.o: $(hdrdir)/ruby/internal/rgengc.h
capacity.o: $(hdrdir)/ruby/internal/scan_args.h
capacity.o: $(hdrdir)/ruby/internal/special_consts.h
capacity.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -226,7 +227,6 @@ coderange.o: $(hdrdir)/ruby/internal/attr/noexcept.h
coderange.o: $(hdrdir)/ruby/internal/attr/noinline.h
coderange.o: $(hdrdir)/ruby/internal/attr/nonnull.h
coderange.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-coderange.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
coderange.o: $(hdrdir)/ruby/internal/attr/pure.h
coderange.o: $(hdrdir)/ruby/internal/attr/restrict.h
coderange.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -295,6 +295,7 @@ coderange.o: $(hdrdir)/ruby/internal/intern/enumerator.h
coderange.o: $(hdrdir)/ruby/internal/intern/error.h
coderange.o: $(hdrdir)/ruby/internal/intern/eval.h
coderange.o: $(hdrdir)/ruby/internal/intern/file.h
+coderange.o: $(hdrdir)/ruby/internal/intern/gc.h
coderange.o: $(hdrdir)/ruby/internal/intern/hash.h
coderange.o: $(hdrdir)/ruby/internal/intern/io.h
coderange.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -325,6 +326,7 @@ coderange.o: $(hdrdir)/ruby/internal/memory.h
coderange.o: $(hdrdir)/ruby/internal/method.h
coderange.o: $(hdrdir)/ruby/internal/module.h
coderange.o: $(hdrdir)/ruby/internal/newobj.h
+coderange.o: $(hdrdir)/ruby/internal/rgengc.h
coderange.o: $(hdrdir)/ruby/internal/scan_args.h
coderange.o: $(hdrdir)/ruby/internal/special_consts.h
coderange.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -397,7 +399,6 @@ cstr.o: $(hdrdir)/ruby/internal/attr/noexcept.h
cstr.o: $(hdrdir)/ruby/internal/attr/noinline.h
cstr.o: $(hdrdir)/ruby/internal/attr/nonnull.h
cstr.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-cstr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
cstr.o: $(hdrdir)/ruby/internal/attr/pure.h
cstr.o: $(hdrdir)/ruby/internal/attr/restrict.h
cstr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -466,6 +467,7 @@ cstr.o: $(hdrdir)/ruby/internal/intern/enumerator.h
cstr.o: $(hdrdir)/ruby/internal/intern/error.h
cstr.o: $(hdrdir)/ruby/internal/intern/eval.h
cstr.o: $(hdrdir)/ruby/internal/intern/file.h
+cstr.o: $(hdrdir)/ruby/internal/intern/gc.h
cstr.o: $(hdrdir)/ruby/internal/intern/hash.h
cstr.o: $(hdrdir)/ruby/internal/intern/io.h
cstr.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -496,6 +498,7 @@ cstr.o: $(hdrdir)/ruby/internal/memory.h
cstr.o: $(hdrdir)/ruby/internal/method.h
cstr.o: $(hdrdir)/ruby/internal/module.h
cstr.o: $(hdrdir)/ruby/internal/newobj.h
+cstr.o: $(hdrdir)/ruby/internal/rgengc.h
cstr.o: $(hdrdir)/ruby/internal/scan_args.h
cstr.o: $(hdrdir)/ruby/internal/special_consts.h
cstr.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -570,7 +573,6 @@ ellipsize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ellipsize.o: $(hdrdir)/ruby/internal/attr/noinline.h
ellipsize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ellipsize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ellipsize.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ellipsize.o: $(hdrdir)/ruby/internal/attr/pure.h
ellipsize.o: $(hdrdir)/ruby/internal/attr/restrict.h
ellipsize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -630,6 +632,7 @@ ellipsize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ellipsize.o: $(hdrdir)/ruby/internal/intern/error.h
ellipsize.o: $(hdrdir)/ruby/internal/intern/eval.h
ellipsize.o: $(hdrdir)/ruby/internal/intern/file.h
+ellipsize.o: $(hdrdir)/ruby/internal/intern/gc.h
ellipsize.o: $(hdrdir)/ruby/internal/intern/hash.h
ellipsize.o: $(hdrdir)/ruby/internal/intern/io.h
ellipsize.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -660,6 +663,7 @@ ellipsize.o: $(hdrdir)/ruby/internal/memory.h
ellipsize.o: $(hdrdir)/ruby/internal/method.h
ellipsize.o: $(hdrdir)/ruby/internal/module.h
ellipsize.o: $(hdrdir)/ruby/internal/newobj.h
+ellipsize.o: $(hdrdir)/ruby/internal/rgengc.h
ellipsize.o: $(hdrdir)/ruby/internal/scan_args.h
ellipsize.o: $(hdrdir)/ruby/internal/special_consts.h
ellipsize.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -730,7 +734,6 @@ enc_associate.o: $(hdrdir)/ruby/internal/attr/noexcept.h
enc_associate.o: $(hdrdir)/ruby/internal/attr/noinline.h
enc_associate.o: $(hdrdir)/ruby/internal/attr/nonnull.h
enc_associate.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-enc_associate.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
enc_associate.o: $(hdrdir)/ruby/internal/attr/pure.h
enc_associate.o: $(hdrdir)/ruby/internal/attr/restrict.h
enc_associate.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -799,6 +802,7 @@ enc_associate.o: $(hdrdir)/ruby/internal/intern/enumerator.h
enc_associate.o: $(hdrdir)/ruby/internal/intern/error.h
enc_associate.o: $(hdrdir)/ruby/internal/intern/eval.h
enc_associate.o: $(hdrdir)/ruby/internal/intern/file.h
+enc_associate.o: $(hdrdir)/ruby/internal/intern/gc.h
enc_associate.o: $(hdrdir)/ruby/internal/intern/hash.h
enc_associate.o: $(hdrdir)/ruby/internal/intern/io.h
enc_associate.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -829,6 +833,7 @@ enc_associate.o: $(hdrdir)/ruby/internal/memory.h
enc_associate.o: $(hdrdir)/ruby/internal/method.h
enc_associate.o: $(hdrdir)/ruby/internal/module.h
enc_associate.o: $(hdrdir)/ruby/internal/newobj.h
+enc_associate.o: $(hdrdir)/ruby/internal/rgengc.h
enc_associate.o: $(hdrdir)/ruby/internal/scan_args.h
enc_associate.o: $(hdrdir)/ruby/internal/special_consts.h
enc_associate.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -847,177 +852,6 @@ enc_associate.o: $(hdrdir)/ruby/ruby.h
enc_associate.o: $(hdrdir)/ruby/st.h
enc_associate.o: $(hdrdir)/ruby/subst.h
enc_associate.o: enc_associate.c
-enc_dummy.o: $(RUBY_EXTCONF_H)
-enc_dummy.o: $(arch_hdrdir)/ruby/config.h
-enc_dummy.o: $(hdrdir)/ruby.h
-enc_dummy.o: $(hdrdir)/ruby/assert.h
-enc_dummy.o: $(hdrdir)/ruby/backward.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/assume.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/attributes.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/bool.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/inttypes.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/limits.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/long_long.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/stdalign.h
-enc_dummy.o: $(hdrdir)/ruby/backward/2/stdarg.h
-enc_dummy.o: $(hdrdir)/ruby/defines.h
-enc_dummy.o: $(hdrdir)/ruby/encoding.h
-enc_dummy.o: $(hdrdir)/ruby/intern.h
-enc_dummy.o: $(hdrdir)/ruby/internal/abi.h
-enc_dummy.o: $(hdrdir)/ruby/internal/anyargs.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-enc_dummy.o: $(hdrdir)/ruby/internal/assume.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/artificial.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/cold.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/const.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/error.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/format.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/noalias.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/noinline.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/pure.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/restrict.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/warning.h
-enc_dummy.o: $(hdrdir)/ruby/internal/attr/weakref.h
-enc_dummy.o: $(hdrdir)/ruby/internal/cast.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-enc_dummy.o: $(hdrdir)/ruby/internal/compiler_since.h
-enc_dummy.o: $(hdrdir)/ruby/internal/config.h
-enc_dummy.o: $(hdrdir)/ruby/internal/constant_p.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rarray.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rbasic.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rbignum.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rclass.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rdata.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rfile.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rhash.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/robject.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rregexp.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rstring.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rstruct.h
-enc_dummy.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-enc_dummy.o: $(hdrdir)/ruby/internal/ctype.h
-enc_dummy.o: $(hdrdir)/ruby/internal/dllexport.h
-enc_dummy.o: $(hdrdir)/ruby/internal/dosish.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/coderange.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/ctype.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/encoding.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/pathname.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/re.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/string.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/symbol.h
-enc_dummy.o: $(hdrdir)/ruby/internal/encoding/transcode.h
-enc_dummy.o: $(hdrdir)/ruby/internal/error.h
-enc_dummy.o: $(hdrdir)/ruby/internal/eval.h
-enc_dummy.o: $(hdrdir)/ruby/internal/event.h
-enc_dummy.o: $(hdrdir)/ruby/internal/fl_type.h
-enc_dummy.o: $(hdrdir)/ruby/internal/gc.h
-enc_dummy.o: $(hdrdir)/ruby/internal/glob.h
-enc_dummy.o: $(hdrdir)/ruby/internal/globals.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/attribute.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/builtin.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/extension.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/feature.h
-enc_dummy.o: $(hdrdir)/ruby/internal/has/warning.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/array.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/bignum.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/class.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/compar.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/complex.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/cont.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/dir.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/enum.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/error.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/eval.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/file.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/hash.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/io.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/load.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/marshal.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/numeric.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/object.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/parse.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/proc.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/process.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/random.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/range.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/rational.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/re.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/ruby.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/select.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/signal.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/string.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/struct.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/thread.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/time.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/variable.h
-enc_dummy.o: $(hdrdir)/ruby/internal/intern/vm.h
-enc_dummy.o: $(hdrdir)/ruby/internal/interpreter.h
-enc_dummy.o: $(hdrdir)/ruby/internal/iterator.h
-enc_dummy.o: $(hdrdir)/ruby/internal/memory.h
-enc_dummy.o: $(hdrdir)/ruby/internal/method.h
-enc_dummy.o: $(hdrdir)/ruby/internal/module.h
-enc_dummy.o: $(hdrdir)/ruby/internal/newobj.h
-enc_dummy.o: $(hdrdir)/ruby/internal/scan_args.h
-enc_dummy.o: $(hdrdir)/ruby/internal/special_consts.h
-enc_dummy.o: $(hdrdir)/ruby/internal/static_assert.h
-enc_dummy.o: $(hdrdir)/ruby/internal/stdalign.h
-enc_dummy.o: $(hdrdir)/ruby/internal/stdbool.h
-enc_dummy.o: $(hdrdir)/ruby/internal/symbol.h
-enc_dummy.o: $(hdrdir)/ruby/internal/value.h
-enc_dummy.o: $(hdrdir)/ruby/internal/value_type.h
-enc_dummy.o: $(hdrdir)/ruby/internal/variable.h
-enc_dummy.o: $(hdrdir)/ruby/internal/warning_push.h
-enc_dummy.o: $(hdrdir)/ruby/internal/xmalloc.h
-enc_dummy.o: $(hdrdir)/ruby/missing.h
-enc_dummy.o: $(hdrdir)/ruby/onigmo.h
-enc_dummy.o: $(hdrdir)/ruby/oniguruma.h
-enc_dummy.o: $(hdrdir)/ruby/ruby.h
-enc_dummy.o: $(hdrdir)/ruby/st.h
-enc_dummy.o: $(hdrdir)/ruby/subst.h
-enc_dummy.o: enc_dummy.c
enc_str_buf_cat.o: $(RUBY_EXTCONF_H)
enc_str_buf_cat.o: $(arch_hdrdir)/ruby/config.h
enc_str_buf_cat.o: $(hdrdir)/ruby/assert.h
@@ -1071,7 +905,6 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noexcept.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noinline.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/nonnull.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/pure.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/restrict.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1140,6 +973,7 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/enumerator.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/error.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/eval.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/file.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/gc.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/hash.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/io.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1170,6 +1004,7 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/memory.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/method.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/module.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/newobj.h
+enc_str_buf_cat.o: $(hdrdir)/ruby/internal/rgengc.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/scan_args.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/special_consts.h
enc_str_buf_cat.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1196,7 +1031,6 @@ fstring.o: $(hdrdir)/ruby/backward.h
fstring.o: $(hdrdir)/ruby/backward/2/assume.h
fstring.o: $(hdrdir)/ruby/backward/2/attributes.h
fstring.o: $(hdrdir)/ruby/backward/2/bool.h
-fstring.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
fstring.o: $(hdrdir)/ruby/backward/2/inttypes.h
fstring.o: $(hdrdir)/ruby/backward/2/limits.h
fstring.o: $(hdrdir)/ruby/backward/2/long_long.h
@@ -1243,7 +1077,6 @@ fstring.o: $(hdrdir)/ruby/internal/attr/noexcept.h
fstring.o: $(hdrdir)/ruby/internal/attr/noinline.h
fstring.o: $(hdrdir)/ruby/internal/attr/nonnull.h
fstring.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-fstring.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
fstring.o: $(hdrdir)/ruby/internal/attr/pure.h
fstring.o: $(hdrdir)/ruby/internal/attr/restrict.h
fstring.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1312,6 +1145,7 @@ fstring.o: $(hdrdir)/ruby/internal/intern/enumerator.h
fstring.o: $(hdrdir)/ruby/internal/intern/error.h
fstring.o: $(hdrdir)/ruby/internal/intern/eval.h
fstring.o: $(hdrdir)/ruby/internal/intern/file.h
+fstring.o: $(hdrdir)/ruby/internal/intern/gc.h
fstring.o: $(hdrdir)/ruby/internal/intern/hash.h
fstring.o: $(hdrdir)/ruby/internal/intern/io.h
fstring.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1342,6 +1176,7 @@ fstring.o: $(hdrdir)/ruby/internal/memory.h
fstring.o: $(hdrdir)/ruby/internal/method.h
fstring.o: $(hdrdir)/ruby/internal/module.h
fstring.o: $(hdrdir)/ruby/internal/newobj.h
+fstring.o: $(hdrdir)/ruby/internal/rgengc.h
fstring.o: $(hdrdir)/ruby/internal/scan_args.h
fstring.o: $(hdrdir)/ruby/internal/special_consts.h
fstring.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1359,8 +1194,6 @@ fstring.o: $(hdrdir)/ruby/oniguruma.h
fstring.o: $(hdrdir)/ruby/ruby.h
fstring.o: $(hdrdir)/ruby/st.h
fstring.o: $(hdrdir)/ruby/subst.h
-fstring.o: $(top_srcdir)/internal/compilers.h
-fstring.o: $(top_srcdir)/internal/string.h
fstring.o: fstring.c
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
@@ -1415,7 +1248,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1475,6 +1307,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1505,6 +1338,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1574,7 +1408,6 @@ modify.o: $(hdrdir)/ruby/internal/attr/noexcept.h
modify.o: $(hdrdir)/ruby/internal/attr/noinline.h
modify.o: $(hdrdir)/ruby/internal/attr/nonnull.h
modify.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-modify.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
modify.o: $(hdrdir)/ruby/internal/attr/pure.h
modify.o: $(hdrdir)/ruby/internal/attr/restrict.h
modify.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1634,6 +1467,7 @@ modify.o: $(hdrdir)/ruby/internal/intern/enumerator.h
modify.o: $(hdrdir)/ruby/internal/intern/error.h
modify.o: $(hdrdir)/ruby/internal/intern/eval.h
modify.o: $(hdrdir)/ruby/internal/intern/file.h
+modify.o: $(hdrdir)/ruby/internal/intern/gc.h
modify.o: $(hdrdir)/ruby/internal/intern/hash.h
modify.o: $(hdrdir)/ruby/internal/intern/io.h
modify.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1664,6 +1498,7 @@ modify.o: $(hdrdir)/ruby/internal/memory.h
modify.o: $(hdrdir)/ruby/internal/method.h
modify.o: $(hdrdir)/ruby/internal/module.h
modify.o: $(hdrdir)/ruby/internal/newobj.h
+modify.o: $(hdrdir)/ruby/internal/rgengc.h
modify.o: $(hdrdir)/ruby/internal/scan_args.h
modify.o: $(hdrdir)/ruby/internal/special_consts.h
modify.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1734,7 +1569,6 @@ new.o: $(hdrdir)/ruby/internal/attr/noexcept.h
new.o: $(hdrdir)/ruby/internal/attr/noinline.h
new.o: $(hdrdir)/ruby/internal/attr/nonnull.h
new.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-new.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
new.o: $(hdrdir)/ruby/internal/attr/pure.h
new.o: $(hdrdir)/ruby/internal/attr/restrict.h
new.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1803,6 +1637,7 @@ new.o: $(hdrdir)/ruby/internal/intern/enumerator.h
new.o: $(hdrdir)/ruby/internal/intern/error.h
new.o: $(hdrdir)/ruby/internal/intern/eval.h
new.o: $(hdrdir)/ruby/internal/intern/file.h
+new.o: $(hdrdir)/ruby/internal/intern/gc.h
new.o: $(hdrdir)/ruby/internal/intern/hash.h
new.o: $(hdrdir)/ruby/internal/intern/io.h
new.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1833,6 +1668,7 @@ new.o: $(hdrdir)/ruby/internal/memory.h
new.o: $(hdrdir)/ruby/internal/method.h
new.o: $(hdrdir)/ruby/internal/module.h
new.o: $(hdrdir)/ruby/internal/newobj.h
+new.o: $(hdrdir)/ruby/internal/rgengc.h
new.o: $(hdrdir)/ruby/internal/scan_args.h
new.o: $(hdrdir)/ruby/internal/special_consts.h
new.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1904,7 +1740,6 @@ nofree.o: $(hdrdir)/ruby/internal/attr/noexcept.h
nofree.o: $(hdrdir)/ruby/internal/attr/noinline.h
nofree.o: $(hdrdir)/ruby/internal/attr/nonnull.h
nofree.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-nofree.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
nofree.o: $(hdrdir)/ruby/internal/attr/pure.h
nofree.o: $(hdrdir)/ruby/internal/attr/restrict.h
nofree.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1964,6 +1799,7 @@ nofree.o: $(hdrdir)/ruby/internal/intern/enumerator.h
nofree.o: $(hdrdir)/ruby/internal/intern/error.h
nofree.o: $(hdrdir)/ruby/internal/intern/eval.h
nofree.o: $(hdrdir)/ruby/internal/intern/file.h
+nofree.o: $(hdrdir)/ruby/internal/intern/gc.h
nofree.o: $(hdrdir)/ruby/internal/intern/hash.h
nofree.o: $(hdrdir)/ruby/internal/intern/io.h
nofree.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1994,6 +1830,7 @@ nofree.o: $(hdrdir)/ruby/internal/memory.h
nofree.o: $(hdrdir)/ruby/internal/method.h
nofree.o: $(hdrdir)/ruby/internal/module.h
nofree.o: $(hdrdir)/ruby/internal/newobj.h
+nofree.o: $(hdrdir)/ruby/internal/rgengc.h
nofree.o: $(hdrdir)/ruby/internal/scan_args.h
nofree.o: $(hdrdir)/ruby/internal/special_consts.h
nofree.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2063,7 +1900,6 @@ normalize.o: $(hdrdir)/ruby/internal/attr/noexcept.h
normalize.o: $(hdrdir)/ruby/internal/attr/noinline.h
normalize.o: $(hdrdir)/ruby/internal/attr/nonnull.h
normalize.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-normalize.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
normalize.o: $(hdrdir)/ruby/internal/attr/pure.h
normalize.o: $(hdrdir)/ruby/internal/attr/restrict.h
normalize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2132,6 +1968,7 @@ normalize.o: $(hdrdir)/ruby/internal/intern/enumerator.h
normalize.o: $(hdrdir)/ruby/internal/intern/error.h
normalize.o: $(hdrdir)/ruby/internal/intern/eval.h
normalize.o: $(hdrdir)/ruby/internal/intern/file.h
+normalize.o: $(hdrdir)/ruby/internal/intern/gc.h
normalize.o: $(hdrdir)/ruby/internal/intern/hash.h
normalize.o: $(hdrdir)/ruby/internal/intern/io.h
normalize.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2162,6 +1999,7 @@ normalize.o: $(hdrdir)/ruby/internal/memory.h
normalize.o: $(hdrdir)/ruby/internal/method.h
normalize.o: $(hdrdir)/ruby/internal/module.h
normalize.o: $(hdrdir)/ruby/internal/newobj.h
+normalize.o: $(hdrdir)/ruby/internal/rgengc.h
normalize.o: $(hdrdir)/ruby/internal/scan_args.h
normalize.o: $(hdrdir)/ruby/internal/special_consts.h
normalize.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2235,7 +2073,6 @@ qsort.o: $(hdrdir)/ruby/internal/attr/noexcept.h
qsort.o: $(hdrdir)/ruby/internal/attr/noinline.h
qsort.o: $(hdrdir)/ruby/internal/attr/nonnull.h
qsort.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-qsort.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
qsort.o: $(hdrdir)/ruby/internal/attr/pure.h
qsort.o: $(hdrdir)/ruby/internal/attr/restrict.h
qsort.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2304,6 +2141,7 @@ qsort.o: $(hdrdir)/ruby/internal/intern/enumerator.h
qsort.o: $(hdrdir)/ruby/internal/intern/error.h
qsort.o: $(hdrdir)/ruby/internal/intern/eval.h
qsort.o: $(hdrdir)/ruby/internal/intern/file.h
+qsort.o: $(hdrdir)/ruby/internal/intern/gc.h
qsort.o: $(hdrdir)/ruby/internal/intern/hash.h
qsort.o: $(hdrdir)/ruby/internal/intern/io.h
qsort.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2334,6 +2172,7 @@ qsort.o: $(hdrdir)/ruby/internal/memory.h
qsort.o: $(hdrdir)/ruby/internal/method.h
qsort.o: $(hdrdir)/ruby/internal/module.h
qsort.o: $(hdrdir)/ruby/internal/newobj.h
+qsort.o: $(hdrdir)/ruby/internal/rgengc.h
qsort.o: $(hdrdir)/ruby/internal/scan_args.h
qsort.o: $(hdrdir)/ruby/internal/special_consts.h
qsort.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2406,7 +2245,6 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noinline.h
rb_interned_str.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rb_interned_str.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rb_interned_str.o: $(hdrdir)/ruby/internal/attr/pure.h
rb_interned_str.o: $(hdrdir)/ruby/internal/attr/restrict.h
rb_interned_str.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2466,6 +2304,7 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rb_interned_str.o: $(hdrdir)/ruby/internal/intern/error.h
rb_interned_str.o: $(hdrdir)/ruby/internal/intern/eval.h
rb_interned_str.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/intern/gc.h
rb_interned_str.o: $(hdrdir)/ruby/internal/intern/hash.h
rb_interned_str.o: $(hdrdir)/ruby/internal/intern/io.h
rb_interned_str.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2496,6 +2335,7 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/memory.h
rb_interned_str.o: $(hdrdir)/ruby/internal/method.h
rb_interned_str.o: $(hdrdir)/ruby/internal/module.h
rb_interned_str.o: $(hdrdir)/ruby/internal/newobj.h
+rb_interned_str.o: $(hdrdir)/ruby/internal/rgengc.h
rb_interned_str.o: $(hdrdir)/ruby/internal/scan_args.h
rb_interned_str.o: $(hdrdir)/ruby/internal/special_consts.h
rb_interned_str.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2565,7 +2405,6 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noinline.h
rb_str_dup.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rb_str_dup.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rb_str_dup.o: $(hdrdir)/ruby/internal/attr/pure.h
rb_str_dup.o: $(hdrdir)/ruby/internal/attr/restrict.h
rb_str_dup.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2625,6 +2464,7 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rb_str_dup.o: $(hdrdir)/ruby/internal/intern/error.h
rb_str_dup.o: $(hdrdir)/ruby/internal/intern/eval.h
rb_str_dup.o: $(hdrdir)/ruby/internal/intern/file.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/intern/gc.h
rb_str_dup.o: $(hdrdir)/ruby/internal/intern/hash.h
rb_str_dup.o: $(hdrdir)/ruby/internal/intern/io.h
rb_str_dup.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2655,6 +2495,7 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/memory.h
rb_str_dup.o: $(hdrdir)/ruby/internal/method.h
rb_str_dup.o: $(hdrdir)/ruby/internal/module.h
rb_str_dup.o: $(hdrdir)/ruby/internal/newobj.h
+rb_str_dup.o: $(hdrdir)/ruby/internal/rgengc.h
rb_str_dup.o: $(hdrdir)/ruby/internal/scan_args.h
rb_str_dup.o: $(hdrdir)/ruby/internal/special_consts.h
rb_str_dup.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2724,7 +2565,6 @@ set_len.o: $(hdrdir)/ruby/internal/attr/noexcept.h
set_len.o: $(hdrdir)/ruby/internal/attr/noinline.h
set_len.o: $(hdrdir)/ruby/internal/attr/nonnull.h
set_len.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-set_len.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
set_len.o: $(hdrdir)/ruby/internal/attr/pure.h
set_len.o: $(hdrdir)/ruby/internal/attr/restrict.h
set_len.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2784,6 +2624,7 @@ set_len.o: $(hdrdir)/ruby/internal/intern/enumerator.h
set_len.o: $(hdrdir)/ruby/internal/intern/error.h
set_len.o: $(hdrdir)/ruby/internal/intern/eval.h
set_len.o: $(hdrdir)/ruby/internal/intern/file.h
+set_len.o: $(hdrdir)/ruby/internal/intern/gc.h
set_len.o: $(hdrdir)/ruby/internal/intern/hash.h
set_len.o: $(hdrdir)/ruby/internal/intern/io.h
set_len.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2814,6 +2655,7 @@ set_len.o: $(hdrdir)/ruby/internal/memory.h
set_len.o: $(hdrdir)/ruby/internal/method.h
set_len.o: $(hdrdir)/ruby/internal/module.h
set_len.o: $(hdrdir)/ruby/internal/newobj.h
+set_len.o: $(hdrdir)/ruby/internal/rgengc.h
set_len.o: $(hdrdir)/ruby/internal/scan_args.h
set_len.o: $(hdrdir)/ruby/internal/special_consts.h
set_len.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/string/enc_dummy.c b/ext/-test-/string/enc_dummy.c
deleted file mode 100644
index 4169552655..0000000000
--- a/ext/-test-/string/enc_dummy.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "ruby.h"
-#include "ruby/encoding.h"
-
-VALUE
-bug_rb_define_dummy_encoding(VALUE self, VALUE name)
-{
- int idx = rb_define_dummy_encoding(RSTRING_PTR(name));
- return rb_enc_from_encoding(rb_enc_from_index(idx));
-}
-
-void
-Init_string_enc_dummy(VALUE klass)
-{
- rb_define_singleton_method(klass, "rb_define_dummy_encoding", bug_rb_define_dummy_encoding, 1);
-}
diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c
index 8dfa36e345..64f079251d 100644
--- a/ext/-test-/string/fstring.c
+++ b/ext/-test-/string/fstring.c
@@ -1,6 +1,5 @@
#include "ruby.h"
#include "ruby/encoding.h"
-#include "internal/string.h"
VALUE rb_fstring(VALUE str);
@@ -11,14 +10,6 @@ bug_s_fstring(VALUE self, VALUE str)
}
VALUE
-bug_s_fstring_fake_str(VALUE self)
-{
- static const char literal[] = "abcdefghijklmnopqrstuvwxyz";
- struct RString fake_str;
- return rb_fstring(rb_setup_fake_str(&fake_str, literal, sizeof(literal) - 1, 0));
-}
-
-VALUE
bug_s_rb_enc_interned_str(VALUE self, VALUE encoding)
{
return rb_enc_interned_str("foo", 3, NIL_P(encoding) ? NULL : RDATA(encoding)->data);
@@ -34,7 +25,6 @@ void
Init_string_fstring(VALUE klass)
{
rb_define_singleton_method(klass, "fstring", bug_s_fstring, 1);
- rb_define_singleton_method(klass, "fstring_fake_str", bug_s_fstring_fake_str, 0);
rb_define_singleton_method(klass, "rb_enc_interned_str", bug_s_rb_enc_interned_str, 1);
rb_define_singleton_method(klass, "rb_enc_str_new", bug_s_rb_enc_str_new, 1);
}
diff --git a/ext/-test-/struct/data.c b/ext/-test-/struct/data.c
deleted file mode 100644
index 5841c342e7..0000000000
--- a/ext/-test-/struct/data.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "ruby.h"
-
-static VALUE
-bug_data_new(VALUE self, VALUE super)
-{
- return rb_data_define(super, "mem1", "mem2", NULL);
-}
-
-void
-Init_data(VALUE klass)
-{
- rb_define_singleton_method(klass, "data_new", bug_data_new, 1);
-}
diff --git a/ext/-test-/struct/depend b/ext/-test-/struct/depend
index 5db943e286..920a065216 100644
--- a/ext/-test-/struct/depend
+++ b/ext/-test-/struct/depend
@@ -1,163 +1,4 @@
# AUTOGENERATED DEPENDENCIES START
-data.o: $(RUBY_EXTCONF_H)
-data.o: $(arch_hdrdir)/ruby/config.h
-data.o: $(hdrdir)/ruby.h
-data.o: $(hdrdir)/ruby/assert.h
-data.o: $(hdrdir)/ruby/backward.h
-data.o: $(hdrdir)/ruby/backward/2/assume.h
-data.o: $(hdrdir)/ruby/backward/2/attributes.h
-data.o: $(hdrdir)/ruby/backward/2/bool.h
-data.o: $(hdrdir)/ruby/backward/2/inttypes.h
-data.o: $(hdrdir)/ruby/backward/2/limits.h
-data.o: $(hdrdir)/ruby/backward/2/long_long.h
-data.o: $(hdrdir)/ruby/backward/2/stdalign.h
-data.o: $(hdrdir)/ruby/backward/2/stdarg.h
-data.o: $(hdrdir)/ruby/defines.h
-data.o: $(hdrdir)/ruby/intern.h
-data.o: $(hdrdir)/ruby/internal/abi.h
-data.o: $(hdrdir)/ruby/internal/anyargs.h
-data.o: $(hdrdir)/ruby/internal/arithmetic.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-data.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-data.o: $(hdrdir)/ruby/internal/assume.h
-data.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-data.o: $(hdrdir)/ruby/internal/attr/artificial.h
-data.o: $(hdrdir)/ruby/internal/attr/cold.h
-data.o: $(hdrdir)/ruby/internal/attr/const.h
-data.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-data.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-data.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-data.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-data.o: $(hdrdir)/ruby/internal/attr/error.h
-data.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-data.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-data.o: $(hdrdir)/ruby/internal/attr/format.h
-data.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-data.o: $(hdrdir)/ruby/internal/attr/noalias.h
-data.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-data.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-data.o: $(hdrdir)/ruby/internal/attr/noinline.h
-data.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-data.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-data.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
-data.o: $(hdrdir)/ruby/internal/attr/pure.h
-data.o: $(hdrdir)/ruby/internal/attr/restrict.h
-data.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-data.o: $(hdrdir)/ruby/internal/attr/warning.h
-data.o: $(hdrdir)/ruby/internal/attr/weakref.h
-data.o: $(hdrdir)/ruby/internal/cast.h
-data.o: $(hdrdir)/ruby/internal/compiler_is.h
-data.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-data.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-data.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-data.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-data.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-data.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-data.o: $(hdrdir)/ruby/internal/compiler_since.h
-data.o: $(hdrdir)/ruby/internal/config.h
-data.o: $(hdrdir)/ruby/internal/constant_p.h
-data.o: $(hdrdir)/ruby/internal/core.h
-data.o: $(hdrdir)/ruby/internal/core/rarray.h
-data.o: $(hdrdir)/ruby/internal/core/rbasic.h
-data.o: $(hdrdir)/ruby/internal/core/rbignum.h
-data.o: $(hdrdir)/ruby/internal/core/rclass.h
-data.o: $(hdrdir)/ruby/internal/core/rdata.h
-data.o: $(hdrdir)/ruby/internal/core/rfile.h
-data.o: $(hdrdir)/ruby/internal/core/rhash.h
-data.o: $(hdrdir)/ruby/internal/core/robject.h
-data.o: $(hdrdir)/ruby/internal/core/rregexp.h
-data.o: $(hdrdir)/ruby/internal/core/rstring.h
-data.o: $(hdrdir)/ruby/internal/core/rstruct.h
-data.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-data.o: $(hdrdir)/ruby/internal/ctype.h
-data.o: $(hdrdir)/ruby/internal/dllexport.h
-data.o: $(hdrdir)/ruby/internal/dosish.h
-data.o: $(hdrdir)/ruby/internal/error.h
-data.o: $(hdrdir)/ruby/internal/eval.h
-data.o: $(hdrdir)/ruby/internal/event.h
-data.o: $(hdrdir)/ruby/internal/fl_type.h
-data.o: $(hdrdir)/ruby/internal/gc.h
-data.o: $(hdrdir)/ruby/internal/glob.h
-data.o: $(hdrdir)/ruby/internal/globals.h
-data.o: $(hdrdir)/ruby/internal/has/attribute.h
-data.o: $(hdrdir)/ruby/internal/has/builtin.h
-data.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-data.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-data.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-data.o: $(hdrdir)/ruby/internal/has/extension.h
-data.o: $(hdrdir)/ruby/internal/has/feature.h
-data.o: $(hdrdir)/ruby/internal/has/warning.h
-data.o: $(hdrdir)/ruby/internal/intern/array.h
-data.o: $(hdrdir)/ruby/internal/intern/bignum.h
-data.o: $(hdrdir)/ruby/internal/intern/class.h
-data.o: $(hdrdir)/ruby/internal/intern/compar.h
-data.o: $(hdrdir)/ruby/internal/intern/complex.h
-data.o: $(hdrdir)/ruby/internal/intern/cont.h
-data.o: $(hdrdir)/ruby/internal/intern/dir.h
-data.o: $(hdrdir)/ruby/internal/intern/enum.h
-data.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-data.o: $(hdrdir)/ruby/internal/intern/error.h
-data.o: $(hdrdir)/ruby/internal/intern/eval.h
-data.o: $(hdrdir)/ruby/internal/intern/file.h
-data.o: $(hdrdir)/ruby/internal/intern/hash.h
-data.o: $(hdrdir)/ruby/internal/intern/io.h
-data.o: $(hdrdir)/ruby/internal/intern/load.h
-data.o: $(hdrdir)/ruby/internal/intern/marshal.h
-data.o: $(hdrdir)/ruby/internal/intern/numeric.h
-data.o: $(hdrdir)/ruby/internal/intern/object.h
-data.o: $(hdrdir)/ruby/internal/intern/parse.h
-data.o: $(hdrdir)/ruby/internal/intern/proc.h
-data.o: $(hdrdir)/ruby/internal/intern/process.h
-data.o: $(hdrdir)/ruby/internal/intern/random.h
-data.o: $(hdrdir)/ruby/internal/intern/range.h
-data.o: $(hdrdir)/ruby/internal/intern/rational.h
-data.o: $(hdrdir)/ruby/internal/intern/re.h
-data.o: $(hdrdir)/ruby/internal/intern/ruby.h
-data.o: $(hdrdir)/ruby/internal/intern/select.h
-data.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-data.o: $(hdrdir)/ruby/internal/intern/signal.h
-data.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-data.o: $(hdrdir)/ruby/internal/intern/string.h
-data.o: $(hdrdir)/ruby/internal/intern/struct.h
-data.o: $(hdrdir)/ruby/internal/intern/thread.h
-data.o: $(hdrdir)/ruby/internal/intern/time.h
-data.o: $(hdrdir)/ruby/internal/intern/variable.h
-data.o: $(hdrdir)/ruby/internal/intern/vm.h
-data.o: $(hdrdir)/ruby/internal/interpreter.h
-data.o: $(hdrdir)/ruby/internal/iterator.h
-data.o: $(hdrdir)/ruby/internal/memory.h
-data.o: $(hdrdir)/ruby/internal/method.h
-data.o: $(hdrdir)/ruby/internal/module.h
-data.o: $(hdrdir)/ruby/internal/newobj.h
-data.o: $(hdrdir)/ruby/internal/scan_args.h
-data.o: $(hdrdir)/ruby/internal/special_consts.h
-data.o: $(hdrdir)/ruby/internal/static_assert.h
-data.o: $(hdrdir)/ruby/internal/stdalign.h
-data.o: $(hdrdir)/ruby/internal/stdbool.h
-data.o: $(hdrdir)/ruby/internal/symbol.h
-data.o: $(hdrdir)/ruby/internal/value.h
-data.o: $(hdrdir)/ruby/internal/value_type.h
-data.o: $(hdrdir)/ruby/internal/variable.h
-data.o: $(hdrdir)/ruby/internal/warning_push.h
-data.o: $(hdrdir)/ruby/internal/xmalloc.h
-data.o: $(hdrdir)/ruby/missing.h
-data.o: $(hdrdir)/ruby/ruby.h
-data.o: $(hdrdir)/ruby/st.h
-data.o: $(hdrdir)/ruby/subst.h
-data.o: data.c
duplicate.o: $(RUBY_EXTCONF_H)
duplicate.o: $(arch_hdrdir)/ruby/config.h
duplicate.o: $(hdrdir)/ruby.h
@@ -211,7 +52,6 @@ duplicate.o: $(hdrdir)/ruby/internal/attr/noexcept.h
duplicate.o: $(hdrdir)/ruby/internal/attr/noinline.h
duplicate.o: $(hdrdir)/ruby/internal/attr/nonnull.h
duplicate.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-duplicate.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
duplicate.o: $(hdrdir)/ruby/internal/attr/pure.h
duplicate.o: $(hdrdir)/ruby/internal/attr/restrict.h
duplicate.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +111,7 @@ duplicate.o: $(hdrdir)/ruby/internal/intern/enumerator.h
duplicate.o: $(hdrdir)/ruby/internal/intern/error.h
duplicate.o: $(hdrdir)/ruby/internal/intern/eval.h
duplicate.o: $(hdrdir)/ruby/internal/intern/file.h
+duplicate.o: $(hdrdir)/ruby/internal/intern/gc.h
duplicate.o: $(hdrdir)/ruby/internal/intern/hash.h
duplicate.o: $(hdrdir)/ruby/internal/intern/io.h
duplicate.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +142,7 @@ duplicate.o: $(hdrdir)/ruby/internal/memory.h
duplicate.o: $(hdrdir)/ruby/internal/method.h
duplicate.o: $(hdrdir)/ruby/internal/module.h
duplicate.o: $(hdrdir)/ruby/internal/newobj.h
+duplicate.o: $(hdrdir)/ruby/internal/rgengc.h
duplicate.o: $(hdrdir)/ruby/internal/scan_args.h
duplicate.o: $(hdrdir)/ruby/internal/special_consts.h
duplicate.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -370,7 +212,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -430,6 +271,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -460,6 +302,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -529,7 +372,6 @@ len.o: $(hdrdir)/ruby/internal/attr/noexcept.h
len.o: $(hdrdir)/ruby/internal/attr/noinline.h
len.o: $(hdrdir)/ruby/internal/attr/nonnull.h
len.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-len.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
len.o: $(hdrdir)/ruby/internal/attr/pure.h
len.o: $(hdrdir)/ruby/internal/attr/restrict.h
len.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -589,6 +431,7 @@ len.o: $(hdrdir)/ruby/internal/intern/enumerator.h
len.o: $(hdrdir)/ruby/internal/intern/error.h
len.o: $(hdrdir)/ruby/internal/intern/eval.h
len.o: $(hdrdir)/ruby/internal/intern/file.h
+len.o: $(hdrdir)/ruby/internal/intern/gc.h
len.o: $(hdrdir)/ruby/internal/intern/hash.h
len.o: $(hdrdir)/ruby/internal/intern/io.h
len.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -619,6 +462,7 @@ len.o: $(hdrdir)/ruby/internal/memory.h
len.o: $(hdrdir)/ruby/internal/method.h
len.o: $(hdrdir)/ruby/internal/module.h
len.o: $(hdrdir)/ruby/internal/newobj.h
+len.o: $(hdrdir)/ruby/internal/rgengc.h
len.o: $(hdrdir)/ruby/internal/scan_args.h
len.o: $(hdrdir)/ruby/internal/special_consts.h
len.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -688,7 +532,6 @@ member.o: $(hdrdir)/ruby/internal/attr/noexcept.h
member.o: $(hdrdir)/ruby/internal/attr/noinline.h
member.o: $(hdrdir)/ruby/internal/attr/nonnull.h
member.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-member.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
member.o: $(hdrdir)/ruby/internal/attr/pure.h
member.o: $(hdrdir)/ruby/internal/attr/restrict.h
member.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -748,6 +591,7 @@ member.o: $(hdrdir)/ruby/internal/intern/enumerator.h
member.o: $(hdrdir)/ruby/internal/intern/error.h
member.o: $(hdrdir)/ruby/internal/intern/eval.h
member.o: $(hdrdir)/ruby/internal/intern/file.h
+member.o: $(hdrdir)/ruby/internal/intern/gc.h
member.o: $(hdrdir)/ruby/internal/intern/hash.h
member.o: $(hdrdir)/ruby/internal/intern/io.h
member.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -778,6 +622,7 @@ member.o: $(hdrdir)/ruby/internal/memory.h
member.o: $(hdrdir)/ruby/internal/method.h
member.o: $(hdrdir)/ruby/internal/module.h
member.o: $(hdrdir)/ruby/internal/newobj.h
+member.o: $(hdrdir)/ruby/internal/rgengc.h
member.o: $(hdrdir)/ruby/internal/scan_args.h
member.o: $(hdrdir)/ruby/internal/special_consts.h
member.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/symbol/depend b/ext/-test-/symbol/depend
index dd1b5c305f..b94e4ce821 100644
--- a/ext/-test-/symbol/depend
+++ b/ext/-test-/symbol/depend
@@ -52,7 +52,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ type.o: $(hdrdir)/ruby/internal/attr/noexcept.h
type.o: $(hdrdir)/ruby/internal/attr/noinline.h
type.o: $(hdrdir)/ruby/internal/attr/nonnull.h
type.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-type.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
type.o: $(hdrdir)/ruby/internal/attr/pure.h
type.o: $(hdrdir)/ruby/internal/attr/restrict.h
type.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ type.o: $(hdrdir)/ruby/internal/intern/enumerator.h
type.o: $(hdrdir)/ruby/internal/intern/error.h
type.o: $(hdrdir)/ruby/internal/intern/eval.h
type.o: $(hdrdir)/ruby/internal/intern/file.h
+type.o: $(hdrdir)/ruby/internal/intern/gc.h
type.o: $(hdrdir)/ruby/internal/intern/hash.h
type.o: $(hdrdir)/ruby/internal/intern/io.h
type.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ type.o: $(hdrdir)/ruby/internal/memory.h
type.o: $(hdrdir)/ruby/internal/method.h
type.o: $(hdrdir)/ruby/internal/module.h
type.o: $(hdrdir)/ruby/internal/newobj.h
+type.o: $(hdrdir)/ruby/internal/rgengc.h
type.o: $(hdrdir)/ruby/internal/scan_args.h
type.o: $(hdrdir)/ruby/internal/special_consts.h
type.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/thread/instrumentation/depend b/ext/-test-/thread/instrumentation/depend
index b03f51870f..e2fcd060d8 100644
--- a/ext/-test-/thread/instrumentation/depend
+++ b/ext/-test-/thread/instrumentation/depend
@@ -52,7 +52,6 @@ instrumentation.o: $(hdrdir)/ruby/internal/attr/noexcept.h
instrumentation.o: $(hdrdir)/ruby/internal/attr/noinline.h
instrumentation.o: $(hdrdir)/ruby/internal/attr/nonnull.h
instrumentation.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-instrumentation.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
instrumentation.o: $(hdrdir)/ruby/internal/attr/pure.h
instrumentation.o: $(hdrdir)/ruby/internal/attr/restrict.h
instrumentation.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ instrumentation.o: $(hdrdir)/ruby/internal/intern/enumerator.h
instrumentation.o: $(hdrdir)/ruby/internal/intern/error.h
instrumentation.o: $(hdrdir)/ruby/internal/intern/eval.h
instrumentation.o: $(hdrdir)/ruby/internal/intern/file.h
+instrumentation.o: $(hdrdir)/ruby/internal/intern/gc.h
instrumentation.o: $(hdrdir)/ruby/internal/intern/hash.h
instrumentation.o: $(hdrdir)/ruby/internal/intern/io.h
instrumentation.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ instrumentation.o: $(hdrdir)/ruby/internal/memory.h
instrumentation.o: $(hdrdir)/ruby/internal/method.h
instrumentation.o: $(hdrdir)/ruby/internal/module.h
instrumentation.o: $(hdrdir)/ruby/internal/newobj.h
+instrumentation.o: $(hdrdir)/ruby/internal/rgengc.h
instrumentation.o: $(hdrdir)/ruby/internal/scan_args.h
instrumentation.o: $(hdrdir)/ruby/internal/special_consts.h
instrumentation.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/thread/instrumentation/instrumentation.c b/ext/-test-/thread/instrumentation/instrumentation.c
index d81bc0f2a7..d2a2c2740b 100644
--- a/ext/-test-/thread/instrumentation/instrumentation.c
+++ b/ext/-test-/thread/instrumentation/instrumentation.c
@@ -2,137 +2,90 @@
#include "ruby/atomic.h"
#include "ruby/thread.h"
-#ifndef RB_THREAD_LOCAL_SPECIFIER
-# define RB_THREAD_LOCAL_SPECIFIER
+static rb_atomic_t started_count = 0;
+static rb_atomic_t ready_count = 0;
+static rb_atomic_t resumed_count = 0;
+static rb_atomic_t suspended_count = 0;
+static rb_atomic_t exited_count = 0;
+
+#if __STDC_VERSION__ >= 201112
+ #define RB_THREAD_LOCAL_SPECIFIER _Thread_local
+#elif defined(__GNUC__) && !defined(RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED)
+ /* note that ICC (linux) and Clang are covered by __GNUC__ */
+ #define RB_THREAD_LOCAL_SPECIFIER __thread
+#else
+ #define RB_THREAD_LOCAL_SPECIFIER
#endif
-static VALUE last_thread = Qnil;
-static VALUE timeline_value = Qnil;
-
-struct thread_event {
- VALUE thread;
- rb_event_flag_t event;
-};
-
-#define MAX_EVENTS 1024
-static struct thread_event event_timeline[MAX_EVENTS];
-static rb_atomic_t timeline_cursor;
-
-static void
-event_timeline_gc_mark(void *ptr) {
- rb_atomic_t cursor;
- for (cursor = 0; cursor < timeline_cursor; cursor++) {
- rb_gc_mark(event_timeline[cursor].thread);
- }
-}
-
-static const rb_data_type_t event_timeline_type = {
- "TestThreadInstrumentation/event_timeline",
- {event_timeline_gc_mark, NULL, NULL,},
- 0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY,
-};
+static RB_THREAD_LOCAL_SPECIFIER unsigned int local_ready_count = 0;
+static RB_THREAD_LOCAL_SPECIFIER unsigned int local_resumed_count = 0;
+static RB_THREAD_LOCAL_SPECIFIER unsigned int local_suspended_count = 0;
static void
-reset_timeline(void)
-{
- timeline_cursor = 0;
- memset(event_timeline, 0, sizeof(struct thread_event) * MAX_EVENTS);
-}
-
-static rb_event_flag_t
-find_last_event(VALUE thread)
-{
- rb_atomic_t cursor = timeline_cursor;
- if (cursor) {
- do {
- if (event_timeline[cursor].thread == thread){
- return event_timeline[cursor].event;
- }
- cursor--;
- } while (cursor > 0);
- }
- return 0;
-}
-
-static const char *
-event_name(rb_event_flag_t event)
+ex_callback(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_data, void *user_data)
{
switch (event) {
case RUBY_INTERNAL_THREAD_EVENT_STARTED:
- return "started";
+ RUBY_ATOMIC_INC(started_count);
+ break;
case RUBY_INTERNAL_THREAD_EVENT_READY:
- return "ready";
+ RUBY_ATOMIC_INC(ready_count);
+ local_ready_count++;
+ break;
case RUBY_INTERNAL_THREAD_EVENT_RESUMED:
- return "resumed";
+ RUBY_ATOMIC_INC(resumed_count);
+ local_resumed_count++;
+ break;
case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED:
- return "suspended";
+ RUBY_ATOMIC_INC(suspended_count);
+ local_suspended_count++;
+ break;
case RUBY_INTERNAL_THREAD_EVENT_EXITED:
- return "exited";
+ RUBY_ATOMIC_INC(exited_count);
+ break;
}
- return "no-event";
}
-static void
-unexpected(bool strict, const char *format, VALUE thread, rb_event_flag_t last_event)
+static rb_internal_thread_event_hook_t * single_hook = NULL;
+
+static VALUE
+thread_counters(VALUE thread)
{
- const char *last_event_name = event_name(last_event);
- if (strict) {
- rb_bug(format, thread, last_event_name);
- }
- else {
- fprintf(stderr, format, thread, last_event_name);
- fprintf(stderr, "\n");
- }
+ VALUE array = rb_ary_new2(5);
+ rb_ary_push(array, UINT2NUM(started_count));
+ rb_ary_push(array, UINT2NUM(ready_count));
+ rb_ary_push(array, UINT2NUM(resumed_count));
+ rb_ary_push(array, UINT2NUM(suspended_count));
+ rb_ary_push(array, UINT2NUM(exited_count));
+ return array;
}
-static void
-ex_callback(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_data, void *user_data)
+static VALUE
+thread_local_counters(VALUE thread)
{
- rb_event_flag_t last_event = find_last_event(event_data->thread);
- bool strict = (bool)user_data;
-
- if (last_event != 0) {
- switch (event) {
- case RUBY_INTERNAL_THREAD_EVENT_STARTED:
- unexpected(strict, "[thread=%"PRIxVALUE"] `started` event can't be preceded by `%s`", event_data->thread, last_event);
- break;
- case RUBY_INTERNAL_THREAD_EVENT_READY:
- if (last_event != RUBY_INTERNAL_THREAD_EVENT_STARTED && last_event != RUBY_INTERNAL_THREAD_EVENT_SUSPENDED) {
- unexpected(strict, "[thread=%"PRIxVALUE"] `ready` must be preceded by `started` or `suspended`, got: `%s`", event_data->thread, last_event);
- }
- break;
- case RUBY_INTERNAL_THREAD_EVENT_RESUMED:
- if (last_event != RUBY_INTERNAL_THREAD_EVENT_READY) {
- unexpected(strict, "[thread=%"PRIxVALUE"] `resumed` must be preceded by `ready`, got: `%s`", event_data->thread, last_event);
- }
- break;
- case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED:
- if (last_event != RUBY_INTERNAL_THREAD_EVENT_RESUMED) {
- unexpected(strict, "[thread=%"PRIxVALUE"] `suspended` must be preceded by `resumed`, got: `%s`", event_data->thread, last_event);
- }
- break;
- case RUBY_INTERNAL_THREAD_EVENT_EXITED:
- if (last_event != RUBY_INTERNAL_THREAD_EVENT_RESUMED && last_event != RUBY_INTERNAL_THREAD_EVENT_SUSPENDED) {
- unexpected(strict, "[thread=%"PRIxVALUE"] `exited` must be preceded by `resumed` or `suspended`, got: `%s`", event_data->thread, last_event);
- }
- break;
- }
- }
-
- rb_atomic_t cursor = RUBY_ATOMIC_FETCH_ADD(timeline_cursor, 1);
- if (cursor >= MAX_EVENTS) {
- rb_bug("TestThreadInstrumentation: ran out of event_timeline space");
- }
-
- event_timeline[cursor].thread = event_data->thread;
- event_timeline[cursor].event = event;
+ VALUE array = rb_ary_new2(3);
+ rb_ary_push(array, UINT2NUM(local_ready_count));
+ rb_ary_push(array, UINT2NUM(local_resumed_count));
+ rb_ary_push(array, UINT2NUM(local_suspended_count));
+ return array;
}
-static rb_internal_thread_event_hook_t * single_hook = NULL;
+static VALUE
+thread_reset_counters(VALUE thread)
+{
+ RUBY_ATOMIC_SET(started_count, 0);
+ RUBY_ATOMIC_SET(ready_count, 0);
+ RUBY_ATOMIC_SET(resumed_count, 0);
+ RUBY_ATOMIC_SET(suspended_count, 0);
+ RUBY_ATOMIC_SET(exited_count, 0);
+ local_ready_count = 0;
+ local_resumed_count = 0;
+ local_suspended_count = 0;
+ return Qtrue;
+}
static VALUE
-thread_register_callback(VALUE thread, VALUE strict)
+thread_register_callback(VALUE thread)
{
single_hook = rb_internal_thread_add_event_hook(
ex_callback,
@@ -141,33 +94,13 @@ thread_register_callback(VALUE thread, VALUE strict)
RUBY_INTERNAL_THREAD_EVENT_RESUMED |
RUBY_INTERNAL_THREAD_EVENT_SUSPENDED |
RUBY_INTERNAL_THREAD_EVENT_EXITED,
- (void *)RTEST(strict)
+ NULL
);
return Qnil;
}
static VALUE
-event_symbol(rb_event_flag_t event)
-{
- switch (event) {
- case RUBY_INTERNAL_THREAD_EVENT_STARTED:
- return rb_id2sym(rb_intern("started"));
- case RUBY_INTERNAL_THREAD_EVENT_READY:
- return rb_id2sym(rb_intern("ready"));
- case RUBY_INTERNAL_THREAD_EVENT_RESUMED:
- return rb_id2sym(rb_intern("resumed"));
- case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED:
- return rb_id2sym(rb_intern("suspended"));
- case RUBY_INTERNAL_THREAD_EVENT_EXITED:
- return rb_id2sym(rb_intern("exited"));
- default:
- rb_bug("TestThreadInstrumentation: Unexpected event");
- break;
- }
-}
-
-static VALUE
thread_unregister_callback(VALUE thread)
{
if (single_hook) {
@@ -175,18 +108,7 @@ thread_unregister_callback(VALUE thread)
single_hook = NULL;
}
- VALUE events = rb_ary_new_capa(timeline_cursor);
- rb_atomic_t cursor;
- for (cursor = 0; cursor < timeline_cursor; cursor++) {
- VALUE pair = rb_ary_new_capa(2);
- rb_ary_push(pair, event_timeline[cursor].thread);
- rb_ary_push(pair, event_symbol(event_timeline[cursor].event));
- rb_ary_push(events, pair);
- }
-
- reset_timeline();
-
- return events;
+ return Qnil;
}
static VALUE
@@ -210,11 +132,10 @@ Init_instrumentation(void)
{
VALUE mBug = rb_define_module("Bug");
VALUE klass = rb_define_module_under(mBug, "ThreadInstrumentation");
- rb_global_variable(&timeline_value);
- timeline_value = TypedData_Wrap_Struct(0, &event_timeline_type, 0);
-
- rb_global_variable(&last_thread);
- rb_define_singleton_method(klass, "register_callback", thread_register_callback, 1);
+ rb_define_singleton_method(klass, "counters", thread_counters, 0);
+ rb_define_singleton_method(klass, "local_counters", thread_local_counters, 0);
+ rb_define_singleton_method(klass, "reset_counters", thread_reset_counters, 0);
+ rb_define_singleton_method(klass, "register_callback", thread_register_callback, 0);
rb_define_singleton_method(klass, "unregister_callback", thread_unregister_callback, 0);
rb_define_singleton_method(klass, "register_and_unregister_callbacks", thread_register_and_unregister_callback, 0);
}
diff --git a/ext/-test-/thread_fd/depend b/ext/-test-/thread_fd/depend
index d4cc772526..ecf738108a 100644
--- a/ext/-test-/thread_fd/depend
+++ b/ext/-test-/thread_fd/depend
@@ -51,7 +51,6 @@ thread_fd.o: $(hdrdir)/ruby/internal/attr/noexcept.h
thread_fd.o: $(hdrdir)/ruby/internal/attr/noinline.h
thread_fd.o: $(hdrdir)/ruby/internal/attr/nonnull.h
thread_fd.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-thread_fd.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
thread_fd.o: $(hdrdir)/ruby/internal/attr/pure.h
thread_fd.o: $(hdrdir)/ruby/internal/attr/restrict.h
thread_fd.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ thread_fd.o: $(hdrdir)/ruby/internal/intern/enumerator.h
thread_fd.o: $(hdrdir)/ruby/internal/intern/error.h
thread_fd.o: $(hdrdir)/ruby/internal/intern/eval.h
thread_fd.o: $(hdrdir)/ruby/internal/intern/file.h
+thread_fd.o: $(hdrdir)/ruby/internal/intern/gc.h
thread_fd.o: $(hdrdir)/ruby/internal/intern/hash.h
thread_fd.o: $(hdrdir)/ruby/internal/intern/io.h
thread_fd.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ thread_fd.o: $(hdrdir)/ruby/internal/memory.h
thread_fd.o: $(hdrdir)/ruby/internal/method.h
thread_fd.o: $(hdrdir)/ruby/internal/module.h
thread_fd.o: $(hdrdir)/ruby/internal/newobj.h
+thread_fd.o: $(hdrdir)/ruby/internal/rgengc.h
thread_fd.o: $(hdrdir)/ruby/internal/scan_args.h
thread_fd.o: $(hdrdir)/ruby/internal/special_consts.h
thread_fd.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/time/depend b/ext/-test-/time/depend
index c015588b09..b7d1a2b114 100644
--- a/ext/-test-/time/depend
+++ b/ext/-test-/time/depend
@@ -52,7 +52,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -212,7 +213,6 @@ leap_second.o: $(hdrdir)/ruby/internal/attr/noexcept.h
leap_second.o: $(hdrdir)/ruby/internal/attr/noinline.h
leap_second.o: $(hdrdir)/ruby/internal/attr/nonnull.h
leap_second.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-leap_second.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
leap_second.o: $(hdrdir)/ruby/internal/attr/pure.h
leap_second.o: $(hdrdir)/ruby/internal/attr/restrict.h
leap_second.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -272,6 +272,7 @@ leap_second.o: $(hdrdir)/ruby/internal/intern/enumerator.h
leap_second.o: $(hdrdir)/ruby/internal/intern/error.h
leap_second.o: $(hdrdir)/ruby/internal/intern/eval.h
leap_second.o: $(hdrdir)/ruby/internal/intern/file.h
+leap_second.o: $(hdrdir)/ruby/internal/intern/gc.h
leap_second.o: $(hdrdir)/ruby/internal/intern/hash.h
leap_second.o: $(hdrdir)/ruby/internal/intern/io.h
leap_second.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -302,6 +303,7 @@ leap_second.o: $(hdrdir)/ruby/internal/memory.h
leap_second.o: $(hdrdir)/ruby/internal/method.h
leap_second.o: $(hdrdir)/ruby/internal/module.h
leap_second.o: $(hdrdir)/ruby/internal/newobj.h
+leap_second.o: $(hdrdir)/ruby/internal/rgengc.h
leap_second.o: $(hdrdir)/ruby/internal/scan_args.h
leap_second.o: $(hdrdir)/ruby/internal/special_consts.h
leap_second.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -375,7 +377,6 @@ new.o: $(hdrdir)/ruby/internal/attr/noexcept.h
new.o: $(hdrdir)/ruby/internal/attr/noinline.h
new.o: $(hdrdir)/ruby/internal/attr/nonnull.h
new.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-new.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
new.o: $(hdrdir)/ruby/internal/attr/pure.h
new.o: $(hdrdir)/ruby/internal/attr/restrict.h
new.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -435,6 +436,7 @@ new.o: $(hdrdir)/ruby/internal/intern/enumerator.h
new.o: $(hdrdir)/ruby/internal/intern/error.h
new.o: $(hdrdir)/ruby/internal/intern/eval.h
new.o: $(hdrdir)/ruby/internal/intern/file.h
+new.o: $(hdrdir)/ruby/internal/intern/gc.h
new.o: $(hdrdir)/ruby/internal/intern/hash.h
new.o: $(hdrdir)/ruby/internal/intern/io.h
new.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -465,6 +467,7 @@ new.o: $(hdrdir)/ruby/internal/memory.h
new.o: $(hdrdir)/ruby/internal/method.h
new.o: $(hdrdir)/ruby/internal/module.h
new.o: $(hdrdir)/ruby/internal/newobj.h
+new.o: $(hdrdir)/ruby/internal/rgengc.h
new.o: $(hdrdir)/ruby/internal/scan_args.h
new.o: $(hdrdir)/ruby/internal/special_consts.h
new.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/tracepoint/depend b/ext/-test-/tracepoint/depend
index 396004926e..8e2aa7eab6 100644
--- a/ext/-test-/tracepoint/depend
+++ b/ext/-test-/tracepoint/depend
@@ -52,7 +52,6 @@ gc_hook.o: $(hdrdir)/ruby/internal/attr/noexcept.h
gc_hook.o: $(hdrdir)/ruby/internal/attr/noinline.h
gc_hook.o: $(hdrdir)/ruby/internal/attr/nonnull.h
gc_hook.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-gc_hook.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
gc_hook.o: $(hdrdir)/ruby/internal/attr/pure.h
gc_hook.o: $(hdrdir)/ruby/internal/attr/restrict.h
gc_hook.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ gc_hook.o: $(hdrdir)/ruby/internal/intern/enumerator.h
gc_hook.o: $(hdrdir)/ruby/internal/intern/error.h
gc_hook.o: $(hdrdir)/ruby/internal/intern/eval.h
gc_hook.o: $(hdrdir)/ruby/internal/intern/file.h
+gc_hook.o: $(hdrdir)/ruby/internal/intern/gc.h
gc_hook.o: $(hdrdir)/ruby/internal/intern/hash.h
gc_hook.o: $(hdrdir)/ruby/internal/intern/io.h
gc_hook.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ gc_hook.o: $(hdrdir)/ruby/internal/memory.h
gc_hook.o: $(hdrdir)/ruby/internal/method.h
gc_hook.o: $(hdrdir)/ruby/internal/module.h
gc_hook.o: $(hdrdir)/ruby/internal/newobj.h
+gc_hook.o: $(hdrdir)/ruby/internal/rgengc.h
gc_hook.o: $(hdrdir)/ruby/internal/scan_args.h
gc_hook.o: $(hdrdir)/ruby/internal/special_consts.h
gc_hook.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -211,7 +212,6 @@ tracepoint.o: $(hdrdir)/ruby/internal/attr/noexcept.h
tracepoint.o: $(hdrdir)/ruby/internal/attr/noinline.h
tracepoint.o: $(hdrdir)/ruby/internal/attr/nonnull.h
tracepoint.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-tracepoint.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
tracepoint.o: $(hdrdir)/ruby/internal/attr/pure.h
tracepoint.o: $(hdrdir)/ruby/internal/attr/restrict.h
tracepoint.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -271,6 +271,7 @@ tracepoint.o: $(hdrdir)/ruby/internal/intern/enumerator.h
tracepoint.o: $(hdrdir)/ruby/internal/intern/error.h
tracepoint.o: $(hdrdir)/ruby/internal/intern/eval.h
tracepoint.o: $(hdrdir)/ruby/internal/intern/file.h
+tracepoint.o: $(hdrdir)/ruby/internal/intern/gc.h
tracepoint.o: $(hdrdir)/ruby/internal/intern/hash.h
tracepoint.o: $(hdrdir)/ruby/internal/intern/io.h
tracepoint.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -301,6 +302,7 @@ tracepoint.o: $(hdrdir)/ruby/internal/memory.h
tracepoint.o: $(hdrdir)/ruby/internal/method.h
tracepoint.o: $(hdrdir)/ruby/internal/module.h
tracepoint.o: $(hdrdir)/ruby/internal/newobj.h
+tracepoint.o: $(hdrdir)/ruby/internal/rgengc.h
tracepoint.o: $(hdrdir)/ruby/internal/scan_args.h
tracepoint.o: $(hdrdir)/ruby/internal/special_consts.h
tracepoint.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/tracepoint/gc_hook.c b/ext/-test-/tracepoint/gc_hook.c
index 54c06c54a5..a3f4e7f68a 100644
--- a/ext/-test-/tracepoint/gc_hook.c
+++ b/ext/-test-/tracepoint/gc_hook.c
@@ -33,9 +33,7 @@ gc_start_end_i(VALUE tpval, void *data)
}
if (invoking == 0) {
- /* will overwrite the existing handle with new data on the second and subsequent call */
- rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, invoke_proc, data);
- rb_postponed_job_trigger(h);
+ rb_postponed_job_register(0, invoke_proc, data);
}
}
diff --git a/ext/-test-/typeddata/depend b/ext/-test-/typeddata/depend
index cbeafa8000..02f6de6e20 100644
--- a/ext/-test-/typeddata/depend
+++ b/ext/-test-/typeddata/depend
@@ -52,7 +52,6 @@ typeddata.o: $(hdrdir)/ruby/internal/attr/noexcept.h
typeddata.o: $(hdrdir)/ruby/internal/attr/noinline.h
typeddata.o: $(hdrdir)/ruby/internal/attr/nonnull.h
typeddata.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-typeddata.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
typeddata.o: $(hdrdir)/ruby/internal/attr/pure.h
typeddata.o: $(hdrdir)/ruby/internal/attr/restrict.h
typeddata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ typeddata.o: $(hdrdir)/ruby/internal/intern/enumerator.h
typeddata.o: $(hdrdir)/ruby/internal/intern/error.h
typeddata.o: $(hdrdir)/ruby/internal/intern/eval.h
typeddata.o: $(hdrdir)/ruby/internal/intern/file.h
+typeddata.o: $(hdrdir)/ruby/internal/intern/gc.h
typeddata.o: $(hdrdir)/ruby/internal/intern/hash.h
typeddata.o: $(hdrdir)/ruby/internal/intern/io.h
typeddata.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ typeddata.o: $(hdrdir)/ruby/internal/memory.h
typeddata.o: $(hdrdir)/ruby/internal/method.h
typeddata.o: $(hdrdir)/ruby/internal/module.h
typeddata.o: $(hdrdir)/ruby/internal/newobj.h
+typeddata.o: $(hdrdir)/ruby/internal/rgengc.h
typeddata.o: $(hdrdir)/ruby/internal/scan_args.h
typeddata.o: $(hdrdir)/ruby/internal/special_consts.h
typeddata.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/vm/depend b/ext/-test-/vm/depend
index f0b3f3b1f4..7f110d48eb 100644
--- a/ext/-test-/vm/depend
+++ b/ext/-test-/vm/depend
@@ -51,7 +51,6 @@ at_exit.o: $(hdrdir)/ruby/internal/attr/noexcept.h
at_exit.o: $(hdrdir)/ruby/internal/attr/noinline.h
at_exit.o: $(hdrdir)/ruby/internal/attr/nonnull.h
at_exit.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-at_exit.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
at_exit.o: $(hdrdir)/ruby/internal/attr/pure.h
at_exit.o: $(hdrdir)/ruby/internal/attr/restrict.h
at_exit.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ at_exit.o: $(hdrdir)/ruby/internal/intern/enumerator.h
at_exit.o: $(hdrdir)/ruby/internal/intern/error.h
at_exit.o: $(hdrdir)/ruby/internal/intern/eval.h
at_exit.o: $(hdrdir)/ruby/internal/intern/file.h
+at_exit.o: $(hdrdir)/ruby/internal/intern/gc.h
at_exit.o: $(hdrdir)/ruby/internal/intern/hash.h
at_exit.o: $(hdrdir)/ruby/internal/intern/io.h
at_exit.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ at_exit.o: $(hdrdir)/ruby/internal/memory.h
at_exit.o: $(hdrdir)/ruby/internal/method.h
at_exit.o: $(hdrdir)/ruby/internal/module.h
at_exit.o: $(hdrdir)/ruby/internal/newobj.h
+at_exit.o: $(hdrdir)/ruby/internal/rgengc.h
at_exit.o: $(hdrdir)/ruby/internal/scan_args.h
at_exit.o: $(hdrdir)/ruby/internal/special_consts.h
at_exit.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/-test-/wait/depend b/ext/-test-/wait/depend
index 2e4887559c..e71bda9968 100644
--- a/ext/-test-/wait/depend
+++ b/ext/-test-/wait/depend
@@ -52,7 +52,6 @@ wait.o: $(hdrdir)/ruby/internal/attr/noexcept.h
wait.o: $(hdrdir)/ruby/internal/attr/noinline.h
wait.o: $(hdrdir)/ruby/internal/attr/nonnull.h
wait.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-wait.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
wait.o: $(hdrdir)/ruby/internal/attr/pure.h
wait.o: $(hdrdir)/ruby/internal/attr/restrict.h
wait.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -121,6 +120,7 @@ wait.o: $(hdrdir)/ruby/internal/intern/enumerator.h
wait.o: $(hdrdir)/ruby/internal/intern/error.h
wait.o: $(hdrdir)/ruby/internal/intern/eval.h
wait.o: $(hdrdir)/ruby/internal/intern/file.h
+wait.o: $(hdrdir)/ruby/internal/intern/gc.h
wait.o: $(hdrdir)/ruby/internal/intern/hash.h
wait.o: $(hdrdir)/ruby/internal/intern/io.h
wait.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -151,6 +151,7 @@ wait.o: $(hdrdir)/ruby/internal/memory.h
wait.o: $(hdrdir)/ruby/internal/method.h
wait.o: $(hdrdir)/ruby/internal/module.h
wait.o: $(hdrdir)/ruby/internal/newobj.h
+wait.o: $(hdrdir)/ruby/internal/rgengc.h
wait.o: $(hdrdir)/ruby/internal/scan_args.h
wait.o: $(hdrdir)/ruby/internal/special_consts.h
wait.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/.document b/ext/.document
index 0efd511a61..aeb40c60fb 100644
--- a/ext/.document
+++ b/ext/.document
@@ -11,6 +11,7 @@ date/date_parse.c
date/date_strftime.c
date/date_strptime.c
date/lib
+dbm/dbm.c
digest/bubblebabble/bubblebabble.c
digest/digest.c
digest/lib
@@ -21,6 +22,7 @@ digest/sha2/sha2init.c
digest/sha2/lib
etc/etc.c
fcntl/fcntl.c
+fiber/fiber.c
fiddle/closure.c
fiddle/conversions.c
fiddle/fiddle.c
@@ -29,7 +31,9 @@ fiddle/pinned.c
fiddle/pointer.c
fiddle/handle.c
fiddle/lib
-io/console/
+gdbm/gdbm.c
+io/console/console.c
+io/console/lib
io/nonblock/nonblock.c
io/wait/wait.c
json/generator/generator.c
diff --git a/ext/Setup b/ext/Setup
index 9c3e2f48fe..0376e2fc6c 100644
--- a/ext/Setup
+++ b/ext/Setup
@@ -5,6 +5,7 @@
#continuation
#coverage
#date
+#dbm
#digest/bubblebabble
#digest
#digest/md5
@@ -13,7 +14,9 @@
#digest/sha2
#etc
#fcntl
+#fiber
#fiddle
+#gdbm
#io/console
#io/nonblock
#io/wait
diff --git a/ext/Setup.atheos b/ext/Setup.atheos
index 91f73f32f9..3f6263b1e2 100644
--- a/ext/Setup.atheos
+++ b/ext/Setup.atheos
@@ -1,19 +1,23 @@
option nodynamic
+#Win32API
bigdecimal
cgi/escape
+dbm
digest
digest/md5
digest/rmd160
digest/sha1
digest/sha2
+enumerator
etc
fcntl
+gdbm
io/wait
nkf
#openssl
pty
-#racc/cparse
+racc/parse
readline
ripper
socket
diff --git a/ext/Setup.nt b/ext/Setup.nt
index 1278f183e4..dc36aa8688 100644
--- a/ext/Setup.nt
+++ b/ext/Setup.nt
@@ -1,20 +1,24 @@
#option platform cygwin|mingw|mswin
#option nodynamic
+Win32API
bigdecimal
cgi/escape
+#dbm
digest
digest/md5
digest/rmd160
digest/sha1
digest/sha2
+enumerator
etc
fcntl
+#gdbm
#io/wait
nkf
#openssl
#pty
-#racc/cparse
+racc/cparse
#readline
#ripper
socket
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index cb8874d31a..d6ea35c615 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -31,8 +31,6 @@
#include "bits.h"
#include "static_assert.h"
-#define BIGDECIMAL_VERSION "3.1.5"
-
/* #define ENABLE_NUMERIC_STRING */
#define SIGNED_VALUE_MAX INTPTR_MAX
@@ -315,7 +313,7 @@ static const rb_data_type_t BigDecimal_data_type = {
"BigDecimal",
{ 0, BigDecimal_delete, BigDecimal_memsize, },
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE
#endif
};
@@ -657,7 +655,7 @@ BigDecimal_precision(VALUE self)
* Returns the number of decimal digits following the decimal digits in +self+.
*
* BigDecimal("0").scale # => 0
- * BigDecimal("1").scale # => 0
+ * BigDecimal("1").scale # => 1
* BigDecimal("1.1").scale # => 1
* BigDecimal("3.1415").scale # => 4
* BigDecimal("-1e20").precision # => 0
@@ -2084,13 +2082,6 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
if (!b) return DoSomeOne(self, r, rb_intern("remainder"));
SAVE(b);
- if (VpIsPosInf(b) || VpIsNegInf(b)) {
- GUARD_OBJ(*dv, NewZeroWrapLimited(1, 1));
- VpSetZero(*dv, 1);
- *rv = a;
- return Qnil;
- }
-
mx = (a->MaxPrec + b->MaxPrec) *VpBaseFig();
GUARD_OBJ(c, NewZeroWrapLimited(1, mx));
GUARD_OBJ(res, NewZeroWrapNolimit(1, (mx+1) * 2 + (VpBaseFig() + 1)));
@@ -2689,7 +2680,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
* A space at the start of s returns positive values with a leading space.
*
* If s contains a number, a space is inserted after each group of that many
- * digits, starting from '.' and counting outwards.
+ * fractional digits.
*
* If s ends with an 'E', engineering notation (0.xxxxEnn) is used.
*
@@ -2697,14 +2688,14 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
*
* Examples:
*
- * BigDecimal('-1234567890123.45678901234567890').to_s('5F')
- * #=> '-123 45678 90123.45678 90123 45678 9'
+ * BigDecimal('-123.45678901234567890').to_s('5F')
+ * #=> '-123.45678 90123 45678 9'
*
- * BigDecimal('1234567890123.45678901234567890').to_s('+8F')
- * #=> '+12345 67890123.45678901 23456789'
+ * BigDecimal('123.45678901234567890').to_s('+8F')
+ * #=> '+123.45678901 23456789'
*
- * BigDecimal('1234567890123.45678901234567890').to_s(' F')
- * #=> ' 1234567890123.4567890123456789'
+ * BigDecimal('123.45678901234567890').to_s(' F')
+ * #=> ' 123.4567890123456789'
*/
static VALUE
BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
@@ -3722,7 +3713,7 @@ rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception)
* - Other type:
*
* - Raises an exception if keyword argument +exception+ is +true+.
- * - Returns +nil+ if keyword argument +exception+ is +false+.
+ * - Returns +nil+ if keyword argument +exception+ is +true+.
*
* Raises an exception if +value+ evaluates to a Float
* and +digits+ is larger than Float::DIG + 1.
@@ -4142,11 +4133,11 @@ get_vp_value:
}
x = VpCheckGetValue(vx);
- one = VpCheckGetValue(NewOneWrapLimited(1, 1));
- two = VpCheckGetValue(VpCreateRbObject(1, "2", true));
+ RB_GC_GUARD(one) = VpCheckGetValue(NewOneWrapLimited(1, 1));
+ RB_GC_GUARD(two) = VpCheckGetValue(VpCreateRbObject(1, "2", true));
n = prec + BIGDECIMAL_DOUBLE_FIGURES;
- vn = SSIZET2NUM(n);
+ RB_GC_GUARD(vn) = SSIZET2NUM(n);
expo = VpExponent10(vx);
if (expo < 0 || expo >= 3) {
char buf[DECIMAL_SIZE_OF_BITS(SIZEOF_VALUE * CHAR_BIT) + 4];
@@ -4158,9 +4149,9 @@ get_vp_value:
}
w = BigDecimal_sub(x, one);
x = BigDecimal_div2(w, BigDecimal_add(x, one), vn);
- x2 = BigDecimal_mult2(x, x, vn);
- y = x;
- d = y;
+ RB_GC_GUARD(x2) = BigDecimal_mult2(x, x, vn);
+ RB_GC_GUARD(y) = x;
+ RB_GC_GUARD(d) = y;
i = 1;
while (!VpIsZero((Real*)DATA_PTR(d))) {
SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y));
@@ -4188,13 +4179,6 @@ get_vp_value:
y = BigDecimal_add(y, dy);
}
- RB_GC_GUARD(one);
- RB_GC_GUARD(two);
- RB_GC_GUARD(vn);
- RB_GC_GUARD(x2);
- RB_GC_GUARD(y);
- RB_GC_GUARD(d);
-
return y;
}
@@ -4363,20 +4347,7 @@ BigDecimal_negative_zero(void)
* (2/3r).to_d(3) # => 0.667e0
* "0.5".to_d # => 0.5e0
*
- * == Methods for Working with \JSON
- *
- * - {::json_create}[rdoc-ref:BigDecimal.json_create]:
- * Returns a new \BigDecimal object constructed from the given object.
- * - {#as_json}[rdoc-ref:BigDecimal#as_json]:
- * Returns a 2-element hash representing +self+.
- * - {#to_json}[rdoc-ref:BigDecimal#to_json]:
- * Returns a \JSON string representing +self+.
- *
- * These methods are provided by the {JSON gem}[https://github.com/flori/json]. To make these methods available:
- *
- * require 'json/add/bigdecimal'
- *
- * * == License
+ * == License
*
* Copyright (C) 2002 by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.
*
@@ -4424,10 +4395,13 @@ Init_bigdecimal(void)
/* Constants definition */
+#ifndef RUBY_BIGDECIMAL_VERSION
+# error RUBY_BIGDECIMAL_VERSION is not defined
+#endif
/*
* The version of bigdecimal library
*/
- rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(BIGDECIMAL_VERSION));
+ rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(RUBY_BIGDECIMAL_VERSION));
/*
* Base value used in internal calculations. On a 32 bit system, BASE
@@ -6479,7 +6453,7 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
}
}
nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a));
- nc += fprintf(fp, " (%"PRIdVALUE", %"PRIuSIZE", %"PRIuSIZE")", a->exponent, a->Prec, a->MaxPrec);
+ nc += fprintf(fp, " (%"PRIdVALUE", %lu, %lu)", a->exponent, a->Prec, a->MaxPrec);
}
else {
nc += fprintf(fp, "0.0");
@@ -6719,90 +6693,95 @@ VpToFString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus)
/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
{
size_t i, n;
- DECDIG m, e;
+ DECDIG m, e, nn;
char *p = buf;
- size_t plen = buflen, delim = fFmt;
+ size_t plen = buflen;
ssize_t ex;
if (VpToSpecialString(a, buf, buflen, fPlus)) return;
-#define APPEND(c, group) do { \
- if (plen < 1) goto overflow; \
- if (group && delim == 0) { \
- *p = ' '; \
- p += 1; \
- plen -= 1; \
- } \
- if (plen < 1) goto overflow; \
- *p = c; \
- p += 1; \
- plen -= 1; \
- if (group) delim = (delim + 1) % fFmt; \
+#define ADVANCE(n) do { \
+ if (plen < n) goto overflow; \
+ p += n; \
+ plen -= n; \
} while (0)
if (BIGDECIMAL_NEGATIVE_P(a)) {
- APPEND('-', false);
+ *p = '-';
+ ADVANCE(1);
}
else if (fPlus == 1) {
- APPEND(' ', false);
+ *p = ' ';
+ ADVANCE(1);
}
else if (fPlus == 2) {
- APPEND('+', false);
+ *p = '+';
+ ADVANCE(1);
}
n = a->Prec;
ex = a->exponent;
if (ex <= 0) {
- APPEND('0', false);
- APPEND('.', false);
- }
- while (ex < 0) {
- for (i=0; i < BASE_FIG; ++i) {
- APPEND('0', fFmt > 0);
+ *p = '0'; ADVANCE(1);
+ *p = '.'; ADVANCE(1);
+ while (ex < 0) {
+ for (i=0; i < BASE_FIG; ++i) {
+ *p = '0'; ADVANCE(1);
+ }
+ ++ex;
}
- ++ex;
+ ex = -1;
}
for (i = 0; i < n; ++i) {
- m = BASE1;
- e = a->frac[i];
- if (i == 0 && ex > 0) {
- for (delim = 0; e / m == 0; delim++) {
+ --ex;
+ if (i == 0 && ex >= 0) {
+ size_t n = snprintf(p, plen, "%lu", (unsigned long)a->frac[i]);
+ if (n > plen) goto overflow;
+ ADVANCE(n);
+ }
+ else {
+ m = BASE1;
+ e = a->frac[i];
+ while (m) {
+ nn = e / m;
+ *p = (char)(nn + '0');
+ ADVANCE(1);
+ e = e - nn * m;
m /= 10;
}
- if (fFmt > 0) {
- delim = 2*fFmt - (ex * BASE_FIG - delim) % fFmt;
- }
- }
- while (m && (e || (i < n - 1) || ex > 0)) {
- APPEND((char)(e / m + '0'), fFmt > 0);
- e %= m;
- m /= 10;
}
- if (--ex == 0) {
- APPEND('.', false);
- delim = fFmt;
+ if (ex == 0) {
+ *p = '.';
+ ADVANCE(1);
}
}
-
- while (ex > 0) {
- for (i=0; i < BASE_FIG; ++i) {
- APPEND('0', fFmt > 0);
+ while (--ex>=0) {
+ m = BASE;
+ while (m /= 10) {
+ *p = '0';
+ ADVANCE(1);
}
- if (--ex == 0) {
- APPEND('.', false);
+ if (ex == 0) {
+ *p = '.';
+ ADVANCE(1);
}
}
*p = '\0';
+ while (p - 1 > buf && p[-1] == '0') {
+ *(--p) = '\0';
+ ++plen;
+ }
if (p - 1 > buf && p[-1] == '.') {
snprintf(p, plen, "0");
}
+ if (fFmt) VpFormatSt(buf, fFmt);
overflow:
return;
-#undef APPEND
+#undef ADVANCE
}
/*
@@ -7179,6 +7158,7 @@ VpSqrt(Real *y, Real *x)
Real *r = NULL;
size_t y_prec;
SIGNED_VALUE n, e;
+ SIGNED_VALUE prec;
ssize_t nr;
double val;
@@ -7217,6 +7197,12 @@ VpSqrt(Real *y, Real *x)
nr = 0;
y_prec = y->MaxPrec;
+ prec = x->exponent - (ssize_t)y_prec;
+ if (x->exponent > 0)
+ ++prec;
+ else
+ --prec;
+
VpVtoD(&val, &e, x); /* val <- x */
e /= (SIGNED_VALUE)BASE_FIG;
n = e / 2;
diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec
index f9f3b45616..d215757188 100644
--- a/ext/bigdecimal/bigdecimal.gemspec
+++ b/ext/bigdecimal/bigdecimal.gemspec
@@ -1,29 +1,28 @@
# coding: utf-8
-name = File.basename(__FILE__, '.*')
-source_version = ["", "ext/#{name}/"].find do |dir|
- begin
- break File.foreach(File.join(__dir__, "#{dir}#{name}.c")) {|line|
- break $1.sub("-", ".") if /^#define\s+#{name.upcase}_VERSION\s+"(.+)"/o =~ line
- }
- rescue Errno::ENOENT
- end
-end or raise "can't find #{name.upcase}_VERSION"
-
Gem::Specification.new do |s|
- s.name = name
- s.version = source_version
+ s.name = "bigdecimal"
+ s.version = "3.1.3"
s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"]
s.email = ["mrkn@mrkn.jp"]
s.summary = "Arbitrary-precision decimal floating-point number library."
s.description = "This library provides arbitrary-precision decimal floating-point number class."
s.homepage = "https://github.com/ruby/bigdecimal"
- s.licenses = ["Ruby", "BSD-2-Clause"]
+ s.licenses = ["Ruby", "bsd-2-clause"]
s.require_paths = %w[lib]
+ s.extensions = %w[ext/bigdecimal/extconf.rb]
s.files = %w[
bigdecimal.gemspec
+ ext/bigdecimal/bigdecimal.c
+ ext/bigdecimal/bigdecimal.h
+ ext/bigdecimal/bits.h
+ ext/bigdecimal/feature.h
+ ext/bigdecimal/missing.c
+ ext/bigdecimal/missing.h
+ ext/bigdecimal/missing/dtoa.c
+ ext/bigdecimal/static_assert.h
lib/bigdecimal.rb
lib/bigdecimal/jacobian.rb
lib/bigdecimal/ludcmp.rb
@@ -34,21 +33,6 @@ Gem::Specification.new do |s|
sample/nlsolve.rb
sample/pi.rb
]
- if Gem::Platform === s.platform and s.platform =~ 'java' or RUBY_ENGINE == 'jruby'
- s.platform = 'java'
- else
- s.extensions = %w[ext/bigdecimal/extconf.rb]
- s.files += %w[
- ext/bigdecimal/bigdecimal.c
- ext/bigdecimal/bigdecimal.h
- ext/bigdecimal/bits.h
- ext/bigdecimal/feature.h
- ext/bigdecimal/missing.c
- ext/bigdecimal/missing.h
- ext/bigdecimal/missing/dtoa.c
- ext/bigdecimal/static_assert.h
- ]
- end
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
end
diff --git a/ext/bigdecimal/depend b/ext/bigdecimal/depend
index a2455ebbda..ee892162f2 100644
--- a/ext/bigdecimal/depend
+++ b/ext/bigdecimal/depend
@@ -1,3 +1,4 @@
+extconf.h: $(srcdir)/$(GEMSPEC)
Makefile: $(BIGDECIMAL_RB)
# AUTOGENERATED DEPENDENCIES START
@@ -52,7 +53,6 @@ bigdecimal.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bigdecimal.o: $(hdrdir)/ruby/internal/attr/noinline.h
bigdecimal.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bigdecimal.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bigdecimal.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bigdecimal.o: $(hdrdir)/ruby/internal/attr/pure.h
bigdecimal.o: $(hdrdir)/ruby/internal/attr/restrict.h
bigdecimal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +112,7 @@ bigdecimal.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bigdecimal.o: $(hdrdir)/ruby/internal/intern/error.h
bigdecimal.o: $(hdrdir)/ruby/internal/intern/eval.h
bigdecimal.o: $(hdrdir)/ruby/internal/intern/file.h
+bigdecimal.o: $(hdrdir)/ruby/internal/intern/gc.h
bigdecimal.o: $(hdrdir)/ruby/internal/intern/hash.h
bigdecimal.o: $(hdrdir)/ruby/internal/intern/io.h
bigdecimal.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +143,7 @@ bigdecimal.o: $(hdrdir)/ruby/internal/memory.h
bigdecimal.o: $(hdrdir)/ruby/internal/method.h
bigdecimal.o: $(hdrdir)/ruby/internal/module.h
bigdecimal.o: $(hdrdir)/ruby/internal/newobj.h
+bigdecimal.o: $(hdrdir)/ruby/internal/rgengc.h
bigdecimal.o: $(hdrdir)/ruby/internal/scan_args.h
bigdecimal.o: $(hdrdir)/ruby/internal/special_consts.h
bigdecimal.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -217,7 +219,6 @@ missing.o: $(hdrdir)/ruby/internal/attr/noexcept.h
missing.o: $(hdrdir)/ruby/internal/attr/noinline.h
missing.o: $(hdrdir)/ruby/internal/attr/nonnull.h
missing.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-missing.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
missing.o: $(hdrdir)/ruby/internal/attr/pure.h
missing.o: $(hdrdir)/ruby/internal/attr/restrict.h
missing.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -277,6 +278,7 @@ missing.o: $(hdrdir)/ruby/internal/intern/enumerator.h
missing.o: $(hdrdir)/ruby/internal/intern/error.h
missing.o: $(hdrdir)/ruby/internal/intern/eval.h
missing.o: $(hdrdir)/ruby/internal/intern/file.h
+missing.o: $(hdrdir)/ruby/internal/intern/gc.h
missing.o: $(hdrdir)/ruby/internal/intern/hash.h
missing.o: $(hdrdir)/ruby/internal/intern/io.h
missing.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -307,6 +309,7 @@ missing.o: $(hdrdir)/ruby/internal/memory.h
missing.o: $(hdrdir)/ruby/internal/method.h
missing.o: $(hdrdir)/ruby/internal/module.h
missing.o: $(hdrdir)/ruby/internal/newobj.h
+missing.o: $(hdrdir)/ruby/internal/rgengc.h
missing.o: $(hdrdir)/ruby/internal/scan_args.h
missing.o: $(hdrdir)/ruby/internal/special_consts.h
missing.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb
index 23904ed60e..17e7905dd6 100644
--- a/ext/bigdecimal/extconf.rb
+++ b/ext/bigdecimal/extconf.rb
@@ -1,6 +1,18 @@
# frozen_string_literal: false
require 'mkmf'
+def check_bigdecimal_version(gemspec_path)
+ message "checking RUBY_BIGDECIMAL_VERSION... "
+ bigdecimal_version = File.read(gemspec_path).match(/^\s*s\.version\s+=\s+['"]([^'"]+)['"]\s*$/)[1]
+
+ version_components = bigdecimal_version.split('.')
+ bigdecimal_version = version_components[0, 3].join('.')
+ bigdecimal_version << "-#{version_components[3]}" if version_components[3]
+ $defs << %Q[-DRUBY_BIGDECIMAL_VERSION=\\"#{bigdecimal_version}\\"]
+
+ message "#{bigdecimal_version}\n"
+end
+
def have_builtin_func(name, check_expr, opt = "", &b)
checking_for checking_message(name.funcall_style, nil, opt) do
if try_compile(<<SRC, opt, &b)
@@ -15,6 +27,18 @@ SRC
end
end
+gemspec_name = gemspec_path = nil
+unless ['', '../../'].any? {|dir|
+ gemspec_name = "#{dir}bigdecimal.gemspec"
+ gemspec_path = File.expand_path("../#{gemspec_name}", __FILE__)
+ File.file?(gemspec_path)
+ }
+ $stderr.puts "Unable to find bigdecimal.gemspec"
+ abort
+end
+
+check_bigdecimal_version(gemspec_path)
+
have_builtin_func("__builtin_clz", "__builtin_clz(0)")
have_builtin_func("__builtin_clzl", "__builtin_clzl(0)")
have_builtin_func("__builtin_clzll", "__builtin_clzll(0)")
@@ -58,5 +82,6 @@ else
end
create_makefile('bigdecimal') {|mf|
+ mf << "GEMSPEC = #{gemspec_name}\n"
mf << "BIGDECIMAL_RB = #{bigdecimal_rb}\n"
}
diff --git a/ext/bigdecimal/lib/bigdecimal.rb b/ext/bigdecimal/lib/bigdecimal.rb
index 82b3e1b7b9..8fd2587c84 100644
--- a/ext/bigdecimal/lib/bigdecimal.rb
+++ b/ext/bigdecimal/lib/bigdecimal.rb
@@ -1,5 +1 @@
-if RUBY_ENGINE == 'jruby'
- JRuby::Util.load_ext("org.jruby.ext.bigdecimal.BigDecimalLibrary")
-else
- require 'bigdecimal.so'
-end
+require 'bigdecimal.so'
diff --git a/ext/bigdecimal/lib/bigdecimal/util.rb b/ext/bigdecimal/lib/bigdecimal/util.rb
index 8bfc0ed8ed..ad92f7cfe6 100644
--- a/ext/bigdecimal/lib/bigdecimal/util.rb
+++ b/ext/bigdecimal/lib/bigdecimal/util.rb
@@ -18,7 +18,7 @@ class Integer < Numeric
#
# 42.to_d # => 0.42e2
#
- # See also Kernel.BigDecimal.
+ # See also BigDecimal::new.
#
def to_d
BigDecimal(self)
@@ -45,7 +45,7 @@ class Float < Numeric
# 1.234.to_d # => 0.1234e1
# 1.234.to_d(2) # => 0.12e1
#
- # See also Kernel.BigDecimal.
+ # See also BigDecimal::new.
#
def to_d(precision=0)
BigDecimal(self, precision)
@@ -67,7 +67,7 @@ class String
# "123.45e1".to_d # => 0.12345e4
# "45.67 degrees".to_d # => 0.4567e2
#
- # See also Kernel.BigDecimal.
+ # See also BigDecimal::new.
#
def to_d
BigDecimal.interpret_loosely(self)
@@ -127,7 +127,7 @@ class Rational < Numeric
#
# Rational(22, 7).to_d(3) # => 0.314e1
#
- # See also Kernel.BigDecimal.
+ # See also BigDecimal::new.
#
def to_d(precision)
BigDecimal(self, precision)
@@ -152,7 +152,7 @@ class Complex < Numeric
# Complex(0.1234567, 0).to_d(4) # => 0.1235e0
# Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1
#
- # See also Kernel.BigDecimal.
+ # See also BigDecimal::new.
#
def to_d(*args)
BigDecimal(self) unless self.imag.zero? # to raise eerror
diff --git a/ext/cgi/escape/depend b/ext/cgi/escape/depend
index 37304a24f4..e3904d0695 100644
--- a/ext/cgi/escape/depend
+++ b/ext/cgi/escape/depend
@@ -53,7 +53,6 @@ escape.o: $(hdrdir)/ruby/internal/attr/noexcept.h
escape.o: $(hdrdir)/ruby/internal/attr/noinline.h
escape.o: $(hdrdir)/ruby/internal/attr/nonnull.h
escape.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-escape.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
escape.o: $(hdrdir)/ruby/internal/attr/pure.h
escape.o: $(hdrdir)/ruby/internal/attr/restrict.h
escape.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ escape.o: $(hdrdir)/ruby/internal/intern/enumerator.h
escape.o: $(hdrdir)/ruby/internal/intern/error.h
escape.o: $(hdrdir)/ruby/internal/intern/eval.h
escape.o: $(hdrdir)/ruby/internal/intern/file.h
+escape.o: $(hdrdir)/ruby/internal/intern/gc.h
escape.o: $(hdrdir)/ruby/internal/intern/hash.h
escape.o: $(hdrdir)/ruby/internal/intern/io.h
escape.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ escape.o: $(hdrdir)/ruby/internal/memory.h
escape.o: $(hdrdir)/ruby/internal/method.h
escape.o: $(hdrdir)/ruby/internal/module.h
escape.o: $(hdrdir)/ruby/internal/newobj.h
+escape.o: $(hdrdir)/ruby/internal/rgengc.h
escape.o: $(hdrdir)/ruby/internal/scan_args.h
escape.o: $(hdrdir)/ruby/internal/special_consts.h
escape.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/cgi/escape/escape.c b/ext/cgi/escape/escape.c
index 495ad83aa3..c5b76de596 100644
--- a/ext/cgi/escape/escape.c
+++ b/ext/cgi/escape/escape.c
@@ -83,7 +83,7 @@ optimized_unescape_html(VALUE str)
unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX :
strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 :
128);
- long i, j, len, beg = 0;
+ long i, len, beg = 0;
size_t clen, plen;
int overflow;
const char *cstr;
@@ -100,7 +100,6 @@ optimized_unescape_html(VALUE str)
plen = i - beg;
if (++i >= len) break;
c = (unsigned char)cstr[i];
- j = i;
#define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \
memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \
(i += rb_strlen_lit(s) - 1, 1))
@@ -113,40 +112,28 @@ optimized_unescape_html(VALUE str)
else if (MATCH("mp;")) {
c = '&';
}
- else {
- i = j;
- continue;
- }
+ else continue;
break;
case 'q':
++i;
if (MATCH("uot;")) {
c = '"';
}
- else {
- i = j;
- continue;
- }
+ else continue;
break;
case 'g':
++i;
if (MATCH("t;")) {
c = '>';
}
- else {
- i = j;
- continue;
- }
+ else continue;
break;
case 'l':
++i;
if (MATCH("t;")) {
c = '<';
}
- else {
- i = j;
- continue;
- }
+ else continue;
break;
case '#':
if (len - ++i >= 2 && ISDIGIT(cstr[i])) {
@@ -155,15 +142,9 @@ optimized_unescape_html(VALUE str)
else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) {
cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow);
}
- else {
- i = j;
- continue;
- }
+ else continue;
i += clen;
- if (overflow || cc >= charlimit || cstr[i] != ';') {
- i = j;
- continue;
- }
+ if (overflow || cc >= charlimit || cstr[i] != ';') continue;
if (!dest) {
dest = rb_str_buf_new(len);
}
@@ -477,9 +458,7 @@ InitVM_escape(void)
rb_define_method(rb_mEscape, "escapeHTML", cgiesc_escape_html, 1);
rb_define_method(rb_mEscape, "unescapeHTML", cgiesc_unescape_html, 1);
rb_define_method(rb_mEscape, "escapeURIComponent", cgiesc_escape_uri_component, 1);
- rb_define_alias(rb_mEscape, "escape_uri_component", "escapeURIComponent");
rb_define_method(rb_mEscape, "unescapeURIComponent", cgiesc_unescape_uri_component, -1);
- rb_define_alias(rb_mEscape, "unescape_uri_component", "unescapeURIComponent");
rb_define_method(rb_mEscape, "escape", cgiesc_escape, 1);
rb_define_method(rb_mEscape, "unescape", cgiesc_unescape, -1);
rb_prepend_module(rb_mUtil, rb_mEscape);
diff --git a/ext/cgi/escape/extconf.rb b/ext/cgi/escape/extconf.rb
index 73acd89ca8..16e8ff224d 100644
--- a/ext/cgi/escape/extconf.rb
+++ b/ext/cgi/escape/extconf.rb
@@ -1,7 +1,3 @@
require 'mkmf'
-if RUBY_ENGINE == 'truffleruby'
- File.write("Makefile", dummy_makefile($srcdir).join(""))
-else
- create_makefile 'cgi/escape'
-end
+create_makefile 'cgi/escape'
diff --git a/ext/continuation/depend b/ext/continuation/depend
index f0333d7fe6..81218f9965 100644
--- a/ext/continuation/depend
+++ b/ext/continuation/depend
@@ -51,7 +51,6 @@ continuation.o: $(hdrdir)/ruby/internal/attr/noexcept.h
continuation.o: $(hdrdir)/ruby/internal/attr/noinline.h
continuation.o: $(hdrdir)/ruby/internal/attr/nonnull.h
continuation.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-continuation.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
continuation.o: $(hdrdir)/ruby/internal/attr/pure.h
continuation.o: $(hdrdir)/ruby/internal/attr/restrict.h
continuation.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ continuation.o: $(hdrdir)/ruby/internal/intern/enumerator.h
continuation.o: $(hdrdir)/ruby/internal/intern/error.h
continuation.o: $(hdrdir)/ruby/internal/intern/eval.h
continuation.o: $(hdrdir)/ruby/internal/intern/file.h
+continuation.o: $(hdrdir)/ruby/internal/intern/gc.h
continuation.o: $(hdrdir)/ruby/internal/intern/hash.h
continuation.o: $(hdrdir)/ruby/internal/intern/io.h
continuation.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ continuation.o: $(hdrdir)/ruby/internal/memory.h
continuation.o: $(hdrdir)/ruby/internal/method.h
continuation.o: $(hdrdir)/ruby/internal/module.h
continuation.o: $(hdrdir)/ruby/internal/newobj.h
+continuation.o: $(hdrdir)/ruby/internal/rgengc.h
continuation.o: $(hdrdir)/ruby/internal/scan_args.h
continuation.o: $(hdrdir)/ruby/internal/special_consts.h
continuation.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/coverage/coverage.c b/ext/coverage/coverage.c
index a3381901ee..4578de54e4 100644
--- a/ext/coverage/coverage.c
+++ b/ext/coverage/coverage.c
@@ -8,7 +8,7 @@
************************************************/
-#include "internal/gc.h"
+#include "gc.h"
#include "internal/hash.h"
#include "internal/thread.h"
#include "internal/sanitizers.h"
@@ -29,7 +29,7 @@ static VALUE me2counter = Qnil;
* Returns true if coverage measurement is supported for the given mode.
*
* The mode should be one of the following symbols:
- * +:lines+, +:oneshot_lines+, +:branches+, +:methods+, +:eval+.
+ * +:lines+, +:branches+, +:methods+, +:eval+.
*
* Example:
*
@@ -43,7 +43,6 @@ rb_coverage_supported(VALUE self, VALUE _mode)
return RBOOL(
mode == rb_intern("lines") ||
- mode == rb_intern("oneshot_lines") ||
mode == rb_intern("branches") ||
mode == rb_intern("methods") ||
mode == rb_intern("eval")
diff --git a/ext/coverage/depend b/ext/coverage/depend
index 0a6c61d5c6..e7fab16484 100644
--- a/ext/coverage/depend
+++ b/ext/coverage/depend
@@ -15,7 +15,6 @@ coverage.o: $(hdrdir)/ruby/backward/2/long_long.h
coverage.o: $(hdrdir)/ruby/backward/2/stdalign.h
coverage.o: $(hdrdir)/ruby/backward/2/stdarg.h
coverage.o: $(hdrdir)/ruby/defines.h
-coverage.o: $(hdrdir)/ruby/encoding.h
coverage.o: $(hdrdir)/ruby/intern.h
coverage.o: $(hdrdir)/ruby/internal/abi.h
coverage.o: $(hdrdir)/ruby/internal/anyargs.h
@@ -55,7 +54,6 @@ coverage.o: $(hdrdir)/ruby/internal/attr/noexcept.h
coverage.o: $(hdrdir)/ruby/internal/attr/noinline.h
coverage.o: $(hdrdir)/ruby/internal/attr/nonnull.h
coverage.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-coverage.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
coverage.o: $(hdrdir)/ruby/internal/attr/pure.h
coverage.o: $(hdrdir)/ruby/internal/attr/restrict.h
coverage.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -88,15 +86,6 @@ coverage.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
coverage.o: $(hdrdir)/ruby/internal/ctype.h
coverage.o: $(hdrdir)/ruby/internal/dllexport.h
coverage.o: $(hdrdir)/ruby/internal/dosish.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/coderange.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/ctype.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/encoding.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/pathname.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/re.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/string.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/symbol.h
-coverage.o: $(hdrdir)/ruby/internal/encoding/transcode.h
coverage.o: $(hdrdir)/ruby/internal/error.h
coverage.o: $(hdrdir)/ruby/internal/eval.h
coverage.o: $(hdrdir)/ruby/internal/event.h
@@ -124,6 +113,7 @@ coverage.o: $(hdrdir)/ruby/internal/intern/enumerator.h
coverage.o: $(hdrdir)/ruby/internal/intern/error.h
coverage.o: $(hdrdir)/ruby/internal/intern/eval.h
coverage.o: $(hdrdir)/ruby/internal/intern/file.h
+coverage.o: $(hdrdir)/ruby/internal/intern/gc.h
coverage.o: $(hdrdir)/ruby/internal/intern/hash.h
coverage.o: $(hdrdir)/ruby/internal/intern/io.h
coverage.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -154,6 +144,7 @@ coverage.o: $(hdrdir)/ruby/internal/memory.h
coverage.o: $(hdrdir)/ruby/internal/method.h
coverage.o: $(hdrdir)/ruby/internal/module.h
coverage.o: $(hdrdir)/ruby/internal/newobj.h
+coverage.o: $(hdrdir)/ruby/internal/rgengc.h
coverage.o: $(hdrdir)/ruby/internal/scan_args.h
coverage.o: $(hdrdir)/ruby/internal/special_consts.h
coverage.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -166,8 +157,6 @@ coverage.o: $(hdrdir)/ruby/internal/variable.h
coverage.o: $(hdrdir)/ruby/internal/warning_push.h
coverage.o: $(hdrdir)/ruby/internal/xmalloc.h
coverage.o: $(hdrdir)/ruby/missing.h
-coverage.o: $(hdrdir)/ruby/onigmo.h
-coverage.o: $(hdrdir)/ruby/oniguruma.h
coverage.o: $(hdrdir)/ruby/ruby.h
coverage.o: $(hdrdir)/ruby/st.h
coverage.o: $(hdrdir)/ruby/subst.h
@@ -177,6 +166,7 @@ coverage.o: $(top_srcdir)/ccan/container_of/container_of.h
coverage.o: $(top_srcdir)/ccan/list/list.h
coverage.o: $(top_srcdir)/ccan/str/str.h
coverage.o: $(top_srcdir)/constant.h
+coverage.o: $(top_srcdir)/gc.h
coverage.o: $(top_srcdir)/id_table.h
coverage.o: $(top_srcdir)/internal.h
coverage.o: $(top_srcdir)/internal/array.h
@@ -196,7 +186,6 @@ coverage.o: $(top_srcdir)/method.h
coverage.o: $(top_srcdir)/node.h
coverage.o: $(top_srcdir)/ruby_assert.h
coverage.o: $(top_srcdir)/ruby_atomic.h
-coverage.o: $(top_srcdir)/rubyparser.h
coverage.o: $(top_srcdir)/shape.h
coverage.o: $(top_srcdir)/thread_pthread.h
coverage.o: $(top_srcdir)/vm_core.h
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
index f4b390584b..21367c0ddf 100644
--- a/ext/date/date_core.c
+++ b/ext/date/date_core.c
@@ -2589,6 +2589,8 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
*
* See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
*
+ * Date.valid_date? is an alias for Date.valid_civil?.
+ *
* Related: Date.jd, Date.new.
*/
static VALUE
@@ -2984,6 +2986,8 @@ date_s_julian_leap_p(VALUE klass, VALUE y)
* Date.gregorian_leap?(2000) # => true
* Date.gregorian_leap?(2001) # => false
*
+ * Date.leap? is an alias for Date.gregorian_leap?.
+ *
* Related: Date.julian_leap?.
*/
static VALUE
@@ -3489,6 +3493,8 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
*
* See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
*
+ * Date.civil is an alias for Date.new.
+ *
* Related: Date.jd.
*/
static VALUE
@@ -4826,6 +4832,8 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
*
* See argument {limit}[rdoc-ref:Date@Argument+limit].
*
+ * Date._rfc822 is an alias for Date._rfc2822.
+ *
* Related: Date.rfc2822 (returns a \Date object).
*/
static VALUE
@@ -4856,6 +4864,8 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
* - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
*
+ * Date.rfc822 is an alias for Date.rfc2822.
+ *
* Related: Date._rfc2822 (returns a hash).
*/
static VALUE
@@ -5336,6 +5346,7 @@ d_lite_yday(VALUE self)
*
* Date.new(2001, 2, 3).mon # => 2
*
+ * Date#month is an alias for Date#mon.
*/
static VALUE
d_lite_mon(VALUE self)
@@ -5352,6 +5363,7 @@ d_lite_mon(VALUE self)
*
* Date.new(2001, 2, 3).mday # => 3
*
+ * Date#day is an alias for Date#mday.
*/
static VALUE
d_lite_mday(VALUE self)
@@ -5601,6 +5613,7 @@ d_lite_hour(VALUE self)
*
* DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5
*
+ * Date#minute is an alias for Date#min.
*/
static VALUE
d_lite_min(VALUE self)
@@ -5617,6 +5630,7 @@ d_lite_min(VALUE self)
*
* DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6
*
+ * Date#second is an alias for Date#sec.
*/
static VALUE
d_lite_sec(VALUE self)
@@ -5634,6 +5648,7 @@ d_lite_sec(VALUE self)
*
* DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2)
*
+ * Date#second_fraction is an alias for Date#sec_fraction.
*/
static VALUE
d_lite_sec_fraction(VALUE self)
@@ -6409,6 +6424,7 @@ d_lite_prev_day(int argc, VALUE *argv, VALUE self)
* d.to_s # => "2001-02-03"
* d.next.to_s # => "2001-02-04"
*
+ * Date#succ is an alias for Date#next.
*/
static VALUE
d_lite_next(VALUE self)
@@ -7282,6 +7298,7 @@ strftimev(const char *fmt, VALUE self,
*
* See {asctime}[https://linux.die.net/man/3/asctime].
*
+ * Date#ctime is an alias for Date#asctime.
*/
static VALUE
d_lite_asctime(VALUE self)
@@ -7299,6 +7316,7 @@ d_lite_asctime(VALUE self)
*
* Date.new(2001, 2, 3).iso8601 # => "2001-02-03"
*
+ * Date#xmlschema is an alias for Date#iso8601.
*/
static VALUE
d_lite_iso8601(VALUE self)
@@ -7331,6 +7349,7 @@ d_lite_rfc3339(VALUE self)
*
* Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
*
+ * Date#rfc822 is an alias for Date#rfc2822.
*/
static VALUE
d_lite_rfc2822(VALUE self)
@@ -8726,8 +8745,8 @@ dt_lite_to_s(VALUE self)
*
* DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"
*
- * For other formats,
- * see {Formats for Dates and Times}[rdoc-ref:strftime_formatting.rdoc]:
+ * For other formats, see
+ * {Formats for Dates and Times}[doc/strftime_formatting.rdoc].
*
*/
static VALUE
diff --git a/ext/date/depend b/ext/date/depend
index 82f85f7bf3..3f550cd0a7 100644
--- a/ext/date/depend
+++ b/ext/date/depend
@@ -53,7 +53,6 @@ date_core.o: $(hdrdir)/ruby/internal/attr/noexcept.h
date_core.o: $(hdrdir)/ruby/internal/attr/noinline.h
date_core.o: $(hdrdir)/ruby/internal/attr/nonnull.h
date_core.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-date_core.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
date_core.o: $(hdrdir)/ruby/internal/attr/pure.h
date_core.o: $(hdrdir)/ruby/internal/attr/restrict.h
date_core.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ date_core.o: $(hdrdir)/ruby/internal/intern/enumerator.h
date_core.o: $(hdrdir)/ruby/internal/intern/error.h
date_core.o: $(hdrdir)/ruby/internal/intern/eval.h
date_core.o: $(hdrdir)/ruby/internal/intern/file.h
+date_core.o: $(hdrdir)/ruby/internal/intern/gc.h
date_core.o: $(hdrdir)/ruby/internal/intern/hash.h
date_core.o: $(hdrdir)/ruby/internal/intern/io.h
date_core.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ date_core.o: $(hdrdir)/ruby/internal/memory.h
date_core.o: $(hdrdir)/ruby/internal/method.h
date_core.o: $(hdrdir)/ruby/internal/module.h
date_core.o: $(hdrdir)/ruby/internal/newobj.h
+date_core.o: $(hdrdir)/ruby/internal/rgengc.h
date_core.o: $(hdrdir)/ruby/internal/scan_args.h
date_core.o: $(hdrdir)/ruby/internal/special_consts.h
date_core.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -226,7 +227,6 @@ date_parse.o: $(hdrdir)/ruby/internal/attr/noexcept.h
date_parse.o: $(hdrdir)/ruby/internal/attr/noinline.h
date_parse.o: $(hdrdir)/ruby/internal/attr/nonnull.h
date_parse.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-date_parse.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
date_parse.o: $(hdrdir)/ruby/internal/attr/pure.h
date_parse.o: $(hdrdir)/ruby/internal/attr/restrict.h
date_parse.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -296,6 +296,7 @@ date_parse.o: $(hdrdir)/ruby/internal/intern/enumerator.h
date_parse.o: $(hdrdir)/ruby/internal/intern/error.h
date_parse.o: $(hdrdir)/ruby/internal/intern/eval.h
date_parse.o: $(hdrdir)/ruby/internal/intern/file.h
+date_parse.o: $(hdrdir)/ruby/internal/intern/gc.h
date_parse.o: $(hdrdir)/ruby/internal/intern/hash.h
date_parse.o: $(hdrdir)/ruby/internal/intern/io.h
date_parse.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -326,6 +327,7 @@ date_parse.o: $(hdrdir)/ruby/internal/memory.h
date_parse.o: $(hdrdir)/ruby/internal/method.h
date_parse.o: $(hdrdir)/ruby/internal/module.h
date_parse.o: $(hdrdir)/ruby/internal/newobj.h
+date_parse.o: $(hdrdir)/ruby/internal/rgengc.h
date_parse.o: $(hdrdir)/ruby/internal/scan_args.h
date_parse.o: $(hdrdir)/ruby/internal/special_consts.h
date_parse.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -400,7 +402,6 @@ date_strftime.o: $(hdrdir)/ruby/internal/attr/noexcept.h
date_strftime.o: $(hdrdir)/ruby/internal/attr/noinline.h
date_strftime.o: $(hdrdir)/ruby/internal/attr/nonnull.h
date_strftime.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-date_strftime.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
date_strftime.o: $(hdrdir)/ruby/internal/attr/pure.h
date_strftime.o: $(hdrdir)/ruby/internal/attr/restrict.h
date_strftime.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -460,6 +461,7 @@ date_strftime.o: $(hdrdir)/ruby/internal/intern/enumerator.h
date_strftime.o: $(hdrdir)/ruby/internal/intern/error.h
date_strftime.o: $(hdrdir)/ruby/internal/intern/eval.h
date_strftime.o: $(hdrdir)/ruby/internal/intern/file.h
+date_strftime.o: $(hdrdir)/ruby/internal/intern/gc.h
date_strftime.o: $(hdrdir)/ruby/internal/intern/hash.h
date_strftime.o: $(hdrdir)/ruby/internal/intern/io.h
date_strftime.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -490,6 +492,7 @@ date_strftime.o: $(hdrdir)/ruby/internal/memory.h
date_strftime.o: $(hdrdir)/ruby/internal/method.h
date_strftime.o: $(hdrdir)/ruby/internal/module.h
date_strftime.o: $(hdrdir)/ruby/internal/newobj.h
+date_strftime.o: $(hdrdir)/ruby/internal/rgengc.h
date_strftime.o: $(hdrdir)/ruby/internal/scan_args.h
date_strftime.o: $(hdrdir)/ruby/internal/special_consts.h
date_strftime.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -561,7 +564,6 @@ date_strptime.o: $(hdrdir)/ruby/internal/attr/noexcept.h
date_strptime.o: $(hdrdir)/ruby/internal/attr/noinline.h
date_strptime.o: $(hdrdir)/ruby/internal/attr/nonnull.h
date_strptime.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-date_strptime.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
date_strptime.o: $(hdrdir)/ruby/internal/attr/pure.h
date_strptime.o: $(hdrdir)/ruby/internal/attr/restrict.h
date_strptime.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -631,6 +633,7 @@ date_strptime.o: $(hdrdir)/ruby/internal/intern/enumerator.h
date_strptime.o: $(hdrdir)/ruby/internal/intern/error.h
date_strptime.o: $(hdrdir)/ruby/internal/intern/eval.h
date_strptime.o: $(hdrdir)/ruby/internal/intern/file.h
+date_strptime.o: $(hdrdir)/ruby/internal/intern/gc.h
date_strptime.o: $(hdrdir)/ruby/internal/intern/hash.h
date_strptime.o: $(hdrdir)/ruby/internal/intern/io.h
date_strptime.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -661,6 +664,7 @@ date_strptime.o: $(hdrdir)/ruby/internal/memory.h
date_strptime.o: $(hdrdir)/ruby/internal/method.h
date_strptime.o: $(hdrdir)/ruby/internal/module.h
date_strptime.o: $(hdrdir)/ruby/internal/newobj.h
+date_strptime.o: $(hdrdir)/ruby/internal/rgengc.h
date_strptime.o: $(hdrdir)/ruby/internal/scan_args.h
date_strptime.o: $(hdrdir)/ruby/internal/special_consts.h
date_strptime.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/date/lib/date.rb b/ext/date/lib/date.rb
index 6888bd2d4e..a9fe3ce4b0 100644
--- a/ext/date/lib/date.rb
+++ b/ext/date/lib/date.rb
@@ -4,7 +4,7 @@
require 'date_core'
class Date
- VERSION = "3.3.4" # :nodoc:
+ VERSION = "3.3.3" # :nodoc:
# call-seq:
# infinite? -> false
diff --git a/ext/digest/bubblebabble/depend b/ext/digest/bubblebabble/depend
index 6f0003a66d..38f5ddb1e2 100644
--- a/ext/digest/bubblebabble/depend
+++ b/ext/digest/bubblebabble/depend
@@ -52,7 +52,6 @@ bubblebabble.o: $(hdrdir)/ruby/internal/attr/noexcept.h
bubblebabble.o: $(hdrdir)/ruby/internal/attr/noinline.h
bubblebabble.o: $(hdrdir)/ruby/internal/attr/nonnull.h
bubblebabble.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-bubblebabble.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
bubblebabble.o: $(hdrdir)/ruby/internal/attr/pure.h
bubblebabble.o: $(hdrdir)/ruby/internal/attr/restrict.h
bubblebabble.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ bubblebabble.o: $(hdrdir)/ruby/internal/intern/enumerator.h
bubblebabble.o: $(hdrdir)/ruby/internal/intern/error.h
bubblebabble.o: $(hdrdir)/ruby/internal/intern/eval.h
bubblebabble.o: $(hdrdir)/ruby/internal/intern/file.h
+bubblebabble.o: $(hdrdir)/ruby/internal/intern/gc.h
bubblebabble.o: $(hdrdir)/ruby/internal/intern/hash.h
bubblebabble.o: $(hdrdir)/ruby/internal/intern/io.h
bubblebabble.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ bubblebabble.o: $(hdrdir)/ruby/internal/memory.h
bubblebabble.o: $(hdrdir)/ruby/internal/method.h
bubblebabble.o: $(hdrdir)/ruby/internal/module.h
bubblebabble.o: $(hdrdir)/ruby/internal/newobj.h
+bubblebabble.o: $(hdrdir)/ruby/internal/rgengc.h
bubblebabble.o: $(hdrdir)/ruby/internal/scan_args.h
bubblebabble.o: $(hdrdir)/ruby/internal/special_consts.h
bubblebabble.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/digest/depend b/ext/digest/depend
index 6df940a679..5a84fd53ec 100644
--- a/ext/digest/depend
+++ b/ext/digest/depend
@@ -52,7 +52,6 @@ digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h
digest.o: $(hdrdir)/ruby/internal/attr/noinline.h
digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h
digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-digest.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
digest.o: $(hdrdir)/ruby/internal/attr/pure.h
digest.o: $(hdrdir)/ruby/internal/attr/restrict.h
digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h
digest.o: $(hdrdir)/ruby/internal/intern/error.h
digest.o: $(hdrdir)/ruby/internal/intern/eval.h
digest.o: $(hdrdir)/ruby/internal/intern/file.h
+digest.o: $(hdrdir)/ruby/internal/intern/gc.h
digest.o: $(hdrdir)/ruby/internal/intern/hash.h
digest.o: $(hdrdir)/ruby/internal/intern/io.h
digest.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ digest.o: $(hdrdir)/ruby/internal/memory.h
digest.o: $(hdrdir)/ruby/internal/method.h
digest.o: $(hdrdir)/ruby/internal/module.h
digest.o: $(hdrdir)/ruby/internal/newobj.h
+digest.o: $(hdrdir)/ruby/internal/rgengc.h
digest.o: $(hdrdir)/ruby/internal/scan_args.h
digest.o: $(hdrdir)/ruby/internal/special_consts.h
digest.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/digest/digest.h b/ext/digest/digest.h
index 68a3da5dd2..8a4c5b7e4e 100644
--- a/ext/digest/digest.h
+++ b/ext/digest/digest.h
@@ -40,8 +40,7 @@ rb_digest_##name##_update(void *ctx, unsigned char *ptr, size_t size) \
for (; size > stride; size -= stride, ptr += stride) { \
name##_Update(ctx, ptr, stride); \
} \
- /* Since size <= stride, size should fit into an unsigned int */ \
- if (size > 0) name##_Update(ctx, ptr, (unsigned int)size); \
+ if (size > 0) name##_Update(ctx, ptr, size); \
}
#define DEFINE_FINISH_FUNC_FROM_FINAL(name) \
diff --git a/ext/digest/md5/depend b/ext/digest/md5/depend
index da1b345999..ea1ceec7fd 100644
--- a/ext/digest/md5/depend
+++ b/ext/digest/md5/depend
@@ -55,7 +55,6 @@ md5.o: $(hdrdir)/ruby/internal/attr/noexcept.h
md5.o: $(hdrdir)/ruby/internal/attr/noinline.h
md5.o: $(hdrdir)/ruby/internal/attr/nonnull.h
md5.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-md5.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
md5.o: $(hdrdir)/ruby/internal/attr/pure.h
md5.o: $(hdrdir)/ruby/internal/attr/restrict.h
md5.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -115,6 +114,7 @@ md5.o: $(hdrdir)/ruby/internal/intern/enumerator.h
md5.o: $(hdrdir)/ruby/internal/intern/error.h
md5.o: $(hdrdir)/ruby/internal/intern/eval.h
md5.o: $(hdrdir)/ruby/internal/intern/file.h
+md5.o: $(hdrdir)/ruby/internal/intern/gc.h
md5.o: $(hdrdir)/ruby/internal/intern/hash.h
md5.o: $(hdrdir)/ruby/internal/intern/io.h
md5.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -145,6 +145,7 @@ md5.o: $(hdrdir)/ruby/internal/memory.h
md5.o: $(hdrdir)/ruby/internal/method.h
md5.o: $(hdrdir)/ruby/internal/module.h
md5.o: $(hdrdir)/ruby/internal/newobj.h
+md5.o: $(hdrdir)/ruby/internal/rgengc.h
md5.o: $(hdrdir)/ruby/internal/scan_args.h
md5.o: $(hdrdir)/ruby/internal/special_consts.h
md5.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -216,7 +217,6 @@ md5init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
md5init.o: $(hdrdir)/ruby/internal/attr/noinline.h
md5init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
md5init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-md5init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
md5init.o: $(hdrdir)/ruby/internal/attr/pure.h
md5init.o: $(hdrdir)/ruby/internal/attr/restrict.h
md5init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -276,6 +276,7 @@ md5init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
md5init.o: $(hdrdir)/ruby/internal/intern/error.h
md5init.o: $(hdrdir)/ruby/internal/intern/eval.h
md5init.o: $(hdrdir)/ruby/internal/intern/file.h
+md5init.o: $(hdrdir)/ruby/internal/intern/gc.h
md5init.o: $(hdrdir)/ruby/internal/intern/hash.h
md5init.o: $(hdrdir)/ruby/internal/intern/io.h
md5init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -306,6 +307,7 @@ md5init.o: $(hdrdir)/ruby/internal/memory.h
md5init.o: $(hdrdir)/ruby/internal/method.h
md5init.o: $(hdrdir)/ruby/internal/module.h
md5init.o: $(hdrdir)/ruby/internal/newobj.h
+md5init.o: $(hdrdir)/ruby/internal/rgengc.h
md5init.o: $(hdrdir)/ruby/internal/scan_args.h
md5init.o: $(hdrdir)/ruby/internal/special_consts.h
md5init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/digest/rmd160/depend b/ext/digest/rmd160/depend
index abfa08b023..3a0ed72732 100644
--- a/ext/digest/rmd160/depend
+++ b/ext/digest/rmd160/depend
@@ -55,7 +55,6 @@ rmd160.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rmd160.o: $(hdrdir)/ruby/internal/attr/noinline.h
rmd160.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rmd160.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rmd160.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rmd160.o: $(hdrdir)/ruby/internal/attr/pure.h
rmd160.o: $(hdrdir)/ruby/internal/attr/restrict.h
rmd160.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -115,6 +114,7 @@ rmd160.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rmd160.o: $(hdrdir)/ruby/internal/intern/error.h
rmd160.o: $(hdrdir)/ruby/internal/intern/eval.h
rmd160.o: $(hdrdir)/ruby/internal/intern/file.h
+rmd160.o: $(hdrdir)/ruby/internal/intern/gc.h
rmd160.o: $(hdrdir)/ruby/internal/intern/hash.h
rmd160.o: $(hdrdir)/ruby/internal/intern/io.h
rmd160.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -145,6 +145,7 @@ rmd160.o: $(hdrdir)/ruby/internal/memory.h
rmd160.o: $(hdrdir)/ruby/internal/method.h
rmd160.o: $(hdrdir)/ruby/internal/module.h
rmd160.o: $(hdrdir)/ruby/internal/newobj.h
+rmd160.o: $(hdrdir)/ruby/internal/rgengc.h
rmd160.o: $(hdrdir)/ruby/internal/scan_args.h
rmd160.o: $(hdrdir)/ruby/internal/special_consts.h
rmd160.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -216,7 +217,6 @@ rmd160init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
rmd160init.o: $(hdrdir)/ruby/internal/attr/noinline.h
rmd160init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
rmd160init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-rmd160init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
rmd160init.o: $(hdrdir)/ruby/internal/attr/pure.h
rmd160init.o: $(hdrdir)/ruby/internal/attr/restrict.h
rmd160init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -276,6 +276,7 @@ rmd160init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
rmd160init.o: $(hdrdir)/ruby/internal/intern/error.h
rmd160init.o: $(hdrdir)/ruby/internal/intern/eval.h
rmd160init.o: $(hdrdir)/ruby/internal/intern/file.h
+rmd160init.o: $(hdrdir)/ruby/internal/intern/gc.h
rmd160init.o: $(hdrdir)/ruby/internal/intern/hash.h
rmd160init.o: $(hdrdir)/ruby/internal/intern/io.h
rmd160init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -306,6 +307,7 @@ rmd160init.o: $(hdrdir)/ruby/internal/memory.h
rmd160init.o: $(hdrdir)/ruby/internal/method.h
rmd160init.o: $(hdrdir)/ruby/internal/module.h
rmd160init.o: $(hdrdir)/ruby/internal/newobj.h
+rmd160init.o: $(hdrdir)/ruby/internal/rgengc.h
rmd160init.o: $(hdrdir)/ruby/internal/scan_args.h
rmd160init.o: $(hdrdir)/ruby/internal/special_consts.h
rmd160init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/digest/sha1/depend b/ext/digest/sha1/depend
index d17338e92b..48aaef158b 100644
--- a/ext/digest/sha1/depend
+++ b/ext/digest/sha1/depend
@@ -55,7 +55,6 @@ sha1.o: $(hdrdir)/ruby/internal/attr/noexcept.h
sha1.o: $(hdrdir)/ruby/internal/attr/noinline.h
sha1.o: $(hdrdir)/ruby/internal/attr/nonnull.h
sha1.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-sha1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
sha1.o: $(hdrdir)/ruby/internal/attr/pure.h
sha1.o: $(hdrdir)/ruby/internal/attr/restrict.h
sha1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -115,6 +114,7 @@ sha1.o: $(hdrdir)/ruby/internal/intern/enumerator.h
sha1.o: $(hdrdir)/ruby/internal/intern/error.h
sha1.o: $(hdrdir)/ruby/internal/intern/eval.h
sha1.o: $(hdrdir)/ruby/internal/intern/file.h
+sha1.o: $(hdrdir)/ruby/internal/intern/gc.h
sha1.o: $(hdrdir)/ruby/internal/intern/hash.h
sha1.o: $(hdrdir)/ruby/internal/intern/io.h
sha1.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -145,6 +145,7 @@ sha1.o: $(hdrdir)/ruby/internal/memory.h
sha1.o: $(hdrdir)/ruby/internal/method.h
sha1.o: $(hdrdir)/ruby/internal/module.h
sha1.o: $(hdrdir)/ruby/internal/newobj.h
+sha1.o: $(hdrdir)/ruby/internal/rgengc.h
sha1.o: $(hdrdir)/ruby/internal/scan_args.h
sha1.o: $(hdrdir)/ruby/internal/special_consts.h
sha1.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -216,7 +217,6 @@ sha1init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
sha1init.o: $(hdrdir)/ruby/internal/attr/noinline.h
sha1init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
sha1init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-sha1init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
sha1init.o: $(hdrdir)/ruby/internal/attr/pure.h
sha1init.o: $(hdrdir)/ruby/internal/attr/restrict.h
sha1init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -276,6 +276,7 @@ sha1init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
sha1init.o: $(hdrdir)/ruby/internal/intern/error.h
sha1init.o: $(hdrdir)/ruby/internal/intern/eval.h
sha1init.o: $(hdrdir)/ruby/internal/intern/file.h
+sha1init.o: $(hdrdir)/ruby/internal/intern/gc.h
sha1init.o: $(hdrdir)/ruby/internal/intern/hash.h
sha1init.o: $(hdrdir)/ruby/internal/intern/io.h
sha1init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -306,6 +307,7 @@ sha1init.o: $(hdrdir)/ruby/internal/memory.h
sha1init.o: $(hdrdir)/ruby/internal/method.h
sha1init.o: $(hdrdir)/ruby/internal/module.h
sha1init.o: $(hdrdir)/ruby/internal/newobj.h
+sha1init.o: $(hdrdir)/ruby/internal/rgengc.h
sha1init.o: $(hdrdir)/ruby/internal/scan_args.h
sha1init.o: $(hdrdir)/ruby/internal/special_consts.h
sha1init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/digest/sha2/depend b/ext/digest/sha2/depend
index 7b88b6411f..47a859068c 100644
--- a/ext/digest/sha2/depend
+++ b/ext/digest/sha2/depend
@@ -55,7 +55,6 @@ sha2.o: $(hdrdir)/ruby/internal/attr/noexcept.h
sha2.o: $(hdrdir)/ruby/internal/attr/noinline.h
sha2.o: $(hdrdir)/ruby/internal/attr/nonnull.h
sha2.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-sha2.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
sha2.o: $(hdrdir)/ruby/internal/attr/pure.h
sha2.o: $(hdrdir)/ruby/internal/attr/restrict.h
sha2.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -115,6 +114,7 @@ sha2.o: $(hdrdir)/ruby/internal/intern/enumerator.h
sha2.o: $(hdrdir)/ruby/internal/intern/error.h
sha2.o: $(hdrdir)/ruby/internal/intern/eval.h
sha2.o: $(hdrdir)/ruby/internal/intern/file.h
+sha2.o: $(hdrdir)/ruby/internal/intern/gc.h
sha2.o: $(hdrdir)/ruby/internal/intern/hash.h
sha2.o: $(hdrdir)/ruby/internal/intern/io.h
sha2.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -145,6 +145,7 @@ sha2.o: $(hdrdir)/ruby/internal/memory.h
sha2.o: $(hdrdir)/ruby/internal/method.h
sha2.o: $(hdrdir)/ruby/internal/module.h
sha2.o: $(hdrdir)/ruby/internal/newobj.h
+sha2.o: $(hdrdir)/ruby/internal/rgengc.h
sha2.o: $(hdrdir)/ruby/internal/scan_args.h
sha2.o: $(hdrdir)/ruby/internal/special_consts.h
sha2.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -216,7 +217,6 @@ sha2init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
sha2init.o: $(hdrdir)/ruby/internal/attr/noinline.h
sha2init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
sha2init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-sha2init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
sha2init.o: $(hdrdir)/ruby/internal/attr/pure.h
sha2init.o: $(hdrdir)/ruby/internal/attr/restrict.h
sha2init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -276,6 +276,7 @@ sha2init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
sha2init.o: $(hdrdir)/ruby/internal/intern/error.h
sha2init.o: $(hdrdir)/ruby/internal/intern/eval.h
sha2init.o: $(hdrdir)/ruby/internal/intern/file.h
+sha2init.o: $(hdrdir)/ruby/internal/intern/gc.h
sha2init.o: $(hdrdir)/ruby/internal/intern/hash.h
sha2init.o: $(hdrdir)/ruby/internal/intern/io.h
sha2init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -306,6 +307,7 @@ sha2init.o: $(hdrdir)/ruby/internal/memory.h
sha2init.o: $(hdrdir)/ruby/internal/method.h
sha2init.o: $(hdrdir)/ruby/internal/module.h
sha2init.o: $(hdrdir)/ruby/internal/newobj.h
+sha2init.o: $(hdrdir)/ruby/internal/rgengc.h
sha2init.o: $(hdrdir)/ruby/internal/scan_args.h
sha2init.o: $(hdrdir)/ruby/internal/special_consts.h
sha2init.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/etc/depend b/ext/etc/depend
index 00787b6aaf..a541db6db6 100644
--- a/ext/etc/depend
+++ b/ext/etc/depend
@@ -58,7 +58,6 @@ etc.o: $(hdrdir)/ruby/internal/attr/noexcept.h
etc.o: $(hdrdir)/ruby/internal/attr/noinline.h
etc.o: $(hdrdir)/ruby/internal/attr/nonnull.h
etc.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-etc.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
etc.o: $(hdrdir)/ruby/internal/attr/pure.h
etc.o: $(hdrdir)/ruby/internal/attr/restrict.h
etc.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -127,6 +126,7 @@ etc.o: $(hdrdir)/ruby/internal/intern/enumerator.h
etc.o: $(hdrdir)/ruby/internal/intern/error.h
etc.o: $(hdrdir)/ruby/internal/intern/eval.h
etc.o: $(hdrdir)/ruby/internal/intern/file.h
+etc.o: $(hdrdir)/ruby/internal/intern/gc.h
etc.o: $(hdrdir)/ruby/internal/intern/hash.h
etc.o: $(hdrdir)/ruby/internal/intern/io.h
etc.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -157,6 +157,7 @@ etc.o: $(hdrdir)/ruby/internal/memory.h
etc.o: $(hdrdir)/ruby/internal/method.h
etc.o: $(hdrdir)/ruby/internal/module.h
etc.o: $(hdrdir)/ruby/internal/newobj.h
+etc.o: $(hdrdir)/ruby/internal/rgengc.h
etc.o: $(hdrdir)/ruby/internal/scan_args.h
etc.o: $(hdrdir)/ruby/internal/special_consts.h
etc.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index 23127ca613..6c7145b40b 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -54,9 +54,9 @@ static VALUE sGroup;
# include <stdlib.h>
# endif
#endif
-RUBY_EXTERN char *getlogin(void);
+char *getlogin();
-#define RUBY_ETC_VERSION "1.4.3"
+#define RUBY_ETC_VERSION "1.4.2"
#ifdef HAVE_RB_DEPRECATE_CONSTANT
void rb_deprecate_constant(VALUE mod, const char *name);
@@ -66,17 +66,6 @@ void rb_deprecate_constant(VALUE mod, const char *name);
#include "constdefs.h"
-#ifndef HAVE_RB_IO_DESCRIPTOR
-static int
-io_descriptor_fallback(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- return fptr->fd;
-}
-#define rb_io_descriptor io_descriptor_fallback
-#endif
-
#ifdef HAVE_RUBY_ATOMIC_H
# include "ruby/atomic.h"
#else
@@ -952,11 +941,14 @@ io_pathconf(VALUE io, VALUE arg)
{
int name;
long ret;
+ rb_io_t *fptr;
name = NUM2INT(arg);
+ GetOpenFile(io, fptr);
+
errno = 0;
- ret = fpathconf(rb_io_descriptor(io), name);
+ ret = fpathconf(fptr->fd, name);
if (ret == -1) {
if (errno == 0) /* no limit */
return Qnil;
diff --git a/ext/etc/extconf.rb b/ext/etc/extconf.rb
index 2e28d58037..159b1614b7 100644
--- a/ext/etc/extconf.rb
+++ b/ext/etc/extconf.rb
@@ -43,23 +43,13 @@ have_struct_member('struct group', 'gr_passwd', 'grp.h')
# for https://github.com/ruby/etc
srcdir = File.expand_path("..", __FILE__)
-constdefs = "#{srcdir}/constdefs.h"
-if !File.exist?(constdefs)
- ruby = RbConfig.ruby
- if File.file?(ruby)
- ruby = [ruby]
- else
- require "shellwords"
- ruby = Shellwords.split(ruby)
- end
- system(*ruby, "#{srcdir}/mkconstants.rb", "-o", constdefs)
+if !File.exist?("#{srcdir}/depend")
+ %x[#{RbConfig.ruby} #{srcdir}/mkconstants.rb -o #{srcdir}/constdefs.h]
end
# TODO: remove when dropping 2.7 support, as exported since 3.0
have_func('rb_deprecate_constant(Qnil, "None")')
-have_func("rb_io_descriptor")
-
$distcleanfiles << "constdefs.h"
create_makefile("etc")
diff --git a/ext/extmk.rb b/ext/extmk.rb
index d9c2417dfa..4e77a7167b 100755
--- a/ext/extmk.rb
+++ b/ext/extmk.rb
@@ -43,7 +43,11 @@ $" << "mkmf.rb"
load File.expand_path("lib/mkmf.rb", srcdir)
require 'optparse/shellwords'
-@null = File::NULL
+if defined?(File::NULL)
+ @null = File::NULL
+elsif !File.chardev?(@null = "/dev/null")
+ @null = "nul"
+end
def verbose?
$mflags.defined?("V") == "1"
@@ -167,8 +171,6 @@ def extmake(target, basedir = 'ext', maybestatic = true)
$mdir = target
$srcdir = File.join($top_srcdir, basedir, $mdir)
$preload = nil
- $objs = []
- $srcs = []
$extso = []
makefile = "./Makefile"
static = $static
@@ -202,7 +204,7 @@ def extmake(target, basedir = 'ext', maybestatic = true)
begin
$extconf_h = nil
ok &&= extract_makefile(makefile)
- old_objs = $objs
+ old_objs = $objs || []
old_cleanfiles = $distcleanfiles | $cleanfiles
conf = ["#{$srcdir}/makefile.rb", "#{$srcdir}/extconf.rb"].find {|f| File.exist?(f)}
if (!ok || ($extconf_h && !File.exist?($extconf_h)) ||
@@ -265,6 +267,8 @@ def extmake(target, basedir = 'ext', maybestatic = true)
unless $destdir.to_s.empty? or $mflags.defined?("DESTDIR")
args += ["DESTDIR=" + relative_from($destdir, "../"+prefix)]
end
+ $objs ||= []
+ $srcs ||= []
if $static and ok and !$objs.empty? and !noinstall
args += ["static"]
$extlist.push [(maybestatic ? $static : false), target, $target, $preload]
@@ -774,13 +778,6 @@ begin
mf.macro "NOTE_MESG", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb skip]
mf.macro "NOTE_NAME", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb fail]
%w[RM RMDIRS RMDIR RMALL].each {|w| mf.macro w, [RbConfig::CONFIG[w]]}
- if $nmake
- message = ['@(for %I in (', ') do @echo.%~I)']
- else
- message = ['@for line in', '; do echo "$$line"; done']
- end
- mf.macro "MESSAGE_BEGIN", [message.first]
- mf.macro "MESSAGE_END", [message.last]
mf.puts
targets = %w[all install static install-so install-rb clean distclean realclean]
targets.each do |tgt|
@@ -843,17 +840,15 @@ begin
fails.each do |ext, (parent, err)|
abandon ||= mandatory_exts[ext]
mf.puts %Q<\t@$(NOTE_NAME) "#{ext}:">
- mf.puts "\t$(MESSAGE_BEGIN) \\"
if parent
- mf.puts %Q<\t"\tCould not be configured. It will not be installed." \\>
+ mf.puts %Q<\t@echo "\tCould not be configured. It will not be installed.">
err and err.scan(/.+/) do |ee|
- mf.puts %Q<\t"\t#{ee.gsub(/["`$^]/, '\\\\\\&')}" \\>
+ mf.puts %Q<\t@echo "\t#{ee.gsub(/["`$^]/, '\\\\\\&')}">
end
- mf.puts %Q<\t"\tCheck #{ext_prefix}/#{ext}/mkmf.log for more details." \\>
+ mf.puts %Q<\t@echo "\tCheck #{ext_prefix}/#{ext}/mkmf.log for more details.">
else
- mf.puts %Q<\t"\tSkipped because its parent was not configured." \\>
+ mf.puts %Q<\t@echo "\tSkipped because its parent was not configured.">
end
- mf.puts "\t$(MESSAGE_END)"
end
mf.puts "note:\n"
mf.puts %Q<\t@$(NOTE_MESG) "*** Fix the problems, then remove these directories and try again if you want.">
diff --git a/ext/fcntl/depend b/ext/fcntl/depend
index 9ce9fa30ef..718de62e26 100644
--- a/ext/fcntl/depend
+++ b/ext/fcntl/depend
@@ -52,7 +52,6 @@ fcntl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
fcntl.o: $(hdrdir)/ruby/internal/attr/noinline.h
fcntl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
fcntl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-fcntl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
fcntl.o: $(hdrdir)/ruby/internal/attr/pure.h
fcntl.o: $(hdrdir)/ruby/internal/attr/restrict.h
fcntl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -112,6 +111,7 @@ fcntl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
fcntl.o: $(hdrdir)/ruby/internal/intern/error.h
fcntl.o: $(hdrdir)/ruby/internal/intern/eval.h
fcntl.o: $(hdrdir)/ruby/internal/intern/file.h
+fcntl.o: $(hdrdir)/ruby/internal/intern/gc.h
fcntl.o: $(hdrdir)/ruby/internal/intern/hash.h
fcntl.o: $(hdrdir)/ruby/internal/intern/io.h
fcntl.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -142,6 +142,7 @@ fcntl.o: $(hdrdir)/ruby/internal/memory.h
fcntl.o: $(hdrdir)/ruby/internal/method.h
fcntl.o: $(hdrdir)/ruby/internal/module.h
fcntl.o: $(hdrdir)/ruby/internal/newobj.h
+fcntl.o: $(hdrdir)/ruby/internal/rgengc.h
fcntl.o: $(hdrdir)/ruby/internal/scan_args.h
fcntl.o: $(hdrdir)/ruby/internal/special_consts.h
fcntl.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/fcntl/fcntl.c b/ext/fcntl/fcntl.c
index 4af2077a0a..3bccc41e4c 100644
--- a/ext/fcntl/fcntl.c
+++ b/ext/fcntl/fcntl.c
@@ -61,16 +61,10 @@ pack up your own arguments to pass as args for locking functions, etc.
* f.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK|m)
*
*/
-
-#define FCNTL_VERSION "1.1.0"
-
void
Init_fcntl(void)
{
VALUE mFcntl = rb_define_module("Fcntl");
-
- rb_define_const(mFcntl, "VERSION", rb_str_new_cstr(FCNTL_VERSION));
-
#ifdef F_DUPFD
/* Document-const: F_DUPFD
*
diff --git a/ext/fcntl/fcntl.gemspec b/ext/fcntl/fcntl.gemspec
index 54aadb4b81..09d3fc2568 100644
--- a/ext/fcntl/fcntl.gemspec
+++ b/ext/fcntl/fcntl.gemspec
@@ -1,19 +1,9 @@
# coding: utf-8
# frozen_string_literal: true
-source_version = ["", "ext/fcntl/"].find do |dir|
- begin
- break File.open(File.join(__dir__, "#{dir}fcntl.c")) {|f|
- f.gets("\n#define FCNTL_VERSION ")
- f.gets[/\s*"(.+)"/, 1]
- }
- rescue Errno::ENOENT
- end
-end
-
Gem::Specification.new do |spec|
spec.name = "fcntl"
- spec.version = source_version
+ spec.version = "1.0.2"
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 2b4cdb6608..892f522a62 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -1,5 +1,4 @@
#include <fiddle.h>
-#include <stdbool.h>
#include <ruby/thread.h>
int ruby_thread_has_gvl_p(void); /* from internal.h */
@@ -55,13 +54,10 @@ closure_memsize(const void * ptr)
}
const rb_data_type_t closure_data_type = {
- .wrap_struct_name = "fiddle/closure",
- .function = {
- .dmark = 0,
- .dfree = dealloc,
- .dsize = closure_memsize
- },
- .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ "fiddle/closure",
+ {0, dealloc, closure_memsize,},
+ 0, 0,
+ RUBY_TYPED_FREE_IMMEDIATELY,
};
struct callback_args {
@@ -140,20 +136,6 @@ with_gvl_callback(void *ptr)
rb_ary_push(params,
rb_str_new_cstr(*((const char **)(x->args[i]))));
break;
- case TYPE_BOOL:
- if (sizeof(bool) == sizeof(char)) {
- rb_ary_push(params, CBOOL2RBBOOL(*(unsigned char *)x->args[i]));
- } else if (sizeof(bool) == sizeof(short)) {
- rb_ary_push(params, CBOOL2RBBOOL(*(unsigned short *)x->args[i]));
- } else if (sizeof(bool) == sizeof(int)) {
- rb_ary_push(params, CBOOL2RBBOOL(*(unsigned int *)x->args[i]));
- } else if (sizeof(bool) == sizeof(long)) {
- rb_ary_push(params, CBOOL2RBBOOL(*(unsigned long *)x->args[i]));
- } else {
- rb_raise(rb_eNotImpError, "bool isn't supported: %u",
- (unsigned int)sizeof(bool));
- }
- break;
default:
rb_raise(rb_eRuntimeError, "closure args: %d", type);
}
@@ -203,13 +185,6 @@ with_gvl_callback(void *ptr)
/* Dangerous. Callback must keep reference of the String. */
*((const char **)(x->resp)) = StringValueCStr(ret);
break;
- case TYPE_BOOL:
- if (sizeof(bool) == sizeof(long)) {
- *(unsigned long *)x->resp = RB_TEST(ret);
- } else {
- *(ffi_arg *)x->resp = RB_TEST(ret);
- }
- break;
default:
rb_raise(rb_eRuntimeError, "closure retval: %d", type);
}
diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c
index 796bf929c3..3b70f7de4c 100644
--- a/ext/fiddle/conversions.c
+++ b/ext/fiddle/conversions.c
@@ -1,5 +1,3 @@
-#include <stdbool.h>
-
#include <fiddle.h>
VALUE
@@ -46,7 +44,6 @@ rb_fiddle_type_ensure(VALUE type)
ID ptrdiff_t_id;
ID intptr_t_id;
ID uintptr_t_id;
- ID bool_id;
RUBY_CONST_ID(void_id, "void");
RUBY_CONST_ID(voidp_id, "voidp");
RUBY_CONST_ID(char_id, "char");
@@ -77,7 +74,6 @@ rb_fiddle_type_ensure(VALUE type)
RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
RUBY_CONST_ID(intptr_t_id, "intptr_t");
RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
- RUBY_CONST_ID(bool_id, "bool");
if (type_id == void_id) {
return INT2NUM(TYPE_VOID);
}
@@ -148,9 +144,6 @@ rb_fiddle_type_ensure(VALUE type)
else if (type_id == uintptr_t_id) {
return INT2NUM(TYPE_UINTPTR_T);
}
- else if (type_id == bool_id) {
- return INT2NUM(TYPE_BOOL);
- }
else {
type = original_type;
}
@@ -194,20 +187,6 @@ rb_fiddle_int_to_ffi_type(int type)
return &ffi_type_double;
case TYPE_CONST_STRING:
return &ffi_type_pointer;
- case TYPE_BOOL:
- signed_p = 0;
- if (sizeof(bool) == sizeof(char)) {
- return rb_ffi_type_of(char);
- } else if (sizeof(bool) == sizeof(short)) {
- return rb_ffi_type_of(short);
- } else if (sizeof(bool) == sizeof(int)) {
- return rb_ffi_type_of(int);
- } else if (sizeof(bool) == sizeof(long)) {
- return rb_ffi_type_of(long);
- } else {
- rb_raise(rb_eNotImpError, "bool isn't supported: %u",
- (unsigned int)sizeof(bool));
- }
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
@@ -230,11 +209,7 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
dst->pointer = NUM2PTR(rb_Integer(*src));
break;
case TYPE_CHAR:
- if (RB_TYPE_P(*src, RUBY_T_STRING) && RSTRING_LEN(*src) == 1) {
- dst->schar = RSTRING_PTR(*src)[0];
- } else {
- dst->schar = (signed char)NUM2INT(*src);
- }
+ dst->schar = (signed char)NUM2INT(*src);
break;
case TYPE_UCHAR:
dst->uchar = (unsigned char)NUM2UINT(*src);
@@ -279,23 +254,8 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
dst->pointer = rb_string_value_cstr(src);
}
break;
- case TYPE_BOOL:
- if (sizeof(bool) == sizeof(char)) {
- dst->uchar = RB_TEST(*src);
- } else if (sizeof(bool) == sizeof(short)) {
- dst->ushort = RB_TEST(*src);
- } else if (sizeof(bool) == sizeof(int)) {
- dst->uint = RB_TEST(*src);
- } else if (sizeof(bool) == sizeof(long)) {
- dst->ulong = RB_TEST(*src);
- } else {
- rb_raise(rb_eNotImpError, "bool isn't supported: %u",
- (unsigned int)sizeof(bool));
- }
- break;
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
- break;
}
}
@@ -354,19 +314,6 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
else {
return Qnil;
}
- case TYPE_BOOL:
- if (sizeof(bool) == sizeof(char)) {
- return CBOOL2RBBOOL((unsigned char)retval.fffi_arg);
- } else if (sizeof(bool) == sizeof(short)) {
- return CBOOL2RBBOOL((unsigned short)retval.fffi_arg);
- } else if (sizeof(bool) == sizeof(int)) {
- return CBOOL2RBBOOL((unsigned int)retval.fffi_arg);
- } else if (sizeof(bool) == sizeof(long)) {
- return CBOOL2RBBOOL(retval.ulong);
- } else {
- rb_raise(rb_eNotImpError, "bool isn't supported: %u",
- (unsigned int)sizeof(bool));
- }
default:
rb_raise(rb_eRuntimeError, "unknown type %d", type);
}
diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h
index 7a1e928d56..c7c12a9234 100644
--- a/ext/fiddle/conversions.h
+++ b/ext/fiddle/conversions.h
@@ -50,6 +50,4 @@ VALUE generic_to_value(VALUE rettype, fiddle_generic retval);
# define NUM2PTR(x) ((void*)(NUM2ULL(x)))
#endif
-#define CBOOL2RBBOOL(cbool) ((cbool) ? RUBY_Qtrue : RUBY_Qfalse)
-
#endif
diff --git a/ext/fiddle/depend b/ext/fiddle/depend
index 561785275e..d6a053f05b 100644
--- a/ext/fiddle/depend
+++ b/ext/fiddle/depend
@@ -105,7 +105,6 @@ closure.o: $(hdrdir)/ruby/internal/attr/noexcept.h
closure.o: $(hdrdir)/ruby/internal/attr/noinline.h
closure.o: $(hdrdir)/ruby/internal/attr/nonnull.h
closure.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-closure.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
closure.o: $(hdrdir)/ruby/internal/attr/pure.h
closure.o: $(hdrdir)/ruby/internal/attr/restrict.h
closure.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -165,6 +164,7 @@ closure.o: $(hdrdir)/ruby/internal/intern/enumerator.h
closure.o: $(hdrdir)/ruby/internal/intern/error.h
closure.o: $(hdrdir)/ruby/internal/intern/eval.h
closure.o: $(hdrdir)/ruby/internal/intern/file.h
+closure.o: $(hdrdir)/ruby/internal/intern/gc.h
closure.o: $(hdrdir)/ruby/internal/intern/hash.h
closure.o: $(hdrdir)/ruby/internal/intern/io.h
closure.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -195,6 +195,7 @@ closure.o: $(hdrdir)/ruby/internal/memory.h
closure.o: $(hdrdir)/ruby/internal/method.h
closure.o: $(hdrdir)/ruby/internal/module.h
closure.o: $(hdrdir)/ruby/internal/newobj.h
+closure.o: $(hdrdir)/ruby/internal/rgengc.h
closure.o: $(hdrdir)/ruby/internal/scan_args.h
closure.o: $(hdrdir)/ruby/internal/special_consts.h
closure.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -269,7 +270,6 @@ conversions.o: $(hdrdir)/ruby/internal/attr/noexcept.h
conversions.o: $(hdrdir)/ruby/internal/attr/noinline.h
conversions.o: $(hdrdir)/ruby/internal/attr/nonnull.h
conversions.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-conversions.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
conversions.o: $(hdrdir)/ruby/internal/attr/pure.h
conversions.o: $(hdrdir)/ruby/internal/attr/restrict.h
conversions.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -329,6 +329,7 @@ conversions.o: $(hdrdir)/ruby/internal/intern/enumerator.h
conversions.o: $(hdrdir)/ruby/internal/intern/error.h
conversions.o: $(hdrdir)/ruby/internal/intern/eval.h
conversions.o: $(hdrdir)/ruby/internal/intern/file.h
+conversions.o: $(hdrdir)/ruby/internal/intern/gc.h
conversions.o: $(hdrdir)/ruby/internal/intern/hash.h
conversions.o: $(hdrdir)/ruby/internal/intern/io.h
conversions.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -359,6 +360,7 @@ conversions.o: $(hdrdir)/ruby/internal/memory.h
conversions.o: $(hdrdir)/ruby/internal/method.h
conversions.o: $(hdrdir)/ruby/internal/module.h
conversions.o: $(hdrdir)/ruby/internal/newobj.h
+conversions.o: $(hdrdir)/ruby/internal/rgengc.h
conversions.o: $(hdrdir)/ruby/internal/scan_args.h
conversions.o: $(hdrdir)/ruby/internal/special_consts.h
conversions.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -432,7 +434,6 @@ fiddle.o: $(hdrdir)/ruby/internal/attr/noexcept.h
fiddle.o: $(hdrdir)/ruby/internal/attr/noinline.h
fiddle.o: $(hdrdir)/ruby/internal/attr/nonnull.h
fiddle.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-fiddle.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
fiddle.o: $(hdrdir)/ruby/internal/attr/pure.h
fiddle.o: $(hdrdir)/ruby/internal/attr/restrict.h
fiddle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -492,6 +493,7 @@ fiddle.o: $(hdrdir)/ruby/internal/intern/enumerator.h
fiddle.o: $(hdrdir)/ruby/internal/intern/error.h
fiddle.o: $(hdrdir)/ruby/internal/intern/eval.h
fiddle.o: $(hdrdir)/ruby/internal/intern/file.h
+fiddle.o: $(hdrdir)/ruby/internal/intern/gc.h
fiddle.o: $(hdrdir)/ruby/internal/intern/hash.h
fiddle.o: $(hdrdir)/ruby/internal/intern/io.h
fiddle.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -522,6 +524,7 @@ fiddle.o: $(hdrdir)/ruby/internal/memory.h
fiddle.o: $(hdrdir)/ruby/internal/method.h
fiddle.o: $(hdrdir)/ruby/internal/module.h
fiddle.o: $(hdrdir)/ruby/internal/newobj.h
+fiddle.o: $(hdrdir)/ruby/internal/rgengc.h
fiddle.o: $(hdrdir)/ruby/internal/scan_args.h
fiddle.o: $(hdrdir)/ruby/internal/special_consts.h
fiddle.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -595,7 +598,6 @@ function.o: $(hdrdir)/ruby/internal/attr/noexcept.h
function.o: $(hdrdir)/ruby/internal/attr/noinline.h
function.o: $(hdrdir)/ruby/internal/attr/nonnull.h
function.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-function.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
function.o: $(hdrdir)/ruby/internal/attr/pure.h
function.o: $(hdrdir)/ruby/internal/attr/restrict.h
function.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -655,6 +657,7 @@ function.o: $(hdrdir)/ruby/internal/intern/enumerator.h
function.o: $(hdrdir)/ruby/internal/intern/error.h
function.o: $(hdrdir)/ruby/internal/intern/eval.h
function.o: $(hdrdir)/ruby/internal/intern/file.h
+function.o: $(hdrdir)/ruby/internal/intern/gc.h
function.o: $(hdrdir)/ruby/internal/intern/hash.h
function.o: $(hdrdir)/ruby/internal/intern/io.h
function.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -685,6 +688,7 @@ function.o: $(hdrdir)/ruby/internal/memory.h
function.o: $(hdrdir)/ruby/internal/method.h
function.o: $(hdrdir)/ruby/internal/module.h
function.o: $(hdrdir)/ruby/internal/newobj.h
+function.o: $(hdrdir)/ruby/internal/rgengc.h
function.o: $(hdrdir)/ruby/internal/scan_args.h
function.o: $(hdrdir)/ruby/internal/special_consts.h
function.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -759,7 +763,6 @@ handle.o: $(hdrdir)/ruby/internal/attr/noexcept.h
handle.o: $(hdrdir)/ruby/internal/attr/noinline.h
handle.o: $(hdrdir)/ruby/internal/attr/nonnull.h
handle.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-handle.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
handle.o: $(hdrdir)/ruby/internal/attr/pure.h
handle.o: $(hdrdir)/ruby/internal/attr/restrict.h
handle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -819,6 +822,7 @@ handle.o: $(hdrdir)/ruby/internal/intern/enumerator.h
handle.o: $(hdrdir)/ruby/internal/intern/error.h
handle.o: $(hdrdir)/ruby/internal/intern/eval.h
handle.o: $(hdrdir)/ruby/internal/intern/file.h
+handle.o: $(hdrdir)/ruby/internal/intern/gc.h
handle.o: $(hdrdir)/ruby/internal/intern/hash.h
handle.o: $(hdrdir)/ruby/internal/intern/io.h
handle.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -849,6 +853,7 @@ handle.o: $(hdrdir)/ruby/internal/memory.h
handle.o: $(hdrdir)/ruby/internal/method.h
handle.o: $(hdrdir)/ruby/internal/module.h
handle.o: $(hdrdir)/ruby/internal/newobj.h
+handle.o: $(hdrdir)/ruby/internal/rgengc.h
handle.o: $(hdrdir)/ruby/internal/scan_args.h
handle.o: $(hdrdir)/ruby/internal/special_consts.h
handle.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -923,7 +928,6 @@ memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h
memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h
memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h
memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -992,6 +996,7 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h
memory_view.o: $(hdrdir)/ruby/internal/intern/error.h
memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h
memory_view.o: $(hdrdir)/ruby/internal/intern/file.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h
memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h
memory_view.o: $(hdrdir)/ruby/internal/intern/io.h
memory_view.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1022,6 +1027,7 @@ memory_view.o: $(hdrdir)/ruby/internal/memory.h
memory_view.o: $(hdrdir)/ruby/internal/method.h
memory_view.o: $(hdrdir)/ruby/internal/module.h
memory_view.o: $(hdrdir)/ruby/internal/newobj.h
+memory_view.o: $(hdrdir)/ruby/internal/rgengc.h
memory_view.o: $(hdrdir)/ruby/internal/scan_args.h
memory_view.o: $(hdrdir)/ruby/internal/special_consts.h
memory_view.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1098,7 +1104,6 @@ pinned.o: $(hdrdir)/ruby/internal/attr/noexcept.h
pinned.o: $(hdrdir)/ruby/internal/attr/noinline.h
pinned.o: $(hdrdir)/ruby/internal/attr/nonnull.h
pinned.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-pinned.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
pinned.o: $(hdrdir)/ruby/internal/attr/pure.h
pinned.o: $(hdrdir)/ruby/internal/attr/restrict.h
pinned.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1158,6 +1163,7 @@ pinned.o: $(hdrdir)/ruby/internal/intern/enumerator.h
pinned.o: $(hdrdir)/ruby/internal/intern/error.h
pinned.o: $(hdrdir)/ruby/internal/intern/eval.h
pinned.o: $(hdrdir)/ruby/internal/intern/file.h
+pinned.o: $(hdrdir)/ruby/internal/intern/gc.h
pinned.o: $(hdrdir)/ruby/internal/intern/hash.h
pinned.o: $(hdrdir)/ruby/internal/intern/io.h
pinned.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1188,6 +1194,7 @@ pinned.o: $(hdrdir)/ruby/internal/memory.h
pinned.o: $(hdrdir)/ruby/internal/method.h
pinned.o: $(hdrdir)/ruby/internal/module.h
pinned.o: $(hdrdir)/ruby/internal/newobj.h
+pinned.o: $(hdrdir)/ruby/internal/rgengc.h
pinned.o: $(hdrdir)/ruby/internal/scan_args.h
pinned.o: $(hdrdir)/ruby/internal/special_consts.h
pinned.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1262,7 +1269,6 @@ pointer.o: $(hdrdir)/ruby/internal/attr/noexcept.h
pointer.o: $(hdrdir)/ruby/internal/attr/noinline.h
pointer.o: $(hdrdir)/ruby/internal/attr/nonnull.h
pointer.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-pointer.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
pointer.o: $(hdrdir)/ruby/internal/attr/pure.h
pointer.o: $(hdrdir)/ruby/internal/attr/restrict.h
pointer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1331,6 +1337,7 @@ pointer.o: $(hdrdir)/ruby/internal/intern/enumerator.h
pointer.o: $(hdrdir)/ruby/internal/intern/error.h
pointer.o: $(hdrdir)/ruby/internal/intern/eval.h
pointer.o: $(hdrdir)/ruby/internal/intern/file.h
+pointer.o: $(hdrdir)/ruby/internal/intern/gc.h
pointer.o: $(hdrdir)/ruby/internal/intern/hash.h
pointer.o: $(hdrdir)/ruby/internal/intern/io.h
pointer.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1361,6 +1368,7 @@ pointer.o: $(hdrdir)/ruby/internal/memory.h
pointer.o: $(hdrdir)/ruby/internal/method.h
pointer.o: $(hdrdir)/ruby/internal/module.h
pointer.o: $(hdrdir)/ruby/internal/newobj.h
+pointer.o: $(hdrdir)/ruby/internal/rgengc.h
pointer.o: $(hdrdir)/ruby/internal/scan_args.h
pointer.o: $(hdrdir)/ruby/internal/special_consts.h
pointer.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb
index 2d85b3eea5..cf8b5223bb 100644
--- a/ext/fiddle/extconf.rb
+++ b/ext/fiddle/extconf.rb
@@ -63,11 +63,6 @@ unless bundle
end
if have_ffi_header && (have_library('ffi') || have_library('libffi'))
have_libffi = true
- checking_for("undefined FFI_GO_CLOSURES is used") do
- if egrep_cpp(/warning: 'FFI_GO_CLOSURES' is not defined/, cpp_include(ffi_header), "2>&1")
- $defs.push('-DFFI_GO_CLOSURES=0')
- end
- end
end
end
diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c
index f420d9fa3b..c06cd5634a 100644
--- a/ext/fiddle/fiddle.c
+++ b/ext/fiddle/fiddle.c
@@ -1,5 +1,3 @@
-#include <stdbool.h>
-
#include <fiddle.h>
VALUE mFiddle;
@@ -60,16 +58,18 @@ rb_fiddle_free(VALUE self, VALUE addr)
/*
* call-seq: Fiddle.dlunwrap(addr)
*
- * Returns the Ruby object stored at the memory address +addr+
+ * Returns the hexadecimal representation of a memory pointer address +addr+
*
* Example:
*
- * x = Object.new
- * # => #<Object:0x0000000107c7d870>
- * Fiddle.dlwrap(x)
- * # => 4425504880
- * Fiddle.dlunwrap(_)
- * # => #<Object:0x0000000107c7d870>
+ * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
+ * => #<Fiddle::Handle:0x00000001342460>
+ *
+ * lib['strcpy'].to_s(16)
+ * => "7f59de6dd240"
+ *
+ * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
+ * => "7f59de6dd240"
*/
VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
@@ -80,22 +80,15 @@ rb_fiddle_ptr2value(VALUE self, VALUE addr)
/*
* call-seq: Fiddle.dlwrap(val)
*
- * Returns the memory address of the Ruby object stored at +val+
+ * Returns a memory pointer of a function's hexadecimal address location +val+
*
* Example:
*
- * x = Object.new
- * # => #<Object:0x0000000107c7d870>
- * Fiddle.dlwrap(x)
- * # => 4425504880
- *
- * In the case +val+ is not a heap allocated object, this method will return
- * the tagged pointer value.
+ * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
+ * => #<Fiddle::Handle:0x00000001342460>
*
- * Example:
- *
- * Fiddle.dlwrap(123)
- * # => 247
+ * Fiddle.dlwrap(lib['strcpy'].to_s(16))
+ * => 25522520
*/
static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
@@ -359,12 +352,6 @@ Init_fiddle(void)
*/
rb_define_const(mFiddleTypes, "UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
- /* Document-const: Fiddle::Types::BOOL
- *
- * C type - bool
- */
- rb_define_const(mFiddleTypes, "BOOL" , INT2NUM(TYPE_BOOL));
-
/* Document-const: ALIGN_VOIDP
*
* The alignment size of a void*
@@ -469,12 +456,6 @@ Init_fiddle(void)
*/
rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
- /* Document-const: ALIGN_BOOL
- *
- * The alignment size of a bool
- */
- rb_define_const(mFiddle, "ALIGN_BOOL", INT2NUM(ALIGN_OF(bool)));
-
/* Document-const: WINDOWS
*
* Returns a boolean regarding whether the host is WIN32
@@ -649,12 +630,6 @@ Init_fiddle(void)
*/
rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
- /* Document-const: SIZEOF_BOOL
- *
- * size of a bool
- */
- rb_define_const(mFiddle, "SIZEOF_BOOL", INT2NUM(sizeof(bool)));
-
/* Document-const: RUBY_FREE
*
* Address of the ruby_xfree() function
diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h
index 348baa9ab9..10eb9ceedb 100644
--- a/ext/fiddle/fiddle.h
+++ b/ext/fiddle/fiddle.h
@@ -118,7 +118,7 @@
#define TYPE_UINT -TYPE_INT
#define TYPE_LONG 5
#define TYPE_ULONG -TYPE_LONG
-#ifdef HAVE_LONG_LONG
+#if HAVE_LONG_LONG
#define TYPE_LONG_LONG 6
#define TYPE_ULONG_LONG -TYPE_LONG_LONG
#endif
@@ -126,7 +126,6 @@
#define TYPE_DOUBLE 8
#define TYPE_VARIADIC 9
#define TYPE_CONST_STRING 10
-#define TYPE_BOOL 11
#define TYPE_INT8_T TYPE_CHAR
#define TYPE_UINT8_T -TYPE_INT8_T
@@ -197,20 +196,7 @@
#endif
#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
-/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
- <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
- clang versions < 8.0.0 have the same bug. */
-#if defined(HAVE__ALIGNOF)
-# /* Autoconf detected availability of a sane `_Alignof()`. */
-# define ALIGN_OF(type) RB_GNUC_EXTENSION(_Alignof(type))
-#elif (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112 \
- || (defined(__GNUC__) && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
- && !defined(__clang__)) \
- || (defined(__clang__) && __clang_major__ < 8))
-# define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
-#else
-# define ALIGN_OF(type) _Alignof(type)
-#endif
+#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
#define ALIGN_VOIDP ALIGN_OF(void*)
#define ALIGN_CHAR ALIGN_OF(char)
diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c
index 5469e09e37..274d181d17 100644
--- a/ext/fiddle/function.c
+++ b/ext/fiddle/function.c
@@ -53,13 +53,8 @@ function_memsize(const void *p)
}
const rb_data_type_t function_data_type = {
- .wrap_struct_name = "fiddle/function",
- .function = {
- .dmark = 0,
- .dfree = deallocate,
- .dsize = function_memsize
- },
- .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ "fiddle/function",
+ {0, deallocate, function_memsize,},
};
static VALUE
diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c
index 8ba416952a..ae8cc3a581 100644
--- a/ext/fiddle/handle.c
+++ b/ext/fiddle/handle.c
@@ -50,13 +50,8 @@ fiddle_handle_memsize(const void *ptr)
}
static const rb_data_type_t fiddle_handle_data_type = {
- .wrap_struct_name = "fiddle/handle",
- .function = {
- .dmark = 0,
- .dfree = fiddle_handle_free,
- .dsize = fiddle_handle_memsize
- },
- .flags = RUBY_TYPED_WB_PROTECTED,
+ "fiddle/handle",
+ {0, fiddle_handle_free, fiddle_handle_memsize,},
};
/*
diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb
index 264ca166dd..9a70402953 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -165,30 +165,18 @@ module Fiddle
raise(RuntimeError, "unsupported type: #{ty}")
end
return TYPE_ULONG_LONG
- when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/,
- /\Aunsigned\s+int\s+long(?:\s+\w+)?\z/,
- /\Along(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
- /\Aint\s+unsigned\s+long(?:\s+\w+)?\z/,
- /\A(?:int\s+)?long\s+unsigned(?:\s+\w+)?\z/
- return TYPE_ULONG
- when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/,
- /\A(?:signed\s+)?int\s+long(?:\s+\w+)?\z/,
- /\Along(?:\s+int)?\s+signed(?:\s+\w+)?\z/
+ when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/
return TYPE_LONG
- when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/,
- /\Aunsigned\s+int\s+short(?:\s+\w+)?\z/,
- /\Ashort(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
- /\Aint\s+unsigned\s+short(?:\s+\w+)?\z/,
- /\A(?:int\s+)?short\s+unsigned(?:\s+\w+)?\z/
- return TYPE_USHORT
- when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/,
- /\A(?:signed\s+)?int\s+short(?:\s+\w+)?\z/,
- /\Aint\s+(?:signed\s+)?short(?:\s+\w+)?\z/
- return TYPE_SHORT
+ when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/
+ return TYPE_ULONG
when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
return TYPE_INT
when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
return TYPE_UINT
+ when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
+ return TYPE_SHORT
+ when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
+ return TYPE_USHORT
when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
return TYPE_CHAR
when /\Aunsigned\s+char(?:\s+\w+)?\z/
@@ -247,8 +235,6 @@ module Fiddle
return TYPE_INTPTR_T
when /\Auintptr_t(?:\s+\w+)?\z/
return TYPE_UINTPTR_T
- when "bool"
- return TYPE_BOOL
when /\*/, /\[[\s\d]*\]/
return TYPE_VOIDP
when "..."
diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb
index 050708fb96..09ffcef544 100644
--- a/ext/fiddle/lib/fiddle/import.rb
+++ b/ext/fiddle/lib/fiddle/import.rb
@@ -119,8 +119,6 @@ module Fiddle
return SIZEOF_VOIDP
when TYPE_CONST_STRING
return SIZEOF_CONST_STRING
- when TYPE_BOOL
- return SIZEOF_BOOL
else
if defined?(TYPE_LONG_LONG) and
ty == TYPE_LONG_LONG
diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb
index 81088f402b..545b985d50 100644
--- a/ext/fiddle/lib/fiddle/pack.rb
+++ b/ext/fiddle/lib/fiddle/pack.rb
@@ -15,7 +15,6 @@ module Fiddle
TYPE_USHORT => ALIGN_SHORT,
TYPE_UINT => ALIGN_INT,
TYPE_ULONG => ALIGN_LONG,
- TYPE_BOOL => ALIGN_BOOL,
}
PACK_MAP = {
@@ -31,16 +30,6 @@ module Fiddle
TYPE_UINT => "I!",
TYPE_ULONG => "L!",
}
- case SIZEOF_BOOL
- when SIZEOF_CHAR
- PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UCHAR]
- when SIZEOF_SHORT
- PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_USHORT]
- when SIZEOF_INT
- PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UINT]
- when SIZEOF_LONG
- PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_ULONG]
- end
SIZE_MAP = {
TYPE_VOIDP => SIZEOF_VOIDP,
@@ -54,7 +43,6 @@ module Fiddle
TYPE_USHORT => SIZEOF_SHORT,
TYPE_UINT => SIZEOF_INT,
TYPE_ULONG => SIZEOF_LONG,
- TYPE_BOOL => SIZEOF_BOOL,
}
if defined?(TYPE_LONG_LONG)
ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG
diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb
index 5f0b2e951e..01fec1c206 100644
--- a/ext/fiddle/lib/fiddle/value.rb
+++ b/ext/fiddle/lib/fiddle/value.rb
@@ -6,17 +6,17 @@ module Fiddle
def unsigned_value(val, ty)
case ty.abs
when TYPE_CHAR
- [val].pack("c").unpack1("C")
+ [val].pack("c").unpack("C")[0]
when TYPE_SHORT
- [val].pack("s!").unpack1("S!")
+ [val].pack("s!").unpack("S!")[0]
when TYPE_INT
- [val].pack("i!").unpack1("I!")
+ [val].pack("i!").unpack("I!")[0]
when TYPE_LONG
- [val].pack("l!").unpack1("L!")
+ [val].pack("l!").unpack("L!")[0]
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
- [val].pack("q").unpack1("Q")
+ [val].pack("q").unpack("Q")[0]
else
val
end
@@ -26,17 +26,17 @@ module Fiddle
def signed_value(val, ty)
case ty.abs
when TYPE_CHAR
- [val].pack("C").unpack1("c")
+ [val].pack("C").unpack("c")[0]
when TYPE_SHORT
- [val].pack("S!").unpack1("s!")
+ [val].pack("S!").unpack("s!")[0]
when TYPE_INT
- [val].pack("I!").unpack1("i!")
+ [val].pack("I!").unpack("i!")[0]
when TYPE_LONG
- [val].pack("L!").unpack1("l!")
+ [val].pack("L!").unpack("l!")[0]
else
if defined?(TYPE_LONG_LONG) and
ty.abs == TYPE_LONG_LONG
- [val].pack("Q").unpack1("q")
+ [val].pack("Q").unpack("q")[0]
else
val
end
@@ -80,11 +80,11 @@ module Fiddle
else
case SIZEOF_VOIDP
when SIZEOF_LONG
- return [arg].pack("p").unpack1("l!")
+ return [arg].pack("p").unpack("l!")[0]
else
if defined?(SIZEOF_LONG_LONG) and
SIZEOF_VOIDP == SIZEOF_LONG_LONG
- return [arg].pack("p").unpack1("q")
+ return [arg].pack("p").unpack("q")[0]
else
raise(RuntimeError, "sizeof(void*)?")
end
@@ -102,8 +102,10 @@ module Fiddle
return val.unpack('C*')
end
end
+ return arg
+ else
+ return arg
end
- return arg
else
if( arg.respond_to?(:to_ptr) )
return arg.to_ptr.to_i
diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb
index 706d98a7b5..719dc62e37 100644
--- a/ext/fiddle/lib/fiddle/version.rb
+++ b/ext/fiddle/lib/fiddle/version.rb
@@ -1,3 +1,3 @@
module Fiddle
- VERSION = "1.1.2"
+ VERSION = "1.1.1"
end
diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c
index 1b7d7a69f6..15107e3862 100644
--- a/ext/fiddle/pointer.c
+++ b/ext/fiddle/pointer.c
@@ -88,13 +88,8 @@ fiddle_ptr_memsize(const void *ptr)
}
static const rb_data_type_t fiddle_ptr_data_type = {
- .wrap_struct_name = "fiddle/pointer",
- .function = {
- .dmark = fiddle_ptr_mark,
- .dfree = fiddle_ptr_free,
- .dsize = fiddle_ptr_memsize,
- },
- .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
+ "fiddle/pointer",
+ {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
};
#ifdef HAVE_RUBY_MEMORY_VIEW_H
@@ -140,8 +135,8 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wra
data->free = func;
data->freed = false;
data->size = size;
- RB_OBJ_WRITE(val, &data->wrap[0], wrap0);
- RB_OBJ_WRITE(val, &data->wrap[1], wrap1);
+ data->wrap[0] = wrap0;
+ data->wrap[1] = wrap1;
return val;
}
@@ -240,8 +235,8 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
(*(data->free))(data->ptr);
}
- RB_OBJ_WRITE(self, &data->wrap[0], wrap);
- RB_OBJ_WRITE(self, &data->wrap[1], funcwrap);
+ data->wrap[0] = wrap;
+ data->wrap[1] = funcwrap;
data->ptr = p;
data->size = s;
data->free = f;
@@ -319,7 +314,7 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
}
obj = rb_fiddle_ptr_malloc(klass, s,f);
- if (wrap) RB_OBJ_WRITE(obj, &RPTR_DATA(obj)->wrap[1], wrap);
+ if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
if (rb_block_given_p()) {
if (!f) {
@@ -800,37 +795,10 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
if (num == val) wrap = 0;
ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
}
- if (wrap) RB_OBJ_WRITE(ptr, &RPTR_DATA(ptr)->wrap[0], wrap);
+ if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
return ptr;
}
-/*
- * call-seq:
- * Fiddle::Pointer.read(address, len) => string
- *
- * Or read the memory at address +address+ with length +len+ and return a
- * string with that memory
- */
-
-static VALUE
-rb_fiddle_ptr_read_mem(VALUE klass, VALUE address, VALUE len)
-{
- return rb_str_new((char *)NUM2PTR(address), NUM2ULONG(len));
-}
-
-/*
- * call-seq:
- * Fiddle::Pointer.write(address, str)
- *
- * Write bytes in +str+ to the location pointed to by +address+.
- */
-static VALUE
-rb_fiddle_ptr_write_mem(VALUE klass, VALUE addr, VALUE str)
-{
- memcpy(NUM2PTR(addr), StringValuePtr(str), RSTRING_LEN(str));
- return str;
-}
-
void
Init_fiddle_pointer(void)
{
@@ -847,8 +815,6 @@ Init_fiddle_pointer(void)
rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1);
rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1);
rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1);
- rb_define_singleton_method(rb_cPointer, "read", rb_fiddle_ptr_read_mem, 2);
- rb_define_singleton_method(rb_cPointer, "write", rb_fiddle_ptr_write_mem, 2);
rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
diff --git a/ext/fiddle/win32/libffi-config.rb b/ext/fiddle/win32/libffi-config.rb
index 8e8069a943..985fc29d36 100755
--- a/ext/fiddle/win32/libffi-config.rb
+++ b/ext/fiddle/win32/libffi-config.rb
@@ -23,7 +23,7 @@ until ARGV.empty?
end
end
-File.foreach("#{srcdir}/configure.ac") do |line|
+IO.foreach("#{srcdir}/configure.ac") do |line|
if /^AC_INIT\((.*)\)/ =~ line
version = $1.split(/,\s*/)[1]
version.gsub!(/\A\[|\]\z/, '')
@@ -38,11 +38,11 @@ conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])
FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true)
-hdr = File.binread("#{srcdir}/include/ffi.h.in")
+hdr = IO.binread("#{srcdir}/include/ffi.h.in")
hdr.gsub!(/@(\w+)@/) {conf[$1] || $&}
hdr.gsub!(/^(#if\s+)@\w+@/, '\10')
-File.binwrite("#{builddir}/include/ffi.h", hdr)
+IO.binwrite("#{builddir}/include/ffi.h", hdr)
-mk = File.binread("#{basedir}/libffi.mk.tmpl")
+mk = IO.binread("#{basedir}/libffi.mk.tmpl")
mk.gsub!(/@(\w+)@/) {conf[$1] || $&}
-File.binwrite("Makefile", mk)
+IO.binwrite("Makefile", mk)
diff --git a/ext/io/console/.document b/ext/io/console/.document
deleted file mode 100644
index 945a377256..0000000000
--- a/ext/io/console/.document
+++ /dev/null
@@ -1,2 +0,0 @@
-console.c
-lib/size.rb
diff --git a/ext/io/console/console.c b/ext/io/console/console.c
index 78eb11a209..21454a73fa 100644
--- a/ext/io/console/console.c
+++ b/ext/io/console/console.c
@@ -76,7 +76,9 @@ getattr(int fd, conmode *t)
#endif
static ID id_getc, id_console, id_close;
-static ID id_gets, id_flush, id_chomp_bang;
+#if ENABLE_IO_GETPASS
+static ID id_gets, id_chomp_bang;
+#endif
#if defined HAVE_RUBY_FIBER_SCHEDULER_H
# include "ruby/fiber/scheduler.h"
@@ -85,41 +87,7 @@ extern VALUE rb_scheduler_timeout(struct timeval *timeout);
# define rb_fiber_scheduler_make_timeout rb_scheduler_timeout
#endif
-#ifndef HAVE_RB_IO_DESCRIPTOR
-static int
-io_descriptor_fallback(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- return fptr->fd;
-}
-#define rb_io_descriptor io_descriptor_fallback
-#endif
-
-#ifndef HAVE_RB_IO_PATH
-static VALUE
-io_path_fallback(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- return fptr->pathv;
-}
-#define rb_io_path io_path_fallback
-#endif
-
-#ifndef HAVE_RB_IO_GET_WRITE_IO
-static VALUE
-io_get_write_io_fallback(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- VALUE wio = fptr->tied_io_for_writing;
- return wio ? wio : io;
-}
-#define rb_io_get_write_io io_get_write_io_fallback
-#endif
-
-#define sys_fail(io) rb_sys_fail_str(rb_io_path(io))
+#define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv)
#ifndef HAVE_RB_F_SEND
#ifndef RB_PASS_CALLED_KEYWORDS
@@ -325,21 +293,33 @@ set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg)
return setattr(fd, &r);
}
-#define GetReadFD(io) rb_io_descriptor(io)
-#define GetWriteFD(io) rb_io_descriptor(rb_io_get_write_io(io))
+#define GetReadFD(fptr) ((fptr)->fd)
+
+static inline int
+get_write_fd(const rb_io_t *fptr)
+{
+ VALUE wio = fptr->tied_io_for_writing;
+ rb_io_t *ofptr;
+ if (!wio) return fptr->fd;
+ GetOpenFile(wio, ofptr);
+ return ofptr->fd;
+}
+#define GetWriteFD(fptr) get_write_fd(fptr)
#define FD_PER_IO 2
static VALUE
ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg)
{
+ rb_io_t *fptr;
int status = -1;
int error = 0;
int fd[FD_PER_IO];
conmode t[FD_PER_IO];
VALUE result = Qnil;
- fd[0] = GetReadFD(io);
+ GetOpenFile(io, fptr);
+ fd[0] = GetReadFD(fptr);
if (fd[0] != -1) {
if (set_ttymode(fd[0], t+0, setter, arg)) {
status = 0;
@@ -349,7 +329,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo
fd[0] = -1;
}
}
- fd[1] = GetWriteFD(io);
+ fd[1] = GetWriteFD(fptr);
if (fd[1] != -1 && fd[1] != fd[0]) {
if (set_ttymode(fd[1], t+1, setter, arg)) {
status = 0;
@@ -362,13 +342,14 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo
if (status == 0) {
result = rb_protect(func, farg, &status);
}
- if (fd[0] != -1 && fd[0] == GetReadFD(io)) {
+ GetOpenFile(io, fptr);
+ if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
if (!setattr(fd[0], t+0)) {
error = errno;
status = -1;
}
}
- if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(io)) {
+ if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) {
if (!setattr(fd[1], t+1)) {
error = errno;
status = -1;
@@ -454,11 +435,15 @@ static VALUE
console_set_raw(int argc, VALUE *argv, VALUE io)
{
conmode t;
+ rb_io_t *fptr;
+ int fd;
rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
- int fd = GetReadFD(io);
- if (!getattr(fd, &t)) sys_fail(io);
+
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
set_rawmode(&t, optp);
- if (!setattr(fd, &t)) sys_fail(io);
+ if (!setattr(fd, &t)) sys_fail_fptr(fptr);
return io;
}
@@ -494,10 +479,14 @@ static VALUE
console_set_cooked(VALUE io)
{
conmode t;
- int fd = GetReadFD(io);
- if (!getattr(fd, &t)) sys_fail(io);
+ rb_io_t *fptr;
+ int fd;
+
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
set_cookedmode(&t, NULL);
- if (!setattr(fd, &t)) sys_fail(io);
+ if (!setattr(fd, &t)) sys_fail_fptr(fptr);
return io;
}
@@ -649,17 +638,17 @@ static VALUE
console_set_echo(VALUE io, VALUE f)
{
conmode t;
- int fd = GetReadFD(io);
-
- if (!getattr(fd, &t)) sys_fail(io);
+ rb_io_t *fptr;
+ int fd;
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
if (RTEST(f))
- set_echo(&t, NULL);
+ set_echo(&t, NULL);
else
- set_noecho(&t, NULL);
-
- if (!setattr(fd, &t)) sys_fail(io);
-
+ set_noecho(&t, NULL);
+ if (!setattr(fd, &t)) sys_fail_fptr(fptr);
return io;
}
@@ -675,9 +664,12 @@ static VALUE
console_echo_p(VALUE io)
{
conmode t;
- int fd = GetReadFD(io);
+ rb_io_t *fptr;
+ int fd;
- if (!getattr(fd, &t)) sys_fail(io);
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
return echo_p(&t) ? Qtrue : Qfalse;
}
@@ -756,9 +748,12 @@ static VALUE
console_conmode_get(VALUE io)
{
conmode t;
- int fd = GetReadFD(io);
+ rb_io_t *fptr;
+ int fd;
- if (!getattr(fd, &t)) sys_fail(io);
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!getattr(fd, &t)) sys_fail_fptr(fptr);
return conmode_new(cConmode, &t);
}
@@ -775,12 +770,14 @@ static VALUE
console_conmode_set(VALUE io, VALUE mode)
{
conmode *t, r;
- int fd = GetReadFD(io);
+ rb_io_t *fptr;
+ int fd;
TypedData_Get_Struct(mode, conmode, &conmode_type, t);
r = *t;
-
- if (!setattr(fd, &r)) sys_fail(io);
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
+ if (!setattr(fd, &r)) sys_fail_fptr(fptr);
return mode;
}
@@ -816,9 +813,13 @@ typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t;
static VALUE
console_winsize(VALUE io)
{
+ rb_io_t *fptr;
+ int fd;
rb_console_size_t ws;
- int fd = GetWriteFD(io);
- if (!getwinsize(fd, &ws)) sys_fail(io);
+
+ GetOpenFile(io, fptr);
+ fd = GetWriteFD(fptr);
+ if (!getwinsize(fd, &ws)) sys_fail_fptr(fptr);
return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
}
@@ -834,6 +835,7 @@ console_winsize(VALUE io)
static VALUE
console_set_winsize(VALUE io, VALUE size)
{
+ rb_io_t *fptr;
rb_console_size_t ws;
#if defined _WIN32
HANDLE wh;
@@ -842,17 +844,20 @@ console_set_winsize(VALUE io, VALUE size)
#endif
VALUE row, col, xpixel, ypixel;
const VALUE *sz;
- long sizelen;
int fd;
+ long sizelen;
+ GetOpenFile(io, fptr);
size = rb_Array(size);
if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) {
- rb_raise(rb_eArgError, "wrong number of arguments (given %ld, expected 2 or 4)", sizelen);
+ rb_raise(rb_eArgError,
+ "wrong number of arguments (given %ld, expected 2 or 4)",
+ sizelen);
}
sz = RARRAY_CONST_PTR(size);
row = sz[0], col = sz[1], xpixel = ypixel = Qnil;
if (sizelen == 4) xpixel = sz[2], ypixel = sz[3];
- fd = GetWriteFD(io);
+ fd = GetWriteFD(fptr);
#if defined TIOCSWINSZ
ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
@@ -861,7 +866,7 @@ console_set_winsize(VALUE io, VALUE size)
SET(xpixel);
SET(ypixel);
#undef SET
- if (!setwinsize(fd, &ws)) sys_fail(io);
+ if (!setwinsize(fd, &ws)) sys_fail_fptr(fptr);
#elif defined _WIN32
wh = (HANDLE)rb_w32_get_osfhandle(fd);
#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
@@ -899,10 +904,12 @@ console_set_winsize(VALUE io, VALUE size)
static VALUE
console_check_winsize_changed(VALUE io)
{
+ rb_io_t *fptr;
HANDLE h;
DWORD num;
- h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(io));
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr));
while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) {
INPUT_RECORD rec;
if (ReadConsoleInput(h, &rec, 1, &num)) {
@@ -928,11 +935,15 @@ console_check_winsize_changed(VALUE io)
static VALUE
console_iflush(VALUE io)
{
+ rb_io_t *fptr;
+ int fd;
+
+ GetOpenFile(io, fptr);
+ fd = GetReadFD(fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
- int fd = GetReadFD(io);
- if (tcflush(fd, TCIFLUSH)) sys_fail(io);
+ if (tcflush(fd, TCIFLUSH)) sys_fail_fptr(fptr);
#endif
-
+ (void)fd;
return io;
}
@@ -947,9 +958,13 @@ console_iflush(VALUE io)
static VALUE
console_oflush(VALUE io)
{
- int fd = GetWriteFD(io);
+ rb_io_t *fptr;
+ int fd;
+
+ GetOpenFile(io, fptr);
+ fd = GetWriteFD(fptr);
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
- if (tcflush(fd, TCOFLUSH)) sys_fail(io);
+ if (tcflush(fd, TCOFLUSH)) sys_fail_fptr(fptr);
#endif
(void)fd;
return io;
@@ -966,30 +981,40 @@ console_oflush(VALUE io)
static VALUE
console_ioflush(VALUE io)
{
+ rb_io_t *fptr;
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
- int fd1 = GetReadFD(io);
- int fd2 = GetWriteFD(io);
+ int fd1, fd2;
+#endif
+ GetOpenFile(io, fptr);
+#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
+ fd1 = GetReadFD(fptr);
+ fd2 = GetWriteFD(fptr);
if (fd2 != -1 && fd1 != fd2) {
- if (tcflush(fd1, TCIFLUSH)) sys_fail(io);
- if (tcflush(fd2, TCOFLUSH)) sys_fail(io);
+ if (tcflush(fd1, TCIFLUSH)) sys_fail_fptr(fptr);
+ if (tcflush(fd2, TCOFLUSH)) sys_fail_fptr(fptr);
}
else {
- if (tcflush(fd1, TCIOFLUSH)) sys_fail(io);
+ if (tcflush(fd1, TCIOFLUSH)) sys_fail_fptr(fptr);
}
#endif
-
return io;
}
static VALUE
console_beep(VALUE io)
{
+ rb_io_t *fptr;
+ int fd;
+
+ GetOpenFile(io, fptr);
+ fd = GetWriteFD(fptr);
#ifdef _WIN32
+ (void)fd;
MessageBeep(0);
#else
- int fd = GetWriteFD(io);
- if (write(fd, "\a", 1) < 0) sys_fail(io);
+ if (write(fd, "\a", 1) < 0)
+ sys_fail_fptr(fptr);
#endif
return io;
}
@@ -1010,6 +1035,79 @@ mode_in_range(VALUE val, int high, const char *modename)
}
#if defined _WIN32
+static VALUE
+console_goto(VALUE io, VALUE y, VALUE x)
+{
+ rb_io_t *fptr;
+ int fd;
+ COORD pos;
+
+ GetOpenFile(io, fptr);
+ fd = GetWriteFD(fptr);
+ pos.X = NUM2UINT(x);
+ pos.Y = NUM2UINT(y);
+ if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ return io;
+}
+
+static VALUE
+console_cursor_pos(VALUE io)
+{
+ rb_io_t *fptr;
+ int fd;
+ rb_console_size_t ws;
+
+ GetOpenFile(io, fptr);
+ fd = GetWriteFD(fptr);
+ if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
+}
+
+static VALUE
+console_move(VALUE io, int y, int x)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ pos->X += x;
+ pos->Y += y;
+ if (!SetConsoleCursorPosition(h, *pos)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ return io;
+}
+
+static VALUE
+console_goto_column(VALUE io, VALUE val)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ pos->X = NUM2INT(val);
+ if (!SetConsoleCursorPosition(h, *pos)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ return io;
+}
+
static void
constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
{
@@ -1020,12 +1118,86 @@ constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
}
static VALUE
+console_erase_line(VALUE io, VALUE val)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+ DWORD w;
+ int mode = mode_in_range(val, 2, "line erase");
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ w = winsize_col(&ws);
+ switch (mode) {
+ case 0: /* after cursor */
+ w -= pos->X;
+ break;
+ case 1: /* before *and* cursor */
+ w = pos->X + 1;
+ pos->X = 0;
+ break;
+ case 2: /* entire line */
+ pos->X = 0;
+ break;
+ }
+ constat_clear(h, ws.wAttributes, w, *pos);
+ return io;
+}
+
+static VALUE
+console_erase_screen(VALUE io, VALUE val)
+{
+ rb_io_t *fptr;
+ HANDLE h;
+ rb_console_size_t ws;
+ COORD *pos = &ws.dwCursorPosition;
+ DWORD w;
+ int mode = mode_in_range(val, 3, "screen erase");
+
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
+ if (!GetConsoleScreenBufferInfo(h, &ws)) {
+ rb_syserr_fail(LAST_ERROR, 0);
+ }
+ w = winsize_col(&ws);
+ switch (mode) {
+ case 0: /* erase after cursor */
+ w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
+ break;
+ case 1: /* erase before *and* cursor */
+ w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
+ pos->X = 0;
+ pos->Y = ws.srWindow.Top;
+ break;
+ case 2: /* erase entire screen */
+ w = (w * winsize_row(&ws));
+ pos->X = 0;
+ pos->Y = ws.srWindow.Top;
+ break;
+ case 3: /* erase entire screen */
+ w = (w * ws.dwSize.Y);
+ pos->X = 0;
+ pos->Y = 0;
+ break;
+ }
+ constat_clear(h, ws.wAttributes, w, *pos);
+ return io;
+}
+
+static VALUE
console_scroll(VALUE io, int line)
{
+ rb_io_t *fptr;
HANDLE h;
rb_console_size_t ws;
- h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
+ GetOpenFile(io, fptr);
+ h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
if (!GetConsoleScreenBufferInfo(h, &ws)) {
rb_syserr_fail(LAST_ERROR, 0);
}
@@ -1084,11 +1256,23 @@ static int
direct_query(VALUE io, const struct query_args *query)
{
if (RB_TYPE_P(io, T_FILE)) {
- VALUE wio = rb_io_get_write_io(io);
- VALUE s = rb_str_new_cstr(query->qstr);
- rb_io_write(wio, s);
- rb_io_flush(wio);
- return 1;
+ rb_io_t *fptr;
+ VALUE wio;
+ GetOpenFile(io, fptr);
+ wio = fptr->tied_io_for_writing;
+ if (wio) {
+ VALUE s = rb_str_new_cstr(query->qstr);
+ rb_io_write(wio, s);
+ rb_io_flush(wio);
+ return 1;
+ }
+ if (write(fptr->fd, query->qstr, strlen(query->qstr)) != -1) {
+ return 1;
+ }
+ if (fptr->fd == 0 &&
+ write(1, query->qstr, strlen(query->qstr)) != -1) {
+ return 1;
+ }
}
return 0;
}
@@ -1139,40 +1323,8 @@ console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qa
}
static VALUE
-console_scroll(VALUE io, int line)
-{
- if (line) {
- VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
- line < 0 ? 'T' : 'S');
- rb_io_write(io, s);
- }
- return io;
-}
-
-# define console_key_pressed_p rb_f_notimplement
-#endif
-
-/*
- * call-seq:
- * io.cursor -> [row, column]
- *
- * Returns the current cursor position as a two-element array of integers (row, column)
- *
- * io.cursor # => [3, 5]
- *
- * You must require 'io/console' to use this method.
- */
-static VALUE
console_cursor_pos(VALUE io)
{
-#ifdef _WIN32
- rb_console_size_t ws;
- int fd = GetWriteFD(io);
- if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
- return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
-#else
static const struct query_args query = {"\033[6n", 0};
VALUE resp = console_vt_response(0, 0, io, &query);
VALUE row, column, term;
@@ -1189,44 +1341,18 @@ console_cursor_pos(VALUE io)
RARRAY_ASET(resp, 0, INT2NUM(r));
RARRAY_ASET(resp, 1, INT2NUM(c));
return resp;
-#endif
}
static VALUE
console_goto(VALUE io, VALUE y, VALUE x)
{
-#ifdef _WIN32
- COORD pos;
- int fd = GetWriteFD(io);
- pos.X = NUM2UINT(x);
- pos.Y = NUM2UINT(y);
- if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
-#else
rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1));
-#endif
return io;
}
static VALUE
console_move(VALUE io, int y, int x)
{
-#ifdef _WIN32
- HANDLE h;
- rb_console_size_t ws;
- COORD *pos = &ws.dwCursorPosition;
-
- h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
- if (!GetConsoleScreenBufferInfo(h, &ws)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
- pos->X += x;
- pos->Y += y;
- if (!SetConsoleCursorPosition(h, *pos)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
-#else
if (x || y) {
VALUE s = rb_str_new_cstr("");
if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B');
@@ -1234,29 +1360,13 @@ console_move(VALUE io, int y, int x)
rb_io_write(io, s);
rb_io_flush(io);
}
-#endif
return io;
}
static VALUE
console_goto_column(VALUE io, VALUE val)
{
-#ifdef _WIN32
- HANDLE h;
- rb_console_size_t ws;
- COORD *pos = &ws.dwCursorPosition;
-
- h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
- if (!GetConsoleScreenBufferInfo(h, &ws)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
- pos->X = NUM2INT(val);
- if (!SetConsoleCursorPosition(h, *pos)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
-#else
rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1));
-#endif
return io;
}
@@ -1264,34 +1374,7 @@ static VALUE
console_erase_line(VALUE io, VALUE val)
{
int mode = mode_in_range(val, 2, "line erase");
-#ifdef _WIN32
- HANDLE h;
- rb_console_size_t ws;
- COORD *pos = &ws.dwCursorPosition;
- DWORD w;
-
- h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
- if (!GetConsoleScreenBufferInfo(h, &ws)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
- w = winsize_col(&ws);
- switch (mode) {
- case 0: /* after cursor */
- w -= pos->X;
- break;
- case 1: /* before *and* cursor */
- w = pos->X + 1;
- pos->X = 0;
- break;
- case 2: /* entire line */
- pos->X = 0;
- break;
- }
- constat_clear(h, ws.wAttributes, w, *pos);
- return io;
-#else
rb_io_write(io, rb_sprintf("\x1b[%dK", mode));
-#endif
return io;
}
@@ -1299,43 +1382,22 @@ static VALUE
console_erase_screen(VALUE io, VALUE val)
{
int mode = mode_in_range(val, 3, "screen erase");
-#ifdef _WIN32
- HANDLE h;
- rb_console_size_t ws;
- COORD *pos = &ws.dwCursorPosition;
- DWORD w;
+ rb_io_write(io, rb_sprintf("\x1b[%dJ", mode));
+ return io;
+}
- h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
- if (!GetConsoleScreenBufferInfo(h, &ws)) {
- rb_syserr_fail(LAST_ERROR, 0);
- }
- w = winsize_col(&ws);
- switch (mode) {
- case 0: /* erase after cursor */
- w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
- break;
- case 1: /* erase before *and* cursor */
- w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
- pos->X = 0;
- pos->Y = ws.srWindow.Top;
- break;
- case 2: /* erase entire screen */
- w = (w * winsize_row(&ws));
- pos->X = 0;
- pos->Y = ws.srWindow.Top;
- break;
- case 3: /* erase entire screen */
- w = (w * ws.dwSize.Y);
- pos->X = 0;
- pos->Y = 0;
- break;
+static VALUE
+console_scroll(VALUE io, int line)
+{
+ if (line) {
+ VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
+ line < 0 ? 'T' : 'S');
+ rb_io_write(io, s);
}
- constat_clear(h, ws.wAttributes, w, *pos);
-#else
- rb_io_write(io, rb_sprintf("\x1b[%dJ", mode));
-#endif
return io;
}
+# define console_key_pressed_p rb_f_notimplement
+#endif
static VALUE
console_cursor_set(VALUE io, VALUE cpos)
@@ -1389,38 +1451,6 @@ console_clear_screen(VALUE io)
return io;
}
-#ifndef HAVE_RB_IO_OPEN_DESCRIPTOR
-static VALUE
-io_open_descriptor_fallback(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, void *encoding)
-{
- rb_update_max_fd(descriptor);
-
- VALUE arguments[2] = {
- INT2NUM(descriptor),
- INT2FIX(mode),
- };
-
- VALUE self = rb_class_new_instance(2, arguments, klass);
-
- rb_io_t *fptr;
- GetOpenFile(self, fptr);
- fptr->pathv = path;
- fptr->mode |= mode;
-
- return self;
-}
-#define rb_io_open_descriptor io_open_descriptor_fallback
-#endif
-
-#ifndef HAVE_RB_IO_CLOSED_P
-static VALUE
-rb_io_closed_p(VALUE io)
-{
- rb_io_t *fptr = RFILE(io)->fptr;
- return fptr->fd == -1 ? Qtrue : Qfalse;
-}
-#endif
-
/*
* call-seq:
* IO.console -> #<File:/dev/tty>
@@ -1438,37 +1468,34 @@ static VALUE
console_dev(int argc, VALUE *argv, VALUE klass)
{
VALUE con = 0;
+ rb_io_t *fptr;
VALUE sym = 0;
rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS);
-
if (argc) {
- Check_Type(sym = argv[0], T_SYMBOL);
+ Check_Type(sym = argv[0], T_SYMBOL);
}
-
- // Force the class to be File.
if (klass == rb_cIO) klass = rb_cFile;
-
if (rb_const_defined(klass, id_console)) {
- con = rb_const_get(klass, id_console);
- if (!RB_TYPE_P(con, T_FILE) || RTEST(rb_io_closed_p(con))) {
- rb_const_remove(klass, id_console);
- con = 0;
- }
+ con = rb_const_get(klass, id_console);
+ if (!RB_TYPE_P(con, T_FILE) ||
+ (!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) {
+ rb_const_remove(klass, id_console);
+ con = 0;
+ }
}
-
if (sym) {
- if (sym == ID2SYM(id_close) && argc == 1) {
- if (con) {
- rb_io_close(con);
- rb_const_remove(klass, id_console);
- con = 0;
- }
- return Qnil;
- }
+ if (sym == ID2SYM(id_close) && argc == 1) {
+ if (con) {
+ rb_io_close(con);
+ rb_const_remove(klass, id_console);
+ con = 0;
+ }
+ return Qnil;
+ }
}
-
if (!con) {
+ VALUE args[2];
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
# define CONSOLE_DEVICE "/dev/tty"
#elif defined _WIN32
@@ -1480,36 +1507,44 @@ console_dev(int argc, VALUE *argv, VALUE klass)
# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
#endif
#ifdef CONSOLE_DEVICE_FOR_WRITING
- VALUE out;
- rb_io_t *ofptr;
+ VALUE out;
+ rb_io_t *ofptr;
#endif
- int fd;
- VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
+ int fd;
#ifdef CONSOLE_DEVICE_FOR_WRITING
- fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
- if (fd < 0) return Qnil;
- out = rb_io_open_descriptor(klass, fd, FMODE_WRITABLE | FMODE_SYNC, path, Qnil, NULL);
+ fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
+ if (fd < 0) return Qnil;
+ rb_update_max_fd(fd);
+ args[1] = INT2FIX(O_WRONLY);
+ args[0] = INT2NUM(fd);
+ out = rb_class_new_instance(2, args, klass);
#endif
- fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
- if (fd < 0) {
+ fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
+ if (fd < 0) {
#ifdef CONSOLE_DEVICE_FOR_WRITING
- rb_io_close(out);
+ rb_io_close(out);
#endif
- return Qnil;
- }
-
- con = rb_io_open_descriptor(klass, fd, FMODE_READWRITE | FMODE_SYNC, path, Qnil, NULL);
+ return Qnil;
+ }
+ rb_update_max_fd(fd);
+ args[1] = INT2FIX(O_RDWR);
+ args[0] = INT2NUM(fd);
+ con = rb_class_new_instance(2, args, klass);
+ GetOpenFile(con, fptr);
+ fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
#ifdef CONSOLE_DEVICE_FOR_WRITING
- rb_io_set_write_io(con, out);
+ GetOpenFile(out, ofptr);
+ ofptr->pathv = fptr->pathv;
+ fptr->tied_io_for_writing = out;
+ ofptr->mode |= FMODE_SYNC;
#endif
- rb_const_set(klass, id_console, con);
+ fptr->mode |= FMODE_SYNC;
+ rb_const_set(klass, id_console, con);
}
-
if (sym) {
- return rb_f_send(argc, argv, con);
+ return rb_f_send(argc, argv, con);
}
-
return con;
}
@@ -1525,6 +1560,7 @@ io_getch(int argc, VALUE *argv, VALUE io)
return rb_funcallv(io, id_getc, argc, argv);
}
+#if ENABLE_IO_GETPASS
static VALUE
puts_call(VALUE io)
{
@@ -1532,12 +1568,6 @@ puts_call(VALUE io)
}
static VALUE
-gets_call(VALUE io)
-{
- return rb_funcallv(io, id_gets, 0, 0);
-}
-
-static VALUE
getpass_call(VALUE io)
{
return ttymode(io, rb_io_gets, io, set_noecho, NULL);
@@ -1557,8 +1587,7 @@ static VALUE
str_chomp(VALUE str)
{
if (!NIL_P(str)) {
- const VALUE rs = rb_default_rs; /* rvalue in TruffleRuby */
- rb_funcallv(str, id_chomp_bang, 1, &rs);
+ rb_funcallv(str, id_chomp_bang, 0, 0);
}
return str;
}
@@ -1575,12 +1604,6 @@ str_chomp(VALUE str)
* see String#chomp!.
*
* You must require 'io/console' to use this method.
- *
- * require 'io/console'
- * IO::console.getpass("Enter password:")
- * Enter password:
- * # => "mypassword"
- *
*/
static VALUE
console_getpass(int argc, VALUE *argv, VALUE io)
@@ -1591,7 +1614,6 @@ console_getpass(int argc, VALUE *argv, VALUE io)
wio = rb_io_get_write_io(io);
if (wio == io && io == rb_stdin) wio = rb_stderr;
prompt(argc, argv, wio);
- rb_io_flush(wio);
str = rb_ensure(getpass_call, io, puts_call, wio);
return str_chomp(str);
}
@@ -1609,10 +1631,11 @@ io_getpass(int argc, VALUE *argv, VALUE io)
rb_check_arity(argc, 0, 1);
prompt(argc, argv, io);
- rb_check_funcall(io, id_flush, 0, 0);
- str = rb_ensure(gets_call, io, puts_call, io);
- return str_chomp(str);
+ str = str_chomp(rb_funcallv(io, id_gets, 0, 0));
+ puts_call(io);
+ return str;
}
+#endif
/*
* IO console methods
@@ -1622,9 +1645,10 @@ Init_console(void)
{
#undef rb_intern
id_getc = rb_intern("getc");
+#if ENABLE_IO_GETPASS
id_gets = rb_intern("gets");
- id_flush = rb_intern("flush");
id_chomp_bang = rb_intern("chomp!");
+#endif
id_console = rb_intern("console");
id_close = rb_intern("close");
#define init_rawmode_opt_id(name) \
@@ -1672,17 +1696,20 @@ InitVM_console(void)
rb_define_method(rb_cIO, "clear_screen", console_clear_screen, 0);
rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1);
rb_define_method(rb_cIO, "check_winsize_changed", console_check_winsize_changed, 0);
+#if ENABLE_IO_GETPASS
rb_define_method(rb_cIO, "getpass", console_getpass, -1);
+#endif
rb_define_singleton_method(rb_cIO, "console", console_dev, -1);
{
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
rb_define_method(mReadable, "getch", io_getch, -1);
+#if ENABLE_IO_GETPASS
rb_define_method(mReadable, "getpass", io_getpass, -1);
+#endif
}
{
/* :stopdoc: */
cConmode = rb_define_class_under(rb_cIO, "ConsoleMode", rb_cObject);
- rb_define_const(cConmode, "VERSION", rb_str_new_cstr(STRINGIZE(IO_CONSOLE_VERSION)));
rb_define_alloc_func(cConmode, conmode_alloc);
rb_undef_method(cConmode, "initialize");
rb_define_method(cConmode, "initialize_copy", conmode_init_copy, 1);
diff --git a/ext/io/console/depend b/ext/io/console/depend
index 59ca3442c2..36747ef583 100644
--- a/ext/io/console/depend
+++ b/ext/io/console/depend
@@ -54,7 +54,6 @@ console.o: $(hdrdir)/ruby/internal/attr/noexcept.h
console.o: $(hdrdir)/ruby/internal/attr/noinline.h
console.o: $(hdrdir)/ruby/internal/attr/nonnull.h
console.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-console.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
console.o: $(hdrdir)/ruby/internal/attr/pure.h
console.o: $(hdrdir)/ruby/internal/attr/restrict.h
console.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -123,6 +122,7 @@ console.o: $(hdrdir)/ruby/internal/intern/enumerator.h
console.o: $(hdrdir)/ruby/internal/intern/error.h
console.o: $(hdrdir)/ruby/internal/intern/eval.h
console.o: $(hdrdir)/ruby/internal/intern/file.h
+console.o: $(hdrdir)/ruby/internal/intern/gc.h
console.o: $(hdrdir)/ruby/internal/intern/hash.h
console.o: $(hdrdir)/ruby/internal/intern/io.h
console.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -153,6 +153,7 @@ console.o: $(hdrdir)/ruby/internal/memory.h
console.o: $(hdrdir)/ruby/internal/method.h
console.o: $(hdrdir)/ruby/internal/module.h
console.o: $(hdrdir)/ruby/internal/newobj.h
+console.o: $(hdrdir)/ruby/internal/rgengc.h
console.o: $(hdrdir)/ruby/internal/scan_args.h
console.o: $(hdrdir)/ruby/internal/special_consts.h
console.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -184,7 +185,7 @@ win32_vk.inc: win32_vk.list
-e 'n=$$F[1] and (n.strip!; /\AVK_/=~n) and' \
-e 'puts(%[#ifndef #{n}\n# define #{n} UNDEFINED_VK\n#endif])' \
$< && \
- gperf --ignore-case -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* $< \
+ gperf --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* $< \
| sed -f $(top_srcdir)/tool/gperf.sed \
) > $(@F)
diff --git a/ext/io/console/extconf.rb b/ext/io/console/extconf.rb
index aa0b6c6cfb..e8c5923b18 100644
--- a/ext/io/console/extconf.rb
+++ b/ext/io/console/extconf.rb
@@ -1,17 +1,6 @@
# frozen_string_literal: false
require 'mkmf'
-version = ["../../..", "."].find do |dir|
- break File.read(File.join(__dir__, dir, "io-console.gemspec"))[/^_VERSION\s*=\s*"(.*?)"/, 1]
-rescue
-end
-
-have_func("rb_io_path")
-have_func("rb_io_descriptor")
-have_func("rb_io_get_write_io")
-have_func("rb_io_closed_p")
-have_func("rb_io_open_descriptor")
-
ok = true if RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby"
hdr = nil
case
@@ -40,7 +29,7 @@ when true
elsif have_func("rb_scheduler_timeout") # 3.0
have_func("rb_io_wait")
end
- $defs << "-D""IO_CONSOLE_VERSION=#{version}"
+ $defs << "-D""ENABLE_IO_GETPASS=1"
create_makefile("io/console") {|conf|
conf << "\n""VK_HEADER = #{vk_header}\n"
}
diff --git a/ext/io/console/io-console.gemspec b/ext/io/console/io-console.gemspec
index d4f52763b7..d26a757b01 100644
--- a/ext/io/console/io-console.gemspec
+++ b/ext/io/console/io-console.gemspec
@@ -1,5 +1,5 @@
# -*- ruby -*-
-_VERSION = "0.7.1"
+_VERSION = "0.6.0"
Gem::Specification.new do |s|
s.name = "io-console"
@@ -13,7 +13,6 @@ Gem::Specification.new do |s|
s.authors = ["Nobu Nakada"]
s.require_path = %[lib]
s.files = %w[
- .document
LICENSE.txt
README.md
ext/io/console/console.c
@@ -26,16 +25,15 @@ Gem::Specification.new do |s|
if Gem::Platform === s.platform and s.platform =~ 'java'
s.files.delete_if {|f| f.start_with?("ext/")}
s.extensions.clear
- s.require_paths.unshift('lib/ffi')
s.files.concat(%w[
- lib/ffi/io/console.rb
- lib/ffi/io/console/bsd_console.rb
- lib/ffi/io/console/common.rb
- lib/ffi/io/console/linux_console.rb
- lib/ffi/io/console/native_console.rb
- lib/ffi/io/console/stty_console.rb
- lib/ffi/io/console/stub_console.rb
- lib/ffi/io/console/version.rb
+ lib/io/console.rb
+ lib/io/console/ffi/bsd_console.rb
+ lib/io/console/ffi/common.rb
+ lib/io/console/ffi/console.rb
+ lib/io/console/ffi/linux_console.rb
+ lib/io/console/ffi/native_console.rb
+ lib/io/console/ffi/stty_console.rb
+ lib/io/console/ffi/stub_console.rb
])
end
diff --git a/ext/io/console/win32_vk.inc b/ext/io/console/win32_vk.inc
index cbec7bef15..d15b1219fb 100644
--- a/ext/io/console/win32_vk.inc
+++ b/ext/io/console/win32_vk.inc
@@ -480,7 +480,7 @@
# define VK_OEM_CLEAR UNDEFINED_VK
#endif
/* ANSI-C code produced by gperf version 3.1 */
-/* Command-line: gperf --ignore-case -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k'*' win32_vk.list */
+/* Command-line: gperf --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k'*' win32_vk.list */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -509,18 +509,17 @@
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
#endif
-#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n)
#line 1 "win32_vk.list"
struct vktable {short ofs; unsigned short vk;};
-static const struct vktable *console_win32_vk(/*const char *, unsigned int*/);
+static const struct vktable *console_win32_vk(const char *, size_t);
#line 5 "win32_vk.list"
struct vktable;
/* maximum key range = 245, duplicates = 0 */
#ifndef GPERF_DOWNCASE
#define GPERF_DOWNCASE 1
-static unsigned char gperf_downcase[256] =
+static const unsigned char gperf_downcase[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
@@ -1007,368 +1006,368 @@ console_win32_vk (register const char *str, register size_t len)
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1},
#line 40 "win32_vk.list"
- {gperf_offsetof(stringpool, 12), VK_UP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str12, VK_UP},
#line 52 "win32_vk.list"
- {gperf_offsetof(stringpool, 13), VK_APPS},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13, VK_APPS},
#line 159 "win32_vk.list"
- {gperf_offsetof(stringpool, 14), VK_CRSEL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14, VK_CRSEL},
#line 34 "win32_vk.list"
- {gperf_offsetof(stringpool, 15), VK_SPACE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15, VK_SPACE},
#line 95 "win32_vk.list"
- {gperf_offsetof(stringpool, 16), VK_SCROLL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16, VK_SCROLL},
#line 29 "win32_vk.list"
- {gperf_offsetof(stringpool, 17), VK_ESCAPE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17, VK_ESCAPE},
#line 9 "win32_vk.list"
- {gperf_offsetof(stringpool, 18), VK_CANCEL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18, VK_CANCEL},
#line 32 "win32_vk.list"
- {gperf_offsetof(stringpool, 19), VK_ACCEPT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19, VK_ACCEPT},
#line 66 "win32_vk.list"
- {gperf_offsetof(stringpool, 20), VK_SEPARATOR},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20, VK_SEPARATOR},
#line 43 "win32_vk.list"
- {gperf_offsetof(stringpool, 21), VK_SELECT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21, VK_SELECT},
#line 18 "win32_vk.list"
- {gperf_offsetof(stringpool, 22), VK_CONTROL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22, VK_CONTROL},
#line 166 "win32_vk.list"
- {gperf_offsetof(stringpool, 23), VK_OEM_CLEAR},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str23, VK_OEM_CLEAR},
#line 145 "win32_vk.list"
- {gperf_offsetof(stringpool, 24), VK_OEM_RESET},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24, VK_OEM_RESET},
#line 155 "win32_vk.list"
- {gperf_offsetof(stringpool, 25), VK_OEM_AUTO},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25, VK_OEM_AUTO},
#line 151 "win32_vk.list"
- {gperf_offsetof(stringpool, 26), VK_OEM_CUSEL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26, VK_OEM_CUSEL},
{-1},
#line 22 "win32_vk.list"
- {gperf_offsetof(stringpool, 28), VK_KANA},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28, VK_KANA},
#line 127 "win32_vk.list"
- {gperf_offsetof(stringpool, 29), VK_OEM_PLUS},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29, VK_OEM_PLUS},
#line 35 "win32_vk.list"
- {gperf_offsetof(stringpool, 30), VK_PRIOR},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30, VK_PRIOR},
#line 152 "win32_vk.list"
- {gperf_offsetof(stringpool, 31), VK_OEM_ATTN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31, VK_OEM_ATTN},
#line 20 "win32_vk.list"
- {gperf_offsetof(stringpool, 32), VK_PAUSE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32, VK_PAUSE},
#line 13 "win32_vk.list"
- {gperf_offsetof(stringpool, 33), VK_BACK},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33, VK_BACK},
#line 144 "win32_vk.list"
- {gperf_offsetof(stringpool, 34), VK_PACKET},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str34, VK_PACKET},
#line 105 "win32_vk.list"
- {gperf_offsetof(stringpool, 35), VK_RCONTROL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35, VK_RCONTROL},
#line 104 "win32_vk.list"
- {gperf_offsetof(stringpool, 36), VK_LCONTROL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36, VK_LCONTROL},
#line 37 "win32_vk.list"
- {gperf_offsetof(stringpool, 37), VK_END},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37, VK_END},
#line 38 "win32_vk.list"
- {gperf_offsetof(stringpool, 38), VK_HOME},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38, VK_HOME},
#line 44 "win32_vk.list"
- {gperf_offsetof(stringpool, 39), VK_PRINT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39, VK_PRINT},
#line 94 "win32_vk.list"
- {gperf_offsetof(stringpool, 40), VK_NUMLOCK},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str40, VK_NUMLOCK},
#line 39 "win32_vk.list"
- {gperf_offsetof(stringpool, 41), VK_LEFT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41, VK_LEFT},
#line 25 "win32_vk.list"
- {gperf_offsetof(stringpool, 42), VK_JUNJA},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42, VK_JUNJA},
#line 19 "win32_vk.list"
- {gperf_offsetof(stringpool, 43), VK_MENU},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43, VK_MENU},
#line 150 "win32_vk.list"
- {gperf_offsetof(stringpool, 44), VK_OEM_WSCTRL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44, VK_OEM_WSCTRL},
#line 156 "win32_vk.list"
- {gperf_offsetof(stringpool, 45), VK_OEM_ENLW},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45, VK_OEM_ENLW},
#line 36 "win32_vk.list"
- {gperf_offsetof(stringpool, 46), VK_NEXT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46, VK_NEXT},
#line 51 "win32_vk.list"
- {gperf_offsetof(stringpool, 47), VK_RWIN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47, VK_RWIN},
#line 50 "win32_vk.list"
- {gperf_offsetof(stringpool, 48), VK_LWIN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48, VK_LWIN},
#line 21 "win32_vk.list"
- {gperf_offsetof(stringpool, 49), VK_CAPITAL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49, VK_CAPITAL},
#line 49 "win32_vk.list"
- {gperf_offsetof(stringpool, 50), VK_HELP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str50, VK_HELP},
#line 164 "win32_vk.list"
- {gperf_offsetof(stringpool, 51), VK_NONAME},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str51, VK_NONAME},
#line 8 "win32_vk.list"
- {gperf_offsetof(stringpool, 52), VK_RBUTTON},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52, VK_RBUTTON},
#line 7 "win32_vk.list"
- {gperf_offsetof(stringpool, 53), VK_LBUTTON},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str53, VK_LBUTTON},
#line 96 "win32_vk.list"
- {gperf_offsetof(stringpool, 54), VK_OEM_NEC_EQUAL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str54, VK_OEM_NEC_EQUAL},
{-1},
#line 47 "win32_vk.list"
- {gperf_offsetof(stringpool, 56), VK_INSERT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str56, VK_INSERT},
#line 27 "win32_vk.list"
- {gperf_offsetof(stringpool, 57), VK_HANJA},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str57, VK_HANJA},
{-1}, {-1},
#line 46 "win32_vk.list"
- {gperf_offsetof(stringpool, 60), VK_SNAPSHOT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str60, VK_SNAPSHOT},
#line 158 "win32_vk.list"
- {gperf_offsetof(stringpool, 61), VK_ATTN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str61, VK_ATTN},
#line 14 "win32_vk.list"
- {gperf_offsetof(stringpool, 62), VK_TAB},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str62, VK_TAB},
#line 157 "win32_vk.list"
- {gperf_offsetof(stringpool, 63), VK_OEM_BACKTAB},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str63, VK_OEM_BACKTAB},
#line 143 "win32_vk.list"
- {gperf_offsetof(stringpool, 64), VK_ICO_CLEAR},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64, VK_ICO_CLEAR},
#line 30 "win32_vk.list"
- {gperf_offsetof(stringpool, 65), VK_CONVERT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str65, VK_CONVERT},
#line 16 "win32_vk.list"
- {gperf_offsetof(stringpool, 66), VK_RETURN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str66, VK_RETURN},
#line 146 "win32_vk.list"
- {gperf_offsetof(stringpool, 67), VK_OEM_JUMP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str67, VK_OEM_JUMP},
{-1}, {-1}, {-1},
#line 111 "win32_vk.list"
- {gperf_offsetof(stringpool, 71), VK_BROWSER_STOP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str71, VK_BROWSER_STOP},
#line 26 "win32_vk.list"
- {gperf_offsetof(stringpool, 72), VK_FINAL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str72, VK_FINAL},
#line 163 "win32_vk.list"
- {gperf_offsetof(stringpool, 73), VK_ZOOM},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str73, VK_ZOOM},
#line 28 "win32_vk.list"
- {gperf_offsetof(stringpool, 74), VK_KANJI},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str74, VK_KANJI},
#line 48 "win32_vk.list"
- {gperf_offsetof(stringpool, 75), VK_DELETE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str75, VK_DELETE},
#line 128 "win32_vk.list"
- {gperf_offsetof(stringpool, 76), VK_OEM_COMMA},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str76, VK_OEM_COMMA},
#line 67 "win32_vk.list"
- {gperf_offsetof(stringpool, 77), VK_SUBTRACT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str77, VK_SUBTRACT},
{-1},
#line 10 "win32_vk.list"
- {gperf_offsetof(stringpool, 79), VK_MBUTTON},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str79, VK_MBUTTON},
#line 78 "win32_vk.list"
- {gperf_offsetof(stringpool, 80), VK_F9},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str80, VK_F9},
#line 17 "win32_vk.list"
- {gperf_offsetof(stringpool, 81), VK_SHIFT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str81, VK_SHIFT},
#line 103 "win32_vk.list"
- {gperf_offsetof(stringpool, 82), VK_RSHIFT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str82, VK_RSHIFT},
#line 102 "win32_vk.list"
- {gperf_offsetof(stringpool, 83), VK_LSHIFT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str83, VK_LSHIFT},
#line 65 "win32_vk.list"
- {gperf_offsetof(stringpool, 84), VK_ADD},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str84, VK_ADD},
#line 31 "win32_vk.list"
- {gperf_offsetof(stringpool, 85), VK_NONCONVERT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str85, VK_NONCONVERT},
#line 160 "win32_vk.list"
- {gperf_offsetof(stringpool, 86), VK_EXSEL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str86, VK_EXSEL},
#line 126 "win32_vk.list"
- {gperf_offsetof(stringpool, 87), VK_OEM_1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str87, VK_OEM_1},
#line 138 "win32_vk.list"
- {gperf_offsetof(stringpool, 88), VK_OEM_AX},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str88, VK_OEM_AX},
#line 108 "win32_vk.list"
- {gperf_offsetof(stringpool, 89), VK_BROWSER_BACK},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str89, VK_BROWSER_BACK},
#line 137 "win32_vk.list"
- {gperf_offsetof(stringpool, 90), VK_OEM_8},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str90, VK_OEM_8},
#line 129 "win32_vk.list"
- {gperf_offsetof(stringpool, 91), VK_OEM_MINUS},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str91, VK_OEM_MINUS},
#line 162 "win32_vk.list"
- {gperf_offsetof(stringpool, 92), VK_PLAY},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str92, VK_PLAY},
#line 131 "win32_vk.list"
- {gperf_offsetof(stringpool, 93), VK_OEM_2},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str93, VK_OEM_2},
#line 15 "win32_vk.list"
- {gperf_offsetof(stringpool, 94), VK_CLEAR},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str94, VK_CLEAR},
#line 99 "win32_vk.list"
- {gperf_offsetof(stringpool, 95), VK_OEM_FJ_TOUROKU},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str95, VK_OEM_FJ_TOUROKU},
#line 147 "win32_vk.list"
- {gperf_offsetof(stringpool, 96), VK_OEM_PA1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str96, VK_OEM_PA1},
#line 140 "win32_vk.list"
- {gperf_offsetof(stringpool, 97), VK_ICO_HELP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str97, VK_ICO_HELP},
#line 112 "win32_vk.list"
- {gperf_offsetof(stringpool, 98), VK_BROWSER_SEARCH},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str98, VK_BROWSER_SEARCH},
#line 53 "win32_vk.list"
- {gperf_offsetof(stringpool, 99), VK_SLEEP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str99, VK_SLEEP},
{-1},
#line 70 "win32_vk.list"
- {gperf_offsetof(stringpool, 101), VK_F1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str101, VK_F1},
#line 148 "win32_vk.list"
- {gperf_offsetof(stringpool, 102), VK_OEM_PA2},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str102, VK_OEM_PA2},
#line 154 "win32_vk.list"
- {gperf_offsetof(stringpool, 103), VK_OEM_COPY},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str103, VK_OEM_COPY},
#line 77 "win32_vk.list"
- {gperf_offsetof(stringpool, 104), VK_F8},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str104, VK_F8},
#line 88 "win32_vk.list"
- {gperf_offsetof(stringpool, 105), VK_F19},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str105, VK_F19},
#line 41 "win32_vk.list"
- {gperf_offsetof(stringpool, 106), VK_RIGHT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str106, VK_RIGHT},
#line 71 "win32_vk.list"
- {gperf_offsetof(stringpool, 107), VK_F2},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str107, VK_F2},
#line 135 "win32_vk.list"
- {gperf_offsetof(stringpool, 108), VK_OEM_6},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str108, VK_OEM_6},
#line 87 "win32_vk.list"
- {gperf_offsetof(stringpool, 109), VK_F18},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str109, VK_F18},
{-1},
#line 117 "win32_vk.list"
- {gperf_offsetof(stringpool, 111), VK_VOLUME_UP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str111, VK_VOLUME_UP},
{-1}, {-1},
#line 120 "win32_vk.list"
- {gperf_offsetof(stringpool, 114), VK_MEDIA_STOP},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str114, VK_MEDIA_STOP},
#line 130 "win32_vk.list"
- {gperf_offsetof(stringpool, 115), VK_OEM_PERIOD},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str115, VK_OEM_PERIOD},
{-1},
#line 161 "win32_vk.list"
- {gperf_offsetof(stringpool, 117), VK_EREOF},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str117, VK_EREOF},
{-1}, {-1}, {-1},
#line 114 "win32_vk.list"
- {gperf_offsetof(stringpool, 121), VK_BROWSER_HOME},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str121, VK_BROWSER_HOME},
#line 75 "win32_vk.list"
- {gperf_offsetof(stringpool, 122), VK_F6},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str122, VK_F6},
{-1},
#line 110 "win32_vk.list"
- {gperf_offsetof(stringpool, 124), VK_BROWSER_REFRESH},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str124, VK_BROWSER_REFRESH},
{-1},
#line 165 "win32_vk.list"
- {gperf_offsetof(stringpool, 126), VK_PA1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str126, VK_PA1},
#line 142 "win32_vk.list"
- {gperf_offsetof(stringpool, 127), VK_PROCESSKEY},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str127, VK_PROCESSKEY},
#line 68 "win32_vk.list"
- {gperf_offsetof(stringpool, 128), VK_DECIMAL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str128, VK_DECIMAL},
#line 132 "win32_vk.list"
- {gperf_offsetof(stringpool, 129), VK_OEM_3},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str129, VK_OEM_3},
#line 107 "win32_vk.list"
- {gperf_offsetof(stringpool, 130), VK_RMENU},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str130, VK_RMENU},
#line 106 "win32_vk.list"
- {gperf_offsetof(stringpool, 131), VK_LMENU},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str131, VK_LMENU},
#line 98 "win32_vk.list"
- {gperf_offsetof(stringpool, 132), VK_OEM_FJ_MASSHOU},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str132, VK_OEM_FJ_MASSHOU},
#line 54 "win32_vk.list"
- {gperf_offsetof(stringpool, 133), VK_NUMPAD0},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str133, VK_NUMPAD0},
#line 24 "win32_vk.list"
- {gperf_offsetof(stringpool, 134), VK_HANGUL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str134, VK_HANGUL},
#line 63 "win32_vk.list"
- {gperf_offsetof(stringpool, 135), VK_NUMPAD9},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str135, VK_NUMPAD9},
#line 23 "win32_vk.list"
- {gperf_offsetof(stringpool, 136), VK_HANGEUL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str136, VK_HANGEUL},
#line 134 "win32_vk.list"
- {gperf_offsetof(stringpool, 137), VK_OEM_5},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str137, VK_OEM_5},
#line 149 "win32_vk.list"
- {gperf_offsetof(stringpool, 138), VK_OEM_PA3},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str138, VK_OEM_PA3},
#line 115 "win32_vk.list"
- {gperf_offsetof(stringpool, 139), VK_VOLUME_MUTE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str139, VK_VOLUME_MUTE},
#line 133 "win32_vk.list"
- {gperf_offsetof(stringpool, 140), VK_OEM_4},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str140, VK_OEM_4},
#line 122 "win32_vk.list"
- {gperf_offsetof(stringpool, 141), VK_LAUNCH_MAIL},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str141, VK_LAUNCH_MAIL},
#line 97 "win32_vk.list"
- {gperf_offsetof(stringpool, 142), VK_OEM_FJ_JISHO},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str142, VK_OEM_FJ_JISHO},
#line 72 "win32_vk.list"
- {gperf_offsetof(stringpool, 143), VK_F3},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str143, VK_F3},
#line 101 "win32_vk.list"
- {gperf_offsetof(stringpool, 144), VK_OEM_FJ_ROYA},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str144, VK_OEM_FJ_ROYA},
#line 100 "win32_vk.list"
- {gperf_offsetof(stringpool, 145), VK_OEM_FJ_LOYA},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str145, VK_OEM_FJ_LOYA},
{-1},
#line 42 "win32_vk.list"
- {gperf_offsetof(stringpool, 147), VK_DOWN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str147, VK_DOWN},
{-1},
#line 153 "win32_vk.list"
- {gperf_offsetof(stringpool, 149), VK_OEM_FINISH},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str149, VK_OEM_FINISH},
{-1},
#line 74 "win32_vk.list"
- {gperf_offsetof(stringpool, 151), VK_F5},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str151, VK_F5},
{-1},
#line 136 "win32_vk.list"
- {gperf_offsetof(stringpool, 153), VK_OEM_7},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str153, VK_OEM_7},
#line 73 "win32_vk.list"
- {gperf_offsetof(stringpool, 154), VK_F4},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str154, VK_F4},
#line 86 "win32_vk.list"
- {gperf_offsetof(stringpool, 155), VK_F17},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str155, VK_F17},
#line 55 "win32_vk.list"
- {gperf_offsetof(stringpool, 156), VK_NUMPAD1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str156, VK_NUMPAD1},
#line 141 "win32_vk.list"
- {gperf_offsetof(stringpool, 157), VK_ICO_00},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str157, VK_ICO_00},
{-1},
#line 62 "win32_vk.list"
- {gperf_offsetof(stringpool, 159), VK_NUMPAD8},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str159, VK_NUMPAD8},
{-1}, {-1},
#line 56 "win32_vk.list"
- {gperf_offsetof(stringpool, 162), VK_NUMPAD2},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str162, VK_NUMPAD2},
{-1},
#line 124 "win32_vk.list"
- {gperf_offsetof(stringpool, 164), VK_LAUNCH_APP1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str164, VK_LAUNCH_APP1},
#line 109 "win32_vk.list"
- {gperf_offsetof(stringpool, 165), VK_BROWSER_FORWARD},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str165, VK_BROWSER_FORWARD},
{-1},
#line 76 "win32_vk.list"
- {gperf_offsetof(stringpool, 167), VK_F7},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str167, VK_F7},
{-1}, {-1},
#line 125 "win32_vk.list"
- {gperf_offsetof(stringpool, 170), VK_LAUNCH_APP2},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str170, VK_LAUNCH_APP2},
#line 64 "win32_vk.list"
- {gperf_offsetof(stringpool, 171), VK_MULTIPLY},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str171, VK_MULTIPLY},
{-1}, {-1},
#line 45 "win32_vk.list"
- {gperf_offsetof(stringpool, 174), VK_EXECUTE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str174, VK_EXECUTE},
{-1},
#line 113 "win32_vk.list"
- {gperf_offsetof(stringpool, 176), VK_BROWSER_FAVORITES},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str176, VK_BROWSER_FAVORITES},
#line 60 "win32_vk.list"
- {gperf_offsetof(stringpool, 177), VK_NUMPAD6},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str177, VK_NUMPAD6},
{-1},
#line 85 "win32_vk.list"
- {gperf_offsetof(stringpool, 179), VK_F16},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str179, VK_F16},
{-1}, {-1},
#line 79 "win32_vk.list"
- {gperf_offsetof(stringpool, 182), VK_F10},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str182, VK_F10},
{-1}, {-1},
#line 116 "win32_vk.list"
- {gperf_offsetof(stringpool, 185), VK_VOLUME_DOWN},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str185, VK_VOLUME_DOWN},
{-1}, {-1},
#line 89 "win32_vk.list"
- {gperf_offsetof(stringpool, 188), VK_F20},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str188, VK_F20},
#line 119 "win32_vk.list"
- {gperf_offsetof(stringpool, 189), VK_MEDIA_PREV_TRACK},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str189, VK_MEDIA_PREV_TRACK},
{-1},
#line 33 "win32_vk.list"
- {gperf_offsetof(stringpool, 191), VK_MODECHANGE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str191, VK_MODECHANGE},
{-1}, {-1}, {-1}, {-1}, {-1},
#line 83 "win32_vk.list"
- {gperf_offsetof(stringpool, 197), VK_F14},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str197, VK_F14},
#line 57 "win32_vk.list"
- {gperf_offsetof(stringpool, 198), VK_NUMPAD3},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str198, VK_NUMPAD3},
#line 11 "win32_vk.list"
- {gperf_offsetof(stringpool, 199), VK_XBUTTON1},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str199, VK_XBUTTON1},
{-1}, {-1}, {-1},
#line 93 "win32_vk.list"
- {gperf_offsetof(stringpool, 203), VK_F24},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str203, VK_F24},
{-1},
#line 12 "win32_vk.list"
- {gperf_offsetof(stringpool, 205), VK_XBUTTON2},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str205, VK_XBUTTON2},
#line 59 "win32_vk.list"
- {gperf_offsetof(stringpool, 206), VK_NUMPAD5},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str206, VK_NUMPAD5},
{-1}, {-1},
#line 58 "win32_vk.list"
- {gperf_offsetof(stringpool, 209), VK_NUMPAD4},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str209, VK_NUMPAD4},
{-1}, {-1}, {-1}, {-1}, {-1},
#line 121 "win32_vk.list"
- {gperf_offsetof(stringpool, 215), VK_MEDIA_PLAY_PAUSE},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str215, VK_MEDIA_PLAY_PAUSE},
{-1},
#line 123 "win32_vk.list"
- {gperf_offsetof(stringpool, 217), VK_LAUNCH_MEDIA_SELECT},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str217, VK_LAUNCH_MEDIA_SELECT},
#line 80 "win32_vk.list"
- {gperf_offsetof(stringpool, 218), VK_F11},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str218, VK_F11},
{-1},
#line 139 "win32_vk.list"
- {gperf_offsetof(stringpool, 220), VK_OEM_102},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str220, VK_OEM_102},
#line 118 "win32_vk.list"
- {gperf_offsetof(stringpool, 221), VK_MEDIA_NEXT_TRACK},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str221, VK_MEDIA_NEXT_TRACK},
#line 61 "win32_vk.list"
- {gperf_offsetof(stringpool, 222), VK_NUMPAD7},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str222, VK_NUMPAD7},
{-1},
#line 90 "win32_vk.list"
- {gperf_offsetof(stringpool, 224), VK_F21},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str224, VK_F21},
{-1},
#line 82 "win32_vk.list"
- {gperf_offsetof(stringpool, 226), VK_F13},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str226, VK_F13},
{-1}, {-1},
#line 81 "win32_vk.list"
- {gperf_offsetof(stringpool, 229), VK_F12},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str229, VK_F12},
{-1}, {-1},
#line 92 "win32_vk.list"
- {gperf_offsetof(stringpool, 232), VK_F23},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str232, VK_F23},
{-1}, {-1},
#line 91 "win32_vk.list"
- {gperf_offsetof(stringpool, 235), VK_F22},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str235, VK_F22},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1},
#line 84 "win32_vk.list"
- {gperf_offsetof(stringpool, 242), VK_F15},
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str242, VK_F15},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1},
#line 69 "win32_vk.list"
- {gperf_offsetof(stringpool, 256), VK_DIVIDE}
+ {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str256, VK_DIVIDE}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/ext/io/console/win32_vk.list b/ext/io/console/win32_vk.list
index 7909a4d1f0..5df3d6da57 100644
--- a/ext/io/console/win32_vk.list
+++ b/ext/io/console/win32_vk.list
@@ -1,6 +1,6 @@
%{
struct vktable {short ofs; unsigned short vk;};
-static const struct vktable *console_win32_vk(/*!ANSI{*/const char *, unsigned int/*}!ANSI*/);
+static const struct vktable *console_win32_vk(const char *, size_t);
%}
struct vktable
%%
diff --git a/ext/io/nonblock/depend b/ext/io/nonblock/depend
index 48384fca62..7f2db65732 100644
--- a/ext/io/nonblock/depend
+++ b/ext/io/nonblock/depend
@@ -53,7 +53,6 @@ nonblock.o: $(hdrdir)/ruby/internal/attr/noexcept.h
nonblock.o: $(hdrdir)/ruby/internal/attr/noinline.h
nonblock.o: $(hdrdir)/ruby/internal/attr/nonnull.h
nonblock.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-nonblock.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
nonblock.o: $(hdrdir)/ruby/internal/attr/pure.h
nonblock.o: $(hdrdir)/ruby/internal/attr/restrict.h
nonblock.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ nonblock.o: $(hdrdir)/ruby/internal/intern/enumerator.h
nonblock.o: $(hdrdir)/ruby/internal/intern/error.h
nonblock.o: $(hdrdir)/ruby/internal/intern/eval.h
nonblock.o: $(hdrdir)/ruby/internal/intern/file.h
+nonblock.o: $(hdrdir)/ruby/internal/intern/gc.h
nonblock.o: $(hdrdir)/ruby/internal/intern/hash.h
nonblock.o: $(hdrdir)/ruby/internal/intern/io.h
nonblock.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ nonblock.o: $(hdrdir)/ruby/internal/memory.h
nonblock.o: $(hdrdir)/ruby/internal/method.h
nonblock.o: $(hdrdir)/ruby/internal/module.h
nonblock.o: $(hdrdir)/ruby/internal/newobj.h
+nonblock.o: $(hdrdir)/ruby/internal/rgengc.h
nonblock.o: $(hdrdir)/ruby/internal/scan_args.h
nonblock.o: $(hdrdir)/ruby/internal/special_consts.h
nonblock.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/io/nonblock/extconf.rb b/ext/io/nonblock/extconf.rb
index a1e6075c9b..d813a01e7c 100644
--- a/ext/io/nonblock/extconf.rb
+++ b/ext/io/nonblock/extconf.rb
@@ -2,13 +2,6 @@
require 'mkmf'
target = "io/nonblock"
-unless RUBY_ENGINE == 'ruby'
- File.write("Makefile", dummy_makefile($srcdir).join(""))
- return
-end
-
-have_func("rb_io_descriptor")
-
hdr = %w"fcntl.h"
if have_macro("O_NONBLOCK", hdr) and
(have_macro("F_GETFL", hdr) or have_macro("F_SETFL", hdr))
diff --git a/ext/io/nonblock/io-nonblock.gemspec b/ext/io/nonblock/io-nonblock.gemspec
index 6a16c8b03b..d6df21a84d 100644
--- a/ext/io/nonblock/io-nonblock.gemspec
+++ b/ext/io/nonblock/io-nonblock.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = "io-nonblock"
- spec.version = "0.3.0"
+ spec.version = "0.2.0"
spec.authors = ["Nobu Nakada"]
spec.email = ["nobu@ruby-lang.org"]
diff --git a/ext/io/nonblock/nonblock.c b/ext/io/nonblock/nonblock.c
index d90538f735..b8a40ff38e 100644
--- a/ext/io/nonblock/nonblock.c
+++ b/ext/io/nonblock/nonblock.c
@@ -17,17 +17,6 @@
#endif
#include <fcntl.h>
-#ifndef HAVE_RB_IO_DESCRIPTOR
-static int
-io_descriptor_fallback(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- return fptr->fd;
-}
-#define rb_io_descriptor io_descriptor_fallback
-#endif
-
#ifdef F_GETFL
static int
get_fcntl_flags(int fd)
@@ -50,8 +39,10 @@ get_fcntl_flags(int fd)
static VALUE
rb_io_nonblock_p(VALUE io)
{
- if (get_fcntl_flags(rb_io_descriptor(io)) & O_NONBLOCK)
- return Qtrue;
+ rb_io_t *fptr;
+ GetOpenFile(io, fptr);
+ if (get_fcntl_flags(fptr->fd) & O_NONBLOCK)
+ return Qtrue;
return Qfalse;
}
#else
@@ -66,8 +57,6 @@ set_fcntl_flags(int fd, int f)
rb_sys_fail(0);
}
-#ifndef RUBY_IO_NONBLOCK_METHODS
-
static int
io_nonblock_set(int fd, int f, int nb)
{
@@ -133,23 +122,17 @@ io_nonblock_set(int fd, int f, int nb)
*
*/
static VALUE
-rb_io_nonblock_set(VALUE self, VALUE value)
+rb_io_nonblock_set(VALUE io, VALUE nb)
{
- if (RTEST(value)) {
- rb_io_t *fptr;
- GetOpenFile(self, fptr);
- rb_io_set_nonblock(fptr);
- }
- else {
- int descriptor = rb_io_descriptor(self);
- io_nonblock_set(descriptor, get_fcntl_flags(descriptor), RTEST(value));
- }
-
- return self;
+ rb_io_t *fptr;
+ GetOpenFile(io, fptr);
+ if (RTEST(nb))
+ rb_io_set_nonblock(fptr);
+ else
+ io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb));
+ return io;
}
-#endif /* RUBY_IO_NONBLOCK_METHODS */
-
static VALUE
io_nonblock_restore(VALUE arg)
{
@@ -169,25 +152,24 @@ io_nonblock_restore(VALUE arg)
* The original mode is restored after the block is executed.
*/
static VALUE
-rb_io_nonblock_block(int argc, VALUE *argv, VALUE self)
+rb_io_nonblock_block(int argc, VALUE *argv, VALUE io)
{
int nb = 1;
+ rb_io_t *fptr;
+ int f, restore[2];
- int descriptor = rb_io_descriptor(self);
-
+ GetOpenFile(io, fptr);
if (argc > 0) {
- VALUE v;
- rb_scan_args(argc, argv, "01", &v);
- nb = RTEST(v);
+ VALUE v;
+ rb_scan_args(argc, argv, "01", &v);
+ nb = RTEST(v);
}
-
- int current_flags = get_fcntl_flags(descriptor);
- int restore[2] = {descriptor, current_flags};
-
- if (!io_nonblock_set(descriptor, current_flags, nb))
- return rb_yield(self);
-
- return rb_ensure(rb_yield, self, io_nonblock_restore, (VALUE)restore);
+ f = get_fcntl_flags(fptr->fd);
+ restore[0] = fptr->fd;
+ restore[1] = f;
+ if (!io_nonblock_set(fptr->fd, f, nb))
+ return rb_yield(io);
+ return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore);
}
#else
#define rb_io_nonblock_set rb_f_notimplement
@@ -197,10 +179,7 @@ rb_io_nonblock_block(int argc, VALUE *argv, VALUE self)
void
Init_nonblock(void)
{
-#ifndef RUBY_IO_NONBLOCK_METHODS
rb_define_method(rb_cIO, "nonblock?", rb_io_nonblock_p, 0);
rb_define_method(rb_cIO, "nonblock=", rb_io_nonblock_set, 1);
-#endif
-
rb_define_method(rb_cIO, "nonblock", rb_io_nonblock_block, -1);
}
diff --git a/ext/io/wait/depend b/ext/io/wait/depend
index 83cf8f94c8..51e1af8280 100644
--- a/ext/io/wait/depend
+++ b/ext/io/wait/depend
@@ -54,7 +54,6 @@ wait.o: $(hdrdir)/ruby/internal/attr/noexcept.h
wait.o: $(hdrdir)/ruby/internal/attr/noinline.h
wait.o: $(hdrdir)/ruby/internal/attr/nonnull.h
wait.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-wait.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
wait.o: $(hdrdir)/ruby/internal/attr/pure.h
wait.o: $(hdrdir)/ruby/internal/attr/restrict.h
wait.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -123,6 +122,7 @@ wait.o: $(hdrdir)/ruby/internal/intern/enumerator.h
wait.o: $(hdrdir)/ruby/internal/intern/error.h
wait.o: $(hdrdir)/ruby/internal/intern/eval.h
wait.o: $(hdrdir)/ruby/internal/intern/file.h
+wait.o: $(hdrdir)/ruby/internal/intern/gc.h
wait.o: $(hdrdir)/ruby/internal/intern/hash.h
wait.o: $(hdrdir)/ruby/internal/intern/io.h
wait.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -153,6 +153,7 @@ wait.o: $(hdrdir)/ruby/internal/memory.h
wait.o: $(hdrdir)/ruby/internal/method.h
wait.o: $(hdrdir)/ruby/internal/module.h
wait.o: $(hdrdir)/ruby/internal/newobj.h
+wait.o: $(hdrdir)/ruby/internal/rgengc.h
wait.o: $(hdrdir)/ruby/internal/scan_args.h
wait.o: $(hdrdir)/ruby/internal/special_consts.h
wait.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/io/wait/extconf.rb b/ext/io/wait/extconf.rb
index e63c046187..c6230b7783 100644
--- a/ext/io/wait/extconf.rb
+++ b/ext/io/wait/extconf.rb
@@ -5,8 +5,7 @@ if RUBY_VERSION < "2.6"
File.write("Makefile", dummy_makefile($srcdir).join(""))
else
target = "io/wait"
- have_func("rb_io_wait")
- have_func("rb_io_descriptor")
+ have_func("rb_io_wait", "ruby/io.h")
unless macro_defined?("DOSISH", "#include <ruby.h>")
have_header(ioctl_h = "sys/ioctl.h") or ioctl_h = nil
fionread = %w[sys/ioctl.h sys/filio.h sys/socket.h].find do |h|
diff --git a/ext/io/wait/io-wait.gemspec b/ext/io/wait/io-wait.gemspec
index e850e10bf9..ebc1f6f5c7 100644
--- a/ext/io/wait/io-wait.gemspec
+++ b/ext/io/wait/io-wait.gemspec
@@ -1,4 +1,4 @@
-_VERSION = "0.3.1"
+_VERSION = "0.3.0"
Gem::Specification.new do |spec|
spec.name = "io-wait"
diff --git a/ext/io/wait/wait.c b/ext/io/wait/wait.c
index 8835670e59..d74afb580b 100644
--- a/ext/io/wait/wait.c
+++ b/ext/io/wait/wait.c
@@ -87,15 +87,8 @@ io_nread(VALUE io)
rb_io_check_readable(fptr);
len = rb_io_read_pending(fptr);
if (len > 0) return INT2FIX(len);
-
-#ifdef HAVE_RB_IO_DESCRIPTOR
- int fd = rb_io_descriptor(io);
-#else
- int fd = fptr->fd;
-#endif
-
- if (!FIONREAD_POSSIBLE_P(fd)) return INT2FIX(0);
- if (ioctl(fd, FIONREAD, &n)) return INT2FIX(0);
+ if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0);
+ if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0);
if (n > 0) return ioctl_arg2num(n);
return INT2FIX(0);
}
diff --git a/ext/json/VERSION b/ext/json/VERSION
new file mode 100644
index 0000000000..ec1cf33c3f
--- /dev/null
+++ b/ext/json/VERSION
@@ -0,0 +1 @@
+2.6.3
diff --git a/ext/json/generator/depend b/ext/json/generator/depend
index 42752d1a35..28ef06b36d 100644
--- a/ext/json/generator/depend
+++ b/ext/json/generator/depend
@@ -56,7 +56,6 @@ generator.o: $(hdrdir)/ruby/internal/attr/noexcept.h
generator.o: $(hdrdir)/ruby/internal/attr/noinline.h
generator.o: $(hdrdir)/ruby/internal/attr/nonnull.h
generator.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-generator.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
generator.o: $(hdrdir)/ruby/internal/attr/pure.h
generator.o: $(hdrdir)/ruby/internal/attr/restrict.h
generator.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -126,6 +125,7 @@ generator.o: $(hdrdir)/ruby/internal/intern/enumerator.h
generator.o: $(hdrdir)/ruby/internal/intern/error.h
generator.o: $(hdrdir)/ruby/internal/intern/eval.h
generator.o: $(hdrdir)/ruby/internal/intern/file.h
+generator.o: $(hdrdir)/ruby/internal/intern/gc.h
generator.o: $(hdrdir)/ruby/internal/intern/hash.h
generator.o: $(hdrdir)/ruby/internal/intern/io.h
generator.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -156,6 +156,7 @@ generator.o: $(hdrdir)/ruby/internal/memory.h
generator.o: $(hdrdir)/ruby/internal/method.h
generator.o: $(hdrdir)/ruby/internal/module.h
generator.o: $(hdrdir)/ruby/internal/newobj.h
+generator.o: $(hdrdir)/ruby/internal/rgengc.h
generator.o: $(hdrdir)/ruby/internal/scan_args.h
generator.o: $(hdrdir)/ruby/internal/special_consts.h
generator.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index a71acfbb76..98d0ea46c3 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -16,7 +16,7 @@ static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
i_pack, i_unpack, i_create_id, i_extend, i_key_p,
i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
- i_buffer_initial_length, i_dup, i_script_safe, i_escape_slash, i_strict;
+ i_buffer_initial_length, i_dup, i_escape_slash;
/*
* Copyright 2001-2004 Unicode, Inc.
@@ -124,7 +124,7 @@ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
* and control characters are JSON escaped. */
-static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char script_safe)
+static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash)
{
const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
const UTF8 *sourceEnd = source + RSTRING_LEN(string);
@@ -175,7 +175,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char scrip
fbuffer_append(buffer, "\\\"", 2);
break;
case '/':
- if(script_safe) {
+ if(escape_slash) {
fbuffer_append(buffer, "\\/", 2);
break;
}
@@ -228,7 +228,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char scrip
* characters required by the JSON standard are JSON escaped. The remaining
* characters (should be UTF8) are just passed through and appended to the
* result. */
-static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char script_safe)
+static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash)
{
const char *ptr = RSTRING_PTR(string), *p;
unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
@@ -280,7 +280,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char script_safe
escape_len = 2;
break;
case '/':
- if(script_safe) {
+ if(escape_slash) {
escape = "\\/";
escape_len = 2;
break;
@@ -294,22 +294,6 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char script_safe
rb_raise(rb_path2class("JSON::GeneratorError"),
"partial character in source, but hit end");
}
-
- if (script_safe && c == 0xE2) {
- unsigned char c2 = (unsigned char) *(p+1);
- unsigned char c3 = (unsigned char) *(p+2);
- if (c2 == 0x80 && (c3 == 0xA8 || c3 == 0xA9)) {
- fbuffer_append(buffer, ptr + start, end - start);
- start = end = (end + clen);
- if (c3 == 0xA8) {
- fbuffer_append(buffer, "\\u2028", 6);
- } else {
- fbuffer_append(buffer, "\\u2029", 6);
- }
- continue;
- }
- }
-
if (!isLegalUTF8((UTF8 *) p, clen)) {
rb_raise(rb_path2class("JSON::GeneratorError"),
"source sequence is illegal/malformed utf-8");
@@ -494,7 +478,6 @@ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
*/
static VALUE mString_included_s(VALUE self, VALUE modul) {
VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
- rb_call_super(1, &modul);
return result;
}
@@ -743,14 +726,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
state->allow_nan = RTEST(tmp);
tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
state->ascii_only = RTEST(tmp);
- tmp = rb_hash_aref(opts, ID2SYM(i_script_safe));
- state->script_safe = RTEST(tmp);
- if (!state->script_safe) {
- tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
- state->script_safe = RTEST(tmp);
- }
- tmp = rb_hash_aref(opts, ID2SYM(i_strict));
- state->strict = RTEST(tmp);
+ tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
+ state->escape_slash = RTEST(tmp);
return self;
}
@@ -785,8 +762,7 @@ static VALUE cState_to_h(VALUE self)
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
- rb_hash_aset(result, ID2SYM(i_script_safe), state->script_safe ? Qtrue : Qfalse);
- rb_hash_aset(result, ID2SYM(i_strict), state->strict ? Qtrue : Qfalse);
+ rb_hash_aset(result, ID2SYM(i_escape_slash), state->escape_slash ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
return result;
@@ -971,9 +947,9 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
}
#endif
if (state->ascii_only) {
- convert_UTF8_to_JSON_ASCII(buffer, obj, state->script_safe);
+ convert_UTF8_to_JSON_ASCII(buffer, obj, state->escape_slash);
} else {
- convert_UTF8_to_JSON(buffer, obj, state->script_safe);
+ convert_UTF8_to_JSON(buffer, obj, state->escape_slash);
}
fbuffer_append_char(buffer, '"');
}
@@ -1052,8 +1028,6 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s
generate_json_bignum(buffer, Vstate, state, obj);
} else if (klass == rb_cFloat) {
generate_json_float(buffer, Vstate, state, obj);
- } else if (state->strict) {
- rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(CLASS_OF(obj)));
} else if (rb_respond_to(obj, i_to_json)) {
tmp = rb_funcall(obj, i_to_json, 1, Vstate);
Check_Type(tmp, T_STRING);
@@ -1416,58 +1390,27 @@ static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
}
/*
- * call-seq: script_safe
+ * call-seq: escape_slash
*
* If this boolean is true, the forward slashes will be escaped in
* the json output.
*/
-static VALUE cState_script_safe(VALUE self)
+static VALUE cState_escape_slash(VALUE self)
{
GET_STATE(self);
- return state->script_safe ? Qtrue : Qfalse;
+ return state->escape_slash ? Qtrue : Qfalse;
}
/*
- * call-seq: script_safe=(enable)
+ * call-seq: escape_slash=(depth)
*
* This sets whether or not the forward slashes will be escaped in
* the json output.
*/
-static VALUE cState_script_safe_set(VALUE self, VALUE enable)
-{
- GET_STATE(self);
- state->script_safe = RTEST(enable);
- return Qnil;
-}
-
-/*
- * call-seq: strict
- *
- * If this boolean is false, types unsupported by the JSON format will
- * be serialized as strings.
- * If this boolean is true, types unsupported by the JSON format will
- * raise a JSON::GeneratorError.
- */
-static VALUE cState_strict(VALUE self)
-{
- GET_STATE(self);
- return state->strict ? Qtrue : Qfalse;
-}
-
-/*
- * call-seq: strict=(enable)
- *
- * This sets whether or not to serialize types unsupported by the
- * JSON format as strings.
- * If this boolean is false, types unsupported by the JSON format will
- * be serialized as strings.
- * If this boolean is true, types unsupported by the JSON format will
- * raise a JSON::GeneratorError.
- */
-static VALUE cState_strict_set(VALUE self, VALUE enable)
+static VALUE cState_escape_slash_set(VALUE self, VALUE enable)
{
GET_STATE(self);
- state->strict = RTEST(enable);
+ state->escape_slash = RTEST(enable);
return Qnil;
}
@@ -1587,15 +1530,9 @@ void Init_generator(void)
rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
- rb_define_method(cState, "script_safe", cState_script_safe, 0);
- rb_define_method(cState, "script_safe?", cState_script_safe, 0);
- rb_define_method(cState, "script_safe=", cState_script_safe_set, 1);
- rb_define_alias(cState, "escape_slash", "script_safe");
- rb_define_alias(cState, "escape_slash?", "script_safe?");
- rb_define_alias(cState, "escape_slash=", "script_safe=");
- rb_define_method(cState, "strict", cState_strict, 0);
- rb_define_method(cState, "strict?", cState_strict, 0);
- rb_define_method(cState, "strict=", cState_strict_set, 1);
+ rb_define_method(cState, "escape_slash", cState_escape_slash, 0);
+ rb_define_method(cState, "escape_slash?", cState_escape_slash, 0);
+ rb_define_method(cState, "escape_slash=", cState_escape_slash_set, 1);
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
@@ -1652,9 +1589,7 @@ void Init_generator(void)
i_object_nl = rb_intern("object_nl");
i_array_nl = rb_intern("array_nl");
i_max_nesting = rb_intern("max_nesting");
- i_script_safe = rb_intern("script_safe");
i_escape_slash = rb_intern("escape_slash");
- i_strict = rb_intern("strict");
i_allow_nan = rb_intern("allow_nan");
i_ascii_only = rb_intern("ascii_only");
i_depth = rb_intern("depth");
diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h
index 1a736b84dd..3ebd622554 100644
--- a/ext/json/generator/generator.h
+++ b/ext/json/generator/generator.h
@@ -49,8 +49,8 @@ static const UTF32 halfMask = 0x3FFUL;
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length);
static void unicode_escape(char *buf, UTF16 character);
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
-static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char script_safe);
-static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char script_safe);
+static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash);
+static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash);
static char *fstrndup(const char *ptr, unsigned long len);
/* ruby api and some helpers */
@@ -72,8 +72,7 @@ typedef struct JSON_Generator_StateStruct {
long max_nesting;
char allow_nan;
char ascii_only;
- char script_safe;
- char strict;
+ char escape_slash;
long depth;
long buffer_initial_length;
} JSON_Generator_State;
@@ -152,10 +151,8 @@ static VALUE cState_allow_nan_p(VALUE self);
static VALUE cState_ascii_only_p(VALUE self);
static VALUE cState_depth(VALUE self);
static VALUE cState_depth_set(VALUE self, VALUE depth);
-static VALUE cState_script_safe(VALUE self);
-static VALUE cState_script_safe_set(VALUE self, VALUE depth);
-static VALUE cState_strict(VALUE self);
-static VALUE cState_strict_set(VALUE self, VALUE strict);
+static VALUE cState_escape_slash(VALUE self);
+static VALUE cState_escape_slash_set(VALUE self, VALUE depth);
static FBuffer *cState_prepare_buffer(VALUE self);
#ifndef ZALLOC
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
diff --git a/ext/json/json.gemspec b/ext/json/json.gemspec
index 64d0c81391..948e92c501 100644
--- a/ext/json/json.gemspec
+++ b/ext/json/json.gemspec
@@ -1,10 +1,8 @@
-version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line|
- /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1
-end rescue nil
+# -*- encoding: utf-8 -*-
Gem::Specification.new do |s|
s.name = "json"
- s.version = version
+ s.version = File.read(File.expand_path('../VERSION', __FILE__)).chomp
s.summary = "JSON Implementation for Ruby"
s.description = "This is a JSON implementation as a Ruby extension in C."
@@ -19,6 +17,7 @@ Gem::Specification.new do |s|
"CHANGES.md",
"LICENSE",
"README.md",
+ "VERSION",
"ext/json/ext/fbuffer/fbuffer.h",
"ext/json/ext/generator/depend",
"ext/json/ext/generator/extconf.rb",
@@ -54,12 +53,12 @@ Gem::Specification.new do |s|
"lib/json/pure/parser.rb",
"lib/json/version.rb",
]
- s.homepage = "https://flori.github.io/json"
+ s.homepage = "http://flori.github.com/json"
s.metadata = {
'bug_tracker_uri' => 'https://github.com/flori/json/issues',
'changelog_uri' => 'https://github.com/flori/json/blob/master/CHANGES.md',
- 'documentation_uri' => 'https://flori.github.io/json/doc/index.html',
- 'homepage_uri' => s.homepage,
+ 'documentation_uri' => 'http://flori.github.io/json/doc/index.html',
+ 'homepage_uri' => 'http://flori.github.io/json/',
'source_code_uri' => 'https://github.com/flori/json',
'wiki_uri' => 'https://github.com/flori/json/wiki'
}
diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb
index 807488ffef..1e64bfcb1a 100644
--- a/ext/json/lib/json.rb
+++ b/ext/json/lib/json.rb
@@ -285,15 +285,6 @@ require 'json/common'
# # Raises JSON::NestingError (nesting of 2 is too deep):
# JSON.generate(obj, max_nesting: 2)
#
-# ====== Escaping Options
-#
-# Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, <tt>'\u2029'</tt>
-# and <tt>'/'</tt> should be escaped as to make the JSON object safe to interpolate in script
-# tags.
-#
-# Options +ascii_only+ (boolean) specifies wether all characters outside the ASCII range
-# should be escaped.
-#
# ====== Output Options
#
# The default formatting options generate the most compact
diff --git a/ext/json/lib/json/add/bigdecimal.rb b/ext/json/lib/json/add/bigdecimal.rb
index b1d0cfa043..c8b4f567cb 100644
--- a/ext/json/lib/json/add/bigdecimal.rb
+++ b/ext/json/lib/json/add/bigdecimal.rb
@@ -2,36 +2,19 @@
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
-begin
- require 'bigdecimal'
-rescue LoadError
-end
+defined?(::BigDecimal) or require 'bigdecimal'
class BigDecimal
-
- # See #as_json.
+ # Import a JSON Marshalled object.
+ #
+ # method used for JSON marshalling support.
def self.json_create(object)
BigDecimal._load object['b']
end
- # Methods <tt>BigDecimal#as_json</tt> and +BigDecimal.json_create+ may be used
- # to serialize and deserialize a \BigDecimal object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>BigDecimal#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/bigdecimal'
- # x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
- # y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"}
- # z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object:
- #
- # BigDecimal.json_create(x) # => 0.2e1
- # BigDecimal.json_create(y) # => 0.2e1
- # BigDecimal.json_create(z) # => 0.2e1
+ # Marshal the object to JSON.
#
+ # method used for JSON marshalling support.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -39,20 +22,8 @@ class BigDecimal
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/bigdecimal'
- # puts BigDecimal(2).to_json
- # puts BigDecimal(2.0, 4).to_json
- # puts BigDecimal(Complex(2, 0)).to_json
- #
- # Output:
- #
- # {"json_class":"BigDecimal","b":"27:0.2e1"}
- # {"json_class":"BigDecimal","b":"36:0.2e1"}
- # {"json_class":"BigDecimal","b":"27:0.2e1"}
- #
+ # return the JSON value
def to_json(*args)
as_json.to_json(*args)
end
-end if defined?(::BigDecimal)
+end
diff --git a/ext/json/lib/json/add/complex.rb b/ext/json/lib/json/add/complex.rb
index ef48c554c6..e63e29fd22 100644
--- a/ext/json/lib/json/add/complex.rb
+++ b/ext/json/lib/json/add/complex.rb
@@ -5,27 +5,14 @@ end
class Complex
- # See #as_json.
+ # Deserializes JSON string by converting Real value <tt>r</tt>, imaginary
+ # value <tt>i</tt>, to a Complex object.
def self.json_create(object)
Complex(object['r'], object['i'])
end
- # Methods <tt>Complex#as_json</tt> and +Complex.json_create+ may be used
- # to serialize and deserialize a \Complex object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Complex#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/complex'
- # x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0}
- # y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Complex object:
- #
- # Complex.json_create(x) # => (2+0i)
- # Complex.json_create(y) # => (2.0+4i)
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -34,17 +21,7 @@ class Complex
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/complex'
- # puts Complex(2).to_json
- # puts Complex(2.0, 4).to_json
- #
- # Output:
- #
- # {"json_class":"Complex","r":2,"i":0}
- # {"json_class":"Complex","r":2.0,"i":4}
- #
+ # Stores class name (Complex) along with real value <tt>r</tt> and imaginary value <tt>i</tt> as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/date.rb b/ext/json/lib/json/add/date.rb
index 19688f751b..25523561a5 100644
--- a/ext/json/lib/json/add/date.rb
+++ b/ext/json/lib/json/add/date.rb
@@ -6,29 +6,16 @@ require 'date'
class Date
- # See #as_json.
+ # Deserializes JSON string by converting Julian year <tt>y</tt>, month
+ # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date.
def self.json_create(object)
civil(*object.values_at('y', 'm', 'd', 'sg'))
end
alias start sg unless method_defined?(:start)
- # Methods <tt>Date#as_json</tt> and +Date.json_create+ may be used
- # to serialize and deserialize a \Date object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Date#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/date'
- # x = Date.today.as_json
- # # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Date object:
- #
- # Date.json_create(x)
- # # => #<Date: 2023-11-21 ((2460270j,0s,0n),+0s,2299161j)>
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -39,15 +26,8 @@ class Date
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/date'
- # puts Date.today.to_json
- #
- # Output:
- #
- # {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0}
- #
+ # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day
+ # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/date_time.rb b/ext/json/lib/json/add/date_time.rb
index d7d42591cf..38b0e86ab8 100644
--- a/ext/json/lib/json/add/date_time.rb
+++ b/ext/json/lib/json/add/date_time.rb
@@ -6,7 +6,9 @@ require 'date'
class DateTime
- # See #as_json.
+ # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
+ # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
+ # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime.
def self.json_create(object)
args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
of_a, of_b = object['of'].split('/')
@@ -21,21 +23,8 @@ class DateTime
alias start sg unless method_defined?(:start)
- # Methods <tt>DateTime#as_json</tt> and +DateTime.json_create+ may be used
- # to serialize and deserialize a \DateTime object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>DateTime#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/datetime'
- # x = DateTime.now.as_json
- # # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \DateTime object:
- #
- # DateTime.json_create(x) # BUG? Raises Date::Error "invalid date"
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -50,15 +39,9 @@ class DateTime
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/datetime'
- # puts DateTime.now.to_json
- #
- # Output:
- #
- # {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0}
- #
+ # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>,
+ # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
+ # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/exception.rb b/ext/json/lib/json/add/exception.rb
index 71d8deb0ea..a107e5b3c4 100644
--- a/ext/json/lib/json/add/exception.rb
+++ b/ext/json/lib/json/add/exception.rb
@@ -5,27 +5,16 @@ end
class Exception
- # See #as_json.
+ # Deserializes JSON string by constructing new Exception object with message
+ # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt>
def self.json_create(object)
result = new(object['m'])
result.set_backtrace object['b']
result
end
- # Methods <tt>Exception#as_json</tt> and +Exception.json_create+ may be used
- # to serialize and deserialize a \Exception object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Exception#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/exception'
- # x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Exception object:
- #
- # Exception.json_create(x) # => #<Exception: Foo>
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -34,15 +23,8 @@ class Exception
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/exception'
- # puts Exception.new('Foo').to_json
- #
- # Output:
- #
- # {"json_class":"Exception","m":"Foo","b":null}
- #
+ # Stores class name (Exception) with message <tt>m</tt> and backtrace array
+ # <tt>b</tt> as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/ostruct.rb b/ext/json/lib/json/add/ostruct.rb
index 498de17178..686cf0025d 100644
--- a/ext/json/lib/json/add/ostruct.rb
+++ b/ext/json/lib/json/add/ostruct.rb
@@ -6,27 +6,14 @@ require 'ostruct'
class OpenStruct
- # See #as_json.
+ # Deserializes JSON string by constructing new Struct object with values
+ # <tt>t</tt> serialized by <tt>to_json</tt>.
def self.json_create(object)
new(object['t'] || object[:t])
end
- # Methods <tt>OpenStruct#as_json</tt> and +OpenStruct.json_create+ may be used
- # to serialize and deserialize a \OpenStruct object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>OpenStruct#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/ostruct'
- # x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json
- # # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct object:
- #
- # OpenStruct.json_create(x)
- # # => #<OpenStruct name='Rowdy', age=nil>
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
klass = self.class.name
klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
@@ -36,15 +23,8 @@ class OpenStruct
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/ostruct'
- # puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json
- #
- # Output:
- #
- # {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}}
- #
+ # Stores class name (OpenStruct) with this struct's values <tt>t</tt> as a
+ # JSON string.
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/range.rb b/ext/json/lib/json/add/range.rb
index 53f54ac372..93529fb1c4 100644
--- a/ext/json/lib/json/add/range.rb
+++ b/ext/json/lib/json/add/range.rb
@@ -5,29 +5,14 @@ end
class Range
- # See #as_json.
+ # Deserializes JSON string by constructing new Range object with arguments
+ # <tt>a</tt> serialized by <tt>to_json</tt>.
def self.json_create(object)
new(*object['a'])
end
- # Methods <tt>Range#as_json</tt> and +Range.json_create+ may be used
- # to serialize and deserialize a \Range object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Range#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/range'
- # x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]}
- # y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]}
- # z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Range object:
- #
- # Range.json_create(x) # => 1..4
- # Range.json_create(y) # => 1...4
- # Range.json_create(z) # => "a".."d"
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -35,19 +20,9 @@ class Range
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/range'
- # puts (1..4).to_json
- # puts (1...4).to_json
- # puts ('a'..'d').to_json
- #
- # Output:
- #
- # {"json_class":"Range","a":[1,4,false]}
- # {"json_class":"Range","a":[1,4,true]}
- # {"json_class":"Range","a":["a","d",false]}
- #
+ # Stores class name (Range) with JSON array of arguments <tt>a</tt> which
+ # include <tt>first</tt> (integer), <tt>last</tt> (integer), and
+ # <tt>exclude_end?</tt> (boolean) as JSON string.
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/rational.rb b/ext/json/lib/json/add/rational.rb
index 8c39a7db55..f776226046 100644
--- a/ext/json/lib/json/add/rational.rb
+++ b/ext/json/lib/json/add/rational.rb
@@ -4,28 +4,14 @@ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
end
class Rational
-
- # See #as_json.
+ # Deserializes JSON string by converting numerator value <tt>n</tt>,
+ # denominator value <tt>d</tt>, to a Rational object.
def self.json_create(object)
Rational(object['n'], object['d'])
end
- # Methods <tt>Rational#as_json</tt> and +Rational.json_create+ may be used
- # to serialize and deserialize a \Rational object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Rational#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/rational'
- # x = Rational(2, 3).as_json
- # # => {"json_class"=>"Rational", "n"=>2, "d"=>3}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Rational object:
- #
- # Rational.json_create(x)
- # # => (2/3)
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -34,15 +20,7 @@ class Rational
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/rational'
- # puts Rational(2, 3).to_json
- #
- # Output:
- #
- # {"json_class":"Rational","n":2,"d":3}
- #
+ # Stores class name (Rational) along with numerator value <tt>n</tt> and denominator value <tt>d</tt> as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/regexp.rb b/ext/json/lib/json/add/regexp.rb
index b63f49608f..39d69fede7 100644
--- a/ext/json/lib/json/add/regexp.rb
+++ b/ext/json/lib/json/add/regexp.rb
@@ -5,26 +5,15 @@ end
class Regexp
- # See #as_json.
+ # Deserializes JSON string by constructing new Regexp object with source
+ # <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by
+ # <tt>to_json</tt>
def self.json_create(object)
new(object['s'], object['o'])
end
- # Methods <tt>Regexp#as_json</tt> and +Regexp.json_create+ may be used
- # to serialize and deserialize a \Regexp object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Regexp#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/regexp'
- # x = /foo/.as_json
- # # => {"json_class"=>"Regexp", "o"=>0, "s"=>"foo"}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Regexp object:
- #
- # Regexp.json_create(x) # => /foo/
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -33,15 +22,8 @@ class Regexp
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/regexp'
- # puts /foo/.to_json
- #
- # Output:
- #
- # {"json_class":"Regexp","o":0,"s":"foo"}
- #
+ # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
+ # (Regexp or String) as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/set.rb b/ext/json/lib/json/add/set.rb
index 1918353187..71e2a0ac8b 100644
--- a/ext/json/lib/json/add/set.rb
+++ b/ext/json/lib/json/add/set.rb
@@ -4,27 +4,16 @@ end
defined?(::Set) or require 'set'
class Set
-
- # See #as_json.
+ # Import a JSON Marshalled object.
+ #
+ # method used for JSON marshalling support.
def self.json_create(object)
new object['a']
end
- # Methods <tt>Set#as_json</tt> and +Set.json_create+ may be used
- # to serialize and deserialize a \Set object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Set#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/set'
- # x = Set.new(%w/foo bar baz/).as_json
- # # => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Set object:
- #
- # Set.json_create(x) # => #<Set: {"foo", "bar", "baz"}>
+ # Marshal the object to JSON.
#
+ # method used for JSON marshalling support.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -32,15 +21,7 @@ class Set
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/set'
- # puts Set.new(%w/foo bar baz/).to_json
- #
- # Output:
- #
- # {"json_class":"Set","a":["foo","bar","baz"]}
- #
+ # return the JSON value
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/struct.rb b/ext/json/lib/json/add/struct.rb
index 86847762ac..e8395ed42f 100644
--- a/ext/json/lib/json/add/struct.rb
+++ b/ext/json/lib/json/add/struct.rb
@@ -5,28 +5,14 @@ end
class Struct
- # See #as_json.
+ # Deserializes JSON string by constructing new Struct object with values
+ # <tt>v</tt> serialized by <tt>to_json</tt>.
def self.json_create(object)
new(*object['v'])
end
- # Methods <tt>Struct#as_json</tt> and +Struct.json_create+ may be used
- # to serialize and deserialize a \Struct object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Struct#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/struct'
- # Customer = Struct.new('Customer', :name, :address, :zip)
- # x = Struct::Customer.new.as_json
- # # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Struct object:
- #
- # Struct::Customer.json_create(x)
- # # => #<struct Struct::Customer name=nil, address=nil, zip=nil>
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
klass = self.class.name
klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
@@ -36,16 +22,8 @@ class Struct
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/struct'
- # Customer = Struct.new('Customer', :name, :address, :zip)
- # puts Struct::Customer.new.to_json
- #
- # Output:
- #
- # {"json_class":"Struct","t":{'name':'Rowdy',"age":null}}
- #
+ # Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string.
+ # Only named structs are supported.
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/add/symbol.rb b/ext/json/lib/json/add/symbol.rb
index b5f3623158..74b13a423f 100644
--- a/ext/json/lib/json/add/symbol.rb
+++ b/ext/json/lib/json/add/symbol.rb
@@ -1,26 +1,11 @@
-
#frozen_string_literal: false
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
class Symbol
-
- # Methods <tt>Symbol#as_json</tt> and +Symbol.json_create+ may be used
- # to serialize and deserialize a \Symbol object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Symbol#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/symbol'
- # x = :foo.as_json
- # # => {"json_class"=>"Symbol", "s"=>"foo"}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Symbol object:
- #
- # Symbol.json_create(x) # => :foo
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
{
JSON.create_id => self.class.name,
@@ -28,20 +13,12 @@ class Symbol
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/symbol'
- # puts :foo.to_json
- #
- # Output:
- #
- # # {"json_class":"Symbol","s":"foo"}
- #
+ # Stores class name (Symbol) with String representation of Symbol as a JSON string.
def to_json(*a)
as_json.to_json(*a)
end
- # See #as_json.
+ # Deserializes JSON string by converting the <tt>string</tt> value stored in the object to a Symbol
def self.json_create(o)
o['s'].to_sym
end
diff --git a/ext/json/lib/json/add/time.rb b/ext/json/lib/json/add/time.rb
index 599ed9e24b..b73acc4086 100644
--- a/ext/json/lib/json/add/time.rb
+++ b/ext/json/lib/json/add/time.rb
@@ -5,7 +5,7 @@ end
class Time
- # See #as_json.
+ # Deserializes JSON string by converting time since epoch to Time
def self.json_create(object)
if usec = object.delete('u') # used to be tv_usec -> tv_nsec
object['n'] = usec * 1000
@@ -17,22 +17,8 @@ class Time
end
end
- # Methods <tt>Time#as_json</tt> and +Time.json_create+ may be used
- # to serialize and deserialize a \Time object;
- # see Marshal[rdoc-ref:Marshal].
- #
- # \Method <tt>Time#as_json</tt> serializes +self+,
- # returning a 2-element hash representing +self+:
- #
- # require 'json/add/time'
- # x = Time.now.as_json
- # # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644}
- #
- # \Method +JSON.create+ deserializes such a hash, returning a \Time object:
- #
- # Time.json_create(x)
- # # => 2023-11-25 11:00:56.472846644 -0600
- #
+ # Returns a hash, that will be turned into a JSON object and represent this
+ # object.
def as_json(*)
nanoseconds = [ tv_usec * 1000 ]
respond_to?(:tv_nsec) and nanoseconds << tv_nsec
@@ -44,15 +30,8 @@ class Time
}
end
- # Returns a JSON string representing +self+:
- #
- # require 'json/add/time'
- # puts Time.now.to_json
- #
- # Output:
- #
- # {"json_class":"Time","s":1700931678,"n":980650786}
- #
+ # Stores class name (Time) with number of seconds since epoch and number of
+ # microseconds for Time as JSON string
def to_json(*args)
as_json.to_json(*args)
end
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index 090066012d..ea46896fcc 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -3,9 +3,6 @@ require 'json/version'
require 'json/generic_object'
module JSON
- NOT_SET = Object.new.freeze
- private_constant :NOT_SET
-
class << self
# :call-seq:
# JSON[object] -> new_array or new_string
@@ -298,9 +295,19 @@ module JSON
#
def generate(obj, opts = nil)
if State === opts
- state = opts
+ state, opts = opts, nil
else
- state = State.new(opts)
+ state = State.new
+ end
+ if opts
+ if opts.respond_to? :to_hash
+ opts = opts.to_hash
+ elsif opts.respond_to? :to_h
+ opts = opts.to_h
+ else
+ raise TypeError, "can't convert #{opts.class} into Hash"
+ end
+ state = state.configure(opts)
end
state.generate(obj)
end
@@ -327,9 +334,19 @@ module JSON
# JSON.fast_generate(a)
def fast_generate(obj, opts = nil)
if State === opts
- state = opts
+ state, opts = opts, nil
else
- state = JSON.create_fast_state.configure(opts)
+ state = JSON.create_fast_state
+ end
+ if opts
+ if opts.respond_to? :to_hash
+ opts = opts.to_hash
+ elsif opts.respond_to? :to_h
+ opts = opts.to_h
+ else
+ raise TypeError, "can't convert #{opts.class} into Hash"
+ end
+ state.configure(opts)
end
state.generate(obj)
end
@@ -575,13 +592,13 @@ module JSON
# Sets or returns the default options for the JSON.dump method.
# Initially:
# opts = JSON.dump_default_options
- # opts # => {:max_nesting=>false, :allow_nan=>true, :script_safe=>false}
+ # opts # => {:max_nesting=>false, :allow_nan=>true, :escape_slash=>false}
attr_accessor :dump_default_options
end
self.dump_default_options = {
:max_nesting => false,
:allow_nan => true,
- :script_safe => false,
+ :escape_slash => false,
}
# :call-seq:
@@ -611,18 +628,16 @@ module JSON
# puts File.read(path)
# Output:
# {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
- def dump(obj, anIO = nil, limit = nil, kwargs = nil)
- io_limit_opt = [anIO, limit, kwargs].compact
- kwargs = io_limit_opt.pop if io_limit_opt.last.is_a?(Hash)
- anIO, limit = io_limit_opt
- if anIO.respond_to?(:to_io)
- anIO = anIO.to_io
- elsif limit.nil? && !anIO.respond_to?(:write)
- anIO, limit = nil, anIO
+ def dump(obj, anIO = nil, limit = nil)
+ if anIO and limit.nil?
+ anIO = anIO.to_io if anIO.respond_to?(:to_io)
+ unless anIO.respond_to?(:write)
+ limit = anIO
+ anIO = nil
+ end
end
opts = JSON.dump_default_options
opts = opts.merge(:max_nesting => limit) if limit
- opts = merge_dump_options(opts, **kwargs) if kwargs
result = generate(obj, opts)
if anIO
anIO.write result
@@ -638,15 +653,6 @@ module JSON
def self.iconv(to, from, string)
string.encode(to, from)
end
-
- def merge_dump_options(opts, strict: NOT_SET)
- opts = opts.merge(strict: strict) if NOT_SET != strict
- opts
- end
-
- class << self
- private :merge_dump_options
- end
end
module ::Kernel
diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb
index b43ceecdcd..3d4326d836 100644
--- a/ext/json/lib/json/version.rb
+++ b/ext/json/lib/json/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module JSON
# JSON version
- VERSION = '2.7.1'
+ VERSION = '2.6.3'
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
diff --git a/ext/json/parser/depend b/ext/json/parser/depend
index cb6e547d29..a8e066ce15 100644
--- a/ext/json/parser/depend
+++ b/ext/json/parser/depend
@@ -56,7 +56,6 @@ parser.o: $(hdrdir)/ruby/internal/attr/noexcept.h
parser.o: $(hdrdir)/ruby/internal/attr/noinline.h
parser.o: $(hdrdir)/ruby/internal/attr/nonnull.h
parser.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-parser.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
parser.o: $(hdrdir)/ruby/internal/attr/pure.h
parser.o: $(hdrdir)/ruby/internal/attr/restrict.h
parser.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -125,6 +124,7 @@ parser.o: $(hdrdir)/ruby/internal/intern/enumerator.h
parser.o: $(hdrdir)/ruby/internal/intern/error.h
parser.o: $(hdrdir)/ruby/internal/intern/eval.h
parser.o: $(hdrdir)/ruby/internal/intern/file.h
+parser.o: $(hdrdir)/ruby/internal/intern/gc.h
parser.o: $(hdrdir)/ruby/internal/intern/hash.h
parser.o: $(hdrdir)/ruby/internal/intern/io.h
parser.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -155,6 +155,7 @@ parser.o: $(hdrdir)/ruby/internal/memory.h
parser.o: $(hdrdir)/ruby/internal/method.h
parser.o: $(hdrdir)/ruby/internal/module.h
parser.o: $(hdrdir)/ruby/internal/newobj.h
+parser.o: $(hdrdir)/ruby/internal/rgengc.h
parser.o: $(hdrdir)/ruby/internal/scan_args.h
parser.o: $(hdrdir)/ruby/internal/special_consts.h
parser.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/json/parser/extconf.rb b/ext/json/parser/extconf.rb
index feb586e1b4..4723a02aee 100644
--- a/ext/json/parser/extconf.rb
+++ b/ext/json/parser/extconf.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: false
require 'mkmf'
-have_func("rb_enc_raise", "ruby.h")
-have_func("rb_enc_interned_str", "ruby.h")
+have_func("rb_enc_raise", "ruby/encoding.h")
+have_func("rb_enc_interned_str", "ruby/encoding.h")
# checking if String#-@ (str_uminus) dedupes... '
begin
diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c
index 57f87432b6..9bd7f1971e 100644
--- a/ext/json/parser/parser.c
+++ b/ext/json/parser/parser.c
@@ -9,14 +9,14 @@
static void
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
{
- va_list args;
- VALUE mesg;
+ va_list args;
+ VALUE mesg;
- va_start(args, fmt);
- mesg = rb_enc_vsprintf(enc, fmt, args);
- va_end(args);
+ va_start(args, fmt);
+ mesg = rb_enc_vsprintf(enc, fmt, args);
+ va_end(args);
- rb_exc_raise(rb_exc_new3(exc, mesg));
+ rb_exc_raise(rb_exc_new3(exc, mesg));
}
# define rb_enc_raise enc_raise
# endif
@@ -28,2184 +28,3320 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
/* unicode */
static const signed char digit_values[256] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
- -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
+ -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1
};
static UTF32 unescape_unicode(const unsigned char *p)
{
- signed char b;
- UTF32 result = 0;
- b = digit_values[p[0]];
- if (b < 0) return UNI_REPLACEMENT_CHAR;
- result = (result << 4) | (unsigned char)b;
- b = digit_values[p[1]];
- if (b < 0) return UNI_REPLACEMENT_CHAR;
- result = (result << 4) | (unsigned char)b;
- b = digit_values[p[2]];
- if (b < 0) return UNI_REPLACEMENT_CHAR;
- result = (result << 4) | (unsigned char)b;
- b = digit_values[p[3]];
- if (b < 0) return UNI_REPLACEMENT_CHAR;
- result = (result << 4) | (unsigned char)b;
- return result;
+ signed char b;
+ UTF32 result = 0;
+ b = digit_values[p[0]];
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
+ result = (result << 4) | (unsigned char)b;
+ b = digit_values[p[1]];
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
+ result = (result << 4) | (unsigned char)b;
+ b = digit_values[p[2]];
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
+ result = (result << 4) | (unsigned char)b;
+ b = digit_values[p[3]];
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
+ result = (result << 4) | (unsigned char)b;
+ return result;
}
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
{
- int len = 1;
- if (ch <= 0x7F) {
- buf[0] = (char) ch;
- } else if (ch <= 0x07FF) {
- buf[0] = (char) ((ch >> 6) | 0xC0);
- buf[1] = (char) ((ch & 0x3F) | 0x80);
- len++;
- } else if (ch <= 0xFFFF) {
- buf[0] = (char) ((ch >> 12) | 0xE0);
- buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
- buf[2] = (char) ((ch & 0x3F) | 0x80);
- len += 2;
- } else if (ch <= 0x1fffff) {
- buf[0] =(char) ((ch >> 18) | 0xF0);
- buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
- buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
- buf[3] =(char) ((ch & 0x3F) | 0x80);
- len += 3;
- } else {
- buf[0] = '?';
- }
- return len;
+ int len = 1;
+ if (ch <= 0x7F) {
+ buf[0] = (char) ch;
+ } else if (ch <= 0x07FF) {
+ buf[0] = (char) ((ch >> 6) | 0xC0);
+ buf[1] = (char) ((ch & 0x3F) | 0x80);
+ len++;
+ } else if (ch <= 0xFFFF) {
+ buf[0] = (char) ((ch >> 12) | 0xE0);
+ buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
+ buf[2] = (char) ((ch & 0x3F) | 0x80);
+ len += 2;
+ } else if (ch <= 0x1fffff) {
+ buf[0] =(char) ((ch >> 18) | 0xF0);
+ buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
+ buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
+ buf[3] =(char) ((ch & 0x3F) | 0x80);
+ len += 3;
+ } else {
+ buf[0] = '?';
+ }
+ return len;
}
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
static VALUE CNaN, CInfinity, CMinusInfinity;
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
- i_object_class, i_array_class, i_decimal_class, i_key_p,
- i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
- i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
+i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
+i_object_class, i_array_class, i_decimal_class, i_key_p,
+i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
+i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
#line 125 "parser.rl"
-#line 107 "parser.c"
enum {JSON_object_start = 1};
enum {JSON_object_first_final = 27};
enum {JSON_object_error = 0};
enum {JSON_object_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_object_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_object_nfa_offsets)[] = {
+ 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, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_object_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_object_nfa_pop_trans)[] = {
+ 0, 0
+};
+
#line 167 "parser.rl"
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
{
- int cs = EVIL;
- VALUE last_name = Qnil;
- VALUE object_class = json->object_class;
+ int cs = EVIL;
+ VALUE last_name = Qnil;
+ VALUE object_class = json->object_class;
- if (json->max_nesting && current_nesting > json->max_nesting) {
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
- }
+ if (json->max_nesting && current_nesting > json->max_nesting) {
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
+ }
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
+ *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
-#line 131 "parser.c"
{
- cs = JSON_object_start;
+ cs = (int)JSON_object_start;
}
-#line 182 "parser.rl"
+ #line 182 "parser.rl"
+
-#line 138 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-case 1:
- if ( (*p) == 123 )
- goto st2;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-st2:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 2:
+ goto st_case_2;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 5:
+ goto st_case_5;
+ case 6:
+ goto st_case_6;
+ case 7:
+ goto st_case_7;
+ case 8:
+ goto st_case_8;
+ case 9:
+ goto st_case_9;
+ case 10:
+ goto st_case_10;
+ case 11:
+ goto st_case_11;
+ case 12:
+ goto st_case_12;
+ case 13:
+ goto st_case_13;
+ case 14:
+ goto st_case_14;
+ case 15:
+ goto st_case_15;
+ case 16:
+ goto st_case_16;
+ case 17:
+ goto st_case_17;
+ case 18:
+ goto st_case_18;
+ case 27:
+ goto st_case_27;
+ case 19:
+ goto st_case_19;
+ case 20:
+ goto st_case_20;
+ case 21:
+ goto st_case_21;
+ case 22:
+ goto st_case_22;
+ case 23:
+ goto st_case_23;
+ case 24:
+ goto st_case_24;
+ case 25:
+ goto st_case_25;
+ case 26:
+ goto st_case_26;
+ }
+ goto st_out;
+ st_case_1:
+ if ( ( (*( p))) == 123 ) {
+ goto st2;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- switch( (*p) ) {
- case 13: goto st2;
- case 32: goto st2;
- case 34: goto tr2;
- case 47: goto st23;
- case 125: goto tr4;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
- goto st2;
- goto st0;
-tr2:
-#line 149 "parser.rl"
- {
- char *np;
- json->parsing_name = 1;
- np = JSON_parse_string(json, p, pe, &last_name);
- json->parsing_name = 0;
- if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
- }
- goto st3;
-st3:
- if ( ++p == pe )
- goto _test_eof3;
-case 3:
-#line 179 "parser.c"
- switch( (*p) ) {
- case 13: goto st3;
- case 32: goto st3;
- case 47: goto st4;
- case 58: goto st8;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
+ st_case_2:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st2;
+ }
+ case 32: {
+ goto st2;
+ }
+ case 34: {
+ goto ctr2;
+ }
+ case 47: {
+ goto st23;
+ }
+ case 125: {
+ goto ctr4;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st2;
+ }
+ {
+ goto st0;
+ }
+ ctr2:
+ {
+ #line 149 "parser.rl"
+
+ char *np;
+ json->parsing_name = 1;
+ np = JSON_parse_string(json, p, pe, &last_name);
+ json->parsing_name = 0;
+ if (np == NULL) { {p = p - 1; } {p+= 1; cs = 3; goto _out;} } else {p = (( np))-1;}
+
+ }
+
goto st3;
- goto st0;
-st4:
- if ( ++p == pe )
+ st3:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof3;
+ st_case_3:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st3;
+ }
+ case 32: {
+ goto st3;
+ }
+ case 47: {
+ goto st4;
+ }
+ case 58: {
+ goto st8;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st3;
+ }
+ {
+ goto st0;
+ }
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
- switch( (*p) ) {
- case 42: goto st5;
- case 47: goto st7;
- }
- goto st0;
-st5:
- if ( ++p == pe )
+ st_case_4:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st5;
+ }
+ case 47: {
+ goto st7;
+ }
+ }
+ {
+ goto st0;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- if ( (*p) == 42 )
- goto st6;
- goto st5;
-st6:
- if ( ++p == pe )
+ st_case_5:
+ if ( ( (*( p))) == 42 ) {
+ goto st6;
+ }
+ {
+ goto st5;
+ }
+ st6:
+ p+= 1;
+ if ( p == pe )
goto _test_eof6;
-case 6:
- switch( (*p) ) {
- case 42: goto st6;
- case 47: goto st3;
- }
- goto st5;
-st7:
- if ( ++p == pe )
+ st_case_6:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st6;
+ }
+ case 47: {
+ goto st3;
+ }
+ }
+ {
+ goto st5;
+ }
+ st7:
+ p+= 1;
+ if ( p == pe )
goto _test_eof7;
-case 7:
- if ( (*p) == 10 )
- goto st3;
- goto st7;
-st8:
- if ( ++p == pe )
+ st_case_7:
+ if ( ( (*( p))) == 10 ) {
+ goto st3;
+ }
+ {
+ goto st7;
+ }
+ st8:
+ p+= 1;
+ if ( p == pe )
goto _test_eof8;
-case 8:
- switch( (*p) ) {
- case 13: goto st8;
- case 32: goto st8;
- case 34: goto tr11;
- case 45: goto tr11;
- case 47: goto st19;
- case 73: goto tr11;
- case 78: goto tr11;
- case 91: goto tr11;
- case 102: goto tr11;
- case 110: goto tr11;
- case 116: goto tr11;
- case 123: goto tr11;
- }
- if ( (*p) > 10 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto tr11;
- } else if ( (*p) >= 9 )
- goto st8;
- goto st0;
-tr11:
-#line 133 "parser.rl"
- {
- VALUE v = Qnil;
- char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
- if (np == NULL) {
- p--; {p++; cs = 9; goto _out;}
- } else {
- if (NIL_P(json->object_class)) {
- OBJ_FREEZE(last_name);
- rb_hash_aset(*result, last_name, v);
- } else {
- rb_funcall(*result, i_aset, 2, last_name, v);
- }
- {p = (( np))-1;}
- }
- }
- goto st9;
-st9:
- if ( ++p == pe )
- goto _test_eof9;
-case 9:
-#line 267 "parser.c"
- switch( (*p) ) {
- case 13: goto st9;
- case 32: goto st9;
- case 44: goto st10;
- case 47: goto st15;
- case 125: goto tr4;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
+ st_case_8:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st8;
+ }
+ case 32: {
+ goto st8;
+ }
+ case 34: {
+ goto ctr11;
+ }
+ case 45: {
+ goto ctr11;
+ }
+ case 47: {
+ goto st19;
+ }
+ case 73: {
+ goto ctr11;
+ }
+ case 78: {
+ goto ctr11;
+ }
+ case 91: {
+ goto ctr11;
+ }
+ case 102: {
+ goto ctr11;
+ }
+ case 110: {
+ goto ctr11;
+ }
+ case 116: {
+ goto ctr11;
+ }
+ case 123: {
+ goto ctr11;
+ }
+ }
+ if ( ( (*( p))) > 10 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto ctr11;
+ }
+ } else if ( ( (*( p))) >= 9 ) {
+ goto st8;
+ }
+ {
+ goto st0;
+ }
+ ctr11:
+ {
+ #line 133 "parser.rl"
+
+ VALUE v = Qnil;
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
+ if (np == NULL) {
+ {p = p - 1; } {p+= 1; cs = 9; goto _out;}
+ } else {
+ if (NIL_P(json->object_class)) {
+ OBJ_FREEZE(last_name);
+ rb_hash_aset(*result, last_name, v);
+ } else {
+ rb_funcall(*result, i_aset, 2, last_name, v);
+ }
+ {p = (( np))-1;}
+
+ }
+ }
+
goto st9;
- goto st0;
-st10:
- if ( ++p == pe )
+ st9:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof9;
+ st_case_9:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st9;
+ }
+ case 32: {
+ goto st9;
+ }
+ case 44: {
+ goto st10;
+ }
+ case 47: {
+ goto st15;
+ }
+ case 125: {
+ goto ctr4;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st9;
+ }
+ {
+ goto st0;
+ }
+ st10:
+ p+= 1;
+ if ( p == pe )
goto _test_eof10;
-case 10:
- switch( (*p) ) {
- case 13: goto st10;
- case 32: goto st10;
- case 34: goto tr2;
- case 47: goto st11;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
- goto st10;
- goto st0;
-st11:
- if ( ++p == pe )
+ st_case_10:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st10;
+ }
+ case 32: {
+ goto st10;
+ }
+ case 34: {
+ goto ctr2;
+ }
+ case 47: {
+ goto st11;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st10;
+ }
+ {
+ goto st0;
+ }
+ st11:
+ p+= 1;
+ if ( p == pe )
goto _test_eof11;
-case 11:
- switch( (*p) ) {
- case 42: goto st12;
- case 47: goto st14;
- }
- goto st0;
-st12:
- if ( ++p == pe )
+ st_case_11:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st12;
+ }
+ case 47: {
+ goto st14;
+ }
+ }
+ {
+ goto st0;
+ }
+ st12:
+ p+= 1;
+ if ( p == pe )
goto _test_eof12;
-case 12:
- if ( (*p) == 42 )
- goto st13;
- goto st12;
-st13:
- if ( ++p == pe )
+ st_case_12:
+ if ( ( (*( p))) == 42 ) {
+ goto st13;
+ }
+ {
+ goto st12;
+ }
+ st13:
+ p+= 1;
+ if ( p == pe )
goto _test_eof13;
-case 13:
- switch( (*p) ) {
- case 42: goto st13;
- case 47: goto st10;
- }
- goto st12;
-st14:
- if ( ++p == pe )
+ st_case_13:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st13;
+ }
+ case 47: {
+ goto st10;
+ }
+ }
+ {
+ goto st12;
+ }
+ st14:
+ p+= 1;
+ if ( p == pe )
goto _test_eof14;
-case 14:
- if ( (*p) == 10 )
- goto st10;
- goto st14;
-st15:
- if ( ++p == pe )
+ st_case_14:
+ if ( ( (*( p))) == 10 ) {
+ goto st10;
+ }
+ {
+ goto st14;
+ }
+ st15:
+ p+= 1;
+ if ( p == pe )
goto _test_eof15;
-case 15:
- switch( (*p) ) {
- case 42: goto st16;
- case 47: goto st18;
- }
- goto st0;
-st16:
- if ( ++p == pe )
+ st_case_15:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st16;
+ }
+ case 47: {
+ goto st18;
+ }
+ }
+ {
+ goto st0;
+ }
+ st16:
+ p+= 1;
+ if ( p == pe )
goto _test_eof16;
-case 16:
- if ( (*p) == 42 )
- goto st17;
- goto st16;
-st17:
- if ( ++p == pe )
+ st_case_16:
+ if ( ( (*( p))) == 42 ) {
+ goto st17;
+ }
+ {
+ goto st16;
+ }
+ st17:
+ p+= 1;
+ if ( p == pe )
goto _test_eof17;
-case 17:
- switch( (*p) ) {
- case 42: goto st17;
- case 47: goto st9;
- }
- goto st16;
-st18:
- if ( ++p == pe )
+ st_case_17:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st17;
+ }
+ case 47: {
+ goto st9;
+ }
+ }
+ {
+ goto st16;
+ }
+ st18:
+ p+= 1;
+ if ( p == pe )
goto _test_eof18;
-case 18:
- if ( (*p) == 10 )
- goto st9;
- goto st18;
-tr4:
-#line 157 "parser.rl"
- { p--; {p++; cs = 27; goto _out;} }
- goto st27;
-st27:
- if ( ++p == pe )
+ st_case_18:
+ if ( ( (*( p))) == 10 ) {
+ goto st9;
+ }
+ {
+ goto st18;
+ }
+ ctr4:
+ {
+ #line 157 "parser.rl"
+ {p = p - 1; } {p+= 1; cs = 27; goto _out;} }
+
+ goto st27;
+ st27:
+ p+= 1;
+ if ( p == pe )
goto _test_eof27;
-case 27:
-#line 363 "parser.c"
- goto st0;
-st19:
- if ( ++p == pe )
+ st_case_27:
+ {
+ goto st0;
+ }
+ st19:
+ p+= 1;
+ if ( p == pe )
goto _test_eof19;
-case 19:
- switch( (*p) ) {
- case 42: goto st20;
- case 47: goto st22;
- }
- goto st0;
-st20:
- if ( ++p == pe )
+ st_case_19:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st20;
+ }
+ case 47: {
+ goto st22;
+ }
+ }
+ {
+ goto st0;
+ }
+ st20:
+ p+= 1;
+ if ( p == pe )
goto _test_eof20;
-case 20:
- if ( (*p) == 42 )
- goto st21;
- goto st20;
-st21:
- if ( ++p == pe )
+ st_case_20:
+ if ( ( (*( p))) == 42 ) {
+ goto st21;
+ }
+ {
+ goto st20;
+ }
+ st21:
+ p+= 1;
+ if ( p == pe )
goto _test_eof21;
-case 21:
- switch( (*p) ) {
- case 42: goto st21;
- case 47: goto st8;
- }
- goto st20;
-st22:
- if ( ++p == pe )
+ st_case_21:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st21;
+ }
+ case 47: {
+ goto st8;
+ }
+ }
+ {
+ goto st20;
+ }
+ st22:
+ p+= 1;
+ if ( p == pe )
goto _test_eof22;
-case 22:
- if ( (*p) == 10 )
- goto st8;
- goto st22;
-st23:
- if ( ++p == pe )
+ st_case_22:
+ if ( ( (*( p))) == 10 ) {
+ goto st8;
+ }
+ {
+ goto st22;
+ }
+ st23:
+ p+= 1;
+ if ( p == pe )
goto _test_eof23;
-case 23:
- switch( (*p) ) {
- case 42: goto st24;
- case 47: goto st26;
- }
- goto st0;
-st24:
- if ( ++p == pe )
+ st_case_23:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st24;
+ }
+ case 47: {
+ goto st26;
+ }
+ }
+ {
+ goto st0;
+ }
+ st24:
+ p+= 1;
+ if ( p == pe )
goto _test_eof24;
-case 24:
- if ( (*p) == 42 )
- goto st25;
- goto st24;
-st25:
- if ( ++p == pe )
+ st_case_24:
+ if ( ( (*( p))) == 42 ) {
+ goto st25;
+ }
+ {
+ goto st24;
+ }
+ st25:
+ p+= 1;
+ if ( p == pe )
goto _test_eof25;
-case 25:
- switch( (*p) ) {
- case 42: goto st25;
- case 47: goto st2;
- }
- goto st24;
-st26:
- if ( ++p == pe )
+ st_case_25:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st25;
+ }
+ case 47: {
+ goto st2;
+ }
+ }
+ {
+ goto st24;
+ }
+ st26:
+ p+= 1;
+ if ( p == pe )
goto _test_eof26;
-case 26:
- if ( (*p) == 10 )
- goto st2;
- goto st26;
- }
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
- _test_eof6: cs = 6; goto _test_eof;
- _test_eof7: cs = 7; goto _test_eof;
- _test_eof8: cs = 8; goto _test_eof;
- _test_eof9: cs = 9; goto _test_eof;
- _test_eof10: cs = 10; goto _test_eof;
- _test_eof11: cs = 11; goto _test_eof;
- _test_eof12: cs = 12; goto _test_eof;
- _test_eof13: cs = 13; goto _test_eof;
- _test_eof14: cs = 14; goto _test_eof;
- _test_eof15: cs = 15; goto _test_eof;
- _test_eof16: cs = 16; goto _test_eof;
- _test_eof17: cs = 17; goto _test_eof;
- _test_eof18: cs = 18; goto _test_eof;
- _test_eof27: cs = 27; goto _test_eof;
- _test_eof19: cs = 19; goto _test_eof;
- _test_eof20: cs = 20; goto _test_eof;
- _test_eof21: cs = 21; goto _test_eof;
- _test_eof22: cs = 22; goto _test_eof;
- _test_eof23: cs = 23; goto _test_eof;
- _test_eof24: cs = 24; goto _test_eof;
- _test_eof25: cs = 25; goto _test_eof;
- _test_eof26: cs = 26; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ st_case_26:
+ if ( ( (*( p))) == 10 ) {
+ goto st2;
+ }
+ {
+ goto st26;
+ }
+ st_out:
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+ _test_eof18: cs = 18; goto _test_eof;
+ _test_eof27: cs = 27; goto _test_eof;
+ _test_eof19: cs = 19; goto _test_eof;
+ _test_eof20: cs = 20; goto _test_eof;
+ _test_eof21: cs = 21; goto _test_eof;
+ _test_eof22: cs = 22; goto _test_eof;
+ _test_eof23: cs = 23; goto _test_eof;
+ _test_eof24: cs = 24; goto _test_eof;
+ _test_eof25: cs = 25; goto _test_eof;
+ _test_eof26: cs = 26; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 183 "parser.rl"
+
+
+ if (cs >= JSON_object_first_final) {
+ if (json->create_additions) {
+ VALUE klassname;
+ if (NIL_P(json->object_class)) {
+ klassname = rb_hash_aref(*result, json->create_id);
+ } else {
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
+ }
+ if (!NIL_P(klassname)) {
+ VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
+ *result = rb_funcall(klass, i_json_create, 1, *result);
+ }
+ }
+ }
+ return p + 1;
+ } else {
+ return NULL;
}
-
-#line 183 "parser.rl"
-
- if (cs >= JSON_object_first_final) {
- if (json->create_additions) {
- VALUE klassname;
- if (NIL_P(json->object_class)) {
- klassname = rb_hash_aref(*result, json->create_id);
- } else {
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
- }
- if (!NIL_P(klassname)) {
- VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
- *result = rb_funcall(klass, i_json_create, 1, *result);
- }
- }
- }
- return p + 1;
- } else {
- return NULL;
- }
}
-#line 486 "parser.c"
enum {JSON_value_start = 1};
enum {JSON_value_first_final = 29};
enum {JSON_value_error = 0};
enum {JSON_value_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_value_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_value_nfa_offsets)[] = {
+ 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, 0, 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_value_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_value_nfa_pop_trans)[] = {
+ 0, 0
+};
+
#line 283 "parser.rl"
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
{
- int cs = EVIL;
+ int cs = EVIL;
-#line 502 "parser.c"
{
- cs = JSON_value_start;
+ cs = (int)JSON_value_start;
}
-#line 290 "parser.rl"
+ #line 290 "parser.rl"
+
-#line 509 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-st1:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 29:
+ goto st_case_29;
+ case 2:
+ goto st_case_2;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 5:
+ goto st_case_5;
+ case 6:
+ goto st_case_6;
+ case 7:
+ goto st_case_7;
+ case 8:
+ goto st_case_8;
+ case 9:
+ goto st_case_9;
+ case 10:
+ goto st_case_10;
+ case 11:
+ goto st_case_11;
+ case 12:
+ goto st_case_12;
+ case 13:
+ goto st_case_13;
+ case 14:
+ goto st_case_14;
+ case 15:
+ goto st_case_15;
+ case 16:
+ goto st_case_16;
+ case 17:
+ goto st_case_17;
+ case 18:
+ goto st_case_18;
+ case 19:
+ goto st_case_19;
+ case 20:
+ goto st_case_20;
+ case 21:
+ goto st_case_21;
+ case 22:
+ goto st_case_22;
+ case 23:
+ goto st_case_23;
+ case 24:
+ goto st_case_24;
+ case 25:
+ goto st_case_25;
+ case 26:
+ goto st_case_26;
+ case 27:
+ goto st_case_27;
+ case 28:
+ goto st_case_28;
+ }
+ goto st_out;
+ st1:
+ p+= 1;
+ if ( p == pe )
goto _test_eof1;
-case 1:
- switch( (*p) ) {
- case 13: goto st1;
- case 32: goto st1;
- case 34: goto tr2;
- case 45: goto tr3;
- case 47: goto st6;
- case 73: goto st10;
- case 78: goto st17;
- case 91: goto tr7;
- case 102: goto st19;
- case 110: goto st23;
- case 116: goto st26;
- case 123: goto tr11;
- }
- if ( (*p) > 10 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto tr3;
- } else if ( (*p) >= 9 )
- goto st1;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-tr2:
-#line 235 "parser.rl"
- {
- char *np = JSON_parse_string(json, p, pe, result);
- if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
- }
- goto st29;
-tr3:
-#line 240 "parser.rl"
- {
- char *np;
- if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
- if (json->allow_nan) {
- *result = CMinusInfinity;
- {p = (( p + 10))-1;}
- p--; {p++; cs = 29; goto _out;}
- } else {
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
- }
- }
- np = JSON_parse_float(json, p, pe, result);
- if (np != NULL) {p = (( np))-1;}
- np = JSON_parse_integer(json, p, pe, result);
- if (np != NULL) {p = (( np))-1;}
- p--; {p++; cs = 29; goto _out;}
- }
- goto st29;
-tr7:
-#line 258 "parser.rl"
- {
- char *np;
- np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
- if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
- }
- goto st29;
-tr11:
-#line 264 "parser.rl"
- {
- char *np;
- np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
- if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
- }
- goto st29;
-tr25:
-#line 228 "parser.rl"
- {
- if (json->allow_nan) {
- *result = CInfinity;
- } else {
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
- }
- }
- goto st29;
-tr27:
-#line 221 "parser.rl"
- {
- if (json->allow_nan) {
- *result = CNaN;
- } else {
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
- }
- }
- goto st29;
-tr31:
-#line 215 "parser.rl"
- {
- *result = Qfalse;
- }
- goto st29;
-tr34:
-#line 212 "parser.rl"
- {
- *result = Qnil;
- }
- goto st29;
-tr37:
-#line 218 "parser.rl"
- {
- *result = Qtrue;
- }
- goto st29;
-st29:
- if ( ++p == pe )
- goto _test_eof29;
-case 29:
-#line 270 "parser.rl"
- { p--; {p++; cs = 29; goto _out;} }
-#line 629 "parser.c"
- switch( (*p) ) {
- case 13: goto st29;
- case 32: goto st29;
- case 47: goto st2;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
+ st_case_1:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st1;
+ }
+ case 32: {
+ goto st1;
+ }
+ case 34: {
+ goto ctr2;
+ }
+ case 45: {
+ goto ctr3;
+ }
+ case 47: {
+ goto st6;
+ }
+ case 73: {
+ goto st10;
+ }
+ case 78: {
+ goto st17;
+ }
+ case 91: {
+ goto ctr7;
+ }
+ case 102: {
+ goto st19;
+ }
+ case 110: {
+ goto st23;
+ }
+ case 116: {
+ goto st26;
+ }
+ case 123: {
+ goto ctr11;
+ }
+ }
+ if ( ( (*( p))) > 10 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto ctr3;
+ }
+ } else if ( ( (*( p))) >= 9 ) {
+ goto st1;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ ctr2:
+ {
+ #line 235 "parser.rl"
+
+ char *np = JSON_parse_string(json, p, pe, result);
+ if (np == NULL) { {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else {p = (( np))-1;}
+
+ }
+
+ goto st29;
+ ctr3:
+ {
+ #line 240 "parser.rl"
+
+ char *np;
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
+ if (json->allow_nan) {
+ *result = CMinusInfinity;
+ {p = (( p + 10))-1;}
+
+ {p = p - 1; } {p+= 1; cs = 29; goto _out;}
+ } else {
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
+ }
+ }
+ np = JSON_parse_float(json, p, pe, result);
+ if (np != NULL) {p = (( np))-1;}
+
+ np = JSON_parse_integer(json, p, pe, result);
+ if (np != NULL) {p = (( np))-1;}
+
+ {p = p - 1; } {p+= 1; cs = 29; goto _out;}
+ }
+
+ goto st29;
+ ctr7:
+ {
+ #line 258 "parser.rl"
+
+ char *np;
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
+ if (np == NULL) { {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else {p = (( np))-1;}
+
+ }
+
+ goto st29;
+ ctr11:
+ {
+ #line 264 "parser.rl"
+
+ char *np;
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
+ if (np == NULL) { {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else {p = (( np))-1;}
+
+ }
+
+ goto st29;
+ ctr25:
+ {
+ #line 228 "parser.rl"
+
+ if (json->allow_nan) {
+ *result = CInfinity;
+ } else {
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 8);
+ }
+ }
+
+ goto st29;
+ ctr27:
+ {
+ #line 221 "parser.rl"
+
+ if (json->allow_nan) {
+ *result = CNaN;
+ } else {
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
+ }
+ }
+
+ goto st29;
+ ctr31:
+ {
+ #line 215 "parser.rl"
+
+ *result = Qfalse;
+ }
+
+ goto st29;
+ ctr34:
+ {
+ #line 212 "parser.rl"
+
+ *result = Qnil;
+ }
+
+ goto st29;
+ ctr37:
+ {
+ #line 218 "parser.rl"
+
+ *result = Qtrue;
+ }
+
goto st29;
- goto st0;
-st2:
- if ( ++p == pe )
+ st29:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof29;
+ st_case_29:
+ {
+ #line 270 "parser.rl"
+ {p = p - 1; } {p+= 1; cs = 29; goto _out;} }
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st29;
+ }
+ case 32: {
+ goto st29;
+ }
+ case 47: {
+ goto st2;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st29;
+ }
+ {
+ goto st0;
+ }
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- switch( (*p) ) {
- case 42: goto st3;
- case 47: goto st5;
- }
- goto st0;
-st3:
- if ( ++p == pe )
+ st_case_2:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st3;
+ }
+ case 47: {
+ goto st5;
+ }
+ }
+ {
+ goto st0;
+ }
+ st3:
+ p+= 1;
+ if ( p == pe )
goto _test_eof3;
-case 3:
- if ( (*p) == 42 )
- goto st4;
- goto st3;
-st4:
- if ( ++p == pe )
+ st_case_3:
+ if ( ( (*( p))) == 42 ) {
+ goto st4;
+ }
+ {
+ goto st3;
+ }
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
- switch( (*p) ) {
- case 42: goto st4;
- case 47: goto st29;
- }
- goto st3;
-st5:
- if ( ++p == pe )
+ st_case_4:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st4;
+ }
+ case 47: {
+ goto st29;
+ }
+ }
+ {
+ goto st3;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- if ( (*p) == 10 )
- goto st29;
- goto st5;
-st6:
- if ( ++p == pe )
+ st_case_5:
+ if ( ( (*( p))) == 10 ) {
+ goto st29;
+ }
+ {
+ goto st5;
+ }
+ st6:
+ p+= 1;
+ if ( p == pe )
goto _test_eof6;
-case 6:
- switch( (*p) ) {
- case 42: goto st7;
- case 47: goto st9;
- }
- goto st0;
-st7:
- if ( ++p == pe )
+ st_case_6:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st7;
+ }
+ case 47: {
+ goto st9;
+ }
+ }
+ {
+ goto st0;
+ }
+ st7:
+ p+= 1;
+ if ( p == pe )
goto _test_eof7;
-case 7:
- if ( (*p) == 42 )
- goto st8;
- goto st7;
-st8:
- if ( ++p == pe )
+ st_case_7:
+ if ( ( (*( p))) == 42 ) {
+ goto st8;
+ }
+ {
+ goto st7;
+ }
+ st8:
+ p+= 1;
+ if ( p == pe )
goto _test_eof8;
-case 8:
- switch( (*p) ) {
- case 42: goto st8;
- case 47: goto st1;
- }
- goto st7;
-st9:
- if ( ++p == pe )
+ st_case_8:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st8;
+ }
+ case 47: {
+ goto st1;
+ }
+ }
+ {
+ goto st7;
+ }
+ st9:
+ p+= 1;
+ if ( p == pe )
goto _test_eof9;
-case 9:
- if ( (*p) == 10 )
- goto st1;
- goto st9;
-st10:
- if ( ++p == pe )
+ st_case_9:
+ if ( ( (*( p))) == 10 ) {
+ goto st1;
+ }
+ {
+ goto st9;
+ }
+ st10:
+ p+= 1;
+ if ( p == pe )
goto _test_eof10;
-case 10:
- if ( (*p) == 110 )
- goto st11;
- goto st0;
-st11:
- if ( ++p == pe )
+ st_case_10:
+ if ( ( (*( p))) == 110 ) {
+ goto st11;
+ }
+ {
+ goto st0;
+ }
+ st11:
+ p+= 1;
+ if ( p == pe )
goto _test_eof11;
-case 11:
- if ( (*p) == 102 )
- goto st12;
- goto st0;
-st12:
- if ( ++p == pe )
+ st_case_11:
+ if ( ( (*( p))) == 102 ) {
+ goto st12;
+ }
+ {
+ goto st0;
+ }
+ st12:
+ p+= 1;
+ if ( p == pe )
goto _test_eof12;
-case 12:
- if ( (*p) == 105 )
- goto st13;
- goto st0;
-st13:
- if ( ++p == pe )
+ st_case_12:
+ if ( ( (*( p))) == 105 ) {
+ goto st13;
+ }
+ {
+ goto st0;
+ }
+ st13:
+ p+= 1;
+ if ( p == pe )
goto _test_eof13;
-case 13:
- if ( (*p) == 110 )
- goto st14;
- goto st0;
-st14:
- if ( ++p == pe )
+ st_case_13:
+ if ( ( (*( p))) == 110 ) {
+ goto st14;
+ }
+ {
+ goto st0;
+ }
+ st14:
+ p+= 1;
+ if ( p == pe )
goto _test_eof14;
-case 14:
- if ( (*p) == 105 )
- goto st15;
- goto st0;
-st15:
- if ( ++p == pe )
+ st_case_14:
+ if ( ( (*( p))) == 105 ) {
+ goto st15;
+ }
+ {
+ goto st0;
+ }
+ st15:
+ p+= 1;
+ if ( p == pe )
goto _test_eof15;
-case 15:
- if ( (*p) == 116 )
- goto st16;
- goto st0;
-st16:
- if ( ++p == pe )
+ st_case_15:
+ if ( ( (*( p))) == 116 ) {
+ goto st16;
+ }
+ {
+ goto st0;
+ }
+ st16:
+ p+= 1;
+ if ( p == pe )
goto _test_eof16;
-case 16:
- if ( (*p) == 121 )
- goto tr25;
- goto st0;
-st17:
- if ( ++p == pe )
+ st_case_16:
+ if ( ( (*( p))) == 121 ) {
+ goto ctr25;
+ }
+ {
+ goto st0;
+ }
+ st17:
+ p+= 1;
+ if ( p == pe )
goto _test_eof17;
-case 17:
- if ( (*p) == 97 )
- goto st18;
- goto st0;
-st18:
- if ( ++p == pe )
+ st_case_17:
+ if ( ( (*( p))) == 97 ) {
+ goto st18;
+ }
+ {
+ goto st0;
+ }
+ st18:
+ p+= 1;
+ if ( p == pe )
goto _test_eof18;
-case 18:
- if ( (*p) == 78 )
- goto tr27;
- goto st0;
-st19:
- if ( ++p == pe )
+ st_case_18:
+ if ( ( (*( p))) == 78 ) {
+ goto ctr27;
+ }
+ {
+ goto st0;
+ }
+ st19:
+ p+= 1;
+ if ( p == pe )
goto _test_eof19;
-case 19:
- if ( (*p) == 97 )
- goto st20;
- goto st0;
-st20:
- if ( ++p == pe )
+ st_case_19:
+ if ( ( (*( p))) == 97 ) {
+ goto st20;
+ }
+ {
+ goto st0;
+ }
+ st20:
+ p+= 1;
+ if ( p == pe )
goto _test_eof20;
-case 20:
- if ( (*p) == 108 )
- goto st21;
- goto st0;
-st21:
- if ( ++p == pe )
+ st_case_20:
+ if ( ( (*( p))) == 108 ) {
+ goto st21;
+ }
+ {
+ goto st0;
+ }
+ st21:
+ p+= 1;
+ if ( p == pe )
goto _test_eof21;
-case 21:
- if ( (*p) == 115 )
- goto st22;
- goto st0;
-st22:
- if ( ++p == pe )
+ st_case_21:
+ if ( ( (*( p))) == 115 ) {
+ goto st22;
+ }
+ {
+ goto st0;
+ }
+ st22:
+ p+= 1;
+ if ( p == pe )
goto _test_eof22;
-case 22:
- if ( (*p) == 101 )
- goto tr31;
- goto st0;
-st23:
- if ( ++p == pe )
+ st_case_22:
+ if ( ( (*( p))) == 101 ) {
+ goto ctr31;
+ }
+ {
+ goto st0;
+ }
+ st23:
+ p+= 1;
+ if ( p == pe )
goto _test_eof23;
-case 23:
- if ( (*p) == 117 )
- goto st24;
- goto st0;
-st24:
- if ( ++p == pe )
+ st_case_23:
+ if ( ( (*( p))) == 117 ) {
+ goto st24;
+ }
+ {
+ goto st0;
+ }
+ st24:
+ p+= 1;
+ if ( p == pe )
goto _test_eof24;
-case 24:
- if ( (*p) == 108 )
- goto st25;
- goto st0;
-st25:
- if ( ++p == pe )
+ st_case_24:
+ if ( ( (*( p))) == 108 ) {
+ goto st25;
+ }
+ {
+ goto st0;
+ }
+ st25:
+ p+= 1;
+ if ( p == pe )
goto _test_eof25;
-case 25:
- if ( (*p) == 108 )
- goto tr34;
- goto st0;
-st26:
- if ( ++p == pe )
+ st_case_25:
+ if ( ( (*( p))) == 108 ) {
+ goto ctr34;
+ }
+ {
+ goto st0;
+ }
+ st26:
+ p+= 1;
+ if ( p == pe )
goto _test_eof26;
-case 26:
- if ( (*p) == 114 )
- goto st27;
- goto st0;
-st27:
- if ( ++p == pe )
+ st_case_26:
+ if ( ( (*( p))) == 114 ) {
+ goto st27;
+ }
+ {
+ goto st0;
+ }
+ st27:
+ p+= 1;
+ if ( p == pe )
goto _test_eof27;
-case 27:
- if ( (*p) == 117 )
- goto st28;
- goto st0;
-st28:
- if ( ++p == pe )
+ st_case_27:
+ if ( ( (*( p))) == 117 ) {
+ goto st28;
+ }
+ {
+ goto st0;
+ }
+ st28:
+ p+= 1;
+ if ( p == pe )
goto _test_eof28;
-case 28:
- if ( (*p) == 101 )
- goto tr37;
- goto st0;
- }
- _test_eof1: cs = 1; goto _test_eof;
- _test_eof29: cs = 29; goto _test_eof;
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
- _test_eof6: cs = 6; goto _test_eof;
- _test_eof7: cs = 7; goto _test_eof;
- _test_eof8: cs = 8; goto _test_eof;
- _test_eof9: cs = 9; goto _test_eof;
- _test_eof10: cs = 10; goto _test_eof;
- _test_eof11: cs = 11; goto _test_eof;
- _test_eof12: cs = 12; goto _test_eof;
- _test_eof13: cs = 13; goto _test_eof;
- _test_eof14: cs = 14; goto _test_eof;
- _test_eof15: cs = 15; goto _test_eof;
- _test_eof16: cs = 16; goto _test_eof;
- _test_eof17: cs = 17; goto _test_eof;
- _test_eof18: cs = 18; goto _test_eof;
- _test_eof19: cs = 19; goto _test_eof;
- _test_eof20: cs = 20; goto _test_eof;
- _test_eof21: cs = 21; goto _test_eof;
- _test_eof22: cs = 22; goto _test_eof;
- _test_eof23: cs = 23; goto _test_eof;
- _test_eof24: cs = 24; goto _test_eof;
- _test_eof25: cs = 25; goto _test_eof;
- _test_eof26: cs = 26; goto _test_eof;
- _test_eof27: cs = 27; goto _test_eof;
- _test_eof28: cs = 28; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ st_case_28:
+ if ( ( (*( p))) == 101 ) {
+ goto ctr37;
+ }
+ {
+ goto st0;
+ }
+ st_out:
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof29: cs = 29; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+ _test_eof18: cs = 18; goto _test_eof;
+ _test_eof19: cs = 19; goto _test_eof;
+ _test_eof20: cs = 20; goto _test_eof;
+ _test_eof21: cs = 21; goto _test_eof;
+ _test_eof22: cs = 22; goto _test_eof;
+ _test_eof23: cs = 23; goto _test_eof;
+ _test_eof24: cs = 24; goto _test_eof;
+ _test_eof25: cs = 25; goto _test_eof;
+ _test_eof26: cs = 26; goto _test_eof;
+ _test_eof27: cs = 27; goto _test_eof;
+ _test_eof28: cs = 28; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 291 "parser.rl"
+
+
+ if (json->freeze) {
+ OBJ_FREEZE(*result);
+ }
+
+ if (cs >= JSON_value_first_final) {
+ return p;
+ } else {
+ return NULL;
}
-
-#line 291 "parser.rl"
-
- if (json->freeze) {
- OBJ_FREEZE(*result);
- }
-
- if (cs >= JSON_value_first_final) {
- return p;
- } else {
- return NULL;
- }
}
-#line 884 "parser.c"
enum {JSON_integer_start = 1};
enum {JSON_integer_first_final = 3};
enum {JSON_integer_error = 0};
enum {JSON_integer_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_integer_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_integer_nfa_offsets)[] = {
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_integer_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_integer_nfa_pop_trans)[] = {
+ 0, 0
+};
+
#line 311 "parser.rl"
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
- int cs = EVIL;
+ int cs = EVIL;
-#line 900 "parser.c"
{
- cs = JSON_integer_start;
+ cs = (int)JSON_integer_start;
}
-#line 318 "parser.rl"
- json->memo = p;
+ #line 318 "parser.rl"
+
+ json->memo = p;
-#line 908 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-case 1:
- switch( (*p) ) {
- case 45: goto st2;
- case 48: goto st3;
- }
- if ( 49 <= (*p) && (*p) <= 57 )
- goto st5;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-st2:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 2:
+ goto st_case_2;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 5:
+ goto st_case_5;
+ }
+ goto st_out;
+ st_case_1:
+ switch( ( (*( p))) ) {
+ case 45: {
+ goto st2;
+ }
+ case 48: {
+ goto st3;
+ }
+ }
+ if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st5;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- if ( (*p) == 48 )
- goto st3;
- if ( 49 <= (*p) && (*p) <= 57 )
- goto st5;
- goto st0;
-st3:
- if ( ++p == pe )
+ st_case_2:
+ if ( ( (*( p))) == 48 ) {
+ goto st3;
+ }
+ if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st5;
+ }
+ {
+ goto st0;
+ }
+ st3:
+ p+= 1;
+ if ( p == pe )
goto _test_eof3;
-case 3:
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st0;
- goto tr4;
-tr4:
-#line 308 "parser.rl"
- { p--; {p++; cs = 4; goto _out;} }
- goto st4;
-st4:
- if ( ++p == pe )
+ st_case_3:
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st0;
+ }
+ {
+ goto ctr4;
+ }
+ ctr4:
+ {
+ #line 308 "parser.rl"
+ {p = p - 1; } {p+= 1; cs = 4; goto _out;} }
+
+ goto st4;
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
-#line 949 "parser.c"
- goto st0;
-st5:
- if ( ++p == pe )
+ st_case_4:
+ {
+ goto st0;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st5;
- goto tr4;
- }
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ st_case_5:
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st5;
+ }
+ {
+ goto ctr4;
+ }
+ st_out:
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 320 "parser.rl"
+
+
+ if (cs >= JSON_integer_first_final) {
+ long len = p - json->memo;
+ fbuffer_clear(json->fbuffer);
+ fbuffer_append(json->fbuffer, json->memo, len);
+ fbuffer_append_char(json->fbuffer, '\0');
+ *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
+ return p + 1;
+ } else {
+ return NULL;
}
-
-#line 320 "parser.rl"
-
- if (cs >= JSON_integer_first_final) {
- long len = p - json->memo;
- fbuffer_clear(json->fbuffer);
- fbuffer_append(json->fbuffer, json->memo, len);
- fbuffer_append_char(json->fbuffer, '\0');
- *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
- return p + 1;
- } else {
- return NULL;
- }
}
-#line 983 "parser.c"
enum {JSON_float_start = 1};
enum {JSON_float_first_final = 8};
enum {JSON_float_error = 0};
enum {JSON_float_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_float_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_float_nfa_offsets)[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_float_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_float_nfa_pop_trans)[] = {
+ 0, 0
+};
+
#line 345 "parser.rl"
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
- int cs = EVIL;
+ int cs = EVIL;
-#line 999 "parser.c"
{
- cs = JSON_float_start;
+ cs = (int)JSON_float_start;
}
-#line 352 "parser.rl"
- json->memo = p;
+ #line 352 "parser.rl"
+
+ json->memo = p;
-#line 1007 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-case 1:
- switch( (*p) ) {
- case 45: goto st2;
- case 48: goto st3;
- }
- if ( 49 <= (*p) && (*p) <= 57 )
- goto st7;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-st2:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 2:
+ goto st_case_2;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 8:
+ goto st_case_8;
+ case 9:
+ goto st_case_9;
+ case 5:
+ goto st_case_5;
+ case 6:
+ goto st_case_6;
+ case 10:
+ goto st_case_10;
+ case 7:
+ goto st_case_7;
+ }
+ goto st_out;
+ st_case_1:
+ switch( ( (*( p))) ) {
+ case 45: {
+ goto st2;
+ }
+ case 48: {
+ goto st3;
+ }
+ }
+ if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st7;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- if ( (*p) == 48 )
- goto st3;
- if ( 49 <= (*p) && (*p) <= 57 )
- goto st7;
- goto st0;
-st3:
- if ( ++p == pe )
+ st_case_2:
+ if ( ( (*( p))) == 48 ) {
+ goto st3;
+ }
+ if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st7;
+ }
+ {
+ goto st0;
+ }
+ st3:
+ p+= 1;
+ if ( p == pe )
goto _test_eof3;
-case 3:
- switch( (*p) ) {
- case 46: goto st4;
- case 69: goto st5;
- case 101: goto st5;
- }
- goto st0;
-st4:
- if ( ++p == pe )
+ st_case_3:
+ switch( ( (*( p))) ) {
+ case 46: {
+ goto st4;
+ }
+ case 69: {
+ goto st5;
+ }
+ case 101: {
+ goto st5;
+ }
+ }
+ {
+ goto st0;
+ }
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st8;
- goto st0;
-st8:
- if ( ++p == pe )
- goto _test_eof8;
-case 8:
- switch( (*p) ) {
- case 69: goto st5;
- case 101: goto st5;
- }
- if ( (*p) > 46 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
+ st_case_4:
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto st8;
- } else if ( (*p) >= 45 )
- goto st0;
- goto tr9;
-tr9:
-#line 339 "parser.rl"
- { p--; {p++; cs = 9; goto _out;} }
- goto st9;
-st9:
- if ( ++p == pe )
+ }
+ {
+ goto st0;
+ }
+ st8:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof8;
+ st_case_8:
+ switch( ( (*( p))) ) {
+ case 69: {
+ goto st5;
+ }
+ case 101: {
+ goto st5;
+ }
+ }
+ if ( ( (*( p))) > 46 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st8;
+ }
+ } else if ( ( (*( p))) >= 45 ) {
+ goto st0;
+ }
+ {
+ goto ctr9;
+ }
+ ctr9:
+ {
+ #line 339 "parser.rl"
+ {p = p - 1; } {p+= 1; cs = 9; goto _out;} }
+
+ goto st9;
+ st9:
+ p+= 1;
+ if ( p == pe )
goto _test_eof9;
-case 9:
-#line 1072 "parser.c"
- goto st0;
-st5:
- if ( ++p == pe )
+ st_case_9:
+ {
+ goto st0;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- switch( (*p) ) {
- case 43: goto st6;
- case 45: goto st6;
- }
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st10;
- goto st0;
-st6:
- if ( ++p == pe )
+ st_case_5:
+ switch( ( (*( p))) ) {
+ case 43: {
+ goto st6;
+ }
+ case 45: {
+ goto st6;
+ }
+ }
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st10;
+ }
+ {
+ goto st0;
+ }
+ st6:
+ p+= 1;
+ if ( p == pe )
goto _test_eof6;
-case 6:
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st10;
- goto st0;
-st10:
- if ( ++p == pe )
- goto _test_eof10;
-case 10:
- switch( (*p) ) {
- case 69: goto st0;
- case 101: goto st0;
- }
- if ( (*p) > 46 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
+ st_case_6:
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto st10;
- } else if ( (*p) >= 45 )
- goto st0;
- goto tr9;
-st7:
- if ( ++p == pe )
+ }
+ {
+ goto st0;
+ }
+ st10:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof10;
+ st_case_10:
+ switch( ( (*( p))) ) {
+ case 69: {
+ goto st0;
+ }
+ case 101: {
+ goto st0;
+ }
+ }
+ if ( ( (*( p))) > 46 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st10;
+ }
+ } else if ( ( (*( p))) >= 45 ) {
+ goto st0;
+ }
+ {
+ goto ctr9;
+ }
+ st7:
+ p+= 1;
+ if ( p == pe )
goto _test_eof7;
-case 7:
- switch( (*p) ) {
- case 46: goto st4;
- case 69: goto st5;
- case 101: goto st5;
- }
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st7;
- goto st0;
- }
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof8: cs = 8; goto _test_eof;
- _test_eof9: cs = 9; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
- _test_eof6: cs = 6; goto _test_eof;
- _test_eof10: cs = 10; goto _test_eof;
- _test_eof7: cs = 7; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ st_case_7:
+ switch( ( (*( p))) ) {
+ case 46: {
+ goto st4;
+ }
+ case 69: {
+ goto st5;
+ }
+ case 101: {
+ goto st5;
+ }
+ }
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st7;
+ }
+ {
+ goto st0;
+ }
+ st_out:
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 354 "parser.rl"
+
+
+ if (cs >= JSON_float_first_final) {
+ VALUE mod = Qnil;
+ ID method_id = 0;
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
+ mod = json->decimal_class;
+ method_id = i_try_convert;
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
+ mod = json->decimal_class;
+ method_id = i_new;
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
+ VALUE name = rb_class_name(json->decimal_class);
+ const char *name_cstr = RSTRING_PTR(name);
+ const char *last_colon = strrchr(name_cstr, ':');
+ if (last_colon) {
+ const char *mod_path_end = last_colon - 1;
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
+ mod = rb_path_to_class(mod_path);
+
+ const char *method_name_beg = last_colon + 1;
+ long before_len = method_name_beg - name_cstr;
+ long len = RSTRING_LEN(name) - before_len;
+ VALUE method_name = rb_str_substr(name, before_len, len);
+ method_id = SYM2ID(rb_str_intern(method_name));
+ } else {
+ mod = rb_mKernel;
+ method_id = SYM2ID(rb_str_intern(name));
+ }
+ }
+
+ long len = p - json->memo;
+ fbuffer_clear(json->fbuffer);
+ fbuffer_append(json->fbuffer, json->memo, len);
+ fbuffer_append_char(json->fbuffer, '\0');
+
+ if (method_id) {
+ VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
+ *result = rb_funcallv(mod, method_id, 1, &text);
+ } else {
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
+ }
+
+ return p + 1;
+ } else {
+ return NULL;
}
-
-#line 354 "parser.rl"
-
- if (cs >= JSON_float_first_final) {
- VALUE mod = Qnil;
- ID method_id = 0;
- if (rb_respond_to(json->decimal_class, i_try_convert)) {
- mod = json->decimal_class;
- method_id = i_try_convert;
- } else if (rb_respond_to(json->decimal_class, i_new)) {
- mod = json->decimal_class;
- method_id = i_new;
- } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
- VALUE name = rb_class_name(json->decimal_class);
- const char *name_cstr = RSTRING_PTR(name);
- const char *last_colon = strrchr(name_cstr, ':');
- if (last_colon) {
- const char *mod_path_end = last_colon - 1;
- VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
- mod = rb_path_to_class(mod_path);
-
- const char *method_name_beg = last_colon + 1;
- long before_len = method_name_beg - name_cstr;
- long len = RSTRING_LEN(name) - before_len;
- VALUE method_name = rb_str_substr(name, before_len, len);
- method_id = SYM2ID(rb_str_intern(method_name));
- } else {
- mod = rb_mKernel;
- method_id = SYM2ID(rb_str_intern(name));
- }
- }
-
- long len = p - json->memo;
- fbuffer_clear(json->fbuffer);
- fbuffer_append(json->fbuffer, json->memo, len);
- fbuffer_append_char(json->fbuffer, '\0');
-
- if (method_id) {
- VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
- *result = rb_funcallv(mod, method_id, 1, &text);
- } else {
- *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
- }
-
- return p + 1;
- } else {
- return NULL;
- }
}
-#line 1184 "parser.c"
enum {JSON_array_start = 1};
enum {JSON_array_first_final = 17};
enum {JSON_array_error = 0};
enum {JSON_array_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_array_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_array_nfa_offsets)[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_array_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_array_nfa_pop_trans)[] = {
+ 0, 0
+};
+
#line 432 "parser.rl"
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
{
- int cs = EVIL;
- VALUE array_class = json->array_class;
+ int cs = EVIL;
+ VALUE array_class = json->array_class;
- if (json->max_nesting && current_nesting > json->max_nesting) {
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
- }
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
+ if (json->max_nesting && current_nesting > json->max_nesting) {
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
+ }
+ *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
-#line 1206 "parser.c"
{
- cs = JSON_array_start;
+ cs = (int)JSON_array_start;
}
-#line 445 "parser.rl"
+ #line 445 "parser.rl"
+
-#line 1213 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-case 1:
- if ( (*p) == 91 )
- goto st2;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-st2:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 2:
+ goto st_case_2;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 5:
+ goto st_case_5;
+ case 6:
+ goto st_case_6;
+ case 7:
+ goto st_case_7;
+ case 8:
+ goto st_case_8;
+ case 9:
+ goto st_case_9;
+ case 10:
+ goto st_case_10;
+ case 11:
+ goto st_case_11;
+ case 12:
+ goto st_case_12;
+ case 17:
+ goto st_case_17;
+ case 13:
+ goto st_case_13;
+ case 14:
+ goto st_case_14;
+ case 15:
+ goto st_case_15;
+ case 16:
+ goto st_case_16;
+ }
+ goto st_out;
+ st_case_1:
+ if ( ( (*( p))) == 91 ) {
+ goto st2;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- switch( (*p) ) {
- case 13: goto st2;
- case 32: goto st2;
- case 34: goto tr2;
- case 45: goto tr2;
- case 47: goto st13;
- case 73: goto tr2;
- case 78: goto tr2;
- case 91: goto tr2;
- case 93: goto tr4;
- case 102: goto tr2;
- case 110: goto tr2;
- case 116: goto tr2;
- case 123: goto tr2;
- }
- if ( (*p) > 10 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto tr2;
- } else if ( (*p) >= 9 )
- goto st2;
- goto st0;
-tr2:
-#line 409 "parser.rl"
- {
- VALUE v = Qnil;
- char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
- if (np == NULL) {
- p--; {p++; cs = 3; goto _out;}
- } else {
- if (NIL_P(json->array_class)) {
- rb_ary_push(*result, v);
- } else {
- rb_funcall(*result, i_leftshift, 1, v);
- }
- {p = (( np))-1;}
- }
- }
- goto st3;
-st3:
- if ( ++p == pe )
- goto _test_eof3;
-case 3:
-#line 1272 "parser.c"
- switch( (*p) ) {
- case 13: goto st3;
- case 32: goto st3;
- case 44: goto st4;
- case 47: goto st9;
- case 93: goto tr4;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
+ st_case_2:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st2;
+ }
+ case 32: {
+ goto st2;
+ }
+ case 34: {
+ goto ctr2;
+ }
+ case 45: {
+ goto ctr2;
+ }
+ case 47: {
+ goto st13;
+ }
+ case 73: {
+ goto ctr2;
+ }
+ case 78: {
+ goto ctr2;
+ }
+ case 91: {
+ goto ctr2;
+ }
+ case 93: {
+ goto ctr4;
+ }
+ case 102: {
+ goto ctr2;
+ }
+ case 110: {
+ goto ctr2;
+ }
+ case 116: {
+ goto ctr2;
+ }
+ case 123: {
+ goto ctr2;
+ }
+ }
+ if ( ( (*( p))) > 10 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto ctr2;
+ }
+ } else if ( ( (*( p))) >= 9 ) {
+ goto st2;
+ }
+ {
+ goto st0;
+ }
+ ctr2:
+ {
+ #line 409 "parser.rl"
+
+ VALUE v = Qnil;
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
+ if (np == NULL) {
+ {p = p - 1; } {p+= 1; cs = 3; goto _out;}
+ } else {
+ if (NIL_P(json->array_class)) {
+ rb_ary_push(*result, v);
+ } else {
+ rb_funcall(*result, i_leftshift, 1, v);
+ }
+ {p = (( np))-1;}
+
+ }
+ }
+
goto st3;
- goto st0;
-st4:
- if ( ++p == pe )
+ st3:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof3;
+ st_case_3:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st3;
+ }
+ case 32: {
+ goto st3;
+ }
+ case 44: {
+ goto st4;
+ }
+ case 47: {
+ goto st9;
+ }
+ case 93: {
+ goto ctr4;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st3;
+ }
+ {
+ goto st0;
+ }
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
- switch( (*p) ) {
- case 13: goto st4;
- case 32: goto st4;
- case 34: goto tr2;
- case 45: goto tr2;
- case 47: goto st5;
- case 73: goto tr2;
- case 78: goto tr2;
- case 91: goto tr2;
- case 102: goto tr2;
- case 110: goto tr2;
- case 116: goto tr2;
- case 123: goto tr2;
- }
- if ( (*p) > 10 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto tr2;
- } else if ( (*p) >= 9 )
- goto st4;
- goto st0;
-st5:
- if ( ++p == pe )
+ st_case_4:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st4;
+ }
+ case 32: {
+ goto st4;
+ }
+ case 34: {
+ goto ctr2;
+ }
+ case 45: {
+ goto ctr2;
+ }
+ case 47: {
+ goto st5;
+ }
+ case 73: {
+ goto ctr2;
+ }
+ case 78: {
+ goto ctr2;
+ }
+ case 91: {
+ goto ctr2;
+ }
+ case 102: {
+ goto ctr2;
+ }
+ case 110: {
+ goto ctr2;
+ }
+ case 116: {
+ goto ctr2;
+ }
+ case 123: {
+ goto ctr2;
+ }
+ }
+ if ( ( (*( p))) > 10 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto ctr2;
+ }
+ } else if ( ( (*( p))) >= 9 ) {
+ goto st4;
+ }
+ {
+ goto st0;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- switch( (*p) ) {
- case 42: goto st6;
- case 47: goto st8;
- }
- goto st0;
-st6:
- if ( ++p == pe )
+ st_case_5:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st6;
+ }
+ case 47: {
+ goto st8;
+ }
+ }
+ {
+ goto st0;
+ }
+ st6:
+ p+= 1;
+ if ( p == pe )
goto _test_eof6;
-case 6:
- if ( (*p) == 42 )
- goto st7;
- goto st6;
-st7:
- if ( ++p == pe )
+ st_case_6:
+ if ( ( (*( p))) == 42 ) {
+ goto st7;
+ }
+ {
+ goto st6;
+ }
+ st7:
+ p+= 1;
+ if ( p == pe )
goto _test_eof7;
-case 7:
- switch( (*p) ) {
- case 42: goto st7;
- case 47: goto st4;
- }
- goto st6;
-st8:
- if ( ++p == pe )
+ st_case_7:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st7;
+ }
+ case 47: {
+ goto st4;
+ }
+ }
+ {
+ goto st6;
+ }
+ st8:
+ p+= 1;
+ if ( p == pe )
goto _test_eof8;
-case 8:
- if ( (*p) == 10 )
- goto st4;
- goto st8;
-st9:
- if ( ++p == pe )
+ st_case_8:
+ if ( ( (*( p))) == 10 ) {
+ goto st4;
+ }
+ {
+ goto st8;
+ }
+ st9:
+ p+= 1;
+ if ( p == pe )
goto _test_eof9;
-case 9:
- switch( (*p) ) {
- case 42: goto st10;
- case 47: goto st12;
- }
- goto st0;
-st10:
- if ( ++p == pe )
+ st_case_9:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st10;
+ }
+ case 47: {
+ goto st12;
+ }
+ }
+ {
+ goto st0;
+ }
+ st10:
+ p+= 1;
+ if ( p == pe )
goto _test_eof10;
-case 10:
- if ( (*p) == 42 )
- goto st11;
- goto st10;
-st11:
- if ( ++p == pe )
+ st_case_10:
+ if ( ( (*( p))) == 42 ) {
+ goto st11;
+ }
+ {
+ goto st10;
+ }
+ st11:
+ p+= 1;
+ if ( p == pe )
goto _test_eof11;
-case 11:
- switch( (*p) ) {
- case 42: goto st11;
- case 47: goto st3;
- }
- goto st10;
-st12:
- if ( ++p == pe )
+ st_case_11:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st11;
+ }
+ case 47: {
+ goto st3;
+ }
+ }
+ {
+ goto st10;
+ }
+ st12:
+ p+= 1;
+ if ( p == pe )
goto _test_eof12;
-case 12:
- if ( (*p) == 10 )
- goto st3;
- goto st12;
-tr4:
-#line 424 "parser.rl"
- { p--; {p++; cs = 17; goto _out;} }
- goto st17;
-st17:
- if ( ++p == pe )
+ st_case_12:
+ if ( ( (*( p))) == 10 ) {
+ goto st3;
+ }
+ {
+ goto st12;
+ }
+ ctr4:
+ {
+ #line 424 "parser.rl"
+ {p = p - 1; } {p+= 1; cs = 17; goto _out;} }
+
+ goto st17;
+ st17:
+ p+= 1;
+ if ( p == pe )
goto _test_eof17;
-case 17:
-#line 1379 "parser.c"
- goto st0;
-st13:
- if ( ++p == pe )
+ st_case_17:
+ {
+ goto st0;
+ }
+ st13:
+ p+= 1;
+ if ( p == pe )
goto _test_eof13;
-case 13:
- switch( (*p) ) {
- case 42: goto st14;
- case 47: goto st16;
- }
- goto st0;
-st14:
- if ( ++p == pe )
+ st_case_13:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st14;
+ }
+ case 47: {
+ goto st16;
+ }
+ }
+ {
+ goto st0;
+ }
+ st14:
+ p+= 1;
+ if ( p == pe )
goto _test_eof14;
-case 14:
- if ( (*p) == 42 )
- goto st15;
- goto st14;
-st15:
- if ( ++p == pe )
+ st_case_14:
+ if ( ( (*( p))) == 42 ) {
+ goto st15;
+ }
+ {
+ goto st14;
+ }
+ st15:
+ p+= 1;
+ if ( p == pe )
goto _test_eof15;
-case 15:
- switch( (*p) ) {
- case 42: goto st15;
- case 47: goto st2;
- }
- goto st14;
-st16:
- if ( ++p == pe )
+ st_case_15:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st15;
+ }
+ case 47: {
+ goto st2;
+ }
+ }
+ {
+ goto st14;
+ }
+ st16:
+ p+= 1;
+ if ( p == pe )
goto _test_eof16;
-case 16:
- if ( (*p) == 10 )
- goto st2;
- goto st16;
- }
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
- _test_eof6: cs = 6; goto _test_eof;
- _test_eof7: cs = 7; goto _test_eof;
- _test_eof8: cs = 8; goto _test_eof;
- _test_eof9: cs = 9; goto _test_eof;
- _test_eof10: cs = 10; goto _test_eof;
- _test_eof11: cs = 11; goto _test_eof;
- _test_eof12: cs = 12; goto _test_eof;
- _test_eof17: cs = 17; goto _test_eof;
- _test_eof13: cs = 13; goto _test_eof;
- _test_eof14: cs = 14; goto _test_eof;
- _test_eof15: cs = 15; goto _test_eof;
- _test_eof16: cs = 16; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ st_case_16:
+ if ( ( (*( p))) == 10 ) {
+ goto st2;
+ }
+ {
+ goto st16;
+ }
+ st_out:
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof11: cs = 11; goto _test_eof;
+ _test_eof12: cs = 12; goto _test_eof;
+ _test_eof17: cs = 17; goto _test_eof;
+ _test_eof13: cs = 13; goto _test_eof;
+ _test_eof14: cs = 14; goto _test_eof;
+ _test_eof15: cs = 15; goto _test_eof;
+ _test_eof16: cs = 16; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 446 "parser.rl"
+
+
+ if(cs >= JSON_array_first_final) {
+ return p + 1;
+ } else {
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
+ return NULL;
}
-
-#line 446 "parser.rl"
-
- if(cs >= JSON_array_first_final) {
- return p + 1;
- } else {
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
- return NULL;
- }
}
static const size_t MAX_STACK_BUFFER_SIZE = 128;
static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
{
- VALUE result = Qnil;
- size_t bufferSize = stringEnd - string;
- char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
- int unescape_len;
- char buf[4];
+ VALUE result = Qnil;
+ size_t bufferSize = stringEnd - string;
+ char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
+ int unescape_len;
+ char buf[4];
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
# ifdef HAVE_RB_ENC_INTERNED_STR
- bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
+ bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
# else
- bufferStart = buffer = ALLOC_N(char, bufferSize);
+ bufferStart = buffer = ALLOC_N(char, bufferSize);
# endif
- } else {
+ } else {
# ifdef HAVE_RB_ENC_INTERNED_STR
- bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
+ bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
# else
- bufferStart = buffer = ALLOCA_N(char, bufferSize);
+ bufferStart = buffer = ALLOCA_N(char, bufferSize);
# endif
- }
-
- while (pe < stringEnd) {
- if (*pe == '\\') {
- unescape = (char *) "?";
- unescape_len = 1;
- if (pe > p) {
- MEMCPY(buffer, p, char, pe - p);
- buffer += pe - p;
- }
- switch (*++pe) {
- case 'n':
- unescape = (char *) "\n";
- break;
- case 'r':
- unescape = (char *) "\r";
- break;
- case 't':
- unescape = (char *) "\t";
- break;
- case '"':
- unescape = (char *) "\"";
- break;
- case '\\':
- unescape = (char *) "\\";
- break;
- case 'b':
- unescape = (char *) "\b";
- break;
- case 'f':
- unescape = (char *) "\f";
- break;
- case 'u':
- if (pe > stringEnd - 4) {
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
- }
- rb_enc_raise(
- EXC_ENCODING eParserError,
- "incomplete unicode character escape sequence at '%s'", p
- );
- } else {
- UTF32 ch = unescape_unicode((unsigned char *) ++pe);
- pe += 3;
- if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
- pe++;
- if (pe > stringEnd - 6) {
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
- }
- rb_enc_raise(
- EXC_ENCODING eParserError,
- "incomplete surrogate pair at '%s'", p
- );
- }
- if (pe[0] == '\\' && pe[1] == 'u') {
- UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
- ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
- | (sur & 0x3FF));
- pe += 5;
- } else {
- unescape = (char *) "?";
- break;
- }
- }
- unescape_len = convert_UTF32_to_UTF8(buf, ch);
- unescape = buf;
- }
- break;
- default:
- p = pe;
- continue;
- }
- MEMCPY(buffer, unescape, char, unescape_len);
- buffer += unescape_len;
- p = ++pe;
- } else {
- pe++;
- }
- }
-
- if (pe > p) {
- MEMCPY(buffer, p, char, pe - p);
- buffer += pe - p;
- }
+ }
-# ifdef HAVE_RB_ENC_INTERNED_STR
- if (intern) {
- result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
- } else {
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
- }
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
- }
-# else
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
-
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
- }
-
- if (intern) {
- # if STR_UMINUS_DEDUPE_FROZEN
- // Starting from MRI 2.8 it is preferable to freeze the string
- // before deduplication so that it can be interned directly
- // otherwise it would be duplicated first which is wasteful.
- result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
- # elif STR_UMINUS_DEDUPE
- // MRI 2.5 and older do not deduplicate strings that are already
- // frozen.
- result = rb_funcall(result, i_uminus, 0);
- # else
- result = rb_str_freeze(result);
- # endif
- }
-# endif
+ while (pe < stringEnd) {
+ if (*pe == '\\') {
+ unescape = (char *) "?";
+ unescape_len = 1;
+ if (pe > p) {
+ MEMCPY(buffer, p, char, pe - p);
+ buffer += pe - p;
+ }
+ switch (*++pe) {
+ case 'n':
+ unescape = (char *) "\n";
+ break;
+ case 'r':
+ unescape = (char *) "\r";
+ break;
+ case 't':
+ unescape = (char *) "\t";
+ break;
+ case '"':
+ unescape = (char *) "\"";
+ break;
+ case '\\':
+ unescape = (char *) "\\";
+ break;
+ case 'b':
+ unescape = (char *) "\b";
+ break;
+ case 'f':
+ unescape = (char *) "\f";
+ break;
+ case 'u':
+ if (pe > stringEnd - 4) {
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
+ free(bufferStart);
+ }
+ rb_enc_raise(
+ EXC_ENCODING eParserError,
+ "incomplete unicode character escape sequence at '%s'", p
+ );
+ } else {
+ UTF32 ch = unescape_unicode((unsigned char *) ++pe);
+ pe += 3;
+ if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
+ pe++;
+ if (pe > stringEnd - 6) {
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
+ free(bufferStart);
+ }
+ rb_enc_raise(
+ EXC_ENCODING eParserError,
+ "incomplete surrogate pair at '%s'", p
+ );
+ }
+ if (pe[0] == '\\' && pe[1] == 'u') {
+ UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
+ ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
+ | (sur & 0x3FF));
+ pe += 5;
+ } else {
+ unescape = (char *) "?";
+ break;
+ }
+ }
+ unescape_len = convert_UTF32_to_UTF8(buf, ch);
+ unescape = buf;
+ }
+ break;
+ default:
+ p = pe;
+ continue;
+ }
+ MEMCPY(buffer, unescape, char, unescape_len);
+ buffer += unescape_len;
+ p = ++pe;
+ } else {
+ pe++;
+ }
+ }
+
+ if (pe > p) {
+ MEMCPY(buffer, p, char, pe - p);
+ buffer += pe - p;
+ }
+
+ # ifdef HAVE_RB_ENC_INTERNED_STR
+ if (intern) {
+ result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
+ } else {
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
+ }
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
+ free(bufferStart);
+ }
+ # else
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
+
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
+ free(bufferStart);
+ }
- if (symbolize) {
- result = rb_str_intern(result);
- }
+ if (intern) {
+ # if STR_UMINUS_DEDUPE_FROZEN
+ // Starting from MRI 2.8 it is preferable to freeze the string
+ // before deduplication so that it can be interned directly
+ // otherwise it would be duplicated first which is wasteful.
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
+ # elif STR_UMINUS_DEDUPE
+ // MRI 2.5 and older do not deduplicate strings that are already
+ // frozen.
+ result = rb_funcall(result, i_uminus, 0);
+ # else
+ result = rb_str_freeze(result);
+ # endif
+ }
+ # endif
- return result;
+ if (symbolize) {
+ result = rb_str_intern(result);
+ }
+
+ return result;
}
-#line 1592 "parser.c"
enum {JSON_string_start = 1};
enum {JSON_string_first_final = 8};
enum {JSON_string_error = 0};
enum {JSON_string_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_string_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_string_nfa_offsets)[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
-#line 620 "parser.rl"
+static const char MAYBE_UNUSED(_JSON_string_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_string_nfa_pop_trans)[] = {
+ 0, 0
+};
+
+
+#line 612 "parser.rl"
static int
match_i(VALUE regexp, VALUE klass, VALUE memo)
{
- if (regexp == Qundef) return ST_STOP;
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
- RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
- rb_ary_push(memo, klass);
- return ST_STOP;
- }
- return ST_CONTINUE;
+ if (regexp == Qundef) return ST_STOP;
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
+ RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
+ rb_ary_push(memo, klass);
+ return ST_STOP;
+ }
+ return ST_CONTINUE;
}
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
- int cs = EVIL;
- VALUE match_string;
+ int cs = EVIL;
+ VALUE match_string;
-#line 1621 "parser.c"
{
- cs = JSON_string_start;
+ cs = (int)JSON_string_start;
}
-#line 640 "parser.rl"
- json->memo = p;
+ #line 632 "parser.rl"
+
+ json->memo = p;
-#line 1629 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-case 1:
- if ( (*p) == 34 )
- goto st2;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-st2:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 2:
+ goto st_case_2;
+ case 8:
+ goto st_case_8;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 5:
+ goto st_case_5;
+ case 6:
+ goto st_case_6;
+ case 7:
+ goto st_case_7;
+ }
+ goto st_out;
+ st_case_1:
+ if ( ( (*( p))) == 34 ) {
+ goto st2;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- switch( (*p) ) {
- case 34: goto tr2;
- case 92: goto st3;
- }
- if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
- goto st0;
- goto st2;
-tr2:
-#line 607 "parser.rl"
- {
- *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
- if (NIL_P(*result)) {
- p--;
- {p++; cs = 8; goto _out;}
- } else {
- {p = (( p + 1))-1;}
- }
- }
-#line 617 "parser.rl"
- { p--; {p++; cs = 8; goto _out;} }
- goto st8;
-st8:
- if ( ++p == pe )
+ st_case_2:
+ switch( ( (*( p))) ) {
+ case 34: {
+ goto ctr2;
+ }
+ case 92: {
+ goto st3;
+ }
+ }
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 ) {
+ goto st0;
+ }
+ {
+ goto st2;
+ }
+ ctr2:
+ {
+ #line 599 "parser.rl"
+
+ *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
+ if (NIL_P(*result)) {
+ {p = p - 1; }
+ {p+= 1; cs = 8; goto _out;}
+ } else {
+ {p = (( p + 1))-1;}
+
+ }
+ }
+ {
+ #line 609 "parser.rl"
+ {p = p - 1; } {p+= 1; cs = 8; goto _out;} }
+
+ goto st8;
+ st8:
+ p+= 1;
+ if ( p == pe )
goto _test_eof8;
-case 8:
-#line 1671 "parser.c"
- goto st0;
-st3:
- if ( ++p == pe )
+ st_case_8:
+ {
+ goto st0;
+ }
+ st3:
+ p+= 1;
+ if ( p == pe )
goto _test_eof3;
-case 3:
- if ( (*p) == 117 )
- goto st4;
- if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
- goto st0;
- goto st2;
-st4:
- if ( ++p == pe )
+ st_case_3:
+ if ( ( (*( p))) == 117 ) {
+ goto st4;
+ }
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 ) {
+ goto st0;
+ }
+ {
+ goto st2;
+ }
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
- if ( (*p) < 65 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
+ st_case_4:
+ if ( ( (*( p))) < 65 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st5;
+ }
+ } else if ( ( (*( p))) > 70 ) {
+ if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) {
+ goto st5;
+ }
+ } else {
goto st5;
- } else if ( (*p) > 70 ) {
- if ( 97 <= (*p) && (*p) <= 102 )
- goto st5;
- } else
- goto st5;
- goto st0;
-st5:
- if ( ++p == pe )
+ }
+ {
+ goto st0;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- if ( (*p) < 65 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st6;
- } else if ( (*p) > 70 ) {
- if ( 97 <= (*p) && (*p) <= 102 )
+ st_case_5:
+ if ( ( (*( p))) < 65 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st6;
+ }
+ } else if ( ( (*( p))) > 70 ) {
+ if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) {
+ goto st6;
+ }
+ } else {
goto st6;
- } else
- goto st6;
- goto st0;
-st6:
- if ( ++p == pe )
+ }
+ {
+ goto st0;
+ }
+ st6:
+ p+= 1;
+ if ( p == pe )
goto _test_eof6;
-case 6:
- if ( (*p) < 65 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
+ st_case_6:
+ if ( ( (*( p))) < 65 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st7;
+ }
+ } else if ( ( (*( p))) > 70 ) {
+ if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) {
+ goto st7;
+ }
+ } else {
goto st7;
- } else if ( (*p) > 70 ) {
- if ( 97 <= (*p) && (*p) <= 102 )
- goto st7;
- } else
- goto st7;
- goto st0;
-st7:
- if ( ++p == pe )
+ }
+ {
+ goto st0;
+ }
+ st7:
+ p+= 1;
+ if ( p == pe )
goto _test_eof7;
-case 7:
- if ( (*p) < 65 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st2;
- } else if ( (*p) > 70 ) {
- if ( 97 <= (*p) && (*p) <= 102 )
+ st_case_7:
+ if ( ( (*( p))) < 65 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto st2;
+ }
+ } else if ( ( (*( p))) > 70 ) {
+ if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) {
+ goto st2;
+ }
+ } else {
goto st2;
- } else
- goto st2;
- goto st0;
- }
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof8: cs = 8; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
- _test_eof6: cs = 6; goto _test_eof;
- _test_eof7: cs = 7; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ }
+ {
+ goto st0;
+ }
+ st_out:
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 634 "parser.rl"
+
+
+ if (json->create_additions && RTEST(match_string = json->match_string)) {
+ VALUE klass;
+ VALUE memo = rb_ary_new2(2);
+ rb_ary_push(memo, *result);
+ rb_hash_foreach(match_string, match_i, memo);
+ klass = rb_ary_entry(memo, 1);
+ if (RTEST(klass)) {
+ *result = rb_funcall(klass, i_json_create, 1, *result);
+ }
+ }
+
+ if (cs >= JSON_string_first_final) {
+ return p + 1;
+ } else {
+ return NULL;
}
-
-#line 642 "parser.rl"
-
- if (json->create_additions && RTEST(match_string = json->match_string)) {
- VALUE klass;
- VALUE memo = rb_ary_new2(2);
- rb_ary_push(memo, *result);
- rb_hash_foreach(match_string, match_i, memo);
- klass = rb_ary_entry(memo, 1);
- if (RTEST(klass)) {
- *result = rb_funcall(klass, i_json_create, 1, *result);
- }
- }
-
- if (cs >= JSON_string_first_final) {
- return p + 1;
- } else {
- return NULL;
- }
}
/*
- * Document-class: JSON::Ext::Parser
- *
- * This is the JSON parser implemented as a C extension. It can be configured
- * to be used by setting
- *
- * JSON.parser = JSON::Ext::Parser
- *
- * with the method parser= in JSON.
- *
- */
+* Document-class: JSON::Ext::Parser
+*
+* This is the JSON parser implemented as a C extension. It can be configured
+* to be used by setting
+*
+* JSON.parser = JSON::Ext::Parser
+*
+* with the method parser= in JSON.
+*
+*/
static VALUE convert_encoding(VALUE source)
{
-#ifdef HAVE_RUBY_ENCODING_H
- rb_encoding *enc = rb_enc_get(source);
- if (enc == rb_ascii8bit_encoding()) {
- if (OBJ_FROZEN(source)) {
- source = rb_str_dup(source);
- }
- FORCE_UTF8(source);
- } else {
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
- }
-#endif
- return source;
+ #ifdef HAVE_RUBY_ENCODING_H
+ rb_encoding *enc = rb_enc_get(source);
+ if (enc == rb_ascii8bit_encoding()) {
+ if (OBJ_FROZEN(source)) {
+ source = rb_str_dup(source);
+ }
+ FORCE_UTF8(source);
+ } else {
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
+ }
+ #endif
+ return source;
}
/*
- * call-seq: new(source, opts => {})
- *
- * Creates a new JSON::Ext::Parser instance for the string _source_.
- *
- * It will be configured by the _opts_ hash. _opts_ can have the following
- * keys:
- *
- * _opts_ can have the following keys:
- * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- * structures. Disable depth checking with :max_nesting => false|nil|0, it
- * defaults to 100.
- * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
- * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
- * false.
- * * *symbolize_names*: If set to true, returns symbols for the names
- * (keys) in a JSON object. Otherwise strings are returned, which is
- * also the default. It's not possible to use this option in
- * conjunction with the *create_additions* option.
- * * *create_additions*: If set to false, the Parser doesn't create
- * additions even if a matching class and create_id was found. This option
- * defaults to false.
- * * *object_class*: Defaults to Hash
- * * *array_class*: Defaults to Array
- */
+* call-seq: new(source, opts => {})
+*
+* Creates a new JSON::Ext::Parser instance for the string _source_.
+*
+* Creates a new JSON::Ext::Parser instance for the string _source_.
+*
+* It will be configured by the _opts_ hash. _opts_ can have the following
+* keys:
+*
+* _opts_ can have the following keys:
+* * *max_nesting*: The maximum depth of nesting allowed in the parsed data
+* structures. Disable depth checking with :max_nesting => false|nil|0, it
+* defaults to 100.
+* * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
+* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
+* false.
+* * *symbolize_names*: If set to true, returns symbols for the names
+* (keys) in a JSON object. Otherwise strings are returned, which is
+* also the default. It's not possible to use this option in
+* conjunction with the *create_additions* option.
+* * *create_additions*: If set to false, the Parser doesn't create
+* additions even if a matching class and create_id was found. This option
+* defaults to false.
+* * *object_class*: Defaults to Hash
+* * *array_class*: Defaults to Array
+*/
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
{
- VALUE source, opts;
- GET_PARSER_INIT;
-
- if (json->Vsource) {
- rb_raise(rb_eTypeError, "already initialized instance");
- }
- rb_scan_args(argc, argv, "1:", &source, &opts);
- if (!NIL_P(opts)) {
- VALUE tmp = ID2SYM(i_max_nesting);
- if (option_given_p(opts, tmp)) {
- VALUE max_nesting = rb_hash_aref(opts, tmp);
- if (RTEST(max_nesting)) {
- Check_Type(max_nesting, T_FIXNUM);
- json->max_nesting = FIX2INT(max_nesting);
- } else {
- json->max_nesting = 0;
- }
- } else {
- json->max_nesting = 100;
- }
- tmp = ID2SYM(i_allow_nan);
- if (option_given_p(opts, tmp)) {
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
- } else {
- json->allow_nan = 0;
- }
- tmp = ID2SYM(i_symbolize_names);
- if (option_given_p(opts, tmp)) {
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
- } else {
- json->symbolize_names = 0;
- }
- tmp = ID2SYM(i_freeze);
- if (option_given_p(opts, tmp)) {
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
- } else {
- json->freeze = 0;
- }
- tmp = ID2SYM(i_create_additions);
- if (option_given_p(opts, tmp)) {
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
- } else {
- json->create_additions = 0;
- }
- if (json->symbolize_names && json->create_additions) {
- rb_raise(rb_eArgError,
- "options :symbolize_names and :create_additions cannot be "
- " used in conjunction");
- }
- tmp = ID2SYM(i_create_id);
- if (option_given_p(opts, tmp)) {
- json->create_id = rb_hash_aref(opts, tmp);
- } else {
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
- }
- tmp = ID2SYM(i_object_class);
- if (option_given_p(opts, tmp)) {
- json->object_class = rb_hash_aref(opts, tmp);
- } else {
- json->object_class = Qnil;
- }
- tmp = ID2SYM(i_array_class);
- if (option_given_p(opts, tmp)) {
- json->array_class = rb_hash_aref(opts, tmp);
- } else {
- json->array_class = Qnil;
- }
- tmp = ID2SYM(i_decimal_class);
- if (option_given_p(opts, tmp)) {
- json->decimal_class = rb_hash_aref(opts, tmp);
+ VALUE source, opts;
+ GET_PARSER_INIT;
+
+ if (json->Vsource) {
+ rb_raise(rb_eTypeError, "already initialized instance");
+ }
+ #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+ rb_scan_args(argc, argv, "1:", &source, &opts);
+ #else
+ rb_scan_args(argc, argv, "11", &source, &opts);
+ #endif
+ if (!NIL_P(opts)) {
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+ opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
+ if (NIL_P(opts)) {
+ rb_raise(rb_eArgError, "opts needs to be like a hash");
+ } else {
+ #endif
+ VALUE tmp = ID2SYM(i_max_nesting);
+ if (option_given_p(opts, tmp)) {
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
+ if (RTEST(max_nesting)) {
+ Check_Type(max_nesting, T_FIXNUM);
+ json->max_nesting = FIX2INT(max_nesting);
+ } else {
+ json->max_nesting = 0;
+ }
+ } else {
+ json->max_nesting = 100;
+ }
+ tmp = ID2SYM(i_allow_nan);
+ if (option_given_p(opts, tmp)) {
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->allow_nan = 0;
+ }
+ tmp = ID2SYM(i_symbolize_names);
+ if (option_given_p(opts, tmp)) {
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->symbolize_names = 0;
+ }
+ tmp = ID2SYM(i_freeze);
+ if (option_given_p(opts, tmp)) {
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->freeze = 0;
+ }
+ tmp = ID2SYM(i_create_additions);
+ if (option_given_p(opts, tmp)) {
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
+ } else {
+ json->create_additions = 0;
+ }
+ if (json->symbolize_names && json->create_additions) {
+ rb_raise(rb_eArgError,
+ "options :symbolize_names and :create_additions cannot be "
+ " used in conjunction");
+ }
+ tmp = ID2SYM(i_create_id);
+ if (option_given_p(opts, tmp)) {
+ json->create_id = rb_hash_aref(opts, tmp);
+ } else {
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
+ }
+ tmp = ID2SYM(i_object_class);
+ if (option_given_p(opts, tmp)) {
+ json->object_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->object_class = Qnil;
+ }
+ tmp = ID2SYM(i_array_class);
+ if (option_given_p(opts, tmp)) {
+ json->array_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->array_class = Qnil;
+ }
+ tmp = ID2SYM(i_decimal_class);
+ if (option_given_p(opts, tmp)) {
+ json->decimal_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->decimal_class = Qnil;
+ }
+ tmp = ID2SYM(i_match_string);
+ if (option_given_p(opts, tmp)) {
+ VALUE match_string = rb_hash_aref(opts, tmp);
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
+ } else {
+ json->match_string = Qnil;
+ }
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+ }
+ #endif
} else {
- json->decimal_class = Qnil;
- }
- tmp = ID2SYM(i_match_string);
- if (option_given_p(opts, tmp)) {
- VALUE match_string = rb_hash_aref(opts, tmp);
- json->match_string = RTEST(match_string) ? match_string : Qnil;
- } else {
- json->match_string = Qnil;
- }
- } else {
- json->max_nesting = 100;
- json->allow_nan = 0;
- json->create_additions = 0;
- json->create_id = Qnil;
- json->object_class = Qnil;
- json->array_class = Qnil;
- json->decimal_class = Qnil;
- }
- source = convert_encoding(StringValue(source));
- StringValue(source);
- json->len = RSTRING_LEN(source);
- json->source = RSTRING_PTR(source);;
- json->Vsource = source;
- return self;
+ json->max_nesting = 100;
+ json->allow_nan = 0;
+ json->create_additions = 0;
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
+ json->object_class = Qnil;
+ json->array_class = Qnil;
+ json->decimal_class = Qnil;
+ }
+ source = convert_encoding(StringValue(source));
+ StringValue(source);
+ json->len = RSTRING_LEN(source);
+ json->source = RSTRING_PTR(source);;
+ json->Vsource = source;
+ return self;
}
-#line 1920 "parser.c"
enum {JSON_start = 1};
enum {JSON_first_final = 10};
enum {JSON_error = 0};
enum {JSON_en_main = 1};
+static const char MAYBE_UNUSED(_JSON_nfa_targs)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_nfa_offsets)[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_nfa_push_actions)[] = {
+ 0, 0
+};
+
+static const char MAYBE_UNUSED(_JSON_nfa_pop_trans)[] = {
+ 0, 0
+};
+
-#line 828 "parser.rl"
+#line 835 "parser.rl"
/*
- * call-seq: parse()
- *
- * Parses the current JSON text _source_ and returns the complete data
- * structure as a result.
- * It raises JSON::ParserError if fail to parse.
- */
+* call-seq: parse()
+*
+* Parses the current JSON text _source_ and returns the complete data
+* structure as a result.
+* It raises JSON::ParseError if fail to parse.
+*/
static VALUE cParser_parse(VALUE self)
{
- char *p, *pe;
- int cs = EVIL;
- VALUE result = Qnil;
- GET_PARSER;
+ char *p, *pe;
+ int cs = EVIL;
+ VALUE result = Qnil;
+ GET_PARSER;
-#line 1946 "parser.c"
{
- cs = JSON_start;
+ cs = (int)JSON_start;
}
-#line 845 "parser.rl"
- p = json->source;
- pe = p + json->len;
+ #line 851 "parser.rl"
+
+ p = json->source;
+ pe = p + json->len;
-#line 1955 "parser.c"
{
- if ( p == pe )
+ if ( p == pe )
goto _test_eof;
- switch ( cs )
- {
-st1:
- if ( ++p == pe )
+ switch ( cs )
+ {
+ case 1:
+ goto st_case_1;
+ case 0:
+ goto st_case_0;
+ case 10:
+ goto st_case_10;
+ case 2:
+ goto st_case_2;
+ case 3:
+ goto st_case_3;
+ case 4:
+ goto st_case_4;
+ case 5:
+ goto st_case_5;
+ case 6:
+ goto st_case_6;
+ case 7:
+ goto st_case_7;
+ case 8:
+ goto st_case_8;
+ case 9:
+ goto st_case_9;
+ }
+ goto st_out;
+ st1:
+ p+= 1;
+ if ( p == pe )
goto _test_eof1;
-case 1:
- switch( (*p) ) {
- case 13: goto st1;
- case 32: goto st1;
- case 34: goto tr2;
- case 45: goto tr2;
- case 47: goto st6;
- case 73: goto tr2;
- case 78: goto tr2;
- case 91: goto tr2;
- case 102: goto tr2;
- case 110: goto tr2;
- case 116: goto tr2;
- case 123: goto tr2;
- }
- if ( (*p) > 10 ) {
- if ( 48 <= (*p) && (*p) <= 57 )
- goto tr2;
- } else if ( (*p) >= 9 )
- goto st1;
- goto st0;
-st0:
-cs = 0;
- goto _out;
-tr2:
-#line 820 "parser.rl"
- {
- char *np = JSON_parse_value(json, p, pe, &result, 0);
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
- }
- goto st10;
-st10:
- if ( ++p == pe )
- goto _test_eof10;
-case 10:
-#line 1999 "parser.c"
- switch( (*p) ) {
- case 13: goto st10;
- case 32: goto st10;
- case 47: goto st2;
- }
- if ( 9 <= (*p) && (*p) <= 10 )
+ st_case_1:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st1;
+ }
+ case 32: {
+ goto st1;
+ }
+ case 34: {
+ goto ctr2;
+ }
+ case 45: {
+ goto ctr2;
+ }
+ case 47: {
+ goto st6;
+ }
+ case 73: {
+ goto ctr2;
+ }
+ case 78: {
+ goto ctr2;
+ }
+ case 91: {
+ goto ctr2;
+ }
+ case 102: {
+ goto ctr2;
+ }
+ case 110: {
+ goto ctr2;
+ }
+ case 116: {
+ goto ctr2;
+ }
+ case 123: {
+ goto ctr2;
+ }
+ }
+ if ( ( (*( p))) > 10 ) {
+ if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
+ goto ctr2;
+ }
+ } else if ( ( (*( p))) >= 9 ) {
+ goto st1;
+ }
+ {
+ goto st0;
+ }
+ st_case_0:
+ st0:
+ cs = 0;
+ goto _out;
+ ctr2:
+ {
+ #line 827 "parser.rl"
+
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
+ if (np == NULL) { {p = p - 1; } {p+= 1; cs = 10; goto _out;} } else {p = (( np))-1;}
+
+ }
+
goto st10;
- goto st0;
-st2:
- if ( ++p == pe )
+ st10:
+ p+= 1;
+ if ( p == pe )
+ goto _test_eof10;
+ st_case_10:
+ switch( ( (*( p))) ) {
+ case 13: {
+ goto st10;
+ }
+ case 32: {
+ goto st10;
+ }
+ case 47: {
+ goto st2;
+ }
+ }
+ if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) {
+ goto st10;
+ }
+ {
+ goto st0;
+ }
+ st2:
+ p+= 1;
+ if ( p == pe )
goto _test_eof2;
-case 2:
- switch( (*p) ) {
- case 42: goto st3;
- case 47: goto st5;
- }
- goto st0;
-st3:
- if ( ++p == pe )
+ st_case_2:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st3;
+ }
+ case 47: {
+ goto st5;
+ }
+ }
+ {
+ goto st0;
+ }
+ st3:
+ p+= 1;
+ if ( p == pe )
goto _test_eof3;
-case 3:
- if ( (*p) == 42 )
- goto st4;
- goto st3;
-st4:
- if ( ++p == pe )
+ st_case_3:
+ if ( ( (*( p))) == 42 ) {
+ goto st4;
+ }
+ {
+ goto st3;
+ }
+ st4:
+ p+= 1;
+ if ( p == pe )
goto _test_eof4;
-case 4:
- switch( (*p) ) {
- case 42: goto st4;
- case 47: goto st10;
- }
- goto st3;
-st5:
- if ( ++p == pe )
+ st_case_4:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st4;
+ }
+ case 47: {
+ goto st10;
+ }
+ }
+ {
+ goto st3;
+ }
+ st5:
+ p+= 1;
+ if ( p == pe )
goto _test_eof5;
-case 5:
- if ( (*p) == 10 )
- goto st10;
- goto st5;
-st6:
- if ( ++p == pe )
+ st_case_5:
+ if ( ( (*( p))) == 10 ) {
+ goto st10;
+ }
+ {
+ goto st5;
+ }
+ st6:
+ p+= 1;
+ if ( p == pe )
goto _test_eof6;
-case 6:
- switch( (*p) ) {
- case 42: goto st7;
- case 47: goto st9;
- }
- goto st0;
-st7:
- if ( ++p == pe )
+ st_case_6:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st7;
+ }
+ case 47: {
+ goto st9;
+ }
+ }
+ {
+ goto st0;
+ }
+ st7:
+ p+= 1;
+ if ( p == pe )
goto _test_eof7;
-case 7:
- if ( (*p) == 42 )
- goto st8;
- goto st7;
-st8:
- if ( ++p == pe )
+ st_case_7:
+ if ( ( (*( p))) == 42 ) {
+ goto st8;
+ }
+ {
+ goto st7;
+ }
+ st8:
+ p+= 1;
+ if ( p == pe )
goto _test_eof8;
-case 8:
- switch( (*p) ) {
- case 42: goto st8;
- case 47: goto st1;
- }
- goto st7;
-st9:
- if ( ++p == pe )
+ st_case_8:
+ switch( ( (*( p))) ) {
+ case 42: {
+ goto st8;
+ }
+ case 47: {
+ goto st1;
+ }
+ }
+ {
+ goto st7;
+ }
+ st9:
+ p+= 1;
+ if ( p == pe )
goto _test_eof9;
-case 9:
- if ( (*p) == 10 )
- goto st1;
- goto st9;
- }
- _test_eof1: cs = 1; goto _test_eof;
- _test_eof10: cs = 10; goto _test_eof;
- _test_eof2: cs = 2; goto _test_eof;
- _test_eof3: cs = 3; goto _test_eof;
- _test_eof4: cs = 4; goto _test_eof;
- _test_eof5: cs = 5; goto _test_eof;
- _test_eof6: cs = 6; goto _test_eof;
- _test_eof7: cs = 7; goto _test_eof;
- _test_eof8: cs = 8; goto _test_eof;
- _test_eof9: cs = 9; goto _test_eof;
-
- _test_eof: {}
- _out: {}
+ st_case_9:
+ if ( ( (*( p))) == 10 ) {
+ goto st1;
+ }
+ {
+ goto st9;
+ }
+ st_out:
+ _test_eof1: cs = 1; goto _test_eof;
+ _test_eof10: cs = 10; goto _test_eof;
+ _test_eof2: cs = 2; goto _test_eof;
+ _test_eof3: cs = 3; goto _test_eof;
+ _test_eof4: cs = 4; goto _test_eof;
+ _test_eof5: cs = 5; goto _test_eof;
+ _test_eof6: cs = 6; goto _test_eof;
+ _test_eof7: cs = 7; goto _test_eof;
+ _test_eof8: cs = 8; goto _test_eof;
+ _test_eof9: cs = 9; goto _test_eof;
+
+ _test_eof: {}
+ _out: {}
+ }
+
+ #line 854 "parser.rl"
+
+
+ if (cs >= JSON_first_final && p == pe) {
+ return result;
+ } else {
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
+ return Qnil;
}
-
-#line 848 "parser.rl"
-
- if (cs >= JSON_first_final && p == pe) {
- return result;
- } else {
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
- return Qnil;
- }
}
static void JSON_mark(void *ptr)
{
- JSON_Parser *json = ptr;
- rb_gc_mark_maybe(json->Vsource);
- rb_gc_mark_maybe(json->create_id);
- rb_gc_mark_maybe(json->object_class);
- rb_gc_mark_maybe(json->array_class);
- rb_gc_mark_maybe(json->decimal_class);
- rb_gc_mark_maybe(json->match_string);
+ JSON_Parser *json = ptr;
+ rb_gc_mark_maybe(json->Vsource);
+ rb_gc_mark_maybe(json->create_id);
+ rb_gc_mark_maybe(json->object_class);
+ rb_gc_mark_maybe(json->array_class);
+ rb_gc_mark_maybe(json->decimal_class);
+ rb_gc_mark_maybe(json->match_string);
}
static void JSON_free(void *ptr)
{
- JSON_Parser *json = ptr;
- fbuffer_free(json->fbuffer);
- ruby_xfree(json);
+ JSON_Parser *json = ptr;
+ fbuffer_free(json->fbuffer);
+ ruby_xfree(json);
}
static size_t JSON_memsize(const void *ptr)
{
- const JSON_Parser *json = ptr;
- return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
+ const JSON_Parser *json = ptr;
+ return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
}
#ifdef NEW_TYPEDDATA_WRAPPER
static const rb_data_type_t JSON_Parser_type = {
- "JSON/Parser",
- {JSON_mark, JSON_free, JSON_memsize,},
-#ifdef RUBY_TYPED_FREE_IMMEDIATELY
- 0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY,
-#endif
+ "JSON/Parser",
+ {JSON_mark, JSON_free, JSON_memsize,},
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
+ 0, 0,
+ RUBY_TYPED_FREE_IMMEDIATELY,
+ #endif
};
#endif
static VALUE cJSON_parser_s_allocate(VALUE klass)
{
- JSON_Parser *json;
- VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
- json->fbuffer = fbuffer_alloc(0);
- return obj;
+ JSON_Parser *json;
+ VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
+ json->fbuffer = fbuffer_alloc(0);
+ return obj;
}
/*
- * call-seq: source()
- *
- * Returns a copy of the current _source_ string, that was used to construct
- * this Parser.
- */
+* call-seq: source()
+*
+* Returns a copy of the current _source_ string, that was used to construct
+* this Parser.
+*/
static VALUE cParser_source(VALUE self)
{
- GET_PARSER;
- return rb_str_dup(json->Vsource);
+ GET_PARSER;
+ return rb_str_dup(json->Vsource);
}
void Init_parser(void)
{
-#ifdef HAVE_RB_EXT_RACTOR_SAFE
- rb_ext_ractor_safe(true);
-#endif
-
-#undef rb_intern
- rb_require("json/common");
- mJSON = rb_define_module("JSON");
- mExt = rb_define_module_under(mJSON, "Ext");
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
- eParserError = rb_path2class("JSON::ParserError");
- eNestingError = rb_path2class("JSON::NestingError");
- rb_gc_register_mark_object(eParserError);
- rb_gc_register_mark_object(eNestingError);
- rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
- rb_define_method(cParser, "initialize", cParser_initialize, -1);
- rb_define_method(cParser, "parse", cParser_parse, 0);
- rb_define_method(cParser, "source", cParser_source, 0);
-
- CNaN = rb_const_get(mJSON, rb_intern("NaN"));
- rb_gc_register_mark_object(CNaN);
-
- CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
- rb_gc_register_mark_object(CInfinity);
-
- CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
- rb_gc_register_mark_object(CMinusInfinity);
-
- i_json_creatable_p = rb_intern("json_creatable?");
- i_json_create = rb_intern("json_create");
- i_create_id = rb_intern("create_id");
- i_create_additions = rb_intern("create_additions");
- i_chr = rb_intern("chr");
- i_max_nesting = rb_intern("max_nesting");
- i_allow_nan = rb_intern("allow_nan");
- i_symbolize_names = rb_intern("symbolize_names");
- i_object_class = rb_intern("object_class");
- i_array_class = rb_intern("array_class");
- i_decimal_class = rb_intern("decimal_class");
- i_match = rb_intern("match");
- i_match_string = rb_intern("match_string");
- i_key_p = rb_intern("key?");
- i_deep_const_get = rb_intern("deep_const_get");
- i_aset = rb_intern("[]=");
- i_aref = rb_intern("[]");
- i_leftshift = rb_intern("<<");
- i_new = rb_intern("new");
- i_try_convert = rb_intern("try_convert");
- i_freeze = rb_intern("freeze");
- i_uminus = rb_intern("-@");
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+ #endif
+
+ #undef rb_intern
+ rb_require("json/common");
+ mJSON = rb_define_module("JSON");
+ mExt = rb_define_module_under(mJSON, "Ext");
+ cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
+ eParserError = rb_path2class("JSON::ParserError");
+ eNestingError = rb_path2class("JSON::NestingError");
+ rb_gc_register_mark_object(eParserError);
+ rb_gc_register_mark_object(eNestingError);
+ rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
+ rb_define_method(cParser, "initialize", cParser_initialize, -1);
+ rb_define_method(cParser, "parse", cParser_parse, 0);
+ rb_define_method(cParser, "source", cParser_source, 0);
+
+ CNaN = rb_const_get(mJSON, rb_intern("NaN"));
+ rb_gc_register_mark_object(CNaN);
+
+ CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
+ rb_gc_register_mark_object(CInfinity);
+
+ CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
+ rb_gc_register_mark_object(CMinusInfinity);
+
+ i_json_creatable_p = rb_intern("json_creatable?");
+ i_json_create = rb_intern("json_create");
+ i_create_id = rb_intern("create_id");
+ i_create_additions = rb_intern("create_additions");
+ i_chr = rb_intern("chr");
+ i_max_nesting = rb_intern("max_nesting");
+ i_allow_nan = rb_intern("allow_nan");
+ i_symbolize_names = rb_intern("symbolize_names");
+ i_object_class = rb_intern("object_class");
+ i_array_class = rb_intern("array_class");
+ i_decimal_class = rb_intern("decimal_class");
+ i_match = rb_intern("match");
+ i_match_string = rb_intern("match_string");
+ i_key_p = rb_intern("key?");
+ i_deep_const_get = rb_intern("deep_const_get");
+ i_aset = rb_intern("[]=");
+ i_aref = rb_intern("[]");
+ i_leftshift = rb_intern("<<");
+ i_new = rb_intern("new");
+ i_try_convert = rb_intern("try_convert");
+ i_freeze = rb_intern("freeze");
+ i_uminus = rb_intern("-@");
}
/*
- * Local variables:
- * mode: c
- * c-file-style: ruby
- * indent-tabs-mode: nil
- * End:
- */
+* Local variables:
+* mode: c
+* c-file-style: ruby
+* indent-tabs-mode: nil
+* End:
+*/
diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl
index af190e7500..2dbdc7ef24 100644
--- a/ext/json/parser/parser.rl
+++ b/ext/json/parser/parser.rl
@@ -229,7 +229,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
if (json->allow_nan) {
*result = CInfinity;
} else {
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 8);
}
}
action parse_string {
@@ -508,7 +508,7 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
case 'u':
if (pe > stringEnd - 4) {
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
+ free(bufferStart);
}
rb_enc_raise(
EXC_ENCODING eParserError,
@@ -521,7 +521,7 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
pe++;
if (pe > stringEnd - 6) {
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
+ free(bufferStart);
}
rb_enc_raise(
EXC_ENCODING eParserError,
@@ -566,13 +566,13 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
}
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
+ free(bufferStart);
}
# else
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
- ruby_xfree(bufferStart);
+ free(bufferStart);
}
if (intern) {
@@ -691,6 +691,8 @@ static VALUE convert_encoding(VALUE source)
*
* Creates a new JSON::Ext::Parser instance for the string _source_.
*
+ * Creates a new JSON::Ext::Parser instance for the string _source_.
+ *
* It will be configured by the _opts_ hash. _opts_ can have the following
* keys:
*
@@ -719,85 +721,98 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
if (json->Vsource) {
rb_raise(rb_eTypeError, "already initialized instance");
}
+#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
rb_scan_args(argc, argv, "1:", &source, &opts);
+#else
+ rb_scan_args(argc, argv, "11", &source, &opts);
+#endif
if (!NIL_P(opts)) {
- VALUE tmp = ID2SYM(i_max_nesting);
- if (option_given_p(opts, tmp)) {
- VALUE max_nesting = rb_hash_aref(opts, tmp);
- if (RTEST(max_nesting)) {
- Check_Type(max_nesting, T_FIXNUM);
- json->max_nesting = FIX2INT(max_nesting);
- } else {
- json->max_nesting = 0;
- }
- } else {
- json->max_nesting = 100;
- }
- tmp = ID2SYM(i_allow_nan);
- if (option_given_p(opts, tmp)) {
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
- } else {
- json->allow_nan = 0;
- }
- tmp = ID2SYM(i_symbolize_names);
- if (option_given_p(opts, tmp)) {
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
- } else {
- json->symbolize_names = 0;
- }
- tmp = ID2SYM(i_freeze);
- if (option_given_p(opts, tmp)) {
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
- } else {
- json->freeze = 0;
- }
- tmp = ID2SYM(i_create_additions);
- if (option_given_p(opts, tmp)) {
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
- } else {
- json->create_additions = 0;
- }
- if (json->symbolize_names && json->create_additions) {
- rb_raise(rb_eArgError,
- "options :symbolize_names and :create_additions cannot be "
- " used in conjunction");
- }
- tmp = ID2SYM(i_create_id);
- if (option_given_p(opts, tmp)) {
- json->create_id = rb_hash_aref(opts, tmp);
- } else {
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
- }
- tmp = ID2SYM(i_object_class);
- if (option_given_p(opts, tmp)) {
- json->object_class = rb_hash_aref(opts, tmp);
- } else {
- json->object_class = Qnil;
- }
- tmp = ID2SYM(i_array_class);
- if (option_given_p(opts, tmp)) {
- json->array_class = rb_hash_aref(opts, tmp);
- } else {
- json->array_class = Qnil;
- }
- tmp = ID2SYM(i_decimal_class);
- if (option_given_p(opts, tmp)) {
- json->decimal_class = rb_hash_aref(opts, tmp);
- } else {
- json->decimal_class = Qnil;
- }
- tmp = ID2SYM(i_match_string);
- if (option_given_p(opts, tmp)) {
- VALUE match_string = rb_hash_aref(opts, tmp);
- json->match_string = RTEST(match_string) ? match_string : Qnil;
- } else {
- json->match_string = Qnil;
- }
+#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+ opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
+ if (NIL_P(opts)) {
+ rb_raise(rb_eArgError, "opts needs to be like a hash");
+ } else {
+#endif
+ VALUE tmp = ID2SYM(i_max_nesting);
+ if (option_given_p(opts, tmp)) {
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
+ if (RTEST(max_nesting)) {
+ Check_Type(max_nesting, T_FIXNUM);
+ json->max_nesting = FIX2INT(max_nesting);
+ } else {
+ json->max_nesting = 0;
+ }
+ } else {
+ json->max_nesting = 100;
+ }
+ tmp = ID2SYM(i_allow_nan);
+ if (option_given_p(opts, tmp)) {
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->allow_nan = 0;
+ }
+ tmp = ID2SYM(i_symbolize_names);
+ if (option_given_p(opts, tmp)) {
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->symbolize_names = 0;
+ }
+ tmp = ID2SYM(i_freeze);
+ if (option_given_p(opts, tmp)) {
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
+ } else {
+ json->freeze = 0;
+ }
+ tmp = ID2SYM(i_create_additions);
+ if (option_given_p(opts, tmp)) {
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
+ } else {
+ json->create_additions = 0;
+ }
+ if (json->symbolize_names && json->create_additions) {
+ rb_raise(rb_eArgError,
+ "options :symbolize_names and :create_additions cannot be "
+ " used in conjunction");
+ }
+ tmp = ID2SYM(i_create_id);
+ if (option_given_p(opts, tmp)) {
+ json->create_id = rb_hash_aref(opts, tmp);
+ } else {
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
+ }
+ tmp = ID2SYM(i_object_class);
+ if (option_given_p(opts, tmp)) {
+ json->object_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->object_class = Qnil;
+ }
+ tmp = ID2SYM(i_array_class);
+ if (option_given_p(opts, tmp)) {
+ json->array_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->array_class = Qnil;
+ }
+ tmp = ID2SYM(i_decimal_class);
+ if (option_given_p(opts, tmp)) {
+ json->decimal_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->decimal_class = Qnil;
+ }
+ tmp = ID2SYM(i_match_string);
+ if (option_given_p(opts, tmp)) {
+ VALUE match_string = rb_hash_aref(opts, tmp);
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
+ } else {
+ json->match_string = Qnil;
+ }
+#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
+ }
+#endif
} else {
json->max_nesting = 100;
json->allow_nan = 0;
json->create_additions = 0;
- json->create_id = Qnil;
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
json->object_class = Qnil;
json->array_class = Qnil;
json->decimal_class = Qnil;
@@ -832,7 +847,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
*
* Parses the current JSON text _source_ and returns the complete data
* structure as a result.
- * It raises JSON::ParserError if fail to parse.
+ * It raises JSON::ParseError if fail to parse.
*/
static VALUE cParser_parse(VALUE self)
{
diff --git a/ext/monitor/depend b/ext/monitor/depend
index 38e21b3f66..3030da71d0 100644
--- a/ext/monitor/depend
+++ b/ext/monitor/depend
@@ -51,7 +51,6 @@ monitor.o: $(hdrdir)/ruby/internal/attr/noexcept.h
monitor.o: $(hdrdir)/ruby/internal/attr/noinline.h
monitor.o: $(hdrdir)/ruby/internal/attr/nonnull.h
monitor.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-monitor.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
monitor.o: $(hdrdir)/ruby/internal/attr/pure.h
monitor.o: $(hdrdir)/ruby/internal/attr/restrict.h
monitor.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ monitor.o: $(hdrdir)/ruby/internal/intern/enumerator.h
monitor.o: $(hdrdir)/ruby/internal/intern/error.h
monitor.o: $(hdrdir)/ruby/internal/intern/eval.h
monitor.o: $(hdrdir)/ruby/internal/intern/file.h
+monitor.o: $(hdrdir)/ruby/internal/intern/gc.h
monitor.o: $(hdrdir)/ruby/internal/intern/hash.h
monitor.o: $(hdrdir)/ruby/internal/intern/io.h
monitor.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ monitor.o: $(hdrdir)/ruby/internal/memory.h
monitor.o: $(hdrdir)/ruby/internal/method.h
monitor.o: $(hdrdir)/ruby/internal/module.h
monitor.o: $(hdrdir)/ruby/internal/newobj.h
+monitor.o: $(hdrdir)/ruby/internal/rgengc.h
monitor.o: $(hdrdir)/ruby/internal/scan_args.h
monitor.o: $(hdrdir)/ruby/internal/special_consts.h
monitor.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/monitor/lib/monitor.rb b/ext/monitor/lib/monitor.rb
index 31d6d2b3c4..11c5ac17d9 100644
--- a/ext/monitor/lib/monitor.rb
+++ b/ext/monitor/lib/monitor.rb
@@ -7,19 +7,17 @@
# You can freely distribute/modify this library.
#
-require 'monitor.so'
-
#
# In concurrent programming, a monitor is an object or module intended to be
-# used safely by more than one thread. The defining characteristic of a
-# monitor is that its methods are executed with mutual exclusion. That is, at
+# used safely by more than one thread. The defining characteristic of a
+# monitor is that its methods are executed with mutual exclusion. That is, at
# each point in time, at most one thread may be executing any of its methods.
# This mutual exclusion greatly simplifies reasoning about the implementation
# of monitors compared to reasoning about parallel code that updates a data
# structure.
#
# You can read more about the general principles on the Wikipedia page for
-# Monitors[https://en.wikipedia.org/wiki/Monitor_%28synchronization%29].
+# Monitors[https://en.wikipedia.org/wiki/Monitor_%28synchronization%29]
#
# == Examples
#
@@ -50,7 +48,7 @@ require 'monitor.so'
# end
#
# The consumer thread waits for the producer thread to push a line to buf
-# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
+# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
# line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt>
# to notify the consumer thread of new data.
#
@@ -88,6 +86,9 @@ require 'monitor.so'
# This Class is implemented as subclass of Array which includes the
# MonitorMixin module.
#
+
+require 'monitor.so'
+
module MonitorMixin
#
# FIXME: This isn't documented in Nutshell.
diff --git a/ext/monitor/monitor.c b/ext/monitor/monitor.c
index 86613f6ade..10209cf2aa 100644
--- a/ext/monitor/monitor.c
+++ b/ext/monitor/monitor.c
@@ -102,7 +102,7 @@ monitor_exit(VALUE monitor)
struct rb_monitor *mc = monitor_ptr(monitor);
- if (mc->count <= 0) rb_bug("monitor_exit: count:%d", (int)mc->count);
+ if (mc->count <= 0) rb_bug("monitor_exit: count:%d\n", (int)mc->count);
mc->count--;
if (mc->count == 0) {
diff --git a/ext/nkf/depend b/ext/nkf/depend
index 98afc5f201..9e2f468ba1 100644
--- a/ext/nkf/depend
+++ b/ext/nkf/depend
@@ -56,7 +56,6 @@ nkf.o: $(hdrdir)/ruby/internal/attr/noexcept.h
nkf.o: $(hdrdir)/ruby/internal/attr/noinline.h
nkf.o: $(hdrdir)/ruby/internal/attr/nonnull.h
nkf.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-nkf.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
nkf.o: $(hdrdir)/ruby/internal/attr/pure.h
nkf.o: $(hdrdir)/ruby/internal/attr/restrict.h
nkf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -125,6 +124,7 @@ nkf.o: $(hdrdir)/ruby/internal/intern/enumerator.h
nkf.o: $(hdrdir)/ruby/internal/intern/error.h
nkf.o: $(hdrdir)/ruby/internal/intern/eval.h
nkf.o: $(hdrdir)/ruby/internal/intern/file.h
+nkf.o: $(hdrdir)/ruby/internal/intern/gc.h
nkf.o: $(hdrdir)/ruby/internal/intern/hash.h
nkf.o: $(hdrdir)/ruby/internal/intern/io.h
nkf.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -155,6 +155,7 @@ nkf.o: $(hdrdir)/ruby/internal/memory.h
nkf.o: $(hdrdir)/ruby/internal/method.h
nkf.o: $(hdrdir)/ruby/internal/module.h
nkf.o: $(hdrdir)/ruby/internal/newobj.h
+nkf.o: $(hdrdir)/ruby/internal/rgengc.h
nkf.o: $(hdrdir)/ruby/internal/scan_args.h
nkf.o: $(hdrdir)/ruby/internal/special_consts.h
nkf.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/nkf/nkf.c b/ext/nkf/nkf.c
index 73b616a54f..c6ddee1976 100644
--- a/ext/nkf/nkf.c
+++ b/ext/nkf/nkf.c
@@ -9,7 +9,6 @@
#define RUBY_NKF_REVISION "$Revision$"
#define RUBY_NKF_VERSION NKF_VERSION " (" NKF_RELEASE_DATE ")"
-#define NKF_GEM_VERSION "0.1.3"
#include "ruby/ruby.h"
#include "ruby/encoding.h"
@@ -501,6 +500,4 @@ Init_nkf(void)
rb_define_const(mNKF, "NKF_VERSION", rb_str_new2(NKF_VERSION));
/* Release date of nkf */
rb_define_const(mNKF, "NKF_RELEASE_DATE", rb_str_new2(NKF_RELEASE_DATE));
- /* Version of nkf library */
- rb_define_const(mNKF, "GEM_VERSION", rb_str_new_cstr(NKF_GEM_VERSION));
}
diff --git a/ext/nkf/nkf.gemspec b/ext/nkf/nkf.gemspec
index 097a9485ed..7f3bd4a4b1 100644
--- a/ext/nkf/nkf.gemspec
+++ b/ext/nkf/nkf.gemspec
@@ -1,16 +1,6 @@
-source_version = ["", "ext/nkf/"].find do |dir|
- begin
- break File.open(File.join(__dir__, "#{dir}nkf.c")) {|f|
- f.gets("\n#define NKF_GEM_VERSION ")
- f.gets[/\s*"(.+)"/, 1]
- }
- rescue Errno::ENOENT
- end
-end
-
Gem::Specification.new do |spec|
spec.name = "nkf"
- spec.version = source_version
+ spec.version = "0.1.2"
spec.authors = ["NARUSE Yui"]
spec.email = ["naruse@airemix.jp"]
@@ -31,5 +21,4 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
- spec.extensions = ["ext/nkf/extconf.rb"]
end
diff --git a/ext/objspace/depend b/ext/objspace/depend
index 85e99a71b4..52797664e0 100644
--- a/ext/objspace/depend
+++ b/ext/objspace/depend
@@ -2,12 +2,10 @@
object_tracing.o: $(RUBY_EXTCONF_H)
object_tracing.o: $(arch_hdrdir)/ruby/config.h
object_tracing.o: $(hdrdir)/ruby/assert.h
-object_tracing.o: $(hdrdir)/ruby/atomic.h
object_tracing.o: $(hdrdir)/ruby/backward.h
object_tracing.o: $(hdrdir)/ruby/backward/2/assume.h
object_tracing.o: $(hdrdir)/ruby/backward/2/attributes.h
object_tracing.o: $(hdrdir)/ruby/backward/2/bool.h
-object_tracing.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
object_tracing.o: $(hdrdir)/ruby/backward/2/inttypes.h
object_tracing.o: $(hdrdir)/ruby/backward/2/limits.h
object_tracing.o: $(hdrdir)/ruby/backward/2/long_long.h
@@ -15,7 +13,6 @@ object_tracing.o: $(hdrdir)/ruby/backward/2/stdalign.h
object_tracing.o: $(hdrdir)/ruby/backward/2/stdarg.h
object_tracing.o: $(hdrdir)/ruby/debug.h
object_tracing.o: $(hdrdir)/ruby/defines.h
-object_tracing.o: $(hdrdir)/ruby/encoding.h
object_tracing.o: $(hdrdir)/ruby/intern.h
object_tracing.o: $(hdrdir)/ruby/internal/abi.h
object_tracing.o: $(hdrdir)/ruby/internal/anyargs.h
@@ -55,7 +52,6 @@ object_tracing.o: $(hdrdir)/ruby/internal/attr/noexcept.h
object_tracing.o: $(hdrdir)/ruby/internal/attr/noinline.h
object_tracing.o: $(hdrdir)/ruby/internal/attr/nonnull.h
object_tracing.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-object_tracing.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
object_tracing.o: $(hdrdir)/ruby/internal/attr/pure.h
object_tracing.o: $(hdrdir)/ruby/internal/attr/restrict.h
object_tracing.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -88,15 +84,6 @@ object_tracing.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
object_tracing.o: $(hdrdir)/ruby/internal/ctype.h
object_tracing.o: $(hdrdir)/ruby/internal/dllexport.h
object_tracing.o: $(hdrdir)/ruby/internal/dosish.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/coderange.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/ctype.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/encoding.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/pathname.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/re.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/string.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/symbol.h
-object_tracing.o: $(hdrdir)/ruby/internal/encoding/transcode.h
object_tracing.o: $(hdrdir)/ruby/internal/error.h
object_tracing.o: $(hdrdir)/ruby/internal/eval.h
object_tracing.o: $(hdrdir)/ruby/internal/event.h
@@ -124,6 +111,7 @@ object_tracing.o: $(hdrdir)/ruby/internal/intern/enumerator.h
object_tracing.o: $(hdrdir)/ruby/internal/intern/error.h
object_tracing.o: $(hdrdir)/ruby/internal/intern/eval.h
object_tracing.o: $(hdrdir)/ruby/internal/intern/file.h
+object_tracing.o: $(hdrdir)/ruby/internal/intern/gc.h
object_tracing.o: $(hdrdir)/ruby/internal/intern/hash.h
object_tracing.o: $(hdrdir)/ruby/internal/intern/io.h
object_tracing.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -154,6 +142,7 @@ object_tracing.o: $(hdrdir)/ruby/internal/memory.h
object_tracing.o: $(hdrdir)/ruby/internal/method.h
object_tracing.o: $(hdrdir)/ruby/internal/module.h
object_tracing.o: $(hdrdir)/ruby/internal/newobj.h
+object_tracing.o: $(hdrdir)/ruby/internal/rgengc.h
object_tracing.o: $(hdrdir)/ruby/internal/scan_args.h
object_tracing.o: $(hdrdir)/ruby/internal/special_consts.h
object_tracing.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -166,37 +155,13 @@ object_tracing.o: $(hdrdir)/ruby/internal/variable.h
object_tracing.o: $(hdrdir)/ruby/internal/warning_push.h
object_tracing.o: $(hdrdir)/ruby/internal/xmalloc.h
object_tracing.o: $(hdrdir)/ruby/missing.h
-object_tracing.o: $(hdrdir)/ruby/onigmo.h
-object_tracing.o: $(hdrdir)/ruby/oniguruma.h
object_tracing.o: $(hdrdir)/ruby/ruby.h
object_tracing.o: $(hdrdir)/ruby/st.h
object_tracing.o: $(hdrdir)/ruby/subst.h
-object_tracing.o: $(hdrdir)/ruby/thread_native.h
-object_tracing.o: $(top_srcdir)/ccan/check_type/check_type.h
-object_tracing.o: $(top_srcdir)/ccan/container_of/container_of.h
-object_tracing.o: $(top_srcdir)/ccan/list/list.h
-object_tracing.o: $(top_srcdir)/ccan/str/str.h
+object_tracing.o: $(top_srcdir)/gc.h
object_tracing.o: $(top_srcdir)/internal.h
-object_tracing.o: $(top_srcdir)/internal/array.h
-object_tracing.o: $(top_srcdir)/internal/basic_operators.h
-object_tracing.o: $(top_srcdir)/internal/compilers.h
-object_tracing.o: $(top_srcdir)/internal/gc.h
-object_tracing.o: $(top_srcdir)/internal/imemo.h
-object_tracing.o: $(top_srcdir)/internal/serial.h
-object_tracing.o: $(top_srcdir)/internal/static_assert.h
-object_tracing.o: $(top_srcdir)/internal/vm.h
-object_tracing.o: $(top_srcdir)/internal/warnings.h
-object_tracing.o: $(top_srcdir)/method.h
-object_tracing.o: $(top_srcdir)/node.h
-object_tracing.o: $(top_srcdir)/ruby_assert.h
-object_tracing.o: $(top_srcdir)/ruby_atomic.h
-object_tracing.o: $(top_srcdir)/rubyparser.h
-object_tracing.o: $(top_srcdir)/thread_pthread.h
-object_tracing.o: $(top_srcdir)/vm_core.h
-object_tracing.o: $(top_srcdir)/vm_opts.h
object_tracing.o: object_tracing.c
object_tracing.o: objspace.h
-object_tracing.o: {$(VPATH)}id.h
objspace.o: $(RUBY_EXTCONF_H)
objspace.o: $(arch_hdrdir)/ruby/config.h
objspace.o: $(hdrdir)/ruby/assert.h
@@ -252,7 +217,6 @@ objspace.o: $(hdrdir)/ruby/internal/attr/noexcept.h
objspace.o: $(hdrdir)/ruby/internal/attr/noinline.h
objspace.o: $(hdrdir)/ruby/internal/attr/nonnull.h
objspace.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-objspace.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
objspace.o: $(hdrdir)/ruby/internal/attr/pure.h
objspace.o: $(hdrdir)/ruby/internal/attr/restrict.h
objspace.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -322,6 +286,7 @@ objspace.o: $(hdrdir)/ruby/internal/intern/enumerator.h
objspace.o: $(hdrdir)/ruby/internal/intern/error.h
objspace.o: $(hdrdir)/ruby/internal/intern/eval.h
objspace.o: $(hdrdir)/ruby/internal/intern/file.h
+objspace.o: $(hdrdir)/ruby/internal/intern/gc.h
objspace.o: $(hdrdir)/ruby/internal/intern/hash.h
objspace.o: $(hdrdir)/ruby/internal/intern/io.h
objspace.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -352,6 +317,7 @@ objspace.o: $(hdrdir)/ruby/internal/memory.h
objspace.o: $(hdrdir)/ruby/internal/method.h
objspace.o: $(hdrdir)/ruby/internal/module.h
objspace.o: $(hdrdir)/ruby/internal/newobj.h
+objspace.o: $(hdrdir)/ruby/internal/rgengc.h
objspace.o: $(hdrdir)/ruby/internal/scan_args.h
objspace.o: $(hdrdir)/ruby/internal/special_consts.h
objspace.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -377,8 +343,7 @@ objspace.o: $(top_srcdir)/ccan/check_type/check_type.h
objspace.o: $(top_srcdir)/ccan/container_of/container_of.h
objspace.o: $(top_srcdir)/ccan/list/list.h
objspace.o: $(top_srcdir)/ccan/str/str.h
-objspace.o: $(top_srcdir)/constant.h
-objspace.o: $(top_srcdir)/debug_counter.h
+objspace.o: $(top_srcdir)/gc.h
objspace.o: $(top_srcdir)/id_table.h
objspace.o: $(top_srcdir)/internal.h
objspace.o: $(top_srcdir)/internal/array.h
@@ -391,21 +356,17 @@ objspace.o: $(top_srcdir)/internal/imemo.h
objspace.o: $(top_srcdir)/internal/sanitizers.h
objspace.o: $(top_srcdir)/internal/serial.h
objspace.o: $(top_srcdir)/internal/static_assert.h
-objspace.o: $(top_srcdir)/internal/variable.h
objspace.o: $(top_srcdir)/internal/vm.h
objspace.o: $(top_srcdir)/internal/warnings.h
objspace.o: $(top_srcdir)/method.h
objspace.o: $(top_srcdir)/node.h
objspace.o: $(top_srcdir)/ruby_assert.h
objspace.o: $(top_srcdir)/ruby_atomic.h
-objspace.o: $(top_srcdir)/rubyparser.h
objspace.o: $(top_srcdir)/shape.h
objspace.o: $(top_srcdir)/symbol.h
objspace.o: $(top_srcdir)/thread_pthread.h
objspace.o: $(top_srcdir)/vm_core.h
-objspace.o: $(top_srcdir)/vm_debug.h
objspace.o: $(top_srcdir)/vm_opts.h
-objspace.o: $(top_srcdir)/vm_sync.h
objspace.o: objspace.c
objspace.o: {$(VPATH)}id.h
objspace_dump.o: $(RUBY_EXTCONF_H)
@@ -464,7 +425,6 @@ objspace_dump.o: $(hdrdir)/ruby/internal/attr/noexcept.h
objspace_dump.o: $(hdrdir)/ruby/internal/attr/noinline.h
objspace_dump.o: $(hdrdir)/ruby/internal/attr/nonnull.h
objspace_dump.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-objspace_dump.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
objspace_dump.o: $(hdrdir)/ruby/internal/attr/pure.h
objspace_dump.o: $(hdrdir)/ruby/internal/attr/restrict.h
objspace_dump.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -533,6 +493,7 @@ objspace_dump.o: $(hdrdir)/ruby/internal/intern/enumerator.h
objspace_dump.o: $(hdrdir)/ruby/internal/intern/error.h
objspace_dump.o: $(hdrdir)/ruby/internal/intern/eval.h
objspace_dump.o: $(hdrdir)/ruby/internal/intern/file.h
+objspace_dump.o: $(hdrdir)/ruby/internal/intern/gc.h
objspace_dump.o: $(hdrdir)/ruby/internal/intern/hash.h
objspace_dump.o: $(hdrdir)/ruby/internal/intern/io.h
objspace_dump.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -563,6 +524,7 @@ objspace_dump.o: $(hdrdir)/ruby/internal/memory.h
objspace_dump.o: $(hdrdir)/ruby/internal/method.h
objspace_dump.o: $(hdrdir)/ruby/internal/module.h
objspace_dump.o: $(hdrdir)/ruby/internal/newobj.h
+objspace_dump.o: $(hdrdir)/ruby/internal/rgengc.h
objspace_dump.o: $(hdrdir)/ruby/internal/scan_args.h
objspace_dump.o: $(hdrdir)/ruby/internal/special_consts.h
objspace_dump.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -588,7 +550,7 @@ objspace_dump.o: $(top_srcdir)/ccan/container_of/container_of.h
objspace_dump.o: $(top_srcdir)/ccan/list/list.h
objspace_dump.o: $(top_srcdir)/ccan/str/str.h
objspace_dump.o: $(top_srcdir)/constant.h
-objspace_dump.o: $(top_srcdir)/debug_counter.h
+objspace_dump.o: $(top_srcdir)/gc.h
objspace_dump.o: $(top_srcdir)/id_table.h
objspace_dump.o: $(top_srcdir)/internal.h
objspace_dump.o: $(top_srcdir)/internal/array.h
@@ -598,7 +560,6 @@ objspace_dump.o: $(top_srcdir)/internal/compilers.h
objspace_dump.o: $(top_srcdir)/internal/gc.h
objspace_dump.o: $(top_srcdir)/internal/hash.h
objspace_dump.o: $(top_srcdir)/internal/imemo.h
-objspace_dump.o: $(top_srcdir)/internal/io.h
objspace_dump.o: $(top_srcdir)/internal/sanitizers.h
objspace_dump.o: $(top_srcdir)/internal/serial.h
objspace_dump.o: $(top_srcdir)/internal/static_assert.h
@@ -610,15 +571,11 @@ objspace_dump.o: $(top_srcdir)/method.h
objspace_dump.o: $(top_srcdir)/node.h
objspace_dump.o: $(top_srcdir)/ruby_assert.h
objspace_dump.o: $(top_srcdir)/ruby_atomic.h
-objspace_dump.o: $(top_srcdir)/rubyparser.h
objspace_dump.o: $(top_srcdir)/shape.h
objspace_dump.o: $(top_srcdir)/symbol.h
objspace_dump.o: $(top_srcdir)/thread_pthread.h
-objspace_dump.o: $(top_srcdir)/vm_callinfo.h
objspace_dump.o: $(top_srcdir)/vm_core.h
-objspace_dump.o: $(top_srcdir)/vm_debug.h
objspace_dump.o: $(top_srcdir)/vm_opts.h
-objspace_dump.o: $(top_srcdir)/vm_sync.h
objspace_dump.o: objspace.h
objspace_dump.o: objspace_dump.c
objspace_dump.o: {$(VPATH)}id.h
diff --git a/ext/objspace/lib/objspace.rb b/ext/objspace/lib/objspace.rb
index 47873f5112..6865fdda4c 100644
--- a/ext/objspace/lib/objspace.rb
+++ b/ext/objspace/lib/objspace.rb
@@ -11,15 +11,12 @@ module ObjectSpace
module_function
- # Dump the contents of a ruby object as JSON.
- #
- # _output_ can be one of: +:stdout+, +:file+, +:string+, or IO object.
+ # call-seq:
+ # ObjectSpace.dump(obj[, output: :string]) -> "{ ... }"
+ # ObjectSpace.dump(obj, output: :file) -> #<File:/tmp/rubyobj20131125-88733-1xkfmpv.json>
+ # ObjectSpace.dump(obj, output: :stdout) -> nil
#
- # * +:file+ means dumping to a tempfile and returning corresponding File object;
- # * +:stdout+ means printing the dump and returning +nil+;
- # * +:string+ means returning a string with the dump;
- # * if an instance of IO object is provided, the output goes there, and the object
- # is returned.
+ # Dump the contents of a ruby object as JSON.
#
# This method is only expected to work with C Ruby.
# This is an experimental method and is subject to change.
@@ -46,11 +43,16 @@ module ObjectSpace
end
- # Dump the contents of the ruby heap as JSON.
+ # call-seq:
+ # ObjectSpace.dump_all([output: :file]) -> #<File:/tmp/rubyheap20131125-88469-laoj3v.json>
+ # ObjectSpace.dump_all(output: :stdout) -> nil
+ # ObjectSpace.dump_all(output: :string) -> "{...}\n{...}\n..."
+ # ObjectSpace.dump_all(output: File.open('heap.json','w')) -> #<File:heap.json>
+ # ObjectSpace.dump_all(output: :string, since: 42) -> "{...}\n{...}\n..."
#
- # _output_ argument is the same as for #dump.
+ # Dump the contents of the ruby heap as JSON.
#
- # _full_ must be a boolean. If true, all heap slots are dumped including the empty ones (+T_NONE+).
+ # _full_ must be a boolean. If true all heap slots are dumped including the empty ones (T_NONE).
#
# _since_ must be a non-negative integer or +nil+.
#
@@ -102,11 +104,16 @@ module ObjectSpace
ret
end
- # Dump the contents of the ruby shape tree as JSON.
+ # call-seq:
+ # ObjectSpace.dump_shapes([output: :file]) -> #<File:/tmp/rubyshapes20131125-88469-laoj3v.json>
+ # ObjectSpace.dump_shapes(output: :stdout) -> nil
+ # ObjectSpace.dump_shapes(output: :string) -> "{...}\n{...}\n..."
+ # ObjectSpace.dump_shapes(output: File.open('shapes.json','w')) -> #<File:shapes.json>
+ # ObjectSpace.dump_all(output: :string, since: 42) -> "{...}\n{...}\n..."
#
- # _output_ argument is the same as for #dump.
+ # Dump the contents of the ruby shape tree as JSON.
#
- # If _since_ is a positive integer, only shapes newer than the provided
+ # If _shapes_ is a positive integer, only shapes newer than the provided
# shape id are dumped. The current shape_id can be accessed using <tt>RubyVM.stat(:next_shape_id)</tt>.
#
# This method is only expected to work with C Ruby.
diff --git a/ext/objspace/object_tracing.c b/ext/objspace/object_tracing.c
index c1c93c51f5..8c54d51eab 100644
--- a/ext/objspace/object_tracing.c
+++ b/ext/objspace/object_tracing.c
@@ -13,8 +13,8 @@
**********************************************************************/
+#include "gc.h"
#include "internal.h"
-#include "internal/gc.h"
#include "ruby/debug.h"
#include "objspace.h"
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 0a7896d5c6..ca08604c95 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -12,13 +12,14 @@
**********************************************************************/
+#include "gc.h"
#include "internal.h"
#include "internal/class.h"
#include "internal/compilers.h"
-#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/imemo.h"
#include "internal/sanitizers.h"
+#include "node.h"
#include "ruby/io.h"
#include "ruby/re.h"
#include "ruby/st.h"
@@ -336,6 +337,17 @@ count_symbols(int argc, VALUE *argv, VALUE os)
return hash;
}
+static void
+cn_i(VALUE v, void *n)
+{
+ size_t *nodes = (size_t *)n;
+
+ if (BUILTIN_TYPE(v) == T_NODE) {
+ size_t s = nd_type((NODE *)v);
+ nodes[s]++;
+ }
+}
+
/*
* call-seq:
* ObjectSpace.count_nodes([result_hash]) -> hash
@@ -362,7 +374,135 @@ count_symbols(int argc, VALUE *argv, VALUE os)
static VALUE
count_nodes(int argc, VALUE *argv, VALUE os)
{
- return setup_hash(argc, argv);
+ size_t nodes[NODE_LAST+1];
+ enum node_type i;
+ VALUE hash = setup_hash(argc, argv);
+
+ for (i = 0; i <= NODE_LAST; i++) {
+ nodes[i] = 0;
+ }
+
+ each_object_with_flags(cn_i, &nodes[0]);
+
+ for (i=0; i<NODE_LAST; i++) {
+ if (nodes[i] != 0) {
+ VALUE node;
+ switch (i) {
+#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); goto set
+ COUNT_NODE(NODE_SCOPE);
+ COUNT_NODE(NODE_BLOCK);
+ COUNT_NODE(NODE_IF);
+ COUNT_NODE(NODE_UNLESS);
+ COUNT_NODE(NODE_CASE);
+ COUNT_NODE(NODE_CASE2);
+ COUNT_NODE(NODE_CASE3);
+ COUNT_NODE(NODE_WHEN);
+ COUNT_NODE(NODE_IN);
+ COUNT_NODE(NODE_WHILE);
+ COUNT_NODE(NODE_UNTIL);
+ COUNT_NODE(NODE_ITER);
+ COUNT_NODE(NODE_FOR);
+ COUNT_NODE(NODE_FOR_MASGN);
+ COUNT_NODE(NODE_BREAK);
+ COUNT_NODE(NODE_NEXT);
+ COUNT_NODE(NODE_REDO);
+ COUNT_NODE(NODE_RETRY);
+ COUNT_NODE(NODE_BEGIN);
+ COUNT_NODE(NODE_RESCUE);
+ COUNT_NODE(NODE_RESBODY);
+ COUNT_NODE(NODE_ENSURE);
+ COUNT_NODE(NODE_AND);
+ COUNT_NODE(NODE_OR);
+ COUNT_NODE(NODE_MASGN);
+ COUNT_NODE(NODE_LASGN);
+ COUNT_NODE(NODE_DASGN);
+ COUNT_NODE(NODE_GASGN);
+ COUNT_NODE(NODE_IASGN);
+ COUNT_NODE(NODE_CDECL);
+ COUNT_NODE(NODE_CVASGN);
+ COUNT_NODE(NODE_OP_ASGN1);
+ COUNT_NODE(NODE_OP_ASGN2);
+ COUNT_NODE(NODE_OP_ASGN_AND);
+ COUNT_NODE(NODE_OP_ASGN_OR);
+ COUNT_NODE(NODE_OP_CDECL);
+ COUNT_NODE(NODE_CALL);
+ COUNT_NODE(NODE_OPCALL);
+ COUNT_NODE(NODE_FCALL);
+ COUNT_NODE(NODE_VCALL);
+ COUNT_NODE(NODE_QCALL);
+ COUNT_NODE(NODE_SUPER);
+ COUNT_NODE(NODE_ZSUPER);
+ COUNT_NODE(NODE_LIST);
+ COUNT_NODE(NODE_ZLIST);
+ COUNT_NODE(NODE_VALUES);
+ COUNT_NODE(NODE_HASH);
+ COUNT_NODE(NODE_RETURN);
+ COUNT_NODE(NODE_YIELD);
+ COUNT_NODE(NODE_LVAR);
+ COUNT_NODE(NODE_DVAR);
+ COUNT_NODE(NODE_GVAR);
+ COUNT_NODE(NODE_IVAR);
+ COUNT_NODE(NODE_CONST);
+ COUNT_NODE(NODE_CVAR);
+ COUNT_NODE(NODE_NTH_REF);
+ COUNT_NODE(NODE_BACK_REF);
+ COUNT_NODE(NODE_MATCH);
+ COUNT_NODE(NODE_MATCH2);
+ COUNT_NODE(NODE_MATCH3);
+ COUNT_NODE(NODE_LIT);
+ COUNT_NODE(NODE_STR);
+ COUNT_NODE(NODE_DSTR);
+ COUNT_NODE(NODE_XSTR);
+ COUNT_NODE(NODE_DXSTR);
+ COUNT_NODE(NODE_EVSTR);
+ COUNT_NODE(NODE_DREGX);
+ COUNT_NODE(NODE_ONCE);
+ COUNT_NODE(NODE_ARGS);
+ COUNT_NODE(NODE_ARGS_AUX);
+ COUNT_NODE(NODE_OPT_ARG);
+ COUNT_NODE(NODE_KW_ARG);
+ COUNT_NODE(NODE_POSTARG);
+ COUNT_NODE(NODE_ARGSCAT);
+ COUNT_NODE(NODE_ARGSPUSH);
+ COUNT_NODE(NODE_SPLAT);
+ COUNT_NODE(NODE_BLOCK_PASS);
+ COUNT_NODE(NODE_DEFN);
+ COUNT_NODE(NODE_DEFS);
+ COUNT_NODE(NODE_ALIAS);
+ COUNT_NODE(NODE_VALIAS);
+ COUNT_NODE(NODE_UNDEF);
+ COUNT_NODE(NODE_CLASS);
+ COUNT_NODE(NODE_MODULE);
+ COUNT_NODE(NODE_SCLASS);
+ COUNT_NODE(NODE_COLON2);
+ COUNT_NODE(NODE_COLON3);
+ COUNT_NODE(NODE_DOT2);
+ COUNT_NODE(NODE_DOT3);
+ COUNT_NODE(NODE_FLIP2);
+ COUNT_NODE(NODE_FLIP3);
+ COUNT_NODE(NODE_SELF);
+ COUNT_NODE(NODE_NIL);
+ COUNT_NODE(NODE_TRUE);
+ COUNT_NODE(NODE_FALSE);
+ COUNT_NODE(NODE_ERRINFO);
+ COUNT_NODE(NODE_DEFINED);
+ COUNT_NODE(NODE_POSTEXE);
+ COUNT_NODE(NODE_DSYM);
+ COUNT_NODE(NODE_ATTRASGN);
+ COUNT_NODE(NODE_LAMBDA);
+ COUNT_NODE(NODE_ARYPTN);
+ COUNT_NODE(NODE_FNDPTN);
+ COUNT_NODE(NODE_HSHPTN);
+ COUNT_NODE(NODE_ERROR);
+#undef COUNT_NODE
+ case NODE_LAST: break;
+ }
+ UNREACHABLE;
+ set:
+ rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
+ }
+ }
+ return hash;
}
static void
@@ -814,7 +954,7 @@ void Init_objspace_dump(VALUE rb_mObjSpace);
*
* You need to <code>require 'objspace'</code> to use this extension module.
*
- * Generally, you *SHOULD* *NOT* use this library if you do not know
+ * Generally, you *SHOULD NOT* use this library if you do not know
* about the MRI implementation. Mainly, this library is for (memory)
* profiler developers and MRI developers who need to know about MRI
* memory usage.
diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c
index 866a49eff4..c3cc9a1e7b 100644
--- a/ext/objspace/objspace_dump.c
+++ b/ext/objspace/objspace_dump.c
@@ -12,13 +12,12 @@
**********************************************************************/
+#include "gc.h"
#include "id_table.h"
#include "internal.h"
#include "internal/array.h"
#include "internal/class.h"
-#include "internal/gc.h"
#include "internal/hash.h"
-#include "internal/io.h"
#include "internal/string.h"
#include "internal/sanitizers.h"
#include "symbol.h"
@@ -28,7 +27,6 @@
#include "ruby/debug.h"
#include "ruby/util.h"
#include "ruby/io.h"
-#include "vm_callinfo.h"
#include "vm_core.h"
RUBY_EXTERN const char ruby_hexdigits[];
@@ -168,8 +166,10 @@ dump_append_c(struct dump_config *dc, unsigned char c)
}
static void
-dump_append_ptr(struct dump_config *dc, VALUE ref)
+dump_append_ref(struct dump_config *dc, VALUE ref)
{
+ RUBY_ASSERT(ref > 0);
+
char buffer[roomof(sizeof(VALUE) * CHAR_BIT, 4) + rb_strlen_lit("\"0x\"")];
char *buffer_start, *buffer_end;
@@ -186,14 +186,6 @@ dump_append_ptr(struct dump_config *dc, VALUE ref)
}
static void
-dump_append_ref(struct dump_config *dc, VALUE ref)
-{
- RUBY_ASSERT(ref > 0);
- dump_append_ptr(dc, ref);
-}
-
-
-static void
dump_append_string_value(struct dump_config *dc, VALUE obj)
{
long i;
@@ -366,9 +358,8 @@ dump_append_string_content(struct dump_config *dc, VALUE obj)
static inline void
dump_append_id(struct dump_config *dc, ID id)
{
- VALUE str = rb_sym2str(ID2SYM(id));
- if (RTEST(str)) {
- dump_append_string_value(dc, str);
+ if (is_instance_id(id)) {
+ dump_append_string_value(dc, rb_sym2str(ID2SYM(id)));
}
else {
dump_append(dc, "\"ID_INTERNAL(");
@@ -386,7 +377,6 @@ dump_object(VALUE obj, struct dump_config *dc)
rb_io_t *fptr;
ID flags[RB_OBJ_GC_FLAGS_MAX];
size_t n, i;
- ID mid;
if (SPECIAL_CONST_P(obj)) {
dump_append_special_const(dc, obj);
@@ -438,33 +428,6 @@ dump_object(VALUE obj, struct dump_config *dc)
dump_append(dc, ", \"imemo_type\":\"");
dump_append(dc, rb_imemo_name(imemo_type(obj)));
dump_append(dc, "\"");
-
- switch (imemo_type(obj)) {
- case imemo_callinfo:
- mid = vm_ci_mid((const struct rb_callinfo *)obj);
- if (mid != 0) {
- dump_append(dc, ", \"mid\":");
- dump_append_id(dc, mid);
- }
- break;
-
- case imemo_callcache:
- mid = vm_cc_cme((const struct rb_callcache *)obj)->called_id;
- if (mid != 0) {
- dump_append(dc, ", \"called_id\":");
- dump_append_id(dc, mid);
-
- VALUE klass = ((const struct rb_callcache *)obj)->klass;
- if (klass != 0) {
- dump_append(dc, ", \"receiver_class\":");
- dump_append_ref(dc, klass);
- }
- }
- break;
-
- default:
- break;
- }
break;
case T_SYMBOL:
@@ -581,10 +544,6 @@ dump_object(VALUE obj, struct dump_config *dc)
break;
case T_OBJECT:
- if (FL_TEST(obj, ROBJECT_EMBED)) {
- dump_append(dc, ", \"embedded\":true");
- }
-
dump_append(dc, ", \"ivars\":");
dump_append_lu(dc, ROBJECT_IV_COUNT(obj));
if (rb_shape_obj_too_complex(obj)) {
@@ -792,6 +751,16 @@ shape_i(rb_shape_t *shape, void *data)
case SHAPE_FROZEN:
dump_append(dc, "\"FROZEN\"");
break;
+ case SHAPE_CAPACITY_CHANGE:
+ dump_append(dc, "\"CAPACITY_CHANGE\"");
+ dump_append(dc, ", \"capacity\":");
+ dump_append_sizet(dc, shape->capacity);
+ break;
+ case SHAPE_INITIAL_CAPACITY:
+ dump_append(dc, "\"INITIAL_CAPACITY\"");
+ dump_append(dc, ", \"capacity\":");
+ dump_append_sizet(dc, shape->capacity);
+ break;
case SHAPE_T_OBJECT:
dump_append(dc, "\"T_OBJECT\"");
break;
diff --git a/ext/openssl/History.md b/ext/openssl/History.md
index 3249f6617a..1e0df7dd87 100644
--- a/ext/openssl/History.md
+++ b/ext/openssl/History.md
@@ -1,43 +1,3 @@
-Version 3.2.0
-=============
-
-Compatibility
--------------
-
-* Ruby >= 2.7
- - Support for Ruby 2.6 has been removed. Note that Ruby 2.6 reached the
- end-of-life in 2022-04.
- [[GitHub #639]](https://github.com/ruby/openssl/pull/639)
-* OpenSSL >= 1.0.2 or LibreSSL >= 3.1
-
-Notable changes
----------------
-
-* Add a stub gemspec for JRuby, which depends on the `jruby-openssl` gem.
- [[GitHub #598]](https://github.com/ruby/openssl/pull/598)
-* Add support for the FIPS module in OpenSSL 3.0/3.1.
- [[GitHub #608]](https://github.com/ruby/openssl/pull/608)
-* Rework `OpenSSL::PKey` routines for loading DER or PEM encoded keys for better
- compatibility with OpenSSL 3.0/3.1 with the FIPS module.
- [[GitHub #615]](https://github.com/ruby/openssl/pull/615)
- [[GitHub #669]](https://github.com/ruby/openssl/pull/669)
-* Add `OpenSSL::Provider` module for loading and unloading OpenSSL 3 providers.
- [[GitHub #635]](https://github.com/ruby/openssl/pull/635)
-* Add `OpenSSL::PKey.new_raw_private_key`, `.new_raw_public_key`,
- `OpenSSL::PKey::PKey#raw_private_key`, and `#raw_public_key` for public key
- algorithms that use "raw private/public key", such as X25519 and Ed25519.
- [[GitHub #646]](https://github.com/ruby/openssl/pull/646)
-* Improve OpenSSL error messages to include additional information when
- it is available in OpenSSL's error queue.
- [[GitHub #648]](https://github.com/ruby/openssl/pull/648)
-* Change `OpenSSL::SSL::SSLContext#ca_file=` and `#ca_path=` to raise
- `OpenSSL::SSL::SSLError` instead of printing a warning message.
- [[GitHub #659]](https://github.com/ruby/openssl/pull/659)
-* Allow `OpenSSL::X509::ExtensionFactory#create_extension` to take OIDs in the
- dotted-decimal notation.
- [[GitHub #141]](https://github.com/ruby/openssl/pull/141)
-
-
Version 3.1.0
=============
@@ -457,7 +417,7 @@ Security fixes
Bug fixes
---------
-* Fixed OpenSSL::PKey::\*.{new,generate} immediately aborting if the thread is
+* Fixed OpenSSL::PKey::*.{new,generate} immediately aborting if the thread is
interrupted.
[[Bug #14882]](https://bugs.ruby-lang.org/issues/14882)
[[GitHub #205]](https://github.com/ruby/openssl/pull/205)
diff --git a/ext/openssl/depend b/ext/openssl/depend
index 0d03c85b80..c38d224c85 100644
--- a/ext/openssl/depend
+++ b/ext/openssl/depend
@@ -57,7 +57,6 @@ ossl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -126,6 +125,7 @@ ossl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl.o: $(hdrdir)/ruby/internal/intern/error.h
ossl.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl.o: $(hdrdir)/ruby/internal/intern/io.h
ossl.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -156,6 +156,7 @@ ossl.o: $(hdrdir)/ruby/internal/memory.h
ossl.o: $(hdrdir)/ruby/internal/method.h
ossl.o: $(hdrdir)/ruby/internal/module.h
ossl.o: $(hdrdir)/ruby/internal/newobj.h
+ossl.o: $(hdrdir)/ruby/internal/rgengc.h
ossl.o: $(hdrdir)/ruby/internal/scan_args.h
ossl.o: $(hdrdir)/ruby/internal/special_consts.h
ossl.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -192,7 +193,6 @@ ossl.o: ossl_ocsp.h
ossl.o: ossl_pkcs12.h
ossl.o: ossl_pkcs7.h
ossl.o: ossl_pkey.h
-ossl.o: ossl_provider.h
ossl.o: ossl_rand.h
ossl.o: ossl_ssl.h
ossl.o: ossl_ts.h
@@ -251,7 +251,6 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_asn1.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_asn1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_asn1.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_asn1.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_asn1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -320,6 +319,7 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_asn1.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_asn1.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_asn1.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_asn1.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_asn1.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_asn1.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -350,6 +350,7 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/memory.h
ossl_asn1.o: $(hdrdir)/ruby/internal/method.h
ossl_asn1.o: $(hdrdir)/ruby/internal/module.h
ossl_asn1.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_asn1.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_asn1.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_asn1.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_asn1.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -386,7 +387,6 @@ ossl_asn1.o: ossl_ocsp.h
ossl_asn1.o: ossl_pkcs12.h
ossl_asn1.o: ossl_pkcs7.h
ossl_asn1.o: ossl_pkey.h
-ossl_asn1.o: ossl_provider.h
ossl_asn1.o: ossl_rand.h
ossl_asn1.o: ossl_ssl.h
ossl_asn1.o: ossl_ts.h
@@ -445,7 +445,6 @@ ossl_bio.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_bio.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_bio.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_bio.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_bio.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_bio.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_bio.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_bio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -514,6 +513,7 @@ ossl_bio.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_bio.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_bio.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_bio.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_bio.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_bio.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_bio.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_bio.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -544,6 +544,7 @@ ossl_bio.o: $(hdrdir)/ruby/internal/memory.h
ossl_bio.o: $(hdrdir)/ruby/internal/method.h
ossl_bio.o: $(hdrdir)/ruby/internal/module.h
ossl_bio.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_bio.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_bio.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_bio.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_bio.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -580,7 +581,6 @@ ossl_bio.o: ossl_ocsp.h
ossl_bio.o: ossl_pkcs12.h
ossl_bio.o: ossl_pkcs7.h
ossl_bio.o: ossl_pkey.h
-ossl_bio.o: ossl_provider.h
ossl_bio.o: ossl_rand.h
ossl_bio.o: ossl_ssl.h
ossl_bio.o: ossl_ts.h
@@ -639,7 +639,6 @@ ossl_bn.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_bn.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_bn.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_bn.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_bn.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_bn.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_bn.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_bn.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -708,6 +707,7 @@ ossl_bn.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_bn.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_bn.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_bn.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_bn.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_bn.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_bn.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_bn.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -738,6 +738,7 @@ ossl_bn.o: $(hdrdir)/ruby/internal/memory.h
ossl_bn.o: $(hdrdir)/ruby/internal/method.h
ossl_bn.o: $(hdrdir)/ruby/internal/module.h
ossl_bn.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_bn.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_bn.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_bn.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_bn.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -775,7 +776,6 @@ ossl_bn.o: ossl_ocsp.h
ossl_bn.o: ossl_pkcs12.h
ossl_bn.o: ossl_pkcs7.h
ossl_bn.o: ossl_pkey.h
-ossl_bn.o: ossl_provider.h
ossl_bn.o: ossl_rand.h
ossl_bn.o: ossl_ssl.h
ossl_bn.o: ossl_ts.h
@@ -834,7 +834,6 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_cipher.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_cipher.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_cipher.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_cipher.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_cipher.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -903,6 +902,7 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_cipher.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_cipher.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_cipher.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_cipher.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_cipher.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_cipher.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -933,6 +933,7 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/memory.h
ossl_cipher.o: $(hdrdir)/ruby/internal/method.h
ossl_cipher.o: $(hdrdir)/ruby/internal/module.h
ossl_cipher.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_cipher.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_cipher.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_cipher.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_cipher.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -969,7 +970,6 @@ ossl_cipher.o: ossl_ocsp.h
ossl_cipher.o: ossl_pkcs12.h
ossl_cipher.o: ossl_pkcs7.h
ossl_cipher.o: ossl_pkey.h
-ossl_cipher.o: ossl_provider.h
ossl_cipher.o: ossl_rand.h
ossl_cipher.o: ossl_ssl.h
ossl_cipher.o: ossl_ts.h
@@ -1028,7 +1028,6 @@ ossl_config.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_config.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_config.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_config.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_config.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_config.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_config.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_config.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1097,6 +1096,7 @@ ossl_config.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_config.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_config.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_config.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_config.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_config.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_config.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_config.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1127,6 +1127,7 @@ ossl_config.o: $(hdrdir)/ruby/internal/memory.h
ossl_config.o: $(hdrdir)/ruby/internal/method.h
ossl_config.o: $(hdrdir)/ruby/internal/module.h
ossl_config.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_config.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_config.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_config.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_config.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1163,7 +1164,6 @@ ossl_config.o: ossl_ocsp.h
ossl_config.o: ossl_pkcs12.h
ossl_config.o: ossl_pkcs7.h
ossl_config.o: ossl_pkey.h
-ossl_config.o: ossl_provider.h
ossl_config.o: ossl_rand.h
ossl_config.o: ossl_ssl.h
ossl_config.o: ossl_ts.h
@@ -1222,7 +1222,6 @@ ossl_digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_digest.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_digest.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_digest.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_digest.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1291,6 +1290,7 @@ ossl_digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_digest.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_digest.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_digest.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_digest.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_digest.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_digest.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_digest.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1321,6 +1321,7 @@ ossl_digest.o: $(hdrdir)/ruby/internal/memory.h
ossl_digest.o: $(hdrdir)/ruby/internal/method.h
ossl_digest.o: $(hdrdir)/ruby/internal/module.h
ossl_digest.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_digest.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_digest.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_digest.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_digest.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1357,7 +1358,6 @@ ossl_digest.o: ossl_ocsp.h
ossl_digest.o: ossl_pkcs12.h
ossl_digest.o: ossl_pkcs7.h
ossl_digest.o: ossl_pkey.h
-ossl_digest.o: ossl_provider.h
ossl_digest.o: ossl_rand.h
ossl_digest.o: ossl_ssl.h
ossl_digest.o: ossl_ts.h
@@ -1416,7 +1416,6 @@ ossl_engine.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_engine.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_engine.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_engine.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_engine.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_engine.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_engine.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_engine.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1485,6 +1484,7 @@ ossl_engine.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_engine.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_engine.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_engine.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_engine.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_engine.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_engine.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_engine.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1515,6 +1515,7 @@ ossl_engine.o: $(hdrdir)/ruby/internal/memory.h
ossl_engine.o: $(hdrdir)/ruby/internal/method.h
ossl_engine.o: $(hdrdir)/ruby/internal/module.h
ossl_engine.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_engine.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_engine.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_engine.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_engine.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1551,7 +1552,6 @@ ossl_engine.o: ossl_ocsp.h
ossl_engine.o: ossl_pkcs12.h
ossl_engine.o: ossl_pkcs7.h
ossl_engine.o: ossl_pkey.h
-ossl_engine.o: ossl_provider.h
ossl_engine.o: ossl_rand.h
ossl_engine.o: ossl_ssl.h
ossl_engine.o: ossl_ts.h
@@ -1610,7 +1610,6 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_hmac.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_hmac.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_hmac.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_hmac.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_hmac.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1679,6 +1678,7 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_hmac.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_hmac.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_hmac.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_hmac.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_hmac.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_hmac.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1709,6 +1709,7 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/memory.h
ossl_hmac.o: $(hdrdir)/ruby/internal/method.h
ossl_hmac.o: $(hdrdir)/ruby/internal/module.h
ossl_hmac.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_hmac.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_hmac.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_hmac.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_hmac.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1745,7 +1746,6 @@ ossl_hmac.o: ossl_ocsp.h
ossl_hmac.o: ossl_pkcs12.h
ossl_hmac.o: ossl_pkcs7.h
ossl_hmac.o: ossl_pkey.h
-ossl_hmac.o: ossl_provider.h
ossl_hmac.o: ossl_rand.h
ossl_hmac.o: ossl_ssl.h
ossl_hmac.o: ossl_ts.h
@@ -1804,7 +1804,6 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_kdf.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_kdf.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_kdf.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_kdf.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_kdf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1873,6 +1872,7 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_kdf.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_kdf.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_kdf.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_kdf.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_kdf.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_kdf.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1903,6 +1903,7 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/memory.h
ossl_kdf.o: $(hdrdir)/ruby/internal/method.h
ossl_kdf.o: $(hdrdir)/ruby/internal/module.h
ossl_kdf.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_kdf.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_kdf.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_kdf.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_kdf.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1939,7 +1940,6 @@ ossl_kdf.o: ossl_ocsp.h
ossl_kdf.o: ossl_pkcs12.h
ossl_kdf.o: ossl_pkcs7.h
ossl_kdf.o: ossl_pkey.h
-ossl_kdf.o: ossl_provider.h
ossl_kdf.o: ossl_rand.h
ossl_kdf.o: ossl_ssl.h
ossl_kdf.o: ossl_ts.h
@@ -1998,7 +1998,6 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2067,6 +2066,7 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2097,6 +2097,7 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/memory.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/method.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/module.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ns_spki.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_ns_spki.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2133,7 +2134,6 @@ ossl_ns_spki.o: ossl_ocsp.h
ossl_ns_spki.o: ossl_pkcs12.h
ossl_ns_spki.o: ossl_pkcs7.h
ossl_ns_spki.o: ossl_pkey.h
-ossl_ns_spki.o: ossl_provider.h
ossl_ns_spki.o: ossl_rand.h
ossl_ns_spki.o: ossl_ssl.h
ossl_ns_spki.o: ossl_ts.h
@@ -2192,7 +2192,6 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2261,6 +2260,7 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2291,6 +2291,7 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/memory.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/method.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/module.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ocsp.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_ocsp.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2327,7 +2328,6 @@ ossl_ocsp.o: ossl_ocsp.h
ossl_ocsp.o: ossl_pkcs12.h
ossl_ocsp.o: ossl_pkcs7.h
ossl_ocsp.o: ossl_pkey.h
-ossl_ocsp.o: ossl_provider.h
ossl_ocsp.o: ossl_rand.h
ossl_ocsp.o: ossl_ssl.h
ossl_ocsp.o: ossl_ts.h
@@ -2386,7 +2386,6 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2455,6 +2454,7 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2485,6 +2485,7 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/method.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/module.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkcs12.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkcs12.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2521,7 +2522,6 @@ ossl_pkcs12.o: ossl_pkcs12.c
ossl_pkcs12.o: ossl_pkcs12.h
ossl_pkcs12.o: ossl_pkcs7.h
ossl_pkcs12.o: ossl_pkey.h
-ossl_pkcs12.o: ossl_provider.h
ossl_pkcs12.o: ossl_rand.h
ossl_pkcs12.o: ossl_ssl.h
ossl_pkcs12.o: ossl_ts.h
@@ -2580,7 +2580,6 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2649,6 +2648,7 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2679,6 +2679,7 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/method.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/module.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkcs7.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkcs7.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2715,7 +2716,6 @@ ossl_pkcs7.o: ossl_pkcs12.h
ossl_pkcs7.o: ossl_pkcs7.c
ossl_pkcs7.o: ossl_pkcs7.h
ossl_pkcs7.o: ossl_pkey.h
-ossl_pkcs7.o: ossl_provider.h
ossl_pkcs7.o: ossl_rand.h
ossl_pkcs7.o: ossl_ssl.h
ossl_pkcs7.o: ossl_ts.h
@@ -2774,7 +2774,6 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkey.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkey.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkey.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkey.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkey.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2843,6 +2842,7 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkey.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkey.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkey.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkey.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkey.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkey.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2873,6 +2873,7 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkey.o: $(hdrdir)/ruby/internal/method.h
ossl_pkey.o: $(hdrdir)/ruby/internal/module.h
ossl_pkey.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkey.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkey.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkey.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2909,7 +2910,6 @@ ossl_pkey.o: ossl_pkcs12.h
ossl_pkey.o: ossl_pkcs7.h
ossl_pkey.o: ossl_pkey.c
ossl_pkey.o: ossl_pkey.h
-ossl_pkey.o: ossl_provider.h
ossl_pkey.o: ossl_rand.h
ossl_pkey.o: ossl_ssl.h
ossl_pkey.o: ossl_ts.h
@@ -2968,7 +2968,6 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -3037,6 +3036,7 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -3067,6 +3067,7 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/method.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/module.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_dh.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkey_dh.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -3103,7 +3104,6 @@ ossl_pkey_dh.o: ossl_pkcs12.h
ossl_pkey_dh.o: ossl_pkcs7.h
ossl_pkey_dh.o: ossl_pkey.h
ossl_pkey_dh.o: ossl_pkey_dh.c
-ossl_pkey_dh.o: ossl_provider.h
ossl_pkey_dh.o: ossl_rand.h
ossl_pkey_dh.o: ossl_ssl.h
ossl_pkey_dh.o: ossl_ts.h
@@ -3162,7 +3162,6 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -3231,6 +3230,7 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -3261,6 +3261,7 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/method.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/module.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -3297,7 +3298,6 @@ ossl_pkey_dsa.o: ossl_pkcs12.h
ossl_pkey_dsa.o: ossl_pkcs7.h
ossl_pkey_dsa.o: ossl_pkey.h
ossl_pkey_dsa.o: ossl_pkey_dsa.c
-ossl_pkey_dsa.o: ossl_provider.h
ossl_pkey_dsa.o: ossl_rand.h
ossl_pkey_dsa.o: ossl_ssl.h
ossl_pkey_dsa.o: ossl_ts.h
@@ -3356,7 +3356,6 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -3425,6 +3424,7 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -3455,6 +3455,7 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/method.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/module.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_ec.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkey_ec.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -3491,7 +3492,6 @@ ossl_pkey_ec.o: ossl_pkcs12.h
ossl_pkey_ec.o: ossl_pkcs7.h
ossl_pkey_ec.o: ossl_pkey.h
ossl_pkey_ec.o: ossl_pkey_ec.c
-ossl_pkey_ec.o: ossl_provider.h
ossl_pkey_ec.o: ossl_rand.h
ossl_pkey_ec.o: ossl_ssl.h
ossl_pkey_ec.o: ossl_ts.h
@@ -3550,7 +3550,6 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -3619,6 +3618,7 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -3649,6 +3649,7 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/memory.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/method.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/module.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -3685,205 +3686,10 @@ ossl_pkey_rsa.o: ossl_pkcs12.h
ossl_pkey_rsa.o: ossl_pkcs7.h
ossl_pkey_rsa.o: ossl_pkey.h
ossl_pkey_rsa.o: ossl_pkey_rsa.c
-ossl_pkey_rsa.o: ossl_provider.h
ossl_pkey_rsa.o: ossl_rand.h
ossl_pkey_rsa.o: ossl_ssl.h
ossl_pkey_rsa.o: ossl_ts.h
ossl_pkey_rsa.o: ossl_x509.h
-ossl_provider.o: $(RUBY_EXTCONF_H)
-ossl_provider.o: $(arch_hdrdir)/ruby/config.h
-ossl_provider.o: $(hdrdir)/ruby.h
-ossl_provider.o: $(hdrdir)/ruby/assert.h
-ossl_provider.o: $(hdrdir)/ruby/backward.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/assume.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/attributes.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/bool.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/inttypes.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/limits.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/long_long.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/stdalign.h
-ossl_provider.o: $(hdrdir)/ruby/backward/2/stdarg.h
-ossl_provider.o: $(hdrdir)/ruby/defines.h
-ossl_provider.o: $(hdrdir)/ruby/encoding.h
-ossl_provider.o: $(hdrdir)/ruby/intern.h
-ossl_provider.o: $(hdrdir)/ruby/internal/abi.h
-ossl_provider.o: $(hdrdir)/ruby/internal/anyargs.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-ossl_provider.o: $(hdrdir)/ruby/internal/assume.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/artificial.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/cold.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/const.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/error.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/format.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/noalias.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/noinline.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/pure.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/restrict.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/warning.h
-ossl_provider.o: $(hdrdir)/ruby/internal/attr/weakref.h
-ossl_provider.o: $(hdrdir)/ruby/internal/cast.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-ossl_provider.o: $(hdrdir)/ruby/internal/compiler_since.h
-ossl_provider.o: $(hdrdir)/ruby/internal/config.h
-ossl_provider.o: $(hdrdir)/ruby/internal/constant_p.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rarray.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rbasic.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rbignum.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rclass.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rdata.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rfile.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rhash.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/robject.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rregexp.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rstring.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rstruct.h
-ossl_provider.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-ossl_provider.o: $(hdrdir)/ruby/internal/ctype.h
-ossl_provider.o: $(hdrdir)/ruby/internal/dllexport.h
-ossl_provider.o: $(hdrdir)/ruby/internal/dosish.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/coderange.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/ctype.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/encoding.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/pathname.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/re.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/string.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/symbol.h
-ossl_provider.o: $(hdrdir)/ruby/internal/encoding/transcode.h
-ossl_provider.o: $(hdrdir)/ruby/internal/error.h
-ossl_provider.o: $(hdrdir)/ruby/internal/eval.h
-ossl_provider.o: $(hdrdir)/ruby/internal/event.h
-ossl_provider.o: $(hdrdir)/ruby/internal/fl_type.h
-ossl_provider.o: $(hdrdir)/ruby/internal/gc.h
-ossl_provider.o: $(hdrdir)/ruby/internal/glob.h
-ossl_provider.o: $(hdrdir)/ruby/internal/globals.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/attribute.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/builtin.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/extension.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/feature.h
-ossl_provider.o: $(hdrdir)/ruby/internal/has/warning.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/array.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/bignum.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/class.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/compar.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/complex.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/cont.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/dir.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/enum.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/error.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/eval.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/file.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/hash.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/io.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/load.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/marshal.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/numeric.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/object.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/parse.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/proc.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/process.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/random.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/range.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/rational.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/re.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/ruby.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/select.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/signal.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/string.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/struct.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/thread.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/time.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/variable.h
-ossl_provider.o: $(hdrdir)/ruby/internal/intern/vm.h
-ossl_provider.o: $(hdrdir)/ruby/internal/interpreter.h
-ossl_provider.o: $(hdrdir)/ruby/internal/iterator.h
-ossl_provider.o: $(hdrdir)/ruby/internal/memory.h
-ossl_provider.o: $(hdrdir)/ruby/internal/method.h
-ossl_provider.o: $(hdrdir)/ruby/internal/module.h
-ossl_provider.o: $(hdrdir)/ruby/internal/newobj.h
-ossl_provider.o: $(hdrdir)/ruby/internal/scan_args.h
-ossl_provider.o: $(hdrdir)/ruby/internal/special_consts.h
-ossl_provider.o: $(hdrdir)/ruby/internal/static_assert.h
-ossl_provider.o: $(hdrdir)/ruby/internal/stdalign.h
-ossl_provider.o: $(hdrdir)/ruby/internal/stdbool.h
-ossl_provider.o: $(hdrdir)/ruby/internal/symbol.h
-ossl_provider.o: $(hdrdir)/ruby/internal/value.h
-ossl_provider.o: $(hdrdir)/ruby/internal/value_type.h
-ossl_provider.o: $(hdrdir)/ruby/internal/variable.h
-ossl_provider.o: $(hdrdir)/ruby/internal/warning_push.h
-ossl_provider.o: $(hdrdir)/ruby/internal/xmalloc.h
-ossl_provider.o: $(hdrdir)/ruby/io.h
-ossl_provider.o: $(hdrdir)/ruby/missing.h
-ossl_provider.o: $(hdrdir)/ruby/onigmo.h
-ossl_provider.o: $(hdrdir)/ruby/oniguruma.h
-ossl_provider.o: $(hdrdir)/ruby/ruby.h
-ossl_provider.o: $(hdrdir)/ruby/st.h
-ossl_provider.o: $(hdrdir)/ruby/subst.h
-ossl_provider.o: $(hdrdir)/ruby/thread.h
-ossl_provider.o: openssl_missing.h
-ossl_provider.o: ossl.h
-ossl_provider.o: ossl_asn1.h
-ossl_provider.o: ossl_bio.h
-ossl_provider.o: ossl_bn.h
-ossl_provider.o: ossl_cipher.h
-ossl_provider.o: ossl_config.h
-ossl_provider.o: ossl_digest.h
-ossl_provider.o: ossl_engine.h
-ossl_provider.o: ossl_hmac.h
-ossl_provider.o: ossl_kdf.h
-ossl_provider.o: ossl_ns_spki.h
-ossl_provider.o: ossl_ocsp.h
-ossl_provider.o: ossl_pkcs12.h
-ossl_provider.o: ossl_pkcs7.h
-ossl_provider.o: ossl_pkey.h
-ossl_provider.o: ossl_provider.c
-ossl_provider.o: ossl_provider.h
-ossl_provider.o: ossl_rand.h
-ossl_provider.o: ossl_ssl.h
-ossl_provider.o: ossl_ts.h
-ossl_provider.o: ossl_x509.h
ossl_rand.o: $(RUBY_EXTCONF_H)
ossl_rand.o: $(arch_hdrdir)/ruby/config.h
ossl_rand.o: $(hdrdir)/ruby.h
@@ -3938,7 +3744,6 @@ ossl_rand.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_rand.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_rand.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_rand.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_rand.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_rand.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_rand.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_rand.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -4007,6 +3812,7 @@ ossl_rand.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_rand.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_rand.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_rand.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_rand.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_rand.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_rand.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_rand.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -4037,6 +3843,7 @@ ossl_rand.o: $(hdrdir)/ruby/internal/memory.h
ossl_rand.o: $(hdrdir)/ruby/internal/method.h
ossl_rand.o: $(hdrdir)/ruby/internal/module.h
ossl_rand.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_rand.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_rand.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_rand.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_rand.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -4072,7 +3879,6 @@ ossl_rand.o: ossl_ocsp.h
ossl_rand.o: ossl_pkcs12.h
ossl_rand.o: ossl_pkcs7.h
ossl_rand.o: ossl_pkey.h
-ossl_rand.o: ossl_provider.h
ossl_rand.o: ossl_rand.c
ossl_rand.o: ossl_rand.h
ossl_rand.o: ossl_ssl.h
@@ -4132,7 +3938,6 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_ssl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_ssl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_ssl.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_ssl.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_ssl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -4201,6 +4006,7 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_ssl.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_ssl.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_ssl.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_ssl.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_ssl.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_ssl.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -4231,6 +4037,7 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/memory.h
ossl_ssl.o: $(hdrdir)/ruby/internal/method.h
ossl_ssl.o: $(hdrdir)/ruby/internal/module.h
ossl_ssl.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ssl.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_ssl.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_ssl.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_ssl.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -4266,7 +4073,6 @@ ossl_ssl.o: ossl_ocsp.h
ossl_ssl.o: ossl_pkcs12.h
ossl_ssl.o: ossl_pkcs7.h
ossl_ssl.o: ossl_pkey.h
-ossl_ssl.o: ossl_provider.h
ossl_ssl.o: ossl_rand.h
ossl_ssl.o: ossl_ssl.c
ossl_ssl.o: ossl_ssl.h
@@ -4326,7 +4132,6 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -4395,6 +4200,7 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -4425,6 +4231,7 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/memory.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/method.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/module.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ssl_session.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_ssl_session.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -4460,7 +4267,6 @@ ossl_ssl_session.o: ossl_ocsp.h
ossl_ssl_session.o: ossl_pkcs12.h
ossl_ssl_session.o: ossl_pkcs7.h
ossl_ssl_session.o: ossl_pkey.h
-ossl_ssl_session.o: ossl_provider.h
ossl_ssl_session.o: ossl_rand.h
ossl_ssl_session.o: ossl_ssl.h
ossl_ssl_session.o: ossl_ssl_session.c
@@ -4520,7 +4326,6 @@ ossl_ts.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_ts.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_ts.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_ts.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_ts.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_ts.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_ts.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_ts.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -4589,6 +4394,7 @@ ossl_ts.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_ts.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_ts.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_ts.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_ts.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_ts.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_ts.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_ts.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -4619,6 +4425,7 @@ ossl_ts.o: $(hdrdir)/ruby/internal/memory.h
ossl_ts.o: $(hdrdir)/ruby/internal/method.h
ossl_ts.o: $(hdrdir)/ruby/internal/module.h
ossl_ts.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_ts.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_ts.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_ts.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_ts.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -4654,7 +4461,6 @@ ossl_ts.o: ossl_ocsp.h
ossl_ts.o: ossl_pkcs12.h
ossl_ts.o: ossl_pkcs7.h
ossl_ts.o: ossl_pkey.h
-ossl_ts.o: ossl_provider.h
ossl_ts.o: ossl_rand.h
ossl_ts.o: ossl_ssl.h
ossl_ts.o: ossl_ts.c
@@ -4714,7 +4520,6 @@ ossl_x509.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -4783,6 +4588,7 @@ ossl_x509.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -4813,6 +4619,7 @@ ossl_x509.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509.o: $(hdrdir)/ruby/internal/method.h
ossl_x509.o: $(hdrdir)/ruby/internal/module.h
ossl_x509.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -4848,7 +4655,6 @@ ossl_x509.o: ossl_ocsp.h
ossl_x509.o: ossl_pkcs12.h
ossl_x509.o: ossl_pkcs7.h
ossl_x509.o: ossl_pkey.h
-ossl_x509.o: ossl_provider.h
ossl_x509.o: ossl_rand.h
ossl_x509.o: ossl_ssl.h
ossl_x509.o: ossl_ts.h
@@ -4908,7 +4714,6 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -4977,6 +4782,7 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -5007,6 +4813,7 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/method.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/module.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509attr.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509attr.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -5042,7 +4849,6 @@ ossl_x509attr.o: ossl_ocsp.h
ossl_x509attr.o: ossl_pkcs12.h
ossl_x509attr.o: ossl_pkcs7.h
ossl_x509attr.o: ossl_pkey.h
-ossl_x509attr.o: ossl_provider.h
ossl_x509attr.o: ossl_rand.h
ossl_x509attr.o: ossl_ssl.h
ossl_x509attr.o: ossl_ts.h
@@ -5102,7 +4908,6 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -5171,6 +4976,7 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -5201,6 +5007,7 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/method.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/module.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509cert.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509cert.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -5236,7 +5043,6 @@ ossl_x509cert.o: ossl_ocsp.h
ossl_x509cert.o: ossl_pkcs12.h
ossl_x509cert.o: ossl_pkcs7.h
ossl_x509cert.o: ossl_pkey.h
-ossl_x509cert.o: ossl_provider.h
ossl_x509cert.o: ossl_rand.h
ossl_x509cert.o: ossl_ssl.h
ossl_x509cert.o: ossl_ts.h
@@ -5296,7 +5102,6 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -5365,6 +5170,7 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -5395,6 +5201,7 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/method.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/module.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509crl.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509crl.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -5430,7 +5237,6 @@ ossl_x509crl.o: ossl_ocsp.h
ossl_x509crl.o: ossl_pkcs12.h
ossl_x509crl.o: ossl_pkcs7.h
ossl_x509crl.o: ossl_pkey.h
-ossl_x509crl.o: ossl_provider.h
ossl_x509crl.o: ossl_rand.h
ossl_x509crl.o: ossl_ssl.h
ossl_x509crl.o: ossl_ts.h
@@ -5490,7 +5296,6 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -5559,6 +5364,7 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -5589,6 +5395,7 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/method.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/module.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509ext.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509ext.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -5624,7 +5431,6 @@ ossl_x509ext.o: ossl_ocsp.h
ossl_x509ext.o: ossl_pkcs12.h
ossl_x509ext.o: ossl_pkcs7.h
ossl_x509ext.o: ossl_pkey.h
-ossl_x509ext.o: ossl_provider.h
ossl_x509ext.o: ossl_rand.h
ossl_x509ext.o: ossl_ssl.h
ossl_x509ext.o: ossl_ts.h
@@ -5684,7 +5490,6 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509name.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509name.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509name.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509name.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -5753,6 +5558,7 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509name.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509name.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509name.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509name.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509name.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509name.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -5783,6 +5589,7 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509name.o: $(hdrdir)/ruby/internal/method.h
ossl_x509name.o: $(hdrdir)/ruby/internal/module.h
ossl_x509name.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509name.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509name.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509name.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509name.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -5818,7 +5625,6 @@ ossl_x509name.o: ossl_ocsp.h
ossl_x509name.o: ossl_pkcs12.h
ossl_x509name.o: ossl_pkcs7.h
ossl_x509name.o: ossl_pkey.h
-ossl_x509name.o: ossl_provider.h
ossl_x509name.o: ossl_rand.h
ossl_x509name.o: ossl_ssl.h
ossl_x509name.o: ossl_ts.h
@@ -5878,7 +5684,6 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509req.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509req.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509req.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509req.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509req.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -5947,6 +5752,7 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509req.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509req.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509req.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509req.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509req.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509req.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -5977,6 +5783,7 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509req.o: $(hdrdir)/ruby/internal/method.h
ossl_x509req.o: $(hdrdir)/ruby/internal/module.h
ossl_x509req.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509req.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509req.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509req.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509req.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -6012,7 +5819,6 @@ ossl_x509req.o: ossl_ocsp.h
ossl_x509req.o: ossl_pkcs12.h
ossl_x509req.o: ossl_pkcs7.h
ossl_x509req.o: ossl_pkey.h
-ossl_x509req.o: ossl_provider.h
ossl_x509req.o: ossl_rand.h
ossl_x509req.o: ossl_ssl.h
ossl_x509req.o: ossl_ts.h
@@ -6072,7 +5878,6 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -6141,6 +5946,7 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -6171,6 +5977,7 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/method.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/module.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509revoked.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509revoked.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -6206,7 +6013,6 @@ ossl_x509revoked.o: ossl_ocsp.h
ossl_x509revoked.o: ossl_pkcs12.h
ossl_x509revoked.o: ossl_pkcs7.h
ossl_x509revoked.o: ossl_pkey.h
-ossl_x509revoked.o: ossl_provider.h
ossl_x509revoked.o: ossl_rand.h
ossl_x509revoked.o: ossl_ssl.h
ossl_x509revoked.o: ossl_ts.h
@@ -6266,7 +6072,6 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noinline.h
ossl_x509store.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ossl_x509store.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ossl_x509store.o: $(hdrdir)/ruby/internal/attr/pure.h
ossl_x509store.o: $(hdrdir)/ruby/internal/attr/restrict.h
ossl_x509store.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -6335,6 +6140,7 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ossl_x509store.o: $(hdrdir)/ruby/internal/intern/error.h
ossl_x509store.o: $(hdrdir)/ruby/internal/intern/eval.h
ossl_x509store.o: $(hdrdir)/ruby/internal/intern/file.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/intern/gc.h
ossl_x509store.o: $(hdrdir)/ruby/internal/intern/hash.h
ossl_x509store.o: $(hdrdir)/ruby/internal/intern/io.h
ossl_x509store.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -6365,6 +6171,7 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/memory.h
ossl_x509store.o: $(hdrdir)/ruby/internal/method.h
ossl_x509store.o: $(hdrdir)/ruby/internal/module.h
ossl_x509store.o: $(hdrdir)/ruby/internal/newobj.h
+ossl_x509store.o: $(hdrdir)/ruby/internal/rgengc.h
ossl_x509store.o: $(hdrdir)/ruby/internal/scan_args.h
ossl_x509store.o: $(hdrdir)/ruby/internal/special_consts.h
ossl_x509store.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -6400,7 +6207,6 @@ ossl_x509store.o: ossl_ocsp.h
ossl_x509store.o: ossl_pkcs12.h
ossl_x509store.o: ossl_pkcs7.h
ossl_x509store.o: ossl_pkey.h
-ossl_x509store.o: ossl_provider.h
ossl_x509store.o: ossl_rand.h
ossl_x509store.o: ossl_ssl.h
ossl_x509store.o: ossl_ts.h
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 56f4a1c3ab..bc3e4d3a21 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -13,41 +13,20 @@
require "mkmf"
-ssl_dirs = nil
-if defined?(::TruffleRuby)
- # Always respect the openssl prefix chosen by truffle/openssl-prefix
- require 'truffle/openssl-prefix'
- ssl_dirs = dir_config("openssl", ENV["OPENSSL_PREFIX"])
-else
- ssl_dirs = dir_config("openssl")
-end
-dir_config_given = ssl_dirs.any?
-
-_, ssl_ldir = ssl_dirs
-if ssl_ldir&.split(File::PATH_SEPARATOR)&.none? { |dir| File.directory?(dir) }
- # According to the `mkmf.rb#dir_config`, the `--with-openssl-dir=<dir>` uses
- # the value of the `File.basename(RbConfig::MAKEFILE_CONFIG["libdir"])` as a
- # loaded library directory name.
- ruby_ldir_name = File.basename(RbConfig::MAKEFILE_CONFIG["libdir"])
-
- raise "OpenSSL library directory could not be found in '#{ssl_ldir}'. " \
- "You might want to fix this error in one of the following ways.\n" \
- " * Recompile OpenSSL by configuring it with --libdir=#{ruby_ldir_name} " \
- " to specify the OpenSSL library directory.\n" \
- " * Recompile Ruby by configuring it with --libdir=<dir> to specify the " \
- "Ruby library directory.\n" \
- " * Compile this openssl gem with --with-openssl-include=<dir> and " \
- "--with-openssl-lib=<dir> options to specify the OpenSSL include and " \
- "library directories."
-end
-
+dir_config_given = dir_config("openssl").any?
dir_config("kerberos")
Logging::message "=== OpenSSL for Ruby configurator ===\n"
+##
+# Adds -DOSSL_DEBUG for compilation and some more targets when GCC is used
+# To turn it on, use: --with-debug or --enable-debug
+#
+if with_config("debug") or enable_config("debug")
+ $defs.push("-DOSSL_DEBUG")
+end
$defs.push("-D""OPENSSL_SUPPRESS_DEPRECATED")
-have_func("rb_io_descriptor")
have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h") # Ruby 3.1
Logging::message "=== Checking for system dependent stuff... ===\n"
@@ -212,12 +191,6 @@ have_func("EVP_PKEY_dup(NULL)", evp_h)
Logging::message "=== Checking done. ===\n"
-# Append flags from environment variables.
-extcflags = ENV["RUBY_OPENSSL_EXTCFLAGS"]
-append_cflags(extcflags.split) if extcflags
-extldflags = ENV["RUBY_OPENSSL_EXTLDFLAGS"]
-append_ldflags(extldflags.split) if extldflags
-
create_header
create_makefile("openssl")
Logging::message "Done.\n"
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index 9570f14f37..d47e1082ef 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -93,7 +93,9 @@ module OpenSSL::Buffering
nil
else
size = @rbuffer.size unless size
- @rbuffer.slice!(0, size)
+ ret = @rbuffer[0, size]
+ @rbuffer[0, size] = ""
+ ret
end
end
@@ -104,7 +106,8 @@ module OpenSSL::Buffering
#
# Get the next 8bit byte from `ssl`. Returns `nil` on EOF
def getbyte
- read(1)&.ord
+ byte = read(1)
+ byte && byte.unpack1("C")
end
##
diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb
index 0f35ddadd3..2ff8398e44 100644
--- a/ext/openssl/lib/openssl/digest.rb
+++ b/ext/openssl/lib/openssl/digest.rb
@@ -18,9 +18,13 @@ module OpenSSL
# Return the hash value computed with _name_ Digest. _name_ is either the
# long name or short name of a supported digest algorithm.
#
- # === Example
+ # === Examples
#
# OpenSSL::Digest.digest("SHA256", "abc")
+ #
+ # which is equivalent to:
+ #
+ # OpenSSL::Digest.digest('SHA256', "abc")
def self.digest(name, data)
super(data, name)
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index e557b8b483..ea8bb2a18e 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -34,21 +34,21 @@ module OpenSSL
}
if defined?(OpenSSL::PKey::DH)
- DH_ffdhe2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
+ DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
-----BEGIN DH PARAMETERS-----
-MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
-+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
-87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
-YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
-7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
-ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
+MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
+JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
+VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
+YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
+1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
+7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
-----END DH PARAMETERS-----
_end_of_pem_
- private_constant :DH_ffdhe2048
+ private_constant :DEFAULT_2048
DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc:
warn "using default DH parameters." if $VERBOSE
- DH_ffdhe2048
+ DEFAULT_2048
}
end
@@ -494,7 +494,7 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
unless ctx.session_id_context
# see #6137 - session id may not exceed 32 bytes
prng = ::Random.new($0.hash)
- session_id = prng.bytes(16).unpack1('H*')
+ session_id = prng.bytes(16).unpack('H*')[0]
@ctx.session_id_context = session_id
end
@start_immediately = true
diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb
index 9315a79381..4163f55064 100644
--- a/ext/openssl/lib/openssl/version.rb
+++ b/ext/openssl/lib/openssl/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module OpenSSL
- VERSION = "3.2.0"
+ VERSION = "3.1.0"
end
diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec
index 2765f55401..8d83b69193 100644
--- a/ext/openssl/openssl.gemspec
+++ b/ext/openssl/openssl.gemspec
@@ -1,27 +1,21 @@
Gem::Specification.new do |spec|
spec.name = "openssl"
- spec.version = "3.2.0"
+ spec.version = "3.1.0"
spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
spec.email = ["ruby-core@ruby-lang.org"]
- spec.summary = %q{SSL/TLS and general-purpose cryptography for Ruby}
- spec.description = %q{OpenSSL for Ruby provides access to SSL/TLS and general-purpose cryptography based on the OpenSSL library.}
+ spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.}
+ spec.description = %q{It wraps the OpenSSL library.}
spec.homepage = "https://github.com/ruby/openssl"
spec.license = "Ruby"
- if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby'
- spec.platform = "java"
- spec.files = []
- spec.add_runtime_dependency('jruby-openssl', '~> 0.14')
- else
- spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "LICENSE.txt"]
- spec.require_paths = ["lib"]
- spec.extensions = ["ext/openssl/extconf.rb"]
- end
+ spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "LICENSE.txt"]
+ spec.require_paths = ["lib"]
+ spec.extensions = ["ext/openssl/extconf.rb"]
spec.extra_rdoc_files = Dir["*.md"]
spec.rdoc_options = ["--main", "README.md"]
- spec.required_ruby_version = ">= 2.7.0"
+ spec.required_ruby_version = ">= 2.6.0"
spec.metadata["msys2_mingw_dependencies"] = "openssl"
end
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index 00eded55cb..6c532aca94 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -207,7 +207,7 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
while (1) {
/*
- * when the flag is nonzero, this password
+ * when the flag is nonzero, this passphrase
* will be used to perform encryption; otherwise it will
* be used to perform decryption.
*/
@@ -272,28 +272,23 @@ VALUE
ossl_make_error(VALUE exc, VALUE str)
{
unsigned long e;
- const char *data;
- int flags;
- if (NIL_P(str))
- str = rb_str_new(NULL, 0);
-
-#ifdef HAVE_ERR_GET_ERROR_ALL
- e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags);
-#else
- e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags);
-#endif
+ e = ERR_peek_last_error();
if (e) {
- const char *msg = ERR_reason_error_string(e);
+ const char *msg = ERR_reason_error_string(e);
- if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": ");
- rb_str_cat_cstr(str, msg ? msg : "(null)");
- if (flags & ERR_TXT_STRING && data)
- rb_str_catf(str, " (%s)", data);
- ossl_clear_error();
+ if (NIL_P(str)) {
+ if (msg) str = rb_str_new_cstr(msg);
+ }
+ else {
+ if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
+ rb_str_cat2(str, msg ? msg : "(null)");
+ }
+ ossl_clear_error();
}
- return rb_exc_new_str(exc, str);
+ if (NIL_P(str)) str = rb_str_new(0, 0);
+ return rb_exc_new3(exc, str);
}
void
@@ -374,6 +369,22 @@ ossl_get_errors(VALUE _)
*/
VALUE dOSSL;
+#if !defined(HAVE_VA_ARGS_MACRO)
+void
+ossl_debug(const char *fmt, ...)
+{
+ va_list args;
+
+ if (dOSSL == Qtrue) {
+ fprintf(stderr, "OSSL_DEBUG: ");
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, " [CONTEXT N/A]\n");
+ }
+}
+#endif
+
/*
* call-seq:
* OpenSSL.debug -> true | false
@@ -407,11 +418,7 @@ static VALUE
ossl_fips_mode_get(VALUE self)
{
-#if OSSL_OPENSSL_PREREQ(3, 0, 0)
- VALUE enabled;
- enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
- return enabled;
-#elif defined(OPENSSL_FIPS)
+#ifdef OPENSSL_FIPS
VALUE enabled;
enabled = FIPS_mode() ? Qtrue : Qfalse;
return enabled;
@@ -435,18 +442,8 @@ ossl_fips_mode_get(VALUE self)
static VALUE
ossl_fips_mode_set(VALUE self, VALUE enabled)
{
-#if OSSL_OPENSSL_PREREQ(3, 0, 0)
- if (RTEST(enabled)) {
- if (!EVP_default_properties_enable_fips(NULL, 1)) {
- ossl_raise(eOSSLError, "Turning on FIPS mode failed");
- }
- } else {
- if (!EVP_default_properties_enable_fips(NULL, 0)) {
- ossl_raise(eOSSLError, "Turning off FIPS mode failed");
- }
- }
- return enabled;
-#elif defined(OPENSSL_FIPS)
+
+#ifdef OPENSSL_FIPS
if (RTEST(enabled)) {
int mode = FIPS_mode();
if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
@@ -463,6 +460,75 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
#endif
}
+#if defined(OSSL_DEBUG)
+#if !defined(LIBRESSL_VERSION_NUMBER) && \
+ (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
+ defined(CRYPTO_malloc_debug_init))
+/*
+ * call-seq:
+ * OpenSSL.mem_check_start -> nil
+ *
+ * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
+ * allocations. See also OpenSSL.print_mem_leaks.
+ *
+ * This is available only when built with a capable OpenSSL and --enable-debug
+ * configure option.
+ */
+static VALUE
+mem_check_start(VALUE self)
+{
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * OpenSSL.print_mem_leaks -> true | false
+ *
+ * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
+ * Prints detected memory leaks to standard error. This cleans the global state
+ * up thus you cannot use any methods of the library after calling this.
+ *
+ * Returns +true+ if leaks detected, +false+ otherwise.
+ *
+ * This is available only when built with a capable OpenSSL and --enable-debug
+ * configure option.
+ *
+ * === Example
+ * OpenSSL.mem_check_start
+ * NOT_GCED = OpenSSL::PKey::RSA.new(256)
+ *
+ * END {
+ * GC.start
+ * OpenSSL.print_mem_leaks # will print the leakage
+ * }
+ */
+static VALUE
+print_mem_leaks(VALUE self)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ int ret;
+#endif
+
+#ifndef HAVE_RB_EXT_RACTOR_SAFE
+ // for Ruby 2.x
+ void ossl_bn_ctx_free(void); // ossl_bn.c
+ ossl_bn_ctx_free();
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ ret = CRYPTO_mem_leaks_fp(stderr);
+ if (ret < 0)
+ ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
+ return ret ? Qfalse : Qtrue;
+#else
+ CRYPTO_mem_leaks_fp(stderr);
+ return Qnil;
+#endif
+}
+#endif
+#endif
+
#if !defined(HAVE_OPENSSL_110_THREADING_API)
/**
* Stores locks needed for OpenSSL thread safety
@@ -605,21 +671,23 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
*
* key = OpenSSL::PKey::RSA.new 2048
*
- * File.write 'private_key.pem', key.private_to_pem
- * File.write 'public_key.pem', key.public_to_pem
+ * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
+ * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
*
* === Exporting a Key
*
* Keys saved to disk without encryption are not secure as anyone who gets
* ahold of the key may use it unless it is encrypted. In order to securely
- * export a key you may export it with a password.
+ * export a key you may export it with a pass phrase.
*
* cipher = OpenSSL::Cipher.new 'aes-256-cbc'
- * password = 'my secure password goes here'
+ * pass_phrase = 'my secure pass phrase goes here'
*
- * key_secure = key.private_to_pem cipher, password
+ * key_secure = key.export cipher, pass_phrase
*
- * File.write 'private.secure.pem', key_secure
+ * open 'private.secure.pem', 'w' do |io|
+ * io.write key_secure
+ * end
*
* OpenSSL::Cipher.ciphers returns a list of available ciphers.
*
@@ -639,13 +707,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
*
* === Loading an Encrypted Key
*
- * OpenSSL will prompt you for your password when loading an encrypted key.
- * If you will not be able to type in the password you may provide it when
+ * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
+ * If you will not be able to type in the pass phrase you may provide it when
* loading the key:
*
* key4_pem = File.read 'private.secure.pem'
- * password = 'my secure password goes here'
- * key4 = OpenSSL::PKey.read key4_pem, password
+ * pass_phrase = 'my secure pass phrase goes here'
+ * key4 = OpenSSL::PKey.read key4_pem, pass_phrase
*
* == RSA Encryption
*
@@ -761,6 +829,45 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
* decrypted = cipher.update encrypted
* decrypted << cipher.final
*
+ * == PKCS #5 Password-based Encryption
+ *
+ * PKCS #5 is a password-based encryption standard documented at
+ * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
+ * passphrase to be used to create a secure encryption key. If possible, PBKDF2
+ * as described above should be used if the circumstances allow it.
+ *
+ * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
+ * key.
+ *
+ * pass_phrase = 'my secure pass phrase goes here'
+ * salt = '8 octets'
+ *
+ * === Encryption
+ *
+ * First set up the cipher for encryption
+ *
+ * encryptor = OpenSSL::Cipher.new 'aes-256-cbc'
+ * encryptor.encrypt
+ * encryptor.pkcs5_keyivgen pass_phrase, salt
+ *
+ * Then pass the data you want to encrypt through
+ *
+ * encrypted = encryptor.update 'top secret document'
+ * encrypted << encryptor.final
+ *
+ * === Decryption
+ *
+ * Use a new Cipher instance set up for decryption
+ *
+ * decryptor = OpenSSL::Cipher.new 'aes-256-cbc'
+ * decryptor.decrypt
+ * decryptor.pkcs5_keyivgen pass_phrase, salt
+ *
+ * Then pass the data you want to decrypt through
+ *
+ * plain = decryptor.update encrypted
+ * plain << decryptor.final
+ *
* == X509 Certificates
*
* === Creating a Certificate
@@ -838,12 +945,12 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
* not readable by other users.
*
* ca_key = OpenSSL::PKey::RSA.new 2048
- * password = 'my secure password goes here'
+ * pass_phrase = 'my secure pass phrase goes here'
*
- * cipher = 'aes-256-cbc'
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
*
* open 'ca_key.pem', 'w', 0400 do |io|
- * io.write ca_key.private_to_pem(cipher, password)
+ * io.write ca_key.export(cipher, pass_phrase)
* end
*
* === CA Certificate
@@ -1063,8 +1170,8 @@ Init_openssl(void)
/*
* Init main module
*/
- rb_global_variable(&mOSSL);
mOSSL = rb_define_module("OpenSSL");
+ rb_global_variable(&mOSSL);
rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
/*
@@ -1083,35 +1190,15 @@ Init_openssl(void)
/*
* Version number of OpenSSL the ruby OpenSSL extension was built with
- * (base 16). The formats are below.
- *
- * [OpenSSL 3] <tt>0xMNN00PP0 (major minor 00 patch 0)</tt>
- * [OpenSSL before 3] <tt>0xMNNFFPPS (major minor fix patch status)</tt>
- * [LibreSSL] <tt>0x20000000 (fixed value)</tt>
- *
- * See also the man page OPENSSL_VERSION_NUMBER(3).
+ * (base 16)
*/
rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
-#if defined(LIBRESSL_VERSION_NUMBER)
- /*
- * Version number of LibreSSL the ruby OpenSSL extension was built with
- * (base 16). The format is <tt>0xMNNFF00f (major minor fix 00
- * status)</tt>. This constant is only defined in LibreSSL cases.
- *
- * See also the man page LIBRESSL_VERSION_NUMBER(3).
- */
- rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER));
-#endif
-
/*
* Boolean indicating whether OpenSSL is FIPS-capable or not
*/
rb_define_const(mOSSL, "OPENSSL_FIPS",
-/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
-#if OSSL_OPENSSL_PREREQ(3, 0, 0)
- Qtrue
-#elif defined(OPENSSL_FIPS)
+#ifdef OPENSSL_FIPS
Qtrue
#else
Qfalse
@@ -1121,12 +1208,12 @@ Init_openssl(void)
rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
- rb_global_variable(&eOSSLError);
/*
* Generic error,
* common for all classes under OpenSSL module
*/
eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
+ rb_global_variable(&eOSSLError);
/*
* Init debug core
@@ -1167,7 +1254,42 @@ Init_openssl(void)
Init_ossl_x509();
Init_ossl_ocsp();
Init_ossl_engine();
- Init_ossl_provider();
Init_ossl_asn1();
Init_ossl_kdf();
+
+#if defined(OSSL_DEBUG)
+ /*
+ * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
+ */
+#if !defined(LIBRESSL_VERSION_NUMBER) && \
+ (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
+ defined(CRYPTO_malloc_debug_init))
+ rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
+ rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
+
+#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
+ CRYPTO_malloc_debug_init();
+#endif
+
+#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
+ {
+ int i;
+ /*
+ * See crypto/ex_data.c; call def_get_class() immediately to avoid
+ * allocations. 15 is the maximum number that is used as the class index
+ * in OpenSSL 1.0.2.
+ */
+ for (i = 0; i <= 15; i++) {
+ if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
+ rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
+ "class index %d failed", i);
+ }
+ }
+#endif
+#endif
+#endif
}
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index 68d42b71e2..facb80aa73 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -62,10 +62,6 @@
# define OSSL_USE_ENGINE
#endif
-#if OSSL_OPENSSL_PREREQ(3, 0, 0)
-# define OSSL_USE_PROVIDER
-#endif
-
/*
* Common Module
*/
@@ -161,6 +157,7 @@ VALUE ossl_to_der_if_possible(VALUE);
*/
extern VALUE dOSSL;
+#if defined(HAVE_VA_ARGS_MACRO)
#define OSSL_Debug(...) do { \
if (dOSSL == Qtrue) { \
fprintf(stderr, "OSSL_DEBUG: "); \
@@ -169,6 +166,11 @@ extern VALUE dOSSL;
} \
} while (0)
+#else
+void ossl_debug(const char *, ...);
+#define OSSL_Debug ossl_debug
+#endif
+
/*
* Include all parts
*/
@@ -192,7 +194,6 @@ extern VALUE dOSSL;
#endif
#include "ossl_x509.h"
#include "ossl_engine.h"
-#include "ossl_provider.h"
#include "ossl_kdf.h"
void Init_openssl(void);
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index ce0d3ec7ee..bf2bac3679 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_bn_type = {
{
0, ossl_bn_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index 110610e1f9..cb8fbc3ca2 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -42,7 +42,7 @@ static const rb_data_type_t ossl_cipher_type = {
{
0, ossl_cipher_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c
index 0e598b4d51..0bac027487 100644
--- a/ext/openssl/ossl_config.c
+++ b/ext/openssl/ossl_config.c
@@ -22,7 +22,7 @@ static const rb_data_type_t ossl_config_type = {
{
0, nconf_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
CONF *
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
index 16aeeb8106..fc326ec14a 100644
--- a/ext/openssl/ossl_digest.c
+++ b/ext/openssl/ossl_digest.c
@@ -35,7 +35,7 @@ static const rb_data_type_t ossl_digest_type = {
{
0, ossl_digest_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c
index 9e86321d06..1abde7f766 100644
--- a/ext/openssl/ossl_engine.c
+++ b/ext/openssl/ossl_engine.c
@@ -78,7 +78,7 @@ static const rb_data_type_t ossl_engine_type = {
{
0, ossl_engine_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index c485ba7e67..1a5f471a27 100644
--- a/ext/openssl/ossl_hmac.c
+++ b/ext/openssl/ossl_hmac.c
@@ -42,7 +42,7 @@ static const rb_data_type_t ossl_hmac_type = {
{
0, ossl_hmac_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c
index 48b161d4f4..0d25a7304b 100644
--- a/ext/openssl/ossl_kdf.c
+++ b/ext/openssl/ossl_kdf.c
@@ -21,7 +21,7 @@ static VALUE mKDF, eKDF;
* (https://tools.ietf.org/html/rfc2898#section-5.2).
*
* === Parameters
- * pass :: The password.
+ * pass :: The passphrase.
* salt :: The salt. Salts prevent attacks based on dictionaries of common
* passwords and attacks based on rainbow tables. It is a public
* value that can be safely stored along with the password (e.g.
diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c
index 9bed1f330e..9b1147367a 100644
--- a/ext/openssl/ossl_ns_spki.c
+++ b/ext/openssl/ossl_ns_spki.c
@@ -50,7 +50,7 @@ static const rb_data_type_t ossl_netscape_spki_type = {
{
0, ossl_netscape_spki_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c
index df986bb3ee..9c8d768d87 100644
--- a/ext/openssl/ossl_ocsp.c
+++ b/ext/openssl/ossl_ocsp.c
@@ -86,7 +86,7 @@ static const rb_data_type_t ossl_ocsp_request_type = {
{
0, ossl_ocsp_request_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -100,7 +100,7 @@ static const rb_data_type_t ossl_ocsp_response_type = {
{
0, ossl_ocsp_response_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -114,7 +114,7 @@ static const rb_data_type_t ossl_ocsp_basicresp_type = {
{
0, ossl_ocsp_basicresp_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -128,7 +128,7 @@ static const rb_data_type_t ossl_ocsp_singleresp_type = {
{
0, ossl_ocsp_singleresp_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -142,7 +142,7 @@ static const rb_data_type_t ossl_ocsp_certid_type = {
{
0, ossl_ocsp_certid_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
@@ -1701,7 +1701,7 @@ Init_ossl_ocsp(void)
* require 'net/http'
*
* http_response =
- * Net::HTTP.start ocsp_uri.hostname, ocsp_uri.port do |http|
+ * Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http|
* http.post ocsp_uri.path, request.to_der,
* 'content-type' => 'application/ocsp-request'
* end
diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c
index 164b2da465..fb947df1d0 100644
--- a/ext/openssl/ossl_pkcs12.c
+++ b/ext/openssl/ossl_pkcs12.c
@@ -44,7 +44,7 @@ static const rb_data_type_t ossl_pkcs12_type = {
{
0, ossl_pkcs12_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 78dcbd667a..dbe5347639 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -65,7 +65,7 @@ const rb_data_type_t ossl_pkcs7_type = {
{
0, ossl_pkcs7_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -79,7 +79,7 @@ static const rb_data_type_t ossl_pkcs7_signer_info_type = {
{
0, ossl_pkcs7_signer_info_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -93,7 +93,7 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = {
{
0, ossl_pkcs7_recip_info_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 013412c27f..476256679b 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -35,7 +35,7 @@ const rb_data_type_t ossl_evp_pkey_type = {
{
0, ossl_evp_pkey_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
@@ -82,62 +82,31 @@ ossl_pkey_new(EVP_PKEY *pkey)
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
# include <openssl/decoder.h>
-static EVP_PKEY *
-ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass)
+EVP_PKEY *
+ossl_pkey_read_generic(BIO *bio, VALUE pass)
{
void *ppass = (void *)pass;
OSSL_DECODER_CTX *dctx;
EVP_PKEY *pkey = NULL;
int pos = 0, pos2;
- dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL,
- selection, NULL, NULL);
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, NULL, 0, NULL, NULL);
if (!dctx)
goto out;
- if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb,
- ppass) != 1)
+ if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1)
+ goto out;
+
+ /* First check DER */
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
goto out;
- while (1) {
- if (OSSL_DECODER_from_bio(dctx, bio) == 1)
- goto out;
- if (BIO_eof(bio))
- break;
- pos2 = BIO_tell(bio);
- if (pos2 < 0 || pos2 <= pos)
- break;
- ossl_clear_error();
- pos = pos2;
- }
- out:
OSSL_BIO_reset(bio);
- OSSL_DECODER_CTX_free(dctx);
- return pkey;
-}
-EVP_PKEY *
-ossl_pkey_read_generic(BIO *bio, VALUE pass)
-{
- EVP_PKEY *pkey = NULL;
- /* First check DER, then check PEM. */
- const char *input_types[] = {"DER", "PEM"};
- int input_type_num = (int)(sizeof(input_types) / sizeof(char *));
+ /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */
+ if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
+ goto out;
/*
- * Non-zero selections to try to decode.
- *
- * See EVP_PKEY_fromdata(3) - Selections to see all the selections.
- *
- * This is a workaround for the decoder failing to decode or returning
- * bogus keys with selection 0, if a key management provider is different
- * from a decoder provider. The workaround is to avoid using selection 0.
- *
- * Affected OpenSSL versions: >= 3.1.0, <= 3.1.2, or >= 3.0.0, <= 3.0.10
- * Fixed OpenSSL versions: 3.2, next release of the 3.1.z and 3.0.z
- *
- * See https://github.com/openssl/openssl/pull/21519 for details.
- *
- * First check for private key formats (EVP_PKEY_KEYPAIR). This is to keep
- * compatibility with ruby/openssl < 3.0 which decoded the following as a
- * private key.
+ * First check for private key formats. This is to keep compatibility with
+ * ruby/openssl < 3.0 which decoded the following as a private key.
*
* $ openssl ecparam -name prime256v1 -genkey -outform PEM
* -----BEGIN EC PARAMETERS-----
@@ -155,28 +124,36 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
*
* Note that normally, the input is supposed to contain a single decodable
* PEM block only, so this special handling should not create a new problem.
- *
- * Note that we need to create the OSSL_DECODER_CTX variable each time when
- * we use the different selection as a workaround.
- * See https://github.com/openssl/openssl/issues/20657 for details.
*/
- int selections[] = {
- EVP_PKEY_KEYPAIR,
- EVP_PKEY_KEY_PARAMETERS,
- EVP_PKEY_PUBLIC_KEY
- };
- int selection_num = (int)(sizeof(selections) / sizeof(int));
- int i, j;
-
- for (i = 0; i < input_type_num; i++) {
- for (j = 0; j < selection_num; j++) {
- pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass);
- if (pkey) {
- goto out;
- }
- }
+ OSSL_DECODER_CTX_set_selection(dctx, EVP_PKEY_KEYPAIR);
+ while (1) {
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
+ goto out;
+ if (BIO_eof(bio))
+ break;
+ pos2 = BIO_tell(bio);
+ if (pos2 < 0 || pos2 <= pos)
+ break;
+ ossl_clear_error();
+ pos = pos2;
}
+
+ OSSL_BIO_reset(bio);
+ OSSL_DECODER_CTX_set_selection(dctx, 0);
+ while (1) {
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
+ goto out;
+ if (BIO_eof(bio))
+ break;
+ pos2 = BIO_tell(bio);
+ if (pos2 < 0 || pos2 <= pos)
+ break;
+ ossl_clear_error();
+ pos = pos2;
+ }
+
out:
+ OSSL_DECODER_CTX_free(dctx);
return pkey;
}
#else
@@ -283,9 +260,9 @@ struct pkey_blocking_generate_arg {
EVP_PKEY_CTX *ctx;
EVP_PKEY *pkey;
int state;
- unsigned int yield: 1;
- unsigned int genparam: 1;
- unsigned int interrupted: 1;
+ int yield: 1;
+ int genparam: 1;
+ int interrupted: 1;
};
static VALUE
@@ -635,72 +612,6 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other)
}
#endif
-#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
-/*
- * call-seq:
- * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey
- *
- * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key()
- */
-
-static VALUE
-ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
-{
- EVP_PKEY *pkey;
- const EVP_PKEY_ASN1_METHOD *ameth;
- int pkey_id;
- size_t keylen;
-
- StringValue(type);
- StringValue(key);
- ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
- if (!ameth)
- ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
-
- keylen = RSTRING_LEN(key);
-
- pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
- if (!pkey)
- ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key");
-
- return ossl_pkey_new(pkey);
-}
-#endif
-
-#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
-/*
- * call-seq:
- * OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey
- *
- * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key()
- */
-
-static VALUE
-ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
-{
- EVP_PKEY *pkey;
- const EVP_PKEY_ASN1_METHOD *ameth;
- int pkey_id;
- size_t keylen;
-
- StringValue(type);
- StringValue(key);
- ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
- if (!ameth)
- ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
-
- keylen = RSTRING_LEN(key);
-
- pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
- if (!pkey)
- ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key");
-
- return ossl_pkey_new(pkey);
-}
-#endif
-
/*
* call-seq:
* pkey.oid -> string
@@ -882,18 +793,6 @@ ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self)
*
* Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der
* for more details.
- *
- * An unencrypted PEM-encoded key will look like:
- *
- * -----BEGIN PRIVATE KEY-----
- * [...]
- * -----END PRIVATE KEY-----
- *
- * An encrypted PEM-encoded key will look like:
- *
- * -----BEGIN ENCRYPTED PRIVATE KEY-----
- * [...]
- * -----END ENCRYPTED PRIVATE KEY-----
*/
static VALUE
ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
@@ -901,35 +800,6 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
return do_pkcs8_export(argc, argv, self, 0);
}
-#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
-/*
- * call-seq:
- * pkey.raw_private_key => string
- *
- * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key()
- */
-
-static VALUE
-ossl_pkey_raw_private_key(VALUE self)
-{
- EVP_PKEY *pkey;
- VALUE str;
- size_t len;
-
- GetPKey(self, pkey);
- if (EVP_PKEY_get_raw_private_key(pkey, NULL, &len) != 1)
- ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key");
- str = rb_str_new(NULL, len);
-
- if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1)
- ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key");
-
- rb_str_set_len(str, len);
-
- return str;
-}
-#endif
-
VALUE
ossl_pkey_export_spki(VALUE self, int to_der)
{
@@ -972,12 +842,6 @@ ossl_pkey_public_to_der(VALUE self)
* pkey.public_to_pem -> string
*
* Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format.
- *
- * A PEM-encoded key will look like:
- *
- * -----BEGIN PUBLIC KEY-----
- * [...]
- * -----END PUBLIC KEY-----
*/
static VALUE
ossl_pkey_public_to_pem(VALUE self)
@@ -985,35 +849,6 @@ ossl_pkey_public_to_pem(VALUE self)
return ossl_pkey_export_spki(self, 0);
}
-#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
-/*
- * call-seq:
- * pkey.raw_public_key => string
- *
- * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key()
- */
-
-static VALUE
-ossl_pkey_raw_public_key(VALUE self)
-{
- EVP_PKEY *pkey;
- VALUE str;
- size_t len;
-
- GetPKey(self, pkey);
- if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1)
- ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key");
- str = rb_str_new(NULL, len);
-
- if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1)
- ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key");
-
- rb_str_set_len(str, len);
-
- return str;
-}
-#endif
-
/*
* call-seq:
* pkey.compare?(another_pkey) -> true | false
@@ -1751,10 +1586,6 @@ Init_ossl_pkey(void)
rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1);
rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1);
-#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
- rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2);
- rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2);
-#endif
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
@@ -1770,10 +1601,6 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
-#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
- rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0);
- rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0);
-#endif
rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1);
rb_define_method(cPKey, "sign", ossl_pkey_sign, -1);
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index a231814a99..83c41378fe 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -216,20 +216,9 @@ ossl_dh_is_private(VALUE self)
* dh.to_pem -> aString
* dh.to_s -> aString
*
- * Serializes the DH parameters to a PEM-encoding.
- *
- * Note that any existing per-session public/private keys will *not* get
- * encoded, just the Diffie-Hellman parameters will be encoded.
- *
- * PEM-encoded parameters will look like:
- *
- * -----BEGIN DH PARAMETERS-----
- * [...]
- * -----END DH PARAMETERS-----
- *
- * See also #public_to_pem (X.509 SubjectPublicKeyInfo) and
- * #private_to_pem (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
- * serialization with the private or public key components.
+ * Encodes this DH to its PEM encoding. Note that any existing per-session
+ * public/private keys will *not* get encoded, just the Diffie-Hellman
+ * parameters will be encoded.
*/
static VALUE
ossl_dh_export(VALUE self)
@@ -255,14 +244,10 @@ ossl_dh_export(VALUE self)
* call-seq:
* dh.to_der -> aString
*
- * Serializes the DH parameters to a DER-encoding
- *
- * Note that any existing per-session public/private keys will *not* get
- * encoded, just the Diffie-Hellman parameters will be encoded.
- *
- * See also #public_to_der (X.509 SubjectPublicKeyInfo) and
- * #private_to_der (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
- * serialization with the private or public key components.
+ * Encodes this DH to its DER encoding. Note that any existing per-session
+ * public/private keys will *not* get encoded, just the Diffie-Hellman
+ * parameters will be encoded.
+
*/
static VALUE
ossl_dh_to_der(VALUE self)
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index 058ce73888..b097f8c9d2 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -211,58 +211,16 @@ ossl_dsa_is_private(VALUE self)
* dsa.to_pem([cipher, password]) -> aString
* dsa.to_s([cipher, password]) -> aString
*
- * Serializes a private or public key to a PEM-encoding.
+ * Encodes this DSA to its PEM encoding.
*
- * [When the key contains public components only]
+ * === Parameters
+ * * _cipher_ is an OpenSSL::Cipher.
+ * * _password_ is a string containing your password.
*
- * Serializes it into an X.509 SubjectPublicKeyInfo.
- * The parameters _cipher_ and _password_ are ignored.
+ * === Examples
+ * DSA.to_pem -> aString
+ * DSA.to_pem(cipher, 'mypassword') -> aString
*
- * A PEM-encoded key will look like:
- *
- * -----BEGIN PUBLIC KEY-----
- * [...]
- * -----END PUBLIC KEY-----
- *
- * Consider using #public_to_pem instead. This serializes the key into an
- * X.509 SubjectPublicKeyInfo regardless of whether it is a public key
- * or a private key.
- *
- * [When the key contains private components, and no parameters are given]
- *
- * Serializes it into a traditional \OpenSSL DSAPrivateKey.
- *
- * A PEM-encoded key will look like:
- *
- * -----BEGIN DSA PRIVATE KEY-----
- * [...]
- * -----END DSA PRIVATE KEY-----
- *
- * [When the key contains private components, and _cipher_ and _password_ are given]
- *
- * Serializes it into a traditional \OpenSSL DSAPrivateKey and encrypts it in
- * OpenSSL's traditional PEM encryption format.
- * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
- * instance of OpenSSL::Cipher.
- *
- * An encrypted PEM-encoded key will look like:
- *
- * -----BEGIN DSA PRIVATE KEY-----
- * Proc-Type: 4,ENCRYPTED
- * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
- *
- * [...]
- * -----END DSA PRIVATE KEY-----
- *
- * Note that this format uses MD5 to derive the encryption key, and hence
- * will not be available on FIPS-compliant systems.
- *
- * <b>This method is kept for compatibility.</b>
- * This should only be used when the traditional, non-standard \OpenSSL format
- * is required.
- *
- * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
- * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
*/
static VALUE
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
@@ -280,15 +238,8 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
* call-seq:
* dsa.to_der -> aString
*
- * Serializes a private or public key to a DER-encoding.
- *
- * See #to_pem for details.
- *
- * <b>This method is kept for compatibility.</b>
- * This should only be used when the traditional, non-standard \OpenSSL format
- * is required.
+ * Encodes this DSA to its DER encoding.
*
- * Consider using #public_to_der or #private_to_der instead.
*/
static VALUE
ossl_dsa_to_der(VALUE self)
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 4b3a1fd0fe..92842f95ac 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -400,61 +400,13 @@ static VALUE ossl_ec_key_is_private(VALUE self)
/*
* call-seq:
- * key.export([cipher, password]) => String
- * key.to_pem([cipher, password]) => String
+ * key.export([cipher, pass_phrase]) => String
+ * key.to_pem([cipher, pass_phrase]) => String
*
- * Serializes a private or public key to a PEM-encoding.
- *
- * [When the key contains public components only]
- *
- * Serializes it into an X.509 SubjectPublicKeyInfo.
- * The parameters _cipher_ and _password_ are ignored.
- *
- * A PEM-encoded key will look like:
- *
- * -----BEGIN PUBLIC KEY-----
- * [...]
- * -----END PUBLIC KEY-----
- *
- * Consider using #public_to_pem instead. This serializes the key into an
- * X.509 SubjectPublicKeyInfo regardless of whether it is a public key
- * or a private key.
- *
- * [When the key contains private components, and no parameters are given]
- *
- * Serializes it into a SEC 1/RFC 5915 ECPrivateKey.
- *
- * A PEM-encoded key will look like:
- *
- * -----BEGIN EC PRIVATE KEY-----
- * [...]
- * -----END EC PRIVATE KEY-----
- *
- * [When the key contains private components, and _cipher_ and _password_ are given]
- *
- * Serializes it into a SEC 1/RFC 5915 ECPrivateKey
- * and encrypts it in OpenSSL's traditional PEM encryption format.
- * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
- * instance of OpenSSL::Cipher.
- *
- * An encrypted PEM-encoded key will look like:
- *
- * -----BEGIN EC PRIVATE KEY-----
- * Proc-Type: 4,ENCRYPTED
- * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
- *
- * [...]
- * -----END EC PRIVATE KEY-----
- *
- * Note that this format uses MD5 to derive the encryption key, and hence
- * will not be available on FIPS-compliant systems.
- *
- * <b>This method is kept for compatibility.</b>
- * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is
- * required.
- *
- * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
- * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
+ * Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given
+ * they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher
+ * instance. Note that encryption will only be effective for a private key,
+ * public keys will always be encoded in plain text.
*/
static VALUE
ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
@@ -474,15 +426,7 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
* call-seq:
* key.to_der => String
*
- * Serializes a private or public key to a DER-encoding.
- *
- * See #to_pem for details.
- *
- * <b>This method is kept for compatibility.</b>
- * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is
- * required.
- *
- * Consider using #public_to_der or #private_to_der instead.
+ * See the OpenSSL documentation for i2d_ECPrivateKey_bio()
*/
static VALUE
ossl_ec_key_to_der(VALUE self)
@@ -586,7 +530,7 @@ static const rb_data_type_t ossl_ec_group_type = {
{
0, ossl_ec_group_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
@@ -1171,7 +1115,7 @@ static const rb_data_type_t ossl_ec_point_type = {
{
0, ossl_ec_point_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 389f76f309..072adabe62 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -50,8 +50,8 @@ VALUE eRSAError;
/*
* call-seq:
* RSA.new -> rsa
- * RSA.new(encoded_key [, password ]) -> rsa
- * RSA.new(encoded_key) { password } -> rsa
+ * RSA.new(encoded_key [, passphrase]) -> rsa
+ * RSA.new(encoded_key) { passphrase } -> rsa
* RSA.new(size [, exponent]) -> rsa
*
* Generates or loads an \RSA keypair.
@@ -61,9 +61,9 @@ VALUE eRSAError;
* #set_crt_params.
*
* If called with a String, tries to parse as DER or PEM encoding of an \RSA key.
- * Note that if _password_ is not specified, but the key is encrypted with a
- * password, \OpenSSL will prompt for it.
- * See also OpenSSL::PKey.read which can parse keys of any kind.
+ * Note that, if _passphrase_ is not specified but the key is encrypted with a
+ * passphrase, \OpenSSL will prompt for it.
+ * See also OpenSSL::PKey.read which can parse keys of any kinds.
*
* If called with a number, generates a new key pair. This form works as an
* alias of RSA.generate.
@@ -71,7 +71,7 @@ VALUE eRSAError;
* Examples:
* OpenSSL::PKey::RSA.new 2048
* OpenSSL::PKey::RSA.new File.read 'rsa.pem'
- * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password'
+ * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
*/
static VALUE
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
@@ -217,61 +217,13 @@ can_export_rsaprivatekey(VALUE self)
/*
* call-seq:
- * rsa.export([cipher, password]) => PEM-format String
- * rsa.to_pem([cipher, password]) => PEM-format String
- * rsa.to_s([cipher, password]) => PEM-format String
+ * rsa.export([cipher, pass_phrase]) => PEM-format String
+ * rsa.to_pem([cipher, pass_phrase]) => PEM-format String
+ * rsa.to_s([cipher, pass_phrase]) => PEM-format String
*
- * Serializes a private or public key to a PEM-encoding.
- *
- * [When the key contains public components only]
- *
- * Serializes it into an X.509 SubjectPublicKeyInfo.
- * The parameters _cipher_ and _password_ are ignored.
- *
- * A PEM-encoded key will look like:
- *
- * -----BEGIN PUBLIC KEY-----
- * [...]
- * -----END PUBLIC KEY-----
- *
- * Consider using #public_to_pem instead. This serializes the key into an
- * X.509 SubjectPublicKeyInfo regardless of whether the key is a public key
- * or a private key.
- *
- * [When the key contains private components, and no parameters are given]
- *
- * Serializes it into a PKCS #1 RSAPrivateKey.
- *
- * A PEM-encoded key will look like:
- *
- * -----BEGIN RSA PRIVATE KEY-----
- * [...]
- * -----END RSA PRIVATE KEY-----
- *
- * [When the key contains private components, and _cipher_ and _password_ are given]
- *
- * Serializes it into a PKCS #1 RSAPrivateKey
- * and encrypts it in OpenSSL's traditional PEM encryption format.
- * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
- * instance of OpenSSL::Cipher.
- *
- * An encrypted PEM-encoded key will look like:
- *
- * -----BEGIN RSA PRIVATE KEY-----
- * Proc-Type: 4,ENCRYPTED
- * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
- *
- * [...]
- * -----END RSA PRIVATE KEY-----
- *
- * Note that this format uses MD5 to derive the encryption key, and hence
- * will not be available on FIPS-compliant systems.
- *
- * <b>This method is kept for compatibility.</b>
- * This should only be used when the PKCS #1 RSAPrivateKey format is required.
- *
- * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
- * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
+ * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are
+ * given they will be used to encrypt the key. _cipher_ must be an
+ * OpenSSL::Cipher instance.
*/
static VALUE
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
@@ -286,14 +238,7 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
* call-seq:
* rsa.to_der => DER-format String
*
- * Serializes a private or public key to a DER-encoding.
- *
- * See #to_pem for details.
- *
- * <b>This method is kept for compatibility.</b>
- * This should only be used when the PKCS #1 RSAPrivateKey format is required.
- *
- * Consider using #public_to_der or #private_to_der instead.
+ * Outputs this keypair in DER encoding.
*/
static VALUE
ossl_rsa_to_der(VALUE self)
diff --git a/ext/openssl/ossl_provider.c b/ext/openssl/ossl_provider.c
deleted file mode 100644
index 981c6ccdc7..0000000000
--- a/ext/openssl/ossl_provider.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * This program is licensed under the same licence as Ruby.
- * (See the file 'LICENCE'.)
- */
-#include "ossl.h"
-
-#ifdef OSSL_USE_PROVIDER
-# include <openssl/provider.h>
-
-#define NewProvider(klass) \
- TypedData_Wrap_Struct((klass), &ossl_provider_type, 0)
-#define SetProvider(obj, provider) do { \
- if (!(provider)) { \
- ossl_raise(rb_eRuntimeError, "Provider wasn't initialized."); \
- } \
- RTYPEDDATA_DATA(obj) = (provider); \
-} while(0)
-#define GetProvider(obj, provider) do { \
- TypedData_Get_Struct((obj), OSSL_PROVIDER, &ossl_provider_type, (provider)); \
- if (!(provider)) { \
- ossl_raise(rb_eRuntimeError, "PROVIDER wasn't initialized."); \
- } \
-} while (0)
-
-static const rb_data_type_t ossl_provider_type = {
- "OpenSSL/Provider",
- {
- 0,
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
-};
-
-/*
- * Classes
- */
-/* Document-class: OpenSSL::Provider
- *
- * This class is the access to openssl's Provider
- * See also, https://www.openssl.org/docs/manmaster/man7/provider.html
- */
-static VALUE cProvider;
-/* Document-class: OpenSSL::Provider::ProviderError
- *
- * This is the generic exception for OpenSSL::Provider related errors
- */
-static VALUE eProviderError;
-
-/*
- * call-seq:
- * OpenSSL::Provider.load(name) -> provider
- *
- * This method loads and initializes a provider
- */
-static VALUE
-ossl_provider_s_load(VALUE klass, VALUE name)
-{
- OSSL_PROVIDER *provider = NULL;
- VALUE obj;
-
- const char *provider_name_ptr = StringValueCStr(name);
-
- provider = OSSL_PROVIDER_load(NULL, provider_name_ptr);
- if (provider == NULL) {
- ossl_raise(eProviderError, "Failed to load %s provider", provider_name_ptr);
- }
- obj = NewProvider(klass);
- SetProvider(obj, provider);
-
- return obj;
-}
-
-struct ary_with_state { VALUE ary; int state; };
-struct rb_push_provider_name_args { OSSL_PROVIDER *prov; VALUE ary; };
-
-static VALUE
-rb_push_provider_name(VALUE rb_push_provider_name_args)
-{
- struct rb_push_provider_name_args *args = (struct rb_push_provider_name_args *)rb_push_provider_name_args;
-
- VALUE name = rb_str_new2(OSSL_PROVIDER_get0_name(args->prov));
- return rb_ary_push(args->ary, name);
-}
-
-static int
-push_provider(OSSL_PROVIDER *prov, void *cbdata)
-{
- struct ary_with_state *ary_with_state = (struct ary_with_state *)cbdata;
- struct rb_push_provider_name_args args = { prov, ary_with_state->ary };
-
- rb_protect(rb_push_provider_name, (VALUE)&args, &ary_with_state->state);
- if (ary_with_state->state) {
- return 0;
- } else {
- return 1;
- }
-}
-
-/*
- * call-seq:
- * OpenSSL::Provider.provider_names -> [provider_name, ...]
- *
- * Returns an array of currently loaded provider names.
- */
-static VALUE
-ossl_provider_s_provider_names(VALUE klass)
-{
- VALUE ary = rb_ary_new();
- struct ary_with_state cbdata = { ary, 0 };
-
- int result = OSSL_PROVIDER_do_all(NULL, &push_provider, (void*)&cbdata);
- if (result != 1 ) {
- if (cbdata.state) {
- rb_jump_tag(cbdata.state);
- } else {
- ossl_raise(eProviderError, "Failed to load provider names");
- }
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * provider.unload -> true
- *
- * This method unloads this provider.
- *
- * if provider unload fails or already unloaded, it raises OpenSSL::Provider::ProviderError
- */
-static VALUE
-ossl_provider_unload(VALUE self)
-{
- OSSL_PROVIDER *prov;
- if (RTYPEDDATA_DATA(self) == NULL) {
- ossl_raise(eProviderError, "Provider already unloaded.");
- }
- GetProvider(self, prov);
-
- int result = OSSL_PROVIDER_unload(prov);
-
- if (result != 1) {
- ossl_raise(eProviderError, "Failed to unload provider");
- }
- RTYPEDDATA_DATA(self) = NULL;
- return Qtrue;
-}
-
-/*
- * call-seq:
- * provider.name -> string
- *
- * Get the name of this provider.
- *
- * if this provider is already unloaded, it raises OpenSSL::Provider::ProviderError
- */
-static VALUE
-ossl_provider_get_name(VALUE self)
-{
- OSSL_PROVIDER *prov;
- if (RTYPEDDATA_DATA(self) == NULL) {
- ossl_raise(eProviderError, "Provider already unloaded.");
- }
- GetProvider(self, prov);
-
- return rb_str_new2(OSSL_PROVIDER_get0_name(prov));
-}
-
-/*
- * call-seq:
- * provider.inspect -> string
- *
- * Pretty prints this provider.
- */
-static VALUE
-ossl_provider_inspect(VALUE self)
-{
- OSSL_PROVIDER *prov;
- if (RTYPEDDATA_DATA(self) == NULL ) {
- return rb_sprintf("#<%"PRIsVALUE" unloaded provider>", rb_obj_class(self));
- }
- GetProvider(self, prov);
-
- return rb_sprintf("#<%"PRIsVALUE" name=\"%s\">",
- rb_obj_class(self), OSSL_PROVIDER_get0_name(prov));
-}
-
-void
-Init_ossl_provider(void)
-{
-#if 0
- mOSSL = rb_define_module("OpenSSL");
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
-#endif
-
- cProvider = rb_define_class_under(mOSSL, "Provider", rb_cObject);
- eProviderError = rb_define_class_under(cProvider, "ProviderError", eOSSLError);
-
- rb_undef_alloc_func(cProvider);
- rb_define_singleton_method(cProvider, "load", ossl_provider_s_load, 1);
- rb_define_singleton_method(cProvider, "provider_names", ossl_provider_s_provider_names, 0);
-
- rb_define_method(cProvider, "unload", ossl_provider_unload, 0);
- rb_define_method(cProvider, "name", ossl_provider_get_name, 0);
- rb_define_method(cProvider, "inspect", ossl_provider_inspect, 0);
-}
-#else
-void
-Init_ossl_provider(void)
-{
-}
-#endif
diff --git a/ext/openssl/ossl_provider.h b/ext/openssl/ossl_provider.h
deleted file mode 100644
index 1d69cb1e44..0000000000
--- a/ext/openssl/ossl_provider.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(OSSL_PROVIDER_H)
-#define OSSL_PROVIDER_H
-
-void Init_ossl_provider(void);
-#endif
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 236d455ff2..f63992664a 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -77,7 +77,7 @@ static const rb_data_type_t ossl_sslctx_type = {
{
ossl_sslctx_mark, ossl_sslctx_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
@@ -885,9 +885,9 @@ ossl_sslctx_setup(VALUE self)
if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
#else
- if (ca_file || ca_path) {
- if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
- ossl_raise(eSSLError, "SSL_CTX_load_verify_locations");
+ if(ca_file || ca_path){
+ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
+ rb_warning("can't set verify locations");
}
#endif
@@ -1553,10 +1553,6 @@ ossl_ssl_mark(void *ptr)
{
SSL *ssl = ptr;
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
-
- // Note: this reference is stored as @verify_callback so we don't need to mark it.
- // However we do need to ensure GC compaction won't move it, hence why
- // we call rb_gc_mark here.
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
}
@@ -1571,7 +1567,7 @@ const rb_data_type_t ossl_ssl_type = {
{
ossl_ssl_mark, ossl_ssl_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
@@ -1650,8 +1646,6 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
SSL_set_info_callback(ssl, ssl_info_cb);
verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
- // We don't need to trigger a write barrier because it's already
- // an instance variable of this object.
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
rb_call_super(0, NULL);
@@ -1659,17 +1653,6 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
return self;
}
-#ifndef HAVE_RB_IO_DESCRIPTOR
-static int
-io_descriptor_fallback(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- return fptr->fd;
-}
-#define rb_io_descriptor io_descriptor_fallback
-#endif
-
static VALUE
ossl_ssl_setup(VALUE self)
{
@@ -1685,8 +1668,8 @@ ossl_ssl_setup(VALUE self)
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
rb_io_check_writable(fptr);
- if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io))))
- ossl_raise(eSSLError, "SSL_set_fd");
+ if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
+ ossl_raise(eSSLError, "SSL_set_fd");
return Qtrue;
}
@@ -1726,25 +1709,21 @@ no_exception_p(VALUE opts)
#endif
static void
-io_wait_writable(VALUE io)
+io_wait_writable(rb_io_t *fptr)
{
#ifdef HAVE_RB_IO_MAYBE_WAIT
- rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
+ rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
#else
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
rb_io_wait_writable(fptr->fd);
#endif
}
static void
-io_wait_readable(VALUE io)
+io_wait_readable(rb_io_t *fptr)
{
#ifdef HAVE_RB_IO_MAYBE_WAIT
- rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
+ rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
#else
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
rb_io_wait_readable(fptr->fd);
#endif
}
@@ -1753,74 +1732,75 @@ static VALUE
ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
{
SSL *ssl;
+ rb_io_t *fptr;
int ret, ret2;
VALUE cb_state;
int nonblock = opts != Qfalse;
+#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
+ unsigned long err;
+#endif
rb_ivar_set(self, ID_callback_state, Qnil);
GetSSL(self, ssl);
- VALUE io = rb_attr_get(self, id_i_io);
- for (;;) {
- ret = func(ssl);
+ GetOpenFile(rb_attr_get(self, id_i_io), fptr);
+ for(;;){
+ ret = func(ssl);
- cb_state = rb_attr_get(self, ID_callback_state);
+ cb_state = rb_attr_get(self, ID_callback_state);
if (!NIL_P(cb_state)) {
- /* must cleanup OpenSSL error stack before re-raising */
- ossl_clear_error();
- rb_jump_tag(NUM2INT(cb_state));
- }
+ /* must cleanup OpenSSL error stack before re-raising */
+ ossl_clear_error();
+ rb_jump_tag(NUM2INT(cb_state));
+ }
- if (ret > 0)
- break;
+ if (ret > 0)
+ break;
- switch ((ret2 = ssl_get_error(ssl, ret))) {
- case SSL_ERROR_WANT_WRITE:
+ switch((ret2 = ssl_get_error(ssl, ret))){
+ case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
- io_wait_writable(io);
+ io_wait_writable(fptr);
continue;
- case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_READ:
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
- io_wait_readable(io);
+ io_wait_readable(fptr);
continue;
- case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SYSCALL:
#ifdef __APPLE__
/* See ossl_ssl_write_internal() */
if (errno == EPROTOTYPE)
continue;
#endif
- if (errno) rb_sys_fail(funcname);
- /* fallthrough */
- default: {
- VALUE error_append = Qnil;
+ if (errno) rb_sys_fail(funcname);
+ ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
+
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
- unsigned long err = ERR_peek_last_error();
- if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
- ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
- const char *err_msg = ERR_reason_error_string(err),
- *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
- if (!err_msg)
- err_msg = "(null)";
- if (!verify_msg)
- verify_msg = "(null)";
- ossl_clear_error(); /* let ossl_raise() not append message */
- error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg);
- }
+ case SSL_ERROR_SSL:
+ err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
+ ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
+ const char *err_msg = ERR_reason_error_string(err),
+ *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
+ if (!err_msg)
+ err_msg = "(null)";
+ if (!verify_msg)
+ verify_msg = "(null)";
+ ossl_clear_error(); /* let ossl_raise() not append message */
+ ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
+ err_msg, verify_msg);
+ }
#endif
- ossl_raise(eSSLError,
- "%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
- funcname,
- ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
- ret2,
- errno,
- peeraddr_ip_str(self),
- SSL_state_string_long(ssl),
- error_append);
- }
- }
+ /* fallthrough */
+ default:
+ ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
+ }
}
return self;
@@ -1926,7 +1906,8 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
SSL *ssl;
int ilen;
VALUE len, str;
- VALUE opts = Qnil;
+ rb_io_t *fptr;
+ VALUE io, opts = Qnil;
if (nonblock) {
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
@@ -1951,7 +1932,8 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
if (ilen == 0)
return str;
- VALUE io = rb_attr_get(self, id_i_io);
+ io = rb_attr_get(self, id_i_io);
+ GetOpenFile(io, fptr);
rb_str_locktmp(str);
for (;;) {
@@ -1971,7 +1953,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
}
- io_wait_writable(io);
+ io_wait_writable(fptr);
continue;
case SSL_ERROR_WANT_READ:
if (nonblock) {
@@ -1979,7 +1961,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
}
- io_wait_readable(io);
+ io_wait_readable(fptr);
continue;
case SSL_ERROR_SYSCALL:
if (!ERR_peek_error()) {
@@ -2045,14 +2027,14 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
SSL *ssl;
rb_io_t *fptr;
int num, nonblock = opts != Qfalse;
- VALUE tmp;
+ VALUE tmp, io;
GetSSL(self, ssl);
if (!ssl_started(ssl))
rb_raise(eSSLError, "SSL session is not started yet");
tmp = rb_str_new_frozen(StringValue(str));
- VALUE io = rb_attr_get(self, id_i_io);
+ io = rb_attr_get(self, id_i_io);
GetOpenFile(io, fptr);
/* SSL_write(3ssl) manpage states num == 0 is undefined */
@@ -2068,12 +2050,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
- io_wait_writable(io);
+ io_wait_writable(fptr);
continue;
case SSL_ERROR_WANT_READ:
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
- io_wait_readable(io);
+ io_wait_readable(fptr);
continue;
case SSL_ERROR_SYSCALL:
#ifdef __APPLE__
diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c
index c5df902c60..139a474b04 100644
--- a/ext/openssl/ossl_ssl_session.c
+++ b/ext/openssl/ossl_ssl_session.c
@@ -19,7 +19,7 @@ const rb_data_type_t ossl_ssl_session_type = {
{
0, ossl_ssl_session_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE ossl_ssl_session_alloc(VALUE klass)
diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c
index f698bdc7ff..b33ff10c10 100644
--- a/ext/openssl/ossl_ts.c
+++ b/ext/openssl/ossl_ts.c
@@ -83,7 +83,7 @@ static const rb_data_type_t ossl_ts_req_type = {
{
0, ossl_ts_req_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -97,7 +97,7 @@ static const rb_data_type_t ossl_ts_resp_type = {
{
0, ossl_ts_resp_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static void
@@ -111,7 +111,7 @@ static const rb_data_type_t ossl_ts_token_info_type = {
{
0, ossl_ts_token_info_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c
index d1d8bb5e95..60846cfe9d 100644
--- a/ext/openssl/ossl_x509attr.c
+++ b/ext/openssl/ossl_x509attr.c
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509attr_type = {
{
0, ossl_x509attr_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index aa6b9bb7ce..9443541645 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509_type = {
{
0, ossl_x509_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
index 80e29f9df2..6c1d915370 100644
--- a/ext/openssl/ossl_x509crl.c
+++ b/ext/openssl/ossl_x509crl.c
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509crl_type = {
{
0, ossl_x509crl_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c
index 192d09bd3f..e54102c771 100644
--- a/ext/openssl/ossl_x509ext.c
+++ b/ext/openssl/ossl_x509ext.c
@@ -55,7 +55,7 @@ static const rb_data_type_t ossl_x509ext_type = {
{
0, ossl_x509ext_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
@@ -108,7 +108,7 @@ static const rb_data_type_t ossl_x509extfactory_type = {
{
0, ossl_x509extfactory_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
@@ -209,16 +209,15 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
int nid;
VALUE rconf;
CONF *conf;
- const char *oid_cstr = NULL;
rb_scan_args(argc, argv, "21", &oid, &value, &critical);
+ StringValueCStr(oid);
StringValue(value);
if(NIL_P(critical)) critical = Qfalse;
- oid_cstr = StringValueCStr(oid);
- nid = OBJ_ln2nid(oid_cstr);
- if (nid != NID_undef)
- oid_cstr = OBJ_nid2sn(nid);
+ nid = OBJ_ln2nid(RSTRING_PTR(oid));
+ if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid));
+ if(!nid) ossl_raise(eX509ExtError, "unknown OID `%"PRIsVALUE"'", oid);
valstr = rb_str_new2(RTEST(critical) ? "critical," : "");
rb_str_append(valstr, value);
@@ -229,12 +228,7 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
rconf = rb_iv_get(self, "@config");
conf = NIL_P(rconf) ? NULL : GetConfig(rconf);
X509V3_set_nconf(ctx, conf);
-
-#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_IS_LIBRESSL
- ext = X509V3_EXT_nconf(conf, ctx, oid_cstr, RSTRING_PTR(valstr));
-#else
- ext = X509V3_EXT_nconf(conf, ctx, (char *)oid_cstr, RSTRING_PTR(valstr));
-#endif
+ ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
X509V3_set_ctx_nodb(ctx);
if (!ext){
ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr);
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c
index 9591912f70..13a2b2c030 100644
--- a/ext/openssl/ossl_x509name.c
+++ b/ext/openssl/ossl_x509name.c
@@ -46,7 +46,7 @@ static const rb_data_type_t ossl_x509name_type = {
{
0, ossl_x509name_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
index f058185151..77a7d3f2ff 100644
--- a/ext/openssl/ossl_x509req.c
+++ b/ext/openssl/ossl_x509req.c
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509req_type = {
{
0, ossl_x509req_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c
index 108447c868..10b8aa4ad6 100644
--- a/ext/openssl/ossl_x509revoked.c
+++ b/ext/openssl/ossl_x509revoked.c
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509rev_type = {
{
0, ossl_x509rev_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c
index f27381ca90..7c546187c3 100644
--- a/ext/openssl/ossl_x509store.c
+++ b/ext/openssl/ossl_x509store.c
@@ -116,9 +116,6 @@ static void
ossl_x509store_mark(void *ptr)
{
X509_STORE *store = ptr;
- // Note: this reference is stored as @verify_callback so we don't need to mark it.
- // However we do need to ensure GC compaction won't move it, hence why
- // we call rb_gc_mark here.
rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
}
@@ -133,7 +130,7 @@ static const rb_data_type_t ossl_x509store_type = {
{
ossl_x509store_mark, ossl_x509store_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
/*
@@ -190,9 +187,8 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
X509_STORE *store;
GetX509Store(self, store);
- rb_iv_set(self, "@verify_callback", cb);
- // We don't need to trigger a write barrier because `rb_iv_set` did it.
X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
+ rb_iv_set(self, "@verify_callback", cb);
return cb;
}
@@ -511,9 +507,6 @@ static void
ossl_x509stctx_mark(void *ptr)
{
X509_STORE_CTX *ctx = ptr;
- // Note: this reference is stored as @verify_callback so we don't need to mark it.
- // However we do need to ensure GC compaction won't move it, hence why
- // we call rb_gc_mark here.
rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
}
@@ -533,7 +526,7 @@ static const rb_data_type_t ossl_x509stctx_type = {
{
ossl_x509stctx_mark, ossl_x509stctx_free,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
@@ -621,8 +614,8 @@ ossl_x509stctx_verify(VALUE self)
X509_STORE_CTX *ctx;
GetX509StCtx(self, ctx);
- VALUE cb = rb_iv_get(self, "@verify_callback");
- X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, (void *)cb);
+ X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx,
+ (void *)rb_iv_get(self, "@verify_callback"));
switch (X509_verify_cert(ctx)) {
case 1:
diff --git a/ext/pathname/depend b/ext/pathname/depend
index 5dd8b042de..a6b000e305 100644
--- a/ext/pathname/depend
+++ b/ext/pathname/depend
@@ -53,7 +53,6 @@ pathname.o: $(hdrdir)/ruby/internal/attr/noexcept.h
pathname.o: $(hdrdir)/ruby/internal/attr/noinline.h
pathname.o: $(hdrdir)/ruby/internal/attr/nonnull.h
pathname.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-pathname.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
pathname.o: $(hdrdir)/ruby/internal/attr/pure.h
pathname.o: $(hdrdir)/ruby/internal/attr/restrict.h
pathname.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ pathname.o: $(hdrdir)/ruby/internal/intern/enumerator.h
pathname.o: $(hdrdir)/ruby/internal/intern/error.h
pathname.o: $(hdrdir)/ruby/internal/intern/eval.h
pathname.o: $(hdrdir)/ruby/internal/intern/file.h
+pathname.o: $(hdrdir)/ruby/internal/intern/gc.h
pathname.o: $(hdrdir)/ruby/internal/intern/hash.h
pathname.o: $(hdrdir)/ruby/internal/intern/io.h
pathname.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ pathname.o: $(hdrdir)/ruby/internal/memory.h
pathname.o: $(hdrdir)/ruby/internal/method.h
pathname.o: $(hdrdir)/ruby/internal/module.h
pathname.o: $(hdrdir)/ruby/internal/newobj.h
+pathname.o: $(hdrdir)/ruby/internal/rgengc.h
pathname.o: $(hdrdir)/ruby/internal/scan_args.h
pathname.o: $(hdrdir)/ruby/internal/special_consts.h
pathname.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index 8eeba6aad2..7bdfd0eb39 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -14,8 +14,6 @@ require 'pathname.so'
class Pathname
- VERSION = "0.3.0"
-
# :stopdoc:
# to_path is implemented so Pathname objects are usable with File.open, etc.
diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c
index 878f216fb5..8ee4bcec5b 100644
--- a/ext/pathname/pathname.c
+++ b/ext/pathname/pathname.c
@@ -131,6 +131,32 @@ path_freeze(VALUE self)
}
/*
+ * call-seq:
+ * pathname.taint -> obj
+ *
+ * Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
+ */
+static VALUE
+path_taint(VALUE self)
+{
+ rb_warn("Pathname#taint is deprecated and will be removed in Ruby 3.2.");
+ return self;
+}
+
+/*
+ * call-seq:
+ * pathname.untaint -> obj
+ *
+ * Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
+ */
+static VALUE
+path_untaint(VALUE self)
+{
+ rb_warn("Pathname#untaint is deprecated and will be removed in Ruby 3.2.");
+ return self;
+}
+
+/*
* Compare this pathname with +other+. The comparison is string-based.
* Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>)
* can refer to the same file.
@@ -1511,6 +1537,8 @@ Init_pathname(void)
rb_cPathname = rb_define_class("Pathname", rb_cObject);
rb_define_method(rb_cPathname, "initialize", path_initialize, 1);
rb_define_method(rb_cPathname, "freeze", path_freeze, 0);
+ rb_define_method(rb_cPathname, "taint", path_taint, 0);
+ rb_define_method(rb_cPathname, "untaint", path_untaint, 0);
rb_define_method(rb_cPathname, "==", path_eq, 1);
rb_define_method(rb_cPathname, "===", path_eq, 1);
rb_define_method(rb_cPathname, "eql?", path_eq, 1);
diff --git a/ext/pathname/pathname.gemspec b/ext/pathname/pathname.gemspec
index 890bc2fde9..92bc02b0db 100644
--- a/ext/pathname/pathname.gemspec
+++ b/ext/pathname/pathname.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", "ext/lib"].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "pathname"
+ spec.version = "0.2.1"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/ext/psych/depend b/ext/psych/depend
index 13fbe3fb19..78bde9a53d 100644
--- a/ext/psych/depend
+++ b/ext/psych/depend
@@ -67,7 +67,6 @@ psych.o: $(hdrdir)/ruby/internal/attr/noexcept.h
psych.o: $(hdrdir)/ruby/internal/attr/noinline.h
psych.o: $(hdrdir)/ruby/internal/attr/nonnull.h
psych.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-psych.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
psych.o: $(hdrdir)/ruby/internal/attr/pure.h
psych.o: $(hdrdir)/ruby/internal/attr/restrict.h
psych.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -136,6 +135,7 @@ psych.o: $(hdrdir)/ruby/internal/intern/enumerator.h
psych.o: $(hdrdir)/ruby/internal/intern/error.h
psych.o: $(hdrdir)/ruby/internal/intern/eval.h
psych.o: $(hdrdir)/ruby/internal/intern/file.h
+psych.o: $(hdrdir)/ruby/internal/intern/gc.h
psych.o: $(hdrdir)/ruby/internal/intern/hash.h
psych.o: $(hdrdir)/ruby/internal/intern/io.h
psych.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -166,6 +166,7 @@ psych.o: $(hdrdir)/ruby/internal/memory.h
psych.o: $(hdrdir)/ruby/internal/method.h
psych.o: $(hdrdir)/ruby/internal/module.h
psych.o: $(hdrdir)/ruby/internal/newobj.h
+psych.o: $(hdrdir)/ruby/internal/rgengc.h
psych.o: $(hdrdir)/ruby/internal/scan_args.h
psych.o: $(hdrdir)/ruby/internal/special_consts.h
psych.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -243,7 +244,6 @@ psych_emitter.o: $(hdrdir)/ruby/internal/attr/noexcept.h
psych_emitter.o: $(hdrdir)/ruby/internal/attr/noinline.h
psych_emitter.o: $(hdrdir)/ruby/internal/attr/nonnull.h
psych_emitter.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-psych_emitter.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
psych_emitter.o: $(hdrdir)/ruby/internal/attr/pure.h
psych_emitter.o: $(hdrdir)/ruby/internal/attr/restrict.h
psych_emitter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -312,6 +312,7 @@ psych_emitter.o: $(hdrdir)/ruby/internal/intern/enumerator.h
psych_emitter.o: $(hdrdir)/ruby/internal/intern/error.h
psych_emitter.o: $(hdrdir)/ruby/internal/intern/eval.h
psych_emitter.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_emitter.o: $(hdrdir)/ruby/internal/intern/gc.h
psych_emitter.o: $(hdrdir)/ruby/internal/intern/hash.h
psych_emitter.o: $(hdrdir)/ruby/internal/intern/io.h
psych_emitter.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -342,6 +343,7 @@ psych_emitter.o: $(hdrdir)/ruby/internal/memory.h
psych_emitter.o: $(hdrdir)/ruby/internal/method.h
psych_emitter.o: $(hdrdir)/ruby/internal/module.h
psych_emitter.o: $(hdrdir)/ruby/internal/newobj.h
+psych_emitter.o: $(hdrdir)/ruby/internal/rgengc.h
psych_emitter.o: $(hdrdir)/ruby/internal/scan_args.h
psych_emitter.o: $(hdrdir)/ruby/internal/special_consts.h
psych_emitter.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -419,7 +421,6 @@ psych_parser.o: $(hdrdir)/ruby/internal/attr/noexcept.h
psych_parser.o: $(hdrdir)/ruby/internal/attr/noinline.h
psych_parser.o: $(hdrdir)/ruby/internal/attr/nonnull.h
psych_parser.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-psych_parser.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
psych_parser.o: $(hdrdir)/ruby/internal/attr/pure.h
psych_parser.o: $(hdrdir)/ruby/internal/attr/restrict.h
psych_parser.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -488,6 +489,7 @@ psych_parser.o: $(hdrdir)/ruby/internal/intern/enumerator.h
psych_parser.o: $(hdrdir)/ruby/internal/intern/error.h
psych_parser.o: $(hdrdir)/ruby/internal/intern/eval.h
psych_parser.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_parser.o: $(hdrdir)/ruby/internal/intern/gc.h
psych_parser.o: $(hdrdir)/ruby/internal/intern/hash.h
psych_parser.o: $(hdrdir)/ruby/internal/intern/io.h
psych_parser.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -518,6 +520,7 @@ psych_parser.o: $(hdrdir)/ruby/internal/memory.h
psych_parser.o: $(hdrdir)/ruby/internal/method.h
psych_parser.o: $(hdrdir)/ruby/internal/module.h
psych_parser.o: $(hdrdir)/ruby/internal/newobj.h
+psych_parser.o: $(hdrdir)/ruby/internal/rgengc.h
psych_parser.o: $(hdrdir)/ruby/internal/scan_args.h
psych_parser.o: $(hdrdir)/ruby/internal/special_consts.h
psych_parser.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -595,7 +598,6 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noexcept.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noinline.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/nonnull.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/pure.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/restrict.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -664,6 +666,7 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/enumerator.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/error.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/eval.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/gc.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/hash.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/io.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -694,6 +697,7 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/memory.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/method.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/module.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/newobj.h
+psych_to_ruby.o: $(hdrdir)/ruby/internal/rgengc.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/scan_args.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/special_consts.h
psych_to_ruby.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -771,7 +775,6 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noexcept.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noinline.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/nonnull.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/pure.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/restrict.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -840,6 +843,7 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/enumerator.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/error.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/eval.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/file.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/gc.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/hash.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/io.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -870,6 +874,7 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/memory.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/method.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/module.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/newobj.h
+psych_yaml_tree.o: $(hdrdir)/ruby/internal/rgengc.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/scan_args.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/special_consts.h
psych_yaml_tree.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/psych/extconf.rb b/ext/psych/extconf.rb
index e7dd0bb60a..41daf8c238 100644
--- a/ext/psych/extconf.rb
+++ b/ext/psych/extconf.rb
@@ -22,7 +22,7 @@ if yaml_source
args = [
yaml_configure,
"--enable-#{shared ? 'shared' : 'static'}",
- "--host=#{RbConfig::CONFIG['host'].sub(/-unknown-/, '-').sub(/arm64/, 'arm')}",
+ "--host=#{RbConfig::CONFIG['host'].sub(/-unknown-/, '-')}",
"CC=#{RbConfig::CONFIG['CC']}",
*(["CFLAGS=-w"] if RbConfig::CONFIG["GCC"] == "yes"),
]
diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb
index ae167472f2..4a2ab58514 100644
--- a/ext/psych/lib/psych.rb
+++ b/ext/psych/lib/psych.rb
@@ -694,8 +694,26 @@ module Psych
dump_tags[klass] = tag
end
+ # Workaround for emulating `warn '...', uplevel: 1` in Ruby 2.4 or lower.
+ def self.warn_with_uplevel(message, uplevel: 1)
+ at = parse_caller(caller[uplevel]).join(':')
+ warn "#{at}: #{message}"
+ end
+
+ def self.parse_caller(at)
+ if /^(.+?):(\d+)(?::in `.*')?/ =~ at
+ file = $1
+ line = $2.to_i
+ [file, line]
+ end
+ end
+ private_class_method :warn_with_uplevel, :parse_caller
+
class << self
if defined?(Ractor)
+ require 'forwardable'
+ extend Forwardable
+
class Config
attr_accessor :load_tags, :dump_tags, :domain_types
def initialize
@@ -709,29 +727,7 @@ module Psych
Ractor.current[:PsychConfig] ||= Config.new
end
- def load_tags
- config.load_tags
- end
-
- def dump_tags
- config.dump_tags
- end
-
- def domain_types
- config.domain_types
- end
-
- def load_tags=(value)
- config.load_tags = value
- end
-
- def dump_tags=(value)
- config.dump_tags = value
- end
-
- def domain_types=(value)
- config.domain_types = value
- end
+ def_delegators :config, :load_tags, :dump_tags, :domain_types, :load_tags=, :dump_tags=, :domain_types=
else
attr_accessor :load_tags
attr_accessor :dump_tags
diff --git a/ext/psych/lib/psych/class_loader.rb b/ext/psych/lib/psych/class_loader.rb
index 50efc35ee2..c2e4ea4c93 100644
--- a/ext/psych/lib/psych/class_loader.rb
+++ b/ext/psych/lib/psych/class_loader.rb
@@ -35,7 +35,7 @@ module Psych
constants.each do |const|
konst = const_get const
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
+ class_eval <<~RUBY
def #{const.to_s.downcase}
load #{konst.inspect}
end
diff --git a/ext/psych/lib/psych/tree_builder.rb b/ext/psych/lib/psych/tree_builder.rb
index 83115bd721..414ca02bf7 100644
--- a/ext/psych/lib/psych/tree_builder.rb
+++ b/ext/psych/lib/psych/tree_builder.rb
@@ -41,7 +41,7 @@ module Psych
Sequence
Mapping
}.each do |node|
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
+ class_eval %{
def start_#{node.downcase}(anchor, tag, implicit, style)
n = Nodes::#{node}.new(anchor, tag, implicit, style)
set_start_location(n)
@@ -54,7 +54,7 @@ module Psych
set_end_location(n)
n
end
- RUBY
+ }
end
###
diff --git a/ext/psych/lib/psych/versions.rb b/ext/psych/lib/psych/versions.rb
index b9e8d9ef11..a592a6916c 100644
--- a/ext/psych/lib/psych/versions.rb
+++ b/ext/psych/lib/psych/versions.rb
@@ -2,9 +2,9 @@
module Psych
# The version of Psych you are using
- VERSION = '5.1.2'
+ VERSION = '5.0.1'
if RUBY_ENGINE == 'jruby'
- DEFAULT_SNAKEYAML_VERSION = '2.7'.freeze
+ DEFAULT_SNAKEYAML_VERSION = '1.33'.freeze
end
end
diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb
index f0fda9bdbc..8614251ca9 100644
--- a/ext/psych/lib/psych/visitors/to_ruby.rb
+++ b/ext/psych/lib/psych/visitors/to_ruby.rb
@@ -101,7 +101,7 @@ module Psych
source = $1
options = 0
lang = nil
- $2&.each_char do |option|
+ ($2 || '').split('').each do |option|
case option
when 'x' then options |= Regexp::EXTENDED
when 'i' then options |= Regexp::IGNORECASE
diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb
index 1dd4094c1d..31858798e4 100644
--- a/ext/psych/lib/psych/visitors/yaml_tree.rb
+++ b/ext/psych/lib/psych/visitors/yaml_tree.rb
@@ -15,29 +15,30 @@ module Psych
class YAMLTree < Psych::Visitors::Visitor
class Registrar # :nodoc:
def initialize
- @obj_to_id = {}.compare_by_identity
- @obj_to_node = {}.compare_by_identity
+ @obj_to_id = {}
+ @obj_to_node = {}
@targets = []
@counter = 0
end
def register target, node
+ return unless target.respond_to? :object_id
@targets << target
- @obj_to_node[target] = node
+ @obj_to_node[target.object_id] = node
end
def key? target
- @obj_to_node.key? target
+ @obj_to_node.key? target.object_id
rescue NoMethodError
false
end
def id_for target
- @obj_to_id[target] ||= (@counter += 1)
+ @obj_to_id[target.object_id] ||= (@counter += 1)
end
def node_for target
- @obj_to_node[target]
+ @obj_to_node[target.object_id]
end
end
@@ -567,7 +568,7 @@ module Psych
raise BadAlias, "Tried to dump an aliased object"
end
- unless Symbol === target || @permitted_classes[target.class]
+ unless @permitted_classes[target.class]
raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
end
@@ -575,7 +576,7 @@ module Psych
end
def visit_Symbol sym
- unless @permitted_classes[Symbol] || @permitted_symbols[sym]
+ unless @permitted_symbols[sym]
raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
end
diff --git a/ext/psych/psych.gemspec b/ext/psych/psych.gemspec
index 34f70095d3..5f5168ddb0 100644
--- a/ext/psych/psych.gemspec
+++ b/ext/psych/psych.gemspec
@@ -21,41 +21,28 @@ DESCRIPTION
s.licenses = ["MIT"]
s.require_paths = ["lib"]
- # for ruby core repository.
- # It was generated by
- # `git ls-files -z`.split("\x0").reject { |f|
- # f.match(%r{^\.git|^(test|spec|features|bin|tool)/|^[A-Z]\w+file$|/extlibs$|\.(gemspec|java)$|jar})
- # }
+ # for ruby core repository. It was generated by `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
s.files = [
- "CONTRIBUTING.md", "LICENSE", "README.md", "ext/psych/depend",
- "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
- "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h",
- "ext/psych/psych_parser.c", "ext/psych/psych_parser.h",
- "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h",
- "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h",
- "lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb",
- "lib/psych/core_ext.rb", "lib/psych/exception.rb", "lib/psych/handler.rb",
- "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb",
- "lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb",
- "lib/psych/json/tree_builder.rb", "lib/psych/json/yaml_events.rb",
- "lib/psych/nodes.rb", "lib/psych/nodes/alias.rb",
- "lib/psych/nodes/document.rb", "lib/psych/nodes/mapping.rb",
- "lib/psych/nodes/node.rb", "lib/psych/nodes/scalar.rb",
- "lib/psych/nodes/sequence.rb", "lib/psych/nodes/stream.rb",
- "lib/psych/omap.rb", "lib/psych/parser.rb", "lib/psych/scalar_scanner.rb",
- "lib/psych/set.rb", "lib/psych/stream.rb", "lib/psych/streaming.rb",
- "lib/psych/syntax_error.rb", "lib/psych/tree_builder.rb",
- "lib/psych/versions.rb", "lib/psych/visitors.rb",
- "lib/psych/visitors/depth_first.rb", "lib/psych/visitors/emitter.rb",
- "lib/psych/visitors/json_tree.rb", "lib/psych/visitors/to_ruby.rb",
- "lib/psych/visitors/visitor.rb", "lib/psych/visitors/yaml_tree.rb",
- "lib/psych/y.rb"
+ ".gitignore", "Gemfile", "LICENSE", "Mavenfile", "README.md", "Rakefile", "bin/console",
+ "bin/setup", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
+ "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h",
+ "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h",
+ "lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb", "lib/psych/core_ext.rb", "lib/psych/exception.rb",
+ "lib/psych/handler.rb", "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb",
+ "lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb", "lib/psych/json/tree_builder.rb",
+ "lib/psych/json/yaml_events.rb", "lib/psych/nodes.rb", "lib/psych/nodes/alias.rb", "lib/psych/nodes/document.rb",
+ "lib/psych/nodes/mapping.rb", "lib/psych/nodes/node.rb", "lib/psych/nodes/scalar.rb", "lib/psych/nodes/sequence.rb",
+ "lib/psych/nodes/stream.rb", "lib/psych/omap.rb", "lib/psych/parser.rb", "lib/psych/scalar_scanner.rb",
+ "lib/psych/set.rb", "lib/psych/stream.rb", "lib/psych/streaming.rb", "lib/psych/syntax_error.rb",
+ "lib/psych/tree_builder.rb", "lib/psych/versions.rb", "lib/psych/visitors.rb","lib/psych/visitors/depth_first.rb",
+ "lib/psych/visitors/emitter.rb", "lib/psych/visitors/json_tree.rb", "lib/psych/visitors/to_ruby.rb",
+ "lib/psych/visitors/visitor.rb", "lib/psych/visitors/yaml_tree.rb", "lib/psych/y.rb", "psych.gemspec"
]
s.rdoc_options = ["--main", "README.md"]
s.extra_rdoc_files = ["README.md"]
- s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
+ s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
s.required_rubygems_version = Gem::Requirement.new(">= 0")
if RUBY_ENGINE == 'jruby'
@@ -65,16 +52,15 @@ DESCRIPTION
"ext/java/org/jruby/ext/psych/PsychLibrary.java",
"ext/java/org/jruby/ext/psych/PsychParser.java",
"ext/java/org/jruby/ext/psych/PsychToRuby.java",
+ "ext/java/org/jruby/ext/psych/PsychYamlTree.java",
"lib/psych_jars.rb",
"lib/psych.jar"
]
- s.requirements = "jar org.snakeyaml:snakeyaml-engine, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
+ s.requirements = "jar org.yaml:snakeyaml, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
s.add_dependency 'jar-dependencies', '>= 0.1.7'
else
s.extensions = ["ext/psych/extconf.rb"]
s.add_dependency 'stringio'
end
- s.metadata['msys2_mingw_dependencies'] = 'libyaml'
-
end
diff --git a/ext/pty/depend b/ext/pty/depend
index d4d0d558ef..f251caae3f 100644
--- a/ext/pty/depend
+++ b/ext/pty/depend
@@ -53,7 +53,6 @@ pty.o: $(hdrdir)/ruby/internal/attr/noexcept.h
pty.o: $(hdrdir)/ruby/internal/attr/noinline.h
pty.o: $(hdrdir)/ruby/internal/attr/nonnull.h
pty.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-pty.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
pty.o: $(hdrdir)/ruby/internal/attr/pure.h
pty.o: $(hdrdir)/ruby/internal/attr/restrict.h
pty.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ pty.o: $(hdrdir)/ruby/internal/intern/enumerator.h
pty.o: $(hdrdir)/ruby/internal/intern/error.h
pty.o: $(hdrdir)/ruby/internal/intern/eval.h
pty.o: $(hdrdir)/ruby/internal/intern/file.h
+pty.o: $(hdrdir)/ruby/internal/intern/gc.h
pty.o: $(hdrdir)/ruby/internal/intern/hash.h
pty.o: $(hdrdir)/ruby/internal/intern/io.h
pty.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ pty.o: $(hdrdir)/ruby/internal/memory.h
pty.o: $(hdrdir)/ruby/internal/method.h
pty.o: $(hdrdir)/ruby/internal/module.h
pty.o: $(hdrdir)/ruby/internal/newobj.h
+pty.o: $(hdrdir)/ruby/internal/rgengc.h
pty.o: $(hdrdir)/ruby/internal/scan_args.h
pty.o: $(hdrdir)/ruby/internal/special_consts.h
pty.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 8dca8ba281..acec33f9bf 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -448,10 +448,8 @@ pty_close_pty(VALUE assoc)
for (i = 0; i < 2; i++) {
io = rb_ary_entry(assoc, i);
- if (RB_TYPE_P(io, T_FILE)) {
- /* it's OK to call rb_io_close again even if it's already closed */
+ if (RB_TYPE_P(io, T_FILE) && 0 <= RFILE(io)->fptr->fd)
rb_io_close(io);
- }
}
return Qnil;
}
@@ -501,21 +499,28 @@ pty_open(VALUE klass)
{
int master_fd, slave_fd;
char slavename[DEVICELEN];
+ VALUE master_io, slave_file;
+ rb_io_t *master_fptr, *slave_fptr;
+ VALUE assoc;
getDevice(&master_fd, &slave_fd, slavename, 1);
- VALUE master_path = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename));
- VALUE master_io = rb_io_open_descriptor(rb_cIO, master_fd, FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX, master_path, RUBY_IO_TIMEOUT_DEFAULT, NULL);
-
- VALUE slave_path = rb_obj_freeze(rb_str_new_cstr(slavename));
- VALUE slave_file = rb_io_open_descriptor(rb_cFile, slave_fd, FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY, slave_path, RUBY_IO_TIMEOUT_DEFAULT, NULL);
+ master_io = rb_obj_alloc(rb_cIO);
+ MakeOpenFile(master_io, master_fptr);
+ master_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX;
+ master_fptr->fd = master_fd;
+ master_fptr->pathv = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename));
- VALUE assoc = rb_assoc_new(master_io, slave_file);
+ slave_file = rb_obj_alloc(rb_cFile);
+ MakeOpenFile(slave_file, slave_fptr);
+ slave_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY;
+ slave_fptr->fd = slave_fd;
+ slave_fptr->pathv = rb_obj_freeze(rb_str_new_cstr(slavename));
+ assoc = rb_assoc_new(master_io, slave_file);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, assoc, pty_close_pty, assoc);
}
-
return assoc;
}
@@ -572,27 +577,30 @@ pty_getpty(int argc, VALUE *argv, VALUE self)
{
VALUE res;
struct pty_info info;
+ rb_io_t *wfptr,*rfptr;
+ VALUE rport = rb_obj_alloc(rb_cFile);
+ VALUE wport = rb_obj_alloc(rb_cFile);
char SlaveName[DEVICELEN];
+ MakeOpenFile(rport, rfptr);
+ MakeOpenFile(wport, wfptr);
+
establishShell(argc, argv, &info, SlaveName);
- VALUE pty_path = rb_obj_freeze(rb_str_new_cstr(SlaveName));
- VALUE rport = rb_io_open_descriptor(
- rb_cFile, info.fd, FMODE_READABLE, pty_path, RUBY_IO_TIMEOUT_DEFAULT, NULL
- );
+ rfptr->mode = rb_io_modestr_fmode("r");
+ rfptr->fd = info.fd;
+ rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName));
- int wpty_fd = rb_cloexec_dup(info.fd);
- if (wpty_fd == -1) {
+ wfptr->mode = rb_io_modestr_fmode("w") | FMODE_SYNC;
+ wfptr->fd = rb_cloexec_dup(info.fd);
+ if (wfptr->fd == -1)
rb_sys_fail("dup()");
- }
- VALUE wport = rb_io_open_descriptor(
- rb_cFile, wpty_fd, FMODE_WRITABLE | FMODE_TRUNC | FMODE_CREATE | FMODE_SYNC,
- pty_path, RUBY_IO_TIMEOUT_DEFAULT, NULL
- );
+ rb_update_max_fd(wfptr->fd);
+ wfptr->pathv = rfptr->pathv;
res = rb_ary_new2(3);
- rb_ary_store(res, 0, rport);
- rb_ary_store(res, 1, wport);
+ rb_ary_store(res,0,(VALUE)rport);
+ rb_ary_store(res,1,(VALUE)wport);
rb_ary_store(res,2,PIDT2NUM(info.child_pid));
if (rb_block_given_p()) {
@@ -745,13 +753,8 @@ void
Init_pty(void)
{
cPTY = rb_define_module("PTY");
-#if 1
- rb_define_module_function(cPTY,"get""pty",pty_getpty,-1);
-#else /* for RDoc */
- /* show getpty as an alias of spawn */
- VALUE sPTY = rb_singleton_class(cPTY);
- rb_define_alias(sPTY, "getpty", "spawn");
-#endif
+ /* :nodoc: */
+ rb_define_module_function(cPTY,"getpty",pty_getpty,-1);
rb_define_module_function(cPTY,"spawn",pty_getpty,-1);
rb_define_singleton_method(cPTY,"check",pty_check,-1);
rb_define_singleton_method(cPTY,"open",pty_open,0);
diff --git a/ext/racc/cparse/README b/ext/racc/cparse/README
new file mode 100644
index 0000000000..550e8d49fe
--- /dev/null
+++ b/ext/racc/cparse/README
@@ -0,0 +1,11 @@
+Racc Runtime README
+===================
+
+This directory contains a runtime library of
+Racc parser generator. If you want to generate
+your own parser, you must get Racc full package.
+Get it from:
+
+ - http://i.loveruby.net/en/projects/racc
+ - https://github.com/ruby/racc
+
diff --git a/ext/racc/cparse/cparse.c b/ext/racc/cparse/cparse.c
new file mode 100644
index 0000000000..f752eb7749
--- /dev/null
+++ b/ext/racc/cparse/cparse.c
@@ -0,0 +1,861 @@
+/*
+
+ cparse.c -- Racc Runtime Core
+
+ Copyright (c) 1999-2006 Minero Aoki
+
+ This library is free software.
+ You can distribute/modify this program under the same terms of ruby.
+
+*/
+
+#include <ruby.h>
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/* -----------------------------------------------------------------------
+ Important Constants
+----------------------------------------------------------------------- */
+
+#define RACC_VERSION "1.6.2"
+
+#define DEFAULT_TOKEN -1
+#define ERROR_TOKEN 1
+#define FINAL_TOKEN 0
+
+#define vDEFAULT_TOKEN INT2FIX(DEFAULT_TOKEN)
+#define vERROR_TOKEN INT2FIX(ERROR_TOKEN)
+#define vFINAL_TOKEN INT2FIX(FINAL_TOKEN)
+
+/* -----------------------------------------------------------------------
+ File Local Variables
+----------------------------------------------------------------------- */
+
+static VALUE RaccBug;
+static VALUE CparseParams;
+
+static ID id_yydebug;
+static ID id_nexttoken;
+static ID id_onerror;
+static ID id_noreduce;
+static ID id_errstatus;
+
+static ID id_d_shift;
+static ID id_d_reduce;
+static ID id_d_accept;
+static ID id_d_read_token;
+static ID id_d_next_state;
+static ID id_d_e_pop;
+
+/* -----------------------------------------------------------------------
+ Utils
+----------------------------------------------------------------------- */
+
+/* For backward compatibility */
+#ifndef ID2SYM
+# define ID2SYM(i) ULONG2NUM(i)
+#endif
+#ifndef SYM2ID
+# define SYM2ID(v) ((ID)NUM2ULONG(v))
+#endif
+#ifndef SYMBOL_P
+# define SYMBOL_P(v) FIXNUM_P(v)
+#endif
+#ifndef LONG2NUM
+# define LONG2NUM(i) INT2NUM(i)
+#endif
+
+#ifndef HAVE_RB_ARY_SUBSEQ
+# define rb_ary_subseq(ary, beg, len) rb_ary_new4(len, RARRAY_PTR(ary) + beg)
+#endif
+
+static ID value_to_id _((VALUE v));
+static inline long num_to_long _((VALUE n));
+
+static ID
+value_to_id(VALUE v)
+{
+ if (! SYMBOL_P(v)) {
+ rb_raise(rb_eTypeError, "not symbol");
+ }
+ return SYM2ID(v);
+}
+
+static inline long
+num_to_long(VALUE n)
+{
+ return NUM2LONG(n);
+}
+
+#define AREF(s, idx) \
+ ((0 <= idx && idx < RARRAY_LEN(s)) ? rb_ary_entry(s, idx) : Qnil)
+
+/* -----------------------------------------------------------------------
+ Parser Stack Interfaces
+----------------------------------------------------------------------- */
+
+static VALUE get_stack_tail _((VALUE stack, long len));
+static void cut_stack_tail _((VALUE stack, long len));
+
+static VALUE
+get_stack_tail(VALUE stack, long len)
+{
+ if (len < 0) return Qnil; /* system error */
+ if (len > RARRAY_LEN(stack)) len = RARRAY_LEN(stack);
+ return rb_ary_subseq(stack, RARRAY_LEN(stack) - len, len);
+}
+
+static void
+cut_stack_tail(VALUE stack, long len)
+{
+ while (len > 0) {
+ rb_ary_pop(stack);
+ len--;
+ }
+}
+
+#define STACK_INIT_LEN 64
+#define NEW_STACK() rb_ary_new2(STACK_INIT_LEN)
+#define PUSH(s, i) rb_ary_store(s, RARRAY_LEN(s), i)
+#define POP(s) rb_ary_pop(s)
+#define LAST_I(s) \
+ ((RARRAY_LEN(s) > 0) ? rb_ary_entry(s, RARRAY_LEN(s) - 1) : Qnil)
+#define GET_TAIL(s, len) get_stack_tail(s, len)
+#define CUT_TAIL(s, len) cut_stack_tail(s, len)
+
+/* -----------------------------------------------------------------------
+ struct cparse_params
+----------------------------------------------------------------------- */
+
+struct cparse_params {
+ VALUE value_v; /* VALUE version of this struct */
+
+ VALUE parser; /* parser object */
+
+ int lex_is_iterator;
+ VALUE lexer; /* scanner object */
+ ID lexmid; /* name of scanner method (must be an iterator) */
+
+ /* State transition tables (immutable)
+ Data structure is from Dragon Book 4.9 */
+ /* action table */
+ VALUE action_table;
+ VALUE action_check;
+ VALUE action_default;
+ VALUE action_pointer;
+ /* goto table */
+ VALUE goto_table;
+ VALUE goto_check;
+ VALUE goto_default;
+ VALUE goto_pointer;
+
+ long nt_base; /* NonTerminal BASE index */
+ VALUE reduce_table; /* reduce data table */
+ VALUE token_table; /* token conversion table */
+
+ /* parser stacks and parameters */
+ VALUE state;
+ long curstate;
+ VALUE vstack;
+ VALUE tstack;
+ VALUE t;
+ long shift_n;
+ long reduce_n;
+ long ruleno;
+
+ long errstatus; /* nonzero in error recovering mode */
+ long nerr; /* number of error */
+
+ int use_result_var;
+
+ VALUE retval; /* return value of parser routine */
+ long fin; /* parse result status */
+#define CP_FIN_ACCEPT 1
+#define CP_FIN_EOT 2
+#define CP_FIN_CANTPOP 3
+
+ int debug; /* user level debug */
+ int sys_debug; /* system level debug */
+
+ long i; /* table index */
+};
+
+/* -----------------------------------------------------------------------
+ Parser Main Routines
+----------------------------------------------------------------------- */
+
+static VALUE racc_cparse _((VALUE parser, VALUE arg, VALUE sysdebug));
+static VALUE racc_yyparse _((VALUE parser, VALUE lexer, VALUE lexmid,
+ VALUE arg, VALUE sysdebug));
+
+static void call_lexer _((struct cparse_params *v));
+static VALUE lexer_i _((RB_BLOCK_CALL_FUNC_ARGLIST(block_args, data)));
+
+static VALUE assert_array _((VALUE a));
+static long assert_integer _((VALUE n));
+static VALUE assert_hash _((VALUE h));
+static VALUE initialize_params _((VALUE vparams, VALUE parser, VALUE arg,
+ VALUE lexer, VALUE lexmid));
+static void cparse_params_mark _((void *ptr));
+static size_t cparse_params_memsize _((const void *ptr));
+
+static void parse_main _((struct cparse_params *v,
+ VALUE tok, VALUE val, int resume));
+static void extract_user_token _((struct cparse_params *v,
+ VALUE block_args, VALUE *tok, VALUE *val));
+static void shift _((struct cparse_params* v, long act, VALUE tok, VALUE val));
+static int reduce _((struct cparse_params* v, long act));
+static rb_block_call_func reduce0;
+
+#ifdef DEBUG
+# define D_puts(msg) if (v->sys_debug) puts(msg)
+# define D_printf(fmt,arg) if (v->sys_debug) printf(fmt,arg)
+#else
+# define D_puts(msg)
+# define D_printf(fmt,arg)
+#endif
+
+#undef RUBY_UNTYPED_DATA_WARNING
+#define RUBY_UNTYPED_DATA_WARNING 1
+
+static const rb_data_type_t cparse_params_type = {
+ "racc/cparse",
+ {
+ cparse_params_mark,
+ RUBY_TYPED_DEFAULT_FREE,
+ cparse_params_memsize,
+ },
+#ifdef RUBY_TYPED_FREE_IMMEDIATELY
+ 0, 0,
+ RUBY_TYPED_FREE_IMMEDIATELY,
+#endif
+};
+
+static VALUE
+racc_cparse(VALUE parser, VALUE arg, VALUE sysdebug)
+{
+ VALUE vparams;
+ struct cparse_params *v;
+
+ vparams = TypedData_Make_Struct(CparseParams, struct cparse_params,
+ &cparse_params_type, v);
+ D_puts("starting cparse");
+ v->sys_debug = RTEST(sysdebug);
+ vparams = initialize_params(vparams, parser, arg, Qnil, Qnil);
+ v->lex_is_iterator = FALSE;
+ parse_main(v, Qnil, Qnil, 0);
+
+ RB_GC_GUARD(vparams);
+ return v->retval;
+}
+
+static VALUE
+racc_yyparse(VALUE parser, VALUE lexer, VALUE lexmid, VALUE arg, VALUE sysdebug)
+{
+ VALUE vparams;
+ struct cparse_params *v;
+
+ vparams = TypedData_Make_Struct(CparseParams, struct cparse_params,
+ &cparse_params_type, v);
+ v->sys_debug = RTEST(sysdebug);
+ D_puts("start C yyparse");
+ vparams = initialize_params(vparams, parser, arg, lexer, lexmid);
+ v->lex_is_iterator = TRUE;
+ D_puts("params initialized");
+ parse_main(v, Qnil, Qnil, 0);
+ call_lexer(v);
+ if (!v->fin) {
+ rb_raise(rb_eArgError, "%s() is finished before EndOfToken",
+ rb_id2name(v->lexmid));
+ }
+
+ RB_GC_GUARD(vparams);
+ return v->retval;
+}
+
+#ifdef HAVE_RB_BLOCK_CALL
+static void
+call_lexer(struct cparse_params *v)
+{
+ rb_block_call(v->lexer, v->lexmid, 0, NULL, lexer_i, v->value_v);
+}
+#else
+static VALUE
+lexer_iter(VALUE data)
+{
+ struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type);
+
+ rb_funcall(v->lexer, v->lexmid, 0);
+ return Qnil;
+}
+
+static void
+call_lexer(struct cparse_params *v)
+{
+ rb_iterate(lexer_iter, v->value_v, lexer_i, v->value_v);
+}
+#endif
+
+static VALUE
+lexer_i(RB_BLOCK_CALL_FUNC_ARGLIST(block_args, data))
+{
+ struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type);
+ VALUE tok, val;
+
+ if (v->fin)
+ rb_raise(rb_eArgError, "extra token after EndOfToken");
+ extract_user_token(v, block_args, &tok, &val);
+ parse_main(v, tok, val, 1);
+ if (v->fin && v->fin != CP_FIN_ACCEPT)
+ rb_iter_break();
+ return Qnil;
+}
+
+static VALUE
+assert_array(VALUE a)
+{
+ Check_Type(a, T_ARRAY);
+ return a;
+}
+
+static VALUE
+assert_hash(VALUE h)
+{
+ Check_Type(h, T_HASH);
+ return h;
+}
+
+static long
+assert_integer(VALUE n)
+{
+ return NUM2LONG(n);
+}
+
+static VALUE
+initialize_params(VALUE vparams, VALUE parser, VALUE arg, VALUE lexer, VALUE lexmid)
+{
+ struct cparse_params *v = rb_check_typeddata(vparams, &cparse_params_type);
+
+ v->value_v = vparams;
+ v->parser = parser;
+ v->lexer = lexer;
+ if (! NIL_P(lexmid))
+ v->lexmid = value_to_id(lexmid);
+
+ v->debug = RTEST(rb_ivar_get(parser, id_yydebug));
+
+ Check_Type(arg, T_ARRAY);
+ if (!(13 <= RARRAY_LEN(arg) && RARRAY_LEN(arg) <= 14))
+ rb_raise(RaccBug, "[Racc Bug] wrong arg.size %ld", RARRAY_LEN(arg));
+ v->action_table = assert_array (rb_ary_entry(arg, 0));
+ v->action_check = assert_array (rb_ary_entry(arg, 1));
+ v->action_default = assert_array (rb_ary_entry(arg, 2));
+ v->action_pointer = assert_array (rb_ary_entry(arg, 3));
+ v->goto_table = assert_array (rb_ary_entry(arg, 4));
+ v->goto_check = assert_array (rb_ary_entry(arg, 5));
+ v->goto_default = assert_array (rb_ary_entry(arg, 6));
+ v->goto_pointer = assert_array (rb_ary_entry(arg, 7));
+ v->nt_base = assert_integer(rb_ary_entry(arg, 8));
+ v->reduce_table = assert_array (rb_ary_entry(arg, 9));
+ v->token_table = assert_hash (rb_ary_entry(arg, 10));
+ v->shift_n = assert_integer(rb_ary_entry(arg, 11));
+ v->reduce_n = assert_integer(rb_ary_entry(arg, 12));
+ if (RARRAY_LEN(arg) > 13) {
+ v->use_result_var = RTEST(rb_ary_entry(arg, 13));
+ }
+ else {
+ v->use_result_var = TRUE;
+ }
+
+ v->tstack = v->debug ? NEW_STACK() : Qnil;
+ v->vstack = NEW_STACK();
+ v->state = NEW_STACK();
+ v->curstate = 0;
+ PUSH(v->state, INT2FIX(0));
+ v->t = INT2FIX(FINAL_TOKEN + 1); /* must not init to FINAL_TOKEN */
+ v->nerr = 0;
+ v->errstatus = 0;
+ rb_ivar_set(parser, id_errstatus, LONG2NUM(v->errstatus));
+
+ v->retval = Qnil;
+ v->fin = 0;
+
+ v->lex_is_iterator = FALSE;
+
+ rb_iv_set(parser, "@vstack", v->vstack);
+ if (v->debug) {
+ rb_iv_set(parser, "@tstack", v->tstack);
+ }
+ else {
+ rb_iv_set(parser, "@tstack", Qnil);
+ }
+
+ return vparams;
+}
+
+static void
+cparse_params_mark(void *ptr)
+{
+ struct cparse_params *v = (struct cparse_params*)ptr;
+
+ rb_gc_mark(v->value_v);
+ rb_gc_mark(v->parser);
+ rb_gc_mark(v->lexer);
+ rb_gc_mark(v->action_table);
+ rb_gc_mark(v->action_check);
+ rb_gc_mark(v->action_default);
+ rb_gc_mark(v->action_pointer);
+ rb_gc_mark(v->goto_table);
+ rb_gc_mark(v->goto_check);
+ rb_gc_mark(v->goto_default);
+ rb_gc_mark(v->goto_pointer);
+ rb_gc_mark(v->reduce_table);
+ rb_gc_mark(v->token_table);
+ rb_gc_mark(v->state);
+ rb_gc_mark(v->vstack);
+ rb_gc_mark(v->tstack);
+ rb_gc_mark(v->t);
+ rb_gc_mark(v->retval);
+}
+
+static size_t
+cparse_params_memsize(const void *ptr)
+{
+ return sizeof(struct cparse_params);
+}
+
+static void
+extract_user_token(struct cparse_params *v, VALUE block_args,
+ VALUE *tok, VALUE *val)
+{
+ if (NIL_P(block_args)) {
+ /* EOF */
+ *tok = Qfalse;
+ *val = rb_str_new("$", 1);
+ return;
+ }
+
+ if (!RB_TYPE_P(block_args, T_ARRAY)) {
+ rb_raise(rb_eTypeError,
+ "%s() %s %"PRIsVALUE" (must be Array[2])",
+ v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token",
+ v->lex_is_iterator ? "yielded" : "returned",
+ rb_obj_class(block_args));
+ }
+ if (RARRAY_LEN(block_args) != 2) {
+ rb_raise(rb_eArgError,
+ "%s() %s wrong size of array (%ld for 2)",
+ v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token",
+ v->lex_is_iterator ? "yielded" : "returned",
+ RARRAY_LEN(block_args));
+ }
+ *tok = AREF(block_args, 0);
+ *val = AREF(block_args, 1);
+}
+
+#define SHIFT(v,act,tok,val) shift(v,act,tok,val)
+#define REDUCE(v,act) do {\
+ switch (reduce(v,act)) { \
+ case 0: /* normal */ \
+ break; \
+ case 1: /* yyerror */ \
+ goto user_yyerror; \
+ case 2: /* yyaccept */ \
+ D_puts("u accept"); \
+ goto accept; \
+ default: \
+ break; \
+ } \
+} while (0)
+
+static void
+parse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume)
+{
+ long i; /* table index */
+ long act; /* action type */
+ VALUE act_value; /* action type, VALUE version */
+ int read_next = 1; /* true if we need to read next token */
+ VALUE tmp;
+
+ if (resume)
+ goto resume;
+
+ while (1) {
+ D_puts("");
+ D_puts("---- enter new loop ----");
+ D_puts("");
+
+ D_printf("(act) k1=%ld\n", v->curstate);
+ tmp = AREF(v->action_pointer, v->curstate);
+ if (NIL_P(tmp)) goto notfound;
+ D_puts("(act) pointer[k1] ok");
+ i = NUM2LONG(tmp);
+
+ D_printf("read_next=%d\n", read_next);
+ if (read_next && (v->t != vFINAL_TOKEN)) {
+ if (v->lex_is_iterator) {
+ D_puts("resuming...");
+ if (v->fin) rb_raise(rb_eArgError, "token given after EOF");
+ v->i = i; /* save i */
+ return;
+ resume:
+ D_puts("resumed");
+ i = v->i; /* load i */
+ }
+ else {
+ D_puts("next_token");
+ tmp = rb_funcall(v->parser, id_nexttoken, 0);
+ extract_user_token(v, tmp, &tok, &val);
+ }
+ /* convert token */
+ v->t = rb_hash_aref(v->token_table, tok);
+ if (NIL_P(v->t)) {
+ v->t = vERROR_TOKEN;
+ }
+ D_printf("(act) t(k2)=%ld\n", NUM2LONG(v->t));
+ if (v->debug) {
+ rb_funcall(v->parser, id_d_read_token,
+ 3, v->t, tok, val);
+ }
+ }
+ read_next = 0;
+
+ i += NUM2LONG(v->t);
+ D_printf("(act) i=%ld\n", i);
+ if (i < 0) goto notfound;
+
+ act_value = AREF(v->action_table, i);
+ if (NIL_P(act_value)) goto notfound;
+ act = NUM2LONG(act_value);
+ D_printf("(act) table[i]=%ld\n", act);
+
+ tmp = AREF(v->action_check, i);
+ if (NIL_P(tmp)) goto notfound;
+ if (NUM2LONG(tmp) != v->curstate) goto notfound;
+ D_printf("(act) check[i]=%ld\n", NUM2LONG(tmp));
+
+ D_puts("(act) found");
+ act_fixed:
+ D_printf("act=%ld\n", act);
+ goto handle_act;
+
+ notfound:
+ D_puts("(act) not found: use default");
+ act_value = AREF(v->action_default, v->curstate);
+ act = NUM2LONG(act_value);
+ goto act_fixed;
+
+
+ handle_act:
+ if (act > 0 && act < v->shift_n) {
+ D_puts("shift");
+ if (v->errstatus > 0) {
+ v->errstatus--;
+ rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus));
+ }
+ SHIFT(v, act, v->t, val);
+ read_next = 1;
+ }
+ else if (act < 0 && act > -(v->reduce_n)) {
+ D_puts("reduce");
+ REDUCE(v, act);
+ }
+ else if (act == -(v->reduce_n)) {
+ goto error;
+ error_recovered:
+ ; /* goto label requires stmt */
+ }
+ else if (act == v->shift_n) {
+ D_puts("accept");
+ goto accept;
+ }
+ else {
+ rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act);
+ }
+
+ if (v->debug) {
+ rb_funcall(v->parser, id_d_next_state,
+ 2, LONG2NUM(v->curstate), v->state);
+ }
+ }
+ /* not reach */
+
+
+ accept:
+ if (v->debug) rb_funcall(v->parser, id_d_accept, 0);
+ v->retval = rb_ary_entry(v->vstack, 0);
+ v->fin = CP_FIN_ACCEPT;
+ return;
+
+
+ error:
+ D_printf("error detected, status=%ld\n", v->errstatus);
+ if (v->errstatus == 0) {
+ v->nerr++;
+ rb_funcall(v->parser, id_onerror,
+ 3, v->t, val, v->vstack);
+ }
+ user_yyerror:
+ if (v->errstatus == 3) {
+ if (v->t == vFINAL_TOKEN) {
+ v->retval = Qnil;
+ v->fin = CP_FIN_EOT;
+ return;
+ }
+ read_next = 1;
+ }
+ v->errstatus = 3;
+ rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus));
+
+ /* check if we can shift/reduce error token */
+ D_printf("(err) k1=%ld\n", v->curstate);
+ D_printf("(err) k2=%d (error)\n", ERROR_TOKEN);
+ while (1) {
+ tmp = AREF(v->action_pointer, v->curstate);
+ if (NIL_P(tmp)) goto error_pop;
+ D_puts("(err) pointer[k1] ok");
+
+ i = NUM2LONG(tmp) + ERROR_TOKEN;
+ D_printf("(err) i=%ld\n", i);
+ if (i < 0) goto error_pop;
+
+ act_value = AREF(v->action_table, i);
+ if (NIL_P(act_value)) {
+ D_puts("(err) table[i] == nil");
+ goto error_pop;
+ }
+ act = NUM2LONG(act_value);
+ D_printf("(err) table[i]=%ld\n", act);
+
+ tmp = AREF(v->action_check, i);
+ if (NIL_P(tmp)) {
+ D_puts("(err) check[i] == nil");
+ goto error_pop;
+ }
+ if (NUM2LONG(tmp) != v->curstate) {
+ D_puts("(err) check[i] != k1");
+ goto error_pop;
+ }
+
+ D_puts("(err) found: can handle error token");
+ break;
+
+ error_pop:
+ D_puts("(err) act not found: can't handle error token; pop");
+
+ if (RARRAY_LEN(v->state) <= 1) {
+ v->retval = Qnil;
+ v->fin = CP_FIN_CANTPOP;
+ return;
+ }
+ POP(v->state);
+ POP(v->vstack);
+ v->curstate = num_to_long(LAST_I(v->state));
+ if (v->debug) {
+ POP(v->tstack);
+ rb_funcall(v->parser, id_d_e_pop,
+ 3, v->state, v->tstack, v->vstack);
+ }
+ }
+
+ /* shift/reduce error token */
+ if (act > 0 && act < v->shift_n) {
+ D_puts("e shift");
+ SHIFT(v, act, ERROR_TOKEN, val);
+ }
+ else if (act < 0 && act > -(v->reduce_n)) {
+ D_puts("e reduce");
+ REDUCE(v, act);
+ }
+ else if (act == v->shift_n) {
+ D_puts("e accept");
+ goto accept;
+ }
+ else {
+ rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act);
+ }
+ goto error_recovered;
+}
+
+static void
+shift(struct cparse_params *v, long act, VALUE tok, VALUE val)
+{
+ PUSH(v->vstack, val);
+ if (v->debug) {
+ PUSH(v->tstack, tok);
+ rb_funcall(v->parser, id_d_shift,
+ 3, tok, v->tstack, v->vstack);
+ }
+ v->curstate = act;
+ PUSH(v->state, LONG2NUM(v->curstate));
+}
+
+static int
+reduce(struct cparse_params *v, long act)
+{
+ VALUE code;
+ v->ruleno = -act * 3;
+ code = rb_catch("racc_jump", reduce0, v->value_v);
+ v->errstatus = num_to_long(rb_ivar_get(v->parser, id_errstatus));
+ return NUM2INT(code);
+}
+
+static VALUE
+reduce0(RB_BLOCK_CALL_FUNC_ARGLIST(_, data))
+{
+ struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type);
+ VALUE reduce_to, reduce_len, method_id;
+ long len;
+ ID mid;
+ VALUE tmp, tmp_t = Qundef, tmp_v = Qundef;
+ long i, k1, k2;
+ VALUE goto_state;
+
+ reduce_len = rb_ary_entry(v->reduce_table, v->ruleno);
+ reduce_to = rb_ary_entry(v->reduce_table, v->ruleno+1);
+ method_id = rb_ary_entry(v->reduce_table, v->ruleno+2);
+ len = NUM2LONG(reduce_len);
+ mid = value_to_id(method_id);
+
+ /* call action */
+ if (len == 0) {
+ tmp = Qnil;
+ if (mid != id_noreduce)
+ tmp_v = rb_ary_new();
+ if (v->debug)
+ tmp_t = rb_ary_new();
+ }
+ else {
+ if (mid != id_noreduce) {
+ tmp_v = GET_TAIL(v->vstack, len);
+ tmp = rb_ary_entry(tmp_v, 0);
+ }
+ else {
+ tmp = rb_ary_entry(v->vstack, RARRAY_LEN(v->vstack) - len);
+ }
+ CUT_TAIL(v->vstack, len);
+ if (v->debug) {
+ tmp_t = GET_TAIL(v->tstack, len);
+ CUT_TAIL(v->tstack, len);
+ }
+ CUT_TAIL(v->state, len);
+ }
+ if (mid != id_noreduce) {
+ if (v->use_result_var) {
+ tmp = rb_funcall(v->parser, mid,
+ 3, tmp_v, v->vstack, tmp);
+ }
+ else {
+ tmp = rb_funcall(v->parser, mid,
+ 2, tmp_v, v->vstack);
+ }
+ }
+
+ /* then push result */
+ PUSH(v->vstack, tmp);
+ if (v->debug) {
+ PUSH(v->tstack, reduce_to);
+ rb_funcall(v->parser, id_d_reduce,
+ 4, tmp_t, reduce_to, v->tstack, v->vstack);
+ }
+
+ /* calculate transition state */
+ if (RARRAY_LEN(v->state) == 0)
+ rb_raise(RaccBug, "state stack unexpectedly empty");
+ k2 = num_to_long(LAST_I(v->state));
+ k1 = num_to_long(reduce_to) - v->nt_base;
+ D_printf("(goto) k1=%ld\n", k1);
+ D_printf("(goto) k2=%ld\n", k2);
+
+ tmp = AREF(v->goto_pointer, k1);
+ if (NIL_P(tmp)) goto notfound;
+
+ i = NUM2LONG(tmp) + k2;
+ D_printf("(goto) i=%ld\n", i);
+ if (i < 0) goto notfound;
+
+ goto_state = AREF(v->goto_table, i);
+ if (NIL_P(goto_state)) {
+ D_puts("(goto) table[i] == nil");
+ goto notfound;
+ }
+ D_printf("(goto) table[i]=%ld (goto_state)\n", NUM2LONG(goto_state));
+
+ tmp = AREF(v->goto_check, i);
+ if (NIL_P(tmp)) {
+ D_puts("(goto) check[i] == nil");
+ goto notfound;
+ }
+ if (tmp != LONG2NUM(k1)) {
+ D_puts("(goto) check[i] != table[i]");
+ goto notfound;
+ }
+ D_printf("(goto) check[i]=%ld\n", NUM2LONG(tmp));
+
+ D_puts("(goto) found");
+ transit:
+ PUSH(v->state, goto_state);
+ v->curstate = NUM2LONG(goto_state);
+ return INT2FIX(0);
+
+ notfound:
+ D_puts("(goto) not found: use default");
+ /* overwrite `goto-state' by default value */
+ goto_state = AREF(v->goto_default, k1);
+ goto transit;
+}
+
+/* -----------------------------------------------------------------------
+ Ruby Interface
+----------------------------------------------------------------------- */
+
+void
+Init_cparse(void)
+{
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+ rb_ext_ractor_safe(true);
+#endif
+
+ VALUE Racc, Parser;
+ ID id_racc = rb_intern_const("Racc");
+
+ if (rb_const_defined(rb_cObject, id_racc)) {
+ Racc = rb_const_get(rb_cObject, id_racc);
+ Parser = rb_const_get_at(Racc, rb_intern_const("Parser"));
+ }
+ else {
+ Racc = rb_define_module("Racc");
+ Parser = rb_define_class_under(Racc, "Parser", rb_cObject);
+ }
+ rb_define_private_method(Parser, "_racc_do_parse_c", racc_cparse, 2);
+ rb_define_private_method(Parser, "_racc_yyparse_c", racc_yyparse, 4);
+ rb_define_const(Parser, "Racc_Runtime_Core_Version_C",
+ rb_str_new2(RACC_VERSION));
+ rb_define_const(Parser, "Racc_Runtime_Core_Id_C",
+ rb_str_new2("$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $"));
+
+ CparseParams = rb_define_class_under(Racc, "CparseParams", rb_cObject);
+ rb_undef_alloc_func(CparseParams);
+ rb_undef_method(CparseParams, "initialize");
+ rb_undef_method(CparseParams, "initialize_copy");
+
+ RaccBug = rb_eRuntimeError;
+
+ id_yydebug = rb_intern_const("@yydebug");
+ id_nexttoken = rb_intern_const("next_token");
+ id_onerror = rb_intern_const("on_error");
+ id_noreduce = rb_intern_const("_reduce_none");
+ id_errstatus = rb_intern_const("@racc_error_status");
+
+ id_d_shift = rb_intern_const("racc_shift");
+ id_d_reduce = rb_intern_const("racc_reduce");
+ id_d_accept = rb_intern_const("racc_accept");
+ id_d_read_token = rb_intern_const("racc_read_token");
+ id_d_next_state = rb_intern_const("racc_next_state");
+ id_d_e_pop = rb_intern_const("racc_e_pop");
+}
diff --git a/ext/racc/cparse/depend b/ext/racc/cparse/depend
new file mode 100644
index 0000000000..9dc509dc7c
--- /dev/null
+++ b/ext/racc/cparse/depend
@@ -0,0 +1,162 @@
+# AUTOGENERATED DEPENDENCIES START
+cparse.o: $(RUBY_EXTCONF_H)
+cparse.o: $(arch_hdrdir)/ruby/config.h
+cparse.o: $(hdrdir)/ruby.h
+cparse.o: $(hdrdir)/ruby/assert.h
+cparse.o: $(hdrdir)/ruby/backward.h
+cparse.o: $(hdrdir)/ruby/backward/2/assume.h
+cparse.o: $(hdrdir)/ruby/backward/2/attributes.h
+cparse.o: $(hdrdir)/ruby/backward/2/bool.h
+cparse.o: $(hdrdir)/ruby/backward/2/inttypes.h
+cparse.o: $(hdrdir)/ruby/backward/2/limits.h
+cparse.o: $(hdrdir)/ruby/backward/2/long_long.h
+cparse.o: $(hdrdir)/ruby/backward/2/stdalign.h
+cparse.o: $(hdrdir)/ruby/backward/2/stdarg.h
+cparse.o: $(hdrdir)/ruby/defines.h
+cparse.o: $(hdrdir)/ruby/intern.h
+cparse.o: $(hdrdir)/ruby/internal/abi.h
+cparse.o: $(hdrdir)/ruby/internal/anyargs.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+cparse.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+cparse.o: $(hdrdir)/ruby/internal/assume.h
+cparse.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+cparse.o: $(hdrdir)/ruby/internal/attr/artificial.h
+cparse.o: $(hdrdir)/ruby/internal/attr/cold.h
+cparse.o: $(hdrdir)/ruby/internal/attr/const.h
+cparse.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+cparse.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+cparse.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+cparse.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+cparse.o: $(hdrdir)/ruby/internal/attr/error.h
+cparse.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+cparse.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+cparse.o: $(hdrdir)/ruby/internal/attr/format.h
+cparse.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noalias.h
+cparse.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noinline.h
+cparse.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+cparse.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+cparse.o: $(hdrdir)/ruby/internal/attr/pure.h
+cparse.o: $(hdrdir)/ruby/internal/attr/restrict.h
+cparse.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+cparse.o: $(hdrdir)/ruby/internal/attr/warning.h
+cparse.o: $(hdrdir)/ruby/internal/attr/weakref.h
+cparse.o: $(hdrdir)/ruby/internal/cast.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+cparse.o: $(hdrdir)/ruby/internal/compiler_since.h
+cparse.o: $(hdrdir)/ruby/internal/config.h
+cparse.o: $(hdrdir)/ruby/internal/constant_p.h
+cparse.o: $(hdrdir)/ruby/internal/core.h
+cparse.o: $(hdrdir)/ruby/internal/core/rarray.h
+cparse.o: $(hdrdir)/ruby/internal/core/rbasic.h
+cparse.o: $(hdrdir)/ruby/internal/core/rbignum.h
+cparse.o: $(hdrdir)/ruby/internal/core/rclass.h
+cparse.o: $(hdrdir)/ruby/internal/core/rdata.h
+cparse.o: $(hdrdir)/ruby/internal/core/rfile.h
+cparse.o: $(hdrdir)/ruby/internal/core/rhash.h
+cparse.o: $(hdrdir)/ruby/internal/core/robject.h
+cparse.o: $(hdrdir)/ruby/internal/core/rregexp.h
+cparse.o: $(hdrdir)/ruby/internal/core/rstring.h
+cparse.o: $(hdrdir)/ruby/internal/core/rstruct.h
+cparse.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+cparse.o: $(hdrdir)/ruby/internal/ctype.h
+cparse.o: $(hdrdir)/ruby/internal/dllexport.h
+cparse.o: $(hdrdir)/ruby/internal/dosish.h
+cparse.o: $(hdrdir)/ruby/internal/error.h
+cparse.o: $(hdrdir)/ruby/internal/eval.h
+cparse.o: $(hdrdir)/ruby/internal/event.h
+cparse.o: $(hdrdir)/ruby/internal/fl_type.h
+cparse.o: $(hdrdir)/ruby/internal/gc.h
+cparse.o: $(hdrdir)/ruby/internal/glob.h
+cparse.o: $(hdrdir)/ruby/internal/globals.h
+cparse.o: $(hdrdir)/ruby/internal/has/attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/builtin.h
+cparse.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+cparse.o: $(hdrdir)/ruby/internal/has/extension.h
+cparse.o: $(hdrdir)/ruby/internal/has/feature.h
+cparse.o: $(hdrdir)/ruby/internal/has/warning.h
+cparse.o: $(hdrdir)/ruby/internal/intern/array.h
+cparse.o: $(hdrdir)/ruby/internal/intern/bignum.h
+cparse.o: $(hdrdir)/ruby/internal/intern/class.h
+cparse.o: $(hdrdir)/ruby/internal/intern/compar.h
+cparse.o: $(hdrdir)/ruby/internal/intern/complex.h
+cparse.o: $(hdrdir)/ruby/internal/intern/cont.h
+cparse.o: $(hdrdir)/ruby/internal/intern/dir.h
+cparse.o: $(hdrdir)/ruby/internal/intern/enum.h
+cparse.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+cparse.o: $(hdrdir)/ruby/internal/intern/error.h
+cparse.o: $(hdrdir)/ruby/internal/intern/eval.h
+cparse.o: $(hdrdir)/ruby/internal/intern/file.h
+cparse.o: $(hdrdir)/ruby/internal/intern/gc.h
+cparse.o: $(hdrdir)/ruby/internal/intern/hash.h
+cparse.o: $(hdrdir)/ruby/internal/intern/io.h
+cparse.o: $(hdrdir)/ruby/internal/intern/load.h
+cparse.o: $(hdrdir)/ruby/internal/intern/marshal.h
+cparse.o: $(hdrdir)/ruby/internal/intern/numeric.h
+cparse.o: $(hdrdir)/ruby/internal/intern/object.h
+cparse.o: $(hdrdir)/ruby/internal/intern/parse.h
+cparse.o: $(hdrdir)/ruby/internal/intern/proc.h
+cparse.o: $(hdrdir)/ruby/internal/intern/process.h
+cparse.o: $(hdrdir)/ruby/internal/intern/random.h
+cparse.o: $(hdrdir)/ruby/internal/intern/range.h
+cparse.o: $(hdrdir)/ruby/internal/intern/rational.h
+cparse.o: $(hdrdir)/ruby/internal/intern/re.h
+cparse.o: $(hdrdir)/ruby/internal/intern/ruby.h
+cparse.o: $(hdrdir)/ruby/internal/intern/select.h
+cparse.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+cparse.o: $(hdrdir)/ruby/internal/intern/signal.h
+cparse.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+cparse.o: $(hdrdir)/ruby/internal/intern/string.h
+cparse.o: $(hdrdir)/ruby/internal/intern/struct.h
+cparse.o: $(hdrdir)/ruby/internal/intern/thread.h
+cparse.o: $(hdrdir)/ruby/internal/intern/time.h
+cparse.o: $(hdrdir)/ruby/internal/intern/variable.h
+cparse.o: $(hdrdir)/ruby/internal/intern/vm.h
+cparse.o: $(hdrdir)/ruby/internal/interpreter.h
+cparse.o: $(hdrdir)/ruby/internal/iterator.h
+cparse.o: $(hdrdir)/ruby/internal/memory.h
+cparse.o: $(hdrdir)/ruby/internal/method.h
+cparse.o: $(hdrdir)/ruby/internal/module.h
+cparse.o: $(hdrdir)/ruby/internal/newobj.h
+cparse.o: $(hdrdir)/ruby/internal/rgengc.h
+cparse.o: $(hdrdir)/ruby/internal/scan_args.h
+cparse.o: $(hdrdir)/ruby/internal/special_consts.h
+cparse.o: $(hdrdir)/ruby/internal/static_assert.h
+cparse.o: $(hdrdir)/ruby/internal/stdalign.h
+cparse.o: $(hdrdir)/ruby/internal/stdbool.h
+cparse.o: $(hdrdir)/ruby/internal/symbol.h
+cparse.o: $(hdrdir)/ruby/internal/value.h
+cparse.o: $(hdrdir)/ruby/internal/value_type.h
+cparse.o: $(hdrdir)/ruby/internal/variable.h
+cparse.o: $(hdrdir)/ruby/internal/warning_push.h
+cparse.o: $(hdrdir)/ruby/internal/xmalloc.h
+cparse.o: $(hdrdir)/ruby/missing.h
+cparse.o: $(hdrdir)/ruby/ruby.h
+cparse.o: $(hdrdir)/ruby/st.h
+cparse.o: $(hdrdir)/ruby/subst.h
+cparse.o: cparse.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/racc/cparse/extconf.rb b/ext/racc/cparse/extconf.rb
new file mode 100644
index 0000000000..18c5689ad8
--- /dev/null
+++ b/ext/racc/cparse/extconf.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: false
+#
+
+require 'mkmf'
+
+have_func('rb_block_call')
+have_func('rb_ary_subseq')
+
+create_makefile 'racc/cparse'
diff --git a/ext/rbconfig/sizeof/depend b/ext/rbconfig/sizeof/depend
index 4e4ebd4ae5..5b65b83772 100644
--- a/ext/rbconfig/sizeof/depend
+++ b/ext/rbconfig/sizeof/depend
@@ -66,7 +66,6 @@ limits.o: $(hdrdir)/ruby/internal/attr/noexcept.h
limits.o: $(hdrdir)/ruby/internal/attr/noinline.h
limits.o: $(hdrdir)/ruby/internal/attr/nonnull.h
limits.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-limits.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
limits.o: $(hdrdir)/ruby/internal/attr/pure.h
limits.o: $(hdrdir)/ruby/internal/attr/restrict.h
limits.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -126,6 +125,7 @@ limits.o: $(hdrdir)/ruby/internal/intern/enumerator.h
limits.o: $(hdrdir)/ruby/internal/intern/error.h
limits.o: $(hdrdir)/ruby/internal/intern/eval.h
limits.o: $(hdrdir)/ruby/internal/intern/file.h
+limits.o: $(hdrdir)/ruby/internal/intern/gc.h
limits.o: $(hdrdir)/ruby/internal/intern/hash.h
limits.o: $(hdrdir)/ruby/internal/intern/io.h
limits.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -156,6 +156,7 @@ limits.o: $(hdrdir)/ruby/internal/memory.h
limits.o: $(hdrdir)/ruby/internal/method.h
limits.o: $(hdrdir)/ruby/internal/module.h
limits.o: $(hdrdir)/ruby/internal/newobj.h
+limits.o: $(hdrdir)/ruby/internal/rgengc.h
limits.o: $(hdrdir)/ruby/internal/scan_args.h
limits.o: $(hdrdir)/ruby/internal/special_consts.h
limits.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -224,7 +225,6 @@ sizes.o: $(hdrdir)/ruby/internal/attr/noexcept.h
sizes.o: $(hdrdir)/ruby/internal/attr/noinline.h
sizes.o: $(hdrdir)/ruby/internal/attr/nonnull.h
sizes.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-sizes.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
sizes.o: $(hdrdir)/ruby/internal/attr/pure.h
sizes.o: $(hdrdir)/ruby/internal/attr/restrict.h
sizes.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -284,6 +284,7 @@ sizes.o: $(hdrdir)/ruby/internal/intern/enumerator.h
sizes.o: $(hdrdir)/ruby/internal/intern/error.h
sizes.o: $(hdrdir)/ruby/internal/intern/eval.h
sizes.o: $(hdrdir)/ruby/internal/intern/file.h
+sizes.o: $(hdrdir)/ruby/internal/intern/gc.h
sizes.o: $(hdrdir)/ruby/internal/intern/hash.h
sizes.o: $(hdrdir)/ruby/internal/intern/io.h
sizes.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -314,6 +315,7 @@ sizes.o: $(hdrdir)/ruby/internal/memory.h
sizes.o: $(hdrdir)/ruby/internal/method.h
sizes.o: $(hdrdir)/ruby/internal/module.h
sizes.o: $(hdrdir)/ruby/internal/newobj.h
+sizes.o: $(hdrdir)/ruby/internal/rgengc.h
sizes.o: $(hdrdir)/ruby/internal/scan_args.h
sizes.o: $(hdrdir)/ruby/internal/special_consts.h
sizes.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/readline/.gitignore b/ext/readline/.gitignore
new file mode 100644
index 0000000000..3d372989ae
--- /dev/null
+++ b/ext/readline/.gitignore
@@ -0,0 +1 @@
+/readline-[1-9]*.*
diff --git a/ext/readline/README b/ext/readline/README
new file mode 100644
index 0000000000..57c51b5f5d
--- /dev/null
+++ b/ext/readline/README
@@ -0,0 +1,10 @@
+The Readline module provides interface for GNU Readline.
+This module defines a number of methods to facilitate completion
+and accesses input history from the Ruby interpreter.
+This module supported Edit Line(libedit) too.
+libedit is compatible with GNU Readline.
+
+GNU Readline:: http://www.gnu.org/directory/readline.html
+libedit:: http://www.thrysoee.dk/editline/
+
+See RDoc for Readline module.
diff --git a/ext/readline/README.ja b/ext/readline/README.ja
new file mode 100644
index 0000000000..57a6ee4126
--- /dev/null
+++ b/ext/readline/README.ja
@@ -0,0 +1,386 @@
+GNU Readline ã«ã‚ˆã‚‹ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å…¥åŠ›ã‚¤ãƒ³ã‚¿ãƒ•ã‚§ãƒ¼ã‚¹ã‚’æä¾›ã™ã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
+ã§ã™ã€‚GNU Readline ã®äº’æ›ãƒ©ã‚¤ãƒ–ラリã®ã²ã¨ã¤ã§ã‚ã‚‹ Edit Line(libedit) ã‚‚
+サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚
+
+GNU Readline:: http://www.gnu.org/directory/readline.html
+libedit:: http://www.thrysoee.dk/editline/
+
+Readline.readline を使用ã—ã¦ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã®å…¥åŠ›ã‚’å–å¾—ã§ãã¾ã™ã€‚ã“ã®ã¨ãã€
+GNU Readline ã®ã‚ˆã†ã«å…¥åŠ›ã®è£œå®Œã‚„Emacs ã®ã‚ˆã†ãªã‚­ãƒ¼æ“作ãªã©ãŒã§ãã¾ã™ã€‚
+
+ require "readline"
+ while buf = Readline.readline("> ", true)
+ p buf
+ end
+
+ユーザãŒå…¥åŠ›ã—ãŸå†…容を履歴(以下ã€ãƒ’ストリ)ã¨ã—ã¦è¨˜éŒ²ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+定数 Readline::HISTORY を使用ã—ã¦ãƒ’ストリã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™ã€‚
+
+ require "readline"
+ while buf = Readline.readline("> ", true)
+ p Readline::HISTORY.to_a
+ print("-> ", buf, "\n")
+ end
+
+使用ã™ã‚‹ãƒ©ã‚¤ãƒ–ラリã«ã‚ˆã‚Šã€ã„ãã¤ã‹ã®ãƒ¡ã‚½ãƒƒãƒ‰ã§ä¾‹å¤– NotImplementedError
+ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+== Readline モジュール
+
+=== モジュール関数
+
+readline([prompt, [add_hist]]) -> String | nil
+
+ prompt を出力ã—ã€ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã®ã‚­ãƒ¼å…¥åŠ›ã‚’å¾…ã¡ã¾ã™ã€‚
+ ã‚¨ãƒ³ã‚¿ãƒ¼ã‚­ãƒ¼ã®æŠ¼ä¸‹ãªã©ã§ãƒ¦ãƒ¼ã‚¶ãŒæ–‡å­—列を入力ã—終ãˆã‚‹ã¨ã€
+ 入力ã—ãŸæ–‡å­—列を返ã—ã¾ã™ã€‚
+ ã“ã®ã¨ãã€add_hist ㌠true ã§ã‚れã°ã€å…¥åŠ›ã—ãŸæ–‡å­—列をヒストリã«è¿½åŠ ã—ã¾ã™ã€‚
+
+ 何も入力ã—ã¦ã„ãªã„状態㧠EOF(UNIX ã§ã¯ ^D) を入力ã™ã‚‹ãªã©ã§ã€
+ ユーザã‹ã‚‰ã®å…¥åŠ›ãŒãªã„å ´åˆã¯ nil ã‚’è¿”ã—ã¾ã™ã€‚
+
+ æ¬¡ã®æ¡ä»¶ã‚’å…¨ã¦æº€ãŸã™å ´åˆã€ä¾‹å¤– IOError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+ 1. 標準入力㌠tty ã§ãªã„。
+ 2. 標準入力をクローズã—ã¦ã„る。(isatty(2) ã® errno ㌠EBADF ã§ã‚る。)
+
+ 本メソッドã¯ã‚¹ãƒ¬ãƒƒãƒ‰ã«å¯¾å¿œã—ã¦ã„ã¾ã™ã€‚
+ 入力待ã¡çŠ¶æ…‹ã®ã¨ãã¯ã‚¹ãƒ¬ãƒƒãƒ‰ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ‡æ›¿ãˆãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+ 入力時ã«ã¯è¡Œå†…編集ãŒå¯èƒ½ã§ã€vi モード㨠Emacs モードãŒç”¨æ„ã•れã¦ã„ã¾ã™ã€‚
+ デフォルト㯠Emacs モードã§ã™ã€‚
+
+ 本メソッドã«ã¯æ³¨æ„事項ãŒã‚りã¾ã™ã€‚
+ 入力待ã¡ã®çŠ¶æ…‹ã§ ^C ã™ã‚‹ã¨ ruby インタプリタãŒçµ‚了ã—ã€ç«¯æœ«çŠ¶æ…‹ã‚’å¾©å¸°ã—ã¾ã›ã‚“。
+ ã“れを回é¿ã™ã‚‹ãŸã‚ã®ä¾‹ã‚’3ã¤æŒ™ã’ã¾ã™ã€‚
+
+ * ^Cã«ã‚ˆã‚‹Interrupt例外を補足ã—ã¦ã€ç«¯æœ«çŠ¶æ…‹ã‚’å¾©å¸°ã—ã¾ã™:
+
+ require "readline"
+
+ stty_save = `stty -g`.chomp
+ begin
+ while buf = Readline.readline
+ p buf
+ end
+ rescue Interrupt
+ system("stty", stty_save)
+ exit
+ end
+ end
+ end
+
+ * INTシグナルを補足ã—ã¦ã€ç«¯æœ«çŠ¶æ…‹ã‚’å¾©å¸°ã—ã¾ã™:
+
+ require "readline"
+
+ stty_save = `stty -g`.chomp
+ trap("INT") { system "stty", stty_save; exit }
+
+ while buf = Readline.readline
+ p buf
+ end
+
+ * å˜ã« ^C を無視ã™ã‚‹æ–¹æ³•ã‚‚ã‚りã¾ã™:
+
+ require "readline"
+
+ trap("INT", "SIG_IGN")
+
+ while buf = Readline.readline
+ p buf
+ end
+
+ 入力履歴 Readline::HISTORY を使用ã—ã¦ã€ç©ºè¡Œã‚„ç›´å‰ã®å…¥åŠ›ã¨åŒã˜å†…容ã¯å…¥åŠ›
+ å±¥æ­´ã«æ®‹ã•ãªã„ã¨ã„ã†ã“ã¨ã‚‚ã§ãã¾ã™ã€‚
+
+ require "readline"
+
+ while buf = Readline.readline("> ", true)
+ # p Readline::HISTORY.to_a
+ Readline::HISTORY.pop if /^\s*$/ =~ buf
+
+ begin
+ if Readline::HISTORY[Readline::HISTORY.length-2] == buf
+ Readline::HISTORY.pop
+ end
+ rescue IndexError
+ end
+
+ # p Readline::HISTORY.to_a
+ print "-> ", buf, "\n"
+ end
+
+=== クラスメソッド
+
+Readline.input = input
+
+ Readline.readline メソッドã§ä½¿ç”¨ã™ã‚‹å…¥åŠ›ç”¨ã® File オブジェクト input
+ を指定ã—ã¾ã™ã€‚
+
+Readline.output = output
+
+ Readline.readline メソッドã§ä½¿ç”¨ã™ã‚‹å‡ºåŠ›ç”¨ã® File オブジェクト
+ output を指定ã—ã¾ã™ã€‚
+
+Readline.completion_proc = proc
+
+ ユーザã‹ã‚‰ã®å…¥åŠ›ã‚’è£œå®Œã™ã‚‹æ™‚ã®å€™è£œã‚’å–å¾—ã™ã‚‹ Proc オブジェクト proc ã‚’
+ 指定ã—ã¾ã™ã€‚proc ã¯ã€æ¬¡ã®ã‚‚ã®ã‚’想定ã—ã¦ã„ã¾ã™ã€‚
+ 1. call メソッドをæŒã¡ã¾ã™ã€‚
+ call メソッドをæŒãŸãªã„å ´åˆã€ä¾‹å¤– ArgumentError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+ 2. 引数ã«ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã®å…¥åŠ›æ–‡å­—åˆ—(注1)ã‚’å–りã¾ã™ã€‚
+ 3. å€™è£œã®æ–‡å­—列ã®é…列を返ã—ã¾ã™ã€‚
+
+ 注1:「/var/lib /vã€ã®å¾Œã§è£œå®Œã‚’行ã†ã¨ã€
+ デフォルトã§ã¯ proc ã®å¼•æ•°ã«ã€Œ/vã€ãŒæ¸¡ã•れã¾ã™ã€‚
+ ã“ã®ã‚ˆã†ã«ã€ãƒ¦ãƒ¼ã‚¶ãŒå…¥åŠ›ã—ãŸæ–‡å­—列を
+ Readline.completer_word_break_characters ã«å«ã¾ã‚Œã‚‹æ–‡å­—ã§åŒºåˆ‡ã£ãŸã‚‚
+ ã®ã‚’å˜èªžã¨ã™ã‚‹ã¨ã€ã‚«ãƒ¼ã‚½ãƒ«ãŒã‚ã‚‹å˜èªžã®æœ€åˆã®æ–‡å­—ã‹ã‚‰ç¾åœ¨ã®ã‚«ãƒ¼ã‚½ãƒ«ä½
+ ç½®ã¾ã§ã®æ–‡å­—列㌠proc ã®å¼•æ•°ã«æ¸¡ã•れã¾ã™ã€‚
+
+Readline.completion_proc -> proc
+
+ ユーザã‹ã‚‰ã®å…¥åŠ›ã‚’è£œå®Œã™ã‚‹æ™‚ã®å€™è£œã‚’å–å¾—ã™ã‚‹ Proc オブジェクト proc
+ ã‚’å–å¾—ã—ã¾ã™ã€‚
+
+Readline.completion_case_fold = bool
+
+ ユーザã®å…¥åŠ›ã‚’è£œå®Œã™ã‚‹éš›ã€å¤§æ–‡å­—ã¨å°æ–‡å­—を区別ã™ã‚‹ï¼ã—ãªã„を指定ã—ã¾ã™ã€‚
+ bool ãŒçœŸãªã‚‰ã°åŒºåˆ¥ã—ã¾ã›ã‚“。bool ãŒå½ãªã‚‰ã°åŒºåˆ¥ã—ã¾ã™ã€‚
+
+Readline.completion_case_fold -> bool
+
+ ユーザã®å…¥åŠ›ã‚’è£œå®Œã™ã‚‹éš›ã€å¤§æ–‡å­—ã¨å°æ–‡å­—を区別ã™ã‚‹ï¼ã—ãªã„ã‚’å–å¾—ã—ã¾ã™ã€‚
+ bool ãŒçœŸãªã‚‰ã°åŒºåˆ¥ã—ã¾ã›ã‚“。bool ãŒå½ãªã‚‰ã°åŒºåˆ¥ã—ã¾ã™ã€‚
+
+ ãªãŠã€Readline.completion_case_fold= ãƒ¡ã‚½ãƒƒãƒ‰ã§æŒ‡å®šã—ãŸã‚ªãƒ–ジェクトを
+ ãã®ã¾ã¾å–å¾—ã™ã‚‹ã®ã§ã€æ¬¡ã®ã‚ˆã†ãªå‹•作をã—ã¾ã™ã€‚
+
+ require "readline"
+
+ Readline.completion_case_fold = "This is a String."
+ p Readline.completion_case_fold # => "This is a String."
+
+Readline.line_buffer -> string
+
+ 入力中ã®è¡Œå…¨ä½“ã‚’è¿”ã—ã¾ã™ã€‚complete_proc ã®ä¸­ã§ä½¿ç”¨ã™ã‚‹ã“ã¨ã‚’想定ã—
+ ã¦ã„ã¾ã™ã€‚Readline.line_buffer ã®é•·ã•㯠GNU Readline ã® rl_end 変数ã®
+ 値ã¨ä¸€è‡´ã—ã¾ã™ã€‚
+
+Readline.point -> int
+
+ ç¾åœ¨ã®ã‚«ãƒ¼ã‚½ãƒ«ã®ä½ç½®ã‚’è¿”ã—ã¾ã™ã€‚
+ Readline モジュールã¯è£œå®Œå¯¾è±¡ã®å˜èªžã®é–‹å§‹ä½ç½®ã®æƒ…報をæä¾›ã—ã¦ã„ã¾ã›ã‚“。
+ ã—ã‹ã—ãªãŒã‚‰ã€ completion_proc ã®ä¸­ã§å…¥åŠ›ã—ãŸå˜èªž text ã¨
+ Readline.point を使用ã™ã‚‹ã“ã¨ã§é–‹å§‹ä½ç½®ã‚’å°Žãã“ã¨ãŒã§ãã¾ã™ã€‚
+
+ é–‹å§‹ä½ç½® = 入力ã—ãŸå˜èªžã®é•·ã• - Readline.point
+
+Readline.vi_editing_mode -> nil
+
+ 編集モードを vi モードã«ã—ã¾ã™ã€‚
+ vi モードã®è©³ç´°ã¯ã€GNU Readline ã®ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.vi_editing_mode? -> bool
+
+ 編集モード㌠vi モードã®å ´åˆã€true ã‚’è¿”ã—ã¾ã™ã€‚ãã†ã§ãªã‘れ㰠false
+ ã‚’è¿”ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.emacs_editing_mode -> nil
+
+ 編集モードを Emacs モードã«ã—ã¾ã™ã€‚
+ デフォルト㯠Emacs モードã§ã™ã€‚
+ Emacs モードã®è©³ç´°ã¯ã€GNU Readline ã®ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.emacs_editing_mode? -> bool
+
+ 編集モード㌠Emacs モードã®å ´åˆã€true ã‚’è¿”ã—ã¾ã™ã€‚ãã†ã§ãªã‘れ㰠false
+ ã‚’è¿”ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.completion_append_character = char
+
+ ユーザã®å…¥åŠ›ã®è£œå®ŒãŒå®Œäº†ã—ãŸå ´åˆã«ã€æœ€å¾Œã«ä»˜åŠ ã™ã‚‹æ–‡å­— char を指定ã—
+ ã¾ã™ã€‚åŠè§’スペース「" "ã€ãªã©ã®å˜èªžã‚’区切る文字を指定ã™ã‚Œã°ã€é€£ç¶šã—ã¦
+ 入力ã™ã‚‹éš›ã«ä¾¿åˆ©ã§ã™ã€‚
+
+ 使用例:
+
+ require "readline"
+
+ Readline.readline("> ", true)
+ Readline.completion_append_character = " "
+
+ 実行例:
+
+ >
+ ã“ã“ã§ "/var/li" を入力ã—ã¾ã™ã€‚
+
+ > /var/li
+ ã“ã“ã§ TAB キーを入力ã—ã¾ã™ã€‚
+
+ > /var/lib
+ "b" ãŒè£œå®Œã•ã‚Œã€æœ€å¾Œã« " " ãŒè¿½åŠ ã•れるã®ã§ã€"/usr" を連続ã—ã¦å…¥åŠ›ã§ãã¾ã™ã€‚
+
+ > /var/lib /usr
+
+ ãªãŠã€1文字ã—ã‹æŒ‡å®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ 例ãˆã°ã€"string"を指定ã—ãŸå ´åˆã¯æœ€åˆã®æ–‡å­—ã§ã‚ã‚‹"s"ã ã‘を使用ã—ã¾ã™ã€‚
+
+ require "readline"
+
+ Readline.completion_append_character = "string"
+ p Readline.completion_append_character # => "s"
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.completion_append_character -> char
+
+ ユーザã®å…¥åŠ›ã®è£œå®ŒãŒå®Œäº†ã—ãŸå ´åˆã«ã€æœ€å¾Œã«ä»˜åŠ ã™ã‚‹æ–‡å­—ã‚’å–å¾—ã—ã¾ã™ã€‚
+ デフォルトã¯ç©ºç™½ (" ") ã§ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.basic_word_break_characters = string
+
+ ユーザã®å…¥åŠ›ã®è£œå®Œã‚’行ã†éš›ã€å˜èªžã®åŒºåˆ‡ã‚Šã‚’示ã™è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる
+ 文字列 string を指定ã—ã¾ã™ã€‚
+
+ GNU Readline ã®ãƒ‡ãƒ•ォルトã®å€¤ã¯ã€Bash ã®è£œå®Œå‡¦ç†ã§ä½¿ç”¨ã—ã¦ã„る文字列
+ " \t\n\"\\'`@$><=;|&{(" (スペースをå«ã‚€) ã«ãªã£ã¦ã„ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.basic_word_break_characters -> string
+
+ ユーザã®å…¥åŠ›ã®è£œå®Œã‚’行ã†éš›ã€å˜èªžã®åŒºåˆ‡ã‚Šã‚’示ã™è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる
+ 文字列をå–å¾—ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.completer_word_break_characters = string
+
+ ユーザã®å…¥åŠ›ã®è£œå®Œã‚’行ã†éš›ã€å˜èªžã®åŒºåˆ‡ã‚Šã‚’示ã™è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる
+ 文字列 string を指定ã—ã¾ã™ã€‚
+ Readline.basic_word_break_characters= ã¨ã®é•ã„ã¯ã€
+ GNU Readline ã® rl_complete_internal 関数ã§ä½¿ç”¨ã•れるã“ã¨ã§ã™ã€‚
+
+ GNU Readline ã®ãƒ‡ãƒ•ォルトã®å€¤ã¯ã€
+ Readline.basic_word_break_characters ã¨åŒã˜ã§ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.completer_word_break_characters -> string
+
+ ユーザã®å…¥åŠ›ã®è£œå®Œã‚’行ã†éš›ã€å˜èªžã®åŒºåˆ‡ã‚Šã‚’示ã™è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れãŸ
+ 文字列をå–å¾—ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.basic_quote_characters = string
+
+ スペースãªã©ã®å˜èªžã®åŒºåˆ‡ã‚Šã‚’クオートã™ã‚‹ãŸã‚ã®è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる
+ 文字列 string を指定ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.basic_quote_characters -> string
+
+ スペースãªã©ã®å˜èªžã®åŒºåˆ‡ã‚Šã‚’クオートã™ã‚‹ãŸã‚ã®è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる
+ 文字列をå–å¾—ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.completer_quote_characters = string
+
+ ユーザã®å…¥åŠ›ã®è£œå®Œã‚’行ã†éš›ã€ã‚¹ãƒšãƒ¼ã‚¹ãªã©ã®å˜èªžã®åŒºåˆ‡ã‚Šã‚’
+ クオートã™ã‚‹ãŸã‚ã®è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる文字列 string を指定ã—ã¾ã™ã€‚
+ 指定ã—ãŸæ–‡å­—ã®é–“ã§ã¯ã€Readline.completer_word_break_characters=
+ ã§æŒ‡å®šã—ãŸæ–‡å­—列ã«å«ã¾ã‚Œã‚‹æ–‡å­—ã‚‚ã€æ™®é€šã®æ–‡å­—列ã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.completer_quote_characters -> string
+
+ ユーザã®å…¥åŠ›ã®è£œå®Œã‚’行ã†éš›ã€ã‚¹ãƒšãƒ¼ã‚¹ãªã©ã®å˜èªžã®åŒºåˆ‡ã‚Šã‚’
+ クオートã™ã‚‹ãŸã‚ã®è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる文字列をå–å¾—ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.filename_quote_characters = string
+
+ ユーザã®å…¥åŠ›æ™‚ã«ãƒ•ァイルåã®è£œå®Œã‚’行ã†éš›ã€ã‚¹ãƒšãƒ¼ã‚¹ãªã©ã®å˜èªžã®åŒºåˆ‡ã‚Šã‚’
+ クオートã™ã‚‹ãŸã‚ã®è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる文字列 string を指定ã—ã¾ã™ã€‚
+
+ GNU Readline ã®ãƒ‡ãƒ•ォルト値㯠nil ã§ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+Readline.filename_quote_characters -> string
+
+ ユーザã®å…¥åŠ›æ™‚ã«ãƒ•ァイルåã®è£œå®Œã‚’行ã†éš›ã€ã‚¹ãƒšãƒ¼ã‚¹ãªã©ã®å˜èªžã®åŒºåˆ‡ã‚Šã‚’
+ クオートã™ã‚‹ãŸã‚ã®è¤‡æ•°ã®æ–‡å­—ã§æ§‹æˆã•れる文字列をå–å¾—ã—ã¾ã™ã€‚
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€ä¾‹å¤– NotImplementedError ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+
+=== クラス定数
+
+HISTORY
+
+ 定数 HISTORY を使用ã—ã¦ãƒ’ストリã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™ã€‚
+ Enumerable モジュールを extend ã—ã¦ãŠã‚Šã€
+ é…列ã®ã‚ˆã†ã«æŒ¯ã‚‹èˆžã†ã“ã¨ãŒã§ãã¾ã™ã€‚
+ 例ãˆã°ã€HISTORY[4] ã«ã‚ˆã‚Š 5 番目ã«å…¥åŠ›ã—ãŸå†…容をå–り出ã™ã“ã¨ãŒã§ãã¾ã™ã€‚
+
+ require "readline"
+
+ Readline::HISTORY.push("a", "b", "c", "d", "e")
+ p Readline::HISTORY[4] # => "e"
+
+ 実装ã—ã¦ã„ã‚‹ãƒ¡ã‚½ãƒƒãƒ‰ã‚’æ¬¡ã«æŒ™ã’ã¾ã™ã€‚
+ * HISTORY.to_s -> "HISTORY"
+ * HISTORY[index] -> string
+ * HISTORY[index] = string
+ * HISTORY.push(string[, string, ...]) -> self
+ * HISTORY << string -> self
+ * HISTORY.pop -> string
+ * HISTORY.shift -> string
+ * HISTORY.each -> Enumerator
+ * HISTORY.each { |i| } -> [string]
+ * HISTORY.length -> Integer
+ * HISTORY.empty? -> true or false
+ * HISTORY.delete_at(index) -> string
+ * HISTORY.clear -> self
+
+ サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„環境ã§ã¯ã€æ¬¡ã®ãƒ¡ã‚½ãƒƒãƒ‰ã§ä¾‹å¤– NotImplementedError ãŒ
+ 発生ã—ã¾ã™ã€‚
+ * HISTORY[index] = string
+ * HISTORY.pop -> string
+ * HISTORY.shift -> string
+ * HISTORY.delete_at(index) -> string
+ * HISTORY.clear -> self
+
+FILENAME_COMPLETION_PROC
+
+ ファイルåã®è£œå®Œã‚’行ㆠcall メソッドをæŒã¤ã‚ªãƒ–ジェクトã§ã™ã€‚
+
+ Readline.completion_proc= ã«ã‚ˆã‚Šã€ãƒ¦ãƒ¼ã‚¶ã®å…¥åŠ›æ™‚ã«ãƒ•ァイルåã®è£œå®Œã‚’
+ 行ã†ã‚ˆã†ã«è¨­å®šã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã‚’想定ã—ã¦ã¾ã™ã€‚
+
+USERNAME_COMPLETION_PROC
+
+ ユーザåã®è£œå®Œã‚’行ㆠcall メソッドをæŒã¤ã‚ªãƒ–ジェクトã§ã™ã€‚
+
+ Readline.completion_proc= ã«ã‚ˆã‚Šã€ãƒ¦ãƒ¼ã‚¶ã®å…¥åŠ›æ™‚ã«ãƒ¦ãƒ¼ã‚¶åã®è£œå®Œã‚’行
+ ã†ã‚ˆã†ã«è¨­å®šã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã‚’想定ã—ã¦ã¾ã™ã€‚
+
+VERSION
+
+ 使用ã—ã¦ã„ã‚‹ GNU Readline ã¾ãŸã¯ libedit ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™ã€‚
diff --git a/ext/readline/depend b/ext/readline/depend
new file mode 100644
index 0000000000..c62309622a
--- /dev/null
+++ b/ext/readline/depend
@@ -0,0 +1,175 @@
+# AUTOGENERATED DEPENDENCIES START
+readline.o: $(RUBY_EXTCONF_H)
+readline.o: $(arch_hdrdir)/ruby/config.h
+readline.o: $(hdrdir)/ruby/assert.h
+readline.o: $(hdrdir)/ruby/backward.h
+readline.o: $(hdrdir)/ruby/backward/2/assume.h
+readline.o: $(hdrdir)/ruby/backward/2/attributes.h
+readline.o: $(hdrdir)/ruby/backward/2/bool.h
+readline.o: $(hdrdir)/ruby/backward/2/inttypes.h
+readline.o: $(hdrdir)/ruby/backward/2/limits.h
+readline.o: $(hdrdir)/ruby/backward/2/long_long.h
+readline.o: $(hdrdir)/ruby/backward/2/stdalign.h
+readline.o: $(hdrdir)/ruby/backward/2/stdarg.h
+readline.o: $(hdrdir)/ruby/defines.h
+readline.o: $(hdrdir)/ruby/encoding.h
+readline.o: $(hdrdir)/ruby/intern.h
+readline.o: $(hdrdir)/ruby/internal/abi.h
+readline.o: $(hdrdir)/ruby/internal/anyargs.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/char.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/double.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/int.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/long.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/short.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
+readline.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
+readline.o: $(hdrdir)/ruby/internal/assume.h
+readline.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
+readline.o: $(hdrdir)/ruby/internal/attr/artificial.h
+readline.o: $(hdrdir)/ruby/internal/attr/cold.h
+readline.o: $(hdrdir)/ruby/internal/attr/const.h
+readline.o: $(hdrdir)/ruby/internal/attr/constexpr.h
+readline.o: $(hdrdir)/ruby/internal/attr/deprecated.h
+readline.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
+readline.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
+readline.o: $(hdrdir)/ruby/internal/attr/error.h
+readline.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
+readline.o: $(hdrdir)/ruby/internal/attr/forceinline.h
+readline.o: $(hdrdir)/ruby/internal/attr/format.h
+readline.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
+readline.o: $(hdrdir)/ruby/internal/attr/noalias.h
+readline.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
+readline.o: $(hdrdir)/ruby/internal/attr/noexcept.h
+readline.o: $(hdrdir)/ruby/internal/attr/noinline.h
+readline.o: $(hdrdir)/ruby/internal/attr/nonnull.h
+readline.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+readline.o: $(hdrdir)/ruby/internal/attr/pure.h
+readline.o: $(hdrdir)/ruby/internal/attr/restrict.h
+readline.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
+readline.o: $(hdrdir)/ruby/internal/attr/warning.h
+readline.o: $(hdrdir)/ruby/internal/attr/weakref.h
+readline.o: $(hdrdir)/ruby/internal/cast.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
+readline.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
+readline.o: $(hdrdir)/ruby/internal/compiler_since.h
+readline.o: $(hdrdir)/ruby/internal/config.h
+readline.o: $(hdrdir)/ruby/internal/constant_p.h
+readline.o: $(hdrdir)/ruby/internal/core.h
+readline.o: $(hdrdir)/ruby/internal/core/rarray.h
+readline.o: $(hdrdir)/ruby/internal/core/rbasic.h
+readline.o: $(hdrdir)/ruby/internal/core/rbignum.h
+readline.o: $(hdrdir)/ruby/internal/core/rclass.h
+readline.o: $(hdrdir)/ruby/internal/core/rdata.h
+readline.o: $(hdrdir)/ruby/internal/core/rfile.h
+readline.o: $(hdrdir)/ruby/internal/core/rhash.h
+readline.o: $(hdrdir)/ruby/internal/core/robject.h
+readline.o: $(hdrdir)/ruby/internal/core/rregexp.h
+readline.o: $(hdrdir)/ruby/internal/core/rstring.h
+readline.o: $(hdrdir)/ruby/internal/core/rstruct.h
+readline.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
+readline.o: $(hdrdir)/ruby/internal/ctype.h
+readline.o: $(hdrdir)/ruby/internal/dllexport.h
+readline.o: $(hdrdir)/ruby/internal/dosish.h
+readline.o: $(hdrdir)/ruby/internal/encoding/coderange.h
+readline.o: $(hdrdir)/ruby/internal/encoding/ctype.h
+readline.o: $(hdrdir)/ruby/internal/encoding/encoding.h
+readline.o: $(hdrdir)/ruby/internal/encoding/pathname.h
+readline.o: $(hdrdir)/ruby/internal/encoding/re.h
+readline.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
+readline.o: $(hdrdir)/ruby/internal/encoding/string.h
+readline.o: $(hdrdir)/ruby/internal/encoding/symbol.h
+readline.o: $(hdrdir)/ruby/internal/encoding/transcode.h
+readline.o: $(hdrdir)/ruby/internal/error.h
+readline.o: $(hdrdir)/ruby/internal/eval.h
+readline.o: $(hdrdir)/ruby/internal/event.h
+readline.o: $(hdrdir)/ruby/internal/fl_type.h
+readline.o: $(hdrdir)/ruby/internal/gc.h
+readline.o: $(hdrdir)/ruby/internal/glob.h
+readline.o: $(hdrdir)/ruby/internal/globals.h
+readline.o: $(hdrdir)/ruby/internal/has/attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/builtin.h
+readline.o: $(hdrdir)/ruby/internal/has/c_attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
+readline.o: $(hdrdir)/ruby/internal/has/extension.h
+readline.o: $(hdrdir)/ruby/internal/has/feature.h
+readline.o: $(hdrdir)/ruby/internal/has/warning.h
+readline.o: $(hdrdir)/ruby/internal/intern/array.h
+readline.o: $(hdrdir)/ruby/internal/intern/bignum.h
+readline.o: $(hdrdir)/ruby/internal/intern/class.h
+readline.o: $(hdrdir)/ruby/internal/intern/compar.h
+readline.o: $(hdrdir)/ruby/internal/intern/complex.h
+readline.o: $(hdrdir)/ruby/internal/intern/cont.h
+readline.o: $(hdrdir)/ruby/internal/intern/dir.h
+readline.o: $(hdrdir)/ruby/internal/intern/enum.h
+readline.o: $(hdrdir)/ruby/internal/intern/enumerator.h
+readline.o: $(hdrdir)/ruby/internal/intern/error.h
+readline.o: $(hdrdir)/ruby/internal/intern/eval.h
+readline.o: $(hdrdir)/ruby/internal/intern/file.h
+readline.o: $(hdrdir)/ruby/internal/intern/gc.h
+readline.o: $(hdrdir)/ruby/internal/intern/hash.h
+readline.o: $(hdrdir)/ruby/internal/intern/io.h
+readline.o: $(hdrdir)/ruby/internal/intern/load.h
+readline.o: $(hdrdir)/ruby/internal/intern/marshal.h
+readline.o: $(hdrdir)/ruby/internal/intern/numeric.h
+readline.o: $(hdrdir)/ruby/internal/intern/object.h
+readline.o: $(hdrdir)/ruby/internal/intern/parse.h
+readline.o: $(hdrdir)/ruby/internal/intern/proc.h
+readline.o: $(hdrdir)/ruby/internal/intern/process.h
+readline.o: $(hdrdir)/ruby/internal/intern/random.h
+readline.o: $(hdrdir)/ruby/internal/intern/range.h
+readline.o: $(hdrdir)/ruby/internal/intern/rational.h
+readline.o: $(hdrdir)/ruby/internal/intern/re.h
+readline.o: $(hdrdir)/ruby/internal/intern/ruby.h
+readline.o: $(hdrdir)/ruby/internal/intern/select.h
+readline.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+readline.o: $(hdrdir)/ruby/internal/intern/signal.h
+readline.o: $(hdrdir)/ruby/internal/intern/sprintf.h
+readline.o: $(hdrdir)/ruby/internal/intern/string.h
+readline.o: $(hdrdir)/ruby/internal/intern/struct.h
+readline.o: $(hdrdir)/ruby/internal/intern/thread.h
+readline.o: $(hdrdir)/ruby/internal/intern/time.h
+readline.o: $(hdrdir)/ruby/internal/intern/variable.h
+readline.o: $(hdrdir)/ruby/internal/intern/vm.h
+readline.o: $(hdrdir)/ruby/internal/interpreter.h
+readline.o: $(hdrdir)/ruby/internal/iterator.h
+readline.o: $(hdrdir)/ruby/internal/memory.h
+readline.o: $(hdrdir)/ruby/internal/method.h
+readline.o: $(hdrdir)/ruby/internal/module.h
+readline.o: $(hdrdir)/ruby/internal/newobj.h
+readline.o: $(hdrdir)/ruby/internal/rgengc.h
+readline.o: $(hdrdir)/ruby/internal/scan_args.h
+readline.o: $(hdrdir)/ruby/internal/special_consts.h
+readline.o: $(hdrdir)/ruby/internal/static_assert.h
+readline.o: $(hdrdir)/ruby/internal/stdalign.h
+readline.o: $(hdrdir)/ruby/internal/stdbool.h
+readline.o: $(hdrdir)/ruby/internal/symbol.h
+readline.o: $(hdrdir)/ruby/internal/value.h
+readline.o: $(hdrdir)/ruby/internal/value_type.h
+readline.o: $(hdrdir)/ruby/internal/variable.h
+readline.o: $(hdrdir)/ruby/internal/warning_push.h
+readline.o: $(hdrdir)/ruby/internal/xmalloc.h
+readline.o: $(hdrdir)/ruby/io.h
+readline.o: $(hdrdir)/ruby/missing.h
+readline.o: $(hdrdir)/ruby/onigmo.h
+readline.o: $(hdrdir)/ruby/oniguruma.h
+readline.o: $(hdrdir)/ruby/ruby.h
+readline.o: $(hdrdir)/ruby/st.h
+readline.o: $(hdrdir)/ruby/subst.h
+readline.o: $(hdrdir)/ruby/thread.h
+readline.o: readline.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/readline/depend-gem b/ext/readline/depend-gem
new file mode 100644
index 0000000000..df01bd2a86
--- /dev/null
+++ b/ext/readline/depend-gem
@@ -0,0 +1,4 @@
+# AUTOGENERATED DEPENDENCIES START
+readline.o: $(RUBY_EXTCONF_H)
+readline.o: readline.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb
new file mode 100644
index 0000000000..d3e7872e65
--- /dev/null
+++ b/ext/readline/extconf.rb
@@ -0,0 +1,112 @@
+# frozen_string_literal: false
+require "mkmf"
+
+readline = Struct.new(:headers, :extra_check).new(["stdio.h"])
+
+def readline.have_header(header)
+ if super(header, &extra_check)
+ headers.push(header)
+ return true
+ else
+ return false
+ end
+end
+
+def readline.have_var(var)
+ return super(var, headers)
+end
+
+def readline.have_func(func)
+ return super(func, headers)
+end
+
+def readline.have_type(type)
+ return super(type, headers)
+end
+
+dir_config('curses')
+dir_config('ncurses')
+dir_config('termcap')
+dir_config("readline")
+enable_libedit = enable_config("libedit")
+
+have_library("user32", nil) if /cygwin/ === RUBY_PLATFORM
+have_library("ncurses", "tgetnum") ||
+ have_library("termcap", "tgetnum") ||
+ have_library("curses", "tgetnum")
+
+case enable_libedit
+when true
+ # --enable-libedit
+ dir_config("libedit")
+ unless (readline.have_header("editline/readline.h") ||
+ readline.have_header("readline/readline.h")) &&
+ have_library("edit", "readline")
+ raise "libedit not found"
+ end
+when false
+ # --disable-libedit
+ unless ((readline.have_header("readline/readline.h") &&
+ readline.have_header("readline/history.h")) &&
+ have_library("readline", "readline"))
+ raise "readline not found"
+ end
+else
+ # does not specify
+ unless ((readline.have_header("readline/readline.h") &&
+ readline.have_header("readline/history.h")) &&
+ (have_library("readline", "readline") ||
+ have_library("edit", "readline"))) ||
+ (readline.have_header("editline/readline.h") &&
+ have_library("edit", "readline"))
+ raise "Neither readline nor libedit was found"
+ end
+end
+
+readline.have_func("rl_getc")
+readline.have_func("rl_getc_function")
+readline.have_func("rl_filename_completion_function")
+readline.have_func("rl_username_completion_function")
+readline.have_func("rl_completion_matches")
+readline.have_func("rl_refresh_line")
+readline.have_var("rl_deprep_term_function")
+readline.have_var("rl_completion_append_character")
+readline.have_var("rl_completion_quote_character")
+readline.have_var("rl_basic_word_break_characters")
+readline.have_var("rl_completer_word_break_characters")
+readline.have_var("rl_basic_quote_characters")
+readline.have_var("rl_completer_quote_characters")
+readline.have_var("rl_filename_quote_characters")
+readline.have_var("rl_attempted_completion_over")
+readline.have_var("rl_library_version")
+readline.have_var("rl_editing_mode")
+readline.have_var("rl_line_buffer")
+readline.have_var("rl_point")
+readline.have_var("rl_char_is_quoted_p")
+# workaround for native windows.
+/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_event_hook")
+/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_sigwinch")
+/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_signals")
+readline.have_var("rl_pre_input_hook")
+readline.have_var("rl_special_prefixes")
+readline.have_func("rl_cleanup_after_signal")
+readline.have_func("rl_free_line_state")
+readline.have_func("rl_clear_signals")
+readline.have_func("rl_set_screen_size")
+readline.have_func("rl_get_screen_size")
+readline.have_func("rl_vi_editing_mode")
+readline.have_func("rl_emacs_editing_mode")
+readline.have_func("replace_history_entry")
+readline.have_func("remove_history")
+readline.have_func("clear_history")
+readline.have_func("rl_redisplay")
+readline.have_func("rl_insert_text")
+readline.have_func("rl_delete_text")
+unless readline.have_type("rl_hook_func_t*")
+ # rl_hook_func_t is available since readline-4.2 (2001).
+ # Function is removed at readline-6.3 (2014).
+ # However, editline (NetBSD 6.1.3, 2014) doesn't have rl_hook_func_t.
+ $defs << "-Drl_hook_func_t=Function"
+end
+
+create_makefile("readline")
diff --git a/ext/readline/readline-ext.gemspec b/ext/readline/readline-ext.gemspec
new file mode 100644
index 0000000000..1e16edbfe6
--- /dev/null
+++ b/ext/readline/readline-ext.gemspec
@@ -0,0 +1,22 @@
+Gem::Specification.new do |spec|
+ spec.name = "readline-ext"
+ spec.version = "0.1.5"
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Provides an interface for GNU Readline and Edit Line (libedit).}
+ spec.description = %q{Provides an interface for GNU Readline and Edit Line (libedit).}
+ spec.homepage = "https://github.com/ruby/readline-ext"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.extensions = %w[ext/readline/extconf.rb]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
new file mode 100644
index 0000000000..fc254ce315
--- /dev/null
+++ b/ext/readline/readline.c
@@ -0,0 +1,2144 @@
+/************************************************
+
+ readline.c - GNU Readline module
+
+ $Author$
+ created at: Wed Jan 20 13:59:32 JST 1999
+
+ Copyright (C) 1997-2008 Shugo Maeda
+ Copyright (C) 2008-2013 Kouji Takao
+
+ $Id$
+
+ Contact:
+ - Kouji Takao <kouji dot takao at gmail dot com> (current maintainer)
+
+************************************************/
+
+#ifdef RUBY_EXTCONF_H
+#include RUBY_EXTCONF_H
+#endif
+
+#include "ruby/config.h"
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_READLINE_READLINE_H
+#include <readline/readline.h>
+#endif
+#ifdef HAVE_READLINE_HISTORY_H
+#include <readline/history.h>
+#endif
+#ifdef HAVE_EDITLINE_READLINE_H
+#include <editline/readline.h>
+#endif
+
+#include "ruby/io.h"
+#include "ruby/thread.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+static VALUE mReadline;
+
+#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
+#ifndef USE_INSERT_IGNORE_ESCAPE
+# if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE)
+# define USE_INSERT_IGNORE_ESCAPE 1
+# else
+# define USE_INSERT_IGNORE_ESCAPE 0
+# endif
+#endif
+
+#define COMPLETION_PROC "completion_proc"
+#define COMPLETION_CASE_FOLD "completion_case_fold"
+static ID id_call, completion_proc, completion_case_fold;
+#if defined HAVE_RL_CHAR_IS_QUOTED_P
+#define QUOTING_DETECTION_PROC "quoting_detection_proc"
+static ID quoting_detection_proc;
+#endif
+#if USE_INSERT_IGNORE_ESCAPE
+static ID id_orig_prompt, id_last_prompt;
+#endif
+#if defined(HAVE_RL_PRE_INPUT_HOOK)
+static ID id_pre_input_hook;
+#endif
+#if defined(HAVE_RL_SPECIAL_PREFIXES)
+static ID id_special_prefixes;
+#endif
+
+#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
+# define rl_filename_completion_function filename_completion_function
+#endif
+#ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
+# define rl_username_completion_function username_completion_function
+#else
+RUBY_EXTERN char *rl_username_completion_function(const char *, int);
+#endif
+#ifndef HAVE_RL_COMPLETION_MATCHES
+# define rl_completion_matches completion_matches
+#endif
+
+static int (*history_get_offset_func)(int);
+static int (*history_replace_offset_func)(int);
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+static int readline_completion_append_character;
+#endif
+
+static char **readline_attempted_completion_function(const char *text,
+ int start, int end);
+
+#define OutputStringValue(str) do {\
+ StringValueCStr(str);\
+ (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
+} while (0)\
+
+
+/*
+ * Document-class: Readline
+ *
+ * The Readline module provides interface for GNU Readline.
+ * This module defines a number of methods to facilitate completion
+ * and accesses input history from the Ruby interpreter.
+ * This module supported Edit Line(libedit) too.
+ * libedit is compatible with GNU Readline.
+ *
+ * GNU Readline:: http://www.gnu.org/directory/readline.html
+ * libedit:: http://www.thrysoee.dk/editline/
+ *
+ * Reads one inputted line with line edit by Readline.readline method.
+ * At this time, the facilitatation completion and the key
+ * bind like Emacs can be operated like GNU Readline.
+ *
+ * require "readline"
+ * while buf = Readline.readline("> ", true)
+ * p buf
+ * end
+ *
+ * The content that the user input can be recorded to the history.
+ * The history can be accessed by Readline::HISTORY constant.
+ *
+ * require "readline"
+ * while buf = Readline.readline("> ", true)
+ * p Readline::HISTORY.to_a
+ * print("-> ", buf, "\n")
+ * end
+ *
+ * Documented by Kouji Takao <kouji dot takao at gmail dot com>.
+ */
+
+static VALUE readline_instream;
+static VALUE readline_outstream;
+static FILE *readline_rl_instream;
+static FILE *readline_rl_outstream;
+
+static void
+mustbe_callable(VALUE proc)
+{
+ if (!NIL_P(proc) && !rb_respond_to(proc, id_call))
+ rb_raise(rb_eArgError, "argument must respond to `call'");
+}
+
+#if defined HAVE_RL_GETC_FUNCTION
+
+#ifndef HAVE_RL_GETC
+#define rl_getc(f) EOF
+#endif
+
+struct getc_struct {
+ FILE *input;
+ int fd;
+ int ret;
+ int err;
+};
+
+static int
+getc_body(struct getc_struct *p)
+{
+ char ch;
+ ssize_t ss;
+
+#if defined(_WIN32)
+ {
+ INPUT_RECORD ir;
+ DWORD n;
+ static int prior_key = '0';
+ for (;;) {
+ HANDLE h;
+ if (prior_key > 0xff) {
+ prior_key = rl_getc(p->input);
+ return prior_key;
+ }
+ h = (HANDLE)_get_osfhandle(p->fd);
+ if (PeekConsoleInput(h, &ir, 1, &n)) {
+ if (n == 1) {
+ if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
+ prior_key = rl_getc(p->input);
+ return prior_key;
+ } else {
+ ReadConsoleInput(h, &ir, 1, &n);
+ }
+ } else {
+ rb_w32_wait_events_blocking(&h, 1, INFINITE);
+ }
+ } else {
+ break;
+ }
+ }
+ }
+#endif
+
+ ss = read(p->fd, &ch, 1);
+ if (ss == 0) {
+ errno = 0;
+ return EOF;
+ }
+ if (ss != 1)
+ return EOF;
+ return (unsigned char)ch;
+}
+
+static void *
+getc_func(void *data1)
+{
+ struct getc_struct *p = data1;
+ errno = 0;
+ p->ret = getc_body(p);
+ p->err = errno;
+ return NULL;
+}
+
+static int
+readline_getc(FILE *input)
+{
+ struct getc_struct data;
+ if (input == NULL) /* editline may give NULL as input. */
+ input = stdin;
+ data.input = input;
+ data.fd = fileno(input);
+ again:
+ data.ret = EOF;
+ data.err = EINTR; /* getc_func is not called if already interrupted. */
+ rb_thread_call_without_gvl2(getc_func, &data, RUBY_UBF_IO, NULL);
+ if (data.ret == EOF) {
+ if (data.err == 0) {
+ return EOF;
+ }
+ if (data.err == EINTR) {
+ rb_thread_check_ints();
+ goto again;
+ }
+ if (data.err == EWOULDBLOCK || data.err == EAGAIN) {
+ int ret;
+ if (fileno(input) != data.fd)
+ rb_bug("readline_getc: input closed unexpectedly or memory corrupted");
+ ret = rb_wait_for_single_fd(data.fd, RB_WAITFD_IN, NULL);
+ if (ret != -1 || errno == EINTR)
+ goto again;
+ rb_sys_fail("rb_wait_for_single_fd");
+ }
+ rb_syserr_fail(data.err, "read");
+ }
+ return data.ret;
+}
+
+#elif defined HAVE_RL_EVENT_HOOK
+#define BUSY_WAIT 0
+
+static int readline_event(void);
+static int
+readline_event(void)
+{
+#if BUSY_WAIT
+ rb_thread_schedule();
+#else
+ rb_wait_for_single_fd(fileno(rl_instream), RB_WAITFD_IN, NULL);
+ return 0;
+#endif
+}
+#endif
+
+#if USE_INSERT_IGNORE_ESCAPE
+static VALUE
+insert_ignore_escape(VALUE self, VALUE prompt)
+{
+ VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt);
+ int ignoring = 0;
+ const char *s0, *s, *e;
+ long len;
+ static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
+
+ prompt = rb_str_new_shared(prompt);
+ last_prompt = rb_attr_get(self, id_last_prompt);
+ if (orig_prompt == prompt) return last_prompt;
+ len = RSTRING_LEN(prompt);
+ if (NIL_P(last_prompt)) {
+ last_prompt = rb_str_tmp_new(len);
+ }
+
+ s = s0 = RSTRING_PTR(prompt);
+ e = s0 + len;
+ rb_str_set_len(last_prompt, 0);
+ while (s < e && *s) {
+ switch (*s) {
+ case RL_PROMPT_START_IGNORE:
+ ignoring = -1;
+ rb_str_cat(last_prompt, s0, ++s - s0);
+ s0 = s;
+ break;
+ case RL_PROMPT_END_IGNORE:
+ ignoring = 0;
+ rb_str_cat(last_prompt, s0, ++s - s0);
+ s0 = s;
+ break;
+ case '\033':
+ if (++s < e && *s == '[') {
+ rb_str_cat(last_prompt, s0, s - s0 - 1);
+ s0 = s - 1;
+ while (++s < e && *s) {
+ if (ISALPHA(*(unsigned char *)s)) {
+ if (!ignoring) {
+ ignoring = 1;
+ rb_str_cat(last_prompt, ignore_code+0, 1);
+ }
+ rb_str_cat(last_prompt, s0, ++s - s0);
+ s0 = s;
+ break;
+ }
+ else if (!(('0' <= *s && *s <= '9') || *s == ';')) {
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ if (ignoring > 0) {
+ ignoring = 0;
+ rb_str_cat(last_prompt, ignore_code+1, 1);
+ }
+ s++;
+ break;
+ }
+ }
+ if (ignoring > 0) {
+ ignoring = 0;
+ rb_str_cat(last_prompt, ignore_code+1, 1);
+ }
+ rb_str_cat(last_prompt, s0, s - s0);
+
+ rb_ivar_set(self, id_orig_prompt, prompt);
+ rb_ivar_set(self, id_last_prompt, last_prompt);
+
+ return last_prompt;
+}
+#endif
+
+static VALUE
+readline_get(VALUE prompt)
+{
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+ readline_completion_append_character = rl_completion_append_character;
+#endif
+ return (VALUE)readline((char *)prompt);
+}
+
+static void
+clear_rl_instream(void)
+{
+ if (readline_rl_instream) {
+ fclose(readline_rl_instream);
+ if (rl_instream == readline_rl_instream)
+ rl_instream = NULL;
+ readline_rl_instream = NULL;
+ }
+ readline_instream = Qfalse;
+}
+
+static void
+clear_rl_outstream(void)
+{
+ if (readline_rl_outstream) {
+ fclose(readline_rl_outstream);
+ if (rl_outstream == readline_rl_outstream)
+ rl_outstream = NULL;
+ readline_rl_outstream = NULL;
+ }
+ readline_outstream = Qfalse;
+}
+
+static void
+prepare_readline(void)
+{
+ static int initialized = 0;
+ if (!initialized) {
+ rl_initialize();
+ initialized = 1;
+ }
+
+ if (readline_instream) {
+ rb_io_t *ifp;
+ rb_io_check_initialized(ifp = RFILE(rb_io_taint_check(readline_instream))->fptr);
+ if (ifp->fd < 0) {
+ clear_rl_instream();
+ rb_raise(rb_eIOError, "closed readline input");
+ }
+ }
+
+ if (readline_outstream) {
+ rb_io_t *ofp;
+ rb_io_check_initialized(ofp = RFILE(rb_io_taint_check(readline_outstream))->fptr);
+ if (ofp->fd < 0) {
+ clear_rl_outstream();
+ rb_raise(rb_eIOError, "closed readline output");
+ }
+ }
+}
+
+/*
+ * call-seq:
+ * Readline.readline(prompt = "", add_hist = false) -> string or nil
+ *
+ * Shows the +prompt+ and reads the inputted line with line editing.
+ * The inputted line is added to the history if +add_hist+ is true.
+ *
+ * Returns nil when the inputted line is empty and user inputs EOF
+ * (Presses ^D on UNIX).
+ *
+ * Raises IOError exception if one of below conditions are satisfied.
+ * 1. stdin was closed.
+ * 2. stdout was closed.
+ *
+ * This method supports thread. Switches the thread context when waits
+ * inputting line.
+ *
+ * Supports line edit when inputs line. Provides VI and Emacs editing mode.
+ * Default is Emacs editing mode.
+ *
+ * NOTE: Terminates ruby interpreter and does not return the terminal
+ * status after user pressed '^C' when wait inputting line.
+ * Give 3 examples that avoid it.
+ *
+ * * Catches the Interrupt exception by pressed ^C after returns
+ * terminal status:
+ *
+ * require "readline"
+ *
+ * stty_save = `stty -g`.chomp
+ * begin
+ * while buf = Readline.readline
+ * p buf
+ * end
+ * rescue Interrupt
+ * system("stty", stty_save)
+ * exit
+ * end
+ * end
+ * end
+ *
+ * * Catches the INT signal by pressed ^C after returns terminal
+ * status:
+ *
+ * require "readline"
+ *
+ * stty_save = `stty -g`.chomp
+ * trap("INT") { system "stty", stty_save; exit }
+ *
+ * while buf = Readline.readline
+ * p buf
+ * end
+ *
+ * * Ignores pressing ^C:
+ *
+ * require "readline"
+ *
+ * trap("INT", "SIG_IGN")
+ *
+ * while buf = Readline.readline
+ * p buf
+ * end
+ *
+ * Can make as follows with Readline::HISTORY constant.
+ * It does not record to the history if the inputted line is empty or
+ * the same it as last one.
+ *
+ * require "readline"
+ *
+ * while buf = Readline.readline("> ", true)
+ * # p Readline::HISTORY.to_a
+ * Readline::HISTORY.pop if /^\s*$/ =~ buf
+ *
+ * begin
+ * if Readline::HISTORY[Readline::HISTORY.length-2] == buf
+ * Readline::HISTORY.pop
+ * end
+ * rescue IndexError
+ * end
+ *
+ * # p Readline::HISTORY.to_a
+ * print "-> ", buf, "\n"
+ * end
+ */
+static VALUE
+readline_readline(int argc, VALUE *argv, VALUE self)
+{
+ VALUE tmp, add_hist, result;
+ char *prompt = NULL;
+ char *buff;
+ int status;
+
+ if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
+ OutputStringValue(tmp);
+#if USE_INSERT_IGNORE_ESCAPE
+ tmp = insert_ignore_escape(self, tmp);
+ rb_str_locktmp(tmp);
+#endif
+ prompt = RSTRING_PTR(tmp);
+ }
+
+ prepare_readline();
+
+#ifdef _WIN32
+ rl_prep_terminal(1);
+#endif
+ buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
+#if USE_INSERT_IGNORE_ESCAPE
+ if (prompt) {
+ rb_str_unlocktmp(tmp);
+ }
+#endif
+ if (status) {
+#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
+ /* restore terminal mode and signal handler*/
+#if defined HAVE_RL_FREE_LINE_STATE
+ rl_free_line_state();
+#endif
+ rl_cleanup_after_signal();
+#elif defined HAVE_RL_DEPREP_TERM_FUNCTION
+ /* restore terminal mode */
+ if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
+ (*rl_deprep_term_function)();
+ else
+#else
+ rl_deprep_terminal();
+#endif
+ rb_jump_tag(status);
+ }
+
+ if (RTEST(add_hist) && buff) {
+ add_history(buff);
+ }
+ if (buff) {
+ result = rb_locale_str_new_cstr(buff);
+ }
+ else
+ result = Qnil;
+ if (buff) free(buff);
+ return result;
+}
+
+/*
+ * call-seq:
+ * Readline.input = input
+ *
+ * Specifies a File object +input+ that is input stream for
+ * Readline.readline method.
+ */
+static VALUE
+readline_s_set_input(VALUE self, VALUE input)
+{
+ rb_io_t *ifp;
+ int fd;
+ FILE *f;
+
+ if (NIL_P(input)) {
+ clear_rl_instream();
+ }
+ else {
+ Check_Type(input, T_FILE);
+ GetOpenFile(input, ifp);
+ clear_rl_instream();
+ fd = rb_cloexec_dup(ifp->fd);
+ if (fd == -1)
+ rb_sys_fail("dup");
+ f = fdopen(fd, "r");
+ if (f == NULL) {
+ int save_errno = errno;
+ close(fd);
+ rb_syserr_fail(save_errno, "fdopen");
+ }
+ rl_instream = readline_rl_instream = f;
+ readline_instream = input;
+ }
+ return input;
+}
+
+/*
+ * call-seq:
+ * Readline.output = output
+ *
+ * Specifies a File object +output+ that is output stream for
+ * Readline.readline method.
+ */
+static VALUE
+readline_s_set_output(VALUE self, VALUE output)
+{
+ rb_io_t *ofp;
+ int fd;
+ FILE *f;
+
+ if (NIL_P(output)) {
+ clear_rl_outstream();
+ }
+ else {
+ Check_Type(output, T_FILE);
+ GetOpenFile(output, ofp);
+ clear_rl_outstream();
+ fd = rb_cloexec_dup(ofp->fd);
+ if (fd == -1)
+ rb_sys_fail("dup");
+ f = fdopen(fd, "w");
+ if (f == NULL) {
+ int save_errno = errno;
+ close(fd);
+ rb_syserr_fail(save_errno, "fdopen");
+ }
+ rl_outstream = readline_rl_outstream = f;
+ readline_outstream = output;
+ }
+ return output;
+}
+
+#if defined(HAVE_RL_PRE_INPUT_HOOK)
+/*
+ * call-seq:
+ * Readline.pre_input_hook = proc
+ *
+ * Specifies a Proc object +proc+ to call after the first prompt has
+ * been printed and just before readline starts reading input
+ * characters.
+ *
+ * See GNU Readline's rl_pre_input_hook variable.
+ *
+ * Raises ArgumentError if +proc+ does not respond to the call method.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_pre_input_hook(VALUE self, VALUE proc)
+{
+ mustbe_callable(proc);
+ return rb_ivar_set(mReadline, id_pre_input_hook, proc);
+}
+
+/*
+ * call-seq:
+ * Readline.pre_input_hook -> proc
+ *
+ * Returns a Proc object +proc+ to call after the first prompt has
+ * been printed and just before readline starts reading input
+ * characters. The default is nil.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_pre_input_hook(VALUE self)
+{
+ return rb_attr_get(mReadline, id_pre_input_hook);
+}
+
+static int
+readline_pre_input_hook(void)
+{
+ VALUE proc;
+
+ proc = rb_attr_get(mReadline, id_pre_input_hook);
+ if (!NIL_P(proc))
+ rb_funcall(proc, id_call, 0);
+ return 0;
+}
+#else
+#define readline_s_set_pre_input_hook rb_f_notimplement
+#define readline_s_get_pre_input_hook rb_f_notimplement
+#endif
+
+#if defined(HAVE_RL_INSERT_TEXT)
+/*
+ * call-seq:
+ * Readline.insert_text(string) -> self
+ *
+ * Insert text into the line at the current cursor position.
+ *
+ * See GNU Readline's rl_insert_text function.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_insert_text(VALUE self, VALUE str)
+{
+ OutputStringValue(str);
+ rl_insert_text(RSTRING_PTR(str));
+ return self;
+}
+#else
+#define readline_s_insert_text rb_f_notimplement
+#endif
+
+#if defined(HAVE_RL_DELETE_TEXT)
+RUBY_EXTERN int rl_delete_text(int, int);
+static const char *
+str_subpos(const char *ptr, const char *end, long beg, long *sublen, rb_encoding *enc)
+{
+ VALUE str = rb_enc_str_new_static(ptr, end-ptr, enc);
+ OBJ_FREEZE(str);
+ ptr = rb_str_subpos(str, beg, sublen);
+ return ptr;
+}
+
+/*
+ * call-seq:
+ * Readline.delete_text([start[, length]]) -> self
+ * Readline.delete_text(start..end) -> self
+ * Readline.delete_text() -> self
+ *
+ * Delete text between start and end in the current line.
+ *
+ * See GNU Readline's rl_delete_text function.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_delete_text(int argc, VALUE *argv, VALUE self)
+{
+ rb_check_arity(argc, 0, 2);
+ if (rl_line_buffer) {
+ const char *p, *ptr = rl_line_buffer;
+ long beg = 0, len = strlen(ptr);
+ const char *end = ptr + len;
+ rb_encoding *enc = rb_locale_encoding();
+ if (argc == 2) {
+ beg = NUM2LONG(argv[0]);
+ len = NUM2LONG(argv[1]);
+ num_pos:
+ p = str_subpos(ptr, end, beg, &len, enc);
+ if (!p) rb_raise(rb_eArgError, "invalid index");
+ beg = p - ptr;
+ }
+ else if (argc == 1) {
+ len = rb_enc_strlen(ptr, ptr + len, enc);
+ if (!rb_range_beg_len(argv[0], &beg, &len, len, 1)) {
+ beg = NUM2LONG(argv[0]);
+ goto num_pos;
+ }
+ }
+ rl_delete_text(rb_long2int(beg), rb_long2int(beg + len));
+ }
+ return self;
+}
+#else
+#define readline_s_delete_text rb_f_notimplement
+#endif
+
+#if defined(HAVE_RL_REDISPLAY)
+/*
+ * call-seq:
+ * Readline.redisplay -> self
+ *
+ * Change what's displayed on the screen to reflect the current
+ * contents.
+ *
+ * See GNU Readline's rl_redisplay function.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_redisplay(VALUE self)
+{
+ rl_redisplay();
+ return self;
+}
+#else
+#define readline_s_redisplay rb_f_notimplement
+#endif
+
+/*
+ * call-seq:
+ * Readline.completion_proc = proc
+ *
+ * Specifies a Proc object +proc+ to determine completion behavior. It
+ * should take input string and return an array of completion candidates.
+ *
+ * The default completion is used if +proc+ is nil.
+ *
+ * The String that is passed to the Proc depends on the
+ * Readline.completer_word_break_characters property. By default the word
+ * under the cursor is passed to the Proc. For example, if the input is "foo
+ * bar" then only "bar" would be passed to the completion Proc.
+ *
+ * Upon successful completion the Readline.completion_append_character will be
+ * appended to the input so the user can start working on their next argument.
+ *
+ * = Examples
+ *
+ * == Completion for a Static List
+ *
+ * require 'readline'
+ *
+ * LIST = [
+ * 'search', 'download', 'open',
+ * 'help', 'history', 'quit',
+ * 'url', 'next', 'clear',
+ * 'prev', 'past'
+ * ].sort
+ *
+ * comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) }
+ *
+ * Readline.completion_append_character = " "
+ * Readline.completion_proc = comp
+ *
+ * while line = Readline.readline('> ', true)
+ * p line
+ * end
+ *
+ * == Completion For Directory Contents
+ *
+ * require 'readline'
+ *
+ * Readline.completion_append_character = " "
+ * Readline.completion_proc = Proc.new do |str|
+ * Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
+ * end
+ *
+ * while line = Readline.readline('> ', true)
+ * p line
+ * end
+ *
+ * = Autocomplete strategies
+ *
+ * When working with auto-complete there are some strategies that work well.
+ * To get some ideas you can take a look at the
+ * completion.rb[https://git.ruby-lang.org/ruby.git/tree/lib/irb/completion.rb]
+ * file for irb.
+ *
+ * The common strategy is to take a list of possible completions and filter it
+ * down to those completions that start with the user input. In the above
+ * examples Enumerator.grep is used. The input is escaped to prevent Regexp
+ * special characters from interfering with the matching.
+ *
+ * It may also be helpful to use the Abbrev library to generate completions.
+ *
+ * Raises ArgumentError if +proc+ does not respond to the call method.
+ */
+static VALUE
+readline_s_set_completion_proc(VALUE self, VALUE proc)
+{
+ mustbe_callable(proc);
+ return rb_ivar_set(mReadline, completion_proc, proc);
+}
+
+/*
+ * call-seq:
+ * Readline.completion_proc -> proc
+ *
+ * Returns the completion Proc object.
+ */
+static VALUE
+readline_s_get_completion_proc(VALUE self)
+{
+ return rb_attr_get(mReadline, completion_proc);
+}
+
+#ifdef HAVE_RL_CHAR_IS_QUOTED_P
+/*
+ * call-seq:
+ * Readline.quoting_detection_proc = proc
+ *
+ * Specifies a Proc object +proc+ to determine if a character in the user's
+ * input is escaped. It should take the user's input and the index of the
+ * character in question as input, and return a boolean (true if the specified
+ * character is escaped).
+ *
+ * Readline will only call this proc with characters specified in
+ * +completer_quote_characters+, to discover if they indicate the end of a
+ * quoted argument, or characters specified in
+ * +completer_word_break_characters+, to discover if they indicate a break
+ * between arguments.
+ *
+ * If +completer_quote_characters+ is not set, or if the user input doesn't
+ * contain one of the +completer_quote_characters+ or a +\+ character,
+ * Readline will not attempt to use this proc at all.
+ *
+ * Raises ArgumentError if +proc+ does not respond to the call method.
+ */
+static VALUE
+readline_s_set_quoting_detection_proc(VALUE self, VALUE proc)
+{
+ mustbe_callable(proc);
+ return rb_ivar_set(mReadline, quoting_detection_proc, proc);
+}
+
+/*
+ * call-seq:
+ * Readline.quoting_detection_proc -> proc
+ *
+ * Returns the quoting detection Proc object.
+ */
+static VALUE
+readline_s_get_quoting_detection_proc(VALUE self)
+{
+ return rb_attr_get(mReadline, quoting_detection_proc);
+}
+#else
+#define readline_s_set_quoting_detection_proc rb_f_notimplement
+#define readline_s_get_quoting_detection_proc rb_f_notimplement
+#endif
+
+/*
+ * call-seq:
+ * Readline.completion_case_fold = bool
+ *
+ * Sets whether or not to ignore case on completion.
+ */
+static VALUE
+readline_s_set_completion_case_fold(VALUE self, VALUE val)
+{
+ return rb_ivar_set(mReadline, completion_case_fold, val);
+}
+
+/*
+ * call-seq:
+ * Readline.completion_case_fold -> bool
+ *
+ * Returns true if completion ignores case. If no, returns false.
+ *
+ * NOTE: Returns the same object that is specified by
+ * Readline.completion_case_fold= method.
+ *
+ * require "readline"
+ *
+ * Readline.completion_case_fold = "This is a String."
+ * p Readline.completion_case_fold # => "This is a String."
+ */
+static VALUE
+readline_s_get_completion_case_fold(VALUE self)
+{
+ return rb_attr_get(mReadline, completion_case_fold);
+}
+
+#ifdef HAVE_RL_LINE_BUFFER
+/*
+ * call-seq:
+ * Readline.line_buffer -> string
+ *
+ * Returns the full line that is being edited. This is useful from
+ * within the complete_proc for determining the context of the
+ * completion request.
+ *
+ * The length of +Readline.line_buffer+ and GNU Readline's rl_end are
+ * same.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_line_buffer(VALUE self)
+{
+ if (rl_line_buffer == NULL)
+ return Qnil;
+ return rb_locale_str_new_cstr(rl_line_buffer);
+}
+#else
+#define readline_s_get_line_buffer rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_POINT
+/*
+ * call-seq:
+ * Readline.point -> int
+ *
+ * Returns the index of the current cursor position in
+ * +Readline.line_buffer+.
+ *
+ * The index in +Readline.line_buffer+ which matches the start of
+ * input-string passed to completion_proc is computed by subtracting
+ * the length of input-string from +Readline.point+.
+ *
+ * start = (the length of input-string) - Readline.point
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_point(VALUE self)
+{
+ return INT2NUM(rl_point);
+}
+
+/*
+ * call-seq:
+ * Readline.point = int
+ *
+ * Set the index of the current cursor position in
+ * +Readline.line_buffer+.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ *
+ * See +Readline.point+.
+ */
+static VALUE
+readline_s_set_point(VALUE self, VALUE pos)
+{
+ rl_point = NUM2INT(pos);
+ return pos;
+}
+#else
+#define readline_s_get_point rb_f_notimplement
+#define readline_s_set_point rb_f_notimplement
+#endif
+
+static char **
+readline_attempted_completion_function(const char *text, int start, int end)
+{
+ VALUE proc, ary, temp;
+ char **result;
+ int case_fold;
+ long i, matches;
+ rb_encoding *enc;
+ VALUE encobj;
+
+ proc = rb_attr_get(mReadline, completion_proc);
+ if (NIL_P(proc))
+ return NULL;
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+ rl_completion_append_character = readline_completion_append_character;
+#endif
+#ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
+ rl_attempted_completion_over = 1;
+#endif
+ case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
+ ary = rb_funcall(proc, id_call, 1, rb_locale_str_new_cstr(text));
+ if (!RB_TYPE_P(ary, T_ARRAY))
+ ary = rb_Array(ary);
+ matches = RARRAY_LEN(ary);
+ if (matches == 0) return NULL;
+ result = (char**)malloc((matches + 2)*sizeof(char*));
+ if (result == NULL) rb_memerror();
+ enc = rb_locale_encoding();
+ encobj = rb_enc_from_encoding(enc);
+ for (i = 0; i < matches; i++) {
+ temp = rb_obj_as_string(RARRAY_AREF(ary, i));
+ StringValueCStr(temp); /* must be NUL-terminated */
+ rb_enc_check(encobj, temp);
+ result[i + 1] = (char*)malloc(RSTRING_LEN(temp) + 1);
+ if (result[i + 1] == NULL) rb_memerror();
+ strcpy(result[i + 1], RSTRING_PTR(temp));
+ }
+ result[matches + 1] = NULL;
+
+ if (matches == 1) {
+ result[0] = strdup(result[1]);
+ }
+ else {
+ const char *result1 = result[1];
+ long low = strlen(result1);
+
+ for (i = 1; i < matches; ++i) {
+ register int c1, c2;
+ long i1, i2, l2;
+ int n1, n2;
+ const char *p2 = result[i + 1];
+
+ l2 = strlen(p2);
+ for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
+ c1 = rb_enc_codepoint_len(result1 + i1, result1 + low, &n1, enc);
+ c2 = rb_enc_codepoint_len(p2 + i2, p2 + l2, &n2, enc);
+ if (case_fold) {
+ c1 = rb_tolower(c1);
+ c2 = rb_tolower(c2);
+ }
+ if (c1 != c2) break;
+ }
+
+ low = i1;
+ }
+ result[0] = (char*)malloc(low + 1);
+ if (result[0] == NULL) rb_memerror();
+ strncpy(result[0], result[1], low);
+ result[0][low] = '\0';
+ }
+
+ return result;
+}
+
+#ifdef HAVE_RL_CHAR_IS_QUOTED_P
+static int
+readline_char_is_quoted(char *text, int byte_index)
+{
+ VALUE proc, result, str;
+ long char_index;
+ size_t len;
+
+ proc = rb_attr_get(mReadline, quoting_detection_proc);
+ if (NIL_P(proc)) {
+ return 0;
+ }
+
+ len = strlen(text);
+ if (byte_index < 0 || len < (size_t)byte_index) {
+ rb_raise(rb_eIndexError, "invalid byte index (%d in %"PRIdSIZE")",
+ byte_index, len);
+ }
+
+ str = rb_locale_str_new(text, len);
+ char_index = rb_str_sublen(str, byte_index);
+ result = rb_funcall(proc, id_call, 2, str, LONG2FIX(char_index));
+ return RTEST(result);
+}
+#endif
+
+#ifdef HAVE_RL_SET_SCREEN_SIZE
+/*
+ * call-seq:
+ * Readline.set_screen_size(rows, columns) -> self
+ *
+ * Set terminal size to +rows+ and +columns+.
+ *
+ * See GNU Readline's rl_set_screen_size function.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns)
+{
+ rl_set_screen_size(NUM2INT(rows), NUM2INT(columns));
+ return self;
+}
+#else
+#define readline_s_set_screen_size rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_GET_SCREEN_SIZE
+/*
+ * call-seq:
+ * Readline.get_screen_size -> [rows, columns]
+ *
+ * Returns the terminal's rows and columns.
+ *
+ * See GNU Readline's rl_get_screen_size function.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_screen_size(VALUE self)
+{
+ int rows, columns;
+ VALUE res;
+
+ rl_get_screen_size(&rows, &columns);
+ res = rb_ary_new();
+ rb_ary_push(res, INT2NUM(rows));
+ rb_ary_push(res, INT2NUM(columns));
+ return res;
+}
+#else
+#define readline_s_get_screen_size rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_VI_EDITING_MODE
+RUBY_EXTERN int rl_vi_editing_mode(int, int);
+/*
+ * call-seq:
+ * Readline.vi_editing_mode -> nil
+ *
+ * Specifies VI editing mode. See the manual of GNU Readline for
+ * details of VI editing mode.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_vi_editing_mode(VALUE self)
+{
+ rl_vi_editing_mode(1,0);
+ return Qnil;
+}
+#else
+#define readline_s_vi_editing_mode rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_EDITING_MODE
+/*
+ * call-seq:
+ * Readline.vi_editing_mode? -> bool
+ *
+ * Returns true if vi mode is active. Returns false if not.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_vi_editing_mode_p(VALUE self)
+{
+ return rl_editing_mode == 0 ? Qtrue : Qfalse;
+}
+#else
+#define readline_s_vi_editing_mode_p rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_EMACS_EDITING_MODE
+RUBY_EXTERN int rl_emacs_editing_mode(int, int);
+/*
+ * call-seq:
+ * Readline.emacs_editing_mode -> nil
+ *
+ * Specifies Emacs editing mode. The default is this mode. See the
+ * manual of GNU Readline for details of Emacs editing mode.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_emacs_editing_mode(VALUE self)
+{
+ rl_emacs_editing_mode(1,0);
+ return Qnil;
+}
+#else
+#define readline_s_emacs_editing_mode rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_EDITING_MODE
+/*
+ * call-seq:
+ * Readline.emacs_editing_mode? -> bool
+ *
+ * Returns true if emacs mode is active. Returns false if not.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_emacs_editing_mode_p(VALUE self)
+{
+ return rl_editing_mode == 1 ? Qtrue : Qfalse;
+}
+#else
+#define readline_s_emacs_editing_mode_p rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+/*
+ * call-seq:
+ * Readline.completion_append_character = char
+ *
+ * Specifies a character to be appended on completion.
+ * Nothing will be appended if an empty string ("") or nil is
+ * specified.
+ *
+ * For example:
+ * require "readline"
+ *
+ * Readline.readline("> ", true)
+ * Readline.completion_append_character = " "
+ *
+ * Result:
+ * >
+ * Input "/var/li".
+ *
+ * > /var/li
+ * Press TAB key.
+ *
+ * > /var/lib
+ * Completes "b" and appends " ". So, you can continuously input "/usr".
+ *
+ * > /var/lib /usr
+ *
+ * NOTE: Only one character can be specified. When "string" is
+ * specified, sets only "s" that is the first.
+ *
+ * require "readline"
+ *
+ * Readline.completion_append_character = "string"
+ * p Readline.completion_append_character # => "s"
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_completion_append_character(VALUE self, VALUE str)
+{
+ if (NIL_P(str)) {
+ rl_completion_append_character = '\0';
+ }
+ else {
+ OutputStringValue(str);
+ if (RSTRING_LEN(str) == 0) {
+ rl_completion_append_character = '\0';
+ } else {
+ rl_completion_append_character = RSTRING_PTR(str)[0];
+ }
+ }
+ return self;
+}
+#else
+#define readline_s_set_completion_append_character rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+/*
+ * call-seq:
+ * Readline.completion_append_character -> char
+ *
+ * Returns a string containing a character to be appended on
+ * completion. The default is a space (" ").
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_completion_append_character(VALUE self)
+{
+ char buf[1];
+
+ if (rl_completion_append_character == '\0')
+ return Qnil;
+
+ buf[0] = (char) rl_completion_append_character;
+ return rb_locale_str_new(buf, 1);
+}
+#else
+#define readline_s_get_completion_append_character rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETION_QUOTE_CHARACTER
+/*
+ * call-seq:
+ * Readline.completion_quote_character -> char
+ *
+ * When called during a completion (e.g. from within your completion_proc),
+ * it will return a string containing the character used to quote the
+ * argument being completed, or nil if the argument is unquoted.
+ *
+ * When called at other times, it will always return nil.
+ *
+ * Note that Readline.completer_quote_characters must be set,
+ * or this method will always return nil.
+ */
+static VALUE
+readline_s_get_completion_quote_character(VALUE self)
+{
+ char buf[1];
+
+ if (rl_completion_quote_character == '\0')
+ return Qnil;
+
+ buf[0] = (char) rl_completion_quote_character;
+ return rb_locale_str_new(buf, 1);
+}
+#else
+#define readline_s_get_completion_quote_character rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
+/*
+ * call-seq:
+ * Readline.basic_word_break_characters = string
+ *
+ * Sets the basic list of characters that signal a break between words
+ * for the completer routine. The default is the characters which
+ * break words for completion in Bash: " \t\n\"\\'`@$><=;|&{(".
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_basic_word_break_characters(VALUE self, VALUE str)
+{
+ static char *basic_word_break_characters = NULL;
+
+ OutputStringValue(str);
+ if (basic_word_break_characters == NULL) {
+ basic_word_break_characters =
+ ALLOC_N(char, RSTRING_LEN(str) + 1);
+ }
+ else {
+ REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
+ }
+ strncpy(basic_word_break_characters,
+ RSTRING_PTR(str), RSTRING_LEN(str));
+ basic_word_break_characters[RSTRING_LEN(str)] = '\0';
+ rl_basic_word_break_characters = basic_word_break_characters;
+ return self;
+}
+#else
+#define readline_s_set_basic_word_break_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
+/*
+ * call-seq:
+ * Readline.basic_word_break_characters -> string
+ *
+ * Gets the basic list of characters that signal a break between words
+ * for the completer routine.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_basic_word_break_characters(VALUE self)
+{
+ if (rl_basic_word_break_characters == NULL)
+ return Qnil;
+ return rb_locale_str_new_cstr(rl_basic_word_break_characters);
+}
+#else
+#define readline_s_get_basic_word_break_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
+/*
+ * call-seq:
+ * Readline.completer_word_break_characters = string
+ *
+ * Sets the basic list of characters that signal a break between words
+ * for rl_complete_internal(). The default is the value of
+ * Readline.basic_word_break_characters.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_completer_word_break_characters(VALUE self, VALUE str)
+{
+ static char *completer_word_break_characters = NULL;
+
+ OutputStringValue(str);
+ if (completer_word_break_characters == NULL) {
+ completer_word_break_characters =
+ ALLOC_N(char, RSTRING_LEN(str) + 1);
+ }
+ else {
+ REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
+ }
+ strncpy(completer_word_break_characters,
+ RSTRING_PTR(str), RSTRING_LEN(str));
+ completer_word_break_characters[RSTRING_LEN(str)] = '\0';
+ rl_completer_word_break_characters = completer_word_break_characters;
+ return self;
+}
+#else
+#define readline_s_set_completer_word_break_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
+/*
+ * call-seq:
+ * Readline.completer_word_break_characters -> string
+ *
+ * Gets the basic list of characters that signal a break between words
+ * for rl_complete_internal().
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_completer_word_break_characters(VALUE self)
+{
+ if (rl_completer_word_break_characters == NULL)
+ return Qnil;
+ return rb_locale_str_new_cstr(rl_completer_word_break_characters);
+}
+#else
+#define readline_s_get_completer_word_break_characters rb_f_notimplement
+#endif
+
+#if defined(HAVE_RL_SPECIAL_PREFIXES)
+/*
+ * call-seq:
+ * Readline.special_prefixes = string
+ *
+ * Sets the list of characters that are word break characters, but
+ * should be left in text when it is passed to the completion
+ * function. Programs can use this to help determine what kind of
+ * completing to do. For instance, Bash sets this variable to "$@" so
+ * that it can complete shell variables and hostnames.
+ *
+ * See GNU Readline's rl_special_prefixes variable.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_special_prefixes(VALUE self, VALUE str)
+{
+ if (!NIL_P(str)) {
+ OutputStringValue(str);
+ str = rb_str_dup_frozen(str);
+ rb_obj_hide(str);
+ }
+ rb_ivar_set(mReadline, id_special_prefixes, str);
+ if (NIL_P(str)) {
+ rl_special_prefixes = NULL;
+ }
+ else {
+ rl_special_prefixes = RSTRING_PTR(str);
+ }
+ return self;
+}
+
+/*
+ * call-seq:
+ * Readline.special_prefixes -> string
+ *
+ * Gets the list of characters that are word break characters, but
+ * should be left in text when it is passed to the completion
+ * function.
+ *
+ * See GNU Readline's rl_special_prefixes variable.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_special_prefixes(VALUE self)
+{
+ VALUE str;
+ if (rl_special_prefixes == NULL) return Qnil;
+ str = rb_ivar_get(mReadline, id_special_prefixes);
+ if (!NIL_P(str)) {
+ str = rb_str_dup_frozen(str);
+ rb_obj_reveal(str, rb_cString);
+ }
+ return str;
+}
+#else
+#define readline_s_set_special_prefixes rb_f_notimplement
+#define readline_s_get_special_prefixes rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
+/*
+ * call-seq:
+ * Readline.basic_quote_characters = string
+ *
+ * Sets a list of quote characters which can cause a word break.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_basic_quote_characters(VALUE self, VALUE str)
+{
+ static char *basic_quote_characters = NULL;
+
+ OutputStringValue(str);
+ if (basic_quote_characters == NULL) {
+ basic_quote_characters =
+ ALLOC_N(char, RSTRING_LEN(str) + 1);
+ }
+ else {
+ REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
+ }
+ strncpy(basic_quote_characters,
+ RSTRING_PTR(str), RSTRING_LEN(str));
+ basic_quote_characters[RSTRING_LEN(str)] = '\0';
+ rl_basic_quote_characters = basic_quote_characters;
+
+ return self;
+}
+#else
+#define readline_s_set_basic_quote_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
+/*
+ * call-seq:
+ * Readline.basic_quote_characters -> string
+ *
+ * Gets a list of quote characters which can cause a word break.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_basic_quote_characters(VALUE self)
+{
+ if (rl_basic_quote_characters == NULL)
+ return Qnil;
+ return rb_locale_str_new_cstr(rl_basic_quote_characters);
+}
+#else
+#define readline_s_get_basic_quote_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
+/*
+ * call-seq:
+ * Readline.completer_quote_characters = string
+ *
+ * Sets a list of characters which can be used to quote a substring of
+ * the line. Completion occurs on the entire substring, and within
+ * the substring Readline.completer_word_break_characters are treated
+ * as any other character, unless they also appear within this list.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_completer_quote_characters(VALUE self, VALUE str)
+{
+ static char *completer_quote_characters = NULL;
+
+ OutputStringValue(str);
+ if (completer_quote_characters == NULL) {
+ completer_quote_characters =
+ ALLOC_N(char, RSTRING_LEN(str) + 1);
+ }
+ else {
+ REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
+ }
+ strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
+ completer_quote_characters[RSTRING_LEN(str)] = '\0';
+ rl_completer_quote_characters = completer_quote_characters;
+
+ return self;
+}
+#else
+#define readline_s_set_completer_quote_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
+/*
+ * call-seq:
+ * Readline.completer_quote_characters -> string
+ *
+ * Gets a list of characters which can be used to quote a substring of
+ * the line.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_completer_quote_characters(VALUE self)
+{
+ if (rl_completer_quote_characters == NULL)
+ return Qnil;
+ return rb_locale_str_new_cstr(rl_completer_quote_characters);
+}
+#else
+#define readline_s_get_completer_quote_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
+/*
+ * call-seq:
+ * Readline.filename_quote_characters = string
+ *
+ * Sets a list of characters that cause a filename to be quoted by the completer
+ * when they appear in a completed filename. The default is nil.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_set_filename_quote_characters(VALUE self, VALUE str)
+{
+ static char *filename_quote_characters = NULL;
+
+ OutputStringValue(str);
+ if (filename_quote_characters == NULL) {
+ filename_quote_characters =
+ ALLOC_N(char, RSTRING_LEN(str) + 1);
+ }
+ else {
+ REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
+ }
+ strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
+ filename_quote_characters[RSTRING_LEN(str)] = '\0';
+ rl_filename_quote_characters = filename_quote_characters;
+
+ return self;
+}
+#else
+#define readline_s_set_filename_quote_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
+/*
+ * call-seq:
+ * Readline.filename_quote_characters -> string
+ *
+ * Gets a list of characters that cause a filename to be quoted by the completer
+ * when they appear in a completed filename.
+ *
+ * Raises NotImplementedError if the using readline library does not support.
+ */
+static VALUE
+readline_s_get_filename_quote_characters(VALUE self)
+{
+ if (rl_filename_quote_characters == NULL)
+ return Qnil;
+ return rb_locale_str_new_cstr(rl_filename_quote_characters);
+}
+#else
+#define readline_s_get_filename_quote_characters rb_f_notimplement
+#endif
+
+#ifdef HAVE_RL_REFRESH_LINE
+RUBY_EXTERN int rl_refresh_line(int, int);
+/*
+ * call-seq:
+ * Readline.refresh_line -> nil
+ *
+ * Clear the current input line.
+ */
+static VALUE
+readline_s_refresh_line(VALUE self)
+{
+ prepare_readline();
+ rl_refresh_line(0, 0);
+ return Qnil;
+}
+#else
+#define readline_s_refresh_line rb_f_notimplement
+#endif
+
+static VALUE
+hist_to_s(VALUE self)
+{
+ return rb_str_new_cstr("HISTORY");
+}
+
+static int
+history_get_offset_history_base(int offset)
+{
+ return history_base + offset;
+}
+
+static int
+history_get_offset_0(int offset)
+{
+ return offset;
+}
+
+static VALUE
+hist_get(VALUE self, VALUE index)
+{
+ HIST_ENTRY *entry = NULL;
+ int i;
+
+ i = NUM2INT(index);
+ if (i < 0) {
+ i += history_length;
+ }
+ if (i >= 0) {
+ entry = history_get(history_get_offset_func(i));
+ }
+ if (entry == NULL) {
+ rb_raise(rb_eIndexError, "invalid index");
+ }
+ return rb_locale_str_new_cstr(entry->line);
+}
+
+#ifdef HAVE_REPLACE_HISTORY_ENTRY
+static VALUE
+hist_set(VALUE self, VALUE index, VALUE str)
+{
+ HIST_ENTRY *entry = NULL;
+ int i;
+
+ i = NUM2INT(index);
+ OutputStringValue(str);
+ if (i < 0) {
+ i += history_length;
+ }
+ if (i >= 0) {
+ entry = replace_history_entry(history_replace_offset_func(i), RSTRING_PTR(str), NULL);
+ }
+ if (entry == NULL) {
+ rb_raise(rb_eIndexError, "invalid index");
+ }
+ return str;
+}
+#else
+#define hist_set rb_f_notimplement
+#endif
+
+static VALUE
+hist_push(VALUE self, VALUE str)
+{
+ OutputStringValue(str);
+ add_history(RSTRING_PTR(str));
+ return self;
+}
+
+static VALUE
+hist_push_method(int argc, VALUE *argv, VALUE self)
+{
+ VALUE str;
+
+ while (argc--) {
+ str = *argv++;
+ OutputStringValue(str);
+ add_history(RSTRING_PTR(str));
+ }
+ return self;
+}
+
+static VALUE
+rb_remove_history(int index)
+{
+#ifdef HAVE_REMOVE_HISTORY
+ HIST_ENTRY *entry;
+ VALUE val;
+
+ entry = remove_history(index);
+ if (entry) {
+ val = rb_locale_str_new_cstr(entry->line);
+ free((void *) entry->line);
+ free(entry);
+ return val;
+ }
+ return Qnil;
+#else
+ rb_notimplement();
+
+ UNREACHABLE_RETURN(Qnil);
+#endif
+}
+
+static VALUE
+hist_pop(VALUE self)
+{
+ if (history_length > 0) {
+ return rb_remove_history(history_length - 1);
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE
+hist_shift(VALUE self)
+{
+ if (history_length > 0) {
+ return rb_remove_history(0);
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE
+hist_each(VALUE self)
+{
+ HIST_ENTRY *entry;
+ int i;
+
+ RETURN_ENUMERATOR(self, 0, 0);
+
+ for (i = 0; i < history_length; i++) {
+ entry = history_get(history_get_offset_func(i));
+ if (entry == NULL)
+ break;
+ rb_yield(rb_locale_str_new_cstr(entry->line));
+ }
+ return self;
+}
+
+static VALUE
+hist_length(VALUE self)
+{
+ return INT2NUM(history_length);
+}
+
+static VALUE
+hist_empty_p(VALUE self)
+{
+ return history_length == 0 ? Qtrue : Qfalse;
+}
+
+static VALUE
+hist_delete_at(VALUE self, VALUE index)
+{
+ int i;
+
+ i = NUM2INT(index);
+ if (i < 0)
+ i += history_length;
+ if (i < 0 || i > history_length - 1) {
+ rb_raise(rb_eIndexError, "invalid index");
+ }
+ return rb_remove_history(i);
+}
+
+#ifdef HAVE_CLEAR_HISTORY
+static VALUE
+hist_clear(VALUE self)
+{
+ clear_history();
+ return self;
+}
+#else
+#define hist_clear rb_f_notimplement
+#endif
+
+static VALUE
+filename_completion_proc_call(VALUE self, VALUE str)
+{
+ VALUE result;
+ char **matches;
+ int i;
+
+ matches = rl_completion_matches(StringValuePtr(str),
+ rl_filename_completion_function);
+ if (matches) {
+ result = rb_ary_new();
+ for (i = 0; matches[i]; i++) {
+ rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
+ free(matches[i]);
+ }
+ free(matches);
+ if (RARRAY_LEN(result) >= 2)
+ rb_ary_shift(result);
+ }
+ else {
+ result = Qnil;
+ }
+ return result;
+}
+
+static VALUE
+username_completion_proc_call(VALUE self, VALUE str)
+{
+ VALUE result;
+ char **matches;
+ int i;
+
+ matches = rl_completion_matches(StringValuePtr(str),
+ rl_username_completion_function);
+ if (matches) {
+ result = rb_ary_new();
+ for (i = 0; matches[i]; i++) {
+ rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
+ free(matches[i]);
+ }
+ free(matches);
+ if (RARRAY_LEN(result) >= 2)
+ rb_ary_shift(result);
+ }
+ else {
+ result = Qnil;
+ }
+ return result;
+}
+
+#ifdef HAVE_RL_CATCH_SIGNALS
+RUBY_EXTERN int rl_catch_signals;
+#endif
+#ifdef HAVE_RL_CLEAR_SIGNALS
+RUBY_EXTERN int rl_clear_signals(void);
+#endif
+
+#undef rb_intern
+void
+Init_readline(void)
+{
+ VALUE history, fcomp, ucomp, version;
+
+ /* Allow conditional parsing of the ~/.inputrc file. */
+ rl_readline_name = (char *)"Ruby";
+
+#if defined HAVE_RL_GETC_FUNCTION
+ /* libedit check rl_getc_function only when rl_initialize() is called, */
+ /* and using_history() call rl_initialize(). */
+ /* This assignment should be placed before using_history() */
+ rl_getc_function = readline_getc;
+#elif defined HAVE_RL_EVENT_HOOK
+ rl_event_hook = readline_event;
+#endif
+
+ using_history();
+
+ id_call = rb_intern("call");
+ completion_proc = rb_intern(COMPLETION_PROC);
+ completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
+#if defined(HAVE_RL_PRE_INPUT_HOOK)
+ id_pre_input_hook = rb_intern("pre_input_hook");
+#endif
+#if defined(HAVE_RL_SPECIAL_PREFIXES)
+ id_special_prefixes = rb_intern("special_prefixes");
+#endif
+#if defined HAVE_RL_CHAR_IS_QUOTED_P
+ quoting_detection_proc = rb_intern(QUOTING_DETECTION_PROC);
+#endif
+
+ mReadline = rb_define_module("Readline");
+ rb_define_module_function(mReadline, "readline",
+ readline_readline, -1);
+ rb_define_singleton_method(mReadline, "input=",
+ readline_s_set_input, 1);
+ rb_define_singleton_method(mReadline, "output=",
+ readline_s_set_output, 1);
+ rb_define_singleton_method(mReadline, "completion_proc=",
+ readline_s_set_completion_proc, 1);
+ rb_define_singleton_method(mReadline, "completion_proc",
+ readline_s_get_completion_proc, 0);
+ rb_define_singleton_method(mReadline, "quoting_detection_proc=",
+ readline_s_set_quoting_detection_proc, 1);
+ rb_define_singleton_method(mReadline, "quoting_detection_proc",
+ readline_s_get_quoting_detection_proc, 0);
+ rb_define_singleton_method(mReadline, "completion_case_fold=",
+ readline_s_set_completion_case_fold, 1);
+ rb_define_singleton_method(mReadline, "completion_case_fold",
+ readline_s_get_completion_case_fold, 0);
+ rb_define_singleton_method(mReadline, "line_buffer",
+ readline_s_get_line_buffer, 0);
+ rb_define_singleton_method(mReadline, "point",
+ readline_s_get_point, 0);
+ rb_define_singleton_method(mReadline, "point=",
+ readline_s_set_point, 1);
+ rb_define_singleton_method(mReadline, "set_screen_size",
+ readline_s_set_screen_size, 2);
+ rb_define_singleton_method(mReadline, "get_screen_size",
+ readline_s_get_screen_size, 0);
+ rb_define_singleton_method(mReadline, "vi_editing_mode",
+ readline_s_vi_editing_mode, 0);
+ rb_define_singleton_method(mReadline, "vi_editing_mode?",
+ readline_s_vi_editing_mode_p, 0);
+ rb_define_singleton_method(mReadline, "emacs_editing_mode",
+ readline_s_emacs_editing_mode, 0);
+ rb_define_singleton_method(mReadline, "emacs_editing_mode?",
+ readline_s_emacs_editing_mode_p, 0);
+ rb_define_singleton_method(mReadline, "completion_append_character=",
+ readline_s_set_completion_append_character, 1);
+ rb_define_singleton_method(mReadline, "completion_append_character",
+ readline_s_get_completion_append_character, 0);
+ rb_define_singleton_method(mReadline, "completion_quote_character",
+ readline_s_get_completion_quote_character, 0);
+ rb_define_singleton_method(mReadline, "basic_word_break_characters=",
+ readline_s_set_basic_word_break_characters, 1);
+ rb_define_singleton_method(mReadline, "basic_word_break_characters",
+ readline_s_get_basic_word_break_characters, 0);
+ rb_define_singleton_method(mReadline, "completer_word_break_characters=",
+ readline_s_set_completer_word_break_characters, 1);
+ rb_define_singleton_method(mReadline, "completer_word_break_characters",
+ readline_s_get_completer_word_break_characters, 0);
+ rb_define_singleton_method(mReadline, "basic_quote_characters=",
+ readline_s_set_basic_quote_characters, 1);
+ rb_define_singleton_method(mReadline, "basic_quote_characters",
+ readline_s_get_basic_quote_characters, 0);
+ rb_define_singleton_method(mReadline, "completer_quote_characters=",
+ readline_s_set_completer_quote_characters, 1);
+ rb_define_singleton_method(mReadline, "completer_quote_characters",
+ readline_s_get_completer_quote_characters, 0);
+ rb_define_singleton_method(mReadline, "filename_quote_characters=",
+ readline_s_set_filename_quote_characters, 1);
+ rb_define_singleton_method(mReadline, "filename_quote_characters",
+ readline_s_get_filename_quote_characters, 0);
+ rb_define_singleton_method(mReadline, "refresh_line",
+ readline_s_refresh_line, 0);
+ rb_define_singleton_method(mReadline, "pre_input_hook=",
+ readline_s_set_pre_input_hook, 1);
+ rb_define_singleton_method(mReadline, "pre_input_hook",
+ readline_s_get_pre_input_hook, 0);
+ rb_define_singleton_method(mReadline, "insert_text",
+ readline_s_insert_text, 1);
+ rb_define_singleton_method(mReadline, "delete_text",
+ readline_s_delete_text, -1);
+ rb_define_singleton_method(mReadline, "redisplay",
+ readline_s_redisplay, 0);
+ rb_define_singleton_method(mReadline, "special_prefixes=",
+ readline_s_set_special_prefixes, 1);
+ rb_define_singleton_method(mReadline, "special_prefixes",
+ readline_s_get_special_prefixes, 0);
+
+#if USE_INSERT_IGNORE_ESCAPE
+ id_orig_prompt = rb_intern("orig_prompt");
+ id_last_prompt = rb_intern("last_prompt");
+#endif
+
+ history = rb_obj_alloc(rb_cObject);
+ rb_extend_object(history, rb_mEnumerable);
+ rb_define_singleton_method(history,"to_s", hist_to_s, 0);
+ rb_define_singleton_method(history,"[]", hist_get, 1);
+ rb_define_singleton_method(history,"[]=", hist_set, 2);
+ rb_define_singleton_method(history,"<<", hist_push, 1);
+ rb_define_singleton_method(history,"push", hist_push_method, -1);
+ rb_define_singleton_method(history,"pop", hist_pop, 0);
+ rb_define_singleton_method(history,"shift", hist_shift, 0);
+ rb_define_singleton_method(history,"each", hist_each, 0);
+ rb_define_singleton_method(history,"length", hist_length, 0);
+ rb_define_singleton_method(history,"size", hist_length, 0);
+ rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
+ rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
+ rb_define_singleton_method(history,"clear", hist_clear, 0);
+
+ /*
+ * The history buffer. It extends Enumerable module, so it behaves
+ * just like an array.
+ * For example, gets the fifth content that the user input by
+ * <code>HISTORY[4]</code>.
+ */
+ rb_define_const(mReadline, "HISTORY", history);
+
+ fcomp = rb_obj_alloc(rb_cObject);
+ rb_define_singleton_method(fcomp, "call",
+ filename_completion_proc_call, 1);
+ /*
+ * The Object with the call method that is a completion for filename.
+ * This is sets by Readline.completion_proc= method.
+ */
+ rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
+
+ ucomp = rb_obj_alloc(rb_cObject);
+ rb_define_singleton_method(ucomp, "call",
+ username_completion_proc_call, 1);
+ /*
+ * The Object with the call method that is a completion for usernames.
+ * This is sets by Readline.completion_proc= method.
+ */
+ rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
+ history_get_offset_func = history_get_offset_history_base;
+ history_replace_offset_func = history_get_offset_0;
+#if defined HAVE_RL_LIBRARY_VERSION
+ version = rb_str_new_cstr(rl_library_version);
+#if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
+ if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,
+ strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) {
+ prepare_readline();
+ add_history("1");
+ if (history_get(history_get_offset_func(0)) == NULL) {
+ history_get_offset_func = history_get_offset_0;
+ }
+#ifdef HAVE_REPLACE_HISTORY_ENTRY
+ if (replace_history_entry(0, "a", NULL) == NULL) {
+ history_replace_offset_func = history_get_offset_history_base;
+ }
+#endif
+#ifdef HAVE_CLEAR_HISTORY
+ clear_history();
+#else
+ {
+ HIST_ENTRY *entry = remove_history(0);
+ if (entry) {
+ free((char *)entry->line);
+ free(entry);
+ }
+ }
+#endif
+ }
+#endif
+#else
+ version = rb_str_new_cstr("2.0 or prior version");
+#endif
+ /* Version string of GNU Readline or libedit. */
+ rb_define_const(mReadline, "VERSION", version);
+
+ rl_attempted_completion_function = readline_attempted_completion_function;
+#if defined(HAVE_RL_PRE_INPUT_HOOK)
+ rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook;
+#endif
+#if defined HAVE_RL_CHAR_IS_QUOTED_P
+ rl_char_is_quoted_p = &readline_char_is_quoted;
+#endif
+#ifdef HAVE_RL_CATCH_SIGNALS
+ rl_catch_signals = 0;
+#endif
+#ifdef HAVE_RL_CLEAR_SIGNALS
+ rl_clear_signals();
+#endif
+
+ rb_gc_register_address(&readline_instream);
+ rb_gc_register_address(&readline_outstream);
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * end:
+ */
diff --git a/ext/ripper/README b/ext/ripper/README
index 70fa208920..2ae2470e13 100644
--- a/ext/ripper/README
+++ b/ext/ripper/README
@@ -13,6 +13,7 @@ Requirements
------------
* ruby 1.9 (support CVS HEAD only)
+ * bison 1.28 or later (Other yaccs do not work)
Usage
-----
diff --git a/ext/ripper/depend b/ext/ripper/depend
index a18b67abe3..856283e177 100644
--- a/ext/ripper/depend
+++ b/ext/ripper/depend
@@ -1,26 +1,27 @@
GEN = $(srcdir)/tools/generate.rb
SRC1 = $(top_srcdir)/parse.y
SRC2 = $(srcdir)/eventids2.c
-BISON = $(BASERUBY) $(top_srcdir)/tool/lrama/exe/lrama
.SUFFIXES: .y
-src: ripper.c ripper_init.c eventids1.c eventids1.h eventids2table.c
-ripper.c ripper_init.c eventids1.c eventids1.h eventids2table.c: depend
+src: ripper.c eventids1.c eventids2table.c
ripper.o: ripper.c
.y.c:
$(ECHO) compiling compiler $<
- $(Q) $(BISON) -t -v -o$@ - $< < $<
+ $(Q) $(BISON) -t -v -oy.tab.c $<
+ $(Q) sed -e "/^#/s!y\.tab\.c!$@!" -f $(top_srcdir)/tool/ytab.sed y.tab.c > $@
+ @$(RM) y.tab.c
all: check
static: check
ripper.y: $(srcdir)/tools/preproc.rb $(srcdir)/tools/dsl.rb $(top_srcdir)/parse.y $(top_srcdir)/defs/id.def
$(ECHO) extracting $@ from $(top_srcdir)/parse.y
- $(Q) $(RUBY) $(top_srcdir)/tool/id2token.rb $(top_srcdir)/parse.y | \
- $(RUBY) $(srcdir)/tools/preproc.rb --output=$@ - ripper.y
+ $(Q) $(RUBY) $(top_srcdir)/tool/id2token.rb $(top_srcdir)/parse.y > ripper.tmp.y
+ $(Q) $(RUBY) $(srcdir)/tools/preproc.rb ripper.tmp.y --output=$@
+ $(Q) $(RM) ripper.tmp.y
check: .eventids2-check
@@ -29,10 +30,6 @@ check: .eventids2-check
$(Q) $(RUBY) $(GEN) --mode=check --ids1src=$(SRC1) --ids2src=$(SRC2)
@exit > $@
-eventids1.h: $(GEN) $(srcdir)/tools/dsl.rb $(SRC1)
- $(ECHO) generating $@ from $(SRC1)
- $(Q) $(RUBY) $(GEN) --mode=eventids1_h --ids1src=$(SRC1) --output=$@
-
eventids1.c: $(GEN) $(srcdir)/tools/dsl.rb $(SRC1)
$(ECHO) generating $@ from $(SRC1)
$(Q) $(RUBY) $(GEN) --mode=eventids1 --ids1src=$(SRC1) --output=$@
@@ -41,10 +38,6 @@ eventids2table.c: $(GEN) $(srcdir)/tools/dsl.rb $(SRC2)
$(ECHO) generating $@ from $(SRC2)
$(Q) $(RUBY) $(GEN) --mode=eventids2table --ids2src=$(SRC2) --output=$@
-ripper_init.c: $(srcdir)/ripper_init.c.tmpl ripper.y $(srcdir)/tools/preproc.rb $(top_srcdir)/internal/ruby_parser.h
- $(ECHO) generating $@ from $(srcdir)/ripper_init.c.tmpl
- $(Q) $(RUBY) $(srcdir)/tools/preproc.rb --output=$@ --template=$(srcdir)/ripper_init.c.tmpl $(top_srcdir)/internal/ruby_parser.h
-
# Entries for Ripper maintainer
preproc: ripper.E
@@ -53,347 +46,10 @@ ripper.E: ripper.c
$(Q) $(CC) -E $(INCFLAGS) $(CPPFLAGS) $< | $(RUBY) $(srcdir)/tools/strip.rb > $@
# AUTOGENERATED DEPENDENCIES START
-eventids1.o: $(RUBY_EXTCONF_H)
-eventids1.o: $(arch_hdrdir)/ruby/config.h
-eventids1.o: $(hdrdir)/ruby/assert.h
-eventids1.o: $(hdrdir)/ruby/backward.h
-eventids1.o: $(hdrdir)/ruby/backward/2/assume.h
-eventids1.o: $(hdrdir)/ruby/backward/2/attributes.h
-eventids1.o: $(hdrdir)/ruby/backward/2/bool.h
-eventids1.o: $(hdrdir)/ruby/backward/2/inttypes.h
-eventids1.o: $(hdrdir)/ruby/backward/2/limits.h
-eventids1.o: $(hdrdir)/ruby/backward/2/long_long.h
-eventids1.o: $(hdrdir)/ruby/backward/2/stdalign.h
-eventids1.o: $(hdrdir)/ruby/backward/2/stdarg.h
-eventids1.o: $(hdrdir)/ruby/defines.h
-eventids1.o: $(hdrdir)/ruby/intern.h
-eventids1.o: $(hdrdir)/ruby/internal/abi.h
-eventids1.o: $(hdrdir)/ruby/internal/anyargs.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-eventids1.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-eventids1.o: $(hdrdir)/ruby/internal/assume.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/artificial.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/cold.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/const.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/error.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/format.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/noalias.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/noinline.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/pure.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/restrict.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/warning.h
-eventids1.o: $(hdrdir)/ruby/internal/attr/weakref.h
-eventids1.o: $(hdrdir)/ruby/internal/cast.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-eventids1.o: $(hdrdir)/ruby/internal/compiler_since.h
-eventids1.o: $(hdrdir)/ruby/internal/config.h
-eventids1.o: $(hdrdir)/ruby/internal/constant_p.h
-eventids1.o: $(hdrdir)/ruby/internal/core.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rarray.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rbasic.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rbignum.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rclass.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rdata.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rfile.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rhash.h
-eventids1.o: $(hdrdir)/ruby/internal/core/robject.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rregexp.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rstring.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rstruct.h
-eventids1.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-eventids1.o: $(hdrdir)/ruby/internal/ctype.h
-eventids1.o: $(hdrdir)/ruby/internal/dllexport.h
-eventids1.o: $(hdrdir)/ruby/internal/dosish.h
-eventids1.o: $(hdrdir)/ruby/internal/error.h
-eventids1.o: $(hdrdir)/ruby/internal/eval.h
-eventids1.o: $(hdrdir)/ruby/internal/event.h
-eventids1.o: $(hdrdir)/ruby/internal/fl_type.h
-eventids1.o: $(hdrdir)/ruby/internal/gc.h
-eventids1.o: $(hdrdir)/ruby/internal/glob.h
-eventids1.o: $(hdrdir)/ruby/internal/globals.h
-eventids1.o: $(hdrdir)/ruby/internal/has/attribute.h
-eventids1.o: $(hdrdir)/ruby/internal/has/builtin.h
-eventids1.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-eventids1.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-eventids1.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-eventids1.o: $(hdrdir)/ruby/internal/has/extension.h
-eventids1.o: $(hdrdir)/ruby/internal/has/feature.h
-eventids1.o: $(hdrdir)/ruby/internal/has/warning.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/array.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/bignum.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/class.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/compar.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/complex.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/cont.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/dir.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/enum.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/error.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/eval.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/file.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/hash.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/io.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/load.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/marshal.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/numeric.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/object.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/parse.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/proc.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/process.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/random.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/range.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/rational.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/re.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/ruby.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/select.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/signal.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/string.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/struct.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/thread.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/time.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/variable.h
-eventids1.o: $(hdrdir)/ruby/internal/intern/vm.h
-eventids1.o: $(hdrdir)/ruby/internal/interpreter.h
-eventids1.o: $(hdrdir)/ruby/internal/iterator.h
-eventids1.o: $(hdrdir)/ruby/internal/memory.h
-eventids1.o: $(hdrdir)/ruby/internal/method.h
-eventids1.o: $(hdrdir)/ruby/internal/module.h
-eventids1.o: $(hdrdir)/ruby/internal/newobj.h
-eventids1.o: $(hdrdir)/ruby/internal/scan_args.h
-eventids1.o: $(hdrdir)/ruby/internal/special_consts.h
-eventids1.o: $(hdrdir)/ruby/internal/static_assert.h
-eventids1.o: $(hdrdir)/ruby/internal/stdalign.h
-eventids1.o: $(hdrdir)/ruby/internal/stdbool.h
-eventids1.o: $(hdrdir)/ruby/internal/symbol.h
-eventids1.o: $(hdrdir)/ruby/internal/value.h
-eventids1.o: $(hdrdir)/ruby/internal/value_type.h
-eventids1.o: $(hdrdir)/ruby/internal/variable.h
-eventids1.o: $(hdrdir)/ruby/internal/warning_push.h
-eventids1.o: $(hdrdir)/ruby/internal/xmalloc.h
-eventids1.o: $(hdrdir)/ruby/missing.h
-eventids1.o: $(hdrdir)/ruby/ruby.h
-eventids1.o: $(hdrdir)/ruby/st.h
-eventids1.o: $(hdrdir)/ruby/subst.h
-eventids1.o: eventids1.h
-eventids1.o: {$(VPATH)}eventids1.c
-eventids1.o: {$(VPATH)}eventids1.h
-eventids2.o: $(RUBY_EXTCONF_H)
-eventids2.o: $(arch_hdrdir)/ruby/config.h
-eventids2.o: $(hdrdir)/ruby/assert.h
-eventids2.o: $(hdrdir)/ruby/backward.h
-eventids2.o: $(hdrdir)/ruby/backward/2/assume.h
-eventids2.o: $(hdrdir)/ruby/backward/2/attributes.h
-eventids2.o: $(hdrdir)/ruby/backward/2/bool.h
-eventids2.o: $(hdrdir)/ruby/backward/2/inttypes.h
-eventids2.o: $(hdrdir)/ruby/backward/2/limits.h
-eventids2.o: $(hdrdir)/ruby/backward/2/long_long.h
-eventids2.o: $(hdrdir)/ruby/backward/2/stdalign.h
-eventids2.o: $(hdrdir)/ruby/backward/2/stdarg.h
-eventids2.o: $(hdrdir)/ruby/defines.h
-eventids2.o: $(hdrdir)/ruby/encoding.h
-eventids2.o: $(hdrdir)/ruby/intern.h
-eventids2.o: $(hdrdir)/ruby/internal/abi.h
-eventids2.o: $(hdrdir)/ruby/internal/anyargs.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-eventids2.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-eventids2.o: $(hdrdir)/ruby/internal/assume.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/artificial.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/cold.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/const.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/error.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/format.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/noalias.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/noinline.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/pure.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/restrict.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/warning.h
-eventids2.o: $(hdrdir)/ruby/internal/attr/weakref.h
-eventids2.o: $(hdrdir)/ruby/internal/cast.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-eventids2.o: $(hdrdir)/ruby/internal/compiler_since.h
-eventids2.o: $(hdrdir)/ruby/internal/config.h
-eventids2.o: $(hdrdir)/ruby/internal/constant_p.h
-eventids2.o: $(hdrdir)/ruby/internal/core.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rarray.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rbasic.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rbignum.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rclass.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rdata.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rfile.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rhash.h
-eventids2.o: $(hdrdir)/ruby/internal/core/robject.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rregexp.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rstring.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rstruct.h
-eventids2.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-eventids2.o: $(hdrdir)/ruby/internal/ctype.h
-eventids2.o: $(hdrdir)/ruby/internal/dllexport.h
-eventids2.o: $(hdrdir)/ruby/internal/dosish.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/coderange.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/ctype.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/encoding.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/pathname.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/re.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/string.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/symbol.h
-eventids2.o: $(hdrdir)/ruby/internal/encoding/transcode.h
-eventids2.o: $(hdrdir)/ruby/internal/error.h
-eventids2.o: $(hdrdir)/ruby/internal/eval.h
-eventids2.o: $(hdrdir)/ruby/internal/event.h
-eventids2.o: $(hdrdir)/ruby/internal/fl_type.h
-eventids2.o: $(hdrdir)/ruby/internal/gc.h
-eventids2.o: $(hdrdir)/ruby/internal/glob.h
-eventids2.o: $(hdrdir)/ruby/internal/globals.h
-eventids2.o: $(hdrdir)/ruby/internal/has/attribute.h
-eventids2.o: $(hdrdir)/ruby/internal/has/builtin.h
-eventids2.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-eventids2.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-eventids2.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-eventids2.o: $(hdrdir)/ruby/internal/has/extension.h
-eventids2.o: $(hdrdir)/ruby/internal/has/feature.h
-eventids2.o: $(hdrdir)/ruby/internal/has/warning.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/array.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/bignum.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/class.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/compar.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/complex.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/cont.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/dir.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/enum.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/error.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/eval.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/file.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/hash.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/io.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/load.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/marshal.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/numeric.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/object.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/parse.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/proc.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/process.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/random.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/range.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/rational.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/re.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/ruby.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/select.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/signal.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/string.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/struct.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/thread.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/time.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/variable.h
-eventids2.o: $(hdrdir)/ruby/internal/intern/vm.h
-eventids2.o: $(hdrdir)/ruby/internal/interpreter.h
-eventids2.o: $(hdrdir)/ruby/internal/iterator.h
-eventids2.o: $(hdrdir)/ruby/internal/memory.h
-eventids2.o: $(hdrdir)/ruby/internal/method.h
-eventids2.o: $(hdrdir)/ruby/internal/module.h
-eventids2.o: $(hdrdir)/ruby/internal/newobj.h
-eventids2.o: $(hdrdir)/ruby/internal/scan_args.h
-eventids2.o: $(hdrdir)/ruby/internal/special_consts.h
-eventids2.o: $(hdrdir)/ruby/internal/static_assert.h
-eventids2.o: $(hdrdir)/ruby/internal/stdalign.h
-eventids2.o: $(hdrdir)/ruby/internal/stdbool.h
-eventids2.o: $(hdrdir)/ruby/internal/symbol.h
-eventids2.o: $(hdrdir)/ruby/internal/value.h
-eventids2.o: $(hdrdir)/ruby/internal/value_type.h
-eventids2.o: $(hdrdir)/ruby/internal/variable.h
-eventids2.o: $(hdrdir)/ruby/internal/warning_push.h
-eventids2.o: $(hdrdir)/ruby/internal/xmalloc.h
-eventids2.o: $(hdrdir)/ruby/missing.h
-eventids2.o: $(hdrdir)/ruby/onigmo.h
-eventids2.o: $(hdrdir)/ruby/oniguruma.h
-eventids2.o: $(hdrdir)/ruby/ruby.h
-eventids2.o: $(hdrdir)/ruby/st.h
-eventids2.o: $(hdrdir)/ruby/subst.h
-eventids2.o: $(top_srcdir)/internal.h
-eventids2.o: $(top_srcdir)/internal/static_assert.h
-eventids2.o: $(top_srcdir)/rubyparser.h
-eventids2.o: eventids2.c
-eventids2.o: eventids2.h
-eventids2.o: {$(VPATH)}eventids2table.c
-eventids2.o: {$(VPATH)}parse.h
ripper.o: $(RUBY_EXTCONF_H)
ripper.o: $(arch_hdrdir)/ruby/config.h
ripper.o: $(hdrdir)/ruby.h
ripper.o: $(hdrdir)/ruby/assert.h
-ripper.o: $(hdrdir)/ruby/atomic.h
ripper.o: $(hdrdir)/ruby/backward.h
ripper.o: $(hdrdir)/ruby/backward/2/assume.h
ripper.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -445,7 +101,6 @@ ripper.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ripper.o: $(hdrdir)/ruby/internal/attr/noinline.h
ripper.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ripper.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ripper.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ripper.o: $(hdrdir)/ruby/internal/attr/pure.h
ripper.o: $(hdrdir)/ruby/internal/attr/restrict.h
ripper.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -514,6 +169,7 @@ ripper.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ripper.o: $(hdrdir)/ruby/internal/intern/error.h
ripper.o: $(hdrdir)/ruby/internal/intern/eval.h
ripper.o: $(hdrdir)/ruby/internal/intern/file.h
+ripper.o: $(hdrdir)/ruby/internal/intern/gc.h
ripper.o: $(hdrdir)/ruby/internal/intern/hash.h
ripper.o: $(hdrdir)/ruby/internal/intern/io.h
ripper.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -544,6 +200,7 @@ ripper.o: $(hdrdir)/ruby/internal/memory.h
ripper.o: $(hdrdir)/ruby/internal/method.h
ripper.o: $(hdrdir)/ruby/internal/module.h
ripper.o: $(hdrdir)/ruby/internal/newobj.h
+ripper.o: $(hdrdir)/ruby/internal/rgengc.h
ripper.o: $(hdrdir)/ruby/internal/scan_args.h
ripper.o: $(hdrdir)/ruby/internal/special_consts.h
ripper.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -564,18 +221,11 @@ ripper.o: $(hdrdir)/ruby/regex.h
ripper.o: $(hdrdir)/ruby/ruby.h
ripper.o: $(hdrdir)/ruby/st.h
ripper.o: $(hdrdir)/ruby/subst.h
-ripper.o: $(hdrdir)/ruby/thread_native.h
ripper.o: $(hdrdir)/ruby/util.h
-ripper.o: $(hdrdir)/ruby/version.h
-ripper.o: $(top_srcdir)/ccan/check_type/check_type.h
-ripper.o: $(top_srcdir)/ccan/container_of/container_of.h
-ripper.o: $(top_srcdir)/ccan/list/list.h
-ripper.o: $(top_srcdir)/ccan/str/str.h
ripper.o: $(top_srcdir)/constant.h
ripper.o: $(top_srcdir)/id_table.h
ripper.o: $(top_srcdir)/internal.h
ripper.o: $(top_srcdir)/internal/array.h
-ripper.o: $(top_srcdir)/internal/basic_operators.h
ripper.o: $(top_srcdir)/internal/bignum.h
ripper.o: $(top_srcdir)/internal/bits.h
ripper.o: $(top_srcdir)/internal/compile.h
@@ -592,7 +242,6 @@ ripper.o: $(top_srcdir)/internal/numeric.h
ripper.o: $(top_srcdir)/internal/parse.h
ripper.o: $(top_srcdir)/internal/rational.h
ripper.o: $(top_srcdir)/internal/re.h
-ripper.o: $(top_srcdir)/internal/ruby_parser.h
ripper.o: $(top_srcdir)/internal/serial.h
ripper.o: $(top_srcdir)/internal/static_assert.h
ripper.o: $(top_srcdir)/internal/string.h
@@ -601,25 +250,14 @@ ripper.o: $(top_srcdir)/internal/thread.h
ripper.o: $(top_srcdir)/internal/variable.h
ripper.o: $(top_srcdir)/internal/vm.h
ripper.o: $(top_srcdir)/internal/warnings.h
-ripper.o: $(top_srcdir)/method.h
ripper.o: $(top_srcdir)/node.h
-ripper.o: $(top_srcdir)/parser_node.h
-ripper.o: $(top_srcdir)/parser_st.h
ripper.o: $(top_srcdir)/regenc.h
ripper.o: $(top_srcdir)/ruby_assert.h
-ripper.o: $(top_srcdir)/ruby_atomic.h
-ripper.o: $(top_srcdir)/rubyparser.h
ripper.o: $(top_srcdir)/shape.h
ripper.o: $(top_srcdir)/symbol.h
-ripper.o: $(top_srcdir)/thread_pthread.h
-ripper.o: $(top_srcdir)/vm_core.h
-ripper.o: $(top_srcdir)/vm_opts.h
ripper.o: ../../probes.h
-ripper.o: eventids1.h
ripper.o: eventids2.c
-ripper.o: eventids2.h
ripper.o: ripper.y
-ripper.o: ripper_init.h
ripper.o: {$(VPATH)}eventids1.c
ripper.o: {$(VPATH)}eventids2table.c
ripper.o: {$(VPATH)}id.h
@@ -627,188 +265,4 @@ ripper.o: {$(VPATH)}lex.c
ripper.o: {$(VPATH)}parse.h
ripper.o: {$(VPATH)}probes.dmyh
ripper.o: {$(VPATH)}ripper.c
-ripper_init.o: $(RUBY_EXTCONF_H)
-ripper_init.o: $(arch_hdrdir)/ruby/config.h
-ripper_init.o: $(hdrdir)/ruby/assert.h
-ripper_init.o: $(hdrdir)/ruby/backward.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/assume.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/attributes.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/bool.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/inttypes.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/limits.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/long_long.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/stdalign.h
-ripper_init.o: $(hdrdir)/ruby/backward/2/stdarg.h
-ripper_init.o: $(hdrdir)/ruby/defines.h
-ripper_init.o: $(hdrdir)/ruby/encoding.h
-ripper_init.o: $(hdrdir)/ruby/intern.h
-ripper_init.o: $(hdrdir)/ruby/internal/abi.h
-ripper_init.o: $(hdrdir)/ruby/internal/anyargs.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-ripper_init.o: $(hdrdir)/ruby/internal/assume.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/artificial.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/cold.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/const.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/error.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/format.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/noalias.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/noinline.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/pure.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/restrict.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/warning.h
-ripper_init.o: $(hdrdir)/ruby/internal/attr/weakref.h
-ripper_init.o: $(hdrdir)/ruby/internal/cast.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-ripper_init.o: $(hdrdir)/ruby/internal/compiler_since.h
-ripper_init.o: $(hdrdir)/ruby/internal/config.h
-ripper_init.o: $(hdrdir)/ruby/internal/constant_p.h
-ripper_init.o: $(hdrdir)/ruby/internal/core.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rarray.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rbasic.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rbignum.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rclass.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rdata.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rfile.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rhash.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/robject.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rregexp.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rstring.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rstruct.h
-ripper_init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-ripper_init.o: $(hdrdir)/ruby/internal/ctype.h
-ripper_init.o: $(hdrdir)/ruby/internal/dllexport.h
-ripper_init.o: $(hdrdir)/ruby/internal/dosish.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/coderange.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/ctype.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/encoding.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/pathname.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/re.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/string.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/symbol.h
-ripper_init.o: $(hdrdir)/ruby/internal/encoding/transcode.h
-ripper_init.o: $(hdrdir)/ruby/internal/error.h
-ripper_init.o: $(hdrdir)/ruby/internal/eval.h
-ripper_init.o: $(hdrdir)/ruby/internal/event.h
-ripper_init.o: $(hdrdir)/ruby/internal/fl_type.h
-ripper_init.o: $(hdrdir)/ruby/internal/gc.h
-ripper_init.o: $(hdrdir)/ruby/internal/glob.h
-ripper_init.o: $(hdrdir)/ruby/internal/globals.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/attribute.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/builtin.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/extension.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/feature.h
-ripper_init.o: $(hdrdir)/ruby/internal/has/warning.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/array.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/bignum.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/class.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/compar.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/complex.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/cont.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/dir.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/enum.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/error.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/eval.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/file.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/hash.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/io.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/load.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/marshal.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/numeric.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/object.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/parse.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/proc.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/process.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/random.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/range.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/rational.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/re.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/ruby.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/select.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/signal.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/string.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/struct.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/thread.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/time.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/variable.h
-ripper_init.o: $(hdrdir)/ruby/internal/intern/vm.h
-ripper_init.o: $(hdrdir)/ruby/internal/interpreter.h
-ripper_init.o: $(hdrdir)/ruby/internal/iterator.h
-ripper_init.o: $(hdrdir)/ruby/internal/memory.h
-ripper_init.o: $(hdrdir)/ruby/internal/method.h
-ripper_init.o: $(hdrdir)/ruby/internal/module.h
-ripper_init.o: $(hdrdir)/ruby/internal/newobj.h
-ripper_init.o: $(hdrdir)/ruby/internal/scan_args.h
-ripper_init.o: $(hdrdir)/ruby/internal/special_consts.h
-ripper_init.o: $(hdrdir)/ruby/internal/static_assert.h
-ripper_init.o: $(hdrdir)/ruby/internal/stdalign.h
-ripper_init.o: $(hdrdir)/ruby/internal/stdbool.h
-ripper_init.o: $(hdrdir)/ruby/internal/symbol.h
-ripper_init.o: $(hdrdir)/ruby/internal/value.h
-ripper_init.o: $(hdrdir)/ruby/internal/value_type.h
-ripper_init.o: $(hdrdir)/ruby/internal/variable.h
-ripper_init.o: $(hdrdir)/ruby/internal/warning_push.h
-ripper_init.o: $(hdrdir)/ruby/internal/xmalloc.h
-ripper_init.o: $(hdrdir)/ruby/missing.h
-ripper_init.o: $(hdrdir)/ruby/onigmo.h
-ripper_init.o: $(hdrdir)/ruby/oniguruma.h
-ripper_init.o: $(hdrdir)/ruby/ruby.h
-ripper_init.o: $(hdrdir)/ruby/st.h
-ripper_init.o: $(hdrdir)/ruby/subst.h
-ripper_init.o: $(top_srcdir)/internal.h
-ripper_init.o: $(top_srcdir)/internal/array.h
-ripper_init.o: $(top_srcdir)/internal/imemo.h
-ripper_init.o: $(top_srcdir)/internal/parse.h
-ripper_init.o: $(top_srcdir)/internal/ruby_parser.h
-ripper_init.o: $(top_srcdir)/internal/serial.h
-ripper_init.o: $(top_srcdir)/internal/static_assert.h
-ripper_init.o: $(top_srcdir)/internal/vm.h
-ripper_init.o: $(top_srcdir)/node.h
-ripper_init.o: $(top_srcdir)/rubyparser.h
-ripper_init.o: eventids1.h
-ripper_init.o: eventids2.h
-ripper_init.o: ripper_init.h
-ripper_init.o: {$(VPATH)}parse.h
-ripper_init.o: {$(VPATH)}ripper_init.c
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/ripper/eventids2.c b/ext/ripper/eventids2.c
index ac54955857..05687497ac 100644
--- a/ext/ripper/eventids2.c
+++ b/ext/ripper/eventids2.c
@@ -1,11 +1,3 @@
-#include "ruby/ruby.h"
-#include "rubyparser.h"
-#define YYSTYPE_IS_DECLARED
-#include "parse.h"
-#include "eventids2.h"
-#include "internal.h"
-#include "internal/static_assert.h"
-
typedef struct {
ID ripper_id_backref;
ID ripper_id_backtick;
@@ -65,7 +57,7 @@ static ripper_scanner_ids_t ripper_scanner_ids;
#include "eventids2table.c"
-void
+static void
ripper_init_eventids2(void)
{
#define set_id2(name) ripper_scanner_ids.ripper_id_##name = rb_intern_const("on_"#name)
@@ -126,7 +118,7 @@ ripper_init_eventids2(void)
STATIC_ASSERT(k__END___range, k__END__ < SHRT_MAX);
STATIC_ASSERT(ripper_scanner_ids_size, sizeof(ripper_scanner_ids) < SHRT_MAX);
-ID
+static ID
ripper_token2eventid(enum yytokentype tok)
{
#define O(member) (int)offsetof(ripper_scanner_ids_t, ripper_id_##member)+1
diff --git a/ext/ripper/eventids2.h b/ext/ripper/eventids2.h
deleted file mode 100644
index 49e46432b9..0000000000
--- a/ext/ripper/eventids2.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef RIPPER_EVENTIDS2
-#define RIPPER_EVENTIDS2
-
-void ripper_init_eventids2(void);
-void ripper_init_eventids2_table(VALUE self);
-ID ripper_token2eventid(enum yytokentype tok);
-
-#endif /* RIPPER_EVENTIDS2 */
diff --git a/ext/ripper/extconf.rb b/ext/ripper/extconf.rb
index c3c56c27c5..65cb5030d3 100644
--- a/ext/ripper/extconf.rb
+++ b/ext/ripper/extconf.rb
@@ -5,14 +5,23 @@ require 'mkmf'
require 'rbconfig'
def main
- $objs = %w(eventids1.o eventids2.o ripper.o ripper_init.o)
- $distcleanfiles.concat %w(ripper.y ripper.c eventids1.c eventids1.h eventids2table.c ripper_init.c)
+ yacc = ENV["YACC"] || "bison"
+
+ unless find_executable(yacc)
+ unless File.exist?('ripper.c') or File.exist?("#{$srcdir}/ripper.c")
+ raise 'missing bison; abort'
+ end
+ end
+ $objs = %w(ripper.o)
+ $distcleanfiles.concat %w(ripper.y ripper.c eventids1.c eventids2table.c)
$cleanfiles.concat %w(ripper.E ripper.output y.output .eventids2-check)
$defs << '-DRIPPER'
$defs << '-DRIPPER_DEBUG' if $debug
$VPATH << '$(topdir)' << '$(top_srcdir)'
$INCFLAGS << ' -I$(topdir) -I$(top_srcdir)'
- create_makefile 'ripper'
+ create_makefile 'ripper' do |conf|
+ conf << "BISON = #{yacc}"
+ end
end
main
diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb
index 6a3c04af30..a0f1cbeaa8 100644
--- a/ext/ripper/lib/ripper/lexer.rb
+++ b/ext/ripper/lib/ripper/lexer.rb
@@ -242,7 +242,12 @@ class Ripper
end
def on_error2(mesg, elem)
- @errors.push Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg)
+ if elem
+ elem = Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg)
+ else
+ elem = Elem.new([lineno(), column()], __callee__, token(), state(), mesg)
+ end
+ @errors.push elem
end
PARSER_EVENTS.grep(/_error\z/) do |e|
arity = PARSER_EVENT_TABLE.fetch(e)
diff --git a/ext/ripper/ripper_init.c.tmpl b/ext/ripper/ripper_init.c.tmpl
deleted file mode 100644
index 5c1a4e5bb5..0000000000
--- a/ext/ripper/ripper_init.c.tmpl
+++ /dev/null
@@ -1,618 +0,0 @@
-%# -*- c -*-
-#include "ruby/ruby.h"
-#include "ruby/encoding.h"
-#include "internal.h"
-#include "internal/imemo.h" /* needed by ruby_parser.h */
-#include "internal/parse.h"
-#include "internal/ruby_parser.h"
-#include "node.h"
-#include "rubyparser.h"
-#include "eventids1.h"
-#define YYSTYPE_IS_DECLARED
-#include "parse.h"
-#include "eventids2.h"
-#include "ripper_init.h"
-
-#define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),rb_ruby_parser_enc(p))
-#define RIPPER_VERSION "0.1.0"
-
-ID id_warn, id_warning, id_gets, id_assoc;
-
-struct ripper {
- rb_parser_t *p;
-};
-
-static void
-ripper_parser_mark2(void *ptr)
-{
- struct ripper *r = (struct ripper*)ptr;
- if (r->p) ripper_parser_mark(r->p);
-}
-
-static void
-ripper_parser_free2(void *ptr)
-{
- struct ripper *r = (struct ripper*)ptr;
- if (r->p) ripper_parser_free(r->p);
- xfree(r);
-}
-
-static size_t
-ripper_parser_memsize2(const void *ptr)
-{
- struct ripper *r = (struct ripper*)ptr;
- return (r->p) ? ripper_parser_memsize(r->p) : 0;
-}
-
-static const rb_data_type_t parser_data_type = {
- "ripper",
- {
- ripper_parser_mark2,
- ripper_parser_free2,
- ripper_parser_memsize2,
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
-};
-
-ID
-ripper_get_id(VALUE v)
-{
- NODE *nd;
- if (!RB_TYPE_P(v, T_NODE)) return 0;
- nd = (NODE *)v;
- if (!nd_type_p(nd, NODE_RIPPER)) return 0;
- return RNODE_RIPPER(nd)->nd_vid;
-}
-
-VALUE
-ripper_get_value(VALUE v)
-{
- NODE *nd;
- if (UNDEF_P(v)) return Qnil;
- if (!RB_TYPE_P(v, T_NODE)) return v;
- nd = (NODE *)v;
- if (!nd_type_p(nd, NODE_RIPPER)) return Qnil;
- return RNODE_RIPPER(nd)->nd_rval;
-}
-
-static VALUE
-ripper_lex_get_generic(struct parser_params *p, VALUE src)
-{
- VALUE line = rb_funcallv_public(src, id_gets, 0, 0);
- if (!NIL_P(line) && !RB_TYPE_P(line, T_STRING)) {
- rb_raise(rb_eTypeError,
- "gets returned %"PRIsVALUE" (expected String or nil)",
- rb_obj_class(line));
- }
- return line;
-}
-
-void
-ripper_compile_error(struct parser_params *p, const char *fmt, ...)
-{
- VALUE str;
- va_list args;
-
- va_start(args, fmt);
- str = rb_vsprintf(fmt, args);
- va_end(args);
- rb_funcall(ripper_value(p), rb_intern("compile_error"), 1, str);
- ripper_error(p);
-}
-
-static VALUE
-ripper_lex_io_get(struct parser_params *p, VALUE src)
-{
- return rb_io_gets(src);
-}
-
-static VALUE
-ripper_s_allocate(VALUE klass)
-{
- struct ripper *r;
-
- VALUE self = TypedData_Make_Struct(klass, struct ripper,
- &parser_data_type, r);
-
-#ifdef UNIVERSAL_PARSER
- rb_parser_config_t *config;
- config = rb_ruby_parser_config_new(ruby_xmalloc);
- rb_parser_config_initialize(config);
- r->p = rb_ruby_parser_allocate(config);
-#else
- r->p = rb_ruby_ripper_parser_allocate();
-#endif
- rb_ruby_parser_set_value(r->p, self);
- return self;
-}
-
-static struct parser_params *
-ripper_parser_params(VALUE self, bool initialized)
-{
- struct ripper *r;
- struct parser_params *p;
-
- TypedData_Get_Struct(self, struct ripper, &parser_data_type, r);
- p = r->p;
- if (initialized && !rb_ruby_ripper_initialized_p(p)) {
- rb_raise(rb_eArgError, "method called for uninitialized object");
- }
- return p;
-}
-
-/*
- * call-seq:
- * ripper.error? -> Boolean
- *
- * Return true if parsed source has errors.
- */
-static VALUE
-ripper_error_p(VALUE vparser)
-{
- struct parser_params *p = ripper_parser_params(vparser, false);
-
- return RBOOL(rb_ruby_parser_error_p(p));
-}
-
-/*
- * call-seq:
- * ripper.end_seen? -> Boolean
- *
- * Return true if parsed source ended by +\_\_END\_\_+.
- */
-static VALUE
-ripper_parser_end_seen_p(VALUE vparser)
-{
- struct parser_params *p = ripper_parser_params(vparser, false);
-
- return RBOOL(rb_ruby_parser_end_seen_p(p));
-}
-
-/*
- * call-seq:
- * ripper.encoding -> encoding
- *
- * Return encoding of the source.
- */
-static VALUE
-ripper_parser_encoding(VALUE vparser)
-{
- struct parser_params *p = ripper_parser_params(vparser, false);
-
- return rb_ruby_parser_encoding(p);
-}
-
-/*
- * call-seq:
- * ripper.yydebug -> true or false
- *
- * Get yydebug.
- */
-static VALUE
-ripper_parser_get_yydebug(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, false);
-
- return RBOOL(rb_ruby_parser_get_yydebug(p));
-}
-
-/*
- * call-seq:
- * ripper.yydebug = flag
- *
- * Set yydebug.
- */
-static VALUE
-ripper_parser_set_yydebug(VALUE self, VALUE flag)
-{
- struct parser_params *p = ripper_parser_params(self, false);
-
- rb_ruby_parser_set_yydebug(p, RTEST(flag));
- return flag;
-}
-
-/*
- * call-seq:
- * ripper.debug_output -> obj
- *
- * Get debug output.
- */
-static VALUE
-ripper_parser_get_debug_output(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, false);
-
- return rb_ruby_parser_debug_output(p);
-}
-
-/*
- * call-seq:
- * ripper.debug_output = obj
- *
- * Set debug output.
- */
-static VALUE
-ripper_parser_set_debug_output(VALUE self, VALUE output)
-{
- struct parser_params *p = ripper_parser_params(self, false);
-
- rb_ruby_parser_set_debug_output(p, output);
- return output;
-}
-
-#ifdef UNIVERSAL_PARSER
-struct dedent_string_arg {
- struct parser_params *p;
- VALUE input;
- VALUE width;
-};
-
-static VALUE
-parser_dedent_string0(VALUE a)
-{
- struct dedent_string_arg *arg = (void *)a;
- int wid, col;
-
- StringValue(arg->input);
- wid = NUM2UINT(arg->width);
- col = rb_ruby_ripper_dedent_string(arg->p, arg->input, wid);
- return INT2NUM(col);
-}
-
-static VALUE
-parser_config_free(VALUE a)
-{
- rb_parser_config_t *config = (void *)a;
-
- rb_ruby_parser_config_free(config);
- return Qnil;
-}
-#endif
-
-/*
- * call-seq:
- * Ripper.dedent_string(input, width) -> Integer
- *
- * USE OF RIPPER LIBRARY ONLY.
- *
- * Strips up to +width+ leading whitespaces from +input+,
- * and returns the stripped column width.
- */
-#ifdef UNIVERSAL_PARSER
-static VALUE
-parser_dedent_string(VALUE self, VALUE input, VALUE width)
-{
- struct parser_params *p;
- rb_parser_config_t *config;
- struct dedent_string_arg args;
-
- config = rb_ruby_parser_config_new(ruby_xmalloc);
- rb_parser_config_initialize(config);
- p = rb_ruby_parser_new(config);
-
- args.p = p;
- args.input = input;
- args.width = width;
- return rb_ensure(parser_dedent_string0, (VALUE)&args, parser_config_free, (VALUE)config);
-}
-#else
-static VALUE
-parser_dedent_string(VALUE self, VALUE input, VALUE width)
-{
- int wid, col;
-
- StringValue(input);
- wid = NUM2UINT(width);
- col = rb_ruby_ripper_dedent_string(0, input, wid);
- return INT2NUM(col);
-}
-#endif
-
-/*
- * call-seq:
- * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
- *
- * Create a new Ripper object.
- * _src_ must be a String, an IO, or an Object which has #gets method.
- *
- * This method does not starts parsing.
- * See also Ripper#parse and Ripper.parse.
- */
-static VALUE
-ripper_initialize(int argc, VALUE *argv, VALUE self)
-{
- struct parser_params *p;
- VALUE src, fname, lineno;
- VALUE (*gets)(struct parser_params*,VALUE);
- VALUE input, sourcefile_string;
- const char *sourcefile;
- int sourceline;
-
- p = ripper_parser_params(self, false);
- rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
- if (RB_TYPE_P(src, T_FILE)) {
- gets = ripper_lex_io_get;
- }
- else if (rb_respond_to(src, id_gets)) {
- gets = ripper_lex_get_generic;
- }
- else {
- StringValue(src);
- gets = rb_ruby_ripper_lex_get_str;
- }
- input = src;
- if (NIL_P(fname)) {
- fname = STR_NEW2("(ripper)");
- OBJ_FREEZE(fname);
- }
- else {
- StringValueCStr(fname);
- fname = rb_str_new_frozen(fname);
- }
- rb_ruby_ripper_parser_initialize(p);
-
- sourcefile_string = fname;
- sourcefile = RSTRING_PTR(fname);
- sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
-
- rb_ruby_parser_ripper_initialize(p, gets, input, sourcefile_string, sourcefile, sourceline);
-
- return Qnil;
-}
-
-static VALUE
-ripper_parse0(VALUE vparser)
-{
- struct parser_params *p = ripper_parser_params(vparser, false);
-
- rb_ruby_ripper_parse0(p);
- return rb_ruby_parser_result(p);
-}
-
-static VALUE
-ripper_ensure(VALUE vparser)
-{
- struct parser_params *p = ripper_parser_params(vparser, false);
-
- rb_ruby_parser_set_parsing_thread(p, Qnil);
- return Qnil;
-}
-
-/*
- * call-seq:
- * ripper.parse
- *
- * Start parsing and returns the value of the root action.
- */
-static VALUE
-ripper_parse(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, true);
- VALUE result;
-
- if (!NIL_P(rb_ruby_parser_parsing_thread(p))) {
- if (rb_ruby_parser_parsing_thread(p) == rb_thread_current())
- rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
- else
- rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
- }
- rb_ruby_parser_set_parsing_thread(p, rb_thread_current());
- result = rb_ensure(ripper_parse0, self, ripper_ensure, self);
- RB_GC_GUARD(self);
-
- return result;
-}
-
-/*
- * call-seq:
- * ripper.column -> Integer
- *
- * Return column number of current parsing line.
- * This number starts from 0.
- */
-static VALUE
-ripper_column(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, true);
- long col;
-
- if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil;
- col = rb_ruby_ripper_column(p);
- return LONG2NUM(col);
-}
-
-/*
- * call-seq:
- * ripper.filename -> String
- *
- * Return current parsing filename.
- */
-static VALUE
-ripper_filename(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, true);
-
- return rb_ruby_parser_ruby_sourcefile_string(p);
-}
-
-/*
- * call-seq:
- * ripper.lineno -> Integer
- *
- * Return line number of current parsing line.
- * This number starts from 1.
- */
-static VALUE
-ripper_lineno(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, true);
-
- if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil;
- return INT2NUM(rb_ruby_parser_ruby_sourceline(p));
-}
-
-/*
- * call-seq:
- * ripper.state -> Integer
- *
- * Return scanner state of current token.
- */
-static VALUE
-ripper_state(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, true);
-
- if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil;
- return INT2NUM(rb_ruby_parser_lex_state(p));
-}
-
-/*
- * call-seq:
- * ripper.token -> String
- *
- * Return the current token string.
- */
-static VALUE
-ripper_token(VALUE self)
-{
- struct parser_params *p = ripper_parser_params(self, true);
- long pos, len;
-
- if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil;
- pos = rb_ruby_ripper_column(p);
- len = rb_ruby_ripper_token_len(p);
- return rb_str_subseq(rb_ruby_ripper_lex_lastline(p), pos, len);
-}
-
-#ifdef RIPPER_DEBUG
-/* :nodoc: */
-static VALUE
-ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
-{
- StringValue(msg);
- if (UNDEF_P(obj)) {
- rb_raise(rb_eArgError, "%"PRIsVALUE, msg);
- }
- return Qnil;
-}
-
-/* :nodoc: */
-static VALUE
-ripper_raw_value(VALUE self, VALUE obj)
-{
- return ULONG2NUM(obj);
-}
-#endif
-
-#ifdef UNIVERSAL_PARSER
-struct lex_state_name_arg {
- struct parser_params *p;
- VALUE state;
-};
-
-static VALUE
-lex_state_name0(VALUE a)
-{
- struct lex_state_name_arg *arg = (void *)a;
-
- return rb_ruby_ripper_lex_state_name(arg->p, NUM2INT(arg->state));
-}
-#endif
-
-/*
- * call-seq:
- * Ripper.lex_state_name(integer) -> string
- *
- * Returns a string representation of lex_state.
- */
-#ifdef UNIVERSAL_PARSER
-static VALUE
-ripper_lex_state_name(VALUE self, VALUE state)
-{
- struct parser_params *p;
- rb_parser_config_t *config;
- struct lex_state_name_arg args;
-
- config = rb_ruby_parser_config_new(ruby_xmalloc);
- rb_parser_config_initialize(config);
- p = rb_ruby_parser_new(config);
-
- args.p = p;
- args.state = state;
-
- return rb_ensure(lex_state_name0, (VALUE)&args, parser_config_free, (VALUE)config);
-}
-#else
-static VALUE
-ripper_lex_state_name(VALUE self, VALUE state)
-{
- return rb_ruby_ripper_lex_state_name(0, NUM2INT(state));
-}
-#endif
-
-void
-Init_ripper(void)
-{
- ripper_init_eventids1();
- ripper_init_eventids2();
- id_warn = rb_intern_const("warn");
- id_warning = rb_intern_const("warning");
- id_gets = rb_intern_const("gets");
- id_assoc = rb_intern_const("=>");
-
- InitVM(ripper);
-}
-
-void
-InitVM_ripper(void)
-{
- VALUE Ripper;
-
- Ripper = rb_define_class("Ripper", rb_cObject);
- /* version of Ripper */
- rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
- rb_define_alloc_func(Ripper, ripper_s_allocate);
- rb_define_method(Ripper, "initialize", ripper_initialize, -1);
- rb_define_method(Ripper, "parse", ripper_parse, 0);
- rb_define_method(Ripper, "column", ripper_column, 0);
- rb_define_method(Ripper, "filename", ripper_filename, 0);
- rb_define_method(Ripper, "lineno", ripper_lineno, 0);
- rb_define_method(Ripper, "state", ripper_state, 0);
- rb_define_method(Ripper, "token", ripper_token, 0);
- rb_define_method(Ripper, "end_seen?", ripper_parser_end_seen_p, 0);
- rb_define_method(Ripper, "encoding", ripper_parser_encoding, 0);
- rb_define_method(Ripper, "yydebug", ripper_parser_get_yydebug, 0);
- rb_define_method(Ripper, "yydebug=", ripper_parser_set_yydebug, 1);
- rb_define_method(Ripper, "debug_output", ripper_parser_get_debug_output, 0);
- rb_define_method(Ripper, "debug_output=", ripper_parser_set_debug_output, 1);
- rb_define_method(Ripper, "error?", ripper_error_p, 0);
-#ifdef RIPPER_DEBUG
- rb_define_method(Ripper, "assert_Qundef", ripper_assert_Qundef, 2);
- rb_define_method(Ripper, "rawVALUE", ripper_raw_value, 1);
- rb_define_method(Ripper, "validate_object", ripper_validate_object, 1);
-#endif
-
- rb_define_singleton_method(Ripper, "dedent_string", parser_dedent_string, 2);
- rb_define_private_method(Ripper, "dedent_string", parser_dedent_string, 2);
-
- rb_define_singleton_method(Ripper, "lex_state_name", ripper_lex_state_name, 1);
-
-<% @exprs.each do |expr, desc| -%>
- /* <%=desc%> */
- rb_define_const(Ripper, "<%=expr%>", INT2NUM(<%=expr%>));
-<% end %>
- ripper_init_eventids1_table(Ripper);
- ripper_init_eventids2_table(Ripper);
-
-# if 0
- /* Hack to let RDoc document SCRIPT_LINES__ */
-
- /*
- * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
- * after the assignment will be added as an Array of lines with the file
- * name as the key.
- */
- rb_define_global_const("SCRIPT_LINES__", Qnil);
-#endif
-
-}
diff --git a/ext/ripper/ripper_init.h b/ext/ripper/ripper_init.h
deleted file mode 100644
index 82ff13b95f..0000000000
--- a/ext/ripper/ripper_init.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef RIPPER_INIT_H
-#define RIPPER_INIT_H
-
-VALUE ripper_get_value(VALUE v);
-ID ripper_get_id(VALUE v);
-PRINTF_ARGS(void ripper_compile_error(struct parser_params*, const char *fmt, ...), 2, 3);
-
-#endif /* RIPPER_INIT_H */
diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb
index 6d662b3fb8..49ff51711f 100644
--- a/ext/ripper/tools/dsl.rb
+++ b/ext/ripper/tools/dsl.rb
@@ -6,18 +6,11 @@
# v1 = dispatch0(stmts_new);
# v2 = dispatch0(void_stmt);
# $$ = dispatch2(stmts_add, v1, v2);
-#
-# - The code must be a single line.
-#
-# - The code is basically Ruby code, even if it appears like in C and
-# the result will be processed as C. e.g., comments need to be in
-# Ruby style.
-class DSL
- TAG_PATTERN = /(?><[a-zA-Z0-9_]+>)/.source
- NAME_PATTERN = /(?>\$|\d+|[a-zA-Z_][a-zA-Z0-9_]*|\[[a-zA-Z_.][-a-zA-Z0-9_.]*\])(?>(?:\.|->)[a-zA-Z_][a-zA-Z0-9_]*)*/.source
- NOT_REF_PATTERN = /(?>\#.*|[^\"$@]*|"(?>\\.|[^\"])*")/.source
+$dollar = "$$"
+alias $$ $dollar
+class DSL
def initialize(code, options)
@events = {}
@error = options.include?("error")
@@ -25,15 +18,19 @@ class DSL
if options.include?("final")
@final = "p->result"
else
- @final = (options.grep(/\A\$#{NAME_PATTERN}\z/o)[0] || "$$")
+ @final = (options.grep(/\A\$(?:\$|\d+)\z/)[0] || "$$")
end
@vars = 0
+ # create $1 == "$1", $2 == "$2", ...
+ s = (1..20).map {|n| "$#{n}"}
+ re = Array.new(s.size, "([^\0]+)")
+ /#{re.join("\0")}/ =~ s.join("\0")
+
# struct parser_params *p
p = p = "p"
@code = ""
- code = code.gsub(%r[\G#{NOT_REF_PATTERN}\K[$@]#{TAG_PATTERN}?#{NAME_PATTERN}]o, '"\&"')
@last_value = eval(code)
end
diff --git a/ext/ripper/tools/generate.rb b/ext/ripper/tools/generate.rb
index bb64d2fe8b..883e6ef2df 100644
--- a/ext/ripper/tools/generate.rb
+++ b/ext/ripper/tools/generate.rb
@@ -11,7 +11,7 @@ def main
parser = @parser = OptionParser.new
parser.banner = "Usage: #{File.basename($0)} --mode=MODE [--ids1src=PATH] [--ids2src=PATH] [--output=PATH]"
- parser.on('--mode=MODE', 'check, eventids1_h, eventids1, or eventids2table.') {|m|
+ parser.on('--mode=MODE', 'check, eventids1, or eventids2table.') {|m|
mode = m
}
parser.on('--ids1src=PATH', 'A source file of event-IDs 1 (parse.y).') {|path|
@@ -45,9 +45,6 @@ def main
abort "event crash: #{common.join(' ')}"
end
exit 0
- when 'eventids1_h'
- usage 'no --ids1src' unless ids1src
- result = generate_eventids1_h(read_ids1(ids1src))
when 'eventids1'
usage 'no --ids1src' unless ids1src
result = generate_eventids1(read_ids1(ids1src))
@@ -70,35 +67,19 @@ def usage(msg)
exit false
end
-def generate_eventids1_h(ids)
+def generate_eventids1(ids)
buf = "".dup
- buf << %Q[#ifndef RIPPER_EVENTIDS1\n]
- buf << %Q[#define RIPPER_EVENTIDS1\n]
- buf << %Q[\n]
- buf << %Q[void ripper_init_eventids1(void);\n]
- buf << %Q[void ripper_init_eventids1_table(VALUE self);\n]
- buf << %Q[\n]
- buf << %Q[struct ripper_parser_ids {\n]
+ buf << %Q[static struct {\n]
ids.each do |id, arity|
buf << %Q[ ID id_#{id};\n]
end
- buf << %Q[};\n]
+ buf << %Q[} ripper_parser_ids;\n]
buf << %Q[\n]
ids.each do |id, arity|
buf << %Q[#define ripper_id_#{id} ripper_parser_ids.id_#{id}\n]
end
- buf << %Q[#endif /* RIPPER_EVENTIDS1 */\n]
buf << %Q[\n]
-end
-
-def generate_eventids1(ids)
- buf = "".dup
- buf << %Q[#include "ruby/ruby.h"\n]
- buf << %Q[#include "eventids1.h"\n]
- buf << %Q[\n]
- buf << %Q[struct ripper_parser_ids ripper_parser_ids;\n]
- buf << %Q[\n]
- buf << %Q[void\n]
+ buf << %Q[static void\n]
buf << %Q[ripper_init_eventids1(void)\n]
buf << %Q[{\n]
buf << %Q[#define set_id1(name) ripper_id_##name = rb_intern_const("on_"#name)\n]
@@ -107,9 +88,7 @@ def generate_eventids1(ids)
end
buf << %Q[}\n]
buf << %Q[\n]
- buf << %Q[#define intern_sym(name) ID2SYM(rb_intern_const(name))\n]
- buf << %Q[\n]
- buf << %Q[void\n]
+ buf << %Q[static void\n]
buf << %Q[ripper_init_eventids1_table(VALUE self)\n]
buf << %Q[{\n]
buf << %Q[ VALUE h = rb_hash_new();\n]
@@ -123,11 +102,7 @@ end
def generate_eventids2_table(ids)
buf = "".dup
- buf << %Q[#include "ruby/ruby.h"\n]
- buf << %Q[\n]
- buf << %Q[#define intern_sym(name) ID2SYM(rb_intern_const(name))\n]
- buf << %Q[\n]
- buf << %Q[void\n]
+ buf << %Q[static void\n]
buf << %Q[ripper_init_eventids2_table(VALUE self)\n]
buf << %Q[{\n]
buf << %Q[ VALUE h = rb_hash_new();\n]
diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb
index a0d5e79d7d..cd85a5da61 100644
--- a/ext/ripper/tools/preproc.rb
+++ b/ext/ripper/tools/preproc.rb
@@ -5,15 +5,11 @@ require 'optparse'
def main
output = nil
- template = nil
parser = OptionParser.new
- parser.banner = "Usage: #{File.basename($0)} [--output=PATH] [--template=PATH] <parse.y>"
+ parser.banner = "Usage: #{File.basename($0)} [--output=PATH] <parse.y>"
parser.on('--output=PATH', 'An output file.') {|path|
output = path
}
- parser.on('--template=PATH', 'An template file.') {|path|
- template = path
- }
parser.on('--help', 'Prints this message and quit.') {
puts parser.help
exit true
@@ -21,36 +17,28 @@ def main
begin
parser.parse!
rescue OptionParser::ParseError => err
- warn err.message
- abort parser.help
+ $stderr.puts err.message
+ $stderr.puts parser.help
+ exit false
end
- out = "".dup
- if ARGV[0] == "-"
- unless ARGV.size == 2
- abort "wrong number of arguments (#{ARGV.size} for 2)"
- end
- process STDIN, out, ARGV[1], template
- else
- unless ARGV.size == 1
- abort "wrong number of arguments (#{ARGV.size} for 1)"
- end
- File.open(ARGV[0]) {|f|
- process f, out, ARGV[0], template
- }
+ unless ARGV.size == 1
+ abort "wrong number of arguments (#{ARGV.size} for 1)"
end
+ out = "".dup
+ File.open(ARGV[0]) {|f|
+ prelude f, out
+ grammar f, out
+ usercode f, out
+ }
if output
- File.write(output, out)
+ File.open(output, 'w') {|f|
+ f.write out
+ }
else
print out
end
end
-def process(f, out, path, template)
- prelude f, out
- grammar f, out
- usercode f, out, path, template
-end
-
def prelude(f, out)
@exprs = {}
lex_state_def = false
@@ -59,9 +47,10 @@ def prelude(f, out)
when /\A%%/
out << "%%\n"
return
- when /\A%token/, /\A%type/, /\A} <node(?>_\w+)?>/
- # types in %union which have corresponding set_yylval_* macro.
- out << line.sub(/<(?:node(?>_\w+)?|num|id)>/, '<val>')
+ when /\A%token/, /\A} <node>/
+ out << line.sub(/<\w+>/, '<val>')
+ when /\A%type/
+ out << line.sub(/<\w+>/, '<val>')
when /^enum lex_state_(?:bits|e) \{/
lex_state_def = true
out << line
@@ -106,26 +95,13 @@ def grammar(f, out)
end
end
-def usercode(f, out, path, template)
+def usercode(f, out)
require 'erb'
- lineno = nil
- src = nil
compiler = ERB::Compiler.new('%-')
compiler.put_cmd = compiler.insert_cmd = "out.<<"
-
- if template
- File.open(template) do |f|
- out.clear
- lineno = f.lineno
- src, = compiler.compile(f.read)
- path = template
- end
- else
- lineno = f.lineno
- src, = compiler.compile(f.read)
- end
-
- eval(src, binding, path, lineno)
+ lineno = f.lineno
+ src, = compiler.compile(f.read)
+ eval(src, binding, f.path, lineno)
end
main
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
index 6ef040b692..7406177de2 100644
--- a/ext/socket/ancdata.c
+++ b/ext/socket/ancdata.c
@@ -1555,10 +1555,6 @@ bsock_recvmsg_internal(VALUE sock,
ss = rb_recvmsg(fptr->fd, &mh, flags);
- if (ss == 0 && !rsock_is_dgram(fptr)) {
- return Qnil;
- }
-
if (ss == -1) {
int e;
if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) {
diff --git a/ext/socket/depend b/ext/socket/depend
index 3db153bb1c..28c5540cd6 100644
--- a/ext/socket/depend
+++ b/ext/socket/depend
@@ -13,7 +13,6 @@ constdefs.c: constdefs.h
ancdata.o: $(RUBY_EXTCONF_H)
ancdata.o: $(arch_hdrdir)/ruby/config.h
ancdata.o: $(hdrdir)/ruby/assert.h
-ancdata.o: $(hdrdir)/ruby/atomic.h
ancdata.o: $(hdrdir)/ruby/backward.h
ancdata.o: $(hdrdir)/ruby/backward/2/assume.h
ancdata.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -66,7 +65,6 @@ ancdata.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ancdata.o: $(hdrdir)/ruby/internal/attr/noinline.h
ancdata.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ancdata.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ancdata.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ancdata.o: $(hdrdir)/ruby/internal/attr/pure.h
ancdata.o: $(hdrdir)/ruby/internal/attr/restrict.h
ancdata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -135,6 +133,7 @@ ancdata.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ancdata.o: $(hdrdir)/ruby/internal/intern/error.h
ancdata.o: $(hdrdir)/ruby/internal/intern/eval.h
ancdata.o: $(hdrdir)/ruby/internal/intern/file.h
+ancdata.o: $(hdrdir)/ruby/internal/intern/gc.h
ancdata.o: $(hdrdir)/ruby/internal/intern/hash.h
ancdata.o: $(hdrdir)/ruby/internal/intern/io.h
ancdata.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -165,6 +164,7 @@ ancdata.o: $(hdrdir)/ruby/internal/memory.h
ancdata.o: $(hdrdir)/ruby/internal/method.h
ancdata.o: $(hdrdir)/ruby/internal/module.h
ancdata.o: $(hdrdir)/ruby/internal/newobj.h
+ancdata.o: $(hdrdir)/ruby/internal/rgengc.h
ancdata.o: $(hdrdir)/ruby/internal/scan_args.h
ancdata.o: $(hdrdir)/ruby/internal/special_consts.h
ancdata.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -184,20 +184,12 @@ ancdata.o: $(hdrdir)/ruby/ruby.h
ancdata.o: $(hdrdir)/ruby/st.h
ancdata.o: $(hdrdir)/ruby/subst.h
ancdata.o: $(hdrdir)/ruby/thread.h
-ancdata.o: $(hdrdir)/ruby/thread_native.h
ancdata.o: $(hdrdir)/ruby/util.h
-ancdata.o: $(hdrdir)/ruby/version.h
-ancdata.o: $(top_srcdir)/ccan/check_type/check_type.h
-ancdata.o: $(top_srcdir)/ccan/container_of/container_of.h
-ancdata.o: $(top_srcdir)/ccan/list/list.h
-ancdata.o: $(top_srcdir)/ccan/str/str.h
ancdata.o: $(top_srcdir)/internal.h
ancdata.o: $(top_srcdir)/internal/array.h
-ancdata.o: $(top_srcdir)/internal/basic_operators.h
ancdata.o: $(top_srcdir)/internal/compilers.h
ancdata.o: $(top_srcdir)/internal/error.h
ancdata.o: $(top_srcdir)/internal/gc.h
-ancdata.o: $(top_srcdir)/internal/imemo.h
ancdata.o: $(top_srcdir)/internal/io.h
ancdata.o: $(top_srcdir)/internal/serial.h
ancdata.o: $(top_srcdir)/internal/static_assert.h
@@ -205,24 +197,14 @@ ancdata.o: $(top_srcdir)/internal/string.h
ancdata.o: $(top_srcdir)/internal/thread.h
ancdata.o: $(top_srcdir)/internal/vm.h
ancdata.o: $(top_srcdir)/internal/warnings.h
-ancdata.o: $(top_srcdir)/method.h
-ancdata.o: $(top_srcdir)/node.h
-ancdata.o: $(top_srcdir)/ruby_assert.h
-ancdata.o: $(top_srcdir)/ruby_atomic.h
-ancdata.o: $(top_srcdir)/rubyparser.h
ancdata.o: $(top_srcdir)/shape.h
-ancdata.o: $(top_srcdir)/thread_pthread.h
-ancdata.o: $(top_srcdir)/vm_core.h
-ancdata.o: $(top_srcdir)/vm_opts.h
ancdata.o: ancdata.c
ancdata.o: constdefs.h
ancdata.o: rubysocket.h
ancdata.o: sockport.h
-ancdata.o: {$(VPATH)}id.h
basicsocket.o: $(RUBY_EXTCONF_H)
basicsocket.o: $(arch_hdrdir)/ruby/config.h
basicsocket.o: $(hdrdir)/ruby/assert.h
-basicsocket.o: $(hdrdir)/ruby/atomic.h
basicsocket.o: $(hdrdir)/ruby/backward.h
basicsocket.o: $(hdrdir)/ruby/backward/2/assume.h
basicsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -275,7 +257,6 @@ basicsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
basicsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
basicsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
basicsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-basicsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
basicsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
basicsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
basicsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -344,6 +325,7 @@ basicsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
basicsocket.o: $(hdrdir)/ruby/internal/intern/error.h
basicsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
basicsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+basicsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
basicsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
basicsocket.o: $(hdrdir)/ruby/internal/intern/io.h
basicsocket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -374,6 +356,7 @@ basicsocket.o: $(hdrdir)/ruby/internal/memory.h
basicsocket.o: $(hdrdir)/ruby/internal/method.h
basicsocket.o: $(hdrdir)/ruby/internal/module.h
basicsocket.o: $(hdrdir)/ruby/internal/newobj.h
+basicsocket.o: $(hdrdir)/ruby/internal/rgengc.h
basicsocket.o: $(hdrdir)/ruby/internal/scan_args.h
basicsocket.o: $(hdrdir)/ruby/internal/special_consts.h
basicsocket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -393,20 +376,12 @@ basicsocket.o: $(hdrdir)/ruby/ruby.h
basicsocket.o: $(hdrdir)/ruby/st.h
basicsocket.o: $(hdrdir)/ruby/subst.h
basicsocket.o: $(hdrdir)/ruby/thread.h
-basicsocket.o: $(hdrdir)/ruby/thread_native.h
basicsocket.o: $(hdrdir)/ruby/util.h
-basicsocket.o: $(hdrdir)/ruby/version.h
-basicsocket.o: $(top_srcdir)/ccan/check_type/check_type.h
-basicsocket.o: $(top_srcdir)/ccan/container_of/container_of.h
-basicsocket.o: $(top_srcdir)/ccan/list/list.h
-basicsocket.o: $(top_srcdir)/ccan/str/str.h
basicsocket.o: $(top_srcdir)/internal.h
basicsocket.o: $(top_srcdir)/internal/array.h
-basicsocket.o: $(top_srcdir)/internal/basic_operators.h
basicsocket.o: $(top_srcdir)/internal/compilers.h
basicsocket.o: $(top_srcdir)/internal/error.h
basicsocket.o: $(top_srcdir)/internal/gc.h
-basicsocket.o: $(top_srcdir)/internal/imemo.h
basicsocket.o: $(top_srcdir)/internal/io.h
basicsocket.o: $(top_srcdir)/internal/serial.h
basicsocket.o: $(top_srcdir)/internal/static_assert.h
@@ -414,24 +389,14 @@ basicsocket.o: $(top_srcdir)/internal/string.h
basicsocket.o: $(top_srcdir)/internal/thread.h
basicsocket.o: $(top_srcdir)/internal/vm.h
basicsocket.o: $(top_srcdir)/internal/warnings.h
-basicsocket.o: $(top_srcdir)/method.h
-basicsocket.o: $(top_srcdir)/node.h
-basicsocket.o: $(top_srcdir)/ruby_assert.h
-basicsocket.o: $(top_srcdir)/ruby_atomic.h
-basicsocket.o: $(top_srcdir)/rubyparser.h
basicsocket.o: $(top_srcdir)/shape.h
-basicsocket.o: $(top_srcdir)/thread_pthread.h
-basicsocket.o: $(top_srcdir)/vm_core.h
-basicsocket.o: $(top_srcdir)/vm_opts.h
basicsocket.o: basicsocket.c
basicsocket.o: constdefs.h
basicsocket.o: rubysocket.h
basicsocket.o: sockport.h
-basicsocket.o: {$(VPATH)}id.h
constants.o: $(RUBY_EXTCONF_H)
constants.o: $(arch_hdrdir)/ruby/config.h
constants.o: $(hdrdir)/ruby/assert.h
-constants.o: $(hdrdir)/ruby/atomic.h
constants.o: $(hdrdir)/ruby/backward.h
constants.o: $(hdrdir)/ruby/backward/2/assume.h
constants.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -484,7 +449,6 @@ constants.o: $(hdrdir)/ruby/internal/attr/noexcept.h
constants.o: $(hdrdir)/ruby/internal/attr/noinline.h
constants.o: $(hdrdir)/ruby/internal/attr/nonnull.h
constants.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-constants.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
constants.o: $(hdrdir)/ruby/internal/attr/pure.h
constants.o: $(hdrdir)/ruby/internal/attr/restrict.h
constants.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -553,6 +517,7 @@ constants.o: $(hdrdir)/ruby/internal/intern/enumerator.h
constants.o: $(hdrdir)/ruby/internal/intern/error.h
constants.o: $(hdrdir)/ruby/internal/intern/eval.h
constants.o: $(hdrdir)/ruby/internal/intern/file.h
+constants.o: $(hdrdir)/ruby/internal/intern/gc.h
constants.o: $(hdrdir)/ruby/internal/intern/hash.h
constants.o: $(hdrdir)/ruby/internal/intern/io.h
constants.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -583,6 +548,7 @@ constants.o: $(hdrdir)/ruby/internal/memory.h
constants.o: $(hdrdir)/ruby/internal/method.h
constants.o: $(hdrdir)/ruby/internal/module.h
constants.o: $(hdrdir)/ruby/internal/newobj.h
+constants.o: $(hdrdir)/ruby/internal/rgengc.h
constants.o: $(hdrdir)/ruby/internal/scan_args.h
constants.o: $(hdrdir)/ruby/internal/special_consts.h
constants.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -602,20 +568,12 @@ constants.o: $(hdrdir)/ruby/ruby.h
constants.o: $(hdrdir)/ruby/st.h
constants.o: $(hdrdir)/ruby/subst.h
constants.o: $(hdrdir)/ruby/thread.h
-constants.o: $(hdrdir)/ruby/thread_native.h
constants.o: $(hdrdir)/ruby/util.h
-constants.o: $(hdrdir)/ruby/version.h
-constants.o: $(top_srcdir)/ccan/check_type/check_type.h
-constants.o: $(top_srcdir)/ccan/container_of/container_of.h
-constants.o: $(top_srcdir)/ccan/list/list.h
-constants.o: $(top_srcdir)/ccan/str/str.h
constants.o: $(top_srcdir)/internal.h
constants.o: $(top_srcdir)/internal/array.h
-constants.o: $(top_srcdir)/internal/basic_operators.h
constants.o: $(top_srcdir)/internal/compilers.h
constants.o: $(top_srcdir)/internal/error.h
constants.o: $(top_srcdir)/internal/gc.h
-constants.o: $(top_srcdir)/internal/imemo.h
constants.o: $(top_srcdir)/internal/io.h
constants.o: $(top_srcdir)/internal/serial.h
constants.o: $(top_srcdir)/internal/static_assert.h
@@ -623,25 +581,15 @@ constants.o: $(top_srcdir)/internal/string.h
constants.o: $(top_srcdir)/internal/thread.h
constants.o: $(top_srcdir)/internal/vm.h
constants.o: $(top_srcdir)/internal/warnings.h
-constants.o: $(top_srcdir)/method.h
-constants.o: $(top_srcdir)/node.h
-constants.o: $(top_srcdir)/ruby_assert.h
-constants.o: $(top_srcdir)/ruby_atomic.h
-constants.o: $(top_srcdir)/rubyparser.h
constants.o: $(top_srcdir)/shape.h
-constants.o: $(top_srcdir)/thread_pthread.h
-constants.o: $(top_srcdir)/vm_core.h
-constants.o: $(top_srcdir)/vm_opts.h
constants.o: constants.c
constants.o: constdefs.c
constants.o: constdefs.h
constants.o: rubysocket.h
constants.o: sockport.h
-constants.o: {$(VPATH)}id.h
ifaddr.o: $(RUBY_EXTCONF_H)
ifaddr.o: $(arch_hdrdir)/ruby/config.h
ifaddr.o: $(hdrdir)/ruby/assert.h
-ifaddr.o: $(hdrdir)/ruby/atomic.h
ifaddr.o: $(hdrdir)/ruby/backward.h
ifaddr.o: $(hdrdir)/ruby/backward/2/assume.h
ifaddr.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -694,7 +642,6 @@ ifaddr.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ifaddr.o: $(hdrdir)/ruby/internal/attr/noinline.h
ifaddr.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ifaddr.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ifaddr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ifaddr.o: $(hdrdir)/ruby/internal/attr/pure.h
ifaddr.o: $(hdrdir)/ruby/internal/attr/restrict.h
ifaddr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -763,6 +710,7 @@ ifaddr.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ifaddr.o: $(hdrdir)/ruby/internal/intern/error.h
ifaddr.o: $(hdrdir)/ruby/internal/intern/eval.h
ifaddr.o: $(hdrdir)/ruby/internal/intern/file.h
+ifaddr.o: $(hdrdir)/ruby/internal/intern/gc.h
ifaddr.o: $(hdrdir)/ruby/internal/intern/hash.h
ifaddr.o: $(hdrdir)/ruby/internal/intern/io.h
ifaddr.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -793,6 +741,7 @@ ifaddr.o: $(hdrdir)/ruby/internal/memory.h
ifaddr.o: $(hdrdir)/ruby/internal/method.h
ifaddr.o: $(hdrdir)/ruby/internal/module.h
ifaddr.o: $(hdrdir)/ruby/internal/newobj.h
+ifaddr.o: $(hdrdir)/ruby/internal/rgengc.h
ifaddr.o: $(hdrdir)/ruby/internal/scan_args.h
ifaddr.o: $(hdrdir)/ruby/internal/special_consts.h
ifaddr.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -812,20 +761,12 @@ ifaddr.o: $(hdrdir)/ruby/ruby.h
ifaddr.o: $(hdrdir)/ruby/st.h
ifaddr.o: $(hdrdir)/ruby/subst.h
ifaddr.o: $(hdrdir)/ruby/thread.h
-ifaddr.o: $(hdrdir)/ruby/thread_native.h
ifaddr.o: $(hdrdir)/ruby/util.h
-ifaddr.o: $(hdrdir)/ruby/version.h
-ifaddr.o: $(top_srcdir)/ccan/check_type/check_type.h
-ifaddr.o: $(top_srcdir)/ccan/container_of/container_of.h
-ifaddr.o: $(top_srcdir)/ccan/list/list.h
-ifaddr.o: $(top_srcdir)/ccan/str/str.h
ifaddr.o: $(top_srcdir)/internal.h
ifaddr.o: $(top_srcdir)/internal/array.h
-ifaddr.o: $(top_srcdir)/internal/basic_operators.h
ifaddr.o: $(top_srcdir)/internal/compilers.h
ifaddr.o: $(top_srcdir)/internal/error.h
ifaddr.o: $(top_srcdir)/internal/gc.h
-ifaddr.o: $(top_srcdir)/internal/imemo.h
ifaddr.o: $(top_srcdir)/internal/io.h
ifaddr.o: $(top_srcdir)/internal/serial.h
ifaddr.o: $(top_srcdir)/internal/static_assert.h
@@ -833,24 +774,14 @@ ifaddr.o: $(top_srcdir)/internal/string.h
ifaddr.o: $(top_srcdir)/internal/thread.h
ifaddr.o: $(top_srcdir)/internal/vm.h
ifaddr.o: $(top_srcdir)/internal/warnings.h
-ifaddr.o: $(top_srcdir)/method.h
-ifaddr.o: $(top_srcdir)/node.h
-ifaddr.o: $(top_srcdir)/ruby_assert.h
-ifaddr.o: $(top_srcdir)/ruby_atomic.h
-ifaddr.o: $(top_srcdir)/rubyparser.h
ifaddr.o: $(top_srcdir)/shape.h
-ifaddr.o: $(top_srcdir)/thread_pthread.h
-ifaddr.o: $(top_srcdir)/vm_core.h
-ifaddr.o: $(top_srcdir)/vm_opts.h
ifaddr.o: constdefs.h
ifaddr.o: ifaddr.c
ifaddr.o: rubysocket.h
ifaddr.o: sockport.h
-ifaddr.o: {$(VPATH)}id.h
init.o: $(RUBY_EXTCONF_H)
init.o: $(arch_hdrdir)/ruby/config.h
init.o: $(hdrdir)/ruby/assert.h
-init.o: $(hdrdir)/ruby/atomic.h
init.o: $(hdrdir)/ruby/backward.h
init.o: $(hdrdir)/ruby/backward/2/assume.h
init.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -903,7 +834,6 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
init.o: $(hdrdir)/ruby/internal/attr/pure.h
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -972,6 +902,7 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
init.o: $(hdrdir)/ruby/internal/intern/error.h
init.o: $(hdrdir)/ruby/internal/intern/eval.h
init.o: $(hdrdir)/ruby/internal/intern/file.h
+init.o: $(hdrdir)/ruby/internal/intern/gc.h
init.o: $(hdrdir)/ruby/internal/intern/hash.h
init.o: $(hdrdir)/ruby/internal/intern/io.h
init.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1002,6 +933,7 @@ init.o: $(hdrdir)/ruby/internal/memory.h
init.o: $(hdrdir)/ruby/internal/method.h
init.o: $(hdrdir)/ruby/internal/module.h
init.o: $(hdrdir)/ruby/internal/newobj.h
+init.o: $(hdrdir)/ruby/internal/rgengc.h
init.o: $(hdrdir)/ruby/internal/scan_args.h
init.o: $(hdrdir)/ruby/internal/special_consts.h
init.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1021,20 +953,12 @@ init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
init.o: $(hdrdir)/ruby/thread.h
-init.o: $(hdrdir)/ruby/thread_native.h
init.o: $(hdrdir)/ruby/util.h
-init.o: $(hdrdir)/ruby/version.h
-init.o: $(top_srcdir)/ccan/check_type/check_type.h
-init.o: $(top_srcdir)/ccan/container_of/container_of.h
-init.o: $(top_srcdir)/ccan/list/list.h
-init.o: $(top_srcdir)/ccan/str/str.h
init.o: $(top_srcdir)/internal.h
init.o: $(top_srcdir)/internal/array.h
-init.o: $(top_srcdir)/internal/basic_operators.h
init.o: $(top_srcdir)/internal/compilers.h
init.o: $(top_srcdir)/internal/error.h
init.o: $(top_srcdir)/internal/gc.h
-init.o: $(top_srcdir)/internal/imemo.h
init.o: $(top_srcdir)/internal/io.h
init.o: $(top_srcdir)/internal/serial.h
init.o: $(top_srcdir)/internal/static_assert.h
@@ -1042,24 +966,14 @@ init.o: $(top_srcdir)/internal/string.h
init.o: $(top_srcdir)/internal/thread.h
init.o: $(top_srcdir)/internal/vm.h
init.o: $(top_srcdir)/internal/warnings.h
-init.o: $(top_srcdir)/method.h
-init.o: $(top_srcdir)/node.h
-init.o: $(top_srcdir)/ruby_assert.h
-init.o: $(top_srcdir)/ruby_atomic.h
-init.o: $(top_srcdir)/rubyparser.h
init.o: $(top_srcdir)/shape.h
-init.o: $(top_srcdir)/thread_pthread.h
-init.o: $(top_srcdir)/vm_core.h
-init.o: $(top_srcdir)/vm_opts.h
init.o: constdefs.h
init.o: init.c
init.o: rubysocket.h
init.o: sockport.h
-init.o: {$(VPATH)}id.h
ipsocket.o: $(RUBY_EXTCONF_H)
ipsocket.o: $(arch_hdrdir)/ruby/config.h
ipsocket.o: $(hdrdir)/ruby/assert.h
-ipsocket.o: $(hdrdir)/ruby/atomic.h
ipsocket.o: $(hdrdir)/ruby/backward.h
ipsocket.o: $(hdrdir)/ruby/backward/2/assume.h
ipsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -1112,7 +1026,6 @@ ipsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
ipsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
ipsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
ipsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-ipsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
ipsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
ipsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
ipsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1181,6 +1094,7 @@ ipsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
ipsocket.o: $(hdrdir)/ruby/internal/intern/error.h
ipsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
ipsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+ipsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
ipsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
ipsocket.o: $(hdrdir)/ruby/internal/intern/io.h
ipsocket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1211,6 +1125,7 @@ ipsocket.o: $(hdrdir)/ruby/internal/memory.h
ipsocket.o: $(hdrdir)/ruby/internal/method.h
ipsocket.o: $(hdrdir)/ruby/internal/module.h
ipsocket.o: $(hdrdir)/ruby/internal/newobj.h
+ipsocket.o: $(hdrdir)/ruby/internal/rgengc.h
ipsocket.o: $(hdrdir)/ruby/internal/scan_args.h
ipsocket.o: $(hdrdir)/ruby/internal/special_consts.h
ipsocket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1230,20 +1145,12 @@ ipsocket.o: $(hdrdir)/ruby/ruby.h
ipsocket.o: $(hdrdir)/ruby/st.h
ipsocket.o: $(hdrdir)/ruby/subst.h
ipsocket.o: $(hdrdir)/ruby/thread.h
-ipsocket.o: $(hdrdir)/ruby/thread_native.h
ipsocket.o: $(hdrdir)/ruby/util.h
-ipsocket.o: $(hdrdir)/ruby/version.h
-ipsocket.o: $(top_srcdir)/ccan/check_type/check_type.h
-ipsocket.o: $(top_srcdir)/ccan/container_of/container_of.h
-ipsocket.o: $(top_srcdir)/ccan/list/list.h
-ipsocket.o: $(top_srcdir)/ccan/str/str.h
ipsocket.o: $(top_srcdir)/internal.h
ipsocket.o: $(top_srcdir)/internal/array.h
-ipsocket.o: $(top_srcdir)/internal/basic_operators.h
ipsocket.o: $(top_srcdir)/internal/compilers.h
ipsocket.o: $(top_srcdir)/internal/error.h
ipsocket.o: $(top_srcdir)/internal/gc.h
-ipsocket.o: $(top_srcdir)/internal/imemo.h
ipsocket.o: $(top_srcdir)/internal/io.h
ipsocket.o: $(top_srcdir)/internal/serial.h
ipsocket.o: $(top_srcdir)/internal/static_assert.h
@@ -1251,24 +1158,14 @@ ipsocket.o: $(top_srcdir)/internal/string.h
ipsocket.o: $(top_srcdir)/internal/thread.h
ipsocket.o: $(top_srcdir)/internal/vm.h
ipsocket.o: $(top_srcdir)/internal/warnings.h
-ipsocket.o: $(top_srcdir)/method.h
-ipsocket.o: $(top_srcdir)/node.h
-ipsocket.o: $(top_srcdir)/ruby_assert.h
-ipsocket.o: $(top_srcdir)/ruby_atomic.h
-ipsocket.o: $(top_srcdir)/rubyparser.h
ipsocket.o: $(top_srcdir)/shape.h
-ipsocket.o: $(top_srcdir)/thread_pthread.h
-ipsocket.o: $(top_srcdir)/vm_core.h
-ipsocket.o: $(top_srcdir)/vm_opts.h
ipsocket.o: constdefs.h
ipsocket.o: ipsocket.c
ipsocket.o: rubysocket.h
ipsocket.o: sockport.h
-ipsocket.o: {$(VPATH)}id.h
option.o: $(RUBY_EXTCONF_H)
option.o: $(arch_hdrdir)/ruby/config.h
option.o: $(hdrdir)/ruby/assert.h
-option.o: $(hdrdir)/ruby/atomic.h
option.o: $(hdrdir)/ruby/backward.h
option.o: $(hdrdir)/ruby/backward/2/assume.h
option.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -1321,7 +1218,6 @@ option.o: $(hdrdir)/ruby/internal/attr/noexcept.h
option.o: $(hdrdir)/ruby/internal/attr/noinline.h
option.o: $(hdrdir)/ruby/internal/attr/nonnull.h
option.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-option.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
option.o: $(hdrdir)/ruby/internal/attr/pure.h
option.o: $(hdrdir)/ruby/internal/attr/restrict.h
option.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1390,6 +1286,7 @@ option.o: $(hdrdir)/ruby/internal/intern/enumerator.h
option.o: $(hdrdir)/ruby/internal/intern/error.h
option.o: $(hdrdir)/ruby/internal/intern/eval.h
option.o: $(hdrdir)/ruby/internal/intern/file.h
+option.o: $(hdrdir)/ruby/internal/intern/gc.h
option.o: $(hdrdir)/ruby/internal/intern/hash.h
option.o: $(hdrdir)/ruby/internal/intern/io.h
option.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1420,6 +1317,7 @@ option.o: $(hdrdir)/ruby/internal/memory.h
option.o: $(hdrdir)/ruby/internal/method.h
option.o: $(hdrdir)/ruby/internal/module.h
option.o: $(hdrdir)/ruby/internal/newobj.h
+option.o: $(hdrdir)/ruby/internal/rgengc.h
option.o: $(hdrdir)/ruby/internal/scan_args.h
option.o: $(hdrdir)/ruby/internal/special_consts.h
option.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1439,20 +1337,12 @@ option.o: $(hdrdir)/ruby/ruby.h
option.o: $(hdrdir)/ruby/st.h
option.o: $(hdrdir)/ruby/subst.h
option.o: $(hdrdir)/ruby/thread.h
-option.o: $(hdrdir)/ruby/thread_native.h
option.o: $(hdrdir)/ruby/util.h
-option.o: $(hdrdir)/ruby/version.h
-option.o: $(top_srcdir)/ccan/check_type/check_type.h
-option.o: $(top_srcdir)/ccan/container_of/container_of.h
-option.o: $(top_srcdir)/ccan/list/list.h
-option.o: $(top_srcdir)/ccan/str/str.h
option.o: $(top_srcdir)/internal.h
option.o: $(top_srcdir)/internal/array.h
-option.o: $(top_srcdir)/internal/basic_operators.h
option.o: $(top_srcdir)/internal/compilers.h
option.o: $(top_srcdir)/internal/error.h
option.o: $(top_srcdir)/internal/gc.h
-option.o: $(top_srcdir)/internal/imemo.h
option.o: $(top_srcdir)/internal/io.h
option.o: $(top_srcdir)/internal/serial.h
option.o: $(top_srcdir)/internal/static_assert.h
@@ -1460,24 +1350,14 @@ option.o: $(top_srcdir)/internal/string.h
option.o: $(top_srcdir)/internal/thread.h
option.o: $(top_srcdir)/internal/vm.h
option.o: $(top_srcdir)/internal/warnings.h
-option.o: $(top_srcdir)/method.h
-option.o: $(top_srcdir)/node.h
-option.o: $(top_srcdir)/ruby_assert.h
-option.o: $(top_srcdir)/ruby_atomic.h
-option.o: $(top_srcdir)/rubyparser.h
option.o: $(top_srcdir)/shape.h
-option.o: $(top_srcdir)/thread_pthread.h
-option.o: $(top_srcdir)/vm_core.h
-option.o: $(top_srcdir)/vm_opts.h
option.o: constdefs.h
option.o: option.c
option.o: rubysocket.h
option.o: sockport.h
-option.o: {$(VPATH)}id.h
raddrinfo.o: $(RUBY_EXTCONF_H)
raddrinfo.o: $(arch_hdrdir)/ruby/config.h
raddrinfo.o: $(hdrdir)/ruby/assert.h
-raddrinfo.o: $(hdrdir)/ruby/atomic.h
raddrinfo.o: $(hdrdir)/ruby/backward.h
raddrinfo.o: $(hdrdir)/ruby/backward/2/assume.h
raddrinfo.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -1530,7 +1410,6 @@ raddrinfo.o: $(hdrdir)/ruby/internal/attr/noexcept.h
raddrinfo.o: $(hdrdir)/ruby/internal/attr/noinline.h
raddrinfo.o: $(hdrdir)/ruby/internal/attr/nonnull.h
raddrinfo.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-raddrinfo.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
raddrinfo.o: $(hdrdir)/ruby/internal/attr/pure.h
raddrinfo.o: $(hdrdir)/ruby/internal/attr/restrict.h
raddrinfo.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1599,6 +1478,7 @@ raddrinfo.o: $(hdrdir)/ruby/internal/intern/enumerator.h
raddrinfo.o: $(hdrdir)/ruby/internal/intern/error.h
raddrinfo.o: $(hdrdir)/ruby/internal/intern/eval.h
raddrinfo.o: $(hdrdir)/ruby/internal/intern/file.h
+raddrinfo.o: $(hdrdir)/ruby/internal/intern/gc.h
raddrinfo.o: $(hdrdir)/ruby/internal/intern/hash.h
raddrinfo.o: $(hdrdir)/ruby/internal/intern/io.h
raddrinfo.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1629,6 +1509,7 @@ raddrinfo.o: $(hdrdir)/ruby/internal/memory.h
raddrinfo.o: $(hdrdir)/ruby/internal/method.h
raddrinfo.o: $(hdrdir)/ruby/internal/module.h
raddrinfo.o: $(hdrdir)/ruby/internal/newobj.h
+raddrinfo.o: $(hdrdir)/ruby/internal/rgengc.h
raddrinfo.o: $(hdrdir)/ruby/internal/scan_args.h
raddrinfo.o: $(hdrdir)/ruby/internal/special_consts.h
raddrinfo.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1648,20 +1529,12 @@ raddrinfo.o: $(hdrdir)/ruby/ruby.h
raddrinfo.o: $(hdrdir)/ruby/st.h
raddrinfo.o: $(hdrdir)/ruby/subst.h
raddrinfo.o: $(hdrdir)/ruby/thread.h
-raddrinfo.o: $(hdrdir)/ruby/thread_native.h
raddrinfo.o: $(hdrdir)/ruby/util.h
-raddrinfo.o: $(hdrdir)/ruby/version.h
-raddrinfo.o: $(top_srcdir)/ccan/check_type/check_type.h
-raddrinfo.o: $(top_srcdir)/ccan/container_of/container_of.h
-raddrinfo.o: $(top_srcdir)/ccan/list/list.h
-raddrinfo.o: $(top_srcdir)/ccan/str/str.h
raddrinfo.o: $(top_srcdir)/internal.h
raddrinfo.o: $(top_srcdir)/internal/array.h
-raddrinfo.o: $(top_srcdir)/internal/basic_operators.h
raddrinfo.o: $(top_srcdir)/internal/compilers.h
raddrinfo.o: $(top_srcdir)/internal/error.h
raddrinfo.o: $(top_srcdir)/internal/gc.h
-raddrinfo.o: $(top_srcdir)/internal/imemo.h
raddrinfo.o: $(top_srcdir)/internal/io.h
raddrinfo.o: $(top_srcdir)/internal/serial.h
raddrinfo.o: $(top_srcdir)/internal/static_assert.h
@@ -1669,24 +1542,14 @@ raddrinfo.o: $(top_srcdir)/internal/string.h
raddrinfo.o: $(top_srcdir)/internal/thread.h
raddrinfo.o: $(top_srcdir)/internal/vm.h
raddrinfo.o: $(top_srcdir)/internal/warnings.h
-raddrinfo.o: $(top_srcdir)/method.h
-raddrinfo.o: $(top_srcdir)/node.h
-raddrinfo.o: $(top_srcdir)/ruby_assert.h
-raddrinfo.o: $(top_srcdir)/ruby_atomic.h
-raddrinfo.o: $(top_srcdir)/rubyparser.h
raddrinfo.o: $(top_srcdir)/shape.h
-raddrinfo.o: $(top_srcdir)/thread_pthread.h
-raddrinfo.o: $(top_srcdir)/vm_core.h
-raddrinfo.o: $(top_srcdir)/vm_opts.h
raddrinfo.o: constdefs.h
raddrinfo.o: raddrinfo.c
raddrinfo.o: rubysocket.h
raddrinfo.o: sockport.h
-raddrinfo.o: {$(VPATH)}id.h
socket.o: $(RUBY_EXTCONF_H)
socket.o: $(arch_hdrdir)/ruby/config.h
socket.o: $(hdrdir)/ruby/assert.h
-socket.o: $(hdrdir)/ruby/atomic.h
socket.o: $(hdrdir)/ruby/backward.h
socket.o: $(hdrdir)/ruby/backward/2/assume.h
socket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -1739,7 +1602,6 @@ socket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
socket.o: $(hdrdir)/ruby/internal/attr/noinline.h
socket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
socket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-socket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
socket.o: $(hdrdir)/ruby/internal/attr/pure.h
socket.o: $(hdrdir)/ruby/internal/attr/restrict.h
socket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -1808,6 +1670,7 @@ socket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
socket.o: $(hdrdir)/ruby/internal/intern/error.h
socket.o: $(hdrdir)/ruby/internal/intern/eval.h
socket.o: $(hdrdir)/ruby/internal/intern/file.h
+socket.o: $(hdrdir)/ruby/internal/intern/gc.h
socket.o: $(hdrdir)/ruby/internal/intern/hash.h
socket.o: $(hdrdir)/ruby/internal/intern/io.h
socket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -1838,6 +1701,7 @@ socket.o: $(hdrdir)/ruby/internal/memory.h
socket.o: $(hdrdir)/ruby/internal/method.h
socket.o: $(hdrdir)/ruby/internal/module.h
socket.o: $(hdrdir)/ruby/internal/newobj.h
+socket.o: $(hdrdir)/ruby/internal/rgengc.h
socket.o: $(hdrdir)/ruby/internal/scan_args.h
socket.o: $(hdrdir)/ruby/internal/special_consts.h
socket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -1857,20 +1721,12 @@ socket.o: $(hdrdir)/ruby/ruby.h
socket.o: $(hdrdir)/ruby/st.h
socket.o: $(hdrdir)/ruby/subst.h
socket.o: $(hdrdir)/ruby/thread.h
-socket.o: $(hdrdir)/ruby/thread_native.h
socket.o: $(hdrdir)/ruby/util.h
-socket.o: $(hdrdir)/ruby/version.h
-socket.o: $(top_srcdir)/ccan/check_type/check_type.h
-socket.o: $(top_srcdir)/ccan/container_of/container_of.h
-socket.o: $(top_srcdir)/ccan/list/list.h
-socket.o: $(top_srcdir)/ccan/str/str.h
socket.o: $(top_srcdir)/internal.h
socket.o: $(top_srcdir)/internal/array.h
-socket.o: $(top_srcdir)/internal/basic_operators.h
socket.o: $(top_srcdir)/internal/compilers.h
socket.o: $(top_srcdir)/internal/error.h
socket.o: $(top_srcdir)/internal/gc.h
-socket.o: $(top_srcdir)/internal/imemo.h
socket.o: $(top_srcdir)/internal/io.h
socket.o: $(top_srcdir)/internal/serial.h
socket.o: $(top_srcdir)/internal/static_assert.h
@@ -1878,24 +1734,14 @@ socket.o: $(top_srcdir)/internal/string.h
socket.o: $(top_srcdir)/internal/thread.h
socket.o: $(top_srcdir)/internal/vm.h
socket.o: $(top_srcdir)/internal/warnings.h
-socket.o: $(top_srcdir)/method.h
-socket.o: $(top_srcdir)/node.h
-socket.o: $(top_srcdir)/ruby_assert.h
-socket.o: $(top_srcdir)/ruby_atomic.h
-socket.o: $(top_srcdir)/rubyparser.h
socket.o: $(top_srcdir)/shape.h
-socket.o: $(top_srcdir)/thread_pthread.h
-socket.o: $(top_srcdir)/vm_core.h
-socket.o: $(top_srcdir)/vm_opts.h
socket.o: constdefs.h
socket.o: rubysocket.h
socket.o: socket.c
socket.o: sockport.h
-socket.o: {$(VPATH)}id.h
sockssocket.o: $(RUBY_EXTCONF_H)
sockssocket.o: $(arch_hdrdir)/ruby/config.h
sockssocket.o: $(hdrdir)/ruby/assert.h
-sockssocket.o: $(hdrdir)/ruby/atomic.h
sockssocket.o: $(hdrdir)/ruby/backward.h
sockssocket.o: $(hdrdir)/ruby/backward/2/assume.h
sockssocket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -1948,7 +1794,6 @@ sockssocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
sockssocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
sockssocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
sockssocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-sockssocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
sockssocket.o: $(hdrdir)/ruby/internal/attr/pure.h
sockssocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
sockssocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2017,6 +1862,7 @@ sockssocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
sockssocket.o: $(hdrdir)/ruby/internal/intern/error.h
sockssocket.o: $(hdrdir)/ruby/internal/intern/eval.h
sockssocket.o: $(hdrdir)/ruby/internal/intern/file.h
+sockssocket.o: $(hdrdir)/ruby/internal/intern/gc.h
sockssocket.o: $(hdrdir)/ruby/internal/intern/hash.h
sockssocket.o: $(hdrdir)/ruby/internal/intern/io.h
sockssocket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2047,6 +1893,7 @@ sockssocket.o: $(hdrdir)/ruby/internal/memory.h
sockssocket.o: $(hdrdir)/ruby/internal/method.h
sockssocket.o: $(hdrdir)/ruby/internal/module.h
sockssocket.o: $(hdrdir)/ruby/internal/newobj.h
+sockssocket.o: $(hdrdir)/ruby/internal/rgengc.h
sockssocket.o: $(hdrdir)/ruby/internal/scan_args.h
sockssocket.o: $(hdrdir)/ruby/internal/special_consts.h
sockssocket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2066,20 +1913,12 @@ sockssocket.o: $(hdrdir)/ruby/ruby.h
sockssocket.o: $(hdrdir)/ruby/st.h
sockssocket.o: $(hdrdir)/ruby/subst.h
sockssocket.o: $(hdrdir)/ruby/thread.h
-sockssocket.o: $(hdrdir)/ruby/thread_native.h
sockssocket.o: $(hdrdir)/ruby/util.h
-sockssocket.o: $(hdrdir)/ruby/version.h
-sockssocket.o: $(top_srcdir)/ccan/check_type/check_type.h
-sockssocket.o: $(top_srcdir)/ccan/container_of/container_of.h
-sockssocket.o: $(top_srcdir)/ccan/list/list.h
-sockssocket.o: $(top_srcdir)/ccan/str/str.h
sockssocket.o: $(top_srcdir)/internal.h
sockssocket.o: $(top_srcdir)/internal/array.h
-sockssocket.o: $(top_srcdir)/internal/basic_operators.h
sockssocket.o: $(top_srcdir)/internal/compilers.h
sockssocket.o: $(top_srcdir)/internal/error.h
sockssocket.o: $(top_srcdir)/internal/gc.h
-sockssocket.o: $(top_srcdir)/internal/imemo.h
sockssocket.o: $(top_srcdir)/internal/io.h
sockssocket.o: $(top_srcdir)/internal/serial.h
sockssocket.o: $(top_srcdir)/internal/static_assert.h
@@ -2087,24 +1926,14 @@ sockssocket.o: $(top_srcdir)/internal/string.h
sockssocket.o: $(top_srcdir)/internal/thread.h
sockssocket.o: $(top_srcdir)/internal/vm.h
sockssocket.o: $(top_srcdir)/internal/warnings.h
-sockssocket.o: $(top_srcdir)/method.h
-sockssocket.o: $(top_srcdir)/node.h
-sockssocket.o: $(top_srcdir)/ruby_assert.h
-sockssocket.o: $(top_srcdir)/ruby_atomic.h
-sockssocket.o: $(top_srcdir)/rubyparser.h
sockssocket.o: $(top_srcdir)/shape.h
-sockssocket.o: $(top_srcdir)/thread_pthread.h
-sockssocket.o: $(top_srcdir)/vm_core.h
-sockssocket.o: $(top_srcdir)/vm_opts.h
sockssocket.o: constdefs.h
sockssocket.o: rubysocket.h
sockssocket.o: sockport.h
sockssocket.o: sockssocket.c
-sockssocket.o: {$(VPATH)}id.h
tcpserver.o: $(RUBY_EXTCONF_H)
tcpserver.o: $(arch_hdrdir)/ruby/config.h
tcpserver.o: $(hdrdir)/ruby/assert.h
-tcpserver.o: $(hdrdir)/ruby/atomic.h
tcpserver.o: $(hdrdir)/ruby/backward.h
tcpserver.o: $(hdrdir)/ruby/backward/2/assume.h
tcpserver.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -2157,7 +1986,6 @@ tcpserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h
tcpserver.o: $(hdrdir)/ruby/internal/attr/noinline.h
tcpserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h
tcpserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-tcpserver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
tcpserver.o: $(hdrdir)/ruby/internal/attr/pure.h
tcpserver.o: $(hdrdir)/ruby/internal/attr/restrict.h
tcpserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2226,6 +2054,7 @@ tcpserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h
tcpserver.o: $(hdrdir)/ruby/internal/intern/error.h
tcpserver.o: $(hdrdir)/ruby/internal/intern/eval.h
tcpserver.o: $(hdrdir)/ruby/internal/intern/file.h
+tcpserver.o: $(hdrdir)/ruby/internal/intern/gc.h
tcpserver.o: $(hdrdir)/ruby/internal/intern/hash.h
tcpserver.o: $(hdrdir)/ruby/internal/intern/io.h
tcpserver.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2256,6 +2085,7 @@ tcpserver.o: $(hdrdir)/ruby/internal/memory.h
tcpserver.o: $(hdrdir)/ruby/internal/method.h
tcpserver.o: $(hdrdir)/ruby/internal/module.h
tcpserver.o: $(hdrdir)/ruby/internal/newobj.h
+tcpserver.o: $(hdrdir)/ruby/internal/rgengc.h
tcpserver.o: $(hdrdir)/ruby/internal/scan_args.h
tcpserver.o: $(hdrdir)/ruby/internal/special_consts.h
tcpserver.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2275,20 +2105,12 @@ tcpserver.o: $(hdrdir)/ruby/ruby.h
tcpserver.o: $(hdrdir)/ruby/st.h
tcpserver.o: $(hdrdir)/ruby/subst.h
tcpserver.o: $(hdrdir)/ruby/thread.h
-tcpserver.o: $(hdrdir)/ruby/thread_native.h
tcpserver.o: $(hdrdir)/ruby/util.h
-tcpserver.o: $(hdrdir)/ruby/version.h
-tcpserver.o: $(top_srcdir)/ccan/check_type/check_type.h
-tcpserver.o: $(top_srcdir)/ccan/container_of/container_of.h
-tcpserver.o: $(top_srcdir)/ccan/list/list.h
-tcpserver.o: $(top_srcdir)/ccan/str/str.h
tcpserver.o: $(top_srcdir)/internal.h
tcpserver.o: $(top_srcdir)/internal/array.h
-tcpserver.o: $(top_srcdir)/internal/basic_operators.h
tcpserver.o: $(top_srcdir)/internal/compilers.h
tcpserver.o: $(top_srcdir)/internal/error.h
tcpserver.o: $(top_srcdir)/internal/gc.h
-tcpserver.o: $(top_srcdir)/internal/imemo.h
tcpserver.o: $(top_srcdir)/internal/io.h
tcpserver.o: $(top_srcdir)/internal/serial.h
tcpserver.o: $(top_srcdir)/internal/static_assert.h
@@ -2296,24 +2118,14 @@ tcpserver.o: $(top_srcdir)/internal/string.h
tcpserver.o: $(top_srcdir)/internal/thread.h
tcpserver.o: $(top_srcdir)/internal/vm.h
tcpserver.o: $(top_srcdir)/internal/warnings.h
-tcpserver.o: $(top_srcdir)/method.h
-tcpserver.o: $(top_srcdir)/node.h
-tcpserver.o: $(top_srcdir)/ruby_assert.h
-tcpserver.o: $(top_srcdir)/ruby_atomic.h
-tcpserver.o: $(top_srcdir)/rubyparser.h
tcpserver.o: $(top_srcdir)/shape.h
-tcpserver.o: $(top_srcdir)/thread_pthread.h
-tcpserver.o: $(top_srcdir)/vm_core.h
-tcpserver.o: $(top_srcdir)/vm_opts.h
tcpserver.o: constdefs.h
tcpserver.o: rubysocket.h
tcpserver.o: sockport.h
tcpserver.o: tcpserver.c
-tcpserver.o: {$(VPATH)}id.h
tcpsocket.o: $(RUBY_EXTCONF_H)
tcpsocket.o: $(arch_hdrdir)/ruby/config.h
tcpsocket.o: $(hdrdir)/ruby/assert.h
-tcpsocket.o: $(hdrdir)/ruby/atomic.h
tcpsocket.o: $(hdrdir)/ruby/backward.h
tcpsocket.o: $(hdrdir)/ruby/backward/2/assume.h
tcpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -2366,7 +2178,6 @@ tcpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
tcpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
tcpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
tcpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-tcpsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
tcpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
tcpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
tcpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2435,6 +2246,7 @@ tcpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
tcpsocket.o: $(hdrdir)/ruby/internal/intern/error.h
tcpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
tcpsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+tcpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
tcpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
tcpsocket.o: $(hdrdir)/ruby/internal/intern/io.h
tcpsocket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2465,6 +2277,7 @@ tcpsocket.o: $(hdrdir)/ruby/internal/memory.h
tcpsocket.o: $(hdrdir)/ruby/internal/method.h
tcpsocket.o: $(hdrdir)/ruby/internal/module.h
tcpsocket.o: $(hdrdir)/ruby/internal/newobj.h
+tcpsocket.o: $(hdrdir)/ruby/internal/rgengc.h
tcpsocket.o: $(hdrdir)/ruby/internal/scan_args.h
tcpsocket.o: $(hdrdir)/ruby/internal/special_consts.h
tcpsocket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2484,20 +2297,12 @@ tcpsocket.o: $(hdrdir)/ruby/ruby.h
tcpsocket.o: $(hdrdir)/ruby/st.h
tcpsocket.o: $(hdrdir)/ruby/subst.h
tcpsocket.o: $(hdrdir)/ruby/thread.h
-tcpsocket.o: $(hdrdir)/ruby/thread_native.h
tcpsocket.o: $(hdrdir)/ruby/util.h
-tcpsocket.o: $(hdrdir)/ruby/version.h
-tcpsocket.o: $(top_srcdir)/ccan/check_type/check_type.h
-tcpsocket.o: $(top_srcdir)/ccan/container_of/container_of.h
-tcpsocket.o: $(top_srcdir)/ccan/list/list.h
-tcpsocket.o: $(top_srcdir)/ccan/str/str.h
tcpsocket.o: $(top_srcdir)/internal.h
tcpsocket.o: $(top_srcdir)/internal/array.h
-tcpsocket.o: $(top_srcdir)/internal/basic_operators.h
tcpsocket.o: $(top_srcdir)/internal/compilers.h
tcpsocket.o: $(top_srcdir)/internal/error.h
tcpsocket.o: $(top_srcdir)/internal/gc.h
-tcpsocket.o: $(top_srcdir)/internal/imemo.h
tcpsocket.o: $(top_srcdir)/internal/io.h
tcpsocket.o: $(top_srcdir)/internal/serial.h
tcpsocket.o: $(top_srcdir)/internal/static_assert.h
@@ -2505,24 +2310,14 @@ tcpsocket.o: $(top_srcdir)/internal/string.h
tcpsocket.o: $(top_srcdir)/internal/thread.h
tcpsocket.o: $(top_srcdir)/internal/vm.h
tcpsocket.o: $(top_srcdir)/internal/warnings.h
-tcpsocket.o: $(top_srcdir)/method.h
-tcpsocket.o: $(top_srcdir)/node.h
-tcpsocket.o: $(top_srcdir)/ruby_assert.h
-tcpsocket.o: $(top_srcdir)/ruby_atomic.h
-tcpsocket.o: $(top_srcdir)/rubyparser.h
tcpsocket.o: $(top_srcdir)/shape.h
-tcpsocket.o: $(top_srcdir)/thread_pthread.h
-tcpsocket.o: $(top_srcdir)/vm_core.h
-tcpsocket.o: $(top_srcdir)/vm_opts.h
tcpsocket.o: constdefs.h
tcpsocket.o: rubysocket.h
tcpsocket.o: sockport.h
tcpsocket.o: tcpsocket.c
-tcpsocket.o: {$(VPATH)}id.h
udpsocket.o: $(RUBY_EXTCONF_H)
udpsocket.o: $(arch_hdrdir)/ruby/config.h
udpsocket.o: $(hdrdir)/ruby/assert.h
-udpsocket.o: $(hdrdir)/ruby/atomic.h
udpsocket.o: $(hdrdir)/ruby/backward.h
udpsocket.o: $(hdrdir)/ruby/backward/2/assume.h
udpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -2575,7 +2370,6 @@ udpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
udpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
udpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
udpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-udpsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
udpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
udpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
udpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2644,6 +2438,7 @@ udpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
udpsocket.o: $(hdrdir)/ruby/internal/intern/error.h
udpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
udpsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+udpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
udpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
udpsocket.o: $(hdrdir)/ruby/internal/intern/io.h
udpsocket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2674,6 +2469,7 @@ udpsocket.o: $(hdrdir)/ruby/internal/memory.h
udpsocket.o: $(hdrdir)/ruby/internal/method.h
udpsocket.o: $(hdrdir)/ruby/internal/module.h
udpsocket.o: $(hdrdir)/ruby/internal/newobj.h
+udpsocket.o: $(hdrdir)/ruby/internal/rgengc.h
udpsocket.o: $(hdrdir)/ruby/internal/scan_args.h
udpsocket.o: $(hdrdir)/ruby/internal/special_consts.h
udpsocket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2693,20 +2489,12 @@ udpsocket.o: $(hdrdir)/ruby/ruby.h
udpsocket.o: $(hdrdir)/ruby/st.h
udpsocket.o: $(hdrdir)/ruby/subst.h
udpsocket.o: $(hdrdir)/ruby/thread.h
-udpsocket.o: $(hdrdir)/ruby/thread_native.h
udpsocket.o: $(hdrdir)/ruby/util.h
-udpsocket.o: $(hdrdir)/ruby/version.h
-udpsocket.o: $(top_srcdir)/ccan/check_type/check_type.h
-udpsocket.o: $(top_srcdir)/ccan/container_of/container_of.h
-udpsocket.o: $(top_srcdir)/ccan/list/list.h
-udpsocket.o: $(top_srcdir)/ccan/str/str.h
udpsocket.o: $(top_srcdir)/internal.h
udpsocket.o: $(top_srcdir)/internal/array.h
-udpsocket.o: $(top_srcdir)/internal/basic_operators.h
udpsocket.o: $(top_srcdir)/internal/compilers.h
udpsocket.o: $(top_srcdir)/internal/error.h
udpsocket.o: $(top_srcdir)/internal/gc.h
-udpsocket.o: $(top_srcdir)/internal/imemo.h
udpsocket.o: $(top_srcdir)/internal/io.h
udpsocket.o: $(top_srcdir)/internal/serial.h
udpsocket.o: $(top_srcdir)/internal/static_assert.h
@@ -2714,24 +2502,14 @@ udpsocket.o: $(top_srcdir)/internal/string.h
udpsocket.o: $(top_srcdir)/internal/thread.h
udpsocket.o: $(top_srcdir)/internal/vm.h
udpsocket.o: $(top_srcdir)/internal/warnings.h
-udpsocket.o: $(top_srcdir)/method.h
-udpsocket.o: $(top_srcdir)/node.h
-udpsocket.o: $(top_srcdir)/ruby_assert.h
-udpsocket.o: $(top_srcdir)/ruby_atomic.h
-udpsocket.o: $(top_srcdir)/rubyparser.h
udpsocket.o: $(top_srcdir)/shape.h
-udpsocket.o: $(top_srcdir)/thread_pthread.h
-udpsocket.o: $(top_srcdir)/vm_core.h
-udpsocket.o: $(top_srcdir)/vm_opts.h
udpsocket.o: constdefs.h
udpsocket.o: rubysocket.h
udpsocket.o: sockport.h
udpsocket.o: udpsocket.c
-udpsocket.o: {$(VPATH)}id.h
unixserver.o: $(RUBY_EXTCONF_H)
unixserver.o: $(arch_hdrdir)/ruby/config.h
unixserver.o: $(hdrdir)/ruby/assert.h
-unixserver.o: $(hdrdir)/ruby/atomic.h
unixserver.o: $(hdrdir)/ruby/backward.h
unixserver.o: $(hdrdir)/ruby/backward/2/assume.h
unixserver.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -2784,7 +2562,6 @@ unixserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h
unixserver.o: $(hdrdir)/ruby/internal/attr/noinline.h
unixserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h
unixserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-unixserver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
unixserver.o: $(hdrdir)/ruby/internal/attr/pure.h
unixserver.o: $(hdrdir)/ruby/internal/attr/restrict.h
unixserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -2853,6 +2630,7 @@ unixserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h
unixserver.o: $(hdrdir)/ruby/internal/intern/error.h
unixserver.o: $(hdrdir)/ruby/internal/intern/eval.h
unixserver.o: $(hdrdir)/ruby/internal/intern/file.h
+unixserver.o: $(hdrdir)/ruby/internal/intern/gc.h
unixserver.o: $(hdrdir)/ruby/internal/intern/hash.h
unixserver.o: $(hdrdir)/ruby/internal/intern/io.h
unixserver.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -2883,6 +2661,7 @@ unixserver.o: $(hdrdir)/ruby/internal/memory.h
unixserver.o: $(hdrdir)/ruby/internal/method.h
unixserver.o: $(hdrdir)/ruby/internal/module.h
unixserver.o: $(hdrdir)/ruby/internal/newobj.h
+unixserver.o: $(hdrdir)/ruby/internal/rgengc.h
unixserver.o: $(hdrdir)/ruby/internal/scan_args.h
unixserver.o: $(hdrdir)/ruby/internal/special_consts.h
unixserver.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -2902,20 +2681,12 @@ unixserver.o: $(hdrdir)/ruby/ruby.h
unixserver.o: $(hdrdir)/ruby/st.h
unixserver.o: $(hdrdir)/ruby/subst.h
unixserver.o: $(hdrdir)/ruby/thread.h
-unixserver.o: $(hdrdir)/ruby/thread_native.h
unixserver.o: $(hdrdir)/ruby/util.h
-unixserver.o: $(hdrdir)/ruby/version.h
-unixserver.o: $(top_srcdir)/ccan/check_type/check_type.h
-unixserver.o: $(top_srcdir)/ccan/container_of/container_of.h
-unixserver.o: $(top_srcdir)/ccan/list/list.h
-unixserver.o: $(top_srcdir)/ccan/str/str.h
unixserver.o: $(top_srcdir)/internal.h
unixserver.o: $(top_srcdir)/internal/array.h
-unixserver.o: $(top_srcdir)/internal/basic_operators.h
unixserver.o: $(top_srcdir)/internal/compilers.h
unixserver.o: $(top_srcdir)/internal/error.h
unixserver.o: $(top_srcdir)/internal/gc.h
-unixserver.o: $(top_srcdir)/internal/imemo.h
unixserver.o: $(top_srcdir)/internal/io.h
unixserver.o: $(top_srcdir)/internal/serial.h
unixserver.o: $(top_srcdir)/internal/static_assert.h
@@ -2923,24 +2694,14 @@ unixserver.o: $(top_srcdir)/internal/string.h
unixserver.o: $(top_srcdir)/internal/thread.h
unixserver.o: $(top_srcdir)/internal/vm.h
unixserver.o: $(top_srcdir)/internal/warnings.h
-unixserver.o: $(top_srcdir)/method.h
-unixserver.o: $(top_srcdir)/node.h
-unixserver.o: $(top_srcdir)/ruby_assert.h
-unixserver.o: $(top_srcdir)/ruby_atomic.h
-unixserver.o: $(top_srcdir)/rubyparser.h
unixserver.o: $(top_srcdir)/shape.h
-unixserver.o: $(top_srcdir)/thread_pthread.h
-unixserver.o: $(top_srcdir)/vm_core.h
-unixserver.o: $(top_srcdir)/vm_opts.h
unixserver.o: constdefs.h
unixserver.o: rubysocket.h
unixserver.o: sockport.h
unixserver.o: unixserver.c
-unixserver.o: {$(VPATH)}id.h
unixsocket.o: $(RUBY_EXTCONF_H)
unixsocket.o: $(arch_hdrdir)/ruby/config.h
unixsocket.o: $(hdrdir)/ruby/assert.h
-unixsocket.o: $(hdrdir)/ruby/atomic.h
unixsocket.o: $(hdrdir)/ruby/backward.h
unixsocket.o: $(hdrdir)/ruby/backward/2/assume.h
unixsocket.o: $(hdrdir)/ruby/backward/2/attributes.h
@@ -2993,7 +2754,6 @@ unixsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h
unixsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h
unixsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h
unixsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-unixsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
unixsocket.o: $(hdrdir)/ruby/internal/attr/pure.h
unixsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h
unixsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -3062,6 +2822,7 @@ unixsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h
unixsocket.o: $(hdrdir)/ruby/internal/intern/error.h
unixsocket.o: $(hdrdir)/ruby/internal/intern/eval.h
unixsocket.o: $(hdrdir)/ruby/internal/intern/file.h
+unixsocket.o: $(hdrdir)/ruby/internal/intern/gc.h
unixsocket.o: $(hdrdir)/ruby/internal/intern/hash.h
unixsocket.o: $(hdrdir)/ruby/internal/intern/io.h
unixsocket.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -3092,6 +2853,7 @@ unixsocket.o: $(hdrdir)/ruby/internal/memory.h
unixsocket.o: $(hdrdir)/ruby/internal/method.h
unixsocket.o: $(hdrdir)/ruby/internal/module.h
unixsocket.o: $(hdrdir)/ruby/internal/newobj.h
+unixsocket.o: $(hdrdir)/ruby/internal/rgengc.h
unixsocket.o: $(hdrdir)/ruby/internal/scan_args.h
unixsocket.o: $(hdrdir)/ruby/internal/special_consts.h
unixsocket.o: $(hdrdir)/ruby/internal/static_assert.h
@@ -3111,20 +2873,12 @@ unixsocket.o: $(hdrdir)/ruby/ruby.h
unixsocket.o: $(hdrdir)/ruby/st.h
unixsocket.o: $(hdrdir)/ruby/subst.h
unixsocket.o: $(hdrdir)/ruby/thread.h
-unixsocket.o: $(hdrdir)/ruby/thread_native.h
unixsocket.o: $(hdrdir)/ruby/util.h
-unixsocket.o: $(hdrdir)/ruby/version.h
-unixsocket.o: $(top_srcdir)/ccan/check_type/check_type.h
-unixsocket.o: $(top_srcdir)/ccan/container_of/container_of.h
-unixsocket.o: $(top_srcdir)/ccan/list/list.h
-unixsocket.o: $(top_srcdir)/ccan/str/str.h
unixsocket.o: $(top_srcdir)/internal.h
unixsocket.o: $(top_srcdir)/internal/array.h
-unixsocket.o: $(top_srcdir)/internal/basic_operators.h
unixsocket.o: $(top_srcdir)/internal/compilers.h
unixsocket.o: $(top_srcdir)/internal/error.h
unixsocket.o: $(top_srcdir)/internal/gc.h
-unixsocket.o: $(top_srcdir)/internal/imemo.h
unixsocket.o: $(top_srcdir)/internal/io.h
unixsocket.o: $(top_srcdir)/internal/serial.h
unixsocket.o: $(top_srcdir)/internal/static_assert.h
@@ -3132,18 +2886,9 @@ unixsocket.o: $(top_srcdir)/internal/string.h
unixsocket.o: $(top_srcdir)/internal/thread.h
unixsocket.o: $(top_srcdir)/internal/vm.h
unixsocket.o: $(top_srcdir)/internal/warnings.h
-unixsocket.o: $(top_srcdir)/method.h
-unixsocket.o: $(top_srcdir)/node.h
-unixsocket.o: $(top_srcdir)/ruby_assert.h
-unixsocket.o: $(top_srcdir)/ruby_atomic.h
-unixsocket.o: $(top_srcdir)/rubyparser.h
unixsocket.o: $(top_srcdir)/shape.h
-unixsocket.o: $(top_srcdir)/thread_pthread.h
-unixsocket.o: $(top_srcdir)/vm_core.h
-unixsocket.o: $(top_srcdir)/vm_opts.h
unixsocket.o: constdefs.h
unixsocket.o: rubysocket.h
unixsocket.o: sockport.h
unixsocket.o: unixsocket.c
-unixsocket.o: {$(VPATH)}id.h
# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index d44ce31b0a..37ff216560 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -327,8 +327,6 @@ end
net/if_dl.h
arpa/nameser.h
resolv.h
- pthread.h
- sched.h
].each {|h|
if have_header(h, headers)
headers << h
@@ -349,22 +347,10 @@ have_type("struct sockaddr_storage", headers)
have_type("struct addrinfo", headers)
-def check_socklen(headers)
- def (fmt = "none").%(x)
- x || self
- end
- s = checking_for("RSTRING_SOCKLEN", fmt) do
- if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers)
- "RSTRING_LEN"
- else
- "RSTRING_LENINT"
- end
- end
- $defs << "-DRSTRING_SOCKLEN=(socklen_t)"+s
-end
-
if have_type("socklen_t", headers)
- check_socklen(headers)
+ if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers)
+ $defs << "-DRSTRING_SOCKLEN=(socklen_t)RSTRING_LEN"
+ end
end
have_type("struct in_pktinfo", headers) {|src|
@@ -701,10 +687,5 @@ SRC
"not needed"
end
end
-
- have_func("pthread_create")
- have_func("pthread_detach")
-
- $VPATH << '$(topdir)' << '$(top_srcdir)'
create_makefile("socket")
end
diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c
index bf0d90129f..95a2feb3be 100644
--- a/ext/socket/getaddrinfo.c
+++ b/ext/socket/getaddrinfo.c
@@ -219,7 +219,8 @@ freeaddrinfo(struct addrinfo *ai)
do {
next = ai->ai_next;
- free(ai->ai_canonname);
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
/* no need to free(ai->ai_addr) */
free(ai);
} while ((ai = next) != NULL);
diff --git a/ext/socket/init.c b/ext/socket/init.c
index dd1158e19d..557d4374a5 100644
--- a/ext/socket/init.c
+++ b/ext/socket/init.c
@@ -27,7 +27,6 @@ VALUE rb_cSocket;
VALUE rb_cAddrinfo;
VALUE rb_eSocket;
-VALUE rb_eResolution;
#ifdef SOCKS
VALUE rb_cSOCKSSocket;
@@ -35,10 +34,9 @@ VALUE rb_cSOCKSSocket;
int rsock_do_not_reverse_lookup = 1;
static VALUE sym_wait_readable;
-static ID id_error_code;
void
-rsock_raise_resolution_error(const char *reason, int error)
+rsock_raise_socket_error(const char *reason, int error)
{
#ifdef EAI_SYSTEM
int e;
@@ -50,14 +48,10 @@ rsock_raise_resolution_error(const char *reason, int error)
VALUE msg = rb_sprintf("%s: ", reason);
if (!enc) enc = rb_default_internal_encoding();
rb_str_concat(msg, rb_w32_conv_from_wchar(gai_strerrorW(error), enc));
+ rb_exc_raise(rb_exc_new_str(rb_eSocket, msg));
#else
- VALUE msg = rb_sprintf("%s: %s", reason, gai_strerror(error));
+ rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error));
#endif
-
- StringValue(msg);
- VALUE self = rb_class_new_instance(1, &msg, rb_eResolution);
- rb_ivar_set(self, id_error_code, INT2NUM(error));
- rb_exc_raise(self);
}
#if defined __APPLE__
@@ -122,7 +116,6 @@ recvfrom_blocking(void *data)
ssize_t ret;
ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), arg->length,
arg->flags, &arg->buf.addr, &arg->alen);
-
if (ret != -1 && len0 < arg->alen)
arg->alen = len0;
@@ -154,18 +147,6 @@ recvfrom_locktmp(VALUE v)
return rb_thread_io_blocking_region(recvfrom_blocking, arg, arg->fd);
}
-int
-rsock_is_dgram(rb_io_t *fptr)
-{
- int socktype;
- socklen_t optlen = (socklen_t)sizeof(socktype);
- int ret = getsockopt(fptr->fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen);
- if (ret == -1) {
- rb_sys_fail("getsockopt(SO_TYPE)");
- }
- return socktype == SOCK_DGRAM;
-}
-
VALUE
rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from)
{
@@ -206,9 +187,6 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from)
slen = (long)rb_str_locktmp_ensure(str, recvfrom_locktmp, (VALUE)&arg);
- if (slen == 0 && !rsock_is_dgram(fptr)) {
- return Qnil;
- }
if (slen >= 0) break;
if (!rb_io_maybe_wait_readable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT))
@@ -281,10 +259,6 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
if (slen != -1 && len0 < alen)
alen = len0;
- if (slen == 0 && !rsock_is_dgram(fptr)) {
- return Qnil;
- }
-
if (slen < 0) {
int e = errno;
switch (e) {
@@ -418,7 +392,7 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex)
if (e == EWOULDBLOCK || e == EAGAIN) {
if (ex == Qfalse) return sym_wait_writable;
rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e,
- "write would block");
+ "write would block");
}
rb_syserr_fail_path(e, fptr->pathv);
}
@@ -459,9 +433,9 @@ rsock_socket(int domain, int type, int proto)
fd = rsock_socket0(domain, type, proto);
if (fd < 0) {
- if (rb_gc_for_fd(errno)) {
- fd = rsock_socket0(domain, type, proto);
- }
+ if (rb_gc_for_fd(errno)) {
+ fd = rsock_socket0(domain, type, proto);
+ }
}
if (0 <= fd)
rb_update_max_fd(fd);
@@ -518,10 +492,10 @@ wait_connectable(int fd, struct timeval *timeout)
switch (sockerr) {
case 0:
- /*
- * be defensive in case some platforms set SO_ERROR on the original,
- * interrupted connect()
- */
+ /*
+ * be defensive in case some platforms set SO_ERROR on the original,
+ * interrupted connect()
+ */
/* when the connection timed out, no errno is set and revents is 0. */
if (timeout && revents == 0) {
@@ -707,9 +681,9 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len)
RB_IO_POINTER(io, fptr);
struct accept_arg accept_arg = {
- .fd = fptr->fd,
- .sockaddr = sockaddr,
- .len = len
+ .fd = fptr->fd,
+ .sockaddr = sockaddr,
+ .len = len
};
int retry = 0, peer;
@@ -756,10 +730,10 @@ rsock_getfamily(rb_io_t *fptr)
if (cached) {
switch (cached) {
#ifdef AF_UNIX
- case FMODE_UNIX: return AF_UNIX;
+ case FMODE_UNIX: return AF_UNIX;
#endif
- case FMODE_INET: return AF_INET;
- case FMODE_INET6: return AF_INET6;
+ case FMODE_INET: return AF_INET;
+ case FMODE_INET6: return AF_INET6;
}
}
@@ -778,18 +752,6 @@ rsock_getfamily(rb_io_t *fptr)
return ss.addr.sa_family;
}
-/*
- * call-seq:
- * error_code -> integer
- *
- * Returns the raw error code occurred at name resolution.
- */
-static VALUE
-sock_resolv_error_code(VALUE self)
-{
- return rb_attr_get(self, id_error_code);
-}
-
void
rsock_init_socket_init(void)
{
@@ -797,11 +759,6 @@ rsock_init_socket_init(void)
* SocketError is the error class for socket.
*/
rb_eSocket = rb_define_class("SocketError", rb_eStandardError);
- /*
- * ResolutionError is the error class for socket name resolution.
- */
- rb_eResolution = rb_define_class_under(rb_cSocket, "ResolutionError", rb_eSocket);
- rb_define_method(rb_eResolution, "error_code", sock_resolv_error_code, 0);
rsock_init_ipsocket();
rsock_init_tcpsocket();
rsock_init_tcpserver();
@@ -815,8 +772,6 @@ rsock_init_socket_init(void)
rsock_init_sockifaddr();
rsock_init_socket_constants();
- id_error_code = rb_intern_const("error_code");
-
#undef rb_intern
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb
index de542223c6..eecdc7d4b8 100644
--- a/ext/socket/lib/socket.rb
+++ b/ext/socket/lib/socket.rb
@@ -333,10 +333,9 @@ class BasicSocket < IO
# _flags_ is zero or more of the +MSG_+ options.
# The result, _mesg_, is the data received.
#
- # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil.
- # In most cases it means the connection was closed, but for UDP connections
- # it may mean an empty packet was received, as the underlying API makes
- # it impossible to distinguish these two cases.
+ # When recvfrom(2) returns 0, Socket#recv_nonblock returns
+ # an empty string as data.
+ # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
#
# === Parameters
# * +maxlen+ - the number of bytes to receive from the socket
@@ -481,10 +480,9 @@ class Socket < BasicSocket
# The second element, _sender_addrinfo_, contains protocol-specific address
# information of the sender.
#
- # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil.
- # In most cases it means the connection was closed, but for UDP connections
- # it may mean an empty packet was received, as the underlying API makes
- # it impossible to distinguish these two cases.
+ # When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns
+ # an empty string as data.
+ # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
#
# === Parameters
# * +maxlen+ - the maximum number of bytes to receive from the socket
@@ -1231,10 +1229,9 @@ class UDPSocket < IPSocket
# The first element of the results, _mesg_, is the data received.
# The second element, _sender_inet_addr_, is an array to represent the sender address.
#
- # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil.
- # In most cases it means the connection was closed, but it may also mean
- # an empty packet was received, as the underlying API makes
- # it impossible to distinguish these two cases.
+ # When recvfrom(2) returns 0,
+ # Socket#recvfrom_nonblock returns an empty string as data.
+ # It means an empty packet.
#
# === Parameters
# * +maxlen+ - the number of bytes to receive from the socket
diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb
index ba7a55b426..5e6c0668f6 100644
--- a/ext/socket/mkconstants.rb
+++ b/ext/socket/mkconstants.rb
@@ -51,10 +51,7 @@ DATA.each_line {|s|
next
end
h[name] = default_value
- if comment
- # Stop unintentional references
- COMMENTS[name] = comment.gsub(/\b(Data|Kernel|Process|Set|Socket|Time)\b/, '\\\\\\&')
- end
+ COMMENTS[name] = comment
}
DEFS = h.to_a
@@ -426,8 +423,8 @@ AF_ISDN nil Integrated Services Digital Network
PF_ISDN nil Integrated Services Digital Network
AF_NATM nil Native ATM access
PF_NATM nil Native ATM access
-AF_SYSTEM nil Kernel event messages
-PF_SYSTEM nil Kernel event messages
+AF_SYSTEM
+PF_SYSTEM
AF_NETBIOS nil NetBIOS
PF_NETBIOS nil NetBIOS
AF_PPP nil Point-to-Point Protocol
@@ -443,8 +440,8 @@ PF_PACKET nil Direct link-layer access
AF_E164 nil CCITT (ITU-T) E.164 recommendation
PF_XTP nil eXpress Transfer Protocol
-PF_RTIP nil Help Identify RTIP packets
-PF_PIP nil Help Identify PIP packets
+PF_RTIP
+PF_PIP
AF_KEY nil Key management protocol, originally developed for usage with IPsec
PF_KEY nil Key management protocol, originally developed for usage with IPsec
AF_NETLINK nil Kernel user interface device
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index e79bcfa332..45b4cad38f 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -10,22 +10,6 @@
#include "rubysocket.h"
-// GETADDRINFO_IMPL == 0 : call getaddrinfo/getnameinfo directly
-// GETADDRINFO_IMPL == 1 : call getaddrinfo/getnameinfo without gvl (but uncancellable)
-// GETADDRINFO_IMPL == 2 : call getaddrinfo/getnameinfo in a dedicated pthread
-// (and if the call is interrupted, the pthread is detached)
-
-#ifndef GETADDRINFO_IMPL
-# ifdef GETADDRINFO_EMU
-# define GETADDRINFO_IMPL 0
-# elif !defined(HAVE_PTHREAD_CREATE) || !defined(HAVE_PTHREAD_DETACH) || defined(__MINGW32__) || defined(__MINGW64__)
-# define GETADDRINFO_IMPL 1
-# else
-# define GETADDRINFO_IMPL 2
-# include "ruby/thread_native.h"
-# endif
-#endif
-
#if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6))
#define LOOKUP_ORDERS (sizeof(lookup_order_table) / sizeof(lookup_order_table[0]))
static const int lookup_order_table[] = {
@@ -189,6 +173,32 @@ parse_numeric_port(const char *service, int *portp)
}
#endif
+#ifndef GETADDRINFO_EMU
+struct getaddrinfo_arg
+{
+ const char *node;
+ const char *service;
+ const struct addrinfo *hints;
+ struct addrinfo **res;
+};
+
+static void *
+nogvl_getaddrinfo(void *arg)
+{
+ int ret;
+ struct getaddrinfo_arg *ptr = arg;
+ ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res);
+#ifdef __linux__
+ /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and
+ * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420]
+ */
+ if (ret == EAI_SYSTEM && errno == ENOENT)
+ ret = EAI_NONAME;
+#endif
+ return (void *)(VALUE)ret;
+}
+#endif
+
static int
numeric_getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
@@ -277,8 +287,9 @@ numeric_getaddrinfo(const char *node, const char *service,
void
rb_freeaddrinfo(struct rb_addrinfo *ai)
{
- if (!ai->allocated_by_malloc)
- freeaddrinfo(ai->ai);
+ if (!ai->allocated_by_malloc) {
+ if (ai->ai) freeaddrinfo(ai->ai);
+ }
else {
struct addrinfo *ai1, *ai2;
ai1 = ai->ai;
@@ -292,263 +303,7 @@ rb_freeaddrinfo(struct rb_addrinfo *ai)
xfree(ai);
}
-#if GETADDRINFO_IMPL == 0
-
-static int
-rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai)
-{
- return getaddrinfo(hostp, portp, hints, ai);
-}
-
-#elif GETADDRINFO_IMPL == 1
-
-struct getaddrinfo_arg
-{
- const char *node;
- const char *service;
- const struct addrinfo *hints;
- struct addrinfo **res;
-};
-
-static void *
-nogvl_getaddrinfo(void *arg)
-{
- int ret;
- struct getaddrinfo_arg *ptr = arg;
- ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res);
-#ifdef __linux__
- /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and
- * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420]
- */
- if (ret == EAI_SYSTEM && errno == ENOENT)
- ret = EAI_NONAME;
-#endif
- return (void *)(VALUE)ret;
-}
-
-static int
-rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai)
-{
- struct getaddrinfo_arg arg;
- MEMZERO(&arg, struct getaddrinfo_arg, 1);
- arg.node = hostp;
- arg.service = portp;
- arg.hints = hints;
- arg.res = ai;
- return (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
-}
-
-#elif GETADDRINFO_IMPL == 2
-
-struct getaddrinfo_arg
-{
- char *node, *service;
- struct addrinfo hints;
- struct addrinfo *ai;
- int err, gai_errno, refcount, done, cancelled;
- rb_nativethread_lock_t lock;
- rb_nativethread_cond_t cond;
-};
-
-static struct getaddrinfo_arg *
-allocate_getaddrinfo_arg(const char *hostp, const char *portp, const struct addrinfo *hints)
-{
- size_t hostp_offset = sizeof(struct getaddrinfo_arg);
- size_t portp_offset = hostp_offset + (hostp ? strlen(hostp) + 1 : 0);
- size_t bufsize = portp_offset + (portp ? strlen(portp) + 1 : 0);
-
- char *buf = malloc(bufsize);
- if (!buf) {
- rb_gc();
- buf = malloc(bufsize);
- if (!buf) return NULL;
- }
- struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)buf;
-
- if (hostp) {
- arg->node = buf + hostp_offset;
- strcpy(arg->node, hostp);
- }
- else {
- arg->node = NULL;
- }
-
- if (portp) {
- arg->service = buf + portp_offset;
- strcpy(arg->service, portp);
- }
- else {
- arg->service = NULL;
- }
-
- arg->hints = *hints;
- arg->ai = NULL;
-
- arg->refcount = 2;
- arg->done = arg->cancelled = 0;
-
- rb_nativethread_lock_initialize(&arg->lock);
- rb_native_cond_initialize(&arg->cond);
-
- return arg;
-}
-
-static void
-free_getaddrinfo_arg(struct getaddrinfo_arg *arg)
-{
- rb_native_cond_destroy(&arg->cond);
- rb_nativethread_lock_destroy(&arg->lock);
- free(arg);
-}
-
-static void *
-do_getaddrinfo(void *ptr)
-{
- struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr;
-
- int err, gai_errno;
- err = getaddrinfo(arg->node, arg->service, &arg->hints, &arg->ai);
- gai_errno = errno;
-#ifdef __linux__
- /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and
- * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420]
- */
- if (err == EAI_SYSTEM && errno == ENOENT)
- err = EAI_NONAME;
-#endif
-
- int need_free = 0;
- rb_nativethread_lock_lock(&arg->lock);
- {
- arg->err = err;
- arg->gai_errno = gai_errno;
- if (arg->cancelled) {
- freeaddrinfo(arg->ai);
- }
- else {
- arg->done = 1;
- rb_native_cond_signal(&arg->cond);
- }
- if (--arg->refcount == 0) need_free = 1;
- }
- rb_nativethread_lock_unlock(&arg->lock);
-
- if (need_free) free_getaddrinfo_arg(arg);
-
- return 0;
-}
-
-static void *
-wait_getaddrinfo(void *ptr)
-{
- struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr;
- rb_nativethread_lock_lock(&arg->lock);
- while (!arg->done && !arg->cancelled) {
- rb_native_cond_wait(&arg->cond, &arg->lock);
- }
- rb_nativethread_lock_unlock(&arg->lock);
- return 0;
-}
-
-static void
-cancel_getaddrinfo(void *ptr)
-{
- struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr;
- rb_nativethread_lock_lock(&arg->lock);
- {
- arg->cancelled = 1;
- rb_native_cond_signal(&arg->cond);
- }
- rb_nativethread_lock_unlock(&arg->lock);
-}
-
-static int
-do_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg)
-{
- int limit = 3, ret;
- do {
- // It is said that pthread_create may fail spuriously, so we follow the JDK and retry several times.
- //
- // https://bugs.openjdk.org/browse/JDK-8268605
- // https://github.com/openjdk/jdk/commit/e35005d5ce383ddd108096a3079b17cb0bcf76f1
- ret = pthread_create(th, 0, start_routine, arg);
- } while (ret == EAGAIN && limit-- > 0);
- return ret;
-}
-
-static int
-rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai)
-{
- int retry;
- struct getaddrinfo_arg *arg;
- int err, gai_errno = 0;
-
-start:
- retry = 0;
-
- arg = allocate_getaddrinfo_arg(hostp, portp, hints);
- if (!arg) {
- return EAI_MEMORY;
- }
-
- pthread_t th;
- if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) {
- free_getaddrinfo_arg(arg);
- return EAI_AGAIN;
- }
- pthread_detach(th);
-
- rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg);
-
- int need_free = 0;
- rb_nativethread_lock_lock(&arg->lock);
- {
- if (arg->done) {
- err = arg->err;
- gai_errno = arg->gai_errno;
- if (err == 0) *ai = arg->ai;
- }
- else if (arg->cancelled) {
- err = EAI_AGAIN;
- }
- else {
- // If already interrupted, rb_thread_call_without_gvl2 may return without calling wait_getaddrinfo.
- // In this case, it could be !arg->done && !arg->cancelled.
- arg->cancelled = 1; // to make do_getaddrinfo call freeaddrinfo
- retry = 1;
- }
- if (--arg->refcount == 0) need_free = 1;
- }
- rb_nativethread_lock_unlock(&arg->lock);
-
- if (need_free) free_getaddrinfo_arg(arg);
-
- // If the current thread is interrupted by asynchronous exception, the following raises the exception.
- // But if the current thread is interrupted by timer thread, the following returns; we need to manually retry.
- rb_thread_check_ints();
- if (retry) goto start;
-
- /* Because errno is threadlocal, the errno value we got from the call to getaddrinfo() in the thread
- * (in case of EAI_SYSTEM return value) is not propagated to the caller of _this_ function. Set errno
- * explicitly, as round-tripped through struct getaddrinfo_arg, to deal with that */
- if (gai_errno) errno = gai_errno;
- return err;
-}
-
-#endif
-
-#if GETADDRINFO_IMPL == 0
-
-int
-rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
- char *host, size_t hostlen,
- char *serv, size_t servlen, int flags)
-{
- return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
-}
-
-#elif GETADDRINFO_IMPL == 1
-
+#ifndef GETADDRINFO_EMU
struct getnameinfo_arg
{
const struct sockaddr *sa;
@@ -569,11 +324,16 @@ nogvl_getnameinfo(void *arg)
ptr->serv, (socklen_t)ptr->servlen,
ptr->flags);
}
+#endif
+
int
rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
- char *host, size_t hostlen,
- char *serv, size_t servlen, int flags)
+ char *host, size_t hostlen,
+ char *serv, size_t servlen, int flags)
{
+#ifdef GETADDRINFO_EMU
+ return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+#else
struct getnameinfo_arg arg;
int ret;
arg.sa = sa;
@@ -585,176 +345,8 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
arg.flags = flags;
ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getnameinfo, &arg, RUBY_UBF_IO, 0);
return ret;
-}
-
-#elif GETADDRINFO_IMPL == 2
-
-struct getnameinfo_arg
-{
- struct sockaddr *sa;
- socklen_t salen;
- int flags;
- char *host;
- size_t hostlen;
- char *serv;
- size_t servlen;
- int err, gni_errno, refcount, done, cancelled;
- rb_nativethread_lock_t lock;
- rb_nativethread_cond_t cond;
-};
-
-static struct getnameinfo_arg *
-allocate_getnameinfo_arg(const struct sockaddr *sa, socklen_t salen, size_t hostlen, size_t servlen, int flags)
-{
- size_t sa_offset = sizeof(struct getnameinfo_arg);
- size_t host_offset = sa_offset + salen;
- size_t serv_offset = host_offset + hostlen;
- size_t bufsize = serv_offset + servlen;
-
- char *buf = malloc(bufsize);
- if (!buf) {
- rb_gc();
- buf = malloc(bufsize);
- if (!buf) return NULL;
- }
- struct getnameinfo_arg *arg = (struct getnameinfo_arg *)buf;
-
- arg->sa = (struct sockaddr *)(buf + sa_offset);
- memcpy(arg->sa, sa, salen);
- arg->salen = salen;
- arg->host = buf + host_offset;
- arg->hostlen = hostlen;
- arg->serv = buf + serv_offset;
- arg->servlen = servlen;
- arg->flags = flags;
-
- arg->refcount = 2;
- arg->done = arg->cancelled = 0;
-
- rb_nativethread_lock_initialize(&arg->lock);
- rb_native_cond_initialize(&arg->cond);
-
- return arg;
-}
-
-static void
-free_getnameinfo_arg(struct getnameinfo_arg *arg)
-{
- rb_native_cond_destroy(&arg->cond);
- rb_nativethread_lock_destroy(&arg->lock);
-
- free(arg);
-}
-
-static void *
-do_getnameinfo(void *ptr)
-{
- struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr;
-
- int err, gni_errno;
- err = getnameinfo(arg->sa, arg->salen, arg->host, (socklen_t)arg->hostlen, arg->serv, (socklen_t)arg->servlen, arg->flags);
- gni_errno = errno;
-
- int need_free = 0;
- rb_nativethread_lock_lock(&arg->lock);
- arg->err = err;
- arg->gni_errno = gni_errno;
- if (!arg->cancelled) {
- arg->done = 1;
- rb_native_cond_signal(&arg->cond);
- }
- if (--arg->refcount == 0) need_free = 1;
- rb_nativethread_lock_unlock(&arg->lock);
-
- if (need_free) free_getnameinfo_arg(arg);
-
- return 0;
-}
-
-static void *
-wait_getnameinfo(void *ptr)
-{
- struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr;
- rb_nativethread_lock_lock(&arg->lock);
- while (!arg->done && !arg->cancelled) {
- rb_native_cond_wait(&arg->cond, &arg->lock);
- }
- rb_nativethread_lock_unlock(&arg->lock);
- return 0;
-}
-
-static void
-cancel_getnameinfo(void *ptr)
-{
- struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr;
- rb_nativethread_lock_lock(&arg->lock);
- arg->cancelled = 1;
- rb_native_cond_signal(&arg->cond);
- rb_nativethread_lock_unlock(&arg->lock);
-}
-
-int
-rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
- char *host, size_t hostlen,
- char *serv, size_t servlen, int flags)
-{
- int retry;
- struct getnameinfo_arg *arg;
- int err, gni_errno = 0;
-
-start:
- retry = 0;
-
- arg = allocate_getnameinfo_arg(sa, salen, hostlen, servlen, flags);
- if (!arg) {
- return EAI_MEMORY;
- }
-
- pthread_t th;
- if (do_pthread_create(&th, do_getnameinfo, arg) != 0) {
- free_getnameinfo_arg(arg);
- return EAI_AGAIN;
- }
- pthread_detach(th);
-
- rb_thread_call_without_gvl2(wait_getnameinfo, arg, cancel_getnameinfo, arg);
-
- int need_free = 0;
- rb_nativethread_lock_lock(&arg->lock);
- if (arg->done) {
- err = arg->err;
- gni_errno = arg->gni_errno;
- if (err == 0) {
- if (host) memcpy(host, arg->host, hostlen);
- if (serv) memcpy(serv, arg->serv, servlen);
- }
- }
- else if (arg->cancelled) {
- err = EAI_AGAIN;
- }
- else {
- // If already interrupted, rb_thread_call_without_gvl2 may return without calling wait_getnameinfo.
- // In this case, it could be !arg->done && !arg->cancelled.
- arg->cancelled = 1;
- retry = 1;
- }
- if (--arg->refcount == 0) need_free = 1;
- rb_nativethread_lock_unlock(&arg->lock);
-
- if (need_free) free_getnameinfo_arg(arg);
-
- // If the current thread is interrupted by asynchronous exception, the following raises the exception.
- // But if the current thread is interrupted by timer thread, the following returns; we need to manually retry.
- rb_thread_check_ints();
- if (retry) goto start;
-
- /* Make sure we copy the thread-local errno value from the getnameinfo thread back to this thread, so
- * calling code sees the correct errno */
- if (gni_errno) errno = gni_errno;
- return err;
-}
-
#endif
+}
static void
make_ipaddr0(struct sockaddr *addr, socklen_t addrlen, char *buf, size_t buflen)
@@ -763,7 +355,7 @@ make_ipaddr0(struct sockaddr *addr, socklen_t addrlen, char *buf, size_t buflen)
error = rb_getnameinfo(addr, addrlen, buf, buflen, NULL, 0, NI_NUMERICHOST);
if (error) {
- rsock_raise_resolution_error("getnameinfo", error);
+ rsock_raise_socket_error("getnameinfo", error);
}
}
@@ -959,7 +551,17 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h
}
if (!resolved) {
- error = rb_getaddrinfo(hostp, portp, hints, &ai);
+#ifdef GETADDRINFO_EMU
+ error = getaddrinfo(hostp, portp, hints, &ai);
+#else
+ struct getaddrinfo_arg arg;
+ MEMZERO(&arg, struct getaddrinfo_arg, 1);
+ arg.node = hostp;
+ arg.service = portp;
+ arg.hints = hints;
+ arg.res = &ai;
+ error = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
+#endif
if (error == 0) {
res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo));
res->allocated_by_malloc = 0;
@@ -972,7 +574,7 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h
if (hostp && hostp[strlen(hostp)-1] == '\n') {
rb_raise(rb_eSocket, "newline at the end of hostname");
}
- rsock_raise_resolution_error("getaddrinfo", error);
+ rsock_raise_socket_error("getaddrinfo", error);
}
return res;
@@ -1031,7 +633,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup)
error = rb_getnameinfo(sockaddr, sockaddrlen, hbuf, sizeof(hbuf),
pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV);
if (error) {
- rsock_raise_resolution_error("getnameinfo", error);
+ rsock_raise_socket_error("getnameinfo", error);
}
addr2 = rb_str_new2(hbuf);
if (addr1 == Qnil) {
@@ -1665,11 +1267,11 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r
* RFC 4007: IPv6 Scoped Address Architecture
* draft-ietf-ipv6-scope-api-00.txt: Scoped Address Extensions to the IPv6 Basic Socket API
*/
- error = rb_getnameinfo(&sockaddr->addr, socklen,
- hbuf, (socklen_t)sizeof(hbuf), NULL, 0,
- NI_NUMERICHOST|NI_NUMERICSERV);
+ error = getnameinfo(&sockaddr->addr, socklen,
+ hbuf, (socklen_t)sizeof(hbuf), NULL, 0,
+ NI_NUMERICHOST|NI_NUMERICSERV);
if (error) {
- rsock_raise_resolution_error("getnameinfo", error);
+ rsock_raise_socket_error("getnameinfo", error);
}
if (addr->sin6_port == 0) {
rb_str_cat2(ret, hbuf);
@@ -2033,11 +1635,11 @@ addrinfo_mdump(VALUE self)
{
char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
int error;
- error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len,
- hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
- NI_NUMERICHOST|NI_NUMERICSERV);
+ error = getnameinfo(&rai->addr.addr, rai->sockaddr_len,
+ hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
+ NI_NUMERICHOST|NI_NUMERICSERV);
if (error) {
- rsock_raise_resolution_error("getnameinfo", error);
+ rsock_raise_socket_error("getnameinfo", error);
}
sockaddr = rb_assoc_new(rb_str_new_cstr(hbuf), rb_str_new_cstr(pbuf));
break;
@@ -2379,11 +1981,11 @@ addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self)
if (rai->socktype == SOCK_DGRAM)
flags |= NI_DGRAM;
- error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len,
- hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
- flags);
+ error = getnameinfo(&rai->addr.addr, rai->sockaddr_len,
+ hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
+ flags);
if (error) {
- rsock_raise_resolution_error("getnameinfo", error);
+ rsock_raise_socket_error("getnameinfo", error);
}
return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));
@@ -3013,12 +2615,12 @@ rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
void
rsock_init_addrinfo(void)
{
- id_timeout = rb_intern("timeout");
-
/*
* The Addrinfo class maps <tt>struct addrinfo</tt> to ruby. This
* structure identifies an Internet host and a service.
*/
+ id_timeout = rb_intern("timeout");
+
rb_cAddrinfo = rb_define_class("Addrinfo", rb_cObject);
rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate);
rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1);
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index 283735b12c..5f803ba0da 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -285,7 +285,6 @@ extern VALUE rb_cAddrinfo;
extern VALUE rb_cSockOpt;
extern VALUE rb_eSocket;
-extern VALUE rb_eResolution;
#ifdef SOCKS
extern VALUE rb_cSOCKSSocket;
@@ -308,7 +307,7 @@ VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *ai_ret
VALUE rb_check_sockaddr_string_type(VALUE);
-NORETURN(void rsock_raise_resolution_error(const char *, int));
+NORETURN(void rsock_raise_socket_error(const char *, int));
int rsock_family_arg(VALUE domain);
int rsock_socktype_arg(VALUE type);
@@ -460,8 +459,6 @@ VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex);
void rsock_make_fd_nonblock(int fd);
-int rsock_is_dgram(rb_io_t *fptr);
-
#if !defined HAVE_INET_NTOP && ! defined _WIN32
const char *inet_ntop(int, const void *, char *, size_t);
#elif defined __MINGW32__
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index c780d77cf6..eb74f7a936 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -1313,7 +1313,7 @@ sock_s_getnameinfo(int argc, VALUE *argv, VALUE _)
saved_errno = errno;
if (res) rb_freeaddrinfo(res);
errno = saved_errno;
- rsock_raise_resolution_error("getnameinfo", error);
+ rsock_raise_socket_error("getnameinfo", error);
UNREACHABLE_RETURN(Qnil);
}
@@ -1654,7 +1654,8 @@ socket_s_ip_address_list(VALUE self)
finish:
save_errno = errno;
- xfree(lc.lifc_req);
+ if (lc.lifc_buf != NULL)
+ xfree(lc.lifc_req);
if (fd != -1)
close(fd);
errno = save_errno;
diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c
index a8475e3e60..26ab76fc9f 100644
--- a/ext/socket/unixsocket.c
+++ b/ext/socket/unixsocket.c
@@ -540,7 +540,7 @@ unix_peeraddr(VALUE sock)
*
* Creates a pair of sockets connected to each other.
*
- * _type_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
+ * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
*
* _protocol_ should be a protocol defined in the domain.
* 0 is default protocol for the domain.
diff --git a/ext/stringio/depend b/ext/stringio/depend
index ba2b812041..828fc6e842 100644
--- a/ext/stringio/depend
+++ b/ext/stringio/depend
@@ -53,7 +53,6 @@ stringio.o: $(hdrdir)/ruby/internal/attr/noexcept.h
stringio.o: $(hdrdir)/ruby/internal/attr/noinline.h
stringio.o: $(hdrdir)/ruby/internal/attr/nonnull.h
stringio.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-stringio.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
stringio.o: $(hdrdir)/ruby/internal/attr/pure.h
stringio.o: $(hdrdir)/ruby/internal/attr/restrict.h
stringio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ stringio.o: $(hdrdir)/ruby/internal/intern/enumerator.h
stringio.o: $(hdrdir)/ruby/internal/intern/error.h
stringio.o: $(hdrdir)/ruby/internal/intern/eval.h
stringio.o: $(hdrdir)/ruby/internal/intern/file.h
+stringio.o: $(hdrdir)/ruby/internal/intern/gc.h
stringio.o: $(hdrdir)/ruby/internal/intern/hash.h
stringio.o: $(hdrdir)/ruby/internal/intern/io.h
stringio.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ stringio.o: $(hdrdir)/ruby/internal/memory.h
stringio.o: $(hdrdir)/ruby/internal/method.h
stringio.o: $(hdrdir)/ruby/internal/module.h
stringio.o: $(hdrdir)/ruby/internal/newobj.h
+stringio.o: $(hdrdir)/ruby/internal/rgengc.h
stringio.o: $(hdrdir)/ruby/internal/scan_args.h
stringio.o: $(hdrdir)/ruby/internal/special_consts.h
stringio.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/stringio/extconf.rb b/ext/stringio/extconf.rb
index 553732f79c..a933159766 100644
--- a/ext/stringio/extconf.rb
+++ b/ext/stringio/extconf.rb
@@ -1,7 +1,4 @@
# frozen_string_literal: false
require 'mkmf'
-if RUBY_ENGINE == 'ruby'
- create_makefile('stringio')
-else
- File.write('Makefile', dummy_makefile("").join)
-end
+have_func("rb_io_extract_modeenc", "ruby/io.h")
+create_makefile('stringio')
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index 74e2b95c99..0054766dac 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -12,8 +12,7 @@
**********************************************************************/
-static const char *const
-STRINGIO_VERSION = "3.1.1";
+#define STRINGIO_VERSION "3.0.4"
#include "ruby.h"
#include "ruby/io.h"
@@ -33,6 +32,86 @@ STRINGIO_VERSION = "3.1.1";
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
#endif
+#ifndef HAVE_RB_IO_EXTRACT_MODEENC
+#define rb_io_extract_modeenc strio_extract_modeenc
+static void
+strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
+ int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p)
+{
+ VALUE mode = *vmode_p;
+ VALUE intmode;
+ int fmode;
+ int has_enc = 0, has_vmode = 0;
+
+ convconfig_p->enc = convconfig_p->enc2 = 0;
+
+ vmode_handle:
+ if (NIL_P(mode)) {
+ fmode = FMODE_READABLE;
+ }
+ else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) {
+ int flags = NUM2INT(intmode);
+ fmode = rb_io_oflags_fmode(flags);
+ }
+ else {
+ const char *m = StringValueCStr(mode), *n, *e;
+ fmode = rb_io_modestr_fmode(m);
+ n = strchr(m, ':');
+ if (n) {
+ long len;
+ char encname[ENCODING_MAXNAMELEN+1];
+ has_enc = 1;
+ if (fmode & FMODE_SETENC_BY_BOM) {
+ n = strchr(n, '|');
+ }
+ e = strchr(++n, ':');
+ len = e ? e - n : (long)strlen(n);
+ if (len > 0 && len <= ENCODING_MAXNAMELEN) {
+ rb_encoding *enc;
+ if (e) {
+ memcpy(encname, n, len);
+ encname[len] = '\0';
+ n = encname;
+ }
+ enc = rb_enc_find(n);
+ if (e)
+ convconfig_p->enc2 = enc;
+ else
+ convconfig_p->enc = enc;
+ }
+ if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) {
+ convconfig_p->enc = rb_enc_find(e);
+ }
+ }
+ }
+
+ if (!NIL_P(opthash)) {
+ rb_encoding *extenc = 0, *intenc = 0;
+ VALUE v;
+ if (!has_vmode) {
+ ID id_mode;
+ CONST_ID(id_mode, "mode");
+ v = rb_hash_aref(opthash, ID2SYM(id_mode));
+ if (!NIL_P(v)) {
+ if (!NIL_P(mode)) {
+ rb_raise(rb_eArgError, "mode specified twice");
+ }
+ has_vmode = 1;
+ mode = v;
+ goto vmode_handle;
+ }
+ }
+
+ if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) {
+ if (has_enc) {
+ rb_raise(rb_eArgError, "encoding specified twice");
+ }
+ }
+ }
+ *fmode_p = fmode;
+}
+#endif
+
struct StringIO {
VALUE string;
rb_encoding *enc;
@@ -92,7 +171,7 @@ static const rb_data_type_t strio_data_type = {
strio_free,
strio_memsize,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
#define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
@@ -277,7 +356,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
{
VALUE string, vmode, opt;
int oflags;
- rb_io_enc_t convconfig;
+ struct rb_io_enc_t convconfig;
argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
@@ -300,7 +379,7 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
if (ptr->flags & FMODE_TRUNC) {
rb_str_resize(string, 0);
}
- RB_OBJ_WRITE(self, &ptr->string, string);
+ ptr->string = string;
if (argc == 1) {
ptr->enc = rb_enc_get(string);
}
@@ -318,7 +397,7 @@ static VALUE
strio_finalize(VALUE self)
{
struct StringIO *ptr = StringIO(self);
- RB_OBJ_WRITE(self, &ptr->string, Qnil);
+ ptr->string = Qnil;
ptr->flags &= ~FMODE_READWRITE;
return self;
}
@@ -484,8 +563,7 @@ strio_set_string(VALUE self, VALUE string)
ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
ptr->pos = 0;
ptr->lineno = 0;
- RB_OBJ_WRITE(self, &ptr->string, string);
- return string;
+ return ptr->string = string;
}
/*
@@ -604,9 +682,11 @@ strio_to_read(VALUE self)
* eof? -> true or false
*
* Returns +true+ if positioned at end-of-stream, +false+ otherwise;
- * see {Position}[rdoc-ref:IO@Position].
+ * see {Position}[rdoc-ref:File@Position].
*
* Raises IOError if the stream is not opened for reading.
+ *
+ * StreamIO#eof is an alias for StreamIO#eof?.
*/
static VALUE
strio_eof(VALUE self)
@@ -619,19 +699,15 @@ strio_eof(VALUE self)
static VALUE
strio_copy(VALUE copy, VALUE orig)
{
- struct StringIO *ptr, *old_ptr;
- VALUE old_string = Qundef;
+ struct StringIO *ptr;
orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
if (copy == orig) return copy;
ptr = StringIO(orig);
- old_ptr = check_strio(copy);
- if (old_ptr) {
- old_string = old_ptr->string;
- strio_free(old_ptr);
+ if (check_strio(copy)) {
+ strio_free(DATA_PTR(copy));
}
DATA_PTR(copy) = ptr;
- RB_OBJ_WRITTEN(copy, old_string, ptr->string);
RBASIC(copy)->flags &= ~STRIO_READWRITE;
RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
++ptr->count;
@@ -732,6 +808,8 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
*
* Returns the current position (in bytes);
* see {Position}[rdoc-ref:IO@Position].
+ *
+ * StringIO#tell is an alias for StringIO#pos.
*/
static VALUE
strio_get_pos(VALUE self)
@@ -1143,57 +1221,38 @@ struct getline_arg {
};
static struct getline_arg *
-prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VALUE *argv)
+prepare_getline_args(struct getline_arg *arg, int argc, VALUE *argv)
{
- VALUE rs, lim, opts;
+ VALUE str, lim, opts;
long limit = -1;
int respect_chomp;
- argc = rb_scan_args(argc, argv, "02:", &rs, &lim, &opts);
- respect_chomp = argc == 0 || !NIL_P(rs);
+ argc = rb_scan_args(argc, argv, "02:", &str, &lim, &opts);
+ respect_chomp = argc == 0 || !NIL_P(str);
switch (argc) {
case 0:
- rs = rb_rs;
+ str = rb_rs;
break;
case 1:
- if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) {
- VALUE tmp = rb_check_string_type(rs);
+ if (!NIL_P(str) && !RB_TYPE_P(str, T_STRING)) {
+ VALUE tmp = rb_check_string_type(str);
if (NIL_P(tmp)) {
- limit = NUM2LONG(rs);
- rs = rb_rs;
+ limit = NUM2LONG(str);
+ str = rb_rs;
}
else {
- rs = tmp;
+ str = tmp;
}
}
break;
case 2:
- if (!NIL_P(rs)) StringValue(rs);
+ if (!NIL_P(str)) StringValue(str);
if (!NIL_P(lim)) limit = NUM2LONG(lim);
break;
}
- if (!NIL_P(rs)) {
- rb_encoding *enc_rs, *enc_io;
- enc_rs = rb_enc_get(rs);
- enc_io = get_enc(ptr);
- if (enc_rs != enc_io &&
- (rb_enc_str_coderange(rs) != ENC_CODERANGE_7BIT ||
- (RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
- if (rs == rb_rs) {
- rs = rb_enc_str_new(0, 0, enc_io);
- rb_str_buf_cat_ascii(rs, "\n");
- rs = rs;
- }
- else {
- rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
- rb_enc_name(enc_io),
- rb_enc_name(enc_rs));
- }
- }
- }
- arg->rs = rs;
+ arg->rs = str;
arg->limit = limit;
arg->chomp = 0;
if (!NIL_P(opts)) {
@@ -1321,15 +1380,15 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
static VALUE
strio_gets(int argc, VALUE *argv, VALUE self)
{
- struct StringIO *ptr = readable(self);
struct getline_arg arg;
VALUE str;
- if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
+ if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
+ struct StringIO *ptr = readable(self);
return rb_enc_str_new(0, 0, get_enc(ptr));
}
- str = strio_getline(&arg, ptr);
+ str = strio_getline(&arg, readable(self));
rb_lastline_set(str);
return str;
}
@@ -1361,21 +1420,23 @@ strio_readline(int argc, VALUE *argv, VALUE self)
* does nothing if already at end-of-file;
* returns +self+.
* See {Line IO}[rdoc-ref:IO@Line+IO].
+ *
+ * StringIO#each is an alias for StringIO#each_line.
*/
static VALUE
strio_each(int argc, VALUE *argv, VALUE self)
{
VALUE line;
- struct StringIO *ptr = readable(self);
struct getline_arg arg;
+ StringIO(self);
RETURN_ENUMERATOR(self, argc, argv);
- if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
+ if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
}
- while (!NIL_P(line = strio_getline(&arg, ptr))) {
+ while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
rb_yield(line);
}
return self;
@@ -1393,15 +1454,15 @@ static VALUE
strio_readlines(int argc, VALUE *argv, VALUE self)
{
VALUE ary, line;
- struct StringIO *ptr = readable(self);
struct getline_arg arg;
- if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
+ StringIO(self);
+ ary = rb_ary_new();
+ if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
}
- ary = rb_ary_new();
- while (!NIL_P(line = strio_getline(&arg, ptr))) {
+ while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
rb_ary_push(ary, line);
}
return ary;
@@ -1604,55 +1665,6 @@ strio_read(int argc, VALUE *argv, VALUE self)
}
/*
- * call-seq:
- * pread(maxlen, offset) -> string
- * pread(maxlen, offset, out_string) -> string
- *
- * See IO#pread.
- */
-static VALUE
-strio_pread(int argc, VALUE *argv, VALUE self)
-{
- VALUE rb_len, rb_offset, rb_buf;
- rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf);
- long len = NUM2LONG(rb_len);
- long offset = NUM2LONG(rb_offset);
-
- if (len < 0) {
- rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
- }
-
- if (len == 0) {
- if (NIL_P(rb_buf)) {
- return rb_str_new("", 0);
- }
- return rb_buf;
- }
-
- if (offset < 0) {
- rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
- }
-
- struct StringIO *ptr = readable(self);
-
- if (offset >= RSTRING_LEN(ptr->string)) {
- rb_eof_error();
- }
-
- if (NIL_P(rb_buf)) {
- return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
- }
-
- long rest = RSTRING_LEN(ptr->string) - offset;
- if (len > rest) len = rest;
- rb_str_resize(rb_buf, len);
- rb_enc_associate(rb_buf, rb_ascii8bit_encoding());
- MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len);
- return rb_buf;
-}
-
-
-/*
* call-seq:
* strio.sysread(integer[, outbuf]) -> string
* strio.readpartial(integer[, outbuf]) -> string
@@ -1812,7 +1824,7 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self)
else {
enc = rb_find_encoding(ext_enc);
if (!enc) {
- rb_io_enc_t convconfig;
+ struct rb_io_enc_t convconfig;
int oflags, fmode;
VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
@@ -1912,7 +1924,6 @@ Init_stringio(void)
rb_define_method(StringIO, "gets", strio_gets, -1);
rb_define_method(StringIO, "readlines", strio_readlines, -1);
rb_define_method(StringIO, "read", strio_read, -1);
- rb_define_method(StringIO, "pread", strio_pread, -1);
rb_define_method(StringIO, "write", strio_write_m, -1);
rb_define_method(StringIO, "putc", strio_putc, 1);
diff --git a/ext/stringio/stringio.gemspec b/ext/stringio/stringio.gemspec
index 8c950f8ff9..1015d261f5 100644
--- a/ext/stringio/stringio.gemspec
+++ b/ext/stringio/stringio.gemspec
@@ -4,7 +4,7 @@
source_version = ["", "ext/stringio/"].find do |dir|
begin
break File.open(File.join(__dir__, "#{dir}stringio.c")) {|f|
- f.gets("\nSTRINGIO_VERSION ")
+ f.gets("\n#define STRINGIO_VERSION ")
f.gets[/\s*"(.+)"/, 1]
}
rescue Errno::ENOENT
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
s.name = "stringio"
s.version = source_version
+ s.required_rubygems_version = Gem::Requirement.new(">= 2.6")
s.require_paths = ["lib"]
s.authors = ["Nobu Nakada", "Charles Oliver Nutter"]
s.description = "Pseudo `IO` class from/to `String`."
@@ -21,8 +22,7 @@ Gem::Specification.new do |s|
s.files = ["README.md"]
jruby = true if Gem::Platform.new('java') =~ s.platform or RUBY_ENGINE == 'jruby'
if jruby
- s.require_paths = "lib/java"
- s.files += ["lib/java/stringio.rb", "lib/java/stringio.jar"]
+ s.files += ["lib/stringio.rb", "lib/stringio.jar"]
s.platform = "java"
else
s.extensions = ["ext/stringio/extconf.rb"]
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
end
s.homepage = "https://github.com/ruby/stringio"
s.licenses = ["Ruby", "BSD-2-Clause"]
- s.required_ruby_version = ">= 2.7"
+ s.required_ruby_version = ">= 2.5"
s.summary = "Pseudo IO on String"
# s.cert_chain = %w[certs/nobu.pem]
diff --git a/ext/strscan/depend b/ext/strscan/depend
index 8d985b59e8..8fe3cb23d9 100644
--- a/ext/strscan/depend
+++ b/ext/strscan/depend
@@ -52,7 +52,6 @@ strscan.o: $(hdrdir)/ruby/internal/attr/noexcept.h
strscan.o: $(hdrdir)/ruby/internal/attr/noinline.h
strscan.o: $(hdrdir)/ruby/internal/attr/nonnull.h
strscan.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-strscan.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
strscan.o: $(hdrdir)/ruby/internal/attr/pure.h
strscan.o: $(hdrdir)/ruby/internal/attr/restrict.h
strscan.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ strscan.o: $(hdrdir)/ruby/internal/intern/enumerator.h
strscan.o: $(hdrdir)/ruby/internal/intern/error.h
strscan.o: $(hdrdir)/ruby/internal/intern/eval.h
strscan.o: $(hdrdir)/ruby/internal/intern/file.h
+strscan.o: $(hdrdir)/ruby/internal/intern/gc.h
strscan.o: $(hdrdir)/ruby/internal/intern/hash.h
strscan.o: $(hdrdir)/ruby/internal/intern/io.h
strscan.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ strscan.o: $(hdrdir)/ruby/internal/memory.h
strscan.o: $(hdrdir)/ruby/internal/method.h
strscan.o: $(hdrdir)/ruby/internal/module.h
strscan.o: $(hdrdir)/ruby/internal/newobj.h
+strscan.o: $(hdrdir)/ruby/internal/rgengc.h
strscan.o: $(hdrdir)/ruby/internal/scan_args.h
strscan.o: $(hdrdir)/ruby/internal/special_consts.h
strscan.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/strscan/extconf.rb b/ext/strscan/extconf.rb
index bd65606a4e..3c311d2364 100644
--- a/ext/strscan/extconf.rb
+++ b/ext/strscan/extconf.rb
@@ -2,8 +2,8 @@
require 'mkmf'
if RUBY_ENGINE == 'ruby'
$INCFLAGS << " -I$(top_srcdir)" if $extmk
- have_func("onig_region_memsize", "ruby.h")
- have_func("rb_reg_onig_match", "ruby.h")
+ have_func("onig_region_memsize(NULL)")
+ have_func("rb_reg_onig_match", "ruby/re.h")
create_makefile 'strscan'
else
File.write('Makefile', dummy_makefile("").join)
diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c
index 4598d13c90..16d669d8a5 100644
--- a/ext/strscan/strscan.c
+++ b/ext/strscan/strscan.c
@@ -22,7 +22,7 @@ extern size_t onig_region_memsize(const struct re_registers *regs);
#include <stdbool.h>
-#define STRSCAN_VERSION "3.0.9"
+#define STRSCAN_VERSION "3.0.7"
/* =======================================================================
Data Type Definitions
@@ -1243,10 +1243,10 @@ strscan_size(VALUE self)
* If nothing was priorly matched, it returns nil.
*
* s = StringScanner.new("Fri Dec 12 1975 14:39")
- * s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> "Fri Dec 12 "
- * s.captures # -> ["Fri", "Dec", "12", nil]
- * s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> nil
- * s.captures # -> nil
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
+ * s.captures # -> ["Fri", "Dec", "12"]
+ * s.scan(/(\w+) (\w+) (\d+) /) # -> nil
+ * s.captures # -> nil
*/
static VALUE
strscan_captures(VALUE self)
@@ -1262,13 +1262,9 @@ strscan_captures(VALUE self)
new_ary = rb_ary_new2(num_regs);
for (i = 1; i < num_regs; i++) {
- VALUE str;
- if (p->regs.beg[i] == -1)
- str = Qnil;
- else
- str = extract_range(p,
- adjust_register_position(p, p->regs.beg[i]),
- adjust_register_position(p, p->regs.end[i]));
+ VALUE str = extract_range(p,
+ adjust_register_position(p, p->regs.beg[i]),
+ adjust_register_position(p, p->regs.end[i]));
rb_ary_push(new_ary, str);
}
diff --git a/ext/syslog/depend b/ext/syslog/depend
index ee4ac5f47d..4eea8c3bf9 100644
--- a/ext/syslog/depend
+++ b/ext/syslog/depend
@@ -51,7 +51,6 @@ syslog.o: $(hdrdir)/ruby/internal/attr/noexcept.h
syslog.o: $(hdrdir)/ruby/internal/attr/noinline.h
syslog.o: $(hdrdir)/ruby/internal/attr/nonnull.h
syslog.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-syslog.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
syslog.o: $(hdrdir)/ruby/internal/attr/pure.h
syslog.o: $(hdrdir)/ruby/internal/attr/restrict.h
syslog.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,6 +110,7 @@ syslog.o: $(hdrdir)/ruby/internal/intern/enumerator.h
syslog.o: $(hdrdir)/ruby/internal/intern/error.h
syslog.o: $(hdrdir)/ruby/internal/intern/eval.h
syslog.o: $(hdrdir)/ruby/internal/intern/file.h
+syslog.o: $(hdrdir)/ruby/internal/intern/gc.h
syslog.o: $(hdrdir)/ruby/internal/intern/hash.h
syslog.o: $(hdrdir)/ruby/internal/intern/io.h
syslog.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -141,6 +141,7 @@ syslog.o: $(hdrdir)/ruby/internal/memory.h
syslog.o: $(hdrdir)/ruby/internal/method.h
syslog.o: $(hdrdir)/ruby/internal/module.h
syslog.o: $(hdrdir)/ruby/internal/newobj.h
+syslog.o: $(hdrdir)/ruby/internal/rgengc.h
syslog.o: $(hdrdir)/ruby/internal/scan_args.h
syslog.o: $(hdrdir)/ruby/internal/special_consts.h
syslog.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/syslog/syslog.c b/ext/syslog/syslog.c
index 4fbbb2ec6e..8f3674aa8d 100644
--- a/ext/syslog/syslog.c
+++ b/ext/syslog/syslog.c
@@ -12,8 +12,6 @@
#include "ruby/util.h"
#include <syslog.h>
-#define SYSLOG_VERSION "0.1.2"
-
/* Syslog class */
static VALUE mSyslog;
/*
@@ -576,8 +574,6 @@ void Init_syslog(void)
/* Syslog macros */
- rb_define_const(mSyslog, "VERSION", rb_str_new_cstr(SYSLOG_VERSION));
-
rb_define_method(mSyslogMacros, "LOG_MASK", mSyslogMacros_LOG_MASK, 1);
rb_define_method(mSyslogMacros, "LOG_UPTO", mSyslogMacros_LOG_UPTO, 1);
rb_define_singleton_method(mSyslogMacros, "included", mSyslogMacros_included, 1);
diff --git a/ext/syslog/syslog.gemspec b/ext/syslog/syslog.gemspec
index 10a6d1f25c..6aa2e9570d 100644
--- a/ext/syslog/syslog.gemspec
+++ b/ext/syslog/syslog.gemspec
@@ -1,18 +1,13 @@
-source_version = %w[. ext/syslog].find do |dir|
- break $1 if File.foreach(File.join(__dir__, dir, "syslog.c")).any?(/^#define\s+SYSLOG_VERSION\s+"(.+)"/)
-rescue Errno::ENOENT
-end
-
Gem::Specification.new do |spec|
spec.name = "syslog"
- spec.version = source_version
+ spec.version = "0.1.1"
spec.authors = ["Akinori MUSHA"]
spec.email = ["knu@idaemons.org"]
spec.summary = %q{Ruby interface for the POSIX system logging facility.}
spec.description = %q{Ruby interface for the POSIX system logging facility.}
spec.homepage = "https://github.com/ruby/syslog"
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.metadata["homepage_uri"] = spec.homepage
diff --git a/ext/win32/lib/win32/registry.rb b/ext/win32/lib/win32/registry.rb
index 16a08310ad..bda8bb012f 100644
--- a/ext/win32/lib/win32/registry.rb
+++ b/ext/win32/lib/win32/registry.rb
@@ -69,7 +69,11 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
WCHAR_NUL = "\0".encode(WCHAR).freeze
WCHAR_CR = "\r".encode(WCHAR).freeze
WCHAR_SIZE = WCHAR_NUL.bytesize
- LOCALE = Encoding.find(Encoding.locale_charmap)
+ begin
+ LOCALE = Encoding.find(Encoding.locale_charmap)
+ rescue ArgumentError
+ LOCALE = Encoding::UTF_8
+ end
class Registry
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index a060165a1c..3f083bb12d 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -27,7 +27,7 @@
const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
#endif
-#define WIN32OLE_VERSION "1.8.10"
+#define WIN32OLE_VERSION "1.8.8"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
diff --git a/ext/win32ole/win32ole.gemspec b/ext/win32ole/win32ole.gemspec
index 9c137a5d70..b6ea8e8a55 100644
--- a/ext/win32ole/win32ole.gemspec
+++ b/ext/win32ole/win32ole.gemspec
@@ -1,16 +1,6 @@
-source_version = ["", "ext/win32ole/"].find do |dir|
- begin
- break File.open(File.join(__dir__, "#{dir}win32ole.c")) {|f|
- f.gets("\n#define WIN32OLE_VERSION ")
- f.gets[/\s*"(.+)"/, 1]
- }
- rescue Errno::ENOENT
- end
-end
-
Gem::Specification.new do |spec|
spec.name = "win32ole"
- spec.version = source_version
+ spec.version = "1.8.9"
spec.authors = ["Masaki Suketa"]
spec.email = ["suke@ruby-lang.org"]
diff --git a/ext/zlib/depend b/ext/zlib/depend
index bdcf6a93e8..15186f8266 100644
--- a/ext/zlib/depend
+++ b/ext/zlib/depend
@@ -53,7 +53,6 @@ zlib.o: $(hdrdir)/ruby/internal/attr/noexcept.h
zlib.o: $(hdrdir)/ruby/internal/attr/noinline.h
zlib.o: $(hdrdir)/ruby/internal/attr/nonnull.h
zlib.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-zlib.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
zlib.o: $(hdrdir)/ruby/internal/attr/pure.h
zlib.o: $(hdrdir)/ruby/internal/attr/restrict.h
zlib.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -122,6 +121,7 @@ zlib.o: $(hdrdir)/ruby/internal/intern/enumerator.h
zlib.o: $(hdrdir)/ruby/internal/intern/error.h
zlib.o: $(hdrdir)/ruby/internal/intern/eval.h
zlib.o: $(hdrdir)/ruby/internal/intern/file.h
+zlib.o: $(hdrdir)/ruby/internal/intern/gc.h
zlib.o: $(hdrdir)/ruby/internal/intern/hash.h
zlib.o: $(hdrdir)/ruby/internal/intern/io.h
zlib.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -152,6 +152,7 @@ zlib.o: $(hdrdir)/ruby/internal/memory.h
zlib.o: $(hdrdir)/ruby/internal/method.h
zlib.o: $(hdrdir)/ruby/internal/module.h
zlib.o: $(hdrdir)/ruby/internal/newobj.h
+zlib.o: $(hdrdir)/ruby/internal/rgengc.h
zlib.o: $(hdrdir)/ruby/internal/scan_args.h
zlib.o: $(hdrdir)/ruby/internal/special_consts.h
zlib.o: $(hdrdir)/ruby/internal/static_assert.h
diff --git a/ext/zlib/extconf.rb b/ext/zlib/extconf.rb
index 2b2dbb1a5b..5477f49178 100644
--- a/ext/zlib/extconf.rb
+++ b/ext/zlib/extconf.rb
@@ -11,9 +11,10 @@ require 'rbconfig'
dir_config 'zlib'
libs = $libs
-have_zlib = %w'z libz zlib1 zlib zdll zlibwapi'.any? {|z| have_library(z, 'deflateReset(NULL)', 'zlib.h')}
-
-unless have_zlib
+if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and
+ have_header('zlib.h') then
+ have_zlib = true
+else
$libs = libs
unless File.directory?(zsrc = "#{$srcdir}/zlib")
dirs = Dir.open($srcdir) {|z| z.grep(/\Azlib-\d+[.\d]*\z/) {|x|"#{$srcdir}/#{x}"}}
@@ -120,18 +121,12 @@ if have_zlib
$defs << "-DHAVE_CRC32_COMBINE"
$defs << "-DHAVE_ADLER32_COMBINE"
$defs << "-DHAVE_TYPE_Z_CRC_T"
- $defs << "-DHAVE_CRC32_Z"
- $defs << "-DHAVE_ADLER32_Z"
- $defs << "-DHAVE_ZLIB_SIZE_T_FUNCS"
+ $defs << "-DHAVE_TYPE_Z_SIZE_T"
else
have_func('crc32_combine', 'zlib.h')
have_func('adler32_combine', 'zlib.h')
have_type('z_crc_t', 'zlib.h')
- if (have_type('z_size_t', 'zlib.h') &&
- have_func('crc32_z', 'zlib.h') &&
- have_func('adler32_z', 'zlib.h'))
- $defs << "-DHAVE_ZLIB_SIZE_T_FUNCS"
- end
+ have_type('z_size_t', 'zlib.h')
end
create_makefile('zlib') {|conf|
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 3db4d25271..aefdba0ebd 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -25,7 +25,7 @@
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
#endif
-#define RUBY_ZLIB_VERSION "3.1.1"
+#define RUBY_ZLIB_VERSION "3.0.0"
#ifndef RB_PASS_CALLED_KEYWORDS
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
@@ -44,7 +44,7 @@
#endif
#endif
-#if defined(HAVE_ZLIB_SIZE_T_FUNCS)
+#if defined(HAVE_TYPE_Z_SIZE_T)
typedef uLong (*checksum_func)(uLong, const Bytef*, z_size_t);
# define crc32 crc32_z
# define adler32 adler32_z
@@ -388,7 +388,7 @@ rb_zlib_version(VALUE klass)
# define mask32(x) (x)
#endif
-#if SIZEOF_LONG > SIZEOF_INT && !defined(HAVE_ZLIB_SIZE_T_FUNCS)
+#if SIZEOF_LONG > SIZEOF_INT && !defined(HAVE_TYPE_Z_SIZE_T)
static uLong
checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
{
@@ -923,7 +923,7 @@ zstream_discard_input(struct zstream *z, long len)
z->input = Qnil;
}
else {
- z->input = rb_str_subseq(z->input, len,
+ z->input = rb_str_substr(z->input, len,
RSTRING_LEN(z->input) - len);
}
}
@@ -3500,9 +3500,6 @@ static VALUE
rb_gzfile_eof_p(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
- while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
- gzfile_read_more(gz, Qnil);
- }
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
diff --git a/ext/zlib/zlib.gemspec b/ext/zlib/zlib.gemspec
index bb67ea156c..4a5f8f2ee8 100644
--- a/ext/zlib/zlib.gemspec
+++ b/ext/zlib/zlib.gemspec
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
spec.executables = []
spec.require_paths = ["lib"]
spec.extensions = "ext/zlib/extconf.rb"
- spec.required_ruby_version = ">= 2.5.0"
+ spec.required_ruby_version = ">= 2.3.0"
end
diff --git a/file.c b/file.c
index 373788b206..3a8439ef07 100644
--- a/file.c
+++ b/file.c
@@ -129,7 +129,7 @@ int flock(int, int);
# endif
#else
# define STAT(p, s) stat((p), (s))
-#endif /* _WIN32 */
+#endif
#if defined _WIN32 || defined __APPLE__
# define USE_OSPATH 1
@@ -169,6 +169,7 @@ int flock(int, int);
#include "internal/thread.h"
#include "internal/vm.h"
#include "ruby/encoding.h"
+#include "ruby/io.h"
#include "ruby/thread.h"
#include "ruby/util.h"
@@ -263,7 +264,7 @@ rb_str_encode_ospath(VALUE path)
rb_encoding *utf8 = rb_utf8_encoding();
path = rb_str_conv_enc(path, enc, utf8);
}
-#endif /* USE_OSPATH */
+#endif
return path;
}
@@ -307,7 +308,7 @@ rb_CFString_class_initialize_before_fork(void)
CFRelease(m);
CFRelease(s);
}
-# endif /* HAVE_WORKING_FORK */
+# endif
static VALUE
rb_str_append_normalized_ospath(VALUE str, const char *ptr, long len)
@@ -408,9 +409,9 @@ ignored_char_p(const char *p, const char *e, rb_encoding *enc)
}
return 0;
}
-#else /* !__APPLE__ */
+#else
# define NORMALIZE_UTF8PATH 0
-#endif /* __APPLE__ */
+#endif
#define apply2args(n) (rb_check_arity(argc, n, UNLIMITED_ARGUMENTS), argc-=n)
@@ -483,29 +484,28 @@ apply2files(int (*func)(const char *, void *), int argc, VALUE *argv, void *arg)
return LONG2FIX(argc);
}
+static size_t
+stat_memsize(const void *p)
+{
+ return sizeof(struct stat);
+}
+
static const rb_data_type_t stat_data_type = {
"stat",
- {
- NULL,
- RUBY_TYPED_DEFAULT_FREE,
- NULL, // No external memory to report
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
-};
-
-struct rb_stat {
- struct stat stat;
- bool initialized;
+ {NULL, RUBY_TYPED_DEFAULT_FREE, stat_memsize,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
stat_new_0(VALUE klass, const struct stat *st)
{
- struct rb_stat *rb_st;
- VALUE obj = TypedData_Make_Struct(klass, struct rb_stat, &stat_data_type, rb_st);
+ struct stat *nst = 0;
+ VALUE obj = TypedData_Wrap_Struct(klass, &stat_data_type, 0);
+
if (st) {
- rb_st->stat = *st;
- rb_st->initialized = true;
+ nst = ALLOC(struct stat);
+ *nst = *st;
+ RTYPEDDATA_DATA(obj) = nst;
}
return obj;
}
@@ -519,10 +519,10 @@ rb_stat_new(const struct stat *st)
static struct stat*
get_stat(VALUE self)
{
- struct rb_stat* rb_st;
- TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
- if (!rb_st->initialized) rb_raise(rb_eTypeError, "uninitialized File::Stat");
- return &rb_st->stat;
+ struct stat* st;
+ TypedData_Get_Struct(self, struct stat, &stat_data_type, st);
+ if (!st) rb_raise(rb_eTypeError, "uninitialized File::Stat");
+ return st;
}
static struct timespec stat_mtimespec(const struct stat *st);
@@ -964,7 +964,7 @@ typedef struct stat statx_data;
# define stat_birthtime stat_ctime
#else
# undef HAVE_STAT_BIRTHTIME
-#endif /* defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) */
+#endif
/*
* call-seq:
@@ -1093,9 +1093,9 @@ rb_stat_inspect(VALUE self)
#endif
};
- struct rb_stat* rb_st;
- TypedData_Get_Struct(self, struct rb_stat, &stat_data_type, rb_st);
- if (!rb_st->initialized) {
+ struct stat* st;
+ TypedData_Get_Struct(self, struct stat, &stat_data_type, st);
+ if (!st) {
return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
}
@@ -1189,8 +1189,8 @@ statx(int dirfd, const char *pathname, int flags,
{
return (int)syscall(__NR_statx, dirfd, pathname, flags, mask, statxbuf);
}
-# endif /* __linux__ */
-# endif /* HAVE_STATX */
+# endif
+# endif
typedef struct no_gvl_statx_data {
struct statx *stx;
@@ -1289,8 +1289,7 @@ typedef struct statx statx_data;
# define rb_statx(file, st, mask) rb_stat(file, st)
#else
# define statx_has_birthtime(st) 0
-#endif /* !defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) && \
- defined(HAVE_STRUCT_STATX_STX_BTIME) */
+#endif
static int
rb_stat(VALUE file, struct stat *st)
@@ -1479,7 +1478,7 @@ rb_group_member(GETGROUPS_T gid)
ALLOCV_END(v);
return rv;
-#endif /* defined(_WIN32) || !defined(HAVE_GETGROUPS) */
+#endif
}
#ifndef S_IXUGO
@@ -1530,9 +1529,9 @@ eaccess(const char *path, int mode)
return -1;
#else
return access(path, mode);
-#endif /* USE_GETEUID */
+#endif
}
-#endif /* HAVE_EACCESS */
+#endif
struct access_arg {
const char *path;
@@ -1594,6 +1593,8 @@ rb_access(VALUE fname, int mode)
*/
/*
+ * Document-method: directory?
+ *
* call-seq:
* File.directory?(path) -> true or false
*
@@ -1772,7 +1773,7 @@ rb_file_blockdev_p(VALUE obj, VALUE fname)
*
* Returns +true+ if +filepath+ points to a character device, +false+ otherwise.
*
- * File.chardev?($stdin) # => true
+ * File.chardev?($stdin) # => true
* File.chardev?('t.txt') # => false
*
*/
@@ -2453,7 +2454,6 @@ rb_file_ctime(VALUE obj)
return stat_ctime(&st);
}
-#if defined(HAVE_STAT_BIRTHTIME)
/*
* call-seq:
* File.birthtime(file_name) -> time
@@ -2468,6 +2468,7 @@ rb_file_ctime(VALUE obj)
*
*/
+#if defined(HAVE_STAT_BIRTHTIME)
RUBY_FUNC_EXPORTED VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
{
@@ -2513,6 +2514,16 @@ rb_file_birthtime(VALUE obj)
# define rb_file_birthtime rb_f_notimplement
#endif
+/*
+ * call-seq:
+ * file.size -> integer
+ *
+ * Returns the size of <i>file</i> in bytes.
+ *
+ * File.new("testfile").size #=> 66
+ *
+ */
+
rb_off_t
rb_file_size(VALUE file)
{
@@ -2536,16 +2547,6 @@ rb_file_size(VALUE file)
}
}
-/*
- * call-seq:
- * file.size -> integer
- *
- * Returns the size of <i>file</i> in bytes.
- *
- * File.new("testfile").size #=> 66
- *
- */
-
static VALUE
file_size(VALUE self)
{
@@ -2835,7 +2836,7 @@ utime_failed(struct apply_arg *aa)
}
rb_syserr_fail_path(e, path);
}
-#endif /* UTIME_EINVAL */
+#endif
#if defined(HAVE_UTIMES)
@@ -2859,8 +2860,8 @@ RBIMPL_WARNING_POP()
# define utimensat rb_utimensat()
# else /* __API_AVAILABLE macro does nothing on gcc */
__attribute__((weak)) int utimensat(int, const char *, const struct timespec [2], int);
-# endif /* defined(__has_attribute) && __has_attribute(availability) */
-# endif /* __APPLE__ && < MAC_OS_X_VERSION_13_0 */
+# endif
+# endif
static int
utime_internal(const char *path, void *arg)
@@ -2873,15 +2874,15 @@ utime_internal(const char *path, void *arg)
# if defined(__APPLE__)
const int try_utimensat = utimensat != NULL;
const int try_utimensat_follow = utimensat != NULL;
-# else /* !__APPLE__ */
+# else
# define TRY_UTIMENSAT 1
static int try_utimensat = 1;
-# ifdef AT_SYMLINK_NOFOLLOW
+# ifdef AT_SYMLINK_NOFOLLOW
static int try_utimensat_follow = 1;
-# else
+# else
const int try_utimensat_follow = 0;
-# endif
-# endif /* __APPLE__ */
+# endif
+# endif
int flags = 0;
if (v->follow ? try_utimensat_follow : try_utimensat) {
@@ -2896,15 +2897,15 @@ utime_internal(const char *path, void *arg)
if (result < 0 && errno == ENOSYS) {
# ifdef AT_SYMLINK_NOFOLLOW
try_utimensat_follow = 0;
-# endif /* AT_SYMLINK_NOFOLLOW */
+# endif
if (!v->follow)
try_utimensat = 0;
}
else
-# endif /* TRY_UTIMESAT */
+# endif
return result;
}
-#endif /* defined(HAVE_UTIMENSAT) */
+#endif
if (tsp) {
tvbuf[0].tv_sec = tsp[0].tv_sec;
@@ -2919,7 +2920,7 @@ utime_internal(const char *path, void *arg)
return utimes(path, tvp);
}
-#else /* !defined(HAVE_UTIMES) */
+#else
#if !defined HAVE_UTIME_H && !defined HAVE_SYS_UTIME_H
struct utimbuf {
@@ -2941,7 +2942,8 @@ utime_internal(const char *path, void *arg)
}
return utime(path, utp);
}
-#endif /* !defined(HAVE_UTIMES) */
+
+#endif
static VALUE
utime_internal_i(int argc, VALUE *argv, int follow)
@@ -3312,13 +3314,12 @@ static const char file_alt_separator[] = {FILE_ALT_SEPARATOR, '\0'};
#endif
#ifndef USE_NTFS
-# if defined _WIN32
-# define USE_NTFS 1
-# else
-# define USE_NTFS 0
-# endif
+#if defined _WIN32
+#define USE_NTFS 1
+#else
+#define USE_NTFS 0
+#endif
#endif
-
#ifndef USE_NTFS_ADS
# if USE_NTFS
# define USE_NTFS_ADS 1
@@ -3332,7 +3333,6 @@ static const char file_alt_separator[] = {FILE_ALT_SEPARATOR, '\0'};
#else
#define istrailinggarbage(x) 0
#endif
-
#if USE_NTFS_ADS
# define isADS(x) ((x) == ':')
#else
@@ -3400,8 +3400,8 @@ not_same_drive(VALUE path, int drive)
return has_unc(p);
}
}
-#endif /* _WIN32 */
-#endif /* DOSISH_DRIVE_LETTER */
+#endif
+#endif
static inline char *
skiproot(const char *path, const char *end, rb_encoding *enc)
@@ -3445,7 +3445,7 @@ rb_enc_path_skip_prefix(const char *path, const char *end, rb_encoding *enc)
if (has_drive_letter(path))
return (char *)(path + 2);
#endif
-#endif /* defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) */
+#endif
return (char *)path;
}
@@ -3540,7 +3540,7 @@ ntfs_tail(const char *path, const char *end, rb_encoding *enc)
}
return (char *)path;
}
-#endif /* USE_NTFS */
+#endif
#define BUFCHECK(cond) do {\
bdiff = p - buf;\
@@ -3645,7 +3645,7 @@ rb_home_dir_of(VALUE user, VALUE result)
return result;
}
-#ifndef _WIN32 /* this encompasses rb_file_expand_path_internal */
+#ifndef _WIN32
VALUE
rb_default_home_dir(VALUE result)
{
@@ -3675,7 +3675,7 @@ rb_default_home_dir(VALUE result)
if (NIL_P(login_name)) {
rb_raise(rb_eArgError, "couldn't find login name -- expanding `~'");
}
-# endif /* !defined(HAVE_GETPWUID_R) && !defined(HAVE_GETPWUID) */
+# endif
VALUE pw_dir = rb_getpwdirnam_for_login(login_name);
if (NIL_P(pw_dir)) {
@@ -3690,7 +3690,7 @@ rb_default_home_dir(VALUE result)
rb_str_resize(pw_dir, 0);
return result;
}
-#endif /* defined HAVE_PWD_H */
+#endif
if (!dir) {
rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
}
@@ -3820,7 +3820,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
s += 2;
}
}
-#endif /* DOSISH_DRIVE_LETTER */
+#endif
else if (!rb_is_absolute_path(s)) {
if (!NIL_P(dname)) {
rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result);
@@ -3840,7 +3840,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
p = skipprefix(buf, p, enc);
}
else
-#endif /* defined DOSISH || defined __CYGWIN__ */
+#endif
p = chompdirsep(skiproot(buf, p, enc), p, enc);
}
else {
@@ -3893,7 +3893,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
else {
do ++s; while (istrailinggarbage(*s));
}
-#endif /* USE_NTFS */
+#endif
break;
case '/':
#if defined DOSISH || defined __CYGWIN__
@@ -3918,7 +3918,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
}
}
-#endif /* USE_NTFS */
+#endif
break;
case '/':
#if defined DOSISH || defined __CYGWIN__
@@ -3943,7 +3943,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
break;
}
}
-#endif /* __APPLE__ */
+#endif
Inc(s, fend, enc);
break;
}
@@ -3967,8 +3967,8 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
s -= prime_len; /* alternative */
}
}
-# endif /* USE_NTFS_ADS */
-#endif /* USE_NTFS */
+# endif
+#endif
BUFCOPY(b, s-b);
rb_str_set_len(result, p-buf);
}
@@ -3989,7 +3989,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
const int flags = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
#else
char w32buf[MAXPATHLEN];
-#endif /* HAVE_CYGWIN_CONV_PATH */
+#endif
const char *path;
ssize_t bufsize;
int lnk_added = 0, is_symlink = 0;
@@ -4013,12 +4013,12 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
b = w32buf;
}
}
-#else /* !HAVE_CYGWIN_CONV_PATH */
+#else
bufsize = MAXPATHLEN;
if (cygwin_conv_to_win32_path(path, w32buf) == 0) {
b = w32buf;
}
-#endif /* !HAVE_CYGWIN_CONV_PATH */
+#endif
if (is_symlink && b == w32buf) {
*p = '\\';
strlcat(w32buf, p, bufsize);
@@ -4030,7 +4030,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
lnk_added = 0;
}
*p = '/';
-#endif /* __CYGWIN__ */
+#endif
rb_str_set_len(result, p - buf + strlen(p));
encidx = ENCODING_GET(result);
tmp = result;
@@ -4078,14 +4078,14 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
#endif
}
-#endif /* USE_NTFS */
+#endif
rb_str_set_len(result, p - buf);
rb_enc_check(fname, result);
ENC_CODERANGE_CLEAR(result);
return result;
}
-#endif /* !_WIN32 (this ifdef started above rb_default_home_dir) */
+#endif /* _WIN32 */
#define EXPAND_PATH_BUFFER() rb_usascii_str_new(0, 1)
@@ -4325,7 +4325,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE f
rb_hash_aset(loopcheck, testpath, rb_str_dup_frozen(*resolvedp));
}
else
-#endif /* HAVE_READLINK */
+#endif
{
VALUE s = rb_str_dup_frozen(testpath);
rb_hash_aset(loopcheck, s, s);
@@ -4494,7 +4494,7 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, rb_encoding *origenc, enum
}
rb_sys_fail_path(unresolved_path);
}
-# endif /* !defined(__LINUX__) && !defined(__APPLE__) */
+# endif
if (origenc && origenc != rb_enc_get(resolved)) {
if (!rb_enc_str_asciionly_p(resolved)) {
@@ -4512,7 +4512,7 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, rb_encoding *origenc, enum
RB_GC_GUARD(unresolved_path);
return resolved;
-#else /* !HAVE_REALPATH */
+#else
if (mode == RB_REALPATH_CHECK) {
VALUE arg[3];
arg[0] = basedir;
@@ -4609,7 +4609,7 @@ rmext(const char *p, long l0, long l1, const char *e, long l2, rb_encoding *enc)
if (l1 < l2) return l1;
s = p+l1-l2;
- if (!at_char_boundary(p, s, p+l1, enc)) return 0;
+ if (rb_enc_left_char_head(p, s, p+l1, enc) != s) return 0;
#if CASEFOLD_FILESYSTEM
#define fncomp strncasecmp
#else
@@ -4649,13 +4649,13 @@ ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encodin
p++;
f = 0;
}
-#endif /* DOSISH_DRIVE_LETTER */
+#endif
#ifdef DOSISH_UNC
else {
p = "/";
}
-#endif /* DOSISH_UNC */
-#endif /* defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC */
+#endif
+#endif
}
else {
if (!(p = strrdirsep(name, end, enc))) {
@@ -4897,7 +4897,7 @@ ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc)
continue;
#else
e = p; /* get the last dot of the last component */
-#endif /* USE_NTFS */
+#endif
}
#if USE_NTFS
else if (isADS(*p)) {
@@ -4970,7 +4970,7 @@ rb_file_s_extname(VALUE klass, VALUE fname)
*
* Returns the string representation of the path
*
- * File.path(File::NULL) #=> "/dev/null"
+ * File.path("/dev/null") #=> "/dev/null"
* File.path(Pathname.new("/tmp")) #=> "/tmp"
*
*/
@@ -5222,75 +5222,47 @@ rb_thread_flock(void *data)
return (VALUE)ret;
}
-/* :markup: markdown
- *
+/*
* call-seq:
- * flock(locking_constant) -> 0 or false
- *
- * Locks or unlocks a file according to the given `locking_constant`,
- * a bitwise OR of the values in the table below.
+ * file.flock(locking_constant) -> 0 or false
+ *
+ * Locks or unlocks a file according to <i>locking_constant</i> (a
+ * logical <em>or</em> of the values in the table below).
+ * Returns <code>false</code> if File::LOCK_NB is specified and the
+ * operation would otherwise have blocked. Not available on all
+ * platforms.
+ *
+ * Locking constants (in class File):
+ *
+ * LOCK_EX | Exclusive lock. Only one process may hold an
+ * | exclusive lock for a given file at a time.
+ * ----------+------------------------------------------------
+ * LOCK_NB | Don't block when locking. May be combined
+ * | with other lock options using logical or.
+ * ----------+------------------------------------------------
+ * LOCK_SH | Shared lock. Multiple processes may each hold a
+ * | shared lock for a given file at the same time.
+ * ----------+------------------------------------------------
+ * LOCK_UN | Unlock.
*
- * Not available on all platforms.
- *
- * Returns `false` if `File::LOCK_NB` is specified and the operation would have blocked;
- * otherwise returns `0`.
- * <br>
- *
- * <table>
- * <tr>
- * <th colspan="3">Locking Constants</th>
- * </tr>
- * <tr>
- * <th>Constant</th>
- * <th>Lock</th>
- * <th>Effect</th>
- * </tr>
- * <tr>
- * <td><tt>File::LOCK_EX</tt></td>
- * <td>Exclusive</td>
- * <td>Only one process may hold an exclusive lock for <tt>self</tt> at a time.</td>
- * </tr>
- * <tr>
- * <td><tt>File::LOCK_NB</tt></td>
- * <td>Non-blocking</td>
- * <td>
- * No blocking; may be combined with other <tt>File::LOCK_SH</tt> or <tt>File::LOCK_EX</tt>
- * using the bitwise OR operator <tt>|</tt>.
- * </td>
- * </tr>
- * <tr>
- * <td><tt>File::LOCK_SH</tt></td>
- * <td>Shared</td>
- * <td>Multiple processes may each hold a shared lock for <tt>self</tt> at the same time.</td>
- * </tr>
- * <tr>
- * <td><tt>File::LOCK_UN</tt></td>
- * <td>Unlock</td>
- * <td>Remove an existing lock held by this process.</td>
- * </tr>
- * </table>
- *
- * <br>
* Example:
*
- * ```ruby
- * # Update a counter using an exclusive lock.
- * # Don't use File::WRONLY because it truncates the file.
- * File.open('counter', File::RDWR | File::CREAT, 0644) do |f|
- * f.flock(File::LOCK_EX)
- * value = f.read.to_i + 1
- * f.rewind
- * f.write("#{value}\n")
- * f.flush
- * f.truncate(f.pos)
- * end
- *
- * # Read the counter using a shared lock.
- * File.open('counter', 'r') do |f|
- * f.flock(File::LOCK_SH)
- * f.read
- * end
- * ```
+ * # update a counter using write lock
+ * # don't use "w" because it truncates the file before lock.
+ * File.open("counter", File::RDWR|File::CREAT, 0644) {|f|
+ * f.flock(File::LOCK_EX)
+ * value = f.read.to_i + 1
+ * f.rewind
+ * f.write("#{value}\n")
+ * f.flush
+ * f.truncate(f.pos)
+ * }
+ *
+ * # read the counter using read lock
+ * File.open("counter", "r") {|f|
+ * f.flock(File::LOCK_SH)
+ * p f.read
+ * }
*
*/
@@ -5586,7 +5558,7 @@ rb_stat_s_alloc(VALUE klass)
static VALUE
rb_stat_init(VALUE obj, VALUE fname)
{
- struct stat st;
+ struct stat st, *nst;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
@@ -5594,11 +5566,13 @@ rb_stat_init(VALUE obj, VALUE fname)
rb_sys_fail_path(fname);
}
- struct rb_stat *rb_st;
- TypedData_Get_Struct(obj, struct rb_stat, &stat_data_type, rb_st);
-
- rb_st->stat = st;
- rb_st->initialized = true;
+ if (DATA_PTR(obj)) {
+ xfree(DATA_PTR(obj));
+ DATA_PTR(obj) = NULL;
+ }
+ nst = ALLOC(struct stat);
+ *nst = st;
+ DATA_PTR(obj) = nst;
return Qnil;
}
@@ -5607,15 +5581,19 @@ rb_stat_init(VALUE obj, VALUE fname)
static VALUE
rb_stat_init_copy(VALUE copy, VALUE orig)
{
- if (!OBJ_INIT_COPY(copy, orig)) return copy;
-
- struct rb_stat *orig_rb_st;
- TypedData_Get_Struct(orig, struct rb_stat, &stat_data_type, orig_rb_st);
+ struct stat *nst;
- struct rb_stat *copy_rb_st;
- TypedData_Get_Struct(copy, struct rb_stat, &stat_data_type, copy_rb_st);
+ if (!OBJ_INIT_COPY(copy, orig)) return copy;
+ if (DATA_PTR(copy)) {
+ xfree(DATA_PTR(copy));
+ DATA_PTR(copy) = 0;
+ }
+ if (DATA_PTR(orig)) {
+ nst = ALLOC(struct stat);
+ *nst = *(struct stat*)DATA_PTR(orig);
+ DATA_PTR(copy) = nst;
+ }
- *copy_rb_st = *orig_rb_st;
return copy;
}
@@ -5899,8 +5877,10 @@ rb_stat_wr(VALUE obj)
if ((st->st_mode & (S_IROTH)) == S_IROTH) {
return UINT2NUM(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
+ else {
+ return Qnil;
+ }
#endif
- return Qnil;
}
/*
@@ -5985,13 +5965,15 @@ rb_stat_W(VALUE obj)
static VALUE
rb_stat_ww(VALUE obj)
{
-#ifdef S_IWOTH
+#ifdef S_IROTH
struct stat *st = get_stat(obj);
if ((st->st_mode & (S_IWOTH)) == S_IWOTH) {
return UINT2NUM(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
+ else {
+ return Qnil;
+ }
#endif
- return Qnil;
}
/*
@@ -6107,7 +6089,7 @@ rb_stat_z(VALUE obj)
* the file otherwise.
*
* File.stat("testfile").size? #=> 66
- * File.stat(File::NULL).size? #=> nil
+ * File.stat("/dev/null").size? #=> nil
*
*/
@@ -6390,11 +6372,7 @@ rb_file_load_ok(const char *path)
#endif
0);
int fd = rb_cloexec_open(path, mode, 0);
- if (fd < 0) {
- if (!rb_gc_for_fd(errno)) return 0;
- fd = rb_cloexec_open(path, mode, 0);
- if (fd < 0) return 0;
- }
+ if (fd == -1) return 0;
rb_update_max_fd(fd);
ret = ruby_is_fd_loadable(fd);
(void)close(fd);
@@ -6552,7 +6530,7 @@ const char ruby_null_device[] =
* \Class \File extends module FileTest, supporting such singleton methods
* as <tt>File.exist?</tt>.
*
- * == About the Examples
+ * === About the Examples
*
* Many examples here use these variables:
*
@@ -6560,11 +6538,11 @@ const char ruby_null_device[] =
*
* == Access Modes
*
- * Methods File.new and File.open each create a \File object for a given file path.
+ * \Methods File.new and File.open each create a \File object for a given file path.
*
* === \String Access Modes
*
- * Methods File.new and File.open each may take string argument +mode+, which:
+ * \Methods File.new and File.open each may take string argument +mode+, which:
*
* - Begins with a 1- or 2-character
* {read/write mode}[rdoc-ref:File@Read-2FWrite+Mode].
@@ -7155,6 +7133,7 @@ const char ruby_null_device[] =
*
* Note that file permissions are quite different from the _mode_
* of a file stream (\File object).
+ * See IO@Modes.
*
* In a \File object, the permissions are available thus,
* where method +mode+, despite its name, returns permissions:
@@ -7200,7 +7179,7 @@ const char ruby_null_device[] =
*
* == \File \Constants
*
- * Various constants for use in \File and IO methods
+ * Various constants for use in \File and \IO methods
* may be found in module File::Constants;
* an array of their names is returned by <tt>File::Constants.constants</tt>.
*
@@ -7210,7 +7189,7 @@ const char ruby_null_device[] =
*
* - Inherits from {class IO}[rdoc-ref:IO@What-27s+Here],
* in particular, methods for creating, reading, and writing files
- * - Includes module FileTest,
+ * - Includes {module FileTest}[rdoc-ref:FileTest@What-27s+Here].
* which provides dozens of additional methods.
*
* Here, class \File provides methods that are useful for:
@@ -7255,15 +7234,15 @@ const char ruby_null_device[] =
*
* _Times_
*
- * - ::atime: Returns a Time for the most recent access to the given file.
- * - ::birthtime: Returns a Time for the creation of the given file.
- * - ::ctime: Returns a Time for the metadata change of the given file.
- * - ::mtime: Returns a Time for the most recent data modification to
+ * - ::atime: Returns a \Time for the most recent access to the given file.
+ * - ::birthtime: Returns a \Time for the creation of the given file.
+ * - ::ctime: Returns a \Time for the metadata change of the given file.
+ * - ::mtime: Returns a \Time for the most recent data modification to
* the content of the given file.
- * - #atime: Returns a Time for the most recent access to +self+.
- * - #birthtime: Returns a Time the creation for +self+.
- * - #ctime: Returns a Time for the metadata change of +self+.
- * - #mtime: Returns a Time for the most recent data modification
+ * - #atime: Returns a \Time for the most recent access to +self+.
+ * - #birthtime: Returns a \Time the creation for +self+.
+ * - #ctime: Returns a \Time for the metadata change of +self+.
+ * - #mtime: Returns a \Time for the most recent data modification
* to the content of +self+.
*
* _Types_
@@ -7452,396 +7431,93 @@ Init_File(void)
/*
* Document-module: File::Constants
*
- * \Module +File::Constants+ defines file-related constants.
- *
- * There are two families of constants here:
- *
- * - Those having to do with {file access}[rdoc-ref:File::Constants@File+Access].
- * - Those having to do with {filename globbing}[rdoc-ref:File::Constants@Filename+Globbing+Constants+-28File-3A-3AFNM_-2A-29].
- *
- * \File constants defined for the local process may be retrieved
- * with method File::Constants.constants:
- *
- * File::Constants.constants.take(5)
- * # => [:RDONLY, :WRONLY, :RDWR, :APPEND, :CREAT]
- *
- * == \File Access
- *
- * \File-access constants may be used with optional argument +mode+ in calls
- * to the following methods:
- *
- * - File.new.
- * - File.open.
- * - IO.for_fd.
- * - IO.new.
- * - IO.open.
- * - IO.popen.
- * - IO.reopen.
- * - IO.sysopen.
- * - StringIO.new.
- * - StringIO.open.
- * - StringIO#reopen.
- *
- * === Read/Write Access
- *
- * Read-write access for a stream
- * may be specified by a file-access constant.
- *
- * The constant may be specified as part of a bitwise OR of other such constants.
- *
- * Any combination of the constants in this section may be specified.
- *
- * ==== File::RDONLY
- *
- * Flag File::RDONLY specifies the the stream should be opened for reading only:
- *
- * filepath = '/tmp/t.tmp'
- * f = File.new(filepath, File::RDONLY)
- * f.write('Foo') # Raises IOError (not opened for writing).
- *
- * ==== File::WRONLY
- *
- * Flag File::WRONLY specifies that the stream should be opened for writing only:
- *
- * f = File.new(filepath, File::WRONLY)
- * f.read # Raises IOError (not opened for reading).
- *
- * ==== File::RDWR
- *
- * Flag File::RDWR specifies that the stream should be opened
- * for both reading and writing:
- *
- * f = File.new(filepath, File::RDWR)
- * f.write('Foo') # => 3
- * f.rewind # => 0
- * f.read # => "Foo"
- *
- * === \File Positioning
- *
- * ==== File::APPEND
- *
- * Flag File::APPEND specifies that the stream should be opened
- * in append mode.
- *
- * Before each write operation, the position is set to end-of-stream.
- * The modification of the position and the following write operation
- * are performed as a single atomic step.
- *
- * ==== File::TRUNC
- *
- * Flag File::TRUNC specifies that the stream should be truncated
- * at its beginning.
- * If the file exists and is successfully opened for writing,
- * it is to be truncated to position zero;
- * its ctime and mtime are updated.
- *
- * There is no effect on a FIFO special file or a terminal device.
- * The effect on other file types is implementation-defined.
- * The result of using File::TRUNC with File::RDONLY is undefined.
- *
- * === Creating and Preserving
- *
- * ==== File::CREAT
- *
- * Flag File::CREAT specifies that the stream should be created
- * if it does not already exist.
- *
- * If the file exists:
- *
- * - Raise an exception if File::EXCL is also specified.
- * - Otherwise, do nothing.
- *
- * If the file does not exist, then it is created.
- * Upon successful completion, the atime, ctime, and mtime of the file are updated,
- * and the ctime and mtime of the parent directory are updated.
- *
- * ==== File::EXCL
- *
- * Flag File::EXCL specifies that the stream should not already exist;
- * If flags File::CREAT and File::EXCL are both specified
- * and the stream already exists, an exception is raised.
- *
- * The check for the existence and creation of the file is performed as an
- * atomic operation.
- *
- * If both File::EXCL and File::CREAT are specified and the path names a symbolic link,
- * an exception is raised regardless of the contents of the symbolic link.
- *
- * If File::EXCL is specified and File::CREAT is not specified,
- * the result is undefined.
- *
- * === POSIX \File \Constants
- *
- * Some file-access constants are defined only on POSIX-compliant systems;
- * those are:
- *
- * - File::SYNC.
- * - File::DSYNC.
- * - File::RSYNC.
- * - File::DIRECT.
- * - File::NOATIME.
- * - File::NOCTTY.
- * - File::NOFOLLOW.
- * - File::TMPFILE.
- *
- * ==== File::SYNC, File::RSYNC, and File::DSYNC
- *
- * Flag File::SYNC, File::RSYNC, or File::DSYNC
- * specifies synchronization of I/O operations with the underlying file system.
- *
- * These flags are valid only for POSIX-compliant systems.
- *
- * - File::SYNC specifies that all write operations (both data and metadata)
- * are immediately to be flushed to the underlying storage device.
- * This means that the data is written to the storage device,
- * and the file's metadata (e.g., file size, timestamps, permissions)
- * are also synchronized.
- * This guarantees that data is safely stored on the storage medium
- * before returning control to the calling program.
- * This flag can have a significant impact on performance
- * since it requires synchronous writes, which can be slower
- * compared to asynchronous writes.
- *
- * - File::RSYNC specifies that any read operations on the file will not return
- * until all outstanding write operations
- * (those that have been issued but not completed) are also synchronized.
- * This is useful when you want to read the most up-to-date data,
- * which may still be in the process of being written.
- *
- * - File::DSYNC specifies that all _data_ write operations
- * are immediately to be flushed to the underlying storage device;
- * this differs from File::SYNC, which requires that _metadata_
- * also be synchronized.
- *
- * Note that the behavior of these flags may vary slightly
- * depending on the operating system and filesystem being used.
- * Additionally, using these flags can have an impact on performance
- * due to the synchronous nature of the I/O operations,
- * so they should be used judiciously,
- * especially in performance-critical applications.
- *
- * ==== File::NOCTTY
+ * File::Constants provides file-related constants. All possible
+ * file constants are listed in the documentation but they may not all
+ * be present on your platform.
*
- * Flag File::NOCTTY specifies that if the stream is a terminal device,
- * that device does not become the controlling terminal for the process.
- *
- * Defined only for POSIX-compliant systems.
- *
- * ==== File::DIRECT
- *
- * Flag File::DIRECT requests that cache effects of the I/O to and from the stream
- * be minimized.
- *
- * Defined only for POSIX-compliant systems.
- *
- * ==== File::NOATIME
- *
- * Flag File::NOATIME specifies that act of opening the stream
- * should not modify its access time (atime).
- *
- * Defined only for POSIX-compliant systems.
- *
- * ==== File::NOFOLLOW
- *
- * Flag File::NOFOLLOW specifies that if path is a symbolic link,
- * it should not be followed.
- *
- * Defined only for POSIX-compliant systems.
- *
- * ==== File::TMPFILE
- *
- * Flag File::TMPFILE specifies that the opened stream
- * should be a new temporary file.
- *
- * Defined only for POSIX-compliant systems.
- *
- * === Other File-Access \Constants
- *
- * ==== File::NONBLOCK
- *
- * When possible, the file is opened in nonblocking mode.
- * Neither the open operation nor any subsequent I/O operations on
- * the file will cause the calling process to wait.
- *
- * ==== File::BINARY
- *
- * Flag File::BINARY specifies that the stream is to be accessed in binary mode.
- *
- * ==== File::SHARE_DELETE (Windows Only)
- *
- * Flag File::SHARE_DELETE enables other processes to open the stream
- * with delete access.
- *
- * If the stream is opened for (local) delete access without File::SHARE_DELETE,
- * and another process attempts to open it with delete access,
- * the attempt fails and the stream is not opened for that process.
- *
- * == Locking
- *
- * Four file constants relate to stream locking;
- * see File#flock:
- *
- * ==== File::LOCK_EX
- *
- * Flag File::LOCK_EX specifies an exclusive lock;
- * only one process a a time may lock the stream.
- *
- * ==== File::LOCK_NB
- *
- * Flag File::LOCK_NB specifies non-blocking locking for the stream;
- * may be combined with File::LOCK_EX or File::LOCK_SH.
- *
- * ==== File::LOCK_SH
- *
- * Flag File::LOCK_SH specifies that multiple processes may lock
- * the stream at the same time.
- *
- * ==== File::LOCK_UN
- *
- * Flag File::LOCK_UN specifies that the stream is not to be locked.
- *
- * == Filename Globbing \Constants (File::FNM_*)
- *
- * Filename-globbing constants may be used with optional argument +flags+
- * in calls to the following methods:
- *
- * - Dir.glob.
- * - File.fnmatch.
- * - Pathname#fnmatch.
- * - Pathname.glob.
- * - Pathname#glob.
- *
- * The constants are:
- *
- * ==== File::FNM_CASEFOLD
- *
- * Flag File::FNM_CASEFOLD makes patterns case insensitive
- * for File.fnmatch (but not Dir.glob).
- *
- * ==== File::FNM_DOTMATCH
- *
- * Flag File::FNM_DOTMATCH makes the <tt>'*'</tt> pattern
- * match a filename starting with <tt>'.'</tt>.
- *
- * ==== File::FNM_EXTGLOB
- *
- * Flag File::FNM_EXTGLOB enables pattern <tt>'{_a_,_b_}'</tt>,
- * which matches pattern '_a_' and pattern '_b_';
- * behaves like
- * a {regexp union}[rdoc-ref:Regexp.union]
- * (e.g., <tt>'(?:_a_|_b_)'</tt>):
- *
- * pattern = '{LEGAL,BSDL}'
- * Dir.glob(pattern) # => ["LEGAL", "BSDL"]
- * Pathname.glob(pattern) # => [#<Pathname:LEGAL>, #<Pathname:BSDL>]
- * pathname.glob(pattern) # => [#<Pathname:LEGAL>, #<Pathname:BSDL>]
- *
- * ==== File::FNM_NOESCAPE
- *
- * Flag File::FNM_NOESCAPE disables <tt>'\'</tt> escaping.
- *
- * ==== File::FNM_PATHNAME
- *
- * Flag File::FNM_PATHNAME specifies that patterns <tt>'*'</tt> and <tt>'?'</tt>
- * do not match the directory separator
- * (the value of constant File::SEPARATOR).
- *
- * ==== File::FNM_SHORTNAME (Windows Only)
- *
- * Flag File::FNM_SHORTNAME Allows patterns to match short names if they exist.
- *
- * ==== File::FNM_SYSCASE
- *
- * Flag File::FNM_SYSCASE specifies that case sensitivity
- * is the same as in the underlying operating system;
- * effective for File.fnmatch, but not Dir.glob.
- *
- * == Other \Constants
- *
- * ==== File::NULL
- *
- * Flag File::NULL contains the string value of the null device:
- *
- * - On a Unix-like OS, <tt>'/dev/null'</tt>.
- * - On Windows, <tt>'NUL'</tt>.
+ * If the underlying platform doesn't define a constant the corresponding
+ * Ruby constant is not defined.
*
+ * Your platform documentations (e.g. man open(2)) may describe more
+ * detailed information.
*/
rb_mFConst = rb_define_module_under(rb_cFile, "Constants");
rb_include_module(rb_cIO, rb_mFConst);
- /* {File::RDONLY}[rdoc-ref:File::Constants@File-3A-3ARDONLY] */
+
+ /* open for reading only */
rb_define_const(rb_mFConst, "RDONLY", INT2FIX(O_RDONLY));
- /* {File::WRONLY}[rdoc-ref:File::Constants@File-3A-3AWRONLY] */
+ /* open for writing only */
rb_define_const(rb_mFConst, "WRONLY", INT2FIX(O_WRONLY));
- /* {File::RDWR}[rdoc-ref:File::Constants@File-3A-3ARDWR] */
+ /* open for reading and writing */
rb_define_const(rb_mFConst, "RDWR", INT2FIX(O_RDWR));
- /* {File::APPEND}[rdoc-ref:File::Constants@File-3A-3AAPPEND] */
+ /* append on each write */
rb_define_const(rb_mFConst, "APPEND", INT2FIX(O_APPEND));
- /* {File::CREAT}[rdoc-ref:File::Constants@File-3A-3ACREAT] */
+ /* create file if it does not exist */
rb_define_const(rb_mFConst, "CREAT", INT2FIX(O_CREAT));
- /* {File::EXCL}[rdoc-ref:File::Constants@File-3A-3AEXCL] */
+ /* error if CREAT and the file exists */
rb_define_const(rb_mFConst, "EXCL", INT2FIX(O_EXCL));
#if defined(O_NDELAY) || defined(O_NONBLOCK)
# ifndef O_NONBLOCK
# define O_NONBLOCK O_NDELAY
# endif
- /* {File::NONBLOCK}[rdoc-ref:File::Constants@File-3A-3ANONBLOCK] */
+ /* do not block on open or for data to become available */
rb_define_const(rb_mFConst, "NONBLOCK", INT2FIX(O_NONBLOCK));
#endif
- /* {File::TRUNC}[rdoc-ref:File::Constants@File-3A-3ATRUNC] */
+ /* truncate size to 0 */
rb_define_const(rb_mFConst, "TRUNC", INT2FIX(O_TRUNC));
#ifdef O_NOCTTY
- /* {File::NOCTTY}[rdoc-ref:File::Constants@File-3A-3ANOCTTY] */
+ /* not to make opened IO the controlling terminal device */
rb_define_const(rb_mFConst, "NOCTTY", INT2FIX(O_NOCTTY));
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif
- /* {File::BINARY}[rdoc-ref:File::Constants@File-3A-3ABINARY] */
+ /* disable line code conversion */
rb_define_const(rb_mFConst, "BINARY", INT2FIX(O_BINARY));
#ifndef O_SHARE_DELETE
# define O_SHARE_DELETE 0
#endif
- /* {File::SHARE_DELETE}[rdoc-ref:File::Constants@File-3A-3ASHARE_DELETE+-28Windows+Only-29] */
+ /* can delete opened file */
rb_define_const(rb_mFConst, "SHARE_DELETE", INT2FIX(O_SHARE_DELETE));
#ifdef O_SYNC
- /* {File::SYNC}[rdoc-ref:File::Constants@File-3A-3ASYNC-2C+File-3A-3ARSYNC-2C+and+File-3A-3ADSYNC] */
+ /* any write operation perform synchronously */
rb_define_const(rb_mFConst, "SYNC", INT2FIX(O_SYNC));
#endif
#ifdef O_DSYNC
- /* {File::DSYNC}[rdoc-ref:File::Constants@File-3A-3ASYNC-2C+File-3A-3ARSYNC-2C+and+File-3A-3ADSYNC] */
+ /* any write operation perform synchronously except some meta data */
rb_define_const(rb_mFConst, "DSYNC", INT2FIX(O_DSYNC));
#endif
#ifdef O_RSYNC
- /* {File::RSYNC}[rdoc-ref:File::Constants@File-3A-3ASYNC-2C+File-3A-3ARSYNC-2C+and+File-3A-3ADSYNC] */
+ /* any read operation perform synchronously. used with SYNC or DSYNC. */
rb_define_const(rb_mFConst, "RSYNC", INT2FIX(O_RSYNC));
#endif
#ifdef O_NOFOLLOW
- /* {File::NOFOLLOW}[rdoc-ref:File::Constants@File-3A-3ANOFOLLOW] */
+ /* do not follow symlinks */
rb_define_const(rb_mFConst, "NOFOLLOW", INT2FIX(O_NOFOLLOW)); /* FreeBSD, Linux */
#endif
#ifdef O_NOATIME
- /* {File::NOATIME}[rdoc-ref:File::Constants@File-3A-3ANOATIME] */
+ /* do not change atime */
rb_define_const(rb_mFConst, "NOATIME", INT2FIX(O_NOATIME)); /* Linux */
#endif
#ifdef O_DIRECT
- /* {File::DIRECT}[rdoc-ref:File::Constants@File-3A-3ADIRECT] */
+ /* Try to minimize cache effects of the I/O to and from this file. */
rb_define_const(rb_mFConst, "DIRECT", INT2FIX(O_DIRECT));
#endif
#ifdef O_TMPFILE
- /* {File::TMPFILE}[rdoc-ref:File::Constants@File-3A-3ATMPFILE] */
+ /* Create an unnamed temporary file */
rb_define_const(rb_mFConst, "TMPFILE", INT2FIX(O_TMPFILE));
#endif
- /* {File::LOCK_SH}[rdoc-ref:File::Constants@File-3A-3ALOCK_SH] */
+ /* shared lock. see File#flock */
rb_define_const(rb_mFConst, "LOCK_SH", INT2FIX(LOCK_SH));
- /* {File::LOCK_EX}[rdoc-ref:File::Constants@File-3A-3ALOCK_EX] */
+ /* exclusive lock. see File#flock */
rb_define_const(rb_mFConst, "LOCK_EX", INT2FIX(LOCK_EX));
- /* {File::LOCK_UN}[rdoc-ref:File::Constants@File-3A-3ALOCK_UN] */
+ /* unlock. see File#flock */
rb_define_const(rb_mFConst, "LOCK_UN", INT2FIX(LOCK_UN));
- /* {File::LOCK_NB}[rdoc-ref:File::Constants@File-3A-3ALOCK_NB] */
+ /* non-blocking lock. used with LOCK_SH or LOCK_EX. see File#flock */
rb_define_const(rb_mFConst, "LOCK_NB", INT2FIX(LOCK_NB));
- /* {File::NULL}[rdoc-ref:File::Constants@File-3A-3ANULL] */
+ /* Name of the null device */
rb_define_const(rb_mFConst, "NULL", rb_fstring_cstr(ruby_null_device));
rb_define_global_function("test", rb_f_test, -1);
diff --git a/gc.c b/gc.c
index 378e4a31cb..919d57989a 100644
--- a/gc.c
+++ b/gc.c
@@ -60,15 +60,6 @@
# endif
#endif
-#ifdef HAVE_MALLOC_TRIM
-# include <malloc.h>
-
-# ifdef __EMSCRIPTEN__
-/* malloc_trim is defined in emscripten/emmalloc.h on emscripten. */
-# include <emscripten/emmalloc.h>
-# endif
-#endif
-
#if !defined(PAGE_SIZE) && defined(HAVE_SYS_USER_H)
/* LIST_HEAD conflicts with sys/queue.h on macOS */
# include <sys/user.h>
@@ -104,13 +95,12 @@
#undef LIST_HEAD /* ccan/list conflicts with BSD-origin sys/queue.h. */
#include "constant.h"
-#include "darray.h"
#include "debug_counter.h"
#include "eval_intern.h"
+#include "gc.h"
#include "id_table.h"
#include "internal.h"
#include "internal/class.h"
-#include "internal/compile.h"
#include "internal/complex.h"
#include "internal/cont.h"
#include "internal/error.h"
@@ -129,7 +119,7 @@
#include "internal/thread.h"
#include "internal/variable.h"
#include "internal/warnings.h"
-#include "rjit.h"
+#include "mjit.h"
#include "probes.h"
#include "regint.h"
#include "ruby/debug.h"
@@ -141,6 +131,7 @@
#include "ruby_assert.h"
#include "ruby_atomic.h"
#include "symbol.h"
+#include "transient_heap.h"
#include "vm_core.h"
#include "vm_sync.h"
#include "vm_callinfo.h"
@@ -157,68 +148,6 @@
#define MAP_ANONYMOUS MAP_ANON
#endif
-
-static size_t malloc_offset = 0;
-#if defined(HAVE_MALLOC_USABLE_SIZE)
-static size_t
-gc_compute_malloc_offset(void)
-{
- // Different allocators use different metadata storage strategies which result in different
- // ideal sizes.
- // For instance malloc(64) will waste 8B with glibc, but waste 0B with jemalloc.
- // But malloc(56) will waste 0B with glibc, but waste 8B with jemalloc.
- // So we try allocating 64, 56 and 48 bytes and select the first offset that doesn't
- // waste memory.
- // This was tested on Linux with glibc 2.35 and jemalloc 5, and for both it result in
- // no wasted memory.
- size_t offset = 0;
- for (offset = 0; offset <= 16; offset += 8) {
- size_t allocated = (64 - offset);
- void *test_ptr = malloc(allocated);
- size_t wasted = malloc_usable_size(test_ptr) - allocated;
- free(test_ptr);
-
- if (wasted == 0) {
- return offset;
- }
- }
- return 0;
-}
-#else
-static size_t
-gc_compute_malloc_offset(void)
-{
- // If we don't have malloc_usable_size, we use powers of 2.
- return 0;
-}
-#endif
-
-size_t
-rb_malloc_grow_capa(size_t current, size_t type_size)
-{
- size_t current_capacity = current;
- if (current_capacity < 4) {
- current_capacity = 4;
- }
- current_capacity *= type_size;
-
- // We double the current capacity.
- size_t new_capacity = (current_capacity * 2);
-
- // And round up to the next power of 2 if it's not already one.
- if (rb_popcount64(new_capacity) != 1) {
- new_capacity = (size_t)(1 << (64 - nlz_int64(new_capacity)));
- }
-
- new_capacity -= malloc_offset;
- new_capacity /= type_size;
- if (current > new_capacity) {
- rb_bug("rb_malloc_grow_capa: current_capacity=%zu, new_capacity=%zu, malloc_offset=%zu", current, new_capacity, malloc_offset);
- }
- RUBY_ASSERT(new_capacity > current);
- return new_capacity;
-}
-
static inline struct rbimpl_size_mul_overflow_tag
size_add_overflow(size_t x, size_t y)
{
@@ -362,9 +291,6 @@ rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val)
#ifndef GC_HEAP_GROWTH_MAX_SLOTS
#define GC_HEAP_GROWTH_MAX_SLOTS 0 /* 0 is disable */
#endif
-#ifndef GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO
-# define GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO 0.01
-#endif
#ifndef GC_HEAP_OLDOBJECT_LIMIT_FACTOR
#define GC_HEAP_OLDOBJECT_LIMIT_FACTOR 2.0
#endif
@@ -399,14 +325,6 @@ rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val)
#define GC_OLDMALLOC_LIMIT_MAX (128 * 1024 * 1024 /* 128MB */)
#endif
-#ifndef GC_CAN_COMPILE_COMPACTION
-#if defined(__wasi__) /* WebAssembly doesn't support signals */
-# define GC_CAN_COMPILE_COMPACTION 0
-#else
-# define GC_CAN_COMPILE_COMPACTION 1
-#endif
-#endif
-
#ifndef PRINT_MEASURE_LINE
#define PRINT_MEASURE_LINE 0
#endif
@@ -421,7 +339,7 @@ rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val)
#define TICK_TYPE 1
typedef struct {
- size_t size_pool_init_slots[SIZE_POOL_COUNT];
+ size_t heap_init_slots;
size_t heap_free_slots;
double growth_factor;
size_t growth_max_slots;
@@ -429,7 +347,6 @@ typedef struct {
double heap_free_slots_min_ratio;
double heap_free_slots_goal_ratio;
double heap_free_slots_max_ratio;
- double uncollectible_wb_unprotected_objects_limit_ratio;
double oldobject_limit_factor;
size_t malloc_limit_min;
@@ -444,7 +361,7 @@ typedef struct {
} ruby_gc_params_t;
static ruby_gc_params_t gc_params = {
- { 0 },
+ GC_HEAP_INIT_SLOTS,
GC_HEAP_FREE_SLOTS,
GC_HEAP_GROWTH_FACTOR,
GC_HEAP_GROWTH_MAX_SLOTS,
@@ -452,7 +369,6 @@ static ruby_gc_params_t gc_params = {
GC_HEAP_FREE_SLOTS_MIN_RATIO,
GC_HEAP_FREE_SLOTS_GOAL_RATIO,
GC_HEAP_FREE_SLOTS_MAX_RATIO,
- GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO,
GC_HEAP_OLDOBJECT_LIMIT_FACTOR,
GC_MALLOC_LIMIT_MIN,
@@ -511,6 +427,16 @@ int ruby_rgengc_debug;
// Note: using RUBY_ASSERT_WHEN() extend a macro in expr (info by nobu).
#define GC_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(RGENGC_CHECK_MODE > 0, expr, #expr)
+/* RGENGC_OLD_NEWOBJ_CHECK
+ * 0: disable all assertions
+ * >0: make a OLD object when new object creation.
+ *
+ * Make one OLD object per RGENGC_OLD_NEWOBJ_CHECK WB protected objects creation.
+ */
+#ifndef RGENGC_OLD_NEWOBJ_CHECK
+#define RGENGC_OLD_NEWOBJ_CHECK 0
+#endif
+
/* RGENGC_PROFILE
* 0: disable RGenGC profiling
* 1: enable profiling for basic information
@@ -543,6 +469,9 @@ int ruby_rgengc_debug;
#ifndef GC_PROFILE_DETAIL_MEMORY
#define GC_PROFILE_DETAIL_MEMORY 0
#endif
+#ifndef GC_ENABLE_INCREMENTAL_MARK
+#define GC_ENABLE_INCREMENTAL_MARK USE_RINCGC
+#endif
#ifndef GC_ENABLE_LAZY_SWEEP
#define GC_ENABLE_LAZY_SWEEP 1
#endif
@@ -561,7 +490,7 @@ int ruby_rgengc_debug;
#endif
#ifndef GC_DEBUG_STRESS_TO_CLASS
-#define GC_DEBUG_STRESS_TO_CLASS RUBY_DEBUG
+#define GC_DEBUG_STRESS_TO_CLASS 0
#endif
#ifndef RGENGC_OBJ_INFO
@@ -759,15 +688,15 @@ typedef struct mark_stack {
#define SIZE_POOL_EDEN_HEAP(size_pool) (&(size_pool)->eden_heap)
#define SIZE_POOL_TOMB_HEAP(size_pool) (&(size_pool)->tomb_heap)
-typedef int (*gc_compact_compare_func)(const void *l, const void *r, void *d);
-
typedef struct rb_heap_struct {
struct heap_page *free_pages;
struct ccan_list_head pages;
struct heap_page *sweeping_page; /* iterator for .pages */
struct heap_page *compact_cursor;
uintptr_t compact_cursor_index;
+#if GC_ENABLE_INCREMENTAL_MARK
struct heap_page *pooled_pages;
+#endif
size_t total_pages; /* total page count in a heap */
size_t total_slots; /* total slot count (about total_pages * HEAP_PAGE_OBJ_LIMIT) */
} rb_heap_t;
@@ -781,13 +710,12 @@ typedef struct rb_size_pool_struct {
size_t total_allocated_pages;
size_t total_freed_pages;
size_t force_major_gc_count;
- size_t force_incremental_marking_finish_count;
- size_t total_allocated_objects;
- size_t total_freed_objects;
+#if USE_RVARGC
/* Sweeping statistics */
size_t freed_slots;
size_t empty_slots;
+#endif
rb_heap_t eden_heap;
rb_heap_t tomb_heap;
@@ -818,15 +746,17 @@ typedef struct rb_objspace {
unsigned int dont_incremental : 1;
unsigned int during_gc : 1;
unsigned int during_compacting : 1;
- unsigned int during_reference_updating : 1;
unsigned int gc_stressful: 1;
- unsigned int has_newobj_hook: 1;
+ unsigned int has_hook: 1;
unsigned int during_minor_gc : 1;
+#if GC_ENABLE_INCREMENTAL_MARK
unsigned int during_incremental_marking : 1;
+#endif
unsigned int measure_gc : 1;
} flags;
rb_event_flag_t hook_events;
+ size_t total_allocated_objects;
VALUE next_object_id;
rb_size_pool_t size_pools[SIZE_POOL_COUNT];
@@ -895,14 +825,9 @@ typedef struct rb_objspace {
/* basic statistics */
size_t count;
- uint64_t marking_time_ns;
- struct timespec marking_start_time;
- uint64_t sweeping_time_ns;
- struct timespec sweeping_start_time;
-
- /* Weak references */
- size_t weak_references_count;
- size_t retained_weak_references_count;
+ size_t total_freed_objects;
+ uint64_t total_time_ns;
+ struct timespec start_time;
} profile;
struct gc_list *global_list;
@@ -934,15 +859,14 @@ typedef struct rb_objspace {
size_t moved_up_count_table[T_MASK];
size_t moved_down_count_table[T_MASK];
size_t total_moved;
-
- /* This function will be used, if set, to sort the heap prior to compaction */
- gc_compact_compare_func compare_func;
} rcompactor;
+#if GC_ENABLE_INCREMENTAL_MARK
struct {
size_t pooled_slots;
size_t step_slots;
} rincgc;
+#endif
st_table *id_to_obj_tbl;
st_table *obj_to_id_tbl;
@@ -950,9 +874,6 @@ typedef struct rb_objspace {
#if GC_DEBUG_STRESS_TO_CLASS
VALUE stress_to_class;
#endif
-
- rb_darray(VALUE *) weak_references;
- rb_postponed_job_handle_t finalize_deferred_pjob;
} rb_objspace_t;
@@ -975,7 +896,7 @@ enum {
#define HEAP_PAGE_ALIGN (1 << HEAP_PAGE_ALIGN_LOG)
#define HEAP_PAGE_SIZE HEAP_PAGE_ALIGN
-#if !defined(INCREMENTAL_MARK_STEP_ALLOCATIONS)
+#if GC_ENABLE_INCREMENTAL_MARK && !defined(INCREMENTAL_MARK_STEP_ALLOCATIONS)
# define INCREMENTAL_MARK_STEP_ALLOCATIONS 500
#endif
@@ -1021,19 +942,15 @@ static const bool HEAP_PAGE_ALLOC_USE_MMAP = false;
static bool heap_page_alloc_use_mmap;
#endif
-#define RVALUE_AGE_BIT_COUNT 2
-#define RVALUE_AGE_BIT_MASK (((bits_t)1 << RVALUE_AGE_BIT_COUNT) - 1)
-
struct heap_page {
short slot_size;
short total_slots;
short free_slots;
short final_slots;
- short pinned_slots;
struct {
unsigned int before_sweep : 1;
unsigned int has_remembered_objects : 1;
- unsigned int has_uncollectible_wb_unprotected_objects : 1;
+ unsigned int has_uncollectible_shady_objects : 1;
unsigned int in_tomb : 1;
} flags;
@@ -1050,11 +967,8 @@ struct heap_page {
bits_t uncollectible_bits[HEAP_PAGE_BITMAP_LIMIT];
bits_t marking_bits[HEAP_PAGE_BITMAP_LIMIT];
- bits_t remembered_bits[HEAP_PAGE_BITMAP_LIMIT];
-
/* If set, the object is not movable */
bits_t pinned_bits[HEAP_PAGE_BITMAP_LIMIT];
- bits_t age_bits[HEAP_PAGE_BITMAP_LIMIT * RVALUE_AGE_BIT_COUNT];
};
/*
@@ -1098,43 +1012,9 @@ asan_unlock_freelist(struct heap_page *page)
#define GC_SWEEP_PAGES_FREEABLE_PER_STEP 3
-#define RVALUE_AGE_BITMAP_INDEX(n) (NUM_IN_PAGE(n) / (BITS_BITLENGTH / RVALUE_AGE_BIT_COUNT))
-#define RVALUE_AGE_BITMAP_OFFSET(n) ((NUM_IN_PAGE(n) % (BITS_BITLENGTH / RVALUE_AGE_BIT_COUNT)) * RVALUE_AGE_BIT_COUNT)
-
-#define RVALUE_OLD_AGE 3
-
-static int
-RVALUE_AGE_GET(VALUE obj)
-{
- bits_t *age_bits = GET_HEAP_PAGE(obj)->age_bits;
- return (int)(age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] >> RVALUE_AGE_BITMAP_OFFSET(obj)) & RVALUE_AGE_BIT_MASK;
-}
-
-static void
-RVALUE_AGE_SET(VALUE obj, int age)
-{
- RUBY_ASSERT(age <= RVALUE_OLD_AGE);
- bits_t *age_bits = GET_HEAP_PAGE(obj)->age_bits;
- // clear the bits
- age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] &= ~(RVALUE_AGE_BIT_MASK << (RVALUE_AGE_BITMAP_OFFSET(obj)));
- // shift the correct value in
- age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] |= ((bits_t)age << RVALUE_AGE_BITMAP_OFFSET(obj));
- if (age == RVALUE_OLD_AGE) {
- RB_FL_SET_RAW(obj, RUBY_FL_PROMOTED);
- }
- else {
- RB_FL_UNSET_RAW(obj, RUBY_FL_PROMOTED);
- }
-}
-
/* Aliases */
#define rb_objspace (*rb_objspace_of(GET_VM()))
#define rb_objspace_of(vm) ((vm)->objspace)
-#define unless_objspace(objspace) \
- rb_objspace_t *objspace; \
- rb_vm_t *unless_objspace_vm = GET_VM(); \
- if (unless_objspace_vm) objspace = unless_objspace_vm->objspace; \
- else /* return; or objspace will be warned uninitialized */
#define ruby_initial_gc_stress gc_params.gc_stress
@@ -1160,10 +1040,8 @@ VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
#define ruby_gc_stress_mode objspace->gc_stress_mode
#if GC_DEBUG_STRESS_TO_CLASS
#define stress_to_class objspace->stress_to_class
-#define set_stress_to_class(c) (stress_to_class = (c))
#else
-#define stress_to_class (objspace, 0)
-#define set_stress_to_class(c) (objspace, (c))
+#define stress_to_class 0
#endif
#if 0
@@ -1280,43 +1158,32 @@ total_freed_pages(rb_objspace_t *objspace)
return count;
}
-static inline size_t
-total_allocated_objects(rb_objspace_t *objspace)
-{
- size_t count = 0;
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
- count += size_pool->total_allocated_objects;
- }
- return count;
-}
-
-static inline size_t
-total_freed_objects(rb_objspace_t *objspace)
-{
- size_t count = 0;
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
- count += size_pool->total_freed_objects;
- }
- return count;
-}
-
#define gc_mode(objspace) gc_mode_verify((enum gc_mode)(objspace)->flags.mode)
-#define gc_mode_set(objspace, m) ((objspace)->flags.mode = (unsigned int)gc_mode_verify(m))
+#define gc_mode_set(objspace, mode) ((objspace)->flags.mode = (unsigned int)gc_mode_verify(mode))
#define is_marking(objspace) (gc_mode(objspace) == gc_mode_marking)
#define is_sweeping(objspace) (gc_mode(objspace) == gc_mode_sweeping)
#define is_full_marking(objspace) ((objspace)->flags.during_minor_gc == FALSE)
+#if GC_ENABLE_INCREMENTAL_MARK
#define is_incremental_marking(objspace) ((objspace)->flags.during_incremental_marking != FALSE)
+#else
+#define is_incremental_marking(objspace) FALSE
+#endif
+#if GC_ENABLE_INCREMENTAL_MARK
#define will_be_incremental_marking(objspace) ((objspace)->rgengc.need_major_gc != GPR_FLAG_NONE)
+#else
+#define will_be_incremental_marking(objspace) FALSE
+#endif
+#if GC_ENABLE_INCREMENTAL_MARK
#define GC_INCREMENTAL_SWEEP_SLOT_COUNT 2048
-#define GC_INCREMENTAL_SWEEP_POOL_SLOT_COUNT 1024
+#endif
#define is_lazy_sweeping(objspace) (GC_ENABLE_LAZY_SWEEP && has_sweeping_pages(objspace))
#if SIZEOF_LONG == SIZEOF_VOIDP
+# define nonspecial_obj_id(obj) (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG)
# define obj_id_to_ref(objid) ((objid) ^ FIXNUM_FLAG) /* unset FIXNUM_FLAG */
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
+# define nonspecial_obj_id(obj) LL2NUM((SIGNED_VALUE)(obj) / 2)
# define obj_id_to_ref(objid) (FIXNUM_P(objid) ? \
((objid) ^ FIXNUM_FLAG) : (NUM2PTR(objid) << 1))
#else
@@ -1342,22 +1209,25 @@ int ruby_gc_debug_indent = 0;
VALUE rb_mGC;
int ruby_disable_gc = 0;
int ruby_enable_autocompact = 0;
-#if RGENGC_CHECK_MODE
-gc_compact_compare_func ruby_autocompact_compare_func;
-#endif
-void rb_iseq_mark_and_move(rb_iseq_t *iseq, bool referece_updating);
+void rb_iseq_mark(const rb_iseq_t *iseq);
+void rb_iseq_update_references(rb_iseq_t *iseq);
void rb_iseq_free(const rb_iseq_t *iseq);
size_t rb_iseq_memsize(const rb_iseq_t *iseq);
void rb_vm_update_references(void *ptr);
void rb_gcdebug_print_obj_condition(VALUE obj);
+static VALUE define_final0(VALUE obj, VALUE block);
+
NORETURN(static void *gc_vraise(void *ptr));
NORETURN(static void gc_raise(VALUE exc, const char *fmt, ...));
NORETURN(static void negative_size_allocation_error(const char *));
static void init_mark_stack(mark_stack_t *stack);
+
+static int ready_to_gc(rb_objspace_t *objspace);
+
static int garbage_collect(rb_objspace_t *, unsigned int reason);
static int gc_start(rb_objspace_t *objspace, unsigned int reason);
@@ -1365,7 +1235,8 @@ static void gc_rest(rb_objspace_t *objspace);
enum gc_enter_event {
gc_enter_event_start,
- gc_enter_event_continue,
+ gc_enter_event_mark_continue,
+ gc_enter_event_sweep_continue,
gc_enter_event_rest,
gc_enter_event_finalizer,
gc_enter_event_rb_memerror,
@@ -1373,26 +1244,46 @@ enum gc_enter_event {
static inline void gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev);
static inline void gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev);
-static void gc_marking_enter(rb_objspace_t *objspace);
-static void gc_marking_exit(rb_objspace_t *objspace);
-static void gc_sweeping_enter(rb_objspace_t *objspace);
-static void gc_sweeping_exit(rb_objspace_t *objspace);
-static bool gc_marks_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
+
+static void gc_marks(rb_objspace_t *objspace, int full_mark);
+static void gc_marks_start(rb_objspace_t *objspace, int full);
+static void gc_marks_finish(rb_objspace_t *objspace);
+static void gc_marks_rest(rb_objspace_t *objspace);
+static void gc_marks_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
static void gc_sweep(rb_objspace_t *objspace);
+static void gc_sweep_start(rb_objspace_t *objspace);
+#if USE_RVARGC
static void gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool);
+#endif
+static void gc_sweep_finish(rb_objspace_t *objspace);
+static int gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
+static void gc_sweep_rest(rb_objspace_t *objspace);
static void gc_sweep_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
static inline void gc_mark(rb_objspace_t *objspace, VALUE ptr);
static inline void gc_pin(rb_objspace_t *objspace, VALUE ptr);
static inline void gc_mark_and_pin(rb_objspace_t *objspace, VALUE ptr);
+static void gc_mark_ptr(rb_objspace_t *objspace, VALUE ptr);
NO_SANITIZE("memory", static void gc_mark_maybe(rb_objspace_t *objspace, VALUE ptr));
+static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr);
static int gc_mark_stacked_objects_incremental(rb_objspace_t *, size_t count);
+static int gc_mark_stacked_objects_all(rb_objspace_t *);
+static void gc_grey(rb_objspace_t *objspace, VALUE ptr);
+
+static inline int gc_mark_set(rb_objspace_t *objspace, VALUE obj);
NO_SANITIZE("memory", static inline int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr));
+static void push_mark_stack(mark_stack_t *, VALUE);
+static int pop_mark_stack(mark_stack_t *, VALUE *);
+static size_t mark_stack_size(mark_stack_t *stack);
+static void shrink_stack_chunk_cache(mark_stack_t *stack);
+
static size_t obj_memsize_of(VALUE obj, int use_all_types);
static void gc_verify_internal_consistency(rb_objspace_t *objspace);
+static int gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj);
+static int gc_verify_heap_pages(rb_objspace_t *objspace);
static void gc_stress_set(rb_objspace_t *objspace, VALUE flag);
static VALUE gc_disable_no_rest(rb_objspace_t *);
@@ -1429,8 +1320,6 @@ PRINTF_ARGS(static void gc_report_body(int level, rb_objspace_t *objspace, const
static const char *obj_info(VALUE obj);
static const char *obj_type_name(VALUE obj);
-static void gc_finalize_deferred(void *dmy);
-
/*
* 1 - TSC (H/W Time Stamp Counter)
* 2 - getrusage
@@ -1472,7 +1361,7 @@ tick(void)
return ((unsigned long long)lo)|( ((unsigned long long)hi)<<32);
}
-#elif defined(__powerpc64__) && (GCC_VERSION_SINCE(4,8,0) || defined(__clang__))
+#elif defined(__powerpc64__) && GCC_VERSION_SINCE(4,8,0)
typedef unsigned long long tick_t;
#define PRItick "llu"
@@ -1606,10 +1495,21 @@ asan_poison_object_restore(VALUE obj, void *ptr)
#define RVALUE_PAGE_UNCOLLECTIBLE(page, obj) MARKED_IN_BITMAP((page)->uncollectible_bits, (obj))
#define RVALUE_PAGE_MARKING(page, obj) MARKED_IN_BITMAP((page)->marking_bits, (obj))
+#define RVALUE_OLD_AGE 3
+#define RVALUE_AGE_SHIFT 5 /* FL_PROMOTED0 bit */
+
+static int rgengc_remembered(rb_objspace_t *objspace, VALUE obj);
+static int rgengc_remembered_sweep(rb_objspace_t *objspace, VALUE obj);
static int rgengc_remember(rb_objspace_t *objspace, VALUE obj);
static void rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap);
static void rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap);
+static inline int
+RVALUE_FLAGS_AGE(VALUE flags)
+{
+ return (int)((flags & (FL_PROMOTED0 | FL_PROMOTED1)) >> RVALUE_AGE_SHIFT);
+}
+
static int
check_rvalue_consistency_force(const VALUE obj, int terminate)
{
@@ -1647,9 +1547,8 @@ check_rvalue_consistency_force(const VALUE obj, int terminate)
const int wb_unprotected_bit = RVALUE_WB_UNPROTECTED_BITMAP(obj) != 0;
const int uncollectible_bit = RVALUE_UNCOLLECTIBLE_BITMAP(obj) != 0;
const int mark_bit = RVALUE_MARK_BITMAP(obj) != 0;
- const int marking_bit = RVALUE_MARKING_BITMAP(obj) != 0;
- const int remembered_bit = MARKED_IN_BITMAP(GET_HEAP_PAGE(obj)->remembered_bits, obj) != 0;
- const int age = RVALUE_AGE_GET((VALUE)obj);
+ const int marking_bit = RVALUE_MARKING_BITMAP(obj) != 0, remembered_bit = marking_bit;
+ const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
if (GET_HEAP_PAGE(obj)->flags.in_tomb) {
fprintf(stderr, "check_rvalue_consistency: %s is in tomb page.\n", obj_info(obj));
@@ -1782,7 +1681,7 @@ static inline int
RVALUE_REMEMBERED(VALUE obj)
{
check_rvalue_consistency(obj);
- return MARKED_IN_BITMAP(GET_HEAP_PAGE(obj)->remembered_bits, obj) != 0;
+ return RVALUE_MARKING_BITMAP(obj) != 0;
}
static inline int
@@ -1793,20 +1692,34 @@ RVALUE_UNCOLLECTIBLE(VALUE obj)
}
static inline int
+RVALUE_OLD_P_RAW(VALUE obj)
+{
+ const VALUE promoted = FL_PROMOTED0 | FL_PROMOTED1;
+ return (RBASIC(obj)->flags & promoted) == promoted;
+}
+
+static inline int
RVALUE_OLD_P(VALUE obj)
{
- GC_ASSERT(!RB_SPECIAL_CONST_P(obj));
check_rvalue_consistency(obj);
- // Because this will only ever be called on GC controlled objects,
- // we can use the faster _RAW function here
- return RB_OBJ_PROMOTED_RAW(obj);
+ return RVALUE_OLD_P_RAW(obj);
}
+#if RGENGC_CHECK_MODE || GC_DEBUG
+static inline int
+RVALUE_AGE(VALUE obj)
+{
+ check_rvalue_consistency(obj);
+ return RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
+}
+#endif
+
static inline void
RVALUE_PAGE_OLD_UNCOLLECTIBLE_SET(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
{
MARK_IN_BITMAP(&page->uncollectible_bits[0], obj);
objspace->rgengc.old_objects++;
+ rb_transient_heap_promote(obj);
#if RGENGC_PROFILE >= 2
objspace->profile.total_promoted_count++;
@@ -1821,39 +1734,64 @@ RVALUE_OLD_UNCOLLECTIBLE_SET(rb_objspace_t *objspace, VALUE obj)
RVALUE_PAGE_OLD_UNCOLLECTIBLE_SET(objspace, GET_HEAP_PAGE(obj), obj);
}
+static inline VALUE
+RVALUE_FLAGS_AGE_SET(VALUE flags, int age)
+{
+ flags &= ~(FL_PROMOTED0 | FL_PROMOTED1);
+ flags |= (age << RVALUE_AGE_SHIFT);
+ return flags;
+}
+
/* set age to age+1 */
static inline void
RVALUE_AGE_INC(rb_objspace_t *objspace, VALUE obj)
{
- int age = RVALUE_AGE_GET((VALUE)obj);
+ VALUE flags = RBASIC(obj)->flags;
+ int age = RVALUE_FLAGS_AGE(flags);
if (RGENGC_CHECK_MODE && age == RVALUE_OLD_AGE) {
rb_bug("RVALUE_AGE_INC: can not increment age of OLD object %s.", obj_info(obj));
}
age++;
- RVALUE_AGE_SET(obj, age);
+ RBASIC(obj)->flags = RVALUE_FLAGS_AGE_SET(flags, age);
if (age == RVALUE_OLD_AGE) {
RVALUE_OLD_UNCOLLECTIBLE_SET(objspace, obj);
}
+ check_rvalue_consistency(obj);
+}
+
+/* set age to RVALUE_OLD_AGE */
+static inline void
+RVALUE_AGE_SET_OLD(rb_objspace_t *objspace, VALUE obj)
+{
+ check_rvalue_consistency(obj);
+ GC_ASSERT(!RVALUE_OLD_P(obj));
+
+ RBASIC(obj)->flags = RVALUE_FLAGS_AGE_SET(RBASIC(obj)->flags, RVALUE_OLD_AGE);
+ RVALUE_OLD_UNCOLLECTIBLE_SET(objspace, obj);
check_rvalue_consistency(obj);
}
+/* set age to RVALUE_OLD_AGE - 1 */
static inline void
RVALUE_AGE_SET_CANDIDATE(rb_objspace_t *objspace, VALUE obj)
{
check_rvalue_consistency(obj);
GC_ASSERT(!RVALUE_OLD_P(obj));
- RVALUE_AGE_SET(obj, RVALUE_OLD_AGE - 1);
+
+ RBASIC(obj)->flags = RVALUE_FLAGS_AGE_SET(RBASIC(obj)->flags, RVALUE_OLD_AGE - 1);
+
check_rvalue_consistency(obj);
}
static inline void
-RVALUE_AGE_RESET(VALUE obj)
+RVALUE_DEMOTE_RAW(rb_objspace_t *objspace, VALUE obj)
{
- RVALUE_AGE_SET(obj, 0);
+ RBASIC(obj)->flags = RVALUE_FLAGS_AGE_SET(RBASIC(obj)->flags, 0);
+ CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS(obj), obj);
}
static inline void
@@ -1863,11 +1801,10 @@ RVALUE_DEMOTE(rb_objspace_t *objspace, VALUE obj)
GC_ASSERT(RVALUE_OLD_P(obj));
if (!is_incremental_marking(objspace) && RVALUE_REMEMBERED(obj)) {
- CLEAR_IN_BITMAP(GET_HEAP_PAGE(obj)->remembered_bits, obj);
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
}
- CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS(obj), obj);
- RVALUE_AGE_RESET(obj);
+ RVALUE_DEMOTE_RAW(objspace, obj);
if (RVALUE_MARKED(obj)) {
objspace->rgengc.old_objects--;
@@ -1876,6 +1813,22 @@ RVALUE_DEMOTE(rb_objspace_t *objspace, VALUE obj)
check_rvalue_consistency(obj);
}
+static inline void
+RVALUE_AGE_RESET_RAW(VALUE obj)
+{
+ RBASIC(obj)->flags = RVALUE_FLAGS_AGE_SET(RBASIC(obj)->flags, 0);
+}
+
+static inline void
+RVALUE_AGE_RESET(VALUE obj)
+{
+ check_rvalue_consistency(obj);
+ GC_ASSERT(!RVALUE_OLD_P(obj));
+
+ RVALUE_AGE_RESET_RAW(obj);
+ check_rvalue_consistency(obj);
+}
+
static inline int
RVALUE_BLACK_P(VALUE obj)
{
@@ -1912,10 +1865,6 @@ rb_objspace_alloc(void)
rb_objspace_t *objspace = calloc1(sizeof(rb_objspace_t));
objspace->flags.measure_gc = 1;
malloc_limit = gc_params.malloc_limit_min;
- objspace->finalize_deferred_pjob = rb_postponed_job_preregister(0, gc_finalize_deferred, objspace);
- if (objspace->finalize_deferred_pjob == POSTPONED_JOB_HANDLE_INVALID) {
- rb_bug("Could not preregister postponed job for GC");
- }
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
rb_size_pool_t *size_pool = &size_pools[i];
@@ -1926,8 +1875,6 @@ rb_objspace_alloc(void)
ccan_list_head_init(&SIZE_POOL_TOMB_HEAP(size_pool)->pages);
}
- rb_darray_make_without_gc(&objspace->weak_references, 0);
-
dont_gc_on();
return objspace;
@@ -1943,8 +1890,10 @@ rb_objspace_free(rb_objspace_t *objspace)
if (is_lazy_sweeping(objspace))
rb_bug("lazy sweeping underway when freeing object space");
- free(objspace->profile.records);
- objspace->profile.records = NULL;
+ if (objspace->profile.records) {
+ free(objspace->profile.records);
+ objspace->profile.records = 0;
+ }
if (global_list) {
struct gc_list *list, *next;
@@ -1955,8 +1904,7 @@ rb_objspace_free(rb_objspace_t *objspace)
}
if (heap_pages_sorted) {
size_t i;
- size_t total_heap_pages = heap_allocated_pages;
- for (i = 0; i < total_heap_pages; ++i) {
+ for (i = 0; i < heap_allocated_pages; ++i) {
heap_page_free(objspace, heap_pages_sorted[i]);
}
free(heap_pages_sorted);
@@ -1977,8 +1925,6 @@ rb_objspace_free(rb_objspace_t *objspace)
free_stack_chunks(&objspace->mark_stack);
mark_stack_free_cache(&objspace->mark_stack);
- rb_darray_free_without_gc(objspace->weak_references);
-
free(objspace);
}
@@ -2052,8 +1998,6 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj
page->freelist = p;
asan_lock_freelist(page);
- RVALUE_AGE_RESET(obj);
-
if (RGENGC_CHECK_MODE &&
/* obj should belong to page */
!(page->start <= (uintptr_t)obj &&
@@ -2081,6 +2025,7 @@ heap_add_freepage(rb_heap_t *heap, struct heap_page *page)
asan_lock_freelist(page);
}
+#if GC_ENABLE_INCREMENTAL_MARK
static inline void
heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
{
@@ -2094,6 +2039,7 @@ heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pa
asan_lock_freelist(page);
}
+#endif
static void
heap_unlink_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
@@ -2146,7 +2092,7 @@ heap_pages_free_unused_pages(rb_objspace_t *objspace)
}
if (has_pages_in_tomb_heap) {
- for (i = j = 0; j < heap_allocated_pages; i++) {
+ for (i = j = 1; j < heap_allocated_pages; i++) {
struct heap_page *page = heap_pages_sorted[i];
if (page->flags.in_tomb && page->free_slots == page->total_slots) {
@@ -2166,11 +2112,6 @@ heap_pages_free_unused_pages(rb_objspace_t *objspace)
GC_ASSERT(himem <= heap_pages_himem);
heap_pages_himem = himem;
- struct heap_page *lopage = heap_pages_sorted[0];
- uintptr_t lomem = (uintptr_t)lopage->start;
- GC_ASSERT(lomem >= heap_pages_lomem);
- heap_pages_lomem = lomem;
-
GC_ASSERT(j == heap_allocated_pages);
}
}
@@ -2382,7 +2323,6 @@ heap_assign_page(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *
heap_add_freepage(heap, page);
}
-#if GC_CAN_COMPILE_COMPACTION
static void
heap_add_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap, size_t add)
{
@@ -2396,26 +2336,6 @@ heap_add_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *he
GC_ASSERT(size_pool->allocatable_pages == 0);
}
-#endif
-
-static size_t
-slots_to_pages_for_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool, size_t slots)
-{
- size_t multiple = size_pool->slot_size / BASE_SLOT_SIZE;
- /* Due to alignment, heap pages may have one less slot. We should
- * ensure there is enough pages to guarantee that we will have at
- * least the required number of slots after allocating all the pages. */
- size_t slots_per_page = (HEAP_PAGE_OBJ_LIMIT / multiple) - 1;
- return CEILDIV(slots, slots_per_page);
-}
-
-static size_t
-minimum_pages_for_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
-{
- size_t size_pool_idx = size_pool - size_pools;
- size_t init_slots = gc_params.size_pool_init_slots[size_pool_idx];
- return slots_to_pages_for_size_pool(objspace, size_pool, init_slots);
-}
static size_t
heap_extend_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, size_t free_slots, size_t total_slots, size_t used)
@@ -2427,7 +2347,8 @@ heap_extend_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, size_t fre
next_used = (size_t)(used * gc_params.growth_factor);
}
else if (total_slots == 0) {
- next_used = minimum_pages_for_size_pool(objspace, size_pool);
+ int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
+ next_used = (gc_params.heap_init_slots * multiple) / HEAP_PAGE_OBJ_LIMIT;
}
else {
/* Find `f' where free_slots = f * total_slots * goal_ratio
@@ -2482,14 +2403,9 @@ heap_increment(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *he
static void
gc_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap)
{
- unsigned int lock_lev;
- gc_enter(objspace, gc_enter_event_continue, &lock_lev);
-
/* Continue marking if in incremental marking. */
- if (is_incremental_marking(objspace)) {
- if (gc_marks_continue(objspace, size_pool, heap)) {
- gc_sweep(objspace);
- }
+ if (heap->free_pages == NULL && is_incremental_marking(objspace)) {
+ gc_marks_continue(objspace, size_pool, heap);
}
/* Continue sweeping if in lazy sweeping or the previous incremental
@@ -2497,8 +2413,6 @@ gc_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap)
if (heap->free_pages == NULL && is_lazy_sweeping(objspace)) {
gc_sweep_continue(objspace, size_pool, heap);
}
-
- gc_exit(objspace, gc_enter_event_continue, &lock_lev);
}
static void
@@ -2554,17 +2468,23 @@ rb_objspace_set_event_hook(const rb_event_flag_t event)
{
rb_objspace_t *objspace = &rb_objspace;
objspace->hook_events = event & RUBY_INTERNAL_EVENT_OBJSPACE_MASK;
- objspace->flags.has_newobj_hook = !!(objspace->hook_events & RUBY_INTERNAL_EVENT_NEWOBJ);
+ objspace->flags.has_hook = (objspace->hook_events != 0);
}
static void
gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
{
if (UNLIKELY(!ec->cfp)) return;
+ const VALUE *pc = ec->cfp->pc;
+ if (pc && VM_FRAME_RUBYFRAME_P(ec->cfp)) {
+ /* increment PC because source line is calculated with PC-1 */
+ ec->cfp->pc++;
+ }
EXEC_EVENT_HOOK(ec, event, ec->cfp->self, 0, 0, 0, data);
+ ec->cfp->pc = pc;
}
-#define gc_event_newobj_hook_needed_p(objspace) ((objspace)->flags.has_newobj_hook)
+#define gc_event_hook_available_p(objspace) ((objspace)->flags.has_hook)
#define gc_event_hook_needed_p(objspace, event) ((objspace)->hook_events & (event))
#define gc_event_hook_prep(objspace, event, data, prep) do { \
@@ -2587,11 +2507,6 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
p->as.basic.flags = flags;
*((VALUE *)&p->as.basic.klass) = klass;
- int t = flags & RUBY_T_MASK;
- if (t == T_CLASS || t == T_MODULE || t == T_ICLASS) {
- RVALUE_AGE_SET_CANDIDATE(objspace, obj);
- }
-
#if RACTOR_CHECK_MODE
rb_ractor_setup_belonging(obj);
#endif
@@ -2608,7 +2523,13 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
GC_ASSERT(RVALUE_OLD_P(obj) == FALSE);
GC_ASSERT(RVALUE_WB_UNPROTECTED(obj) == FALSE);
- if (RVALUE_REMEMBERED((VALUE)obj)) rb_bug("newobj: %s is remembered.", obj_info(obj));
+ if (flags & FL_PROMOTED1) {
+ if (RVALUE_AGE(obj) != 2) rb_bug("newobj: %s of age (%d) != 2.", obj_info(obj), RVALUE_AGE(obj));
+ }
+ else {
+ if (RVALUE_AGE(obj) > 0) rb_bug("newobj: %s of age (%d) > 0.", obj_info(obj), RVALUE_AGE(obj));
+ }
+ if (rgengc_remembered(objspace, (VALUE)obj)) rb_bug("newobj: %s is remembered.", obj_info(obj));
}
RB_VM_LOCK_LEAVE_NO_BARRIER();
#endif
@@ -2618,6 +2539,9 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
}
+ // TODO: make it atomic, or ractor local
+ objspace->total_allocated_objects++;
+
#if RGENGC_PROFILE
if (wb_protected) {
objspace->profile.total_generated_normal_object_count++;
@@ -2640,6 +2564,24 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
gc_report(5, objspace, "newobj: %s\n", obj_info(obj));
+#if RGENGC_OLD_NEWOBJ_CHECK > 0
+ {
+ static int newobj_cnt = RGENGC_OLD_NEWOBJ_CHECK;
+
+ if (!is_incremental_marking(objspace) &&
+ flags & FL_WB_PROTECTED && /* do not promote WB unprotected objects */
+ ! RB_TYPE_P(obj, T_ARRAY)) { /* array.c assumes that allocated objects are new */
+ if (--newobj_cnt == 0) {
+ newobj_cnt = RGENGC_OLD_NEWOBJ_CHECK;
+
+ gc_mark_set(objspace, obj);
+ RVALUE_AGE_SET_OLD(objspace, obj);
+
+ rb_gc_writebarrier_remember(obj);
+ }
+ }
+ }
+#endif
// RUBY_DEBUG_LOG("obj:%p (%s)", (void *)obj, obj_type_name(obj));
return obj;
}
@@ -2686,6 +2628,7 @@ ractor_cache_allocate_slot(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *ca
rb_ractor_newobj_size_pool_cache_t *size_pool_cache = &cache->size_pool_caches[size_pool_idx];
RVALUE *p = size_pool_cache->freelist;
+#if GC_ENABLE_INCREMENTAL_MARK
if (is_incremental_marking(objspace)) {
// Not allowed to allocate without running an incremental marking step
if (cache->incremental_mark_step_allocated_slots >= INCREMENTAL_MARK_STEP_ALLOCATIONS) {
@@ -2696,12 +2639,17 @@ ractor_cache_allocate_slot(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *ca
cache->incremental_mark_step_allocated_slots++;
}
}
+#endif
if (p) {
VALUE obj = (VALUE)p;
MAYBE_UNUSED(const size_t) stride = size_pool_slot_size(size_pool_idx);
size_pool_cache->freelist = p->as.free.next;
+#if USE_RVARGC
asan_unpoison_memory_region(p, stride, true);
+#else
+ asan_unpoison_object(obj, true);
+#endif
#if RGENGC_CHECK_MODE
GC_ASSERT(rb_gc_obj_slot_size(obj) == stride);
// zero clear
@@ -2771,6 +2719,7 @@ newobj_fill(VALUE obj, VALUE v1, VALUE v2, VALUE v3)
static inline size_t
size_pool_idx_for_size(size_t size)
{
+#if USE_RVARGC
size += RVALUE_OVERHEAD;
size_t slot_count = CEILDIV(size, BASE_SLOT_SIZE);
@@ -2779,8 +2728,7 @@ size_pool_idx_for_size(size_t size)
size_t size_pool_idx = 64 - nlz_int64(slot_count - 1);
if (size_pool_idx >= SIZE_POOL_COUNT) {
- rb_bug("size_pool_idx_for_size: allocation size too large "
- "(size=%"PRIuSIZE"u, size_pool_idx=%"PRIuSIZE"u)", size, size_pool_idx);
+ rb_bug("size_pool_idx_for_size: allocation size too large");
}
#if RGENGC_CHECK_MODE
@@ -2790,6 +2738,10 @@ size_pool_idx_for_size(size_t size)
#endif
return size_pool_idx;
+#else
+ GC_ASSERT(size <= sizeof(RVALUE));
+ return 0;
+#endif
}
static VALUE
@@ -2814,13 +2766,15 @@ newobj_alloc(rb_objspace_t *objspace, rb_ractor_t *cr, size_t size_pool_idx, boo
{
ASSERT_vm_locking();
+#if GC_ENABLE_INCREMENTAL_MARK
if (is_incremental_marking(objspace)) {
- gc_continue(objspace, size_pool, heap);
+ gc_marks_continue(objspace, size_pool, heap);
cache->incremental_mark_step_allocated_slots = 0;
// Retry allocation after resetting incremental_mark_step_allocated_slots
obj = ractor_cache_allocate_slot(objspace, cache, size_pool_idx);
}
+#endif
if (obj == Qfalse) {
// Get next free page (possibly running GC)
@@ -2839,8 +2793,6 @@ newobj_alloc(rb_objspace_t *objspace, rb_ractor_t *cr, size_t size_pool_idx, boo
}
}
- size_pool->total_allocated_objects++;
-
return obj;
}
@@ -2875,6 +2827,9 @@ newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *
}
obj = newobj_alloc(objspace, cr, size_pool_idx, true);
+#if SHAPE_IN_BASIC_FLAGS
+ flags |= (VALUE)(size_pool_idx) << SHAPE_FLAG_SHIFT;
+#endif
newobj_init(klass, flags, wb_protected, objspace, obj);
gc_event_hook_prep(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj, newobj_zero_slot(obj));
@@ -2910,24 +2865,25 @@ newobj_of0(VALUE klass, VALUE flags, int wb_protected, rb_ractor_t *cr, size_t a
RB_DEBUG_COUNTER_INC(obj_newobj);
(void)RB_DEBUG_COUNTER_INC_IF(obj_newobj_wb_unprotected, !wb_protected);
+#if GC_DEBUG_STRESS_TO_CLASS
if (UNLIKELY(stress_to_class)) {
long i, cnt = RARRAY_LEN(stress_to_class);
for (i = 0; i < cnt; ++i) {
if (klass == RARRAY_AREF(stress_to_class, i)) rb_memerror();
}
}
+#endif
size_t size_pool_idx = size_pool_idx_for_size(alloc_size);
- if (SHAPE_IN_BASIC_FLAGS || (flags & RUBY_T_MASK) == T_OBJECT) {
- flags |= (VALUE)size_pool_idx << SHAPE_FLAG_SHIFT;
- }
-
if (!UNLIKELY(during_gc ||
ruby_gc_stressful ||
- gc_event_newobj_hook_needed_p(objspace)) &&
+ gc_event_hook_available_p(objspace)) &&
wb_protected) {
obj = newobj_alloc(objspace, cr, size_pool_idx, false);
+#if SHAPE_IN_BASIC_FLAGS
+ flags |= (VALUE)size_pool_idx << SHAPE_FLAG_SHIFT;
+#endif
newobj_init(klass, flags, wb_protected, objspace, obj);
}
else {
@@ -2942,7 +2898,14 @@ newobj_of0(VALUE klass, VALUE flags, int wb_protected, rb_ractor_t *cr, size_t a
}
static inline VALUE
-newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected, size_t alloc_size)
+newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected, size_t alloc_size)
+{
+ VALUE obj = newobj_of0(klass, flags, wb_protected, GET_RACTOR(), alloc_size);
+ return newobj_fill(obj, v1, v2, v3);
+}
+
+static inline VALUE
+newobj_of_cr(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected, size_t alloc_size)
{
VALUE obj = newobj_of0(klass, flags, wb_protected, cr, alloc_size);
return newobj_fill(obj, v1, v2, v3);
@@ -2952,14 +2915,21 @@ VALUE
rb_wb_unprotected_newobj_of(VALUE klass, VALUE flags, size_t size)
{
GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
- return newobj_of(GET_RACTOR(), klass, flags, 0, 0, 0, FALSE, size);
+ return newobj_of(klass, flags, 0, 0, 0, FALSE, size);
+}
+
+VALUE
+rb_wb_protected_newobj_of(VALUE klass, VALUE flags, size_t size)
+{
+ GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
+ return newobj_of(klass, flags, 0, 0, 0, TRUE, size);
}
VALUE
-rb_wb_protected_newobj_of(rb_execution_context_t *ec, VALUE klass, VALUE flags, size_t size)
+rb_ec_wb_protected_newobj_of(rb_execution_context_t *ec, VALUE klass, VALUE flags, size_t size)
{
GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
- return newobj_of(rb_ec_ractor_ptr(ec), klass, flags, 0, 0, 0, TRUE, size);
+ return newobj_of_cr(rb_ec_ractor_ptr(ec), klass, flags, 0, 0, 0, TRUE, size);
}
/* for compatibility */
@@ -2967,7 +2937,13 @@ rb_wb_protected_newobj_of(rb_execution_context_t *ec, VALUE klass, VALUE flags,
VALUE
rb_newobj(void)
{
- return newobj_of(GET_RACTOR(), 0, T_NONE, 0, 0, 0, FALSE, RVALUE_SIZE);
+ return newobj_of(0, T_NONE, 0, 0, 0, FALSE, RVALUE_SIZE);
+}
+
+static size_t
+rb_obj_embedded_size(uint32_t numiv)
+{
+ return offsetof(struct RObject, as.ary) + (sizeof(VALUE) * numiv);
}
static VALUE
@@ -2977,15 +2953,20 @@ rb_class_instance_allocate_internal(VALUE klass, VALUE flags, bool wb_protected)
GC_ASSERT(flags & ROBJECT_EMBED);
size_t size;
+#if USE_RVARGC
uint32_t index_tbl_num_entries = RCLASS_EXT(klass)->max_iv_count;
size = rb_obj_embedded_size(index_tbl_num_entries);
if (!rb_gc_size_allocatable_p(size)) {
size = sizeof(struct RObject);
}
+#else
+ size = sizeof(struct RObject);
+#endif
- VALUE obj = newobj_of(GET_RACTOR(), klass, flags, 0, 0, 0, wb_protected, size);
- RUBY_ASSERT(rb_shape_get_shape(obj)->type == SHAPE_ROOT);
+ VALUE obj = newobj_of(klass, flags, 0, 0, 0, wb_protected, size);
+ RUBY_ASSERT(rb_shape_get_shape(obj)->type == SHAPE_ROOT ||
+ rb_shape_get_shape(obj)->type == SHAPE_INITIAL_CAPACITY);
// Set the shape to the specific T_OBJECT shape which is always
// SIZE_POOL_COUNT away from the root shape.
@@ -3009,7 +2990,7 @@ rb_newobj_of(VALUE klass, VALUE flags)
return rb_class_instance_allocate_internal(klass, (flags | ROBJECT_EMBED) & ~FL_WB_PROTECTED, flags & FL_WB_PROTECTED);
}
else {
- return newobj_of(GET_RACTOR(), klass, flags & ~FL_WB_PROTECTED, 0, 0, 0, flags & FL_WB_PROTECTED, RVALUE_SIZE);
+ return newobj_of(klass, flags & ~FL_WB_PROTECTED, 0, 0, 0, flags & FL_WB_PROTECTED, RVALUE_SIZE);
}
}
@@ -3049,7 +3030,7 @@ rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
{
size_t size = RVALUE_SIZE;
VALUE flags = T_IMEMO | (type << FL_USHIFT);
- return newobj_of(GET_RACTOR(), v0, flags, v1, v2, v3, TRUE, size);
+ return newobj_of(v0, flags, v1, v2, v3, TRUE, size);
}
static VALUE
@@ -3057,7 +3038,7 @@ rb_imemo_tmpbuf_new(VALUE v1, VALUE v2, VALUE v3, VALUE v0)
{
size_t size = sizeof(struct rb_imemo_tmpbuf_struct);
VALUE flags = T_IMEMO | (imemo_tmpbuf << FL_USHIFT);
- return newobj_of(GET_RACTOR(), v0, flags, v1, v2, v3, FALSE, size);
+ return newobj_of(v0, flags, v1, v2, v3, FALSE, size);
}
static VALUE
@@ -3116,7 +3097,7 @@ rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0,
}
#endif
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_class_allocate_instance(VALUE klass)
{
return rb_class_instance_allocate_internal(klass, T_OBJECT | ROBJECT_EMBED, RGENGC_WB_PROTECTED_OBJECT);
@@ -3136,7 +3117,7 @@ rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FU
{
RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);
if (klass) rb_data_object_check(klass);
- return newobj_of(GET_RACTOR(), klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, !dmark, sizeof(struct RTypedData));
+ return newobj_of(klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, FALSE, sizeof(struct RTypedData));
}
VALUE
@@ -3147,42 +3128,18 @@ rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_
return obj;
}
-static VALUE
-typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_t *type, size_t size)
-{
- RBIMPL_NONNULL_ARG(type);
- if (klass) rb_data_object_check(klass);
- bool wb_protected = (type->flags & RUBY_FL_WB_PROTECTED) || !type->function.dmark;
- return newobj_of(GET_RACTOR(), klass, T_DATA, (VALUE)type, 1 | typed_flag, (VALUE)datap, wb_protected, size);
-}
-
VALUE
rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type)
{
- if (UNLIKELY(type->flags & RUBY_TYPED_EMBEDDABLE)) {
- rb_raise(rb_eTypeError, "Cannot wrap an embeddable TypedData");
- }
-
- return typed_data_alloc(klass, 0, datap, type, sizeof(struct RTypedData));
+ RBIMPL_NONNULL_ARG(type);
+ if (klass) rb_data_object_check(klass);
+ return newobj_of(klass, T_DATA, (VALUE)type, (VALUE)1, (VALUE)datap, type->flags & RUBY_FL_WB_PROTECTED, sizeof(struct RTypedData));
}
VALUE
rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type)
{
- if (type->flags & RUBY_TYPED_EMBEDDABLE) {
- if (!(type->flags & RUBY_TYPED_FREE_IMMEDIATELY)) {
- rb_raise(rb_eTypeError, "Embeddable TypedData must be freed immediately");
- }
-
- size_t embed_size = offsetof(struct RTypedData, data) + size;
- if (rb_gc_size_allocatable_p(embed_size)) {
- VALUE obj = typed_data_alloc(klass, TYPED_DATA_EMBEDDED, 0, type, embed_size);
- memset((char *)obj + offsetof(struct RTypedData, data), 0, size);
- return obj;
- }
- }
-
- VALUE obj = typed_data_alloc(klass, 0, NULL, type, sizeof(struct RTypedData));
+ VALUE obj = rb_data_typed_object_wrap(klass, 0, type);
DATA_PTR(obj) = xcalloc(1, size);
return obj;
}
@@ -3190,23 +3147,14 @@ rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type
size_t
rb_objspace_data_type_memsize(VALUE obj)
{
- size_t size = 0;
if (RTYPEDDATA_P(obj)) {
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
- const void *ptr = RTYPEDDATA_GET_DATA(obj);
-
- if (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_EMBEDDABLE && !RTYPEDDATA_EMBEDDED_P(obj)) {
-#ifdef HAVE_MALLOC_USABLE_SIZE
- size += malloc_usable_size((void *)ptr);
-#endif
- }
-
+ const void *ptr = RTYPEDDATA_DATA(obj);
if (ptr && type->function.dsize) {
- size += type->function.dsize(ptr);
+ return type->function.dsize(ptr);
}
}
-
- return size;
+ return 0;
}
const char *
@@ -3330,8 +3278,6 @@ vm_ccs_free(struct rb_class_cc_entries *ccs, int alive, rb_objspace_t *objspace,
asan_poison_object((VALUE)cc);
}
}
-
- VM_ASSERT(!vm_cc_super_p(cc) && !vm_cc_refinement_p(cc));
vm_cc_invalidate(cc);
}
ruby_xfree(ccs->entries);
@@ -3469,53 +3415,8 @@ obj_free_object_id(rb_objspace_t *objspace, VALUE obj)
st_delete(objspace->id_to_obj_tbl, &id, NULL);
}
else {
- rb_bug("Object ID seen, but not in mapping table: %s", obj_info(obj));
- }
-}
-
-static bool
-rb_data_free(rb_objspace_t *objspace, VALUE obj)
-{
- void *data = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
- if (data) {
- int free_immediately = false;
- void (*dfree)(void *);
-
- if (RTYPEDDATA_P(obj)) {
- free_immediately = (RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
- dfree = RANY(obj)->as.typeddata.type->function.dfree;
- }
- else {
- dfree = RANY(obj)->as.data.dfree;
- }
-
- if (dfree) {
- if (dfree == RUBY_DEFAULT_FREE) {
- if (!RTYPEDDATA_EMBEDDED_P(obj)) {
- xfree(data);
- RB_DEBUG_COUNTER_INC(obj_data_xfree);
- }
- }
- else if (free_immediately) {
- (*dfree)(data);
- if (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_EMBEDDABLE && !RTYPEDDATA_EMBEDDED_P(obj)) {
- xfree(data);
- }
-
- RB_DEBUG_COUNTER_INC(obj_data_imm_free);
- }
- else {
- make_zombie(objspace, obj, dfree, data);
- RB_DEBUG_COUNTER_INC(obj_data_zombie);
- return FALSE;
- }
- }
- else {
- RB_DEBUG_COUNTER_INC(obj_data_empty);
- }
+ rb_bug("Object ID seen, but not in mapping table: %s\n", obj_info(obj));
}
-
- return true;
}
static int
@@ -3566,6 +3467,9 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
else if (RANY(obj)->as.basic.flags & ROBJECT_EMBED) {
RB_DEBUG_COUNTER_INC(obj_obj_embed);
}
+ else if (ROBJ_TRANSIENT_P(obj)) {
+ RB_DEBUG_COUNTER_INC(obj_obj_transient);
+ }
else {
xfree(RANY(obj)->as.object.as.heap.ivptr);
RB_DEBUG_COUNTER_INC(obj_obj_ptr);
@@ -3575,13 +3479,9 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
case T_CLASS:
rb_id_table_free(RCLASS_M_TBL(obj));
cc_table_free(objspace, obj, FALSE);
- if (rb_shape_obj_too_complex(obj)) {
- st_free_table((st_table *)RCLASS_IVPTR(obj));
- }
- else if (RCLASS_IVPTR(obj)) {
+ if (RCLASS_IVPTR(obj)) {
xfree(RCLASS_IVPTR(obj));
}
-
if (RCLASS_CONST_TBL(obj)) {
rb_free_const_table(RCLASS_CONST_TBL(obj));
}
@@ -3596,6 +3496,11 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
xfree(RCLASS_SUPERCLASSES(obj));
}
+#if SIZE_POOL_COUNT == 1
+ if (RCLASS_EXT(obj))
+ xfree(RCLASS_EXT(obj));
+#endif
+
(void)RB_DEBUG_COUNTER_INC_IF(obj_module_ptr, BUILTIN_TYPE(obj) == T_MODULE);
(void)RB_DEBUG_COUNTER_INC_IF(obj_class_ptr, BUILTIN_TYPE(obj) == T_CLASS);
break;
@@ -3646,8 +3551,22 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
RB_DEBUG_COUNTER_INC(obj_hash_st);
}
#endif
+ if (/* RHASH_AR_TABLE_P(obj) */ !FL_TEST_RAW(obj, RHASH_ST_TABLE_FLAG)) {
+ struct ar_table_struct *tab = RHASH(obj)->as.ar;
- rb_hash_free(obj);
+ if (tab) {
+ if (RHASH_TRANSIENT_P(obj)) {
+ RB_DEBUG_COUNTER_INC(obj_hash_transient);
+ }
+ else {
+ ruby_xfree(tab);
+ }
+ }
+ }
+ else {
+ GC_ASSERT(RHASH_ST_TABLE_P(obj));
+ st_free_table(RHASH(obj)->as.st);
+ }
break;
case T_REGEXP:
if (RANY(obj)->as.regexp.ptr) {
@@ -3656,11 +3575,46 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
}
break;
case T_DATA:
- if (!rb_data_free(objspace, obj)) return false;
+ if (DATA_PTR(obj)) {
+ int free_immediately = FALSE;
+ void (*dfree)(void *);
+ void *data = DATA_PTR(obj);
+
+ if (RTYPEDDATA_P(obj)) {
+ free_immediately = (RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
+ dfree = RANY(obj)->as.typeddata.type->function.dfree;
+ if (0 && free_immediately == 0) {
+ /* to expose non-free-immediate T_DATA */
+ fprintf(stderr, "not immediate -> %s\n", RANY(obj)->as.typeddata.type->wrap_struct_name);
+ }
+ }
+ else {
+ dfree = RANY(obj)->as.data.dfree;
+ }
+
+ if (dfree) {
+ if (dfree == RUBY_DEFAULT_FREE) {
+ xfree(data);
+ RB_DEBUG_COUNTER_INC(obj_data_xfree);
+ }
+ else if (free_immediately) {
+ (*dfree)(data);
+ RB_DEBUG_COUNTER_INC(obj_data_imm_free);
+ }
+ else {
+ make_zombie(objspace, obj, dfree, data);
+ RB_DEBUG_COUNTER_INC(obj_data_zombie);
+ return FALSE;
+ }
+ }
+ else {
+ RB_DEBUG_COUNTER_INC(obj_data_empty);
+ }
+ }
break;
case T_MATCH:
- {
- rb_matchext_t *rm = RMATCH_EXT(obj);
+ if (RANY(obj)->as.match.rmatch) {
+ struct rmatch *rm = RANY(obj)->as.match.rmatch;
#if USE_DEBUG_COUNTER
if (rm->regs.num_regs >= 8) {
RB_DEBUG_COUNTER_INC(obj_match_ge8);
@@ -3675,6 +3629,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
onig_region_free(&rm->regs, 0);
if (rm->char_offset)
xfree(rm->char_offset);
+ xfree(rm);
RB_DEBUG_COUNTER_INC(obj_match_ptr);
}
@@ -3707,6 +3662,9 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
cc_table_free(objspace, obj, FALSE);
rb_class_remove_from_module_subclasses(obj);
rb_class_remove_from_super_subclasses(obj);
+#if !RCLASS_EXT_EMBEDDED
+ xfree(RCLASS_EXT(obj));
+#endif
RB_DEBUG_COUNTER_INC(obj_iclass_ptr);
break;
@@ -3734,6 +3692,9 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
RANY(obj)->as.rstruct.as.heap.ptr == NULL) {
RB_DEBUG_COUNTER_INC(obj_struct_embed);
}
+ else if (RSTRUCT_TRANSIENT_P(obj)) {
+ RB_DEBUG_COUNTER_INC(obj_struct_transient);
+ }
else {
xfree((void *)RANY(obj)->as.rstruct.as.heap.ptr);
RB_DEBUG_COUNTER_INC(obj_struct_ptr);
@@ -3789,16 +3750,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
RB_DEBUG_COUNTER_INC(obj_imemo_parser_strterm);
break;
case imemo_callinfo:
- {
- const struct rb_callinfo * ci = ((const struct rb_callinfo *)obj);
- rb_vm_ci_free(ci);
- if (ci->kwarg) {
- ((struct rb_callinfo_kwarg *)ci->kwarg)->references--;
- if (ci->kwarg->references == 0) xfree((void *)ci->kwarg);
- }
- RB_DEBUG_COUNTER_INC(obj_imemo_callinfo);
- break;
- }
+ RB_DEBUG_COUNTER_INC(obj_imemo_callinfo);
+ break;
case imemo_callcache:
RB_DEBUG_COUNTER_INC(obj_imemo_callcache);
break;
@@ -3870,14 +3823,13 @@ Init_heap(void)
objspace->rgengc.oldmalloc_increase_limit = gc_params.oldmalloc_limit_min;
#endif
- /* Set size pools allocatable pages. */
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
-
- /* Set the default value of size_pool_init_slots. */
- gc_params.size_pool_init_slots[i] = GC_HEAP_INIT_SLOTS;
+ heap_add_pages(objspace, &size_pools[0], SIZE_POOL_EDEN_HEAP(&size_pools[0]), gc_params.heap_init_slots / HEAP_PAGE_OBJ_LIMIT);
- size_pool->allocatable_pages = minimum_pages_for_size_pool(objspace, size_pool);
+ /* Give other size pools allocatable pages. */
+ for (int i = 1; i < SIZE_POOL_COUNT; i++) {
+ rb_size_pool_t *size_pool = &size_pools[i];
+ int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
+ size_pool->allocatable_pages = gc_params.heap_init_slots * multiple / HEAP_PAGE_OBJ_LIMIT;
}
heap_pages_expand_sorted(objspace);
@@ -3896,7 +3848,6 @@ Init_gc_stress(void)
}
typedef int each_obj_callback(void *, void *, size_t, void *);
-typedef int each_page_callback(struct heap_page *, void *);
static void objspace_each_objects(rb_objspace_t *objspace, each_obj_callback *callback, void *data, bool protected);
static void objspace_reachable_objects_from_root(rb_objspace_t *, void (func)(const char *, VALUE, void *), void *);
@@ -3905,8 +3856,7 @@ struct each_obj_data {
rb_objspace_t *objspace;
bool reenable_incremental;
- each_obj_callback *each_obj_callback;
- each_page_callback *each_page_callback;
+ each_obj_callback *callback;
void *data;
struct heap_page **pages[SIZE_POOL_COUNT];
@@ -3926,7 +3876,11 @@ objspace_each_objects_ensure(VALUE arg)
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
struct heap_page **pages = data->pages[i];
- free(pages);
+ /* pages could be NULL if an error was raised during setup (e.g.
+ * malloc failed due to out of memory). */
+ if (pages) {
+ free(pages);
+ }
}
return Qnil;
@@ -3980,15 +3934,9 @@ objspace_each_objects_try(VALUE arg)
uintptr_t pstart = (uintptr_t)page->start;
uintptr_t pend = pstart + (page->total_slots * size_pool->slot_size);
- if (!__asan_region_is_poisoned((void *)pstart, pend - pstart)) {
- if (data->each_obj_callback &&
- (*data->each_obj_callback)((void *)pstart, (void *)pend, size_pool->slot_size, data->data)) {
- break;
- }
- if (data->each_page_callback &&
- (*data->each_page_callback)(page, data->data)) {
- break;
- }
+ if (!__asan_region_is_poisoned((void *)pstart, pend - pstart) &&
+ (*data->callback)((void *)pstart, (void *)pend, size_pool->slot_size, data->data)) {
+ break;
}
page = ccan_list_next(&SIZE_POOL_EDEN_HEAP(size_pool)->pages, page, page_node);
@@ -4014,16 +3962,14 @@ objspace_each_objects_try(VALUE arg)
*
* This is a sample callback code to iterate liveness objects:
*
- * static int
- * sample_callback(void *vstart, void *vend, int stride, void *data)
- * {
- * VALUE v = (VALUE)vstart;
- * for (; v != (VALUE)vend; v += stride) {
- * if (!rb_objspace_internal_object_p(v)) { // liveness check
- * // do something with live object 'v'
- * }
- * }
- * return 0; // continue to iteration
+ * int
+ * sample_callback(void *vstart, void *vend, int stride, void *data) {
+ * VALUE v = (VALUE)vstart;
+ * for (; v != (VALUE)vend; v += stride) {
+ * if (RBASIC(v)->flags) { // liveness check
+ * // do something with live object 'v'
+ * }
+ * return 0; // continue to iteration
* }
*
* Note: 'vstart' is not a top of heap_page. This point the first
@@ -4043,10 +3989,9 @@ rb_objspace_each_objects(each_obj_callback *callback, void *data)
}
static void
-objspace_each_exec(bool protected, struct each_obj_data *each_obj_data)
+objspace_each_objects(rb_objspace_t *objspace, each_obj_callback *callback, void *data, bool protected)
{
/* Disable incremental GC */
- rb_objspace_t *objspace = each_obj_data->objspace;
bool reenable_incremental = FALSE;
if (protected) {
reenable_incremental = !objspace->flags.dont_incremental;
@@ -4055,35 +4000,18 @@ objspace_each_exec(bool protected, struct each_obj_data *each_obj_data)
objspace->flags.dont_incremental = TRUE;
}
- each_obj_data->reenable_incremental = reenable_incremental;
- memset(&each_obj_data->pages, 0, sizeof(each_obj_data->pages));
- memset(&each_obj_data->pages_counts, 0, sizeof(each_obj_data->pages_counts));
- rb_ensure(objspace_each_objects_try, (VALUE)each_obj_data,
- objspace_each_objects_ensure, (VALUE)each_obj_data);
-}
-
-static void
-objspace_each_objects(rb_objspace_t *objspace, each_obj_callback *callback, void *data, bool protected)
-{
struct each_obj_data each_obj_data = {
.objspace = objspace,
- .each_obj_callback = callback,
- .each_page_callback = NULL,
- .data = data,
- };
- objspace_each_exec(protected, &each_obj_data);
-}
+ .reenable_incremental = reenable_incremental,
-static void
-objspace_each_pages(rb_objspace_t *objspace, each_page_callback *callback, void *data, bool protected)
-{
- struct each_obj_data each_obj_data = {
- .objspace = objspace,
- .each_obj_callback = NULL,
- .each_page_callback = callback,
+ .callback = callback,
.data = data,
+
+ .pages = {NULL},
+ .pages_counts = {0},
};
- objspace_each_exec(protected, &each_obj_data);
+ rb_ensure(objspace_each_objects_try, (VALUE)&each_obj_data,
+ objspace_each_objects_ensure, (VALUE)&each_obj_data);
}
void
@@ -4259,45 +4187,6 @@ should_be_finalizable(VALUE obj)
rb_check_frozen(obj);
}
-VALUE
-rb_define_finalizer_no_check(VALUE obj, VALUE block)
-{
- rb_objspace_t *objspace = &rb_objspace;
- VALUE table;
- st_data_t data;
-
- RBASIC(obj)->flags |= FL_FINALIZE;
-
- if (st_lookup(finalizer_table, obj, &data)) {
- table = (VALUE)data;
-
- /* avoid duplicate block, table is usually small */
- {
- long len = RARRAY_LEN(table);
- long i;
-
- for (i = 0; i < len; i++) {
- VALUE recv = RARRAY_AREF(table, i);
- if (rb_equal(recv, block)) {
- block = recv;
- goto end;
- }
- }
- }
-
- rb_ary_push(table, block);
- }
- else {
- table = rb_ary_new3(1, block);
- RBASIC_CLEAR_CLASS(table);
- st_add_direct(finalizer_table, obj, table);
- }
- end:
- block = rb_ary_new3(2, INT2FIX(0), block);
- OBJ_FREEZE(block);
- return block;
-}
-
/*
* call-seq:
* ObjectSpace.define_finalizer(obj, aProc=proc())
@@ -4378,7 +4267,46 @@ define_final(int argc, VALUE *argv, VALUE os)
rb_warn("finalizer references object to be finalized");
}
- return rb_define_finalizer_no_check(obj, block);
+ return define_final0(obj, block);
+}
+
+static VALUE
+define_final0(VALUE obj, VALUE block)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+ VALUE table;
+ st_data_t data;
+
+ RBASIC(obj)->flags |= FL_FINALIZE;
+
+ if (st_lookup(finalizer_table, obj, &data)) {
+ table = (VALUE)data;
+
+ /* avoid duplicate block, table is usually small */
+ {
+ long len = RARRAY_LEN(table);
+ long i;
+
+ for (i = 0; i < len; i++) {
+ VALUE recv = RARRAY_AREF(table, i);
+ if (rb_equal(recv, block)) {
+ block = recv;
+ goto end;
+ }
+ }
+ }
+
+ rb_ary_push(table, block);
+ }
+ else {
+ table = rb_ary_new3(1, block);
+ RBASIC_CLEAR_CLASS(table);
+ st_add_direct(finalizer_table, obj, table);
+ }
+ end:
+ block = rb_ary_new3(2, INT2FIX(0), block);
+ OBJ_FREEZE(block);
+ return block;
}
VALUE
@@ -4386,7 +4314,7 @@ rb_define_finalizer(VALUE obj, VALUE block)
{
should_be_finalizable(obj);
should_be_callable(block);
- return rb_define_finalizer_no_check(obj, block);
+ return define_final0(obj, block);
}
void
@@ -4503,7 +4431,7 @@ finalize_list(rb_objspace_t *objspace, VALUE zombie)
page->final_slots--;
page->free_slots++;
heap_page_add_freeobj(objspace, page, zombie);
- page->size_pool->total_freed_objects++;
+ objspace->profile.total_freed_objects++;
}
RB_VM_LOCK_LEAVE();
@@ -4542,44 +4470,9 @@ gc_finalize_deferred(void *dmy)
static void
gc_finalize_deferred_register(rb_objspace_t *objspace)
{
- /* will enqueue a call to gc_finalize_deferred */
- rb_postponed_job_trigger(objspace->finalize_deferred_pjob);
-}
-
-static int pop_mark_stack(mark_stack_t *stack, VALUE *data);
-
-static void
-gc_abort(rb_objspace_t *objspace)
-{
- if (is_incremental_marking(objspace)) {
- /* Remove all objects from the mark stack. */
- VALUE obj;
- while (pop_mark_stack(&objspace->mark_stack, &obj));
-
- objspace->flags.during_incremental_marking = FALSE;
+ if (rb_postponed_job_register_one(0, gc_finalize_deferred, objspace) == 0) {
+ rb_bug("gc_finalize_deferred_register: can't register finalizer.");
}
-
- if (is_lazy_sweeping(objspace)) {
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
- rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
-
- heap->sweeping_page = NULL;
- struct heap_page *page = NULL;
-
- ccan_list_for_each(&heap->pages, page, page_node) {
- page->flags.before_sweep = false;
- }
- }
- }
-
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
- rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
- rgengc_mark_and_rememberset_clear(objspace, heap);
- }
-
- gc_mode_set(objspace, gc_mode_none);
}
struct force_finalize_list {
@@ -4603,35 +4496,6 @@ force_chain_object(st_data_t key, st_data_t val, st_data_t arg)
bool rb_obj_is_main_ractor(VALUE gv);
void
-rb_objspace_free_objects(rb_objspace_t *objspace)
-{
- for (size_t i = 0; i < heap_allocated_pages; i++) {
- struct heap_page *page = heap_pages_sorted[i];
- short stride = page->slot_size;
-
- uintptr_t p = (uintptr_t)page->start;
- uintptr_t pend = p + page->total_slots * stride;
- for (; p < pend; p += stride) {
- VALUE vp = (VALUE)p;
- switch (BUILTIN_TYPE(vp)) {
- case T_DATA: {
- if (rb_obj_is_mutex(vp) || rb_obj_is_thread(vp) || rb_obj_is_main_ractor(vp)) {
- obj_free(objspace, vp);
- }
- break;
- }
- case T_ARRAY:
- obj_free(objspace, vp);
- break;
- default:
- break;
- }
- }
- }
-}
-
-
-void
rb_objspace_call_finalizer(rb_objspace_t *objspace)
{
size_t i;
@@ -4639,12 +4503,15 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
#if RGENGC_CHECK_MODE >= 2
gc_verify_internal_consistency(objspace);
#endif
+ gc_rest(objspace);
+
if (ATOMIC_EXCHANGE(finalizing, 1)) return;
/* run finalizers */
finalize_deferred(objspace);
GC_ASSERT(heap_pages_deferred_final == 0);
+ gc_rest(objspace);
/* prohibit incremental GC */
objspace->flags.dont_incremental = 1;
@@ -4662,9 +4529,6 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
}
}
- /* Abort incremental marking and lazy sweeping to speed up shutdown. */
- gc_abort(objspace);
-
/* prohibit GC because force T_DATA finalizers can break an object graph consistency */
dont_gc_on();
@@ -4689,20 +4553,23 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
if (rb_obj_is_mutex(vp)) break;
if (rb_obj_is_fiber(vp)) break;
if (rb_obj_is_main_ractor(vp)) break;
-
- obj_free(objspace, vp);
+ if (RTYPEDDATA_P(vp)) {
+ RDATA(p)->dfree = RANY(p)->as.typeddata.type->function.dfree;
+ }
+ RANY(p)->as.free.flags = 0;
+ if (RANY(p)->as.data.dfree == RUBY_DEFAULT_FREE) {
+ xfree(DATA_PTR(p));
+ }
+ else if (RANY(p)->as.data.dfree) {
+ make_zombie(objspace, vp, RANY(p)->as.data.dfree, RANY(p)->as.data.data);
+ }
break;
case T_FILE:
- obj_free(objspace, vp);
- break;
- case T_SYMBOL:
- case T_ARRAY:
- case T_NONE:
+ if (RANY(p)->as.file.fptr) {
+ make_io_zombie(objspace, vp);
+ }
break;
default:
- if (rb_free_at_exit) {
- obj_free(objspace, vp);
- }
break;
}
if (poisoned) {
@@ -4722,7 +4589,7 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
}
static inline int
-is_swept_object(VALUE ptr)
+is_swept_object(rb_objspace_t *objspace, VALUE ptr)
{
struct heap_page *page = GET_HEAP_PAGE(ptr);
return page->flags.before_sweep ? FALSE : TRUE;
@@ -4733,7 +4600,7 @@ static inline int
is_garbage_object(rb_objspace_t *objspace, VALUE ptr)
{
if (!is_lazy_sweeping(objspace) ||
- is_swept_object(ptr) ||
+ is_swept_object(objspace, ptr) ||
MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(ptr), ptr)) {
return FALSE;
@@ -4764,7 +4631,7 @@ is_live_object(rb_objspace_t *objspace, VALUE ptr)
}
static inline int
-is_markable_object(VALUE obj)
+is_markable_object(rb_objspace_t *objspace, VALUE obj)
{
if (rb_special_const_p(obj)) return FALSE; /* special const is not markable */
check_rvalue_consistency(obj);
@@ -4775,7 +4642,7 @@ int
rb_objspace_markable_object_p(VALUE obj)
{
rb_objspace_t *objspace = &rb_objspace;
- return is_markable_object(obj) && is_live_object(objspace, obj);
+ return is_markable_object(objspace, obj) && is_live_object(objspace, obj);
}
int
@@ -4785,18 +4652,9 @@ rb_objspace_garbage_object_p(VALUE obj)
return is_garbage_object(objspace, obj);
}
-bool
-rb_gc_is_ptr_to_obj(void *ptr)
-{
- rb_objspace_t *objspace = &rb_objspace;
- return is_pointer_to_heap(objspace, ptr);
-}
-
-VALUE
-rb_gc_id2ref_obj_tbl(VALUE objid)
+static VALUE
+id2ref_obj_tbl(rb_objspace_t *objspace, VALUE objid)
{
- rb_objspace_t *objspace = &rb_objspace;
-
VALUE orig;
if (st_lookup(objspace->id_to_obj_tbl, objid, &orig)) {
return orig;
@@ -4853,7 +4711,7 @@ id2ref(VALUE objid)
}
}
- if (!UNDEF_P(orig = rb_gc_id2ref_obj_tbl(objid)) &&
+ if (!UNDEF_P(orig = id2ref_obj_tbl(objspace, objid)) &&
is_live_object(objspace, orig)) {
if (!rb_multi_ractor_p() || rb_ractor_shareable_p(orig)) {
@@ -4927,21 +4785,16 @@ cached_object_id(VALUE obj)
}
static VALUE
-nonspecial_obj_id(VALUE obj)
+nonspecial_obj_id_(VALUE obj)
{
-#if SIZEOF_LONG == SIZEOF_VOIDP
- return (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG);
-#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
- return LL2NUM((SIGNED_VALUE)(obj) / 2);
-#else
-# error not supported
-#endif
+ return nonspecial_obj_id(obj);
}
+
VALUE
rb_memory_id(VALUE obj)
{
- return rb_find_object_id(obj, nonspecial_obj_id);
+ return rb_find_object_id(obj, nonspecial_obj_id_);
}
/*
@@ -5048,22 +4901,27 @@ obj_memsize_of(VALUE obj, int use_all_types)
break;
case T_MODULE:
case T_CLASS:
- if (RCLASS_M_TBL(obj)) {
- size += rb_id_table_memsize(RCLASS_M_TBL(obj));
- }
- // class IV sizes are allocated as powers of two
- size += SIZEOF_VALUE << bit_length(RCLASS_IV_COUNT(obj));
- if (RCLASS_CVC_TBL(obj)) {
- size += rb_id_table_memsize(RCLASS_CVC_TBL(obj));
- }
- if (RCLASS_EXT(obj)->const_tbl) {
- size += rb_id_table_memsize(RCLASS_EXT(obj)->const_tbl);
- }
- if (RCLASS_CC_TBL(obj)) {
- size += cc_table_memsize(RCLASS_CC_TBL(obj));
- }
- if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
- size += (RCLASS_SUPERCLASS_DEPTH(obj) + 1) * sizeof(VALUE);
+ if (RCLASS_EXT(obj)) {
+ if (RCLASS_M_TBL(obj)) {
+ size += rb_id_table_memsize(RCLASS_M_TBL(obj));
+ }
+ // class IV sizes are allocated as powers of two
+ size += SIZEOF_VALUE << bit_length(RCLASS_IV_COUNT(obj));
+ if (RCLASS_CVC_TBL(obj)) {
+ size += rb_id_table_memsize(RCLASS_CVC_TBL(obj));
+ }
+ if (RCLASS_EXT(obj)->const_tbl) {
+ size += rb_id_table_memsize(RCLASS_EXT(obj)->const_tbl);
+ }
+ if (RCLASS_CC_TBL(obj)) {
+ size += cc_table_memsize(RCLASS_CC_TBL(obj));
+ }
+ if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
+ size += (RCLASS_SUPERCLASS_DEPTH(obj) + 1) * sizeof(VALUE);
+ }
+#if SIZE_POOL_COUNT == 1
+ size += sizeof(rb_classext_t);
+#endif
}
break;
case T_ICLASS:
@@ -5072,7 +4930,7 @@ obj_memsize_of(VALUE obj, int use_all_types)
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
}
}
- if (RCLASS_CC_TBL(obj)) {
+ if (RCLASS_EXT(obj) && RCLASS_CC_TBL(obj)) {
size += cc_table_memsize(RCLASS_CC_TBL(obj));
}
break;
@@ -5083,10 +4941,15 @@ obj_memsize_of(VALUE obj, int use_all_types)
size += rb_ary_memsize(obj);
break;
case T_HASH:
- if (RHASH_ST_TABLE_P(obj)) {
+ if (RHASH_AR_TABLE_P(obj)) {
+ if (RHASH_AR_TABLE(obj) != NULL) {
+ size_t rb_hash_ar_table_size(void);
+ size += rb_hash_ar_table_size();
+ }
+ }
+ else {
VM_ASSERT(RHASH_ST_TABLE(obj) != NULL);
- /* st_table is in the slot */
- size += st_memsize(RHASH_ST_TABLE(obj)) - sizeof(st_table);
+ size += st_memsize(RHASH_ST_TABLE(obj));
}
break;
case T_REGEXP:
@@ -5098,10 +4961,11 @@ obj_memsize_of(VALUE obj, int use_all_types)
if (use_all_types) size += rb_objspace_data_type_memsize(obj);
break;
case T_MATCH:
- {
- rb_matchext_t *rm = RMATCH_EXT(obj);
+ if (RMATCH(obj)->rmatch) {
+ struct rmatch *rm = RMATCH(obj)->rmatch;
size += onig_region_memsize(&rm->regs);
size += sizeof(struct rmatch_offset) * rm->char_offset_num_allocated;
+ size += sizeof(struct rmatch);
}
break;
case T_FILE:
@@ -5320,7 +5184,7 @@ objspace_available_slots(rb_objspace_t *objspace)
static size_t
objspace_live_slots(rb_objspace_t *objspace)
{
- return total_allocated_objects(objspace) - total_freed_objects(objspace) - heap_pages_final_slots;
+ return (objspace->total_allocated_objects - objspace->profile.total_freed_objects) - heap_pages_final_slots;
}
static size_t
@@ -5399,9 +5263,7 @@ try_move(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *free_page,
* full */
return false;
}
- asan_unlock_freelist(free_page);
free_page->freelist = RANY(dest)->as.free.next;
- asan_lock_freelist(free_page);
GC_ASSERT(RB_BUILTIN_TYPE(dest) == T_NONE);
@@ -5433,8 +5295,14 @@ gc_unprotect_pages(rb_objspace_t *objspace, rb_heap_t *heap)
}
static void gc_update_references(rb_objspace_t * objspace);
-#if GC_CAN_COMPILE_COMPACTION
static void invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page);
+
+#ifndef GC_CAN_COMPILE_COMPACTION
+#if defined(__wasi__) /* WebAssembly doesn't support signals */
+# define GC_CAN_COMPILE_COMPACTION 0
+#else
+# define GC_CAN_COMPILE_COMPACTION 1
+#endif
#endif
#if defined(__MINGW32__) || defined(_WIN32)
@@ -5620,6 +5488,45 @@ install_handlers(void)
#endif
static void
+revert_stack_objects(VALUE stack_obj, void *ctx)
+{
+ rb_objspace_t * objspace = (rb_objspace_t*)ctx;
+
+ if (BUILTIN_TYPE(stack_obj) == T_MOVED) {
+ /* For now we'll revert the whole page if the object made it to the
+ * stack. I think we can change this to move just the one object
+ * back though */
+ invalidate_moved_page(objspace, GET_HEAP_PAGE(stack_obj));
+ }
+}
+
+static void
+revert_machine_stack_references(rb_objspace_t *objspace, VALUE v)
+{
+ if (is_pointer_to_heap(objspace, (void *)v)) {
+ if (BUILTIN_TYPE(v) == T_MOVED) {
+ /* For now we'll revert the whole page if the object made it to the
+ * stack. I think we can change this to move just the one object
+ * back though */
+ invalidate_moved_page(objspace, GET_HEAP_PAGE(v));
+ }
+ }
+}
+
+static void each_machine_stack_value(const rb_execution_context_t *ec, void (*cb)(rb_objspace_t *, VALUE));
+
+static void
+check_stack_for_moved(rb_objspace_t *objspace)
+{
+ rb_execution_context_t *ec = GET_EC();
+ rb_vm_t *vm = rb_ec_vm_ptr(ec);
+ rb_vm_each_stack_value(vm, revert_stack_objects, (void*)objspace);
+ each_machine_stack_value(ec, revert_machine_stack_references);
+}
+
+static void gc_mode_transition(rb_objspace_t *objspace, enum gc_mode mode);
+
+static void
gc_compact_finish(rb_objspace_t *objspace)
{
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
@@ -5630,6 +5537,13 @@ gc_compact_finish(rb_objspace_t *objspace)
uninstall_handlers();
+ /* The mutator is allowed to run during incremental sweeping. T_MOVED
+ * objects can get pushed on the stack and when the compaction process
+ * finishes up, it may remove the read barrier before anything has a
+ * chance to read from the T_MOVED address. To fix this, we scan the stack
+ * then revert any moved objects that made it to the stack. */
+ check_stack_for_moved(objspace);
+
gc_update_references(objspace);
objspace->profile.compact_count++;
@@ -5675,7 +5589,7 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit
#if RGENGC_CHECK_MODE
if (!is_full_marking(objspace)) {
if (RVALUE_OLD_P(vp)) rb_bug("page_sweep: %p - old while minor GC.", (void *)p);
- if (RVALUE_REMEMBERED(vp)) rb_bug("page_sweep: %p - remembered.", (void *)p);
+ if (rgengc_remembered_sweep(objspace, vp)) rb_bug("page_sweep: %p - remembered.", (void *)p);
}
#endif
if (obj_free(objspace, vp)) {
@@ -5698,7 +5612,7 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit
* The sweep cursor and compact cursor move in
* opposite directions, and when they meet references will
* get updated and "during_compacting" should get disabled */
- rb_bug("T_MOVED shouldn't be seen until compaction is finished");
+ rb_bug("T_MOVED shouldn't be seen until compaction is finished\n");
}
gc_report(3, objspace, "page_sweep: %s is added to freelist\n", obj_info(vp));
ctx->empty_slots++;
@@ -5785,7 +5699,7 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
ctx->freed_slots, ctx->empty_slots, ctx->final_slots);
sweep_page->free_slots += ctx->freed_slots + ctx->empty_slots;
- sweep_page->size_pool->total_freed_objects += ctx->freed_slots;
+ objspace->profile.total_freed_objects += ctx->freed_slots;
if (heap_pages_deferred_final && !finalizing) {
rb_thread_t *th = GET_THREAD();
@@ -5811,6 +5725,23 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
gc_report(2, objspace, "page_sweep: end.\n");
}
+#if !USE_RVARGC
+/* allocate additional minimum page to work */
+static void
+gc_heap_prepare_minimum_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap)
+{
+ for (int i = 0; i < SIZE_POOL_COUNT; i++) {
+ if (!heap->free_pages && heap_increment(objspace, size_pool, heap) == FALSE) {
+ /* there is no free after page_sweep() */
+ size_pool_allocatable_pages_set(objspace, size_pool, 1);
+ if (!heap_increment(objspace, size_pool, heap)) { /* can't allocate additional free objects */
+ rb_memerror();
+ }
+ }
+ }
+}
+#endif
+
static const char *
gc_mode_name(enum gc_mode mode)
{
@@ -5868,7 +5799,9 @@ gc_sweep_start_heap(rb_objspace_t *objspace, rb_heap_t *heap)
{
heap->sweeping_page = ccan_list_top(&heap->pages, struct heap_page, page_node);
heap->free_pages = NULL;
+#if GC_ENABLE_INCREMENTAL_MARK
heap->pooled_pages = NULL;
+#endif
if (!objspace->flags.immediate_sweep) {
struct heap_page *page = NULL;
@@ -5881,25 +5814,13 @@ gc_sweep_start_heap(rb_objspace_t *objspace, rb_heap_t *heap)
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
__attribute__((noinline))
#endif
-
-#if GC_CAN_COMPILE_COMPACTION
-static void gc_sort_heap_by_compare_func(rb_objspace_t *objspace, gc_compact_compare_func compare_func);
-static int compare_pinned_slots(const void *left, const void *right, void *d);
-#endif
-
static void
gc_sweep_start(rb_objspace_t *objspace)
{
gc_mode_transition(objspace, gc_mode_sweeping);
- objspace->rincgc.pooled_slots = 0;
-#if GC_CAN_COMPILE_COMPACTION
- if (objspace->flags.during_compacting) {
- gc_sort_heap_by_compare_func(
- objspace,
- objspace->rcompactor.compare_func ? objspace->rcompactor.compare_func : compare_pinned_slots
- );
- }
+#if GC_ENABLE_INCREMENTAL_MARK
+ objspace->rincgc.pooled_slots = 0;
#endif
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
@@ -5908,12 +5829,14 @@ gc_sweep_start(rb_objspace_t *objspace)
gc_sweep_start_heap(objspace, heap);
+#if USE_RVARGC
/* We should call gc_sweep_finish_size_pool for size pools with no pages. */
if (heap->sweeping_page == NULL) {
GC_ASSERT(heap->total_pages == 0);
GC_ASSERT(heap->total_slots == 0);
gc_sweep_finish_size_pool(objspace, size_pool);
}
+#endif
}
rb_ractor_t *r = NULL;
@@ -5922,6 +5845,7 @@ gc_sweep_start(rb_objspace_t *objspace)
}
}
+#if USE_RVARGC
static void
gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
{
@@ -5930,15 +5854,14 @@ gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
size_t total_pages = heap->total_pages + SIZE_POOL_TOMB_HEAP(size_pool)->total_pages;
size_t swept_slots = size_pool->freed_slots + size_pool->empty_slots;
- size_t init_slots = gc_params.size_pool_init_slots[size_pool - size_pools];
- size_t min_free_slots = (size_t)(MAX(total_slots, init_slots) * gc_params.heap_free_slots_min_ratio);
+ size_t min_free_slots = (size_t)(total_slots * gc_params.heap_free_slots_min_ratio);
/* If we don't have enough slots and we have pages on the tomb heap, move
* pages from the tomb heap to the eden heap. This may prevent page
* creation thrashing (frequently allocating and deallocting pages) and
* GC thrashing (running GC more frequently than required). */
struct heap_page *resurrected_page;
- while (swept_slots < min_free_slots &&
+ while ((swept_slots < min_free_slots || swept_slots < gc_params.heap_init_slots) &&
(resurrected_page = heap_page_resurrect(objspace, size_pool))) {
swept_slots += resurrected_page->free_slots;
@@ -5946,20 +5869,28 @@ gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
heap_add_freepage(heap, resurrected_page);
}
+ /* Some size pools may have very few pages (or even no pages). These size pools
+ * should still have allocatable pages. */
+ if (min_free_slots < gc_params.heap_init_slots && swept_slots < gc_params.heap_init_slots) {
+ int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
+ size_t extra_slots = gc_params.heap_init_slots - swept_slots;
+ size_t extend_page_count = CEILDIV(extra_slots * multiple, HEAP_PAGE_OBJ_LIMIT);
+ if (extend_page_count > size_pool->allocatable_pages) {
+ size_pool_allocatable_pages_set(objspace, size_pool, extend_page_count);
+ }
+ }
+
if (swept_slots < min_free_slots) {
bool grow_heap = is_full_marking(objspace);
- /* Consider growing or starting a major GC if we are not currently in a
- * major GC and we can't allocate any more pages. */
- if (!is_full_marking(objspace) && size_pool->allocatable_pages == 0) {
- /* The heap is a growth heap if it freed more slots than had empty slots. */
- bool is_growth_heap = size_pool->empty_slots == 0 || size_pool->freed_slots > size_pool->empty_slots;
-
- /* Grow this heap if we haven't run at least RVALUE_OLD_AGE minor
- * GC since the last major GC or if this heap is smaller than the
- * the configured initial size. */
- if (objspace->profile.count - objspace->rgengc.last_major_gc < RVALUE_OLD_AGE ||
- total_slots < init_slots) {
+ if (!is_full_marking(objspace)) {
+ /* The heap is a growth heap if it freed more slots than had empty
+ * slots and used up all of its allocatable pages. */
+ bool is_growth_heap = (size_pool->empty_slots == 0 ||
+ size_pool->freed_slots > size_pool->empty_slots) &&
+ size_pool->allocatable_pages == 0;
+
+ if (objspace->profile.count - objspace->rgengc.last_major_gc < RVALUE_OLD_AGE) {
grow_heap = TRUE;
}
else if (is_growth_heap) { /* Only growth heaps are allowed to start a major GC. */
@@ -5977,6 +5908,7 @@ gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
}
}
}
+#endif
static void
gc_sweep_finish(rb_objspace_t *objspace)
@@ -5995,9 +5927,11 @@ gc_sweep_finish(rb_objspace_t *objspace)
size_pool->allocatable_pages = tomb_pages;
}
+#if USE_RVARGC
size_pool->freed_slots = 0;
size_pool->empty_slots = 0;
+#if GC_ENABLE_INCREMENTAL_MARK
if (!will_be_incremental_marking(objspace)) {
rb_heap_t *eden_heap = SIZE_POOL_EDEN_HEAP(size_pool);
struct heap_page *end_page = eden_heap->free_pages;
@@ -6011,15 +5945,13 @@ gc_sweep_finish(rb_objspace_t *objspace)
eden_heap->pooled_pages = NULL;
objspace->rincgc.pooled_slots = 0;
}
+#endif
+#endif
}
heap_pages_expand_sorted(objspace);
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0);
gc_mode_transition(objspace, gc_mode_none);
-
-#if RGENGC_CHECK_MODE >= 2
- gc_verify_internal_consistency(objspace);
-#endif
}
static int
@@ -6027,8 +5959,19 @@ gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *hea
{
struct heap_page *sweep_page = heap->sweeping_page;
int unlink_limit = GC_SWEEP_PAGES_FREEABLE_PER_STEP;
+
+#if GC_ENABLE_INCREMENTAL_MARK
int swept_slots = 0;
- int pooled_slots = 0;
+#if USE_RVARGC
+ bool need_pool = TRUE;
+#else
+ int need_pool = will_be_incremental_marking(objspace) ? TRUE : FALSE;
+#endif
+
+ gc_report(2, objspace, "gc_sweep_step (need_pool: %d)\n", need_pool);
+#else
+ gc_report(2, objspace, "gc_sweep_step\n");
+#endif
if (sweep_page == NULL) return FALSE;
@@ -6060,12 +6003,15 @@ gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *hea
heap_add_page(objspace, size_pool, SIZE_POOL_TOMB_HEAP(size_pool), sweep_page);
}
else if (free_slots > 0) {
+#if USE_RVARGC
size_pool->freed_slots += ctx.freed_slots;
size_pool->empty_slots += ctx.empty_slots;
+#endif
- if (pooled_slots < GC_INCREMENTAL_SWEEP_POOL_SLOT_COUNT) {
+#if GC_ENABLE_INCREMENTAL_MARK
+ if (need_pool) {
heap_add_poolpage(objspace, heap, sweep_page);
- pooled_slots += free_slots;
+ need_pool = FALSE;
}
else {
heap_add_freepage(heap, sweep_page);
@@ -6074,6 +6020,10 @@ gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *hea
break;
}
}
+#else
+ heap_add_freepage(heap, sweep_page);
+ break;
+#endif
}
else {
sweep_page->free_next = NULL;
@@ -6081,7 +6031,9 @@ gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *hea
} while ((sweep_page = heap->sweeping_page));
if (!heap->sweeping_page) {
+#if USE_RVARGC
gc_sweep_finish_size_pool(objspace, size_pool);
+#endif
if (!has_sweeping_pages(objspace)) {
gc_sweep_finish(objspace);
@@ -6113,11 +6065,13 @@ gc_sweep_continue(rb_objspace_t *objspace, rb_size_pool_t *sweep_size_pool, rb_h
GC_ASSERT(dont_gc_val() == FALSE);
if (!GC_ENABLE_LAZY_SWEEP) return;
- gc_sweeping_enter(objspace);
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_sweep_continue, &lock_lev);
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
rb_size_pool_t *size_pool = &size_pools[i];
if (!gc_sweep_step(objspace, size_pool, SIZE_POOL_EDEN_HEAP(size_pool))) {
+#if USE_RVARGC
/* sweep_size_pool requires a free slot but sweeping did not yield any. */
if (size_pool == sweep_size_pool) {
if (size_pool->allocatable_pages > 0) {
@@ -6129,13 +6083,13 @@ gc_sweep_continue(rb_objspace_t *objspace, rb_size_pool_t *sweep_size_pool, rb_h
break;
}
}
+#endif
}
}
- gc_sweeping_exit(objspace);
+ gc_exit(objspace, gc_enter_event_sweep_continue, &lock_lev);
}
-#if GC_CAN_COMPILE_COMPACTION
static void
invalidate_moved_plane(rb_objspace_t *objspace, struct heap_page *page, uintptr_t p, bits_t bitset)
{
@@ -6208,7 +6162,6 @@ invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page)
p += BITS_BITLENGTH * BASE_SLOT_SIZE;
}
}
-#endif
static void
gc_compact_start(rb_objspace_t *objspace)
@@ -6245,8 +6198,6 @@ static void gc_sweep_compact(rb_objspace_t *objspace);
static void
gc_sweep(rb_objspace_t *objspace)
{
- gc_sweeping_enter(objspace);
-
const unsigned int immediate_sweep = objspace->flags.immediate_sweep;
gc_report(1, objspace, "gc_sweep: immediate: %d\n", immediate_sweep);
@@ -6274,7 +6225,10 @@ gc_sweep(rb_objspace_t *objspace)
}
}
- gc_sweeping_exit(objspace);
+#if !USE_RVARGC
+ rb_size_pool_t *size_pool = &size_pools[0];
+ gc_heap_prepare_minimum_pages(objspace, size_pool, SIZE_POOL_EDEN_HEAP(size_pool));
+#endif
}
/* Marking - Marking stack */
@@ -6536,7 +6490,7 @@ stack_check(rb_execution_context_t *ec, int water_mark)
#define STACKFRAME_FOR_CALL_CFUNC 2048
-int
+MJIT_FUNC_EXPORTED int
rb_ec_stack_check(rb_execution_context_t *ec)
{
return stack_check(ec, STACKFRAME_FOR_CALL_CFUNC);
@@ -6576,6 +6530,16 @@ rb_gc_mark_locations(const VALUE *start, const VALUE *end)
gc_mark_locations(&rb_objspace, start, end, gc_mark_maybe);
}
+static void
+gc_mark_values(rb_objspace_t *objspace, long n, const VALUE *values)
+{
+ long i;
+
+ for (i=0; i<n; i++) {
+ gc_mark(objspace, values[i]);
+ }
+}
+
void
rb_gc_mark_values(long n, const VALUE *values)
{
@@ -6583,7 +6547,7 @@ rb_gc_mark_values(long n, const VALUE *values)
rb_objspace_t *objspace = &rb_objspace;
for (i=0; i<n; i++) {
- gc_mark(objspace, values[i]);
+ gc_mark_and_pin(objspace, values[i]);
}
}
@@ -6593,7 +6557,7 @@ gc_mark_stack_values(rb_objspace_t *objspace, long n, const VALUE *values)
long i;
for (i=0; i<n; i++) {
- if (is_markable_object(values[i])) {
+ if (is_markable_object(objspace, values[i])) {
gc_mark_and_pin(objspace, values[i]);
}
}
@@ -6712,6 +6676,14 @@ mark_hash(rb_objspace_t *objspace, VALUE hash)
rb_hash_stlike_foreach(hash, mark_keyvalue, (st_data_t)objspace);
}
+ if (RHASH_AR_TABLE_P(hash)) {
+ if (LIKELY(during_gc) && RHASH_TRANSIENT_P(hash)) {
+ rb_transient_heap_mark(hash, RHASH_AR_TABLE(hash));
+ }
+ }
+ else {
+ VM_ASSERT(!RHASH_TRANSIENT_P(hash));
+ }
gc_mark(objspace, RHASH(hash)->ifnone);
}
@@ -6761,6 +6733,7 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
return;
case VM_METHOD_TYPE_REFINED:
gc_mark(objspace, (VALUE)def->body.refined.orig_me);
+ gc_mark(objspace, (VALUE)def->body.refined.owner);
break;
case VM_METHOD_TYPE_CFUNC:
case VM_METHOD_TYPE_ZSUPER:
@@ -6895,7 +6868,6 @@ each_machine_stack_value(const rb_execution_context_t *ec, void (*cb)(rb_objspac
VALUE *stack_start, *stack_end;
GET_STACK_BOUNDS(stack_start, stack_end, 0);
- RUBY_DEBUG_LOG("ec->th:%u stack_start:%p stack_end:%p", rb_ec_thread_ptr(ec)->serial, stack_start, stack_end);
each_stack_location(objspace, ec, stack_start, stack_end, cb);
}
@@ -6978,7 +6950,7 @@ gc_remember_unprotected(rb_objspace_t *objspace, VALUE obj)
bits_t *uncollectible_bits = &page->uncollectible_bits[0];
if (!MARKED_IN_BITMAP(uncollectible_bits, obj)) {
- page->flags.has_uncollectible_wb_unprotected_objects = TRUE;
+ page->flags.has_uncollectible_shady_objects = TRUE;
MARK_IN_BITMAP(uncollectible_bits, obj);
objspace->rgengc.uncollectible_wb_unprotected_objects++;
@@ -7001,8 +6973,31 @@ rgengc_check_relation(rb_objspace_t *objspace, VALUE obj)
const VALUE old_parent = objspace->rgengc.parent_object;
if (old_parent) { /* parent object is old */
- if (RVALUE_WB_UNPROTECTED(obj) || !RVALUE_OLD_P(obj)) {
- rgengc_remember(objspace, old_parent);
+ if (RVALUE_WB_UNPROTECTED(obj)) {
+ if (gc_remember_unprotected(objspace, obj)) {
+ gc_report(2, objspace, "relation: (O->S) %s -> %s\n", obj_info(old_parent), obj_info(obj));
+ }
+ }
+ else {
+ if (!RVALUE_OLD_P(obj)) {
+ if (RVALUE_MARKED(obj)) {
+ /* An object pointed from an OLD object should be OLD. */
+ gc_report(2, objspace, "relation: (O->unmarked Y) %s -> %s\n", obj_info(old_parent), obj_info(obj));
+ RVALUE_AGE_SET_OLD(objspace, obj);
+ if (is_incremental_marking(objspace)) {
+ if (!RVALUE_MARKING(obj)) {
+ gc_grey(objspace, obj);
+ }
+ }
+ else {
+ rgengc_remember(objspace, obj);
+ }
+ }
+ else {
+ gc_report(2, objspace, "relation: (O->Y) %s -> %s\n", obj_info(old_parent), obj_info(obj));
+ RVALUE_AGE_SET_CANDIDATE(objspace, obj);
+ }
+ }
}
}
@@ -7017,9 +7012,11 @@ gc_grey(rb_objspace_t *objspace, VALUE obj)
if (RVALUE_MARKING(obj) == TRUE) rb_bug("gc_grey: %s is marking/remembered.", obj_info(obj));
#endif
+#if GC_ENABLE_INCREMENTAL_MARK
if (is_incremental_marking(objspace)) {
MARK_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj);
}
+#endif
push_mark_stack(&objspace->mark_stack, obj);
}
@@ -7083,14 +7080,10 @@ gc_mark_ptr(rb_objspace_t *objspace, VALUE obj)
static inline void
gc_pin(rb_objspace_t *objspace, VALUE obj)
{
- GC_ASSERT(is_markable_object(obj));
+ GC_ASSERT(is_markable_object(objspace, obj));
if (UNLIKELY(objspace->flags.during_compacting)) {
if (LIKELY(during_gc)) {
- if (!MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj)) {
- GC_ASSERT(GET_HEAP_PAGE(obj)->pinned_slots <= GET_HEAP_PAGE(obj)->total_slots);
- GET_HEAP_PAGE(obj)->pinned_slots++;
- MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj);
- }
+ MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj);
}
}
}
@@ -7098,7 +7091,7 @@ gc_pin(rb_objspace_t *objspace, VALUE obj)
static inline void
gc_mark_and_pin(rb_objspace_t *objspace, VALUE obj)
{
- if (!is_markable_object(obj)) return;
+ if (!is_markable_object(objspace, obj)) return;
gc_pin(objspace, obj);
gc_mark_ptr(objspace, obj);
}
@@ -7106,7 +7099,7 @@ gc_mark_and_pin(rb_objspace_t *objspace, VALUE obj)
static inline void
gc_mark(rb_objspace_t *objspace, VALUE obj)
{
- if (!is_markable_object(obj)) return;
+ if (!is_markable_object(objspace, obj)) return;
gc_mark_ptr(objspace, obj);
}
@@ -7122,78 +7115,6 @@ rb_gc_mark(VALUE ptr)
gc_mark_and_pin(&rb_objspace, ptr);
}
-void
-rb_gc_mark_and_move(VALUE *ptr)
-{
- rb_objspace_t *objspace = &rb_objspace;
- if (RB_SPECIAL_CONST_P(*ptr)) return;
-
- if (UNLIKELY(objspace->flags.during_reference_updating)) {
- GC_ASSERT(objspace->flags.during_compacting);
- GC_ASSERT(during_gc);
-
- *ptr = rb_gc_location(*ptr);
- }
- else {
- gc_mark_ptr(objspace, *ptr);
- }
-}
-
-void
-rb_gc_mark_weak(VALUE *ptr)
-{
- rb_objspace_t *objspace = &rb_objspace;
-
- if (UNLIKELY(!during_gc)) return;
-
- VALUE obj = *ptr;
- if (RB_SPECIAL_CONST_P(obj)) return;
-
- GC_ASSERT(objspace->rgengc.parent_object == 0 || FL_TEST(objspace->rgengc.parent_object, FL_WB_PROTECTED));
-
- if (UNLIKELY(RB_TYPE_P(obj, T_NONE))) {
- rp(obj);
- rb_bug("try to mark T_NONE object");
- }
-
- /* If we are in a minor GC and the other object is old, then obj should
- * already be marked and cannot be reclaimed in this GC cycle so we don't
- * need to add it to the weak refences list. */
- if (!is_full_marking(objspace) && RVALUE_OLD_P(obj)) {
- GC_ASSERT(RVALUE_MARKED(obj));
- GC_ASSERT(!objspace->flags.during_compacting);
-
- return;
- }
-
- rgengc_check_relation(objspace, obj);
-
- rb_darray_append_without_gc(&objspace->weak_references, ptr);
-
- objspace->profile.weak_references_count++;
-}
-
-void
-rb_gc_remove_weak(VALUE parent_obj, VALUE *ptr)
-{
- rb_objspace_t *objspace = &rb_objspace;
-
- /* If we're not incremental marking, then the state of the objects can't
- * change so we don't need to do anything. */
- if (!is_incremental_marking(objspace)) return;
- /* If parent_obj has not been marked, then ptr has not yet been marked
- * weak, so we don't need to do anything. */
- if (!RVALUE_MARKED(parent_obj)) return;
-
- VALUE **ptr_ptr;
- rb_darray_foreach(objspace->weak_references, i, ptr_ptr) {
- if (*ptr_ptr == ptr) {
- *ptr_ptr = NULL;
- break;
- }
- }
-}
-
/* CAUTION: THIS FUNCTION ENABLE *ONLY BEFORE* SWEEPING.
* This function is only for GC_END_MARK timing.
*/
@@ -7227,7 +7148,7 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
// just after newobj() can be NULL here.
GC_ASSERT(env->ep[VM_ENV_DATA_INDEX_ENV] == obj);
GC_ASSERT(VM_ENV_ESCAPED_P(env->ep));
- rb_gc_mark_values((long)env->env_size, env->env);
+ gc_mark_values(objspace, (long)env->env_size, env->env);
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
gc_mark(objspace, (VALUE)env->iseq);
@@ -7260,7 +7181,7 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
return;
case imemo_iseq:
- rb_iseq_mark_and_move((rb_iseq_t *)obj, false);
+ rb_iseq_mark((rb_iseq_t *)obj);
return;
case imemo_tmpbuf:
{
@@ -7274,34 +7195,15 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
rb_ast_mark(&RANY(obj)->as.imemo.ast);
return;
case imemo_parser_strterm:
+ rb_strterm_mark(obj);
return;
case imemo_callinfo:
return;
case imemo_callcache:
- /* cc is callcache.
- *
- * cc->klass (klass) should not be marked because if the klass is
- * free'ed, the cc->klass will be cleared by `vm_cc_invalidate()`.
- *
- * cc->cme (cme) should not be marked because if cc is invalidated
- * when cme is free'ed.
- * - klass marks cme if klass uses cme.
- * - caller classe's ccs->cme marks cc->cme.
- * - if cc is invalidated (klass doesn't refer the cc),
- * cc is invalidated by `vm_cc_invalidate()` and cc->cme is
- * not be accessed.
- * - On the multi-Ractors, cme will be collected with global GC
- * so that it is safe if GC is not interleaving while accessing
- * cc and cme.
- * - However, cc_type_super and cc_type_refinement are not chained
- * from ccs so cc->cme should be marked; the cme might be
- * reachable only through cc in these cases.
- */
{
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
- if (vm_cc_super_p(cc) || vm_cc_refinement_p(cc)) {
- gc_mark(objspace, (VALUE)cc->cme_);
- }
+ // should not mark klass here
+ gc_mark(objspace, (VALUE)vm_cc_cme(cc));
}
return;
case imemo_constcache:
@@ -7317,12 +7219,6 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
}
}
-static bool
-gc_declarative_marking_p(const rb_data_type_t *type)
-{
- return (type->flags & RUBY_TYPED_DECL_MARKING) != 0;
-}
-
static void mark_cvc_tbl(rb_objspace_t *objspace, VALUE klass);
static void
@@ -7364,29 +7260,19 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
- if (FL_TEST(obj, FL_SINGLETON)) {
- gc_mark(objspace, RCLASS_ATTACHED_OBJECT(obj));
- }
- // Continue to the shared T_CLASS/T_MODULE
case T_MODULE:
if (RCLASS_SUPER(obj)) {
gc_mark(objspace, RCLASS_SUPER(obj));
}
+ if (!RCLASS_EXT(obj)) break;
mark_m_tbl(objspace, RCLASS_M_TBL(obj));
mark_cvc_tbl(objspace, obj);
cc_table_mark(objspace, obj);
- if (rb_shape_obj_too_complex(obj)) {
- mark_tbl_no_pin(objspace, (st_table *)RCLASS_IVPTR(obj));
- }
- else {
- for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) {
- gc_mark(objspace, RCLASS_IVPTR(obj)[i]);
- }
+ for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) {
+ gc_mark(objspace, RCLASS_IVPTR(obj)[i]);
}
mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
-
- gc_mark(objspace, RCLASS_EXT(obj)->classpath);
break;
case T_ICLASS:
@@ -7396,6 +7282,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
if (RCLASS_SUPER(obj)) {
gc_mark(objspace, RCLASS_SUPER(obj));
}
+ if (!RCLASS_EXT(obj)) break;
if (RCLASS_INCLUDER(obj)) {
gc_mark(objspace, RCLASS_INCLUDER(obj));
@@ -7411,10 +7298,16 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
}
else {
long i, len = RARRAY_LEN(obj);
- const VALUE *ptr = RARRAY_CONST_PTR(obj);
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(obj);
for (i=0; i < len; i++) {
gc_mark(objspace, ptr[i]);
}
+
+ if (LIKELY(during_gc)) {
+ if (!ARY_EMBED_P(obj) && RARRAY_TRANSIENT_P(obj)) {
+ rb_transient_heap_mark(obj, ptr);
+ }
+ }
}
break;
@@ -7424,37 +7317,18 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case T_STRING:
if (STR_SHARED_P(obj)) {
- if (STR_EMBED_P(any->as.string.as.heap.aux.shared)) {
- /* Embedded shared strings cannot be moved because this string
- * points into the slot of the shared string. There may be code
- * using the RSTRING_PTR on the stack, which would pin this
- * string but not pin the shared string, causing it to move. */
- gc_mark_and_pin(objspace, any->as.string.as.heap.aux.shared);
- }
- else {
- gc_mark(objspace, any->as.string.as.heap.aux.shared);
- }
+ gc_mark(objspace, any->as.string.as.heap.aux.shared);
}
break;
case T_DATA:
{
- void *const ptr = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
-
+ void *const ptr = DATA_PTR(obj);
if (ptr) {
- if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(any->as.typeddata.type)) {
- size_t *offset_list = (size_t *)RANY(obj)->as.typeddata.type->function.dmark;
-
- for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) {
- rb_gc_mark_movable(*(VALUE *)((char *)ptr + offset));
- }
- }
- else {
- RUBY_DATA_FUNC mark_func = RTYPEDDATA_P(obj) ?
- any->as.typeddata.type->function.dmark :
- any->as.data.dmark;
- if (mark_func) (*mark_func)(ptr);
- }
+ RUBY_DATA_FUNC mark_func = RTYPEDDATA_P(obj) ?
+ any->as.typeddata.type->function.dmark :
+ any->as.data.dmark;
+ if (mark_func) (*mark_func)(ptr);
}
}
break;
@@ -7472,12 +7346,17 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
for (i = 0; i < len; i++) {
gc_mark(objspace, ptr[i]);
}
+
+ if (LIKELY(during_gc) &&
+ ROBJ_TRANSIENT_P(obj)) {
+ rb_transient_heap_mark(obj, ptr);
+ }
}
if (shape) {
VALUE klass = RBASIC_CLASS(obj);
// Increment max_iv_count if applicable, used to determine size pool allocation
- attr_index_t num_of_ivs = shape->next_iv_index;
+ uint32_t num_of_ivs = shape->next_iv_index;
if (RCLASS_EXT(klass)->max_iv_count < num_of_ivs) {
RCLASS_EXT(klass)->max_iv_count = num_of_ivs;
}
@@ -7528,6 +7407,11 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
for (i=0; i<len; i++) {
gc_mark(objspace, ptr[i]);
}
+
+ if (LIKELY(during_gc) &&
+ RSTRUCT_TRANSIENT_P(obj)) {
+ rb_transient_heap_mark(obj, ptr);
+ }
}
break;
@@ -7553,8 +7437,10 @@ gc_mark_stacked_objects(rb_objspace_t *objspace, int incremental, size_t count)
{
mark_stack_t *mstack = &objspace->mark_stack;
VALUE obj;
+#if GC_ENABLE_INCREMENTAL_MARK
size_t marked_slots_at_the_beginning = objspace->marked_slots;
size_t popped_count = 0;
+#endif
while (pop_mark_stack(mstack, &obj)) {
if (UNDEF_P(obj)) continue; /* skip */
@@ -7564,6 +7450,7 @@ gc_mark_stacked_objects(rb_objspace_t *objspace, int incremental, size_t count)
}
gc_mark_children(objspace, obj);
+#if GC_ENABLE_INCREMENTAL_MARK
if (incremental) {
if (RGENGC_CHECK_MODE && !RVALUE_MARKING(obj)) {
rb_bug("gc_mark_stacked_objects: incremental, but marking bit is 0");
@@ -7578,6 +7465,7 @@ gc_mark_stacked_objects(rb_objspace_t *objspace, int incremental, size_t count)
else {
/* just ignore marking bits */
}
+#endif
}
if (RGENGC_CHECK_MODE >= 3) gc_verify_internal_consistency(objspace);
@@ -8003,7 +7891,7 @@ check_children_i(const VALUE child, void *ptr)
if (check_rvalue_consistency_force(child, FALSE) != 0) {
fprintf(stderr, "check_children_i: %s has error (referenced from %s)",
obj_info(child), obj_info(data->parent));
- rb_print_backtrace(stderr); /* C backtrace will help to debug */
+ rb_print_backtrace(); /* C backtrace will help to debug */
data->err_count++;
}
@@ -8111,7 +7999,7 @@ gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
(void *)page, remembered_old_objects, obj ? obj_info(obj) : "");
}
- if (page->flags.has_uncollectible_wb_unprotected_objects == FALSE && has_remembered_shady == TRUE) {
+ if (page->flags.has_uncollectible_shady_objects == FALSE && has_remembered_shady == TRUE) {
rb_bug("page %p's has_remembered_shady should be false, but there are remembered shady objects. %s",
(void *)page, obj ? obj_info(obj) : "");
}
@@ -8119,11 +8007,11 @@ gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
if (0) {
/* free_slots may not equal to free_objects */
if (page->free_slots != free_objects) {
- rb_bug("page %p's free_slots should be %d, but %d", (void *)page, page->free_slots, free_objects);
+ rb_bug("page %p's free_slots should be %d, but %d\n", (void *)page, page->free_slots, free_objects);
}
}
if (page->final_slots != zombie_objects) {
- rb_bug("page %p's final_slots should be %d, but %d", (void *)page, page->final_slots, zombie_objects);
+ rb_bug("page %p's final_slots should be %d, but %d\n", (void *)page, page->final_slots, zombie_objects);
}
return remembered_old_objects;
@@ -8223,8 +8111,9 @@ gc_verify_internal_consistency_(rb_objspace_t *objspace)
!finalizing &&
ruby_single_main_ractor != NULL) {
if (objspace_live_slots(objspace) != data.live_object_count) {
- fprintf(stderr, "heap_pages_final_slots: %"PRIdSIZE", total_freed_objects: %"PRIdSIZE"\n",
- heap_pages_final_slots, total_freed_objects(objspace));
+ fprintf(stderr, "heap_pages_final_slots: %"PRIdSIZE", "
+ "objspace->profile.total_freed_objects: %"PRIdSIZE"\n",
+ heap_pages_final_slots, objspace->profile.total_freed_objects);
rb_bug("inconsistent live slot number: expect %"PRIuSIZE", but %"PRIuSIZE".",
objspace_live_slots(objspace), data.live_object_count);
}
@@ -8291,6 +8180,14 @@ rb_gc_verify_internal_consistency(void)
gc_verify_internal_consistency(&rb_objspace);
}
+static VALUE
+gc_verify_transient_heap_internal_consistency(VALUE dmy)
+{
+ rb_transient_heap_verify();
+ return Qnil;
+}
+
+#if GC_ENABLE_INCREMENTAL_MARK
static void
heap_move_pooled_pages_to_free_pages(rb_heap_t *heap)
{
@@ -8309,6 +8206,7 @@ heap_move_pooled_pages_to_free_pages(rb_heap_t *heap)
heap->pooled_pages = NULL;
}
}
+#endif
/* marks */
@@ -8320,6 +8218,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
gc_mode_transition(objspace, gc_mode_marking);
if (full_mark) {
+#if GC_ENABLE_INCREMENTAL_MARK
size_t incremental_marking_steps = (objspace->rincgc.pooled_slots / INCREMENTAL_MARK_STEP_ALLOCATIONS) + 1;
objspace->rincgc.step_slots = (objspace->marked_slots * 2) / incremental_marking_steps;
@@ -8327,6 +8226,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
"objspace->rincgc.pooled_page_num: %"PRIdSIZE", "
"objspace->rincgc.step_slots: %"PRIdSIZE", \n",
objspace->marked_slots, objspace->rincgc.pooled_slots, objspace->rincgc.step_slots);
+#endif
objspace->flags.during_minor_gc = FALSE;
if (ruby_enable_autocompact) {
objspace->flags.during_compacting |= TRUE;
@@ -8342,14 +8242,6 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
rgengc_mark_and_rememberset_clear(objspace, heap);
heap_move_pooled_pages_to_free_pages(heap);
-
- if (objspace->flags.during_compacting) {
- struct heap_page *page = NULL;
-
- ccan_list_for_each(&heap->pages, page, page_node) {
- page->pinned_slots = 0;
- }
- }
}
}
else {
@@ -8369,6 +8261,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
full_mark ? "full" : "minor", mark_stack_size(&objspace->mark_stack));
}
+#if GC_ENABLE_INCREMENTAL_MARK
static inline void
gc_marks_wb_unprotected_objects_plane(rb_objspace_t *objspace, uintptr_t p, bits_t bits)
{
@@ -8412,36 +8305,12 @@ gc_marks_wb_unprotected_objects(rb_objspace_t *objspace, rb_heap_t *heap)
gc_mark_stacked_objects_all(objspace);
}
-
-static void
-gc_update_weak_references(rb_objspace_t *objspace)
-{
- size_t retained_weak_references_count = 0;
- VALUE **ptr_ptr;
- rb_darray_foreach(objspace->weak_references, i, ptr_ptr) {
- if (!*ptr_ptr) continue;
-
- VALUE obj = **ptr_ptr;
-
- if (RB_SPECIAL_CONST_P(obj)) continue;
-
- if (!RVALUE_MARKED(obj)) {
- **ptr_ptr = Qundef;
- }
- else {
- retained_weak_references_count++;
- }
- }
-
- objspace->profile.retained_weak_references_count = retained_weak_references_count;
-
- rb_darray_clear(objspace->weak_references);
- rb_darray_resize_capa_without_gc(&objspace->weak_references, retained_weak_references_count);
-}
+#endif
static void
gc_marks_finish(rb_objspace_t *objspace)
{
+#if GC_ENABLE_INCREMENTAL_MARK
/* finish incremental GC */
if (is_incremental_marking(objspace)) {
if (RGENGC_CHECK_MODE && is_mark_stack_empty(&objspace->mark_stack) == 0) {
@@ -8464,13 +8333,19 @@ gc_marks_finish(rb_objspace_t *objspace)
gc_marks_wb_unprotected_objects(objspace, SIZE_POOL_EDEN_HEAP(&size_pools[i]));
}
}
-
- gc_update_weak_references(objspace);
+#endif /* GC_ENABLE_INCREMENTAL_MARK */
#if RGENGC_CHECK_MODE >= 2
gc_verify_internal_consistency(objspace);
#endif
+ if (is_full_marking(objspace)) {
+ /* See the comment about RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR */
+ const double r = gc_params.oldobject_limit_factor;
+ objspace->rgengc.uncollectible_wb_unprotected_objects_limit = (size_t)(objspace->rgengc.uncollectible_wb_unprotected_objects * r);
+ objspace->rgengc.old_objects_limit = (size_t)(objspace->rgengc.old_objects * r);
+ }
+
#if RGENGC_CHECK_MODE >= 4
during_gc = FALSE;
gc_marks_check(objspace, gc_check_after_marks_i, "after_marks");
@@ -8489,14 +8364,9 @@ gc_marks_finish(rb_objspace_t *objspace)
GC_ASSERT(heap_eden_total_slots(objspace) >= objspace->marked_slots);
- /* Setup freeable slots. */
- size_t total_init_slots = 0;
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- total_init_slots += gc_params.size_pool_init_slots[i] * r_mul;
- }
-
- if (max_free_slots < total_init_slots) {
- max_free_slots = total_init_slots;
+ /* setup free-able page counts */
+ if (max_free_slots < gc_params.heap_init_slots * r_mul) {
+ max_free_slots = gc_params.heap_init_slots * r_mul;
}
if (sweep_slots > max_free_slots) {
@@ -8523,15 +8393,23 @@ gc_marks_finish(rb_objspace_t *objspace)
objspace->rgengc.need_major_gc |= GPR_FLAG_MAJOR_BY_NOFREE;
}
}
+
+#if !USE_RVARGC
+ if (full_marking) {
+ /* increment: */
+ gc_report(1, objspace, "gc_marks_finish: heap_set_increment!!\n");
+ rb_size_pool_t *size_pool = &size_pools[0];
+ size_pool_allocatable_pages_set(objspace, size_pool, heap_extend_pages(objspace, size_pool, sweep_slots, total_slots, heap_allocated_pages + heap_allocatable_pages(objspace)));
+
+ heap_increment(objspace, size_pool, SIZE_POOL_EDEN_HEAP(size_pool));
+ }
+#endif
}
if (full_marking) {
/* See the comment about RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR */
const double r = gc_params.oldobject_limit_factor;
- objspace->rgengc.uncollectible_wb_unprotected_objects_limit = MAX(
- (size_t)(objspace->rgengc.uncollectible_wb_unprotected_objects * r),
- (size_t)(objspace->rgengc.old_objects * gc_params.uncollectible_wb_unprotected_objects_limit_ratio)
- );
+ objspace->rgengc.uncollectible_wb_unprotected_objects_limit = (size_t)(objspace->rgengc.uncollectible_wb_unprotected_objects * r);
objspace->rgengc.old_objects_limit = (size_t)(objspace->rgengc.old_objects * r);
}
@@ -8552,11 +8430,26 @@ gc_marks_finish(rb_objspace_t *objspace)
objspace->rgengc.need_major_gc ? "major" : "minor");
}
+ rb_transient_heap_finish_marking();
rb_ractor_finish_marking();
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_MARK, 0);
}
+#if GC_ENABLE_INCREMENTAL_MARK
+static void
+gc_marks_step(rb_objspace_t *objspace, size_t slots)
+{
+ GC_ASSERT(is_marking(objspace));
+
+ if (gc_mark_stacked_objects_incremental(objspace, slots)) {
+ gc_marks_finish(objspace);
+ gc_sweep(objspace);
+ }
+ if (0) fprintf(stderr, "objspace->marked_slots: %"PRIdSIZE"\n", objspace->marked_slots);
+}
+#endif
+
static bool
gc_compact_heap_cursors_met_p(rb_heap_t *heap)
{
@@ -8587,10 +8480,6 @@ gc_compact_destination_pool(rb_objspace_t *objspace, rb_size_pool_t *src_pool, V
obj_size = rb_str_size_as_embedded(src);
break;
- case T_HASH:
- obj_size = sizeof(struct RHash) + (RHASH_ST_TABLE_P(src) ? sizeof(st_table) : sizeof(ar_table));
- break;
-
default:
return src_pool;
}
@@ -8646,7 +8535,7 @@ gc_compact_move(rb_objspace_t *objspace, rb_heap_t *heap, rb_size_pool_t *size_p
if (dheap->sweeping_page->free_slots > 0) {
heap_add_freepage(dheap, dheap->sweeping_page);
- }
+ };
dheap->sweeping_page = ccan_list_next(&dheap->pages, dheap->sweeping_page, page_node);
if (gc_compact_heap_cursors_met_p(dheap)) {
@@ -8787,9 +8676,11 @@ gc_marks_rest(rb_objspace_t *objspace)
{
gc_report(1, objspace, "gc_marks_rest\n");
+#if GC_ENABLE_INCREMENTAL_MARK
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
SIZE_POOL_EDEN_HEAP(&size_pools[i])->pooled_pages = NULL;
}
+#endif
if (is_incremental_marking(objspace)) {
while (gc_mark_stacked_objects_incremental(objspace, INT_MAX) == FALSE);
@@ -8799,62 +8690,44 @@ gc_marks_rest(rb_objspace_t *objspace)
}
gc_marks_finish(objspace);
-}
-
-static bool
-gc_marks_step(rb_objspace_t *objspace, size_t slots)
-{
- bool marking_finished = false;
-
- GC_ASSERT(is_marking(objspace));
- if (gc_mark_stacked_objects_incremental(objspace, slots)) {
- gc_marks_finish(objspace);
- marking_finished = true;
- }
-
- return marking_finished;
+ /* move to sweep */
+ gc_sweep(objspace);
}
-static bool
+static void
gc_marks_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap)
{
GC_ASSERT(dont_gc_val() == FALSE);
- bool marking_finished = true;
+#if GC_ENABLE_INCREMENTAL_MARK
- gc_marking_enter(objspace);
+ unsigned int lock_lev;
+ gc_enter(objspace, gc_enter_event_mark_continue, &lock_lev);
if (heap->free_pages) {
gc_report(2, objspace, "gc_marks_continue: has pooled pages");
-
- marking_finished = gc_marks_step(objspace, objspace->rincgc.step_slots);
+ gc_marks_step(objspace, objspace->rincgc.step_slots);
}
else {
gc_report(2, objspace, "gc_marks_continue: no more pooled pages (stack depth: %"PRIdSIZE").\n",
mark_stack_size(&objspace->mark_stack));
- size_pool->force_incremental_marking_finish_count++;
gc_marks_rest(objspace);
}
- gc_marking_exit(objspace);
-
- return marking_finished;
+ gc_exit(objspace, gc_enter_event_mark_continue, &lock_lev);
+#endif
}
-static bool
+static void
gc_marks(rb_objspace_t *objspace, int full_mark)
{
gc_prof_mark_timer_start(objspace);
- gc_marking_enter(objspace);
-
- bool marking_finished = false;
/* setup marking */
gc_marks_start(objspace, full_mark);
if (!is_incremental_marking(objspace)) {
gc_marks_rest(objspace);
- marking_finished = true;
}
#if RGENGC_PROFILE > 0
@@ -8863,11 +8736,7 @@ gc_marks(rb_objspace_t *objspace, int full_mark)
record->old_objects = objspace->rgengc.old_objects;
}
#endif
-
- gc_marking_exit(objspace);
gc_prof_mark_timer_stop(objspace);
-
- return marking_finished;
}
/* RGENGC */
@@ -8905,10 +8774,18 @@ gc_report_body(int level, rb_objspace_t *objspace, const char *fmt, ...)
/* bit operations */
static int
+rgengc_remembersetbits_get(rb_objspace_t *objspace, VALUE obj)
+{
+ return RVALUE_REMEMBERED(obj);
+}
+
+static int
rgengc_remembersetbits_set(rb_objspace_t *objspace, VALUE obj)
{
struct heap_page *page = GET_HEAP_PAGE(obj);
- bits_t *bits = &page->remembered_bits[0];
+ bits_t *bits = &page->marking_bits[0];
+
+ GC_ASSERT(!is_incremental_marking(objspace));
if (MARKED_IN_BITMAP(bits, obj)) {
return FALSE;
@@ -8927,7 +8804,7 @@ static int
rgengc_remember(rb_objspace_t *objspace, VALUE obj)
{
gc_report(6, objspace, "rgengc_remember: %s %s\n", obj_info(obj),
- RVALUE_REMEMBERED(obj) ? "was already remembered" : "is remembered now");
+ rgengc_remembersetbits_get(objspace, obj) ? "was already remembered" : "is remembered now");
check_rvalue_consistency(obj);
@@ -8936,7 +8813,7 @@ rgengc_remember(rb_objspace_t *objspace, VALUE obj)
}
#if RGENGC_PROFILE > 0
- if (!RVALUE_REMEMBERED(obj)) {
+ if (!rgengc_remembered(objspace, obj)) {
if (RVALUE_WB_UNPROTECTED(obj) == 0) {
objspace->profile.total_remembered_normal_object_count++;
#if RGENGC_PROFILE >= 2
@@ -8949,6 +8826,21 @@ rgengc_remember(rb_objspace_t *objspace, VALUE obj)
return rgengc_remembersetbits_set(objspace, obj);
}
+static int
+rgengc_remembered_sweep(rb_objspace_t *objspace, VALUE obj)
+{
+ int result = rgengc_remembersetbits_get(objspace, obj);
+ check_rvalue_consistency(obj);
+ return result;
+}
+
+static int
+rgengc_remembered(rb_objspace_t *objspace, VALUE obj)
+{
+ gc_report(6, objspace, "rgengc_remembered: %s\n", obj_info(obj));
+ return rgengc_remembered_sweep(objspace, obj);
+}
+
#ifndef PROFILE_REMEMBERSET_MARK
#define PROFILE_REMEMBERSET_MARK 0
#endif
@@ -8983,20 +8875,20 @@ rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap)
gc_report(1, objspace, "rgengc_rememberset_mark: start\n");
ccan_list_for_each(&heap->pages, page, page_node) {
- if (page->flags.has_remembered_objects | page->flags.has_uncollectible_wb_unprotected_objects) {
+ if (page->flags.has_remembered_objects | page->flags.has_uncollectible_shady_objects) {
uintptr_t p = page->start;
bits_t bitset, bits[HEAP_PAGE_BITMAP_LIMIT];
- bits_t *remembered_bits = page->remembered_bits;
+ bits_t *marking_bits = page->marking_bits;
bits_t *uncollectible_bits = page->uncollectible_bits;
bits_t *wb_unprotected_bits = page->wb_unprotected_bits;
#if PROFILE_REMEMBERSET_MARK
- if (page->flags.has_remembered_objects && page->flags.has_uncollectible_wb_unprotected_objects) has_both++;
+ if (page->flags.has_remembered_objects && page->flags.has_uncollectible_shady_objects) has_both++;
else if (page->flags.has_remembered_objects) has_old++;
- else if (page->flags.has_uncollectible_wb_unprotected_objects) has_shady++;
+ else if (page->flags.has_uncollectible_shady_objects) has_shady++;
#endif
for (j=0; j<HEAP_PAGE_BITMAP_LIMIT; j++) {
- bits[j] = remembered_bits[j] | (uncollectible_bits[j] & wb_unprotected_bits[j]);
- remembered_bits[j] = 0;
+ bits[j] = marking_bits[j] | (uncollectible_bits[j] & wb_unprotected_bits[j]);
+ marking_bits[j] = 0;
}
page->flags.has_remembered_objects = FALSE;
@@ -9033,9 +8925,8 @@ rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap)
memset(&page->mark_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
memset(&page->uncollectible_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
memset(&page->marking_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
- memset(&page->remembered_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
memset(&page->pinned_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
- page->flags.has_uncollectible_wb_unprotected_objects = FALSE;
+ page->flags.has_uncollectible_shady_objects = FALSE;
page->flags.has_remembered_objects = FALSE;
}
}
@@ -9053,8 +8944,9 @@ gc_writebarrier_generational(VALUE a, VALUE b, rb_objspace_t *objspace)
if (is_incremental_marking(objspace)) rb_bug("gc_writebarrier_generational: called while incremental marking: %s -> %s", obj_info(a), obj_info(b));
}
+#if 1
/* mark `a' and remember (default behavior) */
- if (!RVALUE_REMEMBERED(a)) {
+ if (!rgengc_remembered(objspace, a)) {
RB_VM_LOCK_ENTER_NO_BARRIER();
{
rgengc_remember(objspace, a);
@@ -9062,11 +8954,25 @@ gc_writebarrier_generational(VALUE a, VALUE b, rb_objspace_t *objspace)
RB_VM_LOCK_LEAVE_NO_BARRIER();
gc_report(1, objspace, "gc_writebarrier_generational: %s (remembered) -> %s\n", obj_info(a), obj_info(b));
}
+#else
+ /* mark `b' and remember */
+ MARK_IN_BITMAP(GET_HEAP_MARK_BITS(b), b);
+ if (RVALUE_WB_UNPROTECTED(b)) {
+ gc_remember_unprotected(objspace, b);
+ }
+ else {
+ RVALUE_AGE_SET_OLD(objspace, b);
+ rgengc_remember(objspace, b);
+ }
+
+ gc_report(1, objspace, "gc_writebarrier_generational: %s -> %s (remembered)\n", obj_info(a), obj_info(b));
+#endif
check_rvalue_consistency(a);
check_rvalue_consistency(b);
}
+#if GC_ENABLE_INCREMENTAL_MARK
static void
gc_mark_from(rb_objspace_t *objspace, VALUE obj, VALUE parent)
{
@@ -9092,7 +8998,18 @@ gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t *objspace)
}
}
else if (RVALUE_OLD_P(a) && !RVALUE_OLD_P(b)) {
- rgengc_remember(objspace, a);
+ if (!RVALUE_WB_UNPROTECTED(b)) {
+ gc_report(1, objspace, "gc_writebarrier_incremental: [GN] %p -> %s\n", (void *)a, obj_info(b));
+ RVALUE_AGE_SET_OLD(objspace, b);
+
+ if (RVALUE_BLACK_P(b)) {
+ gc_grey(objspace, b);
+ }
+ }
+ else {
+ gc_report(1, objspace, "gc_writebarrier_incremental: [LL] %p -> %s\n", (void *)a, obj_info(b));
+ gc_remember_unprotected(objspace, b);
+ }
}
if (UNLIKELY(objspace->flags.during_compacting)) {
@@ -9100,6 +9017,9 @@ gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t *objspace)
}
}
}
+#else
+#define gc_writebarrier_incremental(a, b, objspace)
+#endif
void
rb_gc_writebarrier(VALUE a, VALUE b)
@@ -9149,7 +9069,7 @@ rb_gc_writebarrier_unprotect(VALUE obj)
rb_objspace_t *objspace = &rb_objspace;
gc_report(2, objspace, "rb_gc_writebarrier_unprotect: %s %s\n", obj_info(obj),
- RVALUE_REMEMBERED(obj) ? " (already remembered)" : "");
+ rgengc_remembered(objspace, obj) ? " (already remembered)" : "");
RB_VM_LOCK_ENTER_NO_BARRIER();
{
@@ -9180,7 +9100,7 @@ rb_gc_writebarrier_unprotect(VALUE obj)
/*
* remember `obj' if needed.
*/
-void
+MJIT_FUNC_EXPORTED void
rb_gc_writebarrier_remember(VALUE obj)
{
rb_objspace_t *objspace = &rb_objspace;
@@ -9199,6 +9119,49 @@ rb_gc_writebarrier_remember(VALUE obj)
}
}
+static st_table *rgengc_unprotect_logging_table;
+
+static int
+rgengc_unprotect_logging_exit_func_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ fprintf(stderr, "%s\t%"PRIuVALUE"\n", (char *)key, (VALUE)val);
+ return ST_CONTINUE;
+}
+
+static void
+rgengc_unprotect_logging_exit_func(void)
+{
+ st_foreach(rgengc_unprotect_logging_table, rgengc_unprotect_logging_exit_func_i, 0);
+}
+
+void
+rb_gc_unprotect_logging(void *objptr, const char *filename, int line)
+{
+ VALUE obj = (VALUE)objptr;
+
+ if (rgengc_unprotect_logging_table == 0) {
+ rgengc_unprotect_logging_table = st_init_strtable();
+ atexit(rgengc_unprotect_logging_exit_func);
+ }
+
+ if (RVALUE_WB_UNPROTECTED(obj) == 0) {
+ char buff[0x100];
+ st_data_t cnt = 1;
+ char *ptr = buff;
+
+ snprintf(ptr, 0x100 - 1, "%s|%s:%d", obj_info(obj), filename, line);
+
+ if (st_lookup(rgengc_unprotect_logging_table, (st_data_t)ptr, &cnt)) {
+ cnt++;
+ }
+ else {
+ ptr = (strdup)(buff);
+ if (!ptr) rb_memerror();
+ }
+ st_insert(rgengc_unprotect_logging_table, (st_data_t)ptr, cnt);
+ }
+}
+
void
rb_copy_wb_protected_attribute(VALUE dest, VALUE obj)
{
@@ -9207,7 +9170,7 @@ rb_copy_wb_protected_attribute(VALUE dest, VALUE obj)
if (RVALUE_WB_UNPROTECTED(obj) && !RVALUE_WB_UNPROTECTED(dest)) {
if (!RVALUE_OLD_P(dest)) {
MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(dest), dest);
- RVALUE_AGE_RESET(dest);
+ RVALUE_AGE_RESET_RAW(dest);
}
else {
RVALUE_DEMOTE(objspace, dest);
@@ -9263,7 +9226,9 @@ rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
void
rb_gc_ractor_newobj_cache_clear(rb_ractor_newobj_cache_t *newobj_cache)
{
+#if GC_ENABLE_INCREMENTAL_MARK
newobj_cache->incremental_mark_step_allocated_slots = 0;
+#endif
for (size_t size_pool_idx = 0; size_pool_idx < SIZE_POOL_COUNT; size_pool_idx++) {
rb_ractor_newobj_size_pool_cache_t *cache = &newobj_cache->size_pool_caches[size_pool_idx];
@@ -9329,9 +9294,9 @@ rb_gc_register_address(VALUE *addr)
*/
RB_GC_GUARD(obj);
if (0 && !SPECIAL_CONST_P(obj)) {
- rb_warn("Object is assigned to registering address already: %"PRIsVALUE,
- rb_obj_class(obj));
- rb_print_backtrace(stderr);
+ rb_warn("Object is assigned to registering address already: %"PRIsVALUE,
+ rb_obj_class(obj));
+ rb_print_backtrace();
}
}
@@ -9498,10 +9463,21 @@ static int
gc_start(rb_objspace_t *objspace, unsigned int reason)
{
unsigned int do_full_mark = !!(reason & GPR_FLAG_FULL_MARK);
+#if GC_ENABLE_INCREMENTAL_MARK
+ unsigned int immediate_mark = reason & GPR_FLAG_IMMEDIATE_MARK;
+#endif
/* reason may be clobbered, later, so keep set immediate_sweep here */
objspace->flags.immediate_sweep = !!(reason & GPR_FLAG_IMMEDIATE_SWEEP);
+ /* Explicitly enable compaction (GC.compact) */
+ if (do_full_mark && ruby_enable_autocompact) {
+ objspace->flags.during_compacting = TRUE;
+ }
+ else {
+ objspace->flags.during_compacting = !!(reason & GPR_FLAG_COMPACT);
+ }
+
if (!heap_allocated_pages) return FALSE; /* heap is not ready */
if (!(reason & GPR_FLAG_METHOD) && !ready_to_gc(objspace)) return TRUE; /* GC is not allowed */
@@ -9525,41 +9501,31 @@ gc_start(rb_objspace_t *objspace, unsigned int reason)
objspace->flags.immediate_sweep = !(flag & (1<<gc_stress_no_immediate_sweep));
}
+ else {
+ if (objspace->rgengc.need_major_gc) {
+ reason |= objspace->rgengc.need_major_gc;
+ do_full_mark = TRUE;
+ }
+ else if (RGENGC_FORCE_MAJOR_GC) {
+ reason = GPR_FLAG_MAJOR_BY_FORCE;
+ do_full_mark = TRUE;
+ }
- if (objspace->rgengc.need_major_gc) {
- reason |= objspace->rgengc.need_major_gc;
- do_full_mark = TRUE;
+ objspace->rgengc.need_major_gc = GPR_FLAG_NONE;
}
- else if (RGENGC_FORCE_MAJOR_GC) {
- reason = GPR_FLAG_MAJOR_BY_FORCE;
- do_full_mark = TRUE;
- }
-
- objspace->rgengc.need_major_gc = GPR_FLAG_NONE;
if (do_full_mark && (reason & GPR_FLAG_MAJOR_MASK) == 0) {
reason |= GPR_FLAG_MAJOR_BY_FORCE; /* GC by CAPI, METHOD, and so on. */
}
- if (objspace->flags.dont_incremental ||
- reason & GPR_FLAG_IMMEDIATE_MARK ||
- ruby_gc_stressful) {
+#if GC_ENABLE_INCREMENTAL_MARK
+ if (!GC_ENABLE_INCREMENTAL_MARK || objspace->flags.dont_incremental || immediate_mark) {
objspace->flags.during_incremental_marking = FALSE;
}
else {
objspace->flags.during_incremental_marking = do_full_mark;
}
-
- /* Explicitly enable compaction (GC.compact) */
- if (do_full_mark && ruby_enable_autocompact) {
- objspace->flags.during_compacting = TRUE;
-#if RGENGC_CHECK_MODE
- objspace->rcompactor.compare_func = ruby_autocompact_compare_func;
#endif
- }
- else {
- objspace->flags.during_compacting = !!(reason & GPR_FLAG_COMPACT);
- }
if (!GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_incremental) {
objspace->flags.immediate_sweep = TRUE;
@@ -9594,21 +9560,18 @@ gc_start(rb_objspace_t *objspace, unsigned int reason)
objspace->profile.count++;
objspace->profile.latest_gc_info = reason;
- objspace->profile.total_allocated_objects_at_gc_start = total_allocated_objects(objspace);
+ objspace->profile.total_allocated_objects_at_gc_start = objspace->total_allocated_objects;
objspace->profile.heap_used_at_gc_start = heap_allocated_pages;
- objspace->profile.weak_references_count = 0;
- objspace->profile.retained_weak_references_count = 0;
gc_prof_setup_new_record(objspace, reason);
gc_reset_malloc_info(objspace, do_full_mark);
+ rb_transient_heap_start_marking(do_full_mark);
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_START, 0 /* TODO: pass minor/immediate flag? */);
GC_ASSERT(during_gc);
gc_prof_timer_start(objspace);
{
- if (gc_marks(objspace, do_full_mark)) {
- gc_sweep(objspace);
- }
+ gc_marks(objspace, do_full_mark);
}
gc_prof_timer_stop(objspace);
@@ -9629,19 +9592,11 @@ gc_rest(rb_objspace_t *objspace)
if (RGENGC_CHECK_MODE >= 2) gc_verify_internal_consistency(objspace);
if (is_incremental_marking(objspace)) {
- gc_marking_enter(objspace);
gc_marks_rest(objspace);
- gc_marking_exit(objspace);
-
- gc_sweep(objspace);
}
-
if (is_lazy_sweeping(objspace)) {
- gc_sweeping_enter(objspace);
gc_sweep_rest(objspace);
- gc_sweeping_exit(objspace);
}
-
gc_exit(objspace, gc_enter_event_rest, &lock_lev);
}
}
@@ -9658,7 +9613,9 @@ gc_current_status_fill(rb_objspace_t *objspace, char *buff)
if (is_marking(objspace)) {
buff[i++] = 'M';
if (is_full_marking(objspace)) buff[i++] = 'F';
+#if GC_ENABLE_INCREMENTAL_MARK
if (is_incremental_marking(objspace)) buff[i++] = 'I';
+#endif
}
else if (is_sweeping(objspace)) {
buff[i++] = 'S';
@@ -9730,7 +9687,8 @@ gc_enter_event_cstr(enum gc_enter_event event)
{
switch (event) {
case gc_enter_event_start: return "start";
- case gc_enter_event_continue: return "continue";
+ case gc_enter_event_mark_continue: return "mark_continue";
+ case gc_enter_event_sweep_continue: return "sweep_continue";
case gc_enter_event_rest: return "rest";
case gc_enter_event_finalizer: return "finalizer";
case gc_enter_event_rb_memerror: return "rb_memerror";
@@ -9743,37 +9701,71 @@ gc_enter_count(enum gc_enter_event event)
{
switch (event) {
case gc_enter_event_start: RB_DEBUG_COUNTER_INC(gc_enter_start); break;
- case gc_enter_event_continue: RB_DEBUG_COUNTER_INC(gc_enter_continue); break;
+ case gc_enter_event_mark_continue: RB_DEBUG_COUNTER_INC(gc_enter_mark_continue); break;
+ case gc_enter_event_sweep_continue: RB_DEBUG_COUNTER_INC(gc_enter_sweep_continue); break;
case gc_enter_event_rest: RB_DEBUG_COUNTER_INC(gc_enter_rest); break;
case gc_enter_event_finalizer: RB_DEBUG_COUNTER_INC(gc_enter_finalizer); break;
case gc_enter_event_rb_memerror: /* nothing */ break;
}
}
+#ifndef MEASURE_GC
+#define MEASURE_GC (objspace->flags.measure_gc)
+#endif
+
+static bool
+gc_enter_event_measure_p(rb_objspace_t *objspace, enum gc_enter_event event)
+{
+ if (!MEASURE_GC) return false;
+
+ switch (event) {
+ case gc_enter_event_start:
+ case gc_enter_event_mark_continue:
+ case gc_enter_event_sweep_continue:
+ case gc_enter_event_rest:
+ return true;
+
+ default:
+ // case gc_enter_event_finalizer:
+ // case gc_enter_event_rb_memerror:
+ return false;
+ }
+}
+
static bool current_process_time(struct timespec *ts);
static void
-gc_clock_start(struct timespec *ts)
+gc_enter_clock(rb_objspace_t *objspace, enum gc_enter_event event)
{
- if (!current_process_time(ts)) {
- ts->tv_sec = 0;
- ts->tv_nsec = 0;
+ if (gc_enter_event_measure_p(objspace, event)) {
+ if (!current_process_time(&objspace->profile.start_time)) {
+ objspace->profile.start_time.tv_sec = 0;
+ objspace->profile.start_time.tv_nsec = 0;
+ }
}
}
-static uint64_t
-gc_clock_end(struct timespec *ts)
+static void
+gc_exit_clock(rb_objspace_t *objspace, enum gc_enter_event event)
{
- struct timespec end_time;
+ if (gc_enter_event_measure_p(objspace, event)) {
+ struct timespec end_time;
- if ((ts->tv_sec > 0 || ts->tv_nsec > 0) &&
- current_process_time(&end_time) &&
- end_time.tv_sec >= ts->tv_sec) {
- return (uint64_t)(end_time.tv_sec - ts->tv_sec) * (1000 * 1000 * 1000) +
- (end_time.tv_nsec - ts->tv_nsec);
- }
+ if ((objspace->profile.start_time.tv_sec > 0 ||
+ objspace->profile.start_time.tv_nsec > 0) &&
+ current_process_time(&end_time)) {
- return 0;
+ if (end_time.tv_sec < objspace->profile.start_time.tv_sec) {
+ return; // ignore
+ }
+ else {
+ uint64_t ns =
+ (uint64_t)(end_time.tv_sec - objspace->profile.start_time.tv_sec) * (1000 * 1000 * 1000) +
+ (end_time.tv_nsec - objspace->profile.start_time.tv_nsec);
+ objspace->profile.total_time_ns += ns;
+ }
+ }
+ }
}
static inline void
@@ -9781,12 +9773,14 @@ gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_
{
RB_VM_LOCK_ENTER_LEV(lock_lev);
+ gc_enter_clock(objspace, event);
+
switch (event) {
case gc_enter_event_rest:
if (!is_marking(objspace)) break;
// fall through
case gc_enter_event_start:
- case gc_enter_event_continue:
+ case gc_enter_event_mark_continue:
// stop other ractors
rb_vm_barrier();
break;
@@ -9810,57 +9804,22 @@ gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_l
{
GC_ASSERT(during_gc != 0);
- gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_EXIT, 0); /* TODO: which parameter should be passed? */
+ gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_EXIT, 0); /* TODO: which parameter should be passsed? */
gc_record(objspace, 1, gc_enter_event_cstr(event));
RUBY_DEBUG_LOG("%s (%s)", gc_enter_event_cstr(event), gc_current_status(objspace));
gc_report(1, objspace, "gc_exit: %s [%s]\n", gc_enter_event_cstr(event), gc_current_status(objspace));
during_gc = FALSE;
+ gc_exit_clock(objspace, event);
RB_VM_LOCK_LEAVE_LEV(lock_lev);
-}
-#ifndef MEASURE_GC
-#define MEASURE_GC (objspace->flags.measure_gc)
-#endif
-
-static void
-gc_marking_enter(rb_objspace_t *objspace)
-{
- GC_ASSERT(during_gc != 0);
-
- if (MEASURE_GC) {
- gc_clock_start(&objspace->profile.marking_start_time);
- }
-}
-
-static void
-gc_marking_exit(rb_objspace_t *objspace)
-{
- GC_ASSERT(during_gc != 0);
-
- if (MEASURE_GC) {
- objspace->profile.marking_time_ns += gc_clock_end(&objspace->profile.marking_start_time);
- }
-}
-
-static void
-gc_sweeping_enter(rb_objspace_t *objspace)
-{
- GC_ASSERT(during_gc != 0);
-
- if (MEASURE_GC) {
- gc_clock_start(&objspace->profile.sweeping_start_time);
- }
-}
-
-static void
-gc_sweeping_exit(rb_objspace_t *objspace)
-{
- GC_ASSERT(during_gc != 0);
-
- if (MEASURE_GC) {
- objspace->profile.sweeping_time_ns += gc_clock_end(&objspace->profile.sweeping_start_time);
+#if RGENGC_CHECK_MODE >= 2
+ if (event == gc_enter_event_sweep_continue && gc_mode(objspace) == gc_mode_none) {
+ GC_ASSERT(!during_gc);
+ // sweep finished
+ gc_verify_internal_consistency(objspace);
}
+#endif
}
static void *
@@ -9892,31 +9851,6 @@ garbage_collect_with_gvl(rb_objspace_t *objspace, unsigned int reason)
}
}
-static int
-gc_set_candidate_object_i(void *vstart, void *vend, size_t stride, void *data)
-{
- rb_objspace_t *objspace = &rb_objspace;
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- switch (BUILTIN_TYPE(v)) {
- case T_NONE:
- case T_ZOMBIE:
- break;
- case T_STRING:
- // precompute the string coderange. This both save time for when it will be
- // eventually needed, and avoid mutating heap pages after a potential fork.
- rb_enc_str_coderange(v);
- // fall through
- default:
- if (!RVALUE_OLD_P(v) && !RVALUE_WB_UNPROTECTED(v)) {
- RVALUE_AGE_SET_CANDIDATE(objspace, v);
- }
- }
- }
-
- return 0;
-}
-
static VALUE
gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE immediate_mark, VALUE immediate_sweep, VALUE compact)
{
@@ -9944,61 +9878,6 @@ gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE
return Qnil;
}
-static void
-free_empty_pages(void)
-{
- rb_objspace_t *objspace = &rb_objspace;
-
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- /* Move all empty pages to the tomb heap for freeing. */
- rb_size_pool_t *size_pool = &size_pools[i];
- rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
- rb_heap_t *tomb_heap = SIZE_POOL_TOMB_HEAP(size_pool);
-
- size_t freed_pages = 0;
-
- struct heap_page **next_page_ptr = &heap->free_pages;
- struct heap_page *page = heap->free_pages;
- while (page) {
- /* All finalizers should have been ran in gc_start_internal, so there
- * should be no objects that require finalization. */
- GC_ASSERT(page->final_slots == 0);
-
- struct heap_page *next_page = page->free_next;
-
- if (page->free_slots == page->total_slots) {
- heap_unlink_page(objspace, heap, page);
- heap_add_page(objspace, size_pool, tomb_heap, page);
- freed_pages++;
- }
- else {
- *next_page_ptr = page;
- next_page_ptr = &page->free_next;
- }
-
- page = next_page;
- }
-
- *next_page_ptr = NULL;
-
- size_pool_allocatable_pages_set(objspace, size_pool, size_pool->allocatable_pages + freed_pages);
- }
-
- heap_pages_free_unused_pages(objspace);
-}
-
-void
-rb_gc_prepare_heap(void)
-{
- rb_objspace_each_objects(gc_set_candidate_object_i, NULL);
- gc_start_internal(NULL, Qtrue, Qtrue, Qtrue, Qtrue, Qtrue);
- free_empty_pages();
-
-#if defined(HAVE_MALLOC_TRIM) && !defined(RUBY_ALTERNATIVE_MALLOC_HEADER)
- malloc_trim(0);
-#endif
-}
-
static int
gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj)
{
@@ -10039,9 +9918,9 @@ gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj)
* prevent the objects from being collected. This check prevents
* objects that are keys in the finalizer table from being moved
* without directly pinning them. */
- GC_ASSERT(st_is_member(finalizer_table, obj));
-
- return FALSE;
+ if (st_is_member(finalizer_table, obj)) {
+ return FALSE;
+ }
}
GC_ASSERT(RVALUE_MARKED(obj));
GC_ASSERT(!RVALUE_PINNED(obj));
@@ -10056,13 +9935,24 @@ gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj)
return FALSE;
}
+/* Used in places that could malloc, which can cause the GC to run. We need to
+ * temporarily disable the GC to allow the malloc to happen. */
+#define COULD_MALLOC_REGION_START() \
+ GC_ASSERT(during_gc); \
+ VALUE _already_disabled = rb_gc_disable_no_rest(); \
+ during_gc = false;
+
+#define COULD_MALLOC_REGION_END() \
+ during_gc = true; \
+ if (_already_disabled == Qfalse) rb_objspace_gc_enable(objspace);
+
static VALUE
gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, size_t slot_size)
{
int marked;
int wb_unprotected;
int uncollectible;
- int age;
+ int marking;
RVALUE *dest = (RVALUE *)free;
RVALUE *src = (RVALUE *)scan;
@@ -10071,28 +9961,25 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, s
GC_ASSERT(BUILTIN_TYPE(scan) != T_NONE);
GC_ASSERT(!MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(free), free));
- GC_ASSERT(!RVALUE_MARKING((VALUE)src));
-
/* Save off bits for current object. */
marked = rb_objspace_marked_object_p((VALUE)src);
wb_unprotected = RVALUE_WB_UNPROTECTED((VALUE)src);
uncollectible = RVALUE_UNCOLLECTIBLE((VALUE)src);
- bool remembered = RVALUE_REMEMBERED((VALUE)src);
- age = RVALUE_AGE_GET((VALUE)src);
+ marking = RVALUE_MARKING((VALUE)src);
/* Clear bits for eventual T_MOVED */
CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)src), (VALUE)src);
CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)src), (VALUE)src);
CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)src), (VALUE)src);
- CLEAR_IN_BITMAP(GET_HEAP_PAGE((VALUE)src)->remembered_bits, (VALUE)src);
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)src), (VALUE)src);
if (FL_TEST((VALUE)src, FL_EXIVAR)) {
/* Resizing the st table could cause a malloc */
- DURING_GC_COULD_MALLOC_REGION_START();
+ COULD_MALLOC_REGION_START();
{
rb_mv_generic_ivar((VALUE)src, (VALUE)dest);
}
- DURING_GC_COULD_MALLOC_REGION_END();
+ COULD_MALLOC_REGION_END();
}
st_data_t srcid = (st_data_t)src, id;
@@ -10102,12 +9989,12 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, s
if (st_lookup(objspace->obj_to_id_tbl, srcid, &id)) {
gc_report(4, objspace, "Moving object with seen id: %p -> %p\n", (void *)src, (void *)dest);
/* Resizing the st table could cause a malloc */
- DURING_GC_COULD_MALLOC_REGION_START();
+ COULD_MALLOC_REGION_START();
{
st_delete(objspace->obj_to_id_tbl, &srcid, 0);
st_insert(objspace->obj_to_id_tbl, (st_data_t)dest, id);
}
- DURING_GC_COULD_MALLOC_REGION_END();
+ COULD_MALLOC_REGION_END();
}
/* Move the object */
@@ -10121,14 +10008,13 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, s
}
memset(src, 0, src_slot_size);
- RVALUE_AGE_RESET((VALUE)src);
/* Set bits for object in new location */
- if (remembered) {
- MARK_IN_BITMAP(GET_HEAP_PAGE(dest)->remembered_bits, (VALUE)dest);
+ if (marking) {
+ MARK_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)dest), (VALUE)dest);
}
else {
- CLEAR_IN_BITMAP(GET_HEAP_PAGE(dest)->remembered_bits, (VALUE)dest);
+ CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)dest), (VALUE)dest);
}
if (marked) {
@@ -10152,7 +10038,6 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, s
CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)dest), (VALUE)dest);
}
- RVALUE_AGE_SET((VALUE)dest, age);
/* Assign forwarding address */
src->as.moved.flags = T_MOVED;
src->as.moved.dummy = Qundef;
@@ -10164,18 +10049,6 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t src_slot_size, s
#if GC_CAN_COMPILE_COMPACTION
static int
-compare_pinned_slots(const void *left, const void *right, void *dummy)
-{
- struct heap_page *left_page;
- struct heap_page *right_page;
-
- left_page = *(struct heap_page * const *)left;
- right_page = *(struct heap_page * const *)right;
-
- return left_page->pinned_slots - right_page->pinned_slots;
-}
-
-static int
compare_free_slots(const void *left, const void *right, void *dummy)
{
struct heap_page *left_page;
@@ -10188,7 +10061,7 @@ compare_free_slots(const void *left, const void *right, void *dummy)
}
static void
-gc_sort_heap_by_compare_func(rb_objspace_t *objspace, gc_compact_compare_func compare_func)
+gc_sort_heap_by_empty_slots(rb_objspace_t *objspace)
{
for (int j = 0; j < SIZE_POOL_COUNT; j++) {
rb_size_pool_t *size_pool = &size_pools[j];
@@ -10208,7 +10081,7 @@ gc_sort_heap_by_compare_func(rb_objspace_t *objspace, gc_compact_compare_func co
/* Sort the heap so "filled pages" are first. `heap_add_page` adds to the
* head of the list, so empty pages will end up at the start of the heap */
- ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_func, NULL);
+ ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_free_slots, NULL);
/* Reset the eden heap */
ccan_list_head_init(&SIZE_POOL_EDEN_HEAP(size_pool)->pages);
@@ -10229,10 +10102,13 @@ static void
gc_ref_update_array(rb_objspace_t * objspace, VALUE v)
{
if (ARY_SHARED_P(v)) {
+#if USE_RVARGC
VALUE old_root = RARRAY(v)->as.heap.aux.shared_root;
+#endif
UPDATE_IF_MOVED(objspace, RARRAY(v)->as.heap.aux.shared_root);
+#if USE_RVARGC
VALUE new_root = RARRAY(v)->as.heap.aux.shared_root;
// If the root is embedded and its location has changed
if (ARY_EMBED_P(new_root) && new_root != old_root) {
@@ -10240,46 +10116,54 @@ gc_ref_update_array(rb_objspace_t * objspace, VALUE v)
GC_ASSERT(RARRAY(v)->as.heap.ptr >= RARRAY(old_root)->as.ary);
RARRAY(v)->as.heap.ptr = RARRAY(new_root)->as.ary + offset;
}
+#endif
}
else {
long len = RARRAY_LEN(v);
if (len > 0) {
- VALUE *ptr = (VALUE *)RARRAY_CONST_PTR(v);
+ VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(v);
for (long i = 0; i < len; i++) {
UPDATE_IF_MOVED(objspace, ptr[i]);
}
}
+#if USE_RVARGC
if (rb_gc_obj_slot_size(v) >= rb_ary_size_as_embedded(v)) {
if (rb_ary_embeddable_p(v)) {
rb_ary_make_embedded(v);
}
}
+#endif
}
}
-static void gc_ref_update_table_values_only(rb_objspace_t *objspace, st_table *tbl);
-
static void
gc_ref_update_object(rb_objspace_t *objspace, VALUE v)
{
VALUE *ptr = ROBJECT_IVPTR(v);
if (rb_shape_obj_too_complex(v)) {
- gc_ref_update_table_values_only(objspace, ROBJECT_IV_HASH(v));
+ rb_gc_update_tbl_refs(ROBJECT_IV_HASH(v));
return;
}
+#if USE_RVARGC
size_t slot_size = rb_gc_obj_slot_size(v);
size_t embed_size = rb_obj_embedded_size(ROBJECT_IV_CAPACITY(v));
if (slot_size >= embed_size && !RB_FL_TEST_RAW(v, ROBJECT_EMBED)) {
// Object can be re-embedded
memcpy(ROBJECT(v)->as.ary, ptr, sizeof(VALUE) * ROBJECT_IV_COUNT(v));
RB_FL_SET_RAW(v, ROBJECT_EMBED);
- xfree(ptr);
+ if (ROBJ_TRANSIENT_P(v)) {
+ ROBJ_TRANSIENT_UNSET(v);
+ }
+ else {
+ xfree(ptr);
+ }
ptr = ROBJECT(v)->as.ary;
}
+#endif
for (uint32_t i = 0; i < ROBJECT_IV_COUNT(v); i++) {
UPDATE_IF_MOVED(objspace, ptr[i]);
@@ -10345,7 +10229,7 @@ hash_foreach_replace_value(st_data_t key, st_data_t value, st_data_t argp, int e
}
static void
-gc_ref_update_table_values_only(rb_objspace_t *objspace, st_table *tbl)
+gc_update_tbl_refs(rb_objspace_t * objspace, st_table *tbl)
{
if (!tbl || tbl->num_entries == 0) return;
@@ -10354,12 +10238,6 @@ gc_ref_update_table_values_only(rb_objspace_t *objspace, st_table *tbl)
}
}
-void
-rb_gc_ref_update_table_values_only(st_table *tbl)
-{
- gc_ref_update_table_values_only(&rb_objspace, tbl);
-}
-
static void
gc_update_table_refs(rb_objspace_t * objspace, st_table *tbl)
{
@@ -10370,7 +10248,7 @@ gc_update_table_refs(rb_objspace_t * objspace, st_table *tbl)
}
}
-/* Update MOVED references in a VALUE=>VALUE st_table */
+/* Update MOVED references in an st_table */
void
rb_gc_update_tbl_refs(st_table *ptr)
{
@@ -10412,6 +10290,7 @@ gc_ref_update_method_entry(rb_objspace_t *objspace, rb_method_entry_t *me)
return;
case VM_METHOD_TYPE_REFINED:
TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.refined.orig_me);
+ UPDATE_IF_MOVED(objspace, def->body.refined.owner);
break;
case VM_METHOD_TYPE_CFUNC:
case VM_METHOD_TYPE_ZSUPER:
@@ -10434,20 +10313,6 @@ gc_update_values(rb_objspace_t *objspace, long n, VALUE *values)
}
}
-void
-rb_gc_update_values(long n, VALUE *values)
-{
- gc_update_values(&rb_objspace, n, values);
-}
-
-static bool
-moved_or_living_object_strictly_p(rb_objspace_t *objspace, VALUE obj)
-{
- return obj &&
- is_pointer_to_heap(objspace, (void *)obj) &&
- (is_live_object(objspace, obj) || BUILTIN_TYPE(obj) == T_MOVED);
-}
-
static void
gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
{
@@ -10487,7 +10352,7 @@ gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
gc_ref_update_method_entry(objspace, &RANY(obj)->as.imemo.ment);
break;
case imemo_iseq:
- rb_iseq_mark_and_move((rb_iseq_t *)obj, true);
+ rb_iseq_update_references((rb_iseq_t *)obj);
break;
case imemo_ast:
rb_ast_update_references((rb_ast_t *)obj);
@@ -10495,18 +10360,17 @@ gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
case imemo_callcache:
{
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
-
- if (!cc->klass) {
- // already invalidated
- }
- else {
- if (moved_or_living_object_strictly_p(objspace, cc->klass) &&
- moved_or_living_object_strictly_p(objspace, (VALUE)cc->cme_)) {
- UPDATE_IF_MOVED(objspace, cc->klass);
- TYPED_UPDATE_IF_MOVED(objspace, struct rb_callable_method_entry_struct *, cc->cme_);
+ if (cc->klass) {
+ UPDATE_IF_MOVED(objspace, cc->klass);
+ if (!is_live_object(objspace, cc->klass)) {
+ *((VALUE *)(&cc->klass)) = (VALUE)0;
}
- else {
- vm_cc_invalidate(cc);
+ }
+
+ if (cc->cme_) {
+ TYPED_UPDATE_IF_MOVED(objspace, struct rb_callable_method_entry_struct *, cc->cme_);
+ if (!is_live_object(objspace, (VALUE)cc->cme_)) {
+ *((struct rb_callable_method_entry_struct **)(&cc->cme_)) = (struct rb_callable_method_entry_struct *)0;
}
}
}
@@ -10653,13 +10517,12 @@ update_cvc_tbl(rb_objspace_t *objspace, VALUE klass)
static enum rb_id_table_iterator_result
mark_cvc_tbl_i(VALUE cvc_entry, void *data)
{
- rb_objspace_t *objspace = (rb_objspace_t *)data;
struct rb_cvar_class_tbl_entry *entry;
entry = (struct rb_cvar_class_tbl_entry *)cvc_entry;
RUBY_ASSERT(entry->cref == 0 || (BUILTIN_TYPE((VALUE)entry->cref) == T_IMEMO && IMEMO_TYPE_P(entry->cref, imemo_cref)));
- gc_mark(objspace, (VALUE) entry->cref);
+ rb_gc_mark((VALUE) entry->cref);
return ID_TABLE_CONTINUE;
}
@@ -10732,47 +10595,35 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
gc_report(4, objspace, "update-refs: %p ->\n", (void *)obj);
- if (FL_TEST(obj, FL_EXIVAR)) {
- rb_ref_update_generic_ivar(obj);
- }
-
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
- if (FL_TEST(obj, FL_SINGLETON)) {
- UPDATE_IF_MOVED(objspace, RCLASS_ATTACHED_OBJECT(obj));
- }
- // Continue to the shared T_CLASS/T_MODULE
case T_MODULE:
if (RCLASS_SUPER((VALUE)obj)) {
UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
}
+ if (!RCLASS_EXT(obj)) break;
update_m_tbl(objspace, RCLASS_M_TBL(obj));
update_cc_tbl(objspace, obj);
update_cvc_tbl(objspace, obj);
update_superclasses(objspace, obj);
- if (rb_shape_obj_too_complex(obj)) {
- gc_ref_update_table_values_only(objspace, RCLASS_IV_HASH(obj));
- }
- else {
- for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) {
- UPDATE_IF_MOVED(objspace, RCLASS_IVPTR(obj)[i]);
- }
+ for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) {
+ UPDATE_IF_MOVED(objspace, RCLASS_IVPTR(obj)[i]);
}
update_class_ext(objspace, RCLASS_EXT(obj));
update_const_tbl(objspace, RCLASS_CONST_TBL(obj));
-
- UPDATE_IF_MOVED(objspace, RCLASS_EXT(obj)->classpath);
break;
case T_ICLASS:
- if (RICLASS_OWNS_M_TBL_P(obj)) {
+ if (FL_TEST(obj, RICLASS_IS_ORIGIN) &&
+ !FL_TEST(obj, RICLASS_ORIGIN_SHARED_MTBL)) {
update_m_tbl(objspace, RCLASS_M_TBL(obj));
}
if (RCLASS_SUPER((VALUE)obj)) {
UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
}
+ if (!RCLASS_EXT(obj)) break;
update_class_ext(objspace, RCLASS_EXT(obj));
update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
update_cc_tbl(objspace, obj);
@@ -10801,10 +10652,21 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
case T_STRING:
{
+#if USE_RVARGC
+#endif
+
if (STR_SHARED_P(obj)) {
+#if USE_RVARGC
+ VALUE old_root = any->as.string.as.heap.aux.shared;
+#endif
UPDATE_IF_MOVED(objspace, any->as.string.as.heap.aux.shared);
+#if USE_RVARGC
+ VALUE new_root = any->as.string.as.heap.aux.shared;
+ rb_str_update_shared_ary(obj, old_root, new_root);
+#endif
}
+#if USE_RVARGC
/* If, after move the string is not embedded, and can fit in the
* slot it's been placed in, then re-embed it. */
if (rb_gc_obj_slot_size(obj) >= rb_str_size_as_embedded(obj)) {
@@ -10812,24 +10674,16 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
rb_str_make_embedded(obj);
}
}
+#endif
break;
}
case T_DATA:
/* Call the compaction callback, if it exists */
{
- void *const ptr = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
+ void *const ptr = DATA_PTR(obj);
if (ptr) {
- if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(any->as.typeddata.type)) {
- size_t *offset_list = (size_t *)RANY(obj)->as.typeddata.type->function.dmark;
-
- for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) {
- VALUE *ref = (VALUE *)((char *)ptr + offset);
- if (SPECIAL_CONST_P(*ref)) continue;
- *ref = rb_gc_location(*ref);
- }
- }
- else if (RTYPEDDATA_P(obj)) {
+ if (RTYPEDDATA_P(obj)) {
RUBY_DATA_FUNC compact_func = any->as.typeddata.type->function.dcompact;
if (compact_func) (*compact_func)(ptr);
}
@@ -10916,7 +10770,7 @@ gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t * objspace,
VALUE v = (VALUE)vstart;
asan_unlock_freelist(page);
asan_lock_freelist(page);
- page->flags.has_uncollectible_wb_unprotected_objects = FALSE;
+ page->flags.has_uncollectible_shady_objects = FALSE;
page->flags.has_remembered_objects = FALSE;
/* For each object on the page */
@@ -10930,9 +10784,9 @@ gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t * objspace,
break;
default:
if (RVALUE_WB_UNPROTECTED(v)) {
- page->flags.has_uncollectible_wb_unprotected_objects = TRUE;
+ page->flags.has_uncollectible_shady_objects = TRUE;
}
- if (RVALUE_REMEMBERED(v)) {
+ if (RVALUE_PAGE_MARKING(page, v)) {
page->flags.has_remembered_objects = TRUE;
}
if (page->flags.before_sweep) {
@@ -10959,8 +10813,6 @@ extern rb_symbols_t ruby_global_symbols;
static void
gc_update_references(rb_objspace_t *objspace)
{
- objspace->flags.during_reference_updating = true;
-
rb_execution_context_t *ec = GET_EC();
rb_vm_t *vm = rb_ec_vm_ptr(ec);
@@ -10985,15 +10837,14 @@ gc_update_references(rb_objspace_t *objspace)
}
}
rb_vm_update_references(vm);
+ rb_transient_heap_update_references();
rb_gc_update_global_tbl();
global_symbols.ids = rb_gc_location(global_symbols.ids);
global_symbols.dsymbol_fstr_hash = rb_gc_location(global_symbols.dsymbol_fstr_hash);
- gc_ref_update_table_values_only(objspace, objspace->obj_to_id_tbl);
+ gc_update_tbl_refs(objspace, objspace->obj_to_id_tbl);
gc_update_table_refs(objspace, objspace->id_to_obj_tbl);
gc_update_table_refs(objspace, global_symbols.str_sym);
gc_update_table_refs(objspace, finalizer_table);
-
- objspace->flags.during_reference_updating = false;
}
#if GC_CAN_COMPILE_COMPACTION
@@ -11054,7 +10905,7 @@ static void
root_obj_check_moved_i(const char *category, VALUE obj, void *data)
{
if (gc_object_moved_p(&rb_objspace, obj)) {
- rb_bug("ROOT %s points to MOVED: %p -> %s", category, (void *)obj, obj_info(rb_gc_location(obj)));
+ rb_bug("ROOT %s points to MOVED: %p -> %s\n", category, (void *)obj, obj_info(rb_gc_location(obj)));
}
}
@@ -11063,7 +10914,7 @@ reachable_object_check_moved_i(VALUE ref, void *data)
{
VALUE parent = (VALUE)data;
if (gc_object_moved_p(&rb_objspace, ref)) {
- rb_bug("Object %s points to MOVED: %p -> %s", obj_info(parent), (void *)ref, obj_info(rb_gc_location(ref)));
+ rb_bug("Object %s points to MOVED: %p -> %s\n", obj_info(parent), (void *)ref, obj_info(rb_gc_location(ref)));
}
}
@@ -11128,39 +10979,6 @@ gc_compact(VALUE self)
#endif
#if GC_CAN_COMPILE_COMPACTION
-
-struct desired_compaction_pages_i_data {
- rb_objspace_t *objspace;
- size_t required_slots[SIZE_POOL_COUNT];
-};
-
-static int
-desired_compaction_pages_i(struct heap_page *page, void *data)
-{
- struct desired_compaction_pages_i_data *tdata = data;
- rb_objspace_t *objspace = tdata->objspace;
- VALUE vstart = (VALUE)page->start;
- VALUE vend = vstart + (VALUE)(page->total_slots * page->size_pool->slot_size);
-
-
- for (VALUE v = vstart; v != vend; v += page->size_pool->slot_size) {
- /* skip T_NONEs; they won't be moved */
- void *poisoned = asan_unpoison_object_temporary(v);
- if (BUILTIN_TYPE(v) == T_NONE) {
- if (poisoned) {
- asan_poison_object(v);
- }
- continue;
- }
-
- rb_size_pool_t *dest_pool = gc_compact_destination_pool(objspace, page->size_pool, v);
- size_t dest_pool_idx = dest_pool - size_pools;
- tdata->required_slots[dest_pool_idx]++;
- }
-
- return 0;
-}
-
static VALUE
gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE double_heap, VALUE expand_heap, VALUE toward_empty)
{
@@ -11168,6 +10986,7 @@ gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE do
/* Clear the heap. */
gc_start_internal(NULL, self, Qtrue, Qtrue, Qtrue, Qfalse);
+ size_t growth_slots = gc_params.heap_init_slots;
if (RTEST(double_heap)) {
rb_warn("double_heap is deprecated, please use expand_heap instead");
@@ -11178,59 +10997,23 @@ gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE do
gc_rest(objspace);
/* if both double_heap and expand_heap are set, expand_heap takes precedence */
- if (RTEST(expand_heap)) {
- struct desired_compaction_pages_i_data desired_compaction = {
- .objspace = objspace,
- .required_slots = {0},
- };
- /* Work out how many objects want to be in each size pool, taking account of moves */
- objspace_each_pages(objspace, desired_compaction_pages_i, &desired_compaction, TRUE);
-
- /* Find out which pool has the most pages */
- size_t max_existing_pages = 0;
- for(int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
- rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
- max_existing_pages = MAX(max_existing_pages, heap->total_pages);
- }
- /* Add pages to each size pool so that compaction is guaranteed to move every object */
+ if (RTEST(double_heap) || RTEST(expand_heap)) {
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
rb_size_pool_t *size_pool = &size_pools[i];
rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
- size_t pages_to_add = 0;
- /*
- * Step 1: Make sure every pool has the same number of pages, by adding empty pages
- * to smaller pools. This is required to make sure the compact cursor can advance
- * through all of the pools in `gc_sweep_compact` without hitting the "sweep &
- * compact cursors met" condition on some pools before fully compacting others
- */
- pages_to_add += max_existing_pages - heap->total_pages;
- /*
- * Step 2: Now add additional free pages to each size pool sufficient to hold all objects
- * that want to be in that size pool, whether moved into it or moved within it
- */
- pages_to_add += slots_to_pages_for_size_pool(objspace, size_pool, desired_compaction.required_slots[i]);
- /*
- * Step 3: Add two more pages so that the compact & sweep cursors will meet _after_ all objects
- * have been moved, and not on the last iteration of the `gc_sweep_compact` loop
- */
- pages_to_add += 2;
-
- heap_add_pages(objspace, size_pool, heap, pages_to_add);
- }
- }
- else if (RTEST(double_heap)) {
- for (int i = 0; i < SIZE_POOL_COUNT; i++) {
- rb_size_pool_t *size_pool = &size_pools[i];
- rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool);
- heap_add_pages(objspace, size_pool, heap, heap->total_pages);
+ if (RTEST(expand_heap)) {
+ size_t required_pages = growth_slots / size_pool->slot_size;
+ heap_add_pages(objspace, size_pool, heap, MAX(required_pages, heap->total_pages));
+ }
+ else {
+ heap_add_pages(objspace, size_pool, heap, heap->total_pages);
+ }
}
-
}
if (RTEST(toward_empty)) {
- objspace->rcompactor.compare_func = compare_free_slots;
+ gc_sort_heap_by_empty_slots(objspace);
}
}
RB_VM_LOCK_LEAVE();
@@ -11240,7 +11023,6 @@ gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE do
objspace_reachable_objects_from_root(objspace, root_obj_check_moved_i, NULL);
objspace_each_objects(objspace, heap_check_moved_i, NULL, TRUE);
- objspace->rcompactor.compare_func = NULL;
return gc_compact_stats(self);
}
#else
@@ -11257,7 +11039,7 @@ rb_gc_start(void)
void
rb_gc(void)
{
- unless_objspace(objspace) { return; }
+ rb_objspace_t *objspace = &rb_objspace;
unsigned int reason = GPR_DEFAULT_REASON;
garbage_collect(objspace, reason);
}
@@ -11265,7 +11047,7 @@ rb_gc(void)
int
rb_during_gc(void)
{
- unless_objspace(objspace) { return FALSE; }
+ rb_objspace_t *objspace = &rb_objspace;
return during_gc;
}
@@ -11308,7 +11090,6 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const unsigned
#endif
static VALUE sym_newobj, sym_malloc, sym_method, sym_capi;
static VALUE sym_none, sym_marking, sym_sweeping;
- static VALUE sym_weak_references_count, sym_retained_weak_references_count;
VALUE hash = Qnil, key = Qnil;
VALUE major_by, need_major_by;
unsigned int flags = orig_flags ? orig_flags : objspace->profile.latest_gc_info;
@@ -11348,9 +11129,6 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const unsigned
S(none);
S(marking);
S(sweeping);
-
- S(weak_references_count);
- S(retained_weak_references_count);
#undef S
}
@@ -11401,9 +11179,6 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const unsigned
SET(state, gc_mode(objspace) == gc_mode_none ? sym_none :
gc_mode(objspace) == gc_mode_marking ? sym_marking : sym_sweeping);
}
-
- SET(weak_references_count, LONG2FIX(objspace->profile.weak_references_count));
- SET(retained_weak_references_count, LONG2FIX(objspace->profile.retained_weak_references_count));
#undef SET
if (!NIL_P(key)) {/* matched key should return above */
@@ -11438,8 +11213,6 @@ gc_latest_gc_info(rb_execution_context_t *ec, VALUE self, VALUE arg)
enum gc_stat_sym {
gc_stat_sym_count,
gc_stat_sym_time,
- gc_stat_sym_marking_time,
- gc_stat_sym_sweeping_time,
gc_stat_sym_heap_allocated_pages,
gc_stat_sym_heap_sorted_length,
gc_stat_sym_heap_allocatable_pages,
@@ -11469,7 +11242,6 @@ enum gc_stat_sym {
gc_stat_sym_oldmalloc_increase_bytes,
gc_stat_sym_oldmalloc_increase_bytes_limit,
#endif
- gc_stat_sym_weak_references_count,
#if RGENGC_PROFILE
gc_stat_sym_total_generated_normal_object_count,
gc_stat_sym_total_generated_shady_object_count,
@@ -11490,8 +11262,6 @@ setup_gc_stat_symbols(void)
#define S(s) gc_stat_symbols[gc_stat_sym_##s] = ID2SYM(rb_intern_const(#s))
S(count);
S(time);
- S(marking_time),
- S(sweeping_time),
S(heap_allocated_pages);
S(heap_sorted_length);
S(heap_allocatable_pages);
@@ -11521,7 +11291,6 @@ setup_gc_stat_symbols(void)
S(oldmalloc_increase_bytes);
S(oldmalloc_increase_bytes_limit);
#endif
- S(weak_references_count);
#if RGENGC_PROFILE
S(total_generated_normal_object_count);
S(total_generated_shady_object_count);
@@ -11534,12 +11303,6 @@ setup_gc_stat_symbols(void)
}
}
-static uint64_t
-ns_to_ms(uint64_t ns)
-{
- return ns / (1000 * 1000);
-}
-
static size_t
gc_stat_internal(VALUE hash_or_sym)
{
@@ -11565,9 +11328,7 @@ gc_stat_internal(VALUE hash_or_sym)
rb_hash_aset(hash, gc_stat_symbols[gc_stat_sym_##name], SIZET2NUM(attr));
SET(count, objspace->profile.count);
- SET(time, (size_t)ns_to_ms(objspace->profile.marking_time_ns + objspace->profile.sweeping_time_ns)); // TODO: UINT64T2NUM
- SET(marking_time, (size_t)ns_to_ms(objspace->profile.marking_time_ns));
- SET(sweeping_time, (size_t)ns_to_ms(objspace->profile.sweeping_time_ns));
+ SET(time, (size_t) (objspace->profile.total_time_ns / (1000 * 1000) /* ns -> ms */)); // TODO: UINT64T2NUM
/* implementation dependent counters */
SET(heap_allocated_pages, heap_allocated_pages);
@@ -11582,8 +11343,8 @@ gc_stat_internal(VALUE hash_or_sym)
SET(heap_tomb_pages, heap_tomb_total_pages(objspace));
SET(total_allocated_pages, total_allocated_pages(objspace));
SET(total_freed_pages, total_freed_pages(objspace));
- SET(total_allocated_objects, total_allocated_objects(objspace));
- SET(total_freed_objects, total_freed_objects(objspace));
+ SET(total_allocated_objects, objspace->total_allocated_objects);
+ SET(total_freed_objects, objspace->profile.total_freed_objects);
SET(malloc_increase_bytes, malloc_increase);
SET(malloc_increase_bytes_limit, malloc_limit);
SET(minor_gc_count, objspace->profile.minor_gc_count);
@@ -11673,9 +11434,6 @@ enum gc_stat_heap_sym {
gc_stat_heap_sym_total_allocated_pages,
gc_stat_heap_sym_total_freed_pages,
gc_stat_heap_sym_force_major_gc_count,
- gc_stat_heap_sym_force_incremental_marking_finish_count,
- gc_stat_heap_sym_total_allocated_objects,
- gc_stat_heap_sym_total_freed_objects,
gc_stat_heap_sym_last
};
@@ -11695,9 +11453,6 @@ setup_gc_stat_heap_symbols(void)
S(total_allocated_pages);
S(total_freed_pages);
S(force_major_gc_count);
- S(force_incremental_marking_finish_count);
- S(total_allocated_objects);
- S(total_freed_objects);
#undef S
}
}
@@ -11741,9 +11496,6 @@ gc_stat_heap_internal(int size_pool_idx, VALUE hash_or_sym)
SET(total_allocated_pages, size_pool->total_allocated_pages);
SET(total_freed_pages, size_pool->total_freed_pages);
SET(force_major_gc_count, size_pool->force_major_gc_count);
- SET(force_incremental_marking_finish_count, size_pool->force_incremental_marking_finish_count);
- SET(total_allocated_objects, size_pool->total_allocated_objects);
- SET(total_freed_objects, size_pool->total_freed_objects);
#undef SET
if (!NIL_P(key)) { /* matched key should return above */
@@ -11898,18 +11650,6 @@ gc_set_auto_compact(VALUE _, VALUE v)
GC_ASSERT(GC_COMPACTION_SUPPORTED);
ruby_enable_autocompact = RTEST(v);
-
-#if RGENGC_CHECK_MODE
- ruby_autocompact_compare_func = NULL;
-
- if (SYMBOL_P(v)) {
- ID id = RB_SYM2ID(v);
- if (id == rb_intern("empty")) {
- ruby_autocompact_compare_func = compare_free_slots;
- }
- }
-#endif
-
return v;
}
#else
@@ -12039,20 +11779,14 @@ gc_set_initial_pages(rb_objspace_t *objspace)
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
rb_size_pool_t *size_pool = &size_pools[i];
- char env_key[sizeof("RUBY_GC_HEAP_" "_INIT_SLOTS") + DECIMAL_SIZE_OF_BITS(sizeof(int) * CHAR_BIT)];
- snprintf(env_key, sizeof(env_key), "RUBY_GC_HEAP_%d_INIT_SLOTS", i);
-
- size_t size_pool_init_slots = gc_params.size_pool_init_slots[i];
- if (get_envparam_size(env_key, &size_pool_init_slots, 0)) {
- gc_params.size_pool_init_slots[i] = size_pool_init_slots;
- }
- if (size_pool_init_slots > size_pool->eden_heap.total_slots) {
- size_t slots = size_pool_init_slots - size_pool->eden_heap.total_slots;
- size_pool->allocatable_pages = slots_to_pages_for_size_pool(objspace, size_pool, slots);
+ if (gc_params.heap_init_slots > size_pool->eden_heap.total_slots) {
+ size_t slots = gc_params.heap_init_slots - size_pool->eden_heap.total_slots;
+ int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
+ size_pool->allocatable_pages = slots * multiple / HEAP_PAGE_OBJ_LIMIT;
}
else {
- /* We already have more slots than size_pool_init_slots allows, so
+ /* We already have more slots than heap_init_slots allows, so
* prevent creating more pages. */
size_pool->allocatable_pages = 0;
}
@@ -12063,6 +11797,8 @@ gc_set_initial_pages(rb_objspace_t *objspace)
/*
* GC tuning environment variables
*
+ * * RUBY_GC_HEAP_INIT_SLOTS
+ * - Initial allocation slots.
* * RUBY_GC_HEAP_FREE_SLOTS
* - Prepare at least this amount of slots after GC.
* - Allocate slots if there are not enough slots.
@@ -12109,7 +11845,10 @@ ruby_gc_set_params(void)
/* ok */
}
- gc_set_initial_pages(objspace);
+ /* RUBY_GC_HEAP_INIT_SLOTS */
+ if (get_envparam_size("RUBY_GC_HEAP_INIT_SLOTS", &gc_params.heap_init_slots, 0)) {
+ gc_set_initial_pages(objspace);
+ }
get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0, 0.0, FALSE);
get_envparam_size ("RUBY_GC_HEAP_GROWTH_MAX_SLOTS", &gc_params.growth_max_slots, 0);
@@ -12120,7 +11859,6 @@ ruby_gc_set_params(void)
get_envparam_double("RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO", &gc_params.heap_free_slots_goal_ratio,
gc_params.heap_free_slots_min_ratio, gc_params.heap_free_slots_max_ratio, TRUE);
get_envparam_double("RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR", &gc_params.oldobject_limit_factor, 0.0, 0.0, TRUE);
- get_envparam_double("RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO", &gc_params.uncollectible_wb_unprotected_objects_limit_ratio, 0.0, 0.0, TRUE);
if (get_envparam_size("RUBY_GC_MALLOC_LIMIT", &gc_params.malloc_limit_min, 0)) {
malloc_limit = gc_params.malloc_limit_min;
@@ -12156,7 +11894,7 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *
{
if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
- if (is_markable_object(obj)) {
+ if (is_markable_object(objspace, obj)) {
rb_ractor_t *cr = GET_RACTOR();
struct gc_mark_func_data_struct mfd = {
.mark_func = func,
@@ -12532,7 +12270,7 @@ malloc_during_gc_p(rb_objspace_t *objspace)
* (since ractors can run while another thread is sweeping) and when we
* have the GVL (since if we don't have the GVL, we'll try to acquire the
* GVL which will block and ensure the other thread finishes GC). */
- return during_gc && !dont_gc_val() && !rb_multi_ractor_p() && ruby_thread_has_gvl_p();
+ return during_gc && !rb_multi_ractor_p() && ruby_thread_has_gvl_p();
}
static inline void *
@@ -13099,8 +12837,7 @@ gc_malloc_allocations(VALUE self)
void
rb_gc_adjust_memory_usage(ssize_t diff)
{
- unless_objspace(objspace) { return; }
-
+ rb_objspace_t *objspace = &rb_objspace;
if (diff > 0) {
objspace_malloc_increase(objspace, 0, diff, 0, MEMOP_TYPE_REALLOC);
}
@@ -13110,6 +12847,573 @@ rb_gc_adjust_memory_usage(ssize_t diff)
}
/*
+ ------------------------------ WeakMap ------------------------------
+*/
+
+struct weakmap {
+ st_table *obj2wmap; /* obj -> [ref,...] */
+ st_table *wmap2obj; /* ref -> obj */
+ VALUE final;
+};
+
+#define WMAP_DELETE_DEAD_OBJECT_IN_MARK 0
+
+#if WMAP_DELETE_DEAD_OBJECT_IN_MARK
+static int
+wmap_mark_map(st_data_t key, st_data_t val, st_data_t arg)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)arg;
+ VALUE obj = (VALUE)val;
+ if (!is_live_object(objspace, obj)) return ST_DELETE;
+ return ST_CONTINUE;
+}
+#endif
+
+static int
+wmap_replace_ref(st_data_t *key, st_data_t *value, st_data_t _argp, int existing)
+{
+ *key = rb_gc_location((VALUE)*key);
+
+ VALUE *values = (VALUE *)*value;
+ VALUE size = values[0];
+
+ for (VALUE index = 1; index <= size; index++) {
+ values[index] = rb_gc_location(values[index]);
+ }
+
+ return ST_CONTINUE;
+}
+
+static int
+wmap_foreach_replace(st_data_t key, st_data_t value, st_data_t _argp, int error)
+{
+ if (rb_gc_location((VALUE)key) != (VALUE)key) {
+ return ST_REPLACE;
+ }
+
+ VALUE *values = (VALUE *)value;
+ VALUE size = values[0];
+
+ for (VALUE index = 1; index <= size; index++) {
+ VALUE val = values[index];
+ if (rb_gc_location(val) != val) {
+ return ST_REPLACE;
+ }
+ }
+
+ return ST_CONTINUE;
+}
+
+static void
+wmap_compact(void *ptr)
+{
+ struct weakmap *w = ptr;
+ if (w->wmap2obj) rb_gc_update_tbl_refs(w->wmap2obj);
+ if (w->obj2wmap) st_foreach_with_replace(w->obj2wmap, wmap_foreach_replace, wmap_replace_ref, (st_data_t)NULL);
+ w->final = rb_gc_location(w->final);
+}
+
+static void
+wmap_mark(void *ptr)
+{
+ struct weakmap *w = ptr;
+#if WMAP_DELETE_DEAD_OBJECT_IN_MARK
+ if (w->obj2wmap) st_foreach(w->obj2wmap, wmap_mark_map, (st_data_t)&rb_objspace);
+#endif
+ rb_gc_mark_movable(w->final);
+}
+
+static int
+wmap_free_map(st_data_t key, st_data_t val, st_data_t arg)
+{
+ VALUE *ptr = (VALUE *)val;
+ ruby_sized_xfree(ptr, (ptr[0] + 1) * sizeof(VALUE));
+ return ST_CONTINUE;
+}
+
+static void
+wmap_free(void *ptr)
+{
+ struct weakmap *w = ptr;
+ st_foreach(w->obj2wmap, wmap_free_map, 0);
+ st_free_table(w->obj2wmap);
+ st_free_table(w->wmap2obj);
+ xfree(w);
+}
+
+static int
+wmap_memsize_map(st_data_t key, st_data_t val, st_data_t arg)
+{
+ VALUE *ptr = (VALUE *)val;
+ *(size_t *)arg += (ptr[0] + 1) * sizeof(VALUE);
+ return ST_CONTINUE;
+}
+
+static size_t
+wmap_memsize(const void *ptr)
+{
+ size_t size;
+ const struct weakmap *w = ptr;
+ size = sizeof(*w);
+ size += st_memsize(w->obj2wmap);
+ size += st_memsize(w->wmap2obj);
+ st_foreach(w->obj2wmap, wmap_memsize_map, (st_data_t)&size);
+ return size;
+}
+
+static const rb_data_type_t weakmap_type = {
+ "weakmap",
+ {
+ wmap_mark,
+ wmap_free,
+ wmap_memsize,
+ wmap_compact,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static VALUE wmap_finalize(RB_BLOCK_CALL_FUNC_ARGLIST(objid, self));
+
+static VALUE
+wmap_allocate(VALUE klass)
+{
+ struct weakmap *w;
+ VALUE obj = TypedData_Make_Struct(klass, struct weakmap, &weakmap_type, w);
+ w->obj2wmap = rb_init_identtable();
+ w->wmap2obj = rb_init_identtable();
+ w->final = rb_func_lambda_new(wmap_finalize, obj, 1, 1);
+ return obj;
+}
+
+static int
+wmap_live_p(rb_objspace_t *objspace, VALUE obj)
+{
+ if (SPECIAL_CONST_P(obj)) return TRUE;
+ /* If is_pointer_to_heap returns false, the page could be in the tomb heap
+ * or have already been freed. */
+ if (!is_pointer_to_heap(objspace, (void *)obj)) return FALSE;
+
+ void *poisoned = asan_unpoison_object_temporary(obj);
+
+ enum ruby_value_type t = BUILTIN_TYPE(obj);
+ int ret = (!(t == T_NONE || t >= T_FIXNUM || t == T_ICLASS) &&
+ is_live_object(objspace, obj));
+
+ if (poisoned) {
+ asan_poison_object(obj);
+ }
+
+ return ret;
+}
+
+static int
+wmap_remove_inverse_ref(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
+{
+ if (!existing) return ST_STOP;
+
+ VALUE old_ref = (VALUE)arg;
+
+ VALUE *values = (VALUE *)*val;
+ VALUE size = values[0];
+
+ if (size == 1) {
+ // fast path, we only had one backref
+ RUBY_ASSERT(values[1] == old_ref);
+ ruby_sized_xfree(values, 2 * sizeof(VALUE));
+ return ST_DELETE;
+ }
+
+ bool found = false;
+ VALUE index = 1;
+ for (; index <= size; index++) {
+ if (values[index] == old_ref) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return ST_STOP;
+
+ if (size > index) {
+ MEMMOVE(&values[index], &values[index + 1], VALUE, size - index);
+ }
+
+ size -= 1;
+ values[0] = size;
+ SIZED_REALLOC_N(values, VALUE, size + 1, size + 2);
+ *val = (st_data_t)values;
+ return ST_CONTINUE;
+}
+
+/* :nodoc: */
+static VALUE
+wmap_finalize(RB_BLOCK_CALL_FUNC_ARGLIST(objid, self))
+{
+ st_data_t orig, wmap, data;
+ VALUE obj, *rids, i, size;
+ struct weakmap *w;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ /* Get reference from object id. */
+ if (UNDEF_P(obj = id2ref_obj_tbl(&rb_objspace, objid))) {
+ rb_bug("wmap_finalize: objid is not found.");
+ }
+
+ /* obj is original referenced object and/or weak reference. */
+ orig = (st_data_t)obj;
+ if (st_delete(w->obj2wmap, &orig, &data)) {
+ rids = (VALUE *)data;
+ size = *rids++;
+ for (i = 0; i < size; ++i) {
+ wmap = (st_data_t)rids[i];
+ st_delete(w->wmap2obj, &wmap, NULL);
+ }
+ ruby_sized_xfree((VALUE *)data, (size + 1) * sizeof(VALUE));
+ }
+
+ wmap = (st_data_t)obj;
+ if (st_delete(w->wmap2obj, &wmap, &orig)) {
+ wmap = (st_data_t)obj;
+ st_update(w->obj2wmap, orig, wmap_remove_inverse_ref, wmap);
+ }
+ return self;
+}
+
+struct wmap_iter_arg {
+ rb_objspace_t *objspace;
+ VALUE value;
+};
+
+static VALUE
+wmap_inspect_append(rb_objspace_t *objspace, VALUE str, VALUE obj)
+{
+ if (SPECIAL_CONST_P(obj)) {
+ return rb_str_append(str, rb_inspect(obj));
+ }
+ else if (wmap_live_p(objspace, obj)) {
+ return rb_str_append(str, rb_any_to_s(obj));
+ }
+ else {
+ return rb_str_catf(str, "#<collected:%p>", (void*)obj);
+ }
+}
+
+static int
+wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ struct wmap_iter_arg *argp = (struct wmap_iter_arg *)arg;
+ rb_objspace_t *objspace = argp->objspace;
+ VALUE str = argp->value;
+ VALUE k = (VALUE)key, v = (VALUE)val;
+
+ if (RSTRING_PTR(str)[0] == '#') {
+ rb_str_cat2(str, ", ");
+ }
+ else {
+ rb_str_cat2(str, ": ");
+ RSTRING_PTR(str)[0] = '#';
+ }
+ wmap_inspect_append(objspace, str, k);
+ rb_str_cat2(str, " => ");
+ wmap_inspect_append(objspace, str, v);
+
+ return ST_CONTINUE;
+}
+
+static VALUE
+wmap_inspect(VALUE self)
+{
+ VALUE str;
+ VALUE c = rb_class_name(CLASS_OF(self));
+ struct weakmap *w;
+ struct wmap_iter_arg args;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void *)self);
+ if (w->wmap2obj) {
+ args.objspace = &rb_objspace;
+ args.value = str;
+ st_foreach(w->wmap2obj, wmap_inspect_i, (st_data_t)&args);
+ }
+ RSTRING_PTR(str)[0] = '#';
+ rb_str_cat2(str, ">");
+ return str;
+}
+
+static inline bool
+wmap_live_entry_p(rb_objspace_t *objspace, st_data_t key, st_data_t val)
+{
+ return wmap_live_p(objspace, (VALUE)key) && wmap_live_p(objspace, (VALUE)val);
+}
+
+static int
+wmap_each_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)arg;
+
+ if (wmap_live_entry_p(objspace, key, val)) {
+ rb_yield_values(2, (VALUE)key, (VALUE)val);
+ return ST_CONTINUE;
+ }
+ else {
+ return ST_DELETE;
+ }
+}
+
+/* Iterates over keys and objects in a weakly referenced object */
+static VALUE
+wmap_each(VALUE self)
+{
+ struct weakmap *w;
+ rb_objspace_t *objspace = &rb_objspace;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ st_foreach(w->wmap2obj, wmap_each_i, (st_data_t)objspace);
+ return self;
+}
+
+static int
+wmap_each_key_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)arg;
+
+ if (wmap_live_entry_p(objspace, key, val)) {
+ rb_yield((VALUE)key);
+ return ST_CONTINUE;
+ }
+ else {
+ return ST_DELETE;
+ }
+}
+
+/* Iterates over keys and objects in a weakly referenced object */
+static VALUE
+wmap_each_key(VALUE self)
+{
+ struct weakmap *w;
+ rb_objspace_t *objspace = &rb_objspace;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ st_foreach(w->wmap2obj, wmap_each_key_i, (st_data_t)objspace);
+ return self;
+}
+
+static int
+wmap_each_value_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ rb_objspace_t *objspace = (rb_objspace_t *)arg;
+
+ if (wmap_live_entry_p(objspace, key, val)) {
+ rb_yield((VALUE)val);
+ return ST_CONTINUE;
+ }
+ else {
+ return ST_DELETE;
+ }
+}
+
+/* Iterates over keys and objects in a weakly referenced object */
+static VALUE
+wmap_each_value(VALUE self)
+{
+ struct weakmap *w;
+ rb_objspace_t *objspace = &rb_objspace;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ st_foreach(w->wmap2obj, wmap_each_value_i, (st_data_t)objspace);
+ return self;
+}
+
+static int
+wmap_keys_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ struct wmap_iter_arg *argp = (struct wmap_iter_arg *)arg;
+ rb_objspace_t *objspace = argp->objspace;
+ VALUE ary = argp->value;
+
+ if (wmap_live_entry_p(objspace, key, val)) {
+ rb_ary_push(ary, (VALUE)key);
+ return ST_CONTINUE;
+ }
+ else {
+ return ST_DELETE;
+ }
+}
+
+/* Iterates over keys and objects in a weakly referenced object */
+static VALUE
+wmap_keys(VALUE self)
+{
+ struct weakmap *w;
+ struct wmap_iter_arg args;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ args.objspace = &rb_objspace;
+ args.value = rb_ary_new();
+ st_foreach(w->wmap2obj, wmap_keys_i, (st_data_t)&args);
+ return args.value;
+}
+
+static int
+wmap_values_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ struct wmap_iter_arg *argp = (struct wmap_iter_arg *)arg;
+ rb_objspace_t *objspace = argp->objspace;
+ VALUE ary = argp->value;
+
+ if (wmap_live_entry_p(objspace, key, val)) {
+ rb_ary_push(ary, (VALUE)val);
+ return ST_CONTINUE;
+ }
+ else {
+ return ST_DELETE;
+ }
+}
+
+/* Iterates over values and objects in a weakly referenced object */
+static VALUE
+wmap_values(VALUE self)
+{
+ struct weakmap *w;
+ struct wmap_iter_arg args;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ args.objspace = &rb_objspace;
+ args.value = rb_ary_new();
+ st_foreach(w->wmap2obj, wmap_values_i, (st_data_t)&args);
+ return args.value;
+}
+
+static int
+wmap_aset_update(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
+{
+ VALUE size, *ptr, *optr;
+ if (existing) {
+ size = (ptr = optr = (VALUE *)*val)[0];
+
+ for (VALUE index = 1; index <= size; index++) {
+ if (ptr[index] == (VALUE)arg) {
+ // The reference was already registered.
+ return ST_STOP;
+ }
+ }
+
+ ++size;
+ SIZED_REALLOC_N(ptr, VALUE, size + 1, size);
+ }
+ else {
+ optr = 0;
+ size = 1;
+ ptr = ruby_xmalloc0(2 * sizeof(VALUE));
+ }
+ ptr[0] = size;
+ ptr[size] = (VALUE)arg;
+ if (ptr == optr) return ST_STOP;
+ *val = (st_data_t)ptr;
+ return ST_CONTINUE;
+}
+
+struct wmap_aset_replace_args {
+ VALUE new_value;
+ VALUE old_value;
+};
+
+static int
+wmap_aset_replace_value(st_data_t *key, st_data_t *val, st_data_t _args, int existing)
+{
+ struct wmap_aset_replace_args *args = (struct wmap_aset_replace_args *)_args;
+
+ if (existing) {
+ args->old_value = *val;
+ }
+ *val = (st_data_t)args->new_value;
+ return ST_CONTINUE;
+}
+
+/* Creates a weak reference from the given key to the given value */
+static VALUE
+wmap_aset(VALUE self, VALUE key, VALUE value)
+{
+ struct weakmap *w;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ if (FL_ABLE(value)) {
+ define_final0(value, w->final);
+ }
+ if (FL_ABLE(key)) {
+ define_final0(key, w->final);
+ }
+
+ struct wmap_aset_replace_args aset_args = {
+ .new_value = value,
+ .old_value = Qundef,
+ };
+ st_update(w->wmap2obj, (st_data_t)key, wmap_aset_replace_value, (st_data_t)&aset_args);
+
+ // If the value is unchanged, we have nothing to do.
+ if (value != aset_args.old_value) {
+ if (!UNDEF_P(aset_args.old_value) && FL_ABLE(aset_args.old_value)) {
+ // That key existed and had an inverse reference, we need to clear the outdated inverse reference.
+ st_update(w->obj2wmap, (st_data_t)aset_args.old_value, wmap_remove_inverse_ref, key);
+ }
+
+ if (FL_ABLE(value)) {
+ // If the value has no finalizer, we don't need to keep the inverse reference
+ st_update(w->obj2wmap, (st_data_t)value, wmap_aset_update, key);
+ }
+ }
+
+ return nonspecial_obj_id(value);
+}
+
+/* Retrieves a weakly referenced object with the given key */
+static VALUE
+wmap_lookup(VALUE self, VALUE key)
+{
+ st_data_t data;
+ VALUE obj;
+ struct weakmap *w;
+ rb_objspace_t *objspace = &rb_objspace;
+ GC_ASSERT(wmap_live_p(objspace, key));
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ if (!st_lookup(w->wmap2obj, (st_data_t)key, &data)) return Qundef;
+ obj = (VALUE)data;
+ if (!wmap_live_p(objspace, obj)) return Qundef;
+ return obj;
+}
+
+/* Retrieves a weakly referenced object with the given key */
+static VALUE
+wmap_aref(VALUE self, VALUE key)
+{
+ VALUE obj = wmap_lookup(self, key);
+ return !UNDEF_P(obj) ? obj : Qnil;
+}
+
+/* Returns +true+ if +key+ is registered */
+static VALUE
+wmap_has_key(VALUE self, VALUE key)
+{
+ return RBOOL(!UNDEF_P(wmap_lookup(self, key)));
+}
+
+/* Returns the number of referenced objects */
+static VALUE
+wmap_size(VALUE self)
+{
+ struct weakmap *w;
+ st_index_t n;
+
+ TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
+ n = w->wmap2obj->num_entries;
+#if SIZEOF_ST_INDEX_T <= SIZEOF_LONG
+ return ULONG2NUM(n);
+#else
+ return ULL2NUM(n);
+#endif
+}
+
+/*
------------------------------ GC profiler ------------------------------
*/
@@ -13338,7 +13642,7 @@ gc_prof_set_heap_info(rb_objspace_t *objspace)
{
if (gc_prof_enabled(objspace)) {
gc_profile_record *record = gc_prof_record(objspace);
- size_t live = objspace->profile.total_allocated_objects_at_gc_start - total_freed_objects(objspace);
+ size_t live = objspace->profile.total_allocated_objects_at_gc_start - objspace->profile.total_freed_objects;
size_t total = objspace->profile.heap_used_at_gc_start * HEAP_PAGE_OBJ_LIMIT;
#if GC_PROFILE_MORE_DETAIL
@@ -13370,7 +13674,9 @@ gc_profile_clear(VALUE _)
objspace->profile.size = 0;
objspace->profile.next_index = 0;
objspace->profile.current_record = 0;
- free(p);
+ if (p) {
+ free(p);
+ }
return Qnil;
}
@@ -13440,7 +13746,7 @@ gc_profile_record_get(VALUE _)
gc_profile_record *record = &objspace->profile.records[i];
prof = rb_hash_new();
- rb_hash_aset(prof, ID2SYM(rb_intern("GC_FLAGS")), gc_info_decode(objspace, rb_hash_new(), record->flags));
+ rb_hash_aset(prof, ID2SYM(rb_intern("GC_FLAGS")), gc_info_decode(0, rb_hash_new(), record->flags));
rb_hash_aset(prof, ID2SYM(rb_intern("GC_TIME")), DBL2NUM(record->gc_time));
rb_hash_aset(prof, ID2SYM(rb_intern("GC_INVOKE_TIME")), DBL2NUM(record->gc_invoke_time));
rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_USE_SIZE")), SIZET2NUM(record->heap_use_size));
@@ -13834,7 +14140,7 @@ rb_raw_obj_info_common(char *const buff, const size_t buff_size, const VALUE obj
}
}
else {
- const int age = RVALUE_AGE_GET(obj);
+ const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
if (is_pointer_to_heap(&rb_objspace, (void *)obj)) {
APPEND_F("%p [%d%s%s%s%s%s%s] %s ",
@@ -13898,12 +14204,13 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
RARRAY_LEN(obj));
}
else {
- APPEND_F("[%s%s] len: %ld, capa:%ld ptr:%p",
+ APPEND_F("[%s%s%s] len: %ld, capa:%ld ptr:%p",
C(ARY_EMBED_P(obj), "E"),
C(ARY_SHARED_P(obj), "S"),
+ C(RARRAY_TRANSIENT_P(obj), "T"),
RARRAY_LEN(obj),
ARY_EMBED_P(obj) ? -1L : RARRAY(obj)->as.heap.aux.capa,
- (void *)RARRAY_CONST_PTR(obj));
+ (void *)RARRAY_CONST_PTR_TRANSIENT(obj));
}
break;
case T_STRING: {
@@ -13934,8 +14241,9 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
break;
}
case T_HASH: {
- APPEND_F("[%c] %"PRIdSIZE,
+ APPEND_F("[%c%c] %"PRIdSIZE,
RHASH_AR_TABLE_P(obj) ? 'A' : 'S',
+ RHASH_TRANSIENT_P(obj) ? 'T' : ' ',
RHASH_SIZE(obj));
break;
}
@@ -13947,7 +14255,7 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
APPEND_F("%s", RSTRING_PTR(class_path));
}
else {
- APPEND_S("(anon)");
+ APPEND_S("(annon)");
}
break;
}
@@ -13961,20 +14269,14 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
}
case T_OBJECT:
{
- if (rb_shape_obj_too_complex(obj)) {
- size_t hash_len = rb_st_table_size(ROBJECT_IV_HASH(obj));
- APPEND_F("(too_complex) len:%zu", hash_len);
+ uint32_t len = ROBJECT_IV_CAPACITY(obj);
+
+ if (RANY(obj)->as.basic.flags & ROBJECT_EMBED) {
+ APPEND_F("(embed) len:%d", len);
}
else {
- uint32_t len = ROBJECT_IV_CAPACITY(obj);
-
- if (RANY(obj)->as.basic.flags & ROBJECT_EMBED) {
- APPEND_F("(embed) len:%d", len);
- }
- else {
- VALUE *ptr = ROBJECT_IVPTR(obj);
- APPEND_F("len:%d ptr:%p", len, (void *)ptr);
- }
+ VALUE *ptr = ROBJECT_IVPTR(obj);
+ APPEND_F("len:%d ptr:%p", len, (void *)ptr);
}
}
break;
@@ -14131,7 +14433,7 @@ obj_info(VALUE obj)
}
#endif
-const char *
+MJIT_FUNC_EXPORTED const char *
rb_obj_info(VALUE obj)
{
return obj_info(obj);
@@ -14144,7 +14446,7 @@ rb_obj_info_dump(VALUE obj)
fprintf(stderr, "rb_obj_info_dump: %s\n", rb_raw_obj_info(buff, 0x100, obj));
}
-void
+MJIT_FUNC_EXPORTED void
rb_obj_info_dump_loc(VALUE obj, const char *file, int line, const char *func)
{
char buff[0x100];
@@ -14176,14 +14478,14 @@ rb_gcdebug_print_obj_condition(VALUE obj)
fprintf(stderr, "marked? : %s\n", MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj) ? "true" : "false");
fprintf(stderr, "pinned? : %s\n", MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj) ? "true" : "false");
- fprintf(stderr, "age? : %d\n", RVALUE_AGE_GET(obj));
+ fprintf(stderr, "age? : %d\n", RVALUE_AGE(obj));
fprintf(stderr, "old? : %s\n", RVALUE_OLD_P(obj) ? "true" : "false");
fprintf(stderr, "WB-protected?: %s\n", RVALUE_WB_UNPROTECTED(obj) ? "false" : "true");
fprintf(stderr, "remembered? : %s\n", RVALUE_REMEMBERED(obj) ? "true" : "false");
if (is_lazy_sweeping(objspace)) {
fprintf(stderr, "lazy sweeping?: true\n");
- fprintf(stderr, "swept?: %s\n", is_swept_object(obj) ? "done" : "not yet");
+ fprintf(stderr, "swept?: %s\n", is_swept_object(objspace, obj) ? "done" : "not yet");
}
else {
fprintf(stderr, "lazy sweeping?: false\n");
@@ -14205,6 +14507,7 @@ rb_gcdebug_sentinel(VALUE obj, const char *name)
#endif /* GC_DEBUG */
+#if GC_DEBUG_STRESS_TO_CLASS
/*
* call-seq:
* GC.add_stress_to_class(class[, ...])
@@ -14218,7 +14521,7 @@ rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self)
rb_objspace_t *objspace = &rb_objspace;
if (!stress_to_class) {
- set_stress_to_class(rb_ary_hidden_new(argc));
+ stress_to_class = rb_ary_hidden_new(argc);
}
rb_ary_cat(stress_to_class, argv, argc);
return self;
@@ -14243,11 +14546,12 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
rb_ary_delete_same(stress_to_class, argv[i]);
}
if (RARRAY_LEN(stress_to_class) == 0) {
- set_stress_to_class(0);
+ stress_to_class = 0;
}
}
return Qnil;
}
+#endif
/*
* Document-module: ObjectSpace
@@ -14277,6 +14581,16 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
* Finalizer one on 537763480
*/
+/*
+ * Document-class: ObjectSpace::WeakMap
+ *
+ * An ObjectSpace::WeakMap object holds references to
+ * any objects, but those objects can get garbage collected.
+ *
+ * This class is mostly used internally by WeakRef, please use
+ * +lib/weakref.rb+ for the public interface.
+ */
+
/* Document-class: GC::Profiler
*
* The GC profiler provides access to information on GC runs including time,
@@ -14296,13 +14610,27 @@ rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
*/
#include "gc.rbinc"
+/*
+ * call-seq:
+ * GC.using_rvargc? -> true or false
+ *
+ * Returns true if using experimental feature Variable Width Allocation, false
+ * otherwise.
+ */
+static VALUE
+gc_using_rvargc_p(VALUE mod)
+{
+#if USE_RVARGC
+ return Qtrue;
+#else
+ return Qfalse;
+#endif
+}
void
Init_GC(void)
{
#undef rb_intern
- malloc_offset = gc_compute_malloc_offset();
-
VALUE rb_mObjSpace;
VALUE rb_mProfiler;
VALUE gc_constants;
@@ -14319,12 +14647,8 @@ Init_GC(void)
rb_hash_aset(gc_constants, ID2SYM(rb_intern("HEAP_PAGE_SIZE")), SIZET2NUM(HEAP_PAGE_SIZE));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("SIZE_POOL_COUNT")), LONG2FIX(SIZE_POOL_COUNT));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVARGC_MAX_ALLOCATE_SIZE")), LONG2FIX(size_pool_slot_size(SIZE_POOL_COUNT - 1)));
- rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVALUE_OLD_AGE")), LONG2FIX(RVALUE_OLD_AGE));
- if (RB_BUG_INSTEAD_OF_RB_MEMERROR+0) {
- rb_hash_aset(gc_constants, ID2SYM(rb_intern("RB_BUG_INSTEAD_OF_RB_MEMERROR")), Qtrue);
- }
OBJ_FREEZE(gc_constants);
- /* Internal constants in the garbage collector. */
+ /* internal constants */
rb_define_const(rb_mGC, "INTERNAL_CONSTANTS", gc_constants);
rb_mProfiler = rb_define_module_under(rb_mGC, "Profiler");
@@ -14353,13 +14677,36 @@ Init_GC(void)
rb_define_module_function(rb_mObjSpace, "count_objects", count_objects, -1);
+ {
+ VALUE rb_cWeakMap = rb_define_class_under(rb_mObjSpace, "WeakMap", rb_cObject);
+ rb_define_alloc_func(rb_cWeakMap, wmap_allocate);
+ rb_define_method(rb_cWeakMap, "[]=", wmap_aset, 2);
+ rb_define_method(rb_cWeakMap, "[]", wmap_aref, 1);
+ rb_define_method(rb_cWeakMap, "include?", wmap_has_key, 1);
+ rb_define_method(rb_cWeakMap, "member?", wmap_has_key, 1);
+ rb_define_method(rb_cWeakMap, "key?", wmap_has_key, 1);
+ rb_define_method(rb_cWeakMap, "inspect", wmap_inspect, 0);
+ rb_define_method(rb_cWeakMap, "each", wmap_each, 0);
+ rb_define_method(rb_cWeakMap, "each_pair", wmap_each, 0);
+ rb_define_method(rb_cWeakMap, "each_key", wmap_each_key, 0);
+ rb_define_method(rb_cWeakMap, "each_value", wmap_each_value, 0);
+ rb_define_method(rb_cWeakMap, "keys", wmap_keys, 0);
+ rb_define_method(rb_cWeakMap, "values", wmap_values, 0);
+ rb_define_method(rb_cWeakMap, "size", wmap_size, 0);
+ rb_define_method(rb_cWeakMap, "length", wmap_size, 0);
+ rb_include_module(rb_cWeakMap, rb_mEnumerable);
+ }
+
/* internal methods */
rb_define_singleton_method(rb_mGC, "verify_internal_consistency", gc_verify_internal_consistency_m, 0);
+ rb_define_singleton_method(rb_mGC, "verify_transient_heap_internal_consistency", gc_verify_transient_heap_internal_consistency, 0);
#if MALLOC_ALLOCATED_SIZE
rb_define_singleton_method(rb_mGC, "malloc_allocated_size", gc_malloc_allocated_size, 0);
rb_define_singleton_method(rb_mGC, "malloc_allocations", gc_malloc_allocations, 0);
#endif
+ rb_define_singleton_method(rb_mGC, "using_rvargc?", gc_using_rvargc_p, 0);
+
if (GC_COMPACTION_SUPPORTED) {
rb_define_singleton_method(rb_mGC, "compact", gc_compact, 0);
rb_define_singleton_method(rb_mGC, "auto_compact", gc_get_auto_compact, 0);
@@ -14375,10 +14722,10 @@ Init_GC(void)
rb_define_singleton_method(rb_mGC, "verify_compaction_references", rb_f_notimplement, -1);
}
- if (GC_DEBUG_STRESS_TO_CLASS) {
- rb_define_singleton_method(rb_mGC, "add_stress_to_class", rb_gcdebug_add_stress_to_class, -1);
- rb_define_singleton_method(rb_mGC, "remove_stress_to_class", rb_gcdebug_remove_stress_to_class, -1);
- }
+#if GC_DEBUG_STRESS_TO_CLASS
+ rb_define_singleton_method(rb_mGC, "add_stress_to_class", rb_gcdebug_add_stress_to_class, -1);
+ rb_define_singleton_method(rb_mGC, "remove_stress_to_class", rb_gcdebug_remove_stress_to_class, -1);
+#endif
{
VALUE opts;
diff --git a/gc.h b/gc.h
new file mode 100644
index 0000000000..23218c1a9e
--- /dev/null
+++ b/gc.h
@@ -0,0 +1,147 @@
+#ifndef RUBY_GC_H
+#define RUBY_GC_H 1
+#include "ruby/ruby.h"
+
+#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
+#elif defined(__i386) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
+#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && !defined(_AIX) && !defined(__APPLE__) // Not Apple is NEEDED to unbreak ppc64 build on Darwin. Don't ask.
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr\t%0, %%r1" : "=r" (*(p)))
+#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && defined(_AIX)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr %0,1" : "=r" (*(p)))
+#elif defined(__POWERPC__) && defined(__APPLE__) // Darwin ppc and ppc64
+#define SET_MACHINE_STACK_END(p) __asm__ volatile("mr %0, r1" : "=r" (*(p)))
+#elif defined(__aarch64__) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mov\t%0, sp" : "=r" (*(p)))
+#else
+NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
+#define SET_MACHINE_STACK_END(p) rb_gc_set_stack_end(p)
+#define USE_CONSERVATIVE_STACK_END
+#endif
+
+#define RB_GC_SAVE_MACHINE_CONTEXT(th) \
+ do { \
+ FLUSH_REGISTER_WINDOWS; \
+ setjmp((th)->ec->machine.regs); \
+ SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); \
+ } while (0)
+
+/* for GC debug */
+
+#ifndef RUBY_MARK_FREE_DEBUG
+#define RUBY_MARK_FREE_DEBUG 0
+#endif
+
+#if RUBY_MARK_FREE_DEBUG
+extern int ruby_gc_debug_indent;
+
+static inline void
+rb_gc_debug_indent(void)
+{
+ ruby_debug_printf("%*s", ruby_gc_debug_indent, "");
+}
+
+static inline void
+rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
+{
+ if (st == 0) {
+ ruby_gc_debug_indent--;
+ }
+ rb_gc_debug_indent();
+ ruby_debug_printf("%s: %s %s (%p)\n", mode, st ? "->" : "<-", msg, ptr);
+
+ if (st) {
+ ruby_gc_debug_indent++;
+ }
+
+ fflush(stdout);
+}
+
+#define RUBY_MARK_ENTER(msg) rb_gc_debug_body("mark", (msg), 1, ptr)
+#define RUBY_MARK_LEAVE(msg) rb_gc_debug_body("mark", (msg), 0, ptr)
+#define RUBY_FREE_ENTER(msg) rb_gc_debug_body("free", (msg), 1, ptr)
+#define RUBY_FREE_LEAVE(msg) rb_gc_debug_body("free", (msg), 0, ptr)
+#define RUBY_GC_INFO rb_gc_debug_indent(), ruby_debug_printf
+
+#else
+#define RUBY_MARK_ENTER(msg)
+#define RUBY_MARK_LEAVE(msg)
+#define RUBY_FREE_ENTER(msg)
+#define RUBY_FREE_LEAVE(msg)
+#define RUBY_GC_INFO if(0)printf
+#endif
+
+#define RUBY_MARK_MOVABLE_UNLESS_NULL(ptr) do { \
+ VALUE markobj = (ptr); \
+ if (RTEST(markobj)) {rb_gc_mark_movable(markobj);} \
+} while (0)
+#define RUBY_MARK_UNLESS_NULL(ptr) do { \
+ VALUE markobj = (ptr); \
+ if (RTEST(markobj)) {rb_gc_mark(markobj);} \
+} while (0)
+#define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);(ptr)=NULL;}
+
+#if STACK_GROW_DIRECTION > 0
+# define STACK_UPPER(x, a, b) (a)
+#elif STACK_GROW_DIRECTION < 0
+# define STACK_UPPER(x, a, b) (b)
+#else
+RUBY_EXTERN int ruby_stack_grow_direction;
+int ruby_get_stack_grow_direction(volatile VALUE *addr);
+# define stack_growup_p(x) ( \
+ (ruby_stack_grow_direction ? \
+ ruby_stack_grow_direction : \
+ ruby_get_stack_grow_direction(x)) > 0)
+# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? (a) : (b))
+#endif
+
+/*
+ STACK_GROW_DIR_DETECTION is used with STACK_DIR_UPPER.
+
+ On most normal systems, stacks grow from high address to lower address. In
+ this case, STACK_DIR_UPPER(a, b) will return (b), but on exotic systems where
+ the stack grows UP (from low address to high address), it will return (a).
+*/
+
+#if STACK_GROW_DIRECTION
+#define STACK_GROW_DIR_DETECTION
+#define STACK_DIR_UPPER(a,b) STACK_UPPER(0, (a), (b))
+#else
+#define STACK_GROW_DIR_DETECTION VALUE stack_grow_dir_detection
+#define STACK_DIR_UPPER(a,b) STACK_UPPER(&stack_grow_dir_detection, (a), (b))
+#endif
+#define IS_STACK_DIR_UPPER() STACK_DIR_UPPER(1,0)
+
+const char *rb_obj_info(VALUE obj);
+const char *rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj);
+
+struct rb_thread_struct;
+
+size_t rb_size_pool_slot_size(unsigned char pool_id);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+/* exports for objspace module */
+size_t rb_objspace_data_type_memsize(VALUE obj);
+void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
+void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *data);
+int rb_objspace_markable_object_p(VALUE obj);
+int rb_objspace_internal_object_p(VALUE obj);
+int rb_objspace_marked_object_p(VALUE obj);
+
+void rb_objspace_each_objects(
+ int (*callback)(void *start, void *end, size_t stride, void *data),
+ void *data);
+
+void rb_objspace_each_objects_without_setup(
+ int (*callback)(void *, void *, size_t, void *),
+ void *data);
+
+size_t rb_gc_obj_slot_size(VALUE obj);
+
+VALUE rb_gc_disable_no_rest(void);
+
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* RUBY_GC_H */
diff --git a/gc.rb b/gc.rb
index c9c985b994..57aeeb9131 100644
--- a/gc.rb
+++ b/gc.rb
@@ -1,6 +1,6 @@
# for gc.c
-# The \GC module provides an interface to Ruby's mark and
+# The GC module provides an interface to Ruby's mark and
# sweep garbage collection mechanism.
#
# Some of the underlying methods are also available via the ObjectSpace
@@ -10,36 +10,30 @@
# GC::Profiler.
module GC
- # Initiates garbage collection, even if manually disabled.
- #
- # The +full_mark+ keyword argument determines whether or not to perform a
- # major garbage collection cycle. When set to +true+, a major garbage
- # collection cycle is ran, meaning all objects are marked. When set to
- # +false+, a minor garbage collection cycle is ran, meaning only young
- # objects are marked.
- #
- # The +immediate_mark+ keyword argument determines whether or not to perform
- # incremental marking. When set to +true+, marking is completed during the
- # call to this method. When set to +false+, marking is performed in steps
- # that is interleaved with future Ruby code execution, so marking might not
- # be completed during this method call. Note that if +full_mark+ is +false+
- # then marking will always be immediate, regardless of the value of
- # +immediate_mark+.
- #
- # The +immedate_sweep+ keyword argument determines whether or not to defer
- # sweeping (using lazy sweep). When set to +true+, sweeping is performed in
- # steps that is interleaved with future Ruby code execution, so sweeping might
- # not be completed during this method call. When set to +false+, sweeping is
- # completed during the call to this method.
- #
- # Note: These keyword arguments are implementation and version dependent. They
- # are not guaranteed to be future-compatible, and may be ignored if the
- # underlying implementation does not support them.
+ # call-seq:
+ # GC.start -> nil
+ # ObjectSpace.garbage_collect -> nil
+ # include GC; garbage_collect -> nil
+ # GC.start(full_mark: true, immediate_sweep: true) -> nil
+ # ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil
+ # include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil
+ #
+ # Initiates garbage collection, even if manually disabled.
+ #
+ # This method is defined with keyword arguments that default to true:
+ #
+ # def GC.start(full_mark: true, immediate_sweep: true); end
+ #
+ # Use full_mark: false to perform a minor \GC.
+ # Use immediate_sweep: false to defer sweeping (use lazy sweep).
+ #
+ # Note: These keyword arguments are implementation and version dependent. They
+ # are not guaranteed to be future-compatible, and may be ignored if the
+ # underlying implementation does not support them.
def self.start full_mark: true, immediate_mark: true, immediate_sweep: true
Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end
- # Alias of GC.start
def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end
@@ -124,14 +118,14 @@ module GC
# [time]
# The total time spent in garbage collections (in milliseconds)
# [heap_allocated_pages]
- # The total number of +:heap_eden_pages+ + +:heap_tomb_pages+
+ # The total number of `:heap_eden_pages` + `:heap_tomb_pages`
# [heap_sorted_length]
# The number of pages that can fit into the buffer that holds references to
# all pages
# [heap_allocatable_pages]
# The total number of pages the application could allocate without additional \GC
# [heap_available_slots]
- # The total number of slots in all +:heap_allocated_pages+
+ # The total number of slots in all `:heap_allocated_pages`
# [heap_live_slots]
# The total number of slots which contain live objects
# [heap_free_slots]
@@ -155,7 +149,7 @@ module GC
# [malloc_increase_bytes]
# Amount of memory allocated on the heap for objects. Decreased by any \GC
# [malloc_increase_bytes_limit]
- # When +:malloc_increase_bytes+ crosses this limit, \GC is triggered
+ # When `:malloc_increase_bytes` crosses this limit, \GC is triggered
# [minor_gc_count]
# The total number of minor garbage collections run since process start
# [major_gc_count]
@@ -170,16 +164,16 @@ module GC
# [remembered_wb_unprotected_objects]
# The total number of objects without write barriers
# [remembered_wb_unprotected_objects_limit]
- # When +:remembered_wb_unprotected_objects+ crosses this limit,
+ # When `:remembered_wb_unprotected_objects` crosses this limit,
# major \GC is triggered
# [old_objects]
# Number of live, old objects which have survived at least 3 garbage collections
# [old_objects_limit]
- # When +:old_objects+ crosses this limit, major \GC is triggered
+ # When `:old_objects` crosses this limit, major \GC is triggered
# [oldmalloc_increase_bytes]
# Amount of memory allocated on the heap for objects. Decreased by major \GC
# [oldmalloc_increase_bytes_limit]
- # When +:old_malloc_increase_bytes+ crosses this limit, major \GC is triggered
+ # When `:old_malloc_increase_bytes` crosses this limit, major \GC is triggered
#
# If the optional argument, hash, is given,
# it is overwritten and returned.
@@ -197,18 +191,19 @@ module GC
# GC.stat_heap(heap_name, hash) -> Hash
# GC.stat_heap(heap_name, :key) -> Numeric
#
- # Returns information for heaps in the \GC.
+ # Returns information for memory pools in the \GC.
#
# If the first optional argument, +heap_name+, is passed in and not +nil+, it
- # returns a +Hash+ containing information about the particular heap.
- # Otherwise, it will return a +Hash+ with heap names as keys and
- # a +Hash+ containing information about the heap as values.
+ # returns a +Hash+ containing information about the particular memory pool.
+ # Otherwise, it will return a +Hash+ with memory pool names as keys and
+ # a +Hash+ containing information about the memory pool as values.
#
# If the second optional argument, +hash_or_key+, is given as +Hash+, it will
# be overwritten and returned. This is intended to avoid the probe effect.
#
# If both optional arguments are passed in and the second optional argument is
- # a symbol, it will return a +Numeric+ of the value for the particular heap.
+ # a symbol, it will return a +Numeric+ of the value for the particular memory
+ # pool.
#
# On CRuby, +heap_name+ is of the type +Integer+ but may be of type +String+
# on other implementations.
@@ -219,36 +214,6 @@ module GC
# If the optional argument, hash, is given, it is overwritten and returned.
#
# This method is only expected to work on CRuby.
- #
- # The hash includes the following keys about the internal information in
- # the \GC:
- #
- # [slot_size]
- # The slot size of the heap in bytes.
- # [heap_allocatable_pages]
- # The number of pages that can be allocated without triggering a new
- # garbage collection cycle.
- # [heap_eden_pages]
- # The number of pages in the eden heap.
- # [heap_eden_slots]
- # The total number of slots in all of the pages in the eden heap.
- # [heap_tomb_pages]
- # The number of pages in the tomb heap. The tomb heap only contains pages
- # that do not have any live objects.
- # [heap_tomb_slots]
- # The total number of slots in all of the pages in the tomb heap.
- # [total_allocated_pages]
- # The total number of pages that have been allocated in the heap.
- # [total_freed_pages]
- # The total number of pages that have been freed and released back to the
- # system in the heap.
- # [force_major_gc_count]
- # The number of times major garbage collection cycles this heap has forced
- # to start due to running out of free slots.
- # [force_incremental_marking_finish_count]
- # The number of times this heap has forced incremental marking to complete
- # due to running out of pooled slots.
- #
def self.stat_heap heap_name = nil, hash_or_key = nil
Primitive.gc_stat_heap heap_name, hash_or_key
end
@@ -317,13 +282,12 @@ module GC
# Return measured \GC total time in nano seconds.
def self.total_time
Primitive.cexpr! %{
- ULL2NUM(rb_objspace.profile.marking_time_ns + rb_objspace.profile.sweeping_time_ns)
+ ULL2NUM(rb_objspace.profile.total_time_ns)
}
end
end
module ObjectSpace
- # Alias of GC.start
def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end
diff --git a/gem_prelude.rb b/gem_prelude.rb
index bcd2560fab..f382021ca3 100644
--- a/gem_prelude.rb
+++ b/gem_prelude.rb
@@ -4,8 +4,6 @@ rescue LoadError => e
raise unless e.path == 'rubygems'
warn "`RubyGems' were not loaded."
-else
- require 'bundled_gems'
end if defined?(Gem)
begin
diff --git a/gems/bundled_gems b/gems/bundled_gems
index aa96ab841c..d37d869d41 100644
--- a/gems/bundled_gems
+++ b/gems/bundled_gems
@@ -1,23 +1,16 @@
-# gem-name version repository-url [revision]
-#
-# - gem-name: gem name to bundle
-# - version: released version to bundle
-# - repository-url: URL from where clone for test
-# - revision: revision in repository-url to test
-# if `revision` is not given, "v"+`version` or `version` will be used.
-minitest 5.20.0 https://github.com/minitest/minitest
+# gem-name version-to-bundle repository-url [optional-commit-hash-to-test-or-defaults-to-v-version]
+minitest 5.25.1 https://github.com/seattlerb/minitest
power_assert 2.0.3 https://github.com/ruby/power_assert
-rake 13.1.0 https://github.com/ruby/rake
-test-unit 3.6.1 https://github.com/test-unit/test-unit
-rexml 3.2.8 https://github.com/ruby/rexml
-rss 0.3.0 https://github.com/ruby/rss
-net-ftp 0.3.4 https://github.com/ruby/net-ftp
-net-imap 0.4.9.1 https://github.com/ruby/net-imap
+rake 13.0.6 https://github.com/ruby/rake
+test-unit 3.5.7 https://github.com/test-unit/test-unit
+rexml 3.3.9 https://github.com/ruby/rexml
+rss 0.3.1 https://github.com/ruby/rss
+net-ftp 0.2.1 https://github.com/ruby/net-ftp
+net-imap 0.3.9 https://github.com/ruby/net-imap
net-pop 0.1.2 https://github.com/ruby/net-pop
-net-smtp 0.4.0.1 https://github.com/ruby/net-smtp
+net-smtp 0.3.4 https://github.com/ruby/net-smtp
matrix 0.4.2 https://github.com/ruby/matrix
prime 0.1.2 https://github.com/ruby/prime
-rbs 3.4.0 https://github.com/ruby/rbs
-typeprof 0.21.9 https://github.com/ruby/typeprof
-debug 1.9.1 https://github.com/ruby/debug
-racc 1.7.3 https://github.com/ruby/racc
+rbs 2.8.2 https://github.com/ruby/rbs
+typeprof 0.21.3 https://github.com/ruby/typeprof
+debug 1.7.1 https://github.com/ruby/debug
diff --git a/gems/lib/envutil.rb b/gems/lib/envutil.rb
new file mode 100644
index 0000000000..d684c22cf2
--- /dev/null
+++ b/gems/lib/envutil.rb
@@ -0,0 +1 @@
+require_relative "../../tool/lib/envutil.rb"
diff --git a/gems/lib/rake/extensiontask.rb b/gems/lib/rake/extensiontask.rb
index aa668935fc..fdbe8d8874 100644
--- a/gems/lib/rake/extensiontask.rb
+++ b/gems/lib/rake/extensiontask.rb
@@ -1,3 +1,5 @@
+require "rake/tasklib" unless defined?(Rake::TaskLib)
+
module Rake
class ExtensionTask < TaskLib
def initialize(...)
diff --git a/hash.c b/hash.c
index 902a2373b3..d2dce30624 100644
--- a/hash.c
+++ b/hash.c
@@ -44,33 +44,17 @@
#include "ruby/util.h"
#include "ruby_assert.h"
#include "symbol.h"
+#include "transient_heap.h"
#include "ruby/thread_native.h"
#include "ruby/ractor.h"
#include "vm_sync.h"
-/* Flags of RHash
- *
- * 1: RHASH_PASS_AS_KEYWORDS
- * The hash is flagged as Ruby 2 keywords hash.
- * 2: RHASH_PROC_DEFAULT
- * The hash has a default proc (rather than a default value).
- * 3: RHASH_ST_TABLE_FLAG
- * The hash uses a ST table (rather than an AR table).
- * 4-7: RHASH_AR_TABLE_SIZE_MASK
- * The size of the AR table.
- * 8-11: RHASH_AR_TABLE_BOUND_MASK
- * The bounds of the AR table.
- * 13-19: RHASH_LEV_MASK
- * The iterational level of the hash. Used to prevent modifications
- * to the hash during interation.
- */
-
#ifndef HASH_DEBUG
#define HASH_DEBUG 0
#endif
#if HASH_DEBUG
-#include "internal/gc.h"
+#include "gc.h"
#endif
#define SET_DEFAULT(hash, ifnone) ( \
@@ -122,7 +106,7 @@ rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
return hash;
}
-int
+static int
rb_any_cmp(VALUE a, VALUE b)
{
if (a == b) return 0;
@@ -384,10 +368,12 @@ typedef st_index_t st_hash_t;
/*
* RHASH_AR_TABLE_P(h):
- * RHASH_AR_TABLE points to ar_table.
+ * * as.ar == NULL or
+ * as.ar points ar_table.
+ * * as.ar is allocated by transient heap or xmalloc.
*
* !RHASH_AR_TABLE_P(h):
- * RHASH_ST_TABLE points st_table.
+ * * as.st points st_table.
*/
#define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE
@@ -395,6 +381,22 @@ typedef st_index_t st_hash_t;
#define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n])
#define RHASH_AR_CLEARED_HINT 0xff
+typedef struct ar_table_pair_struct {
+ VALUE key;
+ VALUE val;
+} ar_table_pair;
+
+typedef struct ar_table_struct {
+ /* 64bit CPU: 8B * 2 * 8 = 128B */
+ ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE];
+} ar_table;
+
+size_t
+rb_hash_ar_table_size(void)
+{
+ return sizeof(ar_table);
+}
+
static inline st_hash_t
ar_do_hash(st_data_t key)
{
@@ -410,13 +412,13 @@ ar_do_hash_hint(st_hash_t hash_value)
static inline ar_hint_t
ar_hint(VALUE hash, unsigned int index)
{
- return RHASH_AR_TABLE(hash)->ar_hint.ary[index];
+ return RHASH(hash)->ar_hint.ary[index];
}
static inline void
ar_hint_set_hint(VALUE hash, unsigned int index, ar_hint_t hint)
{
- RHASH_AR_TABLE(hash)->ar_hint.ary[index] = hint;
+ RHASH(hash)->ar_hint.ary[index] = hint;
}
static inline void
@@ -464,20 +466,14 @@ ar_set_entry(VALUE hash, unsigned int index, st_data_t key, st_data_t val, st_ha
((unsigned int)((RBASIC(h)->flags >> RHASH_AR_TABLE_BOUND_SHIFT) & \
(RHASH_AR_TABLE_BOUND_MASK >> RHASH_AR_TABLE_BOUND_SHIFT)))
+#define RHASH_AR_TABLE_BOUND(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
+ RHASH_AR_TABLE_BOUND_RAW(h))
+
#define RHASH_ST_TABLE_SET(h, s) rb_hash_st_table_set(h, s)
#define RHASH_TYPE(hash) (RHASH_AR_TABLE_P(hash) ? &objhash : RHASH_ST_TABLE(hash)->type)
#define HASH_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(HASH_DEBUG, expr, #expr)
-static inline unsigned int
-RHASH_AR_TABLE_BOUND(VALUE h)
-{
- HASH_ASSERT(RHASH_AR_TABLE_P(h));
- const unsigned int bound = RHASH_AR_TABLE_BOUND_RAW(h);
- HASH_ASSERT(bound <= RHASH_AR_TABLE_MAX_SIZE);
- return bound;
-}
-
#if HASH_DEBUG
#define hash_verify(hash) hash_verify_(hash, __FILE__, __LINE__)
@@ -487,10 +483,10 @@ rb_hash_dump(VALUE hash)
rb_obj_info_dump(hash);
if (RHASH_AR_TABLE_P(hash)) {
- unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
+ unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
fprintf(stderr, " size:%u bound:%u\n",
- RHASH_AR_TABLE_SIZE(hash), bound);
+ RHASH_AR_TABLE_SIZE(hash), RHASH_AR_TABLE_BOUND(hash));
for (i=0; i<bound; i++) {
st_data_t k, v;
@@ -504,6 +500,7 @@ rb_hash_dump(VALUE hash)
rb_raw_obj_info(b1, 0x100, k),
rb_raw_obj_info(b2, 0x100, v),
ar_hint(hash, i));
+ n++;
}
else {
fprintf(stderr, " %d empty\n", i);
@@ -541,6 +538,13 @@ hash_verify_(VALUE hash, const char *file, int line)
HASH_ASSERT(RHASH_AR_TABLE_BOUND_RAW(hash) == 0);
}
+#if USE_TRANSIENT_HEAP
+ if (RHASH_TRANSIENT_P(hash)) {
+ volatile st_data_t MAYBE_UNUSED(key) = RHASH_AR_TABLE_REF(hash, 0)->key; /* read */
+ HASH_ASSERT(RHASH_AR_TABLE(hash) != NULL);
+ HASH_ASSERT(rb_transient_heap_managed_ptr_p(RHASH_AR_TABLE(hash)));
+ }
+#endif
return hash;
}
@@ -549,30 +553,69 @@ hash_verify_(VALUE hash, const char *file, int line)
#endif
static inline int
+RHASH_TABLE_NULL_P(VALUE hash)
+{
+ if (RHASH(hash)->as.ar == NULL) {
+ HASH_ASSERT(RHASH_AR_TABLE_P(hash));
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static inline int
RHASH_TABLE_EMPTY_P(VALUE hash)
{
return RHASH_SIZE(hash) == 0;
}
-#define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG)
-#define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG)
+int
+rb_hash_ar_table_p(VALUE hash)
+{
+ if (FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG)) {
+ HASH_ASSERT(RHASH(hash)->as.st != NULL);
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
+}
-static void
-hash_st_table_init(VALUE hash, const struct st_hash_type *type, st_index_t size)
+ar_table *
+rb_hash_ar_table(VALUE hash)
{
- st_init_existing_table_with_size(RHASH_ST_TABLE(hash), type, size);
- RHASH_SET_ST_FLAG(hash);
+ HASH_ASSERT(RHASH_AR_TABLE_P(hash));
+ return RHASH(hash)->as.ar;
+}
+
+st_table *
+rb_hash_st_table(VALUE hash)
+{
+ HASH_ASSERT(!RHASH_AR_TABLE_P(hash));
+ return RHASH(hash)->as.st;
}
void
rb_hash_st_table_set(VALUE hash, st_table *st)
{
HASH_ASSERT(st != NULL);
- RHASH_SET_ST_FLAG(hash);
+ FL_SET_RAW((hash), RHASH_ST_TABLE_FLAG);
+ RHASH(hash)->as.st = st;
+}
- *RHASH_ST_TABLE(hash) = *st;
+static void
+hash_ar_table_set(VALUE hash, ar_table *ar)
+{
+ HASH_ASSERT(RHASH_AR_TABLE_P(hash));
+ HASH_ASSERT((RHASH_TRANSIENT_P(hash) && ar == NULL) ? FALSE : TRUE);
+ RHASH(hash)->as.ar = ar;
+ hash_verify(hash);
}
+#define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG)
+#define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG)
+
static inline void
RHASH_AR_TABLE_BOUND_SET(VALUE h, st_index_t n)
{
@@ -627,7 +670,27 @@ RHASH_AR_TABLE_CLEAR(VALUE h)
RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
- memset(RHASH_AR_TABLE(h), 0, sizeof(ar_table));
+ hash_ar_table_set(h, NULL);
+}
+
+static ar_table*
+ar_alloc_table(VALUE hash)
+{
+ ar_table *tab = (ar_table*)rb_transient_heap_alloc(hash, sizeof(ar_table));
+
+ if (tab != NULL) {
+ RHASH_SET_TRANSIENT_FLAG(hash);
+ }
+ else {
+ RHASH_UNSET_TRANSIENT_FLAG(hash);
+ tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
+ }
+
+ RHASH_AR_TABLE_SIZE_SET(hash, 0);
+ RHASH_AR_TABLE_BOUND_SET(hash, 0);
+ hash_ar_table_set(hash, tab);
+
+ return tab;
}
NOINLINE(static int ar_equal(VALUE x, VALUE y));
@@ -642,7 +705,7 @@ static unsigned
ar_find_entry_hint(VALUE hash, ar_hint_t hint, st_data_t key)
{
unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
- const ar_hint_t *hints = RHASH_AR_TABLE(hash)->ar_hint.ary;
+ const ar_hint_t *hints = RHASH(hash)->ar_hint.ary;
/* if table is NULL, then bound also should be 0 */
@@ -689,12 +752,22 @@ ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key)
}
static inline void
-hash_ar_free_and_clear_table(VALUE hash)
+ar_free_and_clear_table(VALUE hash)
{
- RHASH_AR_TABLE_CLEAR(hash);
+ ar_table *tab = RHASH_AR_TABLE(hash);
+ if (tab) {
+ if (RHASH_TRANSIENT_P(hash)) {
+ RHASH_UNSET_TRANSIENT_FLAG(hash);
+ }
+ else {
+ ruby_xfree(RHASH_AR_TABLE(hash));
+ }
+ RHASH_AR_TABLE_CLEAR(hash);
+ }
HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
+ HASH_ASSERT(RHASH_TRANSIENT_P(hash) == 0);
}
void rb_st_add_direct_with_hash(st_table *tab, st_data_t key, st_data_t value, st_hash_t hash); // st.c
@@ -728,13 +801,18 @@ ar_each_key(ar_table *ar, int max, enum ar_each_key_type type, st_data_t *dst_ke
return 0;
}
+
+
static st_table *
ar_force_convert_table(VALUE hash, const char *file, int line)
{
+ st_table *new_tab;
+
if (RHASH_ST_TABLE_P(hash)) {
return RHASH_ST_TABLE(hash);
}
- else {
+
+ if (RHASH_AR_TABLE(hash)) {
ar_table *ar = RHASH_AR_TABLE(hash);
st_hash_t hashes[RHASH_AR_TABLE_MAX_SIZE];
unsigned int bound, size;
@@ -757,15 +835,27 @@ ar_force_convert_table(VALUE hash, const char *file, int line)
if (UNLIKELY(ar_each_key(ar, bound, ar_each_key_cmp, keys, NULL, NULL))) continue;
} while (0);
+
// make st
- st_table tab;
- st_table *new_tab = &tab;
- rb_st_init_existing_table_with_size(new_tab, &objhash, size);
+ new_tab = st_init_table_with_size(&objhash, size);
ar_each_key(ar, bound, ar_each_key_insert, NULL, new_tab, hashes);
- hash_ar_free_and_clear_table(hash);
- RHASH_ST_TABLE_SET(hash, new_tab);
- return RHASH_ST_TABLE(hash);
+ ar_free_and_clear_table(hash);
+ }
+ else {
+ new_tab = st_init_table(&objhash);
}
+ RHASH_ST_TABLE_SET(hash, new_tab);
+
+ return new_tab;
+}
+
+static ar_table *
+hash_ar_table(VALUE hash)
+{
+ if (RHASH_TABLE_NULL_P(hash)) {
+ ar_alloc_table(hash);
+ }
+ return RHASH_AR_TABLE(hash);
}
static int
@@ -818,6 +908,7 @@ ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash
else {
if (UNLIKELY(bin >= RHASH_AR_TABLE_MAX_BOUND)) {
bin = ar_compact_table(hash);
+ hash_ar_table(hash);
}
HASH_ASSERT(bin < RHASH_AR_TABLE_MAX_BOUND);
@@ -828,14 +919,6 @@ ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash
}
}
-static void
-ensure_ar_table(VALUE hash)
-{
- if (!RHASH_AR_TABLE_P(hash)) {
- rb_raise(rb_eRuntimeError, "hash representation was changed during iteration");
- }
-}
-
static int
ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
{
@@ -847,7 +930,6 @@ ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_c
ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
- ensure_ar_table(hash);
/* pair may be not valid here because of theap */
switch (retval) {
@@ -922,7 +1004,6 @@ ar_foreach_check(VALUE hash, st_foreach_check_callback_func *func, st_data_t arg
hint = ar_hint(hash, i);
retval = (*func)(key, pair->val, arg, 0);
- ensure_ar_table(hash);
hash_verify(hash);
switch (retval) {
@@ -972,6 +1053,7 @@ ar_update(VALUE hash, st_data_t key,
existing = (bin != RHASH_AR_TABLE_MAX_BOUND) ? TRUE : FALSE;
}
else {
+ hash_ar_table(hash); /* allocate ltbl if needed */
existing = FALSE;
}
@@ -983,7 +1065,6 @@ ar_update(VALUE hash, st_data_t key,
old_key = key;
retval = (*func)(&key, &value, arg, existing);
/* pair can be invalid here because of theap */
- ensure_ar_table(hash);
switch (retval) {
case ST_CONTINUE:
@@ -1021,6 +1102,8 @@ ar_insert(VALUE hash, st_data_t key, st_data_t value)
return -1;
}
+ hash_ar_table(hash); /* prepare ltbl */
+
bin = ar_find_entry(hash, hash_value, key);
if (bin == RHASH_AR_TABLE_MAX_BOUND) {
if (RHASH_AR_TABLE_SIZE(hash) >= RHASH_AR_TABLE_MAX_SIZE) {
@@ -1028,6 +1111,7 @@ ar_insert(VALUE hash, st_data_t key, st_data_t value)
}
else if (bin >= RHASH_AR_TABLE_MAX_BOUND) {
bin = ar_compact_table(hash);
+ hash_ar_table(hash);
}
HASH_ASSERT(bin < RHASH_AR_TABLE_MAX_BOUND);
@@ -1162,16 +1246,44 @@ static ar_table*
ar_copy(VALUE hash1, VALUE hash2)
{
ar_table *old_tab = RHASH_AR_TABLE(hash2);
- ar_table *new_tab = RHASH_AR_TABLE(hash1);
- *new_tab = *old_tab;
- RHASH_AR_TABLE(hash1)->ar_hint.word = RHASH_AR_TABLE(hash2)->ar_hint.word;
- RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
- RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
+ if (old_tab != NULL) {
+ ar_table *new_tab = RHASH_AR_TABLE(hash1);
+ if (new_tab == NULL) {
+ new_tab = (ar_table*) rb_transient_heap_alloc(hash1, sizeof(ar_table));
+ if (new_tab != NULL) {
+ RHASH_SET_TRANSIENT_FLAG(hash1);
+ }
+ else {
+ RHASH_UNSET_TRANSIENT_FLAG(hash1);
+ new_tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
+ }
+ }
+ *new_tab = *old_tab;
+ RHASH(hash1)->ar_hint.word = RHASH(hash2)->ar_hint.word;
+ RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
+ RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
+ hash_ar_table_set(hash1, new_tab);
- rb_gc_writebarrier_remember(hash1);
+ rb_gc_writebarrier_remember(hash1);
+ return new_tab;
+ }
+ else {
+ RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
+ RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
- return new_tab;
+ if (RHASH_TRANSIENT_P(hash1)) {
+ RHASH_UNSET_TRANSIENT_FLAG(hash1);
+ }
+ else if (RHASH_AR_TABLE(hash1)) {
+ ruby_xfree(RHASH_AR_TABLE(hash1));
+ }
+
+ hash_ar_table_set(hash1, NULL);
+
+ rb_gc_writebarrier_remember(hash1);
+ return old_tab;
+ }
}
static void
@@ -1187,32 +1299,32 @@ ar_clear(VALUE hash)
}
}
-static void
-hash_st_free(VALUE hash)
-{
- HASH_ASSERT(RHASH_ST_TABLE_P(hash));
-
- st_table *tab = RHASH_ST_TABLE(hash);
-
- xfree(tab->bins);
- xfree(tab->entries);
-}
-
-static void
-hash_st_free_and_clear_table(VALUE hash)
-{
- hash_st_free(hash);
-
- RHASH_ST_CLEAR(hash);
-}
-
+#if USE_TRANSIENT_HEAP
void
-rb_hash_free(VALUE hash)
+rb_hash_transient_heap_evacuate(VALUE hash, int promote)
{
- if (RHASH_ST_TABLE_P(hash)) {
- hash_st_free(hash);
+ if (RHASH_TRANSIENT_P(hash)) {
+ ar_table *new_tab;
+ ar_table *old_tab = RHASH_AR_TABLE(hash);
+
+ if (UNLIKELY(old_tab == NULL)) {
+ return;
+ }
+ HASH_ASSERT(old_tab != NULL);
+ if (! promote) {
+ new_tab = rb_transient_heap_alloc(hash, sizeof(ar_table));
+ if (new_tab == NULL) promote = true;
+ }
+ if (promote) {
+ new_tab = ruby_xmalloc(sizeof(ar_table));
+ RHASH_UNSET_TRANSIENT_FLAG(hash);
+ }
+ *new_tab = *old_tab;
+ hash_ar_table_set(hash, new_tab);
}
+ hash_verify(hash);
}
+#endif
typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
@@ -1302,79 +1414,78 @@ hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
return hash_iter_status_check(status);
}
-static unsigned long
+static int
iter_lev_in_ivar(VALUE hash)
{
VALUE levval = rb_ivar_get(hash, id_hash_iter_lev);
HASH_ASSERT(FIXNUM_P(levval));
- long lev = FIX2LONG(levval);
- HASH_ASSERT(lev >= 0);
- return (unsigned long)lev;
+ return FIX2INT(levval);
}
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
static void
-iter_lev_in_ivar_set(VALUE hash, unsigned long lev)
+iter_lev_in_ivar_set(VALUE hash, int lev)
{
- HASH_ASSERT(lev >= RHASH_LEV_MAX);
- HASH_ASSERT(POSFIXABLE(lev)); /* POSFIXABLE means fitting to long */
- rb_ivar_set_internal(hash, id_hash_iter_lev, LONG2FIX((long)lev));
+ rb_ivar_set_internal(hash, id_hash_iter_lev, INT2FIX(lev));
}
-static inline unsigned long
+static inline int
iter_lev_in_flags(VALUE hash)
{
- return (unsigned long)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX);
+ unsigned int u = (unsigned int)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX);
+ return (int)u;
}
static inline void
-iter_lev_in_flags_set(VALUE hash, unsigned long lev)
+iter_lev_in_flags_set(VALUE hash, int lev)
{
- HASH_ASSERT(lev <= RHASH_LEV_MAX);
RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT));
}
-static inline bool
-hash_iterating_p(VALUE hash)
+static int
+RHASH_ITER_LEV(VALUE hash)
{
- return iter_lev_in_flags(hash) > 0;
+ int lev = iter_lev_in_flags(hash);
+
+ if (lev == RHASH_LEV_MAX) {
+ return iter_lev_in_ivar(hash);
+ }
+ else {
+ return lev;
+ }
}
static void
hash_iter_lev_inc(VALUE hash)
{
- unsigned long lev = iter_lev_in_flags(hash);
+ int lev = iter_lev_in_flags(hash);
if (lev == RHASH_LEV_MAX) {
- lev = iter_lev_in_ivar(hash) + 1;
- if (!POSFIXABLE(lev)) { /* paranoiac check */
- rb_raise(rb_eRuntimeError, "too much nested iterations");
- }
+ lev = iter_lev_in_ivar(hash);
+ iter_lev_in_ivar_set(hash, lev+1);
}
else {
lev += 1;
iter_lev_in_flags_set(hash, lev);
- if (lev < RHASH_LEV_MAX) return;
+ if (lev == RHASH_LEV_MAX) {
+ iter_lev_in_ivar_set(hash, lev);
+ }
}
- iter_lev_in_ivar_set(hash, lev);
}
static void
hash_iter_lev_dec(VALUE hash)
{
- unsigned long lev = iter_lev_in_flags(hash);
+ int lev = iter_lev_in_flags(hash);
if (lev == RHASH_LEV_MAX) {
lev = iter_lev_in_ivar(hash);
- if (lev > RHASH_LEV_MAX) {
- iter_lev_in_ivar_set(hash, lev-1);
- return;
- }
- rb_attr_delete(hash, id_hash_iter_lev);
+ HASH_ASSERT(lev > 0);
+ iter_lev_in_ivar_set(hash, lev-1);
}
- else if (lev == 0) {
- rb_raise(rb_eRuntimeError, "iteration level underflow");
+ else {
+ HASH_ASSERT(lev > 0);
+ iter_lev_in_flags_set(hash, lev - 1);
}
- iter_lev_in_flags_set(hash, lev - 1);
}
static VALUE
@@ -1457,18 +1568,16 @@ void rb_st_compact_table(st_table *tab);
static void
compact_after_delete(VALUE hash)
{
- if (!hash_iterating_p(hash) && RHASH_ST_TABLE_P(hash)) {
+ if (RHASH_ITER_LEV(hash) == 0 && RHASH_ST_TABLE_P(hash)) {
rb_st_compact_table(RHASH_ST_TABLE(hash));
}
}
static VALUE
-hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone, bool st)
+hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone)
{
const VALUE wb = (RGENGC_WB_PROTECTED_HASH ? FL_WB_PROTECTED : 0);
- const size_t size = sizeof(struct RHash) + (st ? sizeof(st_table) : sizeof(ar_table));
-
- NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags, size, 0);
+ NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags);
RHASH_SET_IFNONE((VALUE)hash, ifnone);
@@ -1478,8 +1587,7 @@ hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone, bool st)
static VALUE
hash_alloc(VALUE klass)
{
- /* Allocate to be able to fit both st_table and ar_table. */
- return hash_alloc_flags(klass, 0, Qnil, sizeof(st_table) > sizeof(ar_table));
+ return hash_alloc_flags(klass, 0, Qnil);
}
static VALUE
@@ -1505,16 +1613,19 @@ copy_compare_by_id(VALUE hash, VALUE basis)
return hash;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_new_with_size(st_index_t size)
{
- bool st = size > RHASH_AR_TABLE_MAX_SIZE;
- VALUE ret = hash_alloc_flags(rb_cHash, 0, Qnil, st);
-
- if (st) {
- hash_st_table_init(ret, &objhash, size);
+ VALUE ret = rb_hash_new();
+ if (size == 0) {
+ /* do nothing */
+ }
+ else if (size <= RHASH_AR_TABLE_MAX_SIZE) {
+ ar_alloc_table(ret);
+ }
+ else {
+ RHASH_ST_TABLE_SET(ret, st_init_table_with_size(&objhash, size));
}
-
return ret;
}
@@ -1527,32 +1638,11 @@ rb_hash_new_capa(long capa)
static VALUE
hash_copy(VALUE ret, VALUE hash)
{
- if (RHASH_AR_TABLE_P(hash)) {
- if (RHASH_AR_TABLE_P(ret)) {
+ if (!RHASH_EMPTY_P(hash)) {
+ if (RHASH_AR_TABLE_P(hash))
ar_copy(ret, hash);
- }
- else {
- st_table *tab = RHASH_ST_TABLE(ret);
- rb_st_init_existing_table_with_size(tab, &objhash, RHASH_AR_TABLE_SIZE(hash));
-
- int bound = RHASH_AR_TABLE_BOUND(hash);
- for (int i = 0; i < bound; i++) {
- if (ar_cleared_entry(hash, i)) continue;
-
- ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
- st_add_direct(tab, pair->key, pair->val);
- RB_OBJ_WRITTEN(ret, Qundef, pair->key);
- RB_OBJ_WRITTEN(ret, Qundef, pair->val);
- }
- }
- }
- else {
- HASH_ASSERT(sizeof(st_table) <= sizeof(ar_table));
-
- RHASH_SET_ST_FLAG(ret);
- st_replace(RHASH_ST_TABLE(ret), RHASH_ST_TABLE(hash));
-
- rb_gc_writebarrier_remember(ret);
+ else if (RHASH_ST_TABLE_P(hash))
+ RHASH_ST_TABLE_SET(ret, st_copy(RHASH_ST_TABLE(hash)));
}
return ret;
}
@@ -1560,21 +1650,13 @@ hash_copy(VALUE ret, VALUE hash)
static VALUE
hash_dup_with_compare_by_id(VALUE hash)
{
- VALUE dup = hash_alloc_flags(rb_cHash, 0, Qnil, RHASH_ST_TABLE_P(hash));
- if (RHASH_ST_TABLE_P(hash)) {
- RHASH_SET_ST_FLAG(dup);
- }
- else {
- RHASH_UNSET_ST_FLAG(dup);
- }
-
- return hash_copy(dup, hash);
+ return hash_copy(copy_compare_by_id(rb_hash_new(), hash), hash);
}
static VALUE
hash_dup(VALUE hash, VALUE klass, VALUE flags)
{
- return hash_copy(hash_alloc_flags(klass, flags, RHASH_IFNONE(hash), !RHASH_EMPTY_P(hash) && RHASH_ST_TABLE_P(hash)),
+ return hash_copy(hash_alloc_flags(klass, flags, RHASH_IFNONE(hash)),
hash);
}
@@ -1589,7 +1671,7 @@ rb_hash_dup(VALUE hash)
return ret;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_resurrect(VALUE hash)
{
VALUE ret = hash_dup(hash, rb_cHash, 0);
@@ -1602,7 +1684,7 @@ rb_hash_modify_check(VALUE hash)
rb_check_frozen(hash);
}
-RUBY_FUNC_EXPORTED struct st_table *
+MJIT_FUNC_EXPORTED struct st_table *
rb_hash_tbl_raw(VALUE hash, const char *file, int line)
{
return ar_force_convert_table(hash, file, line);
@@ -1720,14 +1802,14 @@ tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
return ret;
}
-#define UPDATE_CALLBACK(iter_p, func) ((iter_p) ? func##_noinsert : func##_insert)
+#define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
-#define RHASH_UPDATE_ITER(h, iter_p, key, func, a) do { \
- tbl_update((h), (key), UPDATE_CALLBACK(iter_p, func), (st_data_t)(a)); \
+#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
+ tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
} while (0)
#define RHASH_UPDATE(hash, key, func, arg) \
- RHASH_UPDATE_ITER(hash, hash_iterating_p(hash), key, func, arg)
+ RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
static void
set_proc_default(VALUE hash, VALUE proc)
@@ -1779,29 +1861,23 @@ set_proc_default(VALUE hash, VALUE proc)
static VALUE
rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
{
- rb_hash_modify(hash);
+ VALUE ifnone;
+ rb_hash_modify(hash);
if (rb_block_given_p()) {
rb_check_arity(argc, 0, 0);
- SET_PROC_DEFAULT(hash, rb_block_proc());
+ ifnone = rb_block_proc();
+ SET_PROC_DEFAULT(hash, ifnone);
}
else {
rb_check_arity(argc, 0, 1);
-
- VALUE options, ifnone;
- rb_scan_args(argc, argv, "01:", &ifnone, &options);
- if (NIL_P(ifnone) && !NIL_P(options)) {
- ifnone = options;
- rb_warn_deprecated_to_remove("3.4", "Calling Hash.new with keyword arguments", "Hash.new({ key: value })");
- }
+ ifnone = argc == 0 ? Qnil : argv[0];
RHASH_SET_IFNONE(hash, ifnone);
}
return hash;
}
-static VALUE rb_hash_to_a(VALUE hash);
-
/*
* call-seq:
* Hash[] -> new_empty_hash
@@ -1821,7 +1897,7 @@ static VALUE rb_hash_to_a(VALUE hash);
* h = {foo: 0, bar: 1, baz: 2}
* Hash[h] # => {:foo=>0, :bar=>1, :baz=>2}
*
- * When the single given argument is an Array of 2-element Arrays,
+ * When the single given argument is an \Array of 2-element Arrays,
* returns a new \Hash object wherein each 2-element array forms a
* key-value entry:
*
@@ -1845,23 +1921,12 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
if (argc == 1) {
tmp = rb_hash_s_try_convert(Qnil, argv[0]);
if (!NIL_P(tmp)) {
- if (!RHASH_EMPTY_P(tmp) && rb_hash_compare_by_id_p(tmp)) {
- /* hash_copy for non-empty hash will copy compare_by_identity
- flag, but we don't want it copied. Work around by
- converting hash to flattened array and using that. */
- tmp = rb_hash_to_a(tmp);
- }
- else {
- hash = hash_alloc(klass);
- if (!RHASH_EMPTY_P(tmp))
- hash_copy(hash, tmp);
- return hash;
- }
- }
- else {
- tmp = rb_check_array_type(argv[0]);
+ hash = hash_alloc(klass);
+ hash_copy(hash, tmp);
+ return hash;
}
+ tmp = rb_check_array_type(argv[0]);
if (!NIL_P(tmp)) {
long i;
@@ -1899,7 +1964,7 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
return hash;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_to_hash_type(VALUE hash)
{
return rb_convert_type_with_id(hash, T_HASH, "Hash", idTo_hash);
@@ -1972,12 +2037,9 @@ static VALUE
rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
{
Check_Type(hash, T_HASH);
- VALUE tmp = rb_hash_dup(hash);
- if (RHASH_EMPTY_P(hash) && rb_hash_compare_by_id_p(hash)) {
- rb_hash_compare_by_id(tmp);
- }
- RHASH(tmp)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
- return tmp;
+ hash = rb_hash_dup(hash);
+ RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
+ return hash;
}
struct rehash_arg {
@@ -2015,27 +2077,25 @@ rb_hash_rehash(VALUE hash)
VALUE tmp;
st_table *tbl;
- if (hash_iterating_p(hash)) {
+ if (RHASH_ITER_LEV(hash) > 0) {
rb_raise(rb_eRuntimeError, "rehash during iteration");
}
rb_hash_modify_check(hash);
if (RHASH_AR_TABLE_P(hash)) {
tmp = hash_alloc(0);
+ ar_alloc_table(tmp);
rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
-
- hash_ar_free_and_clear_table(hash);
+ ar_free_and_clear_table(hash);
ar_copy(hash, tmp);
+ ar_free_and_clear_table(tmp);
}
else if (RHASH_ST_TABLE_P(hash)) {
st_table *old_tab = RHASH_ST_TABLE(hash);
tmp = hash_alloc(0);
-
- hash_st_table_init(tmp, old_tab->type, old_tab->num_entries);
- tbl = RHASH_ST_TABLE(tmp);
-
+ tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
+ RHASH_ST_TABLE_SET(tmp, tbl);
rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
-
- hash_st_free(hash);
+ st_free_table(old_tab);
RHASH_ST_TABLE_SET(hash, tbl);
RHASH_ST_CLEAR(tmp);
}
@@ -2087,15 +2147,11 @@ hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
return ar_lookup(hash, key, pval);
}
else {
- extern st_index_t rb_iseq_cdhash_hash(VALUE);
- RUBY_ASSERT(RHASH_ST_TABLE(hash)->type->hash == rb_any_hash ||
- RHASH_ST_TABLE(hash)->type->hash == rb_ident_hash ||
- RHASH_ST_TABLE(hash)->type->hash == rb_iseq_cdhash_hash);
return st_lookup(RHASH_ST_TABLE(hash), key, pval);
}
}
-int
+MJIT_FUNC_EXPORTED int
rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
{
return hash_stlike_lookup(hash, key, pval);
@@ -2345,7 +2401,7 @@ key_i(VALUE key, VALUE value, VALUE arg)
* h.key(0) # => :foo
* h.key(2) # => :bar
*
- * Returns +nil+ if no such value is found.
+ * Returns +nil+ if so such value is found.
*/
static VALUE
@@ -2478,7 +2534,7 @@ shift_i_safe(VALUE key, VALUE value, VALUE arg)
*
* Removes the first hash entry
* (see {Entry Order}[rdoc-ref:Hash@Entry+Order]);
- * returns a 2-element Array containing the removed key and value:
+ * returns a 2-element \Array containing the removed key and value:
* h = {foo: 0, bar: 1, baz: 2}
* h.shift # => [:foo, 0]
* h # => {:bar=>1, :baz=>2}
@@ -2494,7 +2550,7 @@ rb_hash_shift(VALUE hash)
rb_hash_modify_check(hash);
if (RHASH_AR_TABLE_P(hash)) {
var.key = Qundef;
- if (!hash_iterating_p(hash)) {
+ if (RHASH_ITER_LEV(hash) == 0) {
if (ar_shift(hash, &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val);
}
@@ -2509,7 +2565,7 @@ rb_hash_shift(VALUE hash)
}
if (RHASH_ST_TABLE_P(hash)) {
var.key = Qundef;
- if (!hash_iterating_p(hash)) {
+ if (RHASH_ITER_LEV(hash) == 0) {
if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val);
}
@@ -2552,7 +2608,7 @@ hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
* h = {foo: 0, bar: 1, baz: 2}
* h.delete_if {|key, value| value > 0 } # => {:foo=>0}
*
- * If no block given, returns a new Enumerator:
+ * If no block given, returns a new \Enumerator:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.delete_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:delete_if>
* e.each { |key, value| value > 0 } # => {:foo=>0}
@@ -2582,7 +2638,7 @@ rb_hash_delete_if(VALUE hash)
*
* Returns +nil+ if no entries are removed.
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.reject! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject!>
* e.each {|key, value| key.start_with?('b') } # => {:foo=>0}
@@ -2613,7 +2669,7 @@ rb_hash_reject_bang(VALUE hash)
* h1 = h.reject {|key, value| key.start_with?('b') }
* h1 # => {:foo=>0}
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.reject # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject>
* h1 = e.each {|key, value| key.start_with?('b') }
@@ -2698,7 +2754,7 @@ rb_hash_except(int argc, VALUE *argv, VALUE hash)
* call-seq:
* hash.values_at(*keys) -> new_array
*
- * Returns a new Array containing values for the given +keys+:
+ * Returns a new \Array containing values for the given +keys+:
* h = {foo: 0, bar: 1, baz: 2}
* h.values_at(:baz, :foo) # => [2, 0]
*
@@ -2724,11 +2780,11 @@ rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
* hash.fetch_values(*keys) -> new_array
* hash.fetch_values(*keys) {|key| ... } -> new_array
*
- * Returns a new Array containing the values associated with the given keys *keys:
+ * Returns a new \Array containing the values associated with the given keys *keys:
* h = {foo: 0, bar: 1, baz: 2}
* h.fetch_values(:baz, :foo) # => [2, 0]
*
- * Returns a new empty Array if no arguments given.
+ * Returns a new empty \Array if no arguments given.
*
* When a block is given, calls the block with each missing key,
* treating the block's return value as the value for that key:
@@ -2766,11 +2822,13 @@ keep_if_i(VALUE key, VALUE value, VALUE hash)
* hash.select {|key, value| ... } -> new_hash
* hash.select -> new_enumerator
*
+ * Hash#filter is an alias for Hash#select.
+ *
* Returns a new \Hash object whose entries are those for which the block returns a truthy value:
* h = {foo: 0, bar: 1, baz: 2}
* h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select>
* e.each {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
@@ -2795,13 +2853,15 @@ rb_hash_select(VALUE hash)
* hash.select! {|key, value| ... } -> self or nil
* hash.select! -> new_enumerator
*
+ * Hash#filter! is an alias for Hash#select!.
+ *
* Returns +self+, whose entries are those for which the block returns a truthy value:
* h = {foo: 0, bar: 1, baz: 2}
* h.select! {|key, value| value < 2 } => {:foo=>0, :bar=>1}
*
* Returns +nil+ if no entries were removed.
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.select! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!>
* e.each { |key, value| value < 2 } # => {:foo=>0, :bar=>1}
@@ -2832,7 +2892,7 @@ rb_hash_select_bang(VALUE hash)
* h = {foo: 0, bar: 1, baz: 2}
* h.keep_if { |key, value| key.start_with?('b') } # => {:bar=>1, :baz=>2}
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.keep_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:keep_if>
* e.each { |key, value| key.start_with?('b') } # => {:bar=>1, :baz=>2}
@@ -2867,7 +2927,7 @@ rb_hash_clear(VALUE hash)
{
rb_hash_modify_check(hash);
- if (hash_iterating_p(hash)) {
+ if (RHASH_ITER_LEV(hash) > 0) {
rb_hash_foreach(hash, clear_i, 0);
}
else if (RHASH_AR_TABLE_P(hash)) {
@@ -2916,6 +2976,8 @@ NOINSERT_UPDATE_CALLBACK(hash_aset_str)
* hash[key] = value -> value
* hash.store(key, value)
*
+ * Hash#store is an alias for Hash#[]=.
+
* Associates the given +value+ with the given +key+; returns +value+.
*
* If the given +key+ exists, replaces its value with the given +value+;
@@ -2938,15 +3000,20 @@ NOINSERT_UPDATE_CALLBACK(hash_aset_str)
VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
- bool iter_p = hash_iterating_p(hash);
+ int iter_lev = RHASH_ITER_LEV(hash);
rb_hash_modify(hash);
+ if (RHASH_TABLE_NULL_P(hash)) {
+ if (iter_lev > 0) no_new_key();
+ ar_alloc_table(hash);
+ }
+
if (!RHASH_STRING_KEY_P(hash, key)) {
- RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset, val);
+ RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
}
else {
- RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset_str, val);
+ RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
}
return val;
}
@@ -2966,7 +3033,7 @@ rb_hash_replace(VALUE hash, VALUE hash2)
{
rb_hash_modify_check(hash);
if (hash == hash2) return hash;
- if (hash_iterating_p(hash)) {
+ if (RHASH_ITER_LEV(hash) > 0) {
rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
}
hash2 = to_hash(hash2);
@@ -2974,13 +3041,19 @@ rb_hash_replace(VALUE hash, VALUE hash2)
COPY_DEFAULT(hash, hash2);
if (RHASH_AR_TABLE_P(hash)) {
- hash_ar_free_and_clear_table(hash);
+ ar_free_and_clear_table(hash);
}
else {
- hash_st_free_and_clear_table(hash);
+ st_free_table(RHASH_ST_TABLE(hash));
+ RHASH_ST_CLEAR(hash);
}
-
hash_copy(hash, hash2);
+ if (RHASH_EMPTY_P(hash2) && RHASH_ST_TABLE_P(hash2)) {
+ /* ident hash */
+ RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), 0));
+ }
+
+ rb_gc_writebarrier_remember(hash);
return hash;
}
@@ -2991,9 +3064,9 @@ rb_hash_replace(VALUE hash, VALUE hash2)
* hash.size -> integer
*
* Returns the count of entries in +self+:
- *
* {foo: 0, bar: 1, baz: 2}.length # => 3
*
+ * Hash#length is an alias for Hash#size.
*/
VALUE
@@ -3043,7 +3116,7 @@ each_value_i(VALUE key, VALUE value, VALUE _)
* 1
* 2
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.each_value # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_value>
* h1 = e.each {|value| puts value }
@@ -3082,7 +3155,7 @@ each_key_i(VALUE key, VALUE value, VALUE _)
* bar
* baz
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.each_key # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_key>
* h1 = e.each {|key| puts key }
@@ -3124,6 +3197,8 @@ each_pair_i_fast(VALUE key, VALUE value, VALUE _)
* hash.each -> new_enumerator
* hash.each_pair -> new_enumerator
*
+ * Hash#each is an alias for Hash#each_pair.
+
* Calls the given block with each key-value pair; returns +self+:
* h = {foo: 0, bar: 1, baz: 2}
* h.each_pair {|key, value| puts "#{key}: #{value}"} # => {:foo=>0, :bar=>1, :baz=>2}
@@ -3132,7 +3207,7 @@ each_pair_i_fast(VALUE key, VALUE value, VALUE _)
* bar: 1
* baz: 2
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.each_pair # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_pair>
* h1 = e.each {|key, value| puts "#{key}: #{value}"}
@@ -3215,7 +3290,7 @@ transform_keys_i(VALUE key, VALUE value, VALUE result)
* h1 = h.transform_keys {|key| :bat }
* h1 # => {:bat=>2}
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.transform_keys # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_keys>
* h1 = e.each { |key| key.to_s }
@@ -3340,7 +3415,7 @@ transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t arg
* h1 = h.transform_values {|value| value * 100}
* h1 # => {:foo=>0, :bar=>100, :baz=>200}
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.transform_values # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_values>
* h1 = e.each { |value| value * 100}
@@ -3372,7 +3447,7 @@ rb_hash_transform_values(VALUE hash)
* h = {foo: 0, bar: 1, baz: 2}
* h.transform_values! {|value| value * 100} # => {:foo=>0, :bar=>100, :baz=>200}
*
- * Returns a new Enumerator if no block given:
+ * Returns a new \Enumerator if no block given:
* h = {foo: 0, bar: 1, baz: 2}
* e = h.transform_values! # => #<Enumerator: {:foo=>0, :bar=>100, :baz=>200}:transform_values!>
* h1 = e.each {|value| value * 100}
@@ -3402,8 +3477,8 @@ to_a_i(VALUE key, VALUE value, VALUE ary)
* call-seq:
* hash.to_a -> new_array
*
- * Returns a new Array of 2-element Array objects;
- * each nested Array contains a key-value pair from +self+:
+ * Returns a new \Array of 2-element \Array objects;
+ * each nested \Array contains a key-value pair from +self+:
* h = {foo: 0, bar: 1, baz: 2}
* h.to_a # => [[:foo, 0], [:bar, 1], [:baz, 2]]
*/
@@ -3456,11 +3531,11 @@ inspect_hash(VALUE hash, VALUE dummy, int recur)
* call-seq:
* hash.inspect -> new_string
*
- * Returns a new String containing the hash entries:
-
+ * Returns a new \String containing the hash entries:
* h = {foo: 0, bar: 1, baz: 2}
* h.inspect # => "{:foo=>0, :bar=>1, :baz=>2}"
*
+ * Hash#to_s is an alias for Hash#inspect.
*/
static VALUE
@@ -3528,8 +3603,8 @@ rb_hash_to_h_block(VALUE hash)
*
* When a block is given, returns a new \Hash object
* whose content is based on the block;
- * the block should return a 2-element Array object
- * specifying the key-value pair to be included in the returned Array:
+ * the block should return a 2-element \Array object
+ * specifying the key-value pair to be included in the returned \Array:
* h = {foo: 0, bar: 1, baz: 2}
* h1 = h.to_h {|key, value| [value, key] }
* h1 # => {0=>:foo, 1=>:bar, 2=>:baz}
@@ -3559,12 +3634,12 @@ keys_i(VALUE key, VALUE value, VALUE ary)
* call-seq:
* hash.keys -> new_array
*
- * Returns a new Array containing all keys in +self+:
+ * Returns a new \Array containing all keys in +self+:
* h = {foo: 0, bar: 1, baz: 2}
* h.keys # => [:foo, :bar, :baz]
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_keys(VALUE hash)
{
st_index_t size = RHASH_SIZE(hash);
@@ -3573,7 +3648,7 @@ rb_hash_keys(VALUE hash)
if (size == 0) return keys;
if (ST_DATA_COMPATIBLE_P(VALUE)) {
- RARRAY_PTR_USE(keys, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(keys, ptr, {
if (RHASH_AR_TABLE_P(hash)) {
size = ar_keys(hash, ptr, size);
}
@@ -3603,7 +3678,7 @@ values_i(VALUE key, VALUE value, VALUE ary)
* call-seq:
* hash.values -> new_array
*
- * Returns a new Array containing all values in +self+:
+ * Returns a new \Array containing all values in +self+:
* h = {foo: 0, bar: 1, baz: 2}
* h.values # => [0, 1, 2]
*/
@@ -3620,14 +3695,14 @@ rb_hash_values(VALUE hash)
if (ST_DATA_COMPATIBLE_P(VALUE)) {
if (RHASH_AR_TABLE_P(hash)) {
rb_gc_writebarrier_remember(values);
- RARRAY_PTR_USE(values, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(values, ptr, {
size = ar_values(hash, ptr, size);
});
}
else if (RHASH_ST_TABLE_P(hash)) {
st_table *table = RHASH_ST_TABLE(hash);
rb_gc_writebarrier_remember(values);
- RARRAY_PTR_USE(values, ptr, {
+ RARRAY_PTR_USE_TRANSIENT(values, ptr, {
size = st_values(table, ptr, size);
});
}
@@ -3647,11 +3722,13 @@ rb_hash_values(VALUE hash)
* hash.has_key?(key) -> true or false
* hash.key?(key) -> true or false
* hash.member?(key) -> true or false
+
+ * Methods #has_key?, #key?, and #member? are aliases for \#include?.
*
* Returns +true+ if +key+ is a key in +self+, otherwise +false+.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
return RBOOL(hash_stlike_lookup(hash, key, NULL));
@@ -3674,6 +3751,8 @@ rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
* hash.has_value?(value) -> true or false
* hash.value?(value) -> true or false
*
+ * Method #value? is an alias for \#has_value?.
+ *
* Returns +true+ if +value+ is a value in +self+, otherwise +false+.
*/
@@ -3835,10 +3914,10 @@ hash_i(VALUE key, VALUE val, VALUE arg)
* call-seq:
* hash.hash -> an_integer
*
- * Returns the Integer hash-code for the hash.
+ * Returns the \Integer hash-code for the hash.
*
* Two \Hash objects have the same hash-code if their content is the same
- * (regardless of order):
+ * (regardless or order):
* h1 = {foo: 0, bar: 1, baz: 2}
* h2 = {baz: 2, bar: 1, foo: 0}
* h2.hash == h1.hash # => true
@@ -3930,6 +4009,8 @@ rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
*
* Each argument in +other_hashes+ must be a \Hash.
*
+ * \Method #update is an alias for \#merge!.
+ *
* With arguments and no block:
* * Returns +self+, after the given hashes are merged into it.
* * The given hashes are merged left to right.
@@ -4099,17 +4180,24 @@ assoc_cmp(VALUE a, VALUE b)
return !RTEST(rb_equal(a, b));
}
-struct assoc_arg {
- st_table *tbl;
- st_data_t key;
+static VALUE
+lookup2_call(VALUE arg)
+{
+ VALUE *args = (VALUE *)arg;
+ return rb_hash_lookup2(args[0], args[1], Qundef);
+}
+
+struct reset_hash_type_arg {
+ VALUE hash;
+ const struct st_hash_type *orighash;
};
static VALUE
-assoc_lookup(VALUE arg)
+reset_hash_type(VALUE arg)
{
- struct assoc_arg *p = (struct assoc_arg*)arg;
- st_data_t data;
- if (st_lookup(p->tbl, p->key, &data)) return (VALUE)data;
+ struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
+ HASH_ASSERT(RHASH_ST_TABLE_P(p->hash));
+ RHASH_ST_TABLE(p->hash)->type = p->orighash;
return Qundef;
}
@@ -4129,7 +4217,7 @@ assoc_i(VALUE key, VALUE val, VALUE arg)
* call-seq:
* hash.assoc(key) -> new_array or nil
*
- * If the given +key+ is found, returns a 2-element Array containing that key and its value:
+ * If the given +key+ is found, returns a 2-element \Array containing that key and its value:
* h = {foo: 0, bar: 1, baz: 2}
* h.assoc(:bar) # => [:bar, 1]
*
@@ -4139,30 +4227,30 @@ assoc_i(VALUE key, VALUE val, VALUE arg)
static VALUE
rb_hash_assoc(VALUE hash, VALUE key)
{
+ st_table *table;
+ const struct st_hash_type *orighash;
VALUE args[2];
if (RHASH_EMPTY_P(hash)) return Qnil;
- if (RHASH_ST_TABLE_P(hash) && !RHASH_IDENTHASH_P(hash)) {
- VALUE value = Qundef;
- st_table assoctable = *RHASH_ST_TABLE(hash);
- assoctable.type = &(struct st_hash_type){
- .compare = assoc_cmp,
- .hash = assoctable.type->hash,
- };
- VALUE arg = (VALUE)&(struct assoc_arg){
- .tbl = &assoctable,
- .key = (st_data_t)key,
- };
-
- if (RB_OBJ_FROZEN(hash)) {
- value = assoc_lookup(arg);
- }
- else {
- hash_iter_lev_inc(hash);
- value = rb_ensure(assoc_lookup, arg, hash_foreach_ensure, hash);
- }
- hash_verify(hash);
+ ar_force_convert_table(hash, __FILE__, __LINE__);
+ HASH_ASSERT(RHASH_ST_TABLE_P(hash));
+ table = RHASH_ST_TABLE(hash);
+ orighash = table->type;
+
+ if (!RHASH_IDENTHASH_P(hash)) {
+ VALUE value;
+ struct reset_hash_type_arg ensure_arg;
+ struct st_hash_type assochash;
+
+ assochash.compare = assoc_cmp;
+ assochash.hash = orighash->hash;
+ table->type = &assochash;
+ args[0] = hash;
+ args[1] = key;
+ ensure_arg.hash = hash;
+ ensure_arg.orighash = orighash;
+ value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
if (!UNDEF_P(value)) return rb_assoc_new(key, value);
}
@@ -4188,7 +4276,7 @@ rassoc_i(VALUE key, VALUE val, VALUE arg)
* call-seq:
* hash.rassoc(value) -> new_array or nil
*
- * Returns a new 2-element Array consisting of the key and value
+ * Returns a new 2-element \Array consisting of the key and value
* of the first-found entry whose value is <tt>==</tt> to value
* (see {Entry Order}[rdoc-ref:Hash@Entry+Order]):
* h = {foo: 0, bar: 1, baz: 1}
@@ -4225,7 +4313,7 @@ flatten_i(VALUE key, VALUE val, VALUE ary)
* hash.flatten -> new_array
* hash.flatten(level) -> new_array
*
- * Returns a new Array object that is a 1-dimensional flattening of +self+.
+ * Returns a new \Array object that is a 1-dimensional flattening of +self+.
*
* ---
*
@@ -4233,7 +4321,7 @@ flatten_i(VALUE key, VALUE val, VALUE ary)
* h = {foo: 0, bar: [:bat, 3], baz: 2}
* h.flatten # => [:foo, 0, :bar, [:bat, 3], :baz, 2]
*
- * Takes the depth of recursive flattening from Integer argument +level+:
+ * Takes the depth of recursive flattening from \Integer argument +level+:
* h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
* h.flatten(1) # => [:foo, 0, :bar, [:bat, [:baz, [:bat]]]]
* h.flatten(2) # => [:foo, 0, :bar, :bat, [:baz, [:bat]]]
@@ -4293,6 +4381,15 @@ delete_if_nil(VALUE key, VALUE value, VALUE hash)
return ST_CONTINUE;
}
+static int
+set_if_not_nil(VALUE key, VALUE value, VALUE hash)
+{
+ if (!NIL_P(value)) {
+ rb_hash_aset(hash, key, value);
+ }
+ return ST_CONTINUE;
+}
+
/*
* call-seq:
* hash.compact -> new_hash
@@ -4306,13 +4403,9 @@ delete_if_nil(VALUE key, VALUE value, VALUE hash)
static VALUE
rb_hash_compact(VALUE hash)
{
- VALUE result = rb_hash_dup(hash);
+ VALUE result = rb_hash_new();
if (!RHASH_EMPTY_P(hash)) {
- rb_hash_foreach(result, delete_if_nil, result);
- compact_after_delete(result);
- }
- else if (rb_hash_compare_by_id_p(hash)) {
- result = rb_hash_compare_by_id(result);
+ rb_hash_foreach(hash, set_if_not_nil, result);
}
return result;
}
@@ -4342,6 +4435,8 @@ rb_hash_compact_bang(VALUE hash)
return Qnil;
}
+static st_table *rb_init_identtable_with_size(st_index_t size);
+
/*
* call-seq:
* hash.compare_by_identity -> self
@@ -4379,33 +4474,16 @@ rb_hash_compare_by_id(VALUE hash)
if (rb_hash_compare_by_id_p(hash)) return hash;
rb_hash_modify_check(hash);
- if (hash_iterating_p(hash)) {
- rb_raise(rb_eRuntimeError, "compare_by_identity during iteration");
- }
-
- if (RHASH_TABLE_EMPTY_P(hash)) {
- // Fast path: There's nothing to rehash, so we don't need a `tmp` table.
- // We're most likely an AR table, so this will need an allocation.
- ar_force_convert_table(hash, __FILE__, __LINE__);
- HASH_ASSERT(RHASH_ST_TABLE_P(hash));
-
- RHASH_ST_TABLE(hash)->type = &identhash;
- }
- else {
- // Slow path: Need to rehash the members of `self` into a new
- // `tmp` table using the new `identhash` compare/hash functions.
- tmp = hash_alloc(0);
- hash_st_table_init(tmp, &identhash, RHASH_SIZE(hash));
- identtable = RHASH_ST_TABLE(tmp);
-
- rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
- rb_hash_free(hash);
+ ar_force_convert_table(hash, __FILE__, __LINE__);
+ HASH_ASSERT(RHASH_ST_TABLE_P(hash));
- // We know for sure `identtable` is an st table,
- // so we can skip `ar_force_convert_table` here.
- RHASH_ST_TABLE_SET(hash, identtable);
- RHASH_ST_CLEAR(tmp);
- }
+ tmp = hash_alloc(0);
+ identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
+ RHASH_ST_TABLE_SET(tmp, identtable);
+ rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
+ st_free_table(RHASH_ST_TABLE(hash));
+ RHASH_ST_TABLE_SET(hash, identtable);
+ RHASH_ST_CLEAR(tmp);
return hash;
}
@@ -4417,7 +4495,7 @@ rb_hash_compare_by_id(VALUE hash)
* Returns +true+ if #compare_by_identity has been called, +false+ otherwise.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
return RBOOL(RHASH_IDENTHASH_P(hash));
@@ -4427,7 +4505,7 @@ VALUE
rb_ident_hash_new(void)
{
VALUE hash = rb_hash_new();
- hash_st_table_init(hash, &identhash, 0);
+ RHASH_ST_TABLE_SET(hash, st_init_table(&identhash));
return hash;
}
@@ -4435,7 +4513,7 @@ VALUE
rb_ident_hash_new_with_size(st_index_t size)
{
VALUE hash = rb_hash_new();
- hash_st_table_init(hash, &identhash, size);
+ RHASH_ST_TABLE_SET(hash, st_init_table_with_size(&identhash, size));
return hash;
}
@@ -4445,6 +4523,12 @@ rb_init_identtable(void)
return st_init_table(&identhash);
}
+static st_table *
+rb_init_identtable_with_size(st_index_t size)
+{
+ return st_init_table_with_size(&identhash, size);
+}
+
static int
any_p_i(VALUE key, VALUE value, VALUE arg)
{
@@ -4487,9 +4571,6 @@ any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
* Returns +true+ if any element satisfies a given criterion;
* +false+ otherwise.
*
- * If +self+ has no element, returns +false+ and argument or block
- * are not used.
- *
* With no argument and no block,
* returns +true+ if +self+ is non-empty; +false+ if empty.
*
@@ -4508,8 +4589,6 @@ any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
* h = {foo: 0, bar: 1, baz: 2}
* h.any? {|key, value| value < 3 } # => true
* h.any? {|key, value| value > 3 } # => false
- *
- * Related: Enumerable#any?
*/
static VALUE
@@ -4687,7 +4766,7 @@ hash_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(key, hash))
* call-seq:
* hash.to_proc -> proc
*
- * Returns a Proc object that maps a key to its value:
+ * Returns a \Proc object that maps a key to its value:
* h = {foo: 0, bar: 1, baz: 2}
* proc = h.to_proc
* proc.class # => Proc
@@ -4701,7 +4780,6 @@ rb_hash_to_proc(VALUE hash)
return rb_func_lambda_new(hash_proc_call, hash, 1, 1);
}
-/* :nodoc: */
static VALUE
rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
{
@@ -4732,13 +4810,14 @@ rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
args[1] = val;
if (RHASH_AR_TABLE_P(hash)) {
+ hash_ar_table(hash);
+
ret = ar_update(hash, (st_data_t)key, add_new_i, (st_data_t)args);
if (ret != -1) {
return ret;
}
ar_force_convert_table(hash, __FILE__, __LINE__);
}
-
tbl = RHASH_TBL_RAW(hash);
return st_update(tbl, (st_data_t)key, add_new_i, (st_data_t)args);
@@ -4771,6 +4850,15 @@ rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
if (argc > 0) {
st_index_t size = argc / 2;
+ if (RHASH_TABLE_NULL_P(hash)) {
+ if (size <= RHASH_AR_TABLE_MAX_SIZE) {
+ hash_ar_table(hash);
+ }
+ else {
+ RHASH_TBL_RAW(hash);
+ }
+ }
+
if (RHASH_AR_TABLE_P(hash) &&
(RHASH_AR_TABLE_SIZE(hash) + size <= RHASH_AR_TABLE_MAX_SIZE)) {
ar_bulk_insert(hash, argc, argv);
@@ -4873,7 +4961,9 @@ has_env_with_lock(const char *name)
static const char TZ_ENV[] = "TZ";
static void *
-get_env_cstr(VALUE str, const char *name)
+get_env_cstr(
+ VALUE str,
+ const char *name)
{
char *var;
rb_encoding *enc = rb_enc_get(str);
@@ -4905,7 +4995,7 @@ env_name(volatile VALUE *s)
static VALUE env_aset(VALUE nm, VALUE val);
static void
-reset_by_modified_env(const char *nam)
+reset_by_modified_env(const char *nam, const char *val)
{
/*
* ENV['TZ'] = nil has a special meaning.
@@ -4914,7 +5004,7 @@ reset_by_modified_env(const char *nam)
* This hack might works only on Linux glibc.
*/
if (ENVMATCH(nam, TZ_ENV)) {
- ruby_reset_timezone();
+ ruby_reset_timezone(val);
}
}
@@ -4922,7 +5012,7 @@ static VALUE
env_delete(VALUE name)
{
const char *nam = env_name(name);
- reset_by_modified_env(nam);
+ reset_by_modified_env(nam, NULL);
VALUE val = getenv_with_lock(nam);
if (!NIL_P(val)) {
@@ -5196,7 +5286,7 @@ ruby_setenv(const char *name, const char *value)
}
ENV_UNLOCK();
- if (ret) rb_sys_fail_sprintf("setenv(%s)", name);
+ if (ret) rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
}
else {
#ifdef VOID_UNSETENV
@@ -5213,7 +5303,7 @@ ruby_setenv(const char *name, const char *value)
}
ENV_UNLOCK();
- if (ret) rb_sys_fail_sprintf("unsetenv(%s)", name);
+ if (ret) rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
#endif
}
#elif defined __sun
@@ -5230,7 +5320,7 @@ ruby_setenv(const char *name, const char *value)
mem_size = len + strlen(value) + 2;
mem_ptr = malloc(mem_size);
if (mem_ptr == NULL)
- rb_sys_fail_sprintf("malloc(%"PRIuSIZE")", mem_size);
+ rb_sys_fail_str(rb_sprintf("malloc(%"PRIuSIZE")", mem_size));
snprintf(mem_ptr, mem_size, "%s=%s", name, value);
}
@@ -5256,7 +5346,7 @@ ruby_setenv(const char *name, const char *value)
if (ret) {
free(mem_ptr);
- rb_sys_fail_sprintf("putenv(%s)", name);
+ rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
}
}
#else /* WIN32 */
@@ -5320,6 +5410,8 @@ ruby_unsetenv(const char *name)
* ENV[name] = value -> value
* ENV.store(name, value) -> value
*
+ * ENV.store is an alias for ENV.[]=.
+ *
* Creates, updates, or deletes the named environment variable, returning the value.
* Both +name+ and +value+ may be instances of String.
* See {Valid Names and Values}[rdoc-ref:ENV@Valid+Names+and+Values].
@@ -5380,7 +5472,7 @@ env_aset(VALUE nm, VALUE val)
get_env_ptr(value, val);
ruby_setenv(name, value);
- reset_by_modified_env(name);
+ reset_by_modified_env(name, value);
return val;
}
@@ -5560,7 +5652,7 @@ env_each_value(VALUE ehash)
* ENV.each_pair { |name, value| block } -> ENV
* ENV.each_pair -> an_enumerator
*
- * Yields each environment variable name and its value as a 2-element Array:
+ * Yields each environment variable name and its value as a 2-element \Array:
* h = {}
* ENV.each_pair { |name, value| h[name] = value } # => ENV
* h # => {"bar"=>"1", "foo"=>"0"}
@@ -5696,7 +5788,7 @@ env_delete_if(VALUE ehash)
* Returns +nil+ in the Array for each name that is not an ENV name:
* ENV.values_at('foo', 'bat', 'bar', 'bam') # => ["0", nil, "1", nil]
*
- * Returns an empty Array if no names given.
+ * Returns an empty \Array if no names given.
*
* Raises an exception if any name is invalid.
* See {Invalid Names and Values}[rdoc-ref:ENV@Invalid+Names+and+Values].
@@ -5721,6 +5813,8 @@ env_values_at(int argc, VALUE *argv, VALUE _)
* ENV.filter { |name, value| block } -> hash of name/value pairs
* ENV.filter -> an_enumerator
*
+ * ENV.filter is an alias for ENV.select.
+ *
* Yields each environment variable name and its value as a 2-element Array,
* returning a Hash of the names and values for which the block returns a truthy value:
* ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
@@ -5764,6 +5858,8 @@ env_select(VALUE ehash)
* ENV.filter! { |name, value| block } -> ENV or nil
* ENV.filter! -> an_enumerator
*
+ * ENV.filter! is an alias for ENV.select!.
+ *
* Yields each environment variable name and its value as a 2-element Array,
* deleting each entry for which the block returns +false+ or +nil+,
* and returning ENV if any deletions made, or +nil+ otherwise:
@@ -5931,24 +6027,23 @@ env_to_s(VALUE _)
static VALUE
env_inspect(VALUE _)
{
- VALUE i;
VALUE str = rb_str_buf_new2("{");
+ rb_encoding *enc = env_encoding();
ENV_LOCK();
{
char **env = GET_ENVIRON(environ);
while (*env) {
- char *s = strchr(*env, '=');
+ const char *s = strchr(*env, '=');
if (env != environ) {
rb_str_buf_cat2(str, ", ");
}
if (s) {
- rb_str_buf_cat2(str, "\"");
- rb_str_buf_cat(str, *env, s-*env);
- rb_str_buf_cat2(str, "\"=>");
- i = rb_inspect(rb_str_new2(s+1));
- rb_str_buf_append(str, i);
+ rb_str_buf_append(str, rb_str_inspect(env_enc_str_new(*env, s-*env, enc)));
+ rb_str_buf_cat2(str, "=>");
+ s++;
+ rb_str_buf_append(str, rb_str_inspect(env_enc_str_new(s, strlen(s), enc)));
}
env++;
}
@@ -6074,6 +6169,8 @@ env_empty_p(VALUE _)
* ENV.member?(name) -> true or false
* ENV.key?(name) -> true or false
*
+ * ENV.has_key?, ENV.member?, and ENV.key? are aliases for ENV.include?.
+ *
* Returns +true+ if there is an environment variable with the given +name+:
* ENV.replace('foo' => '0', 'bar' => '1')
* ENV.include?('foo') # => true
@@ -6554,6 +6651,8 @@ env_update_block_i(VALUE key, VALUE val, VALUE _)
* ENV.merge!(*hashes) -> ENV
* ENV.merge!(*hashes) { |name, env_val, hash_val| block } -> ENV
*
+ * ENV.update is an alias for ENV.merge!.
+ *
* Adds to ENV each key/value pair in the given +hash+; returns ENV:
* ENV.replace('foo' => '0', 'bar' => '1')
* ENV.merge!('baz' => '2', 'bat' => '3') # => {"bar"=>"1", "bat"=>"3", "baz"=>"2", "foo"=>"0"}
@@ -6645,8 +6744,8 @@ static const rb_data_type_t env_data_type = {
/*
* A \Hash maps each of its unique keys to a specific value.
*
- * A \Hash has certain similarities to an Array, but:
- * - An Array index is always an Integer.
+ * A \Hash has certain similarities to an \Array, but:
+ * - An \Array index is always an \Integer.
* - A \Hash key can be (almost) any object.
*
* === \Hash \Data Syntax
@@ -6656,14 +6755,14 @@ static const rb_data_type_t env_data_type = {
* h = {:foo => 0, :bar => 1, :baz => 2}
* h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * Alternatively, but only for a \Hash key that's a Symbol,
+ * Alternatively, but only for a \Hash key that's a \Symbol,
* you can use a newer JSON-style syntax,
- * where each bareword becomes a Symbol:
+ * where each bareword becomes a \Symbol:
*
* h = {foo: 0, bar: 1, baz: 2}
* h # => {:foo=>0, :bar=>1, :baz=>2}
*
- * You can also use a String in place of a bareword:
+ * You can also use a \String in place of a bareword:
*
* h = {'foo': 0, 'bar': 1, 'baz': 2}
* h # => {:foo=>0, :bar=>1, :baz=>2}
@@ -6788,7 +6887,7 @@ static const rb_data_type_t env_data_type = {
*
* - Iterative methods such as <tt>each</tt>, <tt>each_key</tt>, <tt>each_pair</tt>, <tt>each_value</tt>.
* - Other order-sensitive methods such as <tt>shift</tt>, <tt>keys</tt>, <tt>values</tt>.
- * - The String returned by method <tt>inspect</tt>.
+ * - The \String returned by method <tt>inspect</tt>.
*
* A new \Hash has its initial ordering per the given entries:
*
@@ -6847,9 +6946,9 @@ static const rb_data_type_t env_data_type = {
* h.include?(a0) # => true
* h[a0] # => 0
*
- * A String key is always safe.
- * That's because an unfrozen String
- * passed as a key will be replaced by a duplicated and frozen String:
+ * A \String key is always safe.
+ * That's because an unfrozen \String
+ * passed as a key will be replaced by a duplicated and frozen \String:
*
* s = 'foo'
* s.frozen? # => false
@@ -6863,9 +6962,9 @@ static const rb_data_type_t env_data_type = {
* Note: this requirement does not apply if the \Hash uses #compare_by_identity since comparison will then
* rely on the keys' object id instead of <code>hash</code> and <code>eql?</code>.
*
- * Object defines basic implementation for <code>hash</code> and <code>eq?</code> that makes each object
+ * \Object defines basic implementation for <code>hash</code> and <code>eq?</code> that makes each object
* a distinct key. Typically, user-defined classes will want to override these methods to provide meaningful
- * behavior, or for example inherit Struct that has useful definitions for these.
+ * behavior, or for example inherit \Struct that has useful definitions for these.
*
* A typical implementation of <code>hash</code> is based on the
* object's data while <code>eql?</code> is usually aliased to the overridden
@@ -6888,7 +6987,7 @@ static const rb_data_type_t env_data_type = {
* alias eql? ==
*
* def hash
- * [self.class, @author, @title].hash
+ * @author.hash ^ @title.hash # XOR
* end
* end
*
@@ -6946,7 +7045,7 @@ static const rb_data_type_t env_data_type = {
*
* To use a mutable object as default, it is recommended to use a default proc
*
- * ==== Default Proc
+ * ==== Default \Proc
*
* When the default proc for a \Hash is set (i.e., not +nil+),
* the default value returned by method #[] is determined by the default proc alone.
@@ -6986,10 +7085,6 @@ static const rb_data_type_t env_data_type = {
*
* Note that setting the default proc will clear the default value and vice versa.
*
- * Be aware that a default proc that modifies the hash is not thread-safe in the
- * sense that multiple threads can call into the default proc concurrently for the
- * same key.
- *
* === What's Here
*
* First, what's elsewhere. \Class \Hash:
@@ -7047,7 +7142,7 @@ static const rb_data_type_t env_data_type = {
* - #<=: Returns whether +self+ is a subset of a given object.
* - #==: Returns whether a given object is equal to +self+.
* - #>: Returns whether +self+ is a proper superset of a given object
- * - #>=: Returns whether +self+ is a superset of a given object.
+ * - #>=: Returns whether +self+ is a proper superset of a given object.
*
* ==== Methods for Fetching
*
@@ -7060,7 +7155,7 @@ static const rb_data_type_t env_data_type = {
* - #key: Returns the key for the first-found entry with a given value.
* - #keys: Returns an array containing all keys in +self+.
* - #rassoc: Returns a 2-element array consisting of the key and value
- * of the first-found entry having a given value.
+ of the first-found entry having a given value.
* - #values: Returns an array containing all values in +self+/
* - #values_at: Returns an array containing values for given keys.
*
@@ -7225,15 +7320,15 @@ Init_Hash(void)
/* Document-class: ENV
*
- * \ENV is a hash-like accessor for environment variables.
+ * ENV is a hash-like accessor for environment variables.
*
* === Interaction with the Operating System
*
- * The \ENV object interacts with the operating system's environment variables:
+ * The ENV object interacts with the operating system's environment variables:
*
- * - When you get the value for a name in \ENV, the value is retrieved from among the current environment variables.
- * - When you create or set a name-value pair in \ENV, the name and value are immediately set in the environment variables.
- * - When you delete a name-value pair in \ENV, it is immediately deleted from the environment variables.
+ * - When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
+ * - When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
+ * - When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
*
* === Names and Values
*
@@ -7283,24 +7378,24 @@ Init_Hash(void)
*
* === About Ordering
*
- * \ENV enumerates its name/value pairs in the order found
+ * ENV enumerates its name/value pairs in the order found
* in the operating system's environment variables.
- * Therefore the ordering of \ENV content is OS-dependent, and may be indeterminate.
+ * Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
*
* This will be seen in:
- * - A Hash returned by an \ENV method.
- * - An Enumerator returned by an \ENV method.
+ * - A Hash returned by an ENV method.
+ * - An Enumerator returned by an ENV method.
* - An Array returned by ENV.keys, ENV.values, or ENV.to_a.
* - The String returned by ENV.inspect.
* - The Array returned by ENV.shift.
* - The name returned by ENV.key.
*
* === About the Examples
- * Some methods in \ENV return \ENV itself. Typically, there are many environment variables.
- * It's not useful to display a large \ENV in the examples here,
- * so most example snippets begin by resetting the contents of \ENV:
- * - ENV.replace replaces \ENV with a new collection of entries.
- * - ENV.clear empties \ENV.
+ * Some methods in ENV return ENV itself. Typically, there are many environment variables.
+ * It's not useful to display a large ENV in the examples here,
+ * so most example snippets begin by resetting the contents of ENV:
+ * - ENV.replace replaces ENV with a new collection of entries.
+ * - ENV.clear empties ENV.
*
* == What's Here
*
@@ -7360,8 +7455,8 @@ Init_Hash(void)
* - ::except: Returns a hash of all name/value pairs except those given.
* - ::fetch: Returns the value for the given name.
* - ::inspect: Returns the contents of \ENV as a string.
- * - ::invert: Returns a hash whose keys are the \ENV values,
- and whose values are the corresponding \ENV names.
+ * - ::invert: Returns a hash whose keys are the ENV values,
+ and whose values are the corresponding ENV names.
* - ::keys: Returns an array of all names.
* - ::rassoc: Returns the name and value of the first found entry
* that has the given value.
@@ -7450,7 +7545,7 @@ Init_Hash(void)
rb_undef_method(envtbl_class, "initialize_dup");
/*
- * \ENV is a Hash-like accessor for environment variables.
+ * ENV is a Hash-like accessor for environment variables.
*
* See ENV (the class) for more details.
*/
diff --git a/id_table.c b/id_table.c
index 650721c670..a9a041b955 100644
--- a/id_table.c
+++ b/id_table.c
@@ -92,7 +92,7 @@ rb_id_table_init(struct rb_id_table *tbl, int capa)
return tbl;
}
-struct rb_id_table *
+MJIT_FUNC_EXPORTED struct rb_id_table *
rb_id_table_create(size_t capa)
{
struct rb_id_table *tbl = ALLOC(struct rb_id_table);
@@ -223,7 +223,7 @@ hash_table_show(struct rb_id_table *tbl)
}
#endif
-int
+MJIT_FUNC_EXPORTED int
rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
{
id_key_t key = id2key(id);
@@ -253,7 +253,7 @@ rb_id_table_insert_key(struct rb_id_table *tbl, const id_key_t key, const VALUE
return TRUE;
}
-int
+MJIT_FUNC_EXPORTED int
rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
{
return rb_id_table_insert_key(tbl, id2key(id), val);
diff --git a/include/ruby/atomic.h b/include/ruby/atomic.h
index eb106631f6..3eb80fbf7d 100644
--- a/include/ruby/atomic.h
+++ b/include/ruby/atomic.h
@@ -139,15 +139,6 @@ typedef unsigned int rb_atomic_t;
rbimpl_atomic_cas(&(var), (oldval), (newval))
/**
- * Atomic load. This loads `var` with an atomic intrinsic and returns
- * its value.
- *
- * @param var A variable of ::rb_atomic_t
- * @return What was stored in `var`j
- */
-#define RUBY_ATOMIC_LOAD(var) rbimpl_atomic_load(&(var))
-
-/**
* Identical to #RUBY_ATOMIC_EXCHANGE, except for the return type.
*
* @param var A variable of ::rb_atomic_t.
@@ -289,17 +280,6 @@ typedef unsigned int rb_atomic_t;
RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))
/**
- * Identical to #RUBY_ATOMIC_LOAD, except it expects its arguments are `void*`.
- * There are cases where ::rb_atomic_t is 32bit while `void*` is 64bit. This
- * should be used for size related operations to support such platforms.
- *
- * @param var A variable of `void*`
- * @return The value of `var` (without tearing)
- */
-#define RUBY_ATOMIC_PTR_LOAD(var) \
- RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var))
-
-/**
* Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are `void*`.
* There are cases where ::rb_atomic_t is 32bit while `void*` is 64bit. This
* should be used for size related operations to support such platforms.
@@ -769,21 +749,6 @@ rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val)
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
-static inline rb_atomic_t
-rbimpl_atomic_load(volatile rb_atomic_t *ptr)
-{
-#if 0
-
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
- return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
-#else
- return rbimpl_atomic_fetch_add(ptr, 0);
-#endif
-}
-
-RBIMPL_ATTR_ARTIFICIAL()
-RBIMPL_ATTR_NOALIAS()
-RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_set(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
@@ -910,22 +875,6 @@ rbimpl_atomic_ptr_cas(void **ptr, const void *oldval, const void *newval)
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
-static inline void *
-rbimpl_atomic_ptr_load(void **ptr)
-{
-#if 0
-
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
- return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
-#else
- void *val = *ptr;
- return rbimpl_atomic_ptr_cas(ptr, val, val);
-#endif
-}
-
-RBIMPL_ATTR_ARTIFICIAL()
-RBIMPL_ATTR_NOALIAS()
-RBIMPL_ATTR_NONNULL((1))
static inline VALUE
rbimpl_atomic_value_cas(volatile VALUE *ptr, VALUE oldval, VALUE newval)
{
diff --git a/include/ruby/backward/2/attributes.h b/include/ruby/backward/2/attributes.h
index 916d9e9d5b..73acfc9dc0 100644
--- a/include/ruby/backward/2/attributes.h
+++ b/include/ruby/backward/2/attributes.h
@@ -39,7 +39,6 @@
#include "ruby/internal/attr/noinline.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
-#include "ruby/internal/attr/packed_struct.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
@@ -81,8 +80,10 @@
#undef NOINLINE
#define NOINLINE(x) RBIMPL_ATTR_NOINLINE() x
-#undef ALWAYS_INLINE
-#define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x
+#ifndef MJIT_HEADER
+# undef ALWAYS_INLINE
+# define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x
+#endif
#undef ERRORFUNC
#define ERRORFUNC(mesg, x) RBIMPL_ATTR_ERROR(mesg) x
@@ -146,14 +147,17 @@
#define NORETURN(x) RBIMPL_ATTR_NORETURN() x
#define NORETURN_STYLE_NEW
-#undef PACKED_STRUCT
-#define PACKED_STRUCT(x) \
- RBIMPL_ATTR_PACKED_STRUCT_BEGIN() x RBIMPL_ATTR_PACKED_STRUCT_END()
+#ifndef PACKED_STRUCT
+# define PACKED_STRUCT(x) x
+#endif
-#undef PACKED_STRUCT_UNALIGNED
-#define PACKED_STRUCT_UNALIGNED(x) \
- RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN() x \
- RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END()
+#ifndef PACKED_STRUCT_UNALIGNED
+# if UNALIGNED_WORD_ACCESS
+# define PACKED_STRUCT_UNALIGNED(x) PACKED_STRUCT(x)
+# else
+# define PACKED_STRUCT_UNALIGNED(x) x
+# endif
+#endif
#undef RB_UNUSED_VAR
#define RB_UNUSED_VAR(x) x RBIMPL_ATTR_MAYBE_UNUSED()
diff --git a/include/ruby/debug.h b/include/ruby/debug.h
index f7c8e6ca8d..f95acdb17e 100644
--- a/include/ruby/debug.h
+++ b/include/ruby/debug.h
@@ -10,7 +10,6 @@
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
-#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
@@ -52,25 +51,6 @@ RBIMPL_ATTR_NONNULL((3))
int rb_profile_frames(int start, int limit, VALUE *buff, int *lines);
/**
- * Queries mysterious "frame"s of the given range.
- *
- * A per-thread version of rb_profile_frames().
- * Arguments and return values are the same with rb_profile_frames() with the
- * exception of the first argument _thread_, which accepts the Thread to be
- * profiled/queried.
- *
- * @param[in] thread The Ruby Thread to be profiled.
- * @param[in] start Start position (0 means the topmost).
- * @param[in] limit Number objects of `buff`.
- * @param[out] buff Return buffer.
- * @param[out] lines Return buffer.
- * @return Number of objects filled into `buff`.
- * @post `buff` is filled with backtrace pointers.
- * @post `lines` is filled with `__LINE__` of each backtraces.
- */
-int rb_profile_thread_frames(VALUE thread, int start, int limit, VALUE *buff, int *lines);
-
-/**
* Queries the path of the passed backtrace.
*
* @param[in] frame What rb_profile_frames() returned.
@@ -616,157 +596,48 @@ VALUE rb_tracearg_object(rb_trace_arg_t *trace_arg);
/*
* Postponed Job API
- *
- * This API is designed to be called from contexts where it is not safe to run Ruby
- * code (e.g. because they do not hold the GVL or because GC is in progress), and
- * defer a callback to run in a context where it _is_ safe. The primary intended
- * users of this API is for sampling profilers like the "stackprof" gem; these work
- * by scheduling the periodic delivery of a SIGPROF signal, and inside the C-level
- * signal handler, deferring a job to collect a Ruby backtrace when it is next safe
- * to do so.
- *
- * Ruby maintains a small, fixed-size postponed job table. An extension using this
- * API should first call `rb_postponed_job_preregister` to register a callback
- * function in this table and obtain a handle of type `rb_postponed_job_handle_t`
- * to it. Subsequently, the callback can be triggered by calling
- * `rb_postponed_job_trigger` with that handle, or the `data` associated with the
- * callback function can be changed by calling `rb_postponed_job_preregister` again.
- *
- * Because the postponed job table is quite small (it only has 32 entries on most
- * common systems), extensions should generally only preregister one or two `func`
- * values.
- *
- * Historically, this API provided two functions `rb_postponed_job_register` and
- * `rb_postponed_job_register_one`, which claimed to be fully async-signal-safe and
- * would call back the provided `func` and `data` at an appropriate time. However,
- * these functions were subject to race conditions which could cause crashes when
- * racing with Ruby's internal use of them. These two functions are still present,
- * but are marked as deprecated and have slightly changed semantics:
- *
- * * rb_postponed_job_register now works like rb_postponed_job_register_one i.e.
- * `func` will only be executed at most one time each time Ruby checks for
- * interrupts, no matter how many times it is registered
- * * They are also called with the last `data` to be registered, not the first
- * (which is how rb_postponed_job_register_one previously worked)
+ * rb_postponed_job_register and rb_postponed_job_register_one are
+ * async-signal-safe and used via SIGPROF by the "stackprof" RubyGem
*/
-
/**
* Type of postponed jobs.
*
- * @param[in,out] arg What was passed to `rb_postponed_job_preregister`
+ * @param[in,out] arg What was passed to rb_postponed_job_register().
*/
typedef void (*rb_postponed_job_func_t)(void *arg);
/**
- * The type of a handle returned from `rb_postponed_job_preregister` and
- * passed to `rb_postponed_job_trigger`
- */
-typedef unsigned int rb_postponed_job_handle_t;
-#define POSTPONED_JOB_HANDLE_INVALID ((rb_postponed_job_handle_t)UINT_MAX)
-
-/**
- * Pre-registers a func in Ruby's postponed job preregistration table,
- * returning an opaque handle which can be used to trigger the job later. Generally,
- * this function will be called during the initialization routine of an extension.
+ * Registers a postponed job.
*
- * The returned handle can be used later to call `rb_postponed_job_trigger`. This will
- * cause Ruby to call back into the registered `func` with `data` at a later time, in
- * a context where the GVL is held and it is safe to perform Ruby allocations.
+ * There are situations when running a ruby program is not possible. For
+ * instance when a program is in a signal handler; for another instance when
+ * the GC is busy. On such situations however, there might be needs to do
+ * something. We cannot but defer such operations until we are 100% sure it is
+ * safe to execute them. This mechanism is called postponed jobs. This
+ * function registers a new one. The registered job would eventually gets
+ * executed.
*
- * If the given `func` was already pre-registered, this function will overwrite the
- * stored data with the newly passed data, and return the same handle instance as
- * was previously returned.
- *
- * If this function is called concurrently with the same `func`, then the stored data
- * could be the value from either call (but will definitely be one of them).
- *
- * If this function is called to update the data concurrently with a call to
- * `rb_postponed_job_trigger` on the same handle, it's undefined whether `func` will
- * be called with the old data or the new data.
- *
- * Although the current implementation of this function is in fact async-signal-safe and
- * has defined semantics when called concurrently on the same `func`, a future Ruby
- * version might require that this method be called under the GVL; thus, programs which
- * aim to be forward-compatible should call this method whilst holding the GVL.
- *
- * @param[in] flags Unused and ignored
- * @param[in] func The function to be pre-registered
- * @param[in] data The data to be pre-registered
- * @retval POSTPONED_JOB_HANDLE_INVALID The job table is full; this registration
- * did not succeed and no further registration will do so for
- * the lifetime of the program.
- * @retval otherwise A handle which can be passed to `rb_postponed_job_trigger`
- */
-rb_postponed_job_handle_t rb_postponed_job_preregister(unsigned int flags, rb_postponed_job_func_t func, void *data);
-
-/**
- * Triggers a pre-registered job registered with rb_postponed_job_preregister,
- * scheduling it for execution the next time the Ruby VM checks for interrupts.
- * The context in which the job is called in holds the GVL and is safe to perform
- * Ruby allocations within (i.e. it is not during GC).
- *
- * This method is async-signal-safe and can be called from any thread, at any
- * time, including in signal handlers.
- *
- * If this method is called multiple times, Ruby will coalesce this into only
- * one call to the job the next time it checks for interrupts.
- *
- * @params[in] h A handle returned from rb_postponed_job_preregister
- */
-void rb_postponed_job_trigger(rb_postponed_job_handle_t h);
-
-/**
- * Schedules the given `func` to be called with `data` when Ruby next checks for
- * interrupts. If this function is called multiple times in between Ruby checking
- * for interrupts, then `func` will be called only once with the `data` value from
- * the first call to this function.
- *
- * Like `rb_postponed_job_trigger`, the context in which the job is called
- * holds the GVL and can allocate Ruby objects.
- *
- * This method essentially has the same semantics as:
- *
- * ```
- * rb_postponed_job_trigger(rb_postponed_job_preregister(func, data));
- * ```
- *
- * @note Previous versions of Ruby promised that the (`func`, `data`) pairs would
- * be executed as many times as they were registered with this function; in
- * reality this was always subject to race conditions and this function no
- * longer provides this guarantee. Instead, multiple calls to this function
- * can be coalesced into a single execution of the passed `func`, with the
- * most recent `data` registered at that time passed in.
- *
- * @deprecated This interface implies that arbitrarily many `func`'s can be enqueued
- * over the lifetime of the program, whilst in reality the registration
- * slots for postponed jobs are a finite resource. This is made clearer
- * by the `rb_postponed_job_preregister` and `rb_postponed_job_trigger`
- * functions, and a future version of Ruby might delete this function.
- *
- * @param[in] flags Unused and ignored.
+ * @param[in] flags (Unused) reserved for future extensions.
* @param[in] func Job body.
* @param[in,out] data Passed as-is to `func`.
- * @retval 0 Postponed job registration table is full. Failed.
- * @retval 1 Registration succeeded.
- * @post The passed job will run on the next interrupt check.
+ * @retval 0 Postponed job buffer is full. Failed.
+ * @retval otherwise Opaque return value.
+ * @post The passed job is postponed.
*/
- RBIMPL_ATTR_DEPRECATED(("use rb_postponed_job_preregister and rb_postponed_job_trigger"))
int rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data);
/**
- * Identical to `rb_postponed_job_register`
- *
- * @deprecated This is deprecated for the same reason as `rb_postponed_job_register`
+ * Identical to rb_postponed_job_register_one(), except it additionally checks
+ * for duplicated registration. In case the passed job is already in the
+ * postponed job buffer this function does nothing.
*
- * @param[in] flags Unused and ignored.
+ * @param[in] flags (Unused) reserved for future extensions.
* @param[in] func Job body.
* @param[in,out] data Passed as-is to `func`.
- * @retval 0 Postponed job registration table is full. Failed.
- * @retval 1 Registration succeeded.
- * @post The passed job will run on the next interrupt check.
+ * @retval 0 Postponed job buffer is full. Failed.
+ * @retval otherwise Opaque return value.
*/
- RBIMPL_ATTR_DEPRECATED(("use rb_postponed_job_preregister and rb_postponed_job_trigger"))
int rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data);
/** @} */
diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h
index 8f3d383330..250b39b6df 100644
--- a/include/ruby/fiber/scheduler.h
+++ b/include/ruby/fiber/scheduler.h
@@ -97,7 +97,7 @@ VALUE rb_fiber_scheduler_get(void);
* current thread will call scheduler's `#close` method on finalisation
* (allowing the scheduler to properly manage all non-finished fibers).
* `scheduler` can be an object of any class corresponding to
- * `Fiber::Scheduler` interface. Its implementation is up to the user.
+ * `Fiber::SchedulerInterface`. Its implementation is up to the user.
*
* @param[in] scheduler The scheduler to set.
* @exception rb_eArgError `scheduler` does not conform the interface.
@@ -267,10 +267,10 @@ VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv);
* Non-blocking read from the passed IO.
*
* @param[in] scheduler Target scheduler.
- * @param[in] io An io object to read from.
- * @param[in] buffer The buffer to read to.
- * @param[in] length The minimum number of bytes to read.
- * @param[in] offset The offset in the buffer to read from.
+ * @param[out] io An io object to read from.
+ * @param[out] buffer Return buffer.
+ * @param[in] length Requested number of bytes to read.
+ * @param[in] offset The offset in the buffer to read to.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns `[-errno, size]`.
*/
@@ -280,9 +280,9 @@ VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t
* Non-blocking write to the passed IO.
*
* @param[in] scheduler Target scheduler.
- * @param[in] io An io object to write to.
- * @param[in] buffer The buffer to write from.
- * @param[in] length The minimum number of bytes to write.
+ * @param[out] io An io object to write to.
+ * @param[in] buffer What to write.
+ * @param[in] length Number of bytes to write.
* @param[in] offset The offset in the buffer to write from.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns `[-errno, size]`.
@@ -293,10 +293,10 @@ VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_
* Non-blocking read from the passed IO at the specified offset.
*
* @param[in] scheduler Target scheduler.
- * @param[in] io An io object to read from.
- * @param[in] from The offset to read from.
- * @param[in] buffer The buffer to read to.
- * @param[in] length The minimum number of bytes to read.
+ * @param[out] io An io object to read from.
+ * @param[in] from The offset in the given IO to read the data from.
+ * @param[out] buffer The buffer to read the data to.
+ * @param[in] length Requested number of bytes to read.
* @param[in] offset The offset in the buffer to read to.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns.
@@ -307,10 +307,10 @@ VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALU
* Non-blocking write to the passed IO at the specified offset.
*
* @param[in] scheduler Target scheduler.
- * @param[in] io An io object to write to.
- * @param[in] from The offset to write to.
- * @param[in] buffer The buffer to write from.
- * @param[in] length The minimum number of bytes to write.
+ * @param[out] io An io object to write to.
+ * @param[in] from The offset in the given IO to write the data to.
+ * @param[in] buffer The buffer to write the data from.
+ * @param[in] length Number of bytes to write.
* @param[in] offset The offset in the buffer to write from.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns.
@@ -321,55 +321,27 @@ VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VAL
* Non-blocking read from the passed IO using a native buffer.
*
* @param[in] scheduler Target scheduler.
- * @param[in] io An io object to read from.
- * @param[in] base The memory to read to.
- * @param[in] size Size of the memory.
- * @param[in] length The minimum number of bytes to read.
+ * @param[out] io An io object to read from.
+ * @param[out] buffer Return buffer.
+ * @param[in] size Size of the return buffer.
+ * @param[in] length Requested number of bytes to read.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns.
*/
-VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *base, size_t size, size_t length);
+VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *buffer, size_t size, size_t length);
/**
* Non-blocking write to the passed IO using a native buffer.
*
* @param[in] scheduler Target scheduler.
- * @param[in] io An io object to write to.
- * @param[in] base The memory to write from.
- * @param[in] size Size of the memory.
- * @param[in] length The minimum number of bytes to write.
- * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
- * @return otherwise What `scheduler.io_write` returns.
- */
-VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *base, size_t size, size_t length);
-
-/**
- * Non-blocking pread from the passed IO using a native buffer.
- *
- * @param[in] scheduler Target scheduler.
- * @param[in] io An io object to read from.
- * @param[in] from The offset to read from.
- * @param[in] base The memory to read to.
- * @param[in] size Size of the memory.
- * @param[in] length The minimum number of bytes to read.
- * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
- * @return otherwise What `scheduler.io_read` returns.
- */
-VALUE rb_fiber_scheduler_io_pread_memory(VALUE scheduler, VALUE io, rb_off_t from, void *base, size_t size, size_t length);
-
-/**
- * Non-blocking pwrite to the passed IO using a native buffer.
- *
- * @param[in] scheduler Target scheduler.
- * @param[in] io An io object to write to.
- * @param[in] from The offset to write from.
- * @param[in] base The memory to write from.
- * @param[in] size Size of the memory.
- * @param[in] length The minimum number of bytes to write.
+ * @param[out] io An io object to write to.
+ * @param[in] buffer What to write.
+ * @param[in] size Size of the buffer.
+ * @param[in] length Number of bytes to write.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns.
*/
-VALUE rb_fiber_scheduler_io_pwrite_memory(VALUE scheduler, VALUE io, rb_off_t from, const void *base, size_t size, size_t length);
+VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *buffer, size_t size, size_t length);
/**
* Non-blocking close the given IO.
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 48e4cd546e..2480e2e703 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -36,6 +36,7 @@
#include "ruby/internal/intern/error.h"
#include "ruby/internal/intern/eval.h"
#include "ruby/internal/intern/file.h"
+#include "ruby/internal/intern/gc.h"
#include "ruby/internal/intern/hash.h"
#include "ruby/internal/intern/io.h"
#include "ruby/internal/intern/load.h"
diff --git a/include/ruby/internal/abi.h b/include/ruby/internal/abi.h
index 8e1bbf3951..44111a0055 100644
--- a/include/ruby/internal/abi.h
+++ b/include/ruby/internal/abi.h
@@ -24,7 +24,7 @@
* In released versions of Ruby, this number is not defined since teeny
* versions of Ruby should guarantee ABI compatibility.
*/
-#define RUBY_ABI_VERSION 0
+#define RUBY_ABI_VERSION 3
/* Windows does not support weak symbols so ruby_abi_version will not exist
* in the shared library. */
diff --git a/include/ruby/internal/anyargs.h b/include/ruby/internal/anyargs.h
index e3e1b6166d..e4c6d155cc 100644
--- a/include/ruby/internal/anyargs.h
+++ b/include/ruby/internal/anyargs.h
@@ -84,12 +84,15 @@
#elif defined(_WIN32) || defined(__CYGWIN__)
# /* Skip due to [Bug #16134] */
+# define RBIMPL_CAST_FN_PTR 1
#elif ! RBIMPL_HAS_ATTRIBUTE(transparent_union)
# /* :TODO: improve here, please find a way to support. */
+# define RBIMPL_CAST_FN_PTR 1
#elif ! defined(HAVE_VA_ARGS_MACRO)
# /* :TODO: improve here, please find a way to support. */
+# define RBIMPL_CAST_FN_PTR 1
#else
# /** @cond INTERNAL_MACRO */
@@ -348,6 +351,25 @@ RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
#endif /* __cplusplus */
+#if defined(RBIMPL_CAST_FN_PTR) && !defined(__cplusplus)
+/* In C23, K&R style prototypes are gone and so `void foo(ANYARGS)` became
+ * equivalent to `void foo(void)` unlike in earlier versions. This is a problem
+ * for rb_define_* functions since that makes all valid functions one can pass
+ * trip -Wincompatible-pointer-types, which we treat as errors. This is mostly
+ * not a problem for the __builtin_choose_expr path, but outside of that we
+ * need to add a cast for compatibility.
+ */
+#define rb_define_method(klass, mid, func, arity) rb_define_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_method_id(klass, mid, func, arity) rb_define_method_id((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_singleton_method(obj, mid, func, arity) rb_define_singleton_method((obj), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_protected_method(klass, mid, func, arity) rb_define_protected_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_private_method(klass, mid, func, arity) rb_define_private_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_module_function(mod, mid, func, arity) rb_define_module_function((mod), (mid), (VALUE (*)(ANYARGS))(func), (arity))
+#define rb_define_global_function(mid, func, arity) rb_define_global_function((mid), (VALUE (*)(ANYARGS))(func), (arity))
+
+#undef RBIMPL_CAST_FN_PTR
+#endif /* defined(RBIMPL_CAST_FN_PTR) && !defined(__cplusplus) */
+
/**
* This macro is to properly cast a function parameter of *_define_method
* family. It has been around since 1.x era so you can maximise backwards
diff --git a/include/ruby/internal/attr/noexcept.h b/include/ruby/internal/attr/noexcept.h
index 7c3f92f1e7..ea3001df2a 100644
--- a/include/ruby/internal/attr/noexcept.h
+++ b/include/ruby/internal/attr/noexcept.h
@@ -54,7 +54,7 @@
* get smarter and smarter. Today they can infer if it actually throws
* or not without any annotations by humans (correct me if I'm wrong).
*
- * - When an inline function attributed `noexcept` actually _does_ throw an
+ * - When an inline function attributed `noexcepr` actually _does_ throw an
* exception: they have to call `std::terminate` then (C++ standard
* mandates so). This means exception handling routines are actually
* enforced, not omitted. This doesn't impact runtime performance (The
diff --git a/include/ruby/internal/attr/nonstring.h b/include/ruby/internal/attr/nonstring.h
new file mode 100644
index 0000000000..de26e926d4
--- /dev/null
+++ b/include/ruby/internal/attr/nonstring.h
@@ -0,0 +1,32 @@
+#ifndef RBIMPL_ATTR_NONSTRING_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_ATTR_NONSTRING_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Defines #RBIMPL_ATTR_NONSTRING.
+ */
+#include "ruby/internal/has/attribute.h"
+
+/** Wraps (or simulates) `__attribute__((nonstring))` */
+#if RBIMPL_HAS_ATTRIBUTE(nonstring)
+# define RBIMPL_ATTR_NONSTRING() __attribute__((nonstring))
+#else
+# define RBIMPL_ATTR_NONSTRING() /* void */
+#endif
+
+#endif /* RBIMPL_ATTR_NONSTRING_H */
diff --git a/include/ruby/internal/attr/packed_struct.h b/include/ruby/internal/attr/packed_struct.h
deleted file mode 100644
index 0678b9acc8..0000000000
--- a/include/ruby/internal/attr/packed_struct.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef RBIMPL_ATTR_PACKED_STRUCT_H /*-*-C++-*-vi:se ft=cpp:*/
-#define RBIMPL_ATTR_PACKED_STRUCT_H
-/**
- * @file
- * @author Ruby developers <ruby-core@ruby-lang.org>
- * @copyright This file is a part of the programming language Ruby.
- * Permission is hereby granted, to either redistribute and/or
- * modify this file, provided that the conditions mentioned in the
- * file COPYING are met. Consult the file for details.
- * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
- * implementation details. Don't take them as canon. They could
- * rapidly appear then vanish. The name (path) of this header file
- * is also an implementation detail. Do not expect it to persist
- * at the place it is now. Developers are free to move it anywhere
- * anytime at will.
- * @note To ruby-core: remember that this header can be possibly
- * recursively included from extension libraries written in C++.
- * Do not expect for instance `__VA_ARGS__` is always available.
- * We assume C99 for ruby itself but we don't assume languages of
- * extension libraries. They could be written in C++98.
- * @brief Defines #RBIMPL_ATTR_PACKED_STRUCT_BEGIN,
- * #RBIMPL_ATTR_PACKED_STRUCT_END,
- * #RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN, and
- * #RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END.
- */
-#include "ruby/internal/config.h"
-
-#ifndef RBIMPL_ATTR_PACKED_STRUCT_BEGIN
-# define RBIMPL_ATTR_PACKED_STRUCT_BEGIN() /* void */
-#endif
-#ifndef RBIMPL_ATTR_PACKED_STRUCT_END
-# define RBIMPL_ATTR_PACKED_STRUCT_END() /* void */
-#endif
-
-#if UNALIGNED_WORD_ACCESS
-# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN() RBIMPL_ATTR_PACKED_STRUCT_BEGIN()
-# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END() RBIMPL_ATTR_PACKED_STRUCT_END()
-#else
-# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN() /* void */
-# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END() /* void */
-#endif
-
-#endif
diff --git a/include/ruby/internal/config.h b/include/ruby/internal/config.h
index da070f0979..aa63376d7c 100644
--- a/include/ruby/internal/config.h
+++ b/include/ruby/internal/config.h
@@ -148,4 +148,8 @@
# undef RBIMPL_TEST3
#endif /* HAVE_VA_ARGS_MACRO */
+#ifndef USE_RVARGC
+# define USE_RVARGC 1
+#endif
+
#endif /* RBIMPL_CONFIG_H */
diff --git a/include/ruby/internal/core/rarray.h b/include/ruby/internal/core/rarray.h
index 90690fe794..c3bb40be25 100644
--- a/include/ruby/internal/core/rarray.h
+++ b/include/ruby/internal/core/rarray.h
@@ -29,13 +29,25 @@
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
-#include "ruby/internal/gc.h"
+#include "ruby/internal/rgengc.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"
/**
+ * @private
+ * @warning Do not touch this macro.
+ * @warning It is an implementation detail.
+ * @warning The value of this macro must match for ruby itself and all
+ * extension libraries, otherwise serious memory corruption shall
+ * occur.
+ */
+#ifndef USE_TRANSIENT_HEAP
+# define USE_TRANSIENT_HEAP 1
+#endif
+
+/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RArray.
@@ -47,9 +59,15 @@
#define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
+#if USE_TRANSIENT_HEAP
+# define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
+#else
+# define RARRAY_TRANSIENT_FLAG 0
+#endif
/** @endcond */
#define RARRAY_LEN rb_array_len /**< @alias{rb_array_len} */
#define RARRAY_CONST_PTR rb_array_const_ptr /**< @alias{rb_array_const_ptr} */
+#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient /**< @alias{rb_array_const_ptr_transient} */
/** @cond INTERNAL_MACRO */
#if defined(__fcc__) || defined(__fcc_version) || \
@@ -62,6 +80,7 @@
#define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
#define RARRAY_LENINT RARRAY_LENINT
+#define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
#define RARRAY_ASET RARRAY_ASET
#define RARRAY_PTR RARRAY_PTR
/** @endcond */
@@ -111,8 +130,30 @@ enum ruby_rarray_flags {
* 3rd parties must not be aware that there even is more than one way to
* store array elements. It was a bad idea to expose this to them.
*/
+#if USE_RVARGC
RARRAY_EMBED_LEN_MASK = RUBY_FL_USER9 | RUBY_FL_USER8 | RUBY_FL_USER7 | RUBY_FL_USER6 |
RUBY_FL_USER5 | RUBY_FL_USER4 | RUBY_FL_USER3
+#else
+ RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
+#endif
+
+#if USE_TRANSIENT_HEAP
+ ,
+
+ /**
+ * This flag has something to do with an array's "transiency". A transient
+ * array is an array of young generation (of generational GC), who stores
+ * its elements inside of dedicated memory pages called a transient heap.
+ * Not every young generation share that storage scheme, but elder
+ * generations must no join.
+ *
+ * @internal
+ *
+ * 3rd parties must not be aware that there even is more than one way to
+ * store array elements. It was a bad idea to expose this to them.
+ */
+ RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
+#endif
};
/**
@@ -122,6 +163,13 @@ enum ruby_rarray_flags {
enum ruby_rarray_consts {
/** Where ::RARRAY_EMBED_LEN_MASK resides. */
RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3
+
+#if !USE_RVARGC
+ ,
+
+ /** Max possible number elements that can be embedded. */
+ RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
+#endif
};
/** Ruby's array. */
@@ -180,12 +228,16 @@ struct RArray {
* to store its elements. In this case the length is encoded into the
* flags.
*/
+#if USE_RVARGC
/* This is a length 1 array because:
* 1. GCC has a bug that does not optimize C flexible array members
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
* 2. Zero length arrays are not supported by all compilers
*/
const VALUE ary[1];
+#else
+ const VALUE ary[RARRAY_EMBED_LEN_MAX];
+#endif
} as;
};
@@ -212,6 +264,16 @@ VALUE *rb_ary_ptr_use_start(VALUE ary);
*/
void rb_ary_ptr_use_end(VALUE a);
+#if USE_TRANSIENT_HEAP
+/**
+ * Destructively converts an array of transient backend into ordinal one.
+ *
+ * @param[out] a An object of ::RArray.
+ * @pre `a` must be a transient array.
+ * @post `a` gets out of transient heap, destructively.
+ */
+void rb_ary_detransient(VALUE a);
+#endif
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
@@ -284,6 +346,33 @@ RARRAY_LENINT(VALUE ary)
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * Queries if the array is a transient array.
+ *
+ * @param[in] ary Array in question.
+ * @retval true Yes it is.
+ * @retval false No it isn't.
+ * @pre `ary` must be an instance of ::RArray.
+ *
+ * @internal
+ *
+ * @shyouhei doesn't understand the benefit of this function called from
+ * extension libraries.
+ */
+static inline bool
+RARRAY_TRANSIENT_P(VALUE ary)
+{
+ RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* @private
*
@@ -294,7 +383,7 @@ RBIMPL_ATTR_PURE_UNLESS_DEBUG()
* @return Its backend storage.
*/
static inline const VALUE *
-rb_array_const_ptr(VALUE a)
+rb_array_const_ptr_transient(VALUE a)
{
RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
@@ -306,21 +395,102 @@ rb_array_const_ptr(VALUE a)
}
}
+#if ! USE_TRANSIENT_HEAP
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+#endif
+/**
+ * @private
+ *
+ * This is an implementation detail of RARRAY_PTR(). People do not use it
+ * directly.
+ *
+ * @param[in] a An object of ::RArray.
+ * @return Its backend storage.
+ * @post `a` is not a transient array.
+ */
+static inline const VALUE *
+rb_array_const_ptr(VALUE a)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+#endif
+ return rb_array_const_ptr_transient(a);
+}
+
+/**
+ * @private
+ *
+ * This is an implementation detail of #RARRAY_PTR_USE. People do not use it
+ * directly.
+ *
+ * @param[in] a An object of ::RArray.
+ * @param[in] allow_transient Whether `a` can be transient or not.
+ * @return Its backend storage.
+ * @post `a` is not a transient array unless `allow_transient`.
+ */
+static inline VALUE *
+rb_array_ptr_use_start(VALUE a,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int allow_transient)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+
+#if USE_TRANSIENT_HEAP
+ if (!allow_transient) {
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+ }
+#endif
+
+ return rb_ary_ptr_use_start(a);
+}
+
+/**
+ * @private
+ *
+ * This is an implementation detail of #RARRAY_PTR_USE. People do not use it
+ * directly.
+ *
+ * @param[in] a An object of ::RArray.
+ * @param[in] allow_transient Whether `a` can be transient or not.
+ */
+static inline void
+rb_array_ptr_use_end(VALUE a,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int allow_transient)
+{
+ RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
+ rb_ary_ptr_use_end(a);
+}
+
/**
* @private
*
* This is an implementation detail of #RARRAY_PTR_USE. People do not use it
* directly.
*/
-#define RBIMPL_RARRAY_STMT(ary, var, expr) do { \
+#define RBIMPL_RARRAY_STMT(flag, ary, var, expr) do { \
RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
const VALUE rbimpl_ary = (ary); \
- VALUE *var = rb_ary_ptr_use_start(rbimpl_ary); \
+ VALUE *var = rb_array_ptr_use_start(rbimpl_ary, (flag)); \
expr; \
- rb_ary_ptr_use_end(rbimpl_ary); \
+ rb_array_ptr_use_end(rbimpl_ary, (flag)); \
} while (0)
/**
+ * @private
+ *
+ * This is an implementation detail of #RARRAY_PTR_USE. People do not use it
+ * directly.
+ */
+#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
+
+/**
* Declares a section of code where raw pointers are used. In case you need to
* touch the raw C array instead of polite CAPIs, then that operation shall be
* wrapped using this macro.
@@ -346,11 +516,21 @@ rb_array_const_ptr(VALUE a)
* them use it... Maybe some transition path can be implemented later.
*/
#define RARRAY_PTR_USE(ary, ptr_name, expr) \
- RBIMPL_RARRAY_STMT(ary, ptr_name, expr)
+ RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
+
+/**
+ * Identical to #RARRAY_PTR_USE, except the pointer can be a transient one.
+ *
+ * @param ary An object of ::RArray.
+ * @param ptr_name A variable name which points the C array in `expr`.
+ * @param expr The expression that touches `ptr_name`.
+ */
+#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) \
+ RBIMPL_RARRAY_STMT(1, ary, ptr_name, expr)
/**
* Wild use of a C pointer. This function accesses the backend storage
- * directly. This is slower than #RARRAY_PTR_USE. It exercises
+ * directly. This is slower than #RARRAY_PTR_USE_TRANSIENT. It exercises
* extra manoeuvres to protect our generational GC. Use of this function is
* considered archaic. Use a modern way instead.
*
@@ -385,7 +565,7 @@ RARRAY_PTR(VALUE ary)
static inline void
RARRAY_ASET(VALUE ary, long i, VALUE v)
{
- RARRAY_PTR_USE(ary, ptr,
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr,
RB_OBJ_WRITE(ary, &ptr[i], v));
}
@@ -400,6 +580,6 @@ RARRAY_ASET(VALUE ary, long i, VALUE v)
* remains as it is due to that. If we could warn such usages we can set a
* transition path, but currently no way is found to do so.
*/
-#define RARRAY_AREF(a, i) RARRAY_CONST_PTR(a)[i]
+#define RARRAY_AREF(a, i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
#endif /* RBIMPL_RARRAY_H */
diff --git a/include/ruby/internal/core/rfile.h b/include/ruby/internal/core/rfile.h
index a0eb8cb833..f8dddde9e5 100644
--- a/include/ruby/internal/core/rfile.h
+++ b/include/ruby/internal/core/rfile.h
@@ -25,7 +25,7 @@
/* rb_io_t is in ruby/io.h. The header file has historically not been included
* into ruby/ruby.h. We follow that tradition. */
-struct rb_io;
+struct rb_io_t;
/**
* Ruby's File and IO. Ruby's IO are not just file descriptors. They have
@@ -38,7 +38,7 @@ struct RFile {
struct RBasic basic;
/** IO's specific fields. */
- struct rb_io *fptr;
+ struct rb_io_t *fptr;
};
/**
diff --git a/include/ruby/internal/core/rhash.h b/include/ruby/internal/core/rhash.h
index 897c570794..61d2c15d87 100644
--- a/include/ruby/internal/core/rhash.h
+++ b/include/ruby/internal/core/rhash.h
@@ -54,6 +54,19 @@
*
* @internal
*
+ * Declaration of rb_hash_iter_lev() is at include/ruby/backward.h.
+ */
+#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
+
+/**
+ * @private
+ *
+ * @deprecated This macro once was a thing in the old days, but makes no sense
+ * any longer today. Exists here for backwards compatibility
+ * only. You can safely forget about it.
+ *
+ * @internal
+ *
* Declaration of rb_hash_ifnone() is at include/ruby/backward.h.
*/
#define RHASH_IFNONE(h) rb_hash_ifnone(h)
diff --git a/include/ruby/internal/core/rmatch.h b/include/ruby/internal/core/rmatch.h
index a528c2999e..2d2fd897f5 100644
--- a/include/ruby/internal/core/rmatch.h
+++ b/include/ruby/internal/core/rmatch.h
@@ -68,7 +68,7 @@ struct rmatch_offset {
};
/** Represents a match. */
-struct rb_matchext_struct {
+struct rmatch {
/**
* "Registers" of a match. This is a quasi-opaque struct that holds
* execution result of a match. Roughly resembles `&~`.
@@ -82,8 +82,6 @@ struct rb_matchext_struct {
int char_offset_num_allocated;
};
-typedef struct rb_matchext_struct rb_matchext_t;
-
/**
* Regular expression execution context. When a regular expression "matches"
* to a string, it generates capture groups etc. This struct holds that info.
@@ -104,13 +102,16 @@ struct RMatch {
VALUE str;
/**
+ * The result of this match.
+ */
+ struct rmatch *rmatch;
+
+ /**
* The expression of this match.
*/
VALUE regexp; /* RRegexp */
};
-#define RMATCH_EXT(m) ((rb_matchext_t *)((char *)(m) + sizeof(struct RMatch)))
-
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
@@ -138,7 +139,8 @@ static inline struct re_registers *
RMATCH_REGS(VALUE match)
{
RBIMPL_ASSERT_TYPE(match, RUBY_T_MATCH);
- return &RMATCH_EXT(match)->regs;
+ RBIMPL_ASSERT_OR_ASSUME(RMATCH(match)->rmatch != NULL);
+ return &RMATCH(match)->rmatch->regs;
}
#endif /* RBIMPL_RMATCH_H */
diff --git a/include/ruby/internal/core/robject.h b/include/ruby/internal/core/robject.h
index c2bcae6306..b1c2e1b0a9 100644
--- a/include/ruby/internal/core/robject.h
+++ b/include/ruby/internal/core/robject.h
@@ -74,6 +74,17 @@ enum ruby_robject_flags {
ROBJECT_EMBED = RUBY_FL_USER1
};
+#if !USE_RVARGC
+/**
+ * This is an enum because GDB wants it (rather than a macro). People need not
+ * bother.
+ */
+enum ruby_robject_consts {
+ /** Max possible number of instance variables that can be embedded. */
+ ROBJECT_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
+};
+#endif
+
struct st_table;
/**
@@ -107,6 +118,7 @@ struct RObject {
struct rb_id_table *iv_index_tbl;
} heap;
+#if USE_RVARGC
/* Embedded instance variables. When an object is small enough, it
* uses this area to store the instance variables.
*
@@ -116,9 +128,23 @@ struct RObject {
* 2. Zero length arrays are not supported by all compilers
*/
VALUE ary[1];
+#else
+ /**
+ * Embedded instance variables. When an object is small enough, it
+ * uses this area to store the instance variables.
+ */
+ VALUE ary[ROBJECT_EMBED_LEN_MAX];
+#endif
} as;
};
+/* Offsets for YJIT */
+#ifndef __cplusplus
+static const int32_t ROBJECT_OFFSET_AS_HEAP_IVPTR = offsetof(struct RObject, as.heap.ivptr);
+static const int32_t ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL = offsetof(struct RObject, as.heap.iv_index_tbl);
+static const int32_t ROBJECT_OFFSET_AS_ARY = offsetof(struct RObject, as.ary);
+#endif
+
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
diff --git a/include/ruby/internal/core/rstring.h b/include/ruby/internal/core/rstring.h
index 0bca74e688..e394ab7dca 100644
--- a/include/ruby/internal/core/rstring.h
+++ b/include/ruby/internal/core/rstring.h
@@ -42,7 +42,13 @@
/** @cond INTERNAL_MACRO */
#define RSTRING_NOEMBED RSTRING_NOEMBED
+#if !USE_RVARGC
+#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
+#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
+#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
+#endif
#define RSTRING_FSTR RSTRING_FSTR
+#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
#define RSTRING_LEN RSTRING_LEN
#define RSTRING_LENINT RSTRING_LENINT
#define RSTRING_PTR RSTRING_PTR
@@ -156,6 +162,21 @@ enum ruby_rstring_flags {
*/
RSTRING_NOEMBED = RUBY_FL_USER1,
+#if !USE_RVARGC
+ /**
+ * When a string employs embedded strategy (see ::RSTRING_NOEMBED), these
+ * bits are used to store the number of bytes actually filled into
+ * ::RString::ary.
+ *
+ * @internal
+ *
+ * 3rd parties must not be aware that there even is more than one way to
+ * store a string. Might better be hidden.
+ */
+ RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
+ RUBY_FL_USER5 | RUBY_FL_USER6,
+#endif
+
/* Actually, string encodings are also encoded into the flags, using
* remaining bits.*/
@@ -181,6 +202,20 @@ enum ruby_rstring_flags {
RSTRING_FSTR = RUBY_FL_USER17
};
+#if !USE_RVARGC
+/**
+ * This is an enum because GDB wants it (rather than a macro). People need not
+ * bother.
+ */
+enum ruby_rstring_consts {
+ /** Where ::RSTRING_EMBED_LEN_MASK resides. */
+ RSTRING_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 2,
+
+ /** Max possible number of characters that can be embedded. */
+ RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
+};
+#endif
+
/**
* Ruby's String. A string in ruby conceptually has these information:
*
@@ -198,13 +233,6 @@ struct RString {
/** Basic part, including flags and class. */
struct RBasic basic;
- /**
- * Length of the string, not including terminating NUL character.
- *
- * @note This is in bytes.
- */
- long len;
-
/** String's specific fields. */
union {
@@ -213,6 +241,14 @@ struct RString {
* pattern.
*/
struct {
+
+ /**
+ * Length of the string, not including terminating NUL character.
+ *
+ * @note This is in bytes.
+ */
+ long len;
+
/**
* Pointer to the contents of the string. In the old days each
* string had dedicated memory regions. That is no longer true
@@ -243,12 +279,24 @@ struct RString {
/** Embedded contents. */
struct {
+#if USE_RVARGC
+ long len;
/* This is a length 1 array because:
* 1. GCC has a bug that does not optimize C flexible array members
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
* 2. Zero length arrays are not supported by all compilers
*/
char ary[1];
+#else
+ /**
+ * When a string is short enough, it uses this area to store the
+ * contents themselves. This was impractical in the 20th century,
+ * but these days 64 bit machines can typically hold 24 bytes here.
+ * Could be sufficiently large. In this case the length is encoded
+ * into the flags.
+ */
+ char ary[RSTRING_EMBED_LEN_MAX + 1];
+#endif
} embed;
} as;
};
@@ -361,12 +409,31 @@ RBIMPL_ATTR_ARTIFICIAL()
*
* @param[in] str String in question.
* @return Its length, in bytes.
- * @pre `str` must be an instance of ::RString.
+ * @pre `str` must be an instance of ::RString, and must has its
+ * ::RSTRING_NOEMBED flag off.
+ *
+ * @internal
+ *
+ * This was a macro before. It was inevitable to be public, since macros are
+ * global constructs. But should it be forever? Now that it is a function,
+ * @shyouhei thinks it could just be eliminated, hidden into implementation
+ * details.
*/
static inline long
-RSTRING_LEN(VALUE str)
+RSTRING_EMBED_LEN(VALUE str)
{
- return RSTRING(str)->len;
+ RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
+ RBIMPL_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
+
+#if USE_RVARGC
+ long f = RSTRING(str)->as.embed.len;
+ return f;
+#else
+ VALUE f = RBASIC(str)->flags;
+ f &= RSTRING_EMBED_LEN_MASK;
+ f >>= RSTRING_EMBED_LEN_SHIFT;
+ return RBIMPL_CAST((long)f);
+#endif
}
RBIMPL_WARNING_PUSH()
@@ -396,7 +463,7 @@ rbimpl_rstring_getmem(VALUE str)
else {
/* Expecting compilers to optimize this on-stack struct away. */
struct RString retval;
- retval.len = RSTRING_LEN(str);
+ retval.as.heap.len = RSTRING_EMBED_LEN(str);
retval.as.heap.ptr = RSTRING(str)->as.embed.ary;
return retval;
}
@@ -404,6 +471,21 @@ rbimpl_rstring_getmem(VALUE str)
RBIMPL_WARNING_POP()
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * Queries the length of the string.
+ *
+ * @param[in] str String in question.
+ * @return Its length, in bytes.
+ * @pre `str` must be an instance of ::RString.
+ */
+static inline long
+RSTRING_LEN(VALUE str)
+{
+ return rbimpl_rstring_getmem(str).as.heap.len;
+}
+
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the contents pointer of the string.
@@ -417,9 +499,13 @@ RSTRING_PTR(VALUE str)
{
char *ptr = rbimpl_rstring_getmem(str).as.heap.ptr;
- if (RUBY_DEBUG && RB_UNLIKELY(! ptr)) {
+ if (RB_UNLIKELY(! ptr)) {
/* :BEWARE: @shyouhei thinks that currently, there are rooms for this
- * function to return NULL. Better check here for maximum safety.
+ * function to return NULL. In the 20th century that was a pointless
+ * concern. However struct RString can hold fake strings nowadays. It
+ * seems no check against NULL are exercised around handling of them
+ * (one of such usages is located in marshal.c, which scares
+ * @shyouhei). Better check here for maximum safety.
*
* Also, this is not rb_warn() because RSTRING_PTR() can be called
* during GC (see what obj_info() does). rb_warn() needs to allocate
@@ -443,12 +529,12 @@ RSTRING_END(VALUE str)
{
struct RString buf = rbimpl_rstring_getmem(str);
- if (RUBY_DEBUG && RB_UNLIKELY(! buf.as.heap.ptr)) {
+ if (RB_UNLIKELY(! buf.as.heap.ptr)) {
/* Ditto. */
rb_debug_rstring_null_ptr("RSTRING_END");
}
- return &buf.as.heap.ptr[buf.len];
+ return &buf.as.heap.ptr[buf.as.heap.len];
}
RBIMPL_ATTR_ARTIFICIAL()
@@ -482,7 +568,7 @@ RSTRING_LENINT(VALUE str)
__extension__ ({ \
struct RString rbimpl_str = rbimpl_rstring_getmem(str); \
(ptrvar) = rbimpl_str.as.heap.ptr; \
- (lenvar) = rbimpl_str.len; \
+ (lenvar) = rbimpl_str.as.heap.len; \
})
#else
# define RSTRING_GETMEM(str, ptrvar, lenvar) \
diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h
index 6c19576c20..bbf208867d 100644
--- a/include/ruby/internal/core/rtypeddata.h
+++ b/include/ruby/internal/core/rtypeddata.h
@@ -114,8 +114,6 @@
#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
/** @endcond */
-#define TYPED_DATA_EMBEDDED 2
-
/**
* @private
*
@@ -139,8 +137,6 @@ rbimpl_typeddata_flags {
*/
RUBY_TYPED_FREE_IMMEDIATELY = 1,
- RUBY_TYPED_EMBEDDABLE = 2,
-
/**
* This flag has something to do with Ractor. Multiple Ractors run without
* protecting each other. Sharing an object among Ractors is basically
@@ -177,16 +173,10 @@ rbimpl_typeddata_flags {
RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */
/**
- * This flag no longer in use
+ * This flag is mysterious. It seems nobody is currently using it. The
+ * intention of this flag is also unclear. We need further investigations.
*/
- RUBY_TYPED_UNUSED = RUBY_FL_UNUSED6,
-
- /**
- * This flag determines whether marking and compaction should be carried out
- * using the dmark/dcompact callback functions or whether we should mark
- * declaratively using a list of references defined inside the data struct we're wrapping
- */
- RUBY_TYPED_DECL_MARKING = RUBY_FL_USER2
+ RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */
};
/**
@@ -357,14 +347,16 @@ struct RTypedData {
* data. This roughly resembles a Ruby level class (apart from method
* definition etc.)
*/
- const rb_data_type_t *const type;
+ const rb_data_type_t *type;
/**
* This has to be always 1.
*
* @internal
+ *
+ * Why, then, this is not a const ::VALUE?
*/
- const VALUE typed_flag;
+ VALUE typed_flag;
/** Pointer to the actual C level struct that you want to wrap. */
void *data;
@@ -464,7 +456,7 @@ RBIMPL_SYMBOL_EXPORT_END()
*/
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
- (sval) = (type *)RTYPEDDATA_GET_DATA(result); \
+ (sval) = RBIMPL_CAST((type *)RTYPEDDATA_DATA(result)); \
RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
/**
@@ -515,36 +507,6 @@ RBIMPL_SYMBOL_EXPORT_END()
#define TypedData_Get_Struct(obj,type,data_type,sval) \
((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type))))
-static inline bool
-RTYPEDDATA_EMBEDDED_P(VALUE obj)
-{
-#if RUBY_DEBUG
- if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
- Check_Type(obj, RUBY_T_DATA);
- RBIMPL_UNREACHABLE_RETURN(false);
- }
-#endif
-
- return RTYPEDDATA(obj)->typed_flag & TYPED_DATA_EMBEDDED;
-}
-
-static inline void *
-RTYPEDDATA_GET_DATA(VALUE obj)
-{
-#if RUBY_DEBUG
- if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
- Check_Type(obj, RUBY_T_DATA);
- RBIMPL_UNREACHABLE_RETURN(false);
- }
-#endif
-
- /* We reuse the data pointer in embedded TypedData. We can't use offsetof
- * since RTypedData a non-POD type in C++. */
- const size_t embedded_typed_data_size = sizeof(struct RTypedData) - sizeof(void *);
-
- return RTYPEDDATA_EMBEDDED_P(obj) ? (char *)obj + embedded_typed_data_size : RTYPEDDATA(obj)->data;
-}
-
RBIMPL_ATTR_PURE()
RBIMPL_ATTR_ARTIFICIAL()
/**
@@ -561,8 +523,7 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline bool
rbimpl_rtypeddata_p(VALUE obj)
{
- VALUE typed_flag = RTYPEDDATA(obj)->typed_flag;
- return typed_flag != 0 && typed_flag <= 3;
+ return RTYPEDDATA(obj)->typed_flag == 1;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
diff --git a/include/ruby/internal/dllexport.h b/include/ruby/internal/dllexport.h
index 71026e7100..08a262209d 100644
--- a/include/ruby/internal/dllexport.h
+++ b/include/ruby/internal/dllexport.h
@@ -37,7 +37,9 @@
* ```
*/
#undef RUBY_EXTERN
-#if defined(RUBY_EXPORT)
+#if defined(MJIT_HEADER) && defined(_WIN32)
+# define RUBY_EXTERN extern __declspec(dllimport)
+#elif defined(RUBY_EXPORT)
# define RUBY_EXTERN extern
#elif defined(_WIN32)
# define RUBY_EXTERN extern __declspec(dllimport)
@@ -57,6 +59,36 @@
# define RUBY_FUNC_EXPORTED /* void */
#endif
+/**
+ * @cond INTERNAL_MACRO
+ *
+ * These MJIT related macros are placed here because translate_mjit_header can
+ * need them. Extension libraries should not touch.
+ */
+
+/* These macros are used for functions which are exported only for MJIT
+ and NOT ensured to be exported in future versions. */
+
+#if ! defined(MJIT_HEADER)
+# define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
+#elif ! RBIMPL_COMPILER_IS(MSVC)
+# define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
+#else
+# define MJIT_FUNC_EXPORTED static
+#endif
+
+#define MJIT_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
+#define MJIT_SYMBOL_EXPORT_END RUBY_SYMBOL_EXPORT_END
+
+/* On mswin, MJIT header transformation can't be used since cl.exe can't output
+ preprocessed output preserving macros. So this `MJIT_STATIC` is needed
+ to force non-static function to static on MJIT header to avoid symbol conflict. */
+#ifdef MJIT_HEADER
+# define MJIT_STATIC static
+#else
+# define MJIT_STATIC
+#endif
+
/** @endcond */
/** Shortcut macro equivalent to `RUBY_SYMBOL_EXPORT_BEGIN extern "C" {`.
diff --git a/include/ruby/internal/encoding/encoding.h b/include/ruby/internal/encoding/encoding.h
index dc3e0151f0..4748ca806b 100644
--- a/include/ruby/internal/encoding/encoding.h
+++ b/include/ruby/internal/encoding/encoding.h
@@ -139,6 +139,23 @@ RBIMPL_ATTR_NOALIAS()
int rb_char_to_option_kcode(int c, int *option, int *kcode);
/**
+ * Creates a new encoding, using the passed one as a template.
+ *
+ * @param[in] name Name of the creating encoding.
+ * @param[in] src Template.
+ * @exception rb_eArgError Duplicated or malformed `name`.
+ * @return Replicated new encoding's index.
+ * @post Encoding named `name` is created as a copy of `src`, whose index
+ * is the return value.
+ *
+ * @internal
+ *
+ * `name` can be `NULL`, but that just raises an exception. OTOH it seems no
+ * sanity check is done against `src`...?
+ */
+int rb_enc_replicate(const char *name, rb_encoding *src);
+
+/**
* Creates a new "dummy" encoding. Roughly speaking, an encoding is dummy when
* it is stateful. Notable example of dummy encoding are those defined in
* ISO/IEC 2022
diff --git a/include/ruby/internal/encoding/string.h b/include/ruby/internal/encoding/string.h
index 2b9dfe4f31..6ed7ca1c90 100644
--- a/include/ruby/internal/encoding/string.h
+++ b/include/ruby/internal/encoding/string.h
@@ -30,7 +30,7 @@
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
- * Identical to rb_str_new(), except it additionally takes an encoding.
+ * Identical to rb_enc_str_new(), except it additionally takes an encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
diff --git a/include/ruby/internal/error.h b/include/ruby/internal/error.h
index cd37f4461a..49e2276cb9 100644
--- a/include/ruby/internal/error.h
+++ b/include/ruby/internal/error.h
@@ -50,19 +50,7 @@ typedef enum {
/** Warning is for experimental features. */
RB_WARN_CATEGORY_EXPERIMENTAL,
- /** Warning is for performance issues (not enabled by -w). */
- RB_WARN_CATEGORY_PERFORMANCE,
-
- RB_WARN_CATEGORY_DEFAULT_BITS = (
- (1U << RB_WARN_CATEGORY_DEPRECATED) |
- (1U << RB_WARN_CATEGORY_EXPERIMENTAL) |
- 0),
-
- RB_WARN_CATEGORY_ALL_BITS = (
- (1U << RB_WARN_CATEGORY_DEPRECATED) |
- (1U << RB_WARN_CATEGORY_EXPERIMENTAL) |
- (1U << RB_WARN_CATEGORY_PERFORMANCE) |
- 0)
+ RB_WARN_CATEGORY_ALL_BITS = 0x6 /* no RB_WARN_CATEGORY_NONE bit */
} rb_warning_category_t;
/** for rb_readwrite_sys_fail first argument */
@@ -481,7 +469,7 @@ VALUE *rb_ruby_debug_ptr(void);
*/
#define ruby_debug (*rb_ruby_debug_ptr())
-/* reports if $VERBOSE is true */
+/* reports if `-W' specified */
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
@@ -496,8 +484,7 @@ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
* default, the method just emits its passed contents to ::rb_stderr using
* rb_io_write().
*
- * @note This function is affected by the value of $VERBOSE, it does
- * nothing unless $VERBOSE is true.
+ * @note This function is affected by the `-W` flag.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*
* @internal
@@ -522,7 +509,7 @@ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
* Issues a compile-time warning that happens at `__file__:__line__`. Purpose
* of this function being exposed to CAPI is unclear.
*
- * @note This function is affected by the value of $VERBOSE.
+ * @note This function is affected by the `-W` flag.
* @param[in] file The path corresponding to Ruby level `__FILE__`.
* @param[in] line The number corresponding to Ruby level `__LINE__`.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
@@ -535,20 +522,19 @@ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
* Identical to rb_sys_fail(), except it does not raise an exception to render
* a warning instead.
*
- * @note This function is affected by the value of $VERBOSE.
+ * @note This function is affected by the `-W` flag.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_sys_warning(const char *fmt, ...);
-/* reports if $VERBOSE is not nil (so if it is true or false) */
+/* reports always */
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
- * Identical to rb_warning(), except it reports unless $VERBOSE is nil.
+ * Identical to rb_warning(), except it reports always regardless of runtime
+ * `-W` flag.
*
- * @note This function is affected by the value of $VERBOSE, it does
- * nothing if $VERBOSE is nil.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_warn(const char *fmt, ...);
@@ -557,7 +543,8 @@ RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
- * Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
+ * Identical to rb_category_warning(), except it reports always regardless of
+ * runtime `-W` flag.
*
* @param[in] cat Category e.g. deprecated.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
@@ -567,7 +554,8 @@ void rb_category_warn(rb_warning_category_t cat, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((1, 3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
- * Identical to rb_compile_warning(), except it reports unless $VERBOSE is nil.
+ * Identical to rb_compile_warning(), except it reports always regardless of
+ * runtime `-W` flag.
*
* @param[in] file The path corresponding to Ruby level `__FILE__`.
* @param[in] line The number corresponding to Ruby level `__LINE__`.
diff --git a/include/ruby/internal/event.h b/include/ruby/internal/event.h
index 1d194ed618..04b137a193 100644
--- a/include/ruby/internal/event.h
+++ b/include/ruby/internal/event.h
@@ -23,10 +23,6 @@
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
/* These macros are not enums because they are wider than int.*/
/**
@@ -58,7 +54,6 @@
#define RUBY_EVENT_THREAD_END 0x0800 /**< Encountered an end of a thread. */
#define RUBY_EVENT_FIBER_SWITCH 0x1000 /**< Encountered a `Fiber#yield`. */
#define RUBY_EVENT_SCRIPT_COMPILED 0x2000 /**< Encountered an `eval`. */
-#define RUBY_EVENT_RESCUE 0x4000 /**< Encountered a `rescue` statement. */
#define RUBY_EVENT_TRACEPOINT_ALL 0xffff /**< Bitmask of extended events. */
/** @} */
diff --git a/include/ruby/internal/fl_type.h b/include/ruby/internal/fl_type.h
index 44b3e8cc0f..7383426b23 100644
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -57,7 +57,8 @@
#define FL_SINGLETON RBIMPL_CAST((VALUE)RUBY_FL_SINGLETON) /**< @old{RUBY_FL_SINGLETON} */
#define FL_WB_PROTECTED RBIMPL_CAST((VALUE)RUBY_FL_WB_PROTECTED) /**< @old{RUBY_FL_WB_PROTECTED} */
-#define FL_PROMOTED RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED) /**< @old{RUBY_FL_PROMOTED} */
+#define FL_PROMOTED0 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED0) /**< @old{RUBY_FL_PROMOTED0} */
+#define FL_PROMOTED1 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED1) /**< @old{RUBY_FL_PROMOTED1} */
#define FL_FINALIZE RBIMPL_CAST((VALUE)RUBY_FL_FINALIZE) /**< @old{RUBY_FL_FINALIZE} */
#define FL_TAINT RBIMPL_CAST((VALUE)RUBY_FL_TAINT) /**< @old{RUBY_FL_TAINT} */
#define FL_SHAREABLE RBIMPL_CAST((VALUE)RUBY_FL_SHAREABLE) /**< @old{RUBY_FL_SHAREABLE} */
@@ -110,6 +111,13 @@
#define RB_OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
#define RB_OBJ_FROZEN RB_OBJ_FROZEN
#define RB_OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
+#define RB_OBJ_INFECT RB_OBJ_INFECT
+#define RB_OBJ_INFECT_RAW RB_OBJ_INFECT_RAW
+#define RB_OBJ_TAINT RB_OBJ_TAINT
+#define RB_OBJ_TAINTABLE RB_OBJ_TAINTABLE
+#define RB_OBJ_TAINTED RB_OBJ_TAINTED
+#define RB_OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW
+#define RB_OBJ_TAINT_RAW RB_OBJ_TAINT_RAW
#define RB_OBJ_UNTRUST RB_OBJ_TAINT
#define RB_OBJ_UNTRUSTED RB_OBJ_TAINTED
/** @endcond */
@@ -199,15 +207,12 @@ ruby_fl_type {
RUBY_FL_WB_PROTECTED = (1<<5),
/**
- * Ruby objects are "generational". There are young objects & old objects.
- * Young objects are prone to die & monitored relatively extensively by the
- * garbage collector. Old objects tend to live longer & are monitored less
- * frequently. When an object survives a GC, its age is incremented. When
- * age is equal to RVALUE_OLD_AGE, the object becomes Old. This flag is set
- * when an object becomes old, and is used by the write barrier to check if
- * an old object should be considered for marking more frequently - as old
- * objects that have references added between major GCs need to be remarked
- * to prevent the referred object being mistakenly swept.
+ * This flag has something to do with our garbage collector. These days
+ * ruby objects are "generational". There are those who are young and
+ * those who are old. Young objects are prone to die; monitored relatively
+ * extensively by the garbage collector. OTOH old objects tend to live
+ * longer. They are relatively rarely considered. This flag is set when a
+ * object experienced promotion i.e. survived a garbage collection.
*
* @internal
*
@@ -215,14 +220,41 @@ ruby_fl_type {
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
- RUBY_FL_PROMOTED = (1<<5),
+ RUBY_FL_PROMOTED0 = (1<<5),
/**
- * This flag is no longer in use
+ * This flag has something to do with our garbage collector. These days
+ * ruby objects are "generational". There are those who are young and
+ * those who are old. Young objects are prone to die; monitored relatively
+ * extensively by the garbage collector. OTOH old objects tend to live
+ * longer. They are relatively rarely considered. This flag is set when a
+ * object experienced two promotions i.e. survived garbage collections
+ * twice.
*
* @internal
+ *
+ * But honestly, @shyouhei doesn't think this flag should be visible from
+ * 3rd parties. It must be an implementation detail that they should never
+ * know. Might better be hidden.
+ */
+ RUBY_FL_PROMOTED1 = (1<<6),
+
+ /**
+ * This flag has something to do with our garbage collector. These days
+ * ruby objects are "generational". There are those who are young and
+ * those who are old. Young objects are prone to die; monitored relatively
+ * extensively by the garbage collector. OTOH old objects tend to live
+ * longer. They are relatively rarely considered. This flag is set when a
+ * object experienced promotions i.e. survived more than one garbage
+ * collections.
+ *
+ * @internal
+ *
+ * But honestly, @shyouhei doesn't think this flag should be visible from
+ * 3rd parties. It must be an implementation detail that they should never
+ * know. Might better be hidden.
*/
- RUBY_FL_UNUSED6 = (1<<6),
+ RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1,
/**
* This flag has something to do with finalisers. A ruby object can have
@@ -251,7 +283,7 @@ ruby_fl_type {
# pragma deprecated(RUBY_FL_TAINT)
#endif
- = 0,
+ = (1<<8),
/**
* This flag has something to do with Ractor. Multiple Ractors run without
@@ -278,7 +310,7 @@ ruby_fl_type {
# pragma deprecated(RUBY_FL_UNTRUSTED)
#endif
- = 0,
+ = (1<<8),
/**
* This flag has something to do with object IDs. Unlike in the old days,
@@ -457,7 +489,7 @@ RB_FL_ABLE(VALUE obj)
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_FL_TEST(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_TEST(). 3rd parties need not use
* this. Just always use RB_FL_TEST().
*
* @param[in] obj Object in question.
@@ -505,7 +537,7 @@ RB_FL_TEST(VALUE obj, VALUE flags)
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_FL_ANY(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_ANY(). 3rd parties need not use
* this. Just always use RB_FL_ANY().
*
* @param[in] obj Object in question.
@@ -539,7 +571,7 @@ RB_FL_ANY(VALUE obj, VALUE flags)
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_FL_ALL(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_ALL(). 3rd parties need not use
* this. Just always use RB_FL_ALL().
*
* @param[in] obj Object in question.
@@ -575,7 +607,7 @@ RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
- * This is an implementation detail of RB_FL_SET(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_SET(). 3rd parties need not use
* this. Just always use RB_FL_SET().
*
* @param[out] obj Object in question.
@@ -595,7 +627,7 @@ rbimpl_fl_set_raw_raw(struct RBasic *obj, VALUE flags)
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_FL_SET(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_SET(). 3rd parties need not use
* this. Just always use RB_FL_SET().
*
* @param[out] obj Object in question.
@@ -635,7 +667,7 @@ RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
- * This is an implementation detail of RB_FL_UNSET(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_UNSET(). 3rd parties need not use
* this. Just always use RB_FL_UNSET().
*
* @param[out] obj Object in question.
@@ -655,7 +687,7 @@ rbimpl_fl_unset_raw_raw(struct RBasic *obj, VALUE flags)
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_FL_UNSET(). 3rd parties need not use
+ * This is an implenentation detail of RB_FL_UNSET(). 3rd parties need not use
* this. Just always use RB_FL_UNSET().
*
* @param[out] obj Object in question.
@@ -690,7 +722,7 @@ RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
- * This is an implementation detail of RB_FL_REVERSE(). 3rd parties need not
+ * This is an implenentation detail of RB_FL_REVERSE(). 3rd parties need not
* use this. Just always use RB_FL_REVERSE().
*
* @param[out] obj Object in question.
@@ -710,7 +742,7 @@ rbimpl_fl_reverse_raw_raw(struct RBasic *obj, VALUE flags)
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_FL_REVERSE(). 3rd parties need not
+ * This is an implenentation detail of RB_FL_REVERSE(). 3rd parties need not
* use this. Just always use RB_FL_REVERSE().
*
* @param[out] obj Object in question.
@@ -755,7 +787,6 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline bool
RB_OBJ_TAINTABLE(VALUE obj)
{
- (void)obj;
return false;
}
@@ -773,7 +804,6 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline VALUE
RB_OBJ_TAINTED_RAW(VALUE obj)
{
- (void)obj;
return false;
}
@@ -791,7 +821,6 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline bool
RB_OBJ_TAINTED(VALUE obj)
{
- (void)obj;
return false;
}
@@ -807,7 +836,6 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline void
RB_OBJ_TAINT_RAW(VALUE obj)
{
- (void)obj;
return;
}
@@ -823,7 +851,6 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline void
RB_OBJ_TAINT(VALUE obj)
{
- (void)obj;
return;
}
@@ -840,8 +867,6 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline void
RB_OBJ_INFECT_RAW(VALUE dst, VALUE src)
{
- (void)dst;
- (void)src;
return;
}
@@ -858,15 +883,13 @@ RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
static inline void
RB_OBJ_INFECT(VALUE dst, VALUE src)
{
- (void)dst;
- (void)src;
return;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_OBJ_FROZEN(). 3rd parties need not
+ * This is an implenentation detail of RB_OBJ_FROZEN(). 3rd parties need not
* use this. Just always use RB_OBJ_FROZEN().
*
* @param[in] obj Object in question.
@@ -907,7 +930,7 @@ RB_OBJ_FROZEN(VALUE obj)
RBIMPL_ATTR_ARTIFICIAL()
/**
- * This is an implementation detail of RB_OBJ_FREEZE(). 3rd parties need not
+ * This is an implenentation detail of RB_OBJ_FREEZE(). 3rd parties need not
* use this. Just always use RB_OBJ_FREEZE().
*
* @param[out] obj Object in question.
diff --git a/include/ruby/internal/gc.h b/include/ruby/internal/gc.h
index ac9dfd8842..054e4b0f9c 100644
--- a/include/ruby/internal/gc.h
+++ b/include/ruby/internal/gc.h
@@ -20,385 +20,11 @@
* extension libraries. They could be written in C++98.
* @brief Registering values to the GC.
*/
-#include "ruby/internal/config.h"
-
-#ifdef STDC_HEADERS
-# include <stddef.h> /* size_t */
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h> /* ssize_t */
-#endif
-
-#include "ruby/assert.h"
-#include "ruby/internal/attr/cold.h"
-#include "ruby/internal/attr/nonnull.h"
-#include "ruby/internal/attr/noreturn.h"
-#include "ruby/internal/attr/artificial.h"
-#include "ruby/internal/attr/maybe_unused.h"
-#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
-#include "ruby/internal/special_consts.h"
-#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
-#define RUBY_REF_EDGE(s, p) offsetof(s, p)
-#define RUBY_REFS_LIST_PTR(l) (RUBY_DATA_FUNC)(l)
-#define RUBY_REF_END SIZE_MAX
-#define RUBY_REFERENCES(t) static const size_t t[]
-#define RUBY_REFERENCES_START(t) RUBY_REFERENCES(t) = {
-#define RUBY_REFERENCES_END RUBY_REF_END, };
-
-/* gc.c */
-
-RBIMPL_ATTR_COLD()
-RBIMPL_ATTR_NORETURN()
-/**
- * Triggers out-of-memory error. If possible it raises ::rb_eNoMemError. But
- * because we are running out of memory that is not always doable. This
- * function tries hard to show something, but ultimately can die silently.
- *
- * @exception rb_eNoMemError Raises it if possible.
- */
-void rb_memerror(void);
-
-RBIMPL_ATTR_PURE()
-/**
- * Queries if the GC is busy.
- *
- * @retval 0 It isn't.
- * @retval 1 It is.
- */
-int rb_during_gc(void);
-
-RBIMPL_ATTR_NONNULL((1))
-/**
- * Marks objects between the two pointers. This is one of the GC utility
- * functions that you can call when you design your own
- * ::rb_data_type_struct::dmark.
- *
- * @pre Continuous memory region from `start` to `end` shall be fully
- * addressable.
- * @param[out] start Pointer to an array of objects.
- * @param[out] end Pointer that terminates the array of objects.
- * @post Objects from `start` (included) to `end` (excluded) are marked.
- *
- * @internal
- *
- * `end` can be NULL... But that just results in no-op.
- */
-void rb_gc_mark_locations(const VALUE *start, const VALUE *end);
-
-/**
- * Identical to rb_mark_hash(), except it marks only values of the table and
- * leave their associated keys unmarked. This is one of the GC utility
- * functions that you can call when you design your own
- * ::rb_data_type_struct::dmark.
- *
- * @warning Of course it can break GC. Leave it unused if unsure.
- * @param[in] tbl A table to mark.
- * @post Values stored in `tbl` are marked.
- */
-void rb_mark_tbl(struct st_table *tbl);
-
-/**
- * Identical to rb_mark_tbl(), except it marks objects using
- * rb_gc_mark_movable(). This is one of the GC utility functions that you can
- * call when you design your own ::rb_data_type_struct::dmark.
- *
- * @warning Of course it can break GC. Leave it unused if unsure.
- * @param[in] tbl A table to mark.
- * @post Values stored in `tbl` are marked.
- */
-void rb_mark_tbl_no_pin(struct st_table *tbl);
-
-/**
- * Identical to rb_mark_hash(), except it marks only keys of the table and
- * leave their associated values unmarked. This is one of the GC utility
- * functions that you can call when you design your own
- * ::rb_data_type_struct::dmark.
- *
- * @warning Of course it can break GC. Leave it unused if unsure.
- * @param[in] tbl A table to mark.
- * @post Keys stored in `tbl` are marked.
- */
-void rb_mark_set(struct st_table *tbl);
-
-/**
- * Marks keys and values associated inside of the given table. This is one of
- * the GC utility functions that you can call when you design your own
- * ::rb_data_type_struct::dmark.
- *
- * @param[in] tbl A table to mark.
- * @post Objects stored in `tbl` are marked.
- */
-void rb_mark_hash(struct st_table *tbl);
-
-/**
- * Updates references inside of tables. After you marked values using
- * rb_mark_tbl_no_pin(), the objects inside of the table could of course be
- * moved. This function is to fixup those references. You can call this from
- * your ::rb_data_type_struct::dcompact.
- *
- * @param[out] ptr A table that potentially includes moved references.
- * @post Moved references, if any, are corrected.
- */
-void rb_gc_update_tbl_refs(st_table *ptr);
-
-/**
- * Identical to rb_gc_mark(), except it allows the passed value be a
- * non-object. For instance pointers to different type of memory regions are
- * allowed here. Such values are silently ignored. This is one of the GC
- * utility functions that you can call when you design your own
- * ::rb_data_type_struct::dmark.
- *
- * @param[out] obj A possible object.
- * @post `obj` is marked, if possible.
- */
-void rb_gc_mark_maybe(VALUE obj);
-
-/**
- * Marks an object. This is one of the GC utility functions that you can call
- * when you design your own ::rb_data_type_struct::dmark.
- *
- * @param[out] obj Arbitrary Ruby object.
- * @post `obj` is marked.
- */
-void rb_gc_mark(VALUE obj);
-
-/**
- * Maybe this is the only function provided for C extensions to control the
- * pinning of objects, so let us describe it in detail. These days Ruby's GC
- * is copying. As far as an object's physical address is guaranteed unused, it
- * can move around the object space. Our GC engine rearranges these objects
- * after it reclaims unreachable objects from our object space, so that the
- * space is compact (improves memory locality). This is called the
- * "compaction" phase, and works well most of the time... as far as there are
- * no C extensions. C extensions complicate the scenario because Ruby core
- * cannot detect any use of the physical address of an object inside of C
- * functions. In order to prevent memory corruptions, objects observable from
- * C extensions are "pinned"; they stick to where they are born until they die,
- * just in case any C extensions touch their raw pointers. This variant of
- * scheme is called "Mostly-Copying" garbage collector. Authors of C
- * extensions, however, can extremely carefully write them to become
- * compaction-aware. To do so avoid referring to a Ruby object from inside of
- * your struct in the first place. But if that is not possible, use this
- * function from your ::rb_data_type_struct::dmark then. This way objects
- * marked using it are considered movable. If you chose this way you have to
- * manually fix up locations of such moved pointers using rb_gc_location().
- *
- * @see Bartlett, Joel F., "Compacting Garbage Collection with Ambiguous
- * Roots", ACM SIGPLAN Lisp Pointers Volume 1 Issue 6 pp. 3-12,
- * April-May-June, 1988. https://doi.org/10.1145/1317224.1317225
- *
- * @param[in] obj Object that is movable.
- * @post Values stored in `tbl` are marked.
- */
-void rb_gc_mark_movable(VALUE obj);
-
-/**
- * Finds a new "location" of an object. An object can be moved on compaction.
- * This function projects its new abode, or just returns the passed object if
- * not moved. This is one of the GC utility functions that you can call when
- * you design your own ::rb_data_type_struct::dcompact.
- *
- * @param[in] obj An object, possibly already moved to somewhere else.
- * @return An object, which holds the current contents of former `obj`.
- */
-VALUE rb_gc_location(VALUE obj);
-
-/**
- * Asserts that the passed object is no longer needed. Such objects are
- * reclaimed sooner or later so this function is not mandatory. But sometimes
- * you can know from your application knowledge that an object is surely dead
- * at some point. Calling this as a hint can be a polite way.
- *
- * @param[out] obj Object, dead.
- * @pre `obj` have never been passed to this function before.
- * @post `obj` could be invalidated.
- * @warning It is a failure to pass an object multiple times to this
- * function.
- * @deprecated This is now a no-op function.
- */
-RBIMPL_ATTR_DEPRECATED(("this is now a no-op function"))
-void rb_gc_force_recycle(VALUE obj);
-
-/**
- * Triggers a GC process. This was the only GC entry point that we had at the
- * beginning. Over time our GC evolved. Now what this function does is just a
- * very simplified variation of the entire GC algorithms. A series of
- * procedures kicked by this API is called a "full" GC.
- *
- * - It immediately scans the entire object space to sort the dead.
- * - It immediately reclaims any single dead bodies to reuse later.
- *
- * It is worth noting that the procedures above do not include evaluations of
- * finalisers. They run later.
- *
- * @internal
- *
- * Finalisers are deferred until we can handle interrupts. See
- * `rb_postponed_job_flush` in vm_trace.c.
- *
- * Of course there are GC that are not "full". For instance this one and the
- * GC which runs when we are running out of memory are different. See
- * `gc_profile_record_flag` defined in gc.c for the kinds of GC.
- *
- * In spite of the name this is not what everything that a GC can trigger. As
- * of writing it seems this function does not trigger compaction. But this
- * might change in future.
- */
-void rb_gc(void);
-
-/**
- * Copy&paste an object's finaliser to another. This is one of the GC utility
- * functions that you can call when you design your own `initialize_copy`,
- * `initialize_dup`, `initialize_clone`.
- *
- * @param[out] dst Destination object.
- * @param[in] src Source object.
- * @post `dst` and `src` share the same finaliser.
- *
- * @internal
- *
- * But isn't it easier for you to call super, and let `Object#initialize_copy`
- * call this function instead?
- */
-void rb_gc_copy_finalizer(VALUE dst, VALUE src);
-
-/**
- * (Re-) enables GC. This makes sense only after you called rb_gc_disable().
- *
- * @retval RUBY_Qtrue GC was disabled before.
- * @retval RUBY_Qfalse GC was enabled before.
- * @post GC is enabled.
- *
- * @internal
- *
- * This is one of such exceptional functions that does not raise both Ruby
- * exceptions and C++ exceptions.
- */
-VALUE rb_gc_enable(void);
-
-/**
- * Disables GC. This prevents automatic GC runs when the process is running
- * out of memory. Such situations shall result in rb_memerror(). However this
- * does not prevent users from manually invoking rb_gc(). That should work.
- * People abused this by disabling GC at the beginning of an event loop,
- * process events without GC overheads, then manually force reclaiming garbage
- * at the bottom of the loop. However because our GC is now much smarter than
- * just calling rb_gc(), this technique is proven to be sub-optimal these days.
- * It is believed that there is currently practically no needs of this
- * function.
- *
- * @retval RUBY_Qtrue GC was disabled before.
- * @retval RUBY_Qfalse GC was enabled before.
- * @post GC is disabled.
- */
-VALUE rb_gc_disable(void);
-
-/**
- * Identical to rb_gc(), except the return value.
- *
- * @return Always returns ::RUBY_Qnil.
- */
-VALUE rb_gc_start(void);
-
-/**
- * Assigns a finaliser for an object. Each objects can have objects (typically
- * blocks) that run immediately after that object dies. They are called
- * finalisers of an object. This function associates a finaliser object with a
- * target object.
- *
- * @note Note that finalisers run _after_ the object they finalise dies. You
- * cannot for instance call its methods.
- * @note If your finaliser references the object it finalises that object
- * loses any chance to become a garbage; effectively leaks memory until
- * the end of the process.
- *
- * @param[in] obj Target to finalise.
- * @param[in] block Something `call`able.
- * @exception rb_eRuntimeError Somehow `obj` cannot have finalisers.
- * @exception rb_eFrozenError `obj` is frozen.
- * @exception rb_eArgError `block` doesn't respond to `call`.
- * @return The passed `block`.
- * @post `block` runs after `obj` dies.
- */
-VALUE rb_define_finalizer(VALUE obj, VALUE block);
-
-/**
- * Modifies the object so that it has no finalisers at all. This function is
- * mainly provided for symmetry. No practical usages can be thought of.
- *
- * @param[out] obj Object to clear its finalisers.
- * @exception rb_eFrozenError `obj` is frozen.
- * @return The passed `obj`.
- * @post `obj` has no finalisers.
- * @note There is no way to undefine a specific part of many finalisers
- * that `obj` could have. All you can do is to clear them all.
- */
-VALUE rb_undefine_finalizer(VALUE obj);
-
-/**
- * Identical to rb_gc_stat(), with "count" parameter.
- *
- * @return Lifetime total number of runs of GC.
- */
-size_t rb_gc_count(void);
-
-/**
- * Obtains various GC related profiles. The parameter can be either a Symbol
- * or a Hash. If a Hash is passed, it is filled with everything currently
- * available. If a Symbol is passed just that portion is returned.
- *
- * Possible variations of keys you can pass here change from version to
- * version. You can get the list of known keys by passing an empty hash and
- * let it be filled.
- *
- * @param[in,out] key_or_buf A Symbol, or a Hash.
- * @exception rb_eTypeError Neither Symbol nor Hash.
- * @exception rb_eFrozenError Frozen hash is passed.
- * @return In case a Hash is passed it returns 0. Otherwise the
- * profile value associated with the given key is returned.
- * @post In case a Hash is passed it is filled with values.
- */
-size_t rb_gc_stat(VALUE key_or_buf);
-
-/**
- * Obtains various info regarding the most recent GC run. This includes for
- * instance the reason of the GC. The parameter can be either a Symbol or a
- * Hash. If a Hash is passed, it is filled with everything currently
- * available. If a Symbol is passed just that portion is returned.
- *
- * Possible variations of keys you can pass here change from version to
- * version. You can get the list of known keys by passing an empty hash and
- * let it be filled.
- *
- * @param[in,out] key_or_buf A Symbol, or a Hash.
- * @exception rb_eTypeError Neither Symbol nor Hash.
- * @exception rb_eFrozenError Frozen hash is passed.
- * @return In case a Hash is passed it returns that hash. Otherwise
- * the profile value associated with the given key is returned.
- * @post In case a Hash is passed it is filled with values.
- */
-VALUE rb_gc_latest_gc_info(VALUE key_or_buf);
-
-/**
- * Informs that there are external memory usages. Our GC runs when we are
- * running out of memory. The amount of memory, however, can increase/decrease
- * behind-the-scene. For instance DLLs can allocate memories using `mmap(2)`
- * etc, which are opaque to us. Registering such external allocations using
- * this function enables proper detection of how much memories an object used
- * as a whole. That will trigger GCs more often than it would otherwise. You
- * can also pass negative numbers here, to indicate that such external
- * allocations are gone.
- *
- * @param[in] diff Amount of memory increased(+)/decreased(-).
- */
-void rb_gc_adjust_memory_usage(ssize_t diff);
-
/**
* Inform the garbage collector that the global or static variable pointed by
* `valptr` stores a live Ruby object that should not be moved. Note that
@@ -433,410 +59,4 @@ void rb_gc_register_mark_object(VALUE object);
RBIMPL_SYMBOL_EXPORT_END()
-/**
- * @private
- *
- * @deprecated This macro once was a thing in the old days, but makes no sense
- * any longer today. Exists here for backwards compatibility
- * only. You can safely forget about it.
- */
-#undef USE_RGENGC
-#define USE_RGENGC 1
-
-/**
- * @deprecated This macro seems broken. Setting this to anything other than
- * zero just doesn't compile. We need to KonMari.
- */
-#ifndef USE_RGENGC_LOGGING_WB_UNPROTECT
-# define USE_RGENGC_LOGGING_WB_UNPROTECT 0
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RArray. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_ARRAY
-# define RGENGC_WB_PROTECTED_ARRAY 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RHash. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_HASH
-# define RGENGC_WB_PROTECTED_HASH 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RStruct. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_STRUCT
-# define RGENGC_WB_PROTECTED_STRUCT 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RString. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_STRING
-# define RGENGC_WB_PROTECTED_STRING 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RObject. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_OBJECT
-# define RGENGC_WB_PROTECTED_OBJECT 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RRegexp. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_REGEXP
-# define RGENGC_WB_PROTECTED_REGEXP 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RMatch. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_MATCH
-# define RGENGC_WB_PROTECTED_MATCH 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RClass. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_CLASS
-# define RGENGC_WB_PROTECTED_CLASS 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RFloat. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_FLOAT
-# define RGENGC_WB_PROTECTED_FLOAT 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RComplex. It has to be set at the time ruby itself compiles.
- * Makes no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_COMPLEX
-# define RGENGC_WB_PROTECTED_COMPLEX 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RRational. It has to be set at the time ruby itself compiles.
- * Makes no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_RATIONAL
-# define RGENGC_WB_PROTECTED_RATIONAL 1
-#endif
-
-/**
- * @private
- *
- * This is a compile-time flag to enable/disable write barrier for
- * struct ::RBignum. It has to be set at the time ruby itself compiles. Makes
- * no sense for 3rd parties.
- */
-#ifndef RGENGC_WB_PROTECTED_BIGNUM
-# define RGENGC_WB_PROTECTED_BIGNUM 1
-#endif
-
-/**
- * @private
- *
- * @deprecated This macro once was a thing in the old days, but makes no sense
- * any longer today. Exists here for backwards compatibility
- * only. You can safely forget about it.
- *
- * @internal
- *
- * @shyouhei doesn't think anybody uses this right now.
- */
-#ifndef RGENGC_WB_PROTECTED_NODE_CREF
-# define RGENGC_WB_PROTECTED_NODE_CREF 1
-#endif
-
-/**
- * @defgroup rgengc Write barrier (WB) interfaces:
- *
- * @note The following core interfaces can be changed in the future. Please
- * catch up if you want to insert WB into C-extensions correctly.
- *
- * @{
- */
-
-/**
- * Declaration of a "back" pointer. This is a write barrier for new reference
- * from "old" generation to "young" generation. It writes `young` into
- * `*slot`, which is a pointer inside of `old`.
- *
- * @param[in] old An old object.
- * @param[in] slot A pointer inside of `old`.
- * @param[out] young A young object.
- */
-#define RB_OBJ_WRITE(old, slot, young) \
- RBIMPL_CAST(rb_obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young), __FILE__, __LINE__))
-
-/**
- * Identical to #RB_OBJ_WRITE(), except it doesn't write any values, but only a
- * WB declaration. `oldv` is replaced value with `b` (not used in current
- * Ruby).
- *
- * @param[in] old An old object.
- * @param[in] oldv An object previously stored inside of `old`.
- * @param[out] young A young object.
- */
-#define RB_OBJ_WRITTEN(old, oldv, young) \
- RBIMPL_CAST(rb_obj_written((VALUE)(old), (VALUE)(oldv), (VALUE)(young), __FILE__, __LINE__))
-/** @} */
-
-#define OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW /**< @old{RB_OBJ_PROMOTED_RAW} */
-#define OBJ_PROMOTED RB_OBJ_PROMOTED /**< @old{RB_OBJ_PROMOTED} */
-#define OBJ_WB_UNPROTECT RB_OBJ_WB_UNPROTECT /**< @old{RB_OBJ_WB_UNPROTECT} */
-
-/**
- * Asserts that the passed object is not fenced by write barriers. Objects of
- * such property do not contribute to generational GCs. They are scanned
- * always.
- *
- * @param[out] x An object that would not be protected by the barrier.
- */
-#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
-
-/**
- * Identical to #RB_OBJ_WB_UNPROTECT(), except it can also assert that the
- * given object is of given type.
- *
- * @param[in] type One of `ARRAY`, `STRING`, etc.
- * @param[out] obj An object of `type` that would not be protected.
- *
- * @internal
- *
- * @shyouhei doesn't understand why this has to be visible from extensions.
- */
-#define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
- (RGENGC_WB_PROTECTED_##type ? OBJ_WB_UNPROTECT(obj) : obj)
-
-/**
- * @private
- *
- * This is an implementation detail of rb_obj_wb_unprotect(). People don't use
- * it directly.
- */
-#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging
-
-/** @cond INTERNAL_MACRO */
-#define RB_OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
-#define RB_OBJ_PROMOTED RB_OBJ_PROMOTED
-/** @endcond */
-
-RBIMPL_SYMBOL_EXPORT_BEGIN()
-/**
- * This is the implementation of #RB_OBJ_WRITE(). People don't use it
- * directly.
- *
- * @param[in] old An object that points to `young`.
- * @param[out] young An object that is referenced from `old`.
- */
-void rb_gc_writebarrier(VALUE old, VALUE young);
-
-/**
- * This is the implementation of #RB_OBJ_WB_UNPROTECT(). People don't use it
- * directly.
- *
- * @param[out] obj An object that does not participate in WB.
- */
-void rb_gc_writebarrier_unprotect(VALUE obj);
-
-#if USE_RGENGC_LOGGING_WB_UNPROTECT
-/**
- * @private
- *
- * This is the implementation of #RGENGC_LOGGING_WB_UNPROTECT(). People
- * don't use it directly.
- *
- * @param[in] objptr Don't know why this is a pointer to void but in
- * reality this is a pointer to an object that is about
- * to be un-protected.
- * @param[in] filename Pass C's `__FILE__` here.
- * @param[in] line Pass C's `__LINE__` here.
- */
-void rb_gc_unprotect_logging(void *objptr, const char *filename, int line);
-#endif
-
-RBIMPL_SYMBOL_EXPORT_END()
-
-RBIMPL_ATTR_PURE_UNLESS_DEBUG()
-RBIMPL_ATTR_ARTIFICIAL()
-/**
- * This is the implementation of #RB_OBJ_PROMOTED(). People don't use it
- * directly.
- *
- * @param[in] obj An object to query.
- * @retval true The object is "promoted".
- * @retval false The object is young. Have not experienced GC at all.
- */
-static inline bool
-RB_OBJ_PROMOTED_RAW(VALUE obj)
-{
- RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
- return RB_FL_ANY_RAW(obj, RUBY_FL_PROMOTED);
-}
-
-RBIMPL_ATTR_PURE_UNLESS_DEBUG()
-RBIMPL_ATTR_ARTIFICIAL()
-/**
- * Tests if the object is "promoted" -- that is, whether the object experienced
- * one or more GC marks.
- *
- * @param[in] obj An object to query.
- * @retval true The object is "promoted".
- * @retval false The object is young. Have not experienced GC at all.
- * @note Hello, is anyone actively calling this function? @shyouhei have
- * never seen any actual usages outside of the GC implementation
- * itself.
- */
-static inline bool
-RB_OBJ_PROMOTED(VALUE obj)
-{
- if (! RB_FL_ABLE(obj)) {
- return false;
- }
- else {
- return RB_OBJ_PROMOTED_RAW(obj);
- }
-}
-
-/**
- * This is the implementation of #RB_OBJ_WB_UNPROTECT(). People don't use it
- * directly.
- *
- * @param[out] x An object that does not participate in WB.
- * @param[in] filename C's `__FILE__` of the caller function.
- * @param[in] line C's `__LINE__` of the caller function.
- * @return x
- */
-static inline VALUE
-rb_obj_wb_unprotect(
- VALUE x,
- RBIMPL_ATTR_MAYBE_UNUSED()
- const char *filename,
- RBIMPL_ATTR_MAYBE_UNUSED()
- int line)
-{
-#if USE_RGENGC_LOGGING_WB_UNPROTECT
- RGENGC_LOGGING_WB_UNPROTECT(RBIMPL_CAST((void *)x), filename, line);
-#endif
- rb_gc_writebarrier_unprotect(x);
- return x;
-}
-
-/**
- * @private
- *
- * This is the implementation of #RB_OBJ_WRITTEN(). People don't use it
- * directly.
- *
- * @param[in] a An old object.
- * @param[in] oldv An object previously stored inside of `old`.
- * @param[out] b A young object.
- * @param[in] filename C's `__FILE__` of the caller function.
- * @param[in] line C's `__LINE__` of the caller function.
- * @return a
- */
-static inline VALUE
-rb_obj_written(
- VALUE a,
- RBIMPL_ATTR_MAYBE_UNUSED()
- VALUE oldv,
- VALUE b,
- RBIMPL_ATTR_MAYBE_UNUSED()
- const char *filename,
- RBIMPL_ATTR_MAYBE_UNUSED()
- int line)
-{
-#if USE_RGENGC_LOGGING_WB_UNPROTECT
- RGENGC_LOGGING_OBJ_WRITTEN(a, oldv, b, filename, line);
-#endif
-
- if (!RB_SPECIAL_CONST_P(b)) {
- rb_gc_writebarrier(a, b);
- }
-
- return a;
-}
-
-/**
- * @private
- *
- * This is the implementation of #RB_OBJ_WRITE(). People don't use it
- * directly.
- *
- * @param[in] a An old object.
- * @param[in] slot A pointer inside of `old`.
- * @param[out] b A young object.
- * @param[in] filename C's `__FILE__` of the caller function.
- * @param[in] line C's `__LINE__` of the caller function.
- * @return a
- */
-static inline VALUE
-rb_obj_write(
- VALUE a, VALUE *slot, VALUE b,
- RBIMPL_ATTR_MAYBE_UNUSED()
- const char *filename,
- RBIMPL_ATTR_MAYBE_UNUSED()
- int line)
-{
-#ifdef RGENGC_LOGGING_WRITE
- RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
-#endif
-
- *slot = b;
-
- rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
- return a;
-}
-
#endif /* RBIMPL_GC_H */
diff --git a/include/ruby/internal/globals.h b/include/ruby/internal/globals.h
index 60d8e5309a..5a414fc472 100644
--- a/include/ruby/internal/globals.h
+++ b/include/ruby/internal/globals.h
@@ -94,7 +94,7 @@ RUBY_EXTERN VALUE rb_cRegexp; /**< `Regexp` class. */
RUBY_EXTERN VALUE rb_cStat; /**< `File::Stat` class. */
RUBY_EXTERN VALUE rb_cString; /**< `String` class. */
RUBY_EXTERN VALUE rb_cStruct; /**< `Struct` class. */
-RUBY_EXTERN VALUE rb_cSymbol; /**< `Symbol` class. */
+RUBY_EXTERN VALUE rb_cSymbol; /**< `Sumbol` class. */
RUBY_EXTERN VALUE rb_cThread; /**< `Thread` class. */
RUBY_EXTERN VALUE rb_cTime; /**< `Time` class. */
RUBY_EXTERN VALUE rb_cTrueClass; /**< `TrueClass` class. */
diff --git a/include/ruby/internal/has/c_attribute.h b/include/ruby/internal/has/c_attribute.h
index 69b0f402cd..c5c48867bf 100644
--- a/include/ruby/internal/has/c_attribute.h
+++ b/include/ruby/internal/has/c_attribute.h
@@ -21,23 +21,11 @@
* @brief Defines #RBIMPL_HAS_C_ATTRIBUTE.
*/
-#include "ruby/internal/has/extension.h"
-#include "ruby/internal/has/warning.h"
-
/** Wraps (or simulates) `__has_c_attribute`. */
#if defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
-#elif RBIMPL_HAS_EXTENSION(c_attributes)
-# /* Hmm. It seems Clang 17 has this macro defined even when -std=c99 mode,
-# * _and_ fails to compile complaining that attributes are C2X feature. We
-# * need to work around this nonsense. */
-# define RBIMPL_HAS_C_ATTRIBUTE(_) __has_c_attribute(_)
-
-#elif RBIMPL_HAS_WARNING("-Wc2x-extensions")
-# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
-
#elif defined(__has_c_attribute)
# define RBIMPL_HAS_C_ATTRIBUTE(_) __has_c_attribute(_)
diff --git a/include/ruby/internal/intern/array.h b/include/ruby/internal/intern/array.h
index 1909fdf17b..2262c6f0c6 100644
--- a/include/ruby/internal/intern/array.h
+++ b/include/ruby/internal/intern/array.h
@@ -187,7 +187,7 @@ VALUE rb_ary_shared_with_p(VALUE lhs, VALUE rhs);
* : (int i) -> T?
* | (int beg, int len) -> ::Array[T]?
* | (Range[int] r) -> ::Array[T]?
- * | (ArithmeticSequence as) -> ::Array[T]? # This also raises RangeError.
+ * | (ArithmeticSequence as) -> ::Array[T]? # This also raises RagneError.
* end
* ```
*/
diff --git a/include/ruby/internal/intern/bignum.h b/include/ruby/internal/intern/bignum.h
index c27f77a1fb..43d68018de 100644
--- a/include/ruby/internal/intern/bignum.h
+++ b/include/ruby/internal/intern/bignum.h
@@ -51,7 +51,7 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
VALUE rb_big_new(size_t len, int sign);
/**
- * Queries if the passed bignum instance is a "bigzero". What is a bigzero?
+ * Queries if the passed bignum instance is a "bigzro". What is a bigzero?
* Well, bignums are for very big integers, but can also represent tiny ones
* like -1, 0, 1. Bigzero are instances of bignums whose values are zero.
* Knowing if a bignum is bigzero can be handy on occasions, like for instance
@@ -793,7 +793,7 @@ size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
* @exception rb_eTypeError `val` doesn't respond to `#to_int`.
* @retval (size_t)-1 Overflowed.
* @retval otherwise
- * `((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)`,
+ `((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)`,
* where val_numbits is the number of bits of `abs(val)`.
* @post If `nlz_bits_ret` is not `NULL` and there is no overflow,
* `(return_value * word_numbits - val_numbits)` is stored in
diff --git a/include/ruby/internal/intern/error.h b/include/ruby/internal/intern/error.h
index bf8daadd3e..9c153cbac5 100644
--- a/include/ruby/internal/intern/error.h
+++ b/include/ruby/internal/intern/error.h
@@ -235,7 +235,7 @@ RBIMPL_ATTR_NORETURN()
* @param[in] max Maximum allowed `argc`.
* @exception rb_eArgError Always.
*/
-void rb_error_arity(int argc, int min, int max);
+MJIT_STATIC void rb_error_arity(int argc, int min, int max);
RBIMPL_SYMBOL_EXPORT_END()
diff --git a/include/ruby/internal/intern/gc.h b/include/ruby/internal/intern/gc.h
new file mode 100644
index 0000000000..2ee1d257db
--- /dev/null
+++ b/include/ruby/internal/intern/gc.h
@@ -0,0 +1,392 @@
+#ifndef RBIMPL_INTERN_GC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_INTERN_GC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Public APIs related to ::rb_mGC.
+ */
+#include "ruby/internal/config.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h> /* size_t */
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* ssize_t */
+#endif
+
+#include "ruby/internal/attr/cold.h"
+#include "ruby/internal/attr/noreturn.h"
+#include "ruby/internal/attr/nonnull.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/value.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* gc.c */
+
+RBIMPL_ATTR_COLD()
+RBIMPL_ATTR_NORETURN()
+/**
+ * Triggers out-of-memory error. If possible it raises ::rb_eNoMemError. But
+ * because we are running out of memory that is not always doable. This
+ * function tries hard to show something, but ultimately can die silently.
+ *
+ * @exception rb_eNoMemError Raises it if possible.
+ */
+void rb_memerror(void);
+
+RBIMPL_ATTR_PURE()
+/**
+ * Queries if the GC is busy.
+ *
+ * @retval 0 It isn't.
+ * @retval 1 It is.
+ */
+int rb_during_gc(void);
+
+RBIMPL_ATTR_NONNULL((1))
+/**
+ * Marks objects between the two pointers. This is one of the GC utility
+ * functions that you can call when you design your own
+ * ::rb_data_type_struct::dmark.
+ *
+ * @pre Continuous memory region from `start` to `end` shall be fully
+ * addressable.
+ * @param[out] start Pointer to an array of objects.
+ * @param[out] end Pointer that terminates the array of objects.
+ * @post Objects from `start` (included) to `end` (excluded) are marked.
+ *
+ * @internal
+ *
+ * `end` can be NULL... But that just results in no-op.
+ */
+void rb_gc_mark_locations(const VALUE *start, const VALUE *end);
+
+/**
+ * Identical to rb_mark_hash(), except it marks only values of the table and
+ * leave their associated keys unmarked. This is one of the GC utility
+ * functions that you can call when you design your own
+ * ::rb_data_type_struct::dmark.
+ *
+ * @warning Of course it can break GC. Leave it unused if unsure.
+ * @param[in] tbl A table to mark.
+ * @post Values stored in `tbl` are marked.
+ */
+void rb_mark_tbl(struct st_table *tbl);
+
+/**
+ * Identical to rb_mark_tbl(), except it marks objects using
+ * rb_gc_mark_movable(). This is one of the GC utility functions that you can
+ * call when you design your own ::rb_data_type_struct::dmark.
+ *
+ * @warning Of course it can break GC. Leave it unused if unsure.
+ * @param[in] tbl A table to mark.
+ * @post Values stored in `tbl` are marked.
+ */
+void rb_mark_tbl_no_pin(struct st_table *tbl);
+
+/**
+ * Identical to rb_mark_hash(), except it marks only keys of the table and
+ * leave their associated values unmarked. This is one of the GC utility
+ * functions that you can call when you design your own
+ * ::rb_data_type_struct::dmark.
+ *
+ * @warning Of course it can break GC. Leave it unused if unsure.
+ * @param[in] tbl A table to mark.
+ * @post Keys stored in `tbl` are marked.
+ */
+void rb_mark_set(struct st_table *tbl);
+
+/**
+ * Marks keys and values associated inside of the given table. This is one of
+ * the GC utility functions that you can call when you design your own
+ * ::rb_data_type_struct::dmark.
+ *
+ * @param[in] tbl A table to mark.
+ * @post Objects stored in `tbl` are marked.
+ */
+void rb_mark_hash(struct st_table *tbl);
+
+/**
+ * Updates references inside of tables. After you marked values using
+ * rb_mark_tbl_no_pin(), the objects inside of the table could of course be
+ * moved. This function is to fixup those references. You can call this from
+ * your ::rb_data_type_struct::dcompact.
+ *
+ * @param[out] ptr A table that potentially includes moved references.
+ * @post Moved references, if any, are corrected.
+ */
+void rb_gc_update_tbl_refs(st_table *ptr);
+
+/**
+ * Identical to rb_gc_mark(), except it allows the passed value be a
+ * non-object. For instance pointers to different type of memory regions are
+ * allowed here. Such values are silently ignored. This is one of the GC
+ * utility functions that you can call when you design your own
+ * ::rb_data_type_struct::dmark.
+ *
+ * @param[out] obj A possible object.
+ * @post `obj` is marked, if possible.
+ */
+void rb_gc_mark_maybe(VALUE obj);
+
+/**
+ * Marks an object. This is one of the GC utility functions that you can call
+ * when you design your own ::rb_data_type_struct::dmark.
+ *
+ * @param[out] obj Arbitrary Ruby object.
+ * @post `obj` is marked.
+ */
+void rb_gc_mark(VALUE obj);
+
+/**
+ * Maybe this is the only function provided for C extensions to control the
+ * pinning of objects, so let us describe it in detail. These days Ruby's GC
+ * is copying. As far as an object's physical address is guaranteed unused, it
+ * can move around the object space. Our GC engine rearranges these objects
+ * after it reclaims unreachable objects from our object space, so that the
+ * space is compact (improves memory locality). This is called the
+ * "compaction" phase, and works well most of the time... as far as there are
+ * no C extensions. C extensions complicate the scenario because Ruby core
+ * cannot detect any use of the physical address of an object inside of C
+ * functions. In order to prevent memory corruptions, objects observable from
+ * C extensions are "pinned"; they stick to where they are born until they die,
+ * just in case any C extensions touch their raw pointers. This variant of
+ * scheme is called "Mostly-Copying" garbage collector. Authors of C
+ * extensions, however, can extremely carefully write them to become
+ * compaction-aware. To do so avoid referring to a Ruby object from inside of
+ * your struct in the first place. But if that is not possible, use this
+ * function from your ::rb_data_type_struct::dmark then. This way objects
+ * marked using it are considered movable. If you chose this way you have to
+ * manually fix up locations of such moved pointers using rb_gc_location().
+ *
+ * @see Bartlett, Joel F., "Compacting Garbage Collection with Ambiguous
+ * Roots", ACM SIGPLAN Lisp Pointers Volume 1 Issue 6 pp. 3-12,
+ * April-May-June, 1988. https://doi.org/10.1145/1317224.1317225
+ *
+ * @param[in] obj Object that is movable.
+ * @post Values stored in `tbl` are marked.
+ */
+void rb_gc_mark_movable(VALUE obj);
+
+/**
+ * Finds a new "location" of an object. An object can be moved on compaction.
+ * This function projects its new abode, or just returns the passed object if
+ * not moved. This is one of the GC utility functions that you can call when
+ * you design your own ::rb_data_type_struct::dcompact.
+ *
+ * @param[in] obj An object, possibly already moved to somewhere else.
+ * @return An object, which holds the current contents of former `obj`.
+ */
+VALUE rb_gc_location(VALUE obj);
+
+/**
+ * Asserts that the passed object is no longer needed. Such objects are
+ * reclaimed sooner or later so this function is not mandatory. But sometimes
+ * you can know from your application knowledge that an object is surely dead
+ * at some point. Calling this as a hint can be a polite way.
+ *
+ * @param[out] obj Object, dead.
+ * @pre `obj` have never been passed to this function before.
+ * @post `obj` could be invalidated.
+ * @warning It is a failure to pass an object multiple times to this
+ * function.
+ * @deprecated This is now a no-op function.
+ */
+RBIMPL_ATTR_DEPRECATED(("this is now a no-op function"))
+void rb_gc_force_recycle(VALUE obj);
+
+/**
+ * Triggers a GC process. This was the only GC entry point that we had at the
+ * beginning. Over time our GC evolved. Now what this function does is just a
+ * very simplified variation of the entire GC algorithms. A series of
+ * procedures kicked by this API is called a "full" GC.
+ *
+ * - It immediately scans the entire object space to sort the dead.
+ * - It immediately reclaims any single dead bodies to reuse later.
+ *
+ * It is worth noting that the procedures above do not include evaluations of
+ * finalisers. They run later.
+ *
+ * @internal
+ *
+ * Finalisers are deferred until we can handle interrupts. See
+ * `rb_postponed_job_flush` in vm_trace.c.
+ *
+ * Of course there are GC that are not "full". For instance this one and the
+ * GC which runs when we are running out of memory are different. See
+ * `gc_profile_record_flag` defined in gc.c for the kinds of GC.
+ *
+ * In spite of the name this is not what everything that a GC can trigger. As
+ * of writing it seems this function does not trigger compaction. But this
+ * might change in future.
+ */
+void rb_gc(void);
+
+/**
+ * Copy&paste an object's finaliser to another. This is one of the GC utility
+ * functions that you can call when you design your own `initialize_copy`,
+ * `initialize_dup`, `initialize_clone`.
+ *
+ * @param[out] dst Destination object.
+ * @param[in] src Source object.
+ * @post `dst` and `src` share the same finaliser.
+ *
+ * @internal
+ *
+ * But isn't it easier for you to call super, and let `Object#initialize_copy`
+ * call this function instead?
+ */
+void rb_gc_copy_finalizer(VALUE dst, VALUE src);
+
+/**
+ * (Re-) enables GC. This makes sense only after you called rb_gc_disable().
+ *
+ * @retval RUBY_Qtrue GC was disabled before.
+ * @retval RUBY_Qfalse GC was enabled before.
+ * @post GC is enabled.
+ *
+ * @internal
+ *
+ * This is one of such exceptional functions that does not raise both Ruby
+ * exceptions and C++ exceptions.
+ */
+VALUE rb_gc_enable(void);
+
+/**
+ * Disables GC. This prevents automatic GC runs when the process is running
+ * out of memory. Such situations shall result in rb_memerror(). However this
+ * does not prevent users from manually invoking rb_gc(). That should work.
+ * People abused this by disabling GC at the beginning of an event loop,
+ * process events without GC overheads, then manually force reclaiming garbage
+ * at the bottom of the loop. However because our GC is now much smarter than
+ * just calling rb_gc(), this technique is proven to be sub-optimal these days.
+ * It is believed that there is currently practically no needs of this
+ * function.
+ *
+ * @retval RUBY_Qtrue GC was disabled before.
+ * @retval RUBY_Qfalse GC was enabled before.
+ * @post GC is disabled.
+ */
+VALUE rb_gc_disable(void);
+
+/**
+ * Identical to rb_gc(), except the return value.
+ *
+ * @return Always returns ::RUBY_Qnil.
+ */
+VALUE rb_gc_start(void);
+
+/**
+ * Assigns a finaliser for an object. Each objects can have objects (typically
+ * blocks) that run immediately after that object dies. They are called
+ * finalisers of an object. This function associates a finaliser object with a
+ * target object.
+ *
+ * @note Note that finalisers run _after_ the object they finalise dies. You
+ * cannot for instance call its methods.
+ * @note If your finaliser references the object it finalises that object
+ * loses any chance to become a garbage; effectively leaks memory until
+ * the end of the process.
+ *
+ * @param[in] obj Target to finalise.
+ * @param[in] block Something `call`able.
+ * @exception rb_eRuntimeError Somehow `obj` cannot have finalisers.
+ * @exception rb_eFrozenError `obj` is frozen.
+ * @exception rb_eArgError `block` doesn't respond to `call`.
+ * @return The passed `block`.
+ * @post `block` runs after `obj` dies.
+ */
+VALUE rb_define_finalizer(VALUE obj, VALUE block);
+
+/**
+ * Modifies the object so that it has no finalisers at all. This function is
+ * mainly provided for symmetry. No practical usages can be thought of.
+ *
+ * @param[out] obj Object to clear its finalisers.
+ * @exception rb_eFrozenError `obj` is frozen.
+ * @return The passed `obj`.
+ * @post `obj` has no finalisers.
+ * @note There is no way to undefine a specific part of many finalisers
+ * that `obj` could have. All you can do is to clear them all.
+ */
+VALUE rb_undefine_finalizer(VALUE obj);
+
+/**
+ * Identical to rb_gc_stat(), with "count" parameter.
+ *
+ * @return Lifetime total number of runs of GC.
+ */
+size_t rb_gc_count(void);
+
+/**
+ * Obtains various GC related profiles. The parameter can be either a Symbol
+ * or a Hash. If a Hash is passed, it is filled with everything currently
+ * available. If a Symbol is passed just that portion is returned.
+ *
+ * Possible variations of keys you can pass here change from version to
+ * version. You can get the list of known keys by passing an empty hash and
+ * let it be filled.
+ *
+ * @param[in,out] key_or_buf A Symbol, or a Hash.
+ * @exception rb_eTypeError Neither Symbol nor Hash.
+ * @exception rb_eFrozenError Frozen hash is passed.
+ * @return In case a Hash is passed it returns 0. Otherwise the
+ * profile value associated with the given key is returned.
+ * @post In case a Hash is passed it is filled with values.
+ */
+size_t rb_gc_stat(VALUE key_or_buf);
+
+/**
+ * Obtains various info regarding the most recent GC run. This includes for
+ * instance the reason of the GC. The parameter can be either a Symbol or a
+ * Hash. If a Hash is passed, it is filled with everything currently
+ * available. If a Symbol is passed just that portion is returned.
+ *
+ * Possible variations of keys you can pass here change from version to
+ * version. You can get the list of known keys by passing an empty hash and
+ * let it be filled.
+ *
+ * @param[in,out] key_or_buf A Symbol, or a Hash.
+ * @exception rb_eTypeError Neither Symbol nor Hash.
+ * @exception rb_eFrozenError Frozen hash is passed.
+ * @return In case a Hash is passed it returns that hash. Otherwise
+ * the profile value associated with the given key is returned.
+ * @post In case a Hash is passed it is filled with values.
+ */
+VALUE rb_gc_latest_gc_info(VALUE key_or_buf);
+
+/**
+ * Informs that there are external memory usages. Our GC runs when we are
+ * running out of memory. The amount of memory, however, can increase/decrease
+ * behind-the-scene. For instance DLLs can allocate memories using `mmap(2)`
+ * etc, which are opaque to us. Registering such external allocations using
+ * this function enables proper detection of how much memories an object used
+ * as a whole. That will trigger GCs more often than it would otherwise. You
+ * can also pass negative numbers here, to indicate that such external
+ * allocations are gone.
+ *
+ * @param[in] diff Amount of memory increased(+)/decreased(-).
+ */
+void rb_gc_adjust_memory_usage(ssize_t diff);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RBIMPL_INTERN_GC_H */
diff --git a/include/ruby/internal/intern/load.h b/include/ruby/internal/intern/load.h
index 9ceb98c2e4..288a16c2ec 100644
--- a/include/ruby/internal/intern/load.h
+++ b/include/ruby/internal/intern/load.h
@@ -177,43 +177,6 @@ VALUE rb_f_require(VALUE self, VALUE feature);
VALUE rb_require_string(VALUE feature);
/**
- * Resolves and returns a symbol of a function in the native extension
- * specified by the feature and symbol names. Extensions will use this function
- * to access the symbols provided by other native extensions.
- *
- * @param[in] feature Name of a feature, e.g. `"json"`.
- * @param[in] symbol Name of a symbol defined by the feature.
- * @return The resolved symbol of a function, defined and externed by the
- * specified feature. It may be NULL if the feature is not loaded,
- * the feature is not extension, or the symbol is not found.
- */
-void *rb_ext_resolve_symbol(const char *feature, const char *symbol);
-
-/**
- * This macro is to provide backwards compatibility. It provides a way to
- * define function prototypes and resolving function symbols in a safe way.
- *
- * ```CXX
- * // prototypes
- * #ifdef HAVE_RB_EXT_RESOLVE_SYMBOL
- * VALUE *(*other_extension_func)(VALUE,VALUE);
- * #else
- * VALUE other_extension_func(VALUE);
- * #endif
- *
- * // in Init_xxx()
- * #ifdef HAVE_RB_EXT_RESOLVE_SYMBOL
- * other_extension_func = \
- * (VALUE(*)(VALUE,VALUE))rb_ext_resolve_symbol(fname, sym_name);
- * if (other_extension_func == NULL) {
- * // raise your own error
- * }
- * #endif
- * ```
- */
-#define HAVE_RB_EXT_RESOLVE_SYMBOL 1
-
-/**
* @name extension configuration
* @{
*/
diff --git a/include/ruby/internal/intern/process.h b/include/ruby/internal/intern/process.h
index cfa5e13162..7a7b24ed4b 100644
--- a/include/ruby/internal/intern/process.h
+++ b/include/ruby/internal/intern/process.h
@@ -31,15 +31,6 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
/* process.c */
/**
- * Wait for the specified process to terminate, reap it, and return its status.
- *
- * @param[in] pid The process ID to wait for.
- * @param[in] flags The flags to pass to waitpid(2).
- * @return VALUE An instance of Process::Status.
- */
-VALUE rb_process_status_wait(rb_pid_t pid, int flags);
-
-/**
* Sets the "last status", or the `$?`.
*
* @param[in] status The termination status, as defined in `waitpid(3posix)`.
@@ -256,7 +247,7 @@ rb_pid_t rb_spawn_err(int argc, const VALUE *argv, char *errbuf, size_t buflen);
*
* @internal
*
- * This function might or might not exist depending on `./configure` result.
+ * This function might or might not exist depending on `./confiugre` result.
* It must be a portability hell. Better not use.
*/
VALUE rb_proc_times(VALUE _);
diff --git a/include/ruby/internal/intern/re.h b/include/ruby/internal/intern/re.h
index 4dd58b469b..31f5593275 100644
--- a/include/ruby/internal/intern/re.h
+++ b/include/ruby/internal/intern/re.h
@@ -87,6 +87,11 @@ void rb_match_busy(VALUE md);
* @retval RUBY_Qfalse There is a `n`-th capture and is empty.
* @retval RUBY_Qtrue There is a `n`-th capture that has something.
*
+ * @internal
+ *
+ * @shyouhei wonders: why there are both rb_reg_match_defined() and
+ * rb_match_nth_defined, which are largely the same things, but do not share
+ * their implementations at all?
*/
VALUE rb_reg_nth_defined(int n, VALUE md);
diff --git a/include/ruby/internal/intern/select.h b/include/ruby/internal/intern/select.h
index 6ba84c6e63..fabc287cd1 100644
--- a/include/ruby/internal/intern/select.h
+++ b/include/ruby/internal/intern/select.h
@@ -76,7 +76,7 @@ struct timeval;
*
* Although any file descriptors are possible here, it makes completely no
* sense to pass a descriptor that is not `O_NONBLOCK`. If you want to know
- * the reason for this limitation in detail, you might find this thread super
+ * the reason for this limitatuon in detail, you might find this thread super
* interesting: https://lkml.org/lkml/2004/10/6/117
*/
int rb_thread_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);
diff --git a/include/ruby/internal/intern/signal.h b/include/ruby/internal/intern/signal.h
index e5b6d6c3d5..84f7558404 100644
--- a/include/ruby/internal/intern/signal.h
+++ b/include/ruby/internal/intern/signal.h
@@ -113,6 +113,12 @@ RBIMPL_ATTR_NONNULL(())
*/
VALUE rb_f_kill(int argc, const VALUE *argv);
+/* This must be private, @shyouhei guesses. */
+#ifdef POSIX_SIGNAL
+#define posix_signal ruby_posix_signal
+void (*posix_signal(int, void (*)(int)))(int);
+#endif
+
RBIMPL_ATTR_PURE()
/**
* Queries the name of the signal. It returns for instance `"KILL"` for
diff --git a/include/ruby/internal/intern/struct.h b/include/ruby/internal/intern/struct.h
index 4510508d77..312cf444e2 100644
--- a/include/ruby/internal/intern/struct.h
+++ b/include/ruby/internal/intern/struct.h
@@ -46,10 +46,10 @@ VALUE rb_struct_new(VALUE klass, ...);
*
* @param[in] name Name of the class.
* @param[in] ... Arbitrary number of `const char*`, terminated by
- * NULL. Each of which are the name of fields.
+ * zero. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
- * @exception rb_eArgError Duplicated field name.
+ * @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post Global toplevel constant `name` is defined.
* @note `name` is allowed to be a null pointer. This function creates
@@ -70,10 +70,10 @@ RBIMPL_ATTR_NONNULL((2))
* @param[out] space Namespace that the defining class shall reside.
* @param[in] name Name of the class.
* @param[in] ... Arbitrary number of `const char*`, terminated by
- * NULL. Each of which are the name of fields.
+ * zero. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
- * @exception rb_eArgError Duplicated field name.
+ * @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post `name` is a constant under `space`.
* @note In contrast to rb_struct_define(), it doesn't make any sense to
@@ -164,10 +164,10 @@ VALUE rb_struct_alloc_noinit(VALUE klass);
* @param[in] super Superclass of the defining class.
* @param[in] func Must be 0 for extension libraries.
* @param[in] ... Arbitrary number of `const char*`, terminated by
- * NULL. Each of which are the name of fields.
+ * zero. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
- * @exception rb_eArgError Duplicated field name.
+ * @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post Global toplevel constant `name` is defined.
* @note `name` is allowed to be a null pointer. This function creates
@@ -187,10 +187,10 @@ RBIMPL_ATTR_NONNULL((2))
* @param[in] super Superclass of the defining class.
* @param[in] alloc Must be 0 for extension libraries.
* @param[in] ... Arbitrary number of `const char*`, terminated by
- * NULL. Each of which are the name of fields.
+ * zero. Each of which are the name of fields.
* @exception rb_eNameError `class_name` is not a constant name.
* @exception rb_eTypeError `class_name` is already taken.
- * @exception rb_eArgError Duplicated field name.
+ * @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post `class_name` is a constant under `outer`.
* @note In contrast to rb_struct_define_without_accessor(), it doesn't
@@ -198,20 +198,6 @@ RBIMPL_ATTR_NONNULL((2))
*/
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);
-/**
- * Defines an anonymous data class.
- *
- * @endinternal
- *
- * @param[in] super Superclass of the defining class. Must be a
- * descendant of ::rb_cData, or 0 as ::rb_cData.
- * @param[in] ... Arbitrary number of `const char*`, terminated by
- * NULL. Each of which are the name of fields.
- * @exception rb_eArgError Duplicated field name.
- * @return The defined class.
- */
-VALUE rb_data_define(VALUE super, ...);
-
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_STRUCT_H */
diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h
index 8f00787512..6884db195d 100644
--- a/include/ruby/internal/memory.h
+++ b/include/ruby/internal/memory.h
@@ -62,7 +62,7 @@
#include "ruby/backward/2/assume.h"
#include "ruby/defines.h"
-/** @cond INTERNAL_MACRO */
+/** @cond INTENAL_MACRO */
/* Make alloca work the best possible way. */
#if defined(alloca)
diff --git a/include/ruby/internal/newobj.h b/include/ruby/internal/newobj.h
index ba1d7cbe59..a8a5557a25 100644
--- a/include/ruby/internal/newobj.h
+++ b/include/ruby/internal/newobj.h
@@ -172,8 +172,6 @@ RBIMPL_ATTR_DEPRECATED(("This is no longer how Object#clone works."))
static inline void
rb_clone_setup(VALUE clone, VALUE obj)
{
- (void)clone;
- (void)obj;
return;
}
@@ -191,8 +189,6 @@ RBIMPL_ATTR_DEPRECATED(("This is no longer how Object#dup works."))
static inline void
rb_dup_setup(VALUE dup, VALUE obj)
{
- (void)dup;
- (void)obj;
return;
}
diff --git a/include/ruby/internal/rgengc.h b/include/ruby/internal/rgengc.h
new file mode 100644
index 0000000000..7ea04442f6
--- /dev/null
+++ b/include/ruby/internal/rgengc.h
@@ -0,0 +1,443 @@
+#ifndef RBIMPL_RGENGC_H /*-*-C++-*-vi:se ft=cpp:*/
+#define RBIMPL_RGENGC_H
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief RGENGC write-barrier APIs.
+ * @see Sasada, K., "Gradual write-barrier insertion into a Ruby
+ * interpreter", in proceedings of the 2019 ACM SIGPLAN
+ * International Symposium on Memory Management (ISMM 2019), pp
+ * 115-121, 2019. https://doi.org/10.1145/3315573.3329986
+ */
+#include "ruby/internal/attr/artificial.h"
+#include "ruby/internal/attr/maybe_unused.h"
+#include "ruby/internal/attr/pure.h"
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/special_consts.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/assert.h"
+
+/**
+ * @private
+ *
+ * @deprecated This macro once was a thing in the old days, but makes no sense
+ * any longer today. Exists here for backwards compatibility
+ * only. You can safely forget about it.
+ */
+#undef USE_RGENGC
+#define USE_RGENGC 1
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable incremental GC feature. It
+ * has to be set at the time ruby itself compiles. Makes no sense for 3rd
+ * parties. It is safe for them to set this though; that just doesn't change
+ * anything.
+ */
+#ifndef USE_RINCGC
+# define USE_RINCGC 1
+#endif
+
+/**
+ * @deprecated This macro seems broken. Setting this to anything other than
+ * zero just doesn't compile. We need to KonMari.
+ */
+#ifndef USE_RGENGC_LOGGING_WB_UNPROTECT
+# define USE_RGENGC_LOGGING_WB_UNPROTECT 0
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RArray. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_ARRAY
+# define RGENGC_WB_PROTECTED_ARRAY 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RHash. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_HASH
+# define RGENGC_WB_PROTECTED_HASH 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RStruct. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_STRUCT
+# define RGENGC_WB_PROTECTED_STRUCT 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RString. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_STRING
+# define RGENGC_WB_PROTECTED_STRING 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RObject. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_OBJECT
+# define RGENGC_WB_PROTECTED_OBJECT 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RRegexp. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_REGEXP
+# define RGENGC_WB_PROTECTED_REGEXP 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RClass. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_CLASS
+# define RGENGC_WB_PROTECTED_CLASS 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RFloat. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_FLOAT
+# define RGENGC_WB_PROTECTED_FLOAT 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RComplex. It has to be set at the time ruby itself compiles.
+ * Makes no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_COMPLEX
+# define RGENGC_WB_PROTECTED_COMPLEX 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RRational. It has to be set at the time ruby itself compiles.
+ * Makes no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_RATIONAL
+# define RGENGC_WB_PROTECTED_RATIONAL 1
+#endif
+
+/**
+ * @private
+ *
+ * This is a compile-time flag to enable/disable write barrier for
+ * struct ::RBignum. It has to be set at the time ruby itself compiles. Makes
+ * no sense for 3rd parties.
+ */
+#ifndef RGENGC_WB_PROTECTED_BIGNUM
+# define RGENGC_WB_PROTECTED_BIGNUM 1
+#endif
+
+/**
+ * @private
+ *
+ * @deprecated This macro once was a thing in the old days, but makes no sense
+ * any longer today. Exists here for backwards compatibility
+ * only. You can safely forget about it.
+ *
+ * @internal
+ *
+ * @shyouhei doesn't think anybody uses this right now.
+ */
+#ifndef RGENGC_WB_PROTECTED_NODE_CREF
+# define RGENGC_WB_PROTECTED_NODE_CREF 1
+#endif
+
+/**
+ * @defgroup rgengc Write barrier (WB) interfaces:
+ *
+ * @note The following core interfaces can be changed in the future. Please
+ * catch up if you want to insert WB into C-extensions correctly.
+ *
+ * @{
+ */
+
+/**
+ * Declaration of a "back" pointer. This is a write barrier for new reference
+ * from "old" generation to "young" generation. It writes `young` into
+ * `*slot`, which is a pointer inside of `old`.
+ *
+ * @param[in] old An old object.
+ * @param[in] slot A pointer inside of `old`.
+ * @param[out] young A young object.
+ */
+#define RB_OBJ_WRITE(old, slot, young) \
+ RBIMPL_CAST(rb_obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young), __FILE__, __LINE__))
+
+/**
+ * Identical to #RB_OBJ_WRITE(), except it doesn't write any values, but only a
+ * WB declaration. `oldv` is replaced value with `b` (not used in current
+ * Ruby).
+ *
+ * @param[in] old An old object.
+ * @param[in] oldv An object previously stored inside of `old`.
+ * @param[out] young A young object.
+ */
+#define RB_OBJ_WRITTEN(old, oldv, young) \
+ RBIMPL_CAST(rb_obj_written((VALUE)(old), (VALUE)(oldv), (VALUE)(young), __FILE__, __LINE__))
+/** @} */
+
+#define OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW /**< @old{RB_OBJ_PROMOTED_RAW} */
+#define OBJ_PROMOTED RB_OBJ_PROMOTED /**< @old{RB_OBJ_PROMOTED} */
+#define OBJ_WB_UNPROTECT RB_OBJ_WB_UNPROTECT /**< @old{RB_OBJ_WB_UNPROTECT} */
+
+/**
+ * Asserts that the passed object is not fenced by write barriers. Objects of
+ * such property do not contribute to generational GCs. They are scanned
+ * always.
+ *
+ * @param[out] x An object that would not be protected by the barrier.
+ */
+#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
+
+/**
+ * Identical to #RB_OBJ_WB_UNPROTECT(), except it can also assert that the
+ * given object is of given type.
+ *
+ * @param[in] type One of `ARRAY`, `STRING`, etc.
+ * @param[out] obj An object of `type` that would not be protected.
+ *
+ * @internal
+ *
+ * @shyouhei doesn't understand why this has to be visible from extensions.
+ */
+#define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
+ (RGENGC_WB_PROTECTED_##type ? OBJ_WB_UNPROTECT(obj) : obj)
+
+/**
+ * @private
+ *
+ * This is an implementation detail of rb_obj_wb_unprotect(). People don't use
+ * it directly.
+ */
+#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging
+
+/** @cond INTERNAL_MACRO */
+#define RB_OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
+#define RB_OBJ_PROMOTED RB_OBJ_PROMOTED
+/** @endcond */
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+/**
+ * This is the implementation of #RB_OBJ_WRITE(). People don't use it
+ * directly.
+ *
+ * @param[in] old An object that points to `young`.
+ * @param[out] young An object that is referenced from `old`.
+ */
+void rb_gc_writebarrier(VALUE old, VALUE young);
+
+/**
+ * This is the implementation of #RB_OBJ_WB_UNPROTECT(). People don't use it
+ * directly.
+ *
+ * @param[out] obj An object that does not participate in WB.
+ */
+void rb_gc_writebarrier_unprotect(VALUE obj);
+
+#if USE_RGENGC_LOGGING_WB_UNPROTECT
+/**
+ * @private
+ *
+ * This is the implementation of #RGENGC_LOGGING_WB_UNPROTECT(). People
+ * don't use it directly.
+ *
+ * @param[in] objptr Don't know why this is a pointer to void but in
+ * reality this is a pointer to an object that is about
+ * to be un-protected.
+ * @param[in] filename Pass C's `__FILE__` here.
+ * @param[in] line Pass C's `__LINE__` here.
+ */
+void rb_gc_unprotect_logging(void *objptr, const char *filename, int line);
+#endif
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * This is the implementation of #RB_OBJ_PROMOTED(). People don't use it
+ * directly.
+ *
+ * @param[in] obj An object to query.
+ * @retval true The object is "promoted".
+ * @retval false The object is young. Have not experienced GC at all.
+ */
+static inline bool
+RB_OBJ_PROMOTED_RAW(VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
+ return RB_FL_ANY_RAW(obj, RUBY_FL_PROMOTED);
+}
+
+RBIMPL_ATTR_PURE_UNLESS_DEBUG()
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * Tests if the object is "promoted" -- that is, whether the object experienced
+ * one or more GC marks.
+ *
+ * @param[in] obj An object to query.
+ * @retval true The object is "promoted".
+ * @retval false The object is young. Have not experienced GC at all.
+ * @note Hello, is anyone actively calling this function? @shyouhei have
+ * never seen any actual usages outside of the GC implementation
+ * itself.
+ */
+static inline bool
+RB_OBJ_PROMOTED(VALUE obj)
+{
+ if (! RB_FL_ABLE(obj)) {
+ return false;
+ }
+ else {
+ return RB_OBJ_PROMOTED_RAW(obj);
+ }
+}
+
+/**
+ * This is the implementation of #RB_OBJ_WB_UNPROTECT(). People don't use it
+ * directly.
+ *
+ * @param[out] x An object that does not participate in WB.
+ * @param[in] filename C's `__FILE__` of the caller function.
+ * @param[in] line C's `__LINE__` of the caller function.
+ * @return x
+ */
+static inline VALUE
+rb_obj_wb_unprotect(
+ VALUE x,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ const char *filename,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int line)
+{
+#if USE_RGENGC_LOGGING_WB_UNPROTECT
+ RGENGC_LOGGING_WB_UNPROTECT(RBIMPL_CAST((void *)x), filename, line);
+#endif
+ rb_gc_writebarrier_unprotect(x);
+ return x;
+}
+
+/**
+ * @private
+ *
+ * This is the implementation of #RB_OBJ_WRITTEN(). People don't use it
+ * directly.
+ *
+ * @param[in] a An old object.
+ * @param[in] oldv An object previously stored inside of `old`.
+ * @param[out] b A young object.
+ * @param[in] filename C's `__FILE__` of the caller function.
+ * @param[in] line C's `__LINE__` of the caller function.
+ * @return a
+ */
+static inline VALUE
+rb_obj_written(
+ VALUE a,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ VALUE oldv,
+ VALUE b,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ const char *filename,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int line)
+{
+#if USE_RGENGC_LOGGING_WB_UNPROTECT
+ RGENGC_LOGGING_OBJ_WRITTEN(a, oldv, b, filename, line);
+#endif
+
+ if (!RB_SPECIAL_CONST_P(b)) {
+ rb_gc_writebarrier(a, b);
+ }
+
+ return a;
+}
+
+/**
+ * @private
+ *
+ * This is the implementation of #RB_OBJ_WRITE(). People don't use it
+ * directly.
+ *
+ * @param[in] a An old object.
+ * @param[in] slot A pointer inside of `old`.
+ * @param[out] b A young object.
+ * @param[in] filename C's `__FILE__` of the caller function.
+ * @param[in] line C's `__LINE__` of the caller function.
+ * @return a
+ */
+static inline VALUE
+rb_obj_write(
+ VALUE a, VALUE *slot, VALUE b,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ const char *filename,
+ RBIMPL_ATTR_MAYBE_UNUSED()
+ int line)
+{
+#ifdef RGENGC_LOGGING_WRITE
+ RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
+#endif
+
+ *slot = b;
+
+ rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
+ return a;
+}
+
+#endif /* RBIMPL_RGENGC_H */
diff --git a/include/ruby/io.h b/include/ruby/io.h
index e9dfeda5b1..88029b1bb9 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -49,11 +49,11 @@
/** @endcond */
#include "ruby/internal/attr/const.h"
-#include "ruby/internal/attr/packed_struct.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
+#include "ruby/backward/2/attributes.h" /* PACKED_STRUCT_UNALIGNED */
// IO#wait, IO#wait_readable, IO#wait_writable, IO#wait_priority are defined by this implementation.
#define RUBY_IO_WAIT_METHODS
@@ -78,20 +78,17 @@ RUBY_EXTERN VALUE rb_eIOTimeoutError;
*
* This is visible from extension libraries because `io/wait` wants it.
*/
-enum rb_io_event {
+typedef enum {
RUBY_IO_READABLE = RB_WAITFD_IN, /**< `IO::READABLE` */
RUBY_IO_WRITABLE = RB_WAITFD_OUT, /**< `IO::WRITABLE` */
RUBY_IO_PRIORITY = RB_WAITFD_PRI, /**< `IO::PRIORITY` */
-};
-
-typedef enum rb_io_event rb_io_event_t;
+} rb_io_event_t;
/**
* IO buffers. This is an implementation detail of ::rb_io_t::wbuf and
* ::rb_io_t::rbuf. People don't manipulate it directly.
*/
-RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN()
-struct rb_io_internal_buffer {
+PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t {
/** Pointer to the underlying memory region, of at least `capa` bytes. */
char *ptr; /* off + len <= capa */
@@ -104,10 +101,10 @@ struct rb_io_internal_buffer {
/** Designed capacity of the buffer. */
int capa;
-} RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END();
+});
/** @alias{rb_io_buffer_t} */
-typedef struct rb_io_internal_buffer rb_io_buffer_t;
+typedef struct rb_io_buffer_t rb_io_buffer_t;
/** Decomposed encoding flags (e.g. `"enc:enc2""`). */
/*
@@ -116,7 +113,7 @@ typedef struct rb_io_internal_buffer rb_io_buffer_t;
* e1 NULL force_encoding(e1) convert str.encoding to e1
* e1 e2 convert from e2 to e1 convert str.encoding to e2
*/
-struct rb_io_encoding {
+struct rb_io_enc_t {
/** Internal encoding. */
rb_encoding *enc;
/** External encoding. */
@@ -137,51 +134,40 @@ struct rb_io_encoding {
VALUE ecopts;
};
-#ifndef HAVE_RB_IO_T
-#define HAVE_RB_IO_T 1
/** Ruby's IO, metadata and buffers. */
-struct rb_io {
+typedef struct rb_io_t {
+
/** The IO's Ruby level counterpart. */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
VALUE self;
/** stdio ptr for read/write, if available. */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
FILE *stdio_file;
/** file descriptor. */
- RBIMPL_ATTR_DEPRECATED(("rb_io_descriptor"))
int fd;
/** mode flags: FMODE_XXXs */
- RBIMPL_ATTR_DEPRECATED(("rb_io_mode"))
int mode;
/** child's pid (for pipes) */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
rb_pid_t pid;
/** number of lines read */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
int lineno;
/** pathname for file */
- RBIMPL_ATTR_DEPRECATED(("rb_io_path"))
VALUE pathv;
/** finalize proc */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
- void (*finalize)(struct rb_io*,int);
+ void (*finalize)(struct rb_io_t*,int);
/** Write buffer. */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
rb_io_buffer_t wbuf;
/**
* (Byte) read buffer. Note also that there is a field called
* ::rb_io_t::cbuf, which also concerns read IO.
*/
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
rb_io_buffer_t rbuf;
/**
@@ -189,25 +175,20 @@ struct rb_io {
*
* @see rb_io_set_write_io()
*/
- RBIMPL_ATTR_DEPRECATED(("rb_io_get_write_io"))
VALUE tied_io_for_writing;
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
- struct rb_io_encoding encs; /**< Decomposed encoding flags. */
+ struct rb_io_enc_t encs; /**< Decomposed encoding flags. */
/** Encoding converter used when reading from this IO. */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
rb_econv_t *readconv;
/**
* rb_io_ungetc() destination. This buffer is read before checking
* ::rb_io_t::rbuf
*/
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
rb_io_buffer_t cbuf;
/** Encoding converter used when writing to this IO. */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
rb_econv_t *writeconv;
/**
@@ -216,25 +197,21 @@ struct rb_io {
* conversion from encoding X to encoding Y does not exist, Ruby finds an
* encoding Z that bridges the two, so that X to Z to Y conversion happens.
*/
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
VALUE writeconv_asciicompat;
/** Whether ::rb_io_t::writeconv is already set up. */
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
int writeconv_initialized;
/**
* Value of ::rb_io_t::rb_io_enc_t::ecflags stored right before
* initialising ::rb_io_t::writeconv.
*/
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
int writeconv_pre_ecflags;
/**
* Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising
* ::rb_io_t::writeconv.
*/
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
VALUE writeconv_pre_ecopts;
/**
@@ -244,21 +221,25 @@ struct rb_io {
*
* This of course doesn't help inter-process IO interleaves, though.
*/
- RBIMPL_ATTR_DEPRECATED(("with no replacement"))
VALUE write_lock;
/**
* The timeout associated with this IO when performing blocking operations.
*/
- RBIMPL_ATTR_DEPRECATED(("rb_io_timeout/rb_io_set_timeout"))
VALUE timeout;
-};
-#endif
-
-typedef struct rb_io rb_io_t;
+} rb_io_t;
/** @alias{rb_io_enc_t} */
-typedef struct rb_io_encoding rb_io_enc_t;
+typedef struct rb_io_enc_t rb_io_enc_t;
+
+/**
+ * @private
+ *
+ * @deprecated This macro once was a thing in the old days, but makes no sense
+ * any longer today. Exists here for backwards compatibility
+ * only. You can safely forget about it.
+ */
+#define HAVE_RB_IO_T 1
/**
* @name Possible flags for ::rb_io_t::mode
@@ -349,16 +330,7 @@ typedef struct rb_io_encoding rb_io_enc_t;
* Setting this one and #FMODE_BINMODE at the same time is a contradiction.
*/
#define FMODE_TEXTMODE 0x00001000
-/**
- * This flag means that an IO object is wrapping an "external" file descriptor,
- * which is owned by something outside the Ruby interpreter (usually a C extension).
- * Ruby will not close this file when the IO object is garbage collected.
- * If this flag is set, then IO#autoclose? is false, and vice-versa.
- *
- * This flag was previously called FMODE_PREP internally.
- */
-#define FMODE_EXTERNAL 0x00010000
-
+/* #define FMODE_PREP 0x00010000 */
/* #define FMODE_SIGNAL_ON_EPIPE 0x00020000 */
/**
@@ -373,18 +345,6 @@ typedef struct rb_io_encoding rb_io_enc_t;
/** @} */
/**
- * Allocate a new IO object, with the given file descriptor.
- */
-VALUE rb_io_open_descriptor(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, struct rb_io_encoding *encoding);
-
-/**
- * Returns whether or not the underlying IO is closed.
- *
- * @return Whether the underlying IO is closed.
- */
-VALUE rb_io_closed_p(VALUE io);
-
-/**
* Queries the underlying IO pointer.
*
* @param[in] obj An IO object.
@@ -454,14 +414,14 @@ rb_io_t *rb_io_make_open_file(VALUE obj);
* like this:
*
* ```CXX
- * typedef struct rb_io {
+ * typedef struct rb_io_t {
* FILE *f; // stdio ptr for read/write
* FILE *f2; // additional ptr for rw pipes
* int mode; // mode flags
* int pid; // child's pid (for pipes)
* int lineno; // number of lines read
* char *path; // pathname for file
- * void (*finalize) _((struct rb_io*,int)); // finalize proc
+ * void (*finalize) _((struct rb_io_t*,int)); // finalize proc
* } rb_io_t;
*```
*
@@ -743,12 +703,6 @@ VALUE rb_io_set_write_io(VALUE io, VALUE w);
void rb_io_set_nonblock(rb_io_t *fptr);
/**
- * Returns the path for the given IO.
- *
- */
-VALUE rb_io_path(VALUE io);
-
-/**
* Returns an integer representing the numeric file descriptor for
* <em>io</em>.
*
@@ -758,12 +712,6 @@ VALUE rb_io_path(VALUE io);
int rb_io_descriptor(VALUE io);
/**
- * Get the mode of the IO.
- *
- */
-int rb_io_mode(VALUE io);
-
-/**
* This function breaks down the option hash that `IO#initialize` takes into
* components. This is an implementation detail of rb_io_extract_modeenc()
* today. People prefer that API instead.
diff --git a/include/ruby/io/buffer.h b/include/ruby/io/buffer.h
index e4d98bf051..e4b855d8e7 100644
--- a/include/ruby/io/buffer.h
+++ b/include/ruby/io/buffer.h
@@ -23,18 +23,10 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
#define RUBY_IO_BUFFER_VERSION 2
-// The `IO::Buffer` class.
RUBY_EXTERN VALUE rb_cIOBuffer;
-
-// The operating system page size.
RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE;
-
-// The default buffer size, usually a (small) multiple of the page size.
-// Can be overridden by the RUBY_IO_BUFFER_DEFAULT_SIZE environment variable.
RUBY_EXTERN size_t RUBY_IO_BUFFER_DEFAULT_SIZE;
-// Represents the internal state of the buffer.
-// More than one flag can be set at a time.
enum rb_io_buffer_flags {
// The memory in the buffer is owned by someone else.
// More specifically, it means that someone else owns the buffer and we shouldn't try to resize it.
@@ -57,15 +49,10 @@ enum rb_io_buffer_flags {
RB_IO_BUFFER_PRIVATE = 64,
// The buffer is read-only and cannot be modified.
- RB_IO_BUFFER_READONLY = 128,
-
- // The buffer is backed by a file.
- RB_IO_BUFFER_FILE = 256,
+ RB_IO_BUFFER_READONLY = 128
};
-// Represents the endian of the data types.
enum rb_io_buffer_endian {
- // The least significant units are put first.
RB_IO_BUFFER_LITTLE_ENDIAN = 4,
RB_IO_BUFFER_BIG_ENDIAN = 8,
@@ -84,14 +71,9 @@ VALUE rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer
VALUE rb_io_buffer_lock(VALUE self);
VALUE rb_io_buffer_unlock(VALUE self);
int rb_io_buffer_try_unlock(VALUE self);
-
VALUE rb_io_buffer_free(VALUE self);
-VALUE rb_io_buffer_free_locked(VALUE self);
-// Access the internal buffer and flags. Validates the pointers.
-// The points may not remain valid if the source buffer is manipulated.
-// Consider using rb_io_buffer_lock if needed.
-enum rb_io_buffer_flags rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size);
+int rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size);
void rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size);
void rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size);
diff --git a/include/ruby/memory_view.h b/include/ruby/memory_view.h
index 42309d5afc..1ddca2d46f 100644
--- a/include/ruby/memory_view.h
+++ b/include/ruby/memory_view.h
@@ -47,10 +47,10 @@ typedef struct {
char format;
/** :FIXME: what is a "native" size is unclear. */
- bool native_size_p;
+ unsigned native_size_p: 1;
/** Endian of the component */
- bool little_endian_p;
+ unsigned little_endian_p: 1;
/** The component's offset. */
size_t offset;
diff --git a/include/ruby/onigmo.h b/include/ruby/onigmo.h
index d233336316..8d7c601703 100644
--- a/include/ruby/onigmo.h
+++ b/include/ruby/onigmo.h
@@ -744,6 +744,8 @@ typedef struct {
typedef struct {
int lower;
int upper;
+ long base_num;
+ long inner_num;
} OnigRepeatRange;
typedef void (*OnigWarnFunc)(const char* s);
@@ -844,8 +846,6 @@ void onig_free(OnigRegex);
ONIG_EXTERN
void onig_free_body(OnigRegex);
ONIG_EXTERN
-int onig_reg_copy(OnigRegex* reg, OnigRegex orig_reg);
-ONIG_EXTERN
OnigPosition onig_scan(OnigRegex reg, const OnigUChar* str, const OnigUChar* end, OnigRegion* region, OnigOptionType option, int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*), void* callback_arg);
ONIG_EXTERN
OnigPosition onig_search(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
diff --git a/include/ruby/random.h b/include/ruby/random.h
index f3df0d96fb..39bdb6f3e3 100644
--- a/include/ruby/random.h
+++ b/include/ruby/random.h
@@ -11,7 +11,7 @@
*
* This is a set of APIs to roll your own subclass of ::rb_cRandom. An
* illustrative example of such PRNG can be found at
- * `ext/-test-/random/loop.c`.
+ * `ext/-test-/ramdom/loop.c`.
*/
#include "ruby/ruby.h"
diff --git a/include/ruby/re.h b/include/ruby/re.h
index f86d6f26cf..3892d6e7f2 100644
--- a/include/ruby/re.h
+++ b/include/ruby/re.h
@@ -18,7 +18,6 @@
#include <stdio.h>
-#include "ruby/onigmo.h"
#include "ruby/regex.h"
#include "ruby/internal/core/rmatch.h"
#include "ruby/internal/dllexport.h"
@@ -127,30 +126,6 @@ VALUE rb_reg_quote(VALUE str);
regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
/**
- * Runs a regular expression match using function `match`. Performs preparation,
- * error handling, and memory cleanup.
- *
- * @param[in] re Target regular expression.
- * @param[in] str What `re` is about to run on.
- * @param[in] match The function to run to match `str` against `re`.
- * @param[in] args Pointer to arguments to pass into `match`.
- * @param[out] regs Registers on a successful match.
- * @exception rb_eArgError `re` does not fit for `str`.
- * @exception rb_eEncCompatError `re` and `str` are incompatible.
- * @exception rb_eRegexpError `re` is malformed.
- * @return Match position on a successful match, `ONIG_MISMATCH` otherwise.
- *
- * @internal
- *
- * The type `regex_t *` is defined in `<ruby/onigmo.h>`, _and_
- * _conflicts_ with POSIX's `<regex.h>`. We can no longer save the situation
- * at this point. Just don't mix the two.
- */
-OnigPosition rb_reg_onig_match(VALUE re, VALUE str,
- OnigPosition (*match)(regex_t *reg, VALUE str, struct re_registers *regs, void *args),
- void *args, struct re_registers *regs);
-
-/**
* Duplicates a match data. This is roughly the same as `onig_region_copy()`,
* except it tries to GC when there is not enough memory.
*
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 035f02c70b..444940ca3a 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -43,6 +43,7 @@
#include "ruby/internal/method.h"
#include "ruby/internal/module.h"
#include "ruby/internal/newobj.h"
+#include "ruby/internal/rgengc.h"
#include "ruby/internal/scan_args.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/symbol.h"
@@ -97,10 +98,8 @@ VALUE rb_get_path(VALUE obj);
VALUE rb_get_path_no_checksafe(VALUE);
/**
- * This macro actually does the same thing as #FilePathValue now. The "String"
- * part indicates that this is for when a string is treated like a pathname,
- * rather than the actual pathname on the file systems. For examples:
- * `Dir.fnmatch?`, `File.join`, `File.basename`, etc.
+ * @deprecated This macro is an alias of #FilePathValue now. The part that did
+ * "String" was deleted. It remains here because of no harm.
*/
#define FilePathStringValue(v) ((v) = rb_get_path(v))
@@ -272,124 +271,6 @@ RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 0)
*/
int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
-#include <errno.h>
-
-/**
- * @name Errno handling routines for userland threads
- * @note POSIX chapter 2 section 3 states that for each thread of a process,
- * the value of `errno` shall not be affected by function calls or
- * assignments to `errno` by other threads.
- *
- * Soooo this `#define errno` below seems like a noob mistake at first sight.
- * If you look at its actual implementation, the functions are just adding one
- * level of indirection. It doesn't make any sense sorry? But yes! @ko1 told
- * @shyouhei that this is inevitable.
- *
- * The ultimate reason is because Ruby now has N:M threads implemented.
- * Threads of that sort change their context in user land. A function can be
- * "transferred" between threads in middle of their executions. Let us for
- * instance consider:
- *
- * ```cxx
- * void foo()
- * {
- * auto i = errno;
- * close(0);
- * errno = i;
- * }
- * ```
- *
- * This function (if ran under our Ractor) could change its running thread at
- * the `close` function. But the two `errno` invocations are different! Look
- * how the source code above is compiled by clang 17 with `-O3` flag @ Linux:
- *
- * ```
- * foo(int): # @foo(int)
- * push rbp
- * push r14
- * push rbx
- * mov ebx, edi
- * call __errno_location@PLT
- * mov r14, rax
- * mov ebp, dword ptr [rax]
- * mov edi, ebx
- * call close@PLT
- * mov dword ptr [r14], ebp
- * pop rbx
- * pop r14
- * pop rbp
- * ret
- * ```
- *
- * Notice how `__errno_location@PLT` is `call`-ed only once. The compiler
- * assumes that the location of `errno` does not change during a function call.
- * Sadly this is no longer true for us. The `close@PLT` now changes threads,
- * which should also change where `errno` is stored.
- *
- * With the `#define errno` below the compilation result changes to this:
- *
- * ```
- * foo(int): # @foo(int)
- * push rbp
- * push rbx
- * push rax
- * mov ebx, edi
- * call rb_errno_ptr()@PLT
- * mov ebp, dword ptr [rax]
- * mov edi, ebx
- * call close@PLT
- * call rb_errno_ptr()@PLT
- * mov dword ptr [rax], ebp
- * add rsp, 8
- * pop rbx
- * pop rbp
- * ret
- * ```
- *
- * Which fixes the problem.
- */
-
-/**
- * Identical to system `errno`.
- *
- * @return The last set `errno` number.
- */
-int rb_errno(void);
-
-/**
- * Set the errno.
- *
- * @param err New `errno`.
- * @post `errno` is now set to `err`.
- */
-void rb_errno_set(int err);
-
-/**
- * The location of `errno`
- *
- * @return The (thread-specific) location of `errno`.
- */
-int *rb_errno_ptr(void);
-
-/**
- * Not sure if it is necessary for extension libraries but this is where the
- * "bare" errno is located.
- *
- * @return The location of `errno`.
- */
-static inline int *
-rb_orig_errno_ptr(void)
-{
- return &errno;
-}
-
-#define rb_orig_errno errno /**< System-provided original `errno`. */
-#undef errno
-#define errno (*rb_errno_ptr()) /**< Ractor-aware version of `errno`. */
-
-/** @} */
-
-
/** @cond INTERNAL_MACRO */
#if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
# /* Skip it; clang -pedantic doesn't like the following */
diff --git a/include/ruby/st.h b/include/ruby/st.h
index ba69c066c9..f35ab43603 100644
--- a/include/ruby/st.h
+++ b/include/ruby/st.h
@@ -104,8 +104,6 @@ st_table *rb_st_init_table(const struct st_hash_type *);
#define st_init_table rb_st_init_table
st_table *rb_st_init_table_with_size(const struct st_hash_type *, st_index_t);
#define st_init_table_with_size rb_st_init_table_with_size
-st_table *rb_st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type, st_index_t size);
-#define st_init_existing_table_with_size rb_st_init_existing_table_with_size
st_table *rb_st_init_numtable(void);
#define st_init_numtable rb_st_init_numtable
st_table *rb_st_init_numtable_with_size(st_index_t);
@@ -162,8 +160,6 @@ void rb_st_cleanup_safe(st_table *, st_data_t);
#define st_cleanup_safe rb_st_cleanup_safe
void rb_st_clear(st_table *);
#define st_clear rb_st_clear
-st_table *rb_st_replace(st_table *new_tab, st_table *old_tab);
-#define st_replace rb_st_replace
st_table *rb_st_copy(st_table *);
#define st_copy rb_st_copy
CONSTFUNC(int rb_st_numcmp(st_data_t, st_data_t));
diff --git a/include/ruby/thread.h b/include/ruby/thread.h
index f01d276a29..0b5b1ca0f3 100644
--- a/include/ruby/thread.h
+++ b/include/ruby/thread.h
@@ -190,46 +190,14 @@ void *rb_nogvl(void *(*func)(void *), void *data1,
*/
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_
-/**
- * Triggered when a new thread is started.
- *
- * @note The callback will be called *without* the GVL held.
- */
-#define RUBY_INTERNAL_THREAD_EVENT_STARTED 1 << 0
-
-/**
-* Triggered when a thread attempt to acquire the GVL.
-*
-* @note The callback will be called *without* the GVL held.
-*/
+#define RUBY_INTERNAL_THREAD_EVENT_STARTED 1 << 0 /** thread started */
#define RUBY_INTERNAL_THREAD_EVENT_READY 1 << 1 /** acquiring GVL */
-
-/**
- * Triggered when a thread successfully acquired the GVL.
- *
- * @note The callback will be called *with* the GVL held.
- */
#define RUBY_INTERNAL_THREAD_EVENT_RESUMED 1 << 2 /** acquired GVL */
-
-/**
- * Triggered when a thread released the GVL.
- *
- * @note The callback will be called *without* the GVL held.
- */
#define RUBY_INTERNAL_THREAD_EVENT_SUSPENDED 1 << 3 /** released GVL */
-
-/**
- * Triggered when a thread exits.
- *
- * @note The callback will be called *without* the GVL held.
- */
#define RUBY_INTERNAL_THREAD_EVENT_EXITED 1 << 4 /** thread terminated */
-
#define RUBY_INTERNAL_THREAD_EVENT_MASK 0xff /** All Thread events */
-typedef struct rb_internal_thread_event_data {
- VALUE thread;
-} rb_internal_thread_event_data_t;
+typedef void rb_internal_thread_event_data_t; // for future extension.
typedef void (*rb_internal_thread_event_callback)(rb_event_flag_t event,
const rb_internal_thread_event_data_t *event_data,
@@ -243,12 +211,7 @@ typedef struct rb_internal_thread_event_hook rb_internal_thread_event_hook_t;
* @param[in] events A set of events that `func` should run.
* @param[in] data Passed as-is to `func`.
* @return An opaque pointer to the hook, to unregister it later.
- * @note This functionality is a noop on Windows and WebAssembly.
- * @note The callback will be called without the GVL held, except for the
- * RESUMED event.
- * @note Callbacks are not guaranteed to be executed on the native threads
- * that corresponds to the Ruby thread. To identify which Ruby thread
- * the event refers to, you must use `event_data->thread`.
+ * @note This functionality is a noop on Windows.
* @warning This function MUST not be called from a thread event callback.
*/
rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook(
@@ -260,53 +223,13 @@ rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook(
* Unregister the passed hook.
*
* @param[in] hook. The hook to unregister.
- * @return Whether the hook was found and unregistered.
- * @note This functionality is a noop on Windows and WebAssembly.
+ * @return Wether the hook was found and unregistered.
+ * @note This functionality is a noop on Windows.
* @warning This function MUST not be called from a thread event callback.
*/
bool rb_internal_thread_remove_event_hook(
rb_internal_thread_event_hook_t * hook);
-
-typedef int rb_internal_thread_specific_key_t;
-#define RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX 8
-/**
- * Create a key to store thread specific data.
- *
- * These APIs are designed for tools using
- * rb_internal_thread_event_hook APIs.
- *
- * Note that only `RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX` keys
- * can be created. raises `ThreadError` if exceeded.
- *
- * Usage:
- * // at initialize time:
- * int tool_key; // gvar
- * Init_tool() {
- * tool_key = rb_internal_thread_specific_key_create();
- * }
- *
- * // at any timing:
- * rb_internal_thread_specific_set(thread, tool_key, per_thread_data);
- * ...
- * per_thread_data = rb_internal_thread_specific_get(thread, tool_key);
- */
-rb_internal_thread_specific_key_t rb_internal_thread_specific_key_create(void);
-
-/**
- * Get thread and tool specific data.
- *
- * This function is async signal safe and thread safe.
- */
-void *rb_internal_thread_specific_get(VALUE thread_val, rb_internal_thread_specific_key_t key);
-
-/**
- * Set thread and tool specific data.
- *
- * This function is async signal safe and thread safe.
- */
-void rb_internal_thread_specific_set(VALUE thread_val, rb_internal_thread_specific_key_t key, void *data);
-
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_THREAD_H */
diff --git a/include/ruby/thread_native.h b/include/ruby/thread_native.h
index 8217a67514..c23b15e133 100644
--- a/include/ruby/thread_native.h
+++ b/include/ruby/thread_native.h
@@ -28,11 +28,6 @@ typedef union rb_thread_lock_union {
CRITICAL_SECTION crit;
} rb_nativethread_lock_t;
-struct rb_thread_cond_struct {
- struct cond_event_entry *next;
- struct cond_event_entry *prev;
-};
-
typedef struct rb_thread_cond_struct rb_nativethread_cond_t;
#elif defined(HAVE_PTHREAD_H)
diff --git a/include/ruby/util.h b/include/ruby/util.h
index 12e69c4b80..e8727a3200 100644
--- a/include/ruby/util.h
+++ b/include/ruby/util.h
@@ -33,20 +33,9 @@
RBIMPL_SYMBOL_EXPORT_BEGIN()
-/** an approximation of ceil(n * log10(2)), up to 1,048,576 (1<<20)
- * without overflow within 32-bit calculation
- */
+/** an approximation of ceil(n * log10(2)), up to 65536 at least */
#define DECIMAL_SIZE_OF_BITS(n) (((n) * 3010 + 9998) / 9999)
-/** an approximation of decimal representation size for n-bytes */
-#define DECIMAL_SIZE_OF_BYTES(n) DECIMAL_SIZE_OF_BITS((n) * CHAR_BIT)
-
-/**
- * An approximation of decimal representation size. `expr` may be a
- * type name
- */
-#define DECIMAL_SIZE_OF(expr) DECIMAL_SIZE_OF_BYTES(sizeof(expr))
-
/**
* Character to number mapping like `'a'` -> `10`, `'b'` -> `11` etc. For
* punctuation etc., the value is -1. "36" terminology comes from the fact
diff --git a/include/ruby/version.h b/include/ruby/version.h
index 08c0aadb07..18b3abc8d7 100644
--- a/include/ruby/version.h
+++ b/include/ruby/version.h
@@ -67,7 +67,7 @@
* Minor version. As of writing this version changes annually. Greater
* version doesn't mean "better"; they just mean years passed.
*/
-#define RUBY_API_VERSION_MINOR 3
+#define RUBY_API_VERSION_MINOR 2
/**
* Teeny version. This digit is kind of reserved these days. Kept 0 for the
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index dfb56f4182..18de3a17d8 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -125,8 +125,15 @@ typedef unsigned int uintptr_t;
#define O_SHARE_DELETE 0x20000000 /* for rb_w32_open(), rb_w32_wopen() */
typedef int clockid_t;
+#if defined(__MINGW32__)
+#undef CLOCK_PROCESS_CPUTIME_ID
+#undef CLOCK_THREAD_CPUTIME_ID
+#undef CLOCK_REALTIME_COARSE
+#endif
+#if defined(HAVE_CLOCK_GETTIME) && !defined(CLOCK_REALTIME)
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
+#endif
#undef utime
#undef lseek
@@ -147,10 +154,8 @@ typedef int clockid_t;
#define open rb_w32_uopen
#define close(h) rb_w32_close(h)
#define fclose(f) rb_w32_fclose(f)
-#define read(f, b, s) rb_w32_read(f, b, s)
-#define write(f, b, s) rb_w32_write(f, b, s)
-#define pread(f, b, s, o) rb_w32_pread(f, b, s, o)
-#define pwrite(f, b, s, o) rb_w32_pwrite(f, b, s, o)
+#define read(f, b, s) rb_w32_read(f, b, s)
+#define write(f, b, s) rb_w32_write(f, b, s)
#define getpid() rb_w32_getpid()
#undef HAVE_GETPPID
#define HAVE_GETPPID 1
@@ -718,8 +723,6 @@ int rb_w32_fclose(FILE*);
int rb_w32_pipe(int[2]);
ssize_t rb_w32_read(int, void *, size_t);
ssize_t rb_w32_write(int, const void *, size_t);
-ssize_t rb_w32_pread(int, void *, size_t, rb_off_t offset);
-ssize_t rb_w32_pwrite(int, const void *, size_t, rb_off_t offset);
rb_off_t rb_w32_lseek(int, rb_off_t, int);
int rb_w32_uutime(const char *, const struct utimbuf *);
int rb_w32_uutimes(const char *, const struct timeval *);
diff --git a/inits.c b/inits.c
index 9ed104f369..e809b56cc9 100644
--- a/inits.c
+++ b/inits.c
@@ -22,6 +22,11 @@ rb_call_inits(void)
{
CALL(default_shapes);
CALL(Thread_Mutex);
+#if USE_TRANSIENT_HEAP
+ CALL(TransientHeap);
+#endif
+ CALL(vm_postponed_job);
+ CALL(Method);
CALL(RandomSeedCore);
CALL(encodings);
CALL(sym);
@@ -51,18 +56,17 @@ rb_call_inits(void)
CALL(Dir);
CALL(Time);
CALL(Random);
+ CALL(signal);
CALL(load);
CALL(Proc);
CALL(Binding);
CALL(Math);
CALL(GC);
- CALL(WeakMap);
CALL(Enumerator);
CALL(Ractor);
CALL(VM);
CALL(ISeq);
CALL(Thread);
- CALL(signal);
CALL(Fiber_Scheduler);
CALL(process);
CALL(Cont);
@@ -75,7 +79,6 @@ rb_call_inits(void)
CALL(ast);
CALL(gc_stress);
CALL(shape);
- CALL(Prism);
// enable builtin loading
CALL(builtin);
@@ -102,9 +105,9 @@ rb_call_builtin_inits(void)
BUILTIN(yjit);
BUILTIN(nilclass);
BUILTIN(marshal);
-#if USE_RJIT
- BUILTIN(rjit_c);
- BUILTIN(rjit);
+#if USE_MJIT
+ BUILTIN(mjit);
+ BUILTIN(mjit_c);
#endif
Init_builtin_prelude();
}
diff --git a/insns.def b/insns.def
index 5f6cb314ff..9f5ee7095a 100644
--- a/insns.def
+++ b/insns.def
@@ -260,7 +260,20 @@ opt_getconstant_path
(VALUE val)
// attr bool leaf = false; /* may autoload or raise */
{
- val = rb_vm_opt_getconstant_path(ec, GET_CFP(), ic);
+ const ID *segments = ic->segments;
+ struct iseq_inline_constant_cache_entry *ice = ic->entry;
+ if (ice && vm_ic_hit_p(ice, GET_EP())) {
+ val = ice->value;
+
+ VM_ASSERT(val == vm_get_ev_const_chain(ec, segments));
+ } else {
+ ruby_vm_constant_cache_misses++;
+ val = vm_get_ev_const_chain(ec, segments);
+ vm_ic_track_const_chain(GET_CFP(), ic, segments);
+ // Because leaf=false, we need to undo the PC increment to get the address to this instruction
+ // INSN_ATTR(width) == 2
+ vm_ic_update(GET_ISEQ(), ic, val, GET_EP(), GET_PC() - 2);
+ }
}
/* Get constant variable id. If klass is Qnil and allow_nil is Qtrue, constants
@@ -498,11 +511,10 @@ expandarray
(rb_num_t num, rb_num_t flag)
(..., VALUE ary)
(...)
-// attr bool handles_sp = true;
// attr bool leaf = false; /* has rb_check_array_type() */
// attr rb_snum_t sp_inc = (rb_snum_t)num - 1 + (flag & 1 ? 1 : 0);
{
- vm_expandarray(GET_CFP(), ary, num, (int)flag);
+ vm_expandarray(GET_SP(), ary, num, (int)flag);
}
/* concat two arrays */
@@ -527,17 +539,6 @@ splatarray
obj = vm_splat_array(flag, ary);
}
-/* call to_hash on hash to keyword splat before converting block */
-DEFINE_INSN
-splatkw
-()
-(VALUE hash, VALUE block)
-(VALUE obj, VALUE block)
-// attr bool leaf = false; /* has rb_to_hash_type() */
-{
- obj = rb_to_hash_type(hash);
-}
-
/* put new Hash from n elements. n must be an even number. */
DEFINE_INSN
newhash
@@ -700,20 +701,6 @@ defined
}
}
-/* defined?(@foo) */
-DEFINE_INSN
-definedivar
-(ID id, IVC ic, VALUE pushval)
-()
-(VALUE val)
-// attr bool leaf = false;
-{
- val = Qnil;
- if (vm_getivar(GET_SELF(), id, GET_ISEQ(), ic, NULL, FALSE, Qundef) != Qundef) {
- val = pushval;
- }
-}
-
/* check `target' matches `pattern'.
`flag & VM_CHECKMATCH_TYPE_MASK' describe how to check pattern.
VM_CHECKMATCH_TYPE_WHEN: ignore target and check pattern is truthy.
@@ -812,7 +799,6 @@ send
{
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false);
val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
- JIT_EXEC(ec, val);
if (val == Qundef) {
RESTORE_REGS();
@@ -832,7 +818,6 @@ opt_send_without_block
{
VALUE bh = VM_BLOCK_HANDLER_NONE;
val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
- JIT_EXEC(ec, val);
if (val == Qundef) {
RESTORE_REGS();
@@ -898,8 +883,8 @@ opt_str_uminus
}
DEFINE_INSN
-opt_newarray_send
-(rb_num_t num, ID method)
+opt_newarray_max
+(rb_num_t num)
(...)
(VALUE val)
/* This instruction typically has no funcalls. But it compares array
@@ -908,21 +893,20 @@ opt_newarray_send
* cannot but mark it being not leaf. */
// attr bool leaf = false; /* has rb_funcall() */
// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
-// attr rb_snum_t comptime_sp_inc = 1 - (rb_snum_t)num;
-{
- switch(method) {
- case idHash:
- val = vm_opt_newarray_hash(ec, num, STACK_ADDR_FROM_TOP(num));
- break;
- case idMin:
- val = vm_opt_newarray_min(ec, num, STACK_ADDR_FROM_TOP(num));
- break;
- case idMax:
- val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num));
- break;
- default:
- rb_bug("unreachable");
- }
+{
+ val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num));
+}
+
+DEFINE_INSN
+opt_newarray_min
+(rb_num_t num)
+(...)
+(VALUE val)
+/* Same discussion as opt_newarray_max. */
+// attr bool leaf = false; /* has rb_funcall() */
+// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
+{
+ val = vm_opt_newarray_min(ec, num, STACK_ADDR_FROM_TOP(num));
}
/* super(args) # args.size => num */
@@ -936,7 +920,6 @@ invokesuper
{
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true);
val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super);
- JIT_EXEC(ec, val);
if (val == Qundef) {
RESTORE_REGS();
@@ -956,7 +939,6 @@ invokeblock
{
VALUE bh = VM_BLOCK_HANDLER_NONE;
val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock);
- JIT_EXEC(ec, val);
if (val == Qundef) {
RESTORE_REGS();
@@ -1363,8 +1345,10 @@ opt_aset_with
val = tmp;
}
else {
+#ifndef MJIT_HEADER
TOPN(0) = rb_str_resurrect(key);
PUSH(val);
+#endif
CALL_SIMPLE_METHOD();
}
}
@@ -1381,7 +1365,9 @@ opt_aref_with
val = vm_opt_aref_with(recv, key);
if (val == Qundef) {
+#ifndef MJIT_HEADER
PUSH(rb_str_resurrect(key));
+#endif
CALL_SIMPLE_METHOD();
}
}
@@ -1471,6 +1457,27 @@ opt_regexpmatch2
}
}
+/* call native compiled method */
+DEFINE_INSN_IF(SUPPORT_CALL_C_FUNCTION)
+opt_call_c_function
+(rb_insn_func_t funcptr)
+()
+()
+// attr bool leaf = false; /* anything can happen inside */
+// attr bool handles_sp = true;
+{
+ reg_cfp = (funcptr)(ec, reg_cfp);
+
+ if (reg_cfp == 0) {
+ VALUE err = ec->errinfo;
+ ec->errinfo = Qnil;
+ THROW_EXCEPTION(err);
+ }
+
+ RESTORE_REGS();
+ NEXT_INSN();
+}
+
/* call specific function with args */
DEFINE_INSN
invokebuiltin
diff --git a/internal.h b/internal.h
index c66e057f60..b63af50616 100644
--- a/internal.h
+++ b/internal.h
@@ -43,6 +43,7 @@
/* internal/gc.h */
#undef NEWOBJ_OF
#undef RB_NEWOBJ_OF
+#undef RB_OBJ_WRITE
/* internal/hash.h */
#undef RHASH_IFNONE
diff --git a/internal/array.h b/internal/array.h
index 39f6fcbea6..a0d16dec3f 100644
--- a/internal/array.h
+++ b/internal/array.h
@@ -23,7 +23,6 @@
#define RARRAY_PTR_IN_USE_FLAG FL_USER14
/* array.c */
-VALUE rb_ary_hash_values(long len, const VALUE *elements);
VALUE rb_ary_last(int, const VALUE *, VALUE);
void rb_ary_set_len(VALUE, long);
void rb_ary_delete_same(VALUE, VALUE);
@@ -40,7 +39,10 @@ VALUE rb_ary_diff(VALUE ary1, VALUE ary2);
static inline VALUE rb_ary_entry_internal(VALUE ary, long offset);
static inline bool ARY_PTR_USING_P(VALUE ary);
+static inline void RARY_TRANSIENT_SET(VALUE ary);
+static inline void RARY_TRANSIENT_UNSET(VALUE ary);
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
VALUE rb_check_to_array(VALUE ary);
VALUE rb_ary_behead(VALUE, long);
@@ -48,13 +50,14 @@ VALUE rb_ary_aref1(VALUE ary, VALUE i);
struct rb_execution_context_struct;
VALUE rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts);
+MJIT_SYMBOL_EXPORT_END
// YJIT needs this function to never allocate and never raise
static inline VALUE
rb_ary_entry_internal(VALUE ary, long offset)
{
long len = RARRAY_LEN(ary);
- const VALUE *ptr = RARRAY_CONST_PTR(ary);
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
if (len == 0) return Qnil;
if (offset < 0) {
offset += len;
@@ -116,6 +119,22 @@ ARY_SHARED_ROOT_REFCNT(VALUE ary)
return RARRAY(ary)->as.heap.aux.capa;
}
+static inline void
+RARY_TRANSIENT_SET(VALUE ary)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+RARY_TRANSIENT_UNSET(VALUE ary)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(ary, RARRAY_TRANSIENT_FLAG);
+#endif
+}
+
#undef rb_ary_new_from_args
#if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
# /* Skip it; clang -pedantic doesn't like the following */
@@ -136,16 +155,9 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline VALUE
RARRAY_AREF(VALUE ary, long i)
{
- VALUE val;
RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
- RBIMPL_WARNING_PUSH();
-#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 13
- RBIMPL_WARNING_IGNORED(-Warray-bounds);
-#endif
- val = RARRAY_CONST_PTR(ary)[i];
- RBIMPL_WARNING_POP();
- return val;
+ return RARRAY_CONST_PTR_TRANSIENT(ary)[i];
}
#endif /* INTERNAL_ARRAY_H */
diff --git a/internal/basic_operators.h b/internal/basic_operators.h
index a59403631e..2cd9f50073 100644
--- a/internal/basic_operators.h
+++ b/internal/basic_operators.h
@@ -31,7 +31,6 @@ enum ruby_basic_operators {
BOP_UMINUS,
BOP_MAX,
BOP_MIN,
- BOP_HASH,
BOP_CALL,
BOP_AND,
BOP_OR,
@@ -41,7 +40,9 @@ enum ruby_basic_operators {
BOP_LAST_
};
+MJIT_SYMBOL_EXPORT_BEGIN
RUBY_EXTERN short ruby_vm_redefined_flag[BOP_LAST_];
+MJIT_SYMBOL_EXPORT_END
/* optimize insn */
#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
diff --git a/internal/bignum.h b/internal/bignum.h
index db8d3aee83..5cd35ede8a 100644
--- a/internal/bignum.h
+++ b/internal/bignum.h
@@ -163,9 +163,11 @@ VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
#if defined(HAVE_INT128_T)
VALUE rb_int128t2big(int128_t n);
#endif
+MJIT_SYMBOL_EXPORT_END
/* sign: positive:1, negative:0 */
static inline bool
diff --git a/internal/bits.h b/internal/bits.h
index 1fe98fa430..2602ff7a31 100644
--- a/internal/bits.h
+++ b/internal/bits.h
@@ -34,7 +34,8 @@
# include <stdlib.h> /* for _byteswap_uint64 */
#endif
-#if defined(HAVE_X86INTRIN_H)
+#if defined(HAVE_X86INTRIN_H) && ! defined(MJIT_HEADER)
+# /* Rule out MJIT_HEADER, which does not interface well with <immintrin.h> */
# include <x86intrin.h> /* for _lzcnt_u64 */
#elif MSC_VERSION_SINCE(1310)
# include <intrin.h> /* for the following intrinsics */
@@ -118,16 +119,12 @@
MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
#endif
-#if defined(MUL_OVERFLOW_P) && defined(USE___BUILTIN_MUL_OVERFLOW_LONG_LONG)
-# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
-#else
-# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
-#endif
-
#ifdef MUL_OVERFLOW_P
+# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b)
#else
+# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
#endif
@@ -238,7 +235,7 @@ nlz_int32(uint32_t x)
* safety. */
return (unsigned int)__lzcnt(x);
-#elif defined(__x86_64__) && defined(__LZCNT__)
+#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
return (unsigned int)_lzcnt_u32(x);
#elif MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
@@ -267,7 +264,7 @@ nlz_int64(uint64_t x)
#if defined(_MSC_VER) && defined(__AVX2__)
return (unsigned int)__lzcnt64(x);
-#elif defined(__x86_64__) && defined(__LZCNT__)
+#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
return (unsigned int)_lzcnt_u64(x);
#elif defined(_WIN64) && MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
@@ -398,9 +395,9 @@ rb_popcount32(uint32_t x)
#else
x = (x & 0x55555555) + (x >> 1 & 0x55555555);
x = (x & 0x33333333) + (x >> 2 & 0x33333333);
- x = (x & 0x07070707) + (x >> 4 & 0x07070707);
- x = (x & 0x000f000f) + (x >> 8 & 0x000f000f);
- x = (x & 0x0000001f) + (x >>16 & 0x0000001f);
+ x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
+ x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
+ x = (x & 0x0000003f) + (x >>16 & 0x0000003f);
return (unsigned int)x;
#endif
@@ -428,9 +425,9 @@ rb_popcount64(uint64_t x)
x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
- x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f);
- x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f);
- x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f);
+ x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
+ x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
+ x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f);
return (unsigned int)x;
#endif
@@ -453,7 +450,7 @@ rb_popcount_intptr(uintptr_t x)
static inline int
ntz_int32(uint32_t x)
{
-#if defined(__x86_64__) && defined(__BMI__)
+#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
return (unsigned)_tzcnt_u32(x);
#elif MSC_VERSION_SINCE(1400)
@@ -475,7 +472,7 @@ ntz_int32(uint32_t x)
static inline int
ntz_int64(uint64_t x)
{
-#if defined(__x86_64__) && defined(__BMI__)
+#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
return (unsigned)_tzcnt_u64(x);
#elif defined(_WIN64) && MSC_VERSION_SINCE(1400)
diff --git a/internal/class.h b/internal/class.h
index 594f1daea7..63917e867f 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -8,18 +8,15 @@
* file COPYING are met. Consult the file for details.
* @brief Internal header for Class.
*/
-#include "id.h"
#include "id_table.h" /* for struct rb_id_table */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/serial.h" /* for rb_serial_t */
-#include "internal/static_assert.h"
-#include "internal/variable.h" /* for rb_class_ivar_set */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/intern.h" /* for rb_alloc_func_t */
#include "ruby/ruby.h" /* for struct RBasic */
#include "shape.h"
#include "ruby_assert.h"
#include "vm_core.h"
-#include "vm_sync.h"
#include "method.h" /* for rb_cref_t */
#ifdef RCLASS_SUPER
@@ -31,7 +28,6 @@ struct rb_subclass_entry {
struct rb_subclass_entry *next;
struct rb_subclass_entry *prev;
};
-typedef struct rb_subclass_entry rb_subclass_entry_t;
struct rb_cvar_class_tbl_entry {
uint32_t index;
@@ -44,7 +40,7 @@ struct rb_classext_struct {
VALUE *iv_ptr;
struct rb_id_table *const_tbl;
struct rb_id_table *callable_m_tbl;
- struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
+ struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
struct rb_id_table *cvc_tbl;
size_t superclass_depth;
VALUE *superclasses;
@@ -58,40 +54,32 @@ struct rb_classext_struct {
struct rb_subclass_entry *module_subclass_entry;
const VALUE origin_;
const VALUE refined_class;
- union {
- struct {
- rb_alloc_func_t allocator;
- } class;
- struct {
- VALUE attached_object;
- } singleton_class;
- } as;
+ rb_alloc_func_t allocator;
const VALUE includer;
- attr_index_t max_iv_count;
- unsigned char variation_count;
- bool permanent_classpath : 1;
- bool cloned : 1;
- VALUE classpath;
+ uint32_t max_iv_count;
+ uint32_t variation_count;
+#if !SHAPE_IN_BASIC_FLAGS
+ shape_id_t shape_id;
+#endif
};
-typedef struct rb_classext_struct rb_classext_t;
-
-STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_classext_t *)0)->variation_count) * CHAR_BIT)));
struct RClass {
struct RBasic basic;
VALUE super;
struct rb_id_table *m_tbl;
+#if SIZE_POOL_COUNT == 1
+ struct rb_classext_struct *ptr;
+#endif
};
-// Assert that classes can be embedded in size_pools[2] (which has 160B slot size)
-STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE);
-
-struct RClass_and_rb_classext_t {
- struct RClass rclass;
- rb_classext_t classext;
-};
+typedef struct rb_subclass_entry rb_subclass_entry_t;
+typedef struct rb_classext_struct rb_classext_t;
-#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
+#if RCLASS_EXT_EMBEDDED
+# define RCLASS_EXT(c) ((rb_classext_t *)((char *)(c) + sizeof(struct RClass)))
+#else
+# define RCLASS_EXT(c) (RCLASS(c)->ptr)
+#endif
#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
#define RCLASS_IVPTR(c) (RCLASS_EXT(c)->iv_ptr)
@@ -103,60 +91,16 @@ struct RClass_and_rb_classext_t {
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)
#define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry)
+#define RCLASS_ALLOCATOR(c) (RCLASS_EXT(c)->allocator)
#define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses)
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth)
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses)
-#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT(c)->as.singleton_class.attached_object)
#define RICLASS_IS_ORIGIN FL_USER0
+#define RCLASS_CLONED FL_USER1
#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
#define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
-static inline st_table *
-RCLASS_IV_HASH(VALUE obj)
-{
- RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
- RUBY_ASSERT(rb_shape_obj_too_complex(obj));
- return (st_table *)RCLASS_IVPTR(obj);
-}
-
-static inline void
-RCLASS_SET_IV_HASH(VALUE obj, const st_table *tbl)
-{
- RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
- RUBY_ASSERT(rb_shape_obj_too_complex(obj));
- RCLASS_IVPTR(obj) = (VALUE *)tbl;
-}
-
-static inline uint32_t
-RCLASS_IV_COUNT(VALUE obj)
-{
- RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
- if (rb_shape_obj_too_complex(obj)) {
- uint32_t count;
-
- // "Too complex" classes could have their IV hash mutated in
- // parallel, so lets lock around getting the hash size.
- RB_VM_LOCK_ENTER();
- {
- count = (uint32_t)rb_st_table_size(RCLASS_IV_HASH(obj));
- }
- RB_VM_LOCK_LEAVE();
-
- return count;
- }
- else {
- return rb_shape_get_shape_by_id(RCLASS_SHAPE_ID(obj))->next_iv_index;
- }
-}
-
-static inline void
-RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
-{
- RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
- RCLASS_M_TBL(klass) = table;
-}
-
/* class.c */
void rb_class_subclass_add(VALUE super, VALUE klass);
void rb_class_remove_from_super_subclasses(VALUE);
@@ -192,24 +136,10 @@ static inline VALUE RCLASS_SUPER(VALUE klass);
static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_class_inherited(VALUE, VALUE);
VALUE rb_keyword_error_new(const char *, VALUE);
-
-static inline rb_alloc_func_t
-RCLASS_ALLOCATOR(VALUE klass)
-{
- if (FL_TEST_RAW(klass, FL_SINGLETON)) {
- return 0;
- }
- return RCLASS_EXT(klass)->as.class.allocator;
-}
-
-static inline void
-RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator)
-{
- assert(!FL_TEST(klass, FL_SINGLETON));
- RCLASS_EXT(klass)->as.class.allocator = allocator;
-}
+MJIT_SYMBOL_EXPORT_END
static inline void
RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
@@ -254,24 +184,4 @@ RCLASS_SET_SUPER(VALUE klass, VALUE super)
return super;
}
-static inline void
-RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
-{
- assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
- assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
-
- RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath);
- RCLASS_EXT(klass)->permanent_classpath = permanent;
-}
-
-static inline VALUE
-RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object)
-{
- assert(BUILTIN_TYPE(klass) == T_CLASS);
- assert(FL_TEST_RAW(klass, FL_SINGLETON));
-
- RB_OBJ_WRITE(klass, &RCLASS_EXT(klass)->as.singleton_class.attached_object, attached_object);
- return attached_object;
-}
-
#endif /* INTERNAL_CLASS_H */
diff --git a/internal/cmdlineopt.h b/internal/cmdlineopt.h
index e79b993345..bf52f1214b 100644
--- a/internal/cmdlineopt.h
+++ b/internal/cmdlineopt.h
@@ -1,7 +1,7 @@
#ifndef INTERNAL_CMDLINEOPT_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_CMDLINEOPT_H
-#include "rjit.h"
+#include "mjit.h"
#include "yjit.h"
typedef struct {
@@ -23,15 +23,11 @@ typedef struct ruby_cmdline_options {
ruby_features_t features;
ruby_features_t warn;
unsigned int dump;
- long backtrace_length_limit;
-#if USE_RJIT
- struct rb_rjit_options rjit;
+#if USE_MJIT
+ struct mjit_options mjit;
#endif
- const char *crash_report;
-
- signed int sflag: 2;
- unsigned int xflag: 1;
+ int sflag, xflag;
unsigned int warning: 1;
unsigned int verbose: 1;
unsigned int do_loop: 1;
diff --git a/internal/compile.h b/internal/compile.h
index 2ece5396f6..d32c2233c9 100644
--- a/internal/compile.h
+++ b/internal/compile.h
@@ -17,7 +17,6 @@ struct rb_iseq_struct; /* in vm_core.h */
/* compile.c */
int rb_dvar_defined(ID, const struct rb_iseq_struct *);
int rb_local_defined(ID, const struct rb_iseq_struct *);
-int rb_insn_len(VALUE insn);
const char *rb_insns_name(int i);
VALUE rb_insns_name_array(void);
int rb_iseq_cdhash_cmp(VALUE val, VALUE lit);
@@ -28,7 +27,9 @@ int rb_vm_insn_addr2insn(const void *);
int rb_vm_insn_decode(const VALUE encoded);
extern bool ruby_vm_keep_script_lines;
+MJIT_SYMBOL_EXPORT_BEGIN
/* iseq.c (export) */
rb_event_flag_t rb_iseq_event_flags(const struct rb_iseq_struct *iseq, size_t pos);
+MJIT_SYMBOL_EXPORT_END
#endif /* INTERNAL_COMPILE_H */
diff --git a/internal/cont.h b/internal/cont.h
index 3c2528a02a..c3b091668a 100644
--- a/internal/cont.h
+++ b/internal/cont.h
@@ -22,9 +22,6 @@ void rb_jit_cont_init(void);
void rb_jit_cont_each_iseq(rb_iseq_callback callback, void *data);
void rb_jit_cont_finish(void);
-/* vm.c */
-void rb_free_shared_fiber_pool(void);
-
// Copy locals from the current execution to the specified fiber.
VALUE rb_fiber_inherit_storage(struct rb_execution_context_struct *ec, struct rb_fiber_struct *fiber);
diff --git a/internal/encoding.h b/internal/encoding.h
index 11ffa6d83d..a3b81bd388 100644
--- a/internal/encoding.h
+++ b/internal/encoding.h
@@ -29,7 +29,4 @@ void rb_enc_set_base(const char *name, const char *orig);
int rb_enc_set_dummy(int index);
PUREFUNC(int rb_data_is_encoding(VALUE obj));
-/* vm.c */
-void rb_free_global_enc_table(void);
-
#endif /* INTERNAL_ENCODING_H */
diff --git a/internal/error.h b/internal/error.h
index 7e41f134d7..11601858f4 100644
--- a/internal/error.h
+++ b/internal/error.h
@@ -29,37 +29,15 @@
#define rb_raise_static(e, m) \
rb_raise_cstr_i((e), rb_str_new_static((m), rb_strlen_lit(m)))
#ifdef RUBY_FUNCTION_NAME_STRING
+# define rb_sys_fail_path(path) rb_sys_fail_path_in(RUBY_FUNCTION_NAME_STRING, path)
# define rb_syserr_fail_path(err, path) rb_syserr_fail_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
# define rb_syserr_new_path(err, path) rb_syserr_new_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
#else
+# define rb_sys_fail_path(path) rb_sys_fail_str(path)
# define rb_syserr_fail_path(err, path) rb_syserr_fail_str((err), (path))
# define rb_syserr_new_path(err, path) rb_syserr_new_str((err), (path))
#endif
-#define rb_sys_fail(mesg) \
-do { \
- int errno_to_fail = errno; \
- rb_syserr_fail(errno_to_fail, (mesg)); \
-} while (0)
-
-#define rb_sys_fail_str(mesg) \
-do { \
- int errno_to_fail = errno; \
- rb_syserr_fail_str(errno_to_fail, (mesg)); \
-} while (0)
-
-#define rb_sys_fail_path(path) \
-do { \
- int errno_to_fail = errno; \
- rb_syserr_fail_path(errno_to_fail, (path)); \
-} while (0)
-
-#define rb_sys_fail_sprintf(...) \
-do { \
- int errno_to_fail = errno; \
- rb_syserr_fail_str(errno_to_fail, rb_sprintf("" __VA_ARGS__)); \
-} while (0)
-
/* error.c */
extern long rb_backtrace_length_limit;
extern VALUE rb_eEAGAIN;
@@ -169,9 +147,6 @@ VALUE rb_syserr_new_path_in(const char *func_name, int n, VALUE path);
#endif
RUBY_SYMBOL_EXPORT_END
-/* vm.c */
-void rb_free_warning(void);
-
static inline void
rb_raise_cstr_i(VALUE etype, VALUE mesg)
{
diff --git a/internal/gc.h b/internal/gc.h
index 34a6043e8a..e54a5dce9d 100644
--- a/internal/gc.h
+++ b/internal/gc.h
@@ -14,116 +14,6 @@
#include "internal/compilers.h" /* for __has_attribute */
#include "ruby/ruby.h" /* for rb_event_flag_t */
-#include "vm_core.h" /* for GET_EC() */
-
-#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__)
-#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
-#elif defined(__i386) && defined(__GNUC__)
-#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
-#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && !defined(_AIX) && !defined(__APPLE__) // Not Apple is NEEDED to unbreak ppc64 build on Darwin. Don't ask.
-#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr\t%0, %%r1" : "=r" (*(p)))
-#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && defined(_AIX)
-#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr %0,1" : "=r" (*(p)))
-#elif defined(__POWERPC__) && defined(__APPLE__) // Darwin ppc and ppc64
-#define SET_MACHINE_STACK_END(p) __asm__ volatile("mr %0, r1" : "=r" (*(p)))
-#elif defined(__aarch64__) && defined(__GNUC__)
-#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mov\t%0, sp" : "=r" (*(p)))
-#else
-NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
-#define SET_MACHINE_STACK_END(p) rb_gc_set_stack_end(p)
-#define USE_CONSERVATIVE_STACK_END
-#endif
-
-/* for GC debug */
-
-#ifndef RUBY_MARK_FREE_DEBUG
-#define RUBY_MARK_FREE_DEBUG 0
-#endif
-
-#if RUBY_MARK_FREE_DEBUG
-extern int ruby_gc_debug_indent;
-
-static inline void
-rb_gc_debug_indent(void)
-{
- ruby_debug_printf("%*s", ruby_gc_debug_indent, "");
-}
-
-static inline void
-rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
-{
- if (st == 0) {
- ruby_gc_debug_indent--;
- }
- rb_gc_debug_indent();
- ruby_debug_printf("%s: %s %s (%p)\n", mode, st ? "->" : "<-", msg, ptr);
-
- if (st) {
- ruby_gc_debug_indent++;
- }
-
- fflush(stdout);
-}
-
-#define RUBY_MARK_ENTER(msg) rb_gc_debug_body("mark", (msg), 1, ptr)
-#define RUBY_MARK_LEAVE(msg) rb_gc_debug_body("mark", (msg), 0, ptr)
-#define RUBY_FREE_ENTER(msg) rb_gc_debug_body("free", (msg), 1, ptr)
-#define RUBY_FREE_LEAVE(msg) rb_gc_debug_body("free", (msg), 0, ptr)
-#define RUBY_GC_INFO rb_gc_debug_indent(), ruby_debug_printf
-
-#else
-#define RUBY_MARK_ENTER(msg)
-#define RUBY_MARK_LEAVE(msg)
-#define RUBY_FREE_ENTER(msg)
-#define RUBY_FREE_LEAVE(msg)
-#define RUBY_GC_INFO if(0)printf
-#endif
-
-#define RUBY_MARK_MOVABLE_UNLESS_NULL(ptr) do { \
- VALUE markobj = (ptr); \
- if (RTEST(markobj)) {rb_gc_mark_movable(markobj);} \
-} while (0)
-#define RUBY_MARK_UNLESS_NULL(ptr) do { \
- VALUE markobj = (ptr); \
- if (RTEST(markobj)) {rb_gc_mark(markobj);} \
-} while (0)
-#define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);(ptr)=NULL;}
-
-#if STACK_GROW_DIRECTION > 0
-# define STACK_UPPER(x, a, b) (a)
-#elif STACK_GROW_DIRECTION < 0
-# define STACK_UPPER(x, a, b) (b)
-#else
-RUBY_EXTERN int ruby_stack_grow_direction;
-int ruby_get_stack_grow_direction(volatile VALUE *addr);
-# define stack_growup_p(x) ( \
- (ruby_stack_grow_direction ? \
- ruby_stack_grow_direction : \
- ruby_get_stack_grow_direction(x)) > 0)
-# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? (a) : (b))
-#endif
-
-/*
- STACK_GROW_DIR_DETECTION is used with STACK_DIR_UPPER.
-
- On most normal systems, stacks grow from high address to lower address. In
- this case, STACK_DIR_UPPER(a, b) will return (b), but on exotic systems where
- the stack grows UP (from low address to high address), it will return (a).
-*/
-
-#if STACK_GROW_DIRECTION
-#define STACK_GROW_DIR_DETECTION
-#define STACK_DIR_UPPER(a,b) STACK_UPPER(0, (a), (b))
-#else
-#define STACK_GROW_DIR_DETECTION VALUE stack_grow_dir_detection
-#define STACK_DIR_UPPER(a,b) STACK_UPPER(&stack_grow_dir_detection, (a), (b))
-#endif
-#define IS_STACK_DIR_UPPER() STACK_DIR_UPPER(1,0)
-
-const char *rb_obj_info(VALUE obj);
-const char *rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj);
-
-size_t rb_size_pool_slot_size(unsigned char pool_id);
struct rb_execution_context_struct; /* in vm_core.h */
struct rb_objspace; /* in vm_core.h */
@@ -131,22 +21,28 @@ struct rb_objspace; /* in vm_core.h */
#ifdef NEWOBJ_OF
# undef NEWOBJ_OF
# undef RB_NEWOBJ_OF
+# undef RB_OBJ_WRITE
#endif
-#define NEWOBJ_OF_0(var, T, c, f, s, ec) \
- T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
- rb_wb_protected_newobj_of(GET_EC(), (c), (f) & ~FL_WB_PROTECTED, s) : \
- rb_wb_unprotected_newobj_of((c), (f), s))
-#define NEWOBJ_OF_ec(var, T, c, f, s, ec) \
- T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
- rb_wb_protected_newobj_of((ec), (c), (f) & ~FL_WB_PROTECTED, s) : \
- rb_wb_unprotected_newobj_of((c), (f), s))
+#define RVALUE_SIZE (sizeof(struct RBasic) + sizeof(VALUE[RBIMPL_RVALUE_EMBED_LEN_MAX]))
+
+#define RB_RVARGC_NEWOBJ_OF(var, T, c, f, s) \
+ T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
+ rb_wb_protected_newobj_of((c), (f) & ~FL_WB_PROTECTED, s) : \
+ rb_wb_unprotected_newobj_of((c), (f), s))
-#define NEWOBJ_OF(var, T, c, f, s, ec) \
- NEWOBJ_OF_HELPER(ec)(var, T, c, f, s, ec)
+#define RB_RVARGC_EC_NEWOBJ_OF(ec, var, T, c, f, s) \
+ T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
+ rb_ec_wb_protected_newobj_of((ec), (c), (f) & ~FL_WB_PROTECTED, s) : \
+ rb_wb_unprotected_newobj_of((c), (f), s))
-#define NEWOBJ_OF_HELPER(ec) NEWOBJ_OF_ ## ec
+/* optimized version of NEWOBJ() */
+#define RB_NEWOBJ_OF(var, T, c, f) RB_RVARGC_NEWOBJ_OF(var, T, c, f, RVALUE_SIZE)
+#define RB_EC_NEWOBJ_OF(ec, var, T, c, f) RB_RVARGC_EC_NEWOBJ_OF(ec, var, T, c, f, RVALUE_SIZE)
+
+#define NEWOBJ_OF(var, T, c, f) RB_NEWOBJ_OF((var), T, (c), (f))
+#define RVARGC_NEWOBJ_OF(var, T, c, f, s) RB_RVARGC_NEWOBJ_OF((var), T, (c), (f), (s))
#define RB_OBJ_GC_FLAGS_MAX 6 /* used in ext/objspace */
#ifndef USE_UNALIGNED_MEMBER_ACCESS
@@ -164,41 +60,22 @@ struct rb_objspace; /* in vm_core.h */
COMPILER_WARNING_POP; \
unaligned_member_access_result; \
})
-
-# define UNALIGNED_MEMBER_PTR(ptr, mem) __extension__({ \
- COMPILER_WARNING_PUSH; \
- COMPILER_WARNING_IGNORED(-Waddress-of-packed-member); \
- const volatile void *unaligned_member_ptr_result = &(ptr)->mem; \
- COMPILER_WARNING_POP; \
- (__typeof__((ptr)->mem) *)unaligned_member_ptr_result; \
-})
#endif
-#ifndef UNALIGNED_MEMBER_PTR
-# define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
-#endif
-
-#define RB_OBJ_WRITE_UNALIGNED(old, slot, young) do { \
- VALUE *_slot = UNALIGNED_MEMBER_ACCESS(slot); \
- RB_OBJ_WRITE(old, _slot, young); \
-} while (0)
+#define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
+#define RB_OBJ_WRITE(a, slot, b) \
+ rb_obj_write((VALUE)(a), UNALIGNED_MEMBER_ACCESS((VALUE *)(slot)), \
+ (VALUE)(b), __FILE__, __LINE__)
// We use SIZE_POOL_COUNT number of shape IDs for transitions out of different size pools
-// The next available shape ID will be the SPECIAL_CONST_SHAPE_ID
-#ifndef SIZE_POOL_COUNT
+// The next available shapd ID will be the SPECIAL_CONST_SHAPE_ID
+#if USE_RVARGC && (SIZEOF_UINT64_T == SIZEOF_VALUE)
# define SIZE_POOL_COUNT 5
+#else
+# define SIZE_POOL_COUNT 1
#endif
-/* Used in places that could malloc during, which can cause the GC to run. We
- * need to temporarily disable the GC to allow the malloc to happen.
- * Allocating memory during GC is a bad idea, so use this only when absolutely
- * necessary. */
-#define DURING_GC_COULD_MALLOC_REGION_START() \
- assert(rb_during_gc()); \
- VALUE _already_disabled = rb_gc_disable_no_rest()
-
-#define DURING_GC_COULD_MALLOC_REGION_END() \
- if (_already_disabled == Qfalse) rb_gc_enable()
+#define RCLASS_EXT_EMBEDDED (SIZE_POOL_COUNT > 1)
typedef struct ractor_newobj_size_pool_cache {
struct RVALUE *freelist;
@@ -215,7 +92,6 @@ extern VALUE *ruby_initial_gc_stress_ptr;
extern int ruby_disable_gc;
RUBY_ATTR_MALLOC void *ruby_mimmalloc(size_t size);
void ruby_mimfree(void *ptr);
-void rb_gc_prepare_heap(void);
void rb_objspace_set_event_hook(const rb_event_flag_t event);
VALUE rb_objspace_gc_enable(struct rb_objspace *);
VALUE rb_objspace_gc_disable(struct rb_objspace *);
@@ -227,7 +103,6 @@ __attribute__((__alloc_align__(1)))
RUBY_ATTR_MALLOC void *rb_aligned_malloc(size_t, size_t) RUBY_ATTR_ALLOC_SIZE((2));
size_t rb_size_mul_or_raise(size_t, size_t, VALUE); /* used in compile.c */
size_t rb_size_mul_add_or_raise(size_t, size_t, size_t, VALUE); /* used in iseq.h */
-size_t rb_malloc_grow_capa(size_t current_capacity, size_t type_size);
RUBY_ATTR_MALLOC void *rb_xmalloc_mul_add(size_t, size_t, size_t);
RUBY_ATTR_MALLOC void *rb_xcalloc_mul_add(size_t, size_t, size_t);
void *rb_xrealloc_mul_add(const void *, size_t, size_t, size_t);
@@ -241,63 +116,28 @@ void rb_gc_ractor_newobj_cache_clear(rb_ractor_newobj_cache_t *newobj_cache);
size_t rb_gc_obj_slot_size(VALUE obj);
bool rb_gc_size_allocatable_p(size_t size);
int rb_objspace_garbage_object_p(VALUE obj);
-bool rb_gc_is_ptr_to_obj(void *ptr);
-VALUE rb_gc_id2ref_obj_tbl(VALUE objid);
-VALUE rb_define_finalizer_no_check(VALUE obj, VALUE block);
-
-void rb_gc_mark_and_move(VALUE *ptr);
-
-void rb_gc_mark_weak(VALUE *ptr);
-void rb_gc_remove_weak(VALUE parent_obj, VALUE *ptr);
-
-void rb_gc_ref_update_table_values_only(st_table *tbl);
-
-#define rb_gc_mark_and_move_ptr(ptr) do { \
- VALUE _obj = (VALUE)*(ptr); \
- rb_gc_mark_and_move(&_obj); \
- if (_obj != (VALUE)*(ptr)) *(ptr) = (void *)_obj; \
-} while (0)
RUBY_SYMBOL_EXPORT_BEGIN
-/* exports for objspace module */
-size_t rb_objspace_data_type_memsize(VALUE obj);
-void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
-void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *data);
-int rb_objspace_markable_object_p(VALUE obj);
-int rb_objspace_internal_object_p(VALUE obj);
-int rb_objspace_marked_object_p(VALUE obj);
-
-void rb_objspace_each_objects(
- int (*callback)(void *start, void *end, size_t stride, void *data),
- void *data);
-
-void rb_objspace_each_objects_without_setup(
- int (*callback)(void *, void *, size_t, void *),
- void *data);
-
-size_t rb_gc_obj_slot_size(VALUE obj);
-
-VALUE rb_gc_disable_no_rest(void);
-
-
/* gc.c (export) */
const char *rb_objspace_data_type_name(VALUE obj);
-VALUE rb_wb_protected_newobj_of(struct rb_execution_context_struct *, VALUE, VALUE, size_t);
+VALUE rb_wb_protected_newobj_of(VALUE, VALUE, size_t);
VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE, size_t);
+VALUE rb_ec_wb_protected_newobj_of(struct rb_execution_context_struct *ec, VALUE klass, VALUE flags, size_t);
size_t rb_obj_memsize_of(VALUE);
void rb_gc_verify_internal_consistency(void);
size_t rb_obj_gc_flags(VALUE, ID[], size_t);
void rb_gc_mark_values(long n, const VALUE *values);
void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
-void rb_gc_update_values(long n, VALUE *values);
void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
void ruby_sized_xfree(void *x, size_t size);
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
int rb_ec_stack_check(struct rb_execution_context_struct *ec);
void rb_gc_writebarrier_remember(VALUE obj);
const char *rb_obj_info(VALUE obj);
+MJIT_SYMBOL_EXPORT_END
#if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE) || defined(_WIN32)
@@ -321,12 +161,6 @@ ruby_sized_xfree_inlined(void *ptr, size_t size)
# define SIZED_REALLOC_N(x, y, z, w) REALLOC_N(x, y, z)
-static inline void *
-ruby_sized_realloc_n(void *ptr, size_t new_count, size_t element_size, size_t old_count)
-{
- return ruby_xrealloc2(ptr, new_count, element_size);
-}
-
#else
static inline void *
@@ -350,12 +184,6 @@ ruby_sized_xfree_inlined(void *ptr, size_t size)
# define SIZED_REALLOC_N(v, T, m, n) \
((v) = (T *)ruby_sized_xrealloc2((void *)(v), (m), sizeof(T), (n)))
-static inline void *
-ruby_sized_realloc_n(void *ptr, size_t new_count, size_t element_size, size_t old_count)
-{
- return ruby_sized_xrealloc2(ptr, new_count, element_size, old_count);
-}
-
#endif /* HAVE_MALLOC_USABLE_SIZE */
#define ruby_sized_xrealloc ruby_sized_xrealloc_inlined
diff --git a/internal/hash.h b/internal/hash.h
index fe859cb716..64832c9610 100644
--- a/internal/hash.h
+++ b/internal/hash.h
@@ -28,6 +28,10 @@ enum ruby_rhash_flags {
RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */
RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
+#if USE_TRANSIENT_HEAP
+ RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */
+#endif
+
// we can not put it in "enum" because it can exceed "int" range.
#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
@@ -36,23 +40,17 @@ enum ruby_rhash_flags {
RHASH_LEV_MAX = 127, /* 7 bits */
};
-typedef struct ar_table_pair_struct {
- VALUE key;
- VALUE val;
-} ar_table_pair;
-
-typedef struct ar_table_struct {
+struct RHash {
+ struct RBasic basic;
+ union {
+ st_table *st;
+ struct ar_table_struct *ar; /* possibly 0 */
+ } as;
+ const VALUE ifnone;
union {
ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE];
VALUE word;
} ar_hint;
- /* 64bit CPU: 8B * 2 * 8 = 128B */
- ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE];
-} ar_table;
-
-struct RHash {
- struct RBasic basic;
- const VALUE ifnone;
};
#define RHASH(obj) ((struct RHash *)(obj))
@@ -76,7 +74,6 @@ VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
long rb_dbl_long_hash(double d);
st_table *rb_init_identtable(void);
st_index_t rb_any_hash(VALUE a);
-int rb_any_cmp(VALUE a, VALUE b);
VALUE rb_to_hash_type(VALUE obj);
VALUE rb_hash_key_str(VALUE);
VALUE rb_hash_values(VALUE hash);
@@ -86,8 +83,8 @@ VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
+extern st_table *rb_hash_st_table(VALUE hash);
VALUE rb_ident_hash_new_with_size(st_index_t size);
-void rb_hash_free(VALUE hash);
static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
static inline VALUE RHASH_IFNONE(VALUE h);
@@ -99,6 +96,9 @@ static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
static inline st_table *RHASH_ST_TABLE(VALUE h);
static inline size_t RHASH_ST_SIZE(VALUE h);
static inline void RHASH_ST_CLEAR(VALUE h);
+static inline bool RHASH_TRANSIENT_P(VALUE h);
+static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
+static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
RUBY_SYMBOL_EXPORT_BEGIN
/* hash.c (export) */
@@ -107,6 +107,7 @@ VALUE rb_ident_hash_new(void);
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_hash_new_with_size(st_index_t size);
VALUE rb_hash_resurrect(VALUE hash);
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
@@ -116,29 +117,54 @@ VALUE rb_hash_compare_by_id_p(VALUE hash);
st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
+MJIT_SYMBOL_EXPORT_END
VALUE rb_hash_compare_by_id(VALUE hash);
+#if 0 /* for debug */
+
+static inline bool
+RHASH_AR_TABLE_P(VALUE h)
+{
+ extern int rb_hash_ar_table_p(VALUE hash);
+ return rb_hash_ar_table_p(h)
+}
+
+static inline struct ar_table_struct *
+RHASH_AR_TABLE(VALUE h)
+{
+ extern struct ar_table_struct *rb_hash_ar_table(VALUE hash);
+ return rb_hash_ar_table(h)
+}
+
+static inline st_table *
+RHASH_ST_TABLE(VALUE h)
+{
+ return rb_hash_st_table(h)
+}
+
+#else
+
static inline bool
RHASH_AR_TABLE_P(VALUE h)
{
return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
}
-RBIMPL_ATTR_RETURNS_NONNULL()
static inline struct ar_table_struct *
RHASH_AR_TABLE(VALUE h)
{
- return (struct ar_table_struct *)((uintptr_t)h + sizeof(struct RHash));
+ return RHASH(h)->as.ar;
}
-RBIMPL_ATTR_RETURNS_NONNULL()
static inline st_table *
RHASH_ST_TABLE(VALUE h)
{
- return (st_table *)((uintptr_t)h + sizeof(struct RHash));
+ return RHASH(h)->as.st;
}
+#endif
+
static inline VALUE
RHASH_IFNONE(VALUE h)
{
@@ -177,7 +203,8 @@ RHASH_ST_SIZE(VALUE h)
static inline void
RHASH_ST_CLEAR(VALUE h)
{
- memset(RHASH_ST_TABLE(h), 0, sizeof(st_table));
+ FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
+ RHASH(h)->as.ar = NULL;
}
static inline unsigned
@@ -188,4 +215,30 @@ RHASH_AR_TABLE_SIZE_RAW(VALUE h)
return (unsigned)ret;
}
+static inline bool
+RHASH_TRANSIENT_P(VALUE h)
+{
+#if USE_TRANSIENT_HEAP
+ return FL_TEST_RAW(h, RHASH_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+static inline void
+RHASH_SET_TRANSIENT_FLAG(VALUE h)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+RHASH_UNSET_TRANSIENT_FLAG(VALUE h)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG);
+#endif
+}
+
#endif /* INTERNAL_HASH_H */
diff --git a/internal/imemo.h b/internal/imemo.h
index 65335285ab..91b524e0a6 100644
--- a/internal/imemo.h
+++ b/internal/imemo.h
@@ -11,6 +11,7 @@
#include "ruby/internal/config.h"
#include <stddef.h> /* for size_t */
#include "internal/array.h" /* for rb_ary_hidden_new_fill */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/ruby.h" /* for rb_block_call_func_t */
@@ -82,7 +83,7 @@ struct vm_ifunc_argc {
/*! IFUNC (Internal FUNCtion) */
struct vm_ifunc {
VALUE flags;
- VALUE *svar_lep;
+ VALUE reserved;
rb_block_call_func_t func;
const void *data;
struct vm_ifunc_argc argc;
@@ -129,6 +130,7 @@ struct MEMO {
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
+void rb_strterm_mark(VALUE obj);
static inline enum imemo_type imemo_type(VALUE imemo);
static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
static inline bool imemo_throw_data_p(VALUE imemo);
diff --git a/internal/io.h b/internal/io.h
index f16d9efc9c..b5f15499d7 100644
--- a/internal/io.h
+++ b/internal/io.h
@@ -9,107 +9,8 @@
* @brief Internal header for IO.
*/
#include "ruby/ruby.h" /* for VALUE */
-
-#define HAVE_RB_IO_T
-struct rb_io;
-
#include "ruby/io.h" /* for rb_io_t */
-/** Ruby's IO, metadata and buffers. */
-struct rb_io {
-
- /** The IO's Ruby level counterpart. */
- VALUE self;
-
- /** stdio ptr for read/write, if available. */
- FILE *stdio_file;
-
- /** file descriptor. */
- int fd;
-
- /** mode flags: FMODE_XXXs */
- int mode;
-
- /** child's pid (for pipes) */
- rb_pid_t pid;
-
- /** number of lines read */
- int lineno;
-
- /** pathname for file */
- VALUE pathv;
-
- /** finalize proc */
- void (*finalize)(struct rb_io*,int);
-
- /** Write buffer. */
- rb_io_buffer_t wbuf;
-
- /**
- * (Byte) read buffer. Note also that there is a field called
- * ::rb_io_t::cbuf, which also concerns read IO.
- */
- rb_io_buffer_t rbuf;
-
- /**
- * Duplex IO object, if set.
- *
- * @see rb_io_set_write_io()
- */
- VALUE tied_io_for_writing;
-
- struct rb_io_encoding encs; /**< Decomposed encoding flags. */
-
- /** Encoding converter used when reading from this IO. */
- rb_econv_t *readconv;
-
- /**
- * rb_io_ungetc() destination. This buffer is read before checking
- * ::rb_io_t::rbuf
- */
- rb_io_buffer_t cbuf;
-
- /** Encoding converter used when writing to this IO. */
- rb_econv_t *writeconv;
-
- /**
- * This is, when set, an instance of ::rb_cString which holds the "common"
- * encoding. Write conversion can convert strings twice... In case
- * conversion from encoding X to encoding Y does not exist, Ruby finds an
- * encoding Z that bridges the two, so that X to Z to Y conversion happens.
- */
- VALUE writeconv_asciicompat;
-
- /** Whether ::rb_io_t::writeconv is already set up. */
- int writeconv_initialized;
-
- /**
- * Value of ::rb_io_t::rb_io_enc_t::ecflags stored right before
- * initialising ::rb_io_t::writeconv.
- */
- int writeconv_pre_ecflags;
-
- /**
- * Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising
- * ::rb_io_t::writeconv.
- */
- VALUE writeconv_pre_ecopts;
-
- /**
- * This is a Ruby level mutex. It avoids multiple threads to write to an
- * IO at once; helps for instance rb_io_puts() to ensure newlines right
- * next to its arguments.
- *
- * This of course doesn't help inter-process IO interleaves, though.
- */
- VALUE write_lock;
-
- /**
- * The timeout associated with this IO when performing blocking operations.
- */
- VALUE timeout;
-};
-
/* io.c */
void ruby_set_inplace_mode(const char *);
void rb_stdio_set_default_encoding(void);
diff --git a/internal/numeric.h b/internal/numeric.h
index f7b8d0ad2d..89bc54b307 100644
--- a/internal/numeric.h
+++ b/internal/numeric.h
@@ -111,6 +111,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
/* numeric.c (export) */
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_flo_div_flo(VALUE x, VALUE y);
double ruby_float_mod(double x, double y);
VALUE rb_float_equal(VALUE x, VALUE y);
@@ -124,6 +125,7 @@ VALUE rb_int_abs(VALUE num);
VALUE rb_int_bit_length(VALUE num);
VALUE rb_int_uminus(VALUE num);
VALUE rb_int_comp(VALUE num);
+MJIT_SYMBOL_EXPORT_END
static inline bool
INT_POSITIVE_P(VALUE num)
diff --git a/internal/object.h b/internal/object.h
index 903e2d29a5..7b54e13dd2 100644
--- a/internal/object.h
+++ b/internal/object.h
@@ -11,13 +11,10 @@
#include "ruby/ruby.h" /* for VALUE */
/* object.c */
-size_t rb_obj_embedded_size(uint32_t numiv);
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
NORETURN(void rb_undefined_alloc(VALUE klass));
double rb_num_to_dbl(VALUE val);
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
-VALUE rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze);
-VALUE rb_obj_dup_setup(VALUE obj, VALUE dup);
VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
int rb_bool_expected(VALUE, const char *, int raise);
@@ -30,6 +27,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
int rb_opts_exception_p(VALUE opts, int default_value);
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
CONSTFUNC(VALUE rb_obj_equal(VALUE obj1, VALUE obj2));
CONSTFUNC(VALUE rb_obj_not(VALUE obj));
VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
@@ -38,6 +36,7 @@ VALUE rb_false(VALUE obj);
VALUE rb_convert_type_with_id(VALUE v, int t, const char* nam, ID mid);
VALUE rb_obj_size(VALUE self, VALUE args, VALUE obj);
VALUE rb_get_freeze_opt(int argc, VALUE *argv);
+MJIT_SYMBOL_EXPORT_END
static inline void
RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass)
diff --git a/internal/parse.h b/internal/parse.h
index bd6d295be1..f242c384ad 100644
--- a/internal/parse.h
+++ b/internal/parse.h
@@ -8,101 +8,18 @@
* file COPYING are met. Consult the file for details.
* @brief Internal header for the parser.
*/
-#include <limits.h>
-#include "rubyparser.h"
-#include "internal/static_assert.h"
-
-#ifdef UNIVERSAL_PARSER
-#define rb_encoding void
-#endif
-
+#include "ruby/ruby.h" /* for VALUE */
struct rb_iseq_struct; /* in vm_core.h */
-#define STRTERM_HEREDOC IMEMO_FL_USER0
-
-/* structs for managing terminator of string literal and heredocment */
-typedef struct rb_strterm_literal_struct {
- long nest;
- int func; /* STR_FUNC_* (e.g., STR_FUNC_ESCAPE and STR_FUNC_EXPAND) */
- int paren; /* '(' of `%q(...)` */
- int term; /* ')' of `%q(...)` */
-} rb_strterm_literal_t;
-
-typedef struct rb_strterm_heredoc_struct {
- VALUE lastline; /* the string of line that contains `<<"END"` */
- long offset; /* the column of END in `<<"END"` */
- int sourceline; /* lineno of the line that contains `<<"END"` */
- unsigned length; /* the length of END in `<<"END"` */
- uint8_t quote;
- uint8_t func;
-} rb_strterm_heredoc_t;
-
-#define HERETERM_LENGTH_MAX UINT_MAX
-
-typedef struct rb_strterm_struct {
- VALUE flags;
- union {
- rb_strterm_literal_t literal;
- rb_strterm_heredoc_t heredoc;
- } u;
-} rb_strterm_t;
-
/* parse.y */
-void rb_ruby_parser_mark(void *ptr);
-size_t rb_ruby_parser_memsize(const void *ptr);
-
-void rb_ruby_parser_set_options(rb_parser_t *p, int print, int loop, int chomp, int split);
-rb_parser_t *rb_ruby_parser_set_context(rb_parser_t *p, const struct rb_iseq_struct *base, int main);
-void rb_ruby_parser_set_script_lines(rb_parser_t *p, VALUE lines_array);
-void rb_ruby_parser_error_tolerant(rb_parser_t *p);
-rb_ast_t* rb_ruby_parser_compile_file_path(rb_parser_t *p, VALUE fname, VALUE file, int start);
-void rb_ruby_parser_keep_tokens(rb_parser_t *p);
-rb_ast_t* rb_ruby_parser_compile_generic(rb_parser_t *p, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start);
-rb_ast_t* rb_ruby_parser_compile_string_path(rb_parser_t *p, VALUE f, VALUE s, int line);
+VALUE rb_parser_set_yydebug(VALUE, VALUE);
+void *rb_parser_load_file(VALUE parser, VALUE name);
+void rb_parser_keep_script_lines(VALUE vparser);
+void rb_parser_error_tolerant(VALUE vparser);
+void rb_parser_keep_tokens(VALUE vparser);
RUBY_SYMBOL_EXPORT_BEGIN
-
-VALUE rb_ruby_parser_encoding(rb_parser_t *p);
-int rb_ruby_parser_end_seen_p(rb_parser_t *p);
-int rb_ruby_parser_set_yydebug(rb_parser_t *p, int flag);
-
+VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
RUBY_SYMBOL_EXPORT_END
-int rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len, rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc);
-
-#ifdef RIPPER
-void ripper_parser_mark(void *ptr);
-void ripper_parser_free(void *ptr);
-size_t ripper_parser_memsize(const void *ptr);
-void ripper_error(struct parser_params *p);
-VALUE ripper_value(struct parser_params *p);
-int rb_ruby_parser_get_yydebug(rb_parser_t *p);
-void rb_ruby_parser_set_value(rb_parser_t *p, VALUE value);
-int rb_ruby_parser_error_p(rb_parser_t *p);
-VALUE rb_ruby_parser_debug_output(rb_parser_t *p);
-void rb_ruby_parser_set_debug_output(rb_parser_t *p, VALUE output);
-VALUE rb_ruby_parser_parsing_thread(rb_parser_t *p);
-void rb_ruby_parser_set_parsing_thread(rb_parser_t *p, VALUE parsing_thread);
-void rb_ruby_parser_ripper_initialize(rb_parser_t *p, VALUE (*gets)(struct parser_params*,VALUE), VALUE input, VALUE sourcefile_string, const char *sourcefile, int sourceline);
-VALUE rb_ruby_parser_result(rb_parser_t *p);
-rb_encoding *rb_ruby_parser_enc(rb_parser_t *p);
-VALUE rb_ruby_parser_ruby_sourcefile_string(rb_parser_t *p);
-int rb_ruby_parser_ruby_sourceline(rb_parser_t *p);
-int rb_ruby_parser_lex_state(rb_parser_t *p);
-void rb_ruby_ripper_parse0(rb_parser_t *p);
-int rb_ruby_ripper_dedent_string(rb_parser_t *p, VALUE string, int width);
-VALUE rb_ruby_ripper_lex_get_str(rb_parser_t *p, VALUE s);
-int rb_ruby_ripper_initialized_p(rb_parser_t *p);
-void rb_ruby_ripper_parser_initialize(rb_parser_t *p);
-long rb_ruby_ripper_column(rb_parser_t *p);
-long rb_ruby_ripper_token_len(rb_parser_t *p);
-VALUE rb_ruby_ripper_lex_lastline(rb_parser_t *p);
-VALUE rb_ruby_ripper_lex_state_name(struct parser_params *p, int state);
-struct parser_params *rb_ruby_ripper_parser_allocate(void);
-#endif
-
-#ifdef UNIVERSAL_PARSER
-#undef rb_encoding
-#endif
-
#endif /* INTERNAL_PARSE_H */
diff --git a/internal/proc.h b/internal/proc.h
index c75f15b283..2416c31e14 100644
--- a/internal/proc.h
+++ b/internal/proc.h
@@ -22,9 +22,11 @@ int rb_block_min_max_arity(int *max);
VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info);
VALUE rb_callable_receiver(VALUE);
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val);
VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc);
VALUE rb_iseq_location(const struct rb_iseq_struct *iseq);
VALUE rb_sym_to_proc(VALUE sym);
+MJIT_SYMBOL_EXPORT_END
#endif /* INTERNAL_PROC_H */
diff --git a/internal/process.h b/internal/process.h
index fd4994cb4b..ceadfdcbbb 100644
--- a/internal/process.h
+++ b/internal/process.h
@@ -20,8 +20,8 @@
#endif
#include "ruby/ruby.h" /* for VALUE */
-#include "internal/compilers.h" /* for __has_warning */
#include "internal/imemo.h" /* for RB_IMEMO_TMPBUF_PTR */
+#include "internal/warnings.h" /* for COMPILER_WARNING_PUSH */
#define RB_MAX_GROUPS (65536)
@@ -121,4 +121,17 @@ ARGVSTR2ARGC(VALUE argv_str)
return i - 1;
}
+#ifdef HAVE_WORKING_FORK
+COMPILER_WARNING_PUSH
+#if __has_warning("-Wdeprecated-declarations") || RBIMPL_COMPILER_IS(GCC)
+COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
+#endif
+static inline rb_pid_t
+rb_fork(void)
+{
+ return fork();
+}
+COMPILER_WARNING_POP
+#endif
+
#endif /* INTERNAL_PROCESS_H */
diff --git a/internal/random.h b/internal/random.h
index 127b908e16..231e2d5d7e 100644
--- a/internal/random.h
+++ b/internal/random.h
@@ -12,6 +12,5 @@
/* random.c */
int ruby_fill_random_bytes(void *, size_t, int);
-void rb_free_default_rand_key(void);
#endif /* INTERNAL_RANDOM_H */
diff --git a/internal/range.h b/internal/range.h
index 2394937bf8..8daba0ecab 100644
--- a/internal/range.h
+++ b/internal/range.h
@@ -24,13 +24,13 @@ RANGE_BEG(VALUE r)
static inline VALUE
RANGE_END(VALUE r)
{
- return RSTRUCT_GET(r, 1);
+ return RSTRUCT(r)->as.ary[1];
}
static inline VALUE
RANGE_EXCL(VALUE r)
{
- return RSTRUCT_GET(r, 2);
+ return RSTRUCT(r)->as.ary[2];
}
VALUE
diff --git a/internal/rational.h b/internal/rational.h
index f11fab4583..61ddbf089a 100644
--- a/internal/rational.h
+++ b/internal/rational.h
@@ -10,6 +10,7 @@
*/
#include "ruby/internal/config.h" /* for HAVE_LIBGMP */
#include "ruby/ruby.h" /* for struct RBasic */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/numeric.h" /* for INT_POSITIVE_P */
#include "ruby_assert.h" /* for assert */
diff --git a/internal/re.h b/internal/re.h
index 3e20114665..8b31b3d8a5 100644
--- a/internal/re.h
+++ b/internal/re.h
@@ -22,7 +22,9 @@ VALUE rb_reg_equal(VALUE re1, VALUE re2);
void rb_backref_set_string(VALUE string, long pos, long len);
void rb_match_unbusy(VALUE);
int rb_match_count(VALUE match);
+int rb_match_nth_defined(int nth, VALUE match);
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_reg_new_ary(VALUE ary, int options);
-VALUE rb_reg_last_defined(VALUE match);
+MJIT_SYMBOL_EXPORT_END
#endif /* INTERNAL_RE_H */
diff --git a/internal/ruby_parser.h b/internal/ruby_parser.h
deleted file mode 100644
index 6beb2808ab..0000000000
--- a/internal/ruby_parser.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef INTERNAL_RUBY_PARSE_H
-#define INTERNAL_RUBY_PARSE_H
-
-#include "internal.h"
-#include "internal/imemo.h"
-#include "rubyparser.h"
-#include "vm.h"
-
-RUBY_SYMBOL_EXPORT_BEGIN
-#ifdef UNIVERSAL_PARSER
-void rb_parser_config_initialize(rb_parser_config_t *config);
-#endif
-VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
-VALUE rb_parser_new(void);
-rb_ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
-RUBY_SYMBOL_EXPORT_END
-
-VALUE rb_parser_end_seen_p(VALUE);
-VALUE rb_parser_encoding(VALUE);
-VALUE rb_parser_set_yydebug(VALUE, VALUE);
-void rb_parser_set_options(VALUE, int, int, int, int);
-void *rb_parser_load_file(VALUE parser, VALUE name);
-void rb_parser_set_script_lines(VALUE vparser, VALUE lines_array);
-void rb_parser_error_tolerant(VALUE vparser);
-void rb_parser_keep_tokens(VALUE vparser);
-
-rb_ast_t *rb_parser_compile_string(VALUE, const char*, VALUE, int);
-rb_ast_t *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
-rb_ast_t *rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int line);
-
-enum lex_state_bits {
- EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
- EXPR_END_bit, /* newline significant, +/- is an operator. */
- EXPR_ENDARG_bit, /* ditto, and unbound braces. */
- EXPR_ENDFN_bit, /* ditto, and unbound braces. */
- EXPR_ARG_bit, /* newline significant, +/- is an operator. */
- EXPR_CMDARG_bit, /* newline significant, +/- is an operator. */
- EXPR_MID_bit, /* newline significant, +/- is an operator. */
- EXPR_FNAME_bit, /* ignore newline, no reserved words. */
- EXPR_DOT_bit, /* right after `.', `&.' or `::', no reserved words. */
- EXPR_CLASS_bit, /* immediate after `class', no here document. */
- EXPR_LABEL_bit, /* flag bit, label is allowed. */
- EXPR_LABELED_bit, /* flag bit, just after a label. */
- EXPR_FITEM_bit, /* symbol literal as FNAME. */
- EXPR_MAX_STATE
-};
-/* examine combinations */
-enum lex_state_e {
-#define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
- DEF_EXPR(BEG),
- DEF_EXPR(END),
- DEF_EXPR(ENDARG),
- DEF_EXPR(ENDFN),
- DEF_EXPR(ARG),
- DEF_EXPR(CMDARG),
- DEF_EXPR(MID),
- DEF_EXPR(FNAME),
- DEF_EXPR(DOT),
- DEF_EXPR(CLASS),
- DEF_EXPR(LABEL),
- DEF_EXPR(LABELED),
- DEF_EXPR(FITEM),
- EXPR_VALUE = EXPR_BEG,
- EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS),
- EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
- EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN),
- EXPR_NONE = 0
-};
-#endif /* INTERNAL_RUBY_PARSE_H */
diff --git a/internal/sanitizers.h b/internal/sanitizers.h
index 7b7d166c74..6e2d81137f 100644
--- a/internal/sanitizers.h
+++ b/internal/sanitizers.h
@@ -89,6 +89,8 @@
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
#endif
+#ifndef MJIT_HEADER
+
/*!
* This function asserts that a (continuous) memory region from ptr to size
* being "poisoned". Both read / write access to such memory region are
@@ -183,4 +185,6 @@ asan_unpoison_object(VALUE obj, bool newobj_p)
asan_unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p);
}
+#endif /* MJIT_HEADER */
+
#endif /* INTERNAL_SANITIZERS_H */
diff --git a/internal/signal.h b/internal/signal.h
index 660cd95f78..86fb54e949 100644
--- a/internal/signal.h
+++ b/internal/signal.h
@@ -13,10 +13,6 @@
extern int ruby_enable_coredump;
int rb_get_next_signal(void);
-#ifdef POSIX_SIGNAL
-void (*ruby_posix_signal(int, void (*)(int)))(int);
-#endif
-
RUBY_SYMBOL_EXPORT_BEGIN
/* signal.c (export) */
int rb_grantpt(int fd);
diff --git a/internal/string.h b/internal/string.h
index ba2af25877..12edbff2b1 100644
--- a/internal/string.h
+++ b/internal/string.h
@@ -57,7 +57,6 @@ static inline VALUE rb_str_eql_internal(const VALUE str1, const VALUE str2);
RUBY_SYMBOL_EXPORT_BEGIN
/* string.c (export) */
VALUE rb_str_tmp_frozen_acquire(VALUE str);
-VALUE rb_str_tmp_frozen_no_embed_acquire(VALUE str);
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
@@ -65,8 +64,10 @@ VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
void rb_str_make_embedded(VALUE);
size_t rb_str_size_as_embedded(VALUE);
bool rb_str_reembeddable_p(VALUE);
+void rb_str_update_shared_ary(VALUE str, VALUE old_root, VALUE new_root);
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_fstring_new(const char *ptr, long len);
VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
VALUE rb_str_opt_plus(VALUE x, VALUE y);
@@ -77,6 +78,7 @@ VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE
struct rb_execution_context_struct;
VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str);
+MJIT_SYMBOL_EXPORT_END
#define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str))
#define rb_fstring_literal(str) rb_fstring_lit(str)
@@ -119,21 +121,6 @@ is_broken_string(VALUE str)
return rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN;
}
-static inline bool
-at_char_boundary(const char *s, const char *p, const char *e, rb_encoding *enc)
-{
- return rb_enc_left_char_head(s, p, e, enc) == p;
-}
-
-static inline bool
-at_char_right_boundary(const char *s, const char *p, const char *e, rb_encoding *enc)
-{
- RUBY_ASSERT(s <= p);
- RUBY_ASSERT(p <= e);
-
- return rb_enc_right_char_head(s, p, e, enc) == p;
-}
-
/* expect tail call optimization */
// YJIT needs this function to never allocate and never raise
static inline VALUE
diff --git a/internal/struct.h b/internal/struct.h
index 6da5bad10a..8acc00ec3c 100644
--- a/internal/struct.h
+++ b/internal/struct.h
@@ -9,12 +9,14 @@
* @brief Internal header for Struct.
*/
#include "ruby/internal/stdbool.h" /* for bool */
+#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "ruby/ruby.h" /* for struct RBasic */
enum {
- RSTRUCT_EMBED_LEN_MASK = RUBY_FL_USER7 | RUBY_FL_USER6 | RUBY_FL_USER5 | RUBY_FL_USER4 |
- RUBY_FL_USER3 | RUBY_FL_USER2 | RUBY_FL_USER1,
+ RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
+ RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
+ RSTRUCT_TRANSIENT_FLAG = FL_USER3,
};
struct RStruct {
@@ -24,12 +26,7 @@ struct RStruct {
long len;
const VALUE *ptr;
} heap;
- /* This is a length 1 array because:
- * 1. GCC has a bug that does not optimize C flexible array members
- * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
- * 2. Zero length arrays are not supported by all compilers
- */
- const VALUE ary[1];
+ const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
} as;
};
@@ -60,6 +57,9 @@ VALUE rb_struct_init_copy(VALUE copy, VALUE s);
VALUE rb_struct_lookup(VALUE s, VALUE idx);
VALUE rb_struct_s_keyword_init(VALUE klass);
static inline const VALUE *rb_struct_const_heap_ptr(VALUE st);
+static inline bool RSTRUCT_TRANSIENT_P(VALUE st);
+static inline void RSTRUCT_TRANSIENT_SET(VALUE st);
+static inline void RSTRUCT_TRANSIENT_UNSET(VALUE st);
static inline long RSTRUCT_EMBED_LEN(VALUE st);
static inline long RSTRUCT_LEN(VALUE st);
static inline int RSTRUCT_LENINT(VALUE st);
@@ -67,6 +67,32 @@ static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
static inline void RSTRUCT_SET(VALUE st, long k, VALUE v);
static inline VALUE RSTRUCT_GET(VALUE st, long k);
+static inline bool
+RSTRUCT_TRANSIENT_P(VALUE st)
+{
+#if USE_TRANSIENT_HEAP
+ return FL_TEST_RAW(st, RSTRUCT_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+static inline void
+RSTRUCT_TRANSIENT_SET(VALUE st)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+RSTRUCT_TRANSIENT_UNSET(VALUE st)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
+#endif
+}
+
static inline long
RSTRUCT_EMBED_LEN(VALUE st)
{
@@ -120,7 +146,7 @@ RSTRUCT_GET(VALUE st, long k)
static inline const VALUE *
rb_struct_const_heap_ptr(VALUE st)
{
- assert(!FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK));
+ /* TODO: check embed on debug mode */
return RSTRUCT(st)->as.heap.ptr;
}
diff --git a/internal/symbol.h b/internal/symbol.h
index e7730cb70f..30c81ea004 100644
--- a/internal/symbol.h
+++ b/internal/symbol.h
@@ -32,9 +32,6 @@ ID rb_make_temporary_id(size_t n);
void rb_gc_free_dsymbol(VALUE);
int rb_static_id_valid_p(ID id);
-/* vm.c */
-void rb_free_static_symid_str(void);
-
#if __has_builtin(__builtin_constant_p)
#define rb_sym_intern_ascii_cstr(ptr) \
(__builtin_constant_p(ptr) ? \
diff --git a/internal/thread.h b/internal/thread.h
index cf25975d8b..c3e54de683 100644
--- a/internal/thread.h
+++ b/internal/thread.h
@@ -10,17 +10,9 @@
*/
#include "ruby/ruby.h" /* for VALUE */
#include "ruby/intern.h" /* for rb_blocking_function_t */
-#include "ccan/list/list.h" /* for list in rb_io_close_wait_list */
struct rb_thread_struct; /* in vm_core.h */
-#define RB_VM_SAVE_MACHINE_CONTEXT(th) \
- do { \
- FLUSH_REGISTER_WINDOWS; \
- setjmp((th)->ec->machine.regs); \
- SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); \
- } while (0)
-
/* thread.c */
#define COVERAGE_INDEX_LINES 0
#define COVERAGE_INDEX_BRANCHES 1
@@ -30,10 +22,6 @@ struct rb_thread_struct; /* in vm_core.h */
#define COVERAGE_TARGET_ONESHOT_LINES 8
#define COVERAGE_TARGET_EVAL 16
-#define RUBY_FATAL_THREAD_KILLED INT2FIX(0)
-#define RUBY_FATAL_THREAD_TERMINATED INT2FIX(1)
-#define RUBY_FATAL_FIBER_KILLED RB_INT2FIX(2)
-
VALUE rb_obj_is_mutex(VALUE obj);
VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
void rb_thread_execute_interrupts(VALUE th);
@@ -50,29 +38,19 @@ void rb_mutex_allow_trap(VALUE self, int val);
VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
VALUE rb_mutex_owned_p(VALUE self);
VALUE rb_exec_recursive_outer_mid(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h, ID mid);
-void ruby_mn_threads_params(void);
int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout);
-struct rb_io_close_wait_list {
- struct ccan_list_head pending_fd_users;
- VALUE closing_thread;
- VALUE wakeup_mutex;
-};
-int rb_notify_fd_close(int fd, struct rb_io_close_wait_list *busy);
-void rb_notify_fd_close_wait(struct rb_io_close_wait_list *busy);
-
RUBY_SYMBOL_EXPORT_BEGIN
-
/* Temporary. This API will be removed (renamed). */
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
-VALUE rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events);
/* thread.c (export) */
int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
-
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
int rb_threadptr_execute_interrupts(struct rb_thread_struct *th, int blocking_timing);
+MJIT_SYMBOL_EXPORT_END
#endif /* INTERNAL_THREAD_H */
diff --git a/internal/time.h b/internal/time.h
index a3bf0587ec..e21b3574f6 100644
--- a/internal/time.h
+++ b/internal/time.h
@@ -28,7 +28,10 @@ struct timeval rb_time_timeval(VALUE);
RUBY_SYMBOL_EXPORT_BEGIN
/* time.c (export) */
void ruby_reset_leap_second_info(void);
-void ruby_reset_timezone(void);
+#ifdef RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY
+RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY()
+#endif
+void ruby_reset_timezone(const char *);
RUBY_SYMBOL_EXPORT_END
#endif /* INTERNAL_TIME_H */
diff --git a/internal/transcode.h b/internal/transcode.h
index ce4f2341be..9922332ea9 100644
--- a/internal/transcode.h
+++ b/internal/transcode.h
@@ -17,7 +17,4 @@
extern VALUE rb_cEncodingConverter;
size_t rb_econv_memsize(rb_econv_t *);
-/* vm.c */
-void rb_free_transcoder_table(void);
-
#endif /* INTERNAL_TRANSCODE_H */
diff --git a/internal/variable.h b/internal/variable.h
index b2a30c7c58..6dec6a6759 100644
--- a/internal/variable.h
+++ b/internal/variable.h
@@ -15,6 +15,10 @@
#include "ruby/ruby.h" /* for VALUE */
#include "shape.h" /* for rb_shape_t */
+/* global variable */
+
+#define ROBJECT_TRANSIENT_FLAG FL_USER2
+
/* variable.c */
void rb_gc_mark_global_tbl(void);
void rb_gc_update_global_tbl(void);
@@ -28,45 +32,59 @@ rb_gvar_getter_t *rb_gvar_getter_function_of(ID);
rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
void rb_gvar_ractor_local(const char *name);
-
-/**
- * Sets the name of a module.
- *
- * Non-permanently named classes can have a temporary name assigned (or
- * cleared). In that case the name will be used for `#inspect` and `#to_s`, and
- * nested classes/modules will be named with the temporary name as a prefix.
- *
- * After the module is assigned to a constant, the temporary name will be
- * discarded, and the name will be computed based on the nesting.
- *
- * @param[in] mod An instance of ::rb_cModule.
- * @param[in] name An instance of ::rb_cString.
- * @retval mod
- */
-VALUE rb_mod_set_temporary_name(VALUE, VALUE);
+static inline bool ROBJ_TRANSIENT_P(VALUE obj);
+static inline void ROBJ_TRANSIENT_SET(VALUE obj);
+static inline void ROBJ_TRANSIENT_UNSET(VALUE obj);
struct gen_ivtbl;
int rb_gen_ivtbl_get(VALUE obj, ID id, struct gen_ivtbl **ivtbl);
-void rb_obj_copy_ivs_to_hash_table(VALUE obj, st_table *table);
-void rb_obj_convert_to_too_complex(VALUE obj, st_table *table);
-void rb_evict_ivars_to_hash(VALUE obj);
+int rb_obj_evacuate_ivs_to_hash_table(ID key, VALUE val, st_data_t arg);
RUBY_SYMBOL_EXPORT_BEGIN
/* variable.c (export) */
-void rb_mark_generic_ivar(VALUE obj);
-void rb_ref_update_generic_ivar(VALUE);
+void rb_mark_generic_ivar(VALUE);
void rb_mv_generic_ivar(VALUE src, VALUE dst);
VALUE rb_const_missing(VALUE klass, VALUE name);
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
void rb_iv_tbl_copy(VALUE dst, VALUE src);
RUBY_SYMBOL_EXPORT_END
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
VALUE rb_gvar_get(ID);
VALUE rb_gvar_set(ID, VALUE);
VALUE rb_gvar_defined(ID);
void rb_const_warn_if_deprecated(const rb_const_entry_t *, VALUE, ID);
+rb_shape_t * rb_grow_iv_list(VALUE obj);
void rb_ensure_iv_list_size(VALUE obj, uint32_t len, uint32_t newsize);
+struct gen_ivtbl *rb_ensure_generic_iv_list_size(VALUE obj, rb_shape_t *shape, uint32_t newsize);
attr_index_t rb_obj_ivar_set(VALUE obj, ID id, VALUE val);
+MJIT_SYMBOL_EXPORT_END
+
+static inline bool
+ROBJ_TRANSIENT_P(VALUE obj)
+{
+#if USE_TRANSIENT_HEAP
+ return FL_TEST_RAW(obj, ROBJECT_TRANSIENT_FLAG);
+#else
+ return false;
+#endif
+}
+
+static inline void
+ROBJ_TRANSIENT_SET(VALUE obj)
+{
+#if USE_TRANSIENT_HEAP
+ FL_SET_RAW(obj, ROBJECT_TRANSIENT_FLAG);
+#endif
+}
+
+static inline void
+ROBJ_TRANSIENT_UNSET(VALUE obj)
+{
+#if USE_TRANSIENT_HEAP
+ FL_UNSET_RAW(obj, ROBJECT_TRANSIENT_FLAG);
+#endif
+}
#endif /* INTERNAL_VARIABLE_H */
diff --git a/internal/vm.h b/internal/vm.h
index a32a14e045..cf245c6579 100644
--- a/internal/vm.h
+++ b/internal/vm.h
@@ -50,15 +50,17 @@ PUREFUNC(VALUE rb_vm_top_self(void));
const void **rb_vm_get_insns_address_table(void);
VALUE rb_source_location(int *pline);
const char *rb_source_location_cstr(int *pline);
-void rb_vm_pop_cfunc_frame(void);
+MJIT_STATIC void rb_vm_pop_cfunc_frame(void);
int rb_vm_add_root_module(VALUE module);
void rb_vm_check_redefinition_by_prepend(VALUE klass);
int rb_vm_check_optimizable_mid(VALUE mid);
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
-VALUE ruby_vm_special_exception_copy(VALUE);
+MJIT_STATIC VALUE ruby_vm_special_exception_copy(VALUE);
PUREFUNC(st_table *rb_vm_fstring_table(void));
-void rb_lastline_set_up(VALUE val, unsigned int up);
+MJIT_SYMBOL_EXPORT_BEGIN
+VALUE vm_exec(struct rb_execution_context_struct *, bool); /* used in JIT-ed code */
+MJIT_SYMBOL_EXPORT_END
/* vm_eval.c */
VALUE rb_current_realfilepath(void);
@@ -78,31 +80,25 @@ VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
VALUE data2);
void rb_check_stack_overflow(void);
-#if USE_YJIT
-/* vm_exec.c */
-extern uint64_t rb_vm_insns_count;
-#endif
-
-extern bool rb_free_at_exit;
-
-/* miniinit.c and builtin.c */
-void rb_free_loaded_builtin_table(void);
-
/* vm_insnhelper.c */
VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
struct rb_iseq_struct;
+MJIT_SYMBOL_EXPORT_BEGIN
const struct rb_callcache *rb_vm_search_method_slowpath(const struct rb_callinfo *ci, VALUE klass);
+MJIT_SYMBOL_EXPORT_END
/* vm_method.c */
struct rb_execution_context_struct;
+MJIT_SYMBOL_EXPORT_BEGIN
int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID id, int priv);
+MJIT_SYMBOL_EXPORT_END
void rb_clear_constant_cache(void);
/* vm_dump.c */
-void rb_print_backtrace(FILE *);
+void rb_print_backtrace(void);
/* vm_backtrace.c */
VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval);
@@ -110,7 +106,7 @@ VALUE rb_vm_thread_backtrace_locations(int argc, const VALUE *argv, VALUE thval)
VALUE rb_vm_backtrace(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
VALUE rb_vm_backtrace_locations(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
VALUE rb_make_backtrace(void);
-void rb_backtrace_print_as_bugreport(FILE*);
+void rb_backtrace_print_as_bugreport(void);
int rb_backtrace_p(VALUE obj);
VALUE rb_backtrace_to_str_ary(VALUE obj);
VALUE rb_backtrace_to_location_ary(VALUE obj);
@@ -119,8 +115,10 @@ int rb_frame_info_p(VALUE obj);
int rb_get_node_id_from_frame_info(VALUE obj);
const struct rb_iseq_struct *rb_get_iseq_from_frame_info(VALUE obj);
+MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_ec_backtrace_object(const struct rb_execution_context_struct *ec);
void rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self);
+MJIT_SYMBOL_EXPORT_END
#define RUBY_DTRACE_CREATE_HOOK(name, arg) \
RUBY_DTRACE_HOOK(name##_CREATE, arg)
diff --git a/io.c b/io.c
index 9d651e016a..99ec59da29 100644
--- a/io.c
+++ b/io.c
@@ -16,6 +16,11 @@
#include "ruby/fiber/scheduler.h"
#include "ruby/io/buffer.h"
+#ifdef _WIN32
+# include "ruby/ruby.h"
+# include "ruby/io.h"
+#endif
+
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
@@ -170,7 +175,6 @@ off_t __syscall(quad_t number, ...);
#define open rb_w32_uopen
#undef rename
#define rename(f, t) rb_w32_urename((f), (t))
-#include "win32/file.h"
#endif
VALUE rb_cIO;
@@ -217,7 +221,7 @@ struct argf {
long lineno;
VALUE argv;
VALUE inplace;
- struct rb_io_encoding encs;
+ struct rb_io_enc_t encs;
int8_t init_p, next_p, binmode;
};
@@ -521,6 +525,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
static int io_fflush(rb_io_t *);
static rb_io_t *flush_before_seek(rb_io_t *fptr);
+#define FMODE_PREP (1<<16)
#define FMODE_SIGNAL_ON_EPIPE (1<<17)
#define fptr_signal_on_epipe(fptr) \
@@ -847,12 +852,9 @@ rb_io_timeout(VALUE self)
* timeout = duration -> duration
* timeout = nil -> nil
*
- * Sets the internal timeout to the specified duration or nil. The timeout
+ * Set the internal timeout to the specified duration or nil. The timeout
* applies to all blocking operations where possible.
*
- * When the operation performs longer than the timeout set, IO::TimeoutError
- * is raised.
- *
* This affects the following methods (but is not limited to): #gets, #puts,
* #read, #write, #wait_readable and #wait_writable. This also affects
* blocking socket operations like Socket#accept and Socket#connect.
@@ -1064,24 +1066,20 @@ rb_gc_for_fd(int err)
return 0;
}
-/* try `expr` upto twice while it returns false and `errno`
- * is to GC. Each `errno`s are available as `first_errno` and
- * `retried_errno` respectively */
-#define TRY_WITH_GC(expr) \
- for (int first_errno, retried_errno = 0, retried = 0; \
- (!retried && \
- !(expr) && \
- (!rb_gc_for_fd(first_errno = errno) || !(expr)) && \
- (retried_errno = errno, 1)); \
- (void)retried_errno, retried = 1)
-
static int
ruby_dup(int orig)
{
- int fd = -1;
+ int fd;
- TRY_WITH_GC((fd = rb_cloexec_dup(orig)) >= 0) {
- rb_syserr_fail(first_errno, 0);
+ fd = rb_cloexec_dup(orig);
+ if (fd < 0) {
+ int e = errno;
+ if (rb_gc_for_fd(e)) {
+ fd = rb_cloexec_dup(orig);
+ }
+ if (fd < 0) {
+ rb_syserr_fail(e, 0);
+ }
}
rb_update_max_fd(fd);
return fd;
@@ -1090,7 +1088,7 @@ ruby_dup(int orig)
static VALUE
io_alloc(VALUE klass)
{
- NEWOBJ_OF(io, struct RFile, klass, T_FILE, sizeof(struct RFile), 0);
+ NEWOBJ_OF(io, struct RFile, klass, T_FILE);
io->fptr = 0;
@@ -1286,7 +1284,7 @@ rb_io_read_memory(rb_io_t *fptr, void *buf, size_t count)
iis.timeout = &timeout_storage;
}
- return (ssize_t)rb_thread_io_blocking_call(internal_read_func, &iis, fptr->fd, RB_WAITFD_IN);
+ return (ssize_t)rb_thread_io_blocking_region(internal_read_func, &iis, fptr->fd);
}
static ssize_t
@@ -1319,7 +1317,7 @@ rb_io_write_memory(rb_io_t *fptr, const void *buf, size_t count)
iis.timeout = &timeout_storage;
}
- return (ssize_t)rb_thread_io_blocking_call(internal_write_func, &iis, fptr->fd, RB_WAITFD_OUT);
+ return (ssize_t)rb_thread_io_blocking_region(internal_write_func, &iis, fptr->fd);
}
#ifdef HAVE_WRITEV
@@ -1356,7 +1354,7 @@ rb_writev_internal(rb_io_t *fptr, const struct iovec *iov, int iovcnt)
iis.timeout = &timeout_storage;
}
- return (ssize_t)rb_thread_io_blocking_call(internal_writev_func, &iis, fptr->fd, RB_WAITFD_OUT);
+ return (ssize_t)rb_thread_io_blocking_region(internal_writev_func, &iis, fptr->fd);
}
#endif
@@ -1386,7 +1384,7 @@ static VALUE
io_flush_buffer_async(VALUE arg)
{
rb_io_t *fptr = (rb_io_t *)arg;
- return rb_thread_io_blocking_call(io_flush_buffer_sync, fptr, fptr->fd, RB_WAITFD_OUT);
+ return rb_thread_io_blocking_region(io_flush_buffer_sync, fptr, fptr->fd);
}
static inline int
@@ -1462,7 +1460,7 @@ rb_io_wait(VALUE io, VALUE events, VALUE timeout)
static VALUE
io_from_fd(int fd)
{
- return prep_io(fd, FMODE_EXTERNAL, rb_cIO, NULL);
+ return prep_io(fd, FMODE_PREP, rb_cIO, NULL);
}
static int
@@ -1836,7 +1834,7 @@ io_allocate_write_buffer(rb_io_t *fptr, int sync)
static inline int
io_binwrite_requires_flush_write(rb_io_t *fptr, long len, int nosync)
{
- // If the requested operation was synchronous and the output mode is synchronous or a TTY:
+ // If the requested operation was synchronous and the output mode is synchronus or a TTY:
if (!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY)))
return 1;
@@ -1970,7 +1968,7 @@ io_fwrite(VALUE str, rb_io_t *fptr, int nosync)
if (converted)
OBJ_FREEZE(str);
- tmp = rb_str_tmp_frozen_no_embed_acquire(str);
+ tmp = rb_str_tmp_frozen_acquire(str);
RSTRING_GETMEM(tmp, ptr, len);
n = io_binwrite(tmp, ptr, len, fptr, nosync);
rb_str_tmp_frozen_release(str, tmp);
@@ -2389,6 +2387,9 @@ rb_io_flush(VALUE io)
* f.close
*
* Related: IO#pos=, IO#seek.
+ *
+ * IO#pos is an alias for IO#tell.
+ *
*/
static VALUE
@@ -2656,6 +2657,9 @@ io_fillbuf(rb_io_t *fptr)
* Note that this method reads data to the input byte buffer. So
* IO#sysread may not behave as you intend with IO#eof?, unless you
* call IO#rewind first (which is not available for some streams).
+ *
+ * IO#eof? is an alias for IO#eof.
+ *
*/
VALUE
@@ -2846,6 +2850,8 @@ rb_io_fdatasync(VALUE io)
* File.open('t.txt').fileno # => 10
* f.close
*
+ * IO#to_i is an alias for IO#fileno.
+ *
*/
static VALUE
@@ -2868,23 +2874,8 @@ rb_io_descriptor(VALUE io)
return fptr->fd;
}
else {
- VALUE fileno = rb_check_funcall(io, id_fileno, 0, NULL);
- if (!UNDEF_P(fileno)) {
- return RB_NUM2INT(fileno);
- }
+ return RB_NUM2INT(rb_funcall(io, id_fileno, 0));
}
-
- rb_raise(rb_eTypeError, "expected IO or #fileno, %"PRIsVALUE" given", rb_obj_class(io));
-
- UNREACHABLE_RETURN(-1);
-}
-
-int
-rb_io_mode(VALUE io)
-{
- rb_io_t *fptr;
- GetOpenFile(io, fptr);
- return fptr->mode;
}
/*
@@ -2933,7 +2924,7 @@ rb_io_pid(VALUE io)
* File.open("testfile") {|f| f.path} # => "testfile"
*/
-VALUE
+static VALUE
rb_io_path(VALUE io)
{
rb_io_t *fptr = RFILE(io)->fptr;
@@ -3274,10 +3265,9 @@ io_setstrbuf(VALUE *str, long len)
}
else {
VALUE s = StringValue(*str);
- rb_str_modify(s);
-
long clen = RSTRING_LEN(s);
if (clen >= len) {
+ rb_str_modify(s);
return FALSE;
}
len -= clen;
@@ -3408,12 +3398,7 @@ io_read_memory_call(VALUE arg)
}
}
- if (iis->nonblock) {
- return rb_thread_io_blocking_call(internal_read_func, iis, iis->fptr->fd, 0);
- }
- else {
- return rb_thread_io_blocking_call(internal_read_func, iis, iis->fptr->fd, RB_WAITFD_IN);
- }
+ return rb_thread_io_blocking_region(internal_read_func, iis, iis->fptr->fd);
}
static long
@@ -3820,8 +3805,33 @@ rscheck(const char *rsptr, long rslen, VALUE rs)
rb_raise(rb_eRuntimeError, "rs modified");
}
+static const char *
+search_delim(const char *p, long len, int delim, rb_encoding *enc)
+{
+ if (rb_enc_mbminlen(enc) == 1) {
+ p = memchr(p, delim, len);
+ if (p) return p + 1;
+ }
+ else {
+ const char *end = p + len;
+ while (p < end) {
+ int r = rb_enc_precise_mbclen(p, end, enc);
+ if (!MBCLEN_CHARFOUND_P(r)) {
+ p += rb_enc_mbminlen(enc);
+ continue;
+ }
+ int n = MBCLEN_CHARFOUND_LEN(r);
+ if (rb_enc_mbc_to_codepoint(p, end, enc) == (unsigned int)delim) {
+ return p + n;
+ }
+ p += n;
+ }
+ }
+ return NULL;
+}
+
static int
-appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
+appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp, rb_encoding *enc)
{
VALUE str = *strp;
long limit = *lp;
@@ -3836,9 +3846,9 @@ appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
p = READ_CHAR_PENDING_PTR(fptr);
if (0 < limit && limit < searchlen)
searchlen = (int)limit;
- e = memchr(p, delim, searchlen);
+ e = search_delim(p, searchlen, delim, enc);
if (e) {
- int len = (int)(e-p+1);
+ int len = (int)(e-p);
if (NIL_P(str))
*strp = str = rb_str_new(p, len);
else
@@ -3878,8 +3888,8 @@ appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
long last;
if (limit > 0 && pending > limit) pending = limit;
- e = memchr(p, delim, pending);
- if (e) pending = e - p + 1;
+ e = search_delim(p, pending, delim, enc);
+ if (e) pending = e - p;
if (!NIL_P(str)) {
last = RSTRING_LEN(str);
rb_str_resize(str, last + pending);
@@ -4139,16 +4149,26 @@ rb_io_getline_0(VALUE rs, long limit, int chomp, rb_io_t *fptr)
rsptr = RSTRING_PTR(rs);
rslen = RSTRING_LEN(rs);
}
+ newline = '\n';
+ }
+ else if (rb_enc_mbminlen(enc) == 1) {
+ rsptr = RSTRING_PTR(rs);
+ newline = (unsigned char)rsptr[rslen - 1];
}
else {
+ rs = rb_str_encode(rs, rb_enc_from_encoding(enc), 0, Qnil);
rsptr = RSTRING_PTR(rs);
+ const char *e = rsptr + rslen;
+ const char *last = rb_enc_prev_char(rsptr, e, e, enc);
+ int n;
+ newline = rb_enc_codepoint_len(last, e, &n, enc);
+ if (last + n != e) rb_raise(rb_eArgError, "broken separator");
}
- newline = (unsigned char)rsptr[rslen - 1];
- chomp_cr = chomp && rslen == 1 && newline == '\n';
+ chomp_cr = chomp && newline == '\n' && rslen == rb_enc_mbminlen(enc);
}
/* MS - Optimization */
- while ((c = appendline(fptr, newline, &str, &limit)) != EOF) {
+ while ((c = appendline(fptr, newline, &str, &limit, enc)) != EOF) {
const char *s, *p, *pp, *e;
if (c == newline) {
@@ -4156,7 +4176,8 @@ rb_io_getline_0(VALUE rs, long limit, int chomp, rb_io_t *fptr)
s = RSTRING_PTR(str);
e = RSTRING_END(str);
p = e - rslen;
- if (!at_char_boundary(s, p, e, enc)) continue;
+ pp = rb_enc_left_char_head(s, p, e, enc);
+ if (pp != p) continue;
if (!rspara) rscheck(rsptr, rslen, rs);
if (memcmp(p, rsptr, rslen) == 0) {
if (chomp) {
@@ -4169,8 +4190,8 @@ rb_io_getline_0(VALUE rs, long limit, int chomp, rb_io_t *fptr)
if (limit == 0) {
s = RSTRING_PTR(str);
p = RSTRING_END(str);
- pp = rb_enc_left_char_head(s, p-1, p, enc);
- if (extra_limit &&
+ pp = rb_enc_prev_char(s, p, p, enc);
+ if (extra_limit && pp &&
MBCLEN_NEEDMORE_P(rb_enc_precise_mbclen(pp, p, enc))) {
/* relax the limit while incomplete character.
* extra_limit limits the relax length */
@@ -4368,28 +4389,22 @@ rb_io_set_lineno(VALUE io, VALUE lineno)
return lineno;
}
-/* :nodoc: */
+/*
+ * call-seq:
+ * readline(sep = $/, chomp: false) -> string
+ * readline(limit, chomp: false) -> string
+ * readline(sep, limit, chomp: false) -> string
+ *
+ * Reads a line as with IO#gets, but raises EOFError if already at end-of-stream.
+ *
+ * Optional keyword argument +chomp+ specifies whether line separators
+ * are to be omitted.
+ */
+
static VALUE
-io_readline(rb_execution_context_t *ec, VALUE io, VALUE sep, VALUE lim, VALUE chomp)
+rb_io_readline(int argc, VALUE *argv, VALUE io)
{
- if (NIL_P(lim)) {
- // If sep is specified, but it's not a string and not nil, then assume
- // it's the limit (it should be an integer)
- if (!NIL_P(sep) && NIL_P(rb_check_string_type(sep))) {
- // If the user has specified a non-nil / non-string value
- // for the separator, we assume it's the limit and set the
- // separator to default: rb_rs.
- lim = sep;
- sep = rb_rs;
- }
- }
-
- if (!NIL_P(sep)) {
- StringValue(sep);
- }
-
- VALUE line = rb_io_getline_1(sep, NIL_P(lim) ? -1L : NUM2LONG(lim), RTEST(chomp), io);
- rb_lastline_set_up(line, 1);
+ VALUE line = rb_io_gets_m(argc, argv, io);
if (NIL_P(line)) {
rb_eof_error();
@@ -4594,6 +4609,9 @@ io_readlines(const struct getline_arg *arg, VALUE io)
* "Fifth line"
*
* Returns an Enumerator if no block is given.
+ *
+ * IO#each is an alias for IO#each_line.
+ *
*/
static VALUE
@@ -5217,6 +5235,8 @@ rb_io_ungetc(VALUE io, VALUE c)
* f = File.new('/dev/tty').isatty #=> true
* f.close
*
+ * IO#tty? is an alias for IO#isatty.
+ *
*/
static VALUE
@@ -5277,7 +5297,7 @@ rb_io_close_on_exec_p(VALUE io)
*
* Sets a close-on-exec flag.
*
- * f = File.open(File::NULL)
+ * f = open("/dev/null")
* f.close_on_exec = true
* system("cat", "/proc/self/fd/#{f.fileno}") # cat: /proc/self/fd/3: No such file or directory
* f.closed? #=> false
@@ -5328,7 +5348,7 @@ rb_io_set_close_on_exec(VALUE io, VALUE arg)
#define rb_io_set_close_on_exec rb_f_notimplement
#endif
-#define RUBY_IO_EXTERNAL_P(f) ((f)->mode & FMODE_EXTERNAL)
+#define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
#define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv))
static VALUE
@@ -5447,7 +5467,7 @@ static void clear_codeconv(rb_io_t *fptr);
static void
fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl,
- struct rb_io_close_wait_list *busy)
+ struct ccan_list_head *busy)
{
VALUE error = Qnil;
int fd = fptr->fd;
@@ -5478,7 +5498,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl,
int done = 0;
- if (RUBY_IO_EXTERNAL_P(fptr) || fd <= 2) {
+ if (IS_PREP_STDIO(fptr) || fd <= 2) {
// Need to keep FILE objects of stdin, stdout and stderr, so we are done:
done = 1;
}
@@ -5490,7 +5510,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl,
// Ensure waiting_fd users do not hit EBADF.
if (busy) {
// Wait for them to exit before we call close().
- rb_notify_fd_close_wait(busy);
+ do rb_thread_schedule(); while (!ccan_list_empty(busy));
}
// Disable for now.
@@ -5592,9 +5612,12 @@ clear_codeconv(rb_io_t *fptr)
clear_writeconv(fptr);
}
-static void
-rb_io_fptr_cleanup_all(rb_io_t *fptr)
+void
+rb_io_fptr_finalize_internal(void *ptr)
{
+ rb_io_t *fptr = ptr;
+
+ if (!ptr) return;
fptr->pathv = Qnil;
if (0 <= fptr->fd)
rb_io_fptr_cleanup(fptr, TRUE);
@@ -5602,14 +5625,7 @@ rb_io_fptr_cleanup_all(rb_io_t *fptr)
free_io_buffer(&fptr->rbuf);
free_io_buffer(&fptr->wbuf);
clear_codeconv(fptr);
-}
-
-void
-rb_io_fptr_finalize_internal(void *ptr)
-{
- if (!ptr) return;
- rb_io_fptr_cleanup_all(ptr);
- free(ptr);
+ free(fptr);
}
#undef rb_io_fptr_finalize
@@ -5645,14 +5661,16 @@ rb_io_memsize(const rb_io_t *fptr)
# define KEEPGVL FALSE
#endif
+int rb_notify_fd_close(int fd, struct ccan_list_head *);
static rb_io_t *
io_close_fptr(VALUE io)
{
rb_io_t *fptr;
VALUE write_io;
rb_io_t *write_fptr;
- struct rb_io_close_wait_list busy;
+ struct ccan_list_head busy;
+ ccan_list_head_init(&busy);
write_io = GetWriteIO(io);
if (io != write_io) {
write_fptr = RFILE(write_io)->fptr;
@@ -5789,8 +5807,10 @@ io_close(VALUE io)
*
* Related: IO#close_read, IO#close_write, IO#close.
*/
-VALUE
-rb_io_closed_p(VALUE io)
+
+
+static VALUE
+rb_io_closed(VALUE io)
{
rb_io_t *fptr;
VALUE write_io;
@@ -6088,37 +6108,28 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
return str;
}
+#if defined(HAVE_PREAD) || defined(HAVE_PWRITE)
struct prdwr_internal_arg {
- VALUE io;
int fd;
void *buf;
size_t count;
rb_off_t offset;
};
+#endif /* HAVE_PREAD || HAVE_PWRITE */
+#if defined(HAVE_PREAD)
static VALUE
-internal_pread_func(void *_arg)
+internal_pread_func(void *arg)
{
- struct prdwr_internal_arg *arg = _arg;
-
- return (VALUE)pread(arg->fd, arg->buf, arg->count, arg->offset);
+ struct prdwr_internal_arg *p = arg;
+ return (VALUE)pread(p->fd, p->buf, p->count, p->offset);
}
static VALUE
-pread_internal_call(VALUE _arg)
+pread_internal_call(VALUE arg)
{
- struct prdwr_internal_arg *arg = (struct prdwr_internal_arg *)_arg;
-
- VALUE scheduler = rb_fiber_scheduler_current();
- if (scheduler != Qnil) {
- VALUE result = rb_fiber_scheduler_io_pread_memory(scheduler, arg->io, arg->offset, arg->buf, arg->count, 0);
-
- if (!UNDEF_P(result)) {
- return rb_fiber_scheduler_io_result_apply(result);
- }
- }
-
- return rb_thread_io_blocking_call(internal_pread_func, arg, arg->fd, RB_WAITFD_IN);
+ struct prdwr_internal_arg *p = (struct prdwr_internal_arg *)arg;
+ return rb_thread_io_blocking_region(internal_pread_func, p, p->fd);
}
/*
@@ -6155,7 +6166,7 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
VALUE len, offset, str;
rb_io_t *fptr;
ssize_t n;
- struct prdwr_internal_arg arg = {.io = io};
+ struct prdwr_internal_arg arg;
int shrinkable;
rb_scan_args(argc, argv, "21", &len, &offset, &str);
@@ -6185,21 +6196,15 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
return str;
}
+#else
+# define rb_io_pread rb_f_notimplement
+#endif /* HAVE_PREAD */
+#if defined(HAVE_PWRITE)
static VALUE
-internal_pwrite_func(void *_arg)
+internal_pwrite_func(void *ptr)
{
- struct prdwr_internal_arg *arg = _arg;
-
- VALUE scheduler = rb_fiber_scheduler_current();
- if (scheduler != Qnil) {
- VALUE result = rb_fiber_scheduler_io_pwrite_memory(scheduler, arg->io, arg->offset, arg->buf, arg->count, 0);
-
- if (!UNDEF_P(result)) {
- return rb_fiber_scheduler_io_result_apply(result);
- }
- }
-
+ struct prdwr_internal_arg *arg = ptr;
return (VALUE)pwrite(arg->fd, arg->buf, arg->count, arg->offset);
}
@@ -6234,7 +6239,7 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
{
rb_io_t *fptr;
ssize_t n;
- struct prdwr_internal_arg arg = {.io = io};
+ struct prdwr_internal_arg arg;
VALUE tmp;
if (!RB_TYPE_P(str, T_STRING))
@@ -6251,12 +6256,15 @@ rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
arg.buf = RSTRING_PTR(tmp);
arg.count = (size_t)RSTRING_LEN(tmp);
- n = (ssize_t)rb_thread_io_blocking_call(internal_pwrite_func, &arg, fptr->fd, RB_WAITFD_OUT);
+ n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
if (n < 0) rb_sys_fail_path(fptr->pathv);
rb_str_tmp_frozen_release(str, tmp);
return SSIZET2NUM(n);
}
+#else
+# define rb_io_pwrite rb_f_notimplement
+#endif /* HAVE_PWRITE */
VALUE
rb_io_binmode(VALUE io)
@@ -6741,6 +6749,8 @@ rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2
return extracted;
}
+typedef struct rb_io_enc_t convconfig_t;
+
static void
validate_enc_binmode(int *fmode_p, int ecflags, rb_encoding *enc, rb_encoding *enc2)
{
@@ -6799,7 +6809,7 @@ extract_binmode(VALUE opthash, int *fmode)
void
rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
- int *oflags_p, int *fmode_p, struct rb_io_encoding *convconfig_p)
+ int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
{
VALUE vmode;
int oflags, fmode;
@@ -6970,7 +6980,7 @@ rb_sysopen_internal(struct sysopen_struct *data)
static int
rb_sysopen(VALUE fname, int oflags, mode_t perm)
{
- int fd = -1;
+ int fd;
struct sysopen_struct data;
data.fname = rb_str_encode_ospath(fname);
@@ -6978,14 +6988,21 @@ rb_sysopen(VALUE fname, int oflags, mode_t perm)
data.oflags = oflags;
data.perm = perm;
- TRY_WITH_GC((fd = rb_sysopen_internal(&data)) >= 0) {
- rb_syserr_fail_path(first_errno, fname);
+ fd = rb_sysopen_internal(&data);
+ if (fd < 0) {
+ int e = errno;
+ if (rb_gc_for_fd(e)) {
+ fd = rb_sysopen_internal(&data);
+ }
+ if (fd < 0) {
+ rb_syserr_fail_path(e, fname);
+ }
}
return fd;
}
-static inline FILE *
-fdopen_internal(int fd, const char *modestr)
+FILE *
+rb_fdopen(int fd, const char *modestr)
{
FILE *file;
@@ -6994,22 +7011,26 @@ fdopen_internal(int fd, const char *modestr)
#endif
file = fdopen(fd, modestr);
if (!file) {
+ int e = errno;
+#if defined(__sun)
+ if (e == 0) {
+ rb_gc();
+ errno = 0;
+ file = fdopen(fd, modestr);
+ }
+ else
+#endif
+ if (rb_gc_for_fd(e)) {
+ file = fdopen(fd, modestr);
+ }
+ if (!file) {
#ifdef _WIN32
- if (errno == 0) errno = EINVAL;
+ if (e == 0) e = EINVAL;
#elif defined(__sun)
- if (errno == 0) errno = EMFILE;
+ if (e == 0) e = EMFILE;
#endif
- }
- return file;
-}
-
-FILE *
-rb_fdopen(int fd, const char *modestr)
-{
- FILE *file = 0;
-
- TRY_WITH_GC((file = fdopen_internal(fd, modestr)) != 0) {
- rb_syserr_fail(first_errno, 0);
+ rb_syserr_fail(e, 0);
+ }
}
/* xxx: should be _IONBF? A buffer in FILE may have trouble. */
@@ -7116,11 +7137,11 @@ io_set_encoding_by_bom(VALUE io)
static VALUE
rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode,
- const struct rb_io_encoding *convconfig, mode_t perm)
+ const convconfig_t *convconfig, mode_t perm)
{
VALUE pathv;
rb_io_t *fptr;
- struct rb_io_encoding cc;
+ convconfig_t cc;
if (!convconfig) {
/* Set to default encodings */
rb_io_ext_int_to_encs(NULL, NULL, &cc.enc, &cc.enc2, fmode);
@@ -7154,7 +7175,7 @@ rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
{
int fmode = rb_io_modestr_fmode(modestr);
const char *p = strchr(modestr, ':');
- struct rb_io_encoding convconfig;
+ convconfig_t convconfig;
if (p) {
parse_mode_enc(p+1, rb_usascii_encoding(),
@@ -7262,7 +7283,7 @@ static void
fptr_copy_finalizer(rb_io_t *fptr, const rb_io_t *orig)
{
#if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK)
- void (*const old_finalize)(struct rb_io*,int) = fptr->finalize;
+ void (*const old_finalize)(struct rb_io_t*,int) = fptr->finalize;
if (old_finalize == orig->finalize) return;
#endif
@@ -7300,7 +7321,12 @@ int
rb_pipe(int *pipes)
{
int ret;
- TRY_WITH_GC((ret = rb_cloexec_pipe(pipes)) >= 0);
+ ret = rb_cloexec_pipe(pipes);
+ if (ret < 0) {
+ if (rb_gc_for_fd(errno)) {
+ ret = rb_cloexec_pipe(pipes);
+ }
+ }
if (ret == 0) {
rb_update_max_fd(pipes[0]);
rb_update_max_fd(pipes[1]);
@@ -7462,7 +7488,7 @@ char *rb_execarg_commandline(const struct rb_execarg *eargp, VALUE *prog);
#ifndef __EMSCRIPTEN__
static VALUE
pipe_open(VALUE execarg_obj, const char *modestr, int fmode,
- const struct rb_io_encoding *convconfig)
+ const convconfig_t *convconfig)
{
struct rb_execarg *eargp = NIL_P(execarg_obj) ? NULL : rb_execarg_get(execarg_obj);
VALUE prog = eargp ? (eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name) : Qfalse ;
@@ -7691,7 +7717,7 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode,
#else
static VALUE
pipe_open(VALUE execarg_obj, const char *modestr, int fmode,
- const struct rb_io_encoding *convconfig)
+ const convconfig_t *convconfig)
{
rb_raise(rb_eNotImpError, "popen() is not available");
}
@@ -7713,7 +7739,7 @@ is_popen_fork(VALUE prog)
static VALUE
pipe_open_s(VALUE prog, const char *modestr, int fmode,
- const struct rb_io_encoding *convconfig)
+ const convconfig_t *convconfig)
{
int argc = 1;
VALUE *argv = &prog;
@@ -7922,7 +7948,7 @@ rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt)
const char *modestr;
VALUE tmp, execarg_obj = Qnil;
int oflags, fmode;
- struct rb_io_encoding convconfig;
+ convconfig_t convconfig;
tmp = rb_check_array_type(pname);
if (!NIL_P(tmp)) {
@@ -7959,7 +7985,7 @@ popen_finish(VALUE port, VALUE klass)
if (NIL_P(port)) {
/* child */
if (rb_block_given_p()) {
- rb_yield(Qnil);
+ rb_protect(rb_yield, Qnil, NULL);
rb_io_flush(rb_ractor_stdout());
rb_io_flush(rb_ractor_stderr());
_exit(0);
@@ -7973,64 +7999,10 @@ popen_finish(VALUE port, VALUE klass)
return port;
}
-#if defined(HAVE_WORKING_FORK) && !defined(__EMSCRIPTEN__)
-struct popen_writer_arg {
- char *const *argv;
- struct popen_arg popen;
-};
-
-static int
-exec_popen_writer(void *arg, char *errmsg, size_t buflen)
-{
- struct popen_writer_arg *pw = arg;
- pw->popen.modef = FMODE_WRITABLE;
- popen_redirect(&pw->popen);
- execv(pw->argv[0], pw->argv);
- strlcpy(errmsg, strerror(errno), buflen);
- return -1;
-}
-#endif
-
-FILE *
-ruby_popen_writer(char *const *argv, rb_pid_t *pid)
-{
-#if (defined(HAVE_WORKING_FORK) && !defined(__EMSCRIPTEN__)) || defined(_WIN32)
-# ifdef HAVE_WORKING_FORK
- struct popen_writer_arg pw;
- int *const write_pair = pw.popen.pair;
-# else
- int write_pair[2];
-# endif
-
- int result = rb_cloexec_pipe(write_pair);
- *pid = -1;
- if (result == 0) {
-# ifdef HAVE_WORKING_FORK
- pw.argv = argv;
- int status;
- char errmsg[80] = {'\0'};
- *pid = rb_fork_async_signal_safe(&status, exec_popen_writer, &pw, Qnil, errmsg, sizeof(errmsg));
-# else
- *pid = rb_w32_uspawn_process(P_NOWAIT, argv[0], argv, write_pair[0], -1, -1, 0);
- const char *errmsg = (*pid < 0) ? strerror(errno) : NULL;
-# endif
- close(write_pair[0]);
- if (*pid < 0) {
- close(write_pair[1]);
- fprintf(stderr, "ruby_popen_writer(%s): %s\n", argv[0], errmsg);
- }
- else {
- return fdopen(write_pair[1], "w");
- }
- }
-#endif
- return NULL;
-}
-
static void
rb_scan_open_args(int argc, const VALUE *argv,
VALUE *fname_p, int *oflags_p, int *fmode_p,
- struct rb_io_encoding *convconfig_p, mode_t *perm_p)
+ convconfig_t *convconfig_p, mode_t *perm_p)
{
VALUE opt, fname, vmode, vperm;
int oflags, fmode;
@@ -8054,7 +8026,7 @@ rb_open_file(int argc, const VALUE *argv, VALUE io)
{
VALUE fname;
int oflags, fmode;
- struct rb_io_encoding convconfig;
+ convconfig_t convconfig;
mode_t perm;
rb_scan_open_args(argc, argv, &fname, &oflags, &fmode, &convconfig, &perm);
@@ -8070,11 +8042,11 @@ rb_open_file(int argc, const VALUE *argv, VALUE io)
* File.open(path, mode = 'r', perm = 0666, **opts) -> file
* File.open(path, mode = 'r', perm = 0666, **opts) {|f| ... } -> object
*
- * Creates a new File object, via File.new with the given arguments.
+ * Creates a new \File object, via File.new with the given arguments.
*
- * With no block given, returns the File object.
+ * With no block given, returns the \File object.
*
- * With a block given, calls the block with the File object
+ * With a block given, calls the block with the \File object
* and returns the block's value.
*
*/
@@ -8172,10 +8144,20 @@ check_pipe_command(VALUE filename_or_command)
* open(path, mode = 'r', perm = 0666, **opts) -> io or nil
* open(path, mode = 'r', perm = 0666, **opts) {|io| ... } -> obj
*
- * Creates an IO object connected to the given file.
+ * Creates an IO object connected to the given stream, file, or subprocess.
*
- * This method has potential security vulnerabilities if called with untrusted input;
- * see {Command Injection}[rdoc-ref:command_injection.rdoc].
+ * Required string argument +path+ determines which of the following occurs:
+ *
+ * - The file at the specified +path+ is opened.
+ * - The process forks.
+ * - A subprocess is created.
+ *
+ * Each of these is detailed below.
+ *
+ * <b>File Opened</b>
+
+ * If +path+ does _not_ start with a pipe character (<tt>'|'</tt>),
+ * a file stream is opened with <tt>File.open(path, mode, perm, **opts)</tt>.
*
* With no block given, file stream is returned:
*
@@ -8192,6 +8174,67 @@ check_pipe_command(VALUE filename_or_command)
*
* See File.open for details.
*
+ * <b>Process Forked</b>
+ *
+ * If +path+ is the 2-character string <tt>'|-'</tt>, the process forks
+ * and the child process is connected to the parent.
+ *
+ * With no block given:
+ *
+ * io = open('|-')
+ * if io
+ * $stderr.puts "In parent, child pid is #{io.pid}."
+ * else
+ * $stderr.puts "In child, pid is #{$$}."
+ * end
+ *
+ * Output:
+ *
+ * In parent, child pid is 27903.
+ * In child, pid is 27903.
+ *
+ * With a block given:
+ *
+ * open('|-') do |io|
+ * if io
+ * $stderr.puts "In parent, child pid is #{io.pid}."
+ * else
+ * $stderr.puts "In child, pid is #{$$}."
+ * end
+ * end
+ *
+ * Output:
+ *
+ * In parent, child pid is 28427.
+ * In child, pid is 28427.
+ *
+ * <b>Subprocess Created</b>
+ *
+ * If +path+ is <tt>'|command'</tt> (<tt>'command' != '-'</tt>),
+ * a new subprocess runs the command; its open stream is returned.
+ * Note that the command may be processed by shell if it contains
+ * shell metacharacters.
+ *
+ * With no block given:
+ *
+ * io = open('|echo "Hi!"') # => #<IO:fd 12>
+ * print io.gets
+ * io.close
+ *
+ * Output:
+ *
+ * "Hi!"
+ *
+ * With a block given, calls the block with the stream, then closes the stream:
+ *
+ * open('|echo "Hi!"') do |io|
+ * print io.gets
+ * end
+ *
+ * Output:
+ *
+ * "Hi!"
+ *
*/
static VALUE
@@ -8214,8 +8257,6 @@ rb_f_open(int argc, VALUE *argv, VALUE _)
else {
VALUE cmd = check_pipe_command(tmp);
if (!NIL_P(cmd)) {
- // TODO: when removed in 4.0, update command_injection.rdoc
- rb_warn_deprecated_to_remove_at(4.0, "Calling Kernel#open with a leading '|'", "IO.popen");
argv[0] = cmd;
return rb_io_s_popen(argc, argv, rb_cIO);
}
@@ -8233,13 +8274,13 @@ rb_f_open(int argc, VALUE *argv, VALUE _)
return rb_io_s_open(argc, argv, rb_cFile);
}
-static VALUE rb_io_open_generic(VALUE, VALUE, int, int, const struct rb_io_encoding *, mode_t);
+static VALUE rb_io_open_generic(VALUE, VALUE, int, int, const convconfig_t *, mode_t);
static VALUE
rb_io_open(VALUE io, VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
{
int oflags, fmode;
- struct rb_io_encoding convconfig;
+ convconfig_t convconfig;
mode_t perm;
rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, &convconfig);
@@ -8249,12 +8290,10 @@ rb_io_open(VALUE io, VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
static VALUE
rb_io_open_generic(VALUE klass, VALUE filename, int oflags, int fmode,
- const struct rb_io_encoding *convconfig, mode_t perm)
+ const convconfig_t *convconfig, mode_t perm)
{
VALUE cmd;
if (klass == rb_cIO && !NIL_P(cmd = check_pipe_command(filename))) {
- // TODO: when removed in 4.0, update command_injection.rdoc
- rb_warn_deprecated_to_remove_at(4.0, "IO process creation with a leading '|'", "IO.popen");
return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, convconfig);
}
else {
@@ -8275,7 +8314,7 @@ io_reopen(VALUE io, VALUE nfile)
GetOpenFile(nfile, orig);
if (fptr == orig) return io;
- if (RUBY_IO_EXTERNAL_P(fptr)) {
+ if (IS_PREP_STDIO(fptr)) {
if ((fptr->stdio_file == stdin && !(orig->mode & FMODE_READABLE)) ||
(fptr->stdio_file == stdout && !(orig->mode & FMODE_WRITABLE)) ||
(fptr->stdio_file == stderr && !(orig->mode & FMODE_WRITABLE))) {
@@ -8301,17 +8340,17 @@ io_reopen(VALUE io, VALUE nfile)
}
/* copy rb_io_t structure */
- fptr->mode = orig->mode | (fptr->mode & FMODE_EXTERNAL);
+ fptr->mode = orig->mode | (fptr->mode & FMODE_PREP);
fptr->pid = orig->pid;
fptr->lineno = orig->lineno;
if (RTEST(orig->pathv)) fptr->pathv = orig->pathv;
- else if (!RUBY_IO_EXTERNAL_P(fptr)) fptr->pathv = Qnil;
+ else if (!IS_PREP_STDIO(fptr)) fptr->pathv = Qnil;
fptr_copy_finalizer(fptr, orig);
fd = fptr->fd;
fd2 = orig->fd;
if (fd != fd2) {
- if (RUBY_IO_EXTERNAL_P(fptr) || fd <= 2 || !fptr->stdio_file) {
+ if (IS_PREP_STDIO(fptr) || fd <= 2 || !fptr->stdio_file) {
/* need to keep FILE objects of stdin, stdout and stderr */
if (rb_cloexec_dup2(fd2, fd) < 0)
rb_sys_fail_path(orig->pathv);
@@ -8416,10 +8455,10 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
if (!NIL_P(nmode) || !NIL_P(opt)) {
int fmode;
- struct rb_io_encoding convconfig;
+ convconfig_t convconfig;
rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
- if (RUBY_IO_EXTERNAL_P(fptr) &&
+ if (IS_PREP_STDIO(fptr) &&
((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) !=
(fptr->mode & FMODE_READWRITE)) {
rb_raise(rb_eArgError,
@@ -8498,7 +8537,7 @@ rb_io_init_copy(VALUE dest, VALUE io)
rb_io_flush(io);
/* copy rb_io_t structure */
- fptr->mode = orig->mode & ~FMODE_EXTERNAL;
+ fptr->mode = orig->mode & ~FMODE_PREP;
fptr->encs = orig->encs;
fptr->pid = orig->pid;
fptr->lineno = orig->lineno;
@@ -8862,9 +8901,9 @@ io_puts_ary(VALUE ary, VALUE out, int recur)
*
* Treatment for each object:
*
- * - String: writes the string.
+ * - \String: writes the string.
* - Neither string nor array: writes <tt>object.to_s</tt>.
- * - Array: writes each element of the array; arrays may be nested.
+ * - \Array: writes each element of the array; arrays may be nested.
*
* To keep these examples brief, we define this helper method:
*
@@ -9020,10 +9059,6 @@ rb_p_result(int argc, const VALUE *argv)
* 0..4
* [0..4, 0..4, 0..4]
*
- * Kernel#p is designed for debugging purposes.
- * Ruby implementations may define Kernel#p to be uninterruptible
- * in whole or in part.
- * On CRuby, Kernel#p's writing of data is uninterruptible.
*/
static VALUE
@@ -9177,78 +9212,26 @@ stderr_getter(ID id, VALUE *ptr)
}
static VALUE
-allocate_and_open_new_file(VALUE klass)
-{
- VALUE self = io_alloc(klass);
- rb_io_make_open_file(self);
- return self;
-}
-
-VALUE
-rb_io_open_descriptor(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, struct rb_io_encoding *encoding)
-{
- int state;
- VALUE self = rb_protect(allocate_and_open_new_file, klass, &state);
- if (state) {
- /* if we raised an exception allocating an IO object, but the caller
- intended to transfer ownership of this FD to us, close the fd before
- raising the exception. Otherwise, we would leak a FD - the caller
- expects GC to close the file, but we never got around to assigning
- it to a rb_io. */
- if (!(mode & FMODE_EXTERNAL)) {
- maygvl_close(descriptor, 0);
- }
- rb_jump_tag(state);
- }
-
-
- rb_io_t *io = RFILE(self)->fptr;
- io->self = self;
- io->fd = descriptor;
- io->mode = mode;
-
- /* At this point, Ruby fully owns the descriptor, and will close it when
- the IO gets GC'd (unless FMODE_EXTERNAL was set), no matter what happens
- in the rest of this method. */
-
- if (NIL_P(path)) {
- io->pathv = Qnil;
- }
- else {
- StringValue(path);
- io->pathv = rb_str_new_frozen(path);
- }
-
- io->timeout = timeout;
-
- if (encoding) {
- io->encs = *encoding;
- }
-
- rb_update_max_fd(descriptor);
-
- return self;
-}
-
-static VALUE
prep_io(int fd, int fmode, VALUE klass, const char *path)
{
- VALUE path_value = Qnil;
- if (path) {
- path_value = rb_obj_freeze(rb_str_new_cstr(path));
- }
-
- VALUE self = rb_io_open_descriptor(klass, fd, fmode, path_value, Qnil, NULL);
- rb_io_t*io = RFILE(self)->fptr;
+ rb_io_t *fp;
+ VALUE io = io_alloc(klass);
- if (!io_check_tty(io)) {
+ MakeOpenFile(io, fp);
+ fp->self = io;
+ fp->fd = fd;
+ fp->mode = fmode;
+ fp->timeout = Qnil;
+ if (!io_check_tty(fp)) {
#ifdef __CYGWIN__
- io->mode |= FMODE_BINMODE;
+ fp->mode |= FMODE_BINMODE;
setmode(fd, O_BINARY);
#endif
}
+ if (path) fp->pathv = rb_obj_freeze(rb_str_new_cstr(path));
+ rb_update_max_fd(fd);
- return self;
+ return io;
}
VALUE
@@ -9264,7 +9247,7 @@ static VALUE
prep_stdio(FILE *f, int fmode, VALUE klass, const char *path)
{
rb_io_t *fptr;
- VALUE io = prep_io(fileno(f), fmode|FMODE_EXTERNAL|DEFAULT_TEXTMODE, klass, path);
+ VALUE io = prep_io(fileno(f), fmode|FMODE_PREP|DEFAULT_TEXTMODE, klass, path);
GetOpenFile(io, fptr);
fptr->encs.ecflags |= ECONV_DEFAULT_NEWLINE_DECORATOR;
@@ -9308,7 +9291,7 @@ rb_io_stdio_file(rb_io_t *fptr)
}
static inline void
-rb_io_buffer_init(struct rb_io_internal_buffer *buf)
+rb_io_buffer_init(rb_io_buffer_t *buf)
{
buf->ptr = NULL;
buf->off = 0;
@@ -9411,7 +9394,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
VALUE fnum, vmode;
rb_io_t *fp;
int fd, fmode, oflags = O_RDONLY;
- struct rb_io_encoding convconfig;
+ convconfig_t convconfig;
VALUE opt;
#if defined(HAVE_FCNTL) && defined(F_GETFL)
int ofmode;
@@ -9448,7 +9431,7 @@ rb_io_initialize(int argc, VALUE *argv, VALUE io)
if (!NIL_P(opt)) {
if (rb_hash_aref(opt, sym_autoclose) == Qfalse) {
- fmode |= FMODE_EXTERNAL;
+ fmode |= FMODE_PREP;
}
path = rb_hash_aref(opt, RB_ID2SYM(idPath));
@@ -9527,9 +9510,9 @@ rb_io_set_encoding_by_bom(VALUE io)
* File.new(path, mode = 'r', perm = 0666, **opts) -> file
*
* Opens the file at the given +path+ according to the given +mode+;
- * creates and returns a new File object for that file.
+ * creates and returns a new \File object for that file.
*
- * The new File object is buffered mode (or non-sync mode), unless
+ * The new \File object is buffered mode (or non-sync mode), unless
* +filename+ is a tty.
* See IO#flush, IO#fsync, IO#fdatasync, and IO#sync=.
*
@@ -9617,7 +9600,7 @@ rb_io_s_for_fd(int argc, VALUE *argv, VALUE klass)
* ios.autoclose? -> true or false
*
* Returns +true+ if the underlying file descriptor of _ios_ will be
- * closed at its finalization or at calling #close, otherwise +false+.
+ * closed automatically at its finalization, otherwise +false+.
*/
static VALUE
@@ -9625,7 +9608,7 @@ rb_io_autoclose_p(VALUE io)
{
rb_io_t *fptr = RFILE(io)->fptr;
rb_io_check_closed(fptr);
- return RBOOL(!(fptr->mode & FMODE_EXTERNAL));
+ return RBOOL(!(fptr->mode & FMODE_PREP));
}
/*
@@ -9634,14 +9617,14 @@ rb_io_autoclose_p(VALUE io)
*
* Sets auto-close flag.
*
- * f = File.open(File::NULL)
- * IO.for_fd(f.fileno).close
- * f.gets # raises Errno::EBADF
+ * f = open("/dev/null")
+ * IO.for_fd(f.fileno)
+ * # ...
+ * f.gets # may cause Errno::EBADF
*
- * f = File.open(File::NULL)
- * g = IO.for_fd(f.fileno)
- * g.autoclose = false
- * g.close
+ * f = open("/dev/null")
+ * IO.for_fd(f.fileno).autoclose = false
+ * # ...
* f.gets # won't cause Errno::EBADF
*/
@@ -9651,9 +9634,9 @@ rb_io_set_autoclose(VALUE io, VALUE autoclose)
rb_io_t *fptr;
GetOpenFile(io, fptr);
if (!RTEST(autoclose))
- fptr->mode |= FMODE_EXTERNAL;
+ fptr->mode |= FMODE_PREP;
else
- fptr->mode &= ~FMODE_EXTERNAL;
+ fptr->mode &= ~FMODE_PREP;
return autoclose;
}
@@ -9786,7 +9769,7 @@ wait_mode_sym(VALUE mode)
rb_raise(rb_eArgError, "unsupported mode: %"PRIsVALUE, mode);
}
-static inline enum rb_io_event
+static inline rb_io_event_t
io_event_from_value(VALUE value)
{
int events = RB_NUM2INT(value);
@@ -9817,7 +9800,7 @@ static VALUE
io_wait(int argc, VALUE *argv, VALUE io)
{
VALUE timeout = Qundef;
- enum rb_io_event events = 0;
+ rb_io_event_t events = 0;
int return_io = 0;
// The documented signature for this method is actually incorrect.
@@ -10471,21 +10454,19 @@ rb_f_readlines(int argc, VALUE *argv, VALUE recv)
/*
* call-seq:
- * ARGF.readlines(sep = $/, chomp: false) -> array
- * ARGF.readlines(limit, chomp: false) -> array
- * ARGF.readlines(sep, limit, chomp: false) -> array
+ * ARGF.readlines(sep = $/) -> array
+ * ARGF.readlines(limit) -> array
+ * ARGF.readlines(sep, limit) -> array
*
- * ARGF.to_a(sep = $/, chomp: false) -> array
- * ARGF.to_a(limit, chomp: false) -> array
- * ARGF.to_a(sep, limit, chomp: false) -> array
+ * ARGF.to_a(sep = $/) -> array
+ * ARGF.to_a(limit) -> array
+ * ARGF.to_a(sep, limit) -> array
*
* Reads each file in ARGF in its entirety, returning an Array containing
* lines from the files. Lines are assumed to be separated by _sep_.
*
* lines = ARGF.readlines
* lines[0] #=> "This is line one\n"
- *
- * See +IO.readlines+ for a full description of all options.
*/
static VALUE
argf_readlines(int argc, VALUE *argv, VALUE argf)
@@ -10547,7 +10528,8 @@ rb_f_backquote(VALUE obj, VALUE str)
GetOpenFile(port, fptr);
result = read_all(fptr, remain_size(fptr), Qnil);
rb_io_close(port);
- rb_io_fptr_cleanup_all(fptr);
+ RFILE(port)->fptr = NULL;
+ rb_io_fptr_finalize(fptr);
RB_GC_GUARD(port);
return result;
@@ -11448,7 +11430,7 @@ rb_fcntl(VALUE io, VALUE req, VALUE arg)
* a file-oriented I/O stream. Arguments and results are platform
* dependent.
*
- * If +argument+ is a number, its value is passed directly;
+ * If +argument is a number, its value is passed directly;
* if it is a string, it is interpreted as a binary sequence of bytes.
* (Array#pack might be a useful way to build this string.)
*
@@ -11636,11 +11618,6 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
enc2 = NULL;
}
}
- if (enc2 == rb_ascii8bit_encoding()) {
- /* If external is ASCII-8BIT, no transcoding */
- enc = enc2;
- enc2 = NULL;
- }
SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags);
ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
}
@@ -11701,9 +11678,9 @@ pipe_pair_close(VALUE rw)
* IO.pipe(**opts) -> [read_io, write_io]
* IO.pipe(enc, **opts) -> [read_io, write_io]
* IO.pipe(ext_enc, int_enc, **opts) -> [read_io, write_io]
- * IO.pipe(**opts) {|read_io, write_io| ...} -> object
- * IO.pipe(enc, **opts) {|read_io, write_io| ...} -> object
- * IO.pipe(ext_enc, int_enc, **opts) {|read_io, write_io| ...} -> object
+ * IO.pipe(**opts) {|read_io, write_io] ...} -> object
+ * IO.pipe(enc, **opts) {|read_io, write_io] ...} -> object
+ * IO.pipe(ext_enc, int_enc, **opts) {|read_io, write_io] ...} -> object
*
* Creates a pair of pipe endpoints, +read_io+ and +write_io+,
* connected to each other.
@@ -11914,6 +11891,9 @@ io_s_foreach(VALUE v)
* IO.foreach(path, sep = $/, **opts) {|line| block } -> nil
* IO.foreach(path, limit, **opts) {|line| block } -> nil
* IO.foreach(path, sep, limit, **opts) {|line| block } -> nil
+ * IO.foreach(command, sep = $/, **opts) {|line| block } -> nil
+ * IO.foreach(command, limit, **opts) {|line| block } -> nil
+ * IO.foreach(command, sep, limit, **opts) {|line| block } -> nil
* IO.foreach(...) -> an_enumerator
*
* Calls the block with each successive line read from the stream.
@@ -11922,7 +11902,16 @@ io_s_foreach(VALUE v)
* this method has potential security vulnerabilities if called with untrusted input;
* see {Command Injection}[rdoc-ref:command_injection.rdoc].
*
- * The first argument must be a string that is the path to a file.
+ * The first argument must be a string that is one of the following:
+ *
+ * - Path: if +self+ is a subclass of \IO (\File, for example),
+ * or if the string _does_ _not_ start with the pipe character (<tt>'|'</tt>),
+ * the string is the path to a file.
+ * - Command: if +self+ is the class \IO,
+ * and if the string starts with the pipe character,
+ * the rest of the string is a command to be executed as a subprocess.
+ * This usage has potential security vulnerabilities if called with untrusted input;
+ * see {Command Injection}[rdoc-ref:command_injection.rdoc].
*
* With only argument +path+ given, parses lines from the file at the given +path+,
* as determined by the default line separator,
@@ -11983,7 +11972,7 @@ io_s_foreach(VALUE v)
*
* - {Open Options}[rdoc-ref:IO@Open+Options].
* - {Encoding options}[rdoc-ref:encodings.rdoc@Encoding+Options].
- * - {Line Options}[rdoc-ref:IO@Line+IO].
+ * - {Line Options}[rdoc-ref:IO@Line+Options].
*
* Returns an Enumerator if no block is given.
*
@@ -12016,6 +12005,9 @@ io_s_readlines(VALUE v)
/*
* call-seq:
+ * IO.readlines(command, sep = $/, **opts) -> array
+ * IO.readlines(command, limit, **opts) -> array
+ * IO.readlines(command, sep, limit, **opts) -> array
* IO.readlines(path, sep = $/, **opts) -> array
* IO.readlines(path, limit, **opts) -> array
* IO.readlines(path, sep, limit, **opts) -> array
@@ -12026,7 +12018,19 @@ io_s_readlines(VALUE v)
* this method has potential security vulnerabilities if called with untrusted input;
* see {Command Injection}[rdoc-ref:command_injection.rdoc].
*
- * The first argument must be a string that is the path to a file.
+ * The first argument must be a string;
+ * its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
+ *
+ * - If so (and if +self+ is \IO),
+ * the rest of the string is a command to be executed as a subprocess.
+ * - Otherwise, the string is the path to a file.
+ *
+ * With only argument +command+ given, executes the command in a shell,
+ * parses its $stdout into lines, as determined by the default line separator,
+ * and returns those lines in an array:
+ *
+ * IO.readlines('| cat t.txt')
+ * # => ["First line\n", "Second line\n", "\n", "Third line\n", "Fourth line\n"]
*
* With only argument +path+ given, parses lines from the file at the given +path+,
* as determined by the default line separator,
@@ -12035,6 +12039,8 @@ io_s_readlines(VALUE v)
* IO.readlines('t.txt')
* # => ["First line\n", "Second line\n", "\n", "Third line\n", "Fourth line\n"]
*
+ * For both forms, command and path, the remaining arguments are the same.
+ *
* With argument +sep+ given, parses lines as determined by that line separator
* (see {Line Separator}[rdoc-ref:IO@Line+Separator]):
*
@@ -12064,7 +12070,7 @@ io_s_readlines(VALUE v)
*
* - {Open Options}[rdoc-ref:IO@Open+Options].
* - {Encoding options}[rdoc-ref:encodings.rdoc@Encoding+Options].
- * - {Line Options}[rdoc-ref:IO@Line+IO].
+ * - {Line Options}[rdoc-ref:IO@Line+Options].
*
*/
@@ -12107,6 +12113,7 @@ seek_before_access(VALUE argp)
/*
* call-seq:
+ * IO.read(command, length = nil, offset = 0, **opts) -> string or nil
* IO.read(path, length = nil, offset = 0, **opts) -> string or nil
*
* Opens the stream, reads and returns some or all of its content,
@@ -12116,7 +12123,18 @@ seek_before_access(VALUE argp)
* this method has potential security vulnerabilities if called with untrusted input;
* see {Command Injection}[rdoc-ref:command_injection.rdoc].
*
- * The first argument must be a string that is the path to a file.
+ * The first argument must be a string;
+ * its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
+ *
+ * - If so (and if +self+ is \IO),
+ * the rest of the string is a command to be executed as a subprocess.
+ * - Otherwise, the string is the path to a file.
+ *
+ * With only argument +command+ given, executes the command in a shell,
+ * returns its entire $stdout:
+ *
+ * IO.read('| cat t.txt')
+ * # => "First line\nSecond line\n\nThird line\nFourth line\n"
*
* With only argument +path+ given, reads in text mode and returns the entire content
* of the file at the given path:
@@ -12128,6 +12146,8 @@ seek_before_access(VALUE argp)
* unread when encountering certain special bytes. Consider using
* IO.binread if all bytes in the file should be read.
*
+ * For both forms, command and path, the remaining arguments are the same.
+ *
* With argument +length+, returns +length+ bytes if available:
*
* IO.read('t.txt', 7) # => "First l"
@@ -12151,13 +12171,9 @@ static VALUE
rb_io_s_read(int argc, VALUE *argv, VALUE io)
{
VALUE opt, offset;
- long off;
struct foreach_arg arg;
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
- if (!NIL_P(offset) && (off = NUM2LONG(offset)) < 0) {
- rb_raise(rb_eArgError, "negative offset %ld given", off);
- }
open_key_args(io, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
@@ -12178,6 +12194,7 @@ rb_io_s_read(int argc, VALUE *argv, VALUE io)
/*
* call-seq:
+ * IO.binread(command, length = nil, offset = 0) -> string or nil
* IO.binread(path, length = nil, offset = 0) -> string or nil
*
* Behaves like IO.read, except that the stream is opened in binary mode
@@ -12201,7 +12218,7 @@ rb_io_s_binread(int argc, VALUE *argv, VALUE io)
|O_BINARY
#endif
};
- struct rb_io_encoding convconfig = {NULL, NULL, 0, Qnil};
+ convconfig_t convconfig = {NULL, NULL, 0, Qnil};
rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
FilePathValue(argv[0]);
@@ -12282,6 +12299,7 @@ io_s_write(int argc, VALUE *argv, VALUE klass, int binary)
/*
* call-seq:
+ * IO.write(command, data, **opts) -> integer
* IO.write(path, data, offset = 0, **opts) -> integer
*
* Opens the stream, writes the given +data+ to it,
@@ -12291,9 +12309,25 @@ io_s_write(int argc, VALUE *argv, VALUE klass, int binary)
* this method has potential security vulnerabilities if called with untrusted input;
* see {Command Injection}[rdoc-ref:command_injection.rdoc].
*
- * The first argument must be a string that is the path to a file.
+ * The first argument must be a string;
+ * its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
+ *
+ * - If so (and if +self+ is \IO),
+ * the rest of the string is a command to be executed as a subprocess.
+ * - Otherwise, the string is the path to a file.
+ *
+ * With argument +command+ given, executes the command in a shell,
+ * passes +data+ through standard input, writes its output to $stdout,
+ * and returns the length of the given +data+:
+ *
+ * IO.write('| cat', 'Hello World!') # => 12
*
- * With only argument +path+ given, writes the given +data+ to the file at that path:
+ * Output:
+ *
+ * Hello World!
+ *
+ * With argument +path+ given, writes the given +data+ to the file
+ * at that path:
*
* IO.write('t.tmp', 'abc') # => 3
* File.read('t.tmp') # => "abc"
@@ -12332,6 +12366,7 @@ rb_io_s_write(int argc, VALUE *argv, VALUE io)
/*
* call-seq:
+ * IO.binwrite(command, string, offset = 0) -> integer
* IO.binwrite(path, string, offset = 0) -> integer
*
* Behaves like IO.write, except that the stream is opened in binary mode
@@ -12888,7 +12923,12 @@ maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf,
ss = maygvl_read(has_gvl, stp->src_fptr, buf, len);
}
else {
+#ifdef HAVE_PREAD
ss = pread(stp->src_fptr->fd, buf, len, offset);
+#else
+ stp->notimp = "pread";
+ return -1;
+#endif
}
if (ss == 0) {
return 0;
@@ -13055,6 +13095,7 @@ copy_stream_fallback_body(VALUE arg)
while (1) {
long numwrote;
long l;
+ rb_str_make_independent(buf);
if (stp->copy_length < (rb_off_t)0) {
l = buflen;
}
@@ -13398,12 +13439,10 @@ rb_io_internal_encoding(VALUE io)
*
* See {Encodings}[rdoc-ref:File@Encodings].
*
- * Argument +ext_enc+, if given, must be an Encoding object
- * or a String with the encoding name;
+ * Argument +ext_enc+, if given, must be an Encoding object;
* it is assigned as the encoding for the stream.
*
- * Argument +int_enc+, if given, must be an Encoding object
- * or a String with the encoding name;
+ * Argument +int_enc+, if given, must be an Encoding object;
* it is assigned as the encoding for the internal string.
*
* Argument <tt>'ext_enc:int_enc'</tt>, if given, is a string
@@ -13411,10 +13450,6 @@ rb_io_internal_encoding(VALUE io)
* corresponding Encoding objects are assigned as the external
* and internal encodings for the stream.
*
- * If the external encoding of a string is binary/ASCII-8BIT,
- * the internal encoding of the string is set to nil, since no
- * transcoding is needed.
- *
* Optional keyword arguments +enc_opts+ specify
* {Encoding options}[rdoc-ref:encodings.rdoc@Encoding+Options].
*
@@ -14422,7 +14457,7 @@ argf_closed(VALUE argf)
{
next_argv();
ARGF_FORWARD(0, 0);
- return rb_io_closed_p(ARGF.current_file);
+ return rb_io_closed(ARGF.current_file);
}
/*
@@ -14701,16 +14736,11 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
* ARGV.replace ["file2", "file3"]
* ARGF.read # Returns the contents of file2 and file3
*
- * If +ARGV+ is empty, ARGF acts as if it contained <tt>"-"</tt> that
- * makes ARGF read from STDIN, i.e. the data piped or typed to your
- * script. For example:
+ * If +ARGV+ is empty, ARGF acts as if it contained STDIN, i.e. the data
+ * piped to your script. For example:
*
* $ echo "glark" | ruby -e 'p ARGF.read'
* "glark\n"
- *
- * $ echo Glark > file1
- * $ echo "glark" | ruby -e 'p ARGF.read' -- - file1
- * "glark\nGlark\n"
*/
/*
@@ -14728,7 +14758,7 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
* ARGF is not itself a subclass of \IO.
*
* \Class StringIO provides an IO-like stream that handles a String.
- * StringIO is not itself a subclass of \IO.
+ * \StringIO is not itself a subclass of \IO.
*
* Important objects based on \IO include:
*
@@ -14746,7 +14776,7 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
* - Kernel#open: Returns a new \IO object connected to a given source:
* stream, file, or subprocess.
*
- * Like a File stream, an \IO stream has:
+ * Like a \File stream, an \IO stream has:
*
* - A read/write mode, which may be read-only, write-only, or read/write;
* see {Read/Write Mode}[rdoc-ref:File@Read-2FWrite+Mode].
@@ -14782,7 +14812,7 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
* that determine how a new stream is to be opened:
*
* - +:mode+: Stream mode.
- * - +:flags+: Integer file open flags;
+ * - +:flags+: \Integer file open flags;
* If +mode+ is also given, the two are bitwise-ORed.
* - +:external_encoding+: External encoding for the stream.
* - +:internal_encoding+: Internal encoding for the stream.
@@ -14797,7 +14827,7 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
* #path method.
*
* Also available are the options offered in String#encode,
- * which may control conversion between external and internal encoding.
+ * which may control conversion between external internal encoding.
*
* == Basic \IO
*
@@ -15072,7 +15102,7 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y)
* # => 41
* f.close
*
- * - When a stream is read, <tt>$.</tt> is set to the line number for that stream:
+ * - When a stream is read, <tt>#.</tt> is set to the line number for that stream:
*
* f0 = File.new('t.txt')
* f1 = File.new('t.dat')
@@ -15321,14 +15351,10 @@ Init_IO(void)
rb_cIO = rb_define_class("IO", rb_cObject);
rb_include_module(rb_cIO, rb_mEnumerable);
- /* Can be raised by IO operations when IO#timeout= is set. */
rb_eIOTimeoutError = rb_define_class_under(rb_cIO, "TimeoutError", rb_eIOError);
- /* Readable event mask for IO#wait. */
rb_define_const(rb_cIO, "READABLE", INT2NUM(RUBY_IO_READABLE));
- /* Writable event mask for IO#wait. */
rb_define_const(rb_cIO, "WRITABLE", INT2NUM(RUBY_IO_WRITABLE));
- /* Priority event mask for IO#wait. */
rb_define_const(rb_cIO, "PRIORITY", INT2NUM(RUBY_IO_PRIORITY));
/* exception to wait for reading. see IO.select. */
@@ -15442,6 +15468,7 @@ Init_IO(void)
rb_define_method(rb_cIO, "read", io_read, -1);
rb_define_method(rb_cIO, "write", io_write_m, -1);
rb_define_method(rb_cIO, "gets", rb_io_gets_m, -1);
+ rb_define_method(rb_cIO, "readline", rb_io_readline, -1);
rb_define_method(rb_cIO, "getc", rb_io_getc, 0);
rb_define_method(rb_cIO, "getbyte", rb_io_getbyte, 0);
rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0);
@@ -15476,7 +15503,7 @@ Init_IO(void)
rb_define_method(rb_cIO, "close_on_exec=", rb_io_set_close_on_exec, 1);
rb_define_method(rb_cIO, "close", rb_io_close_m, 0);
- rb_define_method(rb_cIO, "closed?", rb_io_closed_p, 0);
+ rb_define_method(rb_cIO, "closed?", rb_io_closed, 0);
rb_define_method(rb_cIO, "close_read", rb_io_close_read, 0);
rb_define_method(rb_cIO, "close_write", rb_io_close_write, 0);
diff --git a/io.rb b/io.rb
index 549c5e62bd..40873ea4fd 100644
--- a/io.rb
+++ b/io.rb
@@ -120,17 +120,4 @@ class IO
def write_nonblock(buf, exception: true)
Primitive.io_write_nonblock(buf, exception)
end
-
- # call-seq:
- # readline(sep = $/, chomp: false) -> string
- # readline(limit, chomp: false) -> string
- # readline(sep, limit, chomp: false) -> string
- #
- # Reads a line as with IO#gets, but raises EOFError if already at end-of-stream.
- #
- # Optional keyword argument +chomp+ specifies whether line separators
- # are to be omitted.
- def readline(sep = $/, limit = nil, chomp: false)
- Primitive.io_readline(sep, limit, chomp)
- end
end
diff --git a/io_buffer.c b/io_buffer.c
index 7715aa0d37..87b51c0b8c 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -34,18 +34,6 @@ size_t RUBY_IO_BUFFER_DEFAULT_SIZE;
#include <sys/mman.h>
#endif
-enum {
- RB_IO_BUFFER_HEXDUMP_DEFAULT_WIDTH = 16,
-
- RB_IO_BUFFER_INSPECT_HEXDUMP_MAXIMUM_SIZE = 256,
- RB_IO_BUFFER_INSPECT_HEXDUMP_WIDTH = 16,
-
- // This is used to validate the flags given by the user.
- RB_IO_BUFFER_FLAGS_MASK = RB_IO_BUFFER_EXTERNAL | RB_IO_BUFFER_INTERNAL | RB_IO_BUFFER_MAPPED | RB_IO_BUFFER_SHARED | RB_IO_BUFFER_LOCKED | RB_IO_BUFFER_PRIVATE | RB_IO_BUFFER_READONLY,
-
- RB_IO_BUFFER_DEBUG = 0,
-};
-
struct rb_io_buffer {
void *base;
size_t size;
@@ -103,9 +91,11 @@ io_buffer_map_file(struct rb_io_buffer *buffer, int descriptor, size_t size, rb_
access = FILE_MAP_WRITE;
}
+ HANDLE mapping = CreateFileMapping(file, NULL, protect, 0, 0, NULL);
+ if (!mapping) rb_sys_fail("io_buffer_map_descriptor:CreateFileMapping");
+
if (flags & RB_IO_BUFFER_PRIVATE) {
- protect = PAGE_WRITECOPY;
- access = FILE_MAP_COPY;
+ access |= FILE_MAP_COPY;
buffer->flags |= RB_IO_BUFFER_PRIVATE;
}
else {
@@ -114,10 +104,6 @@ io_buffer_map_file(struct rb_io_buffer *buffer, int descriptor, size_t size, rb_
buffer->flags |= RB_IO_BUFFER_SHARED;
}
- HANDLE mapping = CreateFileMapping(file, NULL, protect, 0, 0, NULL);
- if (RB_IO_BUFFER_DEBUG) fprintf(stderr, "io_buffer_map_file:CreateFileMapping -> %p\n", mapping);
- if (!mapping) rb_sys_fail("io_buffer_map_descriptor:CreateFileMapping");
-
void *base = MapViewOfFile(mapping, access, (DWORD)(offset >> 32), (DWORD)(offset & 0xFFFFFFFF), size);
if (!base) {
@@ -138,7 +124,6 @@ io_buffer_map_file(struct rb_io_buffer *buffer, int descriptor, size_t size, rb_
if (flags & RB_IO_BUFFER_PRIVATE) {
buffer->flags |= RB_IO_BUFFER_PRIVATE;
- access |= MAP_PRIVATE;
}
else {
// This buffer refers to external buffer.
@@ -158,7 +143,16 @@ io_buffer_map_file(struct rb_io_buffer *buffer, int descriptor, size_t size, rb_
buffer->size = size;
buffer->flags |= RB_IO_BUFFER_MAPPED;
- buffer->flags |= RB_IO_BUFFER_FILE;
+}
+
+static inline void
+io_buffer_unmap(void* base, size_t size)
+{
+#ifdef _WIN32
+ VirtualFree(base, 0, MEM_RELEASE);
+#else
+ munmap(base, size);
+#endif
}
static void
@@ -189,7 +183,7 @@ io_buffer_zero(struct rb_io_buffer *buffer)
}
static void
-io_buffer_initialize(VALUE self, struct rb_io_buffer *buffer, void *base, size_t size, enum rb_io_buffer_flags flags, VALUE source)
+io_buffer_initialize(struct rb_io_buffer *buffer, void *base, size_t size, enum rb_io_buffer_flags flags, VALUE source)
{
if (base) {
// If we are provided a pointer, we use it.
@@ -215,14 +209,10 @@ io_buffer_initialize(VALUE self, struct rb_io_buffer *buffer, void *base, size_t
buffer->base = base;
buffer->size = size;
buffer->flags = flags;
- RB_OBJ_WRITE(self, &buffer->source, source);
-
-#if defined(_WIN32)
- buffer->mapping = NULL;
-#endif
+ buffer->source = source;
}
-static void
+static int
io_buffer_free(struct rb_io_buffer *buffer)
{
if (buffer->base) {
@@ -231,16 +221,7 @@ io_buffer_free(struct rb_io_buffer *buffer)
}
if (buffer->flags & RB_IO_BUFFER_MAPPED) {
-#ifdef _WIN32
- if (buffer->flags & RB_IO_BUFFER_FILE) {
- UnmapViewOfFile(buffer->base);
- }
- else {
- VirtualFree(buffer->base, 0, MEM_RELEASE);
- }
-#else
- munmap(buffer->base, buffer->size);
-#endif
+ io_buffer_unmap(buffer->base, buffer->size);
}
// Previously we had this, but we found out due to the way GC works, we
@@ -251,20 +232,20 @@ io_buffer_free(struct rb_io_buffer *buffer)
buffer->base = NULL;
+#if defined(_WIN32)
+ if (buffer->mapping) {
+ CloseHandle(buffer->mapping);
+ buffer->mapping = NULL;
+ }
+#endif
buffer->size = 0;
buffer->flags = 0;
buffer->source = Qnil;
- }
-#if defined(_WIN32)
- if (buffer->mapping) {
- if (RB_IO_BUFFER_DEBUG) fprintf(stderr, "io_buffer_free:CloseHandle -> %p\n", buffer->mapping);
- if (!CloseHandle(buffer->mapping)) {
- fprintf(stderr, "io_buffer_free:GetLastError -> %d\n", GetLastError());
- }
- buffer->mapping = NULL;
+ return 1;
}
-#endif
+
+ return 0;
}
void
@@ -280,6 +261,8 @@ rb_io_buffer_type_free(void *_buffer)
struct rb_io_buffer *buffer = _buffer;
io_buffer_free(buffer);
+
+ free(buffer);
}
size_t
@@ -303,23 +286,10 @@ static const rb_data_type_t rb_io_buffer_type = {
.dsize = rb_io_buffer_type_size,
},
.data = NULL,
- .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
};
-static inline enum rb_io_buffer_flags
-io_buffer_extract_flags(VALUE argument)
-{
- if (rb_int_negative_p(argument)) {
- rb_raise(rb_eArgError, "Flags can't be negative!");
- }
-
- enum rb_io_buffer_flags flags = RB_NUM2UINT(argument);
-
- // We deliberately ignore unknown flags. Any future flags which are exposed this way should be safe to ignore.
- return flags & RB_IO_BUFFER_FLAGS_MASK;
-}
-
-// Extract an offset argument, which must be a non-negative integer.
+// Extract an offset argument, which must be a positive integer.
static inline size_t
io_buffer_extract_offset(VALUE argument)
{
@@ -330,7 +300,7 @@ io_buffer_extract_offset(VALUE argument)
return NUM2SIZET(argument);
}
-// Extract a length argument, which must be a non-negative integer.
+// Extract a length argument, which must be a positive integer.
// Length is generally considered a mutable property of an object and
// semantically should be considered a subset of "size" as a concept.
static inline size_t
@@ -343,7 +313,7 @@ io_buffer_extract_length(VALUE argument)
return NUM2SIZET(argument);
}
-// Extract a size argument, which must be a non-negative integer.
+// Extract a size argument, which must be a positive integer.
// Size is generally considered an immutable property of an object.
static inline size_t
io_buffer_extract_size(VALUE argument)
@@ -355,24 +325,6 @@ io_buffer_extract_size(VALUE argument)
return NUM2SIZET(argument);
}
-// Extract a width argument, which must be a non-negative integer, and must be
-// at least the given minimum.
-static inline size_t
-io_buffer_extract_width(VALUE argument, size_t minimum)
-{
- if (rb_int_negative_p(argument)) {
- rb_raise(rb_eArgError, "Width can't be negative!");
- }
-
- size_t width = NUM2SIZET(argument);
-
- if (width < minimum) {
- rb_raise(rb_eArgError, "Width must be at least %" PRIuSIZE "!", minimum);
- }
-
- return width;
-}
-
// Compute the default length for a buffer, given an offset into that buffer.
// The default length is the size of the buffer minus the offset. The offset
// must be less than the size of the buffer otherwise the length will be
@@ -399,7 +351,7 @@ io_buffer_extract_length_offset(VALUE self, int argc, VALUE argv[], size_t *leng
struct rb_io_buffer *buffer = NULL;
TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
- if (argc >= 2 && !NIL_P(argv[1])) {
+ if (argc >= 2) {
*offset = io_buffer_extract_offset(argv[1]);
}
else {
@@ -417,28 +369,22 @@ io_buffer_extract_length_offset(VALUE self, int argc, VALUE argv[], size_t *leng
}
// Extract the optional offset and length arguments, returning the buffer.
-// Similar to `io_buffer_extract_length_offset` but with the order of arguments
-// reversed.
-//
-// After much consideration, I decided to accept both forms.
-// The `(offset, length)` order is more natural when referring about data,
-// while the `(length, offset)` order is more natural when referring to
-// read/write operations. In many cases, with the latter form, `offset`
-// is usually not supplied.
+// Similar to `io_buffer_extract_length_offset` but with the order of
+// arguments reversed.
static inline struct rb_io_buffer *
io_buffer_extract_offset_length(VALUE self, int argc, VALUE argv[], size_t *offset, size_t *length)
{
struct rb_io_buffer *buffer = NULL;
TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
- if (argc >= 1 && !NIL_P(argv[0])) {
+ if (argc >= 1) {
*offset = io_buffer_extract_offset(argv[0]);
}
else {
*offset = 0;
}
- if (argc >= 2 && !NIL_P(argv[1])) {
+ if (argc >= 2) {
*length = io_buffer_extract_length(argv[1]);
}
else {
@@ -474,7 +420,7 @@ static VALUE io_buffer_for_make_instance(VALUE klass, VALUE string, enum rb_io_b
if (!(flags & RB_IO_BUFFER_READONLY))
rb_str_modify(string);
- io_buffer_initialize(instance, buffer, RSTRING_PTR(string), RSTRING_LEN(string), flags, string);
+ io_buffer_initialize(buffer, RSTRING_PTR(string), RSTRING_LEN(string), flags, string);
return instance;
}
@@ -517,11 +463,11 @@ io_buffer_for_yield_instance_ensure(VALUE _arguments)
* IO::Buffer.for(string) -> readonly io_buffer
* IO::Buffer.for(string) {|io_buffer| ... read/write io_buffer ...}
*
- * Creates a zero-copy IO::Buffer from the given string's memory. Without a
- * block a frozen internal copy of the string is created efficiently and used
- * as the buffer source. When a block is provided, the buffer is associated
- * directly with the string's internal buffer and updating the buffer will
- * update the string.
+ * Creates a IO::Buffer from the given string's memory. Without a block a
+ * frozen internal copy of the string is created efficiently and used as the
+ * buffer source. When a block is provided, the buffer is associated directly
+ * with the string's internal buffer and updating the buffer will update the
+ * string.
*
* Until #free is invoked on the buffer, either explicitly or via the garbage
* collector, the source string will be locked and cannot be modified.
@@ -572,35 +518,6 @@ rb_io_buffer_type_for(VALUE klass, VALUE string)
}
}
-/*
- * call-seq:
- * IO::Buffer.string(length) {|io_buffer| ... read/write io_buffer ...} -> string
- *
- * Creates a new string of the given length and yields a zero-copy IO::Buffer
- * instance to the block which uses the string as a source. The block is
- * expected to write to the buffer and the string will be returned.
- *
- * IO::Buffer.string(4) do |buffer|
- * buffer.set_string("Ruby")
- * end
- * # => "Ruby"
- */
-VALUE
-rb_io_buffer_type_string(VALUE klass, VALUE length)
-{
- VALUE string = rb_str_new(NULL, RB_NUM2LONG(length));
-
- struct io_buffer_for_yield_instance_arguments arguments = {
- .klass = klass,
- .string = string,
- .instance = Qnil,
- };
-
- rb_ensure(io_buffer_for_yield_instance, (VALUE)&arguments, io_buffer_for_yield_instance_ensure, (VALUE)&arguments);
-
- return string;
-}
-
VALUE
rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags)
{
@@ -609,7 +526,7 @@ rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags)
struct rb_io_buffer *buffer = NULL;
TypedData_Get_Struct(instance, struct rb_io_buffer, &rb_io_buffer_type, buffer);
- io_buffer_initialize(instance, buffer, base, size, flags, Qnil);
+ io_buffer_initialize(buffer, base, size, flags, Qnil);
return instance;
}
@@ -643,6 +560,8 @@ rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags
* mapping, you need to open a file in read-write mode, and explicitly pass
* +flags+ argument without IO::Buffer::IMMUTABLE.
*
+ * Example:
+ *
* File.write('test.txt', 'test')
*
* buffer = IO::Buffer.map(File.open('test.txt'), nil, 0, IO::Buffer::READONLY)
@@ -705,7 +624,7 @@ io_buffer_map(int argc, VALUE *argv, VALUE klass)
enum rb_io_buffer_flags flags = 0;
if (argc >= 4) {
- flags = io_buffer_extract_flags(argv[3]);
+ flags = RB_NUM2UINT(argv[3]);
}
return rb_io_buffer_map(io, size, offset, flags);
@@ -733,6 +652,8 @@ io_flags_for_size(size_t size)
* on Windows). The behavior can be forced by passing IO::Buffer::MAPPED
* as a second parameter.
*
+ * Examples
+ *
* buffer = IO::Buffer.new(4)
* # =>
* # #<IO::Buffer 0x000055b34497ea10+4 INTERNAL>
@@ -766,13 +687,13 @@ rb_io_buffer_initialize(int argc, VALUE *argv, VALUE self)
enum rb_io_buffer_flags flags = 0;
if (argc >= 2) {
- flags = io_buffer_extract_flags(argv[1]);
+ flags = RB_NUM2UINT(argv[1]);
}
else {
flags |= io_flags_for_size(size);
}
- io_buffer_initialize(self, buffer, NULL, size, flags, Qnil);
+ io_buffer_initialize(buffer, NULL, size, flags, Qnil);
return self;
}
@@ -818,82 +739,6 @@ io_buffer_validate(struct rb_io_buffer *buffer)
}
}
-enum rb_io_buffer_flags
-rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size)
-{
- struct rb_io_buffer *buffer = NULL;
- TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
-
- if (io_buffer_validate(buffer)) {
- if (buffer->base) {
- *base = buffer->base;
- *size = buffer->size;
-
- return buffer->flags;
- }
- }
-
- *base = NULL;
- *size = 0;
-
- return 0;
-}
-
-// Internal function for accessing bytes for writing, wil
-static inline void
-io_buffer_get_bytes_for_writing(struct rb_io_buffer *buffer, void **base, size_t *size)
-{
- if (buffer->flags & RB_IO_BUFFER_READONLY) {
- rb_raise(rb_eIOBufferAccessError, "Buffer is not writable!");
- }
-
- if (!io_buffer_validate(buffer)) {
- rb_raise(rb_eIOBufferInvalidatedError, "Buffer is invalid!");
- }
-
- if (buffer->base) {
- *base = buffer->base;
- *size = buffer->size;
- } else {
- *base = NULL;
- *size = 0;
- }
-}
-
-void
-rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size)
-{
- struct rb_io_buffer *buffer = NULL;
- TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
-
- io_buffer_get_bytes_for_writing(buffer, base, size);
-}
-
-static void
-io_buffer_get_bytes_for_reading(struct rb_io_buffer *buffer, const void **base, size_t *size)
-{
- if (!io_buffer_validate(buffer)) {
- rb_raise(rb_eIOBufferInvalidatedError, "Buffer has been invalidated!");
- }
-
- if (buffer->base) {
- *base = buffer->base;
- *size = buffer->size;
- } else {
- *base = NULL;
- *size = 0;
- }
-}
-
-void
-rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size)
-{
- struct rb_io_buffer *buffer = NULL;
- TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
-
- io_buffer_get_bytes_for_reading(buffer, base, size);
-}
-
/*
* call-seq: to_s -> string
*
@@ -930,10 +775,6 @@ rb_io_buffer_to_s(VALUE self)
rb_str_cat2(result, " MAPPED");
}
- if (buffer->flags & RB_IO_BUFFER_FILE) {
- rb_str_cat2(result, " FILE");
- }
-
if (buffer->flags & RB_IO_BUFFER_SHARED) {
rb_str_cat2(result, " SHARED");
}
@@ -942,10 +783,6 @@ rb_io_buffer_to_s(VALUE self)
rb_str_cat2(result, " LOCKED");
}
- if (buffer->flags & RB_IO_BUFFER_PRIVATE) {
- rb_str_cat2(result, " PRIVATE");
- }
-
if (buffer->flags & RB_IO_BUFFER_READONLY) {
rb_str_cat2(result, " READONLY");
}
@@ -961,38 +798,13 @@ rb_io_buffer_to_s(VALUE self)
return rb_str_cat2(result, ">");
}
-// Compute the output size of a hexdump of the given width (bytes per line), total size, and whether it is the first line in the output.
-// This is used to preallocate the output string.
-inline static size_t
-io_buffer_hexdump_output_size(size_t width, size_t size, int first)
-{
- // The preview on the right hand side is 1:1:
- size_t total = size;
-
- size_t whole_lines = (size / width);
- size_t partial_line = (size % width) ? 1 : 0;
-
- // For each line:
- // 1 byte 10 bytes 1 byte width*3 bytes 1 byte size bytes
- // (newline) (address) (space) (hexdump ) (space) (preview)
- total += (whole_lines + partial_line) * (1 + 10 + width*3 + 1 + 1);
-
- // If the hexdump is the first line, one less newline will be emitted:
- if (size && first) total -= 1;
-
- return total;
-}
-
-// Append a hexdump of the given width (bytes per line), base address, size, and whether it is the first line in the output.
-// If the hexdump is not the first line, it will prepend a newline if there is any output at all.
-// If formatting here is adjusted, please update io_buffer_hexdump_output_size accordingly.
static VALUE
-io_buffer_hexdump(VALUE string, size_t width, const char *base, size_t length, size_t offset, int first)
+io_buffer_hexdump(VALUE string, size_t width, char *base, size_t size, int first)
{
char *text = alloca(width+1);
text[width] = '\0';
- for (; offset < length; offset += width) {
+ for (size_t offset = 0; offset < size; offset += width) {
memset(text, '\0', width);
if (first) {
rb_str_catf(string, "0x%08" PRIxSIZE " ", offset);
@@ -1003,7 +815,7 @@ io_buffer_hexdump(VALUE string, size_t width, const char *base, size_t length, s
}
for (size_t i = 0; i < width; i += 1) {
- if (offset+i < length) {
+ if (offset+i < size) {
unsigned char value = ((unsigned char*)base)[offset+i];
if (value < 127 && isprint(value)) {
@@ -1026,18 +838,23 @@ io_buffer_hexdump(VALUE string, size_t width, const char *base, size_t length, s
return string;
}
-/*
- * call-seq: inspect -> string
- *
- * Inspect the buffer and report useful information about it's internal state.
- * Only a limited portion of the buffer will be displayed in a hexdump style
- * format.
- *
- * buffer = IO::Buffer.for("Hello World")
- * puts buffer.inspect
- * # #<IO::Buffer 0x000000010198ccd8+11 EXTERNAL READONLY SLICE>
- * # 0x00000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 Hello World
- */
+static VALUE
+rb_io_buffer_hexdump(VALUE self)
+{
+ struct rb_io_buffer *buffer = NULL;
+ TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
+
+ VALUE result = Qnil;
+
+ if (io_buffer_validate(buffer) && buffer->base) {
+ result = rb_str_buf_new(buffer->size*3 + (buffer->size/16)*12 + 1);
+
+ io_buffer_hexdump(result, 16, buffer->base, buffer->size, 1);
+ }
+
+ return result;
+}
+
VALUE
rb_io_buffer_inspect(VALUE self)
{
@@ -1047,19 +864,9 @@ rb_io_buffer_inspect(VALUE self)
VALUE result = rb_io_buffer_to_s(self);
if (io_buffer_validate(buffer)) {
- // Limit the maximum size generated by inspect:
- size_t size = buffer->size;
- int clamped = 0;
-
- if (size > RB_IO_BUFFER_INSPECT_HEXDUMP_MAXIMUM_SIZE) {
- size = RB_IO_BUFFER_INSPECT_HEXDUMP_MAXIMUM_SIZE;
- clamped = 1;
- }
-
- io_buffer_hexdump(result, RB_IO_BUFFER_INSPECT_HEXDUMP_WIDTH, buffer->base, size, 0, 0);
-
- if (clamped) {
- rb_str_catf(result, "\n(and %" PRIuSIZE " more bytes not printed)", buffer->size - size);
+ // Limit the maximum size generated by inspect.
+ if (buffer->size <= 256) {
+ io_buffer_hexdump(result, 16, buffer->base, buffer->size, 0);
}
}
@@ -1086,8 +893,8 @@ rb_io_buffer_size(VALUE self)
*
* Returns whether the buffer buffer is accessible.
*
- * A buffer becomes invalid if it is a slice of another buffer (or string)
- * which has been freed or re-allocated at a different address.
+ * A buffer becomes invalid if it is a slice of another buffer which has been
+ * freed.
*/
static VALUE
rb_io_buffer_valid_p(VALUE self)
@@ -1101,16 +908,8 @@ rb_io_buffer_valid_p(VALUE self)
/*
* call-seq: null? -> true or false
*
- * If the buffer was freed with #free, transferred with #transfer, or was
- * never allocated in the first place.
- *
- * buffer = IO::Buffer.new(0)
- * buffer.null? #=> true
- *
- * buffer = IO::Buffer.new(4)
- * buffer.null? #=> false
- * buffer.free
- * buffer.null? #=> true
+ * If the buffer was freed with #free or was never allocated in the first
+ * place.
*/
static VALUE
rb_io_buffer_null_p(VALUE self)
@@ -1210,22 +1009,6 @@ rb_io_buffer_mapped_p(VALUE self)
* If the buffer is _shared_, meaning it references memory that can be shared
* with other processes (and thus might change without being modified
* locally).
- *
- * # Create a test file:
- * File.write('test.txt', 'test')
- *
- * # Create a shared mapping from the given file, the file must be opened in
- * # read-write mode unless we also specify IO::Buffer::READONLY:
- * buffer = IO::Buffer.map(File.open('test.txt', 'r+'), nil, 0)
- * # => #<IO::Buffer 0x00007f1bffd5e000+4 EXTERNAL MAPPED SHARED>
- *
- * # Write to the buffer, which will modify the mapped file:
- * buffer.set_string('b', 0)
- * # => 1
- *
- * # The file itself is modified:
- * File.read('test.txt')
- * # => "best"
*/
static VALUE
rb_io_buffer_shared_p(VALUE self)
@@ -1246,6 +1029,8 @@ rb_io_buffer_shared_p(VALUE self)
* Locking is not thread safe, but is a semantic used to ensure buffers don't
* move while being used by a system call.
*
+ * Example:
+ *
* buffer.locked do
* buffer.write(io) # theoretical system call interface
* end
@@ -1259,37 +1044,6 @@ rb_io_buffer_locked_p(VALUE self)
return RBOOL(buffer->flags & RB_IO_BUFFER_LOCKED);
}
-/* call-seq: private? -> true or false
- *
- * If the buffer is _private_, meaning modifications to the buffer will not
- * be replicated to the underlying file mapping.
- *
- * # Create a test file:
- * File.write('test.txt', 'test')
- *
- * # Create a private mapping from the given file. Note that the file here
- * # is opened in read-only mode, but it doesn't matter due to the private
- * # mapping:
- * buffer = IO::Buffer.map(File.open('test.txt'), nil, 0, IO::Buffer::PRIVATE)
- * # => #<IO::Buffer 0x00007fce63f11000+4 MAPPED PRIVATE>
- *
- * # Write to the buffer (invoking CoW of the underlying file buffer):
- * buffer.set_string('b', 0)
- * # => 1
- *
- * # The file itself is not modified:
- * File.read('test.txt')
- * # => "test"
- */
-static VALUE
-rb_io_buffer_private_p(VALUE self)
-{
- struct rb_io_buffer *buffer = NULL;
- TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
-
- return RBOOL(buffer->flags & RB_IO_BUFFER_PRIVATE);
-}
-
int
rb_io_buffer_readonly_p(VALUE self)
{
@@ -1383,6 +1137,8 @@ rb_io_buffer_try_unlock(VALUE self)
* non-blocking system calls. You can only share a buffer between threads with
* appropriate synchronisation techniques.
*
+ * Example:
+ *
* buffer = IO::Buffer.new(4)
* buffer.locked? #=> false
*
@@ -1430,6 +1186,8 @@ rb_io_buffer_locked(VALUE self)
*
* You can resize a freed buffer to re-allocate it.
*
+ * Example:
+ *
* buffer = IO::Buffer.for('test')
* buffer.free
* # => #<IO::Buffer 0x0000000000000000+0 NULL>
@@ -1458,17 +1216,6 @@ rb_io_buffer_free(VALUE self)
return self;
}
-VALUE rb_io_buffer_free_locked(VALUE self)
-{
- struct rb_io_buffer *buffer = NULL;
- TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
-
- io_buffer_unlock(buffer);
- io_buffer_free(buffer);
-
- return self;
-}
-
// Validate that access to the buffer is within bounds, assuming you want to
// access length bytes from the specified offset.
static inline void
@@ -1480,49 +1227,6 @@ io_buffer_validate_range(struct rb_io_buffer *buffer, size_t offset, size_t leng
}
}
-/*
- * call-seq: hexdump([offset, [length, [width]]]) -> string
- *
- * Returns a human-readable string representation of the buffer. The exact
- * format is subject to change.
- *
- * buffer = IO::Buffer.for("Hello World")
- * puts buffer.hexdump
- * # 0x00000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 Hello World
- *
- * As buffers are usually fairly big, you may want to limit the output by
- * specifying the offset and length:
- *
- * puts buffer.hexdump(6, 5)
- * # 0x00000006 57 6f 72 6c 64 World
- */
-static VALUE
-rb_io_buffer_hexdump(int argc, VALUE *argv, VALUE self)
-{
- rb_check_arity(argc, 0, 3);
-
- size_t offset, length;
- struct rb_io_buffer *buffer = io_buffer_extract_offset_length(self, argc, argv, &offset, &length);
-
- size_t width = RB_IO_BUFFER_HEXDUMP_DEFAULT_WIDTH;
- if (argc >= 3) {
- width = io_buffer_extract_width(argv[2], 1);
- }
-
- // This may raise an exception if the offset/length is invalid:
- io_buffer_validate_range(buffer, offset, length);
-
- VALUE result = Qnil;
-
- if (io_buffer_validate(buffer) && buffer->base) {
- result = rb_str_buf_new(io_buffer_hexdump_output_size(width, length, 1));
-
- io_buffer_hexdump(result, width, buffer->base, offset+length, offset, 1);
- }
-
- return result;
-}
-
static VALUE
rb_io_buffer_slice(struct rb_io_buffer *buffer, VALUE self, size_t offset, size_t length)
{
@@ -1532,16 +1236,15 @@ rb_io_buffer_slice(struct rb_io_buffer *buffer, VALUE self, size_t offset, size_
struct rb_io_buffer *slice = NULL;
TypedData_Get_Struct(instance, struct rb_io_buffer, &rb_io_buffer_type, slice);
+ slice->flags |= (buffer->flags & RB_IO_BUFFER_READONLY);
slice->base = (char*)buffer->base + offset;
slice->size = length;
// The source should be the root buffer:
- if (buffer->source != Qnil) {
- RB_OBJ_WRITE(instance, &slice->source, buffer->source);
- }
- else {
- RB_OBJ_WRITE(instance, &slice->source, self);
- }
+ if (buffer->source != Qnil)
+ slice->source = buffer->source;
+ else
+ slice->source = self;
return instance;
}
@@ -1565,6 +1268,8 @@ rb_io_buffer_slice(struct rb_io_buffer *buffer, VALUE self, size_t offset, size_
* Raises RuntimeError if the <tt>offset+length</tt> is out of the current
* buffer's bounds.
*
+ * Example:
+ *
* string = 'test'
* buffer = IO::Buffer.for(string)
*
@@ -1611,11 +1316,90 @@ io_buffer_slice(int argc, VALUE *argv, VALUE self)
return rb_io_buffer_slice(buffer, self, offset, length);
}
+int
+rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size)
+{
+ struct rb_io_buffer *buffer = NULL;
+ TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
+
+ if (io_buffer_validate(buffer)) {
+ if (buffer->base) {
+ *base = buffer->base;
+ *size = buffer->size;
+
+ return buffer->flags;
+ }
+ }
+
+ *base = NULL;
+ *size = 0;
+
+ return 0;
+}
+
+static inline void
+io_buffer_get_bytes_for_writing(struct rb_io_buffer *buffer, void **base, size_t *size)
+{
+ if (buffer->flags & RB_IO_BUFFER_READONLY ||
+ (!NIL_P(buffer->source) && OBJ_FROZEN(buffer->source))) {
+ rb_raise(rb_eIOBufferAccessError, "Buffer is not writable!");
+ }
+
+ if (!io_buffer_validate(buffer)) {
+ rb_raise(rb_eIOBufferInvalidatedError, "Buffer is invalid!");
+ }
+
+ if (buffer->base) {
+ *base = buffer->base;
+ *size = buffer->size;
+
+ return;
+ }
+
+ rb_raise(rb_eIOBufferAllocationError, "The buffer is not allocated!");
+}
+
+void
+rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size)
+{
+ struct rb_io_buffer *buffer = NULL;
+ TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
+
+ io_buffer_get_bytes_for_writing(buffer, base, size);
+}
+
+static void
+io_buffer_get_bytes_for_reading(struct rb_io_buffer *buffer, const void **base, size_t *size)
+{
+ if (!io_buffer_validate(buffer)) {
+ rb_raise(rb_eIOBufferInvalidatedError, "Buffer has been invalidated!");
+ }
+
+ if (buffer->base) {
+ *base = buffer->base;
+ *size = buffer->size;
+
+ return;
+ }
+
+ rb_raise(rb_eIOBufferAllocationError, "The buffer is not allocated!");
+}
+
+void
+rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size)
+{
+ struct rb_io_buffer *buffer = NULL;
+ TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer);
+
+ io_buffer_get_bytes_for_reading(buffer, base, size);
+}
+
/*
* call-seq: transfer -> new_io_buffer
*
- * Transfers ownership of the underlying memory to a new buffer, causing the
- * current buffer to become uninitialized.
+ * Transfers ownership to a new buffer, deallocating the current one.
+ *
+ * Example:
*
* buffer = IO::Buffer.new('test')
* other = buffer.transfer
@@ -1658,11 +1442,11 @@ io_buffer_resize_clear(struct rb_io_buffer *buffer, void* base, size_t size)
}
static void
-io_buffer_resize_copy(VALUE self, struct rb_io_buffer *buffer, size_t size)
+io_buffer_resize_copy(struct rb_io_buffer *buffer, size_t size)
{
// Slow path:
struct rb_io_buffer resized;
- io_buffer_initialize(self, &resized, NULL, size, io_flags_for_size(size), Qnil);
+ io_buffer_initialize(&resized, NULL, size, io_flags_for_size(size), Qnil);
if (buffer->base) {
size_t preserve = buffer->size;
@@ -1687,7 +1471,7 @@ rb_io_buffer_resize(VALUE self, size_t size)
}
if (buffer->base == NULL) {
- io_buffer_initialize(self, buffer, NULL, size, io_flags_for_size(size), Qnil);
+ io_buffer_initialize(buffer, NULL, size, io_flags_for_size(size), Qnil);
return;
}
@@ -1732,7 +1516,7 @@ rb_io_buffer_resize(VALUE self, size_t size)
return;
}
- io_buffer_resize_copy(self, buffer, size);
+ io_buffer_resize_copy(buffer, size);
}
/*
@@ -1927,6 +1711,8 @@ io_buffer_buffer_type_size(ID buffer_type)
*
* Returns the size of the given buffer type(s) in bytes.
*
+ * Example:
+ *
* IO::Buffer.size_of(:u32) # => 4
* IO::Buffer.size_of([:u32, :u32]) # => 8
*/
@@ -2005,6 +1791,8 @@ rb_io_buffer_get_value(const void* base, size_t size, ID buffer_type, size_t *of
* in the buffer. For example, a +:u32+ buffer type is a 32-bit unsigned
* integer in little-endian format.
*
+ * Example:
+ *
* string = [1.5].pack('f')
* # => "\x00\x00\xC0?"
* IO::Buffer.for(string).get_value(:f32, 0)
@@ -2028,6 +1816,8 @@ io_buffer_get_value(VALUE self, VALUE type, VALUE _offset)
* Similar to #get_value, except that it can handle multiple buffer types and
* returns an array of values.
*
+ * Example:
+ *
* string = [1.5, 2.5].pack('ff')
* IO::Buffer.for(string).get_values([:f32, :f32], 0)
* # => [1.5, 2.5]
@@ -2100,6 +1890,8 @@ io_buffer_extract_offset_count(ID buffer_type, size_t size, int argc, VALUE *arg
*
* If +count+ is given, only +count+ values will be yielded.
*
+ * Example:
+ *
* IO::Buffer.for("Hello World").each(:U8, 2, 2) do |offset, value|
* puts "#{offset}: #{value}"
* end
@@ -2143,6 +1935,8 @@ io_buffer_each(int argc, VALUE *argv, VALUE self)
*
* If +count+ is given, only +count+ values will be returned.
*
+ * Example:
+ *
* IO::Buffer.for("Hello World").values(:U8, 2, 2)
* # => [108, 108]
*/
@@ -2184,6 +1978,8 @@ io_buffer_values(int argc, VALUE *argv, VALUE self)
*
* If +count+ is given, only +count+ bytes will be yielded.
*
+ * Example:
+ *
* IO::Buffer.for("Hello World").each_byte(2, 2) do |offset, byte|
* puts "#{offset}: #{byte}"
* end
@@ -2293,6 +2089,8 @@ io_buffer_set_value(VALUE self, VALUE type, VALUE _offset, VALUE value)
* should be an array of symbols as described in #get_value. +values+ should
* be an array of values to write.
*
+ * Example:
+ *
* buffer = IO::Buffer.new(8)
* buffer.set_values([:U8, :U16], 0, [1, 2])
* buffer
@@ -2413,7 +2211,7 @@ rb_io_buffer_initialize_copy(VALUE self, VALUE source)
rb_io_buffer_get_bytes_for_reading(source, &source_base, &source_size);
- io_buffer_initialize(self, buffer, NULL, source_size, io_flags_for_size(source_size), Qnil);
+ io_buffer_initialize(buffer, NULL, source_size, io_flags_for_size(source_size), Qnil);
return io_buffer_copy_from(buffer, source_base, source_size, 0, NULL);
}
@@ -2422,8 +2220,8 @@ rb_io_buffer_initialize_copy(VALUE self, VALUE source)
* call-seq:
* copy(source, [offset, [length, [source_offset]]]) -> size
*
- * Efficiently copy from a source IO::Buffer into the buffer, at +offset+
- * using +memcpy+. For copying String instances, see #set_string.
+ * Efficiently copy buffer from a source IO::Buffer into the buffer,
+ * at +offset+ using +memcpy+. For copying String instances, see #set_string.
*
* buffer = IO::Buffer.new(32)
* # =>
@@ -2531,8 +2329,8 @@ io_buffer_get_string(int argc, VALUE *argv, VALUE self)
/*
* call-seq: set_string(string, [offset, [length, [source_offset]]]) -> size
*
- * Efficiently copy from a source String into the buffer, at +offset+ using
- * +memcpy+.
+ * Efficiently copy buffer from a source String into the buffer,
+ * at +offset+ using +memcpy+.
*
* buf = IO::Buffer.new(8)
* # =>
@@ -2704,12 +2502,13 @@ io_buffer_blocking_region(struct rb_io_buffer *buffer, rb_blocking_function_t *f
}
struct io_buffer_read_internal_argument {
- // The file descriptor to read from:
int descriptor;
+
// The base pointer to read from:
char *base;
// The size of the buffer:
size_t size;
+
// The minimum number of bytes to read:
size_t length;
};
@@ -2818,45 +2617,35 @@ io_buffer_read(int argc, VALUE *argv, VALUE self)
}
struct io_buffer_pread_internal_argument {
- // The file descriptor to read from:
int descriptor;
- // The base pointer to read from:
- char *base;
- // The size of the buffer:
+ void *base;
size_t size;
- // The minimum number of bytes to read:
- size_t length;
- // The offset to read from:
off_t offset;
};
static VALUE
io_buffer_pread_internal(void *_argument)
{
- size_t total = 0;
struct io_buffer_pread_internal_argument *argument = _argument;
- while (true) {
- ssize_t result = pread(argument->descriptor, argument->base, argument->size, argument->offset);
+#if defined(HAVE_PREAD)
+ ssize_t result = pread(argument->descriptor, argument->base, argument->size, argument->offset);
+#else
+ // This emulation is not thread safe.
+ rb_off_t offset = lseek(argument->descriptor, 0, SEEK_CUR);
+ if (offset == (rb_off_t)-1)
+ return rb_fiber_scheduler_io_result(-1, errno);
- if (result < 0) {
- return rb_fiber_scheduler_io_result(result, errno);
- }
- else if (result == 0) {
- return rb_fiber_scheduler_io_result(total, 0);
- }
- else {
- total += result;
+ if (lseek(argument->descriptor, argument->offset, SEEK_SET) == (rb_off_t)-1)
+ return rb_fiber_scheduler_io_result(-1, errno);
- if (total >= argument->length) {
- return rb_fiber_scheduler_io_result(total, 0);
- }
+ ssize_t result = read(argument->descriptor, argument->base, argument->size);
- argument->base = argument->base + result;
- argument->size = argument->size - result;
- argument->offset = argument->offset + result;
- }
- }
+ if (lseek(argument->descriptor, offset, SEEK_SET) == (rb_off_t)-1)
+ return rb_fiber_scheduler_io_result(-1, errno);
+#endif
+
+ return rb_fiber_scheduler_io_result(result, errno);
}
VALUE
@@ -2882,14 +2671,16 @@ rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t of
size_t size;
io_buffer_get_bytes_for_writing(buffer, &base, &size);
- base = (unsigned char*)base + offset;
- size = size - offset;
-
struct io_buffer_pread_internal_argument argument = {
.descriptor = descriptor,
- .base = base,
- .size = size,
- .length = length,
+
+ // Move the base pointer to the offset:
+ .base = (unsigned char*)base + offset,
+
+ // And the size to the length of buffer we want to read:
+ .size = length,
+
+ // From the offset in the file we want to read from:
.offset = from,
};
@@ -2897,19 +2688,15 @@ rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t of
}
/*
- * call-seq: pread(io, from, [length, [offset]]) -> read length or -errno
- *
- * Read at least +length+ bytes from the +io+ starting at the specified +from+
- * position, into the buffer starting at +offset+. If an error occurs,
- * return <tt>-errno</tt>.
+ * call-seq: pread(io, from, length, [offset]) -> read length or -errno
*
- * If +length+ is not given or +nil+, it defaults to the size of the buffer
- * minus the offset, i.e. the entire buffer.
+ * Read at most +length+ bytes from +io+ into the buffer, starting at
+ * +from+, and put it in buffer starting from specified +offset+.
+ * If an error occurs, return <tt>-errno</tt>.
*
- * If +length+ is zero, exactly one <tt>pread</tt> operation will occur.
+ * If +offset+ is not given, put it at the beginning of the buffer.
*
- * If +offset+ is not given, it defaults to zero, i.e. the beginning of the
- * buffer.
+ * Example:
*
* IO::Buffer.for('test') do |buffer|
* p buffer
@@ -2941,12 +2728,13 @@ io_buffer_pread(int argc, VALUE *argv, VALUE self)
}
struct io_buffer_write_internal_argument {
- // The file descriptor to write to:
int descriptor;
+
// The base pointer to write from:
const char *base;
// The size of the buffer:
size_t size;
+
// The minimum length to write:
size_t length;
};
@@ -3046,46 +2834,37 @@ io_buffer_write(int argc, VALUE *argv, VALUE self)
return rb_io_buffer_write(self, io, length, offset);
}
+
struct io_buffer_pwrite_internal_argument {
- // The file descriptor to write to:
int descriptor;
- // The base pointer to write from:
- const char *base;
- // The size of the buffer:
+ const void *base;
size_t size;
- // The minimum length to write:
- size_t length;
- // The offset to write to:
off_t offset;
};
static VALUE
io_buffer_pwrite_internal(void *_argument)
{
- size_t total = 0;
struct io_buffer_pwrite_internal_argument *argument = _argument;
- while (true) {
- ssize_t result = pwrite(argument->descriptor, argument->base, argument->size, argument->offset);
+#if defined(HAVE_PWRITE)
+ ssize_t result = pwrite(argument->descriptor, argument->base, argument->size, argument->offset);
+#else
+ // This emulation is not thread safe.
+ rb_off_t offset = lseek(argument->descriptor, 0, SEEK_CUR);
+ if (offset == (rb_off_t)-1)
+ return rb_fiber_scheduler_io_result(-1, errno);
- if (result < 0) {
- return rb_fiber_scheduler_io_result(result, errno);
- }
- else if (result == 0) {
- return rb_fiber_scheduler_io_result(total, 0);
- }
- else {
- total += result;
+ if (lseek(argument->descriptor, argument->offset, SEEK_SET) == (rb_off_t)-1)
+ return rb_fiber_scheduler_io_result(-1, errno);
- if (total >= argument->length) {
- return rb_fiber_scheduler_io_result(total, 0);
- }
+ ssize_t result = write(argument->descriptor, argument->base, argument->size);
- argument->base = argument->base + result;
- argument->size = argument->size - result;
- argument->offset = argument->offset + result;
- }
- }
+ if (lseek(argument->descriptor, offset, SEEK_SET) == (rb_off_t)-1)
+ return rb_fiber_scheduler_io_result(-1, errno);
+#endif
+
+ return rb_fiber_scheduler_io_result(result, errno);
}
VALUE
@@ -3111,20 +2890,14 @@ rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t o
size_t size;
io_buffer_get_bytes_for_reading(buffer, &base, &size);
- base = (unsigned char*)base + offset;
- size = size - offset;
-
struct io_buffer_pwrite_internal_argument argument = {
.descriptor = descriptor,
// Move the base pointer to the offset:
- .base = base,
+ .base = (unsigned char *)base + offset,
// And the size to the length of buffer we want to read:
- .size = size,
-
- // And the length of the buffer we want to write:
- .length = length,
+ .size = length,
// And the offset in the file we want to write from:
.offset = from,
@@ -3134,22 +2907,14 @@ rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t o
}
/*
- * call-seq: pwrite(io, from, [length, [offset]]) -> written length or -errno
- *
- * Write at least +length+ bytes from the buffer starting at +offset+, into
- * the +io+ starting at the specified +from+ position. If an error occurs,
- * return <tt>-errno</tt>.
- *
- * If +length+ is not given or +nil+, it defaults to the size of the buffer
- * minus the offset, i.e. the entire buffer.
+ * call-seq: pwrite(io, from, length, [offset]) -> written length or -errno
*
- * If +length+ is zero, exactly one <tt>pwrite</tt> operation will occur.
+ * Writes +length+ bytes from buffer into +io+, starting at
+ * +offset+ in the buffer. If an error occurs, return <tt>-errno</tt>.
*
- * If +offset+ is not given, it defaults to zero, i.e. the beginning of the
- * buffer.
- *
- * If the +from+ position is beyond the end of the file, the gap will be
- * filled with null (0 value) bytes.
+ * If +offset+ is not given, the bytes are taken from the beginning of the
+ * buffer. If the +offset+ is given and is beyond the end of the file, the
+ * gap will be filled with null (0 value) bytes.
*
* out = File.open('output.txt', File::RDWR) # open for read/write, no truncation
* IO::Buffer.for('1234567').pwrite(out, 2, 3, 1)
@@ -3531,28 +3296,24 @@ io_buffer_not_inplace(VALUE self)
/*
* Document-class: IO::Buffer
*
- * IO::Buffer is a efficient zero-copy buffer for input/output. There are
- * typical use cases:
+ * IO::Buffer is a low-level efficient buffer for input/output. There are three
+ * ways of using buffer:
*
* * Create an empty buffer with ::new, fill it with buffer using #copy or
- * #set_value, #set_string, get buffer with #get_string or write it directly
- * to some file with #write.
+ * #set_value, #set_string, get buffer with #get_string;
* * Create a buffer mapped to some string with ::for, then it could be used
* both for reading with #get_string or #get_value, and writing (writing will
- * change the source string, too).
+ * change the source string, too);
* * Create a buffer mapped to some file with ::map, then it could be used for
* reading and writing the underlying file.
- * * Create a string of a fixed size with ::string, then #read into it, or
- * modify it using #set_value.
*
* Interaction with string and file memory is performed by efficient low-level
* C mechanisms like `memcpy`.
*
* The class is meant to be an utility for implementing more high-level mechanisms
- * like Fiber::Scheduler#io_read and Fiber::Scheduler#io_write and parsing binary
- * protocols.
+ * like Fiber::SchedulerInterface#io_read and Fiber::SchedulerInterface#io_write.
*
- * == Examples of Usage
+ * <b>Examples of usage:</b>
*
* Empty buffer:
*
@@ -3613,33 +3374,20 @@ io_buffer_not_inplace(VALUE self)
* File.read('test.txt')
* # => "t--- buffer"
*
- * <b>The class is experimental and the interface is subject to change, this
- * is especially true of file mappings which may be removed entirely in
- * the future.</b>
+ * <b>The class is experimental and the interface is subject to change.</b>
*/
void
Init_IO_Buffer(void)
{
rb_cIOBuffer = rb_define_class_under(rb_cIO, "Buffer", rb_cObject);
-
- /* Raised when an operation would resize or re-allocate a locked buffer. */
rb_eIOBufferLockedError = rb_define_class_under(rb_cIOBuffer, "LockedError", rb_eRuntimeError);
-
- /* Raised when the buffer cannot be allocated for some reason, or you try to use a buffer that's not allocated. */
rb_eIOBufferAllocationError = rb_define_class_under(rb_cIOBuffer, "AllocationError", rb_eRuntimeError);
-
- /* Raised when you try to write to a read-only buffer, or resize an external buffer. */
rb_eIOBufferAccessError = rb_define_class_under(rb_cIOBuffer, "AccessError", rb_eRuntimeError);
-
- /* Raised if you try to access a buffer slice which no longer references a valid memory range of the underlying source. */
rb_eIOBufferInvalidatedError = rb_define_class_under(rb_cIOBuffer, "InvalidatedError", rb_eRuntimeError);
-
- /* Raised if the mask given to a binary operation is invalid, e.g. zero length or overlaps the target buffer. */
rb_eIOBufferMaskError = rb_define_class_under(rb_cIOBuffer, "MaskError", rb_eArgError);
rb_define_alloc_func(rb_cIOBuffer, rb_io_buffer_type_allocate);
rb_define_singleton_method(rb_cIOBuffer, "for", rb_io_buffer_type_for, 1);
- rb_define_singleton_method(rb_cIOBuffer, "string", rb_io_buffer_type_string, 1);
#ifdef _WIN32
SYSTEM_INFO info;
@@ -3651,57 +3399,37 @@ Init_IO_Buffer(void)
RUBY_IO_BUFFER_DEFAULT_SIZE = io_buffer_default_size(RUBY_IO_BUFFER_PAGE_SIZE);
- /* The operating system page size. Used for efficient page-aligned memory allocations. */
+ // Efficient sizing of mapped buffers:
rb_define_const(rb_cIOBuffer, "PAGE_SIZE", SIZET2NUM(RUBY_IO_BUFFER_PAGE_SIZE));
-
- /* The default buffer size, typically a (small) multiple of the PAGE_SIZE.
- Can be explicitly specified by setting the RUBY_IO_BUFFER_DEFAULT_SIZE
- environment variable. */
rb_define_const(rb_cIOBuffer, "DEFAULT_SIZE", SIZET2NUM(RUBY_IO_BUFFER_DEFAULT_SIZE));
rb_define_singleton_method(rb_cIOBuffer, "map", io_buffer_map, -1);
+ // General use:
rb_define_method(rb_cIOBuffer, "initialize", rb_io_buffer_initialize, -1);
rb_define_method(rb_cIOBuffer, "initialize_copy", rb_io_buffer_initialize_copy, 1);
rb_define_method(rb_cIOBuffer, "inspect", rb_io_buffer_inspect, 0);
- rb_define_method(rb_cIOBuffer, "hexdump", rb_io_buffer_hexdump, -1);
+ rb_define_method(rb_cIOBuffer, "hexdump", rb_io_buffer_hexdump, 0);
rb_define_method(rb_cIOBuffer, "to_s", rb_io_buffer_to_s, 0);
rb_define_method(rb_cIOBuffer, "size", rb_io_buffer_size, 0);
rb_define_method(rb_cIOBuffer, "valid?", rb_io_buffer_valid_p, 0);
+ // Ownership:
rb_define_method(rb_cIOBuffer, "transfer", rb_io_buffer_transfer, 0);
- /* Indicates that the memory in the buffer is owned by someone else. See #external? for more details. */
+ // Flags:
rb_define_const(rb_cIOBuffer, "EXTERNAL", RB_INT2NUM(RB_IO_BUFFER_EXTERNAL));
-
- /* Indicates that the memory in the buffer is owned by the buffer. See #internal? for more details. */
rb_define_const(rb_cIOBuffer, "INTERNAL", RB_INT2NUM(RB_IO_BUFFER_INTERNAL));
-
- /* Indicates that the memory in the buffer is mapped by the operating system. See #mapped? for more details. */
rb_define_const(rb_cIOBuffer, "MAPPED", RB_INT2NUM(RB_IO_BUFFER_MAPPED));
-
- /* Indicates that the memory in the buffer is also mapped such that it can be shared with other processes. See #shared? for more details. */
rb_define_const(rb_cIOBuffer, "SHARED", RB_INT2NUM(RB_IO_BUFFER_SHARED));
-
- /* Indicates that the memory in the buffer is locked and cannot be resized or freed. See #locked? and #locked for more details. */
rb_define_const(rb_cIOBuffer, "LOCKED", RB_INT2NUM(RB_IO_BUFFER_LOCKED));
-
- /* Indicates that the memory in the buffer is mapped privately and changes won't be replicated to the underlying file. See #private? for more details. */
rb_define_const(rb_cIOBuffer, "PRIVATE", RB_INT2NUM(RB_IO_BUFFER_PRIVATE));
-
- /* Indicates that the memory in the buffer is read only, and attempts to modify it will fail. See #readonly? for more details.*/
rb_define_const(rb_cIOBuffer, "READONLY", RB_INT2NUM(RB_IO_BUFFER_READONLY));
- /* Refers to little endian byte order, where the least significant byte is stored first. See #get_value for more details. */
+ // Endian:
rb_define_const(rb_cIOBuffer, "LITTLE_ENDIAN", RB_INT2NUM(RB_IO_BUFFER_LITTLE_ENDIAN));
-
- /* Refers to big endian byte order, where the most significant byte is stored first. See #get_value for more details. */
rb_define_const(rb_cIOBuffer, "BIG_ENDIAN", RB_INT2NUM(RB_IO_BUFFER_BIG_ENDIAN));
-
- /* Refers to the byte order of the host machine. See #get_value for more details. */
rb_define_const(rb_cIOBuffer, "HOST_ENDIAN", RB_INT2NUM(RB_IO_BUFFER_HOST_ENDIAN));
-
- /* Refers to network byte order, which is the same as big endian. See #get_value for more details. */
rb_define_const(rb_cIOBuffer, "NETWORK_ENDIAN", RB_INT2NUM(RB_IO_BUFFER_NETWORK_ENDIAN));
rb_define_method(rb_cIOBuffer, "null?", rb_io_buffer_null_p, 0);
@@ -3711,7 +3439,6 @@ Init_IO_Buffer(void)
rb_define_method(rb_cIOBuffer, "mapped?", rb_io_buffer_mapped_p, 0);
rb_define_method(rb_cIOBuffer, "shared?", rb_io_buffer_shared_p, 0);
rb_define_method(rb_cIOBuffer, "locked?", rb_io_buffer_locked_p, 0);
- rb_define_method(rb_cIOBuffer, "private?", rb_io_buffer_private_p, 0);
rb_define_method(rb_cIOBuffer, "readonly?", io_buffer_readonly_p, 0);
// Locking to prevent changes while using pointer:
diff --git a/iseq.c b/iseq.c
index 27c5bb5d82..d17ce486c5 100644
--- a/iseq.c
+++ b/iseq.c
@@ -19,6 +19,7 @@
#endif
#include "eval_intern.h"
+#include "gc.h"
#include "id_table.h"
#include "internal.h"
#include "internal/bits.h"
@@ -26,15 +27,14 @@
#include "internal/compile.h"
#include "internal/error.h"
#include "internal/file.h"
-#include "internal/gc.h"
#include "internal/hash.h"
-#include "internal/ruby_parser.h"
+#include "internal/parse.h"
#include "internal/sanitizers.h"
#include "internal/symbol.h"
#include "internal/thread.h"
#include "internal/variable.h"
#include "iseq.h"
-#include "rjit.h"
+#include "mjit.h"
#include "ruby/util.h"
#include "vm_core.h"
#include "vm_callinfo.h"
@@ -113,7 +113,9 @@ remove_from_constant_cache(ID id, IC ic)
st_table *ics = (st_table *)lookup_result;
st_delete(ics, &ic_data, NULL);
- if (ics->num_entries == 0) {
+ if (ics->num_entries == 0 &&
+ // See comment in vm_track_constant_cache on why we need this check
+ id != vm->inserting_constant_cache_id) {
rb_id_table_delete(vm->constant_cache, id);
st_free_table(ics);
}
@@ -164,19 +166,15 @@ rb_iseq_free(const rb_iseq_t *iseq)
if (iseq && ISEQ_BODY(iseq)) {
iseq_clear_ic_references(iseq);
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
- rb_rjit_free_iseq(iseq); /* Notify RJIT */
+ mjit_free_iseq(iseq); /* Notify MJIT */
#if USE_YJIT
rb_yjit_iseq_free(body->yjit_payload);
- if (FL_TEST_RAW((VALUE)iseq, ISEQ_TRANSLATED)) {
- RUBY_ASSERT(rb_yjit_live_iseq_count > 0);
- rb_yjit_live_iseq_count--;
- }
#endif
ruby_xfree((void *)body->iseq_encoded);
ruby_xfree((void *)body->insns_info.body);
- ruby_xfree((void *)body->insns_info.positions);
+ if (body->insns_info.positions) ruby_xfree((void *)body->insns_info.positions);
#if VM_INSN_INFO_TABLE_IMPL == 2
- ruby_xfree(body->insns_info.succ_index_table);
+ if (body->insns_info.succ_index_table) ruby_xfree(body->insns_info.succ_index_table);
#endif
if (LIKELY(body->local_table != rb_iseq_shared_exc_local_tbl))
ruby_xfree((void *)body->local_table);
@@ -214,7 +212,7 @@ rb_iseq_free(const rb_iseq_t *iseq)
typedef VALUE iseq_value_itr_t(void *ctx, VALUE obj);
static inline void
-iseq_scan_bits(unsigned int page, iseq_bits_t bits, VALUE *code, VALUE *original_iseq)
+iseq_scan_bits(unsigned int page, iseq_bits_t bits, VALUE *code, iseq_value_itr_t *func, void *data)
{
unsigned int offset;
unsigned int page_offset = (page * ISEQ_MBITS_BITLENGTH);
@@ -222,17 +220,20 @@ iseq_scan_bits(unsigned int page, iseq_bits_t bits, VALUE *code, VALUE *original
while (bits) {
offset = ntz_intptr(bits);
VALUE op = code[page_offset + offset];
- rb_gc_mark_and_move(&code[page_offset + offset]);
- VALUE newop = code[page_offset + offset];
- if (original_iseq && newop != op) {
- original_iseq[page_offset + offset] = newop;
+ VALUE newop = func(data, op);
+ if (newop != op) {
+ code[page_offset + offset] = newop;
+ if (data) {
+ VALUE *original_iseq = (VALUE *)data;
+ original_iseq[page_offset + offset] = newop;
+ }
}
bits &= bits - 1; // Reset Lowest Set Bit (BLSR)
}
}
static void
-rb_iseq_mark_and_move_each_value(const rb_iseq_t *iseq, VALUE *original_iseq)
+rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
{
unsigned int size;
VALUE *code;
@@ -253,7 +254,10 @@ rb_iseq_mark_and_move_each_value(const rb_iseq_t *iseq, VALUE *original_iseq)
if (icvarc->entry) {
RUBY_ASSERT(!RB_TYPE_P(icvarc->entry->class_value, T_NONE));
- rb_gc_mark_and_move(&icvarc->entry->class_value);
+ VALUE nv = func(data, icvarc->entry->class_value);
+ if (icvarc->entry->class_value != nv) {
+ icvarc->entry->class_value = nv;
+ }
}
}
@@ -261,7 +265,10 @@ rb_iseq_mark_and_move_each_value(const rb_iseq_t *iseq, VALUE *original_iseq)
for (unsigned int i = 0; i < body->ise_size; i++, is_entries++) {
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)is_entries;
if (is->once.value) {
- rb_gc_mark_and_move(&is->once.value);
+ VALUE nv = func(data, is->once.value);
+ if (is->once.value != nv) {
+ is->once.value = nv;
+ }
}
}
@@ -269,7 +276,10 @@ rb_iseq_mark_and_move_each_value(const rb_iseq_t *iseq, VALUE *original_iseq)
for (unsigned int i = 0; i < body->ic_size; i++, is_entries++) {
IC ic = (IC)is_entries;
if (ic->entry) {
- rb_gc_mark_and_move_ptr(&ic->entry);
+ VALUE nv = func(data, (VALUE)ic->entry);
+ if ((VALUE)ic->entry != nv) {
+ ic->entry = (void *)nv;
+ }
}
}
}
@@ -277,141 +287,197 @@ rb_iseq_mark_and_move_each_value(const rb_iseq_t *iseq, VALUE *original_iseq)
// Embedded VALUEs
if (body->mark_bits.list) {
if (ISEQ_MBITS_BUFLEN(size) == 1) {
- iseq_scan_bits(0, body->mark_bits.single, code, original_iseq);
+ iseq_scan_bits(0, body->mark_bits.single, code, func, data);
}
else {
if (body->mark_bits.list) {
for (unsigned int i = 0; i < ISEQ_MBITS_BUFLEN(size); i++) {
iseq_bits_t bits = body->mark_bits.list[i];
- iseq_scan_bits(i, bits, code, original_iseq);
+ iseq_scan_bits(i, bits, code, func, data);
}
}
}
}
}
-static bool
-cc_is_active(const struct rb_callcache *cc, bool reference_updating)
+static VALUE
+update_each_insn_value(void *ctx, VALUE obj)
+{
+ return rb_gc_location(obj);
+}
+
+void
+rb_iseq_update_references(rb_iseq_t *iseq)
{
- if (cc) {
- if (reference_updating) {
- cc = (const struct rb_callcache *)rb_gc_location((VALUE)cc);
+ if (ISEQ_BODY(iseq)) {
+ struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
+
+ body->variable.coverage = rb_gc_location(body->variable.coverage);
+ body->variable.pc2branchindex = rb_gc_location(body->variable.pc2branchindex);
+ body->variable.script_lines = rb_gc_location(body->variable.script_lines);
+ body->location.label = rb_gc_location(body->location.label);
+ body->location.base_label = rb_gc_location(body->location.base_label);
+ body->location.pathobj = rb_gc_location(body->location.pathobj);
+ if (body->local_iseq) {
+ body->local_iseq = (struct rb_iseq_struct *)rb_gc_location((VALUE)body->local_iseq);
+ }
+ if (body->parent_iseq) {
+ body->parent_iseq = (struct rb_iseq_struct *)rb_gc_location((VALUE)body->parent_iseq);
}
+ if (body->mandatory_only_iseq) {
+ body->mandatory_only_iseq = (struct rb_iseq_struct *)rb_gc_location((VALUE)body->mandatory_only_iseq);
+ }
+ if (body->call_data) {
+ for (unsigned int i=0; i<body->ci_size; i++) {
+ struct rb_call_data *cds = body->call_data;
+ if (!SPECIAL_CONST_P((VALUE)cds[i].ci)) {
+ cds[i].ci = (struct rb_callinfo *)rb_gc_location((VALUE)cds[i].ci);
+ }
+ cds[i].cc = (struct rb_callcache *)rb_gc_location((VALUE)cds[i].cc);
+ }
+ }
+ VALUE *original_iseq = ISEQ_ORIGINAL_ISEQ(iseq);
+ rb_iseq_each_value(iseq, update_each_insn_value, (void *)original_iseq);
+
+ if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
+ int i, j;
- if (vm_cc_markable(cc)) {
- if (cc->klass) { // cc is not invalidated
- const struct rb_callable_method_entry_struct *cme = vm_cc_cme(cc);
- if (reference_updating) {
- cme = (const struct rb_callable_method_entry_struct *)rb_gc_location((VALUE)cme);
+ i = body->param.keyword->required_num;
+
+ for (j = 0; i < body->param.keyword->num; i++, j++) {
+ VALUE obj = body->param.keyword->default_values[j];
+ if (!UNDEF_P(obj)) {
+ body->param.keyword->default_values[j] = rb_gc_location(obj);
}
- if (!METHOD_ENTRY_INVALIDATED(cme)) {
- return true;
+ }
+ }
+
+ if (body->catch_table) {
+ struct iseq_catch_table *table = body->catch_table;
+ unsigned int i;
+ for (i = 0; i < table->size; i++) {
+ struct iseq_catch_table_entry *entry;
+ entry = UNALIGNED_MEMBER_PTR(table, entries[i]);
+ if (entry->iseq) {
+ entry->iseq = (rb_iseq_t *)rb_gc_location((VALUE)entry->iseq);
}
}
}
+#if USE_MJIT
+ mjit_update_references(iseq);
+#endif
+#if USE_YJIT
+ rb_yjit_iseq_update_references(body->yjit_payload);
+#endif
}
- return false;
+}
+
+static VALUE
+each_insn_value(void *ctx, VALUE obj)
+{
+ rb_gc_mark_movable(obj);
+ return obj;
}
void
-rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
+rb_iseq_mark(const rb_iseq_t *iseq)
{
RUBY_MARK_ENTER("iseq");
- rb_gc_mark_and_move(&iseq->wrapper);
+ RUBY_MARK_UNLESS_NULL(iseq->wrapper);
if (ISEQ_BODY(iseq)) {
- struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
+ const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
- rb_iseq_mark_and_move_each_value(iseq, reference_updating ? ISEQ_ORIGINAL_ISEQ(iseq) : NULL);
+ rb_iseq_each_value(iseq, each_insn_value, NULL);
- rb_gc_mark_and_move(&body->variable.coverage);
- rb_gc_mark_and_move(&body->variable.pc2branchindex);
- rb_gc_mark_and_move(&body->variable.script_lines);
- rb_gc_mark_and_move(&body->location.label);
- rb_gc_mark_and_move(&body->location.base_label);
- rb_gc_mark_and_move(&body->location.pathobj);
- if (body->local_iseq) rb_gc_mark_and_move_ptr(&body->local_iseq);
- if (body->parent_iseq) rb_gc_mark_and_move_ptr(&body->parent_iseq);
- if (body->mandatory_only_iseq) rb_gc_mark_and_move_ptr(&body->mandatory_only_iseq);
+ rb_gc_mark_movable(body->variable.coverage);
+ rb_gc_mark_movable(body->variable.pc2branchindex);
+ rb_gc_mark_movable(body->variable.script_lines);
+ rb_gc_mark_movable(body->location.label);
+ rb_gc_mark_movable(body->location.base_label);
+ rb_gc_mark_movable(body->location.pathobj);
+ RUBY_MARK_MOVABLE_UNLESS_NULL((VALUE)body->mandatory_only_iseq);
+ RUBY_MARK_MOVABLE_UNLESS_NULL((VALUE)body->parent_iseq);
if (body->call_data) {
- for (unsigned int i = 0; i < body->ci_size; i++) {
- struct rb_call_data *cds = body->call_data;
-
- if (cds[i].ci) rb_gc_mark_and_move_ptr(&cds[i].ci);
+ struct rb_call_data *cds = (struct rb_call_data *)body->call_data;
+ for (unsigned int i=0; i<body->ci_size; i++) {
+ const struct rb_callinfo *ci = cds[i].ci;
+ const struct rb_callcache *cc = cds[i].cc;
- if (cc_is_active(cds[i].cc, reference_updating)) {
- rb_gc_mark_and_move_ptr(&cds[i].cc);
+ if (vm_ci_markable(ci)) {
+ rb_gc_mark_movable((VALUE)ci);
}
- else {
- cds[i].cc = rb_vm_empty_cc();
+
+ if (cc) {
+ VM_ASSERT((cc->flags & VM_CALLCACHE_ON_STACK) == 0);
+
+ if (vm_cc_markable(cc)) {
+ if (!vm_cc_invalidated_p(cc)) {
+ rb_gc_mark_movable((VALUE)cc);
+ }
+ else {
+ cds[i].cc = rb_vm_empty_cc();
+ }
+ }
}
}
}
if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
+ int i, j;
+
+ i = keyword->required_num;
- for (int j = 0, i = keyword->required_num; i < keyword->num; i++, j++) {
- rb_gc_mark_and_move(&keyword->default_values[j]);
+ for (j = 0; i < keyword->num; i++, j++) {
+ VALUE obj = keyword->default_values[j];
+ if (!SPECIAL_CONST_P(obj)) {
+ rb_gc_mark_movable(obj);
+ }
}
}
if (body->catch_table) {
- struct iseq_catch_table *table = body->catch_table;
-
- for (unsigned int i = 0; i < table->size; i++) {
- struct iseq_catch_table_entry *entry;
+ const struct iseq_catch_table *table = body->catch_table;
+ unsigned int i;
+ for (i = 0; i < table->size; i++) {
+ const struct iseq_catch_table_entry *entry;
entry = UNALIGNED_MEMBER_PTR(table, entries[i]);
if (entry->iseq) {
- rb_gc_mark_and_move_ptr(&entry->iseq);
+ rb_gc_mark_movable((VALUE)entry->iseq);
}
}
}
- if (reference_updating) {
-#if USE_RJIT
- rb_rjit_iseq_update_references(body);
+#if USE_MJIT
+ mjit_mark_cc_entries(body);
#endif
#if USE_YJIT
- rb_yjit_iseq_update_references(body->yjit_payload);
-#endif
- }
- else {
-#if USE_RJIT
- rb_rjit_iseq_mark(body->rjit_blocks);
+ rb_yjit_iseq_mark(body->yjit_payload);
#endif
-#if USE_YJIT
- rb_yjit_iseq_mark(body->yjit_payload);
-#endif
- }
}
if (FL_TEST_RAW((VALUE)iseq, ISEQ_NOT_LOADED_YET)) {
- rb_gc_mark_and_move(&iseq->aux.loader.obj);
+ rb_gc_mark(iseq->aux.loader.obj);
}
else if (FL_TEST_RAW((VALUE)iseq, ISEQ_USE_COMPILE_DATA)) {
const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq);
- if (!reference_updating) {
- /* The operands in each instruction needs to be pinned because
- * if auto-compaction runs in iseq_set_sequence, then the objects
- * could exist on the generated_iseq buffer, which would not be
- * reference updated which can lead to T_MOVED (and subsequently
- * T_NONE) objects on the iseq. */
- rb_iseq_mark_and_pin_insn_storage(compile_data->insn.storage_head);
- }
+ rb_iseq_mark_insn_storage(compile_data->insn.storage_head);
- rb_gc_mark_and_move((VALUE *)&compile_data->err_info);
- rb_gc_mark_and_move((VALUE *)&compile_data->catch_table_ary);
+ RUBY_MARK_UNLESS_NULL(compile_data->err_info);
+ if (RTEST(compile_data->catch_table_ary)) {
+ rb_gc_mark(compile_data->catch_table_ary);
+ }
+ VM_ASSERT(compile_data != NULL);
}
else {
/* executable */
VM_ASSERT(ISEQ_EXECUTABLE_P(iseq));
-
if (iseq->aux.exec.local_hooks) {
- rb_hook_list_mark_and_update(iseq->aux.exec.local_hooks);
+ rb_hook_list_mark(iseq->aux.exec.local_hooks);
}
}
@@ -531,6 +597,19 @@ rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath)
rb_iseq_pathobj_new(path, realpath));
}
+// Make a dummy iseq for a dummy frame that exposes a path for profilers to inspect
+rb_iseq_t *
+rb_iseq_alloc_with_dummy_path(VALUE fname)
+{
+ rb_iseq_t *dummy_iseq = iseq_alloc();
+
+ ISEQ_BODY(dummy_iseq)->type = ISEQ_TYPE_TOP;
+ RB_OBJ_WRITE(dummy_iseq, &ISEQ_BODY(dummy_iseq)->location.pathobj, fname);
+ RB_OBJ_WRITE(dummy_iseq, &ISEQ_BODY(dummy_iseq)->location.label, fname);
+
+ return dummy_iseq;
+}
+
static rb_iseq_location_t *
iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_code_location_t *code_location, const int node_id)
{
@@ -728,6 +807,7 @@ static rb_compile_option_t COMPILE_OPTION_DEFAULT = {
OPT_SPECIALISED_INSTRUCTION, /* int specialized_instruction; */
OPT_OPERANDS_UNIFICATION, /* int operands_unification; */
OPT_INSTRUCTIONS_UNIFICATION, /* int instructions_unification; */
+ OPT_STACK_CACHING, /* int stack_caching; */
OPT_FROZEN_STRING_LITERAL,
OPT_DEBUG_FROZEN_STRING_LITERAL,
TRUE, /* coverage_enabled */
@@ -744,7 +824,7 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
else if (flag == Qfalse) { (o)->mem = 0; } \
}
#define SET_COMPILE_OPTION_NUM(o, h, mem) \
- { VALUE num = rb_hash_aref((h), ID2SYM(rb_intern(#mem))); \
+ { VALUE num = rb_hash_aref(opt, ID2SYM(rb_intern(#mem))); \
if (!NIL_P(num)) (o)->mem = NUM2INT(num); \
}
SET_COMPILE_OPTION(option, opt, inline_const_cache);
@@ -753,6 +833,7 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
SET_COMPILE_OPTION(option, opt, specialized_instruction);
SET_COMPILE_OPTION(option, opt, operands_unification);
SET_COMPILE_OPTION(option, opt, instructions_unification);
+ SET_COMPILE_OPTION(option, opt, stack_caching);
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
SET_COMPILE_OPTION(option, opt, coverage_enabled);
@@ -761,15 +842,11 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
#undef SET_COMPILE_OPTION_NUM
}
-static rb_compile_option_t *
-set_compile_option_from_ast(rb_compile_option_t *option, const rb_ast_body_t *ast)
+static void
+rb_iseq_make_compile_option(rb_compile_option_t *option, VALUE opt)
{
-#define SET_COMPILE_OPTION(o, a, mem) \
- ((a)->mem < 0 ? 0 : ((o)->mem = (a)->mem > 0))
- SET_COMPILE_OPTION(option, ast, frozen_string_literal);
- SET_COMPILE_OPTION(option, ast, coverage_enabled);
-#undef SET_COMPILE_OPTION
- return option;
+ Check_Type(opt, T_HASH);
+ set_compile_option_from_hash(option, opt);
}
static void
@@ -810,6 +887,7 @@ make_compile_option_value(rb_compile_option_t *option)
SET_COMPILE_OPTION(option, opt, specialized_instruction);
SET_COMPILE_OPTION(option, opt, operands_unification);
SET_COMPILE_OPTION(option, opt, instructions_unification);
+ SET_COMPILE_OPTION(option, opt, stack_caching);
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
SET_COMPILE_OPTION(option, opt, coverage_enabled);
@@ -864,7 +942,7 @@ iseq_new_setup_coverage(VALUE path, const rb_ast_body_t *ast, int line_offset)
VALUE coverages = rb_get_coverages();
if (RTEST(coverages)) {
- iseq_setup_coverage(coverages, path, ast, line_offset);
+ iseq_setup_coverage(coverages, path, ast, 0);
}
}
@@ -925,11 +1003,13 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea
rb_iseq_t *iseq = iseq_alloc();
rb_compile_option_t new_opt;
- if (!option) option = &COMPILE_OPTION_DEFAULT;
- if (ast) {
+ if (option) {
new_opt = *option;
- option = set_compile_option_from_ast(&new_opt, ast);
}
+ else {
+ new_opt = COMPILE_OPTION_DEFAULT;
+ }
+ if (ast && ast->compile_option) rb_iseq_make_compile_option(&new_opt, ast->compile_option);
VALUE script_lines = Qnil;
@@ -941,7 +1021,7 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea
}
prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1,
- parent, isolated_depth, type, script_lines, option);
+ parent, isolated_depth, type, script_lines, &new_opt);
rb_iseq_compile_node(iseq, node);
finish_iseq_build(iseq);
@@ -949,46 +1029,6 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea
return iseq_translate(iseq);
}
-VALUE rb_iseq_compile_prism_node(rb_iseq_t * iseq, pm_scope_node_t *scope_node, pm_parser_t *parser);
-
-/**
- * Initialize an rb_code_location_t with a prism location.
- */
-static void
-pm_code_location(rb_code_location_t *code_location, const pm_newline_list_t *newline_list, const pm_location_t *location)
-{
- pm_line_column_t start = pm_newline_list_line_column(newline_list, location->start);
- pm_line_column_t end = pm_newline_list_line_column(newline_list, location->end);
-
- *code_location = (rb_code_location_t) {
- .beg_pos = { .lineno = (int) start.line, .column = (int) start.column },
- .end_pos = { .lineno = (int) end.line, .column = (int) end.column }
- };
-}
-
-rb_iseq_t *
-pm_iseq_new_with_opt(pm_scope_node_t *scope_node, pm_parser_t *parser, VALUE name, VALUE path, VALUE realpath,
- int first_lineno, const rb_iseq_t *parent, int isolated_depth,
- enum rb_iseq_type type, const rb_compile_option_t *option)
-{
- rb_iseq_t *iseq = iseq_alloc();
- VALUE script_lines = Qnil;
- if (!option) option = &COMPILE_OPTION_DEFAULT;
-
- rb_code_location_t code_location;
- pm_code_location(&code_location, &parser->newline_list, &scope_node->base.location);
-
- // TODO: node_id
- int node_id = -1;
- prepare_iseq_build(iseq, name, path, realpath, first_lineno, &code_location, node_id,
- parent, isolated_depth, type, script_lines, option);
-
- rb_iseq_compile_prism_node(iseq, scope_node, parser);
- finish_iseq_build(iseq);
-
- return iseq_translate(iseq);
-}
-
rb_iseq_t *
rb_iseq_new_with_callback(
const struct rb_iseq_new_with_callback_callback_func * ifunc,
@@ -1170,7 +1210,6 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V
const rb_iseq_t *outer_scope = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
VALUE outer_scope_v = (VALUE)outer_scope;
rb_parser_set_context(parser, outer_scope, FALSE);
- rb_parser_set_script_lines(parser, RBOOL(ruby_vm_keep_script_lines));
RB_GC_GUARD(outer_scope_v);
ast = (*parse)(parser, file, src, ln);
}
@@ -1343,8 +1382,8 @@ rb_iseqw_new(const rb_iseq_t *iseq)
* InstructionSequence.compile(source[, file[, path[, line[, options]]]]) -> iseq
* InstructionSequence.new(source[, file[, path[, line[, options]]]]) -> iseq
*
- * Takes +source+, which can be a string of Ruby code, or an open +File+ object.
- * that contains Ruby source code.
+ * Takes +source+, a String of Ruby code and compiles it to an
+ * InstructionSequence.
*
* Optionally takes +file+, +path+, and +line+ which describe the file path,
* real path and first line number of the ruby code in +source+ which are
@@ -1366,10 +1405,6 @@ rb_iseqw_new(const rb_iseq_t *iseq)
* RubyVM::InstructionSequence.compile(File.read(path), path, File.expand_path(path))
* #=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>
*
- * file = File.open("test.rb")
- * RubyVM::InstructionSequence.compile(file)
- * #=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>
- *
* path = File.expand_path("test.rb")
* RubyVM::InstructionSequence.compile(File.read(path), path, path)
* #=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
@@ -1378,7 +1413,7 @@ rb_iseqw_new(const rb_iseq_t *iseq)
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
- VALUE src, file = Qnil, path = Qnil, line = Qnil, opt = Qnil;
+ VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
int i;
i = rb_scan_args(argc, argv, "1*:", &src, NULL, &opt);
@@ -1400,125 +1435,6 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, opt));
}
-static void
-iseqw_s_compile_prism_compile(pm_parser_t *parser, VALUE opt, rb_iseq_t *iseq, VALUE file, VALUE path, int first_lineno)
-{
- pm_node_t *node = pm_parse(parser);
- rb_code_location_t code_location;
- pm_code_location(&code_location, &parser->newline_list, &node->location);
-
- rb_compile_option_t option;
- make_compile_option(&option, opt);
- prepare_iseq_build(iseq, rb_fstring_lit("<compiled>"), file, path, first_lineno, &code_location, -1, NULL, 0, ISEQ_TYPE_TOP, Qnil, &option);
-
- pm_scope_node_t scope_node;
- pm_scope_node_init(node, &scope_node, NULL, parser);
- rb_iseq_compile_prism_node(iseq, &scope_node, parser);
-
- finish_iseq_build(iseq);
- pm_node_destroy(parser, node);
-}
-
-static VALUE
-iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self)
-{
- VALUE src, file = Qnil, path = Qnil, line = Qnil, opt = Qnil;
- int i;
-
- i = rb_scan_args(argc, argv, "1*:", &src, NULL, &opt);
- if (i > 4+NIL_P(opt)) rb_error_arity(argc, 1, 5);
- switch (i) {
- case 5: opt = argv[--i];
- case 4: line = argv[--i];
- case 3: path = argv[--i];
- case 2: file = argv[--i];
- }
-
- if (NIL_P(file)) file = rb_fstring_lit("<compiled>");
- if (NIL_P(path)) path = file;
- if (NIL_P(line)) line = INT2FIX(1);
-
- Check_Type(path, T_STRING);
- Check_Type(file, T_STRING);
-
- pm_options_t options = { 0 };
- pm_options_filepath_set(&options, RSTRING_PTR(file));
-
- int start_line = NUM2INT(line);
- pm_options_line_set(&options, start_line);
-
- pm_parser_t parser;
-
- if (RB_TYPE_P(src, T_FILE)) {
- FilePathValue(src);
- file = rb_fstring(src); /* rb_io_t->pathv gets frozen anyways */
-
- pm_string_t input;
- pm_string_mapped_init(&input, RSTRING_PTR(file));
-
- pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
- }
- else {
- pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(src), RSTRING_LEN(src), &options);
- }
-
- rb_iseq_t *iseq = iseq_alloc();
- iseqw_s_compile_prism_compile(&parser, opt, iseq, file, path, start_line);
- pm_parser_free(&parser);
- pm_options_free(&options);
-
- return iseqw_new(iseq);
-}
-
-static VALUE
-iseqw_s_compile_file_prism(int argc, VALUE *argv, VALUE self)
-{
- VALUE file = Qnil, opt = Qnil;
- int i;
-
- i = rb_scan_args(argc, argv, "1*:", &file, NULL, &opt);
- if (i > 1+NIL_P(opt)) rb_error_arity(argc, 1, 5);
- switch (i) {
- case 2: opt = argv[--i];
- }
- FilePathValue(file);
- file = rb_fstring(file); /* rb_io_t->pathv gets frozen anyways */
-
- pm_string_t input;
- pm_string_mapped_init(&input, RSTRING_PTR(file));
-
- pm_options_t options = { 0 };
- pm_options_filepath_set(&options, RSTRING_PTR(file));
-
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
-
- rb_iseq_t *iseq = iseq_alloc();
- iseqw_s_compile_prism_compile(&parser, opt, iseq, file, rb_realpath_internal(Qnil, file, 1), 1);
- pm_parser_free(&parser);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return iseqw_new(iseq);
-}
-
-rb_iseq_t *
-rb_iseq_new_main_prism(pm_string_t *input, pm_options_t *options, VALUE path)
-{
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
-
- if (NIL_P(path)) path = rb_fstring_lit("<compiled>");
- int start_line = 0;
- pm_options_line_set(options, start_line);
-
- rb_iseq_t *iseq = iseq_alloc();
- iseqw_s_compile_prism_compile(&parser, Qnil, iseq, path, path, start_line);
-
- pm_parser_free(&parser);
- return iseq;
-}
-
/*
* call-seq:
* InstructionSequence.compile_file(file[, options]) -> iseq
@@ -1607,6 +1523,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
* * +:operands_unification+
* * +:peephole_optimization+
* * +:specialized_instruction+
+ * * +:stack_caching+
* * +:tailcall_optimization+
*
* Additionally, +:debug_level+ can be set to an integer.
@@ -1670,7 +1587,11 @@ rb_iseqw_to_iseq(VALUE iseqw)
static VALUE
iseqw_eval(VALUE self)
{
- return rb_iseq_eval(iseqw_check(self));
+ const rb_iseq_t *iseq = iseqw_check(self);
+ if (0 == ISEQ_BODY(iseq)->iseq_size) {
+ rb_raise(rb_eTypeError, "attempt to evaluate dummy InstructionSequence");
+ }
+ return rb_iseq_eval(iseq);
}
/*
@@ -2092,7 +2013,7 @@ rb_iseq_node_id(const rb_iseq_t *iseq, size_t pos)
}
#endif
-rb_event_flag_t
+MJIT_FUNC_EXPORTED rb_event_flag_t
rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos)
{
const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pos);
@@ -2134,7 +2055,7 @@ local_var_name(const rb_iseq_t *diseq, VALUE level, VALUE op)
if (!name) {
name = rb_str_new_cstr("?");
}
- else if (!rb_is_local_id(lid)) {
+ else if (!rb_str_symname_p(name)) {
name = rb_str_inspect(name);
}
else {
@@ -2288,6 +2209,7 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
CALL_FLAG(FCALL);
CALL_FLAG(VCALL);
CALL_FLAG(ARGS_SIMPLE);
+ CALL_FLAG(BLOCKISEQ);
CALL_FLAG(TAILCALL);
CALL_FLAG(SUPER);
CALL_FLAG(ZSUPER);
@@ -2391,7 +2313,7 @@ rb_iseq_disasm_insn(VALUE ret, const VALUE *code, size_t pos,
{
rb_event_flag_t events = rb_iseq_event_flags(iseq, pos);
if (events) {
- str = rb_str_catf(str, "[%s%s%s%s%s%s%s%s%s%s%s%s]",
+ str = rb_str_catf(str, "[%s%s%s%s%s%s%s%s%s%s%s]",
events & RUBY_EVENT_LINE ? "Li" : "",
events & RUBY_EVENT_CLASS ? "Cl" : "",
events & RUBY_EVENT_END ? "En" : "",
@@ -2401,7 +2323,6 @@ rb_iseq_disasm_insn(VALUE ret, const VALUE *code, size_t pos,
events & RUBY_EVENT_C_RETURN ? "Cr" : "",
events & RUBY_EVENT_B_CALL ? "Bc" : "",
events & RUBY_EVENT_B_RETURN ? "Br" : "",
- events & RUBY_EVENT_RESCUE ? "Rs" : "",
events & RUBY_EVENT_COVERAGE_LINE ? "Cli" : "",
events & RUBY_EVENT_COVERAGE_BRANCH ? "Cbr" : "");
}
@@ -2491,6 +2412,7 @@ rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent)
rb_str_cat2(str, "== disasm: ");
rb_str_append(str, iseq_inspect(iseq));
+ rb_str_catf(str, " (catch: %s)", body->catch_except_p ? "true" : "false");
if ((l = RSTRING_LEN(str) - indent_len) < header_minlen) {
rb_str_modify_expand(str, header_minlen - l);
memset(RSTRING_END(str), '=', header_minlen - l);
@@ -2746,7 +2668,6 @@ push_event_info(const rb_iseq_t *iseq, rb_event_flag_t events, int line, VALUE a
C(RUBY_EVENT_END, "end", INT2FIX(line));
C(RUBY_EVENT_RETURN, "return", INT2FIX(line));
C(RUBY_EVENT_B_RETURN, "b_return", INT2FIX(line));
- C(RUBY_EVENT_RESCUE, "rescue", INT2FIX(line));
#undef C
}
@@ -2890,6 +2811,17 @@ iseqw_s_disasm(VALUE klass, VALUE body)
return NIL_P(iseqw) ? Qnil : rb_iseq_disasm(iseqw_check(iseqw));
}
+const char *
+ruby_node_name(int node)
+{
+ switch (node) {
+#include "node_name.inc"
+ default:
+ rb_bug("unknown node: %d", node);
+ return 0;
+ }
+}
+
static VALUE
register_label(struct st_table *table, unsigned long idx)
{
@@ -3264,7 +3196,6 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
CHECK_EVENT(RUBY_EVENT_RETURN);
CHECK_EVENT(RUBY_EVENT_B_CALL);
CHECK_EVENT(RUBY_EVENT_B_RETURN);
- CHECK_EVENT(RUBY_EVENT_RESCUE);
#undef CHECK_EVENT
prev_insn_info = info;
}
@@ -3453,19 +3384,13 @@ typedef struct insn_data_struct {
static insn_data_t insn_data[VM_INSTRUCTION_SIZE/2];
void
-rb_free_encoded_insn_data(void)
-{
- st_free_table(encoded_insn_data);
-}
-
-void
rb_vm_encoded_insn_data_table_init(void)
{
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
const void * const *table = rb_vm_get_insns_address_table();
#define INSN_CODE(insn) ((VALUE)table[insn])
#else
-#define INSN_CODE(insn) (insn)
+#define INSN_CODE(insn) ((VALUE)(insn))
#endif
st_data_t insn;
encoded_insn_data = st_init_numtable_with_size(VM_INSTRUCTION_SIZE / 2);
@@ -3730,32 +3655,9 @@ rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
}
}
+bool rb_vm_call_ivar_attrset_p(const vm_call_handler ch);
void rb_vm_cc_general(const struct rb_callcache *cc);
-static bool
-clear_attr_cc(VALUE v)
-{
- if (imemo_type_p(v, imemo_callcache) && vm_cc_ivar_p((const struct rb_callcache *)v)) {
- rb_vm_cc_general((struct rb_callcache *)v);
- return true;
- }
- else {
- return false;
- }
-}
-
-static bool
-clear_bf_cc(VALUE v)
-{
- if (imemo_type_p(v, imemo_callcache) && vm_cc_bf_p((const struct rb_callcache *)v)) {
- rb_vm_cc_general((struct rb_callcache *)v);
- return true;
- }
- else {
- return false;
- }
-}
-
static int
clear_attr_ccs_i(void *vstart, void *vend, size_t stride, void *data)
{
@@ -3763,35 +3665,20 @@ clear_attr_ccs_i(void *vstart, void *vend, size_t stride, void *data)
for (; v != (VALUE)vend; v += stride) {
void *ptr = asan_poisoned_object_p(v);
asan_unpoison_object(v, false);
- clear_attr_cc(v);
- asan_poison_object_if(ptr, v);
- }
- return 0;
-}
-void
-rb_clear_attr_ccs(void)
-{
- rb_objspace_each_objects(clear_attr_ccs_i, NULL);
-}
+ if (imemo_type_p(v, imemo_callcache) && rb_vm_call_ivar_attrset_p(((const struct rb_callcache *)v)->call_)) {
+ rb_vm_cc_general((struct rb_callcache *)v);
+ }
-static int
-clear_bf_ccs_i(void *vstart, void *vend, size_t stride, void *data)
-{
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- void *ptr = asan_poisoned_object_p(v);
- asan_unpoison_object(v, false);
- clear_bf_cc(v);
asan_poison_object_if(ptr, v);
}
return 0;
}
void
-rb_clear_bf_ccs(void)
+rb_clear_attr_ccs(void)
{
- rb_objspace_each_objects(clear_bf_ccs_i, NULL);
+ rb_objspace_each_objects(clear_attr_ccs_i, NULL);
}
static int
@@ -3807,9 +3694,8 @@ trace_set_i(void *vstart, void *vend, size_t stride, void *data)
if (rb_obj_is_iseq(v)) {
rb_iseq_trace_set(rb_iseq_check((rb_iseq_t *)v), turnon_events);
}
- else if (clear_attr_cc(v)) {
- }
- else if (clear_bf_cc(v)) {
+ else if (imemo_type_p(v, imemo_callcache) && rb_vm_call_ivar_attrset_p(((const struct rb_callcache *)v)->call_)) {
+ rb_vm_cc_general((struct rb_callcache *)v);
}
asan_poison_object_if(ptr, v);
@@ -4024,7 +3910,7 @@ succ_index_lookup(const struct succ_index_table *sd, int x)
* call-seq:
* iseq.script_lines -> array or nil
*
- * It returns recorded script lines if it is available.
+ * It returns recorded script lines if it is availalble.
* The script lines are not limited to the iseq range, but
* are entire lines of the source file.
*
@@ -4097,8 +3983,6 @@ Init_ISeq(void)
(void)iseq_s_load;
rb_define_singleton_method(rb_cISeq, "compile", iseqw_s_compile, -1);
- rb_define_singleton_method(rb_cISeq, "compile_prism", iseqw_s_compile_prism, -1);
- rb_define_singleton_method(rb_cISeq, "compile_file_prism", iseqw_s_compile_file_prism, -1);
rb_define_singleton_method(rb_cISeq, "new", iseqw_s_compile, -1);
rb_define_singleton_method(rb_cISeq, "compile_file", iseqw_s_compile_file, -1);
rb_define_singleton_method(rb_cISeq, "compile_option", iseqw_s_compile_option_get, 0);
diff --git a/iseq.h b/iseq.h
index d71f37ca13..2f83e7336d 100644
--- a/iseq.h
+++ b/iseq.h
@@ -11,9 +11,7 @@
**********************************************************************/
#include "internal/gc.h"
-#include "shape.h"
#include "vm_core.h"
-#include "prism_compile.h"
RUBY_EXTERN const int ruby_api_version[];
#define ISEQ_MAJOR_VERSION ((unsigned int)ruby_api_version[0])
@@ -84,10 +82,9 @@ ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
RUBY_EVENT_CALL | \
RUBY_EVENT_RETURN| \
RUBY_EVENT_C_CALL| \
- RUBY_EVENT_C_RETURN | \
- RUBY_EVENT_B_CALL | \
- RUBY_EVENT_B_RETURN | \
- RUBY_EVENT_RESCUE | \
+ RUBY_EVENT_C_RETURN| \
+ RUBY_EVENT_B_CALL| \
+ RUBY_EVENT_B_RETURN| \
RUBY_EVENT_COVERAGE_LINE| \
RUBY_EVENT_COVERAGE_BRANCH)
@@ -117,6 +114,7 @@ struct iseq_compile_data {
struct iseq_compile_data_storage *storage_current;
} insn;
bool in_rescue;
+ bool in_masgn;
int loopval_popped; /* used by NODE_BREAK */
int last_line;
int label_no;
@@ -128,7 +126,6 @@ struct iseq_compile_data {
struct rb_id_table *ivar_cache_table;
const struct rb_builtin_function *builtin_function_table;
const NODE *root_node;
- bool catch_except_p; // If a frame of this ISeq may catch exception, set true.
#if OPT_SUPPORT_JOKE
st_table *labels_table;
#endif
@@ -174,7 +171,6 @@ void rb_iseq_init_trace(rb_iseq_t *iseq);
int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line, bool target_bmethod);
int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
-rb_iseq_t * rb_iseq_new_main_prism(pm_string_t *input, pm_options_t *options, VALUE path);
#if VM_INSN_INFO_TABLE_IMPL == 2
unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body);
@@ -191,7 +187,7 @@ VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
VALUE locals, VALUE args,
VALUE exception, VALUE body);
-void rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *arena);
+void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *arena);
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
@@ -229,6 +225,7 @@ struct rb_compile_option_struct {
unsigned int specialized_instruction: 1;
unsigned int operands_unification: 1;
unsigned int instructions_unification: 1;
+ unsigned int stack_caching: 1;
unsigned int frozen_string_literal: 1;
unsigned int debug_frozen_string_literal: 1;
unsigned int coverage_enabled: 1;
@@ -274,11 +271,10 @@ struct iseq_catch_table_entry {
unsigned int sp;
};
-RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN()
-struct iseq_catch_table {
+PACKED_STRUCT_UNALIGNED(struct iseq_catch_table {
unsigned int size;
struct iseq_catch_table_entry entries[FLEX_ARY_LEN];
-} RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END();
+});
static inline int
iseq_catch_table_bytes(int n)
@@ -329,10 +325,6 @@ VALUE rb_iseq_defined_string(enum defined_type type);
/* vm.c */
VALUE rb_iseq_local_variables(const rb_iseq_t *iseq);
-attr_index_t rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq);
-
-void rb_free_encoded_insn_data(void);
-
RUBY_SYMBOL_EXPORT_END
#endif /* RUBY_ISEQ_H */
diff --git a/kernel.rb b/kernel.rb
index c6b3e44000..9cc58bc1d9 100644
--- a/kernel.rb
+++ b/kernel.rb
@@ -16,7 +16,7 @@ module Kernel
#++
#
def class
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_obj_class(self)'
end
@@ -65,7 +65,7 @@ module Kernel
#++
#
def frozen?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_obj_frozen_p(self)'
end
@@ -117,17 +117,8 @@ module Kernel
# # does not meet condition, drop value
# 2.then.detect(&:odd?) # => nil
#
- # Good usage for +then+ is value piping in method chains:
- #
- # require 'open-uri'
- # require 'json'
- #
- # construct_url(arguments).
- # then {|url| URI(url).read }.
- # then {|response| JSON.parse(response) }
- #
def then
- unless block_given?
+ unless Primitive.block_given_p
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
end
yield(self)
@@ -141,8 +132,17 @@ module Kernel
#
# "my string".yield_self {|s| s.upcase } #=> "MY STRING"
#
+ # Good usage for +then+ is value piping in method chains:
+ #
+ # require 'open-uri'
+ # require 'json'
+ #
+ # construct_url(arguments).
+ # then {|url| URI(url).read }.
+ # then {|response| JSON.parse(response) }
+ #
def yield_self
- unless block_given?
+ unless Primitive.block_given_p
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
end
yield(self)
@@ -150,47 +150,6 @@ module Kernel
module_function
- # call-seq:
- # loop { block }
- # loop -> an_enumerator
- #
- # Repeatedly executes the block.
- #
- # If no block is given, an enumerator is returned instead.
- #
- # loop do
- # print "Input: "
- # line = gets
- # break if !line or line =~ /^q/i
- # # ...
- # end
- #
- # StopIteration raised in the block breaks the loop. In this case,
- # loop returns the "result" value stored in the exception.
- #
- # enum = Enumerator.new { |y|
- # y << "one"
- # y << "two"
- # :ok
- # }
- #
- # result = loop {
- # puts enum.next
- # } #=> :ok
- def loop
- unless block_given?
- return enum_for(:loop) { Float::INFINITY }
- end
-
- begin
- while true
- yield
- end
- rescue StopIteration => e
- e.result
- end
- end
-
#
# call-seq:
# Float(arg, exception: true) -> float or nil
@@ -216,97 +175,4 @@ module Kernel
Primitive.rb_f_float(arg, exception)
end
end
-
- # call-seq:
- # Integer(object, base = 0, exception: true) -> integer or nil
- #
- # Returns an integer converted from +object+.
- #
- # Tries to convert +object+ to an integer
- # using +to_int+ first and +to_i+ second;
- # see below for exceptions.
- #
- # With a non-zero +base+, +object+ must be a string or convertible
- # to a string.
- #
- # ==== numeric objects
- #
- # With integer argument +object+ given, returns +object+:
- #
- # Integer(1) # => 1
- # Integer(-1) # => -1
- #
- # With floating-point argument +object+ given,
- # returns +object+ truncated to an integer:
- #
- # Integer(1.9) # => 1 # Rounds toward zero.
- # Integer(-1.9) # => -1 # Rounds toward zero.
- #
- # ==== string objects
- #
- # With string argument +object+ and zero +base+ given,
- # returns +object+ converted to an integer in base 10:
- #
- # Integer('100') # => 100
- # Integer('-100') # => -100
- #
- # With +base+ zero, string +object+ may contain leading characters
- # to specify the actual base (radix indicator):
- #
- # Integer('0100') # => 64 # Leading '0' specifies base 8.
- # Integer('0b100') # => 4 # Leading '0b', specifies base 2.
- # Integer('0x100') # => 256 # Leading '0x' specifies base 16.
- #
- # With a positive +base+ (in range 2..36) given, returns +object+
- # converted to an integer in the given base:
- #
- # Integer('100', 2) # => 4
- # Integer('100', 8) # => 64
- # Integer('-100', 16) # => -256
- #
- # With a negative +base+ (in range -36..-2) given, returns +object+
- # converted to an integer in the radix indicator if exists or
- # +-base+:
- #
- # Integer('0x100', -2) # => 256
- # Integer('100', -2) # => 4
- # Integer('0b100', -8) # => 4
- # Integer('100', -8) # => 64
- # Integer('0o100', -10) # => 64
- # Integer('100', -10) # => 100
- #
- # +base+ -1 is equal the -10 case.
- #
- # When converting strings, surrounding whitespace and embedded underscores
- # are allowed and ignored:
- #
- # Integer(' 100 ') # => 100
- # Integer('-1_0_0', 16) # => -256
- #
- # ==== other classes
- #
- # Examples with +object+ of various other classes:
- #
- # Integer(Rational(9, 10)) # => 0 # Rounds toward zero.
- # Integer(Complex(2, 0)) # => 2 # Imaginary part must be zero.
- # Integer(Time.now) # => 1650974042
- #
- # ==== keywords
- #
- # With optional keyword argument +exception+ given as +true+ (the default):
- #
- # - Raises TypeError if +object+ does not respond to +to_int+ or +to_i+.
- # - Raises TypeError if +object+ is +nil+.
- # - Raise ArgumentError if +object+ is an invalid string.
- #
- # With +exception+ given as +false+, an exception of any kind is suppressed
- # and +nil+ is returned.
-
- def Integer(arg, base = 0, exception: true)
- if Primitive.mandatory_only?
- Primitive.rb_f_integer1(arg)
- else
- Primitive.rb_f_integer(arg, base, exception);
- end
- end
end
diff --git a/lib/English.gemspec b/lib/English.gemspec
index 5f4eb420c2..a08542bcda 100644
--- a/lib/English.gemspec
+++ b/lib/English.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = "english"
- spec.version = "0.8.0"
+ spec.version = "0.7.2"
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.require_paths = ["lib"]
end
diff --git a/lib/English.rb b/lib/English.rb
index 03fe721991..ec90ff10cd 100644
--- a/lib/English.rb
+++ b/lib/English.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
# Include the English library file in a Ruby script, and you can
-# reference the global variables such as <code>$_</code> using less
+# reference the global variables such as <tt>$_</tt> using less
# cryptic names, listed below.
#
# Without 'English':
@@ -39,6 +39,7 @@
# $PROCESS_ID:: $$
# $CHILD_STATUS:: $?
# $LAST_MATCH_INFO:: $~
+# $IGNORECASE:: $=
# $ARGV:: $*
# $MATCH:: $&
# $PREMATCH:: $`
@@ -55,73 +56,87 @@ alias $ERROR_INFO $!
alias $ERROR_POSITION $@
# The default separator pattern used by String#split. May be set from
-# the command line using the <code>-F</code> flag.
+# the command line using the <tt>-F</tt> flag.
alias $FS $;
+
+# The default separator pattern used by String#split. May be set from
+# the command line using the <tt>-F</tt> flag.
alias $FIELD_SEPARATOR $;
# The separator string output between the parameters to methods such
# as Kernel#print and Array#join. Defaults to +nil+, which adds no
# text.
+alias $OFS $,
# The separator string output between the parameters to methods such
# as Kernel#print and Array#join. Defaults to +nil+, which adds no
# text.
-alias $OFS $,
alias $OUTPUT_FIELD_SEPARATOR $,
# The input record separator (newline by default). This is the value
# that routines such as Kernel#gets use to determine record
# boundaries. If set to +nil+, +gets+ will read the entire file.
alias $RS $/
+
+# The input record separator (newline by default). This is the value
+# that routines such as Kernel#gets use to determine record
+# boundaries. If set to +nil+, +gets+ will read the entire file.
alias $INPUT_RECORD_SEPARATOR $/
# The string appended to the output of every call to methods such as
# Kernel#print and IO#write. The default value is +nil+.
alias $ORS $\
+
+# The string appended to the output of every call to methods such as
+# Kernel#print and IO#write. The default value is +nil+.
alias $OUTPUT_RECORD_SEPARATOR $\
# The number of the last line read from the current input file.
-alias $NR $.
alias $INPUT_LINE_NUMBER $.
+# The number of the last line read from the current input file.
+alias $NR $.
+
# The last line read by Kernel#gets or
# Kernel#readline. Many string-related functions in the
-# Kernel module operate on <code>$_</code> by default. The variable is
+# Kernel module operate on <tt>$_</tt> by default. The variable is
# local to the current scope. Thread local.
alias $LAST_READ_LINE $_
# The destination of output for Kernel#print
# and Kernel#printf. The default value is
-# <code>$stdout</code>.
+# <tt>$stdout</tt>.
alias $DEFAULT_OUTPUT $>
# An object that provides access to the concatenation
# of the contents of all the files
-# given as command-line arguments, or <code>$stdin</code>
+# given as command-line arguments, or <tt>$stdin</tt>
# (in the case where there are no
-# arguments). <code>$<</code> supports methods similar to a
+# arguments). <tt>$<</tt> supports methods similar to a
# File object:
# +inmode+, +close+,
-# <code>closed?</code>, +each+,
-# <code>each_byte</code>, <code>each_line</code>,
-# +eof+, <code>eof?</code>, +file+,
+# <tt>closed?</tt>, +each+,
+# <tt>each_byte</tt>, <tt>each_line</tt>,
+# +eof+, <tt>eof?</tt>, +file+,
# +filename+, +fileno+,
# +getc+, +gets+, +lineno+,
-# <code>lineno=</code>, +path+,
-# +pos+, <code>pos=</code>,
+# <tt>lineno=</tt>, +path+,
+# +pos+, <tt>pos=</tt>,
# +read+, +readchar+,
# +readline+, +readlines+,
# +rewind+, +seek+, +skip+,
-# +tell+, <code>to_a</code>, <code>to_i</code>,
-# <code>to_io</code>, <code>to_s</code>, along with the
+# +tell+, <tt>to_a</tt>, <tt>to_i</tt>,
+# <tt>to_io</tt>, <tt>to_s</tt>, along with the
# methods in Enumerable. The method +file+
# returns a File object for the file currently
-# being read. This may change as <code>$<</code> reads
+# being read. This may change as <tt>$<</tt> reads
# through the files on the command line. Read only.
alias $DEFAULT_INPUT $<
# The process number of the program being executed. Read only.
alias $PID $$
+
+# The process number of the program being executed. Read only.
alias $PROCESS_ID $$
# The exit status of the last child process to terminate. Read
@@ -129,13 +144,16 @@ alias $PROCESS_ID $$
alias $CHILD_STATUS $?
# A +MatchData+ object that encapsulates the results of a successful
-# pattern match. The variables <code>$&</code>, <code>$`</code>, <code>$'</code>,
-# and <code>$1</code> to <code>$9</code> are all derived from
-# <code>$~</code>. Assigning to <code>$~</code> changes the values of these
+# pattern match. The variables <tt>$&</tt>, <tt>$`</tt>, <tt>$'</tt>,
+# and <tt>$1</tt> to <tt>$9</tt> are all derived from
+# <tt>$~</tt>. Assigning to <tt>$~</tt> changes the values of these
# derived variables. This variable is local to the current
# scope.
alias $LAST_MATCH_INFO $~
+# This variable is no longer effective. Deprecated.
+alias $IGNORECASE $=
+
# An array of strings containing the command-line
# options from the invocation of the program. Options
# used by the Ruby interpreter will have been
@@ -158,7 +176,7 @@ alias $PREMATCH $`
alias $POSTMATCH $'
# The contents of the highest-numbered group matched in the last
-# successful pattern match. Thus, in <code>"cat" =~ /(c|a)(t|z)/</code>,
-# <code>$+</code> will be set to "t". This variable is local to the
+# successful pattern match. Thus, in <tt>"cat" =~ /(c|a)(t|z)/</tt>,
+# <tt>$+</tt> will be set to "t". This variable is local to the
# current scope. Read only.
alias $LAST_PAREN_MATCH $+
diff --git a/lib/abbrev.gemspec b/lib/abbrev.gemspec
index 50c500bbc7..c28b960c8c 100644
--- a/lib/abbrev.gemspec
+++ b/lib/abbrev.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "abbrev"
+ spec.version = "0.1.1"
spec.authors = ["Akinori MUSHA"]
spec.email = ["knu@idaemons.org"]
diff --git a/lib/abbrev.rb b/lib/abbrev.rb
index 312085c289..2af01d2eae 100644
--- a/lib/abbrev.rb
+++ b/lib/abbrev.rb
@@ -47,7 +47,6 @@
# "w" => "winter" }
module Abbrev
- VERSION = "0.1.2"
# Given a set of strings, calculate the set of unambiguous abbreviations for
# those strings, and return a hash where the keys are all the possible
diff --git a/lib/base64.gemspec b/lib/base64.gemspec
index c013b7c1c2..daa0b7fa14 100644
--- a/lib/base64.gemspec
+++ b/lib/base64.gemspec
@@ -1,20 +1,13 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "base64"
+ spec.version = "0.1.1"
spec.authors = ["Yusuke Endoh"]
spec.email = ["mame@ruby-lang.org"]
spec.summary = %q{Support for encoding and decoding binary data using a Base64 representation.}
spec.description = %q{Support for encoding and decoding binary data using a Base64 representation.}
spec.homepage = "https://github.com/ruby/base64"
- spec.required_ruby_version = Gem::Requirement.new(">= 2.4")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.metadata["homepage_uri"] = spec.homepage
diff --git a/lib/base64.rb b/lib/base64.rb
index cd2ecc18ea..693aa1f519 100644
--- a/lib/base64.rb
+++ b/lib/base64.rb
@@ -1,330 +1,85 @@
# frozen_string_literal: true
#
-# \Module \Base64 provides methods for:
+# = base64.rb: methods for base64-encoding and -decoding strings
#
-# - Encoding a binary string (containing non-ASCII characters)
-# as a string of printable ASCII characters.
-# - Decoding such an encoded string.
-#
-# \Base64 is commonly used in contexts where binary data
-# is not allowed or supported:
-#
-# - Images in HTML or CSS files, or in URLs.
-# - Email attachments.
-#
-# A \Base64-encoded string is about one-third larger that its source.
-# See the {Wikipedia article}[https://en.wikipedia.org/wiki/Base64]
-# for more information.
-#
-# This module provides three pairs of encode/decode methods.
-# Your choices among these methods should depend on:
-#
-# - Which character set is to be used for encoding and decoding.
-# - Whether "padding" is to be used.
-# - Whether encoded strings are to contain newlines.
-#
-# Note: Examples on this page assume that the including program has executed:
-#
-# require 'base64'
-#
-# == Encoding Character Sets
-#
-# A \Base64-encoded string consists only of characters from a 64-character set:
-#
-# - <tt>('A'..'Z')</tt>.
-# - <tt>('a'..'z')</tt>.
-# - <tt>('0'..'9')</tt>.
-# - <tt>=</tt>, the 'padding' character.
-# - Either:
-# - <tt>%w[+ /]</tt>:
-# {RFC-2045-compliant}[https://datatracker.ietf.org/doc/html/rfc2045];
-# _not_ safe for URLs.
-# - <tt>%w[- _]</tt>:
-# {RFC-4648-compliant}[https://datatracker.ietf.org/doc/html/rfc4648];
-# safe for URLs.
-#
-# If you are working with \Base64-encoded strings that will come from
-# or be put into URLs, you should choose this encoder-decoder pair
-# of RFC-4648-compliant methods:
-#
-# - Base64.urlsafe_encode64 and Base64.urlsafe_decode64.
-#
-# Otherwise, you may choose any of the pairs in this module,
-# including the pair above, or the RFC-2045-compliant pairs:
-#
-# - Base64.encode64 and Base64.decode64.
-# - Base64.strict_encode64 and Base64.strict_decode64.
-#
-# == Padding
-#
-# \Base64-encoding changes a triplet of input bytes
-# into a quartet of output characters.
-#
-# <b>Padding in Encode Methods</b>
-#
-# Padding -- extending an encoded string with zero, one, or two trailing
-# <tt>=</tt> characters -- is performed by methods Base64.encode64,
-# Base64.strict_encode64, and, by default, Base64.urlsafe_encode64:
-#
-# Base64.encode64('s') # => "cw==\n"
-# Base64.strict_encode64('s') # => "cw=="
-# Base64.urlsafe_encode64('s') # => "cw=="
-# Base64.urlsafe_encode64('s', padding: false) # => "cw"
-#
-# When padding is performed, the encoded string is always of length <em>4n</em>,
-# where +n+ is a non-negative integer:
-#
-# - Input bytes of length <em>3n</em> generate unpadded output characters
-# of length <em>4n</em>:
-#
-# # n = 1: 3 bytes => 4 characters.
-# Base64.strict_encode64('123') # => "MDEy"
-# # n = 2: 6 bytes => 8 characters.
-# Base64.strict_encode64('123456') # => "MDEyMzQ1"
-#
-# - Input bytes of length <em>3n+1</em> generate padded output characters
-# of length <em>4(n+1)</em>, with two padding characters at the end:
-#
-# # n = 1: 4 bytes => 8 characters.
-# Base64.strict_encode64('1234') # => "MDEyMw=="
-# # n = 2: 7 bytes => 12 characters.
-# Base64.strict_encode64('1234567') # => "MDEyMzQ1Ng=="
-#
-# - Input bytes of length <em>3n+2</em> generate padded output characters
-# of length <em>4(n+1)</em>, with one padding character at the end:
-#
-# # n = 1: 5 bytes => 8 characters.
-# Base64.strict_encode64('12345') # => "MDEyMzQ="
-# # n = 2: 8 bytes => 12 characters.
-# Base64.strict_encode64('12345678') # => "MDEyMzQ1Njc="
-#
-# When padding is suppressed, for a positive integer <em>n</em>:
-#
-# - Input bytes of length <em>3n</em> generate unpadded output characters
-# of length <em>4n</em>:
-#
-# # n = 1: 3 bytes => 4 characters.
-# Base64.urlsafe_encode64('123', padding: false) # => "MDEy"
-# # n = 2: 6 bytes => 8 characters.
-# Base64.urlsafe_encode64('123456', padding: false) # => "MDEyMzQ1"
-#
-# - Input bytes of length <em>3n+1</em> generate unpadded output characters
-# of length <em>4n+2</em>, with two padding characters at the end:
-#
-# # n = 1: 4 bytes => 6 characters.
-# Base64.urlsafe_encode64('1234', padding: false) # => "MDEyMw"
-# # n = 2: 7 bytes => 10 characters.
-# Base64.urlsafe_encode64('1234567', padding: false) # => "MDEyMzQ1Ng"
-#
-# - Input bytes of length <em>3n+2</em> generate unpadded output characters
-# of length <em>4n+3</em>, with one padding character at the end:
-#
-# # n = 1: 5 bytes => 7 characters.
-# Base64.urlsafe_encode64('12345', padding: false) # => "MDEyMzQ"
-# # m = 2: 8 bytes => 11 characters.
-# Base64.urlsafe_encode64('12345678', padding: false) # => "MDEyMzQ1Njc"
-#
-# <b>Padding in Decode Methods</b>
-#
-# All of the \Base64 decode methods support (but do not require) padding.
-#
-# \Method Base64.decode64 does not check the size of the padding:
-#
-# Base64.decode64("MDEyMzQ1Njc") # => "01234567"
-# Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
-# Base64.decode64("MDEyMzQ1Njc==") # => "01234567"
-#
-# \Method Base64.strict_decode64 strictly enforces padding size:
-#
-# Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError
-# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
-# Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
-#
-# \Method Base64.urlsafe_decode64 allows padding in +str+,
-# which if present, must be correct:
-# see {Padding}[Base64.html#module-Base64-label-Padding], above:
-#
-# Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
-# Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567"
-# Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError.
-#
-# == Newlines
-#
-# An encoded string returned by Base64.encode64 or Base64.urlsafe_encode64
-# has an embedded newline character
-# after each 60-character sequence, and, if non-empty, at the end:
-#
-# # No newline if empty.
-# encoded = Base64.encode64("\x00" * 0)
-# encoded.index("\n") # => nil
-#
-# # Newline at end of short output.
-# encoded = Base64.encode64("\x00" * 1)
-# encoded.size # => 4
-# encoded.index("\n") # => 4
+
+# The Base64 module provides for the encoding (#encode64, #strict_encode64,
+# #urlsafe_encode64) and decoding (#decode64, #strict_decode64,
+# #urlsafe_decode64) of binary data using a Base64 representation.
#
-# # Newline at end of longer output.
-# encoded = Base64.encode64("\x00" * 45)
-# encoded.size # => 60
-# encoded.index("\n") # => 60
+# == Example
#
-# # Newlines embedded and at end of still longer output.
-# encoded = Base64.encode64("\x00" * 46)
-# encoded.size # => 65
-# encoded.rindex("\n") # => 65
-# encoded.split("\n").map {|s| s.size } # => [60, 4]
+# A simple encoding and decoding.
#
-# The string to be encoded may itself contain newlines,
-# which are encoded as \Base64:
+# require "base64"
#
-# # Base64.encode64("\n\n\n") # => "CgoK\n"
-# s = "This is line 1\nThis is line 2\n"
-# Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
+# enc = Base64.encode64('Send reinforcements')
+# # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
+# plain = Base64.decode64(enc)
+# # -> "Send reinforcements"
#
-module Base64
-
- VERSION = "0.2.0"
+# The purpose of using base64 to encode data is that it translates any
+# binary data into purely printable characters.
+module Base64
module_function
- # Returns a string containing the RFC-2045-compliant \Base64-encoding of +bin+.
- #
- # Per RFC 2045, the returned string may contain the URL-unsafe characters
- # <tt>+</tt> or <tt>/</tt>;
- # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
- #
- # Base64.encode64("\xFB\xEF\xBE") # => "++++\n"
- # Base64.encode64("\xFF\xFF\xFF") # => "////\n"
+ # Returns the Base64-encoded version of +bin+.
+ # This method complies with RFC 2045.
+ # Line feeds are added to every 60 encoded characters.
#
- # The returned string may include padding;
- # see {Padding}[Base64.html#module-Base64-label-Padding] above.
+ # require 'base64'
+ # Base64.encode64("Now is the time for all good coders\nto learn Ruby")
#
- # Base64.encode64('*') # => "Kg==\n"
- #
- # The returned string ends with a newline character, and if sufficiently long
- # will have one or more embedded newline characters;
- # see {Newlines}[Base64.html#module-Base64-label-Newlines] above:
- #
- # Base64.encode64('*') # => "Kg==\n"
- # Base64.encode64('*' * 46)
- # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq\nKg==\n"
- #
- # The string to be encoded may itself contain newlines,
- # which will be encoded as ordinary \Base64:
- #
- # Base64.encode64("\n\n\n") # => "CgoK\n"
- # s = "This is line 1\nThis is line 2\n"
- # Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
+ # <i>Generates:</i>
#
+ # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
+ # UnVieQ==
def encode64(bin)
[bin].pack("m")
end
- # Returns a string containing the decoding of an RFC-2045-compliant
- # \Base64-encoded string +str+:
- #
- # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
- # Base64.decode64(s) # => "This is line 1\nThis is line 2\n"
- #
- # Non-\Base64 characters in +str+ are ignored;
- # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
- # these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
- #
- # Base64.decode64("\x00\n-_") # => ""
- #
- # Padding in +str+ (even if incorrect) is ignored:
- #
- # Base64.decode64("MDEyMzQ1Njc") # => "01234567"
- # Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
- # Base64.decode64("MDEyMzQ1Njc==") # => "01234567"
- #
+ # Returns the Base64-decoded version of +str+.
+ # This method complies with RFC 2045.
+ # Characters outside the base alphabet are ignored.
+ #
+ # require 'base64'
+ # str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
+ # 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
+ # 'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
+ # puts Base64.decode64(str)
+ #
+ # <i>Generates:</i>
+ #
+ # This is line one
+ # This is line two
+ # This is line three
+ # And so on...
def decode64(str)
str.unpack1("m")
end
- # Returns a string containing the RFC-2045-compliant \Base64-encoding of +bin+.
- #
- # Per RFC 2045, the returned string may contain the URL-unsafe characters
- # <tt>+</tt> or <tt>/</tt>;
- # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
- #
- # Base64.strict_encode64("\xFB\xEF\xBE") # => "++++\n"
- # Base64.strict_encode64("\xFF\xFF\xFF") # => "////\n"
- #
- # The returned string may include padding;
- # see {Padding}[Base64.html#module-Base64-label-Padding] above.
- #
- # Base64.strict_encode64('*') # => "Kg==\n"
- #
- # The returned string will have no newline characters, regardless of its length;
- # see {Newlines}[Base64.html#module-Base64-label-Newlines] above:
- #
- # Base64.strict_encode64('*') # => "Kg=="
- # Base64.strict_encode64('*' * 46)
- # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg=="
- #
- # The string to be encoded may itself contain newlines,
- # which will be encoded as ordinary \Base64:
- #
- # Base64.strict_encode64("\n\n\n") # => "CgoK"
- # s = "This is line 1\nThis is line 2\n"
- # Base64.strict_encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
- #
+ # Returns the Base64-encoded version of +bin+.
+ # This method complies with RFC 4648.
+ # No line feeds are added.
def strict_encode64(bin)
[bin].pack("m0")
end
- # Returns a string containing the decoding of an RFC-2045-compliant
- # \Base64-encoded string +str+:
- #
- # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
- # Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n"
- #
- # Non-\Base64 characters in +str+ not allowed;
- # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
- # these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
- #
- # Base64.strict_decode64("\n") # Raises ArgumentError
- # Base64.strict_decode64('-') # Raises ArgumentError
- # Base64.strict_decode64('_') # Raises ArgumentError
- #
- # Padding in +str+, if present, must be correct:
- #
- # Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError
- # Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
- # Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
- #
+ # Returns the Base64-decoded version of +str+.
+ # This method complies with RFC 4648.
+ # ArgumentError is raised if +str+ is incorrectly padded or contains
+ # non-alphabet characters. Note that CR or LF are also rejected.
def strict_decode64(str)
str.unpack1("m0")
end
- # Returns the RFC-4648-compliant \Base64-encoding of +bin+.
- #
- # Per RFC 4648, the returned string will not contain the URL-unsafe characters
- # <tt>+</tt> or <tt>/</tt>,
- # but instead may contain the URL-safe characters
- # <tt>-</tt> and <tt>_</tt>;
- # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
- #
- # Base64.urlsafe_encode64("\xFB\xEF\xBE") # => "----"
- # Base64.urlsafe_encode64("\xFF\xFF\xFF") # => "____"
- #
- # By default, the returned string may have padding;
- # see {Padding}[Base64.html#module-Base64-label-Padding], above:
- #
- # Base64.urlsafe_encode64('*') # => "Kg=="
- #
- # Optionally, you can suppress padding:
- #
- # Base64.urlsafe_encode64('*', padding: false) # => "Kg"
- #
- # The returned string will have no newline characters, regardless of its length;
- # see {Newlines}[Base64.html#module-Base64-label-Newlines] above:
- #
- # Base64.urlsafe_encode64('*') # => "Kg=="
- # Base64.urlsafe_encode64('*' * 46)
- # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg=="
- #
+ # Returns the Base64-encoded version of +bin+.
+ # This method complies with ``Base 64 Encoding with URL and Filename Safe
+ # Alphabet'' in RFC 4648.
+ # The alphabet uses '-' instead of '+' and '_' instead of '/'.
+ # Note that the result can still contain '='.
+ # You can remove the padding by setting +padding+ as false.
def urlsafe_encode64(bin, padding: true)
str = strict_encode64(bin)
str.chomp!("==") or str.chomp!("=") unless padding
@@ -332,22 +87,14 @@ module Base64
str
end
- # Returns the decoding of an RFC-4648-compliant \Base64-encoded string +str+:
- #
- # +str+ may not contain non-Base64 characters;
- # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
- #
- # Base64.urlsafe_decode64('+') # Raises ArgumentError.
- # Base64.urlsafe_decode64('/') # Raises ArgumentError.
- # Base64.urlsafe_decode64("\n") # Raises ArgumentError.
- #
- # Padding in +str+, if present, must be correct:
- # see {Padding}[Base64.html#module-Base64-label-Padding], above:
- #
- # Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
- # Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567"
- # Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError.
- #
+ # Returns the Base64-decoded version of +str+.
+ # This method complies with ``Base 64 Encoding with URL and Filename Safe
+ # Alphabet'' in RFC 4648.
+ # The alphabet uses '-' instead of '+' and '_' instead of '/'.
+ #
+ # The padding character is optional.
+ # This method accepts both correctly-padded and unpadded input.
+ # Note that it still rejects incorrectly-padded input.
def urlsafe_decode64(str)
# NOTE: RFC 4648 does say nothing about unpadded input, but says that
# "the excess pad characters MAY also be ignored", so it is inferred that
diff --git a/lib/benchmark.gemspec b/lib/benchmark.gemspec
deleted file mode 100644
index d6e98db805..0000000000
--- a/lib/benchmark.gemspec
+++ /dev/null
@@ -1,30 +0,0 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{a performance benchmarking library}
- spec.description = spec.summary
- spec.homepage = "https://github.com/ruby/benchmark"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- # Specify which files should be added to the gem when it is released.
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.bindir = "exe"
- spec.executables = []
- spec.require_paths = ["lib"]
-end
diff --git a/lib/benchmark.rb b/lib/benchmark.rb
index 9f43255e42..79c782e262 100644
--- a/lib/benchmark.rb
+++ b/lib/benchmark.rb
@@ -121,8 +121,6 @@
module Benchmark
- VERSION = "0.3.0"
-
BENCHMARK_VERSION = "2002-04-25" # :nodoc:
# Invokes the block with a Benchmark::Report object, which
diff --git a/lib/benchmark/benchmark.gemspec b/lib/benchmark/benchmark.gemspec
new file mode 100644
index 0000000000..58b47d95e1
--- /dev/null
+++ b/lib/benchmark/benchmark.gemspec
@@ -0,0 +1,29 @@
+begin
+ require_relative "lib/benchmark/version"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "version"
+end
+
+Gem::Specification.new do |spec|
+ spec.name = "benchmark"
+ spec.version = Benchmark::VERSION
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{a performance benchmarking library}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/benchmark"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = []
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/benchmark/version.rb b/lib/benchmark/version.rb
new file mode 100644
index 0000000000..645966fd80
--- /dev/null
+++ b/lib/benchmark/version.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+module Benchmark
+ VERSION = "0.2.1"
+end
diff --git a/lib/bundled_gems.rb b/lib/bundled_gems.rb
deleted file mode 100644
index eea70ca19a..0000000000
--- a/lib/bundled_gems.rb
+++ /dev/null
@@ -1,195 +0,0 @@
-# -*- frozen-string-literal: true -*-
-
-# :stopdoc:
-
-module Gem::BUNDLED_GEMS
- SINCE = {
- "rexml" => "3.0.0",
- "rss" => "3.0.0",
- "webrick" => "3.0.0",
- "matrix" => "3.1.0",
- "net-ftp" => "3.1.0",
- "net-imap" => "3.1.0",
- "net-pop" => "3.1.0",
- "net-smtp" => "3.1.0",
- "prime" => "3.1.0",
- "racc" => "3.3.0",
- "abbrev" => "3.4.0",
- "base64" => "3.4.0",
- "bigdecimal" => "3.4.0",
- "csv" => "3.4.0",
- "drb" => "3.4.0",
- "getoptlong" => "3.4.0",
- "mutex_m" => "3.4.0",
- "nkf" => "3.4.0",
- "observer" => "3.4.0",
- "resolv-replace" => "3.4.0",
- "rinda" => "3.4.0",
- "syslog" => "3.4.0",
- }.freeze
-
- EXACT = {
- "abbrev" => true,
- "base64" => true,
- "bigdecimal" => true,
- "csv" => true,
- "drb" => true,
- "getoptlong" => true,
- "mutex_m" => true,
- "nkf" => true, "kconv" => "nkf",
- "observer" => true,
- "resolv-replace" => true,
- "rinda" => true,
- "syslog" => true,
- }.freeze
-
- PREFIXED = {
- "bigdecimal" => true,
- "csv" => true,
- "drb" => true,
- "rinda" => true,
- "syslog" => true,
- }.freeze
-
- WARNED = {} # unfrozen
-
- conf = ::RbConfig::CONFIG
- LIBDIR = (conf["rubylibdir"] + "/").freeze
- ARCHDIR = (conf["rubyarchdir"] + "/").freeze
- dlext = [conf["DLEXT"], "so"].uniq
- DLEXT = /\.#{Regexp.union(dlext)}\z/
- LIBEXT = /\.#{Regexp.union("rb", *dlext)}\z/
-
- def self.replace_require(specs)
- return if [::Kernel.singleton_class, ::Kernel].any? {|klass| klass.respond_to?(:no_warning_require) }
-
- spec_names = specs.to_a.each_with_object({}) {|spec, h| h[spec.name] = true }
-
- [::Kernel.singleton_class, ::Kernel].each do |kernel_class|
- kernel_class.send(:alias_method, :no_warning_require, :require)
- kernel_class.send(:define_method, :require) do |name|
- if message = ::Gem::BUNDLED_GEMS.warning?(name, specs: spec_names) # rubocop:disable Style/HashSyntax
- warn message, :uplevel => 1
- end
- kernel_class.send(:no_warning_require, name)
- end
- if kernel_class == ::Kernel
- kernel_class.send(:private, :require)
- else
- kernel_class.send(:public, :require)
- end
- end
- end
-
- def self.find_gem(path)
- if !path
- return
- elsif path.start_with?(ARCHDIR)
- n = path.delete_prefix(ARCHDIR).sub(DLEXT, "")
- elsif path.start_with?(LIBDIR)
- n = path.delete_prefix(LIBDIR).chomp(".rb")
- else
- return
- end
- EXACT[n] or PREFIXED[n = n[%r[\A[^/]+(?=/)]]] && n
- end
-
- def self.warning?(name, specs: nil)
- # name can be a feature name or a file path with String or Pathname
- feature = File.path(name)
- # bootsnap expands `require "csv"` to `require "#{LIBDIR}/csv.rb"`,
- # and `require "syslog"` to `require "#{ARCHDIR}/syslog.so"`.
- name = feature.delete_prefix(ARCHDIR)
- name.delete_prefix!(LIBDIR)
- name.tr!("/", "-")
- name.sub!(LIBEXT, "")
- return if specs.include?(name)
- _t, path = $:.resolve_feature_path(feature)
- if gem = find_gem(path)
- return if specs.include?(gem)
- caller = caller_locations(3, 3)&.find {|c| c&.absolute_path}
- return if find_gem(caller&.absolute_path)
- elsif SINCE[name] && !path
- gem = true
- else
- return
- end
-
- return if WARNED[name]
- WARNED[name] = true
- if gem == true
- gem = name
- "#{feature} was loaded from the standard library, but"
- elsif gem
- return if WARNED[gem]
- WARNED[gem] = true
- "#{feature} is found in #{gem}, which"
- else
- return
- end + build_message(gem)
- end
-
- def self.build_message(gem)
- msg = " #{RUBY_VERSION < SINCE[gem] ? "will no longer be" : "is not"} part of the default gems since Ruby #{SINCE[gem]}."
-
- if defined?(Bundler)
- msg += " Add #{gem} to your Gemfile or gemspec."
-
- # We detect the gem name from caller_locations. We need to skip 2 frames like:
- # lib/ruby/3.3.0+0/bundled_gems.rb:90:in `warning?'",
- # lib/ruby/3.3.0+0/bundler/rubygems_integration.rb:247:in `block (2 levels) in replace_require'",
- #
- # Additionally, we need to skip Bootsnap and Zeitwerk if present, these
- # gems decorate Kernel#require, so they are not really the ones issuing
- # the require call users should be warned about. Those are upwards.
- frames_to_skip = 2
- location = nil
- Thread.each_caller_location do |cl|
- if frames_to_skip >= 1
- frames_to_skip -= 1
- next
- end
-
- if cl.base_label != "require"
- location = cl.path
- break
- end
- end
-
- if location && File.file?(location) && !location.start_with?(Gem::BUNDLED_GEMS::LIBDIR)
- caller_gem = nil
- Gem.path.each do |path|
- if location =~ %r{#{path}/gems/([\w\-\.]+)}
- caller_gem = $1
- break
- end
- end
- if caller_gem
- msg += " Also contact author of #{caller_gem} to add #{gem} into its gemspec."
- end
- end
- else
- msg += " Install #{gem} from RubyGems."
- end
-
- msg
- end
-
- freeze
-end
-
-# for RubyGems without Bundler environment.
-# If loading library is not part of the default gems and the bundled gems, warn it.
-class LoadError
- def message
- return super unless path
-
- name = path.tr("/", "-")
- if !defined?(Bundler) && Gem::BUNDLED_GEMS::SINCE[name] && !Gem::BUNDLED_GEMS::WARNED[name]
- warn name + Gem::BUNDLED_GEMS.build_message(name)
- end
- super
- end
-end
-
-# :startdoc:
diff --git a/lib/bundler.rb b/lib/bundler.rb
index cf6ae2994d..f83268e9cd 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -17,7 +17,7 @@ require_relative "bundler/build_metadata"
# Bundler provides a consistent environment for Ruby projects by
# tracking and installing the exact gems and versions that are needed.
#
-# Bundler is a part of Ruby's standard library.
+# Since Ruby 2.6, Bundler is a part of Ruby's standard library.
#
# Bundler is used by creating _gemfiles_ listing all the project dependencies
# and (optionally) their versions and then using
@@ -39,9 +39,6 @@ module Bundler
environment_preserver.replace_with_backup
SUDO_MUTEX = Thread::Mutex.new
- autoload :Checksum, File.expand_path("bundler/checksum", __dir__)
- autoload :CLI, File.expand_path("bundler/cli", __dir__)
- autoload :CIDetector, File.expand_path("bundler/ci_detector", __dir__)
autoload :Definition, File.expand_path("bundler/definition", __dir__)
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
autoload :Deprecate, File.expand_path("bundler/deprecate", __dir__)
@@ -101,7 +98,9 @@ module Bundler
end
def create_bundle_path
- mkdir_p(bundle_path) unless bundle_path.exist?
+ SharedHelpers.filesystem_access(bundle_path.to_s) do |p|
+ mkdir_p(p)
+ end unless bundle_path.exist?
@bundle_path = bundle_path.realpath
rescue Errno::EEXIST
@@ -118,7 +117,7 @@ module Bundler
@bin_path ||= begin
path = settings[:bin] || "bin"
path = Pathname.new(path).expand_path(root).expand_path
- mkdir_p(path)
+ SharedHelpers.filesystem_access(path) {|p| FileUtils.mkdir_p(p) }
path
end
end
@@ -166,25 +165,6 @@ module Bundler
end
end
- # Automatically install dependencies if Bundler.settings[:auto_install] exists.
- # This is set through config cmd `bundle config set --global auto_install 1`.
- #
- # Note that this method `nil`s out the global Definition object, so it
- # should be called first, before you instantiate anything like an
- # `Installer` that'll keep a reference to the old one instead.
- def auto_install
- return unless settings[:auto_install]
-
- begin
- definition.specs
- rescue GemNotFound, GitError
- ui.info "Automatically installing missing gems."
- reset!
- CLI::Install.new({}).run
- reset!
- end
- end
-
# Setups Bundler environment (see Bundler.setup) if it is not already set,
# and loads all gems from groups specified. Unlike ::setup, can be called
# multiple times with different groups (if they were allowed by setup).
@@ -212,7 +192,7 @@ module Bundler
end
def environment
- SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load", print_caller_location: true
+ SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load", :print_caller_location => true
load
end
@@ -220,13 +200,12 @@ module Bundler
#
# @param unlock [Hash, Boolean, nil] Gems that have been requested
# to be updated or true if all gems should be updated
- # @param lockfile [Pathname] Path to Gemfile.lock
# @return [Bundler::Definition]
- def definition(unlock = nil, lockfile = default_lockfile)
+ def definition(unlock = nil)
@definition = nil if unlock
@definition ||= begin
configure
- Definition.build(default_gemfile, lockfile, unlock)
+ Definition.build(default_gemfile, default_lockfile, unlock)
end
end
@@ -351,6 +330,14 @@ module Bundler
def rm_rf(path)
FileUtils.remove_entry_secure(path) if path && File.exist?(path)
+ rescue ArgumentError
+ message = <<EOF
+It is a security vulnerability to allow your home directory to be world-writable, and bundler cannot continue.
+You should probably consider fixing this issue by running `chmod o-w ~` on *nix.
+Please refer to https://ruby-doc.org/stdlib-3.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
+EOF
+ File.world_writable?(path) ? Bundler.ui.warn(message) : raise
+ raise PathError, "Please fix the world-writable issue with your #{path} directory"
end
def settings
@@ -366,13 +353,13 @@ module Bundler
# @deprecated Use `unbundled_env` instead
def clean_env
- message =
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
"`Bundler.clean_env` has been deprecated in favor of `Bundler.unbundled_env`. " \
- "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`"
- removed_message =
- "`Bundler.clean_env` has been removed in favor of `Bundler.unbundled_env`. " \
- "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`"
- Bundler::SharedHelpers.major_deprecation(2, message, removed_message: removed_message, print_caller_location: true)
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`",
+ :print_caller_location => true
+ )
+
unbundled_env
end
@@ -409,13 +396,13 @@ module Bundler
# @deprecated Use `with_unbundled_env` instead
def with_clean_env
- message =
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
"`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \
- "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`"
- removed_message =
- "`Bundler.with_clean_env` has been removed in favor of `Bundler.with_unbundled_env`. " \
- "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`"
- Bundler::SharedHelpers.major_deprecation(2, message, removed_message: removed_message, print_caller_location: true)
+ "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`",
+ :print_caller_location => true
+ )
+
with_env(unbundled_env) { yield }
end
@@ -431,13 +418,13 @@ module Bundler
# @deprecated Use `unbundled_system` instead
def clean_system(*args)
- message =
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
"`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \
- "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`"
- removed_message =
- "`Bundler.clean_system` has been removed in favor of `Bundler.unbundled_system`. " \
- "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`"
- Bundler::SharedHelpers.major_deprecation(2, message, removed_message: removed_message, print_caller_location: true)
+ "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`",
+ :print_caller_location => true
+ )
+
with_env(unbundled_env) { Kernel.system(*args) }
end
@@ -453,13 +440,13 @@ module Bundler
# @deprecated Use `unbundled_exec` instead
def clean_exec(*args)
- message =
+ Bundler::SharedHelpers.major_deprecation(
+ 2,
"`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \
- "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`"
- removed_message =
- "`Bundler.clean_exec` has been removed in favor of `Bundler.unbundled_exec`. " \
- "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`"
- Bundler::SharedHelpers.major_deprecation(2, message, removed_message: removed_message, print_caller_location: true)
+ "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`",
+ :print_caller_location => true
+ )
+
with_env(unbundled_env) { Kernel.exec(*args) }
end
@@ -502,7 +489,7 @@ module Bundler
configured_bundle_path.use_system_gems?
end
- def mkdir_p(path)
+ def mkdir_p(path, options = {})
SharedHelpers.filesystem_access(path, :write) do |p|
FileUtils.mkdir_p(p)
end
@@ -528,16 +515,7 @@ module Bundler
end
def safe_load_marshal(data)
- if Gem.respond_to?(:load_safe_marshal)
- Gem.load_safe_marshal
- begin
- Gem::SafeMarshal.safe_load(data)
- rescue Gem::SafeMarshal::Reader::Error, Gem::SafeMarshal::Visitors::ToRuby::Error => e
- raise MarshalError, "#{e.class}: #{e.message}"
- end
- else
- load_marshal(data, marshal_proc: SafeMarshal.proc)
- end
+ load_marshal(data, :marshal_proc => SafeMarshal.proc)
end
def load_gemspec(file, validate = false)
diff --git a/lib/bundler/build_metadata.rb b/lib/bundler/build_metadata.rb
index 5d2a8b53bb..8bffb2fae7 100644
--- a/lib/bundler/build_metadata.rb
+++ b/lib/bundler/build_metadata.rb
@@ -29,7 +29,7 @@ module Bundler
# commit instance variable then we can't determine its commits SHA.
git_dir = File.expand_path("../../../.git", __dir__)
if File.directory?(git_dir)
- return @git_commit_sha = IO.popen(%w[git rev-parse --short HEAD], { chdir: git_dir }, &:read).strip.freeze
+ return @git_commit_sha = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze }
end
@git_commit_sha ||= "unknown"
diff --git a/lib/bundler/bundler.gemspec b/lib/bundler/bundler.gemspec
index 2d6269fae1..da50b46225 100644
--- a/lib/bundler/bundler.gemspec
+++ b/lib/bundler/bundler.gemspec
@@ -29,17 +29,15 @@ Gem::Specification.new do |s|
"source_code_uri" => "https://github.com/rubygems/rubygems/tree/master/bundler",
}
- s.required_ruby_version = ">= 3.0.0"
-
- # It should match the RubyGems version shipped with `required_ruby_version` above
- s.required_rubygems_version = ">= 3.2.3"
+ s.required_ruby_version = ">= 2.6.0"
+ s.required_rubygems_version = ">= 3.0.1"
s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
# include the gemspec itself because warbler breaks w/o it
s.files += %w[lib/bundler/bundler.gemspec]
- s.bindir = "exe"
+ s.bindir = "libexec"
s.executables = %w[bundle bundler]
s.require_paths = ["lib"]
end
diff --git a/lib/bundler/capistrano.rb b/lib/bundler/capistrano.rb
index 705840143f..1f3712d48e 100644
--- a/lib/bundler/capistrano.rb
+++ b/lib/bundler/capistrano.rb
@@ -17,6 +17,6 @@ end
Capistrano::Configuration.instance(:must_exist).load do
before "deploy:finalize_update", "bundle:install"
- Bundler::Deployment.define_task(self, :task, except: { no_release: true })
+ Bundler::Deployment.define_task(self, :task, :except => { :no_release => true })
set :rake, lambda { "#{fetch(:bundle_cmd, "bundle")} exec rake" }
end
diff --git a/lib/bundler/checksum.rb b/lib/bundler/checksum.rb
deleted file mode 100644
index 60ba93417c..0000000000
--- a/lib/bundler/checksum.rb
+++ /dev/null
@@ -1,254 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class Checksum
- ALGO_SEPARATOR = "="
- DEFAULT_ALGORITHM = "sha256"
- private_constant :DEFAULT_ALGORITHM
- DEFAULT_BLOCK_SIZE = 16_384
- private_constant :DEFAULT_BLOCK_SIZE
-
- class << self
- def from_gem_package(gem_package, algo = DEFAULT_ALGORITHM)
- return if Bundler.settings[:disable_checksum_validation]
- return unless source = gem_package.instance_variable_get(:@gem)
- return unless source.respond_to?(:with_read_io)
-
- source.with_read_io do |io|
- from_gem(io, source.path)
- ensure
- io.rewind
- end
- end
-
- def from_gem(io, pathname, algo = DEFAULT_ALGORITHM)
- digest = Bundler::SharedHelpers.digest(algo.upcase).new
- buf = String.new(capacity: DEFAULT_BLOCK_SIZE)
- digest << io.readpartial(DEFAULT_BLOCK_SIZE, buf) until io.eof?
- Checksum.new(algo, digest.hexdigest!, Source.new(:gem, pathname))
- end
-
- def from_api(digest, source_uri, algo = DEFAULT_ALGORITHM)
- return if Bundler.settings[:disable_checksum_validation]
-
- Checksum.new(algo, to_hexdigest(digest, algo), Source.new(:api, source_uri))
- end
-
- def from_lock(lock_checksum, lockfile_location)
- algo, digest = lock_checksum.strip.split(ALGO_SEPARATOR, 2)
- Checksum.new(algo, to_hexdigest(digest, algo), Source.new(:lock, lockfile_location))
- end
-
- def to_hexdigest(digest, algo = DEFAULT_ALGORITHM)
- return digest unless algo == DEFAULT_ALGORITHM
- return digest if digest.match?(/\A[0-9a-f]{64}\z/i)
-
- if digest.match?(%r{\A[-0-9a-z_+/]{43}={0,2}\z}i)
- digest = digest.tr("-_", "+/") # fix urlsafe base64
- digest.unpack1("m0").unpack1("H*")
- else
- raise ArgumentError, "#{digest.inspect} is not a valid SHA256 hex or base64 digest"
- end
- end
- end
-
- attr_reader :algo, :digest, :sources
-
- def initialize(algo, digest, source)
- @algo = algo
- @digest = digest
- @sources = [source]
- end
-
- def ==(other)
- match?(other) && other.sources == sources
- end
-
- alias_method :eql?, :==
-
- def same_source?(other)
- sources.include?(other.sources.first)
- end
-
- def match?(other)
- other.is_a?(self.class) && other.digest == digest && other.algo == algo
- end
-
- def hash
- digest.hash
- end
-
- def to_s
- "#{to_lock} (from #{sources.first}#{", ..." if sources.size > 1})"
- end
-
- def to_lock
- "#{algo}#{ALGO_SEPARATOR}#{digest}"
- end
-
- def merge!(other)
- return nil unless match?(other)
-
- @sources.concat(other.sources).uniq!
- self
- end
-
- def formatted_sources
- sources.join("\n and ").concat("\n")
- end
-
- def removable?
- sources.all?(&:removable?)
- end
-
- def removal_instructions
- msg = +""
- i = 1
- sources.each do |source|
- msg << " #{i}. #{source.removal}\n"
- i += 1
- end
- msg << " #{i}. run `bundle install`\n"
- end
-
- def inspect
- abbr = "#{algo}#{ALGO_SEPARATOR}#{digest[0, 8]}"
- from = "from #{sources.join(" and ")}"
- "#<#{self.class}:#{object_id} #{abbr} #{from}>"
- end
-
- class Source
- attr_reader :type, :location
-
- def initialize(type, location)
- @type = type
- @location = location
- end
-
- def removable?
- type == :lock || type == :gem
- end
-
- def ==(other)
- other.is_a?(self.class) && other.type == type && other.location == location
- end
-
- # phrased so that the usual string format is grammatically correct
- # rake (10.3.2) sha256=abc123 from #{to_s}
- def to_s
- case type
- when :lock
- "the lockfile CHECKSUMS at #{location}"
- when :gem
- "the gem at #{location}"
- when :api
- "the API at #{location}"
- else
- "#{location} (#{type})"
- end
- end
-
- # A full sentence describing how to remove the checksum
- def removal
- case type
- when :lock
- "remove the matching checksum in #{location}"
- when :gem
- "remove the gem at #{location}"
- when :api
- "checksums from #{location} cannot be locally modified, you may need to update your sources"
- else
- "remove #{location} (#{type})"
- end
- end
- end
-
- class Store
- attr_reader :store
- protected :store
-
- def initialize
- @store = {}
- @store_mutex = Mutex.new
- end
-
- def inspect
- "#<#{self.class}:#{object_id} size=#{store.size}>"
- end
-
- # Replace when the new checksum is from the same source.
- # The primary purpose is registering checksums from gems where there are
- # duplicates of the same gem (according to full_name) in the index.
- #
- # In particular, this is when 2 gems have two similar platforms, e.g.
- # "darwin20" and "darwin-20", both of which resolve to darwin-20.
- # In the Index, the later gem replaces the former, so we do that here.
- #
- # However, if the new checksum is from a different source, we register like normal.
- # This ensures a mismatch error where there are multiple top level sources
- # that contain the same gem with different checksums.
- def replace(spec, checksum)
- return unless checksum
-
- lock_name = spec.name_tuple.lock_name
- @store_mutex.synchronize do
- existing = fetch_checksum(lock_name, checksum.algo)
- if !existing || existing.same_source?(checksum)
- store_checksum(lock_name, checksum)
- else
- merge_checksum(lock_name, checksum, existing)
- end
- end
- end
-
- def register(spec, checksum)
- return unless checksum
-
- register_checksum(spec.name_tuple.lock_name, checksum)
- end
-
- def merge!(other)
- other.store.each do |lock_name, checksums|
- checksums.each do |_algo, checksum|
- register_checksum(lock_name, checksum)
- end
- end
- end
-
- def to_lock(spec)
- lock_name = spec.name_tuple.lock_name
- checksums = @store[lock_name]
- if checksums
- "#{lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}"
- else
- lock_name
- end
- end
-
- private
-
- def register_checksum(lock_name, checksum)
- @store_mutex.synchronize do
- existing = fetch_checksum(lock_name, checksum.algo)
- if existing
- merge_checksum(lock_name, checksum, existing)
- else
- store_checksum(lock_name, checksum)
- end
- end
- end
-
- def merge_checksum(lock_name, checksum, existing)
- existing.merge!(checksum) || raise(ChecksumMismatchError.new(lock_name, existing, checksum))
- end
-
- def store_checksum(lock_name, checksum)
- (@store[lock_name] ||= {})[checksum.algo] = checksum
- end
-
- def fetch_checksum(lock_name, algo)
- @store[lock_name]&.fetch(algo, nil)
- end
- end
- end
-end
diff --git a/lib/bundler/ci_detector.rb b/lib/bundler/ci_detector.rb
deleted file mode 100644
index e5fedbdea8..0000000000
--- a/lib/bundler/ci_detector.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module CIDetector
- # NOTE: Any changes made here will need to be made to both lib/rubygems/ci_detector.rb and
- # bundler/lib/bundler/ci_detector.rb (which are enforced duplicates).
- # TODO: Drop that duplication once bundler drops support for RubyGems 3.4
- #
- # ## Recognized CI providers, their signifiers, and the relevant docs ##
- #
- # Travis CI - CI, TRAVIS https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
- # Cirrus CI - CI, CIRRUS_CI https://cirrus-ci.org/guide/writing-tasks/#environment-variables
- # Circle CI - CI, CIRCLECI https://circleci.com/docs/variables/#built-in-environment-variables
- # Gitlab CI - CI, GITLAB_CI https://docs.gitlab.com/ee/ci/variables/
- # AppVeyor - CI, APPVEYOR https://www.appveyor.com/docs/environment-variables/
- # CodeShip - CI_NAME https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables#_default_environment_variables
- # dsari - CI, DSARI https://github.com/rfinnie/dsari#running
- # Jenkins - BUILD_NUMBER https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
- # TeamCity - TEAMCITY_VERSION https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html#Predefined+Server+Build+Parameters
- # Appflow - CI_BUILD_ID https://ionic.io/docs/appflow/automation/environments#predefined-environments
- # TaskCluster - TASKCLUSTER_ROOT_URL https://docs.taskcluster.net/docs/manual/design/env-vars
- # Semaphore - CI, SEMAPHORE https://docs.semaphoreci.com/ci-cd-environment/environment-variables/
- # BuildKite - CI, BUILDKITE https://buildkite.com/docs/pipelines/environment-variables
- # GoCD - GO_SERVER_URL https://docs.gocd.org/current/faq/dev_use_current_revision_in_build.html
- # GH Actions - CI, GITHUB_ACTIONS https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
- #
- # ### Some "standard" ENVs that multiple providers may set ###
- #
- # * CI - this is set by _most_ (but not all) CI providers now; it's approaching a standard.
- # * CI_NAME - Not as frequently used, but some providers set this to specify their own name
-
- # Any of these being set is a reasonably reliable indicator that we are
- # executing in a CI environment.
- ENV_INDICATORS = [
- "CI",
- "CI_NAME",
- "CONTINUOUS_INTEGRATION",
- "BUILD_NUMBER",
- "CI_APP_ID",
- "CI_BUILD_ID",
- "CI_BUILD_NUMBER",
- "RUN_ID",
- "TASKCLUSTER_ROOT_URL",
- ].freeze
-
- # For each CI, this env suffices to indicate that we're on _that_ CI's
- # containers. (A few of them only supply a CI_NAME variable, which is also
- # nice). And if they set "CI" but we can't tell which one they are, we also
- # want to know that - a bare "ci" without another token tells us as much.
- ENV_DESCRIPTORS = {
- "TRAVIS" => "travis",
- "CIRCLECI" => "circle",
- "CIRRUS_CI" => "cirrus",
- "DSARI" => "dsari",
- "SEMAPHORE" => "semaphore",
- "JENKINS_URL" => "jenkins",
- "BUILDKITE" => "buildkite",
- "GO_SERVER_URL" => "go",
- "GITLAB_CI" => "gitlab",
- "GITHUB_ACTIONS" => "github",
- "TASKCLUSTER_ROOT_URL" => "taskcluster",
- "CI" => "ci",
- }.freeze
-
- def self.ci?
- ENV_INDICATORS.any? {|var| ENV.include?(var) }
- end
-
- def self.ci_strings
- matching_names = ENV_DESCRIPTORS.select {|env, _| ENV[env] }.values
- matching_names << ENV["CI_NAME"].downcase if ENV["CI_NAME"]
- matching_names.reject(&:empty?).sort.uniq
- end
- end
-end
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 40f19c7fed..a3eb494db2 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -5,7 +5,6 @@ require_relative "vendored_thor"
module Bundler
class CLI < Thor
require_relative "cli/common"
- require_relative "cli/install"
package_name "Bundler"
@@ -70,7 +69,7 @@ module Bundler
Bundler.settings.set_command_option_if_given :retry, options[:retry]
current_cmd = args.last[:current_command].name
- Bundler.auto_install if AUTO_INSTALL_CMDS.include?(current_cmd)
+ auto_install if AUTO_INSTALL_CMDS.include?(current_cmd)
rescue UnknownArgumentError => e
raise InvalidOption, e.message
ensure
@@ -81,10 +80,10 @@ module Bundler
unprinted_warnings.each {|w| Bundler.ui.warn(w) }
end
- check_unknown_options!(except: [:config, :exec])
+ check_unknown_options!(:except => [:config, :exec])
stop_on_unknown_option! :exec
- desc "cli_help", "Prints a summary of bundler commands", hide: true
+ desc "cli_help", "Prints a summary of bundler commands", :hide => true
def cli_help
version
Bundler.ui.info "\n"
@@ -100,23 +99,21 @@ module Bundler
shell.say "Bundler commands:\n\n"
shell.say " Primary commands:\n"
- shell.print_table(primary_commands, indent: 4, truncate: true)
+ shell.print_table(primary_commands, :indent => 4, :truncate => true)
shell.say
shell.say " Utilities:\n"
- shell.print_table(utilities, indent: 4, truncate: true)
+ shell.print_table(utilities, :indent => 4, :truncate => true)
shell.say
self.class.send(:class_options_help, shell)
end
default_task(Bundler.feature_flag.default_cli_command)
- class_option "no-color", type: :boolean, desc: "Disable colorization in output"
- class_option "retry", type: :numeric, aliases: "-r", banner: "NUM",
- desc: "Specify the number of times you wish to attempt network commands"
- class_option "verbose", type: :boolean, desc: "Enable verbose output mode", aliases: "-V"
+ class_option "no-color", :type => :boolean, :desc => "Disable colorization in output"
+ class_option "retry", :type => :numeric, :aliases => "-r", :banner => "NUM",
+ :desc => "Specify the number of times you wish to attempt network commands"
+ class_option "verbose", :type => :boolean, :desc => "Enable verbose output mode", :aliases => "-V"
def help(cli = nil)
- cli = self.class.all_aliases[cli] if self.class.all_aliases[cli]
-
case cli
when "gemfile" then command = "gemfile"
when nil then command = "bundle"
@@ -130,8 +127,8 @@ module Bundler
if man_pages.include?(command)
man_page = man_pages[command]
- if Bundler.which("man") && !man_path.match?(%r{^file:/.+!/META-INF/jruby.home/.+})
- Kernel.exec("man", man_page)
+ if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+}
+ Kernel.exec "man #{man_page}"
else
puts File.read("#{man_path}/#{File.basename(man_page)}.ronn")
end
@@ -158,8 +155,8 @@ module Bundler
Gemfile to a gem with a gemspec, the --gemspec option will automatically add each
dependency listed in the gemspec file to the newly created Gemfile.
D
- method_option "gemspec", type: :string, banner: "Use the specified .gemspec to create the Gemfile"
- method_option "gemfile", type: :string, banner: "Use the specified name for the gemfile instead of 'Gemfile'"
+ method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
+ method_option "gemfile", :type => :string, :banner => "Use the specified name for the gemfile instead of 'Gemfile'"
def init
require_relative "cli/init"
Init.new(options.dup).run
@@ -171,9 +168,12 @@ module Bundler
all gems are found, Bundler prints a success message and exits with a status of 0.
If not, the first missing gem is listed and Bundler exits status 1.
D
- method_option "dry-run", type: :boolean, default: false, banner: "Lock the Gemfile"
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
- method_option "path", type: :string, banner: "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
+ method_option "dry-run", :type => :boolean, :default => false, :banner =>
+ "Lock the Gemfile"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
+ method_option "path", :type => :string, :banner =>
+ "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
def check
remembered_flag_deprecation("path")
@@ -187,14 +187,10 @@ module Bundler
long_desc <<-D
Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid. If the gem is not found, Bundler prints a error message and if gem could not be removed due to any reason Bundler will display a warning.
D
- method_option "install", type: :boolean, banner: "Runs 'bundle install' after removing the gems from the Gemfile"
+ method_option "install", :type => :boolean, :banner =>
+ "Runs 'bundle install' after removing the gems from the Gemfile"
def remove(*gems)
- if ARGV.include?("--install")
- message = "The `--install` flag has been deprecated. `bundle install` is triggered by default."
- removed_message = "The `--install` flag has been removed. `bundle install` is triggered by default."
- SharedHelpers.major_deprecation(2, message, removed_message: removed_message)
- end
-
+ SharedHelpers.major_deprecation(2, "The `--install` flag has been deprecated. `bundle install` is triggered by default.") if ARGV.include?("--install")
require_relative "cli/remove"
Remove.new(gems, options).run
end
@@ -210,40 +206,58 @@ module Bundler
If the bundle has already been installed, bundler will tell you so and then exit.
D
- method_option "binstubs", type: :string, lazy_default: "bin", banner: "Generate bin stubs for bundled gems to ./bin"
- method_option "clean", type: :boolean, banner: "Run bundle clean automatically after install"
- method_option "deployment", type: :boolean, banner: "Install using defaults tuned for deployment environments"
- method_option "frozen", type: :boolean, banner: "Do not allow the Gemfile.lock to be updated after this install"
- method_option "full-index", type: :boolean, banner: "Fall back to using the single-file index of all gems"
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
- method_option "jobs", aliases: "-j", type: :numeric, banner: "Specify the number of jobs to run in parallel"
- method_option "local", type: :boolean, banner: "Do not attempt to fetch gems remotely and use the gem cache instead"
- method_option "prefer-local", type: :boolean, banner: "Only attempt to fetch gems remotely if not present locally, even if newer versions are available remotely"
- method_option "no-cache", type: :boolean, banner: "Don't update the existing gem cache."
- method_option "redownload", type: :boolean, aliases: "--force", banner: "Force downloading every gem."
- method_option "no-prune", type: :boolean, banner: "Don't remove stale gems from the cache."
- method_option "path", type: :string, banner: "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
- method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
- method_option "shebang", type: :string, banner: "Specify a different shebang executable name than the default (usually 'ruby')"
- method_option "standalone", type: :array, lazy_default: [], banner: "Make a bundle that can work without the Bundler runtime"
- method_option "system", type: :boolean, banner: "Install to the system location ($BUNDLE_PATH or $GEM_HOME) even if the bundle was previously installed somewhere else for this application"
- method_option "trust-policy", alias: "P", type: :string, banner: "Gem trust policy (like gem install -P). Must be one of " +
- Bundler.rubygems.security_policy_keys.join("|")
- method_option "without", type: :array, banner: "Exclude gems that are part of the specified named group."
- method_option "with", type: :array, banner: "Include gems that are part of the specified named group."
+ method_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
+ "Generate bin stubs for bundled gems to ./bin"
+ method_option "clean", :type => :boolean, :banner =>
+ "Run bundle clean automatically after install"
+ method_option "deployment", :type => :boolean, :banner =>
+ "Install using defaults tuned for deployment environments"
+ method_option "frozen", :type => :boolean, :banner =>
+ "Do not allow the Gemfile.lock to be updated after this install"
+ method_option "full-index", :type => :boolean, :banner =>
+ "Fall back to using the single-file index of all gems"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
+ method_option "jobs", :aliases => "-j", :type => :numeric, :banner =>
+ "Specify the number of jobs to run in parallel"
+ method_option "local", :type => :boolean, :banner =>
+ "Do not attempt to fetch gems remotely and use the gem cache instead"
+ method_option "prefer-local", :type => :boolean, :banner =>
+ "Only attempt to fetch gems remotely if not present locally, even if newer versions are available remotely"
+ method_option "no-cache", :type => :boolean, :banner =>
+ "Don't update the existing gem cache."
+ method_option "redownload", :type => :boolean, :aliases => "--force", :banner =>
+ "Force downloading every gem."
+ method_option "no-prune", :type => :boolean, :banner =>
+ "Don't remove stale gems from the cache."
+ method_option "path", :type => :string, :banner =>
+ "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
+ method_option "quiet", :type => :boolean, :banner =>
+ "Only output warnings and errors."
+ method_option "shebang", :type => :string, :banner =>
+ "Specify a different shebang executable name than the default (usually 'ruby')"
+ method_option "standalone", :type => :array, :lazy_default => [], :banner =>
+ "Make a bundle that can work without the Bundler runtime"
+ method_option "system", :type => :boolean, :banner =>
+ "Install to the system location ($BUNDLE_PATH or $GEM_HOME) even if the bundle was previously installed somewhere else for this application"
+ method_option "trust-policy", :alias => "P", :type => :string, :banner =>
+ "Gem trust policy (like gem install -P). Must be one of " +
+ Bundler.rubygems.security_policy_keys.join("|")
+ method_option "without", :type => :array, :banner =>
+ "Exclude gems that are part of the specified named group."
+ method_option "with", :type => :array, :banner =>
+ "Include gems that are part of the specified named group."
def install
SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
- %w[clean deployment frozen no-prune path shebang without with].each do |option|
+ %w[clean deployment frozen no-prune path shebang system without with].each do |option|
remembered_flag_deprecation(option)
end
- print_remembered_flag_deprecation("--system", "path.system", "true") if ARGV.include?("--system")
-
remembered_negative_flag_deprecation("no-deployment")
require_relative "cli/install"
- Bundler.settings.temporary(no_install: false) do
+ Bundler.settings.temporary(:no_install => false) do
Install.new(options.dup).run
end
end
@@ -256,27 +270,44 @@ module Bundler
update when you have changed the Gemfile, or if you want to get the newest
possible versions of the gems in the bundle.
D
- method_option "full-index", type: :boolean, banner: "Fall back to using the single-file index of all gems"
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
- method_option "group", aliases: "-g", type: :array, banner: "Update a specific group"
- method_option "jobs", aliases: "-j", type: :numeric, banner: "Specify the number of jobs to run in parallel"
- method_option "local", type: :boolean, banner: "Do not attempt to fetch gems remotely and use the gem cache instead"
- method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
- method_option "source", type: :array, banner: "Update a specific source (and all gems associated with it)"
- method_option "redownload", type: :boolean, aliases: "--force", banner: "Force downloading every gem."
- method_option "ruby", type: :boolean, banner: "Update ruby specified in Gemfile.lock"
- method_option "bundler", type: :string, lazy_default: "> 0.a", banner: "Update the locked version of bundler"
- method_option "patch", type: :boolean, banner: "Prefer updating only to next patch version"
- method_option "minor", type: :boolean, banner: "Prefer updating only to next minor version"
- method_option "major", type: :boolean, banner: "Prefer updating to next major version (default)"
- method_option "pre", type: :boolean, banner: "Always choose the highest allowed version when updating gems, regardless of prerelease status"
- method_option "strict", type: :boolean, banner: "Do not allow any gem to be updated past latest --patch | --minor | --major"
- method_option "conservative", type: :boolean, banner: "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
- method_option "all", type: :boolean, banner: "Update everything."
+ method_option "full-index", :type => :boolean, :banner =>
+ "Fall back to using the single-file index of all gems"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
+ method_option "group", :aliases => "-g", :type => :array, :banner =>
+ "Update a specific group"
+ method_option "jobs", :aliases => "-j", :type => :numeric, :banner =>
+ "Specify the number of jobs to run in parallel"
+ method_option "local", :type => :boolean, :banner =>
+ "Do not attempt to fetch gems remotely and use the gem cache instead"
+ method_option "quiet", :type => :boolean, :banner =>
+ "Only output warnings and errors."
+ method_option "source", :type => :array, :banner =>
+ "Update a specific source (and all gems associated with it)"
+ method_option "redownload", :type => :boolean, :aliases => "--force", :banner =>
+ "Force downloading every gem."
+ method_option "ruby", :type => :boolean, :banner =>
+ "Update ruby specified in Gemfile.lock"
+ method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner =>
+ "Update the locked version of bundler"
+ method_option "patch", :type => :boolean, :banner =>
+ "Prefer updating only to next patch version"
+ method_option "minor", :type => :boolean, :banner =>
+ "Prefer updating only to next minor version"
+ method_option "major", :type => :boolean, :banner =>
+ "Prefer updating to next major version (default)"
+ method_option "pre", :type => :boolean, :banner =>
+ "Always choose the highest allowed version when updating gems, regardless of prerelease status"
+ method_option "strict", :type => :boolean, :banner =>
+ "Do not allow any gem to be updated past latest --patch | --minor | --major"
+ method_option "conservative", :type => :boolean, :banner =>
+ "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
+ method_option "all", :type => :boolean, :banner =>
+ "Update everything."
def update(*gems)
SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
require_relative "cli/update"
- Bundler.settings.temporary(no_install: false) do
+ Bundler.settings.temporary(:no_install => false) do
Update.new(options, gems).run
end
end
@@ -286,25 +317,21 @@ module Bundler
Show lists the names and versions of all gems that are required by your Gemfile.
Calling show with [GEM] will list the exact location of that gem on your machine.
D
- method_option "paths", type: :boolean,
- banner: "List the paths of all gems that are required by your Gemfile."
- method_option "outdated", type: :boolean,
- banner: "Show verbose output including whether gems are outdated."
+ method_option "paths", :type => :boolean,
+ :banner => "List the paths of all gems that are required by your Gemfile."
+ method_option "outdated", :type => :boolean,
+ :banner => "Show verbose output including whether gems are outdated."
def show(gem_name = nil)
- if ARGV.include?("--outdated")
- message = "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement"
- removed_message = "the `--outdated` flag to `bundle show` was undocumented and has been removed without replacement"
- SharedHelpers.major_deprecation(2, message, removed_message: removed_message)
- end
+ SharedHelpers.major_deprecation(2, "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement") if ARGV.include?("--outdated")
require_relative "cli/show"
Show.new(options, gem_name).run
end
desc "list", "List all gems in the bundle"
- method_option "name-only", type: :boolean, banner: "print only the gem names"
- method_option "only-group", type: :array, default: [], banner: "print gems from a given set of groups"
- method_option "without-group", type: :array, default: [], banner: "print all gems except from a given set of groups"
- method_option "paths", type: :boolean, banner: "print the path to each gem in the bundle"
+ method_option "name-only", :type => :boolean, :banner => "print only the gem names"
+ method_option "only-group", :type => :array, :default => [], :banner => "print gems from a given set of groups"
+ method_option "without-group", :type => :array, :default => [], :banner => "print all gems except from a given set of groups"
+ method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle"
def list
require_relative "cli/list"
List.new(options).run
@@ -313,8 +340,8 @@ module Bundler
map aliases_for("list")
desc "info GEM [OPTIONS]", "Show information for the given gem"
- method_option "path", type: :boolean, banner: "Print full path to gem"
- method_option "version", type: :boolean, banner: "Print gem version"
+ method_option "path", :type => :boolean, :banner => "Print full path to gem"
+ method_option "version", :type => :boolean, :banner => "Print gem version"
def info(gem_name)
require_relative "cli/info"
Info.new(options, gem_name).run
@@ -326,12 +353,18 @@ module Bundler
or the --binstubs directory if one has been set. Calling binstubs with [GEM [GEM]]
will create binstubs for all given gems.
D
- method_option "force", type: :boolean, default: false, banner: "Overwrite existing binstubs if they exist"
- method_option "path", type: :string, lazy_default: "bin", banner: "Binstub destination directory (default bin)"
- method_option "shebang", type: :string, banner: "Specify a different shebang executable name than the default (usually 'ruby')"
- method_option "standalone", type: :boolean, banner: "Make binstubs that can work without the Bundler runtime"
- method_option "all", type: :boolean, banner: "Install binstubs for all gems"
- method_option "all-platforms", type: :boolean, default: false, banner: "Install binstubs for all platforms"
+ method_option "force", :type => :boolean, :default => false, :banner =>
+ "Overwrite existing binstubs if they exist"
+ method_option "path", :type => :string, :lazy_default => "bin", :banner =>
+ "Binstub destination directory (default bin)"
+ method_option "shebang", :type => :string, :banner =>
+ "Specify a different shebang executable name than the default (usually 'ruby')"
+ method_option "standalone", :type => :boolean, :banner =>
+ "Make binstubs that can work without the Bundler runtime"
+ method_option "all", :type => :boolean, :banner =>
+ "Install binstubs for all gems"
+ method_option "all-platforms", :type => :boolean, :default => false, :banner =>
+ "Install binstubs for all platforms"
def binstubs(*gems)
require_relative "cli/binstubs"
Binstubs.new(options, gems).run
@@ -341,19 +374,19 @@ module Bundler
long_desc <<-D
Adds the specified gem to Gemfile (if valid) and run 'bundle install' in one step.
D
- method_option "version", aliases: "-v", type: :string
- method_option "group", aliases: "-g", type: :string
- method_option "source", aliases: "-s", type: :string
- method_option "require", aliases: "-r", type: :string, banner: "Adds require path to gem. Provide false, or a path as a string."
- method_option "path", type: :string
- method_option "git", type: :string
- method_option "github", type: :string
- method_option "branch", type: :string
- method_option "ref", type: :string
- method_option "glob", type: :string, banner: "The location of a dependency's .gemspec, expanded within Ruby (single quotes recommended)"
- method_option "skip-install", type: :boolean, banner: "Adds gem to the Gemfile but does not install it"
- method_option "optimistic", type: :boolean, banner: "Adds optimistic declaration of version to gem"
- method_option "strict", type: :boolean, banner: "Adds strict declaration of version to gem"
+ method_option "version", :aliases => "-v", :type => :string
+ method_option "group", :aliases => "-g", :type => :string
+ method_option "source", :aliases => "-s", :type => :string
+ method_option "require", :aliases => "-r", :type => :string, :banner => "Adds require path to gem. Provide false, or a path as a string."
+ method_option "path", :type => :string
+ method_option "git", :type => :string
+ method_option "github", :type => :string
+ method_option "branch", :type => :string
+ method_option "ref", :type => :string
+ method_option "skip-install", :type => :boolean, :banner =>
+ "Adds gem to the Gemfile but does not install it"
+ method_option "optimistic", :type => :boolean, :banner => "Adds optimistic declaration of version to gem"
+ method_option "strict", :type => :boolean, :banner => "Adds strict declaration of version to gem"
def add(*gems)
require_relative "cli/add"
Add.new(options.dup, gems).run
@@ -369,45 +402,54 @@ module Bundler
For more information on patch level options (--major, --minor, --patch,
--strict) see documentation on the same options on the update command.
D
- method_option "group", type: :string, banner: "List gems from a specific group"
- method_option "groups", type: :boolean, banner: "List gems organized by groups"
- method_option "local", type: :boolean, banner: "Do not attempt to fetch gems remotely and use the gem cache instead"
- method_option "pre", type: :boolean, banner: "Check for newer pre-release gems"
- method_option "source", type: :array, banner: "Check against a specific source"
- method_option "filter-strict", type: :boolean, aliases: "--strict", banner: "Only list newer versions allowed by your Gemfile requirements"
- method_option "update-strict", type: :boolean, banner: "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major"
- method_option "minor", type: :boolean, banner: "Prefer updating only to next minor version"
- method_option "major", type: :boolean, banner: "Prefer updating to next major version (default)"
- method_option "patch", type: :boolean, banner: "Prefer updating only to next patch version"
- method_option "filter-major", type: :boolean, banner: "Only list major newer versions"
- method_option "filter-minor", type: :boolean, banner: "Only list minor newer versions"
- method_option "filter-patch", type: :boolean, banner: "Only list patch newer versions"
- method_option "parseable", aliases: "--porcelain", type: :boolean, banner: "Use minimal formatting for more parseable output"
- method_option "only-explicit", type: :boolean, banner: "Only list gems specified in your Gemfile, not their dependencies"
+ method_option "group", :type => :string, :banner => "List gems from a specific group"
+ method_option "groups", :type => :boolean, :banner => "List gems organized by groups"
+ method_option "local", :type => :boolean, :banner =>
+ "Do not attempt to fetch gems remotely and use the gem cache instead"
+ method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems"
+ method_option "source", :type => :array, :banner => "Check against a specific source"
+ method_option "filter-strict", :type => :boolean, :aliases => "--strict", :banner =>
+ "Only list newer versions allowed by your Gemfile requirements"
+ method_option "update-strict", :type => :boolean, :banner =>
+ "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major"
+ method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version"
+ method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)"
+ method_option "patch", :type => :boolean, :banner => "Prefer updating only to next patch version"
+ method_option "filter-major", :type => :boolean, :banner => "Only list major newer versions"
+ method_option "filter-minor", :type => :boolean, :banner => "Only list minor newer versions"
+ method_option "filter-patch", :type => :boolean, :banner => "Only list patch newer versions"
+ method_option "parseable", :aliases => "--porcelain", :type => :boolean, :banner =>
+ "Use minimal formatting for more parseable output"
+ method_option "only-explicit", :type => :boolean, :banner =>
+ "Only list gems specified in your Gemfile, not their dependencies"
def outdated(*gems)
require_relative "cli/outdated"
Outdated.new(options, gems).run
end
desc "fund [OPTIONS]", "Lists information about gems seeking funding assistance"
- method_option "group", aliases: "-g", type: :array, banner: "Fetch funding information for a specific group"
+ method_option "group", :aliases => "-g", :type => :array, :banner =>
+ "Fetch funding information for a specific group"
def fund
require_relative "cli/fund"
Fund.new(options).run
end
desc "cache [OPTIONS]", "Locks and then caches all of the gems into vendor/cache"
- method_option "all", type: :boolean,
- default: Bundler.feature_flag.cache_all?,
- banner: "Include all sources (including path and git)."
- method_option "all-platforms", type: :boolean, banner: "Include gems for all platforms present in the lockfile, not only the current one"
- method_option "cache-path", type: :string, banner: "Specify a different cache path than the default (vendor/cache)."
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
- method_option "no-install", type: :boolean, banner: "Don't install the gems, only update the cache."
- method_option "no-prune", type: :boolean, banner: "Don't remove stale gems from the cache."
- method_option "path", type: :string, banner: "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
- method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
- method_option "frozen", type: :boolean, banner: "Do not allow the Gemfile.lock to be updated after this bundle cache operation's install"
+ method_option "all", :type => :boolean,
+ :default => Bundler.feature_flag.cache_all?,
+ :banner => "Include all sources (including path and git)."
+ method_option "all-platforms", :type => :boolean, :banner => "Include gems for all platforms present in the lockfile, not only the current one"
+ method_option "cache-path", :type => :string, :banner =>
+ "Specify a different cache path than the default (vendor/cache)."
+ method_option "gemfile", :type => :string, :banner => "Use the specified gemfile instead of Gemfile"
+ method_option "no-install", :type => :boolean, :banner => "Don't install the gems, only update the cache."
+ method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
+ method_option "path", :type => :string, :banner =>
+ "Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME).#{" Bundler will remember this value for future installs on this machine" unless Bundler.feature_flag.forget_cli_options?}"
+ method_option "quiet", :type => :boolean, :banner => "Only output warnings and errors."
+ method_option "frozen", :type => :boolean, :banner =>
+ "Do not allow the Gemfile.lock to be updated after this bundle cache operation's install"
long_desc <<-D
The cache command will copy the .gem files for every gem in the bundle into the
directory ./vendor/cache. If you then check that directory into your source
@@ -415,20 +457,17 @@ module Bundler
bundle without having to download any additional gems.
D
def cache
- print_remembered_flag_deprecation("--all", "cache_all", "true") if ARGV.include?("--all")
-
- if ARGV.include?("--path")
- message =
- "The `--path` flag is deprecated because its semantics are unclear. " \
- "Use `bundle config cache_path` to configure the path of your cache of gems, " \
- "and `bundle config path` to configure the path where your gems are installed, " \
- "and stop using this flag"
- removed_message =
- "The `--path` flag has been removed because its semantics were unclear. " \
- "Use `bundle config cache_path` to configure the path of your cache of gems, " \
- "and `bundle config path` to configure the path where your gems are installed."
- SharedHelpers.major_deprecation 2, message, removed_message: removed_message
- end
+ SharedHelpers.major_deprecation 2,
+ "The `--all` flag is deprecated because it relies on being " \
+ "remembered across bundler invocations, which bundler will no longer " \
+ "do in future versions. Instead please use `bundle config set cache_all true`, " \
+ "and stop using this flag" if ARGV.include?("--all")
+
+ SharedHelpers.major_deprecation 2,
+ "The `--path` flag is deprecated because its semantics are unclear. " \
+ "Use `bundle config cache_path` to configure the path of your cache of gems, " \
+ "and `bundle config path` to configure the path where your gems are installed, " \
+ "and stop using this flag" if ARGV.include?("--path")
require_relative "cli/cache"
Cache.new(options).run
@@ -437,8 +476,8 @@ module Bundler
map aliases_for("cache")
desc "exec [OPTIONS]", "Run the command in context of the bundle"
- method_option :keep_file_descriptors, type: :boolean, default: true
- method_option :gemfile, type: :string, required: false
+ method_option :keep_file_descriptors, :type => :boolean, :default => true
+ method_option :gemfile, :type => :string, :required => false
long_desc <<-D
Exec runs a command, providing it access to the gems in the bundle. While using
bundle exec you can require and call the bundled gems as if they were installed
@@ -446,9 +485,7 @@ module Bundler
D
def exec(*args)
if ARGV.include?("--no-keep-file-descriptors")
- message = "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to"
- removed_message = "The `--no-keep-file-descriptors` has been removed. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to"
- SharedHelpers.major_deprecation(2, message, removed_message: removed_message)
+ SharedHelpers.major_deprecation(2, "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to")
end
require_relative "cli/exec"
@@ -473,7 +510,7 @@ module Bundler
subcommand "config", Config
desc "open GEM", "Opens the source directory of the given bundled gem"
- method_option "path", type: :string, lazy_default: "", banner: "Open relative path of the gem source."
+ method_option "path", :type => :string, :lazy_default => "", :banner => "Open relative path of the gem source."
def open(name)
require_relative "cli/open"
Open.new(options, name).run
@@ -518,17 +555,17 @@ module Bundler
end
unless Bundler.feature_flag.bundler_3_mode?
- desc "viz [OPTIONS]", "Generates a visual dependency graph", hide: true
+ desc "viz [OPTIONS]", "Generates a visual dependency graph", :hide => true
long_desc <<-D
Viz generates a PNG file of the current Gemfile as a dependency graph.
Viz requires the ruby-graphviz gem (and its dependencies).
The associated gems must also be installed via 'bundle install'.
D
- method_option :file, type: :string, default: "gem_graph", aliases: "-f", desc: "The name to use for the generated file. see format option"
- method_option :format, type: :string, default: "png", aliases: "-F", desc: "This is output format option. Supported format is png, jpg, svg, dot ..."
- method_option :requirements, type: :boolean, default: false, aliases: "-R", desc: "Set to show the version of each required dependency."
- method_option :version, type: :boolean, default: false, aliases: "-v", desc: "Set to show each gem version."
- method_option :without, type: :array, default: [], aliases: "-W", banner: "GROUP[ GROUP...]", desc: "Exclude gems that are part of the specified named group."
+ method_option :file, :type => :string, :default => "gem_graph", :aliases => "-f", :desc => "The name to use for the generated file. see format option"
+ method_option :format, :type => :string, :default => "png", :aliases => "-F", :desc => "This is output format option. Supported format is png, jpg, svg, dot ..."
+ method_option :requirements, :type => :boolean, :default => false, :aliases => "-R", :desc => "Set to show the version of each required dependency."
+ method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
+ method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
def viz
SharedHelpers.major_deprecation 2, "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
require_relative "cli/viz"
@@ -539,23 +576,23 @@ module Bundler
old_gem = instance_method(:gem)
desc "gem NAME [OPTIONS]", "Creates a skeleton for creating a rubygem"
- method_option :exe, type: :boolean, default: false, aliases: ["--bin", "-b"], desc: "Generate a binary executable for your library."
- method_option :coc, type: :boolean, desc: "Generate a code of conduct file. Set a default with `bundle config set --global gem.coc true`."
- method_option :edit, type: :string, aliases: "-e", required: false, banner: "EDITOR",
- lazy_default: [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? },
- desc: "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)"
- method_option :ext, type: :string, desc: "Generate the boilerplate for C extension code.", enum: EXTENSIONS
- method_option :git, type: :boolean, default: true, desc: "Initialize a git repo inside your library."
- method_option :mit, type: :boolean, desc: "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`."
- method_option :rubocop, type: :boolean, desc: "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
- method_option :changelog, type: :boolean, desc: "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
- method_option :test, type: :string, lazy_default: Bundler.settings["gem.test"] || "", aliases: "-t", banner: "Use the specified test framework for your library",
- desc: "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
- method_option :ci, type: :string, lazy_default: Bundler.settings["gem.ci"] || "",
- desc: "Generate CI configuration, either GitHub Actions, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|gitlab|circle)`"
- method_option :linter, type: :string, lazy_default: Bundler.settings["gem.linter"] || "",
- desc: "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
- method_option :github_username, type: :string, default: Bundler.settings["gem.github_username"], banner: "Set your username on GitHub", desc: "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
+ method_option :exe, :type => :boolean, :default => false, :aliases => ["--bin", "-b"], :desc => "Generate a binary executable for your library."
+ method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config set --global gem.coc true`."
+ method_option :edit, :type => :string, :aliases => "-e", :required => false, :banner => "EDITOR",
+ :lazy_default => [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? },
+ :desc => "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)"
+ method_option :ext, :type => :string, :desc => "Generate the boilerplate for C extension code.", :enum => EXTENSIONS
+ method_option :git, :type => :boolean, :default => true, :desc => "Initialize a git repo inside your library."
+ method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`."
+ method_option :rubocop, :type => :boolean, :desc => "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
+ method_option :changelog, :type => :boolean, :desc => "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
+ method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library",
+ :desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
+ method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
+ :desc => "Generate CI configuration, either GitHub Actions, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|gitlab|circle)`"
+ method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "",
+ :desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
+ method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
def gem(name)
end
@@ -586,24 +623,29 @@ module Bundler
File.expand_path("templates", __dir__)
end
- desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", hide: true
- method_option "dry-run", type: :boolean, default: false, banner: "Only print out changes, do not clean gems"
- method_option "force", type: :boolean, default: false, banner: "Forces cleaning up unused gems even if Bundler is configured to use globally installed gems. As a consequence, removes all system gems except for the ones in the current application."
+ desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", :hide => true
+ method_option "dry-run", :type => :boolean, :default => false, :banner =>
+ "Only print out changes, do not clean gems"
+ method_option "force", :type => :boolean, :default => false, :banner =>
+ "Forces cleaning up unused gems even if Bundler is configured to use globally installed gems. As a consequence, removes all system gems except for the ones in the current application."
def clean
require_relative "cli/clean"
Clean.new(options.dup).run
end
desc "platform [OPTIONS]", "Displays platform compatibility information"
- method_option "ruby", type: :boolean, default: false, banner: "only display ruby related platform information"
+ method_option "ruby", :type => :boolean, :default => false, :banner =>
+ "only display ruby related platform information"
def platform
require_relative "cli/platform"
Platform.new(options).run
end
- desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile", hide: true
- method_option "source", type: :string, banner: "Install gem from the given source"
- method_option "group", type: :string, banner: "Install gem into a bundler group"
+ desc "inject GEM VERSION", "Add the named gem, with version requirements, to the resolved Gemfile", :hide => true
+ method_option "source", :type => :string, :banner =>
+ "Install gem from the given source"
+ method_option "group", :type => :string, :banner =>
+ "Install gem into a bundler group"
def inject(name, version)
SharedHelpers.major_deprecation 2, "The `inject` command has been replaced by the `add` command"
require_relative "cli/inject"
@@ -611,21 +653,36 @@ module Bundler
end
desc "lock", "Creates a lockfile without installing"
- method_option "update", type: :array, lazy_default: true, banner: "ignore the existing lockfile, update all gems by default, or update list of given gems"
- method_option "local", type: :boolean, default: false, banner: "do not attempt to fetch remote gemspecs and use the local gem cache only"
- method_option "print", type: :boolean, default: false, banner: "print the lockfile to STDOUT instead of writing to the file system"
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
- method_option "lockfile", type: :string, default: nil, banner: "the path the lockfile should be written to"
- method_option "full-index", type: :boolean, default: false, banner: "Fall back to using the single-file index of all gems"
- method_option "add-platform", type: :array, default: [], banner: "Add a new platform to the lockfile"
- method_option "remove-platform", type: :array, default: [], banner: "Remove a platform from the lockfile"
- method_option "patch", type: :boolean, banner: "If updating, prefer updating only to next patch version"
- method_option "minor", type: :boolean, banner: "If updating, prefer updating only to next minor version"
- method_option "major", type: :boolean, banner: "If updating, prefer updating to next major version (default)"
- method_option "pre", type: :boolean, banner: "If updating, always choose the highest allowed version, regardless of prerelease status"
- method_option "strict", type: :boolean, banner: "If updating, do not allow any gem to be updated past latest --patch | --minor | --major"
- method_option "conservative", type: :boolean, banner: "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
- method_option "bundler", type: :string, lazy_default: "> 0.a", banner: "Update the locked version of bundler"
+ method_option "update", :type => :array, :lazy_default => true, :banner =>
+ "ignore the existing lockfile, update all gems by default, or update list of given gems"
+ method_option "local", :type => :boolean, :default => false, :banner =>
+ "do not attempt to fetch remote gemspecs and use the local gem cache only"
+ method_option "print", :type => :boolean, :default => false, :banner =>
+ "print the lockfile to STDOUT instead of writing to the file system"
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
+ method_option "lockfile", :type => :string, :default => nil, :banner =>
+ "the path the lockfile should be written to"
+ method_option "full-index", :type => :boolean, :default => false, :banner =>
+ "Fall back to using the single-file index of all gems"
+ method_option "add-platform", :type => :array, :default => [], :banner =>
+ "Add a new platform to the lockfile"
+ method_option "remove-platform", :type => :array, :default => [], :banner =>
+ "Remove a platform from the lockfile"
+ method_option "patch", :type => :boolean, :banner =>
+ "If updating, prefer updating only to next patch version"
+ method_option "minor", :type => :boolean, :banner =>
+ "If updating, prefer updating only to next minor version"
+ method_option "major", :type => :boolean, :banner =>
+ "If updating, prefer updating to next major version (default)"
+ method_option "pre", :type => :boolean, :banner =>
+ "If updating, always choose the highest allowed version, regardless of prerelease status"
+ method_option "strict", :type => :boolean, :banner =>
+ "If updating, do not allow any gem to be updated past latest --patch | --minor | --major"
+ method_option "conservative", :type => :boolean, :banner =>
+ "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
+ method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner =>
+ "Update the locked version of bundler"
def lock
require_relative "cli/lock"
Lock.new(options).run
@@ -642,8 +699,10 @@ module Bundler
missing dependencies are detected, Bundler prints them and exits status 1.
Otherwise, Bundler prints a success message and exits with a status of 0.
D
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
- method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
+ method_option "gemfile", :type => :string, :banner =>
+ "Use the specified gemfile instead of Gemfile"
+ method_option "quiet", :type => :boolean, :banner =>
+ "Only output warnings and errors."
def doctor
require_relative "cli/doctor"
Doctor.new(options).run
@@ -663,9 +722,7 @@ module Bundler
D
def pristine(*gems)
require_relative "cli/pristine"
- Bundler.settings.temporary(no_install: false) do
- Pristine.new(gems).run
- end
+ Pristine.new(gems).run
end
if Bundler.feature_flag.plugins?
@@ -686,6 +743,7 @@ module Bundler
exec_used = args.index {|a| exec_commands.include? a }
command = args.find {|a| bundler_commands.include? a }
+ command = all_aliases[command] if all_aliases[command]
if exec_used && help_used
if exec_used + help_used == 1
@@ -706,16 +764,14 @@ module Bundler
# when deprecated version of `--ext` is called
# print out deprecation warning and pretend `--ext=c` was provided
if deprecated_ext_value?(arguments)
- message = "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been deprecated. Please select a language, e.g. `--ext=rust` to generate a Rust extension. This gem will now be generated as if `--ext=c` was used."
- removed_message = "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been removed. Please select a language, e.g. `--ext=rust` to generate a Rust extension."
- SharedHelpers.major_deprecation 2, message, removed_message: removed_message
+ SharedHelpers.major_deprecation 2, "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been deprecated. Please select a language, e.g. `--ext=rust` to generate a Rust extension. This gem will now be generated as if `--ext=c` was used."
arguments[arguments.index("--ext")] = "--ext=c"
end
end
def self.deprecated_ext_value?(arguments)
index = arguments.index("--ext")
- next_argument = arguments[index + 1]
+ next_argument = arguments[index+1]
# it is ok when --ext is followed with valid extension value
# for example `bundle gem hello --ext c`
@@ -738,6 +794,26 @@ module Bundler
private
+ # Automatically invoke `bundle install` and resume if
+ # Bundler.settings[:auto_install] exists. This is set through config cmd
+ # `bundle config set --global auto_install 1`.
+ #
+ # Note that this method `nil`s out the global Definition object, so it
+ # should be called first, before you instantiate anything like an
+ # `Installer` that'll keep a reference to the old one instead.
+ def auto_install
+ return unless Bundler.settings[:auto_install]
+
+ begin
+ Bundler.definition.specs
+ rescue GemNotFound
+ Bundler.ui.info "Automatically installing missing gems."
+ Bundler.reset!
+ invoke :install, []
+ Bundler.reset!
+ end
+ end
+
def current_command
_, _, config = @_initializer
config[:current_command]
@@ -768,7 +844,7 @@ module Bundler
return unless SharedHelpers.md5_available?
latest = Fetcher::CompactIndex.
- new(nil, Source::Rubygems::Remote.new(Gem::URI("https://rubygems.org")), nil, nil).
+ new(nil, Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")), nil).
send(:compact_index_client).
instance_variable_get(:@cache).
dependencies("bundler").
@@ -807,23 +883,12 @@ module Bundler
value = options[name]
value = value.join(" ").to_s if option.type == :array
- value = "'#{value}'" unless option.type == :boolean
- print_remembered_flag_deprecation(flag_name, name.tr("-", "_"), value)
- end
-
- def print_remembered_flag_deprecation(flag_name, option_name, option_value)
- message =
+ Bundler::SharedHelpers.major_deprecation 2,
"The `#{flag_name}` flag is deprecated because it relies on being " \
"remembered across bundler invocations, which bundler will no longer " \
- "do in future versions. Instead please use `bundle config set #{option_name} " \
- "#{option_value}`, and stop using this flag"
- removed_message =
- "The `#{flag_name}` flag has been removed because it relied on being " \
- "remembered across bundler invocations, which bundler will no longer " \
- "do. Instead please use `bundle config set #{option_name} " \
- "#{option_value}`, and stop using this flag"
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
+ "do in future versions. Instead please use `bundle config set --local #{name.tr("-", "_")} " \
+ "'#{value}'`, and stop using this flag"
end
end
end
diff --git a/lib/bundler/cli/add.rb b/lib/bundler/cli/add.rb
index 002d9e1d33..08fa6547fb 100644
--- a/lib/bundler/cli/add.rb
+++ b/lib/bundler/cli/add.rb
@@ -28,9 +28,9 @@ module Bundler
dependencies = gems.map {|g| Bundler::Dependency.new(g, version, options) }
Injector.inject(dependencies,
- conservative_versioning: options[:version].nil?, # Perform conservative versioning only when version is not specified
- optimistic: options[:optimistic],
- strict: options[:strict])
+ :conservative_versioning => options[:version].nil?, # Perform conservative versioning only when version is not specified
+ :optimistic => options[:optimistic],
+ :strict => options[:strict])
end
def validate_options!
diff --git a/lib/bundler/cli/binstubs.rb b/lib/bundler/cli/binstubs.rb
index 8ce138df96..fc2fad47a5 100644
--- a/lib/bundler/cli/binstubs.rb
+++ b/lib/bundler/cli/binstubs.rb
@@ -17,9 +17,9 @@ module Bundler
installer = Installer.new(Bundler.root, Bundler.definition)
installer_opts = {
- force: options[:force],
- binstubs_cmd: true,
- all_platforms: options["all-platforms"],
+ :force => options[:force],
+ :binstubs_cmd => true,
+ :all_platforms => options["all-platforms"],
}
if options[:all]
@@ -45,7 +45,7 @@ module Bundler
next
end
- Bundler.settings.temporary(path: Bundler.settings[:path] || Bundler.root) do
+ Bundler.settings.temporary(:path => (Bundler.settings[:path] || Bundler.root)) do
installer.generate_standalone_bundler_executable_stubs(spec, installer_opts)
end
else
diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb
index 2e63a16ec3..c8698ed7e3 100644
--- a/lib/bundler/cli/cache.rb
+++ b/lib/bundler/cli/cache.rb
@@ -19,7 +19,7 @@ module Bundler
# TODO: move cache contents here now that all bundles are locked
custom_path = Bundler.settings[:path] if options[:path]
- Bundler.settings.temporary(cache_all_platforms: options["all-platforms"]) do
+ Bundler.settings.temporary(:cache_all_platforms => options["all-platforms"]) do
Bundler.load.cache(custom_path)
end
end
diff --git a/lib/bundler/cli/check.rb b/lib/bundler/cli/check.rb
index 33d31cdd27..cc1f37f0c3 100644
--- a/lib/bundler/cli/check.rb
+++ b/lib/bundler/cli/check.rb
@@ -29,10 +29,10 @@ module Bundler
Bundler.ui.warn "Install missing gems with `bundle install`"
exit 1
elsif !Bundler.default_lockfile.file? && Bundler.frozen_bundle?
- Bundler.ui.error "This bundle has been frozen, but there is no #{SharedHelpers.relative_lockfile_path} present"
+ Bundler.ui.error "This bundle has been frozen, but there is no #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} present"
exit 1
else
- Bundler.load.lock(preserve_unknown_sections: true) unless options[:"dry-run"]
+ Bundler.load.lock(:preserve_unknown_sections => true) unless options[:"dry-run"]
Bundler.ui.info "The Gemfile's dependencies are satisfied"
end
end
diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb
index 7ef6deb2cf..d654406f65 100644
--- a/lib/bundler/cli/common.rb
+++ b/lib/bundler/cli/common.rb
@@ -54,12 +54,9 @@ module Bundler
Bundler.definition.specs.each do |spec|
return spec if spec.name == name
- specs << spec if regexp && spec.name.match?(regexp)
+ specs << spec if regexp && spec.name =~ regexp
end
- default_spec = default_gem_spec(name)
- specs << default_spec if default_spec
-
case specs.count
when 0
dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
@@ -78,11 +75,6 @@ module Bundler
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
end
- def self.default_gem_spec(name)
- gem_spec = Gem::Specification.find_all_by_name(name).last
- gem_spec if gem_spec&.default_gem?
- end
-
def self.ask_for_spec_from(specs)
specs.each_with_index do |spec, index|
Bundler.ui.info "#{index.succ} : #{spec.name}", true
diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb
index 77b502fe60..e1222c75dd 100644
--- a/lib/bundler/cli/config.rb
+++ b/lib/bundler/cli/config.rb
@@ -2,17 +2,17 @@
module Bundler
class CLI::Config < Thor
- class_option :parseable, type: :boolean, banner: "Use minimal formatting for more parseable output"
+ class_option :parseable, :type => :boolean, :banner => "Use minimal formatting for more parseable output"
def self.scope_options
- method_option :global, type: :boolean, banner: "Only change the global config"
- method_option :local, type: :boolean, banner: "Only change the local config"
+ method_option :global, :type => :boolean, :banner => "Only change the global config"
+ method_option :local, :type => :boolean, :banner => "Only change the local config"
end
private_class_method :scope_options
- desc "base NAME [VALUE]", "The Bundler 1 config interface", hide: true
+ desc "base NAME [VALUE]", "The Bundler 1 config interface", :hide => true
scope_options
- method_option :delete, type: :boolean, banner: "delete"
+ method_option :delete, :type => :boolean, :banner => "delete"
def base(name = nil, *value)
new_args =
if ARGV.size == 1
@@ -25,9 +25,8 @@ module Bundler
["config", "get", ARGV[1]]
end
- message = "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead."
- removed_message = "Using the `config` command without a subcommand [list, get, set, unset] is has been removed. Use `bundle #{new_args.join(" ")}` instead."
- SharedHelpers.major_deprecation 3, message, removed_message: removed_message
+ SharedHelpers.major_deprecation 3,
+ "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead."
Base.new(options, name, value, self).run
end
diff --git a/lib/bundler/cli/console.rb b/lib/bundler/cli/console.rb
index 840cf14fd7..1eb8ea8254 100644
--- a/lib/bundler/cli/console.rb
+++ b/lib/bundler/cli/console.rb
@@ -9,9 +9,8 @@ module Bundler
end
def run
- message = "bundle console will be replaced by `bin/console` generated by `bundle gem <name>`"
- removed_message = "bundle console has been replaced by `bin/console` generated by `bundle gem <name>`"
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
+ Bundler::SharedHelpers.major_deprecation 2, "bundle console will be replaced " \
+ "by `bin/console` generated by `bundle gem <name>`"
group ? Bundler.require(:default, *group.split(" ").map!(&:to_sym)) : Bundler.require
ARGV.clear
diff --git a/lib/bundler/cli/doctor.rb b/lib/bundler/cli/doctor.rb
index 1f6fc93c16..e299a5a8c2 100644
--- a/lib/bundler/cli/doctor.rb
+++ b/lib/bundler/cli/doctor.rb
@@ -6,8 +6,8 @@ require "fiddle"
module Bundler
class CLI::Doctor
- DARWIN_REGEX = /\s+(.+) \(compatibility /
- LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/
+ DARWIN_REGEX = /\s+(.+) \(compatibility /.freeze
+ LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/.freeze
attr_reader :options
diff --git a/lib/bundler/cli/exec.rb b/lib/bundler/cli/exec.rb
index f81cd5d2c4..42b602a055 100644
--- a/lib/bundler/cli/exec.rb
+++ b/lib/bundler/cli/exec.rb
@@ -12,7 +12,7 @@ module Bundler
@options = options
@cmd = args.shift
@args = args
- @args << { close_others: !options.keep_file_descriptors? } unless Bundler.current_ruby.jruby?
+ @args << { :close_others => !options.keep_file_descriptors? } unless Bundler.current_ruby.jruby?
end
def run
diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb
index f0bb3aab18..7f1200f4a0 100644
--- a/lib/bundler/cli/gem.rb
+++ b/lib/bundler/cli/gem.rb
@@ -11,7 +11,7 @@ module Bundler
class CLI::Gem
TEST_FRAMEWORK_VERSIONS = {
"rspec" => "3.0",
- "minitest" => "5.16",
+ "minitest" => "5.0",
"test-unit" => "3.0",
}.freeze
@@ -59,23 +59,23 @@ module Bundler
end
config = {
- name: name,
- underscored_name: underscored_name,
- namespaced_path: namespaced_path,
- makefile_path: "#{underscored_name}/#{underscored_name}",
- constant_name: constant_name,
- constant_array: constant_array,
- author: git_author_name.empty? ? "TODO: Write your name" : git_author_name,
- email: git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
- test: options[:test],
- ext: extension,
- exe: options[:exe],
- bundler_version: bundler_dependency_version,
- git: use_git,
- github_username: github_username.empty? ? "[USERNAME]" : github_username,
- required_ruby_version: required_ruby_version,
- rust_builder_required_rubygems_version: rust_builder_required_rubygems_version,
- minitest_constant_name: minitest_constant_name,
+ :name => name,
+ :underscored_name => underscored_name,
+ :namespaced_path => namespaced_path,
+ :makefile_path => "#{underscored_name}/#{underscored_name}",
+ :constant_name => constant_name,
+ :constant_array => constant_array,
+ :author => git_author_name.empty? ? "TODO: Write your name" : git_author_name,
+ :email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
+ :test => options[:test],
+ :ext => extension,
+ :exe => options[:exe],
+ :bundler_version => bundler_dependency_version,
+ :git => use_git,
+ :github_username => github_username.empty? ? "[USERNAME]" : github_username,
+ :required_ruby_version => required_ruby_version,
+ :rust_builder_required_rubygems_version => rust_builder_required_rubygems_version,
+ :minitest_constant_name => minitest_constant_name,
}
ensure_safe_gem_name(name, constant_array)
@@ -137,13 +137,10 @@ module Bundler
case config[:ci]
when "github"
templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml")
- config[:ci_config_path] = ".github "
when "gitlab"
templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml")
- config[:ci_config_path] = ".gitlab-ci.yml "
when "circle"
templates.merge!("circleci/config.yml.tt" => ".circleci/config.yml")
- config[:ci_config_path] = ".circleci "
end
if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?",
@@ -236,7 +233,9 @@ module Bundler
end
if use_git
- IO.popen(%w[git add .], { chdir: target }, &:read)
+ Dir.chdir(target) do
+ `git add .`
+ end
end
# Open gemspec in editor
@@ -349,7 +348,7 @@ module Bundler
Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
"Supported Linters:\n" \
"* RuboCop: https://rubocop.org\n" \
- "* Standard: https://github.com/standardrb/standard\n" \
+ "* Standard: https://github.com/testdouble/standard\n" \
"\n"
Bundler.ui.info hint_text("linter")
@@ -380,20 +379,15 @@ module Bundler
def deprecated_rubocop_option
if !options[:rubocop].nil?
if options[:rubocop]
- Bundler::SharedHelpers.major_deprecation 2,
- "--rubocop is deprecated, use --linter=rubocop",
- removed_message: "--rubocop has been removed, use --linter=rubocop"
+ Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
"rubocop"
else
- Bundler::SharedHelpers.major_deprecation 2,
- "--no-rubocop is deprecated, use --linter",
- removed_message: "--no-rubocop has been removed, use --linter"
+ Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
false
end
elsif !Bundler.settings["gem.rubocop"].nil?
Bundler::SharedHelpers.major_deprecation 2,
- "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead",
- removed_message: "config gem.rubocop has been removed; we've updated your config to use gem.linter instead"
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
Bundler.settings["gem.rubocop"] ? "rubocop" : false
end
end
@@ -437,7 +431,7 @@ module Bundler
end
def required_ruby_version
- "3.0.0"
+ "2.6.0"
end
def rubocop_version
diff --git a/lib/bundler/cli/info.rb b/lib/bundler/cli/info.rb
index 8f34956aca..36c7a58f12 100644
--- a/lib/bundler/cli/info.rb
+++ b/lib/bundler/cli/info.rb
@@ -25,8 +25,19 @@ module Bundler
private
- def spec_for_gem(name)
- Bundler::CLI::Common.select_spec(name, :regex_match)
+ def spec_for_gem(gem_name)
+ spec = Bundler.definition.specs.find {|s| s.name == gem_name }
+ spec || default_gem_spec(gem_name) || Bundler::CLI::Common.select_spec(gem_name, :regex_match)
+ end
+
+ def default_gem_spec(gem_name)
+ return unless Gem::Specification.respond_to?(:find_all_by_name)
+ gem_spec = Gem::Specification.find_all_by_name(gem_name).last
+ return gem_spec if gem_spec&.default_gem?
+ end
+
+ def spec_not_found(gem_name)
+ raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(gem_name, Bundler.definition.dependencies)
end
def print_gem_version(spec)
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index a233d5d2e5..c71bcf159f 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -14,7 +14,7 @@ module Bundler
Bundler.self_manager.install_locked_bundler_and_restart_with_it_if_needed
- Bundler::SharedHelpers.set_env "RB_USER_INSTALL", "1" if Gem.freebsd_platform?
+ Bundler::SharedHelpers.set_env "RB_USER_INSTALL", "1" if Bundler::FREEBSD
# Disable color in deployment mode
Bundler.ui.shell = Thor::Shell::Basic.new if options[:deployment]
@@ -28,8 +28,8 @@ module Bundler
flag = "--deployment flag" if options[:deployment]
flag ||= "--frozen flag" if options[:frozen]
flag ||= "deployment setting"
- raise ProductionError, "The #{flag} requires a lockfile. Please make " \
- "sure you have checked your #{SharedHelpers.relative_lockfile_path} into version control " \
+ raise ProductionError, "The #{flag} requires a #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}. Please make " \
+ "sure you have checked your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} into version control " \
"before deploying."
end
@@ -51,8 +51,7 @@ module Bundler
if options["binstubs"]
Bundler::SharedHelpers.major_deprecation 2,
- "The --binstubs option will be removed in favor of `bundle binstubs --all`",
- removed_message: "The --binstubs option have been removed in favor of `bundle binstubs --all`"
+ "The --binstubs option will be removed in favor of `bundle binstubs --all`"
end
Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins?
@@ -62,7 +61,7 @@ module Bundler
installer = Installer.install(Bundler.root, definition, options)
- Bundler.settings.temporary(cache_all_platforms: options[:local] ? false : Bundler.settings[:cache_all_platforms]) do
+ Bundler.settings.temporary(:cache_all_platforms => options[:local] ? false : Bundler.settings[:cache_all_platforms]) do
Bundler.load.cache(nil, options[:local]) if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
end
@@ -96,7 +95,7 @@ module Bundler
def warn_if_root
return if Bundler.settings[:silence_root_warning] || Gem.win_platform? || !Process.uid.zero?
Bundler.ui.warn "Don't run Bundler as root. Installing your bundle as root " \
- "will break this application for all non-root users on this machine.", wrap: true
+ "will break this application for all non-root users on this machine.", :wrap => true
end
def dependencies_count_for(definition)
@@ -149,7 +148,7 @@ module Bundler
Bundler.settings.set_command_option_if_given :path, options[:path]
if options["standalone"] && Bundler.settings[:path].nil? && !options["local"]
- Bundler.settings.temporary(path_relative_to_cwd: false) do
+ Bundler.settings.temporary(:path_relative_to_cwd => false) do
Bundler.settings.set_command_option :path, "bundle"
end
end
diff --git a/lib/bundler/cli/issue.rb b/lib/bundler/cli/issue.rb
index 5f2924c4bd..b891ecb1d2 100644
--- a/lib/bundler/cli/issue.rb
+++ b/lib/bundler/cli/issue.rb
@@ -5,7 +5,7 @@ require "rbconfig"
module Bundler
class CLI::Issue
def run
- Bundler.ui.info <<~EOS
+ Bundler.ui.info <<-EOS.gsub(/^ {8}/, "")
Did you find an issue with Bundler? Before filing a new issue,
be sure to check out these resources:
diff --git a/lib/bundler/cli/lock.rb b/lib/bundler/cli/lock.rb
index dac3d2a09a..cb3ed27138 100644
--- a/lib/bundler/cli/lock.rb
+++ b/lib/bundler/cli/lock.rb
@@ -26,46 +26,42 @@ module Bundler
if update.is_a?(Array) # unlocking specific gems
Bundler::CLI::Common.ensure_all_gems_in_lockfile!(update)
- update = { gems: update, conservative: conservative }
+ update = { :gems => update, :conservative => conservative }
elsif update && conservative
- update = { conservative: conservative }
+ update = { :conservative => conservative }
elsif update && bundler
- update = { bundler: bundler }
+ update = { :bundler => bundler }
end
+ definition = Bundler.definition(update)
- file = options[:lockfile]
- file = file ? Pathname.new(file).expand_path : Bundler.default_lockfile
+ Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options) if options[:update]
- Bundler.settings.temporary(frozen: false) do
- definition = Bundler.definition(update, file)
-
- Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
-
- options["remove-platform"].each do |platform|
- definition.remove_platform(platform)
- end
+ options["remove-platform"].each do |platform|
+ definition.remove_platform(platform)
+ end
- options["add-platform"].each do |platform_string|
- platform = Gem::Platform.new(platform_string)
- if platform.to_s == "unknown"
- Bundler.ui.warn "The platform `#{platform_string}` is unknown to RubyGems " \
- "and adding it will likely lead to resolution errors"
- end
- definition.add_platform(platform)
+ options["add-platform"].each do |platform_string|
+ platform = Gem::Platform.new(platform_string)
+ if platform.to_s == "unknown"
+ Bundler.ui.warn "The platform `#{platform_string}` is unknown to RubyGems " \
+ "and adding it will likely lead to resolution errors"
end
+ definition.add_platform(platform)
+ end
- if definition.platforms.empty?
- raise InvalidOption, "Removing all platforms from the bundle is not allowed"
- end
+ if definition.platforms.empty?
+ raise InvalidOption, "Removing all platforms from the bundle is not allowed"
+ end
- definition.resolve_remotely! unless options[:local]
+ definition.resolve_remotely! unless options[:local]
- if print
- puts definition.to_lock
- else
- puts "Writing lockfile to #{file}"
- definition.lock
- end
+ if print
+ puts definition.to_lock
+ else
+ file = options[:lockfile]
+ file = file ? File.expand_path(file) : Bundler.default_lockfile
+ puts "Writing lockfile to #{file}"
+ definition.lock(file)
end
Bundler.ui.level = previous_ui_level
diff --git a/lib/bundler/cli/open.rb b/lib/bundler/cli/open.rb
index f24693b843..8522ec92d6 100644
--- a/lib/bundler/cli/open.rb
+++ b/lib/bundler/cli/open.rb
@@ -18,11 +18,13 @@ module Bundler
Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist."
else
root_path = spec.full_gem_path
- require "shellwords"
- command = Shellwords.split(editor) << File.join([root_path, path].compact)
- Bundler.with_original_env do
- system(*command, { chdir: root_path })
- end || Bundler.ui.info("Could not run '#{command.join(" ")}'")
+ Dir.chdir(root_path) do
+ require "shellwords"
+ command = Shellwords.split(editor) << File.join([root_path, path].compact)
+ Bundler.with_original_env do
+ system(*command)
+ end || Bundler.ui.info("Could not run '#{command.join(" ")}'")
+ end
end
end
end
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index ec42e631bb..68c701aefb 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -41,12 +41,12 @@ module Bundler
# We're doing a full update
Bundler.definition(true)
else
- Bundler.definition(gems: gems, sources: sources)
+ Bundler.definition(:gems => gems, :sources => sources)
end
Bundler::CLI::Common.configure_gem_version_promoter(
Bundler.definition,
- options.merge(strict: @strict)
+ options.merge(:strict => @strict)
)
definition_resolution = proc do
@@ -90,10 +90,10 @@ module Bundler
end
outdated_gems << {
- active_spec: active_spec,
- current_spec: current_spec,
- dependency: dependency,
- groups: groups,
+ :active_spec => active_spec,
+ :current_spec => current_spec,
+ :dependency => dependency,
+ :groups => groups,
}
end
diff --git a/lib/bundler/cli/plugin.rb b/lib/bundler/cli/plugin.rb
index fd61ef0d95..fe3f4412fa 100644
--- a/lib/bundler/cli/plugin.rb
+++ b/lib/bundler/cli/plugin.rb
@@ -5,15 +5,20 @@ module Bundler
class CLI::Plugin < Thor
desc "install PLUGINS", "Install the plugin from the source"
long_desc <<-D
- Install plugins either from the rubygems source provided (with --source option), from a git source provided with --git, or a local path provided with --path. If no sources are provided, it uses Gem.sources
+ Install plugins either from the rubygems source provided (with --source option) or from a git source provided with --git (for remote repos) or --local_git (for local repos). If no sources are provided, it uses Gem.sources
D
- method_option "source", type: :string, default: nil, banner: "URL of the RubyGems source to fetch the plugin from"
- method_option "version", type: :string, default: nil, banner: "The version of the plugin to fetch"
- method_option "git", type: :string, default: nil, banner: "URL of the git repo to fetch from"
- method_option "local_git", type: :string, default: nil, banner: "Path of the local git repo to fetch from (deprecated)"
- method_option "branch", type: :string, default: nil, banner: "The git branch to checkout"
- method_option "ref", type: :string, default: nil, banner: "The git revision to check out"
- method_option "path", type: :string, default: nil, banner: "Path of a local gem to directly use"
+ method_option "source", :type => :string, :default => nil, :banner =>
+ "URL of the RubyGems source to fetch the plugin from"
+ method_option "version", :type => :string, :default => nil, :banner =>
+ "The version of the plugin to fetch"
+ method_option "git", :type => :string, :default => nil, :banner =>
+ "URL of the git repo to fetch from"
+ method_option "local_git", :type => :string, :default => nil, :banner =>
+ "Path of the local git repo to fetch from"
+ method_option "branch", :type => :string, :default => nil, :banner =>
+ "The git branch to checkout"
+ method_option "ref", :type => :string, :default => nil, :banner =>
+ "The git revision to check out"
def install(*plugins)
Bundler::Plugin.install(plugins, options)
end
@@ -22,7 +27,8 @@ module Bundler
long_desc <<-D
Uninstall given list of plugins. To uninstall all the plugins, use -all option.
D
- method_option "all", type: :boolean, default: nil, banner: "Uninstall all the installed plugins. If no plugin is installed, then it does nothing."
+ method_option "all", :type => :boolean, :default => nil, :banner =>
+ "Uninstall all the installed plugins. If no plugin is installed, then it does nothing."
def uninstall(*plugins)
Bundler::Plugin.uninstall(plugins, options)
end
diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb
index e0d7452c44..d6654f8053 100644
--- a/lib/bundler/cli/pristine.rb
+++ b/lib/bundler/cli/pristine.rb
@@ -12,48 +12,40 @@ module Bundler
definition.validate_runtime!
installer = Bundler::Installer.new(Bundler.root, definition)
- ProcessLock.lock do
- installed_specs = definition.specs.reject do |spec|
- next if spec.name == "bundler" # Source::Rubygems doesn't install bundler
- next if !@gems.empty? && !@gems.include?(spec.name)
-
- gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
- gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
-
- case source = spec.source
- when Source::Rubygems
- cached_gem = spec.cache_file
- unless File.exist?(cached_gem)
- Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
- next
- end
-
- FileUtils.rm_rf spec.full_gem_path
- when Source::Git
- if source.local?
- Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.")
- next
- end
-
- source.remote!
- if extension_cache_path = source.extension_cache_path(spec)
- FileUtils.rm_rf extension_cache_path
- end
- FileUtils.rm_rf spec.extension_dir
- FileUtils.rm_rf spec.full_gem_path
- else
- Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
+ Bundler.load.specs.each do |spec|
+ next if spec.name == "bundler" # Source::Rubygems doesn't install bundler
+ next if !@gems.empty? && !@gems.include?(spec.name)
+
+ gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
+ gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
+
+ case source = spec.source
+ when Source::Rubygems
+ cached_gem = spec.cache_file
+ unless File.exist?(cached_gem)
+ Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
next
end
- true
- end.map(&:name)
+ FileUtils.rm_rf spec.full_gem_path
+ when Source::Git
+ if source.local?
+ Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.")
+ next
+ end
- jobs = installer.send(:installation_parallelization, {})
- pristine_count = definition.specs.count - installed_specs.count
- # allow a pristining a single gem to skip the parallel worker
- jobs = [jobs, pristine_count].min
- ParallelInstaller.call(installer, definition.specs, jobs, false, true, skip: installed_specs)
+ source.remote!
+ if extension_cache_path = source.extension_cache_path(spec)
+ FileUtils.rm_rf extension_cache_path
+ end
+ FileUtils.rm_rf spec.extension_dir
+ FileUtils.rm_rf spec.full_gem_path
+ else
+ Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
+ next
+ end
+
+ Bundler::GemInstaller.new(spec, installer, false, 0, true).install_from_spec
end
end
end
diff --git a/lib/bundler/cli/show.rb b/lib/bundler/cli/show.rb
index 59b0af42e1..2df13db1fa 100644
--- a/lib/bundler/cli/show.rb
+++ b/lib/bundler/cli/show.rb
@@ -40,8 +40,8 @@ module Bundler
desc = " * #{s.name} (#{s.version}#{s.git_version})"
if @verbose
latest = latest_specs.find {|l| l.name == s.name }
- Bundler.ui.info <<~END
- #{desc.lstrip}
+ Bundler.ui.info <<-END.gsub(/^ +/, "")
+ #{desc}
\tSummary: #{s.summary || "No description available."}
\tHomepage: #{s.homepage || "No website available."}
\tStatus: #{outdated?(s, latest) ? "Outdated - #{s.version} < #{latest.version}" : "Up to date"}
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index 985e8db051..b49182655b 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -35,7 +35,7 @@ module Bundler
if full_update
if conservative
- Bundler.definition(conservative: conservative)
+ Bundler.definition(:conservative => conservative)
else
Bundler.definition(true)
end
@@ -51,9 +51,9 @@ module Bundler
gems.concat(deps.map(&:name))
end
- Bundler.definition(gems: gems, sources: sources, ruby: options[:ruby],
- conservative: conservative,
- bundler: update_bundler)
+ Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby],
+ :conservative => conservative,
+ :bundler => update_bundler)
end
Bundler::CLI::Common.configure_gem_version_promoter(Bundler.definition, options)
@@ -63,7 +63,6 @@ module Bundler
opts = options.dup
opts["update"] = true
opts["local"] = options[:local]
- opts["force"] = options[:redownload]
Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
@@ -71,7 +70,7 @@ module Bundler
if locked_gems = Bundler.definition.locked_gems
previous_locked_info = locked_gems.specs.reduce({}) do |h, s|
- h[s.name] = { spec: s, version: s.version, source: s.source.identifier }
+ h[s.name] = { :spec => s, :version => s.version, :source => s.source.identifier }
h
end
end
diff --git a/lib/bundler/compact_index_client.rb b/lib/bundler/compact_index_client.rb
index 68e0d7e0d5..127a50e810 100644
--- a/lib/bundler/compact_index_client.rb
+++ b/lib/bundler/compact_index_client.rb
@@ -5,13 +5,7 @@ require "set"
module Bundler
class CompactIndexClient
- # NOTE: MD5 is here not because we expect a server to respond with it, but
- # because we use it to generate the etag on first request during the upgrade
- # to the compact index client that uses opaque etags saved to files.
- # Remove once 2.5.0 has been out for a while.
- SUPPORTED_DIGESTS = { "sha-256" => :SHA256, "md5" => :MD5 }.freeze
DEBUG_MUTEX = Thread::Mutex.new
-
def self.debug
return unless ENV["DEBUG_COMPACT_INDEX"]
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
@@ -20,7 +14,6 @@ module Bundler
class Error < StandardError; end
require_relative "compact_index_client/cache"
- require_relative "compact_index_client/cache_file"
require_relative "compact_index_client/updater"
attr_reader :directory
@@ -61,13 +54,13 @@ module Bundler
def names
Bundler::CompactIndexClient.debug { "/names" }
- update("names", @cache.names_path, @cache.names_etag_path)
+ update(@cache.names_path, "names")
@cache.names
end
def versions
Bundler::CompactIndexClient.debug { "/versions" }
- update("versions", @cache.versions_path, @cache.versions_etag_path)
+ update(@cache.versions_path, "versions")
versions, @info_checksums_by_name = @cache.versions
versions
end
@@ -83,36 +76,36 @@ module Bundler
def update_and_parse_checksums!
Bundler::CompactIndexClient.debug { "update_and_parse_checksums!" }
return @info_checksums_by_name if @parsed_checksums
- update("versions", @cache.versions_path, @cache.versions_etag_path)
+ update(@cache.versions_path, "versions")
@info_checksums_by_name = @cache.checksums
@parsed_checksums = true
end
private
- def update(remote_path, local_path, local_etag_path)
+ def update(local_path, remote_path)
Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" }
unless synchronize { @endpoints.add?(remote_path) }
Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" }
return
end
- @updater.update(url(remote_path), local_path, local_etag_path)
+ @updater.update(local_path, url(remote_path))
end
def update_info(name)
Bundler::CompactIndexClient.debug { "update_info(#{name})" }
path = @cache.info_path(name)
+ checksum = @updater.checksum_for_file(path)
unless existing = @info_checksums_by_name[name]
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since it is missing from versions" }
return
end
- checksum = SharedHelpers.checksum_for_file(path, :MD5)
if checksum == existing
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since the versions checksum matches the local checksum" }
return
end
Bundler::CompactIndexClient.debug { "updating info for #{name} since the versions checksum #{existing} != the local checksum #{checksum}" }
- update("info/#{name}", path, @cache.info_etag_path(name))
+ update(path, "info/#{name}")
end
def url(path)
diff --git a/lib/bundler/compact_index_client/cache.rb b/lib/bundler/compact_index_client/cache.rb
index bc6abaebc7..0b43581c11 100644
--- a/lib/bundler/compact_index_client/cache.rb
+++ b/lib/bundler/compact_index_client/cache.rb
@@ -9,8 +9,11 @@ module Bundler
def initialize(directory)
@directory = Pathname.new(directory).expand_path
- info_roots.each {|dir| mkdir(dir) }
- mkdir(info_etag_root)
+ info_roots.each do |dir|
+ SharedHelpers.filesystem_access(dir) do
+ FileUtils.mkdir_p(dir)
+ end
+ end
end
def names
@@ -21,10 +24,6 @@ module Bundler
directory.join("names")
end
- def names_etag_path
- directory.join("names.etag")
- end
-
def versions
versions_by_name = Hash.new {|hash, key| hash[key] = [] }
info_checksums_by_name = {}
@@ -32,12 +31,12 @@ module Bundler
lines(versions_path).each do |line|
name, versions_string, info_checksum = line.split(" ", 3)
info_checksums_by_name[name] = info_checksum || ""
- versions_string.split(",") do |version|
- delete = version.delete_prefix!("-")
- version = version.split("-", 2).unshift(name)
- if delete
+ versions_string.split(",").each do |version|
+ if version.start_with?("-")
+ version = version[1..-1].split("-", 2).unshift(name)
versions_by_name[name].delete(version)
else
+ version = version.split("-", 2).unshift(name)
versions_by_name[name] << version
end
end
@@ -50,14 +49,15 @@ module Bundler
directory.join("versions")
end
- def versions_etag_path
- directory.join("versions.etag")
- end
-
def checksums
- lines(versions_path).each_with_object({}) do |line, checksums|
- parse_version_checksum(line, checksums)
+ checksums = {}
+
+ lines(versions_path).each do |line|
+ name, _, checksum = line.split(" ", 3)
+ checksums[name] = checksum
end
+
+ checksums
end
def dependencies(name)
@@ -76,19 +76,8 @@ module Bundler
end
end
- def info_etag_path(name)
- name = name.to_s
- info_etag_root.join("#{name}-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}")
- end
-
private
- def mkdir(dir)
- SharedHelpers.filesystem_access(dir) do
- FileUtils.mkdir_p(dir)
- end
- end
-
def lines(path)
return [] unless path.file?
lines = SharedHelpers.filesystem_access(path, :read, &:read).split("\n")
@@ -101,30 +90,12 @@ module Bundler
@dependency_parser.parse(line)
end
- # This is mostly the same as `split(" ", 3)` but it avoids allocating extra objects.
- # This method gets called at least once for every gem when parsing versions.
- def parse_version_checksum(line, checksums)
- line.freeze # allows slicing into the string to not allocate a copy of the line
- name_end = line.index(" ")
- checksum_start = line.index(" ", name_end + 1) + 1
- checksum_end = line.size - checksum_start
- # freeze name since it is used as a hash key
- # pre-freezing means a frozen copy isn't created
- name = line[0, name_end].freeze
- checksum = line[checksum_start, checksum_end]
- checksums[name] = checksum
- end
-
def info_roots
[
directory.join("info"),
directory.join("info-special-characters"),
]
end
-
- def info_etag_root
- directory.join("info-etags")
- end
end
end
end
diff --git a/lib/bundler/compact_index_client/cache_file.rb b/lib/bundler/compact_index_client/cache_file.rb
deleted file mode 100644
index 5988bc91b3..0000000000
--- a/lib/bundler/compact_index_client/cache_file.rb
+++ /dev/null
@@ -1,153 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "../vendored_fileutils"
-require "rubygems/package"
-
-module Bundler
- class CompactIndexClient
- # write cache files in a way that is robust to concurrent modifications
- # if digests are given, the checksums will be verified
- class CacheFile
- DEFAULT_FILE_MODE = 0o644
- private_constant :DEFAULT_FILE_MODE
-
- class Error < RuntimeError; end
- class ClosedError < Error; end
-
- class DigestMismatchError < Error
- def initialize(digests, expected_digests)
- super "Calculated checksums #{digests.inspect} did not match expected #{expected_digests.inspect}."
- end
- end
-
- # Initialize with a copy of the original file, then yield the instance.
- def self.copy(path, &block)
- new(path) do |file|
- file.initialize_digests
-
- SharedHelpers.filesystem_access(path, :read) do
- path.open("rb") do |s|
- file.open {|f| IO.copy_stream(s, f) }
- end
- end
-
- yield file
- end
- end
-
- # Write data to a temp file, then replace the original file with it verifying the digests if given.
- def self.write(path, data, digests = nil)
- return unless data
- new(path) do |file|
- file.digests = digests
- file.write(data)
- end
- end
-
- attr_reader :original_path, :path
-
- def initialize(original_path, &block)
- @original_path = original_path
- @perm = original_path.file? ? original_path.stat.mode : DEFAULT_FILE_MODE
- @path = original_path.sub(/$/, ".#{$$}.tmp")
- return unless block_given?
- begin
- yield self
- ensure
- close
- end
- end
-
- def size
- path.size
- end
-
- # initialize the digests using CompactIndexClient::SUPPORTED_DIGESTS, or a subset based on keys.
- def initialize_digests(keys = nil)
- @digests = keys ? SUPPORTED_DIGESTS.slice(*keys) : SUPPORTED_DIGESTS.dup
- @digests.transform_values! {|algo_class| SharedHelpers.digest(algo_class).new }
- end
-
- # reset the digests so they don't contain any previously read data
- def reset_digests
- @digests&.each_value(&:reset)
- end
-
- # set the digests that will be verified at the end
- def digests=(expected_digests)
- @expected_digests = expected_digests
-
- if @expected_digests.nil?
- @digests = nil
- elsif @digests
- @digests = @digests.slice(*@expected_digests.keys)
- else
- initialize_digests(@expected_digests.keys)
- end
- end
-
- # remove this method when we stop generating md5 digests for legacy etags
- def md5
- @digests && @digests["md5"]
- end
-
- def digests?
- @digests&.any?
- end
-
- # Open the temp file for writing, reusing original permissions, yielding the IO object.
- def open(write_mode = "wb", perm = @perm, &block)
- raise ClosedError, "Cannot reopen closed file" if @closed
- SharedHelpers.filesystem_access(path, :write) do
- path.open(write_mode, perm) do |f|
- yield digests? ? Gem::Package::DigestIO.new(f, @digests) : f
- end
- end
- end
-
- # Returns false without appending when no digests since appending is too error prone to do without digests.
- def append(data)
- return false unless digests?
- open("a") {|f| f.write data }
- verify && commit
- end
-
- def write(data)
- reset_digests
- open {|f| f.write data }
- commit!
- end
-
- def commit!
- verify || raise(DigestMismatchError.new(@base64digests, @expected_digests))
- commit
- end
-
- # Verify the digests, returning true on match, false on mismatch.
- def verify
- return true unless @expected_digests && digests?
- @base64digests = @digests.transform_values!(&:base64digest)
- @digests = nil
- @base64digests.all? {|algo, digest| @expected_digests[algo] == digest }
- end
-
- # Replace the original file with the temp file without verifying digests.
- # The file is permanently closed.
- def commit
- raise ClosedError, "Cannot commit closed file" if @closed
- SharedHelpers.filesystem_access(original_path, :write) do
- FileUtils.mv(path, original_path)
- end
- @closed = true
- end
-
- # Remove the temp file without replacing the original file.
- # The file is permanently closed.
- def close
- return if @closed
- FileUtils.remove_file(path) if @path&.file?
- @closed = true
- end
- end
- end
-end
diff --git a/lib/bundler/compact_index_client/gem_parser.rb b/lib/bundler/compact_index_client/gem_parser.rb
index 60a1817607..e7bf4c6001 100644
--- a/lib/bundler/compact_index_client/gem_parser.rb
+++ b/lib/bundler/compact_index_client/gem_parser.rb
@@ -6,15 +6,12 @@ module Bundler
GemParser = Gem::Resolver::APISet::GemParser
else
class GemParser
- EMPTY_ARRAY = [].freeze
- private_constant :EMPTY_ARRAY
-
def parse(line)
version_and_platform, rest = line.split(" ", 2)
version, platform = version_and_platform.split("-", 2)
- dependencies, requirements = rest.split("|", 2).map! {|s| s.split(",") } if rest
- dependencies = dependencies ? dependencies.map! {|d| parse_dependency(d) } : EMPTY_ARRAY
- requirements = requirements ? requirements.map! {|d| parse_dependency(d) } : EMPTY_ARRAY
+ dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
+ dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
+ requirements = requirements ? requirements.map {|d| parse_dependency(d) } : []
[version, platform, dependencies, requirements]
end
@@ -23,7 +20,6 @@ module Bundler
def parse_dependency(string)
dependency = string.split(":")
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
- dependency[0] = -dependency[0]
dependency
end
end
diff --git a/lib/bundler/compact_index_client/updater.rb b/lib/bundler/compact_index_client/updater.rb
index 36f6b81db8..0f7bf9bb50 100644
--- a/lib/bundler/compact_index_client/updater.rb
+++ b/lib/bundler/compact_index_client/updater.rb
@@ -1,11 +1,20 @@
# frozen_string_literal: true
+require_relative "../vendored_fileutils"
+
module Bundler
class CompactIndexClient
class Updater
- class MismatchedChecksumError < Error
- def initialize(path, message)
- super "The checksum of /#{path} does not match the checksum provided by the server! Something is wrong. #{message}"
+ class MisMatchedChecksumError < Error
+ def initialize(path, server_checksum, local_checksum)
+ @path = path
+ @server_checksum = server_checksum
+ @local_checksum = local_checksum
+ end
+
+ def message
+ "The checksum of /#{@path} does not match the checksum provided by the server! Something is wrong " \
+ "(local checksum is #{@local_checksum.inspect}, was expecting #{@server_checksum.inspect})."
end
end
@@ -13,102 +22,95 @@ module Bundler
@fetcher = fetcher
end
- def update(remote_path, local_path, etag_path)
- append(remote_path, local_path, etag_path) || replace(remote_path, local_path, etag_path)
- rescue CacheFile::DigestMismatchError => e
- raise MismatchedChecksumError.new(remote_path, e.message)
- rescue Zlib::GzipFile::Error
- raise Bundler::HTTPError
- end
+ def update(local_path, remote_path, retrying = nil)
+ headers = {}
- private
+ local_temp_path = local_path.sub(/$/, ".#{$$}")
+ local_temp_path = local_temp_path.sub(/$/, ".retrying") if retrying
+ local_temp_path = local_temp_path.sub(/$/, ".tmp")
+
+ # first try to fetch any new bytes on the existing file
+ if retrying.nil? && local_path.file?
+ copy_file local_path, local_temp_path
+
+ headers["If-None-Match"] = etag_for(local_temp_path)
+ headers["Range"] =
+ if local_temp_path.size.nonzero?
+ # Subtract a byte to ensure the range won't be empty.
+ # Avoids 416 (Range Not Satisfiable) responses.
+ "bytes=#{local_temp_path.size - 1}-"
+ else
+ "bytes=#{local_temp_path.size}-"
+ end
+ end
- def append(remote_path, local_path, etag_path)
- return false unless local_path.file? && local_path.size.nonzero?
+ response = @fetcher.call(remote_path, headers)
+ return nil if response.is_a?(Net::HTTPNotModified)
- CacheFile.copy(local_path) do |file|
- etag = etag_path.read.tap(&:chomp!) if etag_path.file?
- etag ||= generate_etag(etag_path, file) # Remove this after 2.5.0 has been out for a while.
+ content = response.body
- # Subtract a byte to ensure the range won't be empty.
- # Avoids 416 (Range Not Satisfiable) responses.
- response = @fetcher.call(remote_path, request_headers(etag, file.size - 1))
- break true if response.is_a?(Gem::Net::HTTPNotModified)
+ etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
+ correct_response = SharedHelpers.filesystem_access(local_temp_path) do
+ if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
+ local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
- file.digests = parse_digests(response)
- # server may ignore Range and return the full response
- if response.is_a?(Gem::Net::HTTPPartialContent)
- break false unless file.append(response.body.byteslice(1..-1))
+ etag_for(local_temp_path) == etag
else
- file.write(response.body)
+ local_temp_path.open("wb") {|f| f << content }
+
+ etag.length.zero? || etag_for(local_temp_path) == etag
end
- CacheFile.write(etag_path, etag_from_response(response))
- true
end
- end
- # request without range header to get the full file or a 304 Not Modified
- def replace(remote_path, local_path, etag_path)
- etag = etag_path.read.tap(&:chomp!) if etag_path.file?
- response = @fetcher.call(remote_path, request_headers(etag))
- return true if response.is_a?(Gem::Net::HTTPNotModified)
- CacheFile.write(local_path, response.body, parse_digests(response))
- CacheFile.write(etag_path, etag_from_response(response))
- end
+ if correct_response
+ SharedHelpers.filesystem_access(local_path) do
+ FileUtils.mv(local_temp_path, local_path)
+ end
+ return nil
+ end
- def request_headers(etag, range_start = nil)
- headers = {}
- headers["Range"] = "bytes=#{range_start}-" if range_start
- headers["If-None-Match"] = %("#{etag}") if etag
- headers
- end
+ if retrying
+ raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path))
+ end
- def etag_for_request(etag_path)
- etag_path.read.tap(&:chomp!) if etag_path.file?
+ update(local_path, remote_path, :retrying)
+ rescue Zlib::GzipFile::Error
+ raise Bundler::HTTPError
+ ensure
+ FileUtils.remove_file(local_temp_path) if File.exist?(local_temp_path)
end
- # When first releasing this opaque etag feature, we want to generate the old MD5 etag
- # based on the content of the file. After that it will always use the saved opaque etag.
- # This transparently saves existing users with good caches from updating a bunch of files.
- # Remove this behavior after 2.5.0 has been out for a while.
- def generate_etag(etag_path, file)
- etag = file.md5.hexdigest
- CacheFile.write(etag_path, etag)
- etag
+ def etag_for(path)
+ sum = checksum_for_file(path)
+ sum ? %("#{sum}") : nil
end
- def etag_from_response(response)
- return unless response["ETag"]
- etag = response["ETag"].delete_prefix("W/")
- return if etag.delete_prefix!('"') && !etag.delete_suffix!('"')
- etag
+ def slice_body(body, range)
+ body.byteslice(range)
end
- # Unwraps and returns a Hash of digest algorithms and base64 values
- # according to RFC 8941 Structured Field Values for HTTP.
- # https://www.rfc-editor.org/rfc/rfc8941#name-parsing-a-byte-sequence
- # Ignores unsupported algorithms.
- def parse_digests(response)
- return unless header = response["Repr-Digest"] || response["Digest"]
- digests = {}
- header.split(",") do |param|
- algorithm, value = param.split("=", 2)
- algorithm.strip!
- algorithm.downcase!
- next unless SUPPORTED_DIGESTS.key?(algorithm)
- next unless value = byte_sequence(value)
- digests[algorithm] = value
+ def checksum_for_file(path)
+ return nil unless path.file?
+ # This must use File.read instead of Digest.file().hexdigest
+ # because we need to preserve \n line endings on windows when calculating
+ # the checksum
+ SharedHelpers.filesystem_access(path, :read) do
+ SharedHelpers.digest(:MD5).hexdigest(File.read(path))
end
- digests.empty? ? nil : digests
end
- # Unwrap surrounding colons (byte sequence)
- # The wrapping characters must be matched or we return nil.
- # Also handles quotes because right now rubygems.org sends them.
- def byte_sequence(value)
- return if value.delete_prefix!(":") && !value.delete_suffix!(":")
- return if value.delete_prefix!('"') && !value.delete_suffix!('"')
- value
+ private
+
+ def copy_file(source, dest)
+ SharedHelpers.filesystem_access(source, :read) do
+ File.open(source, "r") do |s|
+ SharedHelpers.filesystem_access(dest, :write) do
+ File.open(dest, "wb", s.stat.mode) do |f|
+ IO.copy_stream(s, f)
+ end
+ end
+ end
+ end
end
end
end
diff --git a/lib/bundler/constants.rb b/lib/bundler/constants.rb
index 9564771e78..8dd8a53815 100644
--- a/lib/bundler/constants.rb
+++ b/lib/bundler/constants.rb
@@ -1,14 +1,7 @@
# frozen_string_literal: true
-require "rbconfig"
-
module Bundler
WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/
- deprecate_constant :WINDOWS
-
FREEBSD = RbConfig::CONFIG["host_os"].to_s.include?("bsd")
- deprecate_constant :FREEBSD
-
- NULL = File::NULL
- deprecate_constant :NULL
+ NULL = WINDOWS ? "NUL" : "/dev/null"
end
diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb
index 93e0c401c0..f009b07ad7 100644
--- a/lib/bundler/current_ruby.rb
+++ b/lib/bundler/current_ruby.rb
@@ -43,7 +43,7 @@ module Bundler
].freeze
def ruby?
- return true if Bundler::GemHelpers.generic_local_platform_is_ruby?
+ return true if Bundler::GemHelpers.generic_local_platform == Gem::Platform::RUBY
!windows? && (RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby")
end
@@ -71,10 +71,26 @@ module Bundler
def windows?
Gem.win_platform?
end
- alias_method :mswin?, :windows?
- alias_method :mswin64?, :windows?
- alias_method :mingw?, :windows?
- alias_method :x64_mingw?, :windows?
+
+ def mswin?
+ # For backwards compatibility
+ windows?
+
+ # TODO: This should correctly be:
+ # windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin32" && Bundler.local_platform.cpu == "x86"
+ end
+
+ def mswin64?
+ windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
+ end
+
+ def mingw?
+ windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
+ end
+
+ def x64_mingw?
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os.start_with?("mingw") && Bundler.local_platform.cpu == "x64"
+ end
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
trimmed_version = version.tr(".", "")
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 6cf1f9a255..564530a98c 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -18,8 +18,7 @@ module Bundler
:platforms,
:ruby_version,
:lockfile,
- :gemfiles,
- :locked_checksums
+ :gemfiles
)
# Given a gemfile and lockfile creates a Bundler definition
@@ -69,6 +68,7 @@ module Bundler
@sources = sources
@unlock = unlock
@optional_groups = optional_groups
+ @remote = false
@prefer_local = false
@specs = nil
@ruby_version = ruby_version
@@ -84,19 +84,17 @@ module Bundler
@new_platform = nil
@removed_platform = nil
- if lockfile_exists?
+ if lockfile && File.exist?(lockfile)
@lockfile_contents = Bundler.read_file(lockfile)
@locked_gems = LockfileParser.new(@lockfile_contents)
@locked_platforms = @locked_gems.platforms
@platforms = @locked_platforms.dup
@locked_bundler_version = @locked_gems.bundler_version
@locked_ruby_version = @locked_gems.ruby_version
- @originally_locked_deps = @locked_gems.dependencies
@originally_locked_specs = SpecSet.new(@locked_gems.specs)
- @locked_checksums = @locked_gems.checksums
if unlock != true
- @locked_deps = @originally_locked_deps
+ @locked_deps = @locked_gems.dependencies
@locked_specs = @originally_locked_specs
@locked_sources = @locked_gems.sources
else
@@ -111,11 +109,9 @@ module Bundler
@locked_gems = nil
@locked_deps = {}
@locked_specs = SpecSet.new([])
- @originally_locked_deps = {}
@originally_locked_specs = @locked_specs
@locked_sources = []
@locked_platforms = []
- @locked_checksums = nil
end
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@@ -131,7 +127,7 @@ module Bundler
@sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
end
- @sources_to_unlock = @unlock.delete(:sources) || []
+ @unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@ruby_version.diff(locked_ruby_version_object)
end
@@ -143,19 +139,17 @@ module Bundler
@path_changes = converge_paths
@source_changes = converge_sources
- @explicit_unlocks = @unlock.delete(:gems) || []
-
if @unlock[:conservative]
- @gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
+ @unlock[:gems] ||= @dependencies.map(&:name)
else
- eager_unlock = @explicit_unlocks.map {|name| Dependency.new(name, ">= 0") }
- @gems_to_unlock = @locked_specs.for(eager_unlock, false, platforms).map(&:name).uniq
+ eager_unlock = (@unlock[:gems] || []).map {|name| Dependency.new(name, ">= 0") }
+ @unlock[:gems] = @locked_specs.for(eager_unlock, false, platforms).map(&:name).uniq
end
@dependency_changes = converge_dependencies
@local_changes = converge_locals
- check_lockfile
+ @missing_lockfile_dep = check_missing_lockfile_dep
end
def gem_version_promoter
@@ -163,24 +157,37 @@ module Bundler
end
def resolve_only_locally!
+ @remote = false
sources.local_only!
resolve
end
def resolve_with_cache!
- sources.local!
sources.cached!
resolve
end
def resolve_remotely!
- sources.cached!
+ @remote = true
sources.remote!
resolve
end
- def prefer_local!
- @prefer_local = true
+ def resolution_mode=(options)
+ if options["local"]
+ @remote = false
+ else
+ @remote = true
+ @prefer_local = options["prefer-local"]
+ end
+ end
+
+ def setup_sources_for_resolve
+ if @remote == false
+ sources.cached!
+ else
+ sources.remote!
+ end
end
# For given dependency list returns a SpecSet with Gemspec of all the required
@@ -215,6 +222,7 @@ module Bundler
@resolver = nil
@resolution_packages = nil
@specs = nil
+ @gem_version_promoter = nil
Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
true
@@ -237,9 +245,8 @@ module Bundler
end
def filter_relevant(dependencies)
- platforms_array = [generic_local_platform].freeze
dependencies.select do |d|
- d.should_include? && !d.gem_platforms(platforms_array).empty?
+ d.should_include? && !d.gem_platforms([generic_local_platform]).empty?
end
end
@@ -263,15 +270,9 @@ module Bundler
def dependencies_for(groups)
groups.map!(&:to_sym)
- deps = current_dependencies # always returns a new array
- deps.select! do |d|
- if RUBY_VERSION >= "3.1"
- d.groups.intersect?(groups)
- else
- !(d.groups & groups).empty?
- end
+ current_dependencies.reject do |d|
+ (d.groups & groups).empty?
end
- deps
end
# Resolve all the dependencies specified in Gemfile. It ensures that
@@ -296,12 +297,7 @@ module Bundler
end
end
else
- if lockfile_exists?
- Bundler.ui.debug "Found changes from the lockfile, re-resolving dependencies because #{change_reason}"
- else
- Bundler.ui.debug "Resolving dependencies because there's no lockfile"
- end
-
+ Bundler.ui.debug "Found changes from the lockfile, re-resolving dependencies because #{change_reason}"
start_resolution
end
end
@@ -314,26 +310,34 @@ module Bundler
dependencies.map(&:groups).flatten.uniq
end
- def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or_unused = false)
- if [true, false, nil].include?(file_or_preserve_unknown_sections)
- target_lockfile = lockfile || Bundler.default_lockfile
- preserve_unknown_sections = file_or_preserve_unknown_sections
- else
- target_lockfile = file_or_preserve_unknown_sections
- preserve_unknown_sections = preserve_unknown_sections_or_unused
+ def lock(file, preserve_unknown_sections = false)
+ return if Definition.no_lock
- suggestion = if target_lockfile == lockfile
- "To fix this warning, remove it from the `Definition#lock` call."
- else
- "Instead, instantiate a new definition passing `#{target_lockfile}`, and call `lock` without a file argument on that definition"
- end
+ contents = to_lock
+
+ # Convert to \r\n if the existing lock has them
+ # i.e., Windows with `git config core.autocrlf=true`
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
+
+ if @locked_bundler_version
+ locked_major = @locked_bundler_version.segments.first
+ current_major = bundler_version_to_lock.segments.first
+
+ updating_major = locked_major < current_major
+ end
+
+ preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
- msg = "`Definition#lock` was passed a target file argument. #{suggestion}"
+ return if file && File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
- Bundler::SharedHelpers.major_deprecation 2, msg
+ if Bundler.frozen_bundle?
+ Bundler.ui.error "Cannot write a changed lockfile while frozen."
+ return
end
- write_lock(target_lockfile, preserve_unknown_sections)
+ SharedHelpers.filesystem_access(file) do |p|
+ File.open(p, "wb") {|f| f.puts(contents) }
+ end
end
def locked_ruby_version
@@ -401,13 +405,13 @@ module Bundler
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
- msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} to version control.\n"
+ msg << "\n\nRun `bundle install` elsewhere and add the updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control.\n"
unless explicit_flag
suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
"bundle config set frozen false"
end
- msg << "If this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \
+ msg << "If this is a development machine, remove the #{Bundler.default_gemfile.relative_path_from(SharedHelpers.pwd)} " \
"freeze by running `#{suggested_command}`." if suggested_command
end
@@ -448,8 +452,8 @@ module Bundler
return if current_platform_locked?
raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
- "but your local platform is #{local_platform}. " \
- "Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again."
+ "but your local platform is #{Bundler.local_platform}. " \
+ "Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again."
end
def add_platform(platform)
@@ -474,17 +478,7 @@ module Bundler
private :sources
def nothing_changed?
- return false unless lockfile_exists?
-
- !@source_changes &&
- !@dependency_changes &&
- !@new_platform &&
- !@path_changes &&
- !@local_changes &&
- !@missing_lockfile_dep &&
- !@unlocking_bundler &&
- !@locked_spec_with_missing_deps &&
- !@locked_spec_with_invalid_deps
+ !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@missing_lockfile_dep && !@unlocking_bundler
end
def no_resolve_needed?
@@ -497,52 +491,6 @@ module Bundler
private
- def should_add_extra_platforms?
- !lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
- end
-
- def lockfile_exists?
- file_exists?(lockfile)
- end
-
- def file_exists?(file)
- file && File.exist?(file)
- end
-
- def write_lock(file, preserve_unknown_sections)
- return if Definition.no_lock
-
- contents = to_lock
-
- # Convert to \r\n if the existing lock has them
- # i.e., Windows with `git config core.autocrlf=true`
- contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
-
- if @locked_bundler_version
- locked_major = @locked_bundler_version.segments.first
- current_major = bundler_version_to_lock.segments.first
-
- updating_major = locked_major < current_major
- end
-
- preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
-
- if file_exists?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
- return if Bundler.frozen_bundle?
- SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
- return
- end
-
- if Bundler.frozen_bundle?
- Bundler.ui.error "Cannot write a changed lockfile while frozen."
- return
- end
-
- SharedHelpers.filesystem_access(file) do |p|
- File.open(p, "wb") {|f| f.puts(contents) }
- end
- end
-
def resolver
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
end
@@ -561,11 +509,9 @@ module Bundler
def resolution_packages
@resolution_packages ||= begin
last_resolve = converge_locked_specs
- remove_invalid_platforms!(current_dependencies)
- packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @gems_to_unlock, prerelease: gem_version_promoter.pre?)
- packages = additional_base_requirements_to_prevent_downgrades(packages, last_resolve)
- packages = additional_base_requirements_to_force_updates(packages)
- packages
+ remove_ruby_from_platforms_if_necessary!(current_dependencies)
+ packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, :locked_specs => @originally_locked_specs, :unlock => @unlock[:gems], :prerelease => gem_version_promoter.pre?)
+ additional_base_requirements_for_resolve(packages, last_resolve)
end
end
@@ -580,7 +526,7 @@ module Bundler
if missing_specs.any?
missing_specs.each do |s|
locked_gem = @locked_specs[s.name].last
- next if locked_gem.nil? || locked_gem.version != s.version || sources.local_mode?
+ next if locked_gem.nil? || locked_gem.version != s.version || !@remote
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
@@ -599,7 +545,7 @@ module Bundler
break if incomplete_specs.empty?
Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
- sources.remote!
+ setup_sources_for_resolve
resolution_packages.delete(incomplete_specs)
@resolve = start_resolution
specs = resolve.materialize(dependencies)
@@ -621,14 +567,11 @@ module Bundler
end
def start_resolution
- result = SpecSet.new(resolver.start)
+ result = resolver.start
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
- @platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
-
- result.complete_platforms!(platforms)
- SpecSet.new(result.for(dependencies, false, @platforms))
+ SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms))
end
def precompute_source_requirements_for_indirect_dependencies?
@@ -649,7 +592,7 @@ module Bundler
end
def current_ruby_platform_locked?
- return false unless generic_local_platform_is_ruby?
+ return false unless generic_local_platform == Gem::Platform::RUBY
return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY)
current_platform_locked?
@@ -657,7 +600,7 @@ module Bundler
def current_platform_locked?
@platforms.any? do |bundle_platform|
- MatchPlatform.platforms_match?(bundle_platform, local_platform)
+ MatchPlatform.platforms_match?(bundle_platform, Bundler.local_platform)
end
end
@@ -669,18 +612,14 @@ module Bundler
def change_reason
if unlocking?
- unlock_targets = if @gems_to_unlock.any?
- ["gems", @gems_to_unlock]
- elsif @sources_to_unlock.any?
- ["sources", @sources_to_unlock]
- end
-
- unlock_reason = if unlock_targets
- "#{unlock_targets.first}: (#{unlock_targets.last.join(", ")})"
- else
- @unlock[:ruby] ? "ruby" : ""
- end
-
+ unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v|
+ if v == true
+ k.to_s
+ else
+ v = Array(v)
+ "#{k}: (#{v.join(", ")})"
+ end
+ end.join(", ")
return "bundler is unlocking #{unlock_reason}"
end
[
@@ -691,8 +630,6 @@ module Bundler
[@local_changes, "the gemspecs for git local gems changed"],
[@missing_lockfile_dep, "your lock file is missing \"#{@missing_lockfile_dep}\""],
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
- [@locked_spec_with_missing_deps, "your lock file includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
- [@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
].select(&:first).map(&:last).join(", ")
end
@@ -719,7 +656,8 @@ module Bundler
locked_index = Index.new
locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
- !locked_index.subset?(source.specs)
+ # order here matters, since Index#== is checking source.specs.include?(locked_index)
+ locked_index != source.specs
rescue PathError, GitError => e
Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})"
false
@@ -735,7 +673,7 @@ module Bundler
spec = @dependencies.find {|s| s.name == k }
source = spec&.source
if source&.respond_to?(:local_override!)
- source.unlock! if @gems_to_unlock.include?(spec.name)
+ source.unlock! if @unlock[:gems].include?(spec.name)
locals << [source, source.local_override!(v)]
end
end
@@ -743,40 +681,27 @@ module Bundler
sources_with_changes = locals.select do |source, changed|
changed || specs_changed?(source)
end.map(&:first)
- !sources_with_changes.each {|source| @sources_to_unlock << source.name }.empty?
+ !sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty?
end
- def check_lockfile
- @missing_lockfile_dep = nil
-
- @locked_spec_with_invalid_deps = nil
- @locked_spec_with_missing_deps = nil
-
- missing = []
- invalid = []
-
- @locked_specs.each do |s|
- validation = @locked_specs.validate_deps(s)
+ def check_missing_lockfile_dep
+ all_locked_specs = @locked_specs.map(&:name) << "bundler"
- missing << s if validation == :missing
- invalid << s if validation == :invalid
+ missing = @locked_specs.select do |s|
+ s.dependencies.any? {|dep| !all_locked_specs.include?(dep.name) }
end
if missing.any?
@locked_specs.delete(missing)
- @locked_spec_with_missing_deps = missing.first.name
- elsif !@dependency_changes
- @missing_lockfile_dep = current_dependencies.find do |d|
- @locked_specs[d.name].empty? && d.name != "bundler"
- end&.name
+ return missing.first.name
end
- if invalid.any?
- @locked_specs.delete(invalid)
+ return if @dependency_changes
- @locked_spec_with_invalid_deps = invalid.first.name
- end
+ current_dependencies.find do |d|
+ @locked_specs[d.name].empty? && d.name != "bundler"
+ end&.name
end
def converge_paths
@@ -810,17 +735,12 @@ module Bundler
changes = sources.replace_sources!(@locked_sources)
sources.all_sources.each do |source|
- # has to be done separately, because we want to keep the locked checksum
- # store for a source, even when doing a full update
- if @locked_checksums && @locked_gems && locked_source = @locked_gems.sources.find {|s| s == source && !s.equal?(source) }
- source.checksum_store.merge!(locked_source.checksum_store)
- end
# If the source is unlockable and the current command allows an unlock of
# the source (for example, you are doing a `bundle update <foo>` of a git-pinned
# gem), unlock it. For git sources, this means to unlock the revision, which
# will cause the `ref` used to be the most recent for the branch (or master) if
# an explicit `ref` is not used.
- if source.respond_to?(:unlock!) && @sources_to_unlock.include?(source.name)
+ if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
source.unlock!
changes = true
end
@@ -837,7 +757,9 @@ module Bundler
dep.source = sources.get(dep.source)
end
- unless locked_dep = @originally_locked_deps[dep.name]
+ next if unlocking?
+
+ unless locked_dep = @locked_deps[dep.name]
changes = true
next
end
@@ -864,7 +786,7 @@ module Bundler
def converge_locked_specs
converged = converge_specs(@locked_specs)
- resolve = SpecSet.new(converged.reject {|s| @gems_to_unlock.include?(s.name) })
+ resolve = SpecSet.new(converged.reject {|s| @unlock[:gems].include?(s.name) })
diff = nil
@@ -897,7 +819,7 @@ module Bundler
@specs_that_changed_sources << s if gemfile_source != lockfile_source
deps << dep if !dep.source || lockfile_source.include?(dep.source)
- @gems_to_unlock << name if lockfile_source.include?(dep.source) && lockfile_source != gemfile_source
+ @unlock[:gems] << name if lockfile_source.include?(dep.source) && lockfile_source != gemfile_source
# Replace the locked dependency's source with the equivalent source from the Gemfile
s.source = gemfile_source
@@ -906,7 +828,7 @@ module Bundler
s.source = default_source unless sources.get(lockfile_source)
end
- next if @sources_to_unlock.include?(s.source.name)
+ next if @unlock[:sources].include?(s.source.name)
# Path sources have special logic
if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
@@ -928,12 +850,12 @@ module Bundler
else
# If the spec is no longer in the path source, unlock it. This
# commonly happens if the version changed in the gemspec
- @gems_to_unlock << name
+ @unlock[:gems] << name
end
end
if dep.nil? && requested_dependencies.find {|d| name == d.name }
- @gems_to_unlock << s.name
+ @unlock[:gems] << s.name
else
converged << s
end
@@ -944,7 +866,7 @@ module Bundler
def metadata_dependencies
@metadata_dependencies ||= [
- Dependency.new("Ruby\0", Bundler::RubyVersion.system.gem_version),
+ Dependency.new("Ruby\0", Gem.ruby_version),
Dependency.new("RubyGems\0", Gem::VERSION),
]
end
@@ -956,11 +878,11 @@ module Bundler
source_requirements = if precompute_source_requirements_for_indirect_dependencies?
all_requirements = source_map.all_requirements
all_requirements = pin_locally_available_names(all_requirements) if @prefer_local
- { default: default_source }.merge(all_requirements)
+ { :default => default_source }.merge(all_requirements)
else
- { default: Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
+ { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
end
- source_requirements.merge!(source_map.locked_requirements) if nothing_changed?
+ source_requirements.merge!(source_map.locked_requirements) unless @remote
metadata_dependencies.each do |dep|
source_requirements[dep.name] = sources.metadata_source
end
@@ -1010,7 +932,7 @@ module Bundler
current == proposed
end
- def additional_base_requirements_to_prevent_downgrades(resolution_packages, last_resolve)
+ def additional_base_requirements_for_resolve(resolution_packages, last_resolve)
return resolution_packages unless @locked_gems && !sources.expired_sources?(@locked_gems.sources)
converge_specs(@originally_locked_specs - last_resolve).each do |locked_spec|
next if locked_spec.source.is_a?(Source::Path)
@@ -1019,39 +941,17 @@ module Bundler
resolution_packages
end
- def additional_base_requirements_to_force_updates(resolution_packages)
- return resolution_packages if @explicit_unlocks.empty?
- full_update = dup_for_full_unlock.resolve
- @explicit_unlocks.each do |name|
- version = full_update[name].first&.version
- resolution_packages.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
- end
- resolution_packages
- end
-
- def dup_for_full_unlock
- unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles)
- unlocked_definition.gem_version_promoter.tap do |gvp|
- gvp.level = gem_version_promoter.level
- gvp.strict = gem_version_promoter.strict
- gvp.pre = gem_version_promoter.pre
- end
- unlocked_definition
- end
-
- def remove_invalid_platforms!(dependencies)
- return if Bundler.frozen_bundle?
-
- platforms.reverse_each do |platform|
- next if local_platform == platform ||
- (@new_platform && platforms.last == platform) ||
+ def remove_ruby_from_platforms_if_necessary!(dependencies)
+ return if Bundler.frozen_bundle? ||
+ Bundler.local_platform == Gem::Platform::RUBY ||
+ !platforms.include?(Gem::Platform::RUBY) ||
+ (@new_platform && platforms.last == Gem::Platform::RUBY) ||
@path_changes ||
@dependency_changes ||
- !@originally_locked_specs.incomplete_for_platform?(dependencies, platform)
+ !@originally_locked_specs.incomplete_ruby_specs?(dependencies)
- remove_platform(platform)
- add_current_platform if platform == Gem::Platform::RUBY
- end
+ remove_platform(Gem::Platform::RUBY)
+ add_current_platform
end
def source_map
diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb
index 2a4f72fe55..5f17943629 100644
--- a/lib/bundler/dependency.rb
+++ b/lib/bundler/dependency.rb
@@ -7,21 +7,20 @@ require_relative "rubygems_ext"
module Bundler
class Dependency < Gem::Dependency
attr_reader :autorequire
- attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref, :glob
+ attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref
- ALL_RUBY_VERSIONS = (18..27).to_a.concat((30..34).to_a).freeze
+ ALL_RUBY_VERSIONS = ((18..27).to_a + (30..33).to_a).freeze
PLATFORM_MAP = {
- ruby: [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
- mri: [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
- rbx: [Gem::Platform::RUBY],
- truffleruby: [Gem::Platform::RUBY],
- jruby: [Gem::Platform::JAVA, [18, 19]],
- windows: [Gem::Platform::WINDOWS, ALL_RUBY_VERSIONS],
- # deprecated
- mswin: [Gem::Platform::MSWIN, ALL_RUBY_VERSIONS],
- mswin64: [Gem::Platform::MSWIN64, ALL_RUBY_VERSIONS - [18]],
- mingw: [Gem::Platform::MINGW, ALL_RUBY_VERSIONS],
- x64_mingw: [Gem::Platform::X64_MINGW, ALL_RUBY_VERSIONS - [18, 19]],
+ :ruby => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
+ :mri => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
+ :rbx => [Gem::Platform::RUBY],
+ :truffleruby => [Gem::Platform::RUBY],
+ :jruby => [Gem::Platform::JAVA, [18, 19]],
+ :windows => [Gem::Platform::WINDOWS, ALL_RUBY_VERSIONS],
+ :mswin => [Gem::Platform::MSWIN, ALL_RUBY_VERSIONS],
+ :mswin64 => [Gem::Platform::MSWIN64, ALL_RUBY_VERSIONS - [18]],
+ :mingw => [Gem::Platform::MINGW, ALL_RUBY_VERSIONS],
+ :x64_mingw => [Gem::Platform::X64_MINGW, ALL_RUBY_VERSIONS - [18, 19]],
}.each_with_object({}) do |(platform, spec), hash|
hash[platform] = spec[0]
spec[1]&.each {|version| hash[:"#{platform}_#{version}"] = spec[0] }
@@ -39,7 +38,6 @@ module Bundler
@github = options["github"]
@branch = options["branch"]
@ref = options["ref"]
- @glob = options["glob"]
@platforms = Array(options["platforms"])
@env = options["env"]
@should_include = options.fetch("should_include", true)
@@ -49,13 +47,10 @@ module Bundler
@autorequire = Array(options["require"] || []) if options.key?("require")
end
- RUBY_PLATFORM_ARRAY = [Gem::Platform::RUBY].freeze
- private_constant :RUBY_PLATFORM_ARRAY
-
# Returns the platforms this dependency is valid for, in the same order as
# passed in the `valid_platforms` parameter
def gem_platforms(valid_platforms)
- return RUBY_PLATFORM_ARRAY if force_ruby_platform
+ return [Gem::Platform::RUBY] if force_ruby_platform
return valid_platforms if @platforms.empty?
valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) }
@@ -69,10 +64,6 @@ module Bundler
@should_include && current_env? && current_platform?
end
- def gemspec_dev_dep?
- type == :development
- end
-
def current_env?
return true unless @env
if @env.is_a?(Hash)
diff --git a/lib/bundler/digest.rb b/lib/bundler/digest.rb
index 2c6d971f1b..f11f5edd38 100644
--- a/lib/bundler/digest.rb
+++ b/lib/bundler/digest.rb
@@ -26,7 +26,7 @@ module Bundler
end
a, b, c, d, e = *words
(16..79).each do |i|
- w[i] = SHA1_MASK & rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1)
+ w[i] = SHA1_MASK & rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1)
end
0.upto(79) do |i|
case i
@@ -50,7 +50,7 @@ module Bundler
words.map!.with_index {|word, index| SHA1_MASK & (word + mutated[index]) }
end
- words.pack("N*").unpack1("H*")
+ words.pack("N*").unpack("H*").first
end
private
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 6af80fb31f..03c80a408c 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -18,10 +18,9 @@ module Bundler
VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
platform platforms type source install_if gemfile force_ruby_platform].freeze
- GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}
- GITLAB_MERGE_REQUEST_URL = %r{\Ahttps://gitlab\.com/([A-Za-z0-9_\-\./]+)/-/merge_requests/(\d+)\z}
+ GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze
- attr_reader :gemspecs, :gemfile
+ attr_reader :gemspecs
attr_accessor :dependencies
def initialize
@@ -47,7 +46,7 @@ module Bundler
@gemfile = expanded_gemfile_path
@gemfiles << expanded_gemfile_path
contents ||= Bundler.read_file(@gemfile.to_s)
- instance_eval(contents, @gemfile.to_s, 1)
+ instance_eval(contents.dup.tap {|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1)
rescue Exception => e # rubocop:disable Lint/RescueException
message = "There was an error " \
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
@@ -77,11 +76,11 @@ module Bundler
@gemspecs << spec
- gem spec.name, name: spec.name, path: path, glob: glob
+ gem spec.name, :name => spec.name, :path => path, :glob => glob
group(development_group) do
spec.development_dependencies.each do |dep|
- gem dep.name, *(dep.requirement.as_list + [type: :development])
+ gem dep.name, *(dep.requirement.as_list + [:type => :development])
end
end
when 0
@@ -103,51 +102,39 @@ module Bundler
# if there's already a dependency with this name we try to prefer one
if current = @dependencies.find {|d| d.name == dep.name }
- if current.requirement != dep.requirement
- current_requirement_open = current.requirements_list.include?(">= 0")
+ deleted_dep = @dependencies.delete(current) if current.type == :development
- gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
- if gemspec_dep
- gemfile_dep = [dep, current].find(&:runtime?)
+ unless deleted_dep
+ if current.requirement != dep.requirement
+ return if dep.type == :development
- unless current_requirement_open
- Bundler.ui.warn "A gemspec development dependency (#{gemspec_dep.name}, #{gemspec_dep.requirement}) is being overridden by a Gemfile dependency (#{gemfile_dep.name}, #{gemfile_dep.requirement}).\n" \
- "This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement\n"
- end
- else
update_prompt = ""
if File.basename(@gemfile) == Injector::INJECTED_GEMS
- if dep.requirements_list.include?(">= 0") && !current_requirement_open
+ if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
update_prompt = ". Gem already added"
else
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
- update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
+ update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
end
end
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
- "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
- "#{update_prompt}"
+ "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
+ "#{update_prompt}"
+ elsif current.source != dep.source
+ return if dep.type == :development
+ raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
+ "You specified that #{dep.name} (#{dep.requirement}) should come from " \
+ "#{current.source || "an unspecified source"} and #{dep.source}\n"
+ else
+ Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
+ "You should probably keep only one of them.\n" \
+ "Remove any duplicate entries and specify the gem only once.\n" \
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
end
end
-
- # Always prefer the dependency from the Gemfile
- if current.gemspec_dev_dep?
- @dependencies.delete(current)
- elsif dep.gemspec_dev_dep?
- return
- elsif current.source != dep.source
- raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
- "You specified that #{dep.name} (#{dep.requirement}) should come from " \
- "#{current.source || "an unspecified source"} and #{dep.source}\n"
- else
- Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
- "You should probably keep only one of them.\n" \
- "Remove any duplicate entries and specify the gem only once.\n" \
- "While it's not a problem now, it could cause errors if you change the version of one of them later."
- end
end
@dependencies << dep
@@ -309,20 +296,6 @@ module Bundler
repo_name ||= user_name
"https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
end
-
- git_source(:gitlab) do |repo_name|
- if repo_name =~ GITLAB_MERGE_REQUEST_URL
- {
- "git" => "https://gitlab.com/#{$1}.git",
- "branch" => nil,
- "ref" => "refs/merge-requests/#{$2}/head",
- "tag" => nil,
- }
- else
- repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
- "https://gitlab.com/#{repo_name}.git"
- end
- end
end
def with_source(source)
@@ -424,11 +397,13 @@ module Bundler
end
def validate_keys(command, opts, valid_keys)
- if opts["branch"] && !(opts["git"] || opts["github"] || (opts.keys & @git_sources.keys.map(&:to_s)).any?)
+ invalid_keys = opts.keys - valid_keys
+
+ git_source = opts.keys & @git_sources.keys.map(&:to_s)
+ if opts["branch"] && !(opts["git"] || opts["github"] || git_source.any?)
raise GemfileError, %(The `branch` option for `#{command}` is not allowed. Only gems with a git source can specify a branch)
end
- invalid_keys = opts.keys - valid_keys
return true unless invalid_keys.any?
message = String.new
@@ -447,13 +422,9 @@ module Bundler
def normalize_source(source)
case source
when :gemcutter, :rubygems, :rubyforge
- message =
- "The source :#{source} is deprecated because HTTP requests are insecure.\n" \
- "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
- removed_message =
- "The source :#{source} is disallowed because HTTP requests are insecure.\n" \
- "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
+ Bundler::SharedHelpers.major_deprecation 2, "The source :#{source} is deprecated because HTTP " \
+ "requests are insecure.\nPlease change your source to 'https://" \
+ "rubygems.org' if possible, or 'http://rubygems.org' if not."
"http://rubygems.org"
when String
source
@@ -498,17 +469,10 @@ module Bundler
"should come from that source"
raise GemfileEvalError, msg
else
- message =
- "Your Gemfile contains multiple global sources. " \
+ Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple global sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source."
- removed_message =
- "Your Gemfile contains multiple global sources. " \
- "Using `source` more than once without a block is a security risk, and " \
- "may result in installing unexpected gems. To resolve this error, use " \
- "a block to indicate which gems should come from the secondary source."
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
end
end
diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb
index 87cb352efa..863544b1f9 100644
--- a/lib/bundler/endpoint_specification.rb
+++ b/lib/bundler/endpoint_specification.rb
@@ -94,7 +94,7 @@ module Bundler
def _local_specification
return unless @loaded_from && File.exist?(local_specification_path)
- eval(File.read(local_specification_path), nil, local_specification_path).tap do |spec|
+ eval(File.read(local_specification_path)).tap do |spec|
spec.loaded_from = @loaded_from
end
end
@@ -125,11 +125,7 @@ module Bundler
next unless v
case k.to_s
when "checksum"
- begin
- @checksum = Checksum.from_api(v.last, @spec_fetcher.uri)
- rescue ArgumentError => e
- raise ArgumentError, "Invalid checksum for #{full_name}: #{e.message}"
- end
+ @checksum = v.last
when "rubygems"
@required_rubygems_version = Gem::Requirement.new(v)
when "ruby"
diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb
index f6cb198e38..7b1152930e 100644
--- a/lib/bundler/env.rb
+++ b/lib/bundler/env.rb
@@ -40,11 +40,11 @@ module Bundler
out << "\n## Gemfile\n"
gemfiles.each do |gemfile|
- out << "\n### #{SharedHelpers.relative_path_to(gemfile)}\n\n"
+ out << "\n### #{Pathname.new(gemfile).relative_path_from(SharedHelpers.pwd)}\n\n"
out << "```ruby\n" << read_file(gemfile).chomp << "\n```\n"
end
- out << "\n### #{SharedHelpers.relative_path_to(Bundler.default_lockfile)}\n\n"
+ out << "\n### #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n"
out << "```\n" << read_file(Bundler.default_lockfile).chomp << "\n```\n"
end
@@ -69,7 +69,9 @@ module Bundler
end
def self.ruby_version
- "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{Gem::Platform.local}]"
+ str = String.new(RUBY_VERSION)
+ str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
+ str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{Gem::Platform.local}]"
end
def self.git_version
diff --git a/lib/bundler/environment_preserver.rb b/lib/bundler/environment_preserver.rb
index 444ab6fd37..57013f5d50 100644
--- a/lib/bundler/environment_preserver.rb
+++ b/lib/bundler/environment_preserver.rb
@@ -19,7 +19,14 @@ module Bundler
BUNDLER_PREFIX = "BUNDLER_ORIG_"
def self.from_env
- new(ENV.to_hash, BUNDLER_KEYS)
+ new(env_to_hash(ENV), BUNDLER_KEYS)
+ end
+
+ def self.env_to_hash(env)
+ to_hash = env.to_hash
+ return to_hash unless Gem.win_platform?
+
+ to_hash.each_with_object({}) {|(k,v), a| a[k.upcase] = v }
end
# @param env [Hash]
@@ -32,7 +39,18 @@ module Bundler
# Replaces `ENV` with the bundler environment variables backed up
def replace_with_backup
- ENV.replace(backup)
+ unless Gem.win_platform?
+ ENV.replace(backup)
+ 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
+
+ backup.each {|k, v| ENV[k] = v }
end
# @return [Hash]
@@ -40,9 +58,9 @@ module Bundler
env = @original.clone
@keys.each do |key|
value = env[key]
- if !value.nil?
+ if !value.nil? && !value.empty?
env[@prefix + key] ||= value
- else
+ elsif value.nil?
env[@prefix + key] ||= INTENTIONALLY_NIL
end
end
@@ -54,7 +72,7 @@ module Bundler
env = @original.clone
@keys.each do |key|
value_original = env[@prefix + key]
- next if value_original.nil?
+ next if value_original.nil? || value_original.empty?
if value_original == INTENTIONALLY_NIL
env.delete(key)
else
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
index c29b1bfed8..5839fc6a73 100644
--- a/lib/bundler/errors.rb
+++ b/lib/bundler/errors.rb
@@ -52,49 +52,6 @@ module Bundler
class GemfileEvalError < GemfileError; end
class MarshalError < StandardError; end
- class ChecksumMismatchError < SecurityError
- def initialize(lock_name, existing, checksum)
- @lock_name = lock_name
- @existing = existing
- @checksum = checksum
- end
-
- def message
- <<~MESSAGE
- Bundler found mismatched checksums. This is a potential security risk.
- #{@lock_name} #{@existing.to_lock}
- from #{@existing.sources.join("\n and ")}
- #{@lock_name} #{@checksum.to_lock}
- from #{@checksum.sources.join("\n and ")}
-
- #{mismatch_resolution_instructions}
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- MESSAGE
- end
-
- def mismatch_resolution_instructions
- removable, remote = [@existing, @checksum].partition(&:removable?)
- case removable.size
- when 0
- msg = +"Mismatched checksums each have an authoritative source:\n"
- msg << " 1. #{@existing.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
- msg << " 2. #{@checksum.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
- msg << "You may need to alter your Gemfile sources to resolve this issue.\n"
- when 1
- msg = +"If you trust #{remote.first.sources.first}, to resolve this issue you can:\n"
- msg << removable.first.removal_instructions
- when 2
- msg = +"To resolve this issue you can either:\n"
- msg << @checksum.removal_instructions
- msg << "or if you are sure that the new checksum from #{@checksum.sources.first} is correct:\n"
- msg << @existing.removal_instructions
- end
- end
-
- status_code(37)
- end
-
class PermissionError < BundlerError
def initialize(path, permission_type = :write)
@path = path
@@ -215,33 +172,4 @@ module Bundler
status_code(36)
end
-
- class InsecureInstallPathError < BundlerError
- def initialize(path)
- @path = path
- end
-
- def message
- "The installation path is insecure. Bundler cannot continue.\n" \
- "#{@path} is world-writable (without sticky bit).\n" \
- "Bundler cannot safely replace gems in world-writeable directories due to potential vulnerabilities.\n" \
- "Please change the permissions of this directory or choose a different install path."
- end
-
- status_code(38)
- end
-
- class CorruptBundlerInstallError < BundlerError
- def initialize(loaded_spec)
- @loaded_spec = loaded_spec
- end
-
- def message
- "The running version of Bundler (#{Bundler::VERSION}) does not match the version of the specification installed for it (#{@loaded_spec.version}). " \
- "This can be caused by reinstalling Ruby without removing previous installation, leaving around an upgraded default version of Bundler. " \
- "Reinstalling Ruby from scratch should fix the problem."
- end
-
- status_code(39)
- end
end
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb
index 6288b22dcd..2119799f68 100644
--- a/lib/bundler/fetcher.rb
+++ b/lib/bundler/fetcher.rb
@@ -1,15 +1,14 @@
# frozen_string_literal: true
require_relative "vendored_persistent"
-require_relative "vendored_timeout"
require "cgi"
require "securerandom"
require "zlib"
+require "rubygems/request"
module Bundler
# Handles all the fetching with the rubygems server
class Fetcher
- autoload :Base, File.expand_path("fetcher/base", __dir__)
autoload :CompactIndex, File.expand_path("fetcher/compact_index", __dir__)
autoload :Downloader, File.expand_path("fetcher/downloader", __dir__)
autoload :Dependency, File.expand_path("fetcher/dependency", __dir__)
@@ -81,9 +80,9 @@ module Bundler
:HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity,
:HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
FAIL_ERRORS = begin
- fail_errors = [AuthenticationRequiredError, BadAuthenticationError, AuthenticationForbiddenError, FallbackError, SecurityError]
+ fail_errors = [AuthenticationRequiredError, BadAuthenticationError, AuthenticationForbiddenError, FallbackError]
fail_errors << Gem::Requirement::BadRequirementError
- fail_errors.concat(NET_ERRORS.map {|e| Gem::Net.const_get(e) })
+ fail_errors.concat(NET_ERRORS.map {|e| Net.const_get(e) })
end.freeze
class << self
@@ -95,7 +94,6 @@ module Bundler
self.max_retries = Bundler.settings[:retry] # How many retries for the API call
def initialize(remote)
- @cis = nil
@remote = remote
Socket.do_not_reverse_lookup = true
@@ -111,17 +109,15 @@ module Bundler
spec -= [nil, "ruby", ""]
spec_file_name = "#{spec.join "-"}.gemspec"
- uri = Gem::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
- spec = if uri.scheme == "file"
- path = Gem::Util.correct_for_windows_path(uri.path)
+ uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
+ if uri.scheme == "file"
+ path = Bundler.rubygems.correct_for_windows_path(uri.path)
Bundler.safe_load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
Bundler.load_gemspec(cached_spec_path)
else
Bundler.safe_load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
end
- raise MarshalError, "is #{spec.inspect}" unless spec.is_a?(Gem::Specification)
- spec
rescue MarshalError
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
"Your network or your gem server is probably having issues right now."
@@ -138,11 +134,20 @@ module Bundler
def specs(gem_names, source)
index = Bundler::Index.new
- fetch_specs(gem_names).each do |name, version, platform, dependencies, metadata|
+ if Bundler::Fetcher.disable_endpoint
+ @use_api = false
+ specs = fetchers.last.specs(gem_names)
+ else
+ specs = []
+ @fetchers = fetchers.drop_while do |f|
+ !f.available? || (f.api_fetcher? && !gem_names) || !specs = f.specs(gem_names)
+ end
+ @use_api = false if fetchers.none?(&:api_fetcher?)
+ end
+
+ specs.each do |name, version, platform, dependencies, metadata|
spec = if dependencies
- EndpointSpecification.new(name, version, platform, self, dependencies, metadata).tap do |es|
- source.checksum_store.replace(es, es.checksum)
- end
+ EndpointSpecification.new(name, version, platform, self, dependencies, metadata)
else
RemoteSpecification.new(name, version, platform, self)
end
@@ -153,10 +158,22 @@ module Bundler
index
rescue CertificateFailureError
- Bundler.ui.info "" if gem_names && api_fetcher? # newline after dots
+ Bundler.ui.info "" if gem_names && use_api # newline after dots
raise
end
+ def use_api
+ return @use_api if defined?(@use_api)
+
+ fetchers.shift until fetchers.first.available?
+
+ @use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
+ false
+ else
+ fetchers.first.api_fetcher?
+ end
+ end
+
def user_agent
@user_agent ||= begin
ruby = Bundler::RubyVersion.system
@@ -192,6 +209,10 @@ module Bundler
end
end
+ def fetchers
+ @fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) }
+ end
+
def http_proxy
return unless uri = connection.proxy_uri
uri.to_s
@@ -201,49 +222,25 @@ module Bundler
"#<#{self.class}:0x#{object_id} uri=#{uri}>"
end
- def api_fetcher?
- fetchers.first.api_fetcher?
- end
-
- def gem_remote_fetcher
- @gem_remote_fetcher ||= begin
- require_relative "fetcher/gem_remote_fetcher"
- fetcher = GemRemoteFetcher.new Gem.configuration[:http_proxy]
- fetcher.headers["User-Agent"] = user_agent
- fetcher.headers["X-Gemfile-Source"] = @remote.original_uri.to_s if @remote.original_uri
- fetcher
- end
- end
-
private
- def available_fetchers
- if Bundler::Fetcher.disable_endpoint
- [Index]
- elsif remote_uri.scheme == "file"
- Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
- [Index]
- else
- [CompactIndex, Dependency, Index]
- end
- end
-
- def fetchers
- @fetchers ||= available_fetchers.map {|f| f.new(downloader, @remote, uri, gem_remote_fetcher) }.drop_while {|f| !f.available? }
- end
-
- def fetch_specs(gem_names)
- fetchers.reject!(&:api_fetcher?) unless gem_names
- fetchers.reject! do |f|
- specs = f.specs(gem_names)
- return specs if specs
- true
- end
- []
- end
+ FETCHERS = [CompactIndex, Dependency, Index].freeze
def cis
- @cis ||= Bundler::CIDetector.ci_strings
+ env_cis = {
+ "TRAVIS" => "travis",
+ "CIRCLECI" => "circle",
+ "SEMAPHORE" => "semaphore",
+ "JENKINS_URL" => "jenkins",
+ "BUILDBOX" => "buildbox",
+ "GO_SERVER_URL" => "go",
+ "SNAP_CI" => "snap",
+ "GITLAB_CI" => "gitlab",
+ "GITHUB_ACTIONS" => "github",
+ "CI_NAME" => ENV["CI_NAME"],
+ "CI" => "ci",
+ }
+ env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
end
def connection
@@ -253,9 +250,9 @@ module Bundler
Bundler.settings[:ssl_client_cert]
raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
- con = Gem::Net::HTTP::Persistent.new name: "bundler", proxy: :ENV
+ con = PersistentHTTP.new :name => "bundler", :proxy => :ENV
if gem_proxy = Gem.configuration[:http_proxy]
- con.proxy = Gem::URI.parse(gem_proxy) if gem_proxy != :no_proxy
+ con.proxy = Bundler::URI.parse(gem_proxy) if gem_proxy != :no_proxy
end
if remote_uri.scheme == "https"
@@ -288,10 +285,10 @@ module Bundler
end
HTTP_ERRORS = [
- Gem::Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
+ Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
- Gem::Net::HTTPBadResponse, Gem::Net::HTTPHeaderSyntaxError, Gem::Net::ProtocolError,
- Gem::Net::HTTP::Persistent::Error, Zlib::BufError, Errno::EHOSTUNREACH
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
+ PersistentHTTP::Error, Zlib::BufError, Errno::EHOSTUNREACH
].freeze
def bundler_cert_store
@@ -307,7 +304,6 @@ module Bundler
end
else
store.set_default_paths
- require "rubygems/request"
Gem::Request.get_cert_files.each {|c| store.add_file c }
end
store
diff --git a/lib/bundler/fetcher/base.rb b/lib/bundler/fetcher/base.rb
index cfec2f8e94..62cc75add8 100644
--- a/lib/bundler/fetcher/base.rb
+++ b/lib/bundler/fetcher/base.rb
@@ -6,14 +6,12 @@ module Bundler
attr_reader :downloader
attr_reader :display_uri
attr_reader :remote
- attr_reader :gem_remote_fetcher
- def initialize(downloader, remote, display_uri, gem_remote_fetcher)
+ def initialize(downloader, remote, display_uri)
raise "Abstract class" if self.class == Base
@downloader = downloader
@remote = remote
@display_uri = display_uri
- @gem_remote_fetcher = gem_remote_fetcher
end
def remote_uri
@@ -40,9 +38,9 @@ module Bundler
private
- def log_specs(&block)
+ def log_specs(debug_msg)
if Bundler.ui.debug?
- Bundler.ui.debug yield
+ Bundler.ui.debug debug_msg
else
Bundler.ui.info ".", false
end
diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb
index db914839b1..8d30dec471 100644
--- a/lib/bundler/fetcher/compact_index.rb
+++ b/lib/bundler/fetcher/compact_index.rb
@@ -13,7 +13,7 @@ module Bundler
undef_method(method_name)
define_method(method_name) do |*args, &blk|
method.bind(self).call(*args, &blk)
- rescue NetworkDownError, CompactIndexClient::Updater::MismatchedChecksumError => e
+ rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
raise HTTPError, e.message
rescue AuthenticationRequiredError, BadAuthenticationError
# Fail since we got a 401 from the server.
@@ -35,7 +35,7 @@ module Bundler
remaining_gems = gem_names.dup
until remaining_gems.empty?
- log_specs { "Looking up gems #{remaining_gems.inspect}" }
+ log_specs "Looking up gems #{remaining_gems.inspect}"
deps = begin
parallel_compact_index_client.dependencies(remaining_gems)
@@ -44,7 +44,7 @@ module Bundler
@bundle_worker = nil # reset it. Not sure if necessary
serial_compact_index_client.dependencies(remaining_gems)
end
- next_gems = deps.flat_map {|d| d[3].flat_map(&:first) }.uniq
+ next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
deps.each {|dep| gem_info << dep }
complete_gems.concat(deps.map(&:first)).uniq!
remaining_gems = next_gems - complete_gems
@@ -60,9 +60,13 @@ module Bundler
Bundler.ui.debug("FIPS mode is enabled, bundler can't use the CompactIndex API")
return nil
end
+ if fetch_uri.scheme == "file"
+ Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
+ return false
+ end
# Read info file checksums out of /versions, so we can know if gems are up to date
compact_index_client.update_and_parse_checksums!
- rescue CompactIndexClient::Updater::MismatchedChecksumError => e
+ rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
Bundler.ui.debug(e.message)
nil
end
@@ -121,7 +125,7 @@ module Bundler
rescue NetworkDownError => e
raise unless Bundler.feature_flag.allow_offline_install? && headers["If-None-Match"]
ui.warn "Using the cached data for the new index because of a network error: #{e}"
- Gem::Net::HTTPNotModified.new(nil, nil, nil)
+ Net::HTTPNotModified.new(nil, nil, nil)
end
end
end
diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb
index 0b807c9a4b..18b606abb6 100644
--- a/lib/bundler/fetcher/dependency.rb
+++ b/lib/bundler/fetcher/dependency.rb
@@ -24,7 +24,7 @@ module Bundler
def specs(gem_names, full_dependency_list = [], last_spec_list = [])
query_list = gem_names.uniq - full_dependency_list
- log_specs { "Query List: #{query_list.inspect}" }
+ log_specs "Query List: #{query_list.inspect}"
return last_spec_list if query_list.empty?
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
index 868b39b959..3062899e0e 100644
--- a/lib/bundler/fetcher/downloader.rb
+++ b/lib/bundler/fetcher/downloader.rb
@@ -20,35 +20,33 @@ module Bundler
Bundler.ui.debug("HTTP #{response.code} #{response.message} #{filtered_uri}")
case response
- when Gem::Net::HTTPSuccess, Gem::Net::HTTPNotModified
+ when Net::HTTPSuccess, Net::HTTPNotModified
response
- when Gem::Net::HTTPRedirection
- new_uri = Gem::URI.parse(response["location"])
+ when Net::HTTPRedirection
+ new_uri = Bundler::URI.parse(response["location"])
if new_uri.host == uri.host
new_uri.user = uri.user
new_uri.password = uri.password
end
fetch(new_uri, headers, counter + 1)
- when Gem::Net::HTTPRequestedRangeNotSatisfiable
+ when Net::HTTPRequestedRangeNotSatisfiable
new_headers = headers.dup
new_headers.delete("Range")
new_headers["Accept-Encoding"] = "gzip"
fetch(uri, new_headers)
- when Gem::Net::HTTPRequestEntityTooLarge
+ when Net::HTTPRequestEntityTooLarge
raise FallbackError, response.body
- when Gem::Net::HTTPTooManyRequests
+ when Net::HTTPTooManyRequests
raise TooManyRequestsError, response.body
- when Gem::Net::HTTPUnauthorized
+ when Net::HTTPUnauthorized
raise BadAuthenticationError, uri.host if uri.userinfo
raise AuthenticationRequiredError, uri.host
- when Gem::Net::HTTPForbidden
+ when Net::HTTPForbidden
raise AuthenticationForbiddenError, uri.host
- when Gem::Net::HTTPNotFound
- raise FallbackError, "Gem::Net::HTTPNotFound: #{filtered_uri}"
+ when Net::HTTPNotFound
+ raise FallbackError, "Net::HTTPNotFound: #{filtered_uri}"
else
- message = "Gem::#{response.class.name.gsub(/\AGem::/, "")}"
- message += ": #{response.body}" unless response.body.empty?
- raise HTTPError, message
+ raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
end
end
@@ -58,7 +56,7 @@ module Bundler
filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
Bundler.ui.debug "HTTP GET #{filtered_uri}"
- req = Gem::Net::HTTP::Get.new uri.request_uri, headers
+ req = Net::HTTP::Get.new uri.request_uri, headers
if uri.user
user = CGI.unescape(uri.user)
password = uri.password ? CGI.unescape(uri.password) : nil
diff --git a/lib/bundler/fetcher/gem_remote_fetcher.rb b/lib/bundler/fetcher/gem_remote_fetcher.rb
deleted file mode 100644
index 3fc7b68263..0000000000
--- a/lib/bundler/fetcher/gem_remote_fetcher.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require "rubygems/remote_fetcher"
-
-module Bundler
- class Fetcher
- class GemRemoteFetcher < Gem::RemoteFetcher
- def request(*args)
- super do |req|
- req.delete("User-Agent") if headers["User-Agent"]
- yield req if block_given?
- end
- end
- end
- end
-end
diff --git a/lib/bundler/fetcher/index.rb b/lib/bundler/fetcher/index.rb
index 6e37e1e5d1..c623647f01 100644
--- a/lib/bundler/fetcher/index.rb
+++ b/lib/bundler/fetcher/index.rb
@@ -6,7 +6,7 @@ module Bundler
class Fetcher
class Index < Base
def specs(_gem_names)
- Bundler.rubygems.fetch_all_remote_specs(remote, gem_remote_fetcher)
+ Bundler.rubygems.fetch_all_remote_specs(remote)
rescue Gem::RemoteFetcher::FetchError => e
case e.message
when /certificate verify failed/
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index e61ed64450..39afe8a071 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -32,7 +32,7 @@ module Bundler
if Bundler.ui.debug?
Bundler.ui.trace error
else
- Bundler.ui.error error.message, wrap: true
+ Bundler.ui.error error.message, :wrap => true
end
when Thor::Error
Bundler.ui.error error.message
@@ -40,7 +40,7 @@ module Bundler
Bundler.ui.error "\nQuitting..."
Bundler.ui.trace error
when Gem::InvalidSpecificationException
- Bundler.ui.error error.message, wrap: true
+ Bundler.ui.error error.message, :wrap => true
when SystemExit
when *[defined?(Java::JavaLang::OutOfMemoryError) && Java::JavaLang::OutOfMemoryError].compact
Bundler.ui.error "\nYour JVM has run out of memory, and Bundler cannot continue. " \
@@ -61,7 +61,7 @@ module Bundler
end
def request_issue_report_for(e)
- Bundler.ui.error <<~EOS, nil, nil
+ Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, nil
--- ERROR REPORT TEMPLATE -------------------------------------------------------
```
@@ -75,7 +75,7 @@ module Bundler
Bundler.ui.error "Unfortunately, an unexpected error occurred, and Bundler cannot continue."
- Bundler.ui.error <<~EOS, nil, :yellow
+ Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, :yellow
First, try this link to see if there are any existing issue reports for this error:
#{issues_url(e)}
@@ -93,7 +93,7 @@ module Bundler
end
def serialized_exception_for(e)
- <<~EOS
+ <<-EOS.gsub(/^ {8}/, "")
#{e.class}: #{e.message}
#{e.backtrace&.join("\n ")&.chomp}
EOS
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb
index 5ce0ef6280..dcf759cded 100644
--- a/lib/bundler/gem_helper.rb
+++ b/lib/bundler/gem_helper.rb
@@ -47,7 +47,7 @@ module Bundler
built_gem_path = build_gem
end
- desc "Generate SHA512 checksum of #{name}-#{version}.gem into the checksums directory."
+ desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."
task "build:checksum" => "build" do
build_checksum(built_gem_path)
end
@@ -215,7 +215,7 @@ module Bundler
def sh_with_status(cmd, &block)
Bundler.ui.debug(cmd)
SharedHelpers.chdir(base) do
- outbuf = IO.popen(cmd, err: [:child, :out], &:read)
+ outbuf = IO.popen(cmd, :err => [:child, :out], &:read)
status = $?
block&.call(outbuf) if status.success?
[outbuf, status]
diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb
index de007523ec..2e6d788f9c 100644
--- a/lib/bundler/gem_helpers.rb
+++ b/lib/bundler/gem_helpers.rb
@@ -34,11 +34,6 @@ module Bundler
end
module_function :local_platform
- def generic_local_platform_is_ruby?
- generic_local_platform == Gem::Platform::RUBY
- end
- module_function :generic_local_platform_is_ruby?
-
def platform_specificity_match(spec_platform, user_platform)
spec_platform = Gem::Platform.new(spec_platform)
@@ -53,13 +48,6 @@ module Bundler
end
module_function :select_best_platform_match
- def force_ruby_platform(specs)
- matching = specs.select {|spec| spec.match_platform(Gem::Platform::RUBY) && spec.force_ruby_platform! }
-
- sort_best_platform_match(matching, Gem::Platform::RUBY)
- end
- module_function :force_ruby_platform
-
def sort_best_platform_match(matching, platform)
exact = matching.select {|spec| spec.platform == platform }
return exact if exact.any?
@@ -119,6 +107,8 @@ module Bundler
def same_deps(spec, exemplary_spec)
same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort
+ return same_runtime_deps unless spec.is_a?(Gem::Specification) && exemplary_spec.is_a?(Gem::Specification)
+
same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version
same_runtime_deps && same_metadata_deps
end
diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb
index ecc65b4956..d281f46eeb 100644
--- a/lib/bundler/gem_version_promoter.rb
+++ b/lib/bundler/gem_version_promoter.rb
@@ -45,37 +45,17 @@ module Bundler
# Given a Resolver::Package and an Array of Specifications of available
# versions for a gem, this method will return the Array of Specifications
- # sorted in an order to give preference to the current level (:major, :minor
- # or :patch) when resolution is deciding what versions best resolve all
- # dependencies in the bundle.
+ # sorted (and possibly truncated if strict is true) in an order to give
+ # preference to the current level (:major, :minor or :patch) when resolution
+ # is deciding what versions best resolve all dependencies in the bundle.
# @param package [Resolver::Package] The package being resolved.
# @param specs [Specification] An array of Specifications for the package.
- # @return [Specification] A new instance of the Specification Array sorted.
+ # @return [Specification] A new instance of the Specification Array sorted and
+ # possibly filtered.
def sort_versions(package, specs)
- locked_version = package.locked_version
-
- result = specs.sort do |a, b|
- unless package.prerelease_specified? || pre?
- a_pre = a.prerelease?
- b_pre = b.prerelease?
+ specs = filter_dep_specs(specs, package) if strict
- next 1 if a_pre && !b_pre
- next -1 if b_pre && !a_pre
- end
-
- if major? || locked_version.nil?
- b <=> a
- elsif either_version_older_than_locked?(a, b, locked_version)
- b <=> a
- elsif segments_do_not_match?(a, b, :major)
- a <=> b
- elsif !minor? && segments_do_not_match?(a, b, :minor)
- a <=> b
- else
- b <=> a
- end
- end
- post_sort(result, package.unlock?, locked_version)
+ sort_dep_specs(specs, package)
end
# @return [bool] Convenience method for testing value of level variable.
@@ -93,18 +73,9 @@ module Bundler
pre == true
end
- # Given a Resolver::Package and an Array of Specifications of available
- # versions for a gem, this method will truncate the Array if strict
- # is true. That means filtering out downgrades from the version currently
- # locked, and filtering out upgrades that go past the selected level (major,
- # minor, or patch).
- # @param package [Resolver::Package] The package being resolved.
- # @param specs [Specification] An array of Specifications for the package.
- # @return [Specification] A new instance of the Specification Array
- # truncated.
- def filter_versions(package, specs)
- return specs unless strict
+ private
+ def filter_dep_specs(specs, package)
locked_version = package.locked_version
return specs if locked_version.nil? || major?
@@ -118,10 +89,35 @@ module Bundler
end
end
- private
+ def sort_dep_specs(specs, package)
+ locked_version = package.locked_version
+
+ result = specs.sort do |a, b|
+ unless package.prerelease_specified? || pre?
+ a_pre = a.prerelease?
+ b_pre = b.prerelease?
+
+ next -1 if a_pre && !b_pre
+ next 1 if b_pre && !a_pre
+ end
+
+ if major?
+ a <=> b
+ elsif either_version_older_than_locked?(a, b, locked_version)
+ a <=> b
+ elsif segments_do_not_match?(a, b, :major)
+ b <=> a
+ elsif !minor? && segments_do_not_match?(a, b, :minor)
+ b <=> a
+ else
+ a <=> b
+ end
+ end
+ post_sort(result, package.unlock?, locked_version)
+ end
def either_version_older_than_locked?(a, b, locked_version)
- a.version < locked_version || b.version < locked_version
+ locked_version && (a.version < locked_version || b.version < locked_version)
end
def segments_do_not_match?(a, b, level)
@@ -137,13 +133,13 @@ module Bundler
if unlock || locked_version.nil?
result
else
- move_version_to_beginning(result, locked_version)
+ move_version_to_end(result, locked_version)
end
end
- def move_version_to_beginning(result, version)
+ def move_version_to_end(result, version)
move, keep = result.partition {|s| s.version.to_s == version.to_s }
- move.concat(keep)
+ keep.concat(move)
end
end
end
diff --git a/lib/bundler/graph.rb b/lib/bundler/graph.rb
index b22b17a453..3c008e63e3 100644
--- a/lib/bundler/graph.rb
+++ b/lib/bundler/graph.rb
@@ -84,7 +84,7 @@ module Bundler
else
raise ArgumentError, "2nd argument is invalid"
end
- label.nil? ? {} : { label: label }
+ label.nil? ? {} : { :label => label }
end
def spec_for_dependency(dependency)
@@ -103,7 +103,7 @@ module Bundler
end
def g
- @g ||= ::GraphViz.digraph(@graph_name, concentrate: true, normalize: true, nodesep: 0.55) do |g|
+ @g ||= ::GraphViz.digraph(@graph_name, :concentrate => true, :normalize => true, :nodesep => 0.55) do |g|
g.edge[:weight] = 2
g.edge[:fontname] = g.node[:fontname] = "Arial, Helvetica, SansSerif"
g.edge[:fontsize] = 12
@@ -114,10 +114,10 @@ module Bundler
@groups.each do |group|
g.add_nodes(
group, {
- style: "filled",
- fillcolor: "#B9B9D5",
- shape: "box3d",
- fontsize: 16,
+ :style => "filled",
+ :fillcolor => "#B9B9D5",
+ :shape => "box3d",
+ :fontsize => 16,
}.merge(@node_options[group])
)
end
@@ -125,8 +125,8 @@ module Bundler
@relations.each do |parent, children|
children.each do |child|
if @groups.include?(parent)
- g.add_nodes(child, { style: "filled", fillcolor: "#B9B9D5" }.merge(@node_options[child]))
- g.add_edges(parent, child, { constraint: false }.merge(@edge_options["#{parent}_#{child}"]))
+ g.add_nodes(child, { :style => "filled", :fillcolor => "#B9B9D5" }.merge(@node_options[child]))
+ g.add_edges(parent, child, { :constraint => false }.merge(@edge_options["#{parent}_#{child}"]))
else
g.add_nodes(child, @node_options[child])
g.add_edges(parent, child, @edge_options["#{parent}_#{child}"])
@@ -135,7 +135,7 @@ module Bundler
end
if @output_format.to_s == "debug"
- $stdout.puts g.output none: String
+ $stdout.puts g.output :none => String
Bundler.ui.info "debugging bundle viz..."
else
begin
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index df46facc88..b8c599f63a 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -10,8 +10,8 @@ module Bundler
i
end
- attr_reader :specs, :duplicates, :sources
- protected :specs, :duplicates
+ attr_reader :specs, :all_specs, :sources
+ protected :specs, :all_specs
RUBY = "ruby"
NULL = "\0"
@@ -19,21 +19,21 @@ module Bundler
def initialize
@sources = []
@cache = {}
- @specs = {}
- @duplicates = {}
+ @specs = Hash.new {|h, k| h[k] = {} }
+ @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH }
end
def initialize_copy(o)
@sources = o.sources.dup
@cache = {}
- @specs = {}
- @duplicates = {}
+ @specs = Hash.new {|h, k| h[k] = {} }
+ @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH }
o.specs.each do |name, hash|
@specs[name] = hash.dup
end
- o.duplicates.each do |name, array|
- @duplicates[name] = array.dup
+ o.all_specs.each do |name, array|
+ @all_specs[name] = array.dup
end
end
@@ -46,11 +46,12 @@ module Bundler
true
end
- def search_all(name, &blk)
- return enum_for(:search_all, name) unless blk
- specs_by_name(name).each(&blk)
- @duplicates[name]&.each(&blk)
- @sources.each {|source| source.search_all(name, &blk) }
+ def search_all(name)
+ all_matches = local_search(name) + @all_specs[name]
+ @sources.each do |source|
+ all_matches.concat(source.search_all(name))
+ end
+ all_matches
end
# Search this index's specs, and any source indexes that this index knows
@@ -60,14 +61,11 @@ module Bundler
return results unless @sources.any?
@sources.each do |source|
- results = safe_concat(results, source.search(query))
+ results.concat(source.search(query))
end
- results.uniq!(&:full_name) unless results.empty? # avoid modifying frozen EMPTY_SEARCH
- results
+ results.uniq(&:full_name)
end
- alias_method :[], :search
-
def local_search(query)
case query
when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query)
@@ -78,10 +76,12 @@ module Bundler
end
end
- def add(spec)
- (@specs[spec.name] ||= {}).store(spec.full_name, spec)
+ alias_method :[], :search
+
+ def <<(spec)
+ @specs[spec.name][spec.full_name] = spec
+ spec
end
- alias_method :<<, :add
def each(&blk)
return enum_for(:each) unless blk
@@ -115,25 +115,15 @@ module Bundler
names.uniq
end
- # Combines indexes proritizing existing specs, like `Hash#reverse_merge!`
- # Duplicate specs found in `other` are stored in `@duplicates`.
- def use(other)
+ def use(other, override_dupes = false)
return unless other
- other.each do |spec|
- exist?(spec) ? add_duplicate(spec) : add(spec)
- end
- self
- end
-
- # Combines indexes proritizing specs from `other`, like `Hash#merge!`
- # Duplicate specs found in `self` are saved in `@duplicates`.
- def merge!(other)
- return unless other
- other.each do |spec|
- if existing = find_by_spec(spec)
- add_duplicate(existing)
+ other.each do |s|
+ if (dupes = search_by_spec(s)) && !dupes.empty?
+ # safe to << since it's a new array when it has contents
+ @all_specs[s.name] = dupes << s
+ next unless override_dupes
end
- add spec
+ self << s
end
self
end
@@ -145,7 +135,8 @@ module Bundler
end
# Whether all the specs in self are in other
- def subset?(other)
+ # TODO: rename to #include?
+ def ==(other)
all? do |spec|
other_spec = other[spec].first
other_spec && dependencies_eql?(spec, other_spec) && spec.source == other_spec.source
@@ -166,40 +157,19 @@ module Bundler
private
- def safe_concat(a, b)
- return a if b.empty?
- return b if a.empty?
- a.concat(b)
- end
-
- def add_duplicate(spec)
- (@duplicates[spec.name] ||= []) << spec
- end
-
def specs_by_name_and_version(name, version)
- results = @specs[name]&.values
- return EMPTY_SEARCH unless results
- results.select! {|spec| spec.version == version }
- results
+ specs_by_name(name).select {|spec| spec.version == version }
end
def specs_by_name(name)
- @specs[name]&.values || EMPTY_SEARCH
+ @specs[name].values
end
EMPTY_SEARCH = [].freeze
def search_by_spec(spec)
- spec = find_by_spec(spec)
+ spec = @specs[spec.name][spec.full_name]
spec ? [spec] : EMPTY_SEARCH
end
-
- def find_by_spec(spec)
- @specs[spec.name]&.fetch(spec.full_name, nil)
- end
-
- def exist?(spec)
- @specs[spec.name]&.key?(spec.full_name)
- end
end
end
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index 879b481339..cb644a7f69 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -29,7 +29,7 @@ module Bundler
end
# temporarily unfreeze
- Bundler.settings.temporary(deployment: false, frozen: false) do
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
# evaluate the Gemfile we have now
builder = Dsl.new
builder.eval_gemfile(gemfile_path)
@@ -50,7 +50,7 @@ module Bundler
append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @deps.any?
# since we resolved successfully, write out the lockfile
- @definition.lock
+ @definition.lock(Bundler.default_lockfile)
# invalidate the cached Bundler.definition
Bundler.reset_paths!
@@ -86,7 +86,7 @@ module Bundler
segments = version.segments
seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
- prerelease_suffix = version.to_s.delete_prefix(version.release.to_s) if version.prerelease?
+ prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease?
"#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
end
@@ -120,10 +120,9 @@ module Bundler
github = ", :github => \"#{d.github}\"" unless d.github.nil?
branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil?
ref = ", :ref => \"#{d.ref}\"" unless d.ref.nil?
- glob = ", :glob => \"#{d.glob}\"" unless d.glob.nil?
require_path = ", :require => #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
- %(gem #{name}#{requirement}#{group}#{source}#{path}#{git}#{github}#{branch}#{ref}#{glob}#{require_path})
+ %(gem #{name}#{requirement}#{group}#{source}#{path}#{git}#{github}#{branch}#{ref}#{require_path})
end.join("\n")
end
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
index ae4ccf2138..5c184f67a1 100644
--- a/lib/bundler/inline.rb
+++ b/lib/bundler/inline.rb
@@ -48,14 +48,14 @@ def gemfile(install = false, options = {}, &gemfile)
builder.instance_eval(&gemfile)
builder.check_primary_source_safety
- Bundler.settings.temporary(deployment: false, frozen: false) do
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
definition = builder.to_definition(nil, true)
def definition.lock(*); end
definition.validate_runtime!
if install || definition.missing_specs?
- Bundler.settings.temporary(inline: true, no_install: false) do
- installer = Bundler::Installer.install(Bundler.root, definition, system: true)
+ Bundler.settings.temporary(:inline => true, :no_install => false) do
+ installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
installer.post_install_messages.each do |name, message|
Bundler.ui.info "Post-install message from #{name}:\n#{message}"
end
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index ef9a0a4e07..59b6a6ad22 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -136,12 +136,12 @@ module Bundler
mode = Gem.win_platform? ? "wb:UTF-8" : "w"
require "erb"
- content = ERB.new(template, trim_mode: "-").result(binding)
+ content = ERB.new(template, :trim_mode => "-").result(binding)
- File.write(binstub_path, content, mode: mode, perm: 0o777 & ~File.umask)
+ File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
if Gem.win_platform? || options[:all_platforms]
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
- File.write("#{binstub_path}.cmd", prefix + content, mode: mode)
+ File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
end
end
@@ -179,12 +179,12 @@ module Bundler
mode = Gem.win_platform? ? "wb:UTF-8" : "w"
require "erb"
- content = ERB.new(template, trim_mode: "-").result(binding)
+ content = ERB.new(template, :trim_mode => "-").result(binding)
- File.write("#{bin_path}/#{executable}", content, mode: mode, perm: 0o755)
+ File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
if Gem.win_platform? || options[:all_platforms]
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
- File.write("#{bin_path}/#{executable}.cmd", prefix + content, mode: mode)
+ File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
end
end
end
@@ -214,7 +214,7 @@ module Bundler
end
def load_plugins
- Gem.load_plugins
+ Bundler.rubygems.load_plugins
requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
path_plugin_files = requested_path_gems.map do |spec|
@@ -223,8 +223,8 @@ module Bundler
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
raise Gem::InvalidSpecificationException, error_message
end.flatten
- Gem.load_plugin_files(path_plugin_files)
- Gem.load_env_plugins
+ Bundler.rubygems.load_plugin_files(path_plugin_files)
+ Bundler.rubygems.load_env_plugins
end
def ensure_specs_are_compatible!
@@ -249,19 +249,19 @@ module Bundler
# returns whether or not a re-resolve was needed
def resolve_if_needed(options)
- @definition.prefer_local! if options["prefer-local"]
-
- if options["local"] || (@definition.no_resolve_needed? && !@definition.missing_specs?)
- @definition.resolve_with_cache!
- false
- else
- @definition.resolve_remotely!
- true
+ @definition.resolution_mode = options
+
+ if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
+ return false if @definition.nothing_changed? && !@definition.missing_specs?
end
+
+ @definition.setup_sources_for_resolve
+
+ true
end
- def lock
- @definition.lock
+ def lock(opts = {})
+ @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
end
end
end
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
index d3bbcc90f5..9a013eea4d 100644
--- a/lib/bundler/installer/gem_installer.rb
+++ b/lib/bundler/installer/gem_installer.rb
@@ -16,13 +16,13 @@ module Bundler
post_install_message = install
Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
generate_executable_stubs
- [true, post_install_message]
- rescue Bundler::InstallHookError, Bundler::SecurityError, Bundler::APIResponseMismatchError, Bundler::InsecureInstallPathError
+ return true, post_install_message
+ rescue Bundler::InstallHookError, Bundler::SecurityError, Bundler::APIResponseMismatchError
raise
rescue Errno::ENOSPC
- [false, out_of_space_message]
- rescue Bundler::BundlerError, Gem::InstallError => e
- [false, specific_failure_message(e)]
+ return false, out_of_space_message
+ rescue Bundler::BundlerError, Gem::InstallError, Bundler::APIResponseInvalidDependenciesError => e
+ return false, specific_failure_message(e)
end
private
@@ -53,10 +53,10 @@ module Bundler
def install
spec.source.install(
spec,
- force: force,
- ensure_builtin_gems_cached: standalone,
- build_args: Array(spec_settings),
- previous_spec: previous_spec,
+ :force => force,
+ :ensure_builtin_gems_cached => standalone,
+ :build_args => Array(spec_settings),
+ :previous_spec => previous_spec,
)
end
@@ -77,7 +77,7 @@ module Bundler
if Bundler.settings[:bin] && standalone
installer.generate_standalone_bundler_executable_stubs(spec)
elsif Bundler.settings[:bin]
- installer.generate_bundler_executable_stubs(spec, force: true)
+ installer.generate_bundler_executable_stubs(spec, :force => true)
end
end
end
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index e745088f81..83a381f592 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -42,7 +42,8 @@ module Bundler
# Checks installed dependencies against spec's dependencies to make
# sure needed dependencies have been installed.
- def dependencies_installed?(installed_specs)
+ def dependencies_installed?(all_specs)
+ installed_specs = all_specs.select(&:installed?).map(&:name)
dependencies.all? {|d| installed_specs.include? d.name }
end
@@ -62,23 +63,20 @@ module Bundler
end
end
- def self.call(*args, **kwargs)
- new(*args, **kwargs).call
+ def self.call(*args)
+ new(*args).call
end
attr_reader :size
- def initialize(installer, all_specs, size, standalone, force, skip: nil)
+ def initialize(installer, all_specs, size, standalone, force)
@installer = installer
@size = size
@standalone = standalone
@force = force
@specs = all_specs.map {|s| SpecInstallation.new(s) }
- @specs.each do |spec_install|
- spec_install.state = :installed if skip.include?(spec_install.name)
- end if skip
@spec_set = all_specs
- @rake = @specs.find {|s| s.name == "rake" unless s.installed? }
+ @rake = @specs.find {|s| s.name == "rake" }
end
def call
@@ -93,12 +91,38 @@ module Bundler
install_serially
end
+ check_for_unmet_dependencies
+
handle_error if failed_specs.any?
@specs
ensure
worker_pool&.stop
end
+ def check_for_unmet_dependencies
+ unmet_dependencies = @specs.map do |s|
+ [
+ s,
+ s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } },
+ ]
+ end.reject {|a| a.last.empty? }
+ return if unmet_dependencies.empty?
+
+ warning = []
+ warning << "Your lockfile doesn't include a valid resolution."
+ warning << "You can fix this by regenerating your lockfile or manually editing the bad locked gems to a version that satisfies all dependencies."
+ warning << "The unmet dependencies are:"
+
+ unmet_dependencies.each do |spec, unmet_spec_dependencies|
+ unmet_spec_dependencies.each do |unmet_spec_dependency|
+ found = @specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }
+ warning << "* #{unmet_spec_dependency}, dependency of #{spec.full_name}, unsatisfied by #{found.full_name}"
+ end
+ end
+
+ Bundler.ui.warn(warning.join("\n"))
+ end
+
private
def failed_specs
@@ -185,14 +209,8 @@ module Bundler
# previously installed specifications. We continue until all specs
# are installed.
def enqueue_specs
- installed_specs = {}
- @specs.each do |spec|
- next unless spec.installed?
- installed_specs[spec.name] = true
- end
-
- @specs.each do |spec|
- if spec.ready_to_enqueue? && spec.dependencies_installed?(installed_specs)
+ @specs.select(&:ready_to_enqueue?).each do |spec|
+ if spec.dependencies_installed? @specs
spec.state = :enqueued
worker_pool.enq spec
end
diff --git a/lib/bundler/installer/standalone.rb b/lib/bundler/installer/standalone.rb
index 5331df2e95..2a8c9a432d 100644
--- a/lib/bundler/installer/standalone.rb
+++ b/lib/bundler/installer/standalone.rb
@@ -12,7 +12,6 @@ module Bundler
end
File.open File.join(bundler_path, "setup.rb"), "w" do |file|
file.puts "require 'rbconfig'"
- file.puts prevent_gem_activation
file.puts define_path_helpers
file.puts reverse_rubygems_kernel_mixin
paths.each do |path|
@@ -56,26 +55,13 @@ module Bundler
if spec.source.instance_of?(Source::Path) && spec.source.path.absolute?
full_path
else
- SharedHelpers.relative_path_to(full_path, from: Bundler.root.join(bundler_path))
+ Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
end
rescue TypeError
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
raise Gem::InvalidSpecificationException.new(error_message)
end
- def prevent_gem_activation
- <<~'END'
- module Kernel
- remove_method(:gem) if private_method_defined?(:gem)
-
- def gem(*)
- end
-
- private :gem
- end
- END
- end
-
def define_path_helpers
<<~'END'
unless defined?(Gem)
@@ -101,7 +87,8 @@ module Bundler
if Gem.respond_to?(:discover_gems_on_require=)
Gem.discover_gems_on_require = false
else
- [::Kernel.singleton_class, ::Kernel].each do |k|
+ kernel = (class << ::Kernel; self; end)
+ [kernel, ::Kernel].each do |k|
if k.private_method_defined?(:gem_original_require)
private_require = k.private_method_defined?(:require)
k.send(:remove_method, :require)
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 38aea2a4aa..c9b161dc0e 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -7,25 +7,13 @@ module Bundler
include MatchPlatform
include ForcePlatform
- attr_reader :name, :version, :platform
- attr_accessor :source, :remote, :force_ruby_platform, :dependencies, :required_ruby_version, :required_rubygems_version
-
- alias_method :runtime_dependencies, :dependencies
-
- def self.from_spec(s)
- lazy_spec = new(s.name, s.version, s.platform, s.source)
- lazy_spec.dependencies = s.dependencies
- lazy_spec.required_ruby_version = s.required_ruby_version
- lazy_spec.required_rubygems_version = s.required_rubygems_version
- lazy_spec
- end
+ attr_reader :name, :version, :dependencies, :platform
+ attr_accessor :source, :remote, :force_ruby_platform
def initialize(name, version, platform, source = nil)
@name = name
@version = version
@dependencies = []
- @required_ruby_version = Gem::Requirement.default
- @required_rubygems_version = Gem::Requirement.default
@platform = platform || Gem::Platform::RUBY
@source = source
@force_ruby_platform = default_force_ruby_platform
@@ -39,14 +27,6 @@ module Bundler
end
end
- def lock_name
- @lock_name ||= name_tuple.lock_name
- end
-
- def name_tuple
- Gem::NameTuple.new(@name, @version, @platform)
- end
-
def ==(other)
full_name == other.full_name
end
@@ -81,7 +61,12 @@ module Bundler
def to_lock
out = String.new
- out << " #{lock_name}\n"
+
+ if platform == Gem::Platform::RUBY
+ out << " #{name} (#{version})\n"
+ else
+ out << " #{name} (#{version}-#{platform})\n"
+ end
dependencies.sort_by(&:to_s).uniq.each do |dep|
next if dep.type == :development
@@ -104,7 +89,7 @@ module Bundler
installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform)
- specification = __materialize__(installable_candidates, fallback_to_non_installable: false)
+ specification = __materialize__(installable_candidates, :fallback_to_non_installable => false)
return specification unless specification.nil?
if target_platform != platform
@@ -124,7 +109,9 @@ module Bundler
# bad gem.
def __materialize__(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
search = candidates.reverse.find do |spec|
- spec.is_a?(StubSpecification) || spec.matches_current_metadata?
+ spec.is_a?(StubSpecification) ||
+ (spec.matches_current_ruby? &&
+ spec.matches_current_rubygems?)
end
if search.nil? && fallback_to_non_installable
search = candidates.last
@@ -135,7 +122,11 @@ module Bundler
end
def to_s
- lock_name
+ @to_s ||= if platform == Gem::Platform::RUBY
+ "#{name} (#{version})"
+ else
+ "#{name} (#{version}-#{platform})"
+ end
end
def git_version
@@ -143,10 +134,6 @@ module Bundler
" #{source.revision[0..6]}"
end
- def force_ruby_platform!
- @force_ruby_platform = true
- end
-
private
def use_exact_resolved_specifications?
diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb
index a646d00ee1..f7ba51b3e6 100644
--- a/lib/bundler/lockfile_generator.rb
+++ b/lib/bundler/lockfile_generator.rb
@@ -19,7 +19,6 @@ module Bundler
add_sources
add_platforms
add_dependencies
- add_checksums
add_locked_ruby_version
add_bundled_with
@@ -66,14 +65,6 @@ module Bundler
end
end
- def add_checksums
- return unless definition.locked_checksums
- checksums = definition.resolve.map do |spec|
- spec.source.checksum_store.to_lock(spec)
- end
- add_section("CHECKSUMS", checksums)
- end
-
def add_locked_ruby_version
return unless locked_ruby_version = definition.locked_ruby_version
add_section("RUBY VERSION", locked_ruby_version.to_s)
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index 1e11621e55..7360a36752 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -2,41 +2,10 @@
module Bundler
class LockfileParser
- class Position
- attr_reader :line, :column
- def initialize(line, column)
- @line = line
- @column = column
- end
-
- def advance!(string)
- lines = string.count("\n")
- if lines > 0
- @line += lines
- @column = string.length - string.rindex("\n")
- else
- @column += string.length
- end
- end
-
- def to_s
- "#{line}:#{column}"
- end
- end
-
- attr_reader(
- :sources,
- :dependencies,
- :specs,
- :platforms,
- :bundler_version,
- :ruby_version,
- :checksums,
- )
+ attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
BUNDLED = "BUNDLED WITH"
DEPENDENCIES = "DEPENDENCIES"
- CHECKSUMS = "CHECKSUMS"
PLATFORMS = "PLATFORMS"
RUBY = "RUBY VERSION"
GIT = "GIT"
@@ -44,7 +13,7 @@ module Bundler
PATH = "PATH"
PLUGIN = "PLUGIN SOURCE"
SPECS = " specs:"
- OPTIONS = /^ ([a-z]+): (.*)$/i
+ OPTIONS = /^ ([a-z]+): (.*)$/i.freeze
SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
SECTIONS_BY_VERSION_INTRODUCED = {
@@ -52,18 +21,15 @@ module Bundler
Gem::Version.create("1.10") => [BUNDLED].freeze,
Gem::Version.create("1.12") => [RUBY].freeze,
Gem::Version.create("1.13") => [PLUGIN].freeze,
- Gem::Version.create("2.5.0") => [CHECKSUMS].freeze,
}.freeze
- KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten!.freeze
+ KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
ENVIRONMENT_VERSION_SECTIONS = [BUNDLED, RUBY].freeze
deprecate_constant(:ENVIRONMENT_VERSION_SECTIONS)
def self.sections_in_lockfile(lockfile_contents)
- sections = lockfile_contents.scan(/^\w[\w ]*$/)
- sections.uniq!
- sections
+ lockfile_contents.scan(/^\w[\w ]*$/).uniq
end
def self.unknown_sections_in_lockfile(lockfile_contents)
@@ -72,7 +38,7 @@ module Bundler
def self.sections_to_ignore(base_version = nil)
base_version &&= base_version.release
- base_version ||= Gem::Version.create("1.0")
+ base_version ||= Gem::Version.create("1.0".dup)
attributes = []
SECTIONS_BY_VERSION_INTRODUCED.each do |version, introduced|
next if version <= base_version
@@ -95,53 +61,37 @@ module Bundler
@platforms = []
@sources = []
@dependencies = {}
- @parse_method = nil
+ @state = nil
@specs = {}
- @lockfile_path = begin
- SharedHelpers.relative_lockfile_path
- rescue GemfileNotFound
- "Gemfile.lock"
- end
- @pos = Position.new(1, 1)
if lockfile.match?(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
- raise LockfileError, "Your #{@lockfile_path} contains merge conflicts.\n" \
- "Run `git checkout HEAD -- #{@lockfile_path}` first to get a clean lock."
+ raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \
+ "Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock."
end
- lockfile.split(/((?:\r?\n)+)/) do |line|
- # split alternates between the line and the following whitespace
- next @pos.advance!(line) if line.match?(/^\s*$/)
-
+ lockfile.split(/(?:\r?\n)+/).each do |line|
if SOURCE.include?(line)
- @parse_method = :parse_source
+ @state = :source
parse_source(line)
elsif line == DEPENDENCIES
- @parse_method = :parse_dependency
- elsif line == CHECKSUMS
- # This is a temporary solution to make this feature disabled by default
- # for all gemfiles that don't already explicitly include the feature.
- @checksums = true
- @parse_method = :parse_checksum
+ @state = :dependency
elsif line == PLATFORMS
- @parse_method = :parse_platform
+ @state = :platform
elsif line == RUBY
- @parse_method = :parse_ruby
+ @state = :ruby
elsif line == BUNDLED
- @parse_method = :parse_bundled_with
+ @state = :bundled_with
elsif /^[^\s]/.match?(line)
- @parse_method = nil
- elsif @parse_method
- send(@parse_method, line)
+ @state = nil
+ elsif @state
+ send("parse_#{@state}", line)
end
- @pos.advance!(line)
end
- @specs = @specs.values.sort_by!(&:full_name)
+ @specs = @specs.values.sort_by(&:full_name)
rescue ArgumentError => e
Bundler.ui.debug(e)
- raise LockfileError, "Your lockfile is unreadable. Run `rm #{@lockfile_path}` " \
- "and then `bundle install` to generate a new lockfile. The error occurred while " \
- "evaluating #{@lockfile_path}:#{@pos}"
+ raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \
+ "and then `bundle install` to generate a new lockfile."
end
def may_include_redundant_platform_specific_gems?
@@ -160,9 +110,21 @@ module Bundler
def parse_source(line)
case line
when SPECS
- return unless TYPES.key?(@type)
- @current_source = TYPES[@type].from_lock(@opts)
- @sources << @current_source
+ case @type
+ when PATH
+ @current_source = TYPES[@type].from_lock(@opts)
+ @sources << @current_source
+ when GIT
+ @current_source = TYPES[@type].from_lock(@opts)
+ @sources << @current_source
+ when GEM
+ @opts["remotes"] = Array(@opts.delete("remote")).reverse
+ @current_source = TYPES[@type].from_lock(@opts)
+ @sources << @current_source
+ when PLUGIN
+ @current_source = Plugin.source_from_lock(@opts)
+ @sources << @current_source
+ end
when OPTIONS
value = $2
value = true if value == "true"
@@ -192,19 +154,18 @@ module Bundler
(?:#{space}\(([^-]*) # Space, followed by version
(?:-(.*))?\))? # Optional platform
(!)? # Optional pinned marker
- (?:#{space}([^ ]+))? # Optional checksum
$ # Line end
- /xo
+ /xo.freeze
def parse_dependency(line)
return unless line =~ NAME_VERSION
spaces = $1
return unless spaces.size == 2
- name = -$2
+ name = $2
version = $3
pinned = $5
- version = version.split(",").each(&:strip!) if version
+ version = version.split(",").map(&:strip) if version
dep = Bundler::Dependency.new(name, version)
@@ -225,47 +186,23 @@ module Bundler
@dependencies[dep.name] = dep
end
- def parse_checksum(line)
+ def parse_spec(line)
return unless line =~ NAME_VERSION
-
spaces = $1
- return unless spaces.size == 2
- checksums = $6
- return unless checksums
name = $2
version = $3
platform = $4
- version = Gem::Version.new(version)
- platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
- full_name = Gem::NameTuple.new(name, version, platform).full_name
- return unless spec = @specs[full_name]
-
- checksums.split(",") do |lock_checksum|
- column = line.index(lock_checksum) + 1
- checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
- spec.source.checksum_store.register(spec, checksum)
- end
- end
-
- def parse_spec(line)
- return unless line =~ NAME_VERSION
- spaces = $1
- name = -$2
- version = $3
-
if spaces.size == 4
- # only load platform for non-dependency (spec) line
- platform = $4
-
version = Gem::Version.new(version)
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
- @current_spec = LazySpecification.new(name, version, platform, @current_source)
+ @current_spec = LazySpecification.new(name, version, platform)
+ @current_spec.source = @current_source
@current_source.add_dependency_names(name)
@specs[@current_spec.full_name] = @current_spec
elsif spaces.size == 6
- version = version.split(",").each(&:strip!) if version
+ version = version.split(",").map(&:strip) if version
dep = Gem::Dependency.new(name, version)
@current_spec.dependencies << dep
end
@@ -276,14 +213,13 @@ module Bundler
end
def parse_bundled_with(line)
- line.strip!
+ line = line.strip
return unless Gem::Version.correct?(line)
@bundler_version = Gem::Version.create(line)
end
def parse_ruby(line)
- line.strip!
- @ruby_version = line
+ @ruby_version = line.strip
end
end
end
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
index 56a3b6f85c..8549855b0d 100644
--- a/lib/bundler/man/bundle-add.1
+++ b/lib/bundler/man/bundle-add.1
@@ -1,58 +1,81 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-ADD" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-ADD" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
+.
.SH "SYNOPSIS"
\fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-path=PATH] [\-\-git=GIT] [\-\-github=GITHUB] [\-\-branch=BRANCH] [\-\-ref=REF] [\-\-skip\-install] [\-\-strict] [\-\-optimistic]
+.
.SH "DESCRIPTION"
Adds the named gem to the Gemfile and run \fBbundle install\fR\. \fBbundle install\fR can be avoided by using the flag \fB\-\-skip\-install\fR\.
+.
.P
Example:
+.
.P
bundle add rails
+.
.P
bundle add rails \-\-version "< 3\.0, > 1\.1"
+.
.P
bundle add rails \-\-version "~> 5\.0\.0" \-\-source "https://gems\.example\.com" \-\-group "development"
+.
.P
bundle add rails \-\-skip\-install
+.
.P
bundle add rails \-\-group "development, test"
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-version\fR, \fB\-v\fR
Specify version requirements(s) for the added gem\.
+.
.TP
\fB\-\-group\fR, \fB\-g\fR
Specify the group(s) for the added gem\. Multiple groups should be separated by commas\.
+.
.TP
\fB\-\-source\fR, \fB\-s\fR
Specify the source for the added gem\.
+.
.TP
\fB\-\-require\fR, \fB\-r\fR
Adds require path to gem\. Provide false, or a path as a string\.
+.
.TP
\fB\-\-path\fR
Specify the file system path for the added gem\.
+.
.TP
\fB\-\-git\fR
Specify the git source for the added gem\.
+.
.TP
\fB\-\-github\fR
Specify the github source for the added gem\.
+.
.TP
\fB\-\-branch\fR
Specify the git branch for the added gem\.
+.
.TP
\fB\-\-ref\fR
Specify the git ref for the added gem\.
+.
.TP
\fB\-\-skip\-install\fR
Adds the gem to the Gemfile but does not install it\.
+.
.TP
\fB\-\-optimistic\fR
Adds optimistic declaration of version\.
+.
.TP
\fB\-\-strict\fR
Adds strict declaration of version\.
diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1
index 4ec301951f..40c338916a 100644
--- a/lib/bundler/man/bundle-binstubs.1
+++ b/lib/bundler/man/bundle-binstubs.1
@@ -1,29 +1,41 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-BINSTUBS" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-BINSTUBS" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
+.
.SH "SYNOPSIS"
\fBbundle binstubs\fR \fIGEM_NAME\fR [\-\-force] [\-\-path PATH] [\-\-standalone]
+.
.SH "DESCRIPTION"
Binstubs are scripts that wrap around executables\. Bundler creates a small Ruby file (a binstub) that loads Bundler, runs the command, and puts it into \fBbin/\fR\. Binstubs are a shortcut\-or alternative\- to always using \fBbundle exec\fR\. This gives you a file that can be run directly, and one that will always run the correct gem version used by the application\.
+.
.P
For example, if you run \fBbundle binstubs rspec\-core\fR, Bundler will create the file \fBbin/rspec\fR\. That file will contain enough code to load Bundler, tell it to load the bundled gems, and then run rspec\.
+.
.P
This command generates binstubs for executables in \fBGEM_NAME\fR\. Binstubs are put into \fBbin\fR, or the \fB\-\-path\fR directory if one has been set\. Calling binstubs with [GEM [GEM]] will create binstubs for all given gems\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-force\fR
Overwrite existing binstubs if they exist\.
+.
.TP
\fB\-\-path\fR
The location to install the specified binstubs to\. This defaults to \fBbin\fR\.
+.
.TP
\fB\-\-standalone\fR
Makes binstubs that can work without depending on Rubygems or Bundler at runtime\.
+.
.TP
\fB\-\-shebang\fR
-Specify a different shebang executable name than the default (default 'ruby')
+Specify a different shebang executable name than the default (default \'ruby\')
+.
.TP
\fB\-\-all\fR
Create binstubs for all gems in the bundle\.
diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1
index e2da1269e6..69b1e1e3dd 100644
--- a/lib/bundler/man/bundle-cache.1
+++ b/lib/bundler/man/bundle-cache.1
@@ -1,40 +1,61 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-CACHE" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CACHE" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
+.
.SH "SYNOPSIS"
\fBbundle cache\fR
+.
.P
alias: \fBpackage\fR, \fBpack\fR
+.
.SH "DESCRIPTION"
Copy all of the \fB\.gem\fR files needed to run the application into the \fBvendor/cache\fR directory\. In the future, when running \fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR, use the gems in the cache in preference to the ones on \fBrubygems\.org\fR\.
+.
.SH "GIT AND PATH GEMS"
The \fBbundle cache\fR command can also package \fB:git\fR and \fB:path\fR dependencies besides \.gem files\. This needs to be explicitly enabled via the \fB\-\-all\fR option\. Once used, the \fB\-\-all\fR option will be remembered\.
+.
.SH "SUPPORT FOR MULTIPLE PLATFORMS"
When using gems that have different packages for different platforms, Bundler supports caching of gems for other platforms where the Gemfile has been resolved (i\.e\. present in the lockfile) in \fBvendor/cache\fR\. This needs to be enabled via the \fB\-\-all\-platforms\fR option\. This setting will be remembered in your local bundler configuration\.
+.
.SH "REMOTE FETCHING"
By default, if you run \fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR after running bundle cache(1) \fIbundle\-cache\.1\.html\fR, bundler will still connect to \fBrubygems\.org\fR to check whether a platform\-specific gem exists for any of the gems in \fBvendor/cache\fR\.
+.
.P
For instance, consider this Gemfile(5):
+.
.IP "" 4
+.
.nf
+
source "https://rubygems\.org"
gem "nokogiri"
+.
.fi
+.
.IP "" 0
+.
.P
If you run \fBbundle cache\fR under C Ruby, bundler will retrieve the version of \fBnokogiri\fR for the \fB"ruby"\fR platform\. If you deploy to JRuby and run \fBbundle install\fR, bundler is forced to check to see whether a \fB"java"\fR platformed \fBnokogiri\fR exists\.
+.
.P
Even though the \fBnokogiri\fR gem for the Ruby platform is \fItechnically\fR acceptable on JRuby, it has a C extension that does not run on JRuby\. As a result, bundler will, by default, still connect to \fBrubygems\.org\fR to check whether it has a version of one of your gems more specific to your platform\.
+.
.P
This problem is also not limited to the \fB"java"\fR platform\. A similar (common) problem can happen when developing on Windows and deploying to Linux, or even when developing on OSX and deploying to Linux\.
+.
.P
If you know for sure that the gems packaged in \fBvendor/cache\fR are appropriate for the platform you are on, you can run \fBbundle install \-\-local\fR to skip checking for more appropriate gems, and use the ones in \fBvendor/cache\fR\.
+.
.P
One way to be sure that you have the right platformed versions of all your gems is to run \fBbundle cache\fR on an identical machine and check in the gems\. For instance, you can run \fBbundle cache\fR on an identical staging box during your staging process, and check in the \fBvendor/cache\fR before deploying to production\.
+.
.P
By default, bundle cache(1) \fIbundle\-cache\.1\.html\fR fetches and also installs the gems to the default location\. To package the dependencies to \fBvendor/cache\fR without installing them to the local install location, you can run \fBbundle cache \-\-no\-install\fR\.
+.
.SH "HISTORY"
In Bundler 2\.1, \fBcache\fR took in the functionalities of \fBpackage\fR and now \fBpackage\fR and \fBpack\fR are aliases of \fBcache\fR\.
diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1
index dee1af1326..748a37e7d1 100644
--- a/lib/bundler/man/bundle-check.1
+++ b/lib/bundler/man/bundle-check.1
@@ -1,23 +1,30 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-CHECK" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CHECK" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
+.
.SH "SYNOPSIS"
\fBbundle check\fR [\-\-dry\-run] [\-\-gemfile=FILE] [\-\-path=PATH]
+.
.SH "DESCRIPTION"
\fBcheck\fR searches the local machine for each of the gems requested in the Gemfile\. If all gems are found, Bundler prints a success message and exits with a status of 0\.
+.
.P
If not, the first missing gem is listed and Bundler exits status 1\.
-.P
-If the lockfile needs to be updated then it will be resolved using the gems installed on the local machine, if they satisfy the requirements\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-dry\-run\fR
Locks the [\fBGemfile(5)\fR][Gemfile(5)] before running the command\.
+.
.TP
\fB\-\-gemfile\fR
Use the specified gemfile instead of the [\fBGemfile(5)\fR][Gemfile(5)]\.
+.
.TP
\fB\-\-path\fR
Specify a different path than the system default (\fB$BUNDLE_PATH\fR or \fB$GEM_HOME\fR)\. Bundler will remember this value for future installs on this machine\.
diff --git a/lib/bundler/man/bundle-check.1.ronn b/lib/bundler/man/bundle-check.1.ronn
index eb3ff1daf9..f2846b8ff2 100644
--- a/lib/bundler/man/bundle-check.1.ronn
+++ b/lib/bundler/man/bundle-check.1.ronn
@@ -15,9 +15,6 @@ a status of 0.
If not, the first missing gem is listed and Bundler exits status 1.
-If the lockfile needs to be updated then it will be resolved using the gems
-installed on the local machine, if they satisfy the requirements.
-
## OPTIONS
* `--dry-run`:
diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1
index 7c7f9b5c77..af8f13cd89 100644
--- a/lib/bundler/man/bundle-clean.1
+++ b/lib/bundler/man/bundle-clean.1
@@ -1,16 +1,23 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-CLEAN" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CLEAN" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
+.
.SH "SYNOPSIS"
\fBbundle clean\fR [\-\-dry\-run] [\-\-force]
+.
.SH "DESCRIPTION"
This command will remove all unused gems in your bundler directory\. This is useful when you have made many changes to your gem dependencies\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-dry\-run\fR
Print the changes, but do not clean the unused gems\.
+.
.TP
\fB\-\-force\fR
Forces cleaning up unused gems even if Bundler is configured to use globally installed gems\. As a consequence, removes all system gems except for the ones in the current application\.
diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1
index a207dbbcaa..4442f33105 100644
--- a/lib/bundler/man/bundle-config.1
+++ b/lib/bundler/man/bundle-config.1
@@ -1,319 +1,512 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-CONFIG" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CONFIG" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
+.
.SH "SYNOPSIS"
\fBbundle config\fR list
+.
.br
\fBbundle config\fR [get] NAME
+.
.br
\fBbundle config\fR [set] NAME VALUE
+.
.br
\fBbundle config\fR unset NAME
+.
.SH "DESCRIPTION"
-This command allows you to interact with Bundler's configuration system\.
+This command allows you to interact with Bundler\'s configuration system\.
+.
.P
Bundler loads configuration settings in this order:
+.
.IP "1." 4
Local config (\fB<project_root>/\.bundle/config\fR or \fB$BUNDLE_APP_CONFIG/config\fR)
+.
.IP "2." 4
Environmental variables (\fBENV\fR)
+.
.IP "3." 4
Global config (\fB~/\.bundle/config\fR)
+.
.IP "4." 4
Bundler default config
+.
.IP "" 0
+.
.P
Executing \fBbundle config list\fR will print a list of all bundler configuration for the current bundle, and where that configuration was set\.
+.
.P
Executing \fBbundle config get <name>\fR will print the value of that configuration setting, and where it was set\.
+.
.P
Executing \fBbundle config set <name> <value>\fR defaults to setting \fBlocal\fR configuration if executing from within a local application, otherwise it will set \fBglobal\fR configuration\. See \fB\-\-local\fR and \fB\-\-global\fR options below\.
+.
.P
Executing \fBbundle config set \-\-local <name> <value>\fR will set that configuration in the directory for the local application\. The configuration will be stored in \fB<project_root>/\.bundle/config\fR\. If \fBBUNDLE_APP_CONFIG\fR is set, the configuration will be stored in \fB$BUNDLE_APP_CONFIG/config\fR\.
+.
.P
Executing \fBbundle config set \-\-global <name> <value>\fR will set that configuration to the value specified for all bundles executed as the current user\. The configuration will be stored in \fB~/\.bundle/config\fR\. If \fIname\fR already is set, \fIname\fR will be overridden and user will be warned\.
+.
.P
Executing \fBbundle config unset <name>\fR will delete the configuration in both local and global sources\.
+.
.P
Executing \fBbundle config unset \-\-global <name>\fR will delete the configuration only from the user configuration\.
+.
.P
Executing \fBbundle config unset \-\-local <name>\fR will delete the configuration only from the local application\.
+.
.P
Executing bundle with the \fBBUNDLE_IGNORE_CONFIG\fR environment variable set will cause it to ignore all configuration\.
+.
.SH "REMEMBERING OPTIONS"
-Flags passed to \fBbundle install\fR or the Bundler runtime, such as \fB\-\-path foo\fR or \fB\-\-without production\fR, are remembered between commands and saved to your local application's configuration (normally, \fB\./\.bundle/config\fR)\.
+Flags passed to \fBbundle install\fR or the Bundler runtime, such as \fB\-\-path foo\fR or \fB\-\-without production\fR, are remembered between commands and saved to your local application\'s configuration (normally, \fB\./\.bundle/config\fR)\.
+.
.P
-However, this will be changed in bundler 3, so it's better not to rely on this behavior\. If these options must be remembered, it's better to set them using \fBbundle config\fR (e\.g\., \fBbundle config set \-\-local path foo\fR)\.
+However, this will be changed in bundler 3, so it\'s better not to rely on this behavior\. If these options must be remembered, it\'s better to set them using \fBbundle config\fR (e\.g\., \fBbundle config set \-\-local path foo\fR)\.
+.
.P
The options that can be configured are:
+.
.TP
\fBbin\fR
-Creates a directory (defaults to \fB~/bin\fR) and place any executables from the gem there\. These executables run in Bundler's context\. If used, you might add this directory to your environment's \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
+Creates a directory (defaults to \fB~/bin\fR) and place any executables from the gem there\. These executables run in Bundler\'s context\. If used, you might add this directory to your environment\'s \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
+.
.TP
\fBdeployment\fR
-In deployment mode, Bundler will 'roll\-out' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\.
+In deployment mode, Bundler will \'roll\-out\' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\.
+.
.TP
\fBonly\fR
A space\-separated list of groups to install only gems of the specified groups\.
+.
.TP
\fBpath\fR
-The location to install the specified gems to\. This defaults to Rubygems' setting\. Bundler shares this location with Rubygems, \fBgem install \|\.\|\.\|\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \|\.\|\.\|\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
+The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
+.
.TP
\fBwithout\fR
A space\-separated list of groups referencing gems to skip during installation\.
+.
.TP
\fBwith\fR
A space\-separated list of \fBoptional\fR groups referencing gems to include during installation\.
+.
.SH "BUILD OPTIONS"
You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\.
+.
.P
A very common example, the \fBmysql\fR gem, requires Snow Leopard users to pass configuration flags to \fBgem install\fR to specify where to find the \fBmysql_config\fR executable\.
+.
.IP "" 4
+.
.nf
+
gem install mysql \-\- \-\-with\-mysql\-config=/usr/local/mysql/bin/mysql_config
+.
.fi
+.
.IP "" 0
+.
.P
Since the specific location of that executable can change from machine to machine, you can specify these flags on a per\-machine basis\.
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global build\.mysql \-\-with\-mysql\-config=/usr/local/mysql/bin/mysql_config
+.
.fi
+.
.IP "" 0
+.
.P
After running this command, every time bundler needs to install the \fBmysql\fR gem, it will pass along the flags you specified\.
+.
.SH "CONFIGURATION KEYS"
Configuration keys in bundler have two forms: the canonical form and the environment variable form\.
+.
.P
-For instance, passing the \fB\-\-without\fR flag to bundle install(1) \fIbundle\-install\.1\.html\fR prevents Bundler from installing certain groups specified in the Gemfile(5)\. Bundler persists this value in \fBapp/\.bundle/config\fR so that calls to \fBBundler\.setup\fR do not try to find gems from the \fBGemfile\fR that you didn't install\. Additionally, subsequent calls to bundle install(1) \fIbundle\-install\.1\.html\fR remember this setting and skip those groups\.
+For instance, passing the \fB\-\-without\fR flag to bundle install(1) \fIbundle\-install\.1\.html\fR prevents Bundler from installing certain groups specified in the Gemfile(5)\. Bundler persists this value in \fBapp/\.bundle/config\fR so that calls to \fBBundler\.setup\fR do not try to find gems from the \fBGemfile\fR that you didn\'t install\. Additionally, subsequent calls to bundle install(1) \fIbundle\-install\.1\.html\fR remember this setting and skip those groups\.
+.
.P
The canonical form of this configuration is \fB"without"\fR\. To convert the canonical form to the environment variable form, capitalize it, and prepend \fBBUNDLE_\fR\. The environment variable form of \fB"without"\fR is \fBBUNDLE_WITHOUT\fR\.
+.
.P
Any periods in the configuration keys must be replaced with two underscores when setting it via environment variables\. The configuration key \fBlocal\.rack\fR becomes the environment variable \fBBUNDLE_LOCAL__RACK\fR\.
+.
.SH "LIST OF AVAILABLE KEYS"
The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\.
+.
+.IP "\(bu" 4
+\fBallow_deployment_source_credential_changes\fR (\fBBUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES\fR): When in deployment mode, allow changing the credentials to a gem\'s source\. Ex: \fBhttps://some\.host\.com/gems/path/\fR \-> \fBhttps://user_name:password@some\.host\.com/gems/path\fR
+.
.IP "\(bu" 4
\fBallow_offline_install\fR (\fBBUNDLE_ALLOW_OFFLINE_INSTALL\fR): Allow Bundler to use cached data when installing without network access\.
+.
.IP "\(bu" 4
\fBauto_clean_without_path\fR (\fBBUNDLE_AUTO_CLEAN_WITHOUT_PATH\fR): Automatically run \fBbundle clean\fR after installing when an explicit \fBpath\fR has not been set and Bundler is not installing into the system gems\.
+.
.IP "\(bu" 4
\fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR): Automatically run \fBbundle install\fR when gems are missing\.
+.
.IP "\(bu" 4
\fBbin\fR (\fBBUNDLE_BIN\fR): Install executables from gems in the bundle to the specified directory\. Defaults to \fBfalse\fR\.
+.
.IP "\(bu" 4
\fBcache_all\fR (\fBBUNDLE_CACHE_ALL\fR): Cache all gems, including path and git gems\. This needs to be explicitly configured on bundler 1 and bundler 2, but will be the default on bundler 3\.
+.
.IP "\(bu" 4
\fBcache_all_platforms\fR (\fBBUNDLE_CACHE_ALL_PLATFORMS\fR): Cache gems for all platforms\.
+.
.IP "\(bu" 4
\fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR): The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\.
+.
.IP "\(bu" 4
\fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\.
+.
.IP "\(bu" 4
\fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\.
+.
.IP "\(bu" 4
\fBdefault_install_uses_path\fR (\fBBUNDLE_DEFAULT_INSTALL_USES_PATH\fR): Whether a \fBbundle install\fR without an explicit \fB\-\-path\fR argument defaults to installing gems in \fB\.bundle\fR\.
+.
.IP "\(bu" 4
\fBdeployment\fR (\fBBUNDLE_DEPLOYMENT\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\.
+.
.IP "\(bu" 4
\fBdisable_checksum_validation\fR (\fBBUNDLE_DISABLE_CHECKSUM_VALIDATION\fR): Allow installing gems even if they do not match the checksum provided by RubyGems\.
+.
.IP "\(bu" 4
\fBdisable_exec_load\fR (\fBBUNDLE_DISABLE_EXEC_LOAD\fR): Stop Bundler from using \fBload\fR to launch an executable in\-process in \fBbundle exec\fR\.
+.
.IP "\(bu" 4
\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR): Allow Bundler to use a local git override without a branch specified in the Gemfile\.
+.
.IP "\(bu" 4
\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\.
+.
.IP "\(bu" 4
-\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems' normal location\.
+\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems\' normal location\.
+.
.IP "\(bu" 4
\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR): Stop Bundler from checking if a newer Bundler version is available on rubygems\.org\.
+.
.IP "\(bu" 4
-\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR): Ignore the current machine's platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\.
+\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR): Ignore the current machine\'s platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\.
+.
.IP "\(bu" 4
\fBfrozen\fR (\fBBUNDLE_FROZEN\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\. Defaults to \fBtrue\fR when \fB\-\-deployment\fR is used\.
+.
.IP "\(bu" 4
\fBgem\.github_username\fR (\fBBUNDLE_GEM__GITHUB_USERNAME\fR): Sets a GitHub username or organization to be used in \fBREADME\fR file when you create a new gem via \fBbundle gem\fR command\. It can be overridden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\.
+.
.IP "\(bu" 4
\fBgem\.push_key\fR (\fBBUNDLE_GEM__PUSH_KEY\fR): Sets the \fB\-\-key\fR parameter for \fBgem push\fR when using the \fBrake release\fR command with a private gemstash server\.
+.
.IP "\(bu" 4
\fBgemfile\fR (\fBBUNDLE_GEMFILE\fR): The name of the file that bundler should use as the \fBGemfile\fR\. This location of this file also sets the root of the project, which is used to resolve relative paths in the \fBGemfile\fR, among other things\. By default, bundler will search up from the current working directory until it finds a \fBGemfile\fR\.
+.
.IP "\(bu" 4
\fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR): Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation\.
+.
.IP "\(bu" 4
\fBignore_funding_requests\fR (\fBBUNDLE_IGNORE_FUNDING_REQUESTS\fR): When set, no funding requests will be printed\.
+.
.IP "\(bu" 4
\fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\.
+.
.IP "\(bu" 4
\fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR): Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\.
+.
.IP "\(bu" 4
\fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can install in parallel\. Defaults to the number of available processors\.
+.
.IP "\(bu" 4
\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\.
+.
.IP "\(bu" 4
\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\.
+.
.IP "\(bu" 4
\fBonly\fR (\fBBUNDLE_ONLY\fR): A space\-separated list of groups to install only gems of the specified groups\.
+.
.IP "\(bu" 4
\fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. Defaults to \fBGem\.dir\fR\. When \-\-deployment is used, defaults to vendor/bundle\.
+.
.IP "\(bu" 4
\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\.
+.
.IP "\(bu" 4
\fBpath_relative_to_cwd\fR (\fBBUNDLE_PATH_RELATIVE_TO_CWD\fR) Makes \fB\-\-path\fR relative to the CWD instead of the \fBGemfile\fR\.
+.
.IP "\(bu" 4
-\fBplugins\fR (\fBBUNDLE_PLUGINS\fR): Enable Bundler's experimental plugin system\.
+\fBplugins\fR (\fBBUNDLE_PLUGINS\fR): Enable Bundler\'s experimental plugin system\.
+.
.IP "\(bu" 4
\fBprefer_patch\fR (BUNDLE_PREFER_PATCH): Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\.
+.
.IP "\(bu" 4
\fBprint_only_version_number\fR (\fBBUNDLE_PRINT_ONLY_VERSION_NUMBER\fR): Print only version number from \fBbundler \-\-version\fR\.
+.
.IP "\(bu" 4
\fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\.
+.
.IP "\(bu" 4
\fBretry\fR (\fBBUNDLE_RETRY\fR): The number of times to retry failed network requests\. Defaults to \fB3\fR\.
+.
.IP "\(bu" 4
\fBsetup_makes_kernel_gem_public\fR (\fBBUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC\fR): Have \fBBundler\.setup\fR make the \fBKernel#gem\fR method public, even though RubyGems declares it as private\.
+.
.IP "\(bu" 4
\fBshebang\fR (\fBBUNDLE_SHEBANG\fR): The program name that should be invoked for generated binstubs\. Defaults to the ruby install name used to generate the binstub\.
+.
.IP "\(bu" 4
\fBsilence_deprecations\fR (\fBBUNDLE_SILENCE_DEPRECATIONS\fR): Whether Bundler should silence deprecation warnings for behavior that will be changed in the next major version\.
+.
.IP "\(bu" 4
\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\.
+.
.IP "\(bu" 4
\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\.
+.
.IP "\(bu" 4
\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR): Path to a designated file containing a X\.509 client certificate and key in PEM format\.
+.
.IP "\(bu" 4
\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR): The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\.
+.
.IP "\(bu" 4
\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\.
+.
.IP "\(bu" 4
\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\.
+.
.IP "\(bu" 4
\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
+.
.IP "\(bu" 4
\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR): The custom user agent fragment Bundler includes in API requests\.
-.IP "\(bu" 4
-\fBversion\fR (\fBBUNDLE_VERSION\fR): The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\.
+.
.IP "\(bu" 4
\fBwith\fR (\fBBUNDLE_WITH\fR): A \fB:\fR\-separated list of groups whose gems bundler should install\.
+.
.IP "\(bu" 4
\fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A \fB:\fR\-separated list of groups whose gems bundler should not install\.
+.
.IP "" 0
+.
.P
In general, you should set these settings per\-application by using the applicable flag to the bundle install(1) \fIbundle\-install\.1\.html\fR or bundle cache(1) \fIbundle\-cache\.1\.html\fR command\.
+.
.P
You can set them globally either via environment variables or \fBbundle config\fR, whichever is preferable for your setup\. If you use both, environment variables will take preference over global settings\.
+.
.SH "LOCAL GIT REPOS"
Bundler also allows you to work against a git repository locally instead of using the remote version\. This can be achieved by setting up a local override:
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-local local\.GEM_NAME /path/to/local/git/repository
+.
.fi
+.
.IP "" 0
+.
.P
For example, in order to use a local Rack repository, a developer could call:
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-local local\.rack ~/Work/git/rack
+.
.fi
+.
.IP "" 0
+.
.P
-Now instead of checking out the remote git repository, the local override will be used\. Similar to a path source, every time the local git repository change, changes will be automatically picked up by Bundler\. This means a commit in the local git repo will update the revision in the \fBGemfile\.lock\fR to the local git repo revision\. This requires the same attention as git submodules\. Before pushing to the remote, you need to ensure the local override was pushed, otherwise you may point to a commit that only exists in your local machine\. You'll also need to CGI escape your usernames and passwords as well\.
+Now instead of checking out the remote git repository, the local override will be used\. Similar to a path source, every time the local git repository change, changes will be automatically picked up by Bundler\. This means a commit in the local git repo will update the revision in the \fBGemfile\.lock\fR to the local git repo revision\. This requires the same attention as git submodules\. Before pushing to the remote, you need to ensure the local override was pushed, otherwise you may point to a commit that only exists in your local machine\. You\'ll also need to CGI escape your usernames and passwords as well\.
+.
.P
-Bundler does many checks to ensure a developer won't work with invalid references\. Particularly, we force a developer to specify a branch in the \fBGemfile\fR in order to use this feature\. If the branch specified in the \fBGemfile\fR and the current branch in the local git repository do not match, Bundler will abort\. This ensures that a developer is always working against the correct branches, and prevents accidental locking to a different branch\.
+Bundler does many checks to ensure a developer won\'t work with invalid references\. Particularly, we force a developer to specify a branch in the \fBGemfile\fR in order to use this feature\. If the branch specified in the \fBGemfile\fR and the current branch in the local git repository do not match, Bundler will abort\. This ensures that a developer is always working against the correct branches, and prevents accidental locking to a different branch\.
+.
.P
Finally, Bundler also ensures that the current revision in the \fBGemfile\.lock\fR exists in the local git repository\. By doing this, Bundler forces you to fetch the latest changes in the remotes\.
+.
.SH "MIRRORS OF GEM SOURCES"
Bundler supports overriding gem sources with mirrors\. This allows you to configure rubygems\.org as the gem source in your Gemfile while still using your mirror to fetch gems\.
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global mirror\.SOURCE_URL MIRROR_URL
+.
.fi
+.
.IP "" 0
+.
.P
For example, to use a mirror of https://rubygems\.org hosted at https://example\.org:
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global mirror\.https://rubygems\.org https://example\.org
+.
.fi
+.
.IP "" 0
+.
.P
Each mirror also provides a fallback timeout setting\. If the mirror does not respond within the fallback timeout, Bundler will try to use the original server instead of the mirror\.
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global mirror\.SOURCE_URL\.fallback_timeout TIMEOUT
+.
.fi
+.
.IP "" 0
+.
.P
For example, to fall back to rubygems\.org after 3 seconds:
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global mirror\.https://rubygems\.org\.fallback_timeout 3
+.
.fi
+.
.IP "" 0
+.
.P
The default fallback timeout is 0\.1 seconds, but the setting can currently only accept whole seconds (for example, 1, 15, or 30)\.
+.
.SH "CREDENTIALS FOR GEM SOURCES"
Bundler allows you to configure credentials for any gem source, which allows you to avoid putting secrets into your Gemfile\.
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global SOURCE_HOSTNAME USERNAME:PASSWORD
+.
.fi
+.
.IP "" 0
+.
.P
For example, to save the credentials of user \fBclaudette\fR for the gem source at \fBgems\.longerous\.com\fR, you would run:
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global gems\.longerous\.com claudette:s00pers3krit
+.
.fi
+.
.IP "" 0
+.
.P
Or you can set the credentials as an environment variable like this:
+.
.IP "" 4
+.
.nf
+
export BUNDLE_GEMS__LONGEROUS__COM="claudette:s00pers3krit"
+.
.fi
+.
.IP "" 0
+.
.P
For gems with a git source with HTTP(S) URL you can specify credentials like so:
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-global https://github\.com/rubygems/rubygems\.git username:password
+.
.fi
+.
.IP "" 0
+.
.P
Or you can set the credentials as an environment variable like so:
+.
.IP "" 4
+.
.nf
+
export BUNDLE_GITHUB__COM=username:password
+.
.fi
+.
.IP "" 0
+.
.P
This is especially useful for private repositories on hosts such as GitHub, where you can use personal OAuth tokens:
+.
.IP "" 4
+.
.nf
+
export BUNDLE_GITHUB__COM=abcd0123generatedtoken:x\-oauth\-basic
+.
.fi
+.
.IP "" 0
+.
.P
Note that any configured credentials will be redacted by informative commands such as \fBbundle config list\fR or \fBbundle config get\fR, unless you use the \fB\-\-parseable\fR flag\. This is to avoid unintentionally leaking credentials when copy\-pasting bundler output\.
+.
.P
Also note that to guarantee a sane mapping between valid environment variable names and valid host names, bundler makes the following transformations:
+.
.IP "\(bu" 4
-Any \fB\-\fR characters in a host name are mapped to a triple underscore (\fB___\fR) in the corresponding environment variable\.
+Any \fB\-\fR characters in a host name are mapped to a triple dash (\fB___\fR) in the corresponding environment variable\.
+.
.IP "\(bu" 4
-Any \fB\.\fR characters in a host name are mapped to a double underscore (\fB__\fR) in the corresponding environment variable\.
+Any \fB\.\fR characters in a host name are mapped to a double dash (\fB__\fR) in the corresponding environment variable\.
+.
.IP "" 0
+.
.P
-This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you'll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\.
+This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you\'ll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\.
+.
.SH "CONFIGURE BUNDLER DIRECTORIES"
-Bundler's home, config, cache and plugin directories are able to be configured through environment variables\. The default location for Bundler's home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values
+Bundler\'s home, config, cache and plugin directories are able to be configured through environment variables\. The default location for Bundler\'s home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values
+.
.IP "" 4
+.
.nf
+
BUNDLE_USER_HOME : $HOME/\.bundle
BUNDLE_USER_CACHE : $BUNDLE_USER_HOME/cache
BUNDLE_USER_CONFIG : $BUNDLE_USER_HOME/config
BUNDLE_USER_PLUGIN : $BUNDLE_USER_HOME/plugin
+.
.fi
+.
.IP "" 0
diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn
index 7e5f458fb2..adc273ec62 100644
--- a/lib/bundler/man/bundle-config.1.ronn
+++ b/lib/bundler/man/bundle-config.1.ronn
@@ -137,6 +137,9 @@ the environment variable `BUNDLE_LOCAL__RACK`.
The following is a list of all configuration keys and their purpose. You can
learn more about their operation in [bundle install(1)](bundle-install.1.html).
+* `allow_deployment_source_credential_changes` (`BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES`):
+ When in deployment mode, allow changing the credentials to a gem's source.
+ Ex: `https://some.host.com/gems/path/` -> `https://user_name:password@some.host.com/gems/path`
* `allow_offline_install` (`BUNDLE_ALLOW_OFFLINE_INSTALL`):
Allow Bundler to use cached data when installing without network access.
* `auto_clean_without_path` (`BUNDLE_AUTO_CLEAN_WITHOUT_PATH`):
@@ -271,12 +274,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
and disallow passing no options to `bundle update`.
* `user_agent` (`BUNDLE_USER_AGENT`):
The custom user agent fragment Bundler includes in API requests.
-* `version` (`BUNDLE_VERSION`):
- The version of Bundler to use when running under Bundler environment.
- Defaults to `lockfile`. You can also specify `system` or `x.y.z`.
- `lockfile` will use the Bundler version specified in the `Gemfile.lock`,
- `system` will use the system version of Bundler, and `x.y.z` will use
- the specified version of Bundler.
* `with` (`BUNDLE_WITH`):
A `:`-separated list of groups whose gems bundler should install.
* `without` (`BUNDLE_WITHOUT`):
@@ -385,10 +382,10 @@ copy-pasting bundler output.
Also note that to guarantee a sane mapping between valid environment variable
names and valid host names, bundler makes the following transformations:
-* Any `-` characters in a host name are mapped to a triple underscore (`___`) in the
+* Any `-` characters in a host name are mapped to a triple dash (`___`) in the
corresponding environment variable.
-* Any `.` characters in a host name are mapped to a double underscore (`__`) in the
+* Any `.` characters in a host name are mapped to a double dash (`__`) in the
corresponding environment variable.
This means that if you have a gem server named `my.gem-host.com`, you'll need to
diff --git a/lib/bundler/man/bundle-console.1 b/lib/bundler/man/bundle-console.1
index dca18ec43d..24fff46cec 100644
--- a/lib/bundler/man/bundle-console.1
+++ b/lib/bundler/man/bundle-console.1
@@ -1,35 +1,53 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-CONSOLE" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-CONSOLE" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-console\fR \- Deprecated way to open an IRB session with the bundle pre\-loaded
+.
.SH "SYNOPSIS"
\fBbundle console\fR [GROUP]
+.
.SH "DESCRIPTION"
Starts an interactive Ruby console session in the context of the current bundle\.
+.
.P
If no \fBGROUP\fR is specified, all gems in the \fBdefault\fR group in the Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR are preliminarily loaded\.
+.
.P
If \fBGROUP\fR is specified, all gems in the given group in the Gemfile in addition to the gems in \fBdefault\fR group are loaded\. Even if the given group does not exist in the Gemfile, IRB console starts without any warning or error\.
+.
.P
The environment variable \fBBUNDLE_CONSOLE\fR or \fBbundle config set console\fR can be used to change the shell from the following:
+.
.IP "\(bu" 4
\fBirb\fR (default)
+.
.IP "\(bu" 4
\fBpry\fR (https://github\.com/pry/pry)
+.
.IP "\(bu" 4
\fBripl\fR (https://github\.com/cldwalker/ripl)
+.
.IP "" 0
+.
.P
\fBbundle console\fR uses irb by default\. An alternative Pry or Ripl can be used with \fBbundle console\fR by adjusting the \fBconsole\fR Bundler setting\. Also make sure that \fBpry\fR or \fBripl\fR is in your Gemfile\.
+.
.SH "EXAMPLE"
+.
.nf
+
$ bundle config set console pry
$ bundle console
-Resolving dependencies\|\.\|\.\|\.
+Resolving dependencies\.\.\.
[1] pry(main)>
+.
.fi
+.
.SH "NOTES"
This command was deprecated in Bundler 2\.1 and will be removed in 3\.0\. Use \fBbin/console\fR script, which can be generated by \fBbundle gem <NAME>\fR\.
+.
.SH "SEE ALSO"
Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
index 6489cc07f7..57da8216cb 100644
--- a/lib/bundler/man/bundle-doctor.1
+++ b/lib/bundler/man/bundle-doctor.1
@@ -1,30 +1,44 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-DOCTOR" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-DOCTOR" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems
+.
.SH "SYNOPSIS"
\fBbundle doctor\fR [\-\-quiet] [\-\-gemfile=GEMFILE]
+.
.SH "DESCRIPTION"
Checks your Gemfile and gem environment for common problems\. If issues are detected, Bundler prints them and exits status 1\. Otherwise, Bundler prints a success message and exits status 0\.
+.
.P
Examples of common problems caught by bundle\-doctor include:
+.
.IP "\(bu" 4
Invalid Bundler settings
+.
.IP "\(bu" 4
Mismatched Ruby versions
+.
.IP "\(bu" 4
Mismatched platforms
+.
.IP "\(bu" 4
Uninstalled gems
+.
.IP "\(bu" 4
Missing dependencies
+.
.IP "" 0
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-quiet\fR
Only output warnings and errors\.
+.
.TP
\fB\-\-gemfile=<gemfile>\fR
-The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project's root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\.
+The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project\'s root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\.
diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1
index 1548d29670..852788db7a 100644
--- a/lib/bundler/man/bundle-exec.1
+++ b/lib/bundler/man/bundle-exec.1
@@ -1,104 +1,165 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-EXEC" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-EXEC" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
+.
.SH "SYNOPSIS"
\fBbundle exec\fR [\-\-keep\-file\-descriptors] \fIcommand\fR
+.
.SH "DESCRIPTION"
This command executes the command, making all gems specified in the [\fBGemfile(5)\fR][Gemfile(5)] available to \fBrequire\fR in Ruby programs\.
+.
.P
Essentially, if you would normally have run something like \fBrspec spec/my_spec\.rb\fR, and you want to use the gems specified in the [\fBGemfile(5)\fR][Gemfile(5)] and installed via bundle install(1) \fIbundle\-install\.1\.html\fR, you should run \fBbundle exec rspec spec/my_spec\.rb\fR\.
+.
.P
-Note that \fBbundle exec\fR does not require that an executable is available on your shell's \fB$PATH\fR\.
+Note that \fBbundle exec\fR does not require that an executable is available on your shell\'s \fB$PATH\fR\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-keep\-file\-descriptors\fR
-Passes all file descriptors to the new processes\. Default is true from bundler version 2\.2\.26\. Setting it to false is now deprecated\.
+Exec in Ruby 2\.0 began discarding non\-standard file descriptors\. When this flag is passed, exec will revert to the 1\.9 behaviour of passing all file descriptors to the new process\.
+.
.SH "BUNDLE INSTALL \-\-BINSTUBS"
If you use the \fB\-\-binstubs\fR flag in bundle install(1) \fIbundle\-install\.1\.html\fR, Bundler will automatically create a directory (which defaults to \fBapp_root/bin\fR) containing all of the executables available from gems in the bundle\.
+.
.P
After using \fB\-\-binstubs\fR, \fBbin/rspec spec/my_spec\.rb\fR is identical to \fBbundle exec rspec spec/my_spec\.rb\fR\.
+.
.SH "ENVIRONMENT MODIFICATIONS"
\fBbundle exec\fR makes a number of changes to the shell environment, then executes the command you specify in full\.
+.
.IP "\(bu" 4
-make sure that it's still possible to shell out to \fBbundle\fR from inside a command invoked by \fBbundle exec\fR (using \fB$BUNDLE_BIN_PATH\fR)
+make sure that it\'s still possible to shell out to \fBbundle\fR from inside a command invoked by \fBbundle exec\fR (using \fB$BUNDLE_BIN_PATH\fR)
+.
.IP "\(bu" 4
put the directory containing executables (like \fBrails\fR, \fBrspec\fR, \fBrackup\fR) for your bundle on \fB$PATH\fR
+.
.IP "\(bu" 4
make sure that if bundler is invoked in the subshell, it uses the same \fBGemfile\fR (by setting \fBBUNDLE_GEMFILE\fR)
+.
.IP "\(bu" 4
add \fB\-rbundler/setup\fR to \fB$RUBYOPT\fR, which makes sure that Ruby programs invoked in the subshell can see the gems in the bundle
+.
.IP "" 0
+.
.P
It also modifies Rubygems:
+.
.IP "\(bu" 4
disallow loading additional gems not in the bundle
+.
.IP "\(bu" 4
-modify the \fBgem\fR method to be a no\-op if a gem matching the requirements is in the bundle, and to raise a \fBGem::LoadError\fR if it's not
+modify the \fBgem\fR method to be a no\-op if a gem matching the requirements is in the bundle, and to raise a \fBGem::LoadError\fR if it\'s not
+.
.IP "\(bu" 4
Define \fBGem\.refresh\fR to be a no\-op, since the source index is always frozen when using bundler, and to prevent gems from the system leaking into the environment
+.
.IP "\(bu" 4
Override \fBGem\.bin_path\fR to use the gems in the bundle, making system executables work
+.
.IP "\(bu" 4
Add all gems in the bundle into Gem\.loaded_specs
+.
.IP "" 0
+.
.P
-Finally, \fBbundle exec\fR also implicitly modifies \fBGemfile\.lock\fR if the lockfile and the Gemfile do not match\. Bundler needs the Gemfile to determine things such as a gem's groups, \fBautorequire\fR, and platforms, etc\., and that information isn't stored in the lockfile\. The Gemfile and lockfile must be synced in order to \fBbundle exec\fR successfully, so \fBbundle exec\fR updates the lockfile beforehand\.
+Finally, \fBbundle exec\fR also implicitly modifies \fBGemfile\.lock\fR if the lockfile and the Gemfile do not match\. Bundler needs the Gemfile to determine things such as a gem\'s groups, \fBautorequire\fR, and platforms, etc\., and that information isn\'t stored in the lockfile\. The Gemfile and lockfile must be synced in order to \fBbundle exec\fR successfully, so \fBbundle exec\fR updates the lockfile beforehand\.
+.
.SS "Loading"
By default, when attempting to \fBbundle exec\fR to a file with a ruby shebang, Bundler will \fBKernel\.load\fR that file instead of using \fBKernel\.exec\fR\. For the vast majority of cases, this is a performance improvement\. In a rare few cases, this could cause some subtle side\-effects (such as dependence on the exact contents of \fB$0\fR or \fB__FILE__\fR) and the optimization can be disabled by enabling the \fBdisable_exec_load\fR setting\.
+.
.SS "Shelling out"
-Any Ruby code that opens a subshell (like \fBsystem\fR, backticks, or \fB%x{}\fR) will automatically use the current Bundler environment\. If you need to shell out to a Ruby command that is not part of your current bundle, use the \fBwith_unbundled_env\fR method with a block\. Any subshells created inside the block will be given the environment present before Bundler was activated\. For example, Homebrew commands run Ruby, but don't work inside a bundle:
+Any Ruby code that opens a subshell (like \fBsystem\fR, backticks, or \fB%x{}\fR) will automatically use the current Bundler environment\. If you need to shell out to a Ruby command that is not part of your current bundle, use the \fBwith_unbundled_env\fR method with a block\. Any subshells created inside the block will be given the environment present before Bundler was activated\. For example, Homebrew commands run Ruby, but don\'t work inside a bundle:
+.
.IP "" 4
+.
.nf
+
Bundler\.with_unbundled_env do
`brew install wget`
end
+.
.fi
+.
.IP "" 0
+.
.P
Using \fBwith_unbundled_env\fR is also necessary if you are shelling out to a different bundle\. Any Bundler commands run in a subshell will inherit the current Gemfile, so commands that need to run in the context of a different bundle also need to use \fBwith_unbundled_env\fR\.
+.
.IP "" 4
+.
.nf
+
Bundler\.with_unbundled_env do
Dir\.chdir "/other/bundler/project" do
`bundle exec \./script`
end
end
+.
.fi
+.
.IP "" 0
+.
.P
Bundler provides convenience helpers that wrap \fBsystem\fR and \fBexec\fR, and they can be used like this:
+.
.IP "" 4
+.
.nf
-Bundler\.clean_system('brew install wget')
-Bundler\.clean_exec('brew install wget')
+
+Bundler\.clean_system(\'brew install wget\')
+Bundler\.clean_exec(\'brew install wget\')
+.
.fi
+.
.IP "" 0
+.
.SH "RUBYGEMS PLUGINS"
At present, the Rubygems plugin system requires all files named \fBrubygems_plugin\.rb\fR on the load path of \fIany\fR installed gem when any Ruby code requires \fBrubygems\.rb\fR\. This includes executables installed into the system, like \fBrails\fR, \fBrackup\fR, and \fBrspec\fR\.
+.
.P
Since Rubygems plugins can contain arbitrary Ruby code, they commonly end up activating themselves or their dependencies\.
+.
.P
For instance, the \fBgemcutter 0\.5\fR gem depended on \fBjson_pure\fR\. If you had that version of gemcutter installed (even if you \fIalso\fR had a newer version without this problem), Rubygems would activate \fBgemcutter 0\.5\fR and \fBjson_pure <latest>\fR\.
+.
.P
If your Gemfile(5) also contained \fBjson_pure\fR (or a gem with a dependency on \fBjson_pure\fR), the latest version on your system might conflict with the version in your Gemfile(5), or the snapshot version in your \fBGemfile\.lock\fR\.
+.
.P
If this happens, bundler will say:
+.
.IP "" 4
+.
.nf
+
You have already activated json_pure 1\.4\.6 but your Gemfile
requires json_pure 1\.4\.3\. Consider using bundle exec\.
+.
.fi
+.
.IP "" 0
+.
.P
In this situation, you almost certainly want to remove the underlying gem with the problematic gem plugin\. In general, the authors of these plugins (in this case, the \fBgemcutter\fR gem) have released newer versions that are more careful in their plugins\.
+.
.P
You can find a list of all the gems containing gem plugins by running
+.
.IP "" 4
+.
.nf
-ruby \-e "puts Gem\.find_files('rubygems_plugin\.rb')"
+
+ruby \-e "puts Gem\.find_files(\'rubygems_plugin\.rb\')"
+.
.fi
+.
.IP "" 0
+.
.P
-At the very least, you should remove all but the newest version of each gem plugin, and also remove all gem plugins that you aren't using (\fBgem uninstall gem_name\fR)\.
+At the very least, you should remove all but the newest version of each gem plugin, and also remove all gem plugins that you aren\'t using (\fBgem uninstall gem_name\fR)\.
diff --git a/lib/bundler/man/bundle-exec.1.ronn b/lib/bundler/man/bundle-exec.1.ronn
index 9d5b559f26..05948095e2 100644
--- a/lib/bundler/man/bundle-exec.1.ronn
+++ b/lib/bundler/man/bundle-exec.1.ronn
@@ -21,8 +21,9 @@ available on your shell's `$PATH`.
## OPTIONS
* `--keep-file-descriptors`:
- Passes all file descriptors to the new processes. Default is true from
- bundler version 2.2.26. Setting it to false is now deprecated.
+ Exec in Ruby 2.0 began discarding non-standard file descriptors. When this
+ flag is passed, exec will revert to the 1.9 behaviour of passing all file
+ descriptors to the new process.
## BUNDLE INSTALL --BINSTUBS
diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1
index 5df7b0ef2f..8339b727ce 100644
--- a/lib/bundler/man/bundle-gem.1
+++ b/lib/bundler/man/bundle-gem.1
@@ -1,69 +1,105 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-GEM" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-GEM" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
+.
.SH "SYNOPSIS"
\fBbundle gem\fR \fIGEM_NAME\fR \fIOPTIONS\fR
+.
.SH "DESCRIPTION"
Generates a directory named \fBGEM_NAME\fR with a \fBRakefile\fR, \fBGEM_NAME\.gemspec\fR, and other supporting files and directories that can be used to develop a rubygem with that name\.
+.
.P
Run \fBrake \-T\fR in the resulting project for a list of Rake tasks that can be used to test and publish the gem to rubygems\.org\.
+.
.P
-The generated project skeleton can be customized with OPTIONS, as explained below\. Note that these options can also be specified via Bundler's global configuration file using the following names:
+The generated project skeleton can be customized with OPTIONS, as explained below\. Note that these options can also be specified via Bundler\'s global configuration file using the following names:
+.
.IP "\(bu" 4
\fBgem\.coc\fR
+.
.IP "\(bu" 4
\fBgem\.mit\fR
+.
.IP "\(bu" 4
\fBgem\.test\fR
+.
.IP "" 0
+.
.SH "OPTIONS"
+.
.IP "\(bu" 4
\fB\-\-exe\fR or \fB\-b\fR or \fB\-\-bin\fR: Specify that Bundler should create a binary executable (as \fBexe/GEM_NAME\fR) in the generated rubygem project\. This binary will also be added to the \fBGEM_NAME\.gemspec\fR manifest\. This behavior is disabled by default\.
+.
.IP "\(bu" 4
\fB\-\-no\-exe\fR: Do not create a binary (overrides \fB\-\-exe\fR specified in the global config)\.
+.
.IP "\(bu" 4
-\fB\-\-coc\fR: Add a \fBCODE_OF_CONDUCT\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\.
+\fB\-\-coc\fR: Add a \fBCODE_OF_CONDUCT\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
.IP "\(bu" 4
\fB\-\-no\-coc\fR: Do not create a \fBCODE_OF_CONDUCT\.md\fR (overrides \fB\-\-coc\fR specified in the global config)\.
+.
.IP "\(bu" 4
\fB\-\-ext=c\fR, \fB\-\-ext=rust\fR Add boilerplate for C or Rust (currently magnus \fIhttps://docs\.rs/magnus\fR based) extension code to the generated project\. This behavior is disabled by default\.
+.
.IP "\(bu" 4
\fB\-\-no\-ext\fR: Do not add extension code (overrides \fB\-\-ext\fR specified in the global config)\.
+.
.IP "\(bu" 4
-\fB\-\-mit\fR: Add an MIT license to a \fBLICENSE\.txt\fR file in the root of the generated project\. Your name from the global git config is used for the copyright statement\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\.
+\fB\-\-mit\fR: Add an MIT license to a \fBLICENSE\.txt\fR file in the root of the generated project\. Your name from the global git config is used for the copyright statement\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
.IP "\(bu" 4
\fB\-\-no\-mit\fR: Do not create a \fBLICENSE\.txt\fR (overrides \fB\-\-mit\fR specified in the global config)\.
+.
.IP "\(bu" 4
\fB\-t\fR, \fB\-\-test=minitest\fR, \fB\-\-test=rspec\fR, \fB\-\-test=test\-unit\fR: Specify the test framework that Bundler should use when generating the project\. Acceptable values are \fBminitest\fR, \fBrspec\fR and \fBtest\-unit\fR\. The \fBGEM_NAME\.gemspec\fR will be configured and a skeleton test/spec directory will be created based on this option\. Given no option is specified:
+.
.IP
-When Bundler is configured to generate tests, this defaults to Bundler's global config setting \fBgem\.test\fR\.
+When Bundler is configured to generate tests, this defaults to Bundler\'s global config setting \fBgem\.test\fR\.
+.
.IP
When Bundler is configured to not generate tests, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
.IP
-When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\.
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
.IP "\(bu" 4
\fB\-\-ci\fR, \fB\-\-ci=github\fR, \fB\-\-ci=gitlab\fR, \fB\-\-ci=circle\fR: Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
+.
.IP
-When Bundler is configured to generate CI files, this defaults to Bundler's global config setting \fBgem\.ci\fR\.
+When Bundler is configured to generate CI files, this defaults to Bundler\'s global config setting \fBgem\.ci\fR\.
+.
.IP
When Bundler is configured to not generate CI files, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
.IP
-When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\.
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
.IP "\(bu" 4
-\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR: Specify the linter and code formatter that Bundler should add to the project's development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
+\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR: Specify the linter and code formatter that Bundler should add to the project\'s development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
+.
.IP
-When Bundler is configured to add a linter, this defaults to Bundler's global config setting \fBgem\.linter\fR\.
+When Bundler is configured to add a linter, this defaults to Bundler\'s global config setting \fBgem\.linter\fR\.
+.
.IP
When Bundler is configured not to add a linter, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
.IP
-When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\.
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
.IP "\(bu" 4
\fB\-e\fR, \fB\-\-edit[=EDITOR]\fR: Open the resulting GEM_NAME\.gemspec in EDITOR, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\.
+.
.IP "" 0
+.
.SH "SEE ALSO"
+.
.IP "\(bu" 4
bundle config(1) \fIbundle\-config\.1\.html\fR
+.
.IP "" 0
diff --git a/lib/bundler/man/bundle-help.1 b/lib/bundler/man/bundle-help.1
index a3e7c7770d..9787c2d49f 100644
--- a/lib/bundler/man/bundle-help.1
+++ b/lib/bundler/man/bundle-help.1
@@ -1,9 +1,13 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-HELP" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-HELP" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-help\fR \- Displays detailed help for each subcommand
+.
.SH "SYNOPSIS"
\fBbundle help\fR [COMMAND]
+.
.SH "DESCRIPTION"
Displays detailed help for the given subcommand\. You can specify a single \fBCOMMAND\fR at the same time\. When \fBCOMMAND\fR is omitted, help for \fBhelp\fR command will be displayed\.
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
index a3d7ff0988..2cced71520 100644
--- a/lib/bundler/man/bundle-info.1
+++ b/lib/bundler/man/bundle-info.1
@@ -1,13 +1,19 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-INFO" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INFO" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle
+.
.SH "SYNOPSIS"
\fBbundle info\fR [GEM_NAME] [\-\-path]
+.
.SH "DESCRIPTION"
Given a gem name present in your bundle, print the basic information about it such as homepage, version, path and summary\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-path\fR
Print the path of the given gem
diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1
index a0edaaa18f..c7a9a155b5 100644
--- a/lib/bundler/man/bundle-init.1
+++ b/lib/bundler/man/bundle-init.1
@@ -1,20 +1,29 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-INIT" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INIT" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
+.
.SH "SYNOPSIS"
\fBbundle init\fR [\-\-gemspec=FILE]
+.
.SH "DESCRIPTION"
Init generates a default [\fBGemfile(5)\fR][Gemfile(5)] in the current working directory\. When adding a [\fBGemfile(5)\fR][Gemfile(5)] to a gem with a gemspec, the \fB\-\-gemspec\fR option will automatically add each dependency listed in the gemspec file to the newly created [\fBGemfile(5)\fR][Gemfile(5)]\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-gemspec\fR
Use the specified \.gemspec to create the [\fBGemfile(5)\fR][Gemfile(5)]
+.
.TP
\fB\-\-gemfile\fR
Use the specified name for the gemfile instead of \fBGemfile\fR
+.
.SH "FILES"
Included in the default [\fBGemfile(5)\fR][Gemfile(5)] generated is the line \fB# frozen_string_literal: true\fR\. This is a magic comment supported for the first time in Ruby 2\.3\. The presence of this line results in all string literals in the file being implicitly frozen\.
+.
.SH "SEE ALSO"
Gemfile(5) \fIhttps://bundler\.io/man/gemfile\.5\.html\fR
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
index 7a1038206e..9e25c29085 100644
--- a/lib/bundler/man/bundle-inject.1
+++ b/lib/bundler/man/bundle-inject.1
@@ -1,23 +1,36 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-INJECT" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INJECT" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
+.
.SH "SYNOPSIS"
\fBbundle inject\fR [GEM] [VERSION]
+.
.SH "DESCRIPTION"
Adds the named gem(s) with their version requirements to the resolved [\fBGemfile(5)\fR][Gemfile(5)]\.
+.
.P
-This command will add the gem to both your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock if it isn't listed yet\.
+This command will add the gem to both your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock if it isn\'t listed yet\.
+.
.P
Example:
+.
.IP "" 4
+.
.nf
+
bundle install
-bundle inject 'rack' '> 0'
+bundle inject \'rack\' \'> 0\'
+.
.fi
+.
.IP "" 0
+.
.P
-This will inject the 'rack' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock\.
+This will inject the \'rack\' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock\.
+.
.P
The \fBbundle inject\fR command was deprecated in Bundler 2\.1 and will be removed in Bundler 3\.0\.
diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1
index cc46a03b7f..337683af06 100644
--- a/lib/bundler/man/bundle-install.1
+++ b/lib/bundler/man/bundle-install.1
@@ -1,215 +1,313 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-INSTALL" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-INSTALL" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
+.
.SH "SYNOPSIS"
-\fBbundle install\fR [\-\-binstubs[=DIRECTORY]] [\-\-clean] [\-\-deployment] [\-\-frozen] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-no\-cache] [\-\-no\-prune] [\-\-path PATH] [\-\-prefer\-local] [\-\-quiet] [\-\-redownload] [\-\-retry=NUMBER] [\-\-shebang] [\-\-standalone[=GROUP[ GROUP\|\.\|\.\|\.]]] [\-\-system] [\-\-trust\-policy=POLICY] [\-\-with=GROUP[ GROUP\|\.\|\.\|\.]] [\-\-without=GROUP[ GROUP\|\.\|\.\|\.]]
+\fBbundle install\fR [\-\-binstubs[=DIRECTORY]] [\-\-clean] [\-\-deployment] [\-\-frozen] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-no\-cache] [\-\-no\-prune] [\-\-path PATH] [\-\-quiet] [\-\-redownload] [\-\-retry=NUMBER] [\-\-shebang] [\-\-standalone[=GROUP[ GROUP\.\.\.]]] [\-\-system] [\-\-trust\-policy=POLICY] [\-\-with=GROUP[ GROUP\.\.\.]] [\-\-without=GROUP[ GROUP\.\.\.]]
+.
.SH "DESCRIPTION"
Install the gems specified in your Gemfile(5)\. If this is the first time you run bundle install (and a \fBGemfile\.lock\fR does not exist), Bundler will fetch all remote sources, resolve dependencies and install all needed gems\.
+.
.P
If a \fBGemfile\.lock\fR does exist, and you have not updated your Gemfile(5), Bundler will fetch all remote sources, but use the dependencies specified in the \fBGemfile\.lock\fR instead of resolving dependencies\.
+.
.P
If a \fBGemfile\.lock\fR does exist, and you have updated your Gemfile(5), Bundler will use the dependencies in the \fBGemfile\.lock\fR for all gems that you did not update, but will re\-resolve the dependencies of gems that you did update\. You can find more information about this update process below under \fICONSERVATIVE UPDATING\fR\.
+.
.SH "OPTIONS"
The \fB\-\-clean\fR, \fB\-\-deployment\fR, \fB\-\-frozen\fR, \fB\-\-no\-prune\fR, \fB\-\-path\fR, \fB\-\-shebang\fR, \fB\-\-system\fR, \fB\-\-without\fR and \fB\-\-with\fR options are deprecated because they only make sense if they are applied to every subsequent \fBbundle install\fR run automatically and that requires \fBbundler\fR to silently remember them\. Since \fBbundler\fR will no longer remember CLI flags in future versions, \fBbundle config\fR (see bundle\-config(1)) should be used to apply them permanently\.
+.
.TP
\fB\-\-binstubs[=<directory>]\fR
Binstubs are scripts that wrap around executables\. Bundler creates a small Ruby file (a binstub) that loads Bundler, runs the command, and puts it in \fBbin/\fR\. This lets you link the binstub inside of an application to the exact gem version the application needs\.
+.
.IP
-Creates a directory (defaults to \fB~/bin\fR) and places any executables from the gem there\. These executables run in Bundler's context\. If used, you might add this directory to your environment's \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
+Creates a directory (defaults to \fB~/bin\fR) and places any executables from the gem there\. These executables run in Bundler\'s context\. If used, you might add this directory to your environment\'s \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
+.
.TP
\fB\-\-clean\fR
-On finishing the installation Bundler is going to remove any gems not present in the current Gemfile(5)\. Don't worry, gems currently in use will not be removed\.
+On finishing the installation Bundler is going to remove any gems not present in the current Gemfile(5)\. Don\'t worry, gems currently in use will not be removed\.
+.
.IP
This option is deprecated in favor of the \fBclean\fR setting\.
+.
.TP
\fB\-\-deployment\fR
-In \fIdeployment mode\fR, Bundler will 'roll\-out' the bundle for production or CI use\. Please check carefully if you want to have this option enabled in your development environment\.
+In \fIdeployment mode\fR, Bundler will \'roll\-out\' the bundle for production or CI use\. Please check carefully if you want to have this option enabled in your development environment\.
+.
.IP
This option is deprecated in favor of the \fBdeployment\fR setting\.
+.
.TP
\fB\-\-redownload\fR
Force download every gem, even if the required versions are already available locally\.
+.
.TP
\fB\-\-frozen\fR
Do not allow the Gemfile\.lock to be updated after this install\. Exits non\-zero if there are going to be changes to the Gemfile\.lock\.
+.
.IP
This option is deprecated in favor of the \fBfrozen\fR setting\.
+.
.TP
\fB\-\-full\-index\fR
-Bundler will not call Rubygems' API endpoint (default) but download and cache a (currently big) index file of all gems\. Performance can be improved for large bundles that seldom change by enabling this option\.
+Bundler will not call Rubygems\' API endpoint (default) but download and cache a (currently big) index file of all gems\. Performance can be improved for large bundles that seldom change by enabling this option\.
+.
.TP
\fB\-\-gemfile=<gemfile>\fR
-The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project's root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\.
+The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project\'s root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\.
+.
.TP
\fB\-\-jobs=[<number>]\fR, \fB\-j[<number>]\fR
The maximum number of parallel download and install jobs\. The default is the number of available processors\.
+.
.TP
\fB\-\-local\fR
-Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
+Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
+.
.TP
\fB\-\-prefer\-local\fR
-Force using locally installed gems, or gems already present in Rubygems' cache or in \fBvendor/cache\fR, when resolving, even if newer versions are available remotely\. Only attempt to connect to \fBrubygems\.org\fR for gems that are not present locally\.
+Force using locally installed gems, or gems already present in Rubygems\' cache or in \fBvendor/cache\fR, when resolving, even if newer versions are available remotely\. Only attempt to connect to \fBrubygems\.org\fR for gems that are not present locally\.
+.
.TP
\fB\-\-no\-cache\fR
Do not update the cache in \fBvendor/cache\fR with the newly bundled gems\. This does not remove any gems in the cache but keeps the newly bundled gems from being cached during the install\.
+.
.TP
\fB\-\-no\-prune\fR
-Don't remove stale gems from the cache when the installation finishes\.
+Don\'t remove stale gems from the cache when the installation finishes\.
+.
.IP
This option is deprecated in favor of the \fBno_prune\fR setting\.
+.
.TP
\fB\-\-path=<path>\fR
-The location to install the specified gems to\. This defaults to Rubygems' setting\. Bundler shares this location with Rubygems, \fBgem install \|\.\|\.\|\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \|\.\|\.\|\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
+The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
+.
.IP
This option is deprecated in favor of the \fBpath\fR setting\.
+.
.TP
\fB\-\-quiet\fR
Do not print progress information to the standard output\. Instead, Bundler will exit using a status code (\fB$?\fR)\.
+.
.TP
\fB\-\-retry=[<number>]\fR
Retry failed network or git requests for \fInumber\fR times\.
+.
.TP
\fB\-\-shebang=<ruby\-executable>\fR
Uses the specified ruby executable (usually \fBruby\fR) to execute the scripts created with \fB\-\-binstubs\fR\. In addition, if you use \fB\-\-binstubs\fR together with \fB\-\-shebang jruby\fR these executables will be changed to execute \fBjruby\fR instead\.
+.
.IP
This option is deprecated in favor of the \fBshebang\fR setting\.
+.
.TP
\fB\-\-standalone[=<list>]\fR
-Makes a bundle that can work without depending on Rubygems or Bundler at runtime\. A space separated list of groups to install has to be specified\. Bundler creates a directory named \fBbundle\fR and installs the bundle there\. It also generates a \fBbundle/bundler/setup\.rb\fR file to replace Bundler's own setup in the manner required\. Using this option implicitly sets \fBpath\fR, which is a [remembered option][REMEMBERED OPTIONS]\.
+Makes a bundle that can work without depending on Rubygems or Bundler at runtime\. A space separated list of groups to install has to be specified\. Bundler creates a directory named \fBbundle\fR and installs the bundle there\. It also generates a \fBbundle/bundler/setup\.rb\fR file to replace Bundler\'s own setup in the manner required\. Using this option implicitly sets \fBpath\fR, which is a [remembered option][REMEMBERED OPTIONS]\.
+.
.TP
\fB\-\-system\fR
-Installs the gems specified in the bundle to the system's Rubygems location\. This overrides any previous configuration of \fB\-\-path\fR\.
+Installs the gems specified in the bundle to the system\'s Rubygems location\. This overrides any previous configuration of \fB\-\-path\fR\.
+.
.IP
This option is deprecated in favor of the \fBsystem\fR setting\.
+.
.TP
\fB\-\-trust\-policy=[<policy>]\fR
Apply the Rubygems security policy \fIpolicy\fR, where policy is one of \fBHighSecurity\fR, \fBMediumSecurity\fR, \fBLowSecurity\fR, \fBAlmostNoSecurity\fR, or \fBNoSecurity\fR\. For more details, please see the Rubygems signing documentation linked below in \fISEE ALSO\fR\.
+.
.TP
\fB\-\-with=<list>\fR
A space\-separated list of groups referencing gems to install\. If an optional group is given it is installed\. If a group is given that is in the remembered list of groups given to \-\-without, it is removed from that list\.
+.
.IP
This option is deprecated in favor of the \fBwith\fR setting\.
+.
.TP
\fB\-\-without=<list>\fR
A space\-separated list of groups referencing gems to skip during installation\. If a group is given that is in the remembered list of groups given to \-\-with, it is removed from that list\.
+.
.IP
This option is deprecated in favor of the \fBwithout\fR setting\.
+.
.SH "DEPLOYMENT MODE"
-Bundler's defaults are optimized for development\. To switch to defaults optimized for deployment and for CI, use the \fB\-\-deployment\fR flag\. Do not activate deployment mode on development machines, as it will cause an error when the Gemfile(5) is modified\.
+Bundler\'s defaults are optimized for development\. To switch to defaults optimized for deployment and for CI, use the \fB\-\-deployment\fR flag\. Do not activate deployment mode on development machines, as it will cause an error when the Gemfile(5) is modified\.
+.
.IP "1." 4
A \fBGemfile\.lock\fR is required\.
+.
.IP
To ensure that the same versions of the gems you developed with and tested with are also used in deployments, a \fBGemfile\.lock\fR is required\.
+.
.IP
This is mainly to ensure that you remember to check your \fBGemfile\.lock\fR into version control\.
+.
.IP "2." 4
The \fBGemfile\.lock\fR must be up to date
+.
.IP
In development, you can modify your Gemfile(5) and re\-run \fBbundle install\fR to \fIconservatively update\fR your \fBGemfile\.lock\fR snapshot\.
+.
.IP
In deployment, your \fBGemfile\.lock\fR should be up\-to\-date with changes made in your Gemfile(5)\.
+.
.IP "3." 4
Gems are installed to \fBvendor/bundle\fR not your default system location
+.
.IP
-In development, it's convenient to share the gems used in your application with other applications and other scripts that run on the system\.
+In development, it\'s convenient to share the gems used in your application with other applications and other scripts that run on the system\.
+.
.IP
In deployment, isolation is a more important default\. In addition, the user deploying the application may not have permission to install gems to the system, or the web server may not have permission to read them\.
+.
.IP
As a result, \fBbundle install \-\-deployment\fR installs gems to the \fBvendor/bundle\fR directory in the application\. This may be overridden using the \fB\-\-path\fR option\.
+.
.IP "" 0
+.
.SH "INSTALLING GROUPS"
By default, \fBbundle install\fR will install all gems in all groups in your Gemfile(5), except those declared for a different platform\.
+.
.P
However, you can explicitly tell Bundler to skip installing certain groups with the \fB\-\-without\fR option\. This option takes a space\-separated list of groups\.
+.
.P
While the \fB\-\-without\fR option will skip \fIinstalling\fR the gems in the specified groups, it will still \fIdownload\fR those gems and use them to resolve the dependencies of every gem in your Gemfile(5)\.
+.
.P
This is so that installing a different set of groups on another machine (such as a production server) will not change the gems and versions that you have already developed and tested against\.
+.
.P
\fBBundler offers a rock\-solid guarantee that the third\-party code you are running in development and testing is also the third\-party code you are running in production\. You can choose to exclude some of that code in different environments, but you will never be caught flat\-footed by different versions of third\-party code being used in different environments\.\fR
+.
.P
For a simple illustration, consider the following Gemfile(5):
+.
.IP "" 4
+.
.nf
-source 'https://rubygems\.org'
-gem 'sinatra'
+source \'https://rubygems\.org\'
+
+gem \'sinatra\'
group :production do
- gem 'rack\-perftools\-profiler'
+ gem \'rack\-perftools\-profiler\'
end
+.
.fi
+.
.IP "" 0
+.
.P
In this case, \fBsinatra\fR depends on any version of Rack (\fB>= 1\.0\fR), while \fBrack\-perftools\-profiler\fR depends on 1\.x (\fB~> 1\.0\fR)\.
+.
.P
When you run \fBbundle install \-\-without production\fR in development, we look at the dependencies of \fBrack\-perftools\-profiler\fR as well\. That way, you do not spend all your time developing against Rack 2\.0, using new APIs unavailable in Rack 1\.x, only to have Bundler switch to Rack 1\.2 when the \fBproduction\fR group \fIis\fR used\.
+.
.P
This should not cause any problems in practice, because we do not attempt to \fBinstall\fR the gems in the excluded groups, and only evaluate as part of the dependency resolution process\.
+.
.P
This also means that you cannot include different versions of the same gem in different groups, because doing so would result in different sets of dependencies used in development and production\. Because of the vagaries of the dependency resolution process, this usually affects more than the gems you list in your Gemfile(5), and can (surprisingly) radically change the gems you are using\.
+.
.SH "THE GEMFILE\.LOCK"
When you run \fBbundle install\fR, Bundler will persist the full names and versions of all gems that you used (including dependencies of the gems specified in the Gemfile(5)) into a file called \fBGemfile\.lock\fR\.
+.
.P
Bundler uses this file in all subsequent calls to \fBbundle install\fR, which guarantees that you always use the same exact code, even as your application moves across machines\.
+.
.P
Because of the way dependency resolution works, even a seemingly small change (for instance, an update to a point\-release of a dependency of a gem in your Gemfile(5)) can result in radically different gems being needed to satisfy all dependencies\.
+.
.P
As a result, you \fBSHOULD\fR check your \fBGemfile\.lock\fR into version control, in both applications and gems\. If you do not, every machine that checks out your repository (including your production server) will resolve all dependencies again, which will result in different versions of third\-party code being used if \fBany\fR of the gems in the Gemfile(5) or any of their dependencies have been updated\.
+.
.P
When Bundler first shipped, the \fBGemfile\.lock\fR was included in the \fB\.gitignore\fR file included with generated gems\. Over time, however, it became clear that this practice forces the pain of broken dependencies onto new contributors, while leaving existing contributors potentially unaware of the problem\. Since \fBbundle install\fR is usually the first step towards a contribution, the pain of broken dependencies would discourage new contributors from contributing\. As a result, we have revised our guidance for gem authors to now recommend checking in the lock for gems\.
+.
.SH "CONSERVATIVE UPDATING"
When you make a change to the Gemfile(5) and then run \fBbundle install\fR, Bundler will update only the gems that you modified\.
+.
.P
In other words, if a gem that you \fBdid not modify\fR worked before you called \fBbundle install\fR, it will continue to use the exact same versions of all dependencies as it used before the update\.
+.
.P
-Let's take a look at an example\. Here's your original Gemfile(5):
+Let\'s take a look at an example\. Here\'s your original Gemfile(5):
+.
.IP "" 4
+.
.nf
-source 'https://rubygems\.org'
-gem 'actionpack', '2\.3\.8'
-gem 'activemerchant'
+source \'https://rubygems\.org\'
+
+gem \'actionpack\', \'2\.3\.8\'
+gem \'activemerchant\'
+.
.fi
+.
.IP "" 0
+.
.P
In this case, both \fBactionpack\fR and \fBactivemerchant\fR depend on \fBactivesupport\fR\. The \fBactionpack\fR gem depends on \fBactivesupport 2\.3\.8\fR and \fBrack ~> 1\.1\.0\fR, while the \fBactivemerchant\fR gem depends on \fBactivesupport >= 2\.3\.2\fR, \fBbraintree >= 2\.0\.0\fR, and \fBbuilder >= 2\.0\.0\fR\.
+.
.P
When the dependencies are first resolved, Bundler will select \fBactivesupport 2\.3\.8\fR, which satisfies the requirements of both gems in your Gemfile(5)\.
+.
.P
Next, you modify your Gemfile(5) to:
+.
.IP "" 4
+.
.nf
-source 'https://rubygems\.org'
-gem 'actionpack', '3\.0\.0\.rc'
-gem 'activemerchant'
+source \'https://rubygems\.org\'
+
+gem \'actionpack\', \'3\.0\.0\.rc\'
+gem \'activemerchant\'
+.
.fi
+.
.IP "" 0
+.
.P
The \fBactionpack 3\.0\.0\.rc\fR gem has a number of new dependencies, and updates the \fBactivesupport\fR dependency to \fB= 3\.0\.0\.rc\fR and the \fBrack\fR dependency to \fB~> 1\.2\.1\fR\.
+.
.P
When you run \fBbundle install\fR, Bundler notices that you changed the \fBactionpack\fR gem, but not the \fBactivemerchant\fR gem\. It evaluates the gems currently being used to satisfy its requirements:
+.
.TP
\fBactivesupport 2\.3\.8\fR
also used to satisfy a dependency in \fBactivemerchant\fR, which is not being updated
+.
.TP
\fBrack ~> 1\.1\.0\fR
not currently being used to satisfy another dependency
+.
.P
Because you did not explicitly ask to update \fBactivemerchant\fR, you would not expect it to suddenly stop working after updating \fBactionpack\fR\. However, satisfying the new \fBactivesupport 3\.0\.0\.rc\fR dependency of actionpack requires updating one of its dependencies\.
+.
.P
Even though \fBactivemerchant\fR declares a very loose dependency that theoretically matches \fBactivesupport 3\.0\.0\.rc\fR, Bundler treats gems in your Gemfile(5) that have not changed as an atomic unit together with their dependencies\. In this case, the \fBactivemerchant\fR dependency is treated as \fBactivemerchant 1\.7\.1 + activesupport 2\.3\.8\fR, so \fBbundle install\fR will report that it cannot update \fBactionpack\fR\.
+.
.P
To explicitly update \fBactionpack\fR, including its dependencies which other gems in the Gemfile(5) still depend on, run \fBbundle update actionpack\fR (see \fBbundle update(1)\fR)\.
+.
.P
\fBSummary\fR: In general, after making a change to the Gemfile(5) , you should first try to run \fBbundle install\fR, which will guarantee that no other gem in the Gemfile(5) is impacted by the change\. If that does not work, run bundle update(1) \fIbundle\-update\.1\.html\fR\.
+.
.SH "SEE ALSO"
+.
.IP "\(bu" 4
-Gem install docs \fIhttps://guides\.rubygems\.org/rubygems\-basics/#installing\-gems\fR
+Gem install docs \fIhttp://guides\.rubygems\.org/rubygems\-basics/#installing\-gems\fR
+.
.IP "\(bu" 4
-Rubygems signing docs \fIhttps://guides\.rubygems\.org/security/\fR
+Rubygems signing docs \fIhttp://guides\.rubygems\.org/security/\fR
+.
.IP "" 0
diff --git a/lib/bundler/man/bundle-install.1.ronn b/lib/bundler/man/bundle-install.1.ronn
index ed8169de05..be9ed0f974 100644
--- a/lib/bundler/man/bundle-install.1.ronn
+++ b/lib/bundler/man/bundle-install.1.ronn
@@ -14,7 +14,6 @@ bundle-install(1) -- Install the dependencies specified in your Gemfile
[--no-cache]
[--no-prune]
[--path PATH]
- [--prefer-local]
[--quiet]
[--redownload]
[--retry=NUMBER]
@@ -379,5 +378,5 @@ does not work, run [bundle update(1)](bundle-update.1.html).
## SEE ALSO
-* [Gem install docs](https://guides.rubygems.org/rubygems-basics/#installing-gems)
-* [Rubygems signing docs](https://guides.rubygems.org/security/)
+* [Gem install docs](http://guides.rubygems.org/rubygems-basics/#installing-gems)
+* [Rubygems signing docs](http://guides.rubygems.org/security/)
diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1
index 21723608cc..1680e6007a 100644
--- a/lib/bundler/man/bundle-list.1
+++ b/lib/bundler/man/bundle-list.1
@@ -1,34 +1,49 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-LIST" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-LIST" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle
+.
.SH "SYNOPSIS"
-\fBbundle list\fR [\-\-name\-only] [\-\-paths] [\-\-without\-group=GROUP[ GROUP\|\.\|\.\|\.]] [\-\-only\-group=GROUP[ GROUP\|\.\|\.\|\.]]
+\fBbundle list\fR [\-\-name\-only] [\-\-paths] [\-\-without\-group=GROUP[ GROUP\.\.\.]] [\-\-only\-group=GROUP[ GROUP\.\.\.]]
+.
.SH "DESCRIPTION"
Prints a list of all the gems in the bundle including their version\.
+.
.P
Example:
+.
.P
bundle list \-\-name\-only
+.
.P
bundle list \-\-paths
+.
.P
bundle list \-\-without\-group test
+.
.P
bundle list \-\-only\-group dev
+.
.P
bundle list \-\-only\-group dev test \-\-paths
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-name\-only\fR
Print only the name of each gem\.
+.
.TP
\fB\-\-paths\fR
Print the path to each gem in the bundle\.
+.
.TP
\fB\-\-without\-group=<list>\fR
A space\-separated list of groups of gems to skip during printing\.
+.
.TP
\fB\-\-only\-group=<list>\fR
A space\-separated list of groups of gems to print\.
diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1
index 8b81b7732f..8722c44b3d 100644
--- a/lib/bundler/man/bundle-lock.1
+++ b/lib/bundler/man/bundle-lock.1
@@ -1,60 +1,84 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-LOCK" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-LOCK" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
+.
.SH "SYNOPSIS"
\fBbundle lock\fR [\-\-update] [\-\-local] [\-\-print] [\-\-lockfile=PATH] [\-\-full\-index] [\-\-add\-platform] [\-\-remove\-platform] [\-\-patch] [\-\-minor] [\-\-major] [\-\-strict] [\-\-conservative]
+.
.SH "DESCRIPTION"
Lock the gems specified in Gemfile\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-update=<*gems>\fR
Ignores the existing lockfile\. Resolve then updates lockfile\. Taking a list of gems or updating all gems if no list is given\.
+.
.TP
\fB\-\-local\fR
-Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems' cache or in \fBvendor/cache\fR\. Note that if a appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
+Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if a appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
+.
.TP
\fB\-\-print\fR
Prints the lockfile to STDOUT instead of writing to the file system\.
+.
.TP
\fB\-\-lockfile=<path>\fR
The path where the lockfile should be written to\.
+.
.TP
\fB\-\-full\-index\fR
Fall back to using the single\-file index of all gems\.
+.
.TP
\fB\-\-add\-platform\fR
Add a new platform to the lockfile, re\-resolving for the addition of that platform\.
+.
.TP
\fB\-\-remove\-platform\fR
Remove a platform from the lockfile\.
+.
.TP
\fB\-\-patch\fR
If updating, prefer updating only to next patch version\.
+.
.TP
\fB\-\-minor\fR
If updating, prefer updating only to next minor version\.
+.
.TP
\fB\-\-major\fR
If updating, prefer updating to next major version (default)\.
+.
.TP
\fB\-\-strict\fR
If updating, do not allow any gem to be updated past latest \-\-patch | \-\-minor | \-\-major\.
+.
.TP
\fB\-\-conservative\fR
If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated\.
+.
.SH "UPDATING ALL GEMS"
If you run \fBbundle lock\fR with \fB\-\-update\fR option without list of gems, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
+.
.SH "UPDATING A LIST OF GEMS"
Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\.
+.
.P
For instance, you only want to update \fBnokogiri\fR, run \fBbundle lock \-\-update nokogiri\fR\.
+.
.P
Bundler will update \fBnokogiri\fR and any of its dependencies, but leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\.
+.
.SH "SUPPORTING OTHER PLATFORMS"
-If you want your bundle to support platforms other than the one you're running locally, you can run \fBbundle lock \-\-add\-platform PLATFORM\fR to add PLATFORM to the lockfile, force bundler to re\-resolve and consider the new platform when picking gems, all without needing to have a machine that matches PLATFORM handy to install those platform\-specific gems on\.
+If you want your bundle to support platforms other than the one you\'re running locally, you can run \fBbundle lock \-\-add\-platform PLATFORM\fR to add PLATFORM to the lockfile, force bundler to re\-resolve and consider the new platform when picking gems, all without needing to have a machine that matches PLATFORM handy to install those platform\-specific gems on\.
+.
.P
For a full explanation of gem platforms, see \fBgem help platform\fR\.
+.
.SH "PATCH LEVEL OPTIONS"
See bundle update(1) \fIbundle\-update\.1\.html\fR for details\.
diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1
index 41a8804a09..3513f0d09b 100644
--- a/lib/bundler/man/bundle-open.1
+++ b/lib/bundler/man/bundle-open.1
@@ -1,31 +1,51 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-OPEN" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-OPEN" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
+.
.SH "SYNOPSIS"
\fBbundle open\fR [GEM] [\-\-path=PATH]
+.
.SH "DESCRIPTION"
Opens the source directory of the provided GEM in your editor\.
+.
.P
For this to work the \fBEDITOR\fR or \fBBUNDLER_EDITOR\fR environment variable has to be set\.
+.
.P
Example:
+.
.IP "" 4
+.
.nf
-bundle open 'rack'
+
+bundle open \'rack\'
+.
.fi
+.
.IP "" 0
+.
.P
-Will open the source directory for the 'rack' gem in your bundle\.
+Will open the source directory for the \'rack\' gem in your bundle\.
+.
.IP "" 4
+.
.nf
-bundle open 'rack' \-\-path 'README\.md'
+
+bundle open \'rack\' \-\-path \'README\.md\'
+.
.fi
+.
.IP "" 0
+.
.P
-Will open the README\.md file of the 'rack' gem source in your bundle\.
+Will open the README\.md file of the \'rack\' gem source in your bundle\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-path\fR
Specify GEM source relative path to open\.
diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1
index 838fce45cd..129ff00f58 100644
--- a/lib/bundler/man/bundle-outdated.1
+++ b/lib/bundler/man/bundle-outdated.1
@@ -1,100 +1,152 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-OUTDATED" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-OUTDATED" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available
+.
.SH "SYNOPSIS"
\fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit]
+.
.SH "DESCRIPTION"
Outdated lists the names and versions of gems that have a newer version available in the given source\. Calling outdated with [GEM [GEM]] will only check for newer versions of the given gems\. Prerelease gems are ignored by default\. If your gems are up to date, Bundler will exit with a status of 0\. Otherwise, it will exit 1\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-local\fR
Do not attempt to fetch gems remotely and use the gem cache instead\.
+.
.TP
\fB\-\-pre\fR
Check for newer pre\-release gems\.
+.
.TP
\fB\-\-source\fR
Check against a specific source\.
+.
.TP
\fB\-\-strict\fR
Only list newer versions allowed by your Gemfile requirements, also respecting conservative update flags (\-\-patch, \-\-minor, \-\-major)\.
+.
.TP
\fB\-\-parseable\fR, \fB\-\-porcelain\fR
Use minimal formatting for more parseable output\.
+.
.TP
\fB\-\-group\fR
List gems from a specific group\.
+.
.TP
\fB\-\-groups\fR
List gems organized by groups\.
+.
.TP
\fB\-\-minor\fR
Prefer updating only to next minor version\.
+.
.TP
\fB\-\-major\fR
Prefer updating to next major version (default)\.
+.
.TP
\fB\-\-patch\fR
Prefer updating only to next patch version\.
+.
.TP
\fB\-\-filter\-major\fR
Only list major newer versions\.
+.
.TP
\fB\-\-filter\-minor\fR
Only list minor newer versions\.
+.
.TP
\fB\-\-filter\-patch\fR
Only list patch newer versions\.
+.
.TP
\fB\-\-only\-explicit\fR
Only list gems specified in your Gemfile, not their dependencies\.
+.
.SH "PATCH LEVEL OPTIONS"
See bundle update(1) \fIbundle\-update\.1\.html\fR for details\.
+.
.SH "FILTERING OUTPUT"
The 3 filtering options do not affect the resolution of versions, merely what versions are shown in the output\.
+.
.P
If the regular output shows the following:
+.
.IP "" 4
+.
.nf
+
* Gem Current Latest Requested Groups
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
* hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default
* headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test
+.
.fi
+.
.IP "" 0
+.
.P
\fB\-\-filter\-major\fR would only show:
+.
.IP "" 4
+.
.nf
+
* Gem Current Latest Requested Groups
* hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default
+.
.fi
+.
.IP "" 0
+.
.P
\fB\-\-filter\-minor\fR would only show:
+.
.IP "" 4
+.
.nf
+
* Gem Current Latest Requested Groups
* headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test
+.
.fi
+.
.IP "" 0
+.
.P
\fB\-\-filter\-patch\fR would only show:
+.
.IP "" 4
+.
.nf
+
* Gem Current Latest Requested Groups
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
+.
.fi
+.
.IP "" 0
+.
.P
Filter options can be combined\. \fB\-\-filter\-minor\fR and \fB\-\-filter\-patch\fR would show:
+.
.IP "" 4
+.
.nf
+
* Gem Current Latest Requested Groups
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
+.
.fi
+.
.IP "" 0
+.
.P
Combining all three \fBfilter\fR options would be the same result as providing none of them\.
diff --git a/lib/bundler/man/bundle-outdated.1.ronn b/lib/bundler/man/bundle-outdated.1.ronn
index 4ac65d0532..27bf21ab9d 100644
--- a/lib/bundler/man/bundle-outdated.1.ronn
+++ b/lib/bundler/man/bundle-outdated.1.ronn
@@ -102,5 +102,4 @@ Filter options can be combined. `--filter-minor` and `--filter-patch` would show
* Gem Current Latest Requested Groups
* faker 1.6.5 1.6.6 ~> 1.4 development, test
-
Combining all three `filter` options would be the same result as providing none of them.
diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1
index 0dbce7a7a4..5021c46b4c 100644
--- a/lib/bundler/man/bundle-platform.1
+++ b/lib/bundler/man/bundle-platform.1
@@ -1,27 +1,41 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-PLATFORM" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-PLATFORM" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information
+.
.SH "SYNOPSIS"
\fBbundle platform\fR [\-\-ruby]
+.
.SH "DESCRIPTION"
\fBplatform\fR displays information from your Gemfile, Gemfile\.lock, and Ruby VM about your platform\.
+.
.P
For instance, using this Gemfile(5):
+.
.IP "" 4
+.
.nf
+
source "https://rubygems\.org"
ruby "3\.1\.2"
gem "rack"
+.
.fi
+.
.IP "" 0
+.
.P
If you run \fBbundle platform\fR on Ruby 3\.1\.2, it displays the following output:
+.
.IP "" 4
+.
.nf
+
Your platform is: x86_64\-linux
Your app has gems that work on these platforms:
@@ -34,16 +48,24 @@ Your Gemfile specifies a Ruby version requirement:
* ruby 3\.1\.2
Your current platform satisfies the Ruby version requirement\.
+.
.fi
+.
.IP "" 0
+.
.P
-\fBplatform\fR lists all the platforms in your \fBGemfile\.lock\fR as well as the \fBruby\fR directive if applicable from your Gemfile(5)\. It also lets you know if the \fBruby\fR directive requirement has been met\. If \fBruby\fR directive doesn't match the running Ruby VM, it tells you what part does not\.
+\fBplatform\fR lists all the platforms in your \fBGemfile\.lock\fR as well as the \fBruby\fR directive if applicable from your Gemfile(5)\. It also lets you know if the \fBruby\fR directive requirement has been met\. If \fBruby\fR directive doesn\'t match the running Ruby VM, it tells you what part does not\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-ruby\fR
-It will display the ruby directive information, so you don't have to parse it from the Gemfile(5)\.
+It will display the ruby directive information, so you don\'t have to parse it from the Gemfile(5)\.
+.
.SH "SEE ALSO"
+.
.IP "\(bu" 4
bundle\-lock(1) \fIbundle\-lock\.1\.html\fR
+.
.IP "" 0
diff --git a/lib/bundler/man/bundle-plugin.1 b/lib/bundler/man/bundle-plugin.1
index 1290abb3ba..ec30e1d0fd 100644
--- a/lib/bundler/man/bundle-plugin.1
+++ b/lib/bundler/man/bundle-plugin.1
@@ -1,58 +1,81 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-PLUGIN" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-PLUGIN" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-plugin\fR \- Manage Bundler plugins
+.
.SH "SYNOPSIS"
-\fBbundle plugin\fR install PLUGINS [\-\-source=\fISOURCE\fR] [\-\-version=\fIversion\fR] [\-\-git=\fIgit\-url\fR] [\-\-branch=\fIbranch\fR|\-\-ref=\fIrev\fR] [\-\-path=\fIpath\fR]
+\fBbundle plugin\fR install PLUGINS [\-\-source=\fISOURCE\fR] [\-\-version=\fIversion\fR] [\-\-git|\-\-local_git=\fIgit\-url\fR] [\-\-branch=\fIbranch\fR|\-\-ref=\fIrev\fR]
+.
.br
\fBbundle plugin\fR uninstall PLUGINS
+.
.br
\fBbundle plugin\fR list
+.
.br
\fBbundle plugin\fR help [COMMAND]
+.
.SH "DESCRIPTION"
You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler\.
+.
.SH "SUB\-COMMANDS"
+.
.SS "install"
Install the given plugin(s)\.
-.TP
-\fBbundle plugin install bundler\-graph\fR
-Install bundler\-graph gem from globally configured sources (defaults to RubyGems\.org)\. The global source, specified in source in Gemfile is ignored\.
-.TP
-\fBbundle plugin install bundler\-graph \-\-source https://example\.com\fR
-Install bundler\-graph gem from example\.com\. The global source, specified in source in Gemfile is not considered\.
-.TP
-\fBbundle plugin install bundler\-graph \-\-version 0\.2\.1\fR
-You can specify the version of the gem via \fB\-\-version\fR\.
-.TP
-\fBbundle plugin install bundler\-graph \-\-git https://github\.com/rubygems/bundler\-graph\fR
-Install bundler\-graph gem from Git repository\. You can use standard Git URLs like:
-.IP
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph\fR: Install bundler\-graph gem from RubyGems\.org\. The global source, specified in source in Gemfile is ignored\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph \-\-source https://example\.com\fR: Install bundler\-graph gem from example\.com\. The global source, specified in source in Gemfile is not considered\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph \-\-version 0\.2\.1\fR: You can specify the version of the gem via \fB\-\-version\fR\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph \-\-git https://github\.com/rubygems/bundler\-graph\fR: Install bundler\-graph gem from Git repository\. \fB\-\-git\fR can be replaced with \fB\-\-local\-git\fR\. You cannot use both \fB\-\-git\fR and \fB\-\-local\-git\fR\. You can use standard Git URLs like:
+.
+.IP "\(bu" 4
\fBssh://[user@]host\.xz[:port]/path/to/repo\.git\fR
-.br
+.
+.IP "\(bu" 4
\fBhttp[s]://host\.xz[:port]/path/to/repo\.git\fR
-.br
+.
+.IP "\(bu" 4
\fB/path/to/repo\fR
-.br
+.
+.IP "\(bu" 4
\fBfile:///path/to/repo\fR
+.
+.IP "" 0
+.
.IP
-When you specify \fB\-\-git\fR, you can use \fB\-\-branch\fR or \fB\-\-ref\fR to specify any branch, tag, or commit hash (revision) to use\.
-.TP
-\fBbundle plugin install bundler\-graph \-\-path \.\./bundler\-graph\fR
-Install bundler\-graph gem from a local path\.
+When you specify \fB\-\-git\fR/\fB\-\-local\-git\fR, you can use \fB\-\-branch\fR or \fB\-\-ref\fR to specify any branch, tag, or commit hash (revision) to use\. When you specify both, only the latter is used\.
+.
+.IP "" 0
+.
.SS "uninstall"
Uninstall the plugin(s) specified in PLUGINS\.
+.
.SS "list"
List the installed plugins and available commands\.
+.
.P
No options\.
+.
.SS "help"
Describe subcommands or one specific subcommand\.
+.
.P
No options\.
+.
.SH "SEE ALSO"
+.
.IP "\(bu" 4
How to write a Bundler plugin \fIhttps://bundler\.io/guides/bundler_plugins\.html\fR
+.
.IP "" 0
diff --git a/lib/bundler/man/bundle-plugin.1.ronn b/lib/bundler/man/bundle-plugin.1.ronn
index b0a34660ea..4f234eeba7 100644
--- a/lib/bundler/man/bundle-plugin.1.ronn
+++ b/lib/bundler/man/bundle-plugin.1.ronn
@@ -4,8 +4,7 @@ bundle-plugin(1) -- Manage Bundler plugins
## SYNOPSIS
`bundle plugin` install PLUGINS [--source=<SOURCE>] [--version=<version>]
- [--git=<git-url>] [--branch=<branch>|--ref=<rev>]
- [--path=<path>]<br>
+ [--git|--local_git=<git-url>] [--branch=<branch>|--ref=<rev>]<br>
`bundle plugin` uninstall PLUGINS<br>
`bundle plugin` list<br>
`bundle plugin` help [COMMAND]
@@ -21,7 +20,7 @@ You can install, uninstall, and list plugin(s) with this command to extend funct
Install the given plugin(s).
* `bundle plugin install bundler-graph`:
- Install bundler-graph gem from globally configured sources (defaults to RubyGems.org). The global source, specified in source in Gemfile is ignored.
+ Install bundler-graph gem from RubyGems.org. The global source, specified in source in Gemfile is ignored.
* `bundle plugin install bundler-graph --source https://example.com`:
Install bundler-graph gem from example.com. The global source, specified in source in Gemfile is not considered.
@@ -30,17 +29,14 @@ Install the given plugin(s).
You can specify the version of the gem via `--version`.
* `bundle plugin install bundler-graph --git https://github.com/rubygems/bundler-graph`:
- Install bundler-graph gem from Git repository. You can use standard Git URLs like:
+ Install bundler-graph gem from Git repository. `--git` can be replaced with `--local-git`. You cannot use both `--git` and `--local-git`. You can use standard Git URLs like:
- `ssh://[user@]host.xz[:port]/path/to/repo.git`<br>
- `http[s]://host.xz[:port]/path/to/repo.git`<br>
- `/path/to/repo`<br>
- `file:///path/to/repo`
+ * `ssh://[user@]host.xz[:port]/path/to/repo.git`
+ * `http[s]://host.xz[:port]/path/to/repo.git`
+ * `/path/to/repo`
+ * `file:///path/to/repo`
- When you specify `--git`, you can use `--branch` or `--ref` to specify any branch, tag, or commit hash (revision) to use.
-
-* `bundle plugin install bundler-graph --path ../bundler-graph`:
- Install bundler-graph gem from a local path.
+ When you specify `--git`/`--local-git`, you can use `--branch` or `--ref` to specify any branch, tag, or commit hash (revision) to use. When you specify both, only the latter is used.
### uninstall
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
index bf4a7cd323..af81c48d2b 100644
--- a/lib/bundler/man/bundle-pristine.1
+++ b/lib/bundler/man/bundle-pristine.1
@@ -1,23 +1,34 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-PRISTINE" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-PRISTINE" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
+.
.SH "SYNOPSIS"
\fBbundle pristine\fR
+.
.SH "DESCRIPTION"
\fBpristine\fR restores the installed gems in the bundle to their pristine condition using the local gem cache from RubyGems\. For git gems, a forced checkout will be performed\.
+.
.P
-For further explanation, \fBbundle pristine\fR ignores unpacked files on disk\. In other words, this command utilizes the local \fB\.gem\fR cache or the gem's git repository as if one were installing from scratch\.
+For further explanation, \fBbundle pristine\fR ignores unpacked files on disk\. In other words, this command utilizes the local \fB\.gem\fR cache or the gem\'s git repository as if one were installing from scratch\.
+.
.P
-Note: the Bundler gem cannot be restored to its original state with \fBpristine\fR\. One also cannot use \fBbundle pristine\fR on gems with a 'path' option in the Gemfile, because bundler has no original copy it can restore from\.
+Note: the Bundler gem cannot be restored to its original state with \fBpristine\fR\. One also cannot use \fBbundle pristine\fR on gems with a \'path\' option in the Gemfile, because bundler has no original copy it can restore from\.
+.
.P
When is it practical to use \fBbundle pristine\fR?
+.
.P
It comes in handy when a developer is debugging a gem\. \fBbundle pristine\fR is a great way to get rid of experimental changes to a gem that one may not want\.
+.
.P
Why use \fBbundle pristine\fR over \fBgem pristine \-\-all\fR?
+.
.P
Both commands are very similar\. For context: \fBbundle pristine\fR, without arguments, cleans all gems from the lockfile\. Meanwhile, \fBgem pristine \-\-all\fR cleans all installed gems for that Ruby version\.
+.
.P
If a developer forgets which gems in their project they might have been debugging, the Rubygems \fBgem pristine [GEMNAME]\fR command may be inconvenient\. One can avoid waiting for \fBgem pristine \-\-all\fR, and instead run \fBbundle pristine\fR\.
diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1
index c3c96b416d..d86cf134bd 100644
--- a/lib/bundler/man/bundle-remove.1
+++ b/lib/bundler/man/bundle-remove.1
@@ -1,21 +1,31 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-REMOVE" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-REMOVE" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile
+.
.SH "SYNOPSIS"
-\fBbundle remove [GEM [GEM \|\.\|\.\|\.]] [\-\-install]\fR
+\fBbundle remove [GEM [GEM \.\.\.]] [\-\-install]\fR
+.
.SH "DESCRIPTION"
Removes the given gems from the Gemfile while ensuring that the resulting Gemfile is still valid\. If a gem cannot be removed, a warning is printed\. If a gem is already absent from the Gemfile, and error is raised\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-install\fR
Runs \fBbundle install\fR after the given gems have been removed from the Gemfile, which ensures that both the lockfile and the installed gems on disk are also updated to remove the given gem(s)\.
+.
.P
Example:
+.
.P
bundle remove rails
+.
.P
bundle remove rails rack
+.
.P
bundle remove rails rack \-\-install
diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1
index c054875efd..aa91176bf2 100644
--- a/lib/bundler/man/bundle-show.1
+++ b/lib/bundler/man/bundle-show.1
@@ -1,15 +1,22 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-SHOW" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-SHOW" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
+.
.SH "SYNOPSIS"
\fBbundle show\fR [GEM] [\-\-paths]
+.
.SH "DESCRIPTION"
Without the [GEM] option, \fBshow\fR will print a list of the names and versions of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by name\.
+.
.P
Calling show with [GEM] will list the exact location of that gem on your machine\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-paths\fR
List the paths of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by gem name\.
diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1
index acd80ec75c..e4e10ad23b 100644
--- a/lib/bundler/man/bundle-update.1
+++ b/lib/bundler/man/bundle-update.1
@@ -1,81 +1,114 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-UPDATE" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-UPDATE" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions
+.
.SH "SYNOPSIS"
\fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-full\-index] [\-\-jobs=JOBS] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-redownload] [\-\-strict] [\-\-conservative]
+.
.SH "DESCRIPTION"
Update the gems specified (all gems, if \fB\-\-all\fR flag is used), ignoring the previously installed gems specified in the \fBGemfile\.lock\fR\. In general, you should use bundle install(1) \fIbundle\-install\.1\.html\fR to install the same exact gems and versions across machines\.
+.
.P
You would use \fBbundle update\fR to explicitly update the version of a gem\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-all\fR
Update all gems specified in Gemfile\.
+.
.TP
\fB\-\-group=<name>\fR, \fB\-g=[<name>]\fR
Only update the gems in the specified group\. For instance, you can update all gems in the development group with \fBbundle update \-\-group development\fR\. You can also call \fBbundle update rails \-\-group test\fR to update the rails gem and all gems in the test group, for example\.
+.
.TP
\fB\-\-source=<name>\fR
The name of a \fB:git\fR or \fB:path\fR source used in the Gemfile(5)\. For instance, with a \fB:git\fR source of \fBhttp://github\.com/rails/rails\.git\fR, you would call \fBbundle update \-\-source rails\fR
+.
.TP
\fB\-\-local\fR
Do not attempt to fetch gems remotely and use the gem cache instead\.
+.
.TP
\fB\-\-ruby\fR
Update the locked version of Ruby to the current version of Ruby\.
+.
.TP
\fB\-\-bundler\fR
Update the locked version of bundler to the invoked bundler version\.
+.
.TP
\fB\-\-full\-index\fR
Fall back to using the single\-file index of all gems\.
+.
.TP
\fB\-\-jobs=[<number>]\fR, \fB\-j[<number>]\fR
Specify the number of jobs to run in parallel\. The default is the number of available processors\.
+.
.TP
\fB\-\-retry=[<number>]\fR
Retry failed network or git requests for \fInumber\fR times\.
+.
.TP
\fB\-\-quiet\fR
Only output warnings and errors\.
+.
.TP
\fB\-\-redownload\fR
Force downloading every gem\.
+.
.TP
\fB\-\-patch\fR
Prefer updating only to next patch version\.
+.
.TP
\fB\-\-minor\fR
Prefer updating only to next minor version\.
+.
.TP
\fB\-\-major\fR
Prefer updating to next major version (default)\.
+.
.TP
\fB\-\-strict\fR
Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR | \fB\-\-major\fR\.
+.
.TP
\fB\-\-conservative\fR
Use bundle install conservative update behavior and do not allow indirect dependencies to be updated\.
+.
.SH "UPDATING ALL GEMS"
If you run \fBbundle update \-\-all\fR, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
+.
.P
Consider the following Gemfile(5):
+.
.IP "" 4
+.
.nf
+
source "https://rubygems\.org"
gem "rails", "3\.0\.0\.rc"
gem "nokogiri"
+.
.fi
+.
.IP "" 0
+.
.P
When you run bundle install(1) \fIbundle\-install\.1\.html\fR the first time, bundler will resolve all of the dependencies, all the way down, and install what you need:
+.
.IP "" 4
+.
.nf
-Fetching gem metadata from https://rubygems\.org/\|\.\|\.\|\.\|\.\|\.\|\.\|\.\|\.\|\.
-Resolving dependencies\|\.\|\.\|\.
+
+Fetching gem metadata from https://rubygems\.org/\.\.\.\.\.\.\.\.\.
+Resolving dependencies\.\.\.
Installing builder 2\.1\.2
Installing abstract 1\.0\.0
Installing rack 1\.2\.8
@@ -105,36 +138,55 @@ Installing nokogiri 1\.6\.5
Bundle complete! 2 Gemfile dependencies, 26 gems total\.
Use `bundle show [gemname]` to see where a bundled gem is installed\.
+.
.fi
+.
.IP "" 0
+.
.P
As you can see, even though you have two gems in the Gemfile(5), your application needs 26 different gems in order to run\. Bundler remembers the exact versions it installed in \fBGemfile\.lock\fR\. The next time you run bundle install(1) \fIbundle\-install\.1\.html\fR, bundler skips the dependency resolution and installs the same gems as it installed last time\.
+.
.P
-After checking in the \fBGemfile\.lock\fR into version control and cloning it on another machine, running bundle install(1) \fIbundle\-install\.1\.html\fR will \fIstill\fR install the gems that you installed last time\. You don't need to worry that a new release of \fBerubis\fR or \fBmail\fR changes the gems you use\.
+After checking in the \fBGemfile\.lock\fR into version control and cloning it on another machine, running bundle install(1) \fIbundle\-install\.1\.html\fR will \fIstill\fR install the gems that you installed last time\. You don\'t need to worry that a new release of \fBerubis\fR or \fBmail\fR changes the gems you use\.
+.
.P
However, from time to time, you might want to update the gems you are using to the newest versions that still match the gems in your Gemfile(5)\.
+.
.P
To do this, run \fBbundle update \-\-all\fR, which will ignore the \fBGemfile\.lock\fR, and resolve all the dependencies again\. Keep in mind that this process can result in a significantly different set of the 25 gems, based on the requirements of new gems that the gem authors released since the last time you ran \fBbundle update \-\-all\fR\.
+.
.SH "UPDATING A LIST OF GEMS"
Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the \fBGemfile\.lock\fR\.
+.
.P
For instance, in the scenario above, imagine that \fBnokogiri\fR releases version \fB1\.4\.4\fR, and you want to update it \fIwithout\fR updating Rails and all of its dependencies\. To do this, run \fBbundle update nokogiri\fR\.
+.
.P
Bundler will update \fBnokogiri\fR and any of its dependencies, but leave alone Rails and its dependencies\.
+.
.SH "OVERLAPPING DEPENDENCIES"
Sometimes, multiple gems declared in your Gemfile(5) are satisfied by the same second\-level dependency\. For instance, consider the case of \fBthin\fR and \fBrack\-perftools\-profiler\fR\.
+.
.IP "" 4
+.
.nf
+
source "https://rubygems\.org"
gem "thin"
gem "rack\-perftools\-profiler"
+.
.fi
+.
.IP "" 0
+.
.P
The \fBthin\fR gem depends on \fBrack >= 1\.0\fR, while \fBrack\-perftools\-profiler\fR depends on \fBrack ~> 1\.0\fR\. If you run bundle install, you get:
+.
.IP "" 4
+.
.nf
+
Fetching source index for https://rubygems\.org/
Installing daemons (1\.1\.0)
Installing eventmachine (0\.12\.10) with native extensions
@@ -144,132 +196,199 @@ Installing rack (1\.2\.1)
Installing rack\-perftools_profiler (0\.0\.2)
Installing thin (1\.2\.7) with native extensions
Using bundler (1\.0\.0\.rc\.3)
+.
.fi
+.
.IP "" 0
+.
.P
-In this case, the two gems have their own set of dependencies, but they share \fBrack\fR in common\. If you run \fBbundle update thin\fR, bundler will update \fBdaemons\fR, \fBeventmachine\fR and \fBrack\fR, which are dependencies of \fBthin\fR, but not \fBopen4\fR or \fBperftools\.rb\fR, which are dependencies of \fBrack\-perftools_profiler\fR\. Note that \fBbundle update thin\fR will update \fBrack\fR even though it's \fIalso\fR a dependency of \fBrack\-perftools_profiler\fR\.
+In this case, the two gems have their own set of dependencies, but they share \fBrack\fR in common\. If you run \fBbundle update thin\fR, bundler will update \fBdaemons\fR, \fBeventmachine\fR and \fBrack\fR, which are dependencies of \fBthin\fR, but not \fBopen4\fR or \fBperftools\.rb\fR, which are dependencies of \fBrack\-perftools_profiler\fR\. Note that \fBbundle update thin\fR will update \fBrack\fR even though it\'s \fIalso\fR a dependency of \fBrack\-perftools_profiler\fR\.
+.
.P
In short, by default, when you update a gem using \fBbundle update\fR, bundler will update all dependencies of that gem, including those that are also dependencies of another gem\.
+.
.P
To prevent updating indirect dependencies, prior to version 1\.14 the only option was the \fBCONSERVATIVE UPDATING\fR behavior in bundle install(1) \fIbundle\-install\.1\.html\fR:
+.
.P
In this scenario, updating the \fBthin\fR version manually in the Gemfile(5), and then running bundle install(1) \fIbundle\-install\.1\.html\fR will only update \fBdaemons\fR and \fBeventmachine\fR, but not \fBrack\fR\. For more information, see the \fBCONSERVATIVE UPDATING\fR section of bundle install(1) \fIbundle\-install\.1\.html\fR\.
+.
.P
Starting with 1\.14, specifying the \fB\-\-conservative\fR option will also prevent indirect dependencies from being updated\.
+.
.SH "PATCH LEVEL OPTIONS"
Version 1\.14 introduced 4 patch\-level options that will influence how gem versions are resolved\. One of the following options can be used: \fB\-\-patch\fR, \fB\-\-minor\fR or \fB\-\-major\fR\. \fB\-\-strict\fR can be added to further influence resolution\.
+.
.TP
\fB\-\-patch\fR
Prefer updating only to next patch version\.
+.
.TP
\fB\-\-minor\fR
Prefer updating only to next minor version\.
+.
.TP
\fB\-\-major\fR
Prefer updating to next major version (default)\.
+.
.TP
\fB\-\-strict\fR
Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR | \fB\-\-major\fR\.
+.
.P
-When Bundler is resolving what versions to use to satisfy declared requirements in the Gemfile or in parent gems, it looks up all available versions, filters out any versions that don't satisfy the requirement, and then, by default, sorts them from newest to oldest, considering them in that order\.
+When Bundler is resolving what versions to use to satisfy declared requirements in the Gemfile or in parent gems, it looks up all available versions, filters out any versions that don\'t satisfy the requirement, and then, by default, sorts them from newest to oldest, considering them in that order\.
+.
.P
Providing one of the patch level options (e\.g\. \fB\-\-patch\fR) changes the sort order of the satisfying versions, causing Bundler to consider the latest \fB\-\-patch\fR or \fB\-\-minor\fR version available before other versions\. Note that versions outside the stated patch level could still be resolved to if necessary to find a suitable dependency graph\.
+.
.P
-For example, if gem 'foo' is locked at 1\.0\.2, with no gem requirement defined in the Gemfile, and versions 1\.0\.3, 1\.0\.4, 1\.1\.0, 1\.1\.1, 2\.0\.0 all exist, the default order of preference by default (\fB\-\-major\fR) will be "2\.0\.0, 1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\.
+For example, if gem \'foo\' is locked at 1\.0\.2, with no gem requirement defined in the Gemfile, and versions 1\.0\.3, 1\.0\.4, 1\.1\.0, 1\.1\.1, 2\.0\.0 all exist, the default order of preference by default (\fB\-\-major\fR) will be "2\.0\.0, 1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\.
+.
.P
If the \fB\-\-patch\fR option is used, the order of preference will change to "1\.0\.4, 1\.0\.3, 1\.0\.2, 1\.1\.1, 1\.1\.0, 2\.0\.0"\.
+.
.P
If the \fB\-\-minor\fR option is used, the order of preference will change to "1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2, 2\.0\.0"\.
+.
.P
Combining the \fB\-\-strict\fR option with any of the patch level options will remove any versions beyond the scope of the patch level option, to ensure that no gem is updated that far\.
+.
.P
To continue the previous example, if both \fB\-\-patch\fR and \fB\-\-strict\fR options are used, the available versions for resolution would be "1\.0\.4, 1\.0\.3, 1\.0\.2"\. If \fB\-\-minor\fR and \fB\-\-strict\fR are used, it would be "1\.1\.1, 1\.1\.0, 1\.0\.4, 1\.0\.3, 1\.0\.2"\.
+.
.P
-Gem requirements as defined in the Gemfile will still be the first determining factor for what versions are available\. If the gem requirement for \fBfoo\fR in the Gemfile is '~> 1\.0', that will accomplish the same thing as providing the \fB\-\-minor\fR and \fB\-\-strict\fR options\.
+Gem requirements as defined in the Gemfile will still be the first determining factor for what versions are available\. If the gem requirement for \fBfoo\fR in the Gemfile is \'~> 1\.0\', that will accomplish the same thing as providing the \fB\-\-minor\fR and \fB\-\-strict\fR options\.
+.
.SH "PATCH LEVEL EXAMPLES"
Given the following gem specifications:
+.
.IP "" 4
+.
.nf
+
foo 1\.4\.3, requires: ~> bar 2\.0
foo 1\.4\.4, requires: ~> bar 2\.0
foo 1\.4\.5, requires: ~> bar 2\.1
foo 1\.5\.0, requires: ~> bar 2\.1
foo 1\.5\.1, requires: ~> bar 3\.0
bar with versions 2\.0\.3, 2\.0\.4, 2\.1\.0, 2\.1\.1, 3\.0\.0
+.
.fi
+.
.IP "" 0
+.
.P
Gemfile:
+.
.IP "" 4
+.
.nf
-gem 'foo'
+
+gem \'foo\'
+.
.fi
+.
.IP "" 0
+.
.P
Gemfile\.lock:
+.
.IP "" 4
+.
.nf
+
foo (1\.4\.3)
bar (~> 2\.0)
bar (2\.0\.3)
+.
.fi
+.
.IP "" 0
+.
.P
Cases:
+.
.IP "" 4
+.
.nf
+
# Command Line Result
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
-1 bundle update \-\-patch 'foo 1\.4\.5', 'bar 2\.1\.1'
-2 bundle update \-\-patch foo 'foo 1\.4\.5', 'bar 2\.1\.1'
-3 bundle update \-\-minor 'foo 1\.5\.1', 'bar 3\.0\.0'
-4 bundle update \-\-minor \-\-strict 'foo 1\.5\.0', 'bar 2\.1\.1'
-5 bundle update \-\-patch \-\-strict 'foo 1\.4\.4', 'bar 2\.0\.4'
+1 bundle update \-\-patch \'foo 1\.4\.5\', \'bar 2\.1\.1\'
+2 bundle update \-\-patch foo \'foo 1\.4\.5\', \'bar 2\.1\.1\'
+3 bundle update \-\-minor \'foo 1\.5\.1\', \'bar 3\.0\.0\'
+4 bundle update \-\-minor \-\-strict \'foo 1\.5\.0\', \'bar 2\.1\.1\'
+5 bundle update \-\-patch \-\-strict \'foo 1\.4\.4\', \'bar 2\.0\.4\'
+.
.fi
+.
.IP "" 0
+.
.P
In case 1, bar is upgraded to 2\.1\.1, a minor version increase, because the dependency from foo 1\.4\.5 required it\.
+.
.P
-In case 2, only foo is requested to be unlocked, but bar is also allowed to move because it's not a declared dependency in the Gemfile\.
+In case 2, only foo is requested to be unlocked, but bar is also allowed to move because it\'s not a declared dependency in the Gemfile\.
+.
.P
In case 3, bar goes up a whole major release, because a minor increase is preferred now for foo, and when it goes to 1\.5\.1, it requires 3\.0\.0 of bar\.
+.
.P
-In case 4, foo is preferred up to a minor version, but 1\.5\.1 won't work because the \-\-strict flag removes bar 3\.0\.0 from consideration since it's a major increment\.
+In case 4, foo is preferred up to a minor version, but 1\.5\.1 won\'t work because the \-\-strict flag removes bar 3\.0\.0 from consideration since it\'s a major increment\.
+.
.P
In case 5, both foo and bar have any minor or major increments removed from consideration because of the \-\-strict flag, so the most they can move is up to 1\.4\.4 and 2\.0\.4\.
+.
.SH "RECOMMENDED WORKFLOW"
In general, when working with an application managed with bundler, you should use the following workflow:
+.
.IP "\(bu" 4
After you create your Gemfile(5) for the first time, run
+.
.IP
$ bundle install
+.
.IP "\(bu" 4
Check the resulting \fBGemfile\.lock\fR into version control
+.
.IP
$ git add Gemfile\.lock
+.
.IP "\(bu" 4
When checking out this repository on another development machine, run
+.
.IP
$ bundle install
+.
.IP "\(bu" 4
When checking out this repository on a deployment machine, run
+.
.IP
$ bundle install \-\-deployment
+.
.IP "\(bu" 4
After changing the Gemfile(5) to reflect a new or update dependency, run
+.
.IP
$ bundle install
+.
.IP "\(bu" 4
Make sure to check the updated \fBGemfile\.lock\fR into version control
+.
.IP
$ git add Gemfile\.lock
+.
.IP "\(bu" 4
If bundle install(1) \fIbundle\-install\.1\.html\fR reports a conflict, manually update the specific gems that you changed in the Gemfile(5)
+.
.IP
$ bundle update rails thin
+.
.IP "\(bu" 4
If you want to update all the gems to the latest possible versions that still match the gems listed in the Gemfile(5), run
+.
.IP
$ bundle update \-\-all
+.
.IP "" 0
diff --git a/lib/bundler/man/bundle-version.1 b/lib/bundler/man/bundle-version.1
index 44eaf92224..5e3ed44600 100644
--- a/lib/bundler/man/bundle-version.1
+++ b/lib/bundler/man/bundle-version.1
@@ -1,22 +1,35 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-VERSION" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-VERSION" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-version\fR \- Prints Bundler version information
+.
.SH "SYNOPSIS"
\fBbundle version\fR
+.
.SH "DESCRIPTION"
Prints Bundler version information\.
+.
.SH "OPTIONS"
No options\.
+.
.SH "EXAMPLE"
Print the version of Bundler with build date and commit hash of the in the Git source\.
+.
.IP "" 4
+.
.nf
+
bundle version
+.
.fi
+.
.IP "" 0
+.
.P
shows \fBBundler version 2\.3\.21 (2022\-08\-24 commit d54be5fdd8)\fR for example\.
+.
.P
cf\. \fBbundle \-\-version\fR shows \fBBundler version 2\.3\.21\fR\.
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
index 77b902214c..d5330ec754 100644
--- a/lib/bundler/man/bundle-viz.1
+++ b/lib/bundler/man/bundle-viz.1
@@ -1,29 +1,41 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE\-VIZ" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-VIZ" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
+.
.SH "SYNOPSIS"
\fBbundle viz\fR [\-\-file=FILE] [\-\-format=FORMAT] [\-\-requirements] [\-\-version] [\-\-without=GROUP GROUP]
+.
.SH "DESCRIPTION"
\fBviz\fR generates a PNG file of the current \fBGemfile(5)\fR as a dependency graph\. \fBviz\fR requires the ruby\-graphviz gem (and its dependencies)\.
+.
.P
The associated gems must also be installed via \fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR\.
+.
.P
\fBviz\fR command was deprecated in Bundler 2\.2\. Use bundler\-graph plugin \fIhttps://github\.com/rubygems/bundler\-graph\fR instead\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-file\fR, \fB\-f\fR
The name to use for the generated file\. See \fB\-\-format\fR option
+.
.TP
\fB\-\-format\fR, \fB\-F\fR
-This is output format option\. Supported format is png, jpg, svg, dot \|\.\|\.\|\.
+This is output format option\. Supported format is png, jpg, svg, dot \.\.\.
+.
.TP
\fB\-\-requirements\fR, \fB\-R\fR
Set to show the version of each required dependency\.
+.
.TP
\fB\-\-version\fR, \fB\-v\fR
Set to show each gem version\.
+.
.TP
\fB\-\-without\fR, \fB\-W\fR
Exclude gems that are part of the specified named group\.
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
index 199d1ce9fd..99c65a72b5 100644
--- a/lib/bundler/man/bundle.1
+++ b/lib/bundler/man/bundle.1
@@ -1,102 +1,141 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "BUNDLE" "1" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE" "1" "August 2023" "" ""
+.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
+.
.SH "SYNOPSIS"
\fBbundle\fR COMMAND [\-\-no\-color] [\-\-verbose] [ARGS]
+.
.SH "DESCRIPTION"
-Bundler manages an \fBapplication's dependencies\fR through its entire life across many machines systematically and repeatably\.
+Bundler manages an \fBapplication\'s dependencies\fR through its entire life across many machines systematically and repeatably\.
+.
.P
See the bundler website \fIhttps://bundler\.io\fR for information on getting started, and Gemfile(5) for more information on the \fBGemfile\fR format\.
+.
.SH "OPTIONS"
+.
.TP
\fB\-\-no\-color\fR
Print all output without color
+.
.TP
\fB\-\-retry\fR, \fB\-r\fR
Specify the number of times you wish to attempt network commands
+.
.TP
\fB\-\-verbose\fR, \fB\-V\fR
Print out additional logging information
+.
.SH "BUNDLE COMMANDS"
We divide \fBbundle\fR subcommands into primary commands and utilities:
+.
.SH "PRIMARY COMMANDS"
+.
.TP
\fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR
Install the gems specified by the \fBGemfile\fR or \fBGemfile\.lock\fR
+.
.TP
\fBbundle update(1)\fR \fIbundle\-update\.1\.html\fR
Update dependencies to their latest versions
+.
.TP
\fBbundle cache(1)\fR \fIbundle\-cache\.1\.html\fR
Package the \.gem files required by your application into the \fBvendor/cache\fR directory (aliases: \fBbundle package\fR, \fBbundle pack\fR)
+.
.TP
\fBbundle exec(1)\fR \fIbundle\-exec\.1\.html\fR
Execute a script in the current bundle
+.
.TP
\fBbundle config(1)\fR \fIbundle\-config\.1\.html\fR
Specify and read configuration options for Bundler
+.
.TP
\fBbundle help(1)\fR \fIbundle\-help\.1\.html\fR
Display detailed help for each subcommand
+.
.SH "UTILITIES"
+.
.TP
\fBbundle add(1)\fR \fIbundle\-add\.1\.html\fR
Add the named gem to the Gemfile and run \fBbundle install\fR
+.
.TP
\fBbundle binstubs(1)\fR \fIbundle\-binstubs\.1\.html\fR
Generate binstubs for executables in a gem
+.
.TP
\fBbundle check(1)\fR \fIbundle\-check\.1\.html\fR
Determine whether the requirements for your application are installed and available to Bundler
+.
.TP
\fBbundle show(1)\fR \fIbundle\-show\.1\.html\fR
Show the source location of a particular gem in the bundle
+.
.TP
\fBbundle outdated(1)\fR \fIbundle\-outdated\.1\.html\fR
Show all of the outdated gems in the current bundle
+.
.TP
\fBbundle console(1)\fR (deprecated)
Start an IRB session in the current bundle
+.
.TP
\fBbundle open(1)\fR \fIbundle\-open\.1\.html\fR
Open an installed gem in the editor
+.
.TP
\fBbundle lock(1)\fR \fIbundle\-lock\.1\.html\fR
Generate a lockfile for your dependencies
+.
.TP
\fBbundle viz(1)\fR \fIbundle\-viz\.1\.html\fR (deprecated)
Generate a visual representation of your dependencies
+.
.TP
\fBbundle init(1)\fR \fIbundle\-init\.1\.html\fR
Generate a simple \fBGemfile\fR, placed in the current directory
+.
.TP
\fBbundle gem(1)\fR \fIbundle\-gem\.1\.html\fR
Create a simple gem, suitable for development with Bundler
+.
.TP
\fBbundle platform(1)\fR \fIbundle\-platform\.1\.html\fR
Display platform compatibility information
+.
.TP
\fBbundle clean(1)\fR \fIbundle\-clean\.1\.html\fR
Clean up unused gems in your Bundler directory
+.
.TP
\fBbundle doctor(1)\fR \fIbundle\-doctor\.1\.html\fR
Display warnings about common problems
+.
.TP
\fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR
Removes gems from the Gemfile
+.
.TP
\fBbundle plugin(1)\fR \fIbundle\-plugin\.1\.html\fR
Manage Bundler plugins
+.
.TP
\fBbundle version(1)\fR \fIbundle\-version\.1\.html\fR
Prints Bundler version information
+.
.SH "PLUGINS"
-When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-<command>\fR and execute it, passing down any extra arguments to it\.
+When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-<command>\fR and execute it, passing down any extra arguments to it\.
+.
.SH "OBSOLETE"
These commands are obsolete and should no longer be used:
+.
.IP "\(bu" 4
\fBbundle inject(1)\fR
+.
.IP "" 0
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index fa9e31f615..352fa0f545 100644
--- a/lib/bundler/man/gemfile.5
+++ b/lib/bundler/man/gemfile.5
@@ -1,143 +1,228 @@
-.\" generated with nRonn/v0.11.1
-.\" https://github.com/n-ronn/nronn/tree/0.11.1
-.TH "GEMFILE" "5" "May 2024" ""
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "GEMFILE" "5" "August 2023" "" ""
+.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
+.
.SH "SYNOPSIS"
A \fBGemfile\fR describes the gem dependencies required to execute associated Ruby code\.
+.
.P
Place the \fBGemfile\fR in the root of the directory containing the associated code\. For instance, in a Rails application, place the \fBGemfile\fR in the same directory as the \fBRakefile\fR\.
+.
.SH "SYNTAX"
A \fBGemfile\fR is evaluated as Ruby code, in a context which makes available a number of methods used to describe the gem requirements\.
+.
.SH "GLOBAL SOURCE"
At the top of the \fBGemfile\fR, add a single line for the \fBRubyGems\fR source that contains the gems listed in the \fBGemfile\fR\.
+.
.IP "" 4
+.
.nf
+
source "https://rubygems\.org"
+.
.fi
+.
.IP "" 0
+.
.P
You can add only one global source\. In Bundler 1\.13, adding multiple global sources was deprecated\. The \fBsource\fR \fBMUST\fR be a valid RubyGems repository\.
+.
.P
To use more than one source of RubyGems, you should use \fI\fBsource\fR block\fR\.
+.
.P
A source is checked for gems following the heuristics described in \fISOURCE PRIORITY\fR\.
+.
.P
\fBNote about a behavior of the feature deprecated in Bundler 1\.13\fR: If a gem is found in more than one global source, Bundler will print a warning after installing the gem indicating which source was used, and listing the other sources where the gem is available\. A specific source can be selected for gems that need to use a non\-standard repository, suppressing this warning, by using the \fI\fB:source\fR option\fR or \fBsource\fR block\.
+.
.SS "CREDENTIALS"
Some gem sources require a username and password\. Use bundle config(1) \fIbundle\-config\.1\.html\fR to set the username and password for any of the sources that need it\. The command must be run once on each computer that will install the Gemfile, but this keeps the credentials from being stored in plain text in version control\.
+.
.IP "" 4
+.
.nf
+
bundle config gems\.example\.com user:password
+.
.fi
+.
.IP "" 0
+.
.P
For some sources, like a company Gemfury account, it may be easier to include the credentials in the Gemfile as part of the source URL\.
+.
.IP "" 4
+.
.nf
+
source "https://user:password@gems\.example\.com"
+.
.fi
+.
.IP "" 0
+.
.P
Credentials in the source URL will take precedence over credentials set using \fBconfig\fR\.
+.
.SH "RUBY"
If your application requires a specific Ruby version or engine, specify your requirements using the \fBruby\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\.
+.
.SS "VERSION (required)"
The version of Ruby that your application requires\. If your application requires an alternate Ruby engine, such as JRuby, TruffleRuby, etc\., this should be the Ruby version that the engine is compatible with\.
+.
.IP "" 4
+.
.nf
+
ruby "3\.1\.2"
+.
.fi
+.
.IP "" 0
+.
.P
If you wish to derive your Ruby version from a version file (ie \.ruby\-version), you can use the \fBfile\fR option instead\.
+.
.IP "" 4
+.
.nf
+
ruby file: "\.ruby\-version"
+.
.fi
+.
.IP "" 0
-.P
-The version file should conform to any of the following formats:
-.IP "\(bu" 4
-\fB3\.1\.2\fR (\.ruby\-version)
-.IP "\(bu" 4
-\fBruby 3\.1\.2\fR (\.tool\-versions, read: https://asdf\-vm\.com/manage/configuration\.html#tool\-versions)
-.IP "" 0
+.
.SS "ENGINE"
Each application \fImay\fR specify a Ruby engine\. If an engine is specified, an engine version \fImust\fR also be specified\.
+.
.P
-What exactly is an Engine?
+What exactly is an Engine? \- A Ruby engine is an implementation of the Ruby language\.
+.
.IP "\(bu" 4
-A Ruby engine is an implementation of the Ruby language\.
+For background: the reference or original implementation of the Ruby programming language is called Matz\'s Ruby Interpreter \fIhttps://en\.wikipedia\.org/wiki/Ruby_MRI\fR, or MRI for short\. This is named after Ruby creator Yukihiro Matsumoto, also known as Matz\. MRI is also known as CRuby, because it is written in C\. MRI is the most widely used Ruby engine\.
+.
.IP "\(bu" 4
-For background: the reference or original implementation of the Ruby programming language is called Matz's Ruby Interpreter \fIhttps://en\.wikipedia\.org/wiki/Ruby_MRI\fR, or MRI for short\. This is named after Ruby creator Yukihiro Matsumoto, also known as Matz\. MRI is also known as CRuby, because it is written in C\. MRI is the most widely used Ruby engine\.
-.IP "\(bu" 4
-Other implementations \fIhttps://www\.ruby\-lang\.org/en/about/\fR of Ruby exist\. Some of the more well\-known implementations include JRuby \fIhttps://www\.jruby\.org/\fR and TruffleRuby \fIhttps://www\.graalvm\.org/ruby/\fR\. Rubinius is an alternative implementation of Ruby written in Ruby\. JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine\. TruffleRuby is a Ruby implementation on the GraalVM, a language toolkit built on the JVM\.
+Other implementations \fIhttps://www\.ruby\-lang\.org/en/about/\fR of Ruby exist\. Some of the more well\-known implementations include JRuby \fIhttp://jruby\.org/\fR and TruffleRuby \fIhttps://www\.graalvm\.org/ruby/\fR\. Rubinius is an alternative implementation of Ruby written in Ruby\. JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine\. TruffleRuby is a Ruby implementation on the GraalVM, a language toolkit built on the JVM\.
+.
.IP "" 0
+.
.SS "ENGINE VERSION"
Each application \fImay\fR specify a Ruby engine version\. If an engine version is specified, an engine \fImust\fR also be specified\. If the engine is "ruby" the engine version specified \fImust\fR match the Ruby version\.
+.
.IP "" 4
+.
.nf
+
ruby "2\.6\.8", engine: "jruby", engine_version: "9\.3\.8\.0"
+.
.fi
+.
.IP "" 0
+.
.SS "PATCHLEVEL"
Each application \fImay\fR specify a Ruby patchlevel\. Specifying the patchlevel has been meaningless since Ruby 2\.1\.0 was released as the patchlevel is now uniquely determined by a combination of major, minor, and teeny version numbers\.
+.
.P
This option was implemented in Bundler 1\.4\.0 for Ruby 2\.0 or earlier\.
+.
.IP "" 4
+.
.nf
+
ruby "3\.1\.2", patchlevel: "20"
+.
.fi
+.
.IP "" 0
+.
.SH "GEMS"
Specify gem requirements using the \fBgem\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\.
+.
.SS "NAME (required)"
For each gem requirement, list a single \fIgem\fR line\.
+.
.IP "" 4
+.
.nf
+
gem "nokogiri"
+.
.fi
+.
.IP "" 0
+.
.SS "VERSION"
Each \fIgem\fR \fBMAY\fR have one or more version specifiers\.
+.
.IP "" 4
+.
.nf
+
gem "nokogiri", ">= 1\.4\.2"
gem "RedCloth", ">= 4\.1\.0", "< 4\.2\.0"
+.
.fi
+.
.IP "" 0
+.
.SS "REQUIRE AS"
Each \fIgem\fR \fBMAY\fR specify files that should be used when autorequiring via \fBBundler\.require\fR\. You may pass an array with multiple files or \fBtrue\fR if the file you want \fBrequired\fR has the same name as \fIgem\fR or \fBfalse\fR to prevent any file from being autorequired\.
+.
.IP "" 4
+.
.nf
+
gem "redis", require: ["redis/connection/hiredis", "redis"]
gem "webmock", require: false
gem "byebug", require: true
+.
.fi
+.
.IP "" 0
+.
.P
The argument defaults to the name of the gem\. For example, these are identical:
+.
.IP "" 4
+.
.nf
+
gem "nokogiri"
gem "nokogiri", require: "nokogiri"
gem "nokogiri", require: true
+.
.fi
+.
.IP "" 0
+.
.SS "GROUPS"
Each \fIgem\fR \fBMAY\fR specify membership in one or more groups\. Any \fIgem\fR that does not specify membership in any group is placed in the \fBdefault\fR group\.
+.
.IP "" 4
+.
.nf
+
gem "rspec", group: :test
gem "wirble", groups: [:development, :test]
+.
.fi
+.
.IP "" 0
+.
.P
The Bundler runtime allows its two main methods, \fBBundler\.setup\fR and \fBBundler\.require\fR, to limit their impact to particular groups\.
+.
.IP "" 4
+.
.nf
-# setup adds gems to Ruby's load path
+
+# setup adds gems to Ruby\'s load path
Bundler\.setup # defaults to all groups
require "bundler/setup" # same as Bundler\.setup
Bundler\.setup(:default) # only set up the _default_ group
@@ -149,269 +234,429 @@ Bundler\.require # defaults to the _default_ group
Bundler\.require(:default) # identical
Bundler\.require(:default, :test) # requires the _default_ and _test_ groups
Bundler\.require(:test) # requires the _test_ group
+.
.fi
+.
.IP "" 0
+.
.P
The Bundler CLI allows you to specify a list of groups whose gems \fBbundle install\fR should not install with the \fBwithout\fR configuration\.
+.
.P
To specify multiple groups to ignore, specify a list of groups separated by spaces\.
+.
.IP "" 4
+.
.nf
+
bundle config set \-\-local without test
bundle config set \-\-local without development test
+.
.fi
+.
.IP "" 0
+.
.P
Also, calling \fBBundler\.setup\fR with no parameters, or calling \fBrequire "bundler/setup"\fR will setup all groups except for the ones you excluded via \fB\-\-without\fR (since they are not available)\.
+.
.P
Note that on \fBbundle install\fR, bundler downloads and evaluates all gems, in order to create a single canonical list of all of the required gems and their dependencies\. This means that you cannot list different versions of the same gems in different groups\. For more details, see Understanding Bundler \fIhttps://bundler\.io/rationale\.html\fR\.
+.
.SS "PLATFORMS"
If a gem should only be used in a particular platform or set of platforms, you can specify them\. Platforms are essentially identical to groups, except that you do not need to use the \fB\-\-without\fR install\-time flag to exclude groups of gems for other platforms\.
+.
.P
There are a number of \fBGemfile\fR platforms:
+.
.TP
\fBruby\fR
C Ruby (MRI), Rubinius, or TruffleRuby, but not Windows
+.
.TP
\fBmri\fR
C Ruby (MRI) only, but not Windows
+.
.TP
\fBwindows\fR
Windows C Ruby (MRI), including RubyInstaller 32\-bit and 64\-bit versions
+.
.TP
\fBmswin\fR
Windows C Ruby (MRI), including RubyInstaller 32\-bit versions
+.
.TP
\fBmswin64\fR
Windows C Ruby (MRI), including RubyInstaller 64\-bit versions
+.
.TP
\fBrbx\fR
Rubinius
+.
.TP
\fBjruby\fR
JRuby
+.
.TP
\fBtruffleruby\fR
TruffleRuby
+.
.P
On platforms \fBruby\fR, \fBmri\fR, \fBmswin\fR, \fBmswin64\fR, and \fBwindows\fR, you may additionally specify a version by appending the major and minor version numbers without a delimiter\. For example, to specify that a gem should only be used on platform \fBruby\fR version 3\.1, use:
+.
.IP "" 4
+.
.nf
+
ruby_31
+.
.fi
+.
.IP "" 0
+.
.P
As with groups (above), you may specify one or more platforms:
+.
.IP "" 4
+.
.nf
+
gem "weakling", platforms: :jruby
gem "ruby\-debug", platforms: :mri_31
gem "nokogiri", platforms: [:windows_31, :jruby]
+.
.fi
+.
.IP "" 0
+.
.P
All operations involving groups (\fBbundle install\fR \fIbundle\-install\.1\.html\fR, \fBBundler\.setup\fR, \fBBundler\.require\fR) behave exactly the same as if any groups not matching the current platform were explicitly excluded\.
-.P
-The following platform values are deprecated and should be replaced with \fBwindows\fR:
-.IP "\(bu" 4
-\fBmswin\fR, \fBmswin64\fR, \fBmingw32\fR, \fBx64_mingw\fR
-.IP "" 0
+.
.SS "FORCE_RUBY_PLATFORM"
If you always want the pure ruby variant of a gem to be chosen over platform specific variants, you can use the \fBforce_ruby_platform\fR option:
+.
.IP "" 4
+.
.nf
+
gem "ffi", force_ruby_platform: true
+.
.fi
+.
.IP "" 0
+.
.P
This can be handy (assuming the pure ruby variant works fine) when:
+.
.IP "\(bu" 4
-You're having issues with the platform specific variant\.
+You\'re having issues with the platform specific variant\.
+.
.IP "\(bu" 4
The platform specific variant does not yet support a newer ruby (and thus has a \fBrequired_ruby_version\fR upper bound), but you still want your Gemfile{\.lock} files to resolve under that ruby\.
+.
.IP "" 0
+.
.SS "SOURCE"
-You can select an alternate RubyGems repository for a gem using the ':source' option\.
+You can select an alternate RubyGems repository for a gem using the \':source\' option\.
+.
.IP "" 4
+.
.nf
+
gem "some_internal_gem", source: "https://gems\.example\.com"
+.
.fi
+.
.IP "" 0
+.
.P
This forces the gem to be loaded from this source and ignores the global source declared at the top level of the file\. If the gem does not exist in this source, it will not be installed\.
+.
.P
Bundler will search for child dependencies of this gem by first looking in the source selected for the parent, but if they are not found there, it will fall back on the global source\.
+.
.P
\fBNote about a behavior of the feature deprecated in Bundler 1\.13\fR: Selecting a specific source repository this way also suppresses the ambiguous gem warning described above in \fIGLOBAL SOURCE\fR\.
+.
.P
Using the \fB:source\fR option for an individual gem will also make that source available as a possible global source for any other gems which do not specify explicit sources\. Thus, when adding gems with explicit sources, it is recommended that you also ensure all other gems in the Gemfile are using explicit sources\.
+.
.SS "GIT"
If necessary, you can specify that a gem is located at a particular git repository using the \fB:git\fR parameter\. The repository can be accessed via several protocols:
+.
.TP
\fBHTTP(S)\fR
gem "rails", git: "https://github\.com/rails/rails\.git"
+.
.TP
\fBSSH\fR
gem "rails", git: "git@github\.com:rails/rails\.git"
+.
.TP
\fBgit\fR
gem "rails", git: "git://github\.com/rails/rails\.git"
+.
.P
If using SSH, the user that you use to run \fBbundle install\fR \fBMUST\fR have the appropriate keys available in their \fB$HOME/\.ssh\fR\.
+.
.P
\fBNOTE\fR: \fBhttp://\fR and \fBgit://\fR URLs should be avoided if at all possible\. These protocols are unauthenticated, so a man\-in\-the\-middle attacker can deliver malicious code and compromise your system\. HTTPS and SSH are strongly preferred\.
+.
.P
The \fBgroup\fR, \fBplatforms\fR, and \fBrequire\fR options are available and behave exactly the same as they would for a normal gem\.
+.
.P
A git repository \fBSHOULD\fR have at least one file, at the root of the directory containing the gem, with the extension \fB\.gemspec\fR\. This file \fBMUST\fR contain a valid gem specification, as expected by the \fBgem build\fR command\.
+.
.P
If a git repository does not have a \fB\.gemspec\fR, bundler will attempt to create one, but it will not contain any dependencies, executables, or C extension compilation instructions\. As a result, it may fail to properly integrate into your application\.
+.
.P
If a git repository does have a \fB\.gemspec\fR for the gem you attached it to, a version specifier, if provided, means that the git repository is only valid if the \fB\.gemspec\fR specifies a version matching the version specifier\. If not, bundler will print a warning\.
+.
.IP "" 4
+.
.nf
+
gem "rails", "2\.3\.8", git: "https://github\.com/rails/rails\.git"
# bundle install will fail, because the \.gemspec in the rails
-# repository's master branch specifies version 3\.0\.0
+# repository\'s master branch specifies version 3\.0\.0
+.
.fi
+.
.IP "" 0
+.
.P
If a git repository does \fBnot\fR have a \fB\.gemspec\fR for the gem you attached it to, a version specifier \fBMUST\fR be provided\. Bundler will use this version in the simple \fB\.gemspec\fR it creates\.
+.
.P
Git repositories support a number of additional options\.
+.
.TP
\fBbranch\fR, \fBtag\fR, and \fBref\fR
You \fBMUST\fR only specify at most one of these options\. The default is \fBbranch: "master"\fR\. For example:
+.
.IP
gem "rails", git: "https://github\.com/rails/rails\.git", branch: "5\-0\-stable"
+.
.IP
gem "rails", git: "https://github\.com/rails/rails\.git", tag: "v5\.0\.0"
+.
.IP
gem "rails", git: "https://github\.com/rails/rails\.git", ref: "4aded"
+.
.TP
\fBsubmodules\fR
For reference, a git submodule \fIhttps://git\-scm\.com/book/en/v2/Git\-Tools\-Submodules\fR lets you have another git repository within a subfolder of your repository\. Specify \fBsubmodules: true\fR to cause bundler to expand any submodules included in the git repository
+.
.P
If a git repository contains multiple \fB\.gemspecs\fR, each \fB\.gemspec\fR represents a gem located at the same place in the file system as the \fB\.gemspec\fR\.
+.
.IP "" 4
+.
.nf
+
|~rails [git root]
| |\-rails\.gemspec [rails gem located here]
|~actionpack
| |\-actionpack\.gemspec [actionpack gem located here]
|~activesupport
| |\-activesupport\.gemspec [activesupport gem located here]
-|\|\.\|\.\|\.
+|\.\.\.
+.
.fi
+.
.IP "" 0
+.
.P
To install a gem located in a git repository, bundler changes to the directory containing the gemspec, runs \fBgem build name\.gemspec\fR and then installs the resulting gem\. The \fBgem build\fR command, which comes standard with Rubygems, evaluates the \fB\.gemspec\fR in the context of the directory in which it is located\.
+.
.SS "GIT SOURCE"
-A custom git source can be defined via the \fBgit_source\fR method\. Provide the source's name as an argument, and a block which receives a single argument and interpolates it into a string to return the full repo address:
+A custom git source can be defined via the \fBgit_source\fR method\. Provide the source\'s name as an argument, and a block which receives a single argument and interpolates it into a string to return the full repo address:
+.
.IP "" 4
+.
.nf
+
git_source(:stash){ |repo_name| "https://stash\.corp\.acme\.pl/#{repo_name}\.git" }
-gem 'rails', stash: 'forks/rails'
+gem \'rails\', stash: \'forks/rails\'
+.
.fi
+.
.IP "" 0
+.
.P
In addition, if you wish to choose a specific branch:
+.
.IP "" 4
+.
.nf
+
gem "rails", stash: "forks/rails", branch: "branch_name"
+.
.fi
+.
.IP "" 0
+.
.SS "GITHUB"
\fBNOTE\fR: This shorthand should be avoided until Bundler 2\.0, since it currently expands to an insecure \fBgit://\fR URL\. This allows a man\-in\-the\-middle attacker to compromise your system\.
+.
.P
If the git repository you want to use is hosted on GitHub and is public, you can use the :github shorthand to specify the github username and repository name (without the trailing "\.git"), separated by a slash\. If both the username and repository name are the same, you can omit one\.
+.
.IP "" 4
+.
.nf
+
gem "rails", github: "rails/rails"
gem "rails", github: "rails"
+.
.fi
+.
.IP "" 0
+.
.P
Are both equivalent to
+.
.IP "" 4
+.
.nf
+
gem "rails", git: "https://github\.com/rails/rails\.git"
+.
.fi
+.
.IP "" 0
+.
.P
Since the \fBgithub\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
+.
.P
You can also directly pass a pull request URL:
+.
.IP "" 4
+.
.nf
+
gem "rails", github: "https://github\.com/rails/rails/pull/43753"
+.
.fi
+.
.IP "" 0
+.
.P
Which is equivalent to:
+.
.IP "" 4
+.
.nf
+
gem "rails", github: "rails/rails", branch: "refs/pull/43753/head"
+.
.fi
+.
.IP "" 0
+.
.SS "GIST"
If the git repository you want to use is hosted as a GitHub Gist and is public, you can use the :gist shorthand to specify the gist identifier (without the trailing "\.git")\.
+.
.IP "" 4
+.
.nf
+
gem "the_hatch", gist: "4815162342"
+.
.fi
+.
.IP "" 0
+.
.P
Is equivalent to:
+.
.IP "" 4
+.
.nf
+
gem "the_hatch", git: "https://gist\.github\.com/4815162342\.git"
+.
.fi
+.
.IP "" 0
+.
.P
Since the \fBgist\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
+.
.SS "BITBUCKET"
If the git repository you want to use is hosted on Bitbucket and is public, you can use the :bitbucket shorthand to specify the bitbucket username and repository name (without the trailing "\.git"), separated by a slash\. If both the username and repository name are the same, you can omit one\.
+.
.IP "" 4
+.
.nf
+
gem "rails", bitbucket: "rails/rails"
gem "rails", bitbucket: "rails"
+.
.fi
+.
.IP "" 0
+.
.P
Are both equivalent to
+.
.IP "" 4
+.
.nf
+
gem "rails", git: "https://rails@bitbucket\.org/rails/rails\.git"
+.
.fi
+.
.IP "" 0
+.
.P
Since the \fBbitbucket\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
+.
.SS "PATH"
You can specify that a gem is located in a particular location on the file system\. Relative paths are resolved relative to the directory containing the \fBGemfile\fR\.
+.
.P
Similar to the semantics of the \fB:git\fR option, the \fB:path\fR option requires that the directory in question either contains a \fB\.gemspec\fR for the gem, or that you specify an explicit version that bundler should use\.
+.
.P
Unlike \fB:git\fR, bundler does not compile C extensions for gems specified as paths\.
+.
.IP "" 4
+.
.nf
+
gem "rails", path: "vendor/rails"
+.
.fi
+.
.IP "" 0
+.
.P
-If you would like to use multiple local gems directly from the filesystem, you can set a global \fBpath\fR option to the path containing the gem's files\. This will automatically load gemspec files from subdirectories\.
+If you would like to use multiple local gems directly from the filesystem, you can set a global \fBpath\fR option to the path containing the gem\'s files\. This will automatically load gemspec files from subdirectories\.
+.
.IP "" 4
+.
.nf
-path 'components' do
- gem 'admin_ui'
- gem 'public_ui'
+
+path \'components\' do
+ gem \'admin_ui\'
+ gem \'public_ui\'
end
+.
.fi
+.
.IP "" 0
+.
.SH "BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS"
The \fB:source\fR, \fB:git\fR, \fB:path\fR, \fB:group\fR, and \fB:platforms\fR options may be applied to a group of gems by using block form\.
+.
.IP "" 4
+.
.nf
+
source "https://gems\.example\.com" do
gem "some_internal_gem"
gem "another_internal_gem"
@@ -431,40 +676,61 @@ group :development, optional: true do
gem "wirble"
gem "faker"
end
+.
.fi
+.
.IP "" 0
+.
.P
In the case of the group block form the :optional option can be given to prevent a group from being installed unless listed in the \fB\-\-with\fR option given to the \fBbundle install\fR command\.
+.
.P
In the case of the \fBgit\fR block form, the \fB:ref\fR, \fB:branch\fR, \fB:tag\fR, and \fB:submodules\fR options may be passed to the \fBgit\fR method, and all gems in the block will inherit those options\.
+.
.P
The presence of a \fBsource\fR block in a Gemfile also makes that source available as a possible global source for any other gems which do not specify explicit sources\. Thus, when defining source blocks, it is recommended that you also ensure all other gems in the Gemfile are using explicit sources, either via source blocks or \fB:source\fR directives on individual gems\.
+.
.SH "INSTALL_IF"
The \fBinstall_if\fR method allows gems to be installed based on a proc or lambda\. This is especially useful for optional gems that can only be used if certain software is installed or some other conditions are met\.
+.
.IP "" 4
+.
.nf
+
install_if \-> { RUBY_PLATFORM =~ /darwin/ } do
gem "pasteboard"
end
+.
.fi
+.
.IP "" 0
+.
.SH "GEMSPEC"
-The \fB\.gemspec\fR \fIhttps://guides\.rubygems\.org/specification\-reference/\fR file is where you provide metadata about your gem to Rubygems\. Some required Gemspec attributes include the name, description, and homepage of your gem\. This is also where you specify the dependencies your gem needs to run\.
+The \fB\.gemspec\fR \fIhttp://guides\.rubygems\.org/specification\-reference/\fR file is where you provide metadata about your gem to Rubygems\. Some required Gemspec attributes include the name, description, and homepage of your gem\. This is also where you specify the dependencies your gem needs to run\.
+.
.P
If you wish to use Bundler to help install dependencies for a gem while it is being developed, use the \fBgemspec\fR method to pull in the dependencies listed in the \fB\.gemspec\fR file\.
+.
.P
-The \fBgemspec\fR method adds any runtime dependencies as gem requirements in the default group\. It also adds development dependencies as gem requirements in the \fBdevelopment\fR group\. Finally, it adds a gem requirement on your project (\fBpath: '\.'\fR)\. In conjunction with \fBBundler\.setup\fR, this allows you to require project files in your test code as you would if the project were installed as a gem; you need not manipulate the load path manually or require project files via relative paths\.
+The \fBgemspec\fR method adds any runtime dependencies as gem requirements in the default group\. It also adds development dependencies as gem requirements in the \fBdevelopment\fR group\. Finally, it adds a gem requirement on your project (\fBpath: \'\.\'\fR)\. In conjunction with \fBBundler\.setup\fR, this allows you to require project files in your test code as you would if the project were installed as a gem; you need not manipulate the load path manually or require project files via relative paths\.
+.
.P
The \fBgemspec\fR method supports optional \fB:path\fR, \fB:glob\fR, \fB:name\fR, and \fB:development_group\fR options, which control where bundler looks for the \fB\.gemspec\fR, the glob it uses to look for the gemspec (defaults to: \fB{,*,*/*}\.gemspec\fR), what named \fB\.gemspec\fR it uses (if more than one is present), and which group development dependencies are included in\.
+.
.P
When a \fBgemspec\fR dependency encounters version conflicts during resolution, the local version under development will always be selected \-\- even if there are remote versions that better match other requirements for the \fBgemspec\fR gem\.
+.
.SH "SOURCE PRIORITY"
When attempting to locate a gem to satisfy a gem requirement, bundler uses the following priority order:
+.
.IP "1." 4
The source explicitly attached to the gem (using \fB:source\fR, \fB:path\fR, or \fB:git\fR)
+.
.IP "2." 4
For implicit gems (dependencies of explicit gems), any source, git, or path repository declared on the parent\. This results in bundler prioritizing the ActiveSupport gem from the Rails git repository over ones from \fBrubygems\.org\fR
+.
.IP "3." 4
If neither of the above conditions are met, the global source will be used\. If multiple global sources are specified, they will be prioritized from last to first, but this is deprecated since Bundler 1\.13, so Bundler prints a warning and will abort with an error in the future\.
+.
.IP "" 0
diff --git a/lib/bundler/man/gemfile.5.ronn b/lib/bundler/man/gemfile.5.ronn
index 7c1e00d13a..6749c33f59 100644
--- a/lib/bundler/man/gemfile.5.ronn
+++ b/lib/bundler/man/gemfile.5.ronn
@@ -74,11 +74,6 @@ you can use the `file` option instead.
ruby file: ".ruby-version"
-The version file should conform to any of the following formats:
-
- - `3.1.2` (.ruby-version)
- - `ruby 3.1.2` (.tool-versions, read: https://asdf-vm.com/manage/configuration.html#tool-versions)
-
### ENGINE
Each application _may_ specify a Ruby engine. If an engine is specified, an
@@ -96,7 +91,7 @@ What exactly is an Engine?
- [Other implementations](https://www.ruby-lang.org/en/about/) of Ruby exist.
Some of the more well-known implementations include
- [JRuby](https://www.jruby.org/) and [TruffleRuby](https://www.graalvm.org/ruby/).
+ [JRuby](http://jruby.org/) and [TruffleRuby](https://www.graalvm.org/ruby/).
Rubinius is an alternative implementation of Ruby written in Ruby.
JRuby is an implementation of Ruby on the JVM, short for Java Virtual Machine.
TruffleRuby is a Ruby implementation on the GraalVM, a language toolkit built on the JVM.
@@ -238,10 +233,6 @@ All operations involving groups ([`bundle install`](bundle-install.1.html), `Bun
`Bundler.require`) behave exactly the same as if any groups not
matching the current platform were explicitly excluded.
-The following platform values are deprecated and should be replaced with `windows`:
-
- * `mswin`, `mswin64`, `mingw32`, `x64_mingw`
-
### FORCE_RUBY_PLATFORM
If you always want the pure ruby variant of a gem to be chosen over platform
@@ -509,7 +500,7 @@ software is installed or some other conditions are met.
## GEMSPEC
-The [`.gemspec`](https://guides.rubygems.org/specification-reference/) file is where
+The [`.gemspec`](http://guides.rubygems.org/specification-reference/) file is where
you provide metadata about your gem to Rubygems. Some required Gemspec
attributes include the name, description, and homepage of your gem. This is
also where you specify the dependencies your gem needs to run.
diff --git a/lib/bundler/match_metadata.rb b/lib/bundler/match_metadata.rb
index f6cc27df32..499036ca93 100644
--- a/lib/bundler/match_metadata.rb
+++ b/lib/bundler/match_metadata.rb
@@ -2,10 +2,6 @@
module Bundler
module MatchMetadata
- def matches_current_metadata?
- matches_current_ruby? && matches_current_rubygems?
- end
-
def matches_current_ruby?
@required_ruby_version.satisfied_by?(Gem.ruby_version)
end
diff --git a/lib/bundler/match_platform.rb b/lib/bundler/match_platform.rb
index ece9fb8679..7f7e8227f9 100644
--- a/lib/bundler/match_platform.rb
+++ b/lib/bundler/match_platform.rb
@@ -12,7 +12,7 @@ module Bundler
def self.platforms_match?(gemspec_platform, local_platform)
return true if gemspec_platform.nil?
- return true if gemspec_platform == Gem::Platform::RUBY
+ return true if Gem::Platform::RUBY == gemspec_platform
return true if local_platform == gemspec_platform
gemspec_platform = Gem::Platform.new(gemspec_platform)
return true if gemspec_platform === local_platform
diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb
index 494a6d6aef..9d437a0951 100644
--- a/lib/bundler/mirror.rb
+++ b/lib/bundler/mirror.rb
@@ -47,7 +47,7 @@ module Bundler
def fetch_valid_mirror_for(uri)
downcased = uri.to_s.downcase
- mirror = @mirrors[downcased] || @mirrors[Gem::URI(downcased).host] || Mirror.new(uri)
+ mirror = @mirrors[downcased] || @mirrors[Bundler::URI(downcased).host] || Mirror.new(uri)
mirror.validate!(@prober)
mirror = Mirror.new(uri) unless mirror.valid?
mirror
@@ -74,7 +74,7 @@ module Bundler
@uri = if uri.nil?
nil
else
- Gem::URI(uri.to_s)
+ Bundler::URI(uri.to_s)
end
@valid = nil
end
@@ -126,7 +126,7 @@ module Bundler
if uri == "all"
@all = true
else
- @uri = Gem::URI(uri).absolute? ? Settings.normalize_uri(uri) : uri
+ @uri = Bundler::URI(uri).absolute? ? Settings.normalize_uri(uri) : uri
end
@value = value
end
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 588fa79be8..f3caff8963 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -62,8 +62,7 @@ module Bundler
if names.any?
names.each do |name|
if index.installed?(name)
- path = index.plugin_path(name).to_s
- Bundler.rm_rf(path) if index.installed_in_plugin_root?(name)
+ Bundler.rm_rf(index.plugin_path(name))
index.unregister_plugin(name)
Bundler.ui.info "Uninstalled plugin #{name}"
else
@@ -101,7 +100,7 @@ module Bundler
# @param [Pathname] gemfile path
# @param [Proc] block that can be evaluated for (inline) Gemfile
def gemfile_install(gemfile = nil, &inline)
- Bundler.settings.temporary(frozen: false, deployment: false) do
+ Bundler.settings.temporary(:frozen => false, :deployment => false) do
builder = DSL.new
if block_given?
builder.instance_eval(&inline)
@@ -198,7 +197,7 @@ module Bundler
# @param [Hash] The options that are present in the lock file
# @return [API::Source] the instance of the class that handles the source
# type passed in locked_opts
- def from_lock(locked_opts)
+ def source_from_lock(locked_opts)
src = source(locked_opts["type"])
src.new(locked_opts.merge("uri" => locked_opts["remote"]))
@@ -228,7 +227,7 @@ module Bundler
plugins = index.hook_plugins(event)
return unless plugins.any?
- plugins.each {|name| load_plugin(name) }
+ (plugins - @loaded_plugin_names).each {|name| load_plugin(name) }
@hooks_by_event[event].each {|blk| blk.call(*args, &arg_blk) }
end
@@ -240,11 +239,6 @@ module Bundler
Index.new.installed?(plugin)
end
- # @return [true, false] whether the plugin is loaded
- def loaded?(plugin)
- @loaded_plugin_names.include?(plugin)
- end
-
# Post installation processing and registering with index
#
# @param [Array<String>] plugins list to be installed
@@ -307,7 +301,7 @@ module Bundler
@hooks_by_event = Hash.new {|h, k| h[k] = [] }
load_paths = spec.load_paths
- Gem.add_to_load_path(*load_paths)
+ Bundler.rubygems.add_to_load_path(load_paths)
path = Pathname.new spec.full_gem_path
begin
@@ -335,14 +329,13 @@ module Bundler
# @param [String] name of the plugin
def load_plugin(name)
return unless name && !name.empty?
- return if loaded?(name)
# Need to ensure before this that plugin root where the rest of gems
# are installed to be on load path to support plugin deps. Currently not
# done to avoid conflicts
path = index.plugin_path(name)
- Gem.add_to_load_path(*index.load_paths(name))
+ Bundler.rubygems.add_to_load_path(index.load_paths(name))
load path.join(PLUGIN_FILE_NAME)
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index 8563ee358a..67c45bd204 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -39,7 +39,7 @@ module Bundler
# is present to be compatible with `Definition` and is used by
# rubygems source.
module Source
- attr_reader :uri, :options, :name, :checksum_store
+ attr_reader :uri, :options, :name
attr_accessor :dependency_names
def initialize(opts)
@@ -48,7 +48,6 @@ module Bundler
@uri = opts["uri"]
@type = opts["type"]
@name = opts["name"] || "#{@type} at #{@uri}"
- @checksum_store = Checksum::Store.new
end
# This is used by the default `spec` method to constructs the
@@ -96,7 +95,7 @@ module Bundler
#
# Note: Do not override if you don't know what you are doing.
def post_install(spec, disable_exts = false)
- opts = { env_shebang: false, disable_extensions: disable_exts }
+ opts = { :env_shebang => false, :disable_extensions => disable_exts }
installer = Bundler::Source::Path::Installer.new(spec, opts)
installer.post_install
end
@@ -107,7 +106,7 @@ module Bundler
def install_path
@install_path ||=
begin
- base_name = File.basename(Gem::URI.parse(uri).normalize.path)
+ base_name = File.basename(Bundler::URI.parse(uri).normalize.path)
gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}")
end
@@ -176,7 +175,7 @@ module Bundler
#
# This is used by `app_cache_path`
def app_cache_dirname
- base_name = File.basename(Gem::URI.parse(uri).normalize.path)
+ base_name = File.basename(Bundler::URI.parse(uri).normalize.path)
"#{base_name}-#{uri_hash}"
end
diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb
index c2ab8f90da..a2d5eaa38a 100644
--- a/lib/bundler/plugin/index.rb
+++ b/lib/bundler/plugin/index.rb
@@ -136,14 +136,6 @@ module Bundler
@hooks[event] || []
end
- # This plugin is installed inside the .bundle/plugin directory,
- # and thus is managed solely by Bundler
- def installed_in_plugin_root?(name)
- return false unless (path = installed?(name))
-
- path.start_with?("#{Plugin.root}/")
- end
-
private
# Reads the index file from the directory and initializes the instance
diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb
index 4f60862bb4..c9ff12ce4b 100644
--- a/lib/bundler/plugin/installer.rb
+++ b/lib/bundler/plugin/installer.rb
@@ -10,7 +10,6 @@ module Bundler
class Installer
autoload :Rubygems, File.expand_path("installer/rubygems", __dir__)
autoload :Git, File.expand_path("installer/git", __dir__)
- autoload :Path, File.expand_path("installer/path", __dir__)
def install(names, options)
check_sources_consistency!(options)
@@ -19,8 +18,8 @@ module Bundler
if options[:git]
install_git(names, version, options)
- elsif options[:path]
- install_path(names, version, options[:path])
+ elsif options[:local_git]
+ install_local_git(names, version, options)
else
sources = options[:source] || Gem.sources
install_rubygems(names, version, sources)
@@ -46,40 +45,20 @@ module Bundler
if options.key?(:git) && options.key?(:local_git)
raise InvalidOption, "Remote and local plugin git sources can't be both specified"
end
-
- # back-compat; local_git is an alias for git
- if options.key?(:local_git)
- Bundler::SharedHelpers.major_deprecation(2, "--local_git is deprecated, use --git")
- options[:git] = options.delete(:local_git)
- end
-
- if (options.keys & [:source, :git, :path]).length > 1
- raise InvalidOption, "Only one of --source, --git, or --path may be specified"
- end
-
- if (options.key?(:branch) || options.key?(:ref)) && !options.key?(:git)
- raise InvalidOption, "--#{options.key?(:branch) ? "branch" : "ref"} can only be used with git sources"
- end
-
- if options.key?(:branch) && options.key?(:ref)
- raise InvalidOption, "--branch and --ref can't be both specified"
- end
end
def install_git(names, version, options)
- source_list = SourceList.new
- source = source_list.add_git_source({ "uri" => options[:git],
- "branch" => options[:branch],
- "ref" => options[:ref] })
+ uri = options.delete(:git)
+ options["uri"] = uri
- install_all_sources(names, version, source_list, source)
+ install_all_sources(names, version, options, options[:source])
end
- def install_path(names, version, path)
- source_list = SourceList.new
- source = source_list.add_path_source({ "path" => path, "root_path" => SharedHelpers.pwd })
+ def install_local_git(names, version, options)
+ uri = options.delete(:local_git)
+ options["uri"] = uri
- install_all_sources(names, version, source_list, source)
+ install_all_sources(names, version, options, options[:source])
end
# Installs the plugin from rubygems source and returns the path where the
@@ -91,19 +70,20 @@ module Bundler
#
# @return [Hash] map of names to the specs of plugins installed
def install_rubygems(names, version, sources)
- source_list = SourceList.new
+ install_all_sources(names, version, nil, sources)
+ end
- Array(sources).each {|remote| source_list.add_global_rubygems_remote(remote) }
+ def install_all_sources(names, version, git_source_options, rubygems_source)
+ source_list = SourceList.new
- install_all_sources(names, version, source_list)
- end
+ source_list.add_git_source(git_source_options) if git_source_options
+ Array(rubygems_source).each {|remote| source_list.add_global_rubygems_remote(remote) } if rubygems_source
- def install_all_sources(names, version, source_list, source = nil)
- deps = names.map {|name| Dependency.new(name, version, { "source" => source }) }
+ deps = names.map {|name| Dependency.new name, version }
Bundler.configure_gem_home_and_path(Plugin.root)
- Bundler.settings.temporary(deployment: false, frozen: false) do
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
definition = Definition.new(nil, deps, source_list, true)
install_definition(definition)
diff --git a/lib/bundler/plugin/installer/path.rb b/lib/bundler/plugin/installer/path.rb
deleted file mode 100644
index 58a8fa7426..0000000000
--- a/lib/bundler/plugin/installer/path.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- module Plugin
- class Installer
- class Path < Bundler::Source::Path
- def root
- SharedHelpers.in_bundle? ? Bundler.root : Plugin.root
- end
-
- def generate_bin(spec, disable_extensions = false)
- # Need to find a way without code duplication
- # For now, we can ignore this
- end
- end
- end
- end
-end
diff --git a/lib/bundler/plugin/source_list.rb b/lib/bundler/plugin/source_list.rb
index 746996de55..547661cf2f 100644
--- a/lib/bundler/plugin/source_list.rb
+++ b/lib/bundler/plugin/source_list.rb
@@ -9,10 +9,6 @@ module Bundler
add_source_to_list Plugin::Installer::Git.new(options), git_sources
end
- def add_path_source(options = {})
- add_source_to_list Plugin::Installer::Path.new(options), path_sources
- end
-
def add_rubygems_source(options = {})
add_source_to_list Plugin::Installer::Rubygems.new(options), @rubygems_sources
end
@@ -21,6 +17,10 @@ module Bundler
path_sources + git_sources + rubygems_sources + [metadata_source]
end
+ def default_source
+ git_sources.first || global_rubygems_source
+ end
+
private
def rubygems_aggregate_class
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index 9d237f3fa0..f626a3218e 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -88,10 +88,6 @@ module Bundler
end
end
- def runtime_dependencies
- dependencies.select(&:runtime?)
- end
-
def git_version
return unless loaded_from && source.is_a?(Bundler::Source::Git)
" #{source.revision[0..6]}"
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 1a6711ea6f..2ad35bc931 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -29,7 +29,7 @@ module Bundler
Bundler.ui.info "Resolving dependencies...", true
- solve_versions(root: root, logger: logger)
+ solve_versions(:root => root, :logger => logger)
end
def setup_solver
@@ -37,39 +37,31 @@ module Bundler
root_version = Resolver::Candidate.new(0)
@all_specs = Hash.new do |specs, name|
- source = source_for(name)
- matches = source.specs.search(name)
-
- # Don't bother to check for circular deps when no dependency API are
- # available, since it's too slow to be usable. That edge case won't work
- # but resolution other than that should work fine and reasonably fast.
- if source.respond_to?(:dependency_api_available?) && source.dependency_api_available?
- matches = filter_invalid_self_dependencies(matches, name)
- end
-
- specs[name] = matches.sort_by {|s| [s.version, s.platform.to_s] }
- end
-
- @all_versions = Hash.new do |candidates, package|
- candidates[package] = all_versions_for(package)
+ specs[name] = source_for(name).specs.search(name).reject do |s|
+ s.dependencies.any? {|d| d.name == name && !d.requirement.satisfied_by?(s.version) } # ignore versions that depend on themselves incorrectly
+ end.sort_by {|s| [s.version, s.platform.to_s] }
end
@sorted_versions = Hash.new do |candidates, package|
- candidates[package] = filtered_versions_for(package).sort
+ candidates[package] = if package.root?
+ [root_version]
+ else
+ all_versions_for(package).sort
+ end
end
- @sorted_versions[root] = [root_version]
-
root_dependencies = prepare_dependencies(@requirements, @packages)
@cached_dependencies = Hash.new do |dependencies, package|
- dependencies[package] = Hash.new do |versions, version|
- versions[version] = to_dependency_hash(version.dependencies.reject {|d| d.name == package.name }, @packages)
+ dependencies[package] = if package.root?
+ { root_version => root_dependencies }
+ else
+ Hash.new do |versions, version|
+ versions[version] = to_dependency_hash(version.dependencies.reject {|d| d.name == package.name }, @packages)
+ end
end
end
- @cached_dependencies[root] = { root_version => root_dependencies }
-
logger = Bundler::UI::Shell.new
logger.level = debug? ? "debug" : "warn"
@@ -77,7 +69,7 @@ module Bundler
end
def solve_versions(root:, logger:)
- solver = PubGrub::VersionSolver.new(source: self, root: root, logger: logger)
+ solver = PubGrub::VersionSolver.new(:source => self, :root => root, :logger => logger)
result = solver.solve
result.map {|package, version| version.to_specs(package) }.flatten.uniq
rescue PubGrub::SolveFailure => e
@@ -131,7 +123,7 @@ module Bundler
if base_requirements[name]
names_to_unlock << name
- elsif package.ignores_prereleases? && @all_specs[name].any? {|s| s.version.prerelease? }
+ elsif package.ignores_prereleases?
names_to_allow_prereleases_for << name
end
@@ -152,19 +144,13 @@ module Bundler
requirement_to_range(dependency)
end
- PubGrub::VersionConstraint.new(package, range: range)
+ PubGrub::VersionConstraint.new(package, :range => range)
end
def versions_for(package, range=VersionRange.any)
- versions = select_sorted_versions(package, range)
+ versions = range.select_versions(@sorted_versions[package])
- # Conditional avoids (among other things) calling
- # sort_versions_by_preferred with the root package
- if versions.size > 1
- sort_versions_by_preferred(package, versions)
- else
- versions
- end
+ sort_versions(package, versions)
end
def no_versions_incompatibility_for(package, unsatisfied_term)
@@ -187,7 +173,7 @@ module Bundler
extended_explanation = other_specs_matching_message(specs_matching_other_platforms, label) if specs_matching_other_platforms.any?
end
- Incompatibility.new([unsatisfied_term], cause: cause, custom_explanation: custom_explanation, extended_explanation: extended_explanation)
+ Incompatibility.new([unsatisfied_term], :cause => cause, :custom_explanation => custom_explanation, :extended_explanation => extended_explanation)
end
def debug?
@@ -226,9 +212,9 @@ module Bundler
sorted_versions[high]
end
- range = PubGrub::VersionRange.new(min: low, max: high, include_min: true)
+ range = PubGrub::VersionRange.new(:min => low, :max => high, :include_min => true)
- self_constraint = PubGrub::VersionConstraint.new(package, range: range)
+ self_constraint = PubGrub::VersionConstraint.new(package, :range => range)
dep_term = PubGrub::Term.new(dep_constraint, false)
self_term = PubGrub::Term.new(self_constraint, true)
@@ -237,7 +223,7 @@ module Bundler
"current #{dep_package} version is #{dep_constraint.constraint_string}"
end
- PubGrub::Incompatibility.new([self_term, dep_term], cause: :dependency, custom_explanation: custom_explanation)
+ PubGrub::Incompatibility.new([self_term, dep_term], :cause => :dependency, :custom_explanation => custom_explanation)
end
end
@@ -253,33 +239,21 @@ module Bundler
locked_requirement = base_requirements[name]
results = filter_matching_specs(results, locked_requirement) if locked_requirement
- results.group_by(&:version).reduce([]) do |groups, (version, specs)|
- platform_specs = package.platforms.map {|platform| select_best_platform_match(specs, platform) }
-
- # If package is a top-level dependency,
- # candidate is only valid if there are matching versions for all resolution platforms.
- #
- # If package is not a top-level deependency,
- # then it's not necessary that it has matching versions for all platforms, since it may have been introduced only as
- # a dependency for a platform specific variant, so it will only need to have a valid version for that platform.
- #
- if package.top_level?
- next groups if platform_specs.any?(&:empty?)
- else
- next groups if platform_specs.all?(&:empty?)
- end
-
- platform_specs.flatten!
+ versions = results.group_by(&:version).reduce([]) do |groups, (version, specs)|
+ platform_specs = package.platforms.flat_map {|platform| select_best_platform_match(specs, platform) }
+ next groups if platform_specs.empty?
ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY)
- groups << Resolver::Candidate.new(version, specs: ruby_specs) if ruby_specs.any?
+ groups << Resolver::Candidate.new(version, :specs => ruby_specs) if ruby_specs.any?
next groups if platform_specs == ruby_specs || package.force_ruby_platform?
- groups << Resolver::Candidate.new(version, specs: platform_specs)
+ groups << Resolver::Candidate.new(version, :specs => platform_specs)
groups
end
+
+ sort_versions(package, versions)
end
def source_for(name)
@@ -313,21 +287,15 @@ module Bundler
end
specs_matching_requirement = filter_matching_specs(specs, package.dependency.requirement)
- not_found_message = if specs_matching_requirement.any?
+ if specs_matching_requirement.any?
specs = specs_matching_requirement
matching_part = requirement_label
platforms = package.platforms
-
- if platforms.size == 1
- "Could not find gem '#{requirement_label}' with platform '#{platforms.first}'"
- else
- "Could not find gems matching '#{requirement_label}' valid for all resolution platforms (#{platforms.join(", ")})"
- end
- else
- "Could not find gem '#{requirement_label}'"
+ platform_label = platforms.size == 1 ? "platform '#{platforms.first}" : "platforms '#{platforms.join("', '")}"
+ requirement_label = "#{requirement_label}' with #{platform_label}"
end
- message = String.new("#{not_found_message} in #{source}#{cache_message}.\n")
+ message = String.new("Could not find gem '#{requirement_label}' in #{source}#{cache_message}.\n")
if specs.any?
message << "\n#{other_specs_matching_message(specs, matching_part)}"
@@ -338,21 +306,6 @@ module Bundler
private
- def filtered_versions_for(package)
- @gem_version_promoter.filter_versions(package, @all_versions[package])
- end
-
- def raise_all_versions_filtered_out!(package)
- level = @gem_version_promoter.level
- name = package.name
- locked_version = package.locked_version
- requirement = package.dependency
-
- raise GemNotFound,
- "#{name} is locked to #{locked_version}, while Gemfile is requesting #{requirement}. " \
- "--strict --#{level} was specified, but there are no #{level} level upgrades from #{locked_version} satisfying #{requirement}, so version solving has failed"
- end
-
def filter_matching_specs(specs, requirements)
Array(requirements).flat_map do |requirement|
specs.select {| spec| requirement_satisfied_by?(requirement, spec) }
@@ -365,19 +318,16 @@ module Bundler
specs.reject {|s| s.version.prerelease? }
end
- # Ignore versions that depend on themselves incorrectly
- def filter_invalid_self_dependencies(specs, name)
- specs.reject do |s|
- s.dependencies.any? {|d| d.name == name && !d.requirement.satisfied_by?(s.version) }
- end
- end
-
def requirement_satisfied_by?(requirement, spec)
requirement.satisfied_by?(spec.version) || spec.source.is_a?(Source::Gemspec)
end
- def sort_versions_by_preferred(package, versions)
- @gem_version_promoter.sort_versions(package, versions)
+ def sort_versions(package, versions)
+ if versions.size > 1
+ @gem_version_promoter.sort_versions(package, versions).reverse
+ else
+ versions
+ end
end
def repository_for(package)
@@ -394,19 +344,12 @@ module Bundler
next [dep_package, dep_constraint] if name == "bundler"
- dep_range = dep_constraint.range
- versions = select_sorted_versions(dep_package, dep_range)
+ versions = versions_for(dep_package, dep_constraint.range)
if versions.empty? && dep_package.ignores_prereleases?
- @all_versions.delete(dep_package)
@sorted_versions.delete(dep_package)
dep_package.consider_prereleases!
- versions = select_sorted_versions(dep_package, dep_range)
- end
-
- if versions.empty? && select_all_versions(dep_package, dep_range).any?
- raise_all_versions_filtered_out!(dep_package)
+ versions = versions_for(dep_package, dep_constraint.range)
end
-
next [dep_package, dep_constraint] unless versions.empty?
next unless dep_package.current_platform?
@@ -415,14 +358,6 @@ module Bundler
end.compact.to_h
end
- def select_sorted_versions(package, range)
- range.select_versions(@sorted_versions[package])
- end
-
- def select_all_versions(package, range)
- range.select_versions(@all_versions[package])
- end
-
def other_specs_matching_message(specs, requirement)
message = String.new("The source contains the following gems matching '#{requirement}':\n")
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
@@ -438,19 +373,19 @@ module Bundler
when "~>"
name = "~> #{ver}"
bump = Resolver::Candidate.new(version.bump.to_s + ".A")
- PubGrub::VersionRange.new(name: name, min: ver, max: bump, include_min: true)
+ PubGrub::VersionRange.new(:name => name, :min => ver, :max => bump, :include_min => true)
when ">"
- PubGrub::VersionRange.new(min: platform_ver)
+ PubGrub::VersionRange.new(:min => platform_ver)
when ">="
- PubGrub::VersionRange.new(min: ver, include_min: true)
+ PubGrub::VersionRange.new(:min => ver, :include_min => true)
when "<"
- PubGrub::VersionRange.new(max: ver)
+ PubGrub::VersionRange.new(:max => ver)
when "<="
- PubGrub::VersionRange.new(max: platform_ver, include_max: true)
+ PubGrub::VersionRange.new(:max => platform_ver, :include_max => true)
when "="
- PubGrub::VersionRange.new(min: ver, max: platform_ver, include_min: true, include_max: true)
+ PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true)
when "!="
- PubGrub::VersionRange.new(min: ver, max: platform_ver, include_min: true, include_max: true).invert
+ PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true).invert
else
raise "bad version specifier: #{op}"
end
diff --git a/lib/bundler/resolver/base.rb b/lib/bundler/resolver/base.rb
index ad19eeb3f4..e5c3763c3f 100644
--- a/lib/bundler/resolver/base.rb
+++ b/lib/bundler/resolver/base.rb
@@ -24,7 +24,7 @@ module Bundler
name = dep.name
- @packages[name] = Package.new(name, dep_platforms, **options.merge(dependency: dep))
+ @packages[name] = Package.new(name, dep_platforms, **options.merge(:dependency => dep))
dep
end.compact
diff --git a/lib/bundler/resolver/candidate.rb b/lib/bundler/resolver/candidate.rb
index 9e8b913335..e695ef08ee 100644
--- a/lib/bundler/resolver/candidate.rb
+++ b/lib/bundler/resolver/candidate.rb
@@ -15,7 +15,7 @@ module Bundler
# considered separately.
#
# Some candidates may also keep some information explicitly about the
- # package they refer to. These candidates are referred to as "canonical" and
+ # package the refer to. These candidates are referred to as "canonical" and
# are used when materializing resolution results back into RubyGems
# specifications that can be installed, written to lock files, and so on.
#
diff --git a/lib/bundler/resolver/incompatibility.rb b/lib/bundler/resolver/incompatibility.rb
index 4ac1b2e1ea..c61151fbeb 100644
--- a/lib/bundler/resolver/incompatibility.rb
+++ b/lib/bundler/resolver/incompatibility.rb
@@ -8,7 +8,7 @@ module Bundler
def initialize(terms, cause:, custom_explanation: nil, extended_explanation: nil)
@extended_explanation = extended_explanation
- super(terms, cause: cause, custom_explanation: custom_explanation)
+ super(terms, :cause => cause, :custom_explanation => custom_explanation)
end
end
end
diff --git a/lib/bundler/resolver/package.rb b/lib/bundler/resolver/package.rb
index 0461328683..7499a75006 100644
--- a/lib/bundler/resolver/package.rb
+++ b/lib/bundler/resolver/package.rb
@@ -21,7 +21,6 @@ module Bundler
@locked_version = locked_specs[name].first&.version
@unlock = unlock
@dependency = dependency || Dependency.new(name, @locked_version)
- @top_level = !dependency.nil?
@prerelease = @dependency.prerelease? || @locked_version&.prerelease? || prerelease ? :consider_first : :ignore
end
@@ -33,10 +32,6 @@ module Bundler
false
end
- def top_level?
- @top_level
- end
-
def meta?
@name.end_with?("\0")
end
diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb
index 5cee444e5e..b44c19a73f 100644
--- a/lib/bundler/resolver/spec_group.rb
+++ b/lib/bundler/resolver/spec_group.rb
@@ -25,8 +25,9 @@ module Bundler
def to_specs(force_ruby_platform)
@specs.map do |s|
- lazy_spec = LazySpecification.from_spec(s)
+ lazy_spec = LazySpecification.new(name, version, s.platform, source)
lazy_spec.force_ruby_platform = force_ruby_platform
+ lazy_spec.dependencies.replace s.dependencies
lazy_spec
end
end
@@ -63,6 +64,8 @@ module Bundler
end
def metadata_dependencies(spec)
+ return [] if spec.is_a?(LazySpecification)
+
[
metadata_dependency("Ruby", spec.required_ruby_version),
metadata_dependency("RubyGems", spec.required_rubygems_version),
diff --git a/lib/bundler/retry.rb b/lib/bundler/retry.rb
index b95c42c361..2415ade200 100644
--- a/lib/bundler/retry.rb
+++ b/lib/bundler/retry.rb
@@ -56,7 +56,7 @@ module Bundler
def keep_trying?
return true if current_run.zero?
return false if last_attempt?
- true if @failed
+ return true if @failed
end
def last_attempt?
diff --git a/lib/bundler/ruby_dsl.rb b/lib/bundler/ruby_dsl.rb
index fb4b79c4df..d054969e8d 100644
--- a/lib/bundler/ruby_dsl.rb
+++ b/lib/bundler/ruby_dsl.rb
@@ -3,51 +3,22 @@
module Bundler
module RubyDsl
def ruby(*ruby_version)
- options = ruby_version.pop if ruby_version.last.is_a?(Hash)
+ options = ruby_version.last.is_a?(Hash) ? ruby_version.pop : {}
ruby_version.flatten!
- if options
- patchlevel = options[:patchlevel]
- engine = options[:engine]
- engine_version = options[:engine_version]
+ raise GemfileError, "Please define :engine_version" if options[:engine] && options[:engine_version].nil?
+ raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil?
- raise GemfileError, "Please define :engine_version" if engine && engine_version.nil?
- raise GemfileError, "Please define :engine" if engine_version && engine.nil?
-
- if options[:file]
- raise GemfileError, "Do not pass version argument when using :file option" unless ruby_version.empty?
- ruby_version << normalize_ruby_file(options[:file])
- end
-
- if engine == "ruby" && engine_version && ruby_version != Array(engine_version)
- raise GemfileEvalError, "ruby_version must match the :engine_version for MRI"
- end
+ if options[:file]
+ raise GemfileError, "Cannot specify version when using the file option" if ruby_version.any?
+ ruby_version << Bundler.read_file(options[:file]).strip
end
- @ruby_version = RubyVersion.new(ruby_version, patchlevel, engine, engine_version)
- end
-
- # Support the various file formats found in .ruby-version files.
- #
- # 3.2.2
- # ruby-3.2.2
- #
- # Also supports .tool-versions files for asdf. Lines not starting with "ruby" are ignored.
- #
- # ruby 2.5.1 # comment is ignored
- # ruby 2.5.1# close comment and extra spaces doesn't confuse
- #
- # Intentionally does not support `3.2.1@gemset` since rvm recommends using .ruby-gemset instead
- #
- # Loads the file relative to the dirname of the Gemfile itself.
- def normalize_ruby_file(filename)
- file_content = Bundler.read_file(gemfile.dirname.join(filename))
- # match "ruby-3.2.2" or "ruby 3.2.2" capturing version string up to the first space or comment
- if /^ruby(-|\s+)([^\s#]+)/.match(file_content)
- $2
- else
- file_content.strip
+ if options[:engine] == "ruby" && options[:engine_version] &&
+ ruby_version != Array(options[:engine_version])
+ raise GemfileEvalError, "ruby_version must match the :engine_version for MRI"
end
+ @ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[:engine_version])
end
end
end
diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb
index 7e9e072b83..b5396abb6e 100644
--- a/lib/bundler/ruby_version.rb
+++ b/lib/bundler/ruby_version.rb
@@ -23,7 +23,7 @@ module Bundler
# specified must match the version.
@versions = Array(versions).map do |v|
- op, v = Gem::Requirement.parse(normalize_version(v))
+ op, v = Gem::Requirement.parse(v)
op == "=" ? v.to_s : "#{op} #{v}"
end
@@ -49,7 +49,7 @@ module Bundler
(\d+\.\d+\.\d+(?:\.\S+)?) # ruby version
(?:p(-?\d+))? # optional patchlevel
(?:\s\((\S+)\s(.+)\))? # optional engine info
- /xo
+ /xo.freeze
# Returns a RubyVersion from the given string.
# @param [String] the version string to match.
@@ -112,13 +112,6 @@ module Bundler
private
- # Ruby's official preview version format uses a `-`: Example: 3.3.0-preview2
- # However, RubyGems recognizes preview version format with a `.`: Example: 3.3.0.preview2
- # Returns version string after replacing `-` with `.`
- def normalize_version(version)
- version.tr("-", ".")
- end
-
def matches?(requirements, version)
# Handles RUBY_PATCHLEVEL of -1 for instances like ruby-head
return requirements == version if requirements.to_s == "-1" || version.to_s == "-1"
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index 18180a81a1..8981612706 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
-require "rubygems" unless defined?(Gem)
+require "pathname"
+
+require "rubygems/specification"
# We can't let `Gem::Source` be autoloaded in the `Gem::Specification#source`
# redefinition below, so we need to load it upfront. The reason is that if
@@ -13,6 +15,10 @@ require "rubygems" unless defined?(Gem)
# `Gem::Source` from the redefined `Gem::Specification#source`.
require "rubygems/source"
+require_relative "match_metadata"
+require_relative "force_platform"
+require_relative "match_platform"
+
# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler
# versions and ignore patchlevels
# (https://github.com/rubygems/rubygems/pull/5472,
@@ -23,19 +29,7 @@ unless Gem.ruby_version.to_s == RUBY_VERSION || RUBY_PATCHLEVEL == -1
end
module Gem
- # Can be removed once RubyGems 3.5.11 support is dropped
- unless Gem.respond_to?(:freebsd_platform?)
- def self.freebsd_platform?
- RbConfig::CONFIG["host_os"].to_s.include?("bsd")
- end
- end
-
- require "rubygems/specification"
-
class Specification
- require_relative "match_metadata"
- require_relative "match_platform"
-
include ::Bundler::MatchMetadata
include ::Bundler::MatchPlatform
@@ -52,7 +46,7 @@ module Gem
def full_gem_path
if source.respond_to?(:root)
- File.expand_path(File.dirname(loaded_from), source.root)
+ Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.tap {|x| x.untaint if RUBY_VERSION < "2.7" }
else
rg_full_gem_path
end
@@ -82,7 +76,7 @@ module Gem
end
end
- remove_method :gem_dir
+ remove_method :gem_dir if instance_methods(false).include?(:gem_dir)
def gem_dir
full_gem_path
end
@@ -123,6 +117,17 @@ module Gem
gemfile
end
+ # Backfill missing YAML require when not defined. Fixed since 3.1.0.pre1.
+ module YamlBackfiller
+ def to_yaml(opts = {})
+ Gem.load_yaml unless defined?(::YAML)
+
+ super(opts)
+ end
+ end
+
+ prepend YamlBackfiller
+
def nondevelopment_dependencies
dependencies - development_dependencies
end
@@ -150,23 +155,7 @@ module Gem
end
end
- module BetterPermissionError
- def data
- super
- rescue Errno::EACCES
- raise Bundler::PermissionError.new(loaded_from, :read)
- end
- end
-
- require "rubygems/stub_specification"
-
- class StubSpecification
- prepend BetterPermissionError
- end
-
class Dependency
- require_relative "force_platform"
-
include ::Bundler::ForcePlatform
attr_accessor :source, :groups
@@ -199,7 +188,37 @@ module Gem
end
end
- # Requirements using lambda operator differentiate trailing zeros since rubygems 3.2.6
+ # comparison is done order independently since rubygems 3.2.0.rc.2
+ unless Gem::Requirement.new("> 1", "< 2") == Gem::Requirement.new("< 2", "> 1")
+ class Requirement
+ module OrderIndependentComparison
+ def ==(other)
+ return unless Gem::Requirement === other
+
+ if _requirements_sorted? && other._requirements_sorted?
+ super
+ else
+ _with_sorted_requirements == other._with_sorted_requirements
+ end
+ end
+
+ protected
+
+ def _requirements_sorted?
+ return @_requirements_sorted if defined?(@_requirements_sorted)
+ strings = as_list
+ @_requirements_sorted = strings == strings.sort
+ end
+
+ def _with_sorted_requirements
+ @_with_sorted_requirements ||= _requirements_sorted? ? self : self.class.new(as_list.sort)
+ end
+ end
+
+ prepend OrderIndependentComparison
+ end
+ end
+
if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash
class Requirement
module CorrectHashForLambdaOperator
@@ -301,7 +320,7 @@ module Gem
end
# On universal Rubies, resolve the "universal" arch to the real CPU arch, without changing the extension directory.
- class BasicSpecification
+ class Specification
if /^universal\.(?<arch>.*?)-/ =~ (CROSS_COMPILING || RUBY_PLATFORM)
local_platform = Platform.local
if local_platform.cpu == "universal"
@@ -314,35 +333,23 @@ module Gem
end
def extensions_dir
- @extensions_dir ||=
- Gem.default_ext_dir_for(base_dir) || File.join(base_dir, "extensions", ORIGINAL_LOCAL_PLATFORM, Gem.extension_api_version)
+ Gem.default_ext_dir_for(base_dir) ||
+ File.join(base_dir, "extensions", ORIGINAL_LOCAL_PLATFORM,
+ Gem.extension_api_version)
end
end
end
end
- require "rubygems/name_tuple"
-
- class NameTuple
- # Versions of RubyGems before about 3.5.0 don't to_s the platform.
- unless Gem::NameTuple.new("a", Gem::Version.new("1"), Gem::Platform.new("x86_64-linux")).platform.is_a?(String)
- alias_method :initialize_with_platform, :initialize
+ require "rubygems/util"
- def initialize(name, version, platform=Gem::Platform::RUBY)
- if Gem::Platform === platform
- initialize_with_platform(name, version, platform.to_s)
- else
- initialize_with_platform(name, version, platform)
- end
- end
+ Util.singleton_class.module_eval do
+ if Util.singleton_methods.include?(:glob_files_in_dir) # since 3.0.0.beta.2
+ remove_method :glob_files_in_dir
end
- def lock_name
- if platform == Gem::Platform::RUBY
- "#{name} (#{version})"
- else
- "#{name} (#{version}-#{platform})"
- end
+ def glob_files_in_dir(glob, base_path)
+ Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) }
end
end
end
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb
index d563868cd2..38035a00ac 100644
--- a/lib/bundler/rubygems_gem_installer.rb
+++ b/lib/bundler/rubygems_gem_installer.rb
@@ -20,7 +20,7 @@ module Bundler
strict_rm_rf spec.extension_dir
SharedHelpers.filesystem_access(gem_dir, :create) do
- FileUtils.mkdir_p gem_dir, mode: 0o755
+ FileUtils.mkdir_p gem_dir, :mode => 0o755
end
extract_files
@@ -45,14 +45,6 @@ module Bundler
spec
end
- def pre_install_checks
- super
- rescue Gem::FilePermissionError
- # Ignore permission checks in RubyGems. Instead, go on, and try to write
- # for real. We properly handle permission errors when they happen.
- nil
- end
-
def generate_plugins
return unless Gem::Installer.instance_methods(false).include?(:generate_plugins)
@@ -68,6 +60,10 @@ module Bundler
end
end
+ def pre_install_checks
+ super && validate_bundler_checksum(options[:bundler_expected_checksum])
+ end
+
def build_extensions
extension_cache_path = options[:bundler_extension_cache_path]
extension_dir = spec.extension_dir
@@ -102,10 +98,6 @@ module Bundler
end
end
- def gem_checksum
- Checksum.from_gem_package(@package)
- end
-
private
def prepare_extension_build(extension_dir)
@@ -116,21 +108,64 @@ module Bundler
end
def strict_rm_rf(dir)
- return unless File.exist?(dir)
+ Bundler.rm_rf dir
+ rescue StandardError => e
+ raise unless File.exist?(dir)
- parent = File.dirname(dir)
- parent_st = File.stat(parent)
+ raise DirectoryRemovalError.new(e, "Could not delete previous installation of `#{dir}`")
+ end
+
+ def validate_bundler_checksum(checksum)
+ return true if Bundler.settings[:disable_checksum_validation]
+ return true unless checksum
+ return true unless source = @package.instance_variable_get(:@gem)
+ return true unless source.respond_to?(:with_read_io)
+ digest = source.with_read_io do |io|
+ digest = SharedHelpers.digest(:SHA256).new
+ digest << io.read(16_384) until io.eof?
+ io.rewind
+ send(checksum_type(checksum), digest)
+ end
+ unless digest == checksum
+ raise SecurityError, <<-MESSAGE
+ Bundler cannot continue installing #{spec.name} (#{spec.version}).
+ The checksum for the downloaded `#{spec.full_name}.gem` does not match \
+ the checksum given by the server. This means the contents of the downloaded \
+ gem is different from what was uploaded to the server, and could be a potential security issue.
+
+ To resolve this issue:
+ 1. delete the downloaded gem located at: `#{spec.gem_dir}/#{spec.full_name}.gem`
+ 2. run `bundle install`
+
+ If you wish to continue installing the downloaded gem, and are certain it does not pose a \
+ security issue despite the mismatching checksum, do the following:
+ 1. run `bundle config set --local disable_checksum_validation true` to turn off checksum verification
+ 2. run `bundle install`
+
+ (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
+ checksum for the downloaded gem was #{digest.inspect}.)
+ MESSAGE
+ end
+ true
+ end
- if parent_st.world_writable? && !parent_st.sticky?
- raise InsecureInstallPathError.new(parent)
+ def checksum_type(checksum)
+ case checksum.length
+ when 64 then :hexdigest!
+ when 44 then :base64digest!
+ else raise InstallError, "The given checksum for #{spec.full_name} (#{checksum.inspect}) is not a valid SHA256 hexdigest nor base64digest"
end
+ end
- begin
- FileUtils.remove_entry_secure(dir)
- rescue StandardError => e
- raise unless File.exist?(dir)
+ def hexdigest!(digest)
+ digest.hexdigest!
+ end
- raise DirectoryRemovalError.new(e, "Could not delete previous installation of `#{dir}`")
+ def base64digest!(digest)
+ if digest.respond_to?(:base64digest!)
+ digest.base64digest!
+ else
+ [digest.digest!].pack("m0")
end
end
end
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index da555681f9..d8b7886af7 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -4,12 +4,17 @@ require "rubygems" unless defined?(Gem)
module Bundler
class RubygemsIntegration
- require "monitor"
+ if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
+ EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
+ else
+ require "monitor"
- EXT_LOCK = Monitor.new
+ EXT_LOCK = Monitor.new
+ end
def initialize
@replaced_methods = {}
+ backport_ext_builder_monitor
end
def version
@@ -38,6 +43,18 @@ module Bundler
Gem.loaded_specs[name]
end
+ def add_to_load_path(paths)
+ return Gem.add_to_load_path(*paths) if Gem.respond_to?(:add_to_load_path)
+
+ if insert_index = Gem.load_path_insert_index
+ # Gem directories must come after -I and ENV['RUBYLIB']
+ $LOAD_PATH.insert(insert_index, *paths)
+ else
+ # We are probably testing in core, -I and RUBYLIB don't apply
+ $LOAD_PATH.unshift(*paths)
+ end
+ end
+
def mark_loaded(spec)
if spec.respond_to?(:activated=)
current = Gem.loaded_specs[spec.name]
@@ -74,9 +91,9 @@ module Bundler
def spec_matches_for_glob(spec, glob)
return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob)
- spec.load_paths.flat_map do |lp|
+ spec.load_paths.map do |lp|
Dir["#{lp}/#{glob}#{suffix_pattern}"]
- end
+ end.flatten(1)
end
def stub_set_spec(stub, spec)
@@ -99,6 +116,16 @@ module Bundler
Gem::Util.inflate(obj)
end
+ def correct_for_windows_path(path)
+ if Gem::Util.respond_to?(:correct_for_windows_path)
+ Gem::Util.correct_for_windows_path(path)
+ elsif path[0].chr == "/" && path[1].chr =~ /[a-z]/i && path[2].chr == ":"
+ path[1..-1]
+ else
+ path
+ end
+ end
+
def gem_dir
Gem.dir
end
@@ -134,7 +161,7 @@ module Bundler
def spec_cache_dirs
@spec_cache_dirs ||= begin
dirs = gem_path.map {|dir| File.join(dir, "specifications") }
- dirs << Gem.spec_cache_dir
+ dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in RubyGems 2.0.3 or earlier
dirs.uniq.select {|dir| File.directory? dir }
end
end
@@ -156,6 +183,18 @@ module Bundler
loaded_gem_paths.flatten
end
+ def load_plugins
+ Gem.load_plugins if Gem.respond_to?(:load_plugins)
+ end
+
+ def load_plugin_files(files)
+ Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files)
+ end
+
+ def load_env_plugins
+ Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)
+ end
+
def ui=(obj)
Gem::DefaultUserInteraction.ui = obj
end
@@ -191,7 +230,8 @@ module Bundler
if Gem.respond_to?(:discover_gems_on_require=)
Gem.discover_gems_on_require = false
else
- [::Kernel.singleton_class, ::Kernel].each do |k|
+ kernel = (class << ::Kernel; self; end)
+ [kernel, ::Kernel].each do |k|
if k.private_method_defined?(:gem_original_require)
redefine_method(k, :require, k.instance_method(:gem_original_require))
end
@@ -200,9 +240,12 @@ module Bundler
end
def replace_gem(specs, specs_by_name)
+ reverse_rubygems_kernel_mixin
+
executables = nil
- [::Kernel.singleton_class, ::Kernel].each do |kernel_class|
+ kernel = (class << ::Kernel; self; end)
+ [kernel, ::Kernel].each do |kernel_class|
redefine_method(kernel_class, :gem) do |dep, *reqs|
if executables&.include?(File.basename(caller.first.split(":").first))
break
@@ -315,14 +358,6 @@ module Bundler
def replace_entrypoints(specs)
specs_by_name = add_default_gems_to(specs)
- reverse_rubygems_kernel_mixin
- begin
- # bundled_gems only provide with Ruby 3.3 or later
- require "bundled_gems"
- rescue LoadError
- else
- Gem::BUNDLED_GEMS.replace_require(specs) if Gem::BUNDLED_GEMS.respond_to?(:replace_require)
- end
replace_gem(specs, specs_by_name)
stub_rubygems(specs)
replace_bin_path(specs_by_name)
@@ -412,28 +447,30 @@ module Bundler
Gem::Specification.all = specs
end
- def fetch_specs(remote, name, fetcher)
+ def fetch_specs(remote, name)
require "rubygems/remote_fetcher"
path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
+ fetcher = gem_remote_fetcher
+ fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
string = fetcher.fetch_path(path)
- specs = Bundler.safe_load_marshal(string)
- raise MarshalError, "Specs #{name} from #{remote} is expected to be an Array but was unexpected class #{specs.class}" unless specs.is_a?(Array)
- specs
+ Bundler.safe_load_marshal(string)
rescue Gem::RemoteFetcher::FetchError
# it's okay for prerelease to fail
raise unless name == "prerelease_specs"
end
- def fetch_all_remote_specs(remote, gem_remote_fetcher)
- specs = fetch_specs(remote, "specs", gem_remote_fetcher)
- pres = fetch_specs(remote, "prerelease_specs", gem_remote_fetcher) || []
+ def fetch_all_remote_specs(remote)
+ specs = fetch_specs(remote, "specs")
+ pres = fetch_specs(remote, "prerelease_specs") || []
specs.concat(pres)
end
- def download_gem(spec, uri, cache_dir, fetcher)
+ def download_gem(spec, uri, cache_dir)
require "rubygems/remote_fetcher"
uri = Bundler.settings.mirror_for(uri)
+ fetcher = gem_remote_fetcher
+ fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
Bundler::Retry.new("download gem from #{uri}").attempts do
gem_file_name = spec.file_name
local_gem_path = File.join cache_dir, gem_file_name
@@ -441,6 +478,7 @@ module Bundler
begin
remote_gem_path = uri + "gems/#{gem_file_name}"
+ remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
SharedHelpers.filesystem_access(local_gem_path) do
fetcher.cache_update_path remote_gem_path, local_gem_path
@@ -459,6 +497,12 @@ module Bundler
raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
end
+ def gem_remote_fetcher
+ require "rubygems/remote_fetcher"
+ proxy = Gem.configuration[:http_proxy]
+ Gem::RemoteFetcher.new(proxy)
+ end
+
def build(spec, skip_validation = false)
require "rubygems/package"
Gem::Package.build(spec, skip_validation)
@@ -474,6 +518,25 @@ module Bundler
end
end
+ def backport_ext_builder_monitor
+ # So we can avoid requiring "rubygems/ext" in its entirety
+ Gem.module_eval <<-RUBY, __FILE__, __LINE__ + 1
+ module Ext
+ end
+ RUBY
+
+ require "rubygems/ext/builder"
+
+ Gem::Ext::Builder.class_eval do
+ unless const_defined?(:CHDIR_MONITOR)
+ const_set(:CHDIR_MONITOR, EXT_LOCK)
+ end
+
+ remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
+ const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
+ end
+ end
+
def find_bundler(version)
find_name("bundler").find {|s| s.version.to_s == version }
end
@@ -482,8 +545,14 @@ module Bundler
Gem::Specification.stubs_for(name).map(&:to_spec)
end
- def default_stubs
- Gem::Specification.default_stubs("*.gemspec")
+ if Gem::Specification.respond_to?(:default_stubs)
+ def default_stubs
+ Gem::Specification.default_stubs("*.gemspec")
+ end
+ else
+ def default_stubs
+ Gem::Specification.send(:default_stubs, "*.gemspec")
+ end
end
end
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index ec772cfe7b..95cf78dd41 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -28,11 +28,11 @@ module Bundler
spec.load_paths.reject {|path| $LOAD_PATH.include?(path) }
end.reverse.flatten
- Gem.add_to_load_path(*load_paths)
+ Bundler.rubygems.add_to_load_path(load_paths)
setup_manpath
- lock(preserve_unknown_sections: true)
+ lock(:preserve_unknown_sections => true)
self
end
@@ -95,7 +95,7 @@ module Bundler
def lock(opts = {})
return if @definition.no_resolve_needed?
- @definition.lock(opts[:preserve_unknown_sections])
+ @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
end
alias_method :gems, :specs
diff --git a/lib/bundler/self_manager.rb b/lib/bundler/self_manager.rb
index 5accda4bcb..827f3f9222 100644
--- a/lib/bundler/self_manager.rb
+++ b/lib/bundler/self_manager.rb
@@ -9,23 +9,17 @@ module Bundler
def restart_with_locked_bundler_if_needed
return unless needs_switching? && installed?
- restart_with(restart_version)
+ restart_with(lockfile_version)
end
def install_locked_bundler_and_restart_with_it_if_needed
return unless needs_switching?
- if restart_version == lockfile_version
- Bundler.ui.info \
- "Bundler #{current_version} is running, but your lockfile was generated with #{lockfile_version}. " \
- "Installing Bundler #{lockfile_version} and restarting using that version."
- else
- Bundler.ui.info \
- "Bundler #{current_version} is running, but your configuration was #{restart_version}. " \
- "Installing Bundler #{restart_version} and restarting using that version."
- end
+ Bundler.ui.info \
+ "Bundler #{current_version} is running, but your lockfile was generated with #{lockfile_version}. " \
+ "Installing Bundler #{lockfile_version} and restarting using that version."
- install_and_restart_with(restart_version)
+ install_and_restart_with(lockfile_version)
end
def update_bundler_and_restart_with_it_if_needed(target)
@@ -85,8 +79,7 @@ module Bundler
autoswitching_applies? &&
released?(lockfile_version) &&
!running?(lockfile_version) &&
- !updating? &&
- Bundler.settings[:version] != "system"
+ !updating?
end
def autoswitching_applies?
@@ -121,7 +114,7 @@ module Bundler
source = Bundler::Source::Rubygems.new("remotes" => "https://rubygems.org")
source.remote!
source.add_dependency_names("bundler")
- source.specs.select(&:matches_current_metadata?)
+ source.specs
end
end
@@ -158,7 +151,7 @@ module Bundler
def installed?
Bundler.configure
- Bundler.rubygems.find_bundler(restart_version.to_s)
+ Bundler.rubygems.find_bundler(lockfile_version.to_s)
end
def current_version
@@ -170,17 +163,6 @@ module Bundler
parsed_version = Bundler::LockfileParser.bundled_with
@lockfile_version = parsed_version ? Gem::Version.new(parsed_version) : nil
- rescue ArgumentError
- @lockfile_version = nil
- end
-
- def restart_version
- return @restart_version if defined?(@restart_version)
- # BUNDLE_VERSION=x.y.z
- @restart_version = Gem::Version.new(Bundler.settings[:version])
- rescue ArgumentError
- # BUNDLE_VERSION=lockfile
- @restart_version = lockfile_version
end
end
end
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index abbaec9783..0af2236a45 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -7,6 +7,7 @@ module Bundler
autoload :Validator, File.expand_path("settings/validator", __dir__)
BOOL_KEYS = %w[
+ allow_deployment_source_credential_changes
allow_offline_install
auto_clean_without_path
auto_install
@@ -45,20 +46,6 @@ module Bundler
update_requires_all_flag
].freeze
- REMEMBERED_KEYS = %w[
- bin
- cache_all
- clean
- deployment
- frozen
- no_prune
- path
- shebang
- path.system
- without
- with
- ].freeze
-
NUMBER_KEYS = %w[
jobs
redirect
@@ -87,7 +74,6 @@ module Bundler
shebang
system_bindir
trust-policy
- version
].freeze
DEFAULT_CONFIG = {
@@ -97,38 +83,25 @@ module Bundler
"BUNDLE_REDIRECT" => 5,
"BUNDLE_RETRY" => 3,
"BUNDLE_TIMEOUT" => 10,
- "BUNDLE_VERSION" => "lockfile",
}.freeze
def initialize(root = nil)
@root = root
@local_config = load_config(local_config_file)
-
- @env_config = ENV.to_h
- @env_config.select! {|key, _value| key.start_with?("BUNDLE_") }
- @env_config.delete("BUNDLE_")
-
+ @env_config = ENV.to_h.select {|key, _value| key =~ /\ABUNDLE_.+/ }
@global_config = load_config(global_config_file)
@temporary = {}
-
- @key_cache = {}
end
def [](name)
key = key_for(name)
-
- value = nil
- configs.each do |_, config|
- value = config[key]
- next if value.nil?
- break
- end
+ value = configs.values.map {|config| config[key] }.compact.first
converted_value(value, name)
end
def set_command_option(key, value)
- if !is_remembered(key) || Bundler.feature_flag.forget_cli_options?
+ if Bundler.feature_flag.forget_cli_options?
temporary(key => value)
value
else
@@ -165,22 +138,17 @@ module Bundler
end
def all
- keys = @temporary.keys.union(@global_config.keys, @local_config.keys, @env_config.keys)
+ keys = @temporary.keys | @global_config.keys | @local_config.keys | @env_config.keys
- keys.map! do |key|
- key = key.delete_prefix("BUNDLE_")
- key.gsub!("___", "-")
- key.gsub!("__", ".")
- key.downcase!
- key
- end.sort!
- keys
+ keys.map do |key|
+ key.sub(/^BUNDLE_/, "").gsub(/___/, "-").gsub(/__/, ".").downcase
+ end.sort
end
def local_overrides
repos = {}
all.each do |k|
- repos[k.delete_prefix("local.")] = self[k] if k.start_with?("local.")
+ repos[$'] = self[k] if k =~ /^local\./
end
repos
end
@@ -188,7 +156,7 @@ module Bundler
def mirror_for(uri)
if uri.is_a?(String)
require_relative "vendored_uri"
- uri = Gem::URI(uri)
+ uri = Bundler::URI(uri)
end
gem_mirrors.for(uri.to_s).uri
@@ -327,18 +295,18 @@ module Bundler
end
def key_for(key)
- @key_cache[key] ||= self.class.key_for(key)
+ self.class.key_for(key)
end
private
def configs
- @configs ||= {
- temporary: @temporary,
- local: @local_config,
- env: @env_config,
- global: @global_config,
- default: DEFAULT_CONFIG,
+ {
+ :temporary => @temporary,
+ :local => @local_config,
+ :env => @env_config,
+ :global => @global_config,
+ :default => DEFAULT_CONFIG,
}
end
@@ -359,20 +327,16 @@ module Bundler
end
def is_bool(name)
- name = self.class.key_to_s(name)
- BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name))
+ BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
end
def is_string(name)
- name = self.class.key_to_s(name)
- STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.")
+ STRING_KEYS.include?(name.to_s) || name.to_s.start_with?("local.") || name.to_s.start_with?("mirror.") || name.to_s.start_with?("build.")
end
def to_bool(value)
case value
- when String
- value.match?(/\A(false|f|no|n|0|)\z/i) ? false : true
- when nil, false
+ when nil, /\A(false|f|no|n|0|)\z/i, false
false
else
true
@@ -380,15 +344,11 @@ module Bundler
end
def is_num(key)
- NUMBER_KEYS.include?(self.class.key_to_s(key))
+ NUMBER_KEYS.include?(key.to_s)
end
def is_array(key)
- ARRAY_KEYS.include?(self.class.key_to_s(key))
- end
-
- def is_remembered(key)
- REMEMBERED_KEYS.include?(self.class.key_to_s(key))
+ ARRAY_KEYS.include?(key.to_s)
end
def is_credential(key)
@@ -411,7 +371,7 @@ module Bundler
end
def set_key(raw_key, value, hash, file)
- raw_key = self.class.key_to_s(raw_key)
+ raw_key = raw_key.to_s
value = array_to_s(value) if is_array(raw_key)
key = key_for(raw_key)
@@ -426,13 +386,12 @@ module Bundler
return unless file
SharedHelpers.filesystem_access(file) do |p|
FileUtils.mkdir_p(p.dirname)
- p.open("w") {|f| f.write(serializer_class.dump(hash)) }
+ require_relative "yaml_serializer"
+ p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) }
end
end
def converted_value(value, key)
- key = self.class.key_to_s(key)
-
if is_array(key)
to_array(value)
elsif value.nil?
@@ -490,34 +449,24 @@ module Bundler
SharedHelpers.filesystem_access(config_file, :read) do |file|
valid_file = file.exist? && !file.size.zero?
return {} unless valid_file
- serializer_class.load(file.read).inject({}) do |config, (k, v)|
- unless k.start_with?("#")
- if k.include?("-")
- Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
- "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
- "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
-
- # string hash keys are frozen
- k = k.gsub("-", "___")
- end
-
- config[k] = v
+ require_relative "yaml_serializer"
+ YAMLSerializer.load(file.read).inject({}) do |config, (k, v)|
+ new_k = k
+
+ if k.include?("-")
+ Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
+ "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
+ "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
+
+ new_k = k.gsub("-", "___")
end
+ config[new_k] = v
config
end
end
end
- def serializer_class
- require "rubygems/yaml_serializer"
- Gem::YAMLSerializer
- rescue LoadError
- # TODO: Remove this when RubyGems 3.4 is EOL
- require_relative "yaml_serializer"
- YAMLSerializer
- end
-
PER_URI_OPTIONS = %w[
fallback_timeout
].freeze
@@ -529,15 +478,12 @@ module Bundler
(https?.*?) # URI
(\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key
\z
- /ix
+ /ix.freeze
def self.key_for(key)
key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http")
- key = key_to_s(key).gsub(".", "__")
- key.gsub!("-", "___")
- key.upcase!
-
- key.prepend("BUNDLE_")
+ key = key.to_s.gsub(".", "__").gsub("-", "___").upcase
+ "BUNDLE_#{key}"
end
# TODO: duplicates Rubygems#normalize_uri
@@ -551,40 +497,11 @@ module Bundler
end
uri = URINormalizer.normalize_suffix(uri)
require_relative "vendored_uri"
- uri = Gem::URI(uri)
+ uri = Bundler::URI(uri)
unless uri.absolute?
raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri)
end
"#{prefix}#{uri}#{suffix}"
end
-
- # This is a hot method, so avoid respond_to? checks on every invocation
- if :read.respond_to?(:name)
- def self.key_to_s(key)
- case key
- when String
- key
- when Symbol
- key.name
- when Gem::URI::HTTP
- key.to_s
- else
- raise ArgumentError, "Invalid key: #{key.inspect}"
- end
- end
- else
- def self.key_to_s(key)
- case key
- when String
- key
- when Symbol
- key.to_s
- when Gem::URI::HTTP
- key.to_s
- else
- raise ArgumentError, "Invalid key: #{key.inspect}"
- end
- end
- end
end
end
diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb
index 6010d66742..801fd5312a 100644
--- a/lib/bundler/setup.rb
+++ b/lib/bundler/setup.rb
@@ -5,9 +5,6 @@ require_relative "shared_helpers"
if Bundler::SharedHelpers.in_bundle?
require_relative "../bundler"
- # try to auto_install first before we get to the `Bundler.ui.silence`, so user knows what is happening
- Bundler.auto_install
-
if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"]
begin
Bundler.ui.silence { Bundler.setup }
@@ -15,10 +12,7 @@ if Bundler::SharedHelpers.in_bundle?
Bundler.ui.error e.message
Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
if e.is_a?(Bundler::GemNotFound)
- default_bundle = Gem.bin_path("bundler", "bundle")
- current_bundle = Bundler::SharedHelpers.bundle_bin_path
- suggested_bundle = default_bundle == current_bundle ? "bundle" : current_bundle
- suggested_cmd = "#{suggested_bundle} install"
+ suggested_cmd = "bundle install"
original_gemfile = Bundler.original_env["BUNDLE_GEMFILE"]
suggested_cmd += " --gemfile #{original_gemfile}" if original_gemfile
Bundler.ui.warn "Run `#{suggested_cmd}` to install missing gems."
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index 28f0cdff19..d1d4e1d07a 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -1,27 +1,25 @@
# frozen_string_literal: true
+require "pathname"
+require "rbconfig"
+
require_relative "version"
+require_relative "constants"
require_relative "rubygems_integration"
require_relative "current_ruby"
module Bundler
- autoload :WINDOWS, File.expand_path("constants", __dir__)
- autoload :FREEBSD, File.expand_path("constants", __dir__)
- autoload :NULL, File.expand_path("constants", __dir__)
-
module SharedHelpers
- autoload :Pathname, "pathname"
-
def root
gemfile = find_gemfile
raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
- Pathname.new(gemfile).expand_path.parent
+ Pathname.new(gemfile).tap {|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path.parent
end
def default_gemfile
gemfile = find_gemfile
raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
- Pathname.new(gemfile).expand_path
+ Pathname.new(gemfile).tap {|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path
end
def default_lockfile
@@ -30,7 +28,7 @@ module Bundler
case gemfile.basename.to_s
when "gems.rb" then Pathname.new(gemfile.sub(/.rb$/, ".locked"))
else Pathname.new("#{gemfile}.lock")
- end
+ end.tap {|x| x.untaint if RUBY_VERSION < "2.7" }
end
def default_bundle_dir
@@ -102,7 +100,7 @@ module Bundler
#
# @see {Bundler::PermissionError}
def filesystem_access(path, action = :write, &block)
- yield(path.dup)
+ yield(path.dup.tap {|x| x.untaint if RUBY_VERSION < "2.7" })
rescue Errno::EACCES
raise PermissionError.new(path, action)
rescue Errno::EAGAIN
@@ -119,18 +117,16 @@ module Bundler
raise GenericSystemCallError.new(e, "There was an error accessing `#{path}`.")
end
- def major_deprecation(major_version, message, removed_message: nil, print_caller_location: false)
+ def major_deprecation(major_version, message, print_caller_location: false)
if print_caller_location
caller_location = caller_locations(2, 2).first
- suffix = " (called at #{caller_location.path}:#{caller_location.lineno})"
- message += suffix
- removed_message += suffix if removed_message
+ message = "#{message} (called at #{caller_location.path}:#{caller_location.lineno})"
end
bundler_major_version = Bundler.bundler_major_version
if bundler_major_version > major_version
require_relative "errors"
- raise DeprecatedError, "[REMOVED] #{removed_message || message}"
+ raise DeprecatedError, "[REMOVED] #{message}"
end
return unless bundler_major_version >= major_version && prints_major_deprecations?
@@ -197,40 +193,10 @@ module Bundler
Digest(name)
end
- def checksum_for_file(path, digest)
- return unless path.file?
- # This must use File.read instead of Digest.file().hexdigest
- # because we need to preserve \n line endings on windows when calculating
- # the checksum
- SharedHelpers.filesystem_access(path, :read) do
- File.open(path, "rb") do |f|
- digest = SharedHelpers.digest(digest).new
- buf = String.new(capacity: 16_384, encoding: Encoding::BINARY)
- digest << buf while f.read(16_384, buf)
- digest.hexdigest
- end
- end
- end
-
def write_to_gemfile(gemfile_path, contents)
filesystem_access(gemfile_path) {|g| File.open(g, "w") {|file| file.puts contents } }
end
- def relative_gemfile_path
- relative_path_to(Bundler.default_gemfile)
- end
-
- def relative_lockfile_path
- relative_path_to(Bundler.default_lockfile)
- end
-
- def relative_path_to(destination, from: pwd)
- Pathname.new(destination).relative_path_from(from).to_s
- rescue ArgumentError
- # on Windows, if source and destination are on different drivers, there's no relative path from one to the other
- destination
- end
-
private
def validate_bundle_path
@@ -269,7 +235,7 @@ module Bundler
def search_up(*names)
previous = nil
- current = File.expand_path(SharedHelpers.pwd)
+ current = File.expand_path(SharedHelpers.pwd).tap {|x| x.untaint if RUBY_VERSION < "2.7" }
until !File.directory?(current) || current == previous
if ENV["BUNDLER_SPEC_RUN"]
@@ -306,13 +272,6 @@ module Bundler
public :set_env
def set_bundle_variables
- Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", bundle_bin_path
- Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
- Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
- Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__)
- end
-
- def bundle_bin_path
# bundler exe & lib folders have same root folder, typical gem installation
exe_file = File.expand_path("../../exe/bundle", __dir__)
@@ -322,9 +281,11 @@ module Bundler
# bundler is a default gem, exe path is separate
exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file)
- exe_file
+ Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
+ Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
+ Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__) unless RUBY_VERSION < "2.7"
end
- public :bundle_bin_path
def set_path
validate_bundle_path
@@ -336,7 +297,7 @@ module Bundler
def set_rubyopt
rubyopt = [ENV["RUBYOPT"]].compact
setup_require = "-r#{File.expand_path("setup", __dir__)}"
- return if !rubyopt.empty? && rubyopt.first.include?(setup_require)
+ return if !rubyopt.empty? && rubyopt.first =~ /#{setup_require}/
rubyopt.unshift setup_require
Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ")
end
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index 115dbd1378..f7f5ea7865 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -11,8 +11,6 @@ module Bundler
attr_accessor :dependency_names
- attr_reader :checksum_store
-
def unmet_deps
specs.unmet_dependency_names
end
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index 198e335bb6..adbce5fce4 100644
--- a/lib/bundler/source/git.rb
+++ b/lib/bundler/source/git.rb
@@ -11,7 +11,6 @@ module Bundler
def initialize(options)
@options = options
- @checksum_store = Checksum::Store.new
@glob = options["glob"] || DEFAULT_GLOB
@allow_cached = false
@@ -20,7 +19,7 @@ module Bundler
# Stringify options that could be set as symbols
%w[ref branch tag revision].each {|k| options[k] = options[k].to_s if options[k] }
- @uri = URINormalizer.normalize_suffix(options["uri"] || "", trailing_slash: false)
+ @uri = URINormalizer.normalize_suffix(options["uri"] || "", :trailing_slash => false)
@safe_uri = URICredentialsFilter.credential_filtered_uri(@uri)
@branch = options["branch"]
@ref = options["ref"] || options["branch"] || options["tag"]
@@ -198,7 +197,7 @@ module Bundler
@copied = true
end
- generate_bin_options = { disable_extensions: !Bundler.rubygems.spec_missing_extensions?(spec), build_args: options[:build_args] }
+ generate_bin_options = { :disable_extensions => !Bundler.rubygems.spec_missing_extensions?(spec), :build_args => options[:build_args] }
generate_bin(spec, generate_bin_options)
requires_checkout? ? spec.post_install_message : nil
@@ -326,7 +325,7 @@ module Bundler
if %r{^\w+://(\w+@)?}.match?(uri)
# Downcase the domain component of the URI
# and strip off a trailing slash, if one is present
- input = Gem::URI.parse(uri).normalize.to_s.sub(%r{/$}, "")
+ input = Bundler::URI.parse(uri).normalize.to_s.sub(%r{/$}, "")
else
# If there is no URI scheme, assume it is an ssh/git URI
input = uri
@@ -360,7 +359,7 @@ module Bundler
def load_gemspec(file)
stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
- stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s
+ stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s.tap {|x| x.untaint if RUBY_VERSION < "2.7" }
StubSpecification.from_stub(stub)
end
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
index 2fc9c6535f..fdb738e52e 100644
--- a/lib/bundler/source/git/git_proxy.rb
+++ b/lib/bundler/source/git/git_proxy.rb
@@ -43,13 +43,6 @@ module Bundler
end
end
- class AmbiguousGitReference < GitError
- def initialize(options)
- msg = "Specification of branch or ref with tag is ambiguous. You specified #{options.inspect}"
- super msg
- end
- end
-
# The GitProxy is responsible to interact with git repositories.
# All actions required by the Git source is encapsulated in this
# object.
@@ -60,15 +53,10 @@ module Bundler
def initialize(path, uri, options = {}, revision = nil, git = nil)
@path = path
@uri = uri
- @tag = options["tag"]
@branch = options["branch"]
+ @tag = options["tag"]
@ref = options["ref"]
- if @tag
- raise AmbiguousGitReference.new(options) if @branch || @ref
- @explicit_ref = @tag
- else
- @explicit_ref = @ref || @branch
- end
+ @explicit_ref = branch || tag || ref
@revision = revision
@git = git
@commit_ref = nil
@@ -80,14 +68,14 @@ module Bundler
def current_branch
@current_branch ||= with_path do
- git_local("rev-parse", "--abbrev-ref", "HEAD", dir: path).strip
+ git_local("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
end
end
def contains?(commit)
allowed_with_path do
- result, status = git_null("branch", "--contains", commit, dir: path)
- status.success? && result.match?(/^\* (.*)$/)
+ result, status = git_null("branch", "--contains", commit, :dir => path)
+ status.success? && result =~ /^\* (.*)$/
end
end
@@ -130,20 +118,15 @@ module Bundler
end
end
- ref = @commit_ref || (locked_to_full_sha? && @revision)
- if ref
- git "config", "uploadpack.allowAnySHA1InWant", "true", dir: path.to_s if @commit_ref.nil? && needs_allow_any_sha1_in_want?
-
- git "fetch", "--force", "--quiet", *extra_fetch_args(ref), dir: destination
- end
+ git "fetch", "--force", "--quiet", *extra_fetch_args, :dir => destination if @commit_ref
- git "reset", "--hard", @revision, dir: destination
+ git "reset", "--hard", @revision, :dir => destination
if submodules
- git_retry "submodule", "update", "--init", "--recursive", dir: destination
+ git_retry "submodule", "update", "--init", "--recursive", :dir => destination
elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
inner_command = "git -C $toplevel submodule deinit --force $sm_path"
- git_retry "submodule", "foreach", "--quiet", inner_command, dir: destination
+ git_retry "submodule", "foreach", "--quiet", inner_command, :dir => destination
end
end
@@ -179,17 +162,10 @@ module Bundler
_, err, status = capture(command, nil)
return extra_ref if status.success?
- if err.include?("Could not find remote branch")
+ if err.include?("Could not find remote branch") || # git up to 2.49
+ err.include?("Remote branch #{branch_option} not found") # git 2.49 or higher
raise MissingGitRevisionError.new(command_with_no_credentials, nil, explicit_ref, credential_filtered_uri)
else
- idx = command.index("--depth")
- if idx
- command.delete_at(idx)
- command.delete_at(idx)
- command_with_no_credentials = check_allowed(command)
-
- err += "Retrying without --depth argument."
- end
raise GitCommandError.new(command_with_no_credentials, path, err)
end
end
@@ -256,50 +232,42 @@ module Bundler
end
def not_pinned?
- branch || tag || ref.nil?
+ branch_option || ref.nil?
end
def pinned_to_full_sha?
- full_sha_revision?(ref)
- end
-
- def locked_to_full_sha?
- full_sha_revision?(@revision)
- end
-
- def full_sha_revision?(ref)
- ref&.match?(/\A\h{40}\z/)
+ ref =~ /\A\h{40}\z/
end
def git_null(*command, dir: nil)
check_allowed(command)
- capture(command, dir, ignore_err: true)
+ capture(command, dir, :ignore_err => true)
end
def git_retry(*command, dir: nil)
command_with_no_credentials = check_allowed(command)
Bundler::Retry.new("`#{command_with_no_credentials}` at #{dir || SharedHelpers.pwd}").attempts do
- git(*command, dir: dir)
+ git(*command, :dir => dir)
end
end
def git(*command, dir: nil)
- run_command(*command, dir: dir) do |unredacted_command|
+ run_command(*command, :dir => dir) do |unredacted_command|
check_allowed(unredacted_command)
end
end
def git_local(*command, dir: nil)
- run_command(*command, dir: dir) do |unredacted_command|
+ run_command(*command, :dir => dir) do |unredacted_command|
redact_and_check_presence(unredacted_command)
end
end
def has_revision_cached?
return unless @revision && path.exist?
- git("cat-file", "-e", @revision, dir: path)
+ git("cat-file", "-e", @revision, :dir => path)
true
rescue GitError
false
@@ -322,13 +290,13 @@ module Bundler
end
def verify(reference)
- git("rev-parse", "--verify", reference, dir: path).strip
+ git("rev-parse", "--verify", reference, :dir => path).strip
end
# Adds credentials to the URI
def configured_uri
if /https?:/.match?(uri)
- remote = Gem::URI(uri)
+ remote = Bundler::URI(uri)
config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
remote.userinfo ||= config_auth
remote.to_s
@@ -406,7 +374,7 @@ module Bundler
if Bundler.feature_flag.bundler_3_mode? || supports_minus_c?
["git", "-C", dir.to_s, *cmd]
else
- ["git", *cmd, { chdir: dir.to_s }]
+ ["git", *cmd, { :chdir => dir.to_s }]
end
end
@@ -422,7 +390,7 @@ module Bundler
# anyways.
return args if @revision
- args += ["--branch", branch || tag] if branch || tag
+ args += ["--branch", branch_option] if branch_option
args
end
@@ -432,12 +400,16 @@ module Bundler
["--depth", depth.to_s]
end
- def extra_fetch_args(ref)
+ def extra_fetch_args
extra_args = [path.to_s, *depth_args]
- extra_args.push(ref)
+ extra_args.push(@commit_ref)
extra_args
end
+ def branch_option
+ branch || tag
+ end
+
def full_clone?
depth.nil?
end
@@ -446,10 +418,6 @@ module Bundler
@supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5")
end
- def needs_allow_any_sha1_in_want?
- @needs_allow_any_sha1_in_want ||= Gem::Version.new(version) <= Gem::Version.new("2.13.7")
- end
-
def supports_fetching_unreachable_refs?
@supports_fetching_unreachable_refs ||= Gem::Version.new(version) >= Gem::Version.new("2.5.0")
end
diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb
index 6b05e17727..593da6d1a7 100644
--- a/lib/bundler/source/metadata.rb
+++ b/lib/bundler/source/metadata.rb
@@ -5,29 +5,27 @@ module Bundler
class Metadata < Source
def specs
@specs ||= Index.build do |idx|
- idx << Gem::Specification.new("Ruby\0", Bundler::RubyVersion.system.gem_version)
+ idx << Gem::Specification.new("Ruby\0", Gem.ruby_version)
idx << Gem::Specification.new("RubyGems\0", Gem::VERSION) do |s|
s.required_rubygems_version = Gem::Requirement.default
end
- if local_spec = Gem.loaded_specs["bundler"]
- raise CorruptBundlerInstallError.new(local_spec) if local_spec.version.to_s != Bundler::VERSION
+ idx << Gem::Specification.new do |s|
+ s.name = "bundler"
+ s.version = VERSION
+ s.license = "MIT"
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["bundler team"]
+ s.bindir = "exe"
+ s.homepage = "https://bundler.io"
+ s.summary = "The best way to manage your application's dependencies"
+ s.executables = %w[bundle]
+ # can't point to the actual gemspec or else the require paths will be wrong
+ s.loaded_from = __dir__
+ end
+ if local_spec = Bundler.rubygems.find_bundler(VERSION)
idx << local_spec
- else
- idx << Gem::Specification.new do |s|
- s.name = "bundler"
- s.version = VERSION
- s.license = "MIT"
- s.platform = Gem::Platform::RUBY
- s.authors = ["bundler team"]
- s.bindir = "exe"
- s.homepage = "https://bundler.io"
- s.summary = "The best way to manage your application's dependencies"
- s.executables = %w[bundle]
- # can't point to the actual gemspec or else the require paths will be wrong
- s.loaded_from = __dir__
- end
end
idx.each {|s| s.source = self }
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 978b0b2c9f..bdfcf8274a 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -14,7 +14,6 @@ module Bundler
DEFAULT_GLOB = "{,*,*/*}.gemspec"
def initialize(options)
- @checksum_store = Checksum::Store.new
@options = options.dup
@glob = options["glob"] || DEFAULT_GLOB
@@ -86,7 +85,7 @@ module Bundler
using_message = "Using #{version_message(spec, options[:previous_spec])} from #{self}"
using_message += " and installing its executables" unless spec.executables.empty?
print_using_message using_message
- generate_bin(spec, disable_extensions: true)
+ generate_bin(spec, :disable_extensions => true)
nil # no post-install message
end
@@ -226,7 +225,7 @@ module Bundler
# Some gem authors put absolute paths in their gemspec
# and we have to save them from themselves
spec.files = spec.files.map do |path|
- next path unless /\A#{Pathname::SEPARATOR_PAT}/o.match?(path)
+ next path unless /\A#{Pathname::SEPARATOR_PAT}/.match?(path)
next if File.directory?(path)
begin
Pathname.new(path).relative_path_from(gem_dir).to_s
@@ -237,10 +236,10 @@ module Bundler
installer = Path::Installer.new(
spec,
- env_shebang: false,
- disable_extensions: options[:disable_extensions],
- build_args: options[:build_args],
- bundler_extension_cache_path: extension_cache_path(spec)
+ :env_shebang => false,
+ :disable_extensions => options[:disable_extensions],
+ :build_args => options[:build_args],
+ :bundler_extension_cache_path => extension_cache_path(spec)
)
installer.post_install
rescue Gem::InvalidSpecificationException => e
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 3ac1bd4ff8..af57acbbc2 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -10,7 +10,7 @@ module Bundler
# Ask for X gems per API request
API_REQUEST_SIZE = 50
- attr_accessor :remotes
+ attr_reader :remotes
def initialize(options = {})
@options = options
@@ -19,7 +19,6 @@ module Bundler
@allow_remote = false
@allow_cached = false
@allow_local = options["allow_local"] || false
- @checksum_store = Checksum::Store.new
Array(options["remotes"]).reverse_each {|r| add_remote(r) }
end
@@ -50,11 +49,10 @@ module Bundler
end
def cached!
- return unless File.exist?(cache_path)
-
return if @allow_cached
@specs = nil
+ @allow_local = true
@allow_cached = true
end
@@ -90,14 +88,13 @@ module Bundler
end
def self.from_lock(options)
- options["remotes"] = Array(options.delete("remote")).reverse
new(options)
end
def to_lock
out = String.new("GEM\n")
remotes.reverse_each do |remote|
- out << " remote: #{remove_auth remote}\n"
+ out << " remote: #{suppress_configured_credentials remote}\n"
end
out << " specs:\n"
end
@@ -131,12 +128,12 @@ module Bundler
def specs
@specs ||= begin
# remote_specs usually generates a way larger Index than the other
- # sources, and large_idx.merge! small_idx is way faster than
- # small_idx.merge! large_idx.
- index = @allow_remote ? remote_specs.dup : Index.new
- index.merge!(cached_specs) if @allow_cached
- index.merge!(installed_specs) if @allow_local
- index
+ # sources, and large_idx.use small_idx is way faster than
+ # small_idx.use large_idx.
+ idx = @allow_remote ? remote_specs.dup : Index.new
+ idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
+ idx.use(installed_specs, :override_dupes) if @allow_local
+ idx
end
end
@@ -172,14 +169,15 @@ module Bundler
installer = Bundler::RubyGemsGemInstaller.at(
path,
- security_policy: Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]],
- install_dir: install_path.to_s,
- bin_dir: bin_path.to_s,
- ignore_dependencies: true,
- wrappers: true,
- env_shebang: true,
- build_args: options[:build_args],
- bundler_extension_cache_path: extension_cache_path(spec)
+ :security_policy => Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]],
+ :install_dir => install_path.to_s,
+ :bin_dir => bin_path.to_s,
+ :ignore_dependencies => true,
+ :wrappers => true,
+ :env_shebang => true,
+ :build_args => options[:build_args],
+ :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
+ :bundler_extension_cache_path => extension_cache_path(spec)
)
if spec.remote
@@ -197,8 +195,6 @@ module Bundler
spec.__swap__(s)
end
- spec.source.checksum_store.register(spec, installer.gem_checksum)
-
message = "Installing #{version_message(spec, options[:previous_spec])}"
message += " with native extensions" if spec.extensions.any?
Bundler.ui.confirm message
@@ -241,7 +237,7 @@ module Bundler
end
def spec_names
- if dependency_api_available?
+ if @allow_remote && dependency_api_available?
remote_specs.spec_names
else
[]
@@ -249,25 +245,22 @@ module Bundler
end
def unmet_deps
- if dependency_api_available?
+ if @allow_remote && dependency_api_available?
remote_specs.unmet_dependency_names
else
[]
end
end
- def remote_fetchers
- @remote_fetchers ||= remotes.to_h do |uri|
- remote = Source::Rubygems::Remote.new(uri)
- [remote, Bundler::Fetcher.new(remote)]
- end.freeze
- end
-
def fetchers
- @fetchers ||= remote_fetchers.values.freeze
+ @fetchers ||= remotes.map do |uri|
+ remote = Source::Rubygems::Remote.new(uri)
+ Bundler::Fetcher.new(remote)
+ end
end
def double_check_for(unmet_dependency_names)
+ return unless @allow_remote
return unless dependency_api_available?
unmet_dependency_names = unmet_dependency_names.call
@@ -282,9 +275,7 @@ module Bundler
Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
- fetch_names(api_fetchers, unmet_dependency_names, remote_specs)
-
- specs.use remote_specs
+ fetch_names(api_fetchers, unmet_dependency_names, specs, false)
end
def dependency_names_to_double_check
@@ -313,7 +304,11 @@ module Bundler
end
def credless_remotes
- remotes.map(&method(:remove_auth))
+ if Bundler.settings[:allow_deployment_source_credential_changes]
+ remotes.map(&method(:remove_auth))
+ else
+ remotes.map(&method(:suppress_configured_credentials))
+ end
end
def remotes_for_spec(spec)
@@ -346,12 +341,21 @@ module Bundler
def normalize_uri(uri)
uri = URINormalizer.normalize_suffix(uri.to_s)
require_relative "../vendored_uri"
- uri = Gem::URI(uri)
+ uri = Bundler::URI(uri)
raise ArgumentError, "The source must be an absolute URI. For example:\n" \
- "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(Gem::URI::HTTP) && uri.host.nil?)
+ "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(Bundler::URI::HTTP) && uri.host.nil?)
uri
end
+ def suppress_configured_credentials(remote)
+ remote_nouser = remove_auth(remote)
+ if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
+ remote_nouser
+ else
+ remote
+ end
+ end
+
def remove_auth(remote)
if remote.user || remote.password
remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
@@ -375,7 +379,7 @@ module Bundler
def cached_specs
@cached_specs ||= begin
- idx = Index.new
+ idx = @allow_local ? installed_specs.dup : Index.new
Dir["#{cache_path}/*.gem"].each do |gemfile|
s ||= Bundler.rubygems.spec_from_gem(gemfile)
@@ -388,30 +392,35 @@ module Bundler
end
def api_fetchers
- fetchers.select(&:api_fetcher?)
+ fetchers.select {|f| f.use_api && f.fetchers.first.api_fetcher? }
end
def remote_specs
@remote_specs ||= Index.build do |idx|
index_fetchers = fetchers - api_fetchers
- if index_fetchers.empty?
- fetch_names(api_fetchers, dependency_names, idx)
- else
- fetch_names(fetchers, nil, idx)
- end
+ # gather lists from non-api sites
+ fetch_names(index_fetchers, nil, idx, false)
+
+ # legacy multi-remote sources need special logic to figure out
+ # dependency names and that logic can be very costly if one remote
+ # uses the dependency API but others don't. So use full indexes
+ # consistently in that particular case.
+ allow_api = !multiple_remotes?
+
+ fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
end
end
- def fetch_names(fetchers, dependency_names, index)
+ def fetch_names(fetchers, dependency_names, index, override_dupes)
fetchers.each do |f|
if dependency_names
Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
- index.use f.specs_with_retry(dependency_names, self)
+ index.use f.specs_with_retry(dependency_names, self), override_dupes
Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
else
Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
- index.use f.specs_with_retry(nil, self)
+ index.use f.specs_with_retry(nil, self), override_dupes
end
end
end
@@ -472,8 +481,7 @@ module Bundler
def download_gem(spec, download_cache_path, previous_spec = nil)
uri = spec.remote.uri
Bundler.ui.confirm("Fetching #{version_message(spec, previous_spec)}")
- gem_remote_fetcher = remote_fetchers.fetch(spec.remote).gem_remote_fetcher
- Bundler.rubygems.download_gem(spec, uri, download_cache_path, gem_remote_fetcher)
+ Bundler.rubygems.download_gem(spec, uri, download_cache_path)
end
# Returns the global cache path of the calling Rubygems::Source object.
diff --git a/lib/bundler/source/rubygems/remote.rb b/lib/bundler/source/rubygems/remote.rb
index 9c5c06de24..82c850ffbb 100644
--- a/lib/bundler/source/rubygems/remote.rb
+++ b/lib/bundler/source/rubygems/remote.rb
@@ -48,7 +48,7 @@ module Bundler
end
uri
- rescue Gem::URI::InvalidComponentError
+ rescue Bundler::URI::InvalidComponentError
error_message = "Please CGI escape your usernames and passwords before " \
"setting them for authentication."
raise HTTPError.new(error_message)
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index 5f9dd68f17..4419695b7f 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -22,7 +22,6 @@ module Bundler
@metadata_source = Source::Metadata.new
@merged_gem_lockfile_sections = false
- @local_mode = true
end
def merged_gem_lockfile_sections?
@@ -74,10 +73,6 @@ module Bundler
global_rubygems_source
end
- def local_mode?
- @local_mode
- end
-
def default_source
global_path_source || global_rubygems_source
end
@@ -145,17 +140,11 @@ module Bundler
all_sources.each(&:local_only!)
end
- def local!
- all_sources.each(&:local!)
- end
-
def cached!
all_sources.each(&:cached!)
end
def remote!
- @local_mode = false
-
all_sources.each(&:remote!)
end
@@ -168,11 +157,7 @@ module Bundler
end
def map_sources(replacement_sources)
- rubygems = @rubygems_sources.map do |source|
- replace_rubygems_source(replacement_sources, source) || source
- end
-
- git, plugin = [@git_sources, @plugin_sources].map do |sources|
+ rubygems, git, plugin = [@rubygems_sources, @git_sources, @plugin_sources].map do |sources|
sources.map do |source|
replacement_sources.find {|s| s == source } || source
end
@@ -186,22 +171,13 @@ module Bundler
end
def global_replacement_source(replacement_sources)
- replacement_source = replace_rubygems_source(replacement_sources, global_rubygems_source)
+ replacement_source = replacement_sources.find {|s| s == global_rubygems_source }
return global_rubygems_source unless replacement_source
replacement_source.local!
replacement_source
end
- def replace_rubygems_source(replacement_sources, gemfile_source)
- replacement_source = replacement_sources.find {|s| s == gemfile_source }
- return unless replacement_source
-
- # locked sources never include credentials so always prefer remotes from the gemfile
- replacement_source.remotes = gemfile_source.remotes
- replacement_source
- end
-
def different_sources?(lock_sources, replacement_sources)
!equivalent_sources?(lock_sources, replacement_sources)
end
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 2933d28450..21630e3a3e 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -37,7 +37,7 @@ module Bundler
specs_for_dep.first.dependencies.each do |d|
next if d.type == :development
- incomplete = true if d.name != "bundler" && lookup[d.name].nil?
+ incomplete = true if d.name != "bundler" && lookup[d.name].empty?
deps << [d, dep[1]]
end
else
@@ -45,64 +45,28 @@ module Bundler
end
if incomplete && check
- @incomplete_specs += lookup[name] || [LazySpecification.new(name, nil, nil)]
+ @incomplete_specs += lookup[name].any? ? lookup[name] : [LazySpecification.new(name, nil, nil)]
end
end
specs.uniq
end
- def add_extra_platforms!(platforms)
- return platforms.concat([Gem::Platform::RUBY]).uniq if @specs.empty?
-
- new_platforms = all_platforms.select do |platform|
- next if platforms.include?(platform)
- next unless GemHelpers.generic(platform) == Gem::Platform::RUBY
-
- complete_platform(platform)
- end
- return platforms if new_platforms.empty?
-
- platforms.concat(new_platforms)
-
- less_specific_platform = new_platforms.find {|platform| platform != Gem::Platform::RUBY && Bundler.local_platform === platform && platform === Bundler.local_platform }
- platforms.delete(Bundler.local_platform) if less_specific_platform
-
- platforms
- end
-
- def complete_platforms!(platforms)
- platforms.each do |platform|
- complete_platform(platform)
- end
- end
-
- def validate_deps(s)
- s.runtime_dependencies.each do |dep|
- next if dep.name == "bundler"
-
- return :missing unless names.include?(dep.name)
- return :invalid if none? {|spec| dep.matches_spec?(spec) }
- end
-
- :valid
- end
-
def [](key)
key = key.name if key.respond_to?(:name)
- lookup[key]&.reverse || []
+ lookup[key].reverse
end
def []=(key, value)
@specs << value
-
- reset!
+ @lookup = nil
+ @sorted = nil
end
def delete(specs)
specs.each {|spec| @specs.delete(spec) }
-
- reset!
+ @lookup = nil
+ @sorted = nil
end
def sort!
@@ -136,12 +100,12 @@ module Bundler
end
end
- def incomplete_for_platform?(deps, platform)
+ def incomplete_ruby_specs?(deps)
return false if @specs.empty?
@incomplete_specs = []
- self.for(deps, true, [platform])
+ self.for(deps, true, [Gem::Platform::RUBY])
@incomplete_specs.any?
end
@@ -150,6 +114,16 @@ module Bundler
@specs.select {|s| s.is_a?(LazySpecification) }
end
+ def merge(set)
+ arr = sorted.dup
+ set.each do |set_spec|
+ full_name = set_spec.full_name
+ next if arr.any? {|spec| spec.full_name == full_name }
+ arr << set_spec
+ end
+ SpecSet.new(arr)
+ end
+
def -(other)
SpecSet.new(to_a - other.to_a)
end
@@ -160,12 +134,12 @@ module Bundler
def delete_by_name(name)
@specs.reject! {|spec| spec.name == name }
-
- reset!
+ @lookup = nil
+ @sorted = nil
end
def what_required(spec)
- unless req = find {|s| s.runtime_dependencies.any? {|d| d.name == spec.name } }
+ unless req = find {|s| s.dependencies.any? {|d| d.type == :runtime && d.name == spec.name } }
return [spec]
end
what_required(req) << spec
@@ -191,52 +165,8 @@ module Bundler
sorted.each(&b)
end
- def names
- lookup.keys
- end
-
private
- def reset!
- @sorted = nil
- @lookup = nil
- end
-
- def complete_platform(platform)
- new_specs = []
-
- valid_platform = lookup.all? do |_, specs|
- spec = specs.first
- matching_specs = spec.source.specs.search([spec.name, spec.version])
- platform_spec = GemHelpers.select_best_platform_match(matching_specs, platform).find do |s|
- s.matches_current_metadata? && valid_dependencies?(s)
- end
-
- if platform_spec
- new_specs << LazySpecification.from_spec(platform_spec) unless specs.include?(platform_spec)
- true
- else
- false
- end
- end
-
- if valid_platform && new_specs.any?
- @specs.concat(new_specs)
-
- reset!
- end
-
- valid_platform
- end
-
- def all_platforms
- @specs.flat_map {|spec| spec.source.specs.search([spec.name, spec.version]).map(&:platform) }.uniq
- end
-
- def valid_dependencies?(s)
- validate_deps(s) == :valid
- end
-
def sorted
rake = @specs.find {|s| s.name == "rake" }
begin
@@ -255,9 +185,8 @@ module Bundler
def lookup
@lookup ||= begin
- lookup = {}
+ lookup = Hash.new {|h, k| h[k] = [] }
@specs.each do |s|
- lookup[s.name] ||= []
lookup[s.name] << s
end
lookup
@@ -271,13 +200,8 @@ module Bundler
def specs_for_dependency(dep, platform)
specs_for_name = lookup[dep.name]
- return [] unless specs_for_name
-
- matching_specs = if dep.force_ruby_platform
- GemHelpers.force_ruby_platform(specs_for_name)
- else
- GemHelpers.select_best_platform_match(specs_for_name, platform || Bundler.local_platform)
- end
+ target_platform = dep.force_ruby_platform ? Gem::Platform::RUBY : (platform || Bundler.local_platform)
+ matching_specs = GemHelpers.select_best_platform_match(specs_for_name, target_platform)
matching_specs.map!(&:materialize_for_installation).compact! if platform.nil?
matching_specs
end
@@ -285,11 +209,7 @@ module Bundler
def tsort_each_child(s)
s.dependencies.sort_by(&:name).each do |d|
next if d.type == :development
-
- specs_for_name = lookup[d.name]
- next unless specs_for_name
-
- specs_for_name.each {|s2| yield s2 }
+ lookup[d.name].each {|s2| yield s2 }
end
end
end
diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index da830cf8d4..88a4257fa4 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -9,7 +9,6 @@ module Bundler
spec
end
- attr_reader :checksum
attr_accessor :stub, :ignored
def source=(source)
@@ -17,8 +16,7 @@ module Bundler
# Stub has no concept of source, which means that extension_dir may be wrong
# This is the case for git-based gems. So, instead manually assign the extension dir
return unless source.respond_to?(:extension_dir_name)
- unique_extension_dir = [source.extension_dir_name, File.basename(full_gem_path)].uniq.join("-")
- path = File.join(stub.extensions_dir, unique_extension_dir)
+ path = File.join(stub.extensions_dir, source.extension_dir_name)
stub.extension_dir = File.expand_path(path)
end
@@ -58,7 +56,7 @@ module Bundler
end
def gem_build_complete_path
- stub.gem_build_complete_path
+ File.join(extension_dir, "gem.build_complete")
end
def default_gem?
@@ -110,7 +108,6 @@ module Bundler
end
rs.source = source
- rs.base_dir = stub.base_dir
rs
end
diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler
index caa2021701..e290fe91eb 100644
--- a/lib/bundler/templates/Executable.bundler
+++ b/lib/bundler/templates/Executable.bundler
@@ -27,7 +27,7 @@ m = Module.new do
bundler_version = nil
update_index = nil
ARGV.each_with_index do |a, i|
- if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN)
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
diff --git a/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt b/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
index 67fe8cee79..175b821a62 100644
--- a/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
+++ b/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
@@ -2,131 +2,83 @@
## Our Pledge
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, caste, color, religion, or sexual
-identity and orientation.
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
-Examples of behavior that contributes to a positive environment for our
-community include:
+Examples of behavior that contributes to a positive environment for our community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
- and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the overall
- community
+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
-* The use of sexualized language or imagery, and sexual attention or advances of
- any kind
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
-* Publishing others' private information, such as a physical or email address,
- without their explicit permission
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
+Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official email address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
+This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-[INSERT CONTACT METHOD].
-All complaints will be reviewed and investigated promptly and fairly.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at <%= config[:email] %>. All complaints will be reviewed and investigated promptly and fairly.
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
+All community leaders are obligated to respect the privacy and security of the reporter of any incident.
## Enforcement Guidelines
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
+Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
+**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
+**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning
-**Community Impact**: A violation through a single incident or series of
-actions.
+**Community Impact**: A violation through a single incident or series of actions.
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or permanent
-ban.
+**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
+**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
+**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
+**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
-**Consequence**: A permanent ban from any sort of public interaction within the
-community.
+**Consequence**: A permanent ban from any sort of public interaction within the community.
## Attribution
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.1, available at
-[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
+available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
-Community Impact Guidelines were inspired by
-[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
-
-For answers to common questions about this code of conduct, see the FAQ at
-[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
-[https://www.contributor-covenant.org/translations][translations].
+Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
-[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
-[Mozilla CoC]: https://github.com/mozilla/diversity
-[FAQ]: https://www.contributor-covenant.org/faq
-[translations]: https://www.contributor-covenant.org/translations
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
diff --git a/lib/bundler/templates/newgem/README.md.tt b/lib/bundler/templates/newgem/README.md.tt
index 5bf36378e8..20eaac8a62 100644
--- a/lib/bundler/templates/newgem/README.md.tt
+++ b/lib/bundler/templates/newgem/README.md.tt
@@ -6,15 +6,15 @@ Welcome to your new gem! In this directory, you'll find the files you need to be
## Installation
-TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
+TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
Install the gem and add to the application's Gemfile by executing:
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
+ $ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
If bundler is not being used to manage dependencies, install the gem by executing:
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
+ $ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
## Usage
diff --git a/lib/bundler/templates/newgem/Rakefile.tt b/lib/bundler/templates/newgem/Rakefile.tt
index 172183d4b4..b5a5c4e392 100644
--- a/lib/bundler/templates/newgem/Rakefile.tt
+++ b/lib/bundler/templates/newgem/Rakefile.tt
@@ -4,9 +4,13 @@ require "bundler/gem_tasks"
<% default_task_names = [config[:test_task]].compact -%>
<% case config[:test] -%>
<% when "minitest" -%>
-require "minitest/test_task"
+require "rake/testtask"
-Minitest::TestTask.create
+Rake::TestTask.new(:test) do |t|
+ t.libs << "test"
+ t.libs << "lib"
+ t.test_files = FileList["test/**/test_*.rb"]
+end
<% when "test-unit" -%>
require "rake/testtask"
@@ -42,9 +46,7 @@ require "rb_sys/extensiontask"
task build: :compile
-GEMSPEC = Gem::Specification.load("<%= config[:underscored_name] %>.gemspec")
-
-RbSys::ExtensionTask.new(<%= config[:name].inspect %>, GEMSPEC) do |ext|
+RbSys::ExtensionTask.new(<%= config[:name].inspect %>) do |ext|
ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
end
<% else -%>
@@ -52,9 +54,7 @@ require "rake/extensiontask"
task build: :compile
-GEMSPEC = Gem::Specification.load("<%= config[:underscored_name] %>.gemspec")
-
-Rake::ExtensionTask.new("<%= config[:underscored_name] %>", GEMSPEC) do |ext|
+Rake::ExtensionTask.new("<%= config[:underscored_name] %>") do |ext|
ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
end
<% end -%>
diff --git a/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt b/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt
index 0ebce0e4a0..c64385486e 100644
--- a/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt
+++ b/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt
@@ -12,4 +12,4 @@ publish = false
crate-type = ["cdylib"]
[dependencies]
-magnus = { version = "0.6.2" }
+magnus = { version = "0.6" }
diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
index 32b39558d8..be58dd8156 100644
--- a/lib/bundler/templates/newgem/github/workflows/main.yml.tt
+++ b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
@@ -17,7 +17,7 @@ jobs:
- '<%= RUBY_VERSION %>'
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v3
<%- if config[:ext] == 'rust' -%>
- name: Set up Ruby & Rust
uses: oxidize-rb/actions/setup-ruby-and-rust@v1
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index 6e88f4dab1..bb76680379 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -27,11 +27,10 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- gemspec = File.basename(__FILE__)
- spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
- ls.readlines("\x0", chomp: true).reject do |f|
- (f == gemspec) ||
- f.start_with?(*%w[bin/ test/ spec/ features/ .git <%= config[:ci_config_path] %>appveyor Gemfile])
+ spec.files = Dir.chdir(__dir__) do
+ `git ls-files -z`.split("\x0").reject do |f|
+ (File.expand_path(f) == __FILE__) ||
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
end
end
spec.bindir = "exe"
diff --git a/lib/bundler/templates/newgem/rubocop.yml.tt b/lib/bundler/templates/newgem/rubocop.yml.tt
index 3d1c4ee7b2..9ecec78807 100644
--- a/lib/bundler/templates/newgem/rubocop.yml.tt
+++ b/lib/bundler/templates/newgem/rubocop.yml.tt
@@ -2,7 +2,12 @@ AllCops:
TargetRubyVersion: <%= ::Gem::Version.new(config[:required_ruby_version]).segments[0..1].join(".") %>
Style/StringLiterals:
+ Enabled: true
EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
+ Enabled: true
EnforcedStyle: double_quotes
+
+Layout/LineLength:
+ Max: 120
diff --git a/lib/bundler/templates/newgem/standard.yml.tt b/lib/bundler/templates/newgem/standard.yml.tt
index a0696cd2e9..934b0b2c37 100644
--- a/lib/bundler/templates/newgem/standard.yml.tt
+++ b/lib/bundler/templates/newgem/standard.yml.tt
@@ -1,3 +1,3 @@
# For available configuration options, see:
-# https://github.com/standardrb/standard
+# https://github.com/testdouble/standard
ruby_version: <%= ::Gem::Version.new(config[:required_ruby_version]).segments[0..1].join(".") %>
diff --git a/lib/bundler/ui/shell.rb b/lib/bundler/ui/shell.rb
index 4555612dbb..4139585c47 100644
--- a/lib/bundler/ui/shell.rb
+++ b/lib/bundler/ui/shell.rb
@@ -130,7 +130,7 @@ module Bundler
def tell_err(message, color = nil, newline = nil)
return if @shell.send(:stderr).closed?
- newline ||= !message.to_s.match?(/( |\t)\Z/)
+ newline ||= message.to_s !~ /( |\t)\Z/
message = word_wrap(message) if newline.is_a?(Hash) && newline[:wrap]
color = nil if color && !$stderr.tty?
@@ -147,7 +147,7 @@ module Bundler
spaces ? text.gsub(/#{spaces}/, "") : text
end
- def word_wrap(text, line_width = Thor::Terminal.terminal_width)
+ def word_wrap(text, line_width = @shell.terminal_width)
strip_leading_spaces(text).split("\n").collect do |line|
line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
end * "\n"
diff --git a/lib/bundler/uri_credentials_filter.rb b/lib/bundler/uri_credentials_filter.rb
index a83f5304e2..ccfaf0bc5d 100644
--- a/lib/bundler/uri_credentials_filter.rb
+++ b/lib/bundler/uri_credentials_filter.rb
@@ -11,7 +11,7 @@ module Bundler
return uri if File.exist?(uri)
require_relative "vendored_uri"
- uri = Gem::URI(uri)
+ uri = Bundler::URI(uri)
end
if uri.userinfo
@@ -25,7 +25,7 @@ module Bundler
end
return uri.to_s if uri_to_anonymize.is_a?(String)
uri
- rescue Gem::URI::InvalidURIError # uri is not canonical uri scheme
+ rescue Bundler::URI::InvalidURIError # uri is not canonical uri scheme
uri
end
diff --git a/lib/bundler/vendor/connection_pool/lib/connection_pool.rb b/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
index 317088a866..455319efe3 100644
--- a/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
+++ b/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
@@ -1,4 +1,4 @@
-require_relative "../../../vendored_timeout"
+require "timeout"
require_relative "connection_pool/version"
class Bundler::ConnectionPool
@@ -6,7 +6,7 @@ class Bundler::ConnectionPool
class PoolShuttingDownError < ::Bundler::ConnectionPool::Error; end
- class TimeoutError < ::Gem::Timeout::Error; end
+ class TimeoutError < ::Timeout::Error; end
end
# Generic connection pool class for sharing a limited number of objects or network connections
@@ -36,57 +36,14 @@ end
# Accepts the following options:
# - :size - number of connections to pool, defaults to 5
# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
-# - :auto_reload_after_fork - automatically drop all connections after fork, defaults to true
#
class Bundler::ConnectionPool
- DEFAULTS = {size: 5, timeout: 5, auto_reload_after_fork: true}
+ DEFAULTS = {size: 5, timeout: 5}
def self.wrap(options, &block)
Wrapper.new(options, &block)
end
- if Process.respond_to?(:fork)
- INSTANCES = ObjectSpace::WeakMap.new
- private_constant :INSTANCES
-
- def self.after_fork
- INSTANCES.values.each do |pool|
- next unless pool.auto_reload_after_fork
-
- # We're on after fork, so we know all other threads are dead.
- # All we need to do is to ensure the main thread doesn't have a
- # checked out connection
- pool.checkin(force: true)
- pool.reload do |connection|
- # Unfortunately we don't know what method to call to close the connection,
- # so we try the most common one.
- connection.close if connection.respond_to?(:close)
- end
- end
- nil
- end
-
- if ::Process.respond_to?(:_fork) # MRI 3.1+
- module ForkTracker
- def _fork
- pid = super
- if pid == 0
- Bundler::ConnectionPool.after_fork
- end
- pid
- end
- end
- Process.singleton_class.prepend(ForkTracker)
- end
- else
- INSTANCES = nil
- private_constant :INSTANCES
-
- def self.after_fork
- # noop
- end
- end
-
def initialize(options = {}, &block)
raise ArgumentError, "Connection pool requires a block" unless block
@@ -94,12 +51,10 @@ class Bundler::ConnectionPool
@size = Integer(options.fetch(:size))
@timeout = options.fetch(:timeout)
- @auto_reload_after_fork = options.fetch(:auto_reload_after_fork)
@available = TimedStack.new(@size, &block)
@key = :"pool-#{@available.object_id}"
@key_count = :"pool-#{@available.object_id}-count"
- INSTANCES[self] = self if INSTANCES
end
def with(options = {})
@@ -126,16 +81,16 @@ class Bundler::ConnectionPool
end
end
- def checkin(force: false)
+ def checkin
if ::Thread.current[@key]
- if ::Thread.current[@key_count] == 1 || force
+ if ::Thread.current[@key_count] == 1
@available.push(::Thread.current[@key])
::Thread.current[@key] = nil
::Thread.current[@key_count] = nil
else
::Thread.current[@key_count] -= 1
end
- elsif !force
+ else
raise Bundler::ConnectionPool::Error, "no connections are checked out"
end
@@ -162,8 +117,6 @@ class Bundler::ConnectionPool
# Size of this connection pool
attr_reader :size
- # Automatically drop all connections after fork
- attr_reader :auto_reload_after_fork
# Number of pool entries available for checkout at this instant.
def available
diff --git a/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb b/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
index 384d6fc977..56ebf69902 100644
--- a/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
+++ b/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
@@ -1,3 +1,3 @@
class Bundler::ConnectionPool
- VERSION = "2.4.1"
+ VERSION = "2.3.0"
end
diff --git a/lib/bundler/vendor/fileutils/lib/fileutils.rb b/lib/bundler/vendor/fileutils/lib/fileutils.rb
index 6db19caf6f..211311c069 100644
--- a/lib/bundler/vendor/fileutils/lib/fileutils.rb
+++ b/lib/bundler/vendor/fileutils/lib/fileutils.rb
@@ -180,7 +180,7 @@ end
# - {CVE-2004-0452}[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452].
#
module Bundler::FileUtils
- VERSION = "1.7.2"
+ VERSION = "1.7.0"
def self.private_module_function(name) #:nodoc:
module_function name
@@ -192,6 +192,8 @@ module Bundler::FileUtils
#
# Bundler::FileUtils.pwd # => "/rdoc/fileutils"
#
+ # Bundler::FileUtils.getwd is an alias for Bundler::FileUtils.pwd.
+ #
# Related: Bundler::FileUtils.cd.
#
def pwd
@@ -233,6 +235,8 @@ module Bundler::FileUtils
# cd ..
# cd fileutils
#
+ # Bundler::FileUtils.chdir is an alias for Bundler::FileUtils.cd.
+ #
# Related: Bundler::FileUtils.pwd.
#
def cd(dir, verbose: nil, &block) # :yield: dir
@@ -511,6 +515,8 @@ module Bundler::FileUtils
# Raises an exception if +dest+ is the path to an existing file
# and keyword argument +force+ is not +true+.
#
+ # Bundler::FileUtils#link is an alias for Bundler::FileUtils#ln.
+ #
# Related: Bundler::FileUtils.link_entry (has different options).
#
def ln(src, dest, force: nil, noop: nil, verbose: nil)
@@ -701,6 +707,8 @@ module Bundler::FileUtils
# ln -sf src2.txt dest2.txt
# ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
#
+ # Bundler::FileUtils.symlink is an alias for Bundler::FileUtils.ln_s.
+ #
# Related: Bundler::FileUtils.ln_sf.
#
def ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
@@ -868,6 +876,8 @@ module Bundler::FileUtils
#
# Raises an exception if +src+ is a directory.
#
+ # Bundler::FileUtils.copy is an alias for Bundler::FileUtils.cp.
+ #
# Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
#
def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
@@ -1154,6 +1164,8 @@ module Bundler::FileUtils
# mv src0 dest0
# mv src1.txt src1 dest1
#
+ # Bundler::FileUtils.move is an alias for Bundler::FileUtils.mv.
+ #
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
return if noop
@@ -1211,6 +1223,8 @@ module Bundler::FileUtils
#
# rm src0.dat src0.txt
#
+ # Bundler::FileUtils.remove is an alias for Bundler::FileUtils.rm.
+ #
# Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
#
def rm(list, force: nil, noop: nil, verbose: nil)
@@ -1236,6 +1250,8 @@ module Bundler::FileUtils
#
# See Bundler::FileUtils.rm for keyword arguments.
#
+ # Bundler::FileUtils.safe_unlink is an alias for Bundler::FileUtils.rm_f.
+ #
# Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
#
def rm_f(list, noop: nil, verbose: nil)
@@ -1323,6 +1339,8 @@ module Bundler::FileUtils
#
# See Bundler::FileUtils.rm_r for keyword arguments.
#
+ # Bundler::FileUtils.rmtree is an alias for Bundler::FileUtils.rm_rf.
+ #
# Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
#
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
@@ -1624,13 +1642,7 @@ module Bundler::FileUtils
st = File.stat(s)
unless File.exist?(d) and compare_file(s, d)
remove_file d, true
- if d.end_with?('/')
- mkdir_p d
- copy_file s, d + File.basename(s)
- else
- mkdir_p File.expand_path('..', d)
- copy_file s, d
- end
+ copy_file s, d
File.utime st.atime, st.mtime, d if preserve
File.chmod fu_mode(mode, st), d if mode
File.chown uid, gid, d if uid or gid
diff --git a/lib/bundler/vendor/net-http-persistent/.document b/lib/bundler/vendor/net-http-persistent/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/bundler/vendor/net-http-persistent/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
index c15b346330..a4e1c5a750 100644
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
@@ -1,14 +1,14 @@
-require_relative '../../../../../vendored_net_http'
-require_relative '../../../../../vendored_uri'
+require 'net/http'
+require_relative '../../../../uri/lib/uri'
require 'cgi' # for escaping
require_relative '../../../../connection_pool/lib/connection_pool'
autoload :OpenSSL, 'openssl'
##
-# Persistent connections for Gem::Net::HTTP
+# Persistent connections for Net::HTTP
#
-# Gem::Net::HTTP::Persistent maintains persistent connections across all the
+# Bundler::Persistent::Net::HTTP::Persistent maintains persistent connections across all the
# servers you wish to talk to. For each host:port you communicate with a
# single persistent connection is created.
#
@@ -22,34 +22,34 @@ autoload :OpenSSL, 'openssl'
#
# require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
#
-# uri = Gem::URI 'http://example.com/awesome/web/service'
+# uri = Bundler::URI 'http://example.com/awesome/web/service'
#
-# http = Gem::Net::HTTP::Persistent.new
+# http = Bundler::Persistent::Net::HTTP::Persistent.new
#
# # perform a GET
# response = http.request uri
#
# # or
#
-# get = Gem::Net::HTTP::Get.new uri.request_uri
+# get = Net::HTTP::Get.new uri.request_uri
# response = http.request get
#
# # create a POST
# post_uri = uri + 'create'
-# post = Gem::Net::HTTP::Post.new post_uri.path
+# post = Net::HTTP::Post.new post_uri.path
# post.set_form_data 'some' => 'cool data'
#
-# # perform the POST, the Gem::URI is always required
+# # perform the POST, the Bundler::URI is always required
# response http.request post_uri, post
#
# Note that for GET, HEAD and other requests that do not have a body you want
-# to use Gem::URI#request_uri not Gem::URI#path. The request_uri contains the query
+# to use Bundler::URI#request_uri not Bundler::URI#path. The request_uri contains the query
# params which are sent in the body for other requests.
#
# == TLS/SSL
#
# TLS connections are automatically created depending upon the scheme of the
-# Gem::URI. TLS connections are automatically verified against the default
+# Bundler::URI. TLS connections are automatically verified against the default
# certificate store for your computer. You can override this by changing
# verify_mode or by specifying an alternate cert_store.
#
@@ -72,7 +72,7 @@ autoload :OpenSSL, 'openssl'
# == Proxies
#
# A proxy can be set through #proxy= or at initialization time by providing a
-# second argument to ::new. The proxy may be the Gem::URI of the proxy server or
+# second argument to ::new. The proxy may be the Bundler::URI of the proxy server or
# <code>:ENV</code> which will consult environment variables.
#
# See #proxy= and #proxy_from_env for details.
@@ -92,7 +92,7 @@ autoload :OpenSSL, 'openssl'
#
# === Segregation
#
-# Each Gem::Net::HTTP::Persistent instance has its own pool of connections. There
+# Each Bundler::Persistent::Net::HTTP::Persistent instance has its own pool of connections. There
# is no sharing with other instances (as was true in earlier versions).
#
# === Idle Timeout
@@ -131,7 +131,7 @@ autoload :OpenSSL, 'openssl'
#
# === Connection Termination
#
-# If you are done using the Gem::Net::HTTP::Persistent instance you may shut down
+# If you are done using the Bundler::Persistent::Net::HTTP::Persistent instance you may shut down
# all the connections in the current thread with #shutdown. This is not
# recommended for normal use, it should only be used when it will be several
# minutes before you make another HTTP request.
@@ -141,7 +141,7 @@ autoload :OpenSSL, 'openssl'
# Ruby will automatically garbage collect and shutdown your HTTP connections
# when the thread terminates.
-class Gem::Net::HTTP::Persistent
+class Bundler::Persistent::Net::HTTP::Persistent
##
# The beginning of Time
@@ -172,12 +172,12 @@ class Gem::Net::HTTP::Persistent
end
##
- # The version of Gem::Net::HTTP::Persistent you are using
+ # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
- VERSION = '4.0.2'
+ VERSION = '4.0.1'
##
- # Error class for errors raised by Gem::Net::HTTP::Persistent. Various
+ # Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various
# SystemCallErrors are re-raised with a human-readable message under this
# class.
@@ -197,10 +197,10 @@ class Gem::Net::HTTP::Persistent
# NOTE: This may not work on ruby > 1.9.
def self.detect_idle_timeout uri, max = 10
- uri = Gem::URI uri unless Gem::URI::Generic === uri
+ uri = Bundler::URI uri unless Bundler::URI::Generic === uri
uri += '/'
- req = Gem::Net::HTTP::Head.new uri.request_uri
+ req = Net::HTTP::Head.new uri.request_uri
http = new 'net-http-persistent detect_idle_timeout'
@@ -214,7 +214,7 @@ class Gem::Net::HTTP::Persistent
$stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
- unless Gem::Net::HTTPOK === response then
+ unless Net::HTTPOK === response then
raise Error, "bad response code #{response.code} detecting idle timeout"
end
@@ -238,7 +238,7 @@ class Gem::Net::HTTP::Persistent
attr_reader :certificate
##
- # For Gem::Net::HTTP parity
+ # For Net::HTTP parity
alias cert certificate
@@ -266,7 +266,7 @@ class Gem::Net::HTTP::Persistent
attr_reader :ciphers
##
- # Sends debug_output to this IO via Gem::Net::HTTP#set_debug_output.
+ # Sends debug_output to this IO via Net::HTTP#set_debug_output.
#
# Never use this method in production code, it causes a serious security
# hole.
@@ -279,7 +279,7 @@ class Gem::Net::HTTP::Persistent
attr_reader :generation # :nodoc:
##
- # Headers that are added to every request using Gem::Net::HTTP#add_field
+ # Headers that are added to every request using Net::HTTP#add_field
attr_reader :headers
@@ -304,7 +304,7 @@ class Gem::Net::HTTP::Persistent
##
# Number of retries to perform if a request fails.
#
- # See also #max_retries=, Gem::Net::HTTP#max_retries=.
+ # See also #max_retries=, Net::HTTP#max_retries=.
attr_reader :max_retries
@@ -325,12 +325,12 @@ class Gem::Net::HTTP::Persistent
attr_reader :name
##
- # Seconds to wait until a connection is opened. See Gem::Net::HTTP#open_timeout
+ # Seconds to wait until a connection is opened. See Net::HTTP#open_timeout
attr_accessor :open_timeout
##
- # Headers that are added to every request using Gem::Net::HTTP#[]=
+ # Headers that are added to every request using Net::HTTP#[]=
attr_reader :override_headers
@@ -340,7 +340,7 @@ class Gem::Net::HTTP::Persistent
attr_reader :private_key
##
- # For Gem::Net::HTTP parity
+ # For Net::HTTP parity
alias key private_key
@@ -360,12 +360,12 @@ class Gem::Net::HTTP::Persistent
attr_reader :pool # :nodoc:
##
- # Seconds to wait until reading one block. See Gem::Net::HTTP#read_timeout
+ # Seconds to wait until reading one block. See Net::HTTP#read_timeout
attr_accessor :read_timeout
##
- # Seconds to wait until writing one block. See Gem::Net::HTTP#write_timeout
+ # Seconds to wait until writing one block. See Net::HTTP#write_timeout
attr_accessor :write_timeout
@@ -450,18 +450,18 @@ class Gem::Net::HTTP::Persistent
attr_reader :verify_mode
##
- # Creates a new Gem::Net::HTTP::Persistent.
+ # Creates a new Bundler::Persistent::Net::HTTP::Persistent.
#
# Set a +name+ for fun. Your library name should be good enough, but this
# otherwise has no purpose.
#
- # +proxy+ may be set to a Gem::URI::HTTP or :ENV to pick up proxy options from
+ # +proxy+ may be set to a Bundler::URI::HTTP or :ENV to pick up proxy options from
# the environment. See proxy_from_env for details.
#
- # In order to use a Gem::URI for the proxy you may need to do some extra work
- # beyond Gem::URI parsing if the proxy requires a password:
+ # In order to use a Bundler::URI for the proxy you may need to do some extra work
+ # beyond Bundler::URI parsing if the proxy requires a password:
#
- # proxy = Gem::URI 'http://proxy.example'
+ # proxy = Bundler::URI 'http://proxy.example'
# proxy.user = 'AzureDiamond'
# proxy.password = 'hunter2'
#
@@ -492,8 +492,8 @@ class Gem::Net::HTTP::Persistent
@socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
Socket.const_defined? :TCP_NODELAY
- @pool = Gem::Net::HTTP::Persistent::Pool.new size: pool_size do |http_args|
- Gem::Net::HTTP::Persistent::Connection.new Gem::Net::HTTP, http_args, @ssl_generation
+ @pool = Bundler::Persistent::Net::HTTP::Persistent::Pool.new size: pool_size do |http_args|
+ Bundler::Persistent::Net::HTTP::Persistent::Connection.new Net::HTTP, http_args, @ssl_generation
end
@certificate = nil
@@ -510,7 +510,7 @@ class Gem::Net::HTTP::Persistent
@verify_mode = nil
@cert_store = nil
- @generation = 0 # incremented when proxy Gem::URI changes
+ @generation = 0 # incremented when proxy Bundler::URI changes
if HAVE_OPENSSL then
@verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -529,7 +529,7 @@ class Gem::Net::HTTP::Persistent
reconnect_ssl
end
- # For Gem::Net::HTTP parity
+ # For Net::HTTP parity
alias cert= certificate=
##
@@ -648,7 +648,7 @@ class Gem::Net::HTTP::Persistent
end
##
- # Starts the Gem::Net::HTTP +connection+
+ # Starts the Net::HTTP +connection+
def start http
http.set_debug_output @debug_output if @debug_output
@@ -666,7 +666,7 @@ class Gem::Net::HTTP::Persistent
end
##
- # Finishes the Gem::Net::HTTP +connection+
+ # Finishes the Net::HTTP +connection+
def finish connection
connection.finish
@@ -716,16 +716,16 @@ class Gem::Net::HTTP::Persistent
reconnect_ssl
end
- # For Gem::Net::HTTP parity
+ # For Net::HTTP parity
alias key= private_key=
##
- # Sets the proxy server. The +proxy+ may be the Gem::URI of the proxy server,
+ # Sets the proxy server. The +proxy+ may be the Bundler::URI of the proxy server,
# the symbol +:ENV+ which will read the proxy from the environment or nil to
# disable use of a proxy. See #proxy_from_env for details on setting the
# proxy from the environment.
#
- # If the proxy Gem::URI is set after requests have been made, the next request
+ # If the proxy Bundler::URI is set after requests have been made, the next request
# will shut-down and re-open all connections.
#
# The +no_proxy+ query parameter can be used to specify hosts which shouldn't
@@ -736,9 +736,9 @@ class Gem::Net::HTTP::Persistent
def proxy= proxy
@proxy_uri = case proxy
when :ENV then proxy_from_env
- when Gem::URI::HTTP then proxy
+ when Bundler::URI::HTTP then proxy
when nil then # ignore
- else raise ArgumentError, 'proxy must be :ENV or a Gem::URI::HTTP'
+ else raise ArgumentError, 'proxy must be :ENV or a Bundler::URI::HTTP'
end
@no_proxy.clear
@@ -763,13 +763,13 @@ class Gem::Net::HTTP::Persistent
end
##
- # Creates a Gem::URI for an HTTP proxy server from ENV variables.
+ # Creates a Bundler::URI for an HTTP proxy server from ENV variables.
#
# If +HTTP_PROXY+ is set a proxy will be returned.
#
- # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the Gem::URI is given the
+ # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the Bundler::URI is given the
# indicated user and password unless HTTP_PROXY contains either of these in
- # the Gem::URI.
+ # the Bundler::URI.
#
# The +NO_PROXY+ ENV variable can be used to specify hosts which shouldn't
# be reached via proxy; if set it should be a comma separated list of
@@ -785,7 +785,7 @@ class Gem::Net::HTTP::Persistent
return nil if env_proxy.nil? or env_proxy.empty?
- uri = Gem::URI normalize_uri env_proxy
+ uri = Bundler::URI normalize_uri env_proxy
env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
@@ -835,7 +835,7 @@ class Gem::Net::HTTP::Persistent
end
##
- # Finishes then restarts the Gem::Net::HTTP +connection+
+ # Finishes then restarts the Net::HTTP +connection+
def reset connection
http = connection.http
@@ -854,16 +854,16 @@ class Gem::Net::HTTP::Persistent
end
##
- # Makes a request on +uri+. If +req+ is nil a Gem::Net::HTTP::Get is performed
+ # Makes a request on +uri+. If +req+ is nil a Net::HTTP::Get is performed
# against +uri+.
#
- # If a block is passed #request behaves like Gem::Net::HTTP#request (the body of
+ # If a block is passed #request behaves like Net::HTTP#request (the body of
# the response will not have been read).
#
- # +req+ must be a Gem::Net::HTTPGenericRequest subclass (see Gem::Net::HTTP for a list).
+ # +req+ must be a Net::HTTPGenericRequest subclass (see Net::HTTP for a list).
def request uri, req = nil, &block
- uri = Gem::URI uri
+ uri = Bundler::URI uri
req = request_setup req || uri
response = nil
@@ -896,14 +896,14 @@ class Gem::Net::HTTP::Persistent
end
##
- # Creates a GET request if +req_or_uri+ is a Gem::URI and adds headers to the
+ # Creates a GET request if +req_or_uri+ is a Bundler::URI and adds headers to the
# request.
#
# Returns the request.
def request_setup req_or_uri # :nodoc:
req = if req_or_uri.respond_to? 'request_uri' then
- Gem::Net::HTTP::Get.new req_or_uri.request_uri
+ Net::HTTP::Get.new req_or_uri.request_uri
else
req_or_uri
end
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb
index 8b9ab5cc78..a57a5d1352 100644
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb
@@ -1,8 +1,8 @@
##
-# A Gem::Net::HTTP connection wrapper that holds extra information for managing the
+# A Net::HTTP connection wrapper that holds extra information for managing the
# connection's lifetime.
-class Gem::Net::HTTP::Persistent::Connection # :nodoc:
+class Bundler::Persistent::Net::HTTP::Persistent::Connection # :nodoc:
attr_accessor :http
@@ -25,10 +25,9 @@ class Gem::Net::HTTP::Persistent::Connection # :nodoc:
ensure
reset
end
- alias_method :close, :finish
def reset
- @last_use = Gem::Net::HTTP::Persistent::EPOCH
+ @last_use = Bundler::Persistent::Net::HTTP::Persistent::EPOCH
@requests = 0
end
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
index 04a1e754bf..9dfa6ffdb1 100644
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
@@ -1,4 +1,4 @@
-class Gem::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc:
+class Bundler::Persistent::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc:
attr_reader :available # :nodoc:
attr_reader :key # :nodoc:
@@ -6,37 +6,25 @@ class Gem::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc:
def initialize(options = {}, &block)
super
- @available = Gem::Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
+ @available = Bundler::Persistent::Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
@key = "current-#{@available.object_id}"
end
def checkin net_http_args
- if net_http_args.is_a?(Hash) && net_http_args.size == 1 && net_http_args[:force]
- # Bundler::ConnectionPool 2.4+ calls `checkin(force: true)` after fork.
- # When this happens, we should remove all connections from Thread.current
- if stacks = Thread.current[@key]
- stacks.each do |http_args, connections|
- connections.each do |conn|
- @available.push conn, connection_args: http_args
- end
- connections.clear
- end
- end
- else
- stack = Thread.current[@key][net_http_args] ||= []
+ stack = Thread.current[@key][net_http_args] ||= []
- raise Bundler::ConnectionPool::Error, 'no connections are checked out' if
- stack.empty?
+ raise Bundler::ConnectionPool::Error, 'no connections are checked out' if
+ stack.empty?
- conn = stack.pop
+ conn = stack.pop
- if stack.empty?
- @available.push conn, connection_args: net_http_args
+ if stack.empty?
+ @available.push conn, connection_args: net_http_args
- Thread.current[@key].delete(net_http_args)
- Thread.current[@key] = nil if Thread.current[@key].empty?
- end
+ Thread.current[@key].delete(net_http_args)
+ Thread.current[@key] = nil if Thread.current[@key].empty?
end
+
nil
end
diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
index 214804fcd9..2da881c554 100644
--- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
+++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
@@ -1,4 +1,4 @@
-class Gem::Net::HTTP::Persistent::TimedStackMulti < Bundler::ConnectionPool::TimedStack # :nodoc:
+class Bundler::Persistent::Net::HTTP::Persistent::TimedStackMulti < Bundler::ConnectionPool::TimedStack # :nodoc:
##
# Returns a new hash that has arrays for keys
diff --git a/lib/bundler/vendor/pub_grub/.document b/lib/bundler/vendor/pub_grub/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/bundler/vendor/pub_grub/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb
index 36ab06254d..4bf61461b2 100644
--- a/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb
+++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb
@@ -1,5 +1,4 @@
require_relative 'package'
-require_relative 'rubygems'
require_relative 'version_constraint'
require_relative 'incompatibility'
require_relative 'basic_package_source'
diff --git a/lib/bundler/vendor/thor/.document b/lib/bundler/vendor/thor/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/bundler/vendor/thor/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb
index 627722164f..0794dbb522 100644
--- a/lib/bundler/vendor/thor/lib/thor.rb
+++ b/lib/bundler/vendor/thor/lib/thor.rb
@@ -65,15 +65,8 @@ class Bundler::Thor
# Defines the long description of the next command.
#
- # Long description is by default indented, line-wrapped and repeated whitespace merged.
- # In order to print long description verbatim, with indentation and spacing exactly
- # as found in the code, use the +wrap+ option
- #
- # long_desc 'your very long description', wrap: false
- #
# ==== Parameters
# long description<String>
- # options<Hash>
#
def long_desc(long_description, options = {})
if options[:for]
@@ -81,7 +74,6 @@ class Bundler::Thor
command.long_description = long_description if long_description
else
@long_desc = long_description
- @long_desc_wrap = options[:wrap] != false
end
end
@@ -141,7 +133,7 @@ class Bundler::Thor
# # magic
# end
#
- # method_option :foo, :for => :previous_command
+ # method_option :foo => :bar, :for => :previous_command
#
# def next_command
# # magic
@@ -161,9 +153,6 @@ class Bundler::Thor
# :hide - If you want to hide this option from the help.
#
def method_option(name, options = {})
- unless [ Symbol, String ].any? { |klass| name.is_a?(klass) }
- raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}"
- end
scope = if options[:for]
find_and_refresh_command(options[:for]).options
else
@@ -174,81 +163,6 @@ class Bundler::Thor
end
alias_method :option, :method_option
- # Adds and declares option group for exclusive options in the
- # block and arguments. You can declare options as the outside of the block.
- #
- # If :for is given as option, it allows you to change the options from
- # a previous defined command.
- #
- # ==== Parameters
- # Array[Bundler::Thor::Option.name]
- # options<Hash>:: :for is applied for previous defined command.
- #
- # ==== Examples
- #
- # exclusive do
- # option :one
- # option :two
- # end
- #
- # Or
- #
- # option :one
- # option :two
- # exclusive :one, :two
- #
- # If you give "--one" and "--two" at the same time ExclusiveArgumentsError
- # will be raised.
- #
- def method_exclusive(*args, &block)
- register_options_relation_for(:method_options,
- :method_exclusive_option_names, *args, &block)
- end
- alias_method :exclusive, :method_exclusive
-
- # Adds and declares option group for required at least one of options in the
- # block of arguments. You can declare options as the outside of the block.
- #
- # If :for is given as option, it allows you to change the options from
- # a previous defined command.
- #
- # ==== Parameters
- # Array[Bundler::Thor::Option.name]
- # options<Hash>:: :for is applied for previous defined command.
- #
- # ==== Examples
- #
- # at_least_one do
- # option :one
- # option :two
- # end
- #
- # Or
- #
- # option :one
- # option :two
- # at_least_one :one, :two
- #
- # If you do not give "--one" and "--two" AtLeastOneRequiredArgumentError
- # will be raised.
- #
- # You can use at_least_one and exclusive at the same time.
- #
- # exclusive do
- # at_least_one do
- # option :one
- # option :two
- # end
- # end
- #
- # Then it is required either only one of "--one" or "--two".
- #
- def method_at_least_one(*args, &block)
- register_options_relation_for(:method_options,
- :method_at_least_one_option_names, *args, &block)
- end
- alias_method :at_least_one, :method_at_least_one
-
# Prints help information for the given command.
#
# ==== Parameters
@@ -264,16 +178,9 @@ class Bundler::Thor
shell.say " #{banner(command).split("\n").join("\n ")}"
shell.say
class_options_help(shell, nil => command.options.values)
- print_exclusive_options(shell, command)
- print_at_least_one_required_options(shell, command)
-
if command.long_description
shell.say "Description:"
- if command.wrap_long_description
- shell.print_wrapped(command.long_description, indent: 2)
- else
- shell.say command.long_description
- end
+ shell.print_wrapped(command.long_description, :indent => 2)
else
shell.say command.description
end
@@ -290,7 +197,7 @@ class Bundler::Thor
Bundler::Thor::Util.thor_classes_in(self).each do |klass|
list += klass.printable_commands(false)
end
- sort_commands!(list)
+ list.sort! { |a, b| a[0] <=> b[0] }
if defined?(@package_name) && @package_name
shell.say "#{@package_name} commands:"
@@ -298,11 +205,9 @@ class Bundler::Thor
shell.say "Commands:"
end
- shell.print_table(list, indent: 2, truncate: true)
+ shell.print_table(list, :indent => 2, :truncate => true)
shell.say
class_options_help(shell)
- print_exclusive_options(shell)
- print_at_least_one_required_options(shell)
end
# Returns commands ready to be printed.
@@ -333,7 +238,7 @@ class Bundler::Thor
define_method(subcommand) do |*args|
args, opts = Bundler::Thor::Arguments.split(args)
- invoke_args = [args, opts, {invoked_via_subcommand: true, class_options: options}]
+ invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}]
invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
invoke subcommand_class, *invoke_args
end
@@ -441,24 +346,6 @@ class Bundler::Thor
protected
- # Returns this class exclusive options array set.
- #
- # ==== Returns
- # Array[Array[Bundler::Thor::Option.name]]
- #
- def method_exclusive_option_names #:nodoc:
- @method_exclusive_option_names ||= []
- end
-
- # Returns this class at least one of required options array set.
- #
- # ==== Returns
- # Array[Array[Bundler::Thor::Option.name]]
- #
- def method_at_least_one_option_names #:nodoc:
- @method_at_least_one_option_names ||= []
- end
-
def stop_on_unknown_option #:nodoc:
@stop_on_unknown_option ||= []
end
@@ -468,30 +355,8 @@ class Bundler::Thor
@disable_required_check ||= [:help]
end
- def print_exclusive_options(shell, command = nil) # :nodoc:
- opts = []
- opts = command.method_exclusive_option_names unless command.nil?
- opts += class_exclusive_option_names
- unless opts.empty?
- shell.say "Exclusive Options:"
- shell.print_table(opts.map{ |ex| ex.map{ |e| "--#{e}"}}, indent: 2 )
- shell.say
- end
- end
-
- def print_at_least_one_required_options(shell, command = nil) # :nodoc:
- opts = []
- opts = command.method_at_least_one_option_names unless command.nil?
- opts += class_at_least_one_option_names
- unless opts.empty?
- shell.say "Required At Least One:"
- shell.print_table(opts.map{ |ex| ex.map{ |e| "--#{e}"}}, indent: 2 )
- shell.say
- end
- end
-
# The method responsible for dispatching given the args.
- def dispatch(meth, given_args, given_opts, config) #:nodoc:
+ def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
meth ||= retrieve_command_name(given_args)
command = all_commands[normalize_command_name(meth)]
@@ -550,16 +415,12 @@ class Bundler::Thor
@usage ||= nil
@desc ||= nil
@long_desc ||= nil
- @long_desc_wrap ||= nil
@hide ||= nil
if @usage && @desc
base_class = @hide ? Bundler::Thor::HiddenCommand : Bundler::Thor::Command
- relations = {exclusive_option_names: method_exclusive_option_names,
- at_least_one_option_names: method_at_least_one_option_names}
- commands[meth] = base_class.new(meth, @desc, @long_desc, @long_desc_wrap, @usage, method_options, relations)
- @usage, @desc, @long_desc, @long_desc_wrap, @method_options, @hide = nil
- @method_exclusive_option_names, @method_at_least_one_option_names = nil
+ commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
+ @usage, @desc, @long_desc, @method_options, @hide = nil
true
elsif all_commands[meth] || meth == "method_missing"
true
@@ -634,14 +495,6 @@ class Bundler::Thor
"
end
alias_method :subtask_help, :subcommand_help
-
- # Sort the commands, lexicographically by default.
- #
- # Can be overridden in the subclass to change the display order of the
- # commands.
- def sort_commands!(list)
- list.sort! { |a, b| a[0] <=> b[0] }
- end
end
include Bundler::Thor::Base
diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb
index ca58182691..de9b3b4c86 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions.rb
@@ -46,17 +46,17 @@ class Bundler::Thor
# Add runtime options that help actions execution.
#
def add_runtime_options!
- class_option :force, type: :boolean, aliases: "-f", group: :runtime,
- desc: "Overwrite files that already exist"
+ class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
+ :desc => "Overwrite files that already exist"
- class_option :pretend, type: :boolean, aliases: "-p", group: :runtime,
- desc: "Run but do not make any changes"
+ class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
+ :desc => "Run but do not make any changes"
- class_option :quiet, type: :boolean, aliases: "-q", group: :runtime,
- desc: "Suppress status output"
+ class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
+ :desc => "Suppress status output"
- class_option :skip, type: :boolean, aliases: "-s", group: :runtime,
- desc: "Skip files that already exist"
+ class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
+ :desc => "Skip files that already exist"
end
end
@@ -113,9 +113,9 @@ class Bundler::Thor
#
def relative_to_original_destination_root(path, remove_dot = true)
root = @destination_stack[0]
- if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ""].include?(path[root.size..root.size])
+ if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
path = path.dup
- path[0...root.size] = "."
+ path[0...root.size] = '.'
remove_dot ? (path[2..-1] || "") : path
else
path
@@ -175,7 +175,7 @@ class Bundler::Thor
shell.padding += 1 if verbose
@destination_stack.push File.expand_path(dir, destination_root)
- # If the directory doesn't exist and we're not pretending
+ # If the directory doesnt exist and we're not pretending
if !File.exist?(destination_root) && !pretend
require "fileutils"
FileUtils.mkdir_p(destination_root)
@@ -225,7 +225,7 @@ class Bundler::Thor
require "open-uri"
URI.open(path, "Accept" => "application/x-thor-template", &:read)
else
- File.open(path, &:read)
+ open(path, &:read)
end
instance_eval(contents, path)
@@ -284,7 +284,7 @@ class Bundler::Thor
#
def run_ruby_script(command, config = {})
return unless behavior == :invoke
- run command, config.merge(with: Bundler::Thor::Util.ruby_command)
+ run command, config.merge(:with => Bundler::Thor::Util.ruby_command)
end
# Run a thor command. A hash of options can be given and it's converted to
@@ -315,7 +315,7 @@ class Bundler::Thor
args.push Bundler::Thor::Options.to_switches(config)
command = args.join(" ").strip
- run command, with: :thor, verbose: verbose, pretend: pretend, capture: capture
+ run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
end
protected
@@ -323,7 +323,7 @@ class Bundler::Thor
# Allow current root to be shared between invocations.
#
def _shared_configuration #:nodoc:
- super.merge!(destination_root: destination_root)
+ super.merge!(:destination_root => destination_root)
end
def _cleanup_options_and_set(options, key) #:nodoc:
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
index 6724835b01..330fc08cae 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb
@@ -43,8 +43,7 @@ class Bundler::Thor
# Boolean:: true if it is identical, false otherwise.
#
def identical?
- # binread uses ASCII-8BIT, so to avoid false negatives, the string must use the same
- exists? && File.binread(destination) == String.new(render).force_encoding("ASCII-8BIT")
+ exists? && File.binread(destination) == render
end
# Holds the content to be added to the file.
@@ -61,7 +60,7 @@ class Bundler::Thor
invoke_with_conflict_check do
require "fileutils"
FileUtils.mkdir_p(File.dirname(destination))
- File.open(destination, "wb", config[:perm]) { |f| f.write render }
+ File.open(destination, "wb") { |f| f.write render }
end
given_destination
end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
index 2f9687c0a5..d37327a139 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb
@@ -58,7 +58,7 @@ class Bundler::Thor
def initialize(base, source, destination = nil, config = {}, &block)
@source = File.expand_path(Dir[Util.escape_globs(base.find_in_source_paths(source.to_s))].first)
@block = block
- super(base, destination, {recursive: true}.merge(config))
+ super(base, destination, {:recursive => true}.merge(config))
end
def invoke!
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb
index c0bca78525..284d92c19a 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb
@@ -33,7 +33,7 @@ class Bundler::Thor
#
def initialize(base, destination, config = {})
@base = base
- @config = {verbose: true}.merge(config)
+ @config = {:verbose => true}.merge(config)
self.destination = destination
end
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
index 80a0255996..bf2a737c84 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb
@@ -66,15 +66,12 @@ class Bundler::Thor
# ==== Parameters
# source<String>:: the address of the given content.
# destination<String>:: the relative path to the destination root.
- # config<Hash>:: give :verbose => false to not log the status, and
- # :http_headers => <Hash> to add headers to an http request.
+ # config<Hash>:: give :verbose => false to not log the status.
#
# ==== Examples
#
# get "http://gist.github.com/103208", "doc/README"
#
- # get "http://gist.github.com/103208", "doc/README", :http_headers => {"Content-Type" => "application/json"}
- #
# get "http://gist.github.com/103208" do |content|
# content.split("\n").first
# end
@@ -85,10 +82,10 @@ class Bundler::Thor
render = if source =~ %r{^https?\://}
require "open-uri"
- URI.send(:open, source, config.fetch(:http_headers, {})) { |input| input.binmode.read }
+ URI.send(:open, source) { |input| input.binmode.read }
else
source = File.expand_path(find_in_source_paths(source.to_s))
- File.open(source) { |input| input.binmode.read }
+ open(source) { |input| input.binmode.read }
end
destination ||= if block_given?
@@ -123,7 +120,12 @@ class Bundler::Thor
context = config.delete(:context) || instance_eval("binding")
create_file destination, nil, config do
- capturable_erb = CapturableERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer")
+ match = ERB.version.match(/(\d+\.\d+\.\d+)/)
+ capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
+ CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
+ else
+ CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
+ end
content = capturable_erb.tap do |erb|
erb.filename = source
end.result(context)
@@ -250,7 +252,7 @@ class Bundler::Thor
# flag<Regexp|String>:: the regexp or string to be replaced
# replacement<String>:: the replacement, can be also given as a block
# config<Hash>:: give :verbose => false to not log the status, and
- # :force => true, to force the replacement regardless of runner behavior.
+ # :force => true, to force the replacement regardles of runner behavior.
#
# ==== Example
#
diff --git a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
index 70526e615f..bf013307f1 100644
--- a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
+++ b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
@@ -21,7 +21,7 @@ class Bundler::Thor
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
# end
#
- WARNINGS = {unchanged_no_flag: "File unchanged! Either the supplied flag value not found or the content has already been inserted!"}
+ WARNINGS = { unchanged_no_flag: 'File unchanged! The supplied flag value not found!' }
def insert_into_file(destination, *args, &block)
data = block_given? ? block : args.shift
@@ -37,7 +37,7 @@ class Bundler::Thor
attr_reader :replacement, :flag, :behavior
def initialize(base, destination, data, config)
- super(base, destination, {verbose: true}.merge(config))
+ super(base, destination, {:verbose => true}.merge(config))
@behavior, @flag = if @config.key?(:after)
[:after, @config.delete(:after)]
@@ -59,8 +59,6 @@ class Bundler::Thor
if exists?
if replace!(/#{flag}/, content, config[:force])
say_status(:invoke)
- elsif replacement_present?
- say_status(:unchanged, color: :blue)
else
say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red)
end
@@ -98,8 +96,6 @@ class Bundler::Thor
end
elsif warning
warning
- elsif behavior == :unchanged
- :unchanged
else
:subtract
end
@@ -107,18 +103,11 @@ class Bundler::Thor
super(status, (color || config[:verbose]))
end
- def content
- @content ||= File.read(destination)
- end
-
- def replacement_present?
- content.include?(replacement)
- end
-
# Adds the content to the file.
#
def replace!(regexp, string, force)
- if force || !replacement_present?
+ content = File.read(destination)
+ if force || !content.include?(replacement)
success = content.gsub!(regexp, string)
File.open(destination, "wb") { |file| file.write(content) } unless pretend?
diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb
index b156899c1e..8487f9590a 100644
--- a/lib/bundler/vendor/thor/lib/thor/base.rb
+++ b/lib/bundler/vendor/thor/lib/thor/base.rb
@@ -24,9 +24,9 @@ class Bundler::Thor
class << self
def deprecation_warning(message) #:nodoc:
- unless ENV["THOR_SILENCE_DEPRECATION"]
+ unless ENV['THOR_SILENCE_DEPRECATION']
warn "Deprecation warning: #{message}\n" +
- "You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION."
+ 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.'
end
end
end
@@ -60,7 +60,6 @@ class Bundler::Thor
command_options = config.delete(:command_options) # hook for start
parse_options = parse_options.merge(command_options) if command_options
-
if local_options.is_a?(Array)
array_options = local_options
hash_options = {}
@@ -74,24 +73,9 @@ class Bundler::Thor
# Let Bundler::Thor::Options parse the options first, so it can remove
# declared options from the array. This will leave us with
# a list of arguments that weren't declared.
- current_command = config[:current_command]
- stop_on_unknown = self.class.stop_on_unknown_option? current_command
-
- # Give a relation of options.
- # After parsing, Bundler::Thor::Options check whether right relations are kept
- relations = if current_command.nil?
- {exclusive_option_names: [], at_least_one_option_names: []}
- else
- current_command.options_relation
- end
-
- self.class.class_exclusive_option_names.map { |n| relations[:exclusive_option_names] << n }
- self.class.class_at_least_one_option_names.map { |n| relations[:at_least_one_option_names] << n }
-
- disable_required_check = self.class.disable_required_check? current_command
-
- opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check, relations)
-
+ stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
+ disable_required_check = self.class.disable_required_check? config[:current_command]
+ opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check)
self.options = opts.parse(array_options)
self.options = config[:class_options].merge(options) if config[:class_options]
@@ -326,92 +310,9 @@ class Bundler::Thor
# :hide:: -- If you want to hide this option from the help.
#
def class_option(name, options = {})
- unless [ Symbol, String ].any? { |klass| name.is_a?(klass) }
- raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}"
- end
build_option(name, options, class_options)
end
- # Adds and declares option group for exclusive options in the
- # block and arguments. You can declare options as the outside of the block.
- #
- # ==== Parameters
- # Array[Bundler::Thor::Option.name]
- #
- # ==== Examples
- #
- # class_exclusive do
- # class_option :one
- # class_option :two
- # end
- #
- # Or
- #
- # class_option :one
- # class_option :two
- # class_exclusive :one, :two
- #
- # If you give "--one" and "--two" at the same time ExclusiveArgumentsError
- # will be raised.
- #
- def class_exclusive(*args, &block)
- register_options_relation_for(:class_options,
- :class_exclusive_option_names, *args, &block)
- end
-
- # Adds and declares option group for required at least one of options in the
- # block and arguments. You can declare options as the outside of the block.
- #
- # ==== Examples
- #
- # class_at_least_one do
- # class_option :one
- # class_option :two
- # end
- #
- # Or
- #
- # class_option :one
- # class_option :two
- # class_at_least_one :one, :two
- #
- # If you do not give "--one" and "--two" AtLeastOneRequiredArgumentError
- # will be raised.
- #
- # You can use class_at_least_one and class_exclusive at the same time.
- #
- # class_exclusive do
- # class_at_least_one do
- # class_option :one
- # class_option :two
- # end
- # end
- #
- # Then it is required either only one of "--one" or "--two".
- #
- def class_at_least_one(*args, &block)
- register_options_relation_for(:class_options,
- :class_at_least_one_option_names, *args, &block)
- end
-
- # Returns this class exclusive options array set, looking up in the ancestors chain.
- #
- # ==== Returns
- # Array[Array[Bundler::Thor::Option.name]]
- #
- def class_exclusive_option_names
- @class_exclusive_option_names ||= from_superclass(:class_exclusive_option_names, [])
- end
-
- # Returns this class at least one of required options array set, looking up in the ancestors chain.
- #
- # ==== Returns
- # Array[Array[Bundler::Thor::Option.name]]
- #
- def class_at_least_one_option_names
- @class_at_least_one_option_names ||= from_superclass(:class_at_least_one_option_names, [])
- end
-
# Removes a previous defined argument. If :undefine is given, undefine
# accessors as well.
#
@@ -605,7 +506,7 @@ class Bundler::Thor
#
def public_command(*names)
names.each do |name|
- class_eval "def #{name}(*); super end", __FILE__, __LINE__
+ class_eval "def #{name}(*); super end"
end
end
alias_method :public_task, :public_command
@@ -657,19 +558,20 @@ class Bundler::Thor
return if options.empty?
list = []
- padding = options.map { |o| o.aliases_for_usage.size }.max.to_i
+ padding = options.map { |o| o.aliases.size }.max.to_i * 4
+
options.each do |option|
next if option.hide
item = [option.usage(padding)]
item.push(option.description ? "# #{option.description}" : "")
list << item
- list << ["", "# Default: #{option.print_default}"] if option.show_default?
- list << ["", "# Possible values: #{option.enum_to_s}"] if option.enum
+ list << ["", "# Default: #{option.default}"] if option.show_default?
+ list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
end
shell.say(group_name ? "#{group_name} options:" : "Options:")
- shell.print_table(list, indent: 2)
+ shell.print_table(list, :indent => 2)
shell.say ""
end
@@ -686,7 +588,7 @@ class Bundler::Thor
# options<Hash>:: Described in both class_option and method_option.
# scope<Hash>:: Options hash that is being built up
def build_option(name, options, scope) #:nodoc:
- scope[name] = Bundler::Thor::Option.new(name, {check_default_type: check_default_type}.merge!(options))
+ scope[name] = Bundler::Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options))
end
# Receives a hash of options, parse them and add to the scope. This is a
@@ -708,7 +610,7 @@ class Bundler::Thor
def find_and_refresh_command(name) #:nodoc:
if commands[name.to_s]
commands[name.to_s]
- elsif command = all_commands[name.to_s] # rubocop:disable Lint/AssignmentInCondition
+ elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition
commands[name.to_s] = command.clone
else
raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
@@ -716,7 +618,7 @@ class Bundler::Thor
end
alias_method :find_and_refresh_task, :find_and_refresh_command
- # Every time someone inherits from a Bundler::Thor class, register the klass
+ # Everytime someone inherits from a Bundler::Thor class, register the klass
# and file into baseclass.
def inherited(klass)
super(klass)
@@ -792,34 +694,6 @@ class Bundler::Thor
def dispatch(command, given_args, given_opts, config) #:nodoc:
raise NotImplementedError
end
-
- # Register a relation of options for target(method_option/class_option)
- # by args and block.
- def register_options_relation_for(target, relation, *args, &block) # :nodoc:
- opt = args.pop if args.last.is_a? Hash
- opt ||= {}
- names = args.map{ |arg| arg.to_s }
- names += built_option_names(target, opt, &block) if block_given?
- command_scope_member(relation, opt) << names
- end
-
- # Get target(method_options or class_options) options
- # of before and after by block evaluation.
- def built_option_names(target, opt = {}, &block) # :nodoc:
- before = command_scope_member(target, opt).map{ |k,v| v.name }
- instance_eval(&block)
- after = command_scope_member(target, opt).map{ |k,v| v.name }
- after - before
- end
-
- # Get command scope member by name.
- def command_scope_member(name, options = {}) # :nodoc:
- if options[:for]
- find_and_refresh_command(options[:for]).send(name)
- else
- send(name)
- end
- end
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/command.rb b/lib/bundler/vendor/thor/lib/thor/command.rb
index 68c8fffedb..040c971c0c 100644
--- a/lib/bundler/vendor/thor/lib/thor/command.rb
+++ b/lib/bundler/vendor/thor/lib/thor/command.rb
@@ -1,15 +1,14 @@
class Bundler::Thor
- class Command < Struct.new(:name, :description, :long_description, :wrap_long_description, :usage, :options, :options_relation, :ancestor_name)
+ class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
- def initialize(name, description, long_description, wrap_long_description, usage, options = nil, options_relation = nil)
- super(name.to_s, description, long_description, wrap_long_description, usage, options || {}, options_relation || {})
+ def initialize(name, description, long_description, usage, options = nil)
+ super(name.to_s, description, long_description, usage, options || {})
end
def initialize_copy(other) #:nodoc:
super(other)
self.options = other.options.dup if other.options
- self.options_relation = other.options_relation.dup if other.options_relation
end
def hidden?
@@ -63,14 +62,6 @@ class Bundler::Thor
end.join("\n")
end
- def method_exclusive_option_names #:nodoc:
- self.options_relation[:exclusive_option_names] || []
- end
-
- def method_at_least_one_option_names #:nodoc:
- self.options_relation[:at_least_one_option_names] || []
- end
-
protected
# Add usage with required arguments
@@ -136,7 +127,7 @@ class Bundler::Thor
# A dynamic command that handles method missing scenarios.
class DynamicCommand < Command
def initialize(name, options = nil)
- super(name.to_s, "A dynamically-generated command", name.to_s, nil, name.to_s, options)
+ super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options)
end
def run(instance, args = [])
diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb
index b16a98f782..3c4483e5dd 100644
--- a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb
+++ b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb
@@ -38,10 +38,6 @@ class Bundler::Thor
super(convert_key(key), *args)
end
- def slice(*keys)
- super(*keys.map{ |key| convert_key(key) })
- end
-
def key?(key)
super(convert_key(key))
end
diff --git a/lib/bundler/vendor/thor/lib/thor/error.rb b/lib/bundler/vendor/thor/lib/thor/error.rb
index 928646e501..03f2ce85bb 100644
--- a/lib/bundler/vendor/thor/lib/thor/error.rb
+++ b/lib/bundler/vendor/thor/lib/thor/error.rb
@@ -1,15 +1,18 @@
class Bundler::Thor
Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
- Module.new do
- def to_s
- super + DidYouMean.formatter.message_for(corrections)
- end
-
- def corrections
- @corrections ||= self.class.const_get(:SpellChecker).new(self).corrections
- end
- end
- end
+ # In order to support versions of Ruby that don't have keyword
+ # arguments, we need our own spell checker class that doesn't take key
+ # words. Even though this code wouldn't be hit because of the check
+ # above, it's still necessary because the interpreter would otherwise be
+ # unable to parse the file.
+ class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
+ def initialize(dictionary)
+ @dictionary = dictionary
+ end
+ end
+
+ DidYouMean::Correctable
+ end
# Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
# errors have their backtrace suppressed and are nicely shown to the user.
@@ -34,7 +37,7 @@ class Bundler::Thor
end
def spell_checker
- DidYouMean::SpellChecker.new(dictionary: error.all_commands)
+ NoKwargSpellChecker.new(error.all_commands)
end
end
@@ -76,7 +79,7 @@ class Bundler::Thor
end
def spell_checker
- @spell_checker ||= DidYouMean::SpellChecker.new(dictionary: error.switches)
+ @spell_checker ||= NoKwargSpellChecker.new(error.switches)
end
end
@@ -98,9 +101,15 @@ class Bundler::Thor
class MalformattedArgumentError < InvocationError
end
- class ExclusiveArgumentError < InvocationError
- end
-
- class AtLeastOneRequiredArgumentError < InvocationError
+ if Correctable
+ if DidYouMean.respond_to?(:correct_error)
+ DidYouMean.correct_error(Bundler::Thor::UndefinedCommandError, UndefinedCommandError::SpellChecker)
+ DidYouMean.correct_error(Bundler::Thor::UnknownArgumentError, UnknownArgumentError::SpellChecker)
+ else
+ DidYouMean::SPELL_CHECKERS.merge!(
+ 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
+ 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
+ )
+ end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/group.rb b/lib/bundler/vendor/thor/lib/thor/group.rb
index 7ea11e8f93..7861d05345 100644
--- a/lib/bundler/vendor/thor/lib/thor/group.rb
+++ b/lib/bundler/vendor/thor/lib/thor/group.rb
@@ -169,7 +169,7 @@ class Bundler::Thor::Group
# options are added to group_options hash. Options that already exists
# in base_options are not added twice.
#
- def get_options_from_invocations(group_options, base_options) #:nodoc:
+ def get_options_from_invocations(group_options, base_options) #:nodoc: # rubocop:disable MethodLength
invocations.each do |name, from_option|
value = if from_option
option = class_options[name]
diff --git a/lib/bundler/vendor/thor/lib/thor/invocation.rb b/lib/bundler/vendor/thor/lib/thor/invocation.rb
index 5ce74710ba..248a466f8e 100644
--- a/lib/bundler/vendor/thor/lib/thor/invocation.rb
+++ b/lib/bundler/vendor/thor/lib/thor/invocation.rb
@@ -143,7 +143,7 @@ class Bundler::Thor
# Configuration values that are shared between invocations.
def _shared_configuration #:nodoc:
- {invocations: @_invocations}
+ {:invocations => @_invocations}
end
# This method simply retrieves the class and command to be invoked.
diff --git a/lib/bundler/vendor/thor/lib/thor/nested_context.rb b/lib/bundler/vendor/thor/lib/thor/nested_context.rb
index 7d60cb1c12..fd36b9d43f 100644
--- a/lib/bundler/vendor/thor/lib/thor/nested_context.rb
+++ b/lib/bundler/vendor/thor/lib/thor/nested_context.rb
@@ -13,10 +13,10 @@ class Bundler::Thor
end
def entered?
- @depth.positive?
+ @depth > 0
end
- private
+ private
def push
@depth += 1
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/argument.rb b/lib/bundler/vendor/thor/lib/thor/parser/argument.rb
index b9e94e4669..dfe7398583 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/argument.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/argument.rb
@@ -24,17 +24,6 @@ class Bundler::Thor
validate! # Trigger specific validations
end
- def print_default
- if @type == :array and @default.is_a?(Array)
- @default.map { |x|
- p = x.gsub('"','\\"')
- "\"#{p}\""
- }.join(" ")
- else
- @default
- end
- end
-
def usage
required? ? banner : "[#{banner}]"
end
@@ -52,19 +41,11 @@ class Bundler::Thor
end
end
- def enum_to_s
- if enum.respond_to? :join
- enum.join(", ")
- else
- "#{enum.first}..#{enum.last}"
- end
- end
-
protected
def validate!
raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
- raise ArgumentError, "An argument cannot have an enum other than an enumerable." if @enum && !@enum.is_a?(Enumerable)
+ raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array)
end
def valid_type?(type)
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
index b6f9c9a37a..3a5d82cf29 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
@@ -1,5 +1,5 @@
class Bundler::Thor
- class Arguments #:nodoc:
+ class Arguments #:nodoc: # rubocop:disable ClassLength
NUMERIC = /[-+]?(\d*\.\d+|\d+)/
# Receives an array of args and returns two arrays, one with arguments
@@ -30,7 +30,11 @@ class Bundler::Thor
arguments.each do |argument|
if !argument.default.nil?
- @assigns[argument.human_name] = argument.default.dup
+ begin
+ @assigns[argument.human_name] = argument.default.dup
+ rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
+ @assigns[argument.human_name] = argument.default
+ end
elsif argument.required?
@non_assigned_required << argument
end
@@ -117,18 +121,8 @@ class Bundler::Thor
#
def parse_array(name)
return shift if peek.is_a?(Array)
-
array = []
-
- while current_is_value?
- value = shift
-
- if !value.empty?
- validate_enum_value!(name, value, "Expected all values of '%s' to be one of %s; got %s")
- end
-
- array << value
- end
+ array << shift while current_is_value?
array
end
@@ -144,9 +138,11 @@ class Bundler::Thor
end
value = $&.index(".") ? shift.to_f : shift.to_i
-
- validate_enum_value!(name, value, "Expected '%s' to be one of %s; got %s")
-
+ if @switches.is_a?(Hash) && switch = @switches[name]
+ if switch.enum && !switch.enum.include?(value)
+ raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
+ end
+ end
value
end
@@ -160,27 +156,15 @@ class Bundler::Thor
nil
else
value = shift
-
- validate_enum_value!(name, value, "Expected '%s' to be one of %s; got %s")
-
+ if @switches.is_a?(Hash) && switch = @switches[name]
+ if switch.enum && !switch.enum.include?(value)
+ raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
+ end
+ end
value
end
end
- # Raises an error if the switch is an enum and the values aren't included on it.
- #
- def validate_enum_value!(name, value, message)
- return unless @switches.is_a?(Hash)
-
- switch = @switches[name]
-
- return unless switch
-
- if switch.enum && !switch.enum.include?(value)
- raise MalformattedArgumentError, message % [name, switch.enum_to_s, value]
- end
- end
-
# Raises an error if @non_assigned_required array is not empty.
#
def check_requirement!
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/option.rb b/lib/bundler/vendor/thor/lib/thor/parser/option.rb
index c6af4e1e87..5a5af6f888 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/option.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/option.rb
@@ -11,7 +11,7 @@ class Bundler::Thor
super
@lazy_default = options[:lazy_default]
@group = options[:group].to_s.capitalize if options[:group]
- @aliases = normalize_aliases(options[:aliases])
+ @aliases = Array(options[:aliases])
@hide = options[:hide]
end
@@ -58,7 +58,7 @@ class Bundler::Thor
default = nil
if VALID_TYPES.include?(value)
value
- elsif required = (value == :required) # rubocop:disable Lint/AssignmentInCondition
+ elsif required = (value == :required) # rubocop:disable AssignmentInCondition
:string
end
when TrueClass, FalseClass
@@ -69,7 +69,7 @@ class Bundler::Thor
value.class.name.downcase.to_sym
end
- new(name.to_s, required: required, type: type, default: default, aliases: aliases)
+ new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
end
def switch_name
@@ -90,26 +90,13 @@ class Bundler::Thor
sample = "[#{sample}]".dup unless required?
if boolean?
- sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.match(/\Ano[\-_]/)
+ sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
end
- aliases_for_usage.ljust(padding) + sample
- end
-
- def aliases_for_usage
if aliases.empty?
- ""
- else
- "#{aliases.join(', ')}, "
- end
- end
-
- def show_default?
- case default
- when TrueClass, FalseClass
- true
+ (" " * padding) << sample
else
- super
+ "#{aliases.join(', ')}, #{sample}"
end
end
@@ -151,8 +138,8 @@ class Bundler::Thor
raise ArgumentError, err
elsif @check_default_type == nil
Bundler::Thor.deprecation_warning "#{err}.\n" +
- "This will be rejected in the future unless you explicitly pass the options `check_default_type: false`" +
- " or call `allow_incompatible_default_type!` in your code"
+ 'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' +
+ ' or call `allow_incompatible_default_type!` in your code'
end
end
end
@@ -168,11 +155,5 @@ class Bundler::Thor
def dasherize(str)
(str.length > 1 ? "--" : "-") + str.tr("_", "-")
end
-
- private
-
- def normalize_aliases(aliases)
- Array(aliases).map { |short| short.to_s.sub(/^(?!\-)/, "-") }
- end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
index 978e76b132..5bd97aba6f 100644
--- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb
+++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb
@@ -1,5 +1,5 @@
class Bundler::Thor
- class Options < Arguments #:nodoc:
+ class Options < Arguments #:nodoc: # rubocop:disable ClassLength
LONG_RE = /^(--\w+(?:-\w+)*)$/
SHORT_RE = /^(-[a-z])$/i
EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
@@ -29,10 +29,8 @@ class Bundler::Thor
#
# If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
# an unknown option or a regular argument.
- def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false, relations = {})
+ def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false)
@stop_on_unknown = stop_on_unknown
- @exclusives = (relations[:exclusive_option_names] || []).select{|array| !array.empty?}
- @at_least_ones = (relations[:at_least_one_option_names] || []).select{|array| !array.empty?}
@disable_required_check = disable_required_check
options = hash_options.values
super(options)
@@ -52,7 +50,8 @@ class Bundler::Thor
options.each do |option|
@switches[option.switch_name] = option
- option.aliases.each do |name|
+ option.aliases.each do |short|
+ name = short.to_s.sub(/^(?!\-)/, "-")
@shorts[name] ||= option.switch_name
end
end
@@ -86,7 +85,7 @@ class Bundler::Thor
super(arg)
end
- def parse(args) # rubocop:disable Metrics/MethodLength
+ def parse(args) # rubocop:disable MethodLength
@pile = args.dup
@is_treated_as_value = false
@parsing_options = true
@@ -133,38 +132,12 @@ class Bundler::Thor
end
check_requirement! unless @disable_required_check
- check_exclusive!
- check_at_least_one!
assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
assigns.freeze
assigns
end
- def check_exclusive!
- opts = @assigns.keys
- # When option A and B are exclusive, if A and B are given at the same time,
- # the diffrence of argument array size will decrease.
- found = @exclusives.find{ |ex| (ex - opts).size < ex.size - 1 }
- if found
- names = names_to_switch_names(found & opts).map{|n| "'#{n}'"}
- class_name = self.class.name.split("::").last.downcase
- fail ExclusiveArgumentError, "Found exclusive #{class_name} #{names.join(", ")}"
- end
- end
-
- def check_at_least_one!
- opts = @assigns.keys
- # When at least one is required of the options A and B,
- # if the both options were not given, none? would be true.
- found = @at_least_ones.find{ |one_reqs| one_reqs.none?{ |o| opts.include? o} }
- if found
- names = names_to_switch_names(found).map{|n| "'#{n}'"}
- class_name = self.class.name.split("::").last.downcase
- fail AtLeastOneRequiredArgumentError, "Not found at least one of required #{class_name} #{names.join(", ")}"
- end
- end
-
def check_unknown!
to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
@@ -175,17 +148,6 @@ class Bundler::Thor
protected
- # Option names changes to swith name or human name
- def names_to_switch_names(names = [])
- @switches.map do |_, o|
- if names.include? o.name
- o.respond_to?(:switch_name) ? o.switch_name : o.human_name
- else
- nil
- end
- end.compact
- end
-
def assign_result!(option, result)
if option.repeatable && option.type == :hash
(@assigns[option.human_name] ||= {}).merge!(result)
@@ -232,7 +194,7 @@ class Bundler::Thor
end
def switch_option(arg)
- if match = no_or_skip?(arg) # rubocop:disable Lint/AssignmentInCondition
+ if match = no_or_skip?(arg) # rubocop:disable AssignmentInCondition
@switches[arg] || @switches["--#{match}"]
else
@switches[arg]
diff --git a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
index c6a4653fc1..f8f86372cc 100644
--- a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
+++ b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb
@@ -41,7 +41,7 @@ instance_eval do
def task(*)
task = super
- if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable Lint/AssignmentInCondition
+ if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
non_namespaced_name = task.name.split(":").last
description = non_namespaced_name
@@ -59,7 +59,7 @@ instance_eval do
end
def namespace(name)
- if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable Lint/AssignmentInCondition
+ if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
const_name = Bundler::Thor::Util.camel_case(name.to_s).to_sym
klass.const_set(const_name, Class.new(Bundler::Thor))
new_klass = klass.const_get(const_name)
diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb
index c7cc873131..54c5525093 100644
--- a/lib/bundler/vendor/thor/lib/thor/runner.rb
+++ b/lib/bundler/vendor/thor/lib/thor/runner.rb
@@ -2,10 +2,12 @@ require_relative "../thor"
require_relative "group"
require "yaml"
-require "digest/sha2"
+require "digest/md5"
require "pathname"
-class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
+class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
+ autoload :OpenURI, "open-uri"
+
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
def self.banner(command, all = false, subcommand = false)
@@ -23,7 +25,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
initialize_thorfiles(meth)
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
self.class.handle_no_command_error(command, false) if klass.nil?
- klass.start(["-h", command].compact, shell: shell)
+ klass.start(["-h", command].compact, :shell => shell)
else
super
end
@@ -38,42 +40,30 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
self.class.handle_no_command_error(command, false) if klass.nil?
args.unshift(command) if command
- klass.start(args, shell: shell)
+ klass.start(args, :shell => shell)
end
desc "install NAME", "Install an optionally named Bundler::Thor file into your system commands"
- method_options as: :string, relative: :boolean, force: :boolean
- def install(name) # rubocop:disable Metrics/MethodLength
+ method_options :as => :string, :relative => :boolean, :force => :boolean
+ def install(name) # rubocop:disable MethodLength
initialize_thorfiles
- is_uri = name =~ %r{^https?\://}
-
- if is_uri
- base = name
- package = :file
- require "open-uri"
- begin
- contents = URI.open(name, &:read)
- rescue OpenURI::HTTPError
- raise Error, "Error opening URI '#{name}'"
- end
- else
- # If a directory name is provided as the argument, look for a 'main.thor'
- # command in said directory.
- begin
- if File.directory?(File.expand_path(name))
- base = File.join(name, "main.thor")
- package = :directory
- contents = File.open(base, &:read)
- else
- base = name
- package = :file
- require "open-uri"
- contents = URI.open(name, &:read)
- end
- rescue Errno::ENOENT
- raise Error, "Error opening file '#{name}'"
+ # If a directory name is provided as the argument, look for a 'main.thor'
+ # command in said directory.
+ begin
+ if File.directory?(File.expand_path(name))
+ base = File.join(name, "main.thor")
+ package = :directory
+ contents = open(base, &:read)
+ else
+ base = name
+ package = :file
+ contents = open(name, &:read)
end
+ rescue OpenURI::HTTPError
+ raise Error, "Error opening URI '#{name}'"
+ rescue Errno::ENOENT
+ raise Error, "Error opening file '#{name}'"
end
say "Your Thorfile contains:"
@@ -94,16 +84,16 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
as = basename if as.empty?
end
- location = if options[:relative] || is_uri
+ location = if options[:relative] || name =~ %r{^https?://}
name
else
File.expand_path(name)
end
thor_yaml[as] = {
- filename: Digest::SHA256.hexdigest(name + as),
- location: location,
- namespaces: Bundler::Thor::Util.namespaces_in_content(contents, base)
+ :filename => Digest::MD5.hexdigest(name + as),
+ :location => location,
+ :namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base)
}
save_yaml(thor_yaml)
@@ -164,14 +154,14 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
end
desc "installed", "List the installed Bundler::Thor modules and commands"
- method_options internal: :boolean
+ method_options :internal => :boolean
def installed
initialize_thorfiles(nil, true)
display_klasses(true, options["internal"])
end
desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)"
- method_options substring: :boolean, group: :string, all: :boolean, debug: :boolean
+ method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
def list(search = "")
initialize_thorfiles
@@ -313,7 +303,7 @@ private
say shell.set_color(namespace, :blue, true)
say "-" * namespace.size
- print_table(list, truncate: true)
+ print_table(list, :truncate => true)
say
end
alias_method :display_tasks, :display_commands
diff --git a/lib/bundler/vendor/thor/lib/thor/shell.rb b/lib/bundler/vendor/thor/lib/thor/shell.rb
index 265f3ba046..a4137d1bde 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell.rb
@@ -75,7 +75,7 @@ class Bundler::Thor
# Allow shell to be shared between invocations.
#
def _shared_configuration #:nodoc:
- super.merge!(shell: shell)
+ super.merge!(:shell => shell)
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
index dc3179e5f3..ef97d52ae7 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
@@ -1,10 +1,8 @@
-require_relative "column_printer"
-require_relative "table_printer"
-require_relative "wrapped_printer"
-
class Bundler::Thor
module Shell
class Basic
+ DEFAULT_TERMINAL_WIDTH = 80
+
attr_accessor :base
attr_reader :padding
@@ -147,14 +145,14 @@ class Bundler::Thor
# "yes".
#
def yes?(statement, color = nil)
- !!(ask(statement, color, add_to_history: false) =~ is?(:yes))
+ !!(ask(statement, color, :add_to_history => false) =~ is?(:yes))
end
# Make a question the to user and returns true if the user replies "n" or
# "no".
#
def no?(statement, color = nil)
- !!(ask(statement, color, add_to_history: false) =~ is?(:no))
+ !!(ask(statement, color, :add_to_history => false) =~ is?(:no))
end
# Prints values in columns
@@ -163,8 +161,16 @@ class Bundler::Thor
# Array[String, String, ...]
#
def print_in_columns(array)
- printer = ColumnPrinter.new(stdout)
- printer.print(array)
+ return if array.empty?
+ colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
+ array.each_with_index do |value, index|
+ # Don't output trailing spaces when printing the last column
+ if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
+ stdout.puts value
+ else
+ stdout.printf("%-#{colwidth}s", value)
+ end
+ end
end
# Prints a table.
@@ -175,11 +181,58 @@ class Bundler::Thor
# ==== Options
# indent<Integer>:: Indent the first column by indent value.
# colwidth<Integer>:: Force the first column to colwidth spaces wide.
- # borders<Boolean>:: Adds ascii borders.
#
- def print_table(array, options = {}) # rubocop:disable Metrics/MethodLength
- printer = TablePrinter.new(stdout, options)
- printer.print(array)
+ def print_table(array, options = {}) # rubocop:disable MethodLength
+ return if array.empty?
+
+ formats = []
+ indent = options[:indent].to_i
+ colwidth = options[:colwidth]
+ options[:truncate] = terminal_width if options[:truncate] == true
+
+ formats << "%-#{colwidth + 2}s".dup if colwidth
+ start = colwidth ? 1 : 0
+
+ colcount = array.max { |a, b| a.size <=> b.size }.size
+
+ maximas = []
+
+ start.upto(colcount - 1) do |index|
+ maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
+ maximas << maxima
+ formats << if index == colcount - 1
+ # Don't output 2 trailing spaces when printing the last column
+ "%-s".dup
+ else
+ "%-#{maxima + 2}s".dup
+ end
+ end
+
+ formats[0] = formats[0].insert(0, " " * indent)
+ formats << "%s"
+
+ array.each do |row|
+ sentence = "".dup
+
+ row.each_with_index do |column, index|
+ maxima = maximas[index]
+
+ f = if column.is_a?(Numeric)
+ if index == row.size - 1
+ # Don't output 2 trailing spaces when printing the last column
+ "%#{maxima}s"
+ else
+ "%#{maxima}s "
+ end
+ else
+ formats[index]
+ end
+ sentence << f % column.to_s
+ end
+
+ sentence = truncate(sentence, options[:truncate]) if options[:truncate]
+ stdout.puts sentence
+ end
end
# Prints a long string, word-wrapping the text to the current width of the
@@ -192,8 +245,33 @@ class Bundler::Thor
# indent<Integer>:: Indent each line of the printed paragraph by indent value.
#
def print_wrapped(message, options = {})
- printer = WrappedPrinter.new(stdout, options)
- printer.print(message)
+ indent = options[:indent] || 0
+ width = terminal_width - indent
+ paras = message.split("\n\n")
+
+ paras.map! do |unwrapped|
+ words = unwrapped.split(" ")
+ counter = words.first.length
+ words.inject do |memo, word|
+ word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
+ counter = 0 if word.include? "\n"
+ if (counter + word.length + 1) < width
+ memo = "#{memo} #{word}"
+ counter += (word.length + 1)
+ else
+ memo = "#{memo}\n#{word}"
+ counter = word.length
+ end
+ memo
+ end
+ end.compact!
+
+ paras.each do |para|
+ para.split("\n").each do |line|
+ stdout.puts line.insert(0, " " * indent)
+ end
+ stdout.puts unless para == paras.last
+ end
end
# Deals with file collision and returns true if the file should be
@@ -211,7 +289,7 @@ class Bundler::Thor
loop do
answer = ask(
%[Overwrite #{destination}? (enter "h" for help) #{options}],
- add_to_history: false
+ :add_to_history => false
)
case answer
@@ -238,11 +316,24 @@ class Bundler::Thor
say "Please specify merge tool to `THOR_MERGE` env."
else
- say file_collision_help(block_given?)
+ say file_collision_help
end
end
end
+ # This code was copied from Rake, available under MIT-LICENSE
+ # Copyright (c) 2003, 2004 Jim Weirich
+ def terminal_width
+ result = if ENV["THOR_COLUMNS"]
+ ENV["THOR_COLUMNS"].to_i
+ else
+ unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
+ end
+ result < 10 ? DEFAULT_TERMINAL_WIDTH : result
+ rescue
+ DEFAULT_TERMINAL_WIDTH
+ end
+
# Called if something goes wrong during the execution. This is used by Bundler::Thor
# internally and should not be used inside your scripts. If something went
# wrong, you can always raise an exception. If you raise a Bundler::Thor::Error, it
@@ -293,21 +384,16 @@ class Bundler::Thor
end
end
- def file_collision_help(block_given) #:nodoc:
- help = <<-HELP
+ def file_collision_help #:nodoc:
+ <<-HELP
Y - yes, overwrite
n - no, do not overwrite
a - all, overwrite this and all others
q - quit, abort
- h - help, show this help
- HELP
- if block_given
- help << <<-HELP
d - diff, show the differences between the old and the new
+ h - help, show this help
m - merge, run merge tool
- HELP
- end
- help
+ HELP
end
def show_diff(destination, content) #:nodoc:
@@ -325,8 +411,46 @@ class Bundler::Thor
mute? || (base && base.options[:quiet])
end
+ # Calculate the dynamic width of the terminal
+ def dynamic_width
+ @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
+ end
+
+ def dynamic_width_stty
+ `stty size 2>/dev/null`.split[1].to_i
+ end
+
+ def dynamic_width_tput
+ `tput cols 2>/dev/null`.to_i
+ end
+
def unix?
- Terminal.unix?
+ RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris)/i
+ end
+
+ def truncate(string, width)
+ as_unicode do
+ chars = string.chars.to_a
+ if chars.length <= width
+ chars.join
+ else
+ chars[0, width - 3].join + "..."
+ end
+ end
+ end
+
+ if "".respond_to?(:encode)
+ def as_unicode
+ yield
+ end
+ else
+ def as_unicode
+ old = $KCODE
+ $KCODE = "U"
+ yield
+ ensure
+ $KCODE = old
+ end
end
def ask_simply(statement, color, options)
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/color.rb b/lib/bundler/vendor/thor/lib/thor/shell/color.rb
index 5d708fadca..dc167ed3cc 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/color.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/color.rb
@@ -105,7 +105,52 @@ class Bundler::Thor
end
def are_colors_disabled?
- !ENV["NO_COLOR"].nil? && !ENV["NO_COLOR"].empty?
+ !ENV['NO_COLOR'].nil?
+ end
+
+ # Overwrite show_diff to show diff with colors if Diff::LCS is
+ # available.
+ #
+ def show_diff(destination, content) #:nodoc:
+ if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
+ actual = File.binread(destination).to_s.split("\n")
+ content = content.to_s.split("\n")
+
+ Diff::LCS.sdiff(actual, content).each do |diff|
+ output_diff_line(diff)
+ end
+ else
+ super
+ end
+ end
+
+ def output_diff_line(diff) #:nodoc:
+ case diff.action
+ when "-"
+ say "- #{diff.old_element.chomp}", :red, true
+ when "+"
+ say "+ #{diff.new_element.chomp}", :green, true
+ when "!"
+ say "- #{diff.old_element.chomp}", :red, true
+ say "+ #{diff.new_element.chomp}", :green, true
+ else
+ say " #{diff.old_element.chomp}", nil, true
+ end
+ end
+
+ # Check if Diff::LCS is loaded. If it is, use it to create pretty output
+ # for diff.
+ #
+ def diff_lcs_loaded? #:nodoc:
+ return true if defined?(Diff::LCS)
+ return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
+
+ @diff_lcs_loaded = begin
+ require "diff/lcs"
+ true
+ rescue LoadError
+ false
+ end
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb b/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb
deleted file mode 100644
index 56a9e6181b..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require_relative "terminal"
-
-class Bundler::Thor
- module Shell
- class ColumnPrinter
- attr_reader :stdout, :options
-
- def initialize(stdout, options = {})
- @stdout = stdout
- @options = options
- @indent = options[:indent].to_i
- end
-
- def print(array)
- return if array.empty?
- colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
- array.each_with_index do |value, index|
- # Don't output trailing spaces when printing the last column
- if ((((index + 1) % (Terminal.terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
- stdout.puts value
- else
- stdout.printf("%-#{colwidth}s", value)
- end
- end
- end
- end
- end
-end
-
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/html.rb b/lib/bundler/vendor/thor/lib/thor/shell/html.rb
index 0277b882b7..77a6d13a23 100644
--- a/lib/bundler/vendor/thor/lib/thor/shell/html.rb
+++ b/lib/bundler/vendor/thor/lib/thor/shell/html.rb
@@ -76,6 +76,51 @@ class Bundler::Thor
def can_display_colors?
true
end
+
+ # Overwrite show_diff to show diff with colors if Diff::LCS is
+ # available.
+ #
+ def show_diff(destination, content) #:nodoc:
+ if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
+ actual = File.binread(destination).to_s.split("\n")
+ content = content.to_s.split("\n")
+
+ Diff::LCS.sdiff(actual, content).each do |diff|
+ output_diff_line(diff)
+ end
+ else
+ super
+ end
+ end
+
+ def output_diff_line(diff) #:nodoc:
+ case diff.action
+ when "-"
+ say "- #{diff.old_element.chomp}", :red, true
+ when "+"
+ say "+ #{diff.new_element.chomp}", :green, true
+ when "!"
+ say "- #{diff.old_element.chomp}", :red, true
+ say "+ #{diff.new_element.chomp}", :green, true
+ else
+ say " #{diff.old_element.chomp}", nil, true
+ end
+ end
+
+ # Check if Diff::LCS is loaded. If it is, use it to create pretty output
+ # for diff.
+ #
+ def diff_lcs_loaded? #:nodoc:
+ return true if defined?(Diff::LCS)
+ return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
+
+ @diff_lcs_loaded = begin
+ require "diff/lcs"
+ true
+ rescue LoadError
+ false
+ end
+ end
end
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb b/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb
deleted file mode 100644
index 525f9ce5bb..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb
+++ /dev/null
@@ -1,134 +0,0 @@
-require_relative "column_printer"
-require_relative "terminal"
-
-class Bundler::Thor
- module Shell
- class TablePrinter < ColumnPrinter
- BORDER_SEPARATOR = :separator
-
- def initialize(stdout, options = {})
- super
- @formats = []
- @maximas = []
- @colwidth = options[:colwidth]
- @truncate = options[:truncate] == true ? Terminal.terminal_width : options[:truncate]
- @padding = 1
- end
-
- def print(array)
- return if array.empty?
-
- prepare(array)
-
- print_border_separator if options[:borders]
-
- array.each do |row|
- if options[:borders] && row == BORDER_SEPARATOR
- print_border_separator
- next
- end
-
- sentence = "".dup
-
- row.each_with_index do |column, index|
- sentence << format_cell(column, row.size, index)
- end
-
- sentence = truncate(sentence)
- sentence << "|" if options[:borders]
- stdout.puts indentation + sentence
-
- end
- print_border_separator if options[:borders]
- end
-
- private
-
- def prepare(array)
- array = array.reject{|row| row == BORDER_SEPARATOR }
-
- @formats << "%-#{@colwidth + 2}s".dup if @colwidth
- start = @colwidth ? 1 : 0
-
- colcount = array.max { |a, b| a.size <=> b.size }.size
-
- start.upto(colcount - 1) do |index|
- maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
-
- @maximas << maxima
- @formats << if options[:borders]
- "%-#{maxima}s".dup
- elsif index == colcount - 1
- # Don't output 2 trailing spaces when printing the last column
- "%-s".dup
- else
- "%-#{maxima + 2}s".dup
- end
- end
-
- @formats << "%s"
- end
-
- def format_cell(column, row_size, index)
- maxima = @maximas[index]
-
- f = if column.is_a?(Numeric)
- if options[:borders]
- # With borders we handle padding separately
- "%#{maxima}s"
- elsif index == row_size - 1
- # Don't output 2 trailing spaces when printing the last column
- "%#{maxima}s"
- else
- "%#{maxima}s "
- end
- else
- @formats[index]
- end
-
- cell = "".dup
- cell << "|" + " " * @padding if options[:borders]
- cell << f % column.to_s
- cell << " " * @padding if options[:borders]
- cell
- end
-
- def print_border_separator
- separator = @maximas.map do |maxima|
- "+" + "-" * (maxima + 2 * @padding)
- end
- stdout.puts indentation + separator.join + "+"
- end
-
- def truncate(string)
- return string unless @truncate
- as_unicode do
- chars = string.chars.to_a
- if chars.length <= @truncate
- chars.join
- else
- chars[0, @truncate - 3 - @indent].join + "..."
- end
- end
- end
-
- def indentation
- " " * @indent
- end
-
- if "".respond_to?(:encode)
- def as_unicode
- yield
- end
- else
- def as_unicode
- old = $KCODE # rubocop:disable Style/GlobalVars
- $KCODE = "U" # rubocop:disable Style/GlobalVars
- yield
- ensure
- $KCODE = old # rubocop:disable Style/GlobalVars
- end
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb b/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb
deleted file mode 100644
index 2c60684308..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-class Bundler::Thor
- module Shell
- module Terminal
- DEFAULT_TERMINAL_WIDTH = 80
-
- class << self
- # This code was copied from Rake, available under MIT-LICENSE
- # Copyright (c) 2003, 2004 Jim Weirich
- def terminal_width
- result = if ENV["THOR_COLUMNS"]
- ENV["THOR_COLUMNS"].to_i
- else
- unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
- end
- result < 10 ? DEFAULT_TERMINAL_WIDTH : result
- rescue
- DEFAULT_TERMINAL_WIDTH
- end
-
- def unix?
- RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris)/i
- end
-
- private
-
- # Calculate the dynamic width of the terminal
- def dynamic_width
- @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
- end
-
- def dynamic_width_stty
- `stty size 2>/dev/null`.split[1].to_i
- end
-
- def dynamic_width_tput
- `tput cols 2>/dev/null`.to_i
- end
-
- end
- end
- end
-end
diff --git a/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb b/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb
deleted file mode 100644
index ba88e952db..0000000000
--- a/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require_relative "column_printer"
-require_relative "terminal"
-
-class Bundler::Thor
- module Shell
- class WrappedPrinter < ColumnPrinter
- def print(message)
- width = Terminal.terminal_width - @indent
- paras = message.split("\n\n")
-
- paras.map! do |unwrapped|
- words = unwrapped.split(" ")
- counter = words.first.length
- words.inject do |memo, word|
- word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
- counter = 0 if word.include? "\n"
- if (counter + word.length + 1) < width
- memo = "#{memo} #{word}"
- counter += (word.length + 1)
- else
- memo = "#{memo}\n#{word}"
- counter = word.length
- end
- memo
- end
- end.compact!
-
- paras.each do |para|
- para.split("\n").each do |line|
- stdout.puts line.insert(0, " " * @indent)
- end
- stdout.puts unless para == paras.last
- end
- end
- end
- end
-end
-
diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb
index 68916daf2e..d2572a4249 100644
--- a/lib/bundler/vendor/thor/lib/thor/util.rb
+++ b/lib/bundler/vendor/thor/lib/thor/util.rb
@@ -90,7 +90,7 @@ class Bundler::Thor
def snake_case(str)
return str.downcase if str =~ /^[A-Z_]+$/
str.gsub(/\B[A-Z]/, '_\&').squeeze("_") =~ /_*(.*)/
- Regexp.last_match(-1).downcase
+ $+.downcase
end
# Receives a string and convert it to camel case. camel_case returns CamelCase.
@@ -130,10 +130,9 @@ class Bundler::Thor
#
def find_class_and_command_by_namespace(namespace, fallback = true)
if namespace.include?(":") # look for a namespaced command
- *pieces, command = namespace.split(":")
- namespace = pieces.join(":")
- namespace = "default" if namespace.empty?
- klass = Bundler::Thor::Base.subclasses.detect { |thor| thor.namespace == namespace && thor.commands.keys.include?(command) }
+ pieces = namespace.split(":")
+ command = pieces.pop
+ klass = Bundler::Thor::Util.find_by_namespace(pieces.join(":"))
end
unless klass # look for a Bundler::Thor::Group with the right name
klass = Bundler::Thor::Util.find_by_namespace(namespace)
@@ -151,7 +150,7 @@ class Bundler::Thor
# inside the sandbox to avoid namespacing conflicts.
#
def load_thorfile(path, content = nil, debug = false)
- content ||= File.read(path)
+ content ||= File.binread(path)
begin
Bundler::Thor::Sandbox.class_eval(content, path)
@@ -190,7 +189,7 @@ class Bundler::Thor
# Returns the root where thor files are located, depending on the OS.
#
def thor_root
- File.join(user_home, ".thor").tr("\\", "/")
+ File.join(user_home, ".thor").tr('\\', "/")
end
# Returns the files in the thor root. On Windows thor_root will be something
@@ -237,7 +236,7 @@ class Bundler::Thor
# symlink points to 'ruby_install_name'
ruby = alternate_ruby if linked_ruby == ruby_name || linked_ruby == ruby
end
- rescue NotImplementedError # rubocop:disable Lint/HandleExceptions
+ rescue NotImplementedError # rubocop:disable HandleExceptions
# just ignore on windows
end
end
diff --git a/lib/bundler/vendor/thor/lib/thor/version.rb b/lib/bundler/vendor/thor/lib/thor/version.rb
index 1fb00017ed..48a4788b3b 100644
--- a/lib/bundler/vendor/thor/lib/thor/version.rb
+++ b/lib/bundler/vendor/thor/lib/thor/version.rb
@@ -1,3 +1,3 @@
class Bundler::Thor
- VERSION = "1.3.0"
+ VERSION = "1.2.1"
end
diff --git a/lib/bundler/vendor/tsort/.document b/lib/bundler/vendor/tsort/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/bundler/vendor/tsort/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/bundler/vendor/tsort/lib/tsort.rb b/lib/bundler/vendor/tsort/lib/tsort.rb
index cf8731f760..4a0e1a4e25 100644
--- a/lib/bundler/vendor/tsort/lib/tsort.rb
+++ b/lib/bundler/vendor/tsort/lib/tsort.rb
@@ -122,9 +122,6 @@
#
module Bundler::TSort
-
- VERSION = "0.2.0"
-
class Cyclic < StandardError
end
diff --git a/lib/bundler/vendor/uri/.document b/lib/bundler/vendor/uri/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/bundler/vendor/uri/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/bundler/vendor/uri/lib/uri/common.rb b/lib/bundler/vendor/uri/lib/uri/common.rb
index 93f4f226ad..914a4c7581 100644
--- a/lib/bundler/vendor/uri/lib/uri/common.rb
+++ b/lib/bundler/vendor/uri/lib/uri/common.rb
@@ -68,32 +68,16 @@ module Bundler::URI
end
private_constant :Schemes
- # Registers the given +klass+ as the class to be instantiated
- # when parsing a \Bundler::URI with the given +scheme+:
#
- # Bundler::URI.register_scheme('MS_SEARCH', Bundler::URI::Generic) # => Bundler::URI::Generic
- # Bundler::URI.scheme_list['MS_SEARCH'] # => Bundler::URI::Generic
+ # Register the given +klass+ to be instantiated when parsing URLs with the given +scheme+.
+ # Note that currently only schemes which after .upcase are valid constant names
+ # can be registered (no -/+/. allowed).
#
- # Note that after calling String#upcase on +scheme+, it must be a valid
- # constant name.
def self.register_scheme(scheme, klass)
Schemes.const_set(scheme.to_s.upcase, klass)
end
- # Returns a hash of the defined schemes:
- #
- # Bundler::URI.scheme_list
- # # =>
- # {"MAILTO"=>Bundler::URI::MailTo,
- # "LDAPS"=>Bundler::URI::LDAPS,
- # "WS"=>Bundler::URI::WS,
- # "HTTP"=>Bundler::URI::HTTP,
- # "HTTPS"=>Bundler::URI::HTTPS,
- # "LDAP"=>Bundler::URI::LDAP,
- # "FILE"=>Bundler::URI::File,
- # "FTP"=>Bundler::URI::FTP}
- #
- # Related: Bundler::URI.register_scheme.
+ # Returns a Hash of the defined schemes.
def self.scheme_list
Schemes.constants.map { |name|
[name.to_s.upcase, Schemes.const_get(name)]
@@ -104,21 +88,9 @@ module Bundler::URI
private_constant :INITIAL_SCHEMES
Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
- # Returns a new object constructed from the given +scheme+, +arguments+,
- # and +default+:
- #
- # - The new object is an instance of <tt>Bundler::URI.scheme_list[scheme.upcase]</tt>.
- # - The object is initialized by calling the class initializer
- # using +scheme+ and +arguments+.
- # See Bundler::URI::Generic.new.
- #
- # Examples:
#
- # values = ['john.doe', 'www.example.com', '123', nil, '/forum/questions/', nil, 'tag=networking&order=newest', 'top']
- # Bundler::URI.for('https', *values)
- # # => #<Bundler::URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- # Bundler::URI.for('foo', *values, default: Bundler::URI::HTTP)
- # # => #<Bundler::URI::HTTP foo://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
+ # Construct a Bundler::URI instance, using the scheme to detect the appropriate class
+ # from +Bundler::URI.scheme_list+.
#
def self.for(scheme, *arguments, default: Generic)
const_name = scheme.to_s.upcase
@@ -149,49 +121,95 @@ module Bundler::URI
#
class BadURIError < Error; end
- # Returns a 9-element array representing the parts of the \Bundler::URI
- # formed from the string +uri+;
- # each array element is a string or +nil+:
- #
- # names = %w[scheme userinfo host port registry path opaque query fragment]
- # values = Bundler::URI.split('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # names.zip(values)
- # # =>
- # [["scheme", "https"],
- # ["userinfo", "john.doe"],
- # ["host", "www.example.com"],
- # ["port", "123"],
- # ["registry", nil],
- # ["path", "/forum/questions/"],
- # ["opaque", nil],
- # ["query", "tag=networking&order=newest"],
- # ["fragment", "top"]]
+ #
+ # == Synopsis
+ #
+ # Bundler::URI::split(uri)
+ #
+ # == Args
+ #
+ # +uri+::
+ # String with Bundler::URI.
+ #
+ # == Description
+ #
+ # Splits the string on following parts and returns array with result:
+ #
+ # * Scheme
+ # * Userinfo
+ # * Host
+ # * Port
+ # * Registry
+ # * Path
+ # * Opaque
+ # * Query
+ # * Fragment
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # Bundler::URI.split("http://www.ruby-lang.org/")
+ # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
#
def self.split(uri)
RFC3986_PARSER.split(uri)
end
- # Returns a new \Bundler::URI object constructed from the given string +uri+:
#
- # Bundler::URI.parse('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # # => #<Bundler::URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- # Bundler::URI.parse('http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # # => #<Bundler::URI::HTTP http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
+ # == Synopsis
+ #
+ # Bundler::URI::parse(uri_str)
+ #
+ # == Args
+ #
+ # +uri_str+::
+ # String with Bundler::URI.
+ #
+ # == Description
+ #
+ # Creates one of the Bundler::URI's subclasses instance from the string.
+ #
+ # == Raises
+ #
+ # Bundler::URI::InvalidURIError::
+ # Raised if Bundler::URI given is not a correct one.
#
- # It's recommended to first ::escape string +uri+
- # if it may contain invalid Bundler::URI characters.
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
+ #
+ # uri = Bundler::URI.parse("http://www.ruby-lang.org/")
+ # # => #<Bundler::URI::HTTP http://www.ruby-lang.org/>
+ # uri.scheme
+ # # => "http"
+ # uri.host
+ # # => "www.ruby-lang.org"
+ #
+ # It's recommended to first ::escape the provided +uri_str+ if there are any
+ # invalid Bundler::URI characters.
#
def self.parse(uri)
RFC3986_PARSER.parse(uri)
end
- # Merges the given Bundler::URI strings +str+
- # per {RFC 2396}[https://www.rfc-editor.org/rfc/rfc2396.html].
#
- # Each string in +str+ is converted to an
- # {RFC3986 Bundler::URI}[https://www.rfc-editor.org/rfc/rfc3986.html] before being merged.
+ # == Synopsis
+ #
+ # Bundler::URI::join(str[, str, ...])
#
- # Examples:
+ # == Args
+ #
+ # +str+::
+ # String(s) to work with, will be converted to RFC3986 URIs before merging.
+ #
+ # == Description
+ #
+ # Joins URIs.
+ #
+ # == Usage
+ #
+ # require 'bundler/vendor/uri/lib/uri'
#
# Bundler::URI.join("http://example.com/","main.rbx")
# # => #<Bundler::URI::HTTP http://example.com/main.rbx>
@@ -236,7 +254,7 @@ module Bundler::URI
# Bundler::URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
# # => ["http://foo.example.com/bla", "mailto:test@example.com"]
#
- def self.extract(str, schemes = nil, &block) # :nodoc:
+ def self.extract(str, schemes = nil, &block)
warn "Bundler::URI.extract is obsolete", uplevel: 1 if $VERBOSE
DEFAULT_PARSER.extract(str, schemes, &block)
end
@@ -273,7 +291,7 @@ module Bundler::URI
# p $&
# end
#
- def self.regexp(schemes = nil)# :nodoc:
+ def self.regexp(schemes = nil)
warn "Bundler::URI.regexp is obsolete", uplevel: 1 if $VERBOSE
DEFAULT_PARSER.make_regexp(schemes)
end
@@ -296,86 +314,40 @@ module Bundler::URI
TBLDECWWWCOMP_['+'] = ' '
TBLDECWWWCOMP_.freeze
- # Returns a URL-encoded string derived from the given string +str+.
- #
- # The returned string:
- #
- # - Preserves:
- #
- # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
- # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
- # and <tt>'0'..'9'</tt>.
- #
- # Example:
+ # Encodes given +str+ to URL-encoded form data.
#
- # Bundler::URI.encode_www_form_component('*.-_azAZ09')
- # # => "*.-_azAZ09"
+ # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
+ # (ASCII space) to + and converts others to %XX.
#
- # - Converts:
+ # If +enc+ is given, convert +str+ to the encoding before percent encoding.
#
- # - Character <tt>' '</tt> to character <tt>'+'</tt>.
- # - Any other character to "percent notation";
- # the percent notation for character <i>c</i> is <tt>'%%%X' % c.ord</tt>.
+ # This is an implementation of
+ # https://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data.
#
- # Example:
- #
- # Bundler::URI.encode_www_form_component('Here are some punctuation characters: ,;?:')
- # # => "Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A"
- #
- # Encoding:
- #
- # - If +str+ has encoding Encoding::ASCII_8BIT, argument +enc+ is ignored.
- # - Otherwise +str+ is converted first to Encoding::UTF_8
- # (with suitable character replacements),
- # and then to encoding +enc+.
- #
- # In either case, the returned string has forced encoding Encoding::US_ASCII.
- #
- # Related: Bundler::URI.encode_uri_component (encodes <tt>' '</tt> as <tt>'%20'</tt>).
+ # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form.
def self.encode_www_form_component(str, enc=nil)
_encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_, str, enc)
end
- # Returns a string decoded from the given \URL-encoded string +str+.
- #
- # The given string is first encoded as Encoding::ASCII-8BIT (using String#b),
- # then decoded (as below), and finally force-encoded to the given encoding +enc+.
- #
- # The returned string:
- #
- # - Preserves:
- #
- # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
- # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
- # and <tt>'0'..'9'</tt>.
- #
- # Example:
- #
- # Bundler::URI.decode_www_form_component('*.-_azAZ09')
- # # => "*.-_azAZ09"
- #
- # - Converts:
- #
- # - Character <tt>'+'</tt> to character <tt>' '</tt>.
- # - Each "percent notation" to an ASCII character.
+ # Decodes given +str+ of URL-encoded form data.
#
- # Example:
+ # This decodes + to SP.
#
- # Bundler::URI.decode_www_form_component('Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A')
- # # => "Here are some punctuation characters: ,;?:"
- #
- # Related: Bundler::URI.decode_uri_component (preserves <tt>'+'</tt>).
+ # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form.
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
_decode_uri_component(/\+|%\h\h/, str, enc)
end
- # Like Bundler::URI.encode_www_form_component, except that <tt>' '</tt> (space)
- # is encoded as <tt>'%20'</tt> (instead of <tt>'+'</tt>).
+ # Encodes +str+ using URL encoding
+ #
+ # This encodes SP to %20 instead of +.
def self.encode_uri_component(str, enc=nil)
_encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCURICOMP_, str, enc)
end
- # Like Bundler::URI.decode_www_form_component, except that <tt>'+'</tt> is preserved.
+ # Decodes given +str+ of URL-encoded data.
+ #
+ # This does not decode + to SP.
def self.decode_uri_component(str, enc=Encoding::UTF_8)
_decode_uri_component(/%\h\h/, str, enc)
end
@@ -400,104 +372,33 @@ module Bundler::URI
end
private_class_method :_decode_uri_component
- # Returns a URL-encoded string derived from the given
- # {Enumerable}[rdoc-ref:Enumerable@Enumerable+in+Ruby+Classes]
- # +enum+.
- #
- # The result is suitable for use as form data
- # for an \HTTP request whose <tt>Content-Type</tt> is
- # <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The returned string consists of the elements of +enum+,
- # each converted to one or more URL-encoded strings,
- # and all joined with character <tt>'&'</tt>.
- #
- # Simple examples:
- #
- # Bundler::URI.encode_www_form([['foo', 0], ['bar', 1], ['baz', 2]])
- # # => "foo=0&bar=1&baz=2"
- # Bundler::URI.encode_www_form({foo: 0, bar: 1, baz: 2})
- # # => "foo=0&bar=1&baz=2"
- #
- # The returned string is formed using method Bundler::URI.encode_www_form_component,
- # which converts certain characters:
- #
- # Bundler::URI.encode_www_form('f#o': '/', 'b-r': '$', 'b z': '@')
- # # => "f%23o=%2F&b-r=%24&b+z=%40"
- #
- # When +enum+ is Array-like, each element +ele+ is converted to a field:
- #
- # - If +ele+ is an array of two or more elements,
- # the field is formed from its first two elements
- # (and any additional elements are ignored):
- #
- # name = Bundler::URI.encode_www_form_component(ele[0], enc)
- # value = Bundler::URI.encode_www_form_component(ele[1], enc)
- # "#{name}=#{value}"
+ # Generates URL-encoded form data from given +enum+.
#
- # Examples:
+ # This generates application/x-www-form-urlencoded data defined in HTML5
+ # from given an Enumerable object.
#
- # Bundler::URI.encode_www_form([%w[foo bar], %w[baz bat bah]])
- # # => "foo=bar&baz=bat"
- # Bundler::URI.encode_www_form([['foo', 0], ['bar', :baz, 'bat']])
- # # => "foo=0&bar=baz"
+ # This internally uses Bundler::URI.encode_www_form_component(str).
#
- # - If +ele+ is an array of one element,
- # the field is formed from <tt>ele[0]</tt>:
+ # This method doesn't convert the encoding of given items, so convert them
+ # before calling this method if you want to send data as other than original
+ # encoding or mixed encoding data. (Strings which are encoded in an HTML5
+ # ASCII incompatible encoding are converted to UTF-8.)
#
- # Bundler::URI.encode_www_form_component(ele[0])
+ # This method doesn't handle files. When you send a file, use
+ # multipart/form-data.
#
- # Example:
+ # This refers https://url.spec.whatwg.org/#concept-urlencoded-serializer
#
- # Bundler::URI.encode_www_form([['foo'], [:bar], [0]])
- # # => "foo&bar&0"
- #
- # - Otherwise the field is formed from +ele+:
- #
- # Bundler::URI.encode_www_form_component(ele)
- #
- # Example:
- #
- # Bundler::URI.encode_www_form(['foo', :bar, 0])
- # # => "foo&bar&0"
- #
- # The elements of an Array-like +enum+ may be mixture:
- #
- # Bundler::URI.encode_www_form([['foo', 0], ['bar', 1, 2], ['baz'], :bat])
- # # => "foo=0&bar=1&baz&bat"
- #
- # When +enum+ is Hash-like,
- # each +key+/+value+ pair is converted to one or more fields:
- #
- # - If +value+ is
- # {Array-convertible}[rdoc-ref:implicit_conversion.rdoc@Array-Convertible+Objects],
- # each element +ele+ in +value+ is paired with +key+ to form a field:
- #
- # name = Bundler::URI.encode_www_form_component(key, enc)
- # value = Bundler::URI.encode_www_form_component(ele, enc)
- # "#{name}=#{value}"
- #
- # Example:
- #
- # Bundler::URI.encode_www_form({foo: [:bar, 1], baz: [:bat, :bam, 2]})
- # # => "foo=bar&foo=1&baz=bat&baz=bam&baz=2"
- #
- # - Otherwise, +key+ and +value+ are paired to form a field:
- #
- # name = Bundler::URI.encode_www_form_component(key, enc)
- # value = Bundler::URI.encode_www_form_component(value, enc)
- # "#{name}=#{value}"
- #
- # Example:
- #
- # Bundler::URI.encode_www_form({foo: 0, bar: 1, baz: 2})
- # # => "foo=0&bar=1&baz=2"
- #
- # The elements of a Hash-like +enum+ may be mixture:
- #
- # Bundler::URI.encode_www_form({foo: [0, 1], bar: 2})
- # # => "foo=0&foo=1&bar=2"
+ # Bundler::URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
+ # #=> "q=ruby&lang=en"
+ # Bundler::URI.encode_www_form("q" => "ruby", "lang" => "en")
+ # #=> "q=ruby&lang=en"
+ # Bundler::URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
+ # #=> "q=ruby&q=perl&lang=en"
+ # Bundler::URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
+ # #=> "q=ruby&q=perl&lang=en"
#
+ # See Bundler::URI.encode_www_form_component, Bundler::URI.decode_www_form.
def self.encode_www_form(enum, enc=nil)
enum.map do |k,v|
if v.nil?
@@ -518,39 +419,22 @@ module Bundler::URI
end.join('&')
end
- # Returns name/value pairs derived from the given string +str+,
- # which must be an ASCII string.
- #
- # The method may be used to decode the body of Net::HTTPResponse object +res+
- # for which <tt>res['Content-Type']</tt> is <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The returned data is an array of 2-element subarrays;
- # each subarray is a name/value pair (both are strings).
- # Each returned string has encoding +enc+,
- # and has had invalid characters removed via
- # {String#scrub}[rdoc-ref:String#scrub].
+ # Decodes URL-encoded form data from given +str+.
#
- # A simple example:
+ # This decodes application/x-www-form-urlencoded data
+ # and returns an array of key-value arrays.
#
- # Bundler::URI.decode_www_form('foo=0&bar=1&baz')
- # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
+ # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser,
+ # so this supports only &-separator, and doesn't support ;-separator.
#
- # The returned strings have certain conversions,
- # similar to those performed in Bundler::URI.decode_www_form_component:
- #
- # Bundler::URI.decode_www_form('f%23o=%2F&b-r=%24&b+z=%40')
- # # => [["f#o", "/"], ["b-r", "$"], ["b z", "@"]]
- #
- # The given string may contain consecutive separators:
- #
- # Bundler::URI.decode_www_form('foo=0&&bar=1&&baz=2')
- # # => [["foo", "0"], ["", ""], ["bar", "1"], ["", ""], ["baz", "2"]]
- #
- # A different separator may be specified:
- #
- # Bundler::URI.decode_www_form('foo=0--bar=1--baz', separator: '--')
- # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
+ # ary = Bundler::URI.decode_www_form("a=1&a=2&b=3")
+ # ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
+ # ary.assoc('a').last #=> '1'
+ # ary.assoc('b').last #=> '3'
+ # ary.rassoc('a').last #=> '2'
+ # Hash[ary] #=> {"a"=>"2", "b"=>"3"}
#
+ # See Bundler::URI.decode_www_form_component, Bundler::URI.encode_www_form.
def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
ary = []
@@ -829,15 +713,7 @@ end # module Bundler::URI
module Bundler
#
- # Returns a \Bundler::URI object derived from the given +uri+,
- # which may be a \Bundler::URI string or an existing \Bundler::URI object:
- #
- # # Returns a new Bundler::URI.
- # uri = Bundler::URI('http://github.com/ruby/ruby')
- # # => #<Bundler::URI::HTTP http://github.com/ruby/ruby>
- # # Returns the given Bundler::URI.
- # Bundler::URI(uri)
- # # => #<Bundler::URI::HTTP http://github.com/ruby/ruby>
+ # Returns +uri+ converted to an Bundler::URI object.
#
def URI(uri)
if uri.is_a?(Bundler::URI::Generic)
diff --git a/lib/bundler/vendor/uri/lib/uri/generic.rb b/lib/bundler/vendor/uri/lib/uri/generic.rb
index 762c425ac1..9ae6915826 100644
--- a/lib/bundler/vendor/uri/lib/uri/generic.rb
+++ b/lib/bundler/vendor/uri/lib/uri/generic.rb
@@ -1376,7 +1376,6 @@ module Bundler::URI
end
str
end
- alias to_str to_s
#
# Compares two URIs.
diff --git a/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb b/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb
index 4c9882f595..a85511c146 100644
--- a/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb
+++ b/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb
@@ -1,73 +1,9 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
module Bundler::URI
class RFC3986_Parser # :nodoc:
# Bundler::URI defined in RFC3986
- HOST = %r[
- (?<IP-literal>\[(?:
- (?<IPv6address>
- (?:\h{1,4}:){6}
- (?<ls32>\h{1,4}:\h{1,4}
- | (?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)
- \.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>)
- )
- | ::(?:\h{1,4}:){5}\g<ls32>
- | \h{1,4}?::(?:\h{1,4}:){4}\g<ls32>
- | (?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>
- | (?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>
- | (?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>
- | (?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>
- | (?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}
- | (?:(?:\h{1,4}:){,6}\h{1,4})?::
- )
- | (?<IPvFuture>v\h++\.[!$&-.0-9:;=A-Z_a-z~]++)
- )\])
- | \g<IPv4address>
- | (?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*+)
- ]x
-
- USERINFO = /(?:%\h\h|[!$&-.0-9:;=A-Z_a-z~])*+/
-
- SCHEME = %r[[A-Za-z][+\-.0-9A-Za-z]*+].source
- SEG = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/])].source
- SEG_NC = %r[(?:%\h\h|[!$&-.0-9;=@A-Z_a-z~])].source
- FRAGMENT = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+].source
-
- RFC3986_URI = %r[\A
- (?<seg>#{SEG}){0}
- (?<Bundler::URI>
- (?<scheme>#{SCHEME}):
- (?<hier-part>//
- (?<authority>
- (?:(?<userinfo>#{USERINFO.source})@)?
- (?<host>#{HOST.source.delete(" \n")})
- (?::(?<port>\d*+))?
- )
- (?<path-abempty>(?:/\g<seg>*+)?)
- | (?<path-absolute>/((?!/)\g<seg>++)?)
- | (?<path-rootless>(?!/)\g<seg>++)
- | (?<path-empty>)
- )
- (?:\?(?<query>[^\#]*+))?
- (?:\#(?<fragment>#{FRAGMENT}))?
- )\z]x
-
- RFC3986_relative_ref = %r[\A
- (?<seg>#{SEG}){0}
- (?<relative-ref>
- (?<relative-part>//
- (?<authority>
- (?:(?<userinfo>#{USERINFO.source})@)?
- (?<host>#{HOST.source.delete(" \n")}(?<!/))?
- (?::(?<port>\d*+))?
- )
- (?<path-abempty>(?:/\g<seg>*+)?)
- | (?<path-absolute>/\g<seg>*+)
- | (?<path-noscheme>#{SEG_NC}++(?:/\g<seg>*+)?)
- | (?<path-empty>)
- )
- (?:\?(?<query>[^#]*+))?
- (?:\#(?<fragment>#{FRAGMENT}))?
- )\z]x
+ RFC3986_URI = /\A(?<Bundler::URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*+):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*+))(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
+ RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])++)(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
attr_reader :regexp
def initialize
@@ -83,9 +19,9 @@ module Bundler::URI
uri.ascii_only? or
raise InvalidURIError, "Bundler::URI must be ascii only #{uri.dump}"
if m = RFC3986_URI.match(uri)
- query = m["query"]
- scheme = m["scheme"]
- opaque = m["path-rootless"]
+ query = m["query".freeze]
+ scheme = m["scheme".freeze]
+ opaque = m["path-rootless".freeze]
if opaque
opaque << "?#{query}" if query
[ scheme,
@@ -96,35 +32,35 @@ module Bundler::URI
nil, # path
opaque,
nil, # query
- m["fragment"]
+ m["fragment".freeze]
]
else # normal
[ scheme,
- m["userinfo"],
- m["host"],
- m["port"],
+ m["userinfo".freeze],
+ m["host".freeze],
+ m["port".freeze],
nil, # registry
- (m["path-abempty"] ||
- m["path-absolute"] ||
- m["path-empty"]),
+ (m["path-abempty".freeze] ||
+ m["path-absolute".freeze] ||
+ m["path-empty".freeze]),
nil, # opaque
query,
- m["fragment"]
+ m["fragment".freeze]
]
end
elsif m = RFC3986_relative_ref.match(uri)
[ nil, # scheme
- m["userinfo"],
- m["host"],
- m["port"],
+ m["userinfo".freeze],
+ m["host".freeze],
+ m["port".freeze],
nil, # registry,
- (m["path-abempty"] ||
- m["path-absolute"] ||
- m["path-noscheme"] ||
- m["path-empty"]),
+ (m["path-abempty".freeze] ||
+ m["path-absolute".freeze] ||
+ m["path-noscheme".freeze] ||
+ m["path-empty".freeze]),
nil, # opaque
- m["query"],
- m["fragment"]
+ m["query".freeze],
+ m["fragment".freeze]
]
else
raise InvalidURIError, "bad Bundler::URI(is not Bundler::URI?): #{uri.inspect}"
@@ -156,14 +92,14 @@ module Bundler::URI
def default_regexp # :nodoc:
{
- SCHEME: %r[\A#{SCHEME}\z]o,
- USERINFO: %r[\A#{USERINFO}\z]o,
- HOST: %r[\A#{HOST}\z]o,
- ABS_PATH: %r[\A/#{SEG}*+\z]o,
- REL_PATH: %r[\A(?!/)#{SEG}++\z]o,
- QUERY: %r[\A(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+\z],
- FRAGMENT: %r[\A#{FRAGMENT}\z]o,
- OPAQUE: %r[\A(?:[^/].*)?\z],
+ SCHEME: /\A[A-Za-z][A-Za-z0-9+\-.]*\z/,
+ USERINFO: /\A(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*\z/,
+ HOST: /\A(?:(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{,4}::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))\z/,
+ ABS_PATH: /\A\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/,
+ REL_PATH: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/,
+ QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
+ FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
+ OPAQUE: /\A(?:[^\/].*)?\z/,
PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
}
end
diff --git a/lib/bundler/vendor/uri/lib/uri/version.rb b/lib/bundler/vendor/uri/lib/uri/version.rb
index 1fa1c7c09a..84b08eee30 100644
--- a/lib/bundler/vendor/uri/lib/uri/version.rb
+++ b/lib/bundler/vendor/uri/lib/uri/version.rb
@@ -1,6 +1,6 @@
module Bundler::URI
# :stopdoc:
- VERSION_CODE = '001300'.freeze
+ VERSION_CODE = '001202'.freeze
VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
# :startdoc:
end
diff --git a/lib/bundler/vendored_net_http.rb b/lib/bundler/vendored_net_http.rb
deleted file mode 100644
index 0dcabaa7d7..0000000000
--- a/lib/bundler/vendored_net_http.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-begin
- require "rubygems/vendored_net_http"
-rescue LoadError
- begin
- require "rubygems/net/http"
- rescue LoadError
- require "net/http"
- Gem::Net = Net
- end
-end
diff --git a/lib/bundler/vendored_persistent.rb b/lib/bundler/vendored_persistent.rb
index ab985c267f..e29f27cdfd 100644
--- a/lib/bundler/vendored_persistent.rb
+++ b/lib/bundler/vendored_persistent.rb
@@ -9,3 +9,7 @@ module Bundler
end
end
require_relative "vendor/net-http-persistent/lib/net/http/persistent"
+
+module Bundler
+ PersistentHTTP = Persistent::Net::HTTP::Persistent
+end
diff --git a/lib/bundler/vendored_timeout.rb b/lib/bundler/vendored_timeout.rb
deleted file mode 100644
index 9b2507c0cc..0000000000
--- a/lib/bundler/vendored_timeout.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-begin
- require "rubygems/vendored_timeout"
-rescue LoadError
- begin
- require "rubygems/timeout"
- rescue LoadError
- require "timeout"
- Gem::Timeout = Timeout
- end
-end
diff --git a/lib/bundler/vendored_uri.rb b/lib/bundler/vendored_uri.rb
index 2efddc65f9..905e8158e8 100644
--- a/lib/bundler/vendored_uri.rb
+++ b/lib/bundler/vendored_uri.rb
@@ -1,21 +1,4 @@
# frozen_string_literal: true
module Bundler; end
-
-# Use RubyGems vendored copy when available. Otherwise fallback to Bundler
-# vendored copy. The vendored copy in Bundler can be removed once support for
-# RubyGems 3.5 is dropped.
-
-begin
- require "rubygems/vendor/uri/lib/uri"
-rescue LoadError
- require_relative "vendor/uri/lib/uri"
- Gem::URI = Bundler::URI
-
- module Gem
- def URI(uri) # rubocop:disable Naming/MethodName
- Bundler::URI(uri)
- end
- module_function :URI
- end
-end
+require_relative "vendor/uri/lib/uri"
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 5a97cd658e..8ef7be935b 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.5.11".freeze
+ VERSION = "2.4.19".freeze
def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i
diff --git a/lib/bundler/vlad.rb b/lib/bundler/vlad.rb
index 6179d0e4eb..538e8c3e74 100644
--- a/lib/bundler/vlad.rb
+++ b/lib/bundler/vlad.rb
@@ -13,5 +13,5 @@ require_relative "deployment"
include Rake::DSL if defined? Rake::DSL
namespace :vlad do
- Bundler::Deployment.define_task(Rake::RemoteTask, :remote_task, roles: :app)
+ Bundler::Deployment.define_task(Rake::RemoteTask, :remote_task, :roles => :app)
end
diff --git a/lib/bundler/yaml_serializer.rb b/lib/bundler/yaml_serializer.rb
index 42e6aaf89d..d5ecbd4aef 100644
--- a/lib/bundler/yaml_serializer.rb
+++ b/lib/bundler/yaml_serializer.rb
@@ -17,11 +17,7 @@ module Bundler
if v.is_a?(Hash)
yaml << dump_hash(v).gsub(/^(?!$)/, " ") # indent all non-empty lines
elsif v.is_a?(Array) # Expected to be array of strings
- if v.empty?
- yaml << " []\n"
- else
- yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n"
- end
+ yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n"
else
yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n"
end
@@ -36,7 +32,7 @@ module Bundler
(.*) # value
\1 # matching closing quote
$
- /xo
+ /xo.freeze
HASH_REGEX = /
^
@@ -48,20 +44,18 @@ module Bundler
(.*) # value
\3 # matching closing quote
$
- /xo
+ /xo.freeze
def load(str)
res = {}
stack = [res]
last_hash = nil
last_empty_key = nil
- str.split(/\r?\n/) do |line|
+ str.split(/\r?\n/).each do |line|
if match = HASH_REGEX.match(line)
indent, key, quote, val = match.captures
- val = strip_comment(val)
-
- convert_to_backward_compatible_key!(key)
- depth = indent.size / 2
+ key = convert_to_backward_compatible_key(key)
+ depth = indent.scan(/ /).length
if quote.empty? && val.empty?
new_hash = {}
stack[depth][key] = new_hash
@@ -69,13 +63,10 @@ module Bundler
last_empty_key = key
last_hash = stack[depth]
else
- val = [] if val == "[]" # empty array
stack[depth][key] = val
end
elsif match = ARRAY_REGEX.match(line)
_, val = match.captures
- val = strip_comment(val)
-
last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array)
last_hash[last_empty_key].push(val)
@@ -84,22 +75,15 @@ module Bundler
res
end
- def strip_comment(val)
- if val.include?("#") && !val.start_with?("#")
- val.split("#", 2).first.strip
- else
- val
- end
- end
-
# for settings' keys
- def convert_to_backward_compatible_key!(key)
- key << "/" if /https?:/i.match?(key) && !%r{/\Z}.match?(key)
- key.gsub!(".", "__")
+ def convert_to_backward_compatible_key(key)
+ key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z}
+ key = key.gsub(".", "__") if key.include?(".")
+ key
end
class << self
- private :dump_hash, :convert_to_backward_compatible_key!
+ private :dump_hash, :convert_to_backward_compatible_key
end
end
end
diff --git a/lib/cgi.rb b/lib/cgi.rb
index 7af85e7fc8..7dc3a64941 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -288,7 +288,7 @@
#
class CGI
- VERSION = "0.4.1"
+ VERSION = "0.3.7"
end
require 'cgi/core'
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
index 9498e2f9fa..1c4ef6a600 100644
--- a/lib/cgi/cookie.rb
+++ b/lib/cgi/cookie.rb
@@ -190,9 +190,10 @@ class CGI
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
- values = cookies[name].value + values
+ cookies[name].concat(values)
+ else
+ cookies[name] = Cookie.new(name, *values)
end
- cookies[name] = Cookie.new(name, *values)
end
cookies
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index aab60869bb..70c7ebca42 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -279,7 +279,7 @@ class CGI
# fields are surrounded by a <fieldset> tag in HTML 4 generation, which
# is _not_ invisible on many browsers; you may wish to disable the
# use of fieldsets with code similar to the following
- # (see https://blade.ruby-lang.org/ruby-list/37805)
+ # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)
#
# cgi = CGI.new("html4")
# class << cgi
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 4986e544e0..ce77a0ccd5 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -36,7 +36,7 @@ module CGI::Util
# URL-encode a string following RFC 3986
# Space characters (+" "+) are encoded with (+"%20"+)
- # url_encoded_string = CGI.escapeURIComponent("'Stop!' said Fred")
+ # url_encoded_string = CGI.escape("'Stop!' said Fred")
# # => "%27Stop%21%27%20said%20Fred"
def escapeURIComponent(string)
encoding = string.encoding
@@ -46,10 +46,9 @@ module CGI::Util
end
buffer.force_encoding(encoding)
end
- alias escape_uri_component escapeURIComponent
# URL-decode a string following RFC 3986 with encoding(optional).
- # string = CGI.unescapeURIComponent("%27Stop%21%27+said%20Fred")
+ # string = CGI.unescape("%27Stop%21%27+said%20Fred")
# # => "'Stop!'+said Fred"
def unescapeURIComponent(string, encoding = @@accept_charset)
str = string.b
@@ -60,8 +59,6 @@ module CGI::Util
str.valid_encoding? ? str : str.force_encoding(string.encoding)
end
- alias unescape_uri_component unescapeURIComponent
-
# The set of special characters and their escaped values
TABLE_FOR_ESCAPE_HTML__ = {
"'" => '&#39;',
@@ -93,12 +90,9 @@ module CGI::Util
end
end
- # TruffleRuby runs the pure-Ruby variant faster, do not use the C extension there
- unless RUBY_ENGINE == 'truffleruby'
- begin
- require 'cgi/escape'
- rescue LoadError
- end
+ begin
+ require 'cgi/escape'
+ rescue LoadError
end
# Unescape a string that has been HTML-escaped
@@ -184,7 +178,7 @@ module CGI::Util
def escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
- string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
+ string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do
CGI.escapeHTML($&)
end
else
@@ -204,7 +198,7 @@ module CGI::Util
def unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
- string.gsub(/&lt;\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?&gt;/i) do
+ string.gsub(/&lt;\/?(?:#{elements.join("|")})\b(?>[^&]+|&(?![gl]t;)\w+;)*(?:&gt;)?/im) do
unescapeHTML($&)
end
else
diff --git a/lib/csv.rb b/lib/csv.rb
index e8aa20ddd2..0307033941 100644
--- a/lib/csv.rb
+++ b/lib/csv.rb
@@ -70,7 +70,7 @@
# == What is CSV, really?
#
# CSV maintains a pretty strict definition of CSV taken directly from
-# {the RFC}[https://www.ietf.org/rfc/rfc4180.txt]. I relax the rules in only one
+# {the RFC}[http://www.ietf.org/rfc/rfc4180.txt]. I relax the rules in only one
# place and that is to make using this library easier. CSV will parse all valid
# CSV.
#
@@ -102,6 +102,14 @@ require_relative "csv/writer"
# == \CSV
#
+# === In a Hurry?
+#
+# If you are familiar with \CSV data and have a particular task in mind,
+# you may want to go directly to the:
+# - {Recipes for CSV}[doc/csv/recipes/recipes_rdoc.html].
+#
+# Otherwise, read on here, about the API: classes, methods, and constants.
+#
# === \CSV Data
#
# \CSV (comma-separated values) data is a text representation of a table:
@@ -846,15 +854,6 @@ class CSV
end
end
- # The error thrown when the parser encounters invalid encoding in CSV.
- class InvalidEncodingError < MalformedCSVError
- attr_reader :encoding
- def initialize(encoding, line_number)
- @encoding = encoding
- super("Invalid byte sequence in #{encoding}", line_number)
- end
- end
-
#
# A FieldInfo Struct contains details about a field's position in the data
# source it was read from. CSV will pass this Struct to some blocks that make
@@ -1315,8 +1314,8 @@ class CSV
#
# Arguments:
# * Argument +path_or_io+ must be a file path or an \IO stream.
- # * Argument +mode+, if given, must be a \File mode.
- # See {Access Modes}[rdoc-ref:File@Access+Modes].
+ # * Argument +mode+, if given, must be a \File mode
+ # See {Open Mode}[https://ruby-doc.org/core/IO.html#method-c-new-label-Open+Mode].
# * Arguments <tt>**options</tt> must be keyword options.
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
# * This method optionally accepts an additional <tt>:encoding</tt> option
@@ -1522,8 +1521,8 @@ class CSV
#
# * Argument +path+, if given, must be the path to a file.
# :include: ../doc/csv/arguments/io.rdoc
- # * Argument +mode+, if given, must be a \File mode.
- # See {Access Modes}[rdoc-ref:File@Access+Modes].
+ # * Argument +mode+, if given, must be a \File mode
+ # See {Open Mode}[IO.html#method-c-new-label-Open+Mode].
# * Arguments <tt>**options</tt> must be keyword options.
# See {Options for Generating}[#class-CSV-label-Options+for+Generating].
# * This method optionally accepts an additional <tt>:encoding</tt> option
diff --git a/lib/csv/delete_suffix.rb b/lib/csv/delete_suffix.rb
new file mode 100644
index 0000000000..d457718997
--- /dev/null
+++ b/lib/csv/delete_suffix.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+# This provides String#delete_suffix? for Ruby 2.4.
+unless String.method_defined?(:delete_suffix)
+ class CSV
+ module DeleteSuffix
+ refine String do
+ def delete_suffix(suffix)
+ if end_with?(suffix)
+ self[0...-suffix.size]
+ else
+ self
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/csv/match_p.rb b/lib/csv/match_p.rb
new file mode 100644
index 0000000000..775559a3eb
--- /dev/null
+++ b/lib/csv/match_p.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# This provides String#match? and Regexp#match? for Ruby 2.3.
+unless String.method_defined?(:match?)
+ class CSV
+ module MatchP
+ refine String do
+ def match?(pattern)
+ self =~ pattern
+ end
+ end
+
+ refine Regexp do
+ def match?(string)
+ self =~ string
+ end
+ end
+ end
+ end
+end
diff --git a/lib/csv/parser.rb b/lib/csv/parser.rb
index 4da87fbac8..afb3131cd5 100644
--- a/lib/csv/parser.rb
+++ b/lib/csv/parser.rb
@@ -101,7 +101,7 @@ class CSV
position = @scanner.pos
offset = 0
n_row_separator_chars = row_separator.size
- # trace(__method__, :start, input)
+ # trace(__method__, :start, line, input)
while true
input.each_line(row_separator) do |line|
@scanner.pos += line.bytesize
@@ -157,7 +157,6 @@ class CSV
# trace(__method__, pattern, :done, :last, value) if @last_scanner
return value if @last_scanner
- # trace(__method__, pattern, :done, :nil) if value.nil?
return nil if value.nil?
while @scanner.eos? and read_chunk and (sub_value = @scanner.scan(pattern))
# trace(__method__, pattern, :sub, sub_value)
@@ -201,8 +200,7 @@ class CSV
# trace(__method__, :rescan, start, buffer)
string = @scanner.string
if scanner == @scanner
- keep = string.byteslice(start,
- string.bytesize - @scanner.pos - start)
+ keep = string.byteslice(start, string.bytesize - start)
else
keep = string
end
@@ -414,7 +412,8 @@ class CSV
else
lineno = @lineno + 1
end
- raise InvalidEncodingError.new(@encoding, lineno)
+ message = "Invalid byte sequence in #{@encoding}"
+ raise MalformedCSVError.new(message, lineno)
rescue UnexpectedError => error
if @scanner
ignore_broken_line
@@ -486,6 +485,7 @@ class CSV
message = ":quote_char has to be nil or a single character String"
raise ArgumentError, message
end
+ @double_quote_character = @quote_character * 2
@escaped_quote_character = Regexp.escape(@quote_character)
@escaped_quote = Regexp.new(@escaped_quote_character)
end
@@ -875,7 +875,8 @@ class CSV
!line.valid_encoding?
end
if index
- raise InvalidEncodingError.new(@encoding, @lineno + index + 1)
+ message = "Invalid byte sequence in #{@encoding}"
+ raise MalformedCSVError.new(message, @lineno + index + 1)
end
end
Scanner.new(string)
diff --git a/lib/csv/version.rb b/lib/csv/version.rb
index 9c65803a34..e05d63d801 100644
--- a/lib/csv/version.rb
+++ b/lib/csv/version.rb
@@ -2,5 +2,5 @@
class CSV
# The version of the installed library.
- VERSION = "3.2.8"
+ VERSION = "3.2.6"
end
diff --git a/lib/delegate.gemspec b/lib/delegate.gemspec
deleted file mode 100644
index 6c3feac74b..0000000000
--- a/lib/delegate.gemspec
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{Provides three abilities to delegate method calls to an object.}
- spec.description = %q{Provides three abilities to delegate method calls to an object.}
- spec.homepage = "https://github.com/ruby/delegate"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.require_paths = ["lib"]
- spec.required_ruby_version = '>= 2.7'
-end
diff --git a/lib/delegate.rb b/lib/delegate.rb
index 4d8994d8a0..387a5f063d 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -39,7 +39,7 @@
# Be advised, RDoc will not detect delegated methods.
#
class Delegator < BasicObject
- VERSION = "0.3.1"
+ VERSION = "0.3.0"
kernel = ::Kernel.dup
kernel.class_eval do
diff --git a/lib/delegate/delegate.gemspec b/lib/delegate/delegate.gemspec
new file mode 100644
index 0000000000..1cfacfeb2f
--- /dev/null
+++ b/lib/delegate/delegate.gemspec
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Provides three abilities to delegate method calls to an object.}
+ spec.description = %q{Provides three abilities to delegate method calls to an object.}
+ spec.homepage = "https://github.com/ruby/delegate"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.require_paths = ["lib"]
+ spec.required_ruby_version = '>= 2.7'
+end
diff --git a/lib/did_you_mean.rb b/lib/did_you_mean.rb
index e177665099..2df238da06 100644
--- a/lib/did_you_mean.rb
+++ b/lib/did_you_mean.rb
@@ -113,7 +113,7 @@ module DidYouMean
correct_error LoadError, RequirePathChecker if RUBY_VERSION >= '2.8.0'
correct_error NoMatchingPatternKeyError, PatternKeyNameChecker if defined?(::NoMatchingPatternKeyError)
- # TODO: Remove on the 3.4 development start:
+ # TODO: Remove on 3.3:
class DeprecatedMapping # :nodoc:
def []=(key, value)
warn "Calling `DidYouMean::SPELL_CHECKERS[#{key.to_s}] = #{value.to_s}' has been deprecated. " \
@@ -132,7 +132,7 @@ module DidYouMean
end
end
- # TODO: Remove on the 3.4 development start:
+ # TODO: Remove on 3.3:
SPELL_CHECKERS = DeprecatedMapping.new
deprecate_constant :SPELL_CHECKERS
private_constant :DeprecatedMapping
diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb
index 5a85e42975..23181bb834 100644
--- a/lib/drb/drb.rb
+++ b/lib/drb/drb.rb
@@ -2,7 +2,7 @@
#
# = drb/drb.rb
#
-# Distributed Ruby: _dRuby_
+# Distributed Ruby: _dRuby_ version 2.0.4
#
# Copyright (c) 1999-2003 Masatoshi SEKI. You can redistribute it and/or
# modify it under the same terms as Ruby.
@@ -50,7 +50,6 @@ require 'socket'
require 'io/wait'
require 'monitor'
require_relative 'eq'
-require_relative 'version'
#
# == Overview
diff --git a/lib/drb/ssl.rb b/lib/drb/ssl.rb
index 392d6560e9..54ab1ef395 100644
--- a/lib/drb/ssl.rb
+++ b/lib/drb/ssl.rb
@@ -73,14 +73,6 @@ module DRb
# :SSLTmpDhCallback ::
# A DH callback. See OpenSSL::SSL::SSLContext.tmp_dh_callback
#
- # :SSLMinVersion ::
- # This is the minimum SSL version to allow. See
- # OpenSSL::SSL::SSLContext#min_version=.
- #
- # :SSLMaxVersion ::
- # This is the maximum SSL version to allow. See
- # OpenSSL::SSL::SSLContext#max_version=.
- #
# :SSLVerifyMode ::
# This is the SSL verification mode. See OpenSSL::SSL::VERIFY_* for
# available modes. The default is OpenSSL::SSL::VERIFY_NONE
@@ -216,8 +208,6 @@ module DRb
ctx = ::OpenSSL::SSL::SSLContext.new
ctx.cert = @cert
ctx.key = @pkey
- ctx.min_version = self[:SSLMinVersion]
- ctx.max_version = self[:SSLMaxVersion]
ctx.client_ca = self[:SSLClientCA]
ctx.ca_path = self[:SSLCACertificatePath]
ctx.ca_file = self[:SSLCACertificateFile]
diff --git a/lib/drb/version.rb b/lib/drb/version.rb
index 73fa4c18fd..10d33445b6 100644
--- a/lib/drb/version.rb
+++ b/lib/drb/version.rb
@@ -1,3 +1,3 @@
module DRb
- VERSION = "2.2.0"
+ VERSION = "2.1.1"
end
diff --git a/lib/erb.gemspec b/lib/erb.gemspec
index 94a8fd5c3e..d973cc10de 100644
--- a/lib/erb.gemspec
+++ b/lib/erb.gemspec
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
spec.name = 'erb'
spec.version = ERB.const_get(:VERSION, false)
spec.authors = ['Masatoshi SEKI', 'Takashi Kokubun']
- spec.email = ['seki@ruby-lang.org', 'k0kubun@ruby-lang.org']
+ spec.email = ['seki@ruby-lang.org', 'takashikkbn@gmail.com']
spec.summary = %q{An easy to use but powerful templating system for Ruby.}
spec.description = %q{An easy to use but powerful templating system for Ruby.}
diff --git a/lib/erb.rb b/lib/erb.rb
index bc1615d7da..754419f819 100644
--- a/lib/erb.rb
+++ b/lib/erb.rb
@@ -307,11 +307,11 @@ class ERB
# def build
# b = binding
# # create and run templates, filling member data variables
- # ERB.new(<<~'END_PRODUCT', trim_mode: "", eoutvar: "@product").result b
+ # ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), trim_mode: "", eoutvar: "@product").result b
# <%= PRODUCT[:name] %>
# <%= PRODUCT[:desc] %>
# END_PRODUCT
- # ERB.new(<<~'END_PRICE', trim_mode: "", eoutvar: "@price").result b
+ # ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), trim_mode: "", eoutvar: "@price").result b
# <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
# <%= PRODUCT[:desc] %>
# END_PRICE
diff --git a/lib/erb/compiler.rb b/lib/erb/compiler.rb
index 7096c8dcea..547d2c4c44 100644
--- a/lib/erb/compiler.rb
+++ b/lib/erb/compiler.rb
@@ -1,4 +1,3 @@
-# frozen_string_literal: true
#--
# ERB::Compiler
#
diff --git a/lib/erb/def_method.rb b/lib/erb/def_method.rb
index aee989a926..17f9c0f9fa 100644
--- a/lib/erb/def_method.rb
+++ b/lib/erb/def_method.rb
@@ -1,4 +1,3 @@
-# frozen_string_literal: true
#--
# ERB::DefMethod
#
diff --git a/lib/erb/util.rb b/lib/erb/util.rb
index 1d2a36275d..0c1e7482a8 100644
--- a/lib/erb/util.rb
+++ b/lib/erb/util.rb
@@ -1,4 +1,3 @@
-# frozen_string_literal: true
#--
# ERB::Escape
#
diff --git a/lib/erb/version.rb b/lib/erb/version.rb
index 295fc5fa6f..38e1b76ff4 100644
--- a/lib/erb/version.rb
+++ b/lib/erb/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class ERB
- VERSION = '4.0.3'
+ VERSION = '4.0.2'
private_constant :VERSION
end
diff --git a/lib/error_highlight/base.rb b/lib/error_highlight/base.rb
index 7d2ff0c889..062871ee16 100644
--- a/lib/error_highlight/base.rb
+++ b/lib/error_highlight/base.rb
@@ -98,40 +98,9 @@ module ErrorHighlight
end
end
- OPT_GETCONSTANT_PATH = (RUBY_VERSION.split(".").map {|s| s.to_i } <=> [3, 2]) >= 0
- private_constant :OPT_GETCONSTANT_PATH
-
def spot
return nil unless @node
- if OPT_GETCONSTANT_PATH && @node.type == :COLON2
- # In Ruby 3.2 or later, a nested constant access (like `Foo::Bar::Baz`)
- # is compiled to one instruction (opt_getconstant_path).
- # @node points to the node of the whole `Foo::Bar::Baz` even if `Foo`
- # or `Foo::Bar` causes NameError.
- # So we try to spot the sub-node that causes the NameError by using
- # `NameError#name`.
- subnodes = []
- node = @node
- while node.type == :COLON2
- node2, const = node.children
- subnodes << node if const == @name
- node = node2
- end
- if node.type == :CONST || node.type == :COLON3
- if node.children.first == @name
- subnodes << node
- end
-
- # If we found only one sub-node whose name is equal to @name, use it
- return nil if subnodes.size != 1
- @node = subnodes.first
- else
- # Do nothing; opt_getconstant_path is used only when the const base is
- # NODE_CONST (`Foo`) or NODE_COLON3 (`::Foo`)
- end
- end
-
case @node.type
when :CALL, :QCALL
diff --git a/lib/error_highlight/version.rb b/lib/error_highlight/version.rb
index 506d37fbc1..5afe5f06d6 100644
--- a/lib/error_highlight/version.rb
+++ b/lib/error_highlight/version.rb
@@ -1,3 +1,3 @@
module ErrorHighlight
- VERSION = "0.6.0"
+ VERSION = "0.5.1"
end
diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 8ec5a3ad12..b495078f93 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -3,7 +3,7 @@
begin
require 'rbconfig'
rescue LoadError
- # for make rjit-headers
+ # for make mjit-headers
end
# Namespace for file utility methods for copying, moving, removing, etc.
@@ -180,7 +180,7 @@ end
# - {CVE-2004-0452}[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452].
#
module FileUtils
- VERSION = "1.7.2"
+ VERSION = "1.7.0"
def self.private_module_function(name) #:nodoc:
module_function name
@@ -192,6 +192,8 @@ module FileUtils
#
# FileUtils.pwd # => "/rdoc/fileutils"
#
+ # FileUtils.getwd is an alias for FileUtils.pwd.
+ #
# Related: FileUtils.cd.
#
def pwd
@@ -233,6 +235,8 @@ module FileUtils
# cd ..
# cd fileutils
#
+ # FileUtils.chdir is an alias for FileUtils.cd.
+ #
# Related: FileUtils.pwd.
#
def cd(dir, verbose: nil, &block) # :yield: dir
@@ -511,6 +515,8 @@ module FileUtils
# Raises an exception if +dest+ is the path to an existing file
# and keyword argument +force+ is not +true+.
#
+ # FileUtils#link is an alias for FileUtils#ln.
+ #
# Related: FileUtils.link_entry (has different options).
#
def ln(src, dest, force: nil, noop: nil, verbose: nil)
@@ -701,6 +707,8 @@ module FileUtils
# ln -sf src2.txt dest2.txt
# ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
#
+ # FileUtils.symlink is an alias for FileUtils.ln_s.
+ #
# Related: FileUtils.ln_sf.
#
def ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
@@ -868,6 +876,8 @@ module FileUtils
#
# Raises an exception if +src+ is a directory.
#
+ # FileUtils.copy is an alias for FileUtils.cp.
+ #
# Related: {methods for copying}[rdoc-ref:FileUtils@Copying].
#
def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
@@ -1154,6 +1164,8 @@ module FileUtils
# mv src0 dest0
# mv src1.txt src1 dest1
#
+ # FileUtils.move is an alias for FileUtils.mv.
+ #
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
return if noop
@@ -1211,6 +1223,8 @@ module FileUtils
#
# rm src0.dat src0.txt
#
+ # FileUtils.remove is an alias for FileUtils.rm.
+ #
# Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
#
def rm(list, force: nil, noop: nil, verbose: nil)
@@ -1236,6 +1250,8 @@ module FileUtils
#
# See FileUtils.rm for keyword arguments.
#
+ # FileUtils.safe_unlink is an alias for FileUtils.rm_f.
+ #
# Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
#
def rm_f(list, noop: nil, verbose: nil)
@@ -1323,6 +1339,8 @@ module FileUtils
#
# See FileUtils.rm_r for keyword arguments.
#
+ # FileUtils.rmtree is an alias for FileUtils.rm_rf.
+ #
# Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting].
#
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
@@ -1624,13 +1642,7 @@ module FileUtils
st = File.stat(s)
unless File.exist?(d) and compare_file(s, d)
remove_file d, true
- if d.end_with?('/')
- mkdir_p d
- copy_file s, d + File.basename(s)
- else
- mkdir_p File.expand_path('..', d)
- copy_file s, d
- end
+ copy_file s, d
File.utime st.atime, st.mtime, d if preserve
File.chmod fu_mode(mode, st), d if mode
File.chown uid, gid, d if uid or gid
diff --git a/lib/find.gemspec b/lib/find.gemspec
index cb845e9409..3f0aadcdae 100644
--- a/lib/find.gemspec
+++ b/lib/find.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "find"
+ spec.version = "0.1.1"
spec.authors = ['Kazuki Tsujimoto']
spec.email = ['kazuki@callcc.net']
diff --git a/lib/find.rb b/lib/find.rb
index 98a79cc76d..9bee99c66d 100644
--- a/lib/find.rb
+++ b/lib/find.rb
@@ -27,8 +27,6 @@
#
module Find
- VERSION = "0.2.0"
-
#
# Calls the associated block with the name of every file and directory listed
# as arguments, then recursively on their subdirectories, and so on.
diff --git a/lib/getoptlong.gemspec b/lib/getoptlong.gemspec
deleted file mode 100644
index c2f65dcaab..0000000000
--- a/lib/getoptlong.gemspec
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{GetoptLong for Ruby}
- spec.description = spec.summary
- spec.homepage = "https://github.com/ruby/getoptlong"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- # Specify which files should be added to the gem when it is released.
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.require_paths = ["lib"]
-end
diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb
index c825962160..5ae0e1497c 100644
--- a/lib/getoptlong.rb
+++ b/lib/getoptlong.rb
@@ -352,7 +352,7 @@
#
# Command line:
#
-# $ ruby fibonacci.rb --number 6 --verbose yes
+# $ ruby fibonacci.rb --number 6 --verbose yes
#
# Output:
#
@@ -368,7 +368,7 @@
#
class GetoptLong
# Version.
- VERSION = "0.2.1"
+ VERSION = "0.2.0"
#
# Orderings.
diff --git a/lib/getoptlong/getoptlong.gemspec b/lib/getoptlong/getoptlong.gemspec
new file mode 100644
index 0000000000..dfe087b886
--- /dev/null
+++ b/lib/getoptlong/getoptlong.gemspec
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{GetoptLong for Ruby}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/getoptlong"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb
index 03e1c18baa..7a5cf94830 100644
--- a/lib/ipaddr.rb
+++ b/lib/ipaddr.rb
@@ -40,7 +40,7 @@ require 'socket'
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
class IPAddr
- VERSION = "1.2.6"
+ VERSION = "1.2.5"
# 32 bit mask for IPv4
IN4MASK = 0xffffffff
@@ -176,7 +176,9 @@ class IPAddr
def include?(other)
other = coerce_other(other)
return false unless other.family == family
- begin_addr <= other.begin_addr && end_addr >= other.end_addr
+ range = to_range
+ other = other.to_range
+ range.begin <= other.begin && range.end >= other.end
end
alias === include?
@@ -261,8 +263,7 @@ class IPAddr
# Returns true if the ipaddr is a private address. IPv4 addresses
# in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC
# 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC
- # 4193 are considered private. Private IPv4 addresses in the
- # IPv4-mapped IPv6 address range are also considered private.
+ # 4193 are considered private.
def private?
case @family
when Socket::AF_INET
@@ -270,12 +271,7 @@ class IPAddr
@addr & 0xfff00000 == 0xac100000 || # 172.16.0.0/12
@addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
when Socket::AF_INET6
- @addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
- (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
- @addr & 0xff000000 == 0x0a000000 || # ::ffff:10.0.0.0/8
- @addr & 0xfff00000 == 0xac100000 || # ::ffff::172.16.0.0/12
- @addr & 0xffff0000 == 0xc0a80000 # ::ffff::192.168.0.0/16
- ))
+ @addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000
else
raise AddressFamilyError, "unsupported address family"
end
@@ -404,6 +400,17 @@ class IPAddr
# Creates a Range object for the network address.
def to_range
+ begin_addr = (@addr & @mask_addr)
+
+ case @family
+ when Socket::AF_INET
+ end_addr = (@addr | (IN4MASK ^ @mask_addr))
+ when Socket::AF_INET6
+ end_addr = (@addr | (IN6MASK ^ @mask_addr))
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+
self.class.new(begin_addr, @family)..self.class.new(end_addr, @family)
end
@@ -484,21 +491,6 @@ class IPAddr
protected
- def begin_addr
- @addr & @mask_addr
- end
-
- def end_addr
- case @family
- when Socket::AF_INET
- @addr | (IN4MASK ^ @mask_addr)
- when Socket::AF_INET6
- @addr | (IN6MASK ^ @mask_addr)
- else
- raise AddressFamilyError, "unsupported address family"
- end
- end
-
# Set +@addr+, the internal stored ip address, to given +addr+. The
# parameter +addr+ is validated using the first +family+ member,
# which is +Socket::AF_INET+ or +Socket::AF_INET6+.
diff --git a/lib/irb.rb b/lib/irb.rb
index b3435c257e..2db99bcd43 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -1,895 +1,412 @@
-# frozen_string_literal: true
-
-# :markup: markdown
+# frozen_string_literal: false
+#
# irb.rb - irb main module
+# $Release Version: 0.9.6 $
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
-
+# --
+#
+#
+#
require "ripper"
require "reline"
require_relative "irb/init"
require_relative "irb/context"
-require_relative "irb/default_commands"
+require_relative "irb/extend-command"
require_relative "irb/ruby-lex"
-require_relative "irb/statement"
require_relative "irb/input-method"
require_relative "irb/locale"
require_relative "irb/color"
require_relative "irb/version"
require_relative "irb/easter-egg"
-require_relative "irb/debug"
-require_relative "irb/pager"
-# ## IRB
+# IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby
+# expressions read from the standard input.
#
-# Module IRB ("Interactive Ruby") provides a shell-like interface that supports
-# user interaction with the Ruby interpreter.
+# The +irb+ command from your shell will start the interpreter.
#
-# It operates as a *read-eval-print loop*
-# ([REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop))
-# that:
+# == Usage
#
-# * ***Reads*** each character as you type. You can modify the IRB context to
-# change the way input works. See [Input](rdoc-ref:IRB@Input).
-# * ***Evaluates*** the code each time it has read a syntactically complete
-# passage.
-# * ***Prints*** after evaluating. You can modify the IRB context to change
-# the way output works. See [Output](rdoc-ref:IRB@Output).
+# Use of irb is easy if you know Ruby.
#
-#
-# Example:
+# When executing irb, prompts are displayed as follows. Then, enter the Ruby
+# expression. An input is executed when it is syntactically complete.
#
# $ irb
-# irb(main):001> File.basename(Dir.pwd)
-# => "irb"
-# irb(main):002> Dir.entries('.').size
-# => 25
-# irb(main):003* Dir.entries('.').select do |entry|
-# irb(main):004* entry.start_with?('R')
-# irb(main):005> end
-# => ["README.md", "Rakefile"]
-#
-# The typed input may also include [\IRB-specific
-# commands](rdoc-ref:IRB@IRB-Specific+Commands).
-#
-# As seen above, you can start IRB by using the shell command `irb`.
-#
-# You can stop an IRB session by typing command `exit`:
-#
-# irb(main):006> exit
-# $
-#
-# At that point, IRB calls any hooks found in array `IRB.conf[:AT_EXIT]`, then
-# exits.
-#
-# ## Startup
-#
-# At startup, IRB:
-#
-# 1. Interprets (as Ruby code) the content of the [configuration
-# file](rdoc-ref:IRB@Configuration+File) (if given).
-# 2. Constructs the initial session context from [hash
-# IRB.conf](rdoc-ref:IRB@Hash+IRB.conf) and from default values; the hash
-# content may have been affected by [command-line
-# options](rdoc-ref:IB@Command-Line+Options), and by direct assignments in
-# the configuration file.
-# 3. Assigns the context to variable `conf`.
-# 4. Assigns command-line arguments to variable `ARGV`.
-# 5. Prints the [prompt](rdoc-ref:IRB@Prompt+and+Return+Formats).
-# 6. Puts the content of the [initialization
-# script](rdoc-ref:IRB@Initialization+Script) onto the IRB shell, just as if
-# it were user-typed commands.
-#
-#
-# ### The Command Line
-#
-# On the command line, all options precede all arguments; the first item that is
-# not recognized as an option is treated as an argument, as are all items that
-# follow.
-#
-# #### Command-Line Options
-#
-# Many command-line options affect entries in hash `IRB.conf`, which in turn
-# affect the initial configuration of the IRB session.
-#
-# Details of the options are described in the relevant subsections below.
-#
-# A cursory list of the IRB command-line options may be seen in the [help
-# message](https://raw.githubusercontent.com/ruby/irb/master/lib/irb/lc/help-message),
-# which is also displayed if you use command-line option `--help`.
-#
-# If you are interested in a specific option, consult the
-# [index](rdoc-ref:doc/irb/indexes.md@Index+of+Command-Line+Options).
-#
-# #### Command-Line Arguments
-#
-# Command-line arguments are passed to IRB in array `ARGV`:
-#
-# $ irb --noscript Foo Bar Baz
-# irb(main):001> ARGV
-# => ["Foo", "Bar", "Baz"]
-# irb(main):002> exit
-# $
-#
-# Command-line option `--` causes everything that follows to be treated as
-# arguments, even those that look like options:
-#
-# $ irb --noscript -- --noscript -- Foo Bar Baz
-# irb(main):001> ARGV
-# => ["--noscript", "--", "Foo", "Bar", "Baz"]
-# irb(main):002> exit
-# $
-#
-# ### Configuration File
-#
-# You can initialize IRB via a *configuration file*.
-#
-# If command-line option `-f` is given, no configuration file is looked for.
-#
-# Otherwise, IRB reads and interprets a configuration file if one is available.
-#
-# The configuration file can contain any Ruby code, and can usefully include
-# user code that:
-#
-# * Can then be debugged in IRB.
-# * Configures IRB itself.
-# * Requires or loads files.
-#
-#
-# The path to the configuration file is the first found among:
-#
-# * The value of variable `$IRBRC`, if defined.
-# * The value of variable `$XDG_CONFIG_HOME/irb/irbrc`, if defined.
-# * File `$HOME/.irbrc`, if it exists.
-# * File `$HOME/.config/irb/irbrc`, if it exists.
-# * File `.irbrc` in the current directory, if it exists.
-# * File `irb.rc` in the current directory, if it exists.
-# * File `_irbrc` in the current directory, if it exists.
-# * File `$irbrc` in the current directory, if it exists.
-#
-#
-# If the search fails, there is no configuration file.
-#
-# If the search succeeds, the configuration file is read as Ruby code, and so
-# can contain any Ruby programming you like.
-#
-# Method `conf.rc?` returns `true` if a configuration file was read, `false`
-# otherwise. Hash entry `IRB.conf[:RC]` also contains that value.
-#
-# ### Hash `IRB.conf`
-#
-# The initial entries in hash `IRB.conf` are determined by:
-#
-# * Default values.
-# * Command-line options, which may override defaults.
-# * Direct assignments in the configuration file.
-#
-#
-# You can see the hash by typing `IRB.conf`.
-#
-# Details of the entries' meanings are described in the relevant subsections
-# below.
-#
-# If you are interested in a specific entry, consult the
-# [index](rdoc-ref:doc/irb/indexes.md@Index+of+IRB.conf+Entries).
-#
-# ### Notes on Initialization Precedence
-#
-# * Any conflict between an entry in hash `IRB.conf` and a command-line option
-# is resolved in favor of the hash entry.
-# * Hash `IRB.conf` affects the context only once, when the configuration file
-# is interpreted; any subsequent changes to it do not affect the context and
-# are therefore essentially meaningless.
-#
-#
-# ### Initialization Script
-#
-# By default, the first command-line argument (after any options) is the path to
-# a Ruby initialization script.
-#
-# IRB reads the initialization script and puts its content onto the IRB shell,
-# just as if it were user-typed commands.
-#
-# Command-line option `--noscript` causes the first command-line argument to be
-# treated as an ordinary argument (instead of an initialization script);
-# `--script` is the default.
-#
-# ## Input
-#
-# This section describes the features that allow you to change the way IRB input
-# works; see also [Input and Output](rdoc-ref:IRB@Input+and+Output).
-#
-# ### Input Command History
-#
-# By default, IRB stores a history of up to 1000 input commands in a file named
-# `.irb_history`. The history file will be in the same directory as the
-# [configuration file](rdoc-ref:IRB@Configuration+File) if one is found, or in
-# `~/` otherwise.
-#
-# A new IRB session creates the history file if it does not exist, and appends
-# to the file if it does exist.
-#
-# You can change the filepath by adding to your configuration file:
-# `IRB.conf[:HISTORY_FILE] = *filepath*`, where *filepath* is a string filepath.
-#
-# During the session, method `conf.history_file` returns the filepath, and
-# method `conf.history_file = *new_filepath*` copies the history to the file at
-# *new_filepath*, which becomes the history file for the session.
-#
-# You can change the number of commands saved by adding to your configuration
-# file: `IRB.conf[:SAVE_HISTORY] = *n*`, wheHISTORY_FILEre *n* is one of:
-#
-# * Positive integer: the number of commands to be saved,
-# * Zero: all commands are to be saved.
-# * `nil`: no commands are to be saved,.
-#
-#
-# During the session, you can use methods `conf.save_history` or
-# `conf.save_history=` to retrieve or change the count.
-#
-# ### Command Aliases
-#
-# By default, IRB defines several command aliases:
-#
-# irb(main):001> conf.command_aliases
-# => {:"$"=>:show_source, :"@"=>:whereami}
-#
-# You can change the initial aliases in the configuration file with:
-#
-# IRB.conf[:COMMAND_ALIASES] = {foo: :show_source, bar: :whereami}
-#
-# You can replace the current aliases at any time with configuration method
-# `conf.command_aliases=`; Because `conf.command_aliases` is a hash, you can
-# modify it.
-#
-# ### End-of-File
-#
-# By default, `IRB.conf[:IGNORE_EOF]` is `false`, which means that typing the
-# end-of-file character `Ctrl-D` causes the session to exit.
-#
-# You can reverse that behavior by adding `IRB.conf[:IGNORE_EOF] = true` to the
-# configuration file.
-#
-# During the session, method `conf.ignore_eof?` returns the setting, and method
-# `conf.ignore_eof = *boolean*` sets it.
-#
-# ### SIGINT
-#
-# By default, `IRB.conf[:IGNORE_SIGINT]` is `true`, which means that typing the
-# interrupt character `Ctrl-C` causes the session to exit.
-#
-# You can reverse that behavior by adding `IRB.conf[:IGNORE_SIGING] = false` to
-# the configuration file.
-#
-# During the session, method `conf.ignore_siging?` returns the setting, and
-# method `conf.ignore_sigint = *boolean*` sets it.
-#
-# ### Automatic Completion
-#
-# By default, IRB enables [automatic
-# completion](https://en.wikipedia.org/wiki/Autocomplete#In_command-line_interpr
-# eters):
-#
-# You can disable it by either of these:
-#
-# * Adding `IRB.conf[:USE_AUTOCOMPLETE] = false` to the configuration file.
-# * Giving command-line option `--noautocomplete` (`--autocomplete` is the
-# default).
-#
-#
-# Method `conf.use_autocomplete?` returns `true` if automatic completion is
-# enabled, `false` otherwise.
-#
-# The setting may not be changed during the session.
-#
-# ### Automatic Indentation
-#
-# By default, IRB automatically indents lines of code to show structure (e.g.,
-# it indent the contents of a block).
-#
-# The current setting is returned by the configuration method
-# `conf.auto_indent_mode`.
-#
-# The default initial setting is `true`:
-#
-# irb(main):001> conf.auto_indent_mode
-# => true
-# irb(main):002* Dir.entries('.').select do |entry|
-# irb(main):003* entry.start_with?('R')
-# irb(main):004> end
-# => ["README.md", "Rakefile"]
-#
-# You can change the initial setting in the configuration file with:
+# irb(main):001:0> 1+2
+# #=> 3
+# irb(main):002:0> class Foo
+# irb(main):003:1> def foo
+# irb(main):004:2> print 1
+# irb(main):005:2> end
+# irb(main):006:1> end
+# #=> nil
+#
+# The singleline editor module or multiline editor module can be used with irb.
+# Use of multiline editor is default if it's installed.
+#
+# == Command line options
+#
+# :include: ./irb/lc/help-message
+#
+# == Commands
+#
+# The following commands are available on IRB.
+#
+# * cwws
+# * Show the current workspace.
+# * cb, cws, chws
+# * Change the current workspace to an object.
+# * bindings, workspaces
+# * Show workspaces.
+# * pushb, pushws
+# * Push an object to the workspace stack.
+# * popb, popws
+# * Pop a workspace from the workspace stack.
+# * load
+# * Load a Ruby file.
+# * require
+# * Require a Ruby file.
+# * source
+# * Loads a given file in the current session.
+# * irb
+# * Start a child IRB.
+# * jobs
+# * List of current sessions.
+# * fg
+# * Switches to the session of the given number.
+# * kill
+# * Kills the session with the given number.
+# * help
+# * Enter the mode to look up RI documents.
+# * irb_info
+# * Show information about IRB.
+# * ls
+# * Show methods, constants, and variables.
+# -g [query] or -G [query] allows you to filter out the output.
+# * measure
+# * measure enables the mode to measure processing time. measure :off disables it.
+# * $, show_source
+# * Show the source code of a given method or constant.
+# * @, whereami
+# * Show the source code around binding.irb again.
+# * debug
+# * Start the debugger of debug.gem.
+# * break, delete, next, step, continue, finish, backtrace, info, catch
+# * Start the debugger of debug.gem and run the command on it.
+#
+# == Configuration
+#
+# IRB reads a personal initialization file when it's invoked.
+# IRB searches a file in the following order and loads the first one found.
+#
+# * <tt>$IRBRC</tt> (if <tt>$IRBRC</tt> is set)
+# * <tt>$XDG_CONFIG_HOME/irb/irbrc</tt> (if <tt>$XDG_CONFIG_HOME</tt> is set)
+# * <tt>~/.irbrc</tt>
+# * +.config/irb/irbrc+
+# * +.irbrc+
+# * +irb.rc+
+# * +_irbrc+
+# * <code>$irbrc</code>
+#
+# The following are alternatives to the command line options. To use them type
+# as follows in an +irb+ session:
+#
+# IRB.conf[:IRB_NAME]="irb"
+# IRB.conf[:INSPECT_MODE]=nil
+# IRB.conf[:IRB_RC] = nil
+# IRB.conf[:BACK_TRACE_LIMIT]=16
+# IRB.conf[:USE_LOADER] = false
+# IRB.conf[:USE_MULTILINE] = nil
+# IRB.conf[:USE_SINGLELINE] = nil
+# IRB.conf[:USE_COLORIZE] = true
+# IRB.conf[:USE_TRACER] = false
+# IRB.conf[:USE_AUTOCOMPLETE] = true
+# IRB.conf[:IGNORE_SIGINT] = true
+# IRB.conf[:IGNORE_EOF] = false
+# IRB.conf[:PROMPT_MODE] = :DEFAULT
+# IRB.conf[:PROMPT] = {...}
+#
+# === Auto indentation
+#
+# To disable auto-indent mode in irb, add the following to your +.irbrc+:
#
# IRB.conf[:AUTO_INDENT] = false
#
-# Note that the *current* setting *may not* be changed in the IRB session.
-#
-# ### Input Method
-#
-# The IRB input method determines how command input is to be read; by default,
-# the input method for a session is IRB::RelineInputMethod. Unless the
-# value of the TERM environment variable is 'dumb', in which case the
-# most simplistic input method is used.
-#
-# You can set the input method by:
-#
-# * Adding to the configuration file:
-#
-# * `IRB.conf[:USE_SINGLELINE] = true` or `IRB.conf[:USE_MULTILINE]=
-# false` sets the input method to IRB::ReadlineInputMethod.
-# * `IRB.conf[:USE_SINGLELINE] = false` or `IRB.conf[:USE_MULTILINE] =
-# true` sets the input method to IRB::RelineInputMethod.
-#
-#
-# * Giving command-line options:
-#
-# * `--singleline` or `--nomultiline` sets the input method to
-# IRB::ReadlineInputMethod.
-# * `--nosingleline` or `--multiline` sets the input method to
-# IRB::RelineInputMethod.
-# * `--nosingleline` together with `--nomultiline` sets the
-# input to IRB::StdioInputMethod.
-#
-#
-# Method `conf.use_multiline?` and its synonym `conf.use_reline` return:
-#
-# * `true` if option `--multiline` was given.
-# * `false` if option `--nomultiline` was given.
-# * `nil` if neither was given.
-#
-#
-# Method `conf.use_singleline?` and its synonym `conf.use_readline` return:
-#
-# * `true` if option `--singleline` was given.
-# * `false` if option `--nosingleline` was given.
-# * `nil` if neither was given.
-#
-#
-# ## Output
-#
-# This section describes the features that allow you to change the way IRB
-# output works; see also [Input and Output](rdoc-ref:IRB@Input+and+Output).
-#
-# ### Return-Value Printing (Echoing)
-#
-# By default, IRB prints (echoes) the values returned by all input commands.
-#
-# You can change the initial behavior and suppress all echoing by:
-#
-# * Adding to the configuration file: `IRB.conf[:ECHO] = false`. (The default
-# value for this entry is `nil`, which means the same as `true`.)
-# * Giving command-line option `--noecho`. (The default is `--echo`.)
-#
-#
-# During the session, you can change the current setting with configuration
-# method `conf.echo=` (set to `true` or `false`).
-#
-# As stated above, by default IRB prints the values returned by all input
-# commands; but IRB offers special treatment for values returned by assignment
-# statements, which may be:
-#
-# * Printed with truncation (to fit on a single line of output), which is the
-# default; an ellipsis (`...` is suffixed, to indicate the truncation):
-#
-# irb(main):001> x = 'abc' * 100
-#
-#
-# > "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc...
-#
-# * Printed in full (regardless of the length).
-# * Suppressed (not printed at all)
-#
+# === Autocompletion
#
-# You can change the initial behavior by:
+# To disable autocompletion for irb, add the following to your +.irbrc+:
#
-# * Adding to the configuration file: `IRB.conf[:ECHO_ON_ASSIGNMENT] = false`.
-# (The default value for this entry is `niL`, which means the same as
-# `:truncate`.)
-# * Giving command-line option `--noecho-on-assignment` or
-# `--echo-on-assignment`. (The default is `--truncate-echo-on-assignment`.)
+# IRB.conf[:USE_AUTOCOMPLETE] = false
#
+# === History
#
-# During the session, you can change the current setting with configuration
-# method `conf.echo_on_assignment=` (set to `true`, `false`, or `:truncate`).
+# By default, irb will store the last 1000 commands you used in
+# <code>IRB.conf[:HISTORY_FILE]</code> (<code>~/.irb_history</code> by default).
#
-# By default, IRB formats returned values by calling method `inspect`.
+# If you want to disable history, add the following to your +.irbrc+:
#
-# You can change the initial behavior by:
+# IRB.conf[:SAVE_HISTORY] = nil
#
-# * Adding to the configuration file: `IRB.conf[:INSPECT_MODE] = false`. (The
-# default value for this entry is `true`.)
-# * Giving command-line option `--noinspect`. (The default is `--inspect`.)
+# See IRB::Context#save_history= for more information.
#
+# The history of _results_ of commands evaluated is not stored by default,
+# but can be turned on to be stored with this +.irbrc+ setting:
#
-# During the session, you can change the setting using method
-# `conf.inspect_mode=`.
+# IRB.conf[:EVAL_HISTORY] = <number>
#
-# ### Multiline Output
+# See IRB::Context#eval_history= and History class. The history of command
+# results is not permanently saved in any file.
#
-# By default, IRB prefixes a newline to a multiline response.
+# == Customizing the IRB Prompt
#
-# You can change the initial default value by adding to the configuration file:
+# In order to customize the prompt, you can change the following Hash:
#
-# IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] = false
+# IRB.conf[:PROMPT]
#
-# During a session, you can retrieve or set the value using methods
-# `conf.newline_before_multiline_output?` and
-# `conf.newline_before_multiline_output=`.
+# This example can be used in your +.irbrc+
#
-# Examples:
-#
-# irb(main):001> conf.inspect_mode = false
-# => false
-# irb(main):002> "foo\nbar"
-# =>
-# foo
-# bar
-# irb(main):003> conf.newline_before_multiline_output = false
-# => false
-# irb(main):004> "foo\nbar"
-# => foo
-# bar
-#
-# ### Evaluation History
-#
-# By default, IRB saves no history of evaluations (returned values), and the
-# related methods `conf.eval_history`, `_`, and `__` are undefined.
-#
-# You can turn on that history, and set the maximum number of evaluations to be
-# stored:
-#
-# * In the configuration file: add `IRB.conf[:EVAL_HISTORY] = *n*`. (Examples
-# below assume that we've added `IRB.conf[:EVAL_HISTORY] = 5`.)
-# * In the session (at any time): `conf.eval_history = *n*`.
-#
-#
-# If `n` is zero, all evaluation history is stored.
-#
-# Doing either of the above:
-#
-# * Sets the maximum size of the evaluation history; defines method
-# `conf.eval_history`, which returns the maximum size `n` of the evaluation
-# history:
-#
-# irb(main):001> conf.eval_history = 5
-# => 5
-# irb(main):002> conf.eval_history
-# => 5
-#
-# * Defines variable `_`, which contains the most recent evaluation, or `nil`
-# if none; same as method `conf.last_value`:
-#
-# irb(main):003> _
-# => 5
-# irb(main):004> :foo
-# => :foo
-# irb(main):005> :bar
-# => :bar
-# irb(main):006> _
-# => :bar
-# irb(main):007> _
-# => :bar
-#
-# * Defines variable `__`:
-#
-# * `__` unadorned: contains all evaluation history:
-#
-# irb(main):008> :foo
-# => :foo
-# irb(main):009> :bar
-# => :bar
-# irb(main):010> :baz
-# => :baz
-# irb(main):011> :bat
-# => :bat
-# irb(main):012> :bam
-# => :bam
-# irb(main):013> __
-# =>
-# 9 :bar
-# 10 :baz
-# 11 :bat
-# 12 :bam
-# irb(main):014> __
-# =>
-# 10 :baz
-# 11 :bat
-# 12 :bam
-# 13 ...self-history...
-#
-# Note that when the evaluation is multiline, it is displayed
-# differently.
-#
-# * `__[`*m*`]`:
-#
-# * Positive *m*: contains the evaluation for the given line number,
-# or `nil` if that line number is not in the evaluation history:
-#
-# irb(main):015> __[12]
-# => :bam
-# irb(main):016> __[1]
-# => nil
-#
-# * Negative *m*: contains the `mth`-from-end evaluation, or `nil` if
-# that evaluation is not in the evaluation history:
-#
-# irb(main):017> __[-3]
-# => :bam
-# irb(main):018> __[-13]
-# => nil
-#
-# * Zero *m*: contains `nil`:
-#
-# irb(main):019> __[0]
-# => nil
-#
-#
-#
-#
-# ### Prompt and Return Formats
-#
-# By default, IRB uses the prompt and return value formats defined in its
-# `:DEFAULT` prompt mode.
-#
-# #### The Default Prompt and Return Format
-#
-# The default prompt and return values look like this:
-#
-# irb(main):001> 1 + 1
-# => 2
-# irb(main):002> 2 + 2
-# => 4
-#
-# The prompt includes:
-#
-# * The name of the running program (`irb`); see [IRB
-# Name](rdoc-ref:IRB@IRB+Name).
-# * The name of the current session (`main`); See [IRB
-# Sessions](rdoc-ref:IRB@IRB+Sessions).
-# * A 3-digit line number (1-based).
-#
-#
-# The default prompt actually defines three formats:
-#
-# * One for most situations (as above):
-#
-# irb(main):003> Dir
-# => Dir
-#
-# * One for when the typed command is a statement continuation (adds trailing
-# asterisk):
-#
-# irb(main):004* Dir.
-#
-# * One for when the typed command is a string continuation (adds trailing
-# single-quote):
-#
-# irb(main):005' Dir.entries('.
-#
-#
-# You can see the prompt change as you type the characters in the following:
-#
-# irb(main):001* Dir.entries('.').select do |entry|
-# irb(main):002* entry.start_with?('R')
-# irb(main):003> end
-# => ["README.md", "Rakefile"]
-#
-# #### Pre-Defined Prompts
-#
-# IRB has several pre-defined prompts, stored in hash `IRB.conf[:PROMPT]`:
-#
-# irb(main):001> IRB.conf[:PROMPT].keys
-# => [:NULL, :DEFAULT, :CLASSIC, :SIMPLE, :INF_RUBY, :XMP]
-#
-# To see the full data for these, type `IRB.conf[:PROMPT]`.
-#
-# Most of these prompt definitions include specifiers that represent values like
-# the IRB name, session name, and line number; see [Prompt
-# Specifiers](rdoc-ref:IRB@Prompt+Specifiers).
-#
-# You can change the initial prompt and return format by:
-#
-# * Adding to the configuration file: `IRB.conf[:PROMPT] = *mode*` where
-# *mode* is the symbol name of a prompt mode.
-# * Giving a command-line option:
-#
-# * `--prompt *mode*`: sets the prompt mode to *mode*. where *mode* is the
-# symbol name of a prompt mode.
-# * `--simple-prompt` or `--sample-book-mode`: sets the prompt mode to
-# `:SIMPLE`.
-# * `--inf-ruby-mode`: sets the prompt mode to `:INF_RUBY` and suppresses
-# both `--multiline` and `--singleline`.
-# * `--noprompt`: suppresses prompting; does not affect echoing.
-#
-#
-#
-# You can retrieve or set the current prompt mode with methods
-#
-# `conf.prompt_mode` and `conf.prompt_mode=`.
-#
-# If you're interested in prompts and return formats other than the defaults,
-# you might experiment by trying some of the others.
-#
-# #### Custom Prompts
-#
-# You can also define custom prompts and return formats, which may be done
-# either in an IRB session or in the configuration file.
-#
-# A prompt in IRB actually defines three prompts, as seen above. For simple
-# custom data, we'll make all three the same:
-#
-# irb(main):001* IRB.conf[:PROMPT][:MY_PROMPT] = {
-# irb(main):002* PROMPT_I: ': ',
-# irb(main):003* PROMPT_C: ': ',
-# irb(main):004* PROMPT_S: ': ',
-# irb(main):005* RETURN: '=> '
-# irb(main):006> }
-# => {:PROMPT_I=>": ", :PROMPT_C=>": ", :PROMPT_S=>": ", :RETURN=>"=> "}
-#
-# If you define the custom prompt in the configuration file, you can also make
-# it the current prompt by adding:
+# IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
+# :AUTO_INDENT => false, # disables auto-indent mode
+# :PROMPT_I => ">> ", # simple prompt
+# :PROMPT_S => nil, # prompt for continuated strings
+# :PROMPT_C => nil, # prompt for continuated statement
+# :RETURN => " ==>%s\n" # format to return value
+# }
#
# IRB.conf[:PROMPT_MODE] = :MY_PROMPT
#
-# Regardless of where it's defined, you can make it the current prompt in a
-# session:
-#
-# conf.prompt_mode = :MY_PROMPT
-#
-# You can view or modify the current prompt data with various configuration
-# methods:
-#
-# * `conf.prompt_mode`, `conf.prompt_mode=`.
-# * `conf.prompt_c`, `conf.c=`.
-# * `conf.prompt_i`, `conf.i=`.
-# * `conf.prompt_s`, `conf.s=`.
-# * `conf.return_format`, `return_format=`.
-#
-#
-# #### Prompt Specifiers
-#
-# A prompt's definition can include specifiers for which certain values are
-# substituted:
-#
-# * `%N`: the name of the running program.
-# * `%m`: the value of `self.to_s`.
-# * `%M`: the value of `self.inspect`.
-# * `%l`: an indication of the type of string; one of `"`, `'`, `/`, `]`.
-# * `%NNi`: Indentation level. NN is a 2-digit number that specifies the number
-# of digits of the indentation level (03 will result in 001).
-# * `%NNn`: Line number. NN is a 2-digit number that specifies the number
-# of digits of the line number (03 will result in 001).
-# * `%%`: Literal `%`.
-#
-#
-# ### Verbosity
-#
-# By default, IRB verbosity is disabled, which means that output is smaller
-# rather than larger.
-#
-# You can enable verbosity by:
-#
-# * Adding to the configuration file: `IRB.conf[:VERBOSE] = true` (the default
-# is `nil`).
-# * Giving command-line options `--verbose` (the default is `--noverbose`).
-#
-#
-# During a session, you can retrieve or set verbosity with methods
-# `conf.verbose` and `conf.verbose=`.
-#
-# ### Help
-#
-# Command-line option `--version` causes IRB to print its help text and exit.
-#
-# ### Version
-#
-# Command-line option `--version` causes IRB to print its version text and exit.
-#
-# ## Input and Output
-#
-# ### Color Highlighting
-#
-# By default, IRB color highlighting is enabled, and is used for both:
-#
-# * Input: As you type, IRB reads the typed characters and highlights elements
-# that it recognizes; it also highlights errors such as mismatched
-# parentheses.
-# * Output: IRB highlights syntactical elements.
-#
-#
-# You can disable color highlighting by:
-#
-# * Adding to the configuration file: `IRB.conf[:USE_COLORIZE] = false` (the
-# default value is `true`).
-# * Giving command-line option `--nocolorize`
-#
-#
-# ## Debugging
-#
-# Command-line option `-d` sets variables `$VERBOSE` and `$DEBUG` to `true`;
-# these have no effect on IRB output.
-#
-# ### Warnings
-#
-# Command-line option `-w` suppresses warnings.
-#
-# Command-line option `-W[*level*]` sets warning level;
-#
-# * 0=silence
-# * 1=medium
-# * 2=verbose
-#
-# ## Other Features
-#
-# ### Load Modules
-#
-# You can specify the names of modules that are to be required at startup.
-#
-# Array `conf.load_modules` determines the modules (if any) that are to be
-# required during session startup. The array is used only during session
-# startup, so the initial value is the only one that counts.
-#
-# The default initial value is `[]` (load no modules):
-#
-# irb(main):001> conf.load_modules
-# => []
-#
-# You can set the default initial value via:
-#
-# * Command-line option `-r`
-#
-# $ irb -r csv -r json
-# irb(main):001> conf.load_modules
-# => ["csv", "json"]
-#
-# * Hash entry `IRB.conf[:LOAD_MODULES] = *array*`:
-#
-# IRB.conf[:LOAD_MODULES] = %w[csv, json]
-#
-#
-# Note that the configuration file entry overrides the command-line options.
-#
-# ### RI Documentation Directories
-#
-# You can specify the paths to RI documentation directories that are to be
-# loaded (in addition to the default directories) at startup; see details about
-# RI by typing `ri --help`.
-#
-# Array `conf.extra_doc_dirs` determines the directories (if any) that are to be
-# loaded during session startup. The array is used only during session startup,
-# so the initial value is the only one that counts.
-#
-# The default initial value is `[]` (load no extra documentation):
-#
-# irb(main):001> conf.extra_doc_dirs
-# => []
-#
-# You can set the default initial value via:
-#
-# * Command-line option `--extra_doc_dir`
-#
-# $ irb --extra-doc-dir your_doc_dir --extra-doc-dir my_doc_dir
-# irb(main):001> conf.extra_doc_dirs
-# => ["your_doc_dir", "my_doc_dir"]
-#
-# * Hash entry `IRB.conf[:EXTRA_DOC_DIRS] = *array*`:
-#
-# IRB.conf[:EXTRA_DOC_DIRS] = %w[your_doc_dir my_doc_dir]
-#
-#
-# Note that the configuration file entry overrides the command-line options.
-#
-# ### IRB Name
-#
-# You can specify a name for IRB.
-#
-# The default initial value is `'irb'`:
-#
-# irb(main):001> conf.irb_name
-# => "irb"
+# Or, invoke irb with the above prompt mode by:
+#
+# irb --prompt my-prompt
+#
+# Constants +PROMPT_I+, +PROMPT_S+ and +PROMPT_C+ specify the format. In the
+# prompt specification, some special strings are available:
+#
+# %N # command name which is running
+# %m # to_s of main object (self)
+# %M # inspect of main object (self)
+# %l # type of string(", ', /, ]), `]' is inner %w[...]
+# %NNi # indent level. NN is digits and means as same as printf("%NNd").
+# # It can be omitted
+# %NNn # line number.
+# %% # %
+#
+# For instance, the default prompt mode is defined as follows:
+#
+# IRB.conf[:PROMPT_MODE][:DEFAULT] = {
+# :PROMPT_I => "%N(%m):%03n:%i> ",
+# :PROMPT_N => "%N(%m):%03n:%i> ",
+# :PROMPT_S => "%N(%m):%03n:%i%l ",
+# :PROMPT_C => "%N(%m):%03n:%i* ",
+# :RETURN => "%s\n" # used to printf
+# }
+#
+# irb comes with a number of available modes:
+#
+# # :NULL:
+# # :PROMPT_I:
+# # :PROMPT_N:
+# # :PROMPT_S:
+# # :PROMPT_C:
+# # :RETURN: |
+# # %s
+# # :DEFAULT:
+# # :PROMPT_I: ! '%N(%m):%03n:%i> '
+# # :PROMPT_N: ! '%N(%m):%03n:%i> '
+# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
+# # :PROMPT_C: ! '%N(%m):%03n:%i* '
+# # :RETURN: |
+# # => %s
+# # :CLASSIC:
+# # :PROMPT_I: ! '%N(%m):%03n:%i> '
+# # :PROMPT_N: ! '%N(%m):%03n:%i> '
+# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
+# # :PROMPT_C: ! '%N(%m):%03n:%i* '
+# # :RETURN: |
+# # %s
+# # :SIMPLE:
+# # :PROMPT_I: ! '>> '
+# # :PROMPT_N: ! '>> '
+# # :PROMPT_S:
+# # :PROMPT_C: ! '?> '
+# # :RETURN: |
+# # => %s
+# # :INF_RUBY:
+# # :PROMPT_I: ! '%N(%m):%03n:%i> '
+# # :PROMPT_N:
+# # :PROMPT_S:
+# # :PROMPT_C:
+# # :RETURN: |
+# # %s
+# # :AUTO_INDENT: true
+# # :XMP:
+# # :PROMPT_I:
+# # :PROMPT_N:
+# # :PROMPT_S:
+# # :PROMPT_C:
+# # :RETURN: |2
+# # ==>%s
+#
+# == Restrictions
+#
+# Because irb evaluates input immediately after it is syntactically complete,
+# the results may be slightly different than directly using Ruby.
+#
+# == IRB Sessions
#
-# You can set the default initial value via hash entry `IRB.conf[:IRB_NAME] =
-# *string*`:
-#
-# IRB.conf[:IRB_NAME] = 'foo'
-#
-# ### Application Name
-#
-# You can specify an application name for the IRB session.
-#
-# The default initial value is `'irb'`:
-#
-# irb(main):001> conf.ap_name
-# => "irb"
-#
-# You can set the default initial value via hash entry `IRB.conf[:AP_NAME] =
-# *string*`:
-#
-# IRB.conf[:AP_NAME] = 'my_ap_name'
-#
-# ### Configuration Monitor
-#
-# You can monitor changes to the configuration by assigning a proc to
-# `IRB.conf[:IRB_RC]` in the configuration file:
-#
-# IRB.conf[:IRB_RC] = proc {|conf| puts conf.class }
-#
-# Each time the configuration is changed, that proc is called with argument
-# `conf`:
-#
-# ### Encodings
+# IRB has a special feature, that allows you to manage many sessions at once.
#
-# Command-line option `-E *ex*[:*in*]` sets initial external (ex) and internal
-# (in) encodings.
+# You can create new sessions with Irb.irb, and get a list of current sessions
+# with the +jobs+ command in the prompt.
#
-# Command-line option `-U` sets both to UTF-8.
+# === Commands
#
-# ### Commands
+# JobManager provides commands to handle the current sessions:
#
-# Please use the `help` command to see the list of available commands.
+# jobs # List of current sessions
+# fg # Switches to the session of the given number
+# kill # Kills the session with the given number
#
-# ### IRB Sessions
+# The +exit+ command, or ::irb_exit, will quit the current session and call any
+# exit hooks with IRB.irb_at_exit.
#
-# IRB has a special feature, that allows you to manage many sessions at once.
+# A few commands for loading files within the session are also available:
#
-# You can create new sessions with Irb.irb, and get a list of current sessions
-# with the `jobs` command in the prompt.
+# +source+::
+# Loads a given file in the current session and displays the source lines,
+# see IrbLoader#source_file
+# +irb_load+::
+# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
+# +irb_require+::
+# Loads the given file similarly to Kernel#require
#
-# #### Configuration
+# === Configuration
#
# The command line options, or IRB.conf, specify the default behavior of
# Irb.irb.
#
-# On the other hand, each conf in IRB@Command-Line+Options is used to
+# On the other hand, each conf in IRB@Command+line+options is used to
# individually configure IRB.irb.
#
-# If a proc is set for `IRB.conf[:IRB_RC]`, its will be invoked after execution
+# If a proc is set for <code>IRB.conf[:IRB_RC]</code>, its will be invoked after execution
# of that proc with the context of the current session as its argument. Each
# session can be configured using this mechanism.
#
-# #### Session variables
+# === Session variables
#
# There are a few variables in every Irb session that can come in handy:
#
-# `_`
-# : The value command executed, as a local variable
-# `__`
-# : The history of evaluated commands. Available only if
-# `IRB.conf[:EVAL_HISTORY]` is not `nil` (which is the default). See also
-# IRB::Context#eval_history= and IRB::History.
-# `__[line_no]`
-# : Returns the evaluation value at the given line number, `line_no`. If
-# `line_no` is a negative, the return value `line_no` many lines before the
-# most recent return value.
-#
-#
-# ## Restrictions
-#
-# Ruby code typed into IRB behaves the same as Ruby code in a file, except that:
-#
-# * Because IRB evaluates input immediately after it is syntactically
-# complete, some results may be slightly different.
-# * Forking may not be well behaved.
-#
+# <code>_</code>::
+# The value command executed, as a local variable
+# <code>__</code>::
+# The history of evaluated commands. Available only if
+# <code>IRB.conf[:EVAL_HISTORY]</code> is not +nil+ (which is the default).
+# See also IRB::Context#eval_history= and IRB::History.
+# <code>__[line_no]</code>::
+# Returns the evaluation value at the given line number, +line_no+.
+# If +line_no+ is a negative, the return value +line_no+ many lines before
+# the most recent return value.
+#
+# === Example using IRB Sessions
+#
+# # invoke a new session
+# irb(main):001:0> irb
+# # list open sessions
+# irb.1(main):001:0> jobs
+# #0->irb on main (#<Thread:0x400fb7e4> : stop)
+# #1->irb#1 on main (#<Thread:0x40125d64> : running)
+#
+# # change the active session
+# irb.1(main):002:0> fg 0
+# # define class Foo in top-level session
+# irb(main):002:0> class Foo;end
+# # invoke a new session with the context of Foo
+# irb(main):003:0> irb Foo
+# # define Foo#foo
+# irb.2(Foo):001:0> def foo
+# irb.2(Foo):002:1> print 1
+# irb.2(Foo):003:1> end
+#
+# # change the active session
+# irb.2(Foo):004:0> fg 0
+# # list open sessions
+# irb(main):004:0> jobs
+# #0->irb on main (#<Thread:0x400fb7e4> : running)
+# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
+# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
+# # check if Foo#foo is available
+# irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
+#
+# # change the active session
+# irb(main):006:0> fg 2
+# # define Foo#bar in the context of Foo
+# irb.2(Foo):005:0> def bar
+# irb.2(Foo):006:1> print "bar"
+# irb.2(Foo):007:1> end
+# irb.2(Foo):010:0> Foo.instance_methods #=> [:bar, :foo, ...]
+#
+# # change the active session
+# irb.2(Foo):011:0> fg 0
+# irb(main):007:0> f = Foo.new #=> #<Foo:0x4010af3c>
+# # invoke a new session with the context of f (instance of Foo)
+# irb(main):008:0> irb f
+# # list open sessions
+# irb.3(<Foo:0x4010af3c>):001:0> jobs
+# #0->irb on main (#<Thread:0x400fb7e4> : stop)
+# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
+# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
+# #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
+# # evaluate f.foo
+# irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
+# # evaluate f.bar
+# irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
+# # kill jobs 1, 2, and 3
+# irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
+# # list open sessions, should only include main session
+# irb(main):009:0> jobs
+# #0->irb on main (#<Thread:0x400fb7e4> : running)
+# # quit irb
+# irb(main):010:0> exit
module IRB
# An exception raised by IRB.irb_abort
class Abort < Exception;end
+ @CONF = {}
+
+
+ # Displays current configuration.
+ #
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
+ #
+ # See IRB@Configuration for more information.
+ def IRB.conf
+ @CONF
+ end
+
+ # Returns the current version of IRB, including release version and last
+ # updated date.
+ def IRB.version
+ if v = @CONF[:VERSION] then return v end
+
+ @CONF[:VERSION] = format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
+ end
+
# The current IRB::Context of the session, see IRB.conf
#
- # irb
- # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
- # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
- def IRB.CurrentContext # :nodoc:
+ # irb
+ # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
+ # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
+ def IRB.CurrentContext
IRB.conf[:MAIN_CONTEXT]
end
- # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
+ # Initializes IRB and creates a new Irb.irb object at the +TOPLEVEL_BINDING+
def IRB.start(ap_path = nil)
STDOUT.sync = true
$0 = File::basename(ap_path, ".rb") if ap_path
@@ -904,49 +421,64 @@ module IRB
irb.run(@CONF)
end
+ # Calls each event hook of <code>IRB.conf[:AT_EXIT]</code> when the current session quits.
+ def IRB.irb_at_exit
+ @CONF[:AT_EXIT].each{|hook| hook.call}
+ end
+
# Quits irb
- def IRB.irb_exit(*) # :nodoc:
- throw :IRB_EXIT, false
+ def IRB.irb_exit(irb, ret)
+ throw :IRB_EXIT, ret
end
# Aborts then interrupts irb.
#
- # Will raise an Abort exception, or the given `exception`.
- def IRB.irb_abort(irb, exception = Abort) # :nodoc:
+ # Will raise an Abort exception, or the given +exception+.
+ def IRB.irb_abort(irb, exception = Abort)
irb.context.thread.raise exception, "abort then interrupt!"
end
class Irb
+ ASSIGNMENT_NODE_TYPES = [
+ # Local, instance, global, class, constant, instance, and index assignment:
+ # "foo = bar",
+ # "@foo = bar",
+ # "$foo = bar",
+ # "@@foo = bar",
+ # "::Foo = bar",
+ # "a::Foo = bar",
+ # "Foo = bar"
+ # "foo.bar = 1"
+ # "foo[1] = bar"
+ :assign,
+
+ # Operation assignment:
+ # "foo += bar"
+ # "foo -= bar"
+ # "foo ||= bar"
+ # "foo &&= bar"
+ :opassign,
+
+ # Multiple assignment:
+ # "foo, bar = 1, 2
+ :massign,
+ ]
# Note: instance and index assignment expressions could also be written like:
- # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former be
- # parsed as :assign and echo will be suppressed, but the latter is parsed as a
- # :method_add_arg and the output won't be suppressed
-
- PROMPT_MAIN_TRUNCATE_LENGTH = 32
- PROMPT_MAIN_TRUNCATE_OMISSION = '...'
- CONTROL_CHARACTERS_PATTERN = "\x00-\x1F"
-
- # Returns the current context of this irb session
- attr_reader :context
- # The lexer used by this irb session
- attr_accessor :scanner
-
- attr_reader :from_binding
+ # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former
+ # be parsed as :assign and echo will be suppressed, but the latter is
+ # parsed as a :method_add_arg and the output won't be suppressed
# Creates a new irb session
- def initialize(workspace = nil, input_method = nil, from_binding: false)
- @from_binding = from_binding
+ def initialize(workspace = nil, input_method = nil)
@context = Context.new(self, workspace, input_method)
- @context.workspace.load_helper_methods_to_main
+ @context.main.extend ExtendCommandBundle
@signal_status = :IN_IRB
@scanner = RubyLex.new
- @line_no = 1
end
- # A hook point for `debug` command's breakpoint after :IRB_EXIT as well as its
- # clean-up
+ # A hook point for `debug` command's TracePoint after :IRB_EXIT as well as its clean-up
def debug_break
- # it means the debug integration has been activated
+ # it means the debug command is executed
if defined?(DEBUGGER__) && DEBUGGER__.respond_to?(:capture_frames_without_irb)
# after leaving this initial breakpoint, revert the capture_frames patch
DEBUGGER__.singleton_class.send(:alias_method, :capture_frames, :capture_frames_without_irb)
@@ -955,101 +487,108 @@ module IRB
end
end
- def debug_readline(binding)
- workspace = IRB::WorkSpace.new(binding)
- context.replace_workspace(workspace)
- context.workspace.load_helper_methods_to_main
- @line_no += 1
-
- # When users run:
- # 1. Debugging commands, like `step 2`
- # 2. Any input that's not irb-command, like `foo = 123`
- #
- #
- # Irb#eval_input will simply return the input, and we need to pass it to the
- # debugger.
- input = nil
- forced_exit = catch(:IRB_EXIT) do
- if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving?
- # Previous IRB session's history has been saved when `Irb#run` is exited We need
- # to make sure the saved history is not saved again by resetting the counter
- context.io.reset_history_counter
-
- begin
- input = eval_input
- ensure
- context.io.save_history
- end
- else
- input = eval_input
- end
- false
- end
-
- Kernel.exit if forced_exit
-
- if input&.include?("\n")
- @line_no += input.count("\n") - 1
- end
-
- input
- end
-
def run(conf = IRB.conf)
- in_nested_session = !!conf[:MAIN_CONTEXT]
conf[:IRB_RC].call(context) if conf[:IRB_RC]
- prev_context = conf[:MAIN_CONTEXT]
conf[:MAIN_CONTEXT] = context
- save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
-
- if save_history
- context.io.load_history
- end
-
prev_trap = trap("SIGINT") do
signal_handle
end
begin
- if defined?(RubyVM.keep_script_lines)
- keep_script_lines_backup = RubyVM.keep_script_lines
- RubyVM.keep_script_lines = true
- end
-
- forced_exit = catch(:IRB_EXIT) do
+ catch(:IRB_EXIT) do
eval_input
end
ensure
- # Do not restore to nil. It will cause IRB crash when used with threads.
- IRB.conf[:MAIN_CONTEXT] = prev_context if prev_context
-
- RubyVM.keep_script_lines = keep_script_lines_backup if defined?(RubyVM.keep_script_lines)
trap("SIGINT", prev_trap)
conf[:AT_EXIT].each{|hook| hook.call}
-
- context.io.save_history if save_history
- Kernel.exit if forced_exit
end
end
+ # Returns the current context of this irb session
+ attr_reader :context
+ # The lexer used by this irb session
+ attr_accessor :scanner
+
# Evaluates input for this session.
def eval_input
- configure_io
+ exc = nil
+
+ @scanner.set_prompt do
+ |ltype, indent, continue, line_no|
+ if ltype
+ f = @context.prompt_s
+ elsif continue
+ f = @context.prompt_c
+ elsif indent > 0
+ f = @context.prompt_n
+ else
+ f = @context.prompt_i
+ end
+ f = "" unless f
+ if @context.prompting?
+ @context.io.prompt = p = prompt(f, ltype, indent, line_no)
+ else
+ @context.io.prompt = p = ""
+ end
+ if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
+ unless ltype
+ prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
+ ind = prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
+ indent * 2 - p.size
+ ind += 2 if continue
+ @context.io.prompt = p + " " * ind if ind > 0
+ end
+ end
+ @context.io.prompt
+ end
- each_top_level_statement do |statement, line_no|
- signal_status(:IN_EVAL) do
- begin
- # If the integration with debugger is activated, we return certain input if it
- # should be dealt with by debugger
- if @context.with_debugger && statement.should_be_handled_by_debugger?
- return statement.code
+ @scanner.set_input(@context.io, context: @context) do
+ signal_status(:IN_INPUT) do
+ if l = @context.io.gets
+ print l if @context.verbose?
+ else
+ if @context.ignore_eof? and @context.io.readable_after_eof?
+ l = "\n"
+ if @context.verbose?
+ printf "Use \"exit\" to leave %s\n", @context.ap_name
+ end
+ else
+ print "\n" if @context.prompting?
end
+ end
+ l
+ end
+ end
- @context.evaluate(statement, line_no)
+ @scanner.set_auto_indent(@context) if @context.auto_indent_mode
- if @context.echo? && !statement.suppresses_echo?
- if statement.is_assignment?
+ @scanner.each_top_level_statement(@context) do |line, line_no|
+ signal_status(:IN_EVAL) do
+ begin
+ line.untaint if RUBY_VERSION < '2.7'
+ if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
+ IRB.set_measure_callback
+ end
+ # Assignment expression check should be done before @context.evaluate to handle code like `a /2#/ if false; a = 1`
+ is_assignment = assignment_expression?(line)
+ if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
+ result = nil
+ last_proc = proc{ result = @context.evaluate(line, line_no, exception: exc) }
+ IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) { |chain, item|
+ _name, callback, arg = item
+ proc {
+ callback.(@context, line, line_no, arg, exception: exc) do
+ chain.call
+ end
+ }
+ }.call
+ @context.set_last_value(result)
+ else
+ @context.evaluate(line, line_no, exception: exc)
+ end
+ if @context.echo?
+ if is_assignment
if @context.echo_on_assignment?
output_value(@context.echo_on_assignment? == :truncate)
end
@@ -1057,157 +596,17 @@ module IRB
output_value
end
end
+ rescue Interrupt => exc
rescue SystemExit, SignalException
raise
- rescue Interrupt, Exception => exc
- handle_exception(exc)
- @context.workspace.local_variable_set(:_, exc)
- end
- end
- end
- end
-
- def read_input(prompt)
- signal_status(:IN_INPUT) do
- @context.io.prompt = prompt
- if l = @context.io.gets
- print l if @context.verbose?
- else
- if @context.ignore_eof? and @context.io.readable_after_eof?
- l = "\n"
- if @context.verbose?
- printf "Use \"exit\" to leave %s\n", @context.ap_name
- end
- else
- print "\n" if @context.prompting?
- end
- end
- l
- end
- end
-
- def readmultiline
- prompt = generate_prompt([], false, 0)
-
- # multiline
- return read_input(prompt) if @context.io.respond_to?(:check_termination)
-
- # nomultiline
- code = +''
- line_offset = 0
- loop do
- line = read_input(prompt)
- unless line
- return code.empty? ? nil : code
- end
-
- code << line
- return code if command?(code)
-
- tokens, opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
- return code if terminated
-
- line_offset += 1
- continue = @scanner.should_continue?(tokens)
- prompt = generate_prompt(opens, continue, line_offset)
- end
- end
-
- def each_top_level_statement
- loop do
- code = readmultiline
- break unless code
- yield build_statement(code), @line_no
- @line_no += code.count("\n")
- rescue RubyLex::TerminateLineInput
- end
- end
-
- def build_statement(code)
- if code.match?(/\A\n*\z/)
- return Statement::EmptyInput.new
- end
-
- code.force_encoding(@context.io.encoding)
- if (command, arg = parse_command(code))
- command_class = Command.load_command(command)
- Statement::Command.new(code, command_class, arg)
- else
- is_assignment_expression = @scanner.assignment_expression?(code, local_variables: @context.local_variables)
- Statement::Expression.new(code, is_assignment_expression)
- end
- end
-
- def parse_command(code)
- command_name, arg = code.strip.split(/\s+/, 2)
- return unless code.lines.size == 1 && command_name
-
- arg ||= ''
- command = command_name.to_sym
- # Command aliases are always command. example: $, @
- if (alias_name = @context.command_aliases[command])
- return [alias_name, arg]
- end
-
- # Check visibility
- public_method = !!Kernel.instance_method(:public_method).bind_call(@context.main, command) rescue false
- private_method = !public_method && !!Kernel.instance_method(:method).bind_call(@context.main, command) rescue false
- if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
- [command, arg]
- end
- end
-
- def command?(code)
- !!parse_command(code)
- end
-
- def configure_io
- if @context.io.respond_to?(:check_termination)
- @context.io.check_termination do |code|
- if Reline::IOGate.in_pasting?
- rest = @scanner.check_termination_in_prev_line(code, local_variables: @context.local_variables)
- if rest
- Reline.delete_text
- rest.bytes.reverse_each do |c|
- Reline.ungetc(c)
- end
- true
- else
- false
- end
+ rescue Exception => exc
else
- next true if command?(code)
-
- _tokens, _opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
- terminated
- end
- end
- end
- if @context.io.respond_to?(:dynamic_prompt)
- @context.io.dynamic_prompt do |lines|
- tokens = RubyLex.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, local_variables: @context.local_variables)
- line_results = IRB::NestingParser.parse_by_line(tokens)
- tokens_until_line = []
- line_results.map.with_index do |(line_tokens, _prev_opens, next_opens, _min_depth), line_num_offset|
- line_tokens.each do |token, _s|
- # Avoid appending duplicated token. Tokens that include "n" like multiline
- # tstring_content can exist in multiple lines.
- tokens_until_line << token if token != tokens_until_line.last
- end
- continue = @scanner.should_continue?(tokens_until_line)
- generate_prompt(next_opens, continue, line_num_offset)
+ exc = nil
+ next
end
- end
- end
-
- if @context.io.respond_to?(:auto_indent) and @context.auto_indent_mode
- @context.io.auto_indent do |lines, line_index, byte_pointer, is_newline|
- next nil if lines == [nil] # Workaround for exit IRB with CTRL+d
- next nil if !is_newline && lines[line_index]&.byteslice(0, byte_pointer)&.match?(/\A\s*\z/)
-
- code = lines[0..line_index].map { |l| "#{l}\n" }.join
- tokens = RubyLex.ripper_lex_without_warning(code, local_variables: @context.local_variables)
- @scanner.process_indent_level(tokens, lines, line_index, is_newline)
+ handle_exception(exc)
+ @context.workspace.local_variable_set(:_, exc)
+ exc = nil
end
end
end
@@ -1242,75 +641,60 @@ module IRB
end
def handle_exception(exc)
- if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
+ if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
!(SyntaxError === exc) && !(EncodingError === exc)
# The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
irb_bug = true
else
irb_bug = false
- # To support backtrace filtering while utilizing Exception#full_message, we need to clone
- # the exception to avoid modifying the original exception's backtrace.
- exc = exc.clone
- filtered_backtrace = exc.backtrace.map { |l| @context.workspace.filter_backtrace(l) }.compact
- backtrace_filter = IRB.conf[:BACKTRACE_FILTER]
-
- if backtrace_filter
- if backtrace_filter.respond_to?(:call)
- filtered_backtrace = backtrace_filter.call(filtered_backtrace)
- else
- warn "IRB.conf[:BACKTRACE_FILTER] #{backtrace_filter} should respond to `call` method"
- end
- end
-
- exc.set_backtrace(filtered_backtrace)
end
- highlight = Color.colorable?
-
- order =
+ if exc.backtrace
+ order = nil
if RUBY_VERSION < '3.0.0'
- STDOUT.tty? ? :bottom : :top
+ if STDOUT.tty?
+ message = exc.full_message(order: :bottom)
+ order = :bottom
+ else
+ message = exc.full_message(order: :top)
+ order = :top
+ end
else # '3.0.0' <= RUBY_VERSION
- :top
+ message = exc.full_message(order: :top)
+ order = :top
end
-
- message = exc.full_message(order: order, highlight: highlight)
- message = convert_invalid_byte_sequence(message, exc.message.encoding)
- message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
- message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
- case order
- when :top
- lines = m.split("\n")
- when :bottom
- lines = m.split("\n").reverse
- end
- unless irb_bug
- if lines.size > @context.back_trace_limit
- omit = lines.size - @context.back_trace_limit
- lines = lines[0..(@context.back_trace_limit - 1)]
- lines << "\t... %d levels..." % omit
+ message = convert_invalid_byte_sequence(message, exc.message.encoding)
+ message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
+ message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
+ case order
+ when :top
+ lines = m.split("\n")
+ when :bottom
+ lines = m.split("\n").reverse
end
- end
- lines = lines.reverse if order == :bottom
- lines.map{ |l| l + "\n" }.join
- }
- # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
- message = message.gsub(/\(irb\):(?<num>\d+):in (?<open_quote>[`'])<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in #{$~[:open_quote]}<main>'" }
- puts message
- puts 'Maybe IRB bug!' if irb_bug
- rescue Exception => handler_exc
- begin
- puts exc.inspect
- puts "backtraces are hidden because #{handler_exc} was raised when processing them"
- rescue Exception
- puts 'Uninspectable exception occurred'
- end
+ unless irb_bug
+ lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
+ if lines.size > @context.back_trace_limit
+ omit = lines.size - @context.back_trace_limit
+ lines = lines[0..(@context.back_trace_limit - 1)]
+ lines << "\t... %d levels..." % omit
+ end
+ end
+ lines = lines.reverse if order == :bottom
+ lines.map{ |l| l + "\n" }.join
+ }
+ # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
+ message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
+ puts message
+ end
+ print "Maybe IRB bug!\n" if irb_bug
end
- # Evaluates the given block using the given `path` as the Context#irb_path and
- # `name` as the Context#irb_name.
+ # Evaluates the given block using the given +path+ as the Context#irb_path
+ # and +name+ as the Context#irb_name.
#
- # Used by the irb command `source`, see IRB@IRB+Sessions for more information.
+ # Used by the irb command +source+, see IRB@IRB+Sessions for more
+ # information.
def suspend_name(path = nil, name = nil)
@context.irb_path, back_path = path, @context.irb_path if path
@context.irb_name, back_name = name, @context.irb_name if name
@@ -1322,22 +706,25 @@ module IRB
end
end
- # Evaluates the given block using the given `workspace` as the
+ # Evaluates the given block using the given +workspace+ as the
# Context#workspace.
#
- # Used by the irb command `irb_load`, see IRB@IRB+Sessions for more information.
+ # Used by the irb command +irb_load+, see IRB@IRB+Sessions for more
+ # information.
def suspend_workspace(workspace)
- current_workspace = @context.workspace
- @context.replace_workspace(workspace)
- yield
- ensure
- @context.replace_workspace current_workspace
+ @context.workspace, back_workspace = workspace, @context.workspace
+ begin
+ yield back_workspace
+ ensure
+ @context.workspace = back_workspace
+ end
end
- # Evaluates the given block using the given `input_method` as the Context#io.
+ # Evaluates the given block using the given +input_method+ as the
+ # Context#io.
#
- # Used by the irb commands `source` and `irb_load`, see IRB@IRB+Sessions for
- # more information.
+ # Used by the irb commands +source+ and +irb_load+, see IRB@IRB+Sessions
+ # for more information.
def suspend_input_method(input_method)
back_io = @context.io
@context.instance_eval{@io = input_method}
@@ -1348,6 +735,16 @@ module IRB
end
end
+ # Evaluates the given block using the given +context+ as the Context.
+ def suspend_context(context)
+ @context, back_context = context, @context
+ begin
+ yield back_context
+ ensure
+ @context = back_context
+ end
+ end
+
# Handler for the signal SIGINT, see Kernel#trap for more information.
def signal_handle
unless @context.ignore_sigint?
@@ -1370,7 +767,7 @@ module IRB
end
end
- # Evaluates the given block using the given `status`.
+ # Evaluates the given block using the given +status+.
def signal_status(status)
return yield if @signal_status == :IN_LOAD
@@ -1383,6 +780,45 @@ module IRB
end
end
+ def prompt(prompt, ltype, indent, line_no) # :nodoc:
+ p = prompt.dup
+ p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
+ case $2
+ when "N"
+ @context.irb_name
+ when "m"
+ @context.main.to_s
+ when "M"
+ @context.main.inspect
+ when "l"
+ ltype
+ when "i"
+ if indent < 0
+ if $1
+ "-".rjust($1.to_i)
+ else
+ "-"
+ end
+ else
+ if $1
+ format("%" + $1 + "d", indent)
+ else
+ indent.to_s
+ end
+ end
+ when "n"
+ if $1
+ format("%" + $1 + "d", line_no)
+ else
+ line_no.to_s
+ end
+ when "%"
+ "%"
+ end
+ end
+ p
+ end
+
def output_value(omit = false) # :nodoc:
str = @context.inspect_last_value
multiline_p = str.include?("\n")
@@ -1412,16 +848,15 @@ module IRB
end
end
end
-
if multiline_p && @context.newline_before_multiline_output?
- str = "\n" + str
+ printf @context.return_format, "\n#{str}"
+ else
+ printf @context.return_format, str
end
-
- Pager.page_content(format(@context.return_format, str), retain_content: true)
end
- # Outputs the local variables to this current session, including #signal_status
- # and #context, using IRB::Locale.
+ # Outputs the local variables to this current session, including
+ # #signal_status and #context, using IRB::Locale.
def inspect
ary = []
for iv in instance_variables
@@ -1437,94 +872,60 @@ module IRB
format("#<%s: %s>", self.class, ary.join(", "))
end
- private
-
- def 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
-
- if ltype
- f = @context.prompt_s
- elsif continue
- f = @context.prompt_c
- else
- f = @context.prompt_i
- end
- f = "" unless f
- if @context.prompting?
- p = format_prompt(f, ltype, indent, line_no)
- else
- p = ""
- end
- if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
- unless ltype
- prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
- ind = format_prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
- indent * 2 - p.size
- p += " " * ind if ind > 0
- end
- end
- p
+ def assignment_expression?(line)
+ # Try to parse the line and check if the last of possibly multiple
+ # expressions is an assignment type.
+
+ # If the expression is invalid, Ripper.sexp should return nil which will
+ # result in false being returned. Any valid expression should return an
+ # s-expression where the second element of the top level array is an
+ # array of parsed expressions. The first element of each expression is the
+ # expression's type.
+ verbose, $VERBOSE = $VERBOSE, nil
+ code = "#{RubyLex.generate_local_variables_assign_code(@context.local_variables) || 'nil;'}\n#{line}"
+ # Get the last node_type of the line. drop(1) is to ignore the local_variables_assign_code part.
+ node_type = Ripper.sexp(code)&.dig(1)&.drop(1)&.dig(-1, 0)
+ ASSIGNMENT_NODE_TYPES.include?(node_type)
+ ensure
+ $VERBOSE = verbose
end
- def truncate_prompt_main(str) # :nodoc:
- str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
- if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH
- str
- else
- str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
- end
- end
+ ATTR_TTY = "\e[%sm"
+ def ATTR_TTY.[](*a) self % a.join(";"); end
+ ATTR_PLAIN = ""
+ def ATTR_PLAIN.[](*) self; end
+ end
- def format_prompt(format, ltype, indent, line_no) # :nodoc:
- format.gsub(/%([0-9]+)?([a-zA-Z%])/) do
- case $2
- when "N"
- @context.irb_name
- when "m"
- main_str = @context.main.to_s rescue "!#{$!.class}"
- truncate_prompt_main(main_str)
- when "M"
- main_str = @context.main.inspect rescue "!#{$!.class}"
- truncate_prompt_main(main_str)
- when "l"
- ltype
- when "i"
- if indent < 0
- if $1
- "-".rjust($1.to_i)
- else
- "-"
- end
- else
- if $1
- format("%" + $1 + "d", indent)
- else
- indent.to_s
- end
- end
- when "n"
- if $1
- format("%" + $1 + "d", line_no)
- else
- line_no.to_s
- end
- when "%"
- "%" unless $1
- end
+ def @CONF.inspect
+ IRB.version unless self[:VERSION]
+
+ array = []
+ for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
+ case k
+ when :MAIN_CONTEXT, :__TMP__EHV__
+ array.push format("CONF[:%s]=...myself...", k.id2name)
+ when :PROMPT
+ s = v.collect{
+ |kk, vv|
+ ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
+ format(":%s=>{%s}", kk.id2name, ss.join(", "))
+ }
+ array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
+ else
+ array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
end
end
+ array.join("\n")
end
end
class Binding
- # Opens an IRB session where `binding.irb` is called which allows for
- # interactive debugging. You can call any methods or variables available in the
- # current scope, and mutate state if you need to.
+ # Opens an IRB session where +binding.irb+ is called which allows for
+ # interactive debugging. You can call any methods or variables available in
+ # the current scope, and mutate state if you need to.
+ #
#
- # Given a Ruby file called `potato.rb` containing the following code:
+ # Given a Ruby file called +potato.rb+ containing the following code:
#
# class Potato
# def initialize
@@ -1536,8 +937,8 @@ class Binding
#
# Potato.new
#
- # Running `ruby potato.rb` will open an IRB session where `binding.irb` is
- # called, and you will see the following:
+ # Running <code>ruby potato.rb</code> will open an IRB session where
+ # +binding.irb+ is called, and you will see the following:
#
# $ ruby potato.rb
#
@@ -1567,42 +968,22 @@ class Binding
# irb(#<Potato:0x00007feea1916670>):004:0> @cooked = true
# => true
#
- # You can exit the IRB session with the `exit` command. Note that exiting will
- # resume execution where `binding.irb` had paused it, as you can see from the
+ # You can exit the IRB session with the +exit+ command. Note that exiting will
+ # resume execution where +binding.irb+ had paused it, as you can see from the
# output printed to standard output in this example:
#
# irb(#<Potato:0x00007feea1916670>):005:0> exit
# Cooked potato: true
#
- # See IRB for more information.
+ #
+ # See IRB@IRB+Usage for more information.
def irb(show_code: true)
- # Setup IRB with the current file's path and no command line arguments
- IRB.setup(source_location[0], argv: []) unless IRB.initialized?
- # Create a new workspace using the current binding
+ IRB.setup(source_location[0], argv: [])
workspace = IRB::WorkSpace.new(self)
- # Print the code around the binding if show_code is true
STDOUT.print(workspace.code_around_binding) if show_code
- # Get the original IRB instance
- debugger_irb = IRB.instance_variable_get(:@debugger_irb)
-
- irb_path = File.expand_path(source_location[0])
-
- if debugger_irb
- # If we're already in a debugger session, set the workspace and irb_path for the original IRB instance
- debugger_irb.context.replace_workspace(workspace)
- debugger_irb.context.irb_path = irb_path
- # If we've started a debugger session and hit another binding.irb, we don't want
- # to start an IRB session instead, we want to resume the irb:rdbg session.
- IRB::Debug.setup(debugger_irb)
- IRB::Debug.insert_debug_break
- debugger_irb.debug_break
- else
- # If we're not in a debugger session, create a new IRB instance with the current
- # workspace
- binding_irb = IRB::Irb.new(workspace, from_binding: true)
- binding_irb.context.irb_path = irb_path
- binding_irb.run(IRB.conf)
- binding_irb.debug_break
- end
+ binding_irb = IRB::Irb.new(workspace)
+ binding_irb.context.irb_path = File.expand_path(source_location[0])
+ binding_irb.run(IRB.conf)
+ binding_irb.debug_break
end
end
diff --git a/lib/irb/cmd/backtrace.rb b/lib/irb/cmd/backtrace.rb
new file mode 100644
index 0000000000..f632894618
--- /dev/null
+++ b/lib/irb/cmd/backtrace.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Backtrace < DebugCommand
+ def self.transform_args(args)
+ args&.dump
+ end
+
+ def execute(*args)
+ super(pre_cmds: ["backtrace", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/break.rb b/lib/irb/cmd/break.rb
new file mode 100644
index 0000000000..df259a90ca
--- /dev/null
+++ b/lib/irb/cmd/break.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Break < DebugCommand
+ def self.transform_args(args)
+ args&.dump
+ end
+
+ def execute(args = nil)
+ super(pre_cmds: "break #{args}")
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/catch.rb b/lib/irb/cmd/catch.rb
new file mode 100644
index 0000000000..40b62c7533
--- /dev/null
+++ b/lib/irb/cmd/catch.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Catch < DebugCommand
+ def self.transform_args(args)
+ args&.dump
+ end
+
+ def execute(*args)
+ super(pre_cmds: ["catch", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/chws.rb b/lib/irb/cmd/chws.rb
new file mode 100644
index 0000000000..7c84ba0a4b
--- /dev/null
+++ b/lib/irb/cmd/chws.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: false
+#
+# change-ws.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require_relative "nop"
+require_relative "../ext/change-ws"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+
+ class CurrentWorkingWorkspace < Nop
+ category "IRB"
+ description "Show the current workspace."
+
+ def execute(*obj)
+ irb_context.main
+ end
+ end
+
+ class ChangeWorkspace < Nop
+ category "IRB"
+ description "Change the current workspace to an object."
+
+ def execute(*obj)
+ irb_context.change_workspace(*obj)
+ irb_context.main
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/continue.rb b/lib/irb/cmd/continue.rb
new file mode 100644
index 0000000000..9136177eef
--- /dev/null
+++ b/lib/irb/cmd/continue.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Continue < DebugCommand
+ def execute(*args)
+ super(do_cmds: ["continue", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/debug.rb b/lib/irb/cmd/debug.rb
new file mode 100644
index 0000000000..7d39b9fa27
--- /dev/null
+++ b/lib/irb/cmd/debug.rb
@@ -0,0 +1,136 @@
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Debug < Nop
+ category "Debugging"
+ description "Start the debugger of debug.gem."
+
+ BINDING_IRB_FRAME_REGEXPS = [
+ '<internal:prelude>',
+ binding.method(:irb).source_location.first,
+ ].map { |file| /\A#{Regexp.escape(file)}:\d+:in `irb'\z/ }
+ IRB_DIR = File.expand_path('..', __dir__)
+
+ def execute(pre_cmds: nil, do_cmds: nil)
+ unless binding_irb?
+ puts "`debug` command is only available when IRB is started with binding.irb"
+ return
+ end
+
+ unless setup_debugger
+ puts <<~MSG
+ You need to install the debug gem before using this command.
+ If you use `bundle exec`, please add `gem "debug"` into your Gemfile.
+ MSG
+ return
+ end
+
+ options = { oneshot: true, hook_call: false }
+ if pre_cmds || do_cmds
+ options[:command] = ['irb', pre_cmds, do_cmds]
+ end
+ if DEBUGGER__::LineBreakpoint.instance_method(:initialize).parameters.include?([:key, :skip_src])
+ options[:skip_src] = true
+ end
+
+ # To make debugger commands like `next` or `continue` work without asking
+ # the user to quit IRB after that, we need to exit IRB first and then hit
+ # a TracePoint on #debug_break.
+ file, lineno = IRB::Irb.instance_method(:debug_break).source_location
+ DEBUGGER__::SESSION.add_line_breakpoint(file, lineno + 1, **options)
+ # exit current Irb#run call
+ throw :IRB_EXIT
+ end
+
+ private
+
+ def binding_irb?
+ caller.any? do |frame|
+ BINDING_IRB_FRAME_REGEXPS.any? do |regexp|
+ frame.match?(regexp)
+ end
+ end
+ end
+
+ module SkipPathHelperForIRB
+ def skip_internal_path?(path)
+ # The latter can be removed once https://github.com/ruby/debug/issues/866 is resolved
+ super || path.match?(IRB_DIR) || path.match?('<internal:prelude>')
+ end
+ end
+
+ def setup_debugger
+ unless defined?(DEBUGGER__::SESSION)
+ begin
+ require "debug/session"
+ rescue LoadError # debug.gem is not written in Gemfile
+ return false unless load_bundled_debug_gem
+ end
+ DEBUGGER__.start(nonstop: true)
+ end
+
+ unless DEBUGGER__.respond_to?(:capture_frames_without_irb)
+ DEBUGGER__.singleton_class.send(:alias_method, :capture_frames_without_irb, :capture_frames)
+
+ def DEBUGGER__.capture_frames(*args)
+ frames = capture_frames_without_irb(*args)
+ frames.reject! do |frame|
+ frame.realpath&.start_with?(IRB_DIR) || frame.path == "<internal:prelude>"
+ end
+ frames
+ end
+
+ DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
+ end
+
+ true
+ end
+
+ # This is used when debug.gem is not written in Gemfile. Even if it's not
+ # installed by `bundle install`, debug.gem is installed by default because
+ # it's a bundled gem. This method tries to activate and load that.
+ def load_bundled_debug_gem
+ # Discover latest debug.gem under GEM_PATH
+ debug_gem = Gem.paths.path.flat_map { |path| Dir.glob("#{path}/gems/debug-*") }.select do |path|
+ File.basename(path).match?(/\Adebug-\d+\.\d+\.\d+(\w+)?\z/)
+ end.sort_by do |path|
+ Gem::Version.new(File.basename(path).delete_prefix('debug-'))
+ end.last
+ return false unless debug_gem
+
+ # Discover debug/debug.so under extensions for Ruby 3.2+
+ ext_name = "/debug/debug.#{RbConfig::CONFIG['DLEXT']}"
+ ext_path = Gem.paths.path.flat_map do |path|
+ Dir.glob("#{path}/extensions/**/#{File.basename(debug_gem)}#{ext_name}")
+ end.first
+
+ # Attempt to forcibly load the bundled gem
+ if ext_path
+ $LOAD_PATH << ext_path.delete_suffix(ext_name)
+ end
+ $LOAD_PATH << "#{debug_gem}/lib"
+ begin
+ require "debug/session"
+ puts "Loaded #{File.basename(debug_gem)}"
+ true
+ rescue LoadError
+ false
+ end
+ end
+ end
+
+ class DebugCommand < Debug
+ def self.category
+ "Debugging"
+ end
+
+ def self.description
+ command_name = self.name.split("::").last.downcase
+ "Start the debugger of debug.gem and run its `#{command_name}` command."
+ end
+ end
+ end
+end
diff --git a/lib/irb/cmd/delete.rb b/lib/irb/cmd/delete.rb
new file mode 100644
index 0000000000..aeb26d2572
--- /dev/null
+++ b/lib/irb/cmd/delete.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Delete < DebugCommand
+ def execute(*args)
+ super(pre_cmds: ["delete", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/edit.rb b/lib/irb/cmd/edit.rb
new file mode 100644
index 0000000000..0103891cf4
--- /dev/null
+++ b/lib/irb/cmd/edit.rb
@@ -0,0 +1,61 @@
+require 'shellwords'
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Edit < Nop
+ category "Misc"
+ description 'Open a file with the editor command defined with `ENV["EDITOR"]`.'
+
+ class << self
+ def transform_args(args)
+ # Return a string literal as is for backward compatibility
+ if args.nil? || args.empty? || string_literal?(args)
+ args
+ else # Otherwise, consider the input as a String for convenience
+ args.strip.dump
+ end
+ end
+ end
+
+ def execute(*args)
+ path = args.first
+
+ if path.nil? && (irb_path = @irb_context.irb_path)
+ path = irb_path
+ end
+
+ if !File.exist?(path)
+ require_relative "show_source"
+
+ source =
+ begin
+ ShowSource.find_source(path, @irb_context)
+ rescue NameError
+ # if user enters a path that doesn't exist, it'll cause NameError when passed here because find_source would try to evaluate it as well
+ # in this case, we should just ignore the error
+ end
+
+ if source && File.exist?(source.file)
+ path = source.file
+ else
+ puts "Can not find file: #{path}"
+ return
+ end
+ end
+
+ if editor = ENV['EDITOR']
+ puts "command: '#{editor}'"
+ puts " path: #{path}"
+ system(*Shellwords.split(editor), path)
+ else
+ puts "Can not find editor setting: ENV['EDITOR']"
+ end
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/finish.rb b/lib/irb/cmd/finish.rb
new file mode 100644
index 0000000000..29f100feb5
--- /dev/null
+++ b/lib/irb/cmd/finish.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Finish < DebugCommand
+ def execute(*args)
+ super(do_cmds: ["finish", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/fork.rb b/lib/irb/cmd/fork.rb
new file mode 100644
index 0000000000..255a670dce
--- /dev/null
+++ b/lib/irb/cmd/fork.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: false
+#
+# fork.rb -
+# $Release Version: 0.9.6 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Fork < Nop
+ def execute
+ pid = __send__ ExtendCommand.irb_original_method_name("fork")
+ unless pid
+ class << self
+ alias_method :exit, ExtendCommand.irb_original_method_name('exit')
+ end
+ if block_given?
+ begin
+ yield
+ ensure
+ exit
+ end
+ end
+ end
+ pid
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/help.rb b/lib/irb/cmd/help.rb
new file mode 100644
index 0000000000..2a135cdb14
--- /dev/null
+++ b/lib/irb/cmd/help.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: false
+#
+# help.rb - helper using ri
+# $Release Version: 0.9.6$
+# $Revision$
+#
+# --
+#
+#
+#
+
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Help < Nop
+ class << self
+ def transform_args(args)
+ # Return a string literal as is for backward compatibility
+ if args.empty? || string_literal?(args)
+ args
+ else # Otherwise, consider the input as a String for convenience
+ args.strip.dump
+ end
+ end
+ end
+
+ category "Context"
+ description "Enter the mode to look up RI documents."
+
+ def execute(*names)
+ require 'rdoc/ri/driver'
+ opts = RDoc::RI::Driver.process_args([])
+ IRB::ExtendCommand::Help.const_set(:Ri, RDoc::RI::Driver.new(opts))
+ rescue LoadError, SystemExit
+ IRB::ExtendCommand::Help.remove_method(:execute)
+ # raise NoMethodError in ensure
+ else
+ def execute(*names)
+ if names.empty?
+ Ri.interactive
+ return
+ end
+ names.each do |name|
+ begin
+ Ri.display_name(name.to_s)
+ rescue RDoc::RI::Error
+ puts $!.message
+ end
+ end
+ nil
+ end
+ nil
+ ensure
+ execute(*names)
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/info.rb b/lib/irb/cmd/info.rb
new file mode 100644
index 0000000000..2c0a32b34f
--- /dev/null
+++ b/lib/irb/cmd/info.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Info < DebugCommand
+ def self.transform_args(args)
+ args&.dump
+ end
+
+ def execute(*args)
+ super(pre_cmds: ["info", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/irb_info.rb b/lib/irb/cmd/irb_info.rb
new file mode 100644
index 0000000000..da11e8d40b
--- /dev/null
+++ b/lib/irb/cmd/irb_info.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: false
+
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class IrbInfo < Nop
+ category "IRB"
+ description "Show information about IRB."
+
+ def execute
+ Class.new {
+ def inspect
+ str = "Ruby version: #{RUBY_VERSION}\n"
+ str += "IRB version: #{IRB.version}\n"
+ str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
+ str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
+ str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
+ str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
+ str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
+ str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
+ if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
+ codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
+ str += "Code page: #{codepage}\n"
+ end
+ str
+ end
+ alias_method :to_s, :inspect
+ }.new
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/load.rb b/lib/irb/cmd/load.rb
new file mode 100644
index 0000000000..2897bbd975
--- /dev/null
+++ b/lib/irb/cmd/load.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: false
+#
+# load.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require_relative "nop"
+require_relative "../ext/loader"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class LoaderCommand < Nop
+ include IrbLoader
+
+ def raise_cmd_argument_error
+ raise CommandArgumentError.new("Please specify the file name.")
+ end
+ end
+
+ class Load < LoaderCommand
+ category "IRB"
+ description "Load a Ruby file."
+
+ def execute(file_name = nil, priv = nil)
+ raise_cmd_argument_error unless file_name
+ irb_load(file_name, priv)
+ end
+ end
+
+ class Require < LoaderCommand
+ category "IRB"
+ description "Require a Ruby file."
+ def execute(file_name = nil)
+ raise_cmd_argument_error unless file_name
+
+ rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
+ return false if $".find{|f| f =~ rex}
+
+ case file_name
+ when /\.rb$/
+ begin
+ if irb_load(file_name)
+ $".push file_name
+ return true
+ end
+ rescue LoadError
+ end
+ when /\.(so|o|sl)$/
+ return ruby_require(file_name)
+ end
+
+ begin
+ irb_load(f = file_name + ".rb")
+ $".push f
+ return true
+ rescue LoadError
+ return ruby_require(file_name)
+ end
+ end
+ end
+
+ class Source < LoaderCommand
+ category "IRB"
+ description "Loads a given file in the current session."
+
+ def execute(file_name = nil)
+ raise_cmd_argument_error unless file_name
+
+ source_file(file_name)
+ end
+ end
+ end
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb
new file mode 100644
index 0000000000..b65fae2bf1
--- /dev/null
+++ b/lib/irb/cmd/ls.rb
@@ -0,0 +1,116 @@
+# frozen_string_literal: true
+
+require "reline"
+require_relative "nop"
+require_relative "../color"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Ls < Nop
+ category "Context"
+ description "Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output."
+
+ def self.transform_args(args)
+ if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
+ args = match[:args]
+ "#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
+ else
+ args
+ end
+ end
+
+ def execute(*arg, grep: nil)
+ o = Output.new(grep: grep)
+
+ obj = arg.empty? ? irb_context.workspace.main : arg.first
+ locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
+ klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
+
+ o.dump("constants", obj.constants) if obj.respond_to?(:constants)
+ dump_methods(o, klass, obj)
+ o.dump("instance variables", obj.instance_variables)
+ o.dump("class variables", klass.class_variables)
+ o.dump("locals", locals)
+ nil
+ end
+
+ def dump_methods(o, klass, obj)
+ singleton_class = begin obj.singleton_class; rescue TypeError; nil end
+ maps = class_method_map((singleton_class || klass).ancestors)
+ maps.each do |mod, methods|
+ name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
+ o.dump(name, methods)
+ end
+ end
+
+ def class_method_map(classes)
+ dumped = Array.new
+ classes.reject { |mod| mod >= Object }.map do |mod|
+ methods = mod.public_instance_methods(false).select do |m|
+ dumped.push(m) unless dumped.include?(m)
+ end
+ [mod, methods]
+ end.reverse
+ end
+
+ class Output
+ MARGIN = " "
+
+ def initialize(grep: nil)
+ @grep = grep
+ @line_width = screen_width - MARGIN.length # right padding
+ end
+
+ def dump(name, strs)
+ strs = strs.grep(@grep) if @grep
+ strs = strs.sort
+ return if strs.empty?
+
+ # Attempt a single line
+ print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
+ if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
+ puts strs.join(MARGIN)
+ return
+ end
+ puts
+
+ # Dump with the largest # of columns that fits on a line
+ cols = strs.size
+ until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
+ cols -= 1
+ end
+ widths = col_widths(strs, cols: cols)
+ strs.each_slice(cols) do |ss|
+ puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
+ end
+ end
+
+ private
+
+ def fits_on_line?(strs, cols:, offset: 0)
+ width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
+ width <= @line_width - offset
+ end
+
+ def col_widths(strs, cols:)
+ cols.times.map do |col|
+ (col...strs.size).step(cols).map do |i|
+ strs[i].length
+ end.max
+ end
+ end
+
+ def screen_width
+ Reline.get_screen_size.last
+ rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
+ 80
+ end
+ end
+ private_constant :Output
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/measure.rb b/lib/irb/cmd/measure.rb
new file mode 100644
index 0000000000..9122e2dac9
--- /dev/null
+++ b/lib/irb/cmd/measure.rb
@@ -0,0 +1,48 @@
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Measure < Nop
+ category "Misc"
+ description "`measure` enables the mode to measure processing time. `measure :off` disables it."
+
+ def initialize(*args)
+ super(*args)
+ end
+
+ def execute(type = nil, arg = nil, &block)
+ # Please check IRB.init_config in lib/irb/init.rb that sets
+ # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
+ # "measure :time" (abbreviated as "measure") and "measure :stackprof".
+ case type
+ when :off
+ IRB.conf[:MEASURE] = nil
+ IRB.unset_measure_callback(arg)
+ when :list
+ IRB.conf[:MEASURE_CALLBACKS].each do |type_name, _, arg_val|
+ puts "- #{type_name}" + (arg_val ? "(#{arg_val.inspect})" : '')
+ end
+ when :on
+ IRB.conf[:MEASURE] = true
+ added = IRB.set_measure_callback(type, arg)
+ puts "#{added[0]} is added." if added
+ else
+ if block_given?
+ IRB.conf[:MEASURE] = true
+ added = IRB.set_measure_callback(&block)
+ puts "#{added[0]} is added." if added
+ else
+ IRB.conf[:MEASURE] = true
+ added = IRB.set_measure_callback(type, arg)
+ puts "#{added[0]} is added." if added
+ end
+ end
+ nil
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/next.rb b/lib/irb/cmd/next.rb
new file mode 100644
index 0000000000..d29c82e7fc
--- /dev/null
+++ b/lib/irb/cmd/next.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Next < DebugCommand
+ def execute(*args)
+ super(do_cmds: ["next", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/nop.rb b/lib/irb/cmd/nop.rb
index 9d2e3c4d47..c616c054a8 100644
--- a/lib/irb/cmd/nop.rb
+++ b/lib/irb/cmd/nop.rb
@@ -1,4 +1,71 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
+#
+# nop.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+module IRB
+ # :stopdoc:
-# This file is just a placeholder for backward-compatibility.
-# Please require 'irb' and inherit your command from `IRB::Command::Base` instead.
+ module ExtendCommand
+ class CommandArgumentError < StandardError; end
+
+ class Nop
+ class << self
+ def category(category = nil)
+ @category = category if category
+ @category
+ end
+
+ def description(description = nil)
+ @description = description if description
+ @description
+ end
+
+ private
+
+ def string_literal?(args)
+ sexp = Ripper.sexp(args)
+ sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
+ end
+ end
+
+ if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
+ def self.execute(conf, *opts, **kwargs, &block)
+ command = new(conf)
+ command.execute(*opts, **kwargs, &block)
+ rescue CommandArgumentError => e
+ puts e.message
+ end
+ else
+ def self.execute(conf, *opts, &block)
+ command = new(conf)
+ command.execute(*opts, &block)
+ rescue CommandArgumentError => e
+ puts e.message
+ end
+ end
+
+ def initialize(conf)
+ @irb_context = conf
+ end
+
+ attr_reader :irb_context
+
+ def irb
+ @irb_context.irb
+ end
+
+ def execute(*opts)
+ #nop
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/pushws.rb b/lib/irb/cmd/pushws.rb
new file mode 100644
index 0000000000..41d2e705f1
--- /dev/null
+++ b/lib/irb/cmd/pushws.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: false
+#
+# change-ws.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require_relative "nop"
+require_relative "../ext/workspaces"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Workspaces < Nop
+ category "IRB"
+ description "Show workspaces."
+
+ def execute(*obj)
+ irb_context.workspaces.collect{|ws| ws.main}
+ end
+ end
+
+ class PushWorkspace < Workspaces
+ category "IRB"
+ description "Push an object to the workspace stack."
+
+ def execute(*obj)
+ irb_context.push_workspace(*obj)
+ super
+ end
+ end
+
+ class PopWorkspace < Workspaces
+ category "IRB"
+ description "Pop a workspace from the workspace stack."
+
+ def execute(*obj)
+ irb_context.pop_workspace(*obj)
+ super
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/show_cmds.rb b/lib/irb/cmd/show_cmds.rb
new file mode 100644
index 0000000000..acced27d48
--- /dev/null
+++ b/lib/irb/cmd/show_cmds.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require "stringio"
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class ShowCmds < Nop
+ category "IRB"
+ description "List all available commands and their description."
+
+ def execute(*args)
+ commands_info = IRB::ExtendCommandBundle.all_commands_info
+ commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
+ longest_cmd_name_length = commands_info.map { |c| c[:display_name] }.max { |a, b| a.length <=> b.length }.length
+
+ output = StringIO.new
+
+ commands_grouped_by_categories.each do |category, cmds|
+ output.puts Color.colorize(category, [:BOLD])
+
+ cmds.each do |cmd|
+ output.puts " #{cmd[:display_name].to_s.ljust(longest_cmd_name_length)} #{cmd[:description]}"
+ end
+
+ output.puts
+ end
+
+ puts output.string
+
+ nil
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/show_source.rb b/lib/irb/cmd/show_source.rb
new file mode 100644
index 0000000000..ea700be4bf
--- /dev/null
+++ b/lib/irb/cmd/show_source.rb
@@ -0,0 +1,112 @@
+# frozen_string_literal: true
+
+require_relative "nop"
+require_relative "../color"
+require_relative "../ruby-lex"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class ShowSource < Nop
+ category "Context"
+ description "Show the source code of a given method or constant."
+
+ class << self
+ def transform_args(args)
+ # Return a string literal as is for backward compatibility
+ if args.empty? || string_literal?(args)
+ args
+ else # Otherwise, consider the input as a String for convenience
+ args.strip.dump
+ end
+ end
+
+ def find_source(str, irb_context)
+ case str
+ when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
+ eval(str, irb_context.workspace.binding) # trigger autoload
+ base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
+ file, line = base.const_source_location(str) if base.respond_to?(:const_source_location) # Ruby 2.7+
+ when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
+ owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
+ method = Regexp.last_match[:method]
+ if owner.respond_to?(:instance_method) && owner.instance_methods.include?(method.to_sym)
+ file, line = owner.instance_method(method).source_location
+ end
+ when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
+ receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
+ method = Regexp.last_match[:method]
+ file, line = receiver.method(method).source_location if receiver.respond_to?(method)
+ end
+ if file && line
+ Source.new(file: file, first_line: line, last_line: find_end(file, line))
+ end
+ end
+
+ private
+
+ def find_end(file, first_line)
+ return first_line unless File.exist?(file)
+ lex = RubyLex.new
+ lines = File.read(file).lines[(first_line - 1)..-1]
+ tokens = RubyLex.ripper_lex_without_warning(lines.join)
+ prev_tokens = []
+
+ # chunk with line number
+ tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
+ code = lines[0..lnum].join
+ prev_tokens.concat chunk
+ continue = lex.process_continue(prev_tokens)
+ code_block_open = lex.check_code_block(code, prev_tokens)
+ if !continue && !code_block_open
+ return first_line + lnum
+ end
+ end
+ first_line
+ end
+ end
+
+ def execute(str = nil)
+ unless str.is_a?(String)
+ puts "Error: Expected a string but got #{str.inspect}"
+ return
+ end
+
+ source = self.class.find_source(str, @irb_context)
+ if source && File.exist?(source.file)
+ show_source(source)
+ else
+ puts "Error: Couldn't locate a definition for #{str}"
+ end
+ nil
+ end
+
+ private
+
+ # @param [IRB::ExtendCommand::ShowSource::Source] source
+ def show_source(source)
+ puts
+ puts "#{bold("From")}: #{source.file}:#{source.first_line}"
+ puts
+ code = IRB::Color.colorize_code(File.read(source.file))
+ puts code.lines[(source.first_line - 1)...source.last_line].join
+ puts
+ end
+
+ def bold(str)
+ Color.colorize(str, [:BOLD])
+ end
+
+ Source = Struct.new(
+ :file, # @param [String] - file name
+ :first_line, # @param [String] - first line
+ :last_line, # @param [String] - last line
+ keyword_init: true,
+ )
+ private_constant :Source
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/step.rb b/lib/irb/cmd/step.rb
new file mode 100644
index 0000000000..2bc74a9d79
--- /dev/null
+++ b/lib/irb/cmd/step.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative "debug"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Step < DebugCommand
+ def execute(*args)
+ super(do_cmds: ["step", *args].join(" "))
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/subirb.rb b/lib/irb/cmd/subirb.rb
new file mode 100644
index 0000000000..699b35fcb4
--- /dev/null
+++ b/lib/irb/cmd/subirb.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: false
+# multi.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class MultiIRBCommand < Nop
+ def initialize(conf)
+ super
+ extend_irb_context
+ end
+
+ private
+
+ def extend_irb_context
+ # this extension patches IRB context like IRB.CurrentContext
+ require_relative "../ext/multi-irb"
+ end
+ end
+
+ class IrbCommand < MultiIRBCommand
+ category "IRB"
+ description "Start a child IRB."
+
+ def execute(*obj)
+ IRB.irb(nil, *obj)
+ end
+ end
+
+ class Jobs < MultiIRBCommand
+ category "IRB"
+ description "List of current sessions."
+
+ def execute
+ IRB.JobManager
+ end
+ end
+
+ class Foreground < MultiIRBCommand
+ category "IRB"
+ description "Switches to the session of the given number."
+
+ def execute(key = nil)
+ raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key
+ IRB.JobManager.switch(key)
+ end
+ end
+
+ class Kill < MultiIRBCommand
+ category "IRB"
+ description "Kills the session with the given number."
+
+ def execute(*keys)
+ IRB.JobManager.kill(*keys)
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/cmd/whereami.rb b/lib/irb/cmd/whereami.rb
new file mode 100644
index 0000000000..8f56ba073d
--- /dev/null
+++ b/lib/irb/cmd/whereami.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require_relative "nop"
+
+module IRB
+ # :stopdoc:
+
+ module ExtendCommand
+ class Whereami < Nop
+ category "Context"
+ description "Show the source code around binding.irb again."
+
+ def execute(*)
+ code = irb_context.workspace.code_around_binding
+ if code
+ puts code
+ else
+ puts "The current context doesn't have code."
+ end
+ end
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/color.rb b/lib/irb/color.rb
index fca942b28b..6378e14856 100644
--- a/lib/irb/color.rb
+++ b/lib/irb/color.rb
@@ -9,14 +9,12 @@ module IRB # :nodoc:
BOLD = 1
UNDERLINE = 4
REVERSE = 7
- BLACK = 30
RED = 31
GREEN = 32
YELLOW = 33
BLUE = 34
MAGENTA = 35
CYAN = 36
- WHITE = 37
TOKEN_KEYWORDS = {
on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__', '__ENCODING__'],
@@ -79,12 +77,12 @@ module IRB # :nodoc:
class << self
def colorable?
- supported = $stdout.tty? && (/mswin|mingw/.match?(RUBY_PLATFORM) || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
+ supported = $stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
# because ruby/debug also uses irb's color module selectively,
# irb won't be activated in that case.
if IRB.respond_to?(:conf)
- supported && !!IRB.conf.fetch(:USE_COLORIZE, true)
+ supported && IRB.conf.fetch(:USE_COLORIZE, true)
else
supported
end
@@ -199,9 +197,15 @@ module IRB # :nodoc:
end
end
- lexer.scan.each do |elem|
- next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
- on_scan.call(elem)
+ if lexer.respond_to?(:scan) # Ruby 2.7+
+ lexer.scan.each do |elem|
+ next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
+ on_scan.call(elem)
+ end
+ else
+ lexer.parse.sort_by(&:pos).each do |elem|
+ on_scan.call(elem)
+ end
end
# yield uncolorable DATA section
yield(nil, inner_code.byteslice(byte_pos...inner_code.bytesize), nil) if byte_pos < inner_code.bytesize
@@ -238,7 +242,7 @@ module IRB # :nodoc:
case token
when :on_symbeg, :on_symbols_beg, :on_qsymbols_beg
@stack << true
- when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw, :on_backtick
+ when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw
if @stack.last # Pop only when it's Symbol
@stack.pop
return prev_state
diff --git a/lib/irb/color_printer.rb b/lib/irb/color_printer.rb
index 31644aa7f9..1127bcecb4 100644
--- a/lib/irb/color_printer.rb
+++ b/lib/irb/color_printer.rb
@@ -4,9 +4,6 @@ require_relative 'color'
module IRB
class ColorPrinter < ::PP
- METHOD_RESPOND_TO = Object.instance_method(:respond_to?)
- METHOD_INSPECT = Object.instance_method(:inspect)
-
class << self
def pp(obj, out = $>, width = screen_width)
q = ColorPrinter.new(out, width)
@@ -25,11 +22,9 @@ module IRB
end
def pp(obj)
- if String === obj
+ if obj.is_a?(String)
# Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
text(obj.inspect)
- elsif !METHOD_RESPOND_TO.bind(obj).call(:inspect)
- text(METHOD_INSPECT.bind(obj).call)
else
super
end
diff --git a/lib/irb/command.rb b/lib/irb/command.rb
deleted file mode 100644
index 68a4b52727..0000000000
--- a/lib/irb/command.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-#
-# irb/command.rb - irb command
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-
-require_relative "command/base"
-
-module IRB # :nodoc:
- module Command
- @commands = {}
-
- class << self
- attr_reader :commands
-
- # Registers a command with the given name.
- # Aliasing is intentionally not supported at the moment.
- def register(name, command_class)
- @commands[name.to_sym] = [command_class, []]
- end
- end
- end
-end
diff --git a/lib/irb/command/backtrace.rb b/lib/irb/command/backtrace.rb
deleted file mode 100644
index 687bb075ac..0000000000
--- a/lib/irb/command/backtrace.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Backtrace < DebugCommand
- def execute(arg)
- execute_debug_command(pre_cmds: "backtrace #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/base.rb b/lib/irb/command/base.rb
deleted file mode 100644
index 1d406630a2..0000000000
--- a/lib/irb/command/base.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-#
-# nop.rb -
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-
-module IRB
- # :stopdoc:
-
- module Command
- class CommandArgumentError < StandardError; end
-
- def self.extract_ruby_args(*args, **kwargs)
- throw :EXTRACT_RUBY_ARGS, [args, kwargs]
- end
-
- class Base
- class << self
- def category(category = nil)
- @category = category if category
- @category || "No category"
- end
-
- def description(description = nil)
- @description = description if description
- @description || "No description provided."
- end
-
- def help_message(help_message = nil)
- @help_message = help_message if help_message
- @help_message
- end
-
- private
-
- def highlight(text)
- Color.colorize(text, [:BOLD, :BLUE])
- end
- end
-
- def self.execute(irb_context, arg)
- new(irb_context).execute(arg)
- rescue CommandArgumentError => e
- puts e.message
- end
-
- def initialize(irb_context)
- @irb_context = irb_context
- end
-
- attr_reader :irb_context
-
- def execute(arg)
- #nop
- end
- end
-
- Nop = Base
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/break.rb b/lib/irb/command/break.rb
deleted file mode 100644
index a8f81fe665..0000000000
--- a/lib/irb/command/break.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Break < DebugCommand
- def execute(arg)
- execute_debug_command(pre_cmds: "break #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/catch.rb b/lib/irb/command/catch.rb
deleted file mode 100644
index 529dcbca5a..0000000000
--- a/lib/irb/command/catch.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Catch < DebugCommand
- def execute(arg)
- execute_debug_command(pre_cmds: "catch #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/chws.rb b/lib/irb/command/chws.rb
deleted file mode 100644
index ef456d0961..0000000000
--- a/lib/irb/command/chws.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-#
-# change-ws.rb -
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-require_relative "../ext/change-ws"
-
-module IRB
- # :stopdoc:
-
- module Command
-
- class CurrentWorkingWorkspace < Base
- category "Workspace"
- description "Show the current workspace."
-
- def execute(_arg)
- puts "Current workspace: #{irb_context.main}"
- end
- end
-
- class ChangeWorkspace < Base
- category "Workspace"
- description "Change the current workspace to an object."
-
- def execute(arg)
- if arg.empty?
- irb_context.change_workspace
- else
- obj = eval(arg, irb_context.workspace.binding)
- irb_context.change_workspace(obj)
- end
-
- puts "Current workspace: #{irb_context.main}"
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/context.rb b/lib/irb/command/context.rb
deleted file mode 100644
index b4fc807343..0000000000
--- a/lib/irb/command/context.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- module Command
- class Context < Base
- category "IRB"
- description "Displays current configuration."
-
- def execute(_arg)
- # This command just displays the configuration.
- # Modifying the configuration is achieved by sending a message to IRB.conf.
- Pager.page_content(IRB.CurrentContext.inspect)
- end
- end
- end
-end
diff --git a/lib/irb/command/continue.rb b/lib/irb/command/continue.rb
deleted file mode 100644
index 0daa029b15..0000000000
--- a/lib/irb/command/continue.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Continue < DebugCommand
- def execute(arg)
- execute_debug_command(do_cmds: "continue #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/debug.rb b/lib/irb/command/debug.rb
deleted file mode 100644
index 8a091a49ed..0000000000
--- a/lib/irb/command/debug.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-require_relative "../debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Debug < Base
- category "Debugging"
- description "Start the debugger of debug.gem."
-
- def execute(_arg)
- execute_debug_command
- end
-
- def execute_debug_command(pre_cmds: nil, do_cmds: nil)
- pre_cmds = pre_cmds&.rstrip
- do_cmds = do_cmds&.rstrip
-
- if irb_context.with_debugger
- # If IRB is already running with a debug session, throw the command and IRB.debug_readline will pass it to the debugger.
- if cmd = pre_cmds || do_cmds
- throw :IRB_EXIT, cmd
- else
- puts "IRB is already running with a debug session."
- return
- end
- else
- # If IRB is not running with a debug session yet, then:
- # 1. Check if the debugging command is run from a `binding.irb` call.
- # 2. If so, try setting up the debug gem.
- # 3. Insert a debug breakpoint at `Irb#debug_break` with the intended command.
- # 4. Exit the current Irb#run call via `throw :IRB_EXIT`.
- # 5. `Irb#debug_break` will be called and trigger the breakpoint, which will run the intended command.
- unless irb_context.from_binding?
- puts "Debugging commands are only available when IRB is started with binding.irb"
- return
- end
-
- if IRB.respond_to?(:JobManager)
- warn "Can't start the debugger when IRB is running in a multi-IRB session."
- return
- end
-
- unless IRB::Debug.setup(irb_context.irb)
- puts <<~MSG
- You need to install the debug gem before using this command.
- If you use `bundle exec`, please add `gem "debug"` into your Gemfile.
- MSG
- return
- end
-
- IRB::Debug.insert_debug_break(pre_cmds: pre_cmds, do_cmds: do_cmds)
-
- # exit current Irb#run call
- throw :IRB_EXIT
- end
- end
- end
-
- class DebugCommand < Debug
- def self.category
- "Debugging"
- end
-
- def self.description
- command_name = self.name.split("::").last.downcase
- "Start the debugger of debug.gem and run its `#{command_name}` command."
- end
- end
- end
-end
diff --git a/lib/irb/command/delete.rb b/lib/irb/command/delete.rb
deleted file mode 100644
index 2a57a4a3de..0000000000
--- a/lib/irb/command/delete.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Delete < DebugCommand
- def execute(arg)
- execute_debug_command(pre_cmds: "delete #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/disable_irb.rb b/lib/irb/command/disable_irb.rb
deleted file mode 100644
index 0b00d0302b..0000000000
--- a/lib/irb/command/disable_irb.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- # :stopdoc:
-
- module Command
- class DisableIrb < Base
- category "IRB"
- description "Disable binding.irb."
-
- def execute(*)
- ::Binding.define_method(:irb) {}
- IRB.irb_exit
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/edit.rb b/lib/irb/command/edit.rb
deleted file mode 100644
index cb7e0c4873..0000000000
--- a/lib/irb/command/edit.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-require 'shellwords'
-
-require_relative "../color"
-require_relative "../source_finder"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Edit < Base
- include RubyArgsExtractor
-
- category "Misc"
- description 'Open a file or source location.'
- help_message <<~HELP_MESSAGE
- Usage: edit [FILE or constant or method signature]
-
- Open a file in the editor specified in #{highlight('ENV["VISUAL"]')} or #{highlight('ENV["EDITOR"]')}
-
- - If no arguments are provided, IRB will attempt to open the file the current context was defined in.
- - If FILE is provided, IRB will open the file.
- - If a constant or method signature is provided, IRB will attempt to locate the source file and open it.
-
- Examples:
-
- edit
- edit foo.rb
- edit Foo
- edit Foo#bar
- HELP_MESSAGE
-
- def execute(arg)
- # Accept string literal for backward compatibility
- path = unwrap_string_literal(arg)
-
- if path.nil?
- path = @irb_context.irb_path
- elsif !File.exist?(path)
- source = SourceFinder.new(@irb_context).find_source(path)
-
- if source&.file_exist? && !source.binary_file?
- path = source.file
- end
- end
-
- unless File.exist?(path)
- puts "Can not find file: #{path}"
- return
- end
-
- if editor = (ENV['VISUAL'] || ENV['EDITOR'])
- puts "command: '#{editor}'"
- puts " path: #{path}"
- system(*Shellwords.split(editor), path)
- else
- puts "Can not find editor setting: ENV['VISUAL'] or ENV['EDITOR']"
- end
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/exit.rb b/lib/irb/command/exit.rb
deleted file mode 100644
index b4436f0343..0000000000
--- a/lib/irb/command/exit.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- # :stopdoc:
-
- module Command
- class Exit < Base
- category "IRB"
- description "Exit the current irb session."
-
- def execute(_arg)
- IRB.irb_exit
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/finish.rb b/lib/irb/command/finish.rb
deleted file mode 100644
index 3311a0e6e9..0000000000
--- a/lib/irb/command/finish.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Finish < DebugCommand
- def execute(arg)
- execute_debug_command(do_cmds: "finish #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/force_exit.rb b/lib/irb/command/force_exit.rb
deleted file mode 100644
index 14086aa849..0000000000
--- a/lib/irb/command/force_exit.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- # :stopdoc:
-
- module Command
- class ForceExit < Base
- category "IRB"
- description "Exit the current process."
-
- def execute(_arg)
- throw :IRB_EXIT, true
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/help.rb b/lib/irb/command/help.rb
deleted file mode 100644
index c2018f9b30..0000000000
--- a/lib/irb/command/help.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- module Command
- class Help < Base
- category "Help"
- description "List all available commands. Use `help <command>` to get information about a specific command."
-
- def execute(command_name)
- content =
- if command_name.empty?
- help_message
- else
- if command_class = Command.load_command(command_name)
- command_class.help_message || command_class.description
- else
- "Can't find command `#{command_name}`. Please check the command name and try again.\n\n"
- end
- end
- Pager.page_content(content)
- end
-
- private
-
- def help_message
- commands_info = IRB::Command.all_commands_info
- helper_methods_info = IRB::HelperMethod.all_helper_methods_info
- commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
- commands_grouped_by_categories["Helper methods"] = helper_methods_info
-
- if irb_context.with_debugger
- # Remove the original "Debugging" category
- commands_grouped_by_categories.delete("Debugging")
- end
-
- longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max
-
- output = StringIO.new
-
- help_cmds = commands_grouped_by_categories.delete("Help")
- no_category_cmds = commands_grouped_by_categories.delete("No category")
- aliases = irb_context.instance_variable_get(:@user_aliases).map do |alias_name, target|
- { display_name: alias_name, description: "Alias for `#{target}`" }
- end
-
- # Display help commands first
- add_category_to_output("Help", help_cmds, output, longest_cmd_name_length)
-
- # Display the rest of the commands grouped by categories
- commands_grouped_by_categories.each do |category, cmds|
- add_category_to_output(category, cmds, output, longest_cmd_name_length)
- end
-
- # Display commands without a category
- if no_category_cmds
- add_category_to_output("No category", no_category_cmds, output, longest_cmd_name_length)
- end
-
- # Display aliases
- add_category_to_output("Aliases", aliases, output, longest_cmd_name_length)
-
- # Append the debugger help at the end
- if irb_context.with_debugger
- # Add "Debugging (from debug.gem)" category as title
- add_category_to_output("Debugging (from debug.gem)", [], output, longest_cmd_name_length)
- output.puts DEBUGGER__.help
- end
-
- output.string
- end
-
- def add_category_to_output(category, cmds, output, longest_cmd_name_length)
- output.puts Color.colorize(category, [:BOLD])
-
- cmds.each do |cmd|
- output.puts " #{cmd[:display_name].to_s.ljust(longest_cmd_name_length)} #{cmd[:description]}"
- end
-
- output.puts
- end
- end
- end
-end
diff --git a/lib/irb/command/history.rb b/lib/irb/command/history.rb
deleted file mode 100644
index 90f87f9102..0000000000
--- a/lib/irb/command/history.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require "stringio"
-
-require_relative "../pager"
-
-module IRB
- # :stopdoc:
-
- module Command
- class History < Base
- category "IRB"
- description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."
-
- def execute(arg)
-
- if (match = arg&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/))
- grep = Regexp.new(match[:grep])
- end
-
- formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index|
- next if grep && !input.match?(grep)
-
- header = "#{index}: "
-
- first_line, *other_lines = input.split("\n")
- first_line = "#{header}#{first_line}"
-
- truncated_lines = other_lines.slice!(1..) # Show 1 additional line (2 total)
- other_lines << "..." if truncated_lines&.any?
-
- other_lines.map! do |line|
- " " * header.length + line
- end
-
- [first_line, *other_lines].join("\n") + "\n"
- end
-
- Pager.page_content(formatted_inputs.join)
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/info.rb b/lib/irb/command/info.rb
deleted file mode 100644
index d08ce00a32..0000000000
--- a/lib/irb/command/info.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Info < DebugCommand
- def execute(arg)
- execute_debug_command(pre_cmds: "info #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/internal_helpers.rb b/lib/irb/command/internal_helpers.rb
deleted file mode 100644
index 249b5cdede..0000000000
--- a/lib/irb/command/internal_helpers.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- module Command
- # Internal use only, for default command's backward compatibility.
- module RubyArgsExtractor # :nodoc:
- def unwrap_string_literal(str)
- return if str.empty?
-
- sexp = Ripper.sexp(str)
- if sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
- @irb_context.workspace.binding.eval(str).to_s
- else
- str
- end
- end
-
- def ruby_args(arg)
- # Use throw and catch to handle arg that includes `;`
- # For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
- catch(:EXTRACT_RUBY_ARGS) do
- @irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
- end || [[], {}]
- end
- end
- end
-end
diff --git a/lib/irb/command/irb_info.rb b/lib/irb/command/irb_info.rb
deleted file mode 100644
index 6d868de94c..0000000000
--- a/lib/irb/command/irb_info.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- # :stopdoc:
-
- module Command
- class IrbInfo < Base
- category "IRB"
- description "Show information about IRB."
-
- def execute(_arg)
- str = "Ruby version: #{RUBY_VERSION}\n"
- str += "IRB version: #{IRB.version}\n"
- str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
- str += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n"
- rc_files = IRB.irbrc_files
- str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any?
- str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
- str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
- str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
- str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
- if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
- codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
- str += "Code page: #{codepage}\n"
- end
- puts str
- nil
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/load.rb b/lib/irb/command/load.rb
deleted file mode 100644
index 1cd3f279d1..0000000000
--- a/lib/irb/command/load.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-#
-# load.rb -
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-require_relative "../ext/loader"
-
-module IRB
- # :stopdoc:
-
- module Command
- class LoaderCommand < Base
- include RubyArgsExtractor
- include IrbLoader
-
- def raise_cmd_argument_error
- raise CommandArgumentError.new("Please specify the file name.")
- end
- end
-
- class Load < LoaderCommand
- category "IRB"
- description "Load a Ruby file."
-
- def execute(arg)
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(file_name = nil, priv = nil)
- raise_cmd_argument_error unless file_name
- irb_load(file_name, priv)
- end
- end
-
- class Require < LoaderCommand
- category "IRB"
- description "Require a Ruby file."
-
- def execute(arg)
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(file_name = nil)
- raise_cmd_argument_error unless file_name
-
- rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
- return false if $".find{|f| f =~ rex}
-
- case file_name
- when /\.rb$/
- begin
- if irb_load(file_name)
- $".push file_name
- return true
- end
- rescue LoadError
- end
- when /\.(so|o|sl)$/
- return ruby_require(file_name)
- end
-
- begin
- irb_load(f = file_name + ".rb")
- $".push f
- return true
- rescue LoadError
- return ruby_require(file_name)
- end
- end
- end
-
- class Source < LoaderCommand
- category "IRB"
- description "Loads a given file in the current session."
-
- def execute(arg)
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(file_name = nil)
- raise_cmd_argument_error unless file_name
-
- source_file(file_name)
- end
- end
- end
- # :startdoc:
-end
diff --git a/lib/irb/command/ls.rb b/lib/irb/command/ls.rb
deleted file mode 100644
index cbd9998bc4..0000000000
--- a/lib/irb/command/ls.rb
+++ /dev/null
@@ -1,155 +0,0 @@
-# frozen_string_literal: true
-
-require "reline"
-require "stringio"
-
-require_relative "../pager"
-require_relative "../color"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Ls < Base
- include RubyArgsExtractor
-
- category "Context"
- description "Show methods, constants, and variables."
-
- help_message <<~HELP_MESSAGE
- Usage: ls [obj] [-g [query]]
-
- -g [query] Filter the output with a query.
- HELP_MESSAGE
-
- def execute(arg)
- if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
- if match[:target].empty?
- use_main = true
- else
- obj = @irb_context.workspace.binding.eval(match[:target])
- end
- grep = Regexp.new(match[:grep])
- else
- args, kwargs = ruby_args(arg)
- use_main = args.empty?
- obj = args.first
- grep = kwargs[:grep]
- end
-
- if use_main
- obj = irb_context.workspace.main
- locals = irb_context.workspace.binding.local_variables
- end
-
- o = Output.new(grep: grep)
-
- klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
-
- o.dump("constants", obj.constants) if obj.respond_to?(:constants)
- dump_methods(o, klass, obj)
- o.dump("instance variables", obj.instance_variables)
- o.dump("class variables", klass.class_variables)
- o.dump("locals", locals) if locals
- o.print_result
- end
-
- def dump_methods(o, klass, obj)
- singleton_class = begin obj.singleton_class; rescue TypeError; nil end
- dumped_mods = Array.new
- ancestors = klass.ancestors
- ancestors = ancestors.reject { |c| c >= Object } if klass < Object
- singleton_ancestors = (singleton_class&.ancestors || []).reject { |c| c >= Class }
-
- # singleton_class' ancestors should be at the front
- maps = class_method_map(singleton_ancestors, dumped_mods) + class_method_map(ancestors, dumped_mods)
- maps.each do |mod, methods|
- name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
- o.dump(name, methods)
- end
- end
-
- def class_method_map(classes, dumped_mods)
- dumped_methods = Array.new
- classes.map do |mod|
- next if dumped_mods.include? mod
-
- dumped_mods << mod
-
- methods = mod.public_instance_methods(false).select do |method|
- if dumped_methods.include? method
- false
- else
- dumped_methods << method
- true
- end
- end
-
- [mod, methods]
- end.compact
- end
-
- class Output
- MARGIN = " "
-
- def initialize(grep: nil)
- @grep = grep
- @line_width = screen_width - MARGIN.length # right padding
- @io = StringIO.new
- end
-
- def print_result
- Pager.page_content(@io.string)
- end
-
- def dump(name, strs)
- strs = strs.grep(@grep) if @grep
- strs = strs.sort
- return if strs.empty?
-
- # Attempt a single line
- @io.print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
- if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
- @io.puts strs.join(MARGIN)
- return
- end
- @io.puts
-
- # Dump with the largest # of columns that fits on a line
- cols = strs.size
- until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
- cols -= 1
- end
- widths = col_widths(strs, cols: cols)
- strs.each_slice(cols) do |ss|
- @io.puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
- end
- end
-
- private
-
- def fits_on_line?(strs, cols:, offset: 0)
- width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
- width <= @line_width - offset
- end
-
- def col_widths(strs, cols:)
- cols.times.map do |col|
- (col...strs.size).step(cols).map do |i|
- strs[i].length
- end.max
- end
- end
-
- def screen_width
- Reline.get_screen_size.last
- rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
- 80
- end
- end
- private_constant :Output
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/measure.rb b/lib/irb/command/measure.rb
deleted file mode 100644
index f96be20de8..0000000000
--- a/lib/irb/command/measure.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-module IRB
- # :stopdoc:
-
- module Command
- class Measure < Base
- include RubyArgsExtractor
-
- category "Misc"
- description "`measure` enables the mode to measure processing time. `measure :off` disables it."
-
- def initialize(*args)
- super(*args)
- end
-
- def execute(arg)
- if arg&.match?(/^do$|^do[^\w]|^\{/)
- warn 'Configure IRB.conf[:MEASURE_PROC] to add custom measure methods.'
- return
- end
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(type = nil, arg = nil)
- # Please check IRB.init_config in lib/irb/init.rb that sets
- # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
- # "measure :time" (abbreviated as "measure") and "measure :stackprof".
-
- case type
- when :off
- IRB.unset_measure_callback(arg)
- when :list
- IRB.conf[:MEASURE_CALLBACKS].each do |type_name, _, arg_val|
- puts "- #{type_name}" + (arg_val ? "(#{arg_val.inspect})" : '')
- end
- when :on
- added = IRB.set_measure_callback(arg)
- puts "#{added[0]} is added." if added
- else
- added = IRB.set_measure_callback(type, arg)
- puts "#{added[0]} is added." if added
- end
- nil
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/next.rb b/lib/irb/command/next.rb
deleted file mode 100644
index 3fc6b68d21..0000000000
--- a/lib/irb/command/next.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Next < DebugCommand
- def execute(arg)
- execute_debug_command(do_cmds: "next #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/pushws.rb b/lib/irb/command/pushws.rb
deleted file mode 100644
index b51928c650..0000000000
--- a/lib/irb/command/pushws.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-#
-# change-ws.rb -
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-
-require_relative "../ext/workspaces"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Workspaces < Base
- category "Workspace"
- description "Show workspaces."
-
- def execute(_arg)
- inspection_resuls = irb_context.instance_variable_get(:@workspace_stack).map do |ws|
- truncated_inspect(ws.main)
- end
-
- puts "[" + inspection_resuls.join(", ") + "]"
- end
-
- private
-
- def truncated_inspect(obj)
- obj_inspection = obj.inspect
-
- if obj_inspection.size > 20
- obj_inspection = obj_inspection[0, 19] + "...>"
- end
-
- obj_inspection
- end
- end
-
- class PushWorkspace < Workspaces
- category "Workspace"
- description "Push an object to the workspace stack."
-
- def execute(arg)
- if arg.empty?
- irb_context.push_workspace
- else
- obj = eval(arg, irb_context.workspace.binding)
- irb_context.push_workspace(obj)
- end
- super
- end
- end
-
- class PopWorkspace < Workspaces
- category "Workspace"
- description "Pop a workspace from the workspace stack."
-
- def execute(_arg)
- irb_context.pop_workspace
- super
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/show_doc.rb b/lib/irb/command/show_doc.rb
deleted file mode 100644
index 8a2188e4eb..0000000000
--- a/lib/irb/command/show_doc.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- module Command
- class ShowDoc < Base
- include RubyArgsExtractor
-
- category "Context"
- description "Look up documentation with RI."
-
- help_message <<~HELP_MESSAGE
- Usage: show_doc [name]
-
- When name is provided, IRB will look up the documentation for the given name.
- When no name is provided, a RI session will be started.
-
- Examples:
-
- show_doc
- show_doc Array
- show_doc Array#each
-
- HELP_MESSAGE
-
- def execute(arg)
- # Accept string literal for backward compatibility
- name = unwrap_string_literal(arg)
- require 'rdoc/ri/driver'
-
- unless ShowDoc.const_defined?(:Ri)
- opts = RDoc::RI::Driver.process_args([])
- ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts))
- end
-
- if name.nil?
- Ri.interactive
- else
- begin
- Ri.display_name(name)
- rescue RDoc::RI::Error
- puts $!.message
- end
- end
-
- nil
- rescue LoadError, SystemExit
- warn "Can't display document because `rdoc` is not installed."
- end
- end
- end
-end
diff --git a/lib/irb/command/show_source.rb b/lib/irb/command/show_source.rb
deleted file mode 100644
index f4c6f104a2..0000000000
--- a/lib/irb/command/show_source.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "../source_finder"
-require_relative "../pager"
-require_relative "../color"
-
-module IRB
- module Command
- class ShowSource < Base
- include RubyArgsExtractor
-
- category "Context"
- description "Show the source code of a given method, class/module, or constant."
-
- help_message <<~HELP_MESSAGE
- Usage: show_source [target] [-s]
-
- -s Show the super method. You can stack it like `-ss` to show the super of the super, etc.
-
- Examples:
-
- show_source Foo
- show_source Foo#bar
- show_source Foo#bar -s
- show_source Foo.baz
- show_source Foo::BAR
- HELP_MESSAGE
-
- def execute(arg)
- # Accept string literal for backward compatibility
- str = unwrap_string_literal(arg)
- unless str.is_a?(String)
- puts "Error: Expected a string but got #{str.inspect}"
- return
- end
-
- str, esses = str.split(" -")
- super_level = esses ? esses.count("s") : 0
- source = SourceFinder.new(@irb_context).find_source(str, super_level)
-
- if source
- show_source(source)
- elsif super_level > 0
- puts "Error: Couldn't locate a super definition for #{str}"
- else
- puts "Error: Couldn't locate a definition for #{str}"
- end
- nil
- end
-
- private
-
- def show_source(source)
- if source.binary_file?
- content = "\n#{bold('Defined in binary file')}: #{source.file}\n\n"
- else
- code = source.colorized_content || 'Source not available'
- content = <<~CONTENT
-
- #{bold("From")}: #{source.file}:#{source.line}
-
- #{code.chomp}
-
- CONTENT
- end
- Pager.page_content(content)
- end
-
- def bold(str)
- Color.colorize(str, [:BOLD])
- end
- end
- end
-end
diff --git a/lib/irb/command/step.rb b/lib/irb/command/step.rb
deleted file mode 100644
index 29e5e35ac0..0000000000
--- a/lib/irb/command/step.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "debug"
-
-module IRB
- # :stopdoc:
-
- module Command
- class Step < DebugCommand
- def execute(arg)
- execute_debug_command(do_cmds: "step #{arg}")
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/subirb.rb b/lib/irb/command/subirb.rb
deleted file mode 100644
index 85af28c1a5..0000000000
--- a/lib/irb/command/subirb.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-# frozen_string_literal: true
-#
-# multi.rb -
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-
-module IRB
- # :stopdoc:
-
- module Command
- class MultiIRBCommand < Base
- include RubyArgsExtractor
-
- private
-
- def print_deprecated_warning
- warn <<~MSG
- Multi-irb commands are deprecated and will be removed in IRB 2.0.0. Please use workspace commands instead.
- If you have any use case for multi-irb, please leave a comment at https://github.com/ruby/irb/issues/653
- MSG
- end
-
- def extend_irb_context
- # this extension patches IRB context like IRB.CurrentContext
- require_relative "../ext/multi-irb"
- end
-
- def print_debugger_warning
- warn "Multi-IRB commands are not available when the debugger is enabled."
- end
- end
-
- class IrbCommand < MultiIRBCommand
- category "Multi-irb (DEPRECATED)"
- description "Start a child IRB."
-
- def execute(arg)
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(*obj)
- print_deprecated_warning
-
- if irb_context.with_debugger
- print_debugger_warning
- return
- end
-
- extend_irb_context
- IRB.irb(nil, *obj)
- puts IRB.JobManager.inspect
- end
- end
-
- class Jobs < MultiIRBCommand
- category "Multi-irb (DEPRECATED)"
- description "List of current sessions."
-
- def execute(_arg)
- print_deprecated_warning
-
- if irb_context.with_debugger
- print_debugger_warning
- return
- end
-
- extend_irb_context
- puts IRB.JobManager.inspect
- end
- end
-
- class Foreground < MultiIRBCommand
- category "Multi-irb (DEPRECATED)"
- description "Switches to the session of the given number."
-
- def execute(arg)
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(key = nil)
- print_deprecated_warning
-
- if irb_context.with_debugger
- print_debugger_warning
- return
- end
-
- extend_irb_context
-
- raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key
- IRB.JobManager.switch(key)
- puts IRB.JobManager.inspect
- end
- end
-
- class Kill < MultiIRBCommand
- category "Multi-irb (DEPRECATED)"
- description "Kills the session with the given number."
-
- def execute(arg)
- args, kwargs = ruby_args(arg)
- execute_internal(*args, **kwargs)
- end
-
- def execute_internal(*keys)
- print_deprecated_warning
-
- if irb_context.with_debugger
- print_debugger_warning
- return
- end
-
- extend_irb_context
- IRB.JobManager.kill(*keys)
- puts IRB.JobManager.inspect
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/command/whereami.rb b/lib/irb/command/whereami.rb
deleted file mode 100644
index c8439f1212..0000000000
--- a/lib/irb/command/whereami.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- # :stopdoc:
-
- module Command
- class Whereami < Base
- category "Context"
- description "Show the source code around binding.irb again."
-
- def execute(_arg)
- code = irb_context.workspace.code_around_binding
- if code
- puts code
- else
- puts "The current context doesn't have code."
- end
- end
- end
- end
-
- # :startdoc:
-end
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index a3d89373c3..34640e17f9 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -1,6 +1,8 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/completion.rb -
+# $Release Version: 0.9$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
# From Original Idea of shugo@ruby-lang.org
#
@@ -8,7 +10,30 @@
require_relative 'ruby-lex'
module IRB
- class BaseCompletor # :nodoc:
+ module InputCompletor # :nodoc:
+ using Module.new {
+ refine ::Binding do
+ def eval_methods
+ ::Kernel.instance_method(:methods).bind(eval("self")).call
+ end
+
+ def eval_private_methods
+ ::Kernel.instance_method(:private_methods).bind(eval("self")).call
+ end
+
+ def eval_instance_variables
+ ::Kernel.instance_method(:instance_variables).bind(eval("self")).call
+ end
+
+ def eval_global_variables
+ ::Kernel.instance_method(:global_variables).bind(eval("self")).call
+ end
+
+ def eval_class_constants
+ ::Module.instance_method(:constants).bind(eval("self.class")).call
+ end
+ end
+ }
# Set of reserved words used by Ruby, you should not use these for
# constants or variables
@@ -33,19 +58,21 @@ module IRB
yield
]
- def completion_candidates(preposing, target, postposing, bind:)
- raise NotImplementedError
- end
+ BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
- def doc_namespace(preposing, matched, postposing, bind:)
- raise NotImplementedError
+ def self.absolute_path?(p) # TODO Remove this method after 2.6 EOL.
+ if File.respond_to?(:absolute_path?)
+ File.absolute_path?(p)
+ else
+ File.absolute_path(p) == p
+ end
end
GEM_PATHS =
if defined?(Gem::Specification)
Gem::Specification.latest_specs(true).map { |s|
s.require_paths.map { |p|
- if File.absolute_path?(p)
+ if absolute_path?(p)
p
else
File.join(s.full_gem_path, p)
@@ -56,7 +83,7 @@ module IRB
[]
end.freeze
- def retrieve_gem_and_system_load_path
+ def self.retrieve_gem_and_system_load_path
candidates = (GEM_PATHS | $LOAD_PATH)
candidates.map do |p|
if p.respond_to?(:to_path)
@@ -67,8 +94,8 @@ module IRB
end.compact.sort
end
- def retrieve_files_to_require_from_load_path
- @files_from_load_path ||=
+ def self.retrieve_files_to_require_from_load_path
+ @@files_from_load_path ||=
(
shortest = []
rest = retrieve_gem_and_system_load_path.each_with_object([]) { |path, result|
@@ -86,74 +113,13 @@ module IRB
)
end
- def command_completions(preposing, target)
- if preposing.empty? && !target.empty?
- IRB::Command.command_names.select { _1.start_with?(target) }
- else
- []
- end
- end
-
- def retrieve_files_to_require_relative_from_current_dir
- @files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
+ def self.retrieve_files_to_require_relative_from_current_dir
+ @@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
}
end
- end
-
- class TypeCompletor < BaseCompletor # :nodoc:
- def initialize(context)
- @context = context
- end
-
- def inspect
- ReplTypeCompletor.info
- end
-
- def completion_candidates(preposing, target, _postposing, bind:)
- commands = command_completions(preposing, target)
- result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
- return commands unless result
-
- commands | result.completion_candidates.map { target + _1 }
- end
-
- def doc_namespace(preposing, matched, _postposing, bind:)
- result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path)
- result&.doc_namespace('')
- end
- end
- class RegexpCompletor < BaseCompletor # :nodoc:
- using Module.new {
- refine ::Binding do
- def eval_methods
- ::Kernel.instance_method(:methods).bind(eval("self")).call
- end
-
- def eval_private_methods
- ::Kernel.instance_method(:private_methods).bind(eval("self")).call
- end
-
- def eval_instance_variables
- ::Kernel.instance_method(:instance_variables).bind(eval("self")).call
- end
-
- def eval_global_variables
- ::Kernel.instance_method(:global_variables).bind(eval("self")).call
- end
-
- def eval_class_constants
- ::Module.instance_method(:constants).bind(eval("self.class")).call
- end
- end
- }
-
- def inspect
- 'RegexpCompletor'
- end
-
- def complete_require_path(target, preposing, postposing)
+ CompletionRequireProc = lambda { |target, preposing = nil, postposing = nil|
if target =~ /\A(['"])([^'"]+)\Z/
quote = $1
actual_target = $2
@@ -168,45 +134,44 @@ module IRB
break
end
end
- return unless tok&.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
-
- case tok.tok
- when 'require'
- retrieve_files_to_require_from_load_path.select { |path|
- path.start_with?(actual_target)
- }.map { |path|
- quote + path
- }
- when 'require_relative'
- retrieve_files_to_require_relative_from_current_dir.select { |path|
- path.start_with?(actual_target)
- }.map { |path|
- quote + path
- }
+ result = []
+ if tok && tok.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
+ case tok.tok
+ when 'require'
+ result = retrieve_files_to_require_from_load_path.select { |path|
+ path.start_with?(actual_target)
+ }.map { |path|
+ quote + path
+ }
+ when 'require_relative'
+ result = retrieve_files_to_require_relative_from_current_dir.select { |path|
+ path.start_with?(actual_target)
+ }.map { |path|
+ quote + path
+ }
+ end
end
- end
+ result
+ }
- def completion_candidates(preposing, target, postposing, bind:)
+ CompletionProc = lambda { |target, preposing = nil, postposing = nil|
if preposing && postposing
- result = complete_require_path(target, preposing, postposing)
- return result if result
+ result = CompletionRequireProc.(target, preposing, postposing)
+ unless result
+ result = retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
+ end
+ result
+ else
+ retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
end
- commands = command_completions(preposing || '', target)
- commands | retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
- end
-
- def doc_namespace(_preposing, matched, _postposing, bind:)
- retrieve_completion_data(matched, bind: bind, doc_namespace: true)
- end
+ }
- def retrieve_completion_data(input, bind:, doc_namespace:)
+ def self.retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
case input
- # this regexp only matches the closing character because of irb's Reline.completer_quote_characters setting
- # details are described in: https://github.com/ruby/irb/pull/523
- when /^(.*["'`])\.([^.]*)$/
+ when /^((["'`]).*\2)\.([^.]*)$/
# String
receiver = $1
- message = $2
+ message = $3
if doc_namespace
"String.#{message}"
@@ -215,9 +180,7 @@ module IRB
select_message(receiver, message, candidates)
end
- # this regexp only matches the closing character because of irb's Reline.completer_quote_characters setting
- # details are described in: https://github.com/ruby/irb/pull/523
- when /^(.*\/)\.([^.]*)$/
+ when /^(\/[^\/]*\/)\.([^.]*)$/
# Regexp
receiver = $1
message = $2
@@ -242,26 +205,26 @@ module IRB
end
when /^([^\}]*\})\.([^.]*)$/
- # Hash or Proc
+ # Proc or Hash
receiver = $1
message = $2
if doc_namespace
- ["Hash.#{message}", "Proc.#{message}"]
+ ["Proc.#{message}", "Hash.#{message}"]
else
- hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, hash_candidates | proc_candidates)
+ hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
+ select_message(receiver, message, proc_candidates | hash_candidates)
end
- when /^(:[^:.]+)$/
+ when /^(:[^:.]*)$/
# Symbol
if doc_namespace
nil
else
sym = $1
candidates = Symbol.all_symbols.collect do |s|
- s.inspect
+ ":" + s.id2name.encode(Encoding.default_external)
rescue EncodingError
# ignore
end
@@ -276,7 +239,7 @@ module IRB
if doc_namespace
candidates.find { |i| i == receiver }
else
- candidates.grep(/^#{Regexp.quote(receiver)}/).collect{|e| "::" + e}
+ candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
end
when /^([A-Z].*)::([^:.]*)$/
@@ -395,11 +358,19 @@ module IRB
else
# func1.func2
candidates = []
+ to_ignore = ignored_modules
+ ObjectSpace.each_object(Module){|m|
+ next if (to_ignore.include?(m) rescue true)
+ next unless m.respond_to?(:instance_methods) # JRuby has modules that represent java packages. They don't include many common ruby methods
+ candidates.concat m.instance_methods(false).collect{|x| x.to_s}
+ }
+ candidates.sort!
+ candidates.uniq!
end
if doc_namespace
rec_class = rec.is_a?(Module) ? rec : rec.class
- "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}" rescue nil
+ "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}"
else
select_message(receiver, message, candidates, sep)
end
@@ -417,19 +388,13 @@ module IRB
else
select_message(receiver, message, candidates.sort)
end
- when /^\s*$/
- # empty input
- if doc_namespace
- nil
- else
- []
- end
+
else
if doc_namespace
vars = (bind.local_variables | bind.eval_instance_variables).collect{|m| m.to_s}
perfect_match_var = vars.find{|m| m.to_s == input}
if perfect_match_var
- eval("#{perfect_match_var}.class.name", bind) rescue nil
+ eval("#{perfect_match_var}.class.name", bind)
else
candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s}
candidates |= ReservedWords
@@ -443,10 +408,44 @@ module IRB
end
end
+ PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
+ begin
+ require 'rdoc'
+ rescue LoadError
+ return
+ end
+
+ RDocRIDriver ||= RDoc::RI::Driver.new
+
+ if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
+ IRB.__send__(:easter_egg)
+ return
+ end
+
+ namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
+ return unless namespace
+
+ if namespace.is_a?(Array)
+ out = RDoc::Markup::Document.new
+ namespace.each do |m|
+ begin
+ RDocRIDriver.add_method(out, m)
+ rescue RDoc::RI::Driver::NotFoundError
+ end
+ end
+ RDocRIDriver.display(out)
+ else
+ begin
+ RDocRIDriver.display_names([namespace])
+ rescue RDoc::RI::Driver::NotFoundError
+ end
+ end
+ }
+
# Set of available operators in Ruby
Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
- def select_message(receiver, message, candidates, sep = ".")
+ def self.select_message(receiver, message, candidates, sep = ".")
candidates.grep(/^#{Regexp.quote(message)}/).collect do |e|
case e
when /^[a-zA-Z_]/
@@ -457,21 +456,30 @@ module IRB
end
end
end
- end
- module InputCompletor
- class << self
- private def regexp_completor
- @regexp_completor ||= RegexpCompletor.new
+ def self.ignored_modules
+ # We could cache the result, but this is very fast already.
+ # By using this approach, we avoid Module#name calls, which are
+ # relatively slow when there are a lot of anonymous modules defined.
+ s = {}
+
+ scanner = lambda do |m|
+ next if s.include?(m) # IRB::ExtendCommandBundle::EXCB recurses.
+ s[m] = true
+ m.constants(false).each do |c|
+ value = m.const_get(c)
+ scanner.call(value) if value.is_a?(Module)
+ end
end
- def retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
- regexp_completor.retrieve_completion_data(input, bind: bind, doc_namespace: doc_namespace)
+ %i(IRB RubyLex).each do |sym|
+ next unless Object.const_defined?(sym)
+ scanner.call(Object.const_get(sym))
end
+
+ s.delete(IRB::Context) if defined?(IRB::Context)
+
+ s
end
- CompletionProc = ->(target, preposing = nil, postposing = nil) {
- regexp_completor.completion_candidates(preposing, target, postposing, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
- }
end
- deprecate_constant :InputCompletor
end
diff --git a/lib/irb/context.rb b/lib/irb/context.rb
index 5d2ff97328..91fbb2fcf1 100644
--- a/lib/irb/context.rb
+++ b/lib/irb/context.rb
@@ -1,9 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/context.rb - irb context
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
-
+# --
+#
+#
+#
require_relative "workspace"
require_relative "inspector"
require_relative "input-method"
@@ -22,11 +27,10 @@ module IRB
# +other+:: uses this as InputMethod
def initialize(irb, workspace = nil, input_method = nil)
@irb = irb
- @workspace_stack = []
if workspace
- @workspace_stack << workspace
+ @workspace = workspace
else
- @workspace_stack << WorkSpace.new
+ @workspace = WorkSpace.new
end
@thread = Thread.current
@@ -62,7 +66,7 @@ module IRB
@io = nil
self.inspect_mode = IRB.conf[:INSPECT_MODE]
- self.use_tracer = IRB.conf[:USE_TRACER]
+ self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]
self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]
self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]
@@ -78,28 +82,28 @@ module IRB
else
@irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
end
- self.irb_path = "(" + @irb_name + ")"
+ @irb_path = "(" + @irb_name + ")"
case input_method
when nil
@io = nil
case use_multiline?
when nil
- if term_interactive? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_singleline?
+ if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_singleline?
# Both of multiline mode and singleline mode aren't specified.
- @io = RelineInputMethod.new(build_completor)
+ @io = RelineInputMethod.new
else
@io = nil
end
when false
@io = nil
when true
- @io = RelineInputMethod.new(build_completor)
+ @io = RelineInputMethod.new
end
unless @io
case use_singleline?
when nil
- if (defined?(ReadlineInputMethod) && term_interactive? &&
+ if (defined?(ReadlineInputMethod) && STDIN.tty? &&
IRB.conf[:PROMPT_MODE] != :INF_RUBY)
@io = ReadlineInputMethod.new
else
@@ -122,14 +126,16 @@ module IRB
when '-'
@io = FileInputMethod.new($stdin)
@irb_name = '-'
- self.irb_path = '-'
+ @irb_path = '-'
when String
@io = FileInputMethod.new(input_method)
@irb_name = File.basename(input_method)
- self.irb_path = input_method
+ @irb_path = input_method
else
@io = input_method
end
+ self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
+
@extra_doc_dirs = IRB.conf[:EXTRA_DOC_DIRS]
@echo = IRB.conf[:ECHO]
@@ -147,112 +153,18 @@ module IRB
@newline_before_multiline_output = true
end
- @user_aliases = IRB.conf[:COMMAND_ALIASES].dup
- @command_aliases = @user_aliases.merge(KEYWORD_ALIASES)
- end
-
- private def term_interactive?
- return true if ENV['TEST_IRB_FORCE_INTERACTIVE']
- STDIN.tty? && ENV['TERM'] != 'dumb'
- end
-
- # because all input will eventually be evaluated as Ruby code,
- # command names that conflict with Ruby keywords need special workaround
- # we can remove them once we implemented a better command system for IRB
- KEYWORD_ALIASES = {
- :break => :irb_break,
- :catch => :irb_catch,
- :next => :irb_next,
- }.freeze
-
- private_constant :KEYWORD_ALIASES
-
- def use_tracer=(val)
- require_relative "ext/tracer" if val
- IRB.conf[:USE_TRACER] = val
- end
-
- def eval_history=(val)
- self.class.remove_method(__method__)
- require_relative "ext/eval_history"
- __send__(__method__, val)
- end
-
- def use_loader=(val)
- self.class.remove_method(__method__)
- require_relative "ext/use-loader"
- __send__(__method__, val)
- end
-
- private def build_completor
- completor_type = IRB.conf[:COMPLETOR]
- case completor_type
- when :regexp
- return RegexpCompletor.new
- when :type
- completor = build_type_completor
- return completor if completor
- else
- warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}"
- end
- # Fallback to RegexpCompletor
- RegexpCompletor.new
- end
-
- private def build_type_completor
- if RUBY_ENGINE == 'truffleruby'
- # Avoid SyntaxError. truffleruby does not support endless method definition yet.
- warn 'TypeCompletor is not supported on TruffleRuby yet'
- return
- end
-
- begin
- require 'repl_type_completor'
- rescue LoadError => e
- warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
- return
- end
-
- ReplTypeCompletor.preload_rbs
- TypeCompletor.new(self)
- end
-
- def save_history=(val)
- IRB.conf[:SAVE_HISTORY] = val
- end
-
- def save_history
- IRB.conf[:SAVE_HISTORY]
- end
-
- # A copy of the default <code>IRB.conf[:HISTORY_FILE]</code>
- def history_file
- IRB.conf[:HISTORY_FILE]
- end
-
- # Set <code>IRB.conf[:HISTORY_FILE]</code> to the given +hist+.
- def history_file=(hist)
- IRB.conf[:HISTORY_FILE] = hist
- end
-
- # Workspace in the current context.
- def workspace
- @workspace_stack.last
- end
-
- # Replace the current workspace with the given +workspace+.
- def replace_workspace(workspace)
- @workspace_stack.pop
- @workspace_stack.push(workspace)
+ @command_aliases = IRB.conf[:COMMAND_ALIASES]
end
# The top-level workspace, see WorkSpace#main
def main
- workspace.main
+ @workspace.main
end
# The toplevel workspace, see #home_workspace
attr_reader :workspace_home
+ # WorkSpace in the current context.
+ attr_accessor :workspace
# The current thread in this context.
attr_reader :thread
# The current input method.
@@ -273,27 +185,9 @@ module IRB
# Can be either name from <code>IRB.conf[:IRB_NAME]</code>, or the number of
# the current job set by JobManager, such as <code>irb#2</code>
attr_accessor :irb_name
-
- # Can be one of the following:
- # - the #irb_name surrounded by parenthesis
- # - the +input_method+ passed to Context.new
- # - the file path of the current IRB context in a binding.irb session
- attr_reader :irb_path
-
- # Sets @irb_path to the given +path+ as well as @eval_path
- # @eval_path is used for evaluating code in the context of IRB session
- # It's the same as irb_path, but with the IRB name postfix
- # This makes sure users can distinguish the methods defined in the IRB session
- # from the methods defined in the current file's context, especially with binding.irb
- def irb_path=(path)
- @irb_path = path
-
- if File.exist?(path)
- @eval_path = "#{path}(#{IRB.conf[:IRB_NAME]})"
- else
- @eval_path = path
- end
- end
+ # Can be either the #irb_name surrounded by parenthesis, or the
+ # +input_method+ passed to Context.new
+ attr_accessor :irb_path
# Whether multiline editor mode is enabled or not.
#
@@ -314,29 +208,18 @@ module IRB
attr_reader :prompt_mode
# Standard IRB prompt.
#
- # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
+ # See IRB@Customizing+the+IRB+Prompt for more information.
attr_accessor :prompt_i
# IRB prompt for continuated strings.
#
- # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
+ # See IRB@Customizing+the+IRB+Prompt for more information.
attr_accessor :prompt_s
# IRB prompt for continuated statement. (e.g. immediately after an +if+)
#
- # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
+ # See IRB@Customizing+the+IRB+Prompt for more information.
attr_accessor :prompt_c
-
- # TODO: Remove this when developing v2.0
- def prompt_n
- warn "IRB::Context#prompt_n is deprecated and will be removed in the next major release."
- ""
- end
-
- # TODO: Remove this when developing v2.0
- def prompt_n=(_)
- warn "IRB::Context#prompt_n= is deprecated and will be removed in the next major release."
- ""
- end
-
+ # See IRB@Customizing+the+IRB+Prompt for more information.
+ attr_accessor :prompt_n
# Can be either the default <code>IRB.conf[:AUTO_INDENT]</code>, or the
# mode set by #prompt_mode=
#
@@ -444,13 +327,13 @@ module IRB
# The default value is 16.
#
# Can also be set using the +--back-trace-limit+ command line option.
+ #
+ # See IRB@Command+line+options for more command line options.
attr_accessor :back_trace_limit
# User-defined IRB command aliases
attr_accessor :command_aliases
- attr_accessor :with_debugger
-
# Alias for #use_multiline
alias use_multiline? use_multiline
# Alias for #use_singleline
@@ -494,7 +377,9 @@ module IRB
# StdioInputMethod or RelineInputMethod or ReadlineInputMethod, see #io
# for more information.
def prompting?
- verbose? || @io.prompting?
+ verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
+ @io.kind_of?(RelineInputMethod) ||
+ (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
end
# The return value of the last statement evaluated.
@@ -504,18 +389,19 @@ module IRB
# to #last_value.
def set_last_value(value)
@last_value = value
- workspace.local_variable_set :_, value
+ @workspace.local_variable_set :_, value
end
# Sets the +mode+ of the prompt in this context.
#
- # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
+ # See IRB@Customizing+the+IRB+Prompt for more information.
def prompt_mode=(mode)
@prompt_mode = mode
pconf = IRB.conf[:PROMPT][mode]
@prompt_i = pconf[:PROMPT_I]
@prompt_s = pconf[:PROMPT_S]
@prompt_c = pconf[:PROMPT_C]
+ @prompt_n = pconf[:PROMPT_N]
@return_format = pconf[:RETURN]
@return_format = "%s\n" if @return_format == nil
if ai = pconf.include?(:AUTO_INDENT)
@@ -547,6 +433,8 @@ module IRB
#
# Can also be set using the +--inspect+ and +--noinspect+ command line
# options.
+ #
+ # See IRB@Command+line+options for more command line options.
def inspect_mode=(opt)
if i = Inspector::INSPECTORS[opt]
@@ -590,55 +478,42 @@ module IRB
@inspect_mode
end
- def evaluate(statement, line_no) # :nodoc:
+ def evaluate(line, line_no, exception: nil) # :nodoc:
@line_no = line_no
-
- case statement
- when Statement::EmptyInput
- return
- when Statement::Expression
- result = evaluate_expression(statement.code, line_no)
- set_last_value(result)
- when Statement::Command
- statement.command_class.execute(self, statement.arg)
- set_last_value(nil)
+ if exception
+ line_no -= 1
+ line = "begin ::Kernel.raise _; rescue _.class\n#{line}\n""end"
+ @workspace.local_variable_set(:_, exception)
end
- nil
- end
-
- def from_binding?
- @irb.from_binding
- end
-
- def evaluate_expression(code, line_no) # :nodoc:
- result = nil
- if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
- IRB.set_measure_callback
+ # Transform a non-identifier alias (@, $) or keywords (next, break)
+ command, args = line.split(/\s/, 2)
+ if original = command_aliases[command.to_sym]
+ line = line.gsub(/\A#{Regexp.escape(command)}/, original.to_s)
+ command = original
end
- if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
- last_proc = proc do
- result = workspace.evaluate(code, @eval_path, line_no)
- end
- IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) do |chain, item|
- _name, callback, arg = item
- proc do
- callback.(self, code, line_no, arg) do
- chain.call
- end
- end
- end.call
- else
- result = workspace.evaluate(code, @eval_path, line_no)
+ # Hook command-specific transformation
+ command_class = ExtendCommandBundle.load_command(command)
+ if command_class&.respond_to?(:transform_args)
+ line = "#{command} #{command_class.transform_args(args)}"
end
- result
+
+ set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
end
def inspect_last_value # :nodoc:
@inspect_method.inspect_value(@last_value)
end
+ alias __exit__ exit
+ # Exits the current session, see IRB.irb_exit
+ def exit(ret = 0)
+ IRB.irb_exit(@irb, ret)
+ rescue UncaughtThrowError
+ super
+ end
+
NOPRINTING_IVARS = ["@last_value"] # :nodoc:
NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc:
IDNAME_IVARS = ["@prompt_mode"] # :nodoc:
@@ -669,5 +544,17 @@ module IRB
def local_variables # :nodoc:
workspace.binding.local_variables
end
+
+ # Return true if it's aliased from the argument and it's not an identifier.
+ def symbol_alias?(command)
+ return nil if command.match?(/\A\w+\z/)
+ command_aliases.key?(command.to_sym)
+ end
+
+ # Return true if the command supports transforming args
+ def transform_args?(command)
+ command = command_aliases.fetch(command.to_sym, command)
+ ExtendCommandBundle.load_command(command)&.respond_to?(:transform_args)
+ end
end
end
diff --git a/lib/irb/debug.rb b/lib/irb/debug.rb
deleted file mode 100644
index 1ec2335a8e..0000000000
--- a/lib/irb/debug.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- module Debug
- IRB_DIR = File.expand_path('..', __dir__)
-
- class << self
- def insert_debug_break(pre_cmds: nil, do_cmds: nil)
- options = { oneshot: true, hook_call: false }
-
- if pre_cmds || do_cmds
- options[:command] = ['irb', pre_cmds, do_cmds]
- end
- if DEBUGGER__::LineBreakpoint.instance_method(:initialize).parameters.include?([:key, :skip_src])
- options[:skip_src] = true
- end
-
- # To make debugger commands like `next` or `continue` work without asking
- # the user to quit IRB after that, we need to exit IRB first and then hit
- # a TracePoint on #debug_break.
- file, lineno = IRB::Irb.instance_method(:debug_break).source_location
- DEBUGGER__::SESSION.add_line_breakpoint(file, lineno + 1, **options)
- end
-
- def setup(irb)
- # When debug session is not started at all
- unless defined?(DEBUGGER__::SESSION)
- begin
- require "debug/session"
- rescue LoadError # debug.gem is not written in Gemfile
- return false unless load_bundled_debug_gem
- end
- DEBUGGER__::CONFIG.set_config
- configure_irb_for_debugger(irb)
-
- DEBUGGER__.initialize_session{ IRB::Debug::UI.new(irb) }
- end
-
- # When debug session was previously started but not by IRB
- if defined?(DEBUGGER__::SESSION) && !irb.context.with_debugger
- configure_irb_for_debugger(irb)
- DEBUGGER__::SESSION.reset_ui(IRB::Debug::UI.new(irb))
- end
-
- # Apply patches to debug gem so it skips IRB frames
- unless DEBUGGER__.respond_to?(:capture_frames_without_irb)
- DEBUGGER__.singleton_class.send(:alias_method, :capture_frames_without_irb, :capture_frames)
-
- def DEBUGGER__.capture_frames(*args)
- frames = capture_frames_without_irb(*args)
- frames.reject! do |frame|
- frame.realpath&.start_with?(IRB_DIR) || frame.path == "<internal:prelude>"
- end
- frames
- end
-
- DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
- end
-
- if !@output_modifier_defined && !DEBUGGER__::CONFIG[:no_hint]
- irb_output_modifier_proc = Reline.output_modifier_proc
-
- Reline.output_modifier_proc = proc do |output, complete:|
- unless output.strip.empty?
- cmd = output.split(/\s/, 2).first
-
- if !complete && DEBUGGER__.commands.key?(cmd)
- output = output.sub(/\n$/, " # debug command\n")
- end
- end
-
- irb_output_modifier_proc.call(output, complete: complete)
- end
-
- @output_modifier_defined = true
- end
-
- true
- end
-
- private
-
- def configure_irb_for_debugger(irb)
- require 'irb/debug/ui'
- IRB.instance_variable_set(:@debugger_irb, irb)
- irb.context.with_debugger = true
- irb.context.irb_name += ":rdbg"
- end
-
- module SkipPathHelperForIRB
- def skip_internal_path?(path)
- # The latter can be removed once https://github.com/ruby/debug/issues/866 is resolved
- super || path.match?(IRB_DIR) || path.match?('<internal:prelude>')
- end
- end
-
- # This is used when debug.gem is not written in Gemfile. Even if it's not
- # installed by `bundle install`, debug.gem is installed by default because
- # it's a bundled gem. This method tries to activate and load that.
- def load_bundled_debug_gem
- # Discover latest debug.gem under GEM_PATH
- debug_gem = Gem.paths.path.flat_map { |path| Dir.glob("#{path}/gems/debug-*") }.select do |path|
- File.basename(path).match?(/\Adebug-\d+\.\d+\.\d+(\w+)?\z/)
- end.sort_by do |path|
- Gem::Version.new(File.basename(path).delete_prefix('debug-'))
- end.last
- return false unless debug_gem
-
- # Discover debug/debug.so under extensions for Ruby 3.2+
- ext_name = "/debug/debug.#{RbConfig::CONFIG['DLEXT']}"
- ext_path = Gem.paths.path.flat_map do |path|
- Dir.glob("#{path}/extensions/**/#{File.basename(debug_gem)}#{ext_name}")
- end.first
-
- # Attempt to forcibly load the bundled gem
- if ext_path
- $LOAD_PATH << ext_path.delete_suffix(ext_name)
- end
- $LOAD_PATH << "#{debug_gem}/lib"
- begin
- require "debug/session"
- puts "Loaded #{File.basename(debug_gem)}"
- true
- rescue LoadError
- false
- end
- end
- end
- end
-end
diff --git a/lib/irb/debug/ui.rb b/lib/irb/debug/ui.rb
deleted file mode 100644
index 307097b8c9..0000000000
--- a/lib/irb/debug/ui.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-require 'io/console/size'
-require 'debug/console'
-
-module IRB
- module Debug
- class UI < DEBUGGER__::UI_Base
- def initialize(irb)
- @irb = irb
- end
-
- def remote?
- false
- end
-
- def activate session, on_fork: false
- end
-
- def deactivate
- end
-
- def width
- if (w = IO.console_size[1]) == 0 # for tests PTY
- 80
- else
- w
- end
- end
-
- def quit n
- yield
- exit n
- end
-
- def ask prompt
- setup_interrupt do
- print prompt
- ($stdin.gets || '').strip
- end
- end
-
- def puts str = nil
- case str
- when Array
- str.each{|line|
- $stdout.puts line.chomp
- }
- when String
- str.each_line{|line|
- $stdout.puts line.chomp
- }
- when nil
- $stdout.puts
- end
- end
-
- def readline _
- setup_interrupt do
- tc = DEBUGGER__::SESSION.instance_variable_get(:@tc)
- cmd = @irb.debug_readline(tc.current_frame.binding || TOPLEVEL_BINDING)
-
- case cmd
- when nil # when user types C-d
- "continue"
- else
- cmd
- end
- end
- end
-
- def setup_interrupt
- DEBUGGER__::SESSION.intercept_trap_sigint false do
- current_thread = Thread.current # should be session_server thread
-
- prev_handler = trap(:INT){
- current_thread.raise Interrupt
- }
-
- yield
- ensure
- trap(:INT, prev_handler)
- end
- end
-
- def after_fork_parent
- parent_pid = Process.pid
-
- at_exit{
- DEBUGGER__::SESSION.intercept_trap_sigint_end
- trap(:SIGINT, :IGNORE)
-
- if Process.pid == parent_pid
- # only check child process from its parent
- begin
- # wait for all child processes to keep terminal
- Process.waitpid
- rescue Errno::ESRCH, Errno::ECHILD
- end
- end
- }
- end
- end
- end
-end
diff --git a/lib/irb/default_commands.rb b/lib/irb/default_commands.rb
deleted file mode 100644
index 1bbc68efa7..0000000000
--- a/lib/irb/default_commands.rb
+++ /dev/null
@@ -1,260 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "command"
-require_relative "command/internal_helpers"
-require_relative "command/context"
-require_relative "command/exit"
-require_relative "command/force_exit"
-require_relative "command/chws"
-require_relative "command/pushws"
-require_relative "command/subirb"
-require_relative "command/load"
-require_relative "command/debug"
-require_relative "command/edit"
-require_relative "command/break"
-require_relative "command/catch"
-require_relative "command/next"
-require_relative "command/delete"
-require_relative "command/step"
-require_relative "command/continue"
-require_relative "command/finish"
-require_relative "command/backtrace"
-require_relative "command/info"
-require_relative "command/help"
-require_relative "command/show_doc"
-require_relative "command/irb_info"
-require_relative "command/ls"
-require_relative "command/measure"
-require_relative "command/show_source"
-require_relative "command/whereami"
-require_relative "command/history"
-
-module IRB
- module Command
- NO_OVERRIDE = 0
- OVERRIDE_PRIVATE_ONLY = 0x01
- OVERRIDE_ALL = 0x02
-
- class << self
- # This API is for IRB's internal use only and may change at any time.
- # Please do NOT use it.
- def _register_with_aliases(name, command_class, *aliases)
- @commands[name.to_sym] = [command_class, aliases]
- end
-
- def all_commands_info
- user_aliases = IRB.CurrentContext.command_aliases.each_with_object({}) do |(alias_name, target), result|
- result[target] ||= []
- result[target] << alias_name
- end
-
- commands.map do |command_name, (command_class, aliases)|
- aliases = aliases.map { |a| a.first }
-
- if additional_aliases = user_aliases[command_name]
- aliases += additional_aliases
- end
-
- display_name = aliases.shift || command_name
- {
- display_name: display_name,
- description: command_class.description,
- category: command_class.category
- }
- end
- end
-
- def command_override_policies
- @@command_override_policies ||= commands.flat_map do |cmd_name, (cmd_class, aliases)|
- [[cmd_name, OVERRIDE_ALL]] + aliases
- end.to_h
- end
-
- def execute_as_command?(name, public_method:, private_method:)
- case command_override_policies[name]
- when OVERRIDE_ALL
- true
- when OVERRIDE_PRIVATE_ONLY
- !public_method
- when NO_OVERRIDE
- !public_method && !private_method
- end
- end
-
- def command_names
- command_override_policies.keys.map(&:to_s)
- end
-
- # Convert a command name to its implementation class if such command exists
- def load_command(command)
- command = command.to_sym
- commands.each do |command_name, (command_class, aliases)|
- if command_name == command || aliases.any? { |alias_name, _| alias_name == command }
- return command_class
- end
- end
- nil
- end
- end
-
- _register_with_aliases(:irb_context, Command::Context,
- [:context, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_exit, Command::Exit,
- [:exit, OVERRIDE_PRIVATE_ONLY],
- [:quit, OVERRIDE_PRIVATE_ONLY],
- [:irb_quit, OVERRIDE_PRIVATE_ONLY]
- )
-
- _register_with_aliases(:irb_exit!, Command::ForceExit,
- [:exit!, OVERRIDE_PRIVATE_ONLY]
- )
-
- _register_with_aliases(:irb_current_working_workspace, Command::CurrentWorkingWorkspace,
- [:cwws, NO_OVERRIDE],
- [:pwws, NO_OVERRIDE],
- [:irb_print_working_workspace, OVERRIDE_ALL],
- [:irb_cwws, OVERRIDE_ALL],
- [:irb_pwws, OVERRIDE_ALL],
- [:irb_current_working_binding, OVERRIDE_ALL],
- [:irb_print_working_binding, OVERRIDE_ALL],
- [:irb_cwb, OVERRIDE_ALL],
- [:irb_pwb, OVERRIDE_ALL],
- )
-
- _register_with_aliases(:irb_change_workspace, Command::ChangeWorkspace,
- [:chws, NO_OVERRIDE],
- [:cws, NO_OVERRIDE],
- [:irb_chws, OVERRIDE_ALL],
- [:irb_cws, OVERRIDE_ALL],
- [:irb_change_binding, OVERRIDE_ALL],
- [:irb_cb, OVERRIDE_ALL],
- [:cb, NO_OVERRIDE],
- )
-
- _register_with_aliases(:irb_workspaces, Command::Workspaces,
- [:workspaces, NO_OVERRIDE],
- [:irb_bindings, OVERRIDE_ALL],
- [:bindings, NO_OVERRIDE],
- )
-
- _register_with_aliases(:irb_push_workspace, Command::PushWorkspace,
- [:pushws, NO_OVERRIDE],
- [:irb_pushws, OVERRIDE_ALL],
- [:irb_push_binding, OVERRIDE_ALL],
- [:irb_pushb, OVERRIDE_ALL],
- [:pushb, NO_OVERRIDE],
- )
-
- _register_with_aliases(:irb_pop_workspace, Command::PopWorkspace,
- [:popws, NO_OVERRIDE],
- [:irb_popws, OVERRIDE_ALL],
- [:irb_pop_binding, OVERRIDE_ALL],
- [:irb_popb, OVERRIDE_ALL],
- [:popb, NO_OVERRIDE],
- )
-
- _register_with_aliases(:irb_load, Command::Load)
- _register_with_aliases(:irb_require, Command::Require)
- _register_with_aliases(:irb_source, Command::Source,
- [:source, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb, Command::IrbCommand)
- _register_with_aliases(:irb_jobs, Command::Jobs,
- [:jobs, NO_OVERRIDE]
- )
- _register_with_aliases(:irb_fg, Command::Foreground,
- [:fg, NO_OVERRIDE]
- )
- _register_with_aliases(:irb_kill, Command::Kill,
- [:kill, OVERRIDE_PRIVATE_ONLY]
- )
-
- _register_with_aliases(:irb_debug, Command::Debug,
- [:debug, NO_OVERRIDE]
- )
- _register_with_aliases(:irb_edit, Command::Edit,
- [:edit, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_break, Command::Break)
- _register_with_aliases(:irb_catch, Command::Catch)
- _register_with_aliases(:irb_next, Command::Next)
- _register_with_aliases(:irb_delete, Command::Delete,
- [:delete, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_step, Command::Step,
- [:step, NO_OVERRIDE]
- )
- _register_with_aliases(:irb_continue, Command::Continue,
- [:continue, NO_OVERRIDE]
- )
- _register_with_aliases(:irb_finish, Command::Finish,
- [:finish, NO_OVERRIDE]
- )
- _register_with_aliases(:irb_backtrace, Command::Backtrace,
- [:backtrace, NO_OVERRIDE],
- [:bt, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_debug_info, Command::Info,
- [:info, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_help, Command::Help,
- [:help, NO_OVERRIDE],
- [:show_cmds, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_show_doc, Command::ShowDoc,
- [:show_doc, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_info, Command::IrbInfo)
-
- _register_with_aliases(:irb_ls, Command::Ls,
- [:ls, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_measure, Command::Measure,
- [:measure, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_show_source, Command::ShowSource,
- [:show_source, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_whereami, Command::Whereami,
- [:whereami, NO_OVERRIDE]
- )
-
- _register_with_aliases(:irb_history, Command::History,
- [:history, NO_OVERRIDE],
- [:hist, NO_OVERRIDE]
- )
- end
-
- ExtendCommand = Command
-
- # For backward compatibility, we need to keep this module:
- # - As a container of helper methods
- # - As a place to register commands with the deprecated def_extend_command method
- module ExtendCommandBundle
- # For backward compatibility
- NO_OVERRIDE = Command::NO_OVERRIDE
- OVERRIDE_PRIVATE_ONLY = Command::OVERRIDE_PRIVATE_ONLY
- OVERRIDE_ALL = Command::OVERRIDE_ALL
-
- # Deprecated. Doesn't have any effect.
- @EXTEND_COMMANDS = []
-
- # Drepcated. Use Command.regiser instead.
- def self.def_extend_command(cmd_name, cmd_class, _, *aliases)
- Command._register_with_aliases(cmd_name, cmd_class, *aliases)
- Command.class_variable_set(:@@command_override_policies, nil)
- end
- end
-end
diff --git a/lib/irb/easter-egg.rb b/lib/irb/easter-egg.rb
index adc0834d55..3e79692de9 100644
--- a/lib/irb/easter-egg.rb
+++ b/lib/irb/easter-egg.rb
@@ -98,26 +98,18 @@ module IRB
end
end
- private def easter_egg_logo(type)
- @easter_egg_logos ||= File.read(File.join(__dir__, 'ruby_logo.aa'), encoding: 'UTF-8:UTF-8')
- .split(/TYPE: ([A-Z]+)\n/)[1..]
- .each_slice(2)
- .to_h
- @easter_egg_logos[type.to_s.upcase]
- end
-
private def easter_egg(type = nil)
type ||= [:logo, :dancing].sample
case type
when :logo
- require "rdoc"
- RDoc::RI::Driver.new.page do |io|
- io.write easter_egg_logo(:large)
+ File.open(File.join(__dir__, 'ruby_logo.aa')) do |f|
+ require "rdoc"
+ RDoc::RI::Driver.new.page do |io|
+ IO.copy_stream(f, io)
+ end
end
when :dancing
- STDOUT.cooked do
- interrupted = false
- prev_trap = trap("SIGINT") { interrupted = true }
+ begin
canvas = Canvas.new(Reline.get_screen_size)
Reline::IOGate.set_winch_handler do
canvas = Canvas.new(Reline.get_screen_size)
@@ -133,12 +125,10 @@ module IRB
buff[0, 20] = "\e[0mPress Ctrl+C to stop\e[31m\e[1m"
print "\e[H" + buff
sleep 0.05
- break if interrupted
end
rescue Interrupt
ensure
print "\e[0m\e[?1049l"
- trap("SIGINT", prev_trap)
end
end
end
diff --git a/lib/irb/ext/change-ws.rb b/lib/irb/ext/change-ws.rb
index 60e8afe31f..4c57e44eab 100644
--- a/lib/irb/ext/change-ws.rb
+++ b/lib/irb/ext/change-ws.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/ext/cb.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB # :nodoc:
class Context
@@ -12,7 +18,7 @@ module IRB # :nodoc:
if defined? @home_workspace
@home_workspace
else
- @home_workspace = workspace
+ @home_workspace = @workspace
end
end
@@ -25,13 +31,15 @@ module IRB # :nodoc:
# See IRB::WorkSpace.new for more information.
def change_workspace(*_main)
if _main.empty?
- replace_workspace(home_workspace)
+ @workspace = home_workspace
return main
end
- workspace = WorkSpace.new(_main[0])
- replace_workspace(workspace)
- workspace.load_helper_methods_to_main
+ @workspace = WorkSpace.new(_main[0])
+
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
+ main.extend ExtendCommandBundle
+ end
end
end
end
diff --git a/lib/irb/ext/eval_history.rb b/lib/irb/ext/eval_history.rb
deleted file mode 100644
index 6c21ff00ee..0000000000
--- a/lib/irb/ext/eval_history.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-# frozen_string_literal: true
-#
-# history.rb -
-# by Keiju ISHITSUKA(keiju@ruby-lang.org)
-#
-
-module IRB # :nodoc:
-
- class Context
-
- NOPRINTING_IVARS.push "@eval_history_values"
-
- # See #set_last_value
- alias _set_last_value set_last_value
-
- def set_last_value(value)
- _set_last_value(value)
-
- if defined?(@eval_history) && @eval_history
- @eval_history_values.push @line_no, @last_value
- workspace.evaluate "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
- end
-
- @last_value
- end
-
- remove_method :eval_history= if method_defined?(:eval_history=)
- # The command result history limit. This method is not available until
- # #eval_history= was called with non-nil value (directly or via
- # setting <code>IRB.conf[:EVAL_HISTORY]</code> in <code>.irbrc</code>).
- attr_reader :eval_history
- # Sets command result history limit. Default value is set from
- # <code>IRB.conf[:EVAL_HISTORY]</code>.
- #
- # +no+ is an Integer or +nil+.
- #
- # Returns +no+ of history items if greater than 0.
- #
- # If +no+ is 0, the number of history items is unlimited.
- #
- # If +no+ is +nil+, execution result history isn't used (default).
- #
- # EvalHistory values are available via <code>__</code> variable, see
- # IRB::EvalHistory.
- def eval_history=(no)
- if no
- if defined?(@eval_history) && @eval_history
- @eval_history_values.size(no)
- else
- @eval_history_values = EvalHistory.new(no)
- IRB.conf[:__TMP__EHV__] = @eval_history_values
- workspace.evaluate("__ = IRB.conf[:__TMP__EHV__]")
- IRB.conf.delete(:__TMP_EHV__)
- end
- else
- @eval_history_values = nil
- end
- @eval_history = no
- end
- end
-
- # Represents history of results of previously evaluated commands.
- #
- # Available via <code>__</code> variable, only if <code>IRB.conf[:EVAL_HISTORY]</code>
- # or <code>IRB::CurrentContext().eval_history</code> is non-nil integer value
- # (by default it is +nil+).
- #
- # Example (in `irb`):
- #
- # # Initialize history
- # IRB::CurrentContext().eval_history = 10
- # # => 10
- #
- # # Perform some commands...
- # 1 + 2
- # # => 3
- # puts 'x'
- # # x
- # # => nil
- # raise RuntimeError
- # # ...error raised
- #
- # # Inspect history (format is "<item number> <evaluated value>":
- # __
- # # => 1 10
- # # 2 3
- # # 3 nil
- #
- # __[1]
- # # => 10
- #
- class EvalHistory
-
- def initialize(size = 16) # :nodoc:
- @size = size
- @contents = []
- end
-
- def size(size) # :nodoc:
- if size != 0 && size < @size
- @contents = @contents[@size - size .. @size]
- end
- @size = size
- end
-
- # Get one item of the content (both positive and negative indexes work).
- def [](idx)
- begin
- if idx >= 0
- @contents.find{|no, val| no == idx}[1]
- else
- @contents[idx][1]
- end
- rescue NameError
- nil
- end
- end
-
- def push(no, val) # :nodoc:
- @contents.push [no, val]
- @contents.shift if @size != 0 && @contents.size > @size
- end
-
- alias real_inspect inspect
-
- def inspect # :nodoc:
- if @contents.empty?
- return real_inspect
- end
-
- unless (last = @contents.pop)[1].equal?(self)
- @contents.push last
- last = nil
- end
- str = @contents.collect{|no, val|
- if val.equal?(self)
- "#{no} ...self-history..."
- else
- "#{no} #{val.inspect}"
- end
- }.join("\n")
- if str == ""
- str = "Empty."
- end
- @contents.push last if last
- str
- end
- end
-end
diff --git a/lib/irb/ext/history.rb b/lib/irb/ext/history.rb
new file mode 100644
index 0000000000..fc304c6f6c
--- /dev/null
+++ b/lib/irb/ext/history.rb
@@ -0,0 +1,155 @@
+# frozen_string_literal: false
+#
+# history.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+
+ class Context
+
+ NOPRINTING_IVARS.push "@eval_history_values"
+
+ # See #set_last_value
+ alias _set_last_value set_last_value
+
+ def set_last_value(value)
+ _set_last_value(value)
+
+ if defined?(@eval_history) && @eval_history
+ @eval_history_values.push @line_no, @last_value
+ @workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
+ end
+
+ @last_value
+ end
+
+ remove_method :eval_history= if method_defined?(:eval_history=)
+ # The command result history limit. This method is not available until
+ # #eval_history= was called with non-nil value (directly or via
+ # setting <code>IRB.conf[:EVAL_HISTORY]</code> in <code>.irbrc</code>).
+ attr_reader :eval_history
+ # Sets command result history limit. Default value is set from
+ # <code>IRB.conf[:EVAL_HISTORY]</code>.
+ #
+ # +no+ is an Integer or +nil+.
+ #
+ # Returns +no+ of history items if greater than 0.
+ #
+ # If +no+ is 0, the number of history items is unlimited.
+ #
+ # If +no+ is +nil+, execution result history isn't used (default).
+ #
+ # History values are available via <code>__</code> variable, see
+ # IRB::History.
+ def eval_history=(no)
+ if no
+ if defined?(@eval_history) && @eval_history
+ @eval_history_values.size(no)
+ else
+ @eval_history_values = History.new(no)
+ IRB.conf[:__TMP__EHV__] = @eval_history_values
+ @workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
+ IRB.conf.delete(:__TMP_EHV__)
+ end
+ else
+ @eval_history_values = nil
+ end
+ @eval_history = no
+ end
+ end
+
+ # Represents history of results of previously evaluated commands.
+ #
+ # Available via <code>__</code> variable, only if <code>IRB.conf[:EVAL_HISTORY]</code>
+ # or <code>IRB::CurrentContext().eval_history</code> is non-nil integer value
+ # (by default it is +nil+).
+ #
+ # Example (in `irb`):
+ #
+ # # Initialize history
+ # IRB::CurrentContext().eval_history = 10
+ # # => 10
+ #
+ # # Perform some commands...
+ # 1 + 2
+ # # => 3
+ # puts 'x'
+ # # x
+ # # => nil
+ # raise RuntimeError
+ # # ...error raised
+ #
+ # # Inspect history (format is "<item number> <evaluated value>":
+ # __
+ # # => 1 10
+ # # 2 3
+ # # 3 nil
+ #
+ # __[1]
+ # # => 10
+ #
+ class History
+
+ def initialize(size = 16) # :nodoc:
+ @size = size
+ @contents = []
+ end
+
+ def size(size) # :nodoc:
+ if size != 0 && size < @size
+ @contents = @contents[@size - size .. @size]
+ end
+ @size = size
+ end
+
+ # Get one item of the content (both positive and negative indexes work).
+ def [](idx)
+ begin
+ if idx >= 0
+ @contents.find{|no, val| no == idx}[1]
+ else
+ @contents[idx][1]
+ end
+ rescue NameError
+ nil
+ end
+ end
+
+ def push(no, val) # :nodoc:
+ @contents.push [no, val]
+ @contents.shift if @size != 0 && @contents.size > @size
+ end
+
+ alias real_inspect inspect
+
+ def inspect # :nodoc:
+ if @contents.empty?
+ return real_inspect
+ end
+
+ unless (last = @contents.pop)[1].equal?(self)
+ @contents.push last
+ last = nil
+ end
+ str = @contents.collect{|no, val|
+ if val.equal?(self)
+ "#{no} ...self-history..."
+ else
+ "#{no} #{val.inspect}"
+ end
+ }.join("\n")
+ if str == ""
+ str = "Empty."
+ end
+ @contents.push last if last
+ str
+ end
+ end
+end
diff --git a/lib/irb/ext/loader.rb b/lib/irb/ext/loader.rb
index df5aaa8e5a..af028996e7 100644
--- a/lib/irb/ext/loader.rb
+++ b/lib/irb/ext/loader.rb
@@ -1,8 +1,15 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# loader.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
+
module IRB # :nodoc:
# Raised in the event of an exception in a file loaded from an Irb session
@@ -24,8 +31,31 @@ module IRB # :nodoc:
load_file(path, priv)
end
+ if File.respond_to?(:absolute_path?)
+ def absolute_path?(path)
+ File.absolute_path?(path)
+ end
+ else
+ separator =
+ if File::ALT_SEPARATOR
+ "[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]"
+ else
+ File::SEPARATOR
+ end
+ ABSOLUTE_PATH_PATTERN = # :nodoc:
+ case Dir.pwd
+ when /\A\w:/, /\A#{separator}{2}/
+ /\A(?:\w:|#{separator})#{separator}/
+ else
+ /\A#{separator}/
+ end
+ def absolute_path?(path)
+ ABSOLUTE_PATH_PATTERN =~ path
+ end
+ end
+
def search_file_from_ruby_path(fn) # :nodoc:
- if File.absolute_path?(fn)
+ if absolute_path?(fn)
return fn if File.exist?(fn)
return nil
end
@@ -42,7 +72,6 @@ module IRB # :nodoc:
#
# See Irb#suspend_input_method for more information.
def source_file(path)
- irb = irb_context.irb
irb.suspend_name(path, File.basename(path)) do
FileInputMethod.open(path) do |io|
irb.suspend_input_method(io) do
@@ -67,7 +96,6 @@ module IRB # :nodoc:
#
# See Irb#suspend_input_method for more information.
def load_file(path, priv = nil)
- irb = irb_context.irb
irb.suspend_name(path, File.basename(path)) do
if priv
@@ -98,13 +126,13 @@ module IRB # :nodoc:
def old # :nodoc:
back_io = @io
- back_path = irb_path
+ back_path = @irb_path
back_name = @irb_name
back_scanner = @irb.scanner
begin
@io = FileInputMethod.new(path)
@irb_name = File.basename(path)
- self.irb_path = path
+ @irb_path = path
@irb.signal_status(:IN_LOAD) do
if back_io.kind_of?(FileInputMethod)
@irb.eval_input
@@ -119,7 +147,7 @@ module IRB # :nodoc:
ensure
@io = back_io
@irb_name = back_name
- self.irb_path = back_path
+ @irb_path = back_path
@irb.scanner = back_scanner
end
end
diff --git a/lib/irb/ext/multi-irb.rb b/lib/irb/ext/multi-irb.rb
index 9f234f0cdc..e57d43a569 100644
--- a/lib/irb/ext/multi-irb.rb
+++ b/lib/irb/ext/multi-irb.rb
@@ -1,11 +1,17 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/multi-irb.rb - multiple irb module
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB
- class JobManager # :nodoc:
+ class JobManager
# Creates a new JobManager object
def initialize
@@ -166,12 +172,12 @@ module IRB
@JobManager = JobManager.new
# The current JobManager in the session
- def IRB.JobManager # :nodoc:
+ def IRB.JobManager
@JobManager
end
# The current Context in this session
- def IRB.CurrentContext # :nodoc:
+ def IRB.CurrentContext
IRB.JobManager.irb(Thread.current).context
end
@@ -179,7 +185,7 @@ module IRB
#
# The optional +file+ argument is given to Context.new, along with the
# workspace created with the remaining arguments, see WorkSpace.new
- def IRB.irb(file = nil, *main) # :nodoc:
+ def IRB.irb(file = nil, *main)
workspace = WorkSpace.new(*main)
parent_thread = Thread.current
Thread.start do
diff --git a/lib/irb/ext/save-history.rb b/lib/irb/ext/save-history.rb
new file mode 100644
index 0000000000..9e7620545a
--- /dev/null
+++ b/lib/irb/ext/save-history.rb
@@ -0,0 +1,130 @@
+# frozen_string_literal: false
+# save-history.rb -
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB
+ module HistorySavingAbility # :nodoc:
+ end
+
+ class Context
+ def init_save_history# :nodoc:
+ unless (class<<@io;self;end).include?(HistorySavingAbility)
+ @io.extend(HistorySavingAbility)
+ end
+ end
+
+ # A copy of the default <code>IRB.conf[:SAVE_HISTORY]</code>
+ def save_history
+ IRB.conf[:SAVE_HISTORY]
+ end
+
+ remove_method(:save_history=) if method_defined?(:save_history=)
+ # Sets <code>IRB.conf[:SAVE_HISTORY]</code> to the given +val+ and calls
+ # #init_save_history with this context.
+ #
+ # Will store the number of +val+ entries of history in the #history_file
+ #
+ # Add the following to your +.irbrc+ to change the number of history
+ # entries stored to 1000:
+ #
+ # IRB.conf[:SAVE_HISTORY] = 1000
+ def save_history=(val)
+ IRB.conf[:SAVE_HISTORY] = val
+ if val
+ main_context = IRB.conf[:MAIN_CONTEXT]
+ main_context = self unless main_context
+ main_context.init_save_history
+ end
+ end
+
+ # A copy of the default <code>IRB.conf[:HISTORY_FILE]</code>
+ def history_file
+ IRB.conf[:HISTORY_FILE]
+ end
+
+ # Set <code>IRB.conf[:HISTORY_FILE]</code> to the given +hist+.
+ def history_file=(hist)
+ IRB.conf[:HISTORY_FILE] = hist
+ end
+ end
+
+ module HistorySavingAbility # :nodoc:
+ def HistorySavingAbility.extended(obj)
+ IRB.conf[:AT_EXIT].push proc{obj.save_history}
+ obj.load_history
+ obj
+ end
+
+ def load_history
+ return unless self.class.const_defined?(:HISTORY)
+ history = self.class::HISTORY
+ if history_file = IRB.conf[:HISTORY_FILE]
+ history_file = File.expand_path(history_file)
+ end
+ history_file = IRB.rc_file("_history") unless history_file
+ if File.exist?(history_file)
+ File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
+ f.each { |l|
+ l = l.chomp
+ if self.class == RelineInputMethod and history.last&.end_with?("\\")
+ history.last.delete_suffix!("\\")
+ history.last << "\n" << l
+ else
+ history << l
+ end
+ }
+ end
+ @loaded_history_lines = history.size
+ @loaded_history_mtime = File.mtime(history_file)
+ end
+ end
+
+ def save_history
+ return unless self.class.const_defined?(:HISTORY)
+ history = self.class::HISTORY
+ if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) != 0
+ if history_file = IRB.conf[:HISTORY_FILE]
+ history_file = File.expand_path(history_file)
+ end
+ history_file = IRB.rc_file("_history") unless history_file
+
+ # Change the permission of a file that already exists[BUG #7694]
+ begin
+ if File.stat(history_file).mode & 066 != 0
+ File.chmod(0600, history_file)
+ end
+ rescue Errno::ENOENT
+ rescue Errno::EPERM
+ return
+ rescue
+ raise
+ end
+
+ if File.exist?(history_file) &&
+ File.mtime(history_file) != @loaded_history_mtime
+ history = history[@loaded_history_lines..-1] if @loaded_history_lines
+ append_history = true
+ end
+
+ File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
+ hist = history.map{ |l| l.split("\n").join("\\\n") }
+ unless append_history
+ begin
+ hist = hist.last(num) if hist.size > num and num > 0
+ rescue RangeError # bignum too big to convert into `long'
+ # Do nothing because the bignum should be treated as inifinity
+ end
+ end
+ f.puts(hist)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/irb/ext/tracer.rb b/lib/irb/ext/tracer.rb
index fd6daa88ae..67ac4bb965 100644
--- a/lib/irb/ext/tracer.rb
+++ b/lib/irb/ext/tracer.rb
@@ -1,39 +1,84 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/lib/tracer.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
-# Loading the gem "tracer" will cause it to extend IRB commands with:
-# https://github.com/ruby/tracer/blob/v0.2.2/lib/tracer/irb.rb
+# --
+#
+#
+#
begin
require "tracer"
rescue LoadError
- $stderr.puts "Tracer extension of IRB is enabled but tracer gem wasn't found."
+ $stderr.puts "Tracer extension of IRB is enabled but tracer gem doesn't found."
+ module IRB
+ TracerLoadError = true
+ class Context
+ def use_tracer=(opt)
+ # do nothing
+ end
+ end
+ end
return # This is about to disable loading below
end
module IRB
- class CallTracer < ::CallTracer
- IRB_DIR = File.expand_path('../..', __dir__)
- def skip?(tp)
- super || tp.path.match?(IRB_DIR) || tp.path.match?('<internal:prelude>')
+ # initialize tracing function
+ def IRB.initialize_tracer
+ Tracer.verbose = false
+ Tracer.add_filter {
+ |event, file, line, id, binding, *rests|
+ /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
+ File::basename(file) != "irb.rb"
+ }
+ end
+
+ class Context
+ # Whether Tracer is used when evaluating statements in this context.
+ #
+ # See +lib/tracer.rb+ for more information.
+ attr_reader :use_tracer
+ alias use_tracer? use_tracer
+
+ # Sets whether or not to use the Tracer library when evaluating statements
+ # in this context.
+ #
+ # See +lib/tracer.rb+ for more information.
+ def use_tracer=(opt)
+ if opt
+ Tracer.set_get_line_procs(@irb_path) {
+ |line_no, *rests|
+ @io.line(line_no)
+ }
+ elsif !opt && @use_tracer
+ Tracer.off
+ end
+ @use_tracer=opt
end
end
+
class WorkSpace
alias __evaluate__ evaluate
# Evaluate the context of this workspace and use the Tracer library to
# output the exact lines of code are being executed in chronological order.
#
- # See https://github.com/ruby/tracer for more information.
- def evaluate(statements, file = __FILE__, line = __LINE__)
- if IRB.conf[:USE_TRACER] == true
- CallTracer.new(colorize: Color.colorable?).start do
- __evaluate__(statements, file, line)
+ # See +lib/tracer.rb+ for more information.
+ def evaluate(context, statements, file = nil, line = nil)
+ if context.use_tracer? && file != nil && line != nil
+ Tracer.on
+ begin
+ __evaluate__(context, statements, file, line)
+ ensure
+ Tracer.off
end
else
- __evaluate__(statements, file, line)
+ __evaluate__(context, statements, file || __FILE__, line || __LINE__)
end
end
end
+
+ IRB.initialize_tracer
end
diff --git a/lib/irb/ext/use-loader.rb b/lib/irb/ext/use-loader.rb
index c8a3ea1fe8..1897bc89e0 100644
--- a/lib/irb/ext/use-loader.rb
+++ b/lib/irb/ext/use-loader.rb
@@ -1,10 +1,16 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# use-loader.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
-require_relative "../command/load"
+require_relative "../cmd/load"
require_relative "loader"
class Object
@@ -17,12 +23,12 @@ module IRB
remove_method :irb_load if method_defined?(:irb_load)
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
def irb_load(*opts, &b)
- Command::Load.execute(irb_context, *opts, &b)
+ ExtendCommand::Load.execute(irb_context, *opts, &b)
end
remove_method :irb_require if method_defined?(:irb_require)
# Loads the given file similarly to Kernel#require
def irb_require(*opts, &b)
- Command::Require.execute(irb_context, *opts, &b)
+ ExtendCommand::Require.execute(irb_context, *opts, &b)
end
end
@@ -49,12 +55,14 @@ module IRB
if IRB.conf[:USE_LOADER] != opt
IRB.conf[:USE_LOADER] = opt
if opt
- (class<<workspace.main;self;end).instance_eval {
+ if !$".include?("irb/cmd/load")
+ end
+ (class<<@workspace.main;self;end).instance_eval {
alias_method :load, :irb_load
alias_method :require, :irb_require
}
else
- (class<<workspace.main;self;end).instance_eval {
+ (class<<@workspace.main;self;end).instance_eval {
alias_method :load, :__original__load__IRB_use_loader__
alias_method :require, :__original__require__IRB_use_loader__
}
diff --git a/lib/irb/ext/workspaces.rb b/lib/irb/ext/workspaces.rb
index da09faa83e..730b58e64d 100644
--- a/lib/irb/ext/workspaces.rb
+++ b/lib/irb/ext/workspaces.rb
@@ -1,11 +1,32 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# push-ws.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB # :nodoc:
class Context
+
+ # Size of the current WorkSpace stack
+ def irb_level
+ workspace_stack.size
+ end
+
+ # WorkSpaces in the current stack
+ def workspaces
+ if defined? @workspaces
+ @workspaces
+ else
+ @workspaces = []
+ end
+ end
+
# Creates a new workspace with the given object or binding, and appends it
# onto the current #workspaces stack.
#
@@ -13,15 +34,20 @@ module IRB # :nodoc:
# information.
def push_workspace(*_main)
if _main.empty?
- if @workspace_stack.size > 1
- # swap the top two workspaces
- previous_workspace, current_workspace = @workspace_stack.pop(2)
- @workspace_stack.push current_workspace, previous_workspace
+ if workspaces.empty?
+ print "No other workspace\n"
+ return nil
end
- else
- new_workspace = WorkSpace.new(workspace.binding, _main[0])
- @workspace_stack.push new_workspace
- new_workspace.load_helper_methods_to_main
+ ws = workspaces.pop
+ workspaces.push @workspace
+ @workspace = ws
+ return workspaces
+ end
+
+ workspaces.push @workspace
+ @workspace = WorkSpace.new(@workspace.binding, _main[0])
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
+ main.extend ExtendCommandBundle
end
end
@@ -30,7 +56,11 @@ module IRB # :nodoc:
#
# Also, see #push_workspace.
def pop_workspace
- @workspace_stack.pop if @workspace_stack.size > 1
+ if workspaces.empty?
+ print "workspace stack empty\n"
+ return
+ end
+ @workspace = workspaces.pop
end
end
end
diff --git a/lib/irb/extend-command.rb b/lib/irb/extend-command.rb
new file mode 100644
index 0000000000..d0829a06c4
--- /dev/null
+++ b/lib/irb/extend-command.rb
@@ -0,0 +1,433 @@
+# frozen_string_literal: false
+#
+# irb/extend-command.rb - irb extend command
+# $Release Version: 0.9.6$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+module IRB # :nodoc:
+ # Installs the default irb extensions command bundle.
+ module ExtendCommandBundle
+ EXCB = ExtendCommandBundle # :nodoc:
+
+ # See #install_alias_method.
+ NO_OVERRIDE = 0
+ # See #install_alias_method.
+ OVERRIDE_PRIVATE_ONLY = 0x01
+ # See #install_alias_method.
+ OVERRIDE_ALL = 0x02
+
+ # Quits the current irb context
+ #
+ # +ret+ is the optional signal or message to send to Context#exit
+ #
+ # Same as <code>IRB.CurrentContext.exit</code>.
+ def irb_exit(ret = 0)
+ irb_context.exit(ret)
+ end
+
+ # Displays current configuration.
+ #
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
+ def irb_context
+ IRB.CurrentContext
+ end
+
+ @ALIASES = [
+ [:context, :irb_context, NO_OVERRIDE],
+ [:conf, :irb_context, NO_OVERRIDE],
+ [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
+ [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
+ [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
+ ]
+
+
+ @EXTEND_COMMANDS = [
+ [
+ :irb_current_working_workspace, :CurrentWorkingWorkspace, "cmd/chws",
+ [:cwws, NO_OVERRIDE],
+ [:pwws, NO_OVERRIDE],
+ [:irb_print_working_workspace, OVERRIDE_ALL],
+ [:irb_cwws, OVERRIDE_ALL],
+ [:irb_pwws, OVERRIDE_ALL],
+ [:irb_current_working_binding, OVERRIDE_ALL],
+ [:irb_print_working_binding, OVERRIDE_ALL],
+ [:irb_cwb, OVERRIDE_ALL],
+ [:irb_pwb, OVERRIDE_ALL],
+ ],
+ [
+ :irb_change_workspace, :ChangeWorkspace, "cmd/chws",
+ [:chws, NO_OVERRIDE],
+ [:cws, NO_OVERRIDE],
+ [:irb_chws, OVERRIDE_ALL],
+ [:irb_cws, OVERRIDE_ALL],
+ [:irb_change_binding, OVERRIDE_ALL],
+ [:irb_cb, OVERRIDE_ALL],
+ [:cb, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_workspaces, :Workspaces, "cmd/pushws",
+ [:workspaces, NO_OVERRIDE],
+ [:irb_bindings, OVERRIDE_ALL],
+ [:bindings, NO_OVERRIDE],
+ ],
+ [
+ :irb_push_workspace, :PushWorkspace, "cmd/pushws",
+ [:pushws, NO_OVERRIDE],
+ [:irb_pushws, OVERRIDE_ALL],
+ [:irb_push_binding, OVERRIDE_ALL],
+ [:irb_pushb, OVERRIDE_ALL],
+ [:pushb, NO_OVERRIDE],
+ ],
+ [
+ :irb_pop_workspace, :PopWorkspace, "cmd/pushws",
+ [:popws, NO_OVERRIDE],
+ [:irb_popws, OVERRIDE_ALL],
+ [:irb_pop_binding, OVERRIDE_ALL],
+ [:irb_popb, OVERRIDE_ALL],
+ [:popb, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_load, :Load, "cmd/load"],
+ [
+ :irb_require, :Require, "cmd/load"],
+ [
+ :irb_source, :Source, "cmd/load",
+ [:source, NO_OVERRIDE],
+ ],
+
+ [
+ :irb, :IrbCommand, "cmd/subirb"],
+ [
+ :irb_jobs, :Jobs, "cmd/subirb",
+ [:jobs, NO_OVERRIDE],
+ ],
+ [
+ :irb_fg, :Foreground, "cmd/subirb",
+ [:fg, NO_OVERRIDE],
+ ],
+ [
+ :irb_kill, :Kill, "cmd/subirb",
+ [:kill, OVERRIDE_PRIVATE_ONLY],
+ ],
+
+ [
+ :irb_debug, :Debug, "cmd/debug",
+ [:debug, NO_OVERRIDE],
+ ],
+ [
+ :irb_edit, :Edit, "cmd/edit",
+ [:edit, NO_OVERRIDE],
+ ],
+ [
+ :irb_break, :Break, "cmd/break",
+ ],
+ [
+ :irb_catch, :Catch, "cmd/catch",
+ ],
+ [
+ :irb_next, :Next, "cmd/next"
+ ],
+ [
+ :irb_delete, :Delete, "cmd/delete",
+ [:delete, NO_OVERRIDE],
+ ],
+ [
+ :irb_step, :Step, "cmd/step",
+ [:step, NO_OVERRIDE],
+ ],
+ [
+ :irb_continue, :Continue, "cmd/continue",
+ [:continue, NO_OVERRIDE],
+ ],
+ [
+ :irb_finish, :Finish, "cmd/finish",
+ [:finish, NO_OVERRIDE],
+ ],
+ [
+ :irb_backtrace, :Backtrace, "cmd/backtrace",
+ [:backtrace, NO_OVERRIDE],
+ [:bt, NO_OVERRIDE],
+ ],
+ [
+ :irb_debug_info, :Info, "cmd/info",
+ [:info, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_help, :Help, "cmd/help",
+ [:show_doc, NO_OVERRIDE],
+ [:help, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_info, :IrbInfo, "cmd/irb_info"
+ ],
+
+ [
+ :irb_ls, :Ls, "cmd/ls",
+ [:ls, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_measure, :Measure, "cmd/measure",
+ [:measure, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_show_source, :ShowSource, "cmd/show_source",
+ [:show_source, NO_OVERRIDE],
+ ],
+
+ [
+ :irb_whereami, :Whereami, "cmd/whereami",
+ [:whereami, NO_OVERRIDE],
+ ],
+ [
+ :irb_show_cmds, :ShowCmds, "cmd/show_cmds",
+ [:show_cmds, NO_OVERRIDE],
+ ]
+ ]
+
+
+ @@commands = []
+
+ def self.all_commands_info
+ return @@commands unless @@commands.empty?
+ user_aliases = IRB.CurrentContext.command_aliases.each_with_object({}) do |(alias_name, target), result|
+ result[target] ||= []
+ result[target] << alias_name
+ end
+
+ @EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
+ if !defined?(ExtendCommand) || !ExtendCommand.const_defined?(cmd_class, false)
+ require_relative load_file
+ end
+
+ klass = ExtendCommand.const_get(cmd_class, false)
+ aliases = aliases.map { |a| a.first }
+
+ if additional_aliases = user_aliases[cmd_name]
+ aliases += additional_aliases
+ end
+
+ display_name = aliases.shift || cmd_name
+ @@commands << { display_name: display_name, description: klass.description, category: klass.category }
+ end
+
+ @@commands
+ end
+
+ # Convert a command name to its implementation class if such command exists
+ def self.load_command(command)
+ command = command.to_sym
+ @EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
+ next if cmd_name != command && aliases.all? { |alias_name, _| alias_name != command }
+
+ if !defined?(ExtendCommand) || !ExtendCommand.const_defined?(cmd_class, false)
+ require_relative load_file
+ end
+ return ExtendCommand.const_get(cmd_class, false)
+ end
+ nil
+ end
+
+ # Installs the default irb commands.
+ def self.install_extend_commands
+ for args in @EXTEND_COMMANDS
+ def_extend_command(*args)
+ end
+ end
+
+ # Evaluate the given +cmd_name+ on the given +cmd_class+ Class.
+ #
+ # Will also define any given +aliases+ for the method.
+ #
+ # The optional +load_file+ parameter will be required within the method
+ # definition.
+ def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
+ case cmd_class
+ when Symbol
+ cmd_class = cmd_class.id2name
+ when String
+ when Class
+ cmd_class = cmd_class.name
+ end
+
+ if load_file
+ kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
+ line = __LINE__; eval %[
+ def #{cmd_name}(*opts#{kwargs}, &b)
+ require_relative "#{load_file}"
+ arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
+ args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
+ args << "*opts#{kwargs}" if arity < 0
+ args << "&block"
+ args = args.join(", ")
+ line = __LINE__; eval %[
+ unless singleton_class.class_variable_defined?(:@@#{cmd_name}_)
+ singleton_class.class_variable_set(:@@#{cmd_name}_, true)
+ def self.#{cmd_name}_(\#{args})
+ ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
+ end
+ end
+ ], nil, __FILE__, line
+ __send__ :#{cmd_name}_, *opts#{kwargs}, &b
+ end
+ ], nil, __FILE__, line
+ else
+ line = __LINE__; eval %[
+ def #{cmd_name}(*opts, &b)
+ ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
+ end
+ ], nil, __FILE__, line
+ end
+
+ for ali, flag in aliases
+ @ALIASES.push [ali, cmd_name, flag]
+ end
+ end
+
+ # Installs alias methods for the default irb commands, see
+ # ::install_extend_commands.
+ def install_alias_method(to, from, override = NO_OVERRIDE)
+ to = to.id2name unless to.kind_of?(String)
+ from = from.id2name unless from.kind_of?(String)
+
+ if override == OVERRIDE_ALL or
+ (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
+ (override == NO_OVERRIDE) && !respond_to?(to, true)
+ target = self
+ (class << self; self; end).instance_eval{
+ if target.respond_to?(to, true) &&
+ !target.respond_to?(EXCB.irb_original_method_name(to), true)
+ alias_method(EXCB.irb_original_method_name(to), to)
+ end
+ alias_method to, from
+ }
+ else
+ Kernel.print "irb: warn: can't alias #{to} from #{from}.\n"
+ end
+ end
+
+ def self.irb_original_method_name(method_name) # :nodoc:
+ "irb_" + method_name + "_org"
+ end
+
+ # Installs alias methods for the default irb commands on the given object
+ # using #install_alias_method.
+ def self.extend_object(obj)
+ unless (class << obj; ancestors; end).include?(EXCB)
+ super
+ for ali, com, flg in @ALIASES
+ obj.install_alias_method(ali, com, flg)
+ end
+ end
+ end
+
+ install_extend_commands
+ end
+
+ # Extends methods for the Context module
+ module ContextExtender
+ CE = ContextExtender # :nodoc:
+
+ @EXTEND_COMMANDS = [
+ [:eval_history=, "ext/history.rb"],
+ [:use_tracer=, "ext/tracer.rb"],
+ [:use_loader=, "ext/use-loader.rb"],
+ [:save_history=, "ext/save-history.rb"],
+ ]
+
+ # Installs the default context extensions as irb commands:
+ #
+ # Context#eval_history=:: +irb/ext/history.rb+
+ # Context#use_tracer=:: +irb/ext/tracer.rb+
+ # Context#use_loader=:: +irb/ext/use-loader.rb+
+ # Context#save_history=:: +irb/ext/save-history.rb+
+ def self.install_extend_commands
+ for args in @EXTEND_COMMANDS
+ def_extend_command(*args)
+ end
+ end
+
+ # Evaluate the given +command+ from the given +load_file+ on the Context
+ # module.
+ #
+ # Will also define any given +aliases+ for the method.
+ def self.def_extend_command(cmd_name, load_file, *aliases)
+ line = __LINE__; Context.module_eval %[
+ def #{cmd_name}(*opts, &b)
+ Context.module_eval {remove_method(:#{cmd_name})}
+ require_relative "#{load_file}"
+ __send__ :#{cmd_name}, *opts, &b
+ end
+ for ali in aliases
+ alias_method ali, cmd_name
+ end
+ ], __FILE__, line
+ end
+
+ CE.install_extend_commands
+ end
+
+ # A convenience module for extending Ruby methods.
+ module MethodExtender
+ # Extends the given +base_method+ with a prefix call to the given
+ # +extend_method+.
+ def def_pre_proc(base_method, extend_method)
+ base_method = base_method.to_s
+ extend_method = extend_method.to_s
+
+ alias_name = new_alias_name(base_method)
+ module_eval %[
+ alias_method alias_name, base_method
+ def #{base_method}(*opts)
+ __send__ :#{extend_method}, *opts
+ __send__ :#{alias_name}, *opts
+ end
+ ]
+ end
+
+ # Extends the given +base_method+ with a postfix call to the given
+ # +extend_method+.
+ def def_post_proc(base_method, extend_method)
+ base_method = base_method.to_s
+ extend_method = extend_method.to_s
+
+ alias_name = new_alias_name(base_method)
+ module_eval %[
+ alias_method alias_name, base_method
+ def #{base_method}(*opts)
+ __send__ :#{alias_name}, *opts
+ __send__ :#{extend_method}, *opts
+ end
+ ]
+ end
+
+ # Returns a unique method name to use as an alias for the given +name+.
+ #
+ # Usually returns <code>#{prefix}#{name}#{postfix}<num></code>, example:
+ #
+ # new_alias_name('foo') #=> __alias_of__foo__
+ # def bar; end
+ # new_alias_name('bar') #=> __alias_of__bar__2
+ def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
+ base_name = "#{prefix}#{name}#{postfix}"
+ all_methods = instance_methods(true) + private_instance_methods(true)
+ same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
+ return base_name if same_methods.empty?
+ no = same_methods.size
+ while !same_methods.include?(alias_name = base_name + no)
+ no += 1
+ end
+ alias_name
+ end
+ end
+end
diff --git a/lib/irb/frame.rb b/lib/irb/frame.rb
index 4b697c8719..de54a98f1b 100644
--- a/lib/irb/frame.rb
+++ b/lib/irb/frame.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# frame.rb -
+# $Release Version: 0.9$
+# $Revision$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
+# --
+#
+#
+#
module IRB
class Frame
diff --git a/lib/irb/help.rb b/lib/irb/help.rb
index a24bc10a15..3eeaf841b0 100644
--- a/lib/irb/help.rb
+++ b/lib/irb/help.rb
@@ -1,16 +1,24 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/help.rb - print usage module
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
+# --
+#
+#
+#
+
+require_relative 'magic-file'
module IRB
- # Outputs the irb help message, see IRB@Command-Line+Options.
- def IRB.print_usage # :nodoc:
+ # Outputs the irb help message, see IRB@Command+line+options.
+ def IRB.print_usage
lc = IRB.conf[:LC_MESSAGES]
path = lc.find("irb/help-message")
space_line = false
- File.open(path){|f|
+ IRB::MagicFile.open(path){|f|
f.each_line do |l|
if /^\s*$/ =~ l
lc.puts l unless space_line
diff --git a/lib/irb/helper_method.rb b/lib/irb/helper_method.rb
deleted file mode 100644
index f1f6fff915..0000000000
--- a/lib/irb/helper_method.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require_relative "helper_method/base"
-
-module IRB
- module HelperMethod
- @helper_methods = {}
-
- class << self
- attr_reader :helper_methods
-
- def register(name, helper_class)
- @helper_methods[name] = helper_class
-
- if defined?(HelpersContainer)
- HelpersContainer.install_helper_methods
- end
- end
-
- def all_helper_methods_info
- @helper_methods.map do |name, helper_class|
- { display_name: name, description: helper_class.description }
- end
- end
- end
-
- # Default helper_methods
- require_relative "helper_method/conf"
- register(:conf, HelperMethod::Conf)
- end
-end
diff --git a/lib/irb/helper_method/base.rb b/lib/irb/helper_method/base.rb
deleted file mode 100644
index a68001ed28..0000000000
--- a/lib/irb/helper_method/base.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require "singleton"
-
-module IRB
- module HelperMethod
- class Base
- include Singleton
-
- class << self
- def description(description = nil)
- @description = description if description
- @description
- end
- end
- end
- end
-end
diff --git a/lib/irb/helper_method/conf.rb b/lib/irb/helper_method/conf.rb
deleted file mode 100644
index 718ed279c0..0000000000
--- a/lib/irb/helper_method/conf.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module IRB
- module HelperMethod
- class Conf < Base
- description "Returns the current IRB context."
-
- def execute
- IRB.CurrentContext
- end
- end
- end
-end
diff --git a/lib/irb/history.rb b/lib/irb/history.rb
deleted file mode 100644
index 685354b2d8..0000000000
--- a/lib/irb/history.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-require "pathname"
-
-module IRB
- module HistorySavingAbility # :nodoc:
- def support_history_saving?
- true
- end
-
- def reset_history_counter
- @loaded_history_lines = self.class::HISTORY.size
- end
-
- def load_history
- history = self.class::HISTORY
-
- if history_file = IRB.conf[:HISTORY_FILE]
- history_file = File.expand_path(history_file)
- end
- history_file = IRB.rc_file("_history") unless history_file
- if history_file && File.exist?(history_file)
- File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
- f.each { |l|
- l = l.chomp
- if self.class == RelineInputMethod and history.last&.end_with?("\\")
- history.last.delete_suffix!("\\")
- history.last << "\n" << l
- else
- history << l
- end
- }
- end
- @loaded_history_lines = history.size
- @loaded_history_mtime = File.mtime(history_file)
- end
- end
-
- def save_history
- history = self.class::HISTORY.to_a
-
- if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) != 0
- if history_file = IRB.conf[:HISTORY_FILE]
- history_file = File.expand_path(history_file)
- end
- history_file = IRB.rc_file("_history") unless history_file
-
- # When HOME and XDG_CONFIG_HOME are not available, history_file might be nil
- return unless history_file
-
- # Change the permission of a file that already exists[BUG #7694]
- begin
- if File.stat(history_file).mode & 066 != 0
- File.chmod(0600, history_file)
- end
- rescue Errno::ENOENT
- rescue Errno::EPERM
- return
- rescue
- raise
- end
-
- if File.exist?(history_file) &&
- File.mtime(history_file) != @loaded_history_mtime
- history = history[@loaded_history_lines..-1] if @loaded_history_lines
- append_history = true
- end
-
- pathname = Pathname.new(history_file)
- unless Dir.exist?(pathname.dirname)
- warn "Warning: The directory to save IRB's history file does not exist. Please double check `IRB.conf[:HISTORY_FILE]`'s value."
- return
- end
-
- File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
- hist = history.map{ |l| l.scrub.split("\n").join("\\\n") }
- unless append_history
- begin
- hist = hist.last(num) if hist.size > num and num > 0
- rescue RangeError # bignum too big to convert into `long'
- # Do nothing because the bignum should be treated as infinity
- end
- end
- f.puts(hist)
- end
- end
- end
- end
-end
diff --git a/lib/irb/init.rb b/lib/irb/init.rb
index 355047519c..55453cc8f7 100644
--- a/lib/irb/init.rb
+++ b/lib/irb/init.rb
@@ -1,50 +1,16 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/init.rb - irb initialize module
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB # :nodoc:
- @CONF = {}
- @INITIALIZED = false
- # Displays current configuration.
- #
- # Modifying the configuration is achieved by sending a message to IRB.conf.
- #
- # See IRB@Configuration for more information.
- def IRB.conf
- @CONF
- end
-
- def @CONF.inspect
- array = []
- for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
- case k
- when :MAIN_CONTEXT, :__TMP__EHV__
- array.push format("CONF[:%s]=...myself...", k.id2name)
- when :PROMPT
- s = v.collect{
- |kk, vv|
- ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
- format(":%s=>{%s}", kk.id2name, ss.join(", "))
- }
- array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
- else
- array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
- end
- end
- array.join("\n")
- end
-
- # Returns the current version of IRB, including release version and last
- # updated date.
- def IRB.version
- format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
- end
-
- def IRB.initialized?
- !!@INITIALIZED
- end
# initialize config
def IRB.setup(ap_path, argv: ::ARGV)
@@ -57,16 +23,17 @@ module IRB # :nodoc:
unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
fail UndefinedPromptMode, @CONF[:PROMPT_MODE]
end
- @INITIALIZED = true
end
# @CONF default setting
def IRB.init_config(ap_path)
+ # class instance variables
+ @TRACER_INITIALIZED = false
+
# default configurations
unless ap_path and @CONF[:AP_NAME]
ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
end
- @CONF[:VERSION] = version
@CONF[:AP_NAME] = File::basename(ap_path, ".rb")
@CONF[:IRB_NAME] = "irb"
@@ -79,13 +46,11 @@ module IRB # :nodoc:
@CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
@CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
@CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false"
- @CONF[:COMPLETOR] = ENV.fetch("IRB_COMPLETOR", "regexp").to_sym
@CONF[:INSPECT_MODE] = true
@CONF[:USE_TRACER] = false
@CONF[:USE_LOADER] = false
@CONF[:IGNORE_SIGINT] = true
@CONF[:IGNORE_EOF] = false
- @CONF[:USE_PAGER] = true
@CONF[:EXTRA_DOC_DIRS] = []
@CONF[:ECHO] = nil
@CONF[:ECHO_ON_ASSIGNMENT] = nil
@@ -99,30 +64,35 @@ module IRB # :nodoc:
@CONF[:PROMPT] = {
:NULL => {
:PROMPT_I => nil,
+ :PROMPT_N => nil,
:PROMPT_S => nil,
:PROMPT_C => nil,
:RETURN => "%s\n"
},
:DEFAULT => {
- :PROMPT_I => "%N(%m):%03n> ",
- :PROMPT_S => "%N(%m):%03n%l ",
- :PROMPT_C => "%N(%m):%03n* ",
+ :PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => "%N(%m):%03n:%i> ",
+ :PROMPT_S => "%N(%m):%03n:%i%l ",
+ :PROMPT_C => "%N(%m):%03n:%i* ",
:RETURN => "=> %s\n"
},
:CLASSIC => {
:PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => "%N(%m):%03n:%i> ",
:PROMPT_S => "%N(%m):%03n:%i%l ",
:PROMPT_C => "%N(%m):%03n:%i* ",
:RETURN => "%s\n"
},
:SIMPLE => {
:PROMPT_I => ">> ",
+ :PROMPT_N => ">> ",
:PROMPT_S => "%l> ",
:PROMPT_C => "?> ",
:RETURN => "=> %s\n"
},
:INF_RUBY => {
- :PROMPT_I => "%N(%m):%03n> ",
+ :PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => nil,
:PROMPT_S => nil,
:PROMPT_C => nil,
:RETURN => "%s\n",
@@ -130,6 +100,7 @@ module IRB # :nodoc:
},
:XMP => {
:PROMPT_I => nil,
+ :PROMPT_N => nil,
:PROMPT_S => nil,
:PROMPT_C => nil,
:RETURN => " ==>%s\n"
@@ -192,6 +163,10 @@ module IRB # :nodoc:
# Symbol aliases
:'$' => :show_source,
:'@' => :whereami,
+ # Keyword aliases
+ :break => :irb_break,
+ :catch => :irb_catch,
+ :next => :irb_next,
}
end
@@ -218,7 +193,6 @@ module IRB # :nodoc:
added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg]
end
if added
- IRB.conf[:MEASURE] = true
found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
if found
# already added
@@ -239,7 +213,6 @@ module IRB # :nodoc:
type_sym = type.upcase.to_sym
IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, | t == type_sym }
end
- IRB.conf[:MEASURE] = nil if IRB.conf[:MEASURE_CALLBACKS].empty?
end
def IRB.init_error
@@ -287,8 +260,6 @@ module IRB # :nodoc:
end
when "--noinspect"
@CONF[:INSPECT_MODE] = false
- when "--no-pager"
- @CONF[:USE_PAGER] = false
when "--singleline", "--readline", "--legacy"
@CONF[:USE_SINGLELINE] = true
when "--nosingleline", "--noreadline"
@@ -334,10 +305,6 @@ module IRB # :nodoc:
@CONF[:USE_AUTOCOMPLETE] = true
when "--noautocomplete"
@CONF[:USE_AUTOCOMPLETE] = false
- when "--regexp-completor"
- @CONF[:COMPLETOR] = :regexp
- when "--type-completor"
- @CONF[:COMPLETOR] = :type
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
opt = $1 || argv.shift
prompt_mode = opt.upcase.tr("-", "_").intern
@@ -392,39 +359,61 @@ module IRB # :nodoc:
$LOAD_PATH.unshift(*load_path)
end
- # Run the config file
+ # running config
def IRB.run_config
if @CONF[:RC]
- irbrc_files.each do |rc|
- load rc
- rescue StandardError, ScriptError => e
- warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}"
+ begin
+ load rc_file
+ rescue LoadError, Errno::ENOENT
+ rescue # StandardError, ScriptError
+ print "load error: #{rc_file}\n"
+ print $!.class, ": ", $!, "\n"
+ for err in $@[0, $@.size - 2]
+ print "\t", err, "\n"
+ end
end
end
end
IRBRC_EXT = "rc"
-
- def IRB.rc_file(ext)
- prepare_irbrc_name_generators
-
- # When irbrc exist in default location
- if (rcgen = @existing_rc_name_generators.first)
- return rcgen.call(ext)
+ def IRB.rc_file(ext = IRBRC_EXT)
+ if !@CONF[:RC_NAME_GENERATOR]
+ rc_file_generators do |rcgen|
+ @CONF[:RC_NAME_GENERATOR] ||= rcgen
+ if File.exist?(rcgen.call(IRBRC_EXT))
+ @CONF[:RC_NAME_GENERATOR] = rcgen
+ break
+ end
+ end
end
-
- # When irbrc does not exist in default location
- rc_file_generators do |rcgen|
- return rcgen.call(ext)
+ case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
+ when String
+ return rc_file
+ else
+ fail IllegalRCNameGenerator
end
-
- # When HOME and XDG_CONFIG_HOME are not available
- nil
end
- def IRB.irbrc_files
- prepare_irbrc_name_generators
- @irbrc_files
+ # enumerate possible rc-file base name generators
+ def IRB.rc_file_generators
+ if irbrc = ENV["IRBRC"]
+ yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
+ end
+ if xdg_config_home = ENV["XDG_CONFIG_HOME"]
+ irb_home = File.join(xdg_config_home, "irb")
+ if File.directory?(irb_home)
+ yield proc{|rc| irb_home + "/irb#{rc}"}
+ end
+ end
+ if home = ENV["HOME"]
+ yield proc{|rc| home+"/.irb#{rc}"}
+ end
+ current_dir = Dir.pwd
+ yield proc{|rc| current_dir+"/.config/irb/irb#{rc}"}
+ yield proc{|rc| current_dir+"/.irb#{rc}"}
+ yield proc{|rc| current_dir+"/irb#{rc.sub(/\A_?/, '.')}"}
+ yield proc{|rc| current_dir+"/_irb#{rc}"}
+ yield proc{|rc| current_dir+"/$irb#{rc}"}
end
# loading modules
@@ -438,52 +427,10 @@ module IRB # :nodoc:
end
end
+
+ DefaultEncodings = Struct.new(:external, :internal)
class << IRB
private
-
- def prepare_irbrc_name_generators
- return if @existing_rc_name_generators
-
- @existing_rc_name_generators = []
- @irbrc_files = []
- rc_file_generators do |rcgen|
- irbrc = rcgen.call(IRBRC_EXT)
- if File.exist?(irbrc)
- @irbrc_files << irbrc
- @existing_rc_name_generators << rcgen
- end
- end
- generate_current_dir_irbrc_files.each do |irbrc|
- @irbrc_files << irbrc if File.exist?(irbrc)
- end
- @irbrc_files.uniq!
- end
-
- # enumerate possible rc-file base name generators
- def rc_file_generators
- if irbrc = ENV["IRBRC"]
- yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
- end
- if xdg_config_home = ENV["XDG_CONFIG_HOME"]
- irb_home = File.join(xdg_config_home, "irb")
- if File.directory?(irb_home)
- yield proc{|rc| irb_home + "/irb#{rc}"}
- end
- end
- if home = ENV["HOME"]
- yield proc{|rc| home+"/.irb#{rc}"}
- if xdg_config_home.nil? || xdg_config_home.empty?
- yield proc{|rc| home+"/.config/irb/irb#{rc}"}
- end
- end
- end
-
- # possible irbrc files in current directory
- def generate_current_dir_irbrc_files
- current_dir = Dir.pwd
- %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{current_dir}/#{file}" }
- end
-
def set_encoding(extern, intern = nil, override: true)
verbose, $VERBOSE = $VERBOSE, nil
Encoding.default_external = extern unless extern.nil? || extern.empty?
diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb
index 684527edc4..9480573195 100644
--- a/lib/irb/input-method.rb
+++ b/lib/irb/input-method.rb
@@ -1,17 +1,30 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/input-method.rb - input methods used irb
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
-
+# --
+#
+#
+#
+require_relative 'src_encoding'
+require_relative 'magic-file'
require_relative 'completion'
-require_relative "history"
require 'io/console'
require 'reline'
module IRB
+ STDIN_FILE_NAME = "(line)" # :nodoc:
class InputMethod
- BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
+
+ # Creates a new input method object
+ def initialize(file = STDIN_FILE_NAME)
+ @file_name = file
+ end
+ # The file name of this input method, usually given during initialization.
+ attr_reader :file_name
# The irb prompt associated with this input method
attr_accessor :prompt
@@ -20,7 +33,7 @@ module IRB
#
# See IO#gets for more information.
def gets
- fail NotImplementedError
+ fail NotImplementedError, "gets"
end
public :gets
@@ -40,14 +53,6 @@ module IRB
false
end
- def support_history_saving?
- false
- end
-
- def prompting?
- false
- end
-
# For debug message
def inspect
'Abstract InputMethod'
@@ -57,6 +62,7 @@ module IRB
class StdioInputMethod < InputMethod
# Creates a new input method object
def initialize
+ super
@line_no = 0
@line = []
@stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
@@ -67,7 +73,6 @@ module IRB
#
# See IO#gets for more information.
def gets
- puts if @stdout.tty? # workaround for debug compatibility test
print @prompt
line = @stdin.gets
@line[@line_no += 1] = line
@@ -96,10 +101,6 @@ module IRB
true
end
- def prompting?
- STDIN.tty?
- end
-
# Returns the current line number for #io.
#
# #line counts the number of times #gets is called.
@@ -135,9 +136,12 @@ module IRB
# Creates a new input method object
def initialize(file)
- @io = file.is_a?(IO) ? file : File.open(file)
+ super
+ @io = file.is_a?(IO) ? file : IRB::MagicFile.open(file)
@external_encoding = @io.external_encoding
end
+ # The file name of this input method, usually given during initialization.
+ attr_reader :file_name
# Whether the end of this input method has been reached, returns +true+ if
# there is no more data to read.
@@ -170,99 +174,114 @@ module IRB
end
end
- class ReadlineInputMethod < StdioInputMethod
- def self.initialize_readline
- require "readline"
- rescue LoadError
- else
- include ::Readline
- end
+ begin
+ class ReadlineInputMethod < InputMethod
+ def self.initialize_readline
+ require "readline"
+ rescue LoadError
+ else
+ include ::Readline
+ end
- include HistorySavingAbility
+ # Creates a new input method object using Readline
+ def initialize
+ self.class.initialize_readline
+ if Readline.respond_to?(:encoding_system_needs)
+ IRB.__send__(:set_encoding, Readline.encoding_system_needs.name, override: false)
+ end
+ super
- # Creates a new input method object using Readline
- def initialize
- self.class.initialize_readline
- if Readline.respond_to?(:encoding_system_needs)
- IRB.__send__(:set_encoding, Readline.encoding_system_needs.name, override: false)
- end
+ @line_no = 0
+ @line = []
+ @eof = false
- super
+ @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
- @eof = false
- @completor = RegexpCompletor.new
+ if Readline.respond_to?("basic_word_break_characters=")
+ Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
+ end
+ Readline.completion_append_character = nil
+ Readline.completion_proc = IRB::InputCompletor::CompletionProc
+ end
- if Readline.respond_to?("basic_word_break_characters=")
- Readline.basic_word_break_characters = BASIC_WORD_BREAK_CHARACTERS
+ # Reads the next line from this input method.
+ #
+ # See IO#gets for more information.
+ def gets
+ Readline.input = @stdin
+ Readline.output = @stdout
+ if l = readline(@prompt, false)
+ HISTORY.push(l) if !l.empty?
+ @line[@line_no += 1] = l + "\n"
+ else
+ @eof = true
+ l
+ end
end
- Readline.completion_append_character = nil
- Readline.completion_proc = ->(target) {
- bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
- @completor.completion_candidates('', target, '', bind: bind)
- }
- end
- def completion_info
- 'RegexpCompletor'
- end
+ # Whether the end of this input method has been reached, returns +true+
+ # if there is no more data to read.
+ #
+ # See IO#eof? for more information.
+ def eof?
+ @eof
+ end
- # Reads the next line from this input method.
- #
- # See IO#gets for more information.
- def gets
- Readline.input = @stdin
- Readline.output = @stdout
- if l = readline(@prompt, false)
- HISTORY.push(l) if !l.empty?
- @line[@line_no += 1] = l + "\n"
- else
- @eof = true
- l
+ # Whether this input method is still readable when there is no more data to
+ # read.
+ #
+ # See IO#eof for more information.
+ def readable_after_eof?
+ true
end
- end
- # Whether the end of this input method has been reached, returns +true+
- # if there is no more data to read.
- #
- # See IO#eof? for more information.
- def eof?
- @eof
- end
+ # Returns the current line number for #io.
+ #
+ # #line counts the number of times #gets is called.
+ #
+ # See IO#lineno for more information.
+ def line(line_no)
+ @line[line_no]
+ end
- def prompting?
- true
- end
+ # The external encoding for standard input.
+ def encoding
+ @stdin.external_encoding
+ end
- # For debug message
- def inspect
- readline_impl = (defined?(Reline) && Readline == Reline) ? 'Reline' : 'ext/readline'
- str = "ReadlineInputMethod with #{readline_impl} #{Readline::VERSION}"
- inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
- str += " and #{inputrc_path}" if File.exist?(inputrc_path)
- str
+ # For debug message
+ def inspect
+ readline_impl = (defined?(Reline) && Readline == Reline) ? 'Reline' : 'ext/readline'
+ str = "ReadlineInputMethod with #{readline_impl} #{Readline::VERSION}"
+ inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
+ str += " and #{inputrc_path}" if File.exist?(inputrc_path)
+ str
+ end
end
end
- class RelineInputMethod < StdioInputMethod
- HISTORY = Reline::HISTORY
- include HistorySavingAbility
+ class RelineInputMethod < InputMethod
+ include Reline
+
# Creates a new input method object using Reline
- def initialize(completor)
+ def initialize
IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
+ super
- super()
-
+ @line_no = 0
+ @line = []
@eof = false
- @completor = completor
- Reline.basic_word_break_characters = BASIC_WORD_BREAK_CHARACTERS
+ @stdin = ::IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ @stdout = ::IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+
+ if Reline.respond_to?("basic_word_break_characters=")
+ Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
+ end
Reline.completion_append_character = nil
Reline.completer_quote_characters = ''
- Reline.completion_proc = ->(target, preposing, postposing) {
- bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
- @completion_params = [preposing, target, postposing, bind]
- @completor.completion_candidates(preposing, target, postposing, bind: bind)
- }
+ Reline.completion_proc = IRB::InputCompletor::CompletionProc
Reline.output_modifier_proc =
if IRB.conf[:USE_COLORIZE]
proc do |output, complete: |
@@ -275,23 +294,18 @@ module IRB
Reline::Unicode.escape_for_print(output)
end
end
- Reline.dig_perfect_match_proc = ->(matched) { display_document(matched) }
+ Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
if IRB.conf[:USE_AUTOCOMPLETE]
begin
require 'rdoc'
- Reline.add_dialog_proc(:show_doc, show_doc_dialog_proc, Reline::DEFAULT_DIALOG_CONTEXT)
+ Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
rescue LoadError
end
end
end
- def completion_info
- autocomplete_message = Reline.autocompletion ? 'Autocomplete' : 'Tab Complete'
- "#{autocomplete_message}, #{@completor.inspect}"
- end
-
def check_termination(&block)
@check_termination_proc = block
end
@@ -304,164 +318,98 @@ module IRB
@auto_indent_proc = block
end
- def retrieve_doc_namespace(matched)
- preposing, _target, postposing, bind = @completion_params
- @completor.doc_namespace(preposing, matched, postposing, bind: bind)
- end
-
- def rdoc_ri_driver
- return @rdoc_ri_driver if defined?(@rdoc_ri_driver)
+ SHOW_DOC_DIALOG = ->() {
+ dialog.trap_key = nil
+ alt_d = [
+ [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
+ [27, 100], # Normal Alt+d when convert-meta isn't used.
+ [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
+ [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
+ ]
- begin
- require 'rdoc'
- rescue LoadError
- @rdoc_ri_driver = nil
- else
- options = {}
- options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
- @rdoc_ri_driver = RDoc::RI::Driver.new(options)
+ if just_cursor_moving and completion_journey_data.nil?
+ return nil
end
- end
+ cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4)
+ return nil if result.nil? or pointer.nil? or pointer < 0
+ name = result[pointer]
+ name = IRB::InputCompletor.retrieve_completion_data(name, doc_namespace: true)
- def show_doc_dialog_proc
- input_method = self # self is changed in the lambda below.
- ->() {
- dialog.trap_key = nil
- alt_d = [
- [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
- [27, 100], # Normal Alt+d when convert-meta isn't used.
- [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
- [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
- ]
-
- if just_cursor_moving and completion_journey_data.nil?
- return nil
- end
- cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4)
- return nil if result.nil? or pointer.nil? or pointer < 0
+ options = {}
+ options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
+ driver = RDoc::RI::Driver.new(options)
- name = input_method.retrieve_doc_namespace(result[pointer])
- # Use first one because document dialog does not support multiple namespaces.
- name = name.first if name.is_a?(Array)
-
- show_easter_egg = name&.match?(/\ARubyVM/) && !ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
-
- driver = input_method.rdoc_ri_driver
-
- if key.match?(dialog.name)
- if show_easter_egg
- IRB.__send__(:easter_egg)
- else
- begin
- driver.display_names([name])
- rescue RDoc::RI::Driver::NotFoundError
- end
- end
+ if key.match?(dialog.name)
+ begin
+ driver.display_names([name])
+ rescue RDoc::RI::Driver::NotFoundError
end
+ end
+ begin
+ name = driver.expand_name(name)
+ rescue RDoc::RI::Driver::NotFoundError
+ return nil
+ rescue
+ return nil # unknown error
+ end
+ doc = nil
+ used_for_class = false
+ if not name =~ /#|\./
+ found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
+ if not found.empty?
+ doc = driver.class_document(name, found, klasses, includes, extends)
+ used_for_class = true
+ end
+ end
+ unless used_for_class
+ doc = RDoc::Markup::Document.new
begin
- name = driver.expand_name(name)
+ driver.add_method(doc, name)
rescue RDoc::RI::Driver::NotFoundError
- return nil
+ doc = nil
rescue
return nil # unknown error
end
- doc = nil
- used_for_class = false
- if not name =~ /#|\./
- found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
- if not found.empty?
- doc = driver.class_document(name, found, klasses, includes, extends)
- used_for_class = true
- end
- end
- unless used_for_class
- doc = RDoc::Markup::Document.new
- begin
- driver.add_method(doc, name)
- rescue RDoc::RI::Driver::NotFoundError
- doc = nil
- rescue
- return nil # unknown error
- end
- end
- return nil if doc.nil?
- width = 40
-
- right_x = cursor_pos_to_render.x + autocomplete_dialog.width
- if right_x + width > screen_width
- right_width = screen_width - (right_x + 1)
- left_x = autocomplete_dialog.column - width
- left_x = 0 if left_x < 0
- left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
- if right_width.positive? and left_width.positive?
- if right_width >= left_width
- width = right_width
- x = right_x
- else
- width = left_width
- x = left_x
- end
- elsif right_width.positive? and left_width <= 0
+ end
+ return nil if doc.nil?
+ width = 40
+
+ right_x = cursor_pos_to_render.x + autocomplete_dialog.width
+ if right_x + width > screen_width
+ right_width = screen_width - (right_x + 1)
+ left_x = autocomplete_dialog.column - width
+ left_x = 0 if left_x < 0
+ left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
+ if right_width.positive? and left_width.positive?
+ if right_width >= left_width
width = right_width
x = right_x
- elsif right_width <= 0 and left_width.positive?
+ else
width = left_width
x = left_x
- else # Both are negative width.
- return nil
end
- else
+ elsif right_width.positive? and left_width <= 0
+ width = right_width
x = right_x
+ elsif right_width <= 0 and left_width.positive?
+ width = left_width
+ x = left_x
+ else # Both are negative width.
+ return nil
end
- formatter = RDoc::Markup::ToAnsi.new
- formatter.width = width
- dialog.trap_key = alt_d
- mod_key = RUBY_PLATFORM.match?(/darwin/) ? "Option" : "Alt"
- if show_easter_egg
- type = STDOUT.external_encoding == Encoding::UTF_8 ? :unicode : :ascii
- contents = IRB.send(:easter_egg_logo, type).split("\n")
- message = "Press #{mod_key}+d to see more"
- contents[0][0, message.size] = message
- else
- message = "Press #{mod_key}+d to read the full document"
- contents = [message] + doc.accept(formatter).split("\n")
- end
- contents = contents.take(preferred_dialog_height)
-
- y = cursor_pos_to_render.y
- Reline::DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
- }
- end
-
- def display_document(matched)
- driver = rdoc_ri_driver
- return unless driver
-
- if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
- IRB.__send__(:easter_egg)
- return
- end
-
- namespace = retrieve_doc_namespace(matched)
- return unless namespace
-
- if namespace.is_a?(Array)
- out = RDoc::Markup::Document.new
- namespace.each do |m|
- begin
- driver.add_method(out, m)
- rescue RDoc::RI::Driver::NotFoundError
- end
- end
- driver.display(out)
else
- begin
- driver.display_names([namespace])
- rescue RDoc::RI::Driver::NotFoundError
- end
+ x = right_x
end
- end
+ formatter = RDoc::Markup::ToAnsi.new
+ formatter.width = width
+ dialog.trap_key = alt_d
+ message = 'Press Alt+d to read the full document'
+ contents = [message] + doc.accept(formatter).split("\n")
+
+ y = cursor_pos_to_render.y
+ DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
+ }
# Reads the next line from this input method.
#
@@ -471,8 +419,8 @@ module IRB
Reline.output = @stdout
Reline.prompt_proc = @prompt_proc
Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc
- if l = Reline.readmultiline(@prompt, false, &@check_termination_proc)
- Reline::HISTORY.push(l) if !l.empty?
+ if l = readmultiline(@prompt, false, &@check_termination_proc)
+ HISTORY.push(l) if !l.empty?
@line[@line_no += 1] = l + "\n"
else
@eof = true
@@ -488,15 +436,37 @@ module IRB
@eof
end
- def prompting?
+ # Whether this input method is still readable when there is no more data to
+ # read.
+ #
+ # See IO#eof for more information.
+ def readable_after_eof?
true
end
+ # Returns the current line number for #io.
+ #
+ # #line counts the number of times #gets is called.
+ #
+ # See IO#lineno for more information.
+ def line(line_no)
+ @line[line_no]
+ end
+
+ # The external encoding for standard input.
+ def encoding
+ @stdin.external_encoding
+ end
+
# For debug message
def inspect
config = Reline::Config.new
str = "RelineInputMethod with Reline #{Reline::VERSION}"
- inputrc_path = File.expand_path(config.inputrc_path)
+ if config.respond_to?(:inputrc_path)
+ inputrc_path = File.expand_path(config.inputrc_path)
+ else
+ inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
+ end
str += " and #{inputrc_path}" if File.exist?(inputrc_path)
str
end
diff --git a/lib/irb/inspector.rb b/lib/irb/inspector.rb
index 667087ccba..d8c0ba90cf 100644
--- a/lib/irb/inspector.rb
+++ b/lib/irb/inspector.rb
@@ -1,8 +1,15 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/inspector.rb - inspect methods
+# $Release Version: 0.9.6$
+# $Revision: 1.19 $
+# $Date: 2002/06/11 07:51:31 $
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB # :nodoc:
@@ -35,7 +42,6 @@ module IRB # :nodoc:
# irb(main):001:0> "what?" #=> omg! what?
#
class Inspector
- KERNEL_INSPECT = Object.instance_method(:inspect)
# Default inspectors available to irb, this includes:
#
# +:pp+:: Using Kernel#pretty_inspect
@@ -46,7 +52,7 @@ module IRB # :nodoc:
# Determines the inspector to use where +inspector+ is one of the keys passed
# during inspector definition.
def self.keys_with_inspector(inspector)
- INSPECTORS.select{|k, v| v == inspector}.collect{|k, v| k}
+ INSPECTORS.select{|k,v| v == inspector}.collect{|k, v| k}
end
# Example
@@ -94,17 +100,9 @@ module IRB # :nodoc:
# Proc to call when the input is evaluated and output in irb.
def inspect_value(v)
@inspect.call(v)
- rescue => e
- puts "An error occurred when inspecting the object: #{e.inspect}"
-
- begin
- puts "Result of Kernel#inspect: #{KERNEL_INSPECT.bind_call(v)}"
- ''
- rescue => e
- puts "An error occurred when running Kernel#inspect: #{e.inspect}"
- puts e.backtrace.join("\n")
- ''
- end
+ rescue
+ puts "(Object doesn't support #inspect)"
+ ''
end
end
@@ -113,7 +111,7 @@ module IRB # :nodoc:
Color.colorize_code(v.inspect, colorable: Color.colorable? && Color.inspect_colorable?(v))
}
Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v|
- IRB::ColorPrinter.pp(v, +'').chomp
+ IRB::ColorPrinter.pp(v, '').chomp
}
Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
begin
diff --git a/lib/irb/irb.gemspec b/lib/irb/irb.gemspec
index b29002f593..c3e8a4dc58 100644
--- a/lib/irb/irb.gemspec
+++ b/lib/irb/irb.gemspec
@@ -16,11 +16,6 @@ Gem::Specification.new do |spec|
spec.homepage = "https://github.com/ruby/irb"
spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
- spec.metadata["documentation_uri"] = spec.homepage
- spec.metadata["changelog_uri"] = "#{spec.homepage}/releases"
-
spec.files = [
".document",
"Gemfile",
@@ -39,8 +34,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6")
- spec.add_dependency "reline", ">= 0.4.2"
- spec.add_dependency "rdoc", ">= 4.0.0"
+ spec.add_dependency "reline", ">= 0.3.0"
end
diff --git a/lib/irb/lc/error.rb b/lib/irb/lc/error.rb
index ee0f047822..cb5c21cdb4 100644
--- a/lib/irb/lc/error.rb
+++ b/lib/irb/lc/error.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/lc/error.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB
# :stopdoc:
@@ -12,6 +18,11 @@ module IRB
super("Unrecognized switch: #{val}")
end
end
+ class NotImplementedError < StandardError
+ def initialize(val)
+ super("Need to define `#{val}'")
+ end
+ end
class CantReturnToNormalMode < StandardError
def initialize
super("Can't return to normal mode.")
@@ -47,6 +58,11 @@ module IRB
super("Undefined prompt mode(#{val}).")
end
end
+ class IllegalRCGenerator < StandardError
+ def initialize
+ super("Define illegal RC_NAME_GENERATOR.")
+ end
+ end
# :startdoc:
end
diff --git a/lib/irb/lc/help-message b/lib/irb/lc/help-message
index 37347306e8..5b23f4c41e 100644
--- a/lib/irb/lc/help-message
+++ b/lib/irb/lc/help-message
@@ -22,18 +22,14 @@ Usage: irb.rb [options] [programfile] [arguments]
Show truncated result on assignment (default).
--inspect Use 'inspect' for output.
--noinspect Don't use 'inspect' for output.
- --no-pager Don't use pager.
- --multiline Use multiline editor module (default).
- --nomultiline Don't use multiline editor module.
+ --multiline Use multiline editor module.
+ --nomultiline Don't use multiline editor module (default).
--singleline Use single line editor module.
--nosingleline Don't use single line editor module (default).
--colorize Use color-highlighting (default).
--nocolorize Don't use color-highlighting.
--autocomplete Use auto-completion (default).
--noautocomplete Don't use auto-completion.
- --regexp-completor
- Use regexp based completion (default).
- --type-completor Use type based completion.
--prompt prompt-mode, --prompt-mode prompt-mode
Set prompt mode. Pre-defined prompt modes are:
'default', 'classic', 'simple', 'inf-ruby', 'xmp', 'null'.
diff --git a/lib/irb/lc/ja/encoding_aliases.rb b/lib/irb/lc/ja/encoding_aliases.rb
new file mode 100644
index 0000000000..08180c3ec2
--- /dev/null
+++ b/lib/irb/lc/ja/encoding_aliases.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: false
+module IRB
+ # :stopdoc:
+
+ class Locale
+ @@legacy_encoding_alias_map = {
+ 'ujis' => Encoding::EUC_JP,
+ 'euc' => Encoding::EUC_JP
+ }.freeze
+ end
+
+ # :startdoc:
+end
diff --git a/lib/irb/lc/ja/error.rb b/lib/irb/lc/ja/error.rb
index 9e2e5b8870..5e3622cbae 100644
--- a/lib/irb/lc/ja/error.rb
+++ b/lib/irb/lc/ja/error.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
-#
+# -*- coding: utf-8 -*-
+# frozen_string_literal: false
# irb/lc/ja/error.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB
# :stopdoc:
@@ -12,6 +18,11 @@ module IRB
super("スイッãƒ(#{val})ãŒåˆ†ã‚Šã¾ã›ã‚“")
end
end
+ class NotImplementedError < StandardError
+ def initialize(val)
+ super("`#{val}'ã®å®šç¾©ãŒå¿…è¦ã§ã™")
+ end
+ end
class CantReturnToNormalMode < StandardError
def initialize
super("Normalãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã‚Œã¾ã›ã‚“.")
@@ -47,6 +58,11 @@ module IRB
super("プロンプトモード(#{val})ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“.")
end
end
+ class IllegalRCGenerator < StandardError
+ def initialize
+ super("RC_NAME_GENERATORãŒæ­£ã—ã定義ã•れã¦ã„ã¾ã›ã‚“.")
+ end
+ end
# :startdoc:
end
diff --git a/lib/irb/lc/ja/help-message b/lib/irb/lc/ja/help-message
index 99f4449b3b..1c15d331ea 100644
--- a/lib/irb/lc/ja/help-message
+++ b/lib/irb/lc/ja/help-message
@@ -9,18 +9,10 @@ Usage: irb.rb [options] [programfile] [arguments]
-W[level=2] ruby -W ã¨åŒã˜.
--context-mode n æ–°ã—ã„ワークスペースを作æˆã—ãŸæ™‚ã«é–¢é€£ã™ã‚‹ Binding
オブジェクトã®ä½œæˆæ–¹æ³•ã‚’ 0 ã‹ã‚‰ 3 ã®ã„ãšã‚Œã‹ã«è¨­å®šã™ã‚‹.
- --extra-doc-dir 指定ã—ãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’追加ã§èª­ã¿è¾¼ã‚€.
--echo å®Ÿè¡Œçµæžœã‚’表示ã™ã‚‹(デフォルト).
--noecho å®Ÿè¡Œçµæžœã‚’表示ã—ãªã„.
- --echo-on-assignment
- ä»£å…¥çµæžœã‚’表示ã™ã‚‹.
- --noecho-on-assignment
- ä»£å…¥çµæžœã‚’表示ã—ãªã„.
- --truncate-echo-on-assignment
- truncateã•れãŸä»£å…¥çµæžœã‚’表示ã™ã‚‹(デフォルト).
--inspect çµæžœå‡ºåŠ›ã«inspectを用ã„ã‚‹.
--noinspect çµæžœå‡ºåŠ›ã«inspectを用ã„ãªã„.
- --no-pager ページャを使用ã—ãªã„.
--multiline マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’利用ã™ã‚‹.
--nomultiline マルãƒãƒ©ã‚¤ãƒ³ã‚¨ãƒ‡ã‚£ã‚¿ã‚’利用ã—ãªã„.
--singleline シングルラインエディタを利用ã™ã‚‹.
@@ -29,9 +21,6 @@ Usage: irb.rb [options] [programfile] [arguments]
--nocolorize 色付ã‘を利用ã—ãªã„.
--autocomplete オートコンプリートを利用ã™ã‚‹.
--noautocomplete オートコンプリートを利用ã—ãªã„.
- --regexp-completor
- è£œå®Œã«æ­£è¦è¡¨ç¾ã‚’利用ã™ã‚‹.
- --type-completor 補完ã«åž‹æƒ…報を利用ã™ã‚‹.
--prompt prompt-mode/--prompt-mode prompt-mode
プロンプトモードを切替ãˆã¾ã™. ç¾åœ¨å®šç¾©ã•れã¦ã„るプ
ロンプトモードã¯, default, simple, xmp, inf-rubyãŒ
@@ -42,8 +31,6 @@ Usage: irb.rb [options] [programfile] [arguments]
--sample-book-mode/--simple-prompt
éžå¸¸ã«ã‚·ãƒ³ãƒ—ルãªãƒ—ロンプトを用ã„るモードã§ã™.
--noprompt プロンプト表示を行ãªã‚ãªã„.
- --script スクリプトモード(最åˆã®å¼•数をスクリプトファイルã¨ã—ã¦æ‰±ã†ã€ãƒ‡ãƒ•ォルト)
- --noscript 引数をargvã¨ã—ã¦æ‰±ã†.
--single-irb irb 中㧠self を実行ã—ã¦å¾—られるオブジェクトをサ
ブ irb ã¨å…±æœ‰ã™ã‚‹.
--tracer コマンド実行時ã«ãƒˆãƒ¬ãƒ¼ã‚¹ã‚’行ãªã†.
diff --git a/lib/irb/locale.rb b/lib/irb/locale.rb
index 2abcc7354b..bb44b41002 100644
--- a/lib/irb/locale.rb
+++ b/lib/irb/locale.rb
@@ -1,9 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/locale.rb - internationalization module
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
-
+# --
+#
+#
+#
module IRB # :nodoc:
class Locale
@@ -15,11 +20,7 @@ module IRB # :nodoc:
]x
LOCALE_DIR = "/lc/"
- LEGACY_ENCODING_ALIAS_MAP = {
- 'ujis' => Encoding::EUC_JP,
- 'euc' => Encoding::EUC_JP
- }
-
+ @@legacy_encoding_alias_map = {}.freeze
@@loaded = []
def initialize(locale = nil)
@@ -30,11 +31,11 @@ module IRB # :nodoc:
@lang, @territory, @encoding_name, @modifier = m[:language], m[:territory], m[:codeset], m[:modifier]
if @encoding_name
- if @encoding = LEGACY_ENCODING_ALIAS_MAP[@encoding_name]
+ begin load 'irb/encoding_aliases.rb'; rescue LoadError; end
+ if @encoding = @@legacy_encoding_alias_map[@encoding_name]
warn(("%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]), uplevel: 1)
- else
- @encoding = Encoding.find(@encoding_name) rescue nil
end
+ @encoding = Encoding.find(@encoding_name) rescue nil
end
end
@encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT)
@@ -82,19 +83,46 @@ module IRB # :nodoc:
super(*ary)
end
- def load(file)
+ def require(file, priv = nil)
+ rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?")
+ return false if $".find{|f| f =~ rex}
+
+ case file
+ when /\.rb$/
+ begin
+ load(file, priv)
+ $".push file
+ return true
+ rescue LoadError
+ end
+ when /\.(so|o|sl)$/
+ return super
+ end
+
+ begin
+ load(f = file + ".rb")
+ $".push f #"
+ return true
+ rescue LoadError
+ return ruby_require(file)
+ end
+ end
+
+ alias toplevel_load load
+
+ def load(file, priv=nil)
found = find(file)
if found
unless @@loaded.include?(found)
@@loaded << found # cache
- Kernel.load(found)
+ return real_load(found, priv)
end
else
raise LoadError, "No such file to load -- #{file}"
end
end
- def find(file, paths = $:)
+ def find(file , paths = $:)
dir = File.dirname(file)
dir = "" if dir == "."
base = File.basename(file)
@@ -106,6 +134,16 @@ module IRB # :nodoc:
end
end
+ private
+ def real_load(path, priv)
+ src = MagicFile.open(path){|f| f.read}
+ if priv
+ eval("self", TOPLEVEL_BINDING).extend(Module.new {eval(src, nil, path)})
+ else
+ eval(src, TOPLEVEL_BINDING, path)
+ end
+ end
+
# @param paths load paths in which IRB find a localized file.
# @param dir directory
# @param file basename to be localized
diff --git a/lib/irb/magic-file.rb b/lib/irb/magic-file.rb
new file mode 100644
index 0000000000..34e06d64b3
--- /dev/null
+++ b/lib/irb/magic-file.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: false
+module IRB
+ class << (MagicFile = Object.new)
+ # see parser_magic_comment in parse.y
+ ENCODING_SPEC_RE = %r"coding\s*[=:]\s*([[:alnum:]\-_]+)"
+
+ def open(path)
+ io = File.open(path, 'rb')
+ line = io.gets
+ line = io.gets if line[0,2] == "#!"
+ encoding = detect_encoding(line)
+ internal_encoding = encoding
+ encoding ||= IRB.default_src_encoding
+ io.rewind
+ io.set_encoding(encoding, internal_encoding)
+
+ if block_given?
+ begin
+ return (yield io)
+ ensure
+ io.close
+ end
+ else
+ return io
+ end
+ end
+
+ private
+ def detect_encoding(line)
+ return unless line[0] == ?#
+ line = line[1..-1]
+ line = $1 if line[/-\*-\s*(.*?)\s*-*-$/]
+ return nil unless ENCODING_SPEC_RE =~ line
+ encoding = $1
+ return encoding.sub(/-(?:mac|dos|unix)/i, '')
+ end
+ end
+end
diff --git a/lib/irb/nesting_parser.rb b/lib/irb/nesting_parser.rb
deleted file mode 100644
index 5aa940cc28..0000000000
--- a/lib/irb/nesting_parser.rb
+++ /dev/null
@@ -1,237 +0,0 @@
-# frozen_string_literal: true
-module IRB
- module NestingParser
- IGNORE_TOKENS = %i[on_sp on_ignored_nl on_comment on_embdoc_beg on_embdoc on_embdoc_end]
-
- # Scan each token and call the given block with array of token and other information for parsing
- def self.scan_opens(tokens)
- opens = []
- pending_heredocs = []
- first_token_on_line = true
- tokens.each do |t|
- skip = false
- last_tok, state, args = opens.last
- case state
- when :in_alias_undef
- skip = t.event == :on_kw
- when :in_unquoted_symbol
- unless IGNORE_TOKENS.include?(t.event)
- opens.pop
- skip = true
- end
- when :in_lambda_head
- opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do')
- when :in_method_head
- unless IGNORE_TOKENS.include?(t.event)
- next_args = []
- body = nil
- if args.include?(:receiver)
- case t.event
- when :on_lparen, :on_ivar, :on_gvar, :on_cvar
- # def (receiver). | def @ivar. | def $gvar. | def @@cvar.
- next_args << :dot
- when :on_kw
- case t.tok
- when 'self', 'true', 'false', 'nil'
- # def self(arg) | def self.
- next_args.push(:arg, :dot)
- else
- # def if(arg)
- skip = true
- next_args << :arg
- end
- when :on_op, :on_backtick
- # def +(arg)
- skip = true
- next_args << :arg
- when :on_ident, :on_const
- # def a(arg) | def a.
- next_args.push(:arg, :dot)
- end
- end
- if args.include?(:dot)
- # def receiver.name
- next_args << :name if t.event == :on_period || (t.event == :on_op && t.tok == '::')
- end
- if args.include?(:name)
- if %i[on_ident on_const on_op on_kw on_backtick].include?(t.event)
- # def name(arg) | def receiver.name(arg)
- next_args << :arg
- skip = true
- end
- end
- if args.include?(:arg)
- case t.event
- when :on_nl, :on_semicolon
- # def receiver.f;
- body = :normal
- when :on_lparen
- # def receiver.f()
- next_args << :eq
- else
- if t.event == :on_op && t.tok == '='
- # def receiver.f =
- body = :oneliner
- else
- # def receiver.f arg
- next_args << :arg_without_paren
- end
- end
- end
- if args.include?(:eq)
- if t.event == :on_op && t.tok == '='
- body = :oneliner
- else
- body = :normal
- end
- end
- if args.include?(:arg_without_paren)
- if %i[on_semicolon on_nl].include?(t.event)
- # def f a;
- body = :normal
- else
- # def f a, b
- next_args << :arg_without_paren
- end
- end
- if body == :oneliner
- opens.pop
- elsif body
- opens[-1] = [last_tok, nil]
- else
- opens[-1] = [last_tok, :in_method_head, next_args]
- end
- end
- when :in_for_while_until_condition
- if t.event == :on_semicolon || t.event == :on_nl || (t.event == :on_kw && t.tok == 'do')
- skip = true if t.event == :on_kw && t.tok == 'do'
- opens[-1] = [last_tok, nil]
- end
- end
-
- unless skip
- case t.event
- when :on_kw
- case t.tok
- when 'begin', 'class', 'module', 'do', 'case'
- opens << [t, nil]
- when 'end'
- opens.pop
- when 'def'
- opens << [t, :in_method_head, [:receiver, :name]]
- when 'if', 'unless'
- unless t.state.allbits?(Ripper::EXPR_LABEL)
- opens << [t, nil]
- end
- when 'while', 'until'
- unless t.state.allbits?(Ripper::EXPR_LABEL)
- opens << [t, :in_for_while_until_condition]
- end
- when 'ensure', 'rescue'
- unless t.state.allbits?(Ripper::EXPR_LABEL)
- opens.pop
- opens << [t, nil]
- end
- when 'alias'
- opens << [t, :in_alias_undef, 2]
- when 'undef'
- opens << [t, :in_alias_undef, 1]
- when 'elsif', 'else', 'when'
- opens.pop
- opens << [t, nil]
- when 'for'
- opens << [t, :in_for_while_until_condition]
- when 'in'
- if last_tok&.event == :on_kw && %w[case in].include?(last_tok.tok) && first_token_on_line
- opens.pop
- opens << [t, nil]
- end
- end
- when :on_tlambda
- opens << [t, :in_lambda_head]
- when :on_lparen, :on_lbracket, :on_lbrace, :on_tlambeg, :on_embexpr_beg, :on_embdoc_beg
- opens << [t, nil]
- when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end, :on_embdoc_end
- opens.pop
- when :on_heredoc_beg
- pending_heredocs << t
- when :on_heredoc_end
- opens.pop
- when :on_backtick
- opens << [t, nil] if t.state.allbits?(Ripper::EXPR_BEG)
- when :on_tstring_beg, :on_words_beg, :on_qwords_beg, :on_symbols_beg, :on_qsymbols_beg, :on_regexp_beg
- opens << [t, nil]
- when :on_tstring_end, :on_regexp_end, :on_label_end
- opens.pop
- when :on_symbeg
- if t.tok == ':'
- opens << [t, :in_unquoted_symbol]
- else
- opens << [t, nil]
- end
- end
- end
- if t.event == :on_nl || t.event == :on_semicolon
- first_token_on_line = true
- elsif t.event != :on_sp
- first_token_on_line = false
- end
- if pending_heredocs.any? && t.tok.include?("\n")
- pending_heredocs.reverse_each { |t| opens << [t, nil] }
- pending_heredocs = []
- end
- if opens.last && opens.last[1] == :in_alias_undef && !IGNORE_TOKENS.include?(t.event) && t.event != :on_heredoc_end
- tok, state, arg = opens.pop
- opens << [tok, state, arg - 1] if arg >= 1
- end
- yield t, opens if block_given?
- end
- opens.map(&:first) + pending_heredocs.reverse
- end
-
- def self.open_tokens(tokens)
- # scan_opens without block will return a list of open tokens at last token position
- scan_opens(tokens)
- end
-
- # Calculates token information [line_tokens, prev_opens, next_opens, min_depth] for each line.
- # Example code
- # ["hello
- # world"+(
- # First line
- # line_tokens: [[lbracket, '['], [tstring_beg, '"'], [tstring_content("hello\nworld"), "hello\n"]]
- # prev_opens: []
- # next_tokens: [lbracket, tstring_beg]
- # min_depth: 0 (minimum at beginning of line)
- # Second line
- # line_tokens: [[tstring_content("hello\nworld"), "world"], [tstring_end, '"'], [op, '+'], [lparen, '(']]
- # prev_opens: [lbracket, tstring_beg]
- # next_tokens: [lbracket, lparen]
- # min_depth: 1 (minimum just after tstring_end)
- def self.parse_by_line(tokens)
- line_tokens = []
- prev_opens = []
- min_depth = 0
- output = []
- last_opens = scan_opens(tokens) do |t, opens|
- depth = t == opens.last&.first ? opens.size - 1 : opens.size
- min_depth = depth if depth < min_depth
- if t.tok.include?("\n")
- t.tok.each_line do |line|
- line_tokens << [t, line]
- next if line[-1] != "\n"
- next_opens = opens.map(&:first)
- output << [line_tokens, prev_opens, next_opens, min_depth]
- prev_opens = next_opens
- min_depth = prev_opens.size
- line_tokens = []
- end
- else
- line_tokens << [t, t.tok]
- end
- end
- output << [line_tokens, prev_opens, last_opens, min_depth] if line_tokens.any?
- output
- end
- end
-end
diff --git a/lib/irb/notifier.rb b/lib/irb/notifier.rb
index dc1b9ef14b..d0e413dd68 100644
--- a/lib/irb/notifier.rb
+++ b/lib/irb/notifier.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# notifier.rb - output methods used by irb
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
require_relative "output-method"
diff --git a/lib/irb/output-method.rb b/lib/irb/output-method.rb
index 69942f47a2..3fda708cb0 100644
--- a/lib/irb/output-method.rb
+++ b/lib/irb/output-method.rb
@@ -1,18 +1,30 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# output-method.rb - output methods used by irb
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
module IRB
# An abstract output class for IO in irb. This is mainly used internally by
# IRB::Notifier. You can define your own output method to use with Irb.new,
# or Context.new
class OutputMethod
+ class NotImplementedError < StandardError
+ def initialize(val)
+ super("Need to define `#{val}'")
+ end
+ end
+
# Open this method to implement your own output method, raises a
# NotImplementedError if you don't define #print in your own class.
def print(*opts)
- raise NotImplementedError
+ raise NotImplementedError, "print"
end
# Prints the given +opts+, with a newline delimiter.
diff --git a/lib/irb/pager.rb b/lib/irb/pager.rb
deleted file mode 100644
index 3391b32c66..0000000000
--- a/lib/irb/pager.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- # The implementation of this class is borrowed from RDoc's lib/rdoc/ri/driver.rb.
- # Please do NOT use this class directly outside of IRB.
- class Pager
- PAGE_COMMANDS = [ENV['RI_PAGER'], ENV['PAGER'], 'less', 'more'].compact.uniq
-
- class << self
- def page_content(content, **options)
- if content_exceeds_screen_height?(content)
- page(**options) do |io|
- io.puts content
- end
- else
- $stdout.puts content
- end
- end
-
- def page(retain_content: false)
- if should_page? && pager = setup_pager(retain_content: retain_content)
- begin
- pid = pager.pid
- yield pager
- ensure
- pager.close
- end
- else
- yield $stdout
- end
- # When user presses Ctrl-C, IRB would raise `IRB::Abort`
- # But since Pager is implemented by running paging commands like `less` in another process with `IO.popen`,
- # the `IRB::Abort` exception only interrupts IRB's execution but doesn't affect the pager
- # So to properly terminate the pager with Ctrl-C, we need to catch `IRB::Abort` and kill the pager process
- rescue IRB::Abort
- Process.kill("TERM", pid) if pid
- nil
- rescue Errno::EPIPE
- end
-
- private
-
- def should_page?
- IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
- end
-
- def content_exceeds_screen_height?(content)
- screen_height, screen_width = begin
- Reline.get_screen_size
- rescue Errno::EINVAL
- [24, 80]
- end
-
- pageable_height = screen_height - 3 # leave some space for previous and the current prompt
-
- # If the content has more lines than the pageable height
- content.lines.count > pageable_height ||
- # Or if the content is a few long lines
- pageable_height * screen_width < Reline::Unicode.calculate_width(content, true)
- end
-
- def setup_pager(retain_content:)
- require 'shellwords'
-
- PAGE_COMMANDS.each do |pager_cmd|
- cmd = Shellwords.split(pager_cmd)
- next if cmd.empty?
-
- if cmd.first == 'less'
- cmd << '-R' unless cmd.include?('-R')
- cmd << '-X' if retain_content && !cmd.include?('-X')
- end
-
- begin
- io = IO.popen(cmd, 'w')
- rescue
- next
- end
-
- if $? && $?.pid == io.pid && $?.exited? # pager didn't work
- next
- end
-
- return io
- end
-
- nil
- end
- end
- end
-end
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb
index cfe36be83f..85b336fbe1 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -1,124 +1,165 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/ruby-lex.rb - ruby lexcal analyzer
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
require "ripper"
require "jruby" if RUBY_ENGINE == "jruby"
-require_relative "nesting_parser"
-
-module IRB
- # :stopdoc:
- class RubyLex
- ASSIGNMENT_NODE_TYPES = [
- # Local, instance, global, class, constant, instance, and index assignment:
- # "foo = bar",
- # "@foo = bar",
- # "$foo = bar",
- # "@@foo = bar",
- # "::Foo = bar",
- # "a::Foo = bar",
- # "Foo = bar"
- # "foo.bar = 1"
- # "foo[1] = bar"
- :assign,
-
- # Operation assignment:
- # "foo += bar"
- # "foo -= bar"
- # "foo ||= bar"
- # "foo &&= bar"
- :opassign,
-
- # Multiple assignment:
- # "foo, bar = 1, 2
- :massign,
- ]
-
- class TerminateLineInput < StandardError
- def initialize
- super("Terminate Line Input")
- end
- end
- def self.compile_with_errors_suppressed(code, line_no: 1)
- begin
- result = yield code, line_no
- rescue ArgumentError
- # Ruby can issue an error for the code if there is an
- # incomplete magic comment for encoding in it. Force an
- # expression with a new line before the code in this
- # case to prevent magic comment handling. To make sure
- # line numbers in the lexed code remain the same,
- # decrease the line number by one.
- code = ";\n#{code}"
- line_no -= 1
- result = yield code, line_no
- end
- result
+# :stopdoc:
+class RubyLex
+
+ class TerminateLineInput < StandardError
+ def initialize
+ super("Terminate Line Input")
end
+ end
+
+ def initialize
+ @exp_line_no = @line_no = 1
+ @indent = 0
+ @continue = false
+ @line = ""
+ @prompt = nil
+ end
- ERROR_TOKENS = [
- :on_parse_error,
- :compile_error,
- :on_assign_error,
- :on_alias_error,
- :on_class_name_error,
- :on_param_error
- ]
-
- def self.generate_local_variables_assign_code(local_variables)
- "#{local_variables.join('=')}=nil;" unless local_variables.empty?
+ def self.compile_with_errors_suppressed(code, line_no: 1)
+ begin
+ result = yield code, line_no
+ rescue ArgumentError
+ # Ruby can issue an error for the code if there is an
+ # incomplete magic comment for encoding in it. Force an
+ # expression with a new line before the code in this
+ # case to prevent magic comment handling. To make sure
+ # line numbers in the lexed code remain the same,
+ # decrease the line number by one.
+ code = ";\n#{code}"
+ line_no -= 1
+ result = yield code, line_no
end
+ result
+ end
- # Some part of the code is not included in Ripper's token.
- # Example: DATA part, token after heredoc_beg when heredoc has unclosed embexpr.
- # With interpolated tokens, tokens.map(&:tok).join will be equal to code.
- def self.interpolate_ripper_ignored_tokens(code, tokens)
- line_positions = [0]
- code.lines.each do |line|
- line_positions << line_positions.last + line.bytesize
- end
- prev_byte_pos = 0
- interpolated = []
- prev_line = 1
- tokens.each do |t|
- line, col = t.pos
- byte_pos = line_positions[line - 1] + col
- if prev_byte_pos < byte_pos
- tok = code.byteslice(prev_byte_pos...byte_pos)
- pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]]
- interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0)
- prev_line += tok.count("\n")
+ # io functions
+ def set_input(io, p = nil, context:, &block)
+ @io = io
+ if @io.respond_to?(:check_termination)
+ @io.check_termination do |code|
+ if Reline::IOGate.in_pasting?
+ lex = RubyLex.new
+ rest = lex.check_termination_in_prev_line(code, context: context)
+ if rest
+ Reline.delete_text
+ rest.bytes.reverse_each do |c|
+ Reline.ungetc(c)
+ end
+ true
+ else
+ false
+ end
+ else
+ # Accept any single-line input for symbol aliases or commands that transform args
+ command = code.split(/\s/, 2).first
+ if context.symbol_alias?(command) || context.transform_args?(command)
+ next true
+ end
+
+ code.gsub!(/\s*\z/, '').concat("\n")
+ ltype, indent, continue, code_block_open = check_state(code, context: context)
+ if ltype or indent > 0 or continue or code_block_open
+ false
+ else
+ true
+ end
end
- interpolated << t
- prev_byte_pos = byte_pos + t.tok.bytesize
- prev_line += t.tok.count("\n")
end
- if prev_byte_pos < code.bytesize
- tok = code.byteslice(prev_byte_pos..)
- pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]]
- interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0)
- end
- interpolated
end
+ if @io.respond_to?(:dynamic_prompt)
+ @io.dynamic_prompt do |lines|
+ lines << '' if lines.empty?
+ result = []
+ tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, context: context)
+ code = String.new
+ partial_tokens = []
+ unprocessed_tokens = []
+ line_num_offset = 0
+ tokens.each do |t|
+ partial_tokens << t
+ unprocessed_tokens << t
+ if t.tok.include?("\n")
+ t_str = t.tok
+ t_str.each_line("\n") do |s|
+ code << s << "\n"
+ ltype, indent, continue, code_block_open = check_state(code, partial_tokens, context: context)
+ result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
+ line_num_offset += 1
+ end
+ unprocessed_tokens = []
+ else
+ code << t.tok
+ end
+ end
- def self.ripper_lex_without_warning(code, local_variables: [])
- verbose, $VERBOSE = $VERBOSE, nil
- lvars_code = generate_local_variables_assign_code(local_variables)
- original_code = code
- if lvars_code
- code = "#{lvars_code}\n#{code}"
- line_no = 0
- else
- line_no = 1
+ unless unprocessed_tokens.empty?
+ ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens, context: context)
+ result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
+ end
+ result
end
+ end
- compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
- lexer = Ripper::Lexer.new(inner_code, '-', line_no)
- tokens = []
- lexer.scan.each do |t|
+ if p.respond_to?(:call)
+ @input = p
+ elsif block_given?
+ @input = block
+ else
+ @input = Proc.new{@io.gets}
+ end
+ end
+
+ def set_prompt(p = nil, &block)
+ p = block if block_given?
+ if p.respond_to?(:call)
+ @prompt = p
+ else
+ @prompt = Proc.new{print p}
+ end
+ end
+
+ ERROR_TOKENS = [
+ :on_parse_error,
+ :compile_error,
+ :on_assign_error,
+ :on_alias_error,
+ :on_class_name_error,
+ :on_param_error
+ ]
+
+ def self.generate_local_variables_assign_code(local_variables)
+ "#{local_variables.join('=')}=nil;" unless local_variables.empty?
+ end
+
+ def self.ripper_lex_without_warning(code, context: nil)
+ verbose, $VERBOSE = $VERBOSE, nil
+ lvars_code = generate_local_variables_assign_code(context&.local_variables || [])
+ if lvars_code
+ code = "#{lvars_code}\n#{code}"
+ line_no = 0
+ else
+ line_no = 1
+ end
+
+ compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
+ lexer = Ripper::Lexer.new(inner_code, '-', line_no)
+ if lexer.respond_to?(:scan) # Ruby 2.7+
+ lexer.scan.each_with_object([]) do |t, tokens|
next if t.pos.first == 0
prev_tk = tokens.last
position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize
@@ -128,347 +169,698 @@ module IRB
tokens << t
end
end
- interpolate_ripper_ignored_tokens(original_code, tokens)
+ else
+ lexer.parse.reject { |it| it.pos.first == 0 }.sort_by(&:pos)
end
- ensure
- $VERBOSE = verbose
end
+ ensure
+ $VERBOSE = verbose
+ end
- def check_code_state(code, local_variables:)
- tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables)
- opens = NestingParser.open_tokens(tokens)
- [tokens, opens, code_terminated?(code, tokens, opens, local_variables: local_variables)]
+ def find_prev_spaces(line_index)
+ return 0 if @tokens.size == 0
+ md = @tokens[0].tok.match(/(\A +)/)
+ prev_spaces = md.nil? ? 0 : md[1].count(' ')
+ line_count = 0
+ @tokens.each_with_index do |t, i|
+ if t.tok.include?("\n")
+ line_count += t.tok.count("\n")
+ if line_count >= line_index
+ return prev_spaces
+ end
+ if (@tokens.size - 1) > i
+ md = @tokens[i + 1].tok.match(/(\A +)/)
+ prev_spaces = md.nil? ? 0 : md[1].count(' ')
+ end
+ end
end
+ prev_spaces
+ end
- def code_terminated?(code, tokens, opens, local_variables:)
- case check_code_syntax(code, local_variables: local_variables)
- when :unrecoverable_error
- true
- when :recoverable_error
- false
- when :other_error
- opens.empty? && !should_continue?(tokens)
- when :valid
- !should_continue?(tokens)
+ def set_auto_indent(context)
+ if @io.respond_to?(:auto_indent) and context.auto_indent_mode
+ @io.auto_indent do |lines, line_index, byte_pointer, is_newline|
+ if is_newline
+ @tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: context)
+ prev_spaces = find_prev_spaces(line_index)
+ depth_difference = check_newline_depth_difference
+ depth_difference = 0 if depth_difference < 0
+ prev_spaces + depth_difference * 2
+ else
+ code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
+ last_line = lines[line_index]&.byteslice(0, byte_pointer)
+ code += last_line if last_line
+ @tokens = self.class.ripper_lex_without_warning(code, context: context)
+ check_corresponding_token_depth(lines, line_index)
+ end
end
end
+ end
- def assignment_expression?(code, local_variables:)
- # Try to parse the code and check if the last of possibly multiple
- # expressions is an assignment type.
+ def check_state(code, tokens = nil, context: nil)
+ tokens = self.class.ripper_lex_without_warning(code, context: context) unless tokens
+ ltype = process_literal_type(tokens)
+ indent = process_nesting_level(tokens)
+ continue = process_continue(tokens)
+ lvars_code = self.class.generate_local_variables_assign_code(context.local_variables)
+ code = "#{lvars_code}\n#{code}" if lvars_code
+ code_block_open = check_code_block(code, tokens)
+ [ltype, indent, continue, code_block_open]
+ end
- # If the expression is invalid, Ripper.sexp should return nil which will
- # result in false being returned. Any valid expression should return an
- # s-expression where the second element of the top level array is an
- # array of parsed expressions. The first element of each expression is the
- # expression's type.
- verbose, $VERBOSE = $VERBOSE, nil
- code = "#{RubyLex.generate_local_variables_assign_code(local_variables) || 'nil;'}\n#{code}"
- # Get the last node_type of the line. drop(1) is to ignore the local_variables_assign_code part.
- node_type = Ripper.sexp(code)&.dig(1)&.drop(1)&.dig(-1, 0)
- ASSIGNMENT_NODE_TYPES.include?(node_type)
- ensure
- $VERBOSE = verbose
+ def prompt
+ if @prompt
+ @prompt.call(@ltype, @indent, @continue, @line_no)
end
+ end
- def should_continue?(tokens)
- # Look at the last token and check if IRB need to continue reading next line.
- # Example code that should continue: `a\` `a +` `a.`
- # Trailing spaces, newline, comments are skipped
- return true if tokens.last&.event == :on_sp && tokens.last.tok == "\\\n"
-
- tokens.reverse_each do |token|
- case token.event
- when :on_sp, :on_nl, :on_ignored_nl, :on_comment, :on_embdoc_beg, :on_embdoc, :on_embdoc_end
- # Skip
- when :on_regexp_end, :on_heredoc_end, :on_semicolon
- # State is EXPR_BEG but should not continue
- return false
- else
- # Endless range should not continue
- return false if token.event == :on_op && token.tok.match?(/\A\.\.\.?\z/)
+ def initialize_input
+ @ltype = nil
+ @indent = 0
+ @continue = false
+ @line = ""
+ @exp_line_no = @line_no
+ @code_block_open = false
+ end
- # EXPR_DOT and most of the EXPR_BEG should continue
- return token.state.anybits?(Ripper::EXPR_BEG | Ripper::EXPR_DOT)
+ def each_top_level_statement(context)
+ initialize_input
+ catch(:TERM_INPUT) do
+ loop do
+ begin
+ prompt
+ unless l = lex(context)
+ throw :TERM_INPUT if @line == ''
+ else
+ @line_no += l.count("\n")
+ if l == "\n"
+ @exp_line_no += 1
+ next
+ end
+ @line.concat l
+ if @code_block_open or @ltype or @continue or @indent > 0
+ next
+ end
+ end
+ if @line != "\n"
+ @line.force_encoding(@io.encoding)
+ yield @line, @exp_line_no
+ end
+ raise TerminateLineInput if @io.eof?
+ @line = ''
+ @exp_line_no = @line_no
+
+ @indent = 0
+ rescue TerminateLineInput
+ initialize_input
+ prompt
end
end
- false
end
+ end
- def check_code_syntax(code, local_variables:)
- lvars_code = RubyLex.generate_local_variables_assign_code(local_variables)
- code = "#{lvars_code}\n#{code}"
+ def lex(context)
+ line = @input.call
+ if @io.respond_to?(:check_termination)
+ return line # multiline
+ end
+ code = @line + (line.nil? ? '' : line)
+ code.gsub!(/\s*\z/, '').concat("\n")
+ @tokens = self.class.ripper_lex_without_warning(code, context: context)
+ @ltype, @indent, @continue, @code_block_open = check_state(code, @tokens, context: context)
+ line
+ end
- begin # check if parser error are available
- verbose, $VERBOSE = $VERBOSE, nil
- case RUBY_ENGINE
- when 'ruby'
- self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
- RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no)
- end
- when 'jruby'
- JRuby.compile_ir(code)
- else
- catch(:valid) do
- eval("BEGIN { throw :valid, true }\n#{code}")
- false
- end
+ def process_continue(tokens = @tokens)
+ # last token is always newline
+ if tokens.size >= 2 and tokens[-2].event == :on_regexp_end
+ # end of regexp literal
+ return false
+ elsif tokens.size >= 2 and tokens[-2].event == :on_semicolon
+ return false
+ elsif tokens.size >= 2 and tokens[-2].event == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2].tok)
+ return false
+ elsif !tokens.empty? and tokens.last.tok == "\\\n"
+ return true
+ elsif tokens.size >= 1 and tokens[-1].event == :on_heredoc_end # "EOH\n"
+ return false
+ elsif tokens.size >= 2 and tokens[-2].state.anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2].tok !~ /\A\.\.\.?\z/
+ # end of literal except for regexp
+ # endless range at end of line is not a continue
+ return true
+ end
+ false
+ end
+
+ def check_code_block(code, tokens = @tokens)
+ return true if tokens.empty?
+ if tokens.last.event == :on_heredoc_beg
+ return true
+ end
+
+ begin # check if parser error are available
+ verbose, $VERBOSE = $VERBOSE, nil
+ case RUBY_ENGINE
+ when 'ruby'
+ self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
+ RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no)
end
- rescue EncodingError
- # This is for a hash with invalid encoding symbol, {"\xAE": 1}
- :unrecoverable_error
- rescue SyntaxError => e
- case e.message
- when /unterminated (?:string|regexp) meets end of file/
- # "unterminated regexp meets end of file"
- #
- # example:
- # /
- #
- # "unterminated string meets end of file"
- #
- # example:
- # '
- return :recoverable_error
- when /syntax error, unexpected end-of-input/
- # "syntax error, unexpected end-of-input, expecting keyword_end"
- #
- # example:
- # if true
- # hoge
- # if false
- # fuga
- # end
- return :recoverable_error
- when /syntax error, unexpected keyword_end/
- # "syntax error, unexpected keyword_end"
- #
- # example:
- # if (
- # end
- #
- # example:
- # end
- return :unrecoverable_error
- when /syntax error, unexpected '\.'/
- # "syntax error, unexpected '.'"
- #
- # example:
- # .
- return :unrecoverable_error
- when /unexpected tREGEXP_BEG/
- # "syntax error, unexpected tREGEXP_BEG, expecting keyword_do or '{' or '('"
- #
- # example:
- # method / f /
- return :unrecoverable_error
- else
- return :other_error
+ when 'jruby'
+ JRuby.compile_ir(code)
+ else
+ catch(:valid) do
+ eval("BEGIN { throw :valid, true }\n#{code}")
+ false
end
- ensure
- $VERBOSE = verbose
end
- :valid
+ rescue EncodingError
+ # This is for a hash with invalid encoding symbol, {"\xAE": 1}
+ rescue SyntaxError => e
+ case e.message
+ when /unterminated (?:string|regexp) meets end of file/
+ # "unterminated regexp meets end of file"
+ #
+ # example:
+ # /
+ #
+ # "unterminated string meets end of file"
+ #
+ # example:
+ # '
+ return true
+ when /syntax error, unexpected end-of-input/
+ # "syntax error, unexpected end-of-input, expecting keyword_end"
+ #
+ # example:
+ # if true
+ # hoge
+ # if false
+ # fuga
+ # end
+ return true
+ when /syntax error, unexpected keyword_end/
+ # "syntax error, unexpected keyword_end"
+ #
+ # example:
+ # if (
+ # end
+ #
+ # example:
+ # end
+ return false
+ when /syntax error, unexpected '\.'/
+ # "syntax error, unexpected '.'"
+ #
+ # example:
+ # .
+ return false
+ when /unexpected tREGEXP_BEG/
+ # "syntax error, unexpected tREGEXP_BEG, expecting keyword_do or '{' or '('"
+ #
+ # example:
+ # method / f /
+ return false
+ end
+ ensure
+ $VERBOSE = verbose
end
- def calc_indent_level(opens)
- indent_level = 0
- opens.each_with_index do |t, index|
- case t.event
- when :on_heredoc_beg
- if opens[index + 1]&.event != :on_heredoc_beg
- if t.tok.match?(/^<<[~-]/)
- indent_level += 1
- else
- indent_level = 0
- end
+ last_lex_state = tokens.last.state
+
+ if last_lex_state.allbits?(Ripper::EXPR_BEG)
+ return false
+ elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_CLASS)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_FNAME)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_VALUE)
+ return true
+ elsif last_lex_state.allbits?(Ripper::EXPR_ARG)
+ return false
+ end
+
+ false
+ end
+
+ def process_nesting_level(tokens = @tokens)
+ indent = 0
+ in_oneliner_def = nil
+ tokens.each_with_index { |t, index|
+ # detecting one-liner method definition
+ if in_oneliner_def.nil?
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
+ in_oneliner_def = :ENDFN
+ end
+ else
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
+ # continuing
+ elsif t.state.allbits?(Ripper::EXPR_BEG)
+ if t.tok == '='
+ in_oneliner_def = :BODY
end
- when :on_tstring_beg, :on_regexp_beg, :on_symbeg, :on_backtick
- # No indent: "", //, :"", ``
- # Indent: %(), %r(), %i(), %x()
- indent_level += 1 if t.tok.start_with? '%'
- when :on_embdoc_beg
- indent_level = 0
else
- indent_level += 1 unless t.tok == 'alias' || t.tok == 'undef'
+ if in_oneliner_def == :BODY
+ # one-liner method definition
+ indent -= 1
+ end
+ in_oneliner_def = nil
end
end
- indent_level
- end
- FREE_INDENT_TOKENS = %i[on_tstring_beg on_backtick on_regexp_beg on_symbeg]
+ case t.event
+ when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
+ indent += 1
+ when :on_rbracket, :on_rbrace, :on_rparen
+ indent -= 1
+ when :on_kw
+ next if index > 0 and tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
+ case t.tok
+ when 'do'
+ syntax_of_do = take_corresponding_syntax_to_kw_do(tokens, index)
+ indent += 1 if syntax_of_do == :method_calling
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
+ indent += 1
+ when 'if', 'unless', 'while', 'until'
+ # postfix if/unless/while/until must be Ripper::EXPR_LABEL
+ indent += 1 unless t.state.allbits?(Ripper::EXPR_LABEL)
+ when 'end'
+ indent -= 1
+ end
+ end
+ # percent literals are not indented
+ }
+ indent
+ end
- def free_indent_token?(token)
- FREE_INDENT_TOKENS.include?(token&.event)
+ def is_method_calling?(tokens, index)
+ tk = tokens[index]
+ if tk.state.anybits?(Ripper::EXPR_CMDARG) and tk.event == :on_ident
+ # The target method call to pass the block with "do".
+ return true
+ elsif tk.state.anybits?(Ripper::EXPR_ARG) and tk.event == :on_ident
+ non_sp_index = tokens[0..(index - 1)].rindex{ |t| t.event != :on_sp }
+ if non_sp_index
+ prev_tk = tokens[non_sp_index]
+ if prev_tk.state.anybits?(Ripper::EXPR_DOT) and prev_tk.event == :on_period
+ # The target method call with receiver to pass the block with "do".
+ return true
+ end
+ end
end
+ false
+ end
- # Calculates the difference of pasted code's indent and indent calculated from tokens
- def indent_difference(lines, line_results, line_index)
- loop do
- _tokens, prev_opens, _next_opens, min_depth = line_results[line_index]
- open_token = prev_opens.last
- if !open_token || (open_token.event != :on_heredoc_beg && !free_indent_token?(open_token))
- # If the leading whitespace is an indent, return the difference
- indent_level = calc_indent_level(prev_opens.take(min_depth))
- calculated_indent = 2 * indent_level
- actual_indent = lines[line_index][/^ */].size
- return actual_indent - calculated_indent
- elsif open_token.event == :on_heredoc_beg && open_token.tok.match?(/^<<[^-~]/)
- return 0
- end
- # If the leading whitespace is not an indent but part of a multiline token
- # Calculate base_indent of the multiline token's beginning line
- line_index = open_token.pos[0] - 1
+ def take_corresponding_syntax_to_kw_do(tokens, index)
+ syntax_of_do = nil
+ # Finding a syntax corresponding to "do".
+ index.downto(0) do |i|
+ tk = tokens[i]
+ # In "continue", the token isn't the corresponding syntax to "do".
+ non_sp_index = tokens[0..(i - 1)].rindex{ |t| t.event != :on_sp }
+ first_in_fomula = false
+ if non_sp_index.nil?
+ first_in_fomula = true
+ elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index].event)
+ first_in_fomula = true
+ end
+ if is_method_calling?(tokens, i)
+ syntax_of_do = :method_calling
+ break if first_in_fomula
+ elsif tk.event == :on_kw && %w{while until for}.include?(tk.tok)
+ # A loop syntax in front of "do" found.
+ #
+ # while cond do # also "until" or "for"
+ # end
+ #
+ # This "do" doesn't increment indent because the loop syntax already
+ # incremented.
+ syntax_of_do = :loop_syntax
+ break if first_in_fomula
end
end
+ syntax_of_do
+ end
+
+ def is_the_in_correspond_to_a_for(tokens, index)
+ syntax_of_in = nil
+ # Finding a syntax corresponding to "do".
+ index.downto(0) do |i|
+ tk = tokens[i]
+ # In "continue", the token isn't the corresponding syntax to "do".
+ non_sp_index = tokens[0..(i - 1)].rindex{ |t| t.event != :on_sp }
+ first_in_fomula = false
+ if non_sp_index.nil?
+ first_in_fomula = true
+ elsif [:on_ignored_nl, :on_nl, :on_comment].include?(tokens[non_sp_index].event)
+ first_in_fomula = true
+ end
+ if tk.event == :on_kw && tk.tok == 'for'
+ # A loop syntax in front of "do" found.
+ #
+ # while cond do # also "until" or "for"
+ # end
+ #
+ # This "do" doesn't increment indent because the loop syntax already
+ # incremented.
+ syntax_of_in = :for
+ end
+ break if first_in_fomula
+ end
+ syntax_of_in
+ end
- def process_indent_level(tokens, lines, line_index, is_newline)
- line_results = NestingParser.parse_by_line(tokens)
- result = line_results[line_index]
- if result
- _tokens, prev_opens, next_opens, min_depth = result
+ def check_newline_depth_difference
+ depth_difference = 0
+ open_brace_on_line = 0
+ in_oneliner_def = nil
+ @tokens.each_with_index do |t, index|
+ # detecting one-liner method definition
+ if in_oneliner_def.nil?
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
+ in_oneliner_def = :ENDFN
+ end
else
- # When last line is empty
- prev_opens = next_opens = line_results.last[2]
- min_depth = next_opens.size
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
+ # continuing
+ elsif t.state.allbits?(Ripper::EXPR_BEG)
+ if t.tok == '='
+ in_oneliner_def = :BODY
+ end
+ else
+ if in_oneliner_def == :BODY
+ # one-liner method definition
+ depth_difference -= 1
+ end
+ in_oneliner_def = nil
+ end
end
- # To correctly indent line like `end.map do`, we use shortest open tokens on each line for indent calculation.
- # Shortest open tokens can be calculated by `opens.take(min_depth)`
- indent = 2 * calc_indent_level(prev_opens.take(min_depth))
+ case t.event
+ when :on_ignored_nl, :on_nl, :on_comment
+ if index != (@tokens.size - 1) and in_oneliner_def != :BODY
+ depth_difference = 0
+ open_brace_on_line = 0
+ end
+ next
+ when :on_sp
+ next
+ end
- preserve_indent = lines[line_index - (is_newline ? 1 : 0)][/^ */].size
+ case t.event
+ when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
+ depth_difference += 1
+ open_brace_on_line += 1
+ when :on_rbracket, :on_rbrace, :on_rparen
+ depth_difference -= 1 if open_brace_on_line > 0
+ when :on_kw
+ next if index > 0 and @tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
+ case t.tok
+ when 'do'
+ syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
+ depth_difference += 1 if syntax_of_do == :method_calling
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
+ depth_difference += 1
+ when 'if', 'unless', 'while', 'until', 'rescue'
+ # postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
+ depth_difference += 1
+ end
+ when 'else', 'elsif', 'ensure', 'when'
+ depth_difference += 1
+ when 'in'
+ unless is_the_in_correspond_to_a_for(@tokens, index)
+ depth_difference += 1
+ end
+ when 'end'
+ depth_difference -= 1
+ end
+ end
+ end
+ depth_difference
+ end
- prev_open_token = prev_opens.last
- next_open_token = next_opens.last
+ def check_corresponding_token_depth(lines, line_index)
+ corresponding_token_depth = nil
+ is_first_spaces_of_line = true
+ is_first_printable_of_line = true
+ spaces_of_nest = []
+ spaces_at_line_head = 0
+ open_brace_on_line = 0
+ in_oneliner_def = nil
+
+ if heredoc_scope?
+ return lines[line_index][/^ */].length
+ end
- # Calculates base indent for pasted code on the line where prev_open_token is located
- # irb(main):001:1* if a # base_indent is 2, indent calculated from tokens is 0
- # irb(main):002:1* if b # base_indent is 6, indent calculated from tokens is 2
- # irb(main):003:0> c # base_indent is 6, indent calculated from tokens is 4
- if prev_open_token
- base_indent = [0, indent_difference(lines, line_results, prev_open_token.pos[0] - 1)].max
+ @tokens.each_with_index do |t, index|
+ # detecting one-liner method definition
+ if in_oneliner_def.nil?
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
+ in_oneliner_def = :ENDFN
+ end
else
- base_indent = 0
+ if t.state.allbits?(Ripper::EXPR_ENDFN)
+ # continuing
+ elsif t.state.allbits?(Ripper::EXPR_BEG)
+ if t.tok == '='
+ in_oneliner_def = :BODY
+ end
+ else
+ if in_oneliner_def == :BODY
+ # one-liner method definition
+ if is_first_printable_of_line
+ corresponding_token_depth = spaces_of_nest.pop
+ else
+ spaces_of_nest.pop
+ corresponding_token_depth = nil
+ end
+ end
+ in_oneliner_def = nil
+ end
end
- if free_indent_token?(prev_open_token)
- if is_newline && prev_open_token.pos[0] == line_index
- # First newline inside free-indent token
- base_indent + indent
- else
- # Accept any number of indent inside free-indent token
- preserve_indent
+ case t.event
+ when :on_ignored_nl, :on_nl, :on_comment
+ if in_oneliner_def != :BODY
+ corresponding_token_depth = nil
+ spaces_at_line_head = 0
+ is_first_spaces_of_line = true
+ is_first_printable_of_line = true
+ open_brace_on_line = 0
end
- elsif prev_open_token&.event == :on_embdoc_beg || next_open_token&.event == :on_embdoc_beg
- if prev_open_token&.event == next_open_token&.event
- # Accept any number of indent inside embdoc content
- preserve_indent
+ next
+ when :on_sp
+ spaces_at_line_head = t.tok.count(' ') if is_first_spaces_of_line
+ is_first_spaces_of_line = false
+ next
+ end
+
+ case t.event
+ when :on_lbracket, :on_lbrace, :on_lparen, :on_tlambeg
+ spaces_of_nest.push(spaces_at_line_head + open_brace_on_line * 2)
+ open_brace_on_line += 1
+ when :on_rbracket, :on_rbrace, :on_rparen
+ if is_first_printable_of_line
+ corresponding_token_depth = spaces_of_nest.pop
else
- # =begin or =end
- 0
+ spaces_of_nest.pop
+ corresponding_token_depth = nil
end
- elsif prev_open_token&.event == :on_heredoc_beg
- tok = prev_open_token.tok
- if prev_opens.size <= next_opens.size
- if is_newline && lines[line_index].empty? && line_results[line_index - 1][1].last != next_open_token
- # First line in heredoc
- tok.match?(/^<<[-~]/) ? base_indent + indent : indent
- elsif tok.match?(/^<<~/)
- # Accept extra indent spaces inside `<<~` heredoc
- [base_indent + indent, preserve_indent].max
+ open_brace_on_line -= 1
+ when :on_kw
+ next if index > 0 and @tokens[index - 1].state.allbits?(Ripper::EXPR_FNAME)
+ case t.tok
+ when 'do'
+ syntax_of_do = take_corresponding_syntax_to_kw_do(@tokens, index)
+ if syntax_of_do == :method_calling
+ spaces_of_nest.push(spaces_at_line_head)
+ end
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
+ spaces_of_nest.push(spaces_at_line_head)
+ when 'rescue'
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
+ corresponding_token_depth = spaces_of_nest.last
+ end
+ when 'if', 'unless', 'while', 'until'
+ # postfix if/unless/while/until must be Ripper::EXPR_LABEL
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
+ spaces_of_nest.push(spaces_at_line_head)
+ end
+ when 'else', 'elsif', 'ensure', 'when'
+ corresponding_token_depth = spaces_of_nest.last
+ when 'in'
+ if in_keyword_case_scope?
+ corresponding_token_depth = spaces_of_nest.last
+ end
+ when 'end'
+ if is_first_printable_of_line
+ corresponding_token_depth = spaces_of_nest.pop
else
- # Accept any number of indent inside other heredoc
- preserve_indent
+ spaces_of_nest.pop
+ corresponding_token_depth = nil
end
- else
- # Heredoc close
- prev_line_indent_level = calc_indent_level(prev_opens)
- tok.match?(/^<<[~-]/) ? base_indent + 2 * (prev_line_indent_level - 1) : 0
end
- else
- base_indent + indent
end
+ is_first_spaces_of_line = false
+ is_first_printable_of_line = false
end
+ corresponding_token_depth
+ end
- LTYPE_TOKENS = %i[
- on_heredoc_beg on_tstring_beg
- on_regexp_beg on_symbeg on_backtick
- on_symbols_beg on_qsymbols_beg
- on_words_beg on_qwords_beg
- ]
+ def check_string_literal(tokens)
+ i = 0
+ start_token = []
+ end_type = []
+ pending_heredocs = []
+ while i < tokens.size
+ t = tokens[i]
+ case t.event
+ when *end_type.last
+ start_token.pop
+ end_type.pop
+ when :on_tstring_beg
+ start_token << t
+ end_type << [:on_tstring_end, :on_label_end]
+ when :on_regexp_beg
+ start_token << t
+ end_type << :on_regexp_end
+ when :on_symbeg
+ acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int on_backtick}
+ if (i + 1) < tokens.size
+ if acceptable_single_tokens.all?{ |st| tokens[i + 1].event != st }
+ start_token << t
+ end_type << :on_tstring_end
+ else
+ i += 1
+ end
+ end
+ when :on_backtick
+ if t.state.allbits?(Ripper::EXPR_BEG)
+ start_token << t
+ end_type << :on_tstring_end
+ end
+ when :on_qwords_beg, :on_words_beg, :on_qsymbols_beg, :on_symbols_beg
+ start_token << t
+ end_type << :on_tstring_end
+ when :on_heredoc_beg
+ pending_heredocs << t
+ end
- def ltype_from_open_tokens(opens)
- start_token = opens.reverse_each.find do |tok|
- LTYPE_TOKENS.include?(tok.event)
+ if pending_heredocs.any? && t.tok.include?("\n")
+ pending_heredocs.reverse_each do |t|
+ start_token << t
+ end_type << :on_heredoc_end
+ end
+ pending_heredocs = []
end
- return nil unless start_token
+ i += 1
+ end
+ pending_heredocs.first || start_token.last
+ end
- case start_token&.event
- when :on_tstring_beg
- case start_token&.tok
- when ?" then ?"
- when /^%.$/ then ?"
- when /^%Q.$/ then ?"
- when ?' then ?'
- when /^%q.$/ then ?'
+ def process_literal_type(tokens = @tokens)
+ start_token = check_string_literal(tokens)
+ return nil if start_token == ""
+
+ case start_token&.event
+ when :on_tstring_beg
+ case start_token&.tok
+ when ?" then ?"
+ when /^%.$/ then ?"
+ when /^%Q.$/ then ?"
+ when ?' then ?'
+ when /^%q.$/ then ?'
+ end
+ when :on_regexp_beg then ?/
+ when :on_symbeg then ?:
+ when :on_backtick then ?`
+ when :on_qwords_beg then ?]
+ when :on_words_beg then ?]
+ when :on_qsymbols_beg then ?]
+ when :on_symbols_beg then ?]
+ when :on_heredoc_beg
+ start_token&.tok =~ /<<[-~]?(['"`])[_a-zA-Z0-9]+\1/
+ case $1
+ when ?" then ?"
+ when ?' then ?'
+ when ?` then ?`
+ else ?"
+ end
+ else
+ nil
+ end
+ end
+
+ def check_termination_in_prev_line(code, context: nil)
+ tokens = self.class.ripper_lex_without_warning(code, context: context)
+ past_first_newline = false
+ index = tokens.rindex do |t|
+ # traverse first token before last line
+ if past_first_newline
+ if t.tok.include?("\n")
+ true
end
- when :on_regexp_beg then ?/
- when :on_symbeg then ?:
- when :on_backtick then ?`
- when :on_qwords_beg then ?]
- when :on_words_beg then ?]
- when :on_qsymbols_beg then ?]
- when :on_symbols_beg then ?]
- when :on_heredoc_beg
- start_token&.tok =~ /<<[-~]?(['"`])\w+\1/
- $1 || ?"
+ elsif t.tok.include?("\n")
+ past_first_newline = true
+ false
else
- nil
+ false
end
end
- def check_termination_in_prev_line(code, local_variables:)
- tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables)
- past_first_newline = false
- index = tokens.rindex do |t|
- # traverse first token before last line
- if past_first_newline
- if t.tok.include?("\n")
- true
- end
- elsif t.tok.include?("\n")
- past_first_newline = true
- false
- else
- false
+ if index
+ first_token = nil
+ last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
+ last_line_tokens.each do |t|
+ unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
+ first_token = t
+ break
end
end
- if index
- first_token = nil
- last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
- last_line_tokens.each do |t|
- unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
- first_token = t
- break
- end
+ if first_token.nil?
+ return false
+ elsif first_token && first_token.state == Ripper::EXPR_DOT
+ return false
+ else
+ tokens_without_last_line = tokens[0..index]
+ ltype = process_literal_type(tokens_without_last_line)
+ indent = process_nesting_level(tokens_without_last_line)
+ continue = process_continue(tokens_without_last_line)
+ code_block_open = check_code_block(tokens_without_last_line.map(&:tok).join(''), tokens_without_last_line)
+ if ltype or indent > 0 or continue or code_block_open
+ return false
+ else
+ return last_line_tokens.map(&:tok).join('')
end
+ end
+ end
+ false
+ end
- if first_token && first_token.state != Ripper::EXPR_DOT
- tokens_without_last_line = tokens[0..index]
- code_without_last_line = tokens_without_last_line.map(&:tok).join
- opens_without_last_line = NestingParser.open_tokens(tokens_without_last_line)
- if code_terminated?(code_without_last_line, tokens_without_last_line, opens_without_last_line, local_variables: local_variables)
- return last_line_tokens.map(&:tok).join
- end
- end
+ private
+
+ def heredoc_scope?
+ heredoc_tokens = @tokens.select { |t| [:on_heredoc_beg, :on_heredoc_end].include?(t.event) }
+ heredoc_tokens[-1]&.event == :on_heredoc_beg
+ end
+
+ def in_keyword_case_scope?
+ kw_tokens = @tokens.select { |t| t.event == :on_kw && ['case', 'for', 'end'].include?(t.tok) }
+ counter = 0
+ kw_tokens.reverse.each do |t|
+ if t.tok == 'case'
+ return true if counter.zero?
+ counter += 1
+ elsif t.tok == 'for'
+ counter += 1
+ elsif t.tok == 'end'
+ counter -= 1
end
- false
end
+ false
end
- # :startdoc:
end
-
-RubyLex = IRB::RubyLex
-Object.deprecate_constant(:RubyLex)
+# :startdoc:
diff --git a/lib/irb/ruby_logo.aa b/lib/irb/ruby_logo.aa
index 61fe22c94a..a34a3e2f28 100644
--- a/lib/irb/ruby_logo.aa
+++ b/lib/irb/ruby_logo.aa
@@ -1,4 +1,3 @@
-TYPE: LARGE
-+smJYYN?mm-
HB"BBYT TQg NggT
@@ -36,45 +35,3 @@ TYPE: LARGE
m7 NW H N HSVO1z=?11-
NgTH bB kH WBHWWHBHWmQgg&gggggNNN
NNggggggNN
-TYPE: ASCII
- ,,,;;;;''''';;;'';,
- ,,;'' ';;,;;; ',
- ,,'' ;;'';'''';;;;;;
- ,;' ;; ',, ;
- ,;' ,;' ';, ;
- ;' ,;; ',,,;
- ,' ,;;,,,,,,,,,,,;;;;
- ;' ;;';;;; ,;;
- ;' ,;' ;; '',, ,;;;
- ;; ,;' ; '';, ,; ;'
-;; ,;;' ;; ;; ;;
-;;, ,,;;' ; ;'; ;;
-;';;,,,,;;;;;;;,,, ;; ,' ; ;;
-; ;;''' ,;'; ''';,,, ; ,;' ;;;;
-;;;;, ; '; ''';;;' ';;;
-;'; ;, ;' '; ,;' ', ;;;
-;;; ; ,; '; ,,' ',, ;;
-;;; '; ;' ';,,'' ';,;;
- '; ';,; ,,;''''''''';;;;;;,,;;;
- ';,,;;,,;;;;;;;;;;''''''''''''''
-TYPE: UNICODE
- ⣀⣤⣴⣾⣿⣿⣿⡛⠛⠛⠛⠛⣻⣿⠿⠛⠛⠶⣤⡀
- â£€â£´â ¾â ›â ‰â  â ™â£¿â£¶â£¤â£¶â£Ÿâ£‰ ⠈⠻⣦
- ⣀⣴⠟⠋ ⢸⣿⠟⠻⣯⡙⠛⠛⠛⠶⠶⠶⢶⣽⣇
- â£ â¡¾â ‹â  â£¾â¡¿ ⠈⠛⢦⣄ ⣿
- ⣠⡾⠋ ⣰⣿⠃ ⠙⠷⣤⡀ ⣿
- ⢀⡾⠋ ⣰⣿⡠⠈⠻⣦⣄⢠⣿
- â£°â Ÿâ  â£´â£¿â£¿â£â£€â£ â£¤â£¤â£¤â£¤â£¤â£¤â£¤â£´â ¶â ¿â£¿â¡
- â£¼â  â¢€â£¾â£¿â Ÿâ£¿â ¿â£¯â£â  ⣰⣿⡇
- ⢀⣼⠋ â¢€â£´â£¿â Ÿâ  â¢¸â¡‡ ⠙⠻⢦⣄⡀ ⢠⡿⣿⡇
-â¢€â£¾â¡ â¢€â£´â£¿â Ÿâ  â£¿ ⠉⠻⢶⣄⡀⣰⡟ ⣿⠃
-â£¾â£¿â  â£ â£¶â¡¿â ‹â  â¢¹â¡‡ ⠈⣿⡠⢸⣿
-⣿⣿⡆ ⢀⣠⣴⣿⡿⠋ ⠈⣿ ⢀⡾⠋⣿ ⢸⣿
-⣿⠸⣿⣶⣤⣤⣤⣤⣶⣾⠿⠿⣿⣿⠶⣤⣤⣀⡀ ⢹⡇ â£´â Ÿâ  â£¿â¡€â¢¸â£¿
-â£¿â¢€â£¿â£Ÿâ ›â ‹â ‰â  â¢°â¡Ÿâ ¹â£§ ⠈⠉⠛⠻⠶⢦⣤⣀⡀ ⠈⣿ ⣠⡾⠃ ⢸⡇⢸⡇
-⣿⣾⣿⢿⡄ â£¿â  â ˜â£§ ⠉⠙⠛⠷⣿⣿⡋ ⠸⣇⣸⡇
-⣿⠃⣿⠈⢿⡄ ⣸⠇ ⠘⣧ ⢀⣤⠾⠋⠈⠻⣦⡀ ⣿⣿⡇
-⣿⢸⡠⠈⣷⡀ ⢠⡿ ⠘⣧⡀ â£ â¡´â Ÿâ  â ˆâ »â£¦â£€ ⢿⣿â 
-⢻⣾⡇ ⠘⣷ ⣼⠃ ⠘⣷⣠⣴⠟⠋ ⠙⢷⣄⢸⣿
- ⠻⣧⡀ ⠘⣧⣰⡠⢀⣠⣤⠶⠛⠉⠛⠛⠛⠛⠛⠛⠻⢶⣶⣶⣶⣶⣶⣤⣤⣽⣿⣿
- ⠈⠛⠷⢦⣤⣽⣿⣥⣤⣶⣶⡿⠿⠿⠶⠶⠶⠶⠾⠛⠛⠛⠛⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉â 
diff --git a/lib/irb/source_finder.rb b/lib/irb/source_finder.rb
deleted file mode 100644
index 5d7d729d19..0000000000
--- a/lib/irb/source_finder.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "ruby-lex"
-
-module IRB
- class SourceFinder
- class EvaluationError < StandardError; end
-
- class Source
- attr_reader :file, :line
- def initialize(file, line, ast_source = nil)
- @file = file
- @line = line
- @ast_source = ast_source
- end
-
- def file_exist?
- File.exist?(@file)
- end
-
- def binary_file?
- # If the line is zero, it means that the target's source is probably in a binary file.
- @line.zero?
- end
-
- def file_content
- @file_content ||= File.read(@file)
- end
-
- def colorized_content
- if !binary_file? && file_exist?
- end_line = find_end
- # To correctly colorize, we need to colorize full content and extract the relevant lines.
- colored = IRB::Color.colorize_code(file_content)
- colored.lines[@line - 1...end_line].join
- elsif @ast_source
- IRB::Color.colorize_code(@ast_source)
- end
- end
-
- private
-
- def find_end
- lex = RubyLex.new
- code = file_content
- lines = code.lines[(@line - 1)..-1]
- tokens = RubyLex.ripper_lex_without_warning(lines.join)
- prev_tokens = []
-
- # chunk with line number
- tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
- code = lines[0..lnum].join
- prev_tokens.concat chunk
- continue = lex.should_continue?(prev_tokens)
- syntax = lex.check_code_syntax(code, local_variables: [])
- if !continue && syntax == :valid
- return @line + lnum
- end
- end
- @line
- end
- end
-
- private_constant :Source
-
- def initialize(irb_context)
- @irb_context = irb_context
- end
-
- def find_source(signature, super_level = 0)
- case signature
- when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName
- eval_receiver_or_owner(signature) # trigger autoload
- *parts, name = signature.split('::', -1)
- base =
- if parts.empty? # ConstName
- find_const_owner(name)
- elsif parts == [''] # ::ConstName
- Object
- else # ConstPath::ConstName
- eval_receiver_or_owner(parts.join('::'))
- end
- file, line = base.const_source_location(name)
- when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
- owner = eval_receiver_or_owner(Regexp.last_match[:owner])
- method = Regexp.last_match[:method]
- return unless owner.respond_to?(:instance_method)
- method = method_target(owner, super_level, method, "owner")
- file, line = method&.source_location
- when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
- receiver = eval_receiver_or_owner(Regexp.last_match[:receiver] || 'self')
- method = Regexp.last_match[:method]
- return unless receiver.respond_to?(method, true)
- method = method_target(receiver, super_level, method, "receiver")
- file, line = method&.source_location
- end
- return unless file && line
-
- if File.exist?(file)
- Source.new(file, line)
- elsif method
- # Method defined with eval, probably in IRB session
- source = RubyVM::AbstractSyntaxTree.of(method)&.source rescue nil
- Source.new(file, line, source)
- end
- rescue EvaluationError
- nil
- end
-
- private
-
- def method_target(owner_receiver, super_level, method, type)
- case type
- when "owner"
- target_method = owner_receiver.instance_method(method)
- when "receiver"
- target_method = owner_receiver.method(method)
- end
- super_level.times do |s|
- target_method = target_method.super_method if target_method
- end
- target_method
- rescue NameError
- nil
- end
-
- def eval_receiver_or_owner(code)
- context_binding = @irb_context.workspace.binding
- eval(code, context_binding)
- rescue NameError
- raise EvaluationError
- end
-
- def find_const_owner(name)
- module_nesting = @irb_context.workspace.binding.eval('::Module.nesting')
- module_nesting.find { |mod| mod.const_defined?(name, false) } || module_nesting.find { |mod| mod.const_defined?(name) } || Object
- end
- end
-end
diff --git a/lib/irb/src_encoding.rb b/lib/irb/src_encoding.rb
new file mode 100644
index 0000000000..99aea2b43e
--- /dev/null
+++ b/lib/irb/src_encoding.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: false
+# DO NOT WRITE ANY MAGIC COMMENT HERE.
+module IRB
+ def self.default_src_encoding
+ return __ENCODING__
+ end
+end
diff --git a/lib/irb/statement.rb b/lib/irb/statement.rb
deleted file mode 100644
index a3391c12a3..0000000000
--- a/lib/irb/statement.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-
-module IRB
- class Statement
- attr_reader :code
-
- def is_assignment?
- raise NotImplementedError
- end
-
- def suppresses_echo?
- raise NotImplementedError
- end
-
- def should_be_handled_by_debugger?
- raise NotImplementedError
- end
-
- class EmptyInput < Statement
- def is_assignment?
- false
- end
-
- def suppresses_echo?
- true
- end
-
- # Debugger takes empty input to repeat the last command
- def should_be_handled_by_debugger?
- true
- end
-
- def code
- ""
- end
- end
-
- class Expression < Statement
- def initialize(code, is_assignment)
- @code = code
- @is_assignment = is_assignment
- end
-
- def suppresses_echo?
- @code.match?(/;\s*\z/)
- end
-
- def should_be_handled_by_debugger?
- true
- end
-
- def is_assignment?
- @is_assignment
- end
- end
-
- class Command < Statement
- attr_reader :command_class, :arg
-
- def initialize(original_code, command_class, arg)
- @code = original_code
- @command_class = command_class
- @arg = arg
- end
-
- def is_assignment?
- false
- end
-
- def suppresses_echo?
- false
- end
-
- def should_be_handled_by_debugger?
- require_relative 'command/debug'
- IRB::Command::DebugCommand > @command_class
- end
- end
- end
-end
diff --git a/lib/irb/version.rb b/lib/irb/version.rb
index c41917329c..d1c0e54fdc 100644
--- a/lib/irb/version.rb
+++ b/lib/irb/version.rb
@@ -1,11 +1,17 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/version.rb - irb version definition file
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
+# --
+#
+#
+#
module IRB # :nodoc:
- VERSION = "1.13.1"
+ VERSION = "1.6.2"
@RELEASE_VERSION = VERSION
- @LAST_UPDATE_DATE = "2024-05-05"
+ @LAST_UPDATE_DATE = "2022-12-13"
end
diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb
index d24d1cc38d..e5ef52528a 100644
--- a/lib/irb/workspace.rb
+++ b/lib/irb/workspace.rb
@@ -1,13 +1,17 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/workspace-binding.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
require "delegate"
-require_relative "helper_method"
-
IRB::TOPLEVEL_BINDING = binding
module IRB # :nodoc:
class WorkSpace
@@ -92,11 +96,11 @@ EOF
IRB.conf[:__MAIN__] = @main
@main.singleton_class.class_eval do
private
+ define_method(:exit) do |*a, &b|
+ # Do nothing, will be overridden
+ end
define_method(:binding, Kernel.instance_method(:binding))
define_method(:local_variables, Kernel.instance_method(:local_variables))
- # Define empty method to avoid delegator warning, will be overridden.
- define_method(:exit) {|*a, &b| }
- define_method(:exit!) {|*a, &b| }
end
@binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
end
@@ -110,14 +114,8 @@ EOF
# <code>IRB.conf[:__MAIN__]</code>
attr_reader :main
- def load_helper_methods_to_main
- ancestors = class<<main;ancestors;end
- main.extend ExtendCommandBundle if !ancestors.include?(ExtendCommandBundle)
- main.extend HelpersContainer if !ancestors.include?(HelpersContainer)
- end
-
# Evaluate the given +statements+ within the context of this workspace.
- def evaluate(statements, file = __FILE__, line = __LINE__)
+ def evaluate(context, statements, file = __FILE__, line = __LINE__)
eval(statements, @binding, file, line)
end
@@ -130,8 +128,6 @@ EOF
end
# error message manipulator
- # WARN: Rails patches this method to filter its own backtrace. Be cautious when changing it.
- # See: https://github.com/rails/rails/blob/main/railties/lib/rails/commands/console/console_command.rb#L8:~:text=def,filter_backtrace
def filter_backtrace(bt)
return nil if bt =~ /\/irb\/.*\.rb/
return nil if bt =~ /\/irb\.rb/
@@ -146,7 +142,11 @@ EOF
end
def code_around_binding
- file, pos = @binding.source_location
+ if @binding.respond_to?(:source_location)
+ file, pos = @binding.source_location
+ else
+ file, pos = @binding.eval('[__FILE__, __LINE__]')
+ end
if defined?(::SCRIPT_LINES__[file]) && lines = ::SCRIPT_LINES__[file]
code = ::SCRIPT_LINES__[file].join('')
@@ -173,17 +173,8 @@ EOF
"\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n"
end
- end
- module HelpersContainer
- def self.install_helper_methods
- HelperMethod.helper_methods.each do |name, helper_method_class|
- define_method name do |*args, **opts, &block|
- helper_method_class.instance.execute(*args, **opts, &block)
- end unless method_defined?(name)
- end
+ def IRB.delete_caller
end
-
- install_helper_methods
end
end
diff --git a/lib/irb/ws-for-case-2.rb b/lib/irb/ws-for-case-2.rb
index 03f42d73d9..eb173fddca 100644
--- a/lib/irb/ws-for-case-2.rb
+++ b/lib/irb/ws-for-case-2.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# irb/ws-for-case-2.rb -
+# $Release Version: 0.9.6$
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
+# --
+#
+#
+#
while true
IRB::BINDING_QUEUE.push _ = binding
diff --git a/lib/irb/xmp.rb b/lib/irb/xmp.rb
index b1bc53283e..88cbd88525 100644
--- a/lib/irb/xmp.rb
+++ b/lib/irb/xmp.rb
@@ -1,8 +1,14 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
#
# xmp.rb - irb version of gotoken xmp
+# $Release Version: 0.9$
+# $Revision$
# by Keiju ISHITSUKA(Nippon Rational Inc.)
#
+# --
+#
+#
+#
require_relative "../irb"
require_relative "frame"
@@ -44,8 +50,8 @@ class XMP
# The top-level binding or, optional +bind+ parameter will be used when
# creating the workspace. See WorkSpace.new for more information.
#
- # This uses the +:XMP+ prompt mode.
- # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
+ # This uses the +:XMP+ prompt mode, see IRB@Customizing+the+IRB+Prompt for
+ # full detail.
def initialize(bind = nil)
IRB.init_config(nil)
diff --git a/lib/logger.rb b/lib/logger.rb
index 4099955ef2..7e4dacc911 100644
--- a/lib/logger.rb
+++ b/lib/logger.rb
@@ -10,7 +10,6 @@
#
# A simple system for logging messages. See Logger for more documentation.
-require 'fiber'
require 'monitor'
require 'rbconfig'
@@ -265,7 +264,8 @@ require_relative 'logger/errors'
# logger.error! # => 3
# logger.fatal! # => 4
#
-# You can retrieve the log level with method #level.
+# You can retrieve the log level with method
+# {level}[Logger.html#attribute-i-level]:
#
# logger.level = Logger::ERROR
# logger.level # => 3
@@ -380,9 +380,7 @@ class Logger
include Severity
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
- def level
- @level_override[Fiber.current] || @level
- end
+ attr_reader :level
# Sets the log level; returns +severity+.
# See {Log Level}[rdoc-ref:Logger@Log+Level].
@@ -397,23 +395,24 @@ class Logger
# Logger#sev_threshold= is an alias for Logger#level=.
#
def level=(severity)
- @level = Severity.coerce(severity)
- end
-
- # Adjust the log level during the block execution for the current Fiber only
- #
- # logger.with_level(:debug) do
- # logger.debug { "Hello" }
- # end
- def with_level(severity)
- prev, @level_override[Fiber.current] = level, Severity.coerce(severity)
- begin
- yield
- ensure
- if prev
- @level_override[Fiber.current] = prev
+ if severity.is_a?(Integer)
+ @level = severity
+ else
+ case severity.to_s.downcase
+ when 'debug'
+ @level = DEBUG
+ when 'info'
+ @level = INFO
+ when 'warn'
+ @level = WARN
+ when 'error'
+ @level = ERROR
+ when 'fatal'
+ @level = FATAL
+ when 'unknown'
+ @level = UNKNOWN
else
- @level_override.delete(Fiber.current)
+ raise ArgumentError, "invalid log level: #{severity}"
end
end
end
@@ -584,7 +583,6 @@ class Logger
self.datetime_format = datetime_format
self.formatter = formatter
@logdev = nil
- @level_override = {}
if logdev && logdev != File::NULL
@logdev = LogDevice.new(logdev, shift_age: shift_age,
shift_size: shift_size,
diff --git a/lib/logger/logger.gemspec b/lib/logger/logger.gemspec
index 5e8232e4ab..d12db625d9 100644
--- a/lib/logger/logger.gemspec
+++ b/lib/logger/logger.gemspec
@@ -18,5 +18,9 @@ Gem::Specification.new do |spec|
spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec"]
spec.require_paths = ["lib"]
- spec.required_ruby_version = ">= 2.5.0"
+ spec.required_ruby_version = ">= 2.3.0"
+
+ spec.add_development_dependency "bundler", ">= 0"
+ spec.add_development_dependency "rake", ">= 12.3.3"
+ spec.add_development_dependency "test-unit"
end
diff --git a/lib/logger/severity.rb b/lib/logger/severity.rb
index e96fb0d320..b38afb7d22 100644
--- a/lib/logger/severity.rb
+++ b/lib/logger/severity.rb
@@ -15,24 +15,5 @@ class Logger
FATAL = 4
# An unknown message that should always be logged.
UNKNOWN = 5
-
- LEVELS = {
- "debug" => DEBUG,
- "info" => INFO,
- "warn" => WARN,
- "error" => ERROR,
- "fatal" => FATAL,
- "unknown" => UNKNOWN,
- }
- private_constant :LEVELS
-
- def self.coerce(severity)
- if severity.is_a?(Integer)
- severity
- else
- key = severity.to_s.downcase
- LEVELS[key] || raise(ArgumentError, "invalid log level: #{severity}")
- end
- end
end
end
diff --git a/lib/logger/version.rb b/lib/logger/version.rb
index 202b6e4fba..f85c72eed3 100644
--- a/lib/logger/version.rb
+++ b/lib/logger/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class Logger
- VERSION = "1.6.0"
+ VERSION = "1.5.3"
end
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 6da7dde5f1..0fbc1cc2e5 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -89,16 +89,26 @@ module MakeMakefile
unless defined? $configure_args
$configure_args = {}
- args = CONFIG["configure_args"].shellsplit
- if arg = ENV["CONFIGURE_ARGS"]
- args.push(*arg.shellsplit)
+ args = CONFIG["configure_args"]
+ if ENV["CONFIGURE_ARGS"]
+ args << " " << ENV["CONFIGURE_ARGS"]
end
- args.delete_if {|a| /\A--(?:top(?:src)?|src|cur)dir(?=\z|=)/ =~ a}
- for arg in args.concat(ARGV)
+ for arg in Shellwords::shellwords(args)
arg, val = arg.split('=', 2)
next unless arg
arg.tr!('_', '-')
- if arg.sub!(/\A(?!--)/, '--')
+ if arg.sub!(/^(?!--)/, '--')
+ val or next
+ arg.downcase!
+ end
+ next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
+ $configure_args[arg] = val || true
+ end
+ for arg in ARGV
+ arg, val = arg.split('=', 2)
+ next unless arg
+ arg.tr!('_', '-')
+ if arg.sub!(/^(?!--)/, '--')
val or next
arg.downcase!
end
@@ -971,11 +981,7 @@ SRC
# Internal use only.
#
def checking_for(m, fmt = nil)
- if f = caller_locations(1, 1).first.base_label and /\A\w/ =~ f
- f += ": "
- else
- f = ""
- end
+ f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
message "%s", m
a = r = nil
@@ -1792,8 +1798,7 @@ SRC
# application.
#
def dir_config(target, idefault=nil, ldefault=nil)
- key = [target, idefault, ldefault].compact.join("\0")
- if conf = $config_dirs[key]
+ if conf = $config_dirs[target]
return conf
end
@@ -1803,13 +1808,9 @@ SRC
end
idir = with_config(target + "-include", idefault)
- if conf = $arg_config.assoc("--with-#{target}-include")
- conf[1] ||= "${#{target}-dir}/include"
- end
+ $arg_config.last[1] ||= "${#{target}-dir}/include"
ldir = with_config(target + "-lib", ldefault)
- if conf = $arg_config.assoc("--with-#{target}-lib")
- conf[1] ||= "${#{target}-dir}/#{_libdir_basename}"
- end
+ $arg_config.last[1] ||= "${#{target}-dir}/#{_libdir_basename}"
idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
if defaults
@@ -1831,7 +1832,7 @@ SRC
end
$LIBPATH = ldirs | $LIBPATH
- $config_dirs[key] = [idir, ldir]
+ $config_dirs[target] = [idir, ldir]
end
# Returns compile/link information about an installed library in a tuple of <code>[cflags,
@@ -1854,73 +1855,66 @@ SRC
# invoked with the options and a stripped output string is returned without
# modifying any of the global values mentioned above.
def pkg_config(pkg, *options)
- fmt = "not found"
- def fmt.%(x)
- x ? x.inspect : self
- end
-
- checking_for "pkg-config for #{pkg}", fmt do
- _, ldir = dir_config(pkg)
- if ldir
- pkg_config_path = "#{ldir}/pkgconfig"
- if File.directory?(pkg_config_path)
- Logging.message("PKG_CONFIG_PATH = %s\n", pkg_config_path)
- envs = ["PKG_CONFIG_PATH"=>[pkg_config_path, ENV["PKG_CONFIG_PATH"]].compact.join(File::PATH_SEPARATOR)]
- end
+ _, ldir = dir_config(pkg)
+ if ldir
+ pkg_config_path = "#{ldir}/pkgconfig"
+ if File.directory?(pkg_config_path)
+ Logging.message("PKG_CONFIG_PATH = %s\n", pkg_config_path)
+ envs = ["PKG_CONFIG_PATH"=>[pkg_config_path, ENV["PKG_CONFIG_PATH"]].compact.join(File::PATH_SEPARATOR)]
end
- if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
+ end
+ if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
# if and only if package specific config command is given
- elsif ($PKGCONFIG ||=
- (pkgconfig = with_config("pkg-config") {config_string("PKG_CONFIG") || "pkg-config"}) &&
- find_executable0(pkgconfig) && pkgconfig) and
- xsystem([*envs, $PKGCONFIG, "--exists", pkg])
- # default to pkg-config command
- pkgconfig = $PKGCONFIG
- args = [pkg]
- elsif find_executable0(pkgconfig = "#{pkg}-config")
+ elsif ($PKGCONFIG ||=
+ (pkgconfig = with_config("pkg-config") {config_string("PKG_CONFIG") || "pkg-config"}) &&
+ find_executable0(pkgconfig) && pkgconfig) and
+ xsystem([*envs, $PKGCONFIG, "--exists", pkg])
+ # default to pkg-config command
+ pkgconfig = $PKGCONFIG
+ args = [pkg]
+ elsif find_executable0(pkgconfig = "#{pkg}-config")
# default to package specific config command, as a last resort.
+ else
+ pkgconfig = nil
+ end
+ if pkgconfig
+ get = proc {|opts|
+ opts = Array(opts).map { |o| "--#{o}" }
+ opts = xpopen([*envs, pkgconfig, *opts, *args], err:[:child, :out], &:read)
+ Logging.open {puts opts.each_line.map{|s|"=> #{s.inspect}"}}
+ opts.strip if $?.success?
+ }
+ end
+ orig_ldflags = $LDFLAGS
+ if get and !options.empty?
+ get[options]
+ elsif get and try_ldflags(ldflags = get['libs'])
+ if incflags = get['cflags-only-I']
+ $INCFLAGS << " " << incflags
+ cflags = get['cflags-only-other']
else
- pkgconfig = nil
- end
- if pkgconfig
- get = proc {|opts|
- opts = Array(opts).map { |o| "--#{o}" }
- opts = xpopen([*envs, pkgconfig, *opts, *args], err:[:child, :out], &:read)
- Logging.open {puts opts.each_line.map{|s|"=> #{s.inspect}"}}
- opts.strip if $?.success?
- }
+ cflags = get['cflags']
end
- orig_ldflags = $LDFLAGS
- if get and !options.empty?
- get[options]
- elsif get and try_ldflags(ldflags = get['libs'])
- if incflags = get['cflags-only-I']
- $INCFLAGS << " " << incflags
- cflags = get['cflags-only-other']
- else
- cflags = get['cflags']
- end
- libs = get['libs-only-l']
- if cflags
- $CFLAGS += " " << cflags
- $CXXFLAGS += " " << cflags
- end
- if libs
- ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
- else
- libs, ldflags = Shellwords.shellwords(ldflags).partition {|s| s =~ /-l([^ ]+)/ }.map {|l|l.quote.join(" ")}
- end
- $libs += " " << libs
-
- $LDFLAGS = [orig_ldflags, ldflags].join(' ')
- Logging::message "package configuration for %s\n", pkg
- Logging::message "incflags: %s\ncflags: %s\nldflags: %s\nlibs: %s\n\n",
- incflags, cflags, ldflags, libs
- [[incflags, cflags].join(' '), ldflags, libs]
+ libs = get['libs-only-l']
+ if cflags
+ $CFLAGS += " " << cflags
+ $CXXFLAGS += " " << cflags
+ end
+ if libs
+ ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
else
- Logging::message "package configuration for %s is not found\n", pkg
- nil
+ libs, ldflags = Shellwords.shellwords(ldflags).partition {|s| s =~ /-l([^ ]+)/ }.map {|l|l.quote.join(" ")}
end
+ $libs += " " << libs
+
+ $LDFLAGS = [orig_ldflags, ldflags].join(' ')
+ Logging::message "package configuration for %s\n", pkg
+ Logging::message "incflags: %s\ncflags: %s\nldflags: %s\nlibs: %s\n\n",
+ incflags, cflags, ldflags, libs
+ [[incflags, cflags].join(' '), ldflags, libs]
+ else
+ Logging::message "package configuration for %s is not found\n", pkg
+ nil
end
end
@@ -1970,14 +1964,14 @@ SRC
def configuration(srcdir)
mk = []
- verbose = with_config('verbose') ? "1" : (CONFIG['MKMF_VERBOSE'] || "0")
+ CONFIG['MKMF_VERBOSE'] ||= "0"
vpath = $VPATH.dup
CONFIG["hdrdir"] ||= $hdrdir
mk << %{
SHELL = /bin/sh
# V=0 quiet, V=1 verbose. other values don't work.
-V = #{verbose}
+V = #{CONFIG['MKMF_VERBOSE']}
V0 = $(V:0=)
Q1 = $(V:1=)
Q = $(Q1:0=@)
@@ -2704,7 +2698,7 @@ MESSAGE
when $mswin
$nmake = ?m if /nmake/i =~ make
end
- $ignore_error = " 2> #{File::NULL} || #{$mswin ? 'exit /b0' : 'true'}"
+ $ignore_error = $nmake ? '' : ' 2> /dev/null || true'
RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
$srcdir = arg_config("--srcdir", File.dirname($0))
diff --git a/lib/mutex_m.gemspec b/lib/mutex_m.gemspec
index ebbda2606c..f614dcd9a0 100644
--- a/lib/mutex_m.gemspec
+++ b/lib/mutex_m.gemspec
@@ -20,7 +20,6 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
- spec.required_ruby_version = '>= 2.5'
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb
index 7e55181881..17ec9924e4 100644
--- a/lib/mutex_m.rb
+++ b/lib/mutex_m.rb
@@ -40,15 +40,17 @@
#
module Mutex_m
- VERSION = "0.2.0"
+ VERSION = "0.1.2"
Ractor.make_shareable(VERSION) if defined?(Ractor)
def Mutex_m.define_aliases(cl) # :nodoc:
- cl.alias_method(:locked?, :mu_locked?)
- cl.alias_method(:lock, :mu_lock)
- cl.alias_method(:unlock, :mu_unlock)
- cl.alias_method(:try_lock, :mu_try_lock)
- cl.alias_method(:synchronize, :mu_synchronize)
+ cl.module_eval %q{
+ alias locked? mu_locked?
+ alias lock mu_lock
+ alias unlock mu_unlock
+ alias try_lock mu_try_lock
+ alias synchronize mu_synchronize
+ }
end
def Mutex_m.append_features(cl) # :nodoc:
diff --git a/lib/net/net-protocol.gemspec b/lib/net/net-protocol.gemspec
index 29ad2504eb..c03621cb0d 100644
--- a/lib/net/net-protocol.gemspec
+++ b/lib/net/net-protocol.gemspec
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.require_paths = ["lib"]
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 197ea09089..ea0752a971 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -26,7 +26,7 @@ require 'io/wait'
module Net # :nodoc:
class Protocol #:nodoc: internal use only
- VERSION = "0.2.2"
+ VERSION = "0.2.1"
private
def Protocol.protocol_param(name, val)
diff --git a/lib/observer.gemspec b/lib/observer.gemspec
deleted file mode 100644
index 93e61b8c84..0000000000
--- a/lib/observer.gemspec
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{Implementation of the Observer object-oriented design pattern.}
- spec.description = spec.summary
- spec.homepage = "https://github.com/ruby/observer"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- # Specify which files should be added to the gem when it is released.
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-end
diff --git a/lib/observer.rb b/lib/observer.rb
index 75832cace2..ef70e39dd8 100644
--- a/lib/observer.rb
+++ b/lib/observer.rb
@@ -136,7 +136,7 @@
# ticker.add_observer(warner, :call)
# ticker.run
module Observable
- VERSION = "0.1.2"
+ VERSION = "0.1.1"
#
# Add +observer+ as an observer on this object. So that it will receive
diff --git a/lib/observer/observer.gemspec b/lib/observer/observer.gemspec
new file mode 100644
index 0000000000..46538e881a
--- /dev/null
+++ b/lib/observer/observer.gemspec
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Implementation of the Observer object-oriented design pattern.}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/observer"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/open-uri.gemspec b/lib/open-uri.gemspec
index b6aaf35200..cad63e4d80 100644
--- a/lib/open-uri.gemspec
+++ b/lib/open-uri.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", "."].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "open-uri"
+ spec.version = "0.3.0"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/lib/open-uri.rb b/lib/open-uri.rb
index ba2379325f..93e8cfcdb7 100644
--- a/lib/open-uri.rb
+++ b/lib/open-uri.rb
@@ -31,7 +31,6 @@ module URI
super
end
end
- singleton_class.send(:ruby2_keywords, :open) if respond_to?(:ruby2_keywords, true)
end
# OpenURI is an easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.
@@ -90,9 +89,6 @@ end
# Author:: Tanaka Akira <akr@m17n.org>
module OpenURI
-
- VERSION = "0.4.1"
-
Options = {
:proxy => true,
:proxy_http_basic_authentication => true,
@@ -108,7 +104,6 @@ module OpenURI
:ftp_active_mode => false,
:redirect => true,
:encoding => nil,
- :max_redirects => 64,
}
def OpenURI.check_options(options) # :nodoc:
@@ -212,7 +207,6 @@ module OpenURI
end
uri_set = {}
- max_redirects = options[:max_redirects]
buf = nil
while true
redirect = catch(:open_uri_redirect) {
@@ -240,7 +234,6 @@ module OpenURI
uri = redirect
raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
uri_set[uri.to_s] = true
- raise TooManyRedirects.new("Too many redirects", buf.io) if max_redirects && uri_set.size > max_redirects
else
break
end
@@ -395,9 +388,6 @@ module OpenURI
attr_reader :uri
end
- class TooManyRedirects < HTTPError
- end
-
class Buffer # :nodoc: all
def initialize
@io = StringIO.new
diff --git a/lib/open3.rb b/lib/open3.rb
index 74d00b86d9..9652b27194 100644
--- a/lib/open3.rb
+++ b/lib/open3.rb
@@ -31,189 +31,57 @@
require 'open3/version'
-# \Module \Open3 supports creating child processes
-# with access to their $stdin, $stdout, and $stderr streams.
-#
-# == What's Here
-#
-# Each of these methods executes a given command in a new process or subshell,
-# or multiple commands in new processes and/or subshells:
-#
-# - Each of these methods executes a single command in a process or subshell,
-# accepts a string for input to $stdin,
-# and returns string output from $stdout, $stderr, or both:
-#
-# - Open3.capture2: Executes the command;
-# returns the string from $stdout.
-# - Open3.capture2e: Executes the command;
-# returns the string from merged $stdout and $stderr.
-# - Open3.capture3: Executes the command;
-# returns strings from $stdout and $stderr.
-#
-# - Each of these methods executes a single command in a process or subshell,
-# and returns pipes for $stdin, $stdout, and/or $stderr:
-#
-# - Open3.popen2: Executes the command;
-# returns pipes for $stdin and $stdout.
-# - Open3.popen2e: Executes the command;
-# returns pipes for $stdin and merged $stdout and $stderr.
-# - Open3.popen3: Executes the command;
-# returns pipes for $stdin, $stdout, and $stderr.
-#
-# - Each of these methods executes one or more commands in processes and/or subshells,
-# returns pipes for the first $stdin, the last $stdout, or both:
-#
-# - Open3.pipeline_r: Returns a pipe for the last $stdout.
-# - Open3.pipeline_rw: Returns pipes for the first $stdin and the last $stdout.
-# - Open3.pipeline_w: Returns a pipe for the first $stdin.
-# - Open3.pipeline_start: Does not wait for processes to complete.
-# - Open3.pipeline: Waits for processes to complete.
-#
-# Each of the methods above accepts:
-#
-# - An optional hash of environment variable names and values;
-# see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
-# - A required string argument that is a +command_line+ or +exe_path+;
-# see {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
-# - An optional hash of execution options;
-# see {Execution Options}[rdoc-ref:Process@Execution+Options].
-#
module Open3
- # :call-seq:
- # Open3.popen3([env, ] command_line, options = {}) -> [stdin, stdout, stderr, wait_thread]
- # Open3.popen3([env, ] exe_path, *args, options = {}) -> [stdin, stdout, stderr, wait_thread]
- # Open3.popen3([env, ] command_line, options = {}) {|stdin, stdout, stderr, wait_thread| ... } -> object
- # Open3.popen3([env, ] exe_path, *args, options = {}) {|stdin, stdout, stderr, wait_thread| ... } -> object
- #
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
- #
- # - Creates a child process, by calling Process.spawn with the given arguments.
- # - Creates streams +stdin+, +stdout+, and +stderr+,
- # which are the standard input, standard output, and standard error streams
- # in the child process.
- # - Creates thread +wait_thread+ that waits for the child process to exit;
- # the thread has method +pid+, which returns the process ID
- # of the child process.
- #
- # With no block given, returns the array
- # <tt>[stdin, stdout, stderr, wait_thread]</tt>.
- # The caller should close each of the three returned streams.
- #
- # stdin, stdout, stderr, wait_thread = Open3.popen3('echo')
- # # => [#<IO:fd 8>, #<IO:fd 10>, #<IO:fd 12>, #<Process::Waiter:0x00007f58d5428f58 run>]
- # stdin.close
- # stdout.close
- # stderr.close
- # wait_thread.pid # => 2210481
- # wait_thread.value # => #<Process::Status: pid 2210481 exit 0>
- #
- # With a block given, calls the block with the four variables
- # (three streams and the wait thread)
- # and returns the block's return value.
- # The caller need not close the streams:
- #
- # Open3.popen3('echo') do |stdin, stdout, stderr, wait_thread|
- # p stdin
- # p stdout
- # p stderr
- # p wait_thread
- # p wait_thread.pid
- # p wait_thread.value
- # end
- #
- # Output:
- #
- # #<IO:fd 6>
- # #<IO:fd 7>
- # #<IO:fd 9>
- # #<Process::Waiter:0x00007f58d53606e8 sleep>
- # 2211047
- # #<Process::Status: pid 2211047 exit 0>
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # Unlike Process.spawn, this method waits for the child process to exit
- # before returning, so the caller need not do so.
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in the call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- #
- # If the last argument is a hash, it becomes trailing argument +options+
- # in the call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
- #
- # The single required argument is one of the following:
- #
- # - +command_line+ if it is a string,
- # and if it begins with a shell reserved word or special built-in,
- # or if it contains one or more metacharacters.
- # - +exe_path+ otherwise.
- #
- # <b>Argument +command_line+</b>
- #
- # \String argument +command_line+ is a command line to be passed to a shell;
- # it must begin with a shell reserved word, begin with a special built-in,
- # or contain meta characters:
- #
- # Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word.
- # Open3.popen3('echo') {|*args| p args } # Built-in.
- # Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character.
- #
- # Output (similar for each call above):
- #
- # [#<IO:(closed)>, #<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f58d52f28c8 dead>]
+ # Open stdin, stdout, and stderr streams and start external executable.
+ # In addition, a thread to wait for the started process is created.
+ # The thread has a pid method and a thread variable :pid which is the pid of
+ # the started process.
#
- # The command line may also contain arguments and options for the command:
+ # Block form:
#
- # Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets }
- # "Foo\n"
+ # Open3.popen3([env,] cmd... [, opts]) {|stdin, stdout, stderr, wait_thr|
+ # pid = wait_thr.pid # pid of the started process.
+ # ...
+ # exit_status = wait_thr.value # Process::Status object returned.
+ # }
#
- # <b>Argument +exe_path+</b>
+ # Non-block form:
#
- # Argument +exe_path+ is one of the following:
- #
- # - The string path to an executable to be called.
- # - A 2-element array containing the path to an executable
- # and the string to be used as the name of the executing process.
- #
- # Example:
- #
- # Open3.popen3('/usr/bin/date') { |i, o, e, t| o.gets }
- # # => "Wed Sep 27 02:56:44 PM CDT 2023\n"
+ # stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts])
+ # pid = wait_thr[:pid] # pid of the started process
+ # ...
+ # stdin.close # stdin, stdout and stderr should be closed explicitly in this form.
+ # stdout.close
+ # stderr.close
+ # exit_status = wait_thr.value # Process::Status object returned.
#
- # Ruby invokes the executable directly, with no shell and no shell expansion:
+ # The parameters env, cmd, and opts are passed to Process.spawn.
+ # A commandline string and a list of argument strings can be accepted as follows:
#
- # Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT
+ # Open3.popen3("echo abc") {|i, o, e, t| ... }
+ # Open3.popen3("echo", "abc") {|i, o, e, t| ... }
+ # Open3.popen3(["echo", "argv0"], "abc") {|i, o, e, t| ... }
#
- # If one or more +args+ is given, each is an argument or option
- # to be passed to the executable:
+ # If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn.
#
- # Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets }
- # # => "C #\n"
- # Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets }
- # # => "hello world\n"
+ # Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t|
+ # p o.read.chomp #=> "/"
+ # }
#
- # Take care to avoid deadlocks.
- # Output streams +stdout+ and +stderr+ have fixed-size buffers,
- # so reading extensively from one but not the other can cause a deadlock
- # when the unread buffer fills.
- # To avoid that, +stdout+ and +stderr+ should be read simultaneously
- # (using threads or IO.select).
+ # wait_thr.value waits for the termination of the process.
+ # The block form also waits for the process when it returns.
#
- # Related:
+ # Closing stdin, stdout and stderr does not wait for the process to complete.
#
- # - Open3.popen2: Makes the standard input and standard output streams
- # of the child process available as separate streams,
- # with no access to the standard error stream.
- # - Open3.popen2e: Makes the standard input and the merge
- # of the standard output and standard error streams
- # of the child process available as separate streams.
+ # You should be careful to avoid deadlocks.
+ # Since pipes are fixed length buffers,
+ # Open3.popen3("prog") {|i, o, e, t| o.read } deadlocks if
+ # the program generates too much output on stderr.
+ # You should read stdout and stderr simultaneously (using threads or IO.select).
+ # However, if you don't need stderr output, you can use Open3.popen2.
+ # If merged stdout and stderr output is not a problem, you can use Open3.popen2e.
+ # If you really need stdout and stderr output as separate strings, you can consider Open3.capture3.
#
def popen3(*cmd, &block)
if Hash === cmd.last
@@ -236,131 +104,45 @@ module Open3
end
module_function :popen3
- # :call-seq:
- # Open3.popen2([env, ] command_line, options = {}) -> [stdin, stdout, wait_thread]
- # Open3.popen2([env, ] exe_path, *args, options = {}) -> [stdin, stdout, wait_thread]
- # Open3.popen2([env, ] command_line, options = {}) {|stdin, stdout, wait_thread| ... } -> object
- # Open3.popen2([env, ] exe_path, *args, options = {}) {|stdin, stdout, wait_thread| ... } -> object
- #
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
- #
- # - Creates a child process, by calling Process.spawn with the given arguments.
- # - Creates streams +stdin+ and +stdout+,
- # which are the standard input and standard output streams
- # in the child process.
- # - Creates thread +wait_thread+ that waits for the child process to exit;
- # the thread has method +pid+, which returns the process ID
- # of the child process.
- #
- # With no block given, returns the array
- # <tt>[stdin, stdout, wait_thread]</tt>.
- # The caller should close each of the two returned streams.
- #
- # stdin, stdout, wait_thread = Open3.popen2('echo')
- # # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f58d52dbe98 run>]
- # stdin.close
- # stdout.close
- # wait_thread.pid # => 2263572
- # wait_thread.value # => #<Process::Status: pid 2263572 exit 0>
- #
- # With a block given, calls the block with the three variables
- # (two streams and the wait thread)
- # and returns the block's return value.
- # The caller need not close the streams:
- #
- # Open3.popen2('echo') do |stdin, stdout, wait_thread|
- # p stdin
- # p stdout
- # p wait_thread
- # p wait_thread.pid
- # p wait_thread.value
- # end
- #
- # Output:
- #
- # #<IO:fd 6>
- # #<IO:fd 7>
- # #<Process::Waiter:0x00007f58d59a34b0 sleep>
- # 2263636
- # #<Process::Status: pid 2263636 exit 0>
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # Unlike Process.spawn, this method waits for the child process to exit
- # before returning, so the caller need not do so.
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in the call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
+ # Open3.popen2 is similar to Open3.popen3 except that it doesn't create a pipe for
+ # the standard error stream.
#
- # If the last argument is a hash, it becomes trailing argument +options+
- # in the call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ # Block form:
#
- # The single required argument is one of the following:
+ # Open3.popen2([env,] cmd... [, opts]) {|stdin, stdout, wait_thr|
+ # pid = wait_thr.pid # pid of the started process.
+ # ...
+ # exit_status = wait_thr.value # Process::Status object returned.
+ # }
#
- # - +command_line+ if it is a string,
- # and if it begins with a shell reserved word or special built-in,
- # or if it contains one or more metacharacters.
- # - +exe_path+ otherwise.
+ # Non-block form:
#
- # <b>Argument +command_line+</b>
- #
- # \String argument +command_line+ is a command line to be passed to a shell;
- # it must begin with a shell reserved word, begin with a special built-in,
- # or contain meta characters:
- #
- # Open3.popen2('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word.
- # Open3.popen2('echo') {|*args| p args } # Built-in.
- # Open3.popen2('date > date.tmp') {|*args| p args } # Contains meta character.
- #
- # Output (similar for each call above):
- #
- # # => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577dfe410 dead>]
- #
- # The command line may also contain arguments and options for the command:
- #
- # Open3.popen2('echo "Foo"') { |i, o, t| o.gets }
- # "Foo\n"
- #
- # <b>Argument +exe_path+</b>
- #
- # Argument +exe_path+ is one of the following:
+ # stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts])
+ # ...
+ # stdin.close # stdin and stdout should be closed explicitly in this form.
+ # stdout.close
#
- # - The string path to an executable to be called.
- # - A 2-element array containing the path to an executable
- # and the string to be used as the name of the executing process.
+ # See Process.spawn for the optional hash arguments _env_ and _opts_.
#
# Example:
#
- # Open3.popen2('/usr/bin/date') { |i, o, t| o.gets }
- # # => "Thu Sep 28 09:41:06 AM CDT 2023\n"
- #
- # Ruby invokes the executable directly, with no shell and no shell expansion:
- #
- # Open3.popen2('doesnt_exist') { |i, o, t| o.gets } # Raises Errno::ENOENT
- #
- # If one or more +args+ is given, each is an argument or option
- # to be passed to the executable:
- #
- # Open3.popen2('echo', 'C #') { |i, o, t| o.gets }
- # # => "C #\n"
- # Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets }
- # # => "hello world\n"
+ # Open3.popen2("wc -c") {|i,o,t|
+ # i.print "answer to life the universe and everything"
+ # i.close
+ # p o.gets #=> "42\n"
+ # }
#
+ # Open3.popen2("bc -q") {|i,o,t|
+ # i.puts "obase=13"
+ # i.puts "6 * 9"
+ # p o.gets #=> "42\n"
+ # }
#
- # Related:
- #
- # - Open3.popen2e: Makes the standard input and the merge
- # of the standard output and standard error streams
- # of the child process available as separate streams.
- # - Open3.popen3: Makes the standard input, standard output,
- # and standard error streams
- # of the child process available as separate streams.
+ # Open3.popen2("dc") {|i,o,t|
+ # i.print "42P"
+ # i.close
+ # p o.read #=> "*"
+ # }
#
def popen2(*cmd, &block)
if Hash === cmd.last
@@ -380,130 +162,36 @@ module Open3
end
module_function :popen2
- # :call-seq:
- # Open3.popen2e([env, ] command_line, options = {}) -> [stdin, stdout_and_stderr, wait_thread]
- # Open3.popen2e([env, ] exe_path, *args, options = {}) -> [stdin, stdout_and_stderr, wait_thread]
- # Open3.popen2e([env, ] command_line, options = {}) {|stdin, stdout_and_stderr, wait_thread| ... } -> object
- # Open3.popen2e([env, ] exe_path, *args, options = {}) {|stdin, stdout_and_stderr, wait_thread| ... } -> object
- #
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
- #
- # - Creates a child process, by calling Process.spawn with the given arguments.
- # - Creates streams +stdin+, +stdout_and_stderr+,
- # which are the standard input and the merge of the standard output
- # and standard error streams in the child process.
- # - Creates thread +wait_thread+ that waits for the child process to exit;
- # the thread has method +pid+, which returns the process ID
- # of the child process.
- #
- # With no block given, returns the array
- # <tt>[stdin, stdout_and_stderr, wait_thread]</tt>.
- # The caller should close each of the two returned streams.
- #
- # stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo')
- # # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f7577da4398 run>]
- # stdin.close
- # stdout_and_stderr.close
- # wait_thread.pid # => 2274600
- # wait_thread.value # => #<Process::Status: pid 2274600 exit 0>
- #
- # With a block given, calls the block with the three variables
- # (two streams and the wait thread)
- # and returns the block's return value.
- # The caller need not close the streams:
- #
- # Open3.popen2e('echo') do |stdin, stdout_and_stderr, wait_thread|
- # p stdin
- # p stdout_and_stderr
- # p wait_thread
- # p wait_thread.pid
- # p wait_thread.value
- # end
- #
- # Output:
- #
- # #<IO:fd 6>
- # #<IO:fd 7>
- # #<Process::Waiter:0x00007f75777578c8 sleep>
- # 2274763
- # #<Process::Status: pid 2274763 exit 0>
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # Unlike Process.spawn, this method waits for the child process to exit
- # before returning, so the caller need not do so.
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in the call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- #
- # If the last argument is a hash, it becomes trailing argument +options+
- # in the call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
- #
- # The single required argument is one of the following:
- #
- # - +command_line+ if it is a string,
- # and if it begins with a shell reserved word or special built-in,
- # or if it contains one or more metacharacters.
- # - +exe_path+ otherwise.
- #
- # <b>Argument +command_line+</b>
- #
- # \String argument +command_line+ is a command line to be passed to a shell;
- # it must begin with a shell reserved word, begin with a special built-in,
- # or contain meta characters:
+ # Open3.popen2e is similar to Open3.popen3 except that it merges
+ # the standard output stream and the standard error stream.
#
- # Open3.popen2e('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word.
- # Open3.popen2e('echo') {|*args| p args } # Built-in.
- # Open3.popen2e('date > date.tmp') {|*args| p args } # Contains meta character.
+ # Block form:
#
- # Output (similar for each call above):
+ # Open3.popen2e([env,] cmd... [, opts]) {|stdin, stdout_and_stderr, wait_thr|
+ # pid = wait_thr.pid # pid of the started process.
+ # ...
+ # exit_status = wait_thr.value # Process::Status object returned.
+ # }
#
- # # => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577d8a1f0 dead>]
+ # Non-block form:
#
- # The command line may also contain arguments and options for the command:
- #
- # Open3.popen2e('echo "Foo"') { |i, o_and_e, t| o_and_e.gets }
- # "Foo\n"
- #
- # <b>Argument +exe_path+</b>
- #
- # Argument +exe_path+ is one of the following:
+ # stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts])
+ # ...
+ # stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form.
+ # stdout_and_stderr.close
#
- # - The string path to an executable to be called.
- # - A 2-element array containing the path to an executable
- # and the string to be used as the name of the executing process.
+ # See Process.spawn for the optional hash arguments _env_ and _opts_.
#
# Example:
- #
- # Open3.popen2e('/usr/bin/date') { |i, o_and_e, t| o_and_e.gets }
- # # => "Thu Sep 28 01:58:45 PM CDT 2023\n"
- #
- # Ruby invokes the executable directly, with no shell and no shell expansion:
- #
- # Open3.popen2e('doesnt_exist') { |i, o_and_e, t| o_and_e.gets } # Raises Errno::ENOENT
- #
- # If one or more +args+ is given, each is an argument or option
- # to be passed to the executable:
- #
- # Open3.popen2e('echo', 'C #') { |i, o_and_e, t| o_and_e.gets }
- # # => "C #\n"
- # Open3.popen2e('echo', 'hello', 'world') { |i, o_and_e, t| o_and_e.gets }
- # # => "hello world\n"
- #
- # Related:
- #
- # - Open3.popen2: Makes the standard input and standard output streams
- # of the child process available as separate streams,
- # with no access to the standard error stream.
- # - Open3.popen3: Makes the standard input, standard output,
- # and standard error streams
- # of the child process available as separate streams.
+ # # check gcc warnings
+ # source = "foo.c"
+ # Open3.popen2e("gcc", "-Wall", source) {|i,oe,t|
+ # oe.each {|line|
+ # if /warning/ =~ line
+ # ...
+ # end
+ # }
+ # }
#
def popen2e(*cmd, &block)
if Hash === cmd.last
@@ -550,100 +238,44 @@ module Open3
private :popen_run
end
- # :call-seq:
- # Open3.capture3([env, ] command_line, options = {}) -> [stdout_s, stderr_s, status]
- # Open3.capture3([env, ] exe_path, *args, options = {}) -> [stdout_s, stderr_s, status]
- #
- # Basically a wrapper for Open3.popen3 that:
- #
- # - Creates a child process, by calling Open3.popen3 with the given arguments
- # (except for certain entries in hash +options+; see below).
- # - Returns as strings +stdout_s+ and +stderr_s+ the standard output
- # and standard error of the child process.
- # - Returns as +status+ a <tt>Process::Status</tt> object
- # that represents the exit status of the child process.
+ # Open3.capture3 captures the standard output and the standard error of a command.
#
- # Returns the array <tt>[stdout_s, stderr_s, status]</tt>:
+ # stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts])
#
- # stdout_s, stderr_s, status = Open3.capture3('echo "Foo"')
- # # => ["Foo\n", "", #<Process::Status: pid 2281954 exit 0>]
+ # The arguments env, cmd and opts are passed to Open3.popen3 except
+ # <code>opts[:stdin_data]</code> and <code>opts[:binmode]</code>. See Process.spawn.
#
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
+ # If <code>opts[:stdin_data]</code> is specified, it is sent to the command's standard input.
#
- # Unlike Process.spawn, this method waits for the child process to exit
- # before returning, so the caller need not do so.
+ # If <code>opts[:binmode]</code> is true, internal pipes are set to binary mode.
#
- # If the first argument is a hash, it becomes leading argument +env+
- # in the call to Open3.popen3;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
+ # Examples:
#
- # If the last argument is a hash, it becomes trailing argument +options+
- # in the call to Open3.popen3;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ # # dot is a command of graphviz.
+ # graph = <<'End'
+ # digraph g {
+ # a -> b
+ # }
+ # End
+ # drawn_graph, dot_log = Open3.capture3("dot -v", :stdin_data=>graph)
#
- # The hash +options+ is given;
- # two options have local effect in method Open3.capture3:
+ # o, e, s = Open3.capture3("echo abc; sort >&2", :stdin_data=>"foo\nbar\nbaz\n")
+ # p o #=> "abc\n"
+ # p e #=> "bar\nbaz\nfoo\n"
+ # p s #=> #<Process::Status: pid 32682 exit 0>
#
- # - If entry <tt>options[:stdin_data]</tt> exists, the entry is removed
- # and its string value is sent to the command's standard input:
- #
- # Open3.capture3('tee', stdin_data: 'Foo')
- # # => ["Foo", "", #<Process::Status: pid 2319575 exit 0>]
- #
- # - If entry <tt>options[:binmode]</tt> exists, the entry is removed and
- # the internal streams are set to binary mode.
- #
- # The single required argument is one of the following:
- #
- # - +command_line+ if it is a string,
- # and if it begins with a shell reserved word or special built-in,
- # or if it contains one or more metacharacters.
- # - +exe_path+ otherwise.
- #
- # <b>Argument +command_line+</b>
- #
- # \String argument +command_line+ is a command line to be passed to a shell;
- # it must begin with a shell reserved word, begin with a special built-in,
- # or contain meta characters:
- #
- # Open3.capture3('if true; then echo "Foo"; fi') # Shell reserved word.
- # # => ["Foo\n", "", #<Process::Status: pid 2282025 exit 0>]
- # Open3.capture3('echo') # Built-in.
- # # => ["\n", "", #<Process::Status: pid 2282092 exit 0>]
- # Open3.capture3('date > date.tmp') # Contains meta character.
- # # => ["", "", #<Process::Status: pid 2282110 exit 0>]
- #
- # The command line may also contain arguments and options for the command:
- #
- # Open3.capture3('echo "Foo"')
- # # => ["Foo\n", "", #<Process::Status: pid 2282092 exit 0>]
- #
- # <b>Argument +exe_path+</b>
- #
- # Argument +exe_path+ is one of the following:
- #
- # - The string path to an executable to be called.
- # - A 2-element array containing the path to an executable
- # and the string to be used as the name of the executing process.
- #
- # Example:
- #
- # Open3.capture3('/usr/bin/date')
- # # => ["Thu Sep 28 05:03:51 PM CDT 2023\n", "", #<Process::Status: pid 2282300 exit 0>]
- #
- # Ruby invokes the executable directly, with no shell and no shell expansion:
- #
- # Open3.capture3('doesnt_exist') # Raises Errno::ENOENT
- #
- # If one or more +args+ is given, each is an argument or option
- # to be passed to the executable:
- #
- # Open3.capture3('echo', 'C #')
- # # => ["C #\n", "", #<Process::Status: pid 2282368 exit 0>]
- # Open3.capture3('echo', 'hello', 'world')
- # # => ["hello world\n", "", #<Process::Status: pid 2282372 exit 0>]
+ # # generate a thumbnail image using the convert command of ImageMagick.
+ # # However, if the image is really stored in a file,
+ # # system("convert", "-thumbnail", "80", "png:#{filename}", "png:-") is better
+ # # because of reduced memory consumption.
+ # # But if the image is stored in a DB or generated by the gnuplot Open3.capture2 example,
+ # # Open3.capture3 should be considered.
+ # #
+ # image = File.read("/usr/share/openclipart/png/animals/mammals/sheep-md-v0.1.png", :binmode=>true)
+ # thumbnail, err, s = Open3.capture3("convert -thumbnail 80 png:- png:-", :stdin_data=>image, :binmode=>true)
+ # if s.success?
+ # STDOUT.binmode; print thumbnail
+ # end
#
def capture3(*cmd)
if Hash === cmd.last
@@ -677,100 +309,34 @@ module Open3
end
module_function :capture3
- # :call-seq:
- # Open3.capture2([env, ] command_line, options = {}) -> [stdout_s, status]
- # Open3.capture2([env, ] exe_path, *args, options = {}) -> [stdout_s, status]
- #
- # Basically a wrapper for Open3.popen3 that:
- #
- # - Creates a child process, by calling Open3.popen3 with the given arguments
- # (except for certain entries in hash +options+; see below).
- # - Returns as string +stdout_s+ the standard output of the child process.
- # - Returns as +status+ a <tt>Process::Status</tt> object
- # that represents the exit status of the child process.
- #
- # Returns the array <tt>[stdout_s, status]</tt>:
- #
- # stdout_s, status = Open3.capture2('echo "Foo"')
- # # => ["Foo\n", #<Process::Status: pid 2326047 exit 0>]
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # Unlike Process.spawn, this method waits for the child process to exit
- # before returning, so the caller need not do so.
+ # Open3.capture2 captures the standard output of a command.
#
- # If the first argument is a hash, it becomes leading argument +env+
- # in the call to Open3.popen3;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
+ # stdout_str, status = Open3.capture2([env,] cmd... [, opts])
#
- # If the last argument is a hash, it becomes trailing argument +options+
- # in the call to Open3.popen3;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ # The arguments env, cmd and opts are passed to Open3.popen3 except
+ # <code>opts[:stdin_data]</code> and <code>opts[:binmode]</code>. See Process.spawn.
#
- # The hash +options+ is given;
- # two options have local effect in method Open3.capture2:
+ # If <code>opts[:stdin_data]</code> is specified, it is sent to the command's standard input.
#
- # - If entry <tt>options[:stdin_data]</tt> exists, the entry is removed
- # and its string value is sent to the command's standard input:
- #
- # Open3.capture2('tee', stdin_data: 'Foo')
- #
- # # => ["Foo", #<Process::Status: pid 2326087 exit 0>]
- #
- # - If entry <tt>options[:binmode]</tt> exists, the entry is removed and
- # the internal streams are set to binary mode.
- #
- # The single required argument is one of the following:
- #
- # - +command_line+ if it is a string,
- # and if it begins with a shell reserved word or special built-in,
- # or if it contains one or more metacharacters.
- # - +exe_path+ otherwise.
- #
- # <b>Argument +command_line+</b>
- #
- # \String argument +command_line+ is a command line to be passed to a shell;
- # it must begin with a shell reserved word, begin with a special built-in,
- # or contain meta characters:
- #
- # Open3.capture2('if true; then echo "Foo"; fi') # Shell reserved word.
- # # => ["Foo\n", #<Process::Status: pid 2326131 exit 0>]
- # Open3.capture2('echo') # Built-in.
- # # => ["\n", #<Process::Status: pid 2326139 exit 0>]
- # Open3.capture2('date > date.tmp') # Contains meta character.
- # # => ["", #<Process::Status: pid 2326174 exit 0>]
- #
- # The command line may also contain arguments and options for the command:
- #
- # Open3.capture2('echo "Foo"')
- # # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
- #
- # <b>Argument +exe_path+</b>
- #
- # Argument +exe_path+ is one of the following:
- #
- # - The string path to an executable to be called.
- # - A 2-element array containing the path to an executable
- # and the string to be used as the name of the executing process.
+ # If <code>opts[:binmode]</code> is true, internal pipes are set to binary mode.
#
# Example:
#
- # Open3.capture2('/usr/bin/date')
- # # => ["Fri Sep 29 01:00:39 PM CDT 2023\n", #<Process::Status: pid 2326222 exit 0>]
- #
- # Ruby invokes the executable directly, with no shell and no shell expansion:
- #
- # Open3.capture2('doesnt_exist') # Raises Errno::ENOENT
- #
- # If one or more +args+ is given, each is an argument or option
- # to be passed to the executable:
- #
- # Open3.capture2('echo', 'C #')
- # # => ["C #\n", #<Process::Status: pid 2326267 exit 0>]
- # Open3.capture2('echo', 'hello', 'world')
- # # => ["hello world\n", #<Process::Status: pid 2326299 exit 0>]
+ # # factor is a command for integer factorization.
+ # o, s = Open3.capture2("factor", :stdin_data=>"42")
+ # p o #=> "42: 2 3 7\n"
+ #
+ # # generate x**2 graph in png using gnuplot.
+ # gnuplot_commands = <<"End"
+ # set terminal png
+ # plot x**2, "-" with lines
+ # 1 14
+ # 2 1
+ # 3 8
+ # 4 5
+ # e
+ # End
+ # image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)
#
def capture2(*cmd)
if Hash === cmd.last
@@ -804,100 +370,21 @@ module Open3
end
module_function :capture2
- # :call-seq:
- # Open3.capture2e([env, ] command_line, options = {}) -> [stdout_and_stderr_s, status]
- # Open3.capture2e([env, ] exe_path, *args, options = {}) -> [stdout_and_stderr_s, status]
- #
- # Basically a wrapper for Open3.popen3 that:
- #
- # - Creates a child process, by calling Open3.popen3 with the given arguments
- # (except for certain entries in hash +options+; see below).
- # - Returns as string +stdout_and_stderr_s+ the merged standard output
- # and standard error of the child process.
- # - Returns as +status+ a <tt>Process::Status</tt> object
- # that represents the exit status of the child process.
- #
- # Returns the array <tt>[stdout_and_stderr_s, status]</tt>:
- #
- # stdout_and_stderr_s, status = Open3.capture2e('echo "Foo"')
- # # => ["Foo\n", #<Process::Status: pid 2371692 exit 0>]
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # Unlike Process.spawn, this method waits for the child process to exit
- # before returning, so the caller need not do so.
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in the call to Open3.popen3;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- #
- # If the last argument is a hash, it becomes trailing argument +options+
- # in the call to Open3.popen3;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
- #
- # The hash +options+ is given;
- # two options have local effect in method Open3.capture2e:
- #
- # - If entry <tt>options[:stdin_data]</tt> exists, the entry is removed
- # and its string value is sent to the command's standard input:
+ # Open3.capture2e captures the standard output and the standard error of a command.
#
- # Open3.capture2e('tee', stdin_data: 'Foo')
- # # => ["Foo", #<Process::Status: pid 2371732 exit 0>]
+ # stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts])
#
- # - If entry <tt>options[:binmode]</tt> exists, the entry is removed and
- # the internal streams are set to binary mode.
+ # The arguments env, cmd and opts are passed to Open3.popen3 except
+ # <code>opts[:stdin_data]</code> and <code>opts[:binmode]</code>. See Process.spawn.
#
- # The single required argument is one of the following:
+ # If <code>opts[:stdin_data]</code> is specified, it is sent to the command's standard input.
#
- # - +command_line+ if it is a string,
- # and if it begins with a shell reserved word or special built-in,
- # or if it contains one or more metacharacters.
- # - +exe_path+ otherwise.
- #
- # <b>Argument +command_line+</b>
- #
- # \String argument +command_line+ is a command line to be passed to a shell;
- # it must begin with a shell reserved word, begin with a special built-in,
- # or contain meta characters:
- #
- # Open3.capture2e('if true; then echo "Foo"; fi') # Shell reserved word.
- # # => ["Foo\n", #<Process::Status: pid 2371740 exit 0>]
- # Open3.capture2e('echo') # Built-in.
- # # => ["\n", #<Process::Status: pid 2371774 exit 0>]
- # Open3.capture2e('date > date.tmp') # Contains meta character.
- # # => ["", #<Process::Status: pid 2371812 exit 0>]
- #
- # The command line may also contain arguments and options for the command:
- #
- # Open3.capture2e('echo "Foo"')
- # # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
- #
- # <b>Argument +exe_path+</b>
- #
- # Argument +exe_path+ is one of the following:
- #
- # - The string path to an executable to be called.
- # - A 2-element array containing the path to an executable
- # and the string to be used as the name of the executing process.
+ # If <code>opts[:binmode]</code> is true, internal pipes are set to binary mode.
#
# Example:
#
- # Open3.capture2e('/usr/bin/date')
- # # => ["Sat Sep 30 09:01:46 AM CDT 2023\n", #<Process::Status: pid 2371820 exit 0>]
- #
- # Ruby invokes the executable directly, with no shell and no shell expansion:
- #
- # Open3.capture2e('doesnt_exist') # Raises Errno::ENOENT
- #
- # If one or more +args+ is given, each is an argument or option
- # to be passed to the executable:
- #
- # Open3.capture2e('echo', 'C #')
- # # => ["C #\n", #<Process::Status: pid 2371856 exit 0>]
- # Open3.capture2e('echo', 'hello', 'world')
- # # => ["hello world\n", #<Process::Status: pid 2371894 exit 0>]
+ # # capture make log
+ # make_log, s = Open3.capture2e("make")
#
def capture2e(*cmd)
if Hash === cmd.last
@@ -931,86 +418,48 @@ module Open3
end
module_function :capture2e
- # :call-seq:
- # Open3.pipeline_rw([env, ] *cmds, options = {}) -> [first_stdin, last_stdout, wait_threads]
- #
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
- #
- # - Creates a child process for each of the given +cmds+
- # by calling Process.spawn.
- # - Pipes the +stdout+ from each child to the +stdin+ of the next child,
- # or, for the first child, from the caller's +stdin+,
- # or, for the last child, to the caller's +stdout+.
- #
- # The method does not wait for child processes to exit,
- # so the caller must do so.
- #
- # With no block given, returns a 3-element array containing:
- #
- # - The +stdin+ stream of the first child process.
- # - The +stdout+ stream of the last child process.
- # - An array of the wait threads for all of the child processes.
- #
- # Example:
- #
- # first_stdin, last_stdout, wait_threads = Open3.pipeline_rw('sort', 'cat -n')
- # # => [#<IO:fd 20>, #<IO:fd 21>, [#<Process::Waiter:0x000055e8de29ab40 sleep>, #<Process::Waiter:0x000055e8de29a690 sleep>]]
- # first_stdin.puts("foo\nbar\nbaz")
- # first_stdin.close # Send EOF to sort.
- # puts last_stdout.read
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- #
- # Output:
- #
- # 1 bar
- # 2 baz
- # 3 foo
- #
- # With a block given, calls the block with the +stdin+ stream of the first child,
- # the +stdout+ stream of the last child,
- # and an array of the wait processes:
- #
- # Open3.pipeline_rw('sort', 'cat -n') do |first_stdin, last_stdout, wait_threads|
- # first_stdin.puts "foo\nbar\nbaz"
- # first_stdin.close # send EOF to sort.
- # puts last_stdout.read
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- # end
+ # Open3.pipeline_rw starts a list of commands as a pipeline with pipes
+ # which connect to stdin of the first command and stdout of the last command.
#
- # Output:
+ # Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) {|first_stdin, last_stdout, wait_threads|
+ # ...
+ # }
#
- # 1 bar
- # 2 baz
- # 3 foo
+ # first_stdin, last_stdout, wait_threads = Open3.pipeline_rw(cmd1, cmd2, ... [, opts])
+ # ...
+ # first_stdin.close
+ # last_stdout.close
#
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
+ # Each cmd is a string or an array.
+ # If it is an array, the elements are passed to Process.spawn.
#
- # If the first argument is a hash, it becomes leading argument +env+
- # in each call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
+ # cmd:
+ # commandline command line string which is passed to a shell
+ # [env, commandline, opts] command line string which is passed to a shell
+ # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
+ # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
#
- # If the last argument is a hash, it becomes trailing argument +options+
- # in each call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ # Note that env and opts are optional, as for Process.spawn.
#
- # Each remaining argument in +cmds+ is one of:
+ # The options to pass to Process.spawn are constructed by merging
+ # +opts+, the last hash element of the array, and
+ # specifications for the pipes between each of the commands.
#
- # - A +command_line+: a string that begins with a shell reserved word
- # or special built-in, or contains one or more metacharacters.
- # - An +exe_path+: the string path to an executable to be called.
- # - An array containing a +command_line+ or an +exe_path+,
- # along with zero or more string arguments for the command.
- #
- # See {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
+ # Example:
#
+ # Open3.pipeline_rw("tr -dc A-Za-z", "wc -c") {|i, o, ts|
+ # i.puts "All persons more than a mile high to leave the court."
+ # i.close
+ # p o.gets #=> "42\n"
+ # }
+ #
+ # Open3.pipeline_rw("sort", "cat -n") {|stdin, stdout, wait_thrs|
+ # stdin.puts "foo"
+ # stdin.puts "bar"
+ # stdin.puts "baz"
+ # stdin.close # send EOF to sort.
+ # p stdout.read #=> " 1\tbar\n 2\tbaz\n 3\tfoo\n"
+ # }
def pipeline_rw(*cmds, &block)
if Hash === cmds.last
opts = cmds.pop.dup
@@ -1029,77 +478,43 @@ module Open3
end
module_function :pipeline_rw
- # :call-seq:
- # Open3.pipeline_r([env, ] *cmds, options = {}) -> [last_stdout, wait_threads]
+ # Open3.pipeline_r starts a list of commands as a pipeline with a pipe
+ # which connects to stdout of the last command.
#
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
+ # Open3.pipeline_r(cmd1, cmd2, ... [, opts]) {|last_stdout, wait_threads|
+ # ...
+ # }
#
- # - Creates a child process for each of the given +cmds+
- # by calling Process.spawn.
- # - Pipes the +stdout+ from each child to the +stdin+ of the next child,
- # or, for the last child, to the caller's +stdout+.
+ # last_stdout, wait_threads = Open3.pipeline_r(cmd1, cmd2, ... [, opts])
+ # ...
+ # last_stdout.close
#
- # The method does not wait for child processes to exit,
- # so the caller must do so.
+ # Each cmd is a string or an array.
+ # If it is an array, the elements are passed to Process.spawn.
#
- # With no block given, returns a 2-element array containing:
+ # cmd:
+ # commandline command line string which is passed to a shell
+ # [env, commandline, opts] command line string which is passed to a shell
+ # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
+ # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
#
- # - The +stdout+ stream of the last child process.
- # - An array of the wait threads for all of the child processes.
+ # Note that env and opts are optional, as for Process.spawn.
#
# Example:
#
- # last_stdout, wait_threads = Open3.pipeline_r('ls', 'grep R')
- # # => [#<IO:fd 5>, [#<Process::Waiter:0x000055e8de2f9898 dead>, #<Process::Waiter:0x000055e8de2f94b0 sleep>]]
- # puts last_stdout.read
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- #
- # Output:
- #
- # Rakefile
- # README.md
- #
- # With a block given, calls the block with the +stdout+ stream
- # of the last child process,
- # and an array of the wait processes:
- #
- # Open3.pipeline_r('ls', 'grep R') do |last_stdout, wait_threads|
- # puts last_stdout.read
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- # end
- #
- # Output:
- #
- # Rakefile
- # README.md
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in each call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- #
- # If the last argument is a hash, it becomes trailing argument +options+
- # in each call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ # Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz",
+ # [{"LANG"=>"C"}, "grep", "GET /favicon.ico"],
+ # "logresolve") {|o, ts|
+ # o.each_line {|line|
+ # ...
+ # }
+ # }
#
- # Each remaining argument in +cmds+ is one of:
- #
- # - A +command_line+: a string that begins with a shell reserved word
- # or special built-in, or contains one or more metacharacters.
- # - An +exe_path+: the string path to an executable to be called.
- # - An array containing a +command_line+ or an +exe_path+,
- # along with zero or more string arguments for the command.
- #
- # See {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
+ # Open3.pipeline_r("yes", "head -10") {|o, ts|
+ # p o.read #=> "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"
+ # p ts[0].value #=> #<Process::Status: pid 24910 SIGPIPE (signal 13)>
+ # p ts[1].value #=> #<Process::Status: pid 24913 exit 0>
+ # }
#
def pipeline_r(*cmds, &block)
if Hash === cmds.last
@@ -1115,82 +530,33 @@ module Open3
end
module_function :pipeline_r
-
- # :call-seq:
- # Open3.pipeline_w([env, ] *cmds, options = {}) -> [first_stdin, wait_threads]
+ # Open3.pipeline_w starts a list of commands as a pipeline with a pipe
+ # which connects to stdin of the first command.
#
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
+ # Open3.pipeline_w(cmd1, cmd2, ... [, opts]) {|first_stdin, wait_threads|
+ # ...
+ # }
#
- # - Creates a child process for each of the given +cmds+
- # by calling Process.spawn.
- # - Pipes the +stdout+ from each child to the +stdin+ of the next child,
- # or, for the first child, pipes the caller's +stdout+ to the child's +stdin+.
+ # first_stdin, wait_threads = Open3.pipeline_w(cmd1, cmd2, ... [, opts])
+ # ...
+ # first_stdin.close
#
- # The method does not wait for child processes to exit,
- # so the caller must do so.
+ # Each cmd is a string or an array.
+ # If it is an array, the elements are passed to Process.spawn.
#
- # With no block given, returns a 2-element array containing:
+ # cmd:
+ # commandline command line string which is passed to a shell
+ # [env, commandline, opts] command line string which is passed to a shell
+ # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
+ # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
#
- # - The +stdin+ stream of the first child process.
- # - An array of the wait threads for all of the child processes.
+ # Note that env and opts are optional, as for Process.spawn.
#
# Example:
#
- # first_stdin, wait_threads = Open3.pipeline_w('sort', 'cat -n')
- # # => [#<IO:fd 7>, [#<Process::Waiter:0x000055e8de928278 run>, #<Process::Waiter:0x000055e8de923e80 run>]]
- # first_stdin.puts("foo\nbar\nbaz")
- # first_stdin.close # Send EOF to sort.
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- #
- # Output:
- #
- # 1 bar
- # 2 baz
- # 3 foo
- #
- # With a block given, calls the block with the +stdin+ stream
- # of the first child process,
- # and an array of the wait processes:
- #
- # Open3.pipeline_w('sort', 'cat -n') do |first_stdin, wait_threads|
- # first_stdin.puts("foo\nbar\nbaz")
- # first_stdin.close # Send EOF to sort.
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- # end
- #
- # Output:
- #
- # 1 bar
- # 2 baz
- # 3 foo
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in each call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- #
- # If the last argument is a hash, it becomes trailing argument +options+
- # in each call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
- #
- # Each remaining argument in +cmds+ is one of:
- #
- # - A +command_line+: a string that begins with a shell reserved word
- # or special built-in, or contains one or more metacharacters.
- # - An +exe_path+: the string path to an executable to be called.
- # - An array containing a +command_line+ or an +exe_path+,
- # along with zero or more string arguments for the command.
- #
- # See {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
+ # Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|i, ts|
+ # i.puts "hello"
+ # }
#
def pipeline_w(*cmds, &block)
if Hash === cmds.last
@@ -1207,67 +573,49 @@ module Open3
end
module_function :pipeline_w
- # :call-seq:
- # Open3.pipeline_start([env, ] *cmds, options = {}) -> [wait_threads]
- #
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
- #
- # - Creates a child process for each of the given +cmds+
- # by calling Process.spawn.
- # - Does not wait for child processes to exit.
- #
- # With no block given, returns an array of the wait threads
- # for all of the child processes.
- #
- # Example:
- #
- # wait_threads = Open3.pipeline_start('ls', 'grep R')
- # # => [#<Process::Waiter:0x000055e8de9d2bb0 run>, #<Process::Waiter:0x000055e8de9d2890 run>]
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- #
- # Output:
- #
- # Rakefile
- # README.md
+ # Open3.pipeline_start starts a list of commands as a pipeline.
+ # No pipes are created for stdin of the first command and
+ # stdout of the last command.
#
- # With a block given, calls the block with an array of the wait processes:
+ # Open3.pipeline_start(cmd1, cmd2, ... [, opts]) {|wait_threads|
+ # ...
+ # }
#
- # Open3.pipeline_start('ls', 'grep R') do |wait_threads|
- # wait_threads.each do |wait_thread|
- # wait_thread.join
- # end
- # end
- #
- # Output:
- #
- # Rakefile
- # README.md
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
+ # wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts])
+ # ...
#
- # If the first argument is a hash, it becomes leading argument +env+
- # in each call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
+ # Each cmd is a string or an array.
+ # If it is an array, the elements are passed to Process.spawn.
#
- # If the last argument is a hash, it becomes trailing argument +options+
- # in each call to Process.spawn;
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ # cmd:
+ # commandline command line string which is passed to a shell
+ # [env, commandline, opts] command line string which is passed to a shell
+ # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
+ # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
#
- # Each remaining argument in +cmds+ is one of:
+ # Note that env and opts are optional, as for Process.spawn.
#
- # - A +command_line+: a string that begins with a shell reserved word
- # or special built-in, or contains one or more metacharacters.
- # - An +exe_path+: the string path to an executable to be called.
- # - An array containing a +command_line+ or an +exe_path+,
- # along with zero or more string arguments for the command.
+ # Example:
#
- # See {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
+ # # Run xeyes in 10 seconds.
+ # Open3.pipeline_start("xeyes") {|ts|
+ # sleep 10
+ # t = ts[0]
+ # Process.kill("TERM", t.pid)
+ # p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)>
+ # }
+ #
+ # # Convert pdf to ps and send it to a printer.
+ # # Collect error message of pdftops and lpr.
+ # pdf_file = "paper.pdf"
+ # printer = "printer-name"
+ # err_r, err_w = IO.pipe
+ # Open3.pipeline_start(["pdftops", pdf_file, "-"],
+ # ["lpr", "-P#{printer}"],
+ # :err=>err_w) {|ts|
+ # err_w.close
+ # p err_r.read # error messages of pdftops and lpr.
+ # }
#
def pipeline_start(*cmds, &block)
if Hash === cmds.last
@@ -1285,51 +633,57 @@ module Open3
end
module_function :pipeline_start
- # :call-seq:
- # Open3.pipeline([env, ] *cmds, options = {}) -> array_of_statuses
- #
- # Basically a wrapper for
- # {Process.spawn}[rdoc-ref:Process.spawn]
- # that:
+ # Open3.pipeline starts a list of commands as a pipeline.
+ # It waits for the completion of the commands.
+ # No pipes are created for stdin of the first command and
+ # stdout of the last command.
#
- # - Creates a child process for each of the given +cmds+
- # by calling Process.spawn.
- # - Pipes the +stdout+ from each child to the +stdin+ of the next child,
- # or, for the last child, to the caller's +stdout+.
- # - Waits for the child processes to exit.
- # - Returns an array of Process::Status objects (one for each child).
+ # status_list = Open3.pipeline(cmd1, cmd2, ... [, opts])
#
- # Example:
+ # Each cmd is a string or an array.
+ # If it is an array, the elements are passed to Process.spawn.
#
- # wait_threads = Open3.pipeline('ls', 'grep R')
- # # => [#<Process::Status: pid 2139200 exit 0>, #<Process::Status: pid 2139202 exit 0>]
+ # cmd:
+ # commandline command line string which is passed to a shell
+ # [env, commandline, opts] command line string which is passed to a shell
+ # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
+ # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
#
- # Output:
+ # Note that env and opts are optional, as Process.spawn.
#
- # Rakefile
- # README.md
- #
- # Like Process.spawn, this method has potential security vulnerabilities
- # if called with untrusted input;
- # see {Command Injection}[rdoc-ref:command_injection.rdoc@Command+Injection].
- #
- # If the first argument is a hash, it becomes leading argument +env+
- # in each call to Process.spawn;
- # see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- #
- # If the last argument is a hash, it becomes trailing argument +options+
- # in each call to Process.spawn'
- # see {Execution Options}[rdoc-ref:Process@Execution+Options].
- #
- # Each remaining argument in +cmds+ is one of:
- #
- # - A +command_line+: a string that begins with a shell reserved word
- # or special built-in, or contains one or more metacharacters.
- # - An +exe_path+: the string path to an executable to be called.
- # - An array containing a +command_line+ or an +exe_path+,
- # along with zero or more string arguments for the command.
+ # Example:
#
- # See {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
+ # fname = "/usr/share/man/man1/ruby.1.gz"
+ # p Open3.pipeline(["zcat", fname], "nroff -man", "less")
+ # #=> [#<Process::Status: pid 11817 exit 0>,
+ # # #<Process::Status: pid 11820 exit 0>,
+ # # #<Process::Status: pid 11828 exit 0>]
+ #
+ # fname = "/usr/share/man/man1/ls.1.gz"
+ # Open3.pipeline(["zcat", fname], "nroff -man", "colcrt")
+ #
+ # # convert PDF to PS and send to a printer by lpr
+ # pdf_file = "paper.pdf"
+ # printer = "printer-name"
+ # Open3.pipeline(["pdftops", pdf_file, "-"],
+ # ["lpr", "-P#{printer}"])
+ #
+ # # count lines
+ # Open3.pipeline("sort", "uniq -c", :in=>"names.txt", :out=>"count")
+ #
+ # # cyclic pipeline
+ # r,w = IO.pipe
+ # w.print "ibase=14\n10\n"
+ # Open3.pipeline("bc", "tee /dev/tty", :in=>r, :out=>w)
+ # #=> 14
+ # # 18
+ # # 22
+ # # 30
+ # # 42
+ # # 58
+ # # 78
+ # # 106
+ # # 202
#
def pipeline(*cmds)
if Hash === cmds.last
diff --git a/lib/open3/open3.gemspec b/lib/open3/open3.gemspec
index 21980decac..a33fca7444 100644
--- a/lib/open3/open3.gemspec
+++ b/lib/open3/open3.gemspec
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
diff --git a/lib/open3/version.rb b/lib/open3/version.rb
index bfcec44ccc..b6b6ee2c9c 100644
--- a/lib/open3/version.rb
+++ b/lib/open3/version.rb
@@ -1,3 +1,3 @@
module Open3
- VERSION = "0.2.1"
+ VERSION = "0.1.2"
end
diff --git a/lib/optparse.rb b/lib/optparse.rb
index 832b928a2d..53a4387bd8 100644
--- a/lib/optparse.rb
+++ b/lib/optparse.rb
@@ -48,7 +48,7 @@
#
# == OptionParser
#
-# === New to +OptionParser+?
+# === New to \OptionParser?
#
# See the {Tutorial}[optparse/tutorial.rdoc].
#
@@ -152,14 +152,14 @@
# OptionParser supports the ability to coerce command line arguments
# into objects for us.
#
-# OptionParser comes with a few ready-to-use kinds of type
+# OptionParser comes with a few ready-to-use kinds of type
# coercion. They are:
#
-# - Date -- Anything accepted by +Date.parse+ (need to require +optparse/date+)
-# - DateTime -- Anything accepted by +DateTime.parse+ (need to require +optparse/date+)
-# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+ (need to require +optparse/time+)
-# - URI -- Anything accepted by +URI.parse+ (need to require +optparse/uri+)
-# - Shellwords -- Anything accepted by +Shellwords.shellwords+ (need to require +optparse/shellwords+)
+# - Date -- Anything accepted by +Date.parse+
+# - DateTime -- Anything accepted by +DateTime.parse+
+# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+
+# - URI -- Anything accepted by +URI.parse+
+# - Shellwords -- Anything accepted by +Shellwords.shellwords+
# - String -- Any non-empty string
# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
# - Float -- Any float. (e.g. 10, 3.14, -100E+13)
@@ -425,7 +425,7 @@
# If you have any questions, file a ticket at http://bugs.ruby-lang.org.
#
class OptionParser
- OptionParser::Version = "0.4.0"
+ OptionParser::Version = "0.3.1"
# :stopdoc:
NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
@@ -1775,16 +1775,7 @@ XXX
# # params["bar"] = "x" # --bar x
# # params["zot"] = "z" # --zot Z
#
- # Option +symbolize_names+ (boolean) specifies whether returned Hash keys should be Symbols; defaults to +false+ (use Strings).
- #
- # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option", symbolize_names: true)
- # # params[:a] = true # -a
- # # params[:b] = "1" # -b1
- # # params[:foo] = "1" # --foo
- # # params[:bar] = "x" # --bar x
- # # params[:zot] = "z" # --zot Z
- #
- def getopts(*args, symbolize_names: false)
+ def getopts(*args)
argv = Array === args.first ? args.shift : default_argv
single_options, *long_options = *args
@@ -1813,14 +1804,14 @@ XXX
end
parse_in_order(argv, result.method(:[]=))
- symbolize_names ? result.transform_keys(&:to_sym) : result
+ result
end
#
# See #getopts.
#
- def self.getopts(*args, symbolize_names: false)
- new.getopts(*args, symbolize_names: symbolize_names)
+ def self.getopts(*args)
+ new.getopts(*args)
end
#
@@ -2298,8 +2289,8 @@ XXX
# rescue OptionParser::ParseError
# end
#
- def getopts(*args, symbolize_names: false)
- options.getopts(self, *args, symbolize_names: symbolize_names)
+ def getopts(*args)
+ options.getopts(self, *args)
end
#
diff --git a/lib/ostruct.gemspec b/lib/ostruct.gemspec
deleted file mode 100644
index 08a7aefb05..0000000000
--- a/lib/ostruct.gemspec
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Marc-Andre Lafortune"]
- spec.email = ["ruby-core@marc-andre.ca"]
-
- spec.summary = %q{Class to build custom data structures, similar to a Hash.}
- spec.description = %q{Class to build custom data structures, similar to a Hash.}
- spec.homepage = "https://github.com/ruby/ostruct"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.required_ruby_version = ">= 2.5.0"
-
- spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/ostruct.rb", "ostruct.gemspec"]
- spec.require_paths = ["lib"]
-end
diff --git a/lib/ostruct.rb b/lib/ostruct.rb
index fa882b7b9b..a08561d6c9 100644
--- a/lib/ostruct.rb
+++ b/lib/ostruct.rb
@@ -107,15 +107,7 @@
# For all these reasons, consider not using OpenStruct at all.
#
class OpenStruct
- VERSION = "0.6.0"
-
- HAS_PERFORMANCE_WARNINGS = begin
- Warning[:performance]
- true
- rescue NoMethodError, ArgumentError
- false
- end
- private_constant :HAS_PERFORMANCE_WARNINGS
+ VERSION = "0.5.5"
#
# Creates a new OpenStruct object. By default, the resulting OpenStruct
@@ -132,10 +124,6 @@ class OpenStruct
# data # => #<OpenStruct country="Australia", capital="Canberra">
#
def initialize(hash=nil)
- if HAS_PERFORMANCE_WARNINGS && Warning[:performance]
- warn "OpenStruct use is discouraged for performance reasons", uplevel: 1, category: :performance
- end
-
if hash
update_to_values!(hash)
else
diff --git a/lib/ostruct/ostruct.gemspec b/lib/ostruct/ostruct.gemspec
new file mode 100644
index 0000000000..31ecc312c3
--- /dev/null
+++ b/lib/ostruct/ostruct.gemspec
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Marc-Andre Lafortune"]
+ spec.email = ["ruby-core@marc-andre.ca"]
+
+ spec.summary = %q{Class to build custom data structures, similar to a Hash.}
+ spec.description = %q{Class to build custom data structures, similar to a Hash.}
+ spec.homepage = "https://github.com/ruby/ostruct"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.required_ruby_version = ">= 2.5.0"
+
+ spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "lib/ostruct.rb", "ostruct.gemspec"]
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency "bundler"
+ spec.add_development_dependency "rake"
+end
diff --git a/lib/pp.gemspec b/lib/pp.gemspec
index 27a92a8ce4..3f08f400c4 100644
--- a/lib/pp.gemspec
+++ b/lib/pp.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "pp"
+ spec.version = "0.4.0"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/lib/pp.rb b/lib/pp.rb
index 1708dee05e..81551aa116 100644
--- a/lib/pp.rb
+++ b/lib/pp.rb
@@ -46,7 +46,6 @@ require 'prettyprint'
#
# To define a customized pretty printing function for your classes,
# redefine method <code>#pretty_print(pp)</code> in the class.
-# Note that <code>require 'pp'</code> is needed before redefining <code>#pretty_print(pp)</code>.
#
# <code>#pretty_print</code> takes the +pp+ argument, which is an instance of the PP class.
# The method uses #text, #breakable, #nest, #group and #pp to print the
@@ -62,9 +61,6 @@ require 'prettyprint'
# Tanaka Akira <akr@fsij.org>
class PP < PrettyPrint
-
- VERSION = "0.5.0"
-
# Returns the usable width for +out+.
# As the width of +out+:
# 1. If +out+ is assigned to a tty device, its width is used.
@@ -633,6 +629,10 @@ end
module Kernel
# Returns a pretty printed object as a string.
#
+ # In order to use this method you must first require the PP module:
+ #
+ # require 'pp'
+ #
# See the PP module for more information.
def pretty_inspect
PP.pp(self, ''.dup)
diff --git a/lib/prettyprint.gemspec b/lib/prettyprint.gemspec
index a18adb174b..eae2227d60 100644
--- a/lib/prettyprint.gemspec
+++ b/lib/prettyprint.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "prettyprint"
+ spec.version = "0.1.1"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/lib/prettyprint.rb b/lib/prettyprint.rb
index 6f50192f5d..188c2e6db0 100644
--- a/lib/prettyprint.rb
+++ b/lib/prettyprint.rb
@@ -23,18 +23,16 @@
#
# == References
# Christian Lindig, Strictly Pretty, March 2000,
-# https://lindig.github.io/papers/strictly-pretty-2000.pdf
+# http://www.st.cs.uni-sb.de/~lindig/papers/#pretty
#
# Philip Wadler, A prettier printer, March 1998,
-# https://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier
+# http://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier
#
# == Author
# Tanaka Akira <akr@fsij.org>
#
class PrettyPrint
- VERSION = "0.2.0"
-
# This is a convenience method which is same as follows:
#
# begin
diff --git a/lib/prism.rb b/lib/prism.rb
deleted file mode 100644
index e44d163d02..0000000000
--- a/lib/prism.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-# The Prism Ruby parser.
-#
-# "Parsing Ruby is suddenly manageable!"
-# - You, hopefully
-#
-module Prism
- # There are many files in prism that are templated to handle every node type,
- # which means the files can end up being quite large. We autoload them to make
- # our require speed faster since consuming libraries are unlikely to use all
- # of these features.
-
- autoload :BasicVisitor, "prism/visitor"
- autoload :Compiler, "prism/compiler"
- autoload :Debug, "prism/debug"
- autoload :DesugarCompiler, "prism/desugar_compiler"
- autoload :Dispatcher, "prism/dispatcher"
- autoload :DotVisitor, "prism/dot_visitor"
- autoload :DSL, "prism/dsl"
- autoload :LexCompat, "prism/lex_compat"
- autoload :LexRipper, "prism/lex_compat"
- autoload :MutationCompiler, "prism/mutation_compiler"
- autoload :NodeInspector, "prism/node_inspector"
- autoload :RipperCompat, "prism/ripper_compat"
- autoload :Pack, "prism/pack"
- autoload :Pattern, "prism/pattern"
- autoload :Serialize, "prism/serialize"
- autoload :Visitor, "prism/visitor"
-
- # Some of these constants are not meant to be exposed, so marking them as
- # private here.
-
- private_constant :Debug
- private_constant :LexCompat
- private_constant :LexRipper
-
- # :call-seq:
- # Prism::lex_compat(source, **options) -> ParseResult
- #
- # Returns a parse result whose value is an array of tokens that closely
- # resembles the return value of Ripper::lex. The main difference is that the
- # `:on_sp` token is not emitted.
- #
- # For supported options, see Prism::parse.
- def self.lex_compat(source, **options)
- LexCompat.new(source, **options).result
- end
-
- # :call-seq:
- # Prism::lex_ripper(source) -> Array
- #
- # This lexes with the Ripper lex. It drops any space events but otherwise
- # returns the same tokens. Raises SyntaxError if the syntax in source is
- # invalid.
- def self.lex_ripper(source)
- LexRipper.new(source).result
- end
-
- # :call-seq:
- # Prism::load(source, serialized) -> ParseResult
- #
- # Load the serialized AST using the source as a reference into a tree.
- def self.load(source, serialized)
- Serialize.load(source, serialized)
- end
-
- # :call-seq:
- # Prism::parse_failure?(source, **options) -> bool
- #
- # Returns true if the source parses with errors.
- def self.parse_failure?(source, **options)
- !parse_success?(source, **options)
- end
-
- # :call-seq:
- # Prism::parse_file_failure?(filepath, **options) -> bool
- #
- # Returns true if the file at filepath parses with errors.
- def self.parse_file_failure?(filepath, **options)
- !parse_file_success?(filepath, **options)
- end
-end
-
-require_relative "prism/node"
-require_relative "prism/node_ext"
-require_relative "prism/parse_result"
-require_relative "prism/parse_result/comments"
-require_relative "prism/parse_result/newlines"
-
-# This is a Ruby implementation of the prism parser. If we're running on CRuby
-# and we haven't explicitly set the PRISM_FFI_BACKEND environment variable, then
-# it's going to require the built library. Otherwise, it's going to require a
-# module that uses FFI to call into the library.
-if RUBY_ENGINE == "ruby" and !ENV["PRISM_FFI_BACKEND"]
- require "prism/prism"
-else
- require_relative "prism/ffi"
-end
diff --git a/lib/prism/debug.rb b/lib/prism/debug.rb
deleted file mode 100644
index e275fe1dff..0000000000
--- a/lib/prism/debug.rb
+++ /dev/null
@@ -1,200 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- # This module is used for testing and debugging and is not meant to be used by
- # consumers of this library.
- module Debug
- # A wrapper around a RubyVM::InstructionSequence that provides a more
- # convenient interface for accessing parts of the iseq.
- class ISeq # :nodoc:
- attr_reader :parts
-
- def initialize(parts)
- @parts = parts
- end
-
- def type
- parts[0]
- end
-
- def local_table
- parts[10]
- end
-
- def instructions
- parts[13]
- end
-
- def each_child
- instructions.each do |instruction|
- # Only look at arrays. Other instructions are line numbers or
- # tracepoint events.
- next unless instruction.is_a?(Array)
-
- instruction.each do |opnd|
- # Only look at arrays. Other operands are literals.
- next unless opnd.is_a?(Array)
-
- # Only look at instruction sequences. Other operands are literals.
- next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat"
-
- yield ISeq.new(opnd)
- end
- end
- end
- end
-
- private_constant :ISeq
-
- # :call-seq:
- # Debug::cruby_locals(source) -> Array
- #
- # For the given source, compiles with CRuby and returns a list of all of the
- # sets of local variables that were encountered.
- def self.cruby_locals(source)
- verbose, $VERBOSE = $VERBOSE, nil
-
- begin
- locals = []
- stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
-
- while (iseq = stack.pop)
- names = [*iseq.local_table]
- names.map!.with_index do |name, index|
- # When an anonymous local variable is present in the iseq's local
- # table, it is represented as the stack offset from the top.
- # However, when these are dumped to binary and read back in, they
- # are replaced with the symbol :#arg_rest. To consistently handle
- # this, we replace them here with their index.
- if name == :"#arg_rest"
- names.length - index + 1
- else
- name
- end
- end
-
- locals << names
- iseq.each_child { |child| stack << child }
- end
-
- locals
- ensure
- $VERBOSE = verbose
- end
- end
-
- # Used to hold the place of a local that will be in the local table but
- # cannot be accessed directly from the source code. For example, the
- # iteration variable in a for loop or the positional parameter on a method
- # definition that is destructured.
- AnonymousLocal = Object.new
- private_constant :AnonymousLocal
-
- # :call-seq:
- # Debug::prism_locals(source) -> Array
- #
- # For the given source, parses with prism and returns a list of all of the
- # sets of local variables that were encountered.
- def self.prism_locals(source)
- locals = []
- stack = [Prism.parse(source).value]
-
- while (node = stack.pop)
- case node
- when BlockNode, DefNode, LambdaNode
- names = node.locals
- params =
- if node.is_a?(DefNode)
- node.parameters
- elsif node.parameters.is_a?(NumberedParametersNode)
- nil
- else
- node.parameters&.parameters
- end
-
- # prism places parameters in the same order that they appear in the
- # source. CRuby places them in the order that they need to appear
- # according to their own internal calling convention. We mimic that
- # order here so that we can compare properly.
- if params
- sorted = [
- *params.requireds.map do |required|
- if required.is_a?(RequiredParameterNode)
- required.name
- else
- AnonymousLocal
- end
- end,
- *params.optionals.map(&:name),
- *((params.rest.name || :*) if params.rest && !params.rest.is_a?(ImplicitRestNode)),
- *params.posts.map do |post|
- if post.is_a?(RequiredParameterNode)
- post.name
- else
- AnonymousLocal
- end
- end,
- *params.keywords.grep(RequiredKeywordParameterNode).map(&:name),
- *params.keywords.grep(OptionalKeywordParameterNode).map(&:name),
- ]
-
- if params.keyword_rest.is_a?(ForwardingParameterNode)
- sorted.push(:*, :&, :"...")
- end
-
- sorted << AnonymousLocal if params.keywords.any?
-
- # Recurse down the parameter tree to find any destructured
- # parameters and add them after the other parameters.
- param_stack = params.requireds.concat(params.posts).grep(MultiTargetNode).reverse
- while (param = param_stack.pop)
- case param
- when MultiTargetNode
- param_stack.concat(param.rights.reverse)
- param_stack << param.rest
- param_stack.concat(param.lefts.reverse)
- when RequiredParameterNode
- sorted << param.name
- when SplatNode
- sorted << param.expression.name if param.expression
- end
- end
-
- names = sorted.concat(names - sorted)
- end
-
- names.map!.with_index do |name, index|
- if name == AnonymousLocal
- names.length - index + 1
- else
- name
- end
- end
-
- locals << names
- when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
- locals << node.locals
- when ForNode
- locals << [2]
- when PostExecutionNode
- locals.push([], [])
- when InterpolatedRegularExpressionNode
- locals << [] if node.once?
- end
-
- stack.concat(node.compact_child_nodes)
- end
-
- locals
- end
-
- # :call-seq:
- # Debug::newlines(source) -> Array
- #
- # For the given source string, return the byte offsets of every newline in
- # the source.
- def self.newlines(source)
- Prism.parse(source).source.offsets
- end
- end
-end
diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb
deleted file mode 100644
index daca02f35e..0000000000
--- a/lib/prism/desugar_compiler.rb
+++ /dev/null
@@ -1,207 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- # DesugarCompiler is a compiler that desugars Ruby code into a more primitive
- # form. This is useful for consumers that want to deal with fewer node types.
- class DesugarCompiler < MutationCompiler
- # @@foo &&= bar
- #
- # becomes
- #
- # @@foo && @@foo = bar
- def visit_class_variable_and_write_node(node)
- desugar_and_write_node(node, ClassVariableReadNode, ClassVariableWriteNode, node.name)
- end
-
- # @@foo ||= bar
- #
- # becomes
- #
- # defined?(@@foo) ? @@foo : @@foo = bar
- def visit_class_variable_or_write_node(node)
- desugar_or_write_defined_node(node, ClassVariableReadNode, ClassVariableWriteNode, node.name)
- end
-
- # @@foo += bar
- #
- # becomes
- #
- # @@foo = @@foo + bar
- def visit_class_variable_operator_write_node(node)
- desugar_operator_write_node(node, ClassVariableReadNode, ClassVariableWriteNode, node.name)
- end
-
- # Foo &&= bar
- #
- # becomes
- #
- # Foo && Foo = bar
- def visit_constant_and_write_node(node)
- desugar_and_write_node(node, ConstantReadNode, ConstantWriteNode, node.name)
- end
-
- # Foo ||= bar
- #
- # becomes
- #
- # defined?(Foo) ? Foo : Foo = bar
- def visit_constant_or_write_node(node)
- desugar_or_write_defined_node(node, ConstantReadNode, ConstantWriteNode, node.name)
- end
-
- # Foo += bar
- #
- # becomes
- #
- # Foo = Foo + bar
- def visit_constant_operator_write_node(node)
- desugar_operator_write_node(node, ConstantReadNode, ConstantWriteNode, node.name)
- end
-
- # $foo &&= bar
- #
- # becomes
- #
- # $foo && $foo = bar
- def visit_global_variable_and_write_node(node)
- desugar_and_write_node(node, GlobalVariableReadNode, GlobalVariableWriteNode, node.name)
- end
-
- # $foo ||= bar
- #
- # becomes
- #
- # defined?($foo) ? $foo : $foo = bar
- def visit_global_variable_or_write_node(node)
- desugar_or_write_defined_node(node, GlobalVariableReadNode, GlobalVariableWriteNode, node.name)
- end
-
- # $foo += bar
- #
- # becomes
- #
- # $foo = $foo + bar
- def visit_global_variable_operator_write_node(node)
- desugar_operator_write_node(node, GlobalVariableReadNode, GlobalVariableWriteNode, node.name)
- end
-
- # @foo &&= bar
- #
- # becomes
- #
- # @foo && @foo = bar
- def visit_instance_variable_and_write_node(node)
- desugar_and_write_node(node, InstanceVariableReadNode, InstanceVariableWriteNode, node.name)
- end
-
- # @foo ||= bar
- #
- # becomes
- #
- # @foo || @foo = bar
- def visit_instance_variable_or_write_node(node)
- desugar_or_write_node(node, InstanceVariableReadNode, InstanceVariableWriteNode, node.name)
- end
-
- # @foo += bar
- #
- # becomes
- #
- # @foo = @foo + bar
- def visit_instance_variable_operator_write_node(node)
- desugar_operator_write_node(node, InstanceVariableReadNode, InstanceVariableWriteNode, node.name)
- end
-
- # foo &&= bar
- #
- # becomes
- #
- # foo && foo = bar
- def visit_local_variable_and_write_node(node)
- desugar_and_write_node(node, LocalVariableReadNode, LocalVariableWriteNode, node.name, node.depth)
- end
-
- # foo ||= bar
- #
- # becomes
- #
- # foo || foo = bar
- def visit_local_variable_or_write_node(node)
- desugar_or_write_node(node, LocalVariableReadNode, LocalVariableWriteNode, node.name, node.depth)
- end
-
- # foo += bar
- #
- # becomes
- #
- # foo = foo + bar
- def visit_local_variable_operator_write_node(node)
- desugar_operator_write_node(node, LocalVariableReadNode, LocalVariableWriteNode, node.name, node.depth)
- end
-
- private
-
- # Desugar `x &&= y` to `x && x = y`
- def desugar_and_write_node(node, read_class, write_class, *arguments)
- AndNode.new(
- read_class.new(*arguments, node.name_loc),
- write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location),
- node.operator_loc,
- node.location
- )
- end
-
- # Desugar `x += y` to `x = x + y`
- def desugar_operator_write_node(node, read_class, write_class, *arguments)
- write_class.new(
- *arguments,
- node.name_loc,
- CallNode.new(
- 0,
- read_class.new(*arguments, node.name_loc),
- nil,
- node.operator_loc.slice.chomp("="),
- node.operator_loc.copy(length: node.operator_loc.length - 1),
- nil,
- ArgumentsNode.new(0, [node.value], node.value.location),
- nil,
- nil,
- node.location
- ),
- node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
- node.location
- )
- end
-
- # Desugar `x ||= y` to `x || x = y`
- def desugar_or_write_node(node, read_class, write_class, *arguments)
- OrNode.new(
- read_class.new(*arguments, node.name_loc),
- write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location),
- node.operator_loc,
- node.location
- )
- end
-
- # Desugar `x ||= y` to `defined?(x) ? x : x = y`
- def desugar_or_write_defined_node(node, read_class, write_class, *arguments)
- IfNode.new(
- node.operator_loc,
- DefinedNode.new(nil, read_class.new(*arguments, node.name_loc), nil, node.operator_loc, node.name_loc),
- node.operator_loc,
- StatementsNode.new([read_class.new(*arguments, node.name_loc)], node.location),
- ElseNode.new(
- node.operator_loc,
- StatementsNode.new(
- [write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location)],
- node.location
- ),
- node.operator_loc,
- node.location
- ),
- node.operator_loc,
- node.location
- )
- end
- end
-end
diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb
deleted file mode 100644
index 8324f722a7..0000000000
--- a/lib/prism/ffi.rb
+++ /dev/null
@@ -1,341 +0,0 @@
-# frozen_string_literal: true
-
-# This file is responsible for mirroring the API provided by the C extension by
-# using FFI to call into the shared library.
-
-require "rbconfig"
-require "ffi"
-
-module Prism
- BACKEND = :FFI
-
- module LibRubyParser # :nodoc:
- extend FFI::Library
-
- # Define the library that we will be pulling functions from. Note that this
- # must align with the build shared library from make/rake.
- ffi_lib File.expand_path("../../build/libprism.#{RbConfig::CONFIG["SOEXT"]}", __dir__)
-
- # Convert a native C type declaration into a symbol that FFI understands.
- # For example:
- #
- # const char * -> :pointer
- # bool -> :bool
- # size_t -> :size_t
- # void -> :void
- #
- def self.resolve_type(type)
- type = type.strip
- type.end_with?("*") ? :pointer : type.delete_prefix("const ").to_sym
- end
-
- # Read through the given header file and find the declaration of each of the
- # given functions. For each one, define a function with the same name and
- # signature as the C function.
- def self.load_exported_functions_from(header, *functions)
- File.foreach(File.expand_path("../../include/#{header}", __dir__)) do |line|
- # We only want to attempt to load exported functions.
- next unless line.start_with?("PRISM_EXPORTED_FUNCTION ")
-
- # We only want to load the functions that we are interested in.
- next unless functions.any? { |function| line.include?(function) }
-
- # Parse the function declaration.
- unless /^PRISM_EXPORTED_FUNCTION (?<return_type>.+) (?<name>\w+)\((?<arg_types>.+)\);$/ =~ line
- raise "Could not parse #{line}"
- end
-
- # Delete the function from the list of functions we are looking for to
- # mark it as having been found.
- functions.delete(name)
-
- # Split up the argument types into an array, ensure we handle the case
- # where there are no arguments (by explicit void).
- arg_types = arg_types.split(",").map(&:strip)
- arg_types = [] if arg_types == %w[void]
-
- # Resolve the type of the argument by dropping the name of the argument
- # first if it is present.
- arg_types.map! { |type| resolve_type(type.sub(/\w+$/, "")) }
-
- # Attach the function using the FFI library.
- attach_function name, arg_types, resolve_type(return_type)
- end
-
- # If we didn't find all of the functions, raise an error.
- raise "Could not find functions #{functions.inspect}" unless functions.empty?
- end
-
- load_exported_functions_from(
- "prism.h",
- "pm_version",
- "pm_serialize_parse",
- "pm_serialize_parse_comments",
- "pm_serialize_lex",
- "pm_serialize_parse_lex",
- "pm_parse_success_p"
- )
-
- load_exported_functions_from(
- "prism/util/pm_buffer.h",
- "pm_buffer_sizeof",
- "pm_buffer_init",
- "pm_buffer_value",
- "pm_buffer_length",
- "pm_buffer_free"
- )
-
- load_exported_functions_from(
- "prism/util/pm_string.h",
- "pm_string_mapped_init",
- "pm_string_free",
- "pm_string_source",
- "pm_string_length",
- "pm_string_sizeof"
- )
-
- # This object represents a pm_buffer_t. We only use it as an opaque pointer,
- # so it doesn't need to know the fields of pm_buffer_t.
- class PrismBuffer # :nodoc:
- SIZEOF = LibRubyParser.pm_buffer_sizeof
-
- attr_reader :pointer
-
- def initialize(pointer)
- @pointer = pointer
- end
-
- def value
- LibRubyParser.pm_buffer_value(pointer)
- end
-
- def length
- LibRubyParser.pm_buffer_length(pointer)
- end
-
- def read
- value.read_string(length)
- end
-
- # Initialize a new buffer and yield it to the block. The buffer will be
- # automatically freed when the block returns.
- def self.with(&block)
- pointer = FFI::MemoryPointer.new(SIZEOF)
-
- begin
- raise unless LibRubyParser.pm_buffer_init(pointer)
- yield new(pointer)
- ensure
- LibRubyParser.pm_buffer_free(pointer)
- pointer.free
- end
- end
- end
-
- # This object represents a pm_string_t. We only use it as an opaque pointer,
- # so it doesn't have to be an FFI::Struct.
- class PrismString # :nodoc:
- SIZEOF = LibRubyParser.pm_string_sizeof
-
- attr_reader :pointer
-
- def initialize(pointer)
- @pointer = pointer
- end
-
- def source
- LibRubyParser.pm_string_source(pointer)
- end
-
- def length
- LibRubyParser.pm_string_length(pointer)
- end
-
- def read
- source.read_string(length)
- end
-
- # Yields a pm_string_t pointer to the given block.
- def self.with(filepath, &block)
- pointer = FFI::MemoryPointer.new(SIZEOF)
-
- begin
- raise unless LibRubyParser.pm_string_mapped_init(pointer, filepath)
- yield new(pointer)
- ensure
- LibRubyParser.pm_string_free(pointer)
- pointer.free
- end
- end
- end
- end
-
- # Mark the LibRubyParser module as private as it should only be called through
- # the prism module.
- private_constant :LibRubyParser
-
- # The version constant is set by reading the result of calling pm_version.
- VERSION = LibRubyParser.pm_version.read_string
-
- class << self
- # Mirror the Prism.dump API by using the serialization API.
- def dump(code, **options)
- LibRubyParser::PrismBuffer.with do |buffer|
- LibRubyParser.pm_serialize_parse(buffer.pointer, code, code.bytesize, dump_options(options))
- buffer.read
- end
- end
-
- # Mirror the Prism.dump_file API by using the serialization API.
- def dump_file(filepath, **options)
- LibRubyParser::PrismString.with(filepath) do |string|
- dump(string.read, **options, filepath: filepath)
- end
- end
-
- # Mirror the Prism.lex API by using the serialization API.
- def lex(code, **options)
- LibRubyParser::PrismBuffer.with do |buffer|
- LibRubyParser.pm_serialize_lex(buffer.pointer, code, code.bytesize, dump_options(options))
- Serialize.load_tokens(Source.new(code), buffer.read)
- end
- end
-
- # Mirror the Prism.lex_file API by using the serialization API.
- def lex_file(filepath, **options)
- LibRubyParser::PrismString.with(filepath) do |string|
- lex(string.read, **options, filepath: filepath)
- end
- end
-
- # Mirror the Prism.parse API by using the serialization API.
- def parse(code, **options)
- Prism.load(code, dump(code, **options))
- end
-
- # Mirror the Prism.parse_file API by using the serialization API. This uses
- # native strings instead of Ruby strings because it allows us to use mmap when
- # it is available.
- def parse_file(filepath, **options)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse(string.read, **options, filepath: filepath)
- end
- end
-
- # Mirror the Prism.parse_comments API by using the serialization API.
- def parse_comments(code, **options)
- LibRubyParser::PrismBuffer.with do |buffer|
- LibRubyParser.pm_serialize_parse_comments(buffer.pointer, code, code.bytesize, dump_options(options))
-
- source = Source.new(code)
- loader = Serialize::Loader.new(source, buffer.read)
-
- loader.load_header
- loader.load_encoding
- loader.load_start_line
- loader.load_comments
- end
- end
-
- # Mirror the Prism.parse_file_comments API by using the serialization
- # API. This uses native strings instead of Ruby strings because it allows us
- # to use mmap when it is available.
- def parse_file_comments(filepath, **options)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse_comments(string.read, **options, filepath: filepath)
- end
- end
-
- # Mirror the Prism.parse_lex API by using the serialization API.
- def parse_lex(code, **options)
- LibRubyParser::PrismBuffer.with do |buffer|
- LibRubyParser.pm_serialize_parse_lex(buffer.pointer, code, code.bytesize, dump_options(options))
-
- source = Source.new(code)
- loader = Serialize::Loader.new(source, buffer.read)
-
- tokens = loader.load_tokens
- node, comments, magic_comments, data_loc, errors, warnings = loader.load_nodes
- tokens.each { |token,| token.value.force_encoding(loader.encoding) }
-
- ParseResult.new([node, tokens], comments, magic_comments, data_loc, errors, warnings, source)
- end
- end
-
- # Mirror the Prism.parse_lex_file API by using the serialization API.
- def parse_lex_file(filepath, **options)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse_lex(string.read, **options, filepath: filepath)
- end
- end
-
- # Mirror the Prism.parse_success? API by using the serialization API.
- def parse_success?(code, **options)
- LibRubyParser.pm_parse_success_p(code, code.bytesize, dump_options(options))
- end
-
- # Mirror the Prism.parse_file_success? API by using the serialization API.
- def parse_file_success?(filepath, **options)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse_success?(string.read, **options, filepath: filepath)
- end
- end
-
- private
-
- # Convert the given options into a serialized options string.
- def dump_options(options)
- template = +""
- values = []
-
- template << "L"
- if (filepath = options[:filepath])
- values.push(filepath.bytesize, filepath.b)
- template << "A*"
- else
- values << 0
- end
-
- template << "L"
- values << options.fetch(:line, 1)
-
- template << "L"
- if (encoding = options[:encoding])
- name = encoding.name
- values.push(name.bytesize, name.b)
- template << "A*"
- else
- values << 0
- end
-
- template << "C"
- values << (options.fetch(:frozen_string_literal, false) ? 1 : 0)
-
- template << "C"
- values << (options.fetch(:verbose, true) ? 0 : 1)
-
- template << "L"
- if (scopes = options[:scopes])
- values << scopes.length
-
- scopes.each do |scope|
- template << "L"
- values << scope.length
-
- scope.each do |local|
- name = local.name
- template << "L"
- values << name.bytesize
-
- template << "A*"
- values << name.b
- end
- end
- else
- values << 0
- end
-
- values.pack(template)
- end
- end
-end
diff --git a/lib/prism/lex_compat.rb b/lib/prism/lex_compat.rb
deleted file mode 100644
index 2c23933714..0000000000
--- a/lib/prism/lex_compat.rb
+++ /dev/null
@@ -1,892 +0,0 @@
-# frozen_string_literal: true
-
-require "delegate"
-
-module Prism
- # This class is responsible for lexing the source using prism and then
- # converting those tokens to be compatible with Ripper. In the vast majority
- # of cases, this is a one-to-one mapping of the token type. Everything else
- # generally lines up. However, there are a few cases that require special
- # handling.
- class LexCompat # :nodoc:
- # This is a mapping of prism token types to Ripper token types. This is a
- # many-to-one mapping because we split up our token types, whereas Ripper
- # tends to group them.
- RIPPER = {
- AMPERSAND: :on_op,
- AMPERSAND_AMPERSAND: :on_op,
- AMPERSAND_AMPERSAND_EQUAL: :on_op,
- AMPERSAND_DOT: :on_op,
- AMPERSAND_EQUAL: :on_op,
- BACK_REFERENCE: :on_backref,
- BACKTICK: :on_backtick,
- BANG: :on_op,
- BANG_EQUAL: :on_op,
- BANG_TILDE: :on_op,
- BRACE_LEFT: :on_lbrace,
- BRACE_RIGHT: :on_rbrace,
- BRACKET_LEFT: :on_lbracket,
- BRACKET_LEFT_ARRAY: :on_lbracket,
- BRACKET_LEFT_RIGHT: :on_op,
- BRACKET_LEFT_RIGHT_EQUAL: :on_op,
- BRACKET_RIGHT: :on_rbracket,
- CARET: :on_op,
- CARET_EQUAL: :on_op,
- CHARACTER_LITERAL: :on_CHAR,
- CLASS_VARIABLE: :on_cvar,
- COLON: :on_op,
- COLON_COLON: :on_op,
- COMMA: :on_comma,
- COMMENT: :on_comment,
- CONSTANT: :on_const,
- DOT: :on_period,
- DOT_DOT: :on_op,
- DOT_DOT_DOT: :on_op,
- EMBDOC_BEGIN: :on_embdoc_beg,
- EMBDOC_END: :on_embdoc_end,
- EMBDOC_LINE: :on_embdoc,
- EMBEXPR_BEGIN: :on_embexpr_beg,
- EMBEXPR_END: :on_embexpr_end,
- EMBVAR: :on_embvar,
- EOF: :on_eof,
- EQUAL: :on_op,
- EQUAL_EQUAL: :on_op,
- EQUAL_EQUAL_EQUAL: :on_op,
- EQUAL_GREATER: :on_op,
- EQUAL_TILDE: :on_op,
- FLOAT: :on_float,
- FLOAT_IMAGINARY: :on_imaginary,
- FLOAT_RATIONAL: :on_rational,
- FLOAT_RATIONAL_IMAGINARY: :on_imaginary,
- GREATER: :on_op,
- GREATER_EQUAL: :on_op,
- GREATER_GREATER: :on_op,
- GREATER_GREATER_EQUAL: :on_op,
- GLOBAL_VARIABLE: :on_gvar,
- HEREDOC_END: :on_heredoc_end,
- HEREDOC_START: :on_heredoc_beg,
- IDENTIFIER: :on_ident,
- IGNORED_NEWLINE: :on_ignored_nl,
- INTEGER: :on_int,
- INTEGER_IMAGINARY: :on_imaginary,
- INTEGER_RATIONAL: :on_rational,
- INTEGER_RATIONAL_IMAGINARY: :on_imaginary,
- INSTANCE_VARIABLE: :on_ivar,
- INVALID: :INVALID,
- KEYWORD___ENCODING__: :on_kw,
- KEYWORD___LINE__: :on_kw,
- KEYWORD___FILE__: :on_kw,
- KEYWORD_ALIAS: :on_kw,
- KEYWORD_AND: :on_kw,
- KEYWORD_BEGIN: :on_kw,
- KEYWORD_BEGIN_UPCASE: :on_kw,
- KEYWORD_BREAK: :on_kw,
- KEYWORD_CASE: :on_kw,
- KEYWORD_CLASS: :on_kw,
- KEYWORD_DEF: :on_kw,
- KEYWORD_DEFINED: :on_kw,
- KEYWORD_DO: :on_kw,
- KEYWORD_DO_LOOP: :on_kw,
- KEYWORD_ELSE: :on_kw,
- KEYWORD_ELSIF: :on_kw,
- KEYWORD_END: :on_kw,
- KEYWORD_END_UPCASE: :on_kw,
- KEYWORD_ENSURE: :on_kw,
- KEYWORD_FALSE: :on_kw,
- KEYWORD_FOR: :on_kw,
- KEYWORD_IF: :on_kw,
- KEYWORD_IF_MODIFIER: :on_kw,
- KEYWORD_IN: :on_kw,
- KEYWORD_MODULE: :on_kw,
- KEYWORD_NEXT: :on_kw,
- KEYWORD_NIL: :on_kw,
- KEYWORD_NOT: :on_kw,
- KEYWORD_OR: :on_kw,
- KEYWORD_REDO: :on_kw,
- KEYWORD_RESCUE: :on_kw,
- KEYWORD_RESCUE_MODIFIER: :on_kw,
- KEYWORD_RETRY: :on_kw,
- KEYWORD_RETURN: :on_kw,
- KEYWORD_SELF: :on_kw,
- KEYWORD_SUPER: :on_kw,
- KEYWORD_THEN: :on_kw,
- KEYWORD_TRUE: :on_kw,
- KEYWORD_UNDEF: :on_kw,
- KEYWORD_UNLESS: :on_kw,
- KEYWORD_UNLESS_MODIFIER: :on_kw,
- KEYWORD_UNTIL: :on_kw,
- KEYWORD_UNTIL_MODIFIER: :on_kw,
- KEYWORD_WHEN: :on_kw,
- KEYWORD_WHILE: :on_kw,
- KEYWORD_WHILE_MODIFIER: :on_kw,
- KEYWORD_YIELD: :on_kw,
- LABEL: :on_label,
- LABEL_END: :on_label_end,
- LAMBDA_BEGIN: :on_tlambeg,
- LESS: :on_op,
- LESS_EQUAL: :on_op,
- LESS_EQUAL_GREATER: :on_op,
- LESS_LESS: :on_op,
- LESS_LESS_EQUAL: :on_op,
- METHOD_NAME: :on_ident,
- MINUS: :on_op,
- MINUS_EQUAL: :on_op,
- MINUS_GREATER: :on_tlambda,
- NEWLINE: :on_nl,
- NUMBERED_REFERENCE: :on_backref,
- PARENTHESIS_LEFT: :on_lparen,
- PARENTHESIS_LEFT_PARENTHESES: :on_lparen,
- PARENTHESIS_RIGHT: :on_rparen,
- PERCENT: :on_op,
- PERCENT_EQUAL: :on_op,
- PERCENT_LOWER_I: :on_qsymbols_beg,
- PERCENT_LOWER_W: :on_qwords_beg,
- PERCENT_LOWER_X: :on_backtick,
- PERCENT_UPPER_I: :on_symbols_beg,
- PERCENT_UPPER_W: :on_words_beg,
- PIPE: :on_op,
- PIPE_EQUAL: :on_op,
- PIPE_PIPE: :on_op,
- PIPE_PIPE_EQUAL: :on_op,
- PLUS: :on_op,
- PLUS_EQUAL: :on_op,
- QUESTION_MARK: :on_op,
- RATIONAL_FLOAT: :on_rational,
- RATIONAL_INTEGER: :on_rational,
- REGEXP_BEGIN: :on_regexp_beg,
- REGEXP_END: :on_regexp_end,
- SEMICOLON: :on_semicolon,
- SLASH: :on_op,
- SLASH_EQUAL: :on_op,
- STAR: :on_op,
- STAR_EQUAL: :on_op,
- STAR_STAR: :on_op,
- STAR_STAR_EQUAL: :on_op,
- STRING_BEGIN: :on_tstring_beg,
- STRING_CONTENT: :on_tstring_content,
- STRING_END: :on_tstring_end,
- SYMBOL_BEGIN: :on_symbeg,
- TILDE: :on_op,
- UAMPERSAND: :on_op,
- UCOLON_COLON: :on_op,
- UDOT_DOT: :on_op,
- UDOT_DOT_DOT: :on_op,
- UMINUS: :on_op,
- UMINUS_NUM: :on_op,
- UPLUS: :on_op,
- USTAR: :on_op,
- USTAR_STAR: :on_op,
- WORDS_SEP: :on_words_sep,
- "__END__": :on___end__
- }.freeze
-
- # When we produce tokens, we produce the same arrays that Ripper does.
- # However, we add a couple of convenience methods onto them to make them a
- # little easier to work with. We delegate all other methods to the array.
- class Token < SimpleDelegator
- # The location of the token in the source.
- def location
- self[0]
- end
-
- # The type of the token.
- def event
- self[1]
- end
-
- # The slice of the source that this token represents.
- def value
- self[2]
- end
-
- # The state of the lexer when this token was produced.
- def state
- self[3]
- end
- end
-
- # Ripper doesn't include the rest of the token in the event, so we need to
- # trim it down to just the content on the first line when comparing.
- class EndContentToken < Token
- def ==(other) # :nodoc:
- [self[0], self[1], self[2][0..self[2].index("\n")], self[3]] == other
- end
- end
-
- # Tokens where state should be ignored
- # used for :on_comment, :on_heredoc_end, :on_embexpr_end
- class IgnoreStateToken < Token
- def ==(other) # :nodoc:
- self[0...-1] == other[0...-1]
- end
- end
-
- # Ident tokens for the most part are exactly the same, except sometimes we
- # know an ident is a local when ripper doesn't (when they are introduced
- # through named captures in regular expressions). In that case we don't
- # compare the state.
- class IdentToken < Token
- def ==(other) # :nodoc:
- (self[0...-1] == other[0...-1]) && (
- (other[3] == Ripper::EXPR_LABEL | Ripper::EXPR_END) ||
- (other[3] & Ripper::EXPR_ARG_ANY != 0)
- )
- end
- end
-
- # Ignored newlines can occasionally have a LABEL state attached to them, so
- # we compare the state differently here.
- class IgnoredNewlineToken < Token
- def ==(other) # :nodoc:
- return false unless self[0...-1] == other[0...-1]
-
- if self[4] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED
- other[4] & Ripper::EXPR_ARG | Ripper::EXPR_LABELED > 0
- else
- self[4] == other[4]
- end
- end
- end
-
- # If we have an identifier that follows a method name like:
- #
- # def foo bar
- #
- # then Ripper will mark bar as END|LABEL if there is a local in a parent
- # scope named bar because it hasn't pushed the local table yet. We do this
- # more accurately, so we need to allow comparing against both END and
- # END|LABEL.
- class ParamToken < Token
- def ==(other) # :nodoc:
- (self[0...-1] == other[0...-1]) && (
- (other[3] == Ripper::EXPR_END) ||
- (other[3] == Ripper::EXPR_END | Ripper::EXPR_LABEL)
- )
- end
- end
-
- # A heredoc in this case is a list of tokens that belong to the body of the
- # heredoc that should be appended onto the list of tokens when the heredoc
- # closes.
- module Heredoc # :nodoc:
- # Heredocs that are no dash or tilde heredocs are just a list of tokens.
- # We need to keep them around so that we can insert them in the correct
- # order back into the token stream and set the state of the last token to
- # the state that the heredoc was opened in.
- class PlainHeredoc # :nodoc:
- attr_reader :tokens
-
- def initialize
- @tokens = []
- end
-
- def <<(token)
- tokens << token
- end
-
- def to_a
- tokens
- end
- end
-
- # Dash heredocs are a little more complicated. They are a list of tokens
- # that need to be split on "\\\n" to mimic Ripper's behavior. We also need
- # to keep track of the state that the heredoc was opened in.
- class DashHeredoc # :nodoc:
- attr_reader :split, :tokens
-
- def initialize(split)
- @split = split
- @tokens = []
- end
-
- def <<(token)
- tokens << token
- end
-
- def to_a
- embexpr_balance = 0
-
- tokens.each_with_object([]) do |token, results|
- case token.event
- when :on_embexpr_beg
- embexpr_balance += 1
- results << token
- when :on_embexpr_end
- embexpr_balance -= 1
- results << token
- when :on_tstring_content
- if embexpr_balance == 0
- lineno = token[0][0]
- column = token[0][1]
-
- if split
- # Split on "\\\n" to mimic Ripper's behavior. Use a lookbehind
- # to keep the delimiter in the result.
- token.value.split(/(?<=[^\\]\\\n)|(?<=[^\\]\\\r\n)/).each_with_index do |value, index|
- column = 0 if index > 0
- results << Token.new([[lineno, column], :on_tstring_content, value, token.state])
- lineno += value.count("\n")
- end
- else
- results << token
- end
- else
- results << token
- end
- else
- results << token
- end
- end
- end
- end
-
- # Heredocs that are dedenting heredocs are a little more complicated.
- # Ripper outputs on_ignored_sp tokens for the whitespace that is being
- # removed from the output. prism only modifies the node itself and keeps
- # the token the same. This simplifies prism, but makes comparing against
- # Ripper much harder because there is a length mismatch.
- #
- # Fortunately, we already have to pull out the heredoc tokens in order to
- # insert them into the stream in the correct order. As such, we can do
- # some extra manipulation on the tokens to make them match Ripper's
- # output by mirroring the dedent logic that Ripper uses.
- class DedentingHeredoc # :nodoc:
- TAB_WIDTH = 8
-
- attr_reader :tokens, :dedent_next, :dedent, :embexpr_balance
-
- def initialize
- @tokens = []
- @dedent_next = true
- @dedent = nil
- @embexpr_balance = 0
- @ended_on_newline = false
- end
-
- # As tokens are coming in, we track the minimum amount of common leading
- # whitespace on plain string content tokens. This allows us to later
- # remove that amount of whitespace from the beginning of each line.
- def <<(token)
- case token.event
- when :on_embexpr_beg, :on_heredoc_beg
- @embexpr_balance += 1
- @dedent = 0 if @dedent_next && @ended_on_newline
- when :on_embexpr_end, :on_heredoc_end
- @embexpr_balance -= 1
- when :on_tstring_content
- if embexpr_balance == 0
- line = token.value
-
- if dedent_next && !(line.strip.empty? && line.end_with?("\n"))
- leading = line[/\A(\s*)\n?/, 1]
- next_dedent = 0
-
- leading.each_char do |char|
- if char == "\t"
- next_dedent = next_dedent - (next_dedent % TAB_WIDTH) + TAB_WIDTH
- else
- next_dedent += 1
- end
- end
-
- @dedent = [dedent, next_dedent].compact.min
- @dedent_next = true
- @ended_on_newline = line.end_with?("\n")
- tokens << token
- return
- end
- end
- end
-
- @dedent_next = token.event == :on_tstring_content && embexpr_balance == 0
- @ended_on_newline = false
- tokens << token
- end
-
- def to_a
- # If every line in the heredoc is blank, we still need to split up the
- # string content token into multiple tokens.
- if dedent.nil?
- results = []
- embexpr_balance = 0
-
- tokens.each do |token|
- case token.event
- when :on_embexpr_beg, :on_heredoc_beg
- embexpr_balance += 1
- results << token
- when :on_embexpr_end, :on_heredoc_end
- embexpr_balance -= 1
- results << token
- when :on_tstring_content
- if embexpr_balance == 0
- lineno = token[0][0]
- column = token[0][1]
-
- token.value.split(/(?<=\n)/).each_with_index do |value, index|
- column = 0 if index > 0
- results << Token.new([[lineno, column], :on_tstring_content, value, token.state])
- lineno += 1
- end
- else
- results << token
- end
- else
- results << token
- end
- end
-
- return results
- end
-
- # If the minimum common whitespace is 0, then we need to concatenate
- # string nodes together that are immediately adjacent.
- if dedent == 0
- results = []
- embexpr_balance = 0
-
- index = 0
- max_index = tokens.length
-
- while index < max_index
- token = tokens[index]
- results << token
- index += 1
-
- case token.event
- when :on_embexpr_beg, :on_heredoc_beg
- embexpr_balance += 1
- when :on_embexpr_end, :on_heredoc_end
- embexpr_balance -= 1
- when :on_tstring_content
- if embexpr_balance == 0
- while index < max_index && tokens[index].event == :on_tstring_content
- token.value << tokens[index].value
- index += 1
- end
- end
- end
- end
-
- return results
- end
-
- # Otherwise, we're going to run through each token in the list and
- # insert on_ignored_sp tokens for the amount of dedent that we need to
- # perform. We also need to remove the dedent from the beginning of
- # each line of plain string content tokens.
- results = []
- dedent_next = true
- embexpr_balance = 0
-
- tokens.each do |token|
- # Notice that the structure of this conditional largely matches the
- # whitespace calculation we performed above. This is because
- # checking if the subsequent token needs to be dedented is common to
- # both the dedent calculation and the ignored_sp insertion.
- case token.event
- when :on_embexpr_beg
- embexpr_balance += 1
- results << token
- when :on_embexpr_end
- embexpr_balance -= 1
- results << token
- when :on_tstring_content
- if embexpr_balance == 0
- # Here we're going to split the string on newlines, but maintain
- # the newlines in the resulting array. We'll do that with a look
- # behind assertion.
- splits = token.value.split(/(?<=\n)/)
- index = 0
-
- while index < splits.length
- line = splits[index]
- lineno = token[0][0] + index
- column = token[0][1]
-
- # Blank lines do not count toward common leading whitespace
- # calculation and do not need to be dedented.
- if dedent_next || index > 0
- column = 0
- end
-
- # If the dedent is 0 and we're not supposed to dedent the next
- # line or this line doesn't start with whitespace, then we
- # should concatenate the rest of the string to match ripper.
- if dedent == 0 && (!dedent_next || !line.start_with?(/\s/))
- line = splits[index..].join
- index = splits.length
- end
-
- # If we are supposed to dedent this line or if this is not the
- # first line of the string and this line isn't entirely blank,
- # then we need to insert an on_ignored_sp token and remove the
- # dedent from the beginning of the line.
- if (dedent > 0) && (dedent_next || index > 0)
- deleting = 0
- deleted_chars = []
-
- # Gather up all of the characters that we're going to
- # delete, stopping when you hit a character that would put
- # you over the dedent amount.
- line.each_char.with_index do |char, i|
- case char
- when "\r"
- if line[i + 1] == "\n"
- break
- end
- when "\n"
- break
- when "\t"
- deleting = deleting - (deleting % TAB_WIDTH) + TAB_WIDTH
- else
- deleting += 1
- end
-
- break if deleting > dedent
- deleted_chars << char
- end
-
- # If we have something to delete, then delete it from the
- # string and insert an on_ignored_sp token.
- if deleted_chars.any?
- ignored = deleted_chars.join
- line.delete_prefix!(ignored)
-
- results << Token.new([[lineno, 0], :on_ignored_sp, ignored, token[3]])
- column = ignored.length
- end
- end
-
- results << Token.new([[lineno, column], token[1], line, token[3]]) unless line.empty?
- index += 1
- end
- else
- results << token
- end
- else
- results << token
- end
-
- dedent_next =
- ((token.event == :on_tstring_content) || (token.event == :on_heredoc_end)) &&
- embexpr_balance == 0
- end
-
- results
- end
- end
-
- # Here we will split between the two types of heredocs and return the
- # object that will store their tokens.
- def self.build(opening)
- case opening.value[2]
- when "~"
- DedentingHeredoc.new
- when "-"
- DashHeredoc.new(opening.value[3] != "'")
- else
- PlainHeredoc.new
- end
- end
- end
-
- private_constant :Heredoc
-
- attr_reader :source, :options
-
- def initialize(source, **options)
- @source = source
- @options = options
- end
-
- def result
- tokens = []
-
- state = :default
- heredoc_stack = [[]]
-
- result = Prism.lex(source, **options)
- result_value = result.value
- previous_state = nil
- last_heredoc_end = nil
-
- # In previous versions of Ruby, Ripper wouldn't flush the bom before the
- # first token, so we had to have a hack in place to account for that. This
- # checks for that behavior.
- bom_flushed = Ripper.lex("\xEF\xBB\xBF# test")[0][0][1] == 0
- bom = source.byteslice(0..2) == "\xEF\xBB\xBF"
-
- result_value.each_with_index do |(token, lex_state), index|
- lineno = token.location.start_line
- column = token.location.start_column
-
- # If there's a UTF-8 byte-order mark as the start of the file, then for
- # certain tokens ripper sets the first token back by 3 bytes. It also
- # keeps the byte order mark in the first token's value. This is weird,
- # and I don't want to mirror that in our parser. So instead, we'll match
- # up the columns and values here.
- if bom && lineno == 1
- column -= 3
-
- if index == 0 && column == 0 && !bom_flushed
- flushed =
- case token.type
- when :BACK_REFERENCE, :INSTANCE_VARIABLE, :CLASS_VARIABLE,
- :GLOBAL_VARIABLE, :NUMBERED_REFERENCE, :PERCENT_LOWER_I,
- :PERCENT_LOWER_X, :PERCENT_LOWER_W, :PERCENT_UPPER_I,
- :PERCENT_UPPER_W, :STRING_BEGIN
- true
- when :REGEXP_BEGIN, :SYMBOL_BEGIN
- token.value.start_with?("%")
- else
- false
- end
-
- unless flushed
- column -= 3
- value = token.value
- value.prepend(String.new("\xEF\xBB\xBF", encoding: value.encoding))
- end
- end
- end
-
- event = RIPPER.fetch(token.type)
- value = token.value
- lex_state = Ripper::Lexer::State.new(lex_state)
-
- token =
- case event
- when :on___end__
- EndContentToken.new([[lineno, column], event, value, lex_state])
- when :on_comment
- IgnoreStateToken.new([[lineno, column], event, value, lex_state])
- when :on_heredoc_end
- # Heredoc end tokens can be emitted in an odd order, so we don't
- # want to bother comparing the state on them.
- last_heredoc_end = token.location.end_offset
- IgnoreStateToken.new([[lineno, column], event, value, lex_state])
- when :on_ident
- if lex_state == Ripper::EXPR_END
- # If we have an identifier that follows a method name like:
- #
- # def foo bar
- #
- # then Ripper will mark bar as END|LABEL if there is a local in a
- # parent scope named bar because it hasn't pushed the local table
- # yet. We do this more accurately, so we need to allow comparing
- # against both END and END|LABEL.
- ParamToken.new([[lineno, column], event, value, lex_state])
- elsif lex_state == Ripper::EXPR_END | Ripper::EXPR_LABEL
- # In the event that we're comparing identifiers, we're going to
- # allow a little divergence. Ripper doesn't account for local
- # variables introduced through named captures in regexes, and we
- # do, which accounts for this difference.
- IdentToken.new([[lineno, column], event, value, lex_state])
- else
- Token.new([[lineno, column], event, value, lex_state])
- end
- when :on_embexpr_end
- IgnoreStateToken.new([[lineno, column], event, value, lex_state])
- when :on_ignored_nl
- # Ignored newlines can occasionally have a LABEL state attached to
- # them which doesn't actually impact anything. We don't mirror that
- # state so we ignored it.
- IgnoredNewlineToken.new([[lineno, column], event, value, lex_state])
- when :on_regexp_end
- # On regex end, Ripper scans and then sets end state, so the ripper
- # lexed output is begin, when it should be end. prism sets lex state
- # correctly to end state, but we want to be able to compare against
- # Ripper's lexed state. So here, if it's a regexp end token, we
- # output the state as the previous state, solely for the sake of
- # comparison.
- previous_token = result_value[index - 1][0]
- lex_state =
- if RIPPER.fetch(previous_token.type) == :on_embexpr_end
- # If the previous token is embexpr_end, then we have to do even
- # more processing. The end of an embedded expression sets the
- # state to the state that it had at the beginning of the
- # embedded expression. So we have to go and find that state and
- # set it here.
- counter = 1
- current_index = index - 1
-
- until counter == 0
- current_index -= 1
- current_event = RIPPER.fetch(result_value[current_index][0].type)
- counter += { on_embexpr_beg: -1, on_embexpr_end: 1 }[current_event] || 0
- end
-
- Ripper::Lexer::State.new(result_value[current_index][1])
- else
- previous_state
- end
-
- Token.new([[lineno, column], event, value, lex_state])
- when :on_eof
- previous_token = result_value[index - 1][0]
-
- # If we're at the end of the file and the previous token was a
- # comment and there is still whitespace after the comment, then
- # Ripper will append a on_nl token (even though there isn't
- # necessarily a newline). We mirror that here.
- if previous_token.type == :COMMENT
- # If the comment is at the start of a heredoc: <<HEREDOC # comment
- # then the comment's end_offset is up near the heredoc_beg.
- # This is not the correct offset to use for figuring out if
- # there is trailing whitespace after the last token.
- # Use the greater offset of the two to determine the start of
- # the trailing whitespace.
- start_offset = [previous_token.location.end_offset, last_heredoc_end].compact.max
- end_offset = token.location.start_offset
-
- if start_offset < end_offset
- if bom
- start_offset += 3
- end_offset += 3
- end
-
- tokens << Token.new([[lineno, 0], :on_nl, source.byteslice(start_offset...end_offset), lex_state])
- end
- end
-
- Token.new([[lineno, column], event, value, lex_state])
- else
- Token.new([[lineno, column], event, value, lex_state])
- end
-
- previous_state = lex_state
-
- # The order in which tokens appear in our lexer is different from the
- # order that they appear in Ripper. When we hit the declaration of a
- # heredoc in prism, we skip forward and lex the rest of the content of
- # the heredoc before going back and lexing at the end of the heredoc
- # identifier.
- #
- # To match up to ripper, we keep a small state variable around here to
- # track whether we're in the middle of a heredoc or not. In this way we
- # can shuffle around the token to match Ripper's output.
- case state
- when :default
- # The default state is when there are no heredocs at all. In this
- # state we can append the token to the list of tokens and move on.
- tokens << token
-
- # If we get the declaration of a heredoc, then we open a new heredoc
- # and move into the heredoc_opened state.
- if event == :on_heredoc_beg
- state = :heredoc_opened
- heredoc_stack.last << Heredoc.build(token)
- end
- when :heredoc_opened
- # The heredoc_opened state is when we've seen the declaration of a
- # heredoc and are now lexing the body of the heredoc. In this state we
- # push tokens onto the most recently created heredoc.
- heredoc_stack.last.last << token
-
- case event
- when :on_heredoc_beg
- # If we receive a heredoc declaration while lexing the body of a
- # heredoc, this means we have nested heredocs. In this case we'll
- # push a new heredoc onto the stack and stay in the heredoc_opened
- # state since we're now lexing the body of the new heredoc.
- heredoc_stack << [Heredoc.build(token)]
- when :on_heredoc_end
- # If we receive the end of a heredoc, then we're done lexing the
- # body of the heredoc. In this case we now have a completed heredoc
- # but need to wait for the next newline to push it into the token
- # stream.
- state = :heredoc_closed
- end
- when :heredoc_closed
- if %i[on_nl on_ignored_nl on_comment].include?(event) || (event == :on_tstring_content && value.end_with?("\n"))
- if heredoc_stack.size > 1
- flushing = heredoc_stack.pop
- heredoc_stack.last.last << token
-
- flushing.each do |heredoc|
- heredoc.to_a.each do |flushed_token|
- heredoc_stack.last.last << flushed_token
- end
- end
-
- state = :heredoc_opened
- next
- end
- elsif event == :on_heredoc_beg
- tokens << token
- state = :heredoc_opened
- heredoc_stack.last << Heredoc.build(token)
- next
- elsif heredoc_stack.size > 1
- heredoc_stack[-2].last << token
- next
- end
-
- heredoc_stack.last.each do |heredoc|
- tokens.concat(heredoc.to_a)
- end
-
- heredoc_stack.last.clear
- state = :default
-
- tokens << token
- end
- end
-
- # Drop the EOF token from the list
- tokens = tokens[0...-1]
-
- # We sort by location to compare against Ripper's output
- tokens.sort_by!(&:location)
-
- ParseResult.new(tokens, result.comments, result.magic_comments, result.data_loc, result.errors, result.warnings, [])
- end
- end
-
- private_constant :LexCompat
-
- # This is a class that wraps the Ripper lexer to produce almost exactly the
- # same tokens.
- class LexRipper # :nodoc:
- attr_reader :source
-
- def initialize(source)
- @source = source
- end
-
- def result
- previous = []
- results = []
-
- Ripper.lex(source, raise_errors: true).each do |token|
- case token[1]
- when :on_sp
- # skip
- when :on_tstring_content
- if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
- previous[2] << token[2]
- else
- results << token
- previous = token
- end
- when :on_words_sep
- if previous[1] == :on_words_sep
- previous[2] << token[2]
- else
- results << token
- previous = token
- end
- else
- results << token
- previous = token
- end
- end
-
- results
- end
- end
-
- private_constant :LexRipper
-end
diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb
deleted file mode 100644
index 8c09632345..0000000000
--- a/lib/prism/node_ext.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-# frozen_string_literal: true
-
-# Here we are reopening the prism module to provide methods on nodes that aren't
-# templated and are meant as convenience methods.
-module Prism
- module RegularExpressionOptions # :nodoc:
- # Returns a numeric value that represents the flags that were used to create
- # the regular expression.
- def options
- o = flags & (RegularExpressionFlags::IGNORE_CASE | RegularExpressionFlags::EXTENDED | RegularExpressionFlags::MULTI_LINE)
- o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8)
- o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
- o
- end
- end
-
- class InterpolatedMatchLastLineNode < Node
- include RegularExpressionOptions
- end
-
- class InterpolatedRegularExpressionNode < Node
- include RegularExpressionOptions
- end
-
- class MatchLastLineNode < Node
- include RegularExpressionOptions
- end
-
- class RegularExpressionNode < Node
- include RegularExpressionOptions
- end
-
- private_constant :RegularExpressionOptions
-
- module HeredocQuery # :nodoc:
- # Returns true if this node was represented as a heredoc in the source code.
- def heredoc?
- opening&.start_with?("<<")
- end
- end
-
- class InterpolatedStringNode < Node
- include HeredocQuery
- end
-
- class InterpolatedXStringNode < Node
- include HeredocQuery
- end
-
- class StringNode < Node
- include HeredocQuery
- end
-
- class XStringNode < Node
- include HeredocQuery
- end
-
- private_constant :HeredocQuery
-
- class FloatNode < Node
- # Returns the value of the node as a Ruby Float.
- def value
- Float(slice)
- end
- end
-
- class ImaginaryNode < Node
- # Returns the value of the node as a Ruby Complex.
- def value
- Complex(0, numeric.value)
- end
- end
-
- class IntegerNode < Node
- # Returns the value of the node as a Ruby Integer.
- def value
- Integer(slice)
- end
- end
-
- class RationalNode < Node
- # Returns the value of the node as a Ruby Rational.
- def value
- Rational(slice.chomp("r"))
- end
- end
-
- class ConstantReadNode < Node
- # Returns the list of parts for the full name of this constant.
- # For example: [:Foo]
- def full_name_parts
- [name]
- end
-
- # Returns the full name of this constant. For example: "Foo"
- def full_name
- name.name
- end
- end
-
- class ConstantPathNode < Node
- # An error class raised when dynamic parts are found while computing a
- # constant path's full name. For example:
- # Foo::Bar::Baz -> does not raise because all parts of the constant path are
- # simple constants
- # var::Bar::Baz -> raises because the first part of the constant path is a
- # local variable
- class DynamicPartsInConstantPathError < StandardError; end
-
- # Returns the list of parts for the full name of this constant path.
- # For example: [:Foo, :Bar]
- def full_name_parts
- parts = [child.name]
- current = parent
-
- while current.is_a?(ConstantPathNode)
- parts.unshift(current.child.name)
- current = current.parent
- end
-
- unless current.is_a?(ConstantReadNode)
- raise DynamicPartsInConstantPathError, "Constant path contains dynamic parts. Cannot compute full name"
- end
-
- parts.unshift(current&.name || :"")
- end
-
- # Returns the full name of this constant path. For example: "Foo::Bar"
- def full_name
- full_name_parts.join("::")
- end
- end
-
- class ConstantPathTargetNode < Node
- # Returns the list of parts for the full name of this constant path.
- # For example: [:Foo, :Bar]
- def full_name_parts
- (parent&.full_name_parts || [:""]).push(child.name)
- end
-
- # Returns the full name of this constant path. For example: "Foo::Bar"
- def full_name
- full_name_parts.join("::")
- end
- end
-
- class ParametersNode < Node
- # Mirrors the Method#parameters method.
- def signature
- names = []
-
- requireds.each do |param|
- names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name])
- end
-
- optionals.each { |param| names << [:opt, param.name] }
- names << [:rest, rest.name || :*] if rest
-
- posts.each do |param|
- names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name])
- end
-
- # Regardless of the order in which the keywords were defined, the required
- # keywords always come first followed by the optional keywords.
- keyopt = []
- keywords.each do |param|
- if param.is_a?(OptionalKeywordParameterNode)
- keyopt << param
- else
- names << [:keyreq, param.name]
- end
- end
-
- keyopt.each { |param| names << [:key, param.name] }
-
- case keyword_rest
- when ForwardingParameterNode
- names.concat([[:rest, :*], [:keyrest, :**], [:block, :&]])
- when KeywordRestParameterNode
- names << [:keyrest, keyword_rest.name || :**]
- when NoKeywordsParameterNode
- names << [:nokey]
- end
-
- names << [:block, block.name || :&] if block
- names
- end
- end
-end
diff --git a/lib/prism/node_inspector.rb b/lib/prism/node_inspector.rb
deleted file mode 100644
index d77af33c3a..0000000000
--- a/lib/prism/node_inspector.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- # This object is responsible for generating the output for the inspect method
- # implementations of child nodes.
- class NodeInspector # :nodoc:
- attr_reader :prefix, :output
-
- def initialize(prefix = "")
- @prefix = prefix
- @output = +""
- end
-
- # Appends a line to the output with the current prefix.
- def <<(line)
- output << "#{prefix}#{line}"
- end
-
- # This generates a string that is used as the header of the inspect output
- # for any given node.
- def header(node)
- output = +"@ #{node.class.name.split("::").last} ("
- output << "location: (#{node.location.start_line},#{node.location.start_column})-(#{node.location.end_line},#{node.location.end_column})"
- output << ", newline: true" if node.newline?
- output << ")\n"
- output
- end
-
- # Generates a string that represents a list of nodes. It handles properly
- # using the box drawing characters to make the output look nice.
- def list(prefix, nodes)
- output = +"(length: #{nodes.length})\n"
- last_index = nodes.length - 1
-
- nodes.each_with_index do |node, index|
- pointer, preadd = (index == last_index) ? ["└── ", " "] : ["├── ", "│ "]
- node_prefix = "#{prefix}#{preadd}"
- output << node.inspect(NodeInspector.new(node_prefix)).sub(node_prefix, "#{prefix}#{pointer}")
- end
-
- output
- end
-
- # Generates a string that represents a location field on a node.
- def location(value)
- if value
- "(#{value.start_line},#{value.start_column})-(#{value.end_line},#{value.end_column}) = #{value.slice.inspect}"
- else
- "∅"
- end
- end
-
- # Generates a string that represents a child node.
- def child_node(node, append)
- node.inspect(child_inspector(append)).delete_prefix(prefix)
- end
-
- # Returns a new inspector that can be used to inspect a child node.
- def child_inspector(append)
- NodeInspector.new("#{prefix}#{append}")
- end
-
- # Returns the output as a string.
- def to_str
- output
- end
- end
-end
diff --git a/lib/prism/pack.rb b/lib/prism/pack.rb
deleted file mode 100644
index 00caf553c6..0000000000
--- a/lib/prism/pack.rb
+++ /dev/null
@@ -1,224 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- # A parser for the pack template language.
- module Pack
- %i[
- SPACE
- COMMENT
- INTEGER
- UTF8
- BER
- FLOAT
- STRING_SPACE_PADDED
- STRING_NULL_PADDED
- STRING_NULL_TERMINATED
- STRING_MSB
- STRING_LSB
- STRING_HEX_HIGH
- STRING_HEX_LOW
- STRING_UU
- STRING_MIME
- STRING_BASE64
- STRING_FIXED
- STRING_POINTER
- MOVE
- BACK
- NULL
-
- UNSIGNED
- SIGNED
- SIGNED_NA
-
- AGNOSTIC_ENDIAN
- LITTLE_ENDIAN
- BIG_ENDIAN
- NATIVE_ENDIAN
- ENDIAN_NA
-
- SIZE_SHORT
- SIZE_INT
- SIZE_LONG
- SIZE_LONG_LONG
- SIZE_8
- SIZE_16
- SIZE_32
- SIZE_64
- SIZE_P
- SIZE_NA
-
- LENGTH_FIXED
- LENGTH_MAX
- LENGTH_RELATIVE
- LENGTH_NA
- ].each do |const|
- const_set(const, const)
- end
-
- # A directive in the pack template language.
- class Directive
- # A symbol representing the version of Ruby.
- attr_reader :version
-
- # A symbol representing whether or not we are packing or unpacking.
- attr_reader :variant
-
- # A byteslice of the source string that this directive represents.
- attr_reader :source
-
- # The type of the directive.
- attr_reader :type
-
- # The type of signedness of the directive.
- attr_reader :signed
-
- # The type of endianness of the directive.
- attr_reader :endian
-
- # The size of the directive.
- attr_reader :size
-
- # The length type of this directive (used for integers).
- attr_reader :length_type
-
- # The length of this directive (used for integers).
- attr_reader :length
-
- # Initialize a new directive with the given values.
- def initialize(version, variant, source, type, signed, endian, size, length_type, length)
- @version = version
- @variant = variant
- @source = source
- @type = type
- @signed = signed
- @endian = endian
- @size = size
- @length_type = length_type
- @length = length
- end
-
- # The descriptions of the various types of endianness.
- ENDIAN_DESCRIPTIONS = {
- AGNOSTIC_ENDIAN: "agnostic",
- LITTLE_ENDIAN: "little-endian (VAX)",
- BIG_ENDIAN: "big-endian (network)",
- NATIVE_ENDIAN: "native-endian",
- ENDIAN_NA: "n/a"
- }
-
- # The descriptions of the various types of signedness.
- SIGNED_DESCRIPTIONS = {
- UNSIGNED: "unsigned",
- SIGNED: "signed",
- SIGNED_NA: "n/a"
- }
-
- # The descriptions of the various types of sizes.
- SIZE_DESCRIPTIONS = {
- SIZE_SHORT: "short",
- SIZE_INT: "int-width",
- SIZE_LONG: "long",
- SIZE_LONG_LONG: "long long",
- SIZE_8: "8-bit",
- SIZE_16: "16-bit",
- SIZE_32: "32-bit",
- SIZE_64: "64-bit",
- SIZE_P: "pointer-width"
- }
-
- # Provide a human-readable description of the directive.
- def describe
- case type
- when SPACE
- "whitespace"
- when COMMENT
- "comment"
- when INTEGER
- if size == SIZE_8
- base = "#{SIGNED_DESCRIPTIONS[signed]} #{SIZE_DESCRIPTIONS[size]} integer"
- else
- base = "#{SIGNED_DESCRIPTIONS[signed]} #{SIZE_DESCRIPTIONS[size]} #{ENDIAN_DESCRIPTIONS[endian]} integer"
- end
- case length_type
- when LENGTH_FIXED
- if length > 1
- base + ", x#{length}"
- else
- base
- end
- when LENGTH_MAX
- base + ", as many as possible"
- end
- when UTF8
- "UTF-8 character"
- when BER
- "BER-compressed integer"
- when FLOAT
- "#{SIZE_DESCRIPTIONS[size]} #{ENDIAN_DESCRIPTIONS[endian]} float"
- when STRING_SPACE_PADDED
- "arbitrary binary string (space padded)"
- when STRING_NULL_PADDED
- "arbitrary binary string (null padded, count is width)"
- when STRING_NULL_TERMINATED
- "arbitrary binary string (null padded, count is width), except that null is added with *"
- when STRING_MSB
- "bit string (MSB first)"
- when STRING_LSB
- "bit string (LSB first)"
- when STRING_HEX_HIGH
- "hex string (high nibble first)"
- when STRING_HEX_LOW
- "hex string (low nibble first)"
- when STRING_UU
- "UU-encoded string"
- when STRING_MIME
- "quoted printable, MIME encoding"
- when STRING_BASE64
- "base64 encoded string"
- when STRING_FIXED
- "pointer to a structure (fixed-length string)"
- when STRING_POINTER
- "pointer to a null-terminated string"
- when MOVE
- "move to absolute position"
- when BACK
- "back up a byte"
- when NULL
- "null byte"
- else
- raise
- end
- end
- end
-
- # The result of parsing a pack template.
- class Format
- # A list of the directives in the template.
- attr_reader :directives
-
- # The encoding of the template.
- attr_reader :encoding
-
- # Create a new Format with the given directives and encoding.
- def initialize(directives, encoding)
- @directives = directives
- @encoding = encoding
- end
-
- # Provide a human-readable description of the format.
- def describe
- source_width = directives.map { |d| d.source.inspect.length }.max
- directive_lines = directives.map do |directive|
- if directive.type == SPACE
- source = directive.source.inspect
- else
- source = directive.source
- end
- " #{source.ljust(source_width)} #{directive.describe}"
- end
-
- (["Directives:"] + directive_lines + ["Encoding:", " #{encoding}"]).join("\n")
- end
- end
- end
-end
diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb
deleted file mode 100644
index 753d72f10b..0000000000
--- a/lib/prism/parse_result.rb
+++ /dev/null
@@ -1,460 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- # This represents a source of Ruby code that has been parsed. It is used in
- # conjunction with locations to allow them to resolve line numbers and source
- # ranges.
- class Source
- # The source code that this source object represents.
- attr_reader :source
-
- # The line number where this source starts.
- attr_accessor :start_line
-
- # The list of newline byte offsets in the source code.
- attr_reader :offsets
-
- # Create a new source object with the given source code and newline byte
- # offsets. If no newline byte offsets are given, they will be computed from
- # the source code.
- def initialize(source, start_line = 1, offsets = compute_offsets(source))
- @source = source
- @start_line = start_line
- @offsets = offsets
- end
-
- # Perform a byteslice on the source code using the given byte offset and
- # byte length.
- def slice(byte_offset, length)
- source.byteslice(byte_offset, length)
- end
-
- # Binary search through the offsets to find the line number for the given
- # byte offset.
- def line(byte_offset)
- start_line + find_line(byte_offset)
- end
-
- # Return the byte offset of the start of the line corresponding to the given
- # byte offset.
- def line_start(byte_offset)
- offsets[find_line(byte_offset)]
- end
-
- # Return the column number for the given byte offset.
- def column(byte_offset)
- byte_offset - line_start(byte_offset)
- end
-
- # Return the character offset for the given byte offset.
- def character_offset(byte_offset)
- source.byteslice(0, byte_offset).length
- end
-
- # Return the column number in characters for the given byte offset.
- def character_column(byte_offset)
- character_offset(byte_offset) - character_offset(line_start(byte_offset))
- end
-
- private
-
- # Binary search through the offsets to find the line number for the given
- # byte offset.
- def find_line(byte_offset)
- left = 0
- right = offsets.length - 1
-
- while left <= right
- mid = left + (right - left) / 2
- return mid if offsets[mid] == byte_offset
-
- if offsets[mid] < byte_offset
- left = mid + 1
- else
- right = mid - 1
- end
- end
-
- left - 1
- end
-
- # Find all of the newlines in the source code and return their byte offsets
- # from the start of the string an array.
- def compute_offsets(code)
- offsets = [0]
- code.b.scan("\n") { offsets << $~.end(0) }
- offsets
- end
- end
-
- # This represents a location in the source.
- class Location
- # A Source object that is used to determine more information from the given
- # offset and length.
- protected attr_reader :source
-
- # The byte offset from the beginning of the source where this location
- # starts.
- attr_reader :start_offset
-
- # The length of this location in bytes.
- attr_reader :length
-
- # The list of comments attached to this location
- attr_reader :comments
-
- # Create a new location object with the given source, start byte offset, and
- # byte length.
- def initialize(source, start_offset, length)
- @source = source
- @start_offset = start_offset
- @length = length
- @comments = []
- end
-
- # Create a new location object with the given options.
- def copy(**options)
- Location.new(
- options.fetch(:source) { source },
- options.fetch(:start_offset) { start_offset },
- options.fetch(:length) { length }
- )
- end
-
- # Returns a string representation of this location.
- def inspect
- "#<Prism::Location @start_offset=#{@start_offset} @length=#{@length} start_line=#{start_line}>"
- end
-
- # The source code that this location represents.
- def slice
- source.slice(start_offset, length)
- end
-
- # The character offset from the beginning of the source where this location
- # starts.
- def start_character_offset
- source.character_offset(start_offset)
- end
-
- # The byte offset from the beginning of the source where this location ends.
- def end_offset
- start_offset + length
- end
-
- # The character offset from the beginning of the source where this location
- # ends.
- def end_character_offset
- source.character_offset(end_offset)
- end
-
- # The line number where this location starts.
- def start_line
- source.line(start_offset)
- end
-
- # The content of the line where this location starts before this location.
- def start_line_slice
- offset = source.line_start(start_offset)
- source.slice(offset, start_offset - offset)
- end
-
- # The line number where this location ends.
- def end_line
- source.line(end_offset)
- end
-
- # The column number in bytes where this location starts from the start of
- # the line.
- def start_column
- source.column(start_offset)
- end
-
- # The column number in characters where this location ends from the start of
- # the line.
- def start_character_column
- source.character_column(start_offset)
- end
-
- # The column number in bytes where this location ends from the start of the
- # line.
- def end_column
- source.column(end_offset)
- end
-
- # The column number in characters where this location ends from the start of
- # the line.
- def end_character_column
- source.character_column(end_offset)
- end
-
- # Implement the hash pattern matching interface for Location.
- def deconstruct_keys(keys)
- { start_offset: start_offset, end_offset: end_offset }
- end
-
- # Implement the pretty print interface for Location.
- def pretty_print(q)
- q.text("(#{start_line},#{start_column})-(#{end_line},#{end_column})")
- end
-
- # Returns true if the given other location is equal to this location.
- def ==(other)
- other.is_a?(Location) &&
- other.start_offset == start_offset &&
- other.end_offset == end_offset
- end
-
- # Returns a new location that stretches from this location to the given
- # other location. Raises an error if this location is not before the other
- # location or if they don't share the same source.
- def join(other)
- raise "Incompatible sources" if source != other.source
- raise "Incompatible locations" if start_offset > other.start_offset
-
- Location.new(source, start_offset, other.end_offset - start_offset)
- end
-
- # Returns a null location that does not correspond to a source and points to
- # the beginning of the file. Useful for when you want a location object but
- # do not care where it points.
- def self.null
- new(nil, 0, 0)
- end
- end
-
- # This represents a comment that was encountered during parsing. It is the
- # base class for all comment types.
- class Comment
- # The location of this comment in the source.
- attr_reader :location
-
- # Create a new comment object with the given location.
- def initialize(location)
- @location = location
- end
-
- # Implement the hash pattern matching interface for Comment.
- def deconstruct_keys(keys)
- { location: location }
- end
- end
-
- # InlineComment objects are the most common. They correspond to comments in
- # the source file like this one that start with #.
- class InlineComment < Comment
- # Returns true if this comment happens on the same line as other code and
- # false if the comment is by itself.
- def trailing?
- !location.start_line_slice.strip.empty?
- end
-
- # Returns a string representation of this comment.
- def inspect
- "#<Prism::InlineComment @location=#{location.inspect}>"
- end
- end
-
- # EmbDocComment objects correspond to comments that are surrounded by =begin
- # and =end.
- class EmbDocComment < Comment
- # This can only be true for inline comments.
- def trailing?
- false
- end
-
- # Returns a string representation of this comment.
- def inspect
- "#<Prism::EmbDocComment @location=#{location.inspect}>"
- end
- end
-
- # This represents a magic comment that was encountered during parsing.
- class MagicComment
- # A Location object representing the location of the key in the source.
- attr_reader :key_loc
-
- # A Location object representing the location of the value in the source.
- attr_reader :value_loc
-
- # Create a new magic comment object with the given key and value locations.
- def initialize(key_loc, value_loc)
- @key_loc = key_loc
- @value_loc = value_loc
- end
-
- # Returns the key of the magic comment by slicing it from the source code.
- def key
- key_loc.slice
- end
-
- # Returns the value of the magic comment by slicing it from the source code.
- def value
- value_loc.slice
- end
-
- # Implement the hash pattern matching interface for MagicComment.
- def deconstruct_keys(keys)
- { key_loc: key_loc, value_loc: value_loc }
- end
-
- # Returns a string representation of this magic comment.
- def inspect
- "#<Prism::MagicComment @key=#{key.inspect} @value=#{value.inspect}>"
- end
- end
-
- # This represents an error that was encountered during parsing.
- class ParseError
- # The message associated with this error.
- attr_reader :message
-
- # A Location object representing the location of this error in the source.
- attr_reader :location
-
- # Create a new error object with the given message and location.
- def initialize(message, location)
- @message = message
- @location = location
- end
-
- # Implement the hash pattern matching interface for ParseError.
- def deconstruct_keys(keys)
- { message: message, location: location }
- end
-
- # Returns a string representation of this error.
- def inspect
- "#<Prism::ParseError @message=#{@message.inspect} @location=#{@location.inspect}>"
- end
- end
-
- # This represents a warning that was encountered during parsing.
- class ParseWarning
- # The message associated with this warning.
- attr_reader :message
-
- # A Location object representing the location of this warning in the source.
- attr_reader :location
-
- # Create a new warning object with the given message and location.
- def initialize(message, location)
- @message = message
- @location = location
- end
-
- # Implement the hash pattern matching interface for ParseWarning.
- def deconstruct_keys(keys)
- { message: message, location: location }
- end
-
- # Returns a string representation of this warning.
- def inspect
- "#<Prism::ParseWarning @message=#{@message.inspect} @location=#{@location.inspect}>"
- end
- end
-
- # This represents the result of a call to ::parse or ::parse_file. It contains
- # the AST, any comments that were encounters, and any errors that were
- # encountered.
- class ParseResult
- # The value that was generated by parsing. Normally this holds the AST, but
- # it can sometimes how a list of tokens or other results passed back from
- # the parser.
- attr_reader :value
-
- # The list of comments that were encountered during parsing.
- attr_reader :comments
-
- # The list of magic comments that were encountered during parsing.
- attr_reader :magic_comments
-
- # An optional location that represents the location of the content after the
- # __END__ marker. This content is loaded into the DATA constant when the
- # file being parsed is the main file being executed.
- attr_reader :data_loc
-
- # The list of errors that were generated during parsing.
- attr_reader :errors
-
- # The list of warnings that were generated during parsing.
- attr_reader :warnings
-
- # A Source instance that represents the source code that was parsed.
- attr_reader :source
-
- # Create a new parse result object with the given values.
- def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
- @value = value
- @comments = comments
- @magic_comments = magic_comments
- @data_loc = data_loc
- @errors = errors
- @warnings = warnings
- @source = source
- end
-
- # Implement the hash pattern matching interface for ParseResult.
- def deconstruct_keys(keys)
- { value: value, comments: comments, magic_comments: magic_comments, data_loc: data_loc, errors: errors, warnings: warnings }
- end
-
- # Returns true if there were no errors during parsing and false if there
- # were.
- def success?
- errors.empty?
- end
-
- # Returns true if there were errors during parsing and false if there were
- # not.
- def failure?
- !success?
- end
- end
-
- # This represents a token from the Ruby source.
- class Token
- # The type of token that this token is.
- attr_reader :type
-
- # A byteslice of the source that this token represents.
- attr_reader :value
-
- # A Location object representing the location of this token in the source.
- attr_reader :location
-
- # Create a new token object with the given type, value, and location.
- def initialize(type, value, location)
- @type = type
- @value = value
- @location = location
- end
-
- # Implement the hash pattern matching interface for Token.
- def deconstruct_keys(keys)
- { type: type, value: value, location: location }
- end
-
- # Implement the pretty print interface for Token.
- def pretty_print(q)
- q.group do
- q.text(type.to_s)
- self.location.pretty_print(q)
- q.text("(")
- q.nest(2) do
- q.breakable("")
- q.pp(value)
- end
- q.breakable("")
- q.text(")")
- end
- end
-
- # Returns true if the given other token is equal to this token.
- def ==(other)
- other.is_a?(Token) &&
- other.type == type &&
- other.value == value
- end
- end
-end
diff --git a/lib/prism/parse_result/comments.rb b/lib/prism/parse_result/comments.rb
deleted file mode 100644
index 7a3a47de50..0000000000
--- a/lib/prism/parse_result/comments.rb
+++ /dev/null
@@ -1,177 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- class ParseResult
- # When we've parsed the source, we have both the syntax tree and the list of
- # comments that we found in the source. This class is responsible for
- # walking the tree and finding the nearest location to attach each comment.
- #
- # It does this by first finding the nearest locations to each comment.
- # Locations can either come from nodes directly or from location fields on
- # nodes. For example, a `ClassNode` has an overall location encompassing the
- # entire class, but it also has a location for the `class` keyword.
- #
- # Once the nearest locations are found, it determines which one to attach
- # to. If it's a trailing comment (a comment on the same line as other source
- # code), it will favor attaching to the nearest location that occurs before
- # the comment. Otherwise it will favor attaching to the nearest location
- # that is after the comment.
- class Comments
- # A target for attaching comments that is based on a specific node's
- # location.
- class NodeTarget # :nodoc:
- attr_reader :node
-
- def initialize(node)
- @node = node
- end
-
- def start_offset
- node.location.start_offset
- end
-
- def end_offset
- node.location.end_offset
- end
-
- def encloses?(comment)
- start_offset <= comment.location.start_offset &&
- comment.location.end_offset <= end_offset
- end
-
- def <<(comment)
- node.location.comments << comment
- end
- end
-
- # A target for attaching comments that is based on a location field on a
- # node. For example, the `end` token of a ClassNode.
- class LocationTarget # :nodoc:
- attr_reader :location
-
- def initialize(location)
- @location = location
- end
-
- def start_offset
- location.start_offset
- end
-
- def end_offset
- location.end_offset
- end
-
- def encloses?(comment)
- false
- end
-
- def <<(comment)
- location.comments << comment
- end
- end
-
- # The parse result that we are attaching comments to.
- attr_reader :parse_result
-
- # Create a new Comments object that will attach comments to the given
- # parse result.
- def initialize(parse_result)
- @parse_result = parse_result
- end
-
- # Attach the comments to their respective locations in the tree by
- # mutating the parse result.
- def attach!
- parse_result.comments.each do |comment|
- preceding, enclosing, following = nearest_targets(parse_result.value, comment)
- target =
- if comment.trailing?
- preceding || following || enclosing || NodeTarget.new(parse_result.value)
- else
- # If a comment exists on its own line, prefer a leading comment.
- following || preceding || enclosing || NodeTarget.new(parse_result.value)
- end
-
- target << comment
- end
- end
-
- private
-
- # Responsible for finding the nearest targets to the given comment within
- # the context of the given encapsulating node.
- def nearest_targets(node, comment)
- comment_start = comment.location.start_offset
- comment_end = comment.location.end_offset
-
- targets = []
- node.comment_targets.map do |value|
- case value
- when StatementsNode
- targets.concat(value.body.map { |node| NodeTarget.new(node) })
- when Node
- targets << NodeTarget.new(value)
- when Location
- targets << LocationTarget.new(value)
- end
- end
-
- targets.sort_by!(&:start_offset)
- preceding = nil
- following = nil
-
- left = 0
- right = targets.length
-
- # This is a custom binary search that finds the nearest nodes to the
- # given comment. When it finds a node that completely encapsulates the
- # comment, it recurses downward into the tree.
- while left < right
- middle = (left + right) / 2
- target = targets[middle]
-
- target_start = target.start_offset
- target_end = target.end_offset
-
- if target.encloses?(comment)
- # The comment is completely contained by this target. Abandon the
- # binary search at this level.
- return nearest_targets(target.node, comment)
- end
-
- if target_end <= comment_start
- # This target falls completely before the comment. Because we will
- # never consider this target or any targets before it again, this
- # target must be the closest preceding target we have encountered so
- # far.
- preceding = target
- left = middle + 1
- next
- end
-
- if comment_end <= target_start
- # This target falls completely after the comment. Because we will
- # never consider this target or any targets after it again, this
- # target must be the closest following target we have encountered so
- # far.
- following = target
- right = middle
- next
- end
-
- # This should only happen if there is a bug in this parser.
- raise "Comment location overlaps with a target location"
- end
-
- [preceding, NodeTarget.new(node), following]
- end
- end
-
- private_constant :Comments
-
- # Attach the list of comments to their respective locations in the tree.
- def attach_comments!
- Comments.new(self).attach!
- end
- end
-end
diff --git a/lib/prism/parse_result/newlines.rb b/lib/prism/parse_result/newlines.rb
deleted file mode 100644
index ca05f5b702..0000000000
--- a/lib/prism/parse_result/newlines.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- class ParseResult
- # The :line tracepoint event gets fired whenever the Ruby VM encounters an
- # expression on a new line. The types of expressions that can trigger this
- # event are:
- #
- # * if statements
- # * unless statements
- # * nodes that are children of statements lists
- #
- # In order to keep track of the newlines, we have a list of offsets that
- # come back from the parser. We assign these offsets to the first nodes that
- # we find in the tree that are on those lines.
- #
- # Note that the logic in this file should be kept in sync with the Java
- # MarkNewlinesVisitor, since that visitor is responsible for marking the
- # newlines for JRuby/TruffleRuby.
- class Newlines < Visitor
- # Create a new Newlines visitor with the given newline offsets.
- def initialize(newline_marked)
- @newline_marked = newline_marked
- end
-
- # Permit block/lambda nodes to mark newlines within themselves.
- def visit_block_node(node)
- old_newline_marked = @newline_marked
- @newline_marked = Array.new(old_newline_marked.size, false)
-
- begin
- super(node)
- ensure
- @newline_marked = old_newline_marked
- end
- end
-
- alias_method :visit_lambda_node, :visit_block_node
-
- # Mark if/unless nodes as newlines.
- def visit_if_node(node)
- node.set_newline_flag(@newline_marked)
- super(node)
- end
-
- alias_method :visit_unless_node, :visit_if_node
-
- # Permit statements lists to mark newlines within themselves.
- def visit_statements_node(node)
- node.body.each do |child|
- child.set_newline_flag(@newline_marked)
- end
- super(node)
- end
- end
-
- private_constant :Newlines
-
- # Walk the tree and mark nodes that are on a new line.
- def mark_newlines!
- value.accept(Newlines.new(Array.new(1 + source.offsets.size, false)))
- end
- end
-end
diff --git a/lib/prism/pattern.rb b/lib/prism/pattern.rb
deleted file mode 100644
index e1643671ec..0000000000
--- a/lib/prism/pattern.rb
+++ /dev/null
@@ -1,250 +0,0 @@
-# frozen_string_literal: true
-
-module Prism
- # A pattern is an object that wraps a Ruby pattern matching expression. The
- # expression would normally be passed to an `in` clause within a `case`
- # expression or a rightward assignment expression. For example, in the
- # following snippet:
- #
- # case node
- # in ConstantPathNode[ConstantReadNode[name: :Prism], ConstantReadNode[name: :Pattern]]
- # end
- #
- # the pattern is the <tt>ConstantPathNode[...]</tt> expression.
- #
- # The pattern gets compiled into an object that responds to #call by running
- # the #compile method. This method itself will run back through Prism to
- # parse the expression into a tree, then walk the tree to generate the
- # necessary callable objects. For example, if you wanted to compile the
- # expression above into a callable, you would:
- #
- # callable = Prism::Pattern.new("ConstantPathNode[ConstantReadNode[name: :Prism], ConstantReadNode[name: :Pattern]]").compile
- # callable.call(node)
- #
- # The callable object returned by #compile is guaranteed to respond to #call
- # with a single argument, which is the node to match against. It also is
- # guaranteed to respond to #===, which means it itself can be used in a `case`
- # expression, as in:
- #
- # case node
- # when callable
- # end
- #
- # If the query given to the initializer cannot be compiled into a valid
- # matcher (either because of a syntax error or because it is using syntax we
- # do not yet support) then a Prism::Pattern::CompilationError will be
- # raised.
- class Pattern
- # Raised when the query given to a pattern is either invalid Ruby syntax or
- # is using syntax that we don't yet support.
- class CompilationError < StandardError
- # Create a new CompilationError with the given representation of the node
- # that caused the error.
- def initialize(repr)
- super(<<~ERROR)
- prism was unable to compile the pattern you provided into a usable
- expression. It failed on to understand the node represented by:
-
- #{repr}
-
- Note that not all syntax supported by Ruby's pattern matching syntax
- is also supported by prism's patterns. If you're using some syntax
- that you believe should be supported, please open an issue on
- GitHub at https://github.com/ruby/prism/issues/new.
- ERROR
- end
- end
-
- # The query that this pattern was initialized with.
- attr_reader :query
-
- # Create a new pattern with the given query. The query should be a string
- # containing a Ruby pattern matching expression.
- def initialize(query)
- @query = query
- @compiled = nil
- end
-
- # Compile the query into a callable object that can be used to match against
- # nodes.
- def compile
- result = Prism.parse("case nil\nin #{query}\nend")
- compile_node(result.value.statements.body.last.conditions.last.pattern)
- end
-
- # Scan the given node and all of its children for nodes that match the
- # pattern. If a block is given, it will be called with each node that
- # matches the pattern. If no block is given, an enumerator will be returned
- # that will yield each node that matches the pattern.
- def scan(root)
- return to_enum(__method__, root) unless block_given?
-
- @compiled ||= compile
- queue = [root]
-
- while (node = queue.shift)
- yield node if @compiled.call(node)
- queue.concat(node.compact_child_nodes)
- end
- end
-
- private
-
- # Shortcut for combining two procs into one that returns true if both return
- # true.
- def combine_and(left, right)
- ->(other) { left.call(other) && right.call(other) }
- end
-
- # Shortcut for combining two procs into one that returns true if either
- # returns true.
- def combine_or(left, right)
- ->(other) { left.call(other) || right.call(other) }
- end
-
- # Raise an error because the given node is not supported.
- def compile_error(node)
- raise CompilationError, node.inspect
- end
-
- # in [foo, bar, baz]
- def compile_array_pattern_node(node)
- compile_error(node) if !node.rest.nil? || node.posts.any?
-
- constant = node.constant
- compiled_constant = compile_node(constant) if constant
-
- preprocessed = node.requireds.map { |required| compile_node(required) }
-
- compiled_requireds = ->(other) do
- deconstructed = other.deconstruct
-
- deconstructed.length == preprocessed.length &&
- preprocessed
- .zip(deconstructed)
- .all? { |(matcher, value)| matcher.call(value) }
- end
-
- if compiled_constant
- combine_and(compiled_constant, compiled_requireds)
- else
- compiled_requireds
- end
- end
-
- # in foo | bar
- def compile_alternation_pattern_node(node)
- combine_or(compile_node(node.left), compile_node(node.right))
- end
-
- # in Prism::ConstantReadNode
- def compile_constant_path_node(node)
- parent = node.parent
-
- if parent.is_a?(ConstantReadNode) && parent.slice == "Prism"
- compile_node(node.child)
- else
- compile_error(node)
- end
- end
-
- # in ConstantReadNode
- # in String
- def compile_constant_read_node(node)
- value = node.slice
-
- if Prism.const_defined?(value, false)
- clazz = Prism.const_get(value)
-
- ->(other) { clazz === other }
- elsif Object.const_defined?(value, false)
- clazz = Object.const_get(value)
-
- ->(other) { clazz === other }
- else
- compile_error(node)
- end
- end
-
- # in InstanceVariableReadNode[name: Symbol]
- # in { name: Symbol }
- def compile_hash_pattern_node(node)
- compile_error(node) if node.rest
- compiled_constant = compile_node(node.constant) if node.constant
-
- preprocessed =
- node.elements.to_h do |element|
- [element.key.unescaped.to_sym, compile_node(element.value)]
- end
-
- compiled_keywords = ->(other) do
- deconstructed = other.deconstruct_keys(preprocessed.keys)
-
- preprocessed.all? do |keyword, matcher|
- deconstructed.key?(keyword) && matcher.call(deconstructed[keyword])
- end
- end
-
- if compiled_constant
- combine_and(compiled_constant, compiled_keywords)
- else
- compiled_keywords
- end
- end
-
- # in nil
- def compile_nil_node(node)
- ->(attribute) { attribute.nil? }
- end
-
- # in /foo/
- def compile_regular_expression_node(node)
- regexp = Regexp.new(node.unescaped, node.closing[1..])
-
- ->(attribute) { regexp === attribute }
- end
-
- # in ""
- # in "foo"
- def compile_string_node(node)
- string = node.unescaped
-
- ->(attribute) { string === attribute }
- end
-
- # in :+
- # in :foo
- def compile_symbol_node(node)
- symbol = node.unescaped.to_sym
-
- ->(attribute) { symbol === attribute }
- end
-
- # Compile any kind of node. Dispatch out to the individual compilation
- # methods based on the type of node.
- def compile_node(node)
- case node
- when AlternationPatternNode
- compile_alternation_pattern_node(node)
- when ArrayPatternNode
- compile_array_pattern_node(node)
- when ConstantPathNode
- compile_constant_path_node(node)
- when ConstantReadNode
- compile_constant_read_node(node)
- when HashPatternNode
- compile_hash_pattern_node(node)
- when NilNode
- compile_nil_node(node)
- when RegularExpressionNode
- compile_regular_expression_node(node)
- when StringNode
- compile_string_node(node)
- when SymbolNode
- compile_symbol_node(node)
- else
- compile_error(node)
- end
- end
- end
-end
diff --git a/lib/prism/prism.gemspec b/lib/prism/prism.gemspec
deleted file mode 100644
index 9f5cea4e20..0000000000
--- a/lib/prism/prism.gemspec
+++ /dev/null
@@ -1,119 +0,0 @@
-# frozen_string_literal: true
-
-Gem::Specification.new do |spec|
- spec.name = "prism"
- spec.version = "0.19.0"
- spec.authors = ["Shopify"]
- spec.email = ["ruby@shopify.com"]
-
- spec.summary = "Prism Ruby parser"
- spec.homepage = "https://github.com/ruby/prism"
- spec.license = "MIT"
-
- spec.required_ruby_version = ">= 3.0.0"
-
- spec.require_paths = ["lib"]
- spec.files = [
- "CHANGELOG.md",
- "CODE_OF_CONDUCT.md",
- "CONTRIBUTING.md",
- "LICENSE.md",
- "Makefile",
- "README.md",
- "config.yml",
- "docs/build_system.md",
- "docs/building.md",
- "docs/configuration.md",
- "docs/design.md",
- "docs/encoding.md",
- "docs/fuzzing.md",
- "docs/heredocs.md",
- "docs/javascript.md",
- "docs/local_variable_depth.md",
- "docs/mapping.md",
- "docs/releasing.md",
- "docs/ripper.md",
- "docs/ruby_api.md",
- "docs/serialization.md",
- "docs/testing.md",
- "ext/prism/api_node.c",
- "ext/prism/api_pack.c",
- "ext/prism/extension.c",
- "ext/prism/extension.h",
- "include/prism.h",
- "include/prism/ast.h",
- "include/prism/defines.h",
- "include/prism/diagnostic.h",
- "include/prism/encoding.h",
- "include/prism/node.h",
- "include/prism/options.h",
- "include/prism/pack.h",
- "include/prism/parser.h",
- "include/prism/prettyprint.h",
- "include/prism/regexp.h",
- "include/prism/util/pm_buffer.h",
- "include/prism/util/pm_char.h",
- "include/prism/util/pm_constant_pool.h",
- "include/prism/util/pm_list.h",
- "include/prism/util/pm_memchr.h",
- "include/prism/util/pm_newline_list.h",
- "include/prism/util/pm_state_stack.h",
- "include/prism/util/pm_strncasecmp.h",
- "include/prism/util/pm_string.h",
- "include/prism/util/pm_string_list.h",
- "include/prism/util/pm_strpbrk.h",
- "include/prism/version.h",
- "lib/prism.rb",
- "lib/prism/compiler.rb",
- "lib/prism/debug.rb",
- "lib/prism/desugar_compiler.rb",
- "lib/prism/dispatcher.rb",
- "lib/prism/dot_visitor.rb",
- "lib/prism/dsl.rb",
- "lib/prism/ffi.rb",
- "lib/prism/lex_compat.rb",
- "lib/prism/mutation_compiler.rb",
- "lib/prism/node.rb",
- "lib/prism/node_ext.rb",
- "lib/prism/node_inspector.rb",
- "lib/prism/pack.rb",
- "lib/prism/parse_result.rb",
- "lib/prism/pattern.rb",
- "lib/prism/ripper_compat.rb",
- "lib/prism/serialize.rb",
- "lib/prism/parse_result/comments.rb",
- "lib/prism/parse_result/newlines.rb",
- "lib/prism/visitor.rb",
- "src/diagnostic.c",
- "src/encoding.c",
- "src/node.c",
- "src/pack.c",
- "src/prettyprint.c",
- "src/regexp.c",
- "src/serialize.c",
- "src/token_type.c",
- "src/util/pm_buffer.c",
- "src/util/pm_char.c",
- "src/util/pm_constant_pool.c",
- "src/util/pm_list.c",
- "src/util/pm_memchr.c",
- "src/util/pm_newline_list.c",
- "src/util/pm_state_stack.c",
- "src/util/pm_string.c",
- "src/util/pm_string_list.c",
- "src/util/pm_strncasecmp.c",
- "src/util/pm_strpbrk.c",
- "src/options.c",
- "src/prism.c",
- "prism.gemspec",
- "sig/prism.rbs",
- "sig/prism_static.rbs",
- "rbi/prism.rbi",
- "rbi/prism_static.rbi"
- ]
-
- spec.extensions = ["ext/prism/extconf.rb"]
- spec.metadata["allowed_push_host"] = "https://rubygems.org"
- spec.metadata["source_code_uri"] = "https://github.com/ruby/prism"
- spec.metadata["changelog_uri"] = "https://github.com/ruby/prism/blob/main/CHANGELOG.md"
-end
diff --git a/lib/prism/ripper_compat.rb b/lib/prism/ripper_compat.rb
deleted file mode 100644
index 5bd3088a6a..0000000000
--- a/lib/prism/ripper_compat.rb
+++ /dev/null
@@ -1,207 +0,0 @@
-# frozen_string_literal: true
-
-require "ripper"
-
-module Prism
- # Note: This integration is not finished, and therefore still has many
- # inconsistencies with Ripper. If you'd like to help out, pull requests would
- # be greatly appreciated!
- #
- # This class is meant to provide a compatibility layer between prism and
- # Ripper. It functions by parsing the entire tree first and then walking it
- # and executing each of the Ripper callbacks as it goes.
- #
- # This class is going to necessarily be slower than the native Ripper API. It
- # is meant as a stopgap until developers migrate to using prism. It is also
- # meant as a test harness for the prism parser.
- #
- # To use this class, you treat `Prism::RipperCompat` effectively as you would
- # treat the `Ripper` class.
- class RipperCompat < Visitor
- # This class mirrors the ::Ripper::SexpBuilder subclass of ::Ripper that
- # returns the arrays of [type, *children].
- class SexpBuilder < RipperCompat
- private
-
- Ripper::PARSER_EVENTS.each do |event|
- define_method(:"on_#{event}") do |*args|
- [event, *args]
- end
- end
-
- Ripper::SCANNER_EVENTS.each do |event|
- define_method(:"on_#{event}") do |value|
- [:"@#{event}", value, [lineno, column]]
- end
- end
- end
-
- # This class mirrors the ::Ripper::SexpBuilderPP subclass of ::Ripper that
- # returns the same values as ::Ripper::SexpBuilder except with a couple of
- # niceties that flatten linked lists into arrays.
- class SexpBuilderPP < SexpBuilder
- private
-
- def _dispatch_event_new # :nodoc:
- []
- end
-
- def _dispatch_event_push(list, item) # :nodoc:
- list << item
- list
- end
-
- Ripper::PARSER_EVENT_TABLE.each do |event, arity|
- case event
- when /_new\z/
- alias_method :"on_#{event}", :_dispatch_event_new if arity == 0
- when /_add\z/
- alias_method :"on_#{event}", :_dispatch_event_push
- end
- end
- end
-
- # The source that is being parsed.
- attr_reader :source
-
- # The current line number of the parser.
- attr_reader :lineno
-
- # The current column number of the parser.
- attr_reader :column
-
- # Create a new RipperCompat object with the given source.
- def initialize(source)
- @source = source
- @result = nil
- @lineno = nil
- @column = nil
- end
-
- ############################################################################
- # Public interface
- ############################################################################
-
- # True if the parser encountered an error during parsing.
- def error?
- result.failure?
- end
-
- # Parse the source and return the result.
- def parse
- result.magic_comments.each do |magic_comment|
- on_magic_comment(magic_comment.key, magic_comment.value)
- end
-
- if error?
- result.errors.each do |error|
- on_parse_error(error.message)
- end
- else
- result.value.accept(self)
- end
- end
-
- ############################################################################
- # Visitor methods
- ############################################################################
-
- # Visit a CallNode node.
- def visit_call_node(node)
- if !node.message.match?(/^[[:alpha:]_]/) && node.opening_loc.nil? && node.arguments&.arguments&.length == 1
- left = visit(node.receiver)
- right = visit(node.arguments.arguments.first)
-
- bounds(node.location)
- on_binary(left, node.name, right)
- else
- raise NotImplementedError
- end
- end
-
- # Visit a FloatNode node.
- def visit_float_node(node)
- bounds(node.location)
- on_float(node.slice)
- end
-
- # Visit a ImaginaryNode node.
- def visit_imaginary_node(node)
- bounds(node.location)
- on_imaginary(node.slice)
- end
-
- # Visit an IntegerNode node.
- def visit_integer_node(node)
- bounds(node.location)
- on_int(node.slice)
- end
-
- # Visit a RationalNode node.
- def visit_rational_node(node)
- bounds(node.location)
- on_rational(node.slice)
- end
-
- # Visit a StatementsNode node.
- def visit_statements_node(node)
- bounds(node.location)
- node.body.inject(on_stmts_new) do |stmts, stmt|
- on_stmts_add(stmts, visit(stmt))
- end
- end
-
- # Visit a ProgramNode node.
- def visit_program_node(node)
- statements = visit(node.statements)
- bounds(node.location)
- on_program(statements)
- end
-
- ############################################################################
- # Entrypoints for subclasses
- ############################################################################
-
- # This is a convenience method that runs the SexpBuilder subclass parser.
- def self.sexp_raw(source)
- SexpBuilder.new(source).parse
- end
-
- # This is a convenience method that runs the SexpBuilderPP subclass parser.
- def self.sexp(source)
- SexpBuilderPP.new(source).parse
- end
-
- private
-
- # This method is responsible for updating lineno and column information
- # to reflect the current node.
- #
- # This method could be drastically improved with some caching on the start
- # of every line, but for now it's good enough.
- def bounds(location)
- @lineno = location.start_line
- @column = location.start_column
- end
-
- # Lazily initialize the parse result.
- def result
- @result ||= Prism.parse(source)
- end
-
- def _dispatch0; end # :nodoc:
- def _dispatch1(_); end # :nodoc:
- def _dispatch2(_, _); end # :nodoc:
- def _dispatch3(_, _, _); end # :nodoc:
- def _dispatch4(_, _, _, _); end # :nodoc:
- def _dispatch5(_, _, _, _, _); end # :nodoc:
- def _dispatch7(_, _, _, _, _, _, _); end # :nodoc:
-
- alias_method :on_parse_error, :_dispatch1
- alias_method :on_magic_comment, :_dispatch2
-
- (Ripper::SCANNER_EVENT_TABLE.merge(Ripper::PARSER_EVENT_TABLE)).each do |event, arity|
- alias_method :"on_#{event}", :"_dispatch#{arity}"
- end
- end
-end
diff --git a/lib/pstore.gemspec b/lib/pstore.gemspec
deleted file mode 100644
index 86051d2f43..0000000000
--- a/lib/pstore.gemspec
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{Transactional File Storage for Ruby Objects}
- spec.description = spec.summary
- spec.homepage = "https://github.com/ruby/pstore"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = "https://github.com/ruby/pstore"
-
- # Specify which files should be added to the gem when it is released.
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-end
diff --git a/lib/pstore.rb b/lib/pstore.rb
index 818ffa07e0..72deaa1017 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -326,7 +326,7 @@ require "digest"
# end
#
class PStore
- VERSION = "0.1.3"
+ VERSION = "0.1.2"
RDWR_ACCESS = {mode: IO::RDWR | IO::CREAT | IO::BINARY, encoding: Encoding::ASCII_8BIT}.freeze
RD_ACCESS = {mode: IO::RDONLY | IO::BINARY, encoding: Encoding::ASCII_8BIT}.freeze
@@ -487,6 +487,8 @@ class PStore
# end
#
# Raises an exception if called outside a transaction block.
+ #
+ # PStore#roots is an alias for PStore#keys.
def keys
in_transaction
@table.keys
@@ -502,6 +504,8 @@ class PStore
# end
#
# Raises an exception if called outside a transaction block.
+ #
+ # PStore#root? is an alias for PStore#key?.
def key?(key)
in_transaction
@table.key? key
@@ -517,8 +521,8 @@ class PStore
end
# Exits the current transaction block, committing any changes
- # specified in the
- # {transaction block}[rdoc-ref:PStore@The+Transaction+Block].
+ # specified in the transaction block.
+ # See {Committing or Aborting}[rdoc-ref:PStore@Committing+or+Aborting].
#
# Raises an exception if called outside a transaction block.
def commit
@@ -528,8 +532,8 @@ class PStore
end
# Exits the current transaction block, discarding any changes
- # specified in the
- # {transaction block}[rdoc-ref:PStore@The+Transaction+Block].
+ # specified in the transaction block.
+ # See {Committing or Aborting}[rdoc-ref:PStore@Committing+or+Aborting].
#
# Raises an exception if called outside a transaction block.
def abort
diff --git a/lib/pstore/pstore.gemspec b/lib/pstore/pstore.gemspec
new file mode 100644
index 0000000000..8425795afe
--- /dev/null
+++ b/lib/pstore/pstore.gemspec
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Transactional File Storage for Ruby Objects}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/pstore"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = "https://github.com/ruby/pstore"
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/racc.rb b/lib/racc.rb
new file mode 100644
index 0000000000..f6e4ac03a8
--- /dev/null
+++ b/lib/racc.rb
@@ -0,0 +1,6 @@
+require 'racc/compat'
+require 'racc/debugflags'
+require 'racc/grammar'
+require 'racc/state'
+require 'racc/exception'
+require 'racc/info'
diff --git a/lib/racc/compat.rb b/lib/racc/compat.rb
new file mode 100644
index 0000000000..62f4f630be
--- /dev/null
+++ b/lib/racc/compat.rb
@@ -0,0 +1,33 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+unless Object.method_defined?(:__send)
+ class Object
+ alias __send __send__
+ end
+end
+
+unless Object.method_defined?(:__send!)
+ class Object
+ alias __send! __send__
+ end
+end
+
+unless Array.method_defined?(:map!)
+ class Array
+ if Array.method_defined?(:collect!)
+ alias map! collect!
+ else
+ alias map! filter
+ end
+ end
+end
diff --git a/lib/racc/debugflags.rb b/lib/racc/debugflags.rb
new file mode 100644
index 0000000000..ee34cf2314
--- /dev/null
+++ b/lib/racc/debugflags.rb
@@ -0,0 +1,60 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ class DebugFlags
+ def DebugFlags.parse_option_string(s)
+ parse = rule = token = state = la = prec = conf = false
+ s.split(//).each do |ch|
+ case ch
+ when 'p' then parse = true
+ when 'r' then rule = true
+ when 't' then token = true
+ when 's' then state = true
+ when 'l' then la = true
+ when 'c' then prec = true
+ when 'o' then conf = true
+ else
+ raise "unknown debug flag char: #{ch.inspect}"
+ end
+ end
+ new(parse, rule, token, state, la, prec, conf)
+ end
+
+ def initialize(parse = false, rule = false, token = false, state = false,
+ la = false, prec = false, conf = false)
+ @parse = parse
+ @rule = rule
+ @token = token
+ @state = state
+ @la = la
+ @prec = prec
+ @any = (parse || rule || token || state || la || prec)
+ @status_logging = conf
+ end
+
+ attr_reader :parse
+ attr_reader :rule
+ attr_reader :token
+ attr_reader :state
+ attr_reader :la
+ attr_reader :prec
+
+ def any?
+ @any
+ end
+
+ attr_reader :status_logging
+ end
+
+end
diff --git a/lib/racc/exception.rb b/lib/racc/exception.rb
new file mode 100644
index 0000000000..c11dc2e43e
--- /dev/null
+++ b/lib/racc/exception.rb
@@ -0,0 +1,16 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+ class Error < StandardError; end
+ class CompileError < Error; end
+end
diff --git a/lib/racc/grammar.rb b/lib/racc/grammar.rb
new file mode 100644
index 0000000000..01c4c3df69
--- /dev/null
+++ b/lib/racc/grammar.rb
@@ -0,0 +1,1118 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/compat'
+require 'racc/iset'
+require 'racc/sourcetext'
+require 'racc/logfilegenerator'
+require 'racc/exception'
+require 'forwardable'
+
+module Racc
+
+ class Grammar
+
+ def initialize(debug_flags = DebugFlags.new)
+ @symboltable = SymbolTable.new
+ @debug_symbol = debug_flags.token
+ @rules = [] # :: [Rule]
+ @start = nil
+ @n_expected_srconflicts = nil
+ @prec_table = []
+ @prec_table_closed = false
+ @closed = false
+ @states = nil
+ end
+
+ attr_reader :start
+ attr_reader :symboltable
+ attr_accessor :n_expected_srconflicts
+
+ def [](x)
+ @rules[x]
+ end
+
+ def each_rule(&block)
+ @rules.each(&block)
+ end
+
+ alias each each_rule
+
+ def each_index(&block)
+ @rules.each_index(&block)
+ end
+
+ def each_with_index(&block)
+ @rules.each_with_index(&block)
+ end
+
+ def size
+ @rules.size
+ end
+
+ def to_s
+ "<Racc::Grammar>"
+ end
+
+ extend Forwardable
+
+ def_delegator "@symboltable", :each, :each_symbol
+ def_delegator "@symboltable", :each_terminal
+ def_delegator "@symboltable", :each_nonterminal
+
+ def intern(value, dummy = false)
+ @symboltable.intern(value, dummy)
+ end
+
+ def symbols
+ @symboltable.symbols
+ end
+
+ def nonterminal_base
+ @symboltable.nt_base
+ end
+
+ def useless_nonterminal_exist?
+ n_useless_nonterminals() != 0
+ end
+
+ def n_useless_nonterminals
+ @n_useless_nonterminals ||= each_useless_nonterminal.count
+ end
+
+ def each_useless_nonterminal
+ return to_enum __method__ unless block_given?
+
+ @symboltable.each_nonterminal do |sym|
+ yield sym if sym.useless?
+ end
+ end
+
+ def useless_rule_exist?
+ n_useless_rules() != 0
+ end
+
+ def n_useless_rules
+ @n_useless_rules ||= each_useless_rule.count
+ end
+
+ def each_useless_rule
+ return to_enum __method__ unless block_given?
+
+ each do |r|
+ yield r if r.useless?
+ end
+ end
+
+ def nfa
+ (@states ||= States.new(self)).nfa
+ end
+
+ def dfa
+ (@states ||= States.new(self)).dfa
+ end
+
+ alias states dfa
+
+ def state_transition_table
+ states().state_transition_table
+ end
+
+ def parser_class
+ states = states() # cache
+ if $DEBUG
+ srcfilename = caller(1).first.slice(/\A(.*?):/, 1)
+ begin
+ write_log srcfilename + ".output"
+ rescue SystemCallError
+ end
+ report = lambda {|s| $stderr.puts "racc: #{srcfilename}: #{s}" }
+ if states.should_report_srconflict?
+ report["#{states.n_srconflicts} shift/reduce conflicts"]
+ end
+ if states.rrconflict_exist?
+ report["#{states.n_rrconflicts} reduce/reduce conflicts"]
+ end
+ g = states.grammar
+ if g.useless_nonterminal_exist?
+ report["#{g.n_useless_nonterminals} useless nonterminals"]
+ end
+ if g.useless_rule_exist?
+ report["#{g.n_useless_rules} useless rules"]
+ end
+ end
+ states.state_transition_table.parser_class
+ end
+
+ def write_log(path)
+ File.open(path, 'w') {|f|
+ LogFileGenerator.new(states()).output f
+ }
+ end
+
+ #
+ # Grammar Definition Interface
+ #
+
+ def add(rule)
+ raise ArgumentError, "rule added after the Grammar closed" if @closed
+ @rules.push rule
+ end
+
+ def added?(sym)
+ @rules.detect {|r| r.target == sym }
+ end
+
+ def start_symbol=(s)
+ raise CompileError, "start symbol set twice'" if @start
+ @start = s
+ end
+
+ def declare_precedence(assoc, syms)
+ raise CompileError, "precedence table defined twice" if @prec_table_closed
+ @prec_table.push [assoc, syms]
+ end
+
+ def end_precedence_declaration(reverse)
+ @prec_table_closed = true
+ return if @prec_table.empty?
+ table = reverse ? @prec_table.reverse : @prec_table
+ table.each_with_index do |(assoc, syms), idx|
+ syms.each do |sym|
+ sym.assoc = assoc
+ sym.precedence = idx
+ end
+ end
+ end
+
+ #
+ # Dynamic Generation Interface
+ #
+
+ def Grammar.define(&block)
+ env = DefinitionEnv.new
+ env.instance_eval(&block)
+ env.grammar
+ end
+
+ class DefinitionEnv
+ def initialize
+ @grammar = Grammar.new
+ @seqs = Hash.new(0)
+ @delayed = []
+ end
+
+ def grammar
+ flush_delayed
+ @grammar.each do |rule|
+ if rule.specified_prec
+ rule.specified_prec = @grammar.intern(rule.specified_prec)
+ end
+ end
+ @grammar.init
+ @grammar
+ end
+
+ def precedence_table(&block)
+ env = PrecedenceDefinitionEnv.new(@grammar)
+ env.instance_eval(&block)
+ @grammar.end_precedence_declaration env.reverse
+ end
+
+ def method_missing(mid, *args, &block)
+ unless mid.to_s[-1,1] == '='
+ super # raises NoMethodError
+ end
+ target = @grammar.intern(mid.to_s.chop.intern)
+ unless args.size == 1
+ raise ArgumentError, "too many arguments for #{mid} (#{args.size} for 1)"
+ end
+ _add target, args.first
+ end
+
+ def _add(target, x)
+ case x
+ when Sym
+ @delayed.each do |rule|
+ rule.replace x, target if rule.target == x
+ end
+ @grammar.symboltable.delete x
+ else
+ x.each_rule do |r|
+ r.target = target
+ @grammar.add r
+ end
+ end
+ flush_delayed
+ end
+
+ def _delayed_add(rule)
+ @delayed.push rule
+ end
+
+ def _added?(sym)
+ @grammar.added?(sym) or @delayed.detect {|r| r.target == sym }
+ end
+
+ def flush_delayed
+ return if @delayed.empty?
+ @delayed.each do |rule|
+ @grammar.add rule
+ end
+ @delayed.clear
+ end
+
+ def seq(*list, &block)
+ Rule.new(nil, list.map {|x| _intern(x) }, UserAction.proc(block))
+ end
+
+ def null(&block)
+ seq(&block)
+ end
+
+ def action(&block)
+ id = "@#{@seqs["action"] += 1}".intern
+ _delayed_add Rule.new(@grammar.intern(id), [], UserAction.proc(block))
+ id
+ end
+
+ alias _ action
+
+ def option(sym, default = nil, &block)
+ _defmetasyntax("option", _intern(sym), block) {|target|
+ seq() { default } | seq(sym)
+ }
+ end
+
+ def many(sym, &block)
+ _defmetasyntax("many", _intern(sym), block) {|target|
+ seq() { [] }\
+ | seq(target, sym) {|list, x| list.push x; list }
+ }
+ end
+
+ def many1(sym, &block)
+ _defmetasyntax("many1", _intern(sym), block) {|target|
+ seq(sym) {|x| [x] }\
+ | seq(target, sym) {|list, x| list.push x; list }
+ }
+ end
+
+ def separated_by(sep, sym, &block)
+ option(separated_by1(sep, sym), [], &block)
+ end
+
+ def separated_by1(sep, sym, &block)
+ _defmetasyntax("separated_by1", _intern(sym), block) {|target|
+ seq(sym) {|x| [x] }\
+ | seq(target, sep, sym) {|list, _, x| list.push x; list }
+ }
+ end
+
+ def _intern(x)
+ case x
+ when Symbol, String
+ @grammar.intern(x)
+ when Racc::Sym
+ x
+ else
+ raise TypeError, "wrong type #{x.class} (expected Symbol/String/Racc::Sym)"
+ end
+ end
+
+ private
+
+ def _defmetasyntax(type, id, action, &block)
+ if action
+ idbase = "#{type}@#{id}-#{@seqs[type] += 1}"
+ target = _wrap(idbase, "#{idbase}-core", action)
+ _register("#{idbase}-core", &block)
+ else
+ target = _register("#{type}@#{id}", &block)
+ end
+ @grammar.intern(target)
+ end
+
+ def _register(target_name)
+ target = target_name.intern
+ unless _added?(@grammar.intern(target))
+ yield(target).each_rule do |rule|
+ rule.target = @grammar.intern(target)
+ _delayed_add rule
+ end
+ end
+ target
+ end
+
+ def _wrap(target_name, sym, block)
+ target = target_name.intern
+ _delayed_add Rule.new(@grammar.intern(target),
+ [@grammar.intern(sym.intern)],
+ UserAction.proc(block))
+ target
+ end
+ end
+
+ class PrecedenceDefinitionEnv
+ def initialize(g)
+ @grammar = g
+ @prechigh_seen = false
+ @preclow_seen = false
+ @reverse = false
+ end
+
+ attr_reader :reverse
+
+ def higher
+ if @prechigh_seen
+ raise CompileError, "prechigh used twice"
+ end
+ @prechigh_seen = true
+ end
+
+ def lower
+ if @preclow_seen
+ raise CompileError, "preclow used twice"
+ end
+ if @prechigh_seen
+ @reverse = true
+ end
+ @preclow_seen = true
+ end
+
+ def left(*syms)
+ @grammar.declare_precedence :Left, syms.map {|s| @grammar.intern(s) }
+ end
+
+ def right(*syms)
+ @grammar.declare_precedence :Right, syms.map {|s| @grammar.intern(s) }
+ end
+
+ def nonassoc(*syms)
+ @grammar.declare_precedence :Nonassoc, syms.map {|s| @grammar.intern(s)}
+ end
+ end
+
+ #
+ # Computation
+ #
+
+ def init
+ return if @closed
+ @closed = true
+ @start ||= @rules.map {|r| r.target }.detect {|sym| not sym.dummy? }
+ raise CompileError, 'no rule in input' if @rules.empty?
+ add_start_rule
+ @rules.freeze
+ fix_ident
+ compute_hash
+ compute_heads
+ determine_terminals
+ compute_nullable_0
+ @symboltable.fix
+ compute_locate
+ @symboltable.each_nonterminal {|t| compute_expand t }
+ compute_nullable
+ compute_useless
+ end
+
+ private
+
+ def add_start_rule
+ r = Rule.new(@symboltable.dummy,
+ [@start, @symboltable.anchor, @symboltable.anchor],
+ UserAction.empty)
+ r.ident = 0
+ r.hash = 0
+ r.precedence = nil
+ @rules.unshift r
+ end
+
+ # Rule#ident
+ # LocationPointer#ident
+ def fix_ident
+ @rules.each_with_index do |rule, idx|
+ rule.ident = idx
+ end
+ end
+
+ # Rule#hash
+ def compute_hash
+ hash = 4 # size of dummy rule
+ @rules.each do |rule|
+ rule.hash = hash
+ hash += (rule.size + 1)
+ end
+ end
+
+ # Sym#heads
+ def compute_heads
+ @rules.each do |rule|
+ rule.target.heads.push rule.ptrs[0]
+ end
+ end
+
+ # Sym#terminal?
+ def determine_terminals
+ @symboltable.each do |s|
+ s.term = s.heads.empty?
+ end
+ end
+
+ # Sym#self_null?
+ def compute_nullable_0
+ @symboltable.each do |s|
+ if s.terminal?
+ s.snull = false
+ else
+ s.snull = s.heads.any? {|loc| loc.reduce? }
+ end
+ end
+ end
+
+ # Sym#locate
+ def compute_locate
+ @rules.each do |rule|
+ t = nil
+ rule.ptrs.each do |ptr|
+ unless ptr.reduce?
+ tok = ptr.dereference
+ tok.locate.push ptr
+ t = tok if tok.terminal?
+ end
+ end
+ rule.precedence = t
+ end
+ end
+
+ # Sym#expand
+ def compute_expand(t)
+ puts "expand> #{t.to_s}" if @debug_symbol
+ t.expand = _compute_expand(t, ISet.new, [])
+ puts "expand< #{t.to_s}: #{t.expand.to_s}" if @debug_symbol
+ end
+
+ def _compute_expand(t, set, lock)
+ if tmp = t.expand
+ set.update tmp
+ return set
+ end
+ tok = nil
+ set.update_a t.heads
+ t.heads.each do |ptr|
+ tok = ptr.dereference
+ if tok and tok.nonterminal?
+ unless lock[tok.ident]
+ lock[tok.ident] = true
+ _compute_expand tok, set, lock
+ end
+ end
+ end
+ set
+ end
+
+ # Sym#nullable?, Rule#nullable?
+ def compute_nullable
+ @rules.each {|r| r.null = false }
+ @symboltable.each {|t| t.null = false }
+ r = @rules.dup
+ s = @symboltable.nonterminals
+ begin
+ rs = r.size
+ ss = s.size
+ check_rules_nullable r
+ check_symbols_nullable s
+ end until rs == r.size and ss == s.size
+ end
+
+ def check_rules_nullable(rules)
+ rules.delete_if do |rule|
+ rule.null = true
+ rule.symbols.each do |t|
+ unless t.nullable?
+ rule.null = false
+ break
+ end
+ end
+ rule.nullable?
+ end
+ end
+
+ def check_symbols_nullable(symbols)
+ symbols.delete_if do |sym|
+ sym.heads.each do |ptr|
+ if ptr.rule.nullable?
+ sym.null = true
+ break
+ end
+ end
+ sym.nullable?
+ end
+ end
+
+ # Sym#useless?, Rule#useless?
+ # FIXME: what means "useless"?
+ def compute_useless
+ @symboltable.each_terminal {|sym| sym.useless = false }
+ @symboltable.each_nonterminal {|sym| sym.useless = true }
+ @rules.each {|rule| rule.useless = true }
+ r = @rules.dup
+ s = @symboltable.nonterminals
+ begin
+ rs = r.size
+ ss = s.size
+ check_rules_useless r
+ check_symbols_useless s
+ end until r.size == rs and s.size == ss
+ end
+
+ def check_rules_useless(rules)
+ rules.delete_if do |rule|
+ rule.useless = false
+ rule.symbols.each do |sym|
+ if sym.useless?
+ rule.useless = true
+ break
+ end
+ end
+ not rule.useless?
+ end
+ end
+
+ def check_symbols_useless(s)
+ s.delete_if do |t|
+ t.heads.each do |ptr|
+ unless ptr.rule.useless?
+ t.useless = false
+ break
+ end
+ end
+ not t.useless?
+ end
+ end
+
+ end # class Grammar
+
+
+ class Rule
+
+ def initialize(target, syms, act)
+ @target = target
+ @symbols = syms
+ @action = act
+ @alternatives = []
+
+ @ident = nil
+ @hash = nil
+ @ptrs = nil
+ @precedence = nil
+ @specified_prec = nil
+ @null = nil
+ @useless = nil
+ end
+
+ attr_accessor :target
+ attr_reader :symbols
+ attr_reader :action
+
+ def |(x)
+ @alternatives.push x.rule
+ self
+ end
+
+ def rule
+ self
+ end
+
+ def each_rule(&block)
+ yield self
+ @alternatives.each(&block)
+ end
+
+ attr_accessor :ident
+
+ attr_reader :hash
+ attr_reader :ptrs
+
+ def hash=(n)
+ @hash = n
+ ptrs = []
+ @symbols.each_with_index do |sym, idx|
+ ptrs.push LocationPointer.new(self, idx, sym)
+ end
+ ptrs.push LocationPointer.new(self, @symbols.size, nil)
+ @ptrs = ptrs
+ end
+
+ def precedence
+ @specified_prec || @precedence
+ end
+
+ def precedence=(sym)
+ @precedence ||= sym
+ end
+
+ def prec(sym, &block)
+ @specified_prec = sym
+ if block
+ unless @action.empty?
+ raise CompileError, 'both of rule action block and prec block given'
+ end
+ @action = UserAction.proc(block)
+ end
+ self
+ end
+
+ attr_accessor :specified_prec
+
+ def nullable?() @null end
+ def null=(n) @null = n end
+
+ def useless?() @useless end
+ def useless=(u) @useless = u end
+
+ def inspect
+ "#<Racc::Rule id=#{@ident} (#{@target})>"
+ end
+
+ def ==(other)
+ other.kind_of?(Rule) and @ident == other.ident
+ end
+
+ def [](idx)
+ @symbols[idx]
+ end
+
+ def size
+ @symbols.size
+ end
+
+ def empty?
+ @symbols.empty?
+ end
+
+ def to_s
+ "#<rule#{@ident}>"
+ end
+
+ def accept?
+ if tok = @symbols[-1]
+ tok.anchor?
+ else
+ false
+ end
+ end
+
+ def each(&block)
+ @symbols.each(&block)
+ end
+
+ def replace(src, dest)
+ @target = dest
+ @symbols = @symbols.map {|s| s == src ? dest : s }
+ end
+
+ end # class Rule
+
+
+ class UserAction
+
+ def UserAction.source_text(src)
+ new(src, nil)
+ end
+
+ def UserAction.proc(pr = nil, &block)
+ if pr and block
+ raise ArgumentError, "both of argument and block given"
+ end
+ new(nil, pr || block)
+ end
+
+ def UserAction.empty
+ new(nil, nil)
+ end
+
+ private_class_method :new
+
+ def initialize(src, proc)
+ @source = src
+ @proc = proc
+ end
+
+ attr_reader :source
+ attr_reader :proc
+
+ def source?
+ not @proc
+ end
+
+ def proc?
+ not @source
+ end
+
+ def empty?
+ not @proc and not @source
+ end
+
+ def name
+ "{action type=#{@source || @proc || 'nil'}}"
+ end
+
+ alias inspect name
+
+ end
+
+
+ class OrMark
+ def initialize(lineno)
+ @lineno = lineno
+ end
+
+ def name
+ '|'
+ end
+
+ alias inspect name
+
+ attr_reader :lineno
+ end
+
+
+ class Prec
+ def initialize(symbol, lineno)
+ @symbol = symbol
+ @lineno = lineno
+ end
+
+ def name
+ "=#{@symbol}"
+ end
+
+ alias inspect name
+
+ attr_reader :symbol
+ attr_reader :lineno
+ end
+
+
+ #
+ # A set of rule and position in it's RHS.
+ # Note that the number of pointers is more than rule's RHS array,
+ # because pointer points right edge of the final symbol when reducing.
+ #
+ class LocationPointer
+
+ def initialize(rule, i, sym)
+ @rule = rule
+ @index = i
+ @symbol = sym
+ @ident = @rule.hash + i
+ @reduce = sym.nil?
+ end
+
+ attr_reader :rule
+ attr_reader :index
+ attr_reader :symbol
+
+ alias dereference symbol
+
+ attr_reader :ident
+ alias hash ident
+ attr_reader :reduce
+ alias reduce? reduce
+
+ def to_s
+ sprintf('(%d,%d %s)',
+ @rule.ident, @index, (reduce?() ? '#' : @symbol.to_s))
+ end
+
+ alias inspect to_s
+
+ def eql?(ot)
+ @hash == ot.hash
+ end
+
+ alias == eql?
+
+ def head?
+ @index == 0
+ end
+
+ def next
+ @rule.ptrs[@index + 1] or ptr_bug!
+ end
+
+ alias increment next
+
+ def before(len)
+ @rule.ptrs[@index - len] or ptr_bug!
+ end
+
+ private
+
+ def ptr_bug!
+ raise "racc: fatal: pointer not exist: self: #{to_s}"
+ end
+
+ end # class LocationPointer
+
+
+ class SymbolTable
+
+ include Enumerable
+
+ def initialize
+ @symbols = [] # :: [Racc::Sym]
+ @cache = {} # :: {(String|Symbol) => Racc::Sym}
+ @dummy = intern(:$start, true)
+ @anchor = intern(false, true) # Symbol ID = 0
+ @error = intern(:error, false) # Symbol ID = 1
+ end
+
+ attr_reader :dummy
+ attr_reader :anchor
+ attr_reader :error
+
+ def [](id)
+ @symbols[id]
+ end
+
+ def intern(val, dummy = false)
+ @cache[val] ||=
+ begin
+ sym = Sym.new(val, dummy)
+ @symbols.push sym
+ sym
+ end
+ end
+
+ attr_reader :symbols
+ alias to_a symbols
+
+ def delete(sym)
+ @symbols.delete sym
+ @cache.delete sym.value
+ end
+
+ attr_reader :nt_base
+
+ def nt_max
+ @symbols.size
+ end
+
+ def each(&block)
+ @symbols.each(&block)
+ end
+
+ def terminals(&block)
+ @symbols[0, @nt_base]
+ end
+
+ def each_terminal(&block)
+ @terms.each(&block)
+ end
+
+ def nonterminals
+ @symbols[@nt_base, @symbols.size - @nt_base]
+ end
+
+ def each_nonterminal(&block)
+ @nterms.each(&block)
+ end
+
+ def fix
+ terms, nterms = @symbols.partition {|s| s.terminal? }
+ @symbols = terms + nterms
+ @terms = terms
+ @nterms = nterms
+ @nt_base = terms.size
+ fix_ident
+ check_terminals
+ end
+
+ private
+
+ def fix_ident
+ @symbols.each_with_index do |t, i|
+ t.ident = i
+ end
+ end
+
+ def check_terminals
+ return unless @symbols.any? {|s| s.should_terminal? }
+ @anchor.should_terminal
+ @error.should_terminal
+ each_terminal do |t|
+ t.should_terminal if t.string_symbol?
+ end
+ each do |s|
+ s.should_terminal if s.assoc
+ end
+ terminals().reject {|t| t.should_terminal? }.each do |t|
+ raise CompileError, "terminal #{t} not declared as terminal"
+ end
+ nonterminals().select {|n| n.should_terminal? }.each do |n|
+ raise CompileError, "symbol #{n} declared as terminal but is not terminal"
+ end
+ end
+
+ end # class SymbolTable
+
+
+ # Stands terminal and nonterminal symbols.
+ class Sym
+
+ def initialize(value, dummyp)
+ @ident = nil
+ @value = value
+ @dummyp = dummyp
+
+ @term = nil
+ @nterm = nil
+ @should_terminal = false
+ @precedence = nil
+ case value
+ when Symbol
+ @to_s = value.to_s
+ @serialized = value.inspect
+ @string = false
+ when String
+ @to_s = value.inspect
+ @serialized = value.dump
+ @string = true
+ when false
+ @to_s = '$end'
+ @serialized = 'false'
+ @string = false
+ when ErrorSymbolValue
+ @to_s = 'error'
+ @serialized = 'Object.new'
+ @string = false
+ else
+ raise ArgumentError, "unknown symbol value: #{value.class}"
+ end
+
+ @heads = []
+ @locate = []
+ @snull = nil
+ @null = nil
+ @expand = nil
+ @useless = nil
+ end
+
+ class << self
+ def once_writer(nm)
+ nm = nm.id2name
+ module_eval(<<-EOS)
+ def #{nm}=(v)
+ raise 'racc: fatal: @#{nm} != nil' unless @#{nm}.nil?
+ @#{nm} = v
+ end
+ EOS
+ end
+ end
+
+ once_writer :ident
+ attr_reader :ident
+
+ alias hash ident
+
+ attr_reader :value
+
+ def dummy?
+ @dummyp
+ end
+
+ def terminal?
+ @term
+ end
+
+ def nonterminal?
+ @nterm
+ end
+
+ def term=(t)
+ raise 'racc: fatal: term= called twice' unless @term.nil?
+ @term = t
+ @nterm = !t
+ end
+
+ def should_terminal
+ @should_terminal = true
+ end
+
+ def should_terminal?
+ @should_terminal
+ end
+
+ def string_symbol?
+ @string
+ end
+
+ def serialize
+ @serialized
+ end
+
+ attr_writer :serialized
+
+ attr_accessor :precedence
+ attr_accessor :assoc
+
+ def to_s
+ @to_s.dup
+ end
+
+ alias inspect to_s
+
+ def |(x)
+ rule() | x.rule
+ end
+
+ def rule
+ Rule.new(nil, [self], UserAction.empty)
+ end
+
+ #
+ # cache
+ #
+
+ attr_reader :heads
+ attr_reader :locate
+
+ def self_null?
+ @snull
+ end
+
+ once_writer :snull
+
+ def nullable?
+ @null
+ end
+
+ def null=(n)
+ @null = n
+ end
+
+ attr_reader :expand
+ once_writer :expand
+
+ def useless?
+ @useless
+ end
+
+ def useless=(f)
+ @useless = f
+ end
+
+ end # class Sym
+
+end # module Racc
diff --git a/lib/racc/grammarfileparser.rb b/lib/racc/grammarfileparser.rb
new file mode 100644
index 0000000000..c7d1207f0b
--- /dev/null
+++ b/lib/racc/grammarfileparser.rb
@@ -0,0 +1,561 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc'
+require 'racc/compat'
+require 'racc/grammar'
+require 'racc/parserfilegenerator'
+require 'racc/sourcetext'
+require 'stringio'
+
+module Racc
+
+ grammar = Grammar.define {
+ g = self
+
+ g.class = seq(:CLASS, :cname, many(:param), :RULE, :rules, option(:END))
+
+ g.cname = seq(:rubyconst) {|name|
+ @result.params.classname = name
+ }\
+ | seq(:rubyconst, "<", :rubyconst) {|c, _, s|
+ @result.params.classname = c
+ @result.params.superclass = s
+ }
+
+ g.rubyconst = separated_by1(:colon2, :SYMBOL) {|syms|
+ syms.map {|s| s.to_s }.join('::')
+ }
+
+ g.colon2 = seq(':', ':')
+
+ g.param = seq(:CONV, many1(:convdef), :END) {|*|
+ #@grammar.end_convert_block # FIXME
+ }\
+ | seq(:PRECHIGH, many1(:precdef), :PRECLOW) {|*|
+ @grammar.end_precedence_declaration true
+ }\
+ | seq(:PRECLOW, many1(:precdef), :PRECHIGH) {|*|
+ @grammar.end_precedence_declaration false
+ }\
+ | seq(:START, :symbol) {|_, sym|
+ @grammar.start_symbol = sym
+ }\
+ | seq(:TOKEN, :symbols) {|_, syms|
+ syms.each do |s|
+ s.should_terminal
+ end
+ }\
+ | seq(:OPTION, :options) {|_, syms|
+ syms.each do |opt|
+ case opt
+ when 'result_var'
+ @result.params.result_var = true
+ when 'no_result_var'
+ @result.params.result_var = false
+ when 'omit_action_call'
+ @result.params.omit_action_call = true
+ when 'no_omit_action_call'
+ @result.params.omit_action_call = false
+ else
+ raise CompileError, "unknown option: #{opt}"
+ end
+ end
+ }\
+ | seq(:EXPECT, :DIGIT) {|_, num|
+ if @grammar.n_expected_srconflicts
+ raise CompileError, "`expect' seen twice"
+ end
+ @grammar.n_expected_srconflicts = num
+ }
+
+ g.convdef = seq(:symbol, :STRING) {|sym, code|
+ sym.serialized = code
+ }
+
+ g.precdef = seq(:LEFT, :symbols) {|_, syms|
+ @grammar.declare_precedence :Left, syms
+ }\
+ | seq(:RIGHT, :symbols) {|_, syms|
+ @grammar.declare_precedence :Right, syms
+ }\
+ | seq(:NONASSOC, :symbols) {|_, syms|
+ @grammar.declare_precedence :Nonassoc, syms
+ }
+
+ g.symbols = seq(:symbol) {|sym|
+ [sym]
+ }\
+ | seq(:symbols, :symbol) {|list, sym|
+ list.push sym
+ list
+ }\
+ | seq(:symbols, "|")
+
+ g.symbol = seq(:SYMBOL) {|sym| @grammar.intern(sym) }\
+ | seq(:STRING) {|str| @grammar.intern(str) }
+
+ g.options = many(:SYMBOL) {|syms| syms.map {|s| s.to_s } }
+
+ g.rules = option(:rules_core) {|list|
+ add_rule_block list unless list.empty?
+ nil
+ }
+
+ g.rules_core = seq(:symbol) {|sym|
+ [sym]
+ }\
+ | seq(:rules_core, :rule_item) {|list, i|
+ list.push i
+ list
+ }\
+ | seq(:rules_core, ';') {|list, *|
+ add_rule_block list unless list.empty?
+ list.clear
+ list
+ }\
+ | seq(:rules_core, ':') {|list, *|
+ next_target = list.pop
+ add_rule_block list unless list.empty?
+ [next_target]
+ }
+
+ g.rule_item = seq(:symbol)\
+ | seq("|") {|*|
+ OrMark.new(@scanner.lineno)
+ }\
+ | seq("=", :symbol) {|_, sym|
+ Prec.new(sym, @scanner.lineno)
+ }\
+ | seq(:ACTION) {|src|
+ UserAction.source_text(src)
+ }
+ }
+
+ GrammarFileParser = grammar.parser_class
+
+ if grammar.states.srconflict_exist?
+ raise 'Racc boot script fatal: S/R conflict in build'
+ end
+ if grammar.states.rrconflict_exist?
+ raise 'Racc boot script fatal: R/R conflict in build'
+ end
+
+ class GrammarFileParser # reopen
+
+ class Result
+ def initialize(grammar)
+ @grammar = grammar
+ @params = ParserFileGenerator::Params.new
+ end
+
+ attr_reader :grammar
+ attr_reader :params
+ end
+
+ def GrammarFileParser.parse_file(filename)
+ parse(File.read(filename), filename, 1)
+ end
+
+ def GrammarFileParser.parse(src, filename = '-', lineno = 1)
+ new().parse(src, filename, lineno)
+ end
+
+ def initialize(debug_flags = DebugFlags.new)
+ @yydebug = debug_flags.parse
+ end
+
+ def parse(src, filename = '-', lineno = 1)
+ @filename = filename
+ @lineno = lineno
+ @scanner = GrammarFileScanner.new(src, @filename)
+ @scanner.debug = @yydebug
+ @grammar = Grammar.new
+ @result = Result.new(@grammar)
+ @embedded_action_seq = 0
+ yyparse @scanner, :yylex
+ parse_user_code
+ @result.grammar.init
+ @result
+ end
+
+ private
+
+ def next_token
+ @scanner.scan
+ end
+
+ def on_error(tok, val, _values)
+ if val.respond_to?(:id2name)
+ v = val.id2name
+ elsif val.kind_of?(String)
+ v = val
+ else
+ v = val.inspect
+ end
+ raise CompileError, "#{location()}: unexpected token '#{v}'"
+ end
+
+ def location
+ "#{@filename}:#{@lineno - 1 + @scanner.lineno}"
+ end
+
+ def add_rule_block(list)
+ sprec = nil
+ target = list.shift
+ case target
+ when OrMark, UserAction, Prec
+ raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}"
+ end
+ curr = []
+ list.each do |i|
+ case i
+ when OrMark
+ add_rule target, curr, sprec
+ curr = []
+ sprec = nil
+ when Prec
+ raise CompileError, "'=<prec>' used twice in one rule" if sprec
+ sprec = i.symbol
+ else
+ curr.push i
+ end
+ end
+ add_rule target, curr, sprec
+ end
+
+ def add_rule(target, list, sprec)
+ if list.last.kind_of?(UserAction)
+ act = list.pop
+ else
+ act = UserAction.empty
+ end
+ list.map! {|s| s.kind_of?(UserAction) ? embedded_action(s) : s }
+ rule = Rule.new(target, list, act)
+ rule.specified_prec = sprec
+ @grammar.add rule
+ end
+
+ def embedded_action(act)
+ sym = @grammar.intern("@#{@embedded_action_seq += 1}".intern, true)
+ @grammar.add Rule.new(sym, [], act)
+ sym
+ end
+
+ #
+ # User Code Block
+ #
+
+ def parse_user_code
+ line = @scanner.lineno
+ _, *blocks = *@scanner.epilogue.split(/^----/)
+ blocks.each do |block|
+ header, *body = block.lines.to_a
+ label0, paths = *header.sub(/\A-+/, '').split('=', 2)
+ label = canonical_label(label0)
+ (paths ? paths.strip.split(' ') : []).each do |path|
+ add_user_code label, SourceText.new(File.read(path), path, 1)
+ end
+ add_user_code label, SourceText.new(body.join(''), @filename, line + 1)
+ line += (1 + body.size)
+ end
+ end
+
+ USER_CODE_LABELS = {
+ 'header' => :header,
+ 'prepare' => :header, # obsolete
+ 'inner' => :inner,
+ 'footer' => :footer,
+ 'driver' => :footer # obsolete
+ }
+
+ def canonical_label(src)
+ label = src.to_s.strip.downcase.slice(/\w+/)
+ unless USER_CODE_LABELS.key?(label)
+ raise CompileError, "unknown user code type: #{label.inspect}"
+ end
+ label
+ end
+
+ def add_user_code(label, src)
+ @result.params.public_send(USER_CODE_LABELS[label]).push src
+ end
+
+ end
+
+
+ class GrammarFileScanner
+
+ def initialize(str, filename = '-')
+ @lines = str.b.split(/\n|\r\n|\r/)
+ @filename = filename
+ @lineno = -1
+ @line_head = true
+ @in_rule_blk = false
+ @in_conv_blk = false
+ @in_block = nil
+ @epilogue = ''
+ @debug = false
+ next_line
+ end
+
+ attr_reader :epilogue
+
+ def lineno
+ @lineno + 1
+ end
+
+ attr_accessor :debug
+
+ def yylex(&block)
+ unless @debug
+ yylex0(&block)
+ else
+ yylex0 do |sym, tok|
+ $stderr.printf "%7d %-10s %s\n", lineno(), sym.inspect, tok.inspect
+ yield [sym, tok]
+ end
+ end
+ end
+
+ private
+
+ def yylex0
+ begin
+ until @line.empty?
+ @line.sub!(/\A\s+/, '')
+ if /\A\#/ =~ @line
+ break
+ elsif /\A\/\*/ =~ @line
+ skip_comment
+ elsif s = reads(/\A[a-zA-Z_]\w*/)
+ yield [atom_symbol(s), s.intern]
+ elsif s = reads(/\A\d+/)
+ yield [:DIGIT, s.to_i]
+ elsif ch = reads(/\A./)
+ case ch
+ when '"', "'"
+ yield [:STRING, eval(scan_quoted(ch))]
+ when '{'
+ lineno = lineno()
+ yield [:ACTION, SourceText.new(scan_action(), @filename, lineno)]
+ else
+ if ch == '|'
+ @line_head = false
+ end
+ yield [ch, ch]
+ end
+ else
+ end
+ end
+ end while next_line()
+ yield nil
+ end
+
+ def next_line
+ @lineno += 1
+ @line = @lines[@lineno]
+ if not @line or /\A----/ =~ @line
+ @epilogue = @lines.join("\n")
+ @lines.clear
+ @line = nil
+ if @in_block
+ @lineno -= 1
+ scan_error! sprintf('unterminated %s', @in_block)
+ end
+ false
+ else
+ @line.sub!(/(?:\n|\r\n|\r)\z/, '')
+ @line_head = true
+ true
+ end
+ end
+
+ ReservedWord = {
+ 'right' => :RIGHT,
+ 'left' => :LEFT,
+ 'nonassoc' => :NONASSOC,
+ 'preclow' => :PRECLOW,
+ 'prechigh' => :PRECHIGH,
+ 'token' => :TOKEN,
+ 'convert' => :CONV,
+ 'options' => :OPTION,
+ 'start' => :START,
+ 'expect' => :EXPECT,
+ 'class' => :CLASS,
+ 'rule' => :RULE,
+ 'end' => :END
+ }
+
+ def atom_symbol(token)
+ if token == 'end'
+ symbol = :END
+ @in_conv_blk = false
+ @in_rule_blk = false
+ else
+ if @line_head and not @in_conv_blk and not @in_rule_blk
+ symbol = ReservedWord[token] || :SYMBOL
+ else
+ symbol = :SYMBOL
+ end
+ case symbol
+ when :RULE then @in_rule_blk = true
+ when :CONV then @in_conv_blk = true
+ end
+ end
+ @line_head = false
+ symbol
+ end
+
+ def skip_comment
+ @in_block = 'comment'
+ until m = /\*\//.match(@line)
+ next_line
+ end
+ @line = m.post_match
+ @in_block = nil
+ end
+
+ $raccs_print_type = false
+
+ def scan_action
+ buf = String.new
+ nest = 1
+ pre = nil
+ @in_block = 'action'
+ begin
+ pre = nil
+ if s = reads(/\A\s+/)
+ # does not set 'pre'
+ buf << s
+ end
+ until @line.empty?
+ if s = reads(/\A[^'"`{}%#\/\$]+/)
+ buf << (pre = s)
+ next
+ end
+ case ch = read(1)
+ when '{'
+ nest += 1
+ buf << (pre = ch)
+ when '}'
+ nest -= 1
+ if nest == 0
+ @in_block = nil
+ buf.sub!(/[ \t\f]+\z/, '')
+ return buf
+ end
+ buf << (pre = ch)
+ when '#' # comment
+ buf << ch << @line
+ break
+ when "'", '"', '`'
+ buf << (pre = scan_quoted(ch))
+ when '%'
+ if literal_head? pre, @line
+ # % string, regexp, array
+ buf << ch
+ case ch = read(1)
+ when /[qQx]/n
+ buf << ch << (pre = scan_quoted(read(1), '%string'))
+ when /wW/n
+ buf << ch << (pre = scan_quoted(read(1), '%array'))
+ when /s/n
+ buf << ch << (pre = scan_quoted(read(1), '%symbol'))
+ when /r/n
+ buf << ch << (pre = scan_quoted(read(1), '%regexp'))
+ when /[a-zA-Z0-9= ]/n # does not include "_"
+ scan_error! "unknown type of % literal '%#{ch}'"
+ else
+ buf << (pre = scan_quoted(ch, '%string'))
+ end
+ else
+ # operator
+ buf << '||op->' if $raccs_print_type
+ buf << (pre = ch)
+ end
+ when '/'
+ if literal_head? pre, @line
+ # regexp
+ buf << (pre = scan_quoted(ch, 'regexp'))
+ else
+ # operator
+ buf << '||op->' if $raccs_print_type
+ buf << (pre = ch)
+ end
+ when '$' # gvar
+ buf << ch << (pre = read(1))
+ else
+ raise 'racc: fatal: must not happen'
+ end
+ end
+ buf << "\n"
+ end while next_line()
+ raise 'racc: fatal: scan finished before parser finished'
+ end
+
+ def literal_head?(pre, post)
+ (!pre || /[a-zA-Z_0-9]/n !~ pre[-1,1]) &&
+ !post.empty? && /\A[\s\=]/n !~ post
+ end
+
+ def read(len)
+ s = @line[0, len]
+ @line = @line[len .. -1]
+ s
+ end
+
+ def reads(re)
+ m = re.match(@line) or return nil
+ @line = m.post_match
+ m[0]
+ end
+
+ def scan_quoted(left, tag = 'string')
+ buf = left.dup
+ buf = "||#{tag}->" + buf if $raccs_print_type
+ re = get_quoted_re(left)
+ sv, @in_block = @in_block, tag
+ begin
+ if s = reads(re)
+ buf << s
+ break
+ else
+ buf << @line
+ end
+ end while next_line()
+ @in_block = sv
+ buf << "<-#{tag}||" if $raccs_print_type
+ buf
+ end
+
+ LEFT_TO_RIGHT = {
+ '(' => ')',
+ '{' => '}',
+ '[' => ']',
+ '<' => '>'
+ }
+
+ CACHE = {}
+
+ def get_quoted_re(left)
+ term = Regexp.quote(LEFT_TO_RIGHT[left] || left)
+ CACHE[left] ||= /\A[^#{term}\\]*(?:\\.[^\\#{term}]*)*#{term}/
+ end
+
+ def scan_error!(msg)
+ raise CompileError, "#{lineno()}: #{msg}"
+ end
+
+ end
+
+end # module Racc
diff --git a/lib/racc/info.rb b/lib/racc/info.rb
new file mode 100644
index 0000000000..37bff7edba
--- /dev/null
+++ b/lib/racc/info.rb
@@ -0,0 +1,17 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+ VERSION = '1.6.2'
+ Version = VERSION
+ Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
+end
diff --git a/lib/racc/iset.rb b/lib/racc/iset.rb
new file mode 100644
index 0000000000..339221d21b
--- /dev/null
+++ b/lib/racc/iset.rb
@@ -0,0 +1,92 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ # An "indexed" set. All items must respond to :ident.
+ class ISet
+
+ def initialize(a = [])
+ @set = a
+ end
+
+ attr_reader :set
+
+ def add(i)
+ @set[i.ident] = i
+ end
+
+ def [](key)
+ @set[key.ident]
+ end
+
+ def []=(key, val)
+ @set[key.ident] = val
+ end
+
+ alias include? []
+ alias key? []
+
+ def update(other)
+ s = @set
+ o = other.set
+ o.each_index do |idx|
+ if t = o[idx]
+ s[idx] = t
+ end
+ end
+ end
+
+ def update_a(a)
+ s = @set
+ a.each {|i| s[i.ident] = i }
+ end
+
+ def delete(key)
+ i = @set[key.ident]
+ @set[key.ident] = nil
+ i
+ end
+
+ def each(&block)
+ @set.compact.each(&block)
+ end
+
+ def to_a
+ @set.compact
+ end
+
+ def to_s
+ "[#{@set.compact.join(' ')}]"
+ end
+
+ alias inspect to_s
+
+ def size
+ @set.nitems
+ end
+
+ def empty?
+ @set.nitems == 0
+ end
+
+ def clear
+ @set.clear
+ end
+
+ def dup
+ ISet.new(@set.dup)
+ end
+
+ end # class ISet
+
+end # module Racc
diff --git a/lib/racc/logfilegenerator.rb b/lib/racc/logfilegenerator.rb
new file mode 100644
index 0000000000..2f5aa0c8b0
--- /dev/null
+++ b/lib/racc/logfilegenerator.rb
@@ -0,0 +1,212 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ class LogFileGenerator
+
+ def initialize(states, debug_flags = DebugFlags.new)
+ @states = states
+ @grammar = states.grammar
+ @debug_flags = debug_flags
+ end
+
+ def output(out)
+ output_conflict out; out.puts
+ output_useless out; out.puts
+ output_rule out; out.puts
+ output_token out; out.puts
+ output_state out
+ end
+
+ #
+ # Warnings
+ #
+
+ def output_conflict(out)
+ @states.each do |state|
+ if state.srconf
+ out.printf "state %d contains %d shift/reduce conflicts\n",
+ state.stateid, state.srconf.size
+ end
+ if state.rrconf
+ out.printf "state %d contains %d reduce/reduce conflicts\n",
+ state.stateid, state.rrconf.size
+ end
+ end
+ end
+
+ def output_useless(out)
+ @grammar.each do |rl|
+ if rl.useless?
+ out.printf "rule %d (%s) never reduced\n",
+ rl.ident, rl.target.to_s
+ end
+ end
+ @grammar.each_nonterminal do |t|
+ if t.useless?
+ out.printf "useless nonterminal %s\n", t.to_s
+ end
+ end
+ end
+
+ #
+ # States
+ #
+
+ def output_state(out)
+ out << "--------- State ---------\n"
+
+ showall = @debug_flags.la || @debug_flags.state
+ @states.each do |state|
+ out << "\nstate #{state.ident}\n\n"
+
+ (showall ? state.closure : state.core).each do |ptr|
+ pointer_out(out, ptr) if ptr.rule.ident != 0 or showall
+ end
+ out << "\n"
+
+ action_out out, state
+ end
+ end
+
+ def pointer_out(out, ptr)
+ buf = sprintf("%4d) %s :", ptr.rule.ident, ptr.rule.target.to_s)
+ ptr.rule.symbols.each_with_index do |tok, idx|
+ buf << ' _' if idx == ptr.index
+ buf << ' ' << tok.to_s
+ end
+ buf << ' _' if ptr.reduce?
+ out.puts buf
+ end
+
+ def action_out(f, state)
+ sr = state.srconf && state.srconf.dup
+ rr = state.rrconf && state.rrconf.dup
+ acts = state.action
+ keys = acts.keys
+ keys.sort! {|a,b| a.ident <=> b.ident }
+
+ [ Shift, Reduce, Error, Accept ].each do |klass|
+ keys.delete_if do |tok|
+ act = acts[tok]
+ if act.kind_of?(klass)
+ outact f, tok, act
+ if sr and c = sr.delete(tok)
+ outsrconf f, c
+ end
+ if rr and c = rr.delete(tok)
+ outrrconf f, c
+ end
+
+ true
+ else
+ false
+ end
+ end
+ end
+ sr.each {|tok, c| outsrconf f, c } if sr
+ rr.each {|tok, c| outrrconf f, c } if rr
+
+ act = state.defact
+ if not act.kind_of?(Error) or @debug_flags.any?
+ outact f, '$default', act
+ end
+
+ f.puts
+ state.goto_table.each do |t, st|
+ if t.nonterminal?
+ f.printf " %-12s go to state %d\n", t.to_s, st.ident
+ end
+ end
+ end
+
+ def outact(f, t, act)
+ case act
+ when Shift
+ f.printf " %-12s shift, and go to state %d\n",
+ t.to_s, act.goto_id
+ when Reduce
+ f.printf " %-12s reduce using rule %d (%s)\n",
+ t.to_s, act.ruleid, act.rule.target.to_s
+ when Accept
+ f.printf " %-12s accept\n", t.to_s
+ when Error
+ f.printf " %-12s error\n", t.to_s
+ else
+ raise "racc: fatal: wrong act for outact: act=#{act}(#{act.class})"
+ end
+ end
+
+ def outsrconf(f, confs)
+ confs.each do |c|
+ r = c.reduce
+ f.printf " %-12s [reduce using rule %d (%s)]\n",
+ c.shift.to_s, r.ident, r.target.to_s
+ end
+ end
+
+ def outrrconf(f, confs)
+ confs.each do |c|
+ r = c.low_prec
+ f.printf " %-12s [reduce using rule %d (%s)]\n",
+ c.token.to_s, r.ident, r.target.to_s
+ end
+ end
+
+ #
+ # Rules
+ #
+
+ def output_rule(out)
+ out.print "-------- Grammar --------\n\n"
+ @grammar.each do |rl|
+ if @debug_flags.any? or rl.ident != 0
+ out.printf "rule %d %s: %s\n",
+ rl.ident, rl.target.to_s, rl.symbols.join(' ')
+ end
+ end
+ end
+
+ #
+ # Tokens
+ #
+
+ def output_token(out)
+ out.print "------- Symbols -------\n\n"
+
+ out.print "**Nonterminals, with rules where they appear\n\n"
+ @grammar.each_nonterminal do |t|
+ tmp = <<SRC
+ %s (%d)
+ on right: %s
+ on left : %s
+SRC
+ out.printf tmp, t.to_s, t.ident,
+ symbol_locations(t.locate).join(' '),
+ symbol_locations(t.heads).join(' ')
+ end
+
+ out.print "\n**Terminals, with rules where they appear\n\n"
+ @grammar.each_terminal do |t|
+ out.printf " %s (%d) %s\n",
+ t.to_s, t.ident, symbol_locations(t.locate).join(' ')
+ end
+ end
+
+ def symbol_locations(locs)
+ locs.map {|loc| loc.rule.ident }.reject {|n| n == 0 }.uniq
+ end
+
+ end
+
+end # module Racc
diff --git a/lib/racc/parser-text.rb b/lib/racc/parser-text.rb
new file mode 100644
index 0000000000..0579f4ce9b
--- /dev/null
+++ b/lib/racc/parser-text.rb
@@ -0,0 +1,637 @@
+module Racc
+ PARSER_TEXT = <<'__end_of_file__'
+# frozen_string_literal: false
+#--
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+#
+# As a special exception, when this code is copied by Racc
+# into a Racc output file, you may use that output file
+# without restriction.
+#++
+
+require 'racc/info'
+
+unless defined?(NotImplementedError)
+ NotImplementedError = NotImplementError # :nodoc:
+end
+
+module Racc
+ class ParseError < StandardError; end
+end
+unless defined?(::ParseError)
+ ParseError = Racc::ParseError # :nodoc:
+end
+
+# Racc is a LALR(1) parser generator.
+# It is written in Ruby itself, and generates Ruby programs.
+#
+# == Command-line Reference
+#
+# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
+# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
+# [-v] [--verbose]
+# [-O<var>filename</var>] [--log-file=<var>filename</var>]
+# [-g] [--debug]
+# [-E] [--embedded]
+# [-l] [--no-line-convert]
+# [-c] [--line-convert-all]
+# [-a] [--no-omit-actions]
+# [-C] [--check-only]
+# [-S] [--output-status]
+# [--version] [--copyright] [--help] <var>grammarfile</var>
+#
+# [+grammarfile+]
+# Racc grammar file. Any extension is permitted.
+# [-o+outfile+, --output-file=+outfile+]
+# A filename for output. default is <+filename+>.tab.rb
+# [-O+filename+, --log-file=+filename+]
+# Place logging output in file +filename+.
+# Default log file name is <+filename+>.output.
+# [-e+rubypath+, --executable=+rubypath+]
+# output executable file(mode 755). where +path+ is the Ruby interpreter.
+# [-v, --verbose]
+# verbose mode. create +filename+.output file, like yacc's y.output file.
+# [-g, --debug]
+# add debug code to parser class. To display debuggin information,
+# use this '-g' option and set @yydebug true in parser class.
+# [-E, --embedded]
+# Output parser which doesn't need runtime files (racc/parser.rb).
+# [-C, --check-only]
+# Check syntax of racc grammar file and quit.
+# [-S, --output-status]
+# Print messages time to time while compiling.
+# [-l, --no-line-convert]
+# turns off line number converting.
+# [-c, --line-convert-all]
+# Convert line number of actions, inner, header and footer.
+# [-a, --no-omit-actions]
+# Call all actions, even if an action is empty.
+# [--version]
+# print Racc version and quit.
+# [--copyright]
+# Print copyright and quit.
+# [--help]
+# Print usage and quit.
+#
+# == Generating Parser Using Racc
+#
+# To compile Racc grammar file, simply type:
+#
+# $ racc parse.y
+#
+# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
+#
+# == Writing A Racc Grammar File
+#
+# If you want your own parser, you have to write a grammar file.
+# A grammar file contains the name of your parser class, grammar for the parser,
+# user code, and anything else.
+# When writing a grammar file, yacc's knowledge is helpful.
+# If you have not used yacc before, Racc is not too difficult.
+#
+# Here's an example Racc grammar file.
+#
+# class Calcparser
+# rule
+# target: exp { print val[0] }
+#
+# exp: exp '+' exp
+# | exp '*' exp
+# | '(' exp ')'
+# | NUMBER
+# end
+#
+# Racc grammar files resemble yacc files.
+# But (of course), this is Ruby code.
+# yacc's $$ is the 'result', $0, $1... is
+# an array called 'val', and $-1, $-2... is an array called '_values'.
+#
+# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
+# more information on grammar files.
+#
+# == Parser
+#
+# Then you must prepare the parse entry method. There are two types of
+# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
+#
+# Racc::Parser#do_parse is simple.
+#
+# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
+# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
+# EOF is [false, false].
+# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
+# If you want to change this, see the grammar reference.
+#
+# Racc::Parser#yyparse is little complicated, but useful.
+# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
+#
+# For example, <code>yyparse(obj, :scan)</code> causes
+# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
+#
+# == Debugging
+#
+# When debugging, "-v" or/and the "-g" option is helpful.
+#
+# "-v" creates verbose log file (.output).
+# "-g" creates a "Verbose Parser".
+# Verbose Parser prints the internal status when parsing.
+# But it's _not_ automatic.
+# You must use -g option and set +@yydebug+ to +true+ in order to get output.
+# -g option only creates the verbose parser.
+#
+# === Racc reported syntax error.
+#
+# Isn't there too many "end"?
+# grammar of racc file is changed in v0.10.
+#
+# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
+#
+# === Racc reported "XXXX conflicts".
+#
+# Try "racc -v xxxx.y".
+# It causes producing racc's internal log file, xxxx.output.
+#
+# === Generated parsers does not work correctly
+#
+# Try "racc -g xxxx.y".
+# This command let racc generate "debugging parser".
+# Then set @yydebug=true in your parser.
+# It produces a working log of your parser.
+#
+# == Re-distributing Racc runtime
+#
+# A parser, which is created by Racc, requires the Racc runtime module;
+# racc/parser.rb.
+#
+# Ruby 1.8.x comes with Racc runtime module,
+# you need NOT distribute Racc runtime files.
+#
+# If you want to include the Racc runtime module with your parser.
+# This can be done by using '-E' option:
+#
+# $ racc -E -omyparser.rb myparser.y
+#
+# This command creates myparser.rb which `includes' Racc runtime.
+# Only you must do is to distribute your parser file (myparser.rb).
+#
+# Note: parser.rb is ruby license, but your parser is not.
+# Your own parser is completely yours.
+module Racc
+
+ unless defined?(Racc_No_Extensions)
+ Racc_No_Extensions = false # :nodoc:
+ end
+
+ class Parser
+
+ Racc_Runtime_Version = ::Racc::VERSION
+ Racc_Runtime_Core_Version_R = ::Racc::VERSION
+
+ begin
+ if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
+ require 'jruby'
+ require 'racc/cparse-jruby.jar'
+ com.headius.racc.Cparse.new.load(JRuby.runtime, false)
+ else
+ require 'racc/cparse'
+ end
+
+ unless new.respond_to?(:_racc_do_parse_c, true)
+ raise LoadError, 'old cparse.so'
+ end
+ if Racc_No_Extensions
+ raise LoadError, 'selecting ruby version of racc runtime core'
+ end
+
+ Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
+ Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
+ Racc_Runtime_Type = 'c' # :nodoc:
+ rescue LoadError
+ Racc_Main_Parsing_Routine = :_racc_do_parse_rb
+ Racc_YY_Parse_Method = :_racc_yyparse_rb
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
+ Racc_Runtime_Type = 'ruby'
+ end
+
+ def Parser.racc_runtime_type # :nodoc:
+ Racc_Runtime_Type
+ end
+
+ def _racc_setup
+ @yydebug = false unless self.class::Racc_debug_parser
+ @yydebug = false unless defined?(@yydebug)
+ if @yydebug
+ @racc_debug_out = $stderr unless defined?(@racc_debug_out)
+ @racc_debug_out ||= $stderr
+ end
+ arg = self.class::Racc_arg
+ arg[13] = true if arg.size < 14
+ arg
+ end
+
+ def _racc_init_sysvars
+ @racc_state = [0]
+ @racc_tstack = []
+ @racc_vstack = []
+
+ @racc_t = nil
+ @racc_val = nil
+
+ @racc_read_next = true
+
+ @racc_user_yyerror = false
+ @racc_error_status = 0
+ end
+
+ # The entry point of the parser. This method is used with #next_token.
+ # If Racc wants to get token (and its value), calls next_token.
+ #
+ # Example:
+ # def parse
+ # @q = [[1,1],
+ # [2,2],
+ # [3,3],
+ # [false, '$']]
+ # do_parse
+ # end
+ #
+ # def next_token
+ # @q.shift
+ # end
+ class_eval %{
+ def do_parse
+ #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
+ end
+ }
+
+ # The method to fetch next token.
+ # If you use #do_parse method, you must implement #next_token.
+ #
+ # The format of return value is [TOKEN_SYMBOL, VALUE].
+ # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
+ # for 'IDENT'. ";" (String) for ';'.
+ #
+ # The final symbol (End of file) must be false.
+ def next_token
+ raise NotImplementedError, "#{self.class}\#next_token is not defined"
+ end
+
+ def _racc_do_parse_rb(arg, in_debug)
+ action_table, action_check, action_default, action_pointer,
+ _, _, _, _,
+ _, _, token_table, * = arg
+
+ _racc_init_sysvars
+ tok = act = i = nil
+
+ catch(:racc_end_parse) {
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ if @racc_read_next
+ if @racc_t != 0 # not EOF
+ tok, @racc_val = next_token()
+ unless tok # EOF
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ racc_read_token(@racc_t, tok, @racc_val) if @yydebug
+ @racc_read_next = false
+ end
+ end
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ else
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ }
+ end
+
+ # Another entry point for the parser.
+ # If you use this method, you must implement RECEIVER#METHOD_ID method.
+ #
+ # RECEIVER#METHOD_ID is a method to get next token.
+ # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
+ class_eval %{
+ def yyparse(recv, mid)
+ #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
+ end
+ }
+
+ def _racc_yyparse_rb(recv, mid, arg, c_debug)
+ action_table, action_check, action_default, action_pointer,
+ _, _, _, _,
+ _, _, token_table, * = arg
+
+ _racc_init_sysvars
+
+ catch(:racc_end_parse) {
+ until i = action_pointer[@racc_state[-1]]
+ while act = _racc_evalact(action_default[@racc_state[-1]], arg)
+ ;
+ end
+ end
+ recv.__send__(mid) do |tok, val|
+ unless tok
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ @racc_val = val
+ @racc_read_next = false
+
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+
+ while !(i = action_pointer[@racc_state[-1]]) ||
+ ! @racc_read_next ||
+ @racc_t == 0 # $
+ unless i and i += @racc_t and
+ i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ end
+ }
+ end
+
+ ###
+ ### common
+ ###
+
+ def _racc_evalact(act, arg)
+ action_table, action_check, _, action_pointer,
+ _, _, _, _,
+ _, _, _, shift_n,
+ reduce_n, * = arg
+ nerr = 0 # tmp
+
+ if act > 0 and act < shift_n
+ #
+ # shift
+ #
+ if @racc_error_status > 0
+ @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
+ end
+ @racc_vstack.push @racc_val
+ @racc_state.push act
+ @racc_read_next = true
+ if @yydebug
+ @racc_tstack.push @racc_t
+ racc_shift @racc_t, @racc_tstack, @racc_vstack
+ end
+
+ elsif act < 0 and act > -reduce_n
+ #
+ # reduce
+ #
+ code = catch(:racc_jump) {
+ @racc_state.push _racc_do_reduce(arg, act)
+ false
+ }
+ if code
+ case code
+ when 1 # yyerror
+ @racc_user_yyerror = true # user_yyerror
+ return -reduce_n
+ when 2 # yyaccept
+ return shift_n
+ else
+ raise '[Racc Bug] unknown jump code'
+ end
+ end
+
+ elsif act == shift_n
+ #
+ # accept
+ #
+ racc_accept if @yydebug
+ throw :racc_end_parse, @racc_vstack[0]
+
+ elsif act == -reduce_n
+ #
+ # error
+ #
+ case @racc_error_status
+ when 0
+ unless arg[21] # user_yyerror
+ nerr += 1
+ on_error @racc_t, @racc_val, @racc_vstack
+ end
+ when 3
+ if @racc_t == 0 # is $
+ # We're at EOF, and another error occurred immediately after
+ # attempting auto-recovery
+ throw :racc_end_parse, nil
+ end
+ @racc_read_next = true
+ end
+ @racc_user_yyerror = false
+ @racc_error_status = 3
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ i += 1 # error token
+ if i >= 0 and
+ (act = action_table[i]) and
+ action_check[i] == @racc_state[-1]
+ break
+ end
+ end
+ throw :racc_end_parse, nil if @racc_state.size <= 1
+ @racc_state.pop
+ @racc_vstack.pop
+ if @yydebug
+ @racc_tstack.pop
+ racc_e_pop @racc_state, @racc_tstack, @racc_vstack
+ end
+ end
+ return act
+
+ else
+ raise "[Racc Bug] unknown action #{act.inspect}"
+ end
+
+ racc_next_state(@racc_state[-1], @racc_state) if @yydebug
+
+ nil
+ end
+
+ def _racc_do_reduce(arg, act)
+ _, _, _, _,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, _, _,
+ _, use_result, * = arg
+
+ state = @racc_state
+ vstack = @racc_vstack
+ tstack = @racc_tstack
+
+ i = act * -3
+ len = reduce_table[i]
+ reduce_to = reduce_table[i+1]
+ method_id = reduce_table[i+2]
+ void_array = []
+
+ tmp_t = tstack[-len, len] if @yydebug
+ tmp_v = vstack[-len, len]
+ tstack[-len, len] = void_array if @yydebug
+ vstack[-len, len] = void_array
+ state[-len, len] = void_array
+
+ # tstack must be updated AFTER method call
+ if use_result
+ vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
+ else
+ vstack.push __send__(method_id, tmp_v, vstack)
+ end
+ tstack.push reduce_to
+
+ racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
+
+ k1 = reduce_to - nt_base
+ if i = goto_pointer[k1]
+ i += state[-1]
+ if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
+ return curstate
+ end
+ end
+ goto_default[k1]
+ end
+
+ # This method is called when a parse error is found.
+ #
+ # ERROR_TOKEN_ID is an internal ID of token which caused error.
+ # You can get string representation of this ID by calling
+ # #token_to_str.
+ #
+ # ERROR_VALUE is a value of error token.
+ #
+ # value_stack is a stack of symbol values.
+ # DO NOT MODIFY this object.
+ #
+ # This method raises ParseError by default.
+ #
+ # If this method returns, parsers enter "error recovering mode".
+ def on_error(t, val, vstack)
+ raise ParseError, sprintf("\nparse error on value %s (%s)",
+ val.inspect, token_to_str(t) || '?')
+ end
+
+ # Enter error recovering mode.
+ # This method does not call #on_error.
+ def yyerror
+ throw :racc_jump, 1
+ end
+
+ # Exit parser.
+ # Return value is +Symbol_Value_Stack[0]+.
+ def yyaccept
+ throw :racc_jump, 2
+ end
+
+ # Leave error recovering mode.
+ def yyerrok
+ @racc_error_status = 0
+ end
+
+ # For debugging output
+ def racc_read_token(t, tok, val)
+ @racc_debug_out.print 'read '
+ @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
+ @racc_debug_out.puts val.inspect
+ @racc_debug_out.puts
+ end
+
+ def racc_shift(tok, tstack, vstack)
+ @racc_debug_out.puts "shift #{racc_token2str tok}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_reduce(toks, sim, tstack, vstack)
+ out = @racc_debug_out
+ out.print 'reduce '
+ if toks.empty?
+ out.print ' <none>'
+ else
+ toks.each {|t| out.print ' ', racc_token2str(t) }
+ end
+ out.puts " --> #{racc_token2str(sim)}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_accept
+ @racc_debug_out.puts 'accept'
+ @racc_debug_out.puts
+ end
+
+ def racc_e_pop(state, tstack, vstack)
+ @racc_debug_out.puts 'error recovering mode: pop token'
+ racc_print_states state
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_next_state(curstate, state)
+ @racc_debug_out.puts "goto #{curstate}"
+ racc_print_states state
+ @racc_debug_out.puts
+ end
+
+ def racc_print_stacks(t, v)
+ out = @racc_debug_out
+ out.print ' ['
+ t.each_index do |i|
+ out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
+ end
+ out.puts ' ]'
+ end
+
+ def racc_print_states(s)
+ out = @racc_debug_out
+ out.print ' ['
+ s.each {|st| out.print ' ', st }
+ out.puts ' ]'
+ end
+
+ def racc_token2str(tok)
+ self.class::Racc_token_to_s_table[tok] or
+ raise "[Racc Bug] can't convert token #{tok} to string"
+ end
+
+ # Convert internal ID of token symbol to the string.
+ def token_to_str(t)
+ self.class::Racc_token_to_s_table[t]
+ end
+
+ end
+
+end
+
+__end_of_file__
+end
diff --git a/lib/racc/parser.rb b/lib/racc/parser.rb
new file mode 100644
index 0000000000..078bfef3e9
--- /dev/null
+++ b/lib/racc/parser.rb
@@ -0,0 +1,632 @@
+# frozen_string_literal: false
+#--
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+#
+# As a special exception, when this code is copied by Racc
+# into a Racc output file, you may use that output file
+# without restriction.
+#++
+
+require 'racc/info'
+
+unless defined?(NotImplementedError)
+ NotImplementedError = NotImplementError # :nodoc:
+end
+
+module Racc
+ class ParseError < StandardError; end
+end
+unless defined?(::ParseError)
+ ParseError = Racc::ParseError # :nodoc:
+end
+
+# Racc is a LALR(1) parser generator.
+# It is written in Ruby itself, and generates Ruby programs.
+#
+# == Command-line Reference
+#
+# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
+# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
+# [-v] [--verbose]
+# [-O<var>filename</var>] [--log-file=<var>filename</var>]
+# [-g] [--debug]
+# [-E] [--embedded]
+# [-l] [--no-line-convert]
+# [-c] [--line-convert-all]
+# [-a] [--no-omit-actions]
+# [-C] [--check-only]
+# [-S] [--output-status]
+# [--version] [--copyright] [--help] <var>grammarfile</var>
+#
+# [+grammarfile+]
+# Racc grammar file. Any extension is permitted.
+# [-o+outfile+, --output-file=+outfile+]
+# A filename for output. default is <+filename+>.tab.rb
+# [-O+filename+, --log-file=+filename+]
+# Place logging output in file +filename+.
+# Default log file name is <+filename+>.output.
+# [-e+rubypath+, --executable=+rubypath+]
+# output executable file(mode 755). where +path+ is the Ruby interpreter.
+# [-v, --verbose]
+# verbose mode. create +filename+.output file, like yacc's y.output file.
+# [-g, --debug]
+# add debug code to parser class. To display debuggin information,
+# use this '-g' option and set @yydebug true in parser class.
+# [-E, --embedded]
+# Output parser which doesn't need runtime files (racc/parser.rb).
+# [-C, --check-only]
+# Check syntax of racc grammar file and quit.
+# [-S, --output-status]
+# Print messages time to time while compiling.
+# [-l, --no-line-convert]
+# turns off line number converting.
+# [-c, --line-convert-all]
+# Convert line number of actions, inner, header and footer.
+# [-a, --no-omit-actions]
+# Call all actions, even if an action is empty.
+# [--version]
+# print Racc version and quit.
+# [--copyright]
+# Print copyright and quit.
+# [--help]
+# Print usage and quit.
+#
+# == Generating Parser Using Racc
+#
+# To compile Racc grammar file, simply type:
+#
+# $ racc parse.y
+#
+# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
+#
+# == Writing A Racc Grammar File
+#
+# If you want your own parser, you have to write a grammar file.
+# A grammar file contains the name of your parser class, grammar for the parser,
+# user code, and anything else.
+# When writing a grammar file, yacc's knowledge is helpful.
+# If you have not used yacc before, Racc is not too difficult.
+#
+# Here's an example Racc grammar file.
+#
+# class Calcparser
+# rule
+# target: exp { print val[0] }
+#
+# exp: exp '+' exp
+# | exp '*' exp
+# | '(' exp ')'
+# | NUMBER
+# end
+#
+# Racc grammar files resemble yacc files.
+# But (of course), this is Ruby code.
+# yacc's $$ is the 'result', $0, $1... is
+# an array called 'val', and $-1, $-2... is an array called '_values'.
+#
+# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
+# more information on grammar files.
+#
+# == Parser
+#
+# Then you must prepare the parse entry method. There are two types of
+# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
+#
+# Racc::Parser#do_parse is simple.
+#
+# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
+# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
+# EOF is [false, false].
+# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
+# If you want to change this, see the grammar reference.
+#
+# Racc::Parser#yyparse is little complicated, but useful.
+# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
+#
+# For example, <code>yyparse(obj, :scan)</code> causes
+# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
+#
+# == Debugging
+#
+# When debugging, "-v" or/and the "-g" option is helpful.
+#
+# "-v" creates verbose log file (.output).
+# "-g" creates a "Verbose Parser".
+# Verbose Parser prints the internal status when parsing.
+# But it's _not_ automatic.
+# You must use -g option and set +@yydebug+ to +true+ in order to get output.
+# -g option only creates the verbose parser.
+#
+# === Racc reported syntax error.
+#
+# Isn't there too many "end"?
+# grammar of racc file is changed in v0.10.
+#
+# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
+#
+# === Racc reported "XXXX conflicts".
+#
+# Try "racc -v xxxx.y".
+# It causes producing racc's internal log file, xxxx.output.
+#
+# === Generated parsers does not work correctly
+#
+# Try "racc -g xxxx.y".
+# This command let racc generate "debugging parser".
+# Then set @yydebug=true in your parser.
+# It produces a working log of your parser.
+#
+# == Re-distributing Racc runtime
+#
+# A parser, which is created by Racc, requires the Racc runtime module;
+# racc/parser.rb.
+#
+# Ruby 1.8.x comes with Racc runtime module,
+# you need NOT distribute Racc runtime files.
+#
+# If you want to include the Racc runtime module with your parser.
+# This can be done by using '-E' option:
+#
+# $ racc -E -omyparser.rb myparser.y
+#
+# This command creates myparser.rb which `includes' Racc runtime.
+# Only you must do is to distribute your parser file (myparser.rb).
+#
+# Note: parser.rb is ruby license, but your parser is not.
+# Your own parser is completely yours.
+module Racc
+
+ unless defined?(Racc_No_Extensions)
+ Racc_No_Extensions = false # :nodoc:
+ end
+
+ class Parser
+
+ Racc_Runtime_Version = ::Racc::VERSION
+ Racc_Runtime_Core_Version_R = ::Racc::VERSION
+
+ begin
+ if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
+ require 'jruby'
+ require 'racc/cparse-jruby.jar'
+ com.headius.racc.Cparse.new.load(JRuby.runtime, false)
+ else
+ require 'racc/cparse'
+ end
+
+ unless new.respond_to?(:_racc_do_parse_c, true)
+ raise LoadError, 'old cparse.so'
+ end
+ if Racc_No_Extensions
+ raise LoadError, 'selecting ruby version of racc runtime core'
+ end
+
+ Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
+ Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
+ Racc_Runtime_Type = 'c' # :nodoc:
+ rescue LoadError
+ Racc_Main_Parsing_Routine = :_racc_do_parse_rb
+ Racc_YY_Parse_Method = :_racc_yyparse_rb
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
+ Racc_Runtime_Type = 'ruby'
+ end
+
+ def Parser.racc_runtime_type # :nodoc:
+ Racc_Runtime_Type
+ end
+
+ def _racc_setup
+ @yydebug = false unless self.class::Racc_debug_parser
+ @yydebug = false unless defined?(@yydebug)
+ if @yydebug
+ @racc_debug_out = $stderr unless defined?(@racc_debug_out)
+ @racc_debug_out ||= $stderr
+ end
+ arg = self.class::Racc_arg
+ arg[13] = true if arg.size < 14
+ arg
+ end
+
+ def _racc_init_sysvars
+ @racc_state = [0]
+ @racc_tstack = []
+ @racc_vstack = []
+
+ @racc_t = nil
+ @racc_val = nil
+
+ @racc_read_next = true
+
+ @racc_user_yyerror = false
+ @racc_error_status = 0
+ end
+
+ # The entry point of the parser. This method is used with #next_token.
+ # If Racc wants to get token (and its value), calls next_token.
+ #
+ # Example:
+ # def parse
+ # @q = [[1,1],
+ # [2,2],
+ # [3,3],
+ # [false, '$']]
+ # do_parse
+ # end
+ #
+ # def next_token
+ # @q.shift
+ # end
+ class_eval %{
+ def do_parse
+ #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
+ end
+ }
+
+ # The method to fetch next token.
+ # If you use #do_parse method, you must implement #next_token.
+ #
+ # The format of return value is [TOKEN_SYMBOL, VALUE].
+ # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
+ # for 'IDENT'. ";" (String) for ';'.
+ #
+ # The final symbol (End of file) must be false.
+ def next_token
+ raise NotImplementedError, "#{self.class}\#next_token is not defined"
+ end
+
+ def _racc_do_parse_rb(arg, in_debug)
+ action_table, action_check, action_default, action_pointer,
+ _, _, _, _,
+ _, _, token_table, * = arg
+
+ _racc_init_sysvars
+ tok = act = i = nil
+
+ catch(:racc_end_parse) {
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ if @racc_read_next
+ if @racc_t != 0 # not EOF
+ tok, @racc_val = next_token()
+ unless tok # EOF
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ racc_read_token(@racc_t, tok, @racc_val) if @yydebug
+ @racc_read_next = false
+ end
+ end
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ else
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ }
+ end
+
+ # Another entry point for the parser.
+ # If you use this method, you must implement RECEIVER#METHOD_ID method.
+ #
+ # RECEIVER#METHOD_ID is a method to get next token.
+ # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
+ class_eval %{
+ def yyparse(recv, mid)
+ #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
+ end
+ }
+
+ def _racc_yyparse_rb(recv, mid, arg, c_debug)
+ action_table, action_check, action_default, action_pointer,
+ _, _, _, _,
+ _, _, token_table, * = arg
+
+ _racc_init_sysvars
+
+ catch(:racc_end_parse) {
+ until i = action_pointer[@racc_state[-1]]
+ while act = _racc_evalact(action_default[@racc_state[-1]], arg)
+ ;
+ end
+ end
+ recv.__send__(mid) do |tok, val|
+ unless tok
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ @racc_val = val
+ @racc_read_next = false
+
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+
+ while !(i = action_pointer[@racc_state[-1]]) ||
+ ! @racc_read_next ||
+ @racc_t == 0 # $
+ unless i and i += @racc_t and
+ i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ end
+ }
+ end
+
+ ###
+ ### common
+ ###
+
+ def _racc_evalact(act, arg)
+ action_table, action_check, _, action_pointer,
+ _, _, _, _,
+ _, _, _, shift_n,
+ reduce_n, * = arg
+ nerr = 0 # tmp
+
+ if act > 0 and act < shift_n
+ #
+ # shift
+ #
+ if @racc_error_status > 0
+ @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
+ end
+ @racc_vstack.push @racc_val
+ @racc_state.push act
+ @racc_read_next = true
+ if @yydebug
+ @racc_tstack.push @racc_t
+ racc_shift @racc_t, @racc_tstack, @racc_vstack
+ end
+
+ elsif act < 0 and act > -reduce_n
+ #
+ # reduce
+ #
+ code = catch(:racc_jump) {
+ @racc_state.push _racc_do_reduce(arg, act)
+ false
+ }
+ if code
+ case code
+ when 1 # yyerror
+ @racc_user_yyerror = true # user_yyerror
+ return -reduce_n
+ when 2 # yyaccept
+ return shift_n
+ else
+ raise '[Racc Bug] unknown jump code'
+ end
+ end
+
+ elsif act == shift_n
+ #
+ # accept
+ #
+ racc_accept if @yydebug
+ throw :racc_end_parse, @racc_vstack[0]
+
+ elsif act == -reduce_n
+ #
+ # error
+ #
+ case @racc_error_status
+ when 0
+ unless arg[21] # user_yyerror
+ nerr += 1
+ on_error @racc_t, @racc_val, @racc_vstack
+ end
+ when 3
+ if @racc_t == 0 # is $
+ # We're at EOF, and another error occurred immediately after
+ # attempting auto-recovery
+ throw :racc_end_parse, nil
+ end
+ @racc_read_next = true
+ end
+ @racc_user_yyerror = false
+ @racc_error_status = 3
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ i += 1 # error token
+ if i >= 0 and
+ (act = action_table[i]) and
+ action_check[i] == @racc_state[-1]
+ break
+ end
+ end
+ throw :racc_end_parse, nil if @racc_state.size <= 1
+ @racc_state.pop
+ @racc_vstack.pop
+ if @yydebug
+ @racc_tstack.pop
+ racc_e_pop @racc_state, @racc_tstack, @racc_vstack
+ end
+ end
+ return act
+
+ else
+ raise "[Racc Bug] unknown action #{act.inspect}"
+ end
+
+ racc_next_state(@racc_state[-1], @racc_state) if @yydebug
+
+ nil
+ end
+
+ def _racc_do_reduce(arg, act)
+ _, _, _, _,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, _, _,
+ _, use_result, * = arg
+
+ state = @racc_state
+ vstack = @racc_vstack
+ tstack = @racc_tstack
+
+ i = act * -3
+ len = reduce_table[i]
+ reduce_to = reduce_table[i+1]
+ method_id = reduce_table[i+2]
+ void_array = []
+
+ tmp_t = tstack[-len, len] if @yydebug
+ tmp_v = vstack[-len, len]
+ tstack[-len, len] = void_array if @yydebug
+ vstack[-len, len] = void_array
+ state[-len, len] = void_array
+
+ # tstack must be updated AFTER method call
+ if use_result
+ vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
+ else
+ vstack.push __send__(method_id, tmp_v, vstack)
+ end
+ tstack.push reduce_to
+
+ racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
+
+ k1 = reduce_to - nt_base
+ if i = goto_pointer[k1]
+ i += state[-1]
+ if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
+ return curstate
+ end
+ end
+ goto_default[k1]
+ end
+
+ # This method is called when a parse error is found.
+ #
+ # ERROR_TOKEN_ID is an internal ID of token which caused error.
+ # You can get string representation of this ID by calling
+ # #token_to_str.
+ #
+ # ERROR_VALUE is a value of error token.
+ #
+ # value_stack is a stack of symbol values.
+ # DO NOT MODIFY this object.
+ #
+ # This method raises ParseError by default.
+ #
+ # If this method returns, parsers enter "error recovering mode".
+ def on_error(t, val, vstack)
+ raise ParseError, sprintf("\nparse error on value %s (%s)",
+ val.inspect, token_to_str(t) || '?')
+ end
+
+ # Enter error recovering mode.
+ # This method does not call #on_error.
+ def yyerror
+ throw :racc_jump, 1
+ end
+
+ # Exit parser.
+ # Return value is +Symbol_Value_Stack[0]+.
+ def yyaccept
+ throw :racc_jump, 2
+ end
+
+ # Leave error recovering mode.
+ def yyerrok
+ @racc_error_status = 0
+ end
+
+ # For debugging output
+ def racc_read_token(t, tok, val)
+ @racc_debug_out.print 'read '
+ @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
+ @racc_debug_out.puts val.inspect
+ @racc_debug_out.puts
+ end
+
+ def racc_shift(tok, tstack, vstack)
+ @racc_debug_out.puts "shift #{racc_token2str tok}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_reduce(toks, sim, tstack, vstack)
+ out = @racc_debug_out
+ out.print 'reduce '
+ if toks.empty?
+ out.print ' <none>'
+ else
+ toks.each {|t| out.print ' ', racc_token2str(t) }
+ end
+ out.puts " --> #{racc_token2str(sim)}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_accept
+ @racc_debug_out.puts 'accept'
+ @racc_debug_out.puts
+ end
+
+ def racc_e_pop(state, tstack, vstack)
+ @racc_debug_out.puts 'error recovering mode: pop token'
+ racc_print_states state
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_next_state(curstate, state)
+ @racc_debug_out.puts "goto #{curstate}"
+ racc_print_states state
+ @racc_debug_out.puts
+ end
+
+ def racc_print_stacks(t, v)
+ out = @racc_debug_out
+ out.print ' ['
+ t.each_index do |i|
+ out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
+ end
+ out.puts ' ]'
+ end
+
+ def racc_print_states(s)
+ out = @racc_debug_out
+ out.print ' ['
+ s.each {|st| out.print ' ', st }
+ out.puts ' ]'
+ end
+
+ def racc_token2str(tok)
+ self.class::Racc_token_to_s_table[tok] or
+ raise "[Racc Bug] can't convert token #{tok} to string"
+ end
+
+ # Convert internal ID of token symbol to the string.
+ def token_to_str(t)
+ self.class::Racc_token_to_s_table[t]
+ end
+
+ end
+
+end
diff --git a/lib/racc/parserfilegenerator.rb b/lib/racc/parserfilegenerator.rb
new file mode 100644
index 0000000000..7131026929
--- /dev/null
+++ b/lib/racc/parserfilegenerator.rb
@@ -0,0 +1,468 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/compat'
+require 'racc/sourcetext'
+require 'racc/parser-text'
+require 'rbconfig'
+
+module Racc
+
+ class ParserFileGenerator
+
+ class Params
+ def self.bool_attr(name)
+ module_eval(<<-End)
+ def #{name}?
+ @#{name}
+ end
+
+ def #{name}=(b)
+ @#{name} = b
+ end
+ End
+ end
+
+ attr_accessor :filename
+ attr_accessor :classname
+ attr_accessor :superclass
+ bool_attr :omit_action_call
+ bool_attr :result_var
+ attr_accessor :header
+ attr_accessor :inner
+ attr_accessor :footer
+
+ bool_attr :debug_parser
+ bool_attr :convert_line
+ bool_attr :convert_line_all
+ bool_attr :embed_runtime
+ bool_attr :make_executable
+ attr_accessor :interpreter
+
+ def initialize
+ # Parameters derived from parser
+ self.filename = nil
+ self.classname = nil
+ self.superclass = 'Racc::Parser'
+ self.omit_action_call = true
+ self.result_var = true
+ self.header = []
+ self.inner = []
+ self.footer = []
+
+ # Parameters derived from command line options
+ self.debug_parser = false
+ self.convert_line = true
+ self.convert_line_all = false
+ self.embed_runtime = false
+ self.make_executable = false
+ self.interpreter = nil
+ end
+ end
+
+ def initialize(states, params)
+ @states = states
+ @grammar = states.grammar
+ @params = params
+ end
+
+ def generate_parser
+ string_io = StringIO.new
+
+ init_line_conversion_system
+ @f = string_io
+ parser_file
+
+ string_io.rewind
+ string_io.read
+ end
+
+ def generate_parser_file(destpath)
+ init_line_conversion_system
+ File.open(destpath, 'w') {|f|
+ @f = f
+ parser_file
+ }
+ File.chmod 0755, destpath if @params.make_executable?
+ end
+
+ private
+
+ def parser_file
+ shebang @params.interpreter if @params.make_executable?
+ notice
+ line
+ if @params.embed_runtime?
+ embed_library runtime_source()
+ else
+ require 'racc/parser.rb'
+ end
+ header
+ parser_class(@params.classname, @params.superclass) {
+ inner
+ state_transition_table
+ }
+ footer
+ end
+
+ c = ::RbConfig::CONFIG
+ RUBY_PATH = "#{c['bindir']}/#{c['ruby_install_name']}#{c['EXEEXT']}"
+
+ def shebang(path)
+ line '#!' + (path == 'ruby' ? RUBY_PATH : path)
+ end
+
+ def notice
+ line %q[#]
+ line %q[# DO NOT MODIFY!!!!]
+ line %Q[# This file is automatically generated by Racc #{Racc::Version}]
+ line %Q[# from Racc grammar file "#{@params.filename}".]
+ line %q[#]
+ end
+
+ def runtime_source
+ SourceText.new(::Racc::PARSER_TEXT, 'racc/parser.rb', 1)
+ end
+
+ def embed_library(src)
+ line %[###### #{src.filename} begin]
+ line %[unless $".index '#{src.filename}']
+ line %[$".push '#{src.filename}']
+ put src, @params.convert_line?
+ line %[end]
+ line %[###### #{src.filename} end]
+ end
+
+ def require(feature)
+ line "require '#{feature}'"
+ end
+
+ def parser_class(classname, superclass)
+ mods = classname.split('::')
+ classid = mods.pop
+ mods.each do |mod|
+ indent; line "module #{mod}"
+ cref_push mod
+ end
+ indent; line "class #{classid} < #{superclass}"
+ cref_push classid
+ yield
+ cref_pop
+ indent; line "end \# class #{classid}"
+ mods.reverse_each do |mod|
+ cref_pop
+ indent; line "end \# module #{mod}"
+ end
+ end
+
+ def header
+ @params.header.each do |src|
+ line
+ put src, @params.convert_line_all?
+ end
+ end
+
+ def inner
+ @params.inner.each do |src|
+ line
+ put src, @params.convert_line?
+ end
+ end
+
+ def footer
+ @params.footer.each do |src|
+ line
+ put src, @params.convert_line_all?
+ end
+ end
+
+ # Low Level Routines
+
+ def put(src, convert_line = false)
+ if convert_line
+ replace_location(src) {
+ @f.puts src.text
+ }
+ else
+ @f.puts src.text
+ end
+ end
+
+ def line(str = '')
+ @f.puts str
+ end
+
+ def init_line_conversion_system
+ @cref = []
+ @used_separator = {}
+ end
+
+ def cref_push(name)
+ @cref.push name
+ end
+
+ def cref_pop
+ @cref.pop
+ end
+
+ def indent
+ @f.print ' ' * @cref.size
+ end
+
+ def toplevel?
+ @cref.empty?
+ end
+
+ def replace_location(src)
+ sep = make_separator(src)
+ @f.print 'self.class.' if toplevel?
+ @f.puts "module_eval(<<'#{sep}', '#{src.filename}', #{src.lineno})"
+ yield
+ @f.puts sep
+ end
+
+ def make_separator(src)
+ sep = unique_separator(src.filename)
+ sep *= 2 while src.text.index(sep)
+ sep
+ end
+
+ def unique_separator(id)
+ sep = String.new "...end #{id}/module_eval..."
+ while @used_separator.key?(sep)
+ sep.concat sprintf('%02x', rand(255))
+ end
+ @used_separator[sep] = true
+ sep
+ end
+
+ #
+ # State Transition Table Serialization
+ #
+
+ public
+
+ def put_state_transition_table(f)
+ @f = f
+ state_transition_table
+ end
+
+ private
+
+ def state_transition_table
+ table = @states.state_transition_table
+ table.use_result_var = @params.result_var?
+ table.debug_parser = @params.debug_parser?
+
+ line "##### State transition tables begin ###"
+ line
+ integer_list 'racc_action_table', table.action_table
+ line
+ integer_list 'racc_action_check', table.action_check
+ line
+ integer_list 'racc_action_pointer', table.action_pointer
+ line
+ integer_list 'racc_action_default', table.action_default
+ line
+ integer_list 'racc_goto_table', table.goto_table
+ line
+ integer_list 'racc_goto_check', table.goto_check
+ line
+ integer_list 'racc_goto_pointer', table.goto_pointer
+ line
+ integer_list 'racc_goto_default', table.goto_default
+ line
+ i_i_sym_list 'racc_reduce_table', table.reduce_table
+ line
+ line "racc_reduce_n = #{table.reduce_n}"
+ line
+ line "racc_shift_n = #{table.shift_n}"
+ line
+ sym_int_hash 'racc_token_table', table.token_table
+ line
+ line "racc_nt_base = #{table.nt_base}"
+ line
+ line "racc_use_result_var = #{table.use_result_var}"
+ line
+ @f.print(unindent_auto(<<-End))
+ 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 ]
+ End
+ line
+ string_list 'Racc_token_to_s_table', table.token_to_s_table
+ line
+ line "Racc_debug_parser = #{table.debug_parser}"
+ line
+ line '##### State transition tables end #####'
+ actions
+ end
+
+ def integer_list(name, table)
+ sep = ''
+ line "#{name} = ["
+ table.each_slice(10) do |ns|
+ @f.print sep; sep = ",\n"
+ @f.print ns.map {|n| sprintf('%6s', n ? n.to_s : 'nil') }.join(',')
+ end
+ line ' ]'
+ end
+
+ def i_i_sym_list(name, table)
+ sep = ''
+ line "#{name} = ["
+ table.each_slice(3) do |len, target, mid|
+ @f.print sep; sep = ",\n"
+ @f.printf ' %d, %d, %s', len, target, mid.inspect
+ end
+ line " ]"
+ end
+
+ def sym_int_hash(name, h)
+ sep = "\n"
+ @f.print "#{name} = {"
+ h.to_a.sort_by {|sym, i| i }.each do |sym, i|
+ @f.print sep; sep = ",\n"
+ @f.printf " %s => %d", sym.serialize, i
+ end
+ line " }"
+ end
+
+ def string_list(name, list)
+ sep = " "
+ line "#{name} = ["
+ list.each do |s|
+ @f.print sep; sep = ",\n "
+ @f.print s.dump
+ end
+ line ' ]'
+ end
+
+ def actions
+ @grammar.each do |rule|
+ unless rule.action.source?
+ raise "racc: fatal: cannot generate parser file when any action is a Proc"
+ end
+ end
+
+ if @params.result_var?
+ decl = ', result'
+ retval = "\n result"
+ default_body = ''
+ else
+ decl = ''
+ retval = ''
+ default_body = 'val[0]'
+ end
+ @grammar.each do |rule|
+ line
+ if rule.action.empty? and @params.omit_action_call?
+ line "# reduce #{rule.ident} omitted"
+ else
+ src0 = rule.action.source || SourceText.new(default_body, __FILE__, 0)
+ if @params.convert_line?
+ src = remove_blank_lines(src0)
+ delim = make_delimiter(src.text)
+ @f.printf unindent_auto(<<-End),
+ module_eval(<<'%s', '%s', %d)
+ def _reduce_%d(val, _values%s)
+ %s%s
+ end
+ %s
+ End
+ delim, src.filename, src.lineno - 1,
+ rule.ident, decl,
+ src.text, retval,
+ delim
+ else
+ src = remove_blank_lines(src0)
+ @f.printf unindent_auto(<<-End),
+ def _reduce_%d(val, _values%s)
+ %s%s
+ end
+ End
+ rule.ident, decl,
+ src.text, retval
+ end
+ end
+ end
+ line
+ @f.printf unindent_auto(<<-'End'), decl
+ def _reduce_none(val, _values%s)
+ val[0]
+ end
+ End
+ line
+ end
+
+ def remove_blank_lines(src)
+ body = src.text.dup
+ line = src.lineno
+ while body.slice!(/\A[ \t\f]*(?:\n|\r\n|\r)/)
+ line += 1
+ end
+ SourceText.new(body, src.filename, line)
+ end
+
+ def make_delimiter(body)
+ delim = '.,.,'
+ while body.index(delim)
+ delim *= 2
+ end
+ delim
+ end
+
+ def unindent_auto(str)
+ lines = str.lines.to_a
+ n = minimum_indent(lines)
+ lines.map {|line| detab(line).sub(indent_re(n), '').rstrip + "\n" }.join('')
+ end
+
+ def minimum_indent(lines)
+ lines.map {|line| n_indent(line) }.min
+ end
+
+ def n_indent(line)
+ line.slice(/\A\s+/).size
+ end
+
+ RE_CACHE = {}
+
+ def indent_re(n)
+ RE_CACHE[n] ||= /\A {#{n}}/
+ end
+
+ def detab(str, ts = 8)
+ add = 0
+ len = nil
+ str.gsub(/\t/) {
+ len = ts - ($`.size + add) % ts
+ add += len - 1
+ ' ' * len
+ }
+ end
+
+ end
+
+end
diff --git a/lib/racc/racc.gemspec b/lib/racc/racc.gemspec
new file mode 100644
index 0000000000..1095c8f47e
--- /dev/null
+++ b/lib/racc/racc.gemspec
@@ -0,0 +1,58 @@
+# -*- encoding: utf-8 -*-
+
+begin
+ require_relative "lib/racc/info"
+rescue LoadError # Fallback to load version file in ruby core repository
+ require_relative "info"
+end
+
+Gem::Specification.new do |s|
+ s.name = "racc"
+ s.version = Racc::VERSION
+ s.summary = "Racc is a LALR(1) parser generator"
+ s.description = <<DESC
+Racc is a LALR(1) parser generator.
+ It is written in Ruby itself, and generates Ruby program.
+
+ NOTE: Ruby 1.8.x comes with Racc runtime module. You
+ can run your parsers generated by racc 1.4.x out of the
+ box.
+DESC
+ s.authors = ["Minero Aoki", "Aaron Patterson"]
+ s.email = [nil, "aaron@tenderlovemaking.com"]
+ s.homepage = "https://github.com/ruby/racc"
+ s.licenses = ["Ruby", "BSD-2-Clause"]
+ s.executables = ["racc"]
+ s.files = [
+ "COPYING", "ChangeLog", "TODO",
+ "README.ja.rdoc", "README.rdoc", "bin/racc",
+ "ext/racc/MANIFEST",
+ "ext/racc/cparse/cparse.c",
+ "ext/racc/cparse/extconf.rb",
+ "lib/racc.rb", "lib/racc/compat.rb",
+ "lib/racc/debugflags.rb", "lib/racc/exception.rb",
+ "lib/racc/grammar.rb", "lib/racc/grammarfileparser.rb",
+ "lib/racc/info.rb", "lib/racc/iset.rb",
+ "lib/racc/logfilegenerator.rb", "lib/racc/parser-text.rb",
+ "lib/racc/parser.rb", "lib/racc/parserfilegenerator.rb",
+ "lib/racc/sourcetext.rb",
+ "lib/racc/state.rb", "lib/racc/statetransitiontable.rb",
+ "lib/racc/static.rb",
+ "doc/en/NEWS.en.rdoc", "doc/en/grammar2.en.rdoc",
+ "doc/en/grammar.en.rdoc", "doc/ja/NEWS.ja.rdoc",
+ "doc/ja/command.ja.html", "doc/ja/debug.ja.rdoc",
+ "doc/ja/grammar.ja.rdoc", "doc/ja/index.ja.html",
+ "doc/ja/parser.ja.rdoc", "doc/ja/usage.ja.html",
+ ]
+ s.require_paths = ["lib"]
+ s.required_ruby_version = ">= 2.5"
+ s.rdoc_options = ["--main", "README.rdoc"]
+ s.extra_rdoc_files = ["README.ja.rdoc", "README.rdoc"]
+
+ if RUBY_PLATFORM =~ /java/
+ s.files << 'lib/racc/cparse-jruby.jar'
+ s.platform = 'java'
+ else
+ s.extensions = ["ext/racc/cparse/extconf.rb"]
+ end
+end
diff --git a/lib/racc/sourcetext.rb b/lib/racc/sourcetext.rb
new file mode 100644
index 0000000000..de52dcae9b
--- /dev/null
+++ b/lib/racc/sourcetext.rb
@@ -0,0 +1,35 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+module Racc
+
+ class SourceText
+ def initialize(text, filename, lineno)
+ @text = text
+ @filename = filename
+ @lineno = lineno
+ end
+
+ attr_reader :text
+ attr_reader :filename
+ attr_reader :lineno
+
+ def to_s
+ "#<SourceText #{location()}>"
+ end
+
+ def location
+ "#{@filename}:#{@lineno}"
+ end
+ end
+
+end
diff --git a/lib/racc/state.rb b/lib/racc/state.rb
new file mode 100644
index 0000000000..f85809fbeb
--- /dev/null
+++ b/lib/racc/state.rb
@@ -0,0 +1,972 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/iset'
+require 'racc/statetransitiontable'
+require 'racc/exception'
+require 'forwardable'
+
+module Racc
+
+ # A table of LALR states.
+ class States
+
+ include Enumerable
+
+ def initialize(grammar, debug_flags = DebugFlags.new)
+ @grammar = grammar
+ @symboltable = grammar.symboltable
+ @d_state = debug_flags.state
+ @d_la = debug_flags.la
+ @d_prec = debug_flags.prec
+ @states = []
+ @statecache = {}
+ @actions = ActionTable.new(@grammar, self)
+ @nfa_computed = false
+ @dfa_computed = false
+ end
+
+ attr_reader :grammar
+ attr_reader :actions
+
+ def size
+ @states.size
+ end
+
+ def inspect
+ '#<state table>'
+ end
+
+ alias to_s inspect
+
+ def [](i)
+ @states[i]
+ end
+
+ def each_state(&block)
+ @states.each(&block)
+ end
+
+ alias each each_state
+
+ def each_index(&block)
+ @states.each_index(&block)
+ end
+
+ extend Forwardable
+
+ def_delegator "@actions", :shift_n
+ def_delegator "@actions", :reduce_n
+ def_delegator "@actions", :nt_base
+
+ def should_report_srconflict?
+ srconflict_exist? and
+ (n_srconflicts() != @grammar.n_expected_srconflicts)
+ end
+
+ def srconflict_exist?
+ n_srconflicts() != 0
+ end
+
+ def n_srconflicts
+ @n_srconflicts ||= inject(0) {|sum, st| sum + st.n_srconflicts }
+ end
+
+ def rrconflict_exist?
+ n_rrconflicts() != 0
+ end
+
+ def n_rrconflicts
+ @n_rrconflicts ||= inject(0) {|sum, st| sum + st.n_rrconflicts }
+ end
+
+ def state_transition_table
+ @state_transition_table ||= StateTransitionTable.generate(self.dfa)
+ end
+
+ #
+ # NFA (Non-deterministic Finite Automaton) Computation
+ #
+
+ public
+
+ def nfa
+ return self if @nfa_computed
+ compute_nfa
+ @nfa_computed = true
+ self
+ end
+
+ private
+
+ def compute_nfa
+ @grammar.init
+ # add state 0
+ core_to_state [ @grammar[0].ptrs[0] ]
+ # generate LALR states
+ cur = 0
+ @gotos = []
+ while cur < @states.size
+ generate_states @states[cur] # state is added here
+ cur += 1
+ end
+ @actions.init
+ end
+
+ def generate_states(state)
+ puts "dstate: #{state}" if @d_state
+
+ table = {}
+ state.closure.each do |ptr|
+ if sym = ptr.dereference
+ addsym table, sym, ptr.next
+ end
+ end
+ table.each do |sym, core|
+ puts "dstate: sym=#{sym} ncore=#{core}" if @d_state
+
+ dest = core_to_state(core.to_a)
+ state.goto_table[sym] = dest
+ id = sym.nonterminal?() ? @gotos.size : nil
+ g = Goto.new(id, sym, state, dest)
+ @gotos.push g if sym.nonterminal?
+ state.gotos[sym] = g
+ puts "dstate: #{state.ident} --#{sym}--> #{dest.ident}" if @d_state
+
+ # check infinite recursion
+ if state.ident == dest.ident and state.closure.size == 1
+ raise CompileError,
+ sprintf("Infinite recursion: state %d, with rule %d",
+ state.ident, state.ptrs[0].rule.ident)
+ end
+ end
+ end
+
+ def addsym(table, sym, ptr)
+ unless s = table[sym]
+ table[sym] = s = ISet.new
+ end
+ s.add ptr
+ end
+
+ def core_to_state(core)
+ #
+ # convert CORE to a State object.
+ # If matching state does not exist, create it and add to the table.
+ #
+
+ k = fingerprint(core)
+ unless dest = @statecache[k]
+ # not registered yet
+ dest = State.new(@states.size, core)
+ @states.push dest
+
+ @statecache[k] = dest
+
+ puts "core_to_state: create state ID #{dest.ident}" if @d_state
+ else
+ if @d_state
+ puts "core_to_state: dest is cached ID #{dest.ident}"
+ puts "core_to_state: dest core #{dest.core.join(' ')}"
+ end
+ end
+
+ dest
+ end
+
+ def fingerprint(arr)
+ arr.map {|i| i.ident }.pack('L*')
+ end
+
+ #
+ # DFA (Deterministic Finite Automaton) Generation
+ #
+
+ public
+
+ def dfa
+ return self if @dfa_computed
+ nfa
+ compute_dfa
+ @dfa_computed = true
+ self
+ end
+
+ private
+
+ def compute_dfa
+ la = lookahead()
+ @states.each do |state|
+ state.la = la
+ resolve state
+ end
+ set_accept
+ @states.each do |state|
+ pack state
+ end
+ check_useless
+ end
+
+ def lookahead
+ #
+ # lookahead algorithm ver.3 -- from bison 1.26
+ #
+
+ gotos = @gotos
+ if @d_la
+ puts "\n--- goto ---"
+ gotos.each_with_index {|g, i| print i, ' '; p g }
+ end
+
+ ### initialize_LA()
+ ### set_goto_map()
+ la_rules = []
+ @states.each do |state|
+ state.check_la la_rules
+ end
+
+ ### initialize_F()
+ f = create_tmap(gotos.size)
+ reads = []
+ edge = []
+ gotos.each do |goto|
+ goto.to_state.goto_table.each do |t, st|
+ if t.terminal?
+ f[goto.ident] |= (1 << t.ident)
+ elsif t.nullable?
+ edge.push goto.to_state.gotos[t].ident
+ end
+ end
+ if edge.empty?
+ reads.push nil
+ else
+ reads.push edge
+ edge = []
+ end
+ end
+ digraph f, reads
+ if @d_la
+ puts "\n--- F1 (reads) ---"
+ print_tab gotos, reads, f
+ end
+
+ ### build_relations()
+ ### compute_FOLLOWS
+ path = nil
+ edge = []
+ lookback = Array.new(la_rules.size, nil)
+ includes = []
+ gotos.each do |goto|
+ goto.symbol.heads.each do |ptr|
+ path = record_path(goto.from_state, ptr.rule)
+ lastgoto = path.last
+ st = lastgoto ? lastgoto.to_state : goto.from_state
+ if st.conflict?
+ addrel lookback, st.rruleid(ptr.rule), goto
+ end
+ path.reverse_each do |g|
+ break if g.symbol.terminal?
+ edge.push g.ident
+ break unless g.symbol.nullable?
+ end
+ end
+ if edge.empty?
+ includes.push nil
+ else
+ includes.push edge
+ edge = []
+ end
+ end
+ includes = transpose(includes)
+ digraph f, includes
+ if @d_la
+ puts "\n--- F2 (includes) ---"
+ print_tab gotos, includes, f
+ end
+
+ ### compute_lookaheads
+ la = create_tmap(la_rules.size)
+ lookback.each_with_index do |arr, i|
+ if arr
+ arr.each do |g|
+ la[i] |= f[g.ident]
+ end
+ end
+ end
+ if @d_la
+ puts "\n--- LA (lookback) ---"
+ print_tab la_rules, lookback, la
+ end
+
+ la
+ end
+
+ def create_tmap(size)
+ Array.new(size, 0) # use Integer as bitmap
+ end
+
+ def addrel(tbl, i, item)
+ if a = tbl[i]
+ a.push item
+ else
+ tbl[i] = [item]
+ end
+ end
+
+ def record_path(begst, rule)
+ st = begst
+ path = []
+ rule.symbols.each do |t|
+ goto = st.gotos[t]
+ path.push goto
+ st = goto.to_state
+ end
+ path
+ end
+
+ def transpose(rel)
+ new = Array.new(rel.size, nil)
+ rel.each_with_index do |arr, idx|
+ if arr
+ arr.each do |i|
+ addrel new, i, idx
+ end
+ end
+ end
+ new
+ end
+
+ def digraph(map, relation)
+ n = relation.size
+ index = Array.new(n, nil)
+ vertices = []
+ @infinity = n + 2
+
+ index.each_index do |i|
+ if not index[i] and relation[i]
+ traverse i, index, vertices, map, relation
+ end
+ end
+ end
+
+ def traverse(i, index, vertices, map, relation)
+ vertices.push i
+ index[i] = height = vertices.size
+
+ if rp = relation[i]
+ rp.each do |proci|
+ unless index[proci]
+ traverse proci, index, vertices, map, relation
+ end
+ if index[i] > index[proci]
+ # circulative recursion !!!
+ index[i] = index[proci]
+ end
+ map[i] |= map[proci]
+ end
+ end
+
+ if index[i] == height
+ while true
+ proci = vertices.pop
+ index[proci] = @infinity
+ break if i == proci
+
+ map[proci] |= map[i]
+ end
+ end
+ end
+
+ # for debug
+ def print_atab(idx, tab)
+ tab.each_with_index do |i,ii|
+ printf '%-20s', idx[ii].inspect
+ p i
+ end
+ end
+
+ def print_tab(idx, rel, tab)
+ tab.each_with_index do |bin,i|
+ print i, ' ', idx[i].inspect, ' << '; p rel[i]
+ print ' '
+ each_t(@symboltable, bin) {|t| print ' ', t }
+ puts
+ end
+ end
+
+ # for debug
+ def print_tab_i(idx, rel, tab, i)
+ bin = tab[i]
+ print i, ' ', idx[i].inspect, ' << '; p rel[i]
+ print ' '
+ each_t(@symboltable, bin) {|t| print ' ', t }
+ end
+
+ # for debug
+ def printb(i)
+ each_t(@symboltable, i) do |t|
+ print t, ' '
+ end
+ puts
+ end
+
+ def each_t(tbl, set)
+ 0.upto( set.size ) do |i|
+ (0..7).each do |ii|
+ if set[idx = i * 8 + ii] == 1
+ yield tbl[idx]
+ end
+ end
+ end
+ end
+
+ #
+ # resolve
+ #
+
+ def resolve(state)
+ if state.conflict?
+ resolve_rr state, state.ritems
+ resolve_sr state, state.stokens
+ else
+ if state.rrules.empty?
+ # shift
+ state.stokens.each do |t|
+ state.action[t] = @actions.shift(state.goto_table[t])
+ end
+ else
+ # reduce
+ state.defact = @actions.reduce(state.rrules[0])
+ end
+ end
+ end
+
+ def resolve_rr(state, r)
+ r.each do |item|
+ item.each_la(@symboltable) do |t|
+ act = state.action[t]
+ if act
+ unless act.kind_of?(Reduce)
+ raise "racc: fatal: #{act.class} in action table"
+ end
+ # Cannot resolve R/R conflict (on t).
+ # Reduce with upper rule as default.
+ state.rr_conflict act.rule, item.rule, t
+ else
+ # No conflict.
+ state.action[t] = @actions.reduce(item.rule)
+ end
+ end
+ end
+ end
+
+ def resolve_sr(state, s)
+ s.each do |stok|
+ goto = state.goto_table[stok]
+ act = state.action[stok]
+
+ unless act
+ # no conflict
+ state.action[stok] = @actions.shift(goto)
+ else
+ unless act.kind_of?(Reduce)
+ puts 'DEBUG -------------------------------'
+ p stok
+ p act
+ state.action.each do |k,v|
+ print k.inspect, ' ', v.inspect, "\n"
+ end
+ raise "racc: fatal: #{act.class} in action table"
+ end
+
+ # conflict on stok
+
+ rtok = act.rule.precedence
+ case do_resolve_sr(stok, rtok)
+ when :Reduce
+ # action is already set
+
+ when :Shift
+ # overwrite
+ act.decref
+ state.action[stok] = @actions.shift(goto)
+
+ when :Error
+ act.decref
+ state.action[stok] = @actions.error
+
+ when :CantResolve
+ # shift as default
+ act.decref
+ state.action[stok] = @actions.shift(goto)
+ state.sr_conflict stok, act.rule
+ end
+ end
+ end
+ end
+
+ ASSOC = {
+ :Left => :Reduce,
+ :Right => :Shift,
+ :Nonassoc => :Error
+ }
+
+ def do_resolve_sr(stok, rtok)
+ puts "resolve_sr: s/r conflict: rtok=#{rtok}, stok=#{stok}" if @d_prec
+
+ unless rtok and rtok.precedence
+ puts "resolve_sr: no prec for #{rtok}(R)" if @d_prec
+ return :CantResolve
+ end
+ rprec = rtok.precedence
+
+ unless stok and stok.precedence
+ puts "resolve_sr: no prec for #{stok}(S)" if @d_prec
+ return :CantResolve
+ end
+ sprec = stok.precedence
+
+ ret = if rprec == sprec
+ ASSOC[rtok.assoc] or
+ raise "racc: fatal: #{rtok}.assoc is not Left/Right/Nonassoc"
+ else
+ (rprec > sprec) ? (:Reduce) : (:Shift)
+ end
+
+ puts "resolve_sr: resolved as #{ret.id2name}" if @d_prec
+ ret
+ end
+
+ #
+ # complete
+ #
+
+ def set_accept
+ anch = @symboltable.anchor
+ init_state = @states[0].goto_table[@grammar.start]
+ targ_state = init_state.action[anch].goto_state
+ acc_state = targ_state.action[anch].goto_state
+
+ acc_state.action.clear
+ acc_state.goto_table.clear
+ acc_state.defact = @actions.accept
+ end
+
+ def pack(state)
+ ### find most frequently used reduce rule
+ act = state.action
+ arr = Array.new(@grammar.size, 0)
+ act.each do |t, a|
+ arr[a.ruleid] += 1 if a.kind_of?(Reduce)
+ end
+ i = arr.max
+ s = (i > 0) ? arr.index(i) : nil
+
+ ### set & delete default action
+ if s
+ r = @actions.reduce(s)
+ if not state.defact or state.defact == r
+ act.delete_if {|t, a| a == r }
+ state.defact = r
+ end
+ else
+ state.defact ||= @actions.error
+ end
+ end
+
+ def check_useless
+ used = []
+ @actions.each_reduce do |act|
+ if not act or act.refn == 0
+ act.rule.useless = true
+ else
+ t = act.rule.target
+ used[t.ident] = t
+ end
+ end
+ @symboltable.nt_base.upto(@symboltable.nt_max - 1) do |n|
+ unless used[n]
+ @symboltable[n].useless = true
+ end
+ end
+ end
+
+ end # class StateTable
+
+
+ # A LALR state.
+ class State
+
+ def initialize(ident, core)
+ @ident = ident
+ @core = core
+ @goto_table = {}
+ @gotos = {}
+ @stokens = nil
+ @ritems = nil
+ @action = {}
+ @defact = nil
+ @rrconf = nil
+ @srconf = nil
+
+ @closure = make_closure(@core)
+ end
+
+ attr_reader :ident
+ alias stateid ident
+ alias hash ident
+
+ attr_reader :core
+ attr_reader :closure
+
+ attr_reader :goto_table
+ attr_reader :gotos
+
+ attr_reader :stokens
+ attr_reader :ritems
+ attr_reader :rrules
+
+ attr_reader :action
+ attr_accessor :defact # default action
+
+ attr_reader :rrconf
+ attr_reader :srconf
+
+ def inspect
+ "<state #{@ident}>"
+ end
+
+ alias to_s inspect
+
+ def ==(oth)
+ @ident == oth.ident
+ end
+
+ alias eql? ==
+
+ def make_closure(core)
+ set = ISet.new
+ core.each do |ptr|
+ set.add ptr
+ if t = ptr.dereference and t.nonterminal?
+ set.update_a t.expand
+ end
+ end
+ set.to_a
+ end
+
+ def check_la(la_rules)
+ @conflict = false
+ s = []
+ r = []
+ @closure.each do |ptr|
+ if t = ptr.dereference
+ if t.terminal?
+ s[t.ident] = t
+ if t.ident == 1 # $error
+ @conflict = true
+ end
+ end
+ else
+ r.push ptr.rule
+ end
+ end
+ unless r.empty?
+ if not s.empty? or r.size > 1
+ @conflict = true
+ end
+ end
+ s.compact!
+ @stokens = s
+ @rrules = r
+
+ if @conflict
+ @la_rules_i = la_rules.size
+ @la_rules = r.map {|i| i.ident }
+ la_rules.concat r
+ else
+ @la_rules_i = @la_rules = nil
+ end
+ end
+
+ def conflict?
+ @conflict
+ end
+
+ def rruleid(rule)
+ if i = @la_rules.index(rule.ident)
+ @la_rules_i + i
+ else
+ puts '/// rruleid'
+ p self
+ p rule
+ p @rrules
+ p @la_rules_i
+ raise 'racc: fatal: cannot get reduce rule id'
+ end
+ end
+
+ def la=(la)
+ return unless @conflict
+ i = @la_rules_i
+ @ritems = r = []
+ @rrules.each do |rule|
+ r.push Item.new(rule, la[i])
+ i += 1
+ end
+ end
+
+ def rr_conflict(high, low, ctok)
+ c = RRconflict.new(@ident, high, low, ctok)
+
+ @rrconf ||= {}
+ if a = @rrconf[ctok]
+ a.push c
+ else
+ @rrconf[ctok] = [c]
+ end
+ end
+
+ def sr_conflict(shift, reduce)
+ c = SRconflict.new(@ident, shift, reduce)
+
+ @srconf ||= {}
+ if a = @srconf[shift]
+ a.push c
+ else
+ @srconf[shift] = [c]
+ end
+ end
+
+ def n_srconflicts
+ @srconf ? @srconf.size : 0
+ end
+
+ def n_rrconflicts
+ @rrconf ? @rrconf.size : 0
+ end
+
+ end # class State
+
+
+ #
+ # Represents a transition on the grammar.
+ # "Real goto" means a transition by nonterminal,
+ # but this class treats also terminal's.
+ # If one is a terminal transition, .ident returns nil.
+ #
+ class Goto
+ def initialize(ident, sym, from, to)
+ @ident = ident
+ @symbol = sym
+ @from_state = from
+ @to_state = to
+ end
+
+ attr_reader :ident
+ attr_reader :symbol
+ attr_reader :from_state
+ attr_reader :to_state
+
+ def inspect
+ "(#{@from_state.ident}-#{@symbol}->#{@to_state.ident})"
+ end
+ end
+
+
+ # LALR item. A set of rule and its lookahead tokens.
+ class Item
+ def initialize(rule, la)
+ @rule = rule
+ @la = la
+ end
+
+ attr_reader :rule
+ attr_reader :la
+
+ def each_la(tbl)
+ la = @la
+ 0.upto(la.size - 1) do |i|
+ (0..7).each do |ii|
+ if la[idx = i * 8 + ii] == 1
+ yield tbl[idx]
+ end
+ end
+ end
+ end
+ end
+
+
+ # The table of LALR actions. Actions are either of
+ # Shift, Reduce, Accept and Error.
+ class ActionTable
+
+ def initialize(rt, st)
+ @grammar = rt
+ @statetable = st
+
+ @reduce = []
+ @shift = []
+ @accept = nil
+ @error = nil
+ end
+
+ def init
+ @grammar.each do |rule|
+ @reduce.push Reduce.new(rule)
+ end
+ @statetable.each do |state|
+ @shift.push Shift.new(state)
+ end
+ @accept = Accept.new
+ @error = Error.new
+ end
+
+ def reduce_n
+ @reduce.size
+ end
+
+ def reduce(i)
+ case i
+ when Rule then i = i.ident
+ when Integer then ;
+ else
+ raise "racc: fatal: wrong class #{i.class} for reduce"
+ end
+
+ r = @reduce[i] or raise "racc: fatal: reduce action #{i.inspect} not exist"
+ r.incref
+ r
+ end
+
+ def each_reduce(&block)
+ @reduce.each(&block)
+ end
+
+ def shift_n
+ @shift.size
+ end
+
+ def shift(i)
+ case i
+ when State then i = i.ident
+ when Integer then ;
+ else
+ raise "racc: fatal: wrong class #{i.class} for shift"
+ end
+
+ @shift[i] or raise "racc: fatal: shift action #{i} does not exist"
+ end
+
+ def each_shift(&block)
+ @shift.each(&block)
+ end
+
+ attr_reader :accept
+ attr_reader :error
+
+ end
+
+
+ class Shift
+ def initialize(goto)
+ @goto_state = goto
+ end
+
+ attr_reader :goto_state
+
+ def goto_id
+ @goto_state.ident
+ end
+
+ def inspect
+ "<shift #{@goto_state.ident}>"
+ end
+ end
+
+
+ class Reduce
+ def initialize(rule)
+ @rule = rule
+ @refn = 0
+ end
+
+ attr_reader :rule
+ attr_reader :refn
+
+ def ruleid
+ @rule.ident
+ end
+
+ def inspect
+ "<reduce #{@rule.ident}>"
+ end
+
+ def incref
+ @refn += 1
+ end
+
+ def decref
+ @refn -= 1
+ raise 'racc: fatal: act.refn < 0' if @refn < 0
+ end
+ end
+
+ class Accept
+ def inspect
+ "<accept>"
+ end
+ end
+
+ class Error
+ def inspect
+ "<error>"
+ end
+ end
+
+ class SRconflict
+ def initialize(sid, shift, reduce)
+ @stateid = sid
+ @shift = shift
+ @reduce = reduce
+ end
+
+ attr_reader :stateid
+ attr_reader :shift
+ attr_reader :reduce
+
+ def to_s
+ sprintf('state %d: S/R conflict rule %d reduce and shift %s',
+ @stateid, @reduce.ruleid, @shift.to_s)
+ end
+ end
+
+ class RRconflict
+ def initialize(sid, high, low, tok)
+ @stateid = sid
+ @high_prec = high
+ @low_prec = low
+ @token = tok
+ end
+
+ attr_reader :stateid
+ attr_reader :high_prec
+ attr_reader :low_prec
+ attr_reader :token
+
+ def to_s
+ sprintf('state %d: R/R conflict with rule %d and %d on %s',
+ @stateid, @high_prec.ident, @low_prec.ident, @token.to_s)
+ end
+ end
+
+end
diff --git a/lib/racc/statetransitiontable.rb b/lib/racc/statetransitiontable.rb
new file mode 100644
index 0000000000..d75fa1657a
--- /dev/null
+++ b/lib/racc/statetransitiontable.rb
@@ -0,0 +1,311 @@
+#--
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+#
+#++
+
+require 'racc/parser'
+
+module Racc
+
+ StateTransitionTable = Struct.new(:action_table,
+ :action_check,
+ :action_default,
+ :action_pointer,
+ :goto_table,
+ :goto_check,
+ :goto_default,
+ :goto_pointer,
+ :token_table,
+ :reduce_table,
+ :reduce_n,
+ :shift_n,
+ :nt_base,
+ :token_to_s_table,
+ :use_result_var,
+ :debug_parser)
+ class StateTransitionTable # reopen
+ def StateTransitionTable.generate(states)
+ StateTransitionTableGenerator.new(states).generate
+ end
+
+ def initialize(states)
+ super()
+ @states = states
+ @grammar = states.grammar
+ self.use_result_var = true
+ self.debug_parser = true
+ end
+
+ attr_reader :states
+ attr_reader :grammar
+
+ def parser_class
+ ParserClassGenerator.new(@states).generate
+ end
+
+ def token_value_table
+ h = {}
+ token_table().each do |sym, i|
+ h[sym.value] = i
+ end
+ h
+ end
+ end
+
+
+ class StateTransitionTableGenerator
+
+ def initialize(states)
+ @states = states
+ @grammar = states.grammar
+ end
+
+ def generate
+ t = StateTransitionTable.new(@states)
+ gen_action_tables t, @states
+ gen_goto_tables t, @grammar
+ t.token_table = token_table(@grammar)
+ t.reduce_table = reduce_table(@grammar)
+ t.reduce_n = @states.reduce_n
+ t.shift_n = @states.shift_n
+ t.nt_base = @grammar.nonterminal_base
+ t.token_to_s_table = @grammar.symbols.map {|sym| sym.to_s }
+ t
+ end
+
+ def reduce_table(grammar)
+ t = [0, 0, :racc_error]
+ grammar.each_with_index do |rule, idx|
+ next if idx == 0
+ t.push rule.size
+ t.push rule.target.ident
+ t.push(if rule.action.empty? # and @params.omit_action_call?
+ then :_reduce_none
+ else "_reduce_#{idx}".intern
+ end)
+ end
+ t
+ end
+
+ def token_table(grammar)
+ h = {}
+ grammar.symboltable.terminals.each do |t|
+ h[t] = t.ident
+ end
+ h
+ end
+
+ def gen_action_tables(t, states)
+ t.action_table = yytable = []
+ t.action_check = yycheck = []
+ t.action_default = yydefact = []
+ t.action_pointer = yypact = []
+ e1 = []
+ e2 = []
+ states.each do |state|
+ yydefact.push act2actid(state.defact)
+ if state.action.empty?
+ yypact.push nil
+ next
+ end
+ vector = []
+ state.action.each do |tok, act|
+ vector[tok.ident] = act2actid(act)
+ end
+ addent e1, vector, state.ident, yypact
+ end
+ set_table e1, e2, yytable, yycheck, yypact
+ end
+
+ def gen_goto_tables(t, grammar)
+ t.goto_table = yytable2 = []
+ t.goto_check = yycheck2 = []
+ t.goto_pointer = yypgoto = []
+ t.goto_default = yydefgoto = []
+ e1 = []
+ e2 = []
+ grammar.each_nonterminal do |tok|
+ tmp = []
+
+ # decide default
+ freq = Array.new(@states.size, 0)
+ @states.each do |state|
+ st = state.goto_table[tok]
+ if st
+ st = st.ident
+ freq[st] += 1
+ end
+ tmp[state.ident] = st
+ end
+ max = freq.max
+ if max > 1
+ default = freq.index(max)
+ tmp.map! {|i| default == i ? nil : i }
+ else
+ default = nil
+ end
+ yydefgoto.push default
+
+ # delete default value
+ tmp.pop until tmp.last or tmp.empty?
+ if tmp.compact.empty?
+ # only default
+ yypgoto.push nil
+ next
+ end
+
+ addent e1, tmp, (tok.ident - grammar.nonterminal_base), yypgoto
+ end
+ set_table e1, e2, yytable2, yycheck2, yypgoto
+ end
+
+ def addent(all, arr, chkval, ptr)
+ max = arr.size
+ min = nil
+ arr.each_with_index do |item, idx|
+ if item
+ min ||= idx
+ end
+ end
+ ptr.push(-7777) # mark
+ arr = arr[min...max]
+ all.push [arr, chkval, mkmapexp(arr), min, ptr.size - 1]
+ end
+
+ n = 2 ** 16
+ begin
+ Regexp.compile("a{#{n}}")
+ RE_DUP_MAX = n
+ rescue RegexpError
+ n /= 2
+ retry
+ end
+
+ def mkmapexp(arr)
+ i = ii = 0
+ as = arr.size
+ map = String.new
+ maxdup = RE_DUP_MAX
+ curr = nil
+ while i < as
+ ii = i + 1
+ if arr[i]
+ ii += 1 while ii < as and arr[ii]
+ curr = '-'
+ else
+ ii += 1 while ii < as and not arr[ii]
+ curr = '.'
+ end
+
+ offset = ii - i
+ if offset == 1
+ map << curr
+ else
+ while offset > maxdup
+ map << "#{curr}{#{maxdup}}"
+ offset -= maxdup
+ end
+ map << "#{curr}{#{offset}}" if offset > 1
+ end
+ i = ii
+ end
+ Regexp.compile(map, Regexp::NOENCODING)
+ end
+
+ def set_table(entries, dummy, tbl, chk, ptr)
+ upper = 0
+ map = '-' * 10240
+
+ # sort long to short
+ entries.sort_by!.with_index {|a,i| [-a[0].size, i] }
+
+ entries.each do |arr, chkval, expr, min, ptri|
+ if upper + arr.size > map.size
+ map << '-' * (arr.size + 1024)
+ end
+ idx = map.index(expr)
+ ptr[ptri] = idx - min
+ arr.each_with_index do |item, i|
+ if item
+ i += idx
+ tbl[i] = item
+ chk[i] = chkval
+ map[i] = ?o
+ end
+ end
+ upper = idx + arr.size
+ end
+ end
+
+ def act2actid(act)
+ case act
+ when Shift then act.goto_id
+ when Reduce then -act.ruleid
+ when Accept then @states.shift_n
+ when Error then @states.reduce_n * -1
+ else
+ raise "racc: fatal: wrong act type #{act.class} in action table"
+ end
+ end
+
+ end
+
+
+ class ParserClassGenerator
+
+ def initialize(states)
+ @states = states
+ @grammar = states.grammar
+ end
+
+ def generate
+ table = @states.state_transition_table
+ c = Class.new(::Racc::Parser)
+ c.const_set :Racc_arg, [table.action_table,
+ table.action_check,
+ table.action_default,
+ table.action_pointer,
+ table.goto_table,
+ table.goto_check,
+ table.goto_default,
+ table.goto_pointer,
+ table.nt_base,
+ table.reduce_table,
+ table.token_value_table,
+ table.shift_n,
+ table.reduce_n,
+ false]
+ c.const_set :Racc_token_to_s_table, table.token_to_s_table
+ c.const_set :Racc_debug_parser, true
+ define_actions c
+ c
+ end
+
+ private
+
+ def define_actions(c)
+ c.module_eval "def _reduce_none(vals, vstack) vals[0] end"
+ @grammar.each do |rule|
+ if rule.action.empty?
+ c.alias_method("_reduce_#{rule.ident}", :_reduce_none)
+ else
+ c.define_method("_racc_action_#{rule.ident}", &rule.action.proc)
+ c.module_eval(<<-End, __FILE__, __LINE__ + 1)
+ def _reduce_#{rule.ident}(vals, vstack)
+ _racc_action_#{rule.ident}(*vals)
+ end
+ End
+ end
+ end
+ end
+
+ end
+
+end # module Racc
diff --git a/lib/racc/static.rb b/lib/racc/static.rb
new file mode 100644
index 0000000000..bebbeb5aa6
--- /dev/null
+++ b/lib/racc/static.rb
@@ -0,0 +1,5 @@
+require 'racc'
+require 'racc/parser'
+require 'racc/grammarfileparser'
+require 'racc/parserfilegenerator'
+require 'racc/logfilegenerator'
diff --git a/lib/random/formatter.rb b/lib/random/formatter.rb
index befa1d03d7..4dea61c16c 100644
--- a/lib/random/formatter.rb
+++ b/lib/random/formatter.rb
@@ -174,125 +174,6 @@ module Random::Formatter
"%08x-%04x-%04x-%04x-%04x%08x" % ary
end
- alias uuid_v4 uuid
-
- # Generate a random v7 UUID (Universally Unique IDentifier).
- #
- # require 'random/formatter'
- #
- # Random.uuid_v7 # => "0188d4c3-1311-7f96-85c7-242a7aa58f1e"
- # Random.uuid_v7 # => "0188d4c3-16fe-744f-86af-38fa04c62bb5"
- # Random.uuid_v7 # => "0188d4c3-1af8-764f-b049-c204ce0afa23"
- # Random.uuid_v7 # => "0188d4c3-1e74-7085-b14f-ef6415dc6f31"
- # # |<--sorted-->| |<----- random ---->|
- #
- # # or
- # prng = Random.new
- # prng.uuid_v7 # => "0188ca51-5e72-7950-a11d-def7ff977c98"
- #
- # The version 7 UUID starts with the least significant 48 bits of a 64 bit
- # Unix timestamp (milliseconds since the epoch) and fills the remaining bits
- # with random data, excluding the version and variant bits.
- #
- # This allows version 7 UUIDs to be sorted by creation time. Time ordered
- # UUIDs can be used for better database index locality of newly inserted
- # records, which may have a significant performance benefit compared to random
- # data inserts.
- #
- # The result contains 74 random bits (9.25 random bytes).
- #
- # Note that this method cannot be made reproducable because its output
- # includes not only random bits but also timestamp.
- #
- # See draft-ietf-uuidrev-rfc4122bis[https://datatracker.ietf.org/doc/draft-ietf-uuidrev-rfc4122bis/]
- # for details of UUIDv7.
- #
- # ==== Monotonicity
- #
- # UUIDv7 has millisecond precision by default, so multiple UUIDs created
- # within the same millisecond are not issued in monotonically increasing
- # order. To create UUIDs that are time-ordered with sub-millisecond
- # precision, up to 12 bits of additional timestamp may added with
- # +extra_timestamp_bits+. The extra timestamp precision comes at the expense
- # of random bits. Setting <tt>extra_timestamp_bits: 12</tt> provides ~244ns
- # of precision, but only 62 random bits (7.75 random bytes).
- #
- # prng = Random.new
- # Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 12) }
- # # =>
- # ["0188d4c7-13da-74f9-8b53-22a786ffdd5a",
- # "0188d4c7-13da-753b-83a5-7fb9b2afaeea",
- # "0188d4c7-13da-754a-88ea-ac0baeedd8db",
- # "0188d4c7-13da-7557-83e1-7cad9cda0d8d"]
- # # |<--- sorted --->| |<-- random --->|
- #
- # Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 8) }
- # # =>
- # ["0188d4c7-3333-7a95-850a-de6edb858f7e",
- # "0188d4c7-3333-7ae8-842e-bc3a8b7d0cf9", # <- out of order
- # "0188d4c7-3333-7ae2-995a-9f135dc44ead", # <- out of order
- # "0188d4c7-3333-7af9-87c3-8f612edac82e"]
- # # |<--- sorted -->||<---- random --->|
- #
- # Any rollbacks of the system clock will break monotonicity. UUIDv7 is based
- # on UTC, which excludes leap seconds and can rollback the clock. To avoid
- # this, the system clock can synchronize with an NTP server configured to use
- # a "leap smear" approach. NTP or PTP will also be needed to synchronize
- # across distributed nodes.
- #
- # Counters and other mechanisms for stronger guarantees of monotonicity are
- # not implemented. Applications with stricter requirements should follow
- # {Section 6.2}[https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-07.html#monotonicity_counters]
- # of the specification.
- #
- def uuid_v7(extra_timestamp_bits: 0)
- case (extra_timestamp_bits = Integer(extra_timestamp_bits))
- when 0 # min timestamp precision
- ms = Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond)
- rand = random_bytes(10)
- rand.setbyte(0, rand.getbyte(0) & 0x0f | 0x70) # version
- rand.setbyte(2, rand.getbyte(2) & 0x3f | 0x80) # variant
- "%08x-%04x-%s" % [
- (ms & 0x0000_ffff_ffff_0000) >> 16,
- (ms & 0x0000_0000_0000_ffff),
- rand.unpack("H4H4H12").join("-")
- ]
-
- when 12 # max timestamp precision
- ms, ns = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
- .divmod(1_000_000)
- extra_bits = ns * 4096 / 1_000_000
- rand = random_bytes(8)
- rand.setbyte(0, rand.getbyte(0) & 0x3f | 0x80) # variant
- "%08x-%04x-7%03x-%s" % [
- (ms & 0x0000_ffff_ffff_0000) >> 16,
- (ms & 0x0000_0000_0000_ffff),
- extra_bits,
- rand.unpack("H4H12").join("-")
- ]
-
- when (0..12) # the generic version is slower than the special cases above
- rand_a, rand_b1, rand_b2, rand_b3 = random_bytes(10).unpack("nnnN")
- rand_mask_bits = 12 - extra_timestamp_bits
- ms, ns = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
- .divmod(1_000_000)
- "%08x-%04x-%04x-%04x-%04x%08x" % [
- (ms & 0x0000_ffff_ffff_0000) >> 16,
- (ms & 0x0000_0000_0000_ffff),
- 0x7000 |
- ((ns * (1 << extra_timestamp_bits) / 1_000_000) << rand_mask_bits) |
- rand_a & ((1 << rand_mask_bits) - 1),
- 0x8000 | (rand_b1 & 0x3fff),
- rand_b2,
- rand_b3
- ]
-
- else
- raise ArgumentError, "extra_timestamp_bits must be in 0..12"
- end
- end
-
- # Internal interface to Random; Generate random data _n_ bytes.
private def gen_random(n)
self.bytes(n)
end
@@ -340,20 +221,16 @@ module Random::Formatter
result
end
- # The default character list for #alphanumeric.
ALPHANUMERIC = [*'A'..'Z', *'a'..'z', *'0'..'9']
-
# Generate a random alphanumeric string.
#
# The argument _n_ specifies the length, in characters, of the alphanumeric
# string to be generated.
- # The argument _chars_ specifies the character list which the result is
- # consist of.
#
# If _n_ is not specified or is nil, 16 is assumed.
# It may be larger in the future.
#
- # The result may contain A-Z, a-z and 0-9, unless _chars_ is specified.
+ # The result may contain A-Z, a-z and 0-9.
#
# require 'random/formatter'
#
@@ -361,13 +238,8 @@ module Random::Formatter
# # or
# prng = Random.new
# prng.alphanumeric(10) #=> "i6K93NdqiH"
- #
- # Random.alphanumeric(4, chars: [*"0".."9"]) #=> "2952"
- # # or
- # prng = Random.new
- # prng.alphanumeric(10, chars: [*"!".."/"]) #=> ",.,++%/''."
- def alphanumeric(n = nil, chars: ALPHANUMERIC)
+ def alphanumeric(n=nil)
n = 16 if n.nil?
- choose(chars, n)
+ choose(ALPHANUMERIC, n)
end
end
diff --git a/lib/rdoc.rb b/lib/rdoc.rb
index cf52ce8792..b62c22576d 100644
--- a/lib/rdoc.rb
+++ b/lib/rdoc.rb
@@ -120,17 +120,6 @@ module RDoc
end
end
- ##
- # Seaches and returns the directory for settings.
- #
- # 1. <tt>$HOME/.rdoc</tt> directory, if it exists.
- # 2. The +rdoc+ directory under the path specified by the
- # +XDG_DATA_HOME+ environment variable, if it is set.
- # 3. <tt>$HOME/.local/share/rdoc</tt> directory.
- #
- # Other than the home directory, the containing directory will be
- # created automatically.
-
def self.home
rdoc_dir = begin
File.expand_path('~/.rdoc')
@@ -140,7 +129,6 @@ module RDoc
if File.directory?(rdoc_dir)
rdoc_dir
else
- require 'fileutils'
begin
# XDG
xdg_data_home = ENV["XDG_DATA_HOME"] || File.join(File.expand_path("~"), '.local', 'share')
diff --git a/lib/rdoc/alias.rb b/lib/rdoc/alias.rb
index 446cf9ccb4..858e053049 100644
--- a/lib/rdoc/alias.rb
+++ b/lib/rdoc/alias.rb
@@ -109,3 +109,4 @@ class RDoc::Alias < RDoc::CodeObject
end
end
+
diff --git a/lib/rdoc/anon_class.rb b/lib/rdoc/anon_class.rb
index 3c2f0e1877..d02a38c2cf 100644
--- a/lib/rdoc/anon_class.rb
+++ b/lib/rdoc/anon_class.rb
@@ -8,3 +8,4 @@
class RDoc::AnonClass < RDoc::ClassModule
end
+
diff --git a/lib/rdoc/any_method.rb b/lib/rdoc/any_method.rb
index 465c4a4fb2..051f946a10 100644
--- a/lib/rdoc/any_method.rb
+++ b/lib/rdoc/any_method.rb
@@ -116,13 +116,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr
end
##
- # Whether the method has a call-seq.
-
- def has_call_seq?
- !!(@call_seq || is_alias_for&._call_seq)
- end
-
- ##
# Loads is_alias_for from the internal name. Returns nil if the alias
# cannot be found.
@@ -304,14 +297,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr
end
##
- # Whether to skip the method description, true for methods that have
- # aliases with a call-seq that doesn't include the method name.
-
- def skip_description?
- has_call_seq? && call_seq.nil? && !!(is_alias_for || !aliases.empty?)
- end
-
- ##
# Sets the store for this method and its referenced code objects.
def store= store
diff --git a/lib/rdoc/attr.rb b/lib/rdoc/attr.rb
index a403235933..f780b3b976 100644
--- a/lib/rdoc/attr.rb
+++ b/lib/rdoc/attr.rb
@@ -173,3 +173,4 @@ class RDoc::Attr < RDoc::MethodAttr
end
end
+
diff --git a/lib/rdoc/class_module.rb b/lib/rdoc/class_module.rb
index c69e14b5e4..7609080fbf 100644
--- a/lib/rdoc/class_module.rb
+++ b/lib/rdoc/class_module.rb
@@ -799,3 +799,4 @@ class RDoc::ClassModule < RDoc::Context
end
end
+
diff --git a/lib/rdoc/comment.rb b/lib/rdoc/comment.rb
index 04ec226436..9e90999eac 100644
--- a/lib/rdoc/comment.rb
+++ b/lib/rdoc/comment.rb
@@ -6,8 +6,8 @@
# Each comment may have a different markup format set by #format=. By default
# 'rdoc' is used. The :markup: directive tells RDoc which format to use.
#
-# See RDoc::MarkupReference@Directive+for+Specifying+RDoc+Source+Format.
-
+# See RDoc::Markup@Other+directives for instructions on adding an alternate
+# format.
class RDoc::Comment
@@ -97,26 +97,42 @@ class RDoc::Comment
# comment. The difficulty is to make sure not to match lines starting
# with ARGF at the same indent, but that are after the first description
# paragraph.
- if /^(?<S> ((?!\n)\s)*+ (?# whitespaces except newline))
- :?call-seq:
- (?<B> \g<S>(?<N>\n|\z) (?# trailing spaces))?
- (?<seq>
- (\g<S>(?!\w)\S.*\g<N>)*
- (?>
- (?<H> \g<S>\w+ (?# ' # ARGF' in the example above))
- .*\g<N>)?
- (\g<S>\S.*\g<N> (?# other non-blank line))*+
- (\g<B>+(\k<H>.*\g<N> (?# ARGF.to_a lines))++)*+
- )
- (?m:^\s*$|\z)
- /x =~ @text
- seq = $~[:seq]
-
+ if @text =~ /^\s*:?call-seq:(.*?(?:\S).*?)^\s*$/m then
all_start, all_stop = $~.offset(0)
+ seq_start, seq_stop = $~.offset(1)
+
+ # we get the following lines that start with the leading word at the
+ # same indent, even if they have blank lines before
+ if $1 =~ /(^\s*\n)+^(\s*\w+)/m then
+ leading = $2 # ' * ARGF' in the example above
+ re = %r%
+ \A(
+ (^\s*\n)+
+ (^#{Regexp.escape leading}.*?\n)+
+ )+
+ ^\s*$
+ %xm
+
+ if @text[seq_stop..-1] =~ re then
+ all_stop = seq_stop + $~.offset(0).last
+ seq_stop = seq_stop + $~.offset(1).last
+ end
+ end
+
+ seq = @text[seq_start..seq_stop]
+ seq.gsub!(/^\s*(\S|\n)/m, '\1')
@text.slice! all_start...all_stop
- seq.gsub!(/^\s*/, '')
- method.call_seq = seq
+ method.call_seq = seq.chomp
+
+ else
+ regexp = /^\s*:?call-seq:(.*?)(^\s*$|\z)/m
+ if regexp =~ @text then
+ @text = @text.sub(regexp, '')
+ seq = $1
+ seq.gsub!(/^\s*/, '')
+ method.call_seq = seq
+ end
end
method
@@ -133,7 +149,12 @@ class RDoc::Comment
# HACK dubious
def encode! encoding
- @text = String.new @text, encoding: encoding
+ # TODO: Remove this condition after Ruby 2.2 EOL
+ if RUBY_VERSION < '2.3.0'
+ @text = @text.force_encoding encoding
+ else
+ @text = String.new @text, encoding: encoding
+ end
self
end
diff --git a/lib/rdoc/constant.rb b/lib/rdoc/constant.rb
index 12b8be775c..0c3d7505a1 100644
--- a/lib/rdoc/constant.rb
+++ b/lib/rdoc/constant.rb
@@ -184,3 +184,4 @@ class RDoc::Constant < RDoc::CodeObject
end
end
+
diff --git a/lib/rdoc/context/section.rb b/lib/rdoc/context/section.rb
index aecd4e0213..c316efe99f 100644
--- a/lib/rdoc/context/section.rb
+++ b/lib/rdoc/context/section.rb
@@ -231,3 +231,4 @@ class RDoc::Context::Section
end
end
+
diff --git a/lib/rdoc/cross_reference.rb b/lib/rdoc/cross_reference.rb
index 4e011219e8..319bbc02ac 100644
--- a/lib/rdoc/cross_reference.rb
+++ b/lib/rdoc/cross_reference.rb
@@ -131,9 +131,6 @@ class RDoc::CrossReference
@seen = {}
end
- ##
- # Returns a method reference to +name+.
-
def resolve_method name
ref = nil
@@ -226,3 +223,4 @@ class RDoc::CrossReference
end
end
+
diff --git a/lib/rdoc/encoding.rb b/lib/rdoc/encoding.rb
index 67e190f782..cf60badd24 100644
--- a/lib/rdoc/encoding.rb
+++ b/lib/rdoc/encoding.rb
@@ -86,6 +86,17 @@ module RDoc::Encoding
nil
end
+ def self.remove_frozen_string_literal string
+ string =~ /\A(?:#!.*\n)?(.*\n)/
+ first_line = $1
+
+ if first_line =~ /\A# +frozen[-_]string[-_]literal[=:].+$/i
+ string = string.sub first_line, ''
+ end
+
+ string
+ end
+
##
# Detects the encoding of +string+ based on the magic comment
@@ -113,7 +124,12 @@ module RDoc::Encoding
if text.kind_of? RDoc::Comment
text.encode! encoding
else
- String.new text, encoding: encoding
+ # TODO: Remove this condition after Ruby 2.2 EOL
+ if RUBY_VERSION < '2.3.0'
+ text.force_encoding encoding
+ else
+ String.new text, encoding: encoding
+ end
end
end
diff --git a/lib/rdoc/erb_partial.rb b/lib/rdoc/erb_partial.rb
index 043d763db1..d6e3f41b7e 100644
--- a/lib/rdoc/erb_partial.rb
+++ b/lib/rdoc/erb_partial.rb
@@ -16,3 +16,4 @@ class RDoc::ERBPartial < ERB
end
end
+
diff --git a/lib/rdoc/erbio.rb b/lib/rdoc/erbio.rb
index 0f98eaedee..0d5f96e133 100644
--- a/lib/rdoc/erbio.rb
+++ b/lib/rdoc/erbio.rb
@@ -20,8 +20,12 @@ class RDoc::ERBIO < ERB
##
# Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize
- def initialize str, trim_mode: nil, eoutvar: 'io'
- super(str, trim_mode: trim_mode, eoutvar: eoutvar)
+ def initialize str, safe_level = nil, legacy_trim_mode = nil, legacy_eoutvar = 'io', trim_mode: nil, eoutvar: 'io'
+ if RUBY_VERSION >= '2.6'
+ super(str, trim_mode: trim_mode, eoutvar: eoutvar)
+ else
+ super(str, safe_level, legacy_trim_mode, legacy_eoutvar)
+ end
end
##
@@ -35,3 +39,4 @@ class RDoc::ERBIO < ERB
end
end
+
diff --git a/lib/rdoc/extend.rb b/lib/rdoc/extend.rb
index 7d57433de6..e1b182902e 100644
--- a/lib/rdoc/extend.rb
+++ b/lib/rdoc/extend.rb
@@ -7,3 +7,4 @@
class RDoc::Extend < RDoc::Mixin
end
+
diff --git a/lib/rdoc/generator/darkfish.rb b/lib/rdoc/generator/darkfish.rb
index 1b408a6f8e..60e0265e8c 100644
--- a/lib/rdoc/generator/darkfish.rb
+++ b/lib/rdoc/generator/darkfish.rb
@@ -610,7 +610,7 @@ class RDoc::Generator::Darkfish
@classes = @store.all_classes_and_modules.sort
@files = @store.all_files.sort
- @methods = @classes.flat_map { |m| m.method_list }.sort
+ @methods = @classes.map { |m| m.method_list }.flatten.sort
@modsort = get_sorted_module_list @classes
end
@@ -778,7 +778,11 @@ class RDoc::Generator::Darkfish
erbout = "_erbout_#{file_var}"
end
- template = klass.new template, trim_mode: '-', eoutvar: erbout
+ if RUBY_VERSION >= '2.6'
+ template = klass.new template, trim_mode: '-', eoutvar: erbout
+ else
+ template = klass.new template, nil, '-', erbout
+ end
@template_cache[file] = template
template
end
diff --git a/lib/rdoc/generator/json_index.rb b/lib/rdoc/generator/json_index.rb
index c454910d5c..3a1000033d 100644
--- a/lib/rdoc/generator/json_index.rb
+++ b/lib/rdoc/generator/json_index.rb
@@ -230,9 +230,9 @@ class RDoc::Generator::JsonIndex
def index_methods
debug_msg " generating method search index"
- list = @classes.uniq.flat_map do |klass|
+ list = @classes.uniq.map do |klass|
klass.method_list
- end.sort_by do |method|
+ end.flatten.sort_by do |method|
[method.name, method.parent.full_name]
end
diff --git a/lib/rdoc/generator/markup.rb b/lib/rdoc/generator/markup.rb
index 76b7d458aa..b54265717c 100644
--- a/lib/rdoc/generator/markup.rb
+++ b/lib/rdoc/generator/markup.rb
@@ -157,3 +157,4 @@ class RDoc::TopLevel
end
end
+
diff --git a/lib/rdoc/generator/pot.rb b/lib/rdoc/generator/pot.rb
index b0b7c07179..bee1133b07 100644
--- a/lib/rdoc/generator/pot.rb
+++ b/lib/rdoc/generator/pot.rb
@@ -81,7 +81,6 @@ class RDoc::Generator::POT
end
end
- # :nodoc:
def class_dir
nil
end
diff --git a/lib/rdoc/generator/ri.rb b/lib/rdoc/generator/ri.rb
index 1c2f018f97..0eef1d03f5 100644
--- a/lib/rdoc/generator/ri.rb
+++ b/lib/rdoc/generator/ri.rb
@@ -28,3 +28,4 @@ class RDoc::Generator::RI
end
end
+
diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml
index afc7f7b88d..9c49b31376 100644
--- a/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml
+++ b/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml
@@ -3,7 +3,7 @@
<div id="search-field-wrapper">
<input id="search-field" role="combobox" aria-label="Search"
aria-autocomplete="list" aria-controls="search-results"
- type="text" name="search" placeholder="Search (/) for a class, method, ..." spellcheck="false"
+ type="text" name="search" placeholder="Search" spellcheck="false"
title="Type to search, Up and Down to navigate, Enter to load">
</div>
diff --git a/lib/rdoc/generator/template/darkfish/class.rhtml b/lib/rdoc/generator/template/darkfish/class.rhtml
index d6510336df..97d175dddc 100644
--- a/lib/rdoc/generator/template/darkfish/class.rhtml
+++ b/lib/rdoc/generator/template/darkfish/class.rhtml
@@ -112,10 +112,6 @@
<%- end -%>
</div>
<%- end -%>
- <%- elsif method.has_call_seq? then -%>
- <div class="method-heading">
- <span class="method-name"><%= h method.name %></span>
- </div>
<%- else -%>
<div class="method-heading">
<span class="method-name"><%= h method.name %></span><span
@@ -127,7 +123,6 @@
<%- end -%>
</div>
- <%- unless method.skip_description? then -%>
<div class="method-description">
<%- if method.comment then -%>
<%= method.description.strip %>
@@ -150,7 +145,6 @@
</div>
<%- end -%>
</div>
- <%- end -%>
<%- unless method.aliases.empty? then -%>
<div class="aliases">
diff --git a/lib/rdoc/generator/template/darkfish/css/rdoc.css b/lib/rdoc/generator/template/darkfish/css/rdoc.css
index 2cc55e03b1..1be815f503 100644
--- a/lib/rdoc/generator/template/darkfish/css/rdoc.css
+++ b/lib/rdoc/generator/template/darkfish/css/rdoc.css
@@ -17,14 +17,6 @@ body {
background: #fafafa;
font-family: Lato, sans-serif;
font-weight: 300;
-
- /* Layout */
- display: grid;
- grid-template-columns: auto 1fr;
-}
-
-body > :last-child {
- grid-column: 1 / 3;
}
h1 span,
@@ -87,17 +79,6 @@ pre {
border-radius: 0.2em;
}
-em {
- text-decoration-color: rgba(52, 48, 64, 0.25);
- text-decoration-line: underline;
- text-decoration-style: dotted;
-}
-
-strong,
-em {
- background-color: rgba(158, 178, 255, 0.1);
-}
-
table {
margin: 0;
border-spacing: 0;
@@ -200,25 +181,21 @@ table tr:nth-child(even) td {
/* @group Top-Level Structure */
nav {
+ float: left;
+ width: 260px;
font-family: Helvetica, sans-serif;
font-size: 14px;
border-right: 1px solid #ccc;
position: sticky;
top: 0;
overflow: auto;
-
- /* Layout */
- width: 260px; /* fallback */
- width: max(50px, 20vw);
- min-width: 50px;
- max-width: 80vw;
height: calc(100vh - 100px); /* reduce the footer height */
- resize: horizontal;
}
main {
display: block;
- margin: 1em;
+ margin: 0 2em 5em 260px;
+ padding-left: 20px;
min-width: 340px;
font-size: 16px;
}
@@ -237,6 +214,7 @@ main h6 {
}
#validator-badges {
+ clear: both;
margin: 1em 1em 2em;
font-size: smaller;
}
@@ -331,26 +309,23 @@ dl.note-list dt {
background: url(../images/arrow_up.png) no-repeat right center;
}
-.nav-section details > summary {
+.nav-section details summary {
display: block;
}
-.nav-section details > summary::-webkit-details-marker {
+.nav-section details summary::-webkit-details-marker {
display: none;
}
-.nav-section details > summary::before {
+.nav-section details summary:before {
content: "";
}
-.nav-section details > summary::after {
- content: "\25B6"; /* BLACK RIGHT-POINTING TRIANGLE */
- font-size: 0.8em;
- margin-left: 0.4em;
+.nav-section details summary:after {
+ content: " \25B6"; /* BLACK RIGHT-POINTING TRIANGLE */
}
-
-.nav-section details[open] > summary::after {
- content: "\25BD"; /* WHITE DOWN-POINTING TRIANGLE */
+.nav-section details[open] > summary:after {
+ content: " \25BD"; /* WHITE DOWN-POINTING TRIANGLE */
}
/* @end */
@@ -578,7 +553,7 @@ main .method-click-advice {
line-height: 20px;
background: url(../images/zoom.png) no-repeat right top;
}
-main .method-header:hover .method-click-advice {
+main .method-heading:hover .method-click-advice {
visibility: visible;
}
diff --git a/lib/rdoc/generator/template/darkfish/js/darkfish.js b/lib/rdoc/generator/template/darkfish/js/darkfish.js
index 19a85c54e1..d0c9467751 100644
--- a/lib/rdoc/generator/template/darkfish/js/darkfish.js
+++ b/lib/rdoc/generator/template/darkfish/js/darkfish.js
@@ -78,20 +78,7 @@ function hookSearch() {
search.scrollIntoView = search.scrollInWindow;
};
-function hookFocus() {
- document.addEventListener("keydown", (event) => {
- if (document.activeElement.tagName === 'INPUT') {
- return;
- }
- if (event.key === "/") {
- event.preventDefault();
- document.querySelector('#search-field').focus();
- }
- });
-}
-
document.addEventListener('DOMContentLoaded', function() {
hookSourceViews();
hookSearch();
- hookFocus();
});
diff --git a/lib/rdoc/generator/template/darkfish/js/search.js b/lib/rdoc/generator/template/darkfish/js/search.js
index d3cded1d57..58e52afecf 100644
--- a/lib/rdoc/generator/template/darkfish/js/search.js
+++ b/lib/rdoc/generator/template/darkfish/js/search.js
@@ -15,9 +15,9 @@ Search.prototype = Object.assign({}, Navigation, new function() {
this.init = function() {
var _this = this;
var observer = function(e) {
- switch(e.key) {
- case 'ArrowUp':
- case 'ArrowDown':
+ switch(e.keyCode) {
+ case 38: // Event.KEY_UP
+ case 40: // Event.KEY_DOWN
return;
}
_this.search(_this.input.value);
diff --git a/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml b/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml
index 54a376c9e5..941ff9d630 100644
--- a/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml
+++ b/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml
@@ -36,9 +36,8 @@
unless table.empty? then %>
<ul>
<%- table.each do |item| -%>
-<%- label = item.respond_to?(:label) ? item.label(klass) : item.aref -%>
- <li><a href="<%= klass.path %>#<%= label %>"><%= item.plain_html %></a>
-<%- end -%>
+ <li><a href="<%= klass.path %>#<%= item.aref %>"><%= item.plain_html %></a>
+<%- end -%>
</ul>
<%- end -%>
</li>
@@ -47,9 +46,9 @@
<h2 id="methods">Methods</h2>
<ul>
-<%- @store.all_classes_and_modules.flat_map do |mod|
+<%- @store.all_classes_and_modules.map do |mod|
mod.method_list
- end.sort.each do |method| %>
+ end.flatten.sort.each do |method| %>
<li class="method">
<a href="<%= method.path %>"><%= h method.pretty_name %></a>
&mdash;
diff --git a/lib/rdoc/generator/template/json_index/js/navigation.js b/lib/rdoc/generator/template/json_index/js/navigation.js
index 137e3a0038..dfad74b1ae 100644
--- a/lib/rdoc/generator/template/json_index/js/navigation.js
+++ b/lib/rdoc/generator/template/json_index/js/navigation.js
@@ -23,24 +23,24 @@ Navigation = new function() {
this.onkeydown = function(e) {
if (!this.navigationActive) return;
- switch(e.key) {
- case 'ArrowLeft':
+ switch(e.keyCode) {
+ case 37: //Event.KEY_LEFT:
if (this.moveLeft()) e.preventDefault();
break;
- case 'ArrowUp':
- if (e.key == 'ArrowUp' || e.ctrlKey) {
+ case 38: //Event.KEY_UP:
+ if (e.keyCode == 38 || e.ctrlKey) {
if (this.moveUp()) e.preventDefault();
}
break;
- case 'ArrowRight':
+ case 39: //Event.KEY_RIGHT:
if (this.moveRight()) e.preventDefault();
break;
- case 'ArrowDown':
- if (e.key == 'ArrowDown' || e.ctrlKey) {
+ case 40: //Event.KEY_DOWN:
+ if (e.keyCode == 40 || e.ctrlKey) {
if (this.moveDown()) e.preventDefault();
}
break;
- case 'Enter':
+ case 13: //Event.KEY_RETURN:
if (this.current) e.preventDefault();
this.select(this.current);
break;
diff --git a/lib/rdoc/ghost_method.rb b/lib/rdoc/ghost_method.rb
index 25f951e35e..2488feb9d7 100644
--- a/lib/rdoc/ghost_method.rb
+++ b/lib/rdoc/ghost_method.rb
@@ -4,3 +4,4 @@
class RDoc::GhostMethod < RDoc::AnyMethod
end
+
diff --git a/lib/rdoc/include.rb b/lib/rdoc/include.rb
index c3e0d45e47..b3ad610649 100644
--- a/lib/rdoc/include.rb
+++ b/lib/rdoc/include.rb
@@ -7,3 +7,4 @@
class RDoc::Include < RDoc::Mixin
end
+
diff --git a/lib/rdoc/markdown.rb b/lib/rdoc/markdown.rb
index 157f2fa3fe..a0709b6352 100644
--- a/lib/rdoc/markdown.rb
+++ b/lib/rdoc/markdown.rb
@@ -175,7 +175,7 @@
# [dingus]: http://daringfireball.net/projects/markdown/dingus
# [GFM]: https://github.github.com/gfm/
# [pegmarkdown]: https://github.com/jgm/peg-markdown
-# [PHPE]: https://michelf.ca/projects/php-markdown/extra/#def-list
+# [PHPE]: http://michelf.com/projects/php-markdown/extra/#def-list
# [syntax]: http://daringfireball.net/projects/markdown/syntax
#--
# Last updated to jgm/peg-markdown commit 8f8fc22ef0
diff --git a/lib/rdoc/markdown/entities.rb b/lib/rdoc/markdown/entities.rb
index 265c2eb3f3..d2cf610293 100644
--- a/lib/rdoc/markdown/entities.rb
+++ b/lib/rdoc/markdown/entities.rb
@@ -2129,3 +2129,4 @@ RDoc::Markdown::HTML_ENTITIES = {
"zwj" => [0x0200D],
"zwnj" => [0x0200C],
}
+
diff --git a/lib/rdoc/markdown/literals.rb b/lib/rdoc/markdown/literals.rb
index c5c15d3100..37659b7ae0 100644
--- a/lib/rdoc/markdown/literals.rb
+++ b/lib/rdoc/markdown/literals.rb
@@ -3,6 +3,7 @@
# :markup: markdown
##
+#--
# This set of literals is for Ruby 1.9 regular expressions and gives full
# unicode support.
#
diff --git a/lib/rdoc/markup/attr_changer.rb b/lib/rdoc/markup/attr_changer.rb
index e5ba470bb6..4c4bc6479e 100644
--- a/lib/rdoc/markup/attr_changer.rb
+++ b/lib/rdoc/markup/attr_changer.rb
@@ -20,3 +20,4 @@ class RDoc::Markup::AttrChanger
end
end
+
diff --git a/lib/rdoc/markup/attr_span.rb b/lib/rdoc/markup/attr_span.rb
index f1fabf1c3b..20ef11cd6d 100644
--- a/lib/rdoc/markup/attr_span.rb
+++ b/lib/rdoc/markup/attr_span.rb
@@ -33,3 +33,4 @@ class RDoc::Markup::AttrSpan
end
end
+
diff --git a/lib/rdoc/markup/attribute_manager.rb b/lib/rdoc/markup/attribute_manager.rb
index f6eb06da95..601e6bc189 100644
--- a/lib/rdoc/markup/attribute_manager.rb
+++ b/lib/rdoc/markup/attribute_manager.rb
@@ -1,19 +1,19 @@
# frozen_string_literal: true
-
##
# Manages changes of attributes in a block of text
-class RDoc::Markup::AttributeManager
- unless ::MatchData.method_defined?(:match_length)
- using ::Module.new {
- refine(::MatchData) {
- def match_length(nth) # :nodoc:
- b, e = offset(nth)
- e - b if b
- end
- }
+unless MatchData.method_defined?(:match_length)
+ using Module.new {
+ refine(MatchData) {
+ def match_length(nth)
+ b, e = offset(nth)
+ e - b if b
+ end
}
- end
+ }
+end
+
+class RDoc::Markup::AttributeManager
##
# The NUL character
@@ -138,7 +138,6 @@ class RDoc::Markup::AttributeManager
res
end
- # :nodoc:
def exclusive?(attr)
(attr & @exclusive_bitmap) != 0
end
@@ -156,7 +155,6 @@ class RDoc::Markup::AttributeManager
convert_attrs_word_pair_map(str, attrs, exclusive)
end
- # :nodoc:
def convert_attrs_matching_word_pairs(str, attrs, exclusive)
# first do matching ones
tags = @matching_word_pairs.select { |start, bitmap|
@@ -181,7 +179,6 @@ class RDoc::Markup::AttributeManager
str.delete!(NON_PRINTING_START + NON_PRINTING_END)
end
- # :nodoc:
def convert_attrs_word_pair_map(str, attrs, exclusive)
# then non-matching
unless @word_pair_map.empty? then
@@ -403,3 +400,4 @@ class RDoc::Markup::AttributeManager
end
end
+
diff --git a/lib/rdoc/markup/attributes.rb b/lib/rdoc/markup/attributes.rb
index d9d18b3059..ce014ce928 100644
--- a/lib/rdoc/markup/attributes.rb
+++ b/lib/rdoc/markup/attributes.rb
@@ -68,3 +68,4 @@ class RDoc::Markup::Attributes
end
end
+
diff --git a/lib/rdoc/markup/blank_line.rb b/lib/rdoc/markup/blank_line.rb
index f63ae9479c..3129ab5e7f 100644
--- a/lib/rdoc/markup/blank_line.rb
+++ b/lib/rdoc/markup/blank_line.rb
@@ -25,3 +25,4 @@ class RDoc::Markup::BlankLine
end
end
+
diff --git a/lib/rdoc/markup/block_quote.rb b/lib/rdoc/markup/block_quote.rb
index d9fcbf213c..7a4b3e36b0 100644
--- a/lib/rdoc/markup/block_quote.rb
+++ b/lib/rdoc/markup/block_quote.rb
@@ -12,3 +12,4 @@ class RDoc::Markup::BlockQuote < RDoc::Markup::Raw
end
end
+
diff --git a/lib/rdoc/markup/document.rb b/lib/rdoc/markup/document.rb
index 94cf6a3666..f3a5de1fc3 100644
--- a/lib/rdoc/markup/document.rb
+++ b/lib/rdoc/markup/document.rb
@@ -162,3 +162,4 @@ class RDoc::Markup::Document
end
end
+
diff --git a/lib/rdoc/markup/formatter.rb b/lib/rdoc/markup/formatter.rb
index 9daffaabb8..2bac76e838 100644
--- a/lib/rdoc/markup/formatter.rb
+++ b/lib/rdoc/markup/formatter.rb
@@ -90,7 +90,7 @@ class RDoc::Markup::Formatter
def add_regexp_handling_TIDYLINK
@markup.add_regexp_handling(/(?:
- \{[^{}]*\} | # multi-word label
+ \{.*?\} | # multi-word label
\b[^\s{}]+? # single-word label
)
@@ -263,3 +263,4 @@ class RDoc::Markup::Formatter
end
end
+
diff --git a/lib/rdoc/markup/hard_break.rb b/lib/rdoc/markup/hard_break.rb
index de1819c903..046068d5c2 100644
--- a/lib/rdoc/markup/hard_break.rb
+++ b/lib/rdoc/markup/hard_break.rb
@@ -29,3 +29,4 @@ class RDoc::Markup::HardBreak
end
end
+
diff --git a/lib/rdoc/markup/heading.rb b/lib/rdoc/markup/heading.rb
index 02476e5226..93a3a52000 100644
--- a/lib/rdoc/markup/heading.rb
+++ b/lib/rdoc/markup/heading.rb
@@ -76,3 +76,4 @@ RDoc::Markup::Heading =
end
end
+
diff --git a/lib/rdoc/markup/include.rb b/lib/rdoc/markup/include.rb
index 2bf63526b2..ad7c4a9640 100644
--- a/lib/rdoc/markup/include.rb
+++ b/lib/rdoc/markup/include.rb
@@ -40,3 +40,4 @@ class RDoc::Markup::Include
end
end
+
diff --git a/lib/rdoc/markup/indented_paragraph.rb b/lib/rdoc/markup/indented_paragraph.rb
index 992cd7cf81..d42b2e52b8 100644
--- a/lib/rdoc/markup/indented_paragraph.rb
+++ b/lib/rdoc/markup/indented_paragraph.rb
@@ -45,3 +45,4 @@ class RDoc::Markup::IndentedParagraph < RDoc::Markup::Raw
end
end
+
diff --git a/lib/rdoc/markup/list.rb b/lib/rdoc/markup/list.rb
index 112b7a1a86..05c3609202 100644
--- a/lib/rdoc/markup/list.rb
+++ b/lib/rdoc/markup/list.rb
@@ -99,3 +99,4 @@ class RDoc::Markup::List
end
end
+
diff --git a/lib/rdoc/markup/list_item.rb b/lib/rdoc/markup/list_item.rb
index 0b8326a69f..d22554ee73 100644
--- a/lib/rdoc/markup/list_item.rb
+++ b/lib/rdoc/markup/list_item.rb
@@ -97,3 +97,4 @@ class RDoc::Markup::ListItem
end
end
+
diff --git a/lib/rdoc/markup/paragraph.rb b/lib/rdoc/markup/paragraph.rb
index 21dfda007a..a2e45ef009 100644
--- a/lib/rdoc/markup/paragraph.rb
+++ b/lib/rdoc/markup/paragraph.rb
@@ -26,3 +26,4 @@ class RDoc::Markup::Paragraph < RDoc::Markup::Raw
end
end
+
diff --git a/lib/rdoc/markup/parser.rb b/lib/rdoc/markup/parser.rb
index 9c77048591..0029df7e65 100644
--- a/lib/rdoc/markup/parser.rb
+++ b/lib/rdoc/markup/parser.rb
@@ -218,7 +218,7 @@ class RDoc::Markup::Parser
break if peek_token.first == :BREAK
- data << ' ' if skip :NEWLINE and /#{SPACE_SEPARATED_LETTER_CLASS}\z/o.match?(data)
+ data << ' ' if skip :NEWLINE
else
unget
break
@@ -420,8 +420,6 @@ class RDoc::Markup::Parser
# A simple wrapper of StringScanner that is aware of the current column and lineno
class MyStringScanner
- # :stopdoc:
-
def initialize(input)
@line = @column = 0
@s = StringScanner.new input
@@ -458,8 +456,6 @@ class RDoc::Markup::Parser
def [](i)
@s[i]
end
-
- #:startdoc:
end
##
diff --git a/lib/rdoc/markup/raw.rb b/lib/rdoc/markup/raw.rb
index a7c1c210a6..85e2c8b825 100644
--- a/lib/rdoc/markup/raw.rb
+++ b/lib/rdoc/markup/raw.rb
@@ -67,3 +67,4 @@ class RDoc::Markup::Raw
end
end
+
diff --git a/lib/rdoc/markup/regexp_handling.rb b/lib/rdoc/markup/regexp_handling.rb
index c471fe73c7..6ed868c2c1 100644
--- a/lib/rdoc/markup/regexp_handling.rb
+++ b/lib/rdoc/markup/regexp_handling.rb
@@ -38,3 +38,4 @@ class RDoc::Markup::RegexpHandling
end
end
+
diff --git a/lib/rdoc/markup/rule.rb b/lib/rdoc/markup/rule.rb
index 448148d6d1..38c1dc7f56 100644
--- a/lib/rdoc/markup/rule.rb
+++ b/lib/rdoc/markup/rule.rb
@@ -18,3 +18,4 @@ class RDoc::Markup::Rule < Struct.new :weight
end
end
+
diff --git a/lib/rdoc/markup/table.rb b/lib/rdoc/markup/table.rb
index 27a20f073a..7bcb10aff3 100644
--- a/lib/rdoc/markup/table.rb
+++ b/lib/rdoc/markup/table.rb
@@ -3,21 +3,12 @@
# A section of table
class RDoc::Markup::Table
- # headers of each column
- attr_accessor :header
+ attr_accessor :header, :align, :body
- # alignments of each column
- attr_accessor :align
-
- # body texts of each column
- attr_accessor :body
-
- # Creates new instance
def initialize header, align, body
@header, @align, @body = header, align, body
end
- # :stopdoc:
def == other
self.class == other.class and
@header == other.header and
@@ -29,7 +20,7 @@ class RDoc::Markup::Table
visitor.accept_table @header, @body, @align
end
- def pretty_print q
+ def pretty_print q # :nodoc:
q.group 2, '[Table: ', ']' do
q.group 2, '[Head: ', ']' do
q.seplist @header.zip(@align) do |text, align|
diff --git a/lib/rdoc/markup/to_ansi.rb b/lib/rdoc/markup/to_ansi.rb
index c3eacab21a..6cc3b70e93 100644
--- a/lib/rdoc/markup/to_ansi.rb
+++ b/lib/rdoc/markup/to_ansi.rb
@@ -91,3 +91,4 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
end
end
+
diff --git a/lib/rdoc/markup/to_html.rb b/lib/rdoc/markup/to_html.rb
index 91cadf9d16..bf323074de 100644
--- a/lib/rdoc/markup/to_html.rb
+++ b/lib/rdoc/markup/to_html.rb
@@ -61,7 +61,6 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
#
# These methods are used by regexp handling markup added by RDoc::Markup#add_regexp_handling.
- # :nodoc:
URL_CHARACTERS_REGEXP_STR = /[A-Za-z0-9\-._~:\/\?#\[\]@!$&'\(\)*+,;%=]/.source
##
@@ -203,9 +202,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
def accept_paragraph paragraph
@res << "\n<p>"
text = paragraph.text @hard_break
- text = text.gsub(/(#{SPACE_SEPARATED_LETTER_CLASS})?\K\r?\n(?=(?(1)(#{SPACE_SEPARATED_LETTER_CLASS})?))/o) {
- defined?($2) && ' '
- }
+ text = text.gsub(/\r?\n/, ' ')
@res << to_html(text)
@res << "</p>\n"
end
@@ -433,9 +430,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
def parseable? text
verbose, $VERBOSE = $VERBOSE, nil
- catch(:valid) do
- eval("BEGIN { throw :valid, true }\n#{text}")
- end
+ eval("BEGIN {return true}\n#{text}")
rescue SyntaxError
false
ensure
@@ -450,3 +445,4 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
end
end
+
diff --git a/lib/rdoc/markup/to_html_crossref.rb b/lib/rdoc/markup/to_html_crossref.rb
index 01831461e3..a9fd09df41 100644
--- a/lib/rdoc/markup/to_html_crossref.rb
+++ b/lib/rdoc/markup/to_html_crossref.rb
@@ -42,7 +42,6 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
@cross_reference = RDoc::CrossReference.new @context
end
- # :nodoc:
def init_link_notation_regexp_handlings
add_regexp_handling_RDOCLINK
@@ -174,3 +173,4 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
end
end
+
diff --git a/lib/rdoc/markup/to_html_snippet.rb b/lib/rdoc/markup/to_html_snippet.rb
index f471395a3a..4eb36592b7 100644
--- a/lib/rdoc/markup/to_html_snippet.rb
+++ b/lib/rdoc/markup/to_html_snippet.rb
@@ -66,9 +66,6 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
alias accept_rule ignore
- ##
- # Adds +paragraph+ to the output
-
def accept_paragraph paragraph
para = @in_list_entry.last || "<p>"
@@ -285,3 +282,4 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
end
end
+
diff --git a/lib/rdoc/markup/to_joined_paragraph.rb b/lib/rdoc/markup/to_joined_paragraph.rb
index 31cbe0853c..46e07c94ad 100644
--- a/lib/rdoc/markup/to_joined_paragraph.rb
+++ b/lib/rdoc/markup/to_joined_paragraph.rb
@@ -25,9 +25,9 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
def accept_paragraph paragraph
parts = paragraph.parts.chunk do |part|
String === part
- end.flat_map do |string, chunk|
+ end.map do |string, chunk|
string ? chunk.join.rstrip : chunk
- end
+ end.flatten
paragraph.parts.replace parts
end
@@ -44,3 +44,4 @@ class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter
alias accept_table ignore
end
+
diff --git a/lib/rdoc/markup/to_label.rb b/lib/rdoc/markup/to_label.rb
index cf808364e9..aa1dbcf2a1 100644
--- a/lib/rdoc/markup/to_label.rb
+++ b/lib/rdoc/markup/to_label.rb
@@ -72,3 +72,4 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
alias start_accepting ignore
end
+
diff --git a/lib/rdoc/markup/to_markdown.rb b/lib/rdoc/markup/to_markdown.rb
index 5dd60e18f5..3ee48becb0 100644
--- a/lib/rdoc/markup/to_markdown.rb
+++ b/lib/rdoc/markup/to_markdown.rb
@@ -189,3 +189,4 @@ class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc
end
end
+
diff --git a/lib/rdoc/markup/to_rdoc.rb b/lib/rdoc/markup/to_rdoc.rb
index 6929049582..2a9b05625c 100644
--- a/lib/rdoc/markup/to_rdoc.rb
+++ b/lib/rdoc/markup/to_rdoc.rb
@@ -342,3 +342,4 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
end
end
+
diff --git a/lib/rdoc/markup/to_table_of_contents.rb b/lib/rdoc/markup/to_table_of_contents.rb
index e5b8225ba3..eb8e8faa16 100644
--- a/lib/rdoc/markup/to_table_of_contents.rb
+++ b/lib/rdoc/markup/to_table_of_contents.rb
@@ -86,3 +86,4 @@ class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter
# :startdoc:
end
+
diff --git a/lib/rdoc/markup/to_test.rb b/lib/rdoc/markup/to_test.rb
index 30113da561..61d3cffaf0 100644
--- a/lib/rdoc/markup/to_test.rb
+++ b/lib/rdoc/markup/to_test.rb
@@ -67,3 +67,4 @@ class RDoc::Markup::ToTest < RDoc::Markup::Formatter
# :startdoc:
end
+
diff --git a/lib/rdoc/markup/to_tt_only.rb b/lib/rdoc/markup/to_tt_only.rb
index 9ac14ed235..9235d33f04 100644
--- a/lib/rdoc/markup/to_tt_only.rb
+++ b/lib/rdoc/markup/to_tt_only.rb
@@ -118,3 +118,4 @@ class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter
end
end
+
diff --git a/lib/rdoc/markup/verbatim.rb b/lib/rdoc/markup/verbatim.rb
index f51c2cfa14..7f1bc29a09 100644
--- a/lib/rdoc/markup/verbatim.rb
+++ b/lib/rdoc/markup/verbatim.rb
@@ -81,3 +81,4 @@ class RDoc::Markup::Verbatim < RDoc::Markup::Raw
end
end
+
diff --git a/lib/rdoc/meta_method.rb b/lib/rdoc/meta_method.rb
index 8c95a0f78c..7927a9ce9c 100644
--- a/lib/rdoc/meta_method.rb
+++ b/lib/rdoc/meta_method.rb
@@ -4,3 +4,4 @@
class RDoc::MetaMethod < RDoc::AnyMethod
end
+
diff --git a/lib/rdoc/method_attr.rb b/lib/rdoc/method_attr.rb
index 61ddb32f46..aae3c47e85 100644
--- a/lib/rdoc/method_attr.rb
+++ b/lib/rdoc/method_attr.rb
@@ -416,3 +416,4 @@ class RDoc::MethodAttr < RDoc::CodeObject
end
end
+
diff --git a/lib/rdoc/mixin.rb b/lib/rdoc/mixin.rb
index fa8faefc15..379d7cc526 100644
--- a/lib/rdoc/mixin.rb
+++ b/lib/rdoc/mixin.rb
@@ -118,3 +118,4 @@ class RDoc::Mixin < RDoc::CodeObject
end
end
+
diff --git a/lib/rdoc/normal_class.rb b/lib/rdoc/normal_class.rb
index aa340b5d15..68dfa7d4a3 100644
--- a/lib/rdoc/normal_class.rb
+++ b/lib/rdoc/normal_class.rb
@@ -90,3 +90,4 @@ class RDoc::NormalClass < RDoc::ClassModule
end
end
+
diff --git a/lib/rdoc/normal_module.rb b/lib/rdoc/normal_module.rb
index 498ec4dde2..edf29f8f1c 100644
--- a/lib/rdoc/normal_module.rb
+++ b/lib/rdoc/normal_module.rb
@@ -71,3 +71,4 @@ class RDoc::NormalModule < RDoc::ClassModule
end
end
+
diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb
index 6ee29fd071..eed0f6b39b 100644
--- a/lib/rdoc/options.rb
+++ b/lib/rdoc/options.rb
@@ -565,10 +565,9 @@ class RDoc::Options
@op_dir ||= 'doc'
+ @rdoc_include << "." if @rdoc_include.empty?
root = @root.to_s
- if @rdoc_include.empty? || !@rdoc_include.include?(root)
- @rdoc_include << root
- end
+ @rdoc_include << root unless @rdoc_include.include?(root)
@exclude = self.exclude
diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb
index d668507dc2..5695bf1acb 100644
--- a/lib/rdoc/parser/c.rb
+++ b/lib/rdoc/parser/c.rb
@@ -575,18 +575,19 @@ class RDoc::Parser::C < RDoc::Parser
table = {}
file_content.scan(%r{
((?>/\*.*?\*/\s*)?)
- ((?:\w+\s+){0,2} VALUE\s+(\w+)
- \s*(?:\([^\)]*\))(?:[^\);]|$))
+ ((?:(?:\w+)\s+)?
+ (?:intern\s+)?VALUE\s+(\w+)
+ \s*(?:\([^)]*\))(?:[^\);]|$))
| ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+))
| ^\s*\#\s*define\s+(\w+)\s+(\w+)
}xm) do
case
- when name = $3
- table[name] = [:func_def, $1, $2, $~.offset(2)] if !(t = table[name]) || t[0] != :func_def
- when name = $6
- table[name] = [:macro_def, $4, $5, $~.offset(5), $7] if !(t = table[name]) || t[0] == :macro_alias
- when name = $8
- table[name] ||= [:macro_alias, $9]
+ when $1
+ table[$3] = [:func_def, $1, $2, $~.offset(2)] if !table[$3] || table[$3][0] != :func_def
+ when $4
+ table[$6] = [:macro_def, $4, $5, $~.offset(5), $7] if !table[$6] || table[$6][0] == :macro_alias
+ when $8
+ table[$8] ||= [:macro_alias, $9]
end
end
table
@@ -938,13 +939,14 @@ class RDoc::Parser::C < RDoc::Parser
# "/* definition: comment */" form. The literal ':' and '\' characters
# can be escaped with a backslash.
if type.downcase == 'const' then
- if /\A(.+?)?:(?!\S)/ =~ comment.text
- new_definition, new_comment = $1, $'
+ no_match, new_definition, new_comment = comment.text.split(/(\A.*):/)
- if !new_definition # Default to literal C definition
+ if no_match and no_match.empty? then
+ if new_definition.empty? then # Default to literal C definition
new_definition = definition
else
- new_definition = new_definition.gsub(/\\([\\:])/, '\1')
+ new_definition = new_definition.gsub("\:", ":")
+ new_definition = new_definition.gsub("\\", '\\')
end
new_definition.sub!(/\A(\s+)/, '')
@@ -1215,9 +1217,6 @@ class RDoc::Parser::C < RDoc::Parser
@top_level
end
- ##
- # Creates a RDoc::Comment instance.
-
def new_comment text = nil, location = nil, language = nil
RDoc::Comment.new(text, location, language).tap do |comment|
comment.format = @markup
diff --git a/lib/rdoc/parser/changelog.rb b/lib/rdoc/parser/changelog.rb
index a046241870..9245d49376 100644
--- a/lib/rdoc/parser/changelog.rb
+++ b/lib/rdoc/parser/changelog.rb
@@ -216,22 +216,12 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
@top_level
end
- ##
- # The extension for Git commit log
-
module Git
- ##
- # Parses auxiliary info. Currentry `base-url` to expand
- # references is effective.
-
def parse_info(info)
/^\s*base-url\s*=\s*(.*\S)/ =~ info
@base_url = $1
end
- ##
- # Parses the entries in the Git commit logs
-
def parse_entries
entries = []
@@ -254,11 +244,6 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
entries
end
- ##
- # Returns a list of ChangeLog entries as
- # RDoc::Parser::ChangeLog::Git::LogEntry list for the given
- # +entries+.
-
def create_entries entries
# git log entries have no strictly itemized style like the old
# style, just assume Markdown.
@@ -347,3 +332,4 @@ class RDoc::Parser::ChangeLog < RDoc::Parser
end
end
end
+
diff --git a/lib/rdoc/parser/markdown.rb b/lib/rdoc/parser/markdown.rb
index 3c316227b9..9ff478f872 100644
--- a/lib/rdoc/parser/markdown.rb
+++ b/lib/rdoc/parser/markdown.rb
@@ -20,3 +20,5 @@ class RDoc::Parser::Markdown < RDoc::Parser
end
end
+
+
diff --git a/lib/rdoc/parser/rd.rb b/lib/rdoc/parser/rd.rb
index 19e47e549d..25f5711731 100644
--- a/lib/rdoc/parser/rd.rb
+++ b/lib/rdoc/parser/rd.rb
@@ -20,3 +20,4 @@ class RDoc::Parser::RD < RDoc::Parser
end
end
+
diff --git a/lib/rdoc/parser/ripper_state_lex.rb b/lib/rdoc/parser/ripper_state_lex.rb
index f6cefd0305..5492f08726 100644
--- a/lib/rdoc/parser/ripper_state_lex.rb
+++ b/lib/rdoc/parser/ripper_state_lex.rb
@@ -1,12 +1,7 @@
# frozen_string_literal: true
require 'ripper'
-##
-# Wrapper for Ripper lex states
-
class RDoc::Parser::RipperStateLex
- # :stopdoc:
-
# TODO: Remove this constants after Ruby 2.4 EOL
RIPPER_HAS_LEX_STATE = Ripper::Filter.method_defined?(:state)
@@ -373,7 +368,7 @@ class RDoc::Parser::RipperStateLex
private def get_symbol_tk(tk)
is_symbol = true
symbol_tk = Token.new(tk.line_no, tk.char_no, :on_symbol)
- if ":'" == tk[:text] or ':"' == tk[:text] or tk[:text].start_with?('%s')
+ if ":'" == tk[:text] or ':"' == tk[:text]
tk1 = get_string_tk(tk)
symbol_tk[:text] = tk1[:text]
symbol_tk[:state] = tk1[:state]
@@ -570,9 +565,6 @@ class RDoc::Parser::RipperStateLex
tk
end
- # :startdoc:
-
- # New lexer for +code+.
def initialize(code)
@buf = []
@heredoc_queue = []
@@ -580,7 +572,6 @@ class RDoc::Parser::RipperStateLex
@tokens = @inner_lex.parse([])
end
- # Returns tokens parsed from +code+.
def self.parse(code)
lex = self.new(code)
tokens = []
@@ -593,7 +584,6 @@ class RDoc::Parser::RipperStateLex
tokens
end
- # Returns +true+ if lex state will be +END+ after +token+.
def self.end?(token)
(token[:state] & EXPR_END)
end
diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb
index 39c3bae4c4..b74ead65ab 100644
--- a/lib/rdoc/parser/ruby.rb
+++ b/lib/rdoc/parser/ruby.rb
@@ -8,9 +8,6 @@
# by Keiju ISHITSUKA (Nippon Rational Inc.)
#
-require 'ripper'
-require_relative 'ripper_state_lex'
-
##
# Extracts code elements from a source file returning a TopLevel object
# containing the constituent file elements.
@@ -141,6 +138,9 @@ require_relative 'ripper_state_lex'
# Note that by default, the :method: directive will be ignored if there is a
# standard rdocable item following it.
+require 'ripper'
+require_relative 'ripper_state_lex'
+
class RDoc::Parser::Ruby < RDoc::Parser
parse_files_matching(/\.rbw?$/)
@@ -180,9 +180,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
reset
end
- ##
- # Return +true+ if +tk+ is a newline.
-
def tk_nl?(tk)
:on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
end
@@ -2137,7 +2134,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
if :on_nl == tk[:kind] or (:on_kw == tk[:kind] && 'def' == tk[:text]) then
return
elsif :on_comment == tk[:kind] or :on_embdoc == tk[:kind] then
- return unless tk[:text] =~ /:?\b([\w-]+):\s*(.*)/
+ return unless tk[:text] =~ /\s*:?([\w-]+):\s*(.*)/
directive = $1.downcase
diff --git a/lib/rdoc/parser/ruby_tools.rb b/lib/rdoc/parser/ruby_tools.rb
index 40ea517c4d..681d7166ce 100644
--- a/lib/rdoc/parser/ruby_tools.rb
+++ b/lib/rdoc/parser/ruby_tools.rb
@@ -163,3 +163,5 @@ module RDoc::Parser::RubyTools
end
end
+
+
diff --git a/lib/rdoc/parser/text.rb b/lib/rdoc/parser/text.rb
index 5095d8cc64..01de0cc595 100644
--- a/lib/rdoc/parser/text.rb
+++ b/lib/rdoc/parser/text.rb
@@ -9,3 +9,4 @@
module RDoc::Parser::Text
end
+
diff --git a/lib/rdoc/rd/block_parser.rb b/lib/rdoc/rd/block_parser.rb
index 527147d91d..6f70622c0b 100644
--- a/lib/rdoc/rd/block_parser.rb
+++ b/lib/rdoc/rd/block_parser.rb
@@ -1,659 +1,11 @@
# frozen_string_literal: true
#
# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.7.3
-# from Racc grammar file "block_parser.ry".
+# This file is automatically generated by Racc 1.6.0
+# from Racc grammar file "".
#
-###### racc/parser.rb begin
-unless $".find {|p| p.end_with?('/racc/parser.rb')}
-$".push "#{__dir__}/racc/parser.rb"
-#--
-# Copyright (c) 1999-2006 Minero Aoki
-#
-# This program is free software.
-# You can distribute/modify this program under the same terms of ruby.
-#
-# As a special exception, when this code is copied by Racc
-# into a Racc output file, you may use that output file
-# without restriction.
-#++
-
-unless $".find {|p| p.end_with?('/racc/info.rb')}
-$".push "#{__dir__}/racc/info.rb"
-
-module Racc
- VERSION = '1.7.3'
- Version = VERSION
- Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
-end
-
-end
-
-
-unless defined?(NotImplementedError)
- NotImplementedError = NotImplementError # :nodoc:
-end
-
-module Racc
- class ParseError < StandardError; end
-end
-unless defined?(::ParseError)
- ParseError = Racc::ParseError # :nodoc:
-end
-
-# Racc is a LALR(1) parser generator.
-# It is written in Ruby itself, and generates Ruby programs.
-#
-# == Command-line Reference
-#
-# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
-# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
-# [-v] [--verbose]
-# [-O<var>filename</var>] [--log-file=<var>filename</var>]
-# [-g] [--debug]
-# [-E] [--embedded]
-# [-l] [--no-line-convert]
-# [-c] [--line-convert-all]
-# [-a] [--no-omit-actions]
-# [-C] [--check-only]
-# [-S] [--output-status]
-# [--version] [--copyright] [--help] <var>grammarfile</var>
-#
-# [+grammarfile+]
-# Racc grammar file. Any extension is permitted.
-# [-o+outfile+, --output-file=+outfile+]
-# A filename for output. default is <+filename+>.tab.rb
-# [-O+filename+, --log-file=+filename+]
-# Place logging output in file +filename+.
-# Default log file name is <+filename+>.output.
-# [-e+rubypath+, --executable=+rubypath+]
-# output executable file(mode 755). where +path+ is the Ruby interpreter.
-# [-v, --verbose]
-# verbose mode. create +filename+.output file, like yacc's y.output file.
-# [-g, --debug]
-# add debug code to parser class. To display debugging information,
-# use this '-g' option and set @yydebug true in parser class.
-# [-E, --embedded]
-# Output parser which doesn't need runtime files (racc/parser.rb).
-# [-F, --frozen]
-# Output parser which declares frozen_string_literals: true
-# [-C, --check-only]
-# Check syntax of racc grammar file and quit.
-# [-S, --output-status]
-# Print messages time to time while compiling.
-# [-l, --no-line-convert]
-# turns off line number converting.
-# [-c, --line-convert-all]
-# Convert line number of actions, inner, header and footer.
-# [-a, --no-omit-actions]
-# Call all actions, even if an action is empty.
-# [--version]
-# print Racc version and quit.
-# [--copyright]
-# Print copyright and quit.
-# [--help]
-# Print usage and quit.
-#
-# == Generating Parser Using Racc
-#
-# To compile Racc grammar file, simply type:
-#
-# $ racc parse.y
-#
-# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
-#
-# == Writing A Racc Grammar File
-#
-# If you want your own parser, you have to write a grammar file.
-# A grammar file contains the name of your parser class, grammar for the parser,
-# user code, and anything else.
-# When writing a grammar file, yacc's knowledge is helpful.
-# If you have not used yacc before, Racc is not too difficult.
-#
-# Here's an example Racc grammar file.
-#
-# class Calcparser
-# rule
-# target: exp { print val[0] }
-#
-# exp: exp '+' exp
-# | exp '*' exp
-# | '(' exp ')'
-# | NUMBER
-# end
-#
-# Racc grammar files resemble yacc files.
-# But (of course), this is Ruby code.
-# yacc's $$ is the 'result', $0, $1... is
-# an array called 'val', and $-1, $-2... is an array called '_values'.
-#
-# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
-# more information on grammar files.
-#
-# == Parser
-#
-# Then you must prepare the parse entry method. There are two types of
-# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
-#
-# Racc::Parser#do_parse is simple.
-#
-# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
-# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
-# EOF is [false, false].
-# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
-# If you want to change this, see the grammar reference.
-#
-# Racc::Parser#yyparse is little complicated, but useful.
-# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
-#
-# For example, <code>yyparse(obj, :scan)</code> causes
-# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
-#
-# == Debugging
-#
-# When debugging, "-v" or/and the "-g" option is helpful.
-#
-# "-v" creates verbose log file (.output).
-# "-g" creates a "Verbose Parser".
-# Verbose Parser prints the internal status when parsing.
-# But it's _not_ automatic.
-# You must use -g option and set +@yydebug+ to +true+ in order to get output.
-# -g option only creates the verbose parser.
-#
-# === Racc reported syntax error.
-#
-# Isn't there too many "end"?
-# grammar of racc file is changed in v0.10.
-#
-# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
-#
-# === Racc reported "XXXX conflicts".
-#
-# Try "racc -v xxxx.y".
-# It causes producing racc's internal log file, xxxx.output.
-#
-# === Generated parsers does not work correctly
-#
-# Try "racc -g xxxx.y".
-# This command let racc generate "debugging parser".
-# Then set @yydebug=true in your parser.
-# It produces a working log of your parser.
-#
-# == Re-distributing Racc runtime
-#
-# A parser, which is created by Racc, requires the Racc runtime module;
-# racc/parser.rb.
-#
-# Ruby 1.8.x comes with Racc runtime module,
-# you need NOT distribute Racc runtime files.
-#
-# If you want to include the Racc runtime module with your parser.
-# This can be done by using '-E' option:
-#
-# $ racc -E -omyparser.rb myparser.y
-#
-# This command creates myparser.rb which `includes' Racc runtime.
-# Only you must do is to distribute your parser file (myparser.rb).
-#
-# Note: parser.rb is ruby license, but your parser is not.
-# Your own parser is completely yours.
-module Racc
-
- unless defined?(Racc_No_Extensions)
- Racc_No_Extensions = false # :nodoc:
- end
-
- class Parser
-
- Racc_Runtime_Version = ::Racc::VERSION
- Racc_Runtime_Core_Version_R = ::Racc::VERSION
-
- begin
- if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
- require 'jruby'
- require 'racc/cparse-jruby.jar'
- com.headius.racc.Cparse.new.load(JRuby.runtime, false)
- else
- require 'racc/cparse'
- end
-
- unless new.respond_to?(:_racc_do_parse_c, true)
- raise LoadError, 'old cparse.so'
- end
- if Racc_No_Extensions
- raise LoadError, 'selecting ruby version of racc runtime core'
- end
-
- Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
- Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
- Racc_Runtime_Type = 'c' # :nodoc:
- rescue LoadError
- Racc_Main_Parsing_Routine = :_racc_do_parse_rb
- Racc_YY_Parse_Method = :_racc_yyparse_rb
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
- Racc_Runtime_Type = 'ruby'
- end
-
- def Parser.racc_runtime_type # :nodoc:
- Racc_Runtime_Type
- end
-
- def _racc_setup
- @yydebug = false unless self.class::Racc_debug_parser
- @yydebug = false unless defined?(@yydebug)
- if @yydebug
- @racc_debug_out = $stderr unless defined?(@racc_debug_out)
- @racc_debug_out ||= $stderr
- end
- arg = self.class::Racc_arg
- arg[13] = true if arg.size < 14
- arg
- end
-
- def _racc_init_sysvars
- @racc_state = [0]
- @racc_tstack = []
- @racc_vstack = []
-
- @racc_t = nil
- @racc_val = nil
-
- @racc_read_next = true
-
- @racc_user_yyerror = false
- @racc_error_status = 0
- end
-
- # The entry point of the parser. This method is used with #next_token.
- # If Racc wants to get token (and its value), calls next_token.
- #
- # Example:
- # def parse
- # @q = [[1,1],
- # [2,2],
- # [3,3],
- # [false, '$']]
- # do_parse
- # end
- #
- # def next_token
- # @q.shift
- # end
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
- def do_parse
- #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
- end
- RUBY
-
- # The method to fetch next token.
- # If you use #do_parse method, you must implement #next_token.
- #
- # The format of return value is [TOKEN_SYMBOL, VALUE].
- # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
- # for 'IDENT'. ";" (String) for ';'.
- #
- # The final symbol (End of file) must be false.
- def next_token
- raise NotImplementedError, "#{self.class}\#next_token is not defined"
- end
-
- def _racc_do_parse_rb(arg, in_debug)
- action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, * = arg
-
- _racc_init_sysvars
- tok = act = i = nil
-
- catch(:racc_end_parse) {
- while true
- if i = action_pointer[@racc_state[-1]]
- if @racc_read_next
- if @racc_t != 0 # not EOF
- tok, @racc_val = next_token()
- unless tok # EOF
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- racc_read_token(@racc_t, tok, @racc_val) if @yydebug
- @racc_read_next = false
- end
- end
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- else
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- }
- end
-
- # Another entry point for the parser.
- # If you use this method, you must implement RECEIVER#METHOD_ID method.
- #
- # RECEIVER#METHOD_ID is a method to get next token.
- # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
- def yyparse(recv, mid)
- #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
- end
- RUBY
-
- def _racc_yyparse_rb(recv, mid, arg, c_debug)
- action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, * = arg
-
- _racc_init_sysvars
-
- catch(:racc_end_parse) {
- until i = action_pointer[@racc_state[-1]]
- while act = _racc_evalact(action_default[@racc_state[-1]], arg)
- ;
- end
- end
- recv.__send__(mid) do |tok, val|
- unless tok
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- @racc_val = val
- @racc_read_next = false
-
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
-
- while !(i = action_pointer[@racc_state[-1]]) ||
- ! @racc_read_next ||
- @racc_t == 0 # $
- unless i and i += @racc_t and
- i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- end
- }
- end
-
- ###
- ### common
- ###
-
- def _racc_evalact(act, arg)
- action_table, action_check, _, action_pointer,
- _, _, _, _,
- _, _, _, shift_n,
- reduce_n, * = arg
- nerr = 0 # tmp
-
- if act > 0 and act < shift_n
- #
- # shift
- #
- if @racc_error_status > 0
- @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
- end
- @racc_vstack.push @racc_val
- @racc_state.push act
- @racc_read_next = true
- if @yydebug
- @racc_tstack.push @racc_t
- racc_shift @racc_t, @racc_tstack, @racc_vstack
- end
-
- elsif act < 0 and act > -reduce_n
- #
- # reduce
- #
- code = catch(:racc_jump) {
- @racc_state.push _racc_do_reduce(arg, act)
- false
- }
- if code
- case code
- when 1 # yyerror
- @racc_user_yyerror = true # user_yyerror
- return -reduce_n
- when 2 # yyaccept
- return shift_n
- else
- raise '[Racc Bug] unknown jump code'
- end
- end
-
- elsif act == shift_n
- #
- # accept
- #
- racc_accept if @yydebug
- throw :racc_end_parse, @racc_vstack[0]
-
- elsif act == -reduce_n
- #
- # error
- #
- case @racc_error_status
- when 0
- unless arg[21] # user_yyerror
- nerr += 1
- on_error @racc_t, @racc_val, @racc_vstack
- end
- when 3
- if @racc_t == 0 # is $
- # We're at EOF, and another error occurred immediately after
- # attempting auto-recovery
- throw :racc_end_parse, nil
- end
- @racc_read_next = true
- end
- @racc_user_yyerror = false
- @racc_error_status = 3
- while true
- if i = action_pointer[@racc_state[-1]]
- i += 1 # error token
- if i >= 0 and
- (act = action_table[i]) and
- action_check[i] == @racc_state[-1]
- break
- end
- end
- throw :racc_end_parse, nil if @racc_state.size <= 1
- @racc_state.pop
- @racc_vstack.pop
- if @yydebug
- @racc_tstack.pop
- racc_e_pop @racc_state, @racc_tstack, @racc_vstack
- end
- end
- return act
-
- else
- raise "[Racc Bug] unknown action #{act.inspect}"
- end
-
- racc_next_state(@racc_state[-1], @racc_state) if @yydebug
-
- nil
- end
-
- def _racc_do_reduce(arg, act)
- _, _, _, _,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, _, _,
- _, use_result, * = arg
-
- state = @racc_state
- vstack = @racc_vstack
- tstack = @racc_tstack
-
- i = act * -3
- len = reduce_table[i]
- reduce_to = reduce_table[i+1]
- method_id = reduce_table[i+2]
- void_array = []
-
- tmp_t = tstack[-len, len] if @yydebug
- tmp_v = vstack[-len, len]
- tstack[-len, len] = void_array if @yydebug
- vstack[-len, len] = void_array
- state[-len, len] = void_array
-
- # tstack must be updated AFTER method call
- if use_result
- vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
- else
- vstack.push __send__(method_id, tmp_v, vstack)
- end
- tstack.push reduce_to
-
- racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
-
- k1 = reduce_to - nt_base
- if i = goto_pointer[k1]
- i += state[-1]
- if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
- return curstate
- end
- end
- goto_default[k1]
- end
-
- # This method is called when a parse error is found.
- #
- # ERROR_TOKEN_ID is an internal ID of token which caused error.
- # You can get string representation of this ID by calling
- # #token_to_str.
- #
- # ERROR_VALUE is a value of error token.
- #
- # value_stack is a stack of symbol values.
- # DO NOT MODIFY this object.
- #
- # This method raises ParseError by default.
- #
- # If this method returns, parsers enter "error recovering mode".
- def on_error(t, val, vstack)
- raise ParseError, sprintf("parse error on value %s (%s)",
- val.inspect, token_to_str(t) || '?')
- end
-
- # Enter error recovering mode.
- # This method does not call #on_error.
- def yyerror
- throw :racc_jump, 1
- end
-
- # Exit parser.
- # Return value is +Symbol_Value_Stack[0]+.
- def yyaccept
- throw :racc_jump, 2
- end
-
- # Leave error recovering mode.
- def yyerrok
- @racc_error_status = 0
- end
-
- # For debugging output
- def racc_read_token(t, tok, val)
- @racc_debug_out.print 'read '
- @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
- @racc_debug_out.puts val.inspect
- @racc_debug_out.puts
- end
-
- def racc_shift(tok, tstack, vstack)
- @racc_debug_out.puts "shift #{racc_token2str tok}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_reduce(toks, sim, tstack, vstack)
- out = @racc_debug_out
- out.print 'reduce '
- if toks.empty?
- out.print ' <none>'
- else
- toks.each {|t| out.print ' ', racc_token2str(t) }
- end
- out.puts " --> #{racc_token2str(sim)}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_accept
- @racc_debug_out.puts 'accept'
- @racc_debug_out.puts
- end
-
- def racc_e_pop(state, tstack, vstack)
- @racc_debug_out.puts 'error recovering mode: pop token'
- racc_print_states state
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_next_state(curstate, state)
- @racc_debug_out.puts "goto #{curstate}"
- racc_print_states state
- @racc_debug_out.puts
- end
-
- def racc_print_stacks(t, v)
- out = @racc_debug_out
- out.print ' ['
- t.each_index do |i|
- out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
- end
- out.puts ' ]'
- end
-
- def racc_print_states(s)
- out = @racc_debug_out
- out.print ' ['
- s.each {|st| out.print ' ', st }
- out.puts ' ]'
- end
-
- def racc_token2str(tok)
- self.class::Racc_token_to_s_table[tok] or
- raise "[Racc Bug] can't convert token #{tok} to string"
- end
-
- # Convert internal ID of token symbol to the string.
- def token_to_str(t)
- self.class::Racc_token_to_s_table[t]
- end
-
- end
-
-end
-
-end
-###### racc/parser.rb end
+require 'racc/parser.rb'
class RDoc::RD
@@ -1008,7 +360,7 @@ def get_included(file)
file_name = File.join dir, file
if File.exist? file_name then
- included = File.readlines file_name
+ included = IO.readlines file_name
break
end
end
@@ -1272,7 +624,6 @@ Racc_arg = [
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
-Ractor.make_shareable(Racc_arg) if defined?(Ractor)
Racc_token_to_s_table = [
"$end",
@@ -1323,7 +674,6 @@ Racc_token_to_s_table = [
"blocks_in_list",
"block_in_list",
"whitelines2" ]
-Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
Racc_debug_parser = false
diff --git a/lib/rdoc/rd/inline.rb b/lib/rdoc/rd/inline.rb
index 77d88b2860..e5cb545728 100644
--- a/lib/rdoc/rd/inline.rb
+++ b/lib/rdoc/rd/inline.rb
@@ -69,3 +69,4 @@ class RDoc::RD::Inline
alias to_s rdoc # :nodoc:
end
+
diff --git a/lib/rdoc/rd/inline_parser.rb b/lib/rdoc/rd/inline_parser.rb
index adacf64d5b..c1da35a109 100644
--- a/lib/rdoc/rd/inline_parser.rb
+++ b/lib/rdoc/rd/inline_parser.rb
@@ -1,659 +1,11 @@
# frozen_string_literal: true
#
# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.7.3
-# from Racc grammar file "inline_parser.ry".
+# This file is automatically generated by Racc 1.6.0
+# from Racc grammar file "".
#
-###### racc/parser.rb begin
-unless $".find {|p| p.end_with?('/racc/parser.rb')}
-$".push "#{__dir__}/racc/parser.rb"
-#--
-# Copyright (c) 1999-2006 Minero Aoki
-#
-# This program is free software.
-# You can distribute/modify this program under the same terms of ruby.
-#
-# As a special exception, when this code is copied by Racc
-# into a Racc output file, you may use that output file
-# without restriction.
-#++
-
-unless $".find {|p| p.end_with?('/racc/info.rb')}
-$".push "#{__dir__}/racc/info.rb"
-
-module Racc
- VERSION = '1.7.3'
- Version = VERSION
- Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
-end
-
-end
-
-
-unless defined?(NotImplementedError)
- NotImplementedError = NotImplementError # :nodoc:
-end
-
-module Racc
- class ParseError < StandardError; end
-end
-unless defined?(::ParseError)
- ParseError = Racc::ParseError # :nodoc:
-end
-
-# Racc is a LALR(1) parser generator.
-# It is written in Ruby itself, and generates Ruby programs.
-#
-# == Command-line Reference
-#
-# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
-# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
-# [-v] [--verbose]
-# [-O<var>filename</var>] [--log-file=<var>filename</var>]
-# [-g] [--debug]
-# [-E] [--embedded]
-# [-l] [--no-line-convert]
-# [-c] [--line-convert-all]
-# [-a] [--no-omit-actions]
-# [-C] [--check-only]
-# [-S] [--output-status]
-# [--version] [--copyright] [--help] <var>grammarfile</var>
-#
-# [+grammarfile+]
-# Racc grammar file. Any extension is permitted.
-# [-o+outfile+, --output-file=+outfile+]
-# A filename for output. default is <+filename+>.tab.rb
-# [-O+filename+, --log-file=+filename+]
-# Place logging output in file +filename+.
-# Default log file name is <+filename+>.output.
-# [-e+rubypath+, --executable=+rubypath+]
-# output executable file(mode 755). where +path+ is the Ruby interpreter.
-# [-v, --verbose]
-# verbose mode. create +filename+.output file, like yacc's y.output file.
-# [-g, --debug]
-# add debug code to parser class. To display debugging information,
-# use this '-g' option and set @yydebug true in parser class.
-# [-E, --embedded]
-# Output parser which doesn't need runtime files (racc/parser.rb).
-# [-F, --frozen]
-# Output parser which declares frozen_string_literals: true
-# [-C, --check-only]
-# Check syntax of racc grammar file and quit.
-# [-S, --output-status]
-# Print messages time to time while compiling.
-# [-l, --no-line-convert]
-# turns off line number converting.
-# [-c, --line-convert-all]
-# Convert line number of actions, inner, header and footer.
-# [-a, --no-omit-actions]
-# Call all actions, even if an action is empty.
-# [--version]
-# print Racc version and quit.
-# [--copyright]
-# Print copyright and quit.
-# [--help]
-# Print usage and quit.
-#
-# == Generating Parser Using Racc
-#
-# To compile Racc grammar file, simply type:
-#
-# $ racc parse.y
-#
-# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
-#
-# == Writing A Racc Grammar File
-#
-# If you want your own parser, you have to write a grammar file.
-# A grammar file contains the name of your parser class, grammar for the parser,
-# user code, and anything else.
-# When writing a grammar file, yacc's knowledge is helpful.
-# If you have not used yacc before, Racc is not too difficult.
-#
-# Here's an example Racc grammar file.
-#
-# class Calcparser
-# rule
-# target: exp { print val[0] }
-#
-# exp: exp '+' exp
-# | exp '*' exp
-# | '(' exp ')'
-# | NUMBER
-# end
-#
-# Racc grammar files resemble yacc files.
-# But (of course), this is Ruby code.
-# yacc's $$ is the 'result', $0, $1... is
-# an array called 'val', and $-1, $-2... is an array called '_values'.
-#
-# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
-# more information on grammar files.
-#
-# == Parser
-#
-# Then you must prepare the parse entry method. There are two types of
-# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
-#
-# Racc::Parser#do_parse is simple.
-#
-# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
-# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
-# EOF is [false, false].
-# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
-# If you want to change this, see the grammar reference.
-#
-# Racc::Parser#yyparse is little complicated, but useful.
-# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
-#
-# For example, <code>yyparse(obj, :scan)</code> causes
-# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
-#
-# == Debugging
-#
-# When debugging, "-v" or/and the "-g" option is helpful.
-#
-# "-v" creates verbose log file (.output).
-# "-g" creates a "Verbose Parser".
-# Verbose Parser prints the internal status when parsing.
-# But it's _not_ automatic.
-# You must use -g option and set +@yydebug+ to +true+ in order to get output.
-# -g option only creates the verbose parser.
-#
-# === Racc reported syntax error.
-#
-# Isn't there too many "end"?
-# grammar of racc file is changed in v0.10.
-#
-# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
-#
-# === Racc reported "XXXX conflicts".
-#
-# Try "racc -v xxxx.y".
-# It causes producing racc's internal log file, xxxx.output.
-#
-# === Generated parsers does not work correctly
-#
-# Try "racc -g xxxx.y".
-# This command let racc generate "debugging parser".
-# Then set @yydebug=true in your parser.
-# It produces a working log of your parser.
-#
-# == Re-distributing Racc runtime
-#
-# A parser, which is created by Racc, requires the Racc runtime module;
-# racc/parser.rb.
-#
-# Ruby 1.8.x comes with Racc runtime module,
-# you need NOT distribute Racc runtime files.
-#
-# If you want to include the Racc runtime module with your parser.
-# This can be done by using '-E' option:
-#
-# $ racc -E -omyparser.rb myparser.y
-#
-# This command creates myparser.rb which `includes' Racc runtime.
-# Only you must do is to distribute your parser file (myparser.rb).
-#
-# Note: parser.rb is ruby license, but your parser is not.
-# Your own parser is completely yours.
-module Racc
-
- unless defined?(Racc_No_Extensions)
- Racc_No_Extensions = false # :nodoc:
- end
-
- class Parser
-
- Racc_Runtime_Version = ::Racc::VERSION
- Racc_Runtime_Core_Version_R = ::Racc::VERSION
-
- begin
- if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
- require 'jruby'
- require 'racc/cparse-jruby.jar'
- com.headius.racc.Cparse.new.load(JRuby.runtime, false)
- else
- require 'racc/cparse'
- end
-
- unless new.respond_to?(:_racc_do_parse_c, true)
- raise LoadError, 'old cparse.so'
- end
- if Racc_No_Extensions
- raise LoadError, 'selecting ruby version of racc runtime core'
- end
-
- Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
- Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
- Racc_Runtime_Type = 'c' # :nodoc:
- rescue LoadError
- Racc_Main_Parsing_Routine = :_racc_do_parse_rb
- Racc_YY_Parse_Method = :_racc_yyparse_rb
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
- Racc_Runtime_Type = 'ruby'
- end
-
- def Parser.racc_runtime_type # :nodoc:
- Racc_Runtime_Type
- end
-
- def _racc_setup
- @yydebug = false unless self.class::Racc_debug_parser
- @yydebug = false unless defined?(@yydebug)
- if @yydebug
- @racc_debug_out = $stderr unless defined?(@racc_debug_out)
- @racc_debug_out ||= $stderr
- end
- arg = self.class::Racc_arg
- arg[13] = true if arg.size < 14
- arg
- end
-
- def _racc_init_sysvars
- @racc_state = [0]
- @racc_tstack = []
- @racc_vstack = []
-
- @racc_t = nil
- @racc_val = nil
-
- @racc_read_next = true
-
- @racc_user_yyerror = false
- @racc_error_status = 0
- end
-
- # The entry point of the parser. This method is used with #next_token.
- # If Racc wants to get token (and its value), calls next_token.
- #
- # Example:
- # def parse
- # @q = [[1,1],
- # [2,2],
- # [3,3],
- # [false, '$']]
- # do_parse
- # end
- #
- # def next_token
- # @q.shift
- # end
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
- def do_parse
- #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
- end
- RUBY
-
- # The method to fetch next token.
- # If you use #do_parse method, you must implement #next_token.
- #
- # The format of return value is [TOKEN_SYMBOL, VALUE].
- # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
- # for 'IDENT'. ";" (String) for ';'.
- #
- # The final symbol (End of file) must be false.
- def next_token
- raise NotImplementedError, "#{self.class}\#next_token is not defined"
- end
-
- def _racc_do_parse_rb(arg, in_debug)
- action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, * = arg
-
- _racc_init_sysvars
- tok = act = i = nil
-
- catch(:racc_end_parse) {
- while true
- if i = action_pointer[@racc_state[-1]]
- if @racc_read_next
- if @racc_t != 0 # not EOF
- tok, @racc_val = next_token()
- unless tok # EOF
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- racc_read_token(@racc_t, tok, @racc_val) if @yydebug
- @racc_read_next = false
- end
- end
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- else
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- }
- end
-
- # Another entry point for the parser.
- # If you use this method, you must implement RECEIVER#METHOD_ID method.
- #
- # RECEIVER#METHOD_ID is a method to get next token.
- # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
- def yyparse(recv, mid)
- #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
- end
- RUBY
-
- def _racc_yyparse_rb(recv, mid, arg, c_debug)
- action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, * = arg
-
- _racc_init_sysvars
-
- catch(:racc_end_parse) {
- until i = action_pointer[@racc_state[-1]]
- while act = _racc_evalact(action_default[@racc_state[-1]], arg)
- ;
- end
- end
- recv.__send__(mid) do |tok, val|
- unless tok
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- @racc_val = val
- @racc_read_next = false
-
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
-
- while !(i = action_pointer[@racc_state[-1]]) ||
- ! @racc_read_next ||
- @racc_t == 0 # $
- unless i and i += @racc_t and
- i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- end
- }
- end
-
- ###
- ### common
- ###
-
- def _racc_evalact(act, arg)
- action_table, action_check, _, action_pointer,
- _, _, _, _,
- _, _, _, shift_n,
- reduce_n, * = arg
- nerr = 0 # tmp
-
- if act > 0 and act < shift_n
- #
- # shift
- #
- if @racc_error_status > 0
- @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
- end
- @racc_vstack.push @racc_val
- @racc_state.push act
- @racc_read_next = true
- if @yydebug
- @racc_tstack.push @racc_t
- racc_shift @racc_t, @racc_tstack, @racc_vstack
- end
-
- elsif act < 0 and act > -reduce_n
- #
- # reduce
- #
- code = catch(:racc_jump) {
- @racc_state.push _racc_do_reduce(arg, act)
- false
- }
- if code
- case code
- when 1 # yyerror
- @racc_user_yyerror = true # user_yyerror
- return -reduce_n
- when 2 # yyaccept
- return shift_n
- else
- raise '[Racc Bug] unknown jump code'
- end
- end
-
- elsif act == shift_n
- #
- # accept
- #
- racc_accept if @yydebug
- throw :racc_end_parse, @racc_vstack[0]
-
- elsif act == -reduce_n
- #
- # error
- #
- case @racc_error_status
- when 0
- unless arg[21] # user_yyerror
- nerr += 1
- on_error @racc_t, @racc_val, @racc_vstack
- end
- when 3
- if @racc_t == 0 # is $
- # We're at EOF, and another error occurred immediately after
- # attempting auto-recovery
- throw :racc_end_parse, nil
- end
- @racc_read_next = true
- end
- @racc_user_yyerror = false
- @racc_error_status = 3
- while true
- if i = action_pointer[@racc_state[-1]]
- i += 1 # error token
- if i >= 0 and
- (act = action_table[i]) and
- action_check[i] == @racc_state[-1]
- break
- end
- end
- throw :racc_end_parse, nil if @racc_state.size <= 1
- @racc_state.pop
- @racc_vstack.pop
- if @yydebug
- @racc_tstack.pop
- racc_e_pop @racc_state, @racc_tstack, @racc_vstack
- end
- end
- return act
-
- else
- raise "[Racc Bug] unknown action #{act.inspect}"
- end
-
- racc_next_state(@racc_state[-1], @racc_state) if @yydebug
-
- nil
- end
-
- def _racc_do_reduce(arg, act)
- _, _, _, _,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, _, _,
- _, use_result, * = arg
-
- state = @racc_state
- vstack = @racc_vstack
- tstack = @racc_tstack
-
- i = act * -3
- len = reduce_table[i]
- reduce_to = reduce_table[i+1]
- method_id = reduce_table[i+2]
- void_array = []
-
- tmp_t = tstack[-len, len] if @yydebug
- tmp_v = vstack[-len, len]
- tstack[-len, len] = void_array if @yydebug
- vstack[-len, len] = void_array
- state[-len, len] = void_array
-
- # tstack must be updated AFTER method call
- if use_result
- vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
- else
- vstack.push __send__(method_id, tmp_v, vstack)
- end
- tstack.push reduce_to
-
- racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
-
- k1 = reduce_to - nt_base
- if i = goto_pointer[k1]
- i += state[-1]
- if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
- return curstate
- end
- end
- goto_default[k1]
- end
-
- # This method is called when a parse error is found.
- #
- # ERROR_TOKEN_ID is an internal ID of token which caused error.
- # You can get string representation of this ID by calling
- # #token_to_str.
- #
- # ERROR_VALUE is a value of error token.
- #
- # value_stack is a stack of symbol values.
- # DO NOT MODIFY this object.
- #
- # This method raises ParseError by default.
- #
- # If this method returns, parsers enter "error recovering mode".
- def on_error(t, val, vstack)
- raise ParseError, sprintf("parse error on value %s (%s)",
- val.inspect, token_to_str(t) || '?')
- end
-
- # Enter error recovering mode.
- # This method does not call #on_error.
- def yyerror
- throw :racc_jump, 1
- end
-
- # Exit parser.
- # Return value is +Symbol_Value_Stack[0]+.
- def yyaccept
- throw :racc_jump, 2
- end
-
- # Leave error recovering mode.
- def yyerrok
- @racc_error_status = 0
- end
-
- # For debugging output
- def racc_read_token(t, tok, val)
- @racc_debug_out.print 'read '
- @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
- @racc_debug_out.puts val.inspect
- @racc_debug_out.puts
- end
-
- def racc_shift(tok, tstack, vstack)
- @racc_debug_out.puts "shift #{racc_token2str tok}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_reduce(toks, sim, tstack, vstack)
- out = @racc_debug_out
- out.print 'reduce '
- if toks.empty?
- out.print ' <none>'
- else
- toks.each {|t| out.print ' ', racc_token2str(t) }
- end
- out.puts " --> #{racc_token2str(sim)}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_accept
- @racc_debug_out.puts 'accept'
- @racc_debug_out.puts
- end
-
- def racc_e_pop(state, tstack, vstack)
- @racc_debug_out.puts 'error recovering mode: pop token'
- racc_print_states state
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_next_state(curstate, state)
- @racc_debug_out.puts "goto #{curstate}"
- racc_print_states state
- @racc_debug_out.puts
- end
-
- def racc_print_stacks(t, v)
- out = @racc_debug_out
- out.print ' ['
- t.each_index do |i|
- out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
- end
- out.puts ' ]'
- end
-
- def racc_print_states(s)
- out = @racc_debug_out
- out.print ' ['
- s.each {|st| out.print ' ', st }
- out.puts ' ]'
- end
-
- def racc_token2str(tok)
- self.class::Racc_token_to_s_table[tok] or
- raise "[Racc Bug] can't convert token #{tok} to string"
- end
-
- # Convert internal ID of token symbol to the string.
- def token_to_str(t)
- self.class::Racc_token_to_s_table[t]
- end
-
- end
-
-end
-
-end
-###### racc/parser.rb end
+require 'racc/parser.rb'
require 'strscan'
@@ -1300,7 +652,6 @@ Racc_arg = [
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
-Ractor.make_shareable(Racc_arg) if defined?(Ractor)
Racc_token_to_s_table = [
"$end",
@@ -1372,7 +723,6 @@ Racc_token_to_s_table = [
"normal_strings",
"verb_string",
"verb_normal_string" ]
-Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
Racc_debug_parser = false
diff --git a/lib/rdoc/rdoc.gemspec b/lib/rdoc/rdoc.gemspec
index 93a281c8ae..3c96f7deb1 100644
--- a/lib/rdoc/rdoc.gemspec
+++ b/lib/rdoc/rdoc.gemspec
@@ -28,10 +28,6 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat
s.homepage = "https://ruby.github.io/rdoc"
s.licenses = ["Ruby"]
- s.metadata["homepage_uri"] = s.homepage
- s.metadata["source_code_uri"] = "https://github.com/ruby/rdoc"
- s.metadata["changelog_uri"] = "#{s.metadata["source_code_uri"]}/releases"
-
s.bindir = "exe"
s.executables = ["rdoc", "ri"]
s.require_paths = ["lib"]
@@ -230,7 +226,7 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat
s.rdoc_options = ["--main", "README.rdoc"]
s.extra_rdoc_files += s.files.grep(%r[\A[^\/]+\.(?:rdoc|md)\z])
- s.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
+ s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
s.required_rubygems_version = Gem::Requirement.new(">= 2.2")
s.add_dependency 'psych', '>= 4.0.0'
diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
index 2da6d9b575..2d8a9dea8c 100644
--- a/lib/rdoc/rdoc.rb
+++ b/lib/rdoc/rdoc.rb
@@ -119,7 +119,7 @@ class RDoc::RDoc
# +files+.
def gather_files files
- files = [@options.root.to_s] if files.empty?
+ files = ["."] if files.empty?
file_list = normalized_file_list files, true, @options.exclude
@@ -429,7 +429,9 @@ The internal error was:
files.reject do |file, *|
file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or
(file =~ /tags$/i and
- /\A(\f\n[^,]+,\d+$|!_TAG_)/.match?(File.binread(file, 100)))
+ File.open(file, 'rb') { |io|
+ io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/
+ })
end
end
diff --git a/lib/rdoc/require.rb b/lib/rdoc/require.rb
index 05e26b84b0..91f9c24e5d 100644
--- a/lib/rdoc/require.rb
+++ b/lib/rdoc/require.rb
@@ -49,3 +49,4 @@ class RDoc::Require < RDoc::CodeObject
end
end
+
diff --git a/lib/rdoc/ri/driver.rb b/lib/rdoc/ri/driver.rb
index 08c4d08f81..819cff8aa3 100644
--- a/lib/rdoc/ri/driver.rb
+++ b/lib/rdoc/ri/driver.rb
@@ -34,9 +34,9 @@ class RDoc::RI::Driver
class NotFoundError < Error
- def initialize(klass, suggestion_proc = nil) # :nodoc:
+ def initialize(klass, suggestions = nil) # :nodoc:
@klass = klass
- @suggestion_proc = suggestion_proc
+ @suggestions = suggestions
end
##
@@ -48,9 +48,8 @@ class RDoc::RI::Driver
def message # :nodoc:
str = "Nothing known about #{@klass}"
- suggestions = @suggestion_proc&.call
- if suggestions and !suggestions.empty?
- str += "\nDid you mean? #{suggestions.join("\n ")}"
+ if @suggestions and !@suggestions.empty?
+ str += "\nDid you mean? #{@suggestions.join("\n ")}"
end
str
end
@@ -949,8 +948,8 @@ or the PAGER environment variable.
ary = class_names.grep(Regexp.new("\\A#{klass.gsub(/(?=::|\z)/, '[^:]*')}\\z"))
if ary.length != 1 && ary.first != klass
if check_did_you_mean
- suggestion_proc = -> { DidYouMean::SpellChecker.new(dictionary: class_names).correct(klass) }
- raise NotFoundError.new(klass, suggestion_proc)
+ suggestions = DidYouMean::SpellChecker.new(dictionary: class_names).correct(klass)
+ raise NotFoundError.new(klass, suggestions)
else
raise NotFoundError, klass
end
@@ -1238,8 +1237,8 @@ or the PAGER environment variable.
methods.push(*store.instance_methods[klass]) if [:instance, :both].include? types
end
methods = methods.uniq
- suggestion_proc = -> { DidYouMean::SpellChecker.new(dictionary: methods).correct(method_name) }
- raise NotFoundError.new(name, suggestion_proc)
+ suggestions = DidYouMean::SpellChecker.new(dictionary: methods).correct(method_name)
+ raise NotFoundError.new(name, suggestions)
else
raise NotFoundError, name
end
diff --git a/lib/rdoc/ri/store.rb b/lib/rdoc/ri/store.rb
index 96742e7ae3..9f4b03734a 100644
--- a/lib/rdoc/ri/store.rb
+++ b/lib/rdoc/ri/store.rb
@@ -4,3 +4,4 @@ module RDoc::RI
Store = RDoc::Store # :nodoc:
end
+
diff --git a/lib/rdoc/single_class.rb b/lib/rdoc/single_class.rb
index dd16529648..860f06a6e5 100644
--- a/lib/rdoc/single_class.rb
+++ b/lib/rdoc/single_class.rb
@@ -28,3 +28,4 @@ class RDoc::SingleClass < RDoc::ClassModule
end
end
end
+
diff --git a/lib/rdoc/stats/quiet.rb b/lib/rdoc/stats/quiet.rb
index 9c98ea5f86..bc4161b2d4 100644
--- a/lib/rdoc/stats/quiet.rb
+++ b/lib/rdoc/stats/quiet.rb
@@ -57,3 +57,4 @@ class RDoc::Stats::Quiet
def done_adding(*) end
end
+
diff --git a/lib/rdoc/stats/verbose.rb b/lib/rdoc/stats/verbose.rb
index 7090d561f8..6ace8937a2 100644
--- a/lib/rdoc/stats/verbose.rb
+++ b/lib/rdoc/stats/verbose.rb
@@ -42,3 +42,5 @@ class RDoc::Stats::Verbose < RDoc::Stats::Normal
end
end
+
+
diff --git a/lib/rdoc/store.rb b/lib/rdoc/store.rb
index cd27d47dd1..c793e49ed8 100644
--- a/lib/rdoc/store.rb
+++ b/lib/rdoc/store.rb
@@ -197,9 +197,6 @@ class RDoc::Store
top_level
end
- ##
- # Sets the parser of +absolute_name+, unless it from a source code file.
-
def update_parser_of_file(absolute_name, parser)
if top_level = @files_hash[absolute_name] then
@text_files_hash[absolute_name] = top_level if top_level.text?
diff --git a/lib/rdoc/task.rb b/lib/rdoc/task.rb
index eb584c9d2a..8ea2d0588c 100644
--- a/lib/rdoc/task.rb
+++ b/lib/rdoc/task.rb
@@ -50,9 +50,6 @@ require 'rake/tasklib'
# [rerdoc]
# Rebuild the rdoc files from scratch, even if they are not out of date.
#
-# [rdoc:coverage]
-# Print RDoc coverage report for all rdoc files.
-#
# Simple Example:
#
# require 'rdoc/task'
@@ -93,8 +90,8 @@ require 'rake/tasklib'
# RDoc::Task.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean",
# :rerdoc => "rdoc:force")
#
-# This will create the tasks <tt>:rdoc</tt>, <tt>:rdoc:clean</tt>,
-# <tt>:rdoc:force</tt>, and <tt>:rdoc:coverage</tt>.
+# This will create the tasks <tt>:rdoc</tt>, <tt>:rdoc:clean</tt> and
+# <tt>:rdoc:force</tt>.
class RDoc::Task < Rake::TaskLib
@@ -251,18 +248,6 @@ class RDoc::Task < Rake::TaskLib
RDoc::RDoc.new.document args
end
- namespace rdoc_task_name do
- desc coverage_task_description
- task coverage_task_name do
- @before_running_rdoc.call if @before_running_rdoc
- opts = option_list << "-C"
- args = opts + @rdoc_files
-
- $stderr.puts "rdoc #{args.join ' '}" if Rake.application.options.trace
- RDoc::RDoc.new.document args
- end
- end
-
self
end
@@ -303,13 +288,6 @@ class RDoc::Task < Rake::TaskLib
"Rebuild RDoc HTML files"
end
- ##
- # Task description for the coverage task or its renamed description
-
- def coverage_task_description
- "Print RDoc coverage report"
- end
-
private
def rdoc_target
@@ -337,10 +315,6 @@ class RDoc::Task < Rake::TaskLib
end
end
- def coverage_task_name
- "coverage"
- end
-
end
# :stopdoc:
diff --git a/lib/rdoc/text.rb b/lib/rdoc/text.rb
index 9804f81abe..0bc4aba428 100644
--- a/lib/rdoc/text.rb
+++ b/lib/rdoc/text.rb
@@ -10,10 +10,6 @@ require 'strscan'
module RDoc::Text
- ##
- # The language for this text. This affects stripping comments
- # markers.
-
attr_accessor :language
##
@@ -313,10 +309,4 @@ module RDoc::Text
res.join.strip
end
- ##
- # Character class to be separated by a space when concatenating
- # lines.
-
- SPACE_SEPARATED_LETTER_CLASS = /[\p{Nd}\p{Lc}\p{Pc}]|[!-~&&\W]/
-
end
diff --git a/lib/rdoc/token_stream.rb b/lib/rdoc/token_stream.rb
index 19ca7ed248..f428e2400c 100644
--- a/lib/rdoc/token_stream.rb
+++ b/lib/rdoc/token_stream.rb
@@ -112,7 +112,8 @@ module RDoc::TokenStream
# Returns a string representation of the token stream
def tokens_to_s
- (token_stream or return '').compact.map { |token| token[:text] }.join ''
+ token_stream.compact.map { |token| token[:text] }.join ''
end
end
+
diff --git a/lib/rdoc/top_level.rb b/lib/rdoc/top_level.rb
index 3864f66431..b8b6110bb2 100644
--- a/lib/rdoc/top_level.rb
+++ b/lib/rdoc/top_level.rb
@@ -52,9 +52,6 @@ class RDoc::TopLevel < RDoc::Context
@classes_or_modules = []
end
- ##
- # Sets the parser for this toplevel context, also the store.
-
def parser=(val)
@parser = val
@store.update_parser_of_file(absolute_name, val) if @store
@@ -289,3 +286,4 @@ class RDoc::TopLevel < RDoc::Context
end
end
+
diff --git a/lib/rdoc/version.rb b/lib/rdoc/version.rb
index 87842d9847..31c1aa0276 100644
--- a/lib/rdoc/version.rb
+++ b/lib/rdoc/version.rb
@@ -5,6 +5,6 @@ module RDoc
##
# RDoc version you are using
- VERSION = '6.6.3.1'
+ VERSION = '6.5.1.1'
end
diff --git a/lib/readline.gemspec b/lib/readline.gemspec
index 9221c29263..3a18f9edb6 100644
--- a/lib/readline.gemspec
+++ b/lib/readline.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = 'readline'
- spec.version = '0.0.4'
+ spec.version = '0.0.3'
spec.authors = ['aycabta']
spec.email = ['aycabta@gmail.com']
diff --git a/lib/readline.rb b/lib/readline.rb
index d1c9d3a955..29cdf3a14f 100644
--- a/lib/readline.rb
+++ b/lib/readline.rb
@@ -1,5 +1,5 @@
begin
- require "readline.#{RbConfig::CONFIG["DLEXT"]}"
+ require 'readline.so'
rescue LoadError
require 'reline' unless defined? Reline
Object.send(:remove_const, :Readline) if Object.const_defined?(:Readline)
diff --git a/lib/reline.rb b/lib/reline.rb
index fb00b96531..7800a281ce 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -1,4 +1,5 @@
require 'io/console'
+require 'timeout'
require 'forwardable'
require 'reline/version'
require 'reline/config'
@@ -7,17 +8,15 @@ require 'reline/key_stroke'
require 'reline/line_editor'
require 'reline/history'
require 'reline/terminfo'
-require 'reline/face'
require 'rbconfig'
module Reline
- # NOTE: For making compatible with the rb-readline gem
FILENAME_COMPLETION_PROC = nil
USERNAME_COMPLETION_PROC = nil
class ConfigEncodingConversionError < StandardError; end
- Key = Struct.new(:char, :combined_char, :with_meta) do
+ Key = Struct.new('Key', :char, :combined_char, :with_meta) do
def match?(other)
case other
when Reline::Key
@@ -37,8 +36,10 @@ module Reline
DialogRenderInfo = Struct.new(
:pos,
:contents,
- :face,
- :bg_color, # For the time being, this line should stay here for the compatibility with IRB.
+ :bg_color,
+ :pointer_bg_color,
+ :fg_color,
+ :pointer_fg_color,
:width,
:height,
:scrollbar,
@@ -75,54 +76,50 @@ module Reline
def initialize
self.output = STDOUT
- @mutex = Mutex.new
@dialog_proc_list = {}
yield self
@completion_quote_character = nil
- end
-
- def io_gate
- Reline::IOGate
+ @bracketed_paste_finished = false
end
def encoding
- io_gate.encoding
+ Reline::IOGate.encoding
end
def completion_append_character=(val)
if val.nil?
@completion_append_character = nil
elsif val.size == 1
- @completion_append_character = val.encode(encoding)
+ @completion_append_character = val.encode(Reline::IOGate.encoding)
elsif val.size > 1
- @completion_append_character = val[0].encode(encoding)
+ @completion_append_character = val[0].encode(Reline::IOGate.encoding)
else
@completion_append_character = nil
end
end
def basic_word_break_characters=(v)
- @basic_word_break_characters = v.encode(encoding)
+ @basic_word_break_characters = v.encode(Reline::IOGate.encoding)
end
def completer_word_break_characters=(v)
- @completer_word_break_characters = v.encode(encoding)
+ @completer_word_break_characters = v.encode(Reline::IOGate.encoding)
end
def basic_quote_characters=(v)
- @basic_quote_characters = v.encode(encoding)
+ @basic_quote_characters = v.encode(Reline::IOGate.encoding)
end
def completer_quote_characters=(v)
- @completer_quote_characters = v.encode(encoding)
+ @completer_quote_characters = v.encode(Reline::IOGate.encoding)
end
def filename_quote_characters=(v)
- @filename_quote_characters = v.encode(encoding)
+ @filename_quote_characters = v.encode(Reline::IOGate.encoding)
end
def special_prefixes=(v)
- @special_prefixes = v.encode(encoding)
+ @special_prefixes = v.encode(Reline::IOGate.encoding)
end
def completion_case_fold=(v)
@@ -168,13 +165,9 @@ module Reline
DialogProc = Struct.new(:dialog_proc, :context)
def add_dialog_proc(name_sym, p, context = nil)
+ raise ArgumentError unless p.respond_to?(:call) or p.nil?
raise ArgumentError unless name_sym.instance_of?(Symbol)
- if p.nil?
- @dialog_proc_list.delete(name_sym)
- else
- raise ArgumentError unless p.respond_to?(:call)
- @dialog_proc_list[name_sym] = DialogProc.new(p, context)
- end
+ @dialog_proc_list[name_sym] = DialogProc.new(p, context)
end
def dialog_proc(name_sym)
@@ -183,16 +176,20 @@ module Reline
def input=(val)
raise TypeError unless val.respond_to?(:getc) or val.nil?
- if val.respond_to?(:getc) && io_gate.respond_to?(:input=)
- io_gate.input = val
+ if val.respond_to?(:getc)
+ if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
+ Reline::ANSI.input = val
+ elsif Reline::IOGate == Reline::GeneralIO
+ Reline::GeneralIO.input = val
+ end
end
end
def output=(val)
raise TypeError unless val.respond_to?(:write) or val.nil?
@output = val
- if io_gate.respond_to?(:output=)
- io_gate.output = val
+ if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
+ Reline::ANSI.output = val
end
end
@@ -215,30 +212,37 @@ module Reline
end
def get_screen_size
- io_gate.get_screen_size
+ Reline::IOGate.get_screen_size
end
Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE = ->() {
# autocomplete
- return unless config.autocompletion
-
- journey_data = completion_journey_data
- return unless journey_data
-
- target = journey_data.list.first
- completed = journey_data.list[journey_data.pointer]
- result = journey_data.list.drop(1)
- pointer = journey_data.pointer - 1
- return if completed.empty? || (result == [completed] && pointer < 0)
-
+ return nil unless config.autocompletion
+ if just_cursor_moving and completion_journey_data.nil?
+ # Auto complete starts only when edited
+ return nil
+ end
+ pre, target, post = retrieve_completion_block(true)
+ if target.nil? or target.empty? or (completion_journey_data&.pointer == -1 and target.size <= 3)
+ return nil
+ end
+ if completion_journey_data and completion_journey_data.list
+ result = completion_journey_data.list.dup
+ result.shift
+ pointer = completion_journey_data.pointer - 1
+ else
+ result = call_completion_proc_with_checking_args(pre, target, post)
+ pointer = nil
+ end
+ if result and result.size == 1 and result[0] == target and pointer != 0
+ result = nil
+ end
target_width = Reline::Unicode.calculate_width(target)
- completed_width = Reline::Unicode.calculate_width(completed)
- if cursor_pos.x <= completed_width - target_width
- # When target is rendered on the line above cursor position
- x = screen_width - completed_width
+ x = cursor_pos.x - target_width
+ if x < 0
+ x = screen_width + x
y = -1
else
- x = [cursor_pos.x - completed_width, 0].max
y = 0
end
cursor_pos_to_render = Reline::CursorPos.new(x, y)
@@ -251,60 +255,47 @@ module Reline
pos: cursor_pos_to_render,
contents: result,
scrollbar: true,
- height: [15, preferred_dialog_height].min,
- face: :completion_dialog
+ height: 15,
+ bg_color: 46,
+ pointer_bg_color: 45,
+ fg_color: 37,
+ pointer_fg_color: 37
)
}
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
- @mutex.synchronize do
- unless confirm_multiline_termination
- raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
- end
-
- Reline.update_iogate
- io_gate.with_raw_input do
- inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
- end
-
- whole_buffer = line_editor.whole_buffer.dup
- whole_buffer.taint if RUBY_VERSION < '2.7'
- if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
- Reline::HISTORY << whole_buffer
- end
+ unless confirm_multiline_termination
+ raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
+ end
+ inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
- if line_editor.eof?
- line_editor.reset_line
- # Return nil if the input is aborted by C-d.
- nil
- else
- whole_buffer
- end
+ whole_buffer = line_editor.whole_buffer.dup
+ whole_buffer.taint if RUBY_VERSION < '2.7'
+ if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
+ Reline::HISTORY << whole_buffer
end
+
+ line_editor.reset_line if line_editor.whole_buffer.nil?
+ whole_buffer
end
def readline(prompt = '', add_hist = false)
- @mutex.synchronize do
- Reline.update_iogate
- io_gate.with_raw_input do
- inner_readline(prompt, add_hist, false)
- end
+ inner_readline(prompt, add_hist, false)
- line = line_editor.line.dup
- line.taint if RUBY_VERSION < '2.7'
- if add_hist and line and line.chomp("\n").size > 0
- Reline::HISTORY << line.chomp("\n")
- end
-
- line_editor.reset_line if line_editor.line.nil?
- line
+ line = line_editor.line.dup
+ line.taint if RUBY_VERSION < '2.7'
+ if add_hist and line and line.chomp("\n").size > 0
+ Reline::HISTORY << line.chomp("\n")
end
+
+ line_editor.reset_line if line_editor.line.nil?
+ line
end
private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
if ENV['RELINE_STDERR_TTY']
- if io_gate.win?
+ if Reline::IOGate.win?
$stderr = File.open(ENV['RELINE_STDERR_TTY'], 'a')
else
$stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
@@ -312,14 +303,10 @@ module Reline
$stderr.sync = true
$stderr.puts "Reline is used by #{Process.pid}"
end
- unless config.test_mode or config.loaded?
- config.read
- io_gate.set_default_key_bindings(config)
- end
- otio = io_gate.prep
+ otio = Reline::IOGate.prep
may_req_ambiguous_char_width
- line_editor.reset(prompt, encoding: encoding)
+ line_editor.reset(prompt, encoding: Reline::IOGate.encoding)
if multiline
line_editor.multiline_on
if block_given?
@@ -335,47 +322,58 @@ module Reline
line_editor.prompt_proc = prompt_proc
line_editor.auto_indent_proc = auto_indent_proc
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
- pre_input_hook&.call
- unless Reline::IOGate == Reline::GeneralIO
- @dialog_proc_list.each_pair do |name_sym, d|
- line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
- end
+ line_editor.pre_input_hook = pre_input_hook
+ @dialog_proc_list.each_pair do |name_sym, d|
+ line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
+ end
+
+ unless config.test_mode
+ config.read
+ config.reset_default_key_bindings
+ Reline::IOGate.set_default_key_bindings(config)
end
- line_editor.print_nomultiline_prompt(prompt)
- line_editor.update_dialogs
line_editor.rerender
begin
line_editor.set_signal_handlers
+ prev_pasting_state = false
loop do
+ prev_pasting_state = Reline::IOGate.in_pasting?
read_io(config.keyseq_timeout) { |inputs|
- line_editor.set_pasting_state(io_gate.in_pasting?)
- inputs.each do |key|
- if key.char == :bracketed_paste_start
- text = io_gate.read_bracketed_paste
- line_editor.insert_pasted_text(text)
- line_editor.scroll_into_view
- else
- line_editor.update(key)
- end
+ line_editor.set_pasting_state(Reline::IOGate.in_pasting?)
+ inputs.each { |c|
+ line_editor.input_key(c)
+ line_editor.rerender
+ }
+ if @bracketed_paste_finished
+ line_editor.rerender_all
+ @bracketed_paste_finished = false
end
}
- if line_editor.finished?
- line_editor.render_finished
- break
- else
- line_editor.set_pasting_state(io_gate.in_pasting?)
- line_editor.rerender
+ if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
+ line_editor.set_pasting_state(false)
+ prev_pasting_state = false
+ line_editor.rerender_all
end
+ break if line_editor.finished?
end
- io_gate.move_cursor_column(0)
+ Reline::IOGate.move_cursor_column(0)
rescue Errno::EIO
# Maybe the I/O has been closed.
- ensure
+ rescue StandardError => e
+ line_editor.finalize
+ Reline::IOGate.deprep(otio)
+ raise e
+ rescue Exception
+ # Including Interrupt
line_editor.finalize
- io_gate.deprep(otio)
+ Reline::IOGate.deprep(otio)
+ raise
end
+
+ line_editor.finalize
+ Reline::IOGate.deprep(otio)
end
# GNU Readline waits for "keyseq-timeout" milliseconds to see if the ESC
@@ -390,9 +388,10 @@ module Reline
private def read_io(keyseq_timeout, &block)
buffer = []
loop do
- c = io_gate.getc(Float::INFINITY)
+ c = Reline::IOGate.getc
if c == -1
result = :unmatched
+ @bracketed_paste_finished = true
else
buffer << c
result = key_stroke.match_status(buffer)
@@ -426,8 +425,15 @@ module Reline
end
private def read_2nd_character_of_key_sequence(keyseq_timeout, buffer, c, block)
- succ_c = io_gate.getc(keyseq_timeout.fdiv(1000))
- if succ_c
+ begin
+ succ_c = nil
+ Timeout.timeout(keyseq_timeout / 1000.0) {
+ succ_c = Reline::IOGate.getc
+ }
+ rescue Timeout::Error # cancel matching only when first byte
+ block.([Reline::Key.new(c, c, false)])
+ return :break
+ else
case key_stroke.match_status(buffer.dup.push(succ_c))
when :unmatched
if c == "\e".ord
@@ -437,7 +443,7 @@ module Reline
end
return :break
when :matching
- io_gate.ungetc(succ_c)
+ Reline::IOGate.ungetc(succ_c)
return :next
when :matched
buffer << succ_c
@@ -447,23 +453,27 @@ module Reline
block.(expanded)
return :break
end
- else
- block.([Reline::Key.new(c, c, false)])
- return :break
end
end
private def read_escaped_key(keyseq_timeout, c, block)
- escaped_c = io_gate.getc(keyseq_timeout.fdiv(1000))
-
- if escaped_c.nil?
+ begin
+ escaped_c = nil
+ Timeout.timeout(keyseq_timeout / 1000.0) {
+ escaped_c = Reline::IOGate.getc
+ }
+ rescue Timeout::Error # independent ESC
block.([Reline::Key.new(c, c, false)])
- elsif escaped_c >= 128 # maybe, first byte of multi byte
- block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
- elsif escaped_c == "\e".ord # escape twice
- block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
else
- block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
+ if escaped_c.nil?
+ block.([Reline::Key.new(c, c, false)])
+ elsif escaped_c >= 128 # maybe, first byte of multi byte
+ block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
+ elsif escaped_c == "\e".ord # escape twice
+ block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
+ else
+ block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
+ end
end
end
@@ -473,19 +483,19 @@ module Reline
end
private def may_req_ambiguous_char_width
- @ambiguous_width = 2 if io_gate == Reline::GeneralIO or !STDOUT.tty?
+ @ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or !STDOUT.tty?
return if defined? @ambiguous_width
- io_gate.move_cursor_column(0)
+ Reline::IOGate.move_cursor_column(0)
begin
output.write "\u{25bd}"
rescue Encoding::UndefinedConversionError
# LANG=C
@ambiguous_width = 1
else
- @ambiguous_width = io_gate.cursor_pos.x
+ @ambiguous_width = Reline::IOGate.cursor_pos.x
end
- io_gate.move_cursor_column(0)
- io_gate.erase_after_cursor
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
end
end
@@ -548,7 +558,7 @@ module Reline
@core ||= Core.new { |core|
core.config = Reline::Config.new
core.key_stroke = Reline::KeyStroke.new(core.config)
- core.line_editor = Reline::LineEditor.new(core.config, core.encoding)
+ core.line_editor = Reline::LineEditor.new(core.config, Reline::IOGate.encoding)
core.basic_word_break_characters = " \t\n`><=;|&{("
core.completer_word_break_characters = " \t\n`><=;|&{("
@@ -561,24 +571,12 @@ module Reline
end
def self.ungetc(c)
- core.io_gate.ungetc(c)
+ Reline::IOGate.ungetc(c)
end
def self.line_editor
core.line_editor
end
-
- def self.update_iogate
- return if core.config.test_mode
-
- # Need to change IOGate when `$stdout.tty?` change from false to true by `$stdout.reopen`
- # Example: rails/spring boot the application in non-tty, then run console in tty.
- if ENV['TERM'] != 'dumb' && core.io_gate == Reline::GeneralIO && $stdout.tty?
- require 'reline/ansi'
- remove_const(:IOGate)
- const_set(:IOGate, Reline::ANSI)
- end
- end
end
require 'reline/general_io'
@@ -599,6 +597,4 @@ else
io
end
-Reline::Face.load_initial_configs
-
Reline::HISTORY = Reline::History.new(Reline.core.config)
diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb
index 45a475a787..c40085e50d 100644
--- a/lib/reline/ansi.rb
+++ b/lib/reline/ansi.rb
@@ -1,35 +1,20 @@
require 'io/console'
require 'io/wait'
+require 'timeout'
require_relative 'terminfo'
class Reline::ANSI
- RESET_COLOR = "\e[0m"
-
CAPNAME_KEY_BINDINGS = {
'khome' => :ed_move_to_beg,
'kend' => :ed_move_to_end,
- 'kdch1' => :key_delete,
- 'kpp' => :ed_search_prev_history,
- 'knp' => :ed_search_next_history,
'kcuu1' => :ed_prev_history,
'kcud1' => :ed_next_history,
'kcuf1' => :ed_next_char,
'kcub1' => :ed_prev_char,
- }
-
- ANSI_CURSOR_KEY_BINDINGS = {
- # Up
- 'A' => [:ed_prev_history, {}],
- # Down
- 'B' => [:ed_next_history, {}],
- # Right
- 'C' => [:ed_next_char, { ctrl: :em_next_word, meta: :em_next_word }],
- # Left
- 'D' => [:ed_prev_char, { ctrl: :ed_prev_word, meta: :ed_prev_word }],
- # End
- 'F' => [:ed_move_to_end, {}],
- # Home
- 'H' => [:ed_move_to_beg, {}],
+ 'cuu' => :ed_prev_history,
+ 'cud' => :ed_next_history,
+ 'cuf' => :ed_next_char,
+ 'cub' => :ed_prev_char,
}
if Reline::Terminfo.enabled?
@@ -44,15 +29,24 @@ class Reline::ANSI
false
end
- def self.set_default_key_bindings(config, allow_terminfo: true)
- set_bracketed_paste_key_bindings(config)
- set_default_key_bindings_ansi_cursor(config)
- if allow_terminfo && Reline::Terminfo.enabled?
+ def self.set_default_key_bindings(config)
+ if Reline::Terminfo.enabled?
set_default_key_bindings_terminfo(config)
else
set_default_key_bindings_comprehensive_list(config)
end
{
+ # extended entries of terminfo
+ [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→, extended entry
+ [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+â†, extended entry
+ [27, 91, 49, 59, 51, 67] => :em_next_word, # Meta+→, extended entry
+ [27, 91, 49, 59, 51, 68] => :ed_prev_word, # Meta+â†, extended entry
+ }.each_pair do |key, func|
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
+ config.add_default_key_binding_by_keymap(:vi_insert, key, func)
+ config.add_default_key_binding_by_keymap(:vi_command, key, func)
+ end
+ {
[27, 91, 90] => :completion_journey_up, # S-Tab
}.each_pair do |key, func|
config.add_default_key_binding_by_keymap(:emacs, key, func)
@@ -67,39 +61,18 @@ class Reline::ANSI
end
end
- def self.set_bracketed_paste_key_bindings(config)
- [:emacs, :vi_insert, :vi_command].each do |keymap|
- config.add_default_key_binding_by_keymap(keymap, START_BRACKETED_PASTE.bytes, :bracketed_paste_start)
- end
- end
-
- def self.set_default_key_bindings_ansi_cursor(config)
- ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)|
- bindings = [["\e[#{char}", default_func]] # CSI + char
- if modifiers[:ctrl]
- # CSI + ctrl_key_modifier + char
- bindings << ["\e[1;5#{char}", modifiers[:ctrl]]
- end
- if modifiers[:meta]
- # CSI + meta_key_modifier + char
- bindings << ["\e[1;3#{char}", modifiers[:meta]]
- # Meta(ESC) + CSI + char
- bindings << ["\e\e[#{char}", modifiers[:meta]]
- end
- bindings.each do |sequence, func|
- key = sequence.bytes
- config.add_default_key_binding_by_keymap(:emacs, key, func)
- config.add_default_key_binding_by_keymap(:vi_insert, key, func)
- config.add_default_key_binding_by_keymap(:vi_command, key, func)
- end
- end
- end
-
def self.set_default_key_bindings_terminfo(config)
key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding|
begin
key_code = Reline::Terminfo.tigetstr(capname)
- [ key_code.bytes, key_binding ]
+ case capname
+ # Escape sequences that omit the move distance and are set to defaults
+ # value 1 may be sometimes sent by pressing the arrow-key.
+ when 'cuu', 'cud', 'cuf', 'cub'
+ [ key_code.sub(/%p1%d/, '').bytes, key_binding ]
+ else
+ [ key_code.bytes, key_binding ]
+ end
rescue Reline::Terminfo::TerminfoError
# capname is undefined
end
@@ -118,8 +91,14 @@ class Reline::ANSI
[27, 91, 49, 126] => :ed_move_to_beg, # Home
[27, 91, 52, 126] => :ed_move_to_end, # End
[27, 91, 51, 126] => :key_delete, # Del
+ [27, 91, 65] => :ed_prev_history, # ↑
+ [27, 91, 66] => :ed_next_history, # ↓
+ [27, 91, 67] => :ed_next_char, # →
+ [27, 91, 68] => :ed_prev_char, # â†
# KDE
+ [27, 91, 72] => :ed_move_to_beg, # Home
+ [27, 91, 70] => :ed_move_to_end, # End
# Del is 0x08
[27, 71, 65] => :ed_prev_history, # ↑
[27, 71, 66] => :ed_next_history, # ↓
@@ -136,6 +115,12 @@ class Reline::ANSI
# Del is 0x08
# Arrow keys are the same of KDE
+ # iTerm2
+ [27, 27, 91, 67] => :em_next_word, # Option+→, extended entry
+ [27, 27, 91, 68] => :ed_prev_word, # Option+â†, extended entry
+ [195, 166] => :em_next_word, # Option+f
+ [195, 162] => :ed_prev_word, # Option+b
+
[27, 79, 65] => :ed_prev_history, # ↑
[27, 79, 66] => :ed_next_history, # ↓
[27, 79, 67] => :ed_next_char, # →
@@ -157,26 +142,14 @@ class Reline::ANSI
@@output = val
end
- def self.with_raw_input
- if @@input.tty?
- @@input.raw(intr: true) { yield }
- else
- yield
- end
- end
-
@@buf = []
- def self.inner_getc(timeout_second)
+ def self.inner_getc
unless @@buf.empty?
return @@buf.shift
end
- until @@input.wait_readable(0.01)
- timeout_second -= 0.01
- return nil if timeout_second <= 0
-
- Reline.core.line_editor.handle_signal
+ until c = @@input.raw(intr: true) { @@input.wait_readable(0.1) && @@input.getbyte }
+ Reline.core.line_editor.resize
end
- c = @@input.getbyte
(c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
rescue Errno::EIO
# Maybe the I/O has been closed.
@@ -185,26 +158,48 @@ class Reline::ANSI
nil
end
- START_BRACKETED_PASTE = String.new("\e[200~", encoding: Encoding::ASCII_8BIT)
- END_BRACKETED_PASTE = String.new("\e[201~", encoding: Encoding::ASCII_8BIT)
- def self.read_bracketed_paste
+ @@in_bracketed_paste_mode = false
+ START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
+ END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
+ def self.getc_with_bracketed_paste
buffer = String.new(encoding: Encoding::ASCII_8BIT)
- until buffer.end_with?(END_BRACKETED_PASTE)
- c = inner_getc(Float::INFINITY)
- break unless c
- buffer << c
+ buffer << inner_getc
+ while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
+ if START_BRACKETED_PASTE == buffer
+ @@in_bracketed_paste_mode = true
+ return inner_getc
+ elsif END_BRACKETED_PASTE == buffer
+ @@in_bracketed_paste_mode = false
+ ungetc(-1)
+ return inner_getc
+ end
+ begin
+ succ_c = nil
+ Timeout.timeout(Reline.core.config.keyseq_timeout * 100) {
+ succ_c = inner_getc
+ }
+ rescue Timeout::Error
+ break
+ else
+ buffer << succ_c
+ end
end
- string = buffer.delete_suffix(END_BRACKETED_PASTE).force_encoding(encoding)
- string.valid_encoding? ? string : ''
+ buffer.bytes.reverse_each do |ch|
+ ungetc ch
+ end
+ inner_getc
end
- # if the usage expects to wait indefinitely, use Float::INFINITY for timeout_second
- def self.getc(timeout_second)
- inner_getc(timeout_second)
+ def self.getc
+ if Reline.core.config.enable_bracketed_paste
+ getc_with_bracketed_paste
+ else
+ inner_getc
+ end
end
def self.in_pasting?
- not empty_buffer?
+ @@in_bracketed_paste_mode or (not Reline::IOGate.empty_buffer?)
end
def self.empty_buffer?
@@ -271,7 +266,7 @@ class Reline::ANSI
buf = @@output.pread(@@output.pos, 0)
row = buf.count("\n")
column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
- rescue Errno::ESPIPE, IOError
+ rescue Errno::ESPIPE
# Just returns column 1 for ambiguous width because this I/O is not
# tty and can't seek.
row = 0
@@ -302,7 +297,7 @@ class Reline::ANSI
end
def self.hide_cursor
- if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
+ if Reline::Terminfo.enabled?
begin
@@output.write Reline::Terminfo.tigetstr('civis')
rescue Reline::Terminfo::TerminfoError
@@ -314,7 +309,7 @@ class Reline::ANSI
end
def self.show_cursor
- if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
+ if Reline::Terminfo.enabled?
begin
@@output.write Reline::Terminfo.tigetstr('cnorm')
rescue Reline::Terminfo::TerminfoError
@@ -329,12 +324,9 @@ class Reline::ANSI
@@output.write "\e[K"
end
- # This only works when the cursor is at the bottom of the scroll range
- # For more details, see https://github.com/ruby/reline/pull/577#issuecomment-1646679623
def self.scroll_down(x)
return if x.zero?
- # We use `\n` instead of CSI + S because CSI + S would cause https://github.com/ruby/reline/issues/576
- @@output.write "\n" * x
+ @@output.write "\e[#{x}S"
end
def self.clear_screen
@@ -348,15 +340,11 @@ class Reline::ANSI
end
def self.prep
- # Enable bracketed paste
- @@output.write "\e[?2004h" if Reline.core.config.enable_bracketed_paste
retrieve_keybuffer
nil
end
def self.deprep(otio)
- # Disable bracketed paste
- @@output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste
Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
end
end
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
index d44c2675ab..5ba269258f 100644
--- a/lib/reline/config.rb
+++ b/lib/reline/config.rb
@@ -8,12 +8,31 @@ class Reline::Config
end
VARIABLE_NAMES = %w{
+ bind-tty-special-chars
+ blink-matching-paren
+ byte-oriented
completion-ignore-case
convert-meta
disable-completion
+ enable-keypad
+ expand-tilde
+ history-preserve-point
history-size
+ horizontal-scroll-mode
+ input-meta
keyseq-timeout
+ mark-directories
+ mark-modified-lines
+ mark-symlinked-directories
+ match-hidden-files
+ meta-flag
+ output-meta
+ page-completions
+ prefer-visible-bell
+ print-completions-horizontally
show-all-if-ambiguous
+ show-all-if-unmodified
+ visible-stats
show-mode-in-prompt
vi-cmd-mode-string
vi-ins-mode-string
@@ -34,6 +53,8 @@ class Reline::Config
@additional_key_bindings[:vi_insert] = {}
@additional_key_bindings[:vi_command] = {}
@oneshot_key_bindings = {}
+ @skip_section = nil
+ @if_stack = nil
@editing_mode_label = :emacs
@keymap_label = :emacs
@keymap_prefix = []
@@ -50,15 +71,17 @@ class Reline::Config
@test_mode = false
@autocompletion = false
@convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
- @loaded = false
- @enable_bracketed_paste = true
end
def reset
if editing_mode_is?(:vi_command)
@editing_mode_label = :vi_insert
end
+ @additional_key_bindings.keys.each do |key|
+ @additional_key_bindings[key].clear
+ end
@oneshot_key_bindings.clear
+ reset_default_key_bindings
end
def editing_mode
@@ -70,17 +93,13 @@ class Reline::Config
end
def editing_mode_is?(*val)
- val.any?(@editing_mode_label)
+ (val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
end
def keymap
@key_actors[@keymap_label]
end
- def loaded?
- @loaded
- end
-
def inputrc_path
case ENV['INPUTRC']
when nil, ''
@@ -112,7 +131,6 @@ class Reline::Config
end
def read(file = nil)
- @loaded = true
file ||= default_inputrc_path
begin
if file.respond_to?(:readlines)
@@ -155,6 +173,12 @@ class Reline::Config
@key_actors[@keymap_label].default_key_bindings[keystroke] = target
end
+ def reset_default_key_bindings
+ @key_actors.values.each do |ka|
+ ka.reset_default_key_bindings
+ end
+ end
+
def read_lines(lines, file = nil)
if not lines.empty? and lines.first.encoding != Reline.encoding_system_needs
begin
@@ -166,7 +190,9 @@ class Reline::Config
end
end
end
- if_stack = []
+ conditions = [@skip_section, @if_stack]
+ @skip_section = nil
+ @if_stack = []
lines.each_with_index do |line, no|
next if line.match(/\A\s*#/)
@@ -175,11 +201,11 @@ class Reline::Config
line = line.chomp.lstrip
if line.start_with?('$')
- handle_directive(line[1..-1], file, no, if_stack)
+ handle_directive(line[1..-1], file, no)
next
end
- next if if_stack.any? { |_no, skip| skip }
+ next if @skip_section
case line
when /^set +([^ ]+) +([^ ]+)/i
@@ -188,49 +214,45 @@ class Reline::Config
next
when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
key, func_name = $1, $2
- func_name = func_name.split.first
keystroke, func = bind_key(key, func_name)
next unless keystroke
@additional_key_bindings[@keymap_label][@keymap_prefix + keystroke] = func
end
end
- unless if_stack.empty?
- raise InvalidInputrc, "#{file}:#{if_stack.last[0]}: unclosed if"
+ unless @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{@if_stack.last[1]}: unclosed if"
end
+ ensure
+ @skip_section, @if_stack = conditions
end
- def handle_directive(directive, file, no, if_stack)
+ def handle_directive(directive, file, no)
directive, args = directive.split(' ')
case directive
when 'if'
condition = false
case args
- when /^mode=(vi|emacs)$/i
- mode = $1.downcase
- # NOTE: mode=vi means vi-insert mode
- mode = 'vi_insert' if mode == 'vi'
- if @editing_mode_label == mode.to_sym
- condition = true
- end
+ when 'mode'
when 'term'
when 'version'
else # application name
condition = true if args == 'Ruby'
condition = true if args == 'Reline'
end
- if_stack << [no, !condition]
+ @if_stack << [file, no, @skip_section]
+ @skip_section = !condition
when 'else'
- if if_stack.empty?
+ if @if_stack.empty?
raise InvalidInputrc, "#{file}:#{no}: unmatched else"
end
- if_stack.last[1] = !if_stack.last[1]
+ @skip_section = !@skip_section
when 'endif'
- if if_stack.empty?
+ if @if_stack.empty?
raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
end
- if_stack.pop
+ @skip_section = @if_stack.pop
when 'include'
- read(File.expand_path(args))
+ read(args)
end
end
diff --git a/lib/reline/face.rb b/lib/reline/face.rb
deleted file mode 100644
index d07196e2e7..0000000000
--- a/lib/reline/face.rb
+++ /dev/null
@@ -1,199 +0,0 @@
-# frozen_string_literal: true
-
-class Reline::Face
- SGR_PARAMETERS = {
- foreground: {
- black: 30,
- red: 31,
- green: 32,
- yellow: 33,
- blue: 34,
- magenta: 35,
- cyan: 36,
- white: 37,
- bright_black: 90,
- gray: 90,
- bright_red: 91,
- bright_green: 92,
- bright_yellow: 93,
- bright_blue: 94,
- bright_magenta: 95,
- bright_cyan: 96,
- bright_white: 97
- },
- background: {
- black: 40,
- red: 41,
- green: 42,
- yellow: 43,
- blue: 44,
- magenta: 45,
- cyan: 46,
- white: 47,
- bright_black: 100,
- gray: 100,
- bright_red: 101,
- bright_green: 102,
- bright_yellow: 103,
- bright_blue: 104,
- bright_magenta: 105,
- bright_cyan: 106,
- bright_white: 107,
- },
- style: {
- reset: 0,
- bold: 1,
- faint: 2,
- italicized: 3,
- underlined: 4,
- slowly_blinking: 5,
- blinking: 5,
- rapidly_blinking: 6,
- negative: 7,
- concealed: 8,
- crossed_out: 9
- }
- }.freeze
-
- class Config
- ESSENTIAL_DEFINE_NAMES = %i(default enhanced scrollbar).freeze
- RESET_SGR = "\e[0m".freeze
-
- def initialize(name, &block)
- @definition = {}
- block.call(self)
- ESSENTIAL_DEFINE_NAMES.each do |name|
- @definition[name] ||= { style: :reset, escape_sequence: RESET_SGR }
- end
- end
-
- attr_reader :definition
-
- def define(name, **values)
- values[:escape_sequence] = format_to_sgr(values.to_a).freeze
- @definition[name] = values
- end
-
- def reconfigure
- @definition.each_value do |values|
- values.delete(:escape_sequence)
- values[:escape_sequence] = format_to_sgr(values.to_a).freeze
- end
- end
-
- def [](name)
- @definition.dig(name, :escape_sequence) or raise ArgumentError, "unknown face: #{name}"
- end
-
- private
-
- def sgr_rgb(key, value)
- return nil unless rgb_expression?(value)
- if Reline::Face.truecolor?
- sgr_rgb_truecolor(key, value)
- else
- sgr_rgb_256color(key, value)
- end
- end
-
- def sgr_rgb_truecolor(key, value)
- case key
- when :foreground
- "38;2;"
- when :background
- "48;2;"
- end + value[1, 6].scan(/../).map(&:hex).join(";")
- end
-
- def sgr_rgb_256color(key, value)
- # 256 colors are
- # 0..15: standard colors, hight intensity colors
- # 16..232: 216 colors (R, G, B each 6 steps)
- # 233..255: grayscale colors (24 steps)
- # This methods converts rgb_expression to 216 colors
- rgb = value[1, 6].scan(/../).map(&:hex)
- # Color steps are [0, 95, 135, 175, 215, 255]
- r, g, b = rgb.map { |v| v <= 95 ? v / 48 : (v - 35) / 40 }
- color = (16 + 36 * r + 6 * g + b)
- case key
- when :foreground
- "38;5;#{color}"
- when :background
- "48;5;#{color}"
- end
- end
-
- def format_to_sgr(ordered_values)
- sgr = "\e[" + ordered_values.map do |key_value|
- key, value = key_value
- case key
- when :foreground, :background
- case value
- when Symbol
- SGR_PARAMETERS[key][value]
- when String
- sgr_rgb(key, value)
- end
- when :style
- [ value ].flatten.map do |style_name|
- SGR_PARAMETERS[:style][style_name]
- end.then do |sgr_parameters|
- sgr_parameters.include?(nil) ? nil : sgr_parameters
- end
- end.then do |rendition_expression|
- unless rendition_expression
- raise ArgumentError, "invalid SGR parameter: #{value.inspect}"
- end
- rendition_expression
- end
- end.join(';') + "m"
- sgr == RESET_SGR ? RESET_SGR : RESET_SGR + sgr
- end
-
- def rgb_expression?(color)
- color.respond_to?(:match?) and color.match?(/\A#[0-9a-fA-F]{6}\z/)
- end
- end
-
- private_constant :SGR_PARAMETERS, :Config
-
- def self.truecolor?
- @force_truecolor || %w[truecolor 24bit].include?(ENV['COLORTERM'])
- end
-
- def self.force_truecolor
- @force_truecolor = true
- @configs&.each_value(&:reconfigure)
- end
-
- def self.[](name)
- @configs[name]
- end
-
- def self.config(name, &block)
- @configs ||= {}
- @configs[name] = Config.new(name, &block)
- end
-
- def self.configs
- @configs.transform_values(&:definition)
- end
-
- def self.load_initial_configs
- config(:default) do |conf|
- conf.define :default, style: :reset
- conf.define :enhanced, style: :reset
- conf.define :scrollbar, style: :reset
- end
- config(:completion_dialog) do |conf|
- conf.define :default, foreground: :bright_white, background: :gray
- conf.define :enhanced, foreground: :black, background: :white
- conf.define :scrollbar, foreground: :white, background: :gray
- end
- end
-
- def self.reset_to_initial_configs
- @configs = {}
- load_initial_configs
- end
-end
diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb
index d52151ad3c..92c76cbba1 100644
--- a/lib/reline/general_io.rb
+++ b/lib/reline/general_io.rb
@@ -1,15 +1,10 @@
+require 'timeout'
require 'io/wait'
class Reline::GeneralIO
- RESET_COLOR = '' # Do not send color reset sequence
-
def self.reset(encoding: nil)
@@pasting = false
- if encoding
- @@encoding = encoding
- elsif defined?(@@encoding)
- remove_class_variable(:@@encoding)
- end
+ @@encoding = encoding
end
def self.encoding
@@ -36,17 +31,12 @@ class Reline::GeneralIO
@@input = val
end
- def self.with_raw_input
- yield
- end
-
- def self.getc(_timeout_second)
+ def self.getc
unless @@buf.empty?
return @@buf.shift
end
c = nil
loop do
- Reline.core.line_editor.handle_signal
result = @@input.wait_readable(0.1)
next if result.nil?
c = @@input.read(1)
@@ -60,7 +50,7 @@ class Reline::GeneralIO
end
def self.get_screen_size
- [24, 80]
+ [1, 1]
end
def self.cursor_pos
@@ -103,6 +93,14 @@ class Reline::GeneralIO
@@pasting
end
+ def self.start_pasting
+ @@pasting = true
+ end
+
+ def self.finish_pasting
+ @@pasting = false
+ end
+
def self.prep
end
diff --git a/lib/reline/history.rb b/lib/reline/history.rb
index 3f3b65fea6..7a1ed6b90b 100644
--- a/lib/reline/history.rb
+++ b/lib/reline/history.rb
@@ -62,7 +62,7 @@ class Reline::History < Array
private def check_index(index)
index += size if index < 0
if index < -2147483648 or 2147483647 < index
- raise RangeError.new("integer #{index} too big to convert to 'int'")
+ raise RangeError.new("integer #{index} too big to convert to `int'")
end
# If history_size is negative, history size is unlimited.
if @config.history_size.positive?
diff --git a/lib/reline/key_actor/base.rb b/lib/reline/key_actor/base.rb
index 194e98938c..a1cd7fb2a1 100644
--- a/lib/reline/key_actor/base.rb
+++ b/lib/reline/key_actor/base.rb
@@ -12,4 +12,8 @@ class Reline::KeyActor::Base
def default_key_bindings
@default_key_bindings
end
+
+ def reset_default_key_bindings
+ @default_key_bindings.clear
+ end
end
diff --git a/lib/reline/key_actor/emacs.rb b/lib/reline/key_actor/emacs.rb
index edd88289a3..a561feee57 100644
--- a/lib/reline/key_actor/emacs.rb
+++ b/lib/reline/key_actor/emacs.rb
@@ -19,7 +19,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 8 ^H
:em_delete_prev_char,
# 9 ^I
- :complete,
+ :ed_unassigned,
# 10 ^J
:ed_newline,
# 11 ^K
@@ -49,13 +49,13 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 23 ^W
:em_kill_region,
# 24 ^X
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 25 ^Y
:em_yank,
# 26 ^Z
:ed_ignore,
# 27 ^[
- :ed_unassigned,
+ :em_meta_next,
# 28 ^\
:ed_ignore,
# 29 ^]
@@ -63,7 +63,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 30 ^^
:ed_unassigned,
# 31 ^_
- :undo,
+ :ed_unassigned,
# 32 SPACE
:ed_insert,
# 33 !
@@ -319,9 +319,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 158 M-^^
:ed_unassigned,
# 159 M-^_
- :ed_unassigned,
+ :em_copy_prev_word,
# 160 M-SPACE
- :em_set_mark,
+ :ed_unassigned,
# 161 M-!
:ed_unassigned,
# 162 M-"
@@ -415,7 +415,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 206 M-N
:vi_search_next,
# 207 M-O
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 208 M-P
:vi_search_prev,
# 209 M-Q
@@ -431,15 +431,15 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 214 M-V
:ed_unassigned,
# 215 M-W
- :ed_unassigned,
+ :em_copy_region,
# 216 M-X
- :ed_unassigned,
+ :ed_command,
# 217 M-Y
- :em_yank_pop,
+ :ed_unassigned,
# 218 M-Z
:ed_unassigned,
# 219 M-[
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 220 M-\
:ed_unassigned,
# 221 M-]
@@ -495,9 +495,9 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
# 246 M-v
:ed_unassigned,
# 247 M-w
- :ed_unassigned,
+ :em_copy_region,
# 248 M-x
- :ed_unassigned,
+ :ed_command,
# 249 M-y
:ed_unassigned,
# 250 M-z
diff --git a/lib/reline/key_actor/vi_command.rb b/lib/reline/key_actor/vi_command.rb
index 06bb0ba8e4..98146d2f77 100644
--- a/lib/reline/key_actor/vi_command.rb
+++ b/lib/reline/key_actor/vi_command.rb
@@ -17,7 +17,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 7 ^G
:ed_unassigned,
# 8 ^H
- :ed_prev_char,
+ :ed_unassigned,
# 9 ^I
:ed_unassigned,
# 10 ^J
@@ -41,7 +41,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 19 ^S
:ed_ignore,
# 20 ^T
- :ed_transpose_chars,
+ :ed_unassigned,
# 21 ^U
:vi_kill_line_prev,
# 22 ^V
@@ -51,7 +51,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 24 ^X
:ed_unassigned,
# 25 ^Y
- :em_yank,
+ :ed_unassigned,
# 26 ^Z
:ed_unassigned,
# 27 ^[
@@ -75,7 +75,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 36 $
:ed_move_to_end,
# 37 %
- :ed_unassigned,
+ :vi_match,
# 38 &
:ed_unassigned,
# 39 '
@@ -89,11 +89,11 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 43 +
:ed_next_history,
# 44 ,
- :ed_unassigned,
+ :vi_repeat_prev_char,
# 45 -
:ed_prev_history,
# 46 .
- :ed_unassigned,
+ :vi_redo,
# 47 /
:vi_search_prev,
# 48 0
@@ -117,9 +117,9 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 57 9
:ed_argument_digit,
# 58 :
- :ed_unassigned,
+ :ed_command,
# 59 ;
- :ed_unassigned,
+ :vi_repeat_next_char,
# 60 <
:ed_unassigned,
# 61 =
@@ -157,21 +157,21 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 77 M
:ed_unassigned,
# 78 N
- :ed_unassigned,
+ :vi_repeat_search_prev,
# 79 O
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 80 P
:vi_paste_prev,
# 81 Q
:ed_unassigned,
# 82 R
- :ed_unassigned,
+ :vi_replace_mode,
# 83 S
- :ed_unassigned,
+ :vi_substitute_line,
# 84 T
:vi_to_prev_char,
# 85 U
- :ed_unassigned,
+ :vi_undo_line,
# 86 V
:ed_unassigned,
# 87 W
@@ -179,11 +179,11 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 88 X
:ed_delete_prev_char,
# 89 Y
- :ed_unassigned,
+ :vi_yank_end,
# 90 Z
:ed_unassigned,
# 91 [
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 92 \
:ed_unassigned,
# 93 ]
@@ -191,7 +191,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 94 ^
:vi_first_print,
# 95 _
- :ed_unassigned,
+ :vi_history_word,
# 96 `
:ed_unassigned,
# 97 a
@@ -221,7 +221,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 109 m
:ed_unassigned,
# 110 n
- :ed_unassigned,
+ :vi_repeat_search_next,
# 111 o
:ed_unassigned,
# 112 p
@@ -231,11 +231,11 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 114 r
:vi_replace_char,
# 115 s
- :ed_unassigned,
+ :vi_substitute_char,
# 116 t
:vi_to_next_char,
# 117 u
- :ed_unassigned,
+ :vi_undo,
# 118 v
:vi_histedit,
# 119 w
@@ -253,9 +253,9 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 125 }
:ed_unassigned,
# 126 ~
- :ed_unassigned,
+ :vi_change_case,
# 127 ^?
- :em_delete_prev_char,
+ :ed_unassigned,
# 128 M-^@
:ed_unassigned,
# 129 M-^A
@@ -415,7 +415,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 206 M-N
:ed_unassigned,
# 207 M-O
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 208 M-P
:ed_unassigned,
# 209 M-Q
@@ -439,7 +439,7 @@ class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
# 218 M-Z
:ed_unassigned,
# 219 M-[
- :ed_unassigned,
+ :ed_sequence_lead_in,
# 220 M-\
:ed_unassigned,
# 221 M-]
diff --git a/lib/reline/key_actor/vi_insert.rb b/lib/reline/key_actor/vi_insert.rb
index f8ccf468c6..b8e89f81d8 100644
--- a/lib/reline/key_actor/vi_insert.rb
+++ b/lib/reline/key_actor/vi_insert.rb
@@ -19,7 +19,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
# 8 ^H
:vi_delete_prev_char,
# 9 ^I
- :complete,
+ :ed_insert,
# 10 ^J
:ed_newline,
# 11 ^K
@@ -29,11 +29,11 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
# 13 ^M
:ed_newline,
# 14 ^N
- :menu_complete,
+ :ed_insert,
# 15 ^O
:ed_insert,
# 16 ^P
- :menu_complete_backward,
+ :ed_insert,
# 17 ^Q
:ed_ignore,
# 18 ^R
@@ -41,7 +41,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
# 19 ^S
:vi_search_next,
# 20 ^T
- :ed_transpose_chars,
+ :ed_insert,
# 21 ^U
:vi_kill_line_prev,
# 22 ^V
@@ -51,7 +51,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
# 24 ^X
:ed_insert,
# 25 ^Y
- :em_yank,
+ :ed_insert,
# 26 ^Z
:ed_insert,
# 27 ^[
diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb
index bceffbb53f..c1c61513a9 100644
--- a/lib/reline/key_stroke.rb
+++ b/lib/reline/key_stroke.rb
@@ -1,8 +1,4 @@
class Reline::KeyStroke
- ESC_BYTE = 27
- CSI_PARAMETER_BYTES_RANGE = 0x30..0x3f
- CSI_INTERMEDIATE_BYTES_RANGE = (0x20..0x2f)
-
def initialize(config)
@config = config
end
@@ -77,26 +73,17 @@ class Reline::KeyStroke
return :matched if it.max_by(&:size)&.size&.< input.size
return :matching if it.size > 1
}
- if key_mapping.keys.any? { |lhs| start_with?(input, lhs) }
- :matched
- else
- match_unknown_escape_sequence(input).first
- end
+ key_mapping.keys.select { |lhs|
+ start_with?(input, lhs)
+ }.tap { |it|
+ return it.size > 0 ? :matched : :unmatched
+ }
end
def expand(input)
+ input = compress_meta_key(input)
lhs = key_mapping.keys.select { |item| start_with?(input, item) }.sort_by(&:size).last
- unless lhs
- status, size = match_unknown_escape_sequence(input)
- case status
- when :matched
- return [:ed_unassigned] + expand(input.drop(size))
- when :matching
- return [:ed_unassigned]
- else
- return input
- end
- end
+ return input unless lhs
rhs = key_mapping[lhs]
case rhs
@@ -112,36 +99,6 @@ class Reline::KeyStroke
private
- # returns match status of CSI/SS3 sequence and matched length
- def match_unknown_escape_sequence(input)
- idx = 0
- return [:unmatched, nil] unless input[idx] == ESC_BYTE
- idx += 1
- idx += 1 if input[idx] == ESC_BYTE
-
- case input[idx]
- when nil
- return [:matching, nil]
- when 91 # == '['.ord
- # CSI sequence
- idx += 1
- idx += 1 while idx < input.size && CSI_PARAMETER_BYTES_RANGE.cover?(input[idx])
- idx += 1 while idx < input.size && CSI_INTERMEDIATE_BYTES_RANGE.cover?(input[idx])
- input[idx] ? [:matched, idx + 1] : [:matching, nil]
- when 79 # == 'O'.ord
- # SS3 sequence
- input[idx + 1] ? [:matched, idx + 2] : [:matching, nil]
- else
- if idx == 1
- # `ESC char`, make it :unmatched so that it will be handled correctly in `read_2nd_character_of_key_sequence`
- [:unmatched, nil]
- else
- # `ESC ESC char`
- [:matched, idx + 1]
- end
- end
- end
-
def key_mapping
@config.key_bindings
end
diff --git a/lib/reline/kill_ring.rb b/lib/reline/kill_ring.rb
index 201f6f3ca0..bb3684b42b 100644
--- a/lib/reline/kill_ring.rb
+++ b/lib/reline/kill_ring.rb
@@ -14,7 +14,7 @@ class Reline::KillRing
end
def ==(other)
- equal?(other)
+ object_id == other.object_id
end
end
@@ -68,7 +68,7 @@ class Reline::KillRing
def append(string, before_p = false)
case @state
when State::FRESH, State::YANK
- @ring << RingPoint.new(+string)
+ @ring << RingPoint.new(string)
@state = State::CONTINUED
when State::CONTINUED, State::PROCESSED
if before_p
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 23ece60220..8153aaba05 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -4,7 +4,9 @@ require 'reline/unicode'
require 'tempfile'
class Reline::LineEditor
+ # TODO: undo
# TODO: Use "private alias_method" idiom after drop Ruby 2.5.
+ attr_reader :line
attr_reader :byte_pointer
attr_accessor :confirm_multiline_termination_proc
attr_accessor :completion_proc
@@ -12,6 +14,7 @@ class Reline::LineEditor
attr_accessor :output_modifier_proc
attr_accessor :prompt_proc
attr_accessor :auto_indent_proc
+ attr_accessor :pre_input_hook
attr_accessor :dig_perfect_match_proc
attr_writer :output
@@ -32,93 +35,98 @@ class Reline::LineEditor
vi_next_big_word
vi_prev_big_word
vi_end_big_word
+ vi_repeat_next_char
+ vi_repeat_prev_char
}
module CompletionState
NORMAL = :normal
COMPLETION = :completion
MENU = :menu
+ JOURNEY = :journey
MENU_WITH_PERFECT_MATCH = :menu_with_perfect_match
PERFECT_MATCH = :perfect_match
end
- RenderedScreen = Struct.new(:base_y, :lines, :cursor_y, keyword_init: true)
+ CompletionJourneyData = Struct.new('CompletionJourneyData', :preposing, :postposing, :list, :pointer)
+ MenuInfo = Struct.new('MenuInfo', :target, :list)
- CompletionJourneyState = Struct.new(:line_index, :pre, :target, :post, :list, :pointer)
-
- class MenuInfo
- attr_reader :list
-
- def initialize(list)
- @list = list
- end
-
- def lines(screen_width)
- return [] if @list.empty?
-
- list = @list.sort
- sizes = list.map { |item| Reline::Unicode.calculate_width(item) }
- item_width = sizes.max + 2
- num_cols = [screen_width / item_width, 1].max
- num_rows = list.size.fdiv(num_cols).ceil
- list_with_padding = list.zip(sizes).map { |item, size| item + ' ' * (item_width - size) }
- aligned = (list_with_padding + [nil] * (num_rows * num_cols - list_with_padding.size)).each_slice(num_rows).to_a.transpose
- aligned.map do |row|
- row.join.rstrip
- end
- end
- end
-
- MINIMUM_SCROLLBAR_HEIGHT = 1
+ PROMPT_LIST_CACHE_TIMEOUT = 0.5
def initialize(config, encoding)
@config = config
@completion_append_character = ''
- @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset
reset_variables(encoding: encoding)
end
- def io_gate
- Reline::IOGate
- end
-
def set_pasting_state(in_pasting)
- # While pasting, text to be inserted is stored to @continuous_insertion_buffer.
- # After pasting, this buffer should be force inserted.
- process_insert(force: true) if @in_pasting && !in_pasting
@in_pasting = in_pasting
end
+ def simplified_rendering?
+ if finished?
+ false
+ elsif @just_cursor_moving and not @rerender_all
+ true
+ else
+ not @rerender_all and not finished? and @in_pasting
+ end
+ end
+
private def check_mode_string
+ mode_string = nil
if @config.show_mode_in_prompt
if @config.editing_mode_is?(:vi_command)
- @config.vi_cmd_mode_string
+ mode_string = @config.vi_cmd_mode_string
elsif @config.editing_mode_is?(:vi_insert)
- @config.vi_ins_mode_string
+ mode_string = @config.vi_ins_mode_string
elsif @config.editing_mode_is?(:emacs)
- @config.emacs_mode_string
+ mode_string = @config.emacs_mode_string
else
- '?'
+ mode_string = '?'
end
end
+ if mode_string != @prev_mode_string
+ @rerender_all = true
+ end
+ @prev_mode_string = mode_string
+ mode_string
end
- private def check_multiline_prompt(buffer, mode_string)
+ private def check_multiline_prompt(buffer)
if @vi_arg
prompt = "(arg: #{@vi_arg}) "
+ @rerender_all = true
elsif @searching_prompt
prompt = @searching_prompt
+ @rerender_all = true
else
prompt = @prompt
end
- if !@is_multiline
+ if simplified_rendering?
mode_string = check_mode_string
prompt = mode_string + prompt if mode_string
- [prompt] + [''] * (buffer.size - 1)
- elsif @prompt_proc
- prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") }
+ return [prompt, calculate_width(prompt, true), [prompt] * buffer.size]
+ end
+ if @prompt_proc
+ use_cached_prompt_list = false
+ if @cached_prompt_list
+ if @just_cursor_moving
+ use_cached_prompt_list = true
+ elsif Time.now.to_f < (@prompt_cache_time + PROMPT_LIST_CACHE_TIMEOUT) and buffer.size == @cached_prompt_list.size
+ use_cached_prompt_list = true
+ end
+ end
+ use_cached_prompt_list = false if @rerender_all
+ if use_cached_prompt_list
+ prompt_list = @cached_prompt_list
+ else
+ prompt_list = @cached_prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") }
+ @prompt_cache_time = Time.now.to_f
+ end
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
prompt_list = [prompt] if prompt_list.empty?
+ mode_string = check_mode_string
prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string
prompt = prompt_list[@line_index]
prompt = prompt_list[0] if prompt.nil?
@@ -128,17 +136,24 @@ class Reline::LineEditor
prompt_list << prompt_list.last
end
end
- prompt_list
+ prompt_width = calculate_width(prompt, true)
+ [prompt, prompt_width, prompt_list]
else
+ mode_string = check_mode_string
prompt = mode_string + prompt if mode_string
- [prompt] * buffer.size
+ prompt_width = calculate_width(prompt, true)
+ [prompt, prompt_width, nil]
end
end
def reset(prompt = '', encoding:)
+ @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
@screen_size = Reline::IOGate.get_screen_size
+ @screen_height = @screen_size.first
reset_variables(prompt, encoding: encoding)
- @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
+ Reline::IOGate.set_winch_handler do
+ @resized = true
+ end
if ENV.key?('RELINE_ALT_SCROLLBAR')
@full_block = '::'
@upper_half_block = "''"
@@ -162,57 +177,82 @@ class Reline::LineEditor
end
end
- def handle_signal
- handle_interrupted
- handle_resized
- end
-
- private def handle_resized
+ def resize
return unless @resized
-
- @screen_size = Reline::IOGate.get_screen_size
@resized = false
- scroll_into_view
- Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
- @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
- @rendered_screen.lines = []
- @rendered_screen.cursor_y = 0
- render_differential
- end
-
- private def handle_interrupted
- return unless @interrupted
-
- @interrupted = false
- clear_dialogs
- scrolldown = render_differential
- Reline::IOGate.scroll_down scrolldown
- Reline::IOGate.move_cursor_column 0
- @rendered_screen.lines = []
- @rendered_screen.cursor_y = 0
- case @old_trap
- when 'DEFAULT', 'SYSTEM_DEFAULT'
- raise Interrupt
- when 'IGNORE'
- # Do nothing
- when 'EXIT'
- exit
+ @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
+ old_screen_size = @screen_size
+ @screen_size = Reline::IOGate.get_screen_size
+ @screen_height = @screen_size.first
+ if old_screen_size.last < @screen_size.last # columns increase
+ @rerender_all = true
+ rerender
else
- @old_trap.call if @old_trap.respond_to?(:call)
+ back = 0
+ new_buffer = whole_lines
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer)
+ new_buffer.each_with_index do |line, index|
+ prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
+ width = prompt_width + calculate_width(line)
+ height = calculate_height_by_width(width)
+ back += height
+ end
+ @highest_in_all = back
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @first_line_started_from =
+ if @line_index.zero?
+ 0
+ else
+ calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ if @prompt_proc
+ prompt = prompt_list[@line_index]
+ prompt_width = calculate_width(prompt, true)
+ end
+ calculate_nearest_cursor
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @rerender_all = true
end
end
def set_signal_handlers
- Reline::IOGate.set_winch_handler do
- @resized = true
- end
- @old_trap = Signal.trap('INT') do
- @interrupted = true
+ @old_trap = Signal.trap('INT') {
+ clear_dialog
+ if @scroll_partial_screen
+ move_cursor_down(@screen_height - (@line_index - @scroll_partial_screen) - 1)
+ else
+ move_cursor_down(@highest_in_all - @line_index - 1)
+ end
+ Reline::IOGate.move_cursor_column(0)
+ scroll_down(1)
+ case @old_trap
+ when 'DEFAULT', 'SYSTEM_DEFAULT'
+ raise Interrupt
+ when 'IGNORE'
+ # Do nothing
+ when 'EXIT'
+ exit
+ else
+ @old_trap.call if @old_trap.respond_to?(:call)
+ end
+ }
+ begin
+ @old_tstp_trap = Signal.trap('TSTP') {
+ Reline::IOGate.ungetc("\C-z".ord)
+ @old_tstp_trap.call if @old_tstp_trap.respond_to?(:call)
+ }
+ rescue ArgumentError
end
end
def finalize
Signal.trap('INT', @old_trap)
+ begin
+ Signal.trap('TSTP', @old_tstp_trap)
+ rescue ArgumentError
+ end
end
def eof?
@@ -225,43 +265,55 @@ class Reline::LineEditor
@encoding = encoding
@is_multiline = false
@finished = false
+ @cleared = false
+ @rerender_all = false
@history_pointer = nil
@kill_ring ||= Reline::KillRing.new
@vi_clipboard = ''
@vi_arg = nil
@waiting_proc = nil
- @vi_waiting_operator = nil
- @vi_waiting_operator_arg = nil
- @completion_journey_state = nil
+ @waiting_operator_proc = nil
+ @waiting_operator_vi_arg = nil
+ @completion_journey_data = nil
@completion_state = CompletionState::NORMAL
@perfect_matched = nil
@menu_info = nil
+ @first_prompt = true
@searching_prompt = nil
@first_char = true
- @just_cursor_moving = false
+ @add_newline_to_end_of_buffer = false
+ @just_cursor_moving = nil
+ @cached_prompt_list = nil
+ @prompt_cache_time = nil
@eof = false
@continuous_insertion_buffer = String.new(encoding: @encoding)
- @scroll_partial_screen = 0
+ @scroll_partial_screen = nil
+ @prev_mode_string = nil
@drop_terminate_spaces = false
@in_pasting = false
@auto_indent_proc = nil
@dialogs = []
- @interrupted = false
+ @last_key = nil
@resized = false
- @cache = {}
- @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
- @past_lines = []
- @undoing = false
reset_line
end
def reset_line
+ @cursor = 0
+ @cursor_max = 0
@byte_pointer = 0
@buffer_of_lines = [String.new(encoding: @encoding)]
@line_index = 0
- @cache.clear
+ @previous_line_index = nil
+ @line = @buffer_of_lines[0]
+ @first_line_started_from = 0
+ @move_up = 0
+ @started_from = 0
+ @highest_in_this = 1
+ @highest_in_all = 1
@line_backup_in_history = nil
@multibyte_buffer = String.new(encoding: 'ASCII-8BIT')
+ @check_new_auto_indent = false
end
def multiline_on
@@ -272,44 +324,68 @@ class Reline::LineEditor
@is_multiline = false
end
+ private def calculate_height_by_lines(lines, prompt)
+ result = 0
+ prompt_list = prompt.is_a?(Array) ? prompt : nil
+ lines.each_with_index { |line, i|
+ prompt = prompt_list[i] if prompt_list and prompt_list[i]
+ result += calculate_height_by_width(calculate_width(prompt, true) + calculate_width(line))
+ }
+ result
+ end
+
private def insert_new_line(cursor_line, next_line)
+ @line = cursor_line
@buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: @encoding))
- @buffer_of_lines[@line_index] = cursor_line
+ @previous_line_index = @line_index
@line_index += 1
- @byte_pointer = 0
- if @auto_indent_proc && !@in_pasting
- if next_line.empty?
- (
- # For compatibility, use this calculation instead of just `process_auto_indent @line_index - 1, cursor_dependent: false`
- indent1 = @auto_indent_proc.(@buffer_of_lines.take(@line_index - 1).push(''), @line_index - 1, 0, true)
- indent2 = @auto_indent_proc.(@buffer_of_lines.take(@line_index), @line_index - 1, @buffer_of_lines[@line_index - 1].bytesize, false)
- indent = indent2 || indent1
- @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A\s*/, '')
- )
- process_auto_indent @line_index, add_newline: true
- else
- process_auto_indent @line_index - 1, cursor_dependent: false
- process_auto_indent @line_index, add_newline: true # Need for compatibility
- process_auto_indent @line_index, cursor_dependent: false
- end
+ @just_cursor_moving = false
+ end
+
+ private def calculate_height_by_width(width)
+ width.div(@screen_size.last) + 1
+ end
+
+ private def split_by_width(str, max_width)
+ Reline::Unicode.split_by_width(str, max_width, @encoding)
+ end
+
+ private def scroll_down(val)
+ if val <= @rest_height
+ Reline::IOGate.move_cursor_down(val)
+ @rest_height -= val
+ else
+ Reline::IOGate.move_cursor_down(@rest_height)
+ Reline::IOGate.scroll_down(val - @rest_height)
+ @rest_height = 0
end
end
- private def split_by_width(str, max_width, offset: 0)
- Reline::Unicode.split_by_width(str, max_width, @encoding, offset: offset)
+ private def move_cursor_up(val)
+ if val > 0
+ Reline::IOGate.move_cursor_up(val)
+ @rest_height += val
+ elsif val < 0
+ move_cursor_down(-val)
+ end
end
- def current_byte_pointer_cursor
- calculate_width(current_line.byteslice(0, @byte_pointer))
+ private def move_cursor_down(val)
+ if val > 0
+ Reline::IOGate.move_cursor_down(val)
+ @rest_height -= val
+ @rest_height = 0 if @rest_height < 0
+ elsif val < 0
+ move_cursor_up(-val)
+ end
end
- private def calculate_nearest_cursor(cursor)
- line_to_calc = current_line
+ private def calculate_nearest_cursor(line_to_calc = @line, cursor = @cursor, started_from = @started_from, byte_pointer = @byte_pointer, update = true)
new_cursor_max = calculate_width(line_to_calc)
new_cursor = 0
new_byte_pointer = 0
height = 1
- max_width = screen_width
+ max_width = @screen_size.last
if @config.editing_mode_is?(:vi_command)
last_byte_size = Reline::Unicode.get_prev_mbchar_size(line_to_calc, line_to_calc.bytesize)
if last_byte_size > 0
@@ -335,242 +411,120 @@ class Reline::LineEditor
end
new_byte_pointer += gc.bytesize
end
- @byte_pointer = new_byte_pointer
- end
-
- def with_cache(key, *deps)
- cached_deps, value = @cache[key]
- if cached_deps != deps
- @cache[key] = [deps, value = yield(*deps, cached_deps, value)]
+ new_started_from = height - 1
+ if update
+ @cursor = new_cursor
+ @cursor_max = new_cursor_max
+ @started_from = new_started_from
+ @byte_pointer = new_byte_pointer
+ else
+ [new_cursor, new_cursor_max, new_started_from, new_byte_pointer]
end
- value
end
- def modified_lines
- with_cache(__method__, whole_lines, finished?) do |whole, complete|
- modify_lines(whole, complete)
- end
+ def rerender_all
+ @rerender_all = true
+ process_insert(force: true)
+ rerender
end
- def prompt_list
- with_cache(__method__, whole_lines, check_mode_string, @vi_arg, @searching_prompt) do |lines, mode_string|
- check_multiline_prompt(lines, mode_string)
+ def rerender
+ return if @line.nil?
+ if @menu_info
+ scroll_down(@highest_in_all - @first_line_started_from)
+ @rerender_all = true
end
- end
-
- def screen_height
- @screen_size.first
- end
-
- def screen_width
- @screen_size.last
- end
-
- def screen_scroll_top
- @scroll_partial_screen
- end
-
- def wrapped_prompt_and_input_lines
- with_cache(__method__, @buffer_of_lines.size, modified_lines, prompt_list, screen_width) do |n, lines, prompts, width, prev_cache_key, cached_value|
- prev_n, prev_lines, prev_prompts, prev_width = prev_cache_key
- cached_wraps = {}
- if prev_width == width
- prev_n.times do |i|
- cached_wraps[[prev_prompts[i], prev_lines[i]]] = cached_value[i]
- end
- end
-
- n.times.map do |i|
- prompt = prompts[i] || ''
- line = lines[i] || ''
- if (cached = cached_wraps[[prompt, line]])
- next cached
- end
- *wrapped_prompts, code_line_prompt = split_by_width(prompt, width).first.compact
- wrapped_lines = split_by_width(line, width, offset: calculate_width(code_line_prompt, true)).first.compact
- wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] }
- end
+ if @menu_info
+ show_menu
+ @menu_info = nil
end
- end
-
- def calculate_overlay_levels(overlay_levels)
- levels = []
- overlay_levels.each do |x, w, l|
- levels.fill(l, x, w)
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines)
+ if @cleared
+ clear_screen_buffer(prompt, prompt_list, prompt_width)
+ @cleared = false
+ return
end
- levels
- end
-
- def render_line_differential(old_items, new_items)
- old_levels = calculate_overlay_levels(old_items.zip(new_items).each_with_index.map {|((x, w, c), (nx, _nw, nc)), i| [x, w, c == nc && x == nx ? i : -1] if x }.compact)
- new_levels = calculate_overlay_levels(new_items.each_with_index.map { |(x, w), i| [x, w, i] if x }.compact).take(screen_width)
- base_x = 0
- new_levels.zip(old_levels).chunk { |n, o| n == o ? :skip : n || :blank }.each do |level, chunk|
- width = chunk.size
- if level == :skip
- # do nothing
- elsif level == :blank
- Reline::IOGate.move_cursor_column base_x
- @output.write "#{Reline::IOGate::RESET_COLOR}#{' ' * width}"
+ if @is_multiline and finished? and @scroll_partial_screen
+ # Re-output all code higher than the screen when finished.
+ Reline::IOGate.move_cursor_up(@first_line_started_from + @started_from - @scroll_partial_screen)
+ Reline::IOGate.move_cursor_column(0)
+ @scroll_partial_screen = nil
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines)
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
else
- x, w, content = new_items[level]
- cover_begin = base_x != 0 && new_levels[base_x - 1] == level
- cover_end = new_levels[base_x + width] == level
- pos = 0
- unless x == base_x && w == width
- content, pos = Reline::Unicode.take_mbchar_range(content, base_x - x, width, cover_begin: cover_begin, cover_end: cover_end, padding: true)
- end
- Reline::IOGate.move_cursor_column x + pos
- @output.write "#{Reline::IOGate::RESET_COLOR}#{content}#{Reline::IOGate::RESET_COLOR}"
+ new_lines = whole_lines
end
- base_x += width
- end
- if old_levels.size > new_levels.size
- Reline::IOGate.move_cursor_column new_levels.size
- Reline::IOGate.erase_after_cursor
- end
- end
-
- # Calculate cursor position in word wrapped content.
- def wrapped_cursor_position
- prompt_width = calculate_width(prompt_list[@line_index], true)
- line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer)
- wrapped_line_before_cursor = split_by_width(' ' * prompt_width + line_before_cursor, screen_width).first.compact
- wrapped_cursor_y = wrapped_prompt_and_input_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
- wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last)
- [wrapped_cursor_x, wrapped_cursor_y]
- end
-
- def clear_dialogs
- @dialogs.each do |dialog|
- dialog.contents = nil
- dialog.trap_key = nil
- end
- end
-
- def update_dialogs(key = nil)
- wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
- @dialogs.each do |dialog|
- dialog.trap_key = nil
- update_each_dialog(dialog, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top, key)
- end
- end
-
- def render_finished
- clear_rendered_lines
- render_full_content
- end
-
- def clear_rendered_lines
- Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
- Reline::IOGate.move_cursor_column 0
-
- num_lines = @rendered_screen.lines.size
- return unless num_lines && num_lines >= 1
-
- Reline::IOGate.move_cursor_down num_lines - 1
- (num_lines - 1).times do
- Reline::IOGate.erase_after_cursor
- Reline::IOGate.move_cursor_up 1
- end
- Reline::IOGate.erase_after_cursor
- @rendered_screen.lines = []
- @rendered_screen.cursor_y = 0
- end
-
- def render_full_content
- lines = @buffer_of_lines.size.times.map do |i|
- line = prompt_list[i] + modified_lines[i]
- wrapped_lines, = split_by_width(line, screen_width)
- wrapped_lines.last.empty? ? "#{line} " : line
- end
- @output.puts lines.map { |l| "#{l}\r\n" }.join
- end
-
- def print_nomultiline_prompt(prompt)
- return unless prompt && !@is_multiline
-
- # Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
- @rendered_screen.lines = [[[0, Reline::Unicode.calculate_width(prompt, true), prompt]]]
- @rendered_screen.cursor_y = 0
- @output.write prompt
- end
-
- def render_differential
- wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
-
- rendered_lines = @rendered_screen.lines
- new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
- prompt_width = Reline::Unicode.calculate_width(prompt, true)
- [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
- end
- if @menu_info
- @menu_info.lines(screen_width).each do |item|
- new_lines << [[0, Reline::Unicode.calculate_width(item), item]]
+ modify_lines(new_lines).each_with_index do |line, index|
+ @output.write "#{prompt_list ? prompt_list[index] : prompt}#{line}\n"
+ Reline::IOGate.erase_after_cursor
end
- @menu_info = nil # TODO: do not change state here
+ @output.flush
+ clear_dialog
+ return
end
-
- @dialogs.each_with_index do |dialog, index|
- next unless dialog.contents
-
- x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top
- y_range.each do |row|
- next if row < 0 || row >= screen_height
- dialog_rows = new_lines[row] ||= []
- # index 0 is for prompt, index 1 is for line, index 2.. is for dialog
- dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
+ new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line))
+ rendered = false
+ if @add_newline_to_end_of_buffer
+ clear_dialog_with_content
+ rerender_added_newline(prompt, prompt_width)
+ @add_newline_to_end_of_buffer = false
+ else
+ if @just_cursor_moving and not @rerender_all
+ clear_dialog_with_content
+ rendered = just_move_cursor
+ @just_cursor_moving = false
+ return
+ elsif @previous_line_index or new_highest_in_this != @highest_in_this
+ clear_dialog_with_content
+ rerender_changed_current_line
+ @previous_line_index = nil
+ rendered = true
+ elsif @rerender_all
+ rerender_all_lines
+ @rerender_all = false
+ rendered = true
+ else
end
end
-
- cursor_y = @rendered_screen.cursor_y
- if new_lines != rendered_lines
- # Hide cursor while rendering to avoid cursor flickering.
- Reline::IOGate.hide_cursor
- num_lines = [[new_lines.size, rendered_lines.size].max, screen_height].min
- if @rendered_screen.base_y + num_lines > screen_height
- Reline::IOGate.scroll_down(num_lines - cursor_y - 1)
- @rendered_screen.base_y = screen_height - num_lines
- cursor_y = num_lines - 1
- end
- num_lines.times do |i|
- rendered_line = rendered_lines[i] || []
- line_to_render = new_lines[i] || []
- next if rendered_line == line_to_render
-
- Reline::IOGate.move_cursor_down i - cursor_y
- cursor_y = i
- unless rendered_lines[i]
- Reline::IOGate.move_cursor_column 0
- Reline::IOGate.erase_after_cursor
+ if @is_multiline
+ if finished?
+ # Always rerender on finish because output_modifier_proc may return a different output.
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ new_lines = whole_lines
end
- render_line_differential(rendered_line, line_to_render)
+ line = modify_lines(new_lines)[@line_index]
+ clear_dialog
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines)
+ render_partial(prompt, prompt_width, line, @first_line_started_from)
+ move_cursor_down(@highest_in_all - (@first_line_started_from + @highest_in_this - 1) - 1)
+ scroll_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
+ else
+ if not rendered and not @in_pasting
+ line = modify_lines(whole_lines)[@line_index]
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines)
+ render_partial(prompt, prompt_width, line, @first_line_started_from)
+ end
+ render_dialog((prompt_width + @cursor) % @screen_size.last)
+ end
+ @buffer_of_lines[@line_index] = @line
+ @rest_height = 0 if @scroll_partial_screen
+ else
+ line = modify_lines(whole_lines)[@line_index]
+ render_partial(prompt, prompt_width, line, 0)
+ if finished?
+ scroll_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
end
- @rendered_screen.lines = new_lines
- Reline::IOGate.show_cursor
end
- y = wrapped_cursor_y - screen_scroll_top
- Reline::IOGate.move_cursor_column wrapped_cursor_x
- Reline::IOGate.move_cursor_down y - cursor_y
- @rendered_screen.cursor_y = y
- new_lines.size - y
- end
-
- def upper_space_height(wrapped_cursor_y)
- wrapped_cursor_y - screen_scroll_top
- end
-
- def rest_height(wrapped_cursor_y)
- screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
- end
-
- def rerender
- render_differential unless @in_pasting
end
class DialogProcScope
- CompletionJourneyData = Struct.new(:preposing, :postposing, :list, :pointer)
-
def initialize(line_editor, config, proc_to_exec, context)
@line_editor = line_editor
@config = config
@@ -621,20 +575,11 @@ class Reline::LineEditor
end
def screen_width
- @line_editor.screen_width
- end
-
- def screen_height
- @line_editor.screen_height
- end
-
- def preferred_dialog_height
- _wrapped_cursor_x, wrapped_cursor_y = @line_editor.wrapped_cursor_position
- [@line_editor.upper_space_height(wrapped_cursor_y), @line_editor.rest_height(wrapped_cursor_y), (screen_height + 6) / 5].max
+ @line_editor.instance_variable_get(:@screen_size).last
end
def completion_journey_data
- @line_editor.dialog_proc_scope_completion_journey_data
+ @line_editor.instance_variable_get(:@completion_journey_data)
end
def config
@@ -648,7 +593,7 @@ class Reline::LineEditor
class Dialog
attr_reader :name, :contents, :width
- attr_accessor :scroll_top, :pointer, :column, :vertical_offset, :trap_key
+ attr_accessor :scroll_top, :scrollbar_pos, :pointer, :column, :vertical_offset, :lines_backup, :trap_key
def initialize(name, config, proc_scope)
@name = name
@@ -703,31 +648,52 @@ class Reline::LineEditor
end
DIALOG_DEFAULT_HEIGHT = 20
+ private def render_dialog(cursor_column)
+ @dialogs.each do |dialog|
+ render_each_dialog(dialog, cursor_column)
+ end
+ end
- private def dialog_range(dialog, dialog_y)
- x_range = dialog.column...dialog.column + dialog.width
- y_range = dialog_y + dialog.vertical_offset...dialog_y + dialog.vertical_offset + dialog.contents.size
- [x_range, y_range]
+ private def padding_space_with_escape_sequences(str, width)
+ padding_width = width - calculate_width(str, true)
+ # padding_width should be only positive value. But macOS and Alacritty returns negative value.
+ padding_width = 0 if padding_width < 0
+ str + (' ' * padding_width)
end
- private def update_each_dialog(dialog, cursor_column, cursor_row, key = nil)
- dialog.set_cursor_pos(cursor_column, cursor_row)
- dialog_render_info = dialog.call(key)
+ private def render_each_dialog(dialog, cursor_column)
+ if @in_pasting
+ clear_each_dialog(dialog)
+ dialog.contents = nil
+ dialog.trap_key = nil
+ return
+ end
+ dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
+ dialog_render_info = dialog.call(@last_key)
if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty?
+ dialog.lines_backup = {
+ lines: modify_lines(whole_lines),
+ line_index: @line_index,
+ first_line_started_from: @first_line_started_from,
+ started_from: @started_from,
+ byte_pointer: @byte_pointer
+ }
+ clear_each_dialog(dialog)
dialog.contents = nil
dialog.trap_key = nil
return
end
- contents = dialog_render_info.contents
+ old_dialog = dialog.clone
+ dialog.contents = dialog_render_info.contents
pointer = dialog.pointer
if dialog_render_info.width
dialog.width = dialog_render_info.width
else
- dialog.width = contents.map { |l| calculate_width(l, true) }.max
+ dialog.width = dialog.contents.map { |l| calculate_width(l, true) }.max
end
height = dialog_render_info.height || DIALOG_DEFAULT_HEIGHT
- height = contents.size if contents.size < height
- if contents.size > height
+ height = dialog.contents.size if dialog.contents.size < height
+ if dialog.contents.size > height
if dialog.pointer
if dialog.pointer < 0
dialog.scroll_top = 0
@@ -737,77 +703,591 @@ class Reline::LineEditor
dialog.scroll_top = dialog.pointer
end
pointer = dialog.pointer - dialog.scroll_top
- else
- dialog.scroll_top = 0
end
- contents = contents[dialog.scroll_top, height]
+ dialog.contents = dialog.contents[dialog.scroll_top, height]
+ end
+ if dialog.contents and dialog.scroll_top >= dialog.contents.size
+ dialog.scroll_top = dialog.contents.size - height
end
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
bar_max_height = height * 2
moving_distance = (dialog_render_info.contents.size - height) * 2
position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
- bar_height = (bar_max_height * ((contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
- bar_height = MINIMUM_SCROLLBAR_HEIGHT if bar_height < MINIMUM_SCROLLBAR_HEIGHT
- scrollbar_pos = ((bar_max_height - bar_height) * position_ratio).floor.to_i
+ bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
+ dialog.scrollbar_pos = ((bar_max_height - bar_height) * position_ratio).floor.to_i
else
- scrollbar_pos = nil
+ dialog.scrollbar_pos = nil
end
+ upper_space = @first_line_started_from - @started_from
dialog.column = dialog_render_info.pos.x
- dialog.width += @block_elem_width if scrollbar_pos
- diff = (dialog.column + dialog.width) - screen_width
+ dialog.width += @block_elem_width if dialog.scrollbar_pos
+ diff = (dialog.column + dialog.width) - (@screen_size.last)
if diff > 0
dialog.column -= diff
end
- if rest_height(screen_scroll_top + cursor_row) - dialog_render_info.pos.y >= height
+ if (@rest_height - dialog_render_info.pos.y) >= height
dialog.vertical_offset = dialog_render_info.pos.y + 1
- elsif cursor_row >= height
+ elsif upper_space >= height
dialog.vertical_offset = dialog_render_info.pos.y - height
else
+ if (@rest_height - dialog_render_info.pos.y) < height
+ scroll_down(height + dialog_render_info.pos.y)
+ move_cursor_up(height + dialog_render_info.pos.y)
+ end
dialog.vertical_offset = dialog_render_info.pos.y + 1
end
+ Reline::IOGate.hide_cursor
if dialog.column < 0
dialog.column = 0
- dialog.width = screen_width
- end
- face = Reline::Face[dialog_render_info.face || :default]
- scrollbar_sgr = face[:scrollbar]
- default_sgr = face[:default]
- enhanced_sgr = face[:enhanced]
- dialog.contents = contents.map.with_index do |item, i|
- line_sgr = i == pointer ? enhanced_sgr : default_sgr
- str_width = dialog.width - (scrollbar_pos.nil? ? 0 : @block_elem_width)
- str, = Reline::Unicode.take_mbchar_range(item, 0, str_width, padding: true)
- colored_content = "#{line_sgr}#{str}"
- if scrollbar_pos
- if scrollbar_pos <= (i * 2) and (i * 2 + 1) < (scrollbar_pos + bar_height)
- colored_content + scrollbar_sgr + @full_block
- elsif scrollbar_pos <= (i * 2) and (i * 2) < (scrollbar_pos + bar_height)
- colored_content + scrollbar_sgr + @upper_half_block
- elsif scrollbar_pos <= (i * 2 + 1) and (i * 2) < (scrollbar_pos + bar_height)
- colored_content + scrollbar_sgr + @lower_half_block
+ dialog.width = @screen_size.last
+ end
+ reset_dialog(dialog, old_dialog)
+ move_cursor_down(dialog.vertical_offset)
+ Reline::IOGate.move_cursor_column(dialog.column)
+ dialog.contents.each_with_index do |item, i|
+ if i == pointer
+ fg_color = dialog_render_info.pointer_fg_color
+ bg_color = dialog_render_info.pointer_bg_color
+ else
+ fg_color = dialog_render_info.fg_color
+ bg_color = dialog_render_info.bg_color
+ end
+ str_width = dialog.width - (dialog.scrollbar_pos.nil? ? 0 : @block_elem_width)
+ str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
+ @output.write "\e[#{bg_color}m\e[#{fg_color}m#{str}"
+ if dialog.scrollbar_pos and (dialog.scrollbar_pos != old_dialog.scrollbar_pos or dialog.column != old_dialog.column)
+ @output.write "\e[37m"
+ if dialog.scrollbar_pos <= (i * 2) and (i * 2 + 1) < (dialog.scrollbar_pos + bar_height)
+ @output.write @full_block
+ elsif dialog.scrollbar_pos <= (i * 2) and (i * 2) < (dialog.scrollbar_pos + bar_height)
+ @output.write @upper_half_block
+ elsif dialog.scrollbar_pos <= (i * 2 + 1) and (i * 2) < (dialog.scrollbar_pos + bar_height)
+ @output.write @lower_half_block
+ else
+ @output.write ' ' * @block_elem_width
+ end
+ end
+ @output.write "\e[0m"
+ Reline::IOGate.move_cursor_column(dialog.column)
+ move_cursor_down(1) if i < (dialog.contents.size - 1)
+ end
+ Reline::IOGate.move_cursor_column(cursor_column)
+ move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
+ Reline::IOGate.show_cursor
+ dialog.lines_backup = {
+ lines: modify_lines(whole_lines),
+ line_index: @line_index,
+ first_line_started_from: @first_line_started_from,
+ started_from: @started_from,
+ byte_pointer: @byte_pointer
+ }
+ end
+
+ private def reset_dialog(dialog, old_dialog)
+ return if dialog.lines_backup.nil? or old_dialog.contents.nil?
+ prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines])
+ visual_lines = []
+ visual_start = nil
+ dialog.lines_backup[:lines].each_with_index { |l, i|
+ pr = prompt_list ? prompt_list[i] : prompt
+ vl, _ = split_by_width(pr + l, @screen_size.last)
+ vl.compact!
+ if i == dialog.lines_backup[:line_index]
+ visual_start = visual_lines.size + dialog.lines_backup[:started_from]
+ end
+ visual_lines.concat(vl)
+ }
+ old_y = dialog.lines_backup[:first_line_started_from] + dialog.lines_backup[:started_from]
+ y = @first_line_started_from + @started_from
+ y_diff = y - old_y
+ if (old_y + old_dialog.vertical_offset) < (y + dialog.vertical_offset)
+ # rerender top
+ move_cursor_down(old_dialog.vertical_offset - y_diff)
+ start = visual_start + old_dialog.vertical_offset
+ line_num = dialog.vertical_offset - old_dialog.vertical_offset
+ line_num.times do |i|
+ Reline::IOGate.move_cursor_column(old_dialog.column)
+ if visual_lines[start + i].nil?
+ s = ' ' * old_dialog.width
+ else
+ s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, old_dialog.width)
+ s = padding_space_with_escape_sequences(s, old_dialog.width)
+ end
+ @output.write "\e[0m#{s}\e[0m"
+ move_cursor_down(1) if i < (line_num - 1)
+ end
+ move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
+ end
+ if (old_y + old_dialog.vertical_offset + old_dialog.contents.size) > (y + dialog.vertical_offset + dialog.contents.size)
+ # rerender bottom
+ move_cursor_down(dialog.vertical_offset + dialog.contents.size - y_diff)
+ start = visual_start + dialog.vertical_offset + dialog.contents.size
+ line_num = (old_dialog.vertical_offset + old_dialog.contents.size) - (dialog.vertical_offset + dialog.contents.size)
+ line_num.times do |i|
+ Reline::IOGate.move_cursor_column(old_dialog.column)
+ if visual_lines[start + i].nil?
+ s = ' ' * old_dialog.width
+ else
+ s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, old_dialog.width)
+ s = padding_space_with_escape_sequences(s, old_dialog.width)
+ end
+ @output.write "\e[0m#{s}\e[0m"
+ move_cursor_down(1) if i < (line_num - 1)
+ end
+ move_cursor_up(dialog.vertical_offset + dialog.contents.size + line_num - 1 - y_diff)
+ end
+ if old_dialog.column < dialog.column
+ # rerender left
+ move_cursor_down(old_dialog.vertical_offset - y_diff)
+ width = dialog.column - old_dialog.column
+ start = visual_start + old_dialog.vertical_offset
+ line_num = old_dialog.contents.size
+ line_num.times do |i|
+ Reline::IOGate.move_cursor_column(old_dialog.column)
+ if visual_lines[start + i].nil?
+ s = ' ' * width
+ else
+ s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, width)
+ s = padding_space_with_escape_sequences(s, dialog.width)
+ end
+ @output.write "\e[0m#{s}\e[0m"
+ move_cursor_down(1) if i < (line_num - 1)
+ end
+ move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
+ end
+ if (old_dialog.column + old_dialog.width) > (dialog.column + dialog.width)
+ # rerender right
+ move_cursor_down(old_dialog.vertical_offset + y_diff)
+ width = (old_dialog.column + old_dialog.width) - (dialog.column + dialog.width)
+ start = visual_start + old_dialog.vertical_offset
+ line_num = old_dialog.contents.size
+ line_num.times do |i|
+ Reline::IOGate.move_cursor_column(old_dialog.column + dialog.width)
+ if visual_lines[start + i].nil?
+ s = ' ' * width
+ else
+ s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column + dialog.width, width)
+ rerender_width = old_dialog.width - dialog.width
+ s = padding_space_with_escape_sequences(s, rerender_width)
+ end
+ Reline::IOGate.move_cursor_column(dialog.column + dialog.width)
+ @output.write "\e[0m#{s}\e[0m"
+ move_cursor_down(1) if i < (line_num - 1)
+ end
+ move_cursor_up(old_dialog.vertical_offset + line_num - 1 + y_diff)
+ end
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ end
+
+ private def clear_dialog
+ @dialogs.each do |dialog|
+ clear_each_dialog(dialog)
+ end
+ end
+
+ private def clear_dialog_with_content
+ @dialogs.each do |dialog|
+ clear_each_dialog(dialog)
+ dialog.contents = nil
+ dialog.trap_key = nil
+ end
+ end
+
+ private def clear_each_dialog(dialog)
+ dialog.trap_key = nil
+ return unless dialog.contents
+ prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines])
+ visual_lines = []
+ visual_lines_under_dialog = []
+ visual_start = nil
+ dialog.lines_backup[:lines].each_with_index { |l, i|
+ pr = prompt_list ? prompt_list[i] : prompt
+ vl, _ = split_by_width(pr + l, @screen_size.last)
+ vl.compact!
+ if i == dialog.lines_backup[:line_index]
+ visual_start = visual_lines.size + dialog.lines_backup[:started_from] + dialog.vertical_offset
+ end
+ visual_lines.concat(vl)
+ }
+ visual_lines_under_dialog = visual_lines[visual_start, dialog.contents.size]
+ visual_lines_under_dialog = [] if visual_lines_under_dialog.nil?
+ Reline::IOGate.hide_cursor
+ move_cursor_down(dialog.vertical_offset)
+ dialog_vertical_size = dialog.contents.size
+ dialog_vertical_size.times do |i|
+ if i < visual_lines_under_dialog.size
+ Reline::IOGate.move_cursor_column(dialog.column)
+ str = Reline::Unicode.take_range(visual_lines_under_dialog[i], dialog.column, dialog.width)
+ str = padding_space_with_escape_sequences(str, dialog.width)
+ @output.write "\e[0m#{str}\e[0m"
+ else
+ Reline::IOGate.move_cursor_column(dialog.column)
+ @output.write "\e[0m#{' ' * dialog.width}\e[0m"
+ end
+ move_cursor_down(1) if i < (dialog_vertical_size - 1)
+ end
+ move_cursor_up(dialog_vertical_size - 1 + dialog.vertical_offset)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ Reline::IOGate.show_cursor
+ end
+
+ private def calculate_scroll_partial_screen(highest_in_all, cursor_y)
+ if @screen_height < highest_in_all
+ old_scroll_partial_screen = @scroll_partial_screen
+ if cursor_y == 0
+ @scroll_partial_screen = 0
+ elsif cursor_y == (highest_in_all - 1)
+ @scroll_partial_screen = highest_in_all - @screen_height
+ else
+ if @scroll_partial_screen
+ if cursor_y <= @scroll_partial_screen
+ @scroll_partial_screen = cursor_y
+ elsif (@scroll_partial_screen + @screen_height - 1) < cursor_y
+ @scroll_partial_screen = cursor_y - (@screen_height - 1)
+ end
+ else
+ if cursor_y > (@screen_height - 1)
+ @scroll_partial_screen = cursor_y - (@screen_height - 1)
+ else
+ @scroll_partial_screen = 0
+ end
+ end
+ end
+ if @scroll_partial_screen != old_scroll_partial_screen
+ @rerender_all = true
+ end
+ else
+ if @scroll_partial_screen
+ @rerender_all = true
+ end
+ @scroll_partial_screen = nil
+ end
+ end
+
+ private def rerender_added_newline(prompt, prompt_width)
+ scroll_down(1)
+ @buffer_of_lines[@previous_line_index] = @line
+ @line = @buffer_of_lines[@line_index]
+ unless @in_pasting
+ render_partial(prompt, prompt_width, @line, @first_line_started_from + @started_from + 1, with_control: false)
+ end
+ @cursor = @cursor_max = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @highest_in_all += @highest_in_this
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @first_line_started_from += @started_from + 1
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ @previous_line_index = nil
+ end
+
+ def just_move_cursor
+ prompt, prompt_width, prompt_list = check_multiline_prompt(@buffer_of_lines)
+ move_cursor_up(@started_from)
+ new_first_line_started_from =
+ if @line_index.zero?
+ 0
+ else
+ calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ first_line_diff = new_first_line_started_from - @first_line_started_from
+ new_cursor, new_cursor_max, new_started_from, new_byte_pointer = calculate_nearest_cursor(@buffer_of_lines[@line_index], @cursor, @started_from, @byte_pointer, false)
+ new_started_from = calculate_height_by_width(prompt_width + new_cursor) - 1
+ calculate_scroll_partial_screen(@highest_in_all, new_first_line_started_from + new_started_from)
+ @previous_line_index = nil
+ if @rerender_all
+ @line = @buffer_of_lines[@line_index]
+ rerender_all_lines
+ @rerender_all = false
+ true
+ else
+ @line = @buffer_of_lines[@line_index]
+ @first_line_started_from = new_first_line_started_from
+ @started_from = new_started_from
+ @cursor = new_cursor
+ @cursor_max = new_cursor_max
+ @byte_pointer = new_byte_pointer
+ move_cursor_down(first_line_diff + @started_from)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ false
+ end
+ end
+
+ private def rerender_changed_current_line
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ new_lines = whole_lines
+ end
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines)
+ all_height = calculate_height_by_lines(new_lines, prompt_list || prompt)
+ diff = all_height - @highest_in_all
+ move_cursor_down(@highest_in_all - @first_line_started_from - @started_from - 1)
+ if diff > 0
+ scroll_down(diff)
+ move_cursor_up(all_height - 1)
+ elsif diff < 0
+ (-diff).times do
+ Reline::IOGate.move_cursor_column(0)
+ Reline::IOGate.erase_after_cursor
+ move_cursor_up(1)
+ end
+ move_cursor_up(all_height - 1)
+ else
+ move_cursor_up(all_height - 1)
+ end
+ @highest_in_all = all_height
+ back = render_whole_lines(new_lines, prompt_list || prompt, prompt_width)
+ move_cursor_up(back)
+ if @previous_line_index
+ @buffer_of_lines[@previous_line_index] = @line
+ @line = @buffer_of_lines[@line_index]
+ end
+ @first_line_started_from =
+ if @line_index.zero?
+ 0
+ else
+ calculate_height_by_lines(@buffer_of_lines[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ if @prompt_proc
+ prompt = prompt_list[@line_index]
+ prompt_width = calculate_width(prompt, true)
+ end
+ move_cursor_down(@first_line_started_from)
+ calculate_nearest_cursor
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ move_cursor_down(@started_from)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ end
+
+ private def rerender_all_lines
+ move_cursor_up(@first_line_started_from + @started_from)
+ Reline::IOGate.move_cursor_column(0)
+ back = 0
+ new_buffer = whole_lines
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer)
+ new_buffer.each_with_index do |line, index|
+ prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
+ width = prompt_width + calculate_width(line)
+ height = calculate_height_by_width(width)
+ back += height
+ end
+ old_highest_in_all = @highest_in_all
+ if @line_index.zero?
+ new_first_line_started_from = 0
+ else
+ new_first_line_started_from = calculate_height_by_lines(new_buffer[0..(@line_index - 1)], prompt_list || prompt)
+ end
+ new_started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ calculate_scroll_partial_screen(back, new_first_line_started_from + new_started_from)
+ if @scroll_partial_screen
+ move_cursor_up(@first_line_started_from + @started_from)
+ scroll_down(@screen_height - 1)
+ move_cursor_up(@screen_height)
+ Reline::IOGate.move_cursor_column(0)
+ elsif back > old_highest_in_all
+ scroll_down(back - 1)
+ move_cursor_up(back - 1)
+ elsif back < old_highest_in_all
+ scroll_down(back)
+ Reline::IOGate.erase_after_cursor
+ (old_highest_in_all - back - 1).times do
+ scroll_down(1)
+ Reline::IOGate.erase_after_cursor
+ end
+ move_cursor_up(old_highest_in_all - 1)
+ end
+ render_whole_lines(new_buffer, prompt_list || prompt, prompt_width)
+ if @prompt_proc
+ prompt = prompt_list[@line_index]
+ prompt_width = calculate_width(prompt, true)
+ end
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
+ @highest_in_all = back
+ @first_line_started_from = new_first_line_started_from
+ @started_from = new_started_from
+ if @scroll_partial_screen
+ Reline::IOGate.move_cursor_up(@screen_height - (@first_line_started_from + @started_from - @scroll_partial_screen) - 1)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ else
+ move_cursor_down(@first_line_started_from + @started_from - back + 1)
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
+ end
+ end
+
+ private def render_whole_lines(lines, prompt, prompt_width)
+ rendered_height = 0
+ modify_lines(lines).each_with_index do |line, index|
+ if prompt.is_a?(Array)
+ line_prompt = prompt[index]
+ prompt_width = calculate_width(line_prompt, true)
+ else
+ line_prompt = prompt
+ end
+ height = render_partial(line_prompt, prompt_width, line, rendered_height, with_control: false)
+ if index < (lines.size - 1)
+ if @scroll_partial_screen
+ if (@scroll_partial_screen - height) < rendered_height and (@scroll_partial_screen + @screen_height - 1) >= (rendered_height + height)
+ move_cursor_down(1)
+ end
+ else
+ scroll_down(1)
+ end
+ rendered_height += height
+ else
+ rendered_height += height - 1
+ end
+ end
+ rendered_height
+ end
+
+ private def render_partial(prompt, prompt_width, line_to_render, this_started_from, with_control: true)
+ visual_lines, height = split_by_width(line_to_render.nil? ? prompt : prompt + line_to_render, @screen_size.last)
+ cursor_up_from_last_line = 0
+ if @scroll_partial_screen
+ last_visual_line = this_started_from + (height - 1)
+ last_screen_line = @scroll_partial_screen + (@screen_height - 1)
+ if (@scroll_partial_screen - this_started_from) >= height
+ # Render nothing because this line is before the screen.
+ visual_lines = []
+ elsif this_started_from > last_screen_line
+ # Render nothing because this line is after the screen.
+ visual_lines = []
+ else
+ deleted_lines_before_screen = []
+ if @scroll_partial_screen > this_started_from and last_visual_line >= @scroll_partial_screen
+ # A part of visual lines are before the screen.
+ deleted_lines_before_screen = visual_lines.shift((@scroll_partial_screen - this_started_from) * 2)
+ deleted_lines_before_screen.compact!
+ end
+ if this_started_from <= last_screen_line and last_screen_line < last_visual_line
+ # A part of visual lines are after the screen.
+ visual_lines.pop((last_visual_line - last_screen_line) * 2)
+ end
+ move_cursor_up(deleted_lines_before_screen.size - @started_from)
+ cursor_up_from_last_line = @started_from - deleted_lines_before_screen.size
+ end
+ end
+ if with_control
+ if height > @highest_in_this
+ diff = height - @highest_in_this
+ scroll_down(diff)
+ @highest_in_all += diff
+ @highest_in_this = height
+ move_cursor_up(diff)
+ elsif height < @highest_in_this
+ diff = @highest_in_this - height
+ @highest_in_all -= diff
+ @highest_in_this = height
+ end
+ move_cursor_up(@started_from)
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
+ cursor_up_from_last_line = height - 1 - @started_from
+ end
+ if Reline::Unicode::CSI_REGEXP.match?(prompt + line_to_render)
+ @output.write "\e[0m" # clear character decorations
+ end
+ visual_lines.each_with_index do |line, index|
+ Reline::IOGate.move_cursor_column(0)
+ if line.nil?
+ if calculate_width(visual_lines[index - 1], true) == Reline::IOGate.get_screen_size.last
+ # reaches the end of line
+ if Reline::IOGate.win? and Reline::IOGate.win_legacy_console?
+ # A newline is automatically inserted if a character is rendered at
+ # eol on command prompt.
+ else
+ # When the cursor is at the end of the line and erases characters
+ # after the cursor, some terminals delete the character at the
+ # cursor position.
+ move_cursor_down(1)
+ Reline::IOGate.move_cursor_column(0)
+ end
else
- colored_content + scrollbar_sgr + ' ' * @block_elem_width
+ Reline::IOGate.erase_after_cursor
+ move_cursor_down(1)
+ Reline::IOGate.move_cursor_column(0)
end
+ next
+ end
+ @output.write line
+ if Reline::IOGate.win? and Reline::IOGate.win_legacy_console? and calculate_width(line, true) == Reline::IOGate.get_screen_size.last
+ # A newline is automatically inserted if a character is rendered at eol on command prompt.
+ @rest_height -= 1 if @rest_height > 0
+ end
+ @output.flush
+ if @first_prompt
+ @first_prompt = false
+ @pre_input_hook&.call
+ end
+ end
+ unless visual_lines.empty?
+ Reline::IOGate.erase_after_cursor
+ Reline::IOGate.move_cursor_column(0)
+ end
+ if with_control
+ # Just after rendring, so the cursor is on the last line.
+ if finished?
+ Reline::IOGate.move_cursor_column(0)
else
- colored_content
+ # Moves up from bottom of lines to the cursor position.
+ move_cursor_up(cursor_up_from_last_line)
+ # This logic is buggy if a fullwidth char is wrapped because there is only one halfwidth at end of a line.
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
end
end
+ height
end
- private def modify_lines(before, complete)
- if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: complete)
+ private def modify_lines(before)
+ return before if before.nil? || before.empty? || simplified_rendering?
+
+ if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: finished?)
after.lines("\n").map { |l| l.chomp('') }
else
- before.map { |l| Reline::Unicode.escape_for_print(l) }
+ before
+ end
+ end
+
+ private def show_menu
+ scroll_down(@highest_in_all - @first_line_started_from)
+ @rerender_all = true
+ @menu_info.list.sort!.each do |item|
+ Reline::IOGate.move_cursor_column(0)
+ @output.write item
+ @output.flush
+ scroll_down(1)
+ end
+ scroll_down(@highest_in_all - 1)
+ move_cursor_up(@highest_in_all - 1 - @first_line_started_from)
+ end
+
+ private def clear_screen_buffer(prompt, prompt_list, prompt_width)
+ Reline::IOGate.clear_screen
+ back = 0
+ modify_lines(whole_lines).each_with_index do |line, index|
+ if @prompt_proc
+ pr = prompt_list[index]
+ height = render_partial(pr, calculate_width(pr), line, back, with_control: false)
+ else
+ height = render_partial(prompt, prompt_width, line, back, with_control: false)
+ end
+ if index < (@buffer_of_lines.size - 1)
+ move_cursor_down(1)
+ back += height
+ end
end
+ move_cursor_up(back)
+ move_cursor_down(@first_line_started_from + @started_from)
+ @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
+ Reline::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)
end
def editing_mode
@config.editing_mode
end
- private def menu(_target, list)
- @menu_info = MenuInfo.new(list)
+ private def menu(target, list)
+ @menu_info = MenuInfo.new(target, list)
end
private def complete_internal_proc(list, is_menu)
@@ -835,7 +1315,7 @@ class Reline::LineEditor
item_mbchars = item.grapheme_clusters
end
size = [memo_mbchars.size, item_mbchars.size].min
- result = +''
+ result = ''
size.times do |i|
if @config.completion_ignore_case
if memo_mbchars[i].casecmp?(item_mbchars[i])
@@ -856,9 +1336,9 @@ class Reline::LineEditor
[target, preposing, completed, postposing]
end
- private def perform_completion(list, just_show_list)
+ private def complete(list, just_show_list = false)
case @completion_state
- when CompletionState::NORMAL
+ when CompletionState::NORMAL, CompletionState::JOURNEY
@completion_state = CompletionState::COMPLETION
when CompletionState::PERFECT_MATCH
@dig_perfect_match_proc&.(@perfect_matched)
@@ -885,80 +1365,100 @@ class Reline::LineEditor
@completion_state = CompletionState::PERFECT_MATCH
else
@completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
- perform_completion(list, true) if @config.show_all_if_ambiguous
end
@perfect_matched = completed
else
@completion_state = CompletionState::MENU
- perform_completion(list, true) if @config.show_all_if_ambiguous
end
if not just_show_list and target < completed
- @buffer_of_lines[@line_index] = (preposing + completed + completion_append_character.to_s + postposing).split("\n")[@line_index] || String.new(encoding: @encoding)
- line_to_pointer = (preposing + completed + completion_append_character.to_s).split("\n")[@line_index] || String.new(encoding: @encoding)
+ @line = preposing + completed + completion_append_character.to_s + postposing
+ line_to_pointer = preposing + completed + completion_append_character.to_s
+ @cursor_max = calculate_width(@line)
+ @cursor = calculate_width(line_to_pointer)
@byte_pointer = line_to_pointer.bytesize
end
end
end
- def dialog_proc_scope_completion_journey_data
- return nil unless @completion_journey_state
- line_index = @completion_journey_state.line_index
- pre_lines = @buffer_of_lines[0...line_index].map { |line| line + "\n" }
- post_lines = @buffer_of_lines[(line_index + 1)..-1].map { |line| line + "\n" }
- DialogProcScope::CompletionJourneyData.new(
- pre_lines.join + @completion_journey_state.pre,
- @completion_journey_state.post + post_lines.join,
- @completion_journey_state.list,
- @completion_journey_state.pointer
- )
- end
-
- private def move_completed_list(direction)
- @completion_journey_state ||= retrieve_completion_journey_state
- return false unless @completion_journey_state
-
- if (delta = { up: -1, down: +1 }[direction])
- @completion_journey_state.pointer = (@completion_journey_state.pointer + delta) % @completion_journey_state.list.size
+ private def move_completed_list(list, direction)
+ case @completion_state
+ when CompletionState::NORMAL, CompletionState::COMPLETION,
+ CompletionState::MENU, CompletionState::MENU_WITH_PERFECT_MATCH
+ @completion_state = CompletionState::JOURNEY
+ result = retrieve_completion_block
+ return if result.nil?
+ preposing, target, postposing = result
+ @completion_journey_data = CompletionJourneyData.new(
+ preposing, postposing,
+ [target] + list.select{ |item| item.start_with?(target) }, 0)
+ if @completion_journey_data.list.size == 1
+ @completion_journey_data.pointer = 0
+ else
+ case direction
+ when :up
+ @completion_journey_data.pointer = @completion_journey_data.list.size - 1
+ when :down
+ @completion_journey_data.pointer = 1
+ end
+ end
+ @completion_state = CompletionState::JOURNEY
+ else
+ case direction
+ when :up
+ @completion_journey_data.pointer -= 1
+ if @completion_journey_data.pointer < 0
+ @completion_journey_data.pointer = @completion_journey_data.list.size - 1
+ end
+ when :down
+ @completion_journey_data.pointer += 1
+ if @completion_journey_data.pointer >= @completion_journey_data.list.size
+ @completion_journey_data.pointer = 0
+ end
+ end
end
- completed = @completion_journey_state.list[@completion_journey_state.pointer]
- set_current_line(@completion_journey_state.pre + completed + @completion_journey_state.post, @completion_journey_state.pre.bytesize + completed.bytesize)
- true
- end
-
- private def retrieve_completion_journey_state
- preposing, target, postposing = retrieve_completion_block
- list = call_completion_proc
- return unless list.is_a?(Array)
-
- candidates = list.select{ |item| item.start_with?(target) }
- return if candidates.empty?
-
- pre = preposing.split("\n", -1).last || ''
- post = postposing.split("\n", -1).first || ''
- CompletionJourneyState.new(
- @line_index, pre, target, post, [target] + candidates, 0
- )
+ completed = @completion_journey_data.list[@completion_journey_data.pointer]
+ new_line = (@completion_journey_data.preposing + completed + @completion_journey_data.postposing).split("\n")[@line_index]
+ @line = new_line.nil? ? String.new(encoding: @encoding) : new_line
+ line_to_pointer = (@completion_journey_data.preposing + completed).split("\n").last
+ line_to_pointer = String.new(encoding: @encoding) if line_to_pointer.nil?
+ @cursor_max = calculate_width(@line)
+ @cursor = calculate_width(line_to_pointer)
+ @byte_pointer = line_to_pointer.bytesize
end
private def run_for_operators(key, method_symbol, &block)
- if @vi_waiting_operator
+ if @waiting_operator_proc
if VI_MOTIONS.include?(method_symbol)
- old_byte_pointer = @byte_pointer
- @vi_arg = (@vi_arg || 1) * @vi_waiting_operator_arg
+ old_cursor, old_byte_pointer = @cursor, @byte_pointer
+ @vi_arg = @waiting_operator_vi_arg if @waiting_operator_vi_arg&.> 1
block.(true)
unless @waiting_proc
- byte_pointer_diff = @byte_pointer - old_byte_pointer
- @byte_pointer = old_byte_pointer
- method_obj = method(@vi_waiting_operator)
- wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
- cleanup_waiting
+ cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer
+ @cursor, @byte_pointer = old_cursor, old_byte_pointer
+ @waiting_operator_proc.(cursor_diff, byte_pointer_diff)
+ else
+ old_waiting_proc = @waiting_proc
+ old_waiting_operator_proc = @waiting_operator_proc
+ current_waiting_operator_proc = @waiting_operator_proc
+ @waiting_proc = proc { |k|
+ old_cursor, old_byte_pointer = @cursor, @byte_pointer
+ old_waiting_proc.(k)
+ cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer
+ @cursor, @byte_pointer = old_cursor, old_byte_pointer
+ current_waiting_operator_proc.(cursor_diff, byte_pointer_diff)
+ @waiting_operator_proc = old_waiting_operator_proc
+ }
end
else
# Ignores operator when not motion is given.
block.(false)
- cleanup_waiting
end
- @vi_arg = nil
+ @waiting_operator_proc = nil
+ @waiting_operator_vi_arg = nil
+ if @vi_arg
+ @rerender_all = true
+ @vi_arg = nil
+ end
else
block.(false)
end
@@ -975,7 +1475,7 @@ class Reline::LineEditor
end
def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
- if @config.editing_mode_is?(:emacs, :vi_insert) and @vi_waiting_operator.nil?
+ if @config.editing_mode_is?(:emacs, :vi_insert) and @waiting_proc.nil? and @waiting_operator_proc.nil?
not_insertion = method_symbol != :ed_insert
process_insert(force: not_insertion)
end
@@ -994,33 +1494,11 @@ class Reline::LineEditor
end
end
- private def cleanup_waiting
- @waiting_proc = nil
- @vi_waiting_operator = nil
- @vi_waiting_operator_arg = nil
- @searching_prompt = nil
- @drop_terminate_spaces = false
- end
-
private def process_key(key, method_symbol)
- if key.is_a?(Symbol)
- cleanup_waiting
- elsif @waiting_proc
- old_byte_pointer = @byte_pointer
- @waiting_proc.call(key)
- if @vi_waiting_operator
- byte_pointer_diff = @byte_pointer - old_byte_pointer
- @byte_pointer = old_byte_pointer
- method_obj = method(@vi_waiting_operator)
- wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
- cleanup_waiting
- end
- @kill_ring.process
- return
- end
-
if method_symbol and respond_to?(method_symbol, true)
method_obj = method(method_symbol)
+ else
+ method_obj = nil
end
if method_symbol and key.is_a?(Symbol)
if @vi_arg and argumentable?(method_obj)
@@ -1032,6 +1510,7 @@ class Reline::LineEditor
end
@kill_ring.process
if @vi_arg
+ @rerender_al = true
@vi_arg = nil
end
elsif @vi_arg
@@ -1042,6 +1521,8 @@ class Reline::LineEditor
run_for_operators(key, method_symbol) do |with_operator|
wrap_method_call(method_symbol, method_obj, key, with_operator)
end
+ elsif @waiting_proc
+ @waiting_proc.(key)
elsif method_obj
wrap_method_call(method_symbol, method_obj, key)
else
@@ -1049,9 +1530,13 @@ class Reline::LineEditor
end
@kill_ring.process
if @vi_arg
+ @rerender_all = true
@vi_arg = nil
end
end
+ elsif @waiting_proc
+ @waiting_proc.(key)
+ @kill_ring.process
elsif method_obj
if method_symbol == :ed_argument_digit
wrap_method_call(method_symbol, method_obj, key)
@@ -1067,6 +1552,11 @@ class Reline::LineEditor
end
private def normal_char(key)
+ method_symbol = method_obj = nil
+ if key.combined_char.is_a?(Symbol)
+ process_key(key.combined_char, key.combined_char)
+ return
+ end
@multibyte_buffer << key.combined_char
if @multibyte_buffer.size > 1
if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding?
@@ -1080,107 +1570,97 @@ class Reline::LineEditor
return if key.char >= 128 # maybe, first byte of multi byte
method_symbol = @config.editing_mode.get_method(key.combined_char)
if key.with_meta and method_symbol == :ed_unassigned
- if @config.editing_mode_is?(:vi_command, :vi_insert)
- # split ESC + key in vi mode
- method_symbol = @config.editing_mode.get_method("\e".ord)
- process_key("\e".ord, method_symbol)
- method_symbol = @config.editing_mode.get_method(key.char)
- process_key(key.char, method_symbol)
- end
+ # split ESC + key
+ method_symbol = @config.editing_mode.get_method("\e".ord)
+ process_key("\e".ord, method_symbol)
+ method_symbol = @config.editing_mode.get_method(key.char)
+ process_key(key.char, method_symbol)
else
process_key(key.combined_char, method_symbol)
end
@multibyte_buffer.clear
end
- if @config.editing_mode_is?(:vi_command) and @byte_pointer > 0 and @byte_pointer == current_line.bytesize
- byte_size = Reline::Unicode.get_prev_mbchar_size(@buffer_of_lines[@line_index], @byte_pointer)
+ if @config.editing_mode_is?(:vi_command) and @cursor > 0 and @cursor == @cursor_max
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
@byte_pointer -= byte_size
- end
- end
-
- def update(key)
- modified = input_key(key)
- unless @in_pasting
- scroll_into_view
- @just_cursor_moving = !modified
- update_dialogs(key)
- @just_cursor_moving = false
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
end
end
def input_key(key)
- save_old_buffer
+ @last_key = key
@config.reset_oneshot_key_bindings
@dialogs.each do |dialog|
if key.char.instance_of?(Symbol) and key.char == dialog.name
return
end
end
+ @just_cursor_moving = nil
if key.char.nil?
- process_insert(force: true)
if @first_char
- @eof = true
+ @line = nil
end
finish
return
end
+ old_line = @line.dup
@first_char = false
- @completion_occurs = false
-
- if key.char.is_a?(Symbol)
+ completion_occurs = false
+ if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
+ unless @config.disable_completion
+ result = call_completion_proc
+ if result.is_a?(Array)
+ completion_occurs = true
+ process_insert
+ if @config.autocompletion
+ move_completed_list(result, :down)
+ else
+ complete(result)
+ end
+ end
+ end
+ elsif @config.editing_mode_is?(:emacs, :vi_insert) and key.char == :completion_journey_up
+ if not @config.disable_completion and @config.autocompletion
+ result = call_completion_proc
+ if result.is_a?(Array)
+ completion_occurs = true
+ process_insert
+ move_completed_list(result, :up)
+ end
+ end
+ elsif not @config.disable_completion and @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
+ unless @config.disable_completion
+ result = call_completion_proc
+ if result.is_a?(Array)
+ completion_occurs = true
+ process_insert
+ move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
+ end
+ end
+ elsif Symbol === key.char and respond_to?(key.char, true)
process_key(key.char, key.char)
else
normal_char(key)
end
- unless @completion_occurs
+ unless completion_occurs
@completion_state = CompletionState::NORMAL
- @completion_journey_state = nil
+ @completion_journey_data = nil
end
-
- push_past_lines unless @undoing
- @undoing = false
-
- if @in_pasting
- clear_dialogs
- return
- end
-
- modified = @old_buffer_of_lines != @buffer_of_lines
- if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
- # Auto complete starts only when edited
- process_insert(force: true)
- @completion_journey_state = retrieve_completion_journey_state
- end
- modified
- end
-
- def save_old_buffer
- @old_buffer_of_lines = @buffer_of_lines.dup
- @old_byte_pointer = @byte_pointer.dup
- @old_line_index = @line_index.dup
- end
-
- def push_past_lines
- if @old_buffer_of_lines != @buffer_of_lines
- @past_lines.push([@old_buffer_of_lines, @old_byte_pointer, @old_line_index])
- end
- trim_past_lines
- end
-
- MAX_PAST_LINES = 100
- def trim_past_lines
- if @past_lines.size > MAX_PAST_LINES
- @past_lines.shift
- end
- end
-
- def scroll_into_view
- _wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
- if wrapped_cursor_y < screen_scroll_top
- @scroll_partial_screen = wrapped_cursor_y
+ if not @in_pasting and @just_cursor_moving.nil?
+ if @previous_line_index and @buffer_of_lines[@previous_line_index] == @line
+ @just_cursor_moving = true
+ elsif @previous_line_index.nil? and @buffer_of_lines[@line_index] == @line and old_line == @line
+ @just_cursor_moving = true
+ else
+ @just_cursor_moving = false
+ end
+ else
+ @just_cursor_moving = false
end
- if wrapped_cursor_y >= screen_scroll_top + screen_height
- @scroll_partial_screen = wrapped_cursor_y - screen_height + 1
+ if @is_multiline and @auto_indent_proc and not simplified_rendering?
+ process_auto_indent
end
end
@@ -1214,52 +1694,46 @@ class Reline::LineEditor
result
end
- private def process_auto_indent(line_index = @line_index, cursor_dependent: true, add_newline: false)
- return if @in_pasting
- return unless @auto_indent_proc
+ private def process_auto_indent
+ return if not @check_new_auto_indent and @previous_line_index # move cursor up or down
+ if @check_new_auto_indent and @previous_line_index and @previous_line_index > 0 and @line_index > @previous_line_index
+ # Fix indent of a line when a newline is inserted to the next
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
+ new_indent = @auto_indent_proc.(new_lines[0..-3].push(''), @line_index - 1, 0, true)
+ md = @line.match(/\A */)
+ prev_indent = md[0].count(' ')
+ @line = ' ' * new_indent + @line.lstrip
- line = @buffer_of_lines[line_index]
- byte_pointer = cursor_dependent && @line_index == line_index ? @byte_pointer : line.bytesize
- new_indent = @auto_indent_proc.(@buffer_of_lines.take(line_index + 1).push(''), line_index, byte_pointer, add_newline)
- return unless new_indent
-
- new_line = ' ' * new_indent + line.lstrip
- @buffer_of_lines[line_index] = new_line
- if @line_index == line_index
- indent_diff = new_line.bytesize - line.bytesize
- @byte_pointer = [@byte_pointer + indent_diff, 0].max
- end
- end
-
- def line()
- @buffer_of_lines.join("\n") unless eof?
- end
-
- def current_line
- @buffer_of_lines[@line_index]
- end
-
- def set_current_line(line, byte_pointer = nil)
- cursor = current_byte_pointer_cursor
- @buffer_of_lines[@line_index] = line
- if byte_pointer
- @byte_pointer = byte_pointer
- else
- calculate_nearest_cursor(cursor)
+ new_indent = nil
+ result = @auto_indent_proc.(new_lines[0..-2], @line_index - 1, (new_lines[-2].size + 1), false)
+ if result
+ new_indent = result
+ end
+ if new_indent&.>= 0
+ @line = ' ' * new_indent + @line.lstrip
+ end
end
- process_auto_indent
- end
-
- def set_current_lines(lines, byte_pointer = nil, line_index = 0)
- cursor = current_byte_pointer_cursor
- @buffer_of_lines = lines
- @line_index = line_index
- if byte_pointer
- @byte_pointer = byte_pointer
+ if @previous_line_index
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
else
- calculate_nearest_cursor(cursor)
+ new_lines = whole_lines
+ end
+ new_indent = @auto_indent_proc.(new_lines, @line_index, @byte_pointer, @check_new_auto_indent)
+ new_indent = @cursor_max if new_indent&.> @cursor_max
+ if new_indent&.>= 0
+ md = new_lines[@line_index].match(/\A */)
+ prev_indent = md[0].count(' ')
+ if @check_new_auto_indent
+ @buffer_of_lines[@line_index] = ' ' * new_indent + @buffer_of_lines[@line_index].lstrip
+ @cursor = new_indent
+ @byte_pointer = new_indent
+ else
+ @line = ' ' * new_indent + @line.lstrip
+ @cursor += new_indent - prev_indent
+ @byte_pointer += new_indent - prev_indent
+ end
end
- process_auto_indent
+ @check_new_auto_indent = false
end
def retrieve_completion_block(set_completion_quote_character = false)
@@ -1273,7 +1747,7 @@ class Reline::LineEditor
else
quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/
end
- before = current_line.byteslice(0, @byte_pointer)
+ before = @line.byteslice(0, @byte_pointer)
rest = nil
break_pointer = nil
quote = nil
@@ -1281,7 +1755,7 @@ class Reline::LineEditor
escaped_quote = nil
i = 0
while i < @byte_pointer do
- slice = current_line.byteslice(i, @byte_pointer - i)
+ slice = @line.byteslice(i, @byte_pointer - i)
unless slice.valid_encoding?
i += 1
next
@@ -1303,15 +1777,15 @@ class Reline::LineEditor
elsif word_break_regexp and not quote and slice =~ word_break_regexp
rest = $'
i += 1
- before = current_line.byteslice(i, @byte_pointer - i)
+ before = @line.byteslice(i, @byte_pointer - i)
break_pointer = i
else
i += 1
end
end
- postposing = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer)
+ postposing = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
if rest
- preposing = current_line.byteslice(0, break_pointer)
+ preposing = @line.byteslice(0, break_pointer)
target = rest
if set_completion_quote_character and quote
Reline.core.instance_variable_set(:@completion_quote_character, quote)
@@ -1322,93 +1796,133 @@ class Reline::LineEditor
else
preposing = ''
if break_pointer
- preposing = current_line.byteslice(0, break_pointer)
+ preposing = @line.byteslice(0, break_pointer)
else
preposing = ''
end
target = before
end
- lines = whole_lines
- if @line_index > 0
- preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
- end
- if (lines.size - 1) > @line_index
- postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
+ if @is_multiline
+ if @previous_line_index
+ lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ lines = whole_lines
+ end
+ if @line_index > 0
+ preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
+ end
+ if (lines.size - 1) > @line_index
+ postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
+ end
end
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
end
def confirm_multiline_termination
temp_buffer = @buffer_of_lines.dup
+ if @previous_line_index and @line_index == (@buffer_of_lines.size - 1)
+ temp_buffer[@previous_line_index] = @line
+ else
+ temp_buffer[@line_index] = @line
+ end
@confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
end
- def insert_pasted_text(text)
- save_old_buffer
- pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
- post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
- lines = (pre + text.gsub(/\r\n?/, "\n") + post).split("\n", -1)
- lines << '' if lines.empty?
- @buffer_of_lines[@line_index, 1] = lines
- @line_index += lines.size - 1
- @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
- push_past_lines
- end
-
def insert_text(text)
- if @buffer_of_lines[@line_index].bytesize == @byte_pointer
- @buffer_of_lines[@line_index] += text
+ width = calculate_width(text)
+ if @cursor == @cursor_max
+ @line += text
else
- @buffer_of_lines[@line_index] = byteinsert(@buffer_of_lines[@line_index], @byte_pointer, text)
+ @line = byteinsert(@line, @byte_pointer, text)
end
@byte_pointer += text.bytesize
- process_auto_indent
+ @cursor += width
+ @cursor_max += width
end
def delete_text(start = nil, length = nil)
if start.nil? and length.nil?
- if @buffer_of_lines.size == 1
- @buffer_of_lines[@line_index] = ''
- @byte_pointer = 0
- elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
- @buffer_of_lines.pop
- @line_index -= 1
- @byte_pointer = 0
- elsif @line_index < (@buffer_of_lines.size - 1)
- @buffer_of_lines.delete_at(@line_index)
+ if @is_multiline
+ if @buffer_of_lines.size == 1
+ @line&.clear
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = 0
+ elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
+ @buffer_of_lines.pop
+ @line_index -= 1
+ @line = @buffer_of_lines[@line_index]
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = calculate_width(@line)
+ elsif @line_index < (@buffer_of_lines.size - 1)
+ @buffer_of_lines.delete_at(@line_index)
+ @line = @buffer_of_lines[@line_index]
+ @byte_pointer = 0
+ @cursor = 0
+ @cursor_max = calculate_width(@line)
+ end
+ else
+ @line&.clear
@byte_pointer = 0
+ @cursor = 0
+ @cursor_max = 0
end
elsif not start.nil? and not length.nil?
- if current_line
- before = current_line.byteslice(0, start)
- after = current_line.byteslice(start + length, current_line.bytesize)
- set_current_line(before + after)
+ if @line
+ before = @line.byteslice(0, start)
+ after = @line.byteslice(start + length, @line.bytesize)
+ @line = before + after
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
end
elsif start.is_a?(Range)
range = start
first = range.first
last = range.last
- last = current_line.bytesize - 1 if last > current_line.bytesize
- last += current_line.bytesize if last < 0
- first += current_line.bytesize if first < 0
+ last = @line.bytesize - 1 if last > @line.bytesize
+ last += @line.bytesize if last < 0
+ first += @line.bytesize if first < 0
range = range.exclude_end? ? first...last : first..last
- line = current_line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(@encoding)
- set_current_line(line)
+ @line = @line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(@encoding)
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
else
- set_current_line(current_line.byteslice(0, start))
+ @line = @line.byteslice(0, start)
+ @byte_pointer = @line.bytesize if @byte_pointer > @line.bytesize
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
end
end
def byte_pointer=(val)
@byte_pointer = val
+ str = @line.byteslice(0, @byte_pointer)
+ @cursor = calculate_width(str)
+ @cursor_max = calculate_width(@line)
end
- def whole_lines
- @buffer_of_lines.dup
+ def whole_lines(index: @line_index, line: @line)
+ temp_lines = @buffer_of_lines.dup
+ temp_lines[index] = line
+ temp_lines
end
def whole_buffer
- whole_lines.join("\n")
+ if @buffer_of_lines.size == 1 and @line.nil?
+ nil
+ else
+ if @previous_line_index
+ whole_lines(index: @previous_line_index, line: @line).join("\n")
+ else
+ whole_lines.join("\n")
+ end
+ end
end
def finished?
@@ -1417,6 +1931,7 @@ class Reline::LineEditor
def finish
@finished = true
+ @rerender_all = true
@config.reset
end
@@ -1438,65 +1953,40 @@ class Reline::LineEditor
end
private def key_delete(key)
- if @config.editing_mode_is?(:vi_insert)
+ if @config.editing_mode_is?(:vi_insert, :emacs)
ed_delete_next_char(key)
- elsif @config.editing_mode_is?(:emacs)
- em_delete(key)
end
end
private def key_newline(key)
if @is_multiline
- next_line = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer)
- cursor_line = current_line.byteslice(0, @byte_pointer)
- insert_new_line(cursor_line, next_line)
- end
- end
-
- private def complete(_key)
- return if @config.disable_completion
-
- process_insert(force: true)
- if @config.autocompletion
- @completion_state = CompletionState::NORMAL
- @completion_occurs = move_completed_list(:down)
- else
- @completion_journey_state = nil
- result = call_completion_proc
- if result.is_a?(Array)
- @completion_occurs = true
- perform_completion(result, false)
+ if (@buffer_of_lines.size - 1) == @line_index and @line.bytesize == @byte_pointer
+ @add_newline_to_end_of_buffer = true
end
+ next_line = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
+ cursor_line = @line.byteslice(0, @byte_pointer)
+ insert_new_line(cursor_line, next_line)
+ @cursor = 0
+ @check_new_auto_indent = true unless @in_pasting
end
end
- private def completion_journey_move(direction)
- return if @config.disable_completion
-
- process_insert(force: true)
- @completion_state = CompletionState::NORMAL
- @completion_occurs = move_completed_list(direction)
- end
-
- private def menu_complete(_key)
- completion_journey_move(:down)
- end
-
- private def menu_complete_backward(_key)
- completion_journey_move(:up)
- end
-
- private def completion_journey_up(_key)
- completion_journey_move(:up) if @config.autocompletion
- end
-
# Editline:: +ed-unassigned+ This editor command always results in an error.
# GNU Readline:: There is no corresponding macro.
private def ed_unassigned(key) end # do nothing
private def process_insert(force: false)
return if @continuous_insertion_buffer.empty? or (@in_pasting and not force)
- insert_text(@continuous_insertion_buffer)
+ width = Reline::Unicode.calculate_width(@continuous_insertion_buffer)
+ bytesize = @continuous_insertion_buffer.bytesize
+ if @cursor == @cursor_max
+ @line += @continuous_insertion_buffer
+ else
+ @line = byteinsert(@line, @byte_pointer, @continuous_insertion_buffer)
+ end
+ @byte_pointer += bytesize
+ @cursor += width
+ @cursor_max += width
@continuous_insertion_buffer.clear
end
@@ -1514,6 +2004,9 @@ class Reline::LineEditor
# million.
# GNU Readline:: +self-insert+ (a, b, A, 1, !, …) Insert yourself.
private def ed_insert(key)
+ str = nil
+ width = nil
+ bytesize = nil
if key.instance_of?(String)
begin
key.encode(Encoding::UTF_8)
@@ -1521,6 +2014,7 @@ class Reline::LineEditor
return
end
str = key
+ bytesize = key.bytesize
else
begin
key.chr.encode(Encoding::UTF_8)
@@ -1528,6 +2022,7 @@ class Reline::LineEditor
return
end
str = key.chr
+ bytesize = 1
end
if @in_pasting
@continuous_insertion_buffer << str
@@ -1535,8 +2030,28 @@ class Reline::LineEditor
elsif not @continuous_insertion_buffer.empty?
process_insert
end
-
- insert_text(str)
+ width = Reline::Unicode.get_mbchar_width(str)
+ if @cursor == @cursor_max
+ @line += str
+ else
+ @line = byteinsert(@line, @byte_pointer, str)
+ end
+ last_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer += bytesize
+ last_mbchar = @line.byteslice((@byte_pointer - bytesize - last_byte_size), last_byte_size)
+ combined_char = last_mbchar + str
+ if last_byte_size != 0 and combined_char.grapheme_clusters.size == 1
+ # combined char
+ last_mbchar_width = Reline::Unicode.get_mbchar_width(last_mbchar)
+ combined_char_width = Reline::Unicode.get_mbchar_width(combined_char)
+ if combined_char_width > last_mbchar_width
+ width = combined_char_width - last_mbchar_width
+ else
+ width = 0
+ end
+ end
+ @cursor += width
+ @cursor_max += width
end
alias_method :ed_digit, :ed_insert
alias_method :self_insert, :ed_insert
@@ -1558,11 +2073,18 @@ class Reline::LineEditor
alias_method :quoted_insert, :ed_quoted_insert
private def ed_next_char(key, arg: 1)
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
- if (@byte_pointer < current_line.bytesize)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if (@byte_pointer < @line.bytesize)
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor += width if width
@byte_pointer += byte_size
- elsif @config.editing_mode_is?(:emacs) and @byte_pointer == current_line.bytesize and @line_index < @buffer_of_lines.size - 1
+ elsif @is_multiline and @config.editing_mode_is?(:emacs) and @byte_pointer == @line.bytesize and @line_index < @buffer_of_lines.size - 1
+ next_line = @buffer_of_lines[@line_index + 1]
+ @cursor = 0
@byte_pointer = 0
+ @cursor_max = calculate_width(next_line)
+ @previous_line_index = @line_index
@line_index += 1
end
arg -= 1
@@ -1571,12 +2093,19 @@ class Reline::LineEditor
alias_method :forward_char, :ed_next_char
private def ed_prev_char(key, arg: 1)
- if @byte_pointer > 0
- byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
+ if @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
@byte_pointer -= byte_size
- elsif @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ elsif @is_multiline and @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
+ prev_line = @buffer_of_lines[@line_index - 1]
+ @cursor = calculate_width(prev_line)
+ @byte_pointer = prev_line.bytesize
+ @cursor_max = calculate_width(prev_line)
+ @previous_line_index = @line_index
@line_index -= 1
- @byte_pointer = current_line.bytesize
end
arg -= 1
ed_prev_char(key, arg: arg) if arg > 0
@@ -1584,109 +2113,157 @@ class Reline::LineEditor
alias_method :backward_char, :ed_prev_char
private def vi_first_print(key)
- @byte_pointer, = Reline::Unicode.vi_first_print(current_line)
+ @byte_pointer, @cursor = Reline::Unicode.vi_first_print(@line)
end
private def ed_move_to_beg(key)
- @byte_pointer = 0
+ @byte_pointer = @cursor = 0
end
alias_method :beginning_of_line, :ed_move_to_beg
- alias_method :vi_zero, :ed_move_to_beg
private def ed_move_to_end(key)
- @byte_pointer = current_line.bytesize
+ @byte_pointer = 0
+ @cursor = 0
+ byte_size = 0
+ while @byte_pointer < @line.bytesize
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ if byte_size > 0
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ @cursor += Reline::Unicode.get_mbchar_width(mbchar)
+ end
+ @byte_pointer += byte_size
+ end
end
alias_method :end_of_line, :ed_move_to_end
- private def generate_searcher(search_key)
- search_word = String.new(encoding: @encoding)
- multibyte_buf = String.new(encoding: 'ASCII-8BIT')
- hit_pointer = nil
- lambda do |key|
- search_again = false
- case key
- when "\C-h".ord, "\C-?".ord
- grapheme_clusters = search_word.grapheme_clusters
- if grapheme_clusters.size > 0
- grapheme_clusters.pop
- search_word = grapheme_clusters.join
- end
- when "\C-r".ord, "\C-s".ord
- search_again = true if search_key == key
- search_key = key
- else
- multibyte_buf << key
- if multibyte_buf.dup.force_encoding(@encoding).valid_encoding?
- search_word << multibyte_buf.dup.force_encoding(@encoding)
- multibyte_buf.clear
- end
+ private def generate_searcher
+ Fiber.new do |first_key|
+ prev_search_key = first_key
+ search_word = String.new(encoding: @encoding)
+ multibyte_buf = String.new(encoding: 'ASCII-8BIT')
+ last_hit = nil
+ case first_key
+ when "\C-r".ord
+ prompt_name = 'reverse-i-search'
+ when "\C-s".ord
+ prompt_name = 'i-search'
end
- hit = nil
- if not search_word.empty? and @line_backup_in_history&.include?(search_word)
- hit_pointer = Reline::HISTORY.size
- hit = @line_backup_in_history
- else
- if search_again
- if search_word.empty? and Reline.last_incremental_search
- search_word = Reline.last_incremental_search
+ loop do
+ key = Fiber.yield(search_word)
+ search_again = false
+ case key
+ when -1 # determined
+ Reline.last_incremental_search = search_word
+ break
+ when "\C-h".ord, "\C-?".ord
+ grapheme_clusters = search_word.grapheme_clusters
+ if grapheme_clusters.size > 0
+ grapheme_clusters.pop
+ search_word = grapheme_clusters.join
end
- if @history_pointer
- case search_key
+ when "\C-r".ord, "\C-s".ord
+ search_again = true if prev_search_key == key
+ prev_search_key = key
+ else
+ multibyte_buf << key
+ if multibyte_buf.dup.force_encoding(@encoding).valid_encoding?
+ search_word << multibyte_buf.dup.force_encoding(@encoding)
+ multibyte_buf.clear
+ end
+ end
+ hit = nil
+ if not search_word.empty? and @line_backup_in_history&.include?(search_word)
+ @history_pointer = nil
+ hit = @line_backup_in_history
+ else
+ if search_again
+ if search_word.empty? and Reline.last_incremental_search
+ search_word = Reline.last_incremental_search
+ end
+ if @history_pointer
+ case prev_search_key
+ when "\C-r".ord
+ history_pointer_base = 0
+ history = Reline::HISTORY[0..(@history_pointer - 1)]
+ when "\C-s".ord
+ history_pointer_base = @history_pointer + 1
+ history = Reline::HISTORY[(@history_pointer + 1)..-1]
+ end
+ else
+ history_pointer_base = 0
+ history = Reline::HISTORY
+ end
+ elsif @history_pointer
+ case prev_search_key
when "\C-r".ord
history_pointer_base = 0
- history = Reline::HISTORY[0..(@history_pointer - 1)]
+ history = Reline::HISTORY[0..@history_pointer]
when "\C-s".ord
- history_pointer_base = @history_pointer + 1
- history = Reline::HISTORY[(@history_pointer + 1)..-1]
+ history_pointer_base = @history_pointer
+ history = Reline::HISTORY[@history_pointer..-1]
end
else
history_pointer_base = 0
history = Reline::HISTORY
end
- elsif @history_pointer
- case search_key
+ case prev_search_key
when "\C-r".ord
- history_pointer_base = 0
- history = Reline::HISTORY[0..@history_pointer]
+ hit_index = history.rindex { |item|
+ item.include?(search_word)
+ }
when "\C-s".ord
- history_pointer_base = @history_pointer
- history = Reline::HISTORY[@history_pointer..-1]
+ hit_index = history.index { |item|
+ item.include?(search_word)
+ }
+ end
+ if hit_index
+ @history_pointer = history_pointer_base + hit_index
+ hit = Reline::HISTORY[@history_pointer]
end
- else
- history_pointer_base = 0
- history = Reline::HISTORY
end
- case search_key
+ case prev_search_key
when "\C-r".ord
- hit_index = history.rindex { |item|
- item.include?(search_word)
- }
+ prompt_name = 'reverse-i-search'
when "\C-s".ord
- hit_index = history.index { |item|
- item.include?(search_word)
- }
+ prompt_name = 'i-search'
end
- if hit_index
- hit_pointer = history_pointer_base + hit_index
- hit = Reline::HISTORY[hit_pointer]
+ if hit
+ if @is_multiline
+ @buffer_of_lines = hit.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @byte_pointer = @line.bytesize
+ @cursor = @cursor_max = calculate_width(@line)
+ @rerender_all = true
+ @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
+ else
+ @line = hit
+ @searching_prompt = "(%s)`%s': %s" % [prompt_name, search_word, hit]
+ end
+ last_hit = hit
+ else
+ if @is_multiline
+ @rerender_all = true
+ @searching_prompt = "(failed %s)`%s'" % [prompt_name, search_word]
+ else
+ @searching_prompt = "(failed %s)`%s': %s" % [prompt_name, search_word, last_hit]
+ end
end
end
- case search_key
- when "\C-r".ord
- prompt_name = 'reverse-i-search'
- when "\C-s".ord
- prompt_name = 'i-search'
- end
- prompt_name = "failed #{prompt_name}" unless hit
- [search_word, prompt_name, hit_pointer]
end
end
private def incremental_search_history(key)
unless @history_pointer
- @line_backup_in_history = whole_buffer
+ if @is_multiline
+ @line_backup_in_history = whole_buffer
+ else
+ @line_backup_in_history = @line
+ end
end
- searcher = generate_searcher(key)
+ searcher = generate_searcher
+ searcher.resume(key)
@searching_prompt = "(reverse-i-search)`': "
termination_keys = ["\C-j".ord]
termination_keys.concat(@config.isearch_terminators&.chars&.map(&:ord)) if @config.isearch_terminators
@@ -1698,41 +2275,67 @@ class Reline::LineEditor
else
buffer = @line_backup_in_history
end
- @buffer_of_lines = buffer.split("\n")
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
- @line_index = @buffer_of_lines.size - 1
+ if @is_multiline
+ @buffer_of_lines = buffer.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line = buffer
+ end
@searching_prompt = nil
@waiting_proc = nil
- @byte_pointer = 0
+ @cursor_max = calculate_width(@line)
+ @cursor = @byte_pointer = 0
+ @rerender_all = true
+ @cached_prompt_list = nil
+ searcher.resume(-1)
when "\C-g".ord
- @buffer_of_lines = @line_backup_in_history.split("\n")
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
- @line_index = @buffer_of_lines.size - 1
- move_history(nil, line: :end, cursor: :end, save_buffer: false)
+ if @is_multiline
+ @buffer_of_lines = @line_backup_in_history.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line = @line_backup_in_history
+ end
+ @history_pointer = nil
@searching_prompt = nil
@waiting_proc = nil
- @byte_pointer = 0
+ @line_backup_in_history = nil
+ @cursor_max = calculate_width(@line)
+ @cursor = @byte_pointer = 0
+ @rerender_all = true
else
chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
if chr.match?(/[[:print:]]/) or k == "\C-h".ord or k == "\C-?".ord or k == "\C-r".ord or k == "\C-s".ord
- search_word, prompt_name, hit_pointer = searcher.call(k)
- Reline.last_incremental_search = search_word
- @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
- @searching_prompt += ': ' unless @is_multiline
- move_history(hit_pointer, line: :end, cursor: :end, save_buffer: false) if hit_pointer
+ searcher.resume(k)
else
if @history_pointer
line = Reline::HISTORY[@history_pointer]
else
line = @line_backup_in_history
end
- @line_backup_in_history = whole_buffer
- @buffer_of_lines = line.split("\n")
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
- @line_index = @buffer_of_lines.size - 1
+ if @is_multiline
+ @line_backup_in_history = whole_buffer
+ @buffer_of_lines = line.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line_backup_in_history = @line
+ @line = line
+ end
@searching_prompt = nil
@waiting_proc = nil
- @byte_pointer = 0
+ @cursor_max = calculate_width(@line)
+ @cursor = @byte_pointer = 0
+ @rerender_all = true
+ @cached_prompt_list = nil
+ searcher.resume(-1)
end
end
}
@@ -1748,95 +2351,199 @@ class Reline::LineEditor
end
alias_method :forward_search_history, :vi_search_next
- private def search_history(prefix, pointer_range)
- pointer_range.each do |pointer|
- lines = Reline::HISTORY[pointer].split("\n")
- lines.each_with_index do |line, index|
- return [pointer, index] if line.start_with?(prefix)
- end
- end
- nil
- end
-
private def ed_search_prev_history(key, arg: 1)
- substr = current_line.byteslice(0, @byte_pointer)
- return if @history_pointer == 0
- return if @history_pointer.nil? && substr.empty? && !current_line.empty?
-
- history_range = 0...(@history_pointer || Reline::HISTORY.size)
- h_pointer, line_index = search_history(substr, history_range.reverse_each)
- return unless h_pointer
- move_history(h_pointer, line: line_index || :start, cursor: @byte_pointer)
+ history = nil
+ h_pointer = nil
+ line_no = nil
+ substr = @line.slice(0, @byte_pointer)
+ if @history_pointer.nil?
+ return if not @line.empty? and substr.empty?
+ history = Reline::HISTORY
+ elsif @history_pointer.zero?
+ history = nil
+ h_pointer = nil
+ else
+ history = Reline::HISTORY.slice(0, @history_pointer)
+ end
+ return if history.nil?
+ if @is_multiline
+ h_pointer = history.rindex { |h|
+ h.split("\n").each_with_index { |l, i|
+ if l.start_with?(substr)
+ line_no = i
+ break
+ end
+ }
+ not line_no.nil?
+ }
+ else
+ h_pointer = history.rindex { |l|
+ l.start_with?(substr)
+ }
+ end
+ return if h_pointer.nil?
+ @history_pointer = h_pointer
+ if @is_multiline
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = line_no
+ @line = @buffer_of_lines[@line_index]
+ @rerender_all = true
+ else
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ @cursor_max = calculate_width(@line)
arg -= 1
ed_search_prev_history(key, arg: arg) if arg > 0
end
alias_method :history_search_backward, :ed_search_prev_history
private def ed_search_next_history(key, arg: 1)
- substr = current_line.byteslice(0, @byte_pointer)
- return if @history_pointer.nil?
-
- history_range = @history_pointer + 1...Reline::HISTORY.size
- h_pointer, line_index = search_history(substr, history_range)
- return if h_pointer.nil? and not substr.empty?
-
- move_history(h_pointer, line: line_index || :start, cursor: @byte_pointer)
- arg -= 1
- ed_search_next_history(key, arg: arg) if arg > 0
- end
- alias_method :history_search_forward, :ed_search_next_history
-
- private def move_history(history_pointer, line:, cursor:, save_buffer: true)
- history_pointer ||= Reline::HISTORY.size
- return if history_pointer < 0 || history_pointer > Reline::HISTORY.size
- old_history_pointer = @history_pointer || Reline::HISTORY.size
- if old_history_pointer == Reline::HISTORY.size
- @line_backup_in_history = save_buffer ? whole_buffer : ''
+ substr = @line.slice(0, @byte_pointer)
+ if @history_pointer.nil?
+ return
+ elsif @history_pointer == (Reline::HISTORY.size - 1) and not substr.empty?
+ return
+ end
+ history = Reline::HISTORY.slice((@history_pointer + 1)..-1)
+ h_pointer = nil
+ line_no = nil
+ if @is_multiline
+ h_pointer = history.index { |h|
+ h.split("\n").each_with_index { |l, i|
+ if l.start_with?(substr)
+ line_no = i
+ break
+ end
+ }
+ not line_no.nil?
+ }
else
- Reline::HISTORY[old_history_pointer] = whole_buffer if save_buffer
+ h_pointer = history.index { |l|
+ l.start_with?(substr)
+ }
end
- if history_pointer == Reline::HISTORY.size
- buf = @line_backup_in_history
- @history_pointer = @line_backup_in_history = nil
+ h_pointer += @history_pointer + 1 if h_pointer and @history_pointer
+ return if h_pointer.nil? and not substr.empty?
+ @history_pointer = h_pointer
+ if @is_multiline
+ if @history_pointer.nil? and substr.empty?
+ @buffer_of_lines = []
+ @line_index = 0
+ else
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @line_index = line_no
+ end
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line = @buffer_of_lines[@line_index]
+ @rerender_all = true
else
- buf = Reline::HISTORY[history_pointer]
- @history_pointer = history_pointer
+ if @history_pointer.nil? and substr.empty?
+ @line = ''
+ else
+ @line = Reline::HISTORY[@history_pointer]
+ end
end
- @buffer_of_lines = buf.split("\n")
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
- @line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line
- @byte_pointer = cursor == :start ? 0 : cursor == :end ? current_line.bytesize : cursor
+ @cursor_max = calculate_width(@line)
+ arg -= 1
+ ed_search_next_history(key, arg: arg) if arg > 0
end
+ alias_method :history_search_forward, :ed_search_next_history
private def ed_prev_history(key, arg: 1)
- if @line_index > 0
- cursor = current_byte_pointer_cursor
+ if @is_multiline and @line_index > 0
+ @previous_line_index = @line_index
@line_index -= 1
- calculate_nearest_cursor(cursor)
return
end
- move_history(
- (@history_pointer || Reline::HISTORY.size) - 1,
- line: :end,
- cursor: @config.editing_mode_is?(:vi_command) ? :start : :end,
- )
+ if Reline::HISTORY.empty?
+ return
+ end
+ if @history_pointer.nil?
+ @history_pointer = Reline::HISTORY.size - 1
+ if @is_multiline
+ @line_backup_in_history = whole_buffer
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ @line_backup_in_history = @line
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ elsif @history_pointer.zero?
+ return
+ else
+ if @is_multiline
+ Reline::HISTORY[@history_pointer] = whole_buffer
+ @history_pointer -= 1
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = @buffer_of_lines.size - 1
+ @line = @buffer_of_lines.last
+ @rerender_all = true
+ else
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer -= 1
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ end
+ if @config.editing_mode_is?(:emacs, :vi_insert)
+ @cursor_max = @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ elsif @config.editing_mode_is?(:vi_command)
+ @byte_pointer = @cursor = 0
+ @cursor_max = calculate_width(@line)
+ end
arg -= 1
ed_prev_history(key, arg: arg) if arg > 0
end
alias_method :previous_history, :ed_prev_history
private def ed_next_history(key, arg: 1)
- if @line_index < (@buffer_of_lines.size - 1)
- cursor = current_byte_pointer_cursor
+ if @is_multiline and @line_index < (@buffer_of_lines.size - 1)
+ @previous_line_index = @line_index
@line_index += 1
- calculate_nearest_cursor(cursor)
return
end
- move_history(
- (@history_pointer || Reline::HISTORY.size) + 1,
- line: :start,
- cursor: @config.editing_mode_is?(:vi_command) ? :start : :end,
- )
+ if @history_pointer.nil?
+ return
+ elsif @history_pointer == (Reline::HISTORY.size - 1)
+ if @is_multiline
+ @history_pointer = nil
+ @buffer_of_lines = @line_backup_in_history.split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = 0
+ @line = @buffer_of_lines.first
+ @rerender_all = true
+ else
+ @history_pointer = nil
+ @line = @line_backup_in_history
+ end
+ else
+ if @is_multiline
+ Reline::HISTORY[@history_pointer] = whole_buffer
+ @history_pointer += 1
+ @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = 0
+ @line = @buffer_of_lines.first
+ @rerender_all = true
+ else
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer += 1
+ @line = Reline::HISTORY[@history_pointer]
+ end
+ end
+ @line = '' unless @line
+ if @config.editing_mode_is?(:emacs, :vi_insert)
+ @cursor_max = @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ elsif @config.editing_mode_is?(:vi_command)
+ @byte_pointer = @cursor = 0
+ @cursor_max = calculate_width(@line)
+ end
arg -= 1
ed_next_history(key, arg: arg) if arg > 0
end
@@ -1861,29 +2568,40 @@ class Reline::LineEditor
end
else
# should check confirm_multiline_termination to finish?
+ @previous_line_index = @line_index
@line_index = @buffer_of_lines.size - 1
- @byte_pointer = current_line.bytesize
finish
end
end
else
+ if @history_pointer
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer = nil
+ end
finish
end
end
private def em_delete_prev_char(key, arg: 1)
- arg.times do
- if @byte_pointer == 0 and @line_index > 0
- @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
- @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
- @line_index -= 1
- elsif @byte_pointer > 0
- byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
- line, = byteslice!(current_line, @byte_pointer - byte_size, byte_size)
- set_current_line(line, @byte_pointer - byte_size)
- end
+ if @is_multiline and @cursor == 0 and @line_index > 0
+ @buffer_of_lines[@line_index] = @line
+ @cursor = calculate_width(@buffer_of_lines[@line_index - 1])
+ @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
+ @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
+ @line_index -= 1
+ @line = @buffer_of_lines[@line_index]
+ @cursor_max = calculate_width(@line)
+ @rerender_all = true
+ elsif @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ @byte_pointer -= byte_size
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ @cursor_max -= width
end
- process_auto_indent
+ arg -= 1
+ em_delete_prev_char(key, arg: arg) if arg > 0
end
alias_method :backward_delete_char, :em_delete_prev_char
@@ -1893,23 +2611,23 @@ class Reline::LineEditor
# the line. With a negative numeric argument, kill backward
# from the cursor to the beginning of the current line.
private def ed_kill_line(key)
- if current_line.bytesize > @byte_pointer
- line, deleted = byteslice!(current_line, @byte_pointer, current_line.bytesize - @byte_pointer)
- set_current_line(line, line.bytesize)
+ if @line.bytesize > @byte_pointer
+ @line, deleted = byteslice!(@line, @byte_pointer, @line.bytesize - @byte_pointer)
+ @byte_pointer = @line.bytesize
+ @cursor = @cursor_max = calculate_width(@line)
@kill_ring.append(deleted)
- elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
- set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
+ elsif @is_multiline and @byte_pointer == @line.bytesize and @buffer_of_lines.size > @line_index + 1
+ @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @line += @buffer_of_lines.delete_at(@line_index + 1)
+ @cursor_max = calculate_width(@line)
+ @buffer_of_lines[@line_index] = @line
+ @rerender_all = true
+ @rest_height += 1
end
end
alias_method :kill_line, :ed_kill_line
- # Editline:: +vi_change_to_eol+ (vi command: +C+) + Kill and change from the cursor to the end of the line.
- private def vi_change_to_eol(key)
- ed_kill_line(key)
-
- @config.editing_mode = :vi_insert
- end
-
# Editline:: +vi-kill-line-prev+ (vi: +Ctrl-U+) Delete the string from the
# beginning of the edit buffer to the cursor and save it to the
# cut buffer.
@@ -1917,9 +2635,11 @@ class Reline::LineEditor
# to the beginning of the current line.
private def vi_kill_line_prev(key)
if @byte_pointer > 0
- line, deleted = byteslice!(current_line, 0, @byte_pointer)
- set_current_line(line, 0)
+ @line, deleted = byteslice!(@line, 0, @byte_pointer)
+ @byte_pointer = 0
@kill_ring.append(deleted, true)
+ @cursor_max = calculate_width(@line)
+ @cursor = 0
end
end
alias_method :unix_line_discard, :vi_kill_line_prev
@@ -1929,35 +2649,50 @@ class Reline::LineEditor
# GNU Readline:: +kill-whole-line+ (not bound) Kill all characters on the
# current line, no matter where point is.
private def em_kill_line(key)
- if current_line.size > 0
- @kill_ring.append(current_line.dup, true)
- set_current_line('', 0)
+ if @line.size > 0
+ @kill_ring.append(@line.dup, true)
+ @line.clear
+ @byte_pointer = 0
+ @cursor_max = 0
+ @cursor = 0
end
end
alias_method :kill_whole_line, :em_kill_line
private def em_delete(key)
- if current_line.empty? and @buffer_of_lines.size == 1 and key == "\C-d".ord
+ if (not @is_multiline and @line.empty?) or (@is_multiline and @line.empty? and @buffer_of_lines.size == 1)
+ @line = nil
+ if @buffer_of_lines.size > 1
+ scroll_down(@highest_in_all - @first_line_started_from)
+ end
+ Reline::IOGate.move_cursor_column(0)
@eof = true
finish
- elsif @byte_pointer < current_line.bytesize
- splitted_last = current_line.byteslice(@byte_pointer, current_line.bytesize)
+ elsif @byte_pointer < @line.bytesize
+ splitted_last = @line.byteslice(@byte_pointer, @line.bytesize)
mbchar = splitted_last.grapheme_clusters.first
- line, = byteslice!(current_line, @byte_pointer, mbchar.bytesize)
- set_current_line(line)
- elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
- set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor_max -= width
+ @line, = byteslice!(@line, @byte_pointer, mbchar.bytesize)
+ elsif @is_multiline and @byte_pointer == @line.bytesize and @buffer_of_lines.size > @line_index + 1
+ @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @line += @buffer_of_lines.delete_at(@line_index + 1)
+ @cursor_max = calculate_width(@line)
+ @buffer_of_lines[@line_index] = @line
+ @rerender_all = true
+ @rest_height += 1
end
end
alias_method :delete_char, :em_delete
private def em_delete_or_list(key)
- if current_line.empty? or @byte_pointer < current_line.bytesize
+ if @line.empty? or @byte_pointer < @line.bytesize
em_delete(key)
- elsif !@config.autocompletion # show completed list
+ else # show completed list
result = call_completion_proc
if result.is_a?(Array)
- perform_completion(result, true)
+ complete(result, true)
end
end
end
@@ -1965,136 +2700,162 @@ class Reline::LineEditor
private def em_yank(key)
yanked = @kill_ring.yank
- insert_text(yanked) if yanked
+ if yanked
+ @line = byteinsert(@line, @byte_pointer, yanked)
+ yanked_width = calculate_width(yanked)
+ @cursor += yanked_width
+ @cursor_max += yanked_width
+ @byte_pointer += yanked.bytesize
+ end
end
alias_method :yank, :em_yank
private def em_yank_pop(key)
yanked, prev_yank = @kill_ring.yank_pop
if yanked
- line, = byteslice!(current_line, @byte_pointer - prev_yank.bytesize, prev_yank.bytesize)
- set_current_line(line, @byte_pointer - prev_yank.bytesize)
- insert_text(yanked)
+ prev_yank_width = calculate_width(prev_yank)
+ @cursor -= prev_yank_width
+ @cursor_max -= prev_yank_width
+ @byte_pointer -= prev_yank.bytesize
+ @line, = byteslice!(@line, @byte_pointer, prev_yank.bytesize)
+ @line = byteinsert(@line, @byte_pointer, yanked)
+ yanked_width = calculate_width(yanked)
+ @cursor += yanked_width
+ @cursor_max += yanked_width
+ @byte_pointer += yanked.bytesize
end
end
alias_method :yank_pop, :em_yank_pop
private def ed_clear_screen(key)
- Reline::IOGate.clear_screen
- @screen_size = Reline::IOGate.get_screen_size
- @rendered_screen.lines = []
- @rendered_screen.base_y = 0
- @rendered_screen.cursor_y = 0
+ @cleared = true
end
alias_method :clear_screen, :ed_clear_screen
private def em_next_word(key)
- if current_line.bytesize > @byte_pointer
- byte_size, _ = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.em_forward_word(@line, @byte_pointer)
@byte_pointer += byte_size
+ @cursor += width
end
end
alias_method :forward_word, :em_next_word
private def ed_prev_word(key)
if @byte_pointer > 0
- byte_size, _ = Reline::Unicode.em_backward_word(current_line, @byte_pointer)
+ byte_size, width = Reline::Unicode.em_backward_word(@line, @byte_pointer)
@byte_pointer -= byte_size
+ @cursor -= width
end
end
alias_method :backward_word, :ed_prev_word
private def em_delete_next_word(key)
- if current_line.bytesize > @byte_pointer
- byte_size, _ = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
- line, word = byteslice!(current_line, @byte_pointer, byte_size)
- set_current_line(line)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ @line, word = byteslice!(@line, @byte_pointer, byte_size)
@kill_ring.append(word)
+ @cursor_max -= width
end
end
- alias_method :kill_word, :em_delete_next_word
private def ed_delete_prev_word(key)
if @byte_pointer > 0
- byte_size, _ = Reline::Unicode.em_backward_word(current_line, @byte_pointer)
- line, word = byteslice!(current_line, @byte_pointer - byte_size, byte_size)
- set_current_line(line, @byte_pointer - byte_size)
+ byte_size, width = Reline::Unicode.em_backward_word(@line, @byte_pointer)
+ @line, word = byteslice!(@line, @byte_pointer - byte_size, byte_size)
@kill_ring.append(word, true)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ @cursor_max -= width
end
end
- alias_method :backward_kill_word, :ed_delete_prev_word
private def ed_transpose_chars(key)
if @byte_pointer > 0
- if @byte_pointer < current_line.bytesize
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
+ if @cursor_max > @cursor
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ mbchar = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor += width
@byte_pointer += byte_size
end
- back1_byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
+ back1_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
if (@byte_pointer - back1_byte_size) > 0
- back2_byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer - back1_byte_size)
+ back2_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer - back1_byte_size)
back2_pointer = @byte_pointer - back1_byte_size - back2_byte_size
- line, back2_mbchar = byteslice!(current_line, back2_pointer, back2_byte_size)
- set_current_line(byteinsert(line, @byte_pointer - back2_byte_size, back2_mbchar))
+ @line, back2_mbchar = byteslice!(@line, back2_pointer, back2_byte_size)
+ @line = byteinsert(@line, @byte_pointer - back2_byte_size, back2_mbchar)
end
end
end
alias_method :transpose_chars, :ed_transpose_chars
private def ed_transpose_words(key)
- left_word_start, middle_start, right_word_start, after_start = Reline::Unicode.ed_transpose_words(current_line, @byte_pointer)
- before = current_line.byteslice(0, left_word_start)
- left_word = current_line.byteslice(left_word_start, middle_start - left_word_start)
- middle = current_line.byteslice(middle_start, right_word_start - middle_start)
- right_word = current_line.byteslice(right_word_start, after_start - right_word_start)
- after = current_line.byteslice(after_start, current_line.bytesize - after_start)
+ left_word_start, middle_start, right_word_start, after_start = Reline::Unicode.ed_transpose_words(@line, @byte_pointer)
+ before = @line.byteslice(0, left_word_start)
+ left_word = @line.byteslice(left_word_start, middle_start - left_word_start)
+ middle = @line.byteslice(middle_start, right_word_start - middle_start)
+ right_word = @line.byteslice(right_word_start, after_start - right_word_start)
+ after = @line.byteslice(after_start, @line.bytesize - after_start)
return if left_word.empty? or right_word.empty?
+ @line = before + right_word + middle + left_word + after
from_head_to_left_word = before + right_word + middle + left_word
- set_current_line(from_head_to_left_word + after, from_head_to_left_word.bytesize)
+ @byte_pointer = from_head_to_left_word.bytesize
+ @cursor = calculate_width(from_head_to_left_word)
end
alias_method :transpose_words, :ed_transpose_words
private def em_capitol_case(key)
- if current_line.bytesize > @byte_pointer
- byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(current_line, @byte_pointer)
- before = current_line.byteslice(0, @byte_pointer)
- after = current_line.byteslice((@byte_pointer + byte_size)..-1)
- set_current_line(before + new_str + after, @byte_pointer + new_str.bytesize)
+ if @line.bytesize > @byte_pointer
+ byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(@line, @byte_pointer)
+ before = @line.byteslice(0, @byte_pointer)
+ after = @line.byteslice((@byte_pointer + byte_size)..-1)
+ @line = before + new_str + after
+ @byte_pointer += new_str.bytesize
+ @cursor += calculate_width(new_str)
end
end
alias_method :capitalize_word, :em_capitol_case
private def em_lower_case(key)
- if current_line.bytesize > @byte_pointer
- byte_size, = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
- part = current_line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
+ if @line.bytesize > @byte_pointer
+ byte_size, = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ part = @line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
mbchar =~ /[A-Z]/ ? mbchar.downcase : mbchar
}.join
- rest = current_line.byteslice((@byte_pointer + byte_size)..-1)
- line = current_line.byteslice(0, @byte_pointer) + part
- set_current_line(line + rest, line.bytesize)
+ rest = @line.byteslice((@byte_pointer + byte_size)..-1)
+ @line = @line.byteslice(0, @byte_pointer) + part
+ @byte_pointer = @line.bytesize
+ @cursor = calculate_width(@line)
+ @cursor_max = @cursor + calculate_width(rest)
+ @line += rest
end
end
alias_method :downcase_word, :em_lower_case
private def em_upper_case(key)
- if current_line.bytesize > @byte_pointer
- byte_size, = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
- part = current_line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
+ if @line.bytesize > @byte_pointer
+ byte_size, = Reline::Unicode.em_forward_word(@line, @byte_pointer)
+ part = @line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
mbchar =~ /[a-z]/ ? mbchar.upcase : mbchar
}.join
- rest = current_line.byteslice((@byte_pointer + byte_size)..-1)
- line = current_line.byteslice(0, @byte_pointer) + part
- set_current_line(line + rest, line.bytesize)
+ rest = @line.byteslice((@byte_pointer + byte_size)..-1)
+ @line = @line.byteslice(0, @byte_pointer) + part
+ @byte_pointer = @line.bytesize
+ @cursor = calculate_width(@line)
+ @cursor_max = @cursor + calculate_width(rest)
+ @line += rest
end
end
alias_method :upcase_word, :em_upper_case
private def em_kill_region(key)
if @byte_pointer > 0
- byte_size, _ = Reline::Unicode.em_big_backward_word(current_line, @byte_pointer)
- line, deleted = byteslice!(current_line, @byte_pointer - byte_size, byte_size)
- set_current_line(line, @byte_pointer - byte_size)
+ byte_size, width = Reline::Unicode.em_big_backward_word(@line, @byte_pointer)
+ @line, deleted = byteslice!(@line, @byte_pointer - byte_size, byte_size)
+ @byte_pointer -= byte_size
+ @cursor -= width
+ @cursor_max -= width
@kill_ring.append(deleted, true)
end
end
@@ -2122,9 +2883,10 @@ class Reline::LineEditor
alias_method :vi_movement_mode, :vi_command_mode
private def vi_next_word(key, arg: 1)
- if current_line.bytesize > @byte_pointer
- byte_size, _ = Reline::Unicode.vi_forward_word(current_line, @byte_pointer, @drop_terminate_spaces)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_forward_word(@line, @byte_pointer, @drop_terminate_spaces)
@byte_pointer += byte_size
+ @cursor += width
end
arg -= 1
vi_next_word(key, arg: arg) if arg > 0
@@ -2132,32 +2894,38 @@ class Reline::LineEditor
private def vi_prev_word(key, arg: 1)
if @byte_pointer > 0
- byte_size, _ = Reline::Unicode.vi_backward_word(current_line, @byte_pointer)
+ byte_size, width = Reline::Unicode.vi_backward_word(@line, @byte_pointer)
@byte_pointer -= byte_size
+ @cursor -= width
end
arg -= 1
vi_prev_word(key, arg: arg) if arg > 0
end
private def vi_end_word(key, arg: 1, inclusive: false)
- if current_line.bytesize > @byte_pointer
- byte_size, _ = Reline::Unicode.vi_forward_end_word(current_line, @byte_pointer)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_forward_end_word(@line, @byte_pointer)
@byte_pointer += byte_size
+ @cursor += width
end
arg -= 1
if inclusive and arg.zero?
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
if byte_size > 0
+ c = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(c)
@byte_pointer += byte_size
+ @cursor += width
end
end
vi_end_word(key, arg: arg) if arg > 0
end
private def vi_next_big_word(key, arg: 1)
- if current_line.bytesize > @byte_pointer
- byte_size, _ = Reline::Unicode.vi_big_forward_word(current_line, @byte_pointer)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_big_forward_word(@line, @byte_pointer)
@byte_pointer += byte_size
+ @cursor += width
end
arg -= 1
vi_next_big_word(key, arg: arg) if arg > 0
@@ -2165,39 +2933,50 @@ class Reline::LineEditor
private def vi_prev_big_word(key, arg: 1)
if @byte_pointer > 0
- byte_size, _ = Reline::Unicode.vi_big_backward_word(current_line, @byte_pointer)
+ byte_size, width = Reline::Unicode.vi_big_backward_word(@line, @byte_pointer)
@byte_pointer -= byte_size
+ @cursor -= width
end
arg -= 1
vi_prev_big_word(key, arg: arg) if arg > 0
end
private def vi_end_big_word(key, arg: 1, inclusive: false)
- if current_line.bytesize > @byte_pointer
- byte_size, _ = Reline::Unicode.vi_big_forward_end_word(current_line, @byte_pointer)
+ if @line.bytesize > @byte_pointer
+ byte_size, width = Reline::Unicode.vi_big_forward_end_word(@line, @byte_pointer)
@byte_pointer += byte_size
+ @cursor += width
end
arg -= 1
if inclusive and arg.zero?
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
if byte_size > 0
+ c = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(c)
@byte_pointer += byte_size
+ @cursor += width
end
end
vi_end_big_word(key, arg: arg) if arg > 0
end
private def vi_delete_prev_char(key)
- if @byte_pointer == 0 and @line_index > 0
+ if @is_multiline and @cursor == 0 and @line_index > 0
+ @buffer_of_lines[@line_index] = @line
+ @cursor = calculate_width(@buffer_of_lines[@line_index - 1])
@byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
@buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
@line_index -= 1
- process_auto_indent cursor_dependent: false
- elsif @byte_pointer > 0
- byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
+ @line = @buffer_of_lines[@line_index]
+ @cursor_max = calculate_width(@line)
+ @rerender_all = true
+ elsif @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
@byte_pointer -= byte_size
- line, _ = byteslice!(current_line, @byte_pointer, byte_size)
- set_current_line(line)
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ @cursor_max -= width
end
end
@@ -2212,81 +2991,78 @@ class Reline::LineEditor
end
private def ed_delete_prev_char(key, arg: 1)
- deleted = +''
+ deleted = ''
arg.times do
- if @byte_pointer > 0
- byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
+ if @cursor > 0
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
@byte_pointer -= byte_size
- line, mbchar = byteslice!(current_line, @byte_pointer, byte_size)
- set_current_line(line)
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
deleted.prepend(mbchar)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor -= width
+ @cursor_max -= width
end
end
copy_for_vi(deleted)
end
- private def vi_change_meta(key, arg: nil)
- if @vi_waiting_operator
- set_current_line('', 0) if @vi_waiting_operator == :vi_change_meta_confirm && arg.nil?
- @vi_waiting_operator = nil
- @vi_waiting_operator_arg = nil
- else
- @drop_terminate_spaces = true
- @vi_waiting_operator = :vi_change_meta_confirm
- @vi_waiting_operator_arg = arg || 1
- end
- end
-
- private def vi_change_meta_confirm(byte_pointer_diff)
- vi_delete_meta_confirm(byte_pointer_diff)
- @config.editing_mode = :vi_insert
- @drop_terminate_spaces = false
- end
-
- private def vi_delete_meta(key, arg: nil)
- if @vi_waiting_operator
- set_current_line('', 0) if @vi_waiting_operator == :vi_delete_meta_confirm && arg.nil?
- @vi_waiting_operator = nil
- @vi_waiting_operator_arg = nil
- else
- @vi_waiting_operator = :vi_delete_meta_confirm
- @vi_waiting_operator_arg = arg || 1
- end
- end
-
- private def vi_delete_meta_confirm(byte_pointer_diff)
- if byte_pointer_diff > 0
- line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
- elsif byte_pointer_diff < 0
- line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
- end
- copy_for_vi(cut)
- set_current_line(line || '', @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
+ private def vi_zero(key)
+ @byte_pointer = 0
+ @cursor = 0
+ end
+
+ private def vi_change_meta(key, arg: 1)
+ @drop_terminate_spaces = true
+ @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
+ if byte_pointer_diff > 0
+ @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff)
+ elsif byte_pointer_diff < 0
+ @line, cut = byteslice!(@line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
+ end
+ copy_for_vi(cut)
+ @cursor += cursor_diff if cursor_diff < 0
+ @cursor_max -= cursor_diff.abs
+ @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
+ @config.editing_mode = :vi_insert
+ @drop_terminate_spaces = false
+ }
+ @waiting_operator_vi_arg = arg
end
- private def vi_yank(key, arg: nil)
- if @vi_waiting_operator
- copy_for_vi(current_line) if @vi_waiting_operator == :vi_yank_confirm && arg.nil?
- @vi_waiting_operator = nil
- @vi_waiting_operator_arg = nil
- else
- @vi_waiting_operator = :vi_yank_confirm
- @vi_waiting_operator_arg = arg || 1
- end
+ private def vi_delete_meta(key, arg: 1)
+ @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
+ if byte_pointer_diff > 0
+ @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff)
+ elsif byte_pointer_diff < 0
+ @line, cut = byteslice!(@line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
+ end
+ copy_for_vi(cut)
+ @cursor += cursor_diff if cursor_diff < 0
+ @cursor_max -= cursor_diff.abs
+ @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
+ }
+ @waiting_operator_vi_arg = arg
end
- private def vi_yank_confirm(byte_pointer_diff)
- if byte_pointer_diff > 0
- cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
- elsif byte_pointer_diff < 0
- cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
- end
- copy_for_vi(cut)
+ private def vi_yank(key, arg: 1)
+ @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
+ if byte_pointer_diff > 0
+ cut = @line.byteslice(@byte_pointer, byte_pointer_diff)
+ elsif byte_pointer_diff < 0
+ cut = @line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
+ end
+ copy_for_vi(cut)
+ }
+ @waiting_operator_vi_arg = arg
end
private def vi_list_or_eof(key)
- if current_line.empty? and @buffer_of_lines.size == 1
- set_current_line('', 0)
+ if (not @is_multiline and @line.empty?) or (@is_multiline and @line.empty? and @buffer_of_lines.size == 1)
+ @line = nil
+ if @buffer_of_lines.size > 1
+ scroll_down(@highest_in_all - @first_line_started_from)
+ end
+ Reline::IOGate.move_cursor_column(0)
@eof = true
finish
else
@@ -2297,15 +3073,18 @@ class Reline::LineEditor
alias_method :vi_eof_maybe, :vi_list_or_eof
private def ed_delete_next_char(key, arg: 1)
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
- unless current_line.empty? || byte_size == 0
- line, mbchar = byteslice!(current_line, @byte_pointer, byte_size)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ unless @line.empty? || byte_size == 0
+ @line, mbchar = byteslice!(@line, @byte_pointer, byte_size)
copy_for_vi(mbchar)
- if @byte_pointer > 0 && current_line.bytesize == @byte_pointer + byte_size
- byte_size = Reline::Unicode.get_prev_mbchar_size(line, @byte_pointer)
- set_current_line(line, @byte_pointer - byte_size)
- else
- set_current_line(line, @byte_pointer)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @cursor_max -= width
+ if @cursor > 0 and @cursor >= @cursor_max
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
+ mbchar = @line.byteslice(@byte_pointer - byte_size, byte_size)
+ width = Reline::Unicode.get_mbchar_width(mbchar)
+ @byte_pointer -= byte_size
+ @cursor -= width
end
end
arg -= 1
@@ -2316,25 +3095,54 @@ class Reline::LineEditor
if Reline::HISTORY.empty?
return
end
- move_history(0, line: :start, cursor: :start)
+ if @history_pointer.nil?
+ @history_pointer = 0
+ @line_backup_in_history = @line
+ @line = Reline::HISTORY[@history_pointer]
+ @cursor_max = calculate_width(@line)
+ @cursor = 0
+ @byte_pointer = 0
+ elsif @history_pointer.zero?
+ return
+ else
+ Reline::HISTORY[@history_pointer] = @line
+ @history_pointer = 0
+ @line = Reline::HISTORY[@history_pointer]
+ @cursor_max = calculate_width(@line)
+ @cursor = 0
+ @byte_pointer = 0
+ end
end
private def vi_histedit(key)
path = Tempfile.open { |fp|
- fp.write whole_lines.join("\n")
+ if @is_multiline
+ fp.write whole_lines.join("\n")
+ else
+ fp.write @line
+ end
fp.path
}
system("#{ENV['EDITOR']} #{path}")
- @buffer_of_lines = File.read(path).split("\n")
- @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
- @line_index = 0
+ if @is_multiline
+ @buffer_of_lines = File.read(path).split("\n")
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
+ @line_index = 0
+ @line = @buffer_of_lines[@line_index]
+ @rerender_all = true
+ else
+ @line = File.read(path)
+ end
finish
end
private def vi_paste_prev(key, arg: 1)
if @vi_clipboard.size > 0
+ @line = byteinsert(@line, @byte_pointer, @vi_clipboard)
+ @cursor_max += calculate_width(@vi_clipboard)
cursor_point = @vi_clipboard.grapheme_clusters[0..-2].join
- set_current_line(byteinsert(current_line, @byte_pointer, @vi_clipboard), @byte_pointer + cursor_point.bytesize)
+ @cursor += calculate_width(cursor_point)
+ @byte_pointer += cursor_point.bytesize
end
arg -= 1
vi_paste_prev(key, arg: arg) if arg > 0
@@ -2342,9 +3150,11 @@ class Reline::LineEditor
private def vi_paste_next(key, arg: 1)
if @vi_clipboard.size > 0
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
- line = byteinsert(current_line, @byte_pointer + byte_size, @vi_clipboard)
- set_current_line(line, @byte_pointer + @vi_clipboard.bytesize)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ @line = byteinsert(@line, @byte_pointer + byte_size, @vi_clipboard)
+ @cursor_max += calculate_width(@vi_clipboard)
+ @cursor += calculate_width(@vi_clipboard)
+ @byte_pointer += @vi_clipboard.bytesize
end
arg -= 1
vi_paste_next(key, arg: arg) if arg > 0
@@ -2368,33 +3178,43 @@ class Reline::LineEditor
end
private def vi_to_column(key, arg: 0)
- # Implementing behavior of vi, not Readline's vi-mode.
- @byte_pointer, = current_line.grapheme_clusters.inject([0, 0]) { |(total_byte_size, total_width), gc|
+ @byte_pointer, @cursor = @line.grapheme_clusters.inject([0, 0]) { |total, gc|
+ # total has [byte_size, cursor]
mbchar_width = Reline::Unicode.get_mbchar_width(gc)
- break [total_byte_size, total_width] if (total_width + mbchar_width) >= arg
- [total_byte_size + gc.bytesize, total_width + mbchar_width]
+ if (total.last + mbchar_width) >= arg
+ break total
+ elsif (total.last + mbchar_width) >= @cursor_max
+ break total
+ else
+ total = [total.first + gc.bytesize, total.last + mbchar_width]
+ total
+ end
}
end
private def vi_replace_char(key, arg: 1)
@waiting_proc = ->(k) {
if arg == 1
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
- before = current_line.byteslice(0, @byte_pointer)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
+ before = @line.byteslice(0, @byte_pointer)
remaining_point = @byte_pointer + byte_size
- after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point)
- set_current_line(before + k.chr + after)
+ after = @line.byteslice(remaining_point, @line.bytesize - remaining_point)
+ @line = before + k.chr + after
+ @cursor_max = calculate_width(@line)
@waiting_proc = nil
elsif arg > 1
byte_size = 0
arg.times do
- byte_size += Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer + byte_size)
+ byte_size += Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer + byte_size)
end
- before = current_line.byteslice(0, @byte_pointer)
+ before = @line.byteslice(0, @byte_pointer)
remaining_point = @byte_pointer + byte_size
- after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point)
+ after = @line.byteslice(remaining_point, @line.bytesize - remaining_point)
replaced = k.chr * arg
- set_current_line(before + replaced + after, @byte_pointer + replaced.bytesize)
+ @line = before + replaced + after
+ @byte_pointer += replaced.bytesize
+ @cursor += calculate_width(replaced)
+ @cursor_max = calculate_width(@line)
@waiting_proc = nil
end
}
@@ -2417,7 +3237,7 @@ class Reline::LineEditor
prev_total = nil
total = nil
found = false
- current_line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar|
+ @line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar|
# total has [byte_size, cursor]
unless total
# skip cursor point
@@ -2437,16 +3257,21 @@ class Reline::LineEditor
end
end
if not need_prev_char and found and total
- byte_size, _ = total
+ byte_size, width = total
@byte_pointer += byte_size
+ @cursor += width
elsif need_prev_char and found and prev_total
- byte_size, _ = prev_total
+ byte_size, width = prev_total
@byte_pointer += byte_size
+ @cursor += width
end
if inclusive
- byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
+ byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer)
if byte_size > 0
+ c = @line.byteslice(@byte_pointer, byte_size)
+ width = Reline::Unicode.get_mbchar_width(c)
@byte_pointer += byte_size
+ @cursor += width
end
end
@waiting_proc = nil
@@ -2469,7 +3294,7 @@ class Reline::LineEditor
prev_total = nil
total = nil
found = false
- current_line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar|
+ @line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar|
# total has [byte_size, cursor]
unless total
# skip cursor point
@@ -2489,19 +3314,26 @@ class Reline::LineEditor
end
end
if not need_next_char and found and total
- byte_size, _ = total
+ byte_size, width = total
@byte_pointer -= byte_size
+ @cursor -= width
elsif need_next_char and found and prev_total
- byte_size, _ = prev_total
+ byte_size, width = prev_total
@byte_pointer -= byte_size
+ @cursor -= width
end
@waiting_proc = nil
end
private def vi_join_lines(key, arg: 1)
- if @buffer_of_lines.size > @line_index + 1
- next_line = @buffer_of_lines.delete_at(@line_index + 1).lstrip
- set_current_line(current_line + ' ' + next_line, current_line.bytesize)
+ if @is_multiline and @buffer_of_lines.size > @line_index + 1
+ @cursor = calculate_width(@line)
+ @byte_pointer = @line.bytesize
+ @line += ' ' + @buffer_of_lines.delete_at(@line_index + 1).lstrip
+ @cursor_max = calculate_width(@line)
+ @buffer_of_lines[@line_index] = @line
+ @rerender_all = true
+ @rest_height += 1
end
arg -= 1
vi_join_lines(key, arg: arg) if arg > 0
@@ -2515,27 +3347,11 @@ class Reline::LineEditor
private def em_exchange_mark(key)
return unless @mark_pointer
new_pointer = [@byte_pointer, @line_index]
+ @previous_line_index = @line_index
@byte_pointer, @line_index = @mark_pointer
+ @cursor = calculate_width(@line.byteslice(0, @byte_pointer))
+ @cursor_max = calculate_width(@line)
@mark_pointer = new_pointer
end
alias_method :exchange_point_and_mark, :em_exchange_mark
-
- private def emacs_editing_mode(key)
- @config.editing_mode = :emacs
- end
-
- private def vi_editing_mode(key)
- @config.editing_mode = :vi_insert
- end
-
- private def undo(_key)
- return if @past_lines.empty?
-
- @undoing = true
-
- target_lines, target_cursor_x, target_cursor_y = @past_lines.last
- set_current_lines(target_lines, target_cursor_x, target_cursor_y)
-
- @past_lines.pop
- end
end
diff --git a/lib/reline/reline.gemspec b/lib/reline/reline.gemspec
index dfaf966728..7bf1f8758b 100644
--- a/lib/reline/reline.gemspec
+++ b/lib/reline/reline.gemspec
@@ -18,11 +18,6 @@ Gem::Specification.new do |spec|
spec.files = Dir['BSDL', 'COPYING', 'README.md', 'license_of_rb-readline', 'lib/**/*']
spec.require_paths = ['lib']
- spec.metadata = {
- "bug_tracker_uri" => "https://github.com/ruby/reline/issues",
- "changelog_uri" => "https://github.com/ruby/reline/releases",
- "source_code_uri" => "https://github.com/ruby/reline"
- }
spec.required_ruby_version = Gem::Requirement.new('>= 2.6')
diff --git a/lib/reline/terminfo.rb b/lib/reline/terminfo.rb
index 6885a0c6be..f53642b919 100644
--- a/lib/reline/terminfo.rb
+++ b/lib/reline/terminfo.rb
@@ -31,7 +31,21 @@ module Reline::Terminfo
@curses_dl = false
def self.curses_dl
return @curses_dl unless @curses_dl == false
- if Fiddle.const_defined?(:TYPE_VARIADIC)
+ if RUBY_VERSION >= '3.0.0'
+ # Gem module isn't defined in test-all of the Ruby repository, and
+ # Fiddle in Ruby 3.0.0 or later supports Fiddle::TYPE_VARIADIC.
+ fiddle_supports_variadic = true
+ elsif Fiddle.const_defined?(:VERSION,false) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
+ # Fiddle::TYPE_VARIADIC is supported from Fiddle 1.0.1.
+ fiddle_supports_variadic = true
+ else
+ fiddle_supports_variadic = false
+ end
+ if fiddle_supports_variadic and not Fiddle.const_defined?(:TYPE_VARIADIC)
+ # If the libffi version is not 3.0.5 or higher, there isn't TYPE_VARIADIC.
+ fiddle_supports_variadic = false
+ end
+ if fiddle_supports_variadic
curses_dl_files.each do |curses_name|
result = Fiddle::Handle.new(curses_name)
rescue Fiddle::DLError
@@ -80,11 +94,23 @@ module Reline::Terminfo
def self.setupterm(term, fildes)
errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
ret = @setupterm.(term, fildes, errret_int)
+ errret = errret_int[0, Fiddle::SIZEOF_INT].unpack1('i')
case ret
when 0 # OK
- @term_supported = true
+ 0
when -1 # ERR
- @term_supported = false
+ case errret
+ when 1
+ raise TerminfoError.new('The terminal is hardcopy, cannot be used for curses applications.')
+ when 0
+ raise TerminfoError.new('The terminal could not be found, or that it is a generic type, having too little information for curses applications to run.')
+ when -1
+ raise TerminfoError.new('The terminfo database could not be found.')
+ else # unknown
+ -1
+ end
+ else # unknown
+ -2
end
end
@@ -136,14 +162,9 @@ module Reline::Terminfo
num
end
- # NOTE: This means Fiddle and curses are enabled.
def self.enabled?
true
end
-
- def self.term_supported?
- @term_supported
- end
end if Reline::Terminfo.curses_dl
module Reline::Terminfo
diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb
index d7460d6d4a..6000c9f82a 100644
--- a/lib/reline/unicode.rb
+++ b/lib/reline/unicode.rb
@@ -38,18 +38,41 @@ class Reline::Unicode
NON_PRINTING_START = "\1"
NON_PRINTING_END = "\2"
CSI_REGEXP = /\e\[[\d;]*[ABCDEFGHJKSTfminsuhl]/
- OSC_REGEXP = /\e\]\d+(?:;[^;\a\e]+)*(?:\a|\e\\)/
+ OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/
WIDTH_SCANNER = /\G(?:(#{NON_PRINTING_START})|(#{NON_PRINTING_END})|(#{CSI_REGEXP})|(#{OSC_REGEXP})|(\X))/o
+ NON_PRINTING_START_INDEX = 0
+ NON_PRINTING_END_INDEX = 1
+ CSI_REGEXP_INDEX = 2
+ OSC_REGEXP_INDEX = 3
+ GRAPHEME_CLUSTER_INDEX = 4
+
+ def self.get_mbchar_byte_size_by_first_char(c)
+ # Checks UTF-8 character byte size
+ case c.ord
+ # 0b0xxxxxxx
+ when ->(code) { (code ^ 0b10000000).allbits?(0b10000000) } then 1
+ # 0b110xxxxx
+ when ->(code) { (code ^ 0b00100000).allbits?(0b11100000) } then 2
+ # 0b1110xxxx
+ when ->(code) { (code ^ 0b00010000).allbits?(0b11110000) } then 3
+ # 0b11110xxx
+ when ->(code) { (code ^ 0b00001000).allbits?(0b11111000) } then 4
+ # 0b111110xx
+ when ->(code) { (code ^ 0b00000100).allbits?(0b11111100) } then 5
+ # 0b1111110x
+ when ->(code) { (code ^ 0b00000010).allbits?(0b11111110) } then 6
+ # successor of mbchar
+ else 0
+ end
+ end
def self.escape_for_print(str)
str.chars.map! { |gr|
- case gr
- when -"\n"
- gr
- when -"\t"
- -' '
+ escaped = EscapedPairs[gr.ord]
+ if escaped && gr != -"\n" && gr != -"\t"
+ escaped
else
- EscapedPairs[gr.ord] || gr
+ gr
end
}.join
end
@@ -109,14 +132,15 @@ class Reline::Unicode
width = 0
rest = str.encode(Encoding::UTF_8)
in_zero_width = false
- rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc|
+ rest.scan(WIDTH_SCANNER) do |gc|
case
- when non_printing_start
+ when gc[NON_PRINTING_START_INDEX]
in_zero_width = true
- when non_printing_end
+ when gc[NON_PRINTING_END_INDEX]
in_zero_width = false
- when csi, osc
- when gc
+ when gc[CSI_REGEXP_INDEX], gc[OSC_REGEXP_INDEX]
+ when gc[GRAPHEME_CLUSTER_INDEX]
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
unless in_zero_width
width += get_mbchar_width(gc)
end
@@ -130,40 +154,30 @@ class Reline::Unicode
end
end
- def self.split_by_width(str, max_width, encoding = str.encoding, offset: 0)
+ def self.split_by_width(str, max_width, encoding = str.encoding)
lines = [String.new(encoding: encoding)]
height = 1
- width = offset
+ width = 0
rest = str.encode(Encoding::UTF_8)
in_zero_width = false
- seq = String.new(encoding: encoding)
- rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc|
+ rest.scan(WIDTH_SCANNER) do |gc|
case
- when non_printing_start
+ when gc[NON_PRINTING_START_INDEX]
in_zero_width = true
- lines.last << NON_PRINTING_START
- when non_printing_end
+ when gc[NON_PRINTING_END_INDEX]
in_zero_width = false
- lines.last << NON_PRINTING_END
- when csi
- lines.last << csi
- unless in_zero_width
- if csi == -"\e[m" || csi == -"\e[0m"
- seq.clear
- else
- seq << csi
- end
- end
- when osc
- lines.last << osc
- seq << osc
- when gc
+ when gc[CSI_REGEXP_INDEX]
+ lines.last << gc[CSI_REGEXP_INDEX]
+ when gc[OSC_REGEXP_INDEX]
+ lines.last << gc[OSC_REGEXP_INDEX]
+ when gc[GRAPHEME_CLUSTER_INDEX]
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
unless in_zero_width
mbchar_width = get_mbchar_width(gc)
if (width += mbchar_width) > max_width
width = mbchar_width
lines << nil
- lines << seq.dup
+ lines << String.new(encoding: encoding)
height += 1
end
end
@@ -180,79 +194,34 @@ class Reline::Unicode
end
# Take a chunk of a String cut by width with escape sequences.
- def self.take_range(str, start_col, max_width)
- take_mbchar_range(str, start_col, max_width).first
- end
-
- def self.take_mbchar_range(str, start_col, width, cover_begin: false, cover_end: false, padding: false)
- chunk = String.new(encoding: str.encoding)
-
- end_col = start_col + width
+ def self.take_range(str, start_col, max_width, encoding = str.encoding)
+ chunk = String.new(encoding: encoding)
total_width = 0
rest = str.encode(Encoding::UTF_8)
in_zero_width = false
- chunk_start_col = nil
- chunk_end_col = nil
- has_csi = false
- rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc|
+ rest.scan(WIDTH_SCANNER) do |gc|
case
- when non_printing_start
+ when gc[NON_PRINTING_START_INDEX]
in_zero_width = true
- chunk << NON_PRINTING_START
- when non_printing_end
+ when gc[NON_PRINTING_END_INDEX]
in_zero_width = false
- chunk << NON_PRINTING_END
- when csi
- has_csi = true
- chunk << csi
- when osc
- chunk << osc
- when gc
+ when gc[CSI_REGEXP_INDEX]
+ chunk << gc[CSI_REGEXP_INDEX]
+ when gc[OSC_REGEXP_INDEX]
+ chunk << gc[OSC_REGEXP_INDEX]
+ when gc[GRAPHEME_CLUSTER_INDEX]
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
if in_zero_width
chunk << gc
- next
- end
-
- mbchar_width = get_mbchar_width(gc)
- prev_width = total_width
- total_width += mbchar_width
-
- if (cover_begin || padding ? total_width <= start_col : prev_width < start_col)
- # Current character haven't reached start_col yet
- next
- elsif padding && !cover_begin && prev_width < start_col && start_col < total_width
- # Add preceding padding. This padding might have background color.
- chunk << ' '
- chunk_start_col ||= start_col
- chunk_end_col = total_width
- next
- elsif (cover_end ? prev_width < end_col : total_width <= end_col)
- # Current character is in the range
- chunk << gc
- chunk_start_col ||= prev_width
- chunk_end_col = total_width
- break if total_width >= end_col
else
- # Current character exceeds end_col
- if padding && end_col < total_width
- # Add succeeding padding. This padding might have background color.
- chunk << ' '
- chunk_start_col ||= prev_width
- chunk_end_col = end_col
- end
- break
+ mbchar_width = get_mbchar_width(gc)
+ total_width += mbchar_width
+ break if (start_col + max_width) < total_width
+ chunk << gc if start_col < total_width
end
end
end
- chunk_start_col ||= start_col
- chunk_end_col ||= start_col
- if padding && chunk_end_col < end_col
- # Append padding. This padding should not include background color.
- chunk << "\e[0m" if has_csi
- chunk << ' ' * (end_col - chunk_end_col)
- chunk_end_col = end_col
- end
- [chunk, chunk_start_col, chunk_end_col - chunk_start_col]
+ chunk
end
def self.get_next_mbchar_size(line, byte_pointer)
diff --git a/lib/reline/unicode/east_asian_width.rb b/lib/reline/unicode/east_asian_width.rb
index fa16a1bb56..89bc9d9435 100644
--- a/lib/reline/unicode/east_asian_width.rb
+++ b/lib/reline/unicode/east_asian_width.rb
@@ -1,6 +1,6 @@
class Reline::Unicode::EastAsianWidth
# This is based on EastAsianWidth.txt
- # UNICODE_VERSION = '15.1.0'
+ # EastAsianWidth.txt
# Fullwidth
TYPE_F = /^[#{ %W(
@@ -60,14 +60,14 @@ class Reline::Unicode::EastAsianWidth
\u{2E80}-\u{2E99}
\u{2E9B}-\u{2EF3}
\u{2F00}-\u{2FD5}
- \u{2FF0}-\u{2FFF}
+ \u{2FF0}-\u{2FFB}
\u{3001}-\u{303E}
\u{3041}-\u{3096}
\u{3099}-\u{30FF}
\u{3105}-\u{312F}
\u{3131}-\u{318E}
\u{3190}-\u{31E3}
- \u{31EF}-\u{321E}
+ \u{31F0}-\u{321E}
\u{3220}-\u{3247}
\u{3250}-\u{4DBF}
\u{4E00}-\u{A48C}
@@ -84,13 +84,8 @@ class Reline::Unicode::EastAsianWidth
\u{17000}-\u{187F7}
\u{18800}-\u{18CD5}
\u{18D00}-\u{18D08}
- \u{1AFF0}-\u{1AFF3}
- \u{1AFF5}-\u{1AFFB}
- \u{1AFFD}-\u{1AFFE}
- \u{1B000}-\u{1B122}
- \u{1B132}
+ \u{1B000}-\u{1B11E}
\u{1B150}-\u{1B152}
- \u{1B155}
\u{1B164}-\u{1B167}
\u{1B170}-\u{1B2FB}
\u{1F004}
@@ -124,21 +119,21 @@ class Reline::Unicode::EastAsianWidth
\u{1F6CC}
\u{1F6D0}-\u{1F6D2}
\u{1F6D5}-\u{1F6D7}
- \u{1F6DC}-\u{1F6DF}
\u{1F6EB}-\u{1F6EC}
\u{1F6F4}-\u{1F6FC}
\u{1F7E0}-\u{1F7EB}
- \u{1F7F0}
\u{1F90C}-\u{1F93A}
\u{1F93C}-\u{1F945}
- \u{1F947}-\u{1F9FF}
- \u{1FA70}-\u{1FA7C}
- \u{1FA80}-\u{1FA88}
- \u{1FA90}-\u{1FABD}
- \u{1FABF}-\u{1FAC5}
- \u{1FACE}-\u{1FADB}
- \u{1FAE0}-\u{1FAE8}
- \u{1FAF0}-\u{1FAF8}
+ \u{1F947}-\u{1F978}
+ \u{1F97A}-\u{1F9CB}
+ \u{1F9CD}-\u{1F9FF}
+ \u{1FA70}-\u{1FA74}
+ \u{1FA78}-\u{1FA7A}
+ \u{1FA80}-\u{1FA86}
+ \u{1FA90}-\u{1FAA8}
+ \u{1FAB0}-\u{1FAB6}
+ \u{1FAC0}-\u{1FAC2}
+ \u{1FAD0}-\u{1FAD6}
\u{20000}-\u{2FFFD}
\u{30000}-\u{3FFFD}
).join }]/
@@ -408,7 +403,8 @@ class Reline::Unicode::EastAsianWidth
\u{0591}-\u{05C7}
\u{05D0}-\u{05EA}
\u{05EF}-\u{05F4}
- \u{0600}-\u{070D}
+ \u{0600}-\u{061C}
+ \u{061E}-\u{070D}
\u{070F}-\u{074A}
\u{074D}-\u{07B1}
\u{07C0}-\u{07FA}
@@ -417,9 +413,9 @@ class Reline::Unicode::EastAsianWidth
\u{0840}-\u{085B}
\u{085E}
\u{0860}-\u{086A}
- \u{0870}-\u{088E}
- \u{0890}-\u{0891}
- \u{0898}-\u{0983}
+ \u{08A0}-\u{08B4}
+ \u{08B6}-\u{08C7}
+ \u{08D3}-\u{0983}
\u{0985}-\u{098C}
\u{098F}-\u{0990}
\u{0993}-\u{09A8}
@@ -497,12 +493,11 @@ class Reline::Unicode::EastAsianWidth
\u{0C0E}-\u{0C10}
\u{0C12}-\u{0C28}
\u{0C2A}-\u{0C39}
- \u{0C3C}-\u{0C44}
+ \u{0C3D}-\u{0C44}
\u{0C46}-\u{0C48}
\u{0C4A}-\u{0C4D}
\u{0C55}-\u{0C56}
\u{0C58}-\u{0C5A}
- \u{0C5D}
\u{0C60}-\u{0C63}
\u{0C66}-\u{0C6F}
\u{0C77}-\u{0C8C}
@@ -514,10 +509,10 @@ class Reline::Unicode::EastAsianWidth
\u{0CC6}-\u{0CC8}
\u{0CCA}-\u{0CCD}
\u{0CD5}-\u{0CD6}
- \u{0CDD}-\u{0CDE}
+ \u{0CDE}
\u{0CE0}-\u{0CE3}
\u{0CE6}-\u{0CEF}
- \u{0CF1}-\u{0CF3}
+ \u{0CF1}-\u{0CF2}
\u{0D00}-\u{0D0C}
\u{0D0E}-\u{0D10}
\u{0D12}-\u{0D44}
@@ -547,7 +542,7 @@ class Reline::Unicode::EastAsianWidth
\u{0EA7}-\u{0EBD}
\u{0EC0}-\u{0EC4}
\u{0EC6}
- \u{0EC8}-\u{0ECE}
+ \u{0EC8}-\u{0ECD}
\u{0ED0}-\u{0ED9}
\u{0EDC}-\u{0EDF}
\u{0F00}-\u{0F47}
@@ -582,8 +577,9 @@ class Reline::Unicode::EastAsianWidth
\u{13F8}-\u{13FD}
\u{1400}-\u{169C}
\u{16A0}-\u{16F8}
- \u{1700}-\u{1715}
- \u{171F}-\u{1736}
+ \u{1700}-\u{170C}
+ \u{170E}-\u{1714}
+ \u{1720}-\u{1736}
\u{1740}-\u{1753}
\u{1760}-\u{176C}
\u{176E}-\u{1770}
@@ -591,7 +587,8 @@ class Reline::Unicode::EastAsianWidth
\u{1780}-\u{17DD}
\u{17E0}-\u{17E9}
\u{17F0}-\u{17F9}
- \u{1800}-\u{1819}
+ \u{1800}-\u{180E}
+ \u{1810}-\u{1819}
\u{1820}-\u{1878}
\u{1880}-\u{18AA}
\u{18B0}-\u{18F5}
@@ -610,9 +607,9 @@ class Reline::Unicode::EastAsianWidth
\u{1A7F}-\u{1A89}
\u{1A90}-\u{1A99}
\u{1AA0}-\u{1AAD}
- \u{1AB0}-\u{1ACE}
- \u{1B00}-\u{1B4C}
- \u{1B50}-\u{1B7E}
+ \u{1AB0}-\u{1AC0}
+ \u{1B00}-\u{1B4B}
+ \u{1B50}-\u{1B7C}
\u{1B80}-\u{1BF3}
\u{1BFC}-\u{1C37}
\u{1C3B}-\u{1C49}
@@ -620,7 +617,8 @@ class Reline::Unicode::EastAsianWidth
\u{1C90}-\u{1CBA}
\u{1CBD}-\u{1CC7}
\u{1CD0}-\u{1CFA}
- \u{1D00}-\u{1F15}
+ \u{1D00}-\u{1DF9}
+ \u{1DFB}-\u{1F15}
\u{1F18}-\u{1F1D}
\u{1F20}-\u{1F45}
\u{1F48}-\u{1F4D}
@@ -655,7 +653,7 @@ class Reline::Unicode::EastAsianWidth
\u{2090}-\u{209C}
\u{20A0}-\u{20A8}
\u{20AA}-\u{20AB}
- \u{20AD}-\u{20C0}
+ \u{20AD}-\u{20BF}
\u{20D0}-\u{20F0}
\u{2100}-\u{2102}
\u{2104}
@@ -769,7 +767,9 @@ class Reline::Unicode::EastAsianWidth
\u{2B51}-\u{2B54}
\u{2B5A}-\u{2B73}
\u{2B76}-\u{2B95}
- \u{2B97}-\u{2CF3}
+ \u{2B97}-\u{2C2E}
+ \u{2C30}-\u{2C5E}
+ \u{2C60}-\u{2CF3}
\u{2CF9}-\u{2D25}
\u{2D27}
\u{2D2D}
@@ -784,16 +784,14 @@ class Reline::Unicode::EastAsianWidth
\u{2DC8}-\u{2DCE}
\u{2DD0}-\u{2DD6}
\u{2DD8}-\u{2DDE}
- \u{2DE0}-\u{2E5D}
+ \u{2DE0}-\u{2E52}
\u{303F}
\u{4DC0}-\u{4DFF}
\u{A4D0}-\u{A62B}
\u{A640}-\u{A6F7}
- \u{A700}-\u{A7CA}
- \u{A7D0}-\u{A7D1}
- \u{A7D3}
- \u{A7D5}-\u{A7D9}
- \u{A7F2}-\u{A82C}
+ \u{A700}-\u{A7BF}
+ \u{A7C2}-\u{A7CA}
+ \u{A7F5}-\u{A82C}
\u{A830}-\u{A839}
\u{A840}-\u{A877}
\u{A880}-\u{A8C5}
@@ -825,11 +823,11 @@ class Reline::Unicode::EastAsianWidth
\u{FB3E}
\u{FB40}-\u{FB41}
\u{FB43}-\u{FB44}
- \u{FB46}-\u{FBC2}
- \u{FBD3}-\u{FD8F}
+ \u{FB46}-\u{FBC1}
+ \u{FBD3}-\u{FD3F}
+ \u{FD50}-\u{FD8F}
\u{FD92}-\u{FDC7}
- \u{FDCF}
- \u{FDF0}-\u{FDFF}
+ \u{FDF0}-\u{FDFD}
\u{FE20}-\u{FE2F}
\u{FE70}-\u{FE74}
\u{FE76}-\u{FEFC}
@@ -863,20 +861,10 @@ class Reline::Unicode::EastAsianWidth
\u{104D8}-\u{104FB}
\u{10500}-\u{10527}
\u{10530}-\u{10563}
- \u{1056F}-\u{1057A}
- \u{1057C}-\u{1058A}
- \u{1058C}-\u{10592}
- \u{10594}-\u{10595}
- \u{10597}-\u{105A1}
- \u{105A3}-\u{105B1}
- \u{105B3}-\u{105B9}
- \u{105BB}-\u{105BC}
+ \u{1056F}
\u{10600}-\u{10736}
\u{10740}-\u{10755}
\u{10760}-\u{10767}
- \u{10780}-\u{10785}
- \u{10787}-\u{107B0}
- \u{107B2}-\u{107BA}
\u{10800}-\u{10805}
\u{10808}
\u{1080A}-\u{10835}
@@ -918,14 +906,13 @@ class Reline::Unicode::EastAsianWidth
\u{10E80}-\u{10EA9}
\u{10EAB}-\u{10EAD}
\u{10EB0}-\u{10EB1}
- \u{10EFD}-\u{10F27}
+ \u{10F00}-\u{10F27}
\u{10F30}-\u{10F59}
- \u{10F70}-\u{10F89}
\u{10FB0}-\u{10FCB}
\u{10FE0}-\u{10FF6}
\u{11000}-\u{1104D}
- \u{11052}-\u{11075}
- \u{1107F}-\u{110C2}
+ \u{11052}-\u{1106F}
+ \u{1107F}-\u{110C1}
\u{110CD}
\u{110D0}-\u{110E8}
\u{110F0}-\u{110F9}
@@ -935,7 +922,7 @@ class Reline::Unicode::EastAsianWidth
\u{11180}-\u{111DF}
\u{111E1}-\u{111F4}
\u{11200}-\u{11211}
- \u{11213}-\u{11241}
+ \u{11213}-\u{1123E}
\u{11280}-\u{11286}
\u{11288}
\u{1128A}-\u{1128D}
@@ -967,11 +954,11 @@ class Reline::Unicode::EastAsianWidth
\u{11600}-\u{11644}
\u{11650}-\u{11659}
\u{11660}-\u{1166C}
- \u{11680}-\u{116B9}
+ \u{11680}-\u{116B8}
\u{116C0}-\u{116C9}
\u{11700}-\u{1171A}
\u{1171D}-\u{1172B}
- \u{11730}-\u{11746}
+ \u{11730}-\u{1173F}
\u{11800}-\u{1183B}
\u{118A0}-\u{118F2}
\u{118FF}-\u{11906}
@@ -987,8 +974,7 @@ class Reline::Unicode::EastAsianWidth
\u{119DA}-\u{119E4}
\u{11A00}-\u{11A47}
\u{11A50}-\u{11AA2}
- \u{11AB0}-\u{11AF8}
- \u{11B00}-\u{11B09}
+ \u{11AC0}-\u{11AF8}
\u{11C00}-\u{11C08}
\u{11C0A}-\u{11C36}
\u{11C38}-\u{11C45}
@@ -1010,23 +996,19 @@ class Reline::Unicode::EastAsianWidth
\u{11D93}-\u{11D98}
\u{11DA0}-\u{11DA9}
\u{11EE0}-\u{11EF8}
- \u{11F00}-\u{11F10}
- \u{11F12}-\u{11F3A}
- \u{11F3E}-\u{11F59}
\u{11FB0}
\u{11FC0}-\u{11FF1}
\u{11FFF}-\u{12399}
\u{12400}-\u{1246E}
\u{12470}-\u{12474}
\u{12480}-\u{12543}
- \u{12F90}-\u{12FF2}
- \u{13000}-\u{13455}
+ \u{13000}-\u{1342E}
+ \u{13430}-\u{13438}
\u{14400}-\u{14646}
\u{16800}-\u{16A38}
\u{16A40}-\u{16A5E}
\u{16A60}-\u{16A69}
- \u{16A6E}-\u{16ABE}
- \u{16AC0}-\u{16AC9}
+ \u{16A6E}-\u{16A6F}
\u{16AD0}-\u{16AED}
\u{16AF0}-\u{16AF5}
\u{16B00}-\u{16B45}
@@ -1043,14 +1025,10 @@ class Reline::Unicode::EastAsianWidth
\u{1BC80}-\u{1BC88}
\u{1BC90}-\u{1BC99}
\u{1BC9C}-\u{1BCA3}
- \u{1CF00}-\u{1CF2D}
- \u{1CF30}-\u{1CF46}
- \u{1CF50}-\u{1CFC3}
\u{1D000}-\u{1D0F5}
\u{1D100}-\u{1D126}
- \u{1D129}-\u{1D1EA}
+ \u{1D129}-\u{1D1E8}
\u{1D200}-\u{1D245}
- \u{1D2C0}-\u{1D2D3}
\u{1D2E0}-\u{1D2F3}
\u{1D300}-\u{1D356}
\u{1D360}-\u{1D378}
@@ -1077,27 +1055,17 @@ class Reline::Unicode::EastAsianWidth
\u{1D7CE}-\u{1DA8B}
\u{1DA9B}-\u{1DA9F}
\u{1DAA1}-\u{1DAAF}
- \u{1DF00}-\u{1DF1E}
- \u{1DF25}-\u{1DF2A}
\u{1E000}-\u{1E006}
\u{1E008}-\u{1E018}
\u{1E01B}-\u{1E021}
\u{1E023}-\u{1E024}
\u{1E026}-\u{1E02A}
- \u{1E030}-\u{1E06D}
- \u{1E08F}
\u{1E100}-\u{1E12C}
\u{1E130}-\u{1E13D}
\u{1E140}-\u{1E149}
\u{1E14E}-\u{1E14F}
- \u{1E290}-\u{1E2AE}
\u{1E2C0}-\u{1E2F9}
\u{1E2FF}
- \u{1E4D0}-\u{1E4F9}
- \u{1E7E0}-\u{1E7E6}
- \u{1E7E8}-\u{1E7EB}
- \u{1E7ED}-\u{1E7EE}
- \u{1E7F0}-\u{1E7FE}
\u{1E800}-\u{1E8C4}
\u{1E8C7}-\u{1E8D6}
\u{1E900}-\u{1E94B}
@@ -1174,8 +1142,8 @@ class Reline::Unicode::EastAsianWidth
\u{1F6D3}-\u{1F6D4}
\u{1F6E0}-\u{1F6EA}
\u{1F6F0}-\u{1F6F3}
- \u{1F700}-\u{1F776}
- \u{1F77B}-\u{1F7D9}
+ \u{1F700}-\u{1F773}
+ \u{1F780}-\u{1F7D8}
\u{1F800}-\u{1F80B}
\u{1F810}-\u{1F847}
\u{1F850}-\u{1F859}
diff --git a/lib/reline/version.rb b/lib/reline/version.rb
index 46613a5952..67a3d694bd 100644
--- a/lib/reline/version.rb
+++ b/lib/reline/version.rb
@@ -1,3 +1,3 @@
module Reline
- VERSION = '0.5.7'
+ VERSION = '0.3.2'
end
diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
index ee3f73e383..b952329911 100644
--- a/lib/reline/windows.rb
+++ b/lib/reline/windows.rb
@@ -1,8 +1,6 @@
require 'fiddle/import'
class Reline::Windows
- RESET_COLOR = "\e[0m"
-
def self.encoding
Encoding::UTF_8
end
@@ -87,7 +85,7 @@ class Reline::Windows
def call(*args)
import = @proto.split("")
args.each_with_index do |x, i|
- args[i], = [x == 0 ? nil : +x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
+ args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
args[i], = [x].pack("I").unpack("i") if import[i] == "I"
end
ret, = @func.call(*args)
@@ -259,7 +257,7 @@ class Reline::Windows
def self.check_input_event
num_of_events = 0.chr * 8
while @@output_buf.empty?
- Reline.core.line_editor.handle_signal
+ Reline.core.line_editor.resize
if @@WaitForSingleObject.(@@hConsoleInputHandle, 100) != 0 # max 0.1 sec
# prevent for background consolemode change
@@legacy_console = (getconsolemode() & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0)
@@ -293,11 +291,7 @@ class Reline::Windows
end
end
- def self.with_raw_input
- yield
- end
-
- def self.getc(_timeout_second)
+ def self.getc
check_input_event
@@output_buf.shift
end
diff --git a/lib/resolv.gemspec b/lib/resolv.gemspec
index 6b83e303d7..f221010ab6 100644
--- a/lib/resolv.gemspec
+++ b/lib/resolv.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "resolv"
+ spec.version = "0.2.3"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/lib/resolv.rb b/lib/resolv.rb
index 57fd173750..eaea69bfd5 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -37,8 +37,6 @@ end
class Resolv
- VERSION = "0.3.0"
-
##
# Looks up the first IP address for +name+.
@@ -84,8 +82,8 @@ class Resolv
##
# Creates a new Resolv using +resolvers+.
- def initialize(resolvers=nil, use_ipv6: nil)
- @resolvers = resolvers || [Hosts.new, DNS.new(DNS::Config.default_config_hash.merge(use_ipv6: use_ipv6))]
+ def initialize(resolvers=[Hosts.new, DNS.new])
+ @resolvers = resolvers
end
##
@@ -198,7 +196,7 @@ class Resolv
next unless addr
@addr2name[addr] = [] unless @addr2name.include? addr
@addr2name[addr] << hostname
- @addr2name[addr].concat(aliases)
+ @addr2name[addr] += aliases
@name2addr[hostname] = [] unless @name2addr.include? hostname
@name2addr[hostname] << addr
aliases.each {|n|
@@ -312,8 +310,6 @@ class Resolv
# String:: Path to a file using /etc/resolv.conf's format.
# Hash:: Must contain :nameserver, :search and :ndots keys.
# :nameserver_port can be used to specify port number of nameserver address.
- # :raise_timeout_errors can be used to raise timeout errors
- # as exceptions instead of treating the same as an NXDOMAIN response.
#
# The value of :nameserver should be an address string or
# an array of address strings.
@@ -410,11 +406,6 @@ class Resolv
end
def use_ipv6? # :nodoc:
- use_ipv6 = @config.use_ipv6?
- unless use_ipv6.nil?
- return use_ipv6
- end
-
begin
list = Socket.ip_address_list
rescue NotImplementedError
@@ -757,7 +748,7 @@ class Resolv
next if @socks_hash[bind_host]
begin
sock = UDPSocket.new(af)
- rescue Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT
+ rescue Errno::EAFNOSUPPORT
next # The kernel doesn't support the address family.
end
@socks << sock
@@ -974,7 +965,7 @@ class Resolv
next unless keyword
case keyword
when 'nameserver'
- nameserver.concat(args)
+ nameserver += args
when 'domain'
next if args.empty?
search = [args[0]]
@@ -1013,7 +1004,6 @@ class Resolv
@mutex.synchronize {
unless @initialized
@nameserver_port = []
- @use_ipv6 = nil
@search = nil
@ndots = 1
case @config_info
@@ -1038,12 +1028,8 @@ class Resolv
if config_hash.include? :nameserver_port
@nameserver_port = config_hash[:nameserver_port].map {|ns, port| [ns, (port || Port)] }
end
- if config_hash.include? :use_ipv6
- @use_ipv6 = config_hash[:use_ipv6]
- end
@search = config_hash[:search] if config_hash.include? :search
@ndots = config_hash[:ndots] if config_hash.include? :ndots
- @raise_timeout_errors = config_hash[:raise_timeout_errors]
if @nameserver_port.empty?
@nameserver_port << ['0.0.0.0', Port]
@@ -1097,10 +1083,6 @@ class Resolv
@nameserver_port
end
- def use_ipv6?
- @use_ipv6
- end
-
def generate_candidates(name)
candidates = nil
name = Name.create(name)
@@ -1134,7 +1116,6 @@ class Resolv
def resolv(name)
candidates = generate_candidates(name)
timeouts = @timeouts || generate_timeouts
- timeout_error = false
begin
candidates.each {|candidate|
begin
@@ -1146,13 +1127,11 @@ class Resolv
end
}
}
- timeout_error = true
raise ResolvError.new("DNS resolv timeout: #{name}")
rescue NXDomain
end
}
rescue ResolvError
- raise if @raise_timeout_errors && timeout_error
end
end
@@ -1508,14 +1487,14 @@ class Resolv
}
end
- def put_name(d, compress: true)
- put_labels(d.to_a, compress: compress)
+ def put_name(d)
+ put_labels(d.to_a)
end
- def put_labels(d, compress: true)
+ def put_labels(d)
d.each_index {|i|
domain = d[i..-1]
- if compress && idx = @names[domain]
+ if idx = @names[domain]
self.put_pack("n", 0xc000 | idx)
return
else
@@ -1539,15 +1518,13 @@ class Resolv
id, flag, qdcount, ancount, nscount, arcount =
msg.get_unpack('nnnnnn')
o.id = id
- o.tc = (flag >> 9) & 1
- o.rcode = flag & 15
- return o unless o.tc.zero?
-
o.qr = (flag >> 15) & 1
o.opcode = (flag >> 11) & 15
o.aa = (flag >> 10) & 1
+ o.tc = (flag >> 9) & 1
o.rd = (flag >> 8) & 1
o.ra = (flag >> 7) & 1
+ o.rcode = flag & 15
(1..qdcount).each {
name, typeclass = msg.get_question
o.add_question(name, typeclass)
@@ -1639,14 +1616,6 @@ class Resolv
strings
end
- def get_list
- [].tap do |values|
- while @index < @limit
- values << yield
- end
- end
- end
-
def get_name
return Name.new(self.get_labels)
end
@@ -1655,6 +1624,7 @@ class Resolv
prev_index = @index
save_index = nil
d = []
+ size = -1
while true
raise DecodeError.new("limit exceeded") if @limit <= @index
case @data.getbyte(@index)
@@ -1675,7 +1645,10 @@ class Resolv
end
@index = idx
else
- d << self.get_label
+ l = self.get_label
+ d << l
+ size += 1 + l.string.bytesize
+ raise DecodeError.new("name label data exceed 255 octets") if size > 255
end
end
end
@@ -1708,378 +1681,6 @@ class Resolv
end
##
- # SvcParams for service binding RRs. [RFC9460]
-
- class SvcParams
- include Enumerable
-
- ##
- # Create a list of SvcParams with the given initial content.
- #
- # +params+ has to be an enumerable of +SvcParam+s.
- # If its content has +SvcParam+s with the duplicate key,
- # the one appears last takes precedence.
-
- def initialize(params = [])
- @params = {}
-
- params.each do |param|
- add param
- end
- end
-
- ##
- # Get SvcParam for the given +key+ in this list.
-
- def [](key)
- @params[canonical_key(key)]
- end
-
- ##
- # Get the number of SvcParams in this list.
-
- def count
- @params.count
- end
-
- ##
- # Get whether this list is empty.
-
- def empty?
- @params.empty?
- end
-
- ##
- # Add the SvcParam +param+ to this list, overwriting the existing one with the same key.
-
- def add(param)
- @params[param.class.key_number] = param
- end
-
- ##
- # Remove the +SvcParam+ with the given +key+ and return it.
-
- def delete(key)
- @params.delete(canonical_key(key))
- end
-
- ##
- # Enumerate the +SvcParam+s in this list.
-
- def each(&block)
- return enum_for(:each) unless block
- @params.each_value(&block)
- end
-
- def encode(msg) # :nodoc:
- @params.keys.sort.each do |key|
- msg.put_pack('n', key)
- msg.put_length16 do
- @params.fetch(key).encode(msg)
- end
- end
- end
-
- def self.decode(msg) # :nodoc:
- params = msg.get_list do
- key, = msg.get_unpack('n')
- msg.get_length16 do
- SvcParam::ClassHash[key].decode(msg)
- end
- end
-
- return self.new(params)
- end
-
- private
-
- def canonical_key(key) # :nodoc:
- case key
- when Integer
- key
- when /\Akey(\d+)\z/
- Integer($1)
- when Symbol
- SvcParam::ClassHash[key].key_number
- else
- raise TypeError, 'key must be either String or Symbol'
- end
- end
- end
-
-
- ##
- # Base class for SvcParam. [RFC9460]
-
- class SvcParam
-
- ##
- # Get the presentation name of the SvcParamKey.
-
- def self.key_name
- const_get(:KeyName)
- end
-
- ##
- # Get the registered number of the SvcParamKey.
-
- def self.key_number
- const_get(:KeyNumber)
- end
-
- ClassHash = Hash.new do |h, key| # :nodoc:
- case key
- when Integer
- Generic.create(key)
- when /\Akey(?<key>\d+)\z/
- Generic.create(key.to_int)
- when Symbol
- raise KeyError, "unknown key #{key}"
- else
- raise TypeError, 'key must be either String or Symbol'
- end
- end
-
- ##
- # Generic SvcParam abstract class.
-
- class Generic < SvcParam
-
- ##
- # SvcParamValue in wire-format byte string.
-
- attr_reader :value
-
- ##
- # Create generic SvcParam
-
- def initialize(value)
- @value = value
- end
-
- def encode(msg) # :nodoc:
- msg.put_bytes(@value)
- end
-
- def self.decode(msg) # :nodoc:
- return self.new(msg.get_bytes)
- end
-
- def self.create(key_number)
- c = Class.new(Generic)
- key_name = :"key#{key_number}"
- c.const_set(:KeyName, key_name)
- c.const_set(:KeyNumber, key_number)
- self.const_set(:"Key#{key_number}", c)
- ClassHash[key_name] = ClassHash[key_number] = c
- return c
- end
- end
-
- ##
- # "mandatory" SvcParam -- Mandatory keys in service binding RR
-
- class Mandatory < SvcParam
- KeyName = :mandatory
- KeyNumber = 0
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Mandatory keys.
-
- attr_reader :keys
-
- ##
- # Initialize "mandatory" ScvParam.
-
- def initialize(keys)
- @keys = keys.map(&:to_int)
- end
-
- def encode(msg) # :nodoc:
- @keys.sort.each do |key|
- msg.put_pack('n', key)
- end
- end
-
- def self.decode(msg) # :nodoc:
- keys = msg.get_list { msg.get_unpack('n')[0] }
- return self.new(keys)
- end
- end
-
- ##
- # "alpn" SvcParam -- Additional supported protocols
-
- class ALPN < SvcParam
- KeyName = :alpn
- KeyNumber = 1
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Supported protocol IDs.
-
- attr_reader :protocol_ids
-
- ##
- # Initialize "alpn" ScvParam.
-
- def initialize(protocol_ids)
- @protocol_ids = protocol_ids.map(&:to_str)
- end
-
- def encode(msg) # :nodoc:
- msg.put_string_list(@protocol_ids)
- end
-
- def self.decode(msg) # :nodoc:
- return self.new(msg.get_string_list)
- end
- end
-
- ##
- # "no-default-alpn" SvcParam -- No support for default protocol
-
- class NoDefaultALPN < SvcParam
- KeyName = :'no-default-alpn'
- KeyNumber = 2
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- def encode(msg) # :nodoc:
- # no payload
- end
-
- def self.decode(msg) # :nodoc:
- return self.new
- end
- end
-
- ##
- # "port" SvcParam -- Port for alternative endpoint
-
- class Port < SvcParam
- KeyName = :port
- KeyNumber = 3
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Port number.
-
- attr_reader :port
-
- ##
- # Initialize "port" ScvParam.
-
- def initialize(port)
- @port = port.to_int
- end
-
- def encode(msg) # :nodoc:
- msg.put_pack('n', @port)
- end
-
- def self.decode(msg) # :nodoc:
- port, = msg.get_unpack('n')
- return self.new(port)
- end
- end
-
- ##
- # "ipv4hint" SvcParam -- IPv4 address hints
-
- class IPv4Hint < SvcParam
- KeyName = :ipv4hint
- KeyNumber = 4
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Set of IPv4 addresses.
-
- attr_reader :addresses
-
- ##
- # Initialize "ipv4hint" ScvParam.
-
- def initialize(addresses)
- @addresses = addresses.map {|address| IPv4.create(address) }
- end
-
- def encode(msg) # :nodoc:
- @addresses.each do |address|
- msg.put_bytes(address.address)
- end
- end
-
- def self.decode(msg) # :nodoc:
- addresses = msg.get_list { IPv4.new(msg.get_bytes(4)) }
- return self.new(addresses)
- end
- end
-
- ##
- # "ipv6hint" SvcParam -- IPv6 address hints
-
- class IPv6Hint < SvcParam
- KeyName = :ipv6hint
- KeyNumber = 6
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Set of IPv6 addresses.
-
- attr_reader :addresses
-
- ##
- # Initialize "ipv6hint" ScvParam.
-
- def initialize(addresses)
- @addresses = addresses.map {|address| IPv6.create(address) }
- end
-
- def encode(msg) # :nodoc:
- @addresses.each do |address|
- msg.put_bytes(address.address)
- end
- end
-
- def self.decode(msg) # :nodoc:
- addresses = msg.get_list { IPv6.new(msg.get_bytes(16)) }
- return self.new(addresses)
- end
- end
-
- ##
- # "dohpath" SvcParam -- DNS over HTTPS path template [RFC9461]
-
- class DoHPath < SvcParam
- KeyName = :dohpath
- KeyNumber = 7
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # URI template for DoH queries.
-
- attr_reader :template
-
- ##
- # Initialize "dohpath" ScvParam.
-
- def initialize(template)
- @template = template.encode('utf-8')
- end
-
- def encode(msg) # :nodoc:
- msg.put_bytes(@template)
- end
-
- def self.decode(msg) # :nodoc:
- template = msg.get_bytes.force_encoding('utf-8')
- return self.new(template)
- end
- end
- end
-
- ##
# A DNS query abstract class.
class Query
@@ -2731,7 +2332,7 @@ class Resolv
msg.put_pack("n", @priority)
msg.put_pack("n", @weight)
msg.put_pack("n", @port)
- msg.put_name(@target, compress: false)
+ msg.put_name(@target)
end
def self.decode_rdata(msg) # :nodoc:
@@ -2742,84 +2343,6 @@ class Resolv
return self.new(priority, weight, port, target)
end
end
-
- ##
- # Common implementation for SVCB-compatible resource records.
-
- class ServiceBinding
-
- ##
- # Create a service binding resource record.
-
- def initialize(priority, target, params = [])
- @priority = priority.to_int
- @target = Name.create(target)
- @params = SvcParams.new(params)
- end
-
- ##
- # The priority of this target host.
- #
- # The range is 0-65535.
- # If set to 0, this RR is in AliasMode. Otherwise, it is in ServiceMode.
-
- attr_reader :priority
-
- ##
- # The domain name of the target host.
-
- attr_reader :target
-
- ##
- # The service paramters for the target host.
-
- attr_reader :params
-
- ##
- # Whether this RR is in AliasMode.
-
- def alias_mode?
- self.priority == 0
- end
-
- ##
- # Whether this RR is in ServiceMode.
-
- def service_mode?
- !alias_mode?
- end
-
- def encode_rdata(msg) # :nodoc:
- msg.put_pack("n", @priority)
- msg.put_name(@target, compress: false)
- @params.encode(msg)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- priority, = msg.get_unpack("n")
- target = msg.get_name
- params = SvcParams.decode(msg)
- return self.new(priority, target, params)
- end
- end
-
- ##
- # SVCB resource record [RFC9460]
-
- class SVCB < ServiceBinding
- TypeValue = 64
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
- end
-
- ##
- # HTTPS resource record [RFC9460]
-
- class HTTPS < ServiceBinding
- TypeValue = 65
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
- end
end
end
end
@@ -3039,7 +2562,11 @@ class Resolv
attr_reader :address
def to_s # :nodoc:
- sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn")).sub(/(^|:)0(:0)+(:|$)/, '::')
+ address = sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn"))
+ unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
+ address.sub!(/(^|:)0(:|$)/, '::')
+ end
+ return address
end
def inspect # :nodoc:
diff --git a/lib/rinda/rinda.gemspec b/lib/rinda/rinda.gemspec
index e9f53dd864..0c13e3c2df 100644
--- a/lib/rinda/rinda.gemspec
+++ b/lib/rinda/rinda.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib/rinda", "."].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "rinda"
+ spec.version = "0.1.1"
spec.authors = ["Masatoshi SEKI"]
spec.email = ["seki@ruby-lang.org"]
diff --git a/lib/rinda/rinda.rb b/lib/rinda/rinda.rb
index e1649e3248..e762286d3b 100644
--- a/lib/rinda/rinda.rb
+++ b/lib/rinda/rinda.rb
@@ -18,8 +18,6 @@ require 'drb/drb'
module Rinda
- VERSION = "0.2.0"
-
##
# Rinda error base class
diff --git a/lib/ruby_vm/mjit/c_pointer.rb b/lib/ruby_vm/mjit/c_pointer.rb
new file mode 100644
index 0000000000..a92c2140ae
--- /dev/null
+++ b/lib/ruby_vm/mjit/c_pointer.rb
@@ -0,0 +1,329 @@
+module RubyVM::MJIT # :nodoc: all
+ # Every class under this namespace is a pointer. Even if the type is
+ # immediate, it shouldn't be dereferenced until `*` is called.
+ module CPointer
+ # Note: We'd like to avoid alphabetic method names to avoid a conflict
+ # with member methods. to_i and to_s are considered an exception.
+ class Struct
+ # @param name [String]
+ # @param sizeof [Integer]
+ # @param members [Hash{ Symbol => [RubyVM::MJIT::CType::*, Integer, TrueClass] }]
+ def initialize(addr, sizeof, members)
+ @addr = addr
+ @sizeof = sizeof
+ @members = members
+ end
+
+ # Get a raw address
+ def to_i
+ @addr
+ end
+
+ # Serialized address for generated code
+ def to_s
+ "0x#{@addr.to_s(16)}"
+ end
+
+ # Pointer diff
+ def -(struct)
+ raise ArgumentError if self.class != struct.class
+ (@addr - struct.to_i) / @sizeof
+ end
+
+ # Primitive API that does no automatic dereference
+ # TODO: remove this?
+ # @param member [Symbol]
+ def [](member)
+ type, offset = @members.fetch(member)
+ type.new(@addr + offset / 8)
+ end
+
+ private
+
+ # @param member [Symbol]
+ # @param value [Object]
+ def []=(member, value)
+ type, offset = @members.fetch(member)
+ type[@addr + offset / 8] = value
+ end
+
+ # @param sizeof [Integer]
+ # @param members [Hash{ Symbol => [Integer, RubyVM::MJIT::CType::*] }]
+ def self.define(sizeof, members)
+ Class.new(self) do
+ # Return the size of this type
+ define_singleton_method(:sizeof) { sizeof }
+
+ define_method(:initialize) do |addr = nil|
+ if addr.nil? # TODO: get rid of this feature later
+ addr = Fiddle.malloc(sizeof)
+ end
+ super(addr, sizeof, members)
+ end
+
+ members.each do |member, (type, offset, to_ruby)|
+ # Intelligent API that does automatic dereference
+ define_method(member) do
+ value = self[member]
+ if value.respond_to?(:*)
+ value = value.*
+ end
+ if to_ruby
+ value = C.to_ruby(value)
+ end
+ value
+ end
+
+ define_method("#{member}=") do |value|
+ self[member] = value
+ end
+ end
+ end
+ end
+ end
+
+ # Note: We'd like to avoid alphabetic method names to avoid a conflict
+ # with member methods. to_i is considered an exception.
+ class Union
+ # @param _name [String] To be used when it starts defining a union pointer class
+ # @param sizeof [Integer]
+ # @param members [Hash{ Symbol => RubyVM::MJIT::CType::* }]
+ def initialize(addr, sizeof, members)
+ @addr = addr
+ @sizeof = sizeof
+ @members = members
+ end
+
+ # Get a raw address
+ def to_i
+ @addr
+ end
+
+ # Move addr to access this pointer like an array
+ def +(index)
+ raise ArgumentError unless index.is_a?(Integer)
+ self.class.new(@addr + index * @sizeof)
+ end
+
+ # Pointer diff
+ def -(union)
+ raise ArgumentError if self.class != union.class
+ (@addr - union.instance_variable_get(:@addr)) / @sizeof
+ end
+
+ # @param sizeof [Integer]
+ # @param members [Hash{ Symbol => RubyVM::MJIT::CType::* }]
+ def self.define(sizeof, members)
+ Class.new(self) do
+ # Return the size of this type
+ define_singleton_method(:sizeof) { sizeof }
+
+ define_method(:initialize) do |addr|
+ super(addr, sizeof, members)
+ end
+
+ members.each do |member, type|
+ # Intelligent API that does automatic dereference
+ define_method(member) do
+ value = type.new(@addr)
+ if value.respond_to?(:*)
+ value = value.*
+ end
+ value
+ end
+ end
+ end
+ end
+ end
+
+ class Immediate
+ # @param addr [Integer]
+ # @param size [Integer]
+ # @param pack [String]
+ def initialize(addr, size, pack)
+ @addr = addr
+ @size = size
+ @pack = pack
+ end
+
+ # Get a raw address
+ def to_i
+ @addr
+ end
+
+ # Move addr to addess this pointer like an array
+ def +(index)
+ Immediate.new(@addr + index * @size, @size, @pack)
+ end
+
+ # Dereference
+ def *
+ self[0]
+ end
+
+ # Array access
+ def [](index)
+ return nil if @addr == 0
+ Fiddle::Pointer.new(@addr + index * @size)[0, @size].unpack1(@pack)
+ end
+
+ # Array set
+ def []=(index, value)
+ Fiddle::Pointer.new(@addr + index * @size)[0, @size] = [value].pack(@pack)
+ end
+
+ # Serialized address for generated code. Used for embedding things like body->iseq_encoded.
+ def to_s
+ "0x#{Integer(@addr).to_s(16)}"
+ end
+
+ # @param fiddle_type [Integer] Fiddle::TYPE_*
+ def self.define(fiddle_type)
+ size = Fiddle::PackInfo::SIZE_MAP.fetch(fiddle_type)
+ pack = Fiddle::PackInfo::PACK_MAP.fetch(fiddle_type)
+
+ Class.new(self) do
+ define_method(:initialize) do |addr|
+ super(addr, size, pack)
+ end
+
+ define_singleton_method(:size) do
+ size
+ end
+
+ # Type-level []=: Used by struct fields
+ define_singleton_method(:[]=) do |addr, value|
+ Fiddle::Pointer.new(addr)[0, size] = [value].pack(pack)
+ end
+ end
+ end
+ end
+
+ # -Fiddle::TYPE_CHAR Immediate with special handling of true/false
+ class Bool < Immediate.define(-Fiddle::TYPE_CHAR)
+ # Dereference
+ def *
+ return nil if @addr == 0
+ super != 0
+ end
+
+ def self.[]=(addr, value)
+ super(addr, value ? 1 : 0)
+ end
+ end
+
+ class Pointer
+ attr_reader :type
+
+ # @param addr [Integer]
+ # @param type [Class] RubyVM::MJIT::CType::*
+ def initialize(addr, type)
+ @addr = addr
+ @type = type
+ end
+
+ # Move addr to addess this pointer like an array
+ def +(index)
+ raise ArgumentError unless index.is_a?(Integer)
+ Pointer.new(@addr + index * Fiddle::SIZEOF_VOIDP, @type)
+ end
+
+ # Dereference
+ def *
+ return nil if dest_addr == 0
+ @type.new(dest_addr)
+ end
+
+ # Array access
+ def [](index)
+ (self + index).*
+ end
+
+ # Array set
+ # @param index [Integer]
+ # @param value [Integer, RubyVM::MJIT::CPointer::Struct] an address itself or an object that return an address with to_i
+ def []=(index, value)
+ Fiddle::Pointer.new(@addr + index * Fiddle::SIZEOF_VOIDP)[0, Fiddle::SIZEOF_VOIDP] =
+ [value.to_i].pack(Fiddle::PackInfo::PACK_MAP[Fiddle::TYPE_VOIDP])
+ end
+
+ private
+
+ def dest_addr
+ Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_VOIDP].unpack1(Fiddle::PackInfo::PACK_MAP[Fiddle::TYPE_VOIDP])
+ end
+
+ def self.define(block)
+ Class.new(self) do
+ define_method(:initialize) do |addr|
+ super(addr, block.call)
+ end
+
+ # Type-level []=: Used by struct fields
+ # @param addr [Integer]
+ # @param value [Integer, RubyVM::MJIT::CPointer::Struct] an address itself, or an object that return an address with to_i
+ define_singleton_method(:[]=) do |addr, value|
+ value = value.to_i
+ Fiddle::Pointer.new(addr)[0, Fiddle::SIZEOF_VOIDP] = [value].pack(Fiddle::PackInfo::PACK_MAP[Fiddle::TYPE_VOIDP])
+ end
+ end
+ end
+ end
+
+ class BitField
+ # @param addr [Integer]
+ # @param width [Integer]
+ # @param offset [Integer]
+ def initialize(addr, width, offset)
+ @addr = addr
+ @width = width
+ @offset = offset
+ end
+
+ # Dereference
+ def *
+ byte = Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_CHAR].unpack1('c')
+ if @width == 1
+ bit = (1 & (byte >> @offset))
+ bit == 1
+ elsif @width <= 8 && @offset == 0
+ bitmask = @width.times.sum { |i| 1 << i }
+ byte & bitmask
+ else
+ raise NotImplementedError.new("not-implemented bit field access: width=#{@width} offset=#{@offset}")
+ end
+ end
+
+ # @param width [Integer]
+ # @param offset [Integer]
+ def self.define(width, offset)
+ Class.new(self) do
+ define_method(:initialize) do |addr|
+ super(addr, width, offset)
+ end
+ end
+ end
+ end
+
+ # Give a name to a dynamic CPointer class to see it on inspect
+ def self.with_class_name(prefix, name, cache: false, &block)
+ return block.call if name.empty?
+
+ # Use a cached result only if cache: true
+ class_name = "#{prefix}_#{name}"
+ klass =
+ if cache && self.const_defined?(class_name)
+ self.const_get(class_name)
+ else
+ block.call
+ end
+
+ # Give it a name unless it's already defined
+ unless self.const_defined?(class_name)
+ self.const_set(class_name, klass)
+ end
+
+ klass
+ end
+ end
+end
diff --git a/lib/ruby_vm/mjit/c_type.rb b/lib/ruby_vm/mjit/c_type.rb
new file mode 100644
index 0000000000..9c965ad2fb
--- /dev/null
+++ b/lib/ruby_vm/mjit/c_type.rb
@@ -0,0 +1,91 @@
+require 'fiddle'
+require 'fiddle/pack'
+require_relative 'c_pointer'
+
+module RubyVM::MJIT # :nodoc: all
+ module CType
+ module Struct
+ # @param name [String]
+ # @param members [Hash{ Symbol => [Integer, RubyVM::MJIT::CType::*] }]
+ def self.new(name, sizeof, **members)
+ name = members.keys.join('_') if name.empty?
+ CPointer.with_class_name('Struct', name) do
+ CPointer::Struct.define(sizeof, members)
+ end
+ end
+ end
+
+ module Union
+ # @param name [String]
+ # @param members [Hash{ Symbol => RubyVM::MJIT::CType::* }]
+ def self.new(name, sizeof, **members)
+ name = members.keys.join('_') if name.empty?
+ CPointer.with_class_name('Union', name) do
+ CPointer::Union.define(sizeof, members)
+ end
+ end
+ end
+
+ module Immediate
+ # @param fiddle_type [Integer]
+ def self.new(fiddle_type)
+ name = Fiddle.constants.find do |const|
+ const.start_with?('TYPE_') && Fiddle.const_get(const) == fiddle_type.abs
+ end&.to_s
+ name.delete_prefix!('TYPE_')
+ if fiddle_type.negative?
+ name.prepend('U')
+ end
+ CPointer.with_class_name('Immediate', name, cache: true) do
+ CPointer::Immediate.define(fiddle_type)
+ end
+ end
+
+ # @param type [String]
+ def self.parse(ctype)
+ new(Fiddle::Importer.parse_ctype(ctype))
+ end
+
+ def self.find(size, signed)
+ fiddle_type = TYPE_MAP.fetch(size)
+ fiddle_type = -fiddle_type unless signed
+ new(fiddle_type)
+ end
+
+ TYPE_MAP = Fiddle::PackInfo::SIZE_MAP.map { |type, size| [size, type.abs] }.to_h
+ private_constant :TYPE_MAP
+ end
+
+ module Bool
+ def self.new
+ CPointer::Bool
+ end
+ end
+
+ class Pointer
+ # This takes a block to avoid "stack level too deep" on a cyclic reference
+ # @param block [Proc]
+ def self.new(&block)
+ CPointer.with_class_name('Pointer', block.object_id.to_s) do
+ CPointer::Pointer.define(block)
+ end
+ end
+ end
+
+ module BitField
+ # @param width [Integer]
+ # @param offset [Integer]
+ def self.new(width, offset)
+ CPointer.with_class_name('BitField', "#{offset}_#{width}") do
+ CPointer::BitField.define(width, offset)
+ end
+ end
+ end
+
+ # Types that are referenced but not part of code generation targets
+ Stub = ::Struct.new(:name)
+
+ # Types that it failed to figure out from the header
+ Unknown = Module.new
+ end
+end
diff --git a/lib/ruby_vm/mjit/compiler.rb b/lib/ruby_vm/mjit/compiler.rb
new file mode 100644
index 0000000000..81022cd0a8
--- /dev/null
+++ b/lib/ruby_vm/mjit/compiler.rb
@@ -0,0 +1,952 @@
+# Available variables and macros in JIT-ed function:
+# ec: the first argument of _mjitXXX
+# reg_cfp: the second argument of _mjitXXX
+# GET_CFP(): refers to `reg_cfp`
+# GET_EP(): refers to `reg_cfp->ep`
+# GET_SP(): refers to `reg_cfp->sp`, or `(stack + stack_size)` if local_stack_p
+# GET_SELF(): refers to `cfp_self`
+# GET_LEP(): refers to `VM_EP_LEP(reg_cfp->ep)`
+# EXEC_EC_CFP(): refers to `val = vm_exec(ec, true)` with frame setup
+# CALL_METHOD(): using `GET_CFP()` and `EXEC_EC_CFP()`
+# TOPN(): refers to `reg_cfp->sp`, or `*(stack + (stack_size - num - 1))` if local_stack_p
+# STACK_ADDR_FROM_TOP(): refers to `reg_cfp->sp`, or `stack + (stack_size - num)` if local_stack_p
+# DISPATCH_ORIGINAL_INSN(): expanded in _mjit_compile_insn.erb
+# THROW_EXCEPTION(): specially defined for JIT
+# RESTORE_REGS(): specially defined for `leave`
+class RubyVM::MJIT::Compiler # :nodoc: all
+ C = RubyVM::MJIT.const_get(:C, false)
+ INSNS = RubyVM::MJIT.const_get(:INSNS, false)
+ UNSUPPORTED_INSNS = [
+ :defineclass, # low priority
+ ]
+
+ def initialize = freeze
+
+ # @param iseq [RubyVM::MJIT::CPointer::Struct]
+ # @param funcname [String]
+ # @param id [Integer]
+ # @return [String,NilClass]
+ def compile(iseq, funcname, id)
+ status = C.compile_status.new # not freed for now
+ status.compiled_iseq = iseq.body
+ status.compiled_id = id
+ init_compile_status(status, iseq.body, true) # not freed for now
+ if iseq.body.ci_size > 0 && status.cc_entries_index == -1
+ return nil
+ end
+
+ src = +''
+ if !status.compile_info.disable_send_cache && !status.compile_info.disable_inlining
+ unless precompile_inlinable_iseqs(src, iseq, status)
+ return nil
+ end
+ end
+
+ src << "VALUE\n#{funcname}(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)\n{\n"
+ success = compile_body(src, iseq, status)
+ src << "\n} // end of #{funcname}\n"
+
+ return success ? src : nil
+ rescue Exception => e # should we use rb_rescue in C instead?
+ if C.mjit_opts.warnings || C.mjit_opts.verbose > 0
+ $stderr.puts "MJIT error: #{e.full_message}"
+ end
+ return nil
+ end
+
+ private
+
+ def compile_body(src, iseq, status)
+ status.success = true
+ status.local_stack_p = !iseq.body.catch_except_p
+
+ if status.local_stack_p
+ src << " VALUE stack[#{iseq.body.stack_max}];\n"
+ else
+ src << " VALUE *stack = reg_cfp->sp;\n"
+ end
+
+ unless status.inlined_iseqs.nil? # i.e. compile root
+ src << " static const rb_iseq_t *original_iseq = (const rb_iseq_t *)#{iseq};\n"
+ end
+ src << " static const VALUE *const original_body_iseq = (VALUE *)#{iseq.body.iseq_encoded};\n"
+
+ src << " VALUE cfp_self = reg_cfp->self;\n" # cache self across the method
+ src << "#undef GET_SELF\n"
+ src << "#define GET_SELF() cfp_self\n"
+
+ # Generate merged ivar guards first if needed
+ if !status.compile_info.disable_ivar_cache && using_ivar?(iseq.body)
+ src << " if (UNLIKELY(!RB_TYPE_P(GET_SELF(), T_OBJECT))) {"
+ src << " goto ivar_cancel;\n"
+ src << " }\n"
+ end
+
+ # Simulate `opt_pc` in setup_parameters_complex. Other PCs which may be passed by catch tables
+ # are not considered since vm_exec doesn't call jit_exec for catch tables.
+ if iseq.body.param.flags.has_opt
+ src << "\n"
+ src << " switch (reg_cfp->pc - ISEQ_BODY(reg_cfp->iseq)->iseq_encoded) {\n"
+ (0..iseq.body.param.opt_num).each do |i|
+ pc_offset = iseq.body.param.opt_table[i]
+ src << " case #{pc_offset}:\n"
+ src << " goto label_#{pc_offset};\n"
+ end
+ src << " }\n"
+ end
+
+ compile_insns(0, 0, status, iseq.body, src)
+ compile_cancel_handler(src, iseq.body, status)
+ src << "#undef GET_SELF\n"
+ return status.success
+ end
+
+ # Compile one conditional branch. If it has branchXXX insn, this should be
+ # called multiple times for each branch.
+ def compile_insns(stack_size, pos, status, body, src)
+ branch = C.compile_branch.new # not freed for now
+ branch.stack_size = stack_size
+ branch.finish_p = false
+
+ while pos < body.iseq_size && !already_compiled?(status, pos) && !branch.finish_p
+ insn = INSNS.fetch(C.rb_vm_insn_decode(body.iseq_encoded[pos]))
+ status.stack_size_for_pos[pos] = branch.stack_size
+
+ src << "\nlabel_#{pos}: /* #{insn.name} */\n"
+ pos = compile_insn(insn, pos, status, body.iseq_encoded + (pos+1), body, branch, src)
+ if status.success && branch.stack_size > body.stack_max
+ if mjit_opts.warnings || mjit_opts.verbose > 0
+ $stderr.puts "MJIT warning: JIT stack size (#{branch.stack_size}) exceeded its max size (#{body.stack_max})"
+ end
+ status.success = false
+ end
+ break unless status.success
+ end
+ end
+
+ # Main function of JIT compilation, vm_exec_core counterpart for JIT. Compile one insn to `f`, may modify
+ # b->stack_size and return next position.
+ #
+ # When you add a new instruction to insns.def, it would be nice to have JIT compilation support here but
+ # it's optional. This JIT compiler just ignores ISeq which includes unknown instruction, and ISeq which
+ # does not have it can be compiled as usual.
+ def compile_insn(insn, pos, status, operands, body, b, src)
+ sp_inc = C.mjit_call_attribute_sp_inc(insn.bin, operands)
+ next_pos = pos + insn.len
+
+ result = compile_insn_entry(insn, b.stack_size, sp_inc, status.local_stack_p, pos, next_pos, insn.len,
+ status.inlined_iseqs.nil?, status, operands, body)
+ if result.nil?
+ if C.mjit_opts.warnings || C.mjit_opts.verbose > 0
+ $stderr.puts "MJIT warning: Skipped to compile unsupported instruction: #{insn.name}"
+ end
+ status.success = false
+ else
+ result_src, next_pos, finish_p, compile_insns_p = result
+
+ src << result_src
+ b.stack_size += sp_inc
+
+ if finish_p
+ b.finish_p = true
+ end
+ if compile_insns_p
+ if already_compiled?(status, pos + insn.len)
+ src << "goto label_#{pos + insn.len};\n"
+ else
+ compile_insns(b.stack_size, pos + insn.len, status, body, src)
+ end
+ end
+ end
+
+ # If next_pos is already compiled and this branch is not finished yet,
+ # next instruction won't be compiled in C code next and will need `goto`.
+ if !b.finish_p && next_pos < body.iseq_size && already_compiled?(status, next_pos)
+ src << "goto label_#{next_pos};\n"
+
+ # Verify stack size assumption is the same among multiple branches
+ if status.stack_size_for_pos[next_pos] != b.stack_size
+ if mjit_opts.warnings || mjit_opts.verbose > 0
+ $stderr.puts "MJIT warning: JIT stack assumption is not the same between branches (#{status.stack_size_for_pos[next_pos]} != #{b.stack_size})\n"
+ end
+ status.success = false
+ end
+ end
+
+ return next_pos
+ end
+
+ def compile_insn_entry(insn, stack_size, sp_inc, local_stack_p, pos, next_pos, insn_len, inlined_iseq_p, status, operands, body)
+ finish_p = false
+ compile_insns = false
+
+ # TODO: define this outside this method, or at least cache it
+ opt_send_without_block = INSNS.values.find { |i| i.name == :opt_send_without_block }
+ if opt_send_without_block.nil?
+ raise 'opt_send_without_block not found'
+ end
+ send_compatible_opt_insns = INSNS.values.select do |insn|
+ insn.name.start_with?('opt_') && opt_send_without_block.opes == insn.opes &&
+ insn.expr.lines.any? { |l| l.match(/\A\s+CALL_SIMPLE_METHOD\(\);\s+\z/) }
+ end.map(&:name)
+
+ case insn.name
+ when *UNSUPPORTED_INSNS
+ return nil
+ when :opt_send_without_block, :send
+ if src = compile_send(insn, stack_size, sp_inc, local_stack_p, pos, next_pos, status, operands, body)
+ return src, next_pos, finish_p, compile_insns
+ end
+ when *send_compatible_opt_insns
+ if C.has_cache_for_send(captured_cc_entries(status)[call_data_index(C.CALL_DATA.new(operands[0]), body)], insn.bin) &&
+ src = compile_send(opt_send_without_block, stack_size, sp_inc, local_stack_p, pos, next_pos, status, operands, body)
+ return src, next_pos, finish_p, compile_insns
+ end
+ when :getinstancevariable, :setinstancevariable
+ if src = compile_ivar(insn.name, stack_size, pos, status, operands, body)
+ return src, next_pos, finish_p, compile_insns
+ end
+ when :opt_getconstant_path
+ if src = compile_getconstant_path(stack_size, pos, insn_len, operands, status)
+ return src, next_pos, finish_p, compile_insns
+ end
+ when :invokebuiltin, :opt_invokebuiltin_delegate, :opt_invokebuiltin_delegate_leave
+ if src = compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
+ if insn.name == :opt_invokebuiltin_delegate_leave
+ src << compile_leave(stack_size, pos, inlined_iseq_p)
+ finish_p = true
+ end
+ return src, next_pos, finish_p, compile_insns
+ end
+ when :leave
+ if stack_size != 1
+ raise "Unexpected JIT stack_size on leave: #{stack_size}"
+ end
+ src = compile_leave(stack_size, pos, inlined_iseq_p)
+ finish_p = true
+ return src, next_pos, finish_p, compile_insns
+ end
+
+ return compile_insn_default(insn, stack_size, sp_inc, local_stack_p, pos, next_pos, insn_len, inlined_iseq_p, operands)
+ end
+
+ # Optimized case of send / opt_send_without_block instructions.
+ def compile_send(insn, stack_size, sp_inc, local_stack_p, pos, next_pos, status, operands, body)
+ # compiler: Use captured cc to avoid race condition
+ cd = C.CALL_DATA.new(operands[0])
+ cd_index = call_data_index(cd, body)
+ captured_cc = captured_cc_entries(status)[cd_index]
+
+ # compiler: Inline send insn where some supported fastpath is used.
+ ci = cd.ci
+ kw_splat = (C.vm_ci_flag(ci) & C.VM_CALL_KW_SPLAT) > 0
+ if !status.compile_info.disable_send_cache && has_valid_method_type?(captured_cc) && (
+ # `CC_SET_FASTPATH(cd->cc, vm_call_cfunc_with_frame, ...)` in `vm_call_cfunc`
+ (vm_cc_cme(captured_cc).def.type == C.VM_METHOD_TYPE_CFUNC && !C.rb_splat_or_kwargs_p(ci) && !kw_splat) ||
+ # `CC_SET_FASTPATH(cc, vm_call_iseq_setup_func(...), vm_call_iseq_optimizable_p(...))` in `vm_callee_setup_arg`,
+ # and support only non-VM_CALL_TAILCALL path inside it
+ (vm_cc_cme(captured_cc).def.type == C.VM_METHOD_TYPE_ISEQ &&
+ C.fastpath_applied_iseq_p(ci, captured_cc, iseq = def_iseq_ptr(vm_cc_cme(captured_cc).def)) &&
+ (C.vm_ci_flag(ci) & C.VM_CALL_TAILCALL) == 0)
+ )
+ src = +"{\n"
+
+ # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things.
+ src << " const struct rb_callcache *cc = (struct rb_callcache *)#{captured_cc};\n"
+ src << " const rb_callable_method_entry_t *cc_cme = (rb_callable_method_entry_t *)#{vm_cc_cme(captured_cc)};\n"
+ src << " const VALUE recv = stack[#{stack_size + sp_inc - 1}];\n"
+ # If opt_class_of is true, use RBASIC_CLASS instead of CLASS_OF to reduce code size
+ opt_class_of = !maybe_special_const?(captured_cc.klass)
+ src << " if (UNLIKELY(#{opt_class_of ? 'RB_SPECIAL_CONST_P(recv)' : 'false'} || !vm_cc_valid_p(cc, cc_cme, #{opt_class_of ? 'RBASIC_CLASS' : 'CLASS_OF'}(recv)))) {\n"
+ src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ src << " goto send_cancel;\n"
+ src << " }\n"
+
+ # JIT: move sp and pc if necessary
+ pc_moved_p = compile_pc_and_sp(src, insn, stack_size, sp_inc, local_stack_p, next_pos)
+
+ # JIT: If ISeq is inlinable, call the inlined method without pushing a frame.
+ if iseq && status.inlined_iseqs && iseq.body.to_i == status.inlined_iseqs[pos]&.to_i
+ src << " {\n"
+ src << " VALUE orig_self = reg_cfp->self;\n"
+ src << " reg_cfp->self = stack[#{stack_size + sp_inc - 1}];\n"
+ src << " stack[#{stack_size + sp_inc - 1}] = _mjit#{status.compiled_id}_inlined_#{pos}(ec, reg_cfp, orig_self, original_iseq);\n"
+ src << " reg_cfp->self = orig_self;\n"
+ src << " }\n"
+ else
+ # JIT: Forked `vm_sendish` (except method_explorer = vm_search_method_wrap) to inline various things
+ src << " {\n"
+ src << " VALUE val;\n"
+ src << " struct rb_calling_info calling;\n"
+ if insn.name == :send
+ src << " calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, (const struct rb_callinfo *)#{ci}, (rb_iseq_t *)0x#{operands[1].to_s(16)}, FALSE);\n"
+ else
+ src << " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n"
+ end
+ src << " calling.kw_splat = #{kw_splat ? 1 : 0};\n"
+ src << " calling.recv = stack[#{stack_size + sp_inc - 1}];\n"
+ src << " calling.argc = #{C.vm_ci_argc(ci)};\n"
+
+ if vm_cc_cme(captured_cc).def.type == C.VM_METHOD_TYPE_CFUNC
+ # TODO: optimize this more
+ src << " calling.ci = (const struct rb_callinfo *)#{ci};\n" # creating local cd here because operand's cd->cc may not be the same as inlined cc.
+ src << " calling.cc = cc;"
+ src << " val = vm_call_cfunc_with_frame(ec, reg_cfp, &calling);\n"
+ else # :iseq
+ # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
+ src << " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, cc_cme, 0, #{iseq.body.param.size}, #{iseq.body.local_table_size});\n"
+ if iseq.body.catch_except_p
+ src << " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n"
+ src << " val = vm_exec(ec, true);\n"
+ else
+ src << " if ((val = jit_exec(ec)) == Qundef) {\n"
+ src << " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n" # This is vm_call0_body's code after vm_call_iseq_setup
+ src << " val = vm_exec(ec, false);\n"
+ src << " }\n"
+ end
+ end
+ src << " stack[#{stack_size + sp_inc - 1}] = val;\n"
+ src << " }\n"
+
+ # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow.
+ src << " if (UNLIKELY(!mjit_call_p)) {\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size + sp_inc};\n"
+ if !pc_moved_p
+ src << " reg_cfp->pc = original_body_iseq + #{next_pos};\n"
+ end
+ src << " goto cancel;\n"
+ src << " }\n"
+ end
+
+ src << "}\n"
+ return src
+ else
+ return nil
+ end
+ end
+
+ def compile_ivar(insn_name, stack_size, pos, status, operands, body)
+ iv_cache = C.iseq_inline_storage_entry.new(operands[1]).iv_cache
+ dest_shape_id = iv_cache.value >> C.SHAPE_FLAG_SHIFT
+ source_shape_id = parent_shape_id(dest_shape_id)
+ attr_index = iv_cache.value & ((1 << C.SHAPE_FLAG_SHIFT) - 1)
+
+ src = +''
+ if !status.compile_info.disable_ivar_cache && source_shape_id != C.INVALID_SHAPE_ID
+ # JIT: optimize away motion of sp and pc. This path does not call rb_warning() and so it's always leaf and not `handles_sp`.
+ # compile_pc_and_sp(src, insn, stack_size, sp_inc, local_stack_p, next_pos)
+
+ # JIT: prepare vm_getivar/vm_setivar arguments and variables
+ src << "{\n"
+ src << " VALUE obj = GET_SELF();\n" # T_OBJECT guaranteed by compile_body
+ # JIT: cache hit path of vm_getivar/vm_setivar, or cancel JIT (recompile it with exivar)
+ if insn_name == :setinstancevariable
+ src << " const uint32_t index = #{attr_index - 1};\n"
+ src << " const shape_id_t dest_shape_id = (shape_id_t)#{dest_shape_id};\n"
+ src << " if (dest_shape_id == ROBJECT_SHAPE_ID(obj)) {\n"
+ src << " VALUE *ptr = ROBJECT_IVPTR(obj);\n"
+ src << " RB_OBJ_WRITE(obj, &ptr[index], stack[#{stack_size - 1}]);\n"
+ src << " }\n"
+ else
+ src << " const shape_id_t source_shape_id = (shape_id_t)#{dest_shape_id};\n"
+ if attr_index == 0 # cache hit, but uninitialized iv
+ src << " /* Uninitialized instance variable */\n"
+ src << " if (source_shape_id == ROBJECT_SHAPE_ID(obj)) {\n"
+ src << " stack[#{stack_size}] = Qnil;\n"
+ src << " }\n"
+ else
+ src << " const uint32_t index = #{attr_index - 1};\n"
+ src << " if (source_shape_id == ROBJECT_SHAPE_ID(obj)) {\n"
+ src << " stack[#{stack_size}] = ROBJECT_IVPTR(obj)[index];\n"
+ src << " }\n"
+ end
+ end
+ src << " else {\n"
+ src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ src << " goto ivar_cancel;\n"
+ src << " }\n"
+ src << "}\n"
+ return src
+ elsif insn_name == :getinstancevariable && !status.compile_info.disable_exivar_cache && source_shape_id != C.INVALID_SHAPE_ID
+ # JIT: optimize away motion of sp and pc. This path does not call rb_warning() and so it's always leaf and not `handles_sp`.
+ # compile_pc_and_sp(src, insn, stack_size, sp_inc, local_stack_p, next_pos)
+
+ # JIT: prepare vm_getivar's arguments and variables
+ src << "{\n"
+ src << " VALUE obj = GET_SELF();\n"
+ src << " const shape_id_t source_shape_id = (shape_id_t)#{dest_shape_id};\n"
+ src << " const uint32_t index = #{attr_index - 1};\n"
+ # JIT: cache hit path of vm_getivar, or cancel JIT (recompile it without any ivar optimization)
+ src << " struct gen_ivtbl *ivtbl;\n"
+ src << " if (LIKELY(FL_TEST_RAW(GET_SELF(), FL_EXIVAR) && source_shape_id == rb_shape_get_shape_id(obj) && rb_ivar_generic_ivtbl_lookup(obj, &ivtbl))) {\n"
+ src << " stack[#{stack_size}] = ivtbl->ivptr[index];\n"
+ src << " }\n"
+ src << " else {\n"
+ src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ src << " goto exivar_cancel;\n"
+ src << " }\n"
+ src << "}\n"
+ return src
+ else
+ return nil
+ end
+ end
+
+ def compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
+ bf = C.RB_BUILTIN.new(operands[0])
+ if bf.compiler > 0
+ index = (insn.name == :invokebuiltin ? -1 : operands[1])
+ src = +"{\n"
+ src << " VALUE val;\n"
+ C.builtin_compiler(src, bf, index, stack_size, body.builtin_inline_p)
+ src << " stack[#{stack_size + sp_inc - 1}] = val;\n"
+ src << "}\n"
+ return src
+ else
+ return nil
+ end
+ end
+
+ def compile_leave(stack_size, pos, inlined_iseq_p)
+ src = +''
+ # Skip vm_pop_frame for inlined call
+ unless inlined_iseq_p
+ # Cancel on interrupts to make leave insn leaf
+ src << " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
+ src << " rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);\n"
+ src << " }\n"
+ src << " ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(reg_cfp);\n" # vm_pop_frame
+ end
+ src << " return stack[0];\n"
+ end
+
+ def compile_getconstant_path(stack_size, pos, insn_len, operands, status)
+ ice = C.IC.new(operands[0]).entry
+ if !status.compile_info.disable_const_cache && ice
+ # JIT: Inline everything in IC, and cancel the slow path
+ src = +" if (vm_inlined_ic_hit_p(#{ice.flags}, #{ice.value}, (const rb_cref_t *)#{to_addr(ice.ic_cref)}, reg_cfp->ep)) {\n"
+ src << " stack[#{stack_size}] = #{ice.value};\n"
+ src << " }\n"
+ src << " else {\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
+ src << " goto const_cancel;\n"
+ src << " }\n"
+ return src
+ else
+ return nil
+ end
+ end
+
+ def compile_insn_default(insn, stack_size, sp_inc, local_stack_p, pos, next_pos, insn_len, inlined_iseq_p, operands)
+ src = +''
+ finish_p = false
+ compile_insns = false
+
+ # JIT: Declare stack_size to be used in some macro of _mjit_compile_insn_body.erb
+ src << "{\n"
+ if local_stack_p
+ src << " MAYBE_UNUSED(unsigned int) stack_size = #{stack_size};\n"
+ end
+
+ # JIT: Declare variables for operands, popped values and return values
+ insn.declarations.each do |decl|
+ src << " #{decl};\n"
+ end
+
+ # JIT: Set const expressions for `RubyVM::OperandsUnifications` insn
+ insn.preamble.each do |amble|
+ src << "#{amble.sub(/const \S+\s+/, '')}\n"
+ end
+
+ # JIT: Initialize operands
+ insn.opes.each_with_index do |ope, i|
+ src << " #{ope.fetch(:name)} = (#{ope.fetch(:type)})#{operands[i]};\n"
+ # TODO: resurrect comment_id
+ end
+
+ # JIT: Initialize popped values
+ insn.pops.reverse_each.with_index.reverse_each do |pop, i|
+ src << " #{pop.fetch(:name)} = stack[#{stack_size - (i + 1)}];\n"
+ end
+
+ # JIT: move sp and pc if necessary
+ pc_moved_p = compile_pc_and_sp(src, insn, stack_size, sp_inc, local_stack_p, next_pos)
+
+ # JIT: Print insn body in insns.def
+ next_pos = compile_insn_body(src, insn, pos, next_pos, insn_len, local_stack_p, stack_size, sp_inc, operands)
+
+ # JIT: Set return values
+ insn.rets.reverse_each.with_index do |ret, i|
+ # TOPN(n) = ...
+ src << " stack[#{stack_size + sp_inc - (i + 1)}] = #{ret.fetch(:name)};\n"
+ end
+
+ # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow.
+ # leaf insn may not cancel JIT. leaf_without_check_ints is covered in RUBY_VM_CHECK_INTS of _mjit_compile_insn_body.erb.
+ unless insn.always_leaf? || insn.leaf_without_check_ints?
+ src << " if (UNLIKELY(!mjit_call_p)) {\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size + sp_inc};\n"
+ if !pc_moved_p
+ src << " reg_cfp->pc = original_body_iseq + #{next_pos};\n"
+ end
+ src << " goto cancel;\n"
+ src << " }\n"
+ end
+
+ src << "}\n"
+
+ # compiler: If insn has conditional JUMP, the code should go to the branch not targeted by JUMP next.
+ if insn.expr.match?(/if\s+\([^{}]+\)\s+\{[^{}]+JUMP\([^)]+\);[^{}]+\}/)
+ compile_insns = true
+ end
+
+ # compiler: If insn returns (leave) or does longjmp (throw), the branch should no longer be compiled. TODO: create attr for it?
+ if insn.expr.match?(/\sTHROW_EXCEPTION\([^)]+\);/) || insn.expr.match?(/\bvm_pop_frame\(/)
+ finish_p = true
+ end
+
+ return src, next_pos, finish_p, compile_insns
+ end
+
+ def compile_insn_body(src, insn, pos, next_pos, insn_len, local_stack_p, stack_size, sp_inc, operands)
+ # Print a body of insn, but with macro expansion.
+ expand_simple_macros(insn.expr).each_line do |line|
+ # Expand dynamic macro here
+ # TODO: support combination of following macros in the same line
+ case line
+ when /\A\s+RUBY_VM_CHECK_INTS\(ec\);\s+\z/
+ if insn.leaf_without_check_ints? # lazily move PC and optionalize mjit_call_p here
+ src << " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"
+ src << " reg_cfp->pc = original_body_iseq + #{next_pos};\n" # ADD_PC(INSN_ATTR(width));
+ src << " rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);\n"
+ src << " if (UNLIKELY(!mjit_call_p)) {\n"
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ src << " goto cancel;\n"
+ src << " }\n"
+ src << " }\n"
+ else
+ src << to_cstr(line)
+ end
+ when /\A\s+JUMP\((?<dest>[^)]+)\);\s+\z/
+ dest = Regexp.last_match[:dest]
+ if insn.name == :opt_case_dispatch # special case... TODO: use another macro to avoid checking name
+ hash_offsets = C.rb_hash_values(operands[0]).uniq
+ else_offset = cast_offset(operands[1])
+ base_pos = pos + insn_len
+
+ src << " switch (#{dest}) {\n"
+ hash_offsets.each do |offset|
+ src << " case #{offset}:\n"
+ src << " goto label_#{base_pos + offset};\n"
+ end
+ src << " case #{else_offset}:\n"
+ src << " goto label_#{base_pos + else_offset};\n"
+ src << " }\n"
+ else
+ # Before we `goto` next insn, we need to set return values, especially for getinlinecache
+ insn.rets.reverse_each.with_index do |ret, i|
+ # TOPN(n) = ...
+ src << " stack[#{stack_size + sp_inc - (i + 1)}] = #{ret.fetch(:name)};\n"
+ end
+
+ next_pos = pos + insn_len + cast_offset(operands[0]) # workaround: assuming dest == operands[0]. TODO: avoid relying on it
+ src << " goto label_#{next_pos};\n"
+ end
+ when /\A\s+CALL_SIMPLE_METHOD\(\);\s+\z/
+ # For `opt_xxx`'s fallbacks.
+ if local_stack_p
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ end
+ src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
+ src << " goto cancel;\n"
+ when /\A(?<prefix>.+\b)INSN_LABEL\((?<name>[^)]+)\)(?<suffix>.+)\z/m
+ prefix, name, suffix = Regexp.last_match[:prefix], Regexp.last_match[:name], Regexp.last_match[:suffix]
+ src << "#{prefix}INSN_LABEL(#{name}_#{pos})#{suffix}"
+ else
+ if insn.handles_sp?
+ # If insn.handles_sp? is true, cfp->sp might be changed inside insns (like vm_caller_setup_arg_block)
+ # and thus we need to use cfp->sp, even when local_stack_p is TRUE. When insn.handles_sp? is true,
+ # cfp->sp should be available too because _mjit_compile_pc_and_sp.erb sets it.
+ src << to_cstr(line)
+ else
+ # If local_stack_p is TRUE and insn.handles_sp? is false, stack values are only available in local variables
+ # for stack. So we need to replace those macros if local_stack_p is TRUE here.
+ case line
+ when /\bGET_SP\(\)/
+ # reg_cfp->sp
+ src << to_cstr(line.sub(/\bGET_SP\(\)/, local_stack_p ? '(stack + stack_size)' : 'GET_SP()'))
+ when /\bSTACK_ADDR_FROM_TOP\((?<num>[^)]+)\)/
+ # #define STACK_ADDR_FROM_TOP(n) (GET_SP()-(n))
+ num = Regexp.last_match[:num]
+ src << to_cstr(line.sub(/\bSTACK_ADDR_FROM_TOP\(([^)]+)\)/, local_stack_p ? "(stack + (stack_size - (#{num})))" : "STACK_ADDR_FROM_TOP(#{num})"))
+ when /\bTOPN\((?<num>[^)]+)\)/
+ # #define TOPN(n) (*(GET_SP()-(n)-1))
+ num = Regexp.last_match[:num]
+ src << to_cstr(line.sub(/\bTOPN\(([^)]+)\)/, local_stack_p ? "*(stack + (stack_size - (#{num}) - 1))" : "TOPN(#{num})"))
+ else
+ src << to_cstr(line)
+ end
+ end
+ end
+ end
+ return next_pos
+ end
+
+ def compile_pc_and_sp(src, insn, stack_size, sp_inc, local_stack_p, next_pos)
+ # JIT: When an insn is leaf, we don't need to Move pc for a catch table on catch_except_p, #caller_locations,
+ # and rb_profile_frames. For check_ints, we lazily move PC when we have interruptions.
+ pc_moved_p = false
+ unless insn.always_leaf? || insn.leaf_without_check_ints?
+ src << " reg_cfp->pc = original_body_iseq + #{next_pos};\n" # ADD_PC(INSN_ATTR(width));
+ pc_moved_p = true
+ end
+
+ # JIT: move sp to use or preserve stack variables
+ if local_stack_p
+ # sp motion is optimized away for `handles_sp? #=> false` case.
+ # Thus sp should be set properly before `goto cancel`.
+ if insn.handles_sp?
+ # JIT-only behavior (pushing JIT's local variables to VM's stack):
+ push_size = -sp_inc + insn.rets.size - insn.pops.size
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{push_size};\n"
+ push_size.times do |i|
+ src << " *(reg_cfp->sp + #{i - push_size}) = stack[#{stack_size - push_size + i}];\n"
+ end
+ end
+ else
+ if insn.handles_sp?
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size - insn.pops.size};\n" # POPN(INSN_ATTR(popn));
+ else
+ src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
+ end
+ end
+ return pc_moved_p
+ end
+
+ # Print the block to cancel inlined method call. It's supporting only `opt_send_without_block` for now.
+ def compile_inlined_cancel_handler(src, body, inline_context)
+ src << "\ncancel:\n"
+ src << " rb_mjit_recompile_inlining(original_iseq);\n"
+
+ # Swap pc/sp set on cancel with original pc/sp.
+ src << " const VALUE *current_pc = reg_cfp->pc;\n"
+ src << " VALUE *current_sp = reg_cfp->sp;\n"
+ src << " reg_cfp->pc = orig_pc;\n"
+ src << " reg_cfp->sp = orig_sp;\n\n"
+
+ # Lazily push the current call frame.
+ src << " struct rb_calling_info calling;\n"
+ src << " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n" # assumes `opt_send_without_block`
+ src << " calling.argc = #{inline_context.orig_argc};\n"
+ src << " calling.recv = reg_cfp->self;\n"
+ src << " reg_cfp->self = orig_self;\n"
+ # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
+ src << " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, (const rb_callable_method_entry_t *)#{inline_context.me}, 0, #{inline_context.param_size}, #{inline_context.local_size});\n\n"
+
+ # Start usual cancel from here.
+ src << " reg_cfp = ec->cfp;\n" # work on the new frame
+ src << " reg_cfp->pc = current_pc;\n"
+ src << " reg_cfp->sp = current_sp;\n"
+ (0...body.stack_max).each do |i| # should be always `status->local_stack_p`
+ src << " *(vm_base_ptr(reg_cfp) + #{i}) = stack[#{i}];\n"
+ end
+ # We're not just returning Qundef here so that caller's normal cancel handler can
+ # push back `stack` to `cfp->sp`.
+ src << " return vm_exec(ec, false);\n"
+ end
+
+ # Print the block to cancel JIT execution.
+ def compile_cancel_handler(src, body, status)
+ if status.inlined_iseqs.nil? # the current ISeq is being inlined
+ compile_inlined_cancel_handler(src, body, status.inline_context)
+ return
+ end
+
+ src << "\nsend_cancel:\n"
+ src << " rb_mjit_recompile_send(original_iseq);\n"
+ src << " goto cancel;\n"
+
+ src << "\nivar_cancel:\n"
+ src << " rb_mjit_recompile_ivar(original_iseq);\n"
+ src << " goto cancel;\n"
+
+ src << "\nexivar_cancel:\n"
+ src << " rb_mjit_recompile_exivar(original_iseq);\n"
+ src << " goto cancel;\n"
+
+ src << "\nconst_cancel:\n"
+ src << " rb_mjit_recompile_const(original_iseq);\n"
+ src << " goto cancel;\n"
+
+ src << "\ncancel:\n"
+ if status.local_stack_p
+ (0...body.stack_max).each do |i|
+ src << " *(vm_base_ptr(reg_cfp) + #{i}) = stack[#{i}];\n"
+ end
+ end
+ src << " return Qundef;\n"
+ end
+
+ def precompile_inlinable_child_iseq(src, child_iseq, status, ci, cc, pos)
+ child_status = C.compile_status.new # not freed for now
+ child_status.compiled_iseq = status.compiled_iseq
+ child_status.compiled_id = status.compiled_id
+ init_compile_status(child_status, child_iseq.body, false) # not freed for now
+ child_status.inline_context.orig_argc = C.vm_ci_argc(ci)
+ child_status.inline_context.me = vm_cc_cme(cc).to_i
+ child_status.inline_context.param_size = child_iseq.body.param.size
+ child_status.inline_context.local_size = child_iseq.body.local_table_size
+ if child_iseq.body.ci_size > 0 && child_status.cc_entries_index == -1
+ return false
+ end
+
+ src << "ALWAYS_INLINE(static VALUE _mjit#{status.compiled_id}_inlined_#{pos}(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq));\n"
+ src << "static inline VALUE\n_mjit#{status.compiled_id}_inlined_#{pos}(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq)\n{\n"
+ src << " const VALUE *orig_pc = reg_cfp->pc;\n"
+ src << " VALUE *orig_sp = reg_cfp->sp;\n"
+
+ success = compile_body(src, child_iseq, child_status)
+
+ src << "\n} /* end of _mjit#{status.compiled_id}_inlined_#{pos} */\n\n"
+
+ return success;
+ end
+
+ def precompile_inlinable_iseqs(src, iseq, status)
+ body = iseq.body
+ pos = 0
+ while pos < body.iseq_size
+ insn = INSNS.fetch(C.rb_vm_insn_decode(body.iseq_encoded[pos]))
+ if insn.name == :opt_send_without_block || insn.name == :opt_size # `compile_inlined_cancel_handler` supports only `opt_send_without_block`
+ cd = C.CALL_DATA.new(body.iseq_encoded[pos + 1])
+ ci = cd.ci
+ cc = captured_cc_entries(status)[call_data_index(cd, body)] # use copy to avoid race condition
+
+ if (child_iseq = rb_mjit_inlinable_iseq(ci, cc)) != nil
+ status.inlined_iseqs[pos] = child_iseq.body
+
+ if C.mjit_opts.verbose >= 1 # print beforehand because ISeq may be GCed during copy job.
+ child_location = child_iseq.body.location
+ $stderr.puts "JIT inline: #{child_location.label}@#{C.rb_iseq_path(child_iseq)}:#{C.rb_iseq_first_lineno(child_iseq)} " \
+ "=> #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{C.rb_iseq_first_lineno(iseq)}"
+ end
+ if !precompile_inlinable_child_iseq(src, child_iseq, status, ci, cc, pos)
+ return false
+ end
+ end
+ end
+ pos += insn.len
+ end
+ return true
+ end
+
+ def init_compile_status(status, body, compile_root_p)
+ status.stack_size_for_pos = Fiddle.malloc(Fiddle::SIZEOF_INT * body.iseq_size)
+ body.iseq_size.times do |i|
+ status.stack_size_for_pos[i] = C.NOT_COMPILED_STACK_SIZE
+ end
+ if compile_root_p
+ status.inlined_iseqs = Fiddle.malloc(Fiddle::SIZEOF_VOIDP * body.iseq_size)
+ body.iseq_size.times do |i|
+ status.inlined_iseqs[i] = nil
+ end
+ end
+ if body.ci_size > 0
+ status.cc_entries_index = C.mjit_capture_cc_entries(status.compiled_iseq, body)
+ else
+ status.cc_entries_index = -1
+ end
+ if compile_root_p
+ status.compile_info = rb_mjit_iseq_compile_info(body)
+ else
+ status.compile_info = Fiddle.malloc(C.rb_mjit_compile_info.sizeof)
+ status.compile_info.disable_ivar_cache = false
+ status.compile_info.disable_exivar_cache = false
+ status.compile_info.disable_send_cache = false
+ status.compile_info.disable_inlining = false
+ status.compile_info.disable_const_cache = false
+ end
+ end
+
+ def using_ivar?(body)
+ pos = 0
+ while pos < body.iseq_size
+ insn = INSNS.fetch(C.rb_vm_insn_decode(body.iseq_encoded[pos]))
+ case insn.name
+ when :getinstancevariable, :setinstancevariable
+ return true
+ end
+ pos += insn.len
+ end
+ return false
+ end
+
+ # Expand simple macro that doesn't require dynamic C code.
+ def expand_simple_macros(arg_expr)
+ arg_expr.dup.tap do |expr|
+ # For `leave`. We can't proceed next ISeq in the same JIT function.
+ expr.gsub!(/^(?<indent>\s*)RESTORE_REGS\(\);\n/) do
+ indent = Regexp.last_match[:indent]
+ <<-end.gsub(/^ {12}/, '')
+ #if OPT_CALL_THREADED_CODE
+ #{indent}rb_ec_thread_ptr(ec)->retval = val;
+ #{indent}return 0;
+ #else
+ #{indent}return val;
+ #endif
+ end
+ end
+ expr.gsub!(/^(?<indent>\s*)NEXT_INSN\(\);\n/) do
+ indent = Regexp.last_match[:indent]
+ <<-end.gsub(/^ {12}/, '')
+ #{indent}UNREACHABLE_RETURN(Qundef);
+ end
+ end
+ end
+ end
+
+ def to_cstr(expr)
+ expr.gsub(/^(?!#)/, ' ') # indent everything but preprocessor lines
+ end
+
+ # Interpret unsigned long as signed long (VALUE -> OFFSET)
+ def cast_offset(offset)
+ if offset >= 1 << 8 * Fiddle::SIZEOF_VOIDP - 1 # negative
+ offset -= 1 << 8 * Fiddle::SIZEOF_VOIDP
+ end
+ offset
+ end
+
+ def captured_cc_entries(status)
+ status.compiled_iseq.mjit_unit.cc_entries + status.cc_entries_index
+ end
+
+ def call_data_index(cd, body)
+ cd - body.call_data
+ end
+
+ def vm_cc_cme(cc)
+ # TODO: add VM_ASSERT like actual vm_cc_cme
+ cc.cme_
+ end
+
+ def def_iseq_ptr(method_def)
+ C.rb_iseq_check(method_def.body.iseq.iseqptr)
+ end
+
+ def rb_mjit_iseq_compile_info(body)
+ body.mjit_unit.compile_info
+ end
+
+ def ISEQ_IS_SIZE(body)
+ body.ic_size + body.ivc_size + body.ise_size + body.icvarc_size
+ end
+
+ # Return true if an object of the class may be a special const (immediate).
+ # It's "maybe" because Integer and Float are not guaranteed to be an immediate.
+ # If this returns false, rb_class_of could be optimzied to RBASIC_CLASS.
+ def maybe_special_const?(klass)
+ [
+ C.rb_cFalseClass,
+ C.rb_cNilClass,
+ C.rb_cTrueClass,
+ C.rb_cInteger,
+ C.rb_cSymbol,
+ C.rb_cFloat,
+ ].include?(klass)
+ end
+
+ def has_valid_method_type?(cc)
+ vm_cc_cme(cc) != nil
+ end
+
+ def already_compiled?(status, pos)
+ status.stack_size_for_pos[pos] != C.NOT_COMPILED_STACK_SIZE
+ end
+
+ # Return an iseq pointer if cc has inlinable iseq.
+ def rb_mjit_inlinable_iseq(ci, cc)
+ if has_valid_method_type?(cc) &&
+ C.vm_ci_flag(ci) & C.VM_CALL_TAILCALL == 0 && # inlining only non-tailcall path
+ vm_cc_cme(cc).def.type == C.VM_METHOD_TYPE_ISEQ &&
+ C.fastpath_applied_iseq_p(ci, cc, iseq = def_iseq_ptr(vm_cc_cme(cc).def)) &&
+ inlinable_iseq_p(iseq.body) # CC_SET_FASTPATH in vm_callee_setup_arg
+ return iseq
+ end
+ return nil
+ end
+
+ # Return true if the ISeq can be inlined without pushing a new control frame.
+ def inlinable_iseq_p(body)
+ # 1) If catch_except_p, caller frame should be preserved when callee catches an exception.
+ # Then we need to wrap `vm_exec()` but then we can't inline the call inside it.
+ #
+ # 2) If `body->catch_except_p` is false and `handles_sp?` of an insn is false,
+ # sp is not moved as we assume `status->local_stack_p = !body->catch_except_p`.
+ #
+ # 3) If `body->catch_except_p` is false and `always_leaf?` of an insn is true,
+ # pc is not moved.
+ if body.catch_except_p
+ return false
+ end
+
+ pos = 0
+ while pos < body.iseq_size
+ insn = INSNS.fetch(C.rb_vm_insn_decode(body.iseq_encoded[pos]))
+ # All insns in the ISeq except `leave` (to be overridden in the inlined code)
+ # should meet following strong assumptions:
+ # * Do not require `cfp->sp` motion
+ # * Do not move `cfp->pc`
+ # * Do not read any `cfp->pc`
+ if insn.name == :invokebuiltin || insn.name == :opt_invokebuiltin_delegate || insn.name == :opt_invokebuiltin_delegate_leave
+ # builtin insn's inlinability is handled by `Primitive.attr! 'inline'` per iseq
+ if !body.builtin_inline_p
+ return false;
+ end
+ elsif insn.name != :leave && C.insn_may_depend_on_sp_or_pc(insn.bin, body.iseq_encoded + (pos + 1))
+ return false
+ end
+ # At this moment, `cfp->ep` in an inlined method is not working.
+ case insn.name
+ when :getlocal,
+ :getlocal_WC_0,
+ :getlocal_WC_1,
+ :setlocal,
+ :setlocal_WC_0,
+ :setlocal_WC_1,
+ :getblockparam,
+ :getblockparamproxy,
+ :setblockparam
+ return false
+ end
+ pos += insn.len
+ end
+ return true
+ end
+
+ # CPointer::Struct could be nil on field reference, and this is a helper to
+ # handle that case while using CPointer::Struct#to_s in most cases.
+ # @param struct [RubyVM::MJIT::CPointer::Struct]
+ def to_addr(struct)
+ struct&.to_s || 'NULL'
+ end
+
+ def parent_shape_id(shape_id)
+ return shape_id if shape_id == C.INVALID_SHAPE_ID
+
+ parent_id = C.rb_shape_get_shape_by_id(shape_id).parent_id
+ parent = C.rb_shape_get_shape_by_id(parent_id)
+
+ if parent.type == C.SHAPE_CAPACITY_CHANGE
+ parent.parent_id
+ else
+ parent_id
+ end
+ end
+end
diff --git a/lib/ruby_vm/mjit/hooks.rb b/lib/ruby_vm/mjit/hooks.rb
new file mode 100644
index 0000000000..3fb1004111
--- /dev/null
+++ b/lib/ruby_vm/mjit/hooks.rb
@@ -0,0 +1,32 @@
+module RubyVM::MJIT::Hooks # :nodoc: all
+ C = RubyVM::MJIT.const_get(:C, false)
+
+ def self.on_bop_redefined(_redefined_flag, _bop)
+ C.mjit_cancel_all("BOP is redefined")
+ end
+
+ def self.on_cme_invalidate(_cme)
+ # to be used later
+ end
+
+ def self.on_ractor_spawn
+ C.mjit_cancel_all("Ractor is spawned")
+ end
+
+ def self.on_constant_state_changed(_id)
+ # to be used later
+ end
+
+ def self.on_constant_ic_update(_iseq, _ic, _insn_idx)
+ # to be used later
+ end
+
+ def self.on_tracing_invalidate_all(new_iseq_events)
+ # Stop calling all JIT-ed code. We can't rewrite existing JIT-ed code to trace_ insns for now.
+ # :class events are triggered only in ISEQ_TYPE_CLASS, but mjit_target_iseq_p ignores such iseqs.
+ # Thus we don't need to cancel JIT-ed code for :class events.
+ if new_iseq_events != C.RUBY_EVENT_CLASS
+ C.mjit_cancel_all("TracePoint is enabled")
+ end
+ end
+end
diff --git a/lib/ruby_vm/rjit/.document b/lib/ruby_vm/rjit/.document
deleted file mode 100644
index 0a603afe3d..0000000000
--- a/lib/ruby_vm/rjit/.document
+++ /dev/null
@@ -1 +0,0 @@
-stats.rb
diff --git a/lib/ruby_vm/rjit/assembler.rb b/lib/ruby_vm/rjit/assembler.rb
deleted file mode 100644
index 645072d11b..0000000000
--- a/lib/ruby_vm/rjit/assembler.rb
+++ /dev/null
@@ -1,1140 +0,0 @@
-# frozen_string_literal: true
-module RubyVM::RJIT
- # 8-bit memory access
- class BytePtr < Data.define(:reg, :disp); end
-
- # 32-bit memory access
- class DwordPtr < Data.define(:reg, :disp); end
-
- # 64-bit memory access
- QwordPtr = Array
-
- # SystemV x64 calling convention
- C_ARGS = [:rdi, :rsi, :rdx, :rcx, :r8, :r9]
- C_RET = :rax
-
- # https://cdrdv2.intel.com/v1/dl/getContent/671110
- # Mostly an x86_64 assembler, but this also has some stuff that is useful for any architecture.
- class Assembler
- # rel8 jumps are made with labels
- class Label < Data.define(:id, :name); end
-
- # rel32 is inserted as [Rel32, Rel32Pad..] and converted on #resolve_rel32
- class Rel32 < Data.define(:addr); end
- Rel32Pad = Object.new
-
- # A set of ModR/M values encoded on #insn
- class ModRM < Data.define(:mod, :reg, :rm); end
- Mod00 = 0b00 # Mod 00: [reg]
- Mod01 = 0b01 # Mod 01: [reg]+disp8
- Mod10 = 0b10 # Mod 10: [reg]+disp32
- Mod11 = 0b11 # Mod 11: reg
-
- # REX = 0100WR0B
- REX_B = 0b01000001
- REX_R = 0b01000100
- REX_W = 0b01001000
-
- # Operand matchers
- R32 = -> (op) { op.is_a?(Symbol) && r32?(op) }
- R64 = -> (op) { op.is_a?(Symbol) && r64?(op) }
- IMM8 = -> (op) { op.is_a?(Integer) && imm8?(op) }
- IMM32 = -> (op) { op.is_a?(Integer) && imm32?(op) }
- IMM64 = -> (op) { op.is_a?(Integer) && imm64?(op) }
-
- def initialize
- @bytes = []
- @labels = {}
- @label_id = 0
- @comments = Hash.new { |h, k| h[k] = [] }
- @blocks = Hash.new { |h, k| h[k] = [] }
- @stub_starts = Hash.new { |h, k| h[k] = [] }
- @stub_ends = Hash.new { |h, k| h[k] = [] }
- @pos_markers = Hash.new { |h, k| h[k] = [] }
- end
-
- def assemble(addr)
- set_code_addrs(addr)
- resolve_rel32(addr)
- resolve_labels
-
- write_bytes(addr)
-
- @pos_markers.each do |write_pos, markers|
- markers.each { |marker| marker.call(addr + write_pos) }
- end
- @bytes.size
- ensure
- @bytes.clear
- end
-
- def size
- @bytes.size
- end
-
- #
- # Instructions
- #
-
- def add(dst, src)
- case [dst, src]
- # ADD r/m64, imm8 (Mod 00: [reg])
- in [QwordPtr[R64 => dst_reg], IMM8 => src_imm]
- # REX.W + 83 /0 ib
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod00, reg: 0, rm: dst_reg],
- imm: imm8(src_imm),
- )
- # ADD r/m64, imm8 (Mod 11: reg)
- in [R64 => dst_reg, IMM8 => src_imm]
- # REX.W + 83 /0 ib
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod11, reg: 0, rm: dst_reg],
- imm: imm8(src_imm),
- )
- # ADD r/m64 imm32 (Mod 11: reg)
- in [R64 => dst_reg, IMM32 => src_imm]
- # REX.W + 81 /0 id
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x81,
- mod_rm: ModRM[mod: Mod11, reg: 0, rm: dst_reg],
- imm: imm32(src_imm),
- )
- # ADD r/m64, r64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 01 /r
- # MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x01,
- mod_rm: ModRM[mod: Mod11, reg: src_reg, rm: dst_reg],
- )
- end
- end
-
- def and(dst, src)
- case [dst, src]
- # AND r/m64, imm8 (Mod 11: reg)
- in [R64 => dst_reg, IMM8 => src_imm]
- # REX.W + 83 /4 ib
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg],
- imm: imm8(src_imm),
- )
- # AND r/m64, imm32 (Mod 11: reg)
- in [R64 => dst_reg, IMM32 => src_imm]
- # REX.W + 81 /4 id
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x81,
- mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg],
- imm: imm32(src_imm),
- )
- # AND r64, r/m64 (Mod 01: [reg]+disp8)
- in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
- # REX.W + 23 /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x23,
- mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
- disp: imm8(src_disp),
- )
- end
- end
-
- def call(dst)
- case dst
- # CALL rel32
- in Integer => dst_addr
- # E8 cd
- # D: Operand 1: Offset
- insn(opcode: 0xe8, imm: rel32(dst_addr))
- # CALL r/m64 (Mod 11: reg)
- in R64 => dst_reg
- # FF /2
- # M: Operand 1: ModRM:r/m (r)
- insn(
- opcode: 0xff,
- mod_rm: ModRM[mod: Mod11, reg: 2, rm: dst_reg],
- )
- end
- end
-
- def cmove(dst, src)
- case [dst, src]
- # CMOVE r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 44 /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x44],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovg(dst, src)
- case [dst, src]
- # CMOVG r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 4F /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x4f],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovge(dst, src)
- case [dst, src]
- # CMOVGE r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 4D /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x4d],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovl(dst, src)
- case [dst, src]
- # CMOVL r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 4C /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x4c],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovle(dst, src)
- case [dst, src]
- # CMOVLE r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 4E /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x4e],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovne(dst, src)
- case [dst, src]
- # CMOVNE r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 45 /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x45],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovnz(dst, src)
- case [dst, src]
- # CMOVNZ r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 45 /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x45],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- end
- end
-
- def cmovz(dst, src)
- case [dst, src]
- # CMOVZ r64, r/m64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 0F 44 /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x44],
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- # CMOVZ r64, r/m64 (Mod 01: [reg]+disp8)
- in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
- # REX.W + 0F 44 /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: [0x0f, 0x44],
- mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
- disp: imm8(src_disp),
- )
- end
- end
-
- def cmp(left, right)
- case [left, right]
- # CMP r/m8, imm8 (Mod 01: [reg]+disp8)
- in [BytePtr[R64 => left_reg, IMM8 => left_disp], IMM8 => right_imm]
- # 80 /7 ib
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- opcode: 0x80,
- mod_rm: ModRM[mod: Mod01, reg: 7, rm: left_reg],
- disp: left_disp,
- imm: imm8(right_imm),
- )
- # CMP r/m32, imm32 (Mod 01: [reg]+disp8)
- in [DwordPtr[R64 => left_reg, IMM8 => left_disp], IMM32 => right_imm]
- # 81 /7 id
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- opcode: 0x81,
- mod_rm: ModRM[mod: Mod01, reg: 7, rm: left_reg],
- disp: left_disp,
- imm: imm32(right_imm),
- )
- # CMP r/m64, imm8 (Mod 01: [reg]+disp8)
- in [QwordPtr[R64 => left_reg, IMM8 => left_disp], IMM8 => right_imm]
- # REX.W + 83 /7 ib
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod01, reg: 7, rm: left_reg],
- disp: left_disp,
- imm: imm8(right_imm),
- )
- # CMP r/m64, imm32 (Mod 01: [reg]+disp8)
- in [QwordPtr[R64 => left_reg, IMM8 => left_disp], IMM32 => right_imm]
- # REX.W + 81 /7 id
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x81,
- mod_rm: ModRM[mod: Mod01, reg: 7, rm: left_reg],
- disp: left_disp,
- imm: imm32(right_imm),
- )
- # CMP r/m64, imm8 (Mod 10: [reg]+disp32)
- in [QwordPtr[R64 => left_reg, IMM32 => left_disp], IMM8 => right_imm]
- # REX.W + 83 /7 ib
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod10, reg: 7, rm: left_reg],
- disp: imm32(left_disp),
- imm: imm8(right_imm),
- )
- # CMP r/m64, imm8 (Mod 11: reg)
- in [R64 => left_reg, IMM8 => right_imm]
- # REX.W + 83 /7 ib
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod11, reg: 7, rm: left_reg],
- imm: imm8(right_imm),
- )
- # CMP r/m64, imm32 (Mod 11: reg)
- in [R64 => left_reg, IMM32 => right_imm]
- # REX.W + 81 /7 id
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x81,
- mod_rm: ModRM[mod: Mod11, reg: 7, rm: left_reg],
- imm: imm32(right_imm),
- )
- # CMP r/m64, r64 (Mod 01: [reg]+disp8)
- in [QwordPtr[R64 => left_reg, IMM8 => left_disp], R64 => right_reg]
- # REX.W + 39 /r
- # MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x39,
- mod_rm: ModRM[mod: Mod01, reg: right_reg, rm: left_reg],
- disp: left_disp,
- )
- # CMP r/m64, r64 (Mod 10: [reg]+disp32)
- in [QwordPtr[R64 => left_reg, IMM32 => left_disp], R64 => right_reg]
- # REX.W + 39 /r
- # MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x39,
- mod_rm: ModRM[mod: Mod10, reg: right_reg, rm: left_reg],
- disp: imm32(left_disp),
- )
- # CMP r/m64, r64 (Mod 11: reg)
- in [R64 => left_reg, R64 => right_reg]
- # REX.W + 39 /r
- # MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x39,
- mod_rm: ModRM[mod: Mod11, reg: right_reg, rm: left_reg],
- )
- end
- end
-
- def jbe(dst)
- case dst
- # JBE rel8
- in Label => dst_label
- # 76 cb
- insn(opcode: 0x76, imm: dst_label)
- # JBE rel32
- in Integer => dst_addr
- # 0F 86 cd
- insn(opcode: [0x0f, 0x86], imm: rel32(dst_addr))
- end
- end
-
- def je(dst)
- case dst
- # JE rel8
- in Label => dst_label
- # 74 cb
- insn(opcode: 0x74, imm: dst_label)
- # JE rel32
- in Integer => dst_addr
- # 0F 84 cd
- insn(opcode: [0x0f, 0x84], imm: rel32(dst_addr))
- end
- end
-
- def jl(dst)
- case dst
- # JL rel32
- in Integer => dst_addr
- # 0F 8C cd
- insn(opcode: [0x0f, 0x8c], imm: rel32(dst_addr))
- end
- end
-
- def jmp(dst)
- case dst
- # JZ rel8
- in Label => dst_label
- # EB cb
- insn(opcode: 0xeb, imm: dst_label)
- # JMP rel32
- in Integer => dst_addr
- # E9 cd
- insn(opcode: 0xe9, imm: rel32(dst_addr))
- # JMP r/m64 (Mod 01: [reg]+disp8)
- in QwordPtr[R64 => dst_reg, IMM8 => dst_disp]
- # FF /4
- insn(opcode: 0xff, mod_rm: ModRM[mod: Mod01, reg: 4, rm: dst_reg], disp: dst_disp)
- # JMP r/m64 (Mod 11: reg)
- in R64 => dst_reg
- # FF /4
- insn(opcode: 0xff, mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg])
- end
- end
-
- def jne(dst)
- case dst
- # JNE rel8
- in Label => dst_label
- # 75 cb
- insn(opcode: 0x75, imm: dst_label)
- # JNE rel32
- in Integer => dst_addr
- # 0F 85 cd
- insn(opcode: [0x0f, 0x85], imm: rel32(dst_addr))
- end
- end
-
- def jnz(dst)
- case dst
- # JE rel8
- in Label => dst_label
- # 75 cb
- insn(opcode: 0x75, imm: dst_label)
- # JNZ rel32
- in Integer => dst_addr
- # 0F 85 cd
- insn(opcode: [0x0f, 0x85], imm: rel32(dst_addr))
- end
- end
-
- def jo(dst)
- case dst
- # JO rel32
- in Integer => dst_addr
- # 0F 80 cd
- insn(opcode: [0x0f, 0x80], imm: rel32(dst_addr))
- end
- end
-
- def jz(dst)
- case dst
- # JZ rel8
- in Label => dst_label
- # 74 cb
- insn(opcode: 0x74, imm: dst_label)
- # JZ rel32
- in Integer => dst_addr
- # 0F 84 cd
- insn(opcode: [0x0f, 0x84], imm: rel32(dst_addr))
- end
- end
-
- def lea(dst, src)
- case [dst, src]
- # LEA r64,m (Mod 01: [reg]+disp8)
- in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
- # REX.W + 8D /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x8d,
- mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
- disp: imm8(src_disp),
- )
- # LEA r64,m (Mod 10: [reg]+disp32)
- in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM32 => src_disp]]
- # REX.W + 8D /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x8d,
- mod_rm: ModRM[mod: Mod10, reg: dst_reg, rm: src_reg],
- disp: imm32(src_disp),
- )
- end
- end
-
- def mov(dst, src)
- case dst
- in R32 => dst_reg
- case src
- # MOV r32 r/m32 (Mod 01: [reg]+disp8)
- in DwordPtr[R64 => src_reg, IMM8 => src_disp]
- # 8B /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- opcode: 0x8b,
- mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
- disp: src_disp,
- )
- # MOV r32, imm32 (Mod 11: reg)
- in IMM32 => src_imm
- # B8+ rd id
- # OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
- insn(
- opcode: 0xb8,
- rd: dst_reg,
- imm: imm32(src_imm),
- )
- end
- in R64 => dst_reg
- case src
- # MOV r64, r/m64 (Mod 00: [reg])
- in QwordPtr[R64 => src_reg]
- # REX.W + 8B /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x8b,
- mod_rm: ModRM[mod: Mod00, reg: dst_reg, rm: src_reg],
- )
- # MOV r64, r/m64 (Mod 01: [reg]+disp8)
- in QwordPtr[R64 => src_reg, IMM8 => src_disp]
- # REX.W + 8B /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x8b,
- mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
- disp: src_disp,
- )
- # MOV r64, r/m64 (Mod 10: [reg]+disp32)
- in QwordPtr[R64 => src_reg, IMM32 => src_disp]
- # REX.W + 8B /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x8b,
- mod_rm: ModRM[mod: Mod10, reg: dst_reg, rm: src_reg],
- disp: imm32(src_disp),
- )
- # MOV r64, r/m64 (Mod 11: reg)
- in R64 => src_reg
- # REX.W + 8B /r
- # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x8b,
- mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
- )
- # MOV r/m64, imm32 (Mod 11: reg)
- in IMM32 => src_imm
- # REX.W + C7 /0 id
- # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
- insn(
- prefix: REX_W,
- opcode: 0xc7,
- mod_rm: ModRM[mod: Mod11, reg: 0, rm: dst_reg],
- imm: imm32(src_imm),
- )
- # MOV r64, imm64
- in IMM64 => src_imm
- # REX.W + B8+ rd io
- # OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
- insn(
- prefix: REX_W,
- opcode: 0xb8,
- rd: dst_reg,
- imm: imm64(src_imm),
- )
- end
- in DwordPtr[R64 => dst_reg, IMM8 => dst_disp]
- case src
- # MOV r/m32, imm32 (Mod 01: [reg]+disp8)
- in IMM32 => src_imm
- # C7 /0 id
- # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
- insn(
- opcode: 0xc7,
- mod_rm: ModRM[mod: Mod01, reg: 0, rm: dst_reg],
- disp: dst_disp,
- imm: imm32(src_imm),
- )
- end
- in QwordPtr[R64 => dst_reg]
- case src
- # MOV r/m64, imm32 (Mod 00: [reg])
- in IMM32 => src_imm
- # REX.W + C7 /0 id
- # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
- insn(
- prefix: REX_W,
- opcode: 0xc7,
- mod_rm: ModRM[mod: Mod00, reg: 0, rm: dst_reg],
- imm: imm32(src_imm),
- )
- # MOV r/m64, r64 (Mod 00: [reg])
- in R64 => src_reg
- # REX.W + 89 /r
- # MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x89,
- mod_rm: ModRM[mod: Mod00, reg: src_reg, rm: dst_reg],
- )
- end
- in QwordPtr[R64 => dst_reg, IMM8 => dst_disp]
- # Optimize encoding when disp is 0
- return mov([dst_reg], src) if dst_disp == 0
-
- case src
- # MOV r/m64, imm32 (Mod 01: [reg]+disp8)
- in IMM32 => src_imm
- # REX.W + C7 /0 id
- # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
- insn(
- prefix: REX_W,
- opcode: 0xc7,
- mod_rm: ModRM[mod: Mod01, reg: 0, rm: dst_reg],
- disp: dst_disp,
- imm: imm32(src_imm),
- )
- # MOV r/m64, r64 (Mod 01: [reg]+disp8)
- in R64 => src_reg
- # REX.W + 89 /r
- # MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x89,
- mod_rm: ModRM[mod: Mod01, reg: src_reg, rm: dst_reg],
- disp: dst_disp,
- )
- end
- in QwordPtr[R64 => dst_reg, IMM32 => dst_disp]
- case src
- # MOV r/m64, imm32 (Mod 10: [reg]+disp32)
- in IMM32 => src_imm
- # REX.W + C7 /0 id
- # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
- insn(
- prefix: REX_W,
- opcode: 0xc7,
- mod_rm: ModRM[mod: Mod10, reg: 0, rm: dst_reg],
- disp: imm32(dst_disp),
- imm: imm32(src_imm),
- )
- # MOV r/m64, r64 (Mod 10: [reg]+disp32)
- in R64 => src_reg
- # REX.W + 89 /r
- # MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x89,
- mod_rm: ModRM[mod: Mod10, reg: src_reg, rm: dst_reg],
- disp: imm32(dst_disp),
- )
- end
- end
- end
-
- def or(dst, src)
- case [dst, src]
- # OR r/m64, imm8 (Mod 11: reg)
- in [R64 => dst_reg, IMM8 => src_imm]
- # REX.W + 83 /1 ib
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod11, reg: 1, rm: dst_reg],
- imm: imm8(src_imm),
- )
- # OR r/m64, imm32 (Mod 11: reg)
- in [R64 => dst_reg, IMM32 => src_imm]
- # REX.W + 81 /1 id
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x81,
- mod_rm: ModRM[mod: Mod11, reg: 1, rm: dst_reg],
- imm: imm32(src_imm),
- )
- # OR r64, r/m64 (Mod 01: [reg]+disp8)
- in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
- # REX.W + 0B /r
- # RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
- insn(
- prefix: REX_W,
- opcode: 0x0b,
- mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
- disp: imm8(src_disp),
- )
- end
- end
-
- def push(src)
- case src
- # PUSH r64
- in R64 => src_reg
- # 50+rd
- # O: Operand 1: opcode + rd (r)
- insn(opcode: 0x50, rd: src_reg)
- end
- end
-
- def pop(dst)
- case dst
- # POP r64
- in R64 => dst_reg
- # 58+ rd
- # O: Operand 1: opcode + rd (r)
- insn(opcode: 0x58, rd: dst_reg)
- end
- end
-
- def ret
- # RET
- # Near return: A return to a procedure within the current code segment
- insn(opcode: 0xc3)
- end
-
- def sar(dst, src)
- case [dst, src]
- in [R64 => dst_reg, IMM8 => src_imm]
- # REX.W + C1 /7 ib
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8
- insn(
- prefix: REX_W,
- opcode: 0xc1,
- mod_rm: ModRM[mod: Mod11, reg: 7, rm: dst_reg],
- imm: imm8(src_imm),
- )
- end
- end
-
- def sub(dst, src)
- case [dst, src]
- # SUB r/m64, imm8 (Mod 11: reg)
- in [R64 => dst_reg, IMM8 => src_imm]
- # REX.W + 83 /5 ib
- # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0x83,
- mod_rm: ModRM[mod: Mod11, reg: 5, rm: dst_reg],
- imm: imm8(src_imm),
- )
- # SUB r/m64, r64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 29 /r
- # MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x29,
- mod_rm: ModRM[mod: Mod11, reg: src_reg, rm: dst_reg],
- )
- end
- end
-
- def test(left, right)
- case [left, right]
- # TEST r/m8*, imm8 (Mod 01: [reg]+disp8)
- in [BytePtr[R64 => left_reg, IMM8 => left_disp], IMM8 => right_imm]
- # REX + F6 /0 ib
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- opcode: 0xf6,
- mod_rm: ModRM[mod: Mod01, reg: 0, rm: left_reg],
- disp: left_disp,
- imm: imm8(right_imm),
- )
- # TEST r/m64, imm32 (Mod 01: [reg]+disp8)
- in [QwordPtr[R64 => left_reg, IMM8 => left_disp], IMM32 => right_imm]
- # REX.W + F7 /0 id
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0xf7,
- mod_rm: ModRM[mod: Mod01, reg: 0, rm: left_reg],
- disp: left_disp,
- imm: imm32(right_imm),
- )
- # TEST r/m64, imm32 (Mod 10: [reg]+disp32)
- in [QwordPtr[R64 => left_reg, IMM32 => left_disp], IMM32 => right_imm]
- # REX.W + F7 /0 id
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0xf7,
- mod_rm: ModRM[mod: Mod10, reg: 0, rm: left_reg],
- disp: imm32(left_disp),
- imm: imm32(right_imm),
- )
- # TEST r/m64, imm32 (Mod 11: reg)
- in [R64 => left_reg, IMM32 => right_imm]
- # REX.W + F7 /0 id
- # MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
- insn(
- prefix: REX_W,
- opcode: 0xf7,
- mod_rm: ModRM[mod: Mod11, reg: 0, rm: left_reg],
- imm: imm32(right_imm),
- )
- # TEST r/m32, r32 (Mod 11: reg)
- in [R32 => left_reg, R32 => right_reg]
- # 85 /r
- # MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
- insn(
- opcode: 0x85,
- mod_rm: ModRM[mod: Mod11, reg: right_reg, rm: left_reg],
- )
- # TEST r/m64, r64 (Mod 11: reg)
- in [R64 => left_reg, R64 => right_reg]
- # REX.W + 85 /r
- # MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x85,
- mod_rm: ModRM[mod: Mod11, reg: right_reg, rm: left_reg],
- )
- end
- end
-
- def xor(dst, src)
- case [dst, src]
- # XOR r/m64, r64 (Mod 11: reg)
- in [R64 => dst_reg, R64 => src_reg]
- # REX.W + 31 /r
- # MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
- insn(
- prefix: REX_W,
- opcode: 0x31,
- mod_rm: ModRM[mod: Mod11, reg: src_reg, rm: dst_reg],
- )
- end
- end
-
- #
- # Utilities
- #
-
- attr_reader :comments
-
- def comment(message)
- @comments[@bytes.size] << message
- end
-
- # Mark the starting address of a block
- def block(block)
- @blocks[@bytes.size] << block
- end
-
- # Mark the starting/ending addresses of a stub
- def stub(stub)
- @stub_starts[@bytes.size] << stub
- yield
- ensure
- @stub_ends[@bytes.size] << stub
- end
-
- def pos_marker(&block)
- @pos_markers[@bytes.size] << block
- end
-
- def new_label(name)
- Label.new(id: @label_id += 1, name:)
- end
-
- # @param [RubyVM::RJIT::Assembler::Label] label
- def write_label(label)
- @labels[label] = @bytes.size
- end
-
- def incr_counter(name)
- if C.rjit_opts.stats
- comment("increment counter #{name}")
- mov(:rax, C.rb_rjit_counters[name].to_i)
- add([:rax], 1) # TODO: lock
- end
- end
-
- private
-
- def insn(prefix: 0, opcode:, rd: nil, mod_rm: nil, disp: nil, imm: nil)
- # Determine prefix
- if rd
- prefix |= REX_B if extended_reg?(rd)
- opcode += reg_code(rd)
- end
- if mod_rm
- prefix |= REX_R if mod_rm.reg.is_a?(Symbol) && extended_reg?(mod_rm.reg)
- prefix |= REX_B if mod_rm.rm.is_a?(Symbol) && extended_reg?(mod_rm.rm)
- end
-
- # Encode insn
- if prefix > 0
- @bytes.push(prefix)
- end
- @bytes.push(*Array(opcode))
- if mod_rm
- mod_rm_byte = encode_mod_rm(
- mod: mod_rm.mod,
- reg: mod_rm.reg.is_a?(Symbol) ? reg_code(mod_rm.reg) : mod_rm.reg,
- rm: mod_rm.rm.is_a?(Symbol) ? reg_code(mod_rm.rm) : mod_rm.rm,
- )
- @bytes.push(mod_rm_byte)
- end
- if disp
- @bytes.push(*Array(disp))
- end
- if imm
- @bytes.push(*imm)
- end
- end
-
- def reg_code(reg)
- reg_code_extended(reg).first
- end
-
- # Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte
- #
- # 7 6 5 4 3 2 1 0
- # +--+--+--+--+--+--+--+--+
- # | Mod | Reg/ | R/M |
- # | | Opcode | |
- # +--+--+--+--+--+--+--+--+
- #
- # The r/m field can specify a register as an operand or it can be combined
- # with the mod field to encode an addressing mode.
- #
- # /0: R/M is 0 (not used)
- # /r: R/M is a register
- def encode_mod_rm(mod:, reg: 0, rm: 0)
- if mod > 0b11
- raise ArgumentError, "too large Mod: #{mod}"
- end
- if reg > 0b111
- raise ArgumentError, "too large Reg/Opcode: #{reg}"
- end
- if rm > 0b111
- raise ArgumentError, "too large R/M: #{rm}"
- end
- (mod << 6) + (reg << 3) + rm
- end
-
- # ib: 1 byte
- def imm8(imm)
- unless imm8?(imm)
- raise ArgumentError, "unexpected imm8: #{imm}"
- end
- [imm].pack('c').unpack('c*') # TODO: consider uimm
- end
-
- # id: 4 bytes
- def imm32(imm)
- unless imm32?(imm)
- raise ArgumentError, "unexpected imm32: #{imm}"
- end
- [imm].pack('l').unpack('c*') # TODO: consider uimm
- end
-
- # io: 8 bytes
- def imm64(imm)
- unless imm64?(imm)
- raise ArgumentError, "unexpected imm64: #{imm}"
- end
- imm_bytes(imm, 8)
- end
-
- def imm_bytes(imm, num_bytes)
- bytes = []
- bits = imm
- num_bytes.times do
- bytes << (bits & 0xff)
- bits >>= 8
- end
- if bits != 0
- raise ArgumentError, "unexpected imm with #{num_bytes} bytes: #{imm}"
- end
- bytes
- end
-
- def rel32(addr)
- [Rel32.new(addr), Rel32Pad, Rel32Pad, Rel32Pad]
- end
-
- def set_code_addrs(write_addr)
- (@bytes.size + 1).times do |index|
- @blocks.fetch(index, []).each do |block|
- block.start_addr = write_addr + index
- end
- @stub_starts.fetch(index, []).each do |stub|
- stub.start_addr = write_addr + index
- end
- @stub_ends.fetch(index, []).each do |stub|
- stub.end_addr = write_addr + index
- end
- end
- end
-
- def resolve_rel32(write_addr)
- @bytes.each_with_index do |byte, index|
- if byte.is_a?(Rel32)
- src_addr = write_addr + index + 4 # offset 4 bytes for rel32 itself
- dst_addr = byte.addr
- rel32 = dst_addr - src_addr
- raise "unexpected offset: #{rel32}" unless imm32?(rel32)
- imm32(rel32).each_with_index do |rel_byte, rel_index|
- @bytes[index + rel_index] = rel_byte
- end
- end
- end
- end
-
- def resolve_labels
- @bytes.each_with_index do |byte, index|
- if byte.is_a?(Label)
- src_index = index + 1 # offset 1 byte for rel8 itself
- dst_index = @labels.fetch(byte)
- rel8 = dst_index - src_index
- raise "unexpected offset: #{rel8}" unless imm8?(rel8)
- @bytes[index] = rel8
- end
- end
- end
-
- def write_bytes(addr)
- Fiddle::Pointer.new(addr)[0, @bytes.size] = @bytes.pack('c*')
- end
- end
-
- module OperandMatcher
- def imm8?(imm)
- (-0x80..0x7f).include?(imm)
- end
-
- def imm32?(imm)
- (-0x8000_0000..0x7fff_ffff).include?(imm) # TODO: consider uimm
- end
-
- def imm64?(imm)
- (-0x8000_0000_0000_0000..0xffff_ffff_ffff_ffff).include?(imm)
- end
-
- def r32?(reg)
- if extended_reg?(reg)
- reg.end_with?('d')
- else
- reg.start_with?('e')
- end
- end
-
- def r64?(reg)
- if extended_reg?(reg)
- reg.match?(/\Ar\d+\z/)
- else
- reg.start_with?('r')
- end
- end
-
- def extended_reg?(reg)
- reg_code_extended(reg).last
- end
-
- def reg_code_extended(reg)
- case reg
- # Not extended
- when :al, :ax, :eax, :rax then [0, false]
- when :cl, :cx, :ecx, :rcx then [1, false]
- when :dl, :dx, :edx, :rdx then [2, false]
- when :bl, :bx, :ebx, :rbx then [3, false]
- when :ah, :sp, :esp, :rsp then [4, false]
- when :ch, :bp, :ebp, :rbp then [5, false]
- when :dh, :si, :esi, :rsi then [6, false]
- when :bh, :di, :edi, :rdi then [7, false]
- # Extended
- when :r8b, :r8w, :r8d, :r8 then [0, true]
- when :r9b, :r9w, :r9d, :r9 then [1, true]
- when :r10b, :r10w, :r10d, :r10 then [2, true]
- when :r11b, :r11w, :r11d, :r11 then [3, true]
- when :r12b, :r12w, :r12d, :r12 then [4, true]
- when :r13b, :r13w, :r13d, :r13 then [5, true]
- when :r14b, :r14w, :r14d, :r14 then [6, true]
- when :r15b, :r15w, :r15d, :r15 then [7, true]
- else raise ArgumentError, "unexpected reg: #{reg.inspect}"
- end
- end
- end
-
- class Assembler
- include OperandMatcher
- extend OperandMatcher
- end
-end
diff --git a/lib/ruby_vm/rjit/block.rb b/lib/ruby_vm/rjit/block.rb
deleted file mode 100644
index cfdaade8b1..0000000000
--- a/lib/ruby_vm/rjit/block.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class RubyVM::RJIT::Block < Struct.new(
- :iseq, # @param ``
- :pc, # @param [Integer] Starting PC
- :ctx, # @param [RubyVM::RJIT::Context] **Starting** Context (TODO: freeze?)
- :start_addr, # @param [Integer] Starting address of this block's JIT code
- :entry_exit, # @param [Integer] Address of entry exit (optional)
- :incoming, # @param [Array<RubyVM::RJIT::BranchStub>] Incoming branches
- :invalidated, # @param [TrueClass,FalseClass] true if already invalidated
-)
- def initialize(incoming: [], invalidated: false, **) = super
-end
diff --git a/lib/ruby_vm/rjit/branch_stub.rb b/lib/ruby_vm/rjit/branch_stub.rb
deleted file mode 100644
index b9fe78b744..0000000000
--- a/lib/ruby_vm/rjit/branch_stub.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module RubyVM::RJIT
- # Branch shapes
- Next0 = :Next0 # target0 is a fallthrough
- Next1 = :Next1 # target1 is a fallthrough
- Default = :Default # neither targets is a fallthrough
-
- class BranchStub < Struct.new(
- :iseq, # @param [RubyVM::RJIT::CPointer::Struct_rb_iseq_struct] Branch target ISEQ
- :shape, # @param [Symbol] Next0, Next1, or Default
- :target0, # @param [RubyVM::RJIT::BranchTarget] First branch target
- :target1, # @param [RubyVM::RJIT::BranchTarget,NilClass] Second branch target (optional)
- :compile, # @param [Proc] A callback to (re-)generate this branch stub
- :start_addr, # @param [Integer] Stub source start address to be re-generated
- :end_addr, # @param [Integer] Stub source end address to be re-generated
- )
- end
-
- class BranchTarget < Struct.new(
- :pc,
- :ctx,
- :address,
- )
- end
-end
diff --git a/lib/ruby_vm/rjit/c_pointer.rb b/lib/ruby_vm/rjit/c_pointer.rb
deleted file mode 100644
index db00c4cd11..0000000000
--- a/lib/ruby_vm/rjit/c_pointer.rb
+++ /dev/null
@@ -1,394 +0,0 @@
-module RubyVM::RJIT
- # Every class under this namespace is a pointer. Even if the type is
- # immediate, it shouldn't be dereferenced until `*` is called.
- module CPointer
- # Note: We'd like to avoid alphabetic method names to avoid a conflict
- # with member methods. to_i and to_s are considered an exception.
- class Struct
- # @param name [String]
- # @param sizeof [Integer]
- # @param members [Hash{ Symbol => [RubyVM::RJIT::CType::*, Integer, TrueClass] }]
- def initialize(addr, sizeof, members)
- @addr = addr
- @sizeof = sizeof
- @members = members
- end
-
- # Get a raw address
- def to_i
- @addr
- end
-
- # Serialized address for generated code
- def to_s
- "0x#{@addr.to_s(16)}"
- end
-
- # Pointer diff
- def -(struct)
- raise ArgumentError if self.class != struct.class
- (@addr - struct.to_i) / @sizeof
- end
-
- # Primitive API that does no automatic dereference
- # TODO: remove this?
- # @param member [Symbol]
- def [](member)
- type, offset = @members.fetch(member)
- type.new(@addr + offset / 8)
- end
-
- private
-
- # @param member [Symbol]
- # @param value [Object]
- def []=(member, value)
- type, offset = @members.fetch(member)
- type[@addr + offset / 8] = value
- end
-
- # @param size [Integer]
- # @param members [Hash{ Symbol => [Integer, RubyVM::RJIT::CType::*] }]
- def self.define(size, members)
- Class.new(self) do
- # Return the size of this type
- define_singleton_method(:size) { size }
-
- # Return the offset to a field
- define_singleton_method(:offsetof) do |field, *fields|
- member, offset = members.fetch(field)
- offset /= 8
- unless fields.empty?
- offset += member.offsetof(*fields)
- end
- offset
- end
-
- # Return member names
- define_singleton_method(:members) { members.keys }
-
- define_method(:initialize) do |addr = nil|
- if addr.nil? # TODO: get rid of this feature later
- addr = Fiddle.malloc(size)
- end
- super(addr, size, members)
- end
-
- members.each do |member, (type, offset, to_ruby)|
- # Intelligent API that does automatic dereference
- define_method(member) do
- value = self[member]
- if value.respond_to?(:*)
- value = value.*
- end
- if to_ruby
- value = C.to_ruby(value)
- end
- value
- end
-
- define_method("#{member}=") do |value|
- if to_ruby
- value = C.to_value(value)
- end
- self[member] = value
- end
- end
- end
- end
- end
-
- # Note: We'd like to avoid alphabetic method names to avoid a conflict
- # with member methods. to_i is considered an exception.
- class Union
- # @param _name [String] To be used when it starts defining a union pointer class
- # @param sizeof [Integer]
- # @param members [Hash{ Symbol => RubyVM::RJIT::CType::* }]
- def initialize(addr, sizeof, members)
- @addr = addr
- @sizeof = sizeof
- @members = members
- end
-
- # Get a raw address
- def to_i
- @addr
- end
-
- # Move addr to access this pointer like an array
- def +(index)
- raise ArgumentError unless index.is_a?(Integer)
- self.class.new(@addr + index * @sizeof)
- end
-
- # Pointer diff
- def -(union)
- raise ArgumentError if self.class != union.class
- (@addr - union.instance_variable_get(:@addr)) / @sizeof
- end
-
- # @param sizeof [Integer]
- # @param members [Hash{ Symbol => RubyVM::RJIT::CType::* }]
- def self.define(sizeof, members)
- Class.new(self) do
- # Return the size of this type
- define_singleton_method(:sizeof) { sizeof }
-
- # Part of Struct's offsetof implementation
- define_singleton_method(:offsetof) do |field, *fields|
- member = members.fetch(field)
- offset = 0
- unless fields.empty?
- offset += member.offsetof(*fields)
- end
- offset
- end
-
- define_method(:initialize) do |addr|
- super(addr, sizeof, members)
- end
-
- members.each do |member, type|
- # Intelligent API that does automatic dereference
- define_method(member) do
- value = type.new(@addr)
- if value.respond_to?(:*)
- value = value.*
- end
- value
- end
- end
- end
- end
- end
-
- class Immediate
- # @param addr [Integer]
- # @param size [Integer]
- # @param pack [String]
- def initialize(addr, size, pack)
- @addr = addr
- @size = size
- @pack = pack
- end
-
- # Get a raw address
- def to_i
- @addr
- end
-
- # Move addr to addess this pointer like an array
- def +(index)
- Immediate.new(@addr + index * @size, @size, @pack)
- end
-
- # Dereference
- def *
- self[0]
- end
-
- # Array access
- def [](index)
- return nil if @addr == 0
- Fiddle::Pointer.new(@addr + index * @size)[0, @size].unpack1(@pack)
- end
-
- # Array set
- def []=(index, value)
- Fiddle::Pointer.new(@addr + index * @size)[0, @size] = [value].pack(@pack)
- end
-
- # Serialized address for generated code. Used for embedding things like body->iseq_encoded.
- def to_s
- "0x#{Integer(@addr).to_s(16)}"
- end
-
- # @param fiddle_type [Integer] Fiddle::TYPE_*
- def self.define(fiddle_type)
- size = Fiddle::PackInfo::SIZE_MAP.fetch(fiddle_type)
- pack = Fiddle::PackInfo::PACK_MAP.fetch(fiddle_type)
-
- Class.new(self) do
- define_method(:initialize) do |addr|
- super(addr, size, pack)
- end
-
- define_singleton_method(:size) do
- size
- end
-
- # Type-level []=: Used by struct fields
- define_singleton_method(:[]=) do |addr, value|
- Fiddle::Pointer.new(addr)[0, size] = [value].pack(pack)
- end
- end
- end
- end
-
- # -Fiddle::TYPE_CHAR Immediate with special handling of true/false
- class Bool < Immediate.define(-Fiddle::TYPE_CHAR)
- # Dereference
- def *
- return nil if @addr == 0
- super != 0
- end
-
- def self.[]=(addr, value)
- super(addr, value ? 1 : 0)
- end
- end
-
- # Basically Immediate but without #* to skip auto-dereference of structs.
- class Array
- attr_reader :type
-
- # @param addr [Integer]
- # @param type [Class] RubyVM::RJIT::CType::*
- def initialize(addr, type)
- @addr = addr
- @type = type
- end
-
- # Array access
- def [](index)
- @type.new(@addr)[index]
- end
-
- # Array set
- # @param index [Integer]
- # @param value [Integer, RubyVM::RJIT::CPointer::Struct] an address itself or an object that return an address with to_i
- def []=(index, value)
- @type.new(@addr)[index] = value
- end
-
- private
-
- def self.define(block)
- Class.new(self) do
- define_method(:initialize) do |addr|
- super(addr, block.call)
- end
- end
- end
- end
-
- class Pointer
- attr_reader :type
-
- # @param addr [Integer]
- # @param type [Class] RubyVM::RJIT::CType::*
- def initialize(addr, type)
- @addr = addr
- @type = type
- end
-
- # Move addr to addess this pointer like an array
- def +(index)
- raise ArgumentError unless index.is_a?(Integer)
- Pointer.new(@addr + index * Fiddle::SIZEOF_VOIDP, @type)
- end
-
- # Dereference
- def *
- return nil if dest_addr == 0
- @type.new(dest_addr)
- end
-
- # Array access
- def [](index)
- (self + index).*
- end
-
- # Array set
- # @param index [Integer]
- # @param value [Integer, RubyVM::RJIT::CPointer::Struct] an address itself or an object that return an address with to_i
- def []=(index, value)
- Fiddle::Pointer.new(@addr + index * Fiddle::SIZEOF_VOIDP)[0, Fiddle::SIZEOF_VOIDP] =
- [value.to_i].pack(Fiddle::PackInfo::PACK_MAP[Fiddle::TYPE_VOIDP])
- end
-
- # Get a raw address
- def to_i
- @addr
- end
-
- private
-
- def dest_addr
- Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_VOIDP].unpack1(Fiddle::PackInfo::PACK_MAP[Fiddle::TYPE_VOIDP])
- end
-
- def self.define(block)
- Class.new(self) do
- define_method(:initialize) do |addr|
- super(addr, block.call)
- end
-
- # Type-level []=: Used by struct fields
- # @param addr [Integer]
- # @param value [Integer, RubyVM::RJIT::CPointer::Struct] an address itself, or an object that return an address with to_i
- define_singleton_method(:[]=) do |addr, value|
- value = value.to_i
- Fiddle::Pointer.new(addr)[0, Fiddle::SIZEOF_VOIDP] = [value].pack(Fiddle::PackInfo::PACK_MAP[Fiddle::TYPE_VOIDP])
- end
- end
- end
- end
-
- class BitField
- # @param addr [Integer]
- # @param width [Integer]
- # @param offset [Integer]
- def initialize(addr, width, offset)
- @addr = addr
- @width = width
- @offset = offset
- end
-
- # Dereference
- def *
- byte = Fiddle::Pointer.new(@addr)[0, Fiddle::SIZEOF_CHAR].unpack('c').first
- if @width == 1
- bit = (1 & (byte >> @offset))
- bit == 1
- elsif @width <= 8 && @offset == 0
- bitmask = @width.times.map { |i| 1 << i }.sum
- byte & bitmask
- else
- raise NotImplementedError.new("not-implemented bit field access: width=#{@width} offset=#{@offset}")
- end
- end
-
- # @param width [Integer]
- # @param offset [Integer]
- def self.define(width, offset)
- Class.new(self) do
- define_method(:initialize) do |addr|
- super(addr, width, offset)
- end
- end
- end
- end
-
- # Give a name to a dynamic CPointer class to see it on inspect
- def self.with_class_name(prefix, name, cache: false, &block)
- return block.call if !name.nil? && name.empty?
-
- # Use a cached result only if cache: true
- class_name = "#{prefix}_#{name}"
- klass =
- if cache && self.const_defined?(class_name)
- self.const_get(class_name)
- else
- block.call
- end
-
- # Give it a name unless it's already defined
- unless self.const_defined?(class_name)
- self.const_set(class_name, klass)
- end
-
- klass
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/c_type.rb b/lib/ruby_vm/rjit/c_type.rb
deleted file mode 100644
index 3b313a658b..0000000000
--- a/lib/ruby_vm/rjit/c_type.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-require 'fiddle'
-require 'fiddle/pack'
-require_relative 'c_pointer'
-
-module RubyVM::RJIT
- module CType
- module Struct
- # @param name [String]
- # @param members [Hash{ Symbol => [Integer, RubyVM::RJIT::CType::*] }]
- def self.new(name, sizeof, **members)
- name = members.keys.join('_') if name.empty?
- CPointer.with_class_name('Struct', name) do
- CPointer::Struct.define(sizeof, members)
- end
- end
- end
-
- module Union
- # @param name [String]
- # @param members [Hash{ Symbol => RubyVM::RJIT::CType::* }]
- def self.new(name, sizeof, **members)
- name = members.keys.join('_') if name.empty?
- CPointer.with_class_name('Union', name) do
- CPointer::Union.define(sizeof, members)
- end
- end
- end
-
- module Immediate
- # @param fiddle_type [Integer]
- def self.new(fiddle_type)
- name = Fiddle.constants.find do |const|
- const.start_with?('TYPE_') && Fiddle.const_get(const) == fiddle_type.abs
- end&.to_s
- name.delete_prefix!('TYPE_')
- if fiddle_type.negative?
- name.prepend('U')
- end
- CPointer.with_class_name('Immediate', name, cache: true) do
- CPointer::Immediate.define(fiddle_type)
- end
- end
-
- # @param type [String]
- def self.parse(ctype)
- new(Fiddle::Importer.parse_ctype(ctype))
- end
-
- def self.find(size, signed)
- fiddle_type = TYPE_MAP.fetch(size)
- fiddle_type = -fiddle_type unless signed
- new(fiddle_type)
- end
-
- TYPE_MAP = Fiddle::PackInfo::SIZE_MAP.map { |type, size| [size, type.abs] }.to_h
- private_constant :TYPE_MAP
- end
-
- module Bool
- def self.new
- CPointer::Bool
- end
- end
-
- class Array
- def self.new(&block)
- CPointer.with_class_name('Array', block.object_id.to_s) do
- CPointer::Array.define(block)
- end
- end
- end
-
- class Pointer
- # This takes a block to avoid "stack level too deep" on a cyclic reference
- # @param block [Proc]
- def self.new(&block)
- CPointer.with_class_name('Pointer', block.object_id.to_s) do
- CPointer::Pointer.define(block)
- end
- end
- end
-
- module BitField
- # @param width [Integer]
- # @param offset [Integer]
- def self.new(width, offset)
- CPointer.with_class_name('BitField', "#{offset}_#{width}") do
- CPointer::BitField.define(width, offset)
- end
- end
- end
-
- # Types that are referenced but not part of code generation targets
- Stub = ::Struct.new(:name)
-
- # Types that it failed to figure out from the header
- Unknown = Module.new
- end
-end
diff --git a/lib/ruby_vm/rjit/code_block.rb b/lib/ruby_vm/rjit/code_block.rb
deleted file mode 100644
index 260bd98671..0000000000
--- a/lib/ruby_vm/rjit/code_block.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-module RubyVM::RJIT
- class CodeBlock
- # @param mem_block [Integer] JIT buffer address
- # @param mem_size [Integer] JIT buffer size
- # @param outliend [TrueClass,FalseClass] true for outlined CodeBlock
- def initialize(mem_block:, mem_size:, outlined: false)
- @comments = Hash.new { |h, k| h[k] = [] } if dump_disasm?
- @mem_block = mem_block
- @mem_size = mem_size
- @write_pos = 0
- @outlined = outlined
- end
-
- # @param asm [RubyVM::RJIT::Assembler]
- def write(asm)
- return 0 if @write_pos + asm.size >= @mem_size
-
- start_addr = write_addr
-
- # Write machine code
- C.mprotect_write(@mem_block, @mem_size)
- @write_pos += asm.assemble(start_addr)
- C.mprotect_exec(@mem_block, @mem_size)
-
- end_addr = write_addr
-
- # Convert comment indexes to addresses
- asm.comments.each do |index, comments|
- @comments[start_addr + index] += comments if dump_disasm?
- end
- asm.comments.clear
-
- # Dump disasm if --rjit-dump-disasm
- if C.rjit_opts.dump_disasm && start_addr < end_addr
- dump_disasm(start_addr, end_addr)
- end
- start_addr
- end
-
- def set_write_addr(addr)
- @write_pos = addr - @mem_block
- @comments.delete(addr) if dump_disasm?
- end
-
- def with_write_addr(addr)
- old_write_pos = @write_pos
- set_write_addr(addr)
- yield
- ensure
- @write_pos = old_write_pos
- end
-
- def write_addr
- @mem_block + @write_pos
- end
-
- def include?(addr)
- (@mem_block...(@mem_block + @mem_size)).include?(addr)
- end
-
- def dump_disasm(from, to, io: STDOUT, color: true, test: false)
- C.dump_disasm(from, to, test:).each do |address, mnemonic, op_str|
- @comments.fetch(address, []).each do |comment|
- io.puts colorize(" # #{comment}", bold: true, color:)
- end
- io.puts colorize(" 0x#{format("%x", address)}: #{mnemonic} #{op_str}", color:)
- end
- io.puts
- end
-
- private
-
- def colorize(text, bold: false, color:)
- return text unless color
- buf = +''
- buf << "\e[1m" if bold
- buf << "\e[34m" if @outlined
- buf << text
- buf << "\e[0m"
- buf
- end
-
- def bold(text)
- "\e[1m#{text}\e[0m"
- end
-
- def dump_disasm?
- C.rjit_opts.dump_disasm
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/compiler.rb b/lib/ruby_vm/rjit/compiler.rb
deleted file mode 100644
index e5c3adf0ec..0000000000
--- a/lib/ruby_vm/rjit/compiler.rb
+++ /dev/null
@@ -1,518 +0,0 @@
-require 'ruby_vm/rjit/assembler'
-require 'ruby_vm/rjit/block'
-require 'ruby_vm/rjit/branch_stub'
-require 'ruby_vm/rjit/code_block'
-require 'ruby_vm/rjit/context'
-require 'ruby_vm/rjit/entry_stub'
-require 'ruby_vm/rjit/exit_compiler'
-require 'ruby_vm/rjit/insn_compiler'
-require 'ruby_vm/rjit/instruction'
-require 'ruby_vm/rjit/invariants'
-require 'ruby_vm/rjit/jit_state'
-require 'ruby_vm/rjit/type'
-
-module RubyVM::RJIT
- # Compilation status
- KeepCompiling = :KeepCompiling
- CantCompile = :CantCompile
- EndBlock = :EndBlock
-
- # Ruby constants
- Qtrue = Fiddle::Qtrue
- Qfalse = Fiddle::Qfalse
- Qnil = Fiddle::Qnil
- Qundef = Fiddle::Qundef
-
- # Callee-saved registers
- # TODO: support using r12/r13 here
- EC = :r14
- CFP = :r15
- SP = :rbx
-
- # Scratch registers: rax, rcx, rdx
-
- # Mark objects in this Array during GC
- GC_REFS = []
-
- # Maximum number of versions per block
- # 1 means always create generic versions
- MAX_VERSIONS = 4
-
- class Compiler
- attr_accessor :write_pos
-
- def self.decode_insn(encoded)
- INSNS.fetch(C.rb_vm_insn_decode(encoded))
- end
-
- def initialize
- mem_size = C.rjit_opts.exec_mem_size * 1024 * 1024
- mem_block = C.mmap(mem_size)
- @cb = CodeBlock.new(mem_block: mem_block, mem_size: mem_size / 2)
- @ocb = CodeBlock.new(mem_block: mem_block + mem_size / 2, mem_size: mem_size / 2, outlined: true)
- @exit_compiler = ExitCompiler.new
- @insn_compiler = InsnCompiler.new(@cb, @ocb, @exit_compiler)
- Invariants.initialize(@cb, @ocb, self, @exit_compiler)
- end
-
- # Compile an ISEQ from its entry point.
- # @param iseq `RubyVM::RJIT::CPointer::Struct_rb_iseq_t`
- # @param cfp `RubyVM::RJIT::CPointer::Struct_rb_control_frame_t`
- def compile(iseq, cfp)
- return unless supported_platform?
- pc = cfp.pc.to_i
- jit = JITState.new(iseq:, cfp:)
- asm = Assembler.new
- compile_prologue(asm, iseq, pc)
- compile_block(asm, jit:, pc:)
- iseq.body.jit_entry = @cb.write(asm)
- rescue Exception => e
- STDERR.puts "#{e.class}: #{e.message}"
- STDERR.puts e.backtrace
- exit 1
- end
-
- # Compile an entry.
- # @param entry [RubyVM::RJIT::EntryStub]
- def entry_stub_hit(entry_stub, cfp)
- # Compile a new entry guard as a next entry
- pc = cfp.pc.to_i
- next_entry = Assembler.new.then do |asm|
- compile_entry_chain_guard(asm, cfp.iseq, pc)
- @cb.write(asm)
- end
-
- # Try to find an existing compiled version of this block
- ctx = Context.new
- block = find_block(cfp.iseq, pc, ctx)
- if block
- # If an existing block is found, generate a jump to the block.
- asm = Assembler.new
- asm.jmp(block.start_addr)
- @cb.write(asm)
- else
- # If this block hasn't yet been compiled, generate blocks after the entry guard.
- asm = Assembler.new
- jit = JITState.new(iseq: cfp.iseq, cfp:)
- compile_block(asm, jit:, pc:, ctx:)
- @cb.write(asm)
-
- block = jit.block
- end
-
- # Regenerate the previous entry
- @cb.with_write_addr(entry_stub.start_addr) do
- # The last instruction of compile_entry_chain_guard is jne
- asm = Assembler.new
- asm.jne(next_entry)
- @cb.write(asm)
- end
-
- return block.start_addr
- rescue Exception => e
- STDERR.puts e.full_message
- exit 1
- end
-
- # Compile a branch stub.
- # @param branch_stub [RubyVM::RJIT::BranchStub]
- # @param cfp `RubyVM::RJIT::CPointer::Struct_rb_control_frame_t`
- # @param target0_p [TrueClass,FalseClass]
- # @return [Integer] The starting address of the compiled branch stub
- def branch_stub_hit(branch_stub, cfp, target0_p)
- # Update cfp->pc for `jit.at_current_insn?`
- target = target0_p ? branch_stub.target0 : branch_stub.target1
- cfp.pc = target.pc
-
- # Reuse an existing block if it already exists
- block = find_block(branch_stub.iseq, target.pc, target.ctx)
-
- # If the branch stub's jump is the last code, allow overwriting part of
- # the old branch code with the new block code.
- fallthrough = block.nil? && @cb.write_addr == branch_stub.end_addr
- if fallthrough
- # If the branch stub's jump is the last code, allow overwriting part of
- # the old branch code with the new block code.
- @cb.set_write_addr(branch_stub.start_addr)
- branch_stub.shape = target0_p ? Next0 : Next1
- Assembler.new.tap do |branch_asm|
- branch_stub.compile.call(branch_asm)
- @cb.write(branch_asm)
- end
- end
-
- # Reuse or generate a block
- if block
- target.address = block.start_addr
- else
- jit = JITState.new(iseq: branch_stub.iseq, cfp:)
- target.address = Assembler.new.then do |asm|
- compile_block(asm, jit:, pc: target.pc, ctx: target.ctx.dup)
- @cb.write(asm)
- end
- block = jit.block
- end
- block.incoming << branch_stub # prepare for invalidate_block
-
- # Re-generate the branch code for non-fallthrough cases
- unless fallthrough
- @cb.with_write_addr(branch_stub.start_addr) do
- branch_asm = Assembler.new
- branch_stub.compile.call(branch_asm)
- @cb.write(branch_asm)
- end
- end
-
- return target.address
- rescue Exception => e
- STDERR.puts e.full_message
- exit 1
- end
-
- # @param iseq `RubyVM::RJIT::CPointer::Struct_rb_iseq_t`
- # @param pc [Integer]
- def invalidate_blocks(iseq, pc)
- list_blocks(iseq, pc).each do |block|
- invalidate_block(block)
- end
-
- # If they were the ISEQ's first blocks, re-compile RJIT entry as well
- if iseq.body.iseq_encoded.to_i == pc
- iseq.body.jit_entry = 0
- iseq.body.jit_entry_calls = 0
- end
- end
-
- def invalidate_block(block)
- iseq = block.iseq
- # Avoid touching GCed ISEQs. We assume it won't be re-entered.
- return unless C.imemo_type_p(iseq, C.imemo_iseq)
-
- # Remove this block from the version array
- remove_block(iseq, block)
-
- # Invalidate the block with entry exit
- unless block.invalidated
- @cb.with_write_addr(block.start_addr) do
- asm = Assembler.new
- asm.comment('invalidate_block')
- asm.jmp(block.entry_exit)
- @cb.write(asm)
- end
- block.invalidated = true
- end
-
- # Re-stub incoming branches
- block.incoming.each do |branch_stub|
- target = [branch_stub.target0, branch_stub.target1].compact.find do |target|
- target.pc == block.pc && target.ctx == block.ctx
- end
- next if target.nil?
- # TODO: Could target.address be a stub address? Is invalidation not needed in that case?
-
- # If the target being re-generated is currently a fallthrough block,
- # the fallthrough code must be rewritten with a jump to the stub.
- if target.address == branch_stub.end_addr
- branch_stub.shape = Default
- end
-
- target.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(block.ctx, ocb_asm, branch_stub, target == branch_stub.target0)
- @ocb.write(ocb_asm)
- end
- @cb.with_write_addr(branch_stub.start_addr) do
- branch_asm = Assembler.new
- branch_stub.compile.call(branch_asm)
- @cb.write(branch_asm)
- end
- end
- end
-
- private
-
- # Callee-saved: rbx, rsp, rbp, r12, r13, r14, r15
- # Caller-saved: rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11
- #
- # @param asm [RubyVM::RJIT::Assembler]
- def compile_prologue(asm, iseq, pc)
- asm.comment('RJIT entry point')
-
- # Save callee-saved registers used by JITed code
- asm.push(CFP)
- asm.push(EC)
- asm.push(SP)
-
- # Move arguments EC and CFP to dedicated registers
- asm.mov(EC, :rdi)
- asm.mov(CFP, :rsi)
-
- # Load sp to a dedicated register
- asm.mov(SP, [CFP, C.rb_control_frame_t.offsetof(:sp)]) # rbx = cfp->sp
-
- # Setup cfp->jit_return
- asm.mov(:rax, leave_exit)
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:jit_return)], :rax)
-
- # We're compiling iseqs that we *expect* to start at `insn_idx`. But in
- # the case of optional parameters, the interpreter can set the pc to a
- # different location depending on the optional parameters. If an iseq
- # has optional parameters, we'll add a runtime check that the PC we've
- # compiled for is the same PC that the interpreter wants us to run with.
- # If they don't match, then we'll take a side exit.
- if iseq.body.param.flags.has_opt
- compile_entry_chain_guard(asm, iseq, pc)
- end
- end
-
- def compile_entry_chain_guard(asm, iseq, pc)
- entry_stub = EntryStub.new
- stub_addr = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_entry_stub(ocb_asm, entry_stub)
- @ocb.write(ocb_asm)
- end
-
- asm.comment('guard expected PC')
- asm.mov(:rax, pc)
- asm.cmp([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax)
-
- asm.stub(entry_stub) do
- asm.jne(stub_addr)
- end
- end
-
- # @param asm [RubyVM::RJIT::Assembler]
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- def compile_block(asm, jit:, pc:, ctx: Context.new)
- # Mark the block start address and prepare an exit code storage
- ctx = limit_block_versions(jit.iseq, pc, ctx)
- block = Block.new(iseq: jit.iseq, pc:, ctx: ctx.dup)
- jit.block = block
- asm.block(block)
-
- iseq = jit.iseq
- asm.comment("Block: #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{iseq_lineno(iseq, pc)}")
-
- # Compile each insn
- index = (pc - iseq.body.iseq_encoded.to_i) / C.VALUE.size
- while index < iseq.body.iseq_size
- # Set the current instruction
- insn = self.class.decode_insn(iseq.body.iseq_encoded[index])
- jit.pc = (iseq.body.iseq_encoded + index).to_i
- jit.stack_size_for_pc = ctx.stack_size
- jit.side_exit_for_pc.clear
-
- # If previous instruction requested to record the boundary
- if jit.record_boundary_patch_point
- # Generate an exit to this instruction and record it
- exit_pos = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_side_exit(jit.pc, ctx, ocb_asm)
- @ocb.write(ocb_asm)
- end
- Invariants.record_global_inval_patch(asm, exit_pos)
- jit.record_boundary_patch_point = false
- end
-
- # In debug mode, verify our existing assumption
- if C.rjit_opts.verify_ctx && jit.at_current_insn?
- verify_ctx(jit, ctx)
- end
-
- case status = @insn_compiler.compile(jit, ctx, asm, insn)
- when KeepCompiling
- # For now, reset the chain depth after each instruction as only the
- # first instruction in the block can concern itself with the depth.
- ctx.chain_depth = 0
-
- index += insn.len
- when EndBlock
- # TODO: pad nops if entry exit exists (not needed for x86_64?)
- break
- when CantCompile
- # Rewind stack_size using ctx.with_stack_size to allow stack_size changes
- # before you return CantCompile.
- @exit_compiler.compile_side_exit(jit.pc, ctx.with_stack_size(jit.stack_size_for_pc), asm)
-
- # If this is the first instruction, this block never needs to be invalidated.
- if block.pc == iseq.body.iseq_encoded.to_i + index * C.VALUE.size
- block.invalidated = true
- end
-
- break
- else
- raise "compiling #{insn.name} returned unexpected status: #{status.inspect}"
- end
- end
-
- incr_counter(:compiled_block_count)
- add_block(iseq, block)
- end
-
- def leave_exit
- @leave_exit ||= Assembler.new.then do |asm|
- @exit_compiler.compile_leave_exit(asm)
- @ocb.write(asm)
- end
- end
-
- def incr_counter(name)
- if C.rjit_opts.stats
- C.rb_rjit_counters[name][0] += 1
- end
- end
-
- # Produce a generic context when the block version limit is hit for the block
- def limit_block_versions(iseq, pc, ctx)
- # Guard chains implement limits separately, do nothing
- if ctx.chain_depth > 0
- return ctx.dup
- end
-
- # If this block version we're about to add will hit the version limit
- if list_blocks(iseq, pc).size + 1 >= MAX_VERSIONS
- # Produce a generic context that stores no type information,
- # but still respects the stack_size and sp_offset constraints.
- # This new context will then match all future requests.
- generic_ctx = Context.new
- generic_ctx.stack_size = ctx.stack_size
- generic_ctx.sp_offset = ctx.sp_offset
-
- if ctx.diff(generic_ctx) == TypeDiff::Incompatible
- raise 'should substitute a compatible context'
- end
-
- return generic_ctx
- end
-
- return ctx.dup
- end
-
- def list_blocks(iseq, pc)
- rjit_blocks(iseq)[pc]
- end
-
- # @param [Integer] pc
- # @param [RubyVM::RJIT::Context] ctx
- # @return [RubyVM::RJIT::Block,NilClass]
- def find_block(iseq, pc, ctx)
- versions = rjit_blocks(iseq)[pc]
-
- best_version = nil
- best_diff = Float::INFINITY
-
- versions.each do |block|
- # Note that we always prefer the first matching
- # version found because of inline-cache chains
- case ctx.diff(block.ctx)
- in TypeDiff::Compatible[diff] if diff < best_diff
- best_version = block
- best_diff = diff
- else
- end
- end
-
- return best_version
- end
-
- # @param [RubyVM::RJIT::Block] block
- def add_block(iseq, block)
- rjit_blocks(iseq)[block.pc] << block
- end
-
- # @param [RubyVM::RJIT::Block] block
- def remove_block(iseq, block)
- rjit_blocks(iseq)[block.pc].delete(block)
- end
-
- def rjit_blocks(iseq)
- # Guard against ISEQ GC at random moments
-
- unless C.imemo_type_p(iseq, C.imemo_iseq)
- return Hash.new { |h, k| h[k] = [] }
- end
-
- unless iseq.body.rjit_blocks
- iseq.body.rjit_blocks = Hash.new { |blocks, pc| blocks[pc] = [] }
- # For some reason, rb_rjit_iseq_mark didn't protect this Hash
- # from being freed. So we rely on GC_REFS to keep the Hash.
- GC_REFS << iseq.body.rjit_blocks
- end
- iseq.body.rjit_blocks
- end
-
- def iseq_lineno(iseq, pc)
- C.rb_iseq_line_no(iseq, (pc - iseq.body.iseq_encoded.to_i) / C.VALUE.size)
- rescue RangeError # bignum too big to convert into `unsigned long long' (RangeError)
- -1
- end
-
- # Verify the ctx's types and mappings against the compile-time stack, self, and locals.
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- def verify_ctx(jit, ctx)
- # Only able to check types when at current insn
- assert(jit.at_current_insn?)
-
- self_val = jit.peek_at_self
- self_val_type = Type.from(self_val)
-
- # Verify self operand type
- assert_compatible(self_val_type, ctx.get_opnd_type(SelfOpnd))
-
- # Verify stack operand types
- [ctx.stack_size, MAX_TEMP_TYPES].min.times do |i|
- learned_mapping, learned_type = ctx.get_opnd_mapping(StackOpnd[i])
- stack_val = jit.peek_at_stack(i)
- val_type = Type.from(stack_val)
-
- case learned_mapping
- in MapToSelf
- if C.to_value(self_val) != C.to_value(stack_val)
- raise "verify_ctx: stack value was mapped to self, but values did not match:\n"\
- "stack: #{stack_val.inspect}, self: #{self_val.inspect}"
- end
- in MapToLocal[local_idx]
- local_val = jit.peek_at_local(local_idx)
- if C.to_value(local_val) != C.to_value(stack_val)
- raise "verify_ctx: stack value was mapped to local, but values did not match:\n"\
- "stack: #{stack_val.inspect}, local: #{local_val.inspect}"
- end
- in MapToStack
- # noop
- end
-
- # If the actual type differs from the learned type
- assert_compatible(val_type, learned_type)
- end
-
- # Verify local variable types
- local_table_size = jit.iseq.body.local_table_size
- [local_table_size, MAX_TEMP_TYPES].min.times do |i|
- learned_type = ctx.get_local_type(i)
- local_val = jit.peek_at_local(i)
- local_type = Type.from(local_val)
-
- assert_compatible(local_type, learned_type)
- end
- end
-
- def assert_compatible(actual_type, ctx_type)
- if actual_type.diff(ctx_type) == TypeDiff::Incompatible
- raise "verify_ctx: ctx type (#{ctx_type.type.inspect}) is incompatible with actual type (#{actual_type.type.inspect})"
- end
- end
-
- def assert(cond)
- unless cond
- raise "'#{cond.inspect}' was not true"
- end
- end
-
- def supported_platform?
- return @supported_platform if defined?(@supported_platform)
- @supported_platform = RUBY_PLATFORM.match?(/x86_64/).tap do |supported|
- warn "warning: RJIT does not support #{RUBY_PLATFORM} yet" unless supported
- end
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/context.rb b/lib/ruby_vm/rjit/context.rb
deleted file mode 100644
index a2a7ecc6dc..0000000000
--- a/lib/ruby_vm/rjit/context.rb
+++ /dev/null
@@ -1,377 +0,0 @@
-module RubyVM::RJIT
- # Maximum number of temp value types we keep track of
- MAX_TEMP_TYPES = 8
- # Maximum number of local variable types we keep track of
- MAX_LOCAL_TYPES = 8
-
- # Operand to a YARV bytecode instruction
- SelfOpnd = :SelfOpnd # The value is self
- StackOpnd = Data.define(:index) # Temporary stack operand with stack index
-
- # Potential mapping of a value on the temporary stack to self,
- # a local variable, or constant so that we can track its type
- MapToStack = :MapToStack # Normal stack value
- MapToSelf = :MapToSelf # Temp maps to the self operand
- MapToLocal = Data.define(:local_index) # Temp maps to a local variable with index
-
- class Context < Struct.new(
- :stack_size, # @param [Integer] The number of values on the stack
- :sp_offset, # @param [Integer] JIT sp offset relative to the interpreter's sp
- :chain_depth, # @param [Integer] jit_chain_guard depth
- :local_types, # @param [Array<RubyVM::RJIT::Type>] Local variable types we keep track of
- :temp_types, # @param [Array<RubyVM::RJIT::Type>] Temporary variable types we keep track of
- :self_type, # @param [RubyVM::RJIT::Type] Type we track for self
- :temp_mapping, # @param [Array<Symbol>] Mapping of temp stack entries to types we track
- )
- def initialize(
- stack_size: 0,
- sp_offset: 0,
- chain_depth: 0,
- local_types: [Type::Unknown] * MAX_LOCAL_TYPES,
- temp_types: [Type::Unknown] * MAX_TEMP_TYPES,
- self_type: Type::Unknown,
- temp_mapping: [MapToStack] * MAX_TEMP_TYPES
- ) = super
-
- # Deep dup by default for safety
- def dup
- ctx = super
- ctx.local_types = ctx.local_types.dup
- ctx.temp_types = ctx.temp_types.dup
- ctx.temp_mapping = ctx.temp_mapping.dup
- ctx
- end
-
- # Create a new Context instance with a given stack_size and sp_offset adjusted
- # accordingly. This is useful when you want to virtually rewind a stack_size for
- # generating a side exit while considering past sp_offset changes on gen_save_sp.
- def with_stack_size(stack_size)
- ctx = self.dup
- ctx.sp_offset -= ctx.stack_size - stack_size
- ctx.stack_size = stack_size
- ctx
- end
-
- def stack_opnd(depth_from_top)
- [SP, C.VALUE.size * (self.sp_offset - 1 - depth_from_top)]
- end
-
- def sp_opnd(offset_bytes = 0)
- [SP, (C.VALUE.size * self.sp_offset) + offset_bytes]
- end
-
- # Push one new value on the temp stack with an explicit mapping
- # Return a pointer to the new stack top
- def stack_push_mapping(mapping_temp_type)
- stack_size = self.stack_size
-
- # Keep track of the type and mapping of the value
- if stack_size < MAX_TEMP_TYPES
- mapping, temp_type = mapping_temp_type
- self.temp_mapping[stack_size] = mapping
- self.temp_types[stack_size] = temp_type
-
- case mapping
- in MapToLocal[idx]
- assert(idx < MAX_LOCAL_TYPES)
- else
- end
- end
-
- self.stack_size += 1
- self.sp_offset += 1
-
- return self.stack_opnd(0)
- end
-
- # Push one new value on the temp stack
- # Return a pointer to the new stack top
- def stack_push(val_type)
- return self.stack_push_mapping([MapToStack, val_type])
- end
-
- # Push the self value on the stack
- def stack_push_self
- return self.stack_push_mapping([MapToStack, Type::Unknown])
- end
-
- # Push a local variable on the stack
- def stack_push_local(local_idx)
- if local_idx >= MAX_LOCAL_TYPES
- return self.stack_push(Type::Unknown)
- end
-
- return self.stack_push_mapping([MapToLocal[local_idx], Type::Unknown])
- end
-
- # Pop N values off the stack
- # Return a pointer to the stack top before the pop operation
- def stack_pop(n = 1)
- assert(n <= self.stack_size)
-
- top = self.stack_opnd(0)
-
- # Clear the types of the popped values
- n.times do |i|
- idx = self.stack_size - i - 1
-
- if idx < MAX_TEMP_TYPES
- self.temp_types[idx] = Type::Unknown
- self.temp_mapping[idx] = MapToStack
- end
- end
-
- self.stack_size -= n
- self.sp_offset -= n
-
- return top
- end
-
- def shift_stack(argc)
- assert(argc < self.stack_size)
-
- method_name_index = self.stack_size - argc - 1
-
- (method_name_index...(self.stack_size - 1)).each do |i|
- if i + 1 < MAX_TEMP_TYPES
- self.temp_types[i] = self.temp_types[i + 1]
- self.temp_mapping[i] = self.temp_mapping[i + 1]
- end
- end
- self.stack_pop(1)
- end
-
- # Get the type of an instruction operand
- def get_opnd_type(opnd)
- case opnd
- in SelfOpnd
- self.self_type
- in StackOpnd[idx]
- assert(idx < self.stack_size)
- stack_idx = self.stack_size - 1 - idx
-
- # If outside of tracked range, do nothing
- if stack_idx >= MAX_TEMP_TYPES
- return Type::Unknown
- end
-
- mapping = self.temp_mapping[stack_idx]
-
- case mapping
- in MapToSelf
- self.self_type
- in MapToStack
- self.temp_types[self.stack_size - 1 - idx]
- in MapToLocal[idx]
- assert(idx < MAX_LOCAL_TYPES)
- self.local_types[idx]
- end
- end
- end
-
- # Get the currently tracked type for a local variable
- def get_local_type(idx)
- self.local_types[idx] || Type::Unknown
- end
-
- # Upgrade (or "learn") the type of an instruction operand
- # This value must be compatible and at least as specific as the previously known type.
- # If this value originated from self, or an lvar, the learned type will be
- # propagated back to its source.
- def upgrade_opnd_type(opnd, opnd_type)
- case opnd
- in SelfOpnd
- self.self_type = self.self_type.upgrade(opnd_type)
- in StackOpnd[idx]
- assert(idx < self.stack_size)
- stack_idx = self.stack_size - 1 - idx
-
- # If outside of tracked range, do nothing
- if stack_idx >= MAX_TEMP_TYPES
- return
- end
-
- mapping = self.temp_mapping[stack_idx]
-
- case mapping
- in MapToSelf
- self.self_type = self.self_type.upgrade(opnd_type)
- in MapToStack
- self.temp_types[stack_idx] = self.temp_types[stack_idx].upgrade(opnd_type)
- in MapToLocal[idx]
- assert(idx < MAX_LOCAL_TYPES)
- self.local_types[idx] = self.local_types[idx].upgrade(opnd_type)
- end
- end
- end
-
- # Get both the type and mapping (where the value originates) of an operand.
- # This is can be used with stack_push_mapping or set_opnd_mapping to copy
- # a stack value's type while maintaining the mapping.
- def get_opnd_mapping(opnd)
- opnd_type = self.get_opnd_type(opnd)
-
- case opnd
- in SelfOpnd
- return [MapToSelf, opnd_type]
- in StackOpnd[idx]
- assert(idx < self.stack_size)
- stack_idx = self.stack_size - 1 - idx
-
- if stack_idx < MAX_TEMP_TYPES
- return [self.temp_mapping[stack_idx], opnd_type]
- else
- # We can't know the source of this stack operand, so we assume it is
- # a stack-only temporary. type will be UNKNOWN
- assert(opnd_type == Type::Unknown)
- return [MapToStack, opnd_type]
- end
- end
- end
-
- # Overwrite both the type and mapping of a stack operand.
- def set_opnd_mapping(opnd, mapping_opnd_type)
- case opnd
- in SelfOpnd
- raise 'self always maps to self'
- in StackOpnd[idx]
- assert(idx < self.stack_size)
- stack_idx = self.stack_size - 1 - idx
-
- # If outside of tracked range, do nothing
- if stack_idx >= MAX_TEMP_TYPES
- return
- end
-
- mapping, opnd_type = mapping_opnd_type
- self.temp_mapping[stack_idx] = mapping
-
- # Only used when mapping == MAP_STACK
- self.temp_types[stack_idx] = opnd_type
- end
- end
-
- # Set the type of a local variable
- def set_local_type(local_idx, local_type)
- if local_idx >= MAX_LOCAL_TYPES
- return
- end
-
- # If any values on the stack map to this local we must detach them
- MAX_TEMP_TYPES.times do |stack_idx|
- case self.temp_mapping[stack_idx]
- in MapToStack
- # noop
- in MapToSelf
- # noop
- in MapToLocal[idx]
- if idx == local_idx
- self.temp_types[stack_idx] = self.local_types[idx]
- self.temp_mapping[stack_idx] = MapToStack
- else
- # noop
- end
- end
- end
-
- self.local_types[local_idx] = local_type
- end
-
- # Erase local variable type information
- # eg: because of a call we can't track
- def clear_local_types
- # When clearing local types we must detach any stack mappings to those
- # locals. Even if local values may have changed, stack values will not.
- MAX_TEMP_TYPES.times do |stack_idx|
- case self.temp_mapping[stack_idx]
- in MapToStack
- # noop
- in MapToSelf
- # noop
- in MapToLocal[local_idx]
- self.temp_types[stack_idx] = self.local_types[local_idx]
- self.temp_mapping[stack_idx] = MapToStack
- end
- end
-
- # Clear the local types
- self.local_types = [Type::Unknown] * MAX_LOCAL_TYPES
- end
-
- # Compute a difference score for two context objects
- def diff(dst)
- # Self is the source context (at the end of the predecessor)
- src = self
-
- # Can only lookup the first version in the chain
- if dst.chain_depth != 0
- return TypeDiff::Incompatible
- end
-
- # Blocks with depth > 0 always produce new versions
- # Sidechains cannot overlap
- if src.chain_depth != 0
- return TypeDiff::Incompatible
- end
-
- if dst.stack_size != src.stack_size
- return TypeDiff::Incompatible
- end
-
- if dst.sp_offset != src.sp_offset
- return TypeDiff::Incompatible
- end
-
- # Difference sum
- diff = 0
-
- # Check the type of self
- diff += case src.self_type.diff(dst.self_type)
- in TypeDiff::Compatible[diff] then diff
- in TypeDiff::Incompatible then return TypeDiff::Incompatible
- end
-
- # For each local type we track
- src.local_types.size.times do |i|
- t_src = src.local_types[i]
- t_dst = dst.local_types[i]
- diff += case t_src.diff(t_dst)
- in TypeDiff::Compatible[diff] then diff
- in TypeDiff::Incompatible then return TypeDiff::Incompatible
- end
- end
-
- # For each value on the temp stack
- src.stack_size.times do |i|
- src_mapping, src_type = src.get_opnd_mapping(StackOpnd[i])
- dst_mapping, dst_type = dst.get_opnd_mapping(StackOpnd[i])
-
- # If the two mappings aren't the same
- if src_mapping != dst_mapping
- if dst_mapping == MapToStack
- # We can safely drop information about the source of the temp
- # stack operand.
- diff += 1
- else
- return TypeDiff::Incompatible
- end
- end
-
- diff += case src_type.diff(dst_type)
- in TypeDiff::Compatible[diff] then diff
- in TypeDiff::Incompatible then return TypeDiff::Incompatible
- end
- end
-
- return TypeDiff::Compatible[diff]
- end
-
- private
-
- def assert(cond)
- unless cond
- raise "'#{cond.inspect}' was not true"
- end
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/entry_stub.rb b/lib/ruby_vm/rjit/entry_stub.rb
deleted file mode 100644
index 9bcef14053..0000000000
--- a/lib/ruby_vm/rjit/entry_stub.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module RubyVM::RJIT
- class EntryStub < Struct.new(
- :start_addr, # @param [Integer] Stub source start address to be re-generated
- :end_addr, # @param [Integer] Stub source end address to be re-generated
- )
- end
-end
diff --git a/lib/ruby_vm/rjit/exit_compiler.rb b/lib/ruby_vm/rjit/exit_compiler.rb
deleted file mode 100644
index 1ced2141a4..0000000000
--- a/lib/ruby_vm/rjit/exit_compiler.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-module RubyVM::RJIT
- class ExitCompiler
- def initialize = freeze
-
- # Used for invalidating a block on entry.
- # @param pc [Integer]
- # @param asm [RubyVM::RJIT::Assembler]
- def compile_entry_exit(pc, ctx, asm, cause:)
- # Fix pc/sp offsets for the interpreter
- save_pc_and_sp(pc, ctx, asm, reset_sp_offset: false)
-
- # Increment per-insn exit counter
- count_insn_exit(pc, asm)
-
- # Restore callee-saved registers
- asm.comment("#{cause}: entry exit")
- asm.pop(SP)
- asm.pop(EC)
- asm.pop(CFP)
-
- asm.mov(C_RET, Qundef)
- asm.ret
- end
-
- # Set to cfp->jit_return by default for leave insn
- # @param asm [RubyVM::RJIT::Assembler]
- def compile_leave_exit(asm)
- asm.comment('default cfp->jit_return')
-
- # Restore callee-saved registers
- asm.pop(SP)
- asm.pop(EC)
- asm.pop(CFP)
-
- # :rax is written by #leave
- asm.ret
- end
-
- # Fire cfunc events on invalidation by TracePoint
- # @param asm [RubyVM::RJIT::Assembler]
- def compile_full_cfunc_return(asm)
- # This chunk of code expects REG_EC to be filled properly and
- # RAX to contain the return value of the C method.
-
- asm.comment('full cfunc return')
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], :rax)
- asm.call(C.rjit_full_cfunc_return)
-
- # TODO: count the exit
-
- # Restore callee-saved registers
- asm.pop(SP)
- asm.pop(EC)
- asm.pop(CFP)
-
- asm.mov(C_RET, Qundef)
- asm.ret
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def compile_side_exit(pc, ctx, asm)
- # Fix pc/sp offsets for the interpreter
- save_pc_and_sp(pc, ctx.dup, asm) # dup to avoid sp_offset update
-
- # Increment per-insn exit counter
- count_insn_exit(pc, asm)
-
- # Restore callee-saved registers
- asm.comment("exit to interpreter on #{pc_to_insn(pc).name}")
- asm.pop(SP)
- asm.pop(EC)
- asm.pop(CFP)
-
- asm.mov(C_RET, Qundef)
- asm.ret
- end
-
- # @param asm [RubyVM::RJIT::Assembler]
- # @param entry_stub [RubyVM::RJIT::EntryStub]
- def compile_entry_stub(asm, entry_stub)
- # Call rb_rjit_entry_stub_hit
- asm.comment('entry stub hit')
- asm.mov(C_ARGS[0], to_value(entry_stub))
- asm.call(C.rb_rjit_entry_stub_hit)
-
- # Jump to the address returned by rb_rjit_entry_stub_hit
- asm.jmp(:rax)
- end
-
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- # @param branch_stub [RubyVM::RJIT::BranchStub]
- # @param target0_p [TrueClass,FalseClass]
- def compile_branch_stub(ctx, asm, branch_stub, target0_p)
- # Call rb_rjit_branch_stub_hit
- iseq = branch_stub.iseq
- if C.rjit_opts.dump_disasm && C.imemo_type_p(iseq, C.imemo_iseq) # Guard against ISEQ GC at random moments
- asm.comment("branch stub hit: #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{iseq_lineno(iseq, target0_p ? branch_stub.target0.pc : branch_stub.target1.pc)}")
- end
- asm.mov(:rdi, to_value(branch_stub))
- asm.mov(:esi, ctx.sp_offset)
- asm.mov(:edx, target0_p ? 1 : 0)
- asm.call(C.rb_rjit_branch_stub_hit)
-
- # Jump to the address returned by rb_rjit_branch_stub_hit
- asm.jmp(:rax)
- end
-
- private
-
- def pc_to_insn(pc)
- Compiler.decode_insn(C.VALUE.new(pc).*)
- end
-
- # @param pc [Integer]
- # @param asm [RubyVM::RJIT::Assembler]
- def count_insn_exit(pc, asm)
- if C.rjit_opts.stats
- insn = Compiler.decode_insn(C.VALUE.new(pc).*)
- asm.comment("increment insn exit: #{insn.name}")
- asm.mov(:rax, (C.rjit_insn_exits + insn.bin).to_i)
- asm.add([:rax], 1) # TODO: lock
- end
- if C.rjit_opts.trace_exits
- asm.comment('rjit_record_exit_stack')
- asm.mov(C_ARGS[0], pc)
- asm.call(C.rjit_record_exit_stack)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def save_pc_and_sp(pc, ctx, asm, reset_sp_offset: true)
- # Update pc (TODO: manage PC offset?)
- asm.comment("save PC#{' and SP' if ctx.sp_offset != 0} to CFP")
- asm.mov(:rax, pc) # rax = jit.pc
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax) # cfp->pc = rax
-
- # Update sp
- if ctx.sp_offset != 0
- asm.add(SP, C.VALUE.size * ctx.sp_offset) # sp += stack_size
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP) # cfp->sp = sp
- if reset_sp_offset
- ctx.sp_offset = 0
- end
- end
- end
-
- def to_value(obj)
- GC_REFS << obj
- C.to_value(obj)
- end
-
- def iseq_lineno(iseq, pc)
- C.rb_iseq_line_no(iseq, (pc - iseq.body.iseq_encoded.to_i) / C.VALUE.size)
- rescue RangeError # bignum too big to convert into `unsigned long long' (RangeError)
- -1
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/hooks.rb b/lib/ruby_vm/rjit/hooks.rb
deleted file mode 100644
index ea9d7bf5a8..0000000000
--- a/lib/ruby_vm/rjit/hooks.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-module RubyVM::RJIT
- module Hooks # :nodoc: all
- def self.on_bop_redefined(_redefined_flag, _bop)
- # C.rjit_cancel_all("BOP is redefined")
- end
-
- def self.on_cme_invalidate(cme)
- cme = C.rb_callable_method_entry_struct.new(cme)
- Invariants.on_cme_invalidate(cme)
- end
-
- def self.on_ractor_spawn
- # C.rjit_cancel_all("Ractor is spawned")
- end
-
- # Global constant changes like const_set
- def self.on_constant_state_changed(id)
- Invariants.on_constant_state_changed(id)
- end
-
- # ISEQ-specific constant invalidation
- def self.on_constant_ic_update(iseq, ic, insn_idx)
- iseq = C.rb_iseq_t.new(iseq)
- ic = C.IC.new(ic)
- Invariants.on_constant_ic_update(iseq, ic, insn_idx)
- end
-
- def self.on_tracing_invalidate_all(_new_iseq_events)
- Invariants.on_tracing_invalidate_all
- end
-
- def self.on_update_references
- Invariants.on_update_references
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb
deleted file mode 100644
index 289963d855..0000000000
--- a/lib/ruby_vm/rjit/insn_compiler.rb
+++ /dev/null
@@ -1,5972 +0,0 @@
-# frozen_string_literal: true
-module RubyVM::RJIT
- class InsnCompiler
- # struct rb_calling_info. Storing flags instead of ci.
- CallingInfo = Struct.new(:argc, :flags, :kwarg, :ci_addr, :send_shift, :block_handler) do
- def kw_splat = flags & C::VM_CALL_KW_SPLAT != 0
- end
-
- # @param ocb [CodeBlock]
- # @param exit_compiler [RubyVM::RJIT::ExitCompiler]
- def initialize(cb, ocb, exit_compiler)
- @ocb = ocb
- @exit_compiler = exit_compiler
-
- @cfunc_codegen_table = {}
- register_cfunc_codegen_funcs
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- # @param insn `RubyVM::RJIT::Instruction`
- def compile(jit, ctx, asm, insn)
- asm.incr_counter(:rjit_insns_count)
-
- stack = ctx.stack_size.times.map do |stack_idx|
- ctx.get_opnd_type(StackOpnd[ctx.stack_size - stack_idx - 1]).type
- end
- locals = jit.iseq.body.local_table_size.times.map do |local_idx|
- (ctx.local_types[local_idx] || Type::Unknown).type
- end
-
- insn_idx = format('%04d', (jit.pc.to_i - jit.iseq.body.iseq_encoded.to_i) / C.VALUE.size)
- asm.comment("Insn: #{insn_idx} #{insn.name} (stack: [#{stack.join(', ')}], locals: [#{locals.join(', ')}])")
-
- # 83/102
- case insn.name
- when :nop then nop(jit, ctx, asm)
- when :getlocal then getlocal(jit, ctx, asm)
- when :setlocal then setlocal(jit, ctx, asm)
- when :getblockparam then getblockparam(jit, ctx, asm)
- # setblockparam
- when :getblockparamproxy then getblockparamproxy(jit, ctx, asm)
- when :getspecial then getspecial(jit, ctx, asm)
- # setspecial
- when :getinstancevariable then getinstancevariable(jit, ctx, asm)
- when :setinstancevariable then setinstancevariable(jit, ctx, asm)
- when :getclassvariable then getclassvariable(jit, ctx, asm)
- when :setclassvariable then setclassvariable(jit, ctx, asm)
- when :opt_getconstant_path then opt_getconstant_path(jit, ctx, asm)
- when :getconstant then getconstant(jit, ctx, asm)
- # setconstant
- when :getglobal then getglobal(jit, ctx, asm)
- # setglobal
- when :putnil then putnil(jit, ctx, asm)
- when :putself then putself(jit, ctx, asm)
- when :putobject then putobject(jit, ctx, asm)
- when :putspecialobject then putspecialobject(jit, ctx, asm)
- when :putstring then putstring(jit, ctx, asm)
- when :concatstrings then concatstrings(jit, ctx, asm)
- when :anytostring then anytostring(jit, ctx, asm)
- when :toregexp then toregexp(jit, ctx, asm)
- when :intern then intern(jit, ctx, asm)
- when :newarray then newarray(jit, ctx, asm)
- # newarraykwsplat
- when :duparray then duparray(jit, ctx, asm)
- # duphash
- when :expandarray then expandarray(jit, ctx, asm)
- when :concatarray then concatarray(jit, ctx, asm)
- when :splatarray then splatarray(jit, ctx, asm)
- when :newhash then newhash(jit, ctx, asm)
- when :newrange then newrange(jit, ctx, asm)
- when :pop then pop(jit, ctx, asm)
- when :dup then dup(jit, ctx, asm)
- when :dupn then dupn(jit, ctx, asm)
- when :swap then swap(jit, ctx, asm)
- # opt_reverse
- when :topn then topn(jit, ctx, asm)
- when :setn then setn(jit, ctx, asm)
- when :adjuststack then adjuststack(jit, ctx, asm)
- when :defined then defined(jit, ctx, asm)
- when :definedivar then definedivar(jit, ctx, asm)
- # checkmatch
- when :checkkeyword then checkkeyword(jit, ctx, asm)
- # checktype
- # defineclass
- # definemethod
- # definesmethod
- when :send then send(jit, ctx, asm)
- when :opt_send_without_block then opt_send_without_block(jit, ctx, asm)
- when :objtostring then objtostring(jit, ctx, asm)
- when :opt_str_freeze then opt_str_freeze(jit, ctx, asm)
- when :opt_nil_p then opt_nil_p(jit, ctx, asm)
- # opt_str_uminus
- when :opt_newarray_send then opt_newarray_send(jit, ctx, asm)
- when :invokesuper then invokesuper(jit, ctx, asm)
- when :invokeblock then invokeblock(jit, ctx, asm)
- when :leave then leave(jit, ctx, asm)
- when :throw then throw(jit, ctx, asm)
- when :jump then jump(jit, ctx, asm)
- when :branchif then branchif(jit, ctx, asm)
- when :branchunless then branchunless(jit, ctx, asm)
- when :branchnil then branchnil(jit, ctx, asm)
- # once
- when :opt_case_dispatch then opt_case_dispatch(jit, ctx, asm)
- when :opt_plus then opt_plus(jit, ctx, asm)
- when :opt_minus then opt_minus(jit, ctx, asm)
- when :opt_mult then opt_mult(jit, ctx, asm)
- when :opt_div then opt_div(jit, ctx, asm)
- when :opt_mod then opt_mod(jit, ctx, asm)
- when :opt_eq then opt_eq(jit, ctx, asm)
- when :opt_neq then opt_neq(jit, ctx, asm)
- when :opt_lt then opt_lt(jit, ctx, asm)
- when :opt_le then opt_le(jit, ctx, asm)
- when :opt_gt then opt_gt(jit, ctx, asm)
- when :opt_ge then opt_ge(jit, ctx, asm)
- when :opt_ltlt then opt_ltlt(jit, ctx, asm)
- when :opt_and then opt_and(jit, ctx, asm)
- when :opt_or then opt_or(jit, ctx, asm)
- when :opt_aref then opt_aref(jit, ctx, asm)
- when :opt_aset then opt_aset(jit, ctx, asm)
- # opt_aset_with
- # opt_aref_with
- when :opt_length then opt_length(jit, ctx, asm)
- when :opt_size then opt_size(jit, ctx, asm)
- when :opt_empty_p then opt_empty_p(jit, ctx, asm)
- when :opt_succ then opt_succ(jit, ctx, asm)
- when :opt_not then opt_not(jit, ctx, asm)
- when :opt_regexpmatch2 then opt_regexpmatch2(jit, ctx, asm)
- # invokebuiltin
- when :opt_invokebuiltin_delegate then opt_invokebuiltin_delegate(jit, ctx, asm)
- when :opt_invokebuiltin_delegate_leave then opt_invokebuiltin_delegate_leave(jit, ctx, asm)
- when :getlocal_WC_0 then getlocal_WC_0(jit, ctx, asm)
- when :getlocal_WC_1 then getlocal_WC_1(jit, ctx, asm)
- when :setlocal_WC_0 then setlocal_WC_0(jit, ctx, asm)
- when :setlocal_WC_1 then setlocal_WC_1(jit, ctx, asm)
- when :putobject_INT2FIX_0_ then putobject_INT2FIX_0_(jit, ctx, asm)
- when :putobject_INT2FIX_1_ then putobject_INT2FIX_1_(jit, ctx, asm)
- else CantCompile
- end
- end
-
- private
-
- #
- # Insns
- #
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def nop(jit, ctx, asm)
- # Do nothing
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getlocal(jit, ctx, asm)
- idx = jit.operand(0)
- level = jit.operand(1)
- jit_getlocal_generic(jit, ctx, asm, idx:, level:)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getlocal_WC_0(jit, ctx, asm)
- idx = jit.operand(0)
- jit_getlocal_generic(jit, ctx, asm, idx:, level: 0)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getlocal_WC_1(jit, ctx, asm)
- idx = jit.operand(0)
- jit_getlocal_generic(jit, ctx, asm, idx:, level: 1)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def setlocal(jit, ctx, asm)
- idx = jit.operand(0)
- level = jit.operand(1)
- jit_setlocal_generic(jit, ctx, asm, idx:, level:)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def setlocal_WC_0(jit, ctx, asm)
- idx = jit.operand(0)
- jit_setlocal_generic(jit, ctx, asm, idx:, level: 0)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def setlocal_WC_1(jit, ctx, asm)
- idx = jit.operand(0)
- jit_setlocal_generic(jit, ctx, asm, idx:, level: 1)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getblockparam(jit, ctx, asm)
- # EP level
- level = jit.operand(1)
-
- # Save the PC and SP because we might allocate
- jit_prepare_routine_call(jit, ctx, asm)
-
- # A mirror of the interpreter code. Checking for the case
- # where it's pushing rb_block_param_proxy.
- side_exit = side_exit(jit, ctx)
-
- # Load environment pointer EP from CFP
- ep_reg = :rax
- jit_get_ep(asm, level, reg: ep_reg)
-
- # Bail when VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM) is non zero
- # FIXME: This is testing bits in the same place that the WB check is testing.
- # We should combine these at some point
- asm.test([ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_FLAGS], C::VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)
-
- # If the frame flag has been modified, then the actual proc value is
- # already in the EP and we should just use the value.
- frame_flag_modified = asm.new_label('frame_flag_modified')
- asm.jnz(frame_flag_modified)
-
- # This instruction writes the block handler to the EP. If we need to
- # fire a write barrier for the write, then exit (we'll let the
- # interpreter handle it so it can fire the write barrier).
- # flags & VM_ENV_FLAG_WB_REQUIRED
- asm.test([ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_FLAGS], C::VM_ENV_FLAG_WB_REQUIRED)
-
- # if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
- asm.jnz(side_exit)
-
- # Convert the block handler in to a proc
- # call rb_vm_bh_to_procval(const rb_execution_context_t *ec, VALUE block_handler)
- asm.mov(C_ARGS[0], EC)
- # The block handler for the current frame
- # note, VM_ASSERT(VM_ENV_LOCAL_P(ep))
- asm.mov(C_ARGS[1], [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL])
- asm.call(C.rb_vm_bh_to_procval)
-
- # Load environment pointer EP from CFP (again)
- ep_reg = :rcx
- jit_get_ep(asm, level, reg: ep_reg)
-
- # Write the value at the environment pointer
- idx = jit.operand(0)
- offs = -(C.VALUE.size * idx)
- asm.mov([ep_reg, offs], C_RET);
-
- # Set the frame modified flag
- asm.mov(:rax, [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_FLAGS]) # flag_check
- asm.or(:rax, C::VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM) # modified_flag
- asm.mov([ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_FLAGS], :rax)
-
- asm.write_label(frame_flag_modified)
-
- # Push the proc on the stack
- stack_ret = ctx.stack_push(Type::Unknown)
- ep_reg = :rax
- jit_get_ep(asm, level, reg: ep_reg)
- asm.mov(:rax, [ep_reg, offs])
- asm.mov(stack_ret, :rax)
-
- KeepCompiling
- end
-
- # setblockparam
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getblockparamproxy(jit, ctx, asm)
- # To get block_handler
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- starting_context = ctx.dup # make a copy for use with jit_chain_guard
-
- # A mirror of the interpreter code. Checking for the case
- # where it's pushing rb_block_param_proxy.
- side_exit = side_exit(jit, ctx)
-
- # EP level
- level = jit.operand(1)
-
- # Peek at the block handler so we can check whether it's nil
- comptime_handler = jit.peek_at_block_handler(level)
-
- # When a block handler is present, it should always be a GC-guarded
- # pointer (VM_BH_ISEQ_BLOCK_P)
- if comptime_handler != 0 && comptime_handler & 0x3 != 0x1
- asm.incr_counter(:getblockpp_not_gc_guarded)
- return CantCompile
- end
-
- # Load environment pointer EP from CFP
- ep_reg = :rax
- jit_get_ep(asm, level, reg: ep_reg)
-
- # Bail when VM_ENV_FLAGS(ep, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM) is non zero
- asm.test([ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_FLAGS], C::VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)
- asm.jnz(counted_exit(side_exit, :getblockpp_block_param_modified))
-
- # Load the block handler for the current frame
- # note, VM_ASSERT(VM_ENV_LOCAL_P(ep))
- block_handler = :rax
- asm.mov(block_handler, [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL])
-
- # Specialize compilation for the case where no block handler is present
- if comptime_handler == 0
- # Bail if there is a block handler
- asm.cmp(block_handler, 0)
-
- jit_chain_guard(:jnz, jit, starting_context, asm, counted_exit(side_exit, :getblockpp_block_handler_none))
-
- putobject(jit, ctx, asm, val: Qnil)
- else
- # Block handler is a tagged pointer. Look at the tag. 0x03 is from VM_BH_ISEQ_BLOCK_P().
- asm.and(block_handler, 0x3)
-
- # Bail unless VM_BH_ISEQ_BLOCK_P(bh). This also checks for null.
- asm.cmp(block_handler, 0x1)
-
- jit_chain_guard(:jnz, jit, starting_context, asm, counted_exit(side_exit, :getblockpp_not_iseq_block))
-
- # Push rb_block_param_proxy. It's a root, so no need to use jit_mov_gc_ptr.
- top = ctx.stack_push(Type::BlockParamProxy)
- asm.mov(:rax, C.rb_block_param_proxy)
- asm.mov(top, :rax)
- end
-
- jump_to_next_insn(jit, ctx, asm)
-
- EndBlock
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getspecial(jit, ctx, asm)
- # This takes two arguments, key and type
- # key is only used when type == 0
- # A non-zero type determines which type of backref to fetch
- #rb_num_t key = jit.jit_get_arg(0);
- rtype = jit.operand(1)
-
- if rtype == 0
- # not yet implemented
- return CantCompile;
- elsif rtype & 0x01 != 0
- # Fetch a "special" backref based on a char encoded by shifting by 1
-
- # Can raise if matchdata uninitialized
- jit_prepare_routine_call(jit, ctx, asm)
-
- # call rb_backref_get()
- asm.comment('rb_backref_get')
- asm.call(C.rb_backref_get)
-
- asm.mov(C_ARGS[0], C_RET) # backref
- case [rtype >> 1].pack('c')
- in ?&
- asm.comment("rb_reg_last_match")
- asm.call(C.rb_reg_last_match)
- in ?`
- asm.comment("rb_reg_match_pre")
- asm.call(C.rb_reg_match_pre)
- in ?'
- asm.comment("rb_reg_match_post")
- asm.call(C.rb_reg_match_post)
- in ?+
- asm.comment("rb_reg_match_last")
- asm.call(C.rb_reg_match_last)
- end
-
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- else
- # Fetch the N-th match from the last backref based on type shifted by 1
-
- # Can raise if matchdata uninitialized
- jit_prepare_routine_call(jit, ctx, asm)
-
- # call rb_backref_get()
- asm.comment('rb_backref_get')
- asm.call(C.rb_backref_get)
-
- # rb_reg_nth_match((int)(type >> 1), backref);
- asm.comment('rb_reg_nth_match')
- asm.mov(C_ARGS[0], rtype >> 1)
- asm.mov(C_ARGS[1], C_RET) # backref
- asm.call(C.rb_reg_nth_match)
-
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
- end
-
- # setspecial
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getinstancevariable(jit, ctx, asm)
- # Specialize on a compile-time receiver, and split a block for chain guards
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- id = jit.operand(0)
- comptime_obj = jit.peek_at_self
-
- jit_getivar(jit, ctx, asm, comptime_obj, id, nil, SelfOpnd)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def setinstancevariable(jit, ctx, asm)
- starting_context = ctx.dup # make a copy for use with jit_chain_guard
-
- # Defer compilation so we can specialize on a runtime `self`
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- ivar_name = jit.operand(0)
- comptime_receiver = jit.peek_at_self
-
- # If the comptime receiver is frozen, writing an IV will raise an exception
- # and we don't want to JIT code to deal with that situation.
- if C.rb_obj_frozen_p(comptime_receiver)
- asm.incr_counter(:setivar_frozen)
- return CantCompile
- end
-
- # Check if the comptime receiver is a T_OBJECT
- receiver_t_object = C::BUILTIN_TYPE(comptime_receiver) == C::T_OBJECT
-
- # If the receiver isn't a T_OBJECT, or uses a custom allocator,
- # then just write out the IV write as a function call.
- # too-complex shapes can't use index access, so we use rb_ivar_get for them too.
- if !receiver_t_object || shape_too_complex?(comptime_receiver) || ctx.chain_depth >= 10
- asm.comment('call rb_vm_setinstancevariable')
-
- ic = jit.operand(1)
-
- # The function could raise exceptions.
- # Note that this modifies REG_SP, which is why we do it first
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Get the operands from the stack
- val_opnd = ctx.stack_pop(1)
-
- # Call rb_vm_setinstancevariable(iseq, obj, id, val, ic);
- asm.mov(:rdi, jit.iseq.to_i)
- asm.mov(:rsi, [CFP, C.rb_control_frame_t.offsetof(:self)])
- asm.mov(:rdx, ivar_name)
- asm.mov(:rcx, val_opnd)
- asm.mov(:r8, ic)
- asm.call(C.rb_vm_setinstancevariable)
- else
- # Get the iv index
- shape_id = C.rb_shape_get_shape_id(comptime_receiver)
- ivar_index = C.rb_shape_get_iv_index(shape_id, ivar_name)
-
- # Get the receiver
- asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
-
- # Generate a side exit
- side_exit = side_exit(jit, ctx)
-
- # Upgrade type
- guard_object_is_heap(jit, ctx, asm, :rax, SelfOpnd, :setivar_not_heap)
-
- asm.comment('guard shape')
- asm.cmp(DwordPtr[:rax, C.rb_shape_id_offset], shape_id)
- megamorphic_side_exit = counted_exit(side_exit, :setivar_megamorphic)
- jit_chain_guard(:jne, jit, starting_context, asm, megamorphic_side_exit)
-
- # If we don't have an instance variable index, then we need to
- # transition out of the current shape.
- if ivar_index.nil?
- shape = C.rb_shape_get_shape_by_id(shape_id)
-
- current_capacity = shape.capacity
- dest_shape = C.rb_shape_get_next_no_warnings(shape, comptime_receiver, ivar_name)
- new_shape_id = C.rb_shape_id(dest_shape)
-
- if new_shape_id == C::OBJ_TOO_COMPLEX_SHAPE_ID
- asm.incr_counter(:setivar_too_complex)
- return CantCompile
- end
-
- ivar_index = shape.next_iv_index
-
- # If the new shape has a different capacity, we need to
- # reallocate the object.
- needs_extension = dest_shape.capacity != shape.capacity
-
- if needs_extension
- # Generate the C call so that runtime code will increase
- # the capacity and set the buffer.
- asm.mov(C_ARGS[0], :rax)
- asm.mov(C_ARGS[1], current_capacity)
- asm.mov(C_ARGS[2], dest_shape.capacity)
- asm.call(C.rb_ensure_iv_list_size)
-
- # Load the receiver again after the function call
- asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
- end
-
- write_val = ctx.stack_pop(1)
- jit_write_iv(asm, comptime_receiver, :rax, :rcx, ivar_index, write_val, needs_extension)
-
- # Store the new shape
- asm.comment('write shape')
- asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)]) # reload after jit_write_iv
- asm.mov(DwordPtr[:rax, C.rb_shape_id_offset], new_shape_id)
- else
- # If the iv index already exists, then we don't need to
- # transition to a new shape. The reason is because we find
- # the iv index by searching up the shape tree. If we've
- # made the transition already, then there's no reason to
- # update the shape on the object. Just set the IV.
- write_val = ctx.stack_pop(1)
- jit_write_iv(asm, comptime_receiver, :rax, :rcx, ivar_index, write_val, false)
- end
-
- skip_wb = asm.new_label('skip_wb')
- # If the value we're writing is an immediate, we don't need to WB
- asm.test(write_val, C::RUBY_IMMEDIATE_MASK)
- asm.jnz(skip_wb)
-
- # If the value we're writing is nil or false, we don't need to WB
- asm.cmp(write_val, Qnil)
- asm.jbe(skip_wb)
-
- asm.comment('write barrier')
- asm.mov(C_ARGS[0], [CFP, C.rb_control_frame_t.offsetof(:self)]) # reload after jit_write_iv
- asm.mov(C_ARGS[1], write_val)
- asm.call(C.rb_gc_writebarrier)
-
- asm.write_label(skip_wb)
- end
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getclassvariable(jit, ctx, asm)
- # rb_vm_getclassvariable can raise exceptions.
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.mov(C_ARGS[0], [CFP, C.rb_control_frame_t.offsetof(:iseq)])
- asm.mov(C_ARGS[1], CFP)
- asm.mov(C_ARGS[2], jit.operand(0))
- asm.mov(C_ARGS[3], jit.operand(1))
- asm.call(C.rb_vm_getclassvariable)
-
- top = ctx.stack_push(Type::Unknown)
- asm.mov(top, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def setclassvariable(jit, ctx, asm)
- # rb_vm_setclassvariable can raise exceptions.
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.mov(C_ARGS[0], [CFP, C.rb_control_frame_t.offsetof(:iseq)])
- asm.mov(C_ARGS[1], CFP)
- asm.mov(C_ARGS[2], jit.operand(0))
- asm.mov(C_ARGS[3], ctx.stack_pop(1))
- asm.mov(C_ARGS[4], jit.operand(1))
- asm.call(C.rb_vm_setclassvariable)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_getconstant_path(jit, ctx, asm)
- # Cut the block for invalidation
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- ic = C.iseq_inline_constant_cache.new(jit.operand(0))
- idlist = ic.segments
-
- # Make sure there is an exit for this block as the interpreter might want
- # to invalidate this block from rb_rjit_constant_ic_update().
- # For now, we always take an entry exit even if it was a side exit.
- Invariants.ensure_block_entry_exit(jit, cause: 'opt_getconstant_path')
-
- # See vm_ic_hit_p(). The same conditions are checked in yjit_constant_ic_update().
- ice = ic.entry
- if ice.nil?
- # In this case, leave a block that unconditionally side exits
- # for the interpreter to invalidate.
- asm.incr_counter(:optgetconst_not_cached)
- return CantCompile
- end
-
- if ice.ic_cref # with cref
- # Cache is keyed on a certain lexical scope. Use the interpreter's cache.
- side_exit = side_exit(jit, ctx)
-
- # Call function to verify the cache. It doesn't allocate or call methods.
- asm.mov(C_ARGS[0], ic.to_i)
- asm.mov(C_ARGS[1], [CFP, C.rb_control_frame_t.offsetof(:ep)])
- asm.call(C.rb_vm_ic_hit_p)
-
- # Check the result. SysV only specifies one byte for _Bool return values,
- # so it's important we only check one bit to ignore the higher bits in the register.
- asm.test(C_RET, 1)
- asm.jz(counted_exit(side_exit, :optgetconst_cache_miss))
-
- asm.mov(:rax, ic.to_i) # inline_cache
- asm.mov(:rax, [:rax, C.iseq_inline_constant_cache.offsetof(:entry)]) # ic_entry
- asm.mov(:rax, [:rax, C.iseq_inline_constant_cache_entry.offsetof(:value)]) # ic_entry_val
-
- # Push ic->entry->value
- stack_top = ctx.stack_push(Type::Unknown)
- asm.mov(stack_top, :rax)
- else # without cref
- # TODO: implement this
- # Optimize for single ractor mode.
- # if !assume_single_ractor_mode(jit, ocb)
- # return CantCompile
- # end
-
- # Invalidate output code on any constant writes associated with
- # constants referenced within the current block.
- Invariants.assume_stable_constant_names(jit, idlist)
-
- putobject(jit, ctx, asm, val: ice.value)
- end
-
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getconstant(jit, ctx, asm)
- id = jit.operand(0)
-
- # vm_get_ev_const can raise exceptions.
- jit_prepare_routine_call(jit, ctx, asm)
-
- allow_nil_opnd = ctx.stack_pop(1)
- klass_opnd = ctx.stack_pop(1)
-
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], klass_opnd)
- asm.mov(C_ARGS[2], id)
- asm.mov(C_ARGS[3], allow_nil_opnd)
- asm.call(C.rb_vm_get_ev_const)
-
- top = ctx.stack_push(Type::Unknown)
- asm.mov(top, C_RET)
-
- KeepCompiling
- end
-
- # setconstant
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def getglobal(jit, ctx, asm)
- gid = jit.operand(0)
-
- # Save the PC and SP because we might make a Ruby call for warning
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.mov(C_ARGS[0], gid)
- asm.call(C.rb_gvar_get)
-
- top = ctx.stack_push(Type::Unknown)
- asm.mov(top, C_RET)
-
- KeepCompiling
- end
-
- # setglobal
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putnil(jit, ctx, asm)
- putobject(jit, ctx, asm, val: Qnil)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putself(jit, ctx, asm)
- stack_top = ctx.stack_push_self
- asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
- asm.mov(stack_top, :rax)
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putobject(jit, ctx, asm, val: jit.operand(0))
- # Push it to the stack
- val_type = Type.from(C.to_ruby(val))
- stack_top = ctx.stack_push(val_type)
- if asm.imm32?(val)
- asm.mov(stack_top, val)
- else # 64-bit immediates can't be directly written to memory
- asm.mov(:rax, val)
- asm.mov(stack_top, :rax)
- end
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putspecialobject(jit, ctx, asm)
- object_type = jit.operand(0)
- if object_type == C::VM_SPECIAL_OBJECT_VMCORE
- stack_top = ctx.stack_push(Type::UnknownHeap)
- asm.mov(:rax, C.rb_mRubyVMFrozenCore)
- asm.mov(stack_top, :rax)
- KeepCompiling
- else
- # TODO: implement for VM_SPECIAL_OBJECT_CBASE and
- # VM_SPECIAL_OBJECT_CONST_BASE
- CantCompile
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putstring(jit, ctx, asm)
- put_val = jit.operand(0, ruby: true)
-
- # Save the PC and SP because the callee will allocate
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], to_value(put_val))
- asm.call(C.rb_ec_str_resurrect)
-
- stack_top = ctx.stack_push(Type::TString)
- asm.mov(stack_top, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def concatstrings(jit, ctx, asm)
- n = jit.operand(0)
-
- # Save the PC and SP because we are allocating
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.lea(:rax, ctx.sp_opnd(-C.VALUE.size * n))
-
- # call rb_str_concat_literals(size_t n, const VALUE *strings);
- asm.mov(C_ARGS[0], n)
- asm.mov(C_ARGS[1], :rax)
- asm.call(C.rb_str_concat_literals)
-
- ctx.stack_pop(n)
- stack_ret = ctx.stack_push(Type::TString)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def anytostring(jit, ctx, asm)
- # Save the PC and SP since we might call #to_s
- jit_prepare_routine_call(jit, ctx, asm)
-
- str = ctx.stack_pop(1)
- val = ctx.stack_pop(1)
-
- asm.mov(C_ARGS[0], str)
- asm.mov(C_ARGS[1], val)
- asm.call(C.rb_obj_as_string_result)
-
- # Push the return value
- stack_ret = ctx.stack_push(Type::TString)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def toregexp(jit, ctx, asm)
- opt = jit.operand(0, signed: true)
- cnt = jit.operand(1)
-
- # Save the PC and SP because this allocates an object and could
- # raise an exception.
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.lea(:rax, ctx.sp_opnd(-C.VALUE.size * cnt)) # values_ptr
- ctx.stack_pop(cnt)
-
- asm.mov(C_ARGS[0], 0)
- asm.mov(C_ARGS[1], cnt)
- asm.mov(C_ARGS[2], :rax) # values_ptr
- asm.call(C.rb_ary_tmp_new_from_values)
-
- # Save the array so we can clear it later
- asm.push(C_RET)
- asm.push(C_RET) # Alignment
-
- asm.mov(C_ARGS[0], C_RET)
- asm.mov(C_ARGS[1], opt)
- asm.call(C.rb_reg_new_ary)
-
- # The actual regex is in RAX now. Pop the temp array from
- # rb_ary_tmp_new_from_values into C arg regs so we can clear it
- asm.pop(:rcx) # Alignment
- asm.pop(:rcx) # ary
-
- # The value we want to push on the stack is in RAX right now
- stack_ret = ctx.stack_push(Type::UnknownHeap)
- asm.mov(stack_ret, C_RET)
-
- # Clear the temp array.
- asm.mov(C_ARGS[0], :rcx) # ary
- asm.call(C.rb_ary_clear)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def intern(jit, ctx, asm)
- # Save the PC and SP because we might allocate
- jit_prepare_routine_call(jit, ctx, asm);
-
- str = ctx.stack_pop(1)
- asm.mov(C_ARGS[0], str)
- asm.call(C.rb_str_intern)
-
- # Push the return value
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def newarray(jit, ctx, asm)
- n = jit.operand(0)
-
- # Save the PC and SP because we are allocating
- jit_prepare_routine_call(jit, ctx, asm)
-
- # If n is 0, then elts is never going to be read, so we can just pass null
- if n == 0
- values_ptr = 0
- else
- asm.comment('load pointer to array elts')
- offset_magnitude = C.VALUE.size * n
- values_opnd = ctx.sp_opnd(-(offset_magnitude))
- asm.lea(:rax, values_opnd)
- values_ptr = :rax
- end
-
- # call rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts);
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], n)
- asm.mov(C_ARGS[2], values_ptr)
- asm.call(C.rb_ec_ary_new_from_values)
-
- ctx.stack_pop(n)
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # newarraykwsplat
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def duparray(jit, ctx, asm)
- ary = jit.operand(0)
-
- # Save the PC and SP because we are allocating
- jit_prepare_routine_call(jit, ctx, asm)
-
- # call rb_ary_resurrect(VALUE ary);
- asm.comment('call rb_ary_resurrect')
- asm.mov(C_ARGS[0], ary)
- asm.call(C.rb_ary_resurrect)
-
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # duphash
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def expandarray(jit, ctx, asm)
- # Both arguments are rb_num_t which is unsigned
- num = jit.operand(0)
- flag = jit.operand(1)
-
- # If this instruction has the splat flag, then bail out.
- if flag & 0x01 != 0
- asm.incr_counter(:expandarray_splat)
- return CantCompile
- end
-
- # If this instruction has the postarg flag, then bail out.
- if flag & 0x02 != 0
- asm.incr_counter(:expandarray_postarg)
- return CantCompile
- end
-
- side_exit = side_exit(jit, ctx)
-
- array_opnd = ctx.stack_opnd(0)
- array_stack_opnd = StackOpnd[0]
-
- # num is the number of requested values. If there aren't enough in the
- # array then we're going to push on nils.
- if ctx.get_opnd_type(array_stack_opnd) == Type::Nil
- ctx.stack_pop(1) # pop after using the type info
- # special case for a, b = nil pattern
- # push N nils onto the stack
- num.times do
- push_opnd = ctx.stack_push(Type::Nil)
- asm.mov(push_opnd, Qnil)
- end
- return KeepCompiling
- end
-
- # Move the array from the stack and check that it's an array.
- asm.mov(:rax, array_opnd)
- guard_object_is_array(jit, ctx, asm, :rax, :rcx, array_stack_opnd, :expandarray_not_array)
- ctx.stack_pop(1) # pop after using the type info
-
- # If we don't actually want any values, then just return.
- if num == 0
- return KeepCompiling
- end
-
- jit_array_len(asm, :rax, :rcx)
-
- # Only handle the case where the number of values in the array is greater
- # than or equal to the number of values requested.
- asm.cmp(:rcx, num)
- asm.jl(counted_exit(side_exit, :expandarray_rhs_too_small))
-
- # Conditionally load the address of the heap array into REG1.
- # (struct RArray *)(obj)->as.heap.ptr
- #asm.mov(:rax, array_opnd)
- asm.mov(:rcx, [:rax, C.RBasic.offsetof(:flags)])
- asm.test(:rcx, C::RARRAY_EMBED_FLAG);
- asm.mov(:rcx, [:rax, C.RArray.offsetof(:as, :heap, :ptr)])
-
- # Load the address of the embedded array into REG1.
- # (struct RArray *)(obj)->as.ary
- asm.lea(:rax, [:rax, C.RArray.offsetof(:as, :ary)])
-
- asm.cmovnz(:rcx, :rax)
-
- # Loop backward through the array and push each element onto the stack.
- (num - 1).downto(0).each do |i|
- top = ctx.stack_push(Type::Unknown)
- asm.mov(:rax, [:rcx, i * C.VALUE.size])
- asm.mov(top, :rax)
- end
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def concatarray(jit, ctx, asm)
- # Save the PC and SP because the callee may allocate
- # Note that this modifies REG_SP, which is why we do it first
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Get the operands from the stack
- ary2st_opnd = ctx.stack_pop(1)
- ary1_opnd = ctx.stack_pop(1)
-
- # Call rb_vm_concat_array(ary1, ary2st)
- asm.mov(C_ARGS[0], ary1_opnd)
- asm.mov(C_ARGS[1], ary2st_opnd)
- asm.call(C.rb_vm_concat_array)
-
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def splatarray(jit, ctx, asm)
- flag = jit.operand(0)
-
- # Save the PC and SP because the callee may allocate
- # Note that this modifies REG_SP, which is why we do it first
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Get the operands from the stack
- ary_opnd = ctx.stack_pop(1)
-
- # Call rb_vm_splat_array(flag, ary)
- asm.mov(C_ARGS[0], flag)
- asm.mov(C_ARGS[1], ary_opnd)
- asm.call(C.rb_vm_splat_array)
-
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def newhash(jit, ctx, asm)
- num = jit.operand(0)
-
- # Save the PC and SP because we are allocating
- jit_prepare_routine_call(jit, ctx, asm)
-
- if num != 0
- # val = rb_hash_new_with_size(num / 2);
- asm.mov(C_ARGS[0], num / 2)
- asm.call(C.rb_hash_new_with_size)
-
- # Save the allocated hash as we want to push it after insertion
- asm.push(C_RET)
- asm.push(C_RET) # x86 alignment
-
- # Get a pointer to the values to insert into the hash
- asm.lea(:rcx, ctx.stack_opnd(num - 1))
-
- # rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);
- asm.mov(C_ARGS[0], num)
- asm.mov(C_ARGS[1], :rcx)
- asm.mov(C_ARGS[2], C_RET)
- asm.call(C.rb_hash_bulk_insert)
-
- asm.pop(:rax)
- asm.pop(:rax)
-
- ctx.stack_pop(num)
- stack_ret = ctx.stack_push(Type::Hash)
- asm.mov(stack_ret, :rax)
- else
- # val = rb_hash_new();
- asm.call(C.rb_hash_new)
- stack_ret = ctx.stack_push(Type::Hash)
- asm.mov(stack_ret, C_RET)
- end
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def newrange(jit, ctx, asm)
- flag = jit.operand(0)
-
- # rb_range_new() allocates and can raise
- jit_prepare_routine_call(jit, ctx, asm)
-
- # val = rb_range_new(low, high, (int)flag);
- asm.mov(C_ARGS[0], ctx.stack_opnd(1))
- asm.mov(C_ARGS[1], ctx.stack_opnd(0))
- asm.mov(C_ARGS[2], flag)
- asm.call(C.rb_range_new)
-
- ctx.stack_pop(2)
- stack_ret = ctx.stack_push(Type::UnknownHeap)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def pop(jit, ctx, asm)
- ctx.stack_pop
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def dup(jit, ctx, asm)
- dup_val = ctx.stack_opnd(0)
- mapping, tmp_type = ctx.get_opnd_mapping(StackOpnd[0])
-
- loc0 = ctx.stack_push_mapping([mapping, tmp_type])
- asm.mov(:rax, dup_val)
- asm.mov(loc0, :rax)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def dupn(jit, ctx, asm)
- n = jit.operand(0)
-
- # In practice, seems to be only used for n==2
- if n != 2
- return CantCompile
- end
-
- opnd1 = ctx.stack_opnd(1)
- opnd0 = ctx.stack_opnd(0)
-
- mapping1 = ctx.get_opnd_mapping(StackOpnd[1])
- mapping0 = ctx.get_opnd_mapping(StackOpnd[0])
-
- dst1 = ctx.stack_push_mapping(mapping1)
- asm.mov(:rax, opnd1)
- asm.mov(dst1, :rax)
-
- dst0 = ctx.stack_push_mapping(mapping0)
- asm.mov(:rax, opnd0)
- asm.mov(dst0, :rax)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def swap(jit, ctx, asm)
- stack_swap(jit, ctx, asm, 0, 1)
- KeepCompiling
- end
-
- # opt_reverse
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def topn(jit, ctx, asm)
- n = jit.operand(0)
-
- top_n_val = ctx.stack_opnd(n)
- mapping = ctx.get_opnd_mapping(StackOpnd[n])
- loc0 = ctx.stack_push_mapping(mapping)
- asm.mov(:rax, top_n_val)
- asm.mov(loc0, :rax)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def setn(jit, ctx, asm)
- n = jit.operand(0)
-
- top_val = ctx.stack_pop(0)
- dst_opnd = ctx.stack_opnd(n)
- asm.mov(:rax, top_val)
- asm.mov(dst_opnd, :rax)
-
- mapping = ctx.get_opnd_mapping(StackOpnd[0])
- ctx.set_opnd_mapping(StackOpnd[n], mapping)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def adjuststack(jit, ctx, asm)
- n = jit.operand(0)
- ctx.stack_pop(n)
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def defined(jit, ctx, asm)
- op_type = jit.operand(0)
- obj = jit.operand(1, ruby: true)
- pushval = jit.operand(2, ruby: true)
-
- # Save the PC and SP because the callee may allocate
- # Note that this modifies REG_SP, which is why we do it first
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Get the operands from the stack
- v_opnd = ctx.stack_pop(1)
-
- # Call vm_defined(ec, reg_cfp, op_type, obj, v)
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], CFP)
- asm.mov(C_ARGS[2], op_type)
- asm.mov(C_ARGS[3], to_value(obj))
- asm.mov(C_ARGS[4], v_opnd)
- asm.call(C.rb_vm_defined)
-
- asm.test(C_RET, 255)
- asm.mov(:rax, Qnil)
- asm.mov(:rcx, to_value(pushval))
- asm.cmovnz(:rax, :rcx)
-
- # Push the return value onto the stack
- out_type = if C::SPECIAL_CONST_P(pushval)
- Type::UnknownImm
- else
- Type::Unknown
- end
- stack_ret = ctx.stack_push(out_type)
- asm.mov(stack_ret, :rax)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def definedivar(jit, ctx, asm)
- # Defer compilation so we can specialize base on a runtime receiver
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- ivar_name = jit.operand(0)
- # Value that will be pushed on the stack if the ivar is defined. In practice this is always the
- # string "instance-variable". If the ivar is not defined, nil will be pushed instead.
- pushval = jit.operand(2, ruby: true)
-
- # Get the receiver
- recv = :rcx
- asm.mov(recv, [CFP, C.rb_control_frame_t.offsetof(:self)])
-
- # Specialize base on compile time values
- comptime_receiver = jit.peek_at_self
-
- if shape_too_complex?(comptime_receiver)
- # Fall back to calling rb_ivar_defined
-
- # Save the PC and SP because the callee may allocate
- # Note that this modifies REG_SP, which is why we do it first
- jit_prepare_routine_call(jit, ctx, asm) # clobbers :rax
-
- # Call rb_ivar_defined(recv, ivar_name)
- asm.mov(C_ARGS[0], recv)
- asm.mov(C_ARGS[1], ivar_name)
- asm.call(C.rb_ivar_defined)
-
- # if (rb_ivar_defined(recv, ivar_name)) {
- # val = pushval;
- # }
- asm.test(C_RET, 255)
- asm.mov(:rax, Qnil)
- asm.mov(:rcx, to_value(pushval))
- asm.cmovnz(:rax, :rcx)
-
- # Push the return value onto the stack
- out_type = C::SPECIAL_CONST_P(pushval) ? Type::UnknownImm : Type::Unknown
- stack_ret = ctx.stack_push(out_type)
- asm.mov(stack_ret, :rax)
-
- return KeepCompiling
- end
-
- shape_id = C.rb_shape_get_shape_id(comptime_receiver)
- ivar_exists = C.rb_shape_get_iv_index(shape_id, ivar_name)
-
- side_exit = side_exit(jit, ctx)
-
- # Guard heap object (recv_opnd must be used before stack_pop)
- guard_object_is_heap(jit, ctx, asm, recv, SelfOpnd)
-
- shape_opnd = DwordPtr[recv, C.rb_shape_id_offset]
-
- asm.comment('guard shape')
- asm.cmp(shape_opnd, shape_id)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit)
-
- result = ivar_exists ? C.to_value(pushval) : Qnil
- putobject(jit, ctx, asm, val: result)
-
- # Jump to next instruction. This allows guard chains to share the same successor.
- jump_to_next_insn(jit, ctx, asm)
-
- return EndBlock
- end
-
- # checkmatch
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def checkkeyword(jit, ctx, asm)
- # When a keyword is unspecified past index 32, a hash will be used
- # instead. This can only happen in iseqs taking more than 32 keywords.
- if jit.iseq.body.param.keyword.num >= 32
- return CantCompile
- end
-
- # The EP offset to the undefined bits local
- bits_offset = jit.operand(0)
-
- # The index of the keyword we want to check
- index = jit.operand(1, signed: true)
-
- # Load environment pointer EP
- ep_reg = :rax
- jit_get_ep(asm, 0, reg: ep_reg)
-
- # VALUE kw_bits = *(ep - bits)
- bits_opnd = [ep_reg, C.VALUE.size * -bits_offset]
-
- # unsigned int b = (unsigned int)FIX2ULONG(kw_bits);
- # if ((b & (0x01 << idx))) {
- #
- # We can skip the FIX2ULONG conversion by shifting the bit we test
- bit_test = 0x01 << (index + 1)
- asm.test(bits_opnd, bit_test)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmovz(:rax, :rcx)
-
- stack_ret = ctx.stack_push(Type::UnknownImm)
- asm.mov(stack_ret, :rax)
-
- KeepCompiling
- end
-
- # checktype
- # defineclass
- # definemethod
- # definesmethod
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def send(jit, ctx, asm)
- # Specialize on a compile-time receiver, and split a block for chain guards
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- cd = C.rb_call_data.new(jit.operand(0))
- blockiseq = jit.operand(1)
-
- # calling->ci
- mid = C.vm_ci_mid(cd.ci)
- calling = build_calling(ci: cd.ci, block_handler: blockiseq)
-
- # vm_sendish
- cme, comptime_recv_klass = jit_search_method(jit, ctx, asm, mid, calling)
- if cme == CantCompile
- return CantCompile
- end
- jit_call_general(jit, ctx, asm, mid, calling, cme, comptime_recv_klass)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_send_without_block(jit, ctx, asm, cd: C.rb_call_data.new(jit.operand(0)))
- # Specialize on a compile-time receiver, and split a block for chain guards
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- # calling->ci
- mid = C.vm_ci_mid(cd.ci)
- calling = build_calling(ci: cd.ci, block_handler: C::VM_BLOCK_HANDLER_NONE)
-
- # vm_sendish
- cme, comptime_recv_klass = jit_search_method(jit, ctx, asm, mid, calling)
- if cme == CantCompile
- return CantCompile
- end
- jit_call_general(jit, ctx, asm, mid, calling, cme, comptime_recv_klass)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def objtostring(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- recv = ctx.stack_opnd(0)
- comptime_recv = jit.peek_at_stack(0)
-
- if C.RB_TYPE_P(comptime_recv, C::RUBY_T_STRING)
- side_exit = side_exit(jit, ctx)
-
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_recv), recv, StackOpnd[0], comptime_recv, side_exit)
- # No work needed. The string value is already on the top of the stack.
- KeepCompiling
- else
- cd = C.rb_call_data.new(jit.operand(0))
- opt_send_without_block(jit, ctx, asm, cd:)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_str_freeze(jit, ctx, asm)
- unless Invariants.assume_bop_not_redefined(jit, C::STRING_REDEFINED_OP_FLAG, C::BOP_FREEZE)
- return CantCompile;
- end
-
- str = jit.operand(0, ruby: true)
-
- # Push the return value onto the stack
- stack_ret = ctx.stack_push(Type::CString)
- asm.mov(:rax, to_value(str))
- asm.mov(stack_ret, :rax)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_nil_p(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # opt_str_uminus
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_newarray_send(jit, ctx, asm)
- type = C.ID2SYM jit.operand(1)
-
- case type
- when :min then opt_newarray_min(jit, ctx, asm)
- when :max then opt_newarray_max(jit, ctx, asm)
- when :hash then opt_newarray_hash(jit, ctx, asm)
- else
- return CantCompile
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_newarray_min(jit, ctx, asm)
- num = jit.operand(0)
-
- # Save the PC and SP because we may allocate
- jit_prepare_routine_call(jit, ctx, asm)
-
- offset_magnitude = C.VALUE.size * num
- values_opnd = ctx.sp_opnd(-offset_magnitude)
- asm.lea(:rax, values_opnd)
-
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], num)
- asm.mov(C_ARGS[2], :rax)
- asm.call(C.rb_vm_opt_newarray_min)
-
- ctx.stack_pop(num)
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_newarray_max(jit, ctx, asm)
- num = jit.operand(0)
-
- # Save the PC and SP because we may allocate
- jit_prepare_routine_call(jit, ctx, asm)
-
- offset_magnitude = C.VALUE.size * num
- values_opnd = ctx.sp_opnd(-offset_magnitude)
- asm.lea(:rax, values_opnd)
-
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], num)
- asm.mov(C_ARGS[2], :rax)
- asm.call(C.rb_vm_opt_newarray_max)
-
- ctx.stack_pop(num)
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_newarray_hash(jit, ctx, asm)
- num = jit.operand(0)
-
- # Save the PC and SP because we may allocate
- jit_prepare_routine_call(jit, ctx, asm)
-
- offset_magnitude = C.VALUE.size * num
- values_opnd = ctx.sp_opnd(-offset_magnitude)
- asm.lea(:rax, values_opnd)
-
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], num)
- asm.mov(C_ARGS[2], :rax)
- asm.call(C.rb_vm_opt_newarray_hash)
-
- ctx.stack_pop(num)
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def invokesuper(jit, ctx, asm)
- cd = C.rb_call_data.new(jit.operand(0))
- block = jit.operand(1)
-
- # Defer compilation so we can specialize on class of receiver
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- me = C.rb_vm_frame_method_entry(jit.cfp)
- if me.nil?
- return CantCompile
- end
-
- # FIXME: We should track and invalidate this block when this cme is invalidated
- current_defined_class = me.defined_class
- mid = me.def.original_id
-
- if me.to_i != C.rb_callable_method_entry(current_defined_class, me.called_id).to_i
- # Though we likely could generate this call, as we are only concerned
- # with the method entry remaining valid, assume_method_lookup_stable
- # below requires that the method lookup matches as well
- return CantCompile
- end
-
- # vm_search_normal_superclass
- rbasic_klass = C.to_ruby(C.RBasic.new(C.to_value(current_defined_class)).klass)
- if C::BUILTIN_TYPE(current_defined_class) == C::RUBY_T_ICLASS && C::BUILTIN_TYPE(rbasic_klass) == C::RUBY_T_MODULE && \
- C::FL_TEST_RAW(rbasic_klass, C::RMODULE_IS_REFINEMENT)
- return CantCompile
- end
- comptime_superclass = C.rb_class_get_superclass(C.RCLASS_ORIGIN(current_defined_class))
-
- ci = cd.ci
- argc = C.vm_ci_argc(ci)
-
- ci_flags = C.vm_ci_flag(ci)
-
- # Don't JIT calls that aren't simple
- # Note, not using VM_CALL_ARGS_SIMPLE because sometimes we pass a block.
-
- if ci_flags & C::VM_CALL_KWARG != 0
- asm.incr_counter(:send_keywords)
- return CantCompile
- end
- if ci_flags & C::VM_CALL_KW_SPLAT != 0
- asm.incr_counter(:send_kw_splat)
- return CantCompile
- end
- if ci_flags & C::VM_CALL_ARGS_BLOCKARG != 0
- asm.incr_counter(:send_block_arg)
- return CantCompile
- end
-
- # Ensure we haven't rebound this method onto an incompatible class.
- # In the interpreter we try to avoid making this check by performing some
- # cheaper calculations first, but since we specialize on the method entry
- # and so only have to do this once at compile time this is fine to always
- # check and side exit.
- comptime_recv = jit.peek_at_stack(argc)
- unless C.obj_is_kind_of(comptime_recv, current_defined_class)
- return CantCompile
- end
-
- # Do method lookup
- cme = C.rb_callable_method_entry(comptime_superclass, mid)
-
- if cme.nil?
- return CantCompile
- end
-
- # Check that we'll be able to write this method dispatch before generating checks
- cme_def_type = cme.def.type
- if cme_def_type != C::VM_METHOD_TYPE_ISEQ && cme_def_type != C::VM_METHOD_TYPE_CFUNC
- # others unimplemented
- return CantCompile
- end
-
- asm.comment('guard known me')
- lep_opnd = :rax
- jit_get_lep(jit, asm, reg: lep_opnd)
- ep_me_opnd = [lep_opnd, C.VALUE.size * C::VM_ENV_DATA_INDEX_ME_CREF]
-
- asm.mov(:rcx, me.to_i)
- asm.cmp(ep_me_opnd, :rcx)
- asm.jne(counted_exit(side_exit(jit, ctx), :invokesuper_me_changed))
-
- if block == C::VM_BLOCK_HANDLER_NONE
- # Guard no block passed
- # rb_vm_frame_block_handler(GET_EC()->cfp) == VM_BLOCK_HANDLER_NONE
- # note, we assume VM_ASSERT(VM_ENV_LOCAL_P(ep))
- #
- # TODO: this could properly forward the current block handler, but
- # would require changes to gen_send_*
- asm.comment('guard no block given')
- ep_specval_opnd = [lep_opnd, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]
- asm.cmp(ep_specval_opnd, C::VM_BLOCK_HANDLER_NONE)
- asm.jne(counted_exit(side_exit(jit, ctx), :invokesuper_block))
- end
-
- # We need to assume that both our current method entry and the super
- # method entry we invoke remain stable
- Invariants.assume_method_lookup_stable(jit, me)
- Invariants.assume_method_lookup_stable(jit, cme)
-
- # Method calls may corrupt types
- ctx.clear_local_types
-
- calling = build_calling(ci:, block_handler: block)
- case cme_def_type
- in C::VM_METHOD_TYPE_ISEQ
- iseq = def_iseq_ptr(cme.def)
- frame_type = C::VM_FRAME_MAGIC_METHOD | C::VM_ENV_FLAG_LOCAL
- jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type:)
- in C::VM_METHOD_TYPE_CFUNC
- jit_call_cfunc(jit, ctx, asm, cme, calling)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def invokeblock(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- # Get call info
- cd = C.rb_call_data.new(jit.operand(0))
- calling = build_calling(ci: cd.ci, block_handler: :captured)
-
- # Get block_handler
- cfp = jit.cfp
- lep = C.rb_vm_ep_local_ep(cfp.ep)
- comptime_handler = lep[C::VM_ENV_DATA_INDEX_SPECVAL]
-
- # Handle each block_handler type
- if comptime_handler == C::VM_BLOCK_HANDLER_NONE # no block given
- asm.incr_counter(:invokeblock_none)
- CantCompile
- elsif comptime_handler & 0x3 == 0x1 # VM_BH_ISEQ_BLOCK_P
- asm.comment('get local EP')
- ep_reg = :rax
- jit_get_lep(jit, asm, reg: ep_reg)
- asm.mov(:rax, [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # block_handler_opnd
-
- asm.comment('guard block_handler type')
- side_exit = side_exit(jit, ctx)
- asm.mov(:rcx, :rax)
- asm.and(:rcx, 0x3) # block_handler is a tagged pointer
- asm.cmp(:rcx, 0x1) # VM_BH_ISEQ_BLOCK_P
- tag_changed_exit = counted_exit(side_exit, :invokeblock_tag_changed)
- jit_chain_guard(:jne, jit, ctx, asm, tag_changed_exit)
-
- comptime_captured = C.rb_captured_block.new(comptime_handler & ~0x3)
- comptime_iseq = comptime_captured.code.iseq
-
- asm.comment('guard known ISEQ')
- asm.and(:rax, ~0x3) # captured
- asm.mov(:rax, [:rax, C.VALUE.size * 2]) # captured->iseq
- asm.mov(:rcx, comptime_iseq.to_i)
- asm.cmp(:rax, :rcx)
- block_changed_exit = counted_exit(side_exit, :invokeblock_iseq_block_changed)
- jit_chain_guard(:jne, jit, ctx, asm, block_changed_exit)
-
- jit_call_iseq(jit, ctx, asm, nil, calling, comptime_iseq, frame_type: C::VM_FRAME_MAGIC_BLOCK)
- elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P
- # We aren't handling CALLER_SETUP_ARG and CALLER_REMOVE_EMPTY_KW_SPLAT yet.
- if calling.flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:invokeblock_ifunc_args_splat)
- return CantCompile
- end
- if calling.flags & C::VM_CALL_KW_SPLAT != 0
- asm.incr_counter(:invokeblock_ifunc_kw_splat)
- return CantCompile
- end
-
- asm.comment('get local EP')
- jit_get_lep(jit, asm, reg: :rax)
- asm.mov(:rcx, [:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # block_handler_opnd
-
- asm.comment('guard block_handler type');
- side_exit = side_exit(jit, ctx)
- asm.mov(:rax, :rcx) # block_handler_opnd
- asm.and(:rax, 0x3) # tag_opnd: block_handler is a tagged pointer
- asm.cmp(:rax, 0x3) # VM_BH_IFUNC_P
- tag_changed_exit = counted_exit(side_exit, :invokeblock_tag_changed)
- jit_chain_guard(:jne, jit, ctx, asm, tag_changed_exit)
-
- # The cfunc may not be leaf
- jit_prepare_routine_call(jit, ctx, asm) # clobbers :rax
-
- asm.comment('call ifunc')
- asm.and(:rcx, ~0x3) # captured_opnd
- asm.lea(:rax, ctx.sp_opnd(-calling.argc * C.VALUE.size)) # argv
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], :rcx) # captured_opnd
- asm.mov(C_ARGS[2], calling.argc)
- asm.mov(C_ARGS[3], :rax) # argv
- asm.call(C.rb_vm_yield_with_cfunc)
-
- ctx.stack_pop(calling.argc)
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- # cfunc calls may corrupt types
- ctx.clear_local_types
-
- # Share the successor with other chains
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- elsif symbol?(comptime_handler)
- asm.incr_counter(:invokeblock_symbol)
- CantCompile
- else # Proc
- asm.incr_counter(:invokeblock_proc)
- CantCompile
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def leave(jit, ctx, asm)
- assert_equal(ctx.stack_size, 1)
-
- jit_check_ints(jit, ctx, asm)
-
- asm.comment('pop stack frame')
- asm.lea(:rax, [CFP, C.rb_control_frame_t.size])
- asm.mov(CFP, :rax)
- asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], :rax)
-
- # Return a value (for compile_leave_exit)
- ret_opnd = ctx.stack_pop
- asm.mov(:rax, ret_opnd)
-
- # Set caller's SP and push a value to its stack (for JIT)
- asm.mov(SP, [CFP, C.rb_control_frame_t.offsetof(:sp)]) # Note: SP is in the position after popping a receiver and arguments
- asm.mov([SP], :rax)
-
- # Jump to cfp->jit_return
- asm.jmp([CFP, -C.rb_control_frame_t.size + C.rb_control_frame_t.offsetof(:jit_return)])
-
- EndBlock
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def throw(jit, ctx, asm)
- throw_state = jit.operand(0)
- asm.mov(:rcx, ctx.stack_pop(1)) # throwobj
-
- # THROW_DATA_NEW allocates. Save SP for GC and PC for allocation tracing as
- # well as handling the catch table. However, not using jit_prepare_routine_call
- # since we don't need a patch point for this implementation.
- jit_save_pc(jit, asm) # clobbers rax
- jit_save_sp(ctx, asm)
-
- # rb_vm_throw verifies it's a valid throw, sets ec->tag->state, and returns throw
- # data, which is throwobj or a vm_throw_data wrapping it. When ec->tag->state is
- # set, JIT code callers will handle the throw with vm_exec_handle_exception.
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], CFP)
- asm.mov(C_ARGS[2], throw_state)
- # asm.mov(C_ARGS[3], :rcx) # same reg
- asm.call(C.rb_vm_throw)
-
- asm.comment('exit from throw')
- asm.pop(SP)
- asm.pop(EC)
- asm.pop(CFP)
-
- # return C_RET as C_RET
- asm.ret
- EndBlock
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jump(jit, ctx, asm)
- # Check for interrupts, but only on backward branches that may create loops
- jump_offset = jit.operand(0, signed: true)
- if jump_offset < 0
- jit_check_ints(jit, ctx, asm)
- end
-
- pc = jit.pc + C.VALUE.size * (jit.insn.len + jump_offset)
- jit_direct_jump(jit.iseq, pc, ctx, asm)
- EndBlock
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def branchif(jit, ctx, asm)
- # Check for interrupts, but only on backward branches that may create loops
- jump_offset = jit.operand(0, signed: true)
- if jump_offset < 0
- jit_check_ints(jit, ctx, asm)
- end
-
- # Get the branch target instruction offsets
- next_pc = jit.pc + C.VALUE.size * jit.insn.len
- jump_pc = jit.pc + C.VALUE.size * (jit.insn.len + jump_offset)
-
- val_type = ctx.get_opnd_type(StackOpnd[0])
- val_opnd = ctx.stack_pop(1)
-
- if (result = val_type.known_truthy) != nil
- target_pc = result ? jump_pc : next_pc
- jit_direct_jump(jit.iseq, target_pc, ctx, asm)
- else
- # This `test` sets ZF only for Qnil and Qfalse, which let jz jump.
- asm.test(val_opnd, ~Qnil)
-
- # Set stubs
- branch_stub = BranchStub.new(
- iseq: jit.iseq,
- shape: Default,
- target0: BranchTarget.new(ctx:, pc: jump_pc), # branch target
- target1: BranchTarget.new(ctx:, pc: next_pc), # fallthrough
- )
- branch_stub.target0.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, true)
- @ocb.write(ocb_asm)
- end
- branch_stub.target1.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, false)
- @ocb.write(ocb_asm)
- end
-
- # Jump to target0 on jnz
- branch_stub.compile = compile_branchif(branch_stub)
- branch_stub.compile.call(asm)
- end
-
- EndBlock
- end
-
- def compile_branchif(branch_stub) # Proc escapes arguments in memory
- proc do |branch_asm|
- branch_asm.comment("branchif #{branch_stub.shape}")
- branch_asm.stub(branch_stub) do
- case branch_stub.shape
- in Default
- branch_asm.jnz(branch_stub.target0.address)
- branch_asm.jmp(branch_stub.target1.address)
- in Next0
- branch_asm.jz(branch_stub.target1.address)
- in Next1
- branch_asm.jnz(branch_stub.target0.address)
- end
- end
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def branchunless(jit, ctx, asm)
- # Check for interrupts, but only on backward branches that may create loops
- jump_offset = jit.operand(0, signed: true)
- if jump_offset < 0
- jit_check_ints(jit, ctx, asm)
- end
-
- # Get the branch target instruction offsets
- next_pc = jit.pc + C.VALUE.size * jit.insn.len
- jump_pc = jit.pc + C.VALUE.size * (jit.insn.len + jump_offset)
-
- val_type = ctx.get_opnd_type(StackOpnd[0])
- val_opnd = ctx.stack_pop(1)
-
- if (result = val_type.known_truthy) != nil
- target_pc = result ? next_pc : jump_pc
- jit_direct_jump(jit.iseq, target_pc, ctx, asm)
- else
- # This `test` sets ZF only for Qnil and Qfalse, which let jz jump.
- asm.test(val_opnd, ~Qnil)
-
- # Set stubs
- branch_stub = BranchStub.new(
- iseq: jit.iseq,
- shape: Default,
- target0: BranchTarget.new(ctx:, pc: jump_pc), # branch target
- target1: BranchTarget.new(ctx:, pc: next_pc), # fallthrough
- )
- branch_stub.target0.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, true)
- @ocb.write(ocb_asm)
- end
- branch_stub.target1.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, false)
- @ocb.write(ocb_asm)
- end
-
- # Jump to target0 on jz
- branch_stub.compile = compile_branchunless(branch_stub)
- branch_stub.compile.call(asm)
- end
-
- EndBlock
- end
-
- def compile_branchunless(branch_stub) # Proc escapes arguments in memory
- proc do |branch_asm|
- branch_asm.comment("branchunless #{branch_stub.shape}")
- branch_asm.stub(branch_stub) do
- case branch_stub.shape
- in Default
- branch_asm.jz(branch_stub.target0.address)
- branch_asm.jmp(branch_stub.target1.address)
- in Next0
- branch_asm.jnz(branch_stub.target1.address)
- in Next1
- branch_asm.jz(branch_stub.target0.address)
- end
- end
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def branchnil(jit, ctx, asm)
- # Check for interrupts, but only on backward branches that may create loops
- jump_offset = jit.operand(0, signed: true)
- if jump_offset < 0
- jit_check_ints(jit, ctx, asm)
- end
-
- # Get the branch target instruction offsets
- next_pc = jit.pc + C.VALUE.size * jit.insn.len
- jump_pc = jit.pc + C.VALUE.size * (jit.insn.len + jump_offset)
-
- val_type = ctx.get_opnd_type(StackOpnd[0])
- val_opnd = ctx.stack_pop(1)
-
- if (result = val_type.known_nil) != nil
- target_pc = result ? jump_pc : next_pc
- jit_direct_jump(jit.iseq, target_pc, ctx, asm)
- else
- asm.cmp(val_opnd, Qnil)
-
- # Set stubs
- branch_stub = BranchStub.new(
- iseq: jit.iseq,
- shape: Default,
- target0: BranchTarget.new(ctx:, pc: jump_pc), # branch target
- target1: BranchTarget.new(ctx:, pc: next_pc), # fallthrough
- )
- branch_stub.target0.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, true)
- @ocb.write(ocb_asm)
- end
- branch_stub.target1.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, false)
- @ocb.write(ocb_asm)
- end
-
- # Jump to target0 on je
- branch_stub.compile = compile_branchnil(branch_stub)
- branch_stub.compile.call(asm)
- end
-
- EndBlock
- end
-
- def compile_branchnil(branch_stub) # Proc escapes arguments in memory
- proc do |branch_asm|
- branch_asm.comment("branchnil #{branch_stub.shape}")
- branch_asm.stub(branch_stub) do
- case branch_stub.shape
- in Default
- branch_asm.je(branch_stub.target0.address)
- branch_asm.jmp(branch_stub.target1.address)
- in Next0
- branch_asm.jne(branch_stub.target1.address)
- in Next1
- branch_asm.je(branch_stub.target0.address)
- end
- end
- end
- end
-
- # once
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_case_dispatch(jit, ctx, asm)
- # Normally this instruction would lookup the key in a hash and jump to an
- # offset based on that.
- # Instead we can take the fallback case and continue with the next
- # instruction.
- # We'd hope that our jitted code will be sufficiently fast without the
- # hash lookup, at least for small hashes, but it's worth revisiting this
- # assumption in the future.
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
- starting_context = ctx.dup
-
- case_hash = jit.operand(0, ruby: true)
- else_offset = jit.operand(1)
-
- # Try to reorder case/else branches so that ones that are actually used come first.
- # Supporting only Fixnum for now so that the implementation can be an equality check.
- key_opnd = ctx.stack_pop(1)
- comptime_key = jit.peek_at_stack(0)
-
- # Check that all cases are fixnums to avoid having to register BOP assumptions on
- # all the types that case hashes support. This spends compile time to save memory.
- if fixnum?(comptime_key) && comptime_key <= 2**32 && C.rb_hash_keys(case_hash).all? { |key| fixnum?(key) }
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_EQQ)
- return CantCompile
- end
-
- # Check if the key is the same value
- asm.cmp(key_opnd, to_value(comptime_key))
- side_exit = side_exit(jit, starting_context)
- jit_chain_guard(:jne, jit, starting_context, asm, side_exit)
-
- # Get the offset for the compile-time key
- offset = C.rb_hash_stlike_lookup(case_hash, comptime_key)
- # NOTE: If we hit the else branch with various values, it could negatively impact the performance.
- jump_offset = offset || else_offset
-
- # Jump to the offset of case or else
- target_pc = jit.pc + (jit.insn.len + jump_offset) * C.VALUE.size
- jit_direct_jump(jit.iseq, target_pc, ctx, asm)
- EndBlock
- else
- KeepCompiling # continue with === branches
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_plus(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- comptime_recv = jit.peek_at_stack(1)
- comptime_obj = jit.peek_at_stack(0)
-
- if fixnum?(comptime_recv) && fixnum?(comptime_obj)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_PLUS)
- return CantCompile
- end
-
- # Check that both operands are fixnums
- guard_two_fixnums(jit, ctx, asm)
-
- obj_opnd = ctx.stack_pop
- recv_opnd = ctx.stack_pop
-
- asm.mov(:rax, recv_opnd)
- asm.sub(:rax, 1) # untag
- asm.mov(:rcx, obj_opnd)
- asm.add(:rax, :rcx)
- asm.jo(side_exit(jit, ctx))
-
- dst_opnd = ctx.stack_push(Type::Fixnum)
- asm.mov(dst_opnd, :rax)
-
- KeepCompiling
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_minus(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- comptime_recv = jit.peek_at_stack(1)
- comptime_obj = jit.peek_at_stack(0)
-
- if fixnum?(comptime_recv) && fixnum?(comptime_obj)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_MINUS)
- return CantCompile
- end
-
- # Check that both operands are fixnums
- guard_two_fixnums(jit, ctx, asm)
-
- obj_opnd = ctx.stack_pop
- recv_opnd = ctx.stack_pop
-
- asm.mov(:rax, recv_opnd)
- asm.mov(:rcx, obj_opnd)
- asm.sub(:rax, :rcx)
- asm.jo(side_exit(jit, ctx))
- asm.add(:rax, 1) # re-tag
-
- dst_opnd = ctx.stack_push(Type::Fixnum)
- asm.mov(dst_opnd, :rax)
-
- KeepCompiling
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_mult(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_div(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_mod(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- if two_fixnums_on_stack?(jit)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_MOD)
- return CantCompile
- end
-
- # Check that both operands are fixnums
- guard_two_fixnums(jit, ctx, asm)
-
- # Get the operands and destination from the stack
- arg1 = ctx.stack_pop(1)
- arg0 = ctx.stack_pop(1)
-
- # Check for arg0 % 0
- asm.cmp(arg1, 0)
- asm.je(side_exit(jit, ctx))
-
- # Call rb_fix_mod_fix(VALUE recv, VALUE obj)
- asm.mov(C_ARGS[0], arg0)
- asm.mov(C_ARGS[1], arg1)
- asm.call(C.rb_fix_mod_fix)
-
- # Push the return value onto the stack
- stack_ret = ctx.stack_push(Type::Fixnum)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_eq(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- if jit_equality_specialized(jit, ctx, asm, true)
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_neq(jit, ctx, asm)
- # opt_neq is passed two rb_call_data as arguments:
- # first for ==, second for !=
- neq_cd = C.rb_call_data.new(jit.operand(1))
- opt_send_without_block(jit, ctx, asm, cd: neq_cd)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_lt(jit, ctx, asm)
- jit_fixnum_cmp(jit, ctx, asm, opcode: :cmovl, bop: C::BOP_LT)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_le(jit, ctx, asm)
- jit_fixnum_cmp(jit, ctx, asm, opcode: :cmovle, bop: C::BOP_LE)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_gt(jit, ctx, asm)
- jit_fixnum_cmp(jit, ctx, asm, opcode: :cmovg, bop: C::BOP_GT)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_ge(jit, ctx, asm)
- jit_fixnum_cmp(jit, ctx, asm, opcode: :cmovge, bop: C::BOP_GE)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_ltlt(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_and(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- if two_fixnums_on_stack?(jit)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_AND)
- return CantCompile
- end
-
- # Check that both operands are fixnums
- guard_two_fixnums(jit, ctx, asm)
-
- # Get the operands and destination from the stack
- arg1 = ctx.stack_pop(1)
- arg0 = ctx.stack_pop(1)
-
- asm.comment('bitwise and')
- asm.mov(:rax, arg0)
- asm.and(:rax, arg1)
-
- # Push the return value onto the stack
- dst = ctx.stack_push(Type::Fixnum)
- asm.mov(dst, :rax)
-
- KeepCompiling
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_or(jit, ctx, asm)
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- if two_fixnums_on_stack?(jit)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_OR)
- return CantCompile
- end
-
- # Check that both operands are fixnums
- guard_two_fixnums(jit, ctx, asm)
-
- # Get the operands and destination from the stack
- asm.comment('bitwise or')
- arg1 = ctx.stack_pop(1)
- arg0 = ctx.stack_pop(1)
-
- # Do the bitwise or arg0 | arg1
- asm.mov(:rax, arg0)
- asm.or(:rax, arg1)
-
- # Push the return value onto the stack
- dst = ctx.stack_push(Type::Fixnum)
- asm.mov(dst, :rax)
-
- KeepCompiling
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_aref(jit, ctx, asm)
- cd = C.rb_call_data.new(jit.operand(0))
- argc = C.vm_ci_argc(cd.ci)
-
- if argc != 1
- asm.incr_counter(:optaref_argc_not_one)
- return CantCompile
- end
-
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- comptime_recv = jit.peek_at_stack(1)
- comptime_obj = jit.peek_at_stack(0)
-
- side_exit = side_exit(jit, ctx)
-
- if C.rb_class_of(comptime_recv) == Array && fixnum?(comptime_obj)
- unless Invariants.assume_bop_not_redefined(jit, C::ARRAY_REDEFINED_OP_FLAG, C::BOP_AREF)
- return CantCompile
- end
-
- idx_opnd = ctx.stack_opnd(0)
- recv_opnd = ctx.stack_opnd(1)
-
- not_array_exit = counted_exit(side_exit, :optaref_recv_not_array)
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_recv), recv_opnd, StackOpnd[1], comptime_recv, not_array_exit)
-
- # Bail if idx is not a FIXNUM
- asm.mov(:rax, idx_opnd)
- asm.test(:rax, C::RUBY_FIXNUM_FLAG)
- asm.jz(counted_exit(side_exit, :optaref_arg_not_fixnum))
-
- # Call VALUE rb_ary_entry_internal(VALUE ary, long offset).
- # It never raises or allocates, so we don't need to write to cfp->pc.
- asm.sar(:rax, 1) # Convert fixnum to int
- asm.mov(C_ARGS[0], recv_opnd)
- asm.mov(C_ARGS[1], :rax)
- asm.call(C.rb_ary_entry_internal)
-
- # Pop the argument and the receiver
- ctx.stack_pop(2)
-
- # Push the return value onto the stack
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- # Let guard chains share the same successor
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- elsif C.rb_class_of(comptime_recv) == Hash
- unless Invariants.assume_bop_not_redefined(jit, C::HASH_REDEFINED_OP_FLAG, C::BOP_AREF)
- return CantCompile
- end
-
- recv_opnd = ctx.stack_opnd(1)
-
- # Guard that the receiver is a Hash
- not_hash_exit = counted_exit(side_exit, :optaref_recv_not_hash)
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_recv), recv_opnd, StackOpnd[1], comptime_recv, not_hash_exit)
-
- # Prepare to call rb_hash_aref(). It might call #hash on the key.
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.comment('call rb_hash_aref')
- key_opnd = ctx.stack_opnd(0)
- recv_opnd = ctx.stack_opnd(1)
- asm.mov(:rdi, recv_opnd)
- asm.mov(:rsi, key_opnd)
- asm.call(C.rb_hash_aref)
-
- # Pop the key and the receiver
- ctx.stack_pop(2)
-
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- # Let guard chains share the same successor
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_aset(jit, ctx, asm)
- # Defer compilation so we can specialize on a runtime `self`
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- comptime_recv = jit.peek_at_stack(2)
- comptime_key = jit.peek_at_stack(1)
-
- # Get the operands from the stack
- recv = ctx.stack_opnd(2)
- key = ctx.stack_opnd(1)
- _val = ctx.stack_opnd(0)
-
- if C.rb_class_of(comptime_recv) == Array && fixnum?(comptime_key)
- side_exit = side_exit(jit, ctx)
-
- # Guard receiver is an Array
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_recv), recv, StackOpnd[2], comptime_recv, side_exit)
-
- # Guard key is a fixnum
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_key), key, StackOpnd[1], comptime_key, side_exit)
-
- # We might allocate or raise
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.comment('call rb_ary_store')
- recv = ctx.stack_opnd(2)
- key = ctx.stack_opnd(1)
- val = ctx.stack_opnd(0)
- asm.mov(:rax, key)
- asm.sar(:rax, 1) # FIX2LONG(key)
- asm.mov(C_ARGS[0], recv)
- asm.mov(C_ARGS[1], :rax)
- asm.mov(C_ARGS[2], val)
- asm.call(C.rb_ary_store)
-
- # rb_ary_store returns void
- # stored value should still be on stack
- val = ctx.stack_opnd(0)
-
- # Push the return value onto the stack
- ctx.stack_pop(3)
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(:rax, val)
- asm.mov(stack_ret, :rax)
-
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- elsif C.rb_class_of(comptime_recv) == Hash
- side_exit = side_exit(jit, ctx)
-
- # Guard receiver is a Hash
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_recv), recv, StackOpnd[2], comptime_recv, side_exit)
-
- # We might allocate or raise
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Call rb_hash_aset
- recv = ctx.stack_opnd(2)
- key = ctx.stack_opnd(1)
- val = ctx.stack_opnd(0)
- asm.mov(C_ARGS[0], recv)
- asm.mov(C_ARGS[1], key)
- asm.mov(C_ARGS[2], val)
- asm.call(C.rb_hash_aset)
-
- # Push the return value onto the stack
- ctx.stack_pop(3)
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # opt_aset_with
- # opt_aref_with
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_length(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_size(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_empty_p(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_succ(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_not(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_regexpmatch2(jit, ctx, asm)
- opt_send_without_block(jit, ctx, asm)
- end
-
- # invokebuiltin
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_invokebuiltin_delegate(jit, ctx, asm)
- bf = C.rb_builtin_function.new(jit.operand(0))
- bf_argc = bf.argc
- start_index = jit.operand(1)
-
- # ec, self, and arguments
- if bf_argc + 2 > C_ARGS.size
- return CantCompile
- end
-
- # If the calls don't allocate, do they need up to date PC, SP?
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Call the builtin func (ec, recv, arg1, arg2, ...)
- asm.comment('call builtin func')
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], [CFP, C.rb_control_frame_t.offsetof(:self)])
-
- # Copy arguments from locals
- if bf_argc > 0
- # Load environment pointer EP from CFP
- asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:ep)])
-
- bf_argc.times do |i|
- table_size = jit.iseq.body.local_table_size
- offs = -table_size - C::VM_ENV_DATA_SIZE + 1 + start_index + i
- asm.mov(C_ARGS[2 + i], [:rax, offs * C.VALUE.size])
- end
- end
- asm.call(bf.func_ptr)
-
- # Push the return value
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- KeepCompiling
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def opt_invokebuiltin_delegate_leave(jit, ctx, asm)
- opt_invokebuiltin_delegate(jit, ctx, asm)
- # opt_invokebuiltin_delegate is always followed by leave insn
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putobject_INT2FIX_0_(jit, ctx, asm)
- putobject(jit, ctx, asm, val: C.to_value(0))
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def putobject_INT2FIX_1_(jit, ctx, asm)
- putobject(jit, ctx, asm, val: C.to_value(1))
- end
-
- #
- # C func
- #
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_true(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 0
- asm.comment('nil? == true')
- ctx.stack_pop(1)
- stack_ret = ctx.stack_push(Type::True)
- asm.mov(stack_ret, Qtrue)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_false(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 0
- asm.comment('nil? == false')
- ctx.stack_pop(1)
- stack_ret = ctx.stack_push(Type::False)
- asm.mov(stack_ret, Qfalse)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_kernel_is_a(jit, ctx, asm, argc, known_recv_class)
- if argc != 1
- return false
- end
-
- # If this is a super call we might not know the class
- if known_recv_class.nil?
- return false
- end
-
- # Important note: The output code will simply `return true/false`.
- # Correctness follows from:
- # - `known_recv_class` implies there is a guard scheduled before here
- # for a particular `CLASS_OF(lhs)`.
- # - We guard that rhs is identical to the compile-time sample
- # - In general, for any two Class instances A, B, `A < B` does not change at runtime.
- # Class#superclass is stable.
-
- sample_rhs = jit.peek_at_stack(0)
- sample_lhs = jit.peek_at_stack(1)
-
- # We are not allowing module here because the module hierarchy can change at runtime.
- if C.RB_TYPE_P(sample_rhs, C::RUBY_T_CLASS)
- return false
- end
- sample_is_a = C.obj_is_kind_of(sample_lhs, sample_rhs)
-
- side_exit = side_exit(jit, ctx)
- asm.comment('Kernel#is_a?')
- asm.mov(:rax, to_value(sample_rhs))
- asm.cmp(ctx.stack_opnd(0), :rax)
- asm.jne(counted_exit(side_exit, :send_is_a_class_mismatch))
-
- ctx.stack_pop(2)
-
- if sample_is_a
- stack_ret = ctx.stack_push(Type::True)
- asm.mov(stack_ret, Qtrue)
- else
- stack_ret = ctx.stack_push(Type::False)
- asm.mov(stack_ret, Qfalse)
- end
- return true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_kernel_instance_of(jit, ctx, asm, argc, known_recv_class)
- if argc != 1
- return false
- end
-
- # If this is a super call we might not know the class
- if known_recv_class.nil?
- return false
- end
-
- # Important note: The output code will simply `return true/false`.
- # Correctness follows from:
- # - `known_recv_class` implies there is a guard scheduled before here
- # for a particular `CLASS_OF(lhs)`.
- # - We guard that rhs is identical to the compile-time sample
- # - For a particular `CLASS_OF(lhs)`, `rb_obj_class(lhs)` does not change.
- # (because for any singleton class `s`, `s.superclass.equal?(s.attached_object.class)`)
-
- sample_rhs = jit.peek_at_stack(0)
- sample_lhs = jit.peek_at_stack(1)
-
- # Filters out cases where the C implementation raises
- unless C.RB_TYPE_P(sample_rhs, C::RUBY_T_CLASS) || C.RB_TYPE_P(sample_rhs, C::RUBY_T_MODULE)
- return false
- end
-
- # We need to grab the class here to deal with singleton classes.
- # Instance of grabs the "real class" of the object rather than the
- # singleton class.
- sample_lhs_real_class = C.rb_obj_class(sample_lhs)
-
- sample_instance_of = (sample_lhs_real_class == sample_rhs)
-
- side_exit = side_exit(jit, ctx)
- asm.comment('Kernel#instance_of?')
- asm.mov(:rax, to_value(sample_rhs))
- asm.cmp(ctx.stack_opnd(0), :rax)
- asm.jne(counted_exit(side_exit, :send_instance_of_class_mismatch))
-
- ctx.stack_pop(2)
-
- if sample_instance_of
- stack_ret = ctx.stack_push(Type::True)
- asm.mov(stack_ret, Qtrue)
- else
- stack_ret = ctx.stack_push(Type::False)
- asm.mov(stack_ret, Qfalse)
- end
- return true;
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_obj_not(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 0
- recv_type = ctx.get_opnd_type(StackOpnd[0])
-
- case recv_type.known_truthy
- in false
- asm.comment('rb_obj_not(nil_or_false)')
- ctx.stack_pop(1)
- out_opnd = ctx.stack_push(Type::True)
- asm.mov(out_opnd, Qtrue)
- in true
- # Note: recv_type != Type::Nil && recv_type != Type::False.
- asm.comment('rb_obj_not(truthy)')
- ctx.stack_pop(1)
- out_opnd = ctx.stack_push(Type::False)
- asm.mov(out_opnd, Qfalse)
- in nil
- asm.comment('rb_obj_not')
-
- recv = ctx.stack_pop
- # This `test` sets ZF only for Qnil and Qfalse, which let cmovz set.
- asm.test(recv, ~Qnil)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmovz(:rax, :rcx)
-
- stack_ret = ctx.stack_push(Type::UnknownImm)
- asm.mov(stack_ret, :rax)
- end
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_obj_equal(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- asm.comment('equal?')
- obj1 = ctx.stack_pop(1)
- obj2 = ctx.stack_pop(1)
-
- asm.mov(:rax, obj1)
- asm.mov(:rcx, obj2)
- asm.cmp(:rax, :rcx)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmove(:rax, :rcx)
-
- stack_ret = ctx.stack_push(Type::UnknownImm)
- asm.mov(stack_ret, :rax)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_obj_not_equal(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- jit_equality_specialized(jit, ctx, asm, false)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_mod_eqq(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
-
- asm.comment('Module#===')
- # By being here, we know that the receiver is a T_MODULE or a T_CLASS, because Module#=== can
- # only live on these objects. With that, we can call rb_obj_is_kind_of() without
- # jit_prepare_routine_call() or a control frame push because it can't raise, allocate, or call
- # Ruby methods with these inputs.
- # Note the difference in approach from Kernel#is_a? because we don't get a free guard for the
- # right hand side.
- lhs = ctx.stack_opnd(1) # the module
- rhs = ctx.stack_opnd(0)
- asm.mov(C_ARGS[0], rhs);
- asm.mov(C_ARGS[1], lhs);
- asm.call(C.rb_obj_is_kind_of)
-
- # Return the result
- ctx.stack_pop(2)
- stack_ret = ctx.stack_push(Type::UnknownImm)
- asm.mov(stack_ret, C_RET)
-
- return true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_int_equal(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- return false unless two_fixnums_on_stack?(jit)
-
- guard_two_fixnums(jit, ctx, asm)
-
- # Compare the arguments
- asm.comment('rb_int_equal')
- arg1 = ctx.stack_pop(1)
- arg0 = ctx.stack_pop(1)
- asm.mov(:rax, arg1)
- asm.cmp(arg0, :rax)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmove(:rax, :rcx)
-
- stack_ret = ctx.stack_push(Type::UnknownImm)
- asm.mov(stack_ret, :rax)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_int_mul(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- return false unless two_fixnums_on_stack?(jit)
-
- guard_two_fixnums(jit, ctx, asm)
-
- asm.comment('rb_int_mul')
- y_opnd = ctx.stack_pop
- x_opnd = ctx.stack_pop
- asm.mov(C_ARGS[0], x_opnd)
- asm.mov(C_ARGS[1], y_opnd)
- asm.call(C.rb_fix_mul_fix)
-
- ret_opnd = ctx.stack_push(Type::Unknown)
- asm.mov(ret_opnd, C_RET)
- true
- end
-
- def jit_rb_int_div(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- return false unless two_fixnums_on_stack?(jit)
-
- guard_two_fixnums(jit, ctx, asm)
-
- asm.comment('rb_int_div')
- y_opnd = ctx.stack_pop
- x_opnd = ctx.stack_pop
- asm.mov(:rax, y_opnd)
- asm.cmp(:rax, C.to_value(0))
- asm.je(side_exit(jit, ctx))
-
- asm.mov(C_ARGS[0], x_opnd)
- asm.mov(C_ARGS[1], :rax)
- asm.call(C.rb_fix_div_fix)
-
- ret_opnd = ctx.stack_push(Type::Unknown)
- asm.mov(ret_opnd, C_RET)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_int_aref(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- return false unless two_fixnums_on_stack?(jit)
-
- guard_two_fixnums(jit, ctx, asm)
-
- asm.comment('rb_int_aref')
- y_opnd = ctx.stack_pop
- x_opnd = ctx.stack_pop
-
- asm.mov(C_ARGS[0], x_opnd)
- asm.mov(C_ARGS[1], y_opnd)
- asm.call(C.rb_fix_aref)
-
- ret_opnd = ctx.stack_push(Type::UnknownImm)
- asm.mov(ret_opnd, C_RET)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_str_empty_p(jit, ctx, asm, argc, known_recv_class)
- recv_opnd = ctx.stack_pop(1)
- out_opnd = ctx.stack_push(Type::UnknownImm)
-
- asm.comment('get string length')
- asm.mov(:rax, recv_opnd)
- str_len_opnd = [:rax, C.RString.offsetof(:len)]
-
- asm.cmp(str_len_opnd, 0)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmove(:rax, :rcx)
- asm.mov(out_opnd, :rax)
-
- return true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_str_to_s(jit, ctx, asm, argc, known_recv_class)
- return false if argc != 0
- if known_recv_class == String
- asm.comment('to_s on plain string')
- # The method returns the receiver, which is already on the stack.
- # No stack movement.
- return true
- end
- false
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_str_bytesize(jit, ctx, asm, argc, known_recv_class)
- asm.comment('String#bytesize')
-
- recv = ctx.stack_pop(1)
- asm.mov(C_ARGS[0], recv)
- asm.call(C.rb_str_bytesize)
-
- out_opnd = ctx.stack_push(Type::Fixnum)
- asm.mov(out_opnd, C_RET)
-
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_str_concat(jit, ctx, asm, argc, known_recv_class)
- # The << operator can accept integer codepoints for characters
- # as the argument. We only specially optimise string arguments.
- # If the peeked-at compile time argument is something other than
- # a string, assume it won't be a string later either.
- comptime_arg = jit.peek_at_stack(0)
- unless C.RB_TYPE_P(comptime_arg, C::RUBY_T_STRING)
- return false
- end
-
- # Guard that the concat argument is a string
- asm.mov(:rax, ctx.stack_opnd(0))
- guard_object_is_string(jit, ctx, asm, :rax, :rcx, StackOpnd[0])
-
- # Guard buffers from GC since rb_str_buf_append may allocate. During the VM lock on GC,
- # other Ractors may trigger global invalidation, so we need ctx.clear_local_types.
- # PC is used on errors like Encoding::CompatibilityError raised by rb_str_buf_append.
- jit_prepare_routine_call(jit, ctx, asm)
-
- concat_arg = ctx.stack_pop(1)
- recv = ctx.stack_pop(1)
-
- # Test if string encodings differ. If different, use rb_str_append. If the same,
- # use rb_yjit_str_simple_append, which calls rb_str_cat.
- asm.comment('<< on strings')
-
- # Take receiver's object flags XOR arg's flags. If any
- # string-encoding flags are different between the two,
- # the encodings don't match.
- recv_reg = :rax
- asm.mov(recv_reg, recv)
- concat_arg_reg = :rcx
- asm.mov(concat_arg_reg, concat_arg)
- asm.mov(recv_reg, [recv_reg, C.RBasic.offsetof(:flags)])
- asm.mov(concat_arg_reg, [concat_arg_reg, C.RBasic.offsetof(:flags)])
- asm.xor(recv_reg, concat_arg_reg)
- asm.test(recv_reg, C::RUBY_ENCODING_MASK)
-
- # Push once, use the resulting operand in both branches below.
- stack_ret = ctx.stack_push(Type::TString)
-
- enc_mismatch = asm.new_label('enc_mismatch')
- asm.jnz(enc_mismatch)
-
- # If encodings match, call the simple append function and jump to return
- asm.mov(C_ARGS[0], recv)
- asm.mov(C_ARGS[1], concat_arg)
- asm.call(C.rjit_str_simple_append)
- ret_label = asm.new_label('func_return')
- asm.mov(stack_ret, C_RET)
- asm.jmp(ret_label)
-
- # If encodings are different, use a slower encoding-aware concatenate
- asm.write_label(enc_mismatch)
- asm.mov(C_ARGS[0], recv)
- asm.mov(C_ARGS[1], concat_arg)
- asm.call(C.rb_str_buf_append)
- asm.mov(stack_ret, C_RET)
- # Drop through to return
-
- asm.write_label(ret_label)
-
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_str_uplus(jit, ctx, asm, argc, _known_recv_class)
- if argc != 0
- return false
- end
-
- # We allocate when we dup the string
- jit_prepare_routine_call(jit, ctx, asm)
-
- asm.comment('Unary plus on string')
- asm.mov(:rax, ctx.stack_pop(1)) # recv_opnd
- asm.mov(:rcx, [:rax, C.RBasic.offsetof(:flags)]) # flags_opnd
- asm.test(:rcx, C::RUBY_FL_FREEZE)
-
- ret_label = asm.new_label('stack_ret')
-
- # String#+@ can only exist on T_STRING
- stack_ret = ctx.stack_push(Type::TString)
-
- # If the string isn't frozen, we just return it.
- asm.mov(stack_ret, :rax) # recv_opnd
- asm.jz(ret_label)
-
- # Str is frozen - duplicate it
- asm.mov(C_ARGS[0], :rax) # recv_opnd
- asm.call(C.rb_str_dup)
- asm.mov(stack_ret, C_RET)
-
- asm.write_label(ret_label)
-
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_str_getbyte(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- asm.comment('rb_str_getbyte')
-
- index_opnd = ctx.stack_pop
- str_opnd = ctx.stack_pop
- asm.mov(C_ARGS[0], str_opnd)
- asm.mov(C_ARGS[1], index_opnd)
- asm.call(C.rb_str_getbyte)
-
- ret_opnd = ctx.stack_push(Type::Fixnum)
- asm.mov(ret_opnd, C_RET)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_ary_empty_p(jit, ctx, asm, argc, _known_recv_class)
- array_reg = :rax
- asm.mov(array_reg, ctx.stack_pop(1))
- jit_array_len(asm, array_reg, :rcx)
-
- asm.test(:rcx, :rcx)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmovz(:rax, :rcx)
-
- out_opnd = ctx.stack_push(Type::UnknownImm)
- asm.mov(out_opnd, :rax)
-
- return true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_ary_push(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 1
- asm.comment('rb_ary_push')
-
- jit_prepare_routine_call(jit, ctx, asm)
-
- item_opnd = ctx.stack_pop
- ary_opnd = ctx.stack_pop
- asm.mov(C_ARGS[0], ary_opnd)
- asm.mov(C_ARGS[1], item_opnd)
- asm.call(C.rb_ary_push)
-
- ret_opnd = ctx.stack_push(Type::TArray)
- asm.mov(ret_opnd, C_RET)
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_obj_respond_to(jit, ctx, asm, argc, known_recv_class)
- # respond_to(:sym) or respond_to(:sym, true)
- if argc != 1 && argc != 2
- return false
- end
-
- if known_recv_class.nil?
- return false
- end
-
- recv_class = known_recv_class
-
- # Get the method_id from compile time. We will later add a guard against it.
- mid_sym = jit.peek_at_stack(argc - 1)
- unless static_symbol?(mid_sym)
- return false
- end
- mid = C.rb_sym2id(mid_sym)
-
- # This represents the value of the "include_all" argument and whether it's known
- allow_priv = if argc == 1
- # Default is false
- false
- else
- # Get value from type information (may or may not be known)
- ctx.get_opnd_type(StackOpnd[0]).known_truthy
- end
-
- target_cme = C.rb_callable_method_entry_or_negative(recv_class, mid)
-
- # Should never be null, as in that case we will be returned a "negative CME"
- assert_equal(false, target_cme.nil?)
-
- cme_def_type = C.UNDEFINED_METHOD_ENTRY_P(target_cme) ? C::VM_METHOD_TYPE_UNDEF : target_cme.def.type
-
- if cme_def_type == C::VM_METHOD_TYPE_REFINED
- return false
- end
-
- visibility = if cme_def_type == C::VM_METHOD_TYPE_UNDEF
- C::METHOD_VISI_UNDEF
- else
- C.METHOD_ENTRY_VISI(target_cme)
- end
-
- result =
- case [visibility, allow_priv]
- in C::METHOD_VISI_UNDEF, _ then Qfalse # No method => false
- in C::METHOD_VISI_PUBLIC, _ then Qtrue # Public method => true regardless of include_all
- in _, true then Qtrue # include_all => always true
- else return false # not public and include_all not known, can't compile
- end
-
- if result != Qtrue
- # Only if respond_to_missing? hasn't been overridden
- # In the future, we might want to jit the call to respond_to_missing?
- unless Invariants.assume_method_basic_definition(jit, recv_class, C.idRespond_to_missing)
- return false
- end
- end
-
- # Invalidate this block if method lookup changes for the method being queried. This works
- # both for the case where a method does or does not exist, as for the latter we asked for a
- # "negative CME" earlier.
- Invariants.assume_method_lookup_stable(jit, target_cme)
-
- # Generate a side exit
- side_exit = side_exit(jit, ctx)
-
- if argc == 2
- # pop include_all argument (we only use its type info)
- ctx.stack_pop(1)
- end
-
- sym_opnd = ctx.stack_pop(1)
- _recv_opnd = ctx.stack_pop(1)
-
- # This is necessary because we have no guarantee that sym_opnd is a constant
- asm.comment('guard known mid')
- asm.mov(:rax, to_value(mid_sym))
- asm.cmp(sym_opnd, :rax)
- asm.jne(side_exit)
-
- putobject(jit, ctx, asm, val: result)
-
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_rb_f_block_given_p(jit, ctx, asm, argc, _known_recv_class)
- asm.comment('block_given?')
-
- # Same as rb_vm_frame_block_handler
- jit_get_lep(jit, asm, reg: :rax)
- asm.mov(:rax, [:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # block_handler
-
- ctx.stack_pop(1)
- out_opnd = ctx.stack_push(Type::UnknownImm)
-
- # Return `block_handler != VM_BLOCK_HANDLER_NONE`
- asm.cmp(:rax, C::VM_BLOCK_HANDLER_NONE)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.cmovne(:rax, :rcx) # block_given
- asm.mov(out_opnd, :rax)
-
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_thread_s_current(jit, ctx, asm, argc, _known_recv_class)
- return false if argc != 0
- asm.comment('Thread.current')
- ctx.stack_pop(1)
-
- # ec->thread_ptr
- asm.mov(:rax, [EC, C.rb_execution_context_t.offsetof(:thread_ptr)])
-
- # thread->self
- asm.mov(:rax, [:rax, C.rb_thread_struct.offsetof(:self)])
-
- stack_ret = ctx.stack_push(Type::UnknownHeap)
- asm.mov(stack_ret, :rax)
- true
- end
-
- #
- # Helpers
- #
-
- def register_cfunc_codegen_funcs
- # Specialization for C methods. See register_cfunc_method for details.
- register_cfunc_method(BasicObject, :!, :jit_rb_obj_not)
-
- register_cfunc_method(NilClass, :nil?, :jit_rb_true)
- register_cfunc_method(Kernel, :nil?, :jit_rb_false)
- register_cfunc_method(Kernel, :is_a?, :jit_rb_kernel_is_a)
- register_cfunc_method(Kernel, :kind_of?, :jit_rb_kernel_is_a)
- register_cfunc_method(Kernel, :instance_of?, :jit_rb_kernel_instance_of)
-
- register_cfunc_method(BasicObject, :==, :jit_rb_obj_equal)
- register_cfunc_method(BasicObject, :equal?, :jit_rb_obj_equal)
- register_cfunc_method(BasicObject, :!=, :jit_rb_obj_not_equal)
- register_cfunc_method(Kernel, :eql?, :jit_rb_obj_equal)
- register_cfunc_method(Module, :==, :jit_rb_obj_equal)
- register_cfunc_method(Module, :===, :jit_rb_mod_eqq)
- register_cfunc_method(Symbol, :==, :jit_rb_obj_equal)
- register_cfunc_method(Symbol, :===, :jit_rb_obj_equal)
- register_cfunc_method(Integer, :==, :jit_rb_int_equal)
- register_cfunc_method(Integer, :===, :jit_rb_int_equal)
-
- # rb_str_to_s() methods in string.c
- register_cfunc_method(String, :empty?, :jit_rb_str_empty_p)
- register_cfunc_method(String, :to_s, :jit_rb_str_to_s)
- register_cfunc_method(String, :to_str, :jit_rb_str_to_s)
- register_cfunc_method(String, :bytesize, :jit_rb_str_bytesize)
- register_cfunc_method(String, :<<, :jit_rb_str_concat)
- register_cfunc_method(String, :+@, :jit_rb_str_uplus)
-
- # rb_ary_empty_p() method in array.c
- register_cfunc_method(Array, :empty?, :jit_rb_ary_empty_p)
-
- register_cfunc_method(Kernel, :respond_to?, :jit_obj_respond_to)
- register_cfunc_method(Kernel, :block_given?, :jit_rb_f_block_given_p)
-
- # Thread.current
- register_cfunc_method(C.rb_singleton_class(Thread), :current, :jit_thread_s_current)
-
- #---
- register_cfunc_method(Array, :<<, :jit_rb_ary_push)
- register_cfunc_method(Integer, :*, :jit_rb_int_mul)
- register_cfunc_method(Integer, :/, :jit_rb_int_div)
- register_cfunc_method(Integer, :[], :jit_rb_int_aref)
- register_cfunc_method(String, :getbyte, :jit_rb_str_getbyte)
- end
-
- def register_cfunc_method(klass, mid_sym, func)
- mid = C.rb_intern(mid_sym.to_s)
- me = C.rb_method_entry_at(klass, mid)
-
- assert_equal(false, me.nil?)
-
- # Only cfuncs are supported
- method_serial = me.def.method_serial
-
- @cfunc_codegen_table[method_serial] = method(func)
- end
-
- def lookup_cfunc_codegen(cme_def)
- @cfunc_codegen_table[cme_def.method_serial]
- end
-
- def stack_swap(_jit, ctx, asm, offset0, offset1)
- stack0_mem = ctx.stack_opnd(offset0)
- stack1_mem = ctx.stack_opnd(offset1)
-
- mapping0 = ctx.get_opnd_mapping(StackOpnd[offset0])
- mapping1 = ctx.get_opnd_mapping(StackOpnd[offset1])
-
- asm.mov(:rax, stack0_mem)
- asm.mov(:rcx, stack1_mem)
- asm.mov(stack0_mem, :rcx)
- asm.mov(stack1_mem, :rax)
-
- ctx.set_opnd_mapping(StackOpnd[offset0], mapping1)
- ctx.set_opnd_mapping(StackOpnd[offset1], mapping0)
- end
-
- def jit_getlocal_generic(jit, ctx, asm, idx:, level:)
- # Load environment pointer EP (level 0) from CFP
- ep_reg = :rax
- jit_get_ep(asm, level, reg: ep_reg)
-
- # Load the local from the block
- # val = *(vm_get_ep(GET_EP(), level) - idx);
- asm.mov(:rax, [ep_reg, -idx * C.VALUE.size])
-
- # Write the local at SP
- stack_top = if level == 0
- local_idx = ep_offset_to_local_idx(jit.iseq, idx)
- ctx.stack_push_local(local_idx)
- else
- ctx.stack_push(Type::Unknown)
- end
-
- asm.mov(stack_top, :rax)
- KeepCompiling
- end
-
- def jit_setlocal_generic(jit, ctx, asm, idx:, level:)
- value_type = ctx.get_opnd_type(StackOpnd[0])
-
- # Load environment pointer EP at level
- ep_reg = :rax
- jit_get_ep(asm, level, reg: ep_reg)
-
- # Write barriers may be required when VM_ENV_FLAG_WB_REQUIRED is set, however write barriers
- # only affect heap objects being written. If we know an immediate value is being written we
- # can skip this check.
- unless value_type.imm?
- # flags & VM_ENV_FLAG_WB_REQUIRED
- flags_opnd = [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_FLAGS]
- asm.test(flags_opnd, C::VM_ENV_FLAG_WB_REQUIRED)
-
- # if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
- asm.jnz(side_exit(jit, ctx))
- end
-
- if level == 0
- local_idx = ep_offset_to_local_idx(jit.iseq, idx)
- ctx.set_local_type(local_idx, value_type)
- end
-
- # Pop the value to write from the stack
- stack_top = ctx.stack_pop(1)
-
- # Write the value at the environment pointer
- asm.mov(:rcx, stack_top)
- asm.mov([ep_reg, -(C.VALUE.size * idx)], :rcx)
-
- KeepCompiling
- end
-
- # Compute the index of a local variable from its slot index
- def ep_offset_to_local_idx(iseq, ep_offset)
- # Layout illustration
- # This is an array of VALUE
- # | VM_ENV_DATA_SIZE |
- # v v
- # low addr <+-------+-------+-------+-------+------------------+
- # |local 0|local 1| ... |local n| .... |
- # +-------+-------+-------+-------+------------------+
- # ^ ^ ^ ^
- # +-------+---local_table_size----+ cfp->ep--+
- # | |
- # +------------------ep_offset---------------+
- #
- # See usages of local_var_name() from iseq.c for similar calculation.
-
- # Equivalent of iseq->body->local_table_size
- local_table_size = iseq.body.local_table_size
- op = ep_offset - C::VM_ENV_DATA_SIZE
- local_idx = local_table_size - op - 1
- assert_equal(true, local_idx >= 0 && local_idx < local_table_size)
- local_idx
- end
-
- # Compute the index of a local variable from its slot index
- def slot_to_local_idx(iseq, slot_idx)
- # Layout illustration
- # This is an array of VALUE
- # | VM_ENV_DATA_SIZE |
- # v v
- # low addr <+-------+-------+-------+-------+------------------+
- # |local 0|local 1| ... |local n| .... |
- # +-------+-------+-------+-------+------------------+
- # ^ ^ ^ ^
- # +-------+---local_table_size----+ cfp->ep--+
- # | |
- # +------------------slot_idx----------------+
- #
- # See usages of local_var_name() from iseq.c for similar calculation.
-
- local_table_size = iseq.body.local_table_size
- op = slot_idx - C::VM_ENV_DATA_SIZE
- local_table_size - op - 1
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def guard_object_is_heap(jit, ctx, asm, object, object_opnd, counter = nil)
- object_type = ctx.get_opnd_type(object_opnd)
- if object_type.heap?
- return
- end
-
- side_exit = side_exit(jit, ctx)
- side_exit = counted_exit(side_exit, counter) if counter
-
- asm.comment('guard object is heap')
- # Test that the object is not an immediate
- asm.test(object, C::RUBY_IMMEDIATE_MASK)
- asm.jnz(side_exit)
-
- # Test that the object is not false
- asm.cmp(object, Qfalse)
- asm.je(side_exit)
-
- if object_type.diff(Type::UnknownHeap) != TypeDiff::Incompatible
- ctx.upgrade_opnd_type(object_opnd, Type::UnknownHeap)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def guard_object_is_array(jit, ctx, asm, object_reg, flags_reg, object_opnd, counter = nil)
- object_type = ctx.get_opnd_type(object_opnd)
- if object_type.array?
- return
- end
-
- guard_object_is_heap(jit, ctx, asm, object_reg, object_opnd, counter)
-
- side_exit = side_exit(jit, ctx)
- side_exit = counted_exit(side_exit, counter) if counter
-
- asm.comment('guard object is array')
- # Pull out the type mask
- asm.mov(flags_reg, [object_reg, C.RBasic.offsetof(:flags)])
- asm.and(flags_reg, C::RUBY_T_MASK)
-
- # Compare the result with T_ARRAY
- asm.cmp(flags_reg, C::RUBY_T_ARRAY)
- asm.jne(side_exit)
-
- if object_type.diff(Type::TArray) != TypeDiff::Incompatible
- ctx.upgrade_opnd_type(object_opnd, Type::TArray)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def guard_object_is_string(jit, ctx, asm, object_reg, flags_reg, object_opnd, counter = nil)
- object_type = ctx.get_opnd_type(object_opnd)
- if object_type.string?
- return
- end
-
- guard_object_is_heap(jit, ctx, asm, object_reg, object_opnd, counter)
-
- side_exit = side_exit(jit, ctx)
- side_exit = counted_exit(side_exit, counter) if counter
-
- asm.comment('guard object is string')
- # Pull out the type mask
- asm.mov(flags_reg, [object_reg, C.RBasic.offsetof(:flags)])
- asm.and(flags_reg, C::RUBY_T_MASK)
-
- # Compare the result with T_STRING
- asm.cmp(flags_reg, C::RUBY_T_STRING)
- asm.jne(side_exit)
-
- if object_type.diff(Type::TString) != TypeDiff::Incompatible
- ctx.upgrade_opnd_type(object_opnd, Type::TString)
- end
- end
-
- # clobbers object_reg
- def guard_object_is_not_ruby2_keyword_hash(asm, object_reg, flags_reg, side_exit)
- asm.comment('guard object is not ruby2 keyword hash')
-
- not_ruby2_keyword = asm.new_label('not_ruby2_keyword')
- asm.test(object_reg, C::RUBY_IMMEDIATE_MASK)
- asm.jnz(not_ruby2_keyword)
-
- asm.cmp(object_reg, Qfalse)
- asm.je(not_ruby2_keyword)
-
- asm.mov(flags_reg, [object_reg, C.RBasic.offsetof(:flags)])
- type_reg = object_reg
- asm.mov(type_reg, flags_reg)
- asm.and(type_reg, C::RUBY_T_MASK)
-
- asm.cmp(type_reg, C::RUBY_T_HASH)
- asm.jne(not_ruby2_keyword)
-
- asm.test(flags_reg, C::RHASH_PASS_AS_KEYWORDS)
- asm.jnz(side_exit)
-
- asm.write_label(not_ruby2_keyword)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_chain_guard(opcode, jit, ctx, asm, side_exit, limit: 20)
- opcode => :je | :jne | :jnz | :jz
-
- if ctx.chain_depth < limit
- deeper = ctx.dup
- deeper.chain_depth += 1
-
- branch_stub = BranchStub.new(
- iseq: jit.iseq,
- shape: Default,
- target0: BranchTarget.new(ctx: deeper, pc: jit.pc),
- )
- branch_stub.target0.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(deeper, ocb_asm, branch_stub, true)
- @ocb.write(ocb_asm)
- end
- branch_stub.compile = compile_jit_chain_guard(branch_stub, opcode:)
- branch_stub.compile.call(asm)
- else
- asm.public_send(opcode, side_exit)
- end
- end
-
- def compile_jit_chain_guard(branch_stub, opcode:) # Proc escapes arguments in memory
- proc do |branch_asm|
- # Not using `asm.comment` here since it's usually put before cmp/test before this.
- branch_asm.stub(branch_stub) do
- case branch_stub.shape
- in Default
- branch_asm.public_send(opcode, branch_stub.target0.address)
- end
- end
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_guard_known_klass(jit, ctx, asm, known_klass, obj_opnd, insn_opnd, comptime_obj, side_exit, limit: 10)
- # Only memory operand is supported for now
- assert_equal(true, obj_opnd.is_a?(Array))
-
- known_klass = C.to_value(known_klass)
- val_type = ctx.get_opnd_type(insn_opnd)
- if val_type.known_class == known_klass
- # We already know from type information that this is a match
- return
- end
-
- # Touching this as Ruby could crash for FrozenCore
- if known_klass == C.rb_cNilClass
- assert(!val_type.heap?)
- assert(val_type.unknown?)
-
- asm.comment('guard object is nil')
- asm.cmp(obj_opnd, Qnil)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
-
- ctx.upgrade_opnd_type(insn_opnd, Type::Nil)
- elsif known_klass == C.rb_cTrueClass
- assert(!val_type.heap?)
- assert(val_type.unknown?)
-
- asm.comment('guard object is true')
- asm.cmp(obj_opnd, Qtrue)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
-
- ctx.upgrade_opnd_type(insn_opnd, Type::True)
- elsif known_klass == C.rb_cFalseClass
- assert(!val_type.heap?)
- assert(val_type.unknown?)
-
- asm.comment('guard object is false')
- asm.cmp(obj_opnd, Qfalse)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
-
- ctx.upgrade_opnd_type(insn_opnd, Type::False)
- elsif known_klass == C.rb_cInteger && fixnum?(comptime_obj)
- # We will guard fixnum and bignum as though they were separate classes
- # BIGNUM can be handled by the general else case below
- assert(val_type.unknown?)
-
- asm.comment('guard object is fixnum')
- asm.test(obj_opnd, C::RUBY_FIXNUM_FLAG)
- jit_chain_guard(:jz, jit, ctx, asm, side_exit, limit:)
-
- ctx.upgrade_opnd_type(insn_opnd, Type::Fixnum)
- elsif known_klass == C.rb_cSymbol && static_symbol?(comptime_obj)
- assert(!val_type.heap?)
- # We will guard STATIC vs DYNAMIC as though they were separate classes
- # DYNAMIC symbols can be handled by the general else case below
- if val_type != Type::ImmSymbol || !val_type.imm?
- assert(val_type.unknown?)
-
- asm.comment('guard object is static symbol')
- assert_equal(8, C::RUBY_SPECIAL_SHIFT)
- asm.cmp(BytePtr[*obj_opnd], C::RUBY_SYMBOL_FLAG)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
-
- ctx.upgrade_opnd_type(insn_opnd, Type::ImmSymbol)
- end
- elsif known_klass == C.rb_cFloat && flonum?(comptime_obj)
- assert(!val_type.heap?)
- if val_type != Type::Flonum || !val_type.imm?
- assert(val_type.unknown?)
-
- # We will guard flonum vs heap float as though they were separate classes
- asm.comment('guard object is flonum')
- asm.mov(:rax, obj_opnd)
- asm.and(:rax, C::RUBY_FLONUM_MASK)
- asm.cmp(:rax, C::RUBY_FLONUM_FLAG)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
-
- ctx.upgrade_opnd_type(insn_opnd, Type::Flonum)
- end
- elsif C.FL_TEST(known_klass, C::RUBY_FL_SINGLETON) && comptime_obj == C.rb_class_attached_object(known_klass)
- # Singleton classes are attached to one specific object, so we can
- # avoid one memory access (and potentially the is_heap check) by
- # looking for the expected object directly.
- # Note that in case the sample instance has a singleton class that
- # doesn't attach to the sample instance, it means the sample instance
- # has an empty singleton class that hasn't been materialized yet. In
- # this case, comparing against the sample instance doesn't guarantee
- # that its singleton class is empty, so we can't avoid the memory
- # access. As an example, `Object.new.singleton_class` is an object in
- # this situation.
- asm.comment('guard known object with singleton class')
- asm.mov(:rax, to_value(comptime_obj))
- asm.cmp(obj_opnd, :rax)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
- elsif val_type == Type::CString && known_klass == C.rb_cString
- # guard elided because the context says we've already checked
- assert_equal(C.to_value(C.rb_class_of(comptime_obj)), C.rb_cString)
- else
- assert(!val_type.imm?)
-
- # Load memory to a register
- asm.mov(:rax, obj_opnd)
- obj_opnd = :rax
-
- # Check that the receiver is a heap object
- # Note: if we get here, the class doesn't have immediate instances.
- unless val_type.heap?
- asm.comment('guard not immediate')
- asm.test(obj_opnd, C::RUBY_IMMEDIATE_MASK)
- jit_chain_guard(:jnz, jit, ctx, asm, side_exit, limit:)
- asm.cmp(obj_opnd, Qfalse)
- jit_chain_guard(:je, jit, ctx, asm, side_exit, limit:)
- end
-
- # Bail if receiver class is different from known_klass
- klass_opnd = [obj_opnd, C.RBasic.offsetof(:klass)]
- asm.comment("guard known class #{known_klass}")
- asm.mov(:rcx, known_klass)
- asm.cmp(klass_opnd, :rcx)
- jit_chain_guard(:jne, jit, ctx, asm, side_exit, limit:)
-
- if known_klass == C.rb_cString
- # Upgrading to Type::CString here is incorrect.
- # The guard we put only checks RBASIC_CLASS(obj),
- # which adding a singleton class can change. We
- # additionally need to know the string is frozen
- # to claim Type::CString.
- ctx.upgrade_opnd_type(insn_opnd, Type::TString)
- elsif known_klass == C.rb_cArray
- ctx.upgrade_opnd_type(insn_opnd, Type::TArray)
- end
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- def two_fixnums_on_stack?(jit)
- comptime_recv = jit.peek_at_stack(1)
- comptime_arg = jit.peek_at_stack(0)
- return fixnum?(comptime_recv) && fixnum?(comptime_arg)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def guard_two_fixnums(jit, ctx, asm)
- # Get stack operands without popping them
- arg1 = ctx.stack_opnd(0)
- arg0 = ctx.stack_opnd(1)
-
- # Get the stack operand types
- arg1_type = ctx.get_opnd_type(StackOpnd[0])
- arg0_type = ctx.get_opnd_type(StackOpnd[1])
-
- if arg0_type.heap? || arg1_type.heap?
- asm.comment('arg is heap object')
- asm.jmp(side_exit(jit, ctx))
- return
- end
-
- if arg0_type != Type::Fixnum && arg0_type.specific?
- asm.comment('arg0 not fixnum')
- asm.jmp(side_exit(jit, ctx))
- return
- end
-
- if arg1_type != Type::Fixnum && arg1_type.specific?
- asm.comment('arg1 not fixnum')
- asm.jmp(side_exit(jit, ctx))
- return
- end
-
- assert(!arg0_type.heap?)
- assert(!arg1_type.heap?)
- assert(arg0_type == Type::Fixnum || arg0_type.unknown?)
- assert(arg1_type == Type::Fixnum || arg1_type.unknown?)
-
- # If not fixnums at run-time, fall back
- if arg0_type != Type::Fixnum
- asm.comment('guard arg0 fixnum')
- asm.test(arg0, C::RUBY_FIXNUM_FLAG)
- jit_chain_guard(:jz, jit, ctx, asm, side_exit(jit, ctx))
- end
- if arg1_type != Type::Fixnum
- asm.comment('guard arg1 fixnum')
- asm.test(arg1, C::RUBY_FIXNUM_FLAG)
- jit_chain_guard(:jz, jit, ctx, asm, side_exit(jit, ctx))
- end
-
- # Set stack types in context
- ctx.upgrade_opnd_type(StackOpnd[0], Type::Fixnum)
- ctx.upgrade_opnd_type(StackOpnd[1], Type::Fixnum)
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_fixnum_cmp(jit, ctx, asm, opcode:, bop:)
- opcode => :cmovl | :cmovle | :cmovg | :cmovge
-
- unless jit.at_current_insn?
- defer_compilation(jit, ctx, asm)
- return EndBlock
- end
-
- comptime_recv = jit.peek_at_stack(1)
- comptime_obj = jit.peek_at_stack(0)
-
- if fixnum?(comptime_recv) && fixnum?(comptime_obj)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, bop)
- return CantCompile
- end
-
- # Check that both operands are fixnums
- guard_two_fixnums(jit, ctx, asm)
-
- obj_opnd = ctx.stack_pop
- recv_opnd = ctx.stack_pop
-
- asm.mov(:rax, obj_opnd)
- asm.cmp(recv_opnd, :rax)
- asm.mov(:rax, Qfalse)
- asm.mov(:rcx, Qtrue)
- asm.public_send(opcode, :rax, :rcx)
-
- dst_opnd = ctx.stack_push(Type::UnknownImm)
- asm.mov(dst_opnd, :rax)
-
- KeepCompiling
- else
- opt_send_without_block(jit, ctx, asm)
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_equality_specialized(jit, ctx, asm, gen_eq)
- # Create a side-exit to fall back to the interpreter
- side_exit = side_exit(jit, ctx)
-
- a_opnd = ctx.stack_opnd(1)
- b_opnd = ctx.stack_opnd(0)
-
- comptime_a = jit.peek_at_stack(1)
- comptime_b = jit.peek_at_stack(0)
-
- if two_fixnums_on_stack?(jit)
- unless Invariants.assume_bop_not_redefined(jit, C::INTEGER_REDEFINED_OP_FLAG, C::BOP_EQ)
- return false
- end
-
- guard_two_fixnums(jit, ctx, asm)
-
- asm.comment('check fixnum equality')
- asm.mov(:rax, a_opnd)
- asm.mov(:rcx, b_opnd)
- asm.cmp(:rax, :rcx)
- asm.mov(:rax, gen_eq ? Qfalse : Qtrue)
- asm.mov(:rcx, gen_eq ? Qtrue : Qfalse)
- asm.cmove(:rax, :rcx)
-
- # Push the output on the stack
- ctx.stack_pop(2)
- dst = ctx.stack_push(Type::UnknownImm)
- asm.mov(dst, :rax)
-
- true
- elsif C.rb_class_of(comptime_a) == String && C.rb_class_of(comptime_b) == String
- unless Invariants.assume_bop_not_redefined(jit, C::STRING_REDEFINED_OP_FLAG, C::BOP_EQ)
- # if overridden, emit the generic version
- return false
- end
-
- # Guard that a is a String
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_a), a_opnd, StackOpnd[1], comptime_a, side_exit)
-
- equal_label = asm.new_label(:equal)
- ret_label = asm.new_label(:ret)
-
- # If they are equal by identity, return true
- asm.mov(:rax, a_opnd)
- asm.mov(:rcx, b_opnd)
- asm.cmp(:rax, :rcx)
- asm.je(equal_label)
-
- # Otherwise guard that b is a T_STRING (from type info) or String (from runtime guard)
- btype = ctx.get_opnd_type(StackOpnd[0])
- unless btype.string?
- # Note: any T_STRING is valid here, but we check for a ::String for simplicity
- # To pass a mutable static variable (rb_cString) requires an unsafe block
- jit_guard_known_klass(jit, ctx, asm, C.rb_class_of(comptime_b), b_opnd, StackOpnd[0], comptime_b, side_exit)
- end
-
- asm.comment('call rb_str_eql_internal')
- asm.mov(C_ARGS[0], a_opnd)
- asm.mov(C_ARGS[1], b_opnd)
- asm.call(gen_eq ? C.rb_str_eql_internal : C.rjit_str_neq_internal)
-
- # Push the output on the stack
- ctx.stack_pop(2)
- dst = ctx.stack_push(Type::UnknownImm)
- asm.mov(dst, C_RET)
- asm.jmp(ret_label)
-
- asm.write_label(equal_label)
- asm.mov(dst, gen_eq ? Qtrue : Qfalse)
-
- asm.write_label(ret_label)
-
- true
- else
- false
- end
- end
-
- # NOTE: This clobbers :rax
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_prepare_routine_call(jit, ctx, asm)
- jit.record_boundary_patch_point = true
- jit_save_pc(jit, asm)
- jit_save_sp(ctx, asm)
-
- # In case the routine calls Ruby methods, it can set local variables
- # through Kernel#binding and other means.
- ctx.clear_local_types
- end
-
- # NOTE: This clobbers :rax
- # @param jit [RubyVM::RJIT::JITState]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_save_pc(jit, asm, comment: 'save PC to CFP')
- next_pc = jit.pc + jit.insn.len * C.VALUE.size # Use the next one for backtrace and side exits
- asm.comment(comment)
- asm.mov(:rax, next_pc)
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax)
- end
-
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_save_sp(ctx, asm)
- if ctx.sp_offset != 0
- asm.comment('save SP to CFP')
- asm.lea(SP, ctx.sp_opnd)
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP)
- ctx.sp_offset = 0
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jump_to_next_insn(jit, ctx, asm)
- reset_depth = ctx.dup
- reset_depth.chain_depth = 0
-
- next_pc = jit.pc + jit.insn.len * C.VALUE.size
-
- # We are at the end of the current instruction. Record the boundary.
- if jit.record_boundary_patch_point
- exit_pos = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_side_exit(next_pc, ctx, ocb_asm)
- @ocb.write(ocb_asm)
- end
- Invariants.record_global_inval_patch(asm, exit_pos)
- jit.record_boundary_patch_point = false
- end
-
- jit_direct_jump(jit.iseq, next_pc, reset_depth, asm, comment: 'jump_to_next_insn')
- end
-
- # rb_vm_check_ints
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_check_ints(jit, ctx, asm)
- asm.comment('RUBY_VM_CHECK_INTS(ec)')
- asm.mov(:eax, DwordPtr[EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
- asm.test(:eax, :eax)
- asm.jnz(side_exit(jit, ctx))
- end
-
- # See get_lvar_level in compile.c
- def get_lvar_level(iseq)
- level = 0
- while iseq.to_i != iseq.body.local_iseq.to_i
- level += 1
- iseq = iseq.body.parent_iseq
- end
- return level
- end
-
- # GET_LEP
- # @param jit [RubyVM::RJIT::JITState]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_get_lep(jit, asm, reg:)
- level = get_lvar_level(jit.iseq)
- jit_get_ep(asm, level, reg:)
- end
-
- # vm_get_ep
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_get_ep(asm, level, reg:)
- asm.mov(reg, [CFP, C.rb_control_frame_t.offsetof(:ep)])
- level.times do
- # GET_PREV_EP: ep[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03
- asm.mov(reg, [reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL])
- asm.and(reg, ~0x03)
- end
- end
-
- # vm_getivar
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_getivar(jit, ctx, asm, comptime_obj, ivar_id, obj_opnd, obj_yarv_opnd)
- side_exit = side_exit(jit, ctx)
- starting_ctx = ctx.dup # copy for jit_chain_guard
-
- # Guard not special const
- if C::SPECIAL_CONST_P(comptime_obj)
- asm.incr_counter(:getivar_special_const)
- return CantCompile
- end
-
- case C::BUILTIN_TYPE(comptime_obj)
- when C::T_OBJECT
- # This is the only supported case for now (ROBJECT_IVPTR)
- else
- # General case. Call rb_ivar_get().
- # VALUE rb_ivar_get(VALUE obj, ID id)
- asm.comment('call rb_ivar_get()')
- asm.mov(C_ARGS[0], obj_opnd ? obj_opnd : [CFP, C.rb_control_frame_t.offsetof(:self)])
- asm.mov(C_ARGS[1], ivar_id)
-
- # The function could raise exceptions.
- jit_prepare_routine_call(jit, ctx, asm) # clobbers obj_opnd and :rax
-
- asm.call(C.rb_ivar_get)
-
- if obj_opnd # attr_reader
- ctx.stack_pop
- end
-
- # Push the ivar on the stack
- out_opnd = ctx.stack_push(Type::Unknown)
- asm.mov(out_opnd, C_RET)
-
- # Jump to next instruction. This allows guard chains to share the same successor.
- jump_to_next_insn(jit, ctx, asm)
- return EndBlock
- end
-
- asm.mov(:rax, obj_opnd ? obj_opnd : [CFP, C.rb_control_frame_t.offsetof(:self)])
- guard_object_is_heap(jit, ctx, asm, :rax, obj_yarv_opnd, :getivar_not_heap)
-
- shape_id = C.rb_shape_get_shape_id(comptime_obj)
- if shape_id == C::OBJ_TOO_COMPLEX_SHAPE_ID
- asm.incr_counter(:getivar_too_complex)
- return CantCompile
- end
-
- asm.comment('guard shape')
- asm.cmp(DwordPtr[:rax, C.rb_shape_id_offset], shape_id)
- jit_chain_guard(:jne, jit, starting_ctx, asm, counted_exit(side_exit, :getivar_megamorphic))
-
- if obj_opnd
- ctx.stack_pop # pop receiver for attr_reader
- end
-
- index = C.rb_shape_get_iv_index(shape_id, ivar_id)
- # If there is no IVAR index, then the ivar was undefined
- # when we entered the compiler. That means we can just return
- # nil for this shape + iv name
- if index.nil?
- stack_opnd = ctx.stack_push(Type::Nil)
- val_opnd = Qnil
- else
- asm.comment('ROBJECT_IVPTR')
- if C::FL_TEST_RAW(comptime_obj, C::ROBJECT_EMBED)
- # Access embedded array
- asm.mov(:rax, [:rax, C.RObject.offsetof(:as, :ary) + (index * C.VALUE.size)])
- else
- # Pull out an ivar table on heap
- asm.mov(:rax, [:rax, C.RObject.offsetof(:as, :heap, :ivptr)])
- # Read the table
- asm.mov(:rax, [:rax, index * C.VALUE.size])
- end
- stack_opnd = ctx.stack_push(Type::Unknown)
- val_opnd = :rax
- end
- asm.mov(stack_opnd, val_opnd)
-
- # Let guard chains share the same successor
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- end
-
- def jit_write_iv(asm, comptime_receiver, recv_reg, temp_reg, ivar_index, set_value, needs_extension)
- # Compile time self is embedded and the ivar index lands within the object
- embed_test_result = C::FL_TEST_RAW(comptime_receiver, C::ROBJECT_EMBED) && !needs_extension
-
- if embed_test_result
- # Find the IV offset
- offs = C.RObject.offsetof(:as, :ary) + ivar_index * C.VALUE.size
-
- # Write the IV
- asm.comment('write IV')
- asm.mov(temp_reg, set_value)
- asm.mov([recv_reg, offs], temp_reg)
- else
- # Compile time value is *not* embedded.
-
- # Get a pointer to the extended table
- asm.mov(recv_reg, [recv_reg, C.RObject.offsetof(:as, :heap, :ivptr)])
-
- # Write the ivar in to the extended table
- asm.comment("write IV");
- asm.mov(temp_reg, set_value)
- asm.mov([recv_reg, C.VALUE.size * ivar_index], temp_reg)
- end
- end
-
- # vm_caller_setup_arg_block: Handle VM_CALL_ARGS_BLOCKARG cases.
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def guard_block_arg(jit, ctx, asm, calling)
- if calling.flags & C::VM_CALL_ARGS_BLOCKARG != 0
- block_arg_type = ctx.get_opnd_type(StackOpnd[0])
- case block_arg_type
- in Type::Nil
- calling.block_handler = C::VM_BLOCK_HANDLER_NONE
- in Type::BlockParamProxy
- calling.block_handler = C.rb_block_param_proxy
- else
- asm.incr_counter(:send_block_arg)
- return CantCompile
- end
- end
- end
-
- # vm_search_method
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_search_method(jit, ctx, asm, mid, calling)
- assert_equal(true, jit.at_current_insn?)
-
- # Generate a side exit
- side_exit = side_exit(jit, ctx)
-
- # kw_splat is not supported yet
- if calling.flags & C::VM_CALL_KW_SPLAT != 0
- asm.incr_counter(:send_kw_splat)
- return CantCompile
- end
-
- # Get a compile-time receiver and its class
- recv_idx = calling.argc + (calling.flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0) # blockarg is not popped yet
- recv_idx += calling.send_shift
- comptime_recv = jit.peek_at_stack(recv_idx)
- comptime_recv_klass = C.rb_class_of(comptime_recv)
-
- # Guard the receiver class (part of vm_search_method_fastpath)
- recv_opnd = ctx.stack_opnd(recv_idx)
- megamorphic_exit = counted_exit(side_exit, :send_klass_megamorphic)
- jit_guard_known_klass(jit, ctx, asm, comptime_recv_klass, recv_opnd, StackOpnd[recv_idx], comptime_recv, megamorphic_exit)
-
- # Do method lookup (vm_cc_cme(cc) != NULL)
- cme = C.rb_callable_method_entry(comptime_recv_klass, mid)
- if cme.nil?
- asm.incr_counter(:send_missing_cme)
- return CantCompile # We don't support vm_call_method_name
- end
-
- # Invalidate on redefinition (part of vm_search_method_fastpath)
- Invariants.assume_method_lookup_stable(jit, cme)
-
- return cme, comptime_recv_klass
- end
-
- # vm_call_general
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_general(jit, ctx, asm, mid, calling, cme, known_recv_class)
- jit_call_method(jit, ctx, asm, mid, calling, cme, known_recv_class)
- end
-
- # vm_call_method
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- # @param send_shift [Integer] The number of shifts needed for VM_CALL_OPT_SEND
- def jit_call_method(jit, ctx, asm, mid, calling, cme, known_recv_class)
- # The main check of vm_call_method before vm_call_method_each_type
- case C::METHOD_ENTRY_VISI(cme)
- in C::METHOD_VISI_PUBLIC
- # You can always call public methods
- in C::METHOD_VISI_PRIVATE
- # Allow only callsites without a receiver
- if calling.flags & C::VM_CALL_FCALL == 0
- asm.incr_counter(:send_private)
- return CantCompile
- end
- in C::METHOD_VISI_PROTECTED
- # If the method call is an FCALL, it is always valid
- if calling.flags & C::VM_CALL_FCALL == 0
- # otherwise we need an ancestry check to ensure the receiver is valid to be called as protected
- jit_protected_callee_ancestry_guard(asm, cme, side_exit(jit, ctx))
- end
- end
-
- # Get a compile-time receiver
- recv_idx = calling.argc + (calling.flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0) # blockarg is not popped yet
- recv_idx += calling.send_shift
- comptime_recv = jit.peek_at_stack(recv_idx)
- recv_opnd = ctx.stack_opnd(recv_idx)
-
- jit_call_method_each_type(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- end
-
- # Generate ancestry guard for protected callee.
- # Calls to protected callees only go through when self.is_a?(klass_that_defines_the_callee).
- def jit_protected_callee_ancestry_guard(asm, cme, side_exit)
- # See vm_call_method().
- def_class = cme.defined_class
- # Note: PC isn't written to current control frame as rb_is_kind_of() shouldn't raise.
- # VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass);
-
- asm.mov(C_ARGS[0], [CFP, C.rb_control_frame_t.offsetof(:self)])
- asm.mov(C_ARGS[1], to_value(def_class))
- asm.call(C.rb_obj_is_kind_of)
- asm.test(C_RET, C_RET)
- asm.jz(counted_exit(side_exit, :send_protected_check_failed))
- end
-
- # vm_call_method_each_type
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_method_each_type(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- case cme.def.type
- in C::VM_METHOD_TYPE_ISEQ
- iseq = def_iseq_ptr(cme.def)
- jit_call_iseq(jit, ctx, asm, cme, calling, iseq)
- in C::VM_METHOD_TYPE_NOTIMPLEMENTED
- asm.incr_counter(:send_notimplemented)
- return CantCompile
- in C::VM_METHOD_TYPE_CFUNC
- jit_call_cfunc(jit, ctx, asm, cme, calling, known_recv_class:)
- in C::VM_METHOD_TYPE_ATTRSET
- jit_call_attrset(jit, ctx, asm, cme, calling, comptime_recv, recv_opnd)
- in C::VM_METHOD_TYPE_IVAR
- jit_call_ivar(jit, ctx, asm, cme, calling, comptime_recv, recv_opnd)
- in C::VM_METHOD_TYPE_MISSING
- asm.incr_counter(:send_missing)
- return CantCompile
- in C::VM_METHOD_TYPE_BMETHOD
- jit_call_bmethod(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- in C::VM_METHOD_TYPE_ALIAS
- jit_call_alias(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- in C::VM_METHOD_TYPE_OPTIMIZED
- jit_call_optimized(jit, ctx, asm, cme, calling, known_recv_class)
- in C::VM_METHOD_TYPE_UNDEF
- asm.incr_counter(:send_undef)
- return CantCompile
- in C::VM_METHOD_TYPE_ZSUPER
- asm.incr_counter(:send_zsuper)
- return CantCompile
- in C::VM_METHOD_TYPE_REFINED
- asm.incr_counter(:send_refined)
- return CantCompile
- end
- end
-
- # vm_call_iseq_setup
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: nil)
- argc = calling.argc
- flags = calling.flags
- send_shift = calling.send_shift
-
- # When you have keyword arguments, there is an extra object that gets
- # placed on the stack the represents a bitmap of the keywords that were not
- # specified at the call site. We need to keep track of the fact that this
- # value is present on the stack in order to properly set up the callee's
- # stack pointer.
- doing_kw_call = iseq.body.param.flags.has_kw
- supplying_kws = flags & C::VM_CALL_KWARG != 0
-
- if flags & C::VM_CALL_TAILCALL != 0
- # We can't handle tailcalls
- asm.incr_counter(:send_tailcall)
- return CantCompile
- end
-
- # No support for callees with these parameters yet as they require allocation
- # or complex handling.
- if iseq.body.param.flags.has_post
- asm.incr_counter(:send_iseq_has_opt)
- return CantCompile
- end
- if iseq.body.param.flags.has_kwrest
- asm.incr_counter(:send_iseq_has_kwrest)
- return CantCompile
- end
-
- # In order to handle backwards compatibility between ruby 3 and 2
- # ruby2_keywords was introduced. It is called only on methods
- # with splat and changes they way they handle them.
- # We are just going to not compile these.
- # https://www.rubydoc.info/stdlib/core/Proc:ruby2_keywords
- if iseq.body.param.flags.ruby2_keywords && flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_iseq_ruby2_keywords)
- return CantCompile
- end
-
- iseq_has_rest = iseq.body.param.flags.has_rest
- if iseq_has_rest && calling.block_handler == :captured
- asm.incr_counter(:send_iseq_has_rest_and_captured)
- return CantCompile
- end
-
- if iseq_has_rest && iseq.body.param.flags.has_kw && supplying_kws
- asm.incr_counter(:send_iseq_has_rest_and_kw_supplied)
- return CantCompile
- end
-
- # If we have keyword arguments being passed to a callee that only takes
- # positionals, then we need to allocate a hash. For now we're going to
- # call that too complex and bail.
- if supplying_kws && !iseq.body.param.flags.has_kw
- asm.incr_counter(:send_iseq_has_no_kw)
- return CantCompile
- end
-
- # If we have a method accepting no kwargs (**nil), exit if we have passed
- # it any kwargs.
- if supplying_kws && iseq.body.param.flags.accepts_no_kwarg
- asm.incr_counter(:send_iseq_accepts_no_kwarg)
- return CantCompile
- end
-
- # For computing number of locals to set up for the callee
- num_params = iseq.body.param.size
-
- # Block parameter handling. This mirrors setup_parameters_complex().
- if iseq.body.param.flags.has_block
- if iseq.body.local_iseq.to_i == iseq.to_i
- num_params -= 1
- else
- # In this case (param.flags.has_block && local_iseq != iseq),
- # the block argument is setup as a local variable and requires
- # materialization (allocation). Bail.
- asm.incr_counter(:send_iseq_materialized_block)
- return CantCompile
- end
- end
-
- if flags & C::VM_CALL_ARGS_SPLAT != 0 && flags & C::VM_CALL_ZSUPER != 0
- # zsuper methods are super calls without any arguments.
- # They are also marked as splat, but don't actually have an array
- # they pull arguments from, instead we need to change to call
- # a different method with the current stack.
- asm.incr_counter(:send_iseq_zsuper)
- return CantCompile
- end
-
- start_pc_offset = 0
- required_num = iseq.body.param.lead_num
-
- # This struct represents the metadata about the caller-specified
- # keyword arguments.
- kw_arg = calling.kwarg
- kw_arg_num = if kw_arg.nil?
- 0
- else
- kw_arg.keyword_len
- end
-
- # Arity handling and optional parameter setup
- opts_filled = argc - required_num - kw_arg_num
- opt_num = iseq.body.param.opt_num
- opts_missing = opt_num - opts_filled
-
- if doing_kw_call && flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_iseq_splat_with_kw)
- return CantCompile
- end
-
- if iseq_has_rest && opt_num != 0
- asm.incr_counter(:send_iseq_has_rest_and_optional)
- return CantCompile
- end
-
- if opts_filled < 0 && flags & C::VM_CALL_ARGS_SPLAT == 0
- # Too few arguments and no splat to make up for it
- asm.incr_counter(:send_iseq_arity_error)
- return CantCompile
- end
-
- if opts_filled > opt_num && !iseq_has_rest
- # Too many arguments and no place to put them (i.e. rest arg)
- asm.incr_counter(:send_iseq_arity_error)
- return CantCompile
- end
-
- block_arg = flags & C::VM_CALL_ARGS_BLOCKARG != 0
-
- # Guard block_arg_type
- if guard_block_arg(jit, ctx, asm, calling) == CantCompile
- return CantCompile
- end
-
- # If we have unfilled optional arguments and keyword arguments then we
- # would need to adjust the arguments location to account for that.
- # For now we aren't handling this case.
- if doing_kw_call && opts_missing > 0
- asm.incr_counter(:send_iseq_missing_optional_kw)
- return CantCompile
- end
-
- # We will handle splat case later
- if opt_num > 0 && flags & C::VM_CALL_ARGS_SPLAT == 0
- num_params -= opts_missing
- start_pc_offset = iseq.body.param.opt_table[opts_filled]
- end
-
- if doing_kw_call
- # Here we're calling a method with keyword arguments and specifying
- # keyword arguments at this call site.
-
- # This struct represents the metadata about the callee-specified
- # keyword parameters.
- keyword = iseq.body.param.keyword
- keyword_num = keyword.num
- keyword_required_num = keyword.required_num
-
- required_kwargs_filled = 0
-
- if keyword_num > 30
- # We have so many keywords that (1 << num) encoded as a FIXNUM
- # (which shifts it left one more) no longer fits inside a 32-bit
- # immediate.
- asm.incr_counter(:send_iseq_too_many_kwargs)
- return CantCompile
- end
-
- # Check that the kwargs being passed are valid
- if supplying_kws
- # This is the list of keyword arguments that the callee specified
- # in its initial declaration.
- # SAFETY: see compile.c for sizing of this slice.
- callee_kwargs = keyword_num.times.map { |i| keyword.table[i] }
-
- # Here we're going to build up a list of the IDs that correspond to
- # the caller-specified keyword arguments. If they're not in the
- # same order as the order specified in the callee declaration, then
- # we're going to need to generate some code to swap values around
- # on the stack.
- caller_kwargs = []
- kw_arg.keyword_len.times do |kwarg_idx|
- sym = C.to_ruby(kw_arg[:keywords][kwarg_idx])
- caller_kwargs << C.rb_sym2id(sym)
- end
-
- # First, we're going to be sure that the names of every
- # caller-specified keyword argument correspond to a name in the
- # list of callee-specified keyword parameters.
- caller_kwargs.each do |caller_kwarg|
- search_result = callee_kwargs.map.with_index.find { |kwarg, _| kwarg == caller_kwarg }
-
- case search_result
- in nil
- # If the keyword was never found, then we know we have a
- # mismatch in the names of the keyword arguments, so we need to
- # bail.
- asm.incr_counter(:send_iseq_kwargs_mismatch)
- return CantCompile
- in _, callee_idx if callee_idx < keyword_required_num
- # Keep a count to ensure all required kwargs are specified
- required_kwargs_filled += 1
- else
- end
- end
- end
- assert_equal(true, required_kwargs_filled <= keyword_required_num)
- if required_kwargs_filled != keyword_required_num
- asm.incr_counter(:send_iseq_kwargs_mismatch)
- return CantCompile
- end
- end
-
- # Check if we need the arg0 splat handling of vm_callee_setup_block_arg
- arg_setup_block = (calling.block_handler == :captured) # arg_setup_type: arg_setup_block (invokeblock)
- block_arg0_splat = arg_setup_block && argc == 1 &&
- (iseq.body.param.flags.has_lead || opt_num > 1) &&
- !iseq.body.param.flags.ambiguous_param0
- if block_arg0_splat
- # If block_arg0_splat, we still need side exits after splat, but
- # doing push_splat_args here disallows it. So bail out.
- if flags & C::VM_CALL_ARGS_SPLAT != 0 && !iseq_has_rest
- asm.incr_counter(:invokeblock_iseq_arg0_args_splat)
- return CantCompile
- end
- # The block_arg0_splat implementation is for the rb_simple_iseq_p case,
- # but doing_kw_call means it's not a simple ISEQ.
- if doing_kw_call
- asm.incr_counter(:invokeblock_iseq_arg0_has_kw)
- return CantCompile
- end
- # The block_arg0_splat implementation cannot deal with optional parameters.
- # This is a setup_parameters_complex() situation and interacts with the
- # starting position of the callee.
- if opt_num > 1
- asm.incr_counter(:invokeblock_iseq_arg0_optional)
- return CantCompile
- end
- end
- if flags & C::VM_CALL_ARGS_SPLAT != 0 && !iseq_has_rest
- array = jit.peek_at_stack(block_arg ? 1 : 0)
- splat_array_length = if array.nil?
- 0
- else
- array.length
- end
-
- if opt_num == 0 && required_num != splat_array_length + argc - 1
- asm.incr_counter(:send_iseq_splat_arity_error)
- return CantCompile
- end
- end
-
- # We will not have CantCompile from here.
-
- if block_arg
- ctx.stack_pop(1)
- end
-
- if calling.block_handler == C::VM_BLOCK_HANDLER_NONE && iseq.body.builtin_attrs & C::BUILTIN_ATTR_LEAF != 0
- if jit_leaf_builtin_func(jit, ctx, asm, flags, iseq)
- return KeepCompiling
- end
- end
-
- # Number of locals that are not parameters
- num_locals = iseq.body.local_table_size - num_params
-
- # Stack overflow check
- # Note that vm_push_frame checks it against a decremented cfp, hence the multiply by 2.
- # #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
- asm.comment('stack overflow check')
- locals_offs = C.VALUE.size * (num_locals + iseq.body.stack_max) + 2 * C.rb_control_frame_t.size
- asm.lea(:rax, ctx.sp_opnd(locals_offs))
- asm.cmp(CFP, :rax)
- asm.jbe(counted_exit(side_exit(jit, ctx), :send_stackoverflow))
-
- # push_splat_args does stack manipulation so we can no longer side exit
- if splat_array_length
- remaining_opt = (opt_num + required_num) - (splat_array_length + (argc - 1))
-
- if opt_num > 0
- # We are going to jump to the correct offset based on how many optional
- # params are remaining.
- offset = opt_num - remaining_opt
- start_pc_offset = iseq.body.param.opt_table[offset]
- end
- # We are going to assume that the splat fills
- # all the remaining arguments. In the generated code
- # we test if this is true and if not side exit.
- argc = argc - 1 + splat_array_length + remaining_opt
- push_splat_args(splat_array_length, jit, ctx, asm)
-
- remaining_opt.times do
- # We need to push nil for the optional arguments
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, Qnil)
- end
- end
-
- # This is a .send call and we need to adjust the stack
- if flags & C::VM_CALL_OPT_SEND != 0
- handle_opt_send_shift_stack(asm, argc, ctx, send_shift:)
- end
-
- if iseq_has_rest
- # We are going to allocate so setting pc and sp.
- jit_save_pc(jit, asm) # clobbers rax
- jit_save_sp(ctx, asm)
-
- if flags & C::VM_CALL_ARGS_SPLAT != 0
- non_rest_arg_count = argc - 1
- # We start by dupping the array because someone else might have
- # a reference to it.
- array = ctx.stack_pop(1)
- asm.mov(C_ARGS[0], array)
- asm.call(C.rb_ary_dup)
- array = C_RET
- if non_rest_arg_count > required_num
- # If we have more arguments than required, we need to prepend
- # the items from the stack onto the array.
- diff = (non_rest_arg_count - required_num)
-
- # diff is >0 so no need to worry about null pointer
- asm.comment('load pointer to array elements')
- offset_magnitude = C.VALUE.size * diff
- values_opnd = ctx.sp_opnd(-offset_magnitude)
- values_ptr = :rcx
- asm.lea(values_ptr, values_opnd)
-
- asm.comment('prepend stack values to rest array')
- asm.mov(C_ARGS[0], diff)
- asm.mov(C_ARGS[1], values_ptr)
- asm.mov(C_ARGS[2], array)
- asm.call(C.rb_ary_unshift_m)
- ctx.stack_pop(diff)
-
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
- # We now should have the required arguments
- # and an array of all the rest arguments
- argc = required_num + 1
- elsif non_rest_arg_count < required_num
- # If we have fewer arguments than required, we need to take some
- # from the array and move them to the stack.
- diff = (required_num - non_rest_arg_count)
- # This moves the arguments onto the stack. But it doesn't modify the array.
- move_rest_args_to_stack(array, diff, jit, ctx, asm)
-
- # We will now slice the array to give us a new array of the correct size
- asm.mov(C_ARGS[0], array)
- asm.mov(C_ARGS[1], diff)
- asm.call(C.rjit_rb_ary_subseq_length)
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
-
- # We now should have the required arguments
- # and an array of all the rest arguments
- argc = required_num + 1
- else
- # The arguments are equal so we can just push to the stack
- assert_equal(non_rest_arg_count, required_num)
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, array)
- end
- else
- assert_equal(true, argc >= required_num)
- n = (argc - required_num)
- argc = required_num + 1
- # If n is 0, then elts is never going to be read, so we can just pass null
- if n == 0
- values_ptr = 0
- else
- asm.comment('load pointer to array elements')
- offset_magnitude = C.VALUE.size * n
- values_opnd = ctx.sp_opnd(-offset_magnitude)
- values_ptr = :rcx
- asm.lea(values_ptr, values_opnd)
- end
-
- asm.mov(C_ARGS[0], EC)
- asm.mov(C_ARGS[1], n)
- asm.mov(C_ARGS[2], values_ptr)
- asm.call(C.rb_ec_ary_new_from_values)
-
- ctx.stack_pop(n)
- stack_ret = ctx.stack_push(Type::TArray)
- asm.mov(stack_ret, C_RET)
- end
- end
-
- if doing_kw_call
- # Here we're calling a method with keyword arguments and specifying
- # keyword arguments at this call site.
-
- # Number of positional arguments the callee expects before the first
- # keyword argument
- args_before_kw = required_num + opt_num
-
- # This struct represents the metadata about the caller-specified
- # keyword arguments.
- ci_kwarg = calling.kwarg
- caller_keyword_len = if ci_kwarg.nil?
- 0
- else
- ci_kwarg.keyword_len
- end
-
- # This struct represents the metadata about the callee-specified
- # keyword parameters.
- keyword = iseq.body.param.keyword
-
- asm.comment('keyword args')
-
- # This is the list of keyword arguments that the callee specified
- # in its initial declaration.
- callee_kwargs = keyword.table
- total_kwargs = keyword.num
-
- # Here we're going to build up a list of the IDs that correspond to
- # the caller-specified keyword arguments. If they're not in the
- # same order as the order specified in the callee declaration, then
- # we're going to need to generate some code to swap values around
- # on the stack.
- caller_kwargs = []
-
- caller_keyword_len.times do |kwarg_idx|
- sym = C.to_ruby(ci_kwarg[:keywords][kwarg_idx])
- caller_kwargs << C.rb_sym2id(sym)
- end
- kwarg_idx = caller_keyword_len
-
- unspecified_bits = 0
-
- keyword_required_num = keyword.required_num
- (keyword_required_num...total_kwargs).each do |callee_idx|
- already_passed = false
- callee_kwarg = callee_kwargs[callee_idx]
-
- caller_keyword_len.times do |caller_idx|
- if caller_kwargs[caller_idx] == callee_kwarg
- already_passed = true
- break
- end
- end
-
- unless already_passed
- # Reserve space on the stack for each default value we'll be
- # filling in (which is done in the next loop). Also increments
- # argc so that the callee's SP is recorded correctly.
- argc += 1
- default_arg = ctx.stack_push(Type::Unknown)
-
- # callee_idx - keyword->required_num is used in a couple of places below.
- req_num = keyword.required_num
- extra_args = callee_idx - req_num
-
- # VALUE default_value = keyword->default_values[callee_idx - keyword->required_num];
- default_value = keyword.default_values[extra_args]
-
- if default_value == Qundef
- # Qundef means that this value is not constant and must be
- # recalculated at runtime, so we record it in unspecified_bits
- # (Qnil is then used as a placeholder instead of Qundef).
- unspecified_bits |= 0x01 << extra_args
- default_value = Qnil
- end
-
- asm.mov(:rax, default_value)
- asm.mov(default_arg, :rax)
-
- caller_kwargs[kwarg_idx] = callee_kwarg
- kwarg_idx += 1
- end
- end
-
- assert_equal(kwarg_idx, total_kwargs)
-
- # Next, we're going to loop through every keyword that was
- # specified by the caller and make sure that it's in the correct
- # place. If it's not we're going to swap it around with another one.
- total_kwargs.times do |kwarg_idx|
- callee_kwarg = callee_kwargs[kwarg_idx]
-
- # If the argument is already in the right order, then we don't
- # need to generate any code since the expected value is already
- # in the right place on the stack.
- if callee_kwarg == caller_kwargs[kwarg_idx]
- next
- end
-
- # In this case the argument is not in the right place, so we
- # need to find its position where it _should_ be and swap with
- # that location.
- ((kwarg_idx + 1)...total_kwargs).each do |swap_idx|
- if callee_kwarg == caller_kwargs[swap_idx]
- # First we're going to generate the code that is going
- # to perform the actual swapping at runtime.
- offset0 = argc - 1 - swap_idx - args_before_kw
- offset1 = argc - 1 - kwarg_idx - args_before_kw
- stack_swap(jit, ctx, asm, offset0, offset1)
-
- # Next we're going to do some bookkeeping on our end so
- # that we know the order that the arguments are
- # actually in now.
- caller_kwargs[kwarg_idx], caller_kwargs[swap_idx] =
- caller_kwargs[swap_idx], caller_kwargs[kwarg_idx]
-
- break
- end
- end
- end
-
- # Keyword arguments cause a special extra local variable to be
- # pushed onto the stack that represents the parameters that weren't
- # explicitly given a value and have a non-constant default.
- asm.mov(ctx.stack_opnd(-1), C.to_value(unspecified_bits))
- end
-
- # Same as vm_callee_setup_block_arg_arg0_check and vm_callee_setup_block_arg_arg0_splat
- # on vm_callee_setup_block_arg for arg_setup_block. This is done after CALLER_SETUP_ARG
- # and CALLER_REMOVE_EMPTY_KW_SPLAT, so this implementation is put here. This may need
- # side exits, so you still need to allow side exits here if block_arg0_splat is true.
- # Note that you can't have side exits after this arg0 splat.
- if block_arg0_splat
- asm.incr_counter(:send_iseq_block_arg0_splat)
- return CantCompile
- end
-
- # Create a context for the callee
- callee_ctx = Context.new
-
- # Set the argument types in the callee's context
- argc.times do |arg_idx|
- stack_offs = argc - arg_idx - 1
- arg_type = ctx.get_opnd_type(StackOpnd[stack_offs])
- callee_ctx.set_local_type(arg_idx, arg_type)
- end
-
- recv_type = if calling.block_handler == :captured
- Type::Unknown # we don't track the type information of captured->self for now
- else
- ctx.get_opnd_type(StackOpnd[argc])
- end
- callee_ctx.upgrade_opnd_type(SelfOpnd, recv_type)
-
- # Setup the new frame
- frame_type ||= C::VM_FRAME_MAGIC_METHOD | C::VM_ENV_FLAG_LOCAL
- jit_push_frame(
- jit, ctx, asm, cme, flags, argc, frame_type, calling.block_handler,
- iseq: iseq,
- local_size: num_locals,
- stack_max: iseq.body.stack_max,
- prev_ep:,
- doing_kw_call:,
- )
-
- # Directly jump to the entry point of the callee
- pc = (iseq.body.iseq_encoded + start_pc_offset).to_i
- jit_direct_jump(iseq, pc, callee_ctx, asm)
-
- EndBlock
- end
-
- def jit_leaf_builtin_func(jit, ctx, asm, flags, iseq)
- builtin_func = builtin_function(iseq)
- if builtin_func.nil?
- return false
- end
-
- # this is a .send call not currently supported for builtins
- if flags & C::VM_CALL_OPT_SEND != 0
- return false
- end
-
- builtin_argc = builtin_func.argc
- if builtin_argc + 1 >= C_ARGS.size
- return false
- end
-
- asm.comment('inlined leaf builtin')
-
- # Skip this if it doesn't trigger GC
- if iseq.body.builtin_attrs & C::BUILTIN_ATTR_NO_GC == 0
- # The callee may allocate, e.g. Integer#abs on a Bignum.
- # Save SP for GC, save PC for allocation tracing, and prepare
- # for global invalidation after GC's VM lock contention.
- jit_prepare_routine_call(jit, ctx, asm)
- end
-
- # Call the builtin func (ec, recv, arg1, arg2, ...)
- asm.mov(C_ARGS[0], EC)
-
- # Copy self and arguments
- (0..builtin_argc).each do |i|
- stack_opnd = ctx.stack_opnd(builtin_argc - i)
- asm.mov(C_ARGS[i + 1], stack_opnd)
- end
- ctx.stack_pop(builtin_argc + 1)
- asm.call(builtin_func.func_ptr)
-
- # Push the return value
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
- return true
- end
-
- # vm_call_cfunc
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_cfunc(jit, ctx, asm, cme, calling, known_recv_class: nil)
- argc = calling.argc
- flags = calling.flags
-
- cfunc = cme.def.body.cfunc
- cfunc_argc = cfunc.argc
-
- # If the function expects a Ruby array of arguments
- if cfunc_argc < 0 && cfunc_argc != -1
- asm.incr_counter(:send_cfunc_ruby_array_varg)
- return CantCompile
- end
-
- # We aren't handling a vararg cfuncs with splat currently.
- if flags & C::VM_CALL_ARGS_SPLAT != 0 && cfunc_argc == -1
- asm.incr_counter(:send_args_splat_cfunc_var_args)
- return CantCompile
- end
-
- if flags & C::VM_CALL_ARGS_SPLAT != 0 && flags & C::VM_CALL_ZSUPER != 0
- # zsuper methods are super calls without any arguments.
- # They are also marked as splat, but don't actually have an array
- # they pull arguments from, instead we need to change to call
- # a different method with the current stack.
- asm.incr_counter(:send_args_splat_cfunc_zuper)
- return CantCompile;
- end
-
- # In order to handle backwards compatibility between ruby 3 and 2
- # ruby2_keywords was introduced. It is called only on methods
- # with splat and changes they way they handle them.
- # We are just going to not compile these.
- # https://docs.ruby-lang.org/en/3.2/Module.html#method-i-ruby2_keywords
- if jit.iseq.body.param.flags.ruby2_keywords && flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_args_splat_cfunc_ruby2_keywords)
- return CantCompile;
- end
-
- kw_arg = calling.kwarg
- kw_arg_num = if kw_arg.nil?
- 0
- else
- kw_arg.keyword_len
- end
-
- if kw_arg_num != 0 && flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_cfunc_splat_with_kw)
- return CantCompile
- end
-
- if c_method_tracing_currently_enabled?
- # Don't JIT if tracing c_call or c_return
- asm.incr_counter(:send_cfunc_tracing)
- return CantCompile
- end
-
- # Delegate to codegen for C methods if we have it.
- if kw_arg.nil? && flags & C::VM_CALL_OPT_SEND == 0 && flags & C::VM_CALL_ARGS_SPLAT == 0 && (cfunc_argc == -1 || argc == cfunc_argc)
- known_cfunc_codegen = lookup_cfunc_codegen(cme.def)
- if known_cfunc_codegen&.call(jit, ctx, asm, argc, known_recv_class)
- # cfunc codegen generated code. Terminate the block so
- # there isn't multiple calls in the same block.
- jump_to_next_insn(jit, ctx, asm)
- return EndBlock
- end
- end
-
- # Check for interrupts
- jit_check_ints(jit, ctx, asm)
-
- # Stack overflow check
- # #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
- # REG_CFP <= REG_SP + 4 * SIZEOF_VALUE + sizeof(rb_control_frame_t)
- asm.comment('stack overflow check')
- asm.lea(:rax, ctx.sp_opnd(C.VALUE.size * 4 + 2 * C.rb_control_frame_t.size))
- asm.cmp(CFP, :rax)
- asm.jbe(counted_exit(side_exit(jit, ctx), :send_stackoverflow))
-
- # Number of args which will be passed through to the callee
- # This is adjusted by the kwargs being combined into a hash.
- passed_argc = if kw_arg.nil?
- argc
- else
- argc - kw_arg_num + 1
- end
-
- # If the argument count doesn't match
- if cfunc_argc >= 0 && cfunc_argc != passed_argc && flags & C::VM_CALL_ARGS_SPLAT == 0
- asm.incr_counter(:send_cfunc_argc_mismatch)
- return CantCompile
- end
-
- # Don't JIT functions that need C stack arguments for now
- if cfunc_argc >= 0 && passed_argc + 1 > C_ARGS.size
- asm.incr_counter(:send_cfunc_toomany_args)
- return CantCompile
- end
-
- block_arg = flags & C::VM_CALL_ARGS_BLOCKARG != 0
-
- # Guard block_arg_type
- if guard_block_arg(jit, ctx, asm, calling) == CantCompile
- return CantCompile
- end
-
- if block_arg
- ctx.stack_pop(1)
- end
-
- # push_splat_args does stack manipulation so we can no longer side exit
- if flags & C::VM_CALL_ARGS_SPLAT != 0
- assert_equal(true, cfunc_argc >= 0)
- required_args = cfunc_argc - (argc - 1)
- # + 1 because we pass self
- if required_args + 1 >= C_ARGS.size
- asm.incr_counter(:send_cfunc_toomany_args)
- return CantCompile
- end
-
- # We are going to assume that the splat fills
- # all the remaining arguments. So the number of args
- # should just equal the number of args the cfunc takes.
- # In the generated code we test if this is true
- # and if not side exit.
- argc = cfunc_argc
- passed_argc = argc
- push_splat_args(required_args, jit, ctx, asm)
- end
-
- # This is a .send call and we need to adjust the stack
- if flags & C::VM_CALL_OPT_SEND != 0
- handle_opt_send_shift_stack(asm, argc, ctx, send_shift: calling.send_shift)
- end
-
- # Points to the receiver operand on the stack
-
- # Store incremented PC into current control frame in case callee raises.
- jit_save_pc(jit, asm)
-
- # Increment the stack pointer by 3 (in the callee)
- # sp += 3
-
- frame_type = C::VM_FRAME_MAGIC_CFUNC | C::VM_FRAME_FLAG_CFRAME | C::VM_ENV_FLAG_LOCAL
- if kw_arg
- frame_type |= C::VM_FRAME_FLAG_CFRAME_KW
- end
-
- jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, calling.block_handler)
-
- if kw_arg
- # Build a hash from all kwargs passed
- asm.comment('build_kwhash')
- imemo_ci = calling.ci_addr
- # we assume all callinfos with kwargs are on the GC heap
- assert_equal(true, C.imemo_type_p(imemo_ci, C.imemo_callinfo))
- asm.mov(C_ARGS[0], imemo_ci)
- asm.lea(C_ARGS[1], ctx.sp_opnd(0))
- asm.call(C.rjit_build_kwhash)
-
- # Replace the stack location at the start of kwargs with the new hash
- stack_opnd = ctx.stack_opnd(argc - passed_argc)
- asm.mov(stack_opnd, C_RET)
- end
-
- # Copy SP because REG_SP will get overwritten
- sp = :rax
- asm.lea(sp, ctx.sp_opnd(0))
-
- # Pop the C function arguments from the stack (in the caller)
- ctx.stack_pop(argc + 1)
-
- # Write interpreter SP into CFP.
- # Needed in case the callee yields to the block.
- jit_save_sp(ctx, asm)
-
- # Non-variadic method
- case cfunc_argc
- in (0..) # Non-variadic method
- # Copy the arguments from the stack to the C argument registers
- # self is the 0th argument and is at index argc from the stack top
- (0..passed_argc).each do |i|
- asm.mov(C_ARGS[i], [sp, -(argc + 1 - i) * C.VALUE.size])
- end
- in -1 # Variadic method: rb_f_puts(int argc, VALUE *argv, VALUE recv)
- # The method gets a pointer to the first argument
- # rb_f_puts(int argc, VALUE *argv, VALUE recv)
- asm.mov(C_ARGS[0], passed_argc)
- asm.lea(C_ARGS[1], [sp, -argc * C.VALUE.size]) # argv
- asm.mov(C_ARGS[2], [sp, -(argc + 1) * C.VALUE.size]) # recv
- end
-
- # Call the C function
- # VALUE ret = (cfunc->func)(recv, argv[0], argv[1]);
- # cfunc comes from compile-time cme->def, which we assume to be stable.
- # Invalidation logic is in yjit_method_lookup_change()
- asm.comment('call C function')
- asm.mov(:rax, cfunc.func)
- asm.call(:rax) # TODO: use rel32 if close enough
-
- # Record code position for TracePoint patching. See full_cfunc_return().
- Invariants.record_global_inval_patch(asm, full_cfunc_return)
-
- # Push the return value on the Ruby stack
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
-
- # Pop the stack frame (ec->cfp++)
- # Instead of recalculating, we can reuse the previous CFP, which is stored in a callee-saved
- # register
- asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], CFP)
-
- # cfunc calls may corrupt types
- ctx.clear_local_types
-
- # Note: the return block of jit_call_iseq has ctx->sp_offset == 1
- # which allows for sharing the same successor.
-
- # Jump (fall through) to the call continuation block
- # We do this to end the current block after the call
- assert_equal(1, ctx.sp_offset)
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- end
-
- # vm_call_attrset
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_attrset(jit, ctx, asm, cme, calling, comptime_recv, recv_opnd)
- argc = calling.argc
- flags = calling.flags
- send_shift = calling.send_shift
-
- if flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_attrset_splat)
- return CantCompile
- end
- if flags & C::VM_CALL_KWARG != 0
- asm.incr_counter(:send_attrset_kwarg)
- return CantCompile
- elsif argc != 1 || !C.RB_TYPE_P(comptime_recv, C::RUBY_T_OBJECT)
- asm.incr_counter(:send_attrset_method)
- return CantCompile
- elsif c_method_tracing_currently_enabled?
- # Can't generate code for firing c_call and c_return events
- # See :attr-tracing:
- asm.incr_counter(:send_c_tracingg)
- return CantCompile
- elsif flags & C::VM_CALL_ARGS_BLOCKARG != 0
- asm.incr_counter(:send_block_arg)
- return CantCompile
- end
-
- ivar_name = cme.def.body.attr.id
-
- # This is a .send call and we need to adjust the stack
- if flags & C::VM_CALL_OPT_SEND != 0
- handle_opt_send_shift_stack(asm, argc, ctx, send_shift:)
- end
-
- # Save the PC and SP because the callee may allocate
- # Note that this modifies REG_SP, which is why we do it first
- jit_prepare_routine_call(jit, ctx, asm)
-
- # Get the operands from the stack
- val_opnd = ctx.stack_pop(1)
- recv_opnd = ctx.stack_pop(1)
-
- # Call rb_vm_set_ivar_id with the receiver, the ivar name, and the value
- asm.mov(C_ARGS[0], recv_opnd)
- asm.mov(C_ARGS[1], ivar_name)
- asm.mov(C_ARGS[2], val_opnd)
- asm.call(C.rb_vm_set_ivar_id)
-
- out_opnd = ctx.stack_push(Type::Unknown)
- asm.mov(out_opnd, C_RET)
-
- KeepCompiling
- end
-
- # vm_call_ivar (+ part of vm_call_method_each_type)
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_ivar(jit, ctx, asm, cme, calling, comptime_recv, recv_opnd)
- argc = calling.argc
- flags = calling.flags
-
- if flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_ivar_splat)
- return CantCompile
- end
-
- if argc != 0
- asm.incr_counter(:send_arity)
- return CantCompile
- end
-
- # We don't support handle_opt_send_shift_stack for this yet.
- if flags & C::VM_CALL_OPT_SEND != 0
- asm.incr_counter(:send_ivar_opt_send)
- return CantCompile
- end
-
- ivar_id = cme.def.body.attr.id
-
- # Not handling block_handler
- if flags & C::VM_CALL_ARGS_BLOCKARG != 0
- asm.incr_counter(:send_block_arg)
- return CantCompile
- end
-
- jit_getivar(jit, ctx, asm, comptime_recv, ivar_id, recv_opnd, StackOpnd[0])
- end
-
- # vm_call_bmethod
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_bmethod(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- proc_addr = cme.def.body.bmethod.proc
-
- proc_t = C.rb_yjit_get_proc_ptr(proc_addr)
- proc_block = proc_t.block
-
- if proc_block.type != C.block_type_iseq
- asm.incr_counter(:send_bmethod_not_iseq)
- return CantCompile
- end
-
- capture = proc_block.as.captured
- iseq = capture.code.iseq
-
- # TODO: implement this
- # Optimize for single ractor mode and avoid runtime check for
- # "defined with an un-shareable Proc in a different Ractor"
- # if !assume_single_ractor_mode(jit, ocb)
- # return CantCompile;
- # end
-
- # Passing a block to a block needs logic different from passing
- # a block to a method and sometimes requires allocation. Bail for now.
- if calling.block_handler != C::VM_BLOCK_HANDLER_NONE
- asm.incr_counter(:send_bmethod_blockarg)
- return CantCompile
- end
-
- jit_call_iseq(
- jit, ctx, asm, cme, calling, iseq,
- frame_type: C::VM_FRAME_MAGIC_BLOCK | C::VM_FRAME_FLAG_BMETHOD | C::VM_FRAME_FLAG_LAMBDA,
- prev_ep: capture.ep,
- )
- end
-
- # vm_call_alias
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_alias(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- cme = C.rb_aliased_callable_method_entry(cme)
- jit_call_method_each_type(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)
- end
-
- # vm_call_optimized
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_optimized(jit, ctx, asm, cme, calling, known_recv_class)
- if calling.flags & C::VM_CALL_ARGS_BLOCKARG != 0
- # Not working yet
- asm.incr_counter(:send_block_arg)
- return CantCompile
- end
-
- case cme.def.body.optimized.type
- in C::OPTIMIZED_METHOD_TYPE_SEND
- jit_call_opt_send(jit, ctx, asm, cme, calling, known_recv_class)
- in C::OPTIMIZED_METHOD_TYPE_CALL
- jit_call_opt_call(jit, ctx, asm, cme, calling.flags, calling.argc, calling.block_handler, known_recv_class, send_shift: calling.send_shift)
- in C::OPTIMIZED_METHOD_TYPE_BLOCK_CALL
- asm.incr_counter(:send_optimized_block_call)
- return CantCompile
- in C::OPTIMIZED_METHOD_TYPE_STRUCT_AREF
- jit_call_opt_struct_aref(jit, ctx, asm, cme, calling.flags, calling.argc, calling.block_handler, known_recv_class, send_shift: calling.send_shift)
- in C::OPTIMIZED_METHOD_TYPE_STRUCT_ASET
- asm.incr_counter(:send_optimized_struct_aset)
- return CantCompile
- end
- end
-
- # vm_call_opt_send
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_opt_send(jit, ctx, asm, cme, calling, known_recv_class)
- if jit_caller_setup_arg(jit, ctx, asm, calling.flags) == CantCompile
- return CantCompile
- end
-
- if calling.argc == 0
- asm.incr_counter(:send_optimized_send_no_args)
- return CantCompile
- end
-
- calling.argc -= 1
- # We aren't handling `send(:send, ...)` yet. This might work, but not tested yet.
- if calling.send_shift > 0
- asm.incr_counter(:send_optimized_send_send)
- return CantCompile
- end
- # Lazily handle stack shift in handle_opt_send_shift_stack
- calling.send_shift += 1
-
- jit_call_symbol(jit, ctx, asm, cme, calling, known_recv_class, C::VM_CALL_FCALL)
- end
-
- # vm_call_opt_call
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_opt_call(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
- if block_handler != C::VM_BLOCK_HANDLER_NONE
- asm.incr_counter(:send_optimized_call_block)
- return CantCompile
- end
-
- if flags & C::VM_CALL_KWARG != 0
- asm.incr_counter(:send_optimized_call_kwarg)
- return CantCompile
- end
-
- if flags & C::VM_CALL_ARGS_SPLAT != 0
- asm.incr_counter(:send_optimized_call_splat)
- return CantCompile
- end
-
- # TODO: implement this
- # Optimize for single ractor mode and avoid runtime check for
- # "defined with an un-shareable Proc in a different Ractor"
- # if !assume_single_ractor_mode(jit, ocb)
- # return CantCompile
- # end
-
- # If this is a .send call we need to adjust the stack
- if flags & C::VM_CALL_OPT_SEND != 0
- handle_opt_send_shift_stack(asm, argc, ctx, send_shift:)
- end
-
- # About to reset the SP, need to load this here
- recv_idx = argc # blockarg is not supported. send_shift is already handled.
- asm.mov(:rcx, ctx.stack_opnd(recv_idx)) # recv
-
- # Save the PC and SP because the callee can make Ruby calls
- jit_prepare_routine_call(jit, ctx, asm) # NOTE: clobbers rax
-
- asm.lea(:rax, ctx.sp_opnd(0)) # sp
-
- kw_splat = flags & C::VM_CALL_KW_SPLAT
-
- asm.mov(C_ARGS[0], :rcx)
- asm.mov(C_ARGS[1], EC)
- asm.mov(C_ARGS[2], argc)
- asm.lea(C_ARGS[3], [:rax, -argc * C.VALUE.size]) # stack_argument_pointer. NOTE: C_ARGS[3] is rcx
- asm.mov(C_ARGS[4], kw_splat)
- asm.mov(C_ARGS[5], C::VM_BLOCK_HANDLER_NONE)
- asm.call(C.rjit_optimized_call)
-
- ctx.stack_pop(argc + 1)
-
- stack_ret = ctx.stack_push(Type::Unknown)
- asm.mov(stack_ret, C_RET)
- return KeepCompiling
- end
-
- # vm_call_opt_struct_aref
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_opt_struct_aref(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
- if argc != 0
- asm.incr_counter(:send_optimized_struct_aref_error)
- return CantCompile
- end
-
- off = cme.def.body.optimized.index
-
- recv_idx = argc # blockarg is not supported
- recv_idx += send_shift
- comptime_recv = jit.peek_at_stack(recv_idx)
-
- # This is a .send call and we need to adjust the stack
- if flags & C::VM_CALL_OPT_SEND != 0
- handle_opt_send_shift_stack(asm, argc, ctx, send_shift:)
- end
-
- # All structs from the same Struct class should have the same
- # length. So if our comptime_recv is embedded all runtime
- # structs of the same class should be as well, and the same is
- # true of the converse.
- embedded = C::FL_TEST_RAW(comptime_recv, C::RSTRUCT_EMBED_LEN_MASK)
-
- asm.comment('struct aref')
- asm.mov(:rax, ctx.stack_pop(1)) # recv
-
- if embedded
- asm.mov(:rax, [:rax, C.RStruct.offsetof(:as, :ary) + (C.VALUE.size * off)])
- else
- asm.mov(:rax, [:rax, C.RStruct.offsetof(:as, :heap, :ptr)])
- asm.mov(:rax, [:rax, C.VALUE.size * off])
- end
-
- ret = ctx.stack_push(Type::Unknown)
- asm.mov(ret, :rax)
-
- jump_to_next_insn(jit, ctx, asm)
- EndBlock
- end
-
- # vm_call_opt_send (lazy part)
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def handle_opt_send_shift_stack(asm, argc, ctx, send_shift:)
- # We don't support `send(:send, ...)` for now.
- assert_equal(1, send_shift)
-
- asm.comment('shift stack')
- (0...argc).reverse_each do |i|
- opnd = ctx.stack_opnd(i)
- opnd2 = ctx.stack_opnd(i + 1)
- asm.mov(:rax, opnd)
- asm.mov(opnd2, :rax)
- end
-
- ctx.shift_stack(argc)
- end
-
- # vm_call_symbol
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_call_symbol(jit, ctx, asm, cme, calling, known_recv_class, flags)
- flags |= C::VM_CALL_OPT_SEND | (calling.kw_splat ? C::VM_CALL_KW_SPLAT : 0)
-
- comptime_symbol = jit.peek_at_stack(calling.argc)
- if comptime_symbol.class != String && !static_symbol?(comptime_symbol)
- asm.incr_counter(:send_optimized_send_not_sym_or_str)
- return CantCompile
- end
-
- mid = C.get_symbol_id(comptime_symbol)
- if mid == 0
- asm.incr_counter(:send_optimized_send_null_mid)
- return CantCompile
- end
-
- asm.comment("Guard #{comptime_symbol.inspect} is on stack")
- class_changed_exit = counted_exit(side_exit(jit, ctx), :send_optimized_send_mid_class_changed)
- jit_guard_known_klass(
- jit, ctx, asm, C.rb_class_of(comptime_symbol), ctx.stack_opnd(calling.argc),
- StackOpnd[calling.argc], comptime_symbol, class_changed_exit,
- )
- asm.mov(C_ARGS[0], ctx.stack_opnd(calling.argc))
- asm.call(C.rb_get_symbol_id)
- asm.cmp(C_RET, mid)
- id_changed_exit = counted_exit(side_exit(jit, ctx), :send_optimized_send_mid_id_changed)
- jit_chain_guard(:jne, jit, ctx, asm, id_changed_exit)
-
- # rb_callable_method_entry_with_refinements
- calling.flags = flags
- cme, _ = jit_search_method(jit, ctx, asm, mid, calling)
- if cme == CantCompile
- return CantCompile
- end
-
- if flags & C::VM_CALL_FCALL != 0
- return jit_call_method(jit, ctx, asm, mid, calling, cme, known_recv_class)
- end
-
- raise NotImplementedError # unreachable for now
- end
-
- # vm_push_frame
- #
- # Frame structure:
- # | args | locals | cme/cref | block_handler/prev EP | frame type (EP here) | stack bottom (SP here)
- #
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, iseq: nil, local_size: 0, stack_max: 0, prev_ep: nil, doing_kw_call: nil)
- # Save caller SP and PC before pushing a callee frame for backtrace and side exits
- asm.comment('save SP to caller CFP')
- recv_idx = argc # blockarg is already popped
- recv_idx += (block_handler == :captured) ? 0 : 1 # receiver is not on stack when captured->self is used
- if iseq
- # Skip setting this to SP register. This cfp->sp will be copied to SP on leave insn.
- asm.lea(:rax, ctx.sp_opnd(C.VALUE.size * -recv_idx)) # Pop receiver and arguments to prepare for side exits
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], :rax)
- else
- asm.lea(SP, ctx.sp_opnd(C.VALUE.size * -recv_idx))
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP)
- ctx.sp_offset = recv_idx
- end
- jit_save_pc(jit, asm, comment: 'save PC to caller CFP')
-
- sp_offset = ctx.sp_offset + 3 + local_size + (doing_kw_call ? 1 : 0) # callee_sp
- local_size.times do |i|
- asm.comment('set local variables') if i == 0
- local_index = sp_offset + i - local_size - 3
- asm.mov([SP, C.VALUE.size * local_index], Qnil)
- end
-
- asm.comment('set up EP with managing data')
- ep_offset = sp_offset - 1
- # ep[-2]: cref_or_me
- asm.mov(:rax, cme.to_i)
- asm.mov([SP, C.VALUE.size * (ep_offset - 2)], :rax)
- # ep[-1]: block handler or prev env ptr (specval)
- if prev_ep
- asm.mov(:rax, prev_ep.to_i | 1) # tagged prev ep
- asm.mov([SP, C.VALUE.size * (ep_offset - 1)], :rax)
- elsif block_handler == :captured
- # Set captured->ep, saving captured in :rcx for captured->self
- ep_reg = :rcx
- jit_get_lep(jit, asm, reg: ep_reg)
- asm.mov(:rcx, [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # block_handler
- asm.and(:rcx, ~0x3) # captured
- asm.mov(:rax, [:rcx, C.VALUE.size]) # captured->ep
- asm.or(:rax, 0x1) # GC_GUARDED_PTR
- asm.mov([SP, C.VALUE.size * (ep_offset - 1)], :rax)
- elsif block_handler == C::VM_BLOCK_HANDLER_NONE
- asm.mov([SP, C.VALUE.size * (ep_offset - 1)], C::VM_BLOCK_HANDLER_NONE)
- elsif block_handler == C.rb_block_param_proxy
- # vm_caller_setup_arg_block: block_code == rb_block_param_proxy
- jit_get_lep(jit, asm, reg: :rax) # VM_CF_BLOCK_HANDLER: VM_CF_LEP
- asm.mov(:rax, [:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # VM_CF_BLOCK_HANDLER: VM_ENV_BLOCK_HANDLER
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:block_code)], :rax) # reg_cfp->block_code = handler
- asm.mov([SP, C.VALUE.size * (ep_offset - 1)], :rax) # return handler;
- else # assume blockiseq
- asm.mov(:rax, block_handler)
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:block_code)], :rax)
- asm.lea(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)]) # VM_CFP_TO_CAPTURED_BLOCK
- asm.or(:rax, 1) # VM_BH_FROM_ISEQ_BLOCK
- asm.mov([SP, C.VALUE.size * (ep_offset - 1)], :rax)
- end
- # ep[-0]: ENV_FLAGS
- asm.mov([SP, C.VALUE.size * (ep_offset - 0)], frame_type)
-
- asm.comment('set up new frame')
- cfp_offset = -C.rb_control_frame_t.size # callee CFP
- # For ISEQ, JIT code will set it as needed. However, C func needs 0 there for svar frame detection.
- if iseq.nil?
- asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:pc)], 0)
- end
- asm.mov(:rax, iseq.to_i)
- asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:iseq)], :rax)
- if block_handler == :captured
- asm.mov(:rax, [:rcx]) # captured->self
- else
- self_index = ctx.sp_offset - (1 + argc) # blockarg has been popped
- asm.mov(:rax, [SP, C.VALUE.size * self_index])
- end
- asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:self)], :rax)
- asm.lea(:rax, [SP, C.VALUE.size * ep_offset])
- asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:ep)], :rax)
- asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:block_code)], 0)
- # Update SP register only for ISEQ calls. SP-relative operations should be done above this.
- sp_reg = iseq ? SP : :rax
- asm.lea(sp_reg, [SP, C.VALUE.size * sp_offset])
- asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:sp)], sp_reg)
-
- # cfp->jit_return is used only for ISEQs
- if iseq
- # The callee might change locals through Kernel#binding and other means.
- ctx.clear_local_types
-
- # Stub cfp->jit_return
- return_ctx = ctx.dup
- return_ctx.stack_pop(argc + ((block_handler == :captured) ? 0 : 1)) # Pop args and receiver. blockarg has been popped
- return_ctx.stack_push(Type::Unknown) # push callee's return value
- return_ctx.sp_offset = 1 # SP is in the position after popping a receiver and arguments
- return_ctx.chain_depth = 0
- branch_stub = BranchStub.new(
- iseq: jit.iseq,
- shape: Default,
- target0: BranchTarget.new(ctx: return_ctx, pc: jit.pc + jit.insn.len * C.VALUE.size),
- )
- branch_stub.target0.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(return_ctx, ocb_asm, branch_stub, true)
- @ocb.write(ocb_asm)
- end
- branch_stub.compile = compile_jit_return(branch_stub, cfp_offset:)
- branch_stub.compile.call(asm)
- end
-
- asm.comment('switch to callee CFP')
- # Update CFP register only for ISEQ calls
- cfp_reg = iseq ? CFP : :rax
- asm.lea(cfp_reg, [CFP, cfp_offset])
- asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], cfp_reg)
- end
-
- def compile_jit_return(branch_stub, cfp_offset:) # Proc escapes arguments in memory
- proc do |branch_asm|
- branch_asm.comment('set jit_return to callee CFP')
- branch_asm.stub(branch_stub) do
- case branch_stub.shape
- in Default
- branch_asm.mov(:rax, branch_stub.target0.address)
- branch_asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:jit_return)], :rax)
- end
- end
- end
- end
-
- # CALLER_SETUP_ARG: Return CantCompile if not supported
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def jit_caller_setup_arg(jit, ctx, asm, flags)
- if flags & C::VM_CALL_ARGS_SPLAT != 0 && flags & C::VM_CALL_KW_SPLAT != 0
- asm.incr_counter(:send_args_splat_kw_splat)
- return CantCompile
- elsif flags & C::VM_CALL_ARGS_SPLAT != 0
- # splat is not supported in this path
- asm.incr_counter(:send_args_splat)
- return CantCompile
- elsif flags & C::VM_CALL_KW_SPLAT != 0
- asm.incr_counter(:send_args_kw_splat)
- return CantCompile
- elsif flags & C::VM_CALL_KWARG != 0
- asm.incr_counter(:send_kwarg)
- return CantCompile
- end
- end
-
- # Pushes arguments from an array to the stack. Differs from push splat because
- # the array can have items left over.
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def move_rest_args_to_stack(array, num_args, jit, ctx, asm)
- side_exit = side_exit(jit, ctx)
-
- asm.comment('move_rest_args_to_stack')
-
- # array is :rax
- array_len_opnd = :rcx
- jit_array_len(asm, array, array_len_opnd)
-
- asm.comment('Side exit if length is less than required')
- asm.cmp(array_len_opnd, num_args)
- asm.jl(counted_exit(side_exit, :send_iseq_has_rest_and_splat_not_equal))
-
- asm.comment('Push arguments from array')
-
- # Load the address of the embedded array
- # (struct RArray *)(obj)->as.ary
- array_reg = array
-
- # Conditionally load the address of the heap array
- # (struct RArray *)(obj)->as.heap.ptr
- flags_opnd = [array_reg, C.RBasic.offsetof(:flags)]
- asm.test(flags_opnd, C::RARRAY_EMBED_FLAG)
- heap_ptr_opnd = [array_reg, C.RArray.offsetof(:as, :heap, :ptr)]
- # Load the address of the embedded array
- # (struct RArray *)(obj)->as.ary
- ary_opnd = :rdx # NOTE: array :rax is used after move_rest_args_to_stack too
- asm.lea(:rcx, [array_reg, C.RArray.offsetof(:as, :ary)])
- asm.mov(ary_opnd, heap_ptr_opnd)
- asm.cmovnz(ary_opnd, :rcx)
-
- num_args.times do |i|
- top = ctx.stack_push(Type::Unknown)
- asm.mov(:rcx, [ary_opnd, i * C.VALUE.size])
- asm.mov(top, :rcx)
- end
- end
-
- # vm_caller_setup_arg_splat (+ CALLER_SETUP_ARG):
- # Pushes arguments from an array to the stack that are passed with a splat (i.e. *args).
- # It optimistically compiles to a static size that is the exact number of arguments needed for the function.
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def push_splat_args(required_args, jit, ctx, asm)
- side_exit = side_exit(jit, ctx)
-
- asm.comment('push_splat_args')
-
- array_opnd = ctx.stack_opnd(0)
- array_stack_opnd = StackOpnd[0]
- array_reg = :rax
- asm.mov(array_reg, array_opnd)
-
- guard_object_is_array(jit, ctx, asm, array_reg, :rcx, array_stack_opnd, :send_args_splat_not_array)
-
- array_len_opnd = :rcx
- jit_array_len(asm, array_reg, array_len_opnd)
-
- asm.comment('Side exit if length is not equal to remaining args')
- asm.cmp(array_len_opnd, required_args)
- asm.jne(counted_exit(side_exit, :send_args_splat_length_not_equal))
-
- asm.comment('Check last argument is not ruby2keyword hash')
-
- ary_opnd = :rcx
- jit_array_ptr(asm, array_reg, ary_opnd) # clobbers array_reg
-
- last_array_value = :rax
- asm.mov(last_array_value, [ary_opnd, (required_args - 1) * C.VALUE.size])
-
- ruby2_exit = counted_exit(side_exit, :send_args_splat_ruby2_hash);
- guard_object_is_not_ruby2_keyword_hash(asm, last_array_value, :rcx, ruby2_exit) # clobbers :rax
-
- asm.comment('Push arguments from array')
- array_opnd = ctx.stack_pop(1)
-
- if required_args > 0
- # Load the address of the embedded array
- # (struct RArray *)(obj)->as.ary
- array_reg = :rax
- asm.mov(array_reg, array_opnd)
-
- # Conditionally load the address of the heap array
- # (struct RArray *)(obj)->as.heap.ptr
- flags_opnd = [array_reg, C.RBasic.offsetof(:flags)]
- asm.test(flags_opnd, C::RARRAY_EMBED_FLAG)
- heap_ptr_opnd = [array_reg, C.RArray.offsetof(:as, :heap, :ptr)]
- # Load the address of the embedded array
- # (struct RArray *)(obj)->as.ary
- asm.lea(:rcx, [array_reg, C.RArray.offsetof(:as, :ary)])
- asm.mov(:rax, heap_ptr_opnd)
- asm.cmovnz(:rax, :rcx)
- ary_opnd = :rax
-
- (0...required_args).each do |i|
- top = ctx.stack_push(Type::Unknown)
- asm.mov(:rcx, [ary_opnd, i * C.VALUE.size])
- asm.mov(top, :rcx)
- end
-
- asm.comment('end push_each')
- end
- end
-
- # Generate RARRAY_LEN. For array_opnd, use Opnd::Reg to reduce memory access,
- # and use Opnd::Mem to save registers.
- def jit_array_len(asm, array_reg, len_reg)
- asm.comment('get array length for embedded or heap')
-
- # Pull out the embed flag to check if it's an embedded array.
- asm.mov(len_reg, [array_reg, C.RBasic.offsetof(:flags)])
-
- # Get the length of the array
- asm.and(len_reg, C::RARRAY_EMBED_LEN_MASK)
- asm.sar(len_reg, C::RARRAY_EMBED_LEN_SHIFT)
-
- # Conditionally move the length of the heap array
- asm.test([array_reg, C.RBasic.offsetof(:flags)], C::RARRAY_EMBED_FLAG)
-
- # Select the array length value
- asm.cmovz(len_reg, [array_reg, C.RArray.offsetof(:as, :heap, :len)])
- end
-
- # Generate RARRAY_CONST_PTR (part of RARRAY_AREF)
- def jit_array_ptr(asm, array_reg, ary_opnd) # clobbers array_reg
- asm.comment('get array pointer for embedded or heap')
-
- flags_opnd = [array_reg, C.RBasic.offsetof(:flags)]
- asm.test(flags_opnd, C::RARRAY_EMBED_FLAG)
- # Load the address of the embedded array
- # (struct RArray *)(obj)->as.ary
- asm.mov(ary_opnd, [array_reg, C.RArray.offsetof(:as, :heap, :ptr)])
- asm.lea(array_reg, [array_reg, C.RArray.offsetof(:as, :ary)]) # clobbers array_reg
- asm.cmovnz(ary_opnd, array_reg)
- end
-
- def assert(cond)
- assert_equal(cond, true)
- end
-
- def assert_equal(left, right)
- if left != right
- raise "'#{left.inspect}' was not '#{right.inspect}'"
- end
- end
-
- def fixnum?(obj)
- (C.to_value(obj) & C::RUBY_FIXNUM_FLAG) == C::RUBY_FIXNUM_FLAG
- end
-
- def flonum?(obj)
- (C.to_value(obj) & C::RUBY_FLONUM_MASK) == C::RUBY_FLONUM_FLAG
- end
-
- def symbol?(obj)
- static_symbol?(obj) || dynamic_symbol?(obj)
- end
-
- def static_symbol?(obj)
- (C.to_value(obj) & 0xff) == C::RUBY_SYMBOL_FLAG
- end
-
- def dynamic_symbol?(obj)
- return false if C::SPECIAL_CONST_P(obj)
- C.RB_TYPE_P(obj, C::RUBY_T_SYMBOL)
- end
-
- def shape_too_complex?(obj)
- C.rb_shape_get_shape_id(obj) == C::OBJ_TOO_COMPLEX_SHAPE_ID
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- # @param asm [RubyVM::RJIT::Assembler]
- def defer_compilation(jit, ctx, asm)
- # Make a stub to compile the current insn
- if ctx.chain_depth != 0
- raise "double defer!"
- end
- ctx.chain_depth += 1
- jit_direct_jump(jit.iseq, jit.pc, ctx, asm, comment: 'defer_compilation')
- end
-
- def jit_direct_jump(iseq, pc, ctx, asm, comment: 'jit_direct_jump')
- branch_stub = BranchStub.new(
- iseq:,
- shape: Default,
- target0: BranchTarget.new(ctx:, pc:),
- )
- branch_stub.target0.address = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, true)
- @ocb.write(ocb_asm)
- end
- branch_stub.compile = compile_jit_direct_jump(branch_stub, comment:)
- branch_stub.compile.call(asm)
- end
-
- def compile_jit_direct_jump(branch_stub, comment:) # Proc escapes arguments in memory
- proc do |branch_asm|
- branch_asm.comment(comment)
- branch_asm.stub(branch_stub) do
- case branch_stub.shape
- in Default
- branch_asm.jmp(branch_stub.target0.address)
- in Next0
- # Just write the block without a jump
- end
- end
- end
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param ctx [RubyVM::RJIT::Context]
- def side_exit(jit, ctx)
- # We use the latest ctx.sp_offset to generate a side exit to tolerate sp_offset changes by jit_save_sp.
- # However, we want to simulate an old stack_size when we take a side exit. We do that by adjusting the
- # sp_offset because gen_outlined_exit uses ctx.sp_offset to move SP.
- ctx = ctx.with_stack_size(jit.stack_size_for_pc)
-
- jit.side_exit_for_pc[ctx.sp_offset] ||= Assembler.new.then do |asm|
- @exit_compiler.compile_side_exit(jit.pc, ctx, asm)
- @ocb.write(asm)
- end
- end
-
- def counted_exit(side_exit, name)
- asm = Assembler.new
- asm.incr_counter(name)
- asm.jmp(side_exit)
- @ocb.write(asm)
- end
-
- def def_iseq_ptr(cme_def)
- C.rb_iseq_check(cme_def.body.iseq.iseqptr)
- end
-
- def to_value(obj)
- GC_REFS << obj
- C.to_value(obj)
- end
-
- def full_cfunc_return
- @full_cfunc_return ||= Assembler.new.then do |asm|
- @exit_compiler.compile_full_cfunc_return(asm)
- @ocb.write(asm)
- end
- end
-
- def c_method_tracing_currently_enabled?
- C.rb_rjit_global_events & (C::RUBY_EVENT_C_CALL | C::RUBY_EVENT_C_RETURN) != 0
- end
-
- # Return a builtin function if a given iseq consists of only that builtin function
- def builtin_function(iseq)
- opt_invokebuiltin_delegate_leave = INSNS.values.find { |i| i.name == :opt_invokebuiltin_delegate_leave }
- leave = INSNS.values.find { |i| i.name == :leave }
- if iseq.body.iseq_size == opt_invokebuiltin_delegate_leave.len + leave.len &&
- C.rb_vm_insn_decode(iseq.body.iseq_encoded[0]) == opt_invokebuiltin_delegate_leave.bin &&
- C.rb_vm_insn_decode(iseq.body.iseq_encoded[opt_invokebuiltin_delegate_leave.len]) == leave.bin
- C.rb_builtin_function.new(iseq.body.iseq_encoded[1])
- end
- end
-
- def build_calling(ci:, block_handler:)
- CallingInfo.new(
- argc: C.vm_ci_argc(ci),
- flags: C.vm_ci_flag(ci),
- kwarg: C.vm_ci_kwarg(ci),
- ci_addr: ci.to_i,
- send_shift: 0,
- block_handler:,
- )
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/invariants.rb b/lib/ruby_vm/rjit/invariants.rb
deleted file mode 100644
index 5b061d1994..0000000000
--- a/lib/ruby_vm/rjit/invariants.rb
+++ /dev/null
@@ -1,155 +0,0 @@
-require 'set'
-
-module RubyVM::RJIT
- class Invariants
- class << self
- # Called by RubyVM::RJIT::Compiler to lazily initialize this
- # @param cb [CodeBlock]
- # @param ocb [CodeBlock]
- # @param compiler [RubyVM::RJIT::Compiler]
- # @param exit_compiler [RubyVM::RJIT::ExitCompiler]
- def initialize(cb, ocb, compiler, exit_compiler)
- @cb = cb
- @ocb = ocb
- @compiler = compiler
- @exit_compiler = exit_compiler
- @bop_blocks = Set.new # TODO: actually invalidate this
- @cme_blocks = Hash.new { |h, k| h[k] = Set.new }
- @const_blocks = Hash.new { |h, k| h[k] = Set.new }
- @patches = {}
-
- # freeze # workaround a binding.irb issue. TODO: resurrect this
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param klass [Integer]
- # @param op [Integer]
- def assume_bop_not_redefined(jit, klass, op)
- return false unless C.BASIC_OP_UNREDEFINED_P(klass, op)
-
- ensure_block_entry_exit(jit, cause: 'assume_bop_not_redefined')
- @bop_blocks << jit.block
- true
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- def assume_method_lookup_stable(jit, cme)
- ensure_block_entry_exit(jit, cause: 'assume_method_lookup_stable')
- @cme_blocks[cme.to_i] << jit.block
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- def assume_method_basic_definition(jit, klass, mid)
- if C.rb_method_basic_definition_p(klass, mid)
- cme = C.rb_callable_method_entry(klass, mid)
- assume_method_lookup_stable(jit, cme)
- true
- else
- false
- end
- end
-
- def assume_stable_constant_names(jit, idlist)
- (0..).each do |i|
- break if (id = idlist[i]) == 0
- @const_blocks[id] << jit.block
- end
- end
-
- # @param asm [RubyVM::RJIT::Assembler]
- def record_global_inval_patch(asm, target)
- asm.pos_marker do |address|
- if @patches.key?(address)
- raise 'multiple patches in the same address'
- end
- @patches[address] = target
- end
- end
-
- def on_cme_invalidate(cme)
- @cme_blocks.fetch(cme.to_i, []).each do |block|
- @cb.with_write_addr(block.start_addr) do
- asm = Assembler.new
- asm.comment('on_cme_invalidate')
- asm.jmp(block.entry_exit)
- @cb.write(asm)
- end
- # TODO: re-generate branches that refer to this block
- end
- @cme_blocks.delete(cme.to_i)
- end
-
- def on_constant_ic_update(iseq, ic, insn_idx)
- # TODO: check multi ractor as well
- if ic.entry.ic_cref
- # No need to recompile the slowpath
- return
- end
-
- pc = iseq.body.iseq_encoded + insn_idx
- insn_name = Compiler.decode_insn(pc.*).name
- if insn_name != :opt_getconstant_path && insn_name != :trace_opt_getconstant_path
- raise 'insn_idx was not at opt_getconstant_path'
- end
- if ic.to_i != pc[1]
- raise 'insn_idx + 1 was not at the updated IC'
- end
- @compiler.invalidate_blocks(iseq, pc.to_i)
- end
-
- def on_constant_state_changed(id)
- @const_blocks.fetch(id, []).each do |block|
- @compiler.invalidate_block(block)
- end
- end
-
- def on_tracing_invalidate_all
- invalidate_all
- end
-
- def on_update_references
- # Give up. In order to support GC.compact, you'd have to update ISEQ
- # addresses in BranchStub, etc. Ideally, we'd need to update moved
- # pointers in JITed code here, but we just invalidate all for now.
- invalidate_all
- end
-
- # @param jit [RubyVM::RJIT::JITState]
- # @param block [RubyVM::RJIT::Block]
- def ensure_block_entry_exit(jit, cause:)
- block = jit.block
- if block.entry_exit.nil?
- block.entry_exit = Assembler.new.then do |asm|
- @exit_compiler.compile_entry_exit(block.pc, block.ctx, asm, cause:)
- @ocb.write(asm)
- end
- end
- end
-
- private
-
- def invalidate_all
- # On-Stack Replacement
- @patches.each do |address, target|
- # TODO: assert patches don't overlap each other
- @cb.with_write_addr(address) do
- asm = Assembler.new
- asm.comment('on_tracing_invalidate_all')
- asm.jmp(target)
- @cb.write(asm)
- end
- end
- @patches.clear
-
- C.rjit_for_each_iseq do |iseq|
- # Avoid entering past code
- iseq.body.jit_entry = 0
- # Avoid reusing past code
- iseq.body.rjit_blocks.clear if iseq.body.rjit_blocks
- # Compile this again if not converted to trace_* insns
- iseq.body.jit_entry_calls = 0
- end
- end
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/jit_state.rb b/lib/ruby_vm/rjit/jit_state.rb
deleted file mode 100644
index 02a713474e..0000000000
--- a/lib/ruby_vm/rjit/jit_state.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-module RubyVM::RJIT
- class JITState < Struct.new(
- :iseq, # @param `RubyVM::RJIT::CPointer::Struct_rb_iseq_t`
- :pc, # @param [Integer] The JIT target PC
- :cfp, # @param `RubyVM::RJIT::CPointer::Struct_rb_control_frame_t` The JIT source CFP (before RJIT is called)
- :block, # @param [RubyVM::RJIT::Block]
- :stack_size_for_pc, # @param [Integer]
- :side_exit_for_pc, # @param [Hash{ Integer => Integer }] { sp_offset => address }
- :record_boundary_patch_point, # @param [TrueClass,FalseClass]
- )
- def initialize(side_exit_for_pc: {}, record_boundary_patch_point: false, **) = super
-
- def insn
- Compiler.decode_insn(C.VALUE.new(pc).*)
- end
-
- def operand(index, signed: false, ruby: false)
- addr = pc + (index + 1) * Fiddle::SIZEOF_VOIDP
- value = Fiddle::Pointer.new(addr)[0, Fiddle::SIZEOF_VOIDP].unpack(signed ? 'q' : 'Q')[0]
- if ruby
- value = C.to_ruby(value)
- end
- value
- end
-
- def at_current_insn?
- pc == cfp.pc.to_i
- end
-
- def peek_at_local(n)
- local_table_size = iseq.body.local_table_size
- offset = -C::VM_ENV_DATA_SIZE - local_table_size + n + 1
- value = (cfp.ep + offset).*
- C.to_ruby(value)
- end
-
- def peek_at_stack(depth_from_top)
- raise 'not at current insn' unless at_current_insn?
- offset = -(1 + depth_from_top)
- # rb_rjit_branch_stub_hit updates SP, so you don't need to worry about sp_offset
- value = (cfp.sp + offset).*
- C.to_ruby(value)
- end
-
- def peek_at_self
- C.to_ruby(cfp.self)
- end
-
- def peek_at_block_handler(level)
- ep = ep_at_level(cfp, level:)
- ep[C::VM_ENV_DATA_INDEX_SPECVAL]
- end
-
- private
-
- def ep_at_level(cfp, level:)
- ep = cfp.ep
- level.times do
- # VM_ENV_PREV_EP
- ep = C.VALUE.new(ep[C::VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)
- end
- ep
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/stats.rb b/lib/ruby_vm/rjit/stats.rb
deleted file mode 100644
index 7e353c698e..0000000000
--- a/lib/ruby_vm/rjit/stats.rb
+++ /dev/null
@@ -1,191 +0,0 @@
-# frozen_string_literal: true
-module RubyVM::RJIT
- # Return a Hash for \RJIT statistics. \--rjit-stats makes more information available.
- def self.runtime_stats
- stats = {}
-
- # Insn exits
- INSNS.each_value do |insn|
- exits = C.rjit_insn_exits[insn.bin]
- if exits > 0
- stats[:"exit_#{insn.name}"] = exits
- end
- end
-
- # Runtime stats
- C.rb_rjit_runtime_counters.members.each do |member|
- stats[member] = C.rb_rjit_counters.public_send(member)
- end
- stats[:vm_insns_count] = C.rb_vm_insns_count
-
- # Other stats are calculated here
- stats[:side_exit_count] = stats.select { |name, _count| name.start_with?('exit_') }.sum(&:last)
- if stats[:vm_insns_count] > 0
- retired_in_rjit = stats[:rjit_insns_count] - stats[:side_exit_count]
- stats[:total_insns_count] = retired_in_rjit + stats[:vm_insns_count]
- stats[:ratio_in_rjit] = 100.0 * retired_in_rjit / stats[:total_insns_count]
- else
- stats.delete(:vm_insns_count)
- end
-
- stats
- end
-
- # :nodoc: all
- class << self
- private
-
- # --yjit-stats at_exit
- def print_stats
- stats = runtime_stats
- $stderr.puts("***RJIT: Printing RJIT statistics on exit***")
-
- print_counters(stats, prefix: 'send_', prompt: 'method call exit reasons')
- print_counters(stats, prefix: 'invokeblock_', prompt: 'invokeblock exit reasons')
- print_counters(stats, prefix: 'invokesuper_', prompt: 'invokesuper exit reasons')
- print_counters(stats, prefix: 'getblockpp_', prompt: 'getblockparamproxy exit reasons')
- print_counters(stats, prefix: 'getivar_', prompt: 'getinstancevariable exit reasons')
- print_counters(stats, prefix: 'setivar_', prompt: 'setinstancevariable exit reasons')
- print_counters(stats, prefix: 'optaref_', prompt: 'opt_aref exit reasons')
- print_counters(stats, prefix: 'optgetconst_', prompt: 'opt_getconstant_path exit reasons')
- print_counters(stats, prefix: 'expandarray_', prompt: 'expandarray exit reasons')
-
- $stderr.puts "compiled_block_count: #{format_number(13, stats[:compiled_block_count])}"
- $stderr.puts "side_exit_count: #{format_number(13, stats[:side_exit_count])}"
- $stderr.puts "total_insns_count: #{format_number(13, stats[:total_insns_count])}" if stats.key?(:total_insns_count)
- $stderr.puts "vm_insns_count: #{format_number(13, stats[:vm_insns_count])}" if stats.key?(:vm_insns_count)
- $stderr.puts "rjit_insns_count: #{format_number(13, stats[:rjit_insns_count])}"
- $stderr.puts "ratio_in_rjit: #{format('%12.1f', stats[:ratio_in_rjit])}%" if stats.key?(:ratio_in_rjit)
-
- print_exit_counts(stats)
- end
-
- def print_counters(stats, prefix:, prompt:)
- $stderr.puts("#{prompt}: ")
- counters = stats.filter { |key, _| key.start_with?(prefix) }
- counters.filter! { |_, value| value != 0 }
- counters.transform_keys! { |key| key.to_s.delete_prefix(prefix) }
-
- if counters.empty?
- $stderr.puts(" (all relevant counters are zero)")
- return
- end
-
- counters = counters.to_a
- counters.sort_by! { |(_, counter_value)| counter_value }
- longest_name_length = counters.max_by { |(name, _)| name.length }.first.length
- total = counters.sum { |(_, counter_value)| counter_value }
-
- counters.reverse_each do |(name, value)|
- percentage = value.fdiv(total) * 100
- $stderr.printf(" %*s %s (%4.1f%%)\n", longest_name_length, name, format_number(10, value), percentage)
- end
- end
-
- def print_exit_counts(stats, how_many: 20, padding: 2)
- exits = stats.filter_map { |name, count| [name.to_s.delete_prefix('exit_'), count] if name.start_with?('exit_') }.to_h
- return if exits.empty?
-
- top_exits = exits.sort_by { |_name, count| -count }.first(how_many).to_h
- total_exits = exits.values.sum
- $stderr.puts "Top-#{top_exits.size} most frequent exit ops (#{format("%.1f", 100.0 * top_exits.values.sum / total_exits)}% of exits):"
-
- name_width = top_exits.map { |name, _count| name.length }.max + padding
- count_width = top_exits.map { |_name, count| format_number(10, count).length }.max + padding
- top_exits.each do |name, count|
- ratio = 100.0 * count / total_exits
- $stderr.puts "#{format("%#{name_width}s", name)}: #{format_number(count_width, count)} (#{format('%4.1f', ratio)}%)"
- end
- end
-
- # Format large numbers with comma separators for readability
- def format_number(pad, number)
- integer, decimal = number.to_s.split('.')
- d_groups = integer.chars.reverse.each_slice(3)
- with_commas = d_groups.map(&:join).join(',').reverse
- [with_commas, decimal].compact.join('.').rjust(pad, ' ')
- end
-
- # --yjit-trace-exits at_exit
- def dump_trace_exits
- filename = "#{Dir.pwd}/rjit_exit_locations.dump"
- File.binwrite(filename, Marshal.dump(exit_traces))
- $stderr.puts("RJIT exit locations dumped to:\n#{filename}")
- end
-
- # Convert rb_rjit_raw_samples and rb_rjit_line_samples into a StackProf format.
- def exit_traces
- results = C.rjit_exit_traces
- raw_samples = results[:raw].dup
- line_samples = results[:lines].dup
- frames = results[:frames].dup
- samples_count = 0
-
- # Loop through the instructions and set the frame hash with the data.
- # We use nonexistent.def for the file name, otherwise insns.def will be displayed
- # and that information isn't useful in this context.
- RubyVM::INSTRUCTION_NAMES.each_with_index do |name, frame_id|
- frame_hash = { samples: 0, total_samples: 0, edges: {}, name: name, file: "nonexistent.def", line: nil, lines: {} }
- results[:frames][frame_id] = frame_hash
- frames[frame_id] = frame_hash
- end
-
- # Loop through the raw_samples and build the hashes for StackProf.
- # The loop is based off an example in the StackProf documentation and therefore
- # this functionality can only work with that library.
- #
- # Raw Samples:
- # [ length, frame1, frame2, frameN, ..., instruction, count
- #
- # Line Samples
- # [ length, line_1, line_2, line_n, ..., dummy value, count
- i = 0
- while i < raw_samples.length
- stack_length = raw_samples[i] + 1
- i += 1 # consume the stack length
-
- prev_frame_id = nil
- stack_length.times do |idx|
- idx += i
- frame_id = raw_samples[idx]
-
- if prev_frame_id
- prev_frame = frames[prev_frame_id]
- prev_frame[:edges][frame_id] ||= 0
- prev_frame[:edges][frame_id] += 1
- end
-
- frame_info = frames[frame_id]
- frame_info[:total_samples] += 1
-
- frame_info[:lines][line_samples[idx]] ||= [0, 0]
- frame_info[:lines][line_samples[idx]][0] += 1
-
- prev_frame_id = frame_id
- end
-
- i += stack_length # consume the stack
-
- top_frame_id = prev_frame_id
- top_frame_line = 1
-
- sample_count = raw_samples[i]
-
- frames[top_frame_id][:samples] += sample_count
- frames[top_frame_id][:lines] ||= {}
- frames[top_frame_id][:lines][top_frame_line] ||= [0, 0]
- frames[top_frame_id][:lines][top_frame_line][1] += sample_count
-
- samples_count += sample_count
- i += 1
- end
-
- results[:samples] = samples_count
- # Set missed_samples and gc_samples to 0 as their values
- # don't matter to us in this context.
- results[:missed_samples] = 0
- results[:gc_samples] = 0
- results
- end
- end
-end
diff --git a/lib/ruby_vm/rjit/type.rb b/lib/ruby_vm/rjit/type.rb
deleted file mode 100644
index 119692014b..0000000000
--- a/lib/ruby_vm/rjit/type.rb
+++ /dev/null
@@ -1,221 +0,0 @@
-module RubyVM::RJIT
- # Represent the type of a value (local/stack/self) in RJIT
- Type = Data.define(:type) do
- # Check if the type is an immediate
- def imm?
- case self
- in Type::UnknownImm then true
- in Type::Nil then true
- in Type::True then true
- in Type::False then true
- in Type::Fixnum then true
- in Type::Flonum then true
- in Type::ImmSymbol then true
- else false
- end
- end
-
- # Returns true when the type is not specific.
- def unknown?
- case self
- in Type::Unknown | Type::UnknownImm | Type::UnknownHeap then true
- else false
- end
- end
-
- # Returns true when we know the VALUE is a specific handle type,
- # such as a static symbol ([Type::ImmSymbol], i.e. true from RB_STATIC_SYM_P()).
- # Opposite of [Self::is_unknown].
- def specific?
- !self.unknown?
- end
-
- # Check if the type is a heap object
- def heap?
- case self
- in Type::UnknownHeap then true
- in Type::TArray then true
- in Type::Hash then true
- in Type::HeapSymbol then true
- in Type::TString then true
- in Type::CString then true
- in Type::BlockParamProxy then true
- else false
- end
- end
-
- # Check if it's a T_ARRAY object
- def array?
- case self
- in Type::TArray then true
- else false
- end
- end
-
- # Check if it's a T_STRING object (both TString and CString are T_STRING)
- def string?
- case self
- in Type::TString then true
- in Type::CString then true
- else false
- end
- end
-
- # Returns the class if it is known, otherwise nil
- def known_class
- case self
- in Type::Nil then C.rb_cNilClass
- in Type::True then C.rb_cTrueClass
- in Type::False then C.rb_cFalseClass
- in Type::Fixnum then C.rb_cInteger
- in Type::Flonum then C.rb_cFloat
- in Type::ImmSymbol | Type::HeapSymbol then C.rb_cSymbol
- in Type::CString then C.rb_cString
- else nil
- end
- end
-
- # Returns a boolean representing whether the value is truthy if known, otherwise nil
- def known_truthy
- case self
- in Type::Nil then false
- in Type::False then false
- in Type::UnknownHeap then false
- in Type::Unknown | Type::UnknownImm then nil
- else true
- end
- end
-
- # Returns a boolean representing whether the value is equal to nil if known, otherwise nil
- def known_nil
- case [self, self.known_truthy]
- in Type::Nil, _ then true
- in Type::False, _ then false # Qfalse is not nil
- in _, true then false # if truthy, can't be nil
- in _, _ then nil # otherwise unknown
- end
- end
-
- def diff(dst)
- # Perfect match, difference is zero
- if self == dst
- return TypeDiff::Compatible[0]
- end
-
- # Any type can flow into an unknown type
- if dst == Type::Unknown
- return TypeDiff::Compatible[1]
- end
-
- # A CString is also a TString.
- if self == Type::CString && dst == Type::TString
- return TypeDiff::Compatible[1]
- end
-
- # Specific heap type into unknown heap type is imperfect but valid
- if self.heap? && dst == Type::UnknownHeap
- return TypeDiff::Compatible[1]
- end
-
- # Specific immediate type into unknown immediate type is imperfect but valid
- if self.imm? && dst == Type::UnknownImm
- return TypeDiff::Compatible[1]
- end
-
- # Incompatible types
- return TypeDiff::Incompatible
- end
-
- def upgrade(new_type)
- assert(new_type.diff(self) != TypeDiff::Incompatible)
- new_type
- end
-
- private
-
- def assert(cond)
- unless cond
- raise "'#{cond.inspect}' was not true"
- end
- end
- end
-
- # This returns an appropriate Type based on a known value
- class << Type
- def from(val)
- if C::SPECIAL_CONST_P(val)
- if fixnum?(val)
- Type::Fixnum
- elsif val.nil?
- Type::Nil
- elsif val == true
- Type::True
- elsif val == false
- Type::False
- elsif static_symbol?(val)
- Type::ImmSymbol
- elsif flonum?(val)
- Type::Flonum
- else
- raise "Illegal value: #{val.inspect}"
- end
- else
- val_class = C.to_value(C.rb_class_of(val))
- if val_class == C.rb_cString && C.rb_obj_frozen_p(val)
- return Type::CString
- end
- if C.to_value(val) == C.rb_block_param_proxy
- return Type::BlockParamProxy
- end
- case C::BUILTIN_TYPE(val)
- in C::RUBY_T_ARRAY
- Type::TArray
- in C::RUBY_T_HASH
- Type::Hash
- in C::RUBY_T_STRING
- Type::TString
- else
- Type::UnknownHeap
- end
- end
- end
-
- private
-
- def fixnum?(obj)
- (C.to_value(obj) & C::RUBY_FIXNUM_FLAG) == C::RUBY_FIXNUM_FLAG
- end
-
- def flonum?(obj)
- (C.to_value(obj) & C::RUBY_FLONUM_MASK) == C::RUBY_FLONUM_FLAG
- end
-
- def static_symbol?(obj)
- (C.to_value(obj) & 0xff) == C::RUBY_SYMBOL_FLAG
- end
- end
-
- # List of types
- Type::Unknown = Type[:Unknown]
- Type::UnknownImm = Type[:UnknownImm]
- Type::UnknownHeap = Type[:UnknownHeap]
- Type::Nil = Type[:Nil]
- Type::True = Type[:True]
- Type::False = Type[:False]
- Type::Fixnum = Type[:Fixnum]
- Type::Flonum = Type[:Flonum]
- Type::Hash = Type[:Hash]
- Type::ImmSymbol = Type[:ImmSymbol]
- Type::HeapSymbol = Type[:HeapSymbol]
-
- Type::TString = Type[:TString] # An object with the T_STRING flag set, possibly an rb_cString
- Type::CString = Type[:CString] # An un-subclassed string of type rb_cString (can have instance vars in some cases)
- Type::TArray = Type[:TArray] # An object with the T_ARRAY flag set, possibly an rb_cArray
-
- Type::BlockParamProxy = Type[:BlockParamProxy] # A special sentinel value indicating the block parameter should be read from
-
- module TypeDiff
- Compatible = Data.define(:diversion) # The smaller, the more compatible.
- Incompatible = :Incompatible
- end
-end
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 2c8515b255..af86646a82 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -9,7 +9,7 @@
require "rbconfig"
module Gem
- VERSION = "3.5.11"
+ VERSION = "3.4.19"
end
# Must be first since it unloads the prelude from 1.9.2
@@ -115,6 +115,11 @@ require_relative "rubygems/errors"
module Gem
RUBYGEMS_DIR = __dir__
+ # Taint support is deprecated in Ruby 2.7.
+ # This allows switching ".untaint" to ".tap(&Gem::UNTAINT)",
+ # to avoid deprecation warnings in Ruby 2.7.
+ UNTAINT = RUBY_VERSION < "2.7" ? :untaint.to_sym : proc {}
+
##
# An Array of Regexps that match windows Ruby platforms.
@@ -206,7 +211,7 @@ module Gem
end
end
- true
+ return true
end
def self.needs
@@ -334,6 +339,16 @@ module Gem
end
##
+ # The path to the data directory specified by the gem name. If the
+ # package is not available as a gem, return nil.
+
+ def self.datadir(gem_name)
+ spec = @loaded_specs[gem_name]
+ return nil if spec.nil?
+ spec.datadir
+ end
+
+ ##
# A Zlib::Deflate.deflate wrapper
def self.deflate(data)
@@ -424,7 +439,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
def self.ensure_subdirectories(dir, mode, subdirs) # :nodoc:
old_umask = File.umask
- File.umask old_umask | 0o002
+ File.umask old_umask | 002
options = {}
@@ -450,7 +465,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# distinction as extensions cannot be shared between the two.
def self.extension_api_version # :nodoc:
- if RbConfig::CONFIG["ENABLE_SHARED"] == "no"
+ if "no" == RbConfig::CONFIG["ENABLE_SHARED"]
"#{ruby_api_version}-static"
else
ruby_api_version
@@ -484,14 +499,14 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# the spec dirs directly, so we prune.
files.uniq! if check_load_path
- files
+ return files
end
def self.find_files_from_load_path(glob) # :nodoc:
glob_with_suffixes = "#{glob}#{Gem.suffix_pattern}"
$LOAD_PATH.map do |load_path|
Gem::Util.glob_files_in_dir(glob_with_suffixes, load_path)
- end.flatten.select {|file| File.file? file }
+ end.flatten.select {|file| File.file? file.tap(&Gem::UNTAINT) }
end
##
@@ -519,7 +534,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# the spec dirs directly, so we prune.
files.uniq! if check_load_path
- files
+ return files
end
##
@@ -567,7 +582,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# The number of paths in the +$LOAD_PATH+ from activated gems. Used to
- # prioritize +-I+ and <code>ENV['RUBYLIB']</code> entries during +require+.
+ # prioritize +-I+ and +ENV['RUBYLIB']+ entries during +require+.
def self.activated_gem_paths
@activated_gem_paths ||= 0
@@ -599,16 +614,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
@yaml_loaded = true
end
- @safe_marshal_loaded = false
-
- def self.load_safe_marshal
- return if @safe_marshal_loaded
-
- require_relative "rubygems/safe_marshal"
-
- @safe_marshal_loaded = true
- end
-
##
# The file name and line number of the caller of the caller of this method.
#
@@ -737,7 +742,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
if prefix != File.expand_path(RbConfig::CONFIG["sitelibdir"]) &&
prefix != File.expand_path(RbConfig::CONFIG["libdir"]) &&
- File.basename(RUBYGEMS_DIR) == "lib"
+ "lib" == File.basename(RUBYGEMS_DIR)
prefix
end
end
@@ -753,9 +758,13 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Safely read a file in binary mode on all platforms.
def self.read_binary(path)
- open_file(path, "rb+", &:read)
+ open_file(path, "rb+") do |io|
+ io.read
+ end
rescue Errno::EACCES, Errno::EROFS
- open_file(path, "rb", &:read)
+ open_file(path, "rb") do |io|
+ io.read
+ end
end
##
@@ -800,7 +809,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
if @ruby.nil?
@ruby = RbConfig.ruby
- @ruby = "\"#{@ruby}\"" if /\s/.match?(@ruby)
+ @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
end
@ruby
@@ -857,7 +866,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
return @ruby_version if defined? @ruby_version
version = RUBY_VERSION.dup
- if RUBY_PATCHLEVEL == -1
+ unless defined?(RUBY_PATCHLEVEL) && RUBY_PATCHLEVEL != -1
if RUBY_ENGINE == "ruby"
desc = RUBY_DESCRIPTION[/\Aruby #{Regexp.quote(RUBY_VERSION)}([^ ]+) /, 1]
else
@@ -905,7 +914,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Glob pattern for require-able path suffixes.
def self.suffix_pattern
- @suffix_pattern ||= "{#{suffixes.join(",")}}"
+ @suffix_pattern ||= "{#{suffixes.join(',')}}"
end
##
@@ -939,14 +948,8 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
val = RbConfig::CONFIG[key]
next unless val && !val.empty?
".#{val}"
- end].compact.uniq
- end
-
- ##
- # Suffixes for dynamic library require-able paths.
-
- def self.dynamic_library_suffixes
- @dynamic_library_suffixes ||= suffixes - [".rb"]
+ end,
+ ].compact.uniq
end
##
@@ -960,7 +963,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
elapsed = Time.now - now
- ui.say format("%2$*1$s: %3$3.3fs", -width, msg, elapsed) if display
+ ui.say "%2$*1$s: %3$3.3fs" % [-width, msg, elapsed] if display
value
end
@@ -992,7 +995,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
def self.win_platform?
if @@win_platform.nil?
ruby_platform = RbConfig::CONFIG["host_os"]
- @@win_platform = !WIN_PATTERNS.find {|r| ruby_platform =~ r }.nil?
+ @@win_platform = !!WIN_PATTERNS.find {|r| ruby_platform =~ r }
end
@@win_platform
@@ -1013,13 +1016,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
- # Is this platform FreeBSD
-
- def self.freebsd_platform?
- RbConfig::CONFIG["host_os"].to_s.include?("bsd")
- end
-
- ##
# Load +plugins+ as Ruby files
def self.load_plugin_files(plugins) # :nodoc:
@@ -1027,11 +1023,11 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Skip older versions of the GemCutter plugin: Its commands are in
# RubyGems proper now.
- next if /gemcutter-0\.[0-3]/.match?(plugin)
+ next if plugin =~ /gemcutter-0\.[0-3]/
begin
load plugin
- rescue ScriptError, StandardError => e
+ rescue ::Exception => e
details = "#{plugin.inspect}: #{e.message} (#{e.class})"
warn "Error loading RubyGems plugin #{details}"
end
@@ -1093,6 +1089,8 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
end
+ path.tap(&Gem::UNTAINT)
+
unless File.file? path
return unless raise_exception
@@ -1104,11 +1102,13 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
require "bundler"
begin
Gem::DefaultUserInteraction.use_ui(ui) do
- Bundler.ui.silence do
- @gemdeps = Bundler.setup
+ begin
+ Bundler.ui.silence do
+ @gemdeps = Bundler.setup
+ end
+ ensure
+ Gem::DefaultUserInteraction.ui.close
end
- ensure
- Gem::DefaultUserInteraction.ui.close
end
rescue Bundler::BundlerError => e
warn e.message
@@ -1154,7 +1154,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# This is used throughout RubyGems for enabling reproducible builds.
def self.source_date_epoch
- Time.at(source_date_epoch_string.to_i).utc.freeze
+ Time.at(self.source_date_epoch_string.to_i).utc.freeze
end
# FIX: Almost everywhere else we use the `def self.` way of defining class
@@ -1223,16 +1223,9 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# Find a Gem::Specification of default gem from +path+
- def find_default_spec(path)
- @path_to_default_spec_map[path]
- end
-
- ##
- # Find an unresolved Gem::Specification of default gem from +path+
-
def find_unresolved_default_spec(path)
default_spec = @path_to_default_spec_map[path]
- default_spec if default_spec && loaded_specs[default_spec.name] != default_spec
+ return default_spec if default_spec && loaded_specs[default_spec.name] != default_spec
end
##
@@ -1308,10 +1301,9 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# Location of Marshal quick gemspecs on remote repositories
- MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze
+ MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
autoload :ConfigFile, File.expand_path("rubygems/config_file", __dir__)
- autoload :CIDetector, File.expand_path("rubygems/ci_detector", __dir__)
autoload :Dependency, File.expand_path("rubygems/dependency", __dir__)
autoload :DependencyList, File.expand_path("rubygems/dependency_list", __dir__)
autoload :Installer, File.expand_path("rubygems/installer", __dir__)
@@ -1358,17 +1350,6 @@ begin
rescue LoadError
end
-# TruffleRuby >= 24 defines REUSE_AS_BINARY_ON_TRUFFLERUBY in defaults/truffleruby.
-# However, TruffleRuby < 24 defines REUSE_AS_BINARY_ON_TRUFFLERUBY directly in its copy
-# of lib/rubygems/platform.rb, so it is not defined if RubyGems is updated (gem update --system).
-# Instead, we define it here in that case, similar to bundler/lib/bundler/rubygems_ext.rb.
-# We must define it here and not in platform.rb because platform.rb is loaded before defaults/truffleruby.
-class Gem::Platform
- if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY)
- REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 libv8-node sorbet-static].freeze
- end
-end
-
##
# Loads the default specs.
Gem::Specification.load_defaults
@@ -1378,7 +1359,7 @@ require_relative "rubygems/core_ext/kernel_gem"
path = File.join(__dir__, "rubygems/core_ext/kernel_require.rb")
# When https://bugs.ruby-lang.org/issues/17259 is available, there is no need to override Kernel#warn
if RUBY_ENGINE == "truffleruby" ||
- RUBY_ENGINE == "ruby"
+ (RUBY_ENGINE == "ruby" && RUBY_VERSION >= "3.0")
file = "<internal:#{path}>"
else
require_relative "rubygems/core_ext/kernel_warn"
diff --git a/lib/rubygems/available_set.rb b/lib/rubygems/available_set.rb
index 0af80cc3db..2ab3e137da 100644
--- a/lib/rubygems/available_set.rb
+++ b/lib/rubygems/available_set.rb
@@ -27,7 +27,7 @@ class Gem::AvailableSet
s = o.set
when Array
s = o.map do |sp,so|
- if !sp.is_a?(Gem::Specification) || !so.is_a?(Gem::Source)
+ if !sp.kind_of?(Gem::Specification) || !so.kind_of?(Gem::Source)
raise TypeError, "Array must be in [[spec, source], ...] form"
end
@@ -70,7 +70,7 @@ class Gem::AvailableSet
end
def all_specs
- @set.map(&:spec)
+ @set.map {|t| t.spec }
end
def match_platform!
@@ -105,14 +105,14 @@ class Gem::AvailableSet
def to_request_set(development = :none)
request_set = Gem::RequestSet.new
- request_set.development = development == :all
+ request_set.development = :all == development
each_spec do |spec|
request_set.always_install << spec
request_set.gem spec.name, spec.version
request_set.import spec.development_dependencies if
- development == :shallow
+ :shallow == development
end
request_set
@@ -147,7 +147,7 @@ class Gem::AvailableSet
end
def remove_installed!(dep)
- @set.reject! do |_t|
+ @set.reject! do |t|
# already locally installed
Gem::Specification.any? do |installed_spec|
dep.name == installed_spec.name &&
diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb
index 0380fceece..5d198114e0 100644
--- a/lib/rubygems/basic_specification.rb
+++ b/lib/rubygems/basic_specification.rb
@@ -76,21 +76,15 @@ class Gem::BasicSpecification
elsif missing_extensions?
@ignored = true
- if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
- warn "Ignoring #{full_name} because its extensions are not built. " \
+ if Gem::Platform::RUBY == platform || Gem::Platform.local === platform
+ warn "Ignoring #{full_name} because its extensions are not built. " +
"Try: gem pristine #{name} --version #{version}"
end
return false
end
- is_soext = file.end_with?(".so", ".o")
-
- if is_soext
- have_file? file.delete_suffix(File.extname(file)), Gem.dynamic_library_suffixes
- else
- have_file? file, Gem.suffixes
- end
+ have_file? file, Gem.suffixes
end
def default_gem?
@@ -102,7 +96,7 @@ class Gem::BasicSpecification
# Returns full path to the directory where gem's extensions are installed.
def extension_dir
- @extension_dir ||= File.expand_path(File.join(extensions_dir, full_name))
+ @extension_dir ||= File.expand_path(File.join(extensions_dir, full_name)).tap(&Gem::UNTAINT)
end
##
@@ -116,7 +110,9 @@ class Gem::BasicSpecification
def find_full_gem_path # :nodoc:
# TODO: also, shouldn't it default to full_name if it hasn't been written?
- File.expand_path File.join(gems_dir, full_name)
+ path = File.expand_path File.join(gems_dir, full_name)
+ path.tap(&Gem::UNTAINT)
+ path
end
private :find_full_gem_path
@@ -137,9 +133,9 @@ class Gem::BasicSpecification
def full_name
if platform == Gem::Platform::RUBY || platform.nil?
- "#{name}-#{version}"
+ "#{name}-#{version}".dup.tap(&Gem::UNTAINT)
else
- "#{name}-#{version}-#{platform}"
+ "#{name}-#{version}-#{platform}".dup.tap(&Gem::UNTAINT)
end
end
@@ -149,15 +145,15 @@ class Gem::BasicSpecification
def full_require_paths
@full_require_paths ||=
- begin
- full_paths = raw_require_paths.map do |path|
- File.join full_gem_path, path
- end
+ begin
+ full_paths = raw_require_paths.map do |path|
+ File.join full_gem_path, path.tap(&Gem::UNTAINT)
+ end
- full_paths << extension_dir if have_extensions?
+ full_paths << extension_dir if have_extensions?
- full_paths
- end
+ full_paths
+ end
end
##
@@ -165,7 +161,7 @@ class Gem::BasicSpecification
def datadir
# TODO: drop the extra ", gem_name" which is uselessly redundant
- File.expand_path(File.join(gems_dir, full_name, "data", name))
+ File.expand_path(File.join(gems_dir, full_name, "data", name)).tap(&Gem::UNTAINT)
end
##
@@ -175,14 +171,18 @@ class Gem::BasicSpecification
def to_fullpath(path)
if activated?
@paths_map ||= {}
- Gem.suffixes.each do |suf|
- full_require_paths.each do |dir|
- fullpath = "#{dir}/#{path}#{suf}"
- next unless File.file?(fullpath)
- @paths_map[path] ||= fullpath
- end
+ @paths_map[path] ||=
+ begin
+ fullpath = nil
+ suffixes = Gem.suffixes
+ suffixes.find do |suf|
+ full_require_paths.find do |dir|
+ File.file?(fullpath = "#{dir}/#{path}#{suf}")
+ end
+ end ? fullpath : nil
end
- @paths_map[path]
+ else
+ nil
end
end
@@ -272,9 +272,9 @@ class Gem::BasicSpecification
# Return all files in this gem that match for +glob+.
def matches_for_glob(glob) # TODO: rename?
- glob = File.join(lib_dirs_glob, glob)
+ glob = File.join(self.lib_dirs_glob, glob)
- Dir[glob]
+ Dir[glob].map {|f| f.tap(&Gem::UNTAINT) } # FIX our tests are broken, run w/ SAFE=1
end
##
@@ -289,17 +289,17 @@ class Gem::BasicSpecification
# for this spec.
def lib_dirs_glob
- dirs = if raw_require_paths
- if raw_require_paths.size > 1
- "{#{raw_require_paths.join(",")}}"
+ dirs = if self.raw_require_paths
+ if self.raw_require_paths.size > 1
+ "{#{self.raw_require_paths.join(',')}}"
else
- raw_require_paths.first
+ self.raw_require_paths.first
end
else
"lib" # default value for require_paths for bundler/inline
end
- "#{full_gem_path}/#{dirs}"
+ "#{self.full_gem_path}/#{dirs}".dup.tap(&Gem::UNTAINT)
end
##
@@ -324,19 +324,15 @@ class Gem::BasicSpecification
raise NotImplementedError
end
- def this
- self
- end
+ def this; self; end
private
- def have_extensions?
- !extensions.empty?
- end
+ def have_extensions?; !extensions.empty?; end
def have_file?(file, suffixes)
return true if raw_require_paths.any? do |path|
- base = File.join(gems_dir, full_name, path, file)
+ base = File.join(gems_dir, full_name, path.tap(&Gem::UNTAINT), file).tap(&Gem::UNTAINT)
suffixes.any? {|suf| File.file? base + suf }
end
diff --git a/lib/rubygems/bundler_version_finder.rb b/lib/rubygems/bundler_version_finder.rb
index dd2fd77418..5b34227d3a 100644
--- a/lib/rubygems/bundler_version_finder.rb
+++ b/lib/rubygems/bundler_version_finder.rb
@@ -52,7 +52,7 @@ module Gem::BundlerVersionFinder
unless gemfile
begin
Gem::Util.traverse_parents(Dir.pwd) do |directory|
- next unless gemfile = Gem::GEM_DEP_FILES.find {|f| File.file?(f) }
+ next unless gemfile = Gem::GEM_DEP_FILES.find {|f| File.file?(f.tap(&Gem::UNTAINT)) }
gemfile = File.join directory, gemfile
break
@@ -65,9 +65,9 @@ module Gem::BundlerVersionFinder
return unless gemfile
lockfile = case gemfile
- when "gems.rb" then "gems.locked"
- else "#{gemfile}.lock"
- end
+ when "gems.rb" then "gems.locked"
+ else "#{gemfile}.lock"
+ end.dup.tap(&Gem::UNTAINT)
return unless File.file?(lockfile)
diff --git a/lib/rubygems/ci_detector.rb b/lib/rubygems/ci_detector.rb
deleted file mode 100644
index 7a2d4ee29a..0000000000
--- a/lib/rubygems/ci_detector.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-module Gem
- module CIDetector
- # NOTE: Any changes made here will need to be made to both lib/rubygems/ci_detector.rb and
- # bundler/lib/bundler/ci_detector.rb (which are enforced duplicates).
- # TODO: Drop that duplication once bundler drops support for RubyGems 3.4
- #
- # ## Recognized CI providers, their signifiers, and the relevant docs ##
- #
- # Travis CI - CI, TRAVIS https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
- # Cirrus CI - CI, CIRRUS_CI https://cirrus-ci.org/guide/writing-tasks/#environment-variables
- # Circle CI - CI, CIRCLECI https://circleci.com/docs/variables/#built-in-environment-variables
- # Gitlab CI - CI, GITLAB_CI https://docs.gitlab.com/ee/ci/variables/
- # AppVeyor - CI, APPVEYOR https://www.appveyor.com/docs/environment-variables/
- # CodeShip - CI_NAME https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables#_default_environment_variables
- # dsari - CI, DSARI https://github.com/rfinnie/dsari#running
- # Jenkins - BUILD_NUMBER https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
- # TeamCity - TEAMCITY_VERSION https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html#Predefined+Server+Build+Parameters
- # Appflow - CI_BUILD_ID https://ionic.io/docs/appflow/automation/environments#predefined-environments
- # TaskCluster - TASKCLUSTER_ROOT_URL https://docs.taskcluster.net/docs/manual/design/env-vars
- # Semaphore - CI, SEMAPHORE https://docs.semaphoreci.com/ci-cd-environment/environment-variables/
- # BuildKite - CI, BUILDKITE https://buildkite.com/docs/pipelines/environment-variables
- # GoCD - GO_SERVER_URL https://docs.gocd.org/current/faq/dev_use_current_revision_in_build.html
- # GH Actions - CI, GITHUB_ACTIONS https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
- #
- # ### Some "standard" ENVs that multiple providers may set ###
- #
- # * CI - this is set by _most_ (but not all) CI providers now; it's approaching a standard.
- # * CI_NAME - Not as frequently used, but some providers set this to specify their own name
-
- # Any of these being set is a reasonably reliable indicator that we are
- # executing in a CI environment.
- ENV_INDICATORS = [
- "CI",
- "CI_NAME",
- "CONTINUOUS_INTEGRATION",
- "BUILD_NUMBER",
- "CI_APP_ID",
- "CI_BUILD_ID",
- "CI_BUILD_NUMBER",
- "RUN_ID",
- "TASKCLUSTER_ROOT_URL",
- ].freeze
-
- # For each CI, this env suffices to indicate that we're on _that_ CI's
- # containers. (A few of them only supply a CI_NAME variable, which is also
- # nice). And if they set "CI" but we can't tell which one they are, we also
- # want to know that - a bare "ci" without another token tells us as much.
- ENV_DESCRIPTORS = {
- "TRAVIS" => "travis",
- "CIRCLECI" => "circle",
- "CIRRUS_CI" => "cirrus",
- "DSARI" => "dsari",
- "SEMAPHORE" => "semaphore",
- "JENKINS_URL" => "jenkins",
- "BUILDKITE" => "buildkite",
- "GO_SERVER_URL" => "go",
- "GITLAB_CI" => "gitlab",
- "GITHUB_ACTIONS" => "github",
- "TASKCLUSTER_ROOT_URL" => "taskcluster",
- "CI" => "ci",
- }.freeze
-
- def self.ci?
- ENV_INDICATORS.any? {|var| ENV.include?(var) }
- end
-
- def self.ci_strings
- matching_names = ENV_DESCRIPTORS.select {|env, _| ENV[env] }.values
- matching_names << ENV["CI_NAME"].downcase if ENV["CI_NAME"]
- matching_names.reject(&:empty?).sort.uniq
- end
- end
-end
diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb
index ec498a8b94..07cf4e0e81 100644
--- a/lib/rubygems/command.rb
+++ b/lib/rubygems/command.rb
@@ -6,7 +6,7 @@
# See LICENSE.txt for permissions.
#++
-require_relative "vendored_optparse"
+require_relative "optparse"
require_relative "requirement"
require_relative "user_interaction"
@@ -20,7 +20,9 @@ require_relative "user_interaction"
class Gem::Command
include Gem::UserInteraction
- Gem::OptionParser.accept Symbol, &:to_sym
+ Gem::OptionParser.accept Symbol do |value|
+ value.to_sym
+ end
##
# The name of the command.
@@ -92,7 +94,7 @@ class Gem::Command
# array or a string to be split on white space.
def self.add_specific_extra_args(cmd,args)
- args = args.split(/\s+/) if args.is_a? String
+ args = args.split(/\s+/) if args.kind_of? String
specific_extra_args_hash[cmd] = args
end
@@ -190,7 +192,7 @@ class Gem::Command
"Please specify at least one gem name (e.g. gem build GEMNAME)"
end
- args.reject {|arg| arg.start_with?("-") }
+ args.select {|arg| arg !~ /^-/ }
end
##
@@ -226,7 +228,7 @@ class Gem::Command
if args.size > 1
raise Gem::CommandLineError,
- "Too many gem names (#{args.join(", ")}); please specify only one"
+ "Too many gem names (#{args.join(', ')}); please specify only one"
end
args.first
@@ -314,7 +316,7 @@ class Gem::Command
options[:build_args] = build_args
if options[:silent]
- old_ui = ui
+ old_ui = self.ui
self.ui = ui = Gem::SilentUI.new
end
@@ -396,21 +398,22 @@ class Gem::Command
def check_deprecated_options(options)
options.each do |option|
- next unless option_is_deprecated?(option)
- deprecation = @deprecated_options[command][option]
- version_to_expire = deprecation["rg_version_to_expire"]
+ if option_is_deprecated?(option)
+ deprecation = @deprecated_options[command][option]
+ version_to_expire = deprecation["rg_version_to_expire"]
- deprecate_option_msg = if version_to_expire
- "The \"#{option}\" option has been deprecated and will be removed in Rubygems #{version_to_expire}."
- else
- "The \"#{option}\" option has been deprecated and will be removed in future versions of Rubygems."
- end
+ deprecate_option_msg = if version_to_expire
+ "The \"#{option}\" option has been deprecated and will be removed in Rubygems #{version_to_expire}."
+ else
+ "The \"#{option}\" option has been deprecated and will be removed in future versions of Rubygems."
+ end
- extra_msg = deprecation["extra_msg"]
+ extra_msg = deprecation["extra_msg"]
- deprecate_option_msg += " #{extra_msg}" if extra_msg
+ deprecate_option_msg += " #{extra_msg}" if extra_msg
- alert_warning(deprecate_option_msg)
+ alert_warning(deprecate_option_msg)
+ end
end
end
@@ -427,10 +430,12 @@ class Gem::Command
# True if the command handles the given argument list.
def handles?(args)
- parser.parse!(args.dup)
- true
- rescue StandardError
- false
+ begin
+ parser.parse!(args.dup)
+ return true
+ rescue
+ return false
+ end
end
##
@@ -457,7 +462,7 @@ class Gem::Command
until extra.empty? do
ex = []
ex << extra.shift
- ex << extra.shift if /^[^-]/.match?(extra.first.to_s)
+ ex << extra.shift if extra.first.to_s =~ /^[^-]/ # rubocop:disable Performance/StartWith
result << ex if handles?(ex)
end
@@ -473,7 +478,7 @@ class Gem::Command
private
def option_is_deprecated?(option)
- @deprecated_options[command].key?(option)
+ @deprecated_options[command].has_key?(option)
end
def add_parser_description # :nodoc:
@@ -485,7 +490,7 @@ class Gem::Command
@parser.separator nil
@parser.separator " Description:"
- formatted.each_line do |line|
+ formatted.split("\n").each do |line|
@parser.separator " #{line.rstrip}"
end
end
@@ -512,8 +517,8 @@ class Gem::Command
@parser.separator nil
@parser.separator " #{title}:"
- content.each_line do |line|
- @parser.separator " #{line.rstrip}"
+ content.split(/\n/).each do |line|
+ @parser.separator " #{line}"
end
end
@@ -522,7 +527,7 @@ class Gem::Command
@parser.separator nil
@parser.separator " Summary:"
- wrap(@summary, 80 - 4).each_line do |line|
+ wrap(@summary, 80 - 4).split("\n").each do |line|
@parser.separator " #{line.strip}"
end
end
@@ -579,12 +584,12 @@ class Gem::Command
# Add the options common to all commands.
add_common_option("-h", "--help",
- "Get help on this command") do |_value, options|
+ "Get help on this command") do |value, options|
options[:help] = true
end
add_common_option("-V", "--[no-]verbose",
- "Set the verbose level of output") do |value, _options|
+ "Set the verbose level of output") do |value, options|
# Set us to "really verbose" so the progress meter works
if Gem.configuration.verbose && value
Gem.configuration.verbose = 1
@@ -593,12 +598,12 @@ class Gem::Command
end
end
- add_common_option("-q", "--quiet", "Silence command progress meter") do |_value, _options|
+ add_common_option("-q", "--quiet", "Silence command progress meter") do |value, options|
Gem.configuration.verbose = false
end
add_common_option("--silent",
- "Silence RubyGems output") do |_value, options|
+ "Silence RubyGems output") do |value, options|
options[:silent] = true
end
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
index 8e578dc196..b3913d465a 100644
--- a/lib/rubygems/command_manager.rb
+++ b/lib/rubygems/command_manager.rb
@@ -60,7 +60,6 @@ class Gem::CommandManager
:push,
:query,
:rdoc,
- :rebuild,
:search,
:server,
:signin,
@@ -107,7 +106,7 @@ class Gem::CommandManager
# Register all the subcommands supported by the gem command.
def initialize
- require_relative "vendored_timeout"
+ require "timeout"
@commands = {}
BUILTIN_COMMANDS.each do |name|
@@ -142,7 +141,7 @@ class Gem::CommandManager
# Return a sorted list of all command names as strings.
def command_names
- @commands.keys.collect(&:to_s).sort
+ @commands.keys.collect {|key| key.to_s }.sort
end
##
@@ -150,7 +149,7 @@ class Gem::CommandManager
def run(args, build_args=nil)
process_args(args, build_args)
- rescue StandardError, Gem::Timeout::Error => ex
+ rescue StandardError, Timeout::Error => ex
if ex.respond_to?(:detailed_message)
msg = ex.detailed_message(highlight: false).sub(/\A(.*?)(?: \(.+?\))/) { $1 }
else
@@ -202,7 +201,7 @@ class Gem::CommandManager
if possibilities.size > 1
raise Gem::CommandLineError,
- "Ambiguous command #{cmd_name} matches [#{possibilities.join(", ")}]"
+ "Ambiguous command #{cmd_name} matches [#{possibilities.join(', ')}]"
elsif possibilities.empty?
raise Gem::UnknownCommandError.new(cmd_name)
end
@@ -239,7 +238,7 @@ class Gem::CommandManager
load_error = e
end
Gem::Commands.const_get(const_name).new
- rescue StandardError => e
+ rescue Exception => e
e = load_error if load_error
alert_error clean_text("Loading command: #{command_name} (#{e.class})\n\t#{e}")
@@ -250,7 +249,6 @@ class Gem::CommandManager
def invoke_command(args, build_args)
cmd_name = args.shift.downcase
cmd = find_command cmd_name
- terminate_interaction 1 unless cmd
cmd.deprecation_warning if cmd.deprecated?
cmd.invoke_with_build_args args, build_args
end
diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb
index 2ec8324141..68e020d94a 100644
--- a/lib/rubygems/commands/build_command.rb
+++ b/lib/rubygems/commands/build_command.rb
@@ -1,24 +1,22 @@
# frozen_string_literal: true
require_relative "../command"
-require_relative "../gemspec_helpers"
require_relative "../package"
require_relative "../version_option"
class Gem::Commands::BuildCommand < Gem::Command
include Gem::VersionOption
- include Gem::GemspecHelpers
def initialize
super "build", "Build a gem from a gemspec"
add_platform_option
- add_option "--force", "skip validation of the spec" do |_value, options|
+ add_option "--force", "skip validation of the spec" do |value, options|
options[:force] = true
end
- add_option "--strict", "consider warnings as errors when validating the spec" do |_value, options|
+ add_option "--strict", "consider warnings as errors when validating the spec" do |value, options|
options[:strict] = true
end
@@ -77,6 +75,17 @@ Gems can be saved to a specified filename with the output option:
private
+ def find_gemspec(glob = "*.gemspec")
+ gemspecs = Dir.glob(glob).sort
+
+ if gemspecs.size > 1
+ alert_error "Multiple gemspecs found: #{gemspecs}, please specify one"
+ terminate_interaction(1)
+ end
+
+ gemspecs.first
+ end
+
def build_gem
gemspec = resolve_gem_name
diff --git a/lib/rubygems/commands/cert_command.rb b/lib/rubygems/commands/cert_command.rb
index 72dcf1dd17..344f31fba9 100644
--- a/lib/rubygems/commands/cert_command.rb
+++ b/lib/rubygems/commands/cert_command.rb
@@ -6,7 +6,7 @@ require_relative "../security"
class Gem::Commands::CertCommand < Gem::Command
def initialize
super "cert", "Manage RubyGems certificates and signing settings",
- add: [], remove: [], list: [], build: [], sign: []
+ :add => [], :remove => [], :list => [], :build => [], :sign => []
add_option("-a", "--add CERT",
"Add a trusted certificate.") do |cert_file, options|
@@ -136,7 +136,7 @@ class Gem::Commands::CertCommand < Gem::Command
end
def build(email)
- unless valid_email?(email)
+ if !valid_email?(email)
raise Gem::CommandLineError, "Invalid email address #{email}"
end
@@ -178,9 +178,9 @@ class Gem::Commands::CertCommand < Gem::Command
algorithm = options[:key_algorithm] || Gem::Security::DEFAULT_KEY_ALGORITHM
key = Gem::Security.create_key(algorithm)
- key_path = Gem::Security.write key, "gem-private_key.pem", 0o600, passphrase
+ key_path = Gem::Security.write key, "gem-private_key.pem", 0600, passphrase
- [key, key_path]
+ return key, key_path
end
def certificates_matching(filter)
@@ -263,6 +263,7 @@ For further reading on signing gems see `ri Gem::Security`.
key = File.read key_file
passphrase = ENV["GEM_PRIVATE_KEY_PASSPHRASE"]
options[:key] = OpenSSL::PKey.read key, passphrase
+
rescue Errno::ENOENT
alert_error \
"--private-key not specified and ~/.gem/gem-private_key.pem does not exist"
@@ -291,7 +292,7 @@ For further reading on signing gems see `ri Gem::Security`.
cert = File.read cert_file
cert = OpenSSL::X509::Certificate.new cert
- permissions = File.stat(cert_file).mode & 0o777
+ permissions = File.stat(cert_file).mode & 0777
issuer_cert = options[:issuer_cert]
issuer_key = options[:key]
diff --git a/lib/rubygems/commands/check_command.rb b/lib/rubygems/commands/check_command.rb
index fb23dd9cb4..b300b4f87a 100644
--- a/lib/rubygems/commands/check_command.rb
+++ b/lib/rubygems/commands/check_command.rb
@@ -10,7 +10,7 @@ class Gem::Commands::CheckCommand < Gem::Command
def initialize
super "check", "Check a gem repository for added or missing files",
- alien: true, doctor: false, dry_run: false, gems: true
+ :alien => true, :doctor => false, :dry_run => false, :gems => true
add_option("-a", "--[no-]alien",
'Report "unmanaged" or rogue files in the',
@@ -41,21 +41,17 @@ class Gem::Commands::CheckCommand < Gem::Command
def check_gems
say "Checking gems..."
say
- gems = begin
- get_all_gem_names
- rescue StandardError
- []
- end
+ gems = get_all_gem_names rescue []
Gem::Validator.new.alien(gems).sort.each do |key, val|
- if val.empty?
- say "#{key} is error-free" if Gem.configuration.verbose
- else
+ unless val.empty?
say "#{key} has #{val.size} problems"
val.each do |error_entry|
say " #{error_entry.path}:"
say " #{error_entry.problem}"
end
+ else
+ say "#{key} is error-free" if Gem.configuration.verbose
end
say
end
diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb
index 08fb598cea..ee5e1252b6 100644
--- a/lib/rubygems/commands/cleanup_command.rb
+++ b/lib/rubygems/commands/cleanup_command.rb
@@ -8,16 +8,16 @@ class Gem::Commands::CleanupCommand < Gem::Command
def initialize
super "cleanup",
"Clean up old versions of installed gems",
- force: false, install_dir: Gem.dir,
- check_dev: true
+ :force => false, :install_dir => Gem.dir,
+ :check_dev => true
add_option("-n", "-d", "--dry-run",
- "Do not uninstall gems") do |_value, options|
+ "Do not uninstall gems") do |value, options|
options[:dryrun] = true
end
add_option(:Deprecated, "--dryrun",
- "Do not uninstall gems") do |_value, options|
+ "Do not uninstall gems") do |value, options|
options[:dryrun] = true
end
deprecate_option("--dryrun", extra_msg: "Use --dry-run instead")
@@ -75,7 +75,7 @@ If no gems are named all gems in GEM_HOME are cleaned.
until done do
clean_gems
- this_set = @gems_to_cleanup.map(&:full_name).sort
+ this_set = @gems_to_cleanup.map {|spec| spec.full_name }.sort
done = this_set.empty? || last_set == this_set
@@ -88,9 +88,9 @@ If no gems are named all gems in GEM_HOME are cleaned.
say "Clean up complete"
verbose do
- skipped = @default_gems.map(&:full_name)
+ skipped = @default_gems.map {|spec| spec.full_name }
- "Skipped default gems: #{skipped.join ", "}"
+ "Skipped default gems: #{skipped.join ', '}"
end
end
@@ -117,12 +117,12 @@ If no gems are named all gems in GEM_HOME are cleaned.
end
def get_candidate_gems
- @candidate_gems = if options[:args].empty?
- Gem::Specification.to_a
- else
+ @candidate_gems = unless options[:args].empty?
options[:args].map do |gem_name|
Gem::Specification.find_all_by_name gem_name
end.flatten
+ else
+ Gem::Specification.to_a
end
end
@@ -131,7 +131,9 @@ If no gems are named all gems in GEM_HOME are cleaned.
@primary_gems[spec.name].version != spec.version
end
- default_gems, gems_to_cleanup = gems_to_cleanup.partition(&:default_gem?)
+ default_gems, gems_to_cleanup = gems_to_cleanup.partition do |spec|
+ spec.default_gem?
+ end
uninstall_from = options[:user_install] ? Gem.user_dir : @original_home
@@ -166,8 +168,8 @@ If no gems are named all gems in GEM_HOME are cleaned.
say "Attempting to uninstall #{spec.full_name}"
uninstall_options = {
- executables: false,
- version: "= #{spec.version}",
+ :executables => false,
+ :version => "= #{spec.version}",
}
uninstall_options[:user_install] = Gem.user_dir == spec.base_dir
diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb
index 807158d9c9..f378441ca4 100644
--- a/lib/rubygems/commands/contents_command.rb
+++ b/lib/rubygems/commands/contents_command.rb
@@ -8,8 +8,8 @@ class Gem::Commands::ContentsCommand < Gem::Command
def initialize
super "contents", "Display the contents of the installed gems",
- specdirs: [], lib_only: false, prefix: true,
- show_install_dir: false
+ :specdirs => [], :lib_only => false, :prefix => true,
+ :show_install_dir => false
add_version_option
@@ -92,9 +92,9 @@ prefix or only the files that are requireable.
def files_in_gem(spec)
gem_path = spec.full_gem_path
- extra = "/{#{spec.require_paths.join ","}}" if options[:lib_only]
+ extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only]
glob = "#{gem_path}#{extra}/**/*"
- prefix_re = %r{#{Regexp.escape(gem_path)}/}
+ prefix_re = /#{Regexp.escape(gem_path)}\//
Dir[glob].map do |file|
[gem_path, file.sub(prefix_re, "")]
@@ -104,7 +104,7 @@ prefix or only the files that are requireable.
def files_in_default_gem(spec)
spec.files.map do |file|
case file
- when %r{\A#{spec.bindir}/}
+ when /\A#{spec.bindir}\//
# $' is POSTMATCH
[RbConfig::CONFIG["bindir"], $']
when /\.so\z/
@@ -178,7 +178,7 @@ prefix or only the files that are requireable.
@spec_dirs.sort.each {|dir| say dir }
end
- nil
+ return nil
end
def specification_directories # :nodoc:
diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb
index 9aaefae999..cef98e30d3 100644
--- a/lib/rubygems/commands/dependency_command.rb
+++ b/lib/rubygems/commands/dependency_command.rb
@@ -11,14 +11,15 @@ class Gem::Commands::DependencyCommand < Gem::Command
def initialize
super "dependency",
"Show the dependencies of an installed gem",
- version: Gem::Requirement.default, domain: :local
+ :version => Gem::Requirement.default, :domain => :local
add_version_option
add_platform_option
add_prerelease_option
add_option("-R", "--[no-]reverse-dependencies",
- "Include reverse dependencies in the output") do |value, options|
+ "Include reverse dependencies in the output") do
+ |value, options|
options[:reverse_dependencies] = value
end
@@ -90,9 +91,10 @@ use with other commands.
def display_pipe(specs) # :nodoc:
specs.each do |spec|
- next if spec.dependencies.empty?
- spec.dependencies.sort_by(&:name).each do |dep|
- say "#{dep.name} --version '#{dep.requirement}'"
+ unless spec.dependencies.empty?
+ spec.dependencies.sort_by {|dep| dep.name }.each do |dep|
+ say "#{dep.name} --version '#{dep.requirement}'"
+ end
end
end
end
@@ -152,7 +154,7 @@ use with other commands.
response = String.new
response << " " * level + "Gem #{spec.full_name}\n"
unless spec.dependencies.empty?
- spec.dependencies.sort_by(&:name).each do |dep|
+ spec.dependencies.sort_by {|dep| dep.name }.each do |dep|
response << " " * level + " #{dep}\n"
end
end
diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb
index 8ed0996069..28dbf93c50 100644
--- a/lib/rubygems/commands/environment_command.rb
+++ b/lib/rubygems/commands/environment_command.rb
@@ -17,7 +17,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
platform display the supported gem platforms
<omitted> display everything
EOF
- args.gsub(/^\s+/, "")
+ return args.gsub(/^\s+/, "")
end
def description # :nodoc:
@@ -108,7 +108,9 @@ lib/rubygems/defaults/operating_system.rb
out << " - RUBYGEMS VERSION: #{Gem::VERSION}\n"
- out << " - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]\n"
+ out << " - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
+ out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
+ out << ") [#{RUBY_PLATFORM}]\n"
out << " - INSTALLATION DIRECTORY: #{Gem.dir}\n"
@@ -171,6 +173,6 @@ lib/rubygems/defaults/operating_system.rb
end
end
- nil
+ return nil
end
end
diff --git a/lib/rubygems/commands/exec_command.rb b/lib/rubygems/commands/exec_command.rb
index d588804290..383c8c5b37 100644
--- a/lib/rubygems/commands/exec_command.rb
+++ b/lib/rubygems/commands/exec_command.rb
@@ -23,7 +23,7 @@ class Gem::Commands::ExecCommand < Gem::Command
add_option(:"Install/Update", "--conservative",
"Prefer the most recent installed version, ",
- "rather than the latest version overall") do |_value, options|
+ "rather than the latest version overall") do |value, options|
options[:conservative] = true
end
end
diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb
index f7f5b62306..950d4fe30e 100644
--- a/lib/rubygems/commands/fetch_command.rb
+++ b/lib/rubygems/commands/fetch_command.rb
@@ -10,8 +10,8 @@ class Gem::Commands::FetchCommand < Gem::Command
def initialize
defaults = {
- suggest_alternate: true,
- version: Gem::Requirement.default,
+ :suggest_alternate => true,
+ :version => Gem::Requirement.default,
}
super "fetch", "Download a gem and place it in the current directory", defaults
diff --git a/lib/rubygems/commands/generate_index_command.rb b/lib/rubygems/commands/generate_index_command.rb
index 13be92593b..ce580cfaf9 100644
--- a/lib/rubygems/commands/generate_index_command.rb
+++ b/lib/rubygems/commands/generate_index_command.rb
@@ -1,51 +1,86 @@
# frozen_string_literal: true
require_relative "../command"
+require_relative "../indexer"
-unless defined? Gem::Commands::GenerateIndexCommand
- class Gem::Commands::GenerateIndexCommand < Gem::Command
- module RubygemsTrampoline
- def description # :nodoc:
- <<~EOF
- The generate_index command has been moved to the rubygems-generate_index gem.
- EOF
- end
+##
+# Generates a index files for use as a gem server.
+#
+# See `gem help generate_index`
- def execute
- alert_error "Install the rubygems-generate_index gem for the generate_index command"
- end
+class Gem::Commands::GenerateIndexCommand < Gem::Command
+ def initialize
+ super "generate_index",
+ "Generates the index files for a gem server directory",
+ :directory => ".", :build_modern => true
- def invoke_with_build_args(args, build_args)
- name = "rubygems-generate_index"
- spec = begin
- Gem::Specification.find_by_name(name)
- rescue Gem::LoadError
- require "rubygems/dependency_installer"
- Gem.install(name, Gem::Requirement.default, Gem::DependencyInstaller::DEFAULT_OPTIONS).find {|s| s.name == name }
- end
-
- # remove the methods defined in this file so that the methods defined in the gem are used instead,
- # and without a method redefinition warning
- %w[description execute invoke_with_build_args].each do |method|
- RubygemsTrampoline.remove_method(method)
- end
- self.class.singleton_class.remove_method(:new)
-
- spec.activate
- Gem.load_plugin_files spec.matches_for_glob("rubygems_plugin#{Gem.suffix_pattern}")
-
- self.class.new.invoke_with_build_args(args, build_args)
- end
+ add_option "-d", "--directory=DIRNAME",
+ "repository base dir containing gems subdir" do |dir, options|
+ options[:directory] = File.expand_path dir
+ end
+
+ add_option "--[no-]modern",
+ "Generate indexes for RubyGems",
+ "(always true)" do |value, options|
+ options[:build_modern] = value
end
- private_constant :RubygemsTrampoline
- # remove_method(:initialize) warns, but removing new does not warn
- def self.new
- command = allocate
- command.send(:initialize, "generate_index", "Generates the index files for a gem server directory (requires rubygems-generate_index)")
- command
+ deprecate_option("--modern", version: "4.0", extra_msg: "Modern indexes (specs, latest_specs, and prerelease_specs) are always generated, so this option is not needed.")
+ deprecate_option("--no-modern", version: "4.0", extra_msg: "The `--no-modern` option is currently ignored. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated.")
+
+ add_option "--update",
+ "Update modern indexes with gems added",
+ "since the last update" do |value, options|
+ options[:update] = value
end
+ end
+
+ def defaults_str # :nodoc:
+ "--directory . --modern"
+ end
+
+ def description # :nodoc:
+ <<-EOF
+The generate_index command creates a set of indexes for serving gems
+statically. The command expects a 'gems' directory under the path given to
+the --directory option. The given directory will be the directory you serve
+as the gem repository.
- prepend(RubygemsTrampoline)
+For `gem generate_index --directory /path/to/repo`, expose /path/to/repo via
+your HTTP server configuration (not /path/to/repo/gems).
+
+When done, it will generate a set of files like this:
+
+ gems/*.gem # .gem files you want to
+ # index
+
+ specs.<version>.gz # specs index
+ latest_specs.<version>.gz # latest specs index
+ prerelease_specs.<version>.gz # prerelease specs index
+ quick/Marshal.<version>/<gemname>.gemspec.rz # Marshal quick index file
+
+The .rz extension files are compressed with the inflate algorithm.
+The Marshal version number comes from ruby's Marshal::MAJOR_VERSION and
+Marshal::MINOR_VERSION constants. It is used to ensure compatibility.
+ EOF
+ end
+
+ def execute
+ # This is always true because it's the only way now.
+ options[:build_modern] = true
+
+ if !File.exist?(options[:directory]) ||
+ !File.directory?(options[:directory])
+ alert_error "unknown directory name #{options[:directory]}."
+ terminate_interaction 1
+ else
+ indexer = Gem::Indexer.new options.delete(:directory), options
+
+ if options[:update]
+ indexer.update_index
+ else
+ indexer.generate_index
+ end
+ end
end
end
diff --git a/lib/rubygems/commands/help_command.rb b/lib/rubygems/commands/help_command.rb
index 1619b152e7..20b99fa366 100644
--- a/lib/rubygems/commands/help_command.rb
+++ b/lib/rubygems/commands/help_command.rb
@@ -59,7 +59,7 @@ multiple environments. The RubyGems implementation is designed to be
compatible with Bundler's Gemfile format. You can see additional
documentation on the format at:
- https://bundler.io
+ http://bundler.io
RubyGems automatically looks for these gem dependencies files:
@@ -172,7 +172,7 @@ and #platforms methods:
See the bundler Gemfile manual page for a list of platforms supported in a gem
dependencies file.:
- https://bundler.io/v2.5/man/gemfile.5.html
+ http://bundler.io/v1.6/man/gemfile.5.html
Ruby Version and Engine Dependency
==================================
@@ -269,7 +269,7 @@ Gem::Platform::CURRENT. This will correctly mark the gem with your ruby's
platform.
EOF
- # NOTE: when updating also update Gem::Command::HELP
+ # NOTE when updating also update Gem::Command::HELP
SUBCOMMANDS = [
["commands", :show_commands],
@@ -324,16 +324,16 @@ platform.
margin_width = 4
- desc_width = @command_manager.command_names.map(&:size).max + 4
+ desc_width = @command_manager.command_names.map {|n| n.size }.max + 4
summary_width = 80 - margin_width - desc_width
wrap_indent = " " * (margin_width + desc_width)
- format = "#{" " * margin_width}%-#{desc_width}s%s"
+ format = "#{' ' * margin_width}%-#{desc_width}s%s"
@command_manager.command_names.each do |cmd_name|
command = @command_manager[cmd_name]
- next if command&.deprecated?
+ next if command.deprecated?
summary =
if command
@@ -343,7 +343,7 @@ platform.
end
summary = wrap(summary, summary_width).split "\n"
- out << format(format, cmd_name, summary.shift)
+ out << sprintf(format, cmd_name, summary.shift)
until summary.empty? do
out << "#{wrap_indent}#{summary.shift}"
end
@@ -367,7 +367,7 @@ platform.
command = @command_manager[possibilities.first]
command.invoke("--help")
elsif possibilities.size > 1
- alert_warning "Ambiguous command #{command_name} (#{possibilities.join(", ")})"
+ alert_warning "Ambiguous command #{command_name} (#{possibilities.join(', ')})"
else
alert_warning "Unknown command #{command_name}. Try: gem help commands"
end
diff --git a/lib/rubygems/commands/info_command.rb b/lib/rubygems/commands/info_command.rb
index f65c639662..ced7751ff5 100644
--- a/lib/rubygems/commands/info_command.rb
+++ b/lib/rubygems/commands/info_command.rb
@@ -8,8 +8,8 @@ class Gem::Commands::InfoCommand < Gem::Command
def initialize
super "info", "Show information for the given gem",
- name: //, domain: :local, details: false, versions: true,
- installed: nil, version: Gem::Requirement.default
+ :name => //, :domain => :local, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
add_query_options
diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb
index 2091634a29..b0bc2908b4 100644
--- a/lib/rubygems/commands/install_command.rb
+++ b/lib/rubygems/commands/install_command.rb
@@ -23,11 +23,11 @@ class Gem::Commands::InstallCommand < Gem::Command
def initialize
defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({
- format_executable: false,
- lock: true,
- suggest_alternate: true,
- version: Gem::Requirement.default,
- without_groups: [],
+ :format_executable => false,
+ :lock => true,
+ :suggest_alternate => true,
+ :version => Gem::Requirement.default,
+ :without_groups => [],
})
defaults.merge!(install_update_options)
@@ -48,7 +48,7 @@ class Gem::Commands::InstallCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--both --version '#{Gem::Requirement.default}' --no-force\n" \
+ "--both --version '#{Gem::Requirement.default}' --no-force\n" +
"--install-dir #{Gem.dir} --lock\n" +
install_update_defaults_str
end
@@ -136,6 +136,13 @@ You can use `i` command instead of `install`.
"#{program_name} [options] GEMNAME [GEMNAME ...] -- --build-flags"
end
+ def check_install_dir # :nodoc:
+ if options[:install_dir] && options[:user_install]
+ alert_error "Use --install-dir or --user-install but not both"
+ terminate_interaction 1
+ end
+ end
+
def check_version # :nodoc:
if options[:version] != Gem::Requirement.default &&
get_all_gem_names.size > 1
@@ -155,6 +162,7 @@ You can use `i` command instead of `install`.
ENV.delete "GEM_PATH" if options[:install_dir].nil?
+ check_install_dir
check_version
load_hooks
@@ -163,7 +171,7 @@ You can use `i` command instead of `install`.
show_installed
- say update_suggestion if eligible_for_update?
+ say update_suggestion if eglible_for_update?
terminate_interaction exit_code
end
@@ -255,7 +263,7 @@ You can use `i` command instead of `install`.
return unless errors
errors.each do |x|
- next unless Gem::SourceFetchProblem === x
+ return unless Gem::SourceFetchProblem === x
require_relative "../uri"
msg = "Unable to pull data from '#{Gem::Uri.redact(x.source.uri)}': #{x.error.message}"
diff --git a/lib/rubygems/commands/list_command.rb b/lib/rubygems/commands/list_command.rb
index fab4b73814..522c771f90 100644
--- a/lib/rubygems/commands/list_command.rb
+++ b/lib/rubygems/commands/list_command.rb
@@ -11,8 +11,8 @@ class Gem::Commands::ListCommand < Gem::Command
def initialize
super "list", "Display local gems whose name matches REGEXP",
- domain: :local, details: false, versions: true,
- installed: nil, version: Gem::Requirement.default
+ :domain => :local, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
add_query_options
end
diff --git a/lib/rubygems/commands/lock_command.rb b/lib/rubygems/commands/lock_command.rb
index f7fd5ada16..3a9512fe3f 100644
--- a/lib/rubygems/commands/lock_command.rb
+++ b/lib/rubygems/commands/lock_command.rb
@@ -5,7 +5,7 @@ require_relative "../command"
class Gem::Commands::LockCommand < Gem::Command
def initialize
super "lock", "Generate a lockdown list of gems",
- strict: false
+ :strict => false
add_option "-s", "--[no-]strict",
"fail if unable to satisfy a dependency" do |strict, options|
diff --git a/lib/rubygems/commands/open_command.rb b/lib/rubygems/commands/open_command.rb
index 0fe90dc8b8..5a13074a1d 100644
--- a/lib/rubygems/commands/open_command.rb
+++ b/lib/rubygems/commands/open_command.rb
@@ -70,7 +70,9 @@ class Gem::Commands::OpenCommand < Gem::Command
end
def open_editor(path)
- system(*@editor.split(/\s+/) + [path], { chdir: path })
+ Dir.chdir(path) do
+ system(*@editor.split(/\s+/) + [path])
+ end
end
def spec_for(name)
diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb
index 12bfe3a834..b51c9cf888 100644
--- a/lib/rubygems/commands/owner_command.rb
+++ b/lib/rubygems/commands/owner_command.rb
@@ -39,7 +39,7 @@ permission to.
add_proxy_option
add_key_option
add_otp_option
- defaults.merge! add: [], remove: []
+ defaults.merge! :add => [], :remove => []
add_option "-a", "--add NEW_OWNER", "Add an owner by user identifier" do |value, options|
options[:add] << value
@@ -79,7 +79,7 @@ permission to.
say "Owners for gem: #{name}"
owners.each do |owner|
- say "- #{owner["email"] || owner["handle"] || owner["id"]}"
+ say "- #{owner['email'] || owner['handle'] || owner['id']}"
end
end
end
@@ -94,14 +94,16 @@ permission to.
def manage_owners(method, name, owners)
owners.each do |owner|
- response = send_owner_request(method, name, owner)
- action = method == :delete ? "Removing" : "Adding"
-
- with_response response, "#{action} #{owner}"
- rescue Gem::WebauthnVerificationError => e
- raise e
- rescue StandardError
- # ignore early exits to allow for completing the iteration of all owners
+ begin
+ response = send_owner_request(method, name, owner)
+ action = method == :delete ? "Removing" : "Adding"
+
+ with_response response, "#{action} #{owner}"
+ rescue Gem::WebauthnVerificationError => e
+ raise e
+ rescue StandardError
+ # ignore early exits to allow for completing the iteration of all owners
+ end
end
end
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index b272a15b6c..64608a033f 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -11,10 +11,10 @@ class Gem::Commands::PristineCommand < Gem::Command
def initialize
super "pristine",
"Restores installed gems to pristine condition from files located in the gem cache",
- version: Gem::Requirement.default,
- extensions: true,
- extensions_set: false,
- all: false
+ :version => Gem::Requirement.default,
+ :extensions => true,
+ :extensions_set => false,
+ :all => false
add_option("--all",
"Restore all installed gems to pristine",
@@ -57,7 +57,7 @@ class Gem::Commands::PristineCommand < Gem::Command
end
add_option("-i", "--install-dir DIR",
- "Gem repository to get gems restored") do |value, options|
+ "Gem repository to get binstubs and plugins installed") do |value, options|
options[:install_dir] = File.expand_path(value)
end
@@ -103,29 +103,27 @@ extensions will be restored.
end
def execute
- install_dir = options[:install_dir]
-
- specification_record = install_dir ? Gem::SpecificationRecord.from_path(install_dir) : Gem::Specification.specification_record
-
specs = if options[:all]
- specification_record.map
+ Gem::Specification.map
# `--extensions` must be explicitly given to pristine only gems
# with extensions.
elsif options[:extensions_set] &&
options[:extensions] && options[:args].empty?
- specification_record.select do |spec|
+ Gem::Specification.select do |spec|
spec.extensions && !spec.extensions.empty?
end
elsif options[:only_missing_extensions]
- specification_record.select(&:missing_extensions?)
+ Gem::Specification.select do |spec|
+ spec.missing_extensions?
+ end
else
get_all_gem_names.sort.map do |gem_name|
- specification_record.find_all_by_name(gem_name, options[:version]).reverse
+ Gem::Specification.find_all_by_name(gem_name, options[:version]).reverse
end.flatten
end
- specs = specs.select {|spec| spec.platform == RUBY_ENGINE || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }
+ specs = specs.select {|spec| RUBY_ENGINE == spec.platform || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }
if specs.to_a.empty?
raise Gem::Exception,
@@ -140,7 +138,7 @@ extensions will be restored.
next
end
- if options.key? :skip
+ if options.has_key? :skip
if options[:skip].include? spec.name
say "Skipped #{spec.full_name}, it was given through options"
next
@@ -180,14 +178,15 @@ extensions will be restored.
end
bin_dir = options[:bin_dir] if options[:bin_dir]
+ install_dir = options[:install_dir] if options[:install_dir]
installer_options = {
- wrappers: true,
- force: true,
- install_dir: install_dir || spec.base_dir,
- env_shebang: env_shebang,
- build_args: spec.build_args,
- bin_dir: bin_dir,
+ :wrappers => true,
+ :force => true,
+ :install_dir => install_dir || spec.base_dir,
+ :env_shebang => env_shebang,
+ :build_args => spec.build_args,
+ :bin_dir => bin_dir,
}
if options[:only_executables]
diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb
index 591ddc3a80..79ca3d59b0 100644
--- a/lib/rubygems/commands/push_command.rb
+++ b/lib/rubygems/commands/push_command.rb
@@ -30,7 +30,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
end
def initialize
- super "push", "Push a gem up to the gem server", host: host
+ super "push", "Push a gem up to the gem server", :host => self.host
@user_defined_host = false
@@ -75,7 +75,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
@host ||= push_host
# Always include @host, even if it's nil
- args += [@host, push_host]
+ args += [ @host, push_host ]
say "Pushing gem to #{@host || Gem.host}..."
diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb
index 3b527974a3..4fa201272e 100644
--- a/lib/rubygems/commands/query_command.rb
+++ b/lib/rubygems/commands/query_command.rb
@@ -10,7 +10,7 @@ class Gem::Commands::QueryCommand < Gem::Command
include Gem::QueryUtils
- alias_method :warning_without_suggested_alternatives, :deprecation_warning
+ alias warning_without_suggested_alternatives deprecation_warning
def deprecation_warning
warning_without_suggested_alternatives
@@ -18,10 +18,11 @@ class Gem::Commands::QueryCommand < Gem::Command
alert_warning message unless Gem::Deprecate.skip
end
- def initialize(name = "query", summary = "Query gem information in local or remote repositories")
+ def initialize(name = "query",
+ summary = "Query gem information in local or remote repositories")
super name, summary,
- domain: :local, details: false, versions: true,
- installed: nil, version: Gem::Requirement.default
+ :domain => :local, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
add_option("-n", "--name-matches REGEXP",
"Name of gem(s) to query on matches the",
diff --git a/lib/rubygems/commands/rdoc_command.rb b/lib/rubygems/commands/rdoc_command.rb
index 977c90b8c4..e318a52914 100644
--- a/lib/rubygems/commands/rdoc_command.rb
+++ b/lib/rubygems/commands/rdoc_command.rb
@@ -10,8 +10,8 @@ class Gem::Commands::RdocCommand < Gem::Command
def initialize
super "rdoc", "Generates RDoc for pre-installed gems",
- version: Gem::Requirement.default,
- include_rdoc: false, include_ri: true, overwrite: false
+ :version => Gem::Requirement.default,
+ :include_rdoc => false, :include_ri => true, :overwrite => false
add_option("--all",
"Generate RDoc/RI documentation for all",
@@ -84,7 +84,14 @@ Use --overwrite to force rebuilding of documentation.
FileUtils.rm_rf File.join(spec.doc_dir, "rdoc")
end
- doc.generate
+ begin
+ doc.generate
+ rescue Errno::ENOENT => e
+ match = / - /.match(e.message)
+ alert_error "Unable to document #{spec.full_name}, " \
+ " #{match.post_match} is missing, skipping"
+ terminate_interaction 1 if specs.length == 1
+ end
end
end
end
diff --git a/lib/rubygems/commands/rebuild_command.rb b/lib/rubygems/commands/rebuild_command.rb
deleted file mode 100644
index 97f05ef79c..0000000000
--- a/lib/rubygems/commands/rebuild_command.rb
+++ /dev/null
@@ -1,264 +0,0 @@
-# frozen_string_literal: true
-
-require "date"
-require "digest"
-require "fileutils"
-require "tmpdir"
-require_relative "../gemspec_helpers"
-require_relative "../package"
-
-class Gem::Commands::RebuildCommand < Gem::Command
- include Gem::GemspecHelpers
-
- DATE_FORMAT = "%Y-%m-%d %H:%M:%S.%N Z"
-
- def initialize
- super "rebuild", "Attempt to reproduce a build of a gem."
-
- add_option "--diff", "If the files don't match, compare them using diffoscope." do |_value, options|
- options[:diff] = true
- end
-
- add_option "--force", "Skip validation of the spec." do |_value, options|
- options[:force] = true
- end
-
- add_option "--strict", "Consider warnings as errors when validating the spec." do |_value, options|
- options[:strict] = true
- end
-
- add_option "--source GEM_SOURCE", "Specify the source to download the gem from." do |value, options|
- options[:source] = value
- end
-
- add_option "--original GEM_FILE", "Specify a local file to compare against (instead of downloading it)." do |value, options|
- options[:original_gem_file] = value
- end
-
- add_option "--gemspec GEMSPEC_FILE", "Specify the name of the gemspec file." do |value, options|
- options[:gemspec_file] = value
- end
-
- add_option "-C PATH", "Run as if gem build was started in <PATH> instead of the current working directory." do |value, options|
- options[:build_path] = value
- end
- end
-
- def arguments # :nodoc:
- "GEM_NAME gem name on gem server\n" \
- "GEM_VERSION gem version you are attempting to rebuild"
- end
-
- def description # :nodoc:
- <<-EOF
-The rebuild command allows you to (attempt to) reproduce a build of a gem
-from a ruby gemspec.
-
-This command assumes the gemspec can be built with the `gem build` command.
-If you use any of `gem build`, `rake build`, or`rake release` in the
-build/release process for a gem, it is a potential candidate.
-
-You will need to match the RubyGems version used, since this is included in
-the Gem metadata.
-
-If the gem includes lockfiles (e.g. Gemfile.lock) and similar, it will
-require more effort to reproduce a build. For example, it might require
-more precisely matched versions of Ruby and/or Bundler to be used.
- EOF
- end
-
- def usage # :nodoc:
- "#{program_name} GEM_NAME GEM_VERSION"
- end
-
- def execute
- gem_name, gem_version = get_gem_name_and_version
-
- old_dir, new_dir = prep_dirs
-
- gem_filename = "#{gem_name}-#{gem_version}.gem"
- old_file = File.join(old_dir, gem_filename)
- new_file = File.join(new_dir, gem_filename)
-
- if options[:original_gem_file]
- FileUtils.copy_file(options[:original_gem_file], old_file)
- else
- download_gem(gem_name, gem_version, old_file)
- end
-
- rg_version = rubygems_version(old_file)
- unless rg_version == Gem::VERSION
- alert_error <<-EOF
-You need to use the same RubyGems version #{gem_name} v#{gem_version} was built with.
-
-#{gem_name} v#{gem_version} was built using RubyGems v#{rg_version}.
-Gem files include the version of RubyGems used to build them.
-This means in order to reproduce #{gem_filename}, you must also use RubyGems v#{rg_version}.
-
-You're using RubyGems v#{Gem::VERSION}.
-
-Please install RubyGems v#{rg_version} and try again.
- EOF
- terminate_interaction 1
- end
-
- source_date_epoch = get_timestamp(old_file).to_s
-
- if build_path = options[:build_path]
- Dir.chdir(build_path) { build_gem(gem_name, source_date_epoch, new_file) }
- else
- build_gem(gem_name, source_date_epoch, new_file)
- end
-
- compare(source_date_epoch, old_file, new_file)
- end
-
- private
-
- def sha256(file)
- Digest::SHA256.hexdigest(Gem.read_binary(file))
- end
-
- def get_timestamp(file)
- mtime = nil
- File.open(file, Gem.binary_mode) do |f|
- Gem::Package::TarReader.new(f) do |tar|
- mtime = tar.seek("metadata.gz") {|tf| tf.header.mtime }
- end
- end
-
- mtime
- end
-
- def compare(source_date_epoch, old_file, new_file)
- date = Time.at(source_date_epoch.to_i).strftime("%F %T %Z")
-
- old_hash = sha256(old_file)
- new_hash = sha256(new_file)
-
- say
- say "Built at: #{date} (#{source_date_epoch})"
- say "Original build saved to: #{old_file}"
- say "Reproduced build saved to: #{new_file}"
- say "Working directory: #{options[:build_path] || Dir.pwd}"
- say
- say "Hash comparison:"
- say " #{old_hash}\t#{old_file}"
- say " #{new_hash}\t#{new_file}"
- say
-
- if old_hash == new_hash
- say "SUCCESS - original and rebuild hashes matched"
- else
- say "FAILURE - original and rebuild hashes did not match"
- say
-
- if options[:diff]
- if system("diffoscope", old_file, new_file).nil?
- alert_error "error: could not find `diffoscope` executable"
- end
- else
- say "Pass --diff for more details (requires diffoscope to be installed)."
- end
-
- terminate_interaction 1
- end
- end
-
- def prep_dirs
- rebuild_dir = Dir.mktmpdir("gem_rebuild")
- old_dir = File.join(rebuild_dir, "old")
- new_dir = File.join(rebuild_dir, "new")
-
- FileUtils.mkdir_p(old_dir)
- FileUtils.mkdir_p(new_dir)
-
- [old_dir, new_dir]
- end
-
- def get_gem_name_and_version
- args = options[:args] || []
- if args.length == 2
- gem_name, gem_version = args
- elsif args.length > 2
- raise Gem::CommandLineError, "Too many arguments"
- else
- raise Gem::CommandLineError, "Expected GEM_NAME and GEM_VERSION arguments (gem rebuild GEM_NAME GEM_VERSION)"
- end
-
- [gem_name, gem_version]
- end
-
- def build_gem(gem_name, source_date_epoch, output_file)
- gemspec = options[:gemspec_file] || find_gemspec("#{gem_name}.gemspec")
-
- if gemspec
- build_package(gemspec, source_date_epoch, output_file)
- else
- alert_error error_message(gem_name)
- terminate_interaction(1)
- end
- end
-
- def build_package(gemspec, source_date_epoch, output_file)
- with_source_date_epoch(source_date_epoch) do
- spec = Gem::Specification.load(gemspec)
- if spec
- Gem::Package.build(
- spec,
- options[:force],
- options[:strict],
- output_file
- )
- else
- alert_error "Error loading gemspec. Aborting."
- terminate_interaction 1
- end
- end
- end
-
- def with_source_date_epoch(source_date_epoch)
- old_sde = ENV["SOURCE_DATE_EPOCH"]
- ENV["SOURCE_DATE_EPOCH"] = source_date_epoch.to_s
-
- yield
- ensure
- ENV["SOURCE_DATE_EPOCH"] = old_sde
- end
-
- def error_message(gem_name)
- if gem_name
- "Couldn't find a gemspec file matching '#{gem_name}' in #{Dir.pwd}"
- else
- "Couldn't find a gemspec file in #{Dir.pwd}"
- end
- end
-
- def download_gem(gem_name, gem_version, old_file)
- # This code was based loosely off the `gem fetch` command.
- version = "= #{gem_version}"
- dep = Gem::Dependency.new gem_name, version
-
- specs_and_sources, errors =
- Gem::SpecFetcher.fetcher.spec_for_dependency dep
-
- # There should never be more than one item in specs_and_sources,
- # since we search for an exact version.
- spec, source = specs_and_sources[0]
-
- if spec.nil?
- show_lookup_failure gem_name, version, errors, options[:domain]
- terminate_interaction 1
- end
-
- download_path = source.download spec
-
- FileUtils.move(download_path, old_file)
-
- say "Downloaded #{gem_name} version #{gem_version} as #{old_file}."
- end
-
- def rubygems_version(gem_file)
- Gem::Package.new(gem_file).spec.rubygems_version
- end
-end
diff --git a/lib/rubygems/commands/search_command.rb b/lib/rubygems/commands/search_command.rb
index 50e161ac9b..c7469e1fa8 100644
--- a/lib/rubygems/commands/search_command.rb
+++ b/lib/rubygems/commands/search_command.rb
@@ -8,8 +8,8 @@ class Gem::Commands::SearchCommand < Gem::Command
def initialize
super "search", "Display remote gems whose name matches REGEXP",
- domain: :remote, details: false, versions: true,
- installed: nil, version: Gem::Requirement.default
+ :domain => :remote, :details => false, :versions => true,
+ :installed => nil, :version => Gem::Requirement.default
add_query_options
end
diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb
index 9c633d6ef7..df1732b49e 100644
--- a/lib/rubygems/commands/setup_command.rb
+++ b/lib/rubygems/commands/setup_command.rb
@@ -7,19 +7,19 @@ require_relative "../command"
# RubyGems checkout or tarball.
class Gem::Commands::SetupCommand < Gem::Command
- HISTORY_HEADER = %r{^#\s*[\d.a-zA-Z]+\s*/\s*\d{4}-\d{2}-\d{2}\s*$}
- VERSION_MATCHER = %r{^#\s*([\d.a-zA-Z]+)\s*/\s*\d{4}-\d{2}-\d{2}\s*$}
+ HISTORY_HEADER = /^#\s*[\d.a-zA-Z]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/.freeze
+ VERSION_MATCHER = /^#\s*([\d.a-zA-Z]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/.freeze
ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
def initialize
super "setup", "Install RubyGems",
- format_executable: false, document: %w[ri],
- force: true,
- site_or_vendor: "sitelibdir",
- destdir: "", prefix: "", previous_version: "",
- regenerate_binstubs: true,
- regenerate_plugins: true
+ :format_executable => false, :document => %w[ri],
+ :force => true,
+ :site_or_vendor => "sitelibdir",
+ :destdir => "", :prefix => "", :previous_version => "",
+ :regenerate_binstubs => true,
+ :regenerate_plugins => true
add_option "--previous-version=VERSION",
"Previous version of RubyGems",
@@ -55,9 +55,9 @@ class Gem::Commands::SetupCommand < Gem::Command
"List the documentation types you wish to",
"generate. For example: rdoc,ri" do |value, options|
options[:document] = case value
- when nil then %w[rdoc ri]
- when false then []
- else value
+ when nil then %w[rdoc ri]
+ when false then []
+ else value
end
end
@@ -134,7 +134,7 @@ prefix and suffix. If ruby was installed as `ruby18`, gem will be
installed as `gem18`.
By default, this RubyGems will install gem as:
- #{Gem.default_exec_format % "gem"}
+ #{Gem.default_exec_format % 'gem'}
EOF
end
@@ -243,7 +243,7 @@ By default, this RubyGems will install gem as:
end
def install_executables(bin_dir)
- prog_mode = options[:prog_mode] || 0o755
+ prog_mode = options[:prog_mode] || 0755
executables = { "gem" => "exe" }
executables.each do |tool, path|
@@ -265,7 +265,7 @@ By default, this RubyGems will install gem as:
fp.puts bin.join
end
- install bin_tmp_file, dest_file, mode: prog_mode
+ install bin_tmp_file, dest_file, :mode => prog_mode
bin_file_names << dest_file
ensure
rm bin_tmp_file
@@ -287,7 +287,7 @@ By default, this RubyGems will install gem as:
TEXT
end
- install bin_cmd_file, "#{dest_file}.bat", mode: prog_mode
+ install bin_cmd_file, "#{dest_file}.bat", :mode => prog_mode
ensure
rm bin_cmd_file
end
@@ -357,7 +357,7 @@ By default, this RubyGems will install gem as:
say "Set the GEM_HOME environment variable if you want RDoc generated"
end
- false
+ return false
end
def install_default_bundler_gem(bin_dir)
@@ -369,21 +369,18 @@ By default, this RubyGems will install gem as:
File.dirname(loaded_from)
else
target_specs_dir = File.join(default_dir, "specifications", "default")
- mkdir_p target_specs_dir, mode: 0o755
+ mkdir_p target_specs_dir, :mode => 0755
target_specs_dir
end
- new_bundler_spec = Dir.chdir("bundler") { Gem::Specification.load("bundler.gemspec") }
- full_name = new_bundler_spec.full_name
- gemspec_path = "#{full_name}.gemspec"
-
- default_spec_path = File.join(specs_dir, gemspec_path)
- Gem.write_binary(default_spec_path, new_bundler_spec.to_ruby)
+ bundler_spec = Dir.chdir("bundler") { Gem::Specification.load("bundler.gemspec") }
+ default_spec_path = File.join(specs_dir, "#{bundler_spec.full_name}.gemspec")
+ Gem.write_binary(default_spec_path, bundler_spec.to_ruby)
bundler_spec = Gem::Specification.load(default_spec_path)
# Remove gemspec that was same version of vendored bundler.
- normal_gemspec = File.join(default_dir, "specifications", gemspec_path)
+ normal_gemspec = File.join(default_dir, "specifications", "bundler-#{bundler_spec.version}.gemspec")
if File.file? normal_gemspec
File.delete normal_gemspec
end
@@ -391,14 +388,20 @@ By default, this RubyGems will install gem as:
# Remove gem files that were same version of vendored bundler.
if File.directory? bundler_spec.gems_dir
Dir.entries(bundler_spec.gems_dir).
- select {|default_gem| File.basename(default_gem) == full_name }.
+ select {|default_gem| File.basename(default_gem) == "bundler-#{bundler_spec.version}" }.
each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }
end
+ bundler_bin_dir = bundler_spec.bin_dir
+ mkdir_p bundler_bin_dir, :mode => 0755
+ bundler_spec.executables.each do |e|
+ cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_bin_dir, e)
+ end
+
require_relative "../installer"
Dir.chdir("bundler") do
- built_gem = Gem::Package.build(new_bundler_spec)
+ built_gem = Gem::Package.build(bundler_spec)
begin
Gem::Installer.at(
built_gem,
@@ -415,9 +418,9 @@ By default, this RubyGems will install gem as:
end
end
- new_bundler_spec.executables.each {|executable| bin_file_names << target_bin_path(bin_dir, executable) }
+ bundler_spec.executables.each {|executable| bin_file_names << target_bin_path(bin_dir, executable) }
- say "Bundler #{new_bundler_spec.version} installed"
+ say "Bundler #{bundler_spec.version} installed"
end
def make_destination_dirs
@@ -427,10 +430,10 @@ By default, this RubyGems will install gem as:
lib_dir, bin_dir = generate_default_dirs
end
- mkdir_p lib_dir, mode: 0o755
- mkdir_p bin_dir, mode: 0o755
+ mkdir_p lib_dir, :mode => 0755
+ mkdir_p bin_dir, :mode => 0755
- [lib_dir, bin_dir]
+ return lib_dir, bin_dir
end
def generate_default_man_dir
@@ -573,8 +576,8 @@ abort "#{deprecation_message}"
def uninstall_old_gemcutter
require_relative "../uninstaller"
- ui = Gem::Uninstaller.new("gemcutter", all: true, ignore: true,
- version: "< 0.4")
+ ui = Gem::Uninstaller.new("gemcutter", :all => true, :ignore => true,
+ :version => "< 0.4")
ui.uninstall
rescue Gem::InstallError
end
@@ -585,8 +588,6 @@ abort "#{deprecation_message}"
args = %w[--all --only-executables --silent]
args << "--bindir=#{bindir}"
- args << "--install-dir=#{default_dir}"
-
if options[:env_shebang]
args << "--env-shebang"
end
@@ -638,10 +639,10 @@ abort "#{deprecation_message}"
dest_file = File.join dest_dir, file
dest_dir = File.dirname dest_file
unless File.directory? dest_dir
- mkdir_p dest_dir, mode: 0o755
+ mkdir_p dest_dir, :mode => 0755
end
- install file, dest_file, mode: options[:data_mode] || 0o644
+ install file, dest_file, :mode => options[:data_mode] || 0644
end
def remove_file_list(files, dir)
diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb
index 976f4a4ea2..85cc68ac09 100644
--- a/lib/rubygems/commands/sources_command.rb
+++ b/lib/rubygems/commands/sources_command.rb
@@ -59,7 +59,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
say "#{source_uri} added to sources"
end
- rescue Gem::URI::Error, ArgumentError
+ rescue URI::Error, ArgumentError
say "#{source_uri} is not a URI"
terminate_interaction 1
rescue Gem::RemoteFetcher::FetchError => e
@@ -71,7 +71,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
def check_typo_squatting(source)
if source.typo_squatting?("rubygems.org")
question = <<-QUESTION.chomp
-#{source.uri} is too similar to https://rubygems.org
+#{source.uri.to_s} is too similar to https://rubygems.org
Do you want to add this source?
QUESTION
@@ -81,10 +81,10 @@ Do you want to add this source?
end
def check_rubygems_https(source_uri) # :nodoc:
- uri = Gem::URI source_uri
+ uri = URI source_uri
- if uri.scheme && uri.scheme.casecmp("http").zero? &&
- uri.host.casecmp("rubygems.org").zero?
+ if uri.scheme && uri.scheme.downcase == "http" &&
+ uri.host.downcase == "rubygems.org"
question = <<-QUESTION.chomp
https://rubygems.org is recommended for security over #{uri}
@@ -99,16 +99,16 @@ Do you want to add this insecure source?
path = Gem.spec_cache_dir
FileUtils.rm_rf path
- if File.exist? path
- if File.writable? path
- say "*** Unable to remove source cache ***"
- else
+ unless File.exist? path
+ say "*** Removed specs cache ***"
+ else
+ unless File.writable? path
say "*** Unable to remove source cache (write protected) ***"
+ else
+ say "*** Unable to remove source cache ***"
end
terminate_interaction 1
- else
- say "*** Removed specs cache ***"
end
end
@@ -194,13 +194,13 @@ To remove a source use the --remove argument:
end
def remove_source(source_uri) # :nodoc:
- if Gem.sources.include? source_uri
+ unless Gem.sources.include? source_uri
+ say "source #{source_uri} not present in cache"
+ else
Gem.sources.delete source_uri
Gem.configuration.write
say "#{source_uri} removed from sources"
- else
- say "source #{source_uri} not present in cache"
end
end
diff --git a/lib/rubygems/commands/specification_command.rb b/lib/rubygems/commands/specification_command.rb
index a21ed35be3..ed158506e0 100644
--- a/lib/rubygems/commands/specification_command.rb
+++ b/lib/rubygems/commands/specification_command.rb
@@ -13,27 +13,27 @@ class Gem::Commands::SpecificationCommand < Gem::Command
Gem.load_yaml
super "specification", "Display gem specification (in yaml)",
- domain: :local, version: Gem::Requirement.default,
- format: :yaml
+ :domain => :local, :version => Gem::Requirement.default,
+ :format => :yaml
add_version_option("examine")
add_platform_option
add_prerelease_option
add_option("--all", "Output specifications for all versions of",
- "the gem") do |_value, options|
+ "the gem") do |value, options|
options[:all] = true
end
- add_option("--ruby", "Output ruby format") do |_value, options|
+ add_option("--ruby", "Output ruby format") do |value, options|
options[:format] = :ruby
end
- add_option("--yaml", "Output YAML format") do |_value, options|
+ add_option("--yaml", "Output YAML format") do |value, options|
options[:format] = :yaml
end
- add_option("--marshal", "Output Marshal format") do |_value, options|
+ add_option("--marshal", "Output Marshal format") do |value, options|
options[:format] = :marshal
end
@@ -107,11 +107,7 @@ Specific fields in the specification can be extracted in YAML format:
if local?
if File.exist? gem
- begin
- specs << Gem::Package.new(gem).spec
- rescue StandardError
- nil
- end
+ specs << Gem::Package.new(gem).spec rescue nil
end
if specs.empty?
@@ -138,16 +134,16 @@ Specific fields in the specification can be extracted in YAML format:
end
unless options[:all]
- specs = [specs.max_by(&:version)]
+ specs = [specs.max_by {|s| s.version }]
end
specs.each do |s|
s = s.send field if field
say case options[:format]
- when :ruby then s.to_ruby
- when :marshal then Marshal.dump s
- else s.to_yaml
+ when :ruby then s.to_ruby
+ when :marshal then Marshal.dump s
+ else s.to_yaml
end
say "\n"
diff --git a/lib/rubygems/commands/stale_command.rb b/lib/rubygems/commands/stale_command.rb
index 0be2b85159..a94d77c193 100644
--- a/lib/rubygems/commands/stale_command.rb
+++ b/lib/rubygems/commands/stale_command.rb
@@ -18,7 +18,7 @@ longer using.
end
def usage # :nodoc:
- program_name.to_s
+ "#{program_name}"
end
def execute
@@ -34,7 +34,7 @@ longer using.
end
gem_to_atime.sort_by {|_, atime| atime }.each do |name, atime|
- say "#{name} at #{atime.strftime "%c"}"
+ say "#{name} at #{atime.strftime '%c'}"
end
end
end
diff --git a/lib/rubygems/commands/uninstall_command.rb b/lib/rubygems/commands/uninstall_command.rb
index 283bc96ce3..feba1c5b7c 100644
--- a/lib/rubygems/commands/uninstall_command.rb
+++ b/lib/rubygems/commands/uninstall_command.rb
@@ -15,11 +15,12 @@ class Gem::Commands::UninstallCommand < Gem::Command
def initialize
super "uninstall", "Uninstall gems from the local repository",
- version: Gem::Requirement.default, user_install: true,
- check_dev: false, vendor: false
+ :version => Gem::Requirement.default, :user_install => true,
+ :check_dev => false, :vendor => false
add_option("-a", "--[no-]all",
- "Uninstall all matching versions") do |value, options|
+ "Uninstall all matching versions"
+ ) do |value, options|
options[:all] = value
end
@@ -79,7 +80,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
add_option("--vendor",
"Uninstall gem from the vendor directory.",
- "Only for use by gem repackagers.") do |_value, options|
+ "Only for use by gem repackagers.") do |value, options|
unless Gem.vendor_dir
raise Gem::OptionParser::InvalidOption.new "your platform is not supported"
end
@@ -95,7 +96,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--version '#{Gem::Requirement.default}' --no-force " \
+ "--version '#{Gem::Requirement.default}' --no-force " +
"--user-install"
end
@@ -138,7 +139,7 @@ that is a dependency of an existing gem. You can use the
end
def uninstall_all
- specs = Gem::Specification.reject(&:default_gem?)
+ specs = Gem::Specification.reject {|spec| spec.default_gem? }
specs.each do |spec|
options[:version] = spec.version
@@ -168,14 +169,15 @@ that is a dependency of an existing gem. You can use the
gems_to_uninstall = {}
deps.each do |dep|
- if original_gem_version[dep.name] == Gem::Requirement.default
- next if gems_to_uninstall[dep.name]
+ unless gems_to_uninstall[dep.name]
gems_to_uninstall[dep.name] = true
- else
- options[:version] = dep.version
- end
- uninstall_gem(dep.name)
+ unless original_gem_version[dep.name] == Gem::Requirement.default
+ options[:version] = dep.version
+ end
+
+ uninstall_gem(dep.name)
+ end
end
end
@@ -183,12 +185,12 @@ that is a dependency of an existing gem. You can use the
uninstall(gem_name)
rescue Gem::GemNotInHomeException => e
spec = e.spec
- alert("In order to remove #{spec.name}, please execute:\n" \
- "\tgem uninstall #{spec.name} --install-dir=#{spec.base_dir}")
+ alert("In order to remove #{spec.name}, please execute:\n" +
+ "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}")
rescue Gem::UninstallError => e
spec = e.spec
- alert_error("Error: unable to successfully uninstall '#{spec.name}' which is " \
- "located at '#{spec.full_gem_path}'. This is most likely because" \
+ alert_error("Error: unable to successfully uninstall '#{spec.name}' which is " +
+ "located at '#{spec.full_gem_path}'. This is most likely because" +
"the current user does not have the appropriate permissions")
terminate_interaction 1
end
diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb
index f25c045c62..1bff53429b 100644
--- a/lib/rubygems/commands/unpack_command.rb
+++ b/lib/rubygems/commands/unpack_command.rb
@@ -21,15 +21,15 @@ class Gem::Commands::UnpackCommand < Gem::Command
require "fileutils"
super "unpack", "Unpack an installed gem to the current directory",
- version: Gem::Requirement.default,
- target: Dir.pwd
+ :version => Gem::Requirement.default,
+ :target => Dir.pwd
add_option("--target=DIR",
"target directory for unpacking") do |value, options|
options[:target] = value
end
- add_option("--spec", "unpack the gem specification") do |_value, options|
+ add_option("--spec", "unpack the gem specification") do |value, options|
options[:spec] = true
end
@@ -96,10 +96,12 @@ command help for an example.
FileUtils.mkdir_p @options[:target] if @options[:target]
- destination = if @options[:target]
- File.join @options[:target], spec_file
- else
- spec_file
+ destination = begin
+ if @options[:target]
+ File.join @options[:target], spec_file
+ else
+ spec_file
+ end
end
File.open destination, "w" do |io|
@@ -130,7 +132,7 @@ command help for an example.
return this_path if File.exist? this_path
end
- nil
+ return nil
end
##
@@ -151,16 +153,16 @@ command help for an example.
# source directories?
def get_path(dependency)
- return dependency.name if /\.gem$/i.match?(dependency.name)
+ return dependency.name if dependency.name =~ /\.gem$/i
specs = dependency.matching_specs
- selected = specs.max_by(&:version)
+ selected = specs.max_by {|s| s.version }
return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
selected
- return unless /^#{selected.name}$/i.match?(dependency.name)
+ return unless dependency.name =~ /^#{selected.name}$/i
# We expect to find (basename).gem in the 'cache' directory. Furthermore,
# the name match must be exact (ignoring case).
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index 8e80d46856..6f084d1c38 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -21,7 +21,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
def initialize
options = {
- force: false,
+ :force => false,
}
options.merge!(install_update_options)
@@ -37,10 +37,10 @@ class Gem::Commands::UpdateCommand < Gem::Command
end
add_option("--system [VERSION]", Gem::Version,
- "Update the RubyGems system software") do |value, opts|
- value ||= true
+ "Update the RubyGems system software") do |value, options|
+ value = true unless value
- opts[:system] = value
+ options[:system] = value
end
add_local_remote_options
@@ -120,7 +120,7 @@ command to remove old versions.
updated = update_gems gems_to_update
installed_names = highest_installed_gems.keys
- updated_names = updated.map(&:name)
+ updated_names = updated.map {|spec| spec.name }
not_updated_names = options[:args].uniq - updated_names
not_installed_names = not_updated_names - installed_names
up_to_date_names = not_updated_names - not_installed_names
@@ -128,10 +128,10 @@ command to remove old versions.
if updated.empty?
say "Nothing to update"
else
- say "Gems updated: #{updated_names.join(" ")}"
+ say "Gems updated: #{updated_names.join(' ')}"
end
- say "Gems already up-to-date: #{up_to_date_names.join(" ")}" unless up_to_date_names.empty?
- say "Gems not currently installed: #{not_installed_names.join(" ")}" unless not_installed_names.empty?
+ say "Gems already up-to-date: #{up_to_date_names.join(' ')}" unless up_to_date_names.empty?
+ say "Gems not currently installed: #{not_installed_names.join(' ')}" unless not_installed_names.empty?
end
def fetch_remote_gems(spec) # :nodoc:
@@ -186,9 +186,7 @@ command to remove old versions.
system Gem.ruby, "--disable-gems", "setup.rb", *args
end
- unless options[:silent]
- say "RubyGems system software updated" if installed
- end
+ say "RubyGems system software updated" if installed unless options[:silent]
end
end
@@ -197,17 +195,18 @@ command to remove old versions.
yield
else
require "tmpdir"
- Dir.mktmpdir("gem_update") do |tmpdir|
- FileUtils.mv Gem.plugindir, tmpdir
-
- status = yield
+ tmpdir = Dir.mktmpdir
+ FileUtils.mv Gem.plugindir, tmpdir
- unless status
- FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
- end
+ status = yield
- status
+ if status
+ FileUtils.rm_rf tmpdir
+ else
+ FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
end
+
+ status
end
end
@@ -232,7 +231,7 @@ command to remove old versions.
highest_remote_tup = highest_remote_name_tuple(rubygems_update)
target = highest_remote_tup ? highest_remote_tup.version : version
- [target, requirement]
+ return target, requirement
end
def update_gem(name, version = Gem::Requirement.default)
@@ -243,7 +242,7 @@ command to remove old versions.
@installer = Gem::DependencyInstaller.new update_options
- say "Updating #{name}" unless options[:system]
+ say "Updating #{name}" unless options[:system] && options[:silent]
begin
@installer.install name, Gem::Requirement.new(version)
rescue Gem::InstallError, Gem::DependencyError => e
@@ -281,7 +280,7 @@ command to remove old versions.
check_oldest_rubygems version
installed_gems = Gem::Specification.find_all_by_name "rubygems-update", requirement
- installed_gems = update_gem("rubygems-update", requirement) if installed_gems.empty? || installed_gems.first.version != version
+ installed_gems = update_gem("rubygems-update", version) if installed_gems.empty? || installed_gems.first.version != version
return if installed_gems.empty?
install_rubygems installed_gems.first
@@ -293,14 +292,16 @@ command to remove old versions.
args << "--prefix" << Gem.prefix if Gem.prefix
args << "--no-document" unless options[:document].include?("rdoc") || options[:document].include?("ri")
args << "--no-format-executable" if options[:no_format_executable]
- args << "--previous-version" << Gem::VERSION
+ args << "--previous-version" << Gem::VERSION if
+ options[:system] == true ||
+ Gem::Version.new(options[:system]) >= Gem::Version.new(2)
args
end
def which_to_update(highest_installed_gems, gem_names)
result = []
- highest_installed_gems.each do |_l_name, l_spec|
+ highest_installed_gems.each do |l_name, l_spec|
next if !gem_names.empty? &&
gem_names.none? {|name| name == l_spec.name }
@@ -325,8 +326,12 @@ command to remove old versions.
@oldest_supported_version ||=
if Gem.ruby_version > Gem::Version.new("3.1.a")
Gem::Version.new("3.3.3")
- else
+ elsif Gem.ruby_version > Gem::Version.new("3.0.a")
Gem::Version.new("3.2.3")
+ elsif Gem.ruby_version > Gem::Version.new("2.7.a")
+ Gem::Version.new("3.1.2")
+ else
+ Gem::Version.new("3.0.1")
end
end
end
diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb
index 5ed4d9d142..ec464d9672 100644
--- a/lib/rubygems/commands/which_command.rb
+++ b/lib/rubygems/commands/which_command.rb
@@ -5,7 +5,7 @@ require_relative "../command"
class Gem::Commands::WhichCommand < Gem::Command
def initialize
super "which", "Find the location of a library file you can require",
- search_gems_first: false, show_all: false
+ :search_gems_first => false, :show_all => false
add_option "-a", "--[no-]all", "show all matching files" do |show_all, options|
options[:show_all] = show_all
diff --git a/lib/rubygems/commands/yank_command.rb b/lib/rubygems/commands/yank_command.rb
index fbdc262549..d344a020c3 100644
--- a/lib/rubygems/commands/yank_command.rb
+++ b/lib/rubygems/commands/yank_command.rb
@@ -62,7 +62,7 @@ data you will need to change them immediately and yank your gem.
end
def yank_gem(version, platform)
- say "Yanking gem from #{host}..."
+ say "Yanking gem from #{self.host}..."
args = [:delete, version, platform, "api/v1/gems/yank"]
response = yank_api_request(*args)
@@ -89,7 +89,7 @@ data you will need to change them immediately and yank your gem.
def get_version_from_requirements(requirements)
requirements.requirements.first[1].version
- rescue StandardError
+ rescue
nil
end
diff --git a/lib/rubygems/compatibility.rb b/lib/rubygems/compatibility.rb
index 0d9df56f8a..b4c1ef16fa 100644
--- a/lib/rubygems/compatibility.rb
+++ b/lib/rubygems/compatibility.rb
@@ -26,16 +26,17 @@ module Gem
rubylibdir
].freeze
- if defined?(ConfigMap)
- RbConfigPriorities.each do |key|
- ConfigMap[key.to_sym] = RbConfig::CONFIG[key]
- end
- else
+ unless defined?(ConfigMap)
##
# Configuration settings from ::RbConfig
ConfigMap = Hash.new do |cm, key|
cm[key] = RbConfig::CONFIG[key.to_s]
end
deprecate_constant(:ConfigMap)
+ else
+ RbConfigPriorities.each do |key|
+ ConfigMap[key.to_sym] = RbConfig::CONFIG[key]
+ end
end
+
end
diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb
index 3200beb45f..68c653269e 100644
--- a/lib/rubygems/config_file.rb
+++ b/lib/rubygems/config_file.rb
@@ -188,10 +188,10 @@ class Gem::ConfigFile
operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
system_config = load_file SYSTEM_WIDE_CONFIG_FILE
- user_config = load_file config_file_name
+ user_config = load_file config_file_name.dup.tap(&Gem::UNTAINT)
- environment_config = (ENV["GEMRC"] || "").
- split(File::PATH_SEPARATOR).inject({}) do |result, file|
+ environment_config = (ENV["GEMRC"] || "")
+ .split(File::PATH_SEPARATOR).inject({}) do |result, file|
result.merge load_file file
end
@@ -202,33 +202,21 @@ class Gem::ConfigFile
@hash = @hash.merge environment_config
end
- @hash.transform_keys! do |k|
- # gemhome and gempath are not working with symbol keys
- if %w[backtrace bulk_threshold verbose update_sources cert_expiration_length_days
- install_extension_in_lib ipv4_fallback_enabled sources disable_default_gem_server
- ssl_verify_mode ssl_ca_cert ssl_client_cert].include?(k)
- k.to_sym
- else
- k
- end
- end
-
- # HACK: these override command-line args, which is bad
+ # HACK these override command-line args, which is bad
@backtrace = @hash[:backtrace] if @hash.key? :backtrace
@bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold
- @verbose = @hash[:verbose] if @hash.key? :verbose
+ @home = @hash[:gemhome] if @hash.key? :gemhome
+ @path = @hash[:gempath] if @hash.key? :gempath
@update_sources = @hash[:update_sources] if @hash.key? :update_sources
- # TODO: We should handle concurrent_downloads same as other options
+ @verbose = @hash[:verbose] if @hash.key? :verbose
+ @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
+ @sources = @hash[:sources] if @hash.key? :sources
@cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
@ipv4_fallback_enabled = @hash[:ipv4_fallback_enabled] if @hash.key? :ipv4_fallback_enabled
- @home = @hash[:gemhome] if @hash.key? :gemhome
- @path = @hash[:gempath] if @hash.key? :gempath
- @sources = @hash[:sources] if @hash.key? :sources
- @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
- @ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
- @ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
- @ssl_client_cert = @hash[:ssl_client_cert] if @hash.key? :ssl_client_cert
+ @ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
+ @ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
+ @ssl_client_cert = @hash[:ssl_client_cert] if @hash.key? :ssl_client_cert
@api_keys = nil
@rubygems_api_key = nil
@@ -253,9 +241,9 @@ class Gem::ConfigFile
return if Gem.win_platform? # windows doesn't write 0600 as 0600
return unless File.exist? credentials_path
- existing_permissions = File.stat(credentials_path).mode & 0o777
+ existing_permissions = File.stat(credentials_path).mode & 0777
- return if existing_permissions == 0o600
+ return if existing_permissions == 0600
alert_error <<-ERROR
Your gem push credentials file located at:
@@ -336,9 +324,11 @@ if you believe they were disclosed to a third party.
require "fileutils"
FileUtils.mkdir_p(dirname)
- permissions = 0o600 & (~File.umask)
+ Gem.load_yaml
+
+ permissions = 0600 & (~File.umask)
File.open(credentials_path, "w", permissions) do |f|
- f.write self.class.dump_with_rubygems_yaml(config)
+ f.write config.to_yaml
end
load_api_keys # reload
@@ -354,18 +344,20 @@ if you believe they were disclosed to a third party.
end
def load_file(filename)
+ Gem.load_yaml
+
yaml_errors = [ArgumentError]
+ yaml_errors << Psych::SyntaxError if defined?(Psych::SyntaxError)
return {} unless filename && !filename.empty? && File.exist?(filename)
begin
- config = self.class.load_with_rubygems_config_hash(File.read(filename))
- if config.keys.any? {|k| k.to_s.gsub(%r{https?:\/\/}, "").include?(": ") }
+ content = Gem::SafeYAML.load(File.read(filename))
+ unless content.kind_of? Hash
warn "Failed to load #{filename} because it doesn't contain valid YAML hash"
return {}
- else
- return config
end
+ return content
rescue *yaml_errors => e
warn "Failed to load #{filename}, #{e}"
rescue Errno::EACCES
@@ -485,17 +477,17 @@ if you believe they were disclosed to a third party.
yaml_hash[:ssl_client_cert] =
@hash[:ssl_client_cert] if @hash.key? :ssl_client_cert
- keys = yaml_hash.keys.map(&:to_s)
+ keys = yaml_hash.keys.map {|key| key.to_s }
keys << "debug"
re = Regexp.union(*keys)
@hash.each do |key, value|
key = key.to_s
- next if key&.match?(re)
+ next if key =~ re
yaml_hash[key.to_s] = value
end
- self.class.dump_with_rubygems_yaml(yaml_hash)
+ yaml_hash.to_yaml
end
# Writes out this config file, replacing its source.
@@ -530,57 +522,6 @@ if you believe they were disclosed to a third party.
attr_reader :hash
protected :hash
- def self.dump_with_rubygems_yaml(content)
- content.transform_keys! do |k|
- k.is_a?(Symbol) ? ":#{k}" : k
- end
-
- require_relative "yaml_serializer"
- Gem::YAMLSerializer.dump(content)
- end
-
- def self.load_with_rubygems_config_hash(yaml)
- require_relative "yaml_serializer"
-
- content = Gem::YAMLSerializer.load(yaml)
-
- content.transform_keys! do |k|
- if k.match?(/\A:(.*)\Z/)
- k[1..-1].to_sym
- elsif k.include?("__") || k.match?(%r{/\Z})
- if k.is_a?(Symbol)
- k.to_s.gsub(/__/,".").gsub(%r{/\Z}, "").to_sym
- else
- k.dup.gsub(/__/,".").gsub(%r{/\Z}, "")
- end
- else
- k
- end
- end
-
- content.transform_values! do |v|
- if v.is_a?(String)
- if v.match?(/\A:(.*)\Z/)
- v[1..-1].to_sym
- elsif v.match?(/\A[+-]?\d+\Z/)
- v.to_i
- elsif v.match?(/\Atrue|false\Z/)
- v == "true"
- elsif v.empty?
- nil
- else
- v
- end
- elsif v.is_a?(Hash) && v.empty?
- nil
- else
- v
- end
- end
-
- content
- end
-
private
def set_config_file_name(args)
@@ -593,7 +534,7 @@ if you believe they were disclosed to a third party.
need_config_file_name = false
elsif arg =~ /^--config-file=(.*)/
@config_file_name = $1
- elsif /^--config-file$/.match?(arg)
+ elsif arg =~ /^--config-file$/
need_config_file_name = true
end
end
diff --git a/lib/rubygems/core_ext/kernel_gem.rb b/lib/rubygems/core_ext/kernel_gem.rb
index 4e09b95c44..b2f97b9ed9 100644
--- a/lib/rubygems/core_ext/kernel_gem.rb
+++ b/lib/rubygems/core_ext/kernel_gem.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
module Kernel
+
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
@@ -36,9 +37,9 @@ module Kernel
skip_list = (ENV["GEM_SKIP"] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
- if gem_name.is_a? Gem::Dependency
+ if gem_name.kind_of? Gem::Dependency
unless Gem::Deprecate.skip
- warn "#{Gem.location_of_caller.join ":"}:Warning: Kernel.gem no longer "\
+ warn "#{Gem.location_of_caller.join ':'}:Warning: Kernel.gem no longer "\
"accepts a Gem::Dependency object, please pass the name "\
"and requirements directly"
end
@@ -65,4 +66,5 @@ module Kernel
end
private :gem
+
end
diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb
index 073966b696..0869c8746f 100644
--- a/lib/rubygems/core_ext/kernel_require.rb
+++ b/lib/rubygems/core_ext/kernel_require.rb
@@ -9,12 +9,13 @@
require "monitor"
module Kernel
+
RUBYGEMS_ACTIVATION_MONITOR = Monitor.new # :nodoc:
# Make sure we have a reference to Ruby's original Kernel#require
unless defined?(gem_original_require)
# :stopdoc:
- alias_method :gem_original_require, :require
+ alias gem_original_require require
private :gem_original_require
# :startdoc:
end
@@ -36,45 +37,53 @@ module Kernel
def require(path) # :doc:
return gem_original_require(path) unless Gem.discover_gems_on_require
- RUBYGEMS_ACTIVATION_MONITOR.synchronize do
- path = File.path(path)
-
- # If +path+ belongs to a default gem, we activate it and then go straight
- # to normal require
-
- if spec = Gem.find_default_spec(path)
- name = spec.name
+ begin
+ RUBYGEMS_ACTIVATION_MONITOR.enter
- next if Gem.loaded_specs[name]
+ path = path.to_path if path.respond_to? :to_path
+ if spec = Gem.find_unresolved_default_spec(path)
# Ensure -I beats a default gem
resolved_path = begin
rp = nil
load_path_check_index = Gem.load_path_insert_index - Gem.activated_gem_paths
- Gem.suffixes.find do |s|
- $LOAD_PATH[0...load_path_check_index].find do |lp|
- if File.symlink? lp # for backward compatibility
- next
+ Gem.suffixes.each do |s|
+ $LOAD_PATH[0...load_path_check_index].each do |lp|
+ safe_lp = lp.dup.tap(&Gem::UNTAINT)
+ begin
+ if File.symlink? safe_lp # for backward compatibility
+ next
+ end
+ rescue SecurityError
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ raise
end
- full_path = File.expand_path(File.join(lp, "#{path}#{s}"))
- rp = full_path if File.file?(full_path)
+ full_path = File.expand_path(File.join(safe_lp, "#{path}#{s}"))
+ if File.file?(full_path)
+ rp = full_path
+ break
+ end
end
+ break if rp
end
rp
end
- Kernel.send(:gem, name, Gem::Requirement.default_prerelease) unless
- resolved_path
-
- next
+ begin
+ Kernel.send(:gem, spec.name, Gem::Requirement.default_prerelease)
+ rescue Exception
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ raise
+ end unless resolved_path
end
# If there are no unresolved deps, then we can use just try
# normal require handle loading a gem from the rescue below.
if Gem::Specification.unresolved_deps.empty?
- next
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
end
# If +path+ is for a gem that has already been loaded, don't
@@ -84,7 +93,8 @@ module Kernel
# TODO request access to the C implementation of this to speed up RubyGems
if Gem::Specification.find_active_stub_by_path(path)
- next
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
end
# Attempt to find +path+ in any unresolved gems...
@@ -104,7 +114,9 @@ module Kernel
if found_specs.empty?
found_specs = Gem::Specification.find_in_unresolved_tree path
- found_specs.each(&:activate)
+ found_specs.each do |found_spec|
+ found_spec.activate
+ end
# We found +path+ directly in an unresolved gem. Now we figure out, of
# the possible found specs, which one we should activate.
@@ -115,7 +127,8 @@ module Kernel
names = found_specs.map(&:name).uniq
if names.size > 1
- raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ", "}"
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ', '}"
end
# Ok, now find a gem that has no conflicts, starting
@@ -125,20 +138,26 @@ module Kernel
unless valid
le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
le.name = names.first
+ RUBYGEMS_ACTIVATION_MONITOR.exit
raise le
end
valid.activate
end
- end
- begin
- gem_original_require(path)
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(path)
rescue LoadError => load_error
- if load_error.path == path &&
- RUBYGEMS_ACTIVATION_MONITOR.synchronize { Gem.try_activate(path) }
+ if load_error.path == path
+ RUBYGEMS_ACTIVATION_MONITOR.enter
- return gem_original_require(path)
+ begin
+ require_again = Gem.try_activate(path)
+ ensure
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ end
+
+ return gem_original_require(path) if require_again
end
raise load_error
@@ -146,4 +165,5 @@ module Kernel
end
private :require
+
end
diff --git a/lib/rubygems/core_ext/kernel_warn.rb b/lib/rubygems/core_ext/kernel_warn.rb
index 9dc9f2218c..1f4c77f04b 100644
--- a/lib/rubygems/core_ext/kernel_warn.rb
+++ b/lib/rubygems/core_ext/kernel_warn.rb
@@ -35,10 +35,11 @@ module Kernel
start += 1
- next unless path = loc.path
- unless path.start_with?(rubygems_path, "<internal:")
- # Non-rubygems frames
- uplevel -= 1
+ if path = loc.path
+ unless path.start_with?(rubygems_path) || path.start_with?("<internal:")
+ # Non-rubygems frames
+ uplevel -= 1
+ end
end
end
kw[:uplevel] = start
diff --git a/lib/rubygems/core_ext/tcpsocket_init.rb b/lib/rubygems/core_ext/tcpsocket_init.rb
index 018c49dbeb..451ffa50b2 100644
--- a/lib/rubygems/core_ext/tcpsocket_init.rb
+++ b/lib/rubygems/core_ext/tcpsocket_init.rb
@@ -19,7 +19,7 @@ module CoreExtensions
cond_var = Thread::ConditionVariable.new
Addrinfo.foreach(host, serv, nil, :STREAM) do |addr|
- Thread.report_on_exception = false
+ Thread.report_on_exception = false if defined? Thread.report_on_exception = ()
threads << Thread.new(addr) do
# give head start to ipv6 addresses
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index ca161a4d95..2b1baa333d 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -24,7 +24,7 @@ module Gem
default_spec_cache_dir = File.join Gem.user_home, ".gem", "specs"
unless File.exist?(default_spec_cache_dir)
- default_spec_cache_dir = File.join Gem.cache_home, "gem", "specs"
+ default_spec_cache_dir = File.join Gem.data_home, "gem", "specs"
end
default_spec_cache_dir
@@ -80,7 +80,7 @@ module Gem
def self.find_home
Dir.home.dup
- rescue StandardError
+ rescue
if Gem.win_platform?
File.expand_path File.join(ENV["HOMEDRIVE"] || ENV["SystemDrive"], "/")
else
@@ -94,7 +94,7 @@ module Gem
# The home directory for the user.
def self.user_home
- @user_home ||= find_home
+ @user_home ||= find_home.tap(&Gem::UNTAINT)
end
##
@@ -112,7 +112,7 @@ module Gem
# The path to standard location of the user's configuration directory.
def self.config_home
- @config_home ||= ENV["XDG_CONFIG_HOME"] || File.join(Gem.user_home, ".config")
+ @config_home ||= (ENV["XDG_CONFIG_HOME"] || File.join(Gem.user_home, ".config"))
end
##
@@ -131,35 +131,35 @@ module Gem
# The path to standard location of the user's .gemrc file.
def self.config_file
- @config_file ||= find_config_file
+ @config_file ||= find_config_file.tap(&Gem::UNTAINT)
end
##
# The path to standard location of the user's state file.
def self.state_file
- @state_file ||= File.join(Gem.state_home, "gem", "last_update_check")
+ @state_file ||= File.join(Gem.state_home, "gem", "last_update_check").tap(&Gem::UNTAINT)
end
##
# The path to standard location of the user's cache directory.
def self.cache_home
- @cache_home ||= ENV["XDG_CACHE_HOME"] || File.join(Gem.user_home, ".cache")
+ @cache_home ||= (ENV["XDG_CACHE_HOME"] || File.join(Gem.user_home, ".cache"))
end
##
# The path to standard location of the user's data directory.
def self.data_home
- @data_home ||= ENV["XDG_DATA_HOME"] || File.join(Gem.user_home, ".local", "share")
+ @data_home ||= (ENV["XDG_DATA_HOME"] || File.join(Gem.user_home, ".local", "share"))
end
##
# The path to standard location of the user's state directory.
def self.state_home
- @state_home ||= ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state")
+ @state_home ||= (ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state"))
end
##
@@ -184,11 +184,7 @@ module Gem
# Deduce Ruby's --program-prefix and --program-suffix from its install name
def self.default_exec_format
- exec_format = begin
- RbConfig::CONFIG["ruby_install_name"].sub("ruby", "%s")
- rescue StandardError
- "%s"
- end
+ exec_format = RbConfig::CONFIG["ruby_install_name"].sub("ruby", "%s") rescue "%s"
unless exec_format.include?("%s")
raise Gem::Exception,
@@ -236,18 +232,6 @@ module Gem
end
##
- # Enables automatic installation into user directory
-
- def self.default_user_install # :nodoc:
- if !ENV.key?("GEM_HOME") && (File.exist?(Gem.dir) && !File.writable?(Gem.dir))
- Gem.ui.say "Defaulting to user installation because default installation directory (#{Gem.dir}) is not writable."
- return true
- end
-
- false
- end
-
- ##
# Install extensions into lib as well as into the extension directory.
def self.install_extension_in_lib # :nodoc:
diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb
index 5ce9c5e840..d9e0c07b0f 100644
--- a/lib/rubygems/dependency.rb
+++ b/lib/rubygems/dependency.rb
@@ -46,10 +46,10 @@ class Gem::Dependency
end
type = Symbol === requirements.last ? requirements.pop : :runtime
- requirements = requirements.first if requirements.length == 1 # unpack
+ requirements = requirements.first if 1 == requirements.length # unpack
unless TYPES.include? type
- raise ArgumentError, "Valid types are #{TYPES.inspect}, " \
+ raise ArgumentError, "Valid types are #{TYPES.inspect}, " +
"not #{type.inspect}"
end
@@ -74,9 +74,11 @@ class Gem::Dependency
def inspect # :nodoc:
if prerelease?
- format("<%s type=%p name=%p requirements=%p prerelease=ok>", self.class, type, name, requirement.to_s)
+ "<%s type=%p name=%p requirements=%p prerelease=ok>" %
+ [self.class, self.type, self.name, requirement.to_s]
else
- format("<%s type=%p name=%p requirements=%p>", self.class, type, name, requirement.to_s)
+ "<%s type=%p name=%p requirements=%p>" %
+ [self.class, self.type, self.name, requirement.to_s]
end
end
@@ -167,16 +169,16 @@ class Gem::Dependency
def ==(other) # :nodoc:
Gem::Dependency === other &&
- name == other.name &&
- type == other.type &&
- requirement == other.requirement
+ self.name == other.name &&
+ self.type == other.type &&
+ self.requirement == other.requirement
end
##
# Dependencies are ordered by name.
def <=>(other)
- name <=> other.name
+ self.name <=> other.name
end
##
@@ -203,7 +205,7 @@ class Gem::Dependency
requirement.satisfied_by? version
end
- alias_method :===, :=~
+ alias === =~
##
# :call-seq:
@@ -261,7 +263,7 @@ class Gem::Dependency
end
default = Gem::Requirement.default
- self_req = requirement
+ self_req = self.requirement
other_req = other.requirement
return self.class.new name, self_req if other_req == default
@@ -271,7 +273,15 @@ class Gem::Dependency
end
def matching_specs(platform_only = false)
- matches = Gem::Specification.find_all_by_name(name, requirement)
+ env_req = Gem.env_requirement(name)
+ matches = Gem::Specification.stubs_for(name).find_all do |spec|
+ requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
+ end.map(&:to_spec)
+
+ if prioritizes_bundler?
+ require_relative "bundler_version_finder"
+ Gem::BundlerVersionFinder.prioritize!(matches)
+ end
if platform_only
matches.reject! do |spec|
@@ -289,6 +299,10 @@ class Gem::Dependency
@requirement.specific?
end
+ def prioritizes_bundler?
+ name == "bundler" && !specific?
+ end
+
def to_specs
matches = matching_specs true
@@ -310,15 +324,15 @@ class Gem::Dependency
end
def to_spec
- matches = to_specs.compact
+ matches = self.to_specs.compact
- active = matches.find(&:activated?)
+ active = matches.find {|spec| spec.activated? }
return active if active
unless prerelease?
- # Consider prereleases only as a fallback
+ # Move prereleases to the end of the list for >= 0 requirements
pre, matches = matches.partition {|spec| spec.version.prerelease? }
- matches = pre if matches.empty?
+ matches += pre if requirement == Gem::Requirement.default
end
matches.first
diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb
index b119dca1cf..a8d73e521b 100644
--- a/lib/rubygems/dependency_installer.rb
+++ b/lib/rubygems/dependency_installer.rb
@@ -17,18 +17,18 @@ class Gem::DependencyInstaller
extend Gem::Deprecate
DEFAULT_OPTIONS = { # :nodoc:
- env_shebang: false,
- document: %w[ri],
- domain: :both, # HACK: dup
- force: false,
- format_executable: false, # HACK: dup
- ignore_dependencies: false,
- prerelease: false,
- security_policy: nil, # HACK: NoSecurity requires OpenSSL. AlmostNo? Low?
- wrappers: true,
- build_args: nil,
- build_docs_in_background: false,
- install_as_default: false,
+ :env_shebang => false,
+ :document => %w[ri],
+ :domain => :both, # HACK dup
+ :force => false,
+ :format_executable => false, # HACK dup
+ :ignore_dependencies => false,
+ :prerelease => false,
+ :security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low?
+ :wrappers => true,
+ :build_args => nil,
+ :build_docs_in_background => false,
+ :install_as_default => false,
}.freeze
##
@@ -66,7 +66,7 @@ class Gem::DependencyInstaller
# :build_args:: See Gem::Installer::new
def initialize(options = {})
- @only_install_dir = !options[:install_dir].nil?
+ @only_install_dir = !!options[:install_dir]
@install_dir = options[:install_dir] || Gem.dir
@build_root = options[:build_root]
@@ -163,11 +163,13 @@ class Gem::DependencyInstaller
specs = []
tuples.each do |tup, source|
- spec = source.fetch_spec(tup)
- rescue Gem::RemoteFetcher::FetchError => e
- errors << Gem::SourceFetchProblem.new(source, e)
- else
- specs << [spec, source]
+ begin
+ spec = source.fetch_spec(tup)
+ rescue Gem::RemoteFetcher::FetchError => e
+ errors << Gem::SourceFetchProblem.new(source, e)
+ else
+ specs << [spec, source]
+ end
end
if @errors
@@ -177,6 +179,7 @@ class Gem::DependencyInstaller
end
set << specs
+
rescue Gem::RemoteFetcher::FetchError => e
# FIX if there is a problem talking to the network, we either need to always tell
# the user (no really_verbose) or fail hard, not silently tell them that we just
@@ -228,22 +231,22 @@ class Gem::DependencyInstaller
@installed_gems = []
options = {
- bin_dir: @bin_dir,
- build_args: @build_args,
- document: @document,
- env_shebang: @env_shebang,
- force: @force,
- format_executable: @format_executable,
- ignore_dependencies: @ignore_dependencies,
- prerelease: @prerelease,
- security_policy: @security_policy,
- user_install: @user_install,
- wrappers: @wrappers,
- build_root: @build_root,
- install_as_default: @install_as_default,
- dir_mode: @dir_mode,
- data_mode: @data_mode,
- prog_mode: @prog_mode,
+ :bin_dir => @bin_dir,
+ :build_args => @build_args,
+ :document => @document,
+ :env_shebang => @env_shebang,
+ :force => @force,
+ :format_executable => @format_executable,
+ :ignore_dependencies => @ignore_dependencies,
+ :prerelease => @prerelease,
+ :security_policy => @security_policy,
+ :user_install => @user_install,
+ :wrappers => @wrappers,
+ :build_root => @build_root,
+ :install_as_default => @install_as_default,
+ :dir_mode => @dir_mode,
+ :data_mode => @data_mode,
+ :prog_mode => @prog_mode,
}
options[:install_dir] = @install_dir if @only_install_dir
@@ -291,11 +294,13 @@ class Gem::DependencyInstaller
src = Gem::Source::SpecificFile.new dep_or_name
installer_set.add_local dep_or_name, src.spec, src
version = src.spec.version if version == Gem::Requirement.default
- elsif dep_or_name =~ /\.gem$/ # rubocop:disable Performance/RegexpMatch
+ elsif dep_or_name =~ /\.gem$/
Dir[dep_or_name].each do |name|
- src = Gem::Source::SpecificFile.new name
- installer_set.add_local dep_or_name, src.spec, src
- rescue Gem::Package::FormatError
+ begin
+ src = Gem::Source::SpecificFile.new name
+ installer_set.add_local dep_or_name, src.spec, src
+ rescue Gem::Package::FormatError
+ end
end
# else This is a dependency. InstallerSet handles this case
end
diff --git a/lib/rubygems/dependency_list.rb b/lib/rubygems/dependency_list.rb
index ad5e59e8c1..5820298bb9 100644
--- a/lib/rubygems/dependency_list.rb
+++ b/lib/rubygems/dependency_list.rb
@@ -6,7 +6,7 @@
# See LICENSE.txt for permissions.
#++
-require_relative "vendored_tsort"
+require_relative "tsort"
require_relative "deprecate"
##
@@ -105,7 +105,7 @@ class Gem::DependencyList
end
def inspect # :nodoc:
- format("%s %p>", super[0..-2], map(&:full_name))
+ "%s %p>" % [super[0..-2], map {|s| s.full_name }]
end
##
diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb
index 7d24f9cbfc..9fff306949 100644
--- a/lib/rubygems/deprecate.rb
+++ b/lib/rubygems/deprecate.rb
@@ -69,101 +69,97 @@
# end
# end
-module Gem
- module Deprecate
- def self.skip # :nodoc:
- @skip ||= false
- end
+module Gem::Deprecate
- def self.skip=(v) # :nodoc:
- @skip = v
- end
+ def self.skip # :nodoc:
+ @skip ||= false
+ end
- ##
- # Temporarily turn off warnings. Intended for tests only.
+ def self.skip=(v) # :nodoc:
+ @skip = v
+ end
- def skip_during
- original = Gem::Deprecate.skip
- Gem::Deprecate.skip = true
- yield
- ensure
- Gem::Deprecate.skip = original
- end
+ ##
+ # Temporarily turn off warnings. Intended for tests only.
- def self.next_rubygems_major_version # :nodoc:
- Gem::Version.new(Gem.rubygems_version.segments.first).bump
- end
+ def skip_during
+ Gem::Deprecate.skip, original = true, Gem::Deprecate.skip
+ yield
+ ensure
+ Gem::Deprecate.skip = original
+ end
+
+ def self.next_rubygems_major_version # :nodoc:
+ Gem::Version.new(Gem.rubygems_version.segments.first).bump
+ end
+
+ ##
+ # Simple deprecation method that deprecates +name+ by wrapping it up
+ # in a dummy method. It warns on each call to the dummy method
+ # telling the user of +repl+ (unless +repl+ is :none) and the
+ # year/month that it is planned to go away.
- ##
- # Simple deprecation method that deprecates +name+ by wrapping it up
- # in a dummy method. It warns on each call to the dummy method
- # telling the user of +repl+ (unless +repl+ is :none) and the
- # year/month that it is planned to go away.
-
- def deprecate(name, repl, year, month)
- class_eval do
- old = "_deprecated_#{name}"
- alias_method old, name
- define_method name do |*args, &block|
- klass = is_a? Module
- target = klass ? "#{self}." : "#{self.class}#"
- msg = [
- "NOTE: #{target}#{name} is deprecated",
- repl == :none ? " with no replacement" : "; use #{repl} instead",
- format(". It will be removed on or after %4d-%02d.", year, month),
- "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
- ]
- warn "#{msg.join}." unless Gem::Deprecate.skip
- send old, *args, &block
- end
- ruby2_keywords name if respond_to?(:ruby2_keywords, true)
+ def deprecate(name, repl, year, month)
+ class_eval do
+ old = "_deprecated_#{name}"
+ alias_method old, name
+ define_method name do |*args, &block|
+ klass = self.kind_of? Module
+ target = klass ? "#{self}." : "#{self.class}#"
+ msg = [ "NOTE: #{target}#{name} is deprecated",
+ repl == :none ? " with no replacement" : "; use #{repl} instead",
+ ". It will be removed on or after %4d-%02d." % [year, month],
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
+ ]
+ warn "#{msg.join}." unless Gem::Deprecate.skip
+ send old, *args, &block
end
+ ruby2_keywords name if respond_to?(:ruby2_keywords, true)
end
+ end
+
+ ##
+ # Simple deprecation method that deprecates +name+ by wrapping it up
+ # in a dummy method. It warns on each call to the dummy method
+ # telling the user of +repl+ (unless +repl+ is :none) and the
+ # Rubygems version that it is planned to go away.
- ##
- # Simple deprecation method that deprecates +name+ by wrapping it up
- # in a dummy method. It warns on each call to the dummy method
- # telling the user of +repl+ (unless +repl+ is :none) and the
- # Rubygems version that it is planned to go away.
-
- def rubygems_deprecate(name, replacement=:none)
- class_eval do
- old = "_deprecated_#{name}"
- alias_method old, name
- define_method name do |*args, &block|
- klass = is_a? Module
- target = klass ? "#{self}." : "#{self.class}#"
- msg = [
- "NOTE: #{target}#{name} is deprecated",
- replacement == :none ? " with no replacement" : "; use #{replacement} instead",
- ". It will be removed in Rubygems #{Gem::Deprecate.next_rubygems_major_version}",
- "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
- ]
- warn "#{msg.join}." unless Gem::Deprecate.skip
- send old, *args, &block
- end
- ruby2_keywords name if respond_to?(:ruby2_keywords, true)
+ def rubygems_deprecate(name, replacement=:none)
+ class_eval do
+ old = "_deprecated_#{name}"
+ alias_method old, name
+ define_method name do |*args, &block|
+ klass = self.kind_of? Module
+ target = klass ? "#{self}." : "#{self.class}#"
+ msg = [ "NOTE: #{target}#{name} is deprecated",
+ replacement == :none ? " with no replacement" : "; use #{replacement} instead",
+ ". It will be removed in Rubygems #{Gem::Deprecate.next_rubygems_major_version}",
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
+ ]
+ warn "#{msg.join}." unless Gem::Deprecate.skip
+ send old, *args, &block
end
+ ruby2_keywords name if respond_to?(:ruby2_keywords, true)
end
+ end
- # Deprecation method to deprecate Rubygems commands
- def rubygems_deprecate_command(version = Gem::Deprecate.next_rubygems_major_version)
- class_eval do
- define_method "deprecated?" do
- true
- end
-
- define_method "deprecation_warning" do
- msg = [
- "#{command} command is deprecated",
- ". It will be removed in Rubygems #{version}.\n",
- ]
-
- alert_warning msg.join.to_s unless Gem::Deprecate.skip
- end
+ # Deprecation method to deprecate Rubygems commands
+ def rubygems_deprecate_command(version = Gem::Deprecate.next_rubygems_major_version)
+ class_eval do
+ define_method "deprecated?" do
+ true
end
- end
- module_function :rubygems_deprecate, :rubygems_deprecate_command, :skip_during
+ define_method "deprecation_warning" do
+ msg = [ "#{self.command} command is deprecated",
+ ". It will be removed in Rubygems #{version}.\n",
+ ]
+
+ alert_warning "#{msg.join}" unless Gem::Deprecate.skip
+ end
+ end
end
+
+ module_function :rubygems_deprecate, :rubygems_deprecate_command, :skip_during
+
end
diff --git a/lib/rubygems/doctor.rb b/lib/rubygems/doctor.rb
index 56b7c081eb..1d3889af77 100644
--- a/lib/rubygems/doctor.rb
+++ b/lib/rubygems/doctor.rb
@@ -33,7 +33,7 @@ class Gem::Doctor
Gem::REPOSITORY_SUBDIRECTORIES.sort -
REPOSITORY_EXTENSION_MAP.map {|(k,_)| k }.sort
- raise "Update REPOSITORY_EXTENSION_MAP, missing: #{missing.join ", "}" unless
+ raise "Update REPOSITORY_EXTENSION_MAP, missing: #{missing.join ', '}" unless
missing.empty?
##
@@ -53,7 +53,7 @@ class Gem::Doctor
# Specs installed in this gem repository
def installed_specs # :nodoc:
- @installed_specs ||= Gem::Specification.map(&:full_name)
+ @installed_specs ||= Gem::Specification.map {|s| s.full_name }
end
##
@@ -75,7 +75,7 @@ class Gem::Doctor
Gem.use_paths @gem_repository.to_s
unless gem_repository?
- say "This directory does not appear to be a RubyGems repository, " \
+ say "This directory does not appear to be a RubyGems repository, " +
"skipping"
say
return
@@ -104,16 +104,16 @@ class Gem::Doctor
directory = File.join(@gem_repository, sub_directory)
Dir.entries(directory).sort.each do |ent|
- next if [".", ".."].include?(ent)
+ next if ent == "." || ent == ".."
child = File.join(directory, ent)
next unless File.exist?(child)
basename = File.basename(child, extension)
next if installed_specs.include? basename
- next if /^rubygems-\d/.match?(basename)
- next if sub_directory == "specifications" && basename == "default"
- next if sub_directory == "plugins" && Gem.plugin_suffix_regexp =~ (basename)
+ next if /^rubygems-\d/ =~ basename
+ next if "specifications" == sub_directory && "default" == basename
+ next if "plugins" == sub_directory && Gem.plugin_suffix_regexp =~ (basename)
type = File.directory?(child) ? "directory" : "file"
diff --git a/lib/rubygems/errors.rb b/lib/rubygems/errors.rb
index be6c34dc85..b36fabffc2 100644
--- a/lib/rubygems/errors.rb
+++ b/lib/rubygems/errors.rb
@@ -61,7 +61,7 @@ module Gem
def build_message
names = specs.map(&:full_name)
- "Could not find '#{name}' (#{requirement}) - did find: [#{names.join ","}]\n"
+ "Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n"
end
end
@@ -134,7 +134,11 @@ module Gem
##
# A wordy description of the error.
def wordy
- format("Found %s (%s), but was for platform%s %s", @name, @version, @platforms.size == 1 ? "" : "s", @platforms.join(" ,"))
+ "Found %s (%s), but was for platform%s %s" %
+ [@name,
+ @version,
+ @platforms.size == 1 ? "" : "s",
+ @platforms.join(" ,")]
end
end
@@ -171,6 +175,6 @@ module Gem
##
# The "exception" alias allows you to call raise on a SourceFetchProblem.
- alias_method :exception, :error
+ alias exception error
end
end
diff --git a/lib/rubygems/exceptions.rb b/lib/rubygems/exceptions.rb
index 65caaab8b1..b92396f0ef 100644
--- a/lib/rubygems/exceptions.rb
+++ b/lib/rubygems/exceptions.rb
@@ -172,7 +172,6 @@ class Gem::ImpossibleDependenciesError < Gem::Exception
end
class Gem::InstallError < Gem::Exception; end
-
class Gem::RuntimeRequirementNotMetError < Gem::InstallError
attr_accessor :suggestion
def message
@@ -232,7 +231,7 @@ class Gem::SystemExitException < SystemExit
##
# The exit code for the process
- alias_method :exit_code, :status
+ alias exit_code status
##
# Creates a new SystemExitException with the given +exit_code+
@@ -265,7 +264,7 @@ class Gem::UnsatisfiableDependencyError < Gem::DependencyError
def initialize(dep, platform_mismatch=nil)
if platform_mismatch && !platform_mismatch.empty?
plats = platform_mismatch.map {|x| x.platform.to_s }.sort.uniq
- super "Unable to resolve dependency: No match for '#{dep}' on this platform. Found: #{plats.join(", ")}"
+ super "Unable to resolve dependency: No match for '#{dep}' on this platform. Found: #{plats.join(', ')}"
else
if dep.explicit?
super "Unable to resolve dependency: user requested '#{dep}'"
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index be1ba3031c..4960ddd7b1 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -27,17 +27,19 @@ class Gem::Ext::Builder
# try to find make program from Ruby configure arguments first
RbConfig::CONFIG["configure_args"] =~ /with-make-prog\=(\w+)/
make_program_name = ENV["MAKE"] || ENV["make"] || $1
- make_program_name ||= RUBY_PLATFORM.include?("mswin") ? "nmake" : "make"
+ unless make_program_name
+ make_program_name = (RUBY_PLATFORM.include?("mswin")) ? "nmake" : "make"
+ end
make_program = Shellwords.split(make_program_name)
# The installation of the bundled gems is failed when DESTDIR is empty in mswin platform.
- destdir = /\bnmake/i !~ make_program_name || ENV["DESTDIR"] && ENV["DESTDIR"] != "" ? format("DESTDIR=%s", ENV["DESTDIR"]) : ""
+ destdir = (/\bnmake/i !~ make_program_name || ENV["DESTDIR"] && ENV["DESTDIR"] != "") ? "DESTDIR=%s" % ENV["DESTDIR"] : ""
env = [destdir]
if sitedir
- env << format("sitearchdir=%s", sitedir)
- env << format("sitelibdir=%s", sitedir)
+ env << "sitearchdir=%s" % sitedir
+ env << "sitelibdir=%s" % sitedir
end
targets.each do |target|
@@ -75,8 +77,7 @@ class Gem::Ext::Builder
verbose = Gem.configuration.really_verbose
begin
- rubygems_gemdeps = ENV["RUBYGEMS_GEMDEPS"]
- ENV["RUBYGEMS_GEMDEPS"] = nil
+ rubygems_gemdeps, ENV["RUBYGEMS_GEMDEPS"] = ENV["RUBYGEMS_GEMDEPS"], nil
if verbose
puts("current directory: #{dir}")
p(command)
@@ -88,20 +89,13 @@ class Gem::Ext::Builder
# Set $SOURCE_DATE_EPOCH for the subprocess.
build_env = { "SOURCE_DATE_EPOCH" => Gem.source_date_epoch_string }.merge(env)
output, status = begin
- Open3.popen2e(build_env, *command, chdir: dir) do |_stdin, stdouterr, wait_thread|
- output = String.new
- while line = stdouterr.gets
- output << line
- if verbose
- print line
- end
- end
- [output, wait_thread.value]
- end
- rescue StandardError => error
+ Open3.capture2e(build_env, *command, :chdir => dir)
+ rescue => error
raise Gem::InstallError, "#{command_name || class_name} failed#{error.message}"
end
- unless verbose
+ if verbose
+ puts output
+ else
results << output
end
ensure
@@ -196,7 +190,7 @@ EOF
verbose { results.join("\n") }
write_gem_make_out results.join "\n"
- rescue StandardError => e
+ rescue => e
results << e.message
build_error(results.join("\n"), $@)
end
@@ -212,7 +206,7 @@ EOF
if @build_args.empty?
say "Building native extensions. This could take a while..."
else
- say "Building native extensions with: '#{@build_args.join " "}'"
+ say "Building native extensions with: '#{@build_args.join ' '}'"
say "This could take a while..."
end
diff --git a/lib/rubygems/ext/cargo_builder.rb b/lib/rubygems/ext/cargo_builder.rb
index f0537ab693..ce3b296f79 100644
--- a/lib/rubygems/ext/cargo_builder.rb
+++ b/lib/rubygems/ext/cargo_builder.rb
@@ -185,7 +185,6 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
end
def cargo_dylib_path(dest_path, crate_name)
- so_ext = RbConfig::CONFIG["SOEXT"]
prefix = so_ext == "dll" ? "" : "lib"
path_parts = [dest_path]
path_parts << ENV["CARGO_BUILD_TARGET"] if ENV["CARGO_BUILD_TARGET"]
@@ -199,8 +198,8 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
output, status =
begin
- Open3.capture2e(cargo, "metadata", "--no-deps", "--format-version", "1", chdir: cargo_dir)
- rescue StandardError => error
+ Open3.capture2e(cargo, "metadata", "--no-deps", "--format-version", "1", :chdir => cargo_dir)
+ rescue => error
raise Gem::InstallError, "cargo metadata failed #{error.message}"
end
@@ -247,10 +246,10 @@ EOF
end
def rustc_dynamic_linker_flags(dest_dir, crate_name)
- split_flags("DLDFLAGS").
- map {|arg| maybe_resolve_ldflag_variable(arg, dest_dir, crate_name) }.
- compact.
- flat_map {|arg| ldflag_to_link_modifier(arg) }
+ split_flags("DLDFLAGS")
+ .map {|arg| maybe_resolve_ldflag_variable(arg, dest_dir, crate_name) }
+ .compact
+ .flat_map {|arg| ldflag_to_link_modifier(arg) }
end
def rustc_lib_flags(dest_dir)
@@ -294,7 +293,7 @@ EOF
case var_name
# On windows, it is assumed that mkmf has setup an exports file for the
- # extension, so we have to create one ourselves.
+ # extension, so we have to to create one ourselves.
when "DEFFILE"
write_deffile(dest_dir, crate_name)
else
@@ -314,6 +313,22 @@ EOF
deffile_path
end
+ # We have to basically reimplement RbConfig::CONFIG['SOEXT'] here to support
+ # Ruby < 2.5
+ #
+ # @see https://github.com/ruby/ruby/blob/c87c027f18c005460746a74c07cd80ee355b16e4/configure.ac#L3185
+ def so_ext
+ return RbConfig::CONFIG["SOEXT"] if RbConfig::CONFIG.key?("SOEXT")
+
+ if win_target?
+ "dll"
+ elsif darwin_target?
+ "dylib"
+ else
+ "so"
+ end
+ end
+
# Corresponds to $(LIBPATH) in mkmf
def mkmf_libpath
["-L", "native=#{makefile_config("libdir")}"]
diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb
index f38fe5947e..9c22329fe3 100644
--- a/lib/rubygems/ext/ext_conf_builder.rb
+++ b/lib/rubygems/ext/ext_conf_builder.rb
@@ -43,12 +43,12 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
full_tmp_dest = File.join(extension_dir, tmp_dest_relative)
- # TODO: remove in RubyGems 4
+ # TODO remove in RubyGems 4
if Gem.install_extension_in_lib && lib_dir
FileUtils.mkdir_p lib_dir
entries = Dir.entries(full_tmp_dest) - %w[. ..]
entries = entries.map {|entry| File.join full_tmp_dest, entry }
- FileUtils.cp_r entries, lib_dir, remove_destination: true
+ FileUtils.cp_r entries, lib_dir, :remove_destination => true
end
FileUtils::Entry_.new(full_tmp_dest).traverse do |ent|
@@ -66,6 +66,8 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
FileUtils.rm_rf tmp_dest if tmp_dest
end
+ private
+
def self.get_relative_path(path, base)
path[0..base.length - 1] = "." if path.start_with?(base)
path
diff --git a/lib/rubygems/ext/rake_builder.rb b/lib/rubygems/ext/rake_builder.rb
index 0171807b39..8f39a63e11 100644
--- a/lib/rubygems/ext/rake_builder.rb
+++ b/lib/rubygems/ext/rake_builder.rb
@@ -10,7 +10,7 @@ require_relative "../shellwords"
class Gem::Ext::RakeBuilder < Gem::Ext::Builder
def self.build(extension, dest_path, results, args=[], lib_dir=nil, extension_dir=Dir.pwd)
- if /mkrf_conf/i.match?(File.basename(extension))
+ if File.basename(extension) =~ /mkrf_conf/i
run([Gem.ruby, File.basename(extension), *args], results, class_name, extension_dir)
end
diff --git a/lib/rubygems/gem_runner.rb b/lib/rubygems/gem_runner.rb
index 8335a0ad03..d238a5863b 100644
--- a/lib/rubygems/gem_runner.rb
+++ b/lib/rubygems/gem_runner.rb
@@ -33,11 +33,7 @@ class Gem::GemRunner
do_configuration args
- begin
- Gem.load_env_plugins
- rescue StandardError
- nil
- end
+ Gem.load_env_plugins rescue nil
Gem.load_plugins
cmd = @command_manager_class.instance
@@ -45,10 +41,10 @@ class Gem::GemRunner
cmd.command_names.each do |command_name|
config_args = Gem.configuration[command_name]
config_args = case config_args
- when String
- config_args.split " "
- else
- Array(config_args)
+ when String
+ config_args.split " "
+ else
+ Array(config_args)
end
Gem::Command.add_specific_extra_args command_name, config_args
end
diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb
index a8361b7ff1..92739617f6 100644
--- a/lib/rubygems/gemcutter_utilities.rb
+++ b/lib/rubygems/gemcutter_utilities.rb
@@ -9,9 +9,9 @@ require_relative "gemcutter_utilities/webauthn_poller"
# Utility methods for using the RubyGems API.
module Gem::GemcutterUtilities
+
ERROR_CODE = 1
- API_SCOPES = [:index_rubygems, :push_rubygem, :yank_rubygem, :add_owner, :remove_owner, :access_webhooks].freeze
- EXCLUSIVELY_API_SCOPES = [:show_dashboard].freeze
+ API_SCOPES = %i[index_rubygems push_rubygem yank_rubygem add_owner remove_owner access_webhooks show_dashboard].freeze
include Gem::Text
@@ -85,7 +85,7 @@ module Gem::GemcutterUtilities
# If +allowed_push_host+ metadata is present, then it will only allow that host.
def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, scope: nil, credentials: {}, &block)
- require_relative "vendored_net_http"
+ require "net/http"
self.host = host if host
unless self.host
@@ -94,8 +94,8 @@ module Gem::GemcutterUtilities
end
if allowed_push_host
- allowed_host_uri = Gem::URI.parse(allowed_push_host)
- host_uri = Gem::URI.parse(self.host)
+ allowed_host_uri = URI.parse(allowed_push_host)
+ host_uri = URI.parse(self.host)
unless (host_uri.scheme == allowed_host_uri.scheme) && (host_uri.host == allowed_host_uri.host)
alert_error "#{self.host.inspect} is not allowed by the gemspec, which only allows #{allowed_push_host.inspect}"
@@ -103,7 +103,7 @@ module Gem::GemcutterUtilities
end
end
- uri = Gem::URI.parse "#{self.host}/#{path}"
+ uri = URI.parse "#{self.host}/#{path}"
response = request_with_otp(method, uri, &block)
if mfa_unauthorized?(response)
@@ -120,27 +120,27 @@ module Gem::GemcutterUtilities
end
def mfa_unauthorized?(response)
- response.is_a?(Gem::Net::HTTPUnauthorized) && response.body.start_with?("You have enabled multifactor authentication")
+ response.kind_of?(Net::HTTPUnauthorized) && response.body.start_with?("You have enabled multifactor authentication")
end
def update_scope(scope)
- sign_in_host = host
+ sign_in_host = self.host
pretty_host = pretty_host(sign_in_host)
update_scope_params = { scope => true }
say "The existing key doesn't have access of #{scope} on #{pretty_host}. Please sign in to update access."
- identifier = ask "Username/email: "
- password = ask_for_password " Password: "
+ email = ask " Email: "
+ password = ask_for_password "Password: "
response = rubygems_api_request(:put, "api/v1/api_key",
sign_in_host, scope: scope) do |request|
- request.basic_auth identifier, password
+ request.basic_auth email, password
request["OTP"] = otp if otp
- request.body = Gem::URI.encode_www_form({ api_key: api_key }.merge(update_scope_params))
+ request.body = URI.encode_www_form({ :api_key => api_key }.merge(update_scope_params))
end
- with_response response do |_resp|
+ with_response response do |resp|
say "Added #{scope} scope to the existing API key"
end
end
@@ -150,34 +150,34 @@ module Gem::GemcutterUtilities
# key.
def sign_in(sign_in_host = nil, scope: nil)
- sign_in_host ||= host
+ sign_in_host ||= self.host
return if api_key
pretty_host = pretty_host(sign_in_host)
say "Enter your #{pretty_host} credentials."
- say "Don't have an account yet? " \
+ say "Don't have an account yet? " +
"Create one at #{sign_in_host}/sign_up"
- identifier = ask "Username/email: "
- password = ask_for_password " Password: "
+ email = ask " Email: "
+ password = ask_for_password "Password: "
say "\n"
key_name = get_key_name(scope)
scope_params = get_scope_params(scope)
- profile = get_user_profile(identifier, password)
+ profile = get_user_profile(email, password)
mfa_params = get_mfa_params(profile)
all_params = scope_params.merge(mfa_params)
warning = profile["warning"]
- credentials = { identifier: identifier, password: password }
+ credentials = { email: email, password: password }
say "#{warning}\n" if warning
response = rubygems_api_request(:post, "api/v1/api_key",
sign_in_host, credentials: credentials, scope: scope) do |request|
- request.basic_auth identifier, password
+ request.basic_auth email, password
request["OTP"] = otp if otp
- request.body = Gem::URI.encode_www_form({ name: key_name }.merge(all_params))
+ request.body = URI.encode_www_form({ name: key_name }.merge(all_params))
end
with_response response do |resp|
@@ -209,14 +209,14 @@ module Gem::GemcutterUtilities
def with_response(response, error_prefix = nil)
case response
- when Gem::Net::HTTPSuccess then
+ when Net::HTTPSuccess then
if block_given?
yield response
else
say clean_text(response.body)
end
- when Gem::Net::HTTPPermanentRedirect, Gem::Net::HTTPRedirection then
- message = "The request has redirected permanently to #{response["location"]}. Please check your defined push host URL."
+ when Net::HTTPPermanentRedirect, Net::HTTPRedirection then
+ message = "The request has redirected permanently to #{response['location']}. Please check your defined push host URL."
message = "#{error_prefix}: #{message}" if error_prefix
say clean_text(message)
@@ -245,7 +245,7 @@ module Gem::GemcutterUtilities
private
def request_with_otp(method, uri, &block)
- request_method = Gem::Net::HTTP.const_get method.to_s.capitalize
+ request_method = Net::HTTP.const_get method.to_s.capitalize
Gem::RemoteFetcher.fetcher.request(uri, request_method) do |req|
req["OTP"] = otp if otp
@@ -295,10 +295,10 @@ module Gem::GemcutterUtilities
if credentials.empty?
request.add_field "Authorization", api_key
else
- request.basic_auth credentials[:identifier], credentials[:password]
+ request.basic_auth credentials[:email], credentials[:password]
end
end
- response.is_a?(Gem::Net::HTTPSuccess) ? response.body : nil
+ response.is_a?(Net::HTTPSuccess) ? response.body : nil
end
def pretty_host(host)
@@ -310,31 +310,15 @@ module Gem::GemcutterUtilities
end
def get_scope_params(scope)
- scope_params = { index_rubygems: true }
+ scope_params = {}
if scope
scope_params = { scope => true }
else
- say "The default access scope is:"
- scope_params.each do |k, _v|
- say " #{k}: y"
- end
- say "\n"
- customise = ask_yes_no("Do you want to customise scopes?", false)
- if customise
- EXCLUSIVELY_API_SCOPES.each do |excl_scope|
- selected = ask_yes_no("#{excl_scope} (exclusive scope, answering yes will not prompt for other scopes)", false)
- next unless selected
-
- return { excl_scope => true }
- end
-
- scope_params = {}
-
- API_SCOPES.each do |s|
- selected = ask_yes_no(s.to_s, false)
- scope_params[s] = true if selected
- end
+ say "Please select scopes you want to enable for the API key (y/n)"
+ API_SCOPES.each do |scope|
+ selected = ask_yes_no("#{scope}", false)
+ scope_params[scope] = true if selected
end
say "\n"
end
@@ -343,25 +327,25 @@ module Gem::GemcutterUtilities
end
def default_host?
- host == Gem::DEFAULT_HOST
+ self.host == Gem::DEFAULT_HOST
end
- def get_user_profile(identifier, password)
+ def get_user_profile(email, password)
return {} unless default_host?
response = rubygems_api_request(:get, "api/v1/profile/me.yaml") do |request|
- request.basic_auth identifier, password
+ request.basic_auth email, password
end
with_response response do |resp|
- Gem::ConfigFile.load_with_rubygems_config_hash(clean_text(resp.body))
+ Gem::SafeYAML.load clean_text(resp.body)
end
end
def get_mfa_params(profile)
mfa_level = profile["mfa"]
params = {}
- if ["ui_only", "ui_and_gem_signin"].include?(mfa_level)
+ if mfa_level == "ui_only" || mfa_level == "ui_and_gem_signin"
selected = ask_yes_no("Would you like to enable MFA for this key? (strongly recommended)")
params["mfa"] = true if selected
end
@@ -383,6 +367,6 @@ module Gem::GemcutterUtilities
end
def api_key_forbidden?(response)
- response.is_a?(Gem::Net::HTTPForbidden) && response.body.start_with?("The API key doesn't have access")
+ response.kind_of?(Net::HTTPForbidden) && response.body.start_with?("The API key doesn't have access")
end
end
diff --git a/lib/rubygems/gemcutter_utilities/webauthn_listener.rb b/lib/rubygems/gemcutter_utilities/webauthn_listener.rb
index abf65efe37..bea9d9e397 100644
--- a/lib/rubygems/gemcutter_utilities/webauthn_listener.rb
+++ b/lib/rubygems/gemcutter_utilities/webauthn_listener.rb
@@ -51,7 +51,7 @@ module Gem::GemcutterUtilities
request_line = socket.gets
method, req_uri, _protocol = request_line.split(" ")
- req_uri = Gem::URI.parse(req_uri)
+ req_uri = URI.parse(req_uri)
responder = SocketResponder.new(socket)
diff --git a/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb b/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb
index 17baa64fff..7709a8fef3 100644
--- a/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb
+++ b/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb
@@ -2,9 +2,9 @@
##
# The WebauthnListener Response class is used by the WebauthnListener to create
-# responses to be sent to the Gem host. It creates a Gem::Net::HTTPResponse instance
+# responses to be sent to the Gem host. It creates a Net::HTTPResponse instance
# when initialized and can be converted to the appropriate format to be sent by a socket using `to_s`.
-# Gem::Net::HTTPResponse instances cannot be directly sent over a socket.
+# Net::HTTPResponse instances cannot be directly sent over a socket.
#
# Types of response classes:
# - OkResponse
@@ -60,7 +60,7 @@ module Gem::GemcutterUtilities
def body; end
def build_http_response
- response_class = Gem::Net::HTTPResponse::CODE_TO_OBJ[code.to_s]
+ response_class = Net::HTTPResponse::CODE_TO_OBJ[code.to_s]
@http_response = response_class.new("1.1", code, reason_phrase)
@http_response.instance_variable_set(:@read, true)
diff --git a/lib/rubygems/gemcutter_utilities/webauthn_poller.rb b/lib/rubygems/gemcutter_utilities/webauthn_poller.rb
index fe3f163a88..e7068605a4 100644
--- a/lib/rubygems/gemcutter_utilities/webauthn_poller.rb
+++ b/lib/rubygems/gemcutter_utilities/webauthn_poller.rb
@@ -37,16 +37,16 @@ module Gem::GemcutterUtilities
thread.abort_on_exception = true
thread.report_on_exception = false
thread[:otp] = new(options, host).poll_for_otp(webauthn_url, credentials)
- rescue Gem::WebauthnVerificationError, Gem::Timeout::Error => e
+ rescue Gem::WebauthnVerificationError, Timeout::Error => e
thread[:error] = e
end
end
def poll_for_otp(webauthn_url, credentials)
- Gem::Timeout.timeout(TIMEOUT_IN_SECONDS) do
+ Timeout.timeout(TIMEOUT_IN_SECONDS) do
loop do
response = webauthn_verification_poll_response(webauthn_url, credentials)
- raise Gem::WebauthnVerificationError, response.message unless response.is_a?(Gem::Net::HTTPSuccess)
+ raise Gem::WebauthnVerificationError, response.message unless response.is_a?(Net::HTTPSuccess)
require "json"
parsed_response = JSON.parse(response.body)
@@ -69,10 +69,8 @@ module Gem::GemcutterUtilities
rubygems_api_request(:get, "api/v1/webauthn_verification/#{webauthn_token}/status.json") do |request|
if credentials.empty?
request.add_field "Authorization", api_key
- elsif credentials[:identifier] && credentials[:password]
- request.basic_auth credentials[:identifier], credentials[:password]
else
- raise Gem::WebauthnVerificationError, "Provided missing credentials"
+ request.basic_auth credentials[:email], credentials[:password]
end
end
end
diff --git a/lib/rubygems/gemspec_helpers.rb b/lib/rubygems/gemspec_helpers.rb
deleted file mode 100644
index 2b20fcafa1..0000000000
--- a/lib/rubygems/gemspec_helpers.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "../rubygems"
-
-##
-# Mixin methods for commands that work with gemspecs.
-
-module Gem::GemspecHelpers
- def find_gemspec(glob = "*.gemspec")
- gemspecs = Dir.glob(glob).sort
-
- if gemspecs.size > 1
- alert_error "Multiple gemspecs found: #{gemspecs}, please specify one"
- terminate_interaction(1)
- end
-
- gemspecs.first
- end
-end
diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb
new file mode 100644
index 0000000000..0935fe8486
--- /dev/null
+++ b/lib/rubygems/indexer.rb
@@ -0,0 +1,428 @@
+# frozen_string_literal: true
+
+require_relative "../rubygems"
+require_relative "package"
+require "tmpdir"
+
+##
+# Top level class for building the gem repository index.
+
+class Gem::Indexer
+ include Gem::UserInteraction
+
+ ##
+ # Build indexes for RubyGems 1.2.0 and newer when true
+
+ attr_accessor :build_modern
+
+ ##
+ # Index install location
+
+ attr_reader :dest_directory
+
+ ##
+ # Specs index install location
+
+ attr_reader :dest_specs_index
+
+ ##
+ # Latest specs index install location
+
+ attr_reader :dest_latest_specs_index
+
+ ##
+ # Prerelease specs index install location
+
+ attr_reader :dest_prerelease_specs_index
+
+ ##
+ # Index build directory
+
+ attr_reader :directory
+
+ ##
+ # Create an indexer that will index the gems in +directory+.
+
+ def initialize(directory, options = {})
+ require "fileutils"
+ require "tmpdir"
+ require "zlib"
+
+ options = { :build_modern => true }.merge options
+
+ @build_modern = options[:build_modern]
+
+ @dest_directory = directory
+ @directory = Dir.mktmpdir "gem_generate_index"
+
+ marshal_name = "Marshal.#{Gem.marshal_version}"
+
+ @master_index = File.join @directory, "yaml"
+ @marshal_index = File.join @directory, marshal_name
+
+ @quick_dir = File.join @directory, "quick"
+ @quick_marshal_dir = File.join @quick_dir, marshal_name
+ @quick_marshal_dir_base = File.join "quick", marshal_name # FIX: UGH
+
+ @quick_index = File.join @quick_dir, "index"
+ @latest_index = File.join @quick_dir, "latest_index"
+
+ @specs_index = File.join @directory, "specs.#{Gem.marshal_version}"
+ @latest_specs_index =
+ File.join(@directory, "latest_specs.#{Gem.marshal_version}")
+ @prerelease_specs_index =
+ File.join(@directory, "prerelease_specs.#{Gem.marshal_version}")
+ @dest_specs_index =
+ File.join(@dest_directory, "specs.#{Gem.marshal_version}")
+ @dest_latest_specs_index =
+ File.join(@dest_directory, "latest_specs.#{Gem.marshal_version}")
+ @dest_prerelease_specs_index =
+ File.join(@dest_directory, "prerelease_specs.#{Gem.marshal_version}")
+
+ @files = []
+ end
+
+ ##
+ # Build various indices
+
+ def build_indices
+ specs = map_gems_to_specs gem_file_list
+ Gem::Specification._resort! specs
+ build_marshal_gemspecs specs
+ build_modern_indices specs if @build_modern
+
+ compress_indices
+ end
+
+ ##
+ # Builds Marshal quick index gemspecs.
+
+ def build_marshal_gemspecs(specs)
+ count = specs.count
+ progress = ui.progress_reporter count,
+ "Generating Marshal quick index gemspecs for #{count} gems",
+ "Complete"
+
+ files = []
+
+ Gem.time "Generated Marshal quick index gemspecs" do
+ specs.each do |spec|
+ next if spec.default_gem?
+ spec_file_name = "#{spec.original_name}.gemspec.rz"
+ marshal_name = File.join @quick_marshal_dir, spec_file_name
+
+ marshal_zipped = Gem.deflate Marshal.dump(spec)
+
+ File.open marshal_name, "wb" do |io|
+ io.write marshal_zipped
+ end
+
+ files << marshal_name
+
+ progress.updated spec.original_name
+ end
+
+ progress.done
+ end
+
+ @files << @quick_marshal_dir
+
+ files
+ end
+
+ ##
+ # Build a single index for RubyGems 1.2 and newer
+
+ def build_modern_index(index, file, name)
+ say "Generating #{name} index"
+
+ Gem.time "Generated #{name} index" do
+ File.open(file, "wb") do |io|
+ specs = index.map do |*spec|
+ # We have to splat here because latest_specs is an array, while the
+ # others are hashes.
+ spec = spec.flatten.last
+ platform = spec.original_platform
+
+ # win32-api-1.0.4-x86-mswin32-60
+ unless String === platform
+ alert_warning "Skipping invalid platform in gem: #{spec.full_name}"
+ next
+ end
+
+ platform = Gem::Platform::RUBY if platform.nil? || platform.empty?
+ [spec.name, spec.version, platform]
+ end
+
+ specs = compact_specs(specs)
+ Marshal.dump(specs, io)
+ end
+ end
+ end
+
+ ##
+ # Builds indices for RubyGems 1.2 and newer. Handles full, latest, prerelease
+
+ def build_modern_indices(specs)
+ prerelease, released = specs.partition do |s|
+ s.version.prerelease?
+ end
+ latest_specs =
+ Gem::Specification._latest_specs specs
+
+ build_modern_index(released.sort, @specs_index, "specs")
+ build_modern_index(latest_specs.sort, @latest_specs_index, "latest specs")
+ build_modern_index(prerelease.sort, @prerelease_specs_index,
+ "prerelease specs")
+
+ @files += [@specs_index,
+ "#{@specs_index}.gz",
+ @latest_specs_index,
+ "#{@latest_specs_index}.gz",
+ @prerelease_specs_index,
+ "#{@prerelease_specs_index}.gz"]
+ end
+
+ def map_gems_to_specs(gems)
+ gems.map do |gemfile|
+ if File.size(gemfile) == 0
+ alert_warning "Skipping zero-length gem: #{gemfile}"
+ next
+ end
+
+ begin
+ spec = Gem::Package.new(gemfile).spec
+ spec.loaded_from = gemfile
+
+ spec.abbreviate
+ spec.sanitize
+
+ spec
+ rescue SignalException
+ alert_error "Received signal, exiting"
+ raise
+ rescue Exception => e
+ msg = ["Unable to process #{gemfile}",
+ "#{e.message} (#{e.class})",
+ "\t#{e.backtrace.join "\n\t"}"].join("\n")
+ alert_error msg
+ end
+ end.compact
+ end
+
+ ##
+ # Compresses indices on disk
+ #--
+ # All future files should be compressed using gzip, not deflate
+
+ def compress_indices
+ say "Compressing indices"
+
+ Gem.time "Compressed indices" do
+ if @build_modern
+ gzip @specs_index
+ gzip @latest_specs_index
+ gzip @prerelease_specs_index
+ end
+ end
+ end
+
+ ##
+ # Compacts Marshal output for the specs index data source by using identical
+ # objects as much as possible.
+
+ def compact_specs(specs)
+ names = {}
+ versions = {}
+ platforms = {}
+
+ specs.map do |(name, version, platform)|
+ names[name] = name unless names.include? name
+ versions[version] = version unless versions.include? version
+ platforms[platform] = platform unless platforms.include? platform
+
+ [names[name], versions[version], platforms[platform]]
+ end
+ end
+
+ ##
+ # Compress +filename+ with +extension+.
+
+ def compress(filename, extension)
+ data = Gem.read_binary filename
+
+ zipped = Gem.deflate data
+
+ File.open "#{filename}.#{extension}", "wb" do |io|
+ io.write zipped
+ end
+ end
+
+ ##
+ # List of gem file names to index.
+
+ def gem_file_list
+ Gem::Util.glob_files_in_dir("*.gem", File.join(@dest_directory, "gems"))
+ end
+
+ ##
+ # Builds and installs indices.
+
+ def generate_index
+ make_temp_directories
+ build_indices
+ install_indices
+ rescue SignalException
+ ensure
+ FileUtils.rm_rf @directory
+ end
+
+ ##
+ # Zlib::GzipWriter wrapper that gzips +filename+ on disk.
+
+ def gzip(filename)
+ Zlib::GzipWriter.open "#{filename}.gz" do |io|
+ io.write Gem.read_binary(filename)
+ end
+ end
+
+ ##
+ # Install generated indices into the destination directory.
+
+ def install_indices
+ verbose = Gem.configuration.really_verbose
+
+ say "Moving index into production dir #{@dest_directory}" if verbose
+
+ files = @files
+ files.delete @quick_marshal_dir if files.include? @quick_dir
+
+ if files.include?(@quick_marshal_dir) && !files.include?(@quick_dir)
+ files.delete @quick_marshal_dir
+
+ dst_name = File.join(@dest_directory, @quick_marshal_dir_base)
+
+ FileUtils.mkdir_p File.dirname(dst_name), :verbose => verbose
+ FileUtils.rm_rf dst_name, :verbose => verbose
+ FileUtils.mv(@quick_marshal_dir, dst_name,
+ :verbose => verbose, :force => true)
+ end
+
+ files = files.map do |path|
+ path.sub(/^#{Regexp.escape @directory}\/?/, "") # HACK?
+ end
+
+ files.each do |file|
+ src_name = File.join @directory, file
+ dst_name = File.join @dest_directory, file
+
+ FileUtils.rm_rf dst_name, :verbose => verbose
+ FileUtils.mv(src_name, @dest_directory,
+ :verbose => verbose, :force => true)
+ end
+ end
+
+ ##
+ # Make directories for index generation
+
+ def make_temp_directories
+ FileUtils.rm_rf @directory
+ FileUtils.mkdir_p @directory, :mode => 0700
+ FileUtils.mkdir_p @quick_marshal_dir
+ end
+
+ ##
+ # Ensure +path+ and path with +extension+ are identical.
+
+ def paranoid(path, extension)
+ data = Gem.read_binary path
+ compressed_data = Gem.read_binary "#{path}.#{extension}"
+
+ unless data == Gem::Util.inflate(compressed_data)
+ raise "Compressed file #{compressed_path} does not match uncompressed file #{path}"
+ end
+ end
+
+ ##
+ # Perform an in-place update of the repository from newly added gems.
+
+ def update_index
+ make_temp_directories
+
+ specs_mtime = File.stat(@dest_specs_index).mtime
+ newest_mtime = Time.at 0
+
+ updated_gems = gem_file_list.select do |gem|
+ gem_mtime = File.stat(gem).mtime
+ newest_mtime = gem_mtime if gem_mtime > newest_mtime
+ gem_mtime >= specs_mtime
+ end
+
+ if updated_gems.empty?
+ say "No new gems"
+ terminate_interaction 0
+ end
+
+ specs = map_gems_to_specs updated_gems
+ prerelease, released = specs.partition {|s| s.version.prerelease? }
+
+ files = build_marshal_gemspecs specs
+
+ Gem.time "Updated indexes" do
+ update_specs_index released, @dest_specs_index, @specs_index
+ update_specs_index released, @dest_latest_specs_index, @latest_specs_index
+ update_specs_index(prerelease,
+ @dest_prerelease_specs_index,
+ @prerelease_specs_index)
+ end
+
+ compress_indices
+
+ verbose = Gem.configuration.really_verbose
+
+ say "Updating production dir #{@dest_directory}" if verbose
+
+ files << @specs_index
+ files << "#{@specs_index}.gz"
+ files << @latest_specs_index
+ files << "#{@latest_specs_index}.gz"
+ files << @prerelease_specs_index
+ files << "#{@prerelease_specs_index}.gz"
+
+ files = files.map do |path|
+ path.sub(/^#{Regexp.escape @directory}\/?/, "") # HACK?
+ end
+
+ files.each do |file|
+ src_name = File.join @directory, file
+ dst_name = File.join @dest_directory, file # REFACTOR: duped above
+
+ FileUtils.mv src_name, dst_name, :verbose => verbose,
+ :force => true
+
+ File.utime newest_mtime, newest_mtime, dst_name
+ end
+ ensure
+ FileUtils.rm_rf @directory
+ end
+
+ ##
+ # Combines specs in +index+ and +source+ then writes out a new copy to
+ # +dest+. For a latest index, does not ensure the new file is minimal.
+
+ def update_specs_index(index, source, dest)
+ specs_index = Marshal.load Gem.read_binary(source)
+
+ index.each do |spec|
+ platform = spec.original_platform
+ platform = Gem::Platform::RUBY if platform.nil? || platform.empty?
+ specs_index << [spec.name, spec.version, platform]
+ end
+
+ specs_index = compact_specs specs_index.uniq.sort
+
+ File.open dest, "wb" do |io|
+ Marshal.dump specs_index, io
+ end
+ end
+end
diff --git a/lib/rubygems/install_update_options.rb b/lib/rubygems/install_update_options.rb
index aad207a718..e125b3b9b3 100644
--- a/lib/rubygems/install_update_options.rb
+++ b/lib/rubygems/install_update_options.rb
@@ -36,9 +36,9 @@ module Gem::InstallUpdateOptions
"List the documentation types you wish to",
"generate. For example: rdoc,ri") do |value, options|
options[:document] = case value
- when nil then %w[ri]
- when false then []
- else value
+ when nil then %w[ri]
+ when false then []
+ else value
end
end
@@ -50,7 +50,7 @@ module Gem::InstallUpdateOptions
add_option(:"Install/Update", "--vendor",
"Install gem into the vendor directory.",
- "Only for use by gem repackagers.") do |_value, options|
+ "Only for use by gem repackagers.") do |value, options|
unless Gem.vendor_dir
raise Gem::OptionParser::InvalidOption.new "your platform is not supported"
end
@@ -60,7 +60,7 @@ module Gem::InstallUpdateOptions
end
add_option(:"Install/Update", "-N", "--no-document",
- "Disable documentation generation") do |_value, options|
+ "Disable documentation generation") do |value, options|
options[:document] = []
end
@@ -104,21 +104,21 @@ module Gem::InstallUpdateOptions
add_option(:"Install/Update", "--development",
"Install additional development",
- "dependencies") do |_value, options|
+ "dependencies") do |value, options|
options[:development] = true
options[:dev_shallow] = true
end
add_option(:"Install/Update", "--development-all",
"Install development dependencies for all",
- "gems (including dev deps themselves)") do |_value, options|
+ "gems (including dev deps themselves)") do |value, options|
options[:development] = true
options[:dev_shallow] = false
end
add_option(:"Install/Update", "--conservative",
"Don't attempt to upgrade gems already",
- "meeting version requirement") do |_value, options|
+ "meeting version requirement") do |value, options|
options[:conservative] = true
options[:minimal_deps] = true
end
@@ -136,13 +136,13 @@ module Gem::InstallUpdateOptions
add_option(:"Install/Update", "-g", "--file [FILE]",
"Read from a gem dependencies API file and",
- "install the listed gems") do |v,_o|
- v ||= Gem::GEM_DEP_FILES.find do |file|
+ "install the listed gems") do |v,o|
+ v = Gem::GEM_DEP_FILES.find do |file|
File.exist? file
- end
+ end unless v
unless v
- message = v ? v : "(tried #{Gem::GEM_DEP_FILES.join ", "})"
+ message = v ? v : "(tried #{Gem::GEM_DEP_FILES.join ', '})"
raise Gem::OptionParser::InvalidArgument,
"cannot find gem dependencies file #{message}"
@@ -154,29 +154,29 @@ module Gem::InstallUpdateOptions
add_option(:"Install/Update", "--without GROUPS", Array,
"Omit the named groups (comma separated)",
"when installing from a gem dependencies",
- "file") do |v,_o|
- options[:without_groups].concat v.map(&:intern)
+ "file") do |v,o|
+ options[:without_groups].concat v.map {|without| without.intern }
end
add_option(:"Install/Update", "--default",
"Add the gem's full specification to",
- "specifications/default and extract only its bin") do |v,_o|
+ "specifications/default and extract only its bin") do |v,o|
options[:install_as_default] = v
end
add_option(:"Install/Update", "--explain",
"Rather than install the gems, indicate which would",
- "be installed") do |v,_o|
+ "be installed") do |v,o|
options[:explain] = v
end
add_option(:"Install/Update", "--[no-]lock",
- "Create a lock file (when used with -g/--file)") do |v,_o|
+ "Create a lock file (when used with -g/--file)") do |v,o|
options[:lock] = v
end
add_option(:"Install/Update", "--[no-]suggestions",
- "Suggest alternates when gems are not found") do |v,_o|
+ "Suggest alternates when gems are not found") do |v,o|
options[:suggest_alternate] = v
end
end
@@ -186,7 +186,7 @@ module Gem::InstallUpdateOptions
def install_update_options
{
- document: %w[ri],
+ :document => %w[ri],
}
end
@@ -196,4 +196,5 @@ module Gem::InstallUpdateOptions
def install_update_defaults_str
"--document=ri"
end
+
end
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 844f292ba2..1b152aaf1f 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -189,12 +189,10 @@ class Gem::Installer
@package.prog_mode = options[:prog_mode]
@package.data_mode = options[:data_mode]
- if @gem_home == Gem.user_dir
- # If we get here, then one of the following likely happened:
- # - `--user-install` was specified
- # - `Gem::PathSupport#home` fell back to `Gem.user_dir`
- # - GEM_HOME was manually set to `Gem.user_dir`
-
+ if options[:user_install]
+ @gem_home = Gem.user_dir
+ @bin_dir = Gem.bindir gem_home unless options[:bin_dir]
+ @plugins_dir = Gem.plugindir(gem_home)
check_that_user_bin_dir_is_in_path
end
end
@@ -224,32 +222,31 @@ class Gem::Installer
File.open generated_bin, "rb" do |io|
line = io.gets
- shebang = /^#!.*ruby/o
+ shebang = /^#!.*ruby/
- # TruffleRuby uses a bash prelude in default launchers
- if load_relative_enabled? || RUBY_ENGINE == "truffleruby"
- until line.nil? || shebang.match?(line) do
+ if load_relative_enabled?
+ until line.nil? || line =~ shebang do
line = io.gets
end
end
- next unless line&.match?(shebang)
+ next unless line =~ shebang
io.gets # blankline
- # TODO: detect a specially formatted comment instead of trying
+ # TODO detect a specially formatted comment instead of trying
# to find a string inside Ruby code.
- next unless io.gets&.include?("This file was generated by RubyGems")
+ next unless io.gets.to_s.include?("This file was generated by RubyGems")
ruby_executable = true
- existing = io.read.slice(/
+ existing = io.read.slice(%r{
^\s*(
gem \s |
load \s Gem\.bin_path\( |
load \s Gem\.activate_bin_path\(
)
(['"])(.*?)(\2),
- /x, 3)
+ }x, 3)
end
return if spec.name == existing
@@ -319,7 +316,7 @@ class Gem::Installer
FileUtils.rm_rf spec.extension_dir
dir_mode = options[:dir_mode]
- FileUtils.mkdir_p gem_dir, mode: dir_mode && 0o755
+ FileUtils.mkdir_p gem_dir, :mode => dir_mode && 0755
if @options[:install_as_default]
extract_bin
@@ -344,37 +341,41 @@ class Gem::Installer
say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil?
- Gem::Specification.add_spec(spec) unless @install_dir
+ Gem::Specification.add_spec(spec)
load_plugin
run_post_install_hooks
spec
- rescue Errno::EACCES => e
- # Permission denied - /path/to/foo
- raise Gem::FilePermissionError, e.message.split(" - ").last
+
+ # TODO This rescue is in the wrong place. What is raising this exception?
+ # move this rescue to around the code that actually might raise it.
+ rescue Zlib::GzipFile::Error
+ raise Gem::InstallError, "gzip error installing #{gem}"
end
def run_pre_install_hooks # :nodoc:
Gem.pre_install_hooks.each do |hook|
- next unless hook.call(self) == false
- location = " at #{$1}" if hook.inspect =~ /[ @](.*:\d+)/
+ if hook.call(self) == false
+ location = " at #{$1}" if hook.inspect =~ /[ @](.*:\d+)/
- message = "pre-install hook#{location} failed for #{spec.full_name}"
- raise Gem::InstallError, message
+ message = "pre-install hook#{location} failed for #{spec.full_name}"
+ raise Gem::InstallError, message
+ end
end
end
def run_post_build_hooks # :nodoc:
Gem.post_build_hooks.each do |hook|
- next unless hook.call(self) == false
- FileUtils.rm_rf gem_dir
+ if hook.call(self) == false
+ FileUtils.rm_rf gem_dir
- location = " at #{$1}" if hook.inspect =~ /[ @](.*:\d+)/
+ location = " at #{$1}" if hook.inspect =~ /[ @](.*:\d+)/
- message = "post-build hook#{location} failed for #{spec.full_name}"
- raise Gem::InstallError, message
+ message = "post-build hook#{location} failed for #{spec.full_name}"
+ raise Gem::InstallError, message
+ end
end
end
@@ -394,7 +395,7 @@ class Gem::Installer
specs = []
Gem::Util.glob_files_in_dir("*.gemspec", File.join(gem_home, "specifications")).each do |path|
- spec = Gem::Specification.load path
+ spec = Gem::Specification.load path.tap(&Gem::UNTAINT)
specs << spec if spec
end
@@ -464,9 +465,6 @@ class Gem::Installer
##
# Writes the full .gemspec specification (in Ruby) to the gem home's
# specifications/default directory.
- #
- # In contrast to #write_spec, this keeps file lists, so the `gem contents`
- # command works.
def write_default_spec
Gem.write_binary(default_spec_file, spec.to_ruby)
@@ -493,11 +491,12 @@ class Gem::Installer
ensure_writable_dir @bin_dir
spec.executables.each do |filename|
+ filename.tap(&Gem::UNTAINT)
bin_path = File.join gem_dir, spec.bindir, filename
next unless File.exist? bin_path
mode = File.stat(bin_path).mode
- dir_mode = options[:prog_mode] || (mode | 0o111)
+ dir_mode = options[:prog_mode] || (mode | 0111)
unless dir_mode == mode
require "fileutils"
@@ -525,8 +524,6 @@ class Gem::Installer
else
regenerate_plugins_for(spec, @plugins_dir)
end
- rescue ArgumentError => e
- raise e, "#{latest.name} #{latest.version} #{spec.name} #{spec.version}: #{e.message}"
end
##
@@ -534,7 +531,7 @@ class Gem::Installer
#--
# The Windows script is generated in addition to the regular one due to a
# bug or misfeature in the Windows shell's pipe. See
- # https://blade.ruby-lang.org/ruby-talk/193379
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/193379
def generate_bin_script(filename, bindir)
bin_script_path = File.join bindir, formatted_program_filename(filename)
@@ -542,9 +539,9 @@ class Gem::Installer
require "fileutils"
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
- File.open bin_script_path, "wb", 0o755 do |file|
+ File.open bin_script_path, "wb", 0755 do |file|
file.print app_script_text(filename)
- file.chmod(options[:prog_mode] || 0o755)
+ file.chmod(options[:prog_mode] || 0755)
end
verbose bin_script_path
@@ -569,7 +566,7 @@ class Gem::Installer
File.unlink dst
end
- FileUtils.symlink src, dst, verbose: Gem.configuration.really_verbose
+ FileUtils.symlink src, dst, :verbose => Gem.configuration.really_verbose
rescue NotImplementedError, SystemCallError
alert_warning "Unable to use symlinks, installing wrapper"
generate_bin_script filename, bindir
@@ -592,7 +589,7 @@ class Gem::Installer
def shebang(bin_file_name)
path = File.join gem_dir, spec.bindir, bin_file_name
- first_line = File.open(path, "rb", &:gets) || ""
+ first_line = File.open(path, "rb") {|file| file.gets } || ""
if first_line.start_with?("#!")
# Preserve extra words on shebang line, like "-w". Thanks RPA.
@@ -634,6 +631,7 @@ class Gem::Installer
def ensure_loadable_spec
ruby = spec.to_ruby_for_cache
+ ruby.tap(&Gem::UNTAINT)
begin
eval ruby
@@ -654,36 +652,31 @@ class Gem::Installer
def process_options # :nodoc:
@options = {
- bin_dir: nil,
- env_shebang: false,
- force: false,
- only_install_dir: false,
- post_install_message: true,
+ :bin_dir => nil,
+ :env_shebang => false,
+ :force => false,
+ :only_install_dir => false,
+ :post_install_message => true,
}.merge options
@env_shebang = options[:env_shebang]
@force = options[:force]
@install_dir = options[:install_dir]
- @user_install = options[:user_install]
+ @gem_home = options[:install_dir] || Gem.dir
+ @plugins_dir = Gem.plugindir(@gem_home)
@ignore_dependencies = options[:ignore_dependencies]
@format_executable = options[:format_executable]
@wrappers = options[:wrappers]
@only_install_dir = options[:only_install_dir]
- @bin_dir = options[:bin_dir]
- @development = options[:development]
- @build_root = options[:build_root]
-
- @build_args = options[:build_args]
-
- @gem_home = @install_dir || user_install_dir || Gem.dir
-
# If the user has asked for the gem to be installed in a directory that is
# the system gem directory, then use the system bin directory, else create
# (or use) a new bin dir under the gem_home.
- @bin_dir ||= Gem.bindir(@gem_home)
+ @bin_dir = options[:bin_dir] || Gem.bindir(gem_home)
+ @development = options[:development]
+ @build_root = options[:build_root]
- @plugins_dir = Gem.plugindir(@gem_home)
+ @build_args = options[:build_args]
unless @build_root.nil?
@bin_dir = File.join(@build_root, @bin_dir.gsub(/^[a-zA-Z]:/, ""))
@@ -718,11 +711,12 @@ class Gem::Installer
end
def verify_gem_home # :nodoc:
- FileUtils.mkdir_p gem_home, mode: options[:dir_mode] && 0o755
+ FileUtils.mkdir_p gem_home, :mode => options[:dir_mode] && 0755
+ raise Gem::FilePermissionError, gem_home unless File.writable?(gem_home)
end
def verify_spec
- unless Gem::Specification::VALID_NAME_PATTERN.match?(spec.name)
+ unless spec.name =~ Gem::Specification::VALID_NAME_PATTERN
raise Gem::InstallError, "#{spec} has an invalid name"
end
@@ -734,11 +728,11 @@ class Gem::Installer
raise Gem::InstallError, "#{spec} has an invalid extensions"
end
- if /\R/.match?(spec.platform.to_s)
+ if spec.platform.to_s =~ /\R/
raise Gem::InstallError, "#{spec.platform} is an invalid platform"
end
- unless /\A\d+\z/.match?(spec.specification_version.to_s)
+ unless spec.specification_version.to_s =~ /\A\d+\z/
raise Gem::InstallError, "#{spec} has an invalid specification_version"
end
@@ -755,9 +749,9 @@ class Gem::Installer
# Return the text for an application file.
def app_script_text(bin_file_name)
- # NOTE: that the `load` lines cannot be indented, as old RG versions match
+ # note that the `load` lines cannot be indented, as old RG versions match
# against the beginning of the line
- <<-TEXT
+ return <<-TEXT
#{shebang bin_file_name}
#
# This file was generated by RubyGems.
@@ -814,10 +808,10 @@ TEXT
rb_topdir = RbConfig::TOPDIR || File.dirname(rb_config["bindir"])
# get ruby executable file name from RbConfig
- ruby_exe = "#{rb_config["RUBY_INSTALL_NAME"]}#{rb_config["EXEEXT"]}"
+ ruby_exe = "#{rb_config['RUBY_INSTALL_NAME']}#{rb_config['EXEEXT']}"
ruby_exe = "ruby.exe" if ruby_exe.empty?
- if File.exist?(File.join(bindir, ruby_exe))
+ if File.exist?(File.join bindir, ruby_exe)
# stub & ruby.exe within same folder. Portable
<<-TEXT
@ECHO OFF
@@ -939,7 +933,7 @@ TEXT
build_info_dir = File.join gem_home, "build_info"
dir_mode = options[:dir_mode]
- FileUtils.mkdir_p build_info_dir, mode: dir_mode && 0o755
+ FileUtils.mkdir_p build_info_dir, :mode => dir_mode && 0755
build_info_file = File.join build_info_dir, "#{spec.full_name}.info"
@@ -962,7 +956,7 @@ TEXT
def ensure_writable_dir(dir) # :nodoc:
begin
- Dir.mkdir dir, *[options[:dir_mode] && 0o755].compact
+ Dir.mkdir dir, *[options[:dir_mode] && 0755].compact
rescue SystemCallError
raise unless File.directory? dir
end
@@ -972,19 +966,6 @@ TEXT
private
- def user_install_dir
- # never install to user home in --build-root mode
- return unless @build_root.nil?
-
- # Please note that @user_install might have three states:
- # * `true`: `--user-install`
- # * `false`: `--no-user-install` and
- # * `nil`: option was not specified
- if @user_install || (@user_install.nil? && Gem.default_user_install)
- Gem.user_dir
- end
- end
-
def build_args
@build_args ||= begin
require_relative "command"
@@ -1010,7 +991,7 @@ TEXT
bindir="${0%/*}"
EOS
- script << %(exec "$bindir/#{ruby_install_name}" "-x" "$0" "$@"\n)
+ script << %Q(exec "$bindir/#{ruby_install_name}" "-x" "$0" "$@"\n)
<<~EOS
#!/bin/sh
diff --git a/lib/rubygems/installer_uninstaller_utils.rb b/lib/rubygems/installer_uninstaller_utils.rb
index c5c2a52bab..d97b4e29b1 100644
--- a/lib/rubygems/installer_uninstaller_utils.rb
+++ b/lib/rubygems/installer_uninstaller_utils.rb
@@ -4,6 +4,7 @@
# Helper methods for both Gem::Installer and Gem::Uninstaller
module Gem::InstallerUninstallerUtils
+
def regenerate_plugins_for(spec, plugins_dir)
plugins = spec.plugins
return if plugins.empty?
@@ -24,4 +25,5 @@ module Gem::InstallerUninstallerUtils
def remove_plugins_for(spec, plugins_dir)
FileUtils.rm_f Gem::Util.glob_files_in_dir("#{spec.name}#{Gem.plugin_suffix_pattern}", plugins_dir)
end
+
end
diff --git a/lib/rubygems/local_remote_options.rb b/lib/rubygems/local_remote_options.rb
index 51a61213a5..3d970ef225 100644
--- a/lib/rubygems/local_remote_options.rb
+++ b/lib/rubygems/local_remote_options.rb
@@ -6,21 +6,22 @@
# See LICENSE.txt for permissions.
#++
-require_relative "vendor/uri/lib/uri"
+require "uri"
require_relative "../rubygems"
##
# Mixin methods for local and remote Gem::Command options.
module Gem::LocalRemoteOptions
+
##
# Allows Gem::OptionParser to handle HTTP URIs.
def accept_uri_http
- Gem::OptionParser.accept Gem::URI::HTTP do |value|
+ Gem::OptionParser.accept URI::HTTP do |value|
begin
- uri = Gem::URI.parse value
- rescue Gem::URI::InvalidURIError
+ uri = URI.parse value
+ rescue URI::InvalidURIError
raise Gem::OptionParser::InvalidArgument, value
end
@@ -39,17 +40,17 @@ module Gem::LocalRemoteOptions
def add_local_remote_options
add_option(:"Local/Remote", "-l", "--local",
- "Restrict operations to the LOCAL domain") do |_value, options|
+ "Restrict operations to the LOCAL domain") do |value, options|
options[:domain] = :local
end
add_option(:"Local/Remote", "-r", "--remote",
- "Restrict operations to the REMOTE domain") do |_value, options|
+ "Restrict operations to the REMOTE domain") do |value, options|
options[:domain] = :remote
end
add_option(:"Local/Remote", "-b", "--both",
- "Allow LOCAL and REMOTE operations") do |_value, options|
+ "Allow LOCAL and REMOTE operations") do |value, options|
options[:domain] = :both
end
@@ -66,7 +67,8 @@ module Gem::LocalRemoteOptions
def add_bulk_threshold_option
add_option(:"Local/Remote", "-B", "--bulk-threshold COUNT",
"Threshold for switching to bulk",
- "synchronization (default #{Gem.configuration.bulk_threshold})") do |value, _options|
+ "synchronization (default #{Gem.configuration.bulk_threshold})") do
+ |value, options|
Gem.configuration.bulk_threshold = value.to_i
end
end
@@ -76,7 +78,7 @@ module Gem::LocalRemoteOptions
def add_clear_sources_option
add_option(:"Local/Remote", "--clear-sources",
- "Clear the gem sources") do |_value, options|
+ "Clear the gem sources") do |value, options|
Gem.sources = nil
options[:sources_cleared] = true
end
@@ -88,9 +90,9 @@ module Gem::LocalRemoteOptions
def add_proxy_option
accept_uri_http
- add_option(:"Local/Remote", "-p", "--[no-]http-proxy [URL]", Gem::URI::HTTP,
+ add_option(:"Local/Remote", "-p", "--[no-]http-proxy [URL]", URI::HTTP,
"Use HTTP proxy for remote operations") do |value, options|
- options[:http_proxy] = value == false ? :no_proxy : value
+ options[:http_proxy] = (value == false) ? :no_proxy : value
Gem.configuration[:http_proxy] = options[:http_proxy]
end
end
@@ -101,9 +103,9 @@ module Gem::LocalRemoteOptions
def add_source_option
accept_uri_http
- add_option(:"Local/Remote", "-s", "--source URL", Gem::URI::HTTP,
+ add_option(:"Local/Remote", "-s", "--source URL", URI::HTTP,
"Append URL to list of remote gem sources") do |source, options|
- source << "/" unless source.end_with?("/")
+ source << "/" if source !~ /\/\z/
if options.delete :sources_cleared
Gem.sources = [source]
@@ -118,7 +120,7 @@ module Gem::LocalRemoteOptions
def add_update_sources_option
add_option(:Deprecated, "-u", "--[no-]update-sources",
- "Update local source cache") do |value, _options|
+ "Update local source cache") do |value, options|
Gem.configuration.update_sources = value
end
end
@@ -143,4 +145,5 @@ module Gem::LocalRemoteOptions
def remote?
options[:domain] == :remote || options[:domain] == :both
end
+
end
diff --git a/lib/rubygems/mock_gem_ui.rb b/lib/rubygems/mock_gem_ui.rb
new file mode 100644
index 0000000000..2dfdc6d523
--- /dev/null
+++ b/lib/rubygems/mock_gem_ui.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require_relative "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/lib/rubygems/name_tuple.rb b/lib/rubygems/name_tuple.rb
index 3f4a6fcf3d..c26d0765e6 100644
--- a/lib/rubygems/name_tuple.rb
+++ b/lib/rubygems/name_tuple.rb
@@ -6,12 +6,14 @@
# wrap the data returned from the indexes.
class Gem::NameTuple
- def initialize(name, version, platform=Gem::Platform::RUBY)
+ def initialize(name, version, platform="ruby")
@name = name
@version = version
- platform &&= platform.to_s
- platform = Gem::Platform::RUBY if !platform || platform.empty?
+ unless platform.kind_of? Gem::Platform
+ platform = "ruby" if !platform || platform.empty?
+ end
+
@platform = platform
end
@@ -30,7 +32,7 @@ class Gem::NameTuple
# [name, version, platform] tuples.
def self.to_basic(list)
- list.map(&:to_a)
+ list.map {|t| t.to_a }
end
##
@@ -47,11 +49,11 @@ class Gem::NameTuple
def full_name
case @platform
- when nil, "", Gem::Platform::RUBY
+ when nil, "ruby", ""
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{@platform}"
- end
+ end.dup.tap(&Gem::UNTAINT)
end
##
@@ -85,7 +87,7 @@ class Gem::NameTuple
"#<Gem::NameTuple #{@name}, #{@version}, #{@platform}>"
end
- alias_method :to_s, :inspect # :nodoc:
+ alias to_s inspect # :nodoc:
def <=>(other)
[@name, @version, Gem::Platform.sort_priority(@platform)] <=>
diff --git a/lib/rubygems/optparse.rb b/lib/rubygems/optparse.rb
new file mode 100644
index 0000000000..6ed718423c
--- /dev/null
+++ b/lib/rubygems/optparse.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require_relative "optparse/lib/optparse"
diff --git a/lib/bundler/vendor/connection_pool/.document b/lib/rubygems/optparse/.document
index 0c43bbd6b3..0c43bbd6b3 100644
--- a/lib/bundler/vendor/connection_pool/.document
+++ b/lib/rubygems/optparse/.document
diff --git a/lib/rubygems/vendor/optparse/lib/optionparser.rb b/lib/rubygems/optparse/lib/optionparser.rb
index 4b9b40d82a..4b9b40d82a 100644
--- a/lib/rubygems/vendor/optparse/lib/optionparser.rb
+++ b/lib/rubygems/optparse/lib/optionparser.rb
diff --git a/lib/rubygems/optparse/lib/optparse.rb b/lib/rubygems/optparse/lib/optparse.rb
new file mode 100644
index 0000000000..1e50bda769
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse.rb
@@ -0,0 +1,2308 @@
+# frozen_string_literal: true
+#
+# optparse.rb - command-line option analysis with the Gem::OptionParser class.
+#
+# Author:: Nobu Nakada
+# Documentation:: Nobu Nakada and Gavin Sinclair.
+#
+# See Gem::OptionParser for documentation.
+#
+
+
+#--
+# == Developer Documentation (not for RDoc output)
+#
+# === Class tree
+#
+# - Gem::OptionParser:: front end
+# - Gem::OptionParser::Switch:: each switches
+# - Gem::OptionParser::List:: options list
+# - Gem::OptionParser::ParseError:: errors on parsing
+# - Gem::OptionParser::AmbiguousOption
+# - Gem::OptionParser::NeedlessArgument
+# - Gem::OptionParser::MissingArgument
+# - Gem::OptionParser::InvalidOption
+# - Gem::OptionParser::InvalidArgument
+# - Gem::OptionParser::AmbiguousArgument
+#
+# === Object relationship diagram
+#
+# +--------------+
+# | Gem::OptionParser |<>-----+
+# +--------------+ | +--------+
+# | ,-| Switch |
+# on_head -------->+---------------+ / +--------+
+# accept/reject -->| List |<|>-
+# | |<|>- +----------+
+# on ------------->+---------------+ `-| argument |
+# : : | class |
+# +---------------+ |==========|
+# on_tail -------->| | |pattern |
+# +---------------+ |----------|
+# Gem::OptionParser.accept ->| DefaultList | |converter |
+# reject |(shared between| +----------+
+# | all instances)|
+# +---------------+
+#
+#++
+#
+# == Gem::OptionParser
+#
+# === New to \Gem::OptionParser?
+#
+# See the {Tutorial}[optparse/tutorial.rdoc].
+#
+# === Introduction
+#
+# Gem::OptionParser is a class for command-line option analysis. It is much more
+# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
+# solution.
+#
+# === Features
+#
+# 1. The argument specification and the code to handle it are written in the
+# same place.
+# 2. It can output an option summary; you don't need to maintain this string
+# separately.
+# 3. Optional and mandatory arguments are specified very gracefully.
+# 4. Arguments can be automatically converted to a specified class.
+# 5. Arguments can be restricted to a certain set.
+#
+# All of these features are demonstrated in the examples below. See
+# #make_switch for full documentation.
+#
+# === Minimal example
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# options = {}
+# Gem::OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
+#
+# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+# options[:verbose] = v
+# end
+# end.parse!
+#
+# p options
+# p ARGV
+#
+# === Generating Help
+#
+# Gem::OptionParser can be used to automatically generate help for the commands you
+# write:
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# Options = Struct.new(:name)
+#
+# class Parser
+# def self.parse(options)
+# args = Options.new("world")
+#
+# opt_parser = Gem::OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
+#
+# parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
+# args.name = n
+# end
+#
+# parser.on("-h", "--help", "Prints this help") do
+# puts parser
+# exit
+# end
+# end
+#
+# opt_parser.parse!(options)
+# return args
+# end
+# end
+# options = Parser.parse %w[--help]
+#
+# #=>
+# # Usage: example.rb [options]
+# # -n, --name=NAME Name to say hello to
+# # -h, --help Prints this help
+#
+# === Required Arguments
+#
+# For options that require an argument, option specification strings may include an
+# option name in all caps. If an option is used without the required argument,
+# an exception will be raised.
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# options = {}
+# Gem::OptionParser.new do |parser|
+# parser.on("-r", "--require LIBRARY",
+# "Require the LIBRARY before executing your script") do |lib|
+# puts "You required #{lib}!"
+# end
+# end.parse!
+#
+# Used:
+#
+# $ ruby optparse-test.rb -r
+# optparse-test.rb:9:in `<main>': missing argument: -r (Gem::OptionParser::MissingArgument)
+# $ ruby optparse-test.rb -r my-library
+# You required my-library!
+#
+# === Type Coercion
+#
+# Gem::OptionParser supports the ability to coerce command line arguments
+# into objects for us.
+#
+# Gem::OptionParser comes with a few ready-to-use kinds of type
+# coercion. They are:
+#
+# - Date -- Anything accepted by +Date.parse+
+# - DateTime -- Anything accepted by +DateTime.parse+
+# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+
+# - URI -- Anything accepted by +URI.parse+
+# - Shellwords -- Anything accepted by +Shellwords.shellwords+
+# - String -- Any non-empty string
+# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
+# - Float -- Any float. (e.g. 10, 3.14, -100E+13)
+# - Numeric -- Any integer, float, or rational (1, 3.4, 1/3)
+# - DecimalInteger -- Like +Integer+, but no octal format.
+# - OctalInteger -- Like +Integer+, but no decimal format.
+# - DecimalNumeric -- Decimal integer or float.
+# - TrueClass -- Accepts '+, yes, true, -, no, false' and
+# defaults as +true+
+# - FalseClass -- Same as +TrueClass+, but defaults to +false+
+# - Array -- Strings separated by ',' (e.g. 1,2,3)
+# - Regexp -- Regular expressions. Also includes options.
+#
+# We can also add our own coercions, which we will cover below.
+#
+# ==== Using Built-in Conversions
+#
+# As an example, the built-in +Time+ conversion is used. The other built-in
+# conversions behave in the same way.
+# Gem::OptionParser will attempt to parse the argument
+# as a +Time+. If it succeeds, that time will be passed to the
+# handler block. Otherwise, an exception will be raised.
+#
+# require 'rubygems/optparse/lib/optparse'
+# require 'rubygems/optparse/lib/optparse/time'
+# Gem::OptionParser.new do |parser|
+# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
+# p time
+# end
+# end.parse!
+#
+# Used:
+#
+# $ ruby optparse-test.rb -t nonsense
+# ... invalid argument: -t nonsense (Gem::OptionParser::InvalidArgument)
+# $ ruby optparse-test.rb -t 10-11-12
+# 2010-11-12 00:00:00 -0500
+# $ ruby optparse-test.rb -t 9:30
+# 2014-08-13 09:30:00 -0400
+#
+# ==== Creating Custom Conversions
+#
+# The +accept+ method on Gem::OptionParser may be used to create converters.
+# It specifies which conversion block to call whenever a class is specified.
+# The example below uses it to fetch a +User+ object before the +on+ handler receives it.
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# User = Struct.new(:id, :name)
+#
+# def find_user id
+# not_found = ->{ raise "No User Found for id #{id}" }
+# [ User.new(1, "Sam"),
+# User.new(2, "Gandalf") ].find(not_found) do |u|
+# u.id == id
+# end
+# end
+#
+# op = Gem::OptionParser.new
+# op.accept(User) do |user_id|
+# find_user user_id.to_i
+# end
+#
+# op.on("--user ID", User) do |user|
+# puts user
+# end
+#
+# op.parse!
+#
+# Used:
+#
+# $ ruby optparse-test.rb --user 1
+# #<struct User id=1, name="Sam">
+# $ ruby optparse-test.rb --user 2
+# #<struct User id=2, name="Gandalf">
+# $ ruby optparse-test.rb --user 3
+# optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
+#
+# === Store options to a Hash
+#
+# The +into+ option of +order+, +parse+ and so on methods stores command line options into a Hash.
+#
+# require 'rubygems/optparse/lib/optparse'
+#
+# options = {}
+# Gem::OptionParser.new do |parser|
+# parser.on('-a')
+# parser.on('-b NUM', Integer)
+# parser.on('-v', '--verbose')
+# end.parse!(into: options)
+#
+# p options
+#
+# Used:
+#
+# $ ruby optparse-test.rb -a
+# {:a=>true}
+# $ ruby optparse-test.rb -a -v
+# {:a=>true, :verbose=>true}
+# $ ruby optparse-test.rb -a -b 100
+# {:a=>true, :b=>100}
+#
+# === Complete example
+#
+# The following example is a complete Ruby program. You can run it and see the
+# effect of specifying various options. This is probably the best way to learn
+# the features of +optparse+.
+#
+# require 'rubygems/optparse/lib/optparse'
+# require 'rubygems/optparse/lib/optparse/time'
+# require 'ostruct'
+# require 'pp'
+#
+# class OptparseExample
+# Version = '1.0.0'
+#
+# CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
+# CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
+#
+# class ScriptOptions
+# attr_accessor :library, :inplace, :encoding, :transfer_type,
+# :verbose, :extension, :delay, :time, :record_separator,
+# :list
+#
+# def initialize
+# self.library = []
+# self.inplace = false
+# self.encoding = "utf8"
+# self.transfer_type = :auto
+# self.verbose = false
+# end
+#
+# def define_options(parser)
+# parser.banner = "Usage: example.rb [options]"
+# parser.separator ""
+# parser.separator "Specific options:"
+#
+# # add additional options
+# perform_inplace_option(parser)
+# delay_execution_option(parser)
+# execute_at_time_option(parser)
+# specify_record_separator_option(parser)
+# list_example_option(parser)
+# specify_encoding_option(parser)
+# optional_option_argument_with_keyword_completion_option(parser)
+# boolean_verbose_option(parser)
+#
+# parser.separator ""
+# parser.separator "Common options:"
+# # No argument, shows at tail. This will print an options summary.
+# # Try it and see!
+# parser.on_tail("-h", "--help", "Show this message") do
+# puts parser
+# exit
+# end
+# # Another typical switch to print the version.
+# parser.on_tail("--version", "Show version") do
+# puts Version
+# exit
+# end
+# end
+#
+# def perform_inplace_option(parser)
+# # Specifies an optional option argument
+# parser.on("-i", "--inplace [EXTENSION]",
+# "Edit ARGV files in place",
+# "(make backup if EXTENSION supplied)") do |ext|
+# self.inplace = true
+# self.extension = ext || ''
+# self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
+# end
+# end
+#
+# def delay_execution_option(parser)
+# # Cast 'delay' argument to a Float.
+# parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
+# self.delay = n
+# end
+# end
+#
+# def execute_at_time_option(parser)
+# # Cast 'time' argument to a Time object.
+# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
+# self.time = time
+# end
+# end
+#
+# def specify_record_separator_option(parser)
+# # Cast to octal integer.
+# parser.on("-F", "--irs [OCTAL]", Gem::OptionParser::OctalInteger,
+# "Specify record separator (default \\0)") do |rs|
+# self.record_separator = rs
+# end
+# end
+#
+# def list_example_option(parser)
+# # List of arguments.
+# parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
+# self.list = list
+# end
+# end
+#
+# def specify_encoding_option(parser)
+# # Keyword completion. We are specifying a specific set of arguments (CODES
+# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
+# # the shortest unambiguous text.
+# code_list = (CODE_ALIASES.keys + CODES).join(', ')
+# parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
+# "(#{code_list})") do |encoding|
+# self.encoding = encoding
+# end
+# end
+#
+# def optional_option_argument_with_keyword_completion_option(parser)
+# # Optional '--type' option argument with keyword completion.
+# parser.on("--type [TYPE]", [:text, :binary, :auto],
+# "Select transfer type (text, binary, auto)") do |t|
+# self.transfer_type = t
+# end
+# end
+#
+# def boolean_verbose_option(parser)
+# # Boolean switch.
+# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+# self.verbose = v
+# end
+# end
+# end
+#
+# #
+# # Return a structure describing the options.
+# #
+# def parse(args)
+# # The options specified on the command line will be collected in
+# # *options*.
+#
+# @options = ScriptOptions.new
+# @args = Gem::OptionParser.new do |parser|
+# @options.define_options(parser)
+# parser.parse!(args)
+# end
+# @options
+# end
+#
+# attr_reader :parser, :options
+# end # class OptparseExample
+#
+# example = OptparseExample.new
+# options = example.parse(ARGV)
+# pp options # example.options
+# pp ARGV
+#
+# === Shell Completion
+#
+# For modern shells (e.g. bash, zsh, etc.), you can use shell
+# completion for command line options.
+#
+# === Further documentation
+#
+# The above examples, along with the accompanying
+# {Tutorial}[optparse/tutorial.rdoc],
+# should be enough to learn how to use this class.
+# If you have any questions, file a ticket at http://bugs.ruby-lang.org.
+#
+class Gem::OptionParser
+ Gem::OptionParser::Version = "0.3.0"
+
+ # :stopdoc:
+ NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
+ RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
+ OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
+ # :startdoc:
+
+ #
+ # Keyword completion module. This allows partial arguments to be specified
+ # and resolved against a list of acceptable values.
+ #
+ module Completion
+ def self.regexp(key, icase)
+ Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase)
+ end
+
+ def self.candidate(key, icase = false, pat = nil, &block)
+ pat ||= Completion.regexp(key, icase)
+ candidates = []
+ block.call do |k, *v|
+ (if Regexp === k
+ kn = ""
+ k === key
+ else
+ kn = defined?(k.id2name) ? k.id2name : k
+ pat === kn
+ end) or next
+ v << k if v.empty?
+ candidates << [k, v, kn]
+ end
+ candidates
+ end
+
+ def candidate(key, icase = false, pat = nil)
+ Completion.candidate(key, icase, pat, &method(:each))
+ end
+
+ public
+ def complete(key, icase = false, pat = nil)
+ candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
+ if candidates.size == 1
+ canon, sw, * = candidates[0]
+ elsif candidates.size > 1
+ canon, sw, cn = candidates.shift
+ candidates.each do |k, v, kn|
+ next if sw == v
+ if String === cn and String === kn
+ if cn.rindex(kn, 0)
+ canon, sw, cn = k, v, kn
+ next
+ elsif kn.rindex(cn, 0)
+ next
+ end
+ end
+ throw :ambiguous, key
+ end
+ end
+ if canon
+ block_given? or return key, *sw
+ yield(key, *sw)
+ end
+ end
+
+ def convert(opt = nil, val = nil, *)
+ val
+ end
+ end
+
+
+ #
+ # Map from option/keyword string to object with completion.
+ #
+ class OptionMap < Hash
+ include Completion
+ end
+
+
+ #
+ # Individual switch class. Not important to the user.
+ #
+ # Defined within Switch are several Switch-derived classes: NoArgument,
+ # RequiredArgument, etc.
+ #
+ class Switch
+ attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block
+
+ #
+ # Guesses argument style from +arg+. Returns corresponding
+ # Gem::OptionParser::Switch class (OptionalArgument, etc.).
+ #
+ def self.guess(arg)
+ case arg
+ when ""
+ t = self
+ when /\A=?\[/
+ t = Switch::OptionalArgument
+ when /\A\s+\[/
+ t = Switch::PlacedArgument
+ else
+ t = Switch::RequiredArgument
+ end
+ self >= t or incompatible_argument_styles(arg, t)
+ t
+ end
+
+ def self.incompatible_argument_styles(arg, t)
+ raise(ArgumentError, "#{arg}: incompatible argument styles\n #{self}, #{t}",
+ ParseError.filter_backtrace(caller(2)))
+ end
+
+ def self.pattern
+ NilClass
+ end
+
+ def initialize(pattern = nil, conv = nil,
+ short = nil, long = nil, arg = nil,
+ desc = ([] if short or long), block = nil, &_block)
+ raise if Array === pattern
+ block ||= _block
+ @pattern, @conv, @short, @long, @arg, @desc, @block =
+ pattern, conv, short, long, arg, desc, block
+ end
+
+ #
+ # Parses +arg+ and returns rest of +arg+ and matched portion to the
+ # argument pattern. Yields when the pattern doesn't match substring.
+ #
+ def parse_arg(arg) # :nodoc:
+ pattern or return nil, [arg]
+ unless m = pattern.match(arg)
+ yield(InvalidArgument, arg)
+ return arg, []
+ end
+ if String === m
+ m = [s = m]
+ else
+ m = m.to_a
+ s = m[0]
+ return nil, m unless String === s
+ end
+ raise InvalidArgument, arg unless arg.rindex(s, 0)
+ return nil, m if s.length == arg.length
+ yield(InvalidArgument, arg) # didn't match whole arg
+ return arg[s.length..-1], m
+ end
+ private :parse_arg
+
+ #
+ # Parses argument, converts and returns +arg+, +block+ and result of
+ # conversion. Yields at semi-error condition instead of raising an
+ # exception.
+ #
+ def conv_arg(arg, val = []) # :nodoc:
+ if conv
+ val = conv.call(*val)
+ else
+ val = proc {|v| v}.call(*val)
+ end
+ return arg, block, val
+ end
+ private :conv_arg
+
+ #
+ # Produces the summary text. Each line of the summary is yielded to the
+ # block (without newline).
+ #
+ # +sdone+:: Already summarized short style options keyed hash.
+ # +ldone+:: Already summarized long style options keyed hash.
+ # +width+:: Width of left side (option part). In other words, the right
+ # side (description part) starts after +width+ columns.
+ # +max+:: Maximum width of left side -> the options are filled within
+ # +max+ columns.
+ # +indent+:: Prefix string indents all summarized lines.
+ #
+ def summarize(sdone = {}, ldone = {}, width = 1, max = width - 1, indent = "")
+ sopts, lopts = [], [], nil
+ @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
+ @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
+ return if sopts.empty? and lopts.empty? # completely hidden
+
+ left = [sopts.join(', ')]
+ right = desc.dup
+
+ while s = lopts.shift
+ l = left[-1].length + s.length
+ l += arg.length if left.size == 1 && arg
+ l < max or sopts.empty? or left << +''
+ left[-1] << (left[-1].empty? ? ' ' * 4 : ', ') << s
+ end
+
+ if arg
+ left[0] << (left[1] ? arg.sub(/\A(\[?)=/, '\1') + ',' : arg)
+ end
+ mlen = left.collect {|ss| ss.length}.max.to_i
+ while mlen > width and l = left.shift
+ mlen = left.collect {|ss| ss.length}.max.to_i if l.length == mlen
+ if l.length < width and (r = right[0]) and !r.empty?
+ l = l.to_s.ljust(width) + ' ' + r
+ right.shift
+ end
+ yield(indent + l)
+ end
+
+ while begin l = left.shift; r = right.shift; l or r end
+ l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
+ yield(indent + l)
+ end
+
+ self
+ end
+
+ def add_banner(to) # :nodoc:
+ unless @short or @long
+ s = desc.join
+ to << " [" + s + "]..." unless s.empty?
+ end
+ to
+ end
+
+ def match_nonswitch?(str) # :nodoc:
+ @pattern =~ str unless @short or @long
+ end
+
+ #
+ # Main name of the switch.
+ #
+ def switch_name
+ (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
+ end
+
+ def compsys(sdone, ldone) # :nodoc:
+ sopts, lopts = [], []
+ @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
+ @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
+ return if sopts.empty? and lopts.empty? # completely hidden
+
+ (sopts+lopts).each do |opt|
+ # "(-x -c -r)-l[left justify]"
+ if /^--\[no-\](.+)$/ =~ opt
+ o = $1
+ yield("--#{o}", desc.join(""))
+ yield("--no-#{o}", desc.join(""))
+ else
+ yield("#{opt}", desc.join(""))
+ end
+ end
+ end
+
+ def pretty_print_contents(q) # :nodoc:
+ if @block
+ q.text ":" + @block.source_location.join(":") + ":"
+ first = false
+ else
+ first = true
+ end
+ [@short, @long].each do |list|
+ list.each do |opt|
+ if first
+ q.text ":"
+ first = false
+ end
+ q.breakable
+ q.text opt
+ end
+ end
+ end
+
+ def pretty_print(q) # :nodoc:
+ q.object_group(self) {pretty_print_contents(q)}
+ end
+
+ #
+ # Switch that takes no arguments.
+ #
+ class NoArgument < self
+
+ #
+ # Raises an exception if any arguments given.
+ #
+ def parse(arg, argv)
+ yield(NeedlessArgument, arg) if arg
+ conv_arg(arg)
+ end
+
+ def self.incompatible_argument_styles(*)
+ end
+
+ def self.pattern
+ Object
+ end
+
+ def pretty_head # :nodoc:
+ "NoArgument"
+ end
+ end
+
+ #
+ # Switch that takes an argument.
+ #
+ class RequiredArgument < self
+
+ #
+ # Raises an exception if argument is not present.
+ #
+ def parse(arg, argv)
+ unless arg
+ raise MissingArgument if argv.empty?
+ arg = argv.shift
+ end
+ conv_arg(*parse_arg(arg, &method(:raise)))
+ end
+
+ def pretty_head # :nodoc:
+ "Required"
+ end
+ end
+
+ #
+ # Switch that can omit argument.
+ #
+ class OptionalArgument < self
+
+ #
+ # Parses argument if given, or uses default value.
+ #
+ def parse(arg, argv, &error)
+ if arg
+ conv_arg(*parse_arg(arg, &error))
+ else
+ conv_arg(arg)
+ end
+ end
+
+ def pretty_head # :nodoc:
+ "Optional"
+ end
+ end
+
+ #
+ # Switch that takes an argument, which does not begin with '-' or is '-'.
+ #
+ class PlacedArgument < self
+
+ #
+ # Returns nil if argument is not present or begins with '-' and is not '-'.
+ #
+ def parse(arg, argv, &error)
+ if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0]))
+ return nil, block, nil
+ end
+ opt = (val = parse_arg(val, &error))[1]
+ val = conv_arg(*val)
+ if opt and !arg
+ argv.shift
+ else
+ val[0] = nil
+ end
+ val
+ end
+
+ def pretty_head # :nodoc:
+ "Placed"
+ end
+ end
+ end
+
+ #
+ # Simple option list providing mapping from short and/or long option
+ # string to Gem::OptionParser::Switch and mapping from acceptable argument to
+ # matching pattern and converter pair. Also provides summary feature.
+ #
+ class List
+ # Map from acceptable argument types to pattern and converter pairs.
+ attr_reader :atype
+
+ # Map from short style option switches to actual switch objects.
+ attr_reader :short
+
+ # Map from long style option switches to actual switch objects.
+ attr_reader :long
+
+ # List of all switches and summary string.
+ attr_reader :list
+
+ #
+ # Just initializes all instance variables.
+ #
+ def initialize
+ @atype = {}
+ @short = OptionMap.new
+ @long = OptionMap.new
+ @list = []
+ end
+
+ def pretty_print(q) # :nodoc:
+ q.group(1, "(", ")") do
+ @list.each do |sw|
+ next unless Switch === sw
+ q.group(1, "(" + sw.pretty_head, ")") do
+ sw.pretty_print_contents(q)
+ end
+ end
+ end
+ end
+
+ #
+ # See Gem::OptionParser.accept.
+ #
+ def accept(t, pat = /.*/m, &block)
+ if pat
+ pat.respond_to?(:match) or
+ raise TypeError, "has no `match'", ParseError.filter_backtrace(caller(2))
+ else
+ pat = t if t.respond_to?(:match)
+ end
+ unless block
+ block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
+ end
+ @atype[t] = [pat, block]
+ end
+
+ #
+ # See Gem::OptionParser.reject.
+ #
+ def reject(t)
+ @atype.delete(t)
+ end
+
+ #
+ # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.
+ #
+ # +sw+:: Gem::OptionParser::Switch instance to be added.
+ # +sopts+:: Short style option list.
+ # +lopts+:: Long style option list.
+ # +nlopts+:: Negated long style options list.
+ #
+ def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
+ sopts.each {|o| @short[o] = sw} if sopts
+ lopts.each {|o| @long[o] = sw} if lopts
+ nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
+ used = @short.invert.update(@long.invert)
+ @list.delete_if {|o| Switch === o and !used[o]}
+ end
+ private :update
+
+ #
+ # Inserts +switch+ at the head of the list, and associates short, long
+ # and negated long options. Arguments are:
+ #
+ # +switch+:: Gem::OptionParser::Switch instance to be inserted.
+ # +short_opts+:: List of short style options.
+ # +long_opts+:: List of long style options.
+ # +nolong_opts+:: List of long style options with "no-" prefix.
+ #
+ # prepend(switch, short_opts, long_opts, nolong_opts)
+ #
+ def prepend(*args)
+ update(*args)
+ @list.unshift(args[0])
+ end
+
+ #
+ # Appends +switch+ at the tail of the list, and associates short, long
+ # and negated long options. Arguments are:
+ #
+ # +switch+:: Gem::OptionParser::Switch instance to be inserted.
+ # +short_opts+:: List of short style options.
+ # +long_opts+:: List of long style options.
+ # +nolong_opts+:: List of long style options with "no-" prefix.
+ #
+ # append(switch, short_opts, long_opts, nolong_opts)
+ #
+ def append(*args)
+ update(*args)
+ @list.push(args[0])
+ end
+
+ #
+ # Searches +key+ in +id+ list. The result is returned or yielded if a
+ # block is given. If it isn't found, nil is returned.
+ #
+ def search(id, key)
+ if list = __send__(id)
+ val = list.fetch(key) {return nil}
+ block_given? ? yield(val) : val
+ end
+ end
+
+ #
+ # Searches list +id+ for +opt+ and the optional patterns for completion
+ # +pat+. If +icase+ is true, the search is case insensitive. The result
+ # is returned or yielded if a block is given. If it isn't found, nil is
+ # returned.
+ #
+ def complete(id, opt, icase = false, *pat, &block)
+ __send__(id).complete(opt, icase, *pat, &block)
+ end
+
+ def get_candidates(id)
+ yield __send__(id).keys
+ end
+
+ #
+ # Iterates over each option, passing the option to the +block+.
+ #
+ def each_option(&block)
+ list.each(&block)
+ end
+
+ #
+ # Creates the summary table, passing each line to the +block+ (without
+ # newline). The arguments +args+ are passed along to the summarize
+ # method which is called on every option.
+ #
+ def summarize(*args, &block)
+ sum = []
+ list.reverse_each do |opt|
+ if opt.respond_to?(:summarize) # perhaps Gem::OptionParser::Switch
+ s = []
+ opt.summarize(*args) {|l| s << l}
+ sum.concat(s.reverse)
+ elsif !opt or opt.empty?
+ sum << ""
+ elsif opt.respond_to?(:each_line)
+ sum.concat([*opt.each_line].reverse)
+ else
+ sum.concat([*opt.each].reverse)
+ end
+ end
+ sum.reverse_each(&block)
+ end
+
+ def add_banner(to) # :nodoc:
+ list.each do |opt|
+ if opt.respond_to?(:add_banner)
+ opt.add_banner(to)
+ end
+ end
+ to
+ end
+
+ def compsys(*args, &block) # :nodoc:
+ list.each do |opt|
+ if opt.respond_to?(:compsys)
+ opt.compsys(*args, &block)
+ end
+ end
+ end
+ end
+
+ #
+ # Hash with completion search feature. See Gem::OptionParser::Completion.
+ #
+ class CompletingHash < Hash
+ include Completion
+
+ #
+ # Completion for hash key.
+ #
+ def match(key)
+ *values = fetch(key) {
+ raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
+ }
+ return key, *values
+ end
+ end
+
+ # :stopdoc:
+
+ #
+ # Enumeration of acceptable argument styles. Possible values are:
+ #
+ # NO_ARGUMENT:: The switch takes no arguments. (:NONE)
+ # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)
+ # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)
+ #
+ # Use like --switch=argument (long style) or -Xargument (short style). For
+ # short style, only portion matched to argument pattern is treated as
+ # argument.
+ #
+ ArgumentStyle = {}
+ NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}
+ RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}
+ OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}
+ ArgumentStyle.freeze
+
+ #
+ # Switches common used such as '--', and also provides default
+ # argument classes
+ #
+ DefaultList = List.new
+ DefaultList.short['-'] = Switch::NoArgument.new {}
+ DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
+
+
+ COMPSYS_HEADER = <<'XXX' # :nodoc:
+
+typeset -A opt_args
+local context state line
+
+_arguments -s -S \
+XXX
+
+ def compsys(to, name = File.basename($0)) # :nodoc:
+ to << "#compdef #{name}\n"
+ to << COMPSYS_HEADER
+ visit(:compsys, {}, {}) {|o, d|
+ to << %Q[ "#{o}[#{d.gsub(/[\"\[\]]/, '\\\\\&')}]" \\\n]
+ }
+ to << " '*:file:_files' && return 0\n"
+ end
+
+ #
+ # Default options for ARGV, which never appear in option summary.
+ #
+ Officious = {}
+
+ #
+ # --help
+ # Shows option summary.
+ #
+ Officious['help'] = proc do |parser|
+ Switch::NoArgument.new do |arg|
+ puts parser.help
+ exit
+ end
+ end
+
+ #
+ # --*-completion-bash=WORD
+ # Shows candidates for command line completion.
+ #
+ Officious['*-completion-bash'] = proc do |parser|
+ Switch::RequiredArgument.new do |arg|
+ puts parser.candidate(arg)
+ exit
+ end
+ end
+
+ #
+ # --*-completion-zsh[=NAME:FILE]
+ # Creates zsh completion file.
+ #
+ Officious['*-completion-zsh'] = proc do |parser|
+ Switch::OptionalArgument.new do |arg|
+ parser.compsys(STDOUT, arg)
+ exit
+ end
+ end
+
+ #
+ # --version
+ # Shows version string if Version is defined.
+ #
+ Officious['version'] = proc do |parser|
+ Switch::OptionalArgument.new do |pkg|
+ if pkg
+ begin
+ require 'rubygems/optparse/lib/optparse/version'
+ rescue LoadError
+ else
+ show_version(*pkg.split(/,/)) or
+ abort("#{parser.program_name}: no version found in package #{pkg}")
+ exit
+ end
+ end
+ v = parser.ver or abort("#{parser.program_name}: version unknown")
+ puts v
+ exit
+ end
+ end
+
+ # :startdoc:
+
+ #
+ # Class methods
+ #
+
+ #
+ # Initializes a new instance and evaluates the optional block in context
+ # of the instance. Arguments +args+ are passed to #new, see there for
+ # description of parameters.
+ #
+ # This method is *deprecated*, its behavior corresponds to the older #new
+ # method.
+ #
+ def self.with(*args, &block)
+ opts = new(*args)
+ opts.instance_eval(&block)
+ opts
+ end
+
+ #
+ # Returns an incremented value of +default+ according to +arg+.
+ #
+ def self.inc(arg, default = nil)
+ case arg
+ when Integer
+ arg.nonzero?
+ when nil
+ default.to_i + 1
+ end
+ end
+ def inc(*args)
+ self.class.inc(*args)
+ end
+
+ #
+ # Initializes the instance and yields itself if called with a block.
+ #
+ # +banner+:: Banner message.
+ # +width+:: Summary width.
+ # +indent+:: Summary indent.
+ #
+ def initialize(banner = nil, width = 32, indent = ' ' * 4)
+ @stack = [DefaultList, List.new, List.new]
+ @program_name = nil
+ @banner = banner
+ @summary_width = width
+ @summary_indent = indent
+ @default_argv = ARGV
+ @require_exact = false
+ @raise_unknown = true
+ add_officious
+ yield self if block_given?
+ end
+
+ def add_officious # :nodoc:
+ list = base()
+ Officious.each do |opt, block|
+ list.long[opt] ||= block.call(self)
+ end
+ end
+
+ #
+ # Terminates option parsing. Optional parameter +arg+ is a string pushed
+ # back to be the first non-option argument.
+ #
+ def terminate(arg = nil)
+ self.class.terminate(arg)
+ end
+ def self.terminate(arg = nil)
+ throw :terminate, arg
+ end
+
+ @stack = [DefaultList]
+ def self.top() DefaultList end
+
+ #
+ # Directs to accept specified class +t+. The argument string is passed to
+ # the block in which it should be converted to the desired class.
+ #
+ # +t+:: Argument class specifier, any object including Class.
+ # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.
+ #
+ # accept(t, pat, &block)
+ #
+ def accept(*args, &blk) top.accept(*args, &blk) end
+ #
+ # See #accept.
+ #
+ def self.accept(*args, &blk) top.accept(*args, &blk) end
+
+ #
+ # Directs to reject specified class argument.
+ #
+ # +t+:: Argument class specifier, any object including Class.
+ #
+ # reject(t)
+ #
+ def reject(*args, &blk) top.reject(*args, &blk) end
+ #
+ # See #reject.
+ #
+ def self.reject(*args, &blk) top.reject(*args, &blk) end
+
+ #
+ # Instance methods
+ #
+
+ # Heading banner preceding summary.
+ attr_writer :banner
+
+ # Program name to be emitted in error message and default banner,
+ # defaults to $0.
+ attr_writer :program_name
+
+ # Width for option list portion of summary. Must be Numeric.
+ attr_accessor :summary_width
+
+ # Indentation for summary. Must be String (or have + String method).
+ attr_accessor :summary_indent
+
+ # Strings to be parsed in default.
+ attr_accessor :default_argv
+
+ # Whether to require that options match exactly (disallows providing
+ # abbreviated long option as short option).
+ attr_accessor :require_exact
+
+ # Whether to raise at unknown option.
+ attr_accessor :raise_unknown
+
+ #
+ # Heading banner preceding summary.
+ #
+ def banner
+ unless @banner
+ @banner = +"Usage: #{program_name} [options]"
+ visit(:add_banner, @banner)
+ end
+ @banner
+ end
+
+ #
+ # Program name to be emitted in error message and default banner, defaults
+ # to $0.
+ #
+ def program_name
+ @program_name || File.basename($0, '.*')
+ end
+
+ # for experimental cascading :-)
+ alias set_banner banner=
+ alias set_program_name program_name=
+ alias set_summary_width summary_width=
+ alias set_summary_indent summary_indent=
+
+ # Version
+ attr_writer :version
+ # Release code
+ attr_writer :release
+
+ #
+ # Version
+ #
+ def version
+ (defined?(@version) && @version) || (defined?(::Version) && ::Version)
+ end
+
+ #
+ # Release code
+ #
+ def release
+ (defined?(@release) && @release) || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
+ end
+
+ #
+ # Returns version string from program_name, version and release.
+ #
+ def ver
+ if v = version
+ str = +"#{program_name} #{[v].join('.')}"
+ str << " (#{v})" if v = release
+ str
+ end
+ end
+
+ def warn(mesg = $!)
+ super("#{program_name}: #{mesg}")
+ end
+
+ def abort(mesg = $!)
+ super("#{program_name}: #{mesg}")
+ end
+
+ #
+ # Subject of #on / #on_head, #accept / #reject
+ #
+ def top
+ @stack[-1]
+ end
+
+ #
+ # Subject of #on_tail.
+ #
+ def base
+ @stack[1]
+ end
+
+ #
+ # Pushes a new List.
+ #
+ def new
+ @stack.push(List.new)
+ if block_given?
+ yield self
+ else
+ self
+ end
+ end
+
+ #
+ # Removes the last List.
+ #
+ def remove
+ @stack.pop
+ end
+
+ #
+ # Puts option summary into +to+ and returns +to+. Yields each line if
+ # a block is given.
+ #
+ # +to+:: Output destination, which must have method <<. Defaults to [].
+ # +width+:: Width of left side, defaults to @summary_width.
+ # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.
+ # +indent+:: Indentation, defaults to @summary_indent.
+ #
+ def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
+ nl = "\n"
+ blk ||= proc {|l| to << (l.index(nl, -1) ? l : l + nl)}
+ visit(:summarize, {}, {}, width, max, indent, &blk)
+ to
+ end
+
+ #
+ # Returns option summary string.
+ #
+ def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end
+ alias to_s help
+
+ def pretty_print(q) # :nodoc:
+ q.object_group(self) do
+ first = true
+ if @stack.size > 2
+ @stack.each_with_index do |s, i|
+ next if i < 2
+ next if s.list.empty?
+ if first
+ first = false
+ q.text ":"
+ end
+ q.breakable
+ s.pretty_print(q)
+ end
+ end
+ end
+ end
+
+ def inspect # :nodoc:
+ require 'pp'
+ pretty_print_inspect
+ end
+
+ #
+ # Returns option summary list.
+ #
+ def to_a; summarize("#{banner}".split(/^/)) end
+
+ #
+ # Checks if an argument is given twice, in which case an ArgumentError is
+ # raised. Called from Gem::OptionParser#switch only.
+ #
+ # +obj+:: New argument.
+ # +prv+:: Previously specified argument.
+ # +msg+:: Exception message.
+ #
+ def notwice(obj, prv, msg) # :nodoc:
+ unless !prv or prv == obj
+ raise(ArgumentError, "argument #{msg} given twice: #{obj}",
+ ParseError.filter_backtrace(caller(2)))
+ end
+ obj
+ end
+ private :notwice
+
+ SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
+
+ # :call-seq:
+ # make_switch(params, block = nil)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def make_switch(opts, block = nil)
+ short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
+ ldesc, sdesc, desc, arg = [], [], []
+ default_style = Switch::NoArgument
+ default_pattern = nil
+ klass = nil
+ q, a = nil
+ has_arg = false
+
+ opts.each do |o|
+ # argument class
+ next if search(:atype, o) do |pat, c|
+ klass = notwice(o, klass, 'type')
+ if not_style and not_style != Switch::NoArgument
+ not_pattern, not_conv = pat, c
+ else
+ default_pattern, conv = pat, c
+ end
+ end
+
+ # directly specified pattern(any object possible to match)
+ if (!(String === o || Symbol === o)) and o.respond_to?(:match)
+ pattern = notwice(o, pattern, 'pattern')
+ if pattern.respond_to?(:convert)
+ conv = pattern.method(:convert).to_proc
+ else
+ conv = SPLAT_PROC
+ end
+ next
+ end
+
+ # anything others
+ case o
+ when Proc, Method
+ block = notwice(o, block, 'block')
+ when Array, Hash
+ case pattern
+ when CompletingHash
+ when nil
+ pattern = CompletingHash.new
+ conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
+ else
+ raise ArgumentError, "argument pattern given twice"
+ end
+ o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
+ when Module
+ raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
+ when *ArgumentStyle.keys
+ style = notwice(ArgumentStyle[o], style, 'style')
+ when /^--no-([^\[\]=\s]*)(.+)?/
+ q, a = $1, $2
+ o = notwice(a ? Object : TrueClass, klass, 'type')
+ not_pattern, not_conv = search(:atype, o) unless not_style
+ not_style = (not_style || default_style).guess(arg = a) if a
+ default_style = Switch::NoArgument
+ default_pattern, conv = search(:atype, FalseClass) unless default_pattern
+ ldesc << "--no-#{q}"
+ (q = q.downcase).tr!('_', '-')
+ long << "no-#{q}"
+ nolong << q
+ when /^--\[no-\]([^\[\]=\s]*)(.+)?/
+ q, a = $1, $2
+ o = notwice(a ? Object : TrueClass, klass, 'type')
+ if a
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ end
+ ldesc << "--[no-]#{q}"
+ (o = q.downcase).tr!('_', '-')
+ long << o
+ not_pattern, not_conv = search(:atype, FalseClass) unless not_style
+ not_style = Switch::NoArgument
+ nolong << "no-#{o}"
+ when /^--([^\[\]=\s]*)(.+)?/
+ q, a = $1, $2
+ if a
+ o = notwice(NilClass, klass, 'type')
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ end
+ ldesc << "--#{q}"
+ (o = q.downcase).tr!('_', '-')
+ long << o
+ when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
+ q, a = $1, $2
+ o = notwice(Object, klass, 'type')
+ if a
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ else
+ has_arg = true
+ end
+ sdesc << "-#{q}"
+ short << Regexp.new(q)
+ when /^-(.)(.+)?/
+ q, a = $1, $2
+ if a
+ o = notwice(NilClass, klass, 'type')
+ default_style = default_style.guess(arg = a)
+ default_pattern, conv = search(:atype, o) unless default_pattern
+ end
+ sdesc << "-#{q}"
+ short << q
+ when /^=/
+ style = notwice(default_style.guess(arg = o), style, 'style')
+ default_pattern, conv = search(:atype, Object) unless default_pattern
+ else
+ desc.push(o) if o && !o.empty?
+ end
+ end
+
+ default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
+ if !(short.empty? and long.empty?)
+ if has_arg and default_style == Switch::NoArgument
+ default_style = Switch::RequiredArgument
+ end
+ s = (style || default_style).new(pattern || default_pattern,
+ conv, sdesc, ldesc, arg, desc, block)
+ elsif !block
+ if style or pattern
+ raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
+ end
+ s = desc
+ else
+ short << pattern
+ s = (style || default_style).new(pattern,
+ conv, nil, nil, arg, desc, block)
+ end
+ return s, short, long,
+ (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
+ nolong
+ end
+
+ # :call-seq:
+ # define(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def define(*opts, &block)
+ top.append(*(sw = make_switch(opts, block)))
+ sw[0]
+ end
+
+ # :call-seq:
+ # on(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def on(*opts, &block)
+ define(*opts, &block)
+ self
+ end
+ alias def_option define
+
+ # :call-seq:
+ # define_head(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def define_head(*opts, &block)
+ top.prepend(*(sw = make_switch(opts, block)))
+ sw[0]
+ end
+
+ # :call-seq:
+ # on_head(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ # The new option is added at the head of the summary.
+ #
+ def on_head(*opts, &block)
+ define_head(*opts, &block)
+ self
+ end
+ alias def_head_option define_head
+
+ # :call-seq:
+ # define_tail(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ def define_tail(*opts, &block)
+ base.append(*(sw = make_switch(opts, block)))
+ sw[0]
+ end
+
+ #
+ # :call-seq:
+ # on_tail(*params, &block)
+ #
+ # :include: ../doc/optparse/creates_option.rdoc
+ #
+ # The new option is added at the tail of the summary.
+ #
+ def on_tail(*opts, &block)
+ define_tail(*opts, &block)
+ self
+ end
+ alias def_tail_option define_tail
+
+ #
+ # Add separator in summary.
+ #
+ def separator(string)
+ top.append(string, nil, nil)
+ end
+
+ #
+ # Parses command line arguments +argv+ in order. When a block is given,
+ # each non-option argument is yielded. When optional +into+ keyword
+ # argument is provided, the parsed option values are stored there via
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
+ # similar object).
+ #
+ # Returns the rest of +argv+ left unparsed.
+ #
+ def order(*argv, into: nil, &nonopt)
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
+ order!(argv, into: into, &nonopt)
+ end
+
+ #
+ # Same as #order, but removes switches destructively.
+ # Non-option arguments remain in +argv+.
+ #
+ def order!(argv = default_argv, into: nil, &nonopt)
+ setter = ->(name, val) {into[name.to_sym] = val} if into
+ parse_in_order(argv, setter, &nonopt)
+ end
+
+ def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc:
+ opt, arg, val, rest = nil
+ nonopt ||= proc {|a| throw :terminate, a}
+ argv.unshift(arg) if arg = catch(:terminate) {
+ while arg = argv.shift
+ case arg
+ # long option
+ when /\A--([^=]*)(?:=(.*))?/m
+ opt, rest = $1, $2
+ opt.tr!('_', '-')
+ begin
+ sw, = complete(:long, opt, true)
+ if require_exact && !sw.long.include?(arg)
+ throw :terminate, arg unless raise_unknown
+ raise InvalidOption, arg
+ end
+ rescue ParseError
+ throw :terminate, arg unless raise_unknown
+ raise $!.set_option(arg, true)
+ end
+ begin
+ opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
+ val = cb.call(val) if cb
+ setter.call(sw.switch_name, val) if setter
+ rescue ParseError
+ raise $!.set_option(arg, rest)
+ end
+
+ # short option
+ when /\A-(.)((=).*|.+)?/m
+ eq, rest, opt = $3, $2, $1
+ has_arg, val = eq, rest
+ begin
+ sw, = search(:short, opt)
+ unless sw
+ begin
+ sw, = complete(:short, opt)
+ # short option matched.
+ val = arg.delete_prefix('-')
+ has_arg = true
+ rescue InvalidOption
+ raise if require_exact
+ # if no short options match, try completion with long
+ # options.
+ sw, = complete(:long, opt)
+ eq ||= !rest
+ end
+ end
+ rescue ParseError
+ throw :terminate, arg unless raise_unknown
+ raise $!.set_option(arg, true)
+ end
+ begin
+ opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
+ rescue ParseError
+ raise $!.set_option(arg, arg.length > 2)
+ else
+ raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
+ end
+ begin
+ argv.unshift(opt) if opt and (!rest or (opt = opt.sub(/\A-*/, '-')) != '-')
+ val = cb.call(val) if cb
+ setter.call(sw.switch_name, val) if setter
+ rescue ParseError
+ raise $!.set_option(arg, arg.length > 2)
+ end
+
+ # non-option argument
+ else
+ catch(:prune) do
+ visit(:each_option) do |sw0|
+ sw = sw0
+ sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)
+ end
+ nonopt.call(arg)
+ end
+ end
+ end
+
+ nil
+ }
+
+ visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}
+
+ argv
+ end
+ private :parse_in_order
+
+ #
+ # Parses command line arguments +argv+ in permutation mode and returns
+ # list of non-option arguments. When optional +into+ keyword
+ # argument is provided, the parsed option values are stored there via
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
+ # similar object).
+ #
+ def permute(*argv, into: nil)
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
+ permute!(argv, into: into)
+ end
+
+ #
+ # Same as #permute, but removes switches destructively.
+ # Non-option arguments remain in +argv+.
+ #
+ def permute!(argv = default_argv, into: nil)
+ nonopts = []
+ order!(argv, into: into, &nonopts.method(:<<))
+ argv[0, 0] = nonopts
+ argv
+ end
+
+ #
+ # Parses command line arguments +argv+ in order when environment variable
+ # POSIXLY_CORRECT is set, and in permutation mode otherwise.
+ # When optional +into+ keyword argument is provided, the parsed option
+ # values are stored there via <code>[]=</code> method (so it can be Hash,
+ # or OpenStruct, or other similar object).
+ #
+ def parse(*argv, into: nil)
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
+ parse!(argv, into: into)
+ end
+
+ #
+ # Same as #parse, but removes switches destructively.
+ # Non-option arguments remain in +argv+.
+ #
+ def parse!(argv = default_argv, into: nil)
+ if ENV.include?('POSIXLY_CORRECT')
+ order!(argv, into: into)
+ else
+ permute!(argv, into: into)
+ end
+ end
+
+ #
+ # Wrapper method for getopts.rb.
+ #
+ # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option")
+ # # params["a"] = true # -a
+ # # params["b"] = "1" # -b1
+ # # params["foo"] = "1" # --foo
+ # # params["bar"] = "x" # --bar x
+ # # params["zot"] = "z" # --zot Z
+ #
+ def getopts(*args)
+ argv = Array === args.first ? args.shift : default_argv
+ single_options, *long_options = *args
+
+ result = {}
+
+ single_options.scan(/(.)(:)?/) do |opt, val|
+ if val
+ result[opt] = nil
+ define("-#{opt} VAL")
+ else
+ result[opt] = false
+ define("-#{opt}")
+ end
+ end if single_options
+
+ long_options.each do |arg|
+ arg, desc = arg.split(';', 2)
+ opt, val = arg.split(':', 2)
+ if val
+ result[opt] = val.empty? ? nil : val
+ define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact)
+ else
+ result[opt] = false
+ define("--#{opt}", *[desc].compact)
+ end
+ end
+
+ parse_in_order(argv, result.method(:[]=))
+ result
+ end
+
+ #
+ # See #getopts.
+ #
+ def self.getopts(*args)
+ new.getopts(*args)
+ end
+
+ #
+ # Traverses @stack, sending each element method +id+ with +args+ and
+ # +block+.
+ #
+ def visit(id, *args, &block) # :nodoc:
+ @stack.reverse_each do |el|
+ el.__send__(id, *args, &block)
+ end
+ nil
+ end
+ private :visit
+
+ #
+ # Searches +key+ in @stack for +id+ hash and returns or yields the result.
+ #
+ def search(id, key) # :nodoc:
+ block_given = block_given?
+ visit(:search, id, key) do |k|
+ return block_given ? yield(k) : k
+ end
+ end
+ private :search
+
+ #
+ # Completes shortened long style option switch and returns pair of
+ # canonical switch and switch descriptor Gem::OptionParser::Switch.
+ #
+ # +typ+:: Searching table.
+ # +opt+:: Searching key.
+ # +icase+:: Search case insensitive if true.
+ # +pat+:: Optional pattern for completion.
+ #
+ def complete(typ, opt, icase = false, *pat) # :nodoc:
+ if pat.empty?
+ search(typ, opt) {|sw| return [sw, opt]} # exact match or...
+ end
+ ambiguous = catch(:ambiguous) {
+ visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
+ }
+ exc = ambiguous ? AmbiguousOption : InvalidOption
+ raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
+ end
+ private :complete
+
+ #
+ # Returns additional info.
+ #
+ def additional_message(typ, opt)
+ return unless typ and opt and defined?(DidYouMean::SpellChecker)
+ all_candidates = []
+ visit(:get_candidates, typ) do |candidates|
+ all_candidates.concat(candidates)
+ end
+ all_candidates.select! {|cand| cand.is_a?(String) }
+ checker = DidYouMean::SpellChecker.new(dictionary: all_candidates)
+ DidYouMean.formatter.message_for(all_candidates & checker.correct(opt))
+ end
+
+ def candidate(word)
+ list = []
+ case word
+ when '-'
+ long = short = true
+ when /\A--/
+ word, arg = word.split(/=/, 2)
+ argpat = Completion.regexp(arg, false) if arg and !arg.empty?
+ long = true
+ when /\A-/
+ short = true
+ end
+ pat = Completion.regexp(word, long)
+ visit(:each_option) do |opt|
+ next unless Switch === opt
+ opts = (long ? opt.long : []) + (short ? opt.short : [])
+ opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
+ if /\A=/ =~ opt.arg
+ opts.map! {|sw| sw + "="}
+ if arg and CompletingHash === opt.pattern
+ if opts = opt.pattern.candidate(arg, false, argpat)
+ opts.map!(&:last)
+ end
+ end
+ end
+ list.concat(opts)
+ end
+ list
+ end
+
+ #
+ # Loads options from file names as +filename+. Does nothing when the file
+ # is not present. Returns whether successfully loaded.
+ #
+ # +filename+ defaults to basename of the program without suffix in a
+ # directory ~/.options, then the basename with '.options' suffix
+ # under XDG and Haiku standard places.
+ #
+ # The optional +into+ keyword argument works exactly like that accepted in
+ # method #parse.
+ #
+ def load(filename = nil, into: nil)
+ unless filename
+ basename = File.basename($0, '.*')
+ return true if load(File.expand_path(basename, '~/.options'), into: into) rescue nil
+ basename << ".options"
+ return [
+ # XDG
+ ENV['XDG_CONFIG_HOME'],
+ '~/.config',
+ *ENV['XDG_CONFIG_DIRS']&.split(File::PATH_SEPARATOR),
+
+ # Haiku
+ '~/config/settings',
+ ].any? {|dir|
+ next if !dir or dir.empty?
+ load(File.expand_path(basename, dir), into: into) rescue nil
+ }
+ end
+ begin
+ parse(*File.readlines(filename, chomp: true), into: into)
+ true
+ rescue Errno::ENOENT, Errno::ENOTDIR
+ false
+ end
+ end
+
+ #
+ # Parses environment variable +env+ or its uppercase with splitting like a
+ # shell.
+ #
+ # +env+ defaults to the basename of the program.
+ #
+ def environment(env = File.basename($0, '.*'))
+ env = ENV[env] || ENV[env.upcase] or return
+ require 'shellwords'
+ parse(*Shellwords.shellwords(env))
+ end
+
+ #
+ # Acceptable argument classes
+ #
+
+ #
+ # Any string and no conversion. This is fall-back.
+ #
+ accept(Object) {|s,|s or s.nil?}
+
+ accept(NilClass) {|s,|s}
+
+ #
+ # Any non-empty string, and no conversion.
+ #
+ accept(String, /.+/m) {|s,*|s}
+
+ #
+ # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal
+ # for 0x, and decimal for others; with optional sign prefix. Converts to
+ # Integer.
+ #
+ decimal = '\d+(?:_\d+)*'
+ binary = 'b[01]+(?:_[01]+)*'
+ hex = 'x[\da-f]+(?:_[\da-f]+)*'
+ octal = "0(?:[0-7]+(?:_[0-7]+)*|#{binary}|#{hex})?"
+ integer = "#{octal}|#{decimal}"
+
+ accept(Integer, %r"\A[-+]?(?:#{integer})\z"io) {|s,|
+ begin
+ Integer(s)
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Float number format, and converts to Float.
+ #
+ float = "(?:#{decimal}(?=(.)?)(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
+ floatpat = %r"\A[-+]?#{float}\z"io
+ accept(Float, floatpat) {|s,| s.to_f if s}
+
+ #
+ # Generic numeric format, converts to Integer for integer format, Float
+ # for float format, and Rational for rational format.
+ #
+ real = "[-+]?(?:#{octal}|#{float})"
+ accept(Numeric, /\A(#{real})(?:\/(#{real}))?\z/io) {|s, d, f, n,|
+ if n
+ Rational(d, n)
+ elsif f
+ Float(s)
+ else
+ Integer(s)
+ end
+ }
+
+ #
+ # Decimal integer format, to be converted to Integer.
+ #
+ DecimalInteger = /\A[-+]?#{decimal}\z/io
+ accept(DecimalInteger, DecimalInteger) {|s,|
+ begin
+ Integer(s, 10)
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Ruby/C like octal/hexadecimal/binary integer format, to be converted to
+ # Integer.
+ #
+ OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))\z/io
+ accept(OctalInteger, OctalInteger) {|s,|
+ begin
+ Integer(s, 8)
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Decimal integer/float number format, to be converted to Integer for
+ # integer format, Float for float format.
+ #
+ DecimalNumeric = floatpat # decimal integer is allowed as float also.
+ accept(DecimalNumeric, floatpat) {|s, f|
+ begin
+ if f
+ Float(s)
+ else
+ Integer(s)
+ end
+ rescue ArgumentError
+ raise Gem::OptionParser::InvalidArgument, s
+ end if s
+ }
+
+ #
+ # Boolean switch, which means whether it is present or not, whether it is
+ # absent or not with prefix no-, or it takes an argument
+ # yes/no/true/false/+/-.
+ #
+ yesno = CompletingHash.new
+ %w[- no false].each {|el| yesno[el] = false}
+ %w[+ yes true].each {|el| yesno[el] = true}
+ yesno['nil'] = false # should be nil?
+ accept(TrueClass, yesno) {|arg, val| val == nil or val}
+ #
+ # Similar to TrueClass, but defaults to false.
+ #
+ accept(FalseClass, yesno) {|arg, val| val != nil and val}
+
+ #
+ # List of strings separated by ",".
+ #
+ accept(Array) do |s, |
+ if s
+ s = s.split(',').collect {|ss| ss unless ss.empty?}
+ end
+ s
+ end
+
+ #
+ # Regular expression with options.
+ #
+ accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o|
+ f = 0
+ if o
+ f |= Regexp::IGNORECASE if /i/ =~ o
+ f |= Regexp::MULTILINE if /m/ =~ o
+ f |= Regexp::EXTENDED if /x/ =~ o
+ k = o.delete("imx")
+ k = nil if k.empty?
+ end
+ Regexp.new(s || all, f, k)
+ end
+
+ #
+ # Exceptions
+ #
+
+ #
+ # Base class of exceptions from Gem::OptionParser.
+ #
+ class ParseError < RuntimeError
+ # Reason which caused the error.
+ Reason = 'parse error'
+
+ def initialize(*args, additional: nil)
+ @additional = additional
+ @arg0, = args
+ @args = args
+ @reason = nil
+ end
+
+ attr_reader :args
+ attr_writer :reason
+ attr_accessor :additional
+
+ #
+ # Pushes back erred argument(s) to +argv+.
+ #
+ def recover(argv)
+ argv[0, 0] = @args
+ argv
+ end
+
+ def self.filter_backtrace(array)
+ unless $DEBUG
+ array.delete_if(&%r"\A#{Regexp.quote(__FILE__)}:"o.method(:=~))
+ end
+ array
+ end
+
+ def set_backtrace(array)
+ super(self.class.filter_backtrace(array))
+ end
+
+ def set_option(opt, eq)
+ if eq
+ @args[0] = opt
+ else
+ @args.unshift(opt)
+ end
+ self
+ end
+
+ #
+ # Returns error reason. Override this for I18N.
+ #
+ def reason
+ @reason || self.class::Reason
+ end
+
+ def inspect
+ "#<#{self.class}: #{args.join(' ')}>"
+ end
+
+ #
+ # Default stringizing method to emit standard error message.
+ #
+ def message
+ "#{reason}: #{args.join(' ')}#{additional[@arg0] if additional}"
+ end
+
+ alias to_s message
+ end
+
+ #
+ # Raises when ambiguously completable string is encountered.
+ #
+ class AmbiguousOption < ParseError
+ const_set(:Reason, 'ambiguous option')
+ end
+
+ #
+ # Raises when there is an argument for a switch which takes no argument.
+ #
+ class NeedlessArgument < ParseError
+ const_set(:Reason, 'needless argument')
+ end
+
+ #
+ # Raises when a switch with mandatory argument has no argument.
+ #
+ class MissingArgument < ParseError
+ const_set(:Reason, 'missing argument')
+ end
+
+ #
+ # Raises when switch is undefined.
+ #
+ class InvalidOption < ParseError
+ const_set(:Reason, 'invalid option')
+ end
+
+ #
+ # Raises when the given argument does not match required format.
+ #
+ class InvalidArgument < ParseError
+ const_set(:Reason, 'invalid argument')
+ end
+
+ #
+ # Raises when the given argument word can't be completed uniquely.
+ #
+ class AmbiguousArgument < InvalidArgument
+ const_set(:Reason, 'ambiguous argument')
+ end
+
+ #
+ # Miscellaneous
+ #
+
+ #
+ # Extends command line arguments array (ARGV) to parse itself.
+ #
+ module Arguable
+
+ #
+ # Sets Gem::OptionParser object, when +opt+ is +false+ or +nil+, methods
+ # Gem::OptionParser::Arguable#options and Gem::OptionParser::Arguable#options= are
+ # undefined. Thus, there is no ways to access the Gem::OptionParser object
+ # via the receiver object.
+ #
+ def options=(opt)
+ unless @optparse = opt
+ class << self
+ undef_method(:options)
+ undef_method(:options=)
+ end
+ end
+ end
+
+ #
+ # Actual Gem::OptionParser object, automatically created if nonexistent.
+ #
+ # If called with a block, yields the Gem::OptionParser object and returns the
+ # result of the block. If an Gem::OptionParser::ParseError exception occurs
+ # in the block, it is rescued, a error message printed to STDERR and
+ # +nil+ returned.
+ #
+ def options
+ @optparse ||= Gem::OptionParser.new
+ @optparse.default_argv = self
+ block_given? or return @optparse
+ begin
+ yield @optparse
+ rescue ParseError
+ @optparse.warn $!
+ nil
+ end
+ end
+
+ #
+ # Parses +self+ destructively in order and returns +self+ containing the
+ # rest arguments left unparsed.
+ #
+ def order!(&blk) options.order!(self, &blk) end
+
+ #
+ # Parses +self+ destructively in permutation mode and returns +self+
+ # containing the rest arguments left unparsed.
+ #
+ def permute!() options.permute!(self) end
+
+ #
+ # Parses +self+ destructively and returns +self+ containing the
+ # rest arguments left unparsed.
+ #
+ def parse!() options.parse!(self) end
+
+ #
+ # Substitution of getopts is possible as follows. Also see
+ # Gem::OptionParser#getopts.
+ #
+ # def getopts(*args)
+ # ($OPT = ARGV.getopts(*args)).each do |opt, val|
+ # eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
+ # end
+ # rescue Gem::OptionParser::ParseError
+ # end
+ #
+ def getopts(*args)
+ options.getopts(self, *args)
+ end
+
+ #
+ # Initializes instance variable.
+ #
+ def self.extend_object(obj)
+ super
+ obj.instance_eval {@optparse = nil}
+ end
+ def initialize(*args)
+ super
+ @optparse = nil
+ end
+ end
+
+ #
+ # Acceptable argument classes. Now contains DecimalInteger, OctalInteger
+ # and DecimalNumeric. See Acceptable argument classes (in source code).
+ #
+ module Acceptables
+ const_set(:DecimalInteger, Gem::OptionParser::DecimalInteger)
+ const_set(:OctalInteger, Gem::OptionParser::OctalInteger)
+ const_set(:DecimalNumeric, Gem::OptionParser::DecimalNumeric)
+ end
+end
+
+# ARGV is arguable by Gem::OptionParser
+ARGV.extend(Gem::OptionParser::Arguable)
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/ac.rb b/lib/rubygems/optparse/lib/optparse/ac.rb
index e84d01bf91..e84d01bf91 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse/ac.rb
+++ b/lib/rubygems/optparse/lib/optparse/ac.rb
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/date.rb b/lib/rubygems/optparse/lib/optparse/date.rb
index d9a9f4f48a..d9a9f4f48a 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse/date.rb
+++ b/lib/rubygems/optparse/lib/optparse/date.rb
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/kwargs.rb b/lib/rubygems/optparse/lib/optparse/kwargs.rb
index 6987a5ed62..6987a5ed62 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse/kwargs.rb
+++ b/lib/rubygems/optparse/lib/optparse/kwargs.rb
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/shellwords.rb b/lib/rubygems/optparse/lib/optparse/shellwords.rb
index d47ad60255..d47ad60255 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse/shellwords.rb
+++ b/lib/rubygems/optparse/lib/optparse/shellwords.rb
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/time.rb b/lib/rubygems/optparse/lib/optparse/time.rb
index c59e1e4ced..c59e1e4ced 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse/time.rb
+++ b/lib/rubygems/optparse/lib/optparse/time.rb
diff --git a/lib/rubygems/optparse/lib/optparse/uri.rb b/lib/rubygems/optparse/lib/optparse/uri.rb
new file mode 100644
index 0000000000..664d7f2af4
--- /dev/null
+++ b/lib/rubygems/optparse/lib/optparse/uri.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: false
+# -*- ruby -*-
+
+require_relative '../optparse'
+require 'uri'
+
+Gem::OptionParser.accept(URI) {|s,| URI.parse(s) if s}
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/version.rb b/lib/rubygems/optparse/lib/optparse/version.rb
index 5d79e9db44..5d79e9db44 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse/version.rb
+++ b/lib/rubygems/optparse/lib/optparse/version.rb
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
index c855423ed7..f28d521bdf 100644
--- a/lib/rubygems/package.rb
+++ b/lib/rubygems/package.rb
@@ -1,12 +1,11 @@
# frozen_string_literal: true
-# rubocop:disable Style/AsciiComments
-
+#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
+#++
-# rubocop:enable Style/AsciiComments
-
+require_relative "../rubygems"
require_relative "security"
require_relative "user_interaction"
@@ -58,9 +57,9 @@ class Gem::Package
def initialize(message, source = nil)
if source
- @path = source.is_a?(String) ? source : source.path
+ @path = source.path
- message += " in #{path}" if path
+ message = message + " in #{path}" if path
end
super message
@@ -69,13 +68,15 @@ class Gem::Package
class PathError < Error
def initialize(destination, destination_dir)
- super format("installing into parent path %s of %s is not allowed", destination, destination_dir)
+ super "installing into parent path %s of %s is not allowed" %
+ [destination, destination_dir]
end
end
class SymlinkError < Error
def initialize(name, destination, destination_dir)
- super format("installing symlink '%s' pointing to parent path %s of %s is not allowed", name, destination, destination_dir)
+ super "installing symlink '%s' pointing to parent path %s of %s is not allowed" %
+ [name, destination, destination_dir]
end
end
@@ -154,7 +155,7 @@ class Gem::Package
Gem::Package::FileSource.new gem
end
- return super unless self == Gem::Package
+ return super unless Gem::Package == self
return super unless gem.present?
return super unless gem.start
@@ -186,7 +187,7 @@ class Gem::Package
end
end
- [spec, metadata]
+ return spec, metadata
end
##
@@ -229,7 +230,7 @@ class Gem::Package
end
end
- tar.add_file_signed "checksums.yaml.gz", 0o444, @signer do |io|
+ tar.add_file_signed "checksums.yaml.gz", 0444, @signer do |io|
gzip_to io do |gz_io|
Psych.dump checksums_by_algorithm, gz_io
end
@@ -241,7 +242,7 @@ class Gem::Package
# and adds this file to the +tar+.
def add_contents(tar) # :nodoc:
- digests = tar.add_file_signed "data.tar.gz", 0o444, @signer do |io|
+ digests = tar.add_file_signed "data.tar.gz", 0444, @signer do |io|
gzip_to io do |gz_io|
Gem::Package::TarWriter.new gz_io do |data_tar|
add_files data_tar
@@ -267,7 +268,7 @@ class Gem::Package
tar.add_file_simple file, stat.mode, stat.size do |dst_io|
File.open file, "rb" do |src_io|
- copy_stream(src_io, dst_io)
+ dst_io.write src_io.read 16384 until src_io.eof?
end
end
end
@@ -277,7 +278,7 @@ class Gem::Package
# Adds the package's Gem::Specification to the +tar+ file
def add_metadata(tar) # :nodoc:
- digests = tar.add_file_signed "metadata.gz", 0o444, @signer do |io|
+ digests = tar.add_file_signed "metadata.gz", 0444, @signer do |io|
gzip_to io do |gz_io|
gz_io.write @spec.to_yaml
end
@@ -294,6 +295,7 @@ class Gem::Package
Gem.load_yaml
+ @spec.mark_version
@spec.validate true, strict_validation unless skip_validation
setup_signer(
@@ -345,8 +347,6 @@ EOM
return @contents
end
end
- rescue Zlib::GzipFile::Error, EOFError, Gem::Package::TarInvalidError => e
- raise Gem::Package::FormatError.new e.message, @gem
end
##
@@ -355,21 +355,18 @@ EOM
def digest(entry) # :nodoc:
algorithms = if @checksums
- @checksums.to_h {|algorithm, _| [algorithm, Gem::Security.create_digest(algorithm)] }
- elsif Gem::Security::DIGEST_NAME
- { Gem::Security::DIGEST_NAME => Gem::Security.create_digest(Gem::Security::DIGEST_NAME) }
+ @checksums.keys
+ else
+ [Gem::Security::DIGEST_NAME].compact
end
- return @digests if algorithms.nil? || algorithms.empty?
+ algorithms.each do |algorithm|
+ digester = Gem::Security.create_digest(algorithm)
- buf = String.new(capacity: 16_384, encoding: Encoding::BINARY)
- until entry.eof?
- entry.readpartial(16_384, buf)
- algorithms.each_value {|digester| digester << buf }
- end
- entry.rewind
+ digester << entry.read(16384) until entry.eof?
+
+ entry.rewind
- algorithms.each do |algorithm, digester|
@digests[algorithm][entry.full_name] = digester
end
@@ -385,7 +382,7 @@ EOM
def extract_files(destination_dir, pattern = "*")
verify unless @spec
- FileUtils.mkdir_p destination_dir, mode: dir_mode && 0o755
+ FileUtils.mkdir_p destination_dir, :mode => dir_mode && 0755
@gem.with_read_io do |io|
reader = Gem::Package::TarReader.new io
@@ -395,11 +392,9 @@ EOM
extract_tar_gz entry, destination_dir, pattern
- break # ignore further entries
+ return # ignore further entries
end
end
- rescue Zlib::GzipFile::Error, EOFError, Gem::Package::TarInvalidError => e
- raise Gem::Package::FormatError.new e.message, @gem
end
##
@@ -414,8 +409,6 @@ EOM
# extracted.
def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc:
- destination_dir = File.realpath(destination_dir)
-
directories = []
symlinks = []
@@ -438,6 +431,8 @@ EOM
FileUtils.rm_rf destination
+ mkdir_options = {}
+ mkdir_options[:mode] = dir_mode ? 0755 : (entry.header.mode if entry.directory?)
mkdir =
if entry.directory?
destination
@@ -446,13 +441,13 @@ EOM
end
unless directories.include?(mkdir)
- FileUtils.mkdir_p mkdir, mode: dir_mode ? 0o755 : (entry.header.mode if entry.directory?)
+ FileUtils.mkdir_p mkdir, **mkdir_options
directories << mkdir
end
if entry.file?
- File.open(destination, "wb") {|out| copy_stream(entry, out) }
- FileUtils.chmod file_mode(entry.header.mode) & ~File.umask, destination
+ File.open(destination, "wb") {|out| out.write entry.read }
+ FileUtils.chmod file_mode(entry.header.mode), destination
end
verbose destination
@@ -473,7 +468,7 @@ EOM
end
def file_mode(mode) # :nodoc:
- ((mode & 0o111).zero? ? data_mode : prog_mode) ||
+ ((mode & 0111).zero? ? data_mode : prog_mode) ||
# If we're not using one of the default modes, then we're going to fall
# back to the mode from the tarball. In this case we need to mask it down
# to fit into 2^16 bits (the maximum value for a mode in CRuby since it
@@ -511,6 +506,7 @@ EOM
raise Gem::Package::PathError.new(destination, destination_dir) unless
normalize_path(destination).start_with? normalize_path(destination_dir + "/")
+ destination.tap(&Gem::UNTAINT)
destination
end
@@ -526,13 +522,12 @@ EOM
# Loads a Gem::Specification from the TarEntry +entry+
def load_spec(entry) # :nodoc:
- limit = 10 * 1024 * 1024
case entry.full_name
when "metadata" then
- @spec = Gem::Specification.from_yaml limit_read(entry, "metadata", limit)
+ @spec = Gem::Specification.from_yaml entry.read
when "metadata.gz" then
Zlib::GzipReader.wrap(entry, external_encoding: Encoding::UTF_8) do |gzio|
- @spec = Gem::Specification.from_yaml limit_read(gzio, "metadata.gz", limit)
+ @spec = Gem::Specification.from_yaml gzio.read
end
end
end
@@ -556,7 +551,7 @@ EOM
@checksums = gem.seek "checksums.yaml.gz" do |entry|
Zlib::GzipReader.wrap entry do |gz_io|
- Gem::SafeYAML.safe_load limit_read(gz_io, "checksums.yaml.gz", 10 * 1024 * 1024)
+ Gem::SafeYAML.safe_load gz_io.read
end
end
end
@@ -577,10 +572,10 @@ EOM
)
@spec.signing_key = nil
- @spec.cert_chain = @signer.cert_chain.map(&:to_s)
+ @spec.cert_chain = @signer.cert_chain.map {|cert| cert.to_s }
else
@signer = Gem::Security::Signer.new nil, nil, passphrase
- @spec.cert_chain = @signer.cert_chain.map(&:to_pem) if
+ @spec.cert_chain = @signer.cert_chain.map {|cert| cert.to_pem } if
@signer.cert_chain
end
end
@@ -631,7 +626,7 @@ EOM
raise
rescue Errno::ENOENT => e
raise Gem::Package::FormatError.new e.message
- rescue Zlib::GzipFile::Error, EOFError, Gem::Package::TarInvalidError => e
+ rescue Gem::Package::TarInvalidError => e
raise Gem::Package::FormatError.new e.message, @gem
end
@@ -663,7 +658,7 @@ EOM
case file_name
when /\.sig$/ then
- @signatures[$`] = limit_read(entry, file_name, 1024 * 1024) if @security_policy
+ @signatures[$`] = entry.read if @security_policy
return
else
digest entry
@@ -675,7 +670,7 @@ EOM
when "data.tar.gz" then
verify_gz entry
end
- rescue StandardError
+ rescue
warn "Exception while verifying #{@gem.path}"
raise
end
@@ -694,11 +689,11 @@ EOM
unless @files.include? "data.tar.gz"
raise Gem::Package::FormatError.new \
- "package content (data.tar.gz) is missing", @gem
+ "package content (data.tar.gz) is missing", @gem
end
- if (duplicates = @files.group_by {|f| f }.select {|_k,v| v.size > 1 }.map(&:first)) && duplicates.any?
- raise Gem::Security::Exception, "duplicate files in the package: (#{duplicates.map(&:inspect).join(", ")})"
+ if (duplicates = @files.group_by {|f| f }.select {|k,v| v.size > 1 }.map(&:first)) && duplicates.any?
+ raise Gem::Security::Exception, "duplicate files in the package: (#{duplicates.map(&:inspect).join(', ')})"
end
end
@@ -707,28 +702,11 @@ EOM
def verify_gz(entry) # :nodoc:
Zlib::GzipReader.wrap entry do |gzio|
- # TODO: read into a buffer once zlib supports it
- gzio.read 16_384 until gzio.eof? # gzip checksum verification
+ gzio.read 16384 until gzio.eof? # gzip checksum verification
end
rescue Zlib::GzipFile::Error => e
raise Gem::Package::FormatError.new(e.message, entry.full_name)
end
-
- if RUBY_ENGINE == "truffleruby"
- def copy_stream(src, dst) # :nodoc:
- dst.write src.read
- end
- else
- def copy_stream(src, dst) # :nodoc:
- IO.copy_stream(src, dst)
- end
- end
-
- def limit_read(io, name, limit)
- bytes = io.read(limit + 1)
- raise Gem::Package::FormatError, "#{name} is too big (over #{limit} bytes)" if bytes.size > limit
- bytes
- end
end
require_relative "package/digest_io"
diff --git a/lib/rubygems/package/digest_io.rb b/lib/rubygems/package/digest_io.rb
index f04ab97462..1572cb9f2c 100644
--- a/lib/rubygems/package/digest_io.rb
+++ b/lib/rubygems/package/digest_io.rb
@@ -36,7 +36,7 @@ class Gem::Package::DigestIO
yield digest_io
- digests
+ return digests
end
##
diff --git a/lib/rubygems/package/old.rb b/lib/rubygems/package/old.rb
index 1a13ac3e29..bf0ed61b0a 100644
--- a/lib/rubygems/package/old.rb
+++ b/lib/rubygems/package/old.rb
@@ -70,7 +70,7 @@ class Gem::Package::Old < Gem::Package
file_data << line
end
- file_data = file_data.strip.unpack1("m")
+ file_data = file_data.strip.unpack("m")[0]
file_data = Zlib::Inflate.inflate file_data
raise Gem::Package::FormatError, "#{full_name} in #{@gem} is corrupt" if
@@ -78,7 +78,7 @@ class Gem::Package::Old < Gem::Package
FileUtils.rm_rf destination
- FileUtils.mkdir_p File.dirname(destination), mode: dir_mode && 0o755
+ FileUtils.mkdir_p File.dirname(destination), :mode => dir_mode && 0755
File.open destination, "wb", file_mode(entry["mode"]) do |out|
out.write file_data
diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb
index dd5e835a1e..99bd755f90 100644
--- a/lib/rubygems/package/tar_header.rb
+++ b/lib/rubygems/package/tar_header.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: true
-# rubocop:disable Style/AsciiComments
-
+#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
-
-# rubocop:enable Style/AsciiComments
+#++
##
#--
@@ -95,40 +93,39 @@ class Gem::Package::TarHeader
attr_reader(*FIELDS)
- EMPTY_HEADER = ("\0" * 512).b.freeze # :nodoc:
+ EMPTY_HEADER = ("\0" * 512).freeze # :nodoc:
##
# Creates a tar header from IO +stream+
def self.from(stream)
header = stream.read 512
- return EMPTY if header == EMPTY_HEADER
+ empty = (EMPTY_HEADER == header)
fields = header.unpack UNPACK_FORMAT
- new name: fields.shift,
- mode: strict_oct(fields.shift),
- uid: oct_or_256based(fields.shift),
- gid: oct_or_256based(fields.shift),
- size: strict_oct(fields.shift),
- mtime: strict_oct(fields.shift),
- checksum: strict_oct(fields.shift),
- typeflag: fields.shift,
- linkname: fields.shift,
- magic: fields.shift,
- version: strict_oct(fields.shift),
- uname: fields.shift,
- gname: fields.shift,
- devmajor: strict_oct(fields.shift),
- devminor: strict_oct(fields.shift),
- prefix: fields.shift,
-
- empty: false
+ new :name => fields.shift,
+ :mode => strict_oct(fields.shift),
+ :uid => oct_or_256based(fields.shift),
+ :gid => oct_or_256based(fields.shift),
+ :size => strict_oct(fields.shift),
+ :mtime => strict_oct(fields.shift),
+ :checksum => strict_oct(fields.shift),
+ :typeflag => fields.shift,
+ :linkname => fields.shift,
+ :magic => fields.shift,
+ :version => strict_oct(fields.shift),
+ :uname => fields.shift,
+ :gname => fields.shift,
+ :devmajor => strict_oct(fields.shift),
+ :devminor => strict_oct(fields.shift),
+ :prefix => fields.shift,
+
+ :empty => empty
end
def self.strict_oct(str)
- str.strip!
- return str.oct if /\A[0-7]*\z/.match?(str)
+ return str.strip.oct if str.strip =~ /\A[0-7]*\z/
raise ArgumentError, "#{str.inspect} is not an octal string"
end
@@ -138,8 +135,7 @@ class Gem::Package::TarHeader
# \ff flags a negative 256-based number
# In case we have a match, parse it as a signed binary value
# in big-endian order, except that the high-order bit is ignored.
-
- return str.unpack1("@4N") if /\A[\x80\xff]/n.match?(str)
+ return str.unpack("N2").last if str =~ /\A[\x80\xff]/n
strict_oct(str)
end
@@ -151,43 +147,25 @@ class Gem::Package::TarHeader
raise ArgumentError, ":name, :size, :prefix and :mode required"
end
- @checksum = vals[:checksum] || ""
- @devmajor = vals[:devmajor] || 0
- @devminor = vals[:devminor] || 0
- @gid = vals[:gid] || 0
- @gname = vals[:gname] || "wheel"
- @linkname = vals[:linkname]
- @magic = vals[:magic] || "ustar"
- @mode = vals[:mode]
- @mtime = vals[:mtime] || 0
- @name = vals[:name]
- @prefix = vals[:prefix]
- @size = vals[:size]
- @typeflag = vals[:typeflag]
- @typeflag = "0" if @typeflag.nil? || @typeflag.empty?
- @uid = vals[:uid] || 0
- @uname = vals[:uname] || "wheel"
- @version = vals[:version] || "00"
+ vals[:uid] ||= 0
+ vals[:gid] ||= 0
+ vals[:mtime] ||= 0
+ vals[:checksum] ||= ""
+ vals[:typeflag] = "0" if vals[:typeflag].nil? || vals[:typeflag].empty?
+ vals[:magic] ||= "ustar"
+ vals[:version] ||= "00"
+ vals[:uname] ||= "wheel"
+ vals[:gname] ||= "wheel"
+ vals[:devmajor] ||= 0
+ vals[:devminor] ||= 0
+
+ FIELDS.each do |name|
+ instance_variable_set "@#{name}", vals[name]
+ end
@empty = vals[:empty]
end
- EMPTY = new({ # :nodoc:
- checksum: 0,
- gname: "",
- linkname: "",
- magic: "",
- mode: 0,
- name: "",
- prefix: "",
- size: 0,
- uname: "",
- version: 0,
-
- empty: true,
- }).freeze
- private_constant :EMPTY
-
##
# Is the tar entry empty?
@@ -257,10 +235,10 @@ class Gem::Package::TarHeader
header = header.pack PACK_FORMAT
- header.ljust 512, "\0"
+ header << ("\0" * ((512 - header.size) % 512))
end
def oct(num, len)
- format("%0#{len}o", num)
+ "%0#{len}o" % num
end
end
diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb
index 25f9b2f945..a8dd39c572 100644
--- a/lib/rubygems/package/tar_reader.rb
+++ b/lib/rubygems/package/tar_reader.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: true
-# rubocop:disable Style/AsciiComments
-
+#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
-
-# rubocop:enable Style/AsciiComments
+#++
##
# TarReader reads tar files and allows iteration over their items
@@ -14,6 +12,11 @@ class Gem::Package::TarReader
include Enumerable
##
+ # Raised if the tar IO is not seekable
+
+ class UnexpectedEOF < StandardError; end
+
+ ##
# Creates a new TarReader on +io+ and yields it to the block, if given.
def self.new(io)
@@ -52,14 +55,7 @@ class Gem::Package::TarReader
return enum_for __method__ unless block_given?
until @io.eof? do
- begin
- header = Gem::Package::TarHeader.from @io
- rescue ArgumentError => e
- # Specialize only exceptions from Gem::Package::TarHeader.strict_oct
- raise e unless e.message.match?(/ is not an octal string$/)
- raise Gem::Package::TarInvalidError, e.message
- end
-
+ header = Gem::Package::TarHeader.from @io
return if header.empty?
entry = Gem::Package::TarReader::Entry.new header, @io
yield entry
@@ -67,7 +63,7 @@ class Gem::Package::TarReader
end
end
- alias_method :each_entry, :each
+ alias each_entry each
##
# NOTE: Do not call #rewind during #each
@@ -92,7 +88,7 @@ class Gem::Package::TarReader
return unless found
- yield found
+ return yield found
ensure
rewind
end
diff --git a/lib/rubygems/package/tar_reader/entry.rb b/lib/rubygems/package/tar_reader/entry.rb
index 5e9d9af5c6..e770079f41 100644
--- a/lib/rubygems/package/tar_reader/entry.rb
+++ b/lib/rubygems/package/tar_reader/entry.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: true
-# rubocop:disable Style/AsciiComments
-
+#++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
-
-# rubocop:enable Style/AsciiComments
+#--
##
# Class for reading entries out of a tar file
@@ -102,7 +100,9 @@ class Gem::Package::TarReader::Entry
# Read one byte from the tar entry
def getc
- return nil if eof?
+ check_closed
+
+ return nil if @read >= @header.size
ret = @io.getc
@read += 1 if ret
@@ -145,37 +145,40 @@ class Gem::Package::TarReader::Entry
def pos=(new_pos)
seek(new_pos, IO::SEEK_SET)
+ new_pos
end
def size
@header.size
end
- alias_method :length, :size
+ alias length size
##
- # Reads +maxlen+ bytes from the tar file entry, or the rest of the entry if nil
+ # Reads +len+ bytes from the tar file entry, or the rest of the entry if
+ # nil
- def read(maxlen = nil)
- if eof?
- return maxlen.to_i.zero? ? "" : nil
- end
+ def read(len = nil)
+ check_closed
+
+ len ||= @header.size - @read
- max_read = [maxlen, @header.size - @read].compact.min
+ return nil if len > 0 && @read >= @header.size
+
+ max_read = [len, @header.size - @read].min
ret = @io.read max_read
- if ret.nil?
- return maxlen ? nil : "" # IO.read returns nil on EOF with len argument
- end
@read += ret.size
ret
end
- def readpartial(maxlen, outbuf = "".b)
- if eof? && maxlen > 0
- raise EOFError, "end of file reached"
- end
+ def readpartial(maxlen = nil, outbuf = "".b)
+ check_closed
+
+ maxlen ||= @header.size - @read
+
+ raise EOFError if maxlen > 0 && @read >= @header.size
max_read = [maxlen, @header.size - @read].min
@@ -209,8 +212,6 @@ class Gem::Package::TarReader::Entry
pending = new_pos - @io.pos
- return 0 if pending == 0
-
if @io.respond_to?(:seek)
begin
# avoid reading if the @io supports seeking
@@ -228,8 +229,8 @@ class Gem::Package::TarReader::Entry
end
while pending > 0 do
- size_read = @io.read([pending, 4096].min)&.size
- raise(EOFError, "end of file reached") if size_read.nil?
+ size_read = @io.read([pending, 4096].min).size
+ raise UnexpectedEOF if @io.eof?
pending -= size_read
end
diff --git a/lib/rubygems/package/tar_writer.rb b/lib/rubygems/package/tar_writer.rb
index b24bdb63e7..32a13e9162 100644
--- a/lib/rubygems/package/tar_writer.rb
+++ b/lib/rubygems/package/tar_writer.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: true
-# rubocop:disable Style/AsciiComments
-
+#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
-
-# rubocop:enable Style/AsciiComments
+#++
##
# Allows writing of tar files
@@ -116,9 +114,9 @@ class Gem::Package::TarWriter
final_pos = @io.pos
@io.pos = init_pos
- header = Gem::Package::TarHeader.new name: name, mode: mode,
- size: size, prefix: prefix,
- mtime: Gem.source_date_epoch
+ header = Gem::Package::TarHeader.new :name => name, :mode => mode,
+ :size => size, :prefix => prefix,
+ :mtime => Gem.source_date_epoch
@io.write header
@io.pos = final_pos
@@ -192,7 +190,7 @@ class Gem::Package::TarWriter
if signer.key
signature = signer.sign signature_digest.digest
- add_file_simple "#{name}.sig", 0o444, signature.length do |io|
+ add_file_simple "#{name}.sig", 0444, signature.length do |io|
io.write signature
end
end
@@ -209,9 +207,9 @@ class Gem::Package::TarWriter
name, prefix = split_name name
- header = Gem::Package::TarHeader.new(name: name, mode: mode,
- size: size, prefix: prefix,
- mtime: Gem.source_date_epoch).to_s
+ header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
+ :size => size, :prefix => prefix,
+ :mtime => Gem.source_date_epoch).to_s
@io.write header
os = BoundedStream.new @io, size
@@ -235,11 +233,11 @@ class Gem::Package::TarWriter
name, prefix = split_name name
- header = Gem::Package::TarHeader.new(name: name, mode: mode,
- size: 0, typeflag: "2",
- linkname: target,
- prefix: prefix,
- mtime: Gem.source_date_epoch).to_s
+ header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
+ :size => 0, :typeflag => "2",
+ :linkname => target,
+ :prefix => prefix,
+ :mtime => Gem.source_date_epoch).to_s
@io.write header
@@ -289,10 +287,10 @@ class Gem::Package::TarWriter
name, prefix = split_name(name)
- header = Gem::Package::TarHeader.new name: name, mode: mode,
- typeflag: "5", size: 0,
- prefix: prefix,
- mtime: Gem.source_date_epoch
+ header = Gem::Package::TarHeader.new :name => name, :mode => mode,
+ :typeflag => "5", :size => 0,
+ :prefix => prefix,
+ :mtime => Gem.source_date_epoch
@io.write header
@@ -326,6 +324,6 @@ class Gem::Package::TarWriter
end
end
- [name, prefix]
+ return name, prefix
end
end
diff --git a/lib/rubygems/package_task.rb b/lib/rubygems/package_task.rb
index d26411684d..a67d8cb916 100644
--- a/lib/rubygems/package_task.rb
+++ b/lib/rubygems/package_task.rb
@@ -97,13 +97,13 @@ class Gem::PackageTask < Rake::PackageTask
gem_path = File.join package_dir, gem_file
gem_dir = File.join package_dir, gem_spec.full_name
- task package: [:gem]
+ task :package => [:gem]
directory package_dir
directory gem_dir
desc "Build the gem file #{gem_file}"
- task gem: [gem_path]
+ task :gem => [gem_path]
trace = Rake.application.options.trace
Gem.configuration.verbose = trace
diff --git a/lib/rubygems/path_support.rb b/lib/rubygems/path_support.rb
index 13091e29ba..d9df543ad9 100644
--- a/lib/rubygems/path_support.rb
+++ b/lib/rubygems/path_support.rb
@@ -24,22 +24,23 @@ class Gem::PathSupport
# hashtable, or defaults to ENV, the system environment.
#
def initialize(env)
- @home = normalize_home_dir(env["GEM_HOME"] || Gem.default_dir)
+ @home = env["GEM_HOME"] || Gem.default_dir
+
+ if File::ALT_SEPARATOR
+ @home = @home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
+ end
+
+ @home = expand(@home)
+
@path = split_gem_path env["GEM_PATH"], @home
@spec_cache_dir = env["GEM_SPEC_CACHE"] || Gem.default_spec_cache_dir
+
+ @spec_cache_dir = @spec_cache_dir.dup.tap(&Gem::UNTAINT)
end
private
- def normalize_home_dir(home)
- if File::ALT_SEPARATOR
- home = home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
- end
-
- expand(home)
- end
-
##
# Split the Gem search path (as reported by Gem.path).
@@ -52,7 +53,7 @@ class Gem::PathSupport
gem_path = gpaths.split(Gem.path_separator)
# Handle the path_separator being set to a regexp, which will cause
# end_with? to error
- if /#{Gem.path_separator}\z/.match?(gpaths)
+ if gpaths =~ /#{Gem.path_separator}\z/
gem_path += default_path
end
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index d54ad12880..b721629b78 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -13,22 +13,15 @@ class Gem::Platform
attr_accessor :cpu, :os, :version
def self.local
- @local ||= begin
- arch = RbConfig::CONFIG["arch"]
- arch = "#{arch}_60" if /mswin(?:32|64)$/.match?(arch)
- new(arch)
- end
+ arch = RbConfig::CONFIG["arch"]
+ arch = "#{arch}_60" if arch =~ /mswin(?:32|64)$/
+ @local ||= new(arch)
end
def self.match(platform)
match_platforms?(platform, Gem.platforms)
end
- class << self
- extend Gem::Deprecate
- rubygems_deprecate :match, "Gem::Platform.match_spec? or match_gem?"
- end
-
def self.match_platforms?(platform, platforms)
platform = Gem::Platform.new(platform) unless platform.is_a?(Gem::Platform)
platforms.any? do |local_platform|
@@ -43,20 +36,10 @@ class Gem::Platform
match_gem?(spec.platform, spec.name)
end
- if RUBY_ENGINE == "truffleruby"
- def self.match_gem?(platform, gem_name)
- raise "Not a string: #{gem_name.inspect}" unless String === gem_name
-
- if REUSE_AS_BINARY_ON_TRUFFLERUBY.include?(gem_name)
- match_platforms?(platform, [Gem::Platform::RUBY, Gem::Platform.local])
- else
- match_platforms?(platform, Gem.platforms)
- end
- end
- else
- def self.match_gem?(platform, gem_name)
- match_platforms?(platform, Gem.platforms)
- end
+ def self.match_gem?(platform, gem_name)
+ # Note: this method might be redefined by Ruby implementations to
+ # customize behavior per RUBY_ENGINE, gem_name or other criteria.
+ match_platforms?(platform, Gem.platforms)
end
def self.sort_priority(platform)
@@ -89,7 +72,7 @@ class Gem::Platform
when String then
arch = arch.split "-"
- if arch.length > 2 && !arch.last.match?(/\d+(\.\d+)?$/) # reassemble x86-linux-{libc}
+ if arch.length > 2 && arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc}
extra = arch.pop
arch.last << "-#{extra}"
end
@@ -97,47 +80,42 @@ class Gem::Platform
cpu = arch.shift
@cpu = case cpu
- when /i\d86/ then "x86"
- else cpu
+ when /i\d86/ then "x86"
+ else cpu
end
- if arch.length == 2 && arch.last.match?(/^\d+(\.\d+)?$/) # for command-line
+ if arch.length == 2 && arch.last =~ /^\d+(\.\d+)?$/ # for command-line
@os, @version = arch
return
end
os, = arch
- if os.nil?
- @cpu = nil
- os = cpu
- end # legacy jruby
+ @cpu, os = nil, cpu if os.nil? # legacy jruby
@os, @version = case os
- when /aix(\d+)?/ then ["aix", $1]
- when /cygwin/ then ["cygwin", nil]
- when /darwin(\d+)?/ then ["darwin", $1]
- when /^macruby$/ then ["macruby", nil]
- when /freebsd(\d+)?/ then ["freebsd", $1]
- when /^java$/, /^jruby$/ then ["java", nil]
- when /^java([\d.]*)/ then ["java", $1]
- when /^dalvik(\d+)?$/ then ["dalvik", $1]
- when /^dotnet$/ then ["dotnet", nil]
- when /^dotnet([\d.]*)/ then ["dotnet", $1]
- when /linux-?(\w+)?/ then ["linux", $1]
- when /mingw32/ then ["mingw32", nil]
- when /mingw-?(\w+)?/ then ["mingw", $1]
- when /(mswin\d+)(\_(\d+))?/ then
- os = $1
- version = $3
- @cpu = "x86" if @cpu.nil? && os =~ /32$/
- [os, version]
- when /netbsdelf/ then ["netbsdelf", nil]
- when /openbsd(\d+\.\d+)?/ then ["openbsd", $1]
- when /solaris(\d+\.\d+)?/ then ["solaris", $1]
- when /wasi/ then ["wasi", nil]
- # test
- when /^(\w+_platform)(\d+)?/ then [$1, $2]
- else ["unknown", nil]
+ when /aix(\d+)?/ then [ "aix", $1 ]
+ when /cygwin/ then [ "cygwin", nil ]
+ when /darwin(\d+)?/ then [ "darwin", $1 ]
+ when /^macruby$/ then [ "macruby", nil ]
+ when /freebsd(\d+)?/ then [ "freebsd", $1 ]
+ when /^java$/, /^jruby$/ then [ "java", nil ]
+ when /^java([\d.]*)/ then [ "java", $1 ]
+ when /^dalvik(\d+)?$/ then [ "dalvik", $1 ]
+ when /^dotnet$/ then [ "dotnet", nil ]
+ when /^dotnet([\d.]*)/ then [ "dotnet", $1 ]
+ when /linux-?(\w+)?/ then [ "linux", $1 ]
+ when /mingw32/ then [ "mingw32", nil ]
+ when /mingw-?(\w+)?/ then [ "mingw", $1 ]
+ when /(mswin\d+)(\_(\d+))?/ then
+ os, version = $1, $3
+ @cpu = "x86" if @cpu.nil? && os =~ /32$/
+ [os, version]
+ when /netbsdelf/ then [ "netbsdelf", nil ]
+ when /openbsd(\d+\.\d+)?/ then [ "openbsd", $1 ]
+ when /solaris(\d+\.\d+)?/ then [ "solaris", $1 ]
+ # test
+ when /^(\w+_platform)(\d+)?/ then [ $1, $2 ]
+ else [ "unknown", nil ]
end
when Gem::Platform then
@cpu = arch.cpu
@@ -164,7 +142,7 @@ class Gem::Platform
self.class === other && to_a == other.to_a
end
- alias_method :eql?, :==
+ alias :eql? :==
def hash # :nodoc:
to_a.hash
@@ -232,18 +210,18 @@ class Gem::Platform
when String then
# This data is from http://gems.rubyforge.org/gems/yaml on 19 Aug 2007
other = case other
- when /^i686-darwin(\d)/ then ["x86", "darwin", $1]
- when /^i\d86-linux/ then ["x86", "linux", nil]
- when "java", "jruby" then [nil, "java", nil]
- when /^dalvik(\d+)?$/ then [nil, "dalvik", $1]
- when /dotnet(\-(\d+\.\d+))?/ then ["universal","dotnet", $2]
- when /mswin32(\_(\d+))?/ then ["x86", "mswin32", $2]
- when /mswin64(\_(\d+))?/ then ["x64", "mswin64", $2]
- when "powerpc-darwin" then ["powerpc", "darwin", nil]
- when /powerpc-darwin(\d)/ then ["powerpc", "darwin", $1]
- when /sparc-solaris2.8/ then ["sparc", "solaris", "2.8"]
- when /universal-darwin(\d)/ then ["universal", "darwin", $1]
- else other
+ when /^i686-darwin(\d)/ then ["x86", "darwin", $1 ]
+ when /^i\d86-linux/ then ["x86", "linux", nil ]
+ when "java", "jruby" then [nil, "java", nil ]
+ when /^dalvik(\d+)?$/ then [nil, "dalvik", $1 ]
+ when /dotnet(\-(\d+\.\d+))?/ then ["universal","dotnet", $2 ]
+ when /mswin32(\_(\d+))?/ then ["x86", "mswin32", $2 ]
+ when /mswin64(\_(\d+))?/ then ["x64", "mswin64", $2 ]
+ when "powerpc-darwin" then ["powerpc", "darwin", nil ]
+ when /powerpc-darwin(\d)/ then ["powerpc", "darwin", $1 ]
+ when /sparc-solaris2.8/ then ["sparc", "solaris", "2.8" ]
+ when /universal-darwin(\d)/ then ["universal", "darwin", $1 ]
+ else other
end
other = Gem::Platform.new other
diff --git a/lib/rubygems/query_utils.rb b/lib/rubygems/query_utils.rb
index a95a759401..c72955f83b 100644
--- a/lib/rubygems/query_utils.rb
+++ b/lib/rubygems/query_utils.rb
@@ -6,6 +6,7 @@ require_relative "version_option"
require_relative "text"
module Gem::QueryUtils
+
include Gem::Text
include Gem::LocalRemoteOptions
include Gem::VersionOption
@@ -16,7 +17,7 @@ module Gem::QueryUtils
options[:installed] = value
end
- add_option("-I", "Equivalent to --no-installed") do |_value, options|
+ add_option("-I", "Equivalent to --no-installed") do |value, options|
options[:installed] = false
end
@@ -84,7 +85,7 @@ module Gem::QueryUtils
installed = !installed unless options[:installed]
say(installed)
- exit_code = 1 unless installed
+ exit_code = 1 if !installed
end
exit_code
@@ -118,7 +119,7 @@ module Gem::QueryUtils
end
end
- # Guts of original execute
+ #Guts of original execute
def show_gems(name)
show_local_gems(name) if local?
show_remote_gems(name) if remote?
@@ -196,7 +197,7 @@ module Gem::QueryUtils
end
def output_versions(output, versions)
- versions.each do |_gem_name, matching_tuples|
+ versions.each do |gem_name, matching_tuples|
matching_tuples = matching_tuples.sort_by {|n,_| n.version }.reverse
platforms = Hash.new {|h,version| h[version] = [] }
@@ -242,7 +243,7 @@ module Gem::QueryUtils
list =
if platforms.empty? || options[:details]
- name_tuples.map(&:version).uniq
+ name_tuples.map {|n| n.version }.uniq
else
platforms.sort.reverse.map do |version, pls|
out = version.to_s
@@ -263,7 +264,7 @@ module Gem::QueryUtils
end
end
- entry << " (#{list.join ", "})"
+ entry << " (#{list.join ', '})"
end
def make_entry(entry_tuples, platforms)
@@ -282,7 +283,7 @@ module Gem::QueryUtils
end
def spec_authors(entry, spec)
- authors = "Author#{spec.authors.length > 1 ? "s" : ""}: ".dup
+ authors = "Author#{spec.authors.length > 1 ? 's' : ''}: ".dup
authors << spec.authors.join(", ")
entry << format_text(authors, 68, 4)
end
@@ -296,7 +297,7 @@ module Gem::QueryUtils
def spec_license(entry, spec)
return if spec.license.nil? || spec.license.empty?
- licenses = "License#{spec.licenses.length > 1 ? "s" : ""}: ".dup
+ licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: ".dup
licenses << spec.licenses.join(", ")
entry << "\n" << format_text(licenses, 68, 4)
end
@@ -311,8 +312,8 @@ module Gem::QueryUtils
label = "Installed at"
specs.each do |s|
version = s.version.to_s
- default = ", default" if s.default_gem?
- entry << "\n" << " #{label} (#{version}#{default}): #{s.base_dir}"
+ version << ", default" if s.default_gem?
+ entry << "\n" << " #{label} (#{version}): #{s.base_dir}"
label = " " * label.length
end
end
@@ -327,11 +328,11 @@ module Gem::QueryUtils
if platforms.length == 1
title = platforms.values.length == 1 ? "Platform" : "Platforms"
- entry << " #{title}: #{platforms.values.sort.join(", ")}\n"
+ entry << " #{title}: #{platforms.values.sort.join(', ')}\n"
else
entry << " Platforms:\n"
- sorted_platforms = platforms.sort
+ sorted_platforms = platforms.sort_by {|version,| version }
sorted_platforms.each do |version, pls|
label = " #{version}: "
@@ -346,4 +347,5 @@ module Gem::QueryUtils
summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
entry << "\n\n" << format_text(summary, 68, 4)
end
+
end
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb
index c3a41592f6..1c8a441d0c 100644
--- a/lib/rubygems/remote_fetcher.rb
+++ b/lib/rubygems/remote_fetcher.rb
@@ -53,7 +53,7 @@ class Gem::RemoteFetcher
# Cached RemoteFetcher instance.
def self.fetcher
- @fetcher ||= new Gem.configuration[:http_proxy]
+ @fetcher ||= self.new Gem.configuration[:http_proxy]
end
attr_accessor :headers
@@ -74,9 +74,9 @@ class Gem::RemoteFetcher
def initialize(proxy=nil, dns=nil, headers={})
require_relative "core_ext/tcpsocket_init" if Gem.configuration.ipv4_fallback_enabled
- require_relative "vendored_net_http"
+ require "net/http"
require "stringio"
- require_relative "vendor/uri/lib/uri"
+ require "uri"
Socket.do_not_reverse_lookup = true
@@ -115,7 +115,7 @@ class Gem::RemoteFetcher
cache_dir =
if Dir.pwd == install_dir # see fetch_command
install_dir
- elsif File.writable?(install_cache_dir) || (File.writable?(install_dir) && !File.exist?(install_cache_dir))
+ elsif File.writable?(install_cache_dir) || (File.writable?(install_dir) && (!File.exist?(install_cache_dir)))
install_cache_dir
else
File.join Gem.user_dir, "cache"
@@ -125,18 +125,14 @@ class Gem::RemoteFetcher
local_gem_path = File.join cache_dir, gem_file_name
require "fileutils"
- begin
- FileUtils.mkdir_p cache_dir
- rescue StandardError
- nil
- end unless File.exist? cache_dir
+ FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
source_uri = Gem::Uri.new(source_uri)
scheme = source_uri.scheme
- # Gem::URI.parse gets confused by MS Windows paths with forward slashes.
- scheme = nil if /^[a-z]$/i.match?(scheme)
+ # URI.parse gets confused by MS Windows paths with forward slashes.
+ scheme = nil if scheme =~ /^[a-z]$/i
# REFACTOR: split this up and dispatch on scheme (eg download_http)
# REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
@@ -148,7 +144,7 @@ class Gem::RemoteFetcher
remote_gem_path = source_uri + "gems/#{gem_file_name}"
- cache_update_path remote_gem_path, local_gem_path
+ self.cache_update_path remote_gem_path, local_gem_path
rescue FetchError
raise if spec.original_platform == spec.platform
@@ -158,7 +154,7 @@ class Gem::RemoteFetcher
remote_gem_path = source_uri + "gems/#{alternate_name}"
- cache_update_path remote_gem_path, local_gem_path
+ self.cache_update_path remote_gem_path, local_gem_path
end
end
when "file" then
@@ -174,7 +170,7 @@ class Gem::RemoteFetcher
end
verbose "Using local gem #{local_gem_path}"
- when nil then # TODO: test for local overriding cache
+ when nil then # TODO test for local overriding cache
source_path = if Gem.win_platform? && source_uri.scheme &&
!source_uri.path.include?(":")
"#{source_uri.scheme}:#{source_uri.path}"
@@ -210,17 +206,17 @@ class Gem::RemoteFetcher
# HTTP Fetcher. Dispatched by +fetch_path+. Use it instead.
def fetch_http(uri, last_modified = nil, head = false, depth = 0)
- fetch_type = head ? Gem::Net::HTTP::Head : Gem::Net::HTTP::Get
+ fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
response = request uri, fetch_type, last_modified do |req|
headers.each {|k,v| req.add_field(k,v) }
end
case response
- when Gem::Net::HTTPOK, Gem::Net::HTTPNotModified then
+ when Net::HTTPOK, Net::HTTPNotModified then
response.uri = uri
head ? response : response.body
- when Gem::Net::HTTPMovedPermanently, Gem::Net::HTTPFound, Gem::Net::HTTPSeeOther,
- Gem::Net::HTTPTemporaryRedirect then
+ when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
+ Net::HTTPTemporaryRedirect then
raise FetchError.new("too many redirects", uri) if depth > 10
unless location = response["Location"]
@@ -238,7 +234,7 @@ class Gem::RemoteFetcher
end
end
- alias_method :fetch_https, :fetch_http
+ alias :fetch_https :fetch_http
##
# Downloads +uri+ and returns it as a String.
@@ -261,7 +257,7 @@ class Gem::RemoteFetcher
end
data
- rescue Gem::Timeout::Error, IOError, SocketError, SystemCallError,
+ rescue Timeout::Error, IOError, SocketError, SystemCallError,
*(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e
raise FetchError.new("#{e.class}: #{e}", uri)
end
@@ -285,11 +281,7 @@ class Gem::RemoteFetcher
# passes the data.
def cache_update_path(uri, path = nil, update = true)
- mtime = begin
- path && File.stat(path).mtime
- rescue StandardError
- nil
- end
+ mtime = path && File.stat(path).mtime rescue nil
data = fetch_path(uri, mtime)
@@ -305,8 +297,8 @@ class Gem::RemoteFetcher
end
##
- # Performs a Gem::Net::HTTP request of type +request_class+ on +uri+ returning
- # a Gem::Net::HTTP response object. request maintains a table of persistent
+ # Performs a Net::HTTP request of type +request_class+ on +uri+ returning
+ # a Net::HTTP response object. request maintains a table of persistent
# connections to reduce connect overhead.
def request(uri, request_class, last_modified = nil)
@@ -321,11 +313,11 @@ class Gem::RemoteFetcher
end
def https?(uri)
- uri.scheme.casecmp("https").zero?
+ uri.scheme.downcase == "https"
end
def close_all
- @pools.each_value(&:close_all)
+ @pools.each_value {|pool| pool.close_all }
end
private
diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb
index 9116785231..8ea39d9358 100644
--- a/lib/rubygems/request.rb
+++ b/lib/rubygems/request.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "vendored_net_http"
+require "net/http"
require_relative "user_interaction"
class Gem::Request
@@ -18,11 +18,11 @@ class Gem::Request
end
def self.proxy_uri(proxy) # :nodoc:
- require_relative "vendor/uri/lib/uri"
+ require "uri"
case proxy
when :no_proxy then nil
- when Gem::URI::HTTP then proxy
- else Gem::URI.parse(proxy)
+ when URI::HTTP then proxy
+ else URI.parse(proxy)
end
end
@@ -30,19 +30,14 @@ class Gem::Request
@uri = uri
@request_class = request_class
@last_modified = last_modified
- @requests = Hash.new(0).compare_by_identity
+ @requests = Hash.new 0
@user_agent = user_agent
@connection_pool = pool
end
- def proxy_uri
- @connection_pool.proxy_uri
- end
-
- def cert_files
- @connection_pool.cert_files
- end
+ def proxy_uri; @connection_pool.proxy_uri; end
+ def cert_files; @connection_pool.cert_files; end
def self.get_cert_files
pattern = File.expand_path("./ssl_certs/*/*.pem", __dir__)
@@ -165,22 +160,23 @@ class Gem::Request
# environment variables.
def self.get_proxy_from_env(scheme = "http")
- downcase_scheme = scheme.downcase
- upcase_scheme = scheme.upcase
- env_proxy = ENV["#{downcase_scheme}_proxy"] || ENV["#{upcase_scheme}_PROXY"]
+ _scheme = scheme.downcase
+ _SCHEME = scheme.upcase
+ env_proxy = ENV["#{_scheme}_proxy"] || ENV["#{_SCHEME}_PROXY"]
no_env_proxy = env_proxy.nil? || env_proxy.empty?
if no_env_proxy
- return ["https", "http"].include?(downcase_scheme) ? :no_proxy : get_proxy_from_env("http")
+ return (_scheme == "https" || _scheme == "http") ?
+ :no_proxy : get_proxy_from_env("http")
end
require "uri"
- uri = Gem::URI(Gem::UriFormatter.new(env_proxy).normalize)
+ uri = URI(Gem::UriFormatter.new(env_proxy).normalize)
if uri && uri.user.nil? && uri.password.nil?
- user = ENV["#{downcase_scheme}_proxy_user"] || ENV["#{upcase_scheme}_PROXY_USER"]
- password = ENV["#{downcase_scheme}_proxy_pass"] || ENV["#{upcase_scheme}_PROXY_PASS"]
+ user = ENV["#{_scheme}_proxy_user"] || ENV["#{_SCHEME}_PROXY_USER"]
+ password = ENV["#{_scheme}_proxy_pass"] || ENV["#{_SCHEME}_PROXY_PASS"]
uri.user = Gem::UriFormatter.new(user).escape
uri.password = Gem::UriFormatter.new(password).escape
@@ -196,7 +192,7 @@ class Gem::Request
bad_response = false
begin
- @requests[connection] += 1
+ @requests[connection.object_id] += 1
verbose "#{request.method} #{Gem::Uri.redact(@uri)}"
@@ -205,7 +201,7 @@ class Gem::Request
if request.response_body_permitted? && file_name =~ /\.gem$/
reporter = ui.download_reporter
response = connection.request(request) do |incomplete_response|
- if Gem::Net::HTTPOK === incomplete_response
+ if Net::HTTPOK === incomplete_response
reporter.fetch(file_name, incomplete_response.content_length)
downloaded = 0
data = String.new
@@ -228,7 +224,8 @@ class Gem::Request
end
verbose "#{response.code} #{response.message}"
- rescue Gem::Net::HTTPBadResponse
+
+ rescue Net::HTTPBadResponse
verbose "bad response"
reset connection
@@ -237,17 +234,17 @@ class Gem::Request
bad_response = true
retry
- rescue Gem::Net::HTTPFatalError
+ rescue Net::HTTPFatalError
verbose "fatal error"
raise Gem::RemoteFetcher::FetchError.new("fatal error", @uri)
- # HACK: work around EOFError bug in Gem::Net::HTTP
+ # HACK work around EOFError bug in Net::HTTP
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
# to install gems.
- rescue EOFError, Gem::Timeout::Error,
+ rescue EOFError, Timeout::Error,
Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
- requests = @requests[connection]
+ requests = @requests[connection.object_id]
verbose "connection reset after #{requests} requests, retrying"
raise Gem::RemoteFetcher::FetchError.new("too many connection resets", @uri) if retried
@@ -267,7 +264,7 @@ class Gem::Request
# Resets HTTP connection +connection+.
def reset(connection)
- @requests.delete connection
+ @requests.delete connection.object_id
connection.finish
connection.start
@@ -282,7 +279,7 @@ class Gem::Request
ua << " Ruby/#{ruby_version} (#{RUBY_RELEASE_DATE}"
if RUBY_PATCHLEVEL >= 0
ua << " patchlevel #{RUBY_PATCHLEVEL}"
- else
+ elsif defined?(RUBY_REVISION)
ua << " revision #{RUBY_REVISION}"
end
ua << ")"
diff --git a/lib/rubygems/request/connection_pools.rb b/lib/rubygems/request/connection_pools.rb
index 6c1b04ab65..44280489fb 100644
--- a/lib/rubygems/request/connection_pools.rb
+++ b/lib/rubygems/request/connection_pools.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Gem::Request::ConnectionPools # :nodoc:
- @client = Gem::Net::HTTP
+ @client = Net::HTTP
class << self
attr_accessor :client
@@ -28,7 +28,7 @@ class Gem::Request::ConnectionPools # :nodoc:
end
def close_all
- @pools.each_value(&:close_all)
+ @pools.each_value {|pool| pool.close_all }
end
private
@@ -45,7 +45,7 @@ class Gem::Request::ConnectionPools # :nodoc:
end
def https?(uri)
- uri.scheme.casecmp("https").zero?
+ uri.scheme.downcase == "https"
end
def no_proxy?(host, env_no_proxy)
diff --git a/lib/rubygems/request_set.rb b/lib/rubygems/request_set.rb
index 875df7e019..b6e0995726 100644
--- a/lib/rubygems/request_set.rb
+++ b/lib/rubygems/request_set.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "vendored_tsort"
+require_relative "tsort"
##
# A RequestSet groups a request to activate a set of dependencies.
@@ -160,7 +160,7 @@ class Gem::RequestSet
end
# Create N threads in a pool, have them download all the gems
- threads = Array.new(Gem.configuration.concurrent_downloads) do
+ threads = Gem.configuration.concurrent_downloads.times.map do
# When a thread pops this item, it knows to stop running. The symbol
# is queued here so that there will be one symbol per thread.
download_queue << :stop
@@ -255,8 +255,7 @@ class Gem::RequestSet
end
def install_into(dir, force = true, options = {})
- gem_home = ENV["GEM_HOME"]
- ENV["GEM_HOME"] = dir
+ gem_home, ENV["GEM_HOME"] = ENV["GEM_HOME"], dir
existing = force ? [] : specs_in(dir)
existing.delete_if {|s| @always_install.include? s }
@@ -324,7 +323,7 @@ class Gem::RequestSet
@git_set.root_dir = @install_dir
- lock_file = "#{File.expand_path(path)}.lock"
+ lock_file = "#{File.expand_path(path)}.lock".dup.tap(&Gem::UNTAINT)
begin
tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file lock_file
parser = tokenizer.make_parser self, []
@@ -376,7 +375,7 @@ class Gem::RequestSet
q.text "sets:"
q.breakable
- q.pp @sets.map(&:class)
+ q.pp @sets.map {|set| set.class }
end
end
@@ -430,7 +429,7 @@ class Gem::RequestSet
end
def specs
- @specs ||= @requests.map(&:full_spec)
+ @specs ||= @requests.map {|r| r.full_spec }
end
def specs_in(dir)
@@ -448,7 +447,7 @@ class Gem::RequestSet
next if dep.type == :development && !@development
match = @requests.find do |r|
- dep.match?(r.spec.name, r.spec.version, r.spec.is_a?(Gem::Resolver::InstalledSpecification) || @prerelease)
+ dep.match? r.spec.name, r.spec.version, r.spec.is_a?(Gem::Resolver::InstalledSpecification) || @prerelease
end
unless match
diff --git a/lib/rubygems/request_set/gem_dependency_api.rb b/lib/rubygems/request_set/gem_dependency_api.rb
index 4347d22ccb..2fd0da340a 100644
--- a/lib/rubygems/request_set/gem_dependency_api.rb
+++ b/lib/rubygems/request_set/gem_dependency_api.rb
@@ -33,22 +33,22 @@
class Gem::RequestSet::GemDependencyAPI
ENGINE_MAP = { # :nodoc:
- jruby: %w[jruby],
- jruby_18: %w[jruby],
- jruby_19: %w[jruby],
- maglev: %w[maglev],
- mri: %w[ruby],
- mri_18: %w[ruby],
- mri_19: %w[ruby],
- mri_20: %w[ruby],
- mri_21: %w[ruby],
- rbx: %w[rbx],
- truffleruby: %w[truffleruby],
- ruby: %w[ruby rbx maglev truffleruby],
- ruby_18: %w[ruby rbx maglev truffleruby],
- ruby_19: %w[ruby rbx maglev truffleruby],
- ruby_20: %w[ruby rbx maglev truffleruby],
- ruby_21: %w[ruby rbx maglev truffleruby],
+ :jruby => %w[jruby],
+ :jruby_18 => %w[jruby],
+ :jruby_19 => %w[jruby],
+ :maglev => %w[maglev],
+ :mri => %w[ruby],
+ :mri_18 => %w[ruby],
+ :mri_19 => %w[ruby],
+ :mri_20 => %w[ruby],
+ :mri_21 => %w[ruby],
+ :rbx => %w[rbx],
+ :truffleruby => %w[truffleruby],
+ :ruby => %w[ruby rbx maglev truffleruby],
+ :ruby_18 => %w[ruby rbx maglev truffleruby],
+ :ruby_19 => %w[ruby rbx maglev truffleruby],
+ :ruby_20 => %w[ruby rbx maglev truffleruby],
+ :ruby_21 => %w[ruby rbx maglev truffleruby],
}.freeze
mswin = Gem::Platform.new "x86-mswin32"
@@ -57,39 +57,39 @@ class Gem::RequestSet::GemDependencyAPI
x64_mingw = Gem::Platform.new "x64-mingw32"
PLATFORM_MAP = { # :nodoc:
- jruby: Gem::Platform::RUBY,
- jruby_18: Gem::Platform::RUBY,
- jruby_19: Gem::Platform::RUBY,
- maglev: Gem::Platform::RUBY,
- mingw: x86_mingw,
- mingw_18: x86_mingw,
- mingw_19: x86_mingw,
- mingw_20: x86_mingw,
- mingw_21: x86_mingw,
- mri: Gem::Platform::RUBY,
- mri_18: Gem::Platform::RUBY,
- mri_19: Gem::Platform::RUBY,
- mri_20: Gem::Platform::RUBY,
- mri_21: Gem::Platform::RUBY,
- mswin: mswin,
- mswin_18: mswin,
- mswin_19: mswin,
- mswin_20: mswin,
- mswin_21: mswin,
- mswin64: mswin64,
- mswin64_19: mswin64,
- mswin64_20: mswin64,
- mswin64_21: mswin64,
- rbx: Gem::Platform::RUBY,
- ruby: Gem::Platform::RUBY,
- ruby_18: Gem::Platform::RUBY,
- ruby_19: Gem::Platform::RUBY,
- ruby_20: Gem::Platform::RUBY,
- ruby_21: Gem::Platform::RUBY,
- truffleruby: Gem::Platform::RUBY,
- x64_mingw: x64_mingw,
- x64_mingw_20: x64_mingw,
- x64_mingw_21: x64_mingw,
+ :jruby => Gem::Platform::RUBY,
+ :jruby_18 => Gem::Platform::RUBY,
+ :jruby_19 => Gem::Platform::RUBY,
+ :maglev => Gem::Platform::RUBY,
+ :mingw => x86_mingw,
+ :mingw_18 => x86_mingw,
+ :mingw_19 => x86_mingw,
+ :mingw_20 => x86_mingw,
+ :mingw_21 => x86_mingw,
+ :mri => Gem::Platform::RUBY,
+ :mri_18 => Gem::Platform::RUBY,
+ :mri_19 => Gem::Platform::RUBY,
+ :mri_20 => Gem::Platform::RUBY,
+ :mri_21 => Gem::Platform::RUBY,
+ :mswin => mswin,
+ :mswin_18 => mswin,
+ :mswin_19 => mswin,
+ :mswin_20 => mswin,
+ :mswin_21 => mswin,
+ :mswin64 => mswin64,
+ :mswin64_19 => mswin64,
+ :mswin64_20 => mswin64,
+ :mswin64_21 => mswin64,
+ :rbx => Gem::Platform::RUBY,
+ :ruby => Gem::Platform::RUBY,
+ :ruby_18 => Gem::Platform::RUBY,
+ :ruby_19 => Gem::Platform::RUBY,
+ :ruby_20 => Gem::Platform::RUBY,
+ :ruby_21 => Gem::Platform::RUBY,
+ :truffleruby => Gem::Platform::RUBY,
+ :x64_mingw => x64_mingw,
+ :x64_mingw_20 => x64_mingw,
+ :x64_mingw_21 => x64_mingw,
}.freeze
gt_eq_0 = Gem::Requirement.new ">= 0"
@@ -99,70 +99,70 @@ class Gem::RequestSet::GemDependencyAPI
tilde_gt_2_1_0 = Gem::Requirement.new "~> 2.1.0"
VERSION_MAP = { # :nodoc:
- jruby: gt_eq_0,
- jruby_18: tilde_gt_1_8_0,
- jruby_19: tilde_gt_1_9_0,
- maglev: gt_eq_0,
- mingw: gt_eq_0,
- mingw_18: tilde_gt_1_8_0,
- mingw_19: tilde_gt_1_9_0,
- mingw_20: tilde_gt_2_0_0,
- mingw_21: tilde_gt_2_1_0,
- mri: gt_eq_0,
- mri_18: tilde_gt_1_8_0,
- mri_19: tilde_gt_1_9_0,
- mri_20: tilde_gt_2_0_0,
- mri_21: tilde_gt_2_1_0,
- mswin: gt_eq_0,
- mswin_18: tilde_gt_1_8_0,
- mswin_19: tilde_gt_1_9_0,
- mswin_20: tilde_gt_2_0_0,
- mswin_21: tilde_gt_2_1_0,
- mswin64: gt_eq_0,
- mswin64_19: tilde_gt_1_9_0,
- mswin64_20: tilde_gt_2_0_0,
- mswin64_21: tilde_gt_2_1_0,
- rbx: gt_eq_0,
- ruby: gt_eq_0,
- ruby_18: tilde_gt_1_8_0,
- ruby_19: tilde_gt_1_9_0,
- ruby_20: tilde_gt_2_0_0,
- ruby_21: tilde_gt_2_1_0,
- truffleruby: gt_eq_0,
- x64_mingw: gt_eq_0,
- x64_mingw_20: tilde_gt_2_0_0,
- x64_mingw_21: tilde_gt_2_1_0,
+ :jruby => gt_eq_0,
+ :jruby_18 => tilde_gt_1_8_0,
+ :jruby_19 => tilde_gt_1_9_0,
+ :maglev => gt_eq_0,
+ :mingw => gt_eq_0,
+ :mingw_18 => tilde_gt_1_8_0,
+ :mingw_19 => tilde_gt_1_9_0,
+ :mingw_20 => tilde_gt_2_0_0,
+ :mingw_21 => tilde_gt_2_1_0,
+ :mri => gt_eq_0,
+ :mri_18 => tilde_gt_1_8_0,
+ :mri_19 => tilde_gt_1_9_0,
+ :mri_20 => tilde_gt_2_0_0,
+ :mri_21 => tilde_gt_2_1_0,
+ :mswin => gt_eq_0,
+ :mswin_18 => tilde_gt_1_8_0,
+ :mswin_19 => tilde_gt_1_9_0,
+ :mswin_20 => tilde_gt_2_0_0,
+ :mswin_21 => tilde_gt_2_1_0,
+ :mswin64 => gt_eq_0,
+ :mswin64_19 => tilde_gt_1_9_0,
+ :mswin64_20 => tilde_gt_2_0_0,
+ :mswin64_21 => tilde_gt_2_1_0,
+ :rbx => gt_eq_0,
+ :ruby => gt_eq_0,
+ :ruby_18 => tilde_gt_1_8_0,
+ :ruby_19 => tilde_gt_1_9_0,
+ :ruby_20 => tilde_gt_2_0_0,
+ :ruby_21 => tilde_gt_2_1_0,
+ :truffleruby => gt_eq_0,
+ :x64_mingw => gt_eq_0,
+ :x64_mingw_20 => tilde_gt_2_0_0,
+ :x64_mingw_21 => tilde_gt_2_1_0,
}.freeze
WINDOWS = { # :nodoc:
- mingw: :only,
- mingw_18: :only,
- mingw_19: :only,
- mingw_20: :only,
- mingw_21: :only,
- mri: :never,
- mri_18: :never,
- mri_19: :never,
- mri_20: :never,
- mri_21: :never,
- mswin: :only,
- mswin_18: :only,
- mswin_19: :only,
- mswin_20: :only,
- mswin_21: :only,
- mswin64: :only,
- mswin64_19: :only,
- mswin64_20: :only,
- mswin64_21: :only,
- rbx: :never,
- ruby: :never,
- ruby_18: :never,
- ruby_19: :never,
- ruby_20: :never,
- ruby_21: :never,
- x64_mingw: :only,
- x64_mingw_20: :only,
- x64_mingw_21: :only,
+ :mingw => :only,
+ :mingw_18 => :only,
+ :mingw_19 => :only,
+ :mingw_20 => :only,
+ :mingw_21 => :only,
+ :mri => :never,
+ :mri_18 => :never,
+ :mri_19 => :never,
+ :mri_20 => :never,
+ :mri_21 => :never,
+ :mswin => :only,
+ :mswin_18 => :only,
+ :mswin_19 => :only,
+ :mswin_20 => :only,
+ :mswin_21 => :only,
+ :mswin64 => :only,
+ :mswin64_19 => :only,
+ :mswin64_20 => :only,
+ :mswin64_21 => :only,
+ :rbx => :never,
+ :ruby => :never,
+ :ruby_18 => :never,
+ :ruby_19 => :never,
+ :ruby_20 => :never,
+ :ruby_21 => :never,
+ :x64_mingw => :only,
+ :x64_mingw_20 => :only,
+ :x64_mingw_21 => :only,
}.freeze
##
@@ -262,7 +262,7 @@ class Gem::RequestSet::GemDependencyAPI
raise ArgumentError, "no gemspecs found at #{Dir.pwd}"
else
raise ArgumentError,
- "found multiple gemspecs at #{Dir.pwd}, " \
+ "found multiple gemspecs at #{Dir.pwd}, " +
"use the name: option to specify the one you want"
end
end
@@ -280,7 +280,7 @@ class Gem::RequestSet::GemDependencyAPI
# Loads the gem dependency file and returns self.
def load
- instance_eval File.read(@path), @path, 1
+ instance_eval File.read(@path).tap(&Gem::UNTAINT), @path, 1
self
end
@@ -357,7 +357,7 @@ class Gem::RequestSet::GemDependencyAPI
# Use the given tag for git:, gist: and github: dependencies.
def gem(name, *requirements)
- options = requirements.pop if requirements.last.is_a?(Hash)
+ options = requirements.pop if requirements.last.kind_of?(Hash)
options ||= {}
options[:git] = @current_repository if @current_repository
@@ -533,8 +533,8 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# platform matches the current platform.
def gem_platforms(name, options) # :nodoc:
- platform_names = Array(options.delete(:platform))
- platform_names.concat Array(options.delete(:platforms))
+ platform_names = Array(options.delete :platform)
+ platform_names.concat Array(options.delete :platforms)
platform_names.concat @current_platforms if @current_platforms
return true if platform_names.empty?
@@ -593,6 +593,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
@current_repository = repository
yield
+
ensure
@current_repository = nil
end
@@ -684,6 +685,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
@current_groups = groups
yield
+
ensure
@current_groups = nil
end
@@ -758,6 +760,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
@current_platforms = platforms
yield
+
ensure
@current_platforms = nil
end
@@ -768,7 +771,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# Block form for restricting gems to a particular set of platforms. See
# #platform.
- alias_method :platforms, :platform
+ alias :platforms :platform
##
# :category: Gem Dependencies DSL
@@ -790,15 +793,15 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
return true if @installing
- unless version == RUBY_VERSION
- message = "Your Ruby version is #{RUBY_VERSION}, " \
+ unless RUBY_VERSION == version
+ message = "Your Ruby version is #{RUBY_VERSION}, " +
"but your #{gem_deps_file} requires #{version}"
raise Gem::RubyVersionMismatch, message
end
if engine && engine != Gem.ruby_engine
- message = "Your Ruby engine is #{Gem.ruby_engine}, " \
+ message = "Your Ruby engine is #{Gem.ruby_engine}, " +
"but your #{gem_deps_file} requires #{engine}"
raise Gem::RubyVersionMismatch, message
@@ -807,14 +810,14 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
if engine_version
if engine_version != RUBY_ENGINE_VERSION
message =
- "Your Ruby engine version is #{Gem.ruby_engine} #{RUBY_ENGINE_VERSION}, " \
+ "Your Ruby engine version is #{Gem.ruby_engine} #{RUBY_ENGINE_VERSION}, " +
"but your #{gem_deps_file} requires #{engine} #{engine_version}"
raise Gem::RubyVersionMismatch, message
end
end
- true
+ return true
end
##
diff --git a/lib/rubygems/request_set/lockfile.rb b/lib/rubygems/request_set/lockfile.rb
index c446b3ae51..9523fa7786 100644
--- a/lib/rubygems/request_set/lockfile.rb
+++ b/lib/rubygems/request_set/lockfile.rb
@@ -76,13 +76,18 @@ class Gem::RequestSet::Lockfile
@dependencies = dependencies
@gem_deps_file = File.expand_path(gem_deps_file)
@gem_deps_dir = File.dirname(@gem_deps_file)
+
+ if RUBY_VERSION < "2.7"
+ @gem_deps_file.untaint unless gem_deps_file.tainted?
+ end
+
@platforms = []
end
def add_DEPENDENCIES(out) # :nodoc:
out << "DEPENDENCIES"
- out.concat @dependencies.sort.map {|name, requirement|
+ out.concat @dependencies.sort_by {|name,| name }.map {|name, requirement|
" #{name}#{requirement.for_lockfile}"
}
@@ -101,10 +106,10 @@ class Gem::RequestSet::Lockfile
out << " remote: #{group}"
out << " specs:"
- requests.sort_by(&:name).each do |request|
+ requests.sort_by {|request| request.name }.each do |request|
next if request.spec.name == "bundler"
platform = "-#{request.spec.platform}" unless
- request.spec.platform == Gem::Platform::RUBY
+ Gem::Platform::RUBY == request.spec.platform
out << " #{request.name} (#{request.version}#{platform})"
@@ -133,10 +138,10 @@ class Gem::RequestSet::Lockfile
out << " revision: #{revision}"
out << " specs:"
- requests.sort_by(&:name).each do |request|
+ requests.sort_by {|request| request.name }.each do |request|
out << " #{request.name} (#{request.version})"
- dependencies = request.spec.dependencies.sort_by(&:name)
+ dependencies = request.spec.dependencies.sort_by {|dep| dep.name }
dependencies.each do |dep|
out << " #{dep.name}#{dep.requirement.for_lockfile}"
end
@@ -180,7 +185,7 @@ class Gem::RequestSet::Lockfile
platforms = requests.map {|request| request.spec.platform }.uniq
- platforms = platforms.sort_by(&:to_s)
+ platforms = platforms.sort_by {|platform| platform.to_s }
platforms.each do |platform|
out << " #{platform}"
diff --git a/lib/rubygems/request_set/lockfile/parser.rb b/lib/rubygems/request_set/lockfile/parser.rb
index e751a1445e..1daec1fabd 100644
--- a/lib/rubygems/request_set/lockfile/parser.rb
+++ b/lib/rubygems/request_set/lockfile/parser.rb
@@ -48,7 +48,7 @@ class Gem::RequestSet::Lockfile::Parser
if expected_types && !Array(expected_types).include?(token.type)
unget token
- message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " \
+ message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " +
"expected #{expected_types.inspect}"
raise Gem::RequestSet::Lockfile::ParseError.new message, token.column, token.line, @filename
@@ -57,8 +57,8 @@ class Gem::RequestSet::Lockfile::Parser
if expected_value && expected_value != token.value
unget token
- message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " \
- "expected [#{expected_types.inspect}, " \
+ message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " +
+ "expected [#{expected_types.inspect}, " +
"#{expected_value.inspect}]"
raise Gem::RequestSet::Lockfile::ParseError.new message, token.column, token.line, @filename
@@ -68,7 +68,7 @@ class Gem::RequestSet::Lockfile::Parser
end
def parse_DEPENDENCIES # :nodoc:
- while !@tokens.empty? && peek.type == :text do
+ while !@tokens.empty? && :text == peek.type do
token = get :text
requirements = []
@@ -111,7 +111,7 @@ class Gem::RequestSet::Lockfile::Parser
def parse_GEM # :nodoc:
sources = []
- while peek.first(2) == [:entry, "remote"] do
+ while [:entry, "remote"] == peek.first(2) do
get :entry, "remote"
data = get(:text).value
skip :newline
@@ -128,7 +128,7 @@ class Gem::RequestSet::Lockfile::Parser
set = Gem::Resolver::LockSet.new sources
last_specs = nil
- while !@tokens.empty? && peek.type == :text do
+ while !@tokens.empty? && :text == peek.type do
token = get :text
name = token.value
column = token.column
@@ -200,7 +200,7 @@ class Gem::RequestSet::Lockfile::Parser
last_spec = nil
- while !@tokens.empty? && peek.type == :text do
+ while !@tokens.empty? && :text == peek.type do
token = get :text
name = token.value
column = token.column
@@ -247,7 +247,7 @@ class Gem::RequestSet::Lockfile::Parser
set = Gem::Resolver::VendorSet.new
last_spec = nil
- while !@tokens.empty? && peek.first == :text do
+ while !@tokens.empty? && :text == peek.first do
token = get :text
name = token.value
column = token.column
@@ -282,7 +282,7 @@ class Gem::RequestSet::Lockfile::Parser
end
def parse_PLATFORMS # :nodoc:
- while !@tokens.empty? && peek.first == :text do
+ while !@tokens.empty? && :text == peek.first do
name = get(:text).value
@platforms << name
diff --git a/lib/rubygems/request_set/lockfile/tokenizer.rb b/lib/rubygems/request_set/lockfile/tokenizer.rb
index 65cef3baa0..e91a11ca93 100644
--- a/lib/rubygems/request_set/lockfile/tokenizer.rb
+++ b/lib/rubygems/request_set/lockfile/tokenizer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-# ) frozen_string_literal: true
+#) frozen_string_literal: true
require_relative "parser"
class Gem::RequestSet::Lockfile::Tokenizer
@@ -50,7 +50,7 @@ class Gem::RequestSet::Lockfile::Tokenizer
def next_token
@tokens.shift
end
- alias_method :shift, :next_token
+ alias :shift :next_token
def peek
@tokens.first || EOF
@@ -75,14 +75,13 @@ class Gem::RequestSet::Lockfile::Tokenizer
end
@tokens <<
- if s.scan(/\r?\n/)
-
+ case
+ when s.scan(/\r?\n/) then
token = Token.new(:newline, nil, *token_pos(pos))
@line_pos = s.pos
@line += 1
token
- elsif s.scan(/[A-Z]+/)
-
+ when s.scan(/[A-Z]+/) then
if leading_whitespace
text = s.matched
text += s.scan(/[^\s)]*/).to_s # in case of no match
@@ -90,27 +89,20 @@ class Gem::RequestSet::Lockfile::Tokenizer
else
Token.new(:section, s.matched, *token_pos(pos))
end
- elsif s.scan(/([a-z]+):\s/)
-
+ when s.scan(/([a-z]+):\s/) then
s.pos -= 1 # rewind for possible newline
Token.new(:entry, s[1], *token_pos(pos))
- elsif s.scan(/\(/)
-
+ when s.scan(/\(/) then
Token.new(:l_paren, nil, *token_pos(pos))
- elsif s.scan(/\)/)
-
+ when s.scan(/\)/) then
Token.new(:r_paren, nil, *token_pos(pos))
- elsif s.scan(/<=|>=|=|~>|<|>|!=/)
-
+ when s.scan(/<=|>=|=|~>|<|>|!=/) then
Token.new(:requirement, s.matched, *token_pos(pos))
- elsif s.scan(/,/)
-
+ when s.scan(/,/) then
Token.new(:comma, nil, *token_pos(pos))
- elsif s.scan(/!/)
-
+ when s.scan(/!/) then
Token.new(:bang, nil, *token_pos(pos))
- elsif s.scan(/[^\s),!]*/)
-
+ when s.scan(/[^\s),!]*/) then
Token.new(:text, s.matched, *token_pos(pos))
else
raise "BUG: can't create token for: #{s.string[s.pos..-1].inspect}"
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
index 02543cb14a..eed12c4914 100644
--- a/lib/rubygems/requirement.rb
+++ b/lib/rubygems/requirement.rb
@@ -10,7 +10,7 @@ require_relative "version"
# together in RubyGems.
class Gem::Requirement
- OPS = { # :nodoc:
+ OPS = { #:nodoc:
"=" => lambda {|v, r| v == r },
"!=" => lambda {|v, r| v != r },
">" => lambda {|v, r| v > r },
@@ -23,12 +23,12 @@ class Gem::Requirement
SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
quoted = OPS.keys.map {|k| Regexp.quote k }.join "|"
- PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*".freeze # :nodoc:
+ PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*" # :nodoc:
##
# A regular expression that matches a requirement
- PATTERN = /\A#{PATTERN_RAW}\z/
+ PATTERN = /\A#{PATTERN_RAW}\z/.freeze
##
# The default requirement matches any non-prerelease version
@@ -120,7 +120,7 @@ class Gem::Requirement
# An array of requirement pairs. The first element of the pair is
# the op, and the second is the Gem::Version.
- attr_reader :requirements # :nodoc:
+ attr_reader :requirements #:nodoc:
##
# Constructs a requirement from +requirements+. Requirements can be
@@ -156,7 +156,7 @@ class Gem::Requirement
# Formats this requirement for use in a Gem::RequestSet::Lockfile.
def for_lockfile # :nodoc:
- return if @requirements == [DefaultRequirement]
+ return if [DefaultRequirement] == @requirements
list = requirements.sort_by do |_, version|
version
@@ -164,7 +164,7 @@ class Gem::Requirement
"#{op} #{version}"
end.uniq
- " (#{list.join ", "})"
+ " (#{list.join ', '})"
end
##
@@ -245,8 +245,8 @@ class Gem::Requirement
requirements.all? {|op, rv| OPS[op].call version, rv }
end
- alias_method :===, :satisfied_by?
- alias_method :=~, :satisfied_by?
+ alias :=== :satisfied_by?
+ alias :=~ :satisfied_by?
##
# True if the requirement will not always match the latest version.
@@ -284,11 +284,6 @@ class Gem::Requirement
def _tilde_requirements
@_tilde_requirements ||= _sorted_requirements.select {|r| r.first == "~>" }
end
-
- def initialize_copy(other) # :nodoc:
- @requirements = other.requirements.dup
- super
- end
end
class Gem::Version
diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb
index 115c716b6b..a912729b37 100644
--- a/lib/rubygems/resolver.rb
+++ b/lib/rubygems/resolver.rb
@@ -11,7 +11,7 @@ require_relative "util/list"
# all the requirements.
class Gem::Resolver
- require_relative "vendored_molinillo"
+ require_relative "resolver/molinillo"
##
# If the DEBUG_RESOLVER environment variable is set then debugging mode is
@@ -38,6 +38,8 @@ class Gem::Resolver
##
# List of dependencies that could not be found in the configured sources.
+ attr_reader :missing
+
attr_reader :stats
##
@@ -47,7 +49,8 @@ class Gem::Resolver
attr_accessor :skip_gems
##
- #
+ # When a missing dependency, don't stop. Just go on and record what was
+ # missing.
attr_accessor :soft_missing
@@ -103,6 +106,7 @@ class Gem::Resolver
@development = false
@development_shallow = false
@ignore_dependencies = false
+ @missing = []
@skip_gems = {}
@soft_missing = false
@stats = Gem::Resolver::Stats.new
@@ -111,7 +115,7 @@ class Gem::Resolver
def explain(stage, *data) # :nodoc:
return unless DEBUG_RESOLVER
- d = data.map(&:pretty_inspect).join(", ")
+ d = data.map {|x| x.pretty_inspect }.join(", ")
$stderr.printf "%10s %s\n", stage.to_s.upcase, d
end
@@ -141,7 +145,7 @@ class Gem::Resolver
activation_request =
Gem::Resolver::ActivationRequest.new spec, dep, possible
- [spec, activation_request]
+ return spec, activation_request
end
def requests(s, act, reqs=[]) # :nodoc:
@@ -167,7 +171,7 @@ class Gem::Resolver
reqs
end
- include Gem::Molinillo::UI
+ include Molinillo::UI
def output
@output ||= debug? ? $stdout : File.open(IO::NULL, "w")
@@ -177,14 +181,15 @@ class Gem::Resolver
DEBUG_RESOLVER
end
- include Gem::Molinillo::SpecificationProvider
+ include Molinillo::SpecificationProvider
##
# Proceed with resolution! Returns an array of ActivationRequest objects.
def resolve
- Gem::Molinillo::Resolver.new(self, self).resolve(@needed.map {|d| DependencyRequest.new d, nil }).tsort.map(&:payload).compact
- rescue Gem::Molinillo::VersionConflict => e
+ locking_dg = Molinillo::DependencyGraph.new
+ Molinillo::Resolver.new(self, self).resolve(@needed.map {|d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload).compact
+ rescue Molinillo::VersionConflict => e
conflict = e.conflicts.values.first
raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement)
ensure
@@ -208,7 +213,7 @@ class Gem::Resolver
matching_platform = select_local_platforms all
- [matching_platform, all]
+ return matching_platform, all
end
##
@@ -223,6 +228,7 @@ class Gem::Resolver
def search_for(dependency)
possibles, all = find_possible(dependency)
if !@soft_missing && possibles.empty?
+ @missing << dependency
exc = Gem::UnsatisfiableDependencyError.new dependency, all
exc.errors = @set.errors
raise exc
@@ -241,7 +247,7 @@ class Gem::Resolver
sources.each do |source|
groups[source].
- sort_by {|spec| [spec.version, spec.platform =~ Gem::Platform.local ? 1 : 0] }. # rubocop:disable Performance/RegexpMatch
+ sort_by {|spec| [spec.version, spec.platform =~ Gem::Platform.local ? 1 : 0] }.
map {|spec| ActivationRequest.new spec, dependency }.
each {|activation_request| activation_requests << activation_request }
end
@@ -269,6 +275,7 @@ class Gem::Resolver
end
def allow_missing?(dependency)
+ @missing << dependency
@soft_missing
end
diff --git a/lib/rubygems/resolver/activation_request.rb b/lib/rubygems/resolver/activation_request.rb
index fc9ff58f57..d59859c102 100644
--- a/lib/rubygems/resolver/activation_request.rb
+++ b/lib/rubygems/resolver/activation_request.rb
@@ -59,8 +59,10 @@ class Gem::Resolver::ActivationRequest
if @spec.respond_to? :sources
exception = nil
path = @spec.sources.find do |source|
- source.download full_spec, path
- rescue exception
+ begin
+ source.download full_spec, path
+ rescue exception
+ end
end
return path if path
raise exception if exception
@@ -92,7 +94,9 @@ class Gem::Resolver::ActivationRequest
end
def inspect # :nodoc:
- format("#<%s for %p from %s>", self.class, @spec, @request)
+ "#<%s for %p from %s>" % [
+ self.class, @spec, @request
+ ]
end
##
diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb
index 3e4dadc40f..9b57b03192 100644
--- a/lib/rubygems/resolver/api_set.rb
+++ b/lib/rubygems/resolver/api_set.rb
@@ -30,7 +30,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
def initialize(dep_uri = "https://index.rubygems.org/info/")
super()
- dep_uri = Gem::URI dep_uri unless Gem::URI === dep_uri
+ dep_uri = URI dep_uri unless URI === dep_uri
@dep_uri = dep_uri
@uri = dep_uri + ".."
@@ -76,8 +76,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
end
def prefetch_now # :nodoc:
- needed = @to_fetch
- @to_fetch = []
+ needed, @to_fetch = @to_fetch, []
needed.sort.each do |name|
versions(name)
diff --git a/lib/rubygems/resolver/api_set/gem_parser.rb b/lib/rubygems/resolver/api_set/gem_parser.rb
index 643b857107..685c39558d 100644
--- a/lib/rubygems/resolver/api_set/gem_parser.rb
+++ b/lib/rubygems/resolver/api_set/gem_parser.rb
@@ -1,15 +1,12 @@
# frozen_string_literal: true
class Gem::Resolver::APISet::GemParser
- EMPTY_ARRAY = [].freeze
- private_constant :EMPTY_ARRAY
-
def parse(line)
version_and_platform, rest = line.split(" ", 2)
version, platform = version_and_platform.split("-", 2)
- dependencies, requirements = rest.split("|", 2).map! {|s| s.split(",") } if rest
- dependencies = dependencies ? dependencies.map! {|d| parse_dependency(d) } : EMPTY_ARRAY
- requirements = requirements ? requirements.map! {|d| parse_dependency(d) } : EMPTY_ARRAY
+ dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
+ dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
+ requirements = requirements ? requirements.map {|d| parse_dependency(d) } : []
[version, platform, dependencies, requirements]
end
@@ -18,7 +15,6 @@ class Gem::Resolver::APISet::GemParser
def parse_dependency(string)
dependency = string.split(":")
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
- dependency[0] = -dependency[0]
dependency
end
end
diff --git a/lib/rubygems/resolver/api_specification.rb b/lib/rubygems/resolver/api_specification.rb
index a14bcbfeb1..f26f82757e 100644
--- a/lib/rubygems/resolver/api_specification.rb
+++ b/lib/rubygems/resolver/api_specification.rb
@@ -22,7 +22,7 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
# Creates an APISpecification for the given +set+ from the rubygems.org
# +api_data+.
#
- # See https://guides.rubygems.org/rubygems-org-api/#misc-methods for the
+ # See https://guides.rubygems.org/rubygems-org-api/#misc_methods for the
# format of the +api_data+.
def initialize(set, api_data)
diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb
index a983f8c6b6..d75fa7c00a 100644
--- a/lib/rubygems/resolver/best_set.rb
+++ b/lib/rubygems/resolver/best_set.rb
@@ -60,8 +60,8 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
def replace_failed_api_set(error) # :nodoc:
uri = error.original_uri
- uri = Gem::URI uri unless Gem::URI === uri
- uri += "."
+ uri = URI uri unless URI === uri
+ uri = uri + "."
raise error unless api_set = @sets.find do |set|
Gem::Resolver::APISet === set && set.dep_uri == uri
diff --git a/lib/rubygems/resolver/composed_set.rb b/lib/rubygems/resolver/composed_set.rb
index 8a714ad447..0991f0713e 100644
--- a/lib/rubygems/resolver/composed_set.rb
+++ b/lib/rubygems/resolver/composed_set.rb
@@ -44,7 +44,7 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
end
def errors
- @errors + @sets.map(&:errors).flatten
+ @errors + @sets.map {|set| set.errors }.flatten
end
##
diff --git a/lib/rubygems/resolver/conflict.rb b/lib/rubygems/resolver/conflict.rb
index 367a36b43d..dca41da51f 100644
--- a/lib/rubygems/resolver/conflict.rb
+++ b/lib/rubygems/resolver/conflict.rb
@@ -55,7 +55,7 @@ class Gem::Resolver::Conflict
activated = @activated.spec.full_name
dependency = @failed_dep.dependency
requirement = dependency.requirement
- alternates = dependency.matching_specs.map(&:full_name)
+ alternates = dependency.matching_specs.map {|spec| spec.full_name }
unless alternates.empty?
matching = <<-MATCHING.chomp
@@ -64,7 +64,10 @@ class Gem::Resolver::Conflict
%s
MATCHING
- matching = format(matching, dependency, alternates.join(", "))
+ matching = matching % [
+ dependency,
+ alternates.join(", "),
+ ]
end
explanation = <<-EXPLANATION
@@ -79,7 +82,12 @@ class Gem::Resolver::Conflict
%s
EXPLANATION
- format(explanation, activated, requirement, request_path(@activated).reverse.join(", depends on\n "), request_path(@failed_dep).reverse.join(", depends on\n "), matching)
+ explanation % [
+ activated, requirement,
+ request_path(@activated).reverse.join(", depends on\n "),
+ request_path(@failed_dep).reverse.join(", depends on\n "),
+ matching
+ ]
end
##
@@ -124,7 +132,7 @@ class Gem::Resolver::Conflict
current = current.parent
when Gem::Resolver::DependencyRequest then
- path << current.dependency.to_s
+ path << "#{current.dependency}"
current = current.requester
else
diff --git a/lib/rubygems/resolver/index_set.rb b/lib/rubygems/resolver/index_set.rb
index 0b4f376452..5e8632c7d8 100644
--- a/lib/rubygems/resolver/index_set.rb
+++ b/lib/rubygems/resolver/index_set.rb
@@ -44,10 +44,10 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
name = req.dependency.name
@all[name].each do |uri, n|
- next unless req.match? n, @prerelease
- res << Gem::Resolver::IndexSpecification.new(
- self, n.name, n.version, uri, n.platform
- )
+ if req.match? n, @prerelease
+ res << Gem::Resolver::IndexSpecification.new(
+ self, n.name, n.version, uri, n.platform)
+ end
end
res
diff --git a/lib/rubygems/resolver/index_specification.rb b/lib/rubygems/resolver/index_specification.rb
index 7b95608071..6fac8c1487 100644
--- a/lib/rubygems/resolver/index_specification.rb
+++ b/lib/rubygems/resolver/index_specification.rb
@@ -68,7 +68,7 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
end
def inspect # :nodoc:
- format("#<%s %s source %s>", self.class, full_name, @source)
+ "#<%s %s source %s>" % [self.class, full_name, @source]
end
def pretty_print(q) # :nodoc:
@@ -76,7 +76,7 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
q.breakable
q.text full_name
- unless @platform == Gem::Platform::RUBY
+ unless Gem::Platform::RUBY == @platform
q.breakable
q.text @platform.to_s
end
diff --git a/lib/rubygems/resolver/installed_specification.rb b/lib/rubygems/resolver/installed_specification.rb
index 8280ae4672..b80f882c77 100644
--- a/lib/rubygems/resolver/installed_specification.rb
+++ b/lib/rubygems/resolver/installed_specification.rb
@@ -25,7 +25,7 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
def installable_platform?
# BACKCOMPAT If the file is coming out of a specified file, then we
# ignore the platform. This code can be removed in RG 3.0.
- return true if @source.is_a? Gem::Source::SpecificFile
+ return true if @source.kind_of? Gem::Source::SpecificFile
super
end
diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb
index d9fe36c589..521d241fd5 100644
--- a/lib/rubygems/resolver/installer_set.rb
+++ b/lib/rubygems/resolver/installer_set.rb
@@ -163,8 +163,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
if local_spec = @local_source.find_gem(name, dep.requirement)
res << Gem::Resolver::IndexSpecification.new(
self, local_spec.name, local_spec.version,
- @local_source, local_spec.platform
- )
+ @local_source, local_spec.platform)
end
rescue Gem::Package::FormatError
# ignore
@@ -187,9 +186,11 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
end
def inspect # :nodoc:
- always_install = @always_install.map(&:full_name)
+ always_install = @always_install.map {|s| s.full_name }
- format("#<%s domain: %s specs: %p always install: %p>", self.class, @domain, @specs.keys, always_install)
+ "#<%s domain: %s specs: %p always install: %p>" % [
+ self.class, @domain, @specs.keys, always_install
+ ]
end
##
@@ -263,7 +264,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
unless rrgv.satisfied_by? Gem.rubygems_version
rg_version = Gem::VERSION
raise Gem::RuntimeRequirementNotMetError,
- "#{spec.full_name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " \
+ "#{spec.full_name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
"Try 'gem update --system' to update RubyGems itself."
end
end
diff --git a/lib/rubygems/resolver/local_specification.rb b/lib/rubygems/resolver/local_specification.rb
index b57d40e795..50bf276345 100644
--- a/lib/rubygems/resolver/local_specification.rb
+++ b/lib/rubygems/resolver/local_specification.rb
@@ -8,7 +8,7 @@ class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification
# Returns +true+ if this gem is installable for the current platform.
def installable_platform?
- return true if @source.is_a? Gem::Source::SpecificFile
+ return true if @source.kind_of? Gem::Source::SpecificFile
super
end
diff --git a/lib/rubygems/resolver/lock_set.rb b/lib/rubygems/resolver/lock_set.rb
index e5ee32a9a6..8eec041bdc 100644
--- a/lib/rubygems/resolver/lock_set.rb
+++ b/lib/rubygems/resolver/lock_set.rb
@@ -75,7 +75,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
q.text "specs:"
q.breakable
- q.pp @specs.map(&:full_name)
+ q.pp @specs.map {|spec| spec.full_name }
end
end
end
diff --git a/lib/rubygems/resolver/molinillo.rb b/lib/rubygems/resolver/molinillo.rb
new file mode 100644
index 0000000000..d703505410
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require_relative "molinillo/lib/molinillo"
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo.rb b/lib/rubygems/resolver/molinillo/lib/molinillo.rb
new file mode 100644
index 0000000000..f67badbde7
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require_relative 'molinillo/gem_metadata'
+require_relative 'molinillo/errors'
+require_relative 'molinillo/resolver'
+require_relative 'molinillo/modules/ui'
+require_relative 'molinillo/modules/specification_provider'
+
+# Gem::Resolver::Molinillo is a generic dependency resolution algorithm.
+module Gem::Resolver::Molinillo
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb
new file mode 100644
index 0000000000..d540d3baff
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ # @!visibility private
+ module Delegates
+ # Delegates all {Gem::Resolver::Molinillo::ResolutionState} methods to a `#state` property.
+ module ResolutionState
+ # (see Gem::Resolver::Molinillo::ResolutionState#name)
+ def name
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.name
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#requirements)
+ def requirements
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.requirements
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#activated)
+ def activated
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.activated
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#requirement)
+ def requirement
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.requirement
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#possibilities)
+ def possibilities
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.possibilities
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#depth)
+ def depth
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.depth
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#conflicts)
+ def conflicts
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.conflicts
+ end
+
+ # (see Gem::Resolver::Molinillo::ResolutionState#unused_unwind_options)
+ def unused_unwind_options
+ current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
+ current_state.unused_unwind_options
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb
new file mode 100644
index 0000000000..b765226fb0
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ module Delegates
+ # Delegates all {Gem::Resolver::Molinillo::SpecificationProvider} methods to a
+ # `#specification_provider` property.
+ module SpecificationProvider
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#search_for)
+ def search_for(dependency)
+ with_no_such_dependency_error_handling do
+ specification_provider.search_for(dependency)
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#dependencies_for)
+ def dependencies_for(specification)
+ with_no_such_dependency_error_handling do
+ specification_provider.dependencies_for(specification)
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#requirement_satisfied_by?)
+ def requirement_satisfied_by?(requirement, activated, spec)
+ with_no_such_dependency_error_handling do
+ specification_provider.requirement_satisfied_by?(requirement, activated, spec)
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#dependencies_equal?)
+ def dependencies_equal?(dependencies, other_dependencies)
+ with_no_such_dependency_error_handling do
+ specification_provider.dependencies_equal?(dependencies, other_dependencies)
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#name_for)
+ def name_for(dependency)
+ with_no_such_dependency_error_handling do
+ specification_provider.name_for(dependency)
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#name_for_explicit_dependency_source)
+ def name_for_explicit_dependency_source
+ with_no_such_dependency_error_handling do
+ specification_provider.name_for_explicit_dependency_source
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#name_for_locking_dependency_source)
+ def name_for_locking_dependency_source
+ with_no_such_dependency_error_handling do
+ specification_provider.name_for_locking_dependency_source
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#sort_dependencies)
+ def sort_dependencies(dependencies, activated, conflicts)
+ with_no_such_dependency_error_handling do
+ specification_provider.sort_dependencies(dependencies, activated, conflicts)
+ end
+ end
+
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#allow_missing?)
+ def allow_missing?(dependency)
+ with_no_such_dependency_error_handling do
+ specification_provider.allow_missing?(dependency)
+ end
+ end
+
+ private
+
+ # Ensures any raised {NoSuchDependencyError} has its
+ # {NoSuchDependencyError#required_by} set.
+ # @yield
+ def with_no_such_dependency_error_handling
+ yield
+ rescue NoSuchDependencyError => error
+ if state
+ vertex = activated.vertex_named(name_for(error.dependency))
+ error.required_by += vertex.incoming_edges.map { |e| e.origin.name }
+ error.required_by << name_for_explicit_dependency_source unless vertex.explicit_requirements.empty?
+ end
+ raise
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb
new file mode 100644
index 0000000000..731a9e3e90
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb
@@ -0,0 +1,255 @@
+# frozen_string_literal: true
+
+require_relative '../../../../tsort'
+
+require_relative 'dependency_graph/log'
+require_relative 'dependency_graph/vertex'
+
+module Gem::Resolver::Molinillo
+ # A directed acyclic graph that is tuned to hold named dependencies
+ class DependencyGraph
+ include Enumerable
+
+ # Enumerates through the vertices of the graph.
+ # @return [Array<Vertex>] The graph's vertices.
+ def each
+ return vertices.values.each unless block_given?
+ vertices.values.each { |v| yield v }
+ end
+
+ include Gem::TSort
+
+ # @!visibility private
+ alias tsort_each_node each
+
+ # @!visibility private
+ def tsort_each_child(vertex, &block)
+ vertex.successors.each(&block)
+ end
+
+ # Topologically sorts the given vertices.
+ # @param [Enumerable<Vertex>] vertices the vertices to be sorted, which must
+ # all belong to the same graph.
+ # @return [Array<Vertex>] The sorted vertices.
+ def self.tsort(vertices)
+ Gem::TSort.tsort(
+ lambda { |b| vertices.each(&b) },
+ lambda { |v, &b| (v.successors & vertices).each(&b) }
+ )
+ end
+
+ # A directed edge of a {DependencyGraph}
+ # @attr [Vertex] origin The origin of the directed edge
+ # @attr [Vertex] destination The destination of the directed edge
+ # @attr [Object] requirement The requirement the directed edge represents
+ Edge = Struct.new(:origin, :destination, :requirement)
+
+ # @return [{String => Vertex}] the vertices of the dependency graph, keyed
+ # by {Vertex#name}
+ attr_reader :vertices
+
+ # @return [Log] the op log for this graph
+ attr_reader :log
+
+ # Initializes an empty dependency graph
+ def initialize
+ @vertices = {}
+ @log = Log.new
+ end
+
+ # Tags the current state of the dependency as the given tag
+ # @param [Object] tag an opaque tag for the current state of the graph
+ # @return [Void]
+ def tag(tag)
+ log.tag(self, tag)
+ end
+
+ # Rewinds the graph to the state tagged as `tag`
+ # @param [Object] tag the tag to rewind to
+ # @return [Void]
+ def rewind_to(tag)
+ log.rewind_to(self, tag)
+ end
+
+ # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
+ # are properly copied.
+ # @param [DependencyGraph] other the graph to copy.
+ def initialize_copy(other)
+ super
+ @vertices = {}
+ @log = other.log.dup
+ traverse = lambda do |new_v, old_v|
+ return if new_v.outgoing_edges.size == old_v.outgoing_edges.size
+ old_v.outgoing_edges.each do |edge|
+ destination = add_vertex(edge.destination.name, edge.destination.payload)
+ add_edge_no_circular(new_v, destination, edge.requirement)
+ traverse.call(destination, edge.destination)
+ end
+ end
+ other.vertices.each do |name, vertex|
+ new_vertex = add_vertex(name, vertex.payload, vertex.root?)
+ new_vertex.explicit_requirements.replace(vertex.explicit_requirements)
+ traverse.call(new_vertex, vertex)
+ end
+ end
+
+ # @return [String] a string suitable for debugging
+ def inspect
+ "#{self.class}:#{vertices.values.inspect}"
+ end
+
+ # @param [Hash] options options for dot output.
+ # @return [String] Returns a dot format representation of the graph
+ def to_dot(options = {})
+ edge_label = options.delete(:edge_label)
+ raise ArgumentError, "Unknown options: #{options.keys}" unless options.empty?
+
+ dot_vertices = []
+ dot_edges = []
+ vertices.each do |n, v|
+ dot_vertices << " #{n} [label=\"{#{n}|#{v.payload}}\"]"
+ v.outgoing_edges.each do |e|
+ label = edge_label ? edge_label.call(e) : e.requirement
+ dot_edges << " #{e.origin.name} -> #{e.destination.name} [label=#{label.to_s.dump}]"
+ end
+ end
+
+ dot_vertices.uniq!
+ dot_vertices.sort!
+ dot_edges.uniq!
+ dot_edges.sort!
+
+ dot = dot_vertices.unshift('digraph G {').push('') + dot_edges.push('}')
+ dot.join("\n")
+ end
+
+ # @param [DependencyGraph] other
+ # @return [Boolean] whether the two dependency graphs are equal, determined
+ # by a recursive traversal of each {#root_vertices} and its
+ # {Vertex#successors}
+ def ==(other)
+ return false unless other
+ return true if equal?(other)
+ vertices.each do |name, vertex|
+ other_vertex = other.vertex_named(name)
+ return false unless other_vertex
+ return false unless vertex.payload == other_vertex.payload
+ return false unless other_vertex.successors.to_set == vertex.successors.to_set
+ end
+ end
+
+ # @param [String] name
+ # @param [Object] payload
+ # @param [Array<String>] parent_names
+ # @param [Object] requirement the requirement that is requiring the child
+ # @return [void]
+ def add_child_vertex(name, payload, parent_names, requirement)
+ root = !parent_names.delete(nil) { true }
+ vertex = add_vertex(name, payload, root)
+ vertex.explicit_requirements << requirement if root
+ parent_names.each do |parent_name|
+ parent_vertex = vertex_named(parent_name)
+ add_edge(parent_vertex, vertex, requirement)
+ end
+ vertex
+ end
+
+ # Adds a vertex with the given name, or updates the existing one.
+ # @param [String] name
+ # @param [Object] payload
+ # @return [Vertex] the vertex that was added to `self`
+ def add_vertex(name, payload, root = false)
+ log.add_vertex(self, name, payload, root)
+ end
+
+ # Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
+ # removing any non-root vertices that were orphaned in the process
+ # @param [String] name
+ # @return [Array<Vertex>] the vertices which have been detached
+ def detach_vertex_named(name)
+ log.detach_vertex_named(self, name)
+ end
+
+ # @param [String] name
+ # @return [Vertex,nil] the vertex with the given name
+ def vertex_named(name)
+ vertices[name]
+ end
+
+ # @param [String] name
+ # @return [Vertex,nil] the root vertex with the given name
+ def root_vertex_named(name)
+ vertex = vertex_named(name)
+ vertex if vertex && vertex.root?
+ end
+
+ # Adds a new {Edge} to the dependency graph
+ # @param [Vertex] origin
+ # @param [Vertex] destination
+ # @param [Object] requirement the requirement that this edge represents
+ # @return [Edge] the added edge
+ def add_edge(origin, destination, requirement)
+ if destination.path_to?(origin)
+ raise CircularDependencyError.new(path(destination, origin))
+ end
+ add_edge_no_circular(origin, destination, requirement)
+ end
+
+ # Deletes an {Edge} from the dependency graph
+ # @param [Edge] edge
+ # @return [Void]
+ def delete_edge(edge)
+ log.delete_edge(self, edge.origin.name, edge.destination.name, edge.requirement)
+ end
+
+ # Sets the payload of the vertex with the given name
+ # @param [String] name the name of the vertex
+ # @param [Object] payload the payload
+ # @return [Void]
+ def set_payload(name, payload)
+ log.set_payload(self, name, payload)
+ end
+
+ private
+
+ # Adds a new {Edge} to the dependency graph without checking for
+ # circularity.
+ # @param (see #add_edge)
+ # @return (see #add_edge)
+ def add_edge_no_circular(origin, destination, requirement)
+ log.add_edge_no_circular(self, origin.name, destination.name, requirement)
+ end
+
+ # Returns the path between two vertices
+ # @raise [ArgumentError] if there is no path between the vertices
+ # @param [Vertex] from
+ # @param [Vertex] to
+ # @return [Array<Vertex>] the shortest path from `from` to `to`
+ def path(from, to)
+ distances = Hash.new(vertices.size + 1)
+ distances[from.name] = 0
+ predecessors = {}
+ each do |vertex|
+ vertex.successors.each do |successor|
+ if distances[successor.name] > distances[vertex.name] + 1
+ distances[successor.name] = distances[vertex.name] + 1
+ predecessors[successor] = vertex
+ end
+ end
+ end
+
+ path = [to]
+ while before = predecessors[to]
+ path << before
+ to = before
+ break if to == from
+ end
+
+ unless path.last.equal?(from)
+ raise ArgumentError, "There is no path from #{from.name} to #{to.name}"
+ end
+
+ path.reverse
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb
new file mode 100644
index 0000000000..cc140031b3
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # An action that modifies a {DependencyGraph} that is reversible.
+ # @abstract
+ class Action
+ # rubocop:disable Lint/UnusedMethodArgument
+
+ # @return [Symbol] The name of the action.
+ def self.action_name
+ raise 'Abstract'
+ end
+
+ # Performs the action on the given graph.
+ # @param [DependencyGraph] graph the graph to perform the action on.
+ # @return [Void]
+ def up(graph)
+ raise 'Abstract'
+ end
+
+ # Reverses the action on the given graph.
+ # @param [DependencyGraph] graph the graph to reverse the action on.
+ # @return [Void]
+ def down(graph)
+ raise 'Abstract'
+ end
+
+ # @return [Action,Nil] The previous action
+ attr_accessor :previous
+
+ # @return [Action,Nil] The next action
+ attr_accessor :next
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
new file mode 100644
index 0000000000..5570483253
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require_relative 'action'
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # @!visibility private
+ # (see DependencyGraph#add_edge_no_circular)
+ class AddEdgeNoCircular < Action
+ # @!group Action
+
+ # (see Action.action_name)
+ def self.action_name
+ :add_vertex
+ end
+
+ # (see Action#up)
+ def up(graph)
+ edge = make_edge(graph)
+ edge.origin.outgoing_edges << edge
+ edge.destination.incoming_edges << edge
+ edge
+ end
+
+ # (see Action#down)
+ def down(graph)
+ edge = make_edge(graph)
+ delete_first(edge.origin.outgoing_edges, edge)
+ delete_first(edge.destination.incoming_edges, edge)
+ end
+
+ # @!group AddEdgeNoCircular
+
+ # @return [String] the name of the origin of the edge
+ attr_reader :origin
+
+ # @return [String] the name of the destination of the edge
+ attr_reader :destination
+
+ # @return [Object] the requirement that the edge represents
+ attr_reader :requirement
+
+ # @param [DependencyGraph] graph the graph to find vertices from
+ # @return [Edge] The edge this action adds
+ def make_edge(graph)
+ Edge.new(graph.vertex_named(origin), graph.vertex_named(destination), requirement)
+ end
+
+ # Initialize an action to add an edge to a dependency graph
+ # @param [String] origin the name of the origin of the edge
+ # @param [String] destination the name of the destination of the edge
+ # @param [Object] requirement the requirement that the edge represents
+ def initialize(origin, destination, requirement)
+ @origin = origin
+ @destination = destination
+ @requirement = requirement
+ end
+
+ private
+
+ def delete_first(array, item)
+ return unless index = array.index(item)
+ array.delete_at(index)
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
new file mode 100644
index 0000000000..f1411d5efa
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require_relative 'action'
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # @!visibility private
+ # (see DependencyGraph#add_vertex)
+ class AddVertex < Action # :nodoc:
+ # @!group Action
+
+ # (see Action.action_name)
+ def self.action_name
+ :add_vertex
+ end
+
+ # (see Action#up)
+ def up(graph)
+ if existing = graph.vertices[name]
+ @existing_payload = existing.payload
+ @existing_root = existing.root
+ end
+ vertex = existing || Vertex.new(name, payload)
+ graph.vertices[vertex.name] = vertex
+ vertex.payload ||= payload
+ vertex.root ||= root
+ vertex
+ end
+
+ # (see Action#down)
+ def down(graph)
+ if defined?(@existing_payload)
+ vertex = graph.vertices[name]
+ vertex.payload = @existing_payload
+ vertex.root = @existing_root
+ else
+ graph.vertices.delete(name)
+ end
+ end
+
+ # @!group AddVertex
+
+ # @return [String] the name of the vertex
+ attr_reader :name
+
+ # @return [Object] the payload for the vertex
+ attr_reader :payload
+
+ # @return [Boolean] whether the vertex is root or not
+ attr_reader :root
+
+ # Initialize an action to add a vertex to a dependency graph
+ # @param [String] name the name of the vertex
+ # @param [Object] payload the payload for the vertex
+ # @param [Boolean] root whether the vertex is root or not
+ def initialize(name, payload, root)
+ @name = name
+ @payload = payload
+ @root = root
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
new file mode 100644
index 0000000000..3b48d77a50
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require_relative 'action'
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # @!visibility private
+ # (see DependencyGraph#delete_edge)
+ class DeleteEdge < Action
+ # @!group Action
+
+ # (see Action.action_name)
+ def self.action_name
+ :delete_edge
+ end
+
+ # (see Action#up)
+ def up(graph)
+ edge = make_edge(graph)
+ edge.origin.outgoing_edges.delete(edge)
+ edge.destination.incoming_edges.delete(edge)
+ end
+
+ # (see Action#down)
+ def down(graph)
+ edge = make_edge(graph)
+ edge.origin.outgoing_edges << edge
+ edge.destination.incoming_edges << edge
+ edge
+ end
+
+ # @!group DeleteEdge
+
+ # @return [String] the name of the origin of the edge
+ attr_reader :origin_name
+
+ # @return [String] the name of the destination of the edge
+ attr_reader :destination_name
+
+ # @return [Object] the requirement that the edge represents
+ attr_reader :requirement
+
+ # @param [DependencyGraph] graph the graph to find vertices from
+ # @return [Edge] The edge this action adds
+ def make_edge(graph)
+ Edge.new(
+ graph.vertex_named(origin_name),
+ graph.vertex_named(destination_name),
+ requirement
+ )
+ end
+
+ # Initialize an action to add an edge to a dependency graph
+ # @param [String] origin_name the name of the origin of the edge
+ # @param [String] destination_name the name of the destination of the edge
+ # @param [Object] requirement the requirement that the edge represents
+ def initialize(origin_name, destination_name, requirement)
+ @origin_name = origin_name
+ @destination_name = destination_name
+ @requirement = requirement
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
new file mode 100644
index 0000000000..92f60d5be8
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require_relative 'action'
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # @!visibility private
+ # @see DependencyGraph#detach_vertex_named
+ class DetachVertexNamed < Action
+ # @!group Action
+
+ # (see Action#name)
+ def self.action_name
+ :add_vertex
+ end
+
+ # (see Action#up)
+ def up(graph)
+ return [] unless @vertex = graph.vertices.delete(name)
+
+ removed_vertices = [@vertex]
+ @vertex.outgoing_edges.each do |e|
+ v = e.destination
+ v.incoming_edges.delete(e)
+ if !v.root? && v.incoming_edges.empty?
+ removed_vertices.concat graph.detach_vertex_named(v.name)
+ end
+ end
+
+ @vertex.incoming_edges.each do |e|
+ v = e.origin
+ v.outgoing_edges.delete(e)
+ end
+
+ removed_vertices
+ end
+
+ # (see Action#down)
+ def down(graph)
+ return unless @vertex
+ graph.vertices[@vertex.name] = @vertex
+ @vertex.outgoing_edges.each do |e|
+ e.destination.incoming_edges << e
+ end
+ @vertex.incoming_edges.each do |e|
+ e.origin.outgoing_edges << e
+ end
+ end
+
+ # @!group DetachVertexNamed
+
+ # @return [String] the name of the vertex to detach
+ attr_reader :name
+
+ # Initialize an action to detach a vertex from a dependency graph
+ # @param [String] name the name of the vertex to detach
+ def initialize(name)
+ @name = name
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb
new file mode 100644
index 0000000000..7aeb8847ec
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+require_relative 'add_edge_no_circular'
+require_relative 'add_vertex'
+require_relative 'delete_edge'
+require_relative 'detach_vertex_named'
+require_relative 'set_payload'
+require_relative 'tag'
+
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # A log for dependency graph actions
+ class Log
+ # Initializes an empty log
+ def initialize
+ @current_action = @first_action = nil
+ end
+
+ # @!macro [new] action
+ # {include:DependencyGraph#$0}
+ # @param [Graph] graph the graph to perform the action on
+ # @param (see DependencyGraph#$0)
+ # @return (see DependencyGraph#$0)
+
+ # @macro action
+ def tag(graph, tag)
+ push_action(graph, Tag.new(tag))
+ end
+
+ # @macro action
+ def add_vertex(graph, name, payload, root)
+ push_action(graph, AddVertex.new(name, payload, root))
+ end
+
+ # @macro action
+ def detach_vertex_named(graph, name)
+ push_action(graph, DetachVertexNamed.new(name))
+ end
+
+ # @macro action
+ def add_edge_no_circular(graph, origin, destination, requirement)
+ push_action(graph, AddEdgeNoCircular.new(origin, destination, requirement))
+ end
+
+ # {include:DependencyGraph#delete_edge}
+ # @param [Graph] graph the graph to perform the action on
+ # @param [String] origin_name
+ # @param [String] destination_name
+ # @param [Object] requirement
+ # @return (see DependencyGraph#delete_edge)
+ def delete_edge(graph, origin_name, destination_name, requirement)
+ push_action(graph, DeleteEdge.new(origin_name, destination_name, requirement))
+ end
+
+ # @macro action
+ def set_payload(graph, name, payload)
+ push_action(graph, SetPayload.new(name, payload))
+ end
+
+ # Pops the most recent action from the log and undoes the action
+ # @param [DependencyGraph] graph
+ # @return [Action] the action that was popped off the log
+ def pop!(graph)
+ return unless action = @current_action
+ unless @current_action = action.previous
+ @first_action = nil
+ end
+ action.down(graph)
+ action
+ end
+
+ extend Enumerable
+
+ # @!visibility private
+ # Enumerates each action in the log
+ # @yield [Action]
+ def each
+ return enum_for unless block_given?
+ action = @first_action
+ loop do
+ break unless action
+ yield action
+ action = action.next
+ end
+ self
+ end
+
+ # @!visibility private
+ # Enumerates each action in the log in reverse order
+ # @yield [Action]
+ def reverse_each
+ return enum_for(:reverse_each) unless block_given?
+ action = @current_action
+ loop do
+ break unless action
+ yield action
+ action = action.previous
+ end
+ self
+ end
+
+ # @macro action
+ def rewind_to(graph, tag)
+ loop do
+ action = pop!(graph)
+ raise "No tag #{tag.inspect} found" unless action
+ break if action.class.action_name == :tag && action.tag == tag
+ end
+ end
+
+ private
+
+ # Adds the given action to the log, running the action
+ # @param [DependencyGraph] graph
+ # @param [Action] action
+ # @return The value returned by `action.up`
+ def push_action(graph, action)
+ action.previous = @current_action
+ @current_action.next = action if @current_action
+ @current_action = action
+ @first_action ||= action
+ action.up(graph)
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb
new file mode 100644
index 0000000000..726292a2c3
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require_relative 'action'
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # @!visibility private
+ # @see DependencyGraph#set_payload
+ class SetPayload < Action # :nodoc:
+ # @!group Action
+
+ # (see Action.action_name)
+ def self.action_name
+ :set_payload
+ end
+
+ # (see Action#up)
+ def up(graph)
+ vertex = graph.vertex_named(name)
+ @old_payload = vertex.payload
+ vertex.payload = payload
+ end
+
+ # (see Action#down)
+ def down(graph)
+ graph.vertex_named(name).payload = @old_payload
+ end
+
+ # @!group SetPayload
+
+ # @return [String] the name of the vertex
+ attr_reader :name
+
+ # @return [Object] the payload for the vertex
+ attr_reader :payload
+
+ # Initialize an action to add set the payload for a vertex in a dependency
+ # graph
+ # @param [String] name the name of the vertex
+ # @param [Object] payload the payload for the vertex
+ def initialize(name, payload)
+ @name = name
+ @payload = payload
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb
new file mode 100644
index 0000000000..bfe6fd31f8
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require_relative 'action'
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # @!visibility private
+ # @see DependencyGraph#tag
+ class Tag < Action
+ # @!group Action
+
+ # (see Action.action_name)
+ def self.action_name
+ :tag
+ end
+
+ # (see Action#up)
+ def up(graph)
+ end
+
+ # (see Action#down)
+ def down(graph)
+ end
+
+ # @!group Tag
+
+ # @return [Object] An opaque tag
+ attr_reader :tag
+
+ # Initialize an action to tag a state of a dependency graph
+ # @param [Object] tag an opaque tag
+ def initialize(tag)
+ @tag = tag
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb
new file mode 100644
index 0000000000..77114951b2
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ class DependencyGraph
+ # A vertex in a {DependencyGraph} that encapsulates a {#name} and a
+ # {#payload}
+ class Vertex
+ # @return [String] the name of the vertex
+ attr_accessor :name
+
+ # @return [Object] the payload the vertex holds
+ attr_accessor :payload
+
+ # @return [Array<Object>] the explicit requirements that required
+ # this vertex
+ attr_reader :explicit_requirements
+
+ # @return [Boolean] whether the vertex is considered a root vertex
+ attr_accessor :root
+ alias root? root
+
+ # Initializes a vertex with the given name and payload.
+ # @param [String] name see {#name}
+ # @param [Object] payload see {#payload}
+ def initialize(name, payload)
+ @name = name.frozen? ? name : name.dup.freeze
+ @payload = payload
+ @explicit_requirements = []
+ @outgoing_edges = []
+ @incoming_edges = []
+ end
+
+ # @return [Array<Object>] all of the requirements that required
+ # this vertex
+ def requirements
+ (incoming_edges.map(&:requirement) + explicit_requirements).uniq
+ end
+
+ # @return [Array<Edge>] the edges of {#graph} that have `self` as their
+ # {Edge#origin}
+ attr_accessor :outgoing_edges
+
+ # @return [Array<Edge>] the edges of {#graph} that have `self` as their
+ # {Edge#destination}
+ attr_accessor :incoming_edges
+
+ # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
+ # `self` as their {Edge#destination}
+ def predecessors
+ incoming_edges.map(&:origin)
+ end
+
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
+ # {#descendent?}
+ def recursive_predecessors
+ _recursive_predecessors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the predecessors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
+ # {#descendent?}
+ def _recursive_predecessors(vertices = new_vertex_set)
+ incoming_edges.each do |edge|
+ vertex = edge.origin
+ next unless vertices.add?(vertex)
+ vertex._recursive_predecessors(vertices)
+ end
+
+ vertices
+ end
+ protected :_recursive_predecessors
+
+ # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
+ # `self` as their {Edge#origin}
+ def successors
+ outgoing_edges.map(&:destination)
+ end
+
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
+ # {#ancestor?}
+ def recursive_successors
+ _recursive_successors
+ end
+
+ # @param [Set<Vertex>] vertices the set to add the successors to
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
+ # {#ancestor?}
+ def _recursive_successors(vertices = new_vertex_set)
+ outgoing_edges.each do |edge|
+ vertex = edge.destination
+ next unless vertices.add?(vertex)
+ vertex._recursive_successors(vertices)
+ end
+
+ vertices
+ end
+ protected :_recursive_successors
+
+ # @return [String] a string suitable for debugging
+ def inspect
+ "#{self.class}:#{name}(#{payload.inspect})"
+ end
+
+ # @return [Boolean] whether the two vertices are equal, determined
+ # by a recursive traversal of each {Vertex#successors}
+ def ==(other)
+ return true if equal?(other)
+ shallow_eql?(other) &&
+ successors.to_set == other.successors.to_set
+ end
+
+ # @param [Vertex] other the other vertex to compare to
+ # @return [Boolean] whether the two vertices are equal, determined
+ # solely by {#name} and {#payload} equality
+ def shallow_eql?(other)
+ return true if equal?(other)
+ other &&
+ name == other.name &&
+ payload == other.payload
+ end
+
+ alias eql? ==
+
+ # @return [Fixnum] a hash for the vertex based upon its {#name}
+ def hash
+ name.hash
+ end
+
+ # Is there a path from `self` to `other` following edges in the
+ # dependency graph?
+ # @return whether there is a path following edges within this {#graph}
+ def path_to?(other)
+ _path_to?(other)
+ end
+
+ alias descendent? path_to?
+
+ # @param [Vertex] other the vertex to check if there's a path to
+ # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
+ # @return [Boolean] whether there is a path to `other` from `self`
+ def _path_to?(other, visited = new_vertex_set)
+ return false unless visited.add?(self)
+ return true if equal?(other)
+ successors.any? { |v| v._path_to?(other, visited) }
+ end
+ protected :_path_to?
+
+ # Is there a path from `other` to `self` following edges in the
+ # dependency graph?
+ # @return whether there is a path following edges within this {#graph}
+ def ancestor?(other)
+ other.path_to?(self)
+ end
+
+ alias is_reachable_from? ancestor?
+
+ def new_vertex_set
+ require 'set'
+ Set.new
+ end
+ private :new_vertex_set
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb
new file mode 100644
index 0000000000..4289902828
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb
@@ -0,0 +1,149 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ # An error that occurred during the resolution process
+ class ResolverError < StandardError; end
+
+ # An error caused by searching for a dependency that is completely unknown,
+ # i.e. has no versions available whatsoever.
+ class NoSuchDependencyError < ResolverError
+ # @return [Object] the dependency that could not be found
+ attr_accessor :dependency
+
+ # @return [Array<Object>] the specifications that depended upon {#dependency}
+ attr_accessor :required_by
+
+ # Initializes a new error with the given missing dependency.
+ # @param [Object] dependency @see {#dependency}
+ # @param [Array<Object>] required_by @see {#required_by}
+ def initialize(dependency, required_by = [])
+ @dependency = dependency
+ @required_by = required_by.uniq
+ super()
+ end
+
+ # The error message for the missing dependency, including the specifications
+ # that had this dependency.
+ def message
+ sources = required_by.map { |r| "`#{r}`" }.join(' and ')
+ message = "Unable to find a specification for `#{dependency}`"
+ message += " depended upon by #{sources}" unless sources.empty?
+ message
+ end
+ end
+
+ # An error caused by attempting to fulfil a dependency that was circular
+ #
+ # @note This exception will be thrown if and only if a {Vertex} is added to a
+ # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
+ # existing {DependencyGraph::Vertex}
+ class CircularDependencyError < ResolverError
+ # [Set<Object>] the dependencies responsible for causing the error
+ attr_reader :dependencies
+
+ # Initializes a new error with the given circular vertices.
+ # @param [Array<DependencyGraph::Vertex>] vertices the vertices in the dependency
+ # that caused the error
+ def initialize(vertices)
+ super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}"
+ @dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set
+ end
+ end
+
+ # An error caused by conflicts in version
+ class VersionConflict < ResolverError
+ # @return [{String => Resolution::Conflict}] the conflicts that caused
+ # resolution to fail
+ attr_reader :conflicts
+
+ # @return [SpecificationProvider] the specification provider used during
+ # resolution
+ attr_reader :specification_provider
+
+ # Initializes a new error with the given version conflicts.
+ # @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
+ # @param [SpecificationProvider] specification_provider see {#specification_provider}
+ def initialize(conflicts, specification_provider)
+ pairs = []
+ conflicts.values.flat_map(&:requirements).each do |conflicting|
+ conflicting.each do |source, conflict_requirements|
+ conflict_requirements.each do |c|
+ pairs << [c, source]
+ end
+ end
+ end
+
+ super "Unable to satisfy the following requirements:\n\n" \
+ "#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
+
+ @conflicts = conflicts
+ @specification_provider = specification_provider
+ end
+
+ require_relative 'delegates/specification_provider'
+ include Delegates::SpecificationProvider
+
+ # @return [String] An error message that includes requirement trees,
+ # which is much more detailed & customizable than the default message
+ # @param [Hash] opts the options to create a message with.
+ # @option opts [String] :solver_name The user-facing name of the solver
+ # @option opts [String] :possibility_type The generic name of a possibility
+ # @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees
+ # @option opts [Proc] :printable_requirement A proc that pretty-prints requirements
+ # @option opts [Proc] :additional_message_for_conflict A proc that appends additional
+ # messages for each conflict
+ # @option opts [Proc] :version_for_spec A proc that returns the version number for a
+ # possibility
+ def message_with_trees(opts = {})
+ solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
+ possibility_type = opts.delete(:possibility_type) { 'possibility named' }
+ reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
+ printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
+ additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
+ version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
+ incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
+ proc do |name, _conflict|
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
+ end
+ end
+
+ full_message_for_conflict = opts.delete(:full_message_for_conflict) do
+ proc do |name, conflict|
+ o = "\n".dup << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
+ if conflict.locked_requirement
+ o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
+ o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
+ o << %(\n)
+ end
+ o << %( In #{name_for_explicit_dependency_source}:\n)
+ trees = reduce_trees.call(conflict.requirement_trees)
+
+ o << trees.map do |tree|
+ t = ''.dup
+ depth = 2
+ tree.each do |req|
+ t << ' ' * depth << printable_requirement.call(req)
+ unless tree.last == req
+ if spec = conflict.activated_by_name[name_for(req)]
+ t << %( was resolved to #{version_for_spec.call(spec)}, which)
+ end
+ t << %( depends on)
+ end
+ t << %(\n)
+ depth += 1
+ end
+ t
+ end.join("\n")
+
+ additional_message_for_conflict.call(o, name, conflict)
+
+ o
+ end
+ end
+
+ conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
+ o << full_message_for_conflict.call(name, conflict)
+ end.strip
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb
new file mode 100644
index 0000000000..86c249c404
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ # The version of Gem::Resolver::Molinillo.
+ VERSION = '0.8.0'.freeze
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb
new file mode 100644
index 0000000000..1067bf7439
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb
@@ -0,0 +1,112 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ # Provides information about specifications and dependencies to the resolver,
+ # allowing the {Resolver} class to remain generic while still providing power
+ # and flexibility.
+ #
+ # This module contains the methods that users of Gem::Resolver::Molinillo must to implement,
+ # using knowledge of their own model classes.
+ module SpecificationProvider
+ # Search for the specifications that match the given dependency.
+ # The specifications in the returned array will be considered in reverse
+ # order, so the latest version ought to be last.
+ # @note This method should be 'pure', i.e. the return value should depend
+ # only on the `dependency` parameter.
+ #
+ # @param [Object] dependency
+ # @return [Array<Object>] the specifications that satisfy the given
+ # `dependency`.
+ def search_for(dependency)
+ []
+ end
+
+ # Returns the dependencies of `specification`.
+ # @note This method should be 'pure', i.e. the return value should depend
+ # only on the `specification` parameter.
+ #
+ # @param [Object] specification
+ # @return [Array<Object>] the dependencies that are required by the given
+ # `specification`.
+ def dependencies_for(specification)
+ []
+ end
+
+ # Determines whether the given `requirement` is satisfied by the given
+ # `spec`, in the context of the current `activated` dependency graph.
+ #
+ # @param [Object] requirement
+ # @param [DependencyGraph] activated the current dependency graph in the
+ # resolution process.
+ # @param [Object] spec
+ # @return [Boolean] whether `requirement` is satisfied by `spec` in the
+ # context of the current `activated` dependency graph.
+ def requirement_satisfied_by?(requirement, activated, spec)
+ true
+ end
+
+ # Determines whether two arrays of dependencies are equal, and thus can be
+ # grouped.
+ #
+ # @param [Array<Object>] dependencies
+ # @param [Array<Object>] other_dependencies
+ # @return [Boolean] whether `dependencies` and `other_dependencies` should
+ # be considered equal.
+ def dependencies_equal?(dependencies, other_dependencies)
+ dependencies == other_dependencies
+ end
+
+ # Returns the name for the given `dependency`.
+ # @note This method should be 'pure', i.e. the return value should depend
+ # only on the `dependency` parameter.
+ #
+ # @param [Object] dependency
+ # @return [String] the name for the given `dependency`.
+ def name_for(dependency)
+ dependency.to_s
+ end
+
+ # @return [String] the name of the source of explicit dependencies, i.e.
+ # those passed to {Resolver#resolve} directly.
+ def name_for_explicit_dependency_source
+ 'user-specified dependency'
+ end
+
+ # @return [String] the name of the source of 'locked' dependencies, i.e.
+ # those passed to {Resolver#resolve} directly as the `base`
+ def name_for_locking_dependency_source
+ 'Lockfile'
+ end
+
+ # Sort dependencies so that the ones that are easiest to resolve are first.
+ # Easiest to resolve is (usually) defined by:
+ # 1) Is this dependency already activated?
+ # 2) How relaxed are the requirements?
+ # 3) Are there any conflicts for this dependency?
+ # 4) How many possibilities are there to satisfy this dependency?
+ #
+ # @param [Array<Object>] dependencies
+ # @param [DependencyGraph] activated the current dependency graph in the
+ # resolution process.
+ # @param [{String => Array<Conflict>}] conflicts
+ # @return [Array<Object>] a sorted copy of `dependencies`.
+ def sort_dependencies(dependencies, activated, conflicts)
+ dependencies.sort_by do |dependency|
+ name = name_for(dependency)
+ [
+ activated.vertex_named(name).payload ? 0 : 1,
+ conflicts[name] ? 0 : 1,
+ ]
+ end
+ end
+
+ # Returns whether this dependency, which has no possible matching
+ # specifications, can safely be ignored.
+ #
+ # @param [Object] dependency
+ # @return [Boolean] whether this dependency can safely be skipped.
+ def allow_missing?(dependency)
+ false
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb
new file mode 100644
index 0000000000..a810fd519c
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ # Conveys information about the resolution process to a user.
+ module UI
+ # The {IO} object that should be used to print output. `STDOUT`, by default.
+ #
+ # @return [IO]
+ def output
+ STDOUT
+ end
+
+ # Called roughly every {#progress_rate}, this method should convey progress
+ # to the user.
+ #
+ # @return [void]
+ def indicate_progress
+ output.print '.' unless debug?
+ end
+
+ # How often progress should be conveyed to the user via
+ # {#indicate_progress}, in seconds. A third of a second, by default.
+ #
+ # @return [Float]
+ def progress_rate
+ 0.33
+ end
+
+ # Called before resolution begins.
+ #
+ # @return [void]
+ def before_resolution
+ output.print 'Resolving dependencies...'
+ end
+
+ # Called after resolution ends (either successfully or with an error).
+ # By default, prints a newline.
+ #
+ # @return [void]
+ def after_resolution
+ output.puts
+ end
+
+ # Conveys debug information to the user.
+ #
+ # @param [Integer] depth the current depth of the resolution process.
+ # @return [void]
+ def debug(depth = 0)
+ if debug?
+ debug_info = yield
+ debug_info = debug_info.inspect unless debug_info.is_a?(String)
+ debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" }
+ output.puts debug_info
+ end
+ end
+
+ # Whether or not debug messages should be printed.
+ # By default, whether or not the `MOLINILLO_DEBUG` environment variable is
+ # set.
+ #
+ # @return [Boolean]
+ def debug?
+ return @debug_mode if defined?(@debug_mode)
+ @debug_mode = ENV['MOLINILLO_DEBUG']
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb
new file mode 100644
index 0000000000..8b40e59e42
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb
@@ -0,0 +1,839 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ class Resolver
+ # A specific resolution from a given {Resolver}
+ class Resolution
+ # A conflict that the resolution process encountered
+ # @attr [Object] requirement the requirement that immediately led to the conflict
+ # @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
+ # @attr [Object, nil] existing the existing spec that was in conflict with
+ # the {#possibility}
+ # @attr [Object] possibility_set the set of specs that was unable to be
+ # activated due to a conflict.
+ # @attr [Object] locked_requirement the relevant locking requirement.
+ # @attr [Array<Array<Object>>] requirement_trees the different requirement
+ # trees that led to every requirement for the conflicting name.
+ # @attr [{String=>Object}] activated_by_name the already-activated specs.
+ # @attr [Object] underlying_error an error that has occurred during resolution, and
+ # will be raised at the end of it if no resolution is found.
+ Conflict = Struct.new(
+ :requirement,
+ :requirements,
+ :existing,
+ :possibility_set,
+ :locked_requirement,
+ :requirement_trees,
+ :activated_by_name,
+ :underlying_error
+ )
+
+ class Conflict
+ # @return [Object] a spec that was unable to be activated due to a conflict
+ def possibility
+ possibility_set && possibility_set.latest_version
+ end
+ end
+
+ # A collection of possibility states that share the same dependencies
+ # @attr [Array] dependencies the dependencies for this set of possibilities
+ # @attr [Array] possibilities the possibilities
+ PossibilitySet = Struct.new(:dependencies, :possibilities)
+
+ class PossibilitySet
+ # String representation of the possibility set, for debugging
+ def to_s
+ "[#{possibilities.join(', ')}]"
+ end
+
+ # @return [Object] most up-to-date dependency in the possibility set
+ def latest_version
+ possibilities.last
+ end
+ end
+
+ # Details of the state to unwind to when a conflict occurs, and the cause of the unwind
+ # @attr [Integer] state_index the index of the state to unwind to
+ # @attr [Object] state_requirement the requirement of the state we're unwinding to
+ # @attr [Array] requirement_tree for the requirement we're relaxing
+ # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict
+ # @attr [Array] requirement_trees for the conflict
+ # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind
+ UnwindDetails = Struct.new(
+ :state_index,
+ :state_requirement,
+ :requirement_tree,
+ :conflicting_requirements,
+ :requirement_trees,
+ :requirements_unwound_to_instead
+ )
+
+ class UnwindDetails
+ include Comparable
+
+ # We compare UnwindDetails when choosing which state to unwind to. If
+ # two options have the same state_index we prefer the one most
+ # removed from a requirement that caused the conflict. Both options
+ # would unwind to the same state, but a `grandparent` option will
+ # filter out fewer of its possibilities after doing so - where a state
+ # is both a `parent` and a `grandparent` to requirements that have
+ # caused a conflict this is the correct behaviour.
+ # @param [UnwindDetail] other UnwindDetail to be compared
+ # @return [Integer] integer specifying ordering
+ def <=>(other)
+ if state_index > other.state_index
+ 1
+ elsif state_index == other.state_index
+ reversed_requirement_tree_index <=> other.reversed_requirement_tree_index
+ else
+ -1
+ end
+ end
+
+ # @return [Integer] index of state requirement in reversed requirement tree
+ # (the conflicting requirement itself will be at position 0)
+ def reversed_requirement_tree_index
+ @reversed_requirement_tree_index ||=
+ if state_requirement
+ requirement_tree.reverse.index(state_requirement)
+ else
+ 999_999
+ end
+ end
+
+ # @return [Boolean] where the requirement of the state we're unwinding
+ # to directly caused the conflict. Note: in this case, it is
+ # impossible for the state we're unwinding to to be a parent of
+ # any of the other conflicting requirements (or we would have
+ # circularity)
+ def unwinding_to_primary_requirement?
+ requirement_tree.last == state_requirement
+ end
+
+ # @return [Array] array of sub-dependencies to avoid when choosing a
+ # new possibility for the state we've unwound to. Only relevant for
+ # non-primary unwinds
+ def sub_dependencies_to_avoid
+ @requirements_to_avoid ||=
+ requirement_trees.map do |tree|
+ index = tree.index(state_requirement)
+ tree[index + 1] if index
+ end.compact
+ end
+
+ # @return [Array] array of all the requirements that led to the need for
+ # this unwind
+ def all_requirements
+ @all_requirements ||= requirement_trees.flatten(1)
+ end
+ end
+
+ # @return [SpecificationProvider] the provider that knows about
+ # dependencies, requirements, specifications, versions, etc.
+ attr_reader :specification_provider
+
+ # @return [UI] the UI that knows how to communicate feedback about the
+ # resolution process back to the user
+ attr_reader :resolver_ui
+
+ # @return [DependencyGraph] the base dependency graph to which
+ # dependencies should be 'locked'
+ attr_reader :base
+
+ # @return [Array] the dependencies that were explicitly required
+ attr_reader :original_requested
+
+ # Initializes a new resolution.
+ # @param [SpecificationProvider] specification_provider
+ # see {#specification_provider}
+ # @param [UI] resolver_ui see {#resolver_ui}
+ # @param [Array] requested see {#original_requested}
+ # @param [DependencyGraph] base see {#base}
+ def initialize(specification_provider, resolver_ui, requested, base)
+ @specification_provider = specification_provider
+ @resolver_ui = resolver_ui
+ @original_requested = requested
+ @base = base
+ @states = []
+ @iteration_counter = 0
+ @parents_of = Hash.new { |h, k| h[k] = [] }
+ end
+
+ # Resolves the {#original_requested} dependencies into a full dependency
+ # graph
+ # @raise [ResolverError] if successful resolution is impossible
+ # @return [DependencyGraph] the dependency graph of successfully resolved
+ # dependencies
+ def resolve
+ start_resolution
+
+ while state
+ break if !state.requirement && state.requirements.empty?
+ indicate_progress
+ if state.respond_to?(:pop_possibility_state) # DependencyState
+ debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
+ state.pop_possibility_state.tap do |s|
+ if s
+ states.push(s)
+ activated.tag(s)
+ end
+ end
+ end
+ process_topmost_state
+ end
+
+ resolve_activated_specs
+ ensure
+ end_resolution
+ end
+
+ # @return [Integer] the number of resolver iterations in between calls to
+ # {#resolver_ui}'s {UI#indicate_progress} method
+ attr_accessor :iteration_rate
+ private :iteration_rate
+
+ # @return [Time] the time at which resolution began
+ attr_accessor :started_at
+ private :started_at
+
+ # @return [Array<ResolutionState>] the stack of states for the resolution
+ attr_accessor :states
+ private :states
+
+ private
+
+ # Sets up the resolution process
+ # @return [void]
+ def start_resolution
+ @started_at = Time.now
+
+ push_initial_state
+
+ debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
+ resolver_ui.before_resolution
+ end
+
+ def resolve_activated_specs
+ activated.vertices.each do |_, vertex|
+ next unless vertex.payload
+
+ latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
+ vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
+ end
+
+ activated.set_payload(vertex.name, latest_version)
+ end
+ activated.freeze
+ end
+
+ # Ends the resolution process
+ # @return [void]
+ def end_resolution
+ resolver_ui.after_resolution
+ debug do
+ "Finished resolution (#{@iteration_counter} steps) " \
+ "(Took #{(ended_at = Time.now) - @started_at} seconds) (#{ended_at})"
+ end
+ debug { 'Unactivated: ' + Hash[activated.vertices.reject { |_n, v| v.payload }].keys.join(', ') } if state
+ debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
+ end
+
+ require_relative 'state'
+ require_relative 'modules/specification_provider'
+
+ require_relative 'delegates/resolution_state'
+ require_relative 'delegates/specification_provider'
+
+ include Gem::Resolver::Molinillo::Delegates::ResolutionState
+ include Gem::Resolver::Molinillo::Delegates::SpecificationProvider
+
+ # Processes the topmost available {RequirementState} on the stack
+ # @return [void]
+ def process_topmost_state
+ if possibility
+ attempt_to_activate
+ else
+ create_conflict
+ unwind_for_conflict
+ end
+ rescue CircularDependencyError => underlying_error
+ create_conflict(underlying_error)
+ unwind_for_conflict
+ end
+
+ # @return [Object] the current possibility that the resolution is trying
+ # to activate
+ def possibility
+ possibilities.last
+ end
+
+ # @return [RequirementState] the current state the resolution is
+ # operating upon
+ def state
+ states.last
+ end
+
+ # Creates and pushes the initial state for the resolution, based upon the
+ # {#requested} dependencies
+ # @return [void]
+ def push_initial_state
+ graph = DependencyGraph.new.tap do |dg|
+ original_requested.each do |requested|
+ vertex = dg.add_vertex(name_for(requested), nil, true)
+ vertex.explicit_requirements << requested
+ end
+ dg.tag(:initial_state)
+ end
+
+ push_state_for_requirements(original_requested, true, graph)
+ end
+
+ # Unwinds the states stack because a conflict has been encountered
+ # @return [void]
+ def unwind_for_conflict
+ details_for_unwind = build_details_for_unwind
+ unwind_options = unused_unwind_options
+ debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" }
+ conflicts.tap do |c|
+ sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1)
+ raise_error_unless_state(c)
+ activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
+ state.conflicts = c
+ state.unused_unwind_options = unwind_options
+ filter_possibilities_after_unwind(details_for_unwind)
+ index = states.size - 1
+ @parents_of.each { |_, a| a.reject! { |i| i >= index } }
+ state.unused_unwind_options.reject! { |uw| uw.state_index >= index }
+ end
+ end
+
+ # Raises a VersionConflict error, or any underlying error, if there is no
+ # current state
+ # @return [void]
+ def raise_error_unless_state(conflicts)
+ return if state
+
+ error = conflicts.values.map(&:underlying_error).compact.first
+ raise error || VersionConflict.new(conflicts, specification_provider)
+ end
+
+ # @return [UnwindDetails] Details of the nearest index to which we could unwind
+ def build_details_for_unwind
+ # Get the possible unwinds for the current conflict
+ current_conflict = conflicts[name]
+ binding_requirements = binding_requirements_for_conflict(current_conflict)
+ unwind_details = unwind_options_for_requirements(binding_requirements)
+
+ last_detail_for_current_unwind = unwind_details.sort.last
+ current_detail = last_detail_for_current_unwind
+
+ # Look for past conflicts that could be unwound to affect the
+ # requirement tree for the current conflict
+ all_reqs = last_detail_for_current_unwind.all_requirements
+ all_reqs_size = all_reqs.size
+ relevant_unused_unwinds = unused_unwind_options.select do |alternative|
+ diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
+ next if diff_reqs.size == all_reqs_size
+ # Find the highest index unwind whilst looping through
+ current_detail = alternative if alternative > current_detail
+ alternative
+ end
+
+ # Add the current unwind options to the `unused_unwind_options` array.
+ # The "used" option will be filtered out during `unwind_for_conflict`.
+ state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
+
+ # Update the requirements_unwound_to_instead on any relevant unused unwinds
+ relevant_unused_unwinds.each do |d|
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
+ end
+ unwind_details.each do |d|
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
+ end
+
+ current_detail
+ end
+
+ # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
+ # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
+ # of resolving the passed requirements
+ def unwind_options_for_requirements(binding_requirements)
+ unwind_details = []
+
+ trees = []
+ binding_requirements.reverse_each do |r|
+ partial_tree = [r]
+ trees << partial_tree
+ unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, [])
+
+ # If this requirement has alternative possibilities, check if any would
+ # satisfy the other requirements that created this conflict
+ requirement_state = find_state_for(r)
+ if conflict_fixing_possibilities?(requirement_state, binding_requirements)
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+
+ # Next, look at the parent of this requirement, and check if the requirement
+ # could have been avoided if an alternative PossibilitySet had been chosen
+ parent_r = parent_of(r)
+ next if parent_r.nil?
+ partial_tree.unshift(parent_r)
+ requirement_state = find_state_for(parent_r)
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) }
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ parent_r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+
+ # Finally, look at the grandparent and up of this requirement, looking
+ # for any possibilities that wouldn't create their parent requirement
+ grandparent_r = parent_of(parent_r)
+ until grandparent_r.nil?
+ partial_tree.unshift(grandparent_r)
+ requirement_state = find_state_for(grandparent_r)
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) }
+ unwind_details << UnwindDetails.new(
+ states.index(requirement_state),
+ grandparent_r,
+ partial_tree,
+ binding_requirements,
+ trees,
+ []
+ )
+ end
+ parent_r = grandparent_r
+ grandparent_r = parent_of(parent_r)
+ end
+ end
+
+ unwind_details
+ end
+
+ # @param [DependencyState] state
+ # @param [Array] binding_requirements array of requirements
+ # @return [Boolean] whether or not the given state has any possibilities
+ # that could satisfy the given requirements
+ def conflict_fixing_possibilities?(state, binding_requirements)
+ return false unless state
+
+ state.possibilities.any? do |possibility_set|
+ possibility_set.possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, binding_requirements)
+ end
+ end
+ end
+
+ # Filter's a state's possibilities to remove any that would not fix the
+ # conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just
+ # unwound from
+ # @return [void]
+ def filter_possibilities_after_unwind(unwind_details)
+ return unless state && !state.possibilities.empty?
+
+ if unwind_details.unwinding_to_primary_requirement?
+ filter_possibilities_for_primary_unwind(unwind_details)
+ else
+ filter_possibilities_for_parent_unwind(unwind_details)
+ end
+ end
+
+ # Filter's a state's possibilities to remove any that would not satisfy
+ # the requirements in the conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
+ # @return [void]
+ def filter_possibilities_for_primary_unwind(unwind_details)
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
+ unwinds_to_state << unwind_details
+ unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
+
+ state.possibilities.reject! do |possibility_set|
+ possibility_set.possibilities.none? do |poss|
+ unwind_requirement_sets.any? do |requirements|
+ possibility_satisfies_requirements?(poss, requirements)
+ end
+ end
+ end
+ end
+
+ # @param [Object] possibility a single possibility
+ # @param [Array] requirements an array of requirements
+ # @return [Boolean] whether the possibility satisfies all of the
+ # given requirements
+ def possibility_satisfies_requirements?(possibility, requirements)
+ name = name_for(possibility)
+
+ activated.tag(:swap)
+ activated.set_payload(name, possibility) if activated.vertex_named(name)
+ satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) }
+ activated.rewind_to(:swap)
+
+ satisfied
+ end
+
+ # Filter's a state's possibilities to remove any that would (eventually)
+ # create a requirement in the conflict we've just rewound from
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
+ # @return [void]
+ def filter_possibilities_for_parent_unwind(unwind_details)
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
+ unwinds_to_state << unwind_details
+
+ primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
+ parent_unwinds = unwinds_to_state.uniq - primary_unwinds
+
+ allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
+ states[unwind.state_index].possibilities.select do |possibility_set|
+ possibility_set.possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
+ end
+ end
+ end
+
+ requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
+
+ state.possibilities.reject! do |possibility_set|
+ !allowed_possibility_sets.include?(possibility_set) &&
+ (requirements_to_avoid - possibility_set.dependencies).empty?
+ end
+ end
+
+ # @param [Conflict] conflict
+ # @return [Array] minimal array of requirements that would cause the passed
+ # conflict to occur.
+ def binding_requirements_for_conflict(conflict)
+ return [conflict.requirement] if conflict.possibility.nil?
+
+ possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
+
+ # When there's a `CircularDependency` error the conflicting requirement
+ # (the one causing the circular) won't be `conflict.requirement`
+ # (which won't be for the right state, because we won't have created it,
+ # because it's circular).
+ # We need to make sure we have that requirement in the conflict's list,
+ # otherwise we won't be able to unwind properly, so we just return all
+ # the requirements for the conflict.
+ return possible_binding_requirements if conflict.underlying_error
+
+ possibilities = search_for(conflict.requirement)
+
+ # If all the requirements together don't filter out all possibilities,
+ # then the only two requirements we need to consider are the initial one
+ # (where the dependency's version was first chosen) and the last
+ if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities)
+ return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact
+ end
+
+ # Loop through the possible binding requirements, removing each one
+ # that doesn't bind. Use a `reverse_each` as we want the earliest set of
+ # binding requirements, and don't use `reject!` as we wish to refine the
+ # array *on each iteration*.
+ binding_requirements = possible_binding_requirements.dup
+ possible_binding_requirements.reverse_each do |req|
+ next if req == conflict.requirement
+ unless binding_requirement_in_set?(req, binding_requirements, possibilities)
+ binding_requirements -= [req]
+ end
+ end
+
+ binding_requirements
+ end
+
+ # @param [Object] requirement we wish to check
+ # @param [Array] possible_binding_requirements array of requirements
+ # @param [Array] possibilities array of possibilities the requirements will be used to filter
+ # @return [Boolean] whether or not the given requirement is required to filter
+ # out all elements of the array of possibilities.
+ def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
+ possibilities.any? do |poss|
+ possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement])
+ end
+ end
+
+ # @param [Object] requirement
+ # @return [Object] the requirement that led to `requirement` being added
+ # to the list of requirements.
+ def parent_of(requirement)
+ return unless requirement
+ return unless index = @parents_of[requirement].last
+ return unless parent_state = @states[index]
+ parent_state.requirement
+ end
+
+ # @param [String] name
+ # @return [Object] the requirement that led to a version of a possibility
+ # with the given name being activated.
+ def requirement_for_existing_name(name)
+ return nil unless vertex = activated.vertex_named(name)
+ return nil unless vertex.payload
+ states.find { |s| s.name == name }.requirement
+ end
+
+ # @param [Object] requirement
+ # @return [ResolutionState] the state whose `requirement` is the given
+ # `requirement`.
+ def find_state_for(requirement)
+ return nil unless requirement
+ states.find { |i| requirement == i.requirement }
+ end
+
+ # @param [Object] underlying_error
+ # @return [Conflict] a {Conflict} that reflects the failure to activate
+ # the {#possibility} in conjunction with the current {#state}
+ def create_conflict(underlying_error = nil)
+ vertex = activated.vertex_named(name)
+ locked_requirement = locked_requirement_named(name)
+
+ requirements = {}
+ unless vertex.explicit_requirements.empty?
+ requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
+ end
+ requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
+ vertex.incoming_edges.each do |edge|
+ (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement)
+ end
+
+ activated_by_name = {}
+ activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload }
+ conflicts[name] = Conflict.new(
+ requirement,
+ requirements,
+ vertex.payload && vertex.payload.latest_version,
+ possibility,
+ locked_requirement,
+ requirement_trees,
+ activated_by_name,
+ underlying_error
+ )
+ end
+
+ # @return [Array<Array<Object>>] The different requirement
+ # trees that led to every requirement for the current spec.
+ def requirement_trees
+ vertex = activated.vertex_named(name)
+ vertex.requirements.map { |r| requirement_tree_for(r) }
+ end
+
+ # @param [Object] requirement
+ # @return [Array<Object>] the list of requirements that led to
+ # `requirement` being required.
+ def requirement_tree_for(requirement)
+ tree = []
+ while requirement
+ tree.unshift(requirement)
+ requirement = parent_of(requirement)
+ end
+ tree
+ end
+
+ # Indicates progress roughly once every second
+ # @return [void]
+ def indicate_progress
+ @iteration_counter += 1
+ @progress_rate ||= resolver_ui.progress_rate
+ if iteration_rate.nil?
+ if Time.now - started_at >= @progress_rate
+ self.iteration_rate = @iteration_counter
+ end
+ end
+
+ if iteration_rate && (@iteration_counter % iteration_rate) == 0
+ resolver_ui.indicate_progress
+ end
+ end
+
+ # Calls the {#resolver_ui}'s {UI#debug} method
+ # @param [Integer] depth the depth of the {#states} stack
+ # @param [Proc] block a block that yields a {#to_s}
+ # @return [void]
+ def debug(depth = 0, &block)
+ resolver_ui.debug(depth, &block)
+ end
+
+ # Attempts to activate the current {#possibility}
+ # @return [void]
+ def attempt_to_activate
+ debug(depth) { 'Attempting to activate ' + possibility.to_s }
+ existing_vertex = activated.vertex_named(name)
+ if existing_vertex.payload
+ debug(depth) { "Found existing spec (#{existing_vertex.payload})" }
+ attempt_to_filter_existing_spec(existing_vertex)
+ else
+ latest = possibility.latest_version
+ possibility.possibilities.select! do |possibility|
+ requirement_satisfied_by?(requirement, activated, possibility)
+ end
+ if possibility.latest_version.nil?
+ # ensure there's a possibility for better error messages
+ possibility.possibilities << latest if latest
+ create_conflict
+ unwind_for_conflict
+ else
+ activate_new_spec
+ end
+ end
+ end
+
+ # Attempts to update the existing vertex's `PossibilitySet` with a filtered version
+ # @return [void]
+ def attempt_to_filter_existing_spec(vertex)
+ filtered_set = filtered_possibility_set(vertex)
+ if !filtered_set.possibilities.empty?
+ activated.set_payload(name, filtered_set)
+ new_requirements = requirements.dup
+ push_state_for_requirements(new_requirements, false)
+ else
+ create_conflict
+ debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" }
+ unwind_for_conflict
+ end
+ end
+
+ # Generates a filtered version of the existing vertex's `PossibilitySet` using the
+ # current state's `requirement`
+ # @param [Object] vertex existing vertex
+ # @return [PossibilitySet] filtered possibility set
+ def filtered_possibility_set(vertex)
+ PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
+ end
+
+ # @param [String] requirement_name the spec name to search for
+ # @return [Object] the locked spec named `requirement_name`, if one
+ # is found on {#base}
+ def locked_requirement_named(requirement_name)
+ vertex = base.vertex_named(requirement_name)
+ vertex && vertex.payload
+ end
+
+ # Add the current {#possibility} to the dependency graph of the current
+ # {#state}
+ # @return [void]
+ def activate_new_spec
+ conflicts.delete(name)
+ debug(depth) { "Activated #{name} at #{possibility}" }
+ activated.set_payload(name, possibility)
+ require_nested_dependencies_for(possibility)
+ end
+
+ # Requires the dependencies that the recently activated spec has
+ # @param [Object] possibility_set the PossibilitySet that has just been
+ # activated
+ # @return [void]
+ def require_nested_dependencies_for(possibility_set)
+ nested_dependencies = dependencies_for(possibility_set.latest_version)
+ debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
+ nested_dependencies.each do |d|
+ activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d)
+ parent_index = states.size - 1
+ parents = @parents_of[d]
+ parents << parent_index if parents.empty?
+ end
+
+ push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?)
+ end
+
+ # Pushes a new {DependencyState} that encapsulates both existing and new
+ # requirements
+ # @param [Array] new_requirements
+ # @param [Boolean] requires_sort
+ # @param [Object] new_activated
+ # @return [void]
+ def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
+ new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
+ new_requirement = nil
+ loop do
+ new_requirement = new_requirements.shift
+ break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement }
+ end
+ new_name = new_requirement ? name_for(new_requirement) : ''.freeze
+ possibilities = possibilities_for_requirement(new_requirement)
+ handle_missing_or_push_dependency_state DependencyState.new(
+ new_name, new_requirements, new_activated,
+ new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup
+ )
+ end
+
+ # Checks a proposed requirement with any existing locked requirement
+ # before generating an array of possibilities for it.
+ # @param [Object] requirement the proposed requirement
+ # @param [Object] activated
+ # @return [Array] possibilities
+ def possibilities_for_requirement(requirement, activated = self.activated)
+ return [] unless requirement
+ if locked_requirement_named(name_for(requirement))
+ return locked_requirement_possibility_set(requirement, activated)
+ end
+
+ group_possibilities(search_for(requirement))
+ end
+
+ # @param [Object] requirement the proposed requirement
+ # @param [Object] activated
+ # @return [Array] possibility set containing only the locked requirement, if any
+ def locked_requirement_possibility_set(requirement, activated = self.activated)
+ all_possibilities = search_for(requirement)
+ locked_requirement = locked_requirement_named(name_for(requirement))
+
+ # Longwinded way to build a possibilities array with either the locked
+ # requirement or nothing in it. Required, since the API for
+ # locked_requirement isn't guaranteed.
+ locked_possibilities = all_possibilities.select do |possibility|
+ requirement_satisfied_by?(locked_requirement, activated, possibility)
+ end
+
+ group_possibilities(locked_possibilities)
+ end
+
+ # Build an array of PossibilitySets, with each element representing a group of
+ # dependency versions that all have the same sub-dependency version constraints
+ # and are contiguous.
+ # @param [Array] possibilities an array of possibilities
+ # @return [Array<PossibilitySet>] an array of possibility sets
+ def group_possibilities(possibilities)
+ possibility_sets = []
+ current_possibility_set = nil
+
+ possibilities.reverse_each do |possibility|
+ dependencies = dependencies_for(possibility)
+ if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
+ current_possibility_set.possibilities.unshift(possibility)
+ else
+ possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
+ current_possibility_set = possibility_sets.first
+ end
+ end
+
+ possibility_sets
+ end
+
+ # Pushes a new {DependencyState}.
+ # If the {#specification_provider} says to
+ # {SpecificationProvider#allow_missing?} that particular requirement, and
+ # there are no possibilities for that requirement, then `state` is not
+ # pushed, and the vertex in {#activated} is removed, and we continue
+ # resolving the remaining requirements.
+ # @param [DependencyState] state
+ # @return [void]
+ def handle_missing_or_push_dependency_state(state)
+ if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement)
+ state.activated.detach_vertex_named(state.name)
+ push_state_for_requirements(state.requirements.dup, false, state.activated)
+ else
+ states.push(state).tap { activated.tag(state) }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb
new file mode 100644
index 0000000000..d43121f8ca
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require_relative 'dependency_graph'
+
+module Gem::Resolver::Molinillo
+ # This class encapsulates a dependency resolver.
+ # The resolver is responsible for determining which set of dependencies to
+ # activate, with feedback from the {#specification_provider}
+ #
+ #
+ class Resolver
+ require_relative 'resolution'
+
+ # @return [SpecificationProvider] the specification provider used
+ # in the resolution process
+ attr_reader :specification_provider
+
+ # @return [UI] the UI module used to communicate back to the user
+ # during the resolution process
+ attr_reader :resolver_ui
+
+ # Initializes a new resolver.
+ # @param [SpecificationProvider] specification_provider
+ # see {#specification_provider}
+ # @param [UI] resolver_ui
+ # see {#resolver_ui}
+ def initialize(specification_provider, resolver_ui)
+ @specification_provider = specification_provider
+ @resolver_ui = resolver_ui
+ end
+
+ # Resolves the requested dependencies into a {DependencyGraph},
+ # locking to the base dependency graph (if specified)
+ # @param [Array] requested an array of 'requested' dependencies that the
+ # {#specification_provider} can understand
+ # @param [DependencyGraph,nil] base the base dependency graph to which
+ # dependencies should be 'locked'
+ def resolve(requested, base = DependencyGraph.new)
+ Resolution.new(specification_provider,
+ resolver_ui,
+ requested,
+ base).
+ resolve
+ end
+ end
+end
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb
new file mode 100644
index 0000000000..6e7c715fce
--- /dev/null
+++ b/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Gem::Resolver::Molinillo
+ # A state that a {Resolution} can be in
+ # @attr [String] name the name of the current requirement
+ # @attr [Array<Object>] requirements currently unsatisfied requirements
+ # @attr [DependencyGraph] activated the graph of activated dependencies
+ # @attr [Object] requirement the current requirement
+ # @attr [Object] possibilities the possibilities to satisfy the current requirement
+ # @attr [Integer] depth the depth of the resolution
+ # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
+ # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
+ ResolutionState = Struct.new(
+ :name,
+ :requirements,
+ :activated,
+ :requirement,
+ :possibilities,
+ :depth,
+ :conflicts,
+ :unused_unwind_options
+ )
+
+ class ResolutionState
+ # Returns an empty resolution state
+ # @return [ResolutionState] an empty state
+ def self.empty
+ new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
+ end
+ end
+
+ # A state that encapsulates a set of {#requirements} with an {Array} of
+ # possibilities
+ class DependencyState < ResolutionState
+ # Removes a possibility from `self`
+ # @return [PossibilityState] a state with a single possibility,
+ # the possibility that was removed from `self`
+ def pop_possibility_state
+ PossibilityState.new(
+ name,
+ requirements.dup,
+ activated,
+ requirement,
+ [possibilities.pop],
+ depth + 1,
+ conflicts.dup,
+ unused_unwind_options.dup
+ ).tap do |state|
+ state.activated.tag(state)
+ end
+ end
+ end
+
+ # A state that encapsulates a single possibility to fulfill the given
+ # {#requirement}
+ class PossibilityState < ResolutionState
+ end
+end
diff --git a/lib/rubygems/resolver/spec_specification.rb b/lib/rubygems/resolver/spec_specification.rb
index 00ef9fdba0..79a34d8063 100644
--- a/lib/rubygems/resolver/spec_specification.rb
+++ b/lib/rubygems/resolver/spec_specification.rb
@@ -66,11 +66,4 @@ class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
def version
spec.version
end
-
- ##
- # The hash value for this specification.
-
- def hash
- spec.hash
- end
end
diff --git a/lib/rubygems/s3_uri_signer.rb b/lib/rubygems/s3_uri_signer.rb
index 7c95a9d4f5..5161e43ebb 100644
--- a/lib/rubygems/s3_uri_signer.rb
+++ b/lib/rubygems/s3_uri_signer.rb
@@ -12,7 +12,7 @@ class Gem::S3URISigner
end
def to_s # :nodoc:
- super.to_s
+ "#{super}"
end
end
@@ -22,7 +22,7 @@ class Gem::S3URISigner
end
def to_s # :nodoc:
- super.to_s
+ "#{super}"
end
end
@@ -34,7 +34,7 @@ class Gem::S3URISigner
##
# Signs S3 URI using query-params according to the reference: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
- def sign(expiration = 86_400)
+ def sign(expiration = 86400)
s3_config = fetch_s3_config
current_time = Time.now.utc
@@ -49,7 +49,7 @@ class Gem::S3URISigner
string_to_sign = generate_string_to_sign(date_time, credential_info, canonical_request)
signature = generate_signature(s3_config, date, string_to_sign)
- Gem::URI.parse("https://#{canonical_host}#{uri.path}?#{query_params}&X-Amz-Signature=#{signature}")
+ URI.parse("https://#{canonical_host}#{uri.path}?#{query_params}&X-Amz-Signature=#{signature}")
end
private
@@ -136,11 +136,11 @@ class Gem::S3URISigner
end
def base64_uri_escape(str)
- str.gsub(%r{[\+/=\n]}, BASE64_URI_TRANSLATE)
+ str.gsub(/[\+\/=\n]/, BASE64_URI_TRANSLATE)
end
def ec2_metadata_credentials_json
- require_relative "vendored_net_http"
+ require "net/http"
require_relative "request"
require_relative "request/connection_pools"
require "json"
@@ -152,13 +152,13 @@ class Gem::S3URISigner
end
def ec2_metadata_request(url)
- uri = Gem::URI(url)
+ uri = URI(url)
@request_pool ||= create_request_pool(uri)
- request = Gem::Request.new(uri, Gem::Net::HTTP::Get, nil, @request_pool)
+ request = Gem::Request.new(uri, Net::HTTP::Get, nil, @request_pool)
response = request.fetch
case response
- when Gem::Net::HTTPOK then
+ when Net::HTTPOK then
JSON.parse(response.body)
else
raise InstanceProfileError.new("Unable to fetch AWS metadata from #{uri}: #{response.message} #{response.code}")
diff --git a/lib/rubygems/safe_marshal.rb b/lib/rubygems/safe_marshal.rb
deleted file mode 100644
index b81d1a0a47..0000000000
--- a/lib/rubygems/safe_marshal.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require "stringio"
-
-require_relative "safe_marshal/reader"
-require_relative "safe_marshal/visitors/to_ruby"
-
-module Gem
- ###
- # This module is used for safely loading Marshal specs from a gem. The
- # `safe_load` method defined on this module is specifically designed for
- # loading Gem specifications.
-
- module SafeMarshal
- PERMITTED_CLASSES = %w[
- Date
- Time
- Rational
-
- Gem::Dependency
- Gem::NameTuple
- Gem::Platform
- Gem::Requirement
- Gem::Specification
- Gem::Version
- Gem::Version::Requirement
-
- YAML::Syck::DefaultKey
- YAML::PrivateType
- ].freeze
- private_constant :PERMITTED_CLASSES
-
- PERMITTED_SYMBOLS = %w[
- development
- runtime
-
- name
- number
- platform
- dependencies
- ].freeze
- private_constant :PERMITTED_SYMBOLS
-
- PERMITTED_IVARS = {
- "String" => %w[E encoding @taguri @debug_created_info],
- "Time" => %w[
- offset zone nano_num nano_den submicro
- @_zone @marshal_with_utc_coercion
- ],
- "Gem::Dependency" => %w[
- @name @requirement @prerelease @version_requirement @version_requirements @type
- @force_ruby_platform
- ],
- "Gem::NameTuple" => %w[@name @version @platform],
- "Gem::Platform" => %w[@os @cpu @version],
- "Psych::PrivateType" => %w[@value @type_id],
- }.freeze
- private_constant :PERMITTED_IVARS
-
- def self.safe_load(input)
- load(input, permitted_classes: PERMITTED_CLASSES, permitted_symbols: PERMITTED_SYMBOLS, permitted_ivars: PERMITTED_IVARS)
- end
-
- def self.load(input, permitted_classes: [::Symbol], permitted_symbols: [], permitted_ivars: {})
- root = Reader.new(StringIO.new(input, "r").binmode).read!
-
- Visitors::ToRuby.new(
- permitted_classes: permitted_classes,
- permitted_symbols: permitted_symbols,
- permitted_ivars: permitted_ivars,
- ).visit(root)
- end
- end
-end
diff --git a/lib/rubygems/safe_marshal/elements.rb b/lib/rubygems/safe_marshal/elements.rb
deleted file mode 100644
index f8874b1b2f..0000000000
--- a/lib/rubygems/safe_marshal/elements.rb
+++ /dev/null
@@ -1,146 +0,0 @@
-# frozen_string_literal: true
-
-module Gem
- module SafeMarshal
- module Elements
- class Element
- end
-
- class Symbol < Element
- def initialize(name)
- @name = name
- end
- attr_reader :name
- end
-
- class UserDefined < Element
- def initialize(name, binary_string)
- @name = name
- @binary_string = binary_string
- end
-
- attr_reader :name, :binary_string
- end
-
- class UserMarshal < Element
- def initialize(name, data)
- @name = name
- @data = data
- end
-
- attr_reader :name, :data
- end
-
- class String < Element
- def initialize(str)
- @str = str
- end
-
- attr_reader :str
- end
-
- class Hash < Element
- def initialize(pairs)
- @pairs = pairs
- end
-
- attr_reader :pairs
- end
-
- class HashWithDefaultValue < Hash
- def initialize(pairs, default)
- super(pairs)
- @default = default
- end
-
- attr_reader :default
- end
-
- class Array < Element
- def initialize(elements)
- @elements = elements
- end
-
- attr_reader :elements
- end
-
- class Integer < Element
- def initialize(int)
- @int = int
- end
-
- attr_reader :int
- end
-
- class True < Element
- def initialize
- end
- TRUE = new.freeze
- end
-
- class False < Element
- def initialize
- end
-
- FALSE = new.freeze
- end
-
- class WithIvars < Element
- def initialize(object, ivars)
- @object = object
- @ivars = ivars
- end
-
- attr_reader :object, :ivars
- end
-
- class Object < Element
- def initialize(name)
- @name = name
- end
- attr_reader :name
- end
-
- class Nil < Element
- NIL = new.freeze
- end
-
- class ObjectLink < Element
- def initialize(offset)
- @offset = offset
- end
- attr_reader :offset
- end
-
- class SymbolLink < Element
- def initialize(offset)
- @offset = offset
- end
- attr_reader :offset
- end
-
- class Float < Element
- def initialize(string)
- @string = string
- end
- attr_reader :string
- end
-
- class Bignum < Element # rubocop:disable Lint/UnifiedInteger
- def initialize(sign, data)
- @sign = sign
- @data = data
- end
- attr_reader :sign, :data
- end
-
- class UserClass < Element
- def initialize(name, wrapped_object)
- @name = name
- @wrapped_object = wrapped_object
- end
- attr_reader :name, :wrapped_object
- end
- end
- end
-end
diff --git a/lib/rubygems/safe_marshal/reader.rb b/lib/rubygems/safe_marshal/reader.rb
deleted file mode 100644
index 740be113e5..0000000000
--- a/lib/rubygems/safe_marshal/reader.rb
+++ /dev/null
@@ -1,308 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "elements"
-
-module Gem
- module SafeMarshal
- class Reader
- class Error < StandardError
- end
-
- class UnsupportedVersionError < Error
- end
-
- class UnconsumedBytesError < Error
- end
-
- class NotImplementedError < Error
- end
-
- class EOFError < Error
- end
-
- def initialize(io)
- @io = io
- end
-
- def read!
- read_header
- root = read_element
- raise UnconsumedBytesError unless @io.eof?
- root
- end
-
- private
-
- MARSHAL_VERSION = [Marshal::MAJOR_VERSION, Marshal::MINOR_VERSION].map(&:chr).join.freeze
- private_constant :MARSHAL_VERSION
-
- def read_header
- v = @io.read(2)
- raise UnsupportedVersionError, "Unsupported marshal version #{v.bytes.map(&:ord).join(".")}, expected #{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" unless v == MARSHAL_VERSION
- end
-
- def read_byte
- @io.getbyte
- end
-
- def read_integer
- b = read_byte
-
- case b
- when 0x00
- 0
- when 0x01
- read_byte
- when 0x02
- read_byte | (read_byte << 8)
- when 0x03
- read_byte | (read_byte << 8) | (read_byte << 16)
- when 0x04
- read_byte | (read_byte << 8) | (read_byte << 16) | (read_byte << 24)
- when 0xFC
- read_byte | (read_byte << 8) | (read_byte << 16) | (read_byte << 24) | -0x100000000
- when 0xFD
- read_byte | (read_byte << 8) | (read_byte << 16) | -0x1000000
- when 0xFE
- read_byte | (read_byte << 8) | -0x10000
- when 0xFF
- read_byte | -0x100
- when nil
- raise EOFError, "Unexpected EOF"
- else
- signed = (b ^ 128) - 128
- if b >= 128
- signed + 5
- else
- signed - 5
- end
- end
- end
-
- def read_element
- type = read_byte
- case type
- when 34 then read_string # ?"
- when 48 then read_nil # ?0
- when 58 then read_symbol # ?:
- when 59 then read_symbol_link # ?;
- when 64 then read_object_link # ?@
- when 70 then read_false # ?F
- when 73 then read_object_with_ivars # ?I
- when 84 then read_true # ?T
- when 85 then read_user_marshal # ?U
- when 91 then read_array # ?[
- when 102 then read_float # ?f
- when 105 then Elements::Integer.new(read_integer) # ?i
- when 108 then read_bignum # ?l
- when 111 then read_object # ?o
- when 117 then read_user_defined # ?u
- when 123 then read_hash # ?{
- when 125 then read_hash_with_default_value # ?}
- when 101 then read_extended_object # ?e
- when 99 then read_class # ?c
- when 109 then read_module # ?m
- when 77 then read_class_or_module # ?M
- when 100 then read_data # ?d
- when 47 then read_regexp # ?/
- when 83 then read_struct # ?S
- when 67 then read_user_class # ?C
- when nil
- raise EOFError, "Unexpected EOF"
- else
- raise Error, "Unknown marshal type discriminator #{type.chr.inspect} (#{type})"
- end
- end
-
- STRING_E_SYMBOL = Elements::Symbol.new("E").freeze
- private_constant :STRING_E_SYMBOL
-
- def read_symbol
- len = read_integer
- if len == 1
- byte = read_byte
- if byte == 69 # ?E
- STRING_E_SYMBOL
- else
- Elements::Symbol.new(byte.chr)
- end
- else
- name = -@io.read(len)
- Elements::Symbol.new(name)
- end
- end
-
- EMPTY_STRING = Elements::String.new("".b.freeze).freeze
- private_constant :EMPTY_STRING
-
- def read_string
- length = read_integer
- return EMPTY_STRING if length == 0
- str = @io.read(length)
- Elements::String.new(str)
- end
-
- def read_true
- Elements::True::TRUE
- end
-
- def read_false
- Elements::False::FALSE
- end
-
- def read_user_defined
- name = read_element
- binary_string = @io.read(read_integer)
- Elements::UserDefined.new(name, binary_string)
- end
-
- EMPTY_ARRAY = Elements::Array.new([].freeze).freeze
- private_constant :EMPTY_ARRAY
-
- def read_array
- length = read_integer
- return EMPTY_ARRAY if length == 0
- elements = Array.new(length) do
- read_element
- end
- Elements::Array.new(elements)
- end
-
- def read_object_with_ivars
- object = read_element
- ivars = Array.new(read_integer) do
- [read_element, read_element]
- end
- Elements::WithIvars.new(object, ivars)
- end
-
- def read_symbol_link
- offset = read_integer
- Elements::SymbolLink.new(offset)
- end
-
- def read_user_marshal
- name = read_element
- data = read_element
- Elements::UserMarshal.new(name, data)
- end
-
- # profiling bundle install --full-index shows that
- # offset 6 is by far the most common object link,
- # so we special case it to avoid allocating a new
- # object a third of the time.
- # the following are all the object links that
- # appear more than 10000 times in my profiling
-
- OBJECT_LINKS = {
- 6 => Elements::ObjectLink.new(6).freeze,
- 30 => Elements::ObjectLink.new(30).freeze,
- 81 => Elements::ObjectLink.new(81).freeze,
- 34 => Elements::ObjectLink.new(34).freeze,
- 38 => Elements::ObjectLink.new(38).freeze,
- 50 => Elements::ObjectLink.new(50).freeze,
- 91 => Elements::ObjectLink.new(91).freeze,
- 42 => Elements::ObjectLink.new(42).freeze,
- 46 => Elements::ObjectLink.new(46).freeze,
- 150 => Elements::ObjectLink.new(150).freeze,
- 100 => Elements::ObjectLink.new(100).freeze,
- 104 => Elements::ObjectLink.new(104).freeze,
- 108 => Elements::ObjectLink.new(108).freeze,
- 242 => Elements::ObjectLink.new(242).freeze,
- 246 => Elements::ObjectLink.new(246).freeze,
- 139 => Elements::ObjectLink.new(139).freeze,
- 143 => Elements::ObjectLink.new(143).freeze,
- 114 => Elements::ObjectLink.new(114).freeze,
- 308 => Elements::ObjectLink.new(308).freeze,
- 200 => Elements::ObjectLink.new(200).freeze,
- 54 => Elements::ObjectLink.new(54).freeze,
- 62 => Elements::ObjectLink.new(62).freeze,
- 1_286_245 => Elements::ObjectLink.new(1_286_245).freeze,
- }.freeze
- private_constant :OBJECT_LINKS
-
- def read_object_link
- offset = read_integer
- OBJECT_LINKS[offset] || Elements::ObjectLink.new(offset)
- end
-
- EMPTY_HASH = Elements::Hash.new([].freeze).freeze
- private_constant :EMPTY_HASH
-
- def read_hash
- length = read_integer
- return EMPTY_HASH if length == 0
- pairs = Array.new(length) do
- [read_element, read_element]
- end
- Elements::Hash.new(pairs)
- end
-
- def read_hash_with_default_value
- pairs = Array.new(read_integer) do
- [read_element, read_element]
- end
- default = read_element
- Elements::HashWithDefaultValue.new(pairs, default)
- end
-
- def read_object
- name = read_element
- object = Elements::Object.new(name)
- ivars = Array.new(read_integer) do
- [read_element, read_element]
- end
- Elements::WithIvars.new(object, ivars)
- end
-
- def read_nil
- Elements::Nil::NIL
- end
-
- def read_float
- string = @io.read(read_integer)
- Elements::Float.new(string)
- end
-
- def read_bignum
- sign = read_byte
- data = @io.read(read_integer * 2)
- Elements::Bignum.new(sign, data)
- end
-
- def read_extended_object
- raise NotImplementedError, "Reading Marshal objects of type extended_object is not implemented"
- end
-
- def read_class
- raise NotImplementedError, "Reading Marshal objects of type class is not implemented"
- end
-
- def read_module
- raise NotImplementedError, "Reading Marshal objects of type module is not implemented"
- end
-
- def read_class_or_module
- raise NotImplementedError, "Reading Marshal objects of type class_or_module is not implemented"
- end
-
- def read_data
- raise NotImplementedError, "Reading Marshal objects of type data is not implemented"
- end
-
- def read_regexp
- raise NotImplementedError, "Reading Marshal objects of type regexp is not implemented"
- end
-
- def read_struct
- raise NotImplementedError, "Reading Marshal objects of type struct is not implemented"
- end
-
- def read_user_class
- name = read_element
- wrapped_object = read_element
- Elements::UserClass.new(name, wrapped_object)
- end
- end
- end
-end
diff --git a/lib/rubygems/safe_marshal/visitors/stream_printer.rb b/lib/rubygems/safe_marshal/visitors/stream_printer.rb
deleted file mode 100644
index 162b36ad05..0000000000
--- a/lib/rubygems/safe_marshal/visitors/stream_printer.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "visitor"
-
-module Gem::SafeMarshal
- module Visitors
- class StreamPrinter < Visitor
- def initialize(io, indent: "")
- @io = io
- @indent = indent
- @level = 0
- end
-
- def visit(target)
- @io.write("#{@indent * @level}#{target.class}")
- target.instance_variables.each do |ivar|
- value = target.instance_variable_get(ivar)
- next if Elements::Element === value || Array === value
- @io.write(" #{ivar}=#{value.inspect}")
- end
- @io.write("\n")
- begin
- @level += 1
- super
- ensure
- @level -= 1
- end
- end
- end
- end
-end
diff --git a/lib/rubygems/safe_marshal/visitors/to_ruby.rb b/lib/rubygems/safe_marshal/visitors/to_ruby.rb
deleted file mode 100644
index a9f1d048d4..0000000000
--- a/lib/rubygems/safe_marshal/visitors/to_ruby.rb
+++ /dev/null
@@ -1,415 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "visitor"
-
-module Gem::SafeMarshal
- module Visitors
- class ToRuby < Visitor
- def initialize(permitted_classes:, permitted_symbols:, permitted_ivars:)
- @permitted_classes = permitted_classes
- @permitted_symbols = ["E"].concat(permitted_symbols).concat(permitted_classes)
- @permitted_ivars = permitted_ivars
-
- @objects = []
- @symbols = []
- @class_cache = {}
-
- @stack = ["root"]
- @stack_idx = 1
- end
-
- def inspect # :nodoc:
- format("#<%s permitted_classes: %p permitted_symbols: %p permitted_ivars: %p>",
- self.class, @permitted_classes, @permitted_symbols, @permitted_ivars)
- end
-
- def visit(target)
- stack_idx = @stack_idx
- super
- ensure
- @stack_idx = stack_idx - 1
- end
-
- private
-
- def push_stack(element)
- @stack[@stack_idx] = element
- @stack_idx += 1
- end
-
- def visit_Gem_SafeMarshal_Elements_Array(a)
- array = register_object([])
-
- elements = a.elements
- size = elements.size
- idx = 0
- # not idiomatic, but there's a huge number of IMEMOs allocated here, so we avoid the block
- # because this is such a hot path when doing a bundle install with the full index
- until idx == size
- push_stack idx
- array << visit(elements[idx])
- idx += 1
- end
-
- array
- end
-
- def visit_Gem_SafeMarshal_Elements_Symbol(s)
- name = s.name
- raise UnpermittedSymbolError.new(symbol: name, stack: formatted_stack) unless @permitted_symbols.include?(name)
- visit_symbol_type(s)
- end
-
- def map_ivars(klass, ivars)
- stack_idx = @stack_idx
- ivars.map.with_index do |(k, v), i|
- @stack_idx = stack_idx
-
- push_stack "ivar_"
- push_stack i
- k = resolve_ivar(klass, k)
-
- @stack_idx = stack_idx
- push_stack k
-
- next k, visit(v)
- end
- end
-
- def visit_Gem_SafeMarshal_Elements_WithIvars(e)
- object_offset = @objects.size
- push_stack "object"
- object = visit(e.object)
- ivars = map_ivars(object.class, e.ivars)
-
- case e.object
- when Elements::UserDefined
- if object.class == ::Time
- internal = []
-
- ivars.reject! do |k, v|
- case k
- when :offset, :zone, :nano_num, :nano_den, :submicro
- internal << [k, v]
- true
- else
- false
- end
- end
-
- s = e.object.binary_string
-
- marshal_string = "\x04\bIu:\tTime".b
- marshal_string.concat(s.size + 5)
- marshal_string << s
- marshal_string.concat(internal.size + 5)
-
- internal.each do |k, v|
- marshal_string.concat(":")
- marshal_string.concat(k.size + 5)
- marshal_string.concat(k.to_s)
- dumped = Marshal.dump(v)
- dumped[0, 2] = ""
- marshal_string.concat(dumped)
- end
-
- object = @objects[object_offset] = Marshal.load(marshal_string)
- end
- when Elements::String
- enc = nil
-
- ivars.reject! do |k, v|
- case k
- when :E
- case v
- when TrueClass
- enc = "UTF-8"
- when FalseClass
- enc = "US-ASCII"
- else
- raise FormatError, "Unexpected value for String :E #{v.inspect}"
- end
- when :encoding
- enc = v
- else
- next false
- end
- true
- end
-
- object.force_encoding(enc) if enc
- end
-
- ivars.each do |k, v|
- object.instance_variable_set k, v
- end
- object
- end
-
- def visit_Gem_SafeMarshal_Elements_Hash(o)
- hash = register_object({})
-
- o.pairs.each_with_index do |(k, v), i|
- push_stack i
- k = visit(k)
- push_stack k
- hash[k] = visit(v)
- end
-
- hash
- end
-
- def visit_Gem_SafeMarshal_Elements_HashWithDefaultValue(o)
- hash = visit_Gem_SafeMarshal_Elements_Hash(o)
- push_stack :default
- hash.default = visit(o.default)
- hash
- end
-
- def visit_Gem_SafeMarshal_Elements_Object(o)
- register_object(resolve_class(o.name).allocate)
- end
-
- def visit_Gem_SafeMarshal_Elements_ObjectLink(o)
- @objects[o.offset]
- end
-
- def visit_Gem_SafeMarshal_Elements_SymbolLink(o)
- @symbols[o.offset]
- end
-
- def visit_Gem_SafeMarshal_Elements_UserDefined(o)
- register_object(call_method(resolve_class(o.name), :_load, o.binary_string))
- end
-
- def visit_Gem_SafeMarshal_Elements_UserMarshal(o)
- klass = resolve_class(o.name)
- compat = COMPAT_CLASSES.fetch(klass, nil)
- idx = @objects.size
- object = register_object(call_method(compat || klass, :allocate))
-
- push_stack :data
- ret = call_method(object, :marshal_load, visit(o.data))
-
- if compat
- object = @objects[idx] = ret
- end
-
- object
- end
-
- def visit_Gem_SafeMarshal_Elements_Integer(i)
- i.int
- end
-
- def visit_Gem_SafeMarshal_Elements_Nil(_)
- nil
- end
-
- def visit_Gem_SafeMarshal_Elements_True(_)
- true
- end
-
- def visit_Gem_SafeMarshal_Elements_False(_)
- false
- end
-
- def visit_Gem_SafeMarshal_Elements_String(s)
- register_object(+s.str)
- end
-
- def visit_Gem_SafeMarshal_Elements_Float(f)
- case f.string
- when "inf"
- ::Float::INFINITY
- when "-inf"
- -::Float::INFINITY
- when "nan"
- ::Float::NAN
- else
- f.string.to_f
- end
- end
-
- def visit_Gem_SafeMarshal_Elements_Bignum(b)
- result = 0
- b.data.each_byte.with_index do |byte, exp|
- result += (byte * 2**(exp * 8))
- end
-
- case b.sign
- when 43 # ?+
- result
- when 45 # ?-
- -result
- else
- raise FormatError, "Unexpected sign for Bignum #{b.sign.chr.inspect} (#{b.sign})"
- end
- end
-
- def visit_Gem_SafeMarshal_Elements_UserClass(r)
- if resolve_class(r.name) == ::Hash && r.wrapped_object.is_a?(Elements::Hash)
-
- hash = register_object({}.compare_by_identity)
-
- o = r.wrapped_object
- o.pairs.each_with_index do |(k, v), i|
- push_stack i
- k = visit(k)
- push_stack k
- hash[k] = visit(v)
- end
-
- if o.is_a?(Elements::HashWithDefaultValue)
- push_stack :default
- hash.default = visit(o.default)
- end
-
- hash
- else
- raise UnsupportedError.new("Unsupported user class #{resolve_class(r.name)} in marshal stream", stack: formatted_stack)
- end
- end
-
- def resolve_class(n)
- @class_cache[n] ||= begin
- to_s = resolve_symbol_name(n)
- raise UnpermittedClassError.new(name: to_s, stack: formatted_stack) unless @permitted_classes.include?(to_s)
- visit_symbol_type(n)
- begin
- ::Object.const_get(to_s)
- rescue NameError
- raise ArgumentError, "Undefined class #{to_s.inspect}"
- end
- end
- end
-
- class RationalCompat
- def marshal_load(s)
- num, den = s
- raise ArgumentError, "Expected 2 ints" unless s.size == 2 && num.is_a?(Integer) && den.is_a?(Integer)
- Rational(num, den)
- end
- end
- private_constant :RationalCompat
-
- COMPAT_CLASSES = {}.tap do |h|
- h[Rational] = RationalCompat
- end.compare_by_identity.freeze
- private_constant :COMPAT_CLASSES
-
- def resolve_ivar(klass, name)
- to_s = resolve_symbol_name(name)
-
- raise UnpermittedIvarError.new(symbol: to_s, klass: klass, stack: formatted_stack) unless @permitted_ivars.fetch(klass.name, [].freeze).include?(to_s)
-
- visit_symbol_type(name)
- end
-
- def visit_symbol_type(element)
- case element
- when Elements::Symbol
- sym = element.name.to_sym
- @symbols << sym
- sym
- when Elements::SymbolLink
- visit_Gem_SafeMarshal_Elements_SymbolLink(element)
- end
- end
-
- # This is a hot method, so avoid respond_to? checks on every invocation
- if :read.respond_to?(:name)
- def resolve_symbol_name(element)
- case element
- when Elements::Symbol
- element.name
- when Elements::SymbolLink
- visit_Gem_SafeMarshal_Elements_SymbolLink(element).name
- else
- raise FormatError, "Expected symbol or symbol link, got #{element.inspect} @ #{formatted_stack.join(".")}"
- end
- end
- else
- def resolve_symbol_name(element)
- case element
- when Elements::Symbol
- element.name
- when Elements::SymbolLink
- visit_Gem_SafeMarshal_Elements_SymbolLink(element).to_s
- else
- raise FormatError, "Expected symbol or symbol link, got #{element.inspect} @ #{formatted_stack.join(".")}"
- end
- end
- end
-
- def register_object(o)
- @objects << o
- o
- end
-
- def call_method(receiver, method, *args)
- receiver.__send__(method, *args)
- rescue NoMethodError => e
- raise unless e.receiver == receiver
-
- raise MethodCallError, "Unable to call #{method.inspect} on #{receiver.inspect}, perhaps it is a class using marshal compat, which is not visible in ruby? #{e}"
- end
-
- def formatted_stack
- formatted = []
- @stack[0, @stack_idx].each do |e|
- if e.is_a?(Integer)
- if formatted.last == "ivar_"
- formatted[-1] = "ivar_#{e}"
- else
- formatted << "[#{e}]"
- end
- else
- formatted << e
- end
- end
- formatted
- end
-
- class Error < StandardError
- end
-
- class UnpermittedSymbolError < Error
- def initialize(symbol:, stack:)
- @symbol = symbol
- @stack = stack
- super "Attempting to load unpermitted symbol #{symbol.inspect} @ #{stack.join "."}"
- end
- end
-
- class UnpermittedIvarError < Error
- def initialize(symbol:, klass:, stack:)
- @symbol = symbol
- @klass = klass
- @stack = stack
- super "Attempting to set unpermitted ivar #{symbol.inspect} on object of class #{klass} @ #{stack.join "."}"
- end
- end
-
- class UnpermittedClassError < Error
- def initialize(name:, stack:)
- @name = name
- @stack = stack
- super "Attempting to load unpermitted class #{name.inspect} @ #{stack.join "."}"
- end
- end
-
- class UnsupportedError < Error
- def initialize(message, stack:)
- super "#{message} @ #{stack.join "."}"
- end
- end
-
- class FormatError < Error
- end
-
- class MethodCallError < Error
- end
- end
- end
-end
diff --git a/lib/rubygems/safe_marshal/visitors/visitor.rb b/lib/rubygems/safe_marshal/visitors/visitor.rb
deleted file mode 100644
index c9a079dc0e..0000000000
--- a/lib/rubygems/safe_marshal/visitors/visitor.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::SafeMarshal::Visitors
- class Visitor
- def visit(target)
- send DISPATCH.fetch(target.class), target
- end
-
- private
-
- DISPATCH = Gem::SafeMarshal::Elements.constants.each_with_object({}) do |c, h|
- next if c == :Element
-
- klass = Gem::SafeMarshal::Elements.const_get(c)
- h[klass] = :"visit_#{klass.name.gsub("::", "_")}"
- h.default = :visit_unknown_element
- end.compare_by_identity.freeze
- private_constant :DISPATCH
-
- def visit_unknown_element(e)
- raise ArgumentError, "Attempting to visit unknown element #{e.inspect}"
- end
-
- def visit_Gem_SafeMarshal_Elements_Array(target)
- target.elements.each {|e| visit(e) }
- end
-
- def visit_Gem_SafeMarshal_Elements_Bignum(target); end
- def visit_Gem_SafeMarshal_Elements_False(target); end
- def visit_Gem_SafeMarshal_Elements_Float(target); end
-
- def visit_Gem_SafeMarshal_Elements_Hash(target)
- target.pairs.each do |k, v|
- visit(k)
- visit(v)
- end
- end
-
- def visit_Gem_SafeMarshal_Elements_HashWithDefaultValue(target)
- visit_Gem_SafeMarshal_Elements_Hash(target)
- visit(target.default)
- end
-
- def visit_Gem_SafeMarshal_Elements_Integer(target); end
- def visit_Gem_SafeMarshal_Elements_Nil(target); end
-
- def visit_Gem_SafeMarshal_Elements_Object(target)
- visit(target.name)
- end
-
- def visit_Gem_SafeMarshal_Elements_ObjectLink(target); end
- def visit_Gem_SafeMarshal_Elements_String(target); end
- def visit_Gem_SafeMarshal_Elements_Symbol(target); end
- def visit_Gem_SafeMarshal_Elements_SymbolLink(target); end
- def visit_Gem_SafeMarshal_Elements_True(target); end
-
- def visit_Gem_SafeMarshal_Elements_UserDefined(target)
- visit(target.name)
- end
-
- def visit_Gem_SafeMarshal_Elements_UserMarshal(target)
- visit(target.name)
- visit(target.data)
- end
-
- def visit_Gem_SafeMarshal_Elements_WithIvars(target)
- visit(target.object)
- target.ivars.each do |k, v|
- visit(k)
- visit(v)
- end
- end
- end
-end
diff --git a/lib/rubygems/safe_yaml.rb b/lib/rubygems/safe_yaml.rb
index 6a02a48230..74ad25ca15 100644
--- a/lib/rubygems/safe_yaml.rb
+++ b/lib/rubygems/safe_yaml.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
module Gem
+
###
# This module is used for safely loading YAML specs from a gem. The
# `safe_load` method defined on this module is specifically designed for
@@ -25,21 +26,34 @@ module Gem
runtime
].freeze
- @aliases_enabled = true
- def self.aliases_enabled=(value) # :nodoc:
- @aliases_enabled = !!value
- end
+ if ::Psych.respond_to? :safe_load
+ def self.safe_load(input)
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new("3.1.0.pre1")
+ ::Psych.safe_load(input, permitted_classes: PERMITTED_CLASSES, permitted_symbols: PERMITTED_SYMBOLS, aliases: true)
+ else
+ ::Psych.safe_load(input, PERMITTED_CLASSES, PERMITTED_SYMBOLS, true)
+ end
+ end
- def self.aliases_enabled? # :nodoc:
- @aliases_enabled
- end
+ def self.load(input)
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new("3.1.0.pre1")
+ ::Psych.safe_load(input, permitted_classes: [::Symbol])
+ else
+ ::Psych.safe_load(input, [::Symbol])
+ end
+ end
+ else
+ unless Gem::Deprecate.skip
+ warn "Psych safe loading is not available. Please upgrade psych to a version that supports safe loading (>= 2.0)."
+ end
- def self.safe_load(input)
- ::Psych.safe_load(input, permitted_classes: PERMITTED_CLASSES, permitted_symbols: PERMITTED_SYMBOLS, aliases: @aliases_enabled)
- end
+ def self.safe_load(input, *args)
+ ::Psych.load input
+ end
- def self.load(input)
- ::Psych.safe_load(input, permitted_classes: [::Symbol])
+ def self.load(input)
+ ::Psych.load input
+ end
end
end
end
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
index 69ba87b07f..73ee1e4bb9 100644
--- a/lib/rubygems/security.rb
+++ b/lib/rubygems/security.rb
@@ -323,9 +323,10 @@ require_relative "openssl"
# == Original author
#
# Paul Duncan <pabs@pablotron.org>
-# https://pablotron.org/
+# http://pablotron.org/
module Gem::Security
+
##
# Gem::Security default exception type
@@ -360,7 +361,7 @@ module Gem::Security
##
# One day in seconds
- ONE_DAY = 86_400
+ ONE_DAY = 86400
##
# One year in seconds
@@ -398,7 +399,8 @@ module Gem::Security
#
# The +extensions+ restrict the key to the indicated uses.
- def self.create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS, serial = 1)
+ def self.create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS,
+ serial = 1)
cert = OpenSSL::X509::Certificate.new
cert.public_key = get_public_key(key)
@@ -449,7 +451,8 @@ module Gem::Security
# Creates a self-signed certificate with an issuer and subject of +subject+
# and the given +extensions+ for the +key+.
- def self.create_cert_self_signed(subject, key, age = ONE_YEAR, extensions = EXTENSIONS, serial = 1)
+ def self.create_cert_self_signed(subject, key, age = ONE_YEAR,
+ extensions = EXTENSIONS, serial = 1)
certificate = create_cert subject, key, age, extensions
sign certificate, key, certificate, age, extensions, serial
@@ -459,8 +462,16 @@ module Gem::Security
# Creates a new digest instance using the specified +algorithm+. The default
# is SHA256.
- def self.create_digest(algorithm = DIGEST_NAME)
- OpenSSL::Digest.new(algorithm)
+ if defined?(OpenSSL::Digest)
+ def self.create_digest(algorithm = DIGEST_NAME)
+ OpenSSL::Digest.new(algorithm)
+ end
+ else
+ require "digest"
+
+ def self.create_digest(algorithm = DIGEST_NAME)
+ Digest.const_get(algorithm).new
+ end
end
##
@@ -505,10 +516,11 @@ module Gem::Security
#--
# TODO increment serial
- def self.re_sign(expired_certificate, private_key, age = ONE_YEAR, extensions = EXTENSIONS)
+ def self.re_sign(expired_certificate, private_key, age = ONE_YEAR,
+ extensions = EXTENSIONS)
raise Gem::Security::Exception,
"incorrect signing key for re-signing " +
- expired_certificate.subject.to_s unless
+ "#{expired_certificate.subject}" unless
expired_certificate.check_private_key(private_key)
unless expired_certificate.subject.to_s ==
@@ -517,7 +529,7 @@ module Gem::Security
issuer = alt_name_or_x509_entry expired_certificate, :issuer
raise Gem::Security::Exception,
- "#{subject} is not self-signed, contact #{issuer} " \
+ "#{subject} is not self-signed, contact #{issuer} " +
"to obtain a valid certificate"
end
@@ -541,7 +553,8 @@ module Gem::Security
#
# Returns the newly signed certificate.
- def self.sign(certificate, signing_key, signing_cert, age = ONE_YEAR, extensions = EXTENSIONS, serial = 1)
+ def self.sign(certificate, signing_key, signing_cert,
+ age = ONE_YEAR, extensions = EXTENSIONS, serial = 1)
signee_subject = certificate.subject
signee_key = certificate.public_key
@@ -589,7 +602,7 @@ module Gem::Security
# +permissions+. If passed +cipher+ and +passphrase+ those arguments will be
# passed to +to_pem+.
- def self.write(pemmable, path, permissions = 0o600, passphrase = nil, cipher = KEY_CIPHER)
+ def self.write(pemmable, path, permissions = 0600, passphrase = nil, cipher = KEY_CIPHER)
path = File.expand_path path
File.open path, "wb", permissions do |io|
@@ -604,6 +617,7 @@ module Gem::Security
end
reset
+
end
if Gem::HAVE_OPENSSL
diff --git a/lib/rubygems/security/policies.rb b/lib/rubygems/security/policies.rb
index 41f66043ad..bdfe9ed43f 100644
--- a/lib/rubygems/security/policies.rb
+++ b/lib/rubygems/security/policies.rb
@@ -1,17 +1,18 @@
# frozen_string_literal: true
module Gem::Security
+
##
# No security policy: all package signature checks are disabled.
NoSecurity = Policy.new(
"No Security",
- verify_data: false,
- verify_signer: false,
- verify_chain: false,
- verify_root: false,
- only_trusted: false,
- only_signed: false
+ :verify_data => false,
+ :verify_signer => false,
+ :verify_chain => false,
+ :verify_root => false,
+ :only_trusted => false,
+ :only_signed => false
)
##
@@ -24,12 +25,12 @@ module Gem::Security
AlmostNoSecurity = Policy.new(
"Almost No Security",
- verify_data: true,
- verify_signer: false,
- verify_chain: false,
- verify_root: false,
- only_trusted: false,
- only_signed: false
+ :verify_data => true,
+ :verify_signer => false,
+ :verify_chain => false,
+ :verify_root => false,
+ :only_trusted => false,
+ :only_signed => false
)
##
@@ -41,12 +42,12 @@ module Gem::Security
LowSecurity = Policy.new(
"Low Security",
- verify_data: true,
- verify_signer: true,
- verify_chain: false,
- verify_root: false,
- only_trusted: false,
- only_signed: false
+ :verify_data => true,
+ :verify_signer => true,
+ :verify_chain => false,
+ :verify_root => false,
+ :only_trusted => false,
+ :only_signed => false
)
##
@@ -60,12 +61,12 @@ module Gem::Security
MediumSecurity = Policy.new(
"Medium Security",
- verify_data: true,
- verify_signer: true,
- verify_chain: true,
- verify_root: true,
- only_trusted: true,
- only_signed: false
+ :verify_data => true,
+ :verify_signer => true,
+ :verify_chain => true,
+ :verify_root => true,
+ :only_trusted => true,
+ :only_signed => false
)
##
@@ -79,12 +80,12 @@ module Gem::Security
HighSecurity = Policy.new(
"High Security",
- verify_data: true,
- verify_signer: true,
- verify_chain: true,
- verify_root: true,
- only_trusted: true,
- only_signed: true
+ :verify_data => true,
+ :verify_signer => true,
+ :verify_chain => true,
+ :verify_root => true,
+ :only_trusted => true,
+ :only_signed => true
)
##
@@ -92,12 +93,12 @@ module Gem::Security
SigningPolicy = Policy.new(
"Signing Policy",
- verify_data: false,
- verify_signer: true,
- verify_chain: true,
- verify_root: true,
- only_trusted: false,
- only_signed: false
+ :verify_data => false,
+ :verify_signer => true,
+ :verify_chain => true,
+ :verify_root => true,
+ :only_trusted => false,
+ :only_signed => false
)
##
@@ -111,4 +112,5 @@ module Gem::Security
"HighSecurity" => HighSecurity,
# SigningPolicy is not intended for use by `gem -P` so do not list it
}.freeze
+
end
diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb
index 7b86ac5763..9b9eac46bf 100644
--- a/lib/rubygems/security/policy.rb
+++ b/lib/rubygems/security/policy.rb
@@ -135,7 +135,7 @@ class Gem::Security::Policy
raise Gem::Security::Exception, "missing root certificate" unless root
raise Gem::Security::Exception,
- "root certificate #{root.subject} is not self-signed " \
+ "root certificate #{root.subject} is not self-signed " +
"(issuer #{root.issuer})" if
root.issuer != root.subject
@@ -171,7 +171,7 @@ class Gem::Security::Policy
cert_dgst = digester.digest pkey_str
raise Gem::Security::Exception,
- "trusted root certificate #{root.subject} checksum " \
+ "trusted root certificate #{root.subject} checksum " +
"does not match signing root certificate checksum" unless
save_dgst == cert_dgst
@@ -192,8 +192,11 @@ class Gem::Security::Policy
end
def inspect # :nodoc:
- format("[Policy: %s - data: %p signer: %p chain: %p root: %p " \
- "signed-only: %p trusted-only: %p]", @name, @verify_chain, @verify_data, @verify_root, @verify_signer, @only_signed, @only_trusted)
+ ("[Policy: %s - data: %p signer: %p chain: %p root: %p " +
+ "signed-only: %p trusted-only: %p]") % [
+ @name, @verify_chain, @verify_data, @verify_root, @verify_signer,
+ @only_signed, @only_trusted
+ ]
end
##
@@ -203,7 +206,8 @@ class Gem::Security::Policy
#
# If +key+ is given it is used to validate the signing certificate.
- def verify(chain, key = nil, digests = {}, signatures = {}, full_name = "(unknown)")
+ def verify(chain, key = nil, digests = {}, signatures = {},
+ full_name = "(unknown)")
if signatures.empty?
if @only_signed
raise Gem::Security::Exception,
@@ -222,7 +226,7 @@ class Gem::Security::Policy
trust_dir = opt[:trust_dir]
time = Time.now
- _, signer_digests = digests.find do |_algorithm, file_digests|
+ _, signer_digests = digests.find do |algorithm, file_digests|
file_digests.values.first.name == Gem::Security::DIGEST_NAME
end
@@ -284,5 +288,5 @@ class Gem::Security::Policy
true
end
- alias_method :to_s, :name # :nodoc:
+ alias to_s name # :nodoc:
end
diff --git a/lib/rubygems/security/signer.rb b/lib/rubygems/security/signer.rb
index 5732fb57fd..d76af03eb8 100644
--- a/lib/rubygems/security/signer.rb
+++ b/lib/rubygems/security/signer.rb
@@ -106,7 +106,7 @@ class Gem::Security::Signer
# this value is preferred, otherwise the subject is used.
def extract_name(cert) # :nodoc:
- subject_alt_name = cert.extensions.find {|e| e.oid == "subjectAltName" }
+ subject_alt_name = cert.extensions.find {|e| "subjectAltName" == e.oid }
if subject_alt_name
/\Aemail:/ =~ subject_alt_name.value # rubocop:disable Performance/StartWith
@@ -175,18 +175,10 @@ class Gem::Security::Signer
old_cert = @cert_chain.last
disk_cert_path = File.join(Gem.default_cert_path)
- disk_cert = begin
- File.read(disk_cert_path)
- rescue StandardError
- nil
- end
+ disk_cert = File.read(disk_cert_path) rescue nil
disk_key_path = File.join(Gem.default_key_path)
- disk_key = begin
- OpenSSL::PKey.read(File.read(disk_key_path), @passphrase)
- rescue StandardError
- nil
- end
+ disk_key = OpenSSL::PKey.read(File.read(disk_key_path), @passphrase) rescue nil
return unless disk_key
diff --git a/lib/rubygems/security/trust_dir.rb b/lib/rubygems/security/trust_dir.rb
index d23d161cfe..4de33068f9 100644
--- a/lib/rubygems/security/trust_dir.rb
+++ b/lib/rubygems/security/trust_dir.rb
@@ -9,8 +9,8 @@ class Gem::Security::TrustDir
# Default permissions for the trust directory and its contents
DEFAULT_PERMISSIONS = {
- trust_dir: 0o700,
- trusted_cert: 0o600,
+ :trust_dir => 0700,
+ :trusted_cert => 0600,
}.freeze
##
@@ -45,11 +45,13 @@ class Gem::Security::TrustDir
glob = File.join @dir, "*.pem"
Dir[glob].each do |certificate_file|
- certificate = load_certificate certificate_file
+ begin
+ certificate = load_certificate certificate_file
- yield certificate, certificate_file
- rescue OpenSSL::X509::CertificateError
- next # HACK: warn
+ yield certificate, certificate_file
+ rescue OpenSSL::X509::CertificateError
+ next # HACK warn
+ end
end
end
@@ -91,7 +93,7 @@ class Gem::Security::TrustDir
destination = cert_path certificate
- File.open destination, "wb", 0o600 do |io|
+ File.open destination, "wb", 0600 do |io|
io.write certificate.to_pem
io.chmod(@permissions[:trusted_cert])
end
@@ -109,9 +111,9 @@ class Gem::Security::TrustDir
"trust directory #{@dir} is not a directory" unless
File.directory? @dir
- FileUtils.chmod 0o700, @dir
+ FileUtils.chmod 0700, @dir
else
- FileUtils.mkdir_p @dir, mode: @permissions[:trust_dir]
+ FileUtils.mkdir_p @dir, :mode => @permissions[:trust_dir]
end
end
end
diff --git a/lib/rubygems/security_option.rb b/lib/rubygems/security_option.rb
index 3a101fe9db..f288ebd047 100644
--- a/lib/rubygems/security_option.rb
+++ b/lib/rubygems/security_option.rb
@@ -29,7 +29,7 @@ module Gem::SecurityOption
policy = Gem::Security::Policies[value]
unless policy
valid = Gem::Security::Policies.keys.sort
- raise Gem::OptionParser::InvalidArgument, "#{value} (#{valid.join ", "} are valid)"
+ raise Gem::OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)"
end
policy
end
diff --git a/lib/rubygems/source.rb b/lib/rubygems/source.rb
index d90e311b65..aa0cbc1641 100644
--- a/lib/rubygems/source.rb
+++ b/lib/rubygems/source.rb
@@ -12,9 +12,9 @@ class Gem::Source
include Gem::Text
FILES = { # :nodoc:
- released: "specs",
- latest: "latest_specs",
- prerelease: "prerelease_specs",
+ :released => "specs",
+ :latest => "latest_specs",
+ :prerelease => "prerelease_specs",
}.freeze
##
@@ -44,18 +44,20 @@ class Gem::Source
Gem::Source::Vendor then
-1
when Gem::Source then
- unless @uri
+ if !@uri
return 0 unless other.uri
return 1
end
- return -1 unless other.uri
+ return -1 if !other.uri
# Returning 1 here ensures that when sorting a list of sources, the
# original ordering of sources supplied by the user is preserved.
return 1 unless @uri.to_s == other.uri.to_s
0
+ else
+ nil
end
end
@@ -69,7 +71,7 @@ class Gem::Source
# Returns a Set that can fetch specifications from this source.
def dependency_resolver_set # :nodoc:
- return Gem::Resolver::IndexSet.new self if uri.scheme == "file"
+ return Gem::Resolver::IndexSet.new self if "file" == uri.scheme
fetch_uri = if uri.host == "rubygems.org"
index_uri = uri.dup
@@ -100,7 +102,8 @@ class Gem::Source
def cache_dir(uri)
# Correct for windows paths
- escaped_path = uri.path.sub(%r{^/([a-z]):/}i, '/\\1-/')
+ escaped_path = uri.path.sub(/^\/([a-z]):\//i, '/\\1-/')
+ escaped_path.tap(&Gem::UNTAINT)
File.join Gem.spec_cache_dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
end
@@ -134,12 +137,7 @@ class Gem::Source
if File.exist? local_spec
spec = Gem.read_binary local_spec
- Gem.load_safe_marshal
- spec = begin
- Gem::SafeMarshal.safe_load(spec)
- rescue StandardError
- nil
- end
+ spec = Marshal.load(spec) rescue nil
return spec if spec
end
@@ -157,9 +155,8 @@ class Gem::Source
end
end
- Gem.load_safe_marshal
# TODO: Investigate setting Gem::Specification#loaded_from to a URI
- Gem::SafeMarshal.safe_load spec
+ Marshal.load spec
end
##
@@ -189,9 +186,8 @@ class Gem::Source
spec_dump = fetcher.cache_update_path spec_path, local_file, update_cache?
- Gem.load_safe_marshal
begin
- Gem::NameTuple.from_list Gem::SafeMarshal.safe_load(spec_dump)
+ Gem::NameTuple.from_list Marshal.load(spec_dump)
rescue ArgumentError
if update_cache? && !retried
FileUtils.rm local_file
@@ -233,7 +229,7 @@ class Gem::Source
private
def enforce_trailing_slash(uri)
- uri.merge(uri.path.gsub(%r{/+$}, "") + "/")
+ uri.merge(uri.path.gsub(/\/+$/, "") + "/")
end
end
diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb
index bda63c6844..7ac685f978 100644
--- a/lib/rubygems/source/git.rb
+++ b/lib/rubygems/source/git.rb
@@ -70,6 +70,8 @@ class Gem::Source::Git < Gem::Source
-1
when Gem::Source then
1
+ else
+ nil
end
end
@@ -221,14 +223,14 @@ class Gem::Source::Git < Gem::Source
end
##
- # A hash for the git gem based on the git repository Gem::URI.
+ # A hash for the git gem based on the git repository URI.
def uri_hash # :nodoc:
require_relative "../openssl"
normalized =
- if @repository.match?(%r{^\w+://(\w+@)?})
- uri = Gem::URI(@repository).normalize.to_s.sub %r{/$},""
+ if @repository =~ %r{^\w+://(\w+@)?}
+ uri = URI(@repository).normalize.to_s.sub %r{/$},""
uri.sub(/\A(\w+)/) { $1.downcase }
else
@repository
diff --git a/lib/rubygems/source/installed.rb b/lib/rubygems/source/installed.rb
index cbe12a0516..f5d3f06d6a 100644
--- a/lib/rubygems/source/installed.rb
+++ b/lib/rubygems/source/installed.rb
@@ -21,6 +21,8 @@ class Gem::Source::Installed < Gem::Source
0
when Gem::Source then
1
+ else
+ nil
end
end
diff --git a/lib/rubygems/source/local.rb b/lib/rubygems/source/local.rb
index d81d8343a8..5068b0b906 100644
--- a/lib/rubygems/source/local.rb
+++ b/lib/rubygems/source/local.rb
@@ -24,12 +24,14 @@ class Gem::Source::Local < Gem::Source
0
when Gem::Source then
1
+ else
+ nil
end
end
def inspect # :nodoc:
keys = @specs ? @specs.keys.sort : "NOT LOADED"
- format("#<%s specs: %p>", self.class, keys)
+ "#<%s specs: %p>" % [self.class, keys]
end
def load_specs(type) # :nodoc:
@@ -39,35 +41,36 @@ class Gem::Source::Local < Gem::Source
@specs = {}
Dir["*.gem"].each do |file|
- pkg = Gem::Package.new(file)
- spec = pkg.spec
- rescue SystemCallError, Gem::Package::FormatError
- # ignore
- else
- tup = spec.name_tuple
- @specs[tup] = [File.expand_path(file), pkg]
-
- case type
- when :released
- unless pkg.spec.version.prerelease?
- names << pkg.spec.name_tuple
- end
- when :prerelease
- if pkg.spec.version.prerelease?
- names << pkg.spec.name_tuple
- end
- when :latest
+ begin
+ pkg = Gem::Package.new(file)
+ rescue SystemCallError, Gem::Package::FormatError
+ # ignore
+ else
tup = pkg.spec.name_tuple
-
- cur = names.find {|x| x.name == tup.name }
- if !cur
- names << tup
- elsif cur.version < tup.version
- names.delete cur
- names << tup
+ @specs[tup] = [File.expand_path(file), pkg]
+
+ case type
+ when :released
+ unless pkg.spec.version.prerelease?
+ names << pkg.spec.name_tuple
+ end
+ when :prerelease
+ if pkg.spec.version.prerelease?
+ names << pkg.spec.name_tuple
+ end
+ when :latest
+ tup = pkg.spec.name_tuple
+
+ cur = names.find {|x| x.name == tup.name }
+ if !cur
+ names << tup
+ elsif cur.version < tup.version
+ names.delete cur
+ names << tup
+ end
+ else
+ names << pkg.spec.name_tuple
end
- else
- names << pkg.spec.name_tuple
end
end
@@ -75,25 +78,27 @@ class Gem::Source::Local < Gem::Source
end
end
- def find_gem(gem_name, version = Gem::Requirement.default, prerelease = false) # :nodoc:
+ def find_gem(gem_name, version = Gem::Requirement.default, # :nodoc:
+ prerelease = false)
load_specs :complete
found = []
@specs.each do |n, data|
- next unless n.name == gem_name
- s = data[1].spec
-
- if version.satisfied_by?(s.version)
- if prerelease
- found << s
- elsif !s.version.prerelease? || version.prerelease?
- found << s
+ if n.name == gem_name
+ s = data[1].spec
+
+ if version.satisfied_by?(s.version)
+ if prerelease
+ found << s
+ elsif !s.version.prerelease? || version.prerelease?
+ found << s
+ end
end
end
end
- found.max_by(&:version)
+ found.max_by {|s| s.version }
end
def fetch_spec(name) # :nodoc:
@@ -109,7 +114,7 @@ class Gem::Source::Local < Gem::Source
def download(spec, cache_dir = nil) # :nodoc:
load_specs :complete
- @specs.each do |_name, data|
+ @specs.each do |name, data|
return data[0] if data[1].spec == spec
end
diff --git a/lib/rubygems/source/lock.rb b/lib/rubygems/source/lock.rb
index 70849210bd..f9388bbd61 100644
--- a/lib/rubygems/source/lock.rb
+++ b/lib/rubygems/source/lock.rb
@@ -25,11 +25,13 @@ class Gem::Source::Lock < Gem::Source
@wrapped <=> other.wrapped
when Gem::Source then
1
+ else
+ nil
end
end
def ==(other) # :nodoc:
- (self <=> other) == 0
+ 0 == (self <=> other)
end
def hash # :nodoc:
diff --git a/lib/rubygems/source/specific_file.rb b/lib/rubygems/source/specific_file.rb
index e9b2753646..61965c2644 100644
--- a/lib/rubygems/source/specific_file.rb
+++ b/lib/rubygems/source/specific_file.rb
@@ -34,6 +34,7 @@ class Gem::Source::SpecificFile < Gem::Source
def fetch_spec(name) # :nodoc:
return @spec if name == @name
raise Gem::Exception, "Unable to find '#{name}'"
+ @spec
end
def download(spec, dir = nil) # :nodoc:
diff --git a/lib/rubygems/source/vendor.rb b/lib/rubygems/source/vendor.rb
index 44ef614441..12161b8cf5 100644
--- a/lib/rubygems/source/vendor.rb
+++ b/lib/rubygems/source/vendor.rb
@@ -19,6 +19,8 @@ class Gem::Source::Vendor < Gem::Source::Installed
0
when Gem::Source then
1
+ else
+ nil
end
end
end
diff --git a/lib/rubygems/source_list.rb b/lib/rubygems/source_list.rb
index 33db64fbc1..7abe796409 100644
--- a/lib/rubygems/source_list.rb
+++ b/lib/rubygems/source_list.rb
@@ -36,7 +36,7 @@ class Gem::SourceList
list.replace ary
- list
+ return list
end
def initialize_copy(other) # :nodoc:
@@ -44,15 +44,15 @@ class Gem::SourceList
end
##
- # Appends +obj+ to the source list which may be a Gem::Source, Gem::URI or URI
+ # Appends +obj+ to the source list which may be a Gem::Source, URI or URI
# String.
def <<(obj)
src = case obj
- when Gem::Source
- obj
- else
- Gem::Source.new(obj)
+ when Gem::Source
+ obj
+ else
+ Gem::Source.new(obj)
end
@sources << src unless @sources.include?(src)
@@ -126,7 +126,7 @@ class Gem::SourceList
# Gem::Source or a source URI.
def include?(other)
- if other.is_a? Gem::Source
+ if other.kind_of? Gem::Source
@sources.include? other
else
@sources.find {|x| x.uri.to_s == other.to_s }
@@ -137,7 +137,7 @@ class Gem::SourceList
# Deletes +source+ from the source list which may be a Gem::Source or a URI.
def delete(source)
- if source.is_a? Gem::Source
+ if source.kind_of? Gem::Source
@sources.delete source
else
@sources.delete_if {|x| x.uri.to_s == source.to_s }
diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb
index 610edf25c9..a5a4fa0c0f 100644
--- a/lib/rubygems/spec_fetcher.rb
+++ b/lib/rubygems/spec_fetcher.rb
@@ -69,9 +69,9 @@ class Gem::SpecFetcher
@prerelease_specs = {}
@caches = {
- latest: @latest_specs,
- prerelease: @prerelease_specs,
- released: @specs,
+ :latest => @latest_specs,
+ :prerelease => @prerelease_specs,
+ :released => @specs,
}
@fetcher = Gem::RemoteFetcher.fetcher
@@ -92,9 +92,9 @@ class Gem::SpecFetcher
list.each do |source, specs|
if dependency.name.is_a?(String) && specs.respond_to?(:bsearch)
- start_index = (0...specs.length).bsearch {|i| specs[i].name >= dependency.name }
- end_index = (0...specs.length).bsearch {|i| specs[i].name > dependency.name }
- specs = specs[start_index...end_index] if start_index && end_index
+ start_index = (0 ... specs.length).bsearch {|i| specs[i].name >= dependency.name }
+ end_index = (0 ... specs.length).bsearch {|i| specs[i].name > dependency.name }
+ specs = specs[start_index ... end_index] if start_index && end_index
end
found[source] = specs.select do |tup|
@@ -124,7 +124,7 @@ class Gem::SpecFetcher
tuples = tuples.sort_by {|x| x[0].version }
- [tuples, errors]
+ return [tuples, errors]
end
##
@@ -155,14 +155,16 @@ class Gem::SpecFetcher
specs = []
tuples.each do |tup, source|
- spec = source.fetch_spec(tup)
- rescue Gem::RemoteFetcher::FetchError => e
- errors << Gem::SourceFetchProblem.new(source, e)
- else
- specs << [spec, source]
+ begin
+ spec = source.fetch_spec(tup)
+ rescue Gem::RemoteFetcher::FetchError => e
+ errors << Gem::SourceFetchProblem.new(source, e)
+ else
+ specs << [spec, source]
+ end
end
- [specs, errors]
+ return [specs, errors]
end
##
@@ -192,10 +194,10 @@ class Gem::SpecFetcher
matches = if matches.empty? && type != :prerelease
suggest_gems_from_name gem_name, :prerelease
else
- matches.uniq.sort_by {|_name, dist| dist }
+ matches.uniq.sort_by {|name, dist| dist }
end
- matches.map {|name, _dist| name }.uniq.first(num_results)
+ matches.map {|name, dist| name }.uniq.first(num_results)
end
##
@@ -213,32 +215,34 @@ class Gem::SpecFetcher
list = {}
@sources.each_source do |source|
- names = case type
- when :latest
- tuples_for source, :latest
- when :released
- tuples_for source, :released
- when :complete
- names =
- tuples_for(source, :prerelease, true) +
- tuples_for(source, :released)
-
- names.sort
- when :abs_latest
- names =
- tuples_for(source, :prerelease, true) +
- tuples_for(source, :latest)
-
- names.sort
- when :prerelease
- tuples_for(source, :prerelease)
- else
- raise Gem::Exception, "Unknown type - :#{type}"
+ begin
+ names = case type
+ when :latest
+ tuples_for source, :latest
+ when :released
+ tuples_for source, :released
+ when :complete
+ names =
+ tuples_for(source, :prerelease, true) +
+ tuples_for(source, :released)
+
+ names.sort
+ when :abs_latest
+ names =
+ tuples_for(source, :prerelease, true) +
+ tuples_for(source, :latest)
+
+ names.sort
+ when :prerelease
+ tuples_for(source, :prerelease)
+ else
+ raise Gem::Exception, "Unknown type - :#{type}"
+ end
+ rescue Gem::RemoteFetcher::FetchError => e
+ errors << Gem::SourceFetchProblem.new(source, e)
+ else
+ list[source] = names
end
- rescue Gem::RemoteFetcher::FetchError => e
- errors << Gem::SourceFetchProblem.new(source, e)
- else
- list[source] = names
end
[list, errors]
@@ -250,7 +254,7 @@ class Gem::SpecFetcher
def tuples_for(source, type, gracefully_ignore=false) # :nodoc:
@caches[type][source.uri] ||=
- source.load_specs(type).sort_by(&:name)
+ source.load_specs(type).sort_by {|tup| tup.name }
rescue Gem::RemoteFetcher::FetchError
raise unless gracefully_ignore
[]
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 05ce483db6..7611e1ba1f 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -11,11 +11,8 @@ require_relative "deprecate"
require_relative "basic_specification"
require_relative "stub_specification"
require_relative "platform"
-require_relative "specification_record"
require_relative "util/list"
-require "rbconfig"
-
##
# The Specification class contains the information for a gem. Typically
# defined in a .gemspec file or a Rakefile, and looks like this:
@@ -109,7 +106,7 @@ class Gem::Specification < Gem::BasicSpecification
@load_cache = {} # :nodoc:
@load_cache_mutex = Thread::Mutex.new
- VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
+ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/.freeze # :nodoc:
# :startdoc:
@@ -128,35 +125,35 @@ class Gem::Specification < Gem::BasicSpecification
# Map of attribute names to default values.
@@default_value = {
- authors: [],
- autorequire: nil,
- bindir: "bin",
- cert_chain: [],
- date: nil,
- dependencies: [],
- description: nil,
- email: nil,
- executables: [],
- extensions: [],
- extra_rdoc_files: [],
- files: [],
- homepage: nil,
- licenses: [],
- metadata: {},
- name: nil,
- platform: Gem::Platform::RUBY,
- post_install_message: nil,
- rdoc_options: [],
- require_paths: ["lib"],
- required_ruby_version: Gem::Requirement.default,
- required_rubygems_version: Gem::Requirement.default,
- requirements: [],
- rubygems_version: Gem::VERSION,
- signing_key: nil,
- specification_version: CURRENT_SPECIFICATION_VERSION,
- summary: nil,
- test_files: [],
- version: nil,
+ :authors => [],
+ :autorequire => nil,
+ :bindir => "bin",
+ :cert_chain => [],
+ :date => nil,
+ :dependencies => [],
+ :description => nil,
+ :email => nil,
+ :executables => [],
+ :extensions => [],
+ :extra_rdoc_files => [],
+ :files => [],
+ :homepage => nil,
+ :licenses => [],
+ :metadata => {},
+ :name => nil,
+ :platform => Gem::Platform::RUBY,
+ :post_install_message => nil,
+ :rdoc_options => [],
+ :require_paths => ["lib"],
+ :required_ruby_version => Gem::Requirement.default,
+ :required_rubygems_version => Gem::Requirement.default,
+ :requirements => [],
+ :rubygems_version => Gem::VERSION,
+ :signing_key => nil,
+ :specification_version => CURRENT_SPECIFICATION_VERSION,
+ :summary => nil,
+ :test_files => [],
+ :version => nil,
}.freeze
# rubocop:disable Style/MutableConstant
@@ -165,27 +162,39 @@ class Gem::Specification < Gem::BasicSpecification
@@default_value.each do |k,v|
INITIALIZE_CODE_FOR_DEFAULTS[k] = case v
- when [], {}, true, false, nil, Numeric, Symbol
- v.inspect
- when String
- v.dump
- else
- "default_value(:#{k}).dup"
+ when [], {}, true, false, nil, Numeric, Symbol
+ v.inspect
+ when String
+ v.dump
+ when Numeric
+ "default_value(:#{k})"
+ else
+ "default_value(:#{k}).dup"
end
end
- @@attributes = @@default_value.keys.sort_by(&:to_s)
- @@array_attributes = @@default_value.reject {|_k,v| v != [] }.keys
+ @@attributes = @@default_value.keys.sort_by {|s| s.to_s }
+ @@array_attributes = @@default_value.reject {|k,v| v != [] }.keys
@@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition do |k|
@@default_value[k].nil?
end
+ def self.clear_specs # :nodoc:
+ @@all = nil
+ @@stubs = nil
+ @@stubs_by_name = {}
+ @@spec_with_requirable_file = {}
+ @@active_stub_with_requirable_file = {}
+ end
+ private_class_method :clear_specs
+
+ clear_specs
+
# Sentinel object to represent "not found" stubs
NOT_FOUND = Struct.new(:to_spec, :this).new # :nodoc:
- deprecate_constant :NOT_FOUND
# Tracking removed method calls to warn users during build time.
- REMOVED_METHODS = [:rubyforge_project=, :mark_version].freeze # :nodoc:
+ REMOVED_METHODS = [:rubyforge_project=].freeze # :nodoc:
def removed_method_calls
@removed_method_calls ||= []
end
@@ -254,7 +263,8 @@ class Gem::Specification < Gem::BasicSpecification
@test_files,
add_bindir(@executables),
@extra_rdoc_files,
- @extensions].flatten.compact.uniq.sort
+ @extensions,
+ ].flatten.compact.uniq.sort
end
##
@@ -292,7 +302,7 @@ class Gem::Specification < Gem::BasicSpecification
#
# Usage:
#
- # spec.description = <<~EOF
+ # spec.description = <<-EOF
# Rake is a Make-like program implemented in Ruby. Tasks and
# dependencies are specified in standard Ruby syntax.
# EOF
@@ -332,7 +342,7 @@ class Gem::Specification < Gem::BasicSpecification
# https://opensource.org/licenses/ approved.
#
# The most commonly used OSI-approved licenses are MIT and Apache-2.0.
- # GitHub also provides a license picker at https://choosealicense.com/.
+ # GitHub also provides a license picker at http://choosealicense.com/.
#
# You can also use a custom license file along with your gemspec and specify
# a LicenseRef-<idstring>, where idstring is the name of the file containing
@@ -417,11 +427,11 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # The path in the gem for executable scripts. Usually 'exe'
+ # The path in the gem for executable scripts. Usually 'bin'
#
# Usage:
#
- # spec.bindir = 'exe'
+ # spec.bindir = 'bin'
attr_accessor :bindir
@@ -493,6 +503,8 @@ class Gem::Specification < Gem::BasicSpecification
@platform = @new_platform.to_s
invalidate_memoized_attributes
+
+ @new_platform
end
##
@@ -522,6 +534,13 @@ class Gem::Specification < Gem::BasicSpecification
attr_reader :required_rubygems_version
##
+ # The version of RubyGems used to create this gem.
+ #
+ # Do not set this, it is set automatically when the gem is packaged.
+
+ attr_accessor :rubygems_version
+
+ ##
# The key used to sign this gem. See Gem::Security for details.
attr_accessor :signing_key
@@ -559,7 +578,7 @@ class Gem::Specification < Gem::BasicSpecification
##
# Executables included in the gem.
#
- # For example, the rake gem has rake as an executable. You don't specify the
+ # For example, the rake gem has rake as an executable. You don’t specify the
# full path (as in bin/rake); all application-style files are expected to be
# found in bindir. These files must be executable Ruby files. Files that
# use bash or other interpreters will not work.
@@ -580,7 +599,7 @@ class Gem::Specification < Gem::BasicSpecification
# extconf.rb-style files used to compile extensions.
#
# These files will be run when the gem is installed, causing the C (or
- # whatever) code to be compiled on the user's machine.
+ # whatever) code to be compiled on the user’s machine.
#
# Usage:
#
@@ -709,21 +728,6 @@ class Gem::Specification < Gem::BasicSpecification
end
######################################################################
- # :section: Read-only attributes
-
- ##
- # The version of RubyGems used to create this gem.
-
- attr_accessor :rubygems_version
-
- ##
- # The path where this gem installs its extensions.
-
- def extensions_dir
- @extensions_dir ||= super
- end
-
- ######################################################################
# :section: Specification internals
##
@@ -731,7 +735,7 @@ class Gem::Specification < Gem::BasicSpecification
attr_accessor :activated
- alias_method :activated?, :activated
+ alias :activated? :activated
##
# Autorequire was used by old RubyGems to automatically require a file.
@@ -761,7 +765,7 @@ class Gem::Specification < Gem::BasicSpecification
attr_accessor :specification_version
def self._all # :nodoc:
- specification_record.all
+ @@all ||= Gem.loaded_specs.values | stubs.map(&:to_spec)
end
def self.clear_load_cache # :nodoc:
@@ -774,14 +778,31 @@ class Gem::Specification < Gem::BasicSpecification
def self.each_gemspec(dirs) # :nodoc:
dirs.each do |dir|
Gem::Util.glob_files_in_dir("*.gemspec", dir).each do |path|
- yield path
+ yield path.tap(&Gem::UNTAINT)
end
end
end
- def self.gemspec_stubs_in(dir, pattern) # :nodoc:
+ def self.gemspec_stubs_in(dir, pattern)
Gem::Util.glob_files_in_dir(pattern, dir).map {|path| yield path }.select(&:valid?)
end
+ private_class_method :gemspec_stubs_in
+
+ def self.installed_stubs(dirs, pattern)
+ map_stubs(dirs, pattern) do |path, base_dir, gems_dir|
+ Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
+ end
+ end
+ private_class_method :installed_stubs
+
+ def self.map_stubs(dirs, pattern) # :nodoc:
+ dirs.flat_map do |dir|
+ base_dir = File.dirname dir
+ gems_dir = File.join base_dir, "gems"
+ gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir }
+ end
+ end
+ private_class_method :map_stubs
def self.each_spec(dirs) # :nodoc:
each_gemspec(dirs) do |path|
@@ -794,7 +815,13 @@ class Gem::Specification < Gem::BasicSpecification
# Returns a Gem::StubSpecification for every installed gem
def self.stubs
- specification_record.stubs
+ @@stubs ||= begin
+ pattern = "*.gemspec"
+ stubs = stubs_for_pattern(pattern, false)
+
+ @@stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name)
+ stubs
+ end
end
##
@@ -813,7 +840,13 @@ class Gem::Specification < Gem::BasicSpecification
# only returns stubs that match Gem.platforms
def self.stubs_for(name)
- specification_record.stubs_for(name)
+ if @@stubs
+ @@stubs_by_name[name] || []
+ else
+ @@stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
+ s.name == name
+ end
+ end
end
##
@@ -821,7 +854,12 @@ class Gem::Specification < Gem::BasicSpecification
# optionally filtering out specs not matching the current platform
#
def self.stubs_for_pattern(pattern, match_platform = true) # :nodoc:
- specification_record.stubs_for_pattern(pattern, match_platform)
+ installed_stubs = installed_stubs(Gem::Specification.dirs, pattern)
+ installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform
+ stubs = installed_stubs + default_stubs(pattern)
+ stubs = stubs.uniq {|stub| stub.full_name }
+ _resort!(stubs)
+ stubs
end
def self._resort!(specs) # :nodoc:
@@ -850,14 +888,23 @@ class Gem::Specification < Gem::BasicSpecification
# properly sorted.
def self.add_spec(spec)
- specification_record.add_spec(spec)
+ return if _all.include? spec
+
+ _all << spec
+ stubs << spec
+ (@@stubs_by_name[spec.name] ||= []) << spec
+
+ _resort!(@@stubs_by_name[spec.name])
+ _resort!(stubs)
end
##
# Removes +spec+ from the known specs.
def self.remove_spec(spec)
- specification_record.remove_spec(spec)
+ _all.delete spec.to_spec
+ stubs.delete spec
+ (@@stubs_by_name[spec.name] || []).delete spec
end
##
@@ -871,17 +918,27 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # Sets the known specs to +specs+.
+ # Sets the known specs to +specs+. Not guaranteed to work for you in
+ # the future. Use at your own risk. Caveat emptor. Doomy doom doom.
+ # Etc etc.
+ #
+ #--
+ # Makes +specs+ the known specs
+ # Listen, time is a river
+ # Winter comes, code breaks
+ #
+ # -- wilsonb
def self.all=(specs)
- specification_record.all = specs
+ @@stubs_by_name = specs.group_by(&:name)
+ @@all = @@stubs = specs
end
##
# Return full names of all specs in sorted order.
def self.all_names
- specification_record.all_names
+ self._all.map(&:full_name)
end
##
@@ -906,7 +963,9 @@ class Gem::Specification < Gem::BasicSpecification
# Return the directories that Specification uses to find specs.
def self.dirs
- @@dirs ||= Gem::SpecificationRecord.dirs_from(Gem.path)
+ @@dirs ||= Gem.path.collect do |dir|
+ File.join dir.dup.tap(&Gem::UNTAINT), "specifications"
+ end
end
##
@@ -914,9 +973,9 @@ class Gem::Specification < Gem::BasicSpecification
# this resets the list of known specs.
def self.dirs=(dirs)
- reset
+ self.reset
- @@dirs = Gem::SpecificationRecord.dirs_from(Array(dirs))
+ @@dirs = Array(dirs).map {|dir| File.join dir, "specifications" }
end
extend Enumerable
@@ -925,15 +984,23 @@ class Gem::Specification < Gem::BasicSpecification
# Enumerate every known spec. See ::dirs= and ::add_spec to set the list of
# specs.
- def self.each(&block)
- specification_record.each(&block)
+ def self.each
+ return enum_for(:each) unless block_given?
+
+ self._all.each do |x|
+ yield x
+ end
end
##
# Returns every spec that matches +name+ and optional +requirements+.
def self.find_all_by_name(name, *requirements)
- specification_record.find_all_by_name(name, *requirements)
+ requirements = Gem::Requirement.default if requirements.empty?
+
+ # TODO: maybe try: find_all { |s| spec === dep }
+
+ Gem::Dependency.new(name, *requirements).matching_specs
end
##
@@ -950,6 +1017,8 @@ class Gem::Specification < Gem::BasicSpecification
def self.find_by_name(name, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
+ # TODO: maybe try: find { |s| spec === dep }
+
Gem::Dependency.new(name, *requirements).to_spec
end
@@ -963,7 +1032,11 @@ class Gem::Specification < Gem::BasicSpecification
# Return the best specification that contains the file matching +path+.
def self.find_by_path(path)
- specification_record.find_by_path(path)
+ path = path.dup.freeze
+ spec = @@spec_with_requirable_file[path] ||= (stubs.find do |s|
+ s.contains_requirable_file? path
+ end || NOT_FOUND)
+ spec.to_spec
end
##
@@ -971,15 +1044,18 @@ class Gem::Specification < Gem::BasicSpecification
# amongst the specs that are not activated.
def self.find_inactive_by_path(path)
- specification_record.find_inactive_by_path(path)
+ stub = stubs.find do |s|
+ next if s.activated?
+ s.contains_requirable_file? path
+ end
+ stub&.to_spec
end
- ##
- # Return the best specification that contains the file matching +path+, among
- # those already activated.
-
def self.find_active_stub_by_path(path)
- specification_record.find_active_stub_by_path(path)
+ stub = @@active_stub_with_requirable_file[path] ||= (stubs.find do |s|
+ s.activated? && s.contains_requirable_file?(path)
+ end || NOT_FOUND)
+ stub.this
end
##
@@ -995,7 +1071,7 @@ class Gem::Specification < Gem::BasicSpecification
def self.find_in_unresolved_tree(path)
unresolved_specs.each do |spec|
- spec.traverse do |_from_spec, _dep, to_spec, trail|
+ spec.traverse do |from_spec, dep, to_spec, trail|
if to_spec.has_conflicts? || to_spec.conficts_when_loaded_with?(trail)
:next
else
@@ -1008,7 +1084,7 @@ class Gem::Specification < Gem::BasicSpecification
end
def self.unresolved_specs
- unresolved_deps.values.map(&:to_specs).flatten
+ unresolved_deps.values.map {|dep| dep.to_specs }.flatten
end
private_class_method :unresolved_specs
@@ -1046,28 +1122,26 @@ class Gem::Specification < Gem::BasicSpecification
# +prerelease+ is true.
def self.latest_specs(prerelease = false)
- specification_record.latest_specs(prerelease)
+ _latest_specs Gem::Specification.stubs, prerelease
end
##
# Return the latest installed spec for gem +name+.
def self.latest_spec_for(name)
- specification_record.latest_spec_for(name)
+ latest_specs(true).find {|installed_spec| installed_spec.name == name }
end
def self._latest_specs(specs, prerelease = false) # :nodoc:
result = {}
specs.reverse_each do |spec|
- unless prerelease
- next if spec.version.prerelease?
- end
+ next if spec.version.prerelease? unless prerelease
result[spec.name] = spec
end
- result.map(&:last).flatten.sort_by(&:name)
+ result.map(&:last).flatten.sort_by {|tup| tup.name }
end
##
@@ -1076,33 +1150,36 @@ class Gem::Specification < Gem::BasicSpecification
def self.load(file)
return unless file
- spec = @load_cache_mutex.synchronize { @load_cache[file] }
- return spec if spec
+ _spec = @load_cache_mutex.synchronize { @load_cache[file] }
+ return _spec if _spec
+ file = file.dup.tap(&Gem::UNTAINT)
return unless File.file?(file)
code = Gem.open_file(file, "r:UTF-8:-", &:read)
+ code.tap(&Gem::UNTAINT)
+
begin
- spec = eval code, binding, file
+ _spec = eval code, binding, file
- if Gem::Specification === spec
- spec.loaded_from = File.expand_path file.to_s
+ if Gem::Specification === _spec
+ _spec.loaded_from = File.expand_path file.to_s
@load_cache_mutex.synchronize do
prev = @load_cache[file]
if prev
- spec = prev
+ _spec = prev
else
- @load_cache[file] = spec
+ @load_cache[file] = _spec
end
end
- return spec
+ return _spec
end
- warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)."
+ warn "[#{file}] isn't a Gem::Specification (#{_spec.class} instead)."
rescue SignalException, SystemExit
raise
- rescue SyntaxError, StandardError => e
+ rescue SyntaxError, Exception => e
warn "Invalid gemspec in [#{file}]: #{e}"
end
@@ -1190,8 +1267,8 @@ class Gem::Specification < Gem::BasicSpecification
def self.reset
@@dirs = nil
- Gem.pre_reset_hooks.each(&:call)
- @specification_record = nil
+ Gem.pre_reset_hooks.each {|hook| hook.call }
+ clear_specs
clear_load_cache
unresolved = unresolved_deps
unless unresolved.empty?
@@ -1209,14 +1286,7 @@ class Gem::Specification < Gem::BasicSpecification
warn "Please report a bug if this causes problems."
unresolved.clear
end
- Gem.post_reset_hooks.each(&:call)
- end
-
- ##
- # Keeps track of all currently known specifications
-
- def self.specification_record
- @specification_record ||= Gem::SpecificationRecord.new(dirs)
+ Gem.post_reset_hooks.each {|hook| hook.call }
end
# DOC: This method needs documented or nodoc'd
@@ -1229,23 +1299,12 @@ class Gem::Specification < Gem::BasicSpecification
def self._load(str)
Gem.load_yaml
- Gem.load_safe_marshal
yaml_set = false
- retry_count = 0
array = begin
- Gem::SafeMarshal.safe_load str
+ Marshal.load str
rescue ArgumentError => e
- # Avoid an infinite retry loop when the argument error has nothing to do
- # with the classes not being defined.
- # 1 retry each allowed in case all 3 of
- # - YAML
- # - YAML::Syck::DefaultKey
- # - YAML::PrivateType
- # need to be defined
- raise if retry_count >= 3
-
#
# Some very old marshaled specs included references to `YAML::PrivateType`
# and `YAML::Syck::DefaultKey` constants due to bugs in the old emitter
@@ -1263,12 +1322,11 @@ class Gem::Specification < Gem::BasicSpecification
if message.include?("YAML::Syck::")
YAML.const_set "Syck", YAML unless YAML.const_defined?(:Syck)
- YAML::Syck.const_set "DefaultKey", Class.new if message.include?("YAML::Syck::DefaultKey") && !YAML::Syck.const_defined?(:DefaultKey)
- elsif message.include?("YAML::PrivateType") && !YAML.const_defined?(:PrivateType)
+ YAML::Syck.const_set "DefaultKey", Class.new if message.include?("YAML::Syck::DefaultKey")
+ elsif message.include?("YAML::PrivateType")
YAML.const_set "PrivateType", Class.new
end
- retry_count += 1
retry
ensure
Object.__send__(:remove_const, "YAML") if yaml_set
@@ -1365,7 +1423,7 @@ class Gem::Specification < Gem::BasicSpecification
# there are conflicts upon activation.
def activate
- other = Gem.loaded_specs[name]
+ other = Gem.loaded_specs[self.name]
if other
check_version_conflict other
return false
@@ -1376,11 +1434,11 @@ class Gem::Specification < Gem::BasicSpecification
activate_dependencies
add_self_to_load_path
- Gem.loaded_specs[name] = self
+ Gem.loaded_specs[self.name] = self
@activated = true
@loaded = true
- true
+ return true
end
##
@@ -1391,7 +1449,7 @@ class Gem::Specification < Gem::BasicSpecification
def activate_dependencies
unresolved = Gem::Specification.unresolved_deps
- runtime_dependencies.each do |spec_dep|
+ self.runtime_dependencies.each do |spec_dep|
if loaded = Gem.loaded_specs[spec_dep.name]
next if spec_dep.matches_spec? loaded
@@ -1405,7 +1463,7 @@ class Gem::Specification < Gem::BasicSpecification
begin
specs = spec_dep.to_specs
rescue Gem::MissingSpecError => e
- raise Gem::MissingSpecError.new(e.name, e.requirement, "at: #{spec_file}")
+ raise Gem::MissingSpecError.new(e.name, e.requirement, "at: #{self.spec_file}")
end
if specs.size == 1
@@ -1451,7 +1509,7 @@ class Gem::Specification < Gem::BasicSpecification
def sanitize_string(string)
return string unless string
- # HACK: the #to_s is in here because RSpec has an Array of Arrays of
+ # HACK the #to_s is in here because RSpec has an Array of Arrays of
# Strings for authors. Need a way to disallow bad values on gemspec
# generation. (Probably won't happen.)
string.to_s
@@ -1469,8 +1527,8 @@ class Gem::Specification < Gem::BasicSpecification
else
executables
end
- rescue StandardError
- nil
+ rescue
+ return nil
end
##
@@ -1495,7 +1553,7 @@ class Gem::Specification < Gem::BasicSpecification
private :add_dependency_with_type
- alias_method :add_dependency, :add_runtime_dependency
+ alias add_dependency add_runtime_dependency
##
# Adds this spec's require paths to LOAD_PATH, in the proper location.
@@ -1547,7 +1605,7 @@ class Gem::Specification < Gem::BasicSpecification
def build_args
if File.exist? build_info_file
build_info = File.readlines build_info_file
- build_info = build_info.map(&:strip)
+ build_info = build_info.map {|x| x.strip }
build_info.delete ""
build_info
else
@@ -1565,8 +1623,8 @@ class Gem::Specification < Gem::BasicSpecification
# we need to fresh build when same name and version of default gems
return if self.class.find_by_full_name(full_name)&.default_gem?
return if File.exist? gem_build_complete_path
- return unless File.writable?(base_dir)
- return unless File.exist?(File.join(base_dir, "extensions"))
+ return if !File.writable?(base_dir)
+ return if !File.exist?(File.join(base_dir, "extensions"))
begin
# We need to require things in $LOAD_PATH without looking for the
@@ -1624,7 +1682,7 @@ class Gem::Specification < Gem::BasicSpecification
def conflicts
conflicts = {}
- runtime_dependencies.each do |dep|
+ self.runtime_dependencies.each do |dep|
spec = Gem.loaded_specs[dep.name]
if spec && !spec.satisfies_requirement?(dep)
(conflicts[spec] ||= []) << dep
@@ -1640,7 +1698,7 @@ class Gem::Specification < Gem::BasicSpecification
def conficts_when_loaded_with?(list_of_specs) # :nodoc:
result = list_of_specs.any? do |spec|
- spec.runtime_dependencies.any? {|dep| (dep.name == name) && !satisfies_requirement?(dep) }
+ spec.dependencies.any? {|dep| dep.runtime? && (dep.name == name) && !satisfies_requirement?(dep) }
end
result
end
@@ -1650,12 +1708,14 @@ class Gem::Specification < Gem::BasicSpecification
def has_conflicts?
return true unless Gem.env_requirement(name).satisfied_by?(version)
- runtime_dependencies.any? do |dep|
- spec = Gem.loaded_specs[dep.name]
- spec && !spec.satisfies_requirement?(dep)
+ self.dependencies.any? do |dep|
+ if dep.runtime?
+ spec = Gem.loaded_specs[dep.name]
+ spec && !spec.satisfies_requirement?(dep)
+ else
+ false
+ end
end
- rescue ArgumentError => e
- raise e, "#{name} #{version}: #{e.message}"
end
# The date this gem was created.
@@ -1679,7 +1739,7 @@ class Gem::Specification < Gem::BasicSpecification
/\A
(\d{4})-(\d{2})-(\d{2})
(\s+ \d{2}:\d{2}:\d{2}\.\d+ \s* (Z | [-+]\d\d:\d\d) )?
- \Z/x
+ \Z/x.freeze
##
# The date this gem was created
@@ -1691,17 +1751,17 @@ class Gem::Specification < Gem::BasicSpecification
# This is the cleanest, most-readable, faster-than-using-Date
# way to do it.
@date = case date
- when String then
- if DateTimeFormat =~ date
- Time.utc($1.to_i, $2.to_i, $3.to_i)
- else
- raise(Gem::InvalidSpecificationException,
- "invalid date format in specification: #{date.inspect}")
- end
- when Time, DateLike then
- Time.utc(date.year, date.month, date.day)
- else
- TODAY
+ when String then
+ if DateTimeFormat =~ date
+ Time.utc($1.to_i, $2.to_i, $3.to_i)
+ else
+ raise(Gem::InvalidSpecificationException,
+ "invalid date format in specification: #{date.inspect}")
+ end
+ when Time, DateLike then
+ Time.utc(date.year, date.month, date.day)
+ else
+ TODAY
end
end
@@ -1751,12 +1811,13 @@ class Gem::Specification < Gem::BasicSpecification
Gem::Specification.each do |spec|
deps = check_dev ? spec.dependencies : spec.runtime_dependencies
deps.each do |dep|
- next unless satisfies_requirement?(dep)
- sats = []
- find_all_satisfiers(dep) do |sat|
- sats << sat
+ if self.satisfies_requirement?(dep)
+ sats = []
+ find_all_satisfiers(dep) do |sat|
+ sats << sat
+ end
+ out << [spec, dep, sats]
end
- out << [spec, dep, sats]
end
end
out
@@ -1766,7 +1827,7 @@ class Gem::Specification < Gem::BasicSpecification
# Returns all specs that matches this spec's runtime dependencies.
def dependent_specs
- runtime_dependencies.map(&:to_specs).flatten
+ runtime_dependencies.map {|dep| dep.to_specs }.flatten
end
##
@@ -1802,15 +1863,17 @@ class Gem::Specification < Gem::BasicSpecification
end
def encode_with(coder) # :nodoc:
+ mark_version
+
coder.add "name", @name
coder.add "version", @version
platform = case @original_platform
- when nil, "" then
- "ruby"
- when String then
- @original_platform
- else
- @original_platform.to_s
+ when nil, "" then
+ "ruby"
+ when String then
+ @original_platform
+ else
+ @original_platform.to_s
end
coder.add "platform", platform
@@ -1933,7 +1996,7 @@ class Gem::Specification < Gem::BasicSpecification
end
rubygems_deprecate :has_rdoc=
- alias_method :has_rdoc?, :has_rdoc # :nodoc:
+ alias :has_rdoc? :has_rdoc # :nodoc:
rubygems_deprecate :has_rdoc?
##
@@ -1944,7 +2007,7 @@ class Gem::Specification < Gem::BasicSpecification
end
# :stopdoc:
- alias_method :has_test_suite?, :has_unit_tests?
+ alias has_test_suite? has_unit_tests?
# :startdoc:
def hash # :nodoc:
@@ -2001,8 +2064,7 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # Duplicates Array and Gem::Requirement attributes from +other_spec+ so state isn't shared.
- #
+ # Duplicates array_attributes from +other_spec+ so state isn't shared.
def initialize_copy(other_spec)
self.class.array_attributes.each do |name|
@@ -2024,9 +2086,6 @@ class Gem::Specification < Gem::BasicSpecification
raise e
end
end
-
- @required_ruby_version = other_spec.required_ruby_version.dup
- @required_rubygems_version = other_spec.required_rubygems_version.dup
end
def base_dir
@@ -2096,6 +2155,13 @@ class Gem::Specification < Gem::BasicSpecification
end
##
+ # Sets the rubygems_version to the current RubyGems version.
+
+ def mark_version
+ @rubygems_version = Gem::VERSION
+ end
+
+ ##
# Track removed method calls to warn about during build time.
# Warn about unknown attributes while loading a spec.
@@ -2188,22 +2254,23 @@ class Gem::Specification < Gem::BasicSpecification
attributes.unshift :name
attributes.each do |attr_name|
- current_value = send attr_name
- current_value = current_value.sort if [:files, :test_files].include? attr_name
- next unless current_value != default_value(attr_name) ||
- self.class.required_attribute?(attr_name)
+ current_value = self.send attr_name
+ current_value = current_value.sort if %i[files test_files].include? attr_name
+ if current_value != default_value(attr_name) ||
+ self.class.required_attribute?(attr_name)
- q.text "s.#{attr_name} = "
+ q.text "s.#{attr_name} = "
- if attr_name == :date
- current_value = current_value.utc
+ if attr_name == :date
+ current_value = current_value.utc
- q.text "Time.utc(#{current_value.year}, #{current_value.month}, #{current_value.day})"
- else
- q.pp current_value
- end
+ q.text "Time.utc(#{current_value.year}, #{current_value.month}, #{current_value.day})"
+ else
+ q.pp current_value
+ end
- q.breakable
+ q.breakable
+ end
end
end
end
@@ -2213,7 +2280,7 @@ class Gem::Specification < Gem::BasicSpecification
# that is already loaded (+other+)
def check_version_conflict(other) # :nodoc:
- return if version == other.version
+ return if self.version == other.version
# This gem is already loaded. If the currently loaded gem is not in the
# list of candidate gems, then we have a version conflict.
@@ -2221,7 +2288,7 @@ class Gem::Specification < Gem::BasicSpecification
msg = "can't activate #{full_name}, already activated #{other.full_name}"
e = Gem::LoadError.new msg
- e.name = name
+ e.name = self.name
raise e
end
@@ -2286,13 +2353,13 @@ class Gem::Specification < Gem::BasicSpecification
when Array then "[" + obj.map {|x| ruby_code x }.join(", ") + "]"
when Hash then
seg = obj.keys.sort.map {|k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" }
- "{ #{seg.join(", ")} }"
- when Gem::Version then ruby_code(obj.to_s)
+ "{ #{seg.join(', ')} }"
+ when Gem::Version then obj.to_s.dump
when DateLike then obj.strftime("%Y-%m-%d").dump
when Time then obj.strftime("%Y-%m-%d").dump
when Numeric then obj.inspect
when true, false, nil then obj.inspect
- when Gem::Platform then "Gem::Platform.new(#{ruby_code obj.to_a})"
+ when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
when Gem::Requirement then
list = obj.as_list
"Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})"
@@ -2313,7 +2380,7 @@ class Gem::Specification < Gem::BasicSpecification
# True if this gem has the same attributes as +other+.
def same_attributes?(spec)
- @@attributes.all? {|name, _default| send(name) == spec.send(name) }
+ @@attributes.all? {|name, default| self.send(name) == spec.send(name) }
end
private :same_attributes?
@@ -2322,8 +2389,8 @@ class Gem::Specification < Gem::BasicSpecification
# Checks if this specification meets the requirement of +dependency+.
def satisfies_requirement?(dependency)
- @name == dependency.name &&
- dependency.requirement.satisfied_by?(@version)
+ return @name == dependency.name &&
+ dependency.requirement.satisfied_by?(@version)
end
##
@@ -2412,6 +2479,7 @@ class Gem::Specification < Gem::BasicSpecification
# still have their default values are omitted.
def to_ruby
+ mark_version
result = []
result << "# -*- encoding: utf-8 -*-"
result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{raw_require_paths.join("\0")}"
@@ -2449,19 +2517,19 @@ class Gem::Specification < Gem::BasicSpecification
@@attributes.each do |attr_name|
next if handled.include? attr_name
- current_value = send(attr_name)
+ current_value = self.send(attr_name)
if current_value != default_value(attr_name) || self.class.required_attribute?(attr_name)
result << " s.#{attr_name} = #{ruby_code current_value}"
end
end
if String === signing_key
- result << " s.signing_key = #{ruby_code signing_key}"
+ result << " s.signing_key = #{signing_key.dump}.freeze"
end
if @installed_by_version
result << nil
- result << " s.installed_by_version = #{ruby_code Gem::VERSION} if s.respond_to? :installed_by_version"
+ result << " s.installed_by_version = \"#{Gem::VERSION}\" if s.respond_to? :installed_by_version"
end
unless dependencies.empty?
@@ -2470,8 +2538,9 @@ class Gem::Specification < Gem::BasicSpecification
result << nil
dependencies.each do |dep|
+ req = dep.requirements_list.inspect
dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
- result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{ruby_code dep.requirements_list})"
+ result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{req})"
end
end
@@ -2532,9 +2601,10 @@ class Gem::Specification < Gem::BasicSpecification
def traverse(trail = [], visited = {}, &block)
trail.push(self)
begin
- runtime_dependencies.each do |dep|
+ dependencies.each do |dep|
+ next unless dep.runtime?
dep.matching_specs(true).each do |dep_spec|
- next if visited.key?(dep_spec)
+ next if visited.has_key?(dep_spec)
visited[dep_spec] = true
trail.push(dep_spec)
begin
@@ -2542,10 +2612,11 @@ class Gem::Specification < Gem::BasicSpecification
ensure
trail.pop
end
- next if result == :next
- spec_name = dep_spec.name
- dep_spec.traverse(trail, visited, &block) unless
- trail.any? {|s| s.name == spec_name }
+ unless result == :next
+ spec_name = dep_spec.name
+ dep_spec.traverse(trail, visited, &block) unless
+ trail.any? {|s| s.name == spec_name }
+ end
end
end
ensure
@@ -2592,13 +2663,22 @@ class Gem::Specification < Gem::BasicSpecification
rubygems_deprecate :validate_permissions
##
- # Set the version to +version+.
+ # Set the version to +version+, potentially also setting
+ # required_rubygems_version if +version+ indicates it is a
+ # prerelease.
def version=(version)
@version = Gem::Version.create(version)
return if @version.nil?
+ # skip to set required_ruby_version when pre-released rubygems.
+ # It caused to raise CircularDependencyError
+ if @version.prerelease? && (@name.nil? || @name.strip != "rubygems")
+ self.required_rubygems_version = "> 1.3.1"
+ end
invalidate_memoized_attributes
+
+ return @version
end
def stubbed?
@@ -2610,9 +2690,9 @@ class Gem::Specification < Gem::BasicSpecification
case ivar
when "date"
# Force Date to go through the extra coerce logic in date=
- self.date = val
+ self.date = val.tap(&Gem::UNTAINT)
else
- instance_variable_set "@#{ivar}", val
+ instance_variable_set "@#{ivar}", val.tap(&Gem::UNTAINT)
end
end
@@ -2629,11 +2709,11 @@ class Gem::Specification < Gem::BasicSpecification
end
nil_attributes.each do |attribute|
- default = default_value attribute
+ default = self.default_value attribute
value = case default
- when Time, Numeric, Symbol, true, false, nil then default
- else default.dup
+ when Time, Numeric, Symbol, true, false, nil then default
+ else default.dup
end
instance_variable_set "@#{attribute}", value
diff --git a/lib/rubygems/specification_policy.rb b/lib/rubygems/specification_policy.rb
index 812b0f889e..cee7eb3fdc 100644
--- a/lib/rubygems/specification_policy.rb
+++ b/lib/rubygems/specification_policy.rb
@@ -5,21 +5,20 @@ require_relative "user_interaction"
class Gem::SpecificationPolicy
include Gem::UserInteraction
- VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
+ VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/.freeze # :nodoc:
- SPECIAL_CHARACTERS = /\A[#{Regexp.escape(".-_")}]+/ # :nodoc:
+ SPECIAL_CHARACTERS = /\A[#{Regexp.escape('.-_')}]+/.freeze # :nodoc:
- VALID_URI_PATTERN = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z} # :nodoc:
+ VALID_URI_PATTERN = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}.freeze # :nodoc:
METADATA_LINK_KEYS = %w[
- homepage_uri
+ bug_tracker_uri
changelog_uri
- source_code_uri
documentation_uri
- wiki_uri
+ homepage_uri
mailing_list_uri
- bug_tracker_uri
- download_uri
+ source_code_uri
+ wiki_uri
funding_uri
].freeze # :nodoc:
@@ -103,14 +102,10 @@ class Gem::SpecificationPolicy
validate_dependencies
- validate_required_ruby_version
-
validate_extensions
validate_removed_attributes
- validate_unique_links
-
if @warnings > 0
if strict
error "specification has warnings"
@@ -132,7 +127,7 @@ class Gem::SpecificationPolicy
metadata.each do |key, value|
entry = "metadata['#{key}']"
- unless key.is_a?(String)
+ if !key.kind_of?(String)
error "metadata keys must be a String"
end
@@ -140,7 +135,7 @@ class Gem::SpecificationPolicy
error "metadata key is too large (#{key.size} > 128)"
end
- unless value.is_a?(String)
+ if !value.kind_of?(String)
error "#{entry} value must be a String"
end
@@ -148,9 +143,10 @@ class Gem::SpecificationPolicy
error "#{entry} value is too large (#{value.size} > 1024)"
end
- next unless METADATA_LINK_KEYS.include? key
- unless VALID_URI_PATTERN.match?(value)
- error "#{entry} has invalid link: #{value.inspect}"
+ if METADATA_LINK_KEYS.include? key
+ if value !~ VALID_URI_PATTERN
+ error "#{entry} has invalid link: #{value.inspect}"
+ end
end
end
end
@@ -167,7 +163,7 @@ class Gem::SpecificationPolicy
if prev = seen[dep.type][dep.name]
error_messages << <<-MESSAGE
duplicate dependency on #{dep}, (#{prev.requirement}) use:
- add_#{dep.type}_dependency \"#{dep.name}\", \"#{dep.requirement}\", \"#{prev.requirement}\"
+ add_#{dep.type}_dependency '#{dep.name}', '#{dep.requirement}', '#{prev.requirement}'
MESSAGE
end
@@ -199,42 +195,37 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
prerelease_dep && !@specification.version.prerelease?
open_ended = dep.requirement.requirements.all? do |op, version|
- !version.prerelease? && [">", ">="].include?(op)
+ !version.prerelease? && (op == ">" || op == ">=")
end
- next unless open_ended
- op, dep_version = dep.requirement.requirements.first
+ if open_ended
+ op, dep_version = dep.requirement.requirements.first
- segments = dep_version.segments
+ segments = dep_version.segments
- base = segments.first 2
+ base = segments.first 2
- recommendation = if [">", ">="].include?(op) && segments == [0]
- " use a bounded requirement, such as \"~> x.y\""
- else
- bugfix = if op == ">"
- ", \"> #{dep_version}\""
- elsif op == ">=" && base != segments
- ", \">= #{dep_version}\""
+ recommendation = if (op == ">" || op == ">=") && segments == [0]
+ " use a bounded requirement, such as '~> x.y'"
+ else
+ bugfix = if op == ">"
+ ", '> #{dep_version}'"
+ elsif op == ">=" && base != segments
+ ", '>= #{dep_version}'"
+ end
+
+ " if #{dep.name} is semantically versioned, use:\n" \
+ " add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}'#{bugfix}"
end
- " if #{dep.name} is semantically versioned, use:\n" \
- " add_#{dep.type}_dependency \"#{dep.name}\", \"~> #{base.join "."}\"#{bugfix}"
+ warning_messages << ["open-ended dependency on #{dep} is not recommended", recommendation].join("\n") + "\n"
end
-
- warning_messages << ["open-ended dependency on #{dep} is not recommended", recommendation].join("\n") + "\n"
end
if warning_messages.any?
warning_messages.each {|warning_message| warning warning_message }
end
end
- def validate_required_ruby_version
- if @specification.required_ruby_version.requirements == [Gem::Requirement::DefaultRequirement]
- warning "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"
- end
- end
-
##
# Issues a warning for each file to be packaged which is world-readable.
#
@@ -245,7 +236,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
@specification.files.each do |file|
next unless File.file?(file)
- next if File.stat(file).mode & 0o444 == 0o444
+ next if File.stat(file).mode & 0444 == 0444
warning "#{file} is not world-readable"
end
@@ -264,7 +255,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
@specification.instance_variable_get("@#{attrname}").nil?
end
return if nil_attributes.empty?
- error "#{nil_attributes.join ", "} must not be nil"
+ error "#{nil_attributes.join ', '} must not be nil"
end
def validate_rubygems_version
@@ -274,9 +265,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
return if rubygems_version == Gem::VERSION
- warning "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
-
- @specification.rubygems_version = Gem::VERSION
+ error "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
end
def validate_required_attributes
@@ -292,11 +281,11 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
if !name.is_a?(String)
error "invalid value for attribute name: \"#{name.inspect}\" must be a string"
- elsif !/[a-zA-Z]/.match?(name)
+ elsif name !~ /[a-zA-Z]/
error "invalid value for attribute name: #{name.dump} must include at least one letter"
- elsif !VALID_NAME_PATTERN.match?(name)
+ elsif name !~ VALID_NAME_PATTERN
error "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
- elsif SPECIAL_CHARACTERS.match?(name)
+ elsif name =~ SPECIAL_CHARACTERS
error "invalid value for attribute name: #{name.dump} can not begin with a period, dash, or underscore"
end
end
@@ -350,13 +339,13 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
def validate_array_attribute(field)
val = @specification.send(field)
klass = case field
- when :dependencies then
- Gem::Dependency
- else
- String
+ when :dependencies then
+ Gem::Dependency
+ else
+ String
end
- unless Array === val && val.all? {|x| x.is_a?(klass) || (field == :licenses && x.nil?) }
+ unless Array === val && val.all? {|x| x.kind_of?(klass) }
error "#{field} must be an Array of #{klass}"
end
end
@@ -371,8 +360,6 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
licenses = @specification.licenses
licenses.each do |license|
- next if license.nil?
-
if license.length > 64
error "each license must be 64 characters or less"
end
@@ -383,38 +370,26 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
licenses = @specification.licenses
licenses.each do |license|
- next if Gem::Licenses.match?(license) || license.nil?
- license_id_deprecated = Gem::Licenses.deprecated_license_id?(license)
- exception_id_deprecated = Gem::Licenses.deprecated_exception_id?(license)
- suggestions = Gem::Licenses.suggestions(license)
-
- if license_id_deprecated
- main_message = "License identifier '#{license}' is deprecated"
- elsif exception_id_deprecated
- main_message = "Exception identifier at '#{license}' is deprecated"
- else
- main_message = "License identifier '#{license}' is invalid"
+ if !Gem::Licenses.match?(license)
+ suggestions = Gem::Licenses.suggestions(license)
+ message = <<-WARNING
+license value '#{license}' is invalid. Use a license identifier from
+http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
+ WARNING
+ message += "Did you mean #{suggestions.map {|s| "'#{s}'" }.join(', ')}?\n" unless suggestions.nil?
+ warning(message)
end
-
- message = <<-WARNING
-#{main_message}. Use an identifier from
-https://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license,
-or set it to nil if you don't want to specify a license.
- WARNING
- message += "Did you mean #{suggestions.map {|s| "'#{s}'" }.join(", ")}?\n" unless suggestions.nil?
- warning(message)
end
warning <<-WARNING if licenses.empty?
-licenses is empty, but is recommended. Use an license identifier from
-https://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license,
-or set it to nil if you don't want to specify a license.
+licenses is empty, but is recommended. Use a license identifier from
+http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
WARNING
end
LAZY = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, "")
- LAZY_PATTERN = /\AFI XME|\ATO DO/x
- HOMEPAGE_URI_PATTERN = /\A[a-z][a-z\d+.-]*:/i
+ LAZY_PATTERN = /\AFI XME|\ATO DO/x.freeze
+ HOMEPAGE_URI_PATTERN = /\A[a-z][a-z\d+.-]*:/i.freeze
def validate_lazy_metadata
unless @specification.authors.grep(LAZY_PATTERN).empty?
@@ -425,11 +400,11 @@ or set it to nil if you don't want to specify a license.
error "#{LAZY} is not an email"
end
- if LAZY_PATTERN.match?(@specification.description)
+ if @specification.description =~ LAZY_PATTERN
error "#{LAZY} is not a description"
end
- if LAZY_PATTERN.match?(@specification.summary)
+ if @specification.summary =~ LAZY_PATTERN
error "#{LAZY} is not a summary"
end
@@ -437,13 +412,13 @@ or set it to nil if you don't want to specify a license.
# Make sure a homepage is valid HTTP/HTTPS URI
if homepage && !homepage.empty?
- require_relative "vendor/uri/lib/uri"
+ require "uri"
begin
- homepage_uri = Gem::URI.parse(homepage)
- unless [Gem::URI::HTTP, Gem::URI::HTTPS].member? homepage_uri.class
+ homepage_uri = URI.parse(homepage)
+ unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class
error "\"#{homepage}\" is not a valid HTTP URI"
end
- rescue Gem::URI::InvalidURIError
+ rescue URI::InvalidURIError
error "\"#{homepage}\" is not a valid HTTP URI"
end
end
@@ -507,29 +482,13 @@ You have specified rust based extension, but Cargo.lock is not part of the gem f
def validate_rake_extensions(builder) # :nodoc:
rake_extension = @specification.extensions.any? {|s| builder.builder_for(s) == Gem::Ext::RakeBuilder }
- rake_dependency = @specification.dependencies.any? {|d| d.name == "rake" && d.type == :runtime }
+ rake_dependency = @specification.dependencies.any? {|d| d.name == "rake" }
warning <<-WARNING if rake_extension && !rake_dependency
-You have specified rake based extension, but rake is not added as runtime dependency. It is recommended to add rake as a runtime dependency in gemspec since there's no guarantee rake will be already installed.
+You have specified rake based extension, but rake is not added as dependency. It is recommended to add rake as a dependency in gemspec since there's no guarantee rake will be already installed.
WARNING
end
- def validate_unique_links
- links = @specification.metadata.slice(*METADATA_LINK_KEYS)
- grouped = links.group_by {|_key, uri| uri }
- grouped.each do |uri, copies|
- next unless copies.length > 1
- keys = copies.map(&:first).join("\n ")
- warning <<~WARNING
- You have specified the uri:
- #{uri}
- for all of the following keys:
- #{keys}
- Only the first one will be shown on rubygems.org
- WARNING
- end
- end
-
def warning(statement) # :nodoc:
@warnings += 1
diff --git a/lib/rubygems/specification_record.rb b/lib/rubygems/specification_record.rb
deleted file mode 100644
index dd6aa7eafa..0000000000
--- a/lib/rubygems/specification_record.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-# frozen_string_literal: true
-
-module Gem
- class SpecificationRecord
- def self.dirs_from(paths)
- paths.map do |path|
- File.join(path, "specifications")
- end
- end
-
- def self.from_path(path)
- new(dirs_from([path]))
- end
-
- def initialize(dirs)
- @all = nil
- @stubs = nil
- @stubs_by_name = {}
- @spec_with_requirable_file = {}
- @active_stub_with_requirable_file = {}
-
- @dirs = dirs
- end
-
- # Sentinel object to represent "not found" stubs
- NOT_FOUND = Struct.new(:to_spec, :this).new
- private_constant :NOT_FOUND
-
- ##
- # Returns the list of all specifications in the record
-
- def all
- @all ||= Gem.loaded_specs.values | stubs.map(&:to_spec)
- end
-
- ##
- # Returns a Gem::StubSpecification for every specification in the record
-
- def stubs
- @stubs ||= begin
- pattern = "*.gemspec"
- stubs = stubs_for_pattern(pattern, false)
-
- @stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name)
- stubs
- end
- end
-
- ##
- # Returns a Gem::StubSpecification for every specification in the record
- # named +name+ only returns stubs that match Gem.platforms
-
- def stubs_for(name)
- if @stubs
- @stubs_by_name[name] || []
- else
- @stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
- s.name == name
- end
- end
- end
-
- ##
- # Finds stub specifications matching a pattern in the record, optionally
- # filtering out specs not matching the current platform
-
- def stubs_for_pattern(pattern, match_platform = true)
- installed_stubs = installed_stubs(pattern)
- installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform
- stubs = installed_stubs + Gem::Specification.default_stubs(pattern)
- stubs = stubs.uniq(&:full_name)
- Gem::Specification._resort!(stubs)
- stubs
- end
-
- ##
- # Adds +spec+ to the the record, keeping the collection properly sorted.
-
- def add_spec(spec)
- return if all.include? spec
-
- all << spec
- stubs << spec
- (@stubs_by_name[spec.name] ||= []) << spec
-
- Gem::Specification._resort!(@stubs_by_name[spec.name])
- Gem::Specification._resort!(stubs)
- end
-
- ##
- # Removes +spec+ from the record.
-
- def remove_spec(spec)
- all.delete spec.to_spec
- stubs.delete spec
- (@stubs_by_name[spec.name] || []).delete spec
- end
-
- ##
- # Sets the specs known by the record to +specs+.
-
- def all=(specs)
- @stubs_by_name = specs.group_by(&:name)
- @all = @stubs = specs
- end
-
- ##
- # Return full names of all specs in the record in sorted order.
-
- def all_names
- all.map(&:full_name)
- end
-
- include Enumerable
-
- ##
- # Enumerate every known spec.
-
- def each
- return enum_for(:each) unless block_given?
-
- all.each do |x|
- yield x
- end
- end
-
- ##
- # Returns every spec in the record that matches +name+ and optional +requirements+.
-
- def find_all_by_name(name, *requirements)
- req = Gem::Requirement.create(*requirements)
- env_req = Gem.env_requirement(name)
-
- matches = stubs_for(name).find_all do |spec|
- req.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
- end.map(&:to_spec)
-
- if name == "bundler" && !req.specific?
- require_relative "bundler_version_finder"
- Gem::BundlerVersionFinder.prioritize!(matches)
- end
-
- matches
- end
-
- ##
- # Return the best specification in the record that contains the file matching +path+.
-
- def find_by_path(path)
- path = path.dup.freeze
- spec = @spec_with_requirable_file[path] ||= stubs.find do |s|
- s.contains_requirable_file? path
- end || NOT_FOUND
-
- spec.to_spec
- end
-
- ##
- # Return the best specification in the record that contains the file
- # matching +path+ amongst the specs that are not activated.
-
- def find_inactive_by_path(path)
- stub = stubs.find do |s|
- next if s.activated?
- s.contains_requirable_file? path
- end
- stub&.to_spec
- end
-
- ##
- # Return the best specification in the record that contains the file
- # matching +path+, among those already activated.
-
- def find_active_stub_by_path(path)
- stub = @active_stub_with_requirable_file[path] ||= stubs.find do |s|
- s.activated? && s.contains_requirable_file?(path)
- end || NOT_FOUND
-
- stub.this
- end
-
- ##
- # Return the latest specs in the record, optionally including prerelease
- # specs if +prerelease+ is true.
-
- def latest_specs(prerelease)
- Gem::Specification._latest_specs stubs, prerelease
- end
-
- ##
- # Return the latest installed spec in the record for gem +name+.
-
- def latest_spec_for(name)
- latest_specs(true).find {|installed_spec| installed_spec.name == name }
- end
-
- private
-
- def installed_stubs(pattern)
- map_stubs(pattern) do |path, base_dir, gems_dir|
- Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
- end
- end
-
- def map_stubs(pattern)
- @dirs.flat_map do |dir|
- base_dir = File.dirname dir
- gems_dir = File.join base_dir, "gems"
- Gem::Specification.gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir }
- end
- end
- end
-end
diff --git a/lib/rubygems/stub_specification.rb b/lib/rubygems/stub_specification.rb
index 58748df5d6..d64d611f48 100644
--- a/lib/rubygems/stub_specification.rb
+++ b/lib/rubygems/stub_specification.rb
@@ -35,7 +35,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
def initialize(data, extensions)
parts = data[PREFIX.length..-1].split(" ", 4)
- @name = -parts[0]
+ @name = parts[0].freeze
@version = if Gem::Version.correct?(parts[1])
Gem::Version.new(parts[1])
else
@@ -69,6 +69,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
def initialize(filename, base_dir, gems_dir, default_gem)
super()
+ filename.tap(&Gem::UNTAINT)
self.loaded_from = filename
@data = nil
@@ -84,10 +85,10 @@ class Gem::StubSpecification < Gem::BasicSpecification
def activated?
@activated ||=
- begin
- loaded = Gem.loaded_specs[name]
- loaded && loaded.version == version
- end
+ begin
+ loaded = Gem.loaded_specs[name]
+ loaded && loaded.version == version
+ end
end
def default_gem?
@@ -111,23 +112,20 @@ class Gem::StubSpecification < Gem::BasicSpecification
saved_lineno = $.
Gem.open_file loaded_from, OPEN_MODE do |file|
- file.readline # discard encoding line
- stubline = file.readline
- if stubline.start_with?(PREFIX)
- extline = file.readline
-
- extensions =
- if extline.delete_prefix!(PREFIX)
- extline.chomp!
- extline.split "\0"
+ begin
+ file.readline # discard encoding line
+ stubline = file.readline.chomp
+ if stubline.start_with?(PREFIX)
+ extensions = if /\A#{PREFIX}/ =~ file.readline.chomp
+ $'.split "\0"
else
StubLine::NO_EXTENSIONS
end
- stubline.chomp! # readline(chomp: true) allocates 3x as much as .readline.chomp!
- @data = StubLine.new stubline, extensions
+ @data = StubLine.new stubline, extensions
+ end
+ rescue EOFError
end
- rescue EOFError
end
ensure
$. = saved_lineno
diff --git a/lib/rubygems/text.rb b/lib/rubygems/text.rb
index da0795b771..be811525f2 100644
--- a/lib/rubygems/text.rb
+++ b/lib/rubygems/text.rb
@@ -4,6 +4,7 @@
# A collection of text-wrangling methods
module Gem::Text
+
##
# Remove any non-printable characters and make the text suitable for
# printing.
@@ -66,7 +67,7 @@ module Gem::Text
str1.each_codepoint.with_index(1) do |char1, i|
j = 0
while j < m
- cost = char1 == str2_codepoints[j] ? 0 : 1
+ cost = (char1 == str2_codepoints[j]) ? 0 : 1
x = min3(
d[j + 1] + 1, # insertion
i + 1, # deletion
diff --git a/lib/rubygems/tsort.rb b/lib/rubygems/tsort.rb
new file mode 100644
index 0000000000..60ebe22e81
--- /dev/null
+++ b/lib/rubygems/tsort.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require_relative "tsort/lib/tsort"
diff --git a/lib/bundler/vendor/fileutils/.document b/lib/rubygems/tsort/.document
index 0c43bbd6b3..0c43bbd6b3 100644
--- a/lib/bundler/vendor/fileutils/.document
+++ b/lib/rubygems/tsort/.document
diff --git a/lib/rubygems/tsort/lib/tsort.rb b/lib/rubygems/tsort/lib/tsort.rb
new file mode 100644
index 0000000000..f825f14257
--- /dev/null
+++ b/lib/rubygems/tsort/lib/tsort.rb
@@ -0,0 +1,452 @@
+# frozen_string_literal: true
+
+#--
+# tsort.rb - provides a module for topological sorting and strongly connected components.
+#++
+#
+
+#
+# Gem::TSort implements topological sorting using Tarjan's algorithm for
+# strongly connected components.
+#
+# Gem::TSort is designed to be able to be used with any object which can be
+# interpreted as a directed graph.
+#
+# Gem::TSort requires two methods to interpret an object as a graph,
+# tsort_each_node and tsort_each_child.
+#
+# * tsort_each_node is used to iterate for all nodes over a graph.
+# * tsort_each_child is used to iterate for child nodes of a given node.
+#
+# The equality of nodes are defined by eql? and hash since
+# Gem::TSort uses Hash internally.
+#
+# == A Simple Example
+#
+# The following example demonstrates how to mix the Gem::TSort module into an
+# existing class (in this case, Hash). Here, we're treating each key in
+# the hash as a node in the graph, and so we simply alias the required
+# #tsort_each_node method to Hash's #each_key method. For each key in the
+# hash, the associated value is an array of the node's child nodes. This
+# choice in turn leads to our implementation of the required #tsort_each_child
+# method, which fetches the array of child nodes and then iterates over that
+# array using the user-supplied block.
+#
+# require 'rubygems/tsort/lib/tsort'
+#
+# class Hash
+# include Gem::TSort
+# alias tsort_each_node each_key
+# def tsort_each_child(node, &block)
+# fetch(node).each(&block)
+# end
+# end
+#
+# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
+# #=> [3, 2, 1, 4]
+#
+# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
+# #=> [[4], [2, 3], [1]]
+#
+# == A More Realistic Example
+#
+# A very simple `make' like tool can be implemented as follows:
+#
+# require 'rubygems/tsort/lib/tsort'
+#
+# class Make
+# def initialize
+# @dep = {}
+# @dep.default = []
+# end
+#
+# def rule(outputs, inputs=[], &block)
+# triple = [outputs, inputs, block]
+# outputs.each {|f| @dep[f] = [triple]}
+# @dep[triple] = inputs
+# end
+#
+# def build(target)
+# each_strongly_connected_component_from(target) {|ns|
+# if ns.length != 1
+# fs = ns.delete_if {|n| Array === n}
+# raise Gem::TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
+# end
+# n = ns.first
+# if Array === n
+# outputs, inputs, block = n
+# inputs_time = inputs.map {|f| File.mtime f}.max
+# begin
+# outputs_time = outputs.map {|f| File.mtime f}.min
+# rescue Errno::ENOENT
+# outputs_time = nil
+# end
+# if outputs_time == nil ||
+# inputs_time != nil && outputs_time <= inputs_time
+# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
+# block.call
+# end
+# end
+# }
+# end
+#
+# def tsort_each_child(node, &block)
+# @dep[node].each(&block)
+# end
+# include Gem::TSort
+# end
+#
+# def command(arg)
+# print arg, "\n"
+# system arg
+# end
+#
+# m = Make.new
+# m.rule(%w[t1]) { command 'date > t1' }
+# m.rule(%w[t2]) { command 'date > t2' }
+# m.rule(%w[t3]) { command 'date > t3' }
+# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
+# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
+# m.build('t5')
+#
+# == Bugs
+#
+# * 'tsort.rb' is wrong name because this library uses
+# Tarjan's algorithm for strongly connected components.
+# Although 'strongly_connected_components.rb' is correct but too long.
+#
+# == References
+#
+# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
+# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
+#
+
+module Gem::TSort
+ class Cyclic < StandardError
+ end
+
+ # Returns a topologically sorted array of nodes.
+ # The array is sorted from children to parents, i.e.
+ # the first element has no child and the last node has no parent.
+ #
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # p graph.tsort #=> [4, 2, 3, 1]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # p graph.tsort # raises Gem::TSort::Cyclic
+ #
+ def tsort
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.tsort(each_node, each_child)
+ end
+
+ # Returns a topologically sorted array of nodes.
+ # The array is sorted from children to parents, i.e.
+ # the first element has no child and the last node has no parent.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
+ #
+ def self.tsort(each_node, each_child)
+ tsort_each(each_node, each_child).to_a
+ end
+
+ # The iterator version of the #tsort method.
+ # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
+ # modification of _obj_ during the iteration may lead to unexpected results.
+ #
+ # #tsort_each returns +nil+.
+ # If there is a cycle, Gem::TSort::Cyclic is raised.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.tsort_each {|n| p n }
+ # #=> 4
+ # # 2
+ # # 3
+ # # 1
+ #
+ def tsort_each(&block) # :yields: node
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.tsort_each(each_node, each_child, &block)
+ end
+
+ # The iterator version of the Gem::TSort.tsort method.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # Gem::TSort.tsort_each(each_node, each_child) {|n| p n }
+ # #=> 4
+ # # 2
+ # # 3
+ # # 1
+ #
+ def self.tsort_each(each_node, each_child) # :yields: node
+ return to_enum(__method__, each_node, each_child) unless block_given?
+
+ each_strongly_connected_component(each_node, each_child) {|component|
+ if component.size == 1
+ yield component.first
+ else
+ raise Cyclic.new("topological sort failed: #{component.inspect}")
+ end
+ }
+ end
+
+ # Returns strongly connected components as an array of arrays of nodes.
+ # The array is sorted from children to parents.
+ # Each elements of the array represents a strongly connected component.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
+ #
+ def strongly_connected_components
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.strongly_connected_components(each_node, each_child)
+ end
+
+ # Returns strongly connected components as an array of arrays of nodes.
+ # The array is sorted from children to parents.
+ # Each elements of the array represents a strongly connected component.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.strongly_connected_components(each_node, each_child)
+ # #=> [[4], [2], [3], [1]]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # p Gem::TSort.strongly_connected_components(each_node, each_child)
+ # #=> [[4], [2, 3], [1]]
+ #
+ def self.strongly_connected_components(each_node, each_child)
+ each_strongly_connected_component(each_node, each_child).to_a
+ end
+
+ # The iterator version of the #strongly_connected_components method.
+ # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
+ # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
+ # modification of _obj_ during the iteration may lead to unexpected results.
+ #
+ # #each_strongly_connected_component returns +nil+.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.each_strongly_connected_component {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ # # [3]
+ # # [1]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # graph.each_strongly_connected_component {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def each_strongly_connected_component(&block) # :yields: nodes
+ each_node = method(:tsort_each_node)
+ each_child = method(:tsort_each_child)
+ Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
+ end
+
+ # The iterator version of the Gem::TSort.strongly_connected_components method.
+ #
+ # The graph is represented by _each_node_ and _each_child_.
+ # _each_node_ should have +call+ method which yields for each node in the graph.
+ # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
+ #
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ # # [3]
+ # # [1]
+ #
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_node = lambda {|&b| g.each_key(&b) }
+ # each_child = lambda {|n, &b| g[n].each(&b) }
+ # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def self.each_strongly_connected_component(each_node, each_child) # :yields: nodes
+ return to_enum(__method__, each_node, each_child) unless block_given?
+
+ id_map = {}
+ stack = []
+ each_node.call {|node|
+ unless id_map.include? node
+ each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
+ yield c
+ }
+ end
+ }
+ nil
+ end
+
+ # Iterates over strongly connected component in the subgraph reachable from
+ # _node_.
+ #
+ # Return value is unspecified.
+ #
+ # #each_strongly_connected_component_from doesn't call #tsort_each_node.
+ #
+ # class G
+ # include Gem::TSort
+ # def initialize(g)
+ # @g = g
+ # end
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
+ # def tsort_each_node(&b) @g.each_key(&b) end
+ # end
+ #
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
+ # #=> [4]
+ # # [2]
+ #
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
+ # #=> [4]
+ # # [2, 3]
+ #
+ def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
+ Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
+ end
+
+ # Iterates over strongly connected components in a graph.
+ # The graph is represented by _node_ and _each_child_.
+ #
+ # _node_ is the first node.
+ # _each_child_ should have +call+ method which takes a node argument
+ # and yields for each child node.
+ #
+ # Return value is unspecified.
+ #
+ # #Gem::TSort.each_strongly_connected_component_from is a class method and
+ # it doesn't need a class to represent a graph which includes Gem::TSort.
+ #
+ # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
+ # each_child = lambda {|n, &b| graph[n].each(&b) }
+ # Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc|
+ # p scc
+ # }
+ # #=> [4]
+ # # [2, 3]
+ # # [1]
+ #
+ def self.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
+ return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
+
+ minimum_id = node_id = id_map[node] = id_map.size
+ stack_length = stack.length
+ stack << node
+
+ each_child.call(node) {|child|
+ if id_map.include? child
+ child_id = id_map[child]
+ minimum_id = child_id if child_id && child_id < minimum_id
+ else
+ sub_minimum_id =
+ each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
+ yield c
+ }
+ minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
+ end
+ }
+
+ if node_id == minimum_id
+ component = stack.slice!(stack_length .. -1)
+ component.each {|n| id_map[n] = nil}
+ yield component
+ end
+
+ minimum_id
+ end
+
+ # Should be implemented by a extended class.
+ #
+ # #tsort_each_node is used to iterate for all nodes over a graph.
+ #
+ def tsort_each_node # :yields: node
+ raise NotImplementedError.new
+ end
+
+ # Should be implemented by a extended class.
+ #
+ # #tsort_each_child is used to iterate for child nodes of _node_.
+ #
+ def tsort_each_child(node) # :yields: child
+ raise NotImplementedError.new
+ end
+end
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 4d72f6fd0a..f678f960f0 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -32,7 +32,7 @@ class Gem::Uninstaller
attr_reader :bin_dir
##
- # The gem repository the gem will be uninstalled from
+ # The gem repository the gem will be installed into
attr_reader :gem_home
@@ -46,12 +46,11 @@ class Gem::Uninstaller
# Constructs an uninstaller that will uninstall +gem+
def initialize(gem, options = {})
- # TODO: document the valid options
+ # TODO document the valid options
@gem = gem
@version = options[:version] || Gem::Requirement.default
- @install_dir = options[:install_dir]
- @gem_home = File.realpath(@install_dir || Gem.dir)
- @user_dir = File.exist?(Gem.user_dir) ? File.realpath(Gem.user_dir) : Gem.user_dir
+ @gem_home = File.realpath(options[:install_dir] || Gem.dir)
+ @plugins_dir = Gem.plugindir(@gem_home)
@force_executables = options[:executables]
@force_all = options[:all]
@force_ignore = options[:ignore]
@@ -71,7 +70,7 @@ class Gem::Uninstaller
# only add user directory if install_dir is not set
@user_install = false
- @user_install = options[:user_install] unless @install_dir
+ @user_install = options[:user_install] unless options[:install_dir]
# Optimization: populated during #uninstall
@default_specs_matching_uninstall_params = []
@@ -100,13 +99,15 @@ class Gem::Uninstaller
raise Gem::InstallError, "gem #{@gem.inspect} is not installed"
end
- default_specs, list = list.partition(&:default_gem?)
+ default_specs, list = list.partition do |spec|
+ spec.default_gem?
+ end
warn_cannot_uninstall_default_gems(default_specs - list)
@default_specs_matching_uninstall_params = default_specs
list, other_repo_specs = list.partition do |spec|
@gem_home == spec.base_dir ||
- (@user_install && spec.base_dir == @user_dir)
+ (@user_install && spec.base_dir == Gem.user_dir)
end
list.sort!
@@ -114,7 +115,7 @@ class Gem::Uninstaller
if list.empty?
return unless other_repo_specs.any?
- other_repos = other_repo_specs.map(&:base_dir).uniq
+ other_repos = other_repo_specs.map {|spec| spec.base_dir }.uniq
message = ["#{@gem} is not installed in GEM_HOME, try:"]
message.concat other_repos.map {|repo|
@@ -126,7 +127,7 @@ class Gem::Uninstaller
remove_all list
elsif list.size > 1
- gem_names = list.map(&:full_name)
+ gem_names = list.map {|gem| gem.full_name }
gem_names << "All versions"
say
@@ -134,7 +135,7 @@ class Gem::Uninstaller
if index == list.size
remove_all list
- elsif index && index >= 0 && index < list.size
+ elsif index >= 0 && index < list.size
uninstall_gem list[index]
else
say "Error: must enter a number [1-#{list.size + 1}]"
@@ -200,8 +201,8 @@ class Gem::Uninstaller
executables = executables.map {|exec| formatted_program_filename exec }
remove = if @force_executables.nil?
- ask_yes_no("Remove executables:\n" \
- "\t#{executables.join ", "}\n\n" \
+ ask_yes_no("Remove executables:\n" +
+ "\t#{executables.join ', '}\n\n" +
"in addition to the gem?",
true)
else
@@ -240,9 +241,9 @@ class Gem::Uninstaller
def remove(spec)
unless path_ok?(@gem_home, spec) ||
- (@user_install && path_ok?(@user_dir, spec))
+ (@user_install && path_ok?(Gem.user_dir, spec))
e = Gem::GemNotInHomeException.new \
- "Gem '#{spec.full_name}' is not installed in directory #{@gem_home}"
+ "Gem '#{spec.full_name}' is not installed in directory #{@gem_home}"
e.spec = spec
raise e
@@ -285,18 +286,17 @@ class Gem::Uninstaller
def remove_plugins(spec) # :nodoc:
return if spec.plugins.empty?
- remove_plugins_for(spec, plugin_dir_for(spec))
+ remove_plugins_for(spec, @plugins_dir)
end
##
# Regenerates plugin wrappers after removal.
def regenerate_plugins
- specification_record = @install_dir ? Gem::SpecificationRecord.from_path(@install_dir) : Gem::Specification.specification_record
- latest = specification_record.latest_spec_for(@spec.name)
+ latest = Gem::Specification.latest_spec_for(@spec.name)
return if latest.nil?
- regenerate_plugins_for(latest, plugin_dir_for(@spec))
+ regenerate_plugins_for(latest, @plugins_dir)
end
##
@@ -342,7 +342,7 @@ class Gem::Uninstaller
s.name == spec.name && s.full_name != spec.full_name
end
- spec.dependent_gems(@check_dev).each do |dep_spec, dep, _satlist|
+ spec.dependent_gems(@check_dev).each do |dep_spec, dep, satlist|
unless siblings.any? {|s| s.satisfies_requirement? dep }
msg << "#{dep_spec.name}-#{dep_spec.version} depends on #{dep}"
end
@@ -350,7 +350,7 @@ class Gem::Uninstaller
msg << "If you remove this gem, these dependencies will not be met."
msg << "Continue with Uninstall?"
- ask_yes_no(msg.join("\n"), false)
+ return ask_yes_no(msg.join("\n"), false)
end
##
@@ -408,8 +408,4 @@ class Gem::Uninstaller
say "Gem #{spec.full_name} cannot be uninstalled because it is a default gem"
end
end
-
- def plugin_dir_for(spec)
- Gem.plugindir(spec.base_dir)
- end
end
diff --git a/lib/rubygems/update_suggestion.rb b/lib/rubygems/update_suggestion.rb
index 6f3ec5f493..c2e81b2374 100644
--- a/lib/rubygems/update_suggestion.rb
+++ b/lib/rubygems/update_suggestion.rb
@@ -4,6 +4,15 @@
# Mixin methods for Gem::Command to promote available RubyGems update
module Gem::UpdateSuggestion
+ # list taken from https://github.com/watson/ci-info/blob/7a3c30d/index.js#L56-L66
+ CI_ENV_VARS = [
+ "CI", # Travis CI, CircleCI, Cirrus CI, Gitlab CI, Appveyor, CodeShip, dsari
+ "CONTINUOUS_INTEGRATION", # Travis CI, Cirrus CI
+ "BUILD_NUMBER", # Jenkins, TeamCity
+ "CI_APP_ID", "CI_BUILD_ID", "CI_BUILD_NUMBER", # Applfow
+ "RUN_ID" # TaskCluster, dsari
+ ].freeze
+
ONE_WEEK = 7 * 24 * 60 * 60
##
@@ -19,9 +28,9 @@ Run `gem update --system #{Gem.latest_rubygems_version}` to update your installa
end
##
- # Determines if current environment is eligible for update suggestion.
+ # Determines if current environment is eglible for update suggestion.
- def eligible_for_update?
+ def eglible_for_update?
# explicit opt-out
return false if Gem.configuration[:prevent_update_suggestion]
return false if ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"]
@@ -30,7 +39,7 @@ Run `gem update --system #{Gem.latest_rubygems_version}` to update your installa
return false unless Gem.ui.tty?
return false if Gem.rubygems_version.prerelease?
return false if Gem.disable_system_update_message
- return false if Gem::CIDetector.ci?
+ return false if ci?
# check makes sense only when we can store timestamp of last try
# otherwise we will not be able to prevent "annoying" update message
@@ -44,13 +53,17 @@ Run `gem update --system #{Gem.latest_rubygems_version}` to update your installa
# compare current and latest version, this is the part where
# latest rubygems spec is fetched from remote
- (Gem.rubygems_version < Gem.latest_rubygems_version).tap do |eligible|
+ (Gem.rubygems_version < Gem.latest_rubygems_version).tap do |eglible|
# store the time of last successful check into state file
Gem.configuration.last_update_check = check_time
- return eligible
+ return eglible
end
- rescue StandardError # don't block install command on any problem
+ rescue # don't block install command on any problem
false
end
+
+ def ci?
+ CI_ENV_VARS.any? {|var| ENV.include?(var) }
+ end
end
diff --git a/lib/rubygems/uri.rb b/lib/rubygems/uri.rb
index a44aaceba5..4b5d035aa0 100644
--- a/lib/rubygems/uri.rb
+++ b/lib/rubygems/uri.rb
@@ -16,9 +16,9 @@ class Gem::Uri
# Parses uri, raising if it's invalid
def self.parse!(uri)
- require_relative "vendor/uri/lib/uri"
+ require "uri"
- raise Gem::URI::InvalidURIError unless uri
+ raise URI::InvalidURIError unless uri
return uri unless uri.is_a?(String)
@@ -28,9 +28,9 @@ class Gem::Uri
# as "%7BDESede%7D". If this is escaped again the percentage
# symbols will be escaped.
begin
- Gem::URI.parse(uri)
- rescue Gem::URI::InvalidURIError
- Gem::URI.parse(Gem::URI::DEFAULT_PARSER.escape(uri))
+ URI.parse(uri)
+ rescue URI::InvalidURIError
+ URI.parse(URI::DEFAULT_PARSER.escape(uri))
end
end
@@ -39,7 +39,7 @@ class Gem::Uri
def self.parse(uri)
parse!(uri)
- rescue Gem::URI::InvalidURIError
+ rescue URI::InvalidURIError
uri
end
diff --git a/lib/rubygems/uri_formatter.rb b/lib/rubygems/uri_formatter.rb
index 517ce33637..3f1d02d774 100644
--- a/lib/rubygems/uri_formatter.rb
+++ b/lib/rubygems/uri_formatter.rb
@@ -34,7 +34,7 @@ class Gem::UriFormatter
# Normalize the URI by adding "http://" if it is missing.
def normalize
- /^(https?|ftp|file):/i.match?(@uri) ? @uri : "http://#{@uri}"
+ (@uri =~ /^(https?|ftp|file):/i) ? @uri : "http://#{@uri}"
end
##
diff --git a/lib/rubygems/user_interaction.rb b/lib/rubygems/user_interaction.rb
index 0172c4ee89..451dba070f 100644
--- a/lib/rubygems/user_interaction.rb
+++ b/lib/rubygems/user_interaction.rb
@@ -14,6 +14,7 @@ require_relative "text"
# module will have access to the +ui+ method that returns the default UI.
module Gem::DefaultUserInteraction
+
include Gem::Text
##
@@ -68,6 +69,7 @@ module Gem::DefaultUserInteraction
def use_ui(new_ui, &block)
Gem::DefaultUserInteraction.use_ui(new_ui, &block)
end
+
end
##
@@ -90,6 +92,7 @@ end
# end
module Gem::UserInteraction
+
include Gem::DefaultUserInteraction
##
@@ -193,7 +196,7 @@ class Gem::StreamUI
# then special operations (like asking for passwords) will use the TTY
# commands to disable character echo.
- def initialize(in_stream, out_stream, err_stream=$stderr, usetty=true)
+ def initialize(in_stream, out_stream, err_stream=STDERR, usetty=true)
@ins = in_stream
@outs = out_stream
@errs = err_stream
@@ -238,7 +241,7 @@ class Gem::StreamUI
result = result.strip.to_i - 1
return nil, nil unless (0...list.size) === result
- [list[result], result]
+ return list[result], result
end
##
@@ -257,32 +260,33 @@ class Gem::StreamUI
end
default_answer = case default
- when nil
- "yn"
- when true
- "Yn"
- else
- "yN"
+ when nil
+ "yn"
+ when true
+ "Yn"
+ else
+ "yN"
end
result = nil
while result.nil? do
result = case ask "#{question} [#{default_answer}]"
- when /^y/i then true
- when /^n/i then false
- when /^$/ then default
+ when /^y/i then true
+ when /^n/i then false
+ when /^$/ then default
+ else nil
end
end
- result
+ return result
end
##
# Ask a question. Returns an answer if connected to a tty, nil otherwise.
def ask(question)
- return nil unless tty?
+ return nil if !tty?
@outs.print(question + " ")
@outs.flush
@@ -296,7 +300,7 @@ class Gem::StreamUI
# Ask for a password. Does not echo response to terminal.
def ask_for_password(question)
- return nil unless tty?
+ return nil if !tty?
@outs.print(question, " ")
@outs.flush
@@ -426,7 +430,8 @@ class Gem::StreamUI
# +size+ items. Shows the given +initial_message+ when progress starts
# and the +terminal_message+ when it is complete.
- def initialize(out_stream, size, initial_message, terminal_message = "complete")
+ def initialize(out_stream, size, initial_message,
+ terminal_message = "complete")
@out = out_stream
@total = size
@count = 0
@@ -468,7 +473,8 @@ class Gem::StreamUI
# +size+ items. Shows the given +initial_message+ when progress starts
# and the +terminal_message+ when it is complete.
- def initialize(out_stream, size, initial_message, terminal_message = "complete")
+ def initialize(out_stream, size, initial_message,
+ terminal_message = "complete")
@out = out_stream
@total = size
@count = 0
@@ -591,8 +597,8 @@ class Gem::StreamUI
end
##
-# Subclass of StreamUI that instantiates the user interaction using $stdin,
-# $stdout, and $stderr.
+# Subclass of StreamUI that instantiates the user interaction using STDIN,
+# STDOUT, and STDERR.
class Gem::ConsoleUI < Gem::StreamUI
##
@@ -600,7 +606,7 @@ class Gem::ConsoleUI < Gem::StreamUI
# stdin, output to stdout and warnings or errors to stderr.
def initialize
- super $stdin, $stdout, $stderr, true
+ super STDIN, STDOUT, STDERR, true
end
end
diff --git a/lib/rubygems/util.rb b/lib/rubygems/util.rb
index 51f9c2029f..bd6ea92cc9 100644
--- a/lib/rubygems/util.rb
+++ b/lib/rubygems/util.rb
@@ -6,6 +6,7 @@ require_relative "deprecate"
# This module contains various utility methods as module methods.
module Gem::Util
+
##
# Zlib::GzipReader wrapper that unzips +data+.
@@ -60,7 +61,7 @@ module Gem::Util
# Invokes system, but silences all output.
def self.silent_system(*command)
- opt = { out: IO::NULL, err: [:child, :out] }
+ opt = { :out => IO::NULL, :err => [:child, :out] }
if Hash === command.last
opt.update(command.last)
cmds = command[0...-1]
@@ -84,11 +85,7 @@ module Gem::Util
here = File.expand_path directory
loop do
- begin
- Dir.chdir here, &block
- rescue StandardError
- Errno::EACCES
- end
+ Dir.chdir here, &block rescue Errno::EACCES
new_here = File.expand_path("..", here)
return if new_here == here # toplevel
@@ -105,14 +102,15 @@ module Gem::Util
end
##
- # Corrects +path+ (usually returned by `Gem::URI.parse().path` on Windows), that
+ # Corrects +path+ (usually returned by `URI.parse().path` on Windows), that
# comes with a leading slash.
def self.correct_for_windows_path(path)
- if path[0].chr == "/" && path[1].chr.match?(/[a-z]/i) && path[2].chr == ":"
+ if path[0].chr == "/" && path[1].chr =~ /[a-z]/i && path[2].chr == ":"
path[1..-1]
else
path
end
end
+
end
diff --git a/lib/rubygems/util/licenses.rb b/lib/rubygems/util/licenses.rb
index 192ae30b9b..1d5efde576 100644
--- a/lib/rubygems/util/licenses.rb
+++ b/lib/rubygems/util/licenses.rb
@@ -1,8 +1,5 @@
# frozen_string_literal: true
-# This is generated by generate_spdx_license_list.rb, any edits to this
-# file will be discarded.
-
require_relative "../text"
class Gem::Licenses
@@ -15,7 +12,6 @@ class Gem::Licenses
# license identifiers
LICENSE_IDENTIFIERS = %w[
0BSD
- 3D-Slicer-1.0
AAL
ADSL
AFL-1.1
@@ -23,14 +19,14 @@ class Gem::Licenses
AFL-2.0
AFL-2.1
AFL-3.0
+ AGPL-1.0
AGPL-1.0-only
AGPL-1.0-or-later
+ AGPL-3.0
AGPL-3.0-only
AGPL-3.0-or-later
- AMD-newlib
AMDPLPA
AML
- AML-glslang
AMPAS
ANTLR-PD
ANTLR-PD-fallback
@@ -40,35 +36,27 @@ class Gem::Licenses
APSL-1.1
APSL-1.2
APSL-2.0
- ASWF-Digital-Assets-1.0
- ASWF-Digital-Assets-1.1
Abstyles
- AdaCore-doc
Adobe-2006
- Adobe-Display-PostScript
Adobe-Glyph
- Adobe-Utopia
Afmparse
Aladdin
Apache-1.0
Apache-1.1
Apache-2.0
- App-s2p
- Arphic-1999
Artistic-1.0
Artistic-1.0-Perl
Artistic-1.0-cl8
Artistic-2.0
BSD-1-Clause
BSD-2-Clause
- BSD-2-Clause-Darwin
+ BSD-2-Clause-FreeBSD
+ BSD-2-Clause-NetBSD
BSD-2-Clause-Patent
BSD-2-Clause-Views
- BSD-2-Clause-first-lines
BSD-3-Clause
BSD-3-Clause-Attribution
BSD-3-Clause-Clear
- BSD-3-Clause-HP
BSD-3-Clause-LBNL
BSD-3-Clause-Modification
BSD-3-Clause-No-Military-License
@@ -76,37 +64,20 @@ class Gem::Licenses
BSD-3-Clause-No-Nuclear-License-2014
BSD-3-Clause-No-Nuclear-Warranty
BSD-3-Clause-Open-MPI
- BSD-3-Clause-Sun
- BSD-3-Clause-acpica
- BSD-3-Clause-flex
BSD-4-Clause
BSD-4-Clause-Shortened
BSD-4-Clause-UC
- BSD-4.3RENO
- BSD-4.3TAHOE
- BSD-Advertising-Acknowledgement
- BSD-Attribution-HPND-disclaimer
- BSD-Inferno-Nettverk
BSD-Protection
BSD-Source-Code
- BSD-Source-beginning-file
- BSD-Systemics
- BSD-Systemics-W3Works
BSL-1.0
BUSL-1.1
- Baekmuk
Bahyph
Barr
Beerware
BitTorrent-1.0
BitTorrent-1.1
- Bitstream-Charter
- Bitstream-Vera
BlueOak-1.0.0
- Boehm-GC
Borceux
- Brian-Gladman-2-Clause
- Brian-Gladman-3-Clause
C-UDA-1.0
CAL-1.0
CAL-1.0-Combined-Work-Exception
@@ -114,43 +85,30 @@ class Gem::Licenses
CC-BY-1.0
CC-BY-2.0
CC-BY-2.5
- CC-BY-2.5-AU
CC-BY-3.0
CC-BY-3.0-AT
- CC-BY-3.0-AU
- CC-BY-3.0-DE
- CC-BY-3.0-IGO
- CC-BY-3.0-NL
CC-BY-3.0-US
CC-BY-4.0
CC-BY-NC-1.0
CC-BY-NC-2.0
CC-BY-NC-2.5
CC-BY-NC-3.0
- CC-BY-NC-3.0-DE
CC-BY-NC-4.0
CC-BY-NC-ND-1.0
CC-BY-NC-ND-2.0
CC-BY-NC-ND-2.5
CC-BY-NC-ND-3.0
- CC-BY-NC-ND-3.0-DE
CC-BY-NC-ND-3.0-IGO
CC-BY-NC-ND-4.0
CC-BY-NC-SA-1.0
CC-BY-NC-SA-2.0
- CC-BY-NC-SA-2.0-DE
- CC-BY-NC-SA-2.0-FR
- CC-BY-NC-SA-2.0-UK
CC-BY-NC-SA-2.5
CC-BY-NC-SA-3.0
- CC-BY-NC-SA-3.0-DE
- CC-BY-NC-SA-3.0-IGO
CC-BY-NC-SA-4.0
CC-BY-ND-1.0
CC-BY-ND-2.0
CC-BY-ND-2.5
CC-BY-ND-3.0
- CC-BY-ND-3.0-DE
CC-BY-ND-4.0
CC-BY-SA-1.0
CC-BY-SA-2.0
@@ -159,8 +117,6 @@ class Gem::Licenses
CC-BY-SA-2.5
CC-BY-SA-3.0
CC-BY-SA-3.0-AT
- CC-BY-SA-3.0-DE
- CC-BY-SA-3.0-IGO
CC-BY-SA-4.0
CC-PDDC
CC0-1.0
@@ -168,7 +124,6 @@ class Gem::Licenses
CDDL-1.1
CDL-1.0
CDLA-Permissive-1.0
- CDLA-Permissive-2.0
CDLA-Sharing-1.0
CECILL-1.0
CECILL-1.1
@@ -181,36 +136,22 @@ class Gem::Licenses
CERN-OHL-P-2.0
CERN-OHL-S-2.0
CERN-OHL-W-2.0
- CFITSIO
- CMU-Mach
- CMU-Mach-nodoc
CNRI-Jython
CNRI-Python
CNRI-Python-GPL-Compatible
- COIL-1.0
CPAL-1.0
CPL-1.0
CPOL-1.02
CUA-OPL-1.0
Caldera
- Caldera-no-preamble
- Catharon
ClArtistic
- Clips
- Community-Spec-1.0
Condor-1.1
- Cornell-Lossless-JPEG
- Cronyx
Crossword
CrystalStacker
Cube
D-FSL-1.0
- DEC-3-Clause
- DL-DE-BY-2.0
- DL-DE-ZERO-2.0
DOC
DRL-1.0
- DRL-1.1
DSDP
Dotseqn
ECL-1.0
@@ -224,38 +165,33 @@ class Gem::Licenses
EUPL-1.0
EUPL-1.1
EUPL-1.2
- Elastic-2.0
Entessa
ErlPL-1.1
Eurosym
- FBM
- FDK-AAC
FSFAP
- FSFAP-no-warranty-disclaimer
FSFUL
FSFULLR
- FSFULLRWD
FTL
Fair
- Ferguson-Twofish
Frameworx-1.0
FreeBSD-DOC
FreeImage
- Furuseth
- GCR-docs
GD
+ GFDL-1.1
GFDL-1.1-invariants-only
GFDL-1.1-invariants-or-later
GFDL-1.1-no-invariants-only
GFDL-1.1-no-invariants-or-later
GFDL-1.1-only
GFDL-1.1-or-later
+ GFDL-1.2
GFDL-1.2-invariants-only
GFDL-1.2-invariants-or-later
GFDL-1.2-no-invariants-only
GFDL-1.2-no-invariants-or-later
GFDL-1.2-only
GFDL-1.2-or-later
+ GFDL-1.3
GFDL-1.3-invariants-only
GFDL-1.3-invariants-or-later
GFDL-1.3-no-invariants-only
@@ -264,80 +200,63 @@ class Gem::Licenses
GFDL-1.3-or-later
GL2PS
GLWTPL
+ GPL-1.0
+ GPL-1.0+
GPL-1.0-only
GPL-1.0-or-later
+ GPL-2.0
+ GPL-2.0+
GPL-2.0-only
GPL-2.0-or-later
+ GPL-2.0-with-GCC-exception
+ GPL-2.0-with-autoconf-exception
+ GPL-2.0-with-bison-exception
+ GPL-2.0-with-classpath-exception
+ GPL-2.0-with-font-exception
+ GPL-3.0
+ GPL-3.0+
GPL-3.0-only
GPL-3.0-or-later
+ GPL-3.0-with-GCC-exception
+ GPL-3.0-with-autoconf-exception
Giftware
Glide
Glulxe
- Graphics-Gems
- Gutmann
- HP-1986
- HP-1989
HPND
- HPND-DEC
- HPND-Fenneberg-Livingston
- HPND-INRIA-IMAG
- HPND-Intel
- HPND-Kevlin-Henney
- HPND-MIT-disclaimer
- HPND-Markus-Kuhn
- HPND-Pbmplus
- HPND-UC
- HPND-UC-export-US
- HPND-doc
- HPND-doc-sell
- HPND-export-US
- HPND-export-US-acknowledgement
- HPND-export-US-modify
- HPND-export2-US
- HPND-merchantability-variant
- HPND-sell-MIT-disclaimer-xserver
- HPND-sell-regexpr
HPND-sell-variant
- HPND-sell-variant-MIT-disclaimer
- HPND-sell-variant-MIT-disclaimer-rev
HTMLTIDY
HaskellReport
Hippocratic-2.1
IBM-pibs
ICU
- IEC-Code-Components-EULA
IJG
- IJG-short
IPA
IPL-1.0
ISC
- ISC-Veillard
ImageMagick
Imlib2
Info-ZIP
- Inner-Net-2.0
Intel
Intel-ACPI
Interbase-1.0
- JPL-image
JPNIC
JSON
- Jam
JasPer-2.0
- Kastrup
- Kazlib
- Knuth-CTAN
LAL-1.2
LAL-1.3
+ LGPL-2.0
+ LGPL-2.0+
LGPL-2.0-only
LGPL-2.0-or-later
+ LGPL-2.1
+ LGPL-2.1+
LGPL-2.1-only
LGPL-2.1-or-later
+ LGPL-3.0
+ LGPL-3.0+
LGPL-3.0-only
LGPL-3.0-or-later
LGPLLR
- LOOP
- LPD-document
LPL-1.0
LPL-1.02
LPPL-1.0
@@ -345,50 +264,30 @@ class Gem::Licenses
LPPL-1.2
LPPL-1.3a
LPPL-1.3c
- LZMA-SDK-9.11-to-9.20
- LZMA-SDK-9.22
Latex2e
- Latex2e-translated-notice
Leptonica
LiLiQ-P-1.1
LiLiQ-R-1.1
LiLiQ-Rplus-1.1
Libpng
Linux-OpenIB
- Linux-man-pages-1-para
- Linux-man-pages-copyleft
- Linux-man-pages-copyleft-2-para
- Linux-man-pages-copyleft-var
- Lucida-Bitmap-Fonts
MIT
MIT-0
MIT-CMU
- MIT-Festival
- MIT-Khronos-old
MIT-Modern-Variant
- MIT-Wu
MIT-advertising
MIT-enna
MIT-feh
MIT-open-group
- MIT-testregex
MITNFA
- MMIXware
- MPEG-SSG
MPL-1.0
MPL-1.1
MPL-2.0
MPL-2.0-no-copyleft-exception
- MS-LPL
MS-PL
MS-RL
MTLL
- Mackerras-3-Clause
- Mackerras-3-Clause-acknowledgment
MakeIndex
- Martin-Birgmeier
- McPhee-slideshow
- Minpack
MirOS
Motosoto
MulanPSL-1.0
@@ -398,17 +297,12 @@ class Gem::Licenses
NAIST-2003
NASA-1.3
NBPL-1.0
- NCBI-PD
NCGL-UK-2.0
- NCL
NCSA
NGPL
- NICTA-1.0
NIST-PD
NIST-PD-fallback
- NIST-Software
NLOD-1.0
- NLOD-2.0
NLPL
NOSL
NPL-1.0
@@ -423,13 +317,12 @@ class Gem::Licenses
Newsletr
Nokia
Noweb
+ Nunit
O-UDA-1.0
- OAR
OCCT-PL
OCLC-2.0
ODC-By-1.0
ODbL-1.0
- OFFIS
OFL-1.0
OFL-1.0-RFN
OFL-1.0-no-RFN
@@ -459,38 +352,27 @@ class Gem::Licenses
OLDAP-2.6
OLDAP-2.7
OLDAP-2.8
- OLFL-1.3
OML
OPL-1.0
- OPL-UK-3.0
- OPUBL-1.0
OSET-PL-2.1
OSL-1.0
OSL-1.1
OSL-2.0
OSL-2.1
OSL-3.0
- OpenPBS-2.3
OpenSSL
- OpenSSL-standalone
- OpenVision
- PADL
PDDL-1.0
PHP-3.0
PHP-3.01
- PPL
PSF-2.0
Parity-6.0.0
Parity-7.0.0
- Pixar
Plexus
PolyForm-Noncommercial-1.0.0
PolyForm-Small-Business-1.0.0
PostgreSQL
Python-2.0
- Python-2.0.1
QPL-1.0
- QPL-1.0-INRIA-2004
Qhull
RHeCos-1.1
RPL-1.1
@@ -501,66 +383,45 @@ class Gem::Licenses
Rdisc
Ruby
SAX-PD
- SAX-PD-2.0
SCEA
SGI-B-1.0
SGI-B-1.1
SGI-B-2.0
- SGI-OpenGL
- SGP4
SHL-0.5
SHL-0.51
SISSL
SISSL-1.2
- SL
SMLNJ
SMPPL
SNIA
SPL-1.0
SSH-OpenSSH
SSH-short
- SSLeay-standalone
SSPL-1.0
SWL
Saxpath
- SchemeReport
Sendmail
Sendmail-8.23
SimPL-2.0
Sleepycat
- Soundex
Spencer-86
Spencer-94
Spencer-99
+ StandardML-NJ
SugarCRM-1.1.3
- Sun-PPP
- Sun-PPP-2000
- SunPro
- Symlinks
TAPR-OHL-1.0
TCL
TCP-wrappers
- TGPPL-1.0
TMate
TORQUE-1.1
TOSL
- TPDL
- TPL-1.0
- TTWL
- TTYP0
TU-Berlin-1.0
TU-Berlin-2.0
- TermReadKey
- UCAR
UCL-1.0
- UMich-Merit
UPL-1.0
- URT-RLE
- Unicode-3.0
Unicode-DFS-2015
Unicode-DFS-2016
Unicode-TOU
- UnixCrypt
Unlicense
VOSTROM
VSL-1.0
@@ -570,15 +431,11 @@ class Gem::Licenses
W3C-20150513
WTFPL
Watcom-1.0
- Widget-Workshop
Wsuipa
X11
- X11-distribute-modifications-variant
XFree86-1.1
XSkat
- Xdebug-1.03
Xerox
- Xfig
Xnet
YPL-1.0
YPL-1.1
@@ -586,109 +443,41 @@ class Gem::Licenses
ZPL-2.0
ZPL-2.1
Zed
- Zeeff
Zend-2.0
Zimbra-1.3
Zimbra-1.4
Zlib
- any-OSI
- bcrypt-Solar-Designer
blessing
+ bzip2-1.0.5
bzip2-1.0.6
- check-cvs
- checkmk
copyleft-next-0.3.0
copyleft-next-0.3.1
curl
- cve-tou
diffmark
- dtoa
dvipdfm
+ eCos-2.0
eGenix
etalab-2.0
- fwlw
gSOAP-1.3b
gnuplot
- gtkbook
- hdparm
iMatix
libpng-2.0
libselinux-1.0
libtiff
- libutil-David-Nugent
- lsof
- magaz
- mailprio
- metamail
- mpi-permissive
mpich2
- mplus
- pkgconf
- pnmstitch
psfrag
psutils
- python-ldap
- radvd
- snprintf
- softSurfer
- ssh-keyscan
- swrule
- threeparttable
- ulem
- w3m
+ wxWindows
xinetd
- xkeyboard-config-Zinoviev
- xlock
xpp
- xzoom
zlib-acknowledgement
].freeze
- DEPRECATED_LICENSE_IDENTIFIERS = %w[
- AGPL-1.0
- AGPL-3.0
- BSD-2-Clause-FreeBSD
- BSD-2-Clause-NetBSD
- GFDL-1.1
- GFDL-1.2
- GFDL-1.3
- GPL-1.0
- GPL-1.0+
- GPL-2.0
- GPL-2.0+
- GPL-2.0-with-GCC-exception
- GPL-2.0-with-autoconf-exception
- GPL-2.0-with-bison-exception
- GPL-2.0-with-classpath-exception
- GPL-2.0-with-font-exception
- GPL-3.0
- GPL-3.0+
- GPL-3.0-with-GCC-exception
- GPL-3.0-with-autoconf-exception
- LGPL-2.0
- LGPL-2.0+
- LGPL-2.1
- LGPL-2.1+
- LGPL-3.0
- LGPL-3.0+
- Nunit
- StandardML-NJ
- bzip2-1.0.5
- eCos-2.0
- wxWindows
- ].freeze
-
# exception identifiers
EXCEPTION_IDENTIFIERS = %w[
389-exception
- Asterisk-exception
- Asterisk-linking-protocols-exception
Autoconf-exception-2.0
Autoconf-exception-3.0
- Autoconf-exception-generic
- Autoconf-exception-generic-3.0
- Autoconf-exception-macro
- Bison-exception-1.24
Bison-exception-2.2
Bootloader-exception
CLISP-exception-2.0
@@ -698,64 +487,38 @@ class Gem::Licenses
Fawkes-Runtime-exception
Font-exception-2.0
GCC-exception-2.0
- GCC-exception-2.0-note
GCC-exception-3.1
- GNAT-exception
- GNOME-examples-exception
- GNU-compiler-exception
- GPL-3.0-interface-exception
GPL-3.0-linking-exception
GPL-3.0-linking-source-exception
GPL-CC-1.0
- GStreamer-exception-2005
- GStreamer-exception-2008
- Gmsh-exception
- KiCad-libraries-exception
LGPL-3.0-linking-exception
- LLGPL
LLVM-exception
LZMA-exception
Libtool-exception
Linux-syscall-note
+ Nokia-Qt-exception-1.1
OCCT-exception-1.0
OCaml-LGPL-linking-exception
OpenJDK-assembly-exception-1.0
- PCRE2-exception
PS-or-PDF-font-exception-20170817
- QPL-1.0-INRIA-2004-exception
Qt-GPL-exception-1.0
Qt-LGPL-exception-1.1
Qwt-exception-1.0
- RRDtool-FLOSS-exception-2.0
- SANE-exception
SHL-2.0
SHL-2.1
- SWI-exception
Swift-exception
- Texinfo-exception
- UBDL-exception
Universal-FOSS-exception-1.0
WxWindows-exception-3.1
- cryptsetup-OpenSSL-exception
eCos-exception-2.0
- fmt-exception
freertos-exception-2.0
gnu-javamail-exception
i2p-gpl-java-exception
- libpri-OpenH323-exception
mif-exception
openvpn-openssl-exception
- stunnel-exception
u-boot-exception-2.0
- vsftpd-openssl-exception
- x11vnc-openssl-exception
].freeze
- DEPRECATED_EXCEPTION_IDENTIFIERS = %w[
- Nokia-Qt-exception-1.1
- ].freeze
-
- VALID_REGEXP = /
+ REGEXP = %r{
\A
(?:
#{Regexp.union(LICENSE_IDENTIFIERS)}
@@ -765,34 +528,10 @@ class Gem::Licenses
| #{LICENSE_REF}
)
\Z
- /ox
-
- DEPRECATED_LICENSE_REGEXP = /
- \A
- #{Regexp.union(DEPRECATED_LICENSE_IDENTIFIERS)}
- \+?
- (?:\s WITH \s .+?)?
- \Z
- /ox
-
- DEPRECATED_EXCEPTION_REGEXP = /
- \A
- .+?
- \+?
- (?:\s WITH \s #{Regexp.union(DEPRECATED_EXCEPTION_IDENTIFIERS)})
- \Z
- /ox
+ }ox.freeze
def self.match?(license)
- VALID_REGEXP.match?(license)
- end
-
- def self.deprecated_license_id?(license)
- DEPRECATED_LICENSE_REGEXP.match?(license)
- end
-
- def self.deprecated_exception_id?(license)
- DEPRECATED_EXCEPTION_REGEXP.match?(license)
+ !REGEXP.match(license).nil?
end
def self.suggestions(license)
diff --git a/lib/rubygems/util/list.rb b/lib/rubygems/util/list.rb
index 2899e8a2b9..acb6c73ddb 100644
--- a/lib/rubygems/util/list.rb
+++ b/lib/rubygems/util/list.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module Gem
- # The Gem::List class is currently unused and will be removed in the next major rubygems version
- class List # :nodoc:
+ class List
include Enumerable
attr_accessor :value, :tail
@@ -36,5 +35,4 @@ module Gem
List.new value, list
end
end
- deprecate_constant :List
end
diff --git a/lib/rubygems/validator.rb b/lib/rubygems/validator.rb
index 57e0747eb4..63493638b6 100644
--- a/lib/rubygems/validator.rb
+++ b/lib/rubygems/validator.rb
@@ -25,7 +25,7 @@ class Gem::Validator
installed_files = []
Find.find gem_directory do |file_name|
- fn = file_name[gem_directory.size..file_name.size - 1].sub(%r{^/}, "")
+ fn = file_name[gem_directory.size..file_name.size - 1].sub(/^\//, "")
installed_files << fn unless
fn.empty? || fn.include?("CVS") || File.directory?(file_name)
end
@@ -63,9 +63,7 @@ class Gem::Validator
errors = Hash.new {|h,k| h[k] = {} }
Gem::Specification.each do |spec|
- unless gems.empty?
- next unless gems.include? spec.name
- end
+ next unless gems.include? spec.name unless gems.empty?
next if spec.default_gem?
gem_name = spec.file_name
@@ -90,7 +88,7 @@ class Gem::Validator
good, gone, unreadable = nil, nil, nil, nil
- File.open gem_path, Gem.binary_mode do |_file|
+ File.open gem_path, Gem.binary_mode do |file|
package = Gem::Package.new gem_path
good, gone = package.contents.partition do |file_name|
@@ -110,13 +108,15 @@ class Gem::Validator
end
good.each do |entry, data|
- next unless data # HACK: `gem check -a mkrf`
+ begin
+ next unless data # HACK `gem check -a mkrf`
- source = File.join gem_directory, entry["path"]
+ source = File.join gem_directory, entry["path"]
- File.open source, Gem.binary_mode do |f|
- unless f.read == data
- errors[gem_name][entry["path"]] = "Modified from original"
+ File.open source, Gem.binary_mode do |f|
+ unless f.read == data
+ errors[gem_name][entry["path"]] = "Modified from original"
+ end
end
end
end
diff --git a/lib/rubygems/vendor/molinillo/.document b/lib/rubygems/vendor/molinillo/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/molinillo/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo.rb b/lib/rubygems/vendor/molinillo/lib/molinillo.rb
deleted file mode 100644
index dd5600c9e3..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'molinillo/gem_metadata'
-require_relative 'molinillo/errors'
-require_relative 'molinillo/resolver'
-require_relative 'molinillo/modules/ui'
-require_relative 'molinillo/modules/specification_provider'
-
-# Gem::Molinillo is a generic dependency resolution algorithm.
-module Gem::Molinillo
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
deleted file mode 100644
index 34842d46d5..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- # @!visibility private
- module Delegates
- # Delegates all {Gem::Molinillo::ResolutionState} methods to a `#state` property.
- module ResolutionState
- # (see Gem::Molinillo::ResolutionState#name)
- def name
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.name
- end
-
- # (see Gem::Molinillo::ResolutionState#requirements)
- def requirements
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.requirements
- end
-
- # (see Gem::Molinillo::ResolutionState#activated)
- def activated
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.activated
- end
-
- # (see Gem::Molinillo::ResolutionState#requirement)
- def requirement
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.requirement
- end
-
- # (see Gem::Molinillo::ResolutionState#possibilities)
- def possibilities
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.possibilities
- end
-
- # (see Gem::Molinillo::ResolutionState#depth)
- def depth
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.depth
- end
-
- # (see Gem::Molinillo::ResolutionState#conflicts)
- def conflicts
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.conflicts
- end
-
- # (see Gem::Molinillo::ResolutionState#unused_unwind_options)
- def unused_unwind_options
- current_state = state || Gem::Molinillo::ResolutionState.empty
- current_state.unused_unwind_options
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
deleted file mode 100644
index 8417721537..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- module Delegates
- # Delegates all {Gem::Molinillo::SpecificationProvider} methods to a
- # `#specification_provider` property.
- module SpecificationProvider
- # (see Gem::Molinillo::SpecificationProvider#search_for)
- def search_for(dependency)
- with_no_such_dependency_error_handling do
- specification_provider.search_for(dependency)
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#dependencies_for)
- def dependencies_for(specification)
- with_no_such_dependency_error_handling do
- specification_provider.dependencies_for(specification)
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#requirement_satisfied_by?)
- def requirement_satisfied_by?(requirement, activated, spec)
- with_no_such_dependency_error_handling do
- specification_provider.requirement_satisfied_by?(requirement, activated, spec)
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#dependencies_equal?)
- def dependencies_equal?(dependencies, other_dependencies)
- with_no_such_dependency_error_handling do
- specification_provider.dependencies_equal?(dependencies, other_dependencies)
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#name_for)
- def name_for(dependency)
- with_no_such_dependency_error_handling do
- specification_provider.name_for(dependency)
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#name_for_explicit_dependency_source)
- def name_for_explicit_dependency_source
- with_no_such_dependency_error_handling do
- specification_provider.name_for_explicit_dependency_source
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#name_for_locking_dependency_source)
- def name_for_locking_dependency_source
- with_no_such_dependency_error_handling do
- specification_provider.name_for_locking_dependency_source
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#sort_dependencies)
- def sort_dependencies(dependencies, activated, conflicts)
- with_no_such_dependency_error_handling do
- specification_provider.sort_dependencies(dependencies, activated, conflicts)
- end
- end
-
- # (see Gem::Molinillo::SpecificationProvider#allow_missing?)
- def allow_missing?(dependency)
- with_no_such_dependency_error_handling do
- specification_provider.allow_missing?(dependency)
- end
- end
-
- private
-
- # Ensures any raised {NoSuchDependencyError} has its
- # {NoSuchDependencyError#required_by} set.
- # @yield
- def with_no_such_dependency_error_handling
- yield
- rescue NoSuchDependencyError => error
- if state
- vertex = activated.vertex_named(name_for(error.dependency))
- error.required_by += vertex.incoming_edges.map { |e| e.origin.name }
- error.required_by << name_for_explicit_dependency_source unless vertex.explicit_requirements.empty?
- end
- raise
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph.rb
deleted file mode 100644
index 2dbbc589dc..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph.rb
+++ /dev/null
@@ -1,255 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../../../../vendored_tsort'
-
-require_relative 'dependency_graph/log'
-require_relative 'dependency_graph/vertex'
-
-module Gem::Molinillo
- # A directed acyclic graph that is tuned to hold named dependencies
- class DependencyGraph
- include Enumerable
-
- # Enumerates through the vertices of the graph.
- # @return [Array<Vertex>] The graph's vertices.
- def each
- return vertices.values.each unless block_given?
- vertices.values.each { |v| yield v }
- end
-
- include Gem::TSort
-
- # @!visibility private
- alias tsort_each_node each
-
- # @!visibility private
- def tsort_each_child(vertex, &block)
- vertex.successors.each(&block)
- end
-
- # Topologically sorts the given vertices.
- # @param [Enumerable<Vertex>] vertices the vertices to be sorted, which must
- # all belong to the same graph.
- # @return [Array<Vertex>] The sorted vertices.
- def self.tsort(vertices)
- Gem::TSort.tsort(
- lambda { |b| vertices.each(&b) },
- lambda { |v, &b| (v.successors & vertices).each(&b) }
- )
- end
-
- # A directed edge of a {DependencyGraph}
- # @attr [Vertex] origin The origin of the directed edge
- # @attr [Vertex] destination The destination of the directed edge
- # @attr [Object] requirement The requirement the directed edge represents
- Edge = Struct.new(:origin, :destination, :requirement)
-
- # @return [{String => Vertex}] the vertices of the dependency graph, keyed
- # by {Vertex#name}
- attr_reader :vertices
-
- # @return [Log] the op log for this graph
- attr_reader :log
-
- # Initializes an empty dependency graph
- def initialize
- @vertices = {}
- @log = Log.new
- end
-
- # Tags the current state of the dependency as the given tag
- # @param [Object] tag an opaque tag for the current state of the graph
- # @return [Void]
- def tag(tag)
- log.tag(self, tag)
- end
-
- # Rewinds the graph to the state tagged as `tag`
- # @param [Object] tag the tag to rewind to
- # @return [Void]
- def rewind_to(tag)
- log.rewind_to(self, tag)
- end
-
- # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
- # are properly copied.
- # @param [DependencyGraph] other the graph to copy.
- def initialize_copy(other)
- super
- @vertices = {}
- @log = other.log.dup
- traverse = lambda do |new_v, old_v|
- return if new_v.outgoing_edges.size == old_v.outgoing_edges.size
- old_v.outgoing_edges.each do |edge|
- destination = add_vertex(edge.destination.name, edge.destination.payload)
- add_edge_no_circular(new_v, destination, edge.requirement)
- traverse.call(destination, edge.destination)
- end
- end
- other.vertices.each do |name, vertex|
- new_vertex = add_vertex(name, vertex.payload, vertex.root?)
- new_vertex.explicit_requirements.replace(vertex.explicit_requirements)
- traverse.call(new_vertex, vertex)
- end
- end
-
- # @return [String] a string suitable for debugging
- def inspect
- "#{self.class}:#{vertices.values.inspect}"
- end
-
- # @param [Hash] options options for dot output.
- # @return [String] Returns a dot format representation of the graph
- def to_dot(options = {})
- edge_label = options.delete(:edge_label)
- raise ArgumentError, "Unknown options: #{options.keys}" unless options.empty?
-
- dot_vertices = []
- dot_edges = []
- vertices.each do |n, v|
- dot_vertices << " #{n} [label=\"{#{n}|#{v.payload}}\"]"
- v.outgoing_edges.each do |e|
- label = edge_label ? edge_label.call(e) : e.requirement
- dot_edges << " #{e.origin.name} -> #{e.destination.name} [label=#{label.to_s.dump}]"
- end
- end
-
- dot_vertices.uniq!
- dot_vertices.sort!
- dot_edges.uniq!
- dot_edges.sort!
-
- dot = dot_vertices.unshift('digraph G {').push('') + dot_edges.push('}')
- dot.join("\n")
- end
-
- # @param [DependencyGraph] other
- # @return [Boolean] whether the two dependency graphs are equal, determined
- # by a recursive traversal of each {#root_vertices} and its
- # {Vertex#successors}
- def ==(other)
- return false unless other
- return true if equal?(other)
- vertices.each do |name, vertex|
- other_vertex = other.vertex_named(name)
- return false unless other_vertex
- return false unless vertex.payload == other_vertex.payload
- return false unless other_vertex.successors.to_set == vertex.successors.to_set
- end
- end
-
- # @param [String] name
- # @param [Object] payload
- # @param [Array<String>] parent_names
- # @param [Object] requirement the requirement that is requiring the child
- # @return [void]
- def add_child_vertex(name, payload, parent_names, requirement)
- root = !parent_names.delete(nil) { true }
- vertex = add_vertex(name, payload, root)
- vertex.explicit_requirements << requirement if root
- parent_names.each do |parent_name|
- parent_vertex = vertex_named(parent_name)
- add_edge(parent_vertex, vertex, requirement)
- end
- vertex
- end
-
- # Adds a vertex with the given name, or updates the existing one.
- # @param [String] name
- # @param [Object] payload
- # @return [Vertex] the vertex that was added to `self`
- def add_vertex(name, payload, root = false)
- log.add_vertex(self, name, payload, root)
- end
-
- # Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
- # removing any non-root vertices that were orphaned in the process
- # @param [String] name
- # @return [Array<Vertex>] the vertices which have been detached
- def detach_vertex_named(name)
- log.detach_vertex_named(self, name)
- end
-
- # @param [String] name
- # @return [Vertex,nil] the vertex with the given name
- def vertex_named(name)
- vertices[name]
- end
-
- # @param [String] name
- # @return [Vertex,nil] the root vertex with the given name
- def root_vertex_named(name)
- vertex = vertex_named(name)
- vertex if vertex && vertex.root?
- end
-
- # Adds a new {Edge} to the dependency graph
- # @param [Vertex] origin
- # @param [Vertex] destination
- # @param [Object] requirement the requirement that this edge represents
- # @return [Edge] the added edge
- def add_edge(origin, destination, requirement)
- if destination.path_to?(origin)
- raise CircularDependencyError.new(path(destination, origin))
- end
- add_edge_no_circular(origin, destination, requirement)
- end
-
- # Deletes an {Edge} from the dependency graph
- # @param [Edge] edge
- # @return [Void]
- def delete_edge(edge)
- log.delete_edge(self, edge.origin.name, edge.destination.name, edge.requirement)
- end
-
- # Sets the payload of the vertex with the given name
- # @param [String] name the name of the vertex
- # @param [Object] payload the payload
- # @return [Void]
- def set_payload(name, payload)
- log.set_payload(self, name, payload)
- end
-
- private
-
- # Adds a new {Edge} to the dependency graph without checking for
- # circularity.
- # @param (see #add_edge)
- # @return (see #add_edge)
- def add_edge_no_circular(origin, destination, requirement)
- log.add_edge_no_circular(self, origin.name, destination.name, requirement)
- end
-
- # Returns the path between two vertices
- # @raise [ArgumentError] if there is no path between the vertices
- # @param [Vertex] from
- # @param [Vertex] to
- # @return [Array<Vertex>] the shortest path from `from` to `to`
- def path(from, to)
- distances = Hash.new(vertices.size + 1)
- distances[from.name] = 0
- predecessors = {}
- each do |vertex|
- vertex.successors.each do |successor|
- if distances[successor.name] > distances[vertex.name] + 1
- distances[successor.name] = distances[vertex.name] + 1
- predecessors[successor] = vertex
- end
- end
- end
-
- path = [to]
- while before = predecessors[to]
- path << before
- to = before
- break if to == from
- end
-
- unless path.last.equal?(from)
- raise ArgumentError, "There is no path from #{from.name} to #{to.name}"
- end
-
- path.reverse
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/action.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
deleted file mode 100644
index 8707ec451d..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/action.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- class DependencyGraph
- # An action that modifies a {DependencyGraph} that is reversible.
- # @abstract
- class Action
- # rubocop:disable Lint/UnusedMethodArgument
-
- # @return [Symbol] The name of the action.
- def self.action_name
- raise 'Abstract'
- end
-
- # Performs the action on the given graph.
- # @param [DependencyGraph] graph the graph to perform the action on.
- # @return [Void]
- def up(graph)
- raise 'Abstract'
- end
-
- # Reverses the action on the given graph.
- # @param [DependencyGraph] graph the graph to reverse the action on.
- # @return [Void]
- def down(graph)
- raise 'Abstract'
- end
-
- # @return [Action,Nil] The previous action
- attr_accessor :previous
-
- # @return [Action,Nil] The next action
- attr_accessor :next
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
deleted file mode 100644
index aa9815c5ae..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'action'
-module Gem::Molinillo
- class DependencyGraph
- # @!visibility private
- # (see DependencyGraph#add_edge_no_circular)
- class AddEdgeNoCircular < Action
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :add_vertex
- end
-
- # (see Action#up)
- def up(graph)
- edge = make_edge(graph)
- edge.origin.outgoing_edges << edge
- edge.destination.incoming_edges << edge
- edge
- end
-
- # (see Action#down)
- def down(graph)
- edge = make_edge(graph)
- delete_first(edge.origin.outgoing_edges, edge)
- delete_first(edge.destination.incoming_edges, edge)
- end
-
- # @!group AddEdgeNoCircular
-
- # @return [String] the name of the origin of the edge
- attr_reader :origin
-
- # @return [String] the name of the destination of the edge
- attr_reader :destination
-
- # @return [Object] the requirement that the edge represents
- attr_reader :requirement
-
- # @param [DependencyGraph] graph the graph to find vertices from
- # @return [Edge] The edge this action adds
- def make_edge(graph)
- Edge.new(graph.vertex_named(origin), graph.vertex_named(destination), requirement)
- end
-
- # Initialize an action to add an edge to a dependency graph
- # @param [String] origin the name of the origin of the edge
- # @param [String] destination the name of the destination of the edge
- # @param [Object] requirement the requirement that the edge represents
- def initialize(origin, destination, requirement)
- @origin = origin
- @destination = destination
- @requirement = requirement
- end
-
- private
-
- def delete_first(array, item)
- return unless index = array.index(item)
- array.delete_at(index)
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
deleted file mode 100644
index 9c7066a669..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'action'
-module Gem::Molinillo
- class DependencyGraph
- # @!visibility private
- # (see DependencyGraph#add_vertex)
- class AddVertex < Action # :nodoc:
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :add_vertex
- end
-
- # (see Action#up)
- def up(graph)
- if existing = graph.vertices[name]
- @existing_payload = existing.payload
- @existing_root = existing.root
- end
- vertex = existing || Vertex.new(name, payload)
- graph.vertices[vertex.name] = vertex
- vertex.payload ||= payload
- vertex.root ||= root
- vertex
- end
-
- # (see Action#down)
- def down(graph)
- if defined?(@existing_payload)
- vertex = graph.vertices[name]
- vertex.payload = @existing_payload
- vertex.root = @existing_root
- else
- graph.vertices.delete(name)
- end
- end
-
- # @!group AddVertex
-
- # @return [String] the name of the vertex
- attr_reader :name
-
- # @return [Object] the payload for the vertex
- attr_reader :payload
-
- # @return [Boolean] whether the vertex is root or not
- attr_reader :root
-
- # Initialize an action to add a vertex to a dependency graph
- # @param [String] name the name of the vertex
- # @param [Object] payload the payload for the vertex
- # @param [Boolean] root whether the vertex is root or not
- def initialize(name, payload, root)
- @name = name
- @payload = payload
- @root = root
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
deleted file mode 100644
index 1e62c0a0b6..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'action'
-module Gem::Molinillo
- class DependencyGraph
- # @!visibility private
- # (see DependencyGraph#delete_edge)
- class DeleteEdge < Action
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :delete_edge
- end
-
- # (see Action#up)
- def up(graph)
- edge = make_edge(graph)
- edge.origin.outgoing_edges.delete(edge)
- edge.destination.incoming_edges.delete(edge)
- end
-
- # (see Action#down)
- def down(graph)
- edge = make_edge(graph)
- edge.origin.outgoing_edges << edge
- edge.destination.incoming_edges << edge
- edge
- end
-
- # @!group DeleteEdge
-
- # @return [String] the name of the origin of the edge
- attr_reader :origin_name
-
- # @return [String] the name of the destination of the edge
- attr_reader :destination_name
-
- # @return [Object] the requirement that the edge represents
- attr_reader :requirement
-
- # @param [DependencyGraph] graph the graph to find vertices from
- # @return [Edge] The edge this action adds
- def make_edge(graph)
- Edge.new(
- graph.vertex_named(origin_name),
- graph.vertex_named(destination_name),
- requirement
- )
- end
-
- # Initialize an action to add an edge to a dependency graph
- # @param [String] origin_name the name of the origin of the edge
- # @param [String] destination_name the name of the destination of the edge
- # @param [Object] requirement the requirement that the edge represents
- def initialize(origin_name, destination_name, requirement)
- @origin_name = origin_name
- @destination_name = destination_name
- @requirement = requirement
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
deleted file mode 100644
index 6132f969b9..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'action'
-module Gem::Molinillo
- class DependencyGraph
- # @!visibility private
- # @see DependencyGraph#detach_vertex_named
- class DetachVertexNamed < Action
- # @!group Action
-
- # (see Action#name)
- def self.action_name
- :add_vertex
- end
-
- # (see Action#up)
- def up(graph)
- return [] unless @vertex = graph.vertices.delete(name)
-
- removed_vertices = [@vertex]
- @vertex.outgoing_edges.each do |e|
- v = e.destination
- v.incoming_edges.delete(e)
- if !v.root? && v.incoming_edges.empty?
- removed_vertices.concat graph.detach_vertex_named(v.name)
- end
- end
-
- @vertex.incoming_edges.each do |e|
- v = e.origin
- v.outgoing_edges.delete(e)
- end
-
- removed_vertices
- end
-
- # (see Action#down)
- def down(graph)
- return unless @vertex
- graph.vertices[@vertex.name] = @vertex
- @vertex.outgoing_edges.each do |e|
- e.destination.incoming_edges << e
- end
- @vertex.incoming_edges.each do |e|
- e.origin.outgoing_edges << e
- end
- end
-
- # @!group DetachVertexNamed
-
- # @return [String] the name of the vertex to detach
- attr_reader :name
-
- # Initialize an action to detach a vertex from a dependency graph
- # @param [String] name the name of the vertex to detach
- def initialize(name)
- @name = name
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/log.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
deleted file mode 100644
index 6954c4b1f8..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/log.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'add_edge_no_circular'
-require_relative 'add_vertex'
-require_relative 'delete_edge'
-require_relative 'detach_vertex_named'
-require_relative 'set_payload'
-require_relative 'tag'
-
-module Gem::Molinillo
- class DependencyGraph
- # A log for dependency graph actions
- class Log
- # Initializes an empty log
- def initialize
- @current_action = @first_action = nil
- end
-
- # @!macro [new] action
- # {include:DependencyGraph#$0}
- # @param [Graph] graph the graph to perform the action on
- # @param (see DependencyGraph#$0)
- # @return (see DependencyGraph#$0)
-
- # @macro action
- def tag(graph, tag)
- push_action(graph, Tag.new(tag))
- end
-
- # @macro action
- def add_vertex(graph, name, payload, root)
- push_action(graph, AddVertex.new(name, payload, root))
- end
-
- # @macro action
- def detach_vertex_named(graph, name)
- push_action(graph, DetachVertexNamed.new(name))
- end
-
- # @macro action
- def add_edge_no_circular(graph, origin, destination, requirement)
- push_action(graph, AddEdgeNoCircular.new(origin, destination, requirement))
- end
-
- # {include:DependencyGraph#delete_edge}
- # @param [Graph] graph the graph to perform the action on
- # @param [String] origin_name
- # @param [String] destination_name
- # @param [Object] requirement
- # @return (see DependencyGraph#delete_edge)
- def delete_edge(graph, origin_name, destination_name, requirement)
- push_action(graph, DeleteEdge.new(origin_name, destination_name, requirement))
- end
-
- # @macro action
- def set_payload(graph, name, payload)
- push_action(graph, SetPayload.new(name, payload))
- end
-
- # Pops the most recent action from the log and undoes the action
- # @param [DependencyGraph] graph
- # @return [Action] the action that was popped off the log
- def pop!(graph)
- return unless action = @current_action
- unless @current_action = action.previous
- @first_action = nil
- end
- action.down(graph)
- action
- end
-
- extend Enumerable
-
- # @!visibility private
- # Enumerates each action in the log
- # @yield [Action]
- def each
- return enum_for unless block_given?
- action = @first_action
- loop do
- break unless action
- yield action
- action = action.next
- end
- self
- end
-
- # @!visibility private
- # Enumerates each action in the log in reverse order
- # @yield [Action]
- def reverse_each
- return enum_for(:reverse_each) unless block_given?
- action = @current_action
- loop do
- break unless action
- yield action
- action = action.previous
- end
- self
- end
-
- # @macro action
- def rewind_to(graph, tag)
- loop do
- action = pop!(graph)
- raise "No tag #{tag.inspect} found" unless action
- break if action.class.action_name == :tag && action.tag == tag
- end
- end
-
- private
-
- # Adds the given action to the log, running the action
- # @param [DependencyGraph] graph
- # @param [Action] action
- # @return The value returned by `action.up`
- def push_action(graph, action)
- action.previous = @current_action
- @current_action.next = action if @current_action
- @current_action = action
- @first_action ||= action
- action.up(graph)
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
deleted file mode 100644
index 9bcaaae0f9..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'action'
-module Gem::Molinillo
- class DependencyGraph
- # @!visibility private
- # @see DependencyGraph#set_payload
- class SetPayload < Action # :nodoc:
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :set_payload
- end
-
- # (see Action#up)
- def up(graph)
- vertex = graph.vertex_named(name)
- @old_payload = vertex.payload
- vertex.payload = payload
- end
-
- # (see Action#down)
- def down(graph)
- graph.vertex_named(name).payload = @old_payload
- end
-
- # @!group SetPayload
-
- # @return [String] the name of the vertex
- attr_reader :name
-
- # @return [Object] the payload for the vertex
- attr_reader :payload
-
- # Initialize an action to add set the payload for a vertex in a dependency
- # graph
- # @param [String] name the name of the vertex
- # @param [Object] payload the payload for the vertex
- def initialize(name, payload)
- @name = name
- @payload = payload
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
deleted file mode 100644
index 62f243a2af..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'action'
-module Gem::Molinillo
- class DependencyGraph
- # @!visibility private
- # @see DependencyGraph#tag
- class Tag < Action
- # @!group Action
-
- # (see Action.action_name)
- def self.action_name
- :tag
- end
-
- # (see Action#up)
- def up(graph)
- end
-
- # (see Action#down)
- def down(graph)
- end
-
- # @!group Tag
-
- # @return [Object] An opaque tag
- attr_reader :tag
-
- # Initialize an action to tag a state of a dependency graph
- # @param [Object] tag an opaque tag
- def initialize(tag)
- @tag = tag
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
deleted file mode 100644
index 074de369be..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- class DependencyGraph
- # A vertex in a {DependencyGraph} that encapsulates a {#name} and a
- # {#payload}
- class Vertex
- # @return [String] the name of the vertex
- attr_accessor :name
-
- # @return [Object] the payload the vertex holds
- attr_accessor :payload
-
- # @return [Array<Object>] the explicit requirements that required
- # this vertex
- attr_reader :explicit_requirements
-
- # @return [Boolean] whether the vertex is considered a root vertex
- attr_accessor :root
- alias root? root
-
- # Initializes a vertex with the given name and payload.
- # @param [String] name see {#name}
- # @param [Object] payload see {#payload}
- def initialize(name, payload)
- @name = name.frozen? ? name : name.dup.freeze
- @payload = payload
- @explicit_requirements = []
- @outgoing_edges = []
- @incoming_edges = []
- end
-
- # @return [Array<Object>] all of the requirements that required
- # this vertex
- def requirements
- (incoming_edges.map(&:requirement) + explicit_requirements).uniq
- end
-
- # @return [Array<Edge>] the edges of {#graph} that have `self` as their
- # {Edge#origin}
- attr_accessor :outgoing_edges
-
- # @return [Array<Edge>] the edges of {#graph} that have `self` as their
- # {Edge#destination}
- attr_accessor :incoming_edges
-
- # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
- # `self` as their {Edge#destination}
- def predecessors
- incoming_edges.map(&:origin)
- end
-
- # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
- # {#descendent?}
- def recursive_predecessors
- _recursive_predecessors
- end
-
- # @param [Set<Vertex>] vertices the set to add the predecessors to
- # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
- # {#descendent?}
- def _recursive_predecessors(vertices = new_vertex_set)
- incoming_edges.each do |edge|
- vertex = edge.origin
- next unless vertices.add?(vertex)
- vertex._recursive_predecessors(vertices)
- end
-
- vertices
- end
- protected :_recursive_predecessors
-
- # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
- # `self` as their {Edge#origin}
- def successors
- outgoing_edges.map(&:destination)
- end
-
- # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
- # {#ancestor?}
- def recursive_successors
- _recursive_successors
- end
-
- # @param [Set<Vertex>] vertices the set to add the successors to
- # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
- # {#ancestor?}
- def _recursive_successors(vertices = new_vertex_set)
- outgoing_edges.each do |edge|
- vertex = edge.destination
- next unless vertices.add?(vertex)
- vertex._recursive_successors(vertices)
- end
-
- vertices
- end
- protected :_recursive_successors
-
- # @return [String] a string suitable for debugging
- def inspect
- "#{self.class}:#{name}(#{payload.inspect})"
- end
-
- # @return [Boolean] whether the two vertices are equal, determined
- # by a recursive traversal of each {Vertex#successors}
- def ==(other)
- return true if equal?(other)
- shallow_eql?(other) &&
- successors.to_set == other.successors.to_set
- end
-
- # @param [Vertex] other the other vertex to compare to
- # @return [Boolean] whether the two vertices are equal, determined
- # solely by {#name} and {#payload} equality
- def shallow_eql?(other)
- return true if equal?(other)
- other &&
- name == other.name &&
- payload == other.payload
- end
-
- alias eql? ==
-
- # @return [Fixnum] a hash for the vertex based upon its {#name}
- def hash
- name.hash
- end
-
- # Is there a path from `self` to `other` following edges in the
- # dependency graph?
- # @return whether there is a path following edges within this {#graph}
- def path_to?(other)
- _path_to?(other)
- end
-
- alias descendent? path_to?
-
- # @param [Vertex] other the vertex to check if there's a path to
- # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
- # @return [Boolean] whether there is a path to `other` from `self`
- def _path_to?(other, visited = new_vertex_set)
- return false unless visited.add?(self)
- return true if equal?(other)
- successors.any? { |v| v._path_to?(other, visited) }
- end
- protected :_path_to?
-
- # Is there a path from `other` to `self` following edges in the
- # dependency graph?
- # @return whether there is a path following edges within this {#graph}
- def ancestor?(other)
- other.path_to?(self)
- end
-
- alias is_reachable_from? ancestor?
-
- def new_vertex_set
- require 'set'
- Set.new
- end
- private :new_vertex_set
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/errors.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/errors.rb
deleted file mode 100644
index 07ea5fdf37..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/errors.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- # An error that occurred during the resolution process
- class ResolverError < StandardError; end
-
- # An error caused by searching for a dependency that is completely unknown,
- # i.e. has no versions available whatsoever.
- class NoSuchDependencyError < ResolverError
- # @return [Object] the dependency that could not be found
- attr_accessor :dependency
-
- # @return [Array<Object>] the specifications that depended upon {#dependency}
- attr_accessor :required_by
-
- # Initializes a new error with the given missing dependency.
- # @param [Object] dependency @see {#dependency}
- # @param [Array<Object>] required_by @see {#required_by}
- def initialize(dependency, required_by = [])
- @dependency = dependency
- @required_by = required_by.uniq
- super()
- end
-
- # The error message for the missing dependency, including the specifications
- # that had this dependency.
- def message
- sources = required_by.map { |r| "`#{r}`" }.join(' and ')
- message = "Unable to find a specification for `#{dependency}`"
- message += " depended upon by #{sources}" unless sources.empty?
- message
- end
- end
-
- # An error caused by attempting to fulfil a dependency that was circular
- #
- # @note This exception will be thrown if and only if a {Vertex} is added to a
- # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
- # existing {DependencyGraph::Vertex}
- class CircularDependencyError < ResolverError
- # [Set<Object>] the dependencies responsible for causing the error
- attr_reader :dependencies
-
- # Initializes a new error with the given circular vertices.
- # @param [Array<DependencyGraph::Vertex>] vertices the vertices in the dependency
- # that caused the error
- def initialize(vertices)
- super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}"
- @dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set
- end
- end
-
- # An error caused by conflicts in version
- class VersionConflict < ResolverError
- # @return [{String => Resolution::Conflict}] the conflicts that caused
- # resolution to fail
- attr_reader :conflicts
-
- # @return [SpecificationProvider] the specification provider used during
- # resolution
- attr_reader :specification_provider
-
- # Initializes a new error with the given version conflicts.
- # @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
- # @param [SpecificationProvider] specification_provider see {#specification_provider}
- def initialize(conflicts, specification_provider)
- pairs = []
- conflicts.values.flat_map(&:requirements).each do |conflicting|
- conflicting.each do |source, conflict_requirements|
- conflict_requirements.each do |c|
- pairs << [c, source]
- end
- end
- end
-
- super "Unable to satisfy the following requirements:\n\n" \
- "#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
-
- @conflicts = conflicts
- @specification_provider = specification_provider
- end
-
- require_relative 'delegates/specification_provider'
- include Delegates::SpecificationProvider
-
- # @return [String] An error message that includes requirement trees,
- # which is much more detailed & customizable than the default message
- # @param [Hash] opts the options to create a message with.
- # @option opts [String] :solver_name The user-facing name of the solver
- # @option opts [String] :possibility_type The generic name of a possibility
- # @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees
- # @option opts [Proc] :printable_requirement A proc that pretty-prints requirements
- # @option opts [Proc] :additional_message_for_conflict A proc that appends additional
- # messages for each conflict
- # @option opts [Proc] :version_for_spec A proc that returns the version number for a
- # possibility
- def message_with_trees(opts = {})
- solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
- possibility_type = opts.delete(:possibility_type) { 'possibility named' }
- reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
- printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
- additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
- version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
- incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
- proc do |name, _conflict|
- %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
- end
- end
-
- full_message_for_conflict = opts.delete(:full_message_for_conflict) do
- proc do |name, conflict|
- o = "\n".dup << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
- if conflict.locked_requirement
- o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
- o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
- o << %(\n)
- end
- o << %( In #{name_for_explicit_dependency_source}:\n)
- trees = reduce_trees.call(conflict.requirement_trees)
-
- o << trees.map do |tree|
- t = ''.dup
- depth = 2
- tree.each do |req|
- t << ' ' * depth << printable_requirement.call(req)
- unless tree.last == req
- if spec = conflict.activated_by_name[name_for(req)]
- t << %( was resolved to #{version_for_spec.call(spec)}, which)
- end
- t << %( depends on)
- end
- t << %(\n)
- depth += 1
- end
- t
- end.join("\n")
-
- additional_message_for_conflict.call(o, name, conflict)
-
- o
- end
- end
-
- conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
- o << full_message_for_conflict.call(name, conflict)
- end.strip
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb
deleted file mode 100644
index 8ed3a920a2..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- # The version of Gem::Molinillo.
- VERSION = '0.8.0'.freeze
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
deleted file mode 100644
index 85860902fc..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/modules/specification_provider.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- # Provides information about specifications and dependencies to the resolver,
- # allowing the {Resolver} class to remain generic while still providing power
- # and flexibility.
- #
- # This module contains the methods that users of Gem::Molinillo must to implement,
- # using knowledge of their own model classes.
- module SpecificationProvider
- # Search for the specifications that match the given dependency.
- # The specifications in the returned array will be considered in reverse
- # order, so the latest version ought to be last.
- # @note This method should be 'pure', i.e. the return value should depend
- # only on the `dependency` parameter.
- #
- # @param [Object] dependency
- # @return [Array<Object>] the specifications that satisfy the given
- # `dependency`.
- def search_for(dependency)
- []
- end
-
- # Returns the dependencies of `specification`.
- # @note This method should be 'pure', i.e. the return value should depend
- # only on the `specification` parameter.
- #
- # @param [Object] specification
- # @return [Array<Object>] the dependencies that are required by the given
- # `specification`.
- def dependencies_for(specification)
- []
- end
-
- # Determines whether the given `requirement` is satisfied by the given
- # `spec`, in the context of the current `activated` dependency graph.
- #
- # @param [Object] requirement
- # @param [DependencyGraph] activated the current dependency graph in the
- # resolution process.
- # @param [Object] spec
- # @return [Boolean] whether `requirement` is satisfied by `spec` in the
- # context of the current `activated` dependency graph.
- def requirement_satisfied_by?(requirement, activated, spec)
- true
- end
-
- # Determines whether two arrays of dependencies are equal, and thus can be
- # grouped.
- #
- # @param [Array<Object>] dependencies
- # @param [Array<Object>] other_dependencies
- # @return [Boolean] whether `dependencies` and `other_dependencies` should
- # be considered equal.
- def dependencies_equal?(dependencies, other_dependencies)
- dependencies == other_dependencies
- end
-
- # Returns the name for the given `dependency`.
- # @note This method should be 'pure', i.e. the return value should depend
- # only on the `dependency` parameter.
- #
- # @param [Object] dependency
- # @return [String] the name for the given `dependency`.
- def name_for(dependency)
- dependency.to_s
- end
-
- # @return [String] the name of the source of explicit dependencies, i.e.
- # those passed to {Resolver#resolve} directly.
- def name_for_explicit_dependency_source
- 'user-specified dependency'
- end
-
- # @return [String] the name of the source of 'locked' dependencies, i.e.
- # those passed to {Resolver#resolve} directly as the `base`
- def name_for_locking_dependency_source
- 'Lockfile'
- end
-
- # Sort dependencies so that the ones that are easiest to resolve are first.
- # Easiest to resolve is (usually) defined by:
- # 1) Is this dependency already activated?
- # 2) How relaxed are the requirements?
- # 3) Are there any conflicts for this dependency?
- # 4) How many possibilities are there to satisfy this dependency?
- #
- # @param [Array<Object>] dependencies
- # @param [DependencyGraph] activated the current dependency graph in the
- # resolution process.
- # @param [{String => Array<Conflict>}] conflicts
- # @return [Array<Object>] a sorted copy of `dependencies`.
- def sort_dependencies(dependencies, activated, conflicts)
- dependencies.sort_by do |dependency|
- name = name_for(dependency)
- [
- activated.vertex_named(name).payload ? 0 : 1,
- conflicts[name] ? 0 : 1,
- ]
- end
- end
-
- # Returns whether this dependency, which has no possible matching
- # specifications, can safely be ignored.
- #
- # @param [Object] dependency
- # @return [Boolean] whether this dependency can safely be skipped.
- def allow_missing?(dependency)
- false
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/modules/ui.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/modules/ui.rb
deleted file mode 100644
index 464722902e..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/modules/ui.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- # Conveys information about the resolution process to a user.
- module UI
- # The {IO} object that should be used to print output. `STDOUT`, by default.
- #
- # @return [IO]
- def output
- STDOUT
- end
-
- # Called roughly every {#progress_rate}, this method should convey progress
- # to the user.
- #
- # @return [void]
- def indicate_progress
- output.print '.' unless debug?
- end
-
- # How often progress should be conveyed to the user via
- # {#indicate_progress}, in seconds. A third of a second, by default.
- #
- # @return [Float]
- def progress_rate
- 0.33
- end
-
- # Called before resolution begins.
- #
- # @return [void]
- def before_resolution
- output.print 'Resolving dependencies...'
- end
-
- # Called after resolution ends (either successfully or with an error).
- # By default, prints a newline.
- #
- # @return [void]
- def after_resolution
- output.puts
- end
-
- # Conveys debug information to the user.
- #
- # @param [Integer] depth the current depth of the resolution process.
- # @return [void]
- def debug(depth = 0)
- if debug?
- debug_info = yield
- debug_info = debug_info.inspect unless debug_info.is_a?(String)
- debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" }
- output.puts debug_info
- end
- end
-
- # Whether or not debug messages should be printed.
- # By default, whether or not the `MOLINILLO_DEBUG` environment variable is
- # set.
- #
- # @return [Boolean]
- def debug?
- return @debug_mode if defined?(@debug_mode)
- @debug_mode = ENV['MOLINILLO_DEBUG']
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/resolution.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/resolution.rb
deleted file mode 100644
index 5cfc6e3a0d..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/resolution.rb
+++ /dev/null
@@ -1,839 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- class Resolver
- # A specific resolution from a given {Resolver}
- class Resolution
- # A conflict that the resolution process encountered
- # @attr [Object] requirement the requirement that immediately led to the conflict
- # @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
- # @attr [Object, nil] existing the existing spec that was in conflict with
- # the {#possibility}
- # @attr [Object] possibility_set the set of specs that was unable to be
- # activated due to a conflict.
- # @attr [Object] locked_requirement the relevant locking requirement.
- # @attr [Array<Array<Object>>] requirement_trees the different requirement
- # trees that led to every requirement for the conflicting name.
- # @attr [{String=>Object}] activated_by_name the already-activated specs.
- # @attr [Object] underlying_error an error that has occurred during resolution, and
- # will be raised at the end of it if no resolution is found.
- Conflict = Struct.new(
- :requirement,
- :requirements,
- :existing,
- :possibility_set,
- :locked_requirement,
- :requirement_trees,
- :activated_by_name,
- :underlying_error
- )
-
- class Conflict
- # @return [Object] a spec that was unable to be activated due to a conflict
- def possibility
- possibility_set && possibility_set.latest_version
- end
- end
-
- # A collection of possibility states that share the same dependencies
- # @attr [Array] dependencies the dependencies for this set of possibilities
- # @attr [Array] possibilities the possibilities
- PossibilitySet = Struct.new(:dependencies, :possibilities)
-
- class PossibilitySet
- # String representation of the possibility set, for debugging
- def to_s
- "[#{possibilities.join(', ')}]"
- end
-
- # @return [Object] most up-to-date dependency in the possibility set
- def latest_version
- possibilities.last
- end
- end
-
- # Details of the state to unwind to when a conflict occurs, and the cause of the unwind
- # @attr [Integer] state_index the index of the state to unwind to
- # @attr [Object] state_requirement the requirement of the state we're unwinding to
- # @attr [Array] requirement_tree for the requirement we're relaxing
- # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict
- # @attr [Array] requirement_trees for the conflict
- # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind
- UnwindDetails = Struct.new(
- :state_index,
- :state_requirement,
- :requirement_tree,
- :conflicting_requirements,
- :requirement_trees,
- :requirements_unwound_to_instead
- )
-
- class UnwindDetails
- include Comparable
-
- # We compare UnwindDetails when choosing which state to unwind to. If
- # two options have the same state_index we prefer the one most
- # removed from a requirement that caused the conflict. Both options
- # would unwind to the same state, but a `grandparent` option will
- # filter out fewer of its possibilities after doing so - where a state
- # is both a `parent` and a `grandparent` to requirements that have
- # caused a conflict this is the correct behaviour.
- # @param [UnwindDetail] other UnwindDetail to be compared
- # @return [Integer] integer specifying ordering
- def <=>(other)
- if state_index > other.state_index
- 1
- elsif state_index == other.state_index
- reversed_requirement_tree_index <=> other.reversed_requirement_tree_index
- else
- -1
- end
- end
-
- # @return [Integer] index of state requirement in reversed requirement tree
- # (the conflicting requirement itself will be at position 0)
- def reversed_requirement_tree_index
- @reversed_requirement_tree_index ||=
- if state_requirement
- requirement_tree.reverse.index(state_requirement)
- else
- 999_999
- end
- end
-
- # @return [Boolean] where the requirement of the state we're unwinding
- # to directly caused the conflict. Note: in this case, it is
- # impossible for the state we're unwinding to to be a parent of
- # any of the other conflicting requirements (or we would have
- # circularity)
- def unwinding_to_primary_requirement?
- requirement_tree.last == state_requirement
- end
-
- # @return [Array] array of sub-dependencies to avoid when choosing a
- # new possibility for the state we've unwound to. Only relevant for
- # non-primary unwinds
- def sub_dependencies_to_avoid
- @requirements_to_avoid ||=
- requirement_trees.map do |tree|
- index = tree.index(state_requirement)
- tree[index + 1] if index
- end.compact
- end
-
- # @return [Array] array of all the requirements that led to the need for
- # this unwind
- def all_requirements
- @all_requirements ||= requirement_trees.flatten(1)
- end
- end
-
- # @return [SpecificationProvider] the provider that knows about
- # dependencies, requirements, specifications, versions, etc.
- attr_reader :specification_provider
-
- # @return [UI] the UI that knows how to communicate feedback about the
- # resolution process back to the user
- attr_reader :resolver_ui
-
- # @return [DependencyGraph] the base dependency graph to which
- # dependencies should be 'locked'
- attr_reader :base
-
- # @return [Array] the dependencies that were explicitly required
- attr_reader :original_requested
-
- # Initializes a new resolution.
- # @param [SpecificationProvider] specification_provider
- # see {#specification_provider}
- # @param [UI] resolver_ui see {#resolver_ui}
- # @param [Array] requested see {#original_requested}
- # @param [DependencyGraph] base see {#base}
- def initialize(specification_provider, resolver_ui, requested, base)
- @specification_provider = specification_provider
- @resolver_ui = resolver_ui
- @original_requested = requested
- @base = base
- @states = []
- @iteration_counter = 0
- @parents_of = Hash.new { |h, k| h[k] = [] }
- end
-
- # Resolves the {#original_requested} dependencies into a full dependency
- # graph
- # @raise [ResolverError] if successful resolution is impossible
- # @return [DependencyGraph] the dependency graph of successfully resolved
- # dependencies
- def resolve
- start_resolution
-
- while state
- break if !state.requirement && state.requirements.empty?
- indicate_progress
- if state.respond_to?(:pop_possibility_state) # DependencyState
- debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
- state.pop_possibility_state.tap do |s|
- if s
- states.push(s)
- activated.tag(s)
- end
- end
- end
- process_topmost_state
- end
-
- resolve_activated_specs
- ensure
- end_resolution
- end
-
- # @return [Integer] the number of resolver iterations in between calls to
- # {#resolver_ui}'s {UI#indicate_progress} method
- attr_accessor :iteration_rate
- private :iteration_rate
-
- # @return [Time] the time at which resolution began
- attr_accessor :started_at
- private :started_at
-
- # @return [Array<ResolutionState>] the stack of states for the resolution
- attr_accessor :states
- private :states
-
- private
-
- # Sets up the resolution process
- # @return [void]
- def start_resolution
- @started_at = Time.now
-
- push_initial_state
-
- debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
- resolver_ui.before_resolution
- end
-
- def resolve_activated_specs
- activated.vertices.each do |_, vertex|
- next unless vertex.payload
-
- latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
- vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
- end
-
- activated.set_payload(vertex.name, latest_version)
- end
- activated.freeze
- end
-
- # Ends the resolution process
- # @return [void]
- def end_resolution
- resolver_ui.after_resolution
- debug do
- "Finished resolution (#{@iteration_counter} steps) " \
- "(Took #{(ended_at = Time.now) - @started_at} seconds) (#{ended_at})"
- end
- debug { 'Unactivated: ' + Hash[activated.vertices.reject { |_n, v| v.payload }].keys.join(', ') } if state
- debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
- end
-
- require_relative 'state'
- require_relative 'modules/specification_provider'
-
- require_relative 'delegates/resolution_state'
- require_relative 'delegates/specification_provider'
-
- include Gem::Molinillo::Delegates::ResolutionState
- include Gem::Molinillo::Delegates::SpecificationProvider
-
- # Processes the topmost available {RequirementState} on the stack
- # @return [void]
- def process_topmost_state
- if possibility
- attempt_to_activate
- else
- create_conflict
- unwind_for_conflict
- end
- rescue CircularDependencyError => underlying_error
- create_conflict(underlying_error)
- unwind_for_conflict
- end
-
- # @return [Object] the current possibility that the resolution is trying
- # to activate
- def possibility
- possibilities.last
- end
-
- # @return [RequirementState] the current state the resolution is
- # operating upon
- def state
- states.last
- end
-
- # Creates and pushes the initial state for the resolution, based upon the
- # {#requested} dependencies
- # @return [void]
- def push_initial_state
- graph = DependencyGraph.new.tap do |dg|
- original_requested.each do |requested|
- vertex = dg.add_vertex(name_for(requested), nil, true)
- vertex.explicit_requirements << requested
- end
- dg.tag(:initial_state)
- end
-
- push_state_for_requirements(original_requested, true, graph)
- end
-
- # Unwinds the states stack because a conflict has been encountered
- # @return [void]
- def unwind_for_conflict
- details_for_unwind = build_details_for_unwind
- unwind_options = unused_unwind_options
- debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" }
- conflicts.tap do |c|
- sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1)
- raise_error_unless_state(c)
- activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
- state.conflicts = c
- state.unused_unwind_options = unwind_options
- filter_possibilities_after_unwind(details_for_unwind)
- index = states.size - 1
- @parents_of.each { |_, a| a.reject! { |i| i >= index } }
- state.unused_unwind_options.reject! { |uw| uw.state_index >= index }
- end
- end
-
- # Raises a VersionConflict error, or any underlying error, if there is no
- # current state
- # @return [void]
- def raise_error_unless_state(conflicts)
- return if state
-
- error = conflicts.values.map(&:underlying_error).compact.first
- raise error || VersionConflict.new(conflicts, specification_provider)
- end
-
- # @return [UnwindDetails] Details of the nearest index to which we could unwind
- def build_details_for_unwind
- # Get the possible unwinds for the current conflict
- current_conflict = conflicts[name]
- binding_requirements = binding_requirements_for_conflict(current_conflict)
- unwind_details = unwind_options_for_requirements(binding_requirements)
-
- last_detail_for_current_unwind = unwind_details.sort.last
- current_detail = last_detail_for_current_unwind
-
- # Look for past conflicts that could be unwound to affect the
- # requirement tree for the current conflict
- all_reqs = last_detail_for_current_unwind.all_requirements
- all_reqs_size = all_reqs.size
- relevant_unused_unwinds = unused_unwind_options.select do |alternative|
- diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
- next if diff_reqs.size == all_reqs_size
- # Find the highest index unwind whilst looping through
- current_detail = alternative if alternative > current_detail
- alternative
- end
-
- # Add the current unwind options to the `unused_unwind_options` array.
- # The "used" option will be filtered out during `unwind_for_conflict`.
- state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
-
- # Update the requirements_unwound_to_instead on any relevant unused unwinds
- relevant_unused_unwinds.each do |d|
- (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
- end
- unwind_details.each do |d|
- (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
- end
-
- current_detail
- end
-
- # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
- # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
- # of resolving the passed requirements
- def unwind_options_for_requirements(binding_requirements)
- unwind_details = []
-
- trees = []
- binding_requirements.reverse_each do |r|
- partial_tree = [r]
- trees << partial_tree
- unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, [])
-
- # If this requirement has alternative possibilities, check if any would
- # satisfy the other requirements that created this conflict
- requirement_state = find_state_for(r)
- if conflict_fixing_possibilities?(requirement_state, binding_requirements)
- unwind_details << UnwindDetails.new(
- states.index(requirement_state),
- r,
- partial_tree,
- binding_requirements,
- trees,
- []
- )
- end
-
- # Next, look at the parent of this requirement, and check if the requirement
- # could have been avoided if an alternative PossibilitySet had been chosen
- parent_r = parent_of(r)
- next if parent_r.nil?
- partial_tree.unshift(parent_r)
- requirement_state = find_state_for(parent_r)
- if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) }
- unwind_details << UnwindDetails.new(
- states.index(requirement_state),
- parent_r,
- partial_tree,
- binding_requirements,
- trees,
- []
- )
- end
-
- # Finally, look at the grandparent and up of this requirement, looking
- # for any possibilities that wouldn't create their parent requirement
- grandparent_r = parent_of(parent_r)
- until grandparent_r.nil?
- partial_tree.unshift(grandparent_r)
- requirement_state = find_state_for(grandparent_r)
- if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) }
- unwind_details << UnwindDetails.new(
- states.index(requirement_state),
- grandparent_r,
- partial_tree,
- binding_requirements,
- trees,
- []
- )
- end
- parent_r = grandparent_r
- grandparent_r = parent_of(parent_r)
- end
- end
-
- unwind_details
- end
-
- # @param [DependencyState] state
- # @param [Array] binding_requirements array of requirements
- # @return [Boolean] whether or not the given state has any possibilities
- # that could satisfy the given requirements
- def conflict_fixing_possibilities?(state, binding_requirements)
- return false unless state
-
- state.possibilities.any? do |possibility_set|
- possibility_set.possibilities.any? do |poss|
- possibility_satisfies_requirements?(poss, binding_requirements)
- end
- end
- end
-
- # Filter's a state's possibilities to remove any that would not fix the
- # conflict we've just rewound from
- # @param [UnwindDetails] unwind_details details of the conflict just
- # unwound from
- # @return [void]
- def filter_possibilities_after_unwind(unwind_details)
- return unless state && !state.possibilities.empty?
-
- if unwind_details.unwinding_to_primary_requirement?
- filter_possibilities_for_primary_unwind(unwind_details)
- else
- filter_possibilities_for_parent_unwind(unwind_details)
- end
- end
-
- # Filter's a state's possibilities to remove any that would not satisfy
- # the requirements in the conflict we've just rewound from
- # @param [UnwindDetails] unwind_details details of the conflict just unwound from
- # @return [void]
- def filter_possibilities_for_primary_unwind(unwind_details)
- unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
- unwinds_to_state << unwind_details
- unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
-
- state.possibilities.reject! do |possibility_set|
- possibility_set.possibilities.none? do |poss|
- unwind_requirement_sets.any? do |requirements|
- possibility_satisfies_requirements?(poss, requirements)
- end
- end
- end
- end
-
- # @param [Object] possibility a single possibility
- # @param [Array] requirements an array of requirements
- # @return [Boolean] whether the possibility satisfies all of the
- # given requirements
- def possibility_satisfies_requirements?(possibility, requirements)
- name = name_for(possibility)
-
- activated.tag(:swap)
- activated.set_payload(name, possibility) if activated.vertex_named(name)
- satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) }
- activated.rewind_to(:swap)
-
- satisfied
- end
-
- # Filter's a state's possibilities to remove any that would (eventually)
- # create a requirement in the conflict we've just rewound from
- # @param [UnwindDetails] unwind_details details of the conflict just unwound from
- # @return [void]
- def filter_possibilities_for_parent_unwind(unwind_details)
- unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
- unwinds_to_state << unwind_details
-
- primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
- parent_unwinds = unwinds_to_state.uniq - primary_unwinds
-
- allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
- states[unwind.state_index].possibilities.select do |possibility_set|
- possibility_set.possibilities.any? do |poss|
- possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
- end
- end
- end
-
- requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
-
- state.possibilities.reject! do |possibility_set|
- !allowed_possibility_sets.include?(possibility_set) &&
- (requirements_to_avoid - possibility_set.dependencies).empty?
- end
- end
-
- # @param [Conflict] conflict
- # @return [Array] minimal array of requirements that would cause the passed
- # conflict to occur.
- def binding_requirements_for_conflict(conflict)
- return [conflict.requirement] if conflict.possibility.nil?
-
- possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
-
- # When there's a `CircularDependency` error the conflicting requirement
- # (the one causing the circular) won't be `conflict.requirement`
- # (which won't be for the right state, because we won't have created it,
- # because it's circular).
- # We need to make sure we have that requirement in the conflict's list,
- # otherwise we won't be able to unwind properly, so we just return all
- # the requirements for the conflict.
- return possible_binding_requirements if conflict.underlying_error
-
- possibilities = search_for(conflict.requirement)
-
- # If all the requirements together don't filter out all possibilities,
- # then the only two requirements we need to consider are the initial one
- # (where the dependency's version was first chosen) and the last
- if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities)
- return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact
- end
-
- # Loop through the possible binding requirements, removing each one
- # that doesn't bind. Use a `reverse_each` as we want the earliest set of
- # binding requirements, and don't use `reject!` as we wish to refine the
- # array *on each iteration*.
- binding_requirements = possible_binding_requirements.dup
- possible_binding_requirements.reverse_each do |req|
- next if req == conflict.requirement
- unless binding_requirement_in_set?(req, binding_requirements, possibilities)
- binding_requirements -= [req]
- end
- end
-
- binding_requirements
- end
-
- # @param [Object] requirement we wish to check
- # @param [Array] possible_binding_requirements array of requirements
- # @param [Array] possibilities array of possibilities the requirements will be used to filter
- # @return [Boolean] whether or not the given requirement is required to filter
- # out all elements of the array of possibilities.
- def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
- possibilities.any? do |poss|
- possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement])
- end
- end
-
- # @param [Object] requirement
- # @return [Object] the requirement that led to `requirement` being added
- # to the list of requirements.
- def parent_of(requirement)
- return unless requirement
- return unless index = @parents_of[requirement].last
- return unless parent_state = @states[index]
- parent_state.requirement
- end
-
- # @param [String] name
- # @return [Object] the requirement that led to a version of a possibility
- # with the given name being activated.
- def requirement_for_existing_name(name)
- return nil unless vertex = activated.vertex_named(name)
- return nil unless vertex.payload
- states.find { |s| s.name == name }.requirement
- end
-
- # @param [Object] requirement
- # @return [ResolutionState] the state whose `requirement` is the given
- # `requirement`.
- def find_state_for(requirement)
- return nil unless requirement
- states.find { |i| requirement == i.requirement }
- end
-
- # @param [Object] underlying_error
- # @return [Conflict] a {Conflict} that reflects the failure to activate
- # the {#possibility} in conjunction with the current {#state}
- def create_conflict(underlying_error = nil)
- vertex = activated.vertex_named(name)
- locked_requirement = locked_requirement_named(name)
-
- requirements = {}
- unless vertex.explicit_requirements.empty?
- requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
- end
- requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
- vertex.incoming_edges.each do |edge|
- (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement)
- end
-
- activated_by_name = {}
- activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload }
- conflicts[name] = Conflict.new(
- requirement,
- requirements,
- vertex.payload && vertex.payload.latest_version,
- possibility,
- locked_requirement,
- requirement_trees,
- activated_by_name,
- underlying_error
- )
- end
-
- # @return [Array<Array<Object>>] The different requirement
- # trees that led to every requirement for the current spec.
- def requirement_trees
- vertex = activated.vertex_named(name)
- vertex.requirements.map { |r| requirement_tree_for(r) }
- end
-
- # @param [Object] requirement
- # @return [Array<Object>] the list of requirements that led to
- # `requirement` being required.
- def requirement_tree_for(requirement)
- tree = []
- while requirement
- tree.unshift(requirement)
- requirement = parent_of(requirement)
- end
- tree
- end
-
- # Indicates progress roughly once every second
- # @return [void]
- def indicate_progress
- @iteration_counter += 1
- @progress_rate ||= resolver_ui.progress_rate
- if iteration_rate.nil?
- if Time.now - started_at >= @progress_rate
- self.iteration_rate = @iteration_counter
- end
- end
-
- if iteration_rate && (@iteration_counter % iteration_rate) == 0
- resolver_ui.indicate_progress
- end
- end
-
- # Calls the {#resolver_ui}'s {UI#debug} method
- # @param [Integer] depth the depth of the {#states} stack
- # @param [Proc] block a block that yields a {#to_s}
- # @return [void]
- def debug(depth = 0, &block)
- resolver_ui.debug(depth, &block)
- end
-
- # Attempts to activate the current {#possibility}
- # @return [void]
- def attempt_to_activate
- debug(depth) { 'Attempting to activate ' + possibility.to_s }
- existing_vertex = activated.vertex_named(name)
- if existing_vertex.payload
- debug(depth) { "Found existing spec (#{existing_vertex.payload})" }
- attempt_to_filter_existing_spec(existing_vertex)
- else
- latest = possibility.latest_version
- possibility.possibilities.select! do |possibility|
- requirement_satisfied_by?(requirement, activated, possibility)
- end
- if possibility.latest_version.nil?
- # ensure there's a possibility for better error messages
- possibility.possibilities << latest if latest
- create_conflict
- unwind_for_conflict
- else
- activate_new_spec
- end
- end
- end
-
- # Attempts to update the existing vertex's `PossibilitySet` with a filtered version
- # @return [void]
- def attempt_to_filter_existing_spec(vertex)
- filtered_set = filtered_possibility_set(vertex)
- if !filtered_set.possibilities.empty?
- activated.set_payload(name, filtered_set)
- new_requirements = requirements.dup
- push_state_for_requirements(new_requirements, false)
- else
- create_conflict
- debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" }
- unwind_for_conflict
- end
- end
-
- # Generates a filtered version of the existing vertex's `PossibilitySet` using the
- # current state's `requirement`
- # @param [Object] vertex existing vertex
- # @return [PossibilitySet] filtered possibility set
- def filtered_possibility_set(vertex)
- PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
- end
-
- # @param [String] requirement_name the spec name to search for
- # @return [Object] the locked spec named `requirement_name`, if one
- # is found on {#base}
- def locked_requirement_named(requirement_name)
- vertex = base.vertex_named(requirement_name)
- vertex && vertex.payload
- end
-
- # Add the current {#possibility} to the dependency graph of the current
- # {#state}
- # @return [void]
- def activate_new_spec
- conflicts.delete(name)
- debug(depth) { "Activated #{name} at #{possibility}" }
- activated.set_payload(name, possibility)
- require_nested_dependencies_for(possibility)
- end
-
- # Requires the dependencies that the recently activated spec has
- # @param [Object] possibility_set the PossibilitySet that has just been
- # activated
- # @return [void]
- def require_nested_dependencies_for(possibility_set)
- nested_dependencies = dependencies_for(possibility_set.latest_version)
- debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
- nested_dependencies.each do |d|
- activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d)
- parent_index = states.size - 1
- parents = @parents_of[d]
- parents << parent_index if parents.empty?
- end
-
- push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?)
- end
-
- # Pushes a new {DependencyState} that encapsulates both existing and new
- # requirements
- # @param [Array] new_requirements
- # @param [Boolean] requires_sort
- # @param [Object] new_activated
- # @return [void]
- def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
- new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
- new_requirement = nil
- loop do
- new_requirement = new_requirements.shift
- break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement }
- end
- new_name = new_requirement ? name_for(new_requirement) : ''.freeze
- possibilities = possibilities_for_requirement(new_requirement)
- handle_missing_or_push_dependency_state DependencyState.new(
- new_name, new_requirements, new_activated,
- new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup
- )
- end
-
- # Checks a proposed requirement with any existing locked requirement
- # before generating an array of possibilities for it.
- # @param [Object] requirement the proposed requirement
- # @param [Object] activated
- # @return [Array] possibilities
- def possibilities_for_requirement(requirement, activated = self.activated)
- return [] unless requirement
- if locked_requirement_named(name_for(requirement))
- return locked_requirement_possibility_set(requirement, activated)
- end
-
- group_possibilities(search_for(requirement))
- end
-
- # @param [Object] requirement the proposed requirement
- # @param [Object] activated
- # @return [Array] possibility set containing only the locked requirement, if any
- def locked_requirement_possibility_set(requirement, activated = self.activated)
- all_possibilities = search_for(requirement)
- locked_requirement = locked_requirement_named(name_for(requirement))
-
- # Longwinded way to build a possibilities array with either the locked
- # requirement or nothing in it. Required, since the API for
- # locked_requirement isn't guaranteed.
- locked_possibilities = all_possibilities.select do |possibility|
- requirement_satisfied_by?(locked_requirement, activated, possibility)
- end
-
- group_possibilities(locked_possibilities)
- end
-
- # Build an array of PossibilitySets, with each element representing a group of
- # dependency versions that all have the same sub-dependency version constraints
- # and are contiguous.
- # @param [Array] possibilities an array of possibilities
- # @return [Array<PossibilitySet>] an array of possibility sets
- def group_possibilities(possibilities)
- possibility_sets = []
- current_possibility_set = nil
-
- possibilities.reverse_each do |possibility|
- dependencies = dependencies_for(possibility)
- if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
- current_possibility_set.possibilities.unshift(possibility)
- else
- possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
- current_possibility_set = possibility_sets.first
- end
- end
-
- possibility_sets
- end
-
- # Pushes a new {DependencyState}.
- # If the {#specification_provider} says to
- # {SpecificationProvider#allow_missing?} that particular requirement, and
- # there are no possibilities for that requirement, then `state` is not
- # pushed, and the vertex in {#activated} is removed, and we continue
- # resolving the remaining requirements.
- # @param [DependencyState] state
- # @return [void]
- def handle_missing_or_push_dependency_state(state)
- if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement)
- state.activated.detach_vertex_named(state.name)
- push_state_for_requirements(state.requirements.dup, false, state.activated)
- else
- states.push(state).tap { activated.tag(state) }
- end
- end
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/resolver.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/resolver.rb
deleted file mode 100644
index 86229c3fa1..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/resolver.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'dependency_graph'
-
-module Gem::Molinillo
- # This class encapsulates a dependency resolver.
- # The resolver is responsible for determining which set of dependencies to
- # activate, with feedback from the {#specification_provider}
- #
- #
- class Resolver
- require_relative 'resolution'
-
- # @return [SpecificationProvider] the specification provider used
- # in the resolution process
- attr_reader :specification_provider
-
- # @return [UI] the UI module used to communicate back to the user
- # during the resolution process
- attr_reader :resolver_ui
-
- # Initializes a new resolver.
- # @param [SpecificationProvider] specification_provider
- # see {#specification_provider}
- # @param [UI] resolver_ui
- # see {#resolver_ui}
- def initialize(specification_provider, resolver_ui)
- @specification_provider = specification_provider
- @resolver_ui = resolver_ui
- end
-
- # Resolves the requested dependencies into a {DependencyGraph},
- # locking to the base dependency graph (if specified)
- # @param [Array] requested an array of 'requested' dependencies that the
- # {#specification_provider} can understand
- # @param [DependencyGraph,nil] base the base dependency graph to which
- # dependencies should be 'locked'
- def resolve(requested, base = DependencyGraph.new)
- Resolution.new(specification_provider,
- resolver_ui,
- requested,
- base).
- resolve
- end
- end
-end
diff --git a/lib/rubygems/vendor/molinillo/lib/molinillo/state.rb b/lib/rubygems/vendor/molinillo/lib/molinillo/state.rb
deleted file mode 100644
index c48ec6af9c..0000000000
--- a/lib/rubygems/vendor/molinillo/lib/molinillo/state.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-module Gem::Molinillo
- # A state that a {Resolution} can be in
- # @attr [String] name the name of the current requirement
- # @attr [Array<Object>] requirements currently unsatisfied requirements
- # @attr [DependencyGraph] activated the graph of activated dependencies
- # @attr [Object] requirement the current requirement
- # @attr [Object] possibilities the possibilities to satisfy the current requirement
- # @attr [Integer] depth the depth of the resolution
- # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
- # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
- ResolutionState = Struct.new(
- :name,
- :requirements,
- :activated,
- :requirement,
- :possibilities,
- :depth,
- :conflicts,
- :unused_unwind_options
- )
-
- class ResolutionState
- # Returns an empty resolution state
- # @return [ResolutionState] an empty state
- def self.empty
- new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
- end
- end
-
- # A state that encapsulates a set of {#requirements} with an {Array} of
- # possibilities
- class DependencyState < ResolutionState
- # Removes a possibility from `self`
- # @return [PossibilityState] a state with a single possibility,
- # the possibility that was removed from `self`
- def pop_possibility_state
- PossibilityState.new(
- name,
- requirements.dup,
- activated,
- requirement,
- [possibilities.pop],
- depth + 1,
- conflicts.dup,
- unused_unwind_options.dup
- ).tap do |state|
- state.activated.tag(state)
- end
- end
- end
-
- # A state that encapsulates a single possibility to fulfill the given
- # {#requirement}
- class PossibilityState < ResolutionState
- end
-end
diff --git a/lib/rubygems/vendor/net-http/.document b/lib/rubygems/vendor/net-http/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/net-http/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/net-http/lib/net/http.rb b/lib/rubygems/vendor/net-http/lib/net/http.rb
deleted file mode 100644
index 25c870a591..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http.rb
+++ /dev/null
@@ -1,2496 +0,0 @@
-# frozen_string_literal: true
-#
-# = net/http.rb
-#
-# Copyright (c) 1999-2007 Yukihiro Matsumoto
-# Copyright (c) 1999-2007 Minero Aoki
-# Copyright (c) 2001 GOTOU Yuuzou
-#
-# Written and maintained by Minero Aoki <aamine@loveruby.net>.
-# HTTPS support added by GOTOU Yuuzou <gotoyuzo@notwork.org>.
-#
-# This file is derived from "http-access.rb".
-#
-# Documented by Minero Aoki; converted to RDoc by William Webber.
-#
-# This program is free software. You can re-distribute and/or
-# modify this program under the same terms of ruby itself ---
-# Ruby Distribution License or GNU General Public License.
-#
-# See Gem::Net::HTTP for an overview and examples.
-#
-
-require_relative '../../../net-protocol/lib/net/protocol'
-require_relative '../../../uri/lib/uri'
-require_relative '../../../resolv/lib/resolv'
-autoload :OpenSSL, 'openssl'
-
-module Gem::Net #:nodoc:
-
- # :stopdoc:
- class HTTPBadResponse < StandardError; end
- class HTTPHeaderSyntaxError < StandardError; end
- # :startdoc:
-
- # \Class \Gem::Net::HTTP provides a rich library that implements the client
- # in a client-server model that uses the \HTTP request-response protocol.
- # For information about \HTTP, see:
- #
- # - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol].
- # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview].
- #
- # == About the Examples
- #
- # :include: doc/net-http/examples.rdoc
- #
- # == Strategies
- #
- # - If you will make only a few GET requests,
- # consider using {OpenURI}[https://docs.ruby-lang.org/en/master/OpenURI.html].
- # - If you will make only a few requests of all kinds,
- # consider using the various singleton convenience methods in this class.
- # Each of the following methods automatically starts and finishes
- # a {session}[rdoc-ref:Gem::Net::HTTP@Sessions] that sends a single request:
- #
- # # Return string response body.
- # Gem::Net::HTTP.get(hostname, path)
- # Gem::Net::HTTP.get(uri)
- #
- # # Write string response body to $stdout.
- # Gem::Net::HTTP.get_print(hostname, path)
- # Gem::Net::HTTP.get_print(uri)
- #
- # # Return response as Gem::Net::HTTPResponse object.
- # Gem::Net::HTTP.get_response(hostname, path)
- # Gem::Net::HTTP.get_response(uri)
- # data = '{"title": "foo", "body": "bar", "userId": 1}'
- # Gem::Net::HTTP.post(uri, data)
- # params = {title: 'foo', body: 'bar', userId: 1}
- # Gem::Net::HTTP.post_form(uri, params)
- #
- # - If performance is important, consider using sessions, which lower request overhead.
- # This {session}[rdoc-ref:Gem::Net::HTTP@Sessions] has multiple requests for
- # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]
- # and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
- #
- # Gem::Net::HTTP.start(hostname) do |http|
- # # Session started automatically before block execution.
- # http.get(path)
- # http.head(path)
- # body = 'Some text'
- # http.post(path, body) # Can also have a block.
- # http.put(path, body)
- # http.delete(path)
- # http.options(path)
- # http.trace(path)
- # http.patch(path, body) # Can also have a block.
- # http.copy(path)
- # http.lock(path, body)
- # http.mkcol(path, body)
- # http.move(path)
- # http.propfind(path, body)
- # http.proppatch(path, body)
- # http.unlock(path, body)
- # # Session finished automatically at block exit.
- # end
- #
- # The methods cited above are convenience methods that, via their few arguments,
- # allow minimal control over the requests.
- # For greater control, consider using {request objects}[rdoc-ref:Gem::Net::HTTPRequest].
- #
- # == URIs
- #
- # On the internet, a URI
- # ({Universal Resource Identifier}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier])
- # is a string that identifies a particular resource.
- # It consists of some or all of: scheme, hostname, path, query, and fragment;
- # see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax].
- #
- # A Ruby {Gem::URI::Generic}[https://docs.ruby-lang.org/en/master/Gem/URI/Generic.html] object
- # represents an internet URI.
- # It provides, among others, methods
- # +scheme+, +hostname+, +path+, +query+, and +fragment+.
- #
- # === Schemes
- #
- # An internet \Gem::URI has
- # a {scheme}[https://en.wikipedia.org/wiki/List_of_URI_schemes].
- #
- # The two schemes supported in \Gem::Net::HTTP are <tt>'https'</tt> and <tt>'http'</tt>:
- #
- # uri.scheme # => "https"
- # Gem::URI('http://example.com').scheme # => "http"
- #
- # === Hostnames
- #
- # A hostname identifies a server (host) to which requests may be sent:
- #
- # hostname = uri.hostname # => "jsonplaceholder.typicode.com"
- # Gem::Net::HTTP.start(hostname) do |http|
- # # Some HTTP stuff.
- # end
- #
- # === Paths
- #
- # A host-specific path identifies a resource on the host:
- #
- # _uri = uri.dup
- # _uri.path = '/todos/1'
- # hostname = _uri.hostname
- # path = _uri.path
- # Gem::Net::HTTP.get(hostname, path)
- #
- # === Queries
- #
- # A host-specific query adds name/value pairs to the URI:
- #
- # _uri = uri.dup
- # params = {userId: 1, completed: false}
- # _uri.query = Gem::URI.encode_www_form(params)
- # _uri # => #<Gem::URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false>
- # Gem::Net::HTTP.get(_uri)
- #
- # === Fragments
- #
- # A {URI fragment}[https://en.wikipedia.org/wiki/URI_fragment] has no effect
- # in \Gem::Net::HTTP;
- # the same data is returned, regardless of whether a fragment is included.
- #
- # == Request Headers
- #
- # Request headers may be used to pass additional information to the host,
- # similar to arguments passed in a method call;
- # each header is a name/value pair.
- #
- # Each of the \Gem::Net::HTTP methods that sends a request to the host
- # has optional argument +headers+,
- # where the headers are expressed as a hash of field-name/value pairs:
- #
- # headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
- # Gem::Net::HTTP.get(uri, headers)
- #
- # See lists of both standard request fields and common request fields at
- # {Request Fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
- # A host may also accept other custom fields.
- #
- # == \HTTP Sessions
- #
- # A _session_ is a connection between a server (host) and a client that:
- #
- # - Is begun by instance method Gem::Net::HTTP#start.
- # - May contain any number of requests.
- # - Is ended by instance method Gem::Net::HTTP#finish.
- #
- # See example sessions at {Strategies}[rdoc-ref:Gem::Net::HTTP@Strategies].
- #
- # === Session Using \Gem::Net::HTTP.start
- #
- # If you have many requests to make to a single host (and port),
- # consider using singleton method Gem::Net::HTTP.start with a block;
- # the method handles the session automatically by:
- #
- # - Calling #start before block execution.
- # - Executing the block.
- # - Calling #finish after block execution.
- #
- # In the block, you can use these instance methods,
- # each of which that sends a single request:
- #
- # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
- #
- # - #get, #request_get: GET.
- # - #head, #request_head: HEAD.
- # - #post, #request_post: POST.
- # - #delete: DELETE.
- # - #options: OPTIONS.
- # - #trace: TRACE.
- # - #patch: PATCH.
- #
- # - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
- #
- # - #copy: COPY.
- # - #lock: LOCK.
- # - #mkcol: MKCOL.
- # - #move: MOVE.
- # - #propfind: PROPFIND.
- # - #proppatch: PROPPATCH.
- # - #unlock: UNLOCK.
- #
- # === Session Using \Gem::Net::HTTP.start and \Gem::Net::HTTP.finish
- #
- # You can manage a session manually using methods #start and #finish:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.start
- # http.get('/todos/1')
- # http.get('/todos/2')
- # http.delete('/posts/1')
- # http.finish # Needed to free resources.
- #
- # === Single-Request Session
- #
- # Certain convenience methods automatically handle a session by:
- #
- # - Creating an \HTTP object
- # - Starting a session.
- # - Sending a single request.
- # - Finishing the session.
- # - Destroying the object.
- #
- # Such methods that send GET requests:
- #
- # - ::get: Returns the string response body.
- # - ::get_print: Writes the string response body to $stdout.
- # - ::get_response: Returns a Gem::Net::HTTPResponse object.
- #
- # Such methods that send POST requests:
- #
- # - ::post: Posts data to the host.
- # - ::post_form: Posts form data to the host.
- #
- # == \HTTP Requests and Responses
- #
- # Many of the methods above are convenience methods,
- # each of which sends a request and returns a string
- # without directly using \Gem::Net::HTTPRequest and \Gem::Net::HTTPResponse objects.
- #
- # You can, however, directly create a request object, send the request,
- # and retrieve the response object; see:
- #
- # - Gem::Net::HTTPRequest.
- # - Gem::Net::HTTPResponse.
- #
- # == Following Redirection
- #
- # Each returned response is an instance of a subclass of Gem::Net::HTTPResponse.
- # See the {response class hierarchy}[rdoc-ref:Gem::Net::HTTPResponse@Response+Subclasses].
- #
- # In particular, class Gem::Net::HTTPRedirection is the parent
- # of all redirection classes.
- # This allows you to craft a case statement to handle redirections properly:
- #
- # def fetch(uri, limit = 10)
- # # You should choose a better exception.
- # raise ArgumentError, 'Too many HTTP redirects' if limit == 0
- #
- # res = Gem::Net::HTTP.get_response(Gem::URI(uri))
- # case res
- # when Gem::Net::HTTPSuccess # Any success class.
- # res
- # when Gem::Net::HTTPRedirection # Any redirection class.
- # location = res['Location']
- # warn "Redirected to #{location}"
- # fetch(location, limit - 1)
- # else # Any other class.
- # res.value
- # end
- # end
- #
- # fetch(uri)
- #
- # == Basic Authentication
- #
- # Basic authentication is performed according to
- # {RFC2617}[http://www.ietf.org/rfc/rfc2617.txt]:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.basic_auth('user', 'pass')
- # res = Gem::Net::HTTP.start(hostname) do |http|
- # http.request(req)
- # end
- #
- # == Streaming Response Bodies
- #
- # By default \Gem::Net::HTTP reads an entire response into memory. If you are
- # handling large files or wish to implement a progress bar you can instead
- # stream the body directly to an IO.
- #
- # Gem::Net::HTTP.start(hostname) do |http|
- # req = Gem::Net::HTTP::Get.new(uri)
- # http.request(req) do |res|
- # open('t.tmp', 'w') do |f|
- # res.read_body do |chunk|
- # f.write chunk
- # end
- # end
- # end
- # end
- #
- # == HTTPS
- #
- # HTTPS is enabled for an \HTTP connection by Gem::Net::HTTP#use_ssl=:
- #
- # Gem::Net::HTTP.start(hostname, :use_ssl => true) do |http|
- # req = Gem::Net::HTTP::Get.new(uri)
- # res = http.request(req)
- # end
- #
- # Or if you simply want to make a GET request, you may pass in a URI
- # object that has an \HTTPS URL. \Gem::Net::HTTP automatically turns on TLS
- # verification if the URI object has a 'https' :URI scheme:
- #
- # uri # => #<Gem::URI::HTTPS https://jsonplaceholder.typicode.com/>
- # Gem::Net::HTTP.get(uri)
- #
- # == Proxy Server
- #
- # An \HTTP object can have
- # a {proxy server}[https://en.wikipedia.org/wiki/Proxy_server].
- #
- # You can create an \HTTP object with a proxy server
- # using method Gem::Net::HTTP.new or method Gem::Net::HTTP.start.
- #
- # The proxy may be defined either by argument +p_addr+
- # or by environment variable <tt>'http_proxy'</tt>.
- #
- # === Proxy Using Argument +p_addr+ as a \String
- #
- # When argument +p_addr+ is a string hostname,
- # the returned +http+ has the given host as its proxy:
- #
- # http = Gem::Net::HTTP.new(hostname, nil, 'proxy.example')
- # http.proxy? # => true
- # http.proxy_from_env? # => false
- # http.proxy_address # => "proxy.example"
- # # These use default values.
- # http.proxy_port # => 80
- # http.proxy_user # => nil
- # http.proxy_pass # => nil
- #
- # The port, username, and password for the proxy may also be given:
- #
- # http = Gem::Net::HTTP.new(hostname, nil, 'proxy.example', 8000, 'pname', 'ppass')
- # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
- # http.proxy? # => true
- # http.proxy_from_env? # => false
- # http.proxy_address # => "proxy.example"
- # http.proxy_port # => 8000
- # http.proxy_user # => "pname"
- # http.proxy_pass # => "ppass"
- #
- # === Proxy Using '<tt>ENV['http_proxy']</tt>'
- #
- # When environment variable <tt>'http_proxy'</tt>
- # is set to a \Gem::URI string,
- # the returned +http+ will have the server at that URI as its proxy;
- # note that the \Gem::URI string must have a protocol
- # such as <tt>'http'</tt> or <tt>'https'</tt>:
- #
- # ENV['http_proxy'] = 'http://example.com'
- # http = Gem::Net::HTTP.new(hostname)
- # http.proxy? # => true
- # http.proxy_from_env? # => true
- # http.proxy_address # => "example.com"
- # # These use default values.
- # http.proxy_port # => 80
- # http.proxy_user # => nil
- # http.proxy_pass # => nil
- #
- # The \Gem::URI string may include proxy username, password, and port number:
- #
- # ENV['http_proxy'] = 'http://pname:ppass@example.com:8000'
- # http = Gem::Net::HTTP.new(hostname)
- # http.proxy? # => true
- # http.proxy_from_env? # => true
- # http.proxy_address # => "example.com"
- # http.proxy_port # => 8000
- # http.proxy_user # => "pname"
- # http.proxy_pass # => "ppass"
- #
- # === Filtering Proxies
- #
- # With method Gem::Net::HTTP.new (but not Gem::Net::HTTP.start),
- # you can use argument +p_no_proxy+ to filter proxies:
- #
- # - Reject a certain address:
- #
- # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
- # http.proxy_address # => nil
- #
- # - Reject certain domains or subdomains:
- #
- # http = Gem::Net::HTTP.new('example.com', nil, 'my.proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
- # http.proxy_address # => nil
- #
- # - Reject certain addresses and port combinations:
- #
- # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:1234')
- # http.proxy_address # => "proxy.example"
- #
- # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:8000')
- # http.proxy_address # => nil
- #
- # - Reject a list of the types above delimited using a comma:
- #
- # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
- # http.proxy_address # => nil
- #
- # http = Gem::Net::HTTP.new('example.com', nil, 'my.proxy', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
- # http.proxy_address # => nil
- #
- # == Compression and Decompression
- #
- # \Gem::Net::HTTP does not compress the body of a request before sending.
- #
- # By default, \Gem::Net::HTTP adds header <tt>'Accept-Encoding'</tt>
- # to a new {request object}[rdoc-ref:Gem::Net::HTTPRequest]:
- #
- # Gem::Net::HTTP::Get.new(uri)['Accept-Encoding']
- # # => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
- #
- # This requests the server to zip-encode the response body if there is one;
- # the server is not required to do so.
- #
- # \Gem::Net::HTTP does not automatically decompress a response body
- # if the response has header <tt>'Content-Range'</tt>.
- #
- # Otherwise decompression (or not) depends on the value of header
- # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]:
- #
- # - <tt>'deflate'</tt>, <tt>'gzip'</tt>, or <tt>'x-gzip'</tt>:
- # decompresses the body and deletes the header.
- # - <tt>'none'</tt> or <tt>'identity'</tt>:
- # does not decompress the body, but deletes the header.
- # - Any other value:
- # leaves the body and header unchanged.
- #
- # == What's Here
- #
- # This is a categorized summary of methods and attributes.
- #
- # === \Gem::Net::HTTP Objects
- #
- # - {::new}[rdoc-ref:Gem::Net::HTTP.new]:
- # Creates a new instance.
- # - {#inspect}[rdoc-ref:Gem::Net::HTTP#inspect]:
- # Returns a string representation of +self+.
- #
- # === Sessions
- #
- # - {::start}[rdoc-ref:Gem::Net::HTTP.start]:
- # Begins a new session in a new \Gem::Net::HTTP object.
- # - {#started?}[rdoc-ref:Gem::Net::HTTP#started?]
- # (aliased as {#active?}[rdoc-ref:Gem::Net::HTTP#active?]):
- # Returns whether in a session.
- # - {#finish}[rdoc-ref:Gem::Net::HTTP#finish]:
- # Ends an active session.
- # - {#start}[rdoc-ref:Gem::Net::HTTP#start]:
- # Begins a new session in an existing \Gem::Net::HTTP object (+self+).
- #
- # === Connections
- #
- # - {:continue_timeout}[rdoc-ref:Gem::Net::HTTP#continue_timeout]:
- # Returns the continue timeout.
- # - {#continue_timeout=}[rdoc-ref:Gem::Net::HTTP#continue_timeout=]:
- # Sets the continue timeout seconds.
- # - {:keep_alive_timeout}[rdoc-ref:Gem::Net::HTTP#keep_alive_timeout]:
- # Returns the keep-alive timeout.
- # - {:keep_alive_timeout=}[rdoc-ref:Gem::Net::HTTP#keep_alive_timeout=]:
- # Sets the keep-alive timeout.
- # - {:max_retries}[rdoc-ref:Gem::Net::HTTP#max_retries]:
- # Returns the maximum retries.
- # - {#max_retries=}[rdoc-ref:Gem::Net::HTTP#max_retries=]:
- # Sets the maximum retries.
- # - {:open_timeout}[rdoc-ref:Gem::Net::HTTP#open_timeout]:
- # Returns the open timeout.
- # - {:open_timeout=}[rdoc-ref:Gem::Net::HTTP#open_timeout=]:
- # Sets the open timeout.
- # - {:read_timeout}[rdoc-ref:Gem::Net::HTTP#read_timeout]:
- # Returns the open timeout.
- # - {:read_timeout=}[rdoc-ref:Gem::Net::HTTP#read_timeout=]:
- # Sets the read timeout.
- # - {:ssl_timeout}[rdoc-ref:Gem::Net::HTTP#ssl_timeout]:
- # Returns the ssl timeout.
- # - {:ssl_timeout=}[rdoc-ref:Gem::Net::HTTP#ssl_timeout=]:
- # Sets the ssl timeout.
- # - {:write_timeout}[rdoc-ref:Gem::Net::HTTP#write_timeout]:
- # Returns the write timeout.
- # - {write_timeout=}[rdoc-ref:Gem::Net::HTTP#write_timeout=]:
- # Sets the write timeout.
- #
- # === Requests
- #
- # - {::get}[rdoc-ref:Gem::Net::HTTP.get]:
- # Sends a GET request and returns the string response body.
- # - {::get_print}[rdoc-ref:Gem::Net::HTTP.get_print]:
- # Sends a GET request and write the string response body to $stdout.
- # - {::get_response}[rdoc-ref:Gem::Net::HTTP.get_response]:
- # Sends a GET request and returns a response object.
- # - {::post_form}[rdoc-ref:Gem::Net::HTTP.post_form]:
- # Sends a POST request with form data and returns a response object.
- # - {::post}[rdoc-ref:Gem::Net::HTTP.post]:
- # Sends a POST request with data and returns a response object.
- # - {#copy}[rdoc-ref:Gem::Net::HTTP#copy]:
- # Sends a COPY request and returns a response object.
- # - {#delete}[rdoc-ref:Gem::Net::HTTP#delete]:
- # Sends a DELETE request and returns a response object.
- # - {#get}[rdoc-ref:Gem::Net::HTTP#get]:
- # Sends a GET request and returns a response object.
- # - {#head}[rdoc-ref:Gem::Net::HTTP#head]:
- # Sends a HEAD request and returns a response object.
- # - {#lock}[rdoc-ref:Gem::Net::HTTP#lock]:
- # Sends a LOCK request and returns a response object.
- # - {#mkcol}[rdoc-ref:Gem::Net::HTTP#mkcol]:
- # Sends a MKCOL request and returns a response object.
- # - {#move}[rdoc-ref:Gem::Net::HTTP#move]:
- # Sends a MOVE request and returns a response object.
- # - {#options}[rdoc-ref:Gem::Net::HTTP#options]:
- # Sends a OPTIONS request and returns a response object.
- # - {#patch}[rdoc-ref:Gem::Net::HTTP#patch]:
- # Sends a PATCH request and returns a response object.
- # - {#post}[rdoc-ref:Gem::Net::HTTP#post]:
- # Sends a POST request and returns a response object.
- # - {#propfind}[rdoc-ref:Gem::Net::HTTP#propfind]:
- # Sends a PROPFIND request and returns a response object.
- # - {#proppatch}[rdoc-ref:Gem::Net::HTTP#proppatch]:
- # Sends a PROPPATCH request and returns a response object.
- # - {#put}[rdoc-ref:Gem::Net::HTTP#put]:
- # Sends a PUT request and returns a response object.
- # - {#request}[rdoc-ref:Gem::Net::HTTP#request]:
- # Sends a request and returns a response object.
- # - {#request_get}[rdoc-ref:Gem::Net::HTTP#request_get]
- # (aliased as {#get2}[rdoc-ref:Gem::Net::HTTP#get2]):
- # Sends a GET request and forms a response object;
- # if a block given, calls the block with the object,
- # otherwise returns the object.
- # - {#request_head}[rdoc-ref:Gem::Net::HTTP#request_head]
- # (aliased as {#head2}[rdoc-ref:Gem::Net::HTTP#head2]):
- # Sends a HEAD request and forms a response object;
- # if a block given, calls the block with the object,
- # otherwise returns the object.
- # - {#request_post}[rdoc-ref:Gem::Net::HTTP#request_post]
- # (aliased as {#post2}[rdoc-ref:Gem::Net::HTTP#post2]):
- # Sends a POST request and forms a response object;
- # if a block given, calls the block with the object,
- # otherwise returns the object.
- # - {#send_request}[rdoc-ref:Gem::Net::HTTP#send_request]:
- # Sends a request and returns a response object.
- # - {#trace}[rdoc-ref:Gem::Net::HTTP#trace]:
- # Sends a TRACE request and returns a response object.
- # - {#unlock}[rdoc-ref:Gem::Net::HTTP#unlock]:
- # Sends an UNLOCK request and returns a response object.
- #
- # === Responses
- #
- # - {:close_on_empty_response}[rdoc-ref:Gem::Net::HTTP#close_on_empty_response]:
- # Returns whether to close connection on empty response.
- # - {:close_on_empty_response=}[rdoc-ref:Gem::Net::HTTP#close_on_empty_response=]:
- # Sets whether to close connection on empty response.
- # - {:ignore_eof}[rdoc-ref:Gem::Net::HTTP#ignore_eof]:
- # Returns whether to ignore end-of-file when reading a response body
- # with <tt>Content-Length</tt> headers.
- # - {:ignore_eof=}[rdoc-ref:Gem::Net::HTTP#ignore_eof=]:
- # Sets whether to ignore end-of-file when reading a response body
- # with <tt>Content-Length</tt> headers.
- # - {:response_body_encoding}[rdoc-ref:Gem::Net::HTTP#response_body_encoding]:
- # Returns the encoding to use for the response body.
- # - {#response_body_encoding=}[rdoc-ref:Gem::Net::HTTP#response_body_encoding=]:
- # Sets the response body encoding.
- #
- # === Proxies
- #
- # - {:proxy_address}[rdoc-ref:Gem::Net::HTTP#proxy_address]:
- # Returns the proxy address.
- # - {:proxy_address=}[rdoc-ref:Gem::Net::HTTP#proxy_address=]:
- # Sets the proxy address.
- # - {::proxy_class?}[rdoc-ref:Gem::Net::HTTP.proxy_class?]:
- # Returns whether +self+ is a proxy class.
- # - {#proxy?}[rdoc-ref:Gem::Net::HTTP#proxy?]:
- # Returns whether +self+ has a proxy.
- # - {#proxy_address}[rdoc-ref:Gem::Net::HTTP#proxy_address]
- # (aliased as {#proxyaddr}[rdoc-ref:Gem::Net::HTTP#proxyaddr]):
- # Returns the proxy address.
- # - {#proxy_from_env?}[rdoc-ref:Gem::Net::HTTP#proxy_from_env?]:
- # Returns whether the proxy is taken from an environment variable.
- # - {:proxy_from_env=}[rdoc-ref:Gem::Net::HTTP#proxy_from_env=]:
- # Sets whether the proxy is to be taken from an environment variable.
- # - {:proxy_pass}[rdoc-ref:Gem::Net::HTTP#proxy_pass]:
- # Returns the proxy password.
- # - {:proxy_pass=}[rdoc-ref:Gem::Net::HTTP#proxy_pass=]:
- # Sets the proxy password.
- # - {:proxy_port}[rdoc-ref:Gem::Net::HTTP#proxy_port]:
- # Returns the proxy port.
- # - {:proxy_port=}[rdoc-ref:Gem::Net::HTTP#proxy_port=]:
- # Sets the proxy port.
- # - {#proxy_user}[rdoc-ref:Gem::Net::HTTP#proxy_user]:
- # Returns the proxy user name.
- # - {:proxy_user=}[rdoc-ref:Gem::Net::HTTP#proxy_user=]:
- # Sets the proxy user.
- #
- # === Security
- #
- # - {:ca_file}[rdoc-ref:Gem::Net::HTTP#ca_file]:
- # Returns the path to a CA certification file.
- # - {:ca_file=}[rdoc-ref:Gem::Net::HTTP#ca_file=]:
- # Sets the path to a CA certification file.
- # - {:ca_path}[rdoc-ref:Gem::Net::HTTP#ca_path]:
- # Returns the path of to CA directory containing certification files.
- # - {:ca_path=}[rdoc-ref:Gem::Net::HTTP#ca_path=]:
- # Sets the path of to CA directory containing certification files.
- # - {:cert}[rdoc-ref:Gem::Net::HTTP#cert]:
- # Returns the OpenSSL::X509::Certificate object to be used for client certification.
- # - {:cert=}[rdoc-ref:Gem::Net::HTTP#cert=]:
- # Sets the OpenSSL::X509::Certificate object to be used for client certification.
- # - {:cert_store}[rdoc-ref:Gem::Net::HTTP#cert_store]:
- # Returns the X509::Store to be used for verifying peer certificate.
- # - {:cert_store=}[rdoc-ref:Gem::Net::HTTP#cert_store=]:
- # Sets the X509::Store to be used for verifying peer certificate.
- # - {:ciphers}[rdoc-ref:Gem::Net::HTTP#ciphers]:
- # Returns the available SSL ciphers.
- # - {:ciphers=}[rdoc-ref:Gem::Net::HTTP#ciphers=]:
- # Sets the available SSL ciphers.
- # - {:extra_chain_cert}[rdoc-ref:Gem::Net::HTTP#extra_chain_cert]:
- # Returns the extra X509 certificates to be added to the certificate chain.
- # - {:extra_chain_cert=}[rdoc-ref:Gem::Net::HTTP#extra_chain_cert=]:
- # Sets the extra X509 certificates to be added to the certificate chain.
- # - {:key}[rdoc-ref:Gem::Net::HTTP#key]:
- # Returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
- # - {:key=}[rdoc-ref:Gem::Net::HTTP#key=]:
- # Sets the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
- # - {:max_version}[rdoc-ref:Gem::Net::HTTP#max_version]:
- # Returns the maximum SSL version.
- # - {:max_version=}[rdoc-ref:Gem::Net::HTTP#max_version=]:
- # Sets the maximum SSL version.
- # - {:min_version}[rdoc-ref:Gem::Net::HTTP#min_version]:
- # Returns the minimum SSL version.
- # - {:min_version=}[rdoc-ref:Gem::Net::HTTP#min_version=]:
- # Sets the minimum SSL version.
- # - {#peer_cert}[rdoc-ref:Gem::Net::HTTP#peer_cert]:
- # Returns the X509 certificate chain for the session's socket peer.
- # - {:ssl_version}[rdoc-ref:Gem::Net::HTTP#ssl_version]:
- # Returns the SSL version.
- # - {:ssl_version=}[rdoc-ref:Gem::Net::HTTP#ssl_version=]:
- # Sets the SSL version.
- # - {#use_ssl=}[rdoc-ref:Gem::Net::HTTP#use_ssl=]:
- # Sets whether a new session is to use Transport Layer Security.
- # - {#use_ssl?}[rdoc-ref:Gem::Net::HTTP#use_ssl?]:
- # Returns whether +self+ uses SSL.
- # - {:verify_callback}[rdoc-ref:Gem::Net::HTTP#verify_callback]:
- # Returns the callback for the server certification verification.
- # - {:verify_callback=}[rdoc-ref:Gem::Net::HTTP#verify_callback=]:
- # Sets the callback for the server certification verification.
- # - {:verify_depth}[rdoc-ref:Gem::Net::HTTP#verify_depth]:
- # Returns the maximum depth for the certificate chain verification.
- # - {:verify_depth=}[rdoc-ref:Gem::Net::HTTP#verify_depth=]:
- # Sets the maximum depth for the certificate chain verification.
- # - {:verify_hostname}[rdoc-ref:Gem::Net::HTTP#verify_hostname]:
- # Returns the flags for server the certification verification at the beginning of the SSL/TLS session.
- # - {:verify_hostname=}[rdoc-ref:Gem::Net::HTTP#verify_hostname=]:
- # Sets he flags for server the certification verification at the beginning of the SSL/TLS session.
- # - {:verify_mode}[rdoc-ref:Gem::Net::HTTP#verify_mode]:
- # Returns the flags for server the certification verification at the beginning of the SSL/TLS session.
- # - {:verify_mode=}[rdoc-ref:Gem::Net::HTTP#verify_mode=]:
- # Sets the flags for server the certification verification at the beginning of the SSL/TLS session.
- #
- # === Addresses and Ports
- #
- # - {:address}[rdoc-ref:Gem::Net::HTTP#address]:
- # Returns the string host name or host IP.
- # - {::default_port}[rdoc-ref:Gem::Net::HTTP.default_port]:
- # Returns integer 80, the default port to use for HTTP requests.
- # - {::http_default_port}[rdoc-ref:Gem::Net::HTTP.http_default_port]:
- # Returns integer 80, the default port to use for HTTP requests.
- # - {::https_default_port}[rdoc-ref:Gem::Net::HTTP.https_default_port]:
- # Returns integer 443, the default port to use for HTTPS requests.
- # - {#ipaddr}[rdoc-ref:Gem::Net::HTTP#ipaddr]:
- # Returns the IP address for the connection.
- # - {#ipaddr=}[rdoc-ref:Gem::Net::HTTP#ipaddr=]:
- # Sets the IP address for the connection.
- # - {:local_host}[rdoc-ref:Gem::Net::HTTP#local_host]:
- # Returns the string local host used to establish the connection.
- # - {:local_host=}[rdoc-ref:Gem::Net::HTTP#local_host=]:
- # Sets the string local host used to establish the connection.
- # - {:local_port}[rdoc-ref:Gem::Net::HTTP#local_port]:
- # Returns the integer local port used to establish the connection.
- # - {:local_port=}[rdoc-ref:Gem::Net::HTTP#local_port=]:
- # Sets the integer local port used to establish the connection.
- # - {:port}[rdoc-ref:Gem::Net::HTTP#port]:
- # Returns the integer port number.
- #
- # === \HTTP Version
- #
- # - {::version_1_2?}[rdoc-ref:Gem::Net::HTTP.version_1_2?]
- # (aliased as {::is_version_1_2?}[rdoc-ref:Gem::Net::HTTP.is_version_1_2?]
- # and {::version_1_2}[rdoc-ref:Gem::Net::HTTP.version_1_2]):
- # Returns true; retained for compatibility.
- #
- # === Debugging
- #
- # - {#set_debug_output}[rdoc-ref:Gem::Net::HTTP#set_debug_output]:
- # Sets the output stream for debugging.
- #
- class HTTP < Protocol
-
- # :stopdoc:
- VERSION = "0.4.0"
- HTTPVersion = '1.1'
- begin
- require 'zlib'
- HAVE_ZLIB=true
- rescue LoadError
- HAVE_ZLIB=false
- end
- # :startdoc:
-
- # Returns +true+; retained for compatibility.
- def HTTP.version_1_2
- true
- end
-
- # Returns +true+; retained for compatibility.
- def HTTP.version_1_2?
- true
- end
-
- # Returns +false+; retained for compatibility.
- def HTTP.version_1_1? #:nodoc:
- false
- end
-
- class << HTTP
- alias is_version_1_1? version_1_1? #:nodoc:
- alias is_version_1_2? version_1_2? #:nodoc:
- end
-
- # :call-seq:
- # Gem::Net::HTTP.get_print(hostname, path, port = 80) -> nil
- # Gem::Net::HTTP:get_print(uri, headers = {}, port = uri.port) -> nil
- #
- # Like Gem::Net::HTTP.get, but writes the returned body to $stdout;
- # returns +nil+.
- def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
- get_response(uri_or_host, path_or_headers, port) {|res|
- res.read_body do |chunk|
- $stdout.print chunk
- end
- }
- nil
- end
-
- # :call-seq:
- # Gem::Net::HTTP.get(hostname, path, port = 80) -> body
- # Gem::Net::HTTP:get(uri, headers = {}, port = uri.port) -> body
- #
- # Sends a GET request and returns the \HTTP response body as a string.
- #
- # With string arguments +hostname+ and +path+:
- #
- # hostname = 'jsonplaceholder.typicode.com'
- # path = '/todos/1'
- # puts Gem::Net::HTTP.get(hostname, path)
- #
- # Output:
- #
- # {
- # "userId": 1,
- # "id": 1,
- # "title": "delectus aut autem",
- # "completed": false
- # }
- #
- # With URI object +uri+ and optional hash argument +headers+:
- #
- # uri = Gem::URI('https://jsonplaceholder.typicode.com/todos/1')
- # headers = {'Content-type' => 'application/json; charset=UTF-8'}
- # Gem::Net::HTTP.get(uri, headers)
- #
- # Related:
- #
- # - Gem::Net::HTTP::Get: request class for \HTTP method +GET+.
- # - Gem::Net::HTTP#get: convenience method for \HTTP method +GET+.
- #
- def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
- get_response(uri_or_host, path_or_headers, port).body
- end
-
- # :call-seq:
- # Gem::Net::HTTP.get_response(hostname, path, port = 80) -> http_response
- # Gem::Net::HTTP:get_response(uri, headers = {}, port = uri.port) -> http_response
- #
- # Like Gem::Net::HTTP.get, but returns a Gem::Net::HTTPResponse object
- # instead of the body string.
- def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
- if path_or_headers && !path_or_headers.is_a?(Hash)
- host = uri_or_host
- path = path_or_headers
- new(host, port || HTTP.default_port).start {|http|
- return http.request_get(path, &block)
- }
- else
- uri = uri_or_host
- headers = path_or_headers
- start(uri.hostname, uri.port,
- :use_ssl => uri.scheme == 'https') {|http|
- return http.request_get(uri, headers, &block)
- }
- end
- end
-
- # Posts data to a host; returns a Gem::Net::HTTPResponse object.
- #
- # Argument +url+ must be a URL;
- # argument +data+ must be a string:
- #
- # _uri = uri.dup
- # _uri.path = '/posts'
- # data = '{"title": "foo", "body": "bar", "userId": 1}'
- # headers = {'content-type': 'application/json'}
- # res = Gem::Net::HTTP.post(_uri, data, headers) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- # puts res.body
- #
- # Output:
- #
- # {
- # "title": "foo",
- # "body": "bar",
- # "userId": 1,
- # "id": 101
- # }
- #
- # Related:
- #
- # - Gem::Net::HTTP::Post: request class for \HTTP method +POST+.
- # - Gem::Net::HTTP#post: convenience method for \HTTP method +POST+.
- #
- def HTTP.post(url, data, header = nil)
- start(url.hostname, url.port,
- :use_ssl => url.scheme == 'https' ) {|http|
- http.post(url, data, header)
- }
- end
-
- # Posts data to a host; returns a Gem::Net::HTTPResponse object.
- #
- # Argument +url+ must be a URI;
- # argument +data+ must be a hash:
- #
- # _uri = uri.dup
- # _uri.path = '/posts'
- # data = {title: 'foo', body: 'bar', userId: 1}
- # res = Gem::Net::HTTP.post_form(_uri, data) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- # puts res.body
- #
- # Output:
- #
- # {
- # "title": "foo",
- # "body": "bar",
- # "userId": "1",
- # "id": 101
- # }
- #
- def HTTP.post_form(url, params)
- req = Post.new(url)
- req.form_data = params
- req.basic_auth url.user, url.password if url.user
- start(url.hostname, url.port,
- :use_ssl => url.scheme == 'https' ) {|http|
- http.request(req)
- }
- end
-
- #
- # \HTTP session management
- #
-
- # Returns integer +80+, the default port to use for \HTTP requests:
- #
- # Gem::Net::HTTP.default_port # => 80
- #
- def HTTP.default_port
- http_default_port()
- end
-
- # Returns integer +80+, the default port to use for \HTTP requests:
- #
- # Gem::Net::HTTP.http_default_port # => 80
- #
- def HTTP.http_default_port
- 80
- end
-
- # Returns integer +443+, the default port to use for HTTPS requests:
- #
- # Gem::Net::HTTP.https_default_port # => 443
- #
- def HTTP.https_default_port
- 443
- end
-
- def HTTP.socket_type #:nodoc: obsolete
- BufferedIO
- end
-
- # :call-seq:
- # HTTP.start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) -> http
- # HTTP.start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) {|http| ... } -> object
- #
- # Creates a new \Gem::Net::HTTP object, +http+, via \Gem::Net::HTTP.new:
- #
- # - For arguments +address+ and +port+, see Gem::Net::HTTP.new.
- # - For proxy-defining arguments +p_addr+ through +p_pass+,
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- # - For argument +opts+, see below.
- #
- # With no block given:
- #
- # - Calls <tt>http.start</tt> with no block (see #start),
- # which opens a TCP connection and \HTTP session.
- # - Returns +http+.
- # - The caller should call #finish to close the session:
- #
- # http = Gem::Net::HTTP.start(hostname)
- # http.started? # => true
- # http.finish
- # http.started? # => false
- #
- # With a block given:
- #
- # - Calls <tt>http.start</tt> with the block (see #start), which:
- #
- # - Opens a TCP connection and \HTTP session.
- # - Calls the block,
- # which may make any number of requests to the host.
- # - Closes the \HTTP session and TCP connection on block exit.
- # - Returns the block's value +object+.
- #
- # - Returns +object+.
- #
- # Example:
- #
- # hostname = 'jsonplaceholder.typicode.com'
- # Gem::Net::HTTP.start(hostname) do |http|
- # puts http.get('/todos/1').body
- # puts http.get('/todos/2').body
- # end
- #
- # Output:
- #
- # {
- # "userId": 1,
- # "id": 1,
- # "title": "delectus aut autem",
- # "completed": false
- # }
- # {
- # "userId": 1,
- # "id": 2,
- # "title": "quis ut nam facilis et officia qui",
- # "completed": false
- # }
- #
- # If the last argument given is a hash, it is the +opts+ hash,
- # where each key is a method or accessor to be called,
- # and its value is the value to be set.
- #
- # The keys may include:
- #
- # - #ca_file
- # - #ca_path
- # - #cert
- # - #cert_store
- # - #ciphers
- # - #close_on_empty_response
- # - +ipaddr+ (calls #ipaddr=)
- # - #keep_alive_timeout
- # - #key
- # - #open_timeout
- # - #read_timeout
- # - #ssl_timeout
- # - #ssl_version
- # - +use_ssl+ (calls #use_ssl=)
- # - #verify_callback
- # - #verify_depth
- # - #verify_mode
- # - #write_timeout
- #
- # Note: If +port+ is +nil+ and <tt>opts[:use_ssl]</tt> is a truthy value,
- # the value passed to +new+ is Gem::Net::HTTP.https_default_port, not +port+.
- #
- def HTTP.start(address, *arg, &block) # :yield: +http+
- arg.pop if opt = Hash.try_convert(arg[-1])
- port, p_addr, p_port, p_user, p_pass = *arg
- p_addr = :ENV if arg.size < 2
- port = https_default_port if !port && opt && opt[:use_ssl]
- http = new(address, port, p_addr, p_port, p_user, p_pass)
- http.ipaddr = opt[:ipaddr] if opt && opt[:ipaddr]
-
- if opt
- if opt[:use_ssl]
- opt = {verify_mode: OpenSSL::SSL::VERIFY_PEER}.update(opt)
- end
- http.methods.grep(/\A(\w+)=\z/) do |meth|
- key = $1.to_sym
- opt.key?(key) or next
- http.__send__(meth, opt[key])
- end
- end
-
- http.start(&block)
- end
-
- class << HTTP
- alias newobj new # :nodoc:
- end
-
- # Returns a new \Gem::Net::HTTP object +http+
- # (but does not open a TCP connection or \HTTP session).
- #
- # With only string argument +address+ given
- # (and <tt>ENV['http_proxy']</tt> undefined or +nil+),
- # the returned +http+:
- #
- # - Has the given address.
- # - Has the default port number, Gem::Net::HTTP.default_port (80).
- # - Has no proxy.
- #
- # Example:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
- # http.address # => "jsonplaceholder.typicode.com"
- # http.port # => 80
- # http.proxy? # => false
- #
- # With integer argument +port+ also given,
- # the returned +http+ has the given port:
- #
- # http = Gem::Net::HTTP.new(hostname, 8000)
- # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:8000 open=false>
- # http.port # => 8000
- #
- # For proxy-defining arguments +p_addr+ through +p_no_proxy+,
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- #
- def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
- http = super address, port
-
- if proxy_class? then # from Gem::Net::HTTP::Proxy()
- http.proxy_from_env = @proxy_from_env
- http.proxy_address = @proxy_address
- http.proxy_port = @proxy_port
- http.proxy_user = @proxy_user
- http.proxy_pass = @proxy_pass
- elsif p_addr == :ENV then
- http.proxy_from_env = true
- else
- if p_addr && p_no_proxy && !Gem::URI::Generic.use_proxy?(address, address, port, p_no_proxy)
- p_addr = nil
- p_port = nil
- end
- http.proxy_address = p_addr
- http.proxy_port = p_port || default_port
- http.proxy_user = p_user
- http.proxy_pass = p_pass
- end
-
- http
- end
-
- # Creates a new \Gem::Net::HTTP object for the specified server address,
- # without opening the TCP connection or initializing the \HTTP session.
- # The +address+ should be a DNS hostname or IP address.
- def initialize(address, port = nil) # :nodoc:
- @address = address
- @port = (port || HTTP.default_port)
- @ipaddr = nil
- @local_host = nil
- @local_port = nil
- @curr_http_version = HTTPVersion
- @keep_alive_timeout = 2
- @last_communicated = nil
- @close_on_empty_response = false
- @socket = nil
- @started = false
- @open_timeout = 60
- @read_timeout = 60
- @write_timeout = 60
- @continue_timeout = nil
- @max_retries = 1
- @debug_output = nil
- @response_body_encoding = false
- @ignore_eof = true
-
- @proxy_from_env = false
- @proxy_uri = nil
- @proxy_address = nil
- @proxy_port = nil
- @proxy_user = nil
- @proxy_pass = nil
-
- @use_ssl = false
- @ssl_context = nil
- @ssl_session = nil
- @sspi_enabled = false
- SSL_IVNAMES.each do |ivname|
- instance_variable_set ivname, nil
- end
- end
-
- # Returns a string representation of +self+:
- #
- # Gem::Net::HTTP.new(hostname).inspect
- # # => "#<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>"
- #
- def inspect
- "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
- end
-
- # *WARNING* This method opens a serious security hole.
- # Never use this method in production code.
- #
- # Sets the output stream for debugging:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # File.open('t.tmp', 'w') do |file|
- # http.set_debug_output(file)
- # http.start
- # http.get('/nosuch/1')
- # http.finish
- # end
- # puts File.read('t.tmp')
- #
- # Output:
- #
- # opening connection to jsonplaceholder.typicode.com:80...
- # opened
- # <- "GET /nosuch/1 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: jsonplaceholder.typicode.com\r\n\r\n"
- # -> "HTTP/1.1 404 Not Found\r\n"
- # -> "Date: Mon, 12 Dec 2022 21:14:11 GMT\r\n"
- # -> "Content-Type: application/json; charset=utf-8\r\n"
- # -> "Content-Length: 2\r\n"
- # -> "Connection: keep-alive\r\n"
- # -> "X-Powered-By: Express\r\n"
- # -> "X-Ratelimit-Limit: 1000\r\n"
- # -> "X-Ratelimit-Remaining: 999\r\n"
- # -> "X-Ratelimit-Reset: 1670879660\r\n"
- # -> "Vary: Origin, Accept-Encoding\r\n"
- # -> "Access-Control-Allow-Credentials: true\r\n"
- # -> "Cache-Control: max-age=43200\r\n"
- # -> "Pragma: no-cache\r\n"
- # -> "Expires: -1\r\n"
- # -> "X-Content-Type-Options: nosniff\r\n"
- # -> "Etag: W/\"2-vyGp6PvFo4RvsFtPoIWeCReyIC8\"\r\n"
- # -> "Via: 1.1 vegur\r\n"
- # -> "CF-Cache-Status: MISS\r\n"
- # -> "Server-Timing: cf-q-config;dur=1.3000000762986e-05\r\n"
- # -> "Report-To: {\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=yOr40jo%2BwS1KHzhTlVpl54beJ5Wx2FcG4gGV0XVrh3X9OlR5q4drUn2dkt5DGO4GDcE%2BVXT7CNgJvGs%2BZleIyMu8CLieFiDIvOviOY3EhHg94m0ZNZgrEdpKD0S85S507l1vsEwEHkoTm%2Ff19SiO\"}],\"group\":\"cf-nel\",\"max_age\":604800}\r\n"
- # -> "NEL: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\n"
- # -> "Server: cloudflare\r\n"
- # -> "CF-RAY: 778977dc484ce591-DFW\r\n"
- # -> "alt-svc: h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\r\n"
- # -> "\r\n"
- # reading 2 bytes...
- # -> "{}"
- # read 2 bytes
- # Conn keep-alive
- #
- def set_debug_output(output)
- warn 'Gem::Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
- @debug_output = output
- end
-
- # Returns the string host name or host IP given as argument +address+ in ::new.
- attr_reader :address
-
- # Returns the integer port number given as argument +port+ in ::new.
- attr_reader :port
-
- # Sets or returns the string local host used to establish the connection;
- # initially +nil+.
- attr_accessor :local_host
-
- # Sets or returns the integer local port used to establish the connection;
- # initially +nil+.
- attr_accessor :local_port
-
- # Returns the encoding to use for the response body;
- # see #response_body_encoding=.
- attr_reader :response_body_encoding
-
- # Sets the encoding to be used for the response body;
- # returns the encoding.
- #
- # The given +value+ may be:
- #
- # - An Encoding object.
- # - The name of an encoding.
- # - An alias for an encoding name.
- #
- # See {Encoding}[https://docs.ruby-lang.org/en/master/Encoding.html].
- #
- # Examples:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.response_body_encoding = Encoding::US_ASCII # => #<Encoding:US-ASCII>
- # http.response_body_encoding = 'US-ASCII' # => "US-ASCII"
- # http.response_body_encoding = 'ASCII' # => "ASCII"
- #
- def response_body_encoding=(value)
- value = Encoding.find(value) if value.is_a?(String)
- @response_body_encoding = value
- end
-
- # Sets whether to determine the proxy from environment variable
- # '<tt>ENV['http_proxy']</tt>';
- # see {Proxy Using ENV['http_proxy']}[rdoc-ref:Gem::Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
- attr_writer :proxy_from_env
-
- # Sets the proxy address;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- attr_writer :proxy_address
-
- # Sets the proxy port;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- attr_writer :proxy_port
-
- # Sets the proxy user;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- attr_writer :proxy_user
-
- # Sets the proxy password;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- attr_writer :proxy_pass
-
- # Returns the IP address for the connection.
- #
- # If the session has not been started,
- # returns the value set by #ipaddr=,
- # or +nil+ if it has not been set:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.ipaddr # => nil
- # http.ipaddr = '172.67.155.76'
- # http.ipaddr # => "172.67.155.76"
- #
- # If the session has been started,
- # returns the IP address from the socket:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.start
- # http.ipaddr # => "172.67.155.76"
- # http.finish
- #
- def ipaddr
- started? ? @socket.io.peeraddr[3] : @ipaddr
- end
-
- # Sets the IP address for the connection:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.ipaddr # => nil
- # http.ipaddr = '172.67.155.76'
- # http.ipaddr # => "172.67.155.76"
- #
- # The IP address may not be set if the session has been started.
- def ipaddr=(addr)
- raise IOError, "ipaddr value changed, but session already started" if started?
- @ipaddr = addr
- end
-
- # Sets or returns the numeric (\Integer or \Float) number of seconds
- # to wait for a connection to open;
- # initially 60.
- # If the connection is not made in the given interval,
- # an exception is raised.
- attr_accessor :open_timeout
-
- # Returns the numeric (\Integer or \Float) number of seconds
- # to wait for one block to be read (via one read(2) call);
- # see #read_timeout=.
- attr_reader :read_timeout
-
- # Returns the numeric (\Integer or \Float) number of seconds
- # to wait for one block to be written (via one write(2) call);
- # see #write_timeout=.
- attr_reader :write_timeout
-
- # Sets the maximum number of times to retry an idempotent request in case of
- # \Gem::Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
- # Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError,
- # Gem::Timeout::Error.
- # The initial value is 1.
- #
- # Argument +retries+ must be a non-negative numeric value:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.max_retries = 2 # => 2
- # http.max_retries # => 2
- #
- def max_retries=(retries)
- retries = retries.to_int
- if retries < 0
- raise ArgumentError, 'max_retries should be non-negative integer number'
- end
- @max_retries = retries
- end
-
- # Returns the maximum number of times to retry an idempotent request;
- # see #max_retries=.
- attr_reader :max_retries
-
- # Sets the read timeout, in seconds, for +self+ to integer +sec+;
- # the initial value is 60.
- #
- # Argument +sec+ must be a non-negative numeric value:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.read_timeout # => 60
- # http.get('/todos/1') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- # http.read_timeout = 0
- # http.get('/todos/1') # Raises Gem::Net::ReadTimeout.
- #
- def read_timeout=(sec)
- @socket.read_timeout = sec if @socket
- @read_timeout = sec
- end
-
- # Sets the write timeout, in seconds, for +self+ to integer +sec+;
- # the initial value is 60.
- #
- # Argument +sec+ must be a non-negative numeric value:
- #
- # _uri = uri.dup
- # _uri.path = '/posts'
- # body = 'bar' * 200000
- # data = <<EOF
- # {"title": "foo", "body": "#{body}", "userId": "1"}
- # EOF
- # headers = {'content-type': 'application/json'}
- # http = Gem::Net::HTTP.new(hostname)
- # http.write_timeout # => 60
- # http.post(_uri.path, data, headers)
- # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- # http.write_timeout = 0
- # http.post(_uri.path, data, headers) # Raises Gem::Net::WriteTimeout.
- #
- def write_timeout=(sec)
- @socket.write_timeout = sec if @socket
- @write_timeout = sec
- end
-
- # Returns the continue timeout value;
- # see continue_timeout=.
- attr_reader :continue_timeout
-
- # Sets the continue timeout value,
- # which is the number of seconds to wait for an expected 100 Continue response.
- # If the \HTTP object does not receive a response in this many seconds
- # it sends the request body.
- def continue_timeout=(sec)
- @socket.continue_timeout = sec if @socket
- @continue_timeout = sec
- end
-
- # Sets or returns the numeric (\Integer or \Float) number of seconds
- # to keep the connection open after a request is sent;
- # initially 2.
- # If a new request is made during the given interval,
- # the still-open connection is used;
- # otherwise the connection will have been closed
- # and a new connection is opened.
- attr_accessor :keep_alive_timeout
-
- # Sets or returns whether to ignore end-of-file when reading a response body
- # with <tt>Content-Length</tt> headers;
- # initially +true+.
- attr_accessor :ignore_eof
-
- # Returns +true+ if the \HTTP session has been started:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.started? # => false
- # http.start
- # http.started? # => true
- # http.finish # => nil
- # http.started? # => false
- #
- # Gem::Net::HTTP.start(hostname) do |http|
- # http.started?
- # end # => true
- # http.started? # => false
- #
- def started?
- @started
- end
-
- alias active? started? #:nodoc: obsolete
-
- # Sets or returns whether to close the connection when the response is empty;
- # initially +false+.
- attr_accessor :close_on_empty_response
-
- # Returns +true+ if +self+ uses SSL, +false+ otherwise.
- # See Gem::Net::HTTP#use_ssl=.
- def use_ssl?
- @use_ssl
- end
-
- # Sets whether a new session is to use
- # {Transport Layer Security}[https://en.wikipedia.org/wiki/Transport_Layer_Security]:
- #
- # Raises IOError if attempting to change during a session.
- #
- # Raises OpenSSL::SSL::SSLError if the port is not an HTTPS port.
- def use_ssl=(flag)
- flag = flag ? true : false
- if started? and @use_ssl != flag
- raise IOError, "use_ssl value changed, but session already started"
- end
- @use_ssl = flag
- end
-
- SSL_IVNAMES = [
- :@ca_file,
- :@ca_path,
- :@cert,
- :@cert_store,
- :@ciphers,
- :@extra_chain_cert,
- :@key,
- :@ssl_timeout,
- :@ssl_version,
- :@min_version,
- :@max_version,
- :@verify_callback,
- :@verify_depth,
- :@verify_mode,
- :@verify_hostname,
- ] # :nodoc:
- SSL_ATTRIBUTES = [
- :ca_file,
- :ca_path,
- :cert,
- :cert_store,
- :ciphers,
- :extra_chain_cert,
- :key,
- :ssl_timeout,
- :ssl_version,
- :min_version,
- :max_version,
- :verify_callback,
- :verify_depth,
- :verify_mode,
- :verify_hostname,
- ] # :nodoc:
-
- # Sets or returns the path to a CA certification file in PEM format.
- attr_accessor :ca_file
-
- # Sets or returns the path of to CA directory
- # containing certification files in PEM format.
- attr_accessor :ca_path
-
- # Sets or returns the OpenSSL::X509::Certificate object
- # to be used for client certification.
- attr_accessor :cert
-
- # Sets or returns the X509::Store to be used for verifying peer certificate.
- attr_accessor :cert_store
-
- # Sets or returns the available SSL ciphers.
- # See {OpenSSL::SSL::SSLContext#ciphers=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D].
- attr_accessor :ciphers
-
- # Sets or returns the extra X509 certificates to be added to the certificate chain.
- # See {OpenSSL::SSL::SSLContext#add_certificate}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-add_certificate].
- attr_accessor :extra_chain_cert
-
- # Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
- attr_accessor :key
-
- # Sets or returns the SSL timeout seconds.
- attr_accessor :ssl_timeout
-
- # Sets or returns the SSL version.
- # See {OpenSSL::SSL::SSLContext#ssl_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D].
- attr_accessor :ssl_version
-
- # Sets or returns the minimum SSL version.
- # See {OpenSSL::SSL::SSLContext#min_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D].
- attr_accessor :min_version
-
- # Sets or returns the maximum SSL version.
- # See {OpenSSL::SSL::SSLContext#max_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D].
- attr_accessor :max_version
-
- # Sets or returns the callback for the server certification verification.
- attr_accessor :verify_callback
-
- # Sets or returns the maximum depth for the certificate chain verification.
- attr_accessor :verify_depth
-
- # Sets or returns the flags for server the certification verification
- # at the beginning of the SSL/TLS session.
- # OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER are acceptable.
- attr_accessor :verify_mode
-
- # Sets or returns whether to verify that the server certificate is valid
- # for the hostname.
- # See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_mode].
- attr_accessor :verify_hostname
-
- # Returns the X509 certificate chain (an array of strings)
- # for the session's socket peer,
- # or +nil+ if none.
- def peer_cert
- if not use_ssl? or not @socket
- return nil
- end
- @socket.io.peer_cert
- end
-
- # Starts an \HTTP session.
- #
- # Without a block, returns +self+:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
- # http.start
- # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=true>
- # http.started? # => true
- # http.finish
- #
- # With a block, calls the block with +self+,
- # finishes the session when the block exits,
- # and returns the block's value:
- #
- # http.start do |http|
- # http
- # end
- # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
- # http.started? # => false
- #
- def start # :yield: http
- raise IOError, 'HTTP session already opened' if @started
- if block_given?
- begin
- do_start
- return yield(self)
- ensure
- do_finish
- end
- end
- do_start
- self
- end
-
- def do_start
- connect
- @started = true
- end
- private :do_start
-
- def connect
- if use_ssl?
- # reference early to load OpenSSL before connecting,
- # as OpenSSL may take time to load.
- @ssl_context = OpenSSL::SSL::SSLContext.new
- end
-
- if proxy? then
- conn_addr = proxy_address
- conn_port = proxy_port
- else
- conn_addr = conn_address
- conn_port = port
- end
-
- debug "opening connection to #{conn_addr}:#{conn_port}..."
- s = Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
- begin
- TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
- rescue => e
- raise e, "Failed to open TCP connection to " +
- "#{conn_addr}:#{conn_port} (#{e.message})"
- end
- }
- s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
- debug "opened"
- if use_ssl?
- if proxy?
- plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
- write_timeout: @write_timeout,
- continue_timeout: @continue_timeout,
- debug_output: @debug_output)
- buf = +"CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n" \
- "Host: #{@address}:#{@port}\r\n"
- if proxy_user
- credential = ["#{proxy_user}:#{proxy_pass}"].pack('m0')
- buf << "Proxy-Authorization: Basic #{credential}\r\n"
- end
- buf << "\r\n"
- plain_sock.write(buf)
- HTTPResponse.read_new(plain_sock).value
- # assuming nothing left in buffers after successful CONNECT response
- end
-
- ssl_parameters = Hash.new
- iv_list = instance_variables
- SSL_IVNAMES.each_with_index do |ivname, i|
- if iv_list.include?(ivname)
- value = instance_variable_get(ivname)
- unless value.nil?
- ssl_parameters[SSL_ATTRIBUTES[i]] = value
- end
- end
- end
- @ssl_context.set_params(ssl_parameters)
- unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
- @ssl_context.session_cache_mode =
- OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
- OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
- end
- if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
- @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
- end
-
- # Still do the post_connection_check below even if connecting
- # to IP address
- verify_hostname = @ssl_context.verify_hostname
-
- # Server Name Indication (SNI) RFC 3546/6066
- case @address
- when Gem::Resolv::IPv4::Regex, Gem::Resolv::IPv6::Regex
- # don't set SNI, as IP addresses in SNI is not valid
- # per RFC 6066, section 3.
-
- # Avoid openssl warning
- @ssl_context.verify_hostname = false
- else
- ssl_host_address = @address
- end
-
- debug "starting SSL for #{conn_addr}:#{conn_port}..."
- s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
- s.sync_close = true
- s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
-
- if @ssl_session and
- Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
- s.session = @ssl_session
- end
- ssl_socket_connect(s, @open_timeout)
- if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
- s.post_connection_check(@address)
- end
- debug "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
- end
- @socket = BufferedIO.new(s, read_timeout: @read_timeout,
- write_timeout: @write_timeout,
- continue_timeout: @continue_timeout,
- debug_output: @debug_output)
- @last_communicated = nil
- on_connect
- rescue => exception
- if s
- debug "Conn close because of connect error #{exception}"
- s.close
- end
- raise
- end
- private :connect
-
- def on_connect
- end
- private :on_connect
-
- # Finishes the \HTTP session:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.start
- # http.started? # => true
- # http.finish # => nil
- # http.started? # => false
- #
- # Raises IOError if not in a session.
- def finish
- raise IOError, 'HTTP session not yet started' unless started?
- do_finish
- end
-
- def do_finish
- @started = false
- @socket.close if @socket
- @socket = nil
- end
- private :do_finish
-
- #
- # proxy
- #
-
- public
-
- # no proxy
- @is_proxy_class = false
- @proxy_from_env = false
- @proxy_addr = nil
- @proxy_port = nil
- @proxy_user = nil
- @proxy_pass = nil
-
- # Creates an \HTTP proxy class which behaves like \Gem::Net::HTTP, but
- # performs all access via the specified proxy.
- #
- # This class is obsolete. You may pass these same parameters directly to
- # \Gem::Net::HTTP.new. See Gem::Net::HTTP.new for details of the arguments.
- def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) #:nodoc:
- return self unless p_addr
-
- Class.new(self) {
- @is_proxy_class = true
-
- if p_addr == :ENV then
- @proxy_from_env = true
- @proxy_address = nil
- @proxy_port = nil
- else
- @proxy_from_env = false
- @proxy_address = p_addr
- @proxy_port = p_port || default_port
- end
-
- @proxy_user = p_user
- @proxy_pass = p_pass
- }
- end
-
- class << HTTP
- # Returns true if self is a class which was created by HTTP::Proxy.
- def proxy_class?
- defined?(@is_proxy_class) ? @is_proxy_class : false
- end
-
- # Returns the address of the proxy host, or +nil+ if none;
- # see Gem::Net::HTTP@Proxy+Server.
- attr_reader :proxy_address
-
- # Returns the port number of the proxy host, or +nil+ if none;
- # see Gem::Net::HTTP@Proxy+Server.
- attr_reader :proxy_port
-
- # Returns the user name for accessing the proxy, or +nil+ if none;
- # see Gem::Net::HTTP@Proxy+Server.
- attr_reader :proxy_user
-
- # Returns the password for accessing the proxy, or +nil+ if none;
- # see Gem::Net::HTTP@Proxy+Server.
- attr_reader :proxy_pass
- end
-
- # Returns +true+ if a proxy server is defined, +false+ otherwise;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- def proxy?
- !!(@proxy_from_env ? proxy_uri : @proxy_address)
- end
-
- # Returns +true+ if the proxy server is defined in the environment,
- # +false+ otherwise;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- def proxy_from_env?
- @proxy_from_env
- end
-
- # The proxy URI determined from the environment for this connection.
- def proxy_uri # :nodoc:
- return if @proxy_uri == false
- @proxy_uri ||= Gem::URI::HTTP.new(
- "http", nil, address, port, nil, nil, nil, nil, nil
- ).find_proxy || false
- @proxy_uri || nil
- end
-
- # Returns the address of the proxy server, if defined, +nil+ otherwise;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- def proxy_address
- if @proxy_from_env then
- proxy_uri&.hostname
- else
- @proxy_address
- end
- end
-
- # Returns the port number of the proxy server, if defined, +nil+ otherwise;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- def proxy_port
- if @proxy_from_env then
- proxy_uri&.port
- else
- @proxy_port
- end
- end
-
- # Returns the user name of the proxy server, if defined, +nil+ otherwise;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- def proxy_user
- if @proxy_from_env
- user = proxy_uri&.user
- unescape(user) if user
- else
- @proxy_user
- end
- end
-
- # Returns the password of the proxy server, if defined, +nil+ otherwise;
- # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
- def proxy_pass
- if @proxy_from_env
- pass = proxy_uri&.password
- unescape(pass) if pass
- else
- @proxy_pass
- end
- end
-
- alias proxyaddr proxy_address #:nodoc: obsolete
- alias proxyport proxy_port #:nodoc: obsolete
-
- private
-
- def unescape(value)
- require 'cgi/util'
- CGI.unescape(value)
- end
-
- # without proxy, obsolete
-
- def conn_address # :nodoc:
- @ipaddr || address()
- end
-
- def conn_port # :nodoc:
- port()
- end
-
- def edit_path(path)
- if proxy?
- if path.start_with?("ftp://") || use_ssl?
- path
- else
- "http://#{addr_port}#{path}"
- end
- else
- path
- end
- end
-
- #
- # HTTP operations
- #
-
- public
-
- # :call-seq:
- # get(path, initheader = nil) {|res| ... }
- #
- # Sends a GET request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Get object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # With a block given, calls the block with the response body:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.get('/todos/1') do |res|
- # p res
- # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # Output:
- #
- # "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n}"
- #
- # With no block given, simply returns the response object:
- #
- # http.get('/') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # Related:
- #
- # - Gem::Net::HTTP::Get: request class for \HTTP method GET.
- # - Gem::Net::HTTP.get: sends GET request, returns response body.
- #
- def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
- res = nil
-
- request(Get.new(path, initheader)) {|r|
- r.read_body dest, &block
- res = r
- }
- res
- end
-
- # Sends a HEAD request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Head object
- # created from string +path+ and initial headers hash +initheader+:
- #
- # res = http.head('/todos/1') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- # res.body # => nil
- # res.to_hash.take(3)
- # # =>
- # [["date", ["Wed, 15 Feb 2023 15:25:42 GMT"]],
- # ["content-type", ["application/json; charset=utf-8"]],
- # ["connection", ["close"]]]
- #
- def head(path, initheader = nil)
- request(Head.new(path, initheader))
- end
-
- # :call-seq:
- # post(path, data, initheader = nil) {|res| ... }
- #
- # Sends a POST request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Post object
- # created from string +path+, string +data+, and initial headers hash +initheader+.
- #
- # With a block given, calls the block with the response body:
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.post('/todos', data) do |res|
- # p res
- # end # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- # Output:
- #
- # "{\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\",\n \"id\": 201\n}"
- #
- # With no block given, simply returns the response object:
- #
- # http.post('/todos', data) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- # Related:
- #
- # - Gem::Net::HTTP::Post: request class for \HTTP method POST.
- # - Gem::Net::HTTP.post: sends POST request, returns response body.
- #
- def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
- send_entity(path, data, initheader, dest, Post, &block)
- end
-
- # :call-seq:
- # patch(path, data, initheader = nil) {|res| ... }
- #
- # Sends a PATCH request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Patch object
- # created from string +path+, string +data+, and initial headers hash +initheader+.
- #
- # With a block given, calls the block with the response body:
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.patch('/todos/1', data) do |res|
- # p res
- # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # Output:
- #
- # "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false,\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\"\n}"
- #
- # With no block given, simply returns the response object:
- #
- # http.patch('/todos/1', data) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
- send_entity(path, data, initheader, dest, Patch, &block)
- end
-
- # Sends a PUT request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Put object
- # created from string +path+, string +data+, and initial headers hash +initheader+.
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.put('/todos/1', data) # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- def put(path, data, initheader = nil)
- request(Put.new(path, initheader), data)
- end
-
- # Sends a PROPPATCH request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Proppatch object
- # created from string +path+, string +body+, and initial headers hash +initheader+.
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.proppatch('/todos/1', data)
- #
- def proppatch(path, body, initheader = nil)
- request(Proppatch.new(path, initheader), body)
- end
-
- # Sends a LOCK request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Lock object
- # created from string +path+, string +body+, and initial headers hash +initheader+.
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.lock('/todos/1', data)
- #
- def lock(path, body, initheader = nil)
- request(Lock.new(path, initheader), body)
- end
-
- # Sends an UNLOCK request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Unlock object
- # created from string +path+, string +body+, and initial headers hash +initheader+.
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.unlock('/todos/1', data)
- #
- def unlock(path, body, initheader = nil)
- request(Unlock.new(path, initheader), body)
- end
-
- # Sends an Options request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Options object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.options('/')
- #
- def options(path, initheader = nil)
- request(Options.new(path, initheader))
- end
-
- # Sends a PROPFIND request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Propfind object
- # created from string +path+, string +body+, and initial headers hash +initheader+.
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http = Gem::Net::HTTP.new(hostname)
- # http.propfind('/todos/1', data)
- #
- def propfind(path, body = nil, initheader = {'Depth' => '0'})
- request(Propfind.new(path, initheader), body)
- end
-
- # Sends a DELETE request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Delete object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.delete('/todos/1')
- #
- def delete(path, initheader = {'Depth' => 'Infinity'})
- request(Delete.new(path, initheader))
- end
-
- # Sends a MOVE request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Move object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.move('/todos/1')
- #
- def move(path, initheader = nil)
- request(Move.new(path, initheader))
- end
-
- # Sends a COPY request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Copy object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.copy('/todos/1')
- #
- def copy(path, initheader = nil)
- request(Copy.new(path, initheader))
- end
-
- # Sends a MKCOL request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Mkcol object
- # created from string +path+, string +body+, and initial headers hash +initheader+.
- #
- # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
- # http.mkcol('/todos/1', data)
- # http = Gem::Net::HTTP.new(hostname)
- #
- def mkcol(path, body = nil, initheader = nil)
- request(Mkcol.new(path, initheader), body)
- end
-
- # Sends a TRACE request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Trace object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.trace('/todos/1')
- #
- def trace(path, initheader = nil)
- request(Trace.new(path, initheader))
- end
-
- # Sends a GET request to the server;
- # forms the response into a Gem::Net::HTTPResponse object.
- #
- # The request is based on the Gem::Net::HTTP::Get object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # With no block given, returns the response object:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.request_get('/todos') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # With a block given, calls the block with the response object
- # and returns the response object:
- #
- # http.request_get('/todos') do |res|
- # p res
- # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # Output:
- #
- # #<Gem::Net::HTTPOK 200 OK readbody=false>
- #
- def request_get(path, initheader = nil, &block) # :yield: +response+
- request(Get.new(path, initheader), &block)
- end
-
- # Sends a HEAD request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Head object
- # created from string +path+ and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.head('/todos/1') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- def request_head(path, initheader = nil, &block)
- request(Head.new(path, initheader), &block)
- end
-
- # Sends a POST request to the server;
- # forms the response into a Gem::Net::HTTPResponse object.
- #
- # The request is based on the Gem::Net::HTTP::Post object
- # created from string +path+, string +data+, and initial headers hash +initheader+.
- #
- # With no block given, returns the response object:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.post('/todos', 'xyzzy')
- # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- # With a block given, calls the block with the response body
- # and returns the response object:
- #
- # http.post('/todos', 'xyzzy') do |res|
- # p res
- # end # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- # Output:
- #
- # "{\n \"xyzzy\": \"\",\n \"id\": 201\n}"
- #
- def request_post(path, data, initheader = nil, &block) # :yield: +response+
- request Post.new(path, initheader), data, &block
- end
-
- # Sends a PUT request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTP::Put object
- # created from string +path+, string +data+, and initial headers hash +initheader+.
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.put('/todos/1', 'xyzzy')
- # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- def request_put(path, data, initheader = nil, &block) #:nodoc:
- request Put.new(path, initheader), data, &block
- end
-
- alias get2 request_get #:nodoc: obsolete
- alias head2 request_head #:nodoc: obsolete
- alias post2 request_post #:nodoc: obsolete
- alias put2 request_put #:nodoc: obsolete
-
- # Sends an \HTTP request to the server;
- # returns an instance of a subclass of Gem::Net::HTTPResponse.
- #
- # The request is based on the Gem::Net::HTTPRequest object
- # created from string +path+, string +data+, and initial headers hash +header+.
- # That object is an instance of the
- # {subclass of Gem::Net::HTTPRequest}[rdoc-ref:Gem::Net::HTTPRequest@Request+Subclasses],
- # that corresponds to the given uppercase string +name+,
- # which must be
- # an {HTTP request method}[https://en.wikipedia.org/wiki/HTTP#Request_methods]
- # or a {WebDAV request method}[https://en.wikipedia.org/wiki/WebDAV#Implementation].
- #
- # Examples:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.send_request('GET', '/todos/1')
- # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- # http.send_request('POST', '/todos', 'xyzzy')
- # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- def send_request(name, path, data = nil, header = nil)
- has_response_body = name != 'HEAD'
- r = HTTPGenericRequest.new(name,(data ? true : false),has_response_body,path,header)
- request r, data
- end
-
- # Sends the given request +req+ to the server;
- # forms the response into a Gem::Net::HTTPResponse object.
- #
- # The given +req+ must be an instance of a
- # {subclass of Gem::Net::HTTPRequest}[rdoc-ref:Gem::Net::HTTPRequest@Request+Subclasses].
- # Argument +body+ should be given only if needed for the request.
- #
- # With no block given, returns the response object:
- #
- # http = Gem::Net::HTTP.new(hostname)
- #
- # req = Gem::Net::HTTP::Get.new('/todos/1')
- # http.request(req)
- # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # req = Gem::Net::HTTP::Post.new('/todos')
- # http.request(req, 'xyzzy')
- # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- # With a block given, calls the block with the response and returns the response:
- #
- # req = Gem::Net::HTTP::Get.new('/todos/1')
- # http.request(req) do |res|
- # p res
- # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
- #
- # Output:
- #
- # #<Gem::Net::HTTPOK 200 OK readbody=false>
- #
- def request(req, body = nil, &block) # :yield: +response+
- unless started?
- start {
- req['connection'] ||= 'close'
- return request(req, body, &block)
- }
- end
- if proxy_user()
- req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
- end
- req.set_body_internal body
- res = transport_request(req, &block)
- if sspi_auth?(res)
- sspi_auth(req)
- res = transport_request(req, &block)
- end
- res
- end
-
- private
-
- # Executes a request which uses a representation
- # and returns its body.
- def send_entity(path, data, initheader, dest, type, &block)
- res = nil
- request(type.new(path, initheader), data) {|r|
- r.read_body dest, &block
- res = r
- }
- res
- end
-
- IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:
-
- def transport_request(req)
- count = 0
- begin
- begin_transport req
- res = catch(:response) {
- begin
- req.exec @socket, @curr_http_version, edit_path(req.path)
- rescue Errno::EPIPE
- # Failure when writing full request, but we can probably
- # still read the received response.
- end
-
- begin
- res = HTTPResponse.read_new(@socket)
- res.decode_content = req.decode_content
- res.body_encoding = @response_body_encoding
- res.ignore_eof = @ignore_eof
- end while res.kind_of?(HTTPInformation)
-
- res.uri = req.uri
-
- res
- }
- res.reading_body(@socket, req.response_body_permitted?) {
- yield res if block_given?
- }
- rescue Gem::Net::OpenTimeout
- raise
- rescue Gem::Net::ReadTimeout, IOError, EOFError,
- Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT,
- # avoid a dependency on OpenSSL
- defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
- Gem::Timeout::Error => exception
- if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
- count += 1
- @socket.close if @socket
- debug "Conn close because of error #{exception}, and retry"
- retry
- end
- debug "Conn close because of error #{exception}"
- @socket.close if @socket
- raise
- end
-
- end_transport req, res
- res
- rescue => exception
- debug "Conn close because of error #{exception}"
- @socket.close if @socket
- raise exception
- end
-
- def begin_transport(req)
- if @socket.closed?
- connect
- elsif @last_communicated
- if @last_communicated + @keep_alive_timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC)
- debug 'Conn close because of keep_alive_timeout'
- @socket.close
- connect
- elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
- debug "Conn close because of EOF"
- @socket.close
- connect
- end
- end
-
- if not req.response_body_permitted? and @close_on_empty_response
- req['connection'] ||= 'close'
- end
-
- req.update_uri address, port, use_ssl?
- req['host'] ||= addr_port()
- end
-
- def end_transport(req, res)
- @curr_http_version = res.http_version
- @last_communicated = nil
- if @socket.closed?
- debug 'Conn socket closed'
- elsif not res.body and @close_on_empty_response
- debug 'Conn close'
- @socket.close
- elsif keep_alive?(req, res)
- debug 'Conn keep-alive'
- @last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- else
- debug 'Conn close'
- @socket.close
- end
- end
-
- def keep_alive?(req, res)
- return false if req.connection_close?
- if @curr_http_version <= '1.0'
- res.connection_keep_alive?
- else # HTTP/1.1 or later
- not res.connection_close?
- end
- end
-
- def sspi_auth?(res)
- return false unless @sspi_enabled
- if res.kind_of?(HTTPProxyAuthenticationRequired) and
- proxy? and res["Proxy-Authenticate"].include?("Negotiate")
- begin
- require 'win32/sspi'
- true
- rescue LoadError
- false
- end
- else
- false
- end
- end
-
- def sspi_auth(req)
- n = Win32::SSPI::NegotiateAuth.new
- req["Proxy-Authorization"] = "Negotiate #{n.get_initial_token}"
- # Some versions of ISA will close the connection if this isn't present.
- req["Connection"] = "Keep-Alive"
- req["Proxy-Connection"] = "Keep-Alive"
- res = transport_request(req)
- authphrase = res["Proxy-Authenticate"] or return res
- req["Proxy-Authorization"] = "Negotiate #{n.complete_authentication(authphrase)}"
- rescue => err
- raise HTTPAuthenticationError.new('HTTP authentication failed', err)
- end
-
- #
- # utils
- #
-
- private
-
- def addr_port
- addr = address
- addr = "[#{addr}]" if addr.include?(":")
- default_port = use_ssl? ? HTTP.https_default_port : HTTP.http_default_port
- default_port == port ? addr : "#{addr}:#{port}"
- end
-
- # Adds a message to debugging output
- def debug(msg)
- return unless @debug_output
- @debug_output << msg
- @debug_output << "\n"
- end
-
- alias_method :D, :debug
- end
-
-end
-
-require_relative 'http/exceptions'
-
-require_relative 'http/header'
-
-require_relative 'http/generic_request'
-require_relative 'http/request'
-require_relative 'http/requests'
-
-require_relative 'http/response'
-require_relative 'http/responses'
-
-require_relative 'http/proxy_delta'
-
-require_relative 'http/backward'
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/backward.rb b/lib/rubygems/vendor/net-http/lib/net/http/backward.rb
deleted file mode 100644
index 10dbc16224..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/backward.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-# for backward compatibility
-
-# :enddoc:
-
-class Gem::Net::HTTP
- ProxyMod = ProxyDelta
- deprecate_constant :ProxyMod
-end
-
-module Gem::Net::NetPrivate
- HTTPRequest = ::Gem::Net::HTTPRequest
- deprecate_constant :HTTPRequest
-end
-
-module Gem::Net
- HTTPSession = HTTP
-
- HTTPInformationCode = HTTPInformation
- HTTPSuccessCode = HTTPSuccess
- HTTPRedirectionCode = HTTPRedirection
- HTTPRetriableCode = HTTPRedirection
- HTTPClientErrorCode = HTTPClientError
- HTTPFatalErrorCode = HTTPClientError
- HTTPServerErrorCode = HTTPServerError
- HTTPResponseReceiver = HTTPResponse
-
- HTTPResponceReceiver = HTTPResponse # Typo since 2001
-
- deprecate_constant :HTTPSession,
- :HTTPInformationCode,
- :HTTPSuccessCode,
- :HTTPRedirectionCode,
- :HTTPRetriableCode,
- :HTTPClientErrorCode,
- :HTTPFatalErrorCode,
- :HTTPServerErrorCode,
- :HTTPResponseReceiver,
- :HTTPResponceReceiver
-end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb b/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
deleted file mode 100644
index c629c0113b..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-module Gem::Net
- # Gem::Net::HTTP exception class.
- # You cannot use Gem::Net::HTTPExceptions directly; instead, you must use
- # its subclasses.
- module HTTPExceptions
- def initialize(msg, res) #:nodoc:
- super msg
- @response = res
- end
- attr_reader :response
- alias data response #:nodoc: obsolete
- end
-
- class HTTPError < ProtocolError
- include HTTPExceptions
- end
-
- class HTTPRetriableError < ProtoRetriableError
- include HTTPExceptions
- end
-
- class HTTPClientException < ProtoServerError
- include HTTPExceptions
- end
-
- class HTTPFatalError < ProtoFatalError
- include HTTPExceptions
- end
-
- # We cannot use the name "HTTPServerError", it is the name of the response.
- HTTPServerException = HTTPClientException # :nodoc:
- deprecate_constant(:HTTPServerException)
-end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb b/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb
deleted file mode 100644
index 5cfe75a7cd..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb
+++ /dev/null
@@ -1,414 +0,0 @@
-# frozen_string_literal: true
-#
-# \HTTPGenericRequest is the parent of the Gem::Net::HTTPRequest class.
-#
-# Do not use this directly; instead, use a subclass of Gem::Net::HTTPRequest.
-#
-# == About the Examples
-#
-# :include: doc/net-http/examples.rdoc
-#
-class Gem::Net::HTTPGenericRequest
-
- include Gem::Net::HTTPHeader
-
- def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc:
- @method = m
- @request_has_body = reqbody
- @response_has_body = resbody
-
- if Gem::URI === uri_or_path then
- raise ArgumentError, "not an HTTP Gem::URI" unless Gem::URI::HTTP === uri_or_path
- hostname = uri_or_path.hostname
- raise ArgumentError, "no host component for Gem::URI" unless (hostname && hostname.length > 0)
- @uri = uri_or_path.dup
- host = @uri.hostname.dup
- host << ":" << @uri.port.to_s if @uri.port != @uri.default_port
- @path = uri_or_path.request_uri
- raise ArgumentError, "no HTTP request path given" unless @path
- else
- @uri = nil
- host = nil
- raise ArgumentError, "no HTTP request path given" unless uri_or_path
- raise ArgumentError, "HTTP request path is empty" if uri_or_path.empty?
- @path = uri_or_path.dup
- end
-
- @decode_content = false
-
- if Gem::Net::HTTP::HAVE_ZLIB then
- if !initheader ||
- !initheader.keys.any? { |k|
- %w[accept-encoding range].include? k.downcase
- } then
- @decode_content = true if @response_has_body
- initheader = initheader ? initheader.dup : {}
- initheader["accept-encoding"] =
- "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
- end
- end
-
- initialize_http_header initheader
- self['Accept'] ||= '*/*'
- self['User-Agent'] ||= 'Ruby'
- self['Host'] ||= host if host
- @body = nil
- @body_stream = nil
- @body_data = nil
- end
-
- # Returns the string method name for the request:
- #
- # Gem::Net::HTTP::Get.new(uri).method # => "GET"
- # Gem::Net::HTTP::Post.new(uri).method # => "POST"
- #
- attr_reader :method
-
- # Returns the string path for the request:
- #
- # Gem::Net::HTTP::Get.new(uri).path # => "/"
- # Gem::Net::HTTP::Post.new('example.com').path # => "example.com"
- #
- attr_reader :path
-
- # Returns the Gem::URI object for the request, or +nil+ if none:
- #
- # Gem::Net::HTTP::Get.new(uri).uri
- # # => #<Gem::URI::HTTPS https://jsonplaceholder.typicode.com/>
- # Gem::Net::HTTP::Get.new('example.com').uri # => nil
- #
- attr_reader :uri
-
- # Returns +false+ if the request's header <tt>'Accept-Encoding'</tt>
- # has been set manually or deleted
- # (indicating that the user intends to handle encoding in the response),
- # +true+ otherwise:
- #
- # req = Gem::Net::HTTP::Get.new(uri) # => #<Gem::Net::HTTP::Get GET>
- # req['Accept-Encoding'] # => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
- # req.decode_content # => true
- # req['Accept-Encoding'] = 'foo'
- # req.decode_content # => false
- # req.delete('Accept-Encoding')
- # req.decode_content # => false
- #
- attr_reader :decode_content
-
- # Returns a string representation of the request:
- #
- # Gem::Net::HTTP::Post.new(uri).inspect # => "#<Gem::Net::HTTP::Post POST>"
- #
- def inspect
- "\#<#{self.class} #{@method}>"
- end
-
- ##
- # Don't automatically decode response content-encoding if the user indicates
- # they want to handle it.
-
- def []=(key, val) # :nodoc:
- @decode_content = false if key.downcase == 'accept-encoding'
-
- super key, val
- end
-
- # Returns whether the request may have a body:
- #
- # Gem::Net::HTTP::Post.new(uri).request_body_permitted? # => true
- # Gem::Net::HTTP::Get.new(uri).request_body_permitted? # => false
- #
- def request_body_permitted?
- @request_has_body
- end
-
- # Returns whether the response may have a body:
- #
- # Gem::Net::HTTP::Post.new(uri).response_body_permitted? # => true
- # Gem::Net::HTTP::Head.new(uri).response_body_permitted? # => false
- #
- def response_body_permitted?
- @response_has_body
- end
-
- def body_exist? # :nodoc:
- warn "Gem::Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?", uplevel: 1 if $VERBOSE
- response_body_permitted?
- end
-
- # Returns the string body for the request, or +nil+ if there is none:
- #
- # req = Gem::Net::HTTP::Post.new(uri)
- # req.body # => nil
- # req.body = '{"title": "foo","body": "bar","userId": 1}'
- # req.body # => "{\"title\": \"foo\",\"body\": \"bar\",\"userId\": 1}"
- #
- attr_reader :body
-
- # Sets the body for the request:
- #
- # req = Gem::Net::HTTP::Post.new(uri)
- # req.body # => nil
- # req.body = '{"title": "foo","body": "bar","userId": 1}'
- # req.body # => "{\"title\": \"foo\",\"body\": \"bar\",\"userId\": 1}"
- #
- def body=(str)
- @body = str
- @body_stream = nil
- @body_data = nil
- str
- end
-
- # Returns the body stream object for the request, or +nil+ if there is none:
- #
- # req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
- # req.body_stream # => nil
- # require 'stringio'
- # req.body_stream = StringIO.new('xyzzy') # => #<StringIO:0x0000027d1e5affa8>
- # req.body_stream # => #<StringIO:0x0000027d1e5affa8>
- #
- attr_reader :body_stream
-
- # Sets the body stream for the request:
- #
- # req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
- # req.body_stream # => nil
- # require 'stringio'
- # req.body_stream = StringIO.new('xyzzy') # => #<StringIO:0x0000027d1e5affa8>
- # req.body_stream # => #<StringIO:0x0000027d1e5affa8>
- #
- def body_stream=(input)
- @body = nil
- @body_stream = input
- @body_data = nil
- input
- end
-
- def set_body_internal(str) #:nodoc: internal use only
- raise ArgumentError, "both of body argument and HTTPRequest#body set" if str and (@body or @body_stream)
- self.body = str if str
- if @body.nil? && @body_stream.nil? && @body_data.nil? && request_body_permitted?
- self.body = ''
- end
- end
-
- #
- # write
- #
-
- def exec(sock, ver, path) #:nodoc: internal use only
- if @body
- send_request_with_body sock, ver, path, @body
- elsif @body_stream
- send_request_with_body_stream sock, ver, path, @body_stream
- elsif @body_data
- send_request_with_body_data sock, ver, path, @body_data
- else
- write_header sock, ver, path
- end
- end
-
- def update_uri(addr, port, ssl) # :nodoc: internal use only
- # reflect the connection and @path to @uri
- return unless @uri
-
- if ssl
- scheme = 'https'
- klass = Gem::URI::HTTPS
- else
- scheme = 'http'
- klass = Gem::URI::HTTP
- end
-
- if host = self['host']
- host.sub!(/:.*/m, '')
- elsif host = @uri.host
- else
- host = addr
- end
- # convert the class of the Gem::URI
- if @uri.is_a?(klass)
- @uri.host = host
- @uri.port = port
- else
- @uri = klass.new(
- scheme, @uri.userinfo,
- host, port, nil,
- @uri.path, nil, @uri.query, nil)
- end
- end
-
- private
-
- class Chunker #:nodoc:
- def initialize(sock)
- @sock = sock
- @prev = nil
- end
-
- def write(buf)
- # avoid memcpy() of buf, buf can huge and eat memory bandwidth
- rv = buf.bytesize
- @sock.write("#{rv.to_s(16)}\r\n", buf, "\r\n")
- rv
- end
-
- def finish
- @sock.write("0\r\n\r\n")
- end
- end
-
- def send_request_with_body(sock, ver, path, body)
- self.content_length = body.bytesize
- delete 'Transfer-Encoding'
- supply_default_content_type
- write_header sock, ver, path
- wait_for_continue sock, ver if sock.continue_timeout
- sock.write body
- end
-
- def send_request_with_body_stream(sock, ver, path, f)
- unless content_length() or chunked?
- raise ArgumentError,
- "Content-Length not given and Transfer-Encoding is not `chunked'"
- end
- supply_default_content_type
- write_header sock, ver, path
- wait_for_continue sock, ver if sock.continue_timeout
- if chunked?
- chunker = Chunker.new(sock)
- IO.copy_stream(f, chunker)
- chunker.finish
- else
- IO.copy_stream(f, sock)
- end
- end
-
- def send_request_with_body_data(sock, ver, path, params)
- if /\Amultipart\/form-data\z/i !~ self.content_type
- self.content_type = 'application/x-www-form-urlencoded'
- return send_request_with_body(sock, ver, path, Gem::URI.encode_www_form(params))
- end
-
- opt = @form_option.dup
- require 'securerandom' unless defined?(SecureRandom)
- opt[:boundary] ||= SecureRandom.urlsafe_base64(40)
- self.set_content_type(self.content_type, boundary: opt[:boundary])
- if chunked?
- write_header sock, ver, path
- encode_multipart_form_data(sock, params, opt)
- else
- require 'tempfile'
- file = Tempfile.new('multipart')
- file.binmode
- encode_multipart_form_data(file, params, opt)
- file.rewind
- self.content_length = file.size
- write_header sock, ver, path
- IO.copy_stream(file, sock)
- file.close(true)
- end
- end
-
- def encode_multipart_form_data(out, params, opt)
- charset = opt[:charset]
- boundary = opt[:boundary]
- require 'securerandom' unless defined?(SecureRandom)
- boundary ||= SecureRandom.urlsafe_base64(40)
- chunked_p = chunked?
-
- buf = +''
- params.each do |key, value, h={}|
- key = quote_string(key, charset)
- filename =
- h.key?(:filename) ? h[:filename] :
- value.respond_to?(:to_path) ? File.basename(value.to_path) :
- nil
-
- buf << "--#{boundary}\r\n"
- if filename
- filename = quote_string(filename, charset)
- type = h[:content_type] || 'application/octet-stream'
- buf << "Content-Disposition: form-data; " \
- "name=\"#{key}\"; filename=\"#{filename}\"\r\n" \
- "Content-Type: #{type}\r\n\r\n"
- if !out.respond_to?(:write) || !value.respond_to?(:read)
- # if +out+ is not an IO or +value+ is not an IO
- buf << (value.respond_to?(:read) ? value.read : value)
- elsif value.respond_to?(:size) && chunked_p
- # if +out+ is an IO and +value+ is a File, use IO.copy_stream
- flush_buffer(out, buf, chunked_p)
- out << "%x\r\n" % value.size if chunked_p
- IO.copy_stream(value, out)
- out << "\r\n" if chunked_p
- else
- # +out+ is an IO, and +value+ is not a File but an IO
- flush_buffer(out, buf, chunked_p)
- 1 while flush_buffer(out, value.read(4096), chunked_p)
- end
- else
- # non-file field:
- # HTML5 says, "The parts of the generated multipart/form-data
- # resource that correspond to non-file fields must not have a
- # Content-Type header specified."
- buf << "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
- buf << (value.respond_to?(:read) ? value.read : value)
- end
- buf << "\r\n"
- end
- buf << "--#{boundary}--\r\n"
- flush_buffer(out, buf, chunked_p)
- out << "0\r\n\r\n" if chunked_p
- end
-
- def quote_string(str, charset)
- str = str.encode(charset, fallback:->(c){'&#%d;'%c.encode("UTF-8").ord}) if charset
- str.gsub(/[\\"]/, '\\\\\&')
- end
-
- def flush_buffer(out, buf, chunked_p)
- return unless buf
- out << "%x\r\n"%buf.bytesize if chunked_p
- out << buf
- out << "\r\n" if chunked_p
- buf.clear
- end
-
- def supply_default_content_type
- return if content_type()
- warn 'net/http: Content-Type did not set; using application/x-www-form-urlencoded', uplevel: 1 if $VERBOSE
- set_content_type 'application/x-www-form-urlencoded'
- end
-
- ##
- # Waits up to the continue timeout for a response from the server provided
- # we're speaking HTTP 1.1 and are expecting a 100-continue response.
-
- def wait_for_continue(sock, ver)
- if ver >= '1.1' and @header['expect'] and
- @header['expect'].include?('100-continue')
- if sock.io.to_io.wait_readable(sock.continue_timeout)
- res = Gem::Net::HTTPResponse.read_new(sock)
- unless res.kind_of?(Gem::Net::HTTPContinue)
- res.decode_content = @decode_content
- throw :response, res
- end
- end
- end
- end
-
- def write_header(sock, ver, path)
- reqline = "#{@method} #{path} HTTP/#{ver}"
- if /[\r\n]/ =~ reqline
- raise ArgumentError, "A Request-Line must not contain CR or LF"
- end
- buf = +''
- buf << reqline << "\r\n"
- each_capitalized do |k,v|
- buf << "#{k}: #{v}\r\n"
- end
- buf << "\r\n"
- sock.write buf
- end
-
-end
-
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/header.rb b/lib/rubygems/vendor/net-http/lib/net/http/header.rb
deleted file mode 100644
index 1488e60068..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/header.rb
+++ /dev/null
@@ -1,981 +0,0 @@
-# frozen_string_literal: true
-#
-# The \HTTPHeader module provides access to \HTTP headers.
-#
-# The module is included in:
-#
-# - Gem::Net::HTTPGenericRequest (and therefore Gem::Net::HTTPRequest).
-# - Gem::Net::HTTPResponse.
-#
-# The headers are a hash-like collection of key/value pairs called _fields_.
-#
-# == Request and Response Fields
-#
-# Headers may be included in:
-#
-# - A Gem::Net::HTTPRequest object:
-# the object's headers will be sent with the request.
-# Any fields may be defined in the request;
-# see {Setters}[rdoc-ref:Gem::Net::HTTPHeader@Setters].
-# - A Gem::Net::HTTPResponse object:
-# the objects headers are usually those returned from the host.
-# Fields may be retrieved from the object;
-# see {Getters}[rdoc-ref:Gem::Net::HTTPHeader@Getters]
-# and {Iterators}[rdoc-ref:Gem::Net::HTTPHeader@Iterators].
-#
-# Exactly which fields should be sent or expected depends on the host;
-# see:
-#
-# - {Request fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
-# - {Response fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields].
-#
-# == About the Examples
-#
-# :include: doc/net-http/examples.rdoc
-#
-# == Fields
-#
-# A header field is a key/value pair.
-#
-# === Field Keys
-#
-# A field key may be:
-#
-# - A string: Key <tt>'Accept'</tt> is treated as if it were
-# <tt>'Accept'.downcase</tt>; i.e., <tt>'accept'</tt>.
-# - A symbol: Key <tt>:Accept</tt> is treated as if it were
-# <tt>:Accept.to_s.downcase</tt>; i.e., <tt>'accept'</tt>.
-#
-# Examples:
-#
-# req = Gem::Net::HTTP::Get.new(uri)
-# req[:accept] # => "*/*"
-# req['Accept'] # => "*/*"
-# req['ACCEPT'] # => "*/*"
-#
-# req['accept'] = 'text/html'
-# req[:accept] = 'text/html'
-# req['ACCEPT'] = 'text/html'
-#
-# === Field Values
-#
-# A field value may be returned as an array of strings or as a string:
-#
-# - These methods return field values as arrays:
-#
-# - #get_fields: Returns the array value for the given key,
-# or +nil+ if it does not exist.
-# - #to_hash: Returns a hash of all header fields:
-# each key is a field name; its value is the array value for the field.
-#
-# - These methods return field values as string;
-# the string value for a field is equivalent to
-# <tt>self[key.downcase.to_s].join(', '))</tt>:
-#
-# - #[]: Returns the string value for the given key,
-# or +nil+ if it does not exist.
-# - #fetch: Like #[], but accepts a default value
-# to be returned if the key does not exist.
-#
-# The field value may be set:
-#
-# - #[]=: Sets the value for the given key;
-# the given value may be a string, a symbol, an array, or a hash.
-# - #add_field: Adds a given value to a value for the given key
-# (not overwriting the existing value).
-# - #delete: Deletes the field for the given key.
-#
-# Example field values:
-#
-# - \String:
-#
-# req['Accept'] = 'text/html' # => "text/html"
-# req['Accept'] # => "text/html"
-# req.get_fields('Accept') # => ["text/html"]
-#
-# - \Symbol:
-#
-# req['Accept'] = :text # => :text
-# req['Accept'] # => "text"
-# req.get_fields('Accept') # => ["text"]
-#
-# - Simple array:
-#
-# req[:foo] = %w[bar baz bat]
-# req[:foo] # => "bar, baz, bat"
-# req.get_fields(:foo) # => ["bar", "baz", "bat"]
-#
-# - Simple hash:
-#
-# req[:foo] = {bar: 0, baz: 1, bat: 2}
-# req[:foo] # => "bar, 0, baz, 1, bat, 2"
-# req.get_fields(:foo) # => ["bar", "0", "baz", "1", "bat", "2"]
-#
-# - Nested:
-#
-# req[:foo] = [%w[bar baz], {bat: 0, bam: 1}]
-# req[:foo] # => "bar, baz, bat, 0, bam, 1"
-# req.get_fields(:foo) # => ["bar", "baz", "bat", "0", "bam", "1"]
-#
-# req[:foo] = {bar: %w[baz bat], bam: {bah: 0, bad: 1}}
-# req[:foo] # => "bar, baz, bat, bam, bah, 0, bad, 1"
-# req.get_fields(:foo) # => ["bar", "baz", "bat", "bam", "bah", "0", "bad", "1"]
-#
-# == Convenience Methods
-#
-# Various convenience methods retrieve values, set values, query values,
-# set form values, or iterate over fields.
-#
-# === Setters
-#
-# \Method #[]= can set any field, but does little to validate the new value;
-# some of the other setter methods provide some validation:
-#
-# - #[]=: Sets the string or array value for the given key.
-# - #add_field: Creates or adds to the array value for the given key.
-# - #basic_auth: Sets the string authorization header for <tt>'Authorization'</tt>.
-# - #content_length=: Sets the integer length for field <tt>'Content-Length</tt>.
-# - #content_type=: Sets the string value for field <tt>'Content-Type'</tt>.
-# - #proxy_basic_auth: Sets the string authorization header for <tt>'Proxy-Authorization'</tt>.
-# - #set_range: Sets the value for field <tt>'Range'</tt>.
-#
-# === Form Setters
-#
-# - #set_form: Sets an HTML form data set.
-# - #set_form_data: Sets header fields and a body from HTML form data.
-#
-# === Getters
-#
-# \Method #[] can retrieve the value of any field that exists,
-# but always as a string;
-# some of the other getter methods return something different
-# from the simple string value:
-#
-# - #[]: Returns the string field value for the given key.
-# - #content_length: Returns the integer value of field <tt>'Content-Length'</tt>.
-# - #content_range: Returns the Range value of field <tt>'Content-Range'</tt>.
-# - #content_type: Returns the string value of field <tt>'Content-Type'</tt>.
-# - #fetch: Returns the string field value for the given key.
-# - #get_fields: Returns the array field value for the given +key+.
-# - #main_type: Returns first part of the string value of field <tt>'Content-Type'</tt>.
-# - #sub_type: Returns second part of the string value of field <tt>'Content-Type'</tt>.
-# - #range: Returns an array of Range objects of field <tt>'Range'</tt>, or +nil+.
-# - #range_length: Returns the integer length of the range given in field <tt>'Content-Range'</tt>.
-# - #type_params: Returns the string parameters for <tt>'Content-Type'</tt>.
-#
-# === Queries
-#
-# - #chunked?: Returns whether field <tt>'Transfer-Encoding'</tt> is set to <tt>'chunked'</tt>.
-# - #connection_close?: Returns whether field <tt>'Connection'</tt> is set to <tt>'close'</tt>.
-# - #connection_keep_alive?: Returns whether field <tt>'Connection'</tt> is set to <tt>'keep-alive'</tt>.
-# - #key?: Returns whether a given key exists.
-#
-# === Iterators
-#
-# - #each_capitalized: Passes each field capitalized-name/value pair to the block.
-# - #each_capitalized_name: Passes each capitalized field name to the block.
-# - #each_header: Passes each field name/value pair to the block.
-# - #each_name: Passes each field name to the block.
-# - #each_value: Passes each string field value to the block.
-#
-module Gem::Net::HTTPHeader
- MAX_KEY_LENGTH = 1024
- MAX_FIELD_LENGTH = 65536
-
- def initialize_http_header(initheader) #:nodoc:
- @header = {}
- return unless initheader
- initheader.each do |key, value|
- warn "net/http: duplicated HTTP header: #{key}", uplevel: 3 if key?(key) and $VERBOSE
- if value.nil?
- warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE
- else
- value = value.strip # raise error for invalid byte sequences
- if key.to_s.bytesize > MAX_KEY_LENGTH
- raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..."
- end
- if value.to_s.bytesize > MAX_FIELD_LENGTH
- raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}"
- end
- if value.count("\r\n") > 0
- raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
- end
- @header[key.downcase.to_s] = [value]
- end
- end
- end
-
- def size #:nodoc: obsolete
- @header.size
- end
-
- alias length size #:nodoc: obsolete
-
- # Returns the string field value for the case-insensitive field +key+,
- # or +nil+ if there is no such key;
- # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['Connection'] # => "keep-alive"
- # res['Nosuch'] # => nil
- #
- # Note that some field values may be retrieved via convenience methods;
- # see {Getters}[rdoc-ref:Gem::Net::HTTPHeader@Getters].
- def [](key)
- a = @header[key.downcase.to_s] or return nil
- a.join(', ')
- end
-
- # Sets the value for the case-insensitive +key+ to +val+,
- # overwriting the previous value if the field exists;
- # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req['Accept'] # => "*/*"
- # req['Accept'] = 'text/html'
- # req['Accept'] # => "text/html"
- #
- # Note that some field values may be set via convenience methods;
- # see {Setters}[rdoc-ref:Gem::Net::HTTPHeader@Setters].
- def []=(key, val)
- unless val
- @header.delete key.downcase.to_s
- return val
- end
- set_field(key, val)
- end
-
- # Adds value +val+ to the value array for field +key+ if the field exists;
- # creates the field with the given +key+ and +val+ if it does not exist.
- # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.add_field('Foo', 'bar')
- # req['Foo'] # => "bar"
- # req.add_field('Foo', 'baz')
- # req['Foo'] # => "bar, baz"
- # req.add_field('Foo', %w[baz bam])
- # req['Foo'] # => "bar, baz, baz, bam"
- # req.get_fields('Foo') # => ["bar", "baz", "baz", "bam"]
- #
- def add_field(key, val)
- stringified_downcased_key = key.downcase.to_s
- if @header.key?(stringified_downcased_key)
- append_field_value(@header[stringified_downcased_key], val)
- else
- set_field(key, val)
- end
- end
-
- private def set_field(key, val)
- case val
- when Enumerable
- ary = []
- append_field_value(ary, val)
- @header[key.downcase.to_s] = ary
- else
- val = val.to_s # for compatibility use to_s instead of to_str
- if val.b.count("\r\n") > 0
- raise ArgumentError, 'header field value cannot include CR/LF'
- end
- @header[key.downcase.to_s] = [val]
- end
- end
-
- private def append_field_value(ary, val)
- case val
- when Enumerable
- val.each{|x| append_field_value(ary, x)}
- else
- val = val.to_s
- if /[\r\n]/n.match?(val.b)
- raise ArgumentError, 'header field value cannot include CR/LF'
- end
- ary.push val
- end
- end
-
- # Returns the array field value for the given +key+,
- # or +nil+ if there is no such field;
- # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res.get_fields('Connection') # => ["keep-alive"]
- # res.get_fields('Nosuch') # => nil
- #
- def get_fields(key)
- stringified_downcased_key = key.downcase.to_s
- return nil unless @header[stringified_downcased_key]
- @header[stringified_downcased_key].dup
- end
-
- # call-seq:
- # fetch(key, default_val = nil) {|key| ... } -> object
- # fetch(key, default_val = nil) -> value or default_val
- #
- # With a block, returns the string value for +key+ if it exists;
- # otherwise returns the value of the block;
- # ignores the +default_val+;
- # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- #
- # # Field exists; block not called.
- # res.fetch('Connection') do |value|
- # fail 'Cannot happen'
- # end # => "keep-alive"
- #
- # # Field does not exist; block called.
- # res.fetch('Nosuch') do |value|
- # value.downcase
- # end # => "nosuch"
- #
- # With no block, returns the string value for +key+ if it exists;
- # otherwise, returns +default_val+ if it was given;
- # otherwise raises an exception:
- #
- # res.fetch('Connection', 'Foo') # => "keep-alive"
- # res.fetch('Nosuch', 'Foo') # => "Foo"
- # res.fetch('Nosuch') # Raises KeyError.
- #
- def fetch(key, *args, &block) #:yield: +key+
- a = @header.fetch(key.downcase.to_s, *args, &block)
- a.kind_of?(Array) ? a.join(', ') : a
- end
-
- # Calls the block with each key/value pair:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res.each_header do |key, value|
- # p [key, value] if key.start_with?('c')
- # end
- #
- # Output:
- #
- # ["content-type", "application/json; charset=utf-8"]
- # ["connection", "keep-alive"]
- # ["cache-control", "max-age=43200"]
- # ["cf-cache-status", "HIT"]
- # ["cf-ray", "771d17e9bc542cf5-ORD"]
- #
- # Returns an enumerator if no block is given.
- #
- # Gem::Net::HTTPHeader#each is an alias for Gem::Net::HTTPHeader#each_header.
- def each_header #:yield: +key+, +value+
- block_given? or return enum_for(__method__) { @header.size }
- @header.each do |k,va|
- yield k, va.join(', ')
- end
- end
-
- alias each each_header
-
- # Calls the block with each field key:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res.each_key do |key|
- # p key if key.start_with?('c')
- # end
- #
- # Output:
- #
- # "content-type"
- # "connection"
- # "cache-control"
- # "cf-cache-status"
- # "cf-ray"
- #
- # Returns an enumerator if no block is given.
- #
- # Gem::Net::HTTPHeader#each_name is an alias for Gem::Net::HTTPHeader#each_key.
- def each_name(&block) #:yield: +key+
- block_given? or return enum_for(__method__) { @header.size }
- @header.each_key(&block)
- end
-
- alias each_key each_name
-
- # Calls the block with each capitalized field name:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res.each_capitalized_name do |key|
- # p key if key.start_with?('C')
- # end
- #
- # Output:
- #
- # "Content-Type"
- # "Connection"
- # "Cache-Control"
- # "Cf-Cache-Status"
- # "Cf-Ray"
- #
- # The capitalization is system-dependent;
- # see {Case Mapping}[https://docs.ruby-lang.org/en/master/case_mapping_rdoc.html].
- #
- # Returns an enumerator if no block is given.
- def each_capitalized_name #:yield: +key+
- block_given? or return enum_for(__method__) { @header.size }
- @header.each_key do |k|
- yield capitalize(k)
- end
- end
-
- # Calls the block with each string field value:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res.each_value do |value|
- # p value if value.start_with?('c')
- # end
- #
- # Output:
- #
- # "chunked"
- # "cf-q-config;dur=6.0000002122251e-06"
- # "cloudflare"
- #
- # Returns an enumerator if no block is given.
- def each_value #:yield: +value+
- block_given? or return enum_for(__method__) { @header.size }
- @header.each_value do |va|
- yield va.join(', ')
- end
- end
-
- # Removes the header for the given case-insensitive +key+
- # (see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]);
- # returns the deleted value, or +nil+ if no such field exists:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.delete('Accept') # => ["*/*"]
- # req.delete('Nosuch') # => nil
- #
- def delete(key)
- @header.delete(key.downcase.to_s)
- end
-
- # Returns +true+ if the field for the case-insensitive +key+ exists, +false+ otherwise:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.key?('Accept') # => true
- # req.key?('Nosuch') # => false
- #
- def key?(key)
- @header.key?(key.downcase.to_s)
- end
-
- # Returns a hash of the key/value pairs:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.to_hash
- # # =>
- # {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
- # "accept"=>["*/*"],
- # "user-agent"=>["Ruby"],
- # "host"=>["jsonplaceholder.typicode.com"]}
- #
- def to_hash
- @header.dup
- end
-
- # Like #each_header, but the keys are returned in capitalized form.
- #
- # Gem::Net::HTTPHeader#canonical_each is an alias for Gem::Net::HTTPHeader#each_capitalized.
- def each_capitalized
- block_given? or return enum_for(__method__) { @header.size }
- @header.each do |k,v|
- yield capitalize(k), v.join(', ')
- end
- end
-
- alias canonical_each each_capitalized
-
- def capitalize(name)
- name.to_s.split(/-/).map {|s| s.capitalize }.join('-')
- end
- private :capitalize
-
- # Returns an array of Range objects that represent
- # the value of field <tt>'Range'</tt>,
- # or +nil+ if there is no such field;
- # see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req['Range'] = 'bytes=0-99,200-299,400-499'
- # req.range # => [0..99, 200..299, 400..499]
- # req.delete('Range')
- # req.range # # => nil
- #
- def range
- return nil unless @header['range']
-
- value = self['Range']
- # byte-range-set = *( "," OWS ) ( byte-range-spec / suffix-byte-range-spec )
- # *( OWS "," [ OWS ( byte-range-spec / suffix-byte-range-spec ) ] )
- # corrected collected ABNF
- # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#section-5.4.1
- # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#appendix-C
- # http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-19#section-3.2.5
- unless /\Abytes=((?:,[ \t]*)*(?:\d+-\d*|-\d+)(?:[ \t]*,(?:[ \t]*\d+-\d*|-\d+)?)*)\z/ =~ value
- raise Gem::Net::HTTPHeaderSyntaxError, "invalid syntax for byte-ranges-specifier: '#{value}'"
- end
-
- byte_range_set = $1
- result = byte_range_set.split(/,/).map {|spec|
- m = /(\d+)?\s*-\s*(\d+)?/i.match(spec) or
- raise Gem::Net::HTTPHeaderSyntaxError, "invalid byte-range-spec: '#{spec}'"
- d1 = m[1].to_i
- d2 = m[2].to_i
- if m[1] and m[2]
- if d1 > d2
- raise Gem::Net::HTTPHeaderSyntaxError, "last-byte-pos MUST greater than or equal to first-byte-pos but '#{spec}'"
- end
- d1..d2
- elsif m[1]
- d1..-1
- elsif m[2]
- -d2..-1
- else
- raise Gem::Net::HTTPHeaderSyntaxError, 'range is not specified'
- end
- }
- # if result.empty?
- # byte-range-set must include at least one byte-range-spec or suffix-byte-range-spec
- # but above regexp already denies it.
- if result.size == 1 && result[0].begin == 0 && result[0].end == -1
- raise Gem::Net::HTTPHeaderSyntaxError, 'only one suffix-byte-range-spec with zero suffix-length'
- end
- result
- end
-
- # call-seq:
- # set_range(length) -> length
- # set_range(offset, length) -> range
- # set_range(begin..length) -> range
- #
- # Sets the value for field <tt>'Range'</tt>;
- # see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
- #
- # With argument +length+:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.set_range(100) # => 100
- # req['Range'] # => "bytes=0-99"
- #
- # With arguments +offset+ and +length+:
- #
- # req.set_range(100, 100) # => 100...200
- # req['Range'] # => "bytes=100-199"
- #
- # With argument +range+:
- #
- # req.set_range(100..199) # => 100..199
- # req['Range'] # => "bytes=100-199"
- #
- # Gem::Net::HTTPHeader#range= is an alias for Gem::Net::HTTPHeader#set_range.
- def set_range(r, e = nil)
- unless r
- @header.delete 'range'
- return r
- end
- r = (r...r+e) if e
- case r
- when Numeric
- n = r.to_i
- rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
- when Range
- first = r.first
- last = r.end
- last -= 1 if r.exclude_end?
- if last == -1
- rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
- else
- raise Gem::Net::HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
- raise Gem::Net::HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
- raise Gem::Net::HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
- rangestr = "#{first}-#{last}"
- end
- else
- raise TypeError, 'Range/Integer is required'
- end
- @header['range'] = ["bytes=#{rangestr}"]
- r
- end
-
- alias range= set_range
-
- # Returns the value of field <tt>'Content-Length'</tt> as an integer,
- # or +nil+ if there is no such field;
- # see {Content-Length request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-request-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/nosuch/1')
- # res.content_length # => 2
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res.content_length # => nil
- #
- def content_length
- return nil unless key?('Content-Length')
- len = self['Content-Length'].slice(/\d+/) or
- raise Gem::Net::HTTPHeaderSyntaxError, 'wrong Content-Length format'
- len.to_i
- end
-
- # Sets the value of field <tt>'Content-Length'</tt> to the given numeric;
- # see {Content-Length response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-response-header]:
- #
- # _uri = uri.dup
- # hostname = _uri.hostname # => "jsonplaceholder.typicode.com"
- # _uri.path = '/posts' # => "/posts"
- # req = Gem::Net::HTTP::Post.new(_uri) # => #<Gem::Net::HTTP::Post POST>
- # req.body = '{"title": "foo","body": "bar","userId": 1}'
- # req.content_length = req.body.size # => 42
- # req.content_type = 'application/json'
- # res = Gem::Net::HTTP.start(hostname) do |http|
- # http.request(req)
- # end # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
- #
- def content_length=(len)
- unless len
- @header.delete 'content-length'
- return nil
- end
- @header['content-length'] = [len.to_i.to_s]
- end
-
- # Returns +true+ if field <tt>'Transfer-Encoding'</tt>
- # exists and has value <tt>'chunked'</tt>,
- # +false+ otherwise;
- # see {Transfer-Encoding response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#transfer-encoding-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['Transfer-Encoding'] # => "chunked"
- # res.chunked? # => true
- #
- def chunked?
- return false unless @header['transfer-encoding']
- field = self['Transfer-Encoding']
- (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
- end
-
- # Returns a Range object representing the value of field
- # <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
- # see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['Content-Range'] # => nil
- # res['Content-Range'] = 'bytes 0-499/1000'
- # res['Content-Range'] # => "bytes 0-499/1000"
- # res.content_range # => 0..499
- #
- def content_range
- return nil unless @header['content-range']
- m = %r<\A\s*(\w+)\s+(\d+)-(\d+)/(\d+|\*)>.match(self['Content-Range']) or
- raise Gem::Net::HTTPHeaderSyntaxError, 'wrong Content-Range format'
- return unless m[1] == 'bytes'
- m[2].to_i .. m[3].to_i
- end
-
- # Returns the integer representing length of the value of field
- # <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
- # see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['Content-Range'] # => nil
- # res['Content-Range'] = 'bytes 0-499/1000'
- # res.range_length # => 500
- #
- def range_length
- r = content_range() or return nil
- r.end - r.begin + 1
- end
-
- # Returns the {media type}[https://en.wikipedia.org/wiki/Media_type]
- # from the value of field <tt>'Content-Type'</tt>,
- # or +nil+ if no such field exists;
- # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['content-type'] # => "application/json; charset=utf-8"
- # res.content_type # => "application/json"
- #
- def content_type
- main = main_type()
- return nil unless main
-
- sub = sub_type()
- if sub
- "#{main}/#{sub}"
- else
- main
- end
- end
-
- # Returns the leading ('type') part of the
- # {media type}[https://en.wikipedia.org/wiki/Media_type]
- # from the value of field <tt>'Content-Type'</tt>,
- # or +nil+ if no such field exists;
- # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['content-type'] # => "application/json; charset=utf-8"
- # res.main_type # => "application"
- #
- def main_type
- return nil unless @header['content-type']
- self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
- end
-
- # Returns the trailing ('subtype') part of the
- # {media type}[https://en.wikipedia.org/wiki/Media_type]
- # from the value of field <tt>'Content-Type'</tt>,
- # or +nil+ if no such field exists;
- # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['content-type'] # => "application/json; charset=utf-8"
- # res.sub_type # => "json"
- #
- def sub_type
- return nil unless @header['content-type']
- _, sub = *self['Content-Type'].split(';').first.to_s.split('/')
- return nil unless sub
- sub.strip
- end
-
- # Returns the trailing ('parameters') part of the value of field <tt>'Content-Type'</tt>,
- # or +nil+ if no such field exists;
- # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
- #
- # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
- # res['content-type'] # => "application/json; charset=utf-8"
- # res.type_params # => {"charset"=>"utf-8"}
- #
- def type_params
- result = {}
- list = self['Content-Type'].to_s.split(';')
- list.shift
- list.each do |param|
- k, v = *param.split('=', 2)
- result[k.strip] = v.strip
- end
- result
- end
-
- # Sets the value of field <tt>'Content-Type'</tt>;
- # returns the new value;
- # see {Content-Type request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-request-header]:
- #
- # req = Gem::Net::HTTP::Get.new(uri)
- # req.set_content_type('application/json') # => ["application/json"]
- #
- # Gem::Net::HTTPHeader#content_type= is an alias for Gem::Net::HTTPHeader#set_content_type.
- def set_content_type(type, params = {})
- @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
- end
-
- alias content_type= set_content_type
-
- # Sets the request body to a URL-encoded string derived from argument +params+,
- # and sets request header field <tt>'Content-Type'</tt>
- # to <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The resulting request is suitable for HTTP request +POST+ or +PUT+.
- #
- # Argument +params+ must be suitable for use as argument +enum+ to
- # {Gem::URI.encode_www_form}[https://docs.ruby-lang.org/en/master/Gem::URI.html#method-c-encode_www_form].
- #
- # With only argument +params+ given,
- # sets the body to a URL-encoded string with the default separator <tt>'&'</tt>:
- #
- # req = Gem::Net::HTTP::Post.new('example.com')
- #
- # req.set_form_data(q: 'ruby', lang: 'en')
- # req.body # => "q=ruby&lang=en"
- # req['Content-Type'] # => "application/x-www-form-urlencoded"
- #
- # req.set_form_data([['q', 'ruby'], ['lang', 'en']])
- # req.body # => "q=ruby&lang=en"
- #
- # req.set_form_data(q: ['ruby', 'perl'], lang: 'en')
- # req.body # => "q=ruby&q=perl&lang=en"
- #
- # req.set_form_data([['q', 'ruby'], ['q', 'perl'], ['lang', 'en']])
- # req.body # => "q=ruby&q=perl&lang=en"
- #
- # With string argument +sep+ also given,
- # uses that string as the separator:
- #
- # req.set_form_data({q: 'ruby', lang: 'en'}, '|')
- # req.body # => "q=ruby|lang=en"
- #
- # Gem::Net::HTTPHeader#form_data= is an alias for Gem::Net::HTTPHeader#set_form_data.
- def set_form_data(params, sep = '&')
- query = Gem::URI.encode_www_form(params)
- query.gsub!(/&/, sep) if sep != '&'
- self.body = query
- self.content_type = 'application/x-www-form-urlencoded'
- end
-
- alias form_data= set_form_data
-
- # Stores form data to be used in a +POST+ or +PUT+ request.
- #
- # The form data given in +params+ consists of zero or more fields;
- # each field is:
- #
- # - A scalar value.
- # - A name/value pair.
- # - An IO stream opened for reading.
- #
- # Argument +params+ should be an
- # {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
- # (method <tt>params.map</tt> will be called),
- # and is often an array or hash.
- #
- # First, we set up a request:
- #
- # _uri = uri.dup
- # _uri.path ='/posts'
- # req = Gem::Net::HTTP::Post.new(_uri)
- #
- # <b>Argument +params+ As an Array</b>
- #
- # When +params+ is an array,
- # each of its elements is a subarray that defines a field;
- # the subarray may contain:
- #
- # - One string:
- #
- # req.set_form([['foo'], ['bar'], ['baz']])
- #
- # - Two strings:
- #
- # req.set_form([%w[foo 0], %w[bar 1], %w[baz 2]])
- #
- # - When argument +enctype+ (see below) is given as
- # <tt>'multipart/form-data'</tt>:
- #
- # - A string name and an IO stream opened for reading:
- #
- # require 'stringio'
- # req.set_form([['file', StringIO.new('Ruby is cool.')]])
- #
- # - A string name, an IO stream opened for reading,
- # and an options hash, which may contain these entries:
- #
- # - +:filename+: The name of the file to use.
- # - +:content_type+: The content type of the uploaded file.
- #
- # Example:
- #
- # req.set_form([['file', file, {filename: "other-filename.foo"}]]
- #
- # The various forms may be mixed:
- #
- # req.set_form(['foo', %w[bar 1], ['file', file]])
- #
- # <b>Argument +params+ As a Hash</b>
- #
- # When +params+ is a hash,
- # each of its entries is a name/value pair that defines a field:
- #
- # - The name is a string.
- # - The value may be:
- #
- # - +nil+.
- # - Another string.
- # - An IO stream opened for reading
- # (only when argument +enctype+ -- see below -- is given as
- # <tt>'multipart/form-data'</tt>).
- #
- # Examples:
- #
- # # Nil-valued fields.
- # req.set_form({'foo' => nil, 'bar' => nil, 'baz' => nil})
- #
- # # String-valued fields.
- # req.set_form({'foo' => 0, 'bar' => 1, 'baz' => 2})
- #
- # # IO-valued field.
- # require 'stringio'
- # req.set_form({'file' => StringIO.new('Ruby is cool.')})
- #
- # # Mixture of fields.
- # req.set_form({'foo' => nil, 'bar' => 1, 'file' => file})
- #
- # Optional argument +enctype+ specifies the value to be given
- # to field <tt>'Content-Type'</tt>, and must be one of:
- #
- # - <tt>'application/x-www-form-urlencoded'</tt> (the default).
- # - <tt>'multipart/form-data'</tt>;
- # see {RFC 7578}[https://www.rfc-editor.org/rfc/rfc7578].
- #
- # Optional argument +formopt+ is a hash of options
- # (applicable only when argument +enctype+
- # is <tt>'multipart/form-data'</tt>)
- # that may include the following entries:
- #
- # - +:boundary+: The value is the boundary string for the multipart message.
- # If not given, the boundary is a random string.
- # See {Boundary}[https://www.rfc-editor.org/rfc/rfc7578#section-4.1].
- # - +:charset+: Value is the character set for the form submission.
- # Field names and values of non-file fields should be encoded with this charset.
- #
- def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
- @body_data = params
- @body = nil
- @body_stream = nil
- @form_option = formopt
- case enctype
- when /\Aapplication\/x-www-form-urlencoded\z/i,
- /\Amultipart\/form-data\z/i
- self.content_type = enctype
- else
- raise ArgumentError, "invalid enctype: #{enctype}"
- end
- end
-
- # Sets header <tt>'Authorization'</tt> using the given
- # +account+ and +password+ strings:
- #
- # req.basic_auth('my_account', 'my_password')
- # req['Authorization']
- # # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
- #
- def basic_auth(account, password)
- @header['authorization'] = [basic_encode(account, password)]
- end
-
- # Sets header <tt>'Proxy-Authorization'</tt> using the given
- # +account+ and +password+ strings:
- #
- # req.proxy_basic_auth('my_account', 'my_password')
- # req['Proxy-Authorization']
- # # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
- #
- def proxy_basic_auth(account, password)
- @header['proxy-authorization'] = [basic_encode(account, password)]
- end
-
- def basic_encode(account, password)
- 'Basic ' + ["#{account}:#{password}"].pack('m0')
- end
- private :basic_encode
-
-# Returns whether the HTTP session is to be closed.
- def connection_close?
- token = /(?:\A|,)\s*close\s*(?:\z|,)/i
- @header['connection']&.grep(token) {return true}
- @header['proxy-connection']&.grep(token) {return true}
- false
- end
-
-# Returns whether the HTTP session is to be kept alive.
- def connection_keep_alive?
- token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i
- @header['connection']&.grep(token) {return true}
- @header['proxy-connection']&.grep(token) {return true}
- false
- end
-
-end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb b/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb
deleted file mode 100644
index 137295a883..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-module Gem::Net::HTTP::ProxyDelta #:nodoc: internal use only
- private
-
- def conn_address
- proxy_address()
- end
-
- def conn_port
- proxy_port()
- end
-
- def edit_path(path)
- use_ssl? ? path : "http://#{addr_port()}#{path}"
- end
-end
-
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/request.rb b/lib/rubygems/vendor/net-http/lib/net/http/request.rb
deleted file mode 100644
index 495ec9be54..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/request.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: true
-
-# This class is the base class for \Gem::Net::HTTP request classes.
-# The class should not be used directly;
-# instead you should use its subclasses, listed below.
-#
-# == Creating a Request
-#
-# An request object may be created with either a Gem::URI or a string hostname:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('https://jsonplaceholder.typicode.com/')
-# req = Gem::Net::HTTP::Get.new(uri) # => #<Gem::Net::HTTP::Get GET>
-# req = Gem::Net::HTTP::Get.new(uri.hostname) # => #<Gem::Net::HTTP::Get GET>
-#
-# And with any of the subclasses:
-#
-# req = Gem::Net::HTTP::Head.new(uri) # => #<Gem::Net::HTTP::Head HEAD>
-# req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
-# req = Gem::Net::HTTP::Put.new(uri) # => #<Gem::Net::HTTP::Put PUT>
-# # ...
-#
-# The new instance is suitable for use as the argument to Gem::Net::HTTP#request.
-#
-# == Request Headers
-#
-# A new request object has these header fields by default:
-#
-# req.to_hash
-# # =>
-# {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
-# "accept"=>["*/*"],
-# "user-agent"=>["Ruby"],
-# "host"=>["jsonplaceholder.typicode.com"]}
-#
-# See:
-#
-# - {Request header Accept-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Accept-Encoding]
-# and {Compression and Decompression}[rdoc-ref:Gem::Net::HTTP@Compression+and+Decompression].
-# - {Request header Accept}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#accept-request-header].
-# - {Request header User-Agent}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#user-agent-request-header].
-# - {Request header Host}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#host-request-header].
-#
-# You can add headers or override default headers:
-#
-# # res = Gem::Net::HTTP::Get.new(uri, {'foo' => '0', 'bar' => '1'})
-#
-# This class (and therefore its subclasses) also includes (indirectly)
-# module Gem::Net::HTTPHeader, which gives access to its
-# {methods for setting headers}[rdoc-ref:Gem::Net::HTTPHeader@Setters].
-#
-# == Request Subclasses
-#
-# Subclasses for HTTP requests:
-#
-# - Gem::Net::HTTP::Get
-# - Gem::Net::HTTP::Head
-# - Gem::Net::HTTP::Post
-# - Gem::Net::HTTP::Put
-# - Gem::Net::HTTP::Delete
-# - Gem::Net::HTTP::Options
-# - Gem::Net::HTTP::Trace
-# - Gem::Net::HTTP::Patch
-#
-# Subclasses for WebDAV requests:
-#
-# - Gem::Net::HTTP::Propfind
-# - Gem::Net::HTTP::Proppatch
-# - Gem::Net::HTTP::Mkcol
-# - Gem::Net::HTTP::Copy
-# - Gem::Net::HTTP::Move
-# - Gem::Net::HTTP::Lock
-# - Gem::Net::HTTP::Unlock
-#
-class Gem::Net::HTTPRequest < Gem::Net::HTTPGenericRequest
- # Creates an HTTP request object for +path+.
- #
- # +initheader+ are the default headers to use. Gem::Net::HTTP adds
- # Accept-Encoding to enable compression of the response body unless
- # Accept-Encoding or Range are supplied in +initheader+.
-
- def initialize(path, initheader = nil)
- super self.class::METHOD,
- self.class::REQUEST_HAS_BODY,
- self.class::RESPONSE_HAS_BODY,
- path, initheader
- end
-end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/requests.rb b/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
deleted file mode 100644
index 1a57ddc7c2..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
+++ /dev/null
@@ -1,425 +0,0 @@
-# frozen_string_literal: true
-
-# HTTP/1.1 methods --- RFC2616
-
-# \Class for representing
-# {HTTP method GET}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#GET_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Get.new(uri) # => #<Gem::Net::HTTP::Get GET>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: optional.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
-#
-# Related:
-#
-# - Gem::Net::HTTP.get: sends +GET+ request, returns response body.
-# - Gem::Net::HTTP#get: sends +GET+ request, returns response object.
-#
-class Gem::Net::HTTP::Get < Gem::Net::HTTPRequest
- METHOD = 'GET'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {HTTP method HEAD}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#HEAD_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Head.new(uri) # => #<Gem::Net::HTTP::Head HEAD>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: optional.
-# - Response body: no.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
-#
-# Related:
-#
-# - Gem::Net::HTTP#head: sends +HEAD+ request, returns response object.
-#
-class Gem::Net::HTTP::Head < Gem::Net::HTTPRequest
- METHOD = 'HEAD'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = false
-end
-
-# \Class for representing
-# {HTTP method POST}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#POST_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# uri.path = '/posts'
-# req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
-# req.body = '{"title": "foo","body": "bar","userId": 1}'
-# req.content_type = 'application/json'
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: yes.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: no.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
-#
-# Related:
-#
-# - Gem::Net::HTTP.post: sends +POST+ request, returns response object.
-# - Gem::Net::HTTP#post: sends +POST+ request, returns response object.
-#
-class Gem::Net::HTTP::Post < Gem::Net::HTTPRequest
- METHOD = 'POST'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {HTTP method PUT}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#PUT_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# uri.path = '/posts'
-# req = Gem::Net::HTTP::Put.new(uri) # => #<Gem::Net::HTTP::Put PUT>
-# req.body = '{"title": "foo","body": "bar","userId": 1}'
-# req.content_type = 'application/json'
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: yes.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
-#
-class Gem::Net::HTTP::Put < Gem::Net::HTTPRequest
- METHOD = 'PUT'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {HTTP method DELETE}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#DELETE_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# uri.path = '/posts/1'
-# req = Gem::Net::HTTP::Delete.new(uri) # => #<Gem::Net::HTTP::Delete DELETE>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: optional.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
-#
-# Related:
-#
-# - Gem::Net::HTTP#delete: sends +DELETE+ request, returns response object.
-#
-class Gem::Net::HTTP::Delete < Gem::Net::HTTPRequest
- METHOD = 'DELETE'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {HTTP method OPTIONS}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#OPTIONS_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Options.new(uri) # => #<Gem::Net::HTTP::Options OPTIONS>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: optional.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
-#
-# Related:
-#
-# - Gem::Net::HTTP#options: sends +OPTIONS+ request, returns response object.
-#
-class Gem::Net::HTTP::Options < Gem::Net::HTTPRequest
- METHOD = 'OPTIONS'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {HTTP method TRACE}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#TRACE_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Trace.new(uri) # => #<Gem::Net::HTTP::Trace TRACE>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: no.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
-#
-# Related:
-#
-# - Gem::Net::HTTP#trace: sends +TRACE+ request, returns response object.
-#
-class Gem::Net::HTTP::Trace < Gem::Net::HTTPRequest
- METHOD = 'TRACE'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {HTTP method PATCH}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#PATCH_method]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# uri.path = '/posts'
-# req = Gem::Net::HTTP::Patch.new(uri) # => #<Gem::Net::HTTP::Patch PATCH>
-# req.body = '{"title": "foo","body": "bar","userId": 1}'
-# req.content_type = 'application/json'
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Properties:
-#
-# - Request body: yes.
-# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: no.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
-#
-# Related:
-#
-# - Gem::Net::HTTP#patch: sends +PATCH+ request, returns response object.
-#
-class Gem::Net::HTTP::Patch < Gem::Net::HTTPRequest
- METHOD = 'PATCH'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-#
-# WebDAV methods --- RFC2518
-#
-
-# \Class for representing
-# {WebDAV method PROPFIND}[http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Propfind.new(uri) # => #<Gem::Net::HTTP::Propfind PROPFIND>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#propfind: sends +PROPFIND+ request, returns response object.
-#
-class Gem::Net::HTTP::Propfind < Gem::Net::HTTPRequest
- METHOD = 'PROPFIND'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {WebDAV method PROPPATCH}[http://www.webdav.org/specs/rfc4918.html#METHOD_PROPPATCH]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Proppatch.new(uri) # => #<Gem::Net::HTTP::Proppatch PROPPATCH>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#proppatch: sends +PROPPATCH+ request, returns response object.
-#
-class Gem::Net::HTTP::Proppatch < Gem::Net::HTTPRequest
- METHOD = 'PROPPATCH'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {WebDAV method MKCOL}[http://www.webdav.org/specs/rfc4918.html#METHOD_MKCOL]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Mkcol.new(uri) # => #<Gem::Net::HTTP::Mkcol MKCOL>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#mkcol: sends +MKCOL+ request, returns response object.
-#
-class Gem::Net::HTTP::Mkcol < Gem::Net::HTTPRequest
- METHOD = 'MKCOL'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {WebDAV method COPY}[http://www.webdav.org/specs/rfc4918.html#METHOD_COPY]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Copy.new(uri) # => #<Gem::Net::HTTP::Copy COPY>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#copy: sends +COPY+ request, returns response object.
-#
-class Gem::Net::HTTP::Copy < Gem::Net::HTTPRequest
- METHOD = 'COPY'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {WebDAV method MOVE}[http://www.webdav.org/specs/rfc4918.html#METHOD_MOVE]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Move.new(uri) # => #<Gem::Net::HTTP::Move MOVE>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#move: sends +MOVE+ request, returns response object.
-#
-class Gem::Net::HTTP::Move < Gem::Net::HTTPRequest
- METHOD = 'MOVE'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {WebDAV method LOCK}[http://www.webdav.org/specs/rfc4918.html#METHOD_LOCK]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Lock.new(uri) # => #<Gem::Net::HTTP::Lock LOCK>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#lock: sends +LOCK+ request, returns response object.
-#
-class Gem::Net::HTTP::Lock < Gem::Net::HTTPRequest
- METHOD = 'LOCK'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
-# \Class for representing
-# {WebDAV method UNLOCK}[http://www.webdav.org/specs/rfc4918.html#METHOD_UNLOCK]:
-#
-# require 'rubygems/vendor/net-http/lib/net/http'
-# uri = Gem::URI('http://example.com')
-# hostname = uri.hostname # => "example.com"
-# req = Gem::Net::HTTP::Unlock.new(uri) # => #<Gem::Net::HTTP::Unlock UNLOCK>
-# res = Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end
-#
-# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
-#
-# Related:
-#
-# - Gem::Net::HTTP#unlock: sends +UNLOCK+ request, returns response object.
-#
-class Gem::Net::HTTP::Unlock < Gem::Net::HTTPRequest
- METHOD = 'UNLOCK'
- REQUEST_HAS_BODY = true
- RESPONSE_HAS_BODY = true
-end
-
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/response.rb b/lib/rubygems/vendor/net-http/lib/net/http/response.rb
deleted file mode 100644
index cbbd191d87..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/response.rb
+++ /dev/null
@@ -1,738 +0,0 @@
-# frozen_string_literal: true
-
-# This class is the base class for \Gem::Net::HTTP response classes.
-#
-# == About the Examples
-#
-# :include: doc/net-http/examples.rdoc
-#
-# == Returned Responses
-#
-# \Method Gem::Net::HTTP.get_response returns
-# an instance of one of the subclasses of \Gem::Net::HTTPResponse:
-#
-# Gem::Net::HTTP.get_response(uri)
-# # => #<Gem::Net::HTTPOK 200 OK readbody=true>
-# Gem::Net::HTTP.get_response(hostname, '/nosuch')
-# # => #<Gem::Net::HTTPNotFound 404 Not Found readbody=true>
-#
-# As does method Gem::Net::HTTP#request:
-#
-# req = Gem::Net::HTTP::Get.new(uri)
-# Gem::Net::HTTP.start(hostname) do |http|
-# http.request(req)
-# end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
-#
-# \Class \Gem::Net::HTTPResponse includes module Gem::Net::HTTPHeader,
-# which provides access to response header values via (among others):
-#
-# - \Hash-like method <tt>[]</tt>.
-# - Specific reader methods, such as +content_type+.
-#
-# Examples:
-#
-# res = Gem::Net::HTTP.get_response(uri) # => #<Gem::Net::HTTPOK 200 OK readbody=true>
-# res['Content-Type'] # => "text/html; charset=UTF-8"
-# res.content_type # => "text/html"
-#
-# == Response Subclasses
-#
-# \Class \Gem::Net::HTTPResponse has a subclass for each
-# {HTTP status code}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes].
-# You can look up the response class for a given code:
-#
-# Gem::Net::HTTPResponse::CODE_TO_OBJ['200'] # => Gem::Net::HTTPOK
-# Gem::Net::HTTPResponse::CODE_TO_OBJ['400'] # => Gem::Net::HTTPBadRequest
-# Gem::Net::HTTPResponse::CODE_TO_OBJ['404'] # => Gem::Net::HTTPNotFound
-#
-# And you can retrieve the status code for a response object:
-#
-# Gem::Net::HTTP.get_response(uri).code # => "200"
-# Gem::Net::HTTP.get_response(hostname, '/nosuch').code # => "404"
-#
-# The response subclasses (indentation shows class hierarchy):
-#
-# - Gem::Net::HTTPUnknownResponse (for unhandled \HTTP extensions).
-#
-# - Gem::Net::HTTPInformation:
-#
-# - Gem::Net::HTTPContinue (100)
-# - Gem::Net::HTTPSwitchProtocol (101)
-# - Gem::Net::HTTPProcessing (102)
-# - Gem::Net::HTTPEarlyHints (103)
-#
-# - Gem::Net::HTTPSuccess:
-#
-# - Gem::Net::HTTPOK (200)
-# - Gem::Net::HTTPCreated (201)
-# - Gem::Net::HTTPAccepted (202)
-# - Gem::Net::HTTPNonAuthoritativeInformation (203)
-# - Gem::Net::HTTPNoContent (204)
-# - Gem::Net::HTTPResetContent (205)
-# - Gem::Net::HTTPPartialContent (206)
-# - Gem::Net::HTTPMultiStatus (207)
-# - Gem::Net::HTTPAlreadyReported (208)
-# - Gem::Net::HTTPIMUsed (226)
-#
-# - Gem::Net::HTTPRedirection:
-#
-# - Gem::Net::HTTPMultipleChoices (300)
-# - Gem::Net::HTTPMovedPermanently (301)
-# - Gem::Net::HTTPFound (302)
-# - Gem::Net::HTTPSeeOther (303)
-# - Gem::Net::HTTPNotModified (304)
-# - Gem::Net::HTTPUseProxy (305)
-# - Gem::Net::HTTPTemporaryRedirect (307)
-# - Gem::Net::HTTPPermanentRedirect (308)
-#
-# - Gem::Net::HTTPClientError:
-#
-# - Gem::Net::HTTPBadRequest (400)
-# - Gem::Net::HTTPUnauthorized (401)
-# - Gem::Net::HTTPPaymentRequired (402)
-# - Gem::Net::HTTPForbidden (403)
-# - Gem::Net::HTTPNotFound (404)
-# - Gem::Net::HTTPMethodNotAllowed (405)
-# - Gem::Net::HTTPNotAcceptable (406)
-# - Gem::Net::HTTPProxyAuthenticationRequired (407)
-# - Gem::Net::HTTPRequestTimeOut (408)
-# - Gem::Net::HTTPConflict (409)
-# - Gem::Net::HTTPGone (410)
-# - Gem::Net::HTTPLengthRequired (411)
-# - Gem::Net::HTTPPreconditionFailed (412)
-# - Gem::Net::HTTPRequestEntityTooLarge (413)
-# - Gem::Net::HTTPRequestURITooLong (414)
-# - Gem::Net::HTTPUnsupportedMediaType (415)
-# - Gem::Net::HTTPRequestedRangeNotSatisfiable (416)
-# - Gem::Net::HTTPExpectationFailed (417)
-# - Gem::Net::HTTPMisdirectedRequest (421)
-# - Gem::Net::HTTPUnprocessableEntity (422)
-# - Gem::Net::HTTPLocked (423)
-# - Gem::Net::HTTPFailedDependency (424)
-# - Gem::Net::HTTPUpgradeRequired (426)
-# - Gem::Net::HTTPPreconditionRequired (428)
-# - Gem::Net::HTTPTooManyRequests (429)
-# - Gem::Net::HTTPRequestHeaderFieldsTooLarge (431)
-# - Gem::Net::HTTPUnavailableForLegalReasons (451)
-#
-# - Gem::Net::HTTPServerError:
-#
-# - Gem::Net::HTTPInternalServerError (500)
-# - Gem::Net::HTTPNotImplemented (501)
-# - Gem::Net::HTTPBadGateway (502)
-# - Gem::Net::HTTPServiceUnavailable (503)
-# - Gem::Net::HTTPGatewayTimeOut (504)
-# - Gem::Net::HTTPVersionNotSupported (505)
-# - Gem::Net::HTTPVariantAlsoNegotiates (506)
-# - Gem::Net::HTTPInsufficientStorage (507)
-# - Gem::Net::HTTPLoopDetected (508)
-# - Gem::Net::HTTPNotExtended (510)
-# - Gem::Net::HTTPNetworkAuthenticationRequired (511)
-#
-# There is also the Gem::Net::HTTPBadResponse exception which is raised when
-# there is a protocol error.
-#
-class Gem::Net::HTTPResponse
- class << self
- # true if the response has a body.
- def body_permitted?
- self::HAS_BODY
- end
-
- def exception_type # :nodoc: internal use only
- self::EXCEPTION_TYPE
- end
-
- def read_new(sock) #:nodoc: internal use only
- httpv, code, msg = read_status_line(sock)
- res = response_class(code).new(httpv, code, msg)
- each_response_header(sock) do |k,v|
- res.add_field k, v
- end
- res
- end
-
- private
-
- def read_status_line(sock)
- str = sock.readline
- m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)(?:\s+(.*))?\z/in.match(str) or
- raise Gem::Net::HTTPBadResponse, "wrong status line: #{str.dump}"
- m.captures
- end
-
- def response_class(code)
- CODE_TO_OBJ[code] or
- CODE_CLASS_TO_OBJ[code[0,1]] or
- Gem::Net::HTTPUnknownResponse
- end
-
- def each_response_header(sock)
- key = value = nil
- while true
- line = sock.readuntil("\n", true).sub(/\s+\z/, '')
- break if line.empty?
- if line[0] == ?\s or line[0] == ?\t and value
- value << ' ' unless value.empty?
- value << line.strip
- else
- yield key, value if key
- key, value = line.strip.split(/\s*:\s*/, 2)
- raise Gem::Net::HTTPBadResponse, 'wrong header line format' if value.nil?
- end
- end
- yield key, value if key
- end
- end
-
- # next is to fix bug in RDoc, where the private inside class << self
- # spills out.
- public
-
- include Gem::Net::HTTPHeader
-
- def initialize(httpv, code, msg) #:nodoc: internal use only
- @http_version = httpv
- @code = code
- @message = msg
- initialize_http_header nil
- @body = nil
- @read = false
- @uri = nil
- @decode_content = false
- @body_encoding = false
- @ignore_eof = true
- end
-
- # The HTTP version supported by the server.
- attr_reader :http_version
-
- # The HTTP result code string. For example, '302'. You can also
- # determine the response type by examining which response subclass
- # the response object is an instance of.
- attr_reader :code
-
- # The HTTP result message sent by the server. For example, 'Not Found'.
- attr_reader :message
- alias msg message # :nodoc: obsolete
-
- # The Gem::URI used to fetch this response. The response Gem::URI is only available
- # if a Gem::URI was used to create the request.
- attr_reader :uri
-
- # Set to true automatically when the request did not contain an
- # Accept-Encoding header from the user.
- attr_accessor :decode_content
-
- # Returns the value set by body_encoding=, or +false+ if none;
- # see #body_encoding=.
- attr_reader :body_encoding
-
- # Sets the encoding that should be used when reading the body:
- #
- # - If the given value is an Encoding object, that encoding will be used.
- # - Otherwise if the value is a string, the value of
- # {Encoding#find(value)}[https://docs.ruby-lang.org/en/master/Encoding.html#method-c-find]
- # will be used.
- # - Otherwise an encoding will be deduced from the body itself.
- #
- # Examples:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # req = Gem::Net::HTTP::Get.new('/')
- #
- # http.request(req) do |res|
- # p res.body.encoding # => #<Encoding:ASCII-8BIT>
- # end
- #
- # http.request(req) do |res|
- # res.body_encoding = "UTF-8"
- # p res.body.encoding # => #<Encoding:UTF-8>
- # end
- #
- def body_encoding=(value)
- value = Encoding.find(value) if value.is_a?(String)
- @body_encoding = value
- end
-
- # Whether to ignore EOF when reading bodies with a specified Content-Length
- # header.
- attr_accessor :ignore_eof
-
- def inspect
- "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
- end
-
- #
- # response <-> exception relationship
- #
-
- def code_type #:nodoc:
- self.class
- end
-
- def error! #:nodoc:
- message = @code
- message = "#{message} #{@message.dump}" if @message
- raise error_type().new(message, self)
- end
-
- def error_type #:nodoc:
- self.class::EXCEPTION_TYPE
- end
-
- # Raises an HTTP error if the response is not 2xx (success).
- def value
- error! unless self.kind_of?(Gem::Net::HTTPSuccess)
- end
-
- def uri= uri # :nodoc:
- @uri = uri.dup if uri
- end
-
- #
- # header (for backward compatibility only; DO NOT USE)
- #
-
- def response #:nodoc:
- warn "Gem::Net::HTTPResponse#response is obsolete", uplevel: 1 if $VERBOSE
- self
- end
-
- def header #:nodoc:
- warn "Gem::Net::HTTPResponse#header is obsolete", uplevel: 1 if $VERBOSE
- self
- end
-
- def read_header #:nodoc:
- warn "Gem::Net::HTTPResponse#read_header is obsolete", uplevel: 1 if $VERBOSE
- self
- end
-
- #
- # body
- #
-
- def reading_body(sock, reqmethodallowbody) #:nodoc: internal use only
- @socket = sock
- @body_exist = reqmethodallowbody && self.class.body_permitted?
- begin
- yield
- self.body # ensure to read body
- ensure
- @socket = nil
- end
- end
-
- # Gets the entity body returned by the remote HTTP server.
- #
- # If a block is given, the body is passed to the block, and
- # the body is provided in fragments, as it is read in from the socket.
- #
- # If +dest+ argument is given, response is read into that variable,
- # with <code>dest#<<</code> method (it could be String or IO, or any
- # other object responding to <code><<</code>).
- #
- # Calling this method a second or subsequent time for the same
- # HTTPResponse object will return the value already read.
- #
- # http.request_get('/index.html') {|res|
- # puts res.read_body
- # }
- #
- # http.request_get('/index.html') {|res|
- # p res.read_body.object_id # 538149362
- # p res.read_body.object_id # 538149362
- # }
- #
- # # using iterator
- # http.request_get('/index.html') {|res|
- # res.read_body do |segment|
- # print segment
- # end
- # }
- #
- def read_body(dest = nil, &block)
- if @read
- raise IOError, "#{self.class}\#read_body called twice" if dest or block
- return @body
- end
- to = procdest(dest, block)
- stream_check
- if @body_exist
- read_body_0 to
- @body = to
- else
- @body = nil
- end
- @read = true
- return if @body.nil?
-
- case enc = @body_encoding
- when Encoding, false, nil
- # Encoding: force given encoding
- # false/nil: do not force encoding
- else
- # other value: detect encoding from body
- enc = detect_encoding(@body)
- end
-
- @body.force_encoding(enc) if enc
-
- @body
- end
-
- # Returns the string response body;
- # note that repeated calls for the unmodified body return a cached string:
- #
- # path = '/todos/1'
- # Gem::Net::HTTP.start(hostname) do |http|
- # res = http.get(path)
- # p res.body
- # p http.head(path).body # No body.
- # end
- #
- # Output:
- #
- # "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n}"
- # nil
- #
- def body
- read_body()
- end
-
- # Sets the body of the response to the given value.
- def body=(value)
- @body = value
- end
-
- alias entity body #:nodoc: obsolete
-
- private
-
- # :nodoc:
- def detect_encoding(str, encoding=nil)
- if encoding
- elsif encoding = type_params['charset']
- elsif encoding = check_bom(str)
- else
- encoding = case content_type&.downcase
- when %r{text/x(?:ht)?ml|application/(?:[^+]+\+)?xml}
- /\A<xml[ \t\r\n]+
- version[ \t\r\n]*=[ \t\r\n]*(?:"[0-9.]+"|'[0-9.]*')[ \t\r\n]+
- encoding[ \t\r\n]*=[ \t\r\n]*
- (?:"([A-Za-z][\-A-Za-z0-9._]*)"|'([A-Za-z][\-A-Za-z0-9._]*)')/x =~ str
- encoding = $1 || $2 || Encoding::UTF_8
- when %r{text/html.*}
- sniff_encoding(str)
- end
- end
- return encoding
- end
-
- # :nodoc:
- def sniff_encoding(str, encoding=nil)
- # the encoding sniffing algorithm
- # http://www.w3.org/TR/html5/parsing.html#determining-the-character-encoding
- if enc = scanning_meta(str)
- enc
- # 6. last visited page or something
- # 7. frequency
- elsif str.ascii_only?
- Encoding::US_ASCII
- elsif str.dup.force_encoding(Encoding::UTF_8).valid_encoding?
- Encoding::UTF_8
- end
- # 8. implementation-defined or user-specified
- end
-
- # :nodoc:
- def check_bom(str)
- case str.byteslice(0, 2)
- when "\xFE\xFF"
- return Encoding::UTF_16BE
- when "\xFF\xFE"
- return Encoding::UTF_16LE
- end
- if "\xEF\xBB\xBF" == str.byteslice(0, 3)
- return Encoding::UTF_8
- end
- nil
- end
-
- # :nodoc:
- def scanning_meta(str)
- require 'strscan'
- ss = StringScanner.new(str)
- if ss.scan_until(/<meta[\t\n\f\r ]*/)
- attrs = {} # attribute_list
- got_pragma = false
- need_pragma = nil
- charset = nil
-
- # step: Attributes
- while attr = get_attribute(ss)
- name, value = *attr
- next if attrs[name]
- attrs[name] = true
- case name
- when 'http-equiv'
- got_pragma = true if value == 'content-type'
- when 'content'
- encoding = extracting_encodings_from_meta_elements(value)
- unless charset
- charset = encoding
- end
- need_pragma = true
- when 'charset'
- need_pragma = false
- charset = value
- end
- end
-
- # step: Processing
- return if need_pragma.nil?
- return if need_pragma && !got_pragma
-
- charset = Encoding.find(charset) rescue nil
- return unless charset
- charset = Encoding::UTF_8 if charset == Encoding::UTF_16
- return charset # tentative
- end
- nil
- end
-
- def get_attribute(ss)
- ss.scan(/[\t\n\f\r \/]*/)
- if ss.peek(1) == '>'
- ss.getch
- return nil
- end
- name = ss.scan(/[^=\t\n\f\r \/>]*/)
- name.downcase!
- raise if name.empty?
- ss.skip(/[\t\n\f\r ]*/)
- if ss.getch != '='
- value = ''
- return [name, value]
- end
- ss.skip(/[\t\n\f\r ]*/)
- case ss.peek(1)
- when '"'
- ss.getch
- value = ss.scan(/[^"]+/)
- value.downcase!
- ss.getch
- when "'"
- ss.getch
- value = ss.scan(/[^']+/)
- value.downcase!
- ss.getch
- when '>'
- value = ''
- else
- value = ss.scan(/[^\t\n\f\r >]+/)
- value.downcase!
- end
- [name, value]
- end
-
- def extracting_encodings_from_meta_elements(value)
- # http://dev.w3.org/html5/spec/fetching-resources.html#algorithm-for-extracting-an-encoding-from-a-meta-element
- if /charset[\t\n\f\r ]*=(?:"([^"]*)"|'([^']*)'|["']|\z|([^\t\n\f\r ;]+))/i =~ value
- return $1 || $2 || $3
- end
- return nil
- end
-
- ##
- # Checks for a supported Content-Encoding header and yields an Inflate
- # wrapper for this response's socket when zlib is present. If the
- # Content-Encoding is not supported or zlib is missing, the plain socket is
- # yielded.
- #
- # If a Content-Range header is present, a plain socket is yielded as the
- # bytes in the range may not be a complete deflate block.
-
- def inflater # :nodoc:
- return yield @socket unless Gem::Net::HTTP::HAVE_ZLIB
- return yield @socket unless @decode_content
- return yield @socket if self['content-range']
-
- v = self['content-encoding']
- case v&.downcase
- when 'deflate', 'gzip', 'x-gzip' then
- self.delete 'content-encoding'
-
- inflate_body_io = Inflater.new(@socket)
-
- begin
- yield inflate_body_io
- success = true
- ensure
- begin
- inflate_body_io.finish
- if self['content-length']
- self['content-length'] = inflate_body_io.bytes_inflated.to_s
- end
- rescue => err
- # Ignore #finish's error if there is an exception from yield
- raise err if success
- end
- end
- when 'none', 'identity' then
- self.delete 'content-encoding'
-
- yield @socket
- else
- yield @socket
- end
- end
-
- def read_body_0(dest)
- inflater do |inflate_body_io|
- if chunked?
- read_chunked dest, inflate_body_io
- return
- end
-
- @socket = inflate_body_io
-
- clen = content_length()
- if clen
- @socket.read clen, dest, @ignore_eof
- return
- end
- clen = range_length()
- if clen
- @socket.read clen, dest
- return
- end
- @socket.read_all dest
- end
- end
-
- ##
- # read_chunked reads from +@socket+ for chunk-size, chunk-extension, CRLF,
- # etc. and +chunk_data_io+ for chunk-data which may be deflate or gzip
- # encoded.
- #
- # See RFC 2616 section 3.6.1 for definitions
-
- def read_chunked(dest, chunk_data_io) # :nodoc:
- total = 0
- while true
- line = @socket.readline
- hexlen = line.slice(/[0-9a-fA-F]+/) or
- raise Gem::Net::HTTPBadResponse, "wrong chunk size line: #{line}"
- len = hexlen.hex
- break if len == 0
- begin
- chunk_data_io.read len, dest
- ensure
- total += len
- @socket.read 2 # \r\n
- end
- end
- until @socket.readline.empty?
- # none
- end
- end
-
- def stream_check
- raise IOError, 'attempt to read body out of block' if @socket.nil? || @socket.closed?
- end
-
- def procdest(dest, block)
- raise ArgumentError, 'both arg and block given for HTTP method' if
- dest and block
- if block
- Gem::Net::ReadAdapter.new(block)
- else
- dest || +''
- end
- end
-
- ##
- # Inflater is a wrapper around Gem::Net::BufferedIO that transparently inflates
- # zlib and gzip streams.
-
- class Inflater # :nodoc:
-
- ##
- # Creates a new Inflater wrapping +socket+
-
- def initialize socket
- @socket = socket
- # zlib with automatic gzip detection
- @inflate = Zlib::Inflate.new(32 + Zlib::MAX_WBITS)
- end
-
- ##
- # Finishes the inflate stream.
-
- def finish
- return if @inflate.total_in == 0
- @inflate.finish
- end
-
- ##
- # The number of bytes inflated, used to update the Content-Length of
- # the response.
-
- def bytes_inflated
- @inflate.total_out
- end
-
- ##
- # Returns a Gem::Net::ReadAdapter that inflates each read chunk into +dest+.
- #
- # This allows a large response body to be inflated without storing the
- # entire body in memory.
-
- def inflate_adapter(dest)
- if dest.respond_to?(:set_encoding)
- dest.set_encoding(Encoding::ASCII_8BIT)
- elsif dest.respond_to?(:force_encoding)
- dest.force_encoding(Encoding::ASCII_8BIT)
- end
- block = proc do |compressed_chunk|
- @inflate.inflate(compressed_chunk) do |chunk|
- compressed_chunk.clear
- dest << chunk
- end
- end
-
- Gem::Net::ReadAdapter.new(block)
- end
-
- ##
- # Reads +clen+ bytes from the socket, inflates them, then writes them to
- # +dest+. +ignore_eof+ is passed down to Gem::Net::BufferedIO#read
- #
- # Unlike Gem::Net::BufferedIO#read, this method returns more than +clen+ bytes.
- # At this time there is no way for a user of Gem::Net::HTTPResponse to read a
- # specific number of bytes from the HTTP response body, so this internal
- # API does not return the same number of bytes as were requested.
- #
- # See https://bugs.ruby-lang.org/issues/6492 for further discussion.
-
- def read clen, dest, ignore_eof = false
- temp_dest = inflate_adapter(dest)
-
- @socket.read clen, temp_dest, ignore_eof
- end
-
- ##
- # Reads the rest of the socket, inflates it, then writes it to +dest+.
-
- def read_all dest
- temp_dest = inflate_adapter(dest)
-
- @socket.read_all temp_dest
- end
-
- end
-
-end
-
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/responses.rb b/lib/rubygems/vendor/net-http/lib/net/http/responses.rb
deleted file mode 100644
index 0f26ae6c26..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/responses.rb
+++ /dev/null
@@ -1,1174 +0,0 @@
-# frozen_string_literal: true
-#--
-# https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
-
-module Gem::Net
-
- class HTTPUnknownResponse < HTTPResponse
- HAS_BODY = true
- EXCEPTION_TYPE = HTTPError #
- end
-
- # Parent class for informational (1xx) HTTP response classes.
- #
- # An informational response indicates that the request was received and understood.
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.1xx].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#1xx_informational_response].
- #
- class HTTPInformation < HTTPResponse
- HAS_BODY = false
- EXCEPTION_TYPE = HTTPError #
- end
-
- # Parent class for success (2xx) HTTP response classes.
- #
- # A success response indicates the action requested by the client
- # was received, understood, and accepted.
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.2xx].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_success].
- #
- class HTTPSuccess < HTTPResponse
- HAS_BODY = true
- EXCEPTION_TYPE = HTTPError #
- end
-
- # Parent class for redirection (3xx) HTTP response classes.
- #
- # A redirection response indicates the client must take additional action
- # to complete the request.
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.3xx].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_redirection].
- #
- class HTTPRedirection < HTTPResponse
- HAS_BODY = true
- EXCEPTION_TYPE = HTTPRetriableError #
- end
-
- # Parent class for client error (4xx) HTTP response classes.
- #
- # A client error response indicates that the client may have caused an error.
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.4xx].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors].
- #
- class HTTPClientError < HTTPResponse
- HAS_BODY = true
- EXCEPTION_TYPE = HTTPClientException #
- end
-
- # Parent class for server error (5xx) HTTP response classes.
- #
- # A server error response indicates that the server failed to fulfill a request.
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.5xx].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_server_errors].
- #
- class HTTPServerError < HTTPResponse
- HAS_BODY = true
- EXCEPTION_TYPE = HTTPFatalError #
- end
-
- # Response class for +Continue+ responses (status code 100).
- #
- # A +Continue+ response indicates that the server has received the request headers.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-100-continue].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#100].
- #
- class HTTPContinue < HTTPInformation
- HAS_BODY = false
- end
-
- # Response class for <tt>Switching Protocol</tt> responses (status code 101).
- #
- # The <tt>Switching Protocol<tt> response indicates that the server has received
- # a request to switch protocols, and has agreed to do so.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-101-switching-protocols].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#101].
- #
- class HTTPSwitchProtocol < HTTPInformation
- HAS_BODY = false
- end
-
- # Response class for +Processing+ responses (status code 102).
- #
- # The +Processing+ response indicates that the server has received
- # and is processing the request, but no response is available yet.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 2518}[https://www.rfc-editor.org/rfc/rfc2518#section-10.1].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#102].
- #
- class HTTPProcessing < HTTPInformation
- HAS_BODY = false
- end
-
- # Response class for <tt>Early Hints</tt> responses (status code 103).
- #
- # The <tt>Early Hints</tt> indicates that the server has received
- # and is processing the request, and contains certain headers;
- # the final response is not available yet.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103].
- # - {RFC 8297}[https://www.rfc-editor.org/rfc/rfc8297.html#section-2].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#103].
- #
- class HTTPEarlyHints < HTTPInformation
- HAS_BODY = false
- end
-
- # Response class for +OK+ responses (status code 200).
- #
- # The +OK+ response indicates that the server has received
- # a request and has responded successfully.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-200-ok].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#200].
- #
- class HTTPOK < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for +Created+ responses (status code 201).
- #
- # The +Created+ response indicates that the server has received
- # and has fulfilled a request to create a new resource.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-201-created].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#201].
- #
- class HTTPCreated < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for +Accepted+ responses (status code 202).
- #
- # The +Accepted+ response indicates that the server has received
- # and is processing a request, but the processing has not yet been completed.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-202-accepted].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#202].
- #
- class HTTPAccepted < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for <tt>Non-Authoritative Information</tt> responses (status code 203).
- #
- # The <tt>Non-Authoritative Information</tt> response indicates that the server
- # is a transforming proxy (such as a Web accelerator)
- # that received a 200 OK response from its origin,
- # and is returning a modified version of the origin's response.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/203].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-203-non-authoritative-infor].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#203].
- #
- class HTTPNonAuthoritativeInformation < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for <tt>No Content</tt> responses (status code 204).
- #
- # The <tt>No Content</tt> response indicates that the server
- # successfully processed the request, and is not returning any content.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-204-no-content].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#204].
- #
- class HTTPNoContent < HTTPSuccess
- HAS_BODY = false
- end
-
- # Response class for <tt>Reset Content</tt> responses (status code 205).
- #
- # The <tt>Reset Content</tt> response indicates that the server
- # successfully processed the request,
- # asks that the client reset its document view, and is not returning any content.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/205].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-205-reset-content].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#205].
- #
- class HTTPResetContent < HTTPSuccess
- HAS_BODY = false
- end
-
- # Response class for <tt>Partial Content</tt> responses (status code 206).
- #
- # The <tt>Partial Content</tt> response indicates that the server is delivering
- # only part of the resource (byte serving)
- # due to a Range header in the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-206-partial-content].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#206].
- #
- class HTTPPartialContent < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for <tt>Multi-Status (WebDAV)</tt> responses (status code 207).
- #
- # The <tt>Multi-Status (WebDAV)</tt> response indicates that the server
- # has received the request,
- # and that the message body can contain a number of separate response codes.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 4818}[https://www.rfc-editor.org/rfc/rfc4918#section-11.1].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#207].
- #
- class HTTPMultiStatus < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for <tt>Already Reported (WebDAV)</tt> responses (status code 208).
- #
- # The <tt>Already Reported (WebDAV)</tt> response indicates that the server
- # has received the request,
- # and that the members of a DAV binding have already been enumerated
- # in a preceding part of the (multi-status) response,
- # and are not being included again.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 5842}[https://www.rfc-editor.org/rfc/rfc5842.html#section-7.1].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#208].
- #
- class HTTPAlreadyReported < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for <tt>IM Used</tt> responses (status code 226).
- #
- # The <tt>IM Used</tt> response indicates that the server has fulfilled a request
- # for the resource, and the response is a representation of the result
- # of one or more instance-manipulations applied to the current instance.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 3229}[https://www.rfc-editor.org/rfc/rfc3229.html#section-10.4.1].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#226].
- #
- class HTTPIMUsed < HTTPSuccess
- HAS_BODY = true
- end
-
- # Response class for <tt>Multiple Choices</tt> responses (status code 300).
- #
- # The <tt>Multiple Choices</tt> response indicates that the server
- # offers multiple options for the resource from which the client may choose.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/300].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-300-multiple-choices].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#300].
- #
- class HTTPMultipleChoices < HTTPRedirection
- HAS_BODY = true
- end
- HTTPMultipleChoice = HTTPMultipleChoices
-
- # Response class for <tt>Moved Permanently</tt> responses (status code 301).
- #
- # The <tt>Moved Permanently</tt> response indicates that links or records
- # returning this response should be updated to use the given URL.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-301-moved-permanently].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#301].
- #
- class HTTPMovedPermanently < HTTPRedirection
- HAS_BODY = true
- end
-
- # Response class for <tt>Found</tt> responses (status code 302).
- #
- # The <tt>Found</tt> response indicates that the client
- # should look at (browse to) another URL.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-302-found].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#302].
- #
- class HTTPFound < HTTPRedirection
- HAS_BODY = true
- end
- HTTPMovedTemporarily = HTTPFound
-
- # Response class for <tt>See Other</tt> responses (status code 303).
- #
- # The response to the request can be found under another Gem::URI using the GET method.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-303-see-other].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#303].
- #
- class HTTPSeeOther < HTTPRedirection
- HAS_BODY = true
- end
-
- # Response class for <tt>Not Modified</tt> responses (status code 304).
- #
- # Indicates that the resource has not been modified since the version
- # specified by the request headers.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-304-not-modified].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#304].
- #
- class HTTPNotModified < HTTPRedirection
- HAS_BODY = false
- end
-
- # Response class for <tt>Use Proxy</tt> responses (status code 305).
- #
- # The requested resource is available only through a proxy,
- # whose address is provided in the response.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-305-use-proxy].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#305].
- #
- class HTTPUseProxy < HTTPRedirection
- HAS_BODY = false
- end
-
- # Response class for <tt>Temporary Redirect</tt> responses (status code 307).
- #
- # The request should be repeated with another Gem::URI;
- # however, future requests should still use the original Gem::URI.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-307-temporary-redirect].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#307].
- #
- class HTTPTemporaryRedirect < HTTPRedirection
- HAS_BODY = true
- end
-
- # Response class for <tt>Permanent Redirect</tt> responses (status code 308).
- #
- # This and all future requests should be directed to the given Gem::URI.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-308-permanent-redirect].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#308].
- #
- class HTTPPermanentRedirect < HTTPRedirection
- HAS_BODY = true
- end
-
- # Response class for <tt>Bad Request</tt> responses (status code 400).
- #
- # The server cannot or will not process the request due to an apparent client error.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-400-bad-request].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#400].
- #
- class HTTPBadRequest < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Unauthorized</tt> responses (status code 401).
- #
- # Authentication is required, but either was not provided or failed.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-401-unauthorized].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#401].
- #
- class HTTPUnauthorized < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Payment Required</tt> responses (status code 402).
- #
- # Reserved for future use.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/402].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-402-payment-required].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#402].
- #
- class HTTPPaymentRequired < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Forbidden</tt> responses (status code 403).
- #
- # The request contained valid data and was understood by the server,
- # but the server is refusing action.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-403-forbidden].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#403].
- #
- class HTTPForbidden < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Not Found</tt> responses (status code 404).
- #
- # The requested resource could not be found but may be available in the future.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-404-not-found].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#404].
- #
- class HTTPNotFound < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Method Not Allowed</tt> responses (status code 405).
- #
- # The request method is not supported for the requested resource.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-405-method-not-allowed].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#405].
- #
- class HTTPMethodNotAllowed < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Not Acceptable</tt> responses (status code 406).
- #
- # The requested resource is capable of generating only content
- # that not acceptable according to the Accept headers sent in the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-406-not-acceptable].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#406].
- #
- class HTTPNotAcceptable < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Proxy Authentication Required</tt> responses (status code 407).
- #
- # The client must first authenticate itself with the proxy.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-407-proxy-authentication-re].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#407].
- #
- class HTTPProxyAuthenticationRequired < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Request Gem::Timeout</tt> responses (status code 408).
- #
- # The server timed out waiting for the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-408-request-timeout].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#408].
- #
- class HTTPRequestTimeout < HTTPClientError
- HAS_BODY = true
- end
- HTTPRequestTimeOut = HTTPRequestTimeout
-
- # Response class for <tt>Conflict</tt> responses (status code 409).
- #
- # The request could not be processed because of conflict in the current state of the resource.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-409-conflict].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#409].
- #
- class HTTPConflict < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Gone</tt> responses (status code 410).
- #
- # The resource requested was previously in use but is no longer available
- # and will not be available again.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/410].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-410-gone].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#410].
- #
- class HTTPGone < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Length Required</tt> responses (status code 411).
- #
- # The request did not specify the length of its content,
- # which is required by the requested resource.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/411].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-411-length-required].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#411].
- #
- class HTTPLengthRequired < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Precondition Failed</tt> responses (status code 412).
- #
- # The server does not meet one of the preconditions
- # specified in the request headers.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-412-precondition-failed].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#412].
- #
- class HTTPPreconditionFailed < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Payload Too Large</tt> responses (status code 413).
- #
- # The request is larger than the server is willing or able to process.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-413-content-too-large].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#413].
- #
- class HTTPPayloadTooLarge < HTTPClientError
- HAS_BODY = true
- end
- HTTPRequestEntityTooLarge = HTTPPayloadTooLarge
-
- # Response class for <tt>Gem::URI Too Long</tt> responses (status code 414).
- #
- # The Gem::URI provided was too long for the server to process.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-414-uri-too-long].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#414].
- #
- class HTTPURITooLong < HTTPClientError
- HAS_BODY = true
- end
- HTTPRequestURITooLong = HTTPURITooLong
- HTTPRequestURITooLarge = HTTPRequestURITooLong
-
- # Response class for <tt>Unsupported Media Type</tt> responses (status code 415).
- #
- # The request entity has a media type which the server or resource does not support.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#415].
- #
- class HTTPUnsupportedMediaType < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Range Not Satisfiable</tt> responses (status code 416).
- #
- # The request entity has a media type which the server or resource does not support.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-416-range-not-satisfiable].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#416].
- #
- class HTTPRangeNotSatisfiable < HTTPClientError
- HAS_BODY = true
- end
- HTTPRequestedRangeNotSatisfiable = HTTPRangeNotSatisfiable
-
- # Response class for <tt>Expectation Failed</tt> responses (status code 417).
- #
- # The server cannot meet the requirements of the Expect request-header field.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/417].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-417-expectation-failed].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#417].
- #
- class HTTPExpectationFailed < HTTPClientError
- HAS_BODY = true
- end
-
- # 418 I'm a teapot - RFC 2324; a joke RFC
- # See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#418.
-
- # 420 Enhance Your Calm - Twitter
-
- # Response class for <tt>Misdirected Request</tt> responses (status code 421).
- #
- # The request was directed at a server that is not able to produce a response.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-421-misdirected-request].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#421].
- #
- class HTTPMisdirectedRequest < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Unprocessable Entity</tt> responses (status code 422).
- #
- # The request was well-formed but had semantic errors.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-422-unprocessable-content].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#422].
- #
- class HTTPUnprocessableEntity < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Locked (WebDAV)</tt> responses (status code 423).
- #
- # The requested resource is locked.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 4918}[https://www.rfc-editor.org/rfc/rfc4918#section-11.3].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#423].
- #
- class HTTPLocked < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Failed Dependency (WebDAV)</tt> responses (status code 424).
- #
- # The request failed because it depended on another request and that request failed.
- # See {424 Failed Dependency (WebDAV)}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#424].
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {RFC 4918}[https://www.rfc-editor.org/rfc/rfc4918#section-11.4].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#424].
- #
- class HTTPFailedDependency < HTTPClientError
- HAS_BODY = true
- end
-
- # 425 Too Early
- # https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#425.
-
- # Response class for <tt>Upgrade Required</tt> responses (status code 426).
- #
- # The client should switch to the protocol given in the Upgrade header field.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/426].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-426-upgrade-required].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#426].
- #
- class HTTPUpgradeRequired < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Precondition Required</tt> responses (status code 428).
- #
- # The origin server requires the request to be conditional.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428].
- # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-3].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#428].
- #
- class HTTPPreconditionRequired < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Too Many Requests</tt> responses (status code 429).
- #
- # The user has sent too many requests in a given amount of time.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429].
- # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-4].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#429].
- #
- class HTTPTooManyRequests < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Request Header Fields Too Large</tt> responses (status code 431).
- #
- # An individual header field is too large,
- # or all the header fields collectively, are too large.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431].
- # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-5].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#431].
- #
- class HTTPRequestHeaderFieldsTooLarge < HTTPClientError
- HAS_BODY = true
- end
-
- # Response class for <tt>Unavailable For Legal Reasons</tt> responses (status code 451).
- #
- # A server operator has received a legal demand to deny access to a resource or to a set of resources
- # that includes the requested resource.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451].
- # - {RFC 7725}[https://www.rfc-editor.org/rfc/rfc7725.html#section-3].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#451].
- #
- class HTTPUnavailableForLegalReasons < HTTPClientError
- HAS_BODY = true
- end
- # 444 No Response - Nginx
- # 449 Retry With - Microsoft
- # 450 Blocked by Windows Parental Controls - Microsoft
- # 499 Client Closed Request - Nginx
-
- # Response class for <tt>Internal Server Error</tt> responses (status code 500).
- #
- # An unexpected condition was encountered and no more specific message is suitable.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-500-internal-server-error].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#500].
- #
- class HTTPInternalServerError < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Not Implemented</tt> responses (status code 501).
- #
- # The server either does not recognize the request method,
- # or it lacks the ability to fulfil the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-501-not-implemented].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#501].
- #
- class HTTPNotImplemented < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Bad Gateway</tt> responses (status code 502).
- #
- # The server was acting as a gateway or proxy
- # and received an invalid response from the upstream server.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-502-bad-gateway].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#502].
- #
- class HTTPBadGateway < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Service Unavailable</tt> responses (status code 503).
- #
- # The server cannot handle the request
- # (because it is overloaded or down for maintenance).
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-503-service-unavailable].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#503].
- #
- class HTTPServiceUnavailable < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Gateway Gem::Timeout</tt> responses (status code 504).
- #
- # The server was acting as a gateway or proxy
- # and did not receive a timely response from the upstream server.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-504-gateway-timeout].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#504].
- #
- class HTTPGatewayTimeout < HTTPServerError
- HAS_BODY = true
- end
- HTTPGatewayTimeOut = HTTPGatewayTimeout
-
- # Response class for <tt>HTTP Version Not Supported</tt> responses (status code 505).
- #
- # The server does not support the HTTP version used in the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/505].
- # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-505-http-version-not-suppor].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#505].
- #
- class HTTPVersionNotSupported < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Variant Also Negotiates</tt> responses (status code 506).
- #
- # Transparent content negotiation for the request results in a circular reference.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/506].
- # - {RFC 2295}[https://www.rfc-editor.org/rfc/rfc2295#section-8.1].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#506].
- #
- class HTTPVariantAlsoNegotiates < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Insufficient Storage (WebDAV)</tt> responses (status code 507).
- #
- # The server is unable to store the representation needed to complete the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/507].
- # - {RFC 4918}[https://www.rfc-editor.org/rfc/rfc4918#section-11.5].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#507].
- #
- class HTTPInsufficientStorage < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Loop Detected (WebDAV)</tt> responses (status code 508).
- #
- # The server detected an infinite loop while processing the request.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508].
- # - {RFC 5942}[https://www.rfc-editor.org/rfc/rfc5842.html#section-7.2].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#508].
- #
- class HTTPLoopDetected < HTTPServerError
- HAS_BODY = true
- end
- # 509 Bandwidth Limit Exceeded - Apache bw/limited extension
-
- # Response class for <tt>Not Extended</tt> responses (status code 510).
- #
- # Further extensions to the request are required for the server to fulfill it.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/510].
- # - {RFC 2774}[https://www.rfc-editor.org/rfc/rfc2774.html#section-7].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#510].
- #
- class HTTPNotExtended < HTTPServerError
- HAS_BODY = true
- end
-
- # Response class for <tt>Network Authentication Required</tt> responses (status code 511).
- #
- # The client needs to authenticate to gain network access.
- #
- # :include: doc/net-http/included_getters.rdoc
- #
- # References:
- #
- # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/511].
- # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-6].
- # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#511].
- #
- class HTTPNetworkAuthenticationRequired < HTTPServerError
- HAS_BODY = true
- end
-
-end
-
-class Gem::Net::HTTPResponse
- CODE_CLASS_TO_OBJ = {
- '1' => Gem::Net::HTTPInformation,
- '2' => Gem::Net::HTTPSuccess,
- '3' => Gem::Net::HTTPRedirection,
- '4' => Gem::Net::HTTPClientError,
- '5' => Gem::Net::HTTPServerError
- }
- CODE_TO_OBJ = {
- '100' => Gem::Net::HTTPContinue,
- '101' => Gem::Net::HTTPSwitchProtocol,
- '102' => Gem::Net::HTTPProcessing,
- '103' => Gem::Net::HTTPEarlyHints,
-
- '200' => Gem::Net::HTTPOK,
- '201' => Gem::Net::HTTPCreated,
- '202' => Gem::Net::HTTPAccepted,
- '203' => Gem::Net::HTTPNonAuthoritativeInformation,
- '204' => Gem::Net::HTTPNoContent,
- '205' => Gem::Net::HTTPResetContent,
- '206' => Gem::Net::HTTPPartialContent,
- '207' => Gem::Net::HTTPMultiStatus,
- '208' => Gem::Net::HTTPAlreadyReported,
- '226' => Gem::Net::HTTPIMUsed,
-
- '300' => Gem::Net::HTTPMultipleChoices,
- '301' => Gem::Net::HTTPMovedPermanently,
- '302' => Gem::Net::HTTPFound,
- '303' => Gem::Net::HTTPSeeOther,
- '304' => Gem::Net::HTTPNotModified,
- '305' => Gem::Net::HTTPUseProxy,
- '307' => Gem::Net::HTTPTemporaryRedirect,
- '308' => Gem::Net::HTTPPermanentRedirect,
-
- '400' => Gem::Net::HTTPBadRequest,
- '401' => Gem::Net::HTTPUnauthorized,
- '402' => Gem::Net::HTTPPaymentRequired,
- '403' => Gem::Net::HTTPForbidden,
- '404' => Gem::Net::HTTPNotFound,
- '405' => Gem::Net::HTTPMethodNotAllowed,
- '406' => Gem::Net::HTTPNotAcceptable,
- '407' => Gem::Net::HTTPProxyAuthenticationRequired,
- '408' => Gem::Net::HTTPRequestTimeout,
- '409' => Gem::Net::HTTPConflict,
- '410' => Gem::Net::HTTPGone,
- '411' => Gem::Net::HTTPLengthRequired,
- '412' => Gem::Net::HTTPPreconditionFailed,
- '413' => Gem::Net::HTTPPayloadTooLarge,
- '414' => Gem::Net::HTTPURITooLong,
- '415' => Gem::Net::HTTPUnsupportedMediaType,
- '416' => Gem::Net::HTTPRangeNotSatisfiable,
- '417' => Gem::Net::HTTPExpectationFailed,
- '421' => Gem::Net::HTTPMisdirectedRequest,
- '422' => Gem::Net::HTTPUnprocessableEntity,
- '423' => Gem::Net::HTTPLocked,
- '424' => Gem::Net::HTTPFailedDependency,
- '426' => Gem::Net::HTTPUpgradeRequired,
- '428' => Gem::Net::HTTPPreconditionRequired,
- '429' => Gem::Net::HTTPTooManyRequests,
- '431' => Gem::Net::HTTPRequestHeaderFieldsTooLarge,
- '451' => Gem::Net::HTTPUnavailableForLegalReasons,
-
- '500' => Gem::Net::HTTPInternalServerError,
- '501' => Gem::Net::HTTPNotImplemented,
- '502' => Gem::Net::HTTPBadGateway,
- '503' => Gem::Net::HTTPServiceUnavailable,
- '504' => Gem::Net::HTTPGatewayTimeout,
- '505' => Gem::Net::HTTPVersionNotSupported,
- '506' => Gem::Net::HTTPVariantAlsoNegotiates,
- '507' => Gem::Net::HTTPInsufficientStorage,
- '508' => Gem::Net::HTTPLoopDetected,
- '510' => Gem::Net::HTTPNotExtended,
- '511' => Gem::Net::HTTPNetworkAuthenticationRequired,
- }
-end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/status.rb b/lib/rubygems/vendor/net-http/lib/net/http/status.rb
deleted file mode 100644
index 9110b108b8..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/http/status.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../http'
-
-if $0 == __FILE__
- require 'open-uri'
- File.foreach(__FILE__) do |line|
- puts line
- break if line.start_with?('end')
- end
- puts
- puts "Gem::Net::HTTP::STATUS_CODES = {"
- url = "https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv"
- Gem::URI(url).read.each_line do |line|
- code, mes, = line.split(',')
- next if ['(Unused)', 'Unassigned', 'Description'].include?(mes)
- puts " #{code} => '#{mes}',"
- end
- puts "} # :nodoc:"
-end
-
-Gem::Net::HTTP::STATUS_CODES = {
- 100 => 'Continue',
- 101 => 'Switching Protocols',
- 102 => 'Processing',
- 103 => 'Early Hints',
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
- 207 => 'Multi-Status',
- 208 => 'Already Reported',
- 226 => 'IM Used',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 303 => 'See Other',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
- 308 => 'Permanent Redirect',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Content Too Large',
- 414 => 'URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Range Not Satisfiable',
- 417 => 'Expectation Failed',
- 421 => 'Misdirected Request',
- 422 => 'Unprocessable Content',
- 423 => 'Locked',
- 424 => 'Failed Dependency',
- 425 => 'Too Early',
- 426 => 'Upgrade Required',
- 428 => 'Precondition Required',
- 429 => 'Too Many Requests',
- 431 => 'Request Header Fields Too Large',
- 451 => 'Unavailable For Legal Reasons',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported',
- 506 => 'Variant Also Negotiates',
- 507 => 'Insufficient Storage',
- 508 => 'Loop Detected',
- 510 => 'Not Extended (OBSOLETED)',
- 511 => 'Network Authentication Required',
-} # :nodoc:
diff --git a/lib/rubygems/vendor/net-http/lib/net/https.rb b/lib/rubygems/vendor/net-http/lib/net/https.rb
deleted file mode 100644
index d2784f0be0..0000000000
--- a/lib/rubygems/vendor/net-http/lib/net/https.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-=begin
-
-= net/https -- SSL/TLS enhancement for Gem::Net::HTTP.
-
- This file has been merged with net/http. There is no longer any need to
- require 'rubygems/vendor/net-http/lib/net/https' to use HTTPS.
-
- See Gem::Net::HTTP for details on how to make HTTPS connections.
-
-== Info
- 'OpenSSL for Ruby 2' project
- Copyright (C) 2001 GOTOU Yuuzou <gotoyuzo@notwork.org>
- All rights reserved.
-
-== Licence
- This program is licensed under the same licence as Ruby.
- (See the file 'LICENCE'.)
-
-=end
-
-require_relative 'http'
-require 'openssl'
diff --git a/lib/rubygems/vendor/net-protocol/.document b/lib/rubygems/vendor/net-protocol/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/net-protocol/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb b/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
deleted file mode 100644
index 53d34d8d98..0000000000
--- a/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
+++ /dev/null
@@ -1,544 +0,0 @@
-# frozen_string_literal: true
-#
-# = net/protocol.rb
-#
-#--
-# Copyright (c) 1999-2004 Yukihiro Matsumoto
-# Copyright (c) 1999-2004 Minero Aoki
-#
-# written and maintained by Minero Aoki <aamine@loveruby.net>
-#
-# This program is free software. You can re-distribute and/or
-# modify this program under the same terms as Ruby itself,
-# Ruby Distribute License or GNU General Public License.
-#
-# $Id$
-#++
-#
-# WARNING: This file is going to remove.
-# Do not rely on the implementation written in this file.
-#
-
-require 'socket'
-require_relative '../../../timeout/lib/timeout'
-require 'io/wait'
-
-module Gem::Net # :nodoc:
-
- class Protocol #:nodoc: internal use only
- VERSION = "0.2.2"
-
- private
- def Protocol.protocol_param(name, val)
- module_eval(<<-End, __FILE__, __LINE__ + 1)
- def #{name}
- #{val}
- end
- End
- end
-
- def ssl_socket_connect(s, timeout)
- if timeout
- while true
- raise Gem::Net::OpenTimeout if timeout <= 0
- start = Process.clock_gettime Process::CLOCK_MONOTONIC
- # to_io is required because SSLSocket doesn't have wait_readable yet
- case s.connect_nonblock(exception: false)
- when :wait_readable; s.to_io.wait_readable(timeout)
- when :wait_writable; s.to_io.wait_writable(timeout)
- else; break
- end
- timeout -= Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
- end
- else
- s.connect
- end
- end
- end
-
-
- class ProtocolError < StandardError; end
- class ProtoSyntaxError < ProtocolError; end
- class ProtoFatalError < ProtocolError; end
- class ProtoUnknownError < ProtocolError; end
- class ProtoServerError < ProtocolError; end
- class ProtoAuthError < ProtocolError; end
- class ProtoCommandError < ProtocolError; end
- class ProtoRetriableError < ProtocolError; end
- ProtocRetryError = ProtoRetriableError
-
- ##
- # OpenTimeout, a subclass of Gem::Timeout::Error, is raised if a connection cannot
- # be created within the open_timeout.
-
- class OpenTimeout < Gem::Timeout::Error; end
-
- ##
- # ReadTimeout, a subclass of Gem::Timeout::Error, is raised if a chunk of the
- # response cannot be read within the read_timeout.
-
- class ReadTimeout < Gem::Timeout::Error
- def initialize(io = nil)
- @io = io
- end
- attr_reader :io
-
- def message
- msg = super
- if @io
- msg = "#{msg} with #{@io.inspect}"
- end
- msg
- end
- end
-
- ##
- # WriteTimeout, a subclass of Gem::Timeout::Error, is raised if a chunk of the
- # response cannot be written within the write_timeout. Not raised on Windows.
-
- class WriteTimeout < Gem::Timeout::Error
- def initialize(io = nil)
- @io = io
- end
- attr_reader :io
-
- def message
- msg = super
- if @io
- msg = "#{msg} with #{@io.inspect}"
- end
- msg
- end
- end
-
-
- class BufferedIO #:nodoc: internal use only
- def initialize(io, read_timeout: 60, write_timeout: 60, continue_timeout: nil, debug_output: nil)
- @io = io
- @read_timeout = read_timeout
- @write_timeout = write_timeout
- @continue_timeout = continue_timeout
- @debug_output = debug_output
- @rbuf = ''.b
- @rbuf_empty = true
- @rbuf_offset = 0
- end
-
- attr_reader :io
- attr_accessor :read_timeout
- attr_accessor :write_timeout
- attr_accessor :continue_timeout
- attr_accessor :debug_output
-
- def inspect
- "#<#{self.class} io=#{@io}>"
- end
-
- def eof?
- @io.eof?
- end
-
- def closed?
- @io.closed?
- end
-
- def close
- @io.close
- end
-
- #
- # Read
- #
-
- public
-
- def read(len, dest = ''.b, ignore_eof = false)
- LOG "reading #{len} bytes..."
- read_bytes = 0
- begin
- while read_bytes + rbuf_size < len
- if s = rbuf_consume_all
- read_bytes += s.bytesize
- dest << s
- end
- rbuf_fill
- end
- s = rbuf_consume(len - read_bytes)
- read_bytes += s.bytesize
- dest << s
- rescue EOFError
- raise unless ignore_eof
- end
- LOG "read #{read_bytes} bytes"
- dest
- end
-
- def read_all(dest = ''.b)
- LOG 'reading all...'
- read_bytes = 0
- begin
- while true
- if s = rbuf_consume_all
- read_bytes += s.bytesize
- dest << s
- end
- rbuf_fill
- end
- rescue EOFError
- ;
- end
- LOG "read #{read_bytes} bytes"
- dest
- end
-
- def readuntil(terminator, ignore_eof = false)
- offset = @rbuf_offset
- begin
- until idx = @rbuf.index(terminator, offset)
- offset = @rbuf.bytesize
- rbuf_fill
- end
- return rbuf_consume(idx + terminator.bytesize - @rbuf_offset)
- rescue EOFError
- raise unless ignore_eof
- return rbuf_consume
- end
- end
-
- def readline
- readuntil("\n").chop
- end
-
- private
-
- BUFSIZE = 1024 * 16
-
- def rbuf_fill
- tmp = @rbuf_empty ? @rbuf : nil
- case rv = @io.read_nonblock(BUFSIZE, tmp, exception: false)
- when String
- @rbuf_empty = false
- if rv.equal?(tmp)
- @rbuf_offset = 0
- else
- @rbuf << rv
- rv.clear
- end
- return
- when :wait_readable
- (io = @io.to_io).wait_readable(@read_timeout) or raise Gem::Net::ReadTimeout.new(io)
- # continue looping
- when :wait_writable
- # OpenSSL::Buffering#read_nonblock may fail with IO::WaitWritable.
- # http://www.openssl.org/support/faq.html#PROG10
- (io = @io.to_io).wait_writable(@read_timeout) or raise Gem::Net::ReadTimeout.new(io)
- # continue looping
- when nil
- raise EOFError, 'end of file reached'
- end while true
- end
-
- def rbuf_flush
- if @rbuf_empty
- @rbuf.clear
- @rbuf_offset = 0
- end
- nil
- end
-
- def rbuf_size
- @rbuf.bytesize - @rbuf_offset
- end
-
- def rbuf_consume_all
- rbuf_consume if rbuf_size > 0
- end
-
- def rbuf_consume(len = nil)
- if @rbuf_offset == 0 && (len.nil? || len == @rbuf.bytesize)
- s = @rbuf
- @rbuf = ''.b
- @rbuf_offset = 0
- @rbuf_empty = true
- elsif len.nil?
- s = @rbuf.byteslice(@rbuf_offset..-1)
- @rbuf = ''.b
- @rbuf_offset = 0
- @rbuf_empty = true
- else
- s = @rbuf.byteslice(@rbuf_offset, len)
- @rbuf_offset += len
- @rbuf_empty = @rbuf_offset == @rbuf.bytesize
- rbuf_flush
- end
-
- @debug_output << %Q[-> #{s.dump}\n] if @debug_output
- s
- end
-
- #
- # Write
- #
-
- public
-
- def write(*strs)
- writing {
- write0(*strs)
- }
- end
-
- alias << write
-
- def writeline(str)
- writing {
- write0 str + "\r\n"
- }
- end
-
- private
-
- def writing
- @written_bytes = 0
- @debug_output << '<- ' if @debug_output
- yield
- @debug_output << "\n" if @debug_output
- bytes = @written_bytes
- @written_bytes = nil
- bytes
- end
-
- def write0(*strs)
- @debug_output << strs.map(&:dump).join if @debug_output
- orig_written_bytes = @written_bytes
- strs.each_with_index do |str, i|
- need_retry = true
- case len = @io.write_nonblock(str, exception: false)
- when Integer
- @written_bytes += len
- len -= str.bytesize
- if len == 0
- if strs.size == i+1
- return @written_bytes - orig_written_bytes
- else
- need_retry = false
- # next string
- end
- elsif len < 0
- str = str.byteslice(len, -len)
- else # len > 0
- need_retry = false
- # next string
- end
- # continue looping
- when :wait_writable
- (io = @io.to_io).wait_writable(@write_timeout) or raise Gem::Net::WriteTimeout.new(io)
- # continue looping
- end while need_retry
- end
- end
-
- #
- # Logging
- #
-
- private
-
- def LOG_off
- @save_debug_out = @debug_output
- @debug_output = nil
- end
-
- def LOG_on
- @debug_output = @save_debug_out
- end
-
- def LOG(msg)
- return unless @debug_output
- @debug_output << msg + "\n"
- end
- end
-
-
- class InternetMessageIO < BufferedIO #:nodoc: internal use only
- def initialize(*, **)
- super
- @wbuf = nil
- end
-
- #
- # Read
- #
-
- def each_message_chunk
- LOG 'reading message...'
- LOG_off()
- read_bytes = 0
- while (line = readuntil("\r\n")) != ".\r\n"
- read_bytes += line.size
- yield line.delete_prefix('.')
- end
- LOG_on()
- LOG "read message (#{read_bytes} bytes)"
- end
-
- # *library private* (cannot handle 'break')
- def each_list_item
- while (str = readuntil("\r\n")) != ".\r\n"
- yield str.chop
- end
- end
-
- def write_message_0(src)
- prev = @written_bytes
- each_crlf_line(src) do |line|
- write0 dot_stuff(line)
- end
- @written_bytes - prev
- end
-
- #
- # Write
- #
-
- def write_message(src)
- LOG "writing message from #{src.class}"
- LOG_off()
- len = writing {
- using_each_crlf_line {
- write_message_0 src
- }
- }
- LOG_on()
- LOG "wrote #{len} bytes"
- len
- end
-
- def write_message_by_block(&block)
- LOG 'writing message from block'
- LOG_off()
- len = writing {
- using_each_crlf_line {
- begin
- block.call(WriteAdapter.new(self.method(:write_message_0)))
- rescue LocalJumpError
- # allow `break' from writer block
- end
- }
- }
- LOG_on()
- LOG "wrote #{len} bytes"
- len
- end
-
- private
-
- def dot_stuff(s)
- s.sub(/\A\./, '..')
- end
-
- def using_each_crlf_line
- @wbuf = ''.b
- yield
- if not @wbuf.empty? # unterminated last line
- write0 dot_stuff(@wbuf.chomp) + "\r\n"
- elsif @written_bytes == 0 # empty src
- write0 "\r\n"
- end
- write0 ".\r\n"
- @wbuf = nil
- end
-
- def each_crlf_line(src)
- buffer_filling(@wbuf, src) do
- while line = @wbuf.slice!(/\A[^\r\n]*(?:\n|\r(?:\n|(?!\z)))/)
- yield line.chomp("\n") + "\r\n"
- end
- end
- end
-
- def buffer_filling(buf, src)
- case src
- when String # for speeding up.
- 0.step(src.size - 1, 1024) do |i|
- buf << src[i, 1024]
- yield
- end
- when File # for speeding up.
- while s = src.read(1024)
- buf << s
- yield
- end
- else # generic reader
- src.each do |str|
- buf << str
- yield if buf.size > 1024
- end
- yield unless buf.empty?
- end
- end
- end
-
-
- #
- # The writer adapter class
- #
- class WriteAdapter
- def initialize(writer)
- @writer = writer
- end
-
- def inspect
- "#<#{self.class} writer=#{@writer.inspect}>"
- end
-
- def write(str)
- @writer.call(str)
- end
-
- alias print write
-
- def <<(str)
- write str
- self
- end
-
- def puts(str = '')
- write str.chomp("\n") + "\n"
- end
-
- def printf(*args)
- write sprintf(*args)
- end
- end
-
-
- class ReadAdapter #:nodoc: internal use only
- def initialize(block)
- @block = block
- end
-
- def inspect
- "#<#{self.class}>"
- end
-
- def <<(str)
- call_block(str, &@block) if @block
- end
-
- private
-
- # This method is needed because @block must be called by yield,
- # not Proc#call. You can see difference when using `break' in
- # the block.
- def call_block(str)
- yield str
- end
- end
-
-
- module NetPrivate #:nodoc: obsolete
- Socket = ::Gem::Net::InternetMessageIO
- end
-
-end # module Gem::Net
diff --git a/lib/rubygems/vendor/optparse/.document b/lib/rubygems/vendor/optparse/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/optparse/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/optparse/lib/optparse.rb b/lib/rubygems/vendor/optparse/lib/optparse.rb
deleted file mode 100644
index 5937431720..0000000000
--- a/lib/rubygems/vendor/optparse/lib/optparse.rb
+++ /dev/null
@@ -1,2330 +0,0 @@
-# frozen_string_literal: true
-#
-# optparse.rb - command-line option analysis with the Gem::OptionParser class.
-#
-# Author:: Nobu Nakada
-# Documentation:: Nobu Nakada and Gavin Sinclair.
-#
-# See Gem::OptionParser for documentation.
-#
-
-
-#--
-# == Developer Documentation (not for RDoc output)
-#
-# === Class tree
-#
-# - Gem::OptionParser:: front end
-# - Gem::OptionParser::Switch:: each switches
-# - Gem::OptionParser::List:: options list
-# - Gem::OptionParser::ParseError:: errors on parsing
-# - Gem::OptionParser::AmbiguousOption
-# - Gem::OptionParser::NeedlessArgument
-# - Gem::OptionParser::MissingArgument
-# - Gem::OptionParser::InvalidOption
-# - Gem::OptionParser::InvalidArgument
-# - Gem::OptionParser::AmbiguousArgument
-#
-# === Object relationship diagram
-#
-# +--------------+
-# | Gem::OptionParser |<>-----+
-# +--------------+ | +--------+
-# | ,-| Switch |
-# on_head -------->+---------------+ / +--------+
-# accept/reject -->| List |<|>-
-# | |<|>- +----------+
-# on ------------->+---------------+ `-| argument |
-# : : | class |
-# +---------------+ |==========|
-# on_tail -------->| | |pattern |
-# +---------------+ |----------|
-# Gem::OptionParser.accept ->| DefaultList | |converter |
-# reject |(shared between| +----------+
-# | all instances)|
-# +---------------+
-#
-#++
-#
-# == Gem::OptionParser
-#
-# === New to +Gem::OptionParser+?
-#
-# See the {Tutorial}[optparse/tutorial.rdoc].
-#
-# === Introduction
-#
-# Gem::OptionParser is a class for command-line option analysis. It is much more
-# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
-# solution.
-#
-# === Features
-#
-# 1. The argument specification and the code to handle it are written in the
-# same place.
-# 2. It can output an option summary; you don't need to maintain this string
-# separately.
-# 3. Optional and mandatory arguments are specified very gracefully.
-# 4. Arguments can be automatically converted to a specified class.
-# 5. Arguments can be restricted to a certain set.
-#
-# All of these features are demonstrated in the examples below. See
-# #make_switch for full documentation.
-#
-# === Minimal example
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-#
-# options = {}
-# Gem::OptionParser.new do |parser|
-# parser.banner = "Usage: example.rb [options]"
-#
-# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
-# options[:verbose] = v
-# end
-# end.parse!
-#
-# p options
-# p ARGV
-#
-# === Generating Help
-#
-# Gem::OptionParser can be used to automatically generate help for the commands you
-# write:
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-#
-# Options = Struct.new(:name)
-#
-# class Parser
-# def self.parse(options)
-# args = Options.new("world")
-#
-# opt_parser = Gem::OptionParser.new do |parser|
-# parser.banner = "Usage: example.rb [options]"
-#
-# parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
-# args.name = n
-# end
-#
-# parser.on("-h", "--help", "Prints this help") do
-# puts parser
-# exit
-# end
-# end
-#
-# opt_parser.parse!(options)
-# return args
-# end
-# end
-# options = Parser.parse %w[--help]
-#
-# #=>
-# # Usage: example.rb [options]
-# # -n, --name=NAME Name to say hello to
-# # -h, --help Prints this help
-#
-# === Required Arguments
-#
-# For options that require an argument, option specification strings may include an
-# option name in all caps. If an option is used without the required argument,
-# an exception will be raised.
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-#
-# options = {}
-# Gem::OptionParser.new do |parser|
-# parser.on("-r", "--require LIBRARY",
-# "Require the LIBRARY before executing your script") do |lib|
-# puts "You required #{lib}!"
-# end
-# end.parse!
-#
-# Used:
-#
-# $ ruby optparse-test.rb -r
-# optparse-test.rb:9:in `<main>': missing argument: -r (Gem::OptionParser::MissingArgument)
-# $ ruby optparse-test.rb -r my-library
-# You required my-library!
-#
-# === Type Coercion
-#
-# Gem::OptionParser supports the ability to coerce command line arguments
-# into objects for us.
-#
-# Gem::OptionParser comes with a few ready-to-use kinds of type
-# coercion. They are:
-#
-# - Date -- Anything accepted by +Date.parse+ (need to require +optparse/date+)
-# - DateTime -- Anything accepted by +DateTime.parse+ (need to require +optparse/date+)
-# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+ (need to require +optparse/time+)
-# - URI -- Anything accepted by +Gem::URI.parse+ (need to require +optparse/uri+)
-# - Shellwords -- Anything accepted by +Shellwords.shellwords+ (need to require +optparse/shellwords+)
-# - String -- Any non-empty string
-# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
-# - Float -- Any float. (e.g. 10, 3.14, -100E+13)
-# - Numeric -- Any integer, float, or rational (1, 3.4, 1/3)
-# - DecimalInteger -- Like +Integer+, but no octal format.
-# - OctalInteger -- Like +Integer+, but no decimal format.
-# - DecimalNumeric -- Decimal integer or float.
-# - TrueClass -- Accepts '+, yes, true, -, no, false' and
-# defaults as +true+
-# - FalseClass -- Same as +TrueClass+, but defaults to +false+
-# - Array -- Strings separated by ',' (e.g. 1,2,3)
-# - Regexp -- Regular expressions. Also includes options.
-#
-# We can also add our own coercions, which we will cover below.
-#
-# ==== Using Built-in Conversions
-#
-# As an example, the built-in +Time+ conversion is used. The other built-in
-# conversions behave in the same way.
-# Gem::OptionParser will attempt to parse the argument
-# as a +Time+. If it succeeds, that time will be passed to the
-# handler block. Otherwise, an exception will be raised.
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-# require 'rubygems/vendor/optparse/lib/optparse/time'
-# Gem::OptionParser.new do |parser|
-# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
-# p time
-# end
-# end.parse!
-#
-# Used:
-#
-# $ ruby optparse-test.rb -t nonsense
-# ... invalid argument: -t nonsense (Gem::OptionParser::InvalidArgument)
-# $ ruby optparse-test.rb -t 10-11-12
-# 2010-11-12 00:00:00 -0500
-# $ ruby optparse-test.rb -t 9:30
-# 2014-08-13 09:30:00 -0400
-#
-# ==== Creating Custom Conversions
-#
-# The +accept+ method on Gem::OptionParser may be used to create converters.
-# It specifies which conversion block to call whenever a class is specified.
-# The example below uses it to fetch a +User+ object before the +on+ handler receives it.
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-#
-# User = Struct.new(:id, :name)
-#
-# def find_user id
-# not_found = ->{ raise "No User Found for id #{id}" }
-# [ User.new(1, "Sam"),
-# User.new(2, "Gandalf") ].find(not_found) do |u|
-# u.id == id
-# end
-# end
-#
-# op = Gem::OptionParser.new
-# op.accept(User) do |user_id|
-# find_user user_id.to_i
-# end
-#
-# op.on("--user ID", User) do |user|
-# puts user
-# end
-#
-# op.parse!
-#
-# Used:
-#
-# $ ruby optparse-test.rb --user 1
-# #<struct User id=1, name="Sam">
-# $ ruby optparse-test.rb --user 2
-# #<struct User id=2, name="Gandalf">
-# $ ruby optparse-test.rb --user 3
-# optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
-#
-# === Store options to a Hash
-#
-# The +into+ option of +order+, +parse+ and so on methods stores command line options into a Hash.
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-#
-# options = {}
-# Gem::OptionParser.new do |parser|
-# parser.on('-a')
-# parser.on('-b NUM', Integer)
-# parser.on('-v', '--verbose')
-# end.parse!(into: options)
-#
-# p options
-#
-# Used:
-#
-# $ ruby optparse-test.rb -a
-# {:a=>true}
-# $ ruby optparse-test.rb -a -v
-# {:a=>true, :verbose=>true}
-# $ ruby optparse-test.rb -a -b 100
-# {:a=>true, :b=>100}
-#
-# === Complete example
-#
-# The following example is a complete Ruby program. You can run it and see the
-# effect of specifying various options. This is probably the best way to learn
-# the features of +optparse+.
-#
-# require 'rubygems/vendor/optparse/lib/optparse'
-# require 'rubygems/vendor/optparse/lib/optparse/time'
-# require 'ostruct'
-# require 'pp'
-#
-# class OptparseExample
-# Version = '1.0.0'
-#
-# CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
-# CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
-#
-# class ScriptOptions
-# attr_accessor :library, :inplace, :encoding, :transfer_type,
-# :verbose, :extension, :delay, :time, :record_separator,
-# :list
-#
-# def initialize
-# self.library = []
-# self.inplace = false
-# self.encoding = "utf8"
-# self.transfer_type = :auto
-# self.verbose = false
-# end
-#
-# def define_options(parser)
-# parser.banner = "Usage: example.rb [options]"
-# parser.separator ""
-# parser.separator "Specific options:"
-#
-# # add additional options
-# perform_inplace_option(parser)
-# delay_execution_option(parser)
-# execute_at_time_option(parser)
-# specify_record_separator_option(parser)
-# list_example_option(parser)
-# specify_encoding_option(parser)
-# optional_option_argument_with_keyword_completion_option(parser)
-# boolean_verbose_option(parser)
-#
-# parser.separator ""
-# parser.separator "Common options:"
-# # No argument, shows at tail. This will print an options summary.
-# # Try it and see!
-# parser.on_tail("-h", "--help", "Show this message") do
-# puts parser
-# exit
-# end
-# # Another typical switch to print the version.
-# parser.on_tail("--version", "Show version") do
-# puts Version
-# exit
-# end
-# end
-#
-# def perform_inplace_option(parser)
-# # Specifies an optional option argument
-# parser.on("-i", "--inplace [EXTENSION]",
-# "Edit ARGV files in place",
-# "(make backup if EXTENSION supplied)") do |ext|
-# self.inplace = true
-# self.extension = ext || ''
-# self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
-# end
-# end
-#
-# def delay_execution_option(parser)
-# # Cast 'delay' argument to a Float.
-# parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
-# self.delay = n
-# end
-# end
-#
-# def execute_at_time_option(parser)
-# # Cast 'time' argument to a Time object.
-# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
-# self.time = time
-# end
-# end
-#
-# def specify_record_separator_option(parser)
-# # Cast to octal integer.
-# parser.on("-F", "--irs [OCTAL]", Gem::OptionParser::OctalInteger,
-# "Specify record separator (default \\0)") do |rs|
-# self.record_separator = rs
-# end
-# end
-#
-# def list_example_option(parser)
-# # List of arguments.
-# parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
-# self.list = list
-# end
-# end
-#
-# def specify_encoding_option(parser)
-# # Keyword completion. We are specifying a specific set of arguments (CODES
-# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
-# # the shortest unambiguous text.
-# code_list = (CODE_ALIASES.keys + CODES).join(', ')
-# parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
-# "(#{code_list})") do |encoding|
-# self.encoding = encoding
-# end
-# end
-#
-# def optional_option_argument_with_keyword_completion_option(parser)
-# # Optional '--type' option argument with keyword completion.
-# parser.on("--type [TYPE]", [:text, :binary, :auto],
-# "Select transfer type (text, binary, auto)") do |t|
-# self.transfer_type = t
-# end
-# end
-#
-# def boolean_verbose_option(parser)
-# # Boolean switch.
-# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
-# self.verbose = v
-# end
-# end
-# end
-#
-# #
-# # Return a structure describing the options.
-# #
-# def parse(args)
-# # The options specified on the command line will be collected in
-# # *options*.
-#
-# @options = ScriptOptions.new
-# @args = Gem::OptionParser.new do |parser|
-# @options.define_options(parser)
-# parser.parse!(args)
-# end
-# @options
-# end
-#
-# attr_reader :parser, :options
-# end # class OptparseExample
-#
-# example = OptparseExample.new
-# options = example.parse(ARGV)
-# pp options # example.options
-# pp ARGV
-#
-# === Shell Completion
-#
-# For modern shells (e.g. bash, zsh, etc.), you can use shell
-# completion for command line options.
-#
-# === Further documentation
-#
-# The above examples, along with the accompanying
-# {Tutorial}[optparse/tutorial.rdoc],
-# should be enough to learn how to use this class.
-# If you have any questions, file a ticket at http://bugs.ruby-lang.org.
-#
-class Gem::OptionParser
- Gem::OptionParser::Version = "0.4.0"
-
- # :stopdoc:
- NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
- RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
- OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
- # :startdoc:
-
- #
- # Keyword completion module. This allows partial arguments to be specified
- # and resolved against a list of acceptable values.
- #
- module Completion
- def self.regexp(key, icase)
- Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase)
- end
-
- def self.candidate(key, icase = false, pat = nil, &block)
- pat ||= Completion.regexp(key, icase)
- candidates = []
- block.call do |k, *v|
- (if Regexp === k
- kn = ""
- k === key
- else
- kn = defined?(k.id2name) ? k.id2name : k
- pat === kn
- end) or next
- v << k if v.empty?
- candidates << [k, v, kn]
- end
- candidates
- end
-
- def candidate(key, icase = false, pat = nil)
- Completion.candidate(key, icase, pat, &method(:each))
- end
-
- public
- def complete(key, icase = false, pat = nil)
- candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
- if candidates.size == 1
- canon, sw, * = candidates[0]
- elsif candidates.size > 1
- canon, sw, cn = candidates.shift
- candidates.each do |k, v, kn|
- next if sw == v
- if String === cn and String === kn
- if cn.rindex(kn, 0)
- canon, sw, cn = k, v, kn
- next
- elsif kn.rindex(cn, 0)
- next
- end
- end
- throw :ambiguous, key
- end
- end
- if canon
- block_given? or return key, *sw
- yield(key, *sw)
- end
- end
-
- def convert(opt = nil, val = nil, *)
- val
- end
- end
-
-
- #
- # Map from option/keyword string to object with completion.
- #
- class OptionMap < Hash
- include Completion
- end
-
-
- #
- # Individual switch class. Not important to the user.
- #
- # Defined within Switch are several Switch-derived classes: NoArgument,
- # RequiredArgument, etc.
- #
- class Switch
- attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block
-
- #
- # Guesses argument style from +arg+. Returns corresponding
- # Gem::OptionParser::Switch class (OptionalArgument, etc.).
- #
- def self.guess(arg)
- case arg
- when ""
- t = self
- when /\A=?\[/
- t = Switch::OptionalArgument
- when /\A\s+\[/
- t = Switch::PlacedArgument
- else
- t = Switch::RequiredArgument
- end
- self >= t or incompatible_argument_styles(arg, t)
- t
- end
-
- def self.incompatible_argument_styles(arg, t)
- raise(ArgumentError, "#{arg}: incompatible argument styles\n #{self}, #{t}",
- ParseError.filter_backtrace(caller(2)))
- end
-
- def self.pattern
- NilClass
- end
-
- def initialize(pattern = nil, conv = nil,
- short = nil, long = nil, arg = nil,
- desc = ([] if short or long), block = nil, &_block)
- raise if Array === pattern
- block ||= _block
- @pattern, @conv, @short, @long, @arg, @desc, @block =
- pattern, conv, short, long, arg, desc, block
- end
-
- #
- # Parses +arg+ and returns rest of +arg+ and matched portion to the
- # argument pattern. Yields when the pattern doesn't match substring.
- #
- def parse_arg(arg) # :nodoc:
- pattern or return nil, [arg]
- unless m = pattern.match(arg)
- yield(InvalidArgument, arg)
- return arg, []
- end
- if String === m
- m = [s = m]
- else
- m = m.to_a
- s = m[0]
- return nil, m unless String === s
- end
- raise InvalidArgument, arg unless arg.rindex(s, 0)
- return nil, m if s.length == arg.length
- yield(InvalidArgument, arg) # didn't match whole arg
- return arg[s.length..-1], m
- end
- private :parse_arg
-
- #
- # Parses argument, converts and returns +arg+, +block+ and result of
- # conversion. Yields at semi-error condition instead of raising an
- # exception.
- #
- def conv_arg(arg, val = []) # :nodoc:
- if conv
- val = conv.call(*val)
- else
- val = proc {|v| v}.call(*val)
- end
- return arg, block, val
- end
- private :conv_arg
-
- #
- # Produces the summary text. Each line of the summary is yielded to the
- # block (without newline).
- #
- # +sdone+:: Already summarized short style options keyed hash.
- # +ldone+:: Already summarized long style options keyed hash.
- # +width+:: Width of left side (option part). In other words, the right
- # side (description part) starts after +width+ columns.
- # +max+:: Maximum width of left side -> the options are filled within
- # +max+ columns.
- # +indent+:: Prefix string indents all summarized lines.
- #
- def summarize(sdone = {}, ldone = {}, width = 1, max = width - 1, indent = "")
- sopts, lopts = [], [], nil
- @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
- @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
- return if sopts.empty? and lopts.empty? # completely hidden
-
- left = [sopts.join(', ')]
- right = desc.dup
-
- while s = lopts.shift
- l = left[-1].length + s.length
- l += arg.length if left.size == 1 && arg
- l < max or sopts.empty? or left << +''
- left[-1] << (left[-1].empty? ? ' ' * 4 : ', ') << s
- end
-
- if arg
- left[0] << (left[1] ? arg.sub(/\A(\[?)=/, '\1') + ',' : arg)
- end
- mlen = left.collect {|ss| ss.length}.max.to_i
- while mlen > width and l = left.shift
- mlen = left.collect {|ss| ss.length}.max.to_i if l.length == mlen
- if l.length < width and (r = right[0]) and !r.empty?
- l = l.to_s.ljust(width) + ' ' + r
- right.shift
- end
- yield(indent + l)
- end
-
- while begin l = left.shift; r = right.shift; l or r end
- l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
- yield(indent + l)
- end
-
- self
- end
-
- def add_banner(to) # :nodoc:
- unless @short or @long
- s = desc.join
- to << " [" + s + "]..." unless s.empty?
- end
- to
- end
-
- def match_nonswitch?(str) # :nodoc:
- @pattern =~ str unless @short or @long
- end
-
- #
- # Main name of the switch.
- #
- def switch_name
- (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
- end
-
- def compsys(sdone, ldone) # :nodoc:
- sopts, lopts = [], []
- @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
- @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
- return if sopts.empty? and lopts.empty? # completely hidden
-
- (sopts+lopts).each do |opt|
- # "(-x -c -r)-l[left justify]"
- if /^--\[no-\](.+)$/ =~ opt
- o = $1
- yield("--#{o}", desc.join(""))
- yield("--no-#{o}", desc.join(""))
- else
- yield("#{opt}", desc.join(""))
- end
- end
- end
-
- def pretty_print_contents(q) # :nodoc:
- if @block
- q.text ":" + @block.source_location.join(":") + ":"
- first = false
- else
- first = true
- end
- [@short, @long].each do |list|
- list.each do |opt|
- if first
- q.text ":"
- first = false
- end
- q.breakable
- q.text opt
- end
- end
- end
-
- def pretty_print(q) # :nodoc:
- q.object_group(self) {pretty_print_contents(q)}
- end
-
- #
- # Switch that takes no arguments.
- #
- class NoArgument < self
-
- #
- # Raises an exception if any arguments given.
- #
- def parse(arg, argv)
- yield(NeedlessArgument, arg) if arg
- conv_arg(arg)
- end
-
- def self.incompatible_argument_styles(*)
- end
-
- def self.pattern
- Object
- end
-
- def pretty_head # :nodoc:
- "NoArgument"
- end
- end
-
- #
- # Switch that takes an argument.
- #
- class RequiredArgument < self
-
- #
- # Raises an exception if argument is not present.
- #
- def parse(arg, argv)
- unless arg
- raise MissingArgument if argv.empty?
- arg = argv.shift
- end
- conv_arg(*parse_arg(arg, &method(:raise)))
- end
-
- def pretty_head # :nodoc:
- "Required"
- end
- end
-
- #
- # Switch that can omit argument.
- #
- class OptionalArgument < self
-
- #
- # Parses argument if given, or uses default value.
- #
- def parse(arg, argv, &error)
- if arg
- conv_arg(*parse_arg(arg, &error))
- else
- conv_arg(arg)
- end
- end
-
- def pretty_head # :nodoc:
- "Optional"
- end
- end
-
- #
- # Switch that takes an argument, which does not begin with '-' or is '-'.
- #
- class PlacedArgument < self
-
- #
- # Returns nil if argument is not present or begins with '-' and is not '-'.
- #
- def parse(arg, argv, &error)
- if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0]))
- return nil, block, nil
- end
- opt = (val = parse_arg(val, &error))[1]
- val = conv_arg(*val)
- if opt and !arg
- argv.shift
- else
- val[0] = nil
- end
- val
- end
-
- def pretty_head # :nodoc:
- "Placed"
- end
- end
- end
-
- #
- # Simple option list providing mapping from short and/or long option
- # string to Gem::OptionParser::Switch and mapping from acceptable argument to
- # matching pattern and converter pair. Also provides summary feature.
- #
- class List
- # Map from acceptable argument types to pattern and converter pairs.
- attr_reader :atype
-
- # Map from short style option switches to actual switch objects.
- attr_reader :short
-
- # Map from long style option switches to actual switch objects.
- attr_reader :long
-
- # List of all switches and summary string.
- attr_reader :list
-
- #
- # Just initializes all instance variables.
- #
- def initialize
- @atype = {}
- @short = OptionMap.new
- @long = OptionMap.new
- @list = []
- end
-
- def pretty_print(q) # :nodoc:
- q.group(1, "(", ")") do
- @list.each do |sw|
- next unless Switch === sw
- q.group(1, "(" + sw.pretty_head, ")") do
- sw.pretty_print_contents(q)
- end
- end
- end
- end
-
- #
- # See Gem::OptionParser.accept.
- #
- def accept(t, pat = /.*/m, &block)
- if pat
- pat.respond_to?(:match) or
- raise TypeError, "has no `match'", ParseError.filter_backtrace(caller(2))
- else
- pat = t if t.respond_to?(:match)
- end
- unless block
- block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
- end
- @atype[t] = [pat, block]
- end
-
- #
- # See Gem::OptionParser.reject.
- #
- def reject(t)
- @atype.delete(t)
- end
-
- #
- # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.
- #
- # +sw+:: Gem::OptionParser::Switch instance to be added.
- # +sopts+:: Short style option list.
- # +lopts+:: Long style option list.
- # +nlopts+:: Negated long style options list.
- #
- def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
- sopts.each {|o| @short[o] = sw} if sopts
- lopts.each {|o| @long[o] = sw} if lopts
- nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
- used = @short.invert.update(@long.invert)
- @list.delete_if {|o| Switch === o and !used[o]}
- end
- private :update
-
- #
- # Inserts +switch+ at the head of the list, and associates short, long
- # and negated long options. Arguments are:
- #
- # +switch+:: Gem::OptionParser::Switch instance to be inserted.
- # +short_opts+:: List of short style options.
- # +long_opts+:: List of long style options.
- # +nolong_opts+:: List of long style options with "no-" prefix.
- #
- # prepend(switch, short_opts, long_opts, nolong_opts)
- #
- def prepend(*args)
- update(*args)
- @list.unshift(args[0])
- end
-
- #
- # Appends +switch+ at the tail of the list, and associates short, long
- # and negated long options. Arguments are:
- #
- # +switch+:: Gem::OptionParser::Switch instance to be inserted.
- # +short_opts+:: List of short style options.
- # +long_opts+:: List of long style options.
- # +nolong_opts+:: List of long style options with "no-" prefix.
- #
- # append(switch, short_opts, long_opts, nolong_opts)
- #
- def append(*args)
- update(*args)
- @list.push(args[0])
- end
-
- #
- # Searches +key+ in +id+ list. The result is returned or yielded if a
- # block is given. If it isn't found, nil is returned.
- #
- def search(id, key)
- if list = __send__(id)
- val = list.fetch(key) {return nil}
- block_given? ? yield(val) : val
- end
- end
-
- #
- # Searches list +id+ for +opt+ and the optional patterns for completion
- # +pat+. If +icase+ is true, the search is case insensitive. The result
- # is returned or yielded if a block is given. If it isn't found, nil is
- # returned.
- #
- def complete(id, opt, icase = false, *pat, &block)
- __send__(id).complete(opt, icase, *pat, &block)
- end
-
- def get_candidates(id)
- yield __send__(id).keys
- end
-
- #
- # Iterates over each option, passing the option to the +block+.
- #
- def each_option(&block)
- list.each(&block)
- end
-
- #
- # Creates the summary table, passing each line to the +block+ (without
- # newline). The arguments +args+ are passed along to the summarize
- # method which is called on every option.
- #
- def summarize(*args, &block)
- sum = []
- list.reverse_each do |opt|
- if opt.respond_to?(:summarize) # perhaps Gem::OptionParser::Switch
- s = []
- opt.summarize(*args) {|l| s << l}
- sum.concat(s.reverse)
- elsif !opt or opt.empty?
- sum << ""
- elsif opt.respond_to?(:each_line)
- sum.concat([*opt.each_line].reverse)
- else
- sum.concat([*opt.each].reverse)
- end
- end
- sum.reverse_each(&block)
- end
-
- def add_banner(to) # :nodoc:
- list.each do |opt|
- if opt.respond_to?(:add_banner)
- opt.add_banner(to)
- end
- end
- to
- end
-
- def compsys(*args, &block) # :nodoc:
- list.each do |opt|
- if opt.respond_to?(:compsys)
- opt.compsys(*args, &block)
- end
- end
- end
- end
-
- #
- # Hash with completion search feature. See Gem::OptionParser::Completion.
- #
- class CompletingHash < Hash
- include Completion
-
- #
- # Completion for hash key.
- #
- def match(key)
- *values = fetch(key) {
- raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
- }
- return key, *values
- end
- end
-
- # :stopdoc:
-
- #
- # Enumeration of acceptable argument styles. Possible values are:
- #
- # NO_ARGUMENT:: The switch takes no arguments. (:NONE)
- # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)
- # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)
- #
- # Use like --switch=argument (long style) or -Xargument (short style). For
- # short style, only portion matched to argument pattern is treated as
- # argument.
- #
- ArgumentStyle = {}
- NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}
- RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}
- OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}
- ArgumentStyle.freeze
-
- #
- # Switches common used such as '--', and also provides default
- # argument classes
- #
- DefaultList = List.new
- DefaultList.short['-'] = Switch::NoArgument.new {}
- DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
-
-
- COMPSYS_HEADER = <<'XXX' # :nodoc:
-
-typeset -A opt_args
-local context state line
-
-_arguments -s -S \
-XXX
-
- def compsys(to, name = File.basename($0)) # :nodoc:
- to << "#compdef #{name}\n"
- to << COMPSYS_HEADER
- visit(:compsys, {}, {}) {|o, d|
- to << %Q[ "#{o}[#{d.gsub(/[\"\[\]]/, '\\\\\&')}]" \\\n]
- }
- to << " '*:file:_files' && return 0\n"
- end
-
- #
- # Default options for ARGV, which never appear in option summary.
- #
- Officious = {}
-
- #
- # --help
- # Shows option summary.
- #
- Officious['help'] = proc do |parser|
- Switch::NoArgument.new do |arg|
- puts parser.help
- exit
- end
- end
-
- #
- # --*-completion-bash=WORD
- # Shows candidates for command line completion.
- #
- Officious['*-completion-bash'] = proc do |parser|
- Switch::RequiredArgument.new do |arg|
- puts parser.candidate(arg)
- exit
- end
- end
-
- #
- # --*-completion-zsh[=NAME:FILE]
- # Creates zsh completion file.
- #
- Officious['*-completion-zsh'] = proc do |parser|
- Switch::OptionalArgument.new do |arg|
- parser.compsys(STDOUT, arg)
- exit
- end
- end
-
- #
- # --version
- # Shows version string if Version is defined.
- #
- Officious['version'] = proc do |parser|
- Switch::OptionalArgument.new do |pkg|
- if pkg
- begin
- require 'rubygems/vendor/optparse/lib/optparse/version'
- rescue LoadError
- else
- show_version(*pkg.split(/,/)) or
- abort("#{parser.program_name}: no version found in package #{pkg}")
- exit
- end
- end
- v = parser.ver or abort("#{parser.program_name}: version unknown")
- puts v
- exit
- end
- end
-
- # :startdoc:
-
- #
- # Class methods
- #
-
- #
- # Initializes a new instance and evaluates the optional block in context
- # of the instance. Arguments +args+ are passed to #new, see there for
- # description of parameters.
- #
- # This method is *deprecated*, its behavior corresponds to the older #new
- # method.
- #
- def self.with(*args, &block)
- opts = new(*args)
- opts.instance_eval(&block)
- opts
- end
-
- #
- # Returns an incremented value of +default+ according to +arg+.
- #
- def self.inc(arg, default = nil)
- case arg
- when Integer
- arg.nonzero?
- when nil
- default.to_i + 1
- end
- end
- def inc(*args)
- self.class.inc(*args)
- end
-
- #
- # Initializes the instance and yields itself if called with a block.
- #
- # +banner+:: Banner message.
- # +width+:: Summary width.
- # +indent+:: Summary indent.
- #
- def initialize(banner = nil, width = 32, indent = ' ' * 4)
- @stack = [DefaultList, List.new, List.new]
- @program_name = nil
- @banner = banner
- @summary_width = width
- @summary_indent = indent
- @default_argv = ARGV
- @require_exact = false
- @raise_unknown = true
- add_officious
- yield self if block_given?
- end
-
- def add_officious # :nodoc:
- list = base()
- Officious.each do |opt, block|
- list.long[opt] ||= block.call(self)
- end
- end
-
- #
- # Terminates option parsing. Optional parameter +arg+ is a string pushed
- # back to be the first non-option argument.
- #
- def terminate(arg = nil)
- self.class.terminate(arg)
- end
- def self.terminate(arg = nil)
- throw :terminate, arg
- end
-
- @stack = [DefaultList]
- def self.top() DefaultList end
-
- #
- # Directs to accept specified class +t+. The argument string is passed to
- # the block in which it should be converted to the desired class.
- #
- # +t+:: Argument class specifier, any object including Class.
- # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.
- #
- # accept(t, pat, &block)
- #
- def accept(*args, &blk) top.accept(*args, &blk) end
- #
- # See #accept.
- #
- def self.accept(*args, &blk) top.accept(*args, &blk) end
-
- #
- # Directs to reject specified class argument.
- #
- # +t+:: Argument class specifier, any object including Class.
- #
- # reject(t)
- #
- def reject(*args, &blk) top.reject(*args, &blk) end
- #
- # See #reject.
- #
- def self.reject(*args, &blk) top.reject(*args, &blk) end
-
- #
- # Instance methods
- #
-
- # Heading banner preceding summary.
- attr_writer :banner
-
- # Program name to be emitted in error message and default banner,
- # defaults to $0.
- attr_writer :program_name
-
- # Width for option list portion of summary. Must be Numeric.
- attr_accessor :summary_width
-
- # Indentation for summary. Must be String (or have + String method).
- attr_accessor :summary_indent
-
- # Strings to be parsed in default.
- attr_accessor :default_argv
-
- # Whether to require that options match exactly (disallows providing
- # abbreviated long option as short option).
- attr_accessor :require_exact
-
- # Whether to raise at unknown option.
- attr_accessor :raise_unknown
-
- #
- # Heading banner preceding summary.
- #
- def banner
- unless @banner
- @banner = +"Usage: #{program_name} [options]"
- visit(:add_banner, @banner)
- end
- @banner
- end
-
- #
- # Program name to be emitted in error message and default banner, defaults
- # to $0.
- #
- def program_name
- @program_name || File.basename($0, '.*')
- end
-
- # for experimental cascading :-)
- alias set_banner banner=
- alias set_program_name program_name=
- alias set_summary_width summary_width=
- alias set_summary_indent summary_indent=
-
- # Version
- attr_writer :version
- # Release code
- attr_writer :release
-
- #
- # Version
- #
- def version
- (defined?(@version) && @version) || (defined?(::Version) && ::Version)
- end
-
- #
- # Release code
- #
- def release
- (defined?(@release) && @release) || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
- end
-
- #
- # Returns version string from program_name, version and release.
- #
- def ver
- if v = version
- str = +"#{program_name} #{[v].join('.')}"
- str << " (#{v})" if v = release
- str
- end
- end
-
- def warn(mesg = $!)
- super("#{program_name}: #{mesg}")
- end
-
- def abort(mesg = $!)
- super("#{program_name}: #{mesg}")
- end
-
- #
- # Subject of #on / #on_head, #accept / #reject
- #
- def top
- @stack[-1]
- end
-
- #
- # Subject of #on_tail.
- #
- def base
- @stack[1]
- end
-
- #
- # Pushes a new List.
- #
- def new
- @stack.push(List.new)
- if block_given?
- yield self
- else
- self
- end
- end
-
- #
- # Removes the last List.
- #
- def remove
- @stack.pop
- end
-
- #
- # Puts option summary into +to+ and returns +to+. Yields each line if
- # a block is given.
- #
- # +to+:: Output destination, which must have method <<. Defaults to [].
- # +width+:: Width of left side, defaults to @summary_width.
- # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.
- # +indent+:: Indentation, defaults to @summary_indent.
- #
- def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
- nl = "\n"
- blk ||= proc {|l| to << (l.index(nl, -1) ? l : l + nl)}
- visit(:summarize, {}, {}, width, max, indent, &blk)
- to
- end
-
- #
- # Returns option summary string.
- #
- def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end
- alias to_s help
-
- def pretty_print(q) # :nodoc:
- q.object_group(self) do
- first = true
- if @stack.size > 2
- @stack.each_with_index do |s, i|
- next if i < 2
- next if s.list.empty?
- if first
- first = false
- q.text ":"
- end
- q.breakable
- s.pretty_print(q)
- end
- end
- end
- end
-
- def inspect # :nodoc:
- require 'pp'
- pretty_print_inspect
- end
-
- #
- # Returns option summary list.
- #
- def to_a; summarize("#{banner}".split(/^/)) end
-
- #
- # Checks if an argument is given twice, in which case an ArgumentError is
- # raised. Called from Gem::OptionParser#switch only.
- #
- # +obj+:: New argument.
- # +prv+:: Previously specified argument.
- # +msg+:: Exception message.
- #
- def notwice(obj, prv, msg) # :nodoc:
- unless !prv or prv == obj
- raise(ArgumentError, "argument #{msg} given twice: #{obj}",
- ParseError.filter_backtrace(caller(2)))
- end
- obj
- end
- private :notwice
-
- SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
-
- # :call-seq:
- # make_switch(params, block = nil)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- def make_switch(opts, block = nil)
- short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
- ldesc, sdesc, desc, arg = [], [], []
- default_style = Switch::NoArgument
- default_pattern = nil
- klass = nil
- q, a = nil
- has_arg = false
-
- opts.each do |o|
- # argument class
- next if search(:atype, o) do |pat, c|
- klass = notwice(o, klass, 'type')
- if not_style and not_style != Switch::NoArgument
- not_pattern, not_conv = pat, c
- else
- default_pattern, conv = pat, c
- end
- end
-
- # directly specified pattern(any object possible to match)
- if (!(String === o || Symbol === o)) and o.respond_to?(:match)
- pattern = notwice(o, pattern, 'pattern')
- if pattern.respond_to?(:convert)
- conv = pattern.method(:convert).to_proc
- else
- conv = SPLAT_PROC
- end
- next
- end
-
- # anything others
- case o
- when Proc, Method
- block = notwice(o, block, 'block')
- when Array, Hash
- case pattern
- when CompletingHash
- when nil
- pattern = CompletingHash.new
- conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
- else
- raise ArgumentError, "argument pattern given twice"
- end
- o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
- when Module
- raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
- when *ArgumentStyle.keys
- style = notwice(ArgumentStyle[o], style, 'style')
- when /^--no-([^\[\]=\s]*)(.+)?/
- q, a = $1, $2
- o = notwice(a ? Object : TrueClass, klass, 'type')
- not_pattern, not_conv = search(:atype, o) unless not_style
- not_style = (not_style || default_style).guess(arg = a) if a
- default_style = Switch::NoArgument
- default_pattern, conv = search(:atype, FalseClass) unless default_pattern
- ldesc << "--no-#{q}"
- (q = q.downcase).tr!('_', '-')
- long << "no-#{q}"
- nolong << q
- when /^--\[no-\]([^\[\]=\s]*)(.+)?/
- q, a = $1, $2
- o = notwice(a ? Object : TrueClass, klass, 'type')
- if a
- default_style = default_style.guess(arg = a)
- default_pattern, conv = search(:atype, o) unless default_pattern
- end
- ldesc << "--[no-]#{q}"
- (o = q.downcase).tr!('_', '-')
- long << o
- not_pattern, not_conv = search(:atype, FalseClass) unless not_style
- not_style = Switch::NoArgument
- nolong << "no-#{o}"
- when /^--([^\[\]=\s]*)(.+)?/
- q, a = $1, $2
- if a
- o = notwice(NilClass, klass, 'type')
- default_style = default_style.guess(arg = a)
- default_pattern, conv = search(:atype, o) unless default_pattern
- end
- ldesc << "--#{q}"
- (o = q.downcase).tr!('_', '-')
- long << o
- when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
- q, a = $1, $2
- o = notwice(Object, klass, 'type')
- if a
- default_style = default_style.guess(arg = a)
- default_pattern, conv = search(:atype, o) unless default_pattern
- else
- has_arg = true
- end
- sdesc << "-#{q}"
- short << Regexp.new(q)
- when /^-(.)(.+)?/
- q, a = $1, $2
- if a
- o = notwice(NilClass, klass, 'type')
- default_style = default_style.guess(arg = a)
- default_pattern, conv = search(:atype, o) unless default_pattern
- end
- sdesc << "-#{q}"
- short << q
- when /^=/
- style = notwice(default_style.guess(arg = o), style, 'style')
- default_pattern, conv = search(:atype, Object) unless default_pattern
- else
- desc.push(o) if o && !o.empty?
- end
- end
-
- default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
- if !(short.empty? and long.empty?)
- if has_arg and default_style == Switch::NoArgument
- default_style = Switch::RequiredArgument
- end
- s = (style || default_style).new(pattern || default_pattern,
- conv, sdesc, ldesc, arg, desc, block)
- elsif !block
- if style or pattern
- raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
- end
- s = desc
- else
- short << pattern
- s = (style || default_style).new(pattern,
- conv, nil, nil, arg, desc, block)
- end
- return s, short, long,
- (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
- nolong
- end
-
- # :call-seq:
- # define(*params, &block)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- def define(*opts, &block)
- top.append(*(sw = make_switch(opts, block)))
- sw[0]
- end
-
- # :call-seq:
- # on(*params, &block)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- def on(*opts, &block)
- define(*opts, &block)
- self
- end
- alias def_option define
-
- # :call-seq:
- # define_head(*params, &block)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- def define_head(*opts, &block)
- top.prepend(*(sw = make_switch(opts, block)))
- sw[0]
- end
-
- # :call-seq:
- # on_head(*params, &block)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- # The new option is added at the head of the summary.
- #
- def on_head(*opts, &block)
- define_head(*opts, &block)
- self
- end
- alias def_head_option define_head
-
- # :call-seq:
- # define_tail(*params, &block)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- def define_tail(*opts, &block)
- base.append(*(sw = make_switch(opts, block)))
- sw[0]
- end
-
- #
- # :call-seq:
- # on_tail(*params, &block)
- #
- # :include: ../doc/optparse/creates_option.rdoc
- #
- # The new option is added at the tail of the summary.
- #
- def on_tail(*opts, &block)
- define_tail(*opts, &block)
- self
- end
- alias def_tail_option define_tail
-
- #
- # Add separator in summary.
- #
- def separator(string)
- top.append(string, nil, nil)
- end
-
- #
- # Parses command line arguments +argv+ in order. When a block is given,
- # each non-option argument is yielded. When optional +into+ keyword
- # argument is provided, the parsed option values are stored there via
- # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
- # similar object).
- #
- # Returns the rest of +argv+ left unparsed.
- #
- def order(*argv, into: nil, &nonopt)
- argv = argv[0].dup if argv.size == 1 and Array === argv[0]
- order!(argv, into: into, &nonopt)
- end
-
- #
- # Same as #order, but removes switches destructively.
- # Non-option arguments remain in +argv+.
- #
- def order!(argv = default_argv, into: nil, &nonopt)
- setter = ->(name, val) {into[name.to_sym] = val} if into
- parse_in_order(argv, setter, &nonopt)
- end
-
- def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc:
- opt, arg, val, rest = nil
- nonopt ||= proc {|a| throw :terminate, a}
- argv.unshift(arg) if arg = catch(:terminate) {
- while arg = argv.shift
- case arg
- # long option
- when /\A--([^=]*)(?:=(.*))?/m
- opt, rest = $1, $2
- opt.tr!('_', '-')
- begin
- sw, = complete(:long, opt, true)
- if require_exact && !sw.long.include?(arg)
- throw :terminate, arg unless raise_unknown
- raise InvalidOption, arg
- end
- rescue ParseError
- throw :terminate, arg unless raise_unknown
- raise $!.set_option(arg, true)
- end
- begin
- opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
- val = cb.call(val) if cb
- setter.call(sw.switch_name, val) if setter
- rescue ParseError
- raise $!.set_option(arg, rest)
- end
-
- # short option
- when /\A-(.)((=).*|.+)?/m
- eq, rest, opt = $3, $2, $1
- has_arg, val = eq, rest
- begin
- sw, = search(:short, opt)
- unless sw
- begin
- sw, = complete(:short, opt)
- # short option matched.
- val = arg.delete_prefix('-')
- has_arg = true
- rescue InvalidOption
- raise if require_exact
- # if no short options match, try completion with long
- # options.
- sw, = complete(:long, opt)
- eq ||= !rest
- end
- end
- rescue ParseError
- throw :terminate, arg unless raise_unknown
- raise $!.set_option(arg, true)
- end
- begin
- opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
- rescue ParseError
- raise $!.set_option(arg, arg.length > 2)
- else
- raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
- end
- begin
- argv.unshift(opt) if opt and (!rest or (opt = opt.sub(/\A-*/, '-')) != '-')
- val = cb.call(val) if cb
- setter.call(sw.switch_name, val) if setter
- rescue ParseError
- raise $!.set_option(arg, arg.length > 2)
- end
-
- # non-option argument
- else
- catch(:prune) do
- visit(:each_option) do |sw0|
- sw = sw0
- sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)
- end
- nonopt.call(arg)
- end
- end
- end
-
- nil
- }
-
- visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}
-
- argv
- end
- private :parse_in_order
-
- #
- # Parses command line arguments +argv+ in permutation mode and returns
- # list of non-option arguments. When optional +into+ keyword
- # argument is provided, the parsed option values are stored there via
- # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
- # similar object).
- #
- def permute(*argv, into: nil)
- argv = argv[0].dup if argv.size == 1 and Array === argv[0]
- permute!(argv, into: into)
- end
-
- #
- # Same as #permute, but removes switches destructively.
- # Non-option arguments remain in +argv+.
- #
- def permute!(argv = default_argv, into: nil)
- nonopts = []
- order!(argv, into: into, &nonopts.method(:<<))
- argv[0, 0] = nonopts
- argv
- end
-
- #
- # Parses command line arguments +argv+ in order when environment variable
- # POSIXLY_CORRECT is set, and in permutation mode otherwise.
- # When optional +into+ keyword argument is provided, the parsed option
- # values are stored there via <code>[]=</code> method (so it can be Hash,
- # or OpenStruct, or other similar object).
- #
- def parse(*argv, into: nil)
- argv = argv[0].dup if argv.size == 1 and Array === argv[0]
- parse!(argv, into: into)
- end
-
- #
- # Same as #parse, but removes switches destructively.
- # Non-option arguments remain in +argv+.
- #
- def parse!(argv = default_argv, into: nil)
- if ENV.include?('POSIXLY_CORRECT')
- order!(argv, into: into)
- else
- permute!(argv, into: into)
- end
- end
-
- #
- # Wrapper method for getopts.rb.
- #
- # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option")
- # # params["a"] = true # -a
- # # params["b"] = "1" # -b1
- # # params["foo"] = "1" # --foo
- # # params["bar"] = "x" # --bar x
- # # params["zot"] = "z" # --zot Z
- #
- # Option +symbolize_names+ (boolean) specifies whether returned Hash keys should be Symbols; defaults to +false+ (use Strings).
- #
- # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option", symbolize_names: true)
- # # params[:a] = true # -a
- # # params[:b] = "1" # -b1
- # # params[:foo] = "1" # --foo
- # # params[:bar] = "x" # --bar x
- # # params[:zot] = "z" # --zot Z
- #
- def getopts(*args, symbolize_names: false)
- argv = Array === args.first ? args.shift : default_argv
- single_options, *long_options = *args
-
- result = {}
-
- single_options.scan(/(.)(:)?/) do |opt, val|
- if val
- result[opt] = nil
- define("-#{opt} VAL")
- else
- result[opt] = false
- define("-#{opt}")
- end
- end if single_options
-
- long_options.each do |arg|
- arg, desc = arg.split(';', 2)
- opt, val = arg.split(':', 2)
- if val
- result[opt] = val.empty? ? nil : val
- define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact)
- else
- result[opt] = false
- define("--#{opt}", *[desc].compact)
- end
- end
-
- parse_in_order(argv, result.method(:[]=))
- symbolize_names ? result.transform_keys(&:to_sym) : result
- end
-
- #
- # See #getopts.
- #
- def self.getopts(*args, symbolize_names: false)
- new.getopts(*args, symbolize_names: symbolize_names)
- end
-
- #
- # Traverses @stack, sending each element method +id+ with +args+ and
- # +block+.
- #
- def visit(id, *args, &block) # :nodoc:
- @stack.reverse_each do |el|
- el.__send__(id, *args, &block)
- end
- nil
- end
- private :visit
-
- #
- # Searches +key+ in @stack for +id+ hash and returns or yields the result.
- #
- def search(id, key) # :nodoc:
- block_given = block_given?
- visit(:search, id, key) do |k|
- return block_given ? yield(k) : k
- end
- end
- private :search
-
- #
- # Completes shortened long style option switch and returns pair of
- # canonical switch and switch descriptor Gem::OptionParser::Switch.
- #
- # +typ+:: Searching table.
- # +opt+:: Searching key.
- # +icase+:: Search case insensitive if true.
- # +pat+:: Optional pattern for completion.
- #
- def complete(typ, opt, icase = false, *pat) # :nodoc:
- if pat.empty?
- search(typ, opt) {|sw| return [sw, opt]} # exact match or...
- end
- ambiguous = catch(:ambiguous) {
- visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
- }
- exc = ambiguous ? AmbiguousOption : InvalidOption
- raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
- end
- private :complete
-
- #
- # Returns additional info.
- #
- def additional_message(typ, opt)
- return unless typ and opt and defined?(DidYouMean::SpellChecker)
- all_candidates = []
- visit(:get_candidates, typ) do |candidates|
- all_candidates.concat(candidates)
- end
- all_candidates.select! {|cand| cand.is_a?(String) }
- checker = DidYouMean::SpellChecker.new(dictionary: all_candidates)
- DidYouMean.formatter.message_for(all_candidates & checker.correct(opt))
- end
-
- def candidate(word)
- list = []
- case word
- when '-'
- long = short = true
- when /\A--/
- word, arg = word.split(/=/, 2)
- argpat = Completion.regexp(arg, false) if arg and !arg.empty?
- long = true
- when /\A-/
- short = true
- end
- pat = Completion.regexp(word, long)
- visit(:each_option) do |opt|
- next unless Switch === opt
- opts = (long ? opt.long : []) + (short ? opt.short : [])
- opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
- if /\A=/ =~ opt.arg
- opts.map! {|sw| sw + "="}
- if arg and CompletingHash === opt.pattern
- if opts = opt.pattern.candidate(arg, false, argpat)
- opts.map!(&:last)
- end
- end
- end
- list.concat(opts)
- end
- list
- end
-
- #
- # Loads options from file names as +filename+. Does nothing when the file
- # is not present. Returns whether successfully loaded.
- #
- # +filename+ defaults to basename of the program without suffix in a
- # directory ~/.options, then the basename with '.options' suffix
- # under XDG and Haiku standard places.
- #
- # The optional +into+ keyword argument works exactly like that accepted in
- # method #parse.
- #
- def load(filename = nil, into: nil)
- unless filename
- basename = File.basename($0, '.*')
- return true if load(File.expand_path(basename, '~/.options'), into: into) rescue nil
- basename << ".options"
- return [
- # XDG
- ENV['XDG_CONFIG_HOME'],
- '~/.config',
- *ENV['XDG_CONFIG_DIRS']&.split(File::PATH_SEPARATOR),
-
- # Haiku
- '~/config/settings',
- ].any? {|dir|
- next if !dir or dir.empty?
- load(File.expand_path(basename, dir), into: into) rescue nil
- }
- end
- begin
- parse(*File.readlines(filename, chomp: true), into: into)
- true
- rescue Errno::ENOENT, Errno::ENOTDIR
- false
- end
- end
-
- #
- # Parses environment variable +env+ or its uppercase with splitting like a
- # shell.
- #
- # +env+ defaults to the basename of the program.
- #
- def environment(env = File.basename($0, '.*'))
- env = ENV[env] || ENV[env.upcase] or return
- require 'shellwords'
- parse(*Shellwords.shellwords(env))
- end
-
- #
- # Acceptable argument classes
- #
-
- #
- # Any string and no conversion. This is fall-back.
- #
- accept(Object) {|s,|s or s.nil?}
-
- accept(NilClass) {|s,|s}
-
- #
- # Any non-empty string, and no conversion.
- #
- accept(String, /.+/m) {|s,*|s}
-
- #
- # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal
- # for 0x, and decimal for others; with optional sign prefix. Converts to
- # Integer.
- #
- decimal = '\d+(?:_\d+)*'
- binary = 'b[01]+(?:_[01]+)*'
- hex = 'x[\da-f]+(?:_[\da-f]+)*'
- octal = "0(?:[0-7]+(?:_[0-7]+)*|#{binary}|#{hex})?"
- integer = "#{octal}|#{decimal}"
-
- accept(Integer, %r"\A[-+]?(?:#{integer})\z"io) {|s,|
- begin
- Integer(s)
- rescue ArgumentError
- raise Gem::OptionParser::InvalidArgument, s
- end if s
- }
-
- #
- # Float number format, and converts to Float.
- #
- float = "(?:#{decimal}(?=(.)?)(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
- floatpat = %r"\A[-+]?#{float}\z"io
- accept(Float, floatpat) {|s,| s.to_f if s}
-
- #
- # Generic numeric format, converts to Integer for integer format, Float
- # for float format, and Rational for rational format.
- #
- real = "[-+]?(?:#{octal}|#{float})"
- accept(Numeric, /\A(#{real})(?:\/(#{real}))?\z/io) {|s, d, f, n,|
- if n
- Rational(d, n)
- elsif f
- Float(s)
- else
- Integer(s)
- end
- }
-
- #
- # Decimal integer format, to be converted to Integer.
- #
- DecimalInteger = /\A[-+]?#{decimal}\z/io
- accept(DecimalInteger, DecimalInteger) {|s,|
- begin
- Integer(s, 10)
- rescue ArgumentError
- raise Gem::OptionParser::InvalidArgument, s
- end if s
- }
-
- #
- # Ruby/C like octal/hexadecimal/binary integer format, to be converted to
- # Integer.
- #
- OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))\z/io
- accept(OctalInteger, OctalInteger) {|s,|
- begin
- Integer(s, 8)
- rescue ArgumentError
- raise Gem::OptionParser::InvalidArgument, s
- end if s
- }
-
- #
- # Decimal integer/float number format, to be converted to Integer for
- # integer format, Float for float format.
- #
- DecimalNumeric = floatpat # decimal integer is allowed as float also.
- accept(DecimalNumeric, floatpat) {|s, f|
- begin
- if f
- Float(s)
- else
- Integer(s)
- end
- rescue ArgumentError
- raise Gem::OptionParser::InvalidArgument, s
- end if s
- }
-
- #
- # Boolean switch, which means whether it is present or not, whether it is
- # absent or not with prefix no-, or it takes an argument
- # yes/no/true/false/+/-.
- #
- yesno = CompletingHash.new
- %w[- no false].each {|el| yesno[el] = false}
- %w[+ yes true].each {|el| yesno[el] = true}
- yesno['nil'] = false # should be nil?
- accept(TrueClass, yesno) {|arg, val| val == nil or val}
- #
- # Similar to TrueClass, but defaults to false.
- #
- accept(FalseClass, yesno) {|arg, val| val != nil and val}
-
- #
- # List of strings separated by ",".
- #
- accept(Array) do |s, |
- if s
- s = s.split(',').collect {|ss| ss unless ss.empty?}
- end
- s
- end
-
- #
- # Regular expression with options.
- #
- accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o|
- f = 0
- if o
- f |= Regexp::IGNORECASE if /i/ =~ o
- f |= Regexp::MULTILINE if /m/ =~ o
- f |= Regexp::EXTENDED if /x/ =~ o
- case o = o.delete("imx")
- when ""
- when "u"
- s = s.encode(Encoding::UTF_8)
- when "e"
- s = s.encode(Encoding::EUC_JP)
- when "s"
- s = s.encode(Encoding::SJIS)
- when "n"
- f |= Regexp::NOENCODING
- else
- raise Gem::OptionParser::InvalidArgument, "unknown regexp option - #{o}"
- end
- else
- s ||= all
- end
- Regexp.new(s, f)
- end
-
- #
- # Exceptions
- #
-
- #
- # Base class of exceptions from Gem::OptionParser.
- #
- class ParseError < RuntimeError
- # Reason which caused the error.
- Reason = 'parse error'
-
- def initialize(*args, additional: nil)
- @additional = additional
- @arg0, = args
- @args = args
- @reason = nil
- end
-
- attr_reader :args
- attr_writer :reason
- attr_accessor :additional
-
- #
- # Pushes back erred argument(s) to +argv+.
- #
- def recover(argv)
- argv[0, 0] = @args
- argv
- end
-
- def self.filter_backtrace(array)
- unless $DEBUG
- array.delete_if(&%r"\A#{Regexp.quote(__FILE__)}:"o.method(:=~))
- end
- array
- end
-
- def set_backtrace(array)
- super(self.class.filter_backtrace(array))
- end
-
- def set_option(opt, eq)
- if eq
- @args[0] = opt
- else
- @args.unshift(opt)
- end
- self
- end
-
- #
- # Returns error reason. Override this for I18N.
- #
- def reason
- @reason || self.class::Reason
- end
-
- def inspect
- "#<#{self.class}: #{args.join(' ')}>"
- end
-
- #
- # Default stringizing method to emit standard error message.
- #
- def message
- "#{reason}: #{args.join(' ')}#{additional[@arg0] if additional}"
- end
-
- alias to_s message
- end
-
- #
- # Raises when ambiguously completable string is encountered.
- #
- class AmbiguousOption < ParseError
- const_set(:Reason, 'ambiguous option')
- end
-
- #
- # Raises when there is an argument for a switch which takes no argument.
- #
- class NeedlessArgument < ParseError
- const_set(:Reason, 'needless argument')
- end
-
- #
- # Raises when a switch with mandatory argument has no argument.
- #
- class MissingArgument < ParseError
- const_set(:Reason, 'missing argument')
- end
-
- #
- # Raises when switch is undefined.
- #
- class InvalidOption < ParseError
- const_set(:Reason, 'invalid option')
- end
-
- #
- # Raises when the given argument does not match required format.
- #
- class InvalidArgument < ParseError
- const_set(:Reason, 'invalid argument')
- end
-
- #
- # Raises when the given argument word can't be completed uniquely.
- #
- class AmbiguousArgument < InvalidArgument
- const_set(:Reason, 'ambiguous argument')
- end
-
- #
- # Miscellaneous
- #
-
- #
- # Extends command line arguments array (ARGV) to parse itself.
- #
- module Arguable
-
- #
- # Sets Gem::OptionParser object, when +opt+ is +false+ or +nil+, methods
- # Gem::OptionParser::Arguable#options and Gem::OptionParser::Arguable#options= are
- # undefined. Thus, there is no ways to access the Gem::OptionParser object
- # via the receiver object.
- #
- def options=(opt)
- unless @optparse = opt
- class << self
- undef_method(:options)
- undef_method(:options=)
- end
- end
- end
-
- #
- # Actual Gem::OptionParser object, automatically created if nonexistent.
- #
- # If called with a block, yields the Gem::OptionParser object and returns the
- # result of the block. If an Gem::OptionParser::ParseError exception occurs
- # in the block, it is rescued, a error message printed to STDERR and
- # +nil+ returned.
- #
- def options
- @optparse ||= Gem::OptionParser.new
- @optparse.default_argv = self
- block_given? or return @optparse
- begin
- yield @optparse
- rescue ParseError
- @optparse.warn $!
- nil
- end
- end
-
- #
- # Parses +self+ destructively in order and returns +self+ containing the
- # rest arguments left unparsed.
- #
- def order!(&blk) options.order!(self, &blk) end
-
- #
- # Parses +self+ destructively in permutation mode and returns +self+
- # containing the rest arguments left unparsed.
- #
- def permute!() options.permute!(self) end
-
- #
- # Parses +self+ destructively and returns +self+ containing the
- # rest arguments left unparsed.
- #
- def parse!() options.parse!(self) end
-
- #
- # Substitution of getopts is possible as follows. Also see
- # Gem::OptionParser#getopts.
- #
- # def getopts(*args)
- # ($OPT = ARGV.getopts(*args)).each do |opt, val|
- # eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
- # end
- # rescue Gem::OptionParser::ParseError
- # end
- #
- def getopts(*args, symbolize_names: false)
- options.getopts(self, *args, symbolize_names: symbolize_names)
- end
-
- #
- # Initializes instance variable.
- #
- def self.extend_object(obj)
- super
- obj.instance_eval {@optparse = nil}
- end
- def initialize(*args)
- super
- @optparse = nil
- end
- end
-
- #
- # Acceptable argument classes. Now contains DecimalInteger, OctalInteger
- # and DecimalNumeric. See Acceptable argument classes (in source code).
- #
- module Acceptables
- const_set(:DecimalInteger, Gem::OptionParser::DecimalInteger)
- const_set(:OctalInteger, Gem::OptionParser::OctalInteger)
- const_set(:DecimalNumeric, Gem::OptionParser::DecimalNumeric)
- end
-end
-
-# ARGV is arguable by Gem::OptionParser
-ARGV.extend(Gem::OptionParser::Arguable)
diff --git a/lib/rubygems/vendor/optparse/lib/optparse/uri.rb b/lib/rubygems/vendor/optparse/lib/optparse/uri.rb
deleted file mode 100644
index 398127479a..0000000000
--- a/lib/rubygems/vendor/optparse/lib/optparse/uri.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: false
-# -*- ruby -*-
-
-require_relative '../optparse'
-require_relative '../../../uri/lib/uri'
-
-Gem::OptionParser.accept(Gem::URI) {|s,| Gem::URI.parse(s) if s}
diff --git a/lib/rubygems/vendor/resolv/.document b/lib/rubygems/vendor/resolv/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/resolv/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/resolv/lib/resolv.rb b/lib/rubygems/vendor/resolv/lib/resolv.rb
deleted file mode 100644
index 1209d5167a..0000000000
--- a/lib/rubygems/vendor/resolv/lib/resolv.rb
+++ /dev/null
@@ -1,3387 +0,0 @@
-# frozen_string_literal: true
-
-require 'socket'
-require_relative '../../timeout/lib/timeout'
-require 'io/wait'
-
-begin
- require 'securerandom'
-rescue LoadError
-end
-
-# Gem::Resolv is a thread-aware DNS resolver library written in Ruby. Gem::Resolv can
-# handle multiple DNS requests concurrently without blocking the entire Ruby
-# interpreter.
-#
-# See also resolv-replace.rb to replace the libc resolver with Gem::Resolv.
-#
-# Gem::Resolv can look up various DNS resources using the DNS module directly.
-#
-# Examples:
-#
-# p Gem::Resolv.getaddress "www.ruby-lang.org"
-# p Gem::Resolv.getname "210.251.121.214"
-#
-# Gem::Resolv::DNS.open do |dns|
-# ress = dns.getresources "www.ruby-lang.org", Gem::Resolv::DNS::Resource::IN::A
-# p ress.map(&:address)
-# ress = dns.getresources "ruby-lang.org", Gem::Resolv::DNS::Resource::IN::MX
-# p ress.map { |r| [r.exchange.to_s, r.preference] }
-# end
-#
-#
-# == Bugs
-#
-# * NIS is not supported.
-# * /etc/nsswitch.conf is not supported.
-
-class Gem::Resolv
-
- VERSION = "0.3.0"
-
- ##
- # Looks up the first IP address for +name+.
-
- def self.getaddress(name)
- DefaultResolver.getaddress(name)
- end
-
- ##
- # Looks up all IP address for +name+.
-
- def self.getaddresses(name)
- DefaultResolver.getaddresses(name)
- end
-
- ##
- # Iterates over all IP addresses for +name+.
-
- def self.each_address(name, &block)
- DefaultResolver.each_address(name, &block)
- end
-
- ##
- # Looks up the hostname of +address+.
-
- def self.getname(address)
- DefaultResolver.getname(address)
- end
-
- ##
- # Looks up all hostnames for +address+.
-
- def self.getnames(address)
- DefaultResolver.getnames(address)
- end
-
- ##
- # Iterates over all hostnames for +address+.
-
- def self.each_name(address, &proc)
- DefaultResolver.each_name(address, &proc)
- end
-
- ##
- # Creates a new Gem::Resolv using +resolvers+.
-
- def initialize(resolvers=nil, use_ipv6: nil)
- @resolvers = resolvers || [Hosts.new, DNS.new(DNS::Config.default_config_hash.merge(use_ipv6: use_ipv6))]
- end
-
- ##
- # Looks up the first IP address for +name+.
-
- def getaddress(name)
- each_address(name) {|address| return address}
- raise ResolvError.new("no address for #{name}")
- end
-
- ##
- # Looks up all IP address for +name+.
-
- def getaddresses(name)
- ret = []
- each_address(name) {|address| ret << address}
- return ret
- end
-
- ##
- # Iterates over all IP addresses for +name+.
-
- def each_address(name)
- if AddressRegex =~ name
- yield name
- return
- end
- yielded = false
- @resolvers.each {|r|
- r.each_address(name) {|address|
- yield address.to_s
- yielded = true
- }
- return if yielded
- }
- end
-
- ##
- # Looks up the hostname of +address+.
-
- def getname(address)
- each_name(address) {|name| return name}
- raise ResolvError.new("no name for #{address}")
- end
-
- ##
- # Looks up all hostnames for +address+.
-
- def getnames(address)
- ret = []
- each_name(address) {|name| ret << name}
- return ret
- end
-
- ##
- # Iterates over all hostnames for +address+.
-
- def each_name(address)
- yielded = false
- @resolvers.each {|r|
- r.each_name(address) {|name|
- yield name.to_s
- yielded = true
- }
- return if yielded
- }
- end
-
- ##
- # Indicates a failure to resolve a name or address.
-
- class ResolvError < StandardError; end
-
- ##
- # Indicates a timeout resolving a name or address.
-
- class ResolvTimeout < Gem::Timeout::Error; end
-
- ##
- # Gem::Resolv::Hosts is a hostname resolver that uses the system hosts file.
-
- class Hosts
- if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and
- begin
- require 'win32/resolv'
- DefaultFileName = Win32::Resolv.get_hosts_path || IO::NULL
- rescue LoadError
- end
- end
- DefaultFileName ||= '/etc/hosts'
-
- ##
- # Creates a new Gem::Resolv::Hosts, using +filename+ for its data source.
-
- def initialize(filename = DefaultFileName)
- @filename = filename
- @mutex = Thread::Mutex.new
- @initialized = nil
- end
-
- def lazy_initialize # :nodoc:
- @mutex.synchronize {
- unless @initialized
- @name2addr = {}
- @addr2name = {}
- File.open(@filename, 'rb') {|f|
- f.each {|line|
- line.sub!(/#.*/, '')
- addr, hostname, *aliases = line.split(/\s+/)
- next unless addr
- @addr2name[addr] = [] unless @addr2name.include? addr
- @addr2name[addr] << hostname
- @addr2name[addr].concat(aliases)
- @name2addr[hostname] = [] unless @name2addr.include? hostname
- @name2addr[hostname] << addr
- aliases.each {|n|
- @name2addr[n] = [] unless @name2addr.include? n
- @name2addr[n] << addr
- }
- }
- }
- @name2addr.each {|name, arr| arr.reverse!}
- @initialized = true
- end
- }
- self
- end
-
- ##
- # Gets the IP address of +name+ from the hosts file.
-
- def getaddress(name)
- each_address(name) {|address| return address}
- raise ResolvError.new("#{@filename} has no name: #{name}")
- end
-
- ##
- # Gets all IP addresses for +name+ from the hosts file.
-
- def getaddresses(name)
- ret = []
- each_address(name) {|address| ret << address}
- return ret
- end
-
- ##
- # Iterates over all IP addresses for +name+ retrieved from the hosts file.
-
- def each_address(name, &proc)
- lazy_initialize
- @name2addr[name]&.each(&proc)
- end
-
- ##
- # Gets the hostname of +address+ from the hosts file.
-
- def getname(address)
- each_name(address) {|name| return name}
- raise ResolvError.new("#{@filename} has no address: #{address}")
- end
-
- ##
- # Gets all hostnames for +address+ from the hosts file.
-
- def getnames(address)
- ret = []
- each_name(address) {|name| ret << name}
- return ret
- end
-
- ##
- # Iterates over all hostnames for +address+ retrieved from the hosts file.
-
- def each_name(address, &proc)
- lazy_initialize
- @addr2name[address]&.each(&proc)
- end
- end
-
- ##
- # Gem::Resolv::DNS is a DNS stub resolver.
- #
- # Information taken from the following places:
- #
- # * STD0013
- # * RFC 1035
- # * ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters
- # * etc.
-
- class DNS
-
- ##
- # Default DNS Port
-
- Port = 53
-
- ##
- # Default DNS UDP packet size
-
- UDPSize = 512
-
- ##
- # Creates a new DNS resolver. See Gem::Resolv::DNS.new for argument details.
- #
- # Yields the created DNS resolver to the block, if given, otherwise
- # returns it.
-
- def self.open(*args)
- dns = new(*args)
- return dns unless block_given?
- begin
- yield dns
- ensure
- dns.close
- end
- end
-
- ##
- # Creates a new DNS resolver.
- #
- # +config_info+ can be:
- #
- # nil:: Uses /etc/resolv.conf.
- # String:: Path to a file using /etc/resolv.conf's format.
- # Hash:: Must contain :nameserver, :search and :ndots keys.
- # :nameserver_port can be used to specify port number of nameserver address.
- # :raise_timeout_errors can be used to raise timeout errors
- # as exceptions instead of treating the same as an NXDOMAIN response.
- #
- # The value of :nameserver should be an address string or
- # an array of address strings.
- # - :nameserver => '8.8.8.8'
- # - :nameserver => ['8.8.8.8', '8.8.4.4']
- #
- # The value of :nameserver_port should be an array of
- # pair of nameserver address and port number.
- # - :nameserver_port => [['8.8.8.8', 53], ['8.8.4.4', 53]]
- #
- # Example:
- #
- # Gem::Resolv::DNS.new(:nameserver => ['210.251.121.21'],
- # :search => ['ruby-lang.org'],
- # :ndots => 1)
-
- def initialize(config_info=nil)
- @mutex = Thread::Mutex.new
- @config = Config.new(config_info)
- @initialized = nil
- end
-
- # Sets the resolver timeouts. This may be a single positive number
- # or an array of positive numbers representing timeouts in seconds.
- # If an array is specified, a DNS request will retry and wait for
- # each successive interval in the array until a successful response
- # is received. Specifying +nil+ reverts to the default timeouts:
- # [ 5, second = 5 * 2 / nameserver_count, 2 * second, 4 * second ]
- #
- # Example:
- #
- # dns.timeouts = 3
- #
- def timeouts=(values)
- @config.timeouts = values
- end
-
- def lazy_initialize # :nodoc:
- @mutex.synchronize {
- unless @initialized
- @config.lazy_initialize
- @initialized = true
- end
- }
- self
- end
-
- ##
- # Closes the DNS resolver.
-
- def close
- @mutex.synchronize {
- if @initialized
- @initialized = false
- end
- }
- end
-
- ##
- # Gets the IP address of +name+ from the DNS resolver.
- #
- # +name+ can be a Gem::Resolv::DNS::Name or a String. Retrieved address will
- # be a Gem::Resolv::IPv4 or Gem::Resolv::IPv6
-
- def getaddress(name)
- each_address(name) {|address| return address}
- raise ResolvError.new("DNS result has no information for #{name}")
- end
-
- ##
- # Gets all IP addresses for +name+ from the DNS resolver.
- #
- # +name+ can be a Gem::Resolv::DNS::Name or a String. Retrieved addresses will
- # be a Gem::Resolv::IPv4 or Gem::Resolv::IPv6
-
- def getaddresses(name)
- ret = []
- each_address(name) {|address| ret << address}
- return ret
- end
-
- ##
- # Iterates over all IP addresses for +name+ retrieved from the DNS
- # resolver.
- #
- # +name+ can be a Gem::Resolv::DNS::Name or a String. Retrieved addresses will
- # be a Gem::Resolv::IPv4 or Gem::Resolv::IPv6
-
- def each_address(name)
- each_resource(name, Resource::IN::A) {|resource| yield resource.address}
- if use_ipv6?
- each_resource(name, Resource::IN::AAAA) {|resource| yield resource.address}
- end
- end
-
- def use_ipv6? # :nodoc:
- use_ipv6 = @config.use_ipv6?
- unless use_ipv6.nil?
- return use_ipv6
- end
-
- begin
- list = Socket.ip_address_list
- rescue NotImplementedError
- return true
- end
- list.any? {|a| a.ipv6? && !a.ipv6_loopback? && !a.ipv6_linklocal? }
- end
- private :use_ipv6?
-
- ##
- # Gets the hostname for +address+ from the DNS resolver.
- #
- # +address+ must be a Gem::Resolv::IPv4, Gem::Resolv::IPv6 or a String. Retrieved
- # name will be a Gem::Resolv::DNS::Name.
-
- def getname(address)
- each_name(address) {|name| return name}
- raise ResolvError.new("DNS result has no information for #{address}")
- end
-
- ##
- # Gets all hostnames for +address+ from the DNS resolver.
- #
- # +address+ must be a Gem::Resolv::IPv4, Gem::Resolv::IPv6 or a String. Retrieved
- # names will be Gem::Resolv::DNS::Name instances.
-
- def getnames(address)
- ret = []
- each_name(address) {|name| ret << name}
- return ret
- end
-
- ##
- # Iterates over all hostnames for +address+ retrieved from the DNS
- # resolver.
- #
- # +address+ must be a Gem::Resolv::IPv4, Gem::Resolv::IPv6 or a String. Retrieved
- # names will be Gem::Resolv::DNS::Name instances.
-
- def each_name(address)
- case address
- when Name
- ptr = address
- when IPv4, IPv6
- ptr = address.to_name
- when IPv4::Regex
- ptr = IPv4.create(address).to_name
- when IPv6::Regex
- ptr = IPv6.create(address).to_name
- else
- raise ResolvError.new("cannot interpret as address: #{address}")
- end
- each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
- end
-
- ##
- # Look up the +typeclass+ DNS resource of +name+.
- #
- # +name+ must be a Gem::Resolv::DNS::Name or a String.
- #
- # +typeclass+ should be one of the following:
- #
- # * Gem::Resolv::DNS::Resource::IN::A
- # * Gem::Resolv::DNS::Resource::IN::AAAA
- # * Gem::Resolv::DNS::Resource::IN::ANY
- # * Gem::Resolv::DNS::Resource::IN::CNAME
- # * Gem::Resolv::DNS::Resource::IN::HINFO
- # * Gem::Resolv::DNS::Resource::IN::MINFO
- # * Gem::Resolv::DNS::Resource::IN::MX
- # * Gem::Resolv::DNS::Resource::IN::NS
- # * Gem::Resolv::DNS::Resource::IN::PTR
- # * Gem::Resolv::DNS::Resource::IN::SOA
- # * Gem::Resolv::DNS::Resource::IN::TXT
- # * Gem::Resolv::DNS::Resource::IN::WKS
- #
- # Returned resource is represented as a Gem::Resolv::DNS::Resource instance,
- # i.e. Gem::Resolv::DNS::Resource::IN::A.
-
- def getresource(name, typeclass)
- each_resource(name, typeclass) {|resource| return resource}
- raise ResolvError.new("DNS result has no information for #{name}")
- end
-
- ##
- # Looks up all +typeclass+ DNS resources for +name+. See #getresource for
- # argument details.
-
- def getresources(name, typeclass)
- ret = []
- each_resource(name, typeclass) {|resource| ret << resource}
- return ret
- end
-
- ##
- # Iterates over all +typeclass+ DNS resources for +name+. See
- # #getresource for argument details.
-
- def each_resource(name, typeclass, &proc)
- fetch_resource(name, typeclass) {|reply, reply_name|
- extract_resources(reply, reply_name, typeclass, &proc)
- }
- end
-
- def fetch_resource(name, typeclass)
- lazy_initialize
- begin
- requester = make_udp_requester
- rescue Errno::EACCES
- # fall back to TCP
- end
- senders = {}
- begin
- @config.resolv(name) {|candidate, tout, nameserver, port|
- requester ||= make_tcp_requester(nameserver, port)
- msg = Message.new
- msg.rd = 1
- msg.add_question(candidate, typeclass)
- unless sender = senders[[candidate, nameserver, port]]
- sender = requester.sender(msg, candidate, nameserver, port)
- next if !sender
- senders[[candidate, nameserver, port]] = sender
- end
- reply, reply_name = requester.request(sender, tout)
- case reply.rcode
- when RCode::NoError
- if reply.tc == 1 and not Requester::TCP === requester
- requester.close
- # Retry via TCP:
- requester = make_tcp_requester(nameserver, port)
- senders = {}
- # This will use TCP for all remaining candidates (assuming the
- # current candidate does not already respond successfully via
- # TCP). This makes sense because we already know the full
- # response will not fit in an untruncated UDP packet.
- redo
- else
- yield(reply, reply_name)
- end
- return
- when RCode::NXDomain
- raise Config::NXDomain.new(reply_name.to_s)
- else
- raise Config::OtherResolvError.new(reply_name.to_s)
- end
- }
- ensure
- requester&.close
- end
- end
-
- def make_udp_requester # :nodoc:
- nameserver_port = @config.nameserver_port
- if nameserver_port.length == 1
- Requester::ConnectedUDP.new(*nameserver_port[0])
- else
- Requester::UnconnectedUDP.new(*nameserver_port)
- end
- end
-
- def make_tcp_requester(host, port) # :nodoc:
- return Requester::TCP.new(host, port)
- end
-
- def extract_resources(msg, name, typeclass) # :nodoc:
- if typeclass < Resource::ANY
- n0 = Name.create(name)
- msg.each_resource {|n, ttl, data|
- yield data if n0 == n
- }
- end
- yielded = false
- n0 = Name.create(name)
- msg.each_resource {|n, ttl, data|
- if n0 == n
- case data
- when typeclass
- yield data
- yielded = true
- when Resource::CNAME
- n0 = data.name
- end
- end
- }
- return if yielded
- msg.each_resource {|n, ttl, data|
- if n0 == n
- case data
- when typeclass
- yield data
- end
- end
- }
- end
-
- if defined? SecureRandom
- def self.random(arg) # :nodoc:
- begin
- SecureRandom.random_number(arg)
- rescue NotImplementedError
- rand(arg)
- end
- end
- else
- def self.random(arg) # :nodoc:
- rand(arg)
- end
- end
-
- RequestID = {} # :nodoc:
- RequestIDMutex = Thread::Mutex.new # :nodoc:
-
- def self.allocate_request_id(host, port) # :nodoc:
- id = nil
- RequestIDMutex.synchronize {
- h = (RequestID[[host, port]] ||= {})
- begin
- id = random(0x0000..0xffff)
- end while h[id]
- h[id] = true
- }
- id
- end
-
- def self.free_request_id(host, port, id) # :nodoc:
- RequestIDMutex.synchronize {
- key = [host, port]
- if h = RequestID[key]
- h.delete id
- if h.empty?
- RequestID.delete key
- end
- end
- }
- end
-
- def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc:
- begin
- port = random(1024..65535)
- udpsock.bind(bind_host, port)
- rescue Errno::EADDRINUSE, # POSIX
- Errno::EACCES, # SunOS: See PRIV_SYS_NFS in privileges(5)
- Errno::EPERM # FreeBSD: security.mac.portacl.port_high is configurable. See mac_portacl(4).
- retry
- end
- end
-
- class Requester # :nodoc:
- def initialize
- @senders = {}
- @socks = nil
- end
-
- def request(sender, tout)
- start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- timelimit = start + tout
- begin
- sender.send
- rescue Errno::EHOSTUNREACH, # multi-homed IPv6 may generate this
- Errno::ENETUNREACH
- raise ResolvTimeout
- end
- while true
- before_select = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- timeout = timelimit - before_select
- if timeout <= 0
- raise ResolvTimeout
- end
- if @socks.size == 1
- select_result = @socks[0].wait_readable(timeout) ? [ @socks ] : nil
- else
- select_result = IO.select(@socks, nil, nil, timeout)
- end
- if !select_result
- after_select = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- next if after_select < timelimit
- raise ResolvTimeout
- end
- begin
- reply, from = recv_reply(select_result[0])
- rescue Errno::ECONNREFUSED, # GNU/Linux, FreeBSD
- Errno::ECONNRESET # Windows
- # No name server running on the server?
- # Don't wait anymore.
- raise ResolvTimeout
- end
- begin
- msg = Message.decode(reply)
- rescue DecodeError
- next # broken DNS message ignored
- end
- if sender == sender_for(from, msg)
- break
- else
- # unexpected DNS message ignored
- end
- end
- return msg, sender.data
- end
-
- def sender_for(addr, msg)
- @senders[[addr,msg.id]]
- end
-
- def close
- socks = @socks
- @socks = nil
- socks&.each(&:close)
- end
-
- class Sender # :nodoc:
- def initialize(msg, data, sock)
- @msg = msg
- @data = data
- @sock = sock
- end
- end
-
- class UnconnectedUDP < Requester # :nodoc:
- def initialize(*nameserver_port)
- super()
- @nameserver_port = nameserver_port
- @initialized = false
- @mutex = Thread::Mutex.new
- end
-
- def lazy_initialize
- @mutex.synchronize {
- next if @initialized
- @initialized = true
- @socks_hash = {}
- @socks = []
- @nameserver_port.each {|host, port|
- if host.index(':')
- bind_host = "::"
- af = Socket::AF_INET6
- else
- bind_host = "0.0.0.0"
- af = Socket::AF_INET
- end
- next if @socks_hash[bind_host]
- begin
- sock = UDPSocket.new(af)
- rescue Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT
- next # The kernel doesn't support the address family.
- end
- @socks << sock
- @socks_hash[bind_host] = sock
- sock.do_not_reverse_lookup = true
- DNS.bind_random_port(sock, bind_host)
- }
- }
- self
- end
-
- def recv_reply(readable_socks)
- lazy_initialize
- reply, from = readable_socks[0].recvfrom(UDPSize)
- return reply, [from[3],from[1]]
- end
-
- def sender(msg, data, host, port=Port)
- host = Addrinfo.ip(host).ip_address
- lazy_initialize
- sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
- return nil if !sock
- service = [host, port]
- id = DNS.allocate_request_id(host, port)
- request = msg.encode
- request[0,2] = [id].pack('n')
- return @senders[[service, id]] =
- Sender.new(request, data, sock, host, port)
- end
-
- def close
- @mutex.synchronize {
- if @initialized
- super
- @senders.each_key {|service, id|
- DNS.free_request_id(service[0], service[1], id)
- }
- @initialized = false
- end
- }
- end
-
- class Sender < Requester::Sender # :nodoc:
- def initialize(msg, data, sock, host, port)
- super(msg, data, sock)
- @host = host
- @port = port
- end
- attr_reader :data
-
- def send
- raise "@sock is nil." if @sock.nil?
- @sock.send(@msg, 0, @host, @port)
- end
- end
- end
-
- class ConnectedUDP < Requester # :nodoc:
- def initialize(host, port=Port)
- super()
- @host = host
- @port = port
- @mutex = Thread::Mutex.new
- @initialized = false
- end
-
- def lazy_initialize
- @mutex.synchronize {
- next if @initialized
- @initialized = true
- is_ipv6 = @host.index(':')
- sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
- @socks = [sock]
- sock.do_not_reverse_lookup = true
- DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0")
- sock.connect(@host, @port)
- }
- self
- end
-
- def recv_reply(readable_socks)
- lazy_initialize
- reply = readable_socks[0].recv(UDPSize)
- return reply, nil
- end
-
- def sender(msg, data, host=@host, port=@port)
- lazy_initialize
- unless host == @host && port == @port
- raise RequestError.new("host/port don't match: #{host}:#{port}")
- end
- id = DNS.allocate_request_id(@host, @port)
- request = msg.encode
- request[0,2] = [id].pack('n')
- return @senders[[nil,id]] = Sender.new(request, data, @socks[0])
- end
-
- def close
- @mutex.synchronize do
- if @initialized
- super
- @senders.each_key {|from, id|
- DNS.free_request_id(@host, @port, id)
- }
- @initialized = false
- end
- end
- end
-
- class Sender < Requester::Sender # :nodoc:
- def send
- raise "@sock is nil." if @sock.nil?
- @sock.send(@msg, 0)
- end
- attr_reader :data
- end
- end
-
- class MDNSOneShot < UnconnectedUDP # :nodoc:
- def sender(msg, data, host, port=Port)
- lazy_initialize
- id = DNS.allocate_request_id(host, port)
- request = msg.encode
- request[0,2] = [id].pack('n')
- sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
- return @senders[id] =
- UnconnectedUDP::Sender.new(request, data, sock, host, port)
- end
-
- def sender_for(addr, msg)
- lazy_initialize
- @senders[msg.id]
- end
- end
-
- class TCP < Requester # :nodoc:
- def initialize(host, port=Port)
- super()
- @host = host
- @port = port
- sock = TCPSocket.new(@host, @port)
- @socks = [sock]
- @senders = {}
- end
-
- def recv_reply(readable_socks)
- len = readable_socks[0].read(2).unpack('n')[0]
- reply = @socks[0].read(len)
- return reply, nil
- end
-
- def sender(msg, data, host=@host, port=@port)
- unless host == @host && port == @port
- raise RequestError.new("host/port don't match: #{host}:#{port}")
- end
- id = DNS.allocate_request_id(@host, @port)
- request = msg.encode
- request[0,2] = [request.length, id].pack('nn')
- return @senders[[nil,id]] = Sender.new(request, data, @socks[0])
- end
-
- class Sender < Requester::Sender # :nodoc:
- def send
- @sock.print(@msg)
- @sock.flush
- end
- attr_reader :data
- end
-
- def close
- super
- @senders.each_key {|from,id|
- DNS.free_request_id(@host, @port, id)
- }
- end
- end
-
- ##
- # Indicates a problem with the DNS request.
-
- class RequestError < StandardError
- end
- end
-
- class Config # :nodoc:
- def initialize(config_info=nil)
- @mutex = Thread::Mutex.new
- @config_info = config_info
- @initialized = nil
- @timeouts = nil
- end
-
- def timeouts=(values)
- if values
- values = Array(values)
- values.each do |t|
- Numeric === t or raise ArgumentError, "#{t.inspect} is not numeric"
- t > 0.0 or raise ArgumentError, "timeout=#{t} must be positive"
- end
- @timeouts = values
- else
- @timeouts = nil
- end
- end
-
- def Config.parse_resolv_conf(filename)
- nameserver = []
- search = nil
- ndots = 1
- File.open(filename, 'rb') {|f|
- f.each {|line|
- line.sub!(/[#;].*/, '')
- keyword, *args = line.split(/\s+/)
- next unless keyword
- case keyword
- when 'nameserver'
- nameserver.concat(args)
- when 'domain'
- next if args.empty?
- search = [args[0]]
- when 'search'
- next if args.empty?
- search = args
- when 'options'
- args.each {|arg|
- case arg
- when /\Andots:(\d+)\z/
- ndots = $1.to_i
- end
- }
- end
- }
- }
- return { :nameserver => nameserver, :search => search, :ndots => ndots }
- end
-
- def Config.default_config_hash(filename="/etc/resolv.conf")
- if File.exist? filename
- config_hash = Config.parse_resolv_conf(filename)
- else
- if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
- require 'win32/resolv'
- search, nameserver = Win32::Resolv.get_resolv_info
- config_hash = {}
- config_hash[:nameserver] = nameserver if nameserver
- config_hash[:search] = [search].flatten if search
- end
- end
- config_hash || {}
- end
-
- def lazy_initialize
- @mutex.synchronize {
- unless @initialized
- @nameserver_port = []
- @use_ipv6 = nil
- @search = nil
- @ndots = 1
- case @config_info
- when nil
- config_hash = Config.default_config_hash
- when String
- config_hash = Config.parse_resolv_conf(@config_info)
- when Hash
- config_hash = @config_info.dup
- if String === config_hash[:nameserver]
- config_hash[:nameserver] = [config_hash[:nameserver]]
- end
- if String === config_hash[:search]
- config_hash[:search] = [config_hash[:search]]
- end
- else
- raise ArgumentError.new("invalid resolv configuration: #{@config_info.inspect}")
- end
- if config_hash.include? :nameserver
- @nameserver_port = config_hash[:nameserver].map {|ns| [ns, Port] }
- end
- if config_hash.include? :nameserver_port
- @nameserver_port = config_hash[:nameserver_port].map {|ns, port| [ns, (port || Port)] }
- end
- if config_hash.include? :use_ipv6
- @use_ipv6 = config_hash[:use_ipv6]
- end
- @search = config_hash[:search] if config_hash.include? :search
- @ndots = config_hash[:ndots] if config_hash.include? :ndots
- @raise_timeout_errors = config_hash[:raise_timeout_errors]
-
- if @nameserver_port.empty?
- @nameserver_port << ['0.0.0.0', Port]
- end
- if @search
- @search = @search.map {|arg| Label.split(arg) }
- else
- hostname = Socket.gethostname
- if /\./ =~ hostname
- @search = [Label.split($')]
- else
- @search = [[]]
- end
- end
-
- if !@nameserver_port.kind_of?(Array) ||
- @nameserver_port.any? {|ns_port|
- !(Array === ns_port) ||
- ns_port.length != 2
- !(String === ns_port[0]) ||
- !(Integer === ns_port[1])
- }
- raise ArgumentError.new("invalid nameserver config: #{@nameserver_port.inspect}")
- end
-
- if !@search.kind_of?(Array) ||
- !@search.all? {|ls| ls.all? {|l| Label::Str === l } }
- raise ArgumentError.new("invalid search config: #{@search.inspect}")
- end
-
- if !@ndots.kind_of?(Integer)
- raise ArgumentError.new("invalid ndots config: #{@ndots.inspect}")
- end
-
- @initialized = true
- end
- }
- self
- end
-
- def single?
- lazy_initialize
- if @nameserver_port.length == 1
- return @nameserver_port[0]
- else
- return nil
- end
- end
-
- def nameserver_port
- @nameserver_port
- end
-
- def use_ipv6?
- @use_ipv6
- end
-
- def generate_candidates(name)
- candidates = nil
- name = Name.create(name)
- if name.absolute?
- candidates = [name]
- else
- if @ndots <= name.length - 1
- candidates = [Name.new(name.to_a)]
- else
- candidates = []
- end
- candidates.concat(@search.map {|domain| Name.new(name.to_a + domain)})
- fname = Name.create("#{name}.")
- if !candidates.include?(fname)
- candidates << fname
- end
- end
- return candidates
- end
-
- InitialTimeout = 5
-
- def generate_timeouts
- ts = [InitialTimeout]
- ts << ts[-1] * 2 / @nameserver_port.length
- ts << ts[-1] * 2
- ts << ts[-1] * 2
- return ts
- end
-
- def resolv(name)
- candidates = generate_candidates(name)
- timeouts = @timeouts || generate_timeouts
- timeout_error = false
- begin
- candidates.each {|candidate|
- begin
- timeouts.each {|tout|
- @nameserver_port.each {|nameserver, port|
- begin
- yield candidate, tout, nameserver, port
- rescue ResolvTimeout
- end
- }
- }
- timeout_error = true
- raise ResolvError.new("DNS resolv timeout: #{name}")
- rescue NXDomain
- end
- }
- rescue ResolvError
- raise if @raise_timeout_errors && timeout_error
- end
- end
-
- ##
- # Indicates no such domain was found.
-
- class NXDomain < ResolvError
- end
-
- ##
- # Indicates some other unhandled resolver error was encountered.
-
- class OtherResolvError < ResolvError
- end
- end
-
- module OpCode # :nodoc:
- Query = 0
- IQuery = 1
- Status = 2
- Notify = 4
- Update = 5
- end
-
- module RCode # :nodoc:
- NoError = 0
- FormErr = 1
- ServFail = 2
- NXDomain = 3
- NotImp = 4
- Refused = 5
- YXDomain = 6
- YXRRSet = 7
- NXRRSet = 8
- NotAuth = 9
- NotZone = 10
- BADVERS = 16
- BADSIG = 16
- BADKEY = 17
- BADTIME = 18
- BADMODE = 19
- BADNAME = 20
- BADALG = 21
- end
-
- ##
- # Indicates that the DNS response was unable to be decoded.
-
- class DecodeError < StandardError
- end
-
- ##
- # Indicates that the DNS request was unable to be encoded.
-
- class EncodeError < StandardError
- end
-
- module Label # :nodoc:
- def self.split(arg)
- labels = []
- arg.scan(/[^\.]+/) {labels << Str.new($&)}
- return labels
- end
-
- class Str # :nodoc:
- def initialize(string)
- @string = string
- # case insensivity of DNS labels doesn't apply non-ASCII characters. [RFC 4343]
- # This assumes @string is given in ASCII compatible encoding.
- @downcase = string.b.downcase
- end
- attr_reader :string, :downcase
-
- def to_s
- return @string
- end
-
- def inspect
- return "#<#{self.class} #{self}>"
- end
-
- def ==(other)
- return self.class == other.class && @downcase == other.downcase
- end
-
- def eql?(other)
- return self == other
- end
-
- def hash
- return @downcase.hash
- end
- end
- end
-
- ##
- # A representation of a DNS name.
-
- class Name
-
- ##
- # Creates a new DNS name from +arg+. +arg+ can be:
- #
- # Name:: returns +arg+.
- # String:: Creates a new Name.
-
- def self.create(arg)
- case arg
- when Name
- return arg
- when String
- return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false)
- else
- raise ArgumentError.new("cannot interpret as DNS name: #{arg.inspect}")
- end
- end
-
- def initialize(labels, absolute=true) # :nodoc:
- labels = labels.map {|label|
- case label
- when String then Label::Str.new(label)
- when Label::Str then label
- else
- raise ArgumentError, "unexpected label: #{label.inspect}"
- end
- }
- @labels = labels
- @absolute = absolute
- end
-
- def inspect # :nodoc:
- "#<#{self.class}: #{self}#{@absolute ? '.' : ''}>"
- end
-
- ##
- # True if this name is absolute.
-
- def absolute?
- return @absolute
- end
-
- def ==(other) # :nodoc:
- return false unless Name === other
- return false unless @absolute == other.absolute?
- return @labels == other.to_a
- end
-
- alias eql? == # :nodoc:
-
- ##
- # Returns true if +other+ is a subdomain.
- #
- # Example:
- #
- # domain = Gem::Resolv::DNS::Name.create("y.z")
- # p Gem::Resolv::DNS::Name.create("w.x.y.z").subdomain_of?(domain) #=> true
- # p Gem::Resolv::DNS::Name.create("x.y.z").subdomain_of?(domain) #=> true
- # p Gem::Resolv::DNS::Name.create("y.z").subdomain_of?(domain) #=> false
- # p Gem::Resolv::DNS::Name.create("z").subdomain_of?(domain) #=> false
- # p Gem::Resolv::DNS::Name.create("x.y.z.").subdomain_of?(domain) #=> false
- # p Gem::Resolv::DNS::Name.create("w.z").subdomain_of?(domain) #=> false
- #
-
- def subdomain_of?(other)
- raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other
- return false if @absolute != other.absolute?
- other_len = other.length
- return false if @labels.length <= other_len
- return @labels[-other_len, other_len] == other.to_a
- end
-
- def hash # :nodoc:
- return @labels.hash ^ @absolute.hash
- end
-
- def to_a # :nodoc:
- return @labels
- end
-
- def length # :nodoc:
- return @labels.length
- end
-
- def [](i) # :nodoc:
- return @labels[i]
- end
-
- ##
- # returns the domain name as a string.
- #
- # The domain name doesn't have a trailing dot even if the name object is
- # absolute.
- #
- # Example:
- #
- # p Gem::Resolv::DNS::Name.create("x.y.z.").to_s #=> "x.y.z"
- # p Gem::Resolv::DNS::Name.create("x.y.z").to_s #=> "x.y.z"
-
- def to_s
- return @labels.join('.')
- end
- end
-
- class Message # :nodoc:
- @@identifier = -1
-
- def initialize(id = (@@identifier += 1) & 0xffff)
- @id = id
- @qr = 0
- @opcode = 0
- @aa = 0
- @tc = 0
- @rd = 0 # recursion desired
- @ra = 0 # recursion available
- @rcode = 0
- @question = []
- @answer = []
- @authority = []
- @additional = []
- end
-
- attr_accessor :id, :qr, :opcode, :aa, :tc, :rd, :ra, :rcode
- attr_reader :question, :answer, :authority, :additional
-
- def ==(other)
- return @id == other.id &&
- @qr == other.qr &&
- @opcode == other.opcode &&
- @aa == other.aa &&
- @tc == other.tc &&
- @rd == other.rd &&
- @ra == other.ra &&
- @rcode == other.rcode &&
- @question == other.question &&
- @answer == other.answer &&
- @authority == other.authority &&
- @additional == other.additional
- end
-
- def add_question(name, typeclass)
- @question << [Name.create(name), typeclass]
- end
-
- def each_question
- @question.each {|name, typeclass|
- yield name, typeclass
- }
- end
-
- def add_answer(name, ttl, data)
- @answer << [Name.create(name), ttl, data]
- end
-
- def each_answer
- @answer.each {|name, ttl, data|
- yield name, ttl, data
- }
- end
-
- def add_authority(name, ttl, data)
- @authority << [Name.create(name), ttl, data]
- end
-
- def each_authority
- @authority.each {|name, ttl, data|
- yield name, ttl, data
- }
- end
-
- def add_additional(name, ttl, data)
- @additional << [Name.create(name), ttl, data]
- end
-
- def each_additional
- @additional.each {|name, ttl, data|
- yield name, ttl, data
- }
- end
-
- def each_resource
- each_answer {|name, ttl, data| yield name, ttl, data}
- each_authority {|name, ttl, data| yield name, ttl, data}
- each_additional {|name, ttl, data| yield name, ttl, data}
- end
-
- def encode
- return MessageEncoder.new {|msg|
- msg.put_pack('nnnnnn',
- @id,
- (@qr & 1) << 15 |
- (@opcode & 15) << 11 |
- (@aa & 1) << 10 |
- (@tc & 1) << 9 |
- (@rd & 1) << 8 |
- (@ra & 1) << 7 |
- (@rcode & 15),
- @question.length,
- @answer.length,
- @authority.length,
- @additional.length)
- @question.each {|q|
- name, typeclass = q
- msg.put_name(name)
- msg.put_pack('nn', typeclass::TypeValue, typeclass::ClassValue)
- }
- [@answer, @authority, @additional].each {|rr|
- rr.each {|r|
- name, ttl, data = r
- msg.put_name(name)
- msg.put_pack('nnN', data.class::TypeValue, data.class::ClassValue, ttl)
- msg.put_length16 {data.encode_rdata(msg)}
- }
- }
- }.to_s
- end
-
- class MessageEncoder # :nodoc:
- def initialize
- @data = ''.dup
- @names = {}
- yield self
- end
-
- def to_s
- return @data
- end
-
- def put_bytes(d)
- @data << d
- end
-
- def put_pack(template, *d)
- @data << d.pack(template)
- end
-
- def put_length16
- length_index = @data.length
- @data << "\0\0"
- data_start = @data.length
- yield
- data_end = @data.length
- @data[length_index, 2] = [data_end - data_start].pack("n")
- end
-
- def put_string(d)
- self.put_pack("C", d.length)
- @data << d
- end
-
- def put_string_list(ds)
- ds.each {|d|
- self.put_string(d)
- }
- end
-
- def put_name(d, compress: true)
- put_labels(d.to_a, compress: compress)
- end
-
- def put_labels(d, compress: true)
- d.each_index {|i|
- domain = d[i..-1]
- if compress && idx = @names[domain]
- self.put_pack("n", 0xc000 | idx)
- return
- else
- if @data.length < 0x4000
- @names[domain] = @data.length
- end
- self.put_label(d[i])
- end
- }
- @data << "\0"
- end
-
- def put_label(d)
- self.put_string(d.to_s)
- end
- end
-
- def Message.decode(m)
- o = Message.new(0)
- MessageDecoder.new(m) {|msg|
- id, flag, qdcount, ancount, nscount, arcount =
- msg.get_unpack('nnnnnn')
- o.id = id
- o.tc = (flag >> 9) & 1
- o.rcode = flag & 15
- return o unless o.tc.zero?
-
- o.qr = (flag >> 15) & 1
- o.opcode = (flag >> 11) & 15
- o.aa = (flag >> 10) & 1
- o.rd = (flag >> 8) & 1
- o.ra = (flag >> 7) & 1
- (1..qdcount).each {
- name, typeclass = msg.get_question
- o.add_question(name, typeclass)
- }
- (1..ancount).each {
- name, ttl, data = msg.get_rr
- o.add_answer(name, ttl, data)
- }
- (1..nscount).each {
- name, ttl, data = msg.get_rr
- o.add_authority(name, ttl, data)
- }
- (1..arcount).each {
- name, ttl, data = msg.get_rr
- o.add_additional(name, ttl, data)
- }
- }
- return o
- end
-
- class MessageDecoder # :nodoc:
- def initialize(data)
- @data = data
- @index = 0
- @limit = data.bytesize
- yield self
- end
-
- def inspect
- "\#<#{self.class}: #{@data.byteslice(0, @index).inspect} #{@data.byteslice(@index..-1).inspect}>"
- end
-
- def get_length16
- len, = self.get_unpack('n')
- save_limit = @limit
- @limit = @index + len
- d = yield(len)
- if @index < @limit
- raise DecodeError.new("junk exists")
- elsif @limit < @index
- raise DecodeError.new("limit exceeded")
- end
- @limit = save_limit
- return d
- end
-
- def get_bytes(len = @limit - @index)
- raise DecodeError.new("limit exceeded") if @limit < @index + len
- d = @data.byteslice(@index, len)
- @index += len
- return d
- end
-
- def get_unpack(template)
- len = 0
- template.each_byte {|byte|
- byte = "%c" % byte
- case byte
- when ?c, ?C
- len += 1
- when ?n
- len += 2
- when ?N
- len += 4
- else
- raise StandardError.new("unsupported template: '#{byte.chr}' in '#{template}'")
- end
- }
- raise DecodeError.new("limit exceeded") if @limit < @index + len
- arr = @data.unpack("@#{@index}#{template}")
- @index += len
- return arr
- end
-
- def get_string
- raise DecodeError.new("limit exceeded") if @limit <= @index
- len = @data.getbyte(@index)
- raise DecodeError.new("limit exceeded") if @limit < @index + 1 + len
- d = @data.byteslice(@index + 1, len)
- @index += 1 + len
- return d
- end
-
- def get_string_list
- strings = []
- while @index < @limit
- strings << self.get_string
- end
- strings
- end
-
- def get_list
- [].tap do |values|
- while @index < @limit
- values << yield
- end
- end
- end
-
- def get_name
- return Name.new(self.get_labels)
- end
-
- def get_labels
- prev_index = @index
- save_index = nil
- d = []
- while true
- raise DecodeError.new("limit exceeded") if @limit <= @index
- case @data.getbyte(@index)
- when 0
- @index += 1
- if save_index
- @index = save_index
- end
- return d
- when 192..255
- idx = self.get_unpack('n')[0] & 0x3fff
- if prev_index <= idx
- raise DecodeError.new("non-backward name pointer")
- end
- prev_index = idx
- if !save_index
- save_index = @index
- end
- @index = idx
- else
- d << self.get_label
- end
- end
- end
-
- def get_label
- return Label::Str.new(self.get_string)
- end
-
- def get_question
- name = self.get_name
- type, klass = self.get_unpack("nn")
- return name, Resource.get_class(type, klass)
- end
-
- def get_rr
- name = self.get_name
- type, klass, ttl = self.get_unpack('nnN')
- typeclass = Resource.get_class(type, klass)
- res = self.get_length16 do
- begin
- typeclass.decode_rdata self
- rescue => e
- raise DecodeError, e.message, e.backtrace
- end
- end
- res.instance_variable_set :@ttl, ttl
- return name, ttl, res
- end
- end
- end
-
- ##
- # SvcParams for service binding RRs. [RFC9460]
-
- class SvcParams
- include Enumerable
-
- ##
- # Create a list of SvcParams with the given initial content.
- #
- # +params+ has to be an enumerable of +SvcParam+s.
- # If its content has +SvcParam+s with the duplicate key,
- # the one appears last takes precedence.
-
- def initialize(params = [])
- @params = {}
-
- params.each do |param|
- add param
- end
- end
-
- ##
- # Get SvcParam for the given +key+ in this list.
-
- def [](key)
- @params[canonical_key(key)]
- end
-
- ##
- # Get the number of SvcParams in this list.
-
- def count
- @params.count
- end
-
- ##
- # Get whether this list is empty.
-
- def empty?
- @params.empty?
- end
-
- ##
- # Add the SvcParam +param+ to this list, overwriting the existing one with the same key.
-
- def add(param)
- @params[param.class.key_number] = param
- end
-
- ##
- # Remove the +SvcParam+ with the given +key+ and return it.
-
- def delete(key)
- @params.delete(canonical_key(key))
- end
-
- ##
- # Enumerate the +SvcParam+s in this list.
-
- def each(&block)
- return enum_for(:each) unless block
- @params.each_value(&block)
- end
-
- def encode(msg) # :nodoc:
- @params.keys.sort.each do |key|
- msg.put_pack('n', key)
- msg.put_length16 do
- @params.fetch(key).encode(msg)
- end
- end
- end
-
- def self.decode(msg) # :nodoc:
- params = msg.get_list do
- key, = msg.get_unpack('n')
- msg.get_length16 do
- SvcParam::ClassHash[key].decode(msg)
- end
- end
-
- return self.new(params)
- end
-
- private
-
- def canonical_key(key) # :nodoc:
- case key
- when Integer
- key
- when /\Akey(\d+)\z/
- Integer($1)
- when Symbol
- SvcParam::ClassHash[key].key_number
- else
- raise TypeError, 'key must be either String or Symbol'
- end
- end
- end
-
-
- ##
- # Base class for SvcParam. [RFC9460]
-
- class SvcParam
-
- ##
- # Get the presentation name of the SvcParamKey.
-
- def self.key_name
- const_get(:KeyName)
- end
-
- ##
- # Get the registered number of the SvcParamKey.
-
- def self.key_number
- const_get(:KeyNumber)
- end
-
- ClassHash = Hash.new do |h, key| # :nodoc:
- case key
- when Integer
- Generic.create(key)
- when /\Akey(?<key>\d+)\z/
- Generic.create(key.to_int)
- when Symbol
- raise KeyError, "unknown key #{key}"
- else
- raise TypeError, 'key must be either String or Symbol'
- end
- end
-
- ##
- # Generic SvcParam abstract class.
-
- class Generic < SvcParam
-
- ##
- # SvcParamValue in wire-format byte string.
-
- attr_reader :value
-
- ##
- # Create generic SvcParam
-
- def initialize(value)
- @value = value
- end
-
- def encode(msg) # :nodoc:
- msg.put_bytes(@value)
- end
-
- def self.decode(msg) # :nodoc:
- return self.new(msg.get_bytes)
- end
-
- def self.create(key_number)
- c = Class.new(Generic)
- key_name = :"key#{key_number}"
- c.const_set(:KeyName, key_name)
- c.const_set(:KeyNumber, key_number)
- self.const_set(:"Key#{key_number}", c)
- ClassHash[key_name] = ClassHash[key_number] = c
- return c
- end
- end
-
- ##
- # "mandatory" SvcParam -- Mandatory keys in service binding RR
-
- class Mandatory < SvcParam
- KeyName = :mandatory
- KeyNumber = 0
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Mandatory keys.
-
- attr_reader :keys
-
- ##
- # Initialize "mandatory" ScvParam.
-
- def initialize(keys)
- @keys = keys.map(&:to_int)
- end
-
- def encode(msg) # :nodoc:
- @keys.sort.each do |key|
- msg.put_pack('n', key)
- end
- end
-
- def self.decode(msg) # :nodoc:
- keys = msg.get_list { msg.get_unpack('n')[0] }
- return self.new(keys)
- end
- end
-
- ##
- # "alpn" SvcParam -- Additional supported protocols
-
- class ALPN < SvcParam
- KeyName = :alpn
- KeyNumber = 1
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Supported protocol IDs.
-
- attr_reader :protocol_ids
-
- ##
- # Initialize "alpn" ScvParam.
-
- def initialize(protocol_ids)
- @protocol_ids = protocol_ids.map(&:to_str)
- end
-
- def encode(msg) # :nodoc:
- msg.put_string_list(@protocol_ids)
- end
-
- def self.decode(msg) # :nodoc:
- return self.new(msg.get_string_list)
- end
- end
-
- ##
- # "no-default-alpn" SvcParam -- No support for default protocol
-
- class NoDefaultALPN < SvcParam
- KeyName = :'no-default-alpn'
- KeyNumber = 2
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- def encode(msg) # :nodoc:
- # no payload
- end
-
- def self.decode(msg) # :nodoc:
- return self.new
- end
- end
-
- ##
- # "port" SvcParam -- Port for alternative endpoint
-
- class Port < SvcParam
- KeyName = :port
- KeyNumber = 3
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Port number.
-
- attr_reader :port
-
- ##
- # Initialize "port" ScvParam.
-
- def initialize(port)
- @port = port.to_int
- end
-
- def encode(msg) # :nodoc:
- msg.put_pack('n', @port)
- end
-
- def self.decode(msg) # :nodoc:
- port, = msg.get_unpack('n')
- return self.new(port)
- end
- end
-
- ##
- # "ipv4hint" SvcParam -- IPv4 address hints
-
- class IPv4Hint < SvcParam
- KeyName = :ipv4hint
- KeyNumber = 4
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Set of IPv4 addresses.
-
- attr_reader :addresses
-
- ##
- # Initialize "ipv4hint" ScvParam.
-
- def initialize(addresses)
- @addresses = addresses.map {|address| IPv4.create(address) }
- end
-
- def encode(msg) # :nodoc:
- @addresses.each do |address|
- msg.put_bytes(address.address)
- end
- end
-
- def self.decode(msg) # :nodoc:
- addresses = msg.get_list { IPv4.new(msg.get_bytes(4)) }
- return self.new(addresses)
- end
- end
-
- ##
- # "ipv6hint" SvcParam -- IPv6 address hints
-
- class IPv6Hint < SvcParam
- KeyName = :ipv6hint
- KeyNumber = 6
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # Set of IPv6 addresses.
-
- attr_reader :addresses
-
- ##
- # Initialize "ipv6hint" ScvParam.
-
- def initialize(addresses)
- @addresses = addresses.map {|address| IPv6.create(address) }
- end
-
- def encode(msg) # :nodoc:
- @addresses.each do |address|
- msg.put_bytes(address.address)
- end
- end
-
- def self.decode(msg) # :nodoc:
- addresses = msg.get_list { IPv6.new(msg.get_bytes(16)) }
- return self.new(addresses)
- end
- end
-
- ##
- # "dohpath" SvcParam -- DNS over HTTPS path template [RFC9461]
-
- class DoHPath < SvcParam
- KeyName = :dohpath
- KeyNumber = 7
- ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
-
- ##
- # URI template for DoH queries.
-
- attr_reader :template
-
- ##
- # Initialize "dohpath" ScvParam.
-
- def initialize(template)
- @template = template.encode('utf-8')
- end
-
- def encode(msg) # :nodoc:
- msg.put_bytes(@template)
- end
-
- def self.decode(msg) # :nodoc:
- template = msg.get_bytes.force_encoding('utf-8')
- return self.new(template)
- end
- end
- end
-
- ##
- # A DNS query abstract class.
-
- class Query
- def encode_rdata(msg) # :nodoc:
- raise EncodeError.new("#{self.class} is query.")
- end
-
- def self.decode_rdata(msg) # :nodoc:
- raise DecodeError.new("#{self.class} is query.")
- end
- end
-
- ##
- # A DNS resource abstract class.
-
- class Resource < Query
-
- ##
- # Remaining Time To Live for this Resource.
-
- attr_reader :ttl
-
- ClassHash = {} # :nodoc:
-
- def encode_rdata(msg) # :nodoc:
- raise NotImplementedError.new
- end
-
- def self.decode_rdata(msg) # :nodoc:
- raise NotImplementedError.new
- end
-
- def ==(other) # :nodoc:
- return false unless self.class == other.class
- s_ivars = self.instance_variables
- s_ivars.sort!
- s_ivars.delete :@ttl
- o_ivars = other.instance_variables
- o_ivars.sort!
- o_ivars.delete :@ttl
- return s_ivars == o_ivars &&
- s_ivars.collect {|name| self.instance_variable_get name} ==
- o_ivars.collect {|name| other.instance_variable_get name}
- end
-
- def eql?(other) # :nodoc:
- return self == other
- end
-
- def hash # :nodoc:
- h = 0
- vars = self.instance_variables
- vars.delete :@ttl
- vars.each {|name|
- h ^= self.instance_variable_get(name).hash
- }
- return h
- end
-
- def self.get_class(type_value, class_value) # :nodoc:
- return ClassHash[[type_value, class_value]] ||
- Generic.create(type_value, class_value)
- end
-
- ##
- # A generic resource abstract class.
-
- class Generic < Resource
-
- ##
- # Creates a new generic resource.
-
- def initialize(data)
- @data = data
- end
-
- ##
- # Data for this generic resource.
-
- attr_reader :data
-
- def encode_rdata(msg) # :nodoc:
- msg.put_bytes(data)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- return self.new(msg.get_bytes)
- end
-
- def self.create(type_value, class_value) # :nodoc:
- c = Class.new(Generic)
- c.const_set(:TypeValue, type_value)
- c.const_set(:ClassValue, class_value)
- Generic.const_set("Type#{type_value}_Class#{class_value}", c)
- ClassHash[[type_value, class_value]] = c
- return c
- end
- end
-
- ##
- # Domain Name resource abstract class.
-
- class DomainName < Resource
-
- ##
- # Creates a new DomainName from +name+.
-
- def initialize(name)
- @name = name
- end
-
- ##
- # The name of this DomainName.
-
- attr_reader :name
-
- def encode_rdata(msg) # :nodoc:
- msg.put_name(@name)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- return self.new(msg.get_name)
- end
- end
-
- # Standard (class generic) RRs
-
- ClassValue = nil # :nodoc:
-
- ##
- # An authoritative name server.
-
- class NS < DomainName
- TypeValue = 2 # :nodoc:
- end
-
- ##
- # The canonical name for an alias.
-
- class CNAME < DomainName
- TypeValue = 5 # :nodoc:
- end
-
- ##
- # Start Of Authority resource.
-
- class SOA < Resource
-
- TypeValue = 6 # :nodoc:
-
- ##
- # Creates a new SOA record. See the attr documentation for the
- # details of each argument.
-
- def initialize(mname, rname, serial, refresh, retry_, expire, minimum)
- @mname = mname
- @rname = rname
- @serial = serial
- @refresh = refresh
- @retry = retry_
- @expire = expire
- @minimum = minimum
- end
-
- ##
- # Name of the host where the master zone file for this zone resides.
-
- attr_reader :mname
-
- ##
- # The person responsible for this domain name.
-
- attr_reader :rname
-
- ##
- # The version number of the zone file.
-
- attr_reader :serial
-
- ##
- # How often, in seconds, a secondary name server is to check for
- # updates from the primary name server.
-
- attr_reader :refresh
-
- ##
- # How often, in seconds, a secondary name server is to retry after a
- # failure to check for a refresh.
-
- attr_reader :retry
-
- ##
- # Time in seconds that a secondary name server is to use the data
- # before refreshing from the primary name server.
-
- attr_reader :expire
-
- ##
- # The minimum number of seconds to be used for TTL values in RRs.
-
- attr_reader :minimum
-
- def encode_rdata(msg) # :nodoc:
- msg.put_name(@mname)
- msg.put_name(@rname)
- msg.put_pack('NNNNN', @serial, @refresh, @retry, @expire, @minimum)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- mname = msg.get_name
- rname = msg.get_name
- serial, refresh, retry_, expire, minimum = msg.get_unpack('NNNNN')
- return self.new(
- mname, rname, serial, refresh, retry_, expire, minimum)
- end
- end
-
- ##
- # A Pointer to another DNS name.
-
- class PTR < DomainName
- TypeValue = 12 # :nodoc:
- end
-
- ##
- # Host Information resource.
-
- class HINFO < Resource
-
- TypeValue = 13 # :nodoc:
-
- ##
- # Creates a new HINFO running +os+ on +cpu+.
-
- def initialize(cpu, os)
- @cpu = cpu
- @os = os
- end
-
- ##
- # CPU architecture for this resource.
-
- attr_reader :cpu
-
- ##
- # Operating system for this resource.
-
- attr_reader :os
-
- def encode_rdata(msg) # :nodoc:
- msg.put_string(@cpu)
- msg.put_string(@os)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- cpu = msg.get_string
- os = msg.get_string
- return self.new(cpu, os)
- end
- end
-
- ##
- # Mailing list or mailbox information.
-
- class MINFO < Resource
-
- TypeValue = 14 # :nodoc:
-
- def initialize(rmailbx, emailbx)
- @rmailbx = rmailbx
- @emailbx = emailbx
- end
-
- ##
- # Domain name responsible for this mail list or mailbox.
-
- attr_reader :rmailbx
-
- ##
- # Mailbox to use for error messages related to the mail list or mailbox.
-
- attr_reader :emailbx
-
- def encode_rdata(msg) # :nodoc:
- msg.put_name(@rmailbx)
- msg.put_name(@emailbx)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- rmailbx = msg.get_string
- emailbx = msg.get_string
- return self.new(rmailbx, emailbx)
- end
- end
-
- ##
- # Mail Exchanger resource.
-
- class MX < Resource
-
- TypeValue= 15 # :nodoc:
-
- ##
- # Creates a new MX record with +preference+, accepting mail at
- # +exchange+.
-
- def initialize(preference, exchange)
- @preference = preference
- @exchange = exchange
- end
-
- ##
- # The preference for this MX.
-
- attr_reader :preference
-
- ##
- # The host of this MX.
-
- attr_reader :exchange
-
- def encode_rdata(msg) # :nodoc:
- msg.put_pack('n', @preference)
- msg.put_name(@exchange)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- preference, = msg.get_unpack('n')
- exchange = msg.get_name
- return self.new(preference, exchange)
- end
- end
-
- ##
- # Unstructured text resource.
-
- class TXT < Resource
-
- TypeValue = 16 # :nodoc:
-
- def initialize(first_string, *rest_strings)
- @strings = [first_string, *rest_strings]
- end
-
- ##
- # Returns an Array of Strings for this TXT record.
-
- attr_reader :strings
-
- ##
- # Returns the concatenated string from +strings+.
-
- def data
- @strings.join("")
- end
-
- def encode_rdata(msg) # :nodoc:
- msg.put_string_list(@strings)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- strings = msg.get_string_list
- return self.new(*strings)
- end
- end
-
- ##
- # Location resource
-
- class LOC < Resource
-
- TypeValue = 29 # :nodoc:
-
- def initialize(version, ssize, hprecision, vprecision, latitude, longitude, altitude)
- @version = version
- @ssize = Gem::Resolv::LOC::Size.create(ssize)
- @hprecision = Gem::Resolv::LOC::Size.create(hprecision)
- @vprecision = Gem::Resolv::LOC::Size.create(vprecision)
- @latitude = Gem::Resolv::LOC::Coord.create(latitude)
- @longitude = Gem::Resolv::LOC::Coord.create(longitude)
- @altitude = Gem::Resolv::LOC::Alt.create(altitude)
- end
-
- ##
- # Returns the version value for this LOC record which should always be 00
-
- attr_reader :version
-
- ##
- # The spherical size of this LOC
- # in meters using scientific notation as 2 integers of XeY
-
- attr_reader :ssize
-
- ##
- # The horizontal precision using ssize type values
- # in meters using scientific notation as 2 integers of XeY
- # for precision use value/2 e.g. 2m = +/-1m
-
- attr_reader :hprecision
-
- ##
- # The vertical precision using ssize type values
- # in meters using scientific notation as 2 integers of XeY
- # for precision use value/2 e.g. 2m = +/-1m
-
- attr_reader :vprecision
-
- ##
- # The latitude for this LOC where 2**31 is the equator
- # in thousandths of an arc second as an unsigned 32bit integer
-
- attr_reader :latitude
-
- ##
- # The longitude for this LOC where 2**31 is the prime meridian
- # in thousandths of an arc second as an unsigned 32bit integer
-
- attr_reader :longitude
-
- ##
- # The altitude of the LOC above a reference sphere whose surface sits 100km below the WGS84 spheroid
- # in centimeters as an unsigned 32bit integer
-
- attr_reader :altitude
-
-
- def encode_rdata(msg) # :nodoc:
- msg.put_bytes(@version)
- msg.put_bytes(@ssize.scalar)
- msg.put_bytes(@hprecision.scalar)
- msg.put_bytes(@vprecision.scalar)
- msg.put_bytes(@latitude.coordinates)
- msg.put_bytes(@longitude.coordinates)
- msg.put_bytes(@altitude.altitude)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- version = msg.get_bytes(1)
- ssize = msg.get_bytes(1)
- hprecision = msg.get_bytes(1)
- vprecision = msg.get_bytes(1)
- latitude = msg.get_bytes(4)
- longitude = msg.get_bytes(4)
- altitude = msg.get_bytes(4)
- return self.new(
- version,
- Gem::Resolv::LOC::Size.new(ssize),
- Gem::Resolv::LOC::Size.new(hprecision),
- Gem::Resolv::LOC::Size.new(vprecision),
- Gem::Resolv::LOC::Coord.new(latitude,"lat"),
- Gem::Resolv::LOC::Coord.new(longitude,"lon"),
- Gem::Resolv::LOC::Alt.new(altitude)
- )
- end
- end
-
- ##
- # A Query type requesting any RR.
-
- class ANY < Query
- TypeValue = 255 # :nodoc:
- end
-
- ClassInsensitiveTypes = [ # :nodoc:
- NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, LOC, ANY
- ]
-
- ##
- # module IN contains ARPA Internet specific RRs.
-
- module IN
-
- ClassValue = 1 # :nodoc:
-
- ClassInsensitiveTypes.each {|s|
- c = Class.new(s)
- c.const_set(:TypeValue, s::TypeValue)
- c.const_set(:ClassValue, ClassValue)
- ClassHash[[s::TypeValue, ClassValue]] = c
- self.const_set(s.name.sub(/.*::/, ''), c)
- }
-
- ##
- # IPv4 Address resource
-
- class A < Resource
- TypeValue = 1
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
-
- ##
- # Creates a new A for +address+.
-
- def initialize(address)
- @address = IPv4.create(address)
- end
-
- ##
- # The Gem::Resolv::IPv4 address for this A.
-
- attr_reader :address
-
- def encode_rdata(msg) # :nodoc:
- msg.put_bytes(@address.address)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- return self.new(IPv4.new(msg.get_bytes(4)))
- end
- end
-
- ##
- # Well Known Service resource.
-
- class WKS < Resource
- TypeValue = 11
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
-
- def initialize(address, protocol, bitmap)
- @address = IPv4.create(address)
- @protocol = protocol
- @bitmap = bitmap
- end
-
- ##
- # The host these services run on.
-
- attr_reader :address
-
- ##
- # IP protocol number for these services.
-
- attr_reader :protocol
-
- ##
- # A bit map of enabled services on this host.
- #
- # If protocol is 6 (TCP) then the 26th bit corresponds to the SMTP
- # service (port 25). If this bit is set, then an SMTP server should
- # be listening on TCP port 25; if zero, SMTP service is not
- # supported.
-
- attr_reader :bitmap
-
- def encode_rdata(msg) # :nodoc:
- msg.put_bytes(@address.address)
- msg.put_pack("n", @protocol)
- msg.put_bytes(@bitmap)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- address = IPv4.new(msg.get_bytes(4))
- protocol, = msg.get_unpack("n")
- bitmap = msg.get_bytes
- return self.new(address, protocol, bitmap)
- end
- end
-
- ##
- # An IPv6 address record.
-
- class AAAA < Resource
- TypeValue = 28
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
-
- ##
- # Creates a new AAAA for +address+.
-
- def initialize(address)
- @address = IPv6.create(address)
- end
-
- ##
- # The Gem::Resolv::IPv6 address for this AAAA.
-
- attr_reader :address
-
- def encode_rdata(msg) # :nodoc:
- msg.put_bytes(@address.address)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- return self.new(IPv6.new(msg.get_bytes(16)))
- end
- end
-
- ##
- # SRV resource record defined in RFC 2782
- #
- # These records identify the hostname and port that a service is
- # available at.
-
- class SRV < Resource
- TypeValue = 33
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
-
- # Create a SRV resource record.
- #
- # See the documentation for #priority, #weight, #port and #target
- # for +priority+, +weight+, +port and +target+ respectively.
-
- def initialize(priority, weight, port, target)
- @priority = priority.to_int
- @weight = weight.to_int
- @port = port.to_int
- @target = Name.create(target)
- end
-
- # The priority of this target host.
- #
- # A client MUST attempt to contact the target host with the
- # lowest-numbered priority it can reach; target hosts with the same
- # priority SHOULD be tried in an order defined by the weight field.
- # The range is 0-65535. Note that it is not widely implemented and
- # should be set to zero.
-
- attr_reader :priority
-
- # A server selection mechanism.
- #
- # The weight field specifies a relative weight for entries with the
- # same priority. Larger weights SHOULD be given a proportionately
- # higher probability of being selected. The range of this number is
- # 0-65535. Domain administrators SHOULD use Weight 0 when there
- # isn't any server selection to do, to make the RR easier to read
- # for humans (less noisy). Note that it is not widely implemented
- # and should be set to zero.
-
- attr_reader :weight
-
- # The port on this target host of this service.
- #
- # The range is 0-65535.
-
- attr_reader :port
-
- # The domain name of the target host.
- #
- # A target of "." means that the service is decidedly not available
- # at this domain.
-
- attr_reader :target
-
- def encode_rdata(msg) # :nodoc:
- msg.put_pack("n", @priority)
- msg.put_pack("n", @weight)
- msg.put_pack("n", @port)
- msg.put_name(@target, compress: false)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- priority, = msg.get_unpack("n")
- weight, = msg.get_unpack("n")
- port, = msg.get_unpack("n")
- target = msg.get_name
- return self.new(priority, weight, port, target)
- end
- end
-
- ##
- # Common implementation for SVCB-compatible resource records.
-
- class ServiceBinding
-
- ##
- # Create a service binding resource record.
-
- def initialize(priority, target, params = [])
- @priority = priority.to_int
- @target = Name.create(target)
- @params = SvcParams.new(params)
- end
-
- ##
- # The priority of this target host.
- #
- # The range is 0-65535.
- # If set to 0, this RR is in AliasMode. Otherwise, it is in ServiceMode.
-
- attr_reader :priority
-
- ##
- # The domain name of the target host.
-
- attr_reader :target
-
- ##
- # The service paramters for the target host.
-
- attr_reader :params
-
- ##
- # Whether this RR is in AliasMode.
-
- def alias_mode?
- self.priority == 0
- end
-
- ##
- # Whether this RR is in ServiceMode.
-
- def service_mode?
- !alias_mode?
- end
-
- def encode_rdata(msg) # :nodoc:
- msg.put_pack("n", @priority)
- msg.put_name(@target, compress: false)
- @params.encode(msg)
- end
-
- def self.decode_rdata(msg) # :nodoc:
- priority, = msg.get_unpack("n")
- target = msg.get_name
- params = SvcParams.decode(msg)
- return self.new(priority, target, params)
- end
- end
-
- ##
- # SVCB resource record [RFC9460]
-
- class SVCB < ServiceBinding
- TypeValue = 64
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
- end
-
- ##
- # HTTPS resource record [RFC9460]
-
- class HTTPS < ServiceBinding
- TypeValue = 65
- ClassValue = IN::ClassValue
- ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
- end
- end
- end
- end
-
- ##
- # A Gem::Resolv::DNS IPv4 address.
-
- class IPv4
-
- ##
- # Regular expression IPv4 addresses must match.
-
- Regex256 = /0
- |1(?:[0-9][0-9]?)?
- |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
- |[3-9][0-9]?/x
- Regex = /\A(#{Regex256})\.(#{Regex256})\.(#{Regex256})\.(#{Regex256})\z/
-
- def self.create(arg)
- case arg
- when IPv4
- return arg
- when Regex
- if (0..255) === (a = $1.to_i) &&
- (0..255) === (b = $2.to_i) &&
- (0..255) === (c = $3.to_i) &&
- (0..255) === (d = $4.to_i)
- return self.new([a, b, c, d].pack("CCCC"))
- else
- raise ArgumentError.new("IPv4 address with invalid value: " + arg)
- end
- else
- raise ArgumentError.new("cannot interpret as IPv4 address: #{arg.inspect}")
- end
- end
-
- def initialize(address) # :nodoc:
- unless address.kind_of?(String)
- raise ArgumentError, 'IPv4 address must be a string'
- end
- unless address.length == 4
- raise ArgumentError, "IPv4 address expects 4 bytes but #{address.length} bytes"
- end
- @address = address
- end
-
- ##
- # A String representation of this IPv4 address.
-
- ##
- # The raw IPv4 address as a String.
-
- attr_reader :address
-
- def to_s # :nodoc:
- return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC"))
- end
-
- def inspect # :nodoc:
- return "#<#{self.class} #{self}>"
- end
-
- ##
- # Turns this IPv4 address into a Gem::Resolv::DNS::Name.
-
- def to_name
- return DNS::Name.create(
- '%d.%d.%d.%d.in-addr.arpa.' % @address.unpack('CCCC').reverse)
- end
-
- def ==(other) # :nodoc:
- return @address == other.address
- end
-
- def eql?(other) # :nodoc:
- return self == other
- end
-
- def hash # :nodoc:
- return @address.hash
- end
- end
-
- ##
- # A Gem::Resolv::DNS IPv6 address.
-
- class IPv6
-
- ##
- # IPv6 address format a:b:c:d:e:f:g:h
- Regex_8Hex = /\A
- (?:[0-9A-Fa-f]{1,4}:){7}
- [0-9A-Fa-f]{1,4}
- \z/x
-
- ##
- # Compressed IPv6 address format a::b
-
- Regex_CompressedHex = /\A
- ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
- ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
- \z/x
-
- ##
- # IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z
-
- Regex_6Hex4Dec = /\A
- ((?:[0-9A-Fa-f]{1,4}:){6,6})
- (\d+)\.(\d+)\.(\d+)\.(\d+)
- \z/x
-
- ##
- # Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z
-
- Regex_CompressedHex4Dec = /\A
- ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
- ((?:[0-9A-Fa-f]{1,4}:)*)
- (\d+)\.(\d+)\.(\d+)\.(\d+)
- \z/x
-
- ##
- # IPv6 link local address format fe80:b:c:d:e:f:g:h%em1
- Regex_8HexLinkLocal = /\A
- [Ff][Ee]80
- (?::[0-9A-Fa-f]{1,4}){7}
- %[-0-9A-Za-z._~]+
- \z/x
-
- ##
- # Compressed IPv6 link local address format fe80::b%em1
-
- Regex_CompressedHexLinkLocal = /\A
- [Ff][Ee]80:
- (?:
- ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
- ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
- |
- :((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
- )?
- :[0-9A-Fa-f]{1,4}%[-0-9A-Za-z._~]+
- \z/x
-
- ##
- # A composite IPv6 address Regexp.
-
- Regex = /
- (?:#{Regex_8Hex}) |
- (?:#{Regex_CompressedHex}) |
- (?:#{Regex_6Hex4Dec}) |
- (?:#{Regex_CompressedHex4Dec}) |
- (?:#{Regex_8HexLinkLocal}) |
- (?:#{Regex_CompressedHexLinkLocal})
- /x
-
- ##
- # Creates a new IPv6 address from +arg+ which may be:
- #
- # IPv6:: returns +arg+.
- # String:: +arg+ must match one of the IPv6::Regex* constants
-
- def self.create(arg)
- case arg
- when IPv6
- return arg
- when String
- address = ''.b
- if Regex_8Hex =~ arg
- arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
- elsif Regex_CompressedHex =~ arg
- prefix = $1
- suffix = $2
- a1 = ''.b
- a2 = ''.b
- prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
- suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
- omitlen = 16 - a1.length - a2.length
- address << a1 << "\0" * omitlen << a2
- elsif Regex_6Hex4Dec =~ arg
- prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i
- if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
- prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
- address << [a, b, c, d].pack('CCCC')
- else
- raise ArgumentError.new("not numeric IPv6 address: " + arg)
- end
- elsif Regex_CompressedHex4Dec =~ arg
- prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
- if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
- a1 = ''.b
- a2 = ''.b
- prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
- suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
- omitlen = 12 - a1.length - a2.length
- address << a1 << "\0" * omitlen << a2 << [a, b, c, d].pack('CCCC')
- else
- raise ArgumentError.new("not numeric IPv6 address: " + arg)
- end
- else
- raise ArgumentError.new("not numeric IPv6 address: " + arg)
- end
- return IPv6.new(address)
- else
- raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
- end
- end
-
- def initialize(address) # :nodoc:
- unless address.kind_of?(String) && address.length == 16
- raise ArgumentError.new('IPv6 address must be 16 bytes')
- end
- @address = address
- end
-
- ##
- # The raw IPv6 address as a String.
-
- attr_reader :address
-
- def to_s # :nodoc:
- sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn")).sub(/(^|:)0(:0)+(:|$)/, '::')
- end
-
- def inspect # :nodoc:
- return "#<#{self.class} #{self}>"
- end
-
- ##
- # Turns this IPv6 address into a Gem::Resolv::DNS::Name.
- #--
- # ip6.arpa should be searched too. [RFC3152]
-
- def to_name
- return DNS::Name.new(
- @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
- end
-
- def ==(other) # :nodoc:
- return @address == other.address
- end
-
- def eql?(other) # :nodoc:
- return self == other
- end
-
- def hash # :nodoc:
- return @address.hash
- end
- end
-
- ##
- # Gem::Resolv::MDNS is a one-shot Multicast DNS (mDNS) resolver. It blindly
- # makes queries to the mDNS addresses without understanding anything about
- # multicast ports.
- #
- # Information taken form the following places:
- #
- # * RFC 6762
-
- class MDNS < DNS
-
- ##
- # Default mDNS Port
-
- Port = 5353
-
- ##
- # Default IPv4 mDNS address
-
- AddressV4 = '224.0.0.251'
-
- ##
- # Default IPv6 mDNS address
-
- AddressV6 = 'ff02::fb'
-
- ##
- # Default mDNS addresses
-
- Addresses = [
- [AddressV4, Port],
- [AddressV6, Port],
- ]
-
- ##
- # Creates a new one-shot Multicast DNS (mDNS) resolver.
- #
- # +config_info+ can be:
- #
- # nil::
- # Uses the default mDNS addresses
- #
- # Hash::
- # Must contain :nameserver or :nameserver_port like
- # Gem::Resolv::DNS#initialize.
-
- def initialize(config_info=nil)
- if config_info then
- super({ nameserver_port: Addresses }.merge(config_info))
- else
- super(nameserver_port: Addresses)
- end
- end
-
- ##
- # Iterates over all IP addresses for +name+ retrieved from the mDNS
- # resolver, provided name ends with "local". If the name does not end in
- # "local" no records will be returned.
- #
- # +name+ can be a Gem::Resolv::DNS::Name or a String. Retrieved addresses will
- # be a Gem::Resolv::IPv4 or Gem::Resolv::IPv6
-
- def each_address(name)
- name = Gem::Resolv::DNS::Name.create(name)
-
- return unless name[-1].to_s == 'local'
-
- super(name)
- end
-
- def make_udp_requester # :nodoc:
- nameserver_port = @config.nameserver_port
- Requester::MDNSOneShot.new(*nameserver_port)
- end
-
- end
-
- module LOC
-
- ##
- # A Gem::Resolv::LOC::Size
-
- class Size
-
- Regex = /^(\d+\.*\d*)[m]$/
-
- ##
- # Creates a new LOC::Size from +arg+ which may be:
- #
- # LOC::Size:: returns +arg+.
- # String:: +arg+ must match the LOC::Size::Regex constant
-
- def self.create(arg)
- case arg
- when Size
- return arg
- when String
- scalar = ''
- if Regex =~ arg
- scalar = [(($1.to_f*(1e2)).to_i.to_s[0].to_i*(2**4)+(($1.to_f*(1e2)).to_i.to_s.length-1))].pack("C")
- else
- raise ArgumentError.new("not a properly formed Size string: " + arg)
- end
- return Size.new(scalar)
- else
- raise ArgumentError.new("cannot interpret as Size: #{arg.inspect}")
- end
- end
-
- def initialize(scalar)
- @scalar = scalar
- end
-
- ##
- # The raw size
-
- attr_reader :scalar
-
- def to_s # :nodoc:
- s = @scalar.unpack("H2").join.to_s
- return ((s[0].to_i)*(10**(s[1].to_i-2))).to_s << "m"
- end
-
- def inspect # :nodoc:
- return "#<#{self.class} #{self}>"
- end
-
- def ==(other) # :nodoc:
- return @scalar == other.scalar
- end
-
- def eql?(other) # :nodoc:
- return self == other
- end
-
- def hash # :nodoc:
- return @scalar.hash
- end
-
- end
-
- ##
- # A Gem::Resolv::LOC::Coord
-
- class Coord
-
- Regex = /^(\d+)\s(\d+)\s(\d+\.\d+)\s([NESW])$/
-
- ##
- # Creates a new LOC::Coord from +arg+ which may be:
- #
- # LOC::Coord:: returns +arg+.
- # String:: +arg+ must match the LOC::Coord::Regex constant
-
- def self.create(arg)
- case arg
- when Coord
- return arg
- when String
- coordinates = ''
- if Regex =~ arg && $1.to_f < 180
- m = $~
- hemi = (m[4][/[NE]/]) || (m[4][/[SW]/]) ? 1 : -1
- coordinates = [ ((m[1].to_i*(36e5)) + (m[2].to_i*(6e4)) +
- (m[3].to_f*(1e3))) * hemi+(2**31) ].pack("N")
- orientation = m[4][/[NS]/] ? 'lat' : 'lon'
- else
- raise ArgumentError.new("not a properly formed Coord string: " + arg)
- end
- return Coord.new(coordinates,orientation)
- else
- raise ArgumentError.new("cannot interpret as Coord: #{arg.inspect}")
- end
- end
-
- def initialize(coordinates,orientation)
- unless coordinates.kind_of?(String)
- raise ArgumentError.new("Coord must be a 32bit unsigned integer in hex format: #{coordinates.inspect}")
- end
- unless orientation.kind_of?(String) && orientation[/^lon$|^lat$/]
- raise ArgumentError.new('Coord expects orientation to be a String argument of "lat" or "lon"')
- end
- @coordinates = coordinates
- @orientation = orientation
- end
-
- ##
- # The raw coordinates
-
- attr_reader :coordinates
-
- ## The orientation of the hemisphere as 'lat' or 'lon'
-
- attr_reader :orientation
-
- def to_s # :nodoc:
- c = @coordinates.unpack("N").join.to_i
- val = (c - (2**31)).abs
- fracsecs = (val % 1e3).to_i.to_s
- val = val / 1e3
- secs = (val % 60).to_i.to_s
- val = val / 60
- mins = (val % 60).to_i.to_s
- degs = (val / 60).to_i.to_s
- posi = (c >= 2**31)
- case posi
- when true
- hemi = @orientation[/^lat$/] ? "N" : "E"
- else
- hemi = @orientation[/^lon$/] ? "W" : "S"
- end
- return degs << " " << mins << " " << secs << "." << fracsecs << " " << hemi
- end
-
- def inspect # :nodoc:
- return "#<#{self.class} #{self}>"
- end
-
- def ==(other) # :nodoc:
- return @coordinates == other.coordinates
- end
-
- def eql?(other) # :nodoc:
- return self == other
- end
-
- def hash # :nodoc:
- return @coordinates.hash
- end
-
- end
-
- ##
- # A Gem::Resolv::LOC::Alt
-
- class Alt
-
- Regex = /^([+-]*\d+\.*\d*)[m]$/
-
- ##
- # Creates a new LOC::Alt from +arg+ which may be:
- #
- # LOC::Alt:: returns +arg+.
- # String:: +arg+ must match the LOC::Alt::Regex constant
-
- def self.create(arg)
- case arg
- when Alt
- return arg
- when String
- altitude = ''
- if Regex =~ arg
- altitude = [($1.to_f*(1e2))+(1e7)].pack("N")
- else
- raise ArgumentError.new("not a properly formed Alt string: " + arg)
- end
- return Alt.new(altitude)
- else
- raise ArgumentError.new("cannot interpret as Alt: #{arg.inspect}")
- end
- end
-
- def initialize(altitude)
- @altitude = altitude
- end
-
- ##
- # The raw altitude
-
- attr_reader :altitude
-
- def to_s # :nodoc:
- a = @altitude.unpack("N").join.to_i
- return ((a.to_f/1e2)-1e5).to_s + "m"
- end
-
- def inspect # :nodoc:
- return "#<#{self.class} #{self}>"
- end
-
- def ==(other) # :nodoc:
- return @altitude == other.altitude
- end
-
- def eql?(other) # :nodoc:
- return self == other
- end
-
- def hash # :nodoc:
- return @altitude.hash
- end
-
- end
-
- end
-
- ##
- # Default resolver to use for Gem::Resolv class methods.
-
- DefaultResolver = self.new
-
- ##
- # Replaces the resolvers in the default resolver with +new_resolvers+. This
- # allows resolvers to be changed for resolv-replace.
-
- def DefaultResolver.replace_resolvers new_resolvers
- @resolvers = new_resolvers
- end
-
- ##
- # Address Regexp to use for matching IP addresses.
-
- AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/
-
-end
-
diff --git a/lib/rubygems/vendor/timeout/.document b/lib/rubygems/vendor/timeout/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/timeout/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/timeout/lib/timeout.rb b/lib/rubygems/vendor/timeout/lib/timeout.rb
deleted file mode 100644
index df97d64ca0..0000000000
--- a/lib/rubygems/vendor/timeout/lib/timeout.rb
+++ /dev/null
@@ -1,199 +0,0 @@
-# frozen_string_literal: true
-# Timeout long-running blocks
-#
-# == Synopsis
-#
-# require 'rubygems/vendor/timeout/lib/timeout'
-# status = Gem::Timeout::timeout(5) {
-# # Something that should be interrupted if it takes more than 5 seconds...
-# }
-#
-# == Description
-#
-# Gem::Timeout provides a way to auto-terminate a potentially long-running
-# operation if it hasn't finished in a fixed amount of time.
-#
-# Previous versions didn't use a module for namespacing, however
-# #timeout is provided for backwards compatibility. You
-# should prefer Gem::Timeout.timeout instead.
-#
-# == Copyright
-#
-# Copyright:: (C) 2000 Network Applied Communication Laboratory, Inc.
-# Copyright:: (C) 2000 Information-technology Promotion Agency, Japan
-
-module Gem::Timeout
- VERSION = "0.4.1"
-
- # Internal error raised to when a timeout is triggered.
- class ExitException < Exception
- def exception(*)
- self
- end
- end
-
- # Raised by Gem::Timeout.timeout when the block times out.
- class Error < RuntimeError
- def self.handle_timeout(message)
- exc = ExitException.new(message)
-
- begin
- yield exc
- rescue ExitException => e
- raise new(message) if exc.equal?(e)
- raise
- end
- end
- end
-
- # :stopdoc:
- CONDVAR = ConditionVariable.new
- QUEUE = Queue.new
- QUEUE_MUTEX = Mutex.new
- TIMEOUT_THREAD_MUTEX = Mutex.new
- @timeout_thread = nil
- private_constant :CONDVAR, :QUEUE, :QUEUE_MUTEX, :TIMEOUT_THREAD_MUTEX
-
- class Request
- attr_reader :deadline
-
- def initialize(thread, timeout, exception_class, message)
- @thread = thread
- @deadline = GET_TIME.call(Process::CLOCK_MONOTONIC) + timeout
- @exception_class = exception_class
- @message = message
-
- @mutex = Mutex.new
- @done = false # protected by @mutex
- end
-
- def done?
- @mutex.synchronize do
- @done
- end
- end
-
- def expired?(now)
- now >= @deadline
- end
-
- def interrupt
- @mutex.synchronize do
- unless @done
- @thread.raise @exception_class, @message
- @done = true
- end
- end
- end
-
- def finished
- @mutex.synchronize do
- @done = true
- end
- end
- end
- private_constant :Request
-
- def self.create_timeout_thread
- watcher = Thread.new do
- requests = []
- while true
- until QUEUE.empty? and !requests.empty? # wait to have at least one request
- req = QUEUE.pop
- requests << req unless req.done?
- end
- closest_deadline = requests.min_by(&:deadline).deadline
-
- now = 0.0
- QUEUE_MUTEX.synchronize do
- while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
- CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
- end
- end
-
- requests.each do |req|
- req.interrupt if req.expired?(now)
- end
- requests.reject!(&:done?)
- end
- end
- ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
- watcher.name = "Gem::Timeout stdlib thread"
- watcher.thread_variable_set(:"\0__detached_thread__", true)
- watcher
- end
- private_class_method :create_timeout_thread
-
- def self.ensure_timeout_thread_created
- unless @timeout_thread and @timeout_thread.alive?
- TIMEOUT_THREAD_MUTEX.synchronize do
- unless @timeout_thread and @timeout_thread.alive?
- @timeout_thread = create_timeout_thread
- end
- end
- end
- end
-
- # We keep a private reference so that time mocking libraries won't break
- # Gem::Timeout.
- GET_TIME = Process.method(:clock_gettime)
- private_constant :GET_TIME
-
- # :startdoc:
-
- # Perform an operation in a block, raising an error if it takes longer than
- # +sec+ seconds to complete.
- #
- # +sec+:: Number of seconds to wait for the block to terminate. Any number
- # may be used, including Floats to specify fractional seconds. A
- # value of 0 or +nil+ will execute the block without any timeout.
- # +klass+:: Exception Class to raise if the block fails to terminate
- # in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error
- # +message+:: Error message to raise with Exception Class.
- # Omitting will use the default, "execution expired"
- #
- # Returns the result of the block *if* the block completed before
- # +sec+ seconds, otherwise throws an exception, based on the value of +klass+.
- #
- # The exception thrown to terminate the given block cannot be rescued inside
- # the block unless +klass+ is given explicitly. However, the block can use
- # ensure to prevent the handling of the exception. For that reason, this
- # method cannot be relied on to enforce timeouts for untrusted blocks.
- #
- # If a scheduler is defined, it will be used to handle the timeout by invoking
- # Scheduler#timeout_after.
- #
- # Note that this is both a method of module Gem::Timeout, so you can <tt>include
- # Gem::Timeout</tt> into your classes so they have a #timeout method, as well as
- # a module method, so you can call it directly as Gem::Timeout.timeout().
- def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
- return yield(sec) if sec == nil or sec.zero?
-
- message ||= "execution expired"
-
- if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after)
- return scheduler.timeout_after(sec, klass || Error, message, &block)
- end
-
- Gem::Timeout.ensure_timeout_thread_created
- perform = Proc.new do |exc|
- request = Request.new(Thread.current, sec, exc, message)
- QUEUE_MUTEX.synchronize do
- QUEUE << request
- CONDVAR.signal
- end
- begin
- return yield(sec)
- ensure
- request.finished
- end
- end
-
- if klass
- perform.call(klass)
- else
- Error.handle_timeout(message, &perform)
- end
- end
- module_function :timeout
-end
diff --git a/lib/rubygems/vendor/tsort/.document b/lib/rubygems/vendor/tsort/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/tsort/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/tsort/lib/tsort.rb b/lib/rubygems/vendor/tsort/lib/tsort.rb
deleted file mode 100644
index 9dd7c09521..0000000000
--- a/lib/rubygems/vendor/tsort/lib/tsort.rb
+++ /dev/null
@@ -1,455 +0,0 @@
-# frozen_string_literal: true
-
-#--
-# tsort.rb - provides a module for topological sorting and strongly connected components.
-#++
-#
-
-#
-# Gem::TSort implements topological sorting using Tarjan's algorithm for
-# strongly connected components.
-#
-# Gem::TSort is designed to be able to be used with any object which can be
-# interpreted as a directed graph.
-#
-# Gem::TSort requires two methods to interpret an object as a graph,
-# tsort_each_node and tsort_each_child.
-#
-# * tsort_each_node is used to iterate for all nodes over a graph.
-# * tsort_each_child is used to iterate for child nodes of a given node.
-#
-# The equality of nodes are defined by eql? and hash since
-# Gem::TSort uses Hash internally.
-#
-# == A Simple Example
-#
-# The following example demonstrates how to mix the Gem::TSort module into an
-# existing class (in this case, Hash). Here, we're treating each key in
-# the hash as a node in the graph, and so we simply alias the required
-# #tsort_each_node method to Hash's #each_key method. For each key in the
-# hash, the associated value is an array of the node's child nodes. This
-# choice in turn leads to our implementation of the required #tsort_each_child
-# method, which fetches the array of child nodes and then iterates over that
-# array using the user-supplied block.
-#
-# require 'rubygems/vendor/tsort/lib/tsort'
-#
-# class Hash
-# include Gem::TSort
-# alias tsort_each_node each_key
-# def tsort_each_child(node, &block)
-# fetch(node).each(&block)
-# end
-# end
-#
-# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
-# #=> [3, 2, 1, 4]
-#
-# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
-# #=> [[4], [2, 3], [1]]
-#
-# == A More Realistic Example
-#
-# A very simple `make' like tool can be implemented as follows:
-#
-# require 'rubygems/vendor/tsort/lib/tsort'
-#
-# class Make
-# def initialize
-# @dep = {}
-# @dep.default = []
-# end
-#
-# def rule(outputs, inputs=[], &block)
-# triple = [outputs, inputs, block]
-# outputs.each {|f| @dep[f] = [triple]}
-# @dep[triple] = inputs
-# end
-#
-# def build(target)
-# each_strongly_connected_component_from(target) {|ns|
-# if ns.length != 1
-# fs = ns.delete_if {|n| Array === n}
-# raise Gem::TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
-# end
-# n = ns.first
-# if Array === n
-# outputs, inputs, block = n
-# inputs_time = inputs.map {|f| File.mtime f}.max
-# begin
-# outputs_time = outputs.map {|f| File.mtime f}.min
-# rescue Errno::ENOENT
-# outputs_time = nil
-# end
-# if outputs_time == nil ||
-# inputs_time != nil && outputs_time <= inputs_time
-# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
-# block.call
-# end
-# end
-# }
-# end
-#
-# def tsort_each_child(node, &block)
-# @dep[node].each(&block)
-# end
-# include Gem::TSort
-# end
-#
-# def command(arg)
-# print arg, "\n"
-# system arg
-# end
-#
-# m = Make.new
-# m.rule(%w[t1]) { command 'date > t1' }
-# m.rule(%w[t2]) { command 'date > t2' }
-# m.rule(%w[t3]) { command 'date > t3' }
-# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
-# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
-# m.build('t5')
-#
-# == Bugs
-#
-# * 'tsort.rb' is wrong name because this library uses
-# Tarjan's algorithm for strongly connected components.
-# Although 'strongly_connected_components.rb' is correct but too long.
-#
-# == References
-#
-# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms",
-# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.
-#
-
-module Gem::TSort
-
- VERSION = "0.2.0"
-
- class Cyclic < StandardError
- end
-
- # Returns a topologically sorted array of nodes.
- # The array is sorted from children to parents, i.e.
- # the first element has no child and the last node has no parent.
- #
- # If there is a cycle, Gem::TSort::Cyclic is raised.
- #
- # class G
- # include Gem::TSort
- # def initialize(g)
- # @g = g
- # end
- # def tsort_each_child(n, &b) @g[n].each(&b) end
- # def tsort_each_node(&b) @g.each_key(&b) end
- # end
- #
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
- # p graph.tsort #=> [4, 2, 3, 1]
- #
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
- # p graph.tsort # raises Gem::TSort::Cyclic
- #
- def tsort
- each_node = method(:tsort_each_node)
- each_child = method(:tsort_each_child)
- Gem::TSort.tsort(each_node, each_child)
- end
-
- # Returns a topologically sorted array of nodes.
- # The array is sorted from children to parents, i.e.
- # the first element has no child and the last node has no parent.
- #
- # The graph is represented by _each_node_ and _each_child_.
- # _each_node_ should have +call+ method which yields for each node in the graph.
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
- #
- # If there is a cycle, Gem::TSort::Cyclic is raised.
- #
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
- #
- # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
- #
- def self.tsort(each_node, each_child)
- tsort_each(each_node, each_child).to_a
- end
-
- # The iterator version of the #tsort method.
- # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
- # modification of _obj_ during the iteration may lead to unexpected results.
- #
- # #tsort_each returns +nil+.
- # If there is a cycle, Gem::TSort::Cyclic is raised.
- #
- # class G
- # include Gem::TSort
- # def initialize(g)
- # @g = g
- # end
- # def tsort_each_child(n, &b) @g[n].each(&b) end
- # def tsort_each_node(&b) @g.each_key(&b) end
- # end
- #
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
- # graph.tsort_each {|n| p n }
- # #=> 4
- # # 2
- # # 3
- # # 1
- #
- def tsort_each(&block) # :yields: node
- each_node = method(:tsort_each_node)
- each_child = method(:tsort_each_child)
- Gem::TSort.tsort_each(each_node, each_child, &block)
- end
-
- # The iterator version of the Gem::TSort.tsort method.
- #
- # The graph is represented by _each_node_ and _each_child_.
- # _each_node_ should have +call+ method which yields for each node in the graph.
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
- #
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # Gem::TSort.tsort_each(each_node, each_child) {|n| p n }
- # #=> 4
- # # 2
- # # 3
- # # 1
- #
- def self.tsort_each(each_node, each_child) # :yields: node
- return to_enum(__method__, each_node, each_child) unless block_given?
-
- each_strongly_connected_component(each_node, each_child) {|component|
- if component.size == 1
- yield component.first
- else
- raise Cyclic.new("topological sort failed: #{component.inspect}")
- end
- }
- end
-
- # Returns strongly connected components as an array of arrays of nodes.
- # The array is sorted from children to parents.
- # Each elements of the array represents a strongly connected component.
- #
- # class G
- # include Gem::TSort
- # def initialize(g)
- # @g = g
- # end
- # def tsort_each_child(n, &b) @g[n].each(&b) end
- # def tsort_each_node(&b) @g.each_key(&b) end
- # end
- #
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
- # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
- #
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
- # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
- #
- def strongly_connected_components
- each_node = method(:tsort_each_node)
- each_child = method(:tsort_each_child)
- Gem::TSort.strongly_connected_components(each_node, each_child)
- end
-
- # Returns strongly connected components as an array of arrays of nodes.
- # The array is sorted from children to parents.
- # Each elements of the array represents a strongly connected component.
- #
- # The graph is represented by _each_node_ and _each_child_.
- # _each_node_ should have +call+ method which yields for each node in the graph.
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
- #
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # p Gem::TSort.strongly_connected_components(each_node, each_child)
- # #=> [[4], [2], [3], [1]]
- #
- # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # p Gem::TSort.strongly_connected_components(each_node, each_child)
- # #=> [[4], [2, 3], [1]]
- #
- def self.strongly_connected_components(each_node, each_child)
- each_strongly_connected_component(each_node, each_child).to_a
- end
-
- # The iterator version of the #strongly_connected_components method.
- # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
- # <tt><em>obj</em>.strongly_connected_components.each</tt>, but
- # modification of _obj_ during the iteration may lead to unexpected results.
- #
- # #each_strongly_connected_component returns +nil+.
- #
- # class G
- # include Gem::TSort
- # def initialize(g)
- # @g = g
- # end
- # def tsort_each_child(n, &b) @g[n].each(&b) end
- # def tsort_each_node(&b) @g.each_key(&b) end
- # end
- #
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
- # graph.each_strongly_connected_component {|scc| p scc }
- # #=> [4]
- # # [2]
- # # [3]
- # # [1]
- #
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
- # graph.each_strongly_connected_component {|scc| p scc }
- # #=> [4]
- # # [2, 3]
- # # [1]
- #
- def each_strongly_connected_component(&block) # :yields: nodes
- each_node = method(:tsort_each_node)
- each_child = method(:tsort_each_child)
- Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
- end
-
- # The iterator version of the Gem::TSort.strongly_connected_components method.
- #
- # The graph is represented by _each_node_ and _each_child_.
- # _each_node_ should have +call+ method which yields for each node in the graph.
- # _each_child_ should have +call+ method which takes a node argument and yields for each child node.
- #
- # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
- # #=> [4]
- # # [2]
- # # [3]
- # # [1]
- #
- # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
- # each_node = lambda {|&b| g.each_key(&b) }
- # each_child = lambda {|n, &b| g[n].each(&b) }
- # Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
- # #=> [4]
- # # [2, 3]
- # # [1]
- #
- def self.each_strongly_connected_component(each_node, each_child) # :yields: nodes
- return to_enum(__method__, each_node, each_child) unless block_given?
-
- id_map = {}
- stack = []
- each_node.call {|node|
- unless id_map.include? node
- each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
- yield c
- }
- end
- }
- nil
- end
-
- # Iterates over strongly connected component in the subgraph reachable from
- # _node_.
- #
- # Return value is unspecified.
- #
- # #each_strongly_connected_component_from doesn't call #tsort_each_node.
- #
- # class G
- # include Gem::TSort
- # def initialize(g)
- # @g = g
- # end
- # def tsort_each_child(n, &b) @g[n].each(&b) end
- # def tsort_each_node(&b) @g.each_key(&b) end
- # end
- #
- # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
- # graph.each_strongly_connected_component_from(2) {|scc| p scc }
- # #=> [4]
- # # [2]
- #
- # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
- # graph.each_strongly_connected_component_from(2) {|scc| p scc }
- # #=> [4]
- # # [2, 3]
- #
- def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
- Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
- end
-
- # Iterates over strongly connected components in a graph.
- # The graph is represented by _node_ and _each_child_.
- #
- # _node_ is the first node.
- # _each_child_ should have +call+ method which takes a node argument
- # and yields for each child node.
- #
- # Return value is unspecified.
- #
- # #Gem::TSort.each_strongly_connected_component_from is a class method and
- # it doesn't need a class to represent a graph which includes Gem::TSort.
- #
- # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
- # each_child = lambda {|n, &b| graph[n].each(&b) }
- # Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc|
- # p scc
- # }
- # #=> [4]
- # # [2, 3]
- # # [1]
- #
- def self.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
- return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
-
- minimum_id = node_id = id_map[node] = id_map.size
- stack_length = stack.length
- stack << node
-
- each_child.call(node) {|child|
- if id_map.include? child
- child_id = id_map[child]
- minimum_id = child_id if child_id && child_id < minimum_id
- else
- sub_minimum_id =
- each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
- yield c
- }
- minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
- end
- }
-
- if node_id == minimum_id
- component = stack.slice!(stack_length .. -1)
- component.each {|n| id_map[n] = nil}
- yield component
- end
-
- minimum_id
- end
-
- # Should be implemented by a extended class.
- #
- # #tsort_each_node is used to iterate for all nodes over a graph.
- #
- def tsort_each_node # :yields: node
- raise NotImplementedError.new
- end
-
- # Should be implemented by a extended class.
- #
- # #tsort_each_child is used to iterate for child nodes of _node_.
- #
- def tsort_each_child(node) # :yields: child
- raise NotImplementedError.new
- end
-end
diff --git a/lib/rubygems/vendor/uri/.document b/lib/rubygems/vendor/uri/.document
deleted file mode 100644
index 0c43bbd6b3..0000000000
--- a/lib/rubygems/vendor/uri/.document
+++ /dev/null
@@ -1 +0,0 @@
-# Vendored files do not need to be documented
diff --git a/lib/rubygems/vendor/uri/lib/uri.rb b/lib/rubygems/vendor/uri/lib/uri.rb
deleted file mode 100644
index f1ccc167cc..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri.rb
+++ /dev/null
@@ -1,104 +0,0 @@
-# frozen_string_literal: false
-# Gem::URI is a module providing classes to handle Uniform Resource Identifiers
-# (RFC2396[http://tools.ietf.org/html/rfc2396]).
-#
-# == Features
-#
-# * Uniform way of handling URIs.
-# * Flexibility to introduce custom Gem::URI schemes.
-# * Flexibility to have an alternate Gem::URI::Parser (or just different patterns
-# and regexp's).
-#
-# == Basic example
-#
-# require 'rubygems/vendor/uri/lib/uri'
-#
-# uri = Gem::URI("http://foo.com/posts?id=30&limit=5#time=1305298413")
-# #=> #<Gem::URI::HTTP http://foo.com/posts?id=30&limit=5#time=1305298413>
-#
-# uri.scheme #=> "http"
-# uri.host #=> "foo.com"
-# uri.path #=> "/posts"
-# uri.query #=> "id=30&limit=5"
-# uri.fragment #=> "time=1305298413"
-#
-# uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
-#
-# == Adding custom URIs
-#
-# module Gem::URI
-# class RSYNC < Generic
-# DEFAULT_PORT = 873
-# end
-# register_scheme 'RSYNC', RSYNC
-# end
-# #=> Gem::URI::RSYNC
-#
-# Gem::URI.scheme_list
-# #=> {"FILE"=>Gem::URI::File, "FTP"=>Gem::URI::FTP, "HTTP"=>Gem::URI::HTTP,
-# # "HTTPS"=>Gem::URI::HTTPS, "LDAP"=>Gem::URI::LDAP, "LDAPS"=>Gem::URI::LDAPS,
-# # "MAILTO"=>Gem::URI::MailTo, "RSYNC"=>Gem::URI::RSYNC}
-#
-# uri = Gem::URI("rsync://rsync.foo.com")
-# #=> #<Gem::URI::RSYNC rsync://rsync.foo.com>
-#
-# == RFC References
-#
-# A good place to view an RFC spec is http://www.ietf.org/rfc.html.
-#
-# Here is a list of all related RFC's:
-# - RFC822[http://tools.ietf.org/html/rfc822]
-# - RFC1738[http://tools.ietf.org/html/rfc1738]
-# - RFC2255[http://tools.ietf.org/html/rfc2255]
-# - RFC2368[http://tools.ietf.org/html/rfc2368]
-# - RFC2373[http://tools.ietf.org/html/rfc2373]
-# - RFC2396[http://tools.ietf.org/html/rfc2396]
-# - RFC2732[http://tools.ietf.org/html/rfc2732]
-# - RFC3986[http://tools.ietf.org/html/rfc3986]
-#
-# == Class tree
-#
-# - Gem::URI::Generic (in uri/generic.rb)
-# - Gem::URI::File - (in uri/file.rb)
-# - Gem::URI::FTP - (in uri/ftp.rb)
-# - Gem::URI::HTTP - (in uri/http.rb)
-# - Gem::URI::HTTPS - (in uri/https.rb)
-# - Gem::URI::LDAP - (in uri/ldap.rb)
-# - Gem::URI::LDAPS - (in uri/ldaps.rb)
-# - Gem::URI::MailTo - (in uri/mailto.rb)
-# - Gem::URI::Parser - (in uri/common.rb)
-# - Gem::URI::REGEXP - (in uri/common.rb)
-# - Gem::URI::REGEXP::PATTERN - (in uri/common.rb)
-# - Gem::URI::Util - (in uri/common.rb)
-# - Gem::URI::Error - (in uri/common.rb)
-# - Gem::URI::InvalidURIError - (in uri/common.rb)
-# - Gem::URI::InvalidComponentError - (in uri/common.rb)
-# - Gem::URI::BadURIError - (in uri/common.rb)
-#
-# == Copyright Info
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# Documentation::
-# Akira Yamada <akira@ruby-lang.org>
-# Dmitry V. Sabanin <sdmitry@lrn.ru>
-# Vincent Batts <vbatts@hashbangbash.com>
-# License::
-# Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
-# You can redistribute it and/or modify it under the same term as Ruby.
-#
-
-module Gem::URI
-end
-
-require_relative 'uri/version'
-require_relative 'uri/common'
-require_relative 'uri/generic'
-require_relative 'uri/file'
-require_relative 'uri/ftp'
-require_relative 'uri/http'
-require_relative 'uri/https'
-require_relative 'uri/ldap'
-require_relative 'uri/ldaps'
-require_relative 'uri/mailto'
-require_relative 'uri/ws'
-require_relative 'uri/wss'
diff --git a/lib/rubygems/vendor/uri/lib/uri/common.rb b/lib/rubygems/vendor/uri/lib/uri/common.rb
deleted file mode 100644
index 921fb9dd28..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/common.rb
+++ /dev/null
@@ -1,853 +0,0 @@
-# frozen_string_literal: true
-#--
-# = uri/common.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License::
-# You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative "rfc2396_parser"
-require_relative "rfc3986_parser"
-
-module Gem::URI
- include RFC2396_REGEXP
-
- REGEXP = RFC2396_REGEXP
- Parser = RFC2396_Parser
- RFC3986_PARSER = RFC3986_Parser.new
- Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
-
- # Gem::URI::Parser.new
- DEFAULT_PARSER = Parser.new
- DEFAULT_PARSER.pattern.each_pair do |sym, str|
- unless REGEXP::PATTERN.const_defined?(sym)
- REGEXP::PATTERN.const_set(sym, str)
- end
- end
- DEFAULT_PARSER.regexp.each_pair do |sym, str|
- const_set(sym, str)
- end
- Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor)
-
- module Util # :nodoc:
- def make_components_hash(klass, array_hash)
- tmp = {}
- if array_hash.kind_of?(Array) &&
- array_hash.size == klass.component.size - 1
- klass.component[1..-1].each_index do |i|
- begin
- tmp[klass.component[i + 1]] = array_hash[i].clone
- rescue TypeError
- tmp[klass.component[i + 1]] = array_hash[i]
- end
- end
-
- elsif array_hash.kind_of?(Hash)
- array_hash.each do |key, value|
- begin
- tmp[key] = value.clone
- rescue TypeError
- tmp[key] = value
- end
- end
- else
- raise ArgumentError,
- "expected Array of or Hash of components of #{klass} (#{klass.component[1..-1].join(', ')})"
- end
- tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase
-
- return tmp
- end
- module_function :make_components_hash
- end
-
- module Schemes
- end
- private_constant :Schemes
-
- # Registers the given +klass+ as the class to be instantiated
- # when parsing a \Gem::URI with the given +scheme+:
- #
- # Gem::URI.register_scheme('MS_SEARCH', Gem::URI::Generic) # => Gem::URI::Generic
- # Gem::URI.scheme_list['MS_SEARCH'] # => Gem::URI::Generic
- #
- # Note that after calling String#upcase on +scheme+, it must be a valid
- # constant name.
- def self.register_scheme(scheme, klass)
- Schemes.const_set(scheme.to_s.upcase, klass)
- end
-
- # Returns a hash of the defined schemes:
- #
- # Gem::URI.scheme_list
- # # =>
- # {"MAILTO"=>Gem::URI::MailTo,
- # "LDAPS"=>Gem::URI::LDAPS,
- # "WS"=>Gem::URI::WS,
- # "HTTP"=>Gem::URI::HTTP,
- # "HTTPS"=>Gem::URI::HTTPS,
- # "LDAP"=>Gem::URI::LDAP,
- # "FILE"=>Gem::URI::File,
- # "FTP"=>Gem::URI::FTP}
- #
- # Related: Gem::URI.register_scheme.
- def self.scheme_list
- Schemes.constants.map { |name|
- [name.to_s.upcase, Schemes.const_get(name)]
- }.to_h
- end
-
- INITIAL_SCHEMES = scheme_list
- private_constant :INITIAL_SCHEMES
- Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
-
- # Returns a new object constructed from the given +scheme+, +arguments+,
- # and +default+:
- #
- # - The new object is an instance of <tt>Gem::URI.scheme_list[scheme.upcase]</tt>.
- # - The object is initialized by calling the class initializer
- # using +scheme+ and +arguments+.
- # See Gem::URI::Generic.new.
- #
- # Examples:
- #
- # values = ['john.doe', 'www.example.com', '123', nil, '/forum/questions/', nil, 'tag=networking&order=newest', 'top']
- # Gem::URI.for('https', *values)
- # # => #<Gem::URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- # Gem::URI.for('foo', *values, default: Gem::URI::HTTP)
- # # => #<Gem::URI::HTTP foo://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- #
- def self.for(scheme, *arguments, default: Generic)
- const_name = scheme.to_s.upcase
-
- uri_class = INITIAL_SCHEMES[const_name]
- uri_class ||= if /\A[A-Z]\w*\z/.match?(const_name) && Schemes.const_defined?(const_name, false)
- Schemes.const_get(const_name, false)
- end
- uri_class ||= default
-
- return uri_class.new(scheme, *arguments)
- end
-
- #
- # Base class for all Gem::URI exceptions.
- #
- class Error < StandardError; end
- #
- # Not a Gem::URI.
- #
- class InvalidURIError < Error; end
- #
- # Not a Gem::URI component.
- #
- class InvalidComponentError < Error; end
- #
- # Gem::URI is valid, bad usage is not.
- #
- class BadURIError < Error; end
-
- # Returns a 9-element array representing the parts of the \Gem::URI
- # formed from the string +uri+;
- # each array element is a string or +nil+:
- #
- # names = %w[scheme userinfo host port registry path opaque query fragment]
- # values = Gem::URI.split('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # names.zip(values)
- # # =>
- # [["scheme", "https"],
- # ["userinfo", "john.doe"],
- # ["host", "www.example.com"],
- # ["port", "123"],
- # ["registry", nil],
- # ["path", "/forum/questions/"],
- # ["opaque", nil],
- # ["query", "tag=networking&order=newest"],
- # ["fragment", "top"]]
- #
- def self.split(uri)
- RFC3986_PARSER.split(uri)
- end
-
- # Returns a new \Gem::URI object constructed from the given string +uri+:
- #
- # Gem::URI.parse('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # # => #<Gem::URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- # Gem::URI.parse('http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # # => #<Gem::URI::HTTP http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- #
- # It's recommended to first ::escape string +uri+
- # if it may contain invalid Gem::URI characters.
- #
- def self.parse(uri)
- RFC3986_PARSER.parse(uri)
- end
-
- # Merges the given Gem::URI strings +str+
- # per {RFC 2396}[https://www.rfc-editor.org/rfc/rfc2396.html].
- #
- # Each string in +str+ is converted to an
- # {RFC3986 Gem::URI}[https://www.rfc-editor.org/rfc/rfc3986.html] before being merged.
- #
- # Examples:
- #
- # Gem::URI.join("http://example.com/","main.rbx")
- # # => #<Gem::URI::HTTP http://example.com/main.rbx>
- #
- # Gem::URI.join('http://example.com', 'foo')
- # # => #<Gem::URI::HTTP http://example.com/foo>
- #
- # Gem::URI.join('http://example.com', '/foo', '/bar')
- # # => #<Gem::URI::HTTP http://example.com/bar>
- #
- # Gem::URI.join('http://example.com', '/foo', 'bar')
- # # => #<Gem::URI::HTTP http://example.com/bar>
- #
- # Gem::URI.join('http://example.com', '/foo/', 'bar')
- # # => #<Gem::URI::HTTP http://example.com/foo/bar>
- #
- def self.join(*str)
- RFC3986_PARSER.join(*str)
- end
-
- #
- # == Synopsis
- #
- # Gem::URI::extract(str[, schemes][,&blk])
- #
- # == Args
- #
- # +str+::
- # String to extract URIs from.
- # +schemes+::
- # Limit Gem::URI matching to specific schemes.
- #
- # == Description
- #
- # Extracts URIs from a string. If block given, iterates through all matched URIs.
- # Returns nil if block given or array with matches.
- #
- # == Usage
- #
- # require "rubygems/vendor/uri/lib/uri"
- #
- # Gem::URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
- # # => ["http://foo.example.com/bla", "mailto:test@example.com"]
- #
- def self.extract(str, schemes = nil, &block) # :nodoc:
- warn "Gem::URI.extract is obsolete", uplevel: 1 if $VERBOSE
- DEFAULT_PARSER.extract(str, schemes, &block)
- end
-
- #
- # == Synopsis
- #
- # Gem::URI::regexp([match_schemes])
- #
- # == Args
- #
- # +match_schemes+::
- # Array of schemes. If given, resulting regexp matches to URIs
- # whose scheme is one of the match_schemes.
- #
- # == Description
- #
- # Returns a Regexp object which matches to Gem::URI-like strings.
- # The Regexp object returned by this method includes arbitrary
- # number of capture group (parentheses). Never rely on its number.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # # extract first Gem::URI from html_string
- # html_string.slice(Gem::URI.regexp)
- #
- # # remove ftp URIs
- # html_string.sub(Gem::URI.regexp(['ftp']), '')
- #
- # # You should not rely on the number of parentheses
- # html_string.scan(Gem::URI.regexp) do |*matches|
- # p $&
- # end
- #
- def self.regexp(schemes = nil)# :nodoc:
- warn "Gem::URI.regexp is obsolete", uplevel: 1 if $VERBOSE
- DEFAULT_PARSER.make_regexp(schemes)
- end
-
- TBLENCWWWCOMP_ = {} # :nodoc:
- 256.times do |i|
- TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i)
- end
- TBLENCURICOMP_ = TBLENCWWWCOMP_.dup.freeze
- TBLENCWWWCOMP_[' '] = '+'
- TBLENCWWWCOMP_.freeze
- TBLDECWWWCOMP_ = {} # :nodoc:
- 256.times do |i|
- h, l = i>>4, i&15
- TBLDECWWWCOMP_[-('%%%X%X' % [h, l])] = -i.chr
- TBLDECWWWCOMP_[-('%%%x%X' % [h, l])] = -i.chr
- TBLDECWWWCOMP_[-('%%%X%x' % [h, l])] = -i.chr
- TBLDECWWWCOMP_[-('%%%x%x' % [h, l])] = -i.chr
- end
- TBLDECWWWCOMP_['+'] = ' '
- TBLDECWWWCOMP_.freeze
-
- # Returns a URL-encoded string derived from the given string +str+.
- #
- # The returned string:
- #
- # - Preserves:
- #
- # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
- # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
- # and <tt>'0'..'9'</tt>.
- #
- # Example:
- #
- # Gem::URI.encode_www_form_component('*.-_azAZ09')
- # # => "*.-_azAZ09"
- #
- # - Converts:
- #
- # - Character <tt>' '</tt> to character <tt>'+'</tt>.
- # - Any other character to "percent notation";
- # the percent notation for character <i>c</i> is <tt>'%%%X' % c.ord</tt>.
- #
- # Example:
- #
- # Gem::URI.encode_www_form_component('Here are some punctuation characters: ,;?:')
- # # => "Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A"
- #
- # Encoding:
- #
- # - If +str+ has encoding Encoding::ASCII_8BIT, argument +enc+ is ignored.
- # - Otherwise +str+ is converted first to Encoding::UTF_8
- # (with suitable character replacements),
- # and then to encoding +enc+.
- #
- # In either case, the returned string has forced encoding Encoding::US_ASCII.
- #
- # Related: Gem::URI.encode_uri_component (encodes <tt>' '</tt> as <tt>'%20'</tt>).
- def self.encode_www_form_component(str, enc=nil)
- _encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_, str, enc)
- end
-
- # Returns a string decoded from the given \URL-encoded string +str+.
- #
- # The given string is first encoded as Encoding::ASCII-8BIT (using String#b),
- # then decoded (as below), and finally force-encoded to the given encoding +enc+.
- #
- # The returned string:
- #
- # - Preserves:
- #
- # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
- # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
- # and <tt>'0'..'9'</tt>.
- #
- # Example:
- #
- # Gem::URI.decode_www_form_component('*.-_azAZ09')
- # # => "*.-_azAZ09"
- #
- # - Converts:
- #
- # - Character <tt>'+'</tt> to character <tt>' '</tt>.
- # - Each "percent notation" to an ASCII character.
- #
- # Example:
- #
- # Gem::URI.decode_www_form_component('Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A')
- # # => "Here are some punctuation characters: ,;?:"
- #
- # Related: Gem::URI.decode_uri_component (preserves <tt>'+'</tt>).
- def self.decode_www_form_component(str, enc=Encoding::UTF_8)
- _decode_uri_component(/\+|%\h\h/, str, enc)
- end
-
- # Like Gem::URI.encode_www_form_component, except that <tt>' '</tt> (space)
- # is encoded as <tt>'%20'</tt> (instead of <tt>'+'</tt>).
- def self.encode_uri_component(str, enc=nil)
- _encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCURICOMP_, str, enc)
- end
-
- # Like Gem::URI.decode_www_form_component, except that <tt>'+'</tt> is preserved.
- def self.decode_uri_component(str, enc=Encoding::UTF_8)
- _decode_uri_component(/%\h\h/, str, enc)
- end
-
- def self._encode_uri_component(regexp, table, str, enc)
- str = str.to_s.dup
- if str.encoding != Encoding::ASCII_8BIT
- if enc && enc != Encoding::ASCII_8BIT
- str.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace)
- str.encode!(enc, fallback: ->(x){"&##{x.ord};"})
- end
- str.force_encoding(Encoding::ASCII_8BIT)
- end
- str.gsub!(regexp, table)
- str.force_encoding(Encoding::US_ASCII)
- end
- private_class_method :_encode_uri_component
-
- def self._decode_uri_component(regexp, str, enc)
- raise ArgumentError, "invalid %-encoding (#{str})" if /%(?!\h\h)/.match?(str)
- str.b.gsub(regexp, TBLDECWWWCOMP_).force_encoding(enc)
- end
- private_class_method :_decode_uri_component
-
- # Returns a URL-encoded string derived from the given
- # {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
- # +enum+.
- #
- # The result is suitable for use as form data
- # for an \HTTP request whose <tt>Content-Type</tt> is
- # <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The returned string consists of the elements of +enum+,
- # each converted to one or more URL-encoded strings,
- # and all joined with character <tt>'&'</tt>.
- #
- # Simple examples:
- #
- # Gem::URI.encode_www_form([['foo', 0], ['bar', 1], ['baz', 2]])
- # # => "foo=0&bar=1&baz=2"
- # Gem::URI.encode_www_form({foo: 0, bar: 1, baz: 2})
- # # => "foo=0&bar=1&baz=2"
- #
- # The returned string is formed using method Gem::URI.encode_www_form_component,
- # which converts certain characters:
- #
- # Gem::URI.encode_www_form('f#o': '/', 'b-r': '$', 'b z': '@')
- # # => "f%23o=%2F&b-r=%24&b+z=%40"
- #
- # When +enum+ is Array-like, each element +ele+ is converted to a field:
- #
- # - If +ele+ is an array of two or more elements,
- # the field is formed from its first two elements
- # (and any additional elements are ignored):
- #
- # name = Gem::URI.encode_www_form_component(ele[0], enc)
- # value = Gem::URI.encode_www_form_component(ele[1], enc)
- # "#{name}=#{value}"
- #
- # Examples:
- #
- # Gem::URI.encode_www_form([%w[foo bar], %w[baz bat bah]])
- # # => "foo=bar&baz=bat"
- # Gem::URI.encode_www_form([['foo', 0], ['bar', :baz, 'bat']])
- # # => "foo=0&bar=baz"
- #
- # - If +ele+ is an array of one element,
- # the field is formed from <tt>ele[0]</tt>:
- #
- # Gem::URI.encode_www_form_component(ele[0])
- #
- # Example:
- #
- # Gem::URI.encode_www_form([['foo'], [:bar], [0]])
- # # => "foo&bar&0"
- #
- # - Otherwise the field is formed from +ele+:
- #
- # Gem::URI.encode_www_form_component(ele)
- #
- # Example:
- #
- # Gem::URI.encode_www_form(['foo', :bar, 0])
- # # => "foo&bar&0"
- #
- # The elements of an Array-like +enum+ may be mixture:
- #
- # Gem::URI.encode_www_form([['foo', 0], ['bar', 1, 2], ['baz'], :bat])
- # # => "foo=0&bar=1&baz&bat"
- #
- # When +enum+ is Hash-like,
- # each +key+/+value+ pair is converted to one or more fields:
- #
- # - If +value+ is
- # {Array-convertible}[https://docs.ruby-lang.org/en/master/implicit_conversion_rdoc.html#label-Array-Convertible+Objects],
- # each element +ele+ in +value+ is paired with +key+ to form a field:
- #
- # name = Gem::URI.encode_www_form_component(key, enc)
- # value = Gem::URI.encode_www_form_component(ele, enc)
- # "#{name}=#{value}"
- #
- # Example:
- #
- # Gem::URI.encode_www_form({foo: [:bar, 1], baz: [:bat, :bam, 2]})
- # # => "foo=bar&foo=1&baz=bat&baz=bam&baz=2"
- #
- # - Otherwise, +key+ and +value+ are paired to form a field:
- #
- # name = Gem::URI.encode_www_form_component(key, enc)
- # value = Gem::URI.encode_www_form_component(value, enc)
- # "#{name}=#{value}"
- #
- # Example:
- #
- # Gem::URI.encode_www_form({foo: 0, bar: 1, baz: 2})
- # # => "foo=0&bar=1&baz=2"
- #
- # The elements of a Hash-like +enum+ may be mixture:
- #
- # Gem::URI.encode_www_form({foo: [0, 1], bar: 2})
- # # => "foo=0&foo=1&bar=2"
- #
- def self.encode_www_form(enum, enc=nil)
- enum.map do |k,v|
- if v.nil?
- encode_www_form_component(k, enc)
- elsif v.respond_to?(:to_ary)
- v.to_ary.map do |w|
- str = encode_www_form_component(k, enc)
- unless w.nil?
- str << '='
- str << encode_www_form_component(w, enc)
- end
- end.join('&')
- else
- str = encode_www_form_component(k, enc)
- str << '='
- str << encode_www_form_component(v, enc)
- end
- end.join('&')
- end
-
- # Returns name/value pairs derived from the given string +str+,
- # which must be an ASCII string.
- #
- # The method may be used to decode the body of Net::HTTPResponse object +res+
- # for which <tt>res['Content-Type']</tt> is <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The returned data is an array of 2-element subarrays;
- # each subarray is a name/value pair (both are strings).
- # Each returned string has encoding +enc+,
- # and has had invalid characters removed via
- # {String#scrub}[https://docs.ruby-lang.org/en/master/String.html#method-i-scrub].
- #
- # A simple example:
- #
- # Gem::URI.decode_www_form('foo=0&bar=1&baz')
- # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
- #
- # The returned strings have certain conversions,
- # similar to those performed in Gem::URI.decode_www_form_component:
- #
- # Gem::URI.decode_www_form('f%23o=%2F&b-r=%24&b+z=%40')
- # # => [["f#o", "/"], ["b-r", "$"], ["b z", "@"]]
- #
- # The given string may contain consecutive separators:
- #
- # Gem::URI.decode_www_form('foo=0&&bar=1&&baz=2')
- # # => [["foo", "0"], ["", ""], ["bar", "1"], ["", ""], ["baz", "2"]]
- #
- # A different separator may be specified:
- #
- # Gem::URI.decode_www_form('foo=0--bar=1--baz', separator: '--')
- # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
- #
- def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
- raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
- ary = []
- return ary if str.empty?
- enc = Encoding.find(enc)
- str.b.each_line(separator) do |string|
- string.chomp!(separator)
- key, sep, val = string.partition('=')
- if isindex
- if sep.empty?
- val = key
- key = +''
- end
- isindex = false
- end
-
- if use__charset_ and key == '_charset_' and e = get_encoding(val)
- enc = e
- use__charset_ = false
- end
-
- key.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_)
- if val
- val.gsub!(/\+|%\h\h/, TBLDECWWWCOMP_)
- else
- val = +''
- end
-
- ary << [key, val]
- end
- ary.each do |k, v|
- k.force_encoding(enc)
- k.scrub!
- v.force_encoding(enc)
- v.scrub!
- end
- ary
- end
-
- private
-=begin command for WEB_ENCODINGS_
- curl https://encoding.spec.whatwg.org/encodings.json|
- ruby -rjson -e 'H={}
- h={
- "shift_jis"=>"Windows-31J",
- "euc-jp"=>"cp51932",
- "iso-2022-jp"=>"cp50221",
- "x-mac-cyrillic"=>"macCyrillic",
- }
- JSON($<.read).map{|x|x["encodings"]}.flatten.each{|x|
- Encoding.find(n=h.fetch(n=x["name"].downcase,n))rescue next
- x["labels"].each{|y|H[y]=n}
- }
- puts "{"
- H.each{|k,v|puts %[ #{k.dump}=>#{v.dump},]}
- puts "}"
-'
-=end
- WEB_ENCODINGS_ = {
- "unicode-1-1-utf-8"=>"utf-8",
- "utf-8"=>"utf-8",
- "utf8"=>"utf-8",
- "866"=>"ibm866",
- "cp866"=>"ibm866",
- "csibm866"=>"ibm866",
- "ibm866"=>"ibm866",
- "csisolatin2"=>"iso-8859-2",
- "iso-8859-2"=>"iso-8859-2",
- "iso-ir-101"=>"iso-8859-2",
- "iso8859-2"=>"iso-8859-2",
- "iso88592"=>"iso-8859-2",
- "iso_8859-2"=>"iso-8859-2",
- "iso_8859-2:1987"=>"iso-8859-2",
- "l2"=>"iso-8859-2",
- "latin2"=>"iso-8859-2",
- "csisolatin3"=>"iso-8859-3",
- "iso-8859-3"=>"iso-8859-3",
- "iso-ir-109"=>"iso-8859-3",
- "iso8859-3"=>"iso-8859-3",
- "iso88593"=>"iso-8859-3",
- "iso_8859-3"=>"iso-8859-3",
- "iso_8859-3:1988"=>"iso-8859-3",
- "l3"=>"iso-8859-3",
- "latin3"=>"iso-8859-3",
- "csisolatin4"=>"iso-8859-4",
- "iso-8859-4"=>"iso-8859-4",
- "iso-ir-110"=>"iso-8859-4",
- "iso8859-4"=>"iso-8859-4",
- "iso88594"=>"iso-8859-4",
- "iso_8859-4"=>"iso-8859-4",
- "iso_8859-4:1988"=>"iso-8859-4",
- "l4"=>"iso-8859-4",
- "latin4"=>"iso-8859-4",
- "csisolatincyrillic"=>"iso-8859-5",
- "cyrillic"=>"iso-8859-5",
- "iso-8859-5"=>"iso-8859-5",
- "iso-ir-144"=>"iso-8859-5",
- "iso8859-5"=>"iso-8859-5",
- "iso88595"=>"iso-8859-5",
- "iso_8859-5"=>"iso-8859-5",
- "iso_8859-5:1988"=>"iso-8859-5",
- "arabic"=>"iso-8859-6",
- "asmo-708"=>"iso-8859-6",
- "csiso88596e"=>"iso-8859-6",
- "csiso88596i"=>"iso-8859-6",
- "csisolatinarabic"=>"iso-8859-6",
- "ecma-114"=>"iso-8859-6",
- "iso-8859-6"=>"iso-8859-6",
- "iso-8859-6-e"=>"iso-8859-6",
- "iso-8859-6-i"=>"iso-8859-6",
- "iso-ir-127"=>"iso-8859-6",
- "iso8859-6"=>"iso-8859-6",
- "iso88596"=>"iso-8859-6",
- "iso_8859-6"=>"iso-8859-6",
- "iso_8859-6:1987"=>"iso-8859-6",
- "csisolatingreek"=>"iso-8859-7",
- "ecma-118"=>"iso-8859-7",
- "elot_928"=>"iso-8859-7",
- "greek"=>"iso-8859-7",
- "greek8"=>"iso-8859-7",
- "iso-8859-7"=>"iso-8859-7",
- "iso-ir-126"=>"iso-8859-7",
- "iso8859-7"=>"iso-8859-7",
- "iso88597"=>"iso-8859-7",
- "iso_8859-7"=>"iso-8859-7",
- "iso_8859-7:1987"=>"iso-8859-7",
- "sun_eu_greek"=>"iso-8859-7",
- "csiso88598e"=>"iso-8859-8",
- "csisolatinhebrew"=>"iso-8859-8",
- "hebrew"=>"iso-8859-8",
- "iso-8859-8"=>"iso-8859-8",
- "iso-8859-8-e"=>"iso-8859-8",
- "iso-ir-138"=>"iso-8859-8",
- "iso8859-8"=>"iso-8859-8",
- "iso88598"=>"iso-8859-8",
- "iso_8859-8"=>"iso-8859-8",
- "iso_8859-8:1988"=>"iso-8859-8",
- "visual"=>"iso-8859-8",
- "csisolatin6"=>"iso-8859-10",
- "iso-8859-10"=>"iso-8859-10",
- "iso-ir-157"=>"iso-8859-10",
- "iso8859-10"=>"iso-8859-10",
- "iso885910"=>"iso-8859-10",
- "l6"=>"iso-8859-10",
- "latin6"=>"iso-8859-10",
- "iso-8859-13"=>"iso-8859-13",
- "iso8859-13"=>"iso-8859-13",
- "iso885913"=>"iso-8859-13",
- "iso-8859-14"=>"iso-8859-14",
- "iso8859-14"=>"iso-8859-14",
- "iso885914"=>"iso-8859-14",
- "csisolatin9"=>"iso-8859-15",
- "iso-8859-15"=>"iso-8859-15",
- "iso8859-15"=>"iso-8859-15",
- "iso885915"=>"iso-8859-15",
- "iso_8859-15"=>"iso-8859-15",
- "l9"=>"iso-8859-15",
- "iso-8859-16"=>"iso-8859-16",
- "cskoi8r"=>"koi8-r",
- "koi"=>"koi8-r",
- "koi8"=>"koi8-r",
- "koi8-r"=>"koi8-r",
- "koi8_r"=>"koi8-r",
- "koi8-ru"=>"koi8-u",
- "koi8-u"=>"koi8-u",
- "dos-874"=>"windows-874",
- "iso-8859-11"=>"windows-874",
- "iso8859-11"=>"windows-874",
- "iso885911"=>"windows-874",
- "tis-620"=>"windows-874",
- "windows-874"=>"windows-874",
- "cp1250"=>"windows-1250",
- "windows-1250"=>"windows-1250",
- "x-cp1250"=>"windows-1250",
- "cp1251"=>"windows-1251",
- "windows-1251"=>"windows-1251",
- "x-cp1251"=>"windows-1251",
- "ansi_x3.4-1968"=>"windows-1252",
- "ascii"=>"windows-1252",
- "cp1252"=>"windows-1252",
- "cp819"=>"windows-1252",
- "csisolatin1"=>"windows-1252",
- "ibm819"=>"windows-1252",
- "iso-8859-1"=>"windows-1252",
- "iso-ir-100"=>"windows-1252",
- "iso8859-1"=>"windows-1252",
- "iso88591"=>"windows-1252",
- "iso_8859-1"=>"windows-1252",
- "iso_8859-1:1987"=>"windows-1252",
- "l1"=>"windows-1252",
- "latin1"=>"windows-1252",
- "us-ascii"=>"windows-1252",
- "windows-1252"=>"windows-1252",
- "x-cp1252"=>"windows-1252",
- "cp1253"=>"windows-1253",
- "windows-1253"=>"windows-1253",
- "x-cp1253"=>"windows-1253",
- "cp1254"=>"windows-1254",
- "csisolatin5"=>"windows-1254",
- "iso-8859-9"=>"windows-1254",
- "iso-ir-148"=>"windows-1254",
- "iso8859-9"=>"windows-1254",
- "iso88599"=>"windows-1254",
- "iso_8859-9"=>"windows-1254",
- "iso_8859-9:1989"=>"windows-1254",
- "l5"=>"windows-1254",
- "latin5"=>"windows-1254",
- "windows-1254"=>"windows-1254",
- "x-cp1254"=>"windows-1254",
- "cp1255"=>"windows-1255",
- "windows-1255"=>"windows-1255",
- "x-cp1255"=>"windows-1255",
- "cp1256"=>"windows-1256",
- "windows-1256"=>"windows-1256",
- "x-cp1256"=>"windows-1256",
- "cp1257"=>"windows-1257",
- "windows-1257"=>"windows-1257",
- "x-cp1257"=>"windows-1257",
- "cp1258"=>"windows-1258",
- "windows-1258"=>"windows-1258",
- "x-cp1258"=>"windows-1258",
- "x-mac-cyrillic"=>"macCyrillic",
- "x-mac-ukrainian"=>"macCyrillic",
- "chinese"=>"gbk",
- "csgb2312"=>"gbk",
- "csiso58gb231280"=>"gbk",
- "gb2312"=>"gbk",
- "gb_2312"=>"gbk",
- "gb_2312-80"=>"gbk",
- "gbk"=>"gbk",
- "iso-ir-58"=>"gbk",
- "x-gbk"=>"gbk",
- "gb18030"=>"gb18030",
- "big5"=>"big5",
- "big5-hkscs"=>"big5",
- "cn-big5"=>"big5",
- "csbig5"=>"big5",
- "x-x-big5"=>"big5",
- "cseucpkdfmtjapanese"=>"cp51932",
- "euc-jp"=>"cp51932",
- "x-euc-jp"=>"cp51932",
- "csiso2022jp"=>"cp50221",
- "iso-2022-jp"=>"cp50221",
- "csshiftjis"=>"Windows-31J",
- "ms932"=>"Windows-31J",
- "ms_kanji"=>"Windows-31J",
- "shift-jis"=>"Windows-31J",
- "shift_jis"=>"Windows-31J",
- "sjis"=>"Windows-31J",
- "windows-31j"=>"Windows-31J",
- "x-sjis"=>"Windows-31J",
- "cseuckr"=>"euc-kr",
- "csksc56011987"=>"euc-kr",
- "euc-kr"=>"euc-kr",
- "iso-ir-149"=>"euc-kr",
- "korean"=>"euc-kr",
- "ks_c_5601-1987"=>"euc-kr",
- "ks_c_5601-1989"=>"euc-kr",
- "ksc5601"=>"euc-kr",
- "ksc_5601"=>"euc-kr",
- "windows-949"=>"euc-kr",
- "utf-16be"=>"utf-16be",
- "utf-16"=>"utf-16le",
- "utf-16le"=>"utf-16le",
- } # :nodoc:
- Ractor.make_shareable(WEB_ENCODINGS_) if defined?(Ractor)
-
- # :nodoc:
- # return encoding or nil
- # http://encoding.spec.whatwg.org/#concept-encoding-get
- def self.get_encoding(label)
- Encoding.find(WEB_ENCODINGS_[label.to_str.strip.downcase]) rescue nil
- end
-end # module Gem::URI
-
-module Gem
-
- #
- # Returns a \Gem::URI object derived from the given +uri+,
- # which may be a \Gem::URI string or an existing \Gem::URI object:
- #
- # # Returns a new Gem::URI.
- # uri = Gem::URI('http://github.com/ruby/ruby')
- # # => #<Gem::URI::HTTP http://github.com/ruby/ruby>
- # # Returns the given Gem::URI.
- # Gem::URI(uri)
- # # => #<Gem::URI::HTTP http://github.com/ruby/ruby>
- #
- def URI(uri)
- if uri.is_a?(Gem::URI::Generic)
- uri
- elsif uri = String.try_convert(uri)
- Gem::URI.parse(uri)
- else
- raise ArgumentError,
- "bad argument (expected Gem::URI object or Gem::URI string)"
- end
- end
- module_function :URI
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/file.rb b/lib/rubygems/vendor/uri/lib/uri/file.rb
deleted file mode 100644
index d419b26055..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/file.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'generic'
-
-module Gem::URI
-
- #
- # The "file" Gem::URI is defined by RFC8089.
- #
- class File < Generic
- # A Default port of nil for Gem::URI::File.
- DEFAULT_PORT = nil
-
- #
- # An Array of the available components for Gem::URI::File.
- #
- COMPONENT = [
- :scheme,
- :host,
- :path
- ].freeze
-
- #
- # == Description
- #
- # Creates a new Gem::URI::File object from components, with syntax checking.
- #
- # The components accepted are +host+ and +path+.
- #
- # The components should be provided either as an Array, or as a Hash
- # with keys formed by preceding the component names with a colon.
- #
- # If an Array is used, the components must be passed in the
- # order <code>[host, path]</code>.
- #
- # A path from e.g. the File class should be escaped before
- # being passed.
- #
- # Examples:
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri1 = Gem::URI::File.build(['host.example.com', '/path/file.zip'])
- # uri1.to_s # => "file://host.example.com/path/file.zip"
- #
- # uri2 = Gem::URI::File.build({:host => 'host.example.com',
- # :path => '/ruby/src'})
- # uri2.to_s # => "file://host.example.com/ruby/src"
- #
- # uri3 = Gem::URI::File.build({:path => Gem::URI::escape('/path/my file.txt')})
- # uri3.to_s # => "file:///path/my%20file.txt"
- #
- def self.build(args)
- tmp = Util::make_components_hash(self, args)
- super(tmp)
- end
-
- # Protected setter for the host component +v+.
- #
- # See also Gem::URI::Generic.host=.
- #
- def set_host(v)
- v = "" if v.nil? || v == "localhost"
- @host = v
- end
-
- # do nothing
- def set_port(v)
- end
-
- # raise InvalidURIError
- def check_userinfo(user)
- raise Gem::URI::InvalidURIError, "can not set userinfo for file Gem::URI"
- end
-
- # raise InvalidURIError
- def check_user(user)
- raise Gem::URI::InvalidURIError, "can not set user for file Gem::URI"
- end
-
- # raise InvalidURIError
- def check_password(user)
- raise Gem::URI::InvalidURIError, "can not set password for file Gem::URI"
- end
-
- # do nothing
- def set_userinfo(v)
- end
-
- # do nothing
- def set_user(v)
- end
-
- # do nothing
- def set_password(v)
- end
- end
-
- register_scheme 'FILE', File
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/ftp.rb b/lib/rubygems/vendor/uri/lib/uri/ftp.rb
deleted file mode 100644
index 100498ffb2..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/ftp.rb
+++ /dev/null
@@ -1,267 +0,0 @@
-# frozen_string_literal: false
-# = uri/ftp.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'generic'
-
-module Gem::URI
-
- #
- # FTP Gem::URI syntax is defined by RFC1738 section 3.2.
- #
- # This class will be redesigned because of difference of implementations;
- # the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it
- # is a good summary about the de facto spec.
- # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04
- #
- class FTP < Generic
- # A Default port of 21 for Gem::URI::FTP.
- DEFAULT_PORT = 21
-
- #
- # An Array of the available components for Gem::URI::FTP.
- #
- COMPONENT = [
- :scheme,
- :userinfo, :host, :port,
- :path, :typecode
- ].freeze
-
- #
- # Typecode is "a", "i", or "d".
- #
- # * "a" indicates a text file (the FTP command was ASCII)
- # * "i" indicates a binary file (FTP command IMAGE)
- # * "d" indicates the contents of a directory should be displayed
- #
- TYPECODE = ['a', 'i', 'd'].freeze
-
- # Typecode prefix ";type=".
- TYPECODE_PREFIX = ';type='.freeze
-
- def self.new2(user, password, host, port, path,
- typecode = nil, arg_check = true) # :nodoc:
- # Do not use this method! Not tested. [Bug #7301]
- # This methods remains just for compatibility,
- # Keep it undocumented until the active maintainer is assigned.
- typecode = nil if typecode.size == 0
- if typecode && !TYPECODE.include?(typecode)
- raise ArgumentError,
- "bad typecode is specified: #{typecode}"
- end
-
- # do escape
-
- self.new('ftp',
- [user, password],
- host, port, nil,
- typecode ? path + TYPECODE_PREFIX + typecode : path,
- nil, nil, nil, arg_check)
- end
-
- #
- # == Description
- #
- # Creates a new Gem::URI::FTP object from components, with syntax checking.
- #
- # The components accepted are +userinfo+, +host+, +port+, +path+, and
- # +typecode+.
- #
- # The components should be provided either as an Array, or as a Hash
- # with keys formed by preceding the component names with a colon.
- #
- # If an Array is used, the components must be passed in the
- # order <code>[userinfo, host, port, path, typecode]</code>.
- #
- # If the path supplied is absolute, it will be escaped in order to
- # make it absolute in the Gem::URI.
- #
- # Examples:
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri1 = Gem::URI::FTP.build(['user:password', 'ftp.example.com', nil,
- # '/path/file.zip', 'i'])
- # uri1.to_s # => "ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i"
- #
- # uri2 = Gem::URI::FTP.build({:host => 'ftp.example.com',
- # :path => 'ruby/src'})
- # uri2.to_s # => "ftp://ftp.example.com/ruby/src"
- #
- def self.build(args)
-
- # Fix the incoming path to be generic URL syntax
- # FTP path -> URL path
- # foo/bar /foo/bar
- # /foo/bar /%2Ffoo/bar
- #
- if args.kind_of?(Array)
- args[3] = '/' + args[3].sub(/^\//, '%2F')
- else
- args[:path] = '/' + args[:path].sub(/^\//, '%2F')
- end
-
- tmp = Util::make_components_hash(self, args)
-
- if tmp[:typecode]
- if tmp[:typecode].size == 1
- tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
- end
- tmp[:path] << tmp[:typecode]
- end
-
- return super(tmp)
- end
-
- #
- # == Description
- #
- # Creates a new Gem::URI::FTP object from generic URL components with no
- # syntax checking.
- #
- # Unlike build(), this method does not escape the path component as
- # required by RFC1738; instead it is treated as per RFC2396.
- #
- # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
- # +opaque+, +query+, and +fragment+, in that order.
- #
- def initialize(scheme,
- userinfo, host, port, registry,
- path, opaque,
- query,
- fragment,
- parser = nil,
- arg_check = false)
- raise InvalidURIError unless path
- path = path.sub(/^\//,'')
- path.sub!(/^%2F/,'/')
- super(scheme, userinfo, host, port, registry, path, opaque,
- query, fragment, parser, arg_check)
- @typecode = nil
- if tmp = @path.index(TYPECODE_PREFIX)
- typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
- @path = @path[0..tmp - 1]
-
- if arg_check
- self.typecode = typecode
- else
- self.set_typecode(typecode)
- end
- end
- end
-
- # typecode accessor.
- #
- # See Gem::URI::FTP::COMPONENT.
- attr_reader :typecode
-
- # Validates typecode +v+,
- # returns +true+ or +false+.
- #
- def check_typecode(v)
- if TYPECODE.include?(v)
- return true
- else
- raise InvalidComponentError,
- "bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
- end
- end
- private :check_typecode
-
- # Private setter for the typecode +v+.
- #
- # See also Gem::URI::FTP.typecode=.
- #
- def set_typecode(v)
- @typecode = v
- end
- protected :set_typecode
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the typecode +v+
- # (with validation).
- #
- # See also Gem::URI::FTP.check_typecode.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("ftp://john@ftp.example.com/my_file.img")
- # #=> #<Gem::URI::FTP ftp://john@ftp.example.com/my_file.img>
- # uri.typecode = "i"
- # uri
- # #=> #<Gem::URI::FTP ftp://john@ftp.example.com/my_file.img;type=i>
- #
- def typecode=(typecode)
- check_typecode(typecode)
- set_typecode(typecode)
- typecode
- end
-
- def merge(oth) # :nodoc:
- tmp = super(oth)
- if self != tmp
- tmp.set_typecode(oth.typecode)
- end
-
- return tmp
- end
-
- # Returns the path from an FTP Gem::URI.
- #
- # RFC 1738 specifically states that the path for an FTP Gem::URI does not
- # include the / which separates the Gem::URI path from the Gem::URI host. Example:
- #
- # <code>ftp://ftp.example.com/pub/ruby</code>
- #
- # The above Gem::URI indicates that the client should connect to
- # ftp.example.com then cd to pub/ruby from the initial login directory.
- #
- # If you want to cd to an absolute directory, you must include an
- # escaped / (%2F) in the path. Example:
- #
- # <code>ftp://ftp.example.com/%2Fpub/ruby</code>
- #
- # This method will then return "/pub/ruby".
- #
- def path
- return @path.sub(/^\//,'').sub(/^%2F/,'/')
- end
-
- # Private setter for the path of the Gem::URI::FTP.
- def set_path(v)
- super("/" + v.sub(/^\//, "%2F"))
- end
- protected :set_path
-
- # Returns a String representation of the Gem::URI::FTP.
- def to_s
- save_path = nil
- if @typecode
- save_path = @path
- @path = @path + TYPECODE_PREFIX + @typecode
- end
- str = super
- if @typecode
- @path = save_path
- end
-
- return str
- end
- end
-
- register_scheme 'FTP', FTP
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/generic.rb b/lib/rubygems/vendor/uri/lib/uri/generic.rb
deleted file mode 100644
index 72c52aa8ee..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/generic.rb
+++ /dev/null
@@ -1,1588 +0,0 @@
-# frozen_string_literal: true
-
-# = uri/generic.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'common'
-autoload :IPSocket, 'socket'
-autoload :IPAddr, 'ipaddr'
-
-module Gem::URI
-
- #
- # Base class for all Gem::URI classes.
- # Implements generic Gem::URI syntax as per RFC 2396.
- #
- class Generic
- include Gem::URI
-
- #
- # A Default port of nil for Gem::URI::Generic.
- #
- DEFAULT_PORT = nil
-
- #
- # Returns default port.
- #
- def self.default_port
- self::DEFAULT_PORT
- end
-
- #
- # Returns default port.
- #
- def default_port
- self.class.default_port
- end
-
- #
- # An Array of the available components for Gem::URI::Generic.
- #
- COMPONENT = [
- :scheme,
- :userinfo, :host, :port, :registry,
- :path, :opaque,
- :query,
- :fragment
- ].freeze
-
- #
- # Components of the Gem::URI in the order.
- #
- def self.component
- self::COMPONENT
- end
-
- USE_REGISTRY = false # :nodoc:
-
- def self.use_registry # :nodoc:
- self::USE_REGISTRY
- end
-
- #
- # == Synopsis
- #
- # See ::new.
- #
- # == Description
- #
- # At first, tries to create a new Gem::URI::Generic instance using
- # Gem::URI::Generic::build. But, if exception Gem::URI::InvalidComponentError is raised,
- # then it does Gem::URI::Escape.escape all Gem::URI components and tries again.
- #
- def self.build2(args)
- begin
- return self.build(args)
- rescue InvalidComponentError
- if args.kind_of?(Array)
- return self.build(args.collect{|x|
- if x.is_a?(String)
- DEFAULT_PARSER.escape(x)
- else
- x
- end
- })
- elsif args.kind_of?(Hash)
- tmp = {}
- args.each do |key, value|
- tmp[key] = if value
- DEFAULT_PARSER.escape(value)
- else
- value
- end
- end
- return self.build(tmp)
- end
- end
- end
-
- #
- # == Synopsis
- #
- # See ::new.
- #
- # == Description
- #
- # Creates a new Gem::URI::Generic instance from components of Gem::URI::Generic
- # with check. Components are: scheme, userinfo, host, port, registry, path,
- # opaque, query, and fragment. You can provide arguments either by an Array or a Hash.
- # See ::new for hash keys to use or for order of array items.
- #
- def self.build(args)
- if args.kind_of?(Array) &&
- args.size == ::Gem::URI::Generic::COMPONENT.size
- tmp = args.dup
- elsif args.kind_of?(Hash)
- tmp = ::Gem::URI::Generic::COMPONENT.collect do |c|
- if args.include?(c)
- args[c]
- else
- nil
- end
- end
- else
- component = self.class.component rescue ::Gem::URI::Generic::COMPONENT
- raise ArgumentError,
- "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})"
- end
-
- tmp << nil
- tmp << true
- return self.new(*tmp)
- end
-
- #
- # == Args
- #
- # +scheme+::
- # Protocol scheme, i.e. 'http','ftp','mailto' and so on.
- # +userinfo+::
- # User name and password, i.e. 'sdmitry:bla'.
- # +host+::
- # Server host name.
- # +port+::
- # Server port.
- # +registry+::
- # Registry of naming authorities.
- # +path+::
- # Path on server.
- # +opaque+::
- # Opaque part.
- # +query+::
- # Query data.
- # +fragment+::
- # Part of the Gem::URI after '#' character.
- # +parser+::
- # Parser for internal use [Gem::URI::DEFAULT_PARSER by default].
- # +arg_check+::
- # Check arguments [false by default].
- #
- # == Description
- #
- # Creates a new Gem::URI::Generic instance from ``generic'' components without check.
- #
- def initialize(scheme,
- userinfo, host, port, registry,
- path, opaque,
- query,
- fragment,
- parser = DEFAULT_PARSER,
- arg_check = false)
- @scheme = nil
- @user = nil
- @password = nil
- @host = nil
- @port = nil
- @path = nil
- @query = nil
- @opaque = nil
- @fragment = nil
- @parser = parser == DEFAULT_PARSER ? nil : parser
-
- if arg_check
- self.scheme = scheme
- self.userinfo = userinfo
- self.hostname = host
- self.port = port
- self.path = path
- self.query = query
- self.opaque = opaque
- self.fragment = fragment
- else
- self.set_scheme(scheme)
- self.set_userinfo(userinfo)
- self.set_host(host)
- self.set_port(port)
- self.set_path(path)
- self.query = query
- self.set_opaque(opaque)
- self.fragment=(fragment)
- end
- if registry
- raise InvalidURIError,
- "the scheme #{@scheme} does not accept registry part: #{registry} (or bad hostname?)"
- end
-
- @scheme&.freeze
- self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
- self.set_port(self.default_port) if self.default_port && !@port
- end
-
- #
- # Returns the scheme component of the Gem::URI.
- #
- # Gem::URI("http://foo/bar/baz").scheme #=> "http"
- #
- attr_reader :scheme
-
- # Returns the host component of the Gem::URI.
- #
- # Gem::URI("http://foo/bar/baz").host #=> "foo"
- #
- # It returns nil if no host component exists.
- #
- # Gem::URI("mailto:foo@example.org").host #=> nil
- #
- # The component does not contain the port number.
- #
- # Gem::URI("http://foo:8080/bar/baz").host #=> "foo"
- #
- # Since IPv6 addresses are wrapped with brackets in URIs,
- # this method returns IPv6 addresses wrapped with brackets.
- # This form is not appropriate to pass to socket methods such as TCPSocket.open.
- # If unwrapped host names are required, use the #hostname method.
- #
- # Gem::URI("http://[::1]/bar/baz").host #=> "[::1]"
- # Gem::URI("http://[::1]/bar/baz").hostname #=> "::1"
- #
- attr_reader :host
-
- # Returns the port component of the Gem::URI.
- #
- # Gem::URI("http://foo/bar/baz").port #=> 80
- # Gem::URI("http://foo:8080/bar/baz").port #=> 8080
- #
- attr_reader :port
-
- def registry # :nodoc:
- nil
- end
-
- # Returns the path component of the Gem::URI.
- #
- # Gem::URI("http://foo/bar/baz").path #=> "/bar/baz"
- #
- attr_reader :path
-
- # Returns the query component of the Gem::URI.
- #
- # Gem::URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"
- #
- attr_reader :query
-
- # Returns the opaque part of the Gem::URI.
- #
- # Gem::URI("mailto:foo@example.org").opaque #=> "foo@example.org"
- # Gem::URI("http://foo/bar/baz").opaque #=> nil
- #
- # The portion of the path that does not make use of the slash '/'.
- # The path typically refers to an absolute path or an opaque part.
- # (See RFC2396 Section 3 and 5.2.)
- #
- attr_reader :opaque
-
- # Returns the fragment component of the Gem::URI.
- #
- # Gem::URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"
- #
- attr_reader :fragment
-
- # Returns the parser to be used.
- #
- # Unless a Gem::URI::Parser is defined, DEFAULT_PARSER is used.
- #
- def parser
- if !defined?(@parser) || !@parser
- DEFAULT_PARSER
- else
- @parser || DEFAULT_PARSER
- end
- end
-
- # Replaces self by other Gem::URI object.
- #
- def replace!(oth)
- if self.class != oth.class
- raise ArgumentError, "expected #{self.class} object"
- end
-
- component.each do |c|
- self.__send__("#{c}=", oth.__send__(c))
- end
- end
- private :replace!
-
- #
- # Components of the Gem::URI in the order.
- #
- def component
- self.class.component
- end
-
- #
- # Checks the scheme +v+ component against the Gem::URI::Parser Regexp for :SCHEME.
- #
- def check_scheme(v)
- if v && parser.regexp[:SCHEME] !~ v
- raise InvalidComponentError,
- "bad component(expected scheme component): #{v}"
- end
-
- return true
- end
- private :check_scheme
-
- # Protected setter for the scheme component +v+.
- #
- # See also Gem::URI::Generic.scheme=.
- #
- def set_scheme(v)
- @scheme = v&.downcase
- end
- protected :set_scheme
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the scheme component +v+
- # (with validation).
- #
- # See also Gem::URI::Generic.check_scheme.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com")
- # uri.scheme = "https"
- # uri.to_s #=> "https://my.example.com"
- #
- def scheme=(v)
- check_scheme(v)
- set_scheme(v)
- v
- end
-
- #
- # Checks the +user+ and +password+.
- #
- # If +password+ is not provided, then +user+ is
- # split, using Gem::URI::Generic.split_userinfo, to
- # pull +user+ and +password.
- #
- # See also Gem::URI::Generic.check_user, Gem::URI::Generic.check_password.
- #
- def check_userinfo(user, password = nil)
- if !password
- user, password = split_userinfo(user)
- end
- check_user(user)
- check_password(password, user)
-
- return true
- end
- private :check_userinfo
-
- #
- # Checks the user +v+ component for RFC2396 compliance
- # and against the Gem::URI::Parser Regexp for :USERINFO.
- #
- # Can not have a registry or opaque component defined,
- # with a user component defined.
- #
- def check_user(v)
- if @opaque
- raise InvalidURIError,
- "can not set user with opaque"
- end
-
- return v unless v
-
- if parser.regexp[:USERINFO] !~ v
- raise InvalidComponentError,
- "bad component(expected userinfo component or user component): #{v}"
- end
-
- return true
- end
- private :check_user
-
- #
- # Checks the password +v+ component for RFC2396 compliance
- # and against the Gem::URI::Parser Regexp for :USERINFO.
- #
- # Can not have a registry or opaque component defined,
- # with a user component defined.
- #
- def check_password(v, user = @user)
- if @opaque
- raise InvalidURIError,
- "can not set password with opaque"
- end
- return v unless v
-
- if !user
- raise InvalidURIError,
- "password component depends user component"
- end
-
- if parser.regexp[:USERINFO] !~ v
- raise InvalidComponentError,
- "bad password component"
- end
-
- return true
- end
- private :check_password
-
- #
- # Sets userinfo, argument is string like 'name:pass'.
- #
- def userinfo=(userinfo)
- if userinfo.nil?
- return nil
- end
- check_userinfo(*userinfo)
- set_userinfo(*userinfo)
- # returns userinfo
- end
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the +user+ component
- # (with validation).
- #
- # See also Gem::URI::Generic.check_user.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://john:S3nsit1ve@my.example.com")
- # uri.user = "sam"
- # uri.to_s #=> "http://sam:V3ry_S3nsit1ve@my.example.com"
- #
- def user=(user)
- check_user(user)
- set_user(user)
- # returns user
- end
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the +password+ component
- # (with validation).
- #
- # See also Gem::URI::Generic.check_password.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://john:S3nsit1ve@my.example.com")
- # uri.password = "V3ry_S3nsit1ve"
- # uri.to_s #=> "http://john:V3ry_S3nsit1ve@my.example.com"
- #
- def password=(password)
- check_password(password)
- set_password(password)
- # returns password
- end
-
- # Protected setter for the +user+ component, and +password+ if available
- # (with validation).
- #
- # See also Gem::URI::Generic.userinfo=.
- #
- def set_userinfo(user, password = nil)
- unless password
- user, password = split_userinfo(user)
- end
- @user = user
- @password = password if password
-
- [@user, @password]
- end
- protected :set_userinfo
-
- # Protected setter for the user component +v+.
- #
- # See also Gem::URI::Generic.user=.
- #
- def set_user(v)
- set_userinfo(v, @password)
- v
- end
- protected :set_user
-
- # Protected setter for the password component +v+.
- #
- # See also Gem::URI::Generic.password=.
- #
- def set_password(v)
- @password = v
- # returns v
- end
- protected :set_password
-
- # Returns the userinfo +ui+ as <code>[user, password]</code>
- # if properly formatted as 'user:password'.
- def split_userinfo(ui)
- return nil, nil unless ui
- user, password = ui.split(':', 2)
-
- return user, password
- end
- private :split_userinfo
-
- # Escapes 'user:password' +v+ based on RFC 1738 section 3.1.
- def escape_userpass(v)
- parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
- end
- private :escape_userpass
-
- # Returns the userinfo, either as 'user' or 'user:password'.
- def userinfo
- if @user.nil?
- nil
- elsif @password.nil?
- @user
- else
- @user + ':' + @password
- end
- end
-
- # Returns the user component (without Gem::URI decoding).
- def user
- @user
- end
-
- # Returns the password component (without Gem::URI decoding).
- def password
- @password
- end
-
- # Returns the user component after Gem::URI decoding.
- def decoded_user
- Gem::URI.decode_uri_component(@user) if @user
- end
-
- # Returns the password component after Gem::URI decoding.
- def decoded_password
- Gem::URI.decode_uri_component(@password) if @password
- end
-
- #
- # Checks the host +v+ component for RFC2396 compliance
- # and against the Gem::URI::Parser Regexp for :HOST.
- #
- # Can not have a registry or opaque component defined,
- # with a host component defined.
- #
- def check_host(v)
- return v unless v
-
- if @opaque
- raise InvalidURIError,
- "can not set host with registry or opaque"
- elsif parser.regexp[:HOST] !~ v
- raise InvalidComponentError,
- "bad component(expected host component): #{v}"
- end
-
- return true
- end
- private :check_host
-
- # Protected setter for the host component +v+.
- #
- # See also Gem::URI::Generic.host=.
- #
- def set_host(v)
- @host = v
- end
- protected :set_host
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the host component +v+
- # (with validation).
- #
- # See also Gem::URI::Generic.check_host.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com")
- # uri.host = "foo.com"
- # uri.to_s #=> "http://foo.com"
- #
- def host=(v)
- check_host(v)
- set_host(v)
- v
- end
-
- # Extract the host part of the Gem::URI and unwrap brackets for IPv6 addresses.
- #
- # This method is the same as Gem::URI::Generic#host except
- # brackets for IPv6 (and future IP) addresses are removed.
- #
- # uri = Gem::URI("http://[::1]/bar")
- # uri.hostname #=> "::1"
- # uri.host #=> "[::1]"
- #
- def hostname
- v = self.host
- v&.start_with?('[') && v.end_with?(']') ? v[1..-2] : v
- end
-
- # Sets the host part of the Gem::URI as the argument with brackets for IPv6 addresses.
- #
- # This method is the same as Gem::URI::Generic#host= except
- # the argument can be a bare IPv6 address.
- #
- # uri = Gem::URI("http://foo/bar")
- # uri.hostname = "::1"
- # uri.to_s #=> "http://[::1]/bar"
- #
- # If the argument seems to be an IPv6 address,
- # it is wrapped with brackets.
- #
- def hostname=(v)
- v = "[#{v}]" if !(v&.start_with?('[') && v&.end_with?(']')) && v&.index(':')
- self.host = v
- end
-
- #
- # Checks the port +v+ component for RFC2396 compliance
- # and against the Gem::URI::Parser Regexp for :PORT.
- #
- # Can not have a registry or opaque component defined,
- # with a port component defined.
- #
- def check_port(v)
- return v unless v
-
- if @opaque
- raise InvalidURIError,
- "can not set port with registry or opaque"
- elsif !v.kind_of?(Integer) && parser.regexp[:PORT] !~ v
- raise InvalidComponentError,
- "bad component(expected port component): #{v.inspect}"
- end
-
- return true
- end
- private :check_port
-
- # Protected setter for the port component +v+.
- #
- # See also Gem::URI::Generic.port=.
- #
- def set_port(v)
- v = v.empty? ? nil : v.to_i unless !v || v.kind_of?(Integer)
- @port = v
- end
- protected :set_port
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the port component +v+
- # (with validation).
- #
- # See also Gem::URI::Generic.check_port.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com")
- # uri.port = 8080
- # uri.to_s #=> "http://my.example.com:8080"
- #
- def port=(v)
- check_port(v)
- set_port(v)
- port
- end
-
- def check_registry(v) # :nodoc:
- raise InvalidURIError, "can not set registry"
- end
- private :check_registry
-
- def set_registry(v) #:nodoc:
- raise InvalidURIError, "can not set registry"
- end
- protected :set_registry
-
- def registry=(v)
- raise InvalidURIError, "can not set registry"
- end
-
- #
- # Checks the path +v+ component for RFC2396 compliance
- # and against the Gem::URI::Parser Regexp
- # for :ABS_PATH and :REL_PATH.
- #
- # Can not have a opaque component defined,
- # with a path component defined.
- #
- def check_path(v)
- # raise if both hier and opaque are not nil, because:
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- if v && @opaque
- raise InvalidURIError,
- "path conflicts with opaque"
- end
-
- # If scheme is ftp, path may be relative.
- # See RFC 1738 section 3.2.2, and RFC 2396.
- if @scheme && @scheme != "ftp"
- if v && v != '' && parser.regexp[:ABS_PATH] !~ v
- raise InvalidComponentError,
- "bad component(expected absolute path component): #{v}"
- end
- else
- if v && v != '' && parser.regexp[:ABS_PATH] !~ v &&
- parser.regexp[:REL_PATH] !~ v
- raise InvalidComponentError,
- "bad component(expected relative path component): #{v}"
- end
- end
-
- return true
- end
- private :check_path
-
- # Protected setter for the path component +v+.
- #
- # See also Gem::URI::Generic.path=.
- #
- def set_path(v)
- @path = v
- end
- protected :set_path
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the path component +v+
- # (with validation).
- #
- # See also Gem::URI::Generic.check_path.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com/pub/files")
- # uri.path = "/faq/"
- # uri.to_s #=> "http://my.example.com/faq/"
- #
- def path=(v)
- check_path(v)
- set_path(v)
- v
- end
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the query component +v+.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com/?id=25")
- # uri.query = "id=1"
- # uri.to_s #=> "http://my.example.com/?id=1"
- #
- def query=(v)
- return @query = nil unless v
- raise InvalidURIError, "query conflicts with opaque" if @opaque
-
- x = v.to_str
- v = x.dup if x.equal? v
- v.encode!(Encoding::UTF_8) rescue nil
- v.delete!("\t\r\n")
- v.force_encoding(Encoding::ASCII_8BIT)
- raise InvalidURIError, "invalid percent escape: #{$1}" if /(%\H\H)/n.match(v)
- v.gsub!(/(?!%\h\h|[!$-&(-;=?-_a-~])./n.freeze){'%%%02X' % $&.ord}
- v.force_encoding(Encoding::US_ASCII)
- @query = v
- end
-
- #
- # Checks the opaque +v+ component for RFC2396 compliance and
- # against the Gem::URI::Parser Regexp for :OPAQUE.
- #
- # Can not have a host, port, user, or path component defined,
- # with an opaque component defined.
- #
- def check_opaque(v)
- return v unless v
-
- # raise if both hier and opaque are not nil, because:
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- if @host || @port || @user || @path # userinfo = @user + ':' + @password
- raise InvalidURIError,
- "can not set opaque with host, port, userinfo or path"
- elsif v && parser.regexp[:OPAQUE] !~ v
- raise InvalidComponentError,
- "bad component(expected opaque component): #{v}"
- end
-
- return true
- end
- private :check_opaque
-
- # Protected setter for the opaque component +v+.
- #
- # See also Gem::URI::Generic.opaque=.
- #
- def set_opaque(v)
- @opaque = v
- end
- protected :set_opaque
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the opaque component +v+
- # (with validation).
- #
- # See also Gem::URI::Generic.check_opaque.
- #
- def opaque=(v)
- check_opaque(v)
- set_opaque(v)
- v
- end
-
- #
- # Checks the fragment +v+ component against the Gem::URI::Parser Regexp for :FRAGMENT.
- #
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # Public setter for the fragment component +v+
- # (with validation).
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com/?id=25#time=1305212049")
- # uri.fragment = "time=1305212086"
- # uri.to_s #=> "http://my.example.com/?id=25#time=1305212086"
- #
- def fragment=(v)
- return @fragment = nil unless v
-
- x = v.to_str
- v = x.dup if x.equal? v
- v.encode!(Encoding::UTF_8) rescue nil
- v.delete!("\t\r\n")
- v.force_encoding(Encoding::ASCII_8BIT)
- v.gsub!(/(?!%\h\h|[!-~])./n){'%%%02X' % $&.ord}
- v.force_encoding(Encoding::US_ASCII)
- @fragment = v
- end
-
- #
- # Returns true if Gem::URI is hierarchical.
- #
- # == Description
- #
- # Gem::URI has components listed in order of decreasing significance from left to right,
- # see RFC3986 https://tools.ietf.org/html/rfc3986 1.2.3.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com/")
- # uri.hierarchical?
- # #=> true
- # uri = Gem::URI.parse("mailto:joe@example.com")
- # uri.hierarchical?
- # #=> false
- #
- def hierarchical?
- if @path
- true
- else
- false
- end
- end
-
- #
- # Returns true if Gem::URI has a scheme (e.g. http:// or https://) specified.
- #
- def absolute?
- if @scheme
- true
- else
- false
- end
- end
- alias absolute absolute?
-
- #
- # Returns true if Gem::URI does not have a scheme (e.g. http:// or https://) specified.
- #
- def relative?
- !absolute?
- end
-
- #
- # Returns an Array of the path split on '/'.
- #
- def split_path(path)
- path.split("/", -1)
- end
- private :split_path
-
- #
- # Merges a base path +base+, with relative path +rel+,
- # returns a modified base path.
- #
- def merge_path(base, rel)
-
- # RFC2396, Section 5.2, 5)
- # RFC2396, Section 5.2, 6)
- base_path = split_path(base)
- rel_path = split_path(rel)
-
- # RFC2396, Section 5.2, 6), a)
- base_path << '' if base_path.last == '..'
- while i = base_path.index('..')
- base_path.slice!(i - 1, 2)
- end
-
- if (first = rel_path.first) and first.empty?
- base_path.clear
- rel_path.shift
- end
-
- # RFC2396, Section 5.2, 6), c)
- # RFC2396, Section 5.2, 6), d)
- rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
- rel_path.delete('.')
-
- # RFC2396, Section 5.2, 6), e)
- tmp = []
- rel_path.each do |x|
- if x == '..' &&
- !(tmp.empty? || tmp.last == '..')
- tmp.pop
- else
- tmp << x
- end
- end
-
- add_trailer_slash = !tmp.empty?
- if base_path.empty?
- base_path = [''] # keep '/' for root directory
- elsif add_trailer_slash
- base_path.pop
- end
- while x = tmp.shift
- if x == '..'
- # RFC2396, Section 4
- # a .. or . in an absolute path has no special meaning
- base_path.pop if base_path.size > 1
- else
- # if x == '..'
- # valid absolute (but abnormal) path "/../..."
- # else
- # valid absolute path
- # end
- base_path << x
- tmp.each {|t| base_path << t}
- add_trailer_slash = false
- break
- end
- end
- base_path.push('') if add_trailer_slash
-
- return base_path.join('/')
- end
- private :merge_path
-
- #
- # == Args
- #
- # +oth+::
- # Gem::URI or String
- #
- # == Description
- #
- # Destructive form of #merge.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com")
- # uri.merge!("/main.rbx?page=1")
- # uri.to_s # => "http://my.example.com/main.rbx?page=1"
- #
- def merge!(oth)
- t = merge(oth)
- if self == t
- nil
- else
- replace!(t)
- self
- end
- end
-
- #
- # == Args
- #
- # +oth+::
- # Gem::URI or String
- #
- # == Description
- #
- # Merges two URIs.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com")
- # uri.merge("/main.rbx?page=1")
- # # => "http://my.example.com/main.rbx?page=1"
- #
- def merge(oth)
- rel = parser.__send__(:convert_to_uri, oth)
-
- if rel.absolute?
- #raise BadURIError, "both Gem::URI are absolute" if absolute?
- # hmm... should return oth for usability?
- return rel
- end
-
- unless self.absolute?
- raise BadURIError, "both Gem::URI are relative"
- end
-
- base = self.dup
-
- authority = rel.userinfo || rel.host || rel.port
-
- # RFC2396, Section 5.2, 2)
- if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
- base.fragment=(rel.fragment) if rel.fragment
- return base
- end
-
- base.query = nil
- base.fragment=(nil)
-
- # RFC2396, Section 5.2, 4)
- if !authority
- base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
- else
- # RFC2396, Section 5.2, 4)
- base.set_path(rel.path) if rel.path
- end
-
- # RFC2396, Section 5.2, 7)
- base.set_userinfo(rel.userinfo) if rel.userinfo
- base.set_host(rel.host) if rel.host
- base.set_port(rel.port) if rel.port
- base.query = rel.query if rel.query
- base.fragment=(rel.fragment) if rel.fragment
-
- return base
- end # merge
- alias + merge
-
- # :stopdoc:
- def route_from_path(src, dst)
- case dst
- when src
- # RFC2396, Section 4.2
- return ''
- when %r{(?:\A|/)\.\.?(?:/|\z)}
- # dst has abnormal absolute path,
- # like "/./", "/../", "/x/../", ...
- return dst.dup
- end
-
- src_path = src.scan(%r{[^/]*/})
- dst_path = dst.scan(%r{[^/]*/?})
-
- # discard same parts
- while !dst_path.empty? && dst_path.first == src_path.first
- src_path.shift
- dst_path.shift
- end
-
- tmp = dst_path.join
-
- # calculate
- if src_path.empty?
- if tmp.empty?
- return './'
- elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
- return './' + tmp
- else
- return tmp
- end
- end
-
- return '../' * src_path.size + tmp
- end
- private :route_from_path
- # :startdoc:
-
- # :stopdoc:
- def route_from0(oth)
- oth = parser.__send__(:convert_to_uri, oth)
- if self.relative?
- raise BadURIError,
- "relative Gem::URI: #{self}"
- end
- if oth.relative?
- raise BadURIError,
- "relative Gem::URI: #{oth}"
- end
-
- if self.scheme != oth.scheme
- return self, self.dup
- end
- rel = Gem::URI::Generic.new(nil, # it is relative Gem::URI
- self.userinfo, self.host, self.port,
- nil, self.path, self.opaque,
- self.query, self.fragment, parser)
-
- if rel.userinfo != oth.userinfo ||
- rel.host.to_s.downcase != oth.host.to_s.downcase ||
- rel.port != oth.port
-
- if self.userinfo.nil? && self.host.nil?
- return self, self.dup
- end
-
- rel.set_port(nil) if rel.port == oth.default_port
- return rel, rel
- end
- rel.set_userinfo(nil)
- rel.set_host(nil)
- rel.set_port(nil)
-
- if rel.path && rel.path == oth.path
- rel.set_path('')
- rel.query = nil if rel.query == oth.query
- return rel, rel
- elsif rel.opaque && rel.opaque == oth.opaque
- rel.set_opaque('')
- rel.query = nil if rel.query == oth.query
- return rel, rel
- end
-
- # you can modify `rel', but can not `oth'.
- return oth, rel
- end
- private :route_from0
- # :startdoc:
-
- #
- # == Args
- #
- # +oth+::
- # Gem::URI or String
- #
- # == Description
- #
- # Calculates relative path from oth to self.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse('http://my.example.com/main.rbx?page=1')
- # uri.route_from('http://my.example.com')
- # #=> #<Gem::URI::Generic /main.rbx?page=1>
- #
- def route_from(oth)
- # you can modify `rel', but can not `oth'.
- begin
- oth, rel = route_from0(oth)
- rescue
- raise $!.class, $!.message
- end
- if oth == rel
- return rel
- end
-
- rel.set_path(route_from_path(oth.path, self.path))
- if rel.path == './' && self.query
- # "./?foo" -> "?foo"
- rel.set_path('')
- end
-
- return rel
- end
-
- alias - route_from
-
- #
- # == Args
- #
- # +oth+::
- # Gem::URI or String
- #
- # == Description
- #
- # Calculates relative path to oth from self.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse('http://my.example.com')
- # uri.route_to('http://my.example.com/main.rbx?page=1')
- # #=> #<Gem::URI::Generic /main.rbx?page=1>
- #
- def route_to(oth)
- parser.__send__(:convert_to_uri, oth).route_from(self)
- end
-
- #
- # Returns normalized Gem::URI.
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # Gem::URI("HTTP://my.EXAMPLE.com").normalize
- # #=> #<Gem::URI::HTTP http://my.example.com/>
- #
- # Normalization here means:
- #
- # * scheme and host are converted to lowercase,
- # * an empty path component is set to "/".
- #
- def normalize
- uri = dup
- uri.normalize!
- uri
- end
-
- #
- # Destructive version of #normalize.
- #
- def normalize!
- if path&.empty?
- set_path('/')
- end
- if scheme && scheme != scheme.downcase
- set_scheme(self.scheme.downcase)
- end
- if host && host != host.downcase
- set_host(self.host.downcase)
- end
- end
-
- #
- # Constructs String from Gem::URI.
- #
- def to_s
- str = ''.dup
- if @scheme
- str << @scheme
- str << ':'
- end
-
- if @opaque
- str << @opaque
- else
- if @host || %w[file postgres].include?(@scheme)
- str << '//'
- end
- if self.userinfo
- str << self.userinfo
- str << '@'
- end
- if @host
- str << @host
- end
- if @port && @port != self.default_port
- str << ':'
- str << @port.to_s
- end
- str << @path
- if @query
- str << '?'
- str << @query
- end
- end
- if @fragment
- str << '#'
- str << @fragment
- end
- str
- end
- alias to_str to_s
-
- #
- # Compares two URIs.
- #
- def ==(oth)
- if self.class == oth.class
- self.normalize.component_ary == oth.normalize.component_ary
- else
- false
- end
- end
-
- def hash
- self.component_ary.hash
- end
-
- def eql?(oth)
- self.class == oth.class &&
- parser == oth.parser &&
- self.component_ary.eql?(oth.component_ary)
- end
-
-=begin
-
---- Gem::URI::Generic#===(oth)
-
-=end
-# def ===(oth)
-# raise NotImplementedError
-# end
-
-=begin
-=end
-
-
- # Returns an Array of the components defined from the COMPONENT Array.
- def component_ary
- component.collect do |x|
- self.__send__(x)
- end
- end
- protected :component_ary
-
- # == Args
- #
- # +components+::
- # Multiple Symbol arguments defined in Gem::URI::HTTP.
- #
- # == Description
- #
- # Selects specified components from Gem::URI.
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse('http://myuser:mypass@my.example.com/test.rbx')
- # uri.select(:userinfo, :host, :path)
- # # => ["myuser:mypass", "my.example.com", "/test.rbx"]
- #
- def select(*components)
- components.collect do |c|
- if component.include?(c)
- self.__send__(c)
- else
- raise ArgumentError,
- "expected of components of #{self.class} (#{self.class.component.join(', ')})"
- end
- end
- end
-
- def inspect
- "#<#{self.class} #{self}>"
- end
-
- #
- # == Args
- #
- # +v+::
- # Gem::URI or String
- #
- # == Description
- #
- # Attempts to parse other Gem::URI +oth+,
- # returns [parsed_oth, self].
- #
- # == Usage
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("http://my.example.com")
- # uri.coerce("http://foo.com")
- # #=> [#<Gem::URI::HTTP http://foo.com>, #<Gem::URI::HTTP http://my.example.com>]
- #
- def coerce(oth)
- case oth
- when String
- oth = parser.parse(oth)
- else
- super
- end
-
- return oth, self
- end
-
- # Returns a proxy Gem::URI.
- # The proxy Gem::URI is obtained from environment variables such as http_proxy,
- # ftp_proxy, no_proxy, etc.
- # If there is no proper proxy, nil is returned.
- #
- # If the optional parameter +env+ is specified, it is used instead of ENV.
- #
- # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
- # are examined, too.
- #
- # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
- # It's because HTTP_PROXY may be set by Proxy: header.
- # So HTTP_PROXY is not used.
- # http_proxy is not used too if the variable is case insensitive.
- # CGI_HTTP_PROXY can be used instead.
- def find_proxy(env=ENV)
- raise BadURIError, "relative Gem::URI: #{self}" if self.relative?
- name = self.scheme.downcase + '_proxy'
- proxy_uri = nil
- if name == 'http_proxy' && env.include?('REQUEST_METHOD') # CGI?
- # HTTP_PROXY conflicts with *_proxy for proxy settings and
- # HTTP_* for header information in CGI.
- # So it should be careful to use it.
- pairs = env.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
- case pairs.length
- when 0 # no proxy setting anyway.
- proxy_uri = nil
- when 1
- k, _ = pairs.shift
- if k == 'http_proxy' && env[k.upcase] == nil
- # http_proxy is safe to use because ENV is case sensitive.
- proxy_uri = env[name]
- else
- proxy_uri = nil
- end
- else # http_proxy is safe to use because ENV is case sensitive.
- proxy_uri = env.to_hash[name]
- end
- if !proxy_uri
- # Use CGI_HTTP_PROXY. cf. libwww-perl.
- proxy_uri = env["CGI_#{name.upcase}"]
- end
- elsif name == 'http_proxy'
- if RUBY_ENGINE == 'jruby' && p_addr = ENV_JAVA['http.proxyHost']
- p_port = ENV_JAVA['http.proxyPort']
- if p_user = ENV_JAVA['http.proxyUser']
- p_pass = ENV_JAVA['http.proxyPass']
- proxy_uri = "http://#{p_user}:#{p_pass}@#{p_addr}:#{p_port}"
- else
- proxy_uri = "http://#{p_addr}:#{p_port}"
- end
- else
- unless proxy_uri = env[name]
- if proxy_uri = env[name.upcase]
- warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.', uplevel: 1
- end
- end
- end
- else
- proxy_uri = env[name] || env[name.upcase]
- end
-
- if proxy_uri.nil? || proxy_uri.empty?
- return nil
- end
-
- if self.hostname
- begin
- addr = IPSocket.getaddress(self.hostname)
- return nil if /\A127\.|\A::1\z/ =~ addr
- rescue SocketError
- end
- end
-
- name = 'no_proxy'
- if no_proxy = env[name] || env[name.upcase]
- return nil unless Gem::URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy)
- end
- Gem::URI.parse(proxy_uri)
- end
-
- def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc:
- hostname = hostname.downcase
- dothostname = ".#{hostname}"
- no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port|
- if !p_port || port == p_port.to_i
- if p_host.start_with?('.')
- return false if hostname.end_with?(p_host.downcase)
- else
- return false if dothostname.end_with?(".#{p_host.downcase}")
- end
- if addr
- begin
- return false if IPAddr.new(p_host).include?(addr)
- rescue IPAddr::InvalidAddressError
- next
- end
- end
- end
- }
- true
- end
- end
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/http.rb b/lib/rubygems/vendor/uri/lib/uri/http.rb
deleted file mode 100644
index bef43490a3..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/http.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-# frozen_string_literal: false
-# = uri/http.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'generic'
-
-module Gem::URI
-
- #
- # The syntax of HTTP URIs is defined in RFC1738 section 3.3.
- #
- # Note that the Ruby Gem::URI library allows HTTP URLs containing usernames and
- # passwords. This is not legal as per the RFC, but used to be
- # supported in Internet Explorer 5 and 6, before the MS04-004 security
- # update. See <URL:http://support.microsoft.com/kb/834489>.
- #
- class HTTP < Generic
- # A Default port of 80 for Gem::URI::HTTP.
- DEFAULT_PORT = 80
-
- # An Array of the available components for Gem::URI::HTTP.
- COMPONENT = %i[
- scheme
- userinfo host port
- path
- query
- fragment
- ].freeze
-
- #
- # == Description
- #
- # Creates a new Gem::URI::HTTP object from components, with syntax checking.
- #
- # The components accepted are userinfo, host, port, path, query, and
- # fragment.
- #
- # The components should be provided either as an Array, or as a Hash
- # with keys formed by preceding the component names with a colon.
- #
- # If an Array is used, the components must be passed in the
- # order <code>[userinfo, host, port, path, query, fragment]</code>.
- #
- # Example:
- #
- # uri = Gem::URI::HTTP.build(host: 'www.example.com', path: '/foo/bar')
- #
- # uri = Gem::URI::HTTP.build([nil, "www.example.com", nil, "/path",
- # "query", 'fragment'])
- #
- # Currently, if passed userinfo components this method generates
- # invalid HTTP URIs as per RFC 1738.
- #
- def self.build(args)
- tmp = Util.make_components_hash(self, args)
- super(tmp)
- end
-
- #
- # == Description
- #
- # Returns the full path for an HTTP request, as required by Net::HTTP::Get.
- #
- # If the Gem::URI contains a query, the full path is Gem::URI#path + '?' + Gem::URI#query.
- # Otherwise, the path is simply Gem::URI#path.
- #
- # Example:
- #
- # uri = Gem::URI::HTTP.build(path: '/foo/bar', query: 'test=true')
- # uri.request_uri # => "/foo/bar?test=true"
- #
- def request_uri
- return unless @path
-
- url = @query ? "#@path?#@query" : @path.dup
- url.start_with?(?/.freeze) ? url : ?/ + url
- end
-
- #
- # == Description
- #
- # Returns the authority for an HTTP uri, as defined in
- # https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.
- #
- #
- # Example:
- #
- # Gem::URI::HTTP.build(host: 'www.example.com', path: '/foo/bar').authority #=> "www.example.com"
- # Gem::URI::HTTP.build(host: 'www.example.com', port: 8000, path: '/foo/bar').authority #=> "www.example.com:8000"
- # Gem::URI::HTTP.build(host: 'www.example.com', port: 80, path: '/foo/bar').authority #=> "www.example.com"
- #
- def authority
- if port == default_port
- host
- else
- "#{host}:#{port}"
- end
- end
-
- #
- # == Description
- #
- # Returns the origin for an HTTP uri, as defined in
- # https://datatracker.ietf.org/doc/html/rfc6454.
- #
- #
- # Example:
- #
- # Gem::URI::HTTP.build(host: 'www.example.com', path: '/foo/bar').origin #=> "http://www.example.com"
- # Gem::URI::HTTP.build(host: 'www.example.com', port: 8000, path: '/foo/bar').origin #=> "http://www.example.com:8000"
- # Gem::URI::HTTP.build(host: 'www.example.com', port: 80, path: '/foo/bar').origin #=> "http://www.example.com"
- # Gem::URI::HTTPS.build(host: 'www.example.com', path: '/foo/bar').origin #=> "https://www.example.com"
- #
- def origin
- "#{scheme}://#{authority}"
- end
- end
-
- register_scheme 'HTTP', HTTP
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/https.rb b/lib/rubygems/vendor/uri/lib/uri/https.rb
deleted file mode 100644
index 6e8e732e1d..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/https.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: false
-# = uri/https.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'http'
-
-module Gem::URI
-
- # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather
- # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs;
- # see Gem::URI::HTTP.
- class HTTPS < HTTP
- # A Default port of 443 for Gem::URI::HTTPS
- DEFAULT_PORT = 443
- end
-
- register_scheme 'HTTPS', HTTPS
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/ldap.rb b/lib/rubygems/vendor/uri/lib/uri/ldap.rb
deleted file mode 100644
index 1a08b5ab7e..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/ldap.rb
+++ /dev/null
@@ -1,261 +0,0 @@
-# frozen_string_literal: false
-# = uri/ldap.rb
-#
-# Author::
-# Takaaki Tateishi <ttate@jaist.ac.jp>
-# Akira Yamada <akira@ruby-lang.org>
-# License::
-# Gem::URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada.
-# You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'generic'
-
-module Gem::URI
-
- #
- # LDAP Gem::URI SCHEMA (described in RFC2255).
- #--
- # ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]]
- #++
- class LDAP < Generic
-
- # A Default port of 389 for Gem::URI::LDAP.
- DEFAULT_PORT = 389
-
- # An Array of the available components for Gem::URI::LDAP.
- COMPONENT = [
- :scheme,
- :host, :port,
- :dn,
- :attributes,
- :scope,
- :filter,
- :extensions,
- ].freeze
-
- # Scopes available for the starting point.
- #
- # * SCOPE_BASE - the Base DN
- # * SCOPE_ONE - one level under the Base DN, not including the base DN and
- # not including any entries under this
- # * SCOPE_SUB - subtrees, all entries at all levels
- #
- SCOPE = [
- SCOPE_ONE = 'one',
- SCOPE_SUB = 'sub',
- SCOPE_BASE = 'base',
- ].freeze
-
- #
- # == Description
- #
- # Creates a new Gem::URI::LDAP object from components, with syntax checking.
- #
- # The components accepted are host, port, dn, attributes,
- # scope, filter, and extensions.
- #
- # The components should be provided either as an Array, or as a Hash
- # with keys formed by preceding the component names with a colon.
- #
- # If an Array is used, the components must be passed in the
- # order <code>[host, port, dn, attributes, scope, filter, extensions]</code>.
- #
- # Example:
- #
- # uri = Gem::URI::LDAP.build({:host => 'ldap.example.com',
- # :dn => '/dc=example'})
- #
- # uri = Gem::URI::LDAP.build(["ldap.example.com", nil,
- # "/dc=example;dc=com", "query", nil, nil, nil])
- #
- def self.build(args)
- tmp = Util::make_components_hash(self, args)
-
- if tmp[:dn]
- tmp[:path] = tmp[:dn]
- end
-
- query = []
- [:extensions, :filter, :scope, :attributes].collect do |x|
- next if !tmp[x] && query.size == 0
- query.unshift(tmp[x])
- end
-
- tmp[:query] = query.join('?')
-
- return super(tmp)
- end
-
- #
- # == Description
- #
- # Creates a new Gem::URI::LDAP object from generic Gem::URI components as per
- # RFC 2396. No LDAP-specific syntax checking is performed.
- #
- # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
- # +opaque+, +query+, and +fragment+, in that order.
- #
- # Example:
- #
- # uri = Gem::URI::LDAP.new("ldap", nil, "ldap.example.com", nil, nil,
- # "/dc=example;dc=com", nil, "query", nil)
- #
- # See also Gem::URI::Generic.new.
- #
- def initialize(*arg)
- super(*arg)
-
- if @fragment
- raise InvalidURIError, 'bad LDAP URL'
- end
-
- parse_dn
- parse_query
- end
-
- # Private method to cleanup +dn+ from using the +path+ component attribute.
- def parse_dn
- raise InvalidURIError, 'bad LDAP URL' unless @path
- @dn = @path[1..-1]
- end
- private :parse_dn
-
- # Private method to cleanup +attributes+, +scope+, +filter+, and +extensions+
- # from using the +query+ component attribute.
- def parse_query
- @attributes = nil
- @scope = nil
- @filter = nil
- @extensions = nil
-
- if @query
- attrs, scope, filter, extensions = @query.split('?')
-
- @attributes = attrs if attrs && attrs.size > 0
- @scope = scope if scope && scope.size > 0
- @filter = filter if filter && filter.size > 0
- @extensions = extensions if extensions && extensions.size > 0
- end
- end
- private :parse_query
-
- # Private method to assemble +query+ from +attributes+, +scope+, +filter+, and +extensions+.
- def build_path_query
- @path = '/' + @dn
-
- query = []
- [@extensions, @filter, @scope, @attributes].each do |x|
- next if !x && query.size == 0
- query.unshift(x)
- end
- @query = query.join('?')
- end
- private :build_path_query
-
- # Returns dn.
- def dn
- @dn
- end
-
- # Private setter for dn +val+.
- def set_dn(val)
- @dn = val
- build_path_query
- @dn
- end
- protected :set_dn
-
- # Setter for dn +val+.
- def dn=(val)
- set_dn(val)
- val
- end
-
- # Returns attributes.
- def attributes
- @attributes
- end
-
- # Private setter for attributes +val+.
- def set_attributes(val)
- @attributes = val
- build_path_query
- @attributes
- end
- protected :set_attributes
-
- # Setter for attributes +val+.
- def attributes=(val)
- set_attributes(val)
- val
- end
-
- # Returns scope.
- def scope
- @scope
- end
-
- # Private setter for scope +val+.
- def set_scope(val)
- @scope = val
- build_path_query
- @scope
- end
- protected :set_scope
-
- # Setter for scope +val+.
- def scope=(val)
- set_scope(val)
- val
- end
-
- # Returns filter.
- def filter
- @filter
- end
-
- # Private setter for filter +val+.
- def set_filter(val)
- @filter = val
- build_path_query
- @filter
- end
- protected :set_filter
-
- # Setter for filter +val+.
- def filter=(val)
- set_filter(val)
- val
- end
-
- # Returns extensions.
- def extensions
- @extensions
- end
-
- # Private setter for extensions +val+.
- def set_extensions(val)
- @extensions = val
- build_path_query
- @extensions
- end
- protected :set_extensions
-
- # Setter for extensions +val+.
- def extensions=(val)
- set_extensions(val)
- val
- end
-
- # Checks if Gem::URI has a path.
- # For Gem::URI::LDAP this will return +false+.
- def hierarchical?
- false
- end
- end
-
- register_scheme 'LDAP', LDAP
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/ldaps.rb b/lib/rubygems/vendor/uri/lib/uri/ldaps.rb
deleted file mode 100644
index b7a5b50e27..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/ldaps.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: false
-# = uri/ldap.rb
-#
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'ldap'
-
-module Gem::URI
-
- # The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather
- # than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs;
- # see Gem::URI::LDAP.
- class LDAPS < LDAP
- # A Default port of 636 for Gem::URI::LDAPS
- DEFAULT_PORT = 636
- end
-
- register_scheme 'LDAPS', LDAPS
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/mailto.rb b/lib/rubygems/vendor/uri/lib/uri/mailto.rb
deleted file mode 100644
index 7ae544d194..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/mailto.rb
+++ /dev/null
@@ -1,293 +0,0 @@
-# frozen_string_literal: false
-# = uri/mailto.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'generic'
-
-module Gem::URI
-
- #
- # RFC6068, the mailto URL scheme.
- #
- class MailTo < Generic
- include RFC2396_REGEXP
-
- # A Default port of nil for Gem::URI::MailTo.
- DEFAULT_PORT = nil
-
- # An Array of the available components for Gem::URI::MailTo.
- COMPONENT = [ :scheme, :to, :headers ].freeze
-
- # :stopdoc:
- # "hname" and "hvalue" are encodings of an RFC 822 header name and
- # value, respectively. As with "to", all URL reserved characters must
- # be encoded.
- #
- # "#mailbox" is as specified in RFC 822 [RFC822]. This means that it
- # consists of zero or more comma-separated mail addresses, possibly
- # including "phrase" and "comment" components. Note that all URL
- # reserved characters in "to" must be encoded: in particular,
- # parentheses, commas, and the percent sign ("%"), which commonly occur
- # in the "mailbox" syntax.
- #
- # Within mailto URLs, the characters "?", "=", "&" are reserved.
-
- # ; RFC 6068
- # hfields = "?" hfield *( "&" hfield )
- # hfield = hfname "=" hfvalue
- # hfname = *qchar
- # hfvalue = *qchar
- # qchar = unreserved / pct-encoded / some-delims
- # some-delims = "!" / "$" / "'" / "(" / ")" / "*"
- # / "+" / "," / ";" / ":" / "@"
- #
- # ; RFC3986
- # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
- # pct-encoded = "%" HEXDIG HEXDIG
- HEADER_REGEXP = /\A(?<hfield>(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g<hfield>)*\z/
- # practical regexp for email address
- # https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
- EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
- # :startdoc:
-
- #
- # == Description
- #
- # Creates a new Gem::URI::MailTo object from components, with syntax checking.
- #
- # Components can be provided as an Array or Hash. If an Array is used,
- # the components must be supplied as <code>[to, headers]</code>.
- #
- # If a Hash is used, the keys are the component names preceded by colons.
- #
- # The headers can be supplied as a pre-encoded string, such as
- # <code>"subject=subscribe&cc=address"</code>, or as an Array of Arrays
- # like <code>[['subject', 'subscribe'], ['cc', 'address']]</code>.
- #
- # Examples:
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # m1 = Gem::URI::MailTo.build(['joe@example.com', 'subject=Ruby'])
- # m1.to_s # => "mailto:joe@example.com?subject=Ruby"
- #
- # m2 = Gem::URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]])
- # m2.to_s # => "mailto:john@example.com?Subject=Ruby&Cc=jack@example.com"
- #
- # m3 = Gem::URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]})
- # m3.to_s # => "mailto:listman@example.com?subject=subscribe"
- #
- def self.build(args)
- tmp = Util.make_components_hash(self, args)
-
- case tmp[:to]
- when Array
- tmp[:opaque] = tmp[:to].join(',')
- when String
- tmp[:opaque] = tmp[:to].dup
- else
- tmp[:opaque] = ''
- end
-
- if tmp[:headers]
- query =
- case tmp[:headers]
- when Array
- tmp[:headers].collect { |x|
- if x.kind_of?(Array)
- x[0] + '=' + x[1..-1].join
- else
- x.to_s
- end
- }.join('&')
- when Hash
- tmp[:headers].collect { |h,v|
- h + '=' + v
- }.join('&')
- else
- tmp[:headers].to_s
- end
- unless query.empty?
- tmp[:opaque] << '?' << query
- end
- end
-
- super(tmp)
- end
-
- #
- # == Description
- #
- # Creates a new Gem::URI::MailTo object from generic URL components with
- # no syntax checking.
- #
- # This method is usually called from Gem::URI::parse, which checks
- # the validity of each component.
- #
- def initialize(*arg)
- super(*arg)
-
- @to = nil
- @headers = []
-
- # The RFC3986 parser does not normally populate opaque
- @opaque = "?#{@query}" if @query && !@opaque
-
- unless @opaque
- raise InvalidComponentError,
- "missing opaque part for mailto URL"
- end
- to, header = @opaque.split('?', 2)
- # allow semicolon as a addr-spec separator
- # http://support.microsoft.com/kb/820868
- unless /\A(?:[^@,;]+@[^@,;]+(?:\z|[,;]))*\z/ =~ to
- raise InvalidComponentError,
- "unrecognised opaque part for mailtoURL: #{@opaque}"
- end
-
- if arg[10] # arg_check
- self.to = to
- self.headers = header
- else
- set_to(to)
- set_headers(header)
- end
- end
-
- # The primary e-mail address of the URL, as a String.
- attr_reader :to
-
- # E-mail headers set by the URL, as an Array of Arrays.
- attr_reader :headers
-
- # Checks the to +v+ component.
- def check_to(v)
- return true unless v
- return true if v.size == 0
-
- v.split(/[,;]/).each do |addr|
- # check url safety as path-rootless
- if /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*\z/ !~ addr
- raise InvalidComponentError,
- "an address in 'to' is invalid as Gem::URI #{addr.dump}"
- end
-
- # check addr-spec
- # don't s/\+/ /g
- addr.gsub!(/%\h\h/, Gem::URI::TBLDECWWWCOMP_)
- if EMAIL_REGEXP !~ addr
- raise InvalidComponentError,
- "an address in 'to' is invalid as uri-escaped addr-spec #{addr.dump}"
- end
- end
-
- true
- end
- private :check_to
-
- # Private setter for to +v+.
- def set_to(v)
- @to = v
- end
- protected :set_to
-
- # Setter for to +v+.
- def to=(v)
- check_to(v)
- set_to(v)
- v
- end
-
- # Checks the headers +v+ component against either
- # * HEADER_REGEXP
- def check_headers(v)
- return true unless v
- return true if v.size == 0
- if HEADER_REGEXP !~ v
- raise InvalidComponentError,
- "bad component(expected opaque component): #{v}"
- end
-
- true
- end
- private :check_headers
-
- # Private setter for headers +v+.
- def set_headers(v)
- @headers = []
- if v
- v.split('&').each do |x|
- @headers << x.split(/=/, 2)
- end
- end
- end
- protected :set_headers
-
- # Setter for headers +v+.
- def headers=(v)
- check_headers(v)
- set_headers(v)
- v
- end
-
- # Constructs String from Gem::URI.
- def to_s
- @scheme + ':' +
- if @to
- @to
- else
- ''
- end +
- if @headers.size > 0
- '?' + @headers.collect{|x| x.join('=')}.join('&')
- else
- ''
- end +
- if @fragment
- '#' + @fragment
- else
- ''
- end
- end
-
- # Returns the RFC822 e-mail text equivalent of the URL, as a String.
- #
- # Example:
- #
- # require 'rubygems/vendor/uri/lib/uri'
- #
- # uri = Gem::URI.parse("mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr")
- # uri.to_mailtext
- # # => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n"
- #
- def to_mailtext
- to = Gem::URI.decode_www_form_component(@to)
- head = ''
- body = ''
- @headers.each do |x|
- case x[0]
- when 'body'
- body = Gem::URI.decode_www_form_component(x[1])
- when 'to'
- to << ', ' + Gem::URI.decode_www_form_component(x[1])
- else
- head << Gem::URI.decode_www_form_component(x[0]).capitalize + ': ' +
- Gem::URI.decode_www_form_component(x[1]) + "\n"
- end
- end
-
- "To: #{to}
-#{head}
-#{body}
-"
- end
- alias to_rfc822text to_mailtext
- end
-
- register_scheme 'MAILTO', MailTo
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb b/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb
deleted file mode 100644
index 735a269f2c..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb
+++ /dev/null
@@ -1,539 +0,0 @@
-# frozen_string_literal: false
-#--
-# = uri/common.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License::
-# You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-module Gem::URI
- #
- # Includes Gem::URI::REGEXP::PATTERN
- #
- module RFC2396_REGEXP
- #
- # Patterns used to parse Gem::URI's
- #
- module PATTERN
- # :stopdoc:
-
- # RFC 2396 (Gem::URI Generic Syntax)
- # RFC 2732 (IPv6 Literal Addresses in URL's)
- # RFC 2373 (IPv6 Addressing Architecture)
-
- # alpha = lowalpha | upalpha
- ALPHA = "a-zA-Z"
- # alphanum = alpha | digit
- ALNUM = "#{ALPHA}\\d"
-
- # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
- # "a" | "b" | "c" | "d" | "e" | "f"
- HEX = "a-fA-F\\d"
- # escaped = "%" hex hex
- ESCAPED = "%[#{HEX}]{2}"
- # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
- # "(" | ")"
- # unreserved = alphanum | mark
- UNRESERVED = "\\-_.!~*'()#{ALNUM}"
- # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
- # "$" | ","
- # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
- # "$" | "," | "[" | "]" (RFC 2732)
- RESERVED = ";/?:@&=+$,\\[\\]"
-
- # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
- DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
- # toplabel = alpha | alpha *( alphanum | "-" ) alphanum
- TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
- # hostname = *( domainlabel "." ) toplabel [ "." ]
- HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"
-
- # :startdoc:
- end # PATTERN
-
- # :startdoc:
- end # REGEXP
-
- # Class that parses String's into Gem::URI's.
- #
- # It contains a Hash set of patterns and Regexp's that match and validate.
- #
- class RFC2396_Parser
- include RFC2396_REGEXP
-
- #
- # == Synopsis
- #
- # Gem::URI::Parser.new([opts])
- #
- # == Args
- #
- # The constructor accepts a hash as options for parser.
- # Keys of options are pattern names of Gem::URI components
- # and values of options are pattern strings.
- # The constructor generates set of regexps for parsing URIs.
- #
- # You can use the following keys:
- #
- # * :ESCAPED (Gem::URI::PATTERN::ESCAPED in default)
- # * :UNRESERVED (Gem::URI::PATTERN::UNRESERVED in default)
- # * :DOMLABEL (Gem::URI::PATTERN::DOMLABEL in default)
- # * :TOPLABEL (Gem::URI::PATTERN::TOPLABEL in default)
- # * :HOSTNAME (Gem::URI::PATTERN::HOSTNAME in default)
- #
- # == Examples
- #
- # p = Gem::URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})")
- # u = p.parse("http://example.jp/%uABCD") #=> #<Gem::URI::HTTP http://example.jp/%uABCD>
- # Gem::URI.parse(u.to_s) #=> raises Gem::URI::InvalidURIError
- #
- # s = "http://example.com/ABCD"
- # u1 = p.parse(s) #=> #<Gem::URI::HTTP http://example.com/ABCD>
- # u2 = Gem::URI.parse(s) #=> #<Gem::URI::HTTP http://example.com/ABCD>
- # u1 == u2 #=> true
- # u1.eql?(u2) #=> false
- #
- def initialize(opts = {})
- @pattern = initialize_pattern(opts)
- @pattern.each_value(&:freeze)
- @pattern.freeze
-
- @regexp = initialize_regexp(@pattern)
- @regexp.each_value(&:freeze)
- @regexp.freeze
- end
-
- # The Hash of patterns.
- #
- # See also Gem::URI::Parser.initialize_pattern.
- attr_reader :pattern
-
- # The Hash of Regexp.
- #
- # See also Gem::URI::Parser.initialize_regexp.
- attr_reader :regexp
-
- # Returns a split Gem::URI against +regexp[:ABS_URI]+.
- def split(uri)
- case uri
- when ''
- # null uri
-
- when @regexp[:ABS_URI]
- scheme, opaque, userinfo, host, port,
- registry, path, query, fragment = $~[1..-1]
-
- # Gem::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- # opaque_part = uric_no_slash *uric
-
- # abs_path = "/" path_segments
- # net_path = "//" authority [ abs_path ]
-
- # authority = server | reg_name
- # server = [ [ userinfo "@" ] hostport ]
-
- if !scheme
- raise InvalidURIError,
- "bad Gem::URI(absolute but no scheme): #{uri}"
- end
- if !opaque && (!path && (!host && !registry))
- raise InvalidURIError,
- "bad Gem::URI(absolute but no path): #{uri}"
- end
-
- when @regexp[:REL_URI]
- scheme = nil
- opaque = nil
-
- userinfo, host, port, registry,
- rel_segment, abs_path, query, fragment = $~[1..-1]
- if rel_segment && abs_path
- path = rel_segment + abs_path
- elsif rel_segment
- path = rel_segment
- elsif abs_path
- path = abs_path
- end
-
- # Gem::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-
- # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
-
- # net_path = "//" authority [ abs_path ]
- # abs_path = "/" path_segments
- # rel_path = rel_segment [ abs_path ]
-
- # authority = server | reg_name
- # server = [ [ userinfo "@" ] hostport ]
-
- else
- raise InvalidURIError, "bad Gem::URI(is not Gem::URI?): #{uri}"
- end
-
- path = '' if !path && !opaque # (see RFC2396 Section 5.2)
- ret = [
- scheme,
- userinfo, host, port, # X
- registry, # X
- path, # Y
- opaque, # Y
- query,
- fragment
- ]
- return ret
- end
-
- #
- # == Args
- #
- # +uri+::
- # String
- #
- # == Description
- #
- # Parses +uri+ and constructs either matching Gem::URI scheme object
- # (File, FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or Gem::URI::Generic.
- #
- # == Usage
- #
- # p = Gem::URI::Parser.new
- # p.parse("ldap://ldap.example.com/dc=example?user=john")
- # #=> #<Gem::URI::LDAP ldap://ldap.example.com/dc=example?user=john>
- #
- def parse(uri)
- Gem::URI.for(*self.split(uri), self)
- end
-
- #
- # == Args
- #
- # +uris+::
- # an Array of Strings
- #
- # == Description
- #
- # Attempts to parse and merge a set of URIs.
- #
- def join(*uris)
- uris[0] = convert_to_uri(uris[0])
- uris.inject :merge
- end
-
- #
- # :call-seq:
- # extract( str )
- # extract( str, schemes )
- # extract( str, schemes ) {|item| block }
- #
- # == Args
- #
- # +str+::
- # String to search
- # +schemes+::
- # Patterns to apply to +str+
- #
- # == Description
- #
- # Attempts to parse and merge a set of URIs.
- # If no +block+ given, then returns the result,
- # else it calls +block+ for each element in result.
- #
- # See also Gem::URI::Parser.make_regexp.
- #
- def extract(str, schemes = nil)
- if block_given?
- str.scan(make_regexp(schemes)) { yield $& }
- nil
- else
- result = []
- str.scan(make_regexp(schemes)) { result.push $& }
- result
- end
- end
-
- # Returns Regexp that is default +self.regexp[:ABS_URI_REF]+,
- # unless +schemes+ is provided. Then it is a Regexp.union with +self.pattern[:X_ABS_URI]+.
- def make_regexp(schemes = nil)
- unless schemes
- @regexp[:ABS_URI_REF]
- else
- /(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
- end
- end
-
- #
- # :call-seq:
- # escape( str )
- # escape( str, unsafe )
- #
- # == Args
- #
- # +str+::
- # String to make safe
- # +unsafe+::
- # Regexp to apply. Defaults to +self.regexp[:UNSAFE]+
- #
- # == Description
- #
- # Constructs a safe String from +str+, removing unsafe characters,
- # replacing them with codes.
- #
- def escape(str, unsafe = @regexp[:UNSAFE])
- unless unsafe.kind_of?(Regexp)
- # perhaps unsafe is String object
- unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
- end
- str.gsub(unsafe) do
- us = $&
- tmp = ''
- us.each_byte do |uc|
- tmp << sprintf('%%%02X', uc)
- end
- tmp
- end.force_encoding(Encoding::US_ASCII)
- end
-
- #
- # :call-seq:
- # unescape( str )
- # unescape( str, escaped )
- #
- # == Args
- #
- # +str+::
- # String to remove escapes from
- # +escaped+::
- # Regexp to apply. Defaults to +self.regexp[:ESCAPED]+
- #
- # == Description
- #
- # Removes escapes from +str+.
- #
- def unescape(str, escaped = @regexp[:ESCAPED])
- enc = str.encoding
- enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
- str.gsub(escaped) { [$&[1, 2]].pack('H2').force_encoding(enc) }
- end
-
- @@to_s = Kernel.instance_method(:to_s)
- if @@to_s.respond_to?(:bind_call)
- def inspect
- @@to_s.bind_call(self)
- end
- else
- def inspect
- @@to_s.bind(self).call
- end
- end
-
- private
-
- # Constructs the default Hash of patterns.
- def initialize_pattern(opts = {})
- ret = {}
- ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED)
- ret[:UNRESERVED] = unreserved = opts.delete(:UNRESERVED) || PATTERN::UNRESERVED
- ret[:RESERVED] = reserved = opts.delete(:RESERVED) || PATTERN::RESERVED
- ret[:DOMLABEL] = opts.delete(:DOMLABEL) || PATTERN::DOMLABEL
- ret[:TOPLABEL] = opts.delete(:TOPLABEL) || PATTERN::TOPLABEL
- ret[:HOSTNAME] = hostname = opts.delete(:HOSTNAME)
-
- # RFC 2396 (Gem::URI Generic Syntax)
- # RFC 2732 (IPv6 Literal Addresses in URL's)
- # RFC 2373 (IPv6 Addressing Architecture)
-
- # uric = reserved | unreserved | escaped
- ret[:URIC] = uric = "(?:[#{unreserved}#{reserved}]|#{escaped})"
- # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
- # "&" | "=" | "+" | "$" | ","
- ret[:URIC_NO_SLASH] = uric_no_slash = "(?:[#{unreserved};?:@&=+$,]|#{escaped})"
- # query = *uric
- ret[:QUERY] = query = "#{uric}*"
- # fragment = *uric
- ret[:FRAGMENT] = fragment = "#{uric}*"
-
- # hostname = *( domainlabel "." ) toplabel [ "." ]
- # reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986
- unless hostname
- ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
- end
-
- # RFC 2373, APPENDIX B:
- # IPv6address = hexpart [ ":" IPv4address ]
- # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
- # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
- # hexseq = hex4 *( ":" hex4)
- # hex4 = 1*4HEXDIG
- #
- # XXX: This definition has a flaw. "::" + IPv4address must be
- # allowed too. Here is a replacement.
- #
- # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
- ret[:IPV4ADDR] = ipv4addr = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
- # hex4 = 1*4HEXDIG
- hex4 = "[#{PATTERN::HEX}]{1,4}"
- # lastpart = hex4 | IPv4address
- lastpart = "(?:#{hex4}|#{ipv4addr})"
- # hexseq1 = *( hex4 ":" ) hex4
- hexseq1 = "(?:#{hex4}:)*#{hex4}"
- # hexseq2 = *( hex4 ":" ) lastpart
- hexseq2 = "(?:#{hex4}:)*#{lastpart}"
- # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ]
- ret[:IPV6ADDR] = ipv6addr = "(?:#{hexseq2}|(?:#{hexseq1})?::(?:#{hexseq2})?)"
-
- # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT
- # unused
-
- # ipv6reference = "[" IPv6address "]" (RFC 2732)
- ret[:IPV6REF] = ipv6ref = "\\[#{ipv6addr}\\]"
-
- # host = hostname | IPv4address
- # host = hostname | IPv4address | IPv6reference (RFC 2732)
- ret[:HOST] = host = "(?:#{hostname}|#{ipv4addr}|#{ipv6ref})"
- # port = *digit
- ret[:PORT] = port = '\d*'
- # hostport = host [ ":" port ]
- ret[:HOSTPORT] = hostport = "#{host}(?::#{port})?"
-
- # userinfo = *( unreserved | escaped |
- # ";" | ":" | "&" | "=" | "+" | "$" | "," )
- ret[:USERINFO] = userinfo = "(?:[#{unreserved};:&=+$,]|#{escaped})*"
-
- # pchar = unreserved | escaped |
- # ":" | "@" | "&" | "=" | "+" | "$" | ","
- pchar = "(?:[#{unreserved}:@&=+$,]|#{escaped})"
- # param = *pchar
- param = "#{pchar}*"
- # segment = *pchar *( ";" param )
- segment = "#{pchar}*(?:;#{param})*"
- # path_segments = segment *( "/" segment )
- ret[:PATH_SEGMENTS] = path_segments = "#{segment}(?:/#{segment})*"
-
- # server = [ [ userinfo "@" ] hostport ]
- server = "(?:#{userinfo}@)?#{hostport}"
- # reg_name = 1*( unreserved | escaped | "$" | "," |
- # ";" | ":" | "@" | "&" | "=" | "+" )
- ret[:REG_NAME] = reg_name = "(?:[#{unreserved}$,;:@&=+]|#{escaped})+"
- # authority = server | reg_name
- authority = "(?:#{server}|#{reg_name})"
-
- # rel_segment = 1*( unreserved | escaped |
- # ";" | "@" | "&" | "=" | "+" | "$" | "," )
- ret[:REL_SEGMENT] = rel_segment = "(?:[#{unreserved};@&=+$,]|#{escaped})+"
-
- # scheme = alpha *( alpha | digit | "+" | "-" | "." )
- ret[:SCHEME] = scheme = "[#{PATTERN::ALPHA}][\\-+.#{PATTERN::ALPHA}\\d]*"
-
- # abs_path = "/" path_segments
- ret[:ABS_PATH] = abs_path = "/#{path_segments}"
- # rel_path = rel_segment [ abs_path ]
- ret[:REL_PATH] = rel_path = "#{rel_segment}(?:#{abs_path})?"
- # net_path = "//" authority [ abs_path ]
- ret[:NET_PATH] = net_path = "//#{authority}(?:#{abs_path})?"
-
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- ret[:HIER_PART] = hier_part = "(?:#{net_path}|#{abs_path})(?:\\?(?:#{query}))?"
- # opaque_part = uric_no_slash *uric
- ret[:OPAQUE_PART] = opaque_part = "#{uric_no_slash}#{uric}*"
-
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- ret[:ABS_URI] = abs_uri = "#{scheme}:(?:#{hier_part}|#{opaque_part})"
- # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
- ret[:REL_URI] = rel_uri = "(?:#{net_path}|#{abs_path}|#{rel_path})(?:\\?#{query})?"
-
- # Gem::URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
- ret[:URI_REF] = "(?:#{abs_uri}|#{rel_uri})?(?:##{fragment})?"
-
- ret[:X_ABS_URI] = "
- (#{scheme}): (?# 1: scheme)
- (?:
- (#{opaque_part}) (?# 2: opaque)
- |
- (?:(?:
- //(?:
- (?:(?:(#{userinfo})@)? (?# 3: userinfo)
- (?:(#{host})(?::(\\d*))?))? (?# 4: host, 5: port)
- |
- (#{reg_name}) (?# 6: registry)
- )
- |
- (?!//)) (?# XXX: '//' is the mark for hostport)
- (#{abs_path})? (?# 7: path)
- )(?:\\?(#{query}))? (?# 8: query)
- )
- (?:\\#(#{fragment}))? (?# 9: fragment)
- "
-
- ret[:X_REL_URI] = "
- (?:
- (?:
- //
- (?:
- (?:(#{userinfo})@)? (?# 1: userinfo)
- (#{host})?(?::(\\d*))? (?# 2: host, 3: port)
- |
- (#{reg_name}) (?# 4: registry)
- )
- )
- |
- (#{rel_segment}) (?# 5: rel_segment)
- )?
- (#{abs_path})? (?# 6: abs_path)
- (?:\\?(#{query}))? (?# 7: query)
- (?:\\#(#{fragment}))? (?# 8: fragment)
- "
-
- ret
- end
-
- # Constructs the default Hash of Regexp's.
- def initialize_regexp(pattern)
- ret = {}
-
- # for Gem::URI::split
- ret[:ABS_URI] = Regexp.new('\A\s*+' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
- ret[:REL_URI] = Regexp.new('\A\s*+' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
-
- # for Gem::URI::extract
- ret[:URI_REF] = Regexp.new(pattern[:URI_REF])
- ret[:ABS_URI_REF] = Regexp.new(pattern[:X_ABS_URI], Regexp::EXTENDED)
- ret[:REL_URI_REF] = Regexp.new(pattern[:X_REL_URI], Regexp::EXTENDED)
-
- # for Gem::URI::escape/unescape
- ret[:ESCAPED] = Regexp.new(pattern[:ESCAPED])
- ret[:UNSAFE] = Regexp.new("[^#{pattern[:UNRESERVED]}#{pattern[:RESERVED]}]")
-
- # for Generic#initialize
- ret[:SCHEME] = Regexp.new("\\A#{pattern[:SCHEME]}\\z")
- ret[:USERINFO] = Regexp.new("\\A#{pattern[:USERINFO]}\\z")
- ret[:HOST] = Regexp.new("\\A#{pattern[:HOST]}\\z")
- ret[:PORT] = Regexp.new("\\A#{pattern[:PORT]}\\z")
- ret[:OPAQUE] = Regexp.new("\\A#{pattern[:OPAQUE_PART]}\\z")
- ret[:REGISTRY] = Regexp.new("\\A#{pattern[:REG_NAME]}\\z")
- ret[:ABS_PATH] = Regexp.new("\\A#{pattern[:ABS_PATH]}\\z")
- ret[:REL_PATH] = Regexp.new("\\A#{pattern[:REL_PATH]}\\z")
- ret[:QUERY] = Regexp.new("\\A#{pattern[:QUERY]}\\z")
- ret[:FRAGMENT] = Regexp.new("\\A#{pattern[:FRAGMENT]}\\z")
-
- ret
- end
-
- def convert_to_uri(uri)
- if uri.is_a?(Gem::URI::Generic)
- uri
- elsif uri = String.try_convert(uri)
- parse(uri)
- else
- raise ArgumentError,
- "bad argument (expected Gem::URI object or Gem::URI string)"
- end
- end
-
- end # class Parser
-end # module Gem::URI
diff --git a/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb b/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb
deleted file mode 100644
index 728bb55674..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb
+++ /dev/null
@@ -1,183 +0,0 @@
-# frozen_string_literal: true
-module Gem::URI
- class RFC3986_Parser # :nodoc:
- # Gem::URI defined in RFC3986
- HOST = %r[
- (?<IP-literal>\[(?:
- (?<IPv6address>
- (?:\h{1,4}:){6}
- (?<ls32>\h{1,4}:\h{1,4}
- | (?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)
- \.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>)
- )
- | ::(?:\h{1,4}:){5}\g<ls32>
- | \h{1,4}?::(?:\h{1,4}:){4}\g<ls32>
- | (?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>
- | (?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>
- | (?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>
- | (?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>
- | (?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}
- | (?:(?:\h{1,4}:){,6}\h{1,4})?::
- )
- | (?<IPvFuture>v\h++\.[!$&-.0-9:;=A-Z_a-z~]++)
- )\])
- | \g<IPv4address>
- | (?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*+)
- ]x
-
- USERINFO = /(?:%\h\h|[!$&-.0-9:;=A-Z_a-z~])*+/
-
- SCHEME = %r[[A-Za-z][+\-.0-9A-Za-z]*+].source
- SEG = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/])].source
- SEG_NC = %r[(?:%\h\h|[!$&-.0-9;=@A-Z_a-z~])].source
- FRAGMENT = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+].source
-
- RFC3986_URI = %r[\A
- (?<seg>#{SEG}){0}
- (?<Gem::URI>
- (?<scheme>#{SCHEME}):
- (?<hier-part>//
- (?<authority>
- (?:(?<userinfo>#{USERINFO.source})@)?
- (?<host>#{HOST.source.delete(" \n")})
- (?::(?<port>\d*+))?
- )
- (?<path-abempty>(?:/\g<seg>*+)?)
- | (?<path-absolute>/((?!/)\g<seg>++)?)
- | (?<path-rootless>(?!/)\g<seg>++)
- | (?<path-empty>)
- )
- (?:\?(?<query>[^\#]*+))?
- (?:\#(?<fragment>#{FRAGMENT}))?
- )\z]x
-
- RFC3986_relative_ref = %r[\A
- (?<seg>#{SEG}){0}
- (?<relative-ref>
- (?<relative-part>//
- (?<authority>
- (?:(?<userinfo>#{USERINFO.source})@)?
- (?<host>#{HOST.source.delete(" \n")}(?<!/))?
- (?::(?<port>\d*+))?
- )
- (?<path-abempty>(?:/\g<seg>*+)?)
- | (?<path-absolute>/\g<seg>*+)
- | (?<path-noscheme>#{SEG_NC}++(?:/\g<seg>*+)?)
- | (?<path-empty>)
- )
- (?:\?(?<query>[^#]*+))?
- (?:\#(?<fragment>#{FRAGMENT}))?
- )\z]x
- attr_reader :regexp
-
- def initialize
- @regexp = default_regexp.each_value(&:freeze).freeze
- end
-
- def split(uri) #:nodoc:
- begin
- uri = uri.to_str
- rescue NoMethodError
- raise InvalidURIError, "bad Gem::URI(is not Gem::URI?): #{uri.inspect}"
- end
- uri.ascii_only? or
- raise InvalidURIError, "Gem::URI must be ascii only #{uri.dump}"
- if m = RFC3986_URI.match(uri)
- query = m["query"]
- scheme = m["scheme"]
- opaque = m["path-rootless"]
- if opaque
- opaque << "?#{query}" if query
- [ scheme,
- nil, # userinfo
- nil, # host
- nil, # port
- nil, # registry
- nil, # path
- opaque,
- nil, # query
- m["fragment"]
- ]
- else # normal
- [ scheme,
- m["userinfo"],
- m["host"],
- m["port"],
- nil, # registry
- (m["path-abempty"] ||
- m["path-absolute"] ||
- m["path-empty"]),
- nil, # opaque
- query,
- m["fragment"]
- ]
- end
- elsif m = RFC3986_relative_ref.match(uri)
- [ nil, # scheme
- m["userinfo"],
- m["host"],
- m["port"],
- nil, # registry,
- (m["path-abempty"] ||
- m["path-absolute"] ||
- m["path-noscheme"] ||
- m["path-empty"]),
- nil, # opaque
- m["query"],
- m["fragment"]
- ]
- else
- raise InvalidURIError, "bad Gem::URI(is not Gem::URI?): #{uri.inspect}"
- end
- end
-
- def parse(uri) # :nodoc:
- Gem::URI.for(*self.split(uri), self)
- end
-
-
- def join(*uris) # :nodoc:
- uris[0] = convert_to_uri(uris[0])
- uris.inject :merge
- end
-
- @@to_s = Kernel.instance_method(:to_s)
- if @@to_s.respond_to?(:bind_call)
- def inspect
- @@to_s.bind_call(self)
- end
- else
- def inspect
- @@to_s.bind(self).call
- end
- end
-
- private
-
- def default_regexp # :nodoc:
- {
- SCHEME: %r[\A#{SCHEME}\z]o,
- USERINFO: %r[\A#{USERINFO}\z]o,
- HOST: %r[\A#{HOST}\z]o,
- ABS_PATH: %r[\A/#{SEG}*+\z]o,
- REL_PATH: %r[\A(?!/)#{SEG}++\z]o,
- QUERY: %r[\A(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+\z],
- FRAGMENT: %r[\A#{FRAGMENT}\z]o,
- OPAQUE: %r[\A(?:[^/].*)?\z],
- PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
- }
- end
-
- def convert_to_uri(uri)
- if uri.is_a?(Gem::URI::Generic)
- uri
- elsif uri = String.try_convert(uri)
- parse(uri)
- else
- raise ArgumentError,
- "bad argument (expected Gem::URI object or Gem::URI string)"
- end
- end
-
- end # class Parser
-end # module Gem::URI
diff --git a/lib/rubygems/vendor/uri/lib/uri/version.rb b/lib/rubygems/vendor/uri/lib/uri/version.rb
deleted file mode 100644
index 3c80c334d4..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/version.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Gem::URI
- # :stopdoc:
- VERSION_CODE = '001300'.freeze
- VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
- # :startdoc:
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/ws.rb b/lib/rubygems/vendor/uri/lib/uri/ws.rb
deleted file mode 100644
index 0dd2a7a1bb..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/ws.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-# frozen_string_literal: false
-# = uri/ws.rb
-#
-# Author:: Matt Muller <mamuller@amazon.com>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'generic'
-
-module Gem::URI
-
- #
- # The syntax of WS URIs is defined in RFC6455 section 3.
- #
- # Note that the Ruby Gem::URI library allows WS URLs containing usernames and
- # passwords. This is not legal as per the RFC, but used to be
- # supported in Internet Explorer 5 and 6, before the MS04-004 security
- # update. See <URL:http://support.microsoft.com/kb/834489>.
- #
- class WS < Generic
- # A Default port of 80 for Gem::URI::WS.
- DEFAULT_PORT = 80
-
- # An Array of the available components for Gem::URI::WS.
- COMPONENT = %i[
- scheme
- userinfo host port
- path
- query
- ].freeze
-
- #
- # == Description
- #
- # Creates a new Gem::URI::WS object from components, with syntax checking.
- #
- # The components accepted are userinfo, host, port, path, and query.
- #
- # The components should be provided either as an Array, or as a Hash
- # with keys formed by preceding the component names with a colon.
- #
- # If an Array is used, the components must be passed in the
- # order <code>[userinfo, host, port, path, query]</code>.
- #
- # Example:
- #
- # uri = Gem::URI::WS.build(host: 'www.example.com', path: '/foo/bar')
- #
- # uri = Gem::URI::WS.build([nil, "www.example.com", nil, "/path", "query"])
- #
- # Currently, if passed userinfo components this method generates
- # invalid WS URIs as per RFC 1738.
- #
- def self.build(args)
- tmp = Util.make_components_hash(self, args)
- super(tmp)
- end
-
- #
- # == Description
- #
- # Returns the full path for a WS Gem::URI, as required by Net::HTTP::Get.
- #
- # If the Gem::URI contains a query, the full path is Gem::URI#path + '?' + Gem::URI#query.
- # Otherwise, the path is simply Gem::URI#path.
- #
- # Example:
- #
- # uri = Gem::URI::WS.build(path: '/foo/bar', query: 'test=true')
- # uri.request_uri # => "/foo/bar?test=true"
- #
- def request_uri
- return unless @path
-
- url = @query ? "#@path?#@query" : @path.dup
- url.start_with?(?/.freeze) ? url : ?/ + url
- end
- end
-
- register_scheme 'WS', WS
-end
diff --git a/lib/rubygems/vendor/uri/lib/uri/wss.rb b/lib/rubygems/vendor/uri/lib/uri/wss.rb
deleted file mode 100644
index 0b91d334bb..0000000000
--- a/lib/rubygems/vendor/uri/lib/uri/wss.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: false
-# = uri/wss.rb
-#
-# Author:: Matt Muller <mamuller@amazon.com>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-#
-# See Gem::URI for general documentation
-#
-
-require_relative 'ws'
-
-module Gem::URI
-
- # The default port for WSS URIs is 443, and the scheme is 'wss:' rather
- # than 'ws:'. Other than that, WSS URIs are identical to WS URIs;
- # see Gem::URI::WS.
- class WSS < WS
- # A Default port of 443 for Gem::URI::WSS
- DEFAULT_PORT = 443
- end
-
- register_scheme 'WSS', WSS
-end
diff --git a/lib/rubygems/vendored_molinillo.rb b/lib/rubygems/vendored_molinillo.rb
deleted file mode 100644
index 45906c0e5c..0000000000
--- a/lib/rubygems/vendored_molinillo.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "vendor/molinillo/lib/molinillo"
diff --git a/lib/rubygems/vendored_net_http.rb b/lib/rubygems/vendored_net_http.rb
deleted file mode 100644
index a84c52a947..0000000000
--- a/lib/rubygems/vendored_net_http.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-# Ruby 3.3 and RubyGems 3.5 is already load Gem::Timeout from lib/rubygems/net/http.rb
-# We should avoid to load it again
-require_relative "vendor/net-http/lib/net/http" unless defined?(Gem::Net::HTTP)
diff --git a/lib/rubygems/vendored_optparse.rb b/lib/rubygems/vendored_optparse.rb
deleted file mode 100644
index a5611d32f0..0000000000
--- a/lib/rubygems/vendored_optparse.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "vendor/optparse/lib/optparse"
diff --git a/lib/rubygems/vendored_timeout.rb b/lib/rubygems/vendored_timeout.rb
deleted file mode 100644
index 45541928e6..0000000000
--- a/lib/rubygems/vendored_timeout.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-# Ruby 3.3 and RubyGems 3.5 is already load Gem::Timeout from lib/rubygems/timeout.rb
-# We should avoid to load it again
-require_relative "vendor/timeout/lib/timeout" unless defined?(Gem::Timeout)
diff --git a/lib/rubygems/vendored_tsort.rb b/lib/rubygems/vendored_tsort.rb
deleted file mode 100644
index c3d815650d..0000000000
--- a/lib/rubygems/vendored_tsort.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "vendor/tsort/lib/tsort"
diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb
index e174d8ad95..c319e1f820 100644
--- a/lib/rubygems/version.rb
+++ b/lib/rubygems/version.rb
@@ -131,7 +131,7 @@ require_relative "deprecate"
#
# == Preventing Version Catastrophe:
#
-# From: https://www.zenspider.com/ruby/2008/10/rubygems-how-to-preventing-catastrophe.html
+# From: http://blog.zenspider.com/2008/10/rubygems-howto-preventing-cata.html
#
# Let's say you're depending on the fnord gem version 2.y.z. If you
# specify your dependency as ">= 2.0.0" then, you're good, right? What
@@ -156,16 +156,16 @@ class Gem::Version
include Comparable
VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/ # :nodoc:
+ ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze # :nodoc:
##
# A string representation of this Version.
def version
- @version
+ @version.dup
end
- alias_method :to_s, :version
+ alias to_s version
##
# True if the +version+ string matches RubyGems' requirements.
@@ -173,7 +173,7 @@ class Gem::Version
def self.correct?(version)
nil_versions_are_discouraged! if version.nil?
- ANCHORED_VERSION_PATTERN.match?(version.to_s)
+ !!(version.to_s =~ ANCHORED_VERSION_PATTERN)
end
##
@@ -201,7 +201,7 @@ class Gem::Version
@@release = {}
def self.new(version) # :nodoc:
- return super unless self == Gem::Version
+ return super unless Gem::Version == self
@@all[version] ||= super
end
@@ -224,17 +224,9 @@ class Gem::Version
end
# If version is an empty string convert it to 0
- version = 0 if version.is_a?(String) && /\A\s*\Z/.match?(version)
-
- @version = version.to_s
+ version = 0 if version.is_a?(String) && version =~ /\A\s*\Z/
- # optimization to avoid allocation when given an integer, since we know
- # it's to_s won't have any spaces or dashes
- unless version.is_a?(Integer)
- @version = @version.strip
- @version.gsub!("-",".pre.")
- end
- @version = -@version
+ @version = version.to_s.strip.gsub("-",".pre.")
@segments = nil
end
@@ -260,7 +252,7 @@ class Gem::Version
# same precision. Version "1.0" is not the same as version "1".
def eql?(other)
- self.class === other && @version == other.version
+ self.class === other && @version == other._version
end
def hash # :nodoc:
@@ -292,7 +284,7 @@ class Gem::Version
end
def yaml_initialize(tag, map) # :nodoc:
- @version = -map["version"]
+ @version = map["version"]
@segments = nil
@hash = nil
end
@@ -310,7 +302,7 @@ class Gem::Version
def prerelease?
unless instance_variable_defined? :@prerelease
- @prerelease = /[a-zA-Z]/.match?(version)
+ @prerelease = !!(@version =~ /[a-zA-Z]/)
end
@prerelease
end
@@ -362,7 +354,7 @@ class Gem::Version
return self <=> self.class.new(other) if (String === other) && self.class.correct?(other)
return unless Gem::Version === other
- return 0 if @version == other.version || canonical_segments == other.canonical_segments
+ return 0 if @version == other._version || canonical_segments == other.canonical_segments
lhsegments = canonical_segments
rhsegments = other.canonical_segments
@@ -374,8 +366,7 @@ class Gem::Version
i = 0
while i <= limit
- lhs = lhsegments[i] || 0
- rhs = rhsegments[i] || 0
+ lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
i += 1
next if lhs == rhs
@@ -385,40 +376,42 @@ class Gem::Version
return lhs <=> rhs
end
- 0
+ return 0
end
- # remove trailing zeros segments before first letter or at the end of the version
def canonical_segments
- @canonical_segments ||= begin
- # remove trailing 0 segments, using dot or letter as anchor
- # may leave a trailing dot which will be ignored by partition_segments
- canonical_version = @version.sub(/(?<=[a-zA-Z.])[.0]+\z/, "")
- # remove 0 segments before the first letter in a prerelease version
- canonical_version.sub!(/(?<=\.|\A)[0.]+(?=[a-zA-Z])/, "") if prerelease?
- partition_segments(canonical_version)
- end
+ @canonical_segments ||=
+ _split_segments.map! do |segments|
+ segments.reverse_each.drop_while {|s| s == 0 }.reverse
+ end.reduce(&:concat)
end
def freeze
prerelease?
- _segments
canonical_segments
super
end
protected
+ def _version
+ @version
+ end
+
def _segments
# segments is lazy so it can pick up version values that come from
# old marshaled versions, which don't go through marshal_load.
# since this version object is cached in @@all, its @segments should be frozen
- @segments ||= partition_segments(@version)
- end
- def partition_segments(ver)
- ver.scan(/\d+|[a-z]+/i).map! do |s|
- /\A\d/.match?(s) ? s.to_i : -s
+ @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
+ /^\d+$/ =~ s ? s.to_i : s
end.freeze
end
+
+ def _split_segments
+ string_start = _segments.index {|s| s.is_a?(String) }
+ string_segments = segments
+ numeric_segments = string_segments.slice!(0, string_start || string_segments.size)
+ return numeric_segments, string_segments
+ end
end
diff --git a/lib/rubygems/version_option.rb b/lib/rubygems/version_option.rb
index 7910fd3d1b..d83a69cf0d 100644
--- a/lib/rubygems/version_option.rb
+++ b/lib/rubygems/version_option.rb
@@ -12,6 +12,7 @@ require_relative "../rubygems"
# Mixin methods for --version and --platform Gem::Command options.
module Gem::VersionOption
+
##
# Add the --platform option to the option parser.
@@ -25,7 +26,8 @@ module Gem::VersionOption
end
add_option("--platform PLATFORM", Gem::Platform,
- "Specify the platform of gem to #{task}", *wrap) do |value, options|
+ "Specify the platform of gem to #{task}", *wrap) do
+ |value, options|
unless options[:added_platform]
Gem.platforms = [Gem::Platform::RUBY]
options[:added_platform] = true
@@ -55,7 +57,8 @@ module Gem::VersionOption
end
add_option("-v", "--version VERSION", Gem::Requirement,
- "Specify version of gem to #{task}", *wrap) do |value, options|
+ "Specify version of gem to #{task}", *wrap) do
+ |value, options|
# Allow handling for multiple --version operators
if options[:version] && !options[:version].none?
options[:version].concat([value])
diff --git a/lib/rubygems/yaml_serializer.rb b/lib/rubygems/yaml_serializer.rb
deleted file mode 100644
index 128becc1ce..0000000000
--- a/lib/rubygems/yaml_serializer.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-# frozen_string_literal: true
-
-module Gem
- # A stub yaml serializer that can handle only hashes and strings (as of now).
- module YAMLSerializer
- module_function
-
- def dump(hash)
- yaml = String.new("---")
- yaml << dump_hash(hash)
- end
-
- def dump_hash(hash)
- yaml = String.new("\n")
- hash.each do |k, v|
- yaml << k << ":"
- if v.is_a?(Hash)
- yaml << dump_hash(v).gsub(/^(?!$)/, " ") # indent all non-empty lines
- elsif v.is_a?(Array) # Expected to be array of strings
- if v.empty?
- yaml << " []\n"
- else
- yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n"
- end
- else
- yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n"
- end
- end
- yaml
- end
-
- ARRAY_REGEX = /
- ^
- (?:[ ]*-[ ]) # '- ' before array items
- (['"]?) # optional opening quote
- (.*) # value
- \1 # matching closing quote
- $
- /xo
-
- HASH_REGEX = /
- ^
- ([ ]*) # indentations
- (.+) # key
- (?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value)
- [ ]?
- (['"]?) # optional opening quote
- (.*) # value
- \3 # matching closing quote
- $
- /xo
-
- def load(str)
- res = {}
- stack = [res]
- last_hash = nil
- last_empty_key = nil
- str.split(/\r?\n/) do |line|
- if match = HASH_REGEX.match(line)
- indent, key, quote, val = match.captures
- val = strip_comment(val)
-
- convert_to_backward_compatible_key!(key)
- depth = indent.size / 2
- if quote.empty? && val.empty?
- new_hash = {}
- stack[depth][key] = new_hash
- stack[depth + 1] = new_hash
- last_empty_key = key
- last_hash = stack[depth]
- else
- val = [] if val == "[]" # empty array
- stack[depth][key] = val
- end
- elsif match = ARRAY_REGEX.match(line)
- _, val = match.captures
- val = strip_comment(val)
-
- last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array)
-
- last_hash[last_empty_key].push(val)
- end
- end
- res
- end
-
- def strip_comment(val)
- if val.include?("#") && !val.start_with?("#")
- val.split("#", 2).first.strip
- else
- val
- end
- end
-
- # for settings' keys
- def convert_to_backward_compatible_key!(key)
- key << "/" if /https?:/i.match?(key) && !%r{/\Z}.match?(key)
- key.gsub!(".", "__")
- end
-
- class << self
- private :dump_hash, :convert_to_backward_compatible_key!
- end
- end
-end
diff --git a/lib/securerandom.gemspec b/lib/securerandom.gemspec
index f42ddbcc97..e095244ce9 100644
--- a/lib/securerandom.gemspec
+++ b/lib/securerandom.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "securerandom"
+ spec.version = "0.2.2"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/lib/securerandom.rb b/lib/securerandom.rb
index 81757f3100..07ae048634 100644
--- a/lib/securerandom.rb
+++ b/lib/securerandom.rb
@@ -39,28 +39,28 @@ require 'random/formatter'
# +NotImplementedError+ is raised.
module SecureRandom
-
- # The version
- VERSION = "0.3.1"
-
class << self
- # Returns a random binary string containing +size+ bytes.
- #
- # See Random.bytes
def bytes(n)
return gen_random(n)
end
private
- # :stopdoc:
-
- # Implementation using OpenSSL
def gen_random_openssl(n)
+ @pid = 0 unless defined?(@pid)
+ pid = $$
+ unless @pid == pid
+ now = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
+ OpenSSL::Random.random_add([now, @pid, pid].join(""), 0.0)
+ seed = Random.urandom(16)
+ if (seed)
+ OpenSSL::Random.random_add(seed, 16)
+ end
+ @pid = pid
+ end
return OpenSSL::Random.random_bytes(n)
end
- # Implementation using system random device
def gen_random_urandom(n)
ret = Random.urandom(n)
unless ret
@@ -86,9 +86,6 @@ module SecureRandom
end
end
- # :startdoc:
-
- # Generate random data bytes for Random::Formatter
public :gen_random
end
end
diff --git a/lib/set.rb b/lib/set.rb
index a0954a31d1..df1e68d081 100644
--- a/lib/set.rb
+++ b/lib/set.rb
@@ -3,7 +3,7 @@
#
# set.rb - defines the Set class
#
-# Copyright (c) 2002-2023 Akinori MUSHA <knu@iDaemons.org>
+# Copyright (c) 2002-2020 Akinori MUSHA <knu@iDaemons.org>
#
# Documentation by Akinori MUSHA and Gavin Sinclair.
#
@@ -12,12 +12,16 @@
##
-# This library provides the Set class, which implements a collection
-# of unordered values with no duplicates. It is a hybrid of Array's
+# This library provides the Set class, which deals with a collection
+# of unordered values with no duplicates. It is a hybrid of Array's
# intuitive inter-operation facilities and Hash's fast lookup.
#
# The method `to_set` is added to Enumerable for convenience.
#
+# Set implements a collection of unordered values with no duplicates.
+# This is a hybrid of Array's intuitive inter-operation facilities and
+# Hash's fast lookup.
+#
# Set is easy to use with Enumerable objects (implementing `each`).
# Most of the initializer methods and binary operators accept generic
# Enumerable objects besides sets and arrays. An Enumerable object
@@ -152,7 +156,7 @@
# If the given object is not an element in the set,
# adds it and returns +self+; otherwise, returns +nil+.
# - \#merge:
-# Merges the elements of each given enumerable object to the set; returns +self+.
+# Adds each given object to the set; returns +self+.
# - \#replace:
# Replaces the contents of the set with the contents
# of a given enumerable.
@@ -216,8 +220,6 @@
# has been modified while an element in the set.
#
class Set
- VERSION = "1.1.0"
-
include Enumerable
# Creates a new set containing the given objects.
@@ -286,10 +288,18 @@ class Set
@hash = orig.instance_variable_get(:@hash).dup
end
- # Clone internal hash.
- def initialize_clone(orig, **options)
- super
- @hash = orig.instance_variable_get(:@hash).clone(**options)
+ if Kernel.instance_method(:initialize_clone).arity != 1
+ # Clone internal hash.
+ def initialize_clone(orig, **options)
+ super
+ @hash = orig.instance_variable_get(:@hash).clone(**options)
+ end
+ else
+ # Clone internal hash.
+ def initialize_clone(orig)
+ super
+ @hash = orig.instance_variable_get(:@hash).clone
+ end
end
def freeze # :nodoc:
@@ -381,7 +391,7 @@ class Set
# Equivalent to Set#flatten, but replaces the receiver with the
# result in place. Returns nil if no modifications were made.
def flatten!
- replace(flatten()) if any?(Set)
+ replace(flatten()) if any? { |e| e.is_a?(Set) }
end
# Returns true if the set contains the given object.
@@ -401,7 +411,7 @@ class Set
when set.instance_of?(self.class) && @hash.respond_to?(:>=)
@hash >= set.instance_variable_get(:@hash)
when set.is_a?(Set)
- size >= set.size && set.all?(self)
+ size >= set.size && set.all? { |o| include?(o) }
else
raise ArgumentError, "value must be a set"
end
@@ -414,7 +424,7 @@ class Set
when set.instance_of?(self.class) && @hash.respond_to?(:>)
@hash > set.instance_variable_get(:@hash)
when set.is_a?(Set)
- size > set.size && set.all?(self)
+ size > set.size && set.all? { |o| include?(o) }
else
raise ArgumentError, "value must be a set"
end
@@ -427,7 +437,7 @@ class Set
when set.instance_of?(self.class) && @hash.respond_to?(:<=)
@hash <= set.instance_variable_get(:@hash)
when set.is_a?(Set)
- size <= set.size && all?(set)
+ size <= set.size && all? { |o| set.include?(o) }
else
raise ArgumentError, "value must be a set"
end
@@ -440,7 +450,7 @@ class Set
when set.instance_of?(self.class) && @hash.respond_to?(:<)
@hash < set.instance_variable_get(:@hash)
when set.is_a?(Set)
- size < set.size && all?(set)
+ size < set.size && all? { |o| set.include?(o) }
else
raise ArgumentError, "value must be a set"
end
@@ -471,12 +481,12 @@ class Set
case set
when Set
if size < set.size
- any?(set)
+ any? { |o| set.include?(o) }
else
- set.any?(self)
+ set.any? { |o| include?(o) }
end
when Enumerable
- set.any?(self)
+ set.any? { |o| include?(o) }
else
raise ArgumentError, "value must be enumerable"
end
@@ -497,7 +507,7 @@ class Set
# the element as parameter. Returns an enumerator if no block is
# given.
def each(&block)
- block_given? or return enum_for(__method__) { size }
+ block or return enum_for(__method__) { size }
@hash.each_key(&block)
self
end
@@ -572,7 +582,7 @@ class Set
# Equivalent to Set#delete_if, but returns nil if no changes were
# made. Returns an enumerator if no block is given.
def reject!(&block)
- block_given? or return enum_for(__method__) { size }
+ block or return enum_for(__method__) { size }
n = size
delete_if(&block)
self if size != n
@@ -581,7 +591,7 @@ class Set
# Equivalent to Set#keep_if, but returns nil if no changes were
# made. Returns an enumerator if no block is given.
def select!(&block)
- block_given? or return enum_for(__method__) { size }
+ block or return enum_for(__method__) { size }
n = size
keep_if(&block)
self if size != n
@@ -590,15 +600,13 @@ class Set
# Equivalent to Set#select!
alias filter! select!
- # Merges the elements of the given enumerable objects to the set and
+ # Merges the elements of the given enumerable object to the set and
# returns self.
- def merge(*enums, **nil)
- enums.each do |enum|
- if enum.instance_of?(self.class)
- @hash.update(enum.instance_variable_get(:@hash))
- else
- do_with_enum(enum) { |o| add(o) }
- end
+ def merge(enum)
+ if enum.instance_of?(self.class)
+ @hash.update(enum.instance_variable_get(:@hash))
+ else
+ do_with_enum(enum) { |o| add(o) }
end
self
diff --git a/lib/set/set.gemspec b/lib/set/set.gemspec
index 2ebef6985d..0def52e859 100644
--- a/lib/set/set.gemspec
+++ b/lib/set/set.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "set"
+ spec.version = "1.0.3"
spec.authors = ["Akinori MUSHA"]
spec.email = ["knu@idaemons.org"]
@@ -15,7 +8,7 @@ Gem::Specification.new do |spec|
spec.description = %q{Provides a class to deal with collections of unordered, unique values}
spec.homepage = "https://github.com/ruby/set"
spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
diff --git a/lib/shellwords.gemspec b/lib/shellwords.gemspec
index d60ab5f650..8ae87b230e 100644
--- a/lib/shellwords.gemspec
+++ b/lib/shellwords.gemspec
@@ -1,14 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "shellwords"
+ spec.version = "0.1.0"
spec.authors = ["Akinori MUSHA"]
spec.email = ["knu@idaemons.org"]
diff --git a/lib/shellwords.rb b/lib/shellwords.rb
index 067432e374..4368a53ea8 100644
--- a/lib/shellwords.rb
+++ b/lib/shellwords.rb
@@ -68,8 +68,6 @@
# 1: {IEEE Std 1003.1-2008, 2016 Edition, the Shell & Utilities volume}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html]
module Shellwords
- VERSION = "0.2.0"
-
# Splits a string into an array of tokens in the same way the UNIX
# Bourne shell does.
#
diff --git a/lib/singleton.gemspec b/lib/singleton.gemspec
deleted file mode 100644
index 7646914905..0000000000
--- a/lib/singleton.gemspec
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{The Singleton module implements the Singleton pattern.}
- spec.description = spec.summary
- spec.homepage = "https://github.com/ruby/singleton"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-end
diff --git a/lib/singleton.rb b/lib/singleton.rb
index 6da939124e..07420d2ea2 100644
--- a/lib/singleton.rb
+++ b/lib/singleton.rb
@@ -92,7 +92,7 @@
# p a.strip # => nil
#
module Singleton
- VERSION = "0.2.0"
+ VERSION = "0.1.1"
# Raises a TypeError to prevent cloning.
def clone
@@ -121,7 +121,12 @@ module Singleton
end
def instance # :nodoc:
- @singleton__instance__ || @singleton__mutex__.synchronize { @singleton__instance__ ||= new }
+ return @singleton__instance__ if @singleton__instance__
+ @singleton__mutex__.synchronize {
+ return @singleton__instance__ if @singleton__instance__
+ @singleton__instance__ = new()
+ }
+ @singleton__instance__
end
private
diff --git a/lib/singleton/singleton.gemspec b/lib/singleton/singleton.gemspec
new file mode 100644
index 0000000000..88d3111b65
--- /dev/null
+++ b/lib/singleton/singleton.gemspec
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{The Singleton module implements the Singleton pattern.}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/singleton"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/syntax_suggest/api.rb b/lib/syntax_suggest/api.rb
index 65660ec5e5..74e53c2563 100644
--- a/lib/syntax_suggest/api.rb
+++ b/lib/syntax_suggest/api.rb
@@ -5,27 +5,8 @@ require_relative "version"
require "tmpdir"
require "stringio"
require "pathname"
-require "timeout"
-
-# We need Ripper loaded for `Prism.lex_compat` even if we're using Prism
-# for lexing and parsing
require "ripper"
-
-# Prism is the new parser, replacing Ripper
-#
-# We need to "dual boot" both for now because syntax_suggest
-# supports older rubies that do not ship with syntax suggest.
-#
-# We also need the ability to control loading of this library
-# so we can test that both modes work correctly in CI.
-if (value = ENV["SYNTAX_SUGGEST_DISABLE_PRISM"])
- warn "Skipping loading prism due to SYNTAX_SUGGEST_DISABLE_PRISM=#{value}"
-else
- begin
- require "prism"
- rescue LoadError
- end
-end
+require "timeout"
module SyntaxSuggest
# Used to indicate a default value that cannot
@@ -35,14 +16,6 @@ module SyntaxSuggest
class Error < StandardError; end
TIMEOUT_DEFAULT = ENV.fetch("SYNTAX_SUGGEST_TIMEOUT", 1).to_i
- # SyntaxSuggest.use_prism_parser? [Private]
- #
- # Tells us if the prism parser is available for use
- # or if we should fallback to `Ripper`
- def self.use_prism_parser?
- defined?(Prism)
- end
-
# SyntaxSuggest.handle_error [Public]
#
# Takes a `SyntaxError` exception, uses the
@@ -156,20 +129,11 @@ module SyntaxSuggest
# SyntaxSuggest.invalid? [Private]
#
# Opposite of `SyntaxSuggest.valid?`
- if defined?(Prism)
- def self.invalid?(source)
- source = source.join if source.is_a?(Array)
- source = source.to_s
+ def self.invalid?(source)
+ source = source.join if source.is_a?(Array)
+ source = source.to_s
- Prism.parse(source).failure?
- end
- else
- def self.invalid?(source)
- source = source.join if source.is_a?(Array)
- source = source.to_s
-
- Ripper.new(source).tap(&:parse).error?
- end
+ Ripper.new(source).tap(&:parse).error?
end
# SyntaxSuggest.valid? [Private]
@@ -227,6 +191,7 @@ require_relative "lex_all"
require_relative "code_line"
require_relative "code_block"
require_relative "block_expand"
+require_relative "ripper_errors"
require_relative "priority_queue"
require_relative "unvisited_lines"
require_relative "around_block_scan"
diff --git a/lib/syntax_suggest/clean_document.rb b/lib/syntax_suggest/clean_document.rb
index 0847a62e27..2c26061bfc 100644
--- a/lib/syntax_suggest/clean_document.rb
+++ b/lib/syntax_suggest/clean_document.rb
@@ -47,9 +47,9 @@ module SyntaxSuggest
# ## Heredocs
#
# A heredoc is an way of defining a multi-line string. They can cause many
- # problems. If left as a single line, the parser would try to parse the contents
+ # problems. If left as a single line, Ripper would try to parse the contents
# as ruby code rather than as a string. Even without this problem, we still
- # hit an issue with indentation:
+ # hit an issue with indentation
#
# 1 foo = <<~HEREDOC
# 2 "Be yourself; everyone else is already taken.""
@@ -224,7 +224,7 @@ module SyntaxSuggest
#
def join_consecutive!
consecutive_groups = @document.select(&:ignore_newline_not_beg?).map do |code_line|
- take_while_including(code_line.index..) do |line|
+ take_while_including(code_line.index..-1) do |line|
line.ignore_newline_not_beg?
end
end
@@ -245,7 +245,7 @@ module SyntaxSuggest
# expect(lines[1].to_s).to eq("")
def join_trailing_slash!
trailing_groups = @document.select(&:trailing_slash?).map do |code_line|
- take_while_including(code_line.index..) { |x| x.trailing_slash? }
+ take_while_including(code_line.index..-1) { |x| x.trailing_slash? }
end
join_groups(trailing_groups)
self
@@ -279,7 +279,7 @@ module SyntaxSuggest
)
# Hide the rest of the lines
- lines[1..].each do |line|
+ lines[1..-1].each do |line|
# The above lines already have newlines in them, if add more
# then there will be double newline, use an empty line instead
@document[line.index] = CodeLine.new(line: "", index: line.index, lex: [])
@@ -293,7 +293,7 @@ module SyntaxSuggest
# Like `take_while` except when it stops
# iterating, it also returns the line
# that caused it to stop
- def take_while_including(range = 0..)
+ def take_while_including(range = 0..-1)
take_next_and_stop = false
@document[range].take_while do |line|
next if take_next_and_stop
diff --git a/lib/syntax_suggest/code_block.rb b/lib/syntax_suggest/code_block.rb
index d842890300..61e7986da4 100644
--- a/lib/syntax_suggest/code_block.rb
+++ b/lib/syntax_suggest/code_block.rb
@@ -81,7 +81,7 @@ module SyntaxSuggest
# lines then the result cannot be invalid
#
# That means there's no reason to re-check all
- # lines with the parser (which is expensive).
+ # lines with ripper (which is expensive).
# Benchmark in commit message
@valid = if lines.all? { |l| l.hidden? || l.empty? }
true
diff --git a/lib/syntax_suggest/code_frontier.rb b/lib/syntax_suggest/code_frontier.rb
index 0f870d0df0..8e93b32514 100644
--- a/lib/syntax_suggest/code_frontier.rb
+++ b/lib/syntax_suggest/code_frontier.rb
@@ -117,7 +117,7 @@ module SyntaxSuggest
if ENV["SYNTAX_SUGGEST_DEBUG"]
puts "```"
- puts @queue.peek
+ puts @queue.peek.to_s
puts "```"
puts " @frontier indent: #{frontier_indent}"
puts " @unvisited indent: #{unvisited_indent}"
diff --git a/lib/syntax_suggest/code_line.rb b/lib/syntax_suggest/code_line.rb
index 58197e95d0..a20f34afa4 100644
--- a/lib/syntax_suggest/code_line.rb
+++ b/lib/syntax_suggest/code_line.rb
@@ -180,19 +180,12 @@ module SyntaxSuggest
# EOM
# expect(lines.first.trailing_slash?).to eq(true)
#
- if SyntaxSuggest.use_prism_parser?
- def trailing_slash?
- last = @lex.last
- last&.type == :on_tstring_end
- end
- else
- def trailing_slash?
- last = @lex.last
- return false unless last
- return false unless last.type == :on_sp
+ def trailing_slash?
+ last = @lex.last
+ return false unless last
+ return false unless last.type == :on_sp
- last.token == TRAILING_SLASH
- end
+ last.token == TRAILING_SLASH
end
# Endless method detection
diff --git a/lib/syntax_suggest/code_search.rb b/lib/syntax_suggest/code_search.rb
index 7628dcd131..2a86dfea90 100644
--- a/lib/syntax_suggest/code_search.rb
+++ b/lib/syntax_suggest/code_search.rb
@@ -43,7 +43,7 @@ module SyntaxSuggest
def initialize(source, record_dir: DEFAULT_VALUE)
record_dir = if record_dir == DEFAULT_VALUE
- (ENV["SYNTAX_SUGGEST_RECORD_DIR"] || ENV["SYNTAX_SUGGEST_DEBUG"]) ? "tmp" : nil
+ ENV["SYNTAX_SUGGEST_RECORD_DIR"] || ENV["SYNTAX_SUGGEST_DEBUG"] ? "tmp" : nil
else
record_dir
end
@@ -73,7 +73,7 @@ module SyntaxSuggest
if ENV["SYNTAX_SUGGEST_DEBUG"]
puts "\n\n==== #{filename} ===="
puts "\n```#{block.starts_at}..#{block.ends_at}"
- puts block
+ puts block.to_s
puts "```"
puts " block indent: #{block.current_indent}"
end
diff --git a/lib/syntax_suggest/core_ext.rb b/lib/syntax_suggest/core_ext.rb
index c299627bb7..e0fd62b81c 100644
--- a/lib/syntax_suggest/core_ext.rb
+++ b/lib/syntax_suggest/core_ext.rb
@@ -21,7 +21,7 @@ if SyntaxError.method_defined?(:detailed_message)
attr_reader :string
end
- # SyntaxSuggest.module_for_detailed_message [Private]
+ # SyntaxSuggest.record_dir [Private]
#
# Used to monkeypatch SyntaxError via Module.prepend
def self.module_for_detailed_message
diff --git a/lib/syntax_suggest/display_invalid_blocks.rb b/lib/syntax_suggest/display_invalid_blocks.rb
index 5e79b3a262..32ec0021a3 100644
--- a/lib/syntax_suggest/display_invalid_blocks.rb
+++ b/lib/syntax_suggest/display_invalid_blocks.rb
@@ -14,7 +14,7 @@ module SyntaxSuggest
@filename = filename
@code_lines = code_lines
- @terminal = (terminal == DEFAULT_VALUE) ? io.isatty : terminal
+ @terminal = terminal == DEFAULT_VALUE ? io.isatty : terminal
end
def document_ok?
diff --git a/lib/syntax_suggest/explain_syntax.rb b/lib/syntax_suggest/explain_syntax.rb
index 0d80c4d869..142ed2e269 100644
--- a/lib/syntax_suggest/explain_syntax.rb
+++ b/lib/syntax_suggest/explain_syntax.rb
@@ -2,21 +2,7 @@
require_relative "left_right_lex_count"
-if !SyntaxSuggest.use_prism_parser?
- require_relative "ripper_errors"
-end
-
module SyntaxSuggest
- class GetParseErrors
- def self.errors(source)
- if SyntaxSuggest.use_prism_parser?
- Prism.parse(source).errors.map(&:message)
- else
- RipperErrors.new(source).call.errors
- end
- end
- end
-
# Explains syntax errors based on their source
#
# example:
@@ -29,8 +15,8 @@ module SyntaxSuggest
# # => "Unmatched keyword, missing `end' ?"
#
# When the error cannot be determined by lexical counting
- # then the parser is run against the input and the raw
- # errors are returned.
+ # then ripper is run against the input and the raw ripper
+ # errors returned.
#
# Example:
#
@@ -105,10 +91,10 @@ module SyntaxSuggest
# Returns an array of syntax error messages
#
# If no missing pairs are found it falls back
- # on the original error messages
+ # on the original ripper error messages
def errors
if missing.empty?
- return GetParseErrors.errors(@code_lines.map(&:original).join).uniq
+ return RipperErrors.new(@code_lines.map(&:original).join).call.errors
end
missing.map { |miss| why(miss) }
diff --git a/lib/syntax_suggest/lex_all.rb b/lib/syntax_suggest/lex_all.rb
index c16fbb52d3..132cba9f5d 100644
--- a/lib/syntax_suggest/lex_all.rb
+++ b/lib/syntax_suggest/lex_all.rb
@@ -3,53 +3,34 @@
module SyntaxSuggest
# Ripper.lex is not guaranteed to lex the entire source document
#
- # This class guarantees the whole document is lex-ed by iteratively
- # lexing the document where ripper stopped.
- #
- # Prism likely doesn't have the same problem. Once ripper support is removed
- # we can likely reduce the complexity here if not remove the whole concept.
- #
- # Example usage:
- #
- # lex = LexAll.new(source: source)
- # lex.each do |value|
- # puts value.line
- # end
+ # lex = LexAll.new(source: source)
+ # lex.each do |value|
+ # puts value.line
+ # end
class LexAll
include Enumerable
def initialize(source:, source_lines: nil)
- @lex = self.class.lex(source, 1)
- lineno = @lex.last[0][0] + 1
+ @lex = Ripper::Lexer.new(source, "-", 1).parse.sort_by(&:pos)
+ lineno = @lex.last.pos.first + 1
source_lines ||= source.lines
last_lineno = source_lines.length
until lineno >= last_lineno
- lines = source_lines[lineno..]
+ lines = source_lines[lineno..-1]
@lex.concat(
- self.class.lex(lines.join, lineno + 1)
+ Ripper::Lexer.new(lines.join, "-", lineno + 1).parse.sort_by(&:pos)
)
-
- lineno = @lex.last[0].first + 1
+ lineno = @lex.last.pos.first + 1
end
last_lex = nil
@lex.map! { |elem|
- last_lex = LexValue.new(elem[0].first, elem[1], elem[2], elem[3], last_lex)
+ last_lex = LexValue.new(elem.pos.first, elem.event, elem.tok, elem.state, last_lex)
}
end
- if SyntaxSuggest.use_prism_parser?
- def self.lex(source, line_number)
- Prism.lex_compat(source, line: line_number).value.sort_by { |values| values[0] }
- end
- else
- def self.lex(source, line_number)
- Ripper::Lexer.new(source, "-", line_number).parse.sort_by(&:pos)
- end
- end
-
def to_a
@lex
end
diff --git a/lib/syntax_suggest/pathname_from_message.rb b/lib/syntax_suggest/pathname_from_message.rb
index ab90227427..b6fe1617be 100644
--- a/lib/syntax_suggest/pathname_from_message.rb
+++ b/lib/syntax_suggest/pathname_from_message.rb
@@ -13,7 +13,7 @@ module SyntaxSuggest
# # => "/tmp/scratch.rb"
#
class PathnameFromMessage
- EVAL_RE = /^\(eval.*\):\d+/
+ EVAL_RE = /^\(eval\):\d+/
STREAMING_RE = /^-:\d+/
attr_reader :name
diff --git a/lib/syntax_suggest/ripper_errors.rb b/lib/syntax_suggest/ripper_errors.rb
index 4e2bc90948..48eb206e48 100644
--- a/lib/syntax_suggest/ripper_errors.rb
+++ b/lib/syntax_suggest/ripper_errors.rb
@@ -1,10 +1,7 @@
# frozen_string_literal: true
module SyntaxSuggest
- # Capture parse errors from Ripper
- #
- # Prism returns the errors with their messages, but Ripper
- # does not. To get them we must make a custom subclass.
+ # Capture parse errors from ripper
#
# Example:
#
diff --git a/lib/syntax_suggest/scan_history.rb b/lib/syntax_suggest/scan_history.rb
index dc36e6ba2e..d15597c440 100644
--- a/lib/syntax_suggest/scan_history.rb
+++ b/lib/syntax_suggest/scan_history.rb
@@ -118,7 +118,7 @@ module SyntaxSuggest
# Returns an array of all the CodeLines that exist after
# the currently scanned block
private def after_lines
- @code_lines[@after_index.next..] || []
+ @code_lines[@after_index.next..-1] || []
end
private def current
diff --git a/lib/syntax_suggest/syntax_suggest.gemspec b/lib/syntax_suggest/syntax_suggest.gemspec
index 756a85bf63..0e611c13d0 100644
--- a/lib/syntax_suggest/syntax_suggest.gemspec
+++ b/lib/syntax_suggest/syntax_suggest.gemspec
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
spec.description = 'When you get an "unexpected end" in your syntax this gem helps you find it'
spec.homepage = "https://github.com/ruby/syntax_suggest.git"
spec.license = "MIT"
- spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "https://github.com/ruby/syntax_suggest.git"
diff --git a/lib/syntax_suggest/version.rb b/lib/syntax_suggest/version.rb
index 4320adb218..ac8c2f62e5 100644
--- a/lib/syntax_suggest/version.rb
+++ b/lib/syntax_suggest/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module SyntaxSuggest
- VERSION = "2.0.0"
+ VERSION = "1.1.0"
end
diff --git a/lib/tempfile.gemspec b/lib/tempfile.gemspec
index a3cb11296d..acb26b68db 100644
--- a/lib/tempfile.gemspec
+++ b/lib/tempfile.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "tempfile"
+ spec.version = "0.1.3"
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
@@ -23,7 +16,7 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.require_paths = ["lib"]
end
diff --git a/lib/tempfile.rb b/lib/tempfile.rb
index cf6085192b..c3263ed3c6 100644
--- a/lib/tempfile.rb
+++ b/lib/tempfile.rb
@@ -57,7 +57,7 @@ require 'tmpdir'
# Note that Tempfile.create returns a File instance instead of a Tempfile, which
# also avoids the overhead and complications of delegation.
#
-# Tempfile.create('foo') do |file|
+# Tempfile.open('foo') do |file|
# # ...do something with file...
# end
#
@@ -88,8 +88,6 @@ require 'tmpdir'
# mutex.
class Tempfile < DelegateClass(File)
- VERSION = "0.2.1"
-
# Creates a file in the underlying file system;
# returns a new \Tempfile object based on that file.
#
@@ -152,50 +150,26 @@ class Tempfile < DelegateClass(File)
@unlinked = false
@mode = mode|File::RDWR|File::CREAT|File::EXCL
- @finalizer_obj = Object.new
- tmpfile = nil
::Dir::Tmpname.create(basename, tmpdir, **options) do |tmpname, n, opts|
opts[:perm] = 0600
- tmpfile = File.open(tmpname, @mode, **opts)
+ @tmpfile = File.open(tmpname, @mode, **opts)
@opts = opts.freeze
end
- ObjectSpace.define_finalizer(@finalizer_obj, Remover.new(tmpfile.path))
- ObjectSpace.define_finalizer(self, Closer.new(tmpfile))
-
- super(tmpfile)
- end
-
- def initialize_dup(other)
- initialize_copy_iv(other)
- super(other)
- ObjectSpace.define_finalizer(self, Closer.new(__getobj__))
- end
-
- def initialize_clone(other)
- initialize_copy_iv(other)
- super(other)
- ObjectSpace.define_finalizer(self, Closer.new(__getobj__))
- end
+ ObjectSpace.define_finalizer(self, Remover.new(@tmpfile))
- private def initialize_copy_iv(other)
- @unlinked = other.unlinked
- @mode = other.mode
- @opts = other.opts
- @finalizer_obj = other.finalizer_obj
+ super(@tmpfile)
end
# Opens or reopens the file with mode "r+".
def open
_close
- ObjectSpace.undefine_finalizer(self)
mode = @mode & ~(File::CREAT|File::EXCL)
- __setobj__(File.open(__getobj__.path, mode, **@opts))
- ObjectSpace.define_finalizer(self, Closer.new(__getobj__))
- __getobj__
+ @tmpfile = File.open(@tmpfile.path, mode, **@opts)
+ __setobj__(@tmpfile)
end
def _close # :nodoc:
- __getobj__.close
+ @tmpfile.close
end
protected :_close
@@ -252,13 +226,13 @@ class Tempfile < DelegateClass(File)
def unlink
return if @unlinked
begin
- File.unlink(__getobj__.path)
+ File.unlink(@tmpfile.path)
rescue Errno::ENOENT
rescue Errno::EACCES
# may not be able to unlink on Windows; just ignore
return
end
- ObjectSpace.undefine_finalizer(@finalizer_obj)
+ ObjectSpace.undefine_finalizer(self)
@unlinked = true
end
alias delete unlink
@@ -266,57 +240,43 @@ class Tempfile < DelegateClass(File)
# Returns the full path name of the temporary file.
# This will be nil if #unlink has been called.
def path
- @unlinked ? nil : __getobj__.path
+ @unlinked ? nil : @tmpfile.path
end
# Returns the size of the temporary file. As a side effect, the IO
# buffer is flushed before determining the size.
def size
- if !__getobj__.closed?
- __getobj__.size # File#size calls rb_io_flush_raw()
+ if !@tmpfile.closed?
+ @tmpfile.size # File#size calls rb_io_flush_raw()
else
- File.size(__getobj__.path)
+ File.size(@tmpfile.path)
end
end
alias length size
# :stopdoc:
def inspect
- if __getobj__.closed?
+ if @tmpfile.closed?
"#<#{self.class}:#{path} (closed)>"
else
"#<#{self.class}:#{path}>"
end
end
- alias to_s inspect
-
- protected
-
- attr_reader :unlinked, :mode, :opts, :finalizer_obj
-
- class Closer # :nodoc:
- def initialize(tmpfile)
- @tmpfile = tmpfile
- end
-
- def call(*args)
- @tmpfile.close
- end
- end
class Remover # :nodoc:
- def initialize(path)
+ def initialize(tmpfile)
@pid = Process.pid
- @path = path
+ @tmpfile = tmpfile
end
def call(*args)
return if @pid != Process.pid
- $stderr.puts "removing #{@path}..." if $DEBUG
+ $stderr.puts "removing #{@tmpfile.path}..." if $DEBUG
+ @tmpfile.close
begin
- File.unlink(@path)
+ File.unlink(@tmpfile.path)
rescue Errno::ENOENT
end
diff --git a/lib/time.gemspec b/lib/time.gemspec
index a9349a253f..bada91a30b 100644
--- a/lib/time.gemspec
+++ b/lib/time.gemspec
@@ -1,20 +1,13 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "time"
+ spec.version = "0.2.2"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
spec.summary = %q{Extends the Time class with methods for parsing and conversion.}
spec.description = %q{Extends the Time class with methods for parsing and conversion.}
spec.homepage = "https://github.com/ruby/time"
- spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.metadata["homepage_uri"] = spec.homepage
diff --git a/lib/time.rb b/lib/time.rb
index 2bfbd57642..6a13212a49 100644
--- a/lib/time.rb
+++ b/lib/time.rb
@@ -25,9 +25,6 @@ require 'date'
# :startdoc:
class Time
-
- VERSION = "0.3.0"
-
class << Time
#
diff --git a/lib/timeout.gemspec b/lib/timeout.gemspec
deleted file mode 100644
index 258517c5f8..0000000000
--- a/lib/timeout.gemspec
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{Auto-terminate potentially long-running operations in Ruby.}
- spec.description = %q{Auto-terminate potentially long-running operations in Ruby.}
- spec.homepage = "https://github.com/ruby/timeout"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- spec.required_ruby_version = '>= 2.6.0'
-
- spec.files = Dir.chdir(__dir__) do
- `git ls-files -z`.split("\x0").reject do |f|
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|rakelib)/|\.(?:git|travis|circleci)|appveyor|Rakefile)})
- end
- end
- spec.require_paths = ["lib"]
-end
diff --git a/lib/timeout.rb b/lib/timeout.rb
index d8806e22b3..7f40bafa4d 100644
--- a/lib/timeout.rb
+++ b/lib/timeout.rb
@@ -23,26 +23,29 @@
# Copyright:: (C) 2000 Information-technology Promotion Agency, Japan
module Timeout
- VERSION = "0.4.1"
-
- # Internal error raised to when a timeout is triggered.
- class ExitException < Exception
- def exception(*)
- self
- end
- end
+ VERSION = "0.3.1"
# Raised by Timeout.timeout when the block times out.
class Error < RuntimeError
- def self.handle_timeout(message)
- exc = ExitException.new(message)
+ attr_reader :thread
- begin
- yield exc
- rescue ExitException => e
- raise new(message) if exc.equal?(e)
- raise
+ def self.catch(*args)
+ exc = new(*args)
+ exc.instance_variable_set(:@thread, Thread.current)
+ exc.instance_variable_set(:@catch_value, exc)
+ ::Kernel.catch(exc) {yield exc}
+ end
+
+ def exception(*)
+ # TODO: use Fiber.current to see if self can be thrown
+ if self.thread == Thread.current
+ bt = caller
+ begin
+ throw(@catch_value, bt)
+ rescue UncaughtThrowError
+ end
end
+ super
end
end
@@ -117,7 +120,7 @@ module Timeout
requests.reject!(&:done?)
end
end
- ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
+ ThreadGroup::Default.add(watcher)
watcher.name = "Timeout stdlib thread"
watcher.thread_variable_set(:"\0__detached_thread__", true)
watcher
@@ -192,7 +195,8 @@ module Timeout
if klass
perform.call(klass)
else
- Error.handle_timeout(message, &perform)
+ backtrace = Error.catch(&perform)
+ raise Error, message, backtrace
end
end
module_function :timeout
diff --git a/lib/timeout/timeout.gemspec b/lib/timeout/timeout.gemspec
new file mode 100644
index 0000000000..7449ae1980
--- /dev/null
+++ b/lib/timeout/timeout.gemspec
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Auto-terminate potentially long-running operations in Ruby.}
+ spec.description = %q{Auto-terminate potentially long-running operations in Ruby.}
+ spec.homepage = "https://github.com/ruby/timeout"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ spec.files = Dir.chdir(__dir__) do
+ `git ls-files -z`.split("\x0").reject do |f|
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|rakelib)/|\.(?:git|travis|circleci)|appveyor|Rakefile)})
+ end
+ end
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/tmpdir.gemspec b/lib/tmpdir.gemspec
index a7463105fa..e42662ea3b 100644
--- a/lib/tmpdir.gemspec
+++ b/lib/tmpdir.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = "tmpdir"
- spec.version = "0.2.0"
+ spec.version = "0.1.3"
spec.authors = ["Yukihiro Matsumoto"]
spec.email = ["matz@ruby-lang.org"]
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
diff --git a/lib/tmpdir.rb b/lib/tmpdir.rb
index db5ed978cd..55920a4a74 100644
--- a/lib/tmpdir.rb
+++ b/lib/tmpdir.rb
@@ -13,20 +13,15 @@ end
class Dir
- # Class variables are inaccessible from non-main Ractor.
- # And instance variables too, in Ruby 3.0.
-
- # System-wide temporary directory path
- SYSTMPDIR = (defined?(Etc.systmpdir) ? Etc.systmpdir.freeze : '/tmp')
- private_constant :SYSTMPDIR
+ @@systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp'
##
# Returns the operating system's temporary file path.
def self.tmpdir
- ['TMPDIR', 'TMP', 'TEMP', ['system temporary path', SYSTMPDIR], ['/tmp']*2, ['.']*2].find do |name, dir|
+ ['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @@systmpdir], ['/tmp']*2, ['.']*2].find do |name, dir|
unless dir
- next if !(dir = ENV[name] rescue next) or dir.empty?
+ next if !(dir = ENV[name]) or dir.empty?
end
dir = File.expand_path(dir)
stat = File.stat(dir) rescue next
@@ -123,17 +118,16 @@ class Dir
UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~"
# Dedicated random number generator
- RANDOM = Object.new
+ RANDOM = Random.new
class << RANDOM # :nodoc:
# Maximum random number
MAX = 36**6 # < 0x100000000
# Returns new random string upto 6 bytes
def next
- (::Random.urandom(4).unpack1("L")%MAX).to_s(36)
+ rand(MAX).to_s(36)
end
end
- RANDOM.freeze
private_constant :RANDOM
# Generates and yields random names to create a temporary name
diff --git a/lib/tsort.gemspec b/lib/tsort.gemspec
index 0e2f110a53..a82393b70b 100644
--- a/lib/tsort.gemspec
+++ b/lib/tsort.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "tsort"
+ spec.version = "0.1.1"
spec.authors = ["Tanaka Akira"]
spec.email = ["akr@fsij.org"]
diff --git a/lib/tsort.rb b/lib/tsort.rb
index dbaed45415..00ee609d64 100644
--- a/lib/tsort.rb
+++ b/lib/tsort.rb
@@ -122,9 +122,6 @@
#
module TSort
-
- VERSION = "0.2.0"
-
class Cyclic < StandardError
end
diff --git a/lib/un.gemspec b/lib/un.gemspec
index 2ed49511cc..1a466fdebe 100644
--- a/lib/un.gemspec
+++ b/lib/un.gemspec
@@ -1,15 +1,8 @@
# frozen_string_literal: true
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "un"
+ spec.version = "0.2.1"
spec.authors = ["WATANABE Hirofumi"]
spec.email = ["eban@ruby-lang.org"]
diff --git a/lib/un.rb b/lib/un.rb
index 8fb3c61a93..796b36fbab 100644
--- a/lib/un.rb
+++ b/lib/un.rb
@@ -30,6 +30,7 @@ require "fileutils"
require "optparse"
module FileUtils
+# @fileutils_label = ""
@fileutils_output = $stdout
end
@@ -411,9 +412,6 @@ def help
end
module UN # :nodoc:
-
- VERSION = "0.3.0"
-
module_function
def help(argv, output: $stdout)
all = argv.empty?
diff --git a/lib/uri/common.rb b/lib/uri/common.rb
index dce09fbc1e..0c4064a67a 100644
--- a/lib/uri/common.rb
+++ b/lib/uri/common.rb
@@ -19,6 +19,8 @@ module URI
Parser = RFC2396_Parser
RFC3986_PARSER = RFC3986_Parser.new
Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
+ RFC2396_PARSER = RFC2396_Parser.new
+ Ractor.make_shareable(RFC2396_PARSER) if defined?(Ractor)
# URI::Parser.new
DEFAULT_PARSER = Parser.new
@@ -68,32 +70,16 @@ module URI
end
private_constant :Schemes
- # Registers the given +klass+ as the class to be instantiated
- # when parsing a \URI with the given +scheme+:
#
- # URI.register_scheme('MS_SEARCH', URI::Generic) # => URI::Generic
- # URI.scheme_list['MS_SEARCH'] # => URI::Generic
+ # Register the given +klass+ to be instantiated when parsing URLs with the given +scheme+.
+ # Note that currently only schemes which after .upcase are valid constant names
+ # can be registered (no -/+/. allowed).
#
- # Note that after calling String#upcase on +scheme+, it must be a valid
- # constant name.
def self.register_scheme(scheme, klass)
Schemes.const_set(scheme.to_s.upcase, klass)
end
- # Returns a hash of the defined schemes:
- #
- # URI.scheme_list
- # # =>
- # {"MAILTO"=>URI::MailTo,
- # "LDAPS"=>URI::LDAPS,
- # "WS"=>URI::WS,
- # "HTTP"=>URI::HTTP,
- # "HTTPS"=>URI::HTTPS,
- # "LDAP"=>URI::LDAP,
- # "FILE"=>URI::File,
- # "FTP"=>URI::FTP}
- #
- # Related: URI.register_scheme.
+ # Returns a Hash of the defined schemes.
def self.scheme_list
Schemes.constants.map { |name|
[name.to_s.upcase, Schemes.const_get(name)]
@@ -104,21 +90,9 @@ module URI
private_constant :INITIAL_SCHEMES
Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
- # Returns a new object constructed from the given +scheme+, +arguments+,
- # and +default+:
- #
- # - The new object is an instance of <tt>URI.scheme_list[scheme.upcase]</tt>.
- # - The object is initialized by calling the class initializer
- # using +scheme+ and +arguments+.
- # See URI::Generic.new.
- #
- # Examples:
#
- # values = ['john.doe', 'www.example.com', '123', nil, '/forum/questions/', nil, 'tag=networking&order=newest', 'top']
- # URI.for('https', *values)
- # # => #<URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- # URI.for('foo', *values, default: URI::HTTP)
- # # => #<URI::HTTP foo://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
+ # Construct a URI instance, using the scheme to detect the appropriate class
+ # from +URI.scheme_list+.
#
def self.for(scheme, *arguments, default: Generic)
const_name = scheme.to_s.upcase
@@ -149,49 +123,95 @@ module URI
#
class BadURIError < Error; end
- # Returns a 9-element array representing the parts of the \URI
- # formed from the string +uri+;
- # each array element is a string or +nil+:
- #
- # names = %w[scheme userinfo host port registry path opaque query fragment]
- # values = URI.split('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # names.zip(values)
- # # =>
- # [["scheme", "https"],
- # ["userinfo", "john.doe"],
- # ["host", "www.example.com"],
- # ["port", "123"],
- # ["registry", nil],
- # ["path", "/forum/questions/"],
- # ["opaque", nil],
- # ["query", "tag=networking&order=newest"],
- # ["fragment", "top"]]
+ #
+ # == Synopsis
+ #
+ # URI::split(uri)
+ #
+ # == Args
+ #
+ # +uri+::
+ # String with URI.
+ #
+ # == Description
+ #
+ # Splits the string on following parts and returns array with result:
+ #
+ # * Scheme
+ # * Userinfo
+ # * Host
+ # * Port
+ # * Registry
+ # * Path
+ # * Opaque
+ # * Query
+ # * Fragment
+ #
+ # == Usage
+ #
+ # require 'uri'
+ #
+ # URI.split("http://www.ruby-lang.org/")
+ # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
#
def self.split(uri)
RFC3986_PARSER.split(uri)
end
- # Returns a new \URI object constructed from the given string +uri+:
#
- # URI.parse('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # # => #<URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
- # URI.parse('http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
- # # => #<URI::HTTP http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
+ # == Synopsis
+ #
+ # URI::parse(uri_str)
+ #
+ # == Args
+ #
+ # +uri_str+::
+ # String with URI.
+ #
+ # == Description
+ #
+ # Creates one of the URI's subclasses instance from the string.
+ #
+ # == Raises
+ #
+ # URI::InvalidURIError::
+ # Raised if URI given is not a correct one.
#
- # It's recommended to first ::escape string +uri+
- # if it may contain invalid URI characters.
+ # == Usage
+ #
+ # require 'uri'
+ #
+ # uri = URI.parse("http://www.ruby-lang.org/")
+ # # => #<URI::HTTP http://www.ruby-lang.org/>
+ # uri.scheme
+ # # => "http"
+ # uri.host
+ # # => "www.ruby-lang.org"
+ #
+ # It's recommended to first ::escape the provided +uri_str+ if there are any
+ # invalid URI characters.
#
def self.parse(uri)
RFC3986_PARSER.parse(uri)
end
- # Merges the given URI strings +str+
- # per {RFC 2396}[https://www.rfc-editor.org/rfc/rfc2396.html].
#
- # Each string in +str+ is converted to an
- # {RFC3986 URI}[https://www.rfc-editor.org/rfc/rfc3986.html] before being merged.
+ # == Synopsis
+ #
+ # URI::join(str[, str, ...])
#
- # Examples:
+ # == Args
+ #
+ # +str+::
+ # String(s) to work with, will be converted to RFC3986 URIs before merging.
+ #
+ # == Description
+ #
+ # Joins URIs.
+ #
+ # == Usage
+ #
+ # require 'uri'
#
# URI.join("http://example.com/","main.rbx")
# # => #<URI::HTTP http://example.com/main.rbx>
@@ -236,7 +256,7 @@ module URI
# URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
# # => ["http://foo.example.com/bla", "mailto:test@example.com"]
#
- def self.extract(str, schemes = nil, &block) # :nodoc:
+ def self.extract(str, schemes = nil, &block)
warn "URI.extract is obsolete", uplevel: 1 if $VERBOSE
DEFAULT_PARSER.extract(str, schemes, &block)
end
@@ -273,7 +293,7 @@ module URI
# p $&
# end
#
- def self.regexp(schemes = nil)# :nodoc:
+ def self.regexp(schemes = nil)
warn "URI.regexp is obsolete", uplevel: 1 if $VERBOSE
DEFAULT_PARSER.make_regexp(schemes)
end
@@ -296,86 +316,40 @@ module URI
TBLDECWWWCOMP_['+'] = ' '
TBLDECWWWCOMP_.freeze
- # Returns a URL-encoded string derived from the given string +str+.
- #
- # The returned string:
- #
- # - Preserves:
- #
- # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
- # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
- # and <tt>'0'..'9'</tt>.
- #
- # Example:
+ # Encodes given +str+ to URL-encoded form data.
#
- # URI.encode_www_form_component('*.-_azAZ09')
- # # => "*.-_azAZ09"
+ # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
+ # (ASCII space) to + and converts others to %XX.
#
- # - Converts:
+ # If +enc+ is given, convert +str+ to the encoding before percent encoding.
#
- # - Character <tt>' '</tt> to character <tt>'+'</tt>.
- # - Any other character to "percent notation";
- # the percent notation for character <i>c</i> is <tt>'%%%X' % c.ord</tt>.
+ # This is an implementation of
+ # https://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data.
#
- # Example:
- #
- # URI.encode_www_form_component('Here are some punctuation characters: ,;?:')
- # # => "Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A"
- #
- # Encoding:
- #
- # - If +str+ has encoding Encoding::ASCII_8BIT, argument +enc+ is ignored.
- # - Otherwise +str+ is converted first to Encoding::UTF_8
- # (with suitable character replacements),
- # and then to encoding +enc+.
- #
- # In either case, the returned string has forced encoding Encoding::US_ASCII.
- #
- # Related: URI.encode_uri_component (encodes <tt>' '</tt> as <tt>'%20'</tt>).
+ # See URI.decode_www_form_component, URI.encode_www_form.
def self.encode_www_form_component(str, enc=nil)
_encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_, str, enc)
end
- # Returns a string decoded from the given \URL-encoded string +str+.
- #
- # The given string is first encoded as Encoding::ASCII-8BIT (using String#b),
- # then decoded (as below), and finally force-encoded to the given encoding +enc+.
- #
- # The returned string:
- #
- # - Preserves:
- #
- # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
- # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
- # and <tt>'0'..'9'</tt>.
- #
- # Example:
- #
- # URI.decode_www_form_component('*.-_azAZ09')
- # # => "*.-_azAZ09"
- #
- # - Converts:
- #
- # - Character <tt>'+'</tt> to character <tt>' '</tt>.
- # - Each "percent notation" to an ASCII character.
+ # Decodes given +str+ of URL-encoded form data.
#
- # Example:
+ # This decodes + to SP.
#
- # URI.decode_www_form_component('Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A')
- # # => "Here are some punctuation characters: ,;?:"
- #
- # Related: URI.decode_uri_component (preserves <tt>'+'</tt>).
+ # See URI.encode_www_form_component, URI.decode_www_form.
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
_decode_uri_component(/\+|%\h\h/, str, enc)
end
- # Like URI.encode_www_form_component, except that <tt>' '</tt> (space)
- # is encoded as <tt>'%20'</tt> (instead of <tt>'+'</tt>).
+ # Encodes +str+ using URL encoding
+ #
+ # This encodes SP to %20 instead of +.
def self.encode_uri_component(str, enc=nil)
_encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCURICOMP_, str, enc)
end
- # Like URI.decode_www_form_component, except that <tt>'+'</tt> is preserved.
+ # Decodes given +str+ of URL-encoded data.
+ #
+ # This does not decode + to SP.
def self.decode_uri_component(str, enc=Encoding::UTF_8)
_decode_uri_component(/%\h\h/, str, enc)
end
@@ -400,104 +374,33 @@ module URI
end
private_class_method :_decode_uri_component
- # Returns a URL-encoded string derived from the given
- # {Enumerable}[rdoc-ref:Enumerable@Enumerable+in+Ruby+Classes]
- # +enum+.
- #
- # The result is suitable for use as form data
- # for an \HTTP request whose <tt>Content-Type</tt> is
- # <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The returned string consists of the elements of +enum+,
- # each converted to one or more URL-encoded strings,
- # and all joined with character <tt>'&'</tt>.
- #
- # Simple examples:
- #
- # URI.encode_www_form([['foo', 0], ['bar', 1], ['baz', 2]])
- # # => "foo=0&bar=1&baz=2"
- # URI.encode_www_form({foo: 0, bar: 1, baz: 2})
- # # => "foo=0&bar=1&baz=2"
- #
- # The returned string is formed using method URI.encode_www_form_component,
- # which converts certain characters:
- #
- # URI.encode_www_form('f#o': '/', 'b-r': '$', 'b z': '@')
- # # => "f%23o=%2F&b-r=%24&b+z=%40"
- #
- # When +enum+ is Array-like, each element +ele+ is converted to a field:
- #
- # - If +ele+ is an array of two or more elements,
- # the field is formed from its first two elements
- # (and any additional elements are ignored):
- #
- # name = URI.encode_www_form_component(ele[0], enc)
- # value = URI.encode_www_form_component(ele[1], enc)
- # "#{name}=#{value}"
+ # Generates URL-encoded form data from given +enum+.
#
- # Examples:
+ # This generates application/x-www-form-urlencoded data defined in HTML5
+ # from given an Enumerable object.
#
- # URI.encode_www_form([%w[foo bar], %w[baz bat bah]])
- # # => "foo=bar&baz=bat"
- # URI.encode_www_form([['foo', 0], ['bar', :baz, 'bat']])
- # # => "foo=0&bar=baz"
+ # This internally uses URI.encode_www_form_component(str).
#
- # - If +ele+ is an array of one element,
- # the field is formed from <tt>ele[0]</tt>:
+ # This method doesn't convert the encoding of given items, so convert them
+ # before calling this method if you want to send data as other than original
+ # encoding or mixed encoding data. (Strings which are encoded in an HTML5
+ # ASCII incompatible encoding are converted to UTF-8.)
#
- # URI.encode_www_form_component(ele[0])
+ # This method doesn't handle files. When you send a file, use
+ # multipart/form-data.
#
- # Example:
+ # This refers https://url.spec.whatwg.org/#concept-urlencoded-serializer
#
- # URI.encode_www_form([['foo'], [:bar], [0]])
- # # => "foo&bar&0"
- #
- # - Otherwise the field is formed from +ele+:
- #
- # URI.encode_www_form_component(ele)
- #
- # Example:
- #
- # URI.encode_www_form(['foo', :bar, 0])
- # # => "foo&bar&0"
- #
- # The elements of an Array-like +enum+ may be mixture:
- #
- # URI.encode_www_form([['foo', 0], ['bar', 1, 2], ['baz'], :bat])
- # # => "foo=0&bar=1&baz&bat"
- #
- # When +enum+ is Hash-like,
- # each +key+/+value+ pair is converted to one or more fields:
- #
- # - If +value+ is
- # {Array-convertible}[rdoc-ref:implicit_conversion.rdoc@Array-Convertible+Objects],
- # each element +ele+ in +value+ is paired with +key+ to form a field:
- #
- # name = URI.encode_www_form_component(key, enc)
- # value = URI.encode_www_form_component(ele, enc)
- # "#{name}=#{value}"
- #
- # Example:
- #
- # URI.encode_www_form({foo: [:bar, 1], baz: [:bat, :bam, 2]})
- # # => "foo=bar&foo=1&baz=bat&baz=bam&baz=2"
- #
- # - Otherwise, +key+ and +value+ are paired to form a field:
- #
- # name = URI.encode_www_form_component(key, enc)
- # value = URI.encode_www_form_component(value, enc)
- # "#{name}=#{value}"
- #
- # Example:
- #
- # URI.encode_www_form({foo: 0, bar: 1, baz: 2})
- # # => "foo=0&bar=1&baz=2"
- #
- # The elements of a Hash-like +enum+ may be mixture:
- #
- # URI.encode_www_form({foo: [0, 1], bar: 2})
- # # => "foo=0&foo=1&bar=2"
+ # URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
+ # #=> "q=ruby&lang=en"
+ # URI.encode_www_form("q" => "ruby", "lang" => "en")
+ # #=> "q=ruby&lang=en"
+ # URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
+ # #=> "q=ruby&q=perl&lang=en"
+ # URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
+ # #=> "q=ruby&q=perl&lang=en"
#
+ # See URI.encode_www_form_component, URI.decode_www_form.
def self.encode_www_form(enum, enc=nil)
enum.map do |k,v|
if v.nil?
@@ -518,39 +421,22 @@ module URI
end.join('&')
end
- # Returns name/value pairs derived from the given string +str+,
- # which must be an ASCII string.
- #
- # The method may be used to decode the body of Net::HTTPResponse object +res+
- # for which <tt>res['Content-Type']</tt> is <tt>'application/x-www-form-urlencoded'</tt>.
- #
- # The returned data is an array of 2-element subarrays;
- # each subarray is a name/value pair (both are strings).
- # Each returned string has encoding +enc+,
- # and has had invalid characters removed via
- # {String#scrub}[rdoc-ref:String#scrub].
+ # Decodes URL-encoded form data from given +str+.
#
- # A simple example:
+ # This decodes application/x-www-form-urlencoded data
+ # and returns an array of key-value arrays.
#
- # URI.decode_www_form('foo=0&bar=1&baz')
- # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
+ # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser,
+ # so this supports only &-separator, and doesn't support ;-separator.
#
- # The returned strings have certain conversions,
- # similar to those performed in URI.decode_www_form_component:
- #
- # URI.decode_www_form('f%23o=%2F&b-r=%24&b+z=%40')
- # # => [["f#o", "/"], ["b-r", "$"], ["b z", "@"]]
- #
- # The given string may contain consecutive separators:
- #
- # URI.decode_www_form('foo=0&&bar=1&&baz=2')
- # # => [["foo", "0"], ["", ""], ["bar", "1"], ["", ""], ["baz", "2"]]
- #
- # A different separator may be specified:
- #
- # URI.decode_www_form('foo=0--bar=1--baz', separator: '--')
- # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
+ # ary = URI.decode_www_form("a=1&a=2&b=3")
+ # ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
+ # ary.assoc('a').last #=> '1'
+ # ary.assoc('b').last #=> '3'
+ # ary.rassoc('a').last #=> '2'
+ # Hash[ary] #=> {"a"=>"2", "b"=>"3"}
#
+ # See URI.decode_www_form_component, URI.encode_www_form.
def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
ary = []
@@ -829,15 +715,7 @@ end # module URI
module Kernel
#
- # Returns a \URI object derived from the given +uri+,
- # which may be a \URI string or an existing \URI object:
- #
- # # Returns a new URI.
- # uri = URI('http://github.com/ruby/ruby')
- # # => #<URI::HTTP http://github.com/ruby/ruby>
- # # Returns the given URI.
- # URI(uri)
- # # => #<URI::HTTP http://github.com/ruby/ruby>
+ # Returns +uri+ converted to an URI object.
#
def URI(uri)
if uri.is_a?(URI::Generic)
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index f3540a24bb..f7eed57924 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -1133,17 +1133,16 @@ module URI
base.fragment=(nil)
# RFC2396, Section 5.2, 4)
- if !authority
- base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
- else
- # RFC2396, Section 5.2, 4)
- base.set_path(rel.path) if rel.path
+ if authority
+ base.set_userinfo(rel.userinfo)
+ base.set_host(rel.host)
+ base.set_port(rel.port || base.default_port)
+ base.set_path(rel.path)
+ elsif base.path && rel.path
+ base.set_path(merge_path(base.path, rel.path))
end
# RFC2396, Section 5.2, 7)
- base.set_userinfo(rel.userinfo) if rel.userinfo
- base.set_host(rel.host) if rel.host
- base.set_port(rel.port) if rel.port
base.query = rel.query if rel.query
base.fragment=(rel.fragment) if rel.fragment
@@ -1376,7 +1375,6 @@ module URI
end
str
end
- alias to_str to_s
#
# Compares two URIs.
diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb
index 092a1ac89d..9b1663dbb6 100644
--- a/lib/uri/rfc3986_parser.rb
+++ b/lib/uri/rfc3986_parser.rb
@@ -1,73 +1,9 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
module URI
class RFC3986_Parser # :nodoc:
# URI defined in RFC3986
- HOST = %r[
- (?<IP-literal>\[(?:
- (?<IPv6address>
- (?:\h{1,4}:){6}
- (?<ls32>\h{1,4}:\h{1,4}
- | (?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)
- \.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>)
- )
- | ::(?:\h{1,4}:){5}\g<ls32>
- | \h{1,4}?::(?:\h{1,4}:){4}\g<ls32>
- | (?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>
- | (?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>
- | (?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>
- | (?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>
- | (?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}
- | (?:(?:\h{1,4}:){,6}\h{1,4})?::
- )
- | (?<IPvFuture>v\h++\.[!$&-.0-9:;=A-Z_a-z~]++)
- )\])
- | \g<IPv4address>
- | (?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*+)
- ]x
-
- USERINFO = /(?:%\h\h|[!$&-.0-9:;=A-Z_a-z~])*+/
-
- SCHEME = %r[[A-Za-z][+\-.0-9A-Za-z]*+].source
- SEG = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/])].source
- SEG_NC = %r[(?:%\h\h|[!$&-.0-9;=@A-Z_a-z~])].source
- FRAGMENT = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+].source
-
- RFC3986_URI = %r[\A
- (?<seg>#{SEG}){0}
- (?<URI>
- (?<scheme>#{SCHEME}):
- (?<hier-part>//
- (?<authority>
- (?:(?<userinfo>#{USERINFO.source})@)?
- (?<host>#{HOST.source.delete(" \n")})
- (?::(?<port>\d*+))?
- )
- (?<path-abempty>(?:/\g<seg>*+)?)
- | (?<path-absolute>/((?!/)\g<seg>++)?)
- | (?<path-rootless>(?!/)\g<seg>++)
- | (?<path-empty>)
- )
- (?:\?(?<query>[^\#]*+))?
- (?:\#(?<fragment>#{FRAGMENT}))?
- )\z]x
-
- RFC3986_relative_ref = %r[\A
- (?<seg>#{SEG}){0}
- (?<relative-ref>
- (?<relative-part>//
- (?<authority>
- (?:(?<userinfo>#{USERINFO.source})@)?
- (?<host>#{HOST.source.delete(" \n")}(?<!/))?
- (?::(?<port>\d*+))?
- )
- (?<path-abempty>(?:/\g<seg>*+)?)
- | (?<path-absolute>/\g<seg>*+)
- | (?<path-noscheme>#{SEG_NC}++(?:/\g<seg>*+)?)
- | (?<path-empty>)
- )
- (?:\?(?<query>[^#]*+))?
- (?:\#(?<fragment>#{FRAGMENT}))?
- )\z]x
+ RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*+):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*+))(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
+ RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])++)(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
attr_reader :regexp
def initialize
@@ -83,9 +19,9 @@ module URI
uri.ascii_only? or
raise InvalidURIError, "URI must be ascii only #{uri.dump}"
if m = RFC3986_URI.match(uri)
- query = m["query"]
- scheme = m["scheme"]
- opaque = m["path-rootless"]
+ query = m["query".freeze]
+ scheme = m["scheme".freeze]
+ opaque = m["path-rootless".freeze]
if opaque
opaque << "?#{query}" if query
[ scheme,
@@ -96,35 +32,35 @@ module URI
nil, # path
opaque,
nil, # query
- m["fragment"]
+ m["fragment".freeze]
]
else # normal
[ scheme,
- m["userinfo"],
- m["host"],
- m["port"],
+ m["userinfo".freeze],
+ m["host".freeze],
+ m["port".freeze],
nil, # registry
- (m["path-abempty"] ||
- m["path-absolute"] ||
- m["path-empty"]),
+ (m["path-abempty".freeze] ||
+ m["path-absolute".freeze] ||
+ m["path-empty".freeze]),
nil, # opaque
query,
- m["fragment"]
+ m["fragment".freeze]
]
end
elsif m = RFC3986_relative_ref.match(uri)
[ nil, # scheme
- m["userinfo"],
- m["host"],
- m["port"],
+ m["userinfo".freeze],
+ m["host".freeze],
+ m["port".freeze],
nil, # registry,
- (m["path-abempty"] ||
- m["path-absolute"] ||
- m["path-noscheme"] ||
- m["path-empty"]),
+ (m["path-abempty".freeze] ||
+ m["path-absolute".freeze] ||
+ m["path-noscheme".freeze] ||
+ m["path-empty".freeze]),
nil, # opaque
- m["query"],
- m["fragment"]
+ m["query".freeze],
+ m["fragment".freeze]
]
else
raise InvalidURIError, "bad URI(is not URI?): #{uri.inspect}"
@@ -156,14 +92,14 @@ module URI
def default_regexp # :nodoc:
{
- SCHEME: %r[\A#{SCHEME}\z]o,
- USERINFO: %r[\A#{USERINFO}\z]o,
- HOST: %r[\A#{HOST}\z]o,
- ABS_PATH: %r[\A/#{SEG}*+\z]o,
- REL_PATH: %r[\A(?!/)#{SEG}++\z]o,
- QUERY: %r[\A(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+\z],
- FRAGMENT: %r[\A#{FRAGMENT}\z]o,
- OPAQUE: %r[\A(?:[^/].*)?\z],
+ SCHEME: /\A[A-Za-z][A-Za-z0-9+\-.]*\z/,
+ USERINFO: /\A(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*\z/,
+ HOST: /\A(?:(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{,4}::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))\z/,
+ ABS_PATH: /\A\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/,
+ REL_PATH: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+(?:\/(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*)*\z/,
+ QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
+ FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/,
+ OPAQUE: /\A(?:[^\/].*)?\z/,
PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
}
end
diff --git a/lib/uri/uri.gemspec b/lib/uri/uri.gemspec
index 9cf0a71196..584a4faa11 100644
--- a/lib/uri/uri.gemspec
+++ b/lib/uri/uri.gemspec
@@ -12,26 +12,18 @@ Gem::Specification.new do |spec|
spec.summary = %q{URI is a module providing classes to handle Uniform Resource Identifiers}
spec.description = spec.summary
-
- github_link = "https://github.com/ruby/uri"
-
- spec.homepage = github_link
+ spec.homepage = "https://github.com/ruby/uri"
spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.required_ruby_version = '>= 2.5'
+ spec.required_ruby_version = '>= 2.4'
- spec.metadata = {
- "bug_tracker_uri" => "#{github_link}/issues",
- "changelog_uri" => "#{github_link}/releases",
- "documentation_uri" => "https://ruby.github.io/uri/",
- "homepage_uri" => spec.homepage,
- "source_code_uri" => github_link
- }
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
diff --git a/lib/uri/version.rb b/lib/uri/version.rb
index 2dafa57d59..c93c97cf6f 100644
--- a/lib/uri/version.rb
+++ b/lib/uri/version.rb
@@ -1,6 +1,6 @@
module URI
# :stopdoc:
- VERSION_CODE = '001300'.freeze
+ VERSION_CODE = '001204'.freeze
VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
# :startdoc:
end
diff --git a/lib/weakref.gemspec b/lib/weakref.gemspec
deleted file mode 100644
index 03893f77e6..0000000000
--- a/lib/weakref.gemspec
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{Allows a referenced object to be garbage-collected.}
- spec.description = %q{Allows a referenced object to be garbage-collected.}
- spec.homepage = "https://github.com/ruby/weakref"
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = "https://github.com/ruby/weakref"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
-
- # Specify which files should be added to the gem when it is released.
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-
- spec.add_dependency "delegate"
-end
diff --git a/lib/weakref.rb b/lib/weakref.rb
index a8da39a26a..2bbadf68f9 100644
--- a/lib/weakref.rb
+++ b/lib/weakref.rb
@@ -17,7 +17,7 @@ require "delegate"
#
class WeakRef < Delegator
- VERSION = "0.1.3"
+ VERSION = "0.1.2"
##
# RefError is raised when a referenced object has been recycled by the
diff --git a/lib/weakref/weakref.gemspec b/lib/weakref/weakref.gemspec
new file mode 100644
index 0000000000..96a9765079
--- /dev/null
+++ b/lib/weakref/weakref.gemspec
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Yukihiro Matsumoto"]
+ spec.email = ["matz@ruby-lang.org"]
+
+ spec.summary = %q{Allows a referenced object to be garbage-collected.}
+ spec.description = %q{Allows a referenced object to be garbage-collected.}
+ spec.homepage = "https://github.com/ruby/weakref"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = "https://github.com/ruby/weakref"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "delegate"
+end
diff --git a/lib/yaml.rb b/lib/yaml.rb
index b2669899dd..6d5d5ebd4c 100644
--- a/lib/yaml.rb
+++ b/lib/yaml.rb
@@ -66,5 +66,4 @@ YAML = Psych # :nodoc:
#
# Syck can also be found on github: https://github.com/ruby/syck
module YAML
- LOADER_VERSION = "0.3.0"
end
diff --git a/lib/yaml/store.rb b/lib/yaml/store.rb
index 88dd1b978c..f8650b942f 100644
--- a/lib/yaml/store.rb
+++ b/lib/yaml/store.rb
@@ -65,7 +65,7 @@ class YAML::Store < PStore
end
def load(content)
- table = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(content) : YAML.load(content)
+ table = YAML.unsafe_load(content)
if table == false
{}
else
diff --git a/lib/yaml/yaml.gemspec b/lib/yaml/yaml.gemspec
index 17e1ce89e0..80554d8a7a 100644
--- a/lib/yaml/yaml.gemspec
+++ b/lib/yaml/yaml.gemspec
@@ -1,13 +1,6 @@
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*LOADER_VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
+ spec.name = "yaml"
+ spec.version = "0.2.1"
spec.authors = ["Aaron Patterson", "SHIBATA Hiroshi"]
spec.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org"]
@@ -22,7 +15,7 @@ Gem::Specification.new do |spec|
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
diff --git a/libexec/bundle b/libexec/bundle
index 92387bc2cf..90c62627f8 100755
--- a/libexec/bundle
+++ b/libexec/bundle
@@ -15,6 +15,15 @@ end
require "bundler"
+if Gem.rubygems_version < Gem::Version.new("3.2.3") && Gem.ruby_version < Gem::Version.new("2.7.a") && !ENV["BUNDLER_NO_OLD_RUBYGEMS_WARNING"]
+ Bundler.ui.warn \
+ "Your RubyGems version (#{Gem::VERSION}) has a bug that prevents " \
+ "`required_ruby_version` from working for Bundler. Any scripts that use " \
+ "`gem install bundler` will break as soon as Bundler drops support for " \
+ "your Ruby version. Please upgrade RubyGems to avoid future breakage " \
+ "and silence this warning by running `gem update --system 3.2.3`"
+end
+
require "bundler/friendly_errors"
Bundler.with_friendly_errors do
@@ -25,5 +34,5 @@ Bundler.with_friendly_errors do
help_flag_used = ARGV.any? {|a| help_flags.include? a }
args = help_flag_used ? Bundler::CLI.reformatted_help_args(ARGV) : ARGV
- Bundler::CLI.start(args, debug: true)
+ Bundler::CLI.start(args, :debug => true)
end
diff --git a/libexec/irb b/libexec/irb
index 12f41e4f0a..c64ee85fbd 100755
--- a/libexec/irb
+++ b/libexec/irb
@@ -1,6 +1,8 @@
#!/usr/bin/env ruby
#
# irb.rb - interactive ruby
+# $Release Version: 0.9.6 $
+# $Revision$
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
diff --git a/libexec/racc b/libexec/racc
new file mode 100755
index 0000000000..4507d04962
--- /dev/null
+++ b/libexec/racc
@@ -0,0 +1,320 @@
+#!/usr/bin/env ruby
+#
+#
+#
+# Copyright (c) 1999-2006 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+# see the file "COPYING".
+
+require 'racc/static'
+require 'optparse'
+
+def main
+ output = nil
+ debug_parser = false
+ make_logfile = false
+ logfilename = nil
+ make_executable = false
+ rubypath = nil
+ embed_runtime = false
+ debug_flags = Racc::DebugFlags.new
+ line_convert = true
+ line_convert_all = false
+ omit_action_call = true
+ superclass = nil
+ check_only = false
+ verbose = false
+ profiler = RaccProfiler.new(false)
+
+ parser = OptionParser.new
+ parser.banner = "Usage: #{File.basename($0)} [options] <input>"
+ parser.on('-o', '--output-file=PATH',
+ 'output file name [<input>.tab.rb]') {|name|
+ output = name
+ }
+ parser.on('-t', '--debug', 'Outputs debugging parser.') {|fl|
+ debug_parser = fl
+ }
+ parser.on('-g', 'Equivalent to -t (obsolete).') {|fl|
+ $stderr.puts "racc -g is obsolete. Use racc -t instead." if $VERBOSE
+ debug_parser = fl
+ }
+ parser.on('-v', '--verbose',
+ 'Creates <filename>.output log file.') {|fl|
+ make_logfile = fl
+ }
+ parser.on('-O', '--log-file=PATH',
+ 'Log file name [<input>.output]') {|path|
+ make_logfile = true
+ logfilename = path
+ }
+ parser.on('-e', '--executable [RUBYPATH]', 'Makes executable parser.') {|path|
+ make_executable = true
+ rubypath = (path == 'ruby' ? nil : path)
+ }
+ parser.on('-E', '--embedded', "Embeds Racc runtime in output.") {
+ embed_runtime = true
+ }
+ parser.on('--line-convert-all', 'Converts line numbers of user codes.') {
+ line_convert_all = true
+ }
+ parser.on('-l', '--no-line-convert', 'Never convert line numbers.') {
+ line_convert = false
+ line_convert_all = false
+ }
+ parser.on('-a', '--no-omit-actions', 'Never omit actions.') {
+ omit_action_call = false
+ }
+ parser.on('--superclass=CLASSNAME',
+ 'Uses CLASSNAME instead of Racc::Parser.') {|name|
+ superclass = name
+ }
+ parser.on('-C', '--check-only', 'Checks syntax and quit immediately.') {|fl|
+ check_only = fl
+ }
+ parser.on('-S', '--output-status', 'Outputs internal status time to time.') {
+ verbose = true
+ }
+ parser.on('-P', 'Enables generator profile') {
+ profiler = RaccProfiler.new(true)
+ }
+ parser.on('-D flags', "Flags for Racc debugging (do not use).") {|flags|
+ debug_flags = Racc::DebugFlags.parse_option_string(flags)
+ }
+ #parser.on('--no-extensions', 'Run Racc without any Ruby extension.') {
+ # Racc.const_set :Racc_No_Extensions, true
+ #}
+ parser.on('--version', 'Prints version and quit.') {
+ puts "racc version #{Racc::Version}"
+ exit 0
+ }
+ parser.on('--runtime-version', 'Prints runtime version and quit.') {
+ printf "racc runtime version %s; %s\n",
+ Racc::Parser::Racc_Runtime_Version,
+ if Racc::Parser.racc_runtime_type == 'ruby'
+ sprintf('ruby core version %s',
+ Racc::Parser::Racc_Runtime_Core_Version_R)
+ else
+ sprintf('c core version %s',
+ Racc::Parser::Racc_Runtime_Core_Version_C)
+ end
+ exit 0
+ }
+ parser.on('--copyright', 'Prints copyright and quit.') {
+ puts Racc::Copyright
+ exit 0
+ }
+ parser.on('--help', 'Prints this message and quit.') {
+ puts parser.help
+ exit 1
+ }
+ begin
+ parser.parse!
+ rescue OptionParser::ParseError => err
+ $stderr.puts err.message
+ $stderr.puts parser.help
+ exit 1
+ end
+ if ARGV.empty?
+ $stderr.puts 'no input'
+ exit 1
+ end
+ if ARGV.size > 1
+ $stderr.puts 'too many input'
+ exit 1
+ end
+ input = ARGV[0]
+
+ begin
+ $stderr.puts 'Parsing grammar file...' if verbose
+ result = profiler.section('parse') {
+ parser = Racc::GrammarFileParser.new(debug_flags)
+ parser.parse(File.read(input), File.basename(input))
+ }
+ if check_only
+ $stderr.puts 'syntax ok'
+ exit 0
+ end
+
+ $stderr.puts 'Generating LALR states...' if verbose
+ states = profiler.section('nfa') {
+ Racc::States.new(result.grammar).nfa
+ }
+
+ $stderr.puts "Resolving #{states.size} states..." if verbose
+ profiler.section('dfa') {
+ states.dfa
+ }
+
+ $stderr.puts 'Creating parser file...' if verbose
+ params = result.params.dup
+ # Overwrites parameters given by a grammar file with command line options.
+ params.superclass = superclass if superclass
+ params.omit_action_call = true if omit_action_call
+ # From command line option
+ if make_executable
+ params.make_executable = true
+ params.interpreter = rubypath
+ end
+ params.debug_parser = debug_parser
+ params.convert_line = line_convert
+ params.convert_line_all = line_convert_all
+ params.embed_runtime = embed_runtime
+ profiler.section('generation') {
+ generator = Racc::ParserFileGenerator.new(states, params)
+ generator.generate_parser_file(output || make_filename(input, '.tab.rb'))
+ }
+
+ if make_logfile
+ profiler.section('logging') {
+ $stderr.puts 'Creating log file...' if verbose
+ logfilename ||= make_filename(output || File.basename(input), '.output')
+ File.open(logfilename, 'w') {|f|
+ Racc::LogFileGenerator.new(states, debug_flags).output f
+ }
+ }
+ end
+ if debug_flags.status_logging
+ log_useless states.grammar
+ log_conflict states
+ else
+ has_useless = report_useless states.grammar
+ has_conflicts = report_conflict states
+ if has_useless || has_conflicts
+ preamble = make_logfile ? 'C' : 'Turn on logging with "-v" and c'
+ $stderr.puts %Q{#{preamble}heck ".output" file for details}
+ end
+ end
+
+ profiler.report
+ rescue Racc::Error, Errno::ENOENT, Errno::EPERM => err
+ raise if $DEBUG or debug_flags.any?
+ lineno = err.message.slice(/\A\d+:/).to_s
+ $stderr.puts "#{File.basename $0}: #{input}:#{lineno} #{err.message.strip}"
+ exit 1
+ end
+end
+
+def make_filename(path, suffix)
+ path.sub(/(?:\..*?)?\z/, suffix)
+end
+
+LIST_LIMIT = 10
+def report_list(enum, label)
+ c = enum.count
+ if c > 0
+ $stderr.puts "#{c} #{label}:"
+ enum.first(LIST_LIMIT).each do |item|
+ $stderr.puts " #{yield item}"
+ end
+ $stderr.puts " ..." if c > LIST_LIMIT
+ end
+end
+
+# @return [Boolean] if anything was reported
+def report_conflict(states)
+ if states.should_report_srconflict?
+ reported = true
+ $stderr.puts "#{states.n_srconflicts} shift/reduce conflicts"
+ end
+ if states.rrconflict_exist?
+ reported = true
+ $stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts"
+ end
+ reported
+end
+
+def log_conflict(states)
+ logging('w') {|f|
+ f.puts "ex#{states.grammar.n_expected_srconflicts}"
+ if states.should_report_srconflict?
+ f.puts "sr#{states.n_srconflicts}"
+ end
+ if states.rrconflict_exist?
+ f.puts "rr#{states.n_rrconflicts}"
+ end
+ }
+end
+
+# @return [Boolean] if anything was reported
+def report_useless(grammar)
+ reported = report_list(grammar.each_useless_nonterminal, 'useless nonterminals', &:to_s)
+
+ reported ||= report_list(grammar.each_useless_rule, 'useless rules') { |r| "##{r.ident} (#{r.target})" }
+
+ if grammar.start.useless?
+ $stderr.puts 'fatal: start symbol does not derive any sentence'
+ reported = true
+ end
+ reported
+end
+
+def log_useless(grammar)
+ logging('a') {|f|
+ if grammar.useless_nonterminal_exist?
+ f.puts "un#{grammar.n_useless_nonterminals}"
+ end
+ if grammar.useless_rule_exist?
+ f.puts "ur#{grammar.n_useless_rules}"
+ end
+ }
+end
+
+def logging(mode, &block)
+ File.open("log/#{File.basename(ARGV[0])}", mode, &block)
+end
+
+class RaccProfiler
+ def initialize(really)
+ @really = really
+ @log = []
+ unless ::Process.respond_to?(:times)
+ # Ruby 1.6
+ @class = ::Time
+ else
+ @class = ::Process
+ end
+ end
+
+ def section(name)
+ if @really
+ t1 = @class.times.utime
+ result = yield
+ t2 = @class.times.utime
+ @log.push [name, t2 - t1]
+ result
+ else
+ yield
+ end
+ end
+
+ def report
+ return unless @really
+ f = $stderr
+ total = cumulative_time()
+ f.puts '--task-----------+--sec------+---%-'
+ @log.each do |name, time|
+ f.printf "%-19s %s %3d%%\n", name, pjust(time,4,4), (time/total*100).to_i
+ end
+ f.puts '-----------------+-----------+-----'
+ f.printf "%-20s%s\n", 'total', pjust(total,4,4)
+ end
+
+ private
+
+ def cumulative_time
+ t = @log.inject(0) {|sum, (name, time)| sum + time }
+ t == 0 ? 0.01 : t
+ end
+
+ def pjust(num, i, j)
+ m = /(\d+)(\.\d+)?/.match(num.to_s)
+ str = m[1].rjust(i)
+ str.concat m[2].ljust(j+1)[0,j+1] if m[2]
+ str
+ end
+end
+
+main
diff --git a/load.c b/load.c
index d962d08b37..ecb21faa72 100644
--- a/load.c
+++ b/load.c
@@ -8,9 +8,8 @@
#include "internal/dir.h"
#include "internal/error.h"
#include "internal/file.h"
-#include "internal/hash.h"
#include "internal/load.h"
-#include "internal/ruby_parser.h"
+#include "internal/parse.h"
#include "internal/thread.h"
#include "internal/variable.h"
#include "iseq.h"
@@ -19,27 +18,12 @@
#include "ruby/encoding.h"
#include "ruby/util.h"
-static VALUE ruby_dln_libmap;
+static VALUE ruby_dln_librefs;
#define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
#define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
#define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
-#if SIZEOF_VALUE <= SIZEOF_LONG
-# define SVALUE2NUM(x) LONG2NUM((long)(x))
-# define NUM2SVALUE(x) (SIGNED_VALUE)NUM2LONG(x)
-#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
-# define SVALUE2NUM(x) LL2NUM((LONG_LONG)(x))
-# define NUM2SVALUE(x) (SIGNED_VALUE)NUM2LL(x)
-#else
-# error Need integer for VALUE
-#endif
-
-enum {
- loadable_ext_rb = (0+ /* .rb extension is the first in both tables */
- 1) /* offset by rb_find_file_ext() */
-};
-
static const char *const loadable_ext[] = {
".rb", DLEXT,
0
@@ -371,13 +355,6 @@ loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
return ST_DELETE;
}
-void
-rb_free_loaded_features_index(rb_vm_t *vm)
-{
- st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
- st_free_table(vm->loaded_features_index);
-}
-
static st_table *
get_loaded_features_index(rb_vm_t *vm)
{
@@ -399,7 +376,7 @@ get_loaded_features_index(rb_vm_t *vm)
VALUE entry, as_str;
as_str = entry = rb_ary_entry(features, i);
StringValue(as_str);
- as_str = rb_fstring(as_str);
+ as_str = rb_fstring(rb_str_freeze(as_str));
if (as_str != entry)
rb_ary_store(features, i, as_str);
features_index_add(vm, as_str, INT2FIX(i));
@@ -498,12 +475,6 @@ loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
return ST_STOP;
}
-/*
- * Returns the type of already provided feature.
- * 'r': ruby script (".rb")
- * 's': shared object (".so"/"."DLEXT)
- * 'u': unsuffixed
- */
static int
rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn)
{
@@ -596,7 +567,7 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
loading_tbl = get_loading_table(vm);
f = 0;
- if (!expanded) {
+ if (!expanded && !rb_is_absolute_path(feature)) {
struct loaded_feature_searching fs;
fs.name = feature;
fs.len = len;
@@ -698,14 +669,14 @@ rb_provide_feature(rb_vm_t *vm, VALUE feature)
rb_raise(rb_eRuntimeError,
"$LOADED_FEATURES is frozen; cannot append feature");
}
- feature = rb_fstring(feature);
+ rb_str_freeze(feature);
get_loaded_features_index(vm);
// If loaded_features and loaded_features_snapshot share the same backing
// array, pushing into it would cause the whole array to be copied.
// To avoid this we first clear loaded_features_snapshot.
rb_ary_clear(vm->loaded_features_snapshot);
- rb_ary_push(features, feature);
+ rb_ary_push(features, rb_fstring(feature));
features_index_add(vm, feature, INT2FIX(RARRAY_LEN(features)-1));
reset_loaded_features_snapshot(vm);
}
@@ -718,57 +689,23 @@ rb_provide(const char *feature)
NORETURN(static void load_failed(VALUE));
-static inline VALUE
-realpath_internal_cached(VALUE hash, VALUE path)
-{
- VALUE ret = rb_hash_aref(hash, path);
- if(RTEST(ret)) {
- return ret;
- }
-
- VALUE realpath = rb_realpath_internal(Qnil, path, 1);
- rb_hash_aset(hash, rb_fstring(path), rb_fstring(realpath));
- return realpath;
-}
-
static inline void
load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
{
const rb_iseq_t *iseq = rb_iseq_load_iseq(fname);
if (!iseq) {
- if (*rb_ruby_prism_ptr()) {
- pm_string_t input;
- pm_options_t options = { 0 };
-
- pm_string_mapped_init(&input, RSTRING_PTR(fname));
- pm_options_filepath_set(&options, RSTRING_PTR(fname));
-
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
-
- iseq = rb_iseq_new_main_prism(&input, &options, fname);
-
- pm_string_free(&input);
- pm_options_free(&options);
- }
- else {
- rb_execution_context_t *ec = GET_EC();
- VALUE v = rb_vm_push_frame_fname(ec, fname);
- rb_ast_t *ast;
- VALUE parser = rb_parser_new();
- rb_parser_set_context(parser, NULL, FALSE);
- ast = (rb_ast_t *)rb_parser_load_file(parser, fname);
-
- rb_thread_t *th = rb_ec_thread_ptr(ec);
- VALUE realpath_map = get_loaded_features_realpath_map(th->vm);
-
- iseq = rb_iseq_new_top(&ast->body, rb_fstring_lit("<top (required)>"),
- fname, realpath_internal_cached(realpath_map, fname), NULL);
- rb_ast_dispose(ast);
- rb_vm_pop_frame(ec);
- RB_GC_GUARD(v);
- }
+ rb_execution_context_t *ec = GET_EC();
+ VALUE v = rb_vm_push_frame_fname(ec, fname);
+ rb_ast_t *ast;
+ VALUE parser = rb_parser_new();
+ rb_parser_set_context(parser, NULL, FALSE);
+ ast = (rb_ast_t *)rb_parser_load_file(parser, fname);
+ iseq = rb_iseq_new_top(&ast->body, rb_fstring_lit("<top (required)>"),
+ fname, rb_realpath_internal(Qnil, fname, 1), NULL);
+ rb_ast_dispose(ast);
+ rb_vm_pop_frame(ec);
+ RB_GC_GUARD(v);
}
rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
rb_iseq_eval(iseq);
@@ -970,7 +907,7 @@ load_unlock(rb_vm_t *vm, const char *ftptr, int done)
}
}
-static VALUE rb_require_string_internal(VALUE fname, bool resurrect);
+static VALUE rb_require_string_internal(VALUE fname);
/*
* call-seq:
@@ -985,14 +922,15 @@ static VALUE rb_require_string_internal(VALUE fname, bool resurrect);
* If the filename starts with './' or '../', resolution is based on Dir.pwd.
*
* If the filename has the extension ".rb", it is loaded as a source file; if
- * the extension is ".so", ".o", or the default shared library extension on
- * the current platform, Ruby loads the shared library as a Ruby extension.
- * Otherwise, Ruby tries adding ".rb", ".so", and so on to the name until
- * found. If the file named cannot be found, a LoadError will be raised.
+ * the extension is ".so", ".o", or ".dll", or the default shared library
+ * extension on the current platform, Ruby loads the shared library as a
+ * Ruby extension. Otherwise, Ruby tries adding ".rb", ".so", and so on
+ * to the name until found. If the file named cannot be found, a LoadError
+ * will be raised.
*
- * For Ruby extensions the filename given may use ".so" or ".o". For example,
- * on macOS the socket extension is "socket.bundle" and
- * <code>require 'socket.so'</code> will load the socket extension.
+ * For Ruby extensions the filename given may use any shared library
+ * extension. For example, on Linux the socket extension is "socket.so" and
+ * <code>require 'socket.dll'</code> will load the socket extension.
*
* The absolute path of the loaded file is added to
* <code>$LOADED_FEATURES</code> (<code>$"</code>). A file will not be
@@ -1032,7 +970,7 @@ rb_f_require_relative(VALUE obj, VALUE fname)
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
- return rb_require_string_internal(rb_file_absolute_path(fname, base), false);
+ return rb_require_string_internal(rb_file_absolute_path(fname, base));
}
typedef int (*feature_func)(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn);
@@ -1042,7 +980,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
{
VALUE tmp;
char *ext, *ftptr;
- int ft = 0;
+ int type, ft = 0;
const char *loading;
*path = 0;
@@ -1094,11 +1032,11 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
return 'r';
}
tmp = fname;
- const unsigned int type = rb_find_file_ext(&tmp, ft == 's' ? ruby_ext : loadable_ext);
+ type = rb_find_file_ext(&tmp, ft == 's' ? ruby_ext : loadable_ext);
// Check if it's a statically linked extension when
// not already a feature and not found as a dynamic library.
- if (!ft && type != loadable_ext_rb && vm->static_ext_inits) {
+ if (!ft && type != 1 && vm->static_ext_inits) {
VALUE lookup_name = tmp;
// Append ".so" if not already present so for example "etc" can find "etc.so".
// We always register statically linked extensions with a ".so" extension.
@@ -1126,13 +1064,13 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
goto feature_present;
}
/* fall through */
- case loadable_ext_rb:
+ case 1:
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (rb_feature_p(vm, ftptr, ext, type == loadable_ext_rb, TRUE, &loading) && !loading)
+ if (rb_feature_p(vm, ftptr, ext, !--type, TRUE, &loading) && !loading)
break;
*path = tmp;
}
- return type > loadable_ext_rb ? 's' : 'r';
+ return type ? 's' : 'r';
feature_present:
if (loading) *path = rb_filesystem_str_new_cstr(loading);
@@ -1230,10 +1168,8 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
rb_thread_t *th = rb_ec_thread_ptr(ec);
volatile const struct {
VALUE wrapper, self, errinfo;
- rb_execution_context_t *ec;
} saved = {
th->top_wrapper, th->top_self, ec->errinfo,
- ec,
};
enum ruby_tag_type state;
char *volatile ftptr = 0;
@@ -1253,7 +1189,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
ec->errinfo = Qnil; /* ensure */
th->top_wrapper = 0;
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
- VALUE handle;
+ long handle;
int found;
RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname));
@@ -1272,7 +1208,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
result = TAG_RETURN;
}
else if (RTEST(rb_hash_aref(realpaths,
- realpath = realpath_internal_cached(realpath_map, path)))) {
+ realpath = rb_realpath_internal(Qnil, path, 1)))) {
result = 0;
}
else {
@@ -1284,9 +1220,9 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
case 's':
reset_ext_config = true;
ext_config_push(th, &prev_ext_config);
- handle = rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
- path, VM_BLOCK_HANDLER_NONE, path);
- rb_hash_aset(ruby_dln_libmap, path, SVALUE2NUM((SIGNED_VALUE)handle));
+ handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
+ path, VM_BLOCK_HANDLER_NONE, path);
+ rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
break;
}
result = TAG_RETURN;
@@ -1295,7 +1231,6 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
}
EC_POP_TAG();
- ec = saved.ec;
rb_thread_t *th2 = rb_ec_thread_ptr(ec);
th2->top_self = saved.self;
th2->top_wrapper = saved.wrapper;
@@ -1333,6 +1268,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
if (real) {
real = rb_fstring(real);
rb_hash_aset(realpaths, real, Qtrue);
+ rb_hash_aset(realpath_map, path, real);
}
}
ec->errinfo = saved.errinfo;
@@ -1370,11 +1306,11 @@ ruby_require_internal(const char *fname, unsigned int len)
VALUE
rb_require_string(VALUE fname)
{
- return rb_require_string_internal(FilePathValue(fname), false);
+ return rb_require_string_internal(FilePathValue(fname));
}
static VALUE
-rb_require_string_internal(VALUE fname, bool resurrect)
+rb_require_string_internal(VALUE fname)
{
rb_execution_context_t *ec = GET_EC();
int result = require_internal(ec, fname, 1, RTEST(ruby_verbose));
@@ -1383,7 +1319,6 @@ rb_require_string_internal(VALUE fname, bool resurrect)
EC_JUMP_TAG(ec, result);
}
if (result < 0) {
- if (resurrect) fname = rb_str_resurrect(fname);
load_failed(fname);
}
@@ -1395,7 +1330,7 @@ rb_require(const char *fname)
{
struct RString fake;
VALUE str = rb_setup_fake_str(&fake, fname, strlen(fname), 0);
- return rb_require_string_internal(str, true);
+ return rb_require_string_internal(str);
}
static int
@@ -1546,37 +1481,6 @@ rb_f_autoload_p(int argc, VALUE *argv, VALUE obj)
return rb_mod_autoload_p(argc, argv, klass);
}
-void *
-rb_ext_resolve_symbol(const char* fname, const char* symbol)
-{
- VALUE handle;
- VALUE resolved;
- VALUE path;
- char *ext;
- VALUE fname_str = rb_str_new_cstr(fname);
-
- resolved = rb_resolve_feature_path((VALUE)NULL, fname_str);
- if (NIL_P(resolved)) {
- ext = strrchr(fname, '.');
- if (!ext || !IS_SOEXT(ext)) {
- rb_str_cat_cstr(fname_str, ".so");
- }
- if (rb_feature_p(GET_VM(), fname, 0, FALSE, FALSE, 0)) {
- return dln_symbol(NULL, symbol);
- }
- return NULL;
- }
- if (RARRAY_LEN(resolved) != 2 || rb_ary_entry(resolved, 0) != ID2SYM(rb_intern("so"))) {
- return NULL;
- }
- path = rb_ary_entry(resolved, 1);
- handle = rb_hash_lookup(ruby_dln_libmap, path);
- if (NIL_P(handle)) {
- return NULL;
- }
- return dln_symbol((void *)NUM2SVALUE(handle), symbol);
-}
-
void
Init_load(void)
{
@@ -1611,6 +1515,6 @@ Init_load(void)
rb_define_global_function("autoload", rb_f_autoload, 2);
rb_define_global_function("autoload?", rb_f_autoload_p, -1);
- ruby_dln_libmap = rb_hash_new_with_size(0);
- rb_gc_register_mark_object(ruby_dln_libmap);
+ ruby_dln_librefs = rb_ary_hidden_new(0);
+ rb_gc_register_mark_object(ruby_dln_librefs);
}
diff --git a/main.c b/main.c
index 072dc56dd5..c87355e46e 100644
--- a/main.c
+++ b/main.c
@@ -23,7 +23,6 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
-
#if defined RUBY_DEVEL && !defined RUBY_DEBUG_ENV
# define RUBY_DEBUG_ENV 1
#endif
@@ -44,10 +43,16 @@ int rb_wasm_rt_start(int (main)(int argc, char **argv), int argc, char **argv);
#define rb_main(argc, argv) rb_wasm_rt_start(rb_main, argc, argv)
#endif
+#ifdef _WIN32
+#define main(argc, argv) w32_main(argc, argv)
+static int main(int argc, char **argv);
+int wmain(void) {return main(0, NULL);}
+#endif
+
int
main(int argc, char **argv)
{
-#if defined(RUBY_DEBUG_ENV) || USE_RUBY_DEBUG_LOG
+#ifdef RUBY_DEBUG_ENV
ruby_set_debug_option(getenv("RUBY_DEBUG"));
#endif
#ifdef HAVE_LOCALE_H
diff --git a/man/irb.1 b/man/irb.1
index 93ef9b8f66..c589c99c78 100644
--- a/man/irb.1
+++ b/man/irb.1
@@ -140,13 +140,6 @@ Use autocompletion.
Don't use autocompletion.
.Pp
.Pp
-.It Fl -regexp-completor
-Use regexp based completion.
-.Pp
-.It Fl -type-completor
-Use type based completion.
-.Pp
-.Pp
.It Fl -verbose
Show details.
.Pp
diff --git a/man/ruby.1 b/man/ruby.1
index a2b69c3cd6..86ad73c2ab 100644
--- a/man/ruby.1
+++ b/man/ruby.1
@@ -25,7 +25,6 @@
.Op Fl - Ns Bro Cm enable Ns | Ns Cm disable Brc Ns - Ns Ar FEATURE
.Op Fl -dump Ns = Ns Ar target
.Op Fl -verbose
-.Op Fl -crash-report Ns = Ns Ar template
.Op Fl -
.Op Ar program_file
.Op Ar argument ...
@@ -272,11 +271,6 @@ In auto-split mode, Ruby executes
.Dl $F = $_.split
at beginning of each loop.
.Pp
-.It Fl -backtrace-limit Ns = Ns Ar num
-Limits the maximum length of backtraces to
-.Ar num
-lines (default -1, meaning no limit).
-.Pp
.It Fl c
Causes Ruby to check the syntax of the script and exit without
executing. If there are no syntax errors, Ruby will print
@@ -394,7 +388,7 @@ before executing script.
.Pp
.It Fl y
.It Fl -yydebug
-This option is not guaranteed to be compatible.
+DO NOT USE.
.Pp
Turns on compiler debug mode. Ruby will print a bunch of internal
state messages during compilation. Only specify this switch you are going to
@@ -470,12 +464,6 @@ variable to true.
If this switch is given, and no script arguments (script file or
.Fl e
options) are present, Ruby quits immediately.
-.Pp
-.It Fl -crash-report Ns = Ns Ar template
-Sets the template of path name to save crash report.
-See
-.Ev RUBY_CRASH_REPORT
-environment variable for details.
.El
.Pp
.Sh ENVIRONMENT
@@ -562,12 +550,7 @@ There are currently 4 possible areas where the GC may be tuned by
the following 11 environment variables:
.Bl -hang -compact -width "RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR"
.It Ev RUBY_GC_HEAP_INIT_SLOTS
-Initial allocation slots. Applies to all slot sizes. Introduced in Ruby 2.1, default: 10000.
-.Pp
-.It Ev RUBY_GC_HEAP_%d_INIT_SLOTS
-Initial allocation of slots in a specific heap.
-The available heaps can be found in the keys of `GC.stat_heap`.
-Introduced in Ruby 3.3.
+Initial allocation slots. Introduced in Ruby 2.1, default: 10000.
.Pp
.It Ev RUBY_GC_HEAP_FREE_SLOTS
Prepare at least this amount of slots after GC.
@@ -652,61 +635,6 @@ Machine stack size used at fiber creation.
default: 262144 or 524288
.Pp
.El
-.Sh CRASH REPORT ENVIRONMENT
-.Pp
-.Bl -tag -compact -width "RUBY_CRASH_REPORT"
-.It Ev RUBY_CRASH_REPORT
-The template of path name to save crash report.
-default: none
-.El
-.Ss Naming crash report files
-The template can contain
-.Li \fB%\fP
-specifiers which are substituted by the following values when a crash
-report file is created:
-.Pp
-.Bl -hang -compact -width "%NNN"
-.It Li \fB%%\fP
-A single
-.Li \fB%\fP
-character.
-.It Li \fB%e\fP
-Basename of executable.
-.It Li \fB%E\fP
-Pathname of executable,
-with slashes (\fB/\fP) replaced by exclamation marks (\fB!\fP).
-.It Li \fB%f\fP
-Basename of the program name,
-.Li "$0" .
-.It Li \fB%F\fP
-Pathname of the program name,
-.Li "$0",
-with slashes (\fB/\fP) replaced by exclamation marks (\fB!\fP).
-.It Li \fB%p\fP
-PID of dumped process.
-.It Li \fB%t\fP
-Time of dump, expressed as seconds since the
-Epoch, 1970-01-01 00:00:00 +0000 (UTC).
-.It Li \fB%NNN\fP
-A character code in octal.
-.El
-.Pp
-A single
-.Li \fB%\fP
-at the end of the template is dropped from the core filename, as is
-the combination of a
-.Li \fB%\fP
-followed by any character other than those listed above. All other
-characters in the template become a literal part of the core filename.
-The template may include \(aq/\(aq characters, which are interpreted
-as delimiters for directory names.
-.Ss Piping crash reports to a program
-If the first character of this file is a pipe symbol (\fB|\fP),
-then the remainder of the line is interpreted as the command-line for
-a program (or script) that is to be executed.
-.Pp
-The pipe template is split on spaces into an argument list before the
-template parameters are expanded.
.Sh SEE ALSO
.Bl -hang -compact -width "https://www.ruby-toolbox.com/"
.It Lk https://www.ruby-lang.org/
@@ -734,5 +662,5 @@ Ruby is designed and implemented by
.An Yukihiro Matsumoto Aq matz@netlab.jp .
.Pp
See
-.Aq Lk https://github.com/ruby/ruby/graphs/contributors
+.Aq Lk https://bugs.ruby-lang.org/projects/ruby/wiki/Contributors
for contributors to Ruby.
diff --git a/marshal.c b/marshal.c
index 1cd71efd54..4ea4255971 100644
--- a/marshal.c
+++ b/marshal.c
@@ -40,6 +40,7 @@
#include "ruby/util.h"
#include "builtin.h"
#include "shape.h"
+#include "ruby/internal/attr/nonstring.h"
#define BITSPERSHORT (2*CHAR_BIT)
#define SHORTMASK ((1<<BITSPERSHORT)-1)
@@ -173,7 +174,7 @@ struct dump_arg {
st_table *data;
st_table *compat_tbl;
st_table *encodings;
- st_index_t num_entries;
+ unsigned long num_entries;
};
struct dump_call_arg {
@@ -228,24 +229,19 @@ static void
free_dump_arg(void *ptr)
{
clear_dump_arg(ptr);
+ xfree(ptr);
}
static size_t
memsize_dump_arg(const void *ptr)
{
- const struct dump_arg *p = (struct dump_arg *)ptr;
- size_t memsize = 0;
- if (p->symbols) memsize += rb_st_memsize(p->symbols);
- if (p->data) memsize += rb_st_memsize(p->data);
- if (p->compat_tbl) memsize += rb_st_memsize(p->compat_tbl);
- if (p->encodings) memsize += rb_st_memsize(p->encodings);
- return memsize;
+ return sizeof(struct dump_arg);
}
static const rb_data_type_t dump_arg_data = {
"dump_arg",
{mark_dump_arg, free_dump_arg, memsize_dump_arg,},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
@@ -466,7 +462,7 @@ w_float(double d, struct dump_arg *arg)
memcpy(buf + len, p, digs);
len += digs;
}
- free(p);
+ xfree(p);
w_bytes(buf, len, arg);
}
}
@@ -528,7 +524,7 @@ hash_each(VALUE key, VALUE value, VALUE v)
#define SINGLETON_DUMP_UNABLE_P(klass) \
(rb_id_table_size(RCLASS_M_TBL(klass)) > 0 || \
- rb_ivar_count(klass) > 0)
+ rb_ivar_count(klass) > 1)
static void
w_extended(VALUE klass, struct dump_arg *arg, int check)
@@ -610,8 +606,10 @@ struct w_ivar_arg {
};
static int
-w_obj_each(ID id, VALUE value, st_data_t a)
+w_obj_each(st_data_t key, st_data_t val, st_data_t a)
{
+ ID id = (ID)key;
+ VALUE value = (VALUE)val;
struct w_ivar_arg *ivarg = (struct w_ivar_arg *)a;
struct dump_call_arg *arg = ivarg->dump;
@@ -633,8 +631,9 @@ w_obj_each(ID id, VALUE value, st_data_t a)
}
static int
-obj_count_ivars(ID id, VALUE val, st_data_t a)
+obj_count_ivars(st_data_t key, st_data_t val, st_data_t a)
{
+ ID id = (ID)key;
if (!to_be_skipped_id(id) && UNLIKELY(!++*(st_index_t *)a)) {
rb_raise(rb_eRuntimeError, "too many instance variables");
}
@@ -1274,24 +1273,19 @@ static void
free_load_arg(void *ptr)
{
clear_load_arg(ptr);
+ xfree(ptr);
}
static size_t
memsize_load_arg(const void *ptr)
{
- const struct load_arg *p = (struct load_arg *)ptr;
- size_t memsize = 0;
- if (p->symbols) memsize += rb_st_memsize(p->symbols);
- if (p->data) memsize += rb_st_memsize(p->data);
- if (p->partial_objects) memsize += rb_st_memsize(p->partial_objects);
- if (p->compat_tbl) memsize += rb_st_memsize(p->compat_tbl);
- return memsize;
+ return sizeof(struct load_arg);
}
static const rb_data_type_t load_arg_data = {
"load_arg",
{mark_load_arg, free_load_arg, memsize_load_arg,},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
#define r_entry(v, arg) r_entry0((v), (arg)->data->num_entries, (arg))
@@ -1508,7 +1502,7 @@ name_equal(const char *name, size_t nlen, const char *p, long l)
static int
sym2encidx(VALUE sym, VALUE val)
{
- static const char name_encoding[8] = "encoding";
+ RBIMPL_ATTR_NONSTRING() static const char name_encoding[8] = "encoding";
const char *p;
long l;
if (rb_enc_get_index(sym) != ENCINDEX_US_ASCII) return -1;
@@ -1680,9 +1674,10 @@ r_leave(VALUE v, struct load_arg *arg, bool partial)
}
static int
-copy_ivar_i(ID vid, VALUE value, st_data_t arg)
+copy_ivar_i(st_data_t key, st_data_t val, st_data_t arg)
{
- VALUE obj = (VALUE)arg;
+ VALUE obj = (VALUE)arg, value = (VALUE)val;
+ ID vid = (ID)key;
if (!rb_ivar_defined(obj, vid))
rb_ivar_set(obj, vid, value);
@@ -1809,6 +1804,20 @@ r_object0(struct load_arg *arg, bool partial, int *ivp, VALUE extmod)
return r_object_for(arg, partial, ivp, extmod, type);
}
+static int
+r_move_ivar(st_data_t k, st_data_t v, st_data_t d)
+{
+ ID key = (ID)k;
+ VALUE value = (VALUE)v;
+ VALUE dest = (VALUE)d;
+
+ if (rb_is_instance_id(key)) {
+ rb_ivar_set(dest, key, value);
+ return ST_DELETE;
+ }
+ return ST_CONTINUE;
+}
+
static VALUE
r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int type)
{
@@ -1870,7 +1879,6 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ
rb_extend_object(v, m);
}
}
- v = r_leave(v, arg, partial);
}
break;
@@ -2026,7 +2034,7 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ
rb_str_set_len(str, dst - ptr);
}
VALUE regexp = rb_reg_new_str(str, options);
- r_copy_ivar(regexp, str);
+ rb_ivar_foreach(str, r_move_ivar, regexp);
v = r_entry0(regexp, idx, arg);
v = r_leave(v, arg, partial);
@@ -2147,12 +2155,7 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ
marshal_compat_t *compat = (marshal_compat_t*)d;
v = compat->loader(klass, v);
}
- if (!partial) {
- if (arg->freeze) {
- OBJ_FREEZE(v);
- }
- v = r_post_proc(v, arg);
- }
+ if (!partial) v = r_post_proc(v, arg);
}
break;
@@ -2177,9 +2180,6 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ
load_funcall(arg, v, s_mload, 1, &data);
v = r_fixup_compat(v, arg);
v = r_copy_ivar(v, data);
- if (arg->freeze) {
- OBJ_FREEZE(v);
- }
v = r_post_proc(v, arg);
if (!NIL_P(extmod)) {
if (oldclass) append_extmod(v, extmod);
@@ -2517,20 +2517,6 @@ Init_marshal(void)
rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR));
}
-static int
-free_compat_i(st_data_t key, st_data_t value, st_data_t _)
-{
- xfree((marshal_compat_t *)value);
- return ST_CONTINUE;
-}
-
-static void
-free_compat_allocator_table(void *data)
-{
- st_foreach(data, free_compat_i, 0);
- st_free_table(data);
-}
-
static st_table *
compat_allocator_table(void)
{
@@ -2539,7 +2525,7 @@ compat_allocator_table(void)
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
compat_allocator_tbl_wrapper =
- Data_Wrap_Struct(0, mark_marshal_compat_t, free_compat_allocator_table, compat_allocator_tbl);
+ Data_Wrap_Struct(0, mark_marshal_compat_t, 0, compat_allocator_tbl);
rb_gc_register_mark_object(compat_allocator_tbl_wrapper);
return compat_allocator_tbl;
}
diff --git a/math.c b/math.c
index 2394fe9f58..67bf8b7b63 100644
--- a/math.c
+++ b/math.c
@@ -170,12 +170,6 @@ math_tan(VALUE unused_obj, VALUE x)
return DBL2NUM(tan(Get_Double(x)));
}
-#define math_arc(num, func) \
- double d; \
- d = Get_Double((num)); \
- domain_check_range(d, -1.0, 1.0, #func); \
- return DBL2NUM(func(d));
-
/*
* call-seq:
* Math.acos(x) -> float
@@ -196,7 +190,11 @@ math_tan(VALUE unused_obj, VALUE x)
static VALUE
math_acos(VALUE unused_obj, VALUE x)
{
- math_arc(x, acos)
+ double d;
+
+ d = Get_Double(x);
+ domain_check_range(d, -1.0, 1.0, "acos");
+ return DBL2NUM(acos(d));
}
/*
@@ -219,7 +217,11 @@ math_acos(VALUE unused_obj, VALUE x)
static VALUE
math_asin(VALUE unused_obj, VALUE x)
{
- math_arc(x, asin)
+ double d;
+
+ d = Get_Double(x);
+ domain_check_range(d, -1.0, 1.0, "asin");
+ return DBL2NUM(asin(d));
}
/*
@@ -474,6 +476,7 @@ math_exp(VALUE unused_obj, VALUE x)
# define M_LN10 2.30258509299404568401799145468436421
#endif
+static double math_log1(VALUE x);
FUNC_MINIMIZED(static VALUE math_log(int, const VALUE *, VALUE));
/*
@@ -508,6 +511,20 @@ math_log(int argc, const VALUE *argv, VALUE unused_obj)
return rb_math_log(argc, argv);
}
+VALUE
+rb_math_log(int argc, const VALUE *argv)
+{
+ VALUE x, base;
+ double d;
+
+ rb_scan_args(argc, argv, "11", &x, &base);
+ d = math_log1(x);
+ if (argc == 2) {
+ d /= math_log1(base);
+ }
+ return DBL2NUM(d);
+}
+
static double
get_double_rshift(VALUE x, size_t *pnumbits)
{
@@ -526,51 +543,16 @@ get_double_rshift(VALUE x, size_t *pnumbits)
}
static double
-math_log_split(VALUE x, size_t *numbits)
+math_log1(VALUE x)
{
- double d = get_double_rshift(x, numbits);
+ size_t numbits;
+ double d = get_double_rshift(x, &numbits);
domain_check_min(d, 0.0, "log");
- return d;
-}
-
-#if defined(log2) || defined(HAVE_LOG2)
-# define log_intermediate log2
-#else
-# define log_intermediate log10
-double log2(double x);
-#endif
-
-VALUE
-rb_math_log(int argc, const VALUE *argv)
-{
- VALUE x, base;
- double d;
- size_t numbits;
+ /* check for pole error */
+ if (d == 0.0) return -HUGE_VAL;
- argc = rb_scan_args(argc, argv, "11", &x, &base);
- d = math_log_split(x, &numbits);
- if (argc == 2) {
- size_t numbits_2;
- double b = math_log_split(base, &numbits_2);
- /* check for pole error */
- if (d == 0.0) {
- // Already DomainError if b < 0.0
- return b ? DBL2NUM(-HUGE_VAL) : DBL2NUM(NAN);
- }
- else if (b == 0.0) {
- return DBL2NUM(-0.0);
- }
- d = log_intermediate(d) / log_intermediate(b);
- d += (numbits - numbits_2) / log2(b);
- }
- else {
- /* check for pole error */
- if (d == 0.0) return DBL2NUM(-HUGE_VAL);
- d = log(d);
- d += numbits * M_LN2;
- }
- return DBL2NUM(d);
+ return log(d) + numbits * M_LN2; /* log(d * 2 ** numbits) */
}
#ifndef log2
@@ -731,7 +713,7 @@ rb_math_sqrt(VALUE x)
* cbrt(1.0) # => 1.0
* cbrt(0.0) # => 0.0
* cbrt(1.0) # => 1.0
- * cbrt(2.0) # => 1.2599210498948732
+ cbrt(2.0) # => 1.2599210498948732
* cbrt(8.0) # => 2.0
* cbrt(27.0) # => 3.0
* cbrt(INFINITY) # => Infinity
diff --git a/method.h b/method.h
index ad66690c6a..ec89bf26bb 100644
--- a/method.h
+++ b/method.h
@@ -153,6 +153,7 @@ typedef struct rb_method_alias_struct {
typedef struct rb_method_refined_struct {
struct rb_method_entry_struct * orig_me;
+ VALUE owner;
} rb_method_refined_t;
typedef struct rb_method_bmethod_struct {
@@ -199,7 +200,7 @@ struct rb_method_definition_struct {
struct rb_id_table;
typedef struct rb_method_definition_struct rb_method_definition_t;
-STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body) <= 8);
+STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body)==8);
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
#define UNDEFINED_REFINED_METHOD_P(def) \
@@ -249,6 +250,6 @@ void rb_scope_visibility_set(rb_method_visibility_t);
VALUE rb_unnamed_parameters(int arity);
void rb_clear_method_cache(VALUE klass_or_module, ID mid);
-void rb_clear_all_refinement_method_cache(void);
+void rb_clear_method_cache_all(void);
#endif /* RUBY_METHOD_H */
diff --git a/mini_builtin.c b/mini_builtin.c
index 457327ee06..c263d1ee71 100644
--- a/mini_builtin.c
+++ b/mini_builtin.c
@@ -21,22 +21,18 @@ builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *ta
rb_ast_t *ast = rb_builtin_ast(feature_name, &name_str);
rb_vm_t *vm = GET_VM();
- if (!ast) {
- rb_fatal("builtin_iseq_load: can not find %s; "
- "probably miniprelude.c is out of date",
- feature_name);
- }
vm->builtin_function_table = table;
vm->builtin_inline_index = 0;
static const rb_compile_option_t optimization = {
- TRUE, /* unsigned int inline_const_cache; */
- TRUE, /* unsigned int peephole_optimization; */
- FALSE,/* unsigned int tailcall_optimization; */
- TRUE, /* unsigned int specialized_instruction; */
- TRUE, /* unsigned int operands_unification; */
- TRUE, /* unsigned int instructions_unification; */
- TRUE, /* unsigned int frozen_string_literal; */
- FALSE, /* unsigned int debug_frozen_string_literal; */
+ TRUE, /* int inline_const_cache; */
+ TRUE, /* int peephole_optimization; */
+ FALSE,/* int tailcall_optimization; */
+ TRUE, /* int specialized_instruction; */
+ TRUE, /* int operands_unification; */
+ TRUE, /* int instructions_unification; */
+ TRUE, /* int stack_caching; */
+ TRUE, /* int frozen_string_literal; */
+ FALSE, /* int debug_frozen_string_literal; */
FALSE, /* unsigned int coverage_enabled; */
0, /* int debug_level; */
};
@@ -78,7 +74,6 @@ each_builtin_i(st_data_t key, st_data_t val, st_data_t dmy)
return ST_CONTINUE;
}
-/* :nodoc: */
static VALUE
each_builtin(VALUE self)
{
diff --git a/miniinit.c b/miniinit.c
index bb22d6d9f5..2a14a0d1c5 100644
--- a/miniinit.c
+++ b/miniinit.c
@@ -49,10 +49,3 @@ Init_enc(void)
}
#include "mini_builtin.c"
-
-void
-rb_free_loaded_builtin_table(void)
-{
- if (loaded_builtin_table)
- st_free_table(loaded_builtin_table);
-}
diff --git a/misc/.vscode/launch.json b/misc/.vscode/launch.json
deleted file mode 100644
index 51bfef09d7..0000000000
--- a/misc/.vscode/launch.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "version": "0.2.0",
- "configurations": [
- {
- "type": "lldb",
- "name": "Run ruby",
- "request": "launch",
- "program": "${workspaceFolder}/ruby",
- "args": ["test.rb"],
- "preLaunchTask": "${defaultBuildTask}"
- }
- ]
-}
diff --git a/misc/.vscode/settings.json b/misc/.vscode/settings.json
deleted file mode 100644
index 7b1a38c536..0000000000
--- a/misc/.vscode/settings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "rust-analyzer.cargo.features": [
- "disasm",
- ],
- "rust-analyzer.cargo.unsetTest": [
- "yjit",
- ],
-}
diff --git a/misc/.vscode/tasks.json b/misc/.vscode/tasks.json
deleted file mode 100644
index 045fe7e5c0..0000000000
--- a/misc/.vscode/tasks.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "version": "2.0.0",
- "tasks": [
- {
- "label": "build",
- "type": "shell",
- "command": "make -j",
- "group": {
- "kind": "build",
- "isDefault": true
- }
- }
- ]
-}
diff --git a/misc/README b/misc/README
index 86b680e724..1728b42700 100644
--- a/misc/README
+++ b/misc/README
@@ -4,4 +4,3 @@ rb_optparse.zsh zsh completion script
ruby-style.el Ruby's C/C++ mode style for emacs
lldb_cruby.py LLDB port of debug utility
test_lldb_cruby.rb test file for LLDB port
-.vscode example VSCode config to debug Ruby
diff --git a/misc/call_fuzzer.rb b/misc/call_fuzzer.rb
deleted file mode 100644
index c3f9f90490..0000000000
--- a/misc/call_fuzzer.rb
+++ /dev/null
@@ -1,372 +0,0 @@
-require 'optparse'
-require 'set'
-
-# Number of iterations to test
-num_iters = 10_000
-
-# Parse the command-line options
-OptionParser.new do |opts|
- opts.on("--num-iters=N") do |n|
- num_iters = n.to_i
- end
-end.parse!
-
-# Format large numbers with comma separators for readability
-def format_number(pad, number)
- s = number.to_s
- i = s.index('.') || s.size
- s.insert(i -= 3, ',') while i > 3
- s.rjust(pad, ' ')
-end
-
-# Wrap an integer to pass as argument
-# We use this so we can have some object arguments
-class IntWrapper
- def initialize(v)
- # Force the object to have a random shape
- if rand() < 50
- @v0 = 1
- end
- if rand() < 50
- @v1 = 1
- end
- if rand() < 50
- @v2 = 1
- end
- if rand() < 50
- @v3 = 1
- end
- if rand() < 50
- @v4 = 1
- end
- if rand() < 50
- @v5 = 1
- end
- if rand() < 50
- @v6 = 1
- end
-
- @value = v
- end
-
- attr_reader :value
-end
-
-# Generate a random argument value, integer or string or object
-def sample_arg()
- c = ['int', 'string', 'object'].sample()
-
- if c == 'int'
- return rand(0...100)
- end
-
- if c == 'string'
- return 'f' * rand(0...100)
- end
-
- if c == 'object'
- return IntWrapper.new(rand(0...100))
- end
-
- raise "should not get here"
-end
-
-# Evaluate the value of an argument with respect to the checksum
-def arg_val(arg)
- if arg.kind_of? Integer
- return arg
- end
-
- if arg.kind_of? String
- return arg.length
- end
-
- if arg.kind_of? Object
- return arg.value
- end
-
- raise "unknown arg type"
-end
-
-# List of parameters/arguments for a method
-class ParamList
- def initialize()
- self.sample_params()
- self.sample_args()
- end
-
- # Sample/generate a random set of parameters for a method
- def sample_params()
- # Choose how many positional arguments to use, and how many are optional
- num_pargs = rand(10)
- @opt_parg_idx = rand(num_pargs)
- @num_opt_pargs = rand(num_pargs + 1 - @opt_parg_idx)
- @num_pargs_req = num_pargs - @num_opt_pargs
- @pargs = (0...num_pargs).map do |i|
- {
- :name => "p#{i}",
- :optional => (i >= @opt_parg_idx && i < @opt_parg_idx + @num_opt_pargs)
- }
- end
-
- # Choose how many kwargs to use, and how many are optional
- num_kwargs = rand(10)
- @kwargs = (0...num_kwargs).map do |i|
- {
- :name => "k#{i}",
- :optional => rand() < 0.5
- }
- end
-
- # Choose whether to have rest parameters or not
- @has_rest = @num_opt_pargs == 0 && rand() < 0.5
- @has_kwrest = rand() < 0.25
-
- # Choose whether to have a named block parameter or not
- @has_block_param = rand() < 0.25
- end
-
- # Sample/generate a random set of arguments corresponding to the parameters
- def sample_args()
- # Choose how many positional args to pass
- num_pargs_passed = rand(@num_pargs_req..@pargs.size)
-
- # How many optional arguments will be filled
- opt_pargs_filled = num_pargs_passed - @num_pargs_req
-
- @pargs.each_with_index do |parg, i|
- if parg[:optional]
- parg[:default] = rand(100)
- end
-
- if !parg[:optional] || i < @opt_parg_idx + opt_pargs_filled
- parg[:argval] = rand(100)
- end
- end
-
- @kwargs.each_with_index do |kwarg, i|
- if kwarg[:optional]
- kwarg[:default] = rand(100)
- end
-
- if !kwarg[:optional] || rand() < 0.5
- kwarg[:argval] = rand(100)
- end
- end
-
- # Randomly pass a block or not
- @block_arg = nil
- if rand() < 0.5
- @block_arg = rand(100)
- end
- end
-
- # Compute the expected checksum of arguments ahead of time
- def compute_checksum()
- checksum = 0
-
- @pargs.each_with_index do |arg, i|
- value = (arg.key? :argval)? arg[:argval]:arg[:default]
- checksum += (i+1) * arg_val(value)
- end
-
- @kwargs.each_with_index do |arg, i|
- value = (arg.key? :argval)? arg[:argval]:arg[:default]
- checksum += (i+1) * arg_val(value)
- end
-
- if @block_arg
- if @has_block_param
- checksum += arg_val(@block_arg)
- end
-
- checksum += arg_val(@block_arg)
- end
-
- checksum
- end
-
- # Generate code for the method signature and method body
- def gen_method_str()
- m_str = "def m("
-
- @pargs.each do |arg|
- if !m_str.end_with?("(")
- m_str += ", "
- end
-
- m_str += arg[:name]
-
- # If this has a default value
- if arg[:optional]
- m_str += " = #{arg[:default]}"
- end
- end
-
- if @has_rest
- if !m_str.end_with?("(")
- m_str += ", "
- end
- m_str += "*rest"
- end
-
- @kwargs.each do |arg|
- if !m_str.end_with?("(")
- m_str += ", "
- end
-
- m_str += "#{arg[:name]}:"
-
- # If this has a default value
- if arg[:optional]
- m_str += " #{arg[:default]}"
- end
- end
-
- if @has_kwrest
- if !m_str.end_with?("(")
- m_str += ", "
- end
- m_str += "**kwrest"
- end
-
- if @has_block_param
- if !m_str.end_with?("(")
- m_str += ", "
- end
-
- m_str += "&block"
- end
-
- m_str += ")\n"
-
- # Add some useless locals
- rand(0...16).times do |i|
- m_str += "local#{i} = #{i}\n"
- end
-
- # Add some useless if statements
- @pargs.each_with_index do |arg, i|
- if rand() < 50
- m_str += "if #{arg[:name]} > 4; end\n"
- end
- end
-
- m_str += "checksum = 0\n"
-
- @pargs.each_with_index do |arg, i|
- m_str += "checksum += #{i+1} * arg_val(#{arg[:name]})\n"
- end
-
- @kwargs.each_with_index do |arg, i|
- m_str += "checksum += #{i+1} * arg_val(#{arg[:name]})\n"
- end
-
- if @has_block_param
- m_str += "if block; r = block.call; checksum += arg_val(r); end\n"
- end
-
- m_str += "if block_given?; r = yield; checksum += arg_val(r); end\n"
-
- if @has_rest
- m_str += "raise 'rest is not array' unless rest.kind_of?(Array)\n"
- m_str += "raise 'rest size not integer' unless rest.size.kind_of?(Integer)\n"
- end
-
- if @has_kwrest
- m_str += "raise 'kwrest is not a hash' unless kwrest.kind_of?(Hash)\n"
- m_str += "raise 'kwrest size not integer' unless kwrest.size.kind_of?(Integer)\n"
- end
-
- m_str += "checksum\n"
- m_str += "end"
-
- m_str
- end
-
- # Generate code to call into the method and pass the arguments
- def gen_call_str()
- c_str = "m("
-
- @pargs.each_with_index do |arg, i|
- if !arg.key? :argval
- next
- end
-
- if !c_str.end_with?("(")
- c_str += ", "
- end
-
- c_str += "#{arg[:argval]}"
- end
-
- @kwargs.each_with_index do |arg, i|
- if !arg.key? :argval
- next
- end
-
- if !c_str.end_with?("(")
- c_str += ", "
- end
-
- c_str += "#{arg[:name]}: #{arg[:argval]}"
- end
-
- c_str += ")"
-
- # Randomly pass a block or not
- if @block_arg
- c_str += " { #{@block_arg} }"
- end
-
- c_str
- end
-end
-
-iseqs_compiled_start = RubyVM::YJIT.runtime_stats[:compiled_iseq_entry]
-start_time = Time.now.to_f
-
-num_iters.times do |i|
- puts "Iteration #{i}"
-
- lst = ParamList.new()
- m_str = lst.gen_method_str()
- c_str = lst.gen_call_str()
- checksum = lst.compute_checksum()
-
- f = Object.new
-
- # Define the method on f
- puts "Defining"
- p m_str
- f.instance_eval(m_str)
- #puts RubyVM::InstructionSequence.disasm(f.method(:m))
- #exit 0
-
- puts "Calling"
- c_str = "f.#{c_str}"
- p c_str
- r = eval(c_str)
- puts "checksum=#{r}"
-
- if r != checksum
- raise "return value #{r} doesn't match checksum #{checksum}"
- end
-
- puts ""
-end
-
-# Make sure that YJIT actually compiled the tests we ran
-# Should be run with --yjit-call-threshold=1
-iseqs_compiled_end = RubyVM::YJIT.runtime_stats[:compiled_iseq_entry]
-if iseqs_compiled_end - iseqs_compiled_start < num_iters
- raise "YJIT did not compile enough ISEQs"
-end
-
-puts "Code region size: #{ format_number(0, RubyVM::YJIT.runtime_stats[:code_region_size]) }"
-
-end_time = Time.now.to_f
-itrs_per_sec = num_iters / (end_time - start_time)
-itrs_per_hour = 3600 * itrs_per_sec
-puts "#{'%.1f' % itrs_per_sec} iterations/s"
-puts "#{format_number(0, itrs_per_hour.round)} iterations/hour"
diff --git a/misc/call_fuzzer.sh b/misc/call_fuzzer.sh
deleted file mode 100755
index cf4ec76fe8..0000000000
--- a/misc/call_fuzzer.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-# Stop at first error
-set -e
-
-# TODO
-# TODO: boost --num-iters to 1M+ for actual test
-# TODO
-export NUM_ITERS=25000
-
-# Enable code GC so we don't stop compiling when we hit the code size limit
-ruby --yjit-call-threshold=1 --yjit-code-gc misc/call_fuzzer.rb --num-iters=$NUM_ITERS
-
-# Do another pass with --verify-ctx
-ruby --yjit-call-threshold=1 --yjit-code-gc --yjit-verify-ctx misc/call_fuzzer.rb --num-iters=$NUM_ITERS
diff --git a/misc/gdb.py b/misc/gdb.py
deleted file mode 100644
index 6034a389bb..0000000000
--- a/misc/gdb.py
+++ /dev/null
@@ -1,181 +0,0 @@
-import argparse
-import textwrap
-
-# usage: [-h] [-a | --all | --no-all] [-s STACK_SIZE] [uplevel]
-#
-# Dump a control frame
-#
-# positional arguments:
-# uplevel CFP offset from the stack top
-#
-# options:
-# -h, --help show this help message and exit
-# -a, --all, --no-all dump all frames
-# -s STACK_SIZE, --stack-size STACK_SIZE
-# override stack_size (useful for JIT frames)
-class CFP(gdb.Command):
- FRAME_MAGICS = [
- # frame types
- 'VM_FRAME_MAGIC_METHOD',
- 'VM_FRAME_MAGIC_BLOCK',
- 'VM_FRAME_MAGIC_CLASS',
- 'VM_FRAME_MAGIC_TOP',
- 'VM_FRAME_MAGIC_CFUNC',
- 'VM_FRAME_MAGIC_IFUNC',
- 'VM_FRAME_MAGIC_EVAL',
- 'VM_FRAME_MAGIC_RESCUE',
- 'VM_FRAME_MAGIC_DUMMY',
- ]
- FRAME_FLAGS = [
- # frame flag
- 'VM_FRAME_FLAG_FINISH',
- 'VM_FRAME_FLAG_BMETHOD',
- 'VM_FRAME_FLAG_CFRAME',
- 'VM_FRAME_FLAG_LAMBDA',
- 'VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM',
- 'VM_FRAME_FLAG_CFRAME_KW',
- 'VM_FRAME_FLAG_PASSED',
- # env flag
- 'VM_ENV_FLAG_LOCAL',
- 'VM_ENV_FLAG_ESCAPED',
- 'VM_ENV_FLAG_WB_REQUIRED',
- 'VM_ENV_FLAG_ISOLATED',
- ]
-
- def __init__(self):
- super(CFP, self).__init__('cfp', gdb.COMMAND_USER)
-
- self.parser = argparse.ArgumentParser(description='Dump a control frame')
- self.parser.add_argument('uplevel', type=int, nargs='?', default=0, help='CFP offset from the stack top')
- self.parser.add_argument('-a', '--all', action=argparse.BooleanOptionalAction, help='dump all frames')
- self.parser.add_argument('-s', '--stack-size', type=int, help='override stack_size (useful for JIT frames)')
-
- def invoke(self, args, from_tty):
- try:
- args = self.parser.parse_args(args.split())
- except SystemExit:
- return
- cfp = f'(ruby_current_ec->cfp + ({args.uplevel}))'
- end_cfp = self.get_int('ruby_current_ec->vm_stack + ruby_current_ec->vm_stack_size')
- cfp_index = int((end_cfp - self.get_int(cfp) - 1) / self.get_int('sizeof(rb_control_frame_t)'))
-
- if args.all:
- cfp_count = int((end_cfp - self.get_int('ruby_current_ec->cfp')) / self.get_int('sizeof(rb_control_frame_t)')) - 1 # exclude dummy CFP
- for i in range(cfp_count):
- print('-' * 80)
- self.invoke(str(cfp_count - i - 1), from_tty)
- return
-
- print('CFP (addr=0x{:x}, index={}):'.format(self.get_int(cfp), cfp_index))
- gdb.execute(f'p *({cfp})')
- print()
-
- if self.get_int(f'{cfp}->iseq'):
- local_size = self.get_int(f'{cfp}->iseq->body->local_table_size - {cfp}->iseq->body->param.size')
- param_size = self.get_int(f'{cfp}->iseq->body->param.size')
-
- if local_size:
- print(f'Params (size={param_size}):')
- for i in range(-3 - local_size - param_size, -3 - local_size):
- self.print_stack(cfp, i, self.rp(cfp, i))
- print()
-
- if param_size:
- print(f'Locals (size={local_size}):')
- for i in range(-3 - local_size, -3):
- self.print_stack(cfp, i, self.rp(cfp, i))
- print()
-
- print('Env:')
- self.print_env(cfp, -3, self.rp_env(cfp, -3))
- self.print_env(cfp, -2, self.specval(cfp, -2))
- self.print_env(cfp, -1, self.frame_types(cfp, -1))
- print()
-
- # We can't calculate BP for the first frame.
- # vm_base_ptr doesn't work for C frames either.
- if cfp_index > 0 and self.get_int(f'{cfp}->iseq'):
- if args.stack_size is not None:
- stack_size = args.stack_size
- else:
- stack_size = int((self.get_int(f'{cfp}->sp') - self.get_int(f'vm_base_ptr({cfp})')) / 8)
- print(f'Stack (size={stack_size}):')
- for i in range(0, stack_size):
- self.print_stack(cfp, i, self.rp(cfp, i))
- print(self.regs(cfp, stack_size))
-
- def print_env(self, cfp, bp_index, content):
- ep_index = bp_index + 1
- address = self.get_int(f'((rb_control_frame_t *){cfp})->ep + {ep_index}')
- value = self.get_env(cfp, bp_index)
- regs = self.regs(cfp, bp_index)
- if content:
- content = textwrap.indent(content, ' ' * 3).lstrip() # Leave the regs column empty
- content = f'{content} '
- print('{:2} 0x{:x} [{}] {}(0x{:x})'.format(regs, address, bp_index, content, value))
-
- def print_stack(self, cfp, bp_index, content):
- address = self.get_int(f'vm_base_ptr({cfp}) + {bp_index}')
- value = self.get_value(cfp, bp_index)
- regs = self.regs(cfp, bp_index)
- if content:
- content = textwrap.indent(content, ' ' * 3).lstrip() # Leave the regs column empty
- content = f'{content} '
- print('{:2} 0x{:x} [{}] {}(0x{:x})'.format(regs, address, bp_index, content, value))
-
- def regs(self, cfp, bp_index):
- address = self.get_int(f'vm_base_ptr({cfp}) + {bp_index}')
- regs = []
- for reg, field in { 'EP': 'ep', 'SP': 'sp' }.items():
- if address == self.get_int(f'{cfp}->{field}'):
- regs.append(reg)
- return ' '.join(regs)
-
- def rp(self, cfp, bp_index):
- value = self.get_value(cfp, bp_index)
- return self.get_string(f'rp {value}').rstrip()
-
- def rp_env(self, cfp, bp_index):
- value = self.get_env(cfp, bp_index)
- return self.get_string(f'rp {value}').rstrip()
-
- # specval: block_handler or previous EP
- def specval(self, cfp, bp_index):
- value = self.get_env(cfp, bp_index)
- if value == 0:
- return 'VM_BLOCK_HANDLER_NONE'
- if value == self.get_int('rb_block_param_proxy'):
- return 'rb_block_param_proxy'
- return ''
-
- def frame_types(self, cfp, bp_index):
- types = []
- value = self.get_env(cfp, bp_index)
-
- magic_mask = self.get_int('VM_FRAME_MAGIC_MASK')
- for magic in self.FRAME_MAGICS:
- magic_value = self.get_int(magic)
- if value & magic_mask == magic_value:
- types.append(magic)
-
- for flag in self.FRAME_FLAGS:
- flag_value = self.get_int(flag)
- if value & flag_value:
- types.append(flag)
-
- return ' | '.join(types)
-
- def get_env(self, cfp, bp_index):
- ep_index = bp_index + 1
- return self.get_int(f'((rb_control_frame_t *){cfp})->ep[{ep_index}]')
-
- def get_value(self, cfp, bp_index):
- return self.get_int(f'vm_base_ptr({cfp})[{bp_index}]')
-
- def get_int(self, expr):
- return int(self.get_string(f'printf "%ld", ({expr})'))
-
- def get_string(self, expr):
- return gdb.execute(expr, to_string=True)
-
-CFP()
diff --git a/misc/lldb_cruby.py b/misc/lldb_cruby.py
index 400ccb45b9..9ef9d3967b 100755
--- a/misc/lldb_cruby.py
+++ b/misc/lldb_cruby.py
@@ -197,16 +197,18 @@ def string2cstr(rstring):
flags = rstring.GetValueForExpressionPath(".basic->flags").unsigned
if flags & RUBY_T_MASK != RUBY_T_STRING:
raise TypeError("not a string")
- clen = int(rstring.GetValueForExpressionPath(".len").value, 0)
if flags & RUBY_FL_USER1:
cptr = int(rstring.GetValueForExpressionPath(".as.heap.ptr").value, 0)
+ clen = int(rstring.GetValueForExpressionPath(".as.heap.len").value, 0)
else:
cptr = int(rstring.GetValueForExpressionPath(".as.embed.ary").location, 0)
+ clen = int(rstring.GetValueForExpressionPath(".as.embed.len").value, 0)
return cptr, clen
def output_string(debugger, result, rstring):
cptr, clen = string2cstr(rstring)
- append_expression(debugger, "*(const char (*)[%d])%0#x" % (clen, cptr), result)
+ expr = "print *(const char (*)[%d])%0#x" % (clen, cptr)
+ append_command_output(debugger, expr, result)
def fixnum_p(x):
return x & RUBY_FIXNUM_FLAG != 0
@@ -225,9 +227,6 @@ def append_command_output(debugger, command, result):
result.write(output1)
result.write(output2)
-def append_expression(debugger, expression, result):
- append_command_output(debugger, "expression " + expression, result)
-
def lldb_rp(debugger, command, result, internal_dict):
if not ('RUBY_Qfalse' in globals()):
lldb_init(debugger)
@@ -259,13 +258,13 @@ def lldb_inspect(debugger, target, result, val):
elif fixnum_p(num):
print(num >> 1, file=result)
elif flonum_p(num):
- append_expression(debugger, "rb_float_value(%0#x)" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "print rb_float_value(%0#x)" % val.GetValueAsUnsigned(), result)
elif static_sym_p(num):
if num < 128:
print("T_SYMBOL: %c" % num, file=result)
else:
print("T_SYMBOL: (%x)" % num, file=result)
- append_expression(debugger, "rb_id2name(%0#x)" % (num >> 8), result)
+ append_command_output(debugger, "p rb_id2name(%0#x)" % (num >> 8), result)
elif num & RUBY_IMMEDIATE_MASK:
print('immediate(%x)' % num, file=result)
else:
@@ -293,13 +292,13 @@ def lldb_inspect(debugger, target, result, val):
print('T_NIL: %s%s' % (flaginfo, val.Dereference()), file=result)
elif flType == RUBY_T_OBJECT:
result.write('T_OBJECT: %s' % flaginfo)
- append_expression(debugger, "*(struct RObject*)%0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "print *(struct RObject*)%0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_CLASS or flType == RUBY_T_MODULE or flType == RUBY_T_ICLASS:
result.write('T_%s: %s' % ('CLASS' if flType == RUBY_T_CLASS else 'MODULE' if flType == RUBY_T_MODULE else 'ICLASS', flaginfo))
- append_expression(debugger, "*(struct RClass*)%0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "print *(struct RClass*)%0#x" % val.GetValueAsUnsigned(), result)
tRClass = target.FindFirstType("struct RClass")
if not val.Cast(tRClass).GetChildMemberWithName("ptr").IsValid():
- append_expression(debugger, "*(struct rb_classext_struct*)%0#x" % (val.GetValueAsUnsigned() + tRClass.GetByteSize()), result)
+ append_command_output(debugger, "print *(struct rb_classext_struct*)%0#x" % (val.GetValueAsUnsigned() + tRClass.GetByteSize()), result)
elif flType == RUBY_T_STRING:
result.write('T_STRING: %s' % flaginfo)
encidx = ((flags & RUBY_ENCODING_MASK)>>RUBY_ENCODING_SHIFT)
@@ -313,12 +312,12 @@ def lldb_inspect(debugger, target, result, val):
if len == 0:
result.write("(empty)\n")
else:
- append_expression(debugger, "*(const char (*)[%d])%0#x" % (len, ptr), result)
+ append_command_output(debugger, "print *(const char (*)[%d])%0#x" % (len, ptr), result)
elif flType == RUBY_T_SYMBOL:
result.write('T_SYMBOL: %s' % flaginfo)
tRSymbol = target.FindFirstType("struct RSymbol").GetPointerType()
val = val.Cast(tRSymbol)
- append_expression(debugger, '(ID)%0#x ' % val.GetValueForExpressionPath("->id").GetValueAsUnsigned(), result)
+ append_command_output(debugger, 'print (ID)%0#x ' % val.GetValueForExpressionPath("->id").GetValueAsUnsigned(), result)
tRString = target.FindFirstType("struct RString").GetPointerType()
output_string(debugger, result, val.GetValueForExpressionPath("->fstr").Cast(tRString))
elif flType == RUBY_T_ARRAY:
@@ -344,12 +343,12 @@ def lldb_inspect(debugger, target, result, val):
else:
result.write("\n")
if ptr.GetValueAsSigned() == 0:
- append_expression(debugger, "-fx -- ((struct RArray*)%0#x)->as.ary" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "expression -fx -- ((struct RArray*)%0#x)->as.ary" % val.GetValueAsUnsigned(), result)
else:
- append_expression(debugger, "-Z %d -fx -- (const VALUE*)%0#x" % (len, ptr.GetValueAsUnsigned()), result)
+ append_command_output(debugger, "expression -Z %d -fx -- (const VALUE*)%0#x" % (len, ptr.GetValueAsUnsigned()), result)
elif flType == RUBY_T_HASH:
result.write("T_HASH: %s" % flaginfo)
- append_expression(debugger, "*(struct RHash *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RHash *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_BIGNUM:
tRBignum = target.FindFirstType("struct RBignum").GetPointerType()
val = val.Cast(tRBignum)
@@ -357,15 +356,15 @@ def lldb_inspect(debugger, target, result, val):
if flags & RUBY_FL_USER2:
len = ((flags & (RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5)) >> (RUBY_FL_USHIFT+3))
print("T_BIGNUM: sign=%s len=%d (embed)" % (sign, len), file=result)
- append_expression(debugger, "((struct RBignum *) %0#x)->as.ary" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "print ((struct RBignum *) %0#x)->as.ary" % val.GetValueAsUnsigned(), result)
else:
len = val.GetValueForExpressionPath("->as.heap.len").GetValueAsSigned()
print("T_BIGNUM: sign=%s len=%d" % (sign, len), file=result)
print(val.Dereference(), file=result)
- append_expression(debugger, "-Z %x -fx -- (const BDIGIT*)((struct RBignum*)%d)->as.heap.digits" % (len, val.GetValueAsUnsigned()), result)
- # append_expression(debugger, "((struct RBignum *) %0#x)->as.heap.digits / %d" % (val.GetValueAsUnsigned(), len), result)
+ append_command_output(debugger, "expression -Z %x -fx -- (const BDIGIT*)((struct RBignum*)%d)->as.heap.digits" % (len, val.GetValueAsUnsigned()), result)
+ # append_command_output(debugger, "x ((struct RBignum *) %0#x)->as.heap.digits / %d" % (val.GetValueAsUnsigned(), len), result)
elif flType == RUBY_T_FLOAT:
- append_expression(debugger, "((struct RFloat *)%d)->float_value" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "print ((struct RFloat *)%d)->float_value" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_RATIONAL:
tRRational = target.FindFirstType("struct RRational").GetPointerType()
val = val.Cast(tRRational)
@@ -398,39 +397,39 @@ def lldb_inspect(debugger, target, result, val):
flag = val.GetValueForExpressionPath("->typed_flag")
if flag.GetValueAsUnsigned() == 1:
print("T_DATA: %s" % val.GetValueForExpressionPath("->type->wrap_struct_name"), file=result)
- append_expression(debugger, "*(struct RTypedData *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RTypedData *) %0#x" % val.GetValueAsUnsigned(), result)
else:
print("T_DATA:", file=result)
- append_expression(debugger, "*(struct RData *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RData *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_NODE:
tRTypedData = target.FindFirstType("struct RNode").GetPointerType()
nd_type = (flags & RUBY_NODE_TYPEMASK) >> RUBY_NODE_TYPESHIFT
- append_expression(debugger, "(node_type) %d" % nd_type, result)
+ append_command_output(debugger, "p (node_type) %d" % nd_type, result)
val = val.Cast(tRTypedData)
- append_expression(debugger, "*(struct RNode *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RNode *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_MOVED:
tRTypedData = target.FindFirstType("struct RMoved").GetPointerType()
val = val.Cast(tRTypedData)
- append_expression(debugger, "*(struct RMoved *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RMoved *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_MATCH:
tRTypedData = target.FindFirstType("struct RMatch").GetPointerType()
val = val.Cast(tRTypedData)
- append_expression(debugger, "*(struct RMatch *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RMatch *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_IMEMO:
# I'm not sure how to get IMEMO_MASK out of lldb. It's not in globals()
imemo_type = (flags >> RUBY_FL_USHIFT) & 0x0F # IMEMO_MASK
print("T_IMEMO: ", file=result)
- append_expression(debugger, "(enum imemo_type) %d" % imemo_type, result)
- append_expression(debugger, "*(struct MEMO *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p (enum imemo_type) %d" % imemo_type, result)
+ append_command_output(debugger, "p *(struct MEMO *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_STRUCT:
tRTypedData = target.FindFirstType("struct RStruct").GetPointerType()
val = val.Cast(tRTypedData)
- append_expression(debugger, "*(struct RStruct *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RStruct *) %0#x" % val.GetValueAsUnsigned(), result)
elif flType == RUBY_T_ZOMBIE:
tRZombie = target.FindFirstType("struct RZombie").GetPointerType()
val = val.Cast(tRZombie)
- append_expression(debugger, "*(struct RZombie *) %0#x" % val.GetValueAsUnsigned(), result)
+ append_command_output(debugger, "p *(struct RZombie *) %0#x" % val.GetValueAsUnsigned(), result)
else:
print("Not-handled type %0#x" % flType, file=result)
print(val, file=result)
@@ -728,13 +727,13 @@ def __lldb_init_module(debugger, internal_dict):
# Register all classes that subclass RbBaseCommand
for memname, mem in inspect.getmembers(sys.modules["lldb_rb.rb_base_command"]):
- if memname == "RbBaseCommand":
+ if inspect.isclass(mem):
for sclass in mem.__subclasses__():
sclass.register_lldb_command(debugger, f"{__name__}.{sclass.__module__}")
## FUNCTION INITS - These should be removed when converted to class commands
- debugger.HandleCommand("command script add -f lldb_cruby.lldb_rp old_rp")
+ debugger.HandleCommand("command script add -f lldb_cruby.lldb_rp rp")
debugger.HandleCommand("command script add -f lldb_cruby.count_objects rb_count_objects")
debugger.HandleCommand("command script add -f lldb_cruby.stack_dump_raw SDR")
debugger.HandleCommand("command script add -f lldb_cruby.dump_node dump_node")
@@ -742,7 +741,7 @@ def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command script add -f lldb_cruby.rb_backtrace rbbt")
debugger.HandleCommand("command script add -f lldb_cruby.dump_page dump_page")
debugger.HandleCommand("command script add -f lldb_cruby.dump_page_rvalue dump_page_rvalue")
- debugger.HandleCommand("command script add -f lldb_cruby.rb_id2str old_rb_id2str")
+ debugger.HandleCommand("command script add -f lldb_cruby.rb_id2str rb_id2str")
lldb_rb.rb_base_command.RbBaseCommand.lldb_init(debugger)
diff --git a/misc/lldb_rb/commands/heap_page_command.py b/misc/lldb_rb/commands/heap_page_command.py
index b56a3eae4e..edb74a415b 100644
--- a/misc/lldb_rb/commands/heap_page_command.py
+++ b/misc/lldb_rb/commands/heap_page_command.py
@@ -14,8 +14,8 @@ class HeapPageCommand(RbBaseCommand):
page = self._get_page(self.frame.EvaluateExpression(command))
page.Cast(self.t_heap_page_ptr)
- self._append_expression(debugger, "(struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result)
- self._append_expression(debugger, "*(struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result)
+ self._append_command_output(debugger, "p (struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result)
+ self._append_command_output(debugger, "p *(struct heap_page *) %0#x" % page.GetValueAsUnsigned(), result)
def _get_page(self, val):
addr = val.GetValueAsUnsigned()
diff --git a/misc/lldb_rb/commands/print_flags_command.py b/misc/lldb_rb/commands/print_flags_command.py
deleted file mode 100644
index 00da4834bf..0000000000
--- a/misc/lldb_rb/commands/print_flags_command.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import lldb
-import re
-
-from lldb_rb.constants import *
-from lldb_rb.rb_base_command import RbBaseCommand
-
-class PrintFlagsCommand(RbBaseCommand):
- program = "print_flags"
-
- help_string = "Print out the individial flags of an RVALUE object in human readable format"
-
- # call is where our command logic will be implemented
- def call(self, debugger, command, exe_ctx, result):
- rclass_t = self.target.FindFirstType("struct RBasic")
- rcass_ptr = self.target.EvaluateExpression(command).Cast(rclass_t.GetPointerType())
- obj_flags = rcass_ptr.GetValueForExpressionPath("->flags").GetValueAsUnsigned()
-
- flags = [
- "RUBY_FL_WB_PROTECTED", "RUBY_FL_PROMOTED0", "RUBY_FL_PROMOTED1", "RUBY_FL_FINALIZE",
- "RUBY_FL_SHAREABLE", "RUBY_FL_EXIVAR", "RUBY_FL_FREEZE",
- "RUBY_FL_USER0", "RUBY_FL_USER1", "RUBY_FL_USER2", "RUBY_FL_USER3", "RUBY_FL_USER4",
- "RUBY_FL_USER5", "RUBY_FL_USER6", "RUBY_FL_USER7", "RUBY_FL_USER8", "RUBY_FL_USER9",
- "RUBY_FL_USER10", "RUBY_FL_USER11", "RUBY_FL_USER12", "RUBY_FL_USER13", "RUBY_FL_USER14",
- "RUBY_FL_USER15", "RUBY_FL_USER16", "RUBY_FL_USER17", "RUBY_FL_USER18"
- ]
-
- types_index = {v: k for k, v in self.ruby_globals.items() if re.match(r'RUBY_T_', k)}
- print("TYPE: {}".format(types_index[obj_flags & self.ruby_globals["RUBY_T_MASK"]]))
- for flag in flags:
- output = "{} : {}".format(flag, "1" if (obj_flags & self.ruby_globals[flag]) else "0")
- print(output, file=result)
diff --git a/misc/lldb_rb/commands/rb_id2str_command.py b/misc/lldb_rb/commands/rb_id2str_command.py
deleted file mode 100644
index 6ee859ebf6..0000000000
--- a/misc/lldb_rb/commands/rb_id2str_command.py
+++ /dev/null
@@ -1,49 +0,0 @@
-import lldb
-
-from lldb_rb.constants import *
-from lldb_rb.utils import *
-from lldb_rb.rb_base_command import RbBaseCommand
-
-class RbID2StrCommand(RbBaseCommand):
- program = "rb_id2str"
-
- help_string = "convert and print a Ruby ID to a C string and print it to the LLDB console"
-
- def call(self, debugger, command, exe_ctx, result):
- global_symbols = self.target.FindFirstGlobalVariable("ruby_global_symbols")
-
- id_val = self.frame.EvaluateExpression(command).GetValueAsUnsigned()
- num = self.rb_id_to_serial(id_val)
-
- last_id = global_symbols.GetChildMemberWithName("last_id").GetValueAsUnsigned()
- ID_ENTRY_SIZE = 2
- ID_ENTRY_UNIT = int(self.target.FindFirstGlobalVariable("ID_ENTRY_UNIT").GetValue())
-
- ids = global_symbols.GetChildMemberWithName("ids")
-
- if num <= last_id:
- idx = num // ID_ENTRY_UNIT
- ary = self.rb_ary_entry(ids, idx, result)
- pos = (num % ID_ENTRY_UNIT) * ID_ENTRY_SIZE
- id_str = self.rb_ary_entry(ary, pos, result)
-
- RbInspector(debugger, result, self.ruby_globals).inspect(id_str)
-
- def rb_id_to_serial(self, id_val):
- if id_val > self.ruby_globals["tLAST_OP_ID"]:
- return id_val >> self.ruby_globals["RUBY_ID_SCOPE_SHIFT"]
- else:
- return id_val
-
- def rb_ary_entry(self, ary, idx, result):
- tRArray = self.target.FindFirstType("struct RArray").GetPointerType()
- ary = ary.Cast(tRArray)
- flags = ary.GetValueForExpressionPath("->flags").GetValueAsUnsigned()
-
- if flags & self.ruby_globals["RUBY_FL_USER1"]:
- ptr = ary.GetValueForExpressionPath("->as.ary")
- else:
- ptr = ary.GetValueForExpressionPath("->as.heap.ptr")
-
- ptr_addr = ptr.GetValueAsUnsigned() + (idx * ptr.GetType().GetByteSize())
- return self.target.CreateValueFromAddress("ary_entry[%d]" % idx, lldb.SBAddress(ptr_addr, self.target), ptr.GetType().GetPointeeType())
diff --git a/misc/lldb_rb/commands/rp_command.py b/misc/lldb_rb/commands/rp_command.py
deleted file mode 100644
index 06b2516d50..0000000000
--- a/misc/lldb_rb/commands/rp_command.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import lldb
-
-from lldb_rb.constants import *
-from lldb_rb.utils import *
-from lldb_rb.rb_base_command import RbBaseCommand
-
-class RbID2StrCommand(RbBaseCommand):
- program = "rp"
-
- help_string = "convert and print a Ruby ID to a C string and print it to the LLDB console"
-
- def call(self, debugger, command, exe_ctx, result):
- val = self.frame.EvaluateExpression(command)
- inspector = RbInspector(debugger, result, self.ruby_globals)
- inspector.inspect(val)
diff --git a/misc/lldb_rb/constants.py b/misc/lldb_rb/constants.py
index 9cd56eccb0..ec3050a399 100644
--- a/misc/lldb_rb/constants.py
+++ b/misc/lldb_rb/constants.py
@@ -2,5 +2,3 @@ HEAP_PAGE_ALIGN_LOG = 16
HEAP_PAGE_ALIGN_MASK = (~(~0 << HEAP_PAGE_ALIGN_LOG))
HEAP_PAGE_ALIGN = (1 << HEAP_PAGE_ALIGN_LOG)
HEAP_PAGE_SIZE = HEAP_PAGE_ALIGN
-
-IMEMO_MASK = 0x0F
diff --git a/misc/lldb_rb/lldb_interface.py b/misc/lldb_rb/lldb_interface.py
deleted file mode 100644
index 785a54b3e3..0000000000
--- a/misc/lldb_rb/lldb_interface.py
+++ /dev/null
@@ -1,7 +0,0 @@
-class LLDBInterface:
- def build_environment(self, debugger):
- self.debugger = debugger
- self.target = debugger.GetSelectedTarget()
- self.process = self.target.GetProcess()
- self.thread = self.process.GetSelectedThread()
- self.frame = self.thread.GetSelectedFrame()
diff --git a/misc/lldb_rb/rb_base_command.py b/misc/lldb_rb/rb_base_command.py
index 70a5addd6d..de90a1617c 100644
--- a/misc/lldb_rb/rb_base_command.py
+++ b/misc/lldb_rb/rb_base_command.py
@@ -1,9 +1,7 @@
import lldb
from pydoc import locate
-from lldb_rb.constants import *
-from lldb_rb.utils import *
-class RbBaseCommand(LLDBInterface):
+class RbBaseCommand:
@classmethod
def register_lldb_command(cls, debugger, module_name):
# Add any commands contained in this module to LLDB
@@ -36,14 +34,14 @@ class RbBaseCommand(LLDBInterface):
if name.startswith("RUBY_T_"):
value_types.append(name)
g["value_types"] = value_types
- return g
def __init__(self, debugger, _internal_dict):
- self.ruby_globals = RbBaseCommand.lldb_init(debugger)
self.internal_dict = _internal_dict
def __call__(self, debugger, command, exe_ctx, result):
- self.ruby_globals = RbBaseCommand.lldb_init(debugger)
+ if not ("RUBY_Qfalse" in globals()):
+ RbBaseCommand.lldb_init(debugger)
+
self.build_environment(debugger)
self.call(debugger, command, exe_ctx, result)
@@ -55,3 +53,17 @@ class RbBaseCommand(LLDBInterface):
def get_long_help(self):
return self.__class__.help_string
+
+ def build_environment(self, debugger):
+ self.target = debugger.GetSelectedTarget()
+ self.process = self.target.GetProcess()
+ self.thread = self.process.GetSelectedThread()
+ self.frame = self.thread.GetSelectedFrame()
+
+ def _append_command_output(self, debugger, command, result):
+ output1 = result.GetOutput()
+ debugger.GetCommandInterpreter().HandleCommand(command, result)
+ output2 = result.GetOutput()
+ result.Clear()
+ result.write(output1)
+ result.write(output2)
diff --git a/misc/lldb_rb/rb_heap_structs.py b/misc/lldb_rb/rb_heap_structs.py
deleted file mode 100644
index 86b38dbbbd..0000000000
--- a/misc/lldb_rb/rb_heap_structs.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import lldb
-from lldb_rb.lldb_interface import LLDBInterface
-from lldb_rb.constants import *
-
-class HeapPage(LLDBInterface):
- def __init__(self, debugger, val):
- self.build_environment(debugger)
- self.page_type = self.target.FindFirstType("struct heap_page").GetPointerType()
- self.val = val
-
- def heap_page_body(self, command, ctx, result, internal_dict):
- process = self.target.GetProcess()
- thread = process.GetSelectedThread()
- frame = thread.GetSelectedFrame()
-
- val = frame.EvaluateExpression(command)
- page = self.get_page_body(val)
- print("Page body address: ", page.GetAddress(), file=result)
- print(page, file=result)
-
- def get_page_body(self, val):
- tHeapPageBody = self.target.FindFirstType("struct heap_page_body")
- addr = val.GetValueAsUnsigned()
- page_addr = addr & ~(HEAP_PAGE_ALIGN_MASK)
- address = lldb.SBAddress(page_addr, self.target)
- return self.target.CreateValueFromAddress("page", address, tHeapPageBody)
-
- def get_page_raw(self, val):
- body = self.get_page_body(val)
- return body.GetValueForExpressionPath("->header.page")
-
- def to_heap_page_struct(self):
- pagePtr = self.get_page_raw(self.val)
- return pagePtr.Cast(self.page_type)
-
-
-class RbObject(LLDBInterface):
- def __init__(self, ptr, debugger, ruby_globals):
- self.build_environment(debugger)
- self.ruby_globals = ruby_globals
-
- self.flUser1 = self.ruby_globals["RUBY_FL_USER1"]
- self.flUser2 = self.ruby_globals["RUBY_FL_USER2"]
- self.flUser3 = self.ruby_globals["RUBY_FL_USER3"]
- self.flUser4 = self.ruby_globals["RUBY_FL_USER4"]
- self.flUser5 = self.ruby_globals["RUBY_FL_USER5"]
- self.flUser6 = self.ruby_globals["RUBY_FL_USER6"]
- self.flUser7 = self.ruby_globals["RUBY_FL_USER7"]
- self.flUser8 = self.ruby_globals["RUBY_FL_USER8"]
- self.flUser9 = self.ruby_globals["RUBY_FL_USER9"]
- self.flUshift = self.ruby_globals["RUBY_FL_USHIFT"]
-
- self.tRBasic = self.target.FindFirstType("struct RBasic").GetPointerType()
- self.tRValue = self.target.FindFirstType("struct RVALUE")
-
- self.val = ptr.Cast(self.tRBasic)
- self.page = HeapPage(self.debugger, self.val)
- self.flags = self.val.GetValueForExpressionPath("->flags").GetValueAsUnsigned()
-
- self.type = None
- self.type_name = ""
-
- def check_bits(self, bitmap_name, bitmap_index, bitmap_bit, v):
- page = self.page.to_heap_page_struct()
- bits = page.GetChildMemberWithName(bitmap_name)
- plane = bits.GetChildAtIndex(bitmap_index).GetValueAsUnsigned()
- if (plane & bitmap_bit) != 0:
- return v
- else:
- return ' '
-
- def dump_bits(self, result, end = "\n"):
- tRValue = self.target.FindFirstType("struct RVALUE")
- tUintPtr = self.target.FindFirstType("uintptr_t") # bits_t
-
- num_in_page = (self.val.GetValueAsUnsigned() & HEAP_PAGE_ALIGN_MASK) // tRValue.GetByteSize();
- bits_bitlength = tUintPtr.GetByteSize() * 8
- bitmap_index = num_in_page // bits_bitlength
- bitmap_offset = num_in_page & (bits_bitlength - 1)
- bitmap_bit = 1 << bitmap_offset
-
- page = self.page.to_heap_page_struct()
- print("bits: [%s%s%s%s%s]" % (
- self.check_bits("uncollectible_bits", bitmap_index, bitmap_bit, "L"),
- self.check_bits("mark_bits", bitmap_index, bitmap_bit, "M"),
- self.check_bits("pinned_bits", bitmap_index, bitmap_bit, "P"),
- self.check_bits("marking_bits", bitmap_index, bitmap_bit, "R"),
- self.check_bits("wb_unprotected_bits", bitmap_index, bitmap_bit, "U"),
- ), end=end, file=result)
-
- def promoted_p(self):
- rbFlPromoted = self.ruby_globals["RUBY_FL_PROMOTED"]
- return (self.flags & rbFlPromoted) == rbFlPromoted
-
- def frozen_p(self):
- rbFlFreeze = self.ruby_globals["RUBY_FL_FREEZE"]
- return (self.flags & rbFlFreeze) == rbFlFreeze
-
- def is_type(self, type_name):
- if self.type is None:
- flTMask = self.ruby_globals["RUBY_T_MASK"]
- flType = self.flags & flTMask
- self.type = flType
-
- if self.type == self.ruby_globals[type_name]:
- self.type_name = type_name
- return True
- else:
- return False
-
- def as_type(self, type_name):
- return self.val.Cast(self.tRValue.GetPointerType()).GetValueForExpressionPath("->as."+type_name)
-
- def ary_ptr(self):
- rval = self.as_type("array")
- if self.flags & self.ruby_globals["RUBY_FL_USER1"]:
- ptr = rval.GetValueForExpressionPath("->as.ary")
- else:
- ptr = rval.GetValueForExpressionPath("->as.heap.ptr")
- return ptr
-
- def ary_len(self):
- if self.flags & self.flUser1:
- len = ((self.flags &
- (self.flUser3 | self.flUser4 | self.flUser5 | self.flUser6 |
- self.flUser7 | self.flUser8 | self.flUser9)
- ) >> (self.flUshift + 3))
- else:
- rval = self.as_type("array")
- len = rval.GetValueForExpressionPath("->as.heap.len").GetValueAsSigned()
-
- return len
-
- def bignum_len(self):
- if self.flags & self.flUser2:
- len = ((self.flags &
- (self.flUser3 | self.flUser4 | self.flUser5)
- ) >> (self.flUshift + 3))
- else:
- len = (self.as_type("bignum").GetValueForExpressionPath("->as.heap.len").
- GetValueAsUnsigned())
-
- return len
diff --git a/misc/lldb_rb/utils.py b/misc/lldb_rb/utils.py
deleted file mode 100644
index e18e468ca5..0000000000
--- a/misc/lldb_rb/utils.py
+++ /dev/null
@@ -1,490 +0,0 @@
-from lldb_rb.lldb_interface import LLDBInterface
-from lldb_rb.rb_heap_structs import HeapPage, RbObject
-from lldb_rb.constants import *
-
-class RbInspector(LLDBInterface):
- def __init__(self, debugger, result, ruby_globals):
- self.build_environment(debugger)
- self.result = result
- self.ruby_globals = ruby_globals
-
- def _append_command_output(self, command):
- output1 = self.result.GetOutput()
- self.debugger.GetCommandInterpreter().HandleCommand(command, self.result)
- output2 = self.result.GetOutput()
- self.result.Clear()
- self.result.write(output1)
- self.result.write(output2)
-
- def _append_expression(self, expression):
- self._append_command_output("expression " + expression)
-
- def string2cstr(self, rstring):
- """Returns the pointer to the C-string in the given String object"""
- if rstring.TypeIsPointerType():
- rstring = rstring.Dereference()
-
- flags = rstring.GetValueForExpressionPath(".basic->flags").unsigned
- clen = int(rstring.GetValueForExpressionPath(".len").value, 0)
- if flags & self.ruby_globals["RUBY_FL_USER1"]:
- cptr = int(rstring.GetValueForExpressionPath(".as.heap.ptr").value, 0)
- else:
- cptr = int(rstring.GetValueForExpressionPath(".as.embed.ary").location, 0)
-
- return cptr, clen
-
- def output_string(self, rstring):
- cptr, clen = self.string2cstr(rstring)
- self._append_expression("*(const char (*)[%d])%0#x" % (clen, cptr))
-
- def fixnum_p(self, x):
- return x & self.ruby_globals["RUBY_FIXNUM_FLAG"] != 0
-
- def flonum_p(self, x):
- return (x & self.ruby_globals["RUBY_FLONUM_MASK"]) == self.ruby_globals["RUBY_FLONUM_FLAG"]
-
- def static_sym_p(self, x):
- special_shift = self.ruby_globals["RUBY_SPECIAL_SHIFT"]
- symbol_flag = self.ruby_globals["RUBY_SYMBOL_FLAG"]
- return (x & ~(~0 << special_shift)) == symbol_flag
-
- def generic_inspect(self, val, rtype):
- tRType = self.target.FindFirstType("struct %s" % rtype).GetPointerType()
- val = val.Cast(tRType)
- self._append_expression("*(struct %s *) %0#x" % (rtype, val.GetValueAsUnsigned()))
-
- def inspect(self, val):
- rbTrue = self.ruby_globals["RUBY_Qtrue"]
- rbFalse = self.ruby_globals["RUBY_Qfalse"]
- rbNil = self.ruby_globals["RUBY_Qnil"]
- rbUndef = self.ruby_globals["RUBY_Qundef"]
- rbImmediateMask = self.ruby_globals["RUBY_IMMEDIATE_MASK"]
-
- num = val.GetValueAsSigned()
- if num == rbFalse:
- print('false', file=self.result)
- elif num == rbTrue:
- print('true', file=self.result)
- elif num == rbNil:
- print('nil', file=self.result)
- elif num == rbUndef:
- print('undef', file=self.result)
- elif self.fixnum_p(num):
- print(num >> 1, file=self.result)
- elif self.flonum_p(num):
- self._append_expression("rb_float_value(%0#x)" % val.GetValueAsUnsigned())
- elif self.static_sym_p(num):
- if num < 128:
- print("T_SYMBOL: %c" % num, file=self.result)
- else:
- print("T_SYMBOL: (%x)" % num, file=self.result)
- self._append_expression("rb_id2name(%0#x)" % (num >> 8))
-
- elif num & rbImmediateMask:
- print('immediate(%x)' % num, file=self.result)
- else:
- rval = RbObject(val, self.debugger, self.ruby_globals)
- rval.dump_bits(self.result)
-
- flaginfo = ""
- if rval.promoted_p():
- flaginfo += "[PROMOTED] "
- if rval.frozen_p():
- flaginfo += "[FROZEN] "
-
- if rval.is_type("RUBY_T_NONE"):
- print('T_NONE: %s%s' % (flaginfo, val.Dereference()), file=self.result)
-
- elif rval.is_type("RUBY_T_NIL"):
- print('T_NIL: %s%s' % (flaginfo, val.Dereference()), file=self.result)
-
- elif rval.is_type("RUBY_T_OBJECT"):
- self.result.write('T_OBJECT: %s' % flaginfo)
- self._append_expression("*(struct RObject*)%0#x" % val.GetValueAsUnsigned())
-
- elif (rval.is_type("RUBY_T_CLASS") or
- rval.is_type("RUBY_T_MODULE") or
- rval.is_type("RUBY_T_ICLASS")):
- self.result.write('T_%s: %s' % (rval.type_name.split('_')[-1], flaginfo))
- tRClass = self.target.FindFirstType("struct RClass")
-
- self._append_expression("*(struct RClass*)%0#x" % val.GetValueAsUnsigned())
- if not val.Cast(tRClass).GetChildMemberWithName("ptr").IsValid():
- self._append_expression(
- "*(struct rb_classext_struct*)%0#x" %
- (val.GetValueAsUnsigned() + tRClass.GetByteSize())
- )
-
- elif rval.is_type("RUBY_T_STRING"):
- self.result.write('T_STRING: %s' % flaginfo)
- tRString = self.target.FindFirstType("struct RString").GetPointerType()
-
- rb_enc_mask = self.ruby_globals["RUBY_ENCODING_MASK"]
- rb_enc_shift = self.ruby_globals["RUBY_ENCODING_SHIFT"]
- encidx = ((rval.flags & rb_enc_mask) >> rb_enc_shift)
- encname = self.target.FindFirstType("enum ruby_preserved_encindex") \
- .GetEnumMembers().GetTypeEnumMemberAtIndex(encidx) \
- .GetName()
-
- if encname is not None:
- self.result.write('[%s] ' % encname[14:])
- else:
- self.result.write('[enc=%d] ' % encidx)
-
- ptr, len = self.string2cstr(val.Cast(tRString))
- if len == 0:
- self.result.write("(empty)\n")
- else:
- self._append_expression("*(const char (*)[%d])%0#x" % (len, ptr))
-
- elif rval.is_type("RUBY_T_SYMBOL"):
- self.result.write('T_SYMBOL: %s' % flaginfo)
- tRSymbol = self.target.FindFirstType("struct RSymbol").GetPointerType()
- tRString = self.target.FindFirstType("struct RString").GetPointerType()
-
- val = val.Cast(tRSymbol)
- self._append_expression('(ID)%0#x ' % val.GetValueForExpressionPath("->id").GetValueAsUnsigned())
- self.output_string(val.GetValueForExpressionPath("->fstr").Cast(tRString))
-
- elif rval.is_type("RUBY_T_ARRAY"):
- len = rval.ary_len()
- ptr = rval.ary_ptr()
-
- self.result.write("T_ARRAY: %slen=%d" % (flaginfo, len))
-
- if rval.flags & self.ruby_globals["RUBY_FL_USER1"]:
- self.result.write(" (embed)")
- elif rval.flags & self.ruby_globals["RUBY_FL_USER2"]:
- shared = val.GetValueForExpressionPath("->as.heap.aux.shared").GetValueAsUnsigned()
- self.result.write(" (shared) shared=%016x" % shared)
- else:
- capa = val.GetValueForExpressionPath("->as.heap.aux.capa").GetValueAsSigned()
- self.result.write(" (ownership) capa=%d" % capa)
- if len == 0:
- self.result.write(" {(empty)}\n")
- else:
- self.result.write("\n")
- if ptr.GetValueAsSigned() == 0:
- self._append_expression("-fx -- ((struct RArray*)%0#x)->as.ary" % val.GetValueAsUnsigned())
- else:
- self._append_expression("-Z %d -fx -- (const VALUE*)%0#x" % (len, ptr.GetValueAsUnsigned()))
-
- elif rval.is_type("RUBY_T_HASH"):
- self.result.write("T_HASH: %s" % flaginfo)
- ptr = val.GetValueAsUnsigned()
- self._append_expression("*(struct RHash *) %0#x" % ptr)
- if rval.flags & self.ruby_globals["RUBY_FL_USER3"]:
- self._append_expression("*(struct st_table *) (%0#x + sizeof(struct RHash))" % ptr)
- else:
- self._append_expression("*(struct ar_table *) (%0#x + sizeof(struct RHash))" % ptr)
-
- elif rval.is_type("RUBY_T_BIGNUM"):
- sign = '-'
- if (rval.flags & self.ruby_globals["RUBY_FL_USER1"]) != 0:
- sign = '+'
- len = rval.bignum_len()
-
- if rval.flags & self.ruby_globals["RUBY_FL_USER2"]:
- print("T_BIGNUM: sign=%s len=%d (embed)" % (sign, len), file=self.result)
- self._append_expression("((struct RBignum *) %0#x)->as.ary"
- % val.GetValueAsUnsigned())
- else:
- print("T_BIGNUM: sign=%s len=%d" % (sign, len), file=self.result)
- print(rval.as_type("bignum"), file=self.result)
- self._append_expression("-Z %d -fx -- ((struct RBignum*)%d)->as.heap.digits" %
- (len, val.GetValueAsUnsigned()))
-
- elif rval.is_type("RUBY_T_FLOAT"):
- self._append_expression("((struct RFloat *)%d)->float_value"
- % val.GetValueAsUnsigned())
-
- elif rval.is_type("RUBY_T_RATIONAL"):
- tRRational = self.target.FindFirstType("struct RRational").GetPointerType()
- val = val.Cast(tRRational)
- self.inspect(val.GetValueForExpressionPath("->num"))
- output = self.result.GetOutput()
- self.result.Clear()
- self.result.write("(Rational) " + output.rstrip() + " / ")
- self.inspect(val.GetValueForExpressionPath("->den"))
-
- elif rval.is_type("RUBY_T_COMPLEX"):
- tRComplex = self.target.FindFirstType("struct RComplex").GetPointerType()
- val = val.Cast(tRComplex)
- self.inspect(val.GetValueForExpressionPath("->real"))
- real = self.result.GetOutput().rstrip()
- self.result.Clear()
- self.inspect(val.GetValueForExpressionPath("->imag"))
- imag = self.result.GetOutput().rstrip()
- self.result.Clear()
- if not imag.startswith("-"):
- imag = "+" + imag
- print("(Complex) " + real + imag + "i", file=self.result)
-
- elif rval.is_type("RUBY_T_REGEXP"):
- tRRegex = self.target.FindFirstType("struct RRegexp").GetPointerType()
- val = val.Cast(tRRegex)
- print("(Regex) ->src {", file=self.result)
- self.inspect(val.GetValueForExpressionPath("->src"))
- print("}", file=self.result)
-
- elif rval.is_type("RUBY_T_DATA"):
- tRTypedData = self.target.FindFirstType("struct RTypedData").GetPointerType()
- val = val.Cast(tRTypedData)
- flag = val.GetValueForExpressionPath("->typed_flag")
-
- if flag.GetValueAsUnsigned() == 1:
- print("T_DATA: %s" %
- val.GetValueForExpressionPath("->type->wrap_struct_name"),
- file=self.result)
- self._append_expression("*(struct RTypedData *) %0#x" % val.GetValueAsUnsigned())
- else:
- print("T_DATA:", file=self.result)
- self._append_expression("*(struct RData *) %0#x" % val.GetValueAsUnsigned())
-
- elif rval.is_type("RUBY_T_NODE"):
- tRNode = self.target.FindFirstType("struct RNode").GetPointerType()
- rbNodeTypeMask = self.ruby_globals["RUBY_NODE_TYPEMASK"]
- rbNodeTypeShift = self.ruby_globals["RUBY_NODE_TYPESHIFT"]
-
- nd_type = (rval.flags & rbNodeTypeMask) >> rbNodeTypeShift
- val = val.Cast(tRNode)
-
- self._append_expression("(node_type) %d" % nd_type)
-
- if nd_type == self.ruby_globals["NODE_SCOPE"]:
- self._append_expression("*(struct RNode_SCOPE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_BLOCK"]:
- self._append_expression("*(struct RNode_BLOCK *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_IF"]:
- self._append_expression("*(struct RNode_IF *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_UNLESS"]:
- self._append_expression("*(struct RNode_UNLESS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CASE"]:
- self._append_expression("*(struct RNode_CASE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CASE2"]:
- self._append_expression("*(struct RNode_CASE2 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CASE3"]:
- self._append_expression("*(struct RNode_CASE3 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_WHEN"]:
- self._append_expression("*(struct RNode_WHEN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_IN"]:
- self._append_expression("*(struct RNode_IN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_WHILE"]:
- self._append_expression("*(struct RNode_WHILE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_UNTIL"]:
- self._append_expression("*(struct RNode_UNTIL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ITER"]:
- self._append_expression("*(struct RNode_ITER *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FOR"]:
- self._append_expression("*(struct RNode_FOR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FOR_MASGN"]:
- self._append_expression("*(struct RNode_FOR_MASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_BREAK"]:
- self._append_expression("*(struct RNode_BREAK *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_NEXT"]:
- self._append_expression("*(struct RNode_NEXT *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_REDO"]:
- self._append_expression("*(struct RNode_REDO *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_RETRY"]:
- self._append_expression("*(struct RNode_RETRY *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_BEGIN"]:
- self._append_expression("*(struct RNode_BEGIN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_RESCUE"]:
- self._append_expression("*(struct RNode_RESCUE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_RESBODY"]:
- self._append_expression("*(struct RNode_RESBODY *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ENSURE"]:
- self._append_expression("*(struct RNode_ENSURE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_AND"]:
- self._append_expression("*(struct RNode_AND *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OR"]:
- self._append_expression("*(struct RNode_OR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_MASGN"]:
- self._append_expression("*(struct RNode_MASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_LASGN"]:
- self._append_expression("*(struct RNode_LASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DASGN"]:
- self._append_expression("*(struct RNode_DASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_GASGN"]:
- self._append_expression("*(struct RNode_GASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_IASGN"]:
- self._append_expression("*(struct RNode_IASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CDECL"]:
- self._append_expression("*(struct RNode_CDECL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CVASGN"]:
- self._append_expression("*(struct RNode_CVASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OP_ASGN1"]:
- self._append_expression("*(struct RNode_OP_ASGN1 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OP_ASGN2"]:
- self._append_expression("*(struct RNode_OP_ASGN2 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OP_ASGN_AND"]:
- self._append_expression("*(struct RNode_OP_ASGN_AND *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OP_ASGN_OR"]:
- self._append_expression("*(struct RNode_OP_ASGN_OR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OP_CDECL"]:
- self._append_expression("*(struct RNode_OP_CDECL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CALL"]:
- self._append_expression("*(struct RNode_CALL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OPCALL"]:
- self._append_expression("*(struct RNode_OPCALL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FCALL"]:
- self._append_expression("*(struct RNode_FCALL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_VCALL"]:
- self._append_expression("*(struct RNode_VCALL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_QCALL"]:
- self._append_expression("*(struct RNode_QCALL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_SUPER"]:
- self._append_expression("*(struct RNode_SUPER *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ZSUPER"]:
- self._append_expression("*(struct RNode_ZSUPER *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_LIST"]:
- self._append_expression("*(struct RNode_LIST *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ZLIST"]:
- self._append_expression("*(struct RNode_ZLIST *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_HASH"]:
- self._append_expression("*(struct RNode_HASH *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_RETURN"]:
- self._append_expression("*(struct RNode_RETURN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_YIELD"]:
- self._append_expression("*(struct RNode_YIELD *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_LVAR"]:
- self._append_expression("*(struct RNode_LVAR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DVAR"]:
- self._append_expression("*(struct RNode_DVAR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_GVAR"]:
- self._append_expression("*(struct RNode_GVAR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CONST"]:
- self._append_expression("*(struct RNode_CONST *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CVAR"]:
- self._append_expression("*(struct RNode_CVAR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_NTH_REF"]:
- self._append_expression("*(struct RNode_NTH_REF *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_BACK_REF"]:
- self._append_expression("*(struct RNode_BACK_REF *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_MATCH"]:
- self._append_expression("*(struct RNode_MATCH *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_MATCH2"]:
- self._append_expression("*(struct RNode_MATCH2 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_MATCH3"]:
- self._append_expression("*(struct RNode_MATCH3 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_LIT"]:
- self._append_expression("*(struct RNode_LIT *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_STR"]:
- self._append_expression("*(struct RNode_STR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DSTR"]:
- self._append_expression("*(struct RNode_DSTR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_XSTR"]:
- self._append_expression("*(struct RNode_XSTR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DXSTR"]:
- self._append_expression("*(struct RNode_DXSTR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_EVSTR"]:
- self._append_expression("*(struct RNode_EVSTR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DREGX"]:
- self._append_expression("*(struct RNode_DREGX *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ONCE"]:
- self._append_expression("*(struct RNode_ONCE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ARGS"]:
- self._append_expression("*(struct RNode_ARGS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ARGS_AUX"]:
- self._append_expression("*(struct RNode_ARGS_AUX *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_OPT_ARG"]:
- self._append_expression("*(struct RNode_OPT_ARG *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_KW_ARG"]:
- self._append_expression("*(struct RNode_KW_ARG *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_POSTARG"]:
- self._append_expression("*(struct RNode_POSTARG *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ARGSCAT"]:
- self._append_expression("*(struct RNode_ARGSCAT *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ARGSPUSH"]:
- self._append_expression("*(struct RNode_ARGSPUSH *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_SPLAT"]:
- self._append_expression("*(struct RNode_SPLAT *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DEFN"]:
- self._append_expression("*(struct RNode_DEFN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DEFS"]:
- self._append_expression("*(struct RNode_DEFS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ALIAS"]:
- self._append_expression("*(struct RNode_ALIAS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_VALIAS"]:
- self._append_expression("*(struct RNode_VALIAS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_UNDEF"]:
- self._append_expression("*(struct RNode_UNDEF *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_CLASS"]:
- self._append_expression("*(struct RNode_CLASS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_MODULE"]:
- self._append_expression("*(struct RNode_MODULE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_SCLASS"]:
- self._append_expression("*(struct RNode_SCLASS *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_COLON2"]:
- self._append_expression("*(struct RNode_COLON2 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_COLON3"]:
- self._append_expression("*(struct RNode_COLON3 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DOT2"]:
- self._append_expression("*(struct RNode_DOT2 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DOT3"]:
- self._append_expression("*(struct RNode_DOT3 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FLIP2"]:
- self._append_expression("*(struct RNode_FLIP2 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FLIP3"]:
- self._append_expression("*(struct RNode_FLIP3 *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_SELF"]:
- self._append_expression("*(struct RNode_SELF *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_NIL"]:
- self._append_expression("*(struct RNode_NIL *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_TRUE"]:
- self._append_expression("*(struct RNode_TRUE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FALSE"]:
- self._append_expression("*(struct RNode_FALSE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ERRINFO"]:
- self._append_expression("*(struct RNode_ERRINFO *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DEFINED"]:
- self._append_expression("*(struct RNode_DEFINED *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_POSTEXE"]:
- self._append_expression("*(struct RNode_POSTEXE *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_DSYM"]:
- self._append_expression("*(struct RNode_DSYM *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ATTRASGN"]:
- self._append_expression("*(struct RNode_ATTRASGN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_LAMBDA"]:
- self._append_expression("*(struct RNode_LAMBDA *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ARYPTN"]:
- self._append_expression("*(struct RNode_ARYPTN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_HSHPTN"]:
- self._append_expression("*(struct RNode_HSHPTN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_FNDPTN"]:
- self._append_expression("*(struct RNode_FNDPTN *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_ERROR"]:
- self._append_expression("*(struct RNode_ERROR *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_RIPPER"]:
- self._append_expression("*(struct RNode_RIPPER *) %0#x" % val.GetValueAsUnsigned())
- elif nd_type == self.ruby_globals["NODE_RIPPER_VALUES"]:
- self._append_expression("*(struct RNode_RIPPER_VALUES *) %0#x" % val.GetValueAsUnsigned())
- else:
- self._append_expression("*(struct RNode *) %0#x" % val.GetValueAsUnsigned())
-
- elif rval.is_type("RUBY_T_IMEMO"):
- imemo_type = ((rval.flags >> self.ruby_globals["RUBY_FL_USHIFT"])
- & IMEMO_MASK)
- print("T_IMEMO: ", file=self.result)
-
- self._append_expression("(enum imemo_type) %d" % imemo_type)
- self._append_expression("*(struct MEMO *) %0#x" % val.GetValueAsUnsigned())
-
- elif rval.is_type("RUBY_T_FILE"):
- self.generic_inspect(val, "RFile")
-
- elif rval.is_type("RUBY_T_MOVED"):
- self.generic_inspect(val, "RMoved")
-
- elif rval.is_type("RUBY_T_MATCH"):
- self.generic_inspect(val, "RMatch")
-
- elif rval.is_type("RUBY_T_STRUCT"):
- self.generic_inspect(val, "RStruct")
-
- elif rval.is_type("RUBY_T_ZOMBIE"):
- self.generic_inspect(val, "RZombie")
-
- else:
- print("Not-handled type %0#x" % rval.type, file=self.result)
- print(val, file=self.result)
diff --git a/missing/dtoa.c b/missing/dtoa.c
index bce2cb22a1..b7a8302875 100644
--- a/missing/dtoa.c
+++ b/missing/dtoa.c
@@ -183,10 +183,7 @@
#undef Long
#undef ULong
-#include <assert.h>
#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
#if (INT_MAX >> 30) && !(INT_MAX >> 31)
#define Long int
@@ -198,7 +195,7 @@
#error No 32bit integer
#endif
-#if defined(HAVE_LONG_LONG) && (HAVE_LONG_LONG)
+#if HAVE_LONG_LONG
#define Llong LONG_LONG
#else
#define NO_LONG_LONG
@@ -224,12 +221,12 @@
#ifdef MALLOC
extern void *MALLOC(size_t);
#else
-#define MALLOC malloc
+#define MALLOC xmalloc
#endif
#ifdef FREE
extern void FREE(void*);
#else
-#define FREE free
+#define FREE xfree
#endif
#ifndef NO_SANITIZE
#define NO_SANITIZE(x, y) y
@@ -505,7 +502,7 @@ extern double rnd_prod(double, double), rnd_quot(double, double);
#endif
#ifndef ATOMIC_PTR_CAS
-#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (void *)(old))
+#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old))
#endif
#ifndef LIKELY
#define LIKELY(x) (x)
diff --git a/missing/explicit_bzero.c b/missing/explicit_bzero.c
index 59417e158e..1220e5f9ad 100644
--- a/missing/explicit_bzero.c
+++ b/missing/explicit_bzero.c
@@ -1,9 +1,12 @@
#ifndef __STDC_WANT_LIB_EXT1__
-#define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s() */
+#define __STDC_WANT_LIB_EXT1__ 1
#endif
#include "ruby/missing.h"
#include <string.h>
+#ifdef HAVE_MEMSET_S
+# include <string.h>
+#endif
#ifdef _WIN32
#include <windows.h>
diff --git a/missing/procstat_vm.c b/missing/procstat_vm.c
index 155ee355d1..76fd8f61ba 100644
--- a/missing/procstat_vm.c
+++ b/missing/procstat_vm.c
@@ -6,7 +6,7 @@
# define KVME_TYPE_MGTDEVICE 8
# endif
void
-procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout)
+procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
{
struct kinfo_vmentry *freep, *kve;
int ptrwidth;
@@ -17,7 +17,7 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout)
#else
ptrwidth = 2*sizeof(void *) + 2;
#endif
- fprintf(errout, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n",
+ fprintf(stderr, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n",
ptrwidth, "START", ptrwidth, "END", "PRT", "RES",
"P""RES", "REF", "SHD", "FL", "TP", "PATH");
@@ -30,20 +30,20 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout)
return;
for (i = 0; i < cnt; i++) {
kve = &freep[i];
- fprintf(errout, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start);
- fprintf(errout, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end);
- fprintf(errout, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-");
- fprintf(errout, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-");
- fprintf(errout, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-");
- fprintf(errout, "%4d ", kve->kve_resident);
- fprintf(errout, "%4d ", kve->kve_private_resident);
- fprintf(errout, "%3d ", kve->kve_ref_count);
- fprintf(errout, "%3d ", kve->kve_shadow_count);
- fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-");
- fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" :
+ fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start);
+ fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end);
+ fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-");
+ fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-");
+ fprintf(stderr, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-");
+ fprintf(stderr, "%4d ", kve->kve_resident);
+ fprintf(stderr, "%4d ", kve->kve_private_resident);
+ fprintf(stderr, "%3d ", kve->kve_ref_count);
+ fprintf(stderr, "%3d ", kve->kve_shadow_count);
+ fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-");
+ fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" :
"-");
- fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-");
- fprintf(errout, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" :
+ fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-");
+ fprintf(stderr, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" :
kve->kve_flags & KVME_FLAG_GROWS_DOWN ? "D" : "-");
switch (kve->kve_type) {
case KVME_TYPE_NONE:
@@ -78,8 +78,8 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout)
str = "??";
break;
}
- fprintf(errout, "%-2s ", str);
- fprintf(errout, "%-s\n", kve->kve_path);
+ fprintf(stderr, "%-2s ", str);
+ fprintf(stderr, "%-s\n", kve->kve_path);
}
free(freep);
}
diff --git a/missing/setproctitle.c b/missing/setproctitle.c
index 6a85323818..811829c060 100644
--- a/missing/setproctitle.c
+++ b/missing/setproctitle.c
@@ -135,7 +135,6 @@ compat_init_setproctitle(int argc, char *argv[])
}
#ifndef HAVE_SETPROCTITLE
-
void
setproctitle(const char *fmt, ...)
{
diff --git a/mjit.c b/mjit.c
new file mode 100644
index 0000000000..3200ee2621
--- /dev/null
+++ b/mjit.c
@@ -0,0 +1,1999 @@
+/**********************************************************************
+
+ mjit.c - MRI method JIT compiler functions
+
+ Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
+ Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
+
+**********************************************************************/
+
+/* We utilize widely used C compilers (GCC and LLVM Clang) to
+ implement MJIT. We feed them a C code generated from ISEQ. The
+ industrial C compilers are slower than regular JIT engines.
+ Generated code performance of the used C compilers has a higher
+ priority over the compilation speed.
+
+ So our major goal is to minimize the ISEQ compilation time when we
+ use widely optimization level (-O2). It is achieved by
+
+ o Using a precompiled version of the header
+ o Keeping all files in `/tmp`. On modern Linux `/tmp` is a file
+ system in memory. So it is pretty fast
+ o Implementing MJIT as a multi-threaded code because we want to
+ compile ISEQs in parallel with iseq execution to speed up Ruby
+ code execution. MJIT has one thread (*worker*) to do
+ parallel compilations:
+ o It prepares a precompiled code of the minimized header.
+ It starts at the MRI execution start
+ o It generates PIC object files of ISEQs
+ o It takes one JIT unit from a priority queue unless it is empty.
+ o It translates the JIT unit ISEQ into C-code using the precompiled
+ header, calls CC and load PIC code when it is ready
+ o Currently MJIT put ISEQ in the queue when ISEQ is called
+ o MJIT can reorder ISEQs in the queue if some ISEQ has been called
+ many times and its compilation did not start yet
+ o MRI reuses the machine code if it already exists for ISEQ
+ o The machine code we generate can stop and switch to the ISEQ
+ interpretation if some condition is not satisfied as the machine
+ code can be speculative or some exception raises
+ o Speculative machine code can be canceled.
+
+ Here is a diagram showing the MJIT organization:
+
+ _______
+ |header |
+ |_______|
+ | MRI building
+ --------------|----------------------------------------
+ | MRI execution
+ |
+ _____________|_____
+ | | |
+ | ___V__ | CC ____________________
+ | | |----------->| precompiled header |
+ | | | | |____________________|
+ | | | | |
+ | | MJIT | | |
+ | | | | |
+ | | | | ____V___ CC __________
+ | |______|----------->| C code |--->| .so file |
+ | | |________| |__________|
+ | | |
+ | | |
+ | MRI machine code |<-----------------------------
+ |___________________| loading
+
+*/
+
+#include "ruby/internal/config.h" // defines USE_MJIT
+
+#if USE_MJIT
+
+#include "constant.h"
+#include "id_table.h"
+#include "internal.h"
+#include "internal/class.h"
+#include "internal/cmdlineopt.h"
+#include "internal/cont.h"
+#include "internal/file.h"
+#include "internal/hash.h"
+#include "internal/process.h"
+#include "internal/warnings.h"
+#include "vm_sync.h"
+#include "ractor_core.h"
+
+#ifdef __sun
+#define __EXTENSIONS__ 1
+#endif
+
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "mjit.h"
+#include "mjit_c.h"
+#include "gc.h"
+#include "ruby_assert.h"
+#include "ruby/debug.h"
+#include "ruby/thread.h"
+#include "ruby/version.h"
+#include "builtin.h"
+#include "insns.inc"
+#include "insns_info.inc"
+#include "internal/compile.h"
+
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#include "dln.h"
+
+#include "ruby/util.h"
+#undef strdup // ruby_strdup may trigger GC
+
+#ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+#endif
+
+// Atomically set function pointer if possible.
+#define MJIT_ATOMIC_SET(var, val) (void)ATOMIC_PTR_EXCHANGE(var, val)
+
+#define MJIT_TMP_PREFIX "_ruby_mjit_"
+
+extern void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
+extern void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
+extern void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
+extern void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
+
+// process.c
+extern void mjit_add_waiting_pid(rb_vm_t *vm, rb_pid_t pid);
+
+// A copy of MJIT portion of MRI options since MJIT initialization. We
+// need them as MJIT threads still can work when the most MRI data were
+// freed.
+struct mjit_options mjit_opts;
+
+// true if MJIT is enabled.
+bool mjit_enabled = false;
+// true if JIT-ed code should be called. When `ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS`
+// and `mjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
+bool mjit_call_p = false;
+// A flag to communicate that mjit_call_p should be disabled while it's temporarily false.
+bool mjit_cancel_p = false;
+// There's an ISEQ in unit_queue whose total_calls reached 2 * call_threshold.
+// If this is true, check_unit_queue will start compiling ISEQs in unit_queue.
+static bool mjit_compile_p = false;
+// The actual number of units in active_units
+static int active_units_length = 0;
+// The actual number of units in compact_units
+static int compact_units_length = 0;
+
+// Priority queue of iseqs waiting for JIT compilation.
+// This variable is a pointer to head unit of the queue.
+static struct rb_mjit_unit_list unit_queue = { CCAN_LIST_HEAD_INIT(unit_queue.head) };
+// List of units which are successfully compiled.
+static struct rb_mjit_unit_list active_units = { CCAN_LIST_HEAD_INIT(active_units.head) };
+// List of compacted so files which will be cleaned up by `free_list()` in `mjit_finish()`.
+static struct rb_mjit_unit_list compact_units = { CCAN_LIST_HEAD_INIT(compact_units.head) };
+// List of units before recompilation and just waiting for dlclose().
+static struct rb_mjit_unit_list stale_units = { CCAN_LIST_HEAD_INIT(stale_units.head) };
+// The number of so far processed ISEQs, used to generate unique id.
+static int current_unit_num;
+// A mutex for conitionals and critical sections.
+static rb_nativethread_lock_t mjit_engine_mutex;
+// Set to true to stop worker.
+static bool stop_worker_p;
+// Set to true if worker is stopped.
+static bool worker_stopped = true;
+
+// Path of "/tmp", which is different on Windows or macOS. See: system_default_tmpdir()
+static char *tmp_dir;
+
+// Used C compiler path.
+static const char *cc_path;
+// Used C compiler flags.
+static const char **cc_common_args;
+// Used C compiler flags added by --mjit-debug=...
+static char **cc_added_args;
+// Name of the precompiled header file.
+static char *pch_file;
+// The process id which should delete the pch_file on mjit_finish.
+static rb_pid_t pch_owner_pid;
+// Status of the precompiled header creation. The status is
+// shared by the workers and the pch thread.
+static enum {PCH_NOT_READY, PCH_FAILED, PCH_SUCCESS} pch_status;
+
+// The start timestamp of current compilation
+static double current_cc_ms = 0.0; // TODO: make this part of unit?
+// Currently compiling MJIT unit
+static struct rb_mjit_unit *current_cc_unit = NULL;
+// PID of currently running C compiler process. 0 if nothing is running.
+static pid_t current_cc_pid = 0; // TODO: make this part of unit?
+
+// Name of the header file.
+static char *header_file;
+
+#include "mjit_config.h"
+
+#if defined(__GNUC__) && \
+ (!defined(__clang__) || \
+ (defined(__clang__) && (defined(__FreeBSD__) || defined(__GLIBC__))))
+# define GCC_PIC_FLAGS "-Wfatal-errors", "-fPIC", "-shared", "-w", "-pipe",
+# define MJIT_CFLAGS_PIPE 1
+#else
+# define GCC_PIC_FLAGS /* empty */
+# define MJIT_CFLAGS_PIPE 0
+#endif
+
+// Use `-nodefaultlibs -nostdlib` for GCC where possible, which does not work on cygwin, AIX, and OpenBSD.
+// This seems to improve MJIT performance on GCC.
+#if defined __GNUC__ && !defined __clang__ && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__OpenBSD__)
+# define GCC_NOSTDLIB_FLAGS "-nodefaultlibs", "-nostdlib",
+#else
+# define GCC_NOSTDLIB_FLAGS // empty
+#endif
+
+static const char *const CC_COMMON_ARGS[] = {
+ MJIT_CC_COMMON MJIT_CFLAGS GCC_PIC_FLAGS
+ NULL
+};
+
+static const char *const CC_DEBUG_ARGS[] = {MJIT_DEBUGFLAGS NULL};
+static const char *const CC_OPTIMIZE_ARGS[] = {MJIT_OPTFLAGS NULL};
+
+static const char *const CC_LDSHARED_ARGS[] = {MJIT_LDSHARED MJIT_CFLAGS GCC_PIC_FLAGS NULL};
+static const char *const CC_DLDFLAGS_ARGS[] = {MJIT_DLDFLAGS NULL};
+// `CC_LINKER_ARGS` are linker flags which must be passed to `-c` as well.
+static const char *const CC_LINKER_ARGS[] = {
+#if defined __GNUC__ && !defined __clang__ && !defined(__OpenBSD__)
+ "-nostartfiles",
+#endif
+ GCC_NOSTDLIB_FLAGS NULL
+};
+
+static const char *const CC_LIBS[] = {
+#if defined(__CYGWIN__)
+ MJIT_LIBS // mswin, cygwin
+#endif
+#if defined __GNUC__ && !defined __clang__
+ "-lgcc", // cygwin, and GCC platforms using `-nodefaultlibs -nostdlib`
+#endif
+#if defined __ANDROID__
+ "-lm", // to avoid 'cannot locate symbol "modf" referenced by .../_ruby_mjit_XXX.so"'
+#endif
+ NULL
+};
+
+#define CC_CODEFLAG_ARGS (mjit_opts.debug ? CC_DEBUG_ARGS : CC_OPTIMIZE_ARGS)
+
+// Print the arguments according to FORMAT to stderr only if MJIT
+// verbose option value is more or equal to LEVEL.
+PRINTF_ARGS(static void, 2, 3)
+verbose(int level, const char *format, ...)
+{
+ if (mjit_opts.verbose >= level) {
+ va_list args;
+ size_t len = strlen(format);
+ char *full_format = alloca(sizeof(char) * (len + 2));
+
+ // Creating `format + '\n'` to atomically print format and '\n'.
+ memcpy(full_format, format, len);
+ full_format[len] = '\n';
+ full_format[len+1] = '\0';
+
+ va_start(args, format);
+ vfprintf(stderr, full_format, args);
+ va_end(args);
+ }
+}
+
+PRINTF_ARGS(static void, 1, 2)
+mjit_warning(const char *format, ...)
+{
+ if (mjit_opts.warnings || mjit_opts.verbose) {
+ va_list args;
+
+ fprintf(stderr, "MJIT warning: ");
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+}
+
+// Add unit node to the tail of doubly linked `list`. It should be not in
+// the list before.
+static void
+add_to_list(struct rb_mjit_unit *unit, struct rb_mjit_unit_list *list)
+{
+ ccan_list_add_tail(&list->head, &unit->unode);
+ list->length++;
+}
+
+static void
+remove_from_list(struct rb_mjit_unit *unit, struct rb_mjit_unit_list *list)
+{
+ ccan_list_del(&unit->unode);
+ list->length--;
+}
+
+static void
+remove_file(const char *filename)
+{
+ if (remove(filename)) {
+ mjit_warning("failed to remove \"%s\": %s", filename, strerror(errno));
+ }
+}
+
+// This is called in the following situations:
+// 1) On dequeue or `unload_units()`, associated ISeq is already GCed.
+// 2) The unit is not called often and unloaded by `unload_units()`.
+// 3) Freeing lists on `mjit_finish()`.
+//
+// `jit_func` value does not matter for 1 and 3 since the unit won't be used anymore.
+// For the situation 2, this sets the ISeq's JIT state to MJIT_FUNC_FAILED
+// to prevent the situation that the same methods are continuously compiled.
+static void
+free_unit(struct rb_mjit_unit *unit)
+{
+ if (unit->iseq) { // ISeq is not GCed
+ ISEQ_BODY(unit->iseq)->jit_func = (jit_func_t)MJIT_FUNC_FAILED;
+ ISEQ_BODY(unit->iseq)->mjit_unit = NULL;
+ }
+ if (unit->cc_entries) {
+ void *entries = (void *)unit->cc_entries;
+ free(entries);
+ }
+ if (unit->handle && dlclose(unit->handle)) { // handle is NULL if it's in queue
+ mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
+ }
+ xfree(unit);
+}
+
+// Start a critical section. Use message `msg` to print debug info at `level`.
+static inline void
+CRITICAL_SECTION_START(int level, const char *msg)
+{
+ verbose(level, "Locking %s", msg);
+ rb_native_mutex_lock(&mjit_engine_mutex);
+ verbose(level, "Locked %s", msg);
+}
+
+// Finish the current critical section. Use message `msg` to print
+// debug info at `level`.
+static inline void
+CRITICAL_SECTION_FINISH(int level, const char *msg)
+{
+ verbose(level, "Unlocked %s", msg);
+ rb_native_mutex_unlock(&mjit_engine_mutex);
+}
+
+static pid_t mjit_pid = 0;
+
+static int
+sprint_uniq_filename(char *str, size_t size, unsigned long id, const char *prefix, const char *suffix)
+{
+ return snprintf(str, size, "%s/%sp%"PRI_PIDT_PREFIX"uu%lu%s", tmp_dir, prefix, mjit_pid, id, suffix);
+}
+
+// Return time in milliseconds as a double.
+#ifdef __APPLE__
+double ruby_real_ms_time(void);
+# define real_ms_time() ruby_real_ms_time()
+#else
+static double
+real_ms_time(void)
+{
+# ifdef HAVE_CLOCK_GETTIME
+ struct timespec tv;
+# ifdef CLOCK_MONOTONIC
+ const clockid_t c = CLOCK_MONOTONIC;
+# else
+ const clockid_t c = CLOCK_REALTIME;
+# endif
+
+ clock_gettime(c, &tv);
+ return tv.tv_nsec / 1000000.0 + tv.tv_sec * 1000.0;
+# else
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return tv.tv_usec / 1000.0 + tv.tv_sec * 1000.0;
+# endif
+}
+#endif
+
+// Return the best unit from list. The best is the first
+// high priority unit or the unit whose iseq has the biggest number
+// of calls so far.
+static struct rb_mjit_unit *
+get_from_list(struct rb_mjit_unit_list *list)
+{
+ // Find iseq with max total_calls
+ struct rb_mjit_unit *unit = NULL, *next, *best = NULL;
+ ccan_list_for_each_safe(&list->head, unit, next, unode) {
+ if (unit->iseq == NULL) { // ISeq is GCed.
+ remove_from_list(unit, list);
+ free_unit(unit);
+ continue;
+ }
+
+ if (best == NULL || ISEQ_BODY(best->iseq)->total_calls < ISEQ_BODY(unit->iseq)->total_calls) {
+ best = unit;
+ }
+ }
+
+ if (best) {
+ remove_from_list(best, list);
+ }
+ return best;
+}
+
+// Return length of NULL-terminated array `args` excluding the NULL marker.
+static size_t
+args_len(char *const *args)
+{
+ size_t i;
+
+ for (i = 0; (args[i]) != NULL;i++)
+ ;
+ return i;
+}
+
+// Concatenate `num` passed NULL-terminated arrays of strings, put the
+// result (with NULL end marker) into the heap, and return the result.
+static char **
+form_args(int num, ...)
+{
+ va_list argp;
+ size_t len, n;
+ int i;
+ char **args, **res, **tmp;
+
+ va_start(argp, num);
+ res = NULL;
+ for (i = len = 0; i < num; i++) {
+ args = va_arg(argp, char **);
+ n = args_len(args);
+ if ((tmp = (char **)realloc(res, sizeof(char *) * (len + n + 1))) == NULL) {
+ free(res);
+ res = NULL;
+ break;
+ }
+ res = tmp;
+ MEMCPY(res + len, args, char *, n + 1);
+ len += n;
+ }
+ va_end(argp);
+ return res;
+}
+
+COMPILER_WARNING_PUSH
+#if __has_warning("-Wdeprecated-declarations") || RBIMPL_COMPILER_IS(GCC)
+COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
+#endif
+// Start an OS process of absolute executable path with arguments `argv`.
+// Return PID of the process.
+static pid_t
+start_process(const char *abspath, char *const *argv)
+{
+ // Not calling non-async-signal-safe functions between vfork
+ // and execv for safety
+ int dev_null = rb_cloexec_open(ruby_null_device, O_WRONLY, 0);
+ if (dev_null < 0) {
+ verbose(1, "MJIT: Failed to open a null device: %s", strerror(errno));
+ return -1;
+ }
+ if (mjit_opts.verbose >= 2) {
+ const char *arg;
+ fprintf(stderr, "Starting process: %s", abspath);
+ for (int i = 0; (arg = argv[i]) != NULL; i++)
+ fprintf(stderr, " %s", arg);
+ fprintf(stderr, "\n");
+ }
+
+ pid_t pid;
+ if ((pid = vfork()) == 0) { /* TODO: reuse some function in process.c */
+ umask(0077);
+ if (mjit_opts.verbose == 0) {
+ // CC can be started in a thread using a file which has been
+ // already removed while MJIT is finishing. Discard the
+ // messages about missing files.
+ dup2(dev_null, STDERR_FILENO);
+ dup2(dev_null, STDOUT_FILENO);
+ }
+ (void)close(dev_null);
+ pid = execv(abspath, argv); // Pid will be negative on an error
+ // Even if we successfully found CC to compile PCH we still can
+ // fail with loading the CC in very rare cases for some reasons.
+ // Stop the forked process in this case.
+ verbose(1, "MJIT: Error in execv: %s", abspath);
+ _exit(1);
+ }
+ (void)close(dev_null);
+ return pid;
+}
+COMPILER_WARNING_POP
+
+// Execute an OS process of executable PATH with arguments ARGV.
+// Return -1 or -2 if failed to execute, otherwise exit code of the process.
+// TODO: Use a similar function in process.c
+static int
+exec_process(const char *path, char *const argv[])
+{
+ int stat, exit_code = -2;
+ pid_t pid = start_process(path, argv);
+ for (;pid > 0;) {
+ pid_t r = waitpid(pid, &stat, 0);
+ if (r == -1) {
+ if (errno == EINTR) continue;
+ fprintf(stderr, "[%"PRI_PIDT_PREFIX"d] waitpid(%lu): %s (SIGCHLD=%d,%u)\n",
+ getpid(), (unsigned long)pid, strerror(errno),
+ RUBY_SIGCHLD, SIGCHLD_LOSSY);
+ break;
+ }
+ else if (r == pid) {
+ if (WIFEXITED(stat)) {
+ exit_code = WEXITSTATUS(stat);
+ break;
+ }
+ else if (WIFSIGNALED(stat)) {
+ exit_code = -1;
+ break;
+ }
+ }
+ }
+ return exit_code;
+}
+
+static void
+remove_so_file(const char *so_file, struct rb_mjit_unit *unit)
+{
+ remove_file(so_file);
+}
+
+// Print _mjitX, but make a human-readable funcname when --mjit-debug is used
+static void
+sprint_funcname(char *funcname, size_t funcname_size, const struct rb_mjit_unit *unit)
+{
+ const rb_iseq_t *iseq = unit->iseq;
+ if (iseq == NULL || (!mjit_opts.debug && !mjit_opts.debug_flags)) {
+ snprintf(funcname, funcname_size, "_mjit%d", unit->id);
+ return;
+ }
+
+ // Generate a short path
+ const char *path = RSTRING_PTR(rb_iseq_path(iseq));
+ const char *lib = "/lib/";
+ const char *version = "/" STRINGIZE(RUBY_API_VERSION_MAJOR) "." STRINGIZE(RUBY_API_VERSION_MINOR) "." STRINGIZE(RUBY_API_VERSION_TEENY) "/";
+ while (strstr(path, lib)) // skip "/lib/"
+ path = strstr(path, lib) + strlen(lib);
+ while (strstr(path, version)) // skip "/x.y.z/"
+ path = strstr(path, version) + strlen(version);
+
+ // Annotate all-normalized method names
+ const char *method = RSTRING_PTR(ISEQ_BODY(iseq)->location.label);
+ if (!strcmp(method, "[]")) method = "AREF";
+ if (!strcmp(method, "[]=")) method = "ASET";
+
+ // Print and normalize
+ snprintf(funcname, funcname_size, "_mjit%d_%s_%s", unit->id, path, method);
+ for (size_t i = 0; i < strlen(funcname); i++) {
+ char c = funcname[i];
+ if (!(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_')) {
+ funcname[i] = '_';
+ }
+ }
+}
+
+static const int c_file_access_mode =
+#ifdef O_BINARY
+ O_BINARY|
+#endif
+ O_WRONLY|O_EXCL|O_CREAT;
+
+#define append_str2(p, str, len) ((char *)memcpy((p), str, (len))+(len))
+#define append_str(p, str) append_str2(p, str, sizeof(str)-1)
+#define append_lit(p, str) append_str2(p, str, rb_strlen_lit(str))
+
+// The function producing the pre-compiled header.
+static void
+make_pch(void)
+{
+ const char *rest_args[] = {
+# ifdef __clang__
+ "-Xclang",
+ "-emit-pch",
+ "-c",
+# endif
+ // -nodefaultlibs is a linker flag, but it may affect cc1 behavior on Gentoo, which should NOT be changed on pch:
+ // https://gitweb.gentoo.org/proj/gcc-patches.git/tree/7.3.0/gentoo/13_all_default-ssp-fix.patch
+ GCC_NOSTDLIB_FLAGS
+ "-o", pch_file, header_file,
+ NULL,
+ };
+
+ verbose(2, "Creating precompiled header");
+ char **args = form_args(4, cc_common_args, CC_CODEFLAG_ARGS, cc_added_args, rest_args);
+ if (args == NULL) {
+ mjit_warning("making precompiled header failed on forming args");
+ pch_status = PCH_FAILED;
+ return;
+ }
+
+ int exit_code = exec_process(cc_path, args);
+ free(args);
+
+ if (exit_code == 0) {
+ pch_status = PCH_SUCCESS;
+ }
+ else {
+ mjit_warning("Making precompiled header failed on compilation. Stopping MJIT worker...");
+ pch_status = PCH_FAILED;
+ }
+}
+
+static int
+c_compile(const char *c_file, const char *so_file)
+{
+ const char *so_args[] = {
+ "-o", so_file,
+# ifdef __clang__
+ "-include-pch", pch_file,
+# endif
+ c_file, NULL
+ };
+
+# if defined(__MACH__)
+ extern VALUE rb_libruby_selfpath;
+ const char *loader_args[] = {"-bundle_loader", StringValuePtr(rb_libruby_selfpath), NULL};
+# else
+ const char *loader_args[] = {NULL};
+# endif
+
+ char **args = form_args(8, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS, cc_added_args,
+ so_args, loader_args, CC_LIBS, CC_DLDFLAGS_ARGS, CC_LINKER_ARGS);
+ if (args == NULL) return 1;
+
+ int exit_code = exec_process(cc_path, args);
+ if (!mjit_opts.save_temps)
+ remove_file(c_file);
+
+ free(args);
+ return exit_code;
+}
+
+static int
+c_compile_unit(struct rb_mjit_unit *unit)
+{
+ static const char c_ext[] = ".c";
+ static const char so_ext[] = DLEXT;
+ char c_file[MAXPATHLEN], so_file[MAXPATHLEN];
+
+ sprint_uniq_filename(c_file, (int)sizeof(c_file), unit->id, MJIT_TMP_PREFIX, c_ext);
+ sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
+
+ return c_compile(c_file, so_file);
+}
+
+static void compile_prelude(FILE *f);
+
+static bool
+mjit_batch(struct rb_mjit_unit *unit)
+{
+ VM_ASSERT(unit->type == MJIT_UNIT_BATCH);
+ static const char c_ext[] = ".c";
+ static const char so_ext[] = DLEXT;
+ char c_file[MAXPATHLEN], so_file[MAXPATHLEN];
+
+ sprint_uniq_filename(c_file, (int)sizeof(c_file), unit->id, MJIT_TMP_PREFIX, c_ext);
+ sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
+
+ FILE *f;
+ int fd = rb_cloexec_open(c_file, c_file_access_mode, 0600);
+ if (fd < 0 || (f = fdopen(fd, "w")) == NULL) {
+ int e = errno;
+ if (fd >= 0) (void)close(fd);
+ verbose(1, "Failed to fopen '%s', giving up JIT for it (%s)", c_file, strerror(e));
+ return false;
+ }
+
+ compile_prelude(f);
+
+ bool success = true;
+ struct rb_mjit_unit *child_unit = 0;
+ ccan_list_for_each(&unit->units.head, child_unit, unode) {
+ if (!success) continue;
+ if (child_unit->iseq == NULL) continue; // ISEQ is GCed
+
+ char funcname[MAXPATHLEN];
+ sprint_funcname(funcname, sizeof(funcname), child_unit);
+
+ int iseq_lineno = ISEQ_BODY(child_unit->iseq)->location.first_lineno;
+ const char *sep = "@";
+ const char *iseq_label = RSTRING_PTR(ISEQ_BODY(child_unit->iseq)->location.label);
+ const char *iseq_path = RSTRING_PTR(rb_iseq_path(child_unit->iseq));
+ if (!iseq_label) iseq_label = sep = "";
+ fprintf(f, "\n/* %s%s%s:%d */\n", iseq_label, sep, iseq_path, iseq_lineno);
+ success &= mjit_compile(f, child_unit->iseq, funcname, child_unit->id);
+ }
+
+ fclose(f);
+ return success;
+}
+
+// Compile all cached .c files and build a single .so file. Reload all JIT func from it.
+// This improves the code locality for better performance in terms of iTLB and iCache.
+static bool
+mjit_compact(struct rb_mjit_unit *unit)
+{
+ VM_ASSERT(unit->type == MJIT_UNIT_COMPACT);
+ static const char c_ext[] = ".c";
+ static const char so_ext[] = DLEXT;
+ char c_file[MAXPATHLEN], so_file[MAXPATHLEN];
+
+ sprint_uniq_filename(c_file, (int)sizeof(c_file), unit->id, MJIT_TMP_PREFIX, c_ext);
+ sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
+
+ FILE *f;
+ int fd = rb_cloexec_open(c_file, c_file_access_mode, 0600);
+ if (fd < 0 || (f = fdopen(fd, "w")) == NULL) {
+ int e = errno;
+ if (fd >= 0) (void)close(fd);
+ verbose(1, "Failed to fopen '%s', giving up JIT for it (%s)", c_file, strerror(e));
+ return false;
+ }
+
+ compile_prelude(f);
+
+ bool success = true;
+ compact_units_length = 0;
+ struct rb_mjit_unit *batch_unit = 0, *child_unit = 0;
+ ccan_list_for_each(&active_units.head, batch_unit, unode) {
+ ccan_list_for_each(&batch_unit->units.head, child_unit, unode) {
+ if (!success) continue;
+ if (child_unit->iseq == NULL) continue; // ISEQ is GCed
+
+ char funcname[MAXPATHLEN];
+ sprint_funcname(funcname, sizeof(funcname), child_unit);
+
+ int iseq_lineno = ISEQ_BODY(child_unit->iseq)->location.first_lineno;
+ const char *sep = "@";
+ const char *iseq_label = RSTRING_PTR(ISEQ_BODY(child_unit->iseq)->location.label);
+ const char *iseq_path = RSTRING_PTR(rb_iseq_path(child_unit->iseq));
+ if (!iseq_label) iseq_label = sep = "";
+ fprintf(f, "\n/* %s%s%s:%d */\n", iseq_label, sep, iseq_path, iseq_lineno);
+ success &= mjit_compile(f, child_unit->iseq, funcname, child_unit->id);
+ compact_units_length++;
+ }
+ }
+
+ fclose(f);
+ return success;
+}
+
+static void
+load_batch_funcs_from_so(struct rb_mjit_unit *unit, char *c_file, char *so_file)
+{
+ double end_time = real_ms_time();
+
+ void *handle = dlopen(so_file, RTLD_NOW);
+ if (handle == NULL) {
+ mjit_warning("failure in loading code from batched '%s': %s", so_file, dlerror());
+ xfree(unit);
+ return;
+ }
+ unit->handle = handle;
+
+ // lazily dlclose handle on `mjit_finish()`.
+ add_to_list(unit, &active_units);
+ active_units_length += unit->units.length;
+
+ if (!mjit_opts.save_temps)
+ remove_so_file(so_file, unit);
+
+ struct rb_mjit_unit *child_unit = 0;
+ ccan_list_for_each(&unit->units.head, child_unit, unode) {
+ char funcname[MAXPATHLEN];
+ sprint_funcname(funcname, sizeof(funcname), child_unit);
+
+ void *func;
+ if ((func = dlsym(handle, funcname)) == NULL) {
+ mjit_warning("skipping to load '%s' from '%s': %s", funcname, so_file, dlerror());
+ continue;
+ }
+
+ if (child_unit->iseq) { // Check whether GCed or not
+ // Usage of jit_code might be not in a critical section.
+ const rb_iseq_t *iseq = child_unit->iseq;
+ MJIT_ATOMIC_SET(ISEQ_BODY(iseq)->jit_func, (jit_func_t)func);
+
+ verbose(1, "JIT success: %s@%s:%d",
+ RSTRING_PTR(ISEQ_BODY(iseq)->location.label),
+ RSTRING_PTR(rb_iseq_path(iseq)), ISEQ_BODY(iseq)->location.first_lineno);
+ }
+ else {
+ verbose(1, "JIT skip: A compiled method has been GCed");
+ }
+ }
+ verbose(1, "JIT batch (%.1fms): Batched %d methods %s -> %s", end_time - current_cc_ms, unit->units.length, c_file, so_file);
+}
+
+static void
+load_compact_funcs_from_so(struct rb_mjit_unit *unit, char *c_file, char *so_file)
+{
+ double end_time = real_ms_time();
+
+ void *handle = dlopen(so_file, RTLD_NOW);
+ if (handle == NULL) {
+ mjit_warning("failure in loading code from compacted '%s': %s", so_file, dlerror());
+ xfree(unit);
+ return;
+ }
+ unit->handle = handle;
+
+ // lazily dlclose handle on `mjit_finish()`.
+ add_to_list(unit, &compact_units);
+
+ if (!mjit_opts.save_temps)
+ remove_so_file(so_file, unit);
+
+ struct rb_mjit_unit *batch_unit = 0, *child_unit = 0;
+ ccan_list_for_each(&active_units.head, batch_unit, unode) {
+ ccan_list_for_each(&batch_unit->units.head, child_unit, unode) {
+ if (child_unit->iseq == NULL) continue; // ISEQ is GCed
+
+ char funcname[MAXPATHLEN];
+ sprint_funcname(funcname, sizeof(funcname), child_unit);
+
+ void *func;
+ if ((func = dlsym(handle, funcname)) == NULL) {
+ mjit_warning("skipping to reload '%s' from '%s': %s", funcname, so_file, dlerror());
+ continue;
+ }
+
+ if (child_unit->iseq) { // Check whether GCed or not
+ // Usage of jit_code might be not in a critical section.
+ MJIT_ATOMIC_SET(ISEQ_BODY(child_unit->iseq)->jit_func, (jit_func_t)func);
+ }
+ }
+ }
+ verbose(1, "JIT compaction (%.1fms): Compacted %d methods %s -> %s", end_time - current_cc_ms, active_units_length, c_file, so_file);
+}
+
+#ifndef __clang__
+static const char *
+header_name_end(const char *s)
+{
+ const char *e = s + strlen(s);
+# ifdef __GNUC__ // don't chomp .pch for mswin
+ static const char suffix[] = ".gch";
+
+ // chomp .gch suffix
+ if (e > s+sizeof(suffix)-1 && strcmp(e-sizeof(suffix)+1, suffix) == 0) {
+ e -= sizeof(suffix)-1;
+ }
+# endif
+ return e;
+}
+#endif
+
+// Print platform-specific prerequisites in generated code.
+static void
+compile_prelude(FILE *f)
+{
+#ifndef __clang__ // -include-pch is used for Clang
+ const char *s = pch_file;
+ const char *e = header_name_end(s);
+
+ fprintf(f, "#include \"");
+ // print pch_file except .gch for gcc, but keep .pch for mswin
+ for (; s < e; s++) {
+ switch (*s) {
+ case '\\': case '"':
+ fputc('\\', f);
+ }
+ fputc(*s, f);
+ }
+ fprintf(f, "\"\n");
+#endif
+}
+
+static pid_t
+start_c_compile_unit(struct rb_mjit_unit *unit)
+{
+ extern pid_t rb_mjit_fork();
+ pid_t pid = rb_mjit_fork();
+ if (pid == 0) {
+ int exit_code = c_compile_unit(unit);
+ exit(exit_code);
+ }
+ else {
+ return pid;
+ }
+}
+
+// Capture cc entries of `captured_iseq` and append them to `compiled_iseq->mjit_unit->cc_entries`.
+// This is needed when `captured_iseq` is inlined by `compiled_iseq` and GC needs to mark inlined cc.
+//
+// Index to refer to `compiled_iseq->mjit_unit->cc_entries` is returned instead of the address
+// because old addresses may be invalidated by `realloc` later. -1 is returned on failure.
+//
+// This assumes that it's safe to reference cc without acquiring GVL.
+int
+mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq)
+{
+ VM_ASSERT(compiled_iseq != NULL);
+ VM_ASSERT(compiled_iseq->mjit_unit != NULL);
+ VM_ASSERT(captured_iseq != NULL);
+
+ struct rb_mjit_unit *unit = compiled_iseq->mjit_unit;
+ unsigned int new_entries_size = unit->cc_entries_size + captured_iseq->ci_size;
+ VM_ASSERT(captured_iseq->ci_size > 0);
+
+ // Allocate new cc_entries and append them to unit->cc_entries
+ const struct rb_callcache **cc_entries;
+ int cc_entries_index = unit->cc_entries_size;
+ if (unit->cc_entries_size == 0) {
+ VM_ASSERT(unit->cc_entries == NULL);
+ unit->cc_entries = cc_entries = malloc(sizeof(struct rb_callcache *) * new_entries_size);
+ if (cc_entries == NULL) return -1;
+ }
+ else {
+ void *cc_ptr = (void *)unit->cc_entries; // get rid of bogus warning by VC
+ cc_entries = realloc(cc_ptr, sizeof(struct rb_callcache *) * new_entries_size);
+ if (cc_entries == NULL) return -1;
+ unit->cc_entries = cc_entries;
+ cc_entries += cc_entries_index;
+ }
+ unit->cc_entries_size = new_entries_size;
+
+ // Capture cc to cc_enties
+ for (unsigned int i = 0; i < captured_iseq->ci_size; i++) {
+ cc_entries[i] = captured_iseq->call_data[i].cc;
+ }
+
+ return cc_entries_index;
+}
+
+static void mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info);
+
+// Return an unique file name in /tmp with PREFIX and SUFFIX and
+// number ID. Use getpid if ID == 0. The return file name exists
+// until the next function call.
+static char *
+get_uniq_filename(unsigned long id, const char *prefix, const char *suffix)
+{
+ char buff[70], *str = buff;
+ int size = sprint_uniq_filename(buff, sizeof(buff), id, prefix, suffix);
+ str = 0;
+ ++size;
+ str = xmalloc(size);
+ if (size <= (int)sizeof(buff)) {
+ memcpy(str, buff, size);
+ }
+ else {
+ sprint_uniq_filename(str, size, id, prefix, suffix);
+ }
+ return str;
+}
+
+// Prohibit calling JIT-ed code and let existing JIT-ed frames exit before the next insn.
+void
+mjit_cancel_all(const char *reason)
+{
+ if (!mjit_enabled)
+ return;
+
+ mjit_call_p = false;
+ mjit_cancel_p = true;
+ if (mjit_opts.warnings || mjit_opts.verbose) {
+ fprintf(stderr, "JIT cancel: Disabled JIT-ed code because %s\n", reason);
+ }
+}
+
+// Deal with ISeq movement from compactor
+void
+mjit_update_references(const rb_iseq_t *iseq)
+{
+ if (!mjit_enabled)
+ return;
+
+ CRITICAL_SECTION_START(4, "mjit_update_references");
+ if (ISEQ_BODY(iseq)->mjit_unit) {
+ ISEQ_BODY(iseq)->mjit_unit->iseq = (rb_iseq_t *)rb_gc_location((VALUE)ISEQ_BODY(iseq)->mjit_unit->iseq);
+ // We need to invalidate JIT-ed code for the ISeq because it embeds pointer addresses.
+ // To efficiently do that, we use the same thing as TracePoint and thus everything is cancelled for now.
+ // See mjit.h and tool/ruby_vm/views/_mjit_compile_insn.erb for how `mjit_call_p` is used.
+ mjit_cancel_all("GC.compact is used"); // TODO: instead of cancelling all, invalidate only this one and recompile it with some threshold.
+ }
+
+ // Units in stale_units (list of over-speculated and invalidated code) are not referenced from
+ // `ISEQ_BODY(iseq)->mjit_unit` anymore (because new one replaces that). So we need to check them too.
+ // TODO: we should be able to reduce the number of units checked here.
+ struct rb_mjit_unit *unit = NULL;
+ ccan_list_for_each(&stale_units.head, unit, unode) {
+ if (unit->iseq == iseq) {
+ unit->iseq = (rb_iseq_t *)rb_gc_location((VALUE)unit->iseq);
+ }
+ }
+ CRITICAL_SECTION_FINISH(4, "mjit_update_references");
+}
+
+// Iseqs can be garbage collected. This function should call when it
+// happens. It removes iseq from the unit.
+void
+mjit_free_iseq(const rb_iseq_t *iseq)
+{
+ if (!mjit_enabled)
+ return;
+
+ if (ISEQ_BODY(iseq)->mjit_unit) {
+ // mjit_unit is not freed here because it may be referred by multiple
+ // lists of units. `get_from_list` and `mjit_finish` do the job.
+ ISEQ_BODY(iseq)->mjit_unit->iseq = NULL;
+ }
+ // Units in stale_units (list of over-speculated and invalidated code) are not referenced from
+ // `ISEQ_BODY(iseq)->mjit_unit` anymore (because new one replaces that). So we need to check them too.
+ // TODO: we should be able to reduce the number of units checked here.
+ struct rb_mjit_unit *unit = NULL;
+ ccan_list_for_each(&stale_units.head, unit, unode) {
+ if (unit->iseq == iseq) {
+ unit->iseq = NULL;
+ }
+ }
+}
+
+// Free unit list. This should be called only when worker is finished
+// because node of unit_queue and one of active_units may have the same unit
+// during proceeding unit.
+static void
+free_list(struct rb_mjit_unit_list *list, bool close_handle_p)
+{
+ struct rb_mjit_unit *unit = 0, *next;
+
+ ccan_list_for_each_safe(&list->head, unit, next, unode) {
+ ccan_list_del(&unit->unode);
+ if (!close_handle_p) unit->handle = NULL; /* Skip dlclose in free_unit() */
+
+ if (list == &stale_units) { // `free_unit(unit)` crashes after GC.compact on `stale_units`
+ /*
+ * TODO: REVERT THIS BRANCH
+ * Debug the crash on stale_units w/ GC.compact and just use `free_unit(unit)`!!
+ */
+ if (unit->handle && dlclose(unit->handle)) {
+ mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
+ }
+ xfree(unit);
+ }
+ else {
+ free_unit(unit);
+ }
+ }
+ list->length = 0;
+}
+
+static struct rb_mjit_unit*
+create_unit(enum rb_mjit_unit_type type)
+{
+ struct rb_mjit_unit *unit = ZALLOC_N(struct rb_mjit_unit, 1);
+ unit->id = current_unit_num++;
+ unit->type = type;
+ if (type == MJIT_UNIT_BATCH) {
+ ccan_list_head_init(&unit->units.head);
+ }
+ return unit;
+}
+
+static struct rb_mjit_unit*
+create_iseq_unit(const rb_iseq_t *iseq)
+{
+ struct rb_mjit_unit *unit = create_unit(MJIT_UNIT_ISEQ);
+ unit->iseq = (rb_iseq_t *)iseq;
+ ISEQ_BODY(iseq)->mjit_unit = unit;
+ return unit;
+}
+
+static void mjit_wait(struct rb_mjit_unit *unit);
+
+// Check the unit queue and start mjit_compile if nothing is in progress.
+static void
+check_unit_queue(void)
+{
+ if (mjit_opts.custom) return; // Custom RubyVM::MJIT.compile is in use
+ if (worker_stopped) return;
+ if (current_cc_pid != 0) return; // still compiling
+
+ // TODO: resurrect unload_units
+ if (active_units_length >= mjit_opts.max_cache_size) return; // wait until unload_units makes a progress
+
+ // No ISEQ in unit_queue has enough calls to trigger JIT
+ if (!mjit_compile_p) return;
+ mjit_compile_p = false;
+
+ // Compile all ISEQs in unit_queue together
+ struct rb_mjit_unit *unit = create_unit(MJIT_UNIT_BATCH);
+ struct rb_mjit_unit *child_unit = NULL;
+ VM_ASSERT(unit_queue.length > 0);
+ while ((child_unit = get_from_list(&unit_queue)) != NULL && (active_units_length + unit->units.length) < mjit_opts.max_cache_size) {
+ add_to_list(child_unit, &unit->units);
+ ISEQ_BODY(child_unit->iseq)->jit_func = (jit_func_t)MJIT_FUNC_COMPILING;
+ }
+
+ // Run the MJIT compiler synchronously
+ current_cc_ms = real_ms_time();
+ current_cc_unit = unit;
+ bool success = mjit_batch(unit);
+ if (!success) {
+ mjit_notify_waitpid(1);
+ return;
+ }
+
+ // Run the C compiler asynchronously (unless --mjit-wait)
+ if (mjit_opts.wait) {
+ int exit_code = c_compile_unit(unit);
+ mjit_notify_waitpid(exit_code);
+ }
+ else {
+ current_cc_pid = start_c_compile_unit(unit);
+ if (current_cc_pid == -1) { // JIT failure
+ mjit_notify_waitpid(1);
+ }
+ }
+}
+
+// Check if it should compact all JIT code and start it as needed
+static void
+check_compaction(void)
+{
+ // Allow only `max_cache_size / 100` times (default: 100) of compaction.
+ // Note: GC of compacted code has not been implemented yet.
+ int max_compact_size = mjit_opts.max_cache_size / 100;
+ if (max_compact_size < 10) max_compact_size = 10;
+
+ // Run JIT compaction only when it's going to add 10%+ units.
+ int throttle_threshold = active_units_length / 10;
+
+ if (compact_units.length < max_compact_size
+ && active_units_length - compact_units_length > throttle_threshold
+ && ((!mjit_opts.wait && unit_queue.length == 0 && active_units.length > 1)
+ || (active_units_length == mjit_opts.max_cache_size))) {
+ struct rb_mjit_unit *unit = create_unit(MJIT_UNIT_COMPACT);
+
+ // Run the MJIT compiler synchronously
+ current_cc_ms = real_ms_time();
+ current_cc_unit = unit;
+ bool success = mjit_compact(unit);
+ if (!success) {
+ mjit_notify_waitpid(1);
+ return;
+ }
+
+ // Run the C compiler asynchronously (unless --mjit-wait)
+ if (mjit_opts.wait) {
+ int exit_code = c_compile_unit(unit);
+ mjit_notify_waitpid(exit_code);
+ }
+ else {
+ current_cc_pid = start_c_compile_unit(unit);
+ if (current_cc_pid == -1) { // JIT failure
+ mjit_notify_waitpid(1);
+ }
+ }
+ }
+}
+
+// Check the current CC process if any, and start a next C compiler process as needed.
+void
+mjit_notify_waitpid(int exit_code)
+{
+ VM_ASSERT(mjit_opts.wait || current_cc_pid != 0);
+ current_cc_pid = 0;
+
+ // Delete .c file
+ char c_file[MAXPATHLEN];
+ sprint_uniq_filename(c_file, (int)sizeof(c_file), current_cc_unit->id, MJIT_TMP_PREFIX, ".c");
+
+ // Check the result
+ if (exit_code != 0) {
+ verbose(2, "Failed to generate so");
+ // TODO: set MJIT_FUNC_FAILED to unit->units
+ // TODO: free list of unit->units
+ free_unit(current_cc_unit);
+ current_cc_unit = NULL;
+ return;
+ }
+
+ // Load .so file
+ char so_file[MAXPATHLEN];
+ sprint_uniq_filename(so_file, (int)sizeof(so_file), current_cc_unit->id, MJIT_TMP_PREFIX, DLEXT);
+ switch (current_cc_unit->type) {
+ case MJIT_UNIT_ISEQ:
+ rb_bug("unreachable: current_cc_unit->type must not be MJIT_UNIT_ISEQ");
+ case MJIT_UNIT_BATCH:
+ load_batch_funcs_from_so(current_cc_unit, c_file, so_file);
+ current_cc_unit = NULL;
+
+ // Run compaction if it should
+ if (!stop_worker_p) {
+ check_compaction();
+ }
+ break;
+ case MJIT_UNIT_COMPACT:
+ load_compact_funcs_from_so(current_cc_unit, c_file, so_file);
+ current_cc_unit = NULL;
+ break;
+ }
+
+ // Skip further compilation if mjit_finish is trying to stop it
+ if (!stop_worker_p) {
+ // Start the next one as needed
+ check_unit_queue();
+ }
+}
+
+// Return true if given ISeq body should be compiled by MJIT
+static inline int
+mjit_target_iseq_p(const rb_iseq_t *iseq)
+{
+ struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
+ return (body->type == ISEQ_TYPE_METHOD || body->type == ISEQ_TYPE_BLOCK)
+ && !body->builtin_inline_p
+ && strcmp("<internal:mjit>", RSTRING_PTR(rb_iseq_path(iseq))) != 0;
+}
+
+// RubyVM::MJIT
+static VALUE rb_mMJIT = 0;
+// RubyVM::MJIT::C
+static VALUE rb_mMJITC = 0;
+// RubyVM::MJIT::Compiler
+static VALUE rb_cMJITCompiler = 0;
+// RubyVM::MJIT::CPointer::Struct_rb_iseq_t
+static VALUE rb_cMJITIseqPtr = 0;
+// RubyVM::MJIT::CPointer::Struct_IC
+static VALUE rb_cMJITICPtr = 0;
+// RubyVM::MJIT::Compiler
+static VALUE rb_mMJITHooks = 0;
+
+#define WITH_MJIT_DISABLED(stmt) do { \
+ bool original_call_p = mjit_call_p; \
+ mjit_call_p = false; \
+ stmt; \
+ mjit_call_p = original_call_p; \
+ if (mjit_cancel_p) mjit_call_p = false; \
+} while (0);
+
+// Hook MJIT when BOP is redefined.
+MJIT_FUNC_EXPORTED void
+rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ WITH_MJIT_DISABLED({
+ rb_funcall(rb_mMJITHooks, rb_intern("on_bop_redefined"), 2, INT2NUM(redefined_flag), INT2NUM((int)bop));
+ });
+}
+
+// Hook MJIT when CME is invalidated.
+MJIT_FUNC_EXPORTED void
+rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ WITH_MJIT_DISABLED({
+ VALUE cme_klass = rb_funcall(rb_mMJITC, rb_intern("rb_callable_method_entry_struct"), 0);
+ VALUE cme_ptr = rb_funcall(cme_klass, rb_intern("new"), 1, SIZET2NUM((size_t)cme));
+ rb_funcall(rb_mMJITHooks, rb_intern("on_cme_invalidate"), 1, cme_ptr);
+ });
+}
+
+// Hook MJIT when Ractor is spawned.
+void
+rb_mjit_before_ractor_spawn(void)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ WITH_MJIT_DISABLED({
+ rb_funcall(rb_mMJITHooks, rb_intern("on_ractor_spawn"), 0);
+ });
+}
+
+static void
+mjit_constant_state_changed(void *data)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ ID id = (ID)data;
+ WITH_MJIT_DISABLED({
+ rb_funcall(rb_mMJITHooks, rb_intern("on_constant_state_changed"), 1, ID2SYM(id));
+ });
+}
+
+// Hook MJIT when constant state is changed.
+MJIT_FUNC_EXPORTED void
+rb_mjit_constant_state_changed(ID id)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ // Asynchronously hook the Ruby code since this is hooked during a "Ruby critical section".
+ extern int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t func, void *data);
+ rb_workqueue_register(0, mjit_constant_state_changed, (void *)id);
+}
+
+// Hook MJIT when constant IC is updated.
+MJIT_FUNC_EXPORTED void
+rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ WITH_MJIT_DISABLED({
+ VALUE iseq_ptr = rb_funcall(rb_cMJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
+ VALUE ic_ptr = rb_funcall(rb_cMJITICPtr, rb_intern("new"), 1, SIZET2NUM((size_t)ic));
+ rb_funcall(rb_mMJITHooks, rb_intern("on_constant_ic_update"), 3, iseq_ptr, ic_ptr, UINT2NUM(insn_idx));
+ });
+}
+
+// Hook MJIT when TracePoint is enabled.
+MJIT_FUNC_EXPORTED void
+rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ WITH_MJIT_DISABLED({
+ rb_funcall(rb_mMJITHooks, rb_intern("on_tracing_invalidate_all"), 1, UINT2NUM(new_iseq_events));
+ });
+}
+
+// [experimental] Call custom RubyVM::MJIT.compile if defined
+static void
+mjit_hook_custom_compile(const rb_iseq_t *iseq)
+{
+ WITH_MJIT_DISABLED({
+ VALUE iseq_class = rb_funcall(rb_mMJITC, rb_intern("rb_iseq_t"), 0);
+ VALUE iseq_ptr = rb_funcall(iseq_class, rb_intern("new"), 1, ULONG2NUM((size_t)iseq));
+ VALUE jit_func = rb_funcall(rb_mMJIT, rb_intern("compile"), 1, iseq_ptr);
+ ISEQ_BODY(iseq)->jit_func = (jit_func_t)NUM2ULONG(jit_func);
+ });
+}
+
+static void
+mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_info *compile_info)
+{
+ if (!mjit_enabled) return;
+ if (mjit_opts.custom) { // Hook custom RubyVM::MJIT.compile if defined
+ mjit_hook_custom_compile(iseq);
+ return;
+ }
+ if (pch_status != PCH_SUCCESS || !rb_ractor_main_p()) // TODO: Support non-main Ractors
+ return;
+ if (!mjit_target_iseq_p(iseq)) {
+ ISEQ_BODY(iseq)->jit_func = (jit_func_t)MJIT_FUNC_FAILED; // skip mjit_wait
+ return;
+ }
+
+ // For batching multiple ISEQs, we only enqueue ISEQs when total_calls reaches call_threshold,
+ // and compile all enqueued ISEQs when any ISEQ reaches call_threshold * 2.
+ bool recompile_p = !MJIT_FUNC_STATE_P(ISEQ_BODY(iseq)->jit_func);
+ if (!ISEQ_BODY(iseq)->mjit_unit || recompile_p) { // call_threshold, or recompile
+ // Discard an old unit with recompile_p
+ if (recompile_p) {
+ ISEQ_BODY(iseq)->mjit_unit->iseq = NULL; // Ignore this from compaction
+ ISEQ_BODY(iseq)->jit_func = (jit_func_t)MJIT_FUNC_NOT_COMPILED;
+ active_units_length--;
+ }
+
+ // Create a new unit and enqueue it
+ struct rb_mjit_unit *unit = create_iseq_unit(iseq);
+ if (recompile_p) {
+ VM_ASSERT(compile_info != NULL);
+ unit->compile_info = *compile_info;
+ }
+ add_to_list(unit, &unit_queue);
+ ISEQ_BODY(iseq)->total_calls = 0; // come here again :)
+ }
+ else { // call_threshold * 2
+ VM_ASSERT(compile_info == NULL);
+ mjit_compile_p = true; // compile all ISEQs in unit_queue
+ }
+}
+
+// Add ISEQ to be JITed in parallel with the current thread.
+// Unload some JIT codes if there are too many of them.
+void
+rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq)
+{
+ mjit_add_iseq_to_process(iseq, NULL);
+ check_unit_queue();
+}
+
+// For this timeout seconds, mjit_finish will wait for JIT compilation finish.
+#define MJIT_WAIT_TIMEOUT_SECONDS 5
+
+static void
+mjit_wait(struct rb_mjit_unit *unit)
+{
+ pid_t initial_pid = current_cc_pid;
+ if (initial_pid == 0) {
+ mjit_warning("initial_pid was 0 on mjit_wait");
+ return;
+ }
+ if (pch_status == PCH_FAILED) return;
+
+ int tries = 0;
+ struct timeval tv = { .tv_sec = 0, .tv_usec = 1000 };
+ while (current_cc_pid == initial_pid) {
+ tries++;
+ if (tries / 1000 > MJIT_WAIT_TIMEOUT_SECONDS) {
+ if (unit->type == MJIT_UNIT_ISEQ) {
+ unit->iseq->body->jit_func = (jit_func_t)MJIT_FUNC_FAILED; // C compiler was too slow. Give up.
+ }
+ mjit_warning("timed out to wait for JIT finish");
+ break;
+ }
+
+ rb_thread_wait_for(tv);
+ }
+}
+
+struct rb_mjit_compile_info*
+rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body)
+{
+ VM_ASSERT(body->mjit_unit != NULL);
+ return &body->mjit_unit->compile_info;
+}
+
+static void
+mjit_recompile(const rb_iseq_t *iseq)
+{
+ if (MJIT_FUNC_STATE_P(ISEQ_BODY(iseq)->jit_func))
+ return;
+
+ verbose(1, "JIT recompile: %s@%s:%d", RSTRING_PTR(ISEQ_BODY(iseq)->location.label),
+ RSTRING_PTR(rb_iseq_path(iseq)), ISEQ_BODY(iseq)->location.first_lineno);
+ VM_ASSERT(ISEQ_BODY(iseq)->mjit_unit != NULL);
+
+ mjit_add_iseq_to_process(iseq, &ISEQ_BODY(iseq)->mjit_unit->compile_info);
+ check_unit_queue();
+}
+
+// Recompile iseq, disabling send optimization
+void
+rb_mjit_recompile_send(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(ISEQ_BODY(iseq))->disable_send_cache = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling ivar optimization
+void
+rb_mjit_recompile_ivar(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(ISEQ_BODY(iseq))->disable_ivar_cache = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling exivar optimization
+void
+rb_mjit_recompile_exivar(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(ISEQ_BODY(iseq))->disable_exivar_cache = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling method inlining
+void
+rb_mjit_recompile_inlining(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(ISEQ_BODY(iseq))->disable_inlining = true;
+ mjit_recompile(iseq);
+}
+
+// Recompile iseq, disabling getconstant inlining
+void
+rb_mjit_recompile_const(const rb_iseq_t *iseq)
+{
+ rb_mjit_iseq_compile_info(ISEQ_BODY(iseq))->disable_const_cache = true;
+ mjit_recompile(iseq);
+}
+
+extern VALUE ruby_archlibdir_path, ruby_prefix_path;
+
+// Initialize header_file, pch_file, libruby_pathflag. Return true on success.
+static bool
+init_header_filename(void)
+{
+ int fd;
+#ifdef LOAD_RELATIVE
+ // Root path of the running ruby process. Equal to RbConfig::TOPDIR.
+ VALUE basedir_val;
+#endif
+ const char *basedir = "";
+ size_t baselen = 0;
+ char *p;
+
+#ifdef LOAD_RELATIVE
+ basedir_val = ruby_prefix_path;
+ basedir = StringValuePtr(basedir_val);
+ baselen = RSTRING_LEN(basedir_val);
+#else
+ if (getenv("MJIT_SEARCH_BUILD_DIR")) {
+ // This path is not intended to be used on production, but using build directory's
+ // header file here because people want to run `make test-all` without running
+ // `make install`. Don't use $MJIT_SEARCH_BUILD_DIR except for test-all.
+
+ struct stat st;
+ const char *hdr = dlsym(RTLD_DEFAULT, "MJIT_HEADER");
+ if (!hdr) {
+ verbose(1, "No MJIT_HEADER");
+ }
+ else if (hdr[0] != '/') {
+ verbose(1, "Non-absolute header file path: %s", hdr);
+ }
+ else if (stat(hdr, &st) || !S_ISREG(st.st_mode)) {
+ verbose(1, "Non-file header file path: %s", hdr);
+ }
+ else if ((st.st_uid != getuid()) || (st.st_mode & 022) ||
+ !rb_path_check(hdr)) {
+ verbose(1, "Unsafe header file: uid=%ld mode=%#o %s",
+ (long)st.st_uid, (unsigned)st.st_mode, hdr);
+ return FALSE;
+ }
+ else {
+ // Do not pass PRELOADENV to child processes, on
+ // multi-arch environment
+ verbose(3, "PRELOADENV("PRELOADENV")=%s", getenv(PRELOADENV));
+ // assume no other PRELOADENV in test-all
+ unsetenv(PRELOADENV);
+ verbose(3, "MJIT_HEADER: %s", hdr);
+ header_file = ruby_strdup(hdr);
+ if (!header_file) return false;
+ }
+ }
+ else
+#endif
+ {
+ // A name of the header file included in any C file generated by MJIT for iseqs.
+ static const char header_name[] = MJIT_HEADER_INSTALL_DIR "/" MJIT_MIN_HEADER_NAME;
+ const size_t header_name_len = sizeof(header_name) - 1;
+
+ header_file = xmalloc(baselen + header_name_len + 1);
+ p = append_str2(header_file, basedir, baselen);
+ p = append_str2(p, header_name, header_name_len + 1);
+
+ if ((fd = rb_cloexec_open(header_file, O_RDONLY, 0)) < 0) {
+ verbose(1, "Cannot access header file: %s", header_file);
+ xfree(header_file);
+ header_file = NULL;
+ return false;
+ }
+ (void)close(fd);
+ }
+
+ pch_file = get_uniq_filename(0, MJIT_TMP_PREFIX "h", ".h.gch");
+
+ return true;
+}
+
+static char *
+system_default_tmpdir(void)
+{
+ // c.f. ext/etc/etc.c:etc_systmpdir()
+#if defined _CS_DARWIN_USER_TEMP_DIR
+ char path[MAXPATHLEN];
+ size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
+ if (len > 0) {
+ char *tmpdir = xmalloc(len);
+ if (len > sizeof(path)) {
+ confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, len);
+ }
+ else {
+ memcpy(tmpdir, path, len);
+ }
+ return tmpdir;
+ }
+#endif
+ return 0;
+}
+
+static int
+check_tmpdir(const char *dir)
+{
+ struct stat st;
+
+ if (!dir) return FALSE;
+ if (stat(dir, &st)) return FALSE;
+#ifndef S_ISDIR
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+ if (!S_ISDIR(st.st_mode)) return FALSE;
+#ifndef S_IWOTH
+# define S_IWOTH 002
+#endif
+ if (st.st_mode & S_IWOTH) {
+#ifdef S_ISVTX
+ if (!(st.st_mode & S_ISVTX)) return FALSE;
+#else
+ return FALSE;
+#endif
+ }
+ if (access(dir, W_OK)) return FALSE;
+ return TRUE;
+}
+
+static char *
+system_tmpdir(void)
+{
+ char *tmpdir;
+# define RETURN_ENV(name) \
+ if (check_tmpdir(tmpdir = getenv(name))) return ruby_strdup(tmpdir)
+ RETURN_ENV("TMPDIR");
+ RETURN_ENV("TMP");
+ tmpdir = system_default_tmpdir();
+ if (check_tmpdir(tmpdir)) return tmpdir;
+ return ruby_strdup("/tmp");
+# undef RETURN_ENV
+}
+
+// Minimum value for JIT cache size.
+#define MIN_CACHE_SIZE 10
+// Default permitted number of units with a JIT code kept in memory.
+#define DEFAULT_MAX_CACHE_SIZE 100
+// A default threshold used to add iseq to JIT.
+#define DEFAULT_CALL_THRESHOLD 10000
+
+// Start MJIT worker. Return TRUE if worker is successfully started.
+static bool
+start_worker(void)
+{
+ stop_worker_p = false;
+ worker_stopped = false;
+ return true;
+}
+
+// There's no strndup on Windows
+static char*
+ruby_strndup(const char *str, size_t n)
+{
+ char *ret = xmalloc(n + 1);
+ memcpy(ret, str, n);
+ ret[n] = '\0';
+ return ret;
+}
+
+// Convert "foo bar" to {"foo", "bar", NULL} array. Caller is responsible for
+// freeing a returned buffer and its elements.
+static char **
+split_flags(const char *flags)
+{
+ char *buf[MAXPATHLEN];
+ int i = 0;
+ char *next;
+ for (; flags != NULL; flags = next) {
+ next = strchr(flags, ' ');
+ if (next == NULL) {
+ if (strlen(flags) > 0)
+ buf[i++] = strdup(flags);
+ }
+ else {
+ if (next > flags)
+ buf[i++] = ruby_strndup(flags, next - flags);
+ next++; // skip space
+ }
+ }
+
+ char **ret = xmalloc(sizeof(char *) * (i + 1));
+ memcpy(ret, buf, sizeof(char *) * i);
+ ret[i] = NULL;
+ return ret;
+}
+
+#define opt_match_noarg(s, l, name) \
+ opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --mjit-" name " is ignored"), 1) : 1)
+#define opt_match_arg(s, l, name) \
+ opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--mjit-" name " needs an argument"), 0))
+
+void
+mjit_setup_options(const char *s, struct mjit_options *mjit_opt)
+{
+ const size_t l = strlen(s);
+ if (l == 0) {
+ return;
+ }
+ else if (opt_match_noarg(s, l, "warnings")) {
+ mjit_opt->warnings = true;
+ }
+ else if (opt_match(s, l, "debug")) {
+ if (*s)
+ mjit_opt->debug_flags = strdup(s + 1);
+ else
+ mjit_opt->debug = true;
+ }
+ else if (opt_match_noarg(s, l, "wait")) {
+ mjit_opt->wait = true;
+ }
+ else if (opt_match_noarg(s, l, "save-temps")) {
+ mjit_opt->save_temps = true;
+ }
+ else if (opt_match(s, l, "verbose")) {
+ mjit_opt->verbose = *s ? atoi(s + 1) : 1;
+ }
+ else if (opt_match_arg(s, l, "max-cache")) {
+ mjit_opt->max_cache_size = atoi(s + 1);
+ }
+ else if (opt_match_arg(s, l, "call-threshold")) {
+ mjit_opt->call_threshold = atoi(s + 1);
+ }
+ // --mjit=pause is an undocumented feature for experiments
+ else if (opt_match_noarg(s, l, "pause")) {
+ mjit_opt->pause = true;
+ }
+ else {
+ rb_raise(rb_eRuntimeError,
+ "invalid MJIT option `%s' (--help will show valid MJIT options)", s);
+ }
+}
+
+#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc)
+const struct ruby_opt_message mjit_option_messages[] = {
+ M("--mjit-warnings", "", "Enable printing JIT warnings"),
+ M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
+ M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
+ M("--mjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
+ M("--mjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
+ M("--mjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: "
+ STRINGIZE(DEFAULT_MAX_CACHE_SIZE) ")"),
+ M("--mjit-call-threshold=num", "", "Number of calls to trigger JIT (for testing, default: "
+ STRINGIZE(DEFAULT_CALL_THRESHOLD) ")"),
+ {0}
+};
+#undef M
+
+// Initialize MJIT. Start a thread creating the precompiled header and
+// processing ISeqs. The function should be called first for using MJIT.
+// If everything is successful, MJIT_INIT_P will be TRUE.
+void
+mjit_init(const struct mjit_options *opts)
+{
+ VM_ASSERT(mjit_enabled);
+ mjit_opts = *opts;
+
+ // MJIT doesn't support miniruby, but it might reach here by MJIT_FORCE_ENABLE.
+ rb_mMJIT = rb_const_get(rb_cRubyVM, rb_intern("MJIT"));
+ if (!rb_const_defined(rb_mMJIT, rb_intern("Compiler"))) {
+ verbose(1, "Disabling MJIT because RubyVM::MJIT::Compiler is not defined");
+ mjit_enabled = false;
+ return;
+ }
+ rb_mMJITC = rb_const_get(rb_mMJIT, rb_intern("C"));
+ rb_cMJITCompiler = rb_funcall(rb_const_get(rb_mMJIT, rb_intern("Compiler")), rb_intern("new"), 0);
+ rb_cMJITIseqPtr = rb_funcall(rb_mMJITC, rb_intern("rb_iseq_t"), 0);
+ rb_cMJITICPtr = rb_funcall(rb_mMJITC, rb_intern("IC"), 0);
+ rb_funcall(rb_cMJITICPtr, rb_intern("new"), 1, SIZET2NUM(0)); // Trigger no-op constant events before enabling hooks
+ rb_mMJITHooks = rb_const_get(rb_mMJIT, rb_intern("Hooks"));
+
+ mjit_call_p = true;
+ mjit_pid = getpid();
+
+ // Normalize options
+ if (mjit_opts.call_threshold == 0)
+ mjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD;
+ if (mjit_opts.call_threshold % 2 == 1) {
+ mjit_opts.call_threshold += 1;
+ mjit_warning("--mjit-call-threshold must be an even number. Using %d instead.", mjit_opts.call_threshold);
+ }
+ mjit_opts.call_threshold /= 2; // Half for enqueue, half for trigger
+ if (mjit_opts.max_cache_size <= 0)
+ mjit_opts.max_cache_size = DEFAULT_MAX_CACHE_SIZE;
+ if (mjit_opts.max_cache_size < MIN_CACHE_SIZE)
+ mjit_opts.max_cache_size = MIN_CACHE_SIZE;
+
+ // Initialize variables for compilation
+ pch_status = PCH_NOT_READY;
+ cc_path = CC_COMMON_ARGS[0];
+ verbose(2, "MJIT: CC defaults to %s", cc_path);
+ cc_common_args = xmalloc(sizeof(CC_COMMON_ARGS));
+ memcpy((void *)cc_common_args, CC_COMMON_ARGS, sizeof(CC_COMMON_ARGS));
+ cc_added_args = split_flags(opts->debug_flags);
+ xfree(opts->debug_flags);
+#if MJIT_CFLAGS_PIPE
+ // Filter out `-save-temps`. It's a C compiler flag used by update-deps and not compatible with `-pipe`.
+ for (size_t i = 0, j = 0; i < sizeof(CC_COMMON_ARGS) / sizeof(char *); i++) {
+ if (CC_COMMON_ARGS[i] && strncmp("-save-temps", CC_COMMON_ARGS[i], strlen("-save-temps")) == 0)
+ continue; // Skip `-save-temps`
+ cc_common_args[j] = CC_COMMON_ARGS[i];
+ j++;
+ }
+#endif
+
+ tmp_dir = system_tmpdir();
+ verbose(2, "MJIT: tmp_dir is %s", tmp_dir);
+
+ if (!init_header_filename()) {
+ mjit_enabled = false;
+ verbose(1, "Failure in MJIT header file name initialization\n");
+ return;
+ }
+ pch_owner_pid = getpid();
+
+ // Initialize mutex
+ rb_native_mutex_initialize(&mjit_engine_mutex);
+
+ // If --mjit=pause is given, lazily start MJIT when RubyVM::MJIT.resume is called.
+ // You can use it to control MJIT warmup, or to customize the JIT implementation.
+ if (!mjit_opts.pause) {
+ // TODO: Consider running C compiler asynchronously
+ make_pch();
+
+ // Enable MJIT compilation
+ start_worker();
+ }
+}
+
+static void
+stop_worker(void)
+{
+ stop_worker_p = true;
+ if (current_cc_unit != NULL) {
+ mjit_wait(current_cc_unit);
+ }
+ worker_stopped = true;
+}
+
+// Stop JIT-compiling methods but compiled code is kept available.
+VALUE
+mjit_pause(bool wait_p)
+{
+ if (!mjit_enabled) {
+ rb_raise(rb_eRuntimeError, "MJIT is not enabled");
+ }
+ if (worker_stopped) {
+ return Qfalse;
+ }
+
+ // Flush all queued units with no option or `wait: true`
+ if (wait_p) {
+ while (current_cc_unit != NULL) {
+ mjit_wait(current_cc_unit);
+ }
+ }
+
+ stop_worker();
+ return Qtrue;
+}
+
+// Restart JIT-compiling methods after mjit_pause.
+VALUE
+mjit_resume(void)
+{
+ if (!mjit_enabled) {
+ rb_raise(rb_eRuntimeError, "MJIT is not enabled");
+ }
+ if (!worker_stopped) {
+ return Qfalse;
+ }
+
+ // Lazily prepare PCH when --mjit=pause is given
+ if (pch_status == PCH_NOT_READY) {
+ if (rb_respond_to(rb_mMJIT, rb_intern("compile"))) {
+ // [experimental] defining RubyVM::MJIT.compile allows you to replace JIT
+ mjit_opts.custom = true;
+ pch_status = PCH_SUCCESS;
+ }
+ else {
+ // Lazy MJIT boot
+ make_pch();
+ }
+ }
+
+ if (!start_worker()) {
+ rb_raise(rb_eRuntimeError, "Failed to resume MJIT worker");
+ }
+ return Qtrue;
+}
+
+// This is called after fork initiated by Ruby's method to launch MJIT worker thread
+// for child Ruby process.
+//
+// In multi-process Ruby applications, child Ruby processes do most of the jobs.
+// Thus we want child Ruby processes to enqueue ISeqs to MJIT worker's queue and
+// call the JIT-ed code.
+//
+// But unfortunately current MJIT-generated code is process-specific. After the fork,
+// JIT-ed code created by parent Ruby process cannot be used in child Ruby process
+// because the code could rely on inline cache values (ivar's IC, send's CC) which
+// may vary between processes after fork or embed some process-specific addresses.
+//
+// So child Ruby process can't request parent process to JIT an ISeq and use the code.
+// Instead of that, MJIT worker thread is created for all child Ruby processes, even
+// while child processes would end up with compiling the same ISeqs.
+void
+mjit_child_after_fork(void)
+{
+ if (!mjit_enabled)
+ return;
+
+ /* MJIT worker thread is not inherited on fork. Start it for this child process. */
+ start_worker();
+}
+
+// Finish the threads processing units and creating PCH, finalize
+// and free MJIT data. It should be called last during MJIT
+// life.
+//
+// If close_handle_p is true, it calls dlclose() for JIT-ed code. So it should be false
+// if the code can still be on stack. ...But it means to leak JIT-ed handle forever (FIXME).
+void
+mjit_finish(bool close_handle_p)
+{
+ if (!mjit_enabled)
+ return;
+
+ // Stop worker
+ verbose(2, "Stopping worker thread");
+ stop_worker();
+
+ rb_native_mutex_destroy(&mjit_engine_mutex);
+
+ if (!mjit_opts.save_temps && getpid() == pch_owner_pid && pch_status == PCH_SUCCESS && !mjit_opts.custom)
+ remove_file(pch_file);
+
+ xfree(header_file); header_file = NULL;
+ xfree((void *)cc_common_args); cc_common_args = NULL;
+ for (char **flag = cc_added_args; *flag != NULL; flag++)
+ xfree(*flag);
+ xfree((void *)cc_added_args); cc_added_args = NULL;
+ xfree(tmp_dir); tmp_dir = NULL;
+ xfree(pch_file); pch_file = NULL;
+
+ mjit_call_p = false;
+ free_list(&unit_queue, close_handle_p);
+ free_list(&active_units, close_handle_p);
+ free_list(&compact_units, close_handle_p);
+ free_list(&stale_units, close_handle_p);
+
+ mjit_enabled = false;
+ verbose(1, "Successful MJIT finish");
+}
+
+// Called by rb_vm_mark().
+//
+// Mark active_units so that we do not GC ISeq which may still be
+// referenced by mjit_recompile() or mjit_compact().
+void
+mjit_mark(void)
+{
+ if (!mjit_enabled)
+ return;
+ RUBY_MARK_ENTER("mjit");
+
+ // Mark objects used by the MJIT compiler
+ rb_gc_mark(rb_cMJITCompiler);
+ rb_gc_mark(rb_cMJITIseqPtr);
+ rb_gc_mark(rb_cMJITICPtr);
+ rb_gc_mark(rb_mMJITHooks);
+
+ // Mark JIT-compiled ISEQs
+ struct rb_mjit_unit *unit = NULL;
+ ccan_list_for_each(&active_units.head, unit, unode) {
+ rb_gc_mark((VALUE)unit->iseq);
+ }
+
+ RUBY_MARK_LEAVE("mjit");
+}
+
+// Called by rb_iseq_mark() to mark cc_entries captured for MJIT
+void
+mjit_mark_cc_entries(const struct rb_iseq_constant_body *const body)
+{
+ const struct rb_callcache **cc_entries;
+ if (body->mjit_unit && (cc_entries = body->mjit_unit->cc_entries) != NULL) {
+ // It must be `body->mjit_unit->cc_entries_size` instead of `body->ci_size` to mark children's cc_entries
+ for (unsigned int i = 0; i < body->mjit_unit->cc_entries_size; i++) {
+ const struct rb_callcache *cc = cc_entries[i];
+ if (cc != NULL && vm_cc_markable(cc)) {
+ // Pin `cc` and `cc->cme` against GC.compact as their addresses may be written in JIT-ed code.
+ rb_gc_mark((VALUE)cc);
+ rb_gc_mark((VALUE)vm_cc_cme(cc));
+ }
+ }
+ }
+}
+
+// Compile ISeq to C code in `f`. It returns true if it succeeds to compile.
+bool
+mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
+{
+ bool original_call_p = mjit_call_p;
+ mjit_call_p = false; // Avoid impacting JIT metrics by itself
+
+ VALUE iseq_ptr = rb_funcall(rb_cMJITIseqPtr, rb_intern("new"), 1, ULONG2NUM((size_t)iseq));
+ VALUE src = rb_funcall(rb_cMJITCompiler, rb_intern("compile"), 3,
+ iseq_ptr, rb_str_new_cstr(funcname), INT2NUM(id));
+ if (!NIL_P(src)) {
+ fprintf(f, "%s", RSTRING_PTR(src));
+ }
+
+ mjit_call_p = original_call_p;
+ return !NIL_P(src);
+}
+
+#include "mjit.rbinc"
+
+#endif // USE_MJIT
diff --git a/mjit.h b/mjit.h
new file mode 100644
index 0000000000..260cf4af78
--- /dev/null
+++ b/mjit.h
@@ -0,0 +1,145 @@
+#ifndef RUBY_MJIT_H
+#define RUBY_MJIT_H 1
+/**********************************************************************
+
+ mjit.h - Interface to MRI method JIT compiler
+
+ Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
+ Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
+
+**********************************************************************/
+
+#include "ruby/internal/config.h" // defines USE_MJIT
+#include "ruby/internal/stdbool.h"
+#include "vm_core.h"
+
+# if USE_MJIT
+
+#include "ruby.h"
+#include "vm_core.h"
+
+// Special address values of a function generated from the
+// corresponding iseq by MJIT:
+enum rb_mjit_func_state {
+ // ISEQ has not been compiled yet
+ MJIT_FUNC_NOT_COMPILED = 0,
+ // ISEQ is already queued for the machine code generation but the
+ // code is not ready yet for the execution
+ MJIT_FUNC_COMPILING = 1,
+ // ISEQ included not compilable insn, some internal assertion failed
+ // or the unit is unloaded
+ MJIT_FUNC_FAILED = 2,
+};
+// Return true if jit_func is part of enum rb_mjit_func_state
+#define MJIT_FUNC_STATE_P(jit_func) ((uintptr_t)(jit_func) <= (uintptr_t)MJIT_FUNC_FAILED)
+
+// MJIT options which can be defined on the MRI command line.
+struct mjit_options {
+ // Converted from "jit" feature flag to tell the enablement
+ // information to ruby_show_version().
+ bool on;
+ // Save temporary files after MRI finish. The temporary files
+ // include the pre-compiled header, C code file generated for ISEQ,
+ // and the corresponding object file.
+ bool save_temps;
+ // Print MJIT warnings to stderr.
+ bool warnings;
+ // Disable compiler optimization and add debug symbols. It can be
+ // very slow.
+ bool debug;
+ // Add arbitrary cflags.
+ char* debug_flags;
+ // If true, all ISeqs are synchronously compiled. For testing.
+ bool wait;
+ // Number of calls to trigger JIT compilation. For testing.
+ unsigned int call_threshold;
+ // Force printing info about MJIT work of level VERBOSE or
+ // less. 0=silence, 1=medium, 2=verbose.
+ int verbose;
+ // Maximal permitted number of iseq JIT codes in a MJIT memory
+ // cache.
+ int max_cache_size;
+ // [experimental] Do not start MJIT until MJIT.resume is called.
+ bool pause;
+ // [experimental] Call custom RubyVM::MJIT.compile instead of MJIT.
+ bool custom;
+};
+
+// State of optimization switches
+struct rb_mjit_compile_info {
+ // Disable getinstancevariable/setinstancevariable optimizations based on inline cache (T_OBJECT)
+ bool disable_ivar_cache;
+ // Disable getinstancevariable/setinstancevariable optimizations based on inline cache (FL_EXIVAR)
+ bool disable_exivar_cache;
+ // Disable send/opt_send_without_block optimizations based on inline cache
+ bool disable_send_cache;
+ // Disable method inlining
+ bool disable_inlining;
+ // Disable opt_getinlinecache inlining
+ bool disable_const_cache;
+};
+
+typedef VALUE (*jit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
+
+RUBY_SYMBOL_EXPORT_BEGIN
+RUBY_EXTERN struct mjit_options mjit_opts;
+RUBY_EXTERN bool mjit_call_p;
+
+extern void rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq);
+extern struct rb_mjit_compile_info* rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body);
+extern void rb_mjit_recompile_send(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_ivar(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_exivar(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_inlining(const rb_iseq_t *iseq);
+extern void rb_mjit_recompile_const(const rb_iseq_t *iseq);
+RUBY_SYMBOL_EXPORT_END
+
+extern void mjit_cancel_all(const char *reason);
+extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
+extern void mjit_init(const struct mjit_options *opts);
+extern void mjit_free_iseq(const rb_iseq_t *iseq);
+extern void mjit_update_references(const rb_iseq_t *iseq);
+extern void mjit_mark(void);
+extern void mjit_mark_cc_entries(const struct rb_iseq_constant_body *const body);
+extern void mjit_notify_waitpid(int exit_code);
+
+extern void rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
+extern void rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme);
+extern void rb_mjit_before_ractor_spawn(void);
+extern void rb_mjit_constant_state_changed(ID id);
+extern void rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx);
+extern void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
+
+void mjit_child_after_fork(void);
+
+# ifdef MJIT_HEADER
+#define mjit_enabled true
+# else // MJIT_HEADER
+extern bool mjit_enabled;
+# endif // MJIT_HEADER
+VALUE mjit_pause(bool wait_p);
+VALUE mjit_resume(void);
+void mjit_finish(bool close_handle_p);
+
+# else // USE_MJIT
+
+static inline void mjit_cancel_all(const char *reason){}
+static inline void mjit_free_iseq(const rb_iseq_t *iseq){}
+static inline void mjit_mark(void){}
+static inline VALUE jit_exec(rb_execution_context_t *ec) { return Qundef; /* unreachable */ }
+static inline void mjit_child_after_fork(void){}
+
+static inline void rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
+static inline void rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
+static inline void rb_mjit_before_ractor_spawn(void) {}
+static inline void rb_mjit_constant_state_changed(ID id) {}
+static inline void rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx) {}
+static inline void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events) {}
+
+#define mjit_enabled false
+static inline VALUE mjit_pause(bool wait_p){ return Qnil; } // unreachable
+static inline VALUE mjit_resume(void){ return Qnil; } // unreachable
+static inline void mjit_finish(bool close_handle_p){}
+
+# endif // USE_MJIT
+#endif // RUBY_MJIT_H
diff --git a/mjit.rb b/mjit.rb
new file mode 100644
index 0000000000..717ab832a4
--- /dev/null
+++ b/mjit.rb
@@ -0,0 +1,37 @@
+module RubyVM::MJIT
+ # Return true if MJIT is enabled.
+ def self.enabled?
+ Primitive.cexpr! 'RBOOL(mjit_enabled)'
+ end
+
+ # Stop generating JITed code.
+ def self.pause(wait: true)
+ Primitive.cexpr! 'mjit_pause(RTEST(wait))'
+ end
+
+ # Start generating JITed code again after pause.
+ def self.resume
+ Primitive.cexpr! 'mjit_resume()'
+ end
+end
+
+if RubyVM::MJIT.enabled?
+ begin
+ require 'fiddle'
+ require 'fiddle/import'
+ rescue LoadError
+ return # miniruby doesn't support MJIT
+ end
+
+ # forward declaration for ruby_vm/mjit/compiler
+ RubyVM::MJIT::C = Object.new # :nodoc:
+
+ require 'ruby_vm/mjit/c_type'
+ require 'ruby_vm/mjit/instruction'
+ require 'ruby_vm/mjit/compiler'
+ require 'ruby_vm/mjit/hooks'
+
+ module RubyVM::MJIT
+ private_constant(*constants)
+ end
+end
diff --git a/mjit_c.c b/mjit_c.c
new file mode 100644
index 0000000000..9ba023e84b
--- /dev/null
+++ b/mjit_c.c
@@ -0,0 +1,43 @@
+/**********************************************************************
+
+ mjit_c.c - C helpers for MJIT
+
+ Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
+
+**********************************************************************/
+
+#include "ruby/internal/config.h" // defines USE_MJIT
+
+#if USE_MJIT
+
+#include "mjit.h"
+#include "mjit_c.h"
+#include "internal.h"
+#include "internal/compile.h"
+#include "internal/hash.h"
+#include "yjit.h"
+#include "vm_insnhelper.h"
+
+#include "insns.inc"
+#include "insns_info.inc"
+
+#include "mjit_sp_inc.inc"
+
+#if SIZEOF_LONG == SIZEOF_VOIDP
+#define NUM2PTR(x) NUM2ULONG(x)
+#define PTR2NUM(x) ULONG2NUM(x)
+#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
+#define NUM2PTR(x) NUM2ULL(x)
+#define PTR2NUM(x) ULL2NUM(x)
+#endif
+
+// An offsetof implementation that works for unnamed struct and union.
+// Multiplying 8 for compatibility with libclang's offsetof.
+#define OFFSETOF(ptr, member) RB_SIZE2NUM(((char *)&ptr.member - (char*)&ptr) * 8)
+
+#define SIZEOF(type) RB_SIZE2NUM(sizeof(type))
+#define SIGNED_TYPE_P(type) RBOOL((type)(-1) < (type)(1))
+
+#include "mjit_c.rbinc"
+
+#endif // USE_MJIT
diff --git a/mjit_c.h b/mjit_c.h
new file mode 100644
index 0000000000..cc4040c9df
--- /dev/null
+++ b/mjit_c.h
@@ -0,0 +1,97 @@
+// This file is parsed by tool/mjit/generate.rb to generate mjit_c.rb
+#ifndef MJIT_C_H
+#define MJIT_C_H
+
+#include "ruby/internal/config.h"
+#include "vm_core.h"
+#include "vm_callinfo.h"
+#include "builtin.h"
+#include "ccan/list/list.h"
+#include "mjit.h"
+#include "shape.h"
+
+// Macros to check if a position is already compiled using compile_status.stack_size_for_pos
+#define NOT_COMPILED_STACK_SIZE -1
+#define ALREADY_COMPILED_P(status, pos) (status->stack_size_for_pos[pos] != NOT_COMPILED_STACK_SIZE)
+
+// Linked list of struct rb_mjit_unit.
+struct rb_mjit_unit_list {
+ struct ccan_list_head head;
+ int length; // the list length
+};
+
+enum rb_mjit_unit_type {
+ // Single-ISEQ unit for unit_queue
+ MJIT_UNIT_ISEQ = 0,
+ // Multi-ISEQ unit for mjit_batch
+ MJIT_UNIT_BATCH = 1,
+ // All-ISEQ unit for mjit_compact
+ MJIT_UNIT_COMPACT = 2,
+};
+
+// The unit structure that holds metadata of ISeq for MJIT.
+// TODO: Use different structs for ISEQ and BATCH/COMPACT
+struct rb_mjit_unit {
+ struct ccan_list_node unode;
+ // Unique order number of unit.
+ int id;
+ // Type of this unit
+ enum rb_mjit_unit_type type;
+
+ /* MJIT_UNIT_ISEQ */
+ // ISEQ for a non-batch unit
+ rb_iseq_t *iseq;
+ // Only used by unload_units. Flag to check this unit is currently on stack or not.
+ bool used_code_p;
+ // mjit_compile's optimization switches
+ struct rb_mjit_compile_info compile_info;
+ // captured CC values, they should be marked with iseq.
+ const struct rb_callcache **cc_entries;
+ // ISEQ_BODY(iseq)->ci_size + ones of inlined iseqs
+ unsigned int cc_entries_size;
+
+ /* MJIT_UNIT_BATCH, MJIT_UNIT_COMPACT */
+ // Dlopen handle of the loaded object file.
+ void *handle;
+ // Units compacted by this batch
+ struct rb_mjit_unit_list units; // MJIT_UNIT_BATCH only
+};
+
+// Storage to keep data which is consistent in each conditional branch.
+// This is created and used for one `compile_insns` call and its values
+// should be copied for extra `compile_insns` call.
+struct compile_branch {
+ unsigned int stack_size; // this simulates sp (stack pointer) of YARV
+ bool finish_p; // if true, compilation in this branch should stop and let another branch to be compiled
+};
+
+// For propagating information needed for lazily pushing a frame.
+struct inlined_call_context {
+ int orig_argc; // ci->orig_argc
+ VALUE me; // vm_cc_cme(cc)
+ int param_size; // def_iseq_ptr(vm_cc_cme(cc)->def)->body->param.size
+ int local_size; // def_iseq_ptr(vm_cc_cme(cc)->def)->body->local_table_size
+};
+
+// Storage to keep compiler's status. This should have information
+// which is global during one `mjit_compile` call. Ones conditional
+// in each branch should be stored in `compile_branch`.
+struct compile_status {
+ bool success; // has true if compilation has had no issue
+ int *stack_size_for_pos; // stack_size_for_pos[pos] has stack size for the position (otherwise -1)
+ // If true, JIT-ed code will use local variables to store pushed values instead of
+ // using VM's stack and moving stack pointer.
+ bool local_stack_p;
+ // Index of call cache entries captured to compiled_iseq to be marked on GC
+ int cc_entries_index;
+ // A pointer to root (i.e. not inlined) iseq being compiled.
+ const struct rb_iseq_constant_body *compiled_iseq;
+ int compiled_id; // Just a copy of compiled_iseq->jit_unit->id
+ // Mutated optimization levels
+ struct rb_mjit_compile_info *compile_info;
+ // If `inlined_iseqs[pos]` is not NULL, `mjit_compile_body` tries to inline ISeq there.
+ const struct rb_iseq_constant_body **inlined_iseqs;
+ struct inlined_call_context inline_context;
+};
+
+#endif /* MJIT_C_H */
diff --git a/mjit_c.rb b/mjit_c.rb
new file mode 100644
index 0000000000..966289c5ab
--- /dev/null
+++ b/mjit_c.rb
@@ -0,0 +1,807 @@
+# frozen_string_literal: true
+# Part of this file is generated by tool/mjit/bindgen.rb.
+# Run `make mjit-bindgen` to update code between "MJIT bindgen begin" and "MJIT bindgen end".
+module RubyVM::MJIT # :nodoc: all
+ # This `class << C` section is for calling C functions. For importing variables
+ # or macros as is, please consider using tool/mjit/bindgen.rb instead.
+ class << C
+ def rb_hash_values(cdhash_addr)
+ Primitive.cexpr! 'rb_hash_values((VALUE)NUM2PTR(cdhash_addr))'
+ end
+
+ def builtin_compiler(buf, bf_ptr, index, stack_size, builtin_inline_p)
+ _bf_addr = bf_ptr.to_i
+ # Call "mjit_compile_invokebuiltin_for_#{func}" in mk_builtin_loader.rb
+ Primitive.cstmt! %{
+ RB_BUILTIN bf = (RB_BUILTIN)NUM2PTR(_bf_addr);
+ bf->compiler(buf, NIL_P(index) ? -1 : NUM2LONG(index), NUM2UINT(stack_size), RTEST(builtin_inline_p));
+ return Qnil;
+ }
+ end
+
+ def has_cache_for_send(cc_ptr, insn)
+ _cc_addr = cc_ptr.to_i
+ Primitive.cstmt! %{
+ extern bool rb_vm_opt_cfunc_p(CALL_CACHE cc, int insn);
+ CALL_CACHE cc = (CALL_CACHE)NUM2PTR(_cc_addr);
+ bool has_cache = vm_cc_cme(cc) != NULL &&
+ !(vm_cc_cme(cc)->def->type == VM_METHOD_TYPE_CFUNC && rb_vm_opt_cfunc_p(cc, NUM2INT(insn)));
+ return RBOOL(has_cache);
+ }
+ end
+
+ def rb_shape_get_shape_by_id(shape_id)
+ _shape_id = shape_id.to_i
+ shape_addr = Primitive.cexpr! 'PTR2NUM((VALUE)rb_shape_get_shape_by_id((shape_id_t)NUM2UINT(_shape_id)))'
+ rb_shape_t.new(shape_addr)
+ end
+
+ def rb_iseq_check(iseq)
+ _iseq_addr = iseq.to_i
+ iseq_addr = Primitive.cexpr! 'PTR2NUM((VALUE)rb_iseq_check((rb_iseq_t *)NUM2PTR(_iseq_addr)))'
+ rb_iseq_t.new(iseq_addr)
+ end
+
+ def rb_iseq_path(iseq)
+ _iseq_addr = iseq.to_i
+ Primitive.cexpr! 'rb_iseq_path((rb_iseq_t *)NUM2PTR(_iseq_addr))'
+ end
+
+ def rb_iseq_first_lineno(iseq)
+ _iseq_addr = iseq.to_i
+ Primitive.cexpr! 'rb_iseq_first_lineno((rb_iseq_t *)NUM2PTR(_iseq_addr))'
+ end
+
+ def vm_ci_argc(ci)
+ _ci_addr = ci.to_i
+ Primitive.cexpr! 'UINT2NUM(vm_ci_argc((CALL_INFO)NUM2PTR(_ci_addr)))'
+ end
+
+ def vm_ci_flag(ci)
+ _ci_addr = ci.to_i
+ Primitive.cexpr! 'UINT2NUM(vm_ci_flag((CALL_INFO)NUM2PTR(_ci_addr)))'
+ end
+
+ def rb_splat_or_kwargs_p(ci)
+ _ci_addr = ci.to_i
+ Primitive.cstmt! %{
+ extern bool rb_splat_or_kwargs_p(const struct rb_callinfo *restrict ci);
+ return RBOOL(rb_splat_or_kwargs_p((CALL_INFO)NUM2PTR(_ci_addr)));
+ }
+ end
+
+ # Returns true if iseq can use fastpath for setup, otherwise NULL. This becomes true in the same condition
+ # as CC_SET_FASTPATH (in vm_callee_setup_arg) is called from vm_call_iseq_setup.
+ def fastpath_applied_iseq_p(ci_ptr, cc_ptr, iseq_ptr)
+ _ci_addr = ci_ptr.to_i
+ _cc_addr = cc_ptr.to_i
+ _iseq_addr = iseq_ptr.to_i
+ Primitive.cstmt! %q{
+ extern bool rb_simple_iseq_p(const rb_iseq_t *iseq);
+ CALL_INFO ci = (CALL_INFO)NUM2PTR(_ci_addr);
+ CALL_CACHE cc = (CALL_CACHE)NUM2PTR(_cc_addr);
+ const rb_iseq_t *iseq = (rb_iseq_t *)NUM2PTR(_iseq_addr);
+
+ bool result = iseq != NULL
+ && !(vm_ci_flag(ci) & VM_CALL_KW_SPLAT) && rb_simple_iseq_p(iseq) // Top of vm_callee_setup_arg. In this case, opt_pc is 0.
+ && vm_ci_argc(ci) == (unsigned int)ISEQ_BODY(iseq)->param.lead_num // exclude argument_arity_error (assumption: `calling->argc == ci->orig_argc` in send insns)
+ && vm_call_iseq_optimizable_p(ci, cc); // CC_SET_FASTPATH condition
+ return RBOOL(result);
+ }
+ end
+
+ def mjit_opts
+ addr = Primitive.cexpr! 'PTR2NUM((VALUE)&mjit_opts)'
+ mjit_options.new(addr)
+ end
+
+ def mjit_call_attribute_sp_inc(insn, operands)
+ _operands_addr = operands.to_i
+ Primitive.cexpr! 'LONG2NUM(mjit_call_attribute_sp_inc(NUM2INT(insn), (VALUE *)NUM2PTR(_operands_addr)))'
+ end
+
+ def mjit_capture_cc_entries(compiled_body, captured_body)
+ _compiled_body_addr = compiled_body.to_i
+ _captured_body_addr = captured_body.to_i
+ Primitive.cstmt! %{
+ extern int mjit_capture_cc_entries(const struct rb_iseq_constant_body *compiled_iseq, const struct rb_iseq_constant_body *captured_iseq);
+ return INT2NUM(mjit_capture_cc_entries((struct rb_iseq_constant_body *)NUM2PTR(_compiled_body_addr), (struct rb_iseq_constant_body *)NUM2PTR(_captured_body_addr)));
+ }
+ end
+
+ def mjit_cancel_all(reason)
+ Primitive.cstmt! %{
+ mjit_cancel_all(RSTRING_PTR(reason));
+ return Qnil;
+ }
+ end
+
+ # Convert encoded VM pointers to insn BINs.
+ def rb_vm_insn_decode(encoded)
+ Primitive.cexpr! 'INT2NUM(rb_vm_insn_decode(NUM2PTR(encoded)))'
+ end
+
+ # Convert insn BINs to encoded VM pointers. This one is not used by the compiler, but useful for debugging.
+ def rb_vm_insn_encode(bin)
+ Primitive.cexpr! 'PTR2NUM((VALUE)rb_vm_get_insns_address_table()[NUM2INT(bin)])'
+ end
+
+ def insn_may_depend_on_sp_or_pc(insn, opes)
+ _opes_addr = opes.to_i
+ Primitive.cexpr! 'RBOOL(insn_may_depend_on_sp_or_pc(NUM2INT(insn), (VALUE *)NUM2PTR(_opes_addr)))'
+ end
+
+ # Convert Integer VALUE to an actual Ruby object
+ def to_ruby(value)
+ Primitive.cexpr! '(VALUE)NUM2PTR(value)'
+ end
+
+ # Convert RubyVM::InstructionSequence to C.rb_iseq_t. Not used by the compiler, but useful for debugging.
+ def rb_iseqw_to_iseq(iseqw)
+ iseq_addr = Primitive.cexpr! 'PTR2NUM((VALUE)rb_iseqw_to_iseq(iseqw))'
+ rb_iseq_t.new(iseq_addr)
+ end
+ end
+
+ ### MJIT bindgen begin ###
+
+ def C.USE_LAZY_LOAD
+ Primitive.cexpr! %q{ RBOOL(USE_LAZY_LOAD != 0) }
+ end
+
+ def C.NOT_COMPILED_STACK_SIZE
+ Primitive.cexpr! %q{ INT2NUM(NOT_COMPILED_STACK_SIZE) }
+ end
+
+ def C.VM_CALL_KW_SPLAT
+ Primitive.cexpr! %q{ INT2NUM(VM_CALL_KW_SPLAT) }
+ end
+
+ def C.VM_CALL_KW_SPLAT_bit
+ Primitive.cexpr! %q{ INT2NUM(VM_CALL_KW_SPLAT_bit) }
+ end
+
+ def C.VM_CALL_TAILCALL
+ Primitive.cexpr! %q{ INT2NUM(VM_CALL_TAILCALL) }
+ end
+
+ def C.VM_CALL_TAILCALL_bit
+ Primitive.cexpr! %q{ INT2NUM(VM_CALL_TAILCALL_bit) }
+ end
+
+ def C.VM_METHOD_TYPE_CFUNC
+ Primitive.cexpr! %q{ INT2NUM(VM_METHOD_TYPE_CFUNC) }
+ end
+
+ def C.VM_METHOD_TYPE_ISEQ
+ Primitive.cexpr! %q{ INT2NUM(VM_METHOD_TYPE_ISEQ) }
+ end
+
+ def C.RUBY_EVENT_CLASS
+ Primitive.cexpr! %q{ UINT2NUM(RUBY_EVENT_CLASS) }
+ end
+
+ def C.SHAPE_CAPACITY_CHANGE
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_CAPACITY_CHANGE) }
+ end
+
+ def C.SHAPE_FLAG_SHIFT
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_FLAG_SHIFT) }
+ end
+
+ def C.SHAPE_FROZEN
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_FROZEN) }
+ end
+
+ def C.SHAPE_ID_NUM_BITS
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_ID_NUM_BITS) }
+ end
+
+ def C.SHAPE_INITIAL_CAPACITY
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_INITIAL_CAPACITY) }
+ end
+
+ def C.SHAPE_IVAR
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_IVAR) }
+ end
+
+ def C.SHAPE_ROOT
+ Primitive.cexpr! %q{ UINT2NUM(SHAPE_ROOT) }
+ end
+
+ def C.INVALID_SHAPE_ID
+ Primitive.cexpr! %q{ ULONG2NUM(INVALID_SHAPE_ID) }
+ end
+
+ def C.SHAPE_MASK
+ Primitive.cexpr! %q{ ULONG2NUM(SHAPE_MASK) }
+ end
+
+ def C.rb_cFalseClass
+ Primitive.cexpr! %q{ PTR2NUM(rb_cFalseClass) }
+ end
+
+ def C.rb_cFloat
+ Primitive.cexpr! %q{ PTR2NUM(rb_cFloat) }
+ end
+
+ def C.rb_cInteger
+ Primitive.cexpr! %q{ PTR2NUM(rb_cInteger) }
+ end
+
+ def C.rb_cNilClass
+ Primitive.cexpr! %q{ PTR2NUM(rb_cNilClass) }
+ end
+
+ def C.rb_cSymbol
+ Primitive.cexpr! %q{ PTR2NUM(rb_cSymbol) }
+ end
+
+ def C.rb_cTrueClass
+ Primitive.cexpr! %q{ PTR2NUM(rb_cTrueClass) }
+ end
+
+ def C.CALL_DATA
+ @CALL_DATA ||= self.rb_call_data
+ end
+
+ def C.IC
+ @IC ||= self.iseq_inline_constant_cache
+ end
+
+ def C.IVC
+ @IVC ||= self.iseq_inline_iv_cache_entry
+ end
+
+ def C.RB_BUILTIN
+ @RB_BUILTIN ||= self.rb_builtin_function
+ end
+
+ def C.attr_index_t
+ @attr_index_t ||= CType::Immediate.parse("uint32_t")
+ end
+
+ def C.compile_branch
+ @compile_branch ||= CType::Struct.new(
+ "compile_branch", Primitive.cexpr!("SIZEOF(struct compile_branch)"),
+ stack_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct compile_branch *)NULL)), stack_size)")],
+ finish_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct compile_branch *)NULL)), finish_p)")],
+ )
+ end
+
+ def C.compile_status
+ @compile_status ||= CType::Struct.new(
+ "compile_status", Primitive.cexpr!("SIZEOF(struct compile_status)"),
+ success: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), success)")],
+ stack_size_for_pos: [CType::Pointer.new { CType::Immediate.parse("int") }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), stack_size_for_pos)")],
+ local_stack_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), local_stack_p)")],
+ cc_entries_index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), cc_entries_index)")],
+ compiled_iseq: [CType::Pointer.new { self.rb_iseq_constant_body }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compiled_iseq)")],
+ compiled_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compiled_id)")],
+ compile_info: [CType::Pointer.new { self.rb_mjit_compile_info }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compile_info)")],
+ inlined_iseqs: [CType::Pointer.new { CType::Pointer.new { self.rb_iseq_constant_body } }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), inlined_iseqs)")],
+ inline_context: [self.inlined_call_context, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), inline_context)")],
+ )
+ end
+
+ def C.inlined_call_context
+ @inlined_call_context ||= CType::Struct.new(
+ "inlined_call_context", Primitive.cexpr!("SIZEOF(struct inlined_call_context)"),
+ orig_argc: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct inlined_call_context *)NULL)), orig_argc)")],
+ me: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct inlined_call_context *)NULL)), me)")],
+ param_size: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct inlined_call_context *)NULL)), param_size)")],
+ local_size: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct inlined_call_context *)NULL)), local_size)")],
+ )
+ end
+
+ def C.iseq_inline_constant_cache
+ @iseq_inline_constant_cache ||= CType::Struct.new(
+ "iseq_inline_constant_cache", Primitive.cexpr!("SIZEOF(struct iseq_inline_constant_cache)"),
+ entry: [CType::Pointer.new { self.iseq_inline_constant_cache_entry }, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache *)NULL)), entry)")],
+ segments: [CType::Pointer.new { self.ID }, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache *)NULL)), segments)")],
+ )
+ end
+
+ def C.iseq_inline_constant_cache_entry
+ @iseq_inline_constant_cache_entry ||= CType::Struct.new(
+ "iseq_inline_constant_cache_entry", Primitive.cexpr!("SIZEOF(struct iseq_inline_constant_cache_entry)"),
+ flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), flags)")],
+ value: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), value)")],
+ _unused1: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), _unused1)")],
+ _unused2: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), _unused2)")],
+ ic_cref: [CType::Pointer.new { self.rb_cref_t }, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), ic_cref)")],
+ )
+ end
+
+ def C.iseq_inline_iv_cache_entry
+ @iseq_inline_iv_cache_entry ||= CType::Struct.new(
+ "iseq_inline_iv_cache_entry", Primitive.cexpr!("SIZEOF(struct iseq_inline_iv_cache_entry)"),
+ value: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_iv_cache_entry *)NULL)), value)")],
+ iv_set_name: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_iv_cache_entry *)NULL)), iv_set_name)")],
+ )
+ end
+
+ def C.iseq_inline_storage_entry
+ @iseq_inline_storage_entry ||= CType::Union.new(
+ "iseq_inline_storage_entry", Primitive.cexpr!("SIZEOF(union iseq_inline_storage_entry)"),
+ once: CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((union iseq_inline_storage_entry *)NULL)->once)"),
+ running_thread: [CType::Pointer.new { self.rb_thread_struct }, Primitive.cexpr!("OFFSETOF(((union iseq_inline_storage_entry *)NULL)->once, running_thread)")],
+ value: [self.VALUE, Primitive.cexpr!("OFFSETOF(((union iseq_inline_storage_entry *)NULL)->once, value)")],
+ ),
+ ic_cache: self.iseq_inline_constant_cache,
+ iv_cache: self.iseq_inline_iv_cache_entry,
+ )
+ end
+
+ def C.mjit_options
+ @mjit_options ||= CType::Struct.new(
+ "mjit_options", Primitive.cexpr!("SIZEOF(struct mjit_options)"),
+ on: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), on)")],
+ save_temps: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), save_temps)")],
+ warnings: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), warnings)")],
+ debug: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), debug)")],
+ debug_flags: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), debug_flags)")],
+ wait: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), wait)")],
+ call_threshold: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), call_threshold)")],
+ verbose: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), verbose)")],
+ max_cache_size: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), max_cache_size)")],
+ pause: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), pause)")],
+ custom: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), custom)")],
+ )
+ end
+
+ def C.rb_builtin_function
+ @rb_builtin_function ||= CType::Struct.new(
+ "rb_builtin_function", Primitive.cexpr!("SIZEOF(struct rb_builtin_function)"),
+ func_ptr: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), func_ptr)")],
+ argc: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), argc)")],
+ index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), index)")],
+ name: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), name)")],
+ compiler: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), compiler)")],
+ )
+ end
+
+ def C.rb_call_data
+ @rb_call_data ||= CType::Struct.new(
+ "rb_call_data", Primitive.cexpr!("SIZEOF(struct rb_call_data)"),
+ ci: [CType::Pointer.new { self.rb_callinfo }, Primitive.cexpr!("OFFSETOF((*((struct rb_call_data *)NULL)), ci)")],
+ cc: [CType::Pointer.new { self.rb_callcache }, Primitive.cexpr!("OFFSETOF((*((struct rb_call_data *)NULL)), cc)")],
+ )
+ end
+
+ def C.rb_callable_method_entry_struct
+ @rb_callable_method_entry_struct ||= CType::Struct.new(
+ "rb_callable_method_entry_struct", Primitive.cexpr!("SIZEOF(struct rb_callable_method_entry_struct)"),
+ flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), flags)")],
+ defined_class: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), defined_class)")],
+ def: [CType::Pointer.new { self.rb_method_definition_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), def)")],
+ called_id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), called_id)")],
+ owner: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), owner)")],
+ )
+ end
+
+ def C.rb_callcache
+ @rb_callcache ||= CType::Struct.new(
+ "rb_callcache", Primitive.cexpr!("SIZEOF(struct rb_callcache)"),
+ flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), flags)")],
+ klass: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), klass)")],
+ cme_: [CType::Pointer.new { self.rb_callable_method_entry_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), cme_)")],
+ call_: [self.vm_call_handler, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), call_)")],
+ aux_: [CType::Union.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_callcache *)NULL)->aux_)"),
+ attr: CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_callcache *)NULL)->aux_.attr)"),
+ value: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF(((struct rb_callcache *)NULL)->aux_.attr, value)")],
+ ),
+ method_missing_reason: self.method_missing_reason,
+ v: self.VALUE,
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), aux_)")],
+ )
+ end
+
+ def C.rb_callinfo
+ @rb_callinfo ||= CType::Struct.new(
+ "rb_callinfo", Primitive.cexpr!("SIZEOF(struct rb_callinfo)"),
+ flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), flags)")],
+ kwarg: [CType::Pointer.new { self.rb_callinfo_kwarg }, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), kwarg)")],
+ mid: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), mid)")],
+ flag: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), flag)")],
+ argc: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), argc)")],
+ )
+ end
+
+ def C.rb_control_frame_t
+ @rb_control_frame_t ||= CType::Struct.new(
+ "rb_control_frame_struct", Primitive.cexpr!("SIZEOF(struct rb_control_frame_struct)"),
+ pc: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), pc)")],
+ sp: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), sp)")],
+ iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), iseq)")],
+ self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), self)")],
+ ep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), ep)")],
+ block_code: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), block_code)")],
+ __bp__: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), __bp__)")],
+ jit_return: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), jit_return)")],
+ )
+ end
+
+ def C.rb_cref_t
+ @rb_cref_t ||= CType::Struct.new(
+ "rb_cref_struct", Primitive.cexpr!("SIZEOF(struct rb_cref_struct)"),
+ flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), flags)")],
+ refinements: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), refinements)")],
+ klass_or_self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), klass_or_self)")],
+ next: [CType::Pointer.new { self.rb_cref_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), next)")],
+ scope_visi: [self.rb_scope_visibility_t, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), scope_visi)")],
+ )
+ end
+
+ def C.rb_execution_context_struct
+ @rb_execution_context_struct ||= CType::Struct.new(
+ "rb_execution_context_struct", Primitive.cexpr!("SIZEOF(struct rb_execution_context_struct)"),
+ vm_stack: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), vm_stack)")],
+ vm_stack_size: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), vm_stack_size)")],
+ cfp: [CType::Pointer.new { self.rb_control_frame_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), cfp)")],
+ tag: [CType::Pointer.new { self.rb_vm_tag }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), tag)")],
+ interrupt_flag: [self.rb_atomic_t, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), interrupt_flag)")],
+ interrupt_mask: [self.rb_atomic_t, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), interrupt_mask)")],
+ fiber_ptr: [CType::Pointer.new { self.rb_fiber_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), fiber_ptr)")],
+ thread_ptr: [CType::Pointer.new { self.rb_thread_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), thread_ptr)")],
+ local_storage: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), local_storage)")],
+ local_storage_recursive_hash: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), local_storage_recursive_hash)")],
+ local_storage_recursive_hash_for_trace: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), local_storage_recursive_hash_for_trace)")],
+ storage: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), storage)")],
+ root_lep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), root_lep)")],
+ root_svar: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), root_svar)")],
+ ensure_list: [CType::Pointer.new { self.rb_ensure_list_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), ensure_list)")],
+ trace_arg: [CType::Pointer.new { self.rb_trace_arg_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), trace_arg)")],
+ errinfo: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), errinfo)")],
+ passed_block_handler: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), passed_block_handler)")],
+ raised_flag: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), raised_flag)")],
+ private_const_reference: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), private_const_reference)")],
+ machine: [CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_execution_context_struct *)NULL)->machine)"),
+ stack_start: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_start)")],
+ stack_end: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_end)")],
+ stack_maxsize: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_maxsize)")],
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), machine)")],
+ )
+ end
+
+ def C.rb_execution_context_t
+ @rb_execution_context_t ||= self.rb_execution_context_struct
+ end
+
+ def C.rb_iseq_constant_body
+ @rb_iseq_constant_body ||= CType::Struct.new(
+ "rb_iseq_constant_body", Primitive.cexpr!("SIZEOF(struct rb_iseq_constant_body)"),
+ type: [self.rb_iseq_type, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), type)")],
+ iseq_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), iseq_size)")],
+ iseq_encoded: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), iseq_encoded)")],
+ param: [CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->param)"),
+ flags: [CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->param.flags)"),
+ has_lead: [CType::BitField.new(1, 0), 0],
+ has_opt: [CType::BitField.new(1, 1), 1],
+ has_rest: [CType::BitField.new(1, 2), 2],
+ has_post: [CType::BitField.new(1, 3), 3],
+ has_kw: [CType::BitField.new(1, 4), 4],
+ has_kwrest: [CType::BitField.new(1, 5), 5],
+ has_block: [CType::BitField.new(1, 6), 6],
+ ambiguous_param0: [CType::BitField.new(1, 7), 7],
+ accepts_no_kwarg: [CType::BitField.new(1, 0), 8],
+ ruby2_keywords: [CType::BitField.new(1, 1), 9],
+ ), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, flags)")],
+ size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, size)")],
+ lead_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, lead_num)")],
+ opt_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, opt_num)")],
+ rest_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, rest_start)")],
+ post_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, post_start)")],
+ post_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, post_num)")],
+ block_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, block_start)")],
+ opt_table: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, opt_table)")],
+ keyword: [CType::Pointer.new { self.rb_iseq_param_keyword }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, keyword)")],
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), param)")],
+ location: [self.rb_iseq_location_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), location)")],
+ insns_info: [self.iseq_insn_info, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), insns_info)")],
+ local_table: [CType::Pointer.new { self.ID }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), local_table)")],
+ catch_table: [CType::Pointer.new { self.iseq_catch_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), catch_table)")],
+ parent_iseq: [CType::Pointer.new { self.rb_iseq_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), parent_iseq)")],
+ local_iseq: [CType::Pointer.new { self.rb_iseq_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), local_iseq)")],
+ is_entries: [CType::Pointer.new { self.iseq_inline_storage_entry }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), is_entries)")],
+ call_data: [CType::Pointer.new { self.rb_call_data }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), call_data)")],
+ variable: [CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->variable)"),
+ flip_count: [self.rb_snum_t, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, flip_count)")],
+ script_lines: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, script_lines)")],
+ coverage: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, coverage)")],
+ pc2branchindex: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, pc2branchindex)")],
+ original_iseq: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, original_iseq)")],
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), variable)")],
+ local_table_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), local_table_size)")],
+ ic_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ic_size)")],
+ ise_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ise_size)")],
+ ivc_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ivc_size)")],
+ icvarc_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), icvarc_size)")],
+ ci_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ci_size)")],
+ stack_max: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), stack_max)")],
+ catch_except_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), catch_except_p)")],
+ builtin_inline_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), builtin_inline_p)")],
+ mark_bits: [CType::Union.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->mark_bits)"),
+ list: CType::Pointer.new { self.iseq_bits_t },
+ single: self.iseq_bits_t,
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mark_bits)")],
+ outer_variables: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), outer_variables)")],
+ mandatory_only_iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mandatory_only_iseq)")],
+ jit_func: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), jit_func)")],
+ total_calls: [CType::Immediate.parse("unsigned long"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), total_calls)")],
+ mjit_unit: [CType::Pointer.new { self.rb_mjit_unit }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mjit_unit)")],
+ )
+ end
+
+ def C.rb_iseq_location_t
+ @rb_iseq_location_t ||= CType::Struct.new(
+ "rb_iseq_location_struct", Primitive.cexpr!("SIZEOF(struct rb_iseq_location_struct)"),
+ pathobj: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), pathobj)"), true],
+ base_label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), base_label)"), true],
+ label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), label)"), true],
+ first_lineno: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), first_lineno)"), true],
+ node_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), node_id)")],
+ code_location: [self.rb_code_location_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), code_location)")],
+ )
+ end
+
+ def C.rb_iseq_struct
+ @rb_iseq_struct ||= CType::Struct.new(
+ "rb_iseq_struct", Primitive.cexpr!("SIZEOF(struct rb_iseq_struct)"),
+ flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), flags)")],
+ wrapper: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), wrapper)")],
+ body: [CType::Pointer.new { self.rb_iseq_constant_body }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), body)")],
+ aux: [CType::Union.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_struct *)NULL)->aux)"),
+ compile_data: CType::Pointer.new { self.iseq_compile_data },
+ loader: CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_struct *)NULL)->aux.loader)"),
+ obj: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.loader, obj)")],
+ index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.loader, index)")],
+ ),
+ exec: CType::Struct.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_struct *)NULL)->aux.exec)"),
+ local_hooks: [CType::Pointer.new { self.rb_hook_list_struct }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.exec, local_hooks)")],
+ global_trace_events: [self.rb_event_flag_t, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.exec, global_trace_events)")],
+ ),
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), aux)")],
+ )
+ end
+
+ def C.rb_iseq_t
+ @rb_iseq_t ||= self.rb_iseq_struct
+ end
+
+ def C.rb_method_definition_struct
+ @rb_method_definition_struct ||= CType::Struct.new(
+ "rb_method_definition_struct", Primitive.cexpr!("SIZEOF(struct rb_method_definition_struct)"),
+ type: [CType::BitField.new(4, 0), 0],
+ iseq_overload: [CType::BitField.new(1, 4), 4],
+ no_redef_warning: [CType::BitField.new(1, 5), 5],
+ aliased: [CType::BitField.new(1, 6), 6],
+ reference_count: [CType::BitField.new(28, 0), 32],
+ body: [CType::Union.new(
+ "", Primitive.cexpr!("SIZEOF(((struct rb_method_definition_struct *)NULL)->body)"),
+ iseq: self.rb_method_iseq_t,
+ cfunc: self.rb_method_cfunc_t,
+ attr: self.rb_method_attr_t,
+ alias: self.rb_method_alias_t,
+ refined: self.rb_method_refined_t,
+ bmethod: self.rb_method_bmethod_t,
+ optimized: self.rb_method_optimized_t,
+ ), Primitive.cexpr!("OFFSETOF((*((struct rb_method_definition_struct *)NULL)), body)")],
+ original_id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_method_definition_struct *)NULL)), original_id)")],
+ method_serial: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_method_definition_struct *)NULL)), method_serial)")],
+ )
+ end
+
+ def C.rb_method_iseq_t
+ @rb_method_iseq_t ||= CType::Struct.new(
+ "rb_method_iseq_struct", Primitive.cexpr!("SIZEOF(struct rb_method_iseq_struct)"),
+ iseqptr: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_method_iseq_struct *)NULL)), iseqptr)")],
+ cref: [CType::Pointer.new { self.rb_cref_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_method_iseq_struct *)NULL)), cref)")],
+ )
+ end
+
+ def C.rb_method_type_t
+ @rb_method_type_t ||= CType::Immediate.parse("int")
+ end
+
+ def C.rb_mjit_compile_info
+ @rb_mjit_compile_info ||= CType::Struct.new(
+ "rb_mjit_compile_info", Primitive.cexpr!("SIZEOF(struct rb_mjit_compile_info)"),
+ disable_ivar_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_ivar_cache)")],
+ disable_exivar_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_exivar_cache)")],
+ disable_send_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_send_cache)")],
+ disable_inlining: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_inlining)")],
+ disable_const_cache: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_compile_info *)NULL)), disable_const_cache)")],
+ )
+ end
+
+ def C.rb_mjit_unit
+ @rb_mjit_unit ||= CType::Struct.new(
+ "rb_mjit_unit", Primitive.cexpr!("SIZEOF(struct rb_mjit_unit)"),
+ unode: [self.ccan_list_node, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), unode)")],
+ id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), id)")],
+ type: [self.rb_mjit_unit_type, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), type)")],
+ iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), iseq)")],
+ used_code_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), used_code_p)")],
+ compile_info: [self.rb_mjit_compile_info, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), compile_info)")],
+ cc_entries: [CType::Pointer.new { CType::Pointer.new { self.rb_callcache } }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), cc_entries)")],
+ cc_entries_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), cc_entries_size)")],
+ handle: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), handle)")],
+ units: [self.rb_mjit_unit_list, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), units)")],
+ )
+ end
+
+ def C.rb_serial_t
+ @rb_serial_t ||= CType::Immediate.parse("unsigned long long")
+ end
+
+ def C.rb_shape
+ @rb_shape ||= CType::Struct.new(
+ "rb_shape", Primitive.cexpr!("SIZEOF(struct rb_shape)"),
+ edges: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), edges)")],
+ edge_name: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), edge_name)")],
+ next_iv_index: [self.attr_index_t, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), next_iv_index)")],
+ capacity: [CType::Immediate.parse("uint32_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), capacity)")],
+ type: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), type)")],
+ size_pool_index: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), size_pool_index)")],
+ parent_id: [self.shape_id_t, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), parent_id)")],
+ )
+ end
+
+ def C.rb_shape_t
+ @rb_shape_t ||= self.rb_shape
+ end
+
+ def C.VALUE
+ @VALUE ||= CType::Immediate.find(Primitive.cexpr!("SIZEOF(VALUE)"), Primitive.cexpr!("SIGNED_TYPE_P(VALUE)"))
+ end
+
+ def C.shape_id_t
+ @shape_id_t ||= CType::Immediate.find(Primitive.cexpr!("SIZEOF(shape_id_t)"), Primitive.cexpr!("SIGNED_TYPE_P(shape_id_t)"))
+ end
+
+ def C._Bool
+ CType::Bool.new
+ end
+
+ def C.ID
+ CType::Stub.new(:ID)
+ end
+
+ def C.rb_thread_struct
+ CType::Stub.new(:rb_thread_struct)
+ end
+
+ def C.vm_call_handler
+ CType::Stub.new(:vm_call_handler)
+ end
+
+ def C.method_missing_reason
+ CType::Stub.new(:method_missing_reason)
+ end
+
+ def C.rb_callinfo_kwarg
+ CType::Stub.new(:rb_callinfo_kwarg)
+ end
+
+ def C.rb_cref_struct
+ CType::Stub.new(:rb_cref_struct)
+ end
+
+ def C.rb_scope_visibility_t
+ CType::Stub.new(:rb_scope_visibility_t)
+ end
+
+ def C.rb_vm_tag
+ CType::Stub.new(:rb_vm_tag)
+ end
+
+ def C.rb_atomic_t
+ CType::Stub.new(:rb_atomic_t)
+ end
+
+ def C.rb_fiber_t
+ CType::Stub.new(:rb_fiber_t)
+ end
+
+ def C.rb_id_table
+ CType::Stub.new(:rb_id_table)
+ end
+
+ def C.rb_ensure_list_t
+ CType::Stub.new(:rb_ensure_list_t)
+ end
+
+ def C.rb_trace_arg_struct
+ CType::Stub.new(:rb_trace_arg_struct)
+ end
+
+ def C.rb_iseq_type
+ CType::Stub.new(:rb_iseq_type)
+ end
+
+ def C.rb_iseq_param_keyword
+ CType::Stub.new(:rb_iseq_param_keyword)
+ end
+
+ def C.iseq_insn_info
+ CType::Stub.new(:iseq_insn_info)
+ end
+
+ def C.iseq_catch_table
+ CType::Stub.new(:iseq_catch_table)
+ end
+
+ def C.rb_snum_t
+ CType::Stub.new(:rb_snum_t)
+ end
+
+ def C.iseq_bits_t
+ CType::Stub.new(:iseq_bits_t)
+ end
+
+ def C.rb_code_location_t
+ CType::Stub.new(:rb_code_location_t)
+ end
+
+ def C.iseq_compile_data
+ CType::Stub.new(:iseq_compile_data)
+ end
+
+ def C.rb_hook_list_struct
+ CType::Stub.new(:rb_hook_list_struct)
+ end
+
+ def C.rb_event_flag_t
+ CType::Stub.new(:rb_event_flag_t)
+ end
+
+ def C.rb_method_cfunc_t
+ CType::Stub.new(:rb_method_cfunc_t)
+ end
+
+ def C.rb_method_attr_t
+ CType::Stub.new(:rb_method_attr_t)
+ end
+
+ def C.rb_method_alias_t
+ CType::Stub.new(:rb_method_alias_t)
+ end
+
+ def C.rb_method_refined_t
+ CType::Stub.new(:rb_method_refined_t)
+ end
+
+ def C.rb_method_bmethod_t
+ CType::Stub.new(:rb_method_bmethod_t)
+ end
+
+ def C.rb_method_optimized_t
+ CType::Stub.new(:rb_method_optimized_t)
+ end
+
+ def C.ccan_list_node
+ CType::Stub.new(:ccan_list_node)
+ end
+
+ def C.rb_mjit_unit_type
+ CType::Stub.new(:rb_mjit_unit_type)
+ end
+
+ def C.rb_mjit_unit_list
+ CType::Stub.new(:rb_mjit_unit_list)
+ end
+
+ ### MJIT bindgen end ###
+end if RubyVM::MJIT.enabled? && RubyVM::MJIT.const_defined?(:C) # not defined for miniruby
diff --git a/node.c b/node.c
index 1f10258343..a6cb498778 100644
--- a/node.c
+++ b/node.c
@@ -9,96 +9,1119 @@
**********************************************************************/
-#ifdef UNIVERSAL_PARSER
-
-#include <stddef.h>
-#include "node.h"
-#include "rubyparser.h"
-#include "internal/parse.h"
-#define T_NODE 0x1b
-
-#else
-
#include "internal.h"
#include "internal/hash.h"
#include "internal/variable.h"
#include "ruby/ruby.h"
#include "vm_core.h"
-#endif
+#define NODE_BUF_DEFAULT_LEN 16
+
+#define A(str) rb_str_cat2(buf, (str))
+#define AR(str) rb_str_concat(buf, (str))
+
+#define A_INDENT add_indent(buf, indent)
+#define D_INDENT rb_str_cat2(indent, next_indent)
+#define D_DEDENT rb_str_resize(indent, RSTRING_LEN(indent) - 4)
+#define A_ID(id) add_id(buf, (id))
+#define A_INT(val) rb_str_catf(buf, "%d", (val))
+#define A_LONG(val) rb_str_catf(buf, "%ld", (val))
+#define A_LIT(lit) AR(rb_dump_literal(lit))
+#define A_NODE_HEADER(node, term) \
+ rb_str_catf(buf, "@ %s (id: %d, line: %d, location: (%d,%d)-(%d,%d))%s"term, \
+ ruby_node_name(nd_type(node)), nd_node_id(node), nd_line(node), \
+ nd_first_lineno(node), nd_first_column(node), \
+ nd_last_lineno(node), nd_last_column(node), \
+ (node->flags & NODE_FL_NEWLINE ? "*" : ""))
+#define A_FIELD_HEADER(len, name, term) \
+ rb_str_catf(buf, "+- %.*s:"term, (len), (name))
+#define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
+
+#define D_NULL_NODE (A_INDENT, A("(null node)\n"))
+#define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
+
+#define COMPOUND_FIELD(len, name) \
+ FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
+
+#define COMPOUND_FIELD1(name, ann) \
+ COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
+ FIELD_NAME_DESC(name, ann))
+
+#define FIELD_NAME_DESC(name, ann) name " (" ann ")"
+#define FIELD_NAME_LEN(name, ann) (int)( \
+ comment ? \
+ rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
+ rb_strlen_lit(name))
+#define SIMPLE_FIELD(len, name) \
+ FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
+
+#define FIELD_BLOCK(init, reset) \
+ for (init, field_flag = 1; \
+ field_flag; /* should be optimized away */ \
+ reset, field_flag = 0)
+
+#define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
+#define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
+#define F_ID(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
+#define F_GENTRY(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
+#define F_INT(name, ann) SIMPLE_FIELD1(#name, ann) A_INT(node->name)
+#define F_LONG(name, ann) SIMPLE_FIELD1(#name, ann) A_LONG(node->name)
+#define F_LIT(name, ann) SIMPLE_FIELD1(#name, ann) A_LIT(node->name)
+#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
+
+#define F_NODE(name, ann) \
+ COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, node->name);}
+
+#define ANN(ann) \
+ if (comment) { \
+ A_INDENT; A("| # " ann "\n"); \
+ }
+
+#define LAST_NODE (next_indent = " ")
-#define NODE_BUF_DEFAULT_SIZE (sizeof(struct RNode) * 16)
+VALUE
+rb_dump_literal(VALUE lit)
+{
+ if (!RB_SPECIAL_CONST_P(lit)) {
+ VALUE str;
+ switch (RB_BUILTIN_TYPE(lit)) {
+ case T_CLASS: case T_MODULE: case T_ICLASS:
+ str = rb_class_path(lit);
+ if (FL_TEST(lit, FL_SINGLETON)) {
+ str = rb_sprintf("<%"PRIsVALUE">", str);
+ }
+ return str;
+ default:
+ break;
+ }
+ }
+ return rb_inspect(lit);
+}
static void
-init_node_buffer_elem(node_buffer_elem_t *nbe, size_t allocated, void *xmalloc(size_t))
+add_indent(VALUE buf, VALUE indent)
{
- nbe->allocated = allocated;
- nbe->used = 0;
- nbe->len = 0;
- nbe->nodes = xmalloc(allocated / sizeof(struct RNode) * sizeof(struct RNode *)); /* All node requires at least RNode */
+ AR(indent);
}
static void
-init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head, void *xmalloc(size_t))
+add_id(VALUE buf, ID id)
{
- init_node_buffer_elem(head, NODE_BUF_DEFAULT_SIZE, xmalloc);
- nb->head = nb->last = head;
- nb->head->next = NULL;
+ if (id == 0) {
+ A("(null)");
+ }
+ else {
+ VALUE str = rb_id2str(id);
+ if (str) {
+ A(":"); AR(str);
+ }
+ else {
+ rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
+ }
+ }
}
-#ifdef UNIVERSAL_PARSER
-#define ruby_xmalloc config->malloc
-#define Qnil config->qnil
-#endif
+struct add_option_arg {
+ VALUE buf, indent;
+ st_index_t count;
+};
-#ifdef UNIVERSAL_PARSER
-static node_buffer_t *
-rb_node_buffer_new(rb_parser_config_t *config)
-#else
-static node_buffer_t *
-rb_node_buffer_new(void)
-#endif
+static void dump_node(VALUE, VALUE, int, const NODE *);
+static const char default_indent[] = "| ";
+
+static void
+dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
{
- const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_SIZE;
- const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
- STATIC_ASSERT(
- integer_overflow,
- offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_SIZE
- > sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
- node_buffer_t *nb = ruby_xmalloc(alloc_size);
- init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1], ruby_xmalloc);
- init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size), ruby_xmalloc);
- nb->local_tables = 0;
- nb->mark_hash = Qnil;
- nb->tokens = Qnil;
-#ifdef UNIVERSAL_PARSER
- nb->config = config;
-#endif
- return nb;
+ int field_flag;
+ const char *next_indent = default_indent;
+ F_LONG(nd_alen, "length");
+ F_NODE(nd_head, "element");
+ while (node->nd_next && nd_type_p(node->nd_next, NODE_LIST)) {
+ node = node->nd_next;
+ F_NODE(nd_head, "element");
+ }
+ LAST_NODE;
+ F_NODE(nd_next, "next element");
}
-#ifdef UNIVERSAL_PARSER
-#undef ruby_xmalloc
-#define ruby_xmalloc ast->node_buffer->config->malloc
-#undef xfree
-#define xfree ast->node_buffer->config->free
-#define rb_ident_hash_new ast->node_buffer->config->ident_hash_new
-#define rb_xmalloc_mul_add ast->node_buffer->config->xmalloc_mul_add
-#define ruby_xrealloc(var,size) (ast->node_buffer->config->realloc_n((void *)var, 1, size))
-#define rb_gc_mark ast->node_buffer->config->gc_mark
-#define rb_gc_location ast->node_buffer->config->gc_location
-#define rb_gc_mark_movable ast->node_buffer->config->gc_mark_movable
-#undef Qnil
-#define Qnil ast->node_buffer->config->qnil
-#define Qtrue ast->node_buffer->config->qtrue
-#define NIL_P ast->node_buffer->config->nil_p
-#define rb_hash_aset ast->node_buffer->config->hash_aset
-#define rb_hash_delete ast->node_buffer->config->hash_delete
-#define RB_OBJ_WRITE(old, slot, young) ast->node_buffer->config->obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young))
-#endif
-
-typedef void node_itr_t(rb_ast_t *ast, void *ctx, NODE *node);
-static void iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, void *ctx);
+static void
+dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
+{
+ int field_flag;
+ int i;
+ const char *next_indent = default_indent;
+ enum node_type type;
+
+ if (!node) {
+ D_NULL_NODE;
+ return;
+ }
+
+ D_NODE_HEADER(node);
+
+ type = nd_type(node);
+ switch (type) {
+ case NODE_BLOCK:
+ ANN("statement sequence");
+ ANN("format: [nd_head]; ...; [nd_next]");
+ ANN("example: foo; bar");
+ i = 0;
+ do {
+ A_INDENT;
+ rb_str_catf(buf, "+- nd_head (%s%d):\n",
+ comment ? "statement #" : "", ++i);
+ if (!node->nd_next) LAST_NODE;
+ D_INDENT;
+ dump_node(buf, indent, comment, node->nd_head);
+ D_DEDENT;
+ } while (node->nd_next &&
+ nd_type_p(node->nd_next, NODE_BLOCK) &&
+ (node = node->nd_next, 1));
+ if (node->nd_next) {
+ LAST_NODE;
+ F_NODE(nd_next, "next block");
+ }
+ return;
+
+ case NODE_IF:
+ ANN("if statement");
+ ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
+ ANN("example: if x == 1 then foo else bar end");
+ F_NODE(nd_cond, "condition expr");
+ F_NODE(nd_body, "then clause");
+ LAST_NODE;
+ F_NODE(nd_else, "else clause");
+ return;
+
+ case NODE_UNLESS:
+ ANN("unless statement");
+ ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
+ ANN("example: unless x == 1 then foo else bar end");
+ F_NODE(nd_cond, "condition expr");
+ F_NODE(nd_body, "then clause");
+ LAST_NODE;
+ F_NODE(nd_else, "else clause");
+ return;
+
+ case NODE_CASE:
+ ANN("case statement");
+ ANN("format: case [nd_head]; [nd_body]; end");
+ ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
+ F_NODE(nd_head, "case expr");
+ LAST_NODE;
+ F_NODE(nd_body, "when clauses");
+ return;
+ case NODE_CASE2:
+ ANN("case statement with no head");
+ ANN("format: case; [nd_body]; end");
+ ANN("example: case; when 1; foo; when 2; bar; else baz; end");
+ F_NODE(nd_head, "case expr");
+ LAST_NODE;
+ F_NODE(nd_body, "when clauses");
+ return;
+ case NODE_CASE3:
+ ANN("case statement (pattern matching)");
+ ANN("format: case [nd_head]; [nd_body]; end");
+ ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
+ F_NODE(nd_head, "case expr");
+ LAST_NODE;
+ F_NODE(nd_body, "in clauses");
+ return;
+
+ case NODE_WHEN:
+ ANN("when clause");
+ ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
+ ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
+ F_NODE(nd_head, "when value");
+ F_NODE(nd_body, "when body");
+ LAST_NODE;
+ F_NODE(nd_next, "next when clause");
+ return;
+
+ case NODE_IN:
+ ANN("in clause");
+ ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
+ ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
+ F_NODE(nd_head, "in pattern");
+ F_NODE(nd_body, "in body");
+ LAST_NODE;
+ F_NODE(nd_next, "next in clause");
+ return;
+
+ case NODE_WHILE:
+ ANN("while statement");
+ ANN("format: while [nd_cond]; [nd_body]; end");
+ ANN("example: while x == 1; foo; end");
+ goto loop;
+ case NODE_UNTIL:
+ ANN("until statement");
+ ANN("format: until [nd_cond]; [nd_body]; end");
+ ANN("example: until x == 1; foo; end");
+ loop:
+ F_CUSTOM1(nd_state, "begin-end-while?") {
+ A_INT((int)node->nd_state);
+ A((node->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
+ }
+ F_NODE(nd_cond, "condition");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
+
+ case NODE_ITER:
+ ANN("method call with block");
+ ANN("format: [nd_iter] { [nd_body] }");
+ ANN("example: 3.times { foo }");
+ goto iter;
+ case NODE_FOR:
+ ANN("for statement");
+ ANN("format: for * in [nd_iter] do [nd_body] end");
+ ANN("example: for i in 1..3 do foo end");
+ iter:
+ F_NODE(nd_iter, "iteration receiver");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
+
+ case NODE_FOR_MASGN:
+ ANN("vars of for statement with masgn");
+ ANN("format: for [nd_var] in ... do ... end");
+ ANN("example: for x, y in 1..3 do foo end");
+ LAST_NODE;
+ F_NODE(nd_var, "var");
+ return;
+
+ case NODE_BREAK:
+ ANN("break statement");
+ ANN("format: break [nd_stts]");
+ ANN("example: break 1");
+ goto jump;
+ case NODE_NEXT:
+ ANN("next statement");
+ ANN("format: next [nd_stts]");
+ ANN("example: next 1");
+ goto jump;
+ case NODE_RETURN:
+ ANN("return statement");
+ ANN("format: return [nd_stts]");
+ ANN("example: return 1");
+ jump:
+ LAST_NODE;
+ F_NODE(nd_stts, "value");
+ return;
+
+ case NODE_REDO:
+ ANN("redo statement");
+ ANN("format: redo");
+ ANN("example: redo");
+ return;
+
+ case NODE_RETRY:
+ ANN("retry statement");
+ ANN("format: retry");
+ ANN("example: retry");
+ return;
+
+ case NODE_BEGIN:
+ ANN("begin statement");
+ ANN("format: begin; [nd_body]; end");
+ ANN("example: begin; 1; end");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
+
+ case NODE_RESCUE:
+ ANN("rescue clause");
+ ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
+ ANN("example: begin; foo; rescue; bar; else; baz; end");
+ F_NODE(nd_head, "body");
+ F_NODE(nd_resq, "rescue clause list");
+ LAST_NODE;
+ F_NODE(nd_else, "rescue else clause");
+ return;
+
+ case NODE_RESBODY:
+ ANN("rescue clause (cont'd)");
+ ANN("format: rescue [nd_args]; [nd_body]; (rescue) [nd_head]");
+ ANN("example: begin; foo; rescue; bar; else; baz; end");
+ F_NODE(nd_args, "rescue exceptions");
+ F_NODE(nd_body, "rescue clause");
+ LAST_NODE;
+ F_NODE(nd_head, "next rescue clause");
+ return;
+
+ case NODE_ENSURE:
+ ANN("ensure clause");
+ ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
+ ANN("example: begin; foo; ensure; bar; end");
+ F_NODE(nd_head, "body");
+ LAST_NODE;
+ F_NODE(nd_ensr, "ensure clause");
+ return;
+
+ case NODE_AND:
+ ANN("&& operator");
+ ANN("format: [nd_1st] && [nd_2nd]");
+ ANN("example: foo && bar");
+ goto andor;
+ case NODE_OR:
+ ANN("|| operator");
+ ANN("format: [nd_1st] || [nd_2nd]");
+ ANN("example: foo || bar");
+ andor:
+ while (1) {
+ F_NODE(nd_1st, "left expr");
+ if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type))
+ break;
+ node = node->nd_2nd;
+ }
+ LAST_NODE;
+ F_NODE(nd_2nd, "right expr");
+ return;
+
+ case NODE_MASGN:
+ ANN("multiple assignment");
+ ANN("format: [nd_head], [nd_args] = [nd_value]");
+ ANN("example: a, b = foo");
+ F_NODE(nd_value, "rhsn");
+ F_NODE(nd_head, "lhsn");
+ if (NODE_NAMED_REST_P(node->nd_args)) {
+ LAST_NODE;
+ F_NODE(nd_args, "splatn");
+ }
+ else {
+ F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ return;
+
+ case NODE_LASGN:
+ ANN("local variable assignment");
+ ANN("format: [nd_vid](lvar) = [nd_value]");
+ ANN("example: x = foo");
+ F_ID(nd_vid, "local variable");
+ if (NODE_REQUIRED_KEYWORD_P(node)) {
+ F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
+ }
+ else {
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ }
+ return;
+ case NODE_DASGN:
+ ANN("dynamic variable assignment");
+ ANN("format: [nd_vid](dvar) = [nd_value]");
+ ANN("example: x = nil; 1.times { x = foo }");
+ ANN("example: 1.times { x = foo }");
+ F_ID(nd_vid, "local variable");
+ if (NODE_REQUIRED_KEYWORD_P(node)) {
+ F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
+ }
+ else {
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ }
+ return;
+ case NODE_IASGN:
+ ANN("instance variable assignment");
+ ANN("format: [nd_vid](ivar) = [nd_value]");
+ ANN("example: @x = foo");
+ F_ID(nd_vid, "instance variable");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+ case NODE_CVASGN:
+ ANN("class variable assignment");
+ ANN("format: [nd_vid](cvar) = [nd_value]");
+ ANN("example: @@x = foo");
+ F_ID(nd_vid, "class variable");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+ case NODE_GASGN:
+ ANN("global variable assignment");
+ ANN("format: [nd_entry](gvar) = [nd_value]");
+ ANN("example: $x = foo");
+ F_GENTRY(nd_entry, "global variable");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+
+ case NODE_CDECL:
+ ANN("constant declaration");
+ ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
+ ANN("example: X = foo");
+ if (node->nd_vid) {
+ F_ID(nd_vid, "constant");
+ F_MSG(nd_else, "extension", "not used");
+ }
+ else {
+ F_MSG(nd_vid, "constant", "0 (see extension field)");
+ F_NODE(nd_else, "extension");
+ }
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+
+ case NODE_OP_ASGN1:
+ ANN("array assignment with operator");
+ ANN("format: [nd_recv] [ [nd_args->nd_head] ] [nd_mid]= [nd_args->nd_body]");
+ ANN("example: ary[1] += foo");
+ F_NODE(nd_recv, "receiver");
+ F_ID(nd_mid, "operator");
+ F_NODE(nd_args->nd_head, "index");
+ LAST_NODE;
+ F_NODE(nd_args->nd_body, "rvalue");
+ return;
+
+ case NODE_OP_ASGN2:
+ ANN("attr assignment with operator");
+ ANN("format: [nd_recv].[attr] [nd_next->nd_mid]= [nd_value]");
+ ANN(" where [attr]: [nd_next->nd_vid]");
+ ANN("example: struct.field += foo");
+ F_NODE(nd_recv, "receiver");
+ F_CUSTOM1(nd_next->nd_vid, "attr") {
+ if (node->nd_next->nd_aid) A("? ");
+ A_ID(node->nd_next->nd_vid);
+ }
+ F_ID(nd_next->nd_mid, "operator");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+
+ case NODE_OP_ASGN_AND:
+ ANN("assignment with && operator");
+ ANN("format: [nd_head] &&= [nd_value]");
+ ANN("example: foo &&= bar");
+ goto asgn_andor;
+ case NODE_OP_ASGN_OR:
+ ANN("assignment with || operator");
+ ANN("format: [nd_head] ||= [nd_value]");
+ ANN("example: foo ||= bar");
+ asgn_andor:
+ F_NODE(nd_head, "variable");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+
+ case NODE_OP_CDECL:
+ ANN("constant declaration with operator");
+ ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
+ ANN("example: A::B ||= 1");
+ F_NODE(nd_head, "constant");
+ F_ID(nd_aid, "operator");
+ LAST_NODE;
+ F_NODE(nd_value, "rvalue");
+ return;
+
+ case NODE_CALL:
+ ANN("method invocation");
+ ANN("format: [nd_recv].[nd_mid]([nd_args])");
+ ANN("example: obj.foo(1)");
+ F_ID(nd_mid, "method id");
+ F_NODE(nd_recv, "receiver");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
+
+ case NODE_OPCALL:
+ ANN("method invocation");
+ ANN("format: [nd_recv] [nd_mid] [nd_args]");
+ ANN("example: foo + bar");
+ F_ID(nd_mid, "method id");
+ F_NODE(nd_recv, "receiver");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
+
+ case NODE_FCALL:
+ ANN("function call");
+ ANN("format: [nd_mid]([nd_args])");
+ ANN("example: foo(1)");
+ F_ID(nd_mid, "method id");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
+
+ case NODE_VCALL:
+ ANN("function call with no argument");
+ ANN("format: [nd_mid]");
+ ANN("example: foo");
+ F_ID(nd_mid, "method id");
+ return;
+
+ case NODE_QCALL:
+ ANN("safe method invocation");
+ ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
+ ANN("example: obj&.foo(1)");
+ F_ID(nd_mid, "method id");
+ F_NODE(nd_recv, "receiver");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
+
+ case NODE_SUPER:
+ ANN("super invocation");
+ ANN("format: super [nd_args]");
+ ANN("example: super 1");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
+
+ case NODE_ZSUPER:
+ ANN("super invocation with no argument");
+ ANN("format: super");
+ ANN("example: super");
+ return;
+
+ case NODE_LIST:
+ ANN("list constructor");
+ ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
+ ANN("example: [1, 2, 3]");
+ goto ary;
+ case NODE_VALUES:
+ ANN("return arguments");
+ ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
+ ANN("example: return 1, 2, 3");
+ ary:
+ dump_array(buf, indent, comment, node);
+ return;
+
+ case NODE_ZLIST:
+ ANN("empty list constructor");
+ ANN("format: []");
+ ANN("example: []");
+ return;
+
+ case NODE_HASH:
+ if (!node->nd_brace) {
+ ANN("keyword arguments");
+ ANN("format: nd_head");
+ ANN("example: a: 1, b: 2");
+ }
+ else {
+ ANN("hash constructor");
+ ANN("format: { [nd_head] }");
+ ANN("example: { 1 => 2, 3 => 4 }");
+ }
+ F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
+ switch (node->nd_brace) {
+ case 0: A("0 (keyword argument)"); break;
+ case 1: A("1 (hash literal)"); break;
+ }
+ }
+ LAST_NODE;
+ F_NODE(nd_head, "contents");
+ return;
+
+ case NODE_YIELD:
+ ANN("yield invocation");
+ ANN("format: yield [nd_head]");
+ ANN("example: yield 1");
+ LAST_NODE;
+ F_NODE(nd_head, "arguments");
+ return;
+
+ case NODE_LVAR:
+ ANN("local variable reference");
+ ANN("format: [nd_vid](lvar)");
+ ANN("example: x");
+ F_ID(nd_vid, "local variable");
+ return;
+ case NODE_DVAR:
+ ANN("dynamic variable reference");
+ ANN("format: [nd_vid](dvar)");
+ ANN("example: 1.times { x = 1; x }");
+ F_ID(nd_vid, "local variable");
+ return;
+ case NODE_IVAR:
+ ANN("instance variable reference");
+ ANN("format: [nd_vid](ivar)");
+ ANN("example: @x");
+ F_ID(nd_vid, "instance variable");
+ return;
+ case NODE_CONST:
+ ANN("constant reference");
+ ANN("format: [nd_vid](constant)");
+ ANN("example: X");
+ F_ID(nd_vid, "constant");
+ return;
+ case NODE_CVAR:
+ ANN("class variable reference");
+ ANN("format: [nd_vid](cvar)");
+ ANN("example: @@x");
+ F_ID(nd_vid, "class variable");
+ return;
+
+ case NODE_GVAR:
+ ANN("global variable reference");
+ ANN("format: [nd_entry](gvar)");
+ ANN("example: $x");
+ F_GENTRY(nd_entry, "global variable");
+ return;
+
+ case NODE_NTH_REF:
+ ANN("nth special variable reference");
+ ANN("format: $[nd_nth]");
+ ANN("example: $1, $2, ..");
+ F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(node->nd_nth); }
+ return;
+
+ case NODE_BACK_REF:
+ ANN("back special variable reference");
+ ANN("format: $[nd_nth]");
+ ANN("example: $&, $`, $', $+");
+ F_CUSTOM1(nd_nth, "variable") {
+ char name[3] = "$ ";
+ name[1] = (char)node->nd_nth;
+ A(name);
+ }
+ return;
+
+ case NODE_MATCH:
+ ANN("match expression (against $_ implicitly)");
+ ANN("format: [nd_lit] (in condition)");
+ ANN("example: if /foo/; foo; end");
+ F_LIT(nd_lit, "regexp");
+ return;
+
+ case NODE_MATCH2:
+ ANN("match expression (regexp first)");
+ ANN("format: [nd_recv] =~ [nd_value]");
+ ANN("example: /foo/ =~ 'foo'");
+ F_NODE(nd_recv, "regexp (receiver)");
+ if (!node->nd_args) LAST_NODE;
+ F_NODE(nd_value, "string (argument)");
+ if (node->nd_args) {
+ LAST_NODE;
+ F_NODE(nd_args, "named captures");
+ }
+ return;
+
+ case NODE_MATCH3:
+ ANN("match expression (regexp second)");
+ ANN("format: [nd_recv] =~ [nd_value]");
+ ANN("example: 'foo' =~ /foo/");
+ F_NODE(nd_recv, "string (receiver)");
+ LAST_NODE;
+ F_NODE(nd_value, "regexp (argument)");
+ return;
+
+ case NODE_LIT:
+ ANN("literal");
+ ANN("format: [nd_lit]");
+ ANN("example: 1, /foo/");
+ goto lit;
+ case NODE_STR:
+ ANN("string literal");
+ ANN("format: [nd_lit]");
+ ANN("example: 'foo'");
+ goto lit;
+ case NODE_XSTR:
+ ANN("xstring literal");
+ ANN("format: [nd_lit]");
+ ANN("example: `foo`");
+ lit:
+ F_LIT(nd_lit, "literal");
+ return;
+
+ case NODE_ONCE:
+ ANN("once evaluation");
+ ANN("format: [nd_body]");
+ ANN("example: /foo#{ bar }baz/o");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
+ case NODE_DSTR:
+ ANN("string literal with interpolation");
+ ANN("format: [nd_lit]");
+ ANN("example: \"foo#{ bar }baz\"");
+ goto dlit;
+ case NODE_DXSTR:
+ ANN("xstring literal with interpolation");
+ ANN("format: [nd_lit]");
+ ANN("example: `foo#{ bar }baz`");
+ goto dlit;
+ case NODE_DREGX:
+ ANN("regexp literal with interpolation");
+ ANN("format: [nd_lit]");
+ ANN("example: /foo#{ bar }baz/");
+ goto dlit;
+ case NODE_DSYM:
+ ANN("symbol literal with interpolation");
+ ANN("format: [nd_lit]");
+ ANN("example: :\"foo#{ bar }baz\"");
+ dlit:
+ F_LIT(nd_lit, "preceding string");
+ if (!node->nd_next) return;
+ F_NODE(nd_next->nd_head, "interpolation");
+ LAST_NODE;
+ F_NODE(nd_next->nd_next, "tailing strings");
+ return;
+
+ case NODE_EVSTR:
+ ANN("interpolation expression");
+ ANN("format: \"..#{ [nd_lit] }..\"");
+ ANN("example: \"foo#{ bar }baz\"");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
+
+ case NODE_ARGSCAT:
+ ANN("splat argument following arguments");
+ ANN("format: ..(*[nd_head], [nd_body..])");
+ ANN("example: foo(*ary, post_arg1, post_arg2)");
+ F_NODE(nd_head, "preceding array");
+ LAST_NODE;
+ F_NODE(nd_body, "following array");
+ return;
+
+ case NODE_ARGSPUSH:
+ ANN("splat argument following one argument");
+ ANN("format: ..(*[nd_head], [nd_body])");
+ ANN("example: foo(*ary, post_arg)");
+ F_NODE(nd_head, "preceding array");
+ LAST_NODE;
+ F_NODE(nd_body, "following element");
+ return;
+
+ case NODE_SPLAT:
+ ANN("splat argument");
+ ANN("format: *[nd_head]");
+ ANN("example: foo(*ary)");
+ LAST_NODE;
+ F_NODE(nd_head, "splat'ed array");
+ return;
+
+ case NODE_BLOCK_PASS:
+ ANN("arguments with block argument");
+ ANN("format: ..([nd_head], &[nd_body])");
+ ANN("example: foo(x, &blk)");
+ F_NODE(nd_head, "other arguments");
+ LAST_NODE;
+ F_NODE(nd_body, "block argument");
+ return;
+
+ case NODE_DEFN:
+ ANN("method definition");
+ ANN("format: def [nd_mid] [nd_defn]; end");
+ ANN("example: def foo; bar; end");
+ F_ID(nd_mid, "method name");
+ LAST_NODE;
+ F_NODE(nd_defn, "method definition");
+ return;
+
+ case NODE_DEFS:
+ ANN("singleton method definition");
+ ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
+ ANN("example: def obj.foo; bar; end");
+ F_NODE(nd_recv, "receiver");
+ F_ID(nd_mid, "method name");
+ LAST_NODE;
+ F_NODE(nd_defn, "method definition");
+ return;
+
+ case NODE_ALIAS:
+ ANN("method alias statement");
+ ANN("format: alias [nd_1st] [nd_2nd]");
+ ANN("example: alias bar foo");
+ F_NODE(nd_1st, "new name");
+ LAST_NODE;
+ F_NODE(nd_2nd, "old name");
+ return;
+
+ case NODE_VALIAS:
+ ANN("global variable alias statement");
+ ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
+ ANN("example: alias $y $x");
+ F_ID(nd_alias, "new name");
+ F_ID(nd_orig, "old name");
+ return;
+
+ case NODE_UNDEF:
+ ANN("method undef statement");
+ ANN("format: undef [nd_undef]");
+ ANN("example: undef foo");
+ LAST_NODE;
+ F_NODE(nd_undef, "old name");
+ return;
+
+ case NODE_CLASS:
+ ANN("class definition");
+ ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
+ ANN("example: class C2 < C; ..; end");
+ F_NODE(nd_cpath, "class path");
+ F_NODE(nd_super, "superclass");
+ LAST_NODE;
+ F_NODE(nd_body, "class definition");
+ return;
+
+ case NODE_MODULE:
+ ANN("module definition");
+ ANN("format: module [nd_cpath]; [nd_body]; end");
+ ANN("example: module M; ..; end");
+ F_NODE(nd_cpath, "module path");
+ LAST_NODE;
+ F_NODE(nd_body, "module definition");
+ return;
+
+ case NODE_SCLASS:
+ ANN("singleton class definition");
+ ANN("format: class << [nd_recv]; [nd_body]; end");
+ ANN("example: class << obj; ..; end");
+ F_NODE(nd_recv, "receiver");
+ LAST_NODE;
+ F_NODE(nd_body, "singleton class definition");
+ return;
+
+ case NODE_COLON2:
+ ANN("scoped constant reference");
+ ANN("format: [nd_head]::[nd_mid]");
+ ANN("example: M::C");
+ F_ID(nd_mid, "constant name");
+ LAST_NODE;
+ F_NODE(nd_head, "receiver");
+ return;
+
+ case NODE_COLON3:
+ ANN("top-level constant reference");
+ ANN("format: ::[nd_mid]");
+ ANN("example: ::Object");
+ F_ID(nd_mid, "constant name");
+ return;
+
+ case NODE_DOT2:
+ ANN("range constructor (incl.)");
+ ANN("format: [nd_beg]..[nd_end]");
+ ANN("example: 1..5");
+ goto dot;
+ case NODE_DOT3:
+ ANN("range constructor (excl.)");
+ ANN("format: [nd_beg]...[nd_end]");
+ ANN("example: 1...5");
+ goto dot;
+ case NODE_FLIP2:
+ ANN("flip-flop condition (incl.)");
+ ANN("format: [nd_beg]..[nd_end]");
+ ANN("example: if (x==1)..(x==5); foo; end");
+ goto dot;
+ case NODE_FLIP3:
+ ANN("flip-flop condition (excl.)");
+ ANN("format: [nd_beg]...[nd_end]");
+ ANN("example: if (x==1)...(x==5); foo; end");
+ dot:
+ F_NODE(nd_beg, "begin");
+ LAST_NODE;
+ F_NODE(nd_end, "end");
+ return;
+
+ case NODE_SELF:
+ ANN("self");
+ ANN("format: self");
+ ANN("example: self");
+ return;
+
+ case NODE_NIL:
+ ANN("nil");
+ ANN("format: nil");
+ ANN("example: nil");
+ return;
+
+ case NODE_TRUE:
+ ANN("true");
+ ANN("format: true");
+ ANN("example: true");
+ return;
+
+ case NODE_FALSE:
+ ANN("false");
+ ANN("format: false");
+ ANN("example: false");
+ return;
+
+ case NODE_ERRINFO:
+ ANN("virtual reference to $!");
+ ANN("format: rescue => id");
+ ANN("example: rescue => id");
+ return;
+
+ case NODE_DEFINED:
+ ANN("defined? expression");
+ ANN("format: defined?([nd_head])");
+ ANN("example: defined?(foo)");
+ F_NODE(nd_head, "expr");
+ return;
+
+ case NODE_POSTEXE:
+ ANN("post-execution");
+ ANN("format: END { [nd_body] }");
+ ANN("example: END { foo }");
+ LAST_NODE;
+ F_NODE(nd_body, "END clause");
+ return;
+
+ case NODE_ATTRASGN:
+ ANN("attr assignment");
+ ANN("format: [nd_recv].[nd_mid] = [nd_args]");
+ ANN("example: struct.field = foo");
+ F_NODE(nd_recv, "receiver");
+ F_ID(nd_mid, "method name");
+ LAST_NODE;
+ F_NODE(nd_args, "arguments");
+ return;
+
+ case NODE_LAMBDA:
+ ANN("lambda expression");
+ ANN("format: -> [nd_body]");
+ ANN("example: -> { foo }");
+ LAST_NODE;
+ F_NODE(nd_body, "lambda clause");
+ return;
+
+ case NODE_OPT_ARG:
+ ANN("optional arguments");
+ ANN("format: def method_name([nd_body=some], [nd_next..])");
+ ANN("example: def foo(a, b=1, c); end");
+ F_NODE(nd_body, "body");
+ LAST_NODE;
+ F_NODE(nd_next, "next");
+ return;
+
+ case NODE_KW_ARG:
+ ANN("keyword arguments");
+ ANN("format: def method_name([nd_body=some], [nd_next..])");
+ ANN("example: def foo(a:1, b:2); end");
+ F_NODE(nd_body, "body");
+ LAST_NODE;
+ F_NODE(nd_next, "next");
+ return;
+
+ case NODE_POSTARG:
+ ANN("post arguments");
+ ANN("format: *[nd_1st], [nd_2nd..] = ..");
+ ANN("example: a, *rest, z = foo");
+ if (NODE_NAMED_REST_P(node->nd_1st)) {
+ F_NODE(nd_1st, "rest argument");
+ }
+ else {
+ F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ LAST_NODE;
+ F_NODE(nd_2nd, "post arguments");
+ return;
+
+ case NODE_ARGS:
+ ANN("method parameters");
+ ANN("format: def method_name(.., [nd_ainfo->nd_optargs], *[nd_ainfo->rest_arg], [nd_ainfo->first_post_arg], .., [nd_ainfo->kw_args], **[nd_ainfo->kw_rest_arg], &[nd_ainfo->block_arg])");
+ ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, kw: 1, **kwrest, &blk); end");
+ F_INT(nd_ainfo->pre_args_num, "count of mandatory (pre-)arguments");
+ F_NODE(nd_ainfo->pre_init, "initialization of (pre-)arguments");
+ F_INT(nd_ainfo->post_args_num, "count of mandatory post-arguments");
+ F_NODE(nd_ainfo->post_init, "initialization of post-arguments");
+ F_ID(nd_ainfo->first_post_arg, "first post argument");
+ F_CUSTOM1(nd_ainfo->rest_arg, "rest argument") {
+ if (node->nd_ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
+ A("1 (excessed comma)");
+ }
+ else {
+ A_ID(node->nd_ainfo->rest_arg);
+ }
+ }
+ F_ID(nd_ainfo->block_arg, "block argument");
+ F_NODE(nd_ainfo->opt_args, "optional arguments");
+ F_NODE(nd_ainfo->kw_args, "keyword arguments");
+ LAST_NODE;
+ F_NODE(nd_ainfo->kw_rest_arg, "keyword rest argument");
+ return;
+
+ case NODE_SCOPE:
+ ANN("new scope");
+ ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
+ F_CUSTOM1(nd_tbl, "local table") {
+ rb_ast_id_table_t *tbl = node->nd_tbl;
+ int i;
+ int size = tbl ? tbl->size : 0;
+ if (size == 0) A("(empty)");
+ for (i = 0; i < size; i++) {
+ A_ID(tbl->ids[i]); if (i < size - 1) A(",");
+ }
+ }
+ F_NODE(nd_args, "arguments");
+ LAST_NODE;
+ F_NODE(nd_body, "body");
+ return;
+
+ case NODE_ARYPTN:
+ ANN("array pattern");
+ ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
+ F_NODE(nd_pconst, "constant");
+ F_NODE(nd_apinfo->pre_args, "pre arguments");
+ if (NODE_NAMED_REST_P(node->nd_apinfo->rest_arg)) {
+ F_NODE(nd_apinfo->rest_arg, "rest argument");
+ }
+ else {
+ F_MSG(nd_apinfo->rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ LAST_NODE;
+ F_NODE(nd_apinfo->post_args, "post arguments");
+ return;
+
+ case NODE_FNDPTN:
+ ANN("find pattern");
+ ANN("format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])");
+ F_NODE(nd_pconst, "constant");
+ if (NODE_NAMED_REST_P(node->nd_fpinfo->pre_rest_arg)) {
+ F_NODE(nd_fpinfo->pre_rest_arg, "pre rest argument");
+ }
+ else {
+ F_MSG(nd_fpinfo->pre_rest_arg, "pre rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ F_NODE(nd_fpinfo->args, "arguments");
+
+ LAST_NODE;
+ if (NODE_NAMED_REST_P(node->nd_fpinfo->post_rest_arg)) {
+ F_NODE(nd_fpinfo->post_rest_arg, "post rest argument");
+ }
+ else {
+ F_MSG(nd_fpinfo->post_rest_arg, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
+ return;
+
+ case NODE_HSHPTN:
+ ANN("hash pattern");
+ ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
+ F_NODE(nd_pconst, "constant");
+ F_NODE(nd_pkwargs, "keyword arguments");
+ LAST_NODE;
+ if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
+ F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
+ }
+ else {
+ F_NODE(nd_pkwrestarg, "keyword rest argument");
+ }
+ return;
+ case NODE_ERROR:
+ ANN("Broken input recovered by Error Tolerant mode");
+ return;
+
+ case NODE_ARGS_AUX:
+ case NODE_LAST:
+ break;
+ }
+
+ rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
+}
+
+VALUE
+rb_parser_dump_tree(const NODE *node, int comment)
+{
+ VALUE buf = rb_str_new_cstr(
+ "###########################################################\n"
+ "## Do NOT use this node dump for any purpose other than ##\n"
+ "## debug and research. Compatibility is not guaranteed. ##\n"
+ "###########################################################\n\n"
+ );
+ dump_node(buf, rb_str_new_cstr("# "), comment, node);
+ return buf;
+}
/* Setup NODE structure.
* NODE is not an object managed by GC, but it imitates an object
@@ -107,58 +1130,83 @@ static void iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_
* objects.
*/
void
-rb_node_init(NODE *n, enum node_type type)
+rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
- RNODE(n)->flags = T_NODE;
- nd_init_type(RNODE(n), type);
- RNODE(n)->nd_loc.beg_pos.lineno = 0;
- RNODE(n)->nd_loc.beg_pos.column = 0;
- RNODE(n)->nd_loc.end_pos.lineno = 0;
- RNODE(n)->nd_loc.end_pos.column = 0;
- RNODE(n)->node_id = -1;
+ n->flags = T_NODE;
+ nd_init_type(n, type);
+ n->u1.value = a0;
+ n->u2.value = a1;
+ n->u3.value = a2;
+ n->nd_loc.beg_pos.lineno = 0;
+ n->nd_loc.beg_pos.column = 0;
+ n->nd_loc.end_pos.lineno = 0;
+ n->nd_loc.end_pos.column = 0;
+ n->node_id = -1;
}
-const char *
-rb_node_name(int node)
-{
- switch (node) {
-#include "node_name.inc"
- default:
- return 0;
- }
-}
+typedef struct node_buffer_elem_struct {
+ struct node_buffer_elem_struct *next;
+ long len;
+ NODE buf[FLEX_ARY_LEN];
+} node_buffer_elem_t;
+
+typedef struct {
+ long idx, len;
+ node_buffer_elem_t *head;
+ node_buffer_elem_t *last;
+} node_buffer_list_t;
+
+struct node_buffer_struct {
+ node_buffer_list_t unmarkable;
+ node_buffer_list_t markable;
+ struct rb_ast_local_table_link *local_tables;
+ VALUE mark_hash;
+ // - id (sequence number)
+ // - token_type
+ // - text of token
+ // - location info
+ // Array, whose entry is array
+ VALUE tokens;
+};
-#ifdef UNIVERSAL_PARSER
-const char *
-ruby_node_name(int node)
+static void
+init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
{
- return rb_node_name(node);
+ nb->idx = 0;
+ nb->len = NODE_BUF_DEFAULT_LEN;
+ nb->head = nb->last = head;
+ nb->head->len = nb->len;
+ nb->head->next = NULL;
}
-#else
-const char *
-ruby_node_name(int node)
-{
- const char *name = rb_node_name(node);
- if (!name) rb_bug("unknown node: %d", node);
- return name;
+static node_buffer_t *
+rb_node_buffer_new(void)
+{
+ const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
+ const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
+ STATIC_ASSERT(
+ integer_overflow,
+ offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE)
+ > sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
+ node_buffer_t *nb = ruby_xmalloc(alloc_size);
+ init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
+ init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
+ nb->local_tables = 0;
+ nb->mark_hash = Qnil;
+ nb->tokens = Qnil;
+ return nb;
}
-#endif
static void
-node_buffer_list_free(rb_ast_t *ast, node_buffer_list_t * nb)
+node_buffer_list_free(node_buffer_list_t * nb)
{
node_buffer_elem_t *nbe = nb->head;
+
while (nbe != nb->last) {
void *buf = nbe;
- xfree(nbe->nodes);
nbe = nbe->next;
xfree(buf);
}
-
- /* The last node_buffer_elem_t is allocated in the node_buffer_t, so we
- * only need to free the nodes. */
- xfree(nbe->nodes);
}
struct rb_ast_local_table_link {
@@ -170,20 +1218,10 @@ struct rb_ast_local_table_link {
};
static void
-free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
-{
- switch (nd_type(node)) {
- default:
- break;
- }
-}
-
-static void
-rb_node_buffer_free(rb_ast_t *ast, node_buffer_t *nb)
+rb_node_buffer_free(node_buffer_t *nb)
{
- iterate_node_values(ast, &nb->unmarkable, free_ast_value, NULL);
- node_buffer_list_free(ast, &nb->unmarkable);
- node_buffer_list_free(ast, &nb->markable);
+ node_buffer_list_free(&nb->unmarkable);
+ node_buffer_list_free(&nb->markable);
struct rb_ast_local_table_link *local_table = nb->local_tables;
while (local_table) {
struct rb_ast_local_table_link *next_table = local_table->next;
@@ -193,31 +1231,20 @@ rb_node_buffer_free(rb_ast_t *ast, node_buffer_t *nb)
xfree(nb);
}
-#define buf_add_offset(nbe, offset) ((char *)(nbe->buf) + (offset))
-
static NODE *
-ast_newnode_in_bucket(rb_ast_t *ast, node_buffer_list_t *nb, size_t size, size_t alignment)
+ast_newnode_in_bucket(node_buffer_list_t *nb)
{
- size_t padding;
- NODE *ptr;
-
- padding = alignment - (size_t)buf_add_offset(nb->head, nb->head->used) % alignment;
- padding = padding == alignment ? 0 : padding;
-
- if (nb->head->used + size + padding > nb->head->allocated) {
- size_t n = nb->head->allocated * 2;
+ if (nb->idx >= nb->len) {
+ long n = nb->len * 2;
node_buffer_elem_t *nbe;
- nbe = rb_xmalloc_mul_add(n, sizeof(char *), offsetof(node_buffer_elem_t, buf));
- init_node_buffer_elem(nbe, n, ruby_xmalloc);
+ nbe = rb_xmalloc_mul_add(n, sizeof(NODE), offsetof(node_buffer_elem_t, buf));
+ nbe->len = n;
+ nb->idx = 0;
+ nb->len = n;
nbe->next = nb->head;
nb->head = nbe;
- padding = 0; /* malloc returns aligned address then no need to add padding */
}
-
- ptr = (NODE *)buf_add_offset(nb->head, nb->head->used + padding);
- nb->head->used += (size + padding);
- nb->head->nodes[nb->head->len++] = ptr;
- return ptr;
+ return &nb->head->buf[nb->idx++];
}
RBIMPL_ATTR_PURE()
@@ -233,6 +1260,9 @@ nodetype_markable_p(enum node_type type)
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
+ case NODE_ARGS:
+ case NODE_ARYPTN:
+ case NODE_FNDPTN:
return true;
default:
return false;
@@ -240,15 +1270,14 @@ nodetype_markable_p(enum node_type type)
}
NODE *
-rb_ast_newnode(rb_ast_t *ast, enum node_type type, size_t size, size_t alignment)
+rb_ast_newnode(rb_ast_t *ast, enum node_type type)
{
node_buffer_t *nb = ast->node_buffer;
node_buffer_list_t *bucket =
(nodetype_markable_p(type) ? &nb->markable : &nb->unmarkable);
- return ast_newnode_in_bucket(ast, bucket, size, alignment);
+ return ast_newnode_in_bucket(bucket);
}
-#if RUBY_DEBUG
void
rb_ast_node_type_change(NODE *n, enum node_type type)
{
@@ -258,7 +1287,6 @@ rb_ast_node_type_change(NODE *n, enum node_type type)
ruby_node_name(old_type), ruby_node_name(type));
}
}
-#endif
rb_ast_id_table_t *
rb_ast_new_local_table(rb_ast_t *ast, int size)
@@ -292,15 +1320,6 @@ rb_ast_delete_node(rb_ast_t *ast, NODE *n)
/* should we implement freelist? */
}
-#ifdef UNIVERSAL_PARSER
-rb_ast_t *
-rb_ast_new(rb_parser_config_t *config)
-{
- node_buffer_t *nb = rb_node_buffer_new(config);
- config->counter++;
- return config->ast_new((VALUE)nb);
-}
-#else
rb_ast_t *
rb_ast_new(void)
{
@@ -308,36 +1327,43 @@ rb_ast_new(void)
rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, (VALUE)nb);
return ast;
}
-#endif
+
+typedef void node_itr_t(void *ctx, NODE * node);
static void
-iterate_buffer_elements(rb_ast_t *ast, node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
+iterate_buffer_elements(node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
{
long cursor;
for (cursor = 0; cursor < len; cursor++) {
- func(ast, ctx, nbe->nodes[cursor]);
+ func(ctx, &nbe->buf[cursor]);
}
}
static void
-iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, void *ctx)
+iterate_node_values(node_buffer_list_t *nb, node_itr_t * func, void *ctx)
{
node_buffer_elem_t *nbe = nb->head;
+ /* iterate over the head first because it's not full */
+ iterate_buffer_elements(nbe, nb->idx, func, ctx);
+
+ nbe = nbe->next;
while (nbe) {
- iterate_buffer_elements(ast, nbe, nbe->len, func, ctx);
+ iterate_buffer_elements(nbe, nbe->len, func, ctx);
nbe = nbe->next;
}
}
static void
-mark_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
+mark_ast_value(void *ctx, NODE * node)
{
-#ifdef UNIVERSAL_PARSER
- bug_report_func rb_bug = ast->node_buffer->config->bug;
-#endif
-
switch (nd_type(node)) {
+ case NODE_ARGS:
+ {
+ struct rb_args_info *args = node->nd_ainfo;
+ rb_gc_mark_movable(args->imemo);
+ break;
+ }
case NODE_MATCH:
case NODE_LIT:
case NODE_STR:
@@ -346,7 +1372,11 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
- rb_gc_mark_movable(RNODE_LIT(node)->nd_lit);
+ rb_gc_mark_movable(node->nd_lit);
+ break;
+ case NODE_ARYPTN:
+ case NODE_FNDPTN:
+ rb_gc_mark_movable(node->nd_rval);
break;
default:
rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
@@ -354,13 +1384,15 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
}
static void
-update_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
+update_ast_value(void *ctx, NODE * node)
{
-#ifdef UNIVERSAL_PARSER
- bug_report_func rb_bug = ast->node_buffer->config->bug;
-#endif
-
switch (nd_type(node)) {
+ case NODE_ARGS:
+ {
+ struct rb_args_info *args = node->nd_ainfo;
+ args->imemo = rb_gc_location(args->imemo);
+ break;
+ }
case NODE_MATCH:
case NODE_LIT:
case NODE_STR:
@@ -369,7 +1401,11 @@ update_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
- RNODE_LIT(node)->nd_lit = rb_gc_location(RNODE_LIT(node)->nd_lit);
+ node->nd_lit = rb_gc_location(node->nd_lit);
+ break;
+ case NODE_ARYPTN:
+ case NODE_FNDPTN:
+ node->nd_rval = rb_gc_location(node->nd_rval);
break;
default:
rb_bug("unreachable");
@@ -382,7 +1418,7 @@ rb_ast_update_references(rb_ast_t *ast)
if (ast->node_buffer) {
node_buffer_t *nb = ast->node_buffer;
- iterate_node_values(ast, &nb->markable, update_ast_value, NULL);
+ iterate_node_values(&nb->markable, update_ast_value, NULL);
}
}
@@ -392,28 +1428,22 @@ rb_ast_mark(rb_ast_t *ast)
if (ast->node_buffer) {
rb_gc_mark(ast->node_buffer->mark_hash);
rb_gc_mark(ast->node_buffer->tokens);
+ }
+ if (ast->body.compile_option) rb_gc_mark(ast->body.compile_option);
+ if (ast->node_buffer) {
node_buffer_t *nb = ast->node_buffer;
- iterate_node_values(ast, &nb->markable, mark_ast_value, NULL);
- if (ast->body.script_lines) rb_gc_mark(ast->body.script_lines);
+
+ iterate_node_values(&nb->markable, mark_ast_value, NULL);
}
+ if (ast->body.script_lines) rb_gc_mark(ast->body.script_lines);
}
void
rb_ast_free(rb_ast_t *ast)
{
if (ast->node_buffer) {
-#ifdef UNIVERSAL_PARSER
- rb_parser_config_t *config = ast->node_buffer->config;
-#endif
-
- rb_node_buffer_free(ast, ast->node_buffer);
+ rb_node_buffer_free(ast->node_buffer);
ast->node_buffer = 0;
-#ifdef UNIVERSAL_PARSER
- config->counter--;
- if (config->counter <= 0) {
- rb_ruby_parser_config_free(config);
- }
-#endif
}
}
@@ -423,8 +1453,8 @@ buffer_list_size(node_buffer_list_t *nb)
size_t size = 0;
node_buffer_elem_t *nbe = nb->head;
while (nbe != nb->last) {
- size += offsetof(node_buffer_elem_t, buf) + nbe->used;
nbe = nbe->next;
+ size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
}
return size;
}
@@ -436,7 +1466,7 @@ rb_ast_memsize(const rb_ast_t *ast)
node_buffer_t *nb = ast->node_buffer;
if (nb) {
- size += sizeof(node_buffer_t);
+ size += sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
size += buffer_list_size(&nb->unmarkable);
size += buffer_list_size(&nb->markable);
}
@@ -458,13 +1488,6 @@ rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
rb_hash_aset(ast->node_buffer->mark_hash, obj, Qtrue);
}
-void
-rb_ast_delete_mark_object(rb_ast_t *ast, VALUE obj)
-{
- if (NIL_P(ast->node_buffer->mark_hash)) return;
- rb_hash_delete(ast->node_buffer->mark_hash, obj);
-}
-
VALUE
rb_ast_tokens(rb_ast_t *ast)
{
@@ -476,12 +1499,3 @@ rb_ast_set_tokens(rb_ast_t *ast, VALUE tokens)
{
RB_OBJ_WRITE(ast, &ast->node_buffer->tokens, tokens);
}
-
-VALUE
-rb_node_set_type(NODE *n, enum node_type t)
-{
-#if RUBY_DEBUG
- rb_ast_node_type_change(n, t);
-#endif
- return nd_init_type(n, t);
-}
diff --git a/node.h b/node.h
index d8d104975a..befb1328fb 100644
--- a/node.h
+++ b/node.h
@@ -11,118 +11,504 @@
**********************************************************************/
-#include <stdbool.h>
-#include "rubyparser.h"
-#include "ruby/backward/2/attributes.h"
-
-typedef void (*bug_report_func)(const char *fmt, ...);
-
-typedef struct node_buffer_elem_struct {
- struct node_buffer_elem_struct *next;
- long len; /* Length of nodes */
- size_t allocated; /* Total memory size of allocated buf */
- size_t used; /* Current usage of buf */
- NODE **nodes; /* Array of node pointers */
- NODE *buf[FLEX_ARY_LEN];
-} node_buffer_elem_t;
-
-typedef struct {
- node_buffer_elem_t *head;
- node_buffer_elem_t *last;
-} node_buffer_list_t;
-
-struct node_buffer_struct {
- node_buffer_list_t unmarkable;
- node_buffer_list_t markable;
- struct rb_ast_local_table_link *local_tables;
- VALUE mark_hash;
- // - id (sequence number)
- // - token_type
- // - text of token
- // - location info
- // Array, whose entry is array
- VALUE tokens;
-#ifdef UNIVERSAL_PARSER
- rb_parser_config_t *config;
+#include "internal/compilers.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#if 0
+} /* satisfy cc-mode */
+#endif
#endif
+
+enum node_type {
+ NODE_SCOPE,
+ NODE_BLOCK,
+ NODE_IF,
+ NODE_UNLESS,
+ NODE_CASE,
+ NODE_CASE2,
+ NODE_CASE3,
+ NODE_WHEN,
+ NODE_IN,
+ NODE_WHILE,
+ NODE_UNTIL,
+ NODE_ITER,
+ NODE_FOR,
+ NODE_FOR_MASGN,
+ NODE_BREAK,
+ NODE_NEXT,
+ NODE_REDO,
+ NODE_RETRY,
+ NODE_BEGIN,
+ NODE_RESCUE,
+ NODE_RESBODY,
+ NODE_ENSURE,
+ NODE_AND,
+ NODE_OR,
+ NODE_MASGN,
+ NODE_LASGN,
+ NODE_DASGN,
+ NODE_GASGN,
+ NODE_IASGN,
+ NODE_CDECL,
+ NODE_CVASGN,
+ NODE_OP_ASGN1,
+ NODE_OP_ASGN2,
+ NODE_OP_ASGN_AND,
+ NODE_OP_ASGN_OR,
+ NODE_OP_CDECL,
+ NODE_CALL,
+ NODE_OPCALL,
+ NODE_FCALL,
+ NODE_VCALL,
+ NODE_QCALL,
+ NODE_SUPER,
+ NODE_ZSUPER,
+ NODE_LIST,
+ NODE_ZLIST,
+ NODE_VALUES,
+ NODE_HASH,
+ NODE_RETURN,
+ NODE_YIELD,
+ NODE_LVAR,
+ NODE_DVAR,
+ NODE_GVAR,
+ NODE_IVAR,
+ NODE_CONST,
+ NODE_CVAR,
+ NODE_NTH_REF,
+ NODE_BACK_REF,
+ NODE_MATCH,
+ NODE_MATCH2,
+ NODE_MATCH3,
+ NODE_LIT,
+ NODE_STR,
+ NODE_DSTR,
+ NODE_XSTR,
+ NODE_DXSTR,
+ NODE_EVSTR,
+ NODE_DREGX,
+ NODE_ONCE,
+ NODE_ARGS,
+ NODE_ARGS_AUX,
+ NODE_OPT_ARG,
+ NODE_KW_ARG,
+ NODE_POSTARG,
+ NODE_ARGSCAT,
+ NODE_ARGSPUSH,
+ NODE_SPLAT,
+ NODE_BLOCK_PASS,
+ NODE_DEFN,
+ NODE_DEFS,
+ NODE_ALIAS,
+ NODE_VALIAS,
+ NODE_UNDEF,
+ NODE_CLASS,
+ NODE_MODULE,
+ NODE_SCLASS,
+ NODE_COLON2,
+ NODE_COLON3,
+ NODE_DOT2,
+ NODE_DOT3,
+ NODE_FLIP2,
+ NODE_FLIP3,
+ NODE_SELF,
+ NODE_NIL,
+ NODE_TRUE,
+ NODE_FALSE,
+ NODE_ERRINFO,
+ NODE_DEFINED,
+ NODE_POSTEXE,
+ NODE_DSYM,
+ NODE_ATTRASGN,
+ NODE_LAMBDA,
+ NODE_ARYPTN,
+ NODE_HSHPTN,
+ NODE_FNDPTN,
+ NODE_ERROR,
+ NODE_LAST
};
+typedef struct rb_code_position_struct {
+ int lineno;
+ int column;
+} rb_code_position_t;
+
+typedef struct rb_code_location_struct {
+ rb_code_position_t beg_pos;
+ rb_code_position_t end_pos;
+} rb_code_location_t;
+
+static inline rb_code_location_t
+code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2)
+{
+ rb_code_location_t loc;
+ loc.beg_pos = loc1->beg_pos;
+ loc.end_pos = loc2->end_pos;
+ return loc;
+}
+
+typedef struct rb_ast_id_table {
+ int size;
+ ID ids[FLEX_ARY_LEN];
+} rb_ast_id_table_t;
+
+typedef struct RNode {
+ VALUE flags;
+ union {
+ struct RNode *node;
+ ID id;
+ VALUE value;
+ rb_ast_id_table_t *tbl;
+ } u1;
+ union {
+ struct RNode *node;
+ ID id;
+ long argc;
+ VALUE value;
+ } u2;
+ union {
+ struct RNode *node;
+ ID id;
+ long state;
+ struct rb_args_info *args;
+ struct rb_ary_pattern_info *apinfo;
+ struct rb_fnd_pattern_info *fpinfo;
+ VALUE value;
+ } u3;
+ rb_code_location_t nd_loc;
+ int node_id;
+} NODE;
+
+#define RNODE(obj) ((struct RNode *)(obj))
+
+/* FL : 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: FINALIZE, 8: UNUSED, 9: UNUSED, 10: EXIVAR, 11: FREEZE */
+/* NODE_FL: 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: NODE_FL_NEWLINE,
+ * 8..14: nd_type,
+ * 15..: nd_line
+ */
+#define NODE_FL_NEWLINE (((VALUE)1)<<7)
+
+#define NODE_TYPESHIFT 8
+#define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT)
+
+#define nd_type(n) ((int) (((n)->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
+#define nd_set_type(n,t) \
+ rb_node_set_type(n, t)
+#define nd_init_type(n,t) \
+ (n)->flags=(((n)->flags&~NODE_TYPEMASK)|((((unsigned long)(t))<<NODE_TYPESHIFT)&NODE_TYPEMASK))
+
+#define NODE_LSHIFT (NODE_TYPESHIFT+7)
+#define NODE_LMASK (((SIGNED_VALUE)1<<(sizeof(VALUE)*CHAR_BIT-NODE_LSHIFT))-1)
+#define nd_line(n) (int)(((SIGNED_VALUE)(n)->flags)>>NODE_LSHIFT)
+#define nd_set_line(n,l) \
+ (n)->flags=(((n)->flags&~((VALUE)(-1)<<NODE_LSHIFT))|((VALUE)((l)&NODE_LMASK)<<NODE_LSHIFT))
+
+#define nd_first_column(n) ((int)((n)->nd_loc.beg_pos.column))
+#define nd_set_first_column(n, v) ((n)->nd_loc.beg_pos.column = (v))
+#define nd_first_lineno(n) ((int)((n)->nd_loc.beg_pos.lineno))
+#define nd_set_first_lineno(n, v) ((n)->nd_loc.beg_pos.lineno = (v))
+#define nd_first_loc(n) ((n)->nd_loc.beg_pos)
+#define nd_set_first_loc(n, v) (nd_first_loc(n) = (v))
+
+#define nd_last_column(n) ((int)((n)->nd_loc.end_pos.column))
+#define nd_set_last_column(n, v) ((n)->nd_loc.end_pos.column = (v))
+#define nd_last_lineno(n) ((int)((n)->nd_loc.end_pos.lineno))
+#define nd_set_last_lineno(n, v) ((n)->nd_loc.end_pos.lineno = (v))
+#define nd_last_loc(n) ((n)->nd_loc.end_pos)
+#define nd_set_last_loc(n, v) (nd_last_loc(n) = (v))
+#define nd_node_id(n) ((n)->node_id)
+#define nd_set_node_id(n,id) ((n)->node_id = (id))
+
+#define nd_head u1.node
+#define nd_alen u2.argc
+#define nd_next u3.node
+
+#define nd_cond u1.node
+#define nd_body u2.node
+#define nd_else u3.node
+
+#define nd_resq u2.node
+#define nd_ensr u3.node
+
+#define nd_1st u1.node
+#define nd_2nd u2.node
+
+#define nd_stts u1.node
+
+#define nd_entry u3.id
+#define nd_vid u1.id
+
+#define nd_var u1.node
+#define nd_iter u3.node
+
+#define nd_value u2.node
+#define nd_aid u3.id
+
+#define nd_lit u1.value
+
+#define nd_recv u1.node
+#define nd_mid u2.id
+#define nd_args u3.node
+#define nd_ainfo u3.args
+
+#define nd_defn u3.node
+
+#define nd_cpath u1.node
+#define nd_super u3.node
+
+#define nd_beg u1.node
+#define nd_end u2.node
+#define nd_state u3.state
+
+#define nd_nth u2.argc
+
+#define nd_alias u1.id
+#define nd_orig u2.id
+#define nd_undef u2.node
+
+#define nd_brace u2.argc
+
+#define nd_pconst u1.node
+#define nd_pkwargs u2.node
+#define nd_pkwrestarg u3.node
+
+#define nd_apinfo u3.apinfo
+
+#define nd_fpinfo u3.fpinfo
+
+// for NODE_SCOPE
+#define nd_tbl u1.tbl
+
+// for NODE_ARGS_AUX
+#define nd_pid u1.id
+#define nd_plen u2.argc
+#define nd_cflag u2.id
+
+// for ripper
+#define nd_cval u3.value
+#define nd_rval u2.value
+#define nd_tag u1.id
+
+#define NEW_NODE(t,a0,a1,a2,loc) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2),loc)
+#define NEW_NODE_WITH_LOCALS(t,a1,a2,loc) node_newnode_with_locals(p, (t),(VALUE)(a1),(VALUE)(a2),loc)
+
+#define NEW_DEFN(i,a,d,loc) NEW_NODE(NODE_DEFN,0,i,NEW_SCOPE(a,d,loc),loc)
+#define NEW_DEFS(r,i,a,d,loc) NEW_NODE(NODE_DEFS,r,i,NEW_SCOPE(a,d,loc),loc)
+#define NEW_SCOPE(a,b,loc) NEW_NODE_WITH_LOCALS(NODE_SCOPE,b,a,loc)
+#define NEW_BLOCK(a,loc) NEW_NODE(NODE_BLOCK,a,0,0,loc)
+#define NEW_IF(c,t,e,loc) NEW_NODE(NODE_IF,c,t,e,loc)
+#define NEW_UNLESS(c,t,e,loc) NEW_NODE(NODE_UNLESS,c,t,e,loc)
+#define NEW_CASE(h,b,loc) NEW_NODE(NODE_CASE,h,b,0,loc)
+#define NEW_CASE2(b,loc) NEW_NODE(NODE_CASE2,0,b,0,loc)
+#define NEW_CASE3(h,b,loc) NEW_NODE(NODE_CASE3,h,b,0,loc)
+#define NEW_WHEN(c,t,e,loc) NEW_NODE(NODE_WHEN,c,t,e,loc)
+#define NEW_IN(c,t,e,loc) NEW_NODE(NODE_IN,c,t,e,loc)
+#define NEW_WHILE(c,b,n,loc) NEW_NODE(NODE_WHILE,c,b,n,loc)
+#define NEW_UNTIL(c,b,n,loc) NEW_NODE(NODE_UNTIL,c,b,n,loc)
+#define NEW_FOR(i,b,loc) NEW_NODE(NODE_FOR,0,b,i,loc)
+#define NEW_FOR_MASGN(v,loc) NEW_NODE(NODE_FOR_MASGN,v,0,0,loc)
+#define NEW_ITER(a,b,loc) NEW_NODE(NODE_ITER,0,NEW_SCOPE(a,b,loc),0,loc)
+#define NEW_LAMBDA(a,b,loc) NEW_NODE(NODE_LAMBDA,0,NEW_SCOPE(a,b,loc),0,loc)
+#define NEW_BREAK(s,loc) NEW_NODE(NODE_BREAK,s,0,0,loc)
+#define NEW_NEXT(s,loc) NEW_NODE(NODE_NEXT,s,0,0,loc)
+#define NEW_REDO(loc) NEW_NODE(NODE_REDO,0,0,0,loc)
+#define NEW_RETRY(loc) NEW_NODE(NODE_RETRY,0,0,0,loc)
+#define NEW_BEGIN(b,loc) NEW_NODE(NODE_BEGIN,0,b,0,loc)
+#define NEW_RESCUE(b,res,e,loc) NEW_NODE(NODE_RESCUE,b,res,e,loc)
+#define NEW_RESBODY(a,ex,n,loc) NEW_NODE(NODE_RESBODY,n,ex,a,loc)
+#define NEW_ENSURE(b,en,loc) NEW_NODE(NODE_ENSURE,b,0,en,loc)
+#define NEW_RETURN(s,loc) NEW_NODE(NODE_RETURN,s,0,0,loc)
+#define NEW_YIELD(a,loc) NEW_NODE(NODE_YIELD,a,0,0,loc)
+#define NEW_LIST(a,loc) NEW_NODE(NODE_LIST,a,1,0,loc)
+#define NEW_ZLIST(loc) NEW_NODE(NODE_ZLIST,0,0,0,loc)
+#define NEW_HASH(a,loc) NEW_NODE(NODE_HASH,a,0,0,loc)
+#define NEW_MASGN(l,r,loc) NEW_NODE(NODE_MASGN,l,0,r,loc)
+#define NEW_GASGN(v,val,loc) NEW_NODE(NODE_GASGN,v,val,v,loc)
+#define NEW_LASGN(v,val,loc) NEW_NODE(NODE_LASGN,v,val,0,loc)
+#define NEW_DASGN(v,val,loc) NEW_NODE(NODE_DASGN,v,val,0,loc)
+#define NEW_IASGN(v,val,loc) NEW_NODE(NODE_IASGN,v,val,0,loc)
+#define NEW_CDECL(v,val,path,loc) NEW_NODE(NODE_CDECL,v,val,path,loc)
+#define NEW_CVASGN(v,val,loc) NEW_NODE(NODE_CVASGN,v,val,0,loc)
+#define NEW_OP_ASGN1(p,id,a,loc) NEW_NODE(NODE_OP_ASGN1,p,id,a,loc)
+#define NEW_OP_ASGN2(r,t,i,o,val,loc) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o,t,loc),loc)
+#define NEW_OP_ASGN22(i,o,t,loc) NEW_NODE(NODE_OP_ASGN2,i,o,t,loc)
+#define NEW_OP_ASGN_OR(i,val,loc) NEW_NODE(NODE_OP_ASGN_OR,i,val,0,loc)
+#define NEW_OP_ASGN_AND(i,val,loc) NEW_NODE(NODE_OP_ASGN_AND,i,val,0,loc)
+#define NEW_OP_CDECL(v,op,val,loc) NEW_NODE(NODE_OP_CDECL,v,val,op,loc)
+#define NEW_GVAR(v,loc) NEW_NODE(NODE_GVAR,v,0,v,loc)
+#define NEW_LVAR(v,loc) NEW_NODE(NODE_LVAR,v,0,0,loc)
+#define NEW_DVAR(v,loc) NEW_NODE(NODE_DVAR,v,0,0,loc)
+#define NEW_IVAR(v,loc) NEW_NODE(NODE_IVAR,v,0,0,loc)
+#define NEW_CONST(v,loc) NEW_NODE(NODE_CONST,v,0,0,loc)
+#define NEW_CVAR(v,loc) NEW_NODE(NODE_CVAR,v,0,0,loc)
+#define NEW_NTH_REF(n,loc) NEW_NODE(NODE_NTH_REF,0,n,0,loc)
+#define NEW_BACK_REF(n,loc) NEW_NODE(NODE_BACK_REF,0,n,0,loc)
+#define NEW_MATCH(c,loc) NEW_NODE(NODE_MATCH,c,0,0,loc)
+#define NEW_MATCH2(n1,n2,loc) NEW_NODE(NODE_MATCH2,n1,n2,0,loc)
+#define NEW_MATCH3(r,n2,loc) NEW_NODE(NODE_MATCH3,r,n2,0,loc)
+#define NEW_LIT(l,loc) NEW_NODE(NODE_LIT,l,0,0,loc)
+#define NEW_STR(s,loc) NEW_NODE(NODE_STR,s,0,0,loc)
+#define NEW_DSTR(s,loc) NEW_NODE(NODE_DSTR,s,1,0,loc)
+#define NEW_XSTR(s,loc) NEW_NODE(NODE_XSTR,s,0,0,loc)
+#define NEW_DXSTR(s,loc) NEW_NODE(NODE_DXSTR,s,0,0,loc)
+#define NEW_DSYM(s,loc) NEW_NODE(NODE_DSYM,s,0,0,loc)
+#define NEW_EVSTR(n,loc) NEW_NODE(NODE_EVSTR,0,(n),0,loc)
+#define NEW_CALL(r,m,a,loc) NEW_NODE(NODE_CALL,r,m,a,loc)
+#define NEW_OPCALL(r,m,a,loc) NEW_NODE(NODE_OPCALL,r,m,a,loc)
+#define NEW_FCALL(m,a,loc) NEW_NODE(NODE_FCALL,0,m,a,loc)
+#define NEW_VCALL(m,loc) NEW_NODE(NODE_VCALL,0,m,0,loc)
+#define NEW_SUPER(a,loc) NEW_NODE(NODE_SUPER,0,0,a,loc)
+#define NEW_ZSUPER(loc) NEW_NODE(NODE_ZSUPER,0,0,0,loc)
+#define NEW_ARGS_AUX(r,b,loc) NEW_NODE(NODE_ARGS_AUX,r,b,0,loc)
+#define NEW_OPT_ARG(i,v,loc) NEW_NODE(NODE_OPT_ARG,i,v,0,loc)
+#define NEW_KW_ARG(i,v,loc) NEW_NODE(NODE_KW_ARG,i,v,0,loc)
+#define NEW_POSTARG(i,v,loc) NEW_NODE(NODE_POSTARG,i,v,0,loc)
+#define NEW_ARGSCAT(a,b,loc) NEW_NODE(NODE_ARGSCAT,a,b,0,loc)
+#define NEW_ARGSPUSH(a,b,loc) NEW_NODE(NODE_ARGSPUSH,a,b,0,loc)
+#define NEW_SPLAT(a,loc) NEW_NODE(NODE_SPLAT,a,0,0,loc)
+#define NEW_BLOCK_PASS(b,loc) NEW_NODE(NODE_BLOCK_PASS,0,b,0,loc)
+#define NEW_ALIAS(n,o,loc) NEW_NODE(NODE_ALIAS,n,o,0,loc)
+#define NEW_VALIAS(n,o,loc) NEW_NODE(NODE_VALIAS,n,o,0,loc)
+#define NEW_UNDEF(i,loc) NEW_NODE(NODE_UNDEF,0,i,0,loc)
+#define NEW_CLASS(n,b,s,loc) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(0,b,loc),(s),loc)
+#define NEW_SCLASS(r,b,loc) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(0,b,loc),0,loc)
+#define NEW_MODULE(n,b,loc) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b,loc),0,loc)
+#define NEW_COLON2(c,i,loc) NEW_NODE(NODE_COLON2,c,i,0,loc)
+#define NEW_COLON3(i,loc) NEW_NODE(NODE_COLON3,0,i,0,loc)
+#define NEW_DOT2(b,e,loc) NEW_NODE(NODE_DOT2,b,e,0,loc)
+#define NEW_DOT3(b,e,loc) NEW_NODE(NODE_DOT3,b,e,0,loc)
+#define NEW_SELF(loc) NEW_NODE(NODE_SELF,0,0,1,loc)
+#define NEW_NIL(loc) NEW_NODE(NODE_NIL,0,0,0,loc)
+#define NEW_TRUE(loc) NEW_NODE(NODE_TRUE,0,0,0,loc)
+#define NEW_FALSE(loc) NEW_NODE(NODE_FALSE,0,0,0,loc)
+#define NEW_ERRINFO(loc) NEW_NODE(NODE_ERRINFO,0,0,0,loc)
+#define NEW_DEFINED(e,loc) NEW_NODE(NODE_DEFINED,e,0,0,loc)
+#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
+#define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
+#define NEW_ERROR(loc) NEW_NODE(NODE_ERROR,0,0,0,loc)
+
+#define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
+#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
+#define NODE_SPECIAL_NO_NAME_REST ((NODE *)-1)
+#define NODE_NAMED_REST_P(node) ((node) != NODE_SPECIAL_NO_NAME_REST)
+#define NODE_SPECIAL_EXCESSIVE_COMMA ((ID)1)
+#define NODE_SPECIAL_NO_REST_KEYWORD ((NODE *)-1)
+
+VALUE rb_node_case_when_optimizable_literal(const NODE *const node);
+
RUBY_SYMBOL_EXPORT_BEGIN
-#ifdef UNIVERSAL_PARSER
-rb_ast_t *rb_ast_new(rb_parser_config_t *config);
-#else
+typedef struct node_buffer_struct node_buffer_t;
+/* T_IMEMO/ast */
+typedef struct rb_ast_body_struct {
+ const NODE *root;
+ VALUE compile_option;
+ VALUE script_lines;
+ // script_lines is either:
+ // - a Fixnum that represents the line count of the original source, or
+ // - an Array that contains the lines of the original source
+} rb_ast_body_t;
+typedef struct rb_ast_struct {
+ VALUE flags;
+ node_buffer_t *node_buffer;
+ rb_ast_body_t body;
+} rb_ast_t;
rb_ast_t *rb_ast_new(void);
-#endif
-size_t rb_ast_memsize(const rb_ast_t*);
-void rb_ast_dispose(rb_ast_t*);
-VALUE rb_ast_tokens(rb_ast_t *ast);
-#if RUBY_DEBUG
-void rb_ast_node_type_change(NODE *n, enum node_type type);
-#endif
-const char *ruby_node_name(int node);
-void rb_node_init(NODE *n, enum node_type type);
-
void rb_ast_mark(rb_ast_t*);
void rb_ast_update_references(rb_ast_t*);
+void rb_ast_dispose(rb_ast_t*);
void rb_ast_free(rb_ast_t*);
+size_t rb_ast_memsize(const rb_ast_t*);
void rb_ast_add_mark_object(rb_ast_t*, VALUE);
-void rb_ast_delete_mark_object(rb_ast_t*, VALUE);
void rb_ast_set_tokens(rb_ast_t*, VALUE);
-NODE *rb_ast_newnode(rb_ast_t*, enum node_type type, size_t size, size_t alignment);
+VALUE rb_ast_tokens(rb_ast_t *ast);
+NODE *rb_ast_newnode(rb_ast_t*, enum node_type type);
void rb_ast_delete_node(rb_ast_t*, NODE *n);
rb_ast_id_table_t *rb_ast_new_local_table(rb_ast_t*, int);
rb_ast_id_table_t *rb_ast_resize_latest_local_table(rb_ast_t*, int);
+VALUE rb_parser_new(void);
+VALUE rb_parser_end_seen_p(VALUE);
+VALUE rb_parser_encoding(VALUE);
+VALUE rb_parser_set_yydebug(VALUE, VALUE);
VALUE rb_parser_dump_tree(const NODE *node, int comment);
+void rb_parser_set_options(VALUE, int, int, int, int);
+
+rb_ast_t *rb_parser_compile_string(VALUE, const char*, VALUE, int);
+rb_ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
+rb_ast_t *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
+rb_ast_t *rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int line);
+
+void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2);
+const char *ruby_node_name(int node);
const struct kwtable *rb_reserved_word(const char *, unsigned int);
+struct rb_args_info {
+ NODE *pre_init;
+ NODE *post_init;
+
+ int pre_args_num; /* count of mandatory pre-arguments */
+ int post_args_num; /* count of mandatory post-arguments */
+
+ ID first_post_arg;
+
+ ID rest_arg;
+ ID block_arg;
+
+ NODE *kw_args;
+ NODE *kw_rest_arg;
+
+ NODE *opt_args;
+ unsigned int no_kwarg: 1;
+ unsigned int ruby2_keywords: 1;
+ unsigned int forwarding: 1;
+
+ VALUE imemo;
+};
+
+struct rb_ary_pattern_info {
+ NODE *pre_args;
+ NODE *rest_arg;
+ NODE *post_args;
+};
+
+struct rb_fnd_pattern_info {
+ NODE *pre_rest_arg;
+ NODE *args;
+ NODE *post_rest_arg;
+};
+
struct parser_params;
void *rb_parser_malloc(struct parser_params *, size_t);
void *rb_parser_realloc(struct parser_params *, void *, size_t);
void *rb_parser_calloc(struct parser_params *, size_t, size_t);
void rb_parser_free(struct parser_params *, void *);
PRINTF_ARGS(void rb_parser_printf(struct parser_params *parser, const char *fmt, ...), 2, 3);
-VALUE rb_node_set_type(NODE *n, enum node_type t);
+void rb_ast_node_type_change(NODE *n, enum node_type type);
RUBY_SYMBOL_EXPORT_END
-#define NODE_LSHIFT (NODE_TYPESHIFT+7)
-#define NODE_LMASK (((SIGNED_VALUE)1<<(sizeof(VALUE)*CHAR_BIT-NODE_LSHIFT))-1)
-
-#define nd_line(n) (int)(((SIGNED_VALUE)(n)->flags)>>NODE_LSHIFT)
-#define nd_set_line(n,l) \
- (n)->flags=(((n)->flags&~((VALUE)(-1)<<NODE_LSHIFT))|((VALUE)((l)&NODE_LMASK)<<NODE_LSHIFT))
-
-
-#define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
-#define NODE_REQUIRED_KEYWORD_P(node) ((node) == NODE_SPECIAL_REQUIRED_KEYWORD)
-#define NODE_SPECIAL_NO_NAME_REST ((NODE *)-1)
-#define NODE_NAMED_REST_P(node) ((node) != NODE_SPECIAL_NO_NAME_REST)
-#define NODE_SPECIAL_EXCESSIVE_COMMA ((ID)1)
-#define NODE_SPECIAL_NO_REST_KEYWORD ((NODE *)-1)
-
-#define nd_first_column(n) ((int)(RNODE(n)->nd_loc.beg_pos.column))
-#define nd_set_first_column(n, v) (RNODE(n)->nd_loc.beg_pos.column = (v))
-#define nd_first_lineno(n) ((int)(RNODE(n)->nd_loc.beg_pos.lineno))
-#define nd_set_first_lineno(n, v) (RNODE(n)->nd_loc.beg_pos.lineno = (v))
-#define nd_first_loc(n) (RNODE(n)->nd_loc.beg_pos)
-#define nd_set_first_loc(n, v) (nd_first_loc(n) = (v))
-
-#define nd_last_column(n) ((int)(RNODE(n)->nd_loc.end_pos.column))
-#define nd_set_last_column(n, v) (RNODE(n)->nd_loc.end_pos.column = (v))
-#define nd_last_lineno(n) ((int)(RNODE(n)->nd_loc.end_pos.lineno))
-#define nd_set_last_lineno(n, v) (RNODE(n)->nd_loc.end_pos.lineno = (v))
-#define nd_last_loc(n) (RNODE(n)->nd_loc.end_pos)
-#define nd_set_last_loc(n, v) (nd_last_loc(n) = (v))
-#define nd_node_id(n) (RNODE(n)->node_id)
-#define nd_set_node_id(n,id) (RNODE(n)->node_id = (id))
+static inline VALUE
+rb_node_set_type(NODE *n, enum node_type t)
+{
+#if RUBY_DEBUG
+ rb_ast_node_type_change(n, t);
+#endif
+ return nd_init_type(n, t);
+}
static inline bool
nd_type_p(const NODE *n, enum node_type t)
{
return (enum node_type)nd_type(n) == t;
}
+#if defined(__cplusplus)
+#if 0
+{ /* satisfy cc-mode */
+#endif
+} /* extern "C" { */
+#endif
#endif /* RUBY_NODE_H */
diff --git a/node_dump.c b/node_dump.c
deleted file mode 100644
index 391aea10b1..0000000000
--- a/node_dump.c
+++ /dev/null
@@ -1,1123 +0,0 @@
-/**********************************************************************
-
- node_dump.c - dump ruby node tree
-
- $Author: mame $
- created at: 09/12/06 21:23:44 JST
-
- Copyright (C) 2009 Yusuke Endoh
-
-**********************************************************************/
-
-#include "internal.h"
-#include "internal/hash.h"
-#include "internal/variable.h"
-#include "ruby/ruby.h"
-#include "vm_core.h"
-
-#define A(str) rb_str_cat2(buf, (str))
-#define AR(str) rb_str_concat(buf, (str))
-
-#define A_INDENT add_indent(buf, indent)
-#define D_INDENT rb_str_cat2(indent, next_indent)
-#define D_DEDENT rb_str_resize(indent, RSTRING_LEN(indent) - 4)
-#define A_ID(id) add_id(buf, (id))
-#define A_INT(val) rb_str_catf(buf, "%d", (val))
-#define A_LONG(val) rb_str_catf(buf, "%ld", (val))
-#define A_LIT(lit) AR(rb_dump_literal(lit))
-#define A_NODE_HEADER(node, term) \
- rb_str_catf(buf, "@ %s (id: %d, line: %d, location: (%d,%d)-(%d,%d))%s"term, \
- ruby_node_name(nd_type(node)), nd_node_id(node), nd_line(node), \
- nd_first_lineno(node), nd_first_column(node), \
- nd_last_lineno(node), nd_last_column(node), \
- (nd_fl_newline(node) ? "*" : ""))
-#define A_FIELD_HEADER(len, name, term) \
- rb_str_catf(buf, "+- %.*s:"term, (len), (name))
-#define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
-
-#define D_NULL_NODE (A_INDENT, A("(null node)\n"))
-#define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
-
-#define COMPOUND_FIELD(len, name) \
- FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
-
-#define COMPOUND_FIELD1(name, ann) \
- COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
- FIELD_NAME_DESC(name, ann))
-
-#define FIELD_NAME_DESC(name, ann) name " (" ann ")"
-#define FIELD_NAME_LEN(name, ann) (int)( \
- comment ? \
- rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
- rb_strlen_lit(name))
-#define SIMPLE_FIELD(len, name) \
- FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
-
-#define FIELD_BLOCK(init, reset) \
- for (init, field_flag = 1; \
- field_flag; /* should be optimized away */ \
- reset, field_flag = 0)
-
-#define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
-#define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
-#define F_ID(name, type, ann) SIMPLE_FIELD1(#name, ann) A_ID(type(node)->name)
-#define F_INT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_INT(type(node)->name)
-#define F_LONG(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LONG(type(node)->name)
-#define F_LIT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LIT(type(node)->name)
-#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
-
-#define F_NODE(name, type, ann) \
- COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, RNODE(type(node)->name));}
-
-#define F_NODE2(name, n, ann) \
- COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);}
-
-#define ANN(ann) \
- if (comment) { \
- A_INDENT; A("| # " ann "\n"); \
- }
-
-#define LAST_NODE (next_indent = " ")
-
-VALUE
-rb_dump_literal(VALUE lit)
-{
- if (!RB_SPECIAL_CONST_P(lit)) {
- VALUE str;
- switch (RB_BUILTIN_TYPE(lit)) {
- case T_CLASS: case T_MODULE: case T_ICLASS:
- str = rb_class_path(lit);
- if (FL_TEST(lit, FL_SINGLETON)) {
- str = rb_sprintf("<%"PRIsVALUE">", str);
- }
- return str;
- default:
- break;
- }
- }
- return rb_inspect(lit);
-}
-
-static void
-add_indent(VALUE buf, VALUE indent)
-{
- AR(indent);
-}
-
-static void
-add_id(VALUE buf, ID id)
-{
- if (id == 0) {
- A("(null)");
- }
- else {
- VALUE str = rb_id2str(id);
- if (str) {
- A(":"); AR(str);
- }
- else {
- rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
- }
- }
-}
-
-struct add_option_arg {
- VALUE buf, indent;
- st_index_t count;
-};
-
-static void dump_node(VALUE, VALUE, int, const NODE *);
-static const char default_indent[] = "| ";
-
-static void
-dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
-{
- int field_flag;
- const char *next_indent = default_indent;
- F_LONG(as.nd_alen, RNODE_LIST, "length");
- F_NODE(nd_head, RNODE_LIST, "element");
- while (RNODE_LIST(node)->nd_next && nd_type_p(RNODE_LIST(node)->nd_next, NODE_LIST)) {
- node = RNODE_LIST(node)->nd_next;
- F_NODE(nd_head, RNODE_LIST, "element");
- }
- LAST_NODE;
- F_NODE(nd_next, RNODE_LIST, "next element");
-}
-
-static void
-dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
-{
- int field_flag;
- int i;
- const char *next_indent = default_indent;
- enum node_type type;
-
- if (!node) {
- D_NULL_NODE;
- return;
- }
-
- D_NODE_HEADER(node);
-
- type = nd_type(node);
- switch (type) {
- case NODE_BLOCK:
- ANN("statement sequence");
- ANN("format: [nd_head]; ...; [nd_next]");
- ANN("example: foo; bar");
- i = 0;
- do {
- A_INDENT;
- rb_str_catf(buf, "+- nd_head (%s%d):\n",
- comment ? "statement #" : "", ++i);
- if (!RNODE_BLOCK(node)->nd_next) LAST_NODE;
- D_INDENT;
- dump_node(buf, indent, comment, RNODE_BLOCK(node)->nd_head);
- D_DEDENT;
- } while (RNODE_BLOCK(node)->nd_next &&
- nd_type_p(RNODE_BLOCK(node)->nd_next, NODE_BLOCK) &&
- (node = RNODE_BLOCK(node)->nd_next, 1));
- if (RNODE_BLOCK(node)->nd_next) {
- LAST_NODE;
- F_NODE(nd_next, RNODE_BLOCK, "next block");
- }
- return;
-
- case NODE_IF:
- ANN("if statement");
- ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
- ANN("example: if x == 1 then foo else bar end");
- F_NODE(nd_cond, RNODE_IF, "condition expr");
- F_NODE(nd_body, RNODE_IF, "then clause");
- LAST_NODE;
- F_NODE(nd_else, RNODE_IF, "else clause");
- return;
-
- case NODE_UNLESS:
- ANN("unless statement");
- ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
- ANN("example: unless x == 1 then foo else bar end");
- F_NODE(nd_cond, RNODE_UNLESS, "condition expr");
- F_NODE(nd_body, RNODE_UNLESS, "then clause");
- LAST_NODE;
- F_NODE(nd_else, RNODE_UNLESS, "else clause");
- return;
-
- case NODE_CASE:
- ANN("case statement");
- ANN("format: case [nd_head]; [nd_body]; end");
- ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
- F_NODE(nd_head, RNODE_CASE, "case expr");
- LAST_NODE;
- F_NODE(nd_body, RNODE_CASE, "when clauses");
- return;
- case NODE_CASE2:
- ANN("case statement with no head");
- ANN("format: case; [nd_body]; end");
- ANN("example: case; when 1; foo; when 2; bar; else baz; end");
- F_NODE(nd_head, RNODE_CASE2, "case expr");
- LAST_NODE;
- F_NODE(nd_body, RNODE_CASE2, "when clauses");
- return;
- case NODE_CASE3:
- ANN("case statement (pattern matching)");
- ANN("format: case [nd_head]; [nd_body]; end");
- ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
- F_NODE(nd_head, RNODE_CASE3, "case expr");
- LAST_NODE;
- F_NODE(nd_body, RNODE_CASE3, "in clauses");
- return;
-
- case NODE_WHEN:
- ANN("when clause");
- ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
- ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
- F_NODE(nd_head, RNODE_WHEN, "when value");
- F_NODE(nd_body, RNODE_WHEN, "when body");
- LAST_NODE;
- F_NODE(nd_next, RNODE_WHEN, "next when clause");
- return;
-
- case NODE_IN:
- ANN("in clause");
- ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
- ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
- F_NODE(nd_head, RNODE_IN, "in pattern");
- F_NODE(nd_body, RNODE_IN, "in body");
- LAST_NODE;
- F_NODE(nd_next, RNODE_IN, "next in clause");
- return;
-
- case NODE_WHILE:
- ANN("while statement");
- ANN("format: while [nd_cond]; [nd_body]; end");
- ANN("example: while x == 1; foo; end");
- goto loop;
- case NODE_UNTIL:
- ANN("until statement");
- ANN("format: until [nd_cond]; [nd_body]; end");
- ANN("example: until x == 1; foo; end");
- loop:
- F_CUSTOM1(nd_state, "begin-end-while?") {
- A_INT((int)RNODE_WHILE(node)->nd_state);
- A((RNODE_WHILE(node)->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
- }
- F_NODE(nd_cond, RNODE_WHILE, "condition");
- LAST_NODE;
- F_NODE(nd_body, RNODE_WHILE, "body");
- return;
-
- case NODE_ITER:
- ANN("method call with block");
- ANN("format: [nd_iter] { [nd_body] }");
- ANN("example: 3.times { foo }");
- goto iter;
- case NODE_FOR:
- ANN("for statement");
- ANN("format: for * in [nd_iter] do [nd_body] end");
- ANN("example: for i in 1..3 do foo end");
- iter:
- F_NODE(nd_iter, RNODE_ITER, "iteration receiver");
- LAST_NODE;
- F_NODE(nd_body, RNODE_ITER, "body");
- return;
-
- case NODE_FOR_MASGN:
- ANN("vars of for statement with masgn");
- ANN("format: for [nd_var] in ... do ... end");
- ANN("example: for x, y in 1..3 do foo end");
- LAST_NODE;
- F_NODE(nd_var, RNODE_FOR_MASGN, "var");
- return;
-
- case NODE_BREAK:
- ANN("break statement");
- ANN("format: break [nd_stts]");
- ANN("example: break 1");
- LAST_NODE;
- F_NODE(nd_stts, RNODE_BREAK, "value");
- return;
- case NODE_NEXT:
- ANN("next statement");
- ANN("format: next [nd_stts]");
- ANN("example: next 1");
- LAST_NODE;
- F_NODE(nd_stts, RNODE_NEXT, "value");
- return;
- case NODE_RETURN:
- ANN("return statement");
- ANN("format: return [nd_stts]");
- ANN("example: return 1");
- LAST_NODE;
- F_NODE(nd_stts, RNODE_RETURN, "value");
- return;
-
- case NODE_REDO:
- ANN("redo statement");
- ANN("format: redo");
- ANN("example: redo");
- return;
-
- case NODE_RETRY:
- ANN("retry statement");
- ANN("format: retry");
- ANN("example: retry");
- return;
-
- case NODE_BEGIN:
- ANN("begin statement");
- ANN("format: begin; [nd_body]; end");
- ANN("example: begin; 1; end");
- LAST_NODE;
- F_NODE(nd_body, RNODE_BEGIN, "body");
- return;
-
- case NODE_RESCUE:
- ANN("rescue clause");
- ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
- ANN("example: begin; foo; rescue; bar; else; baz; end");
- F_NODE(nd_head, RNODE_RESCUE, "body");
- F_NODE(nd_resq, RNODE_RESCUE, "rescue clause list");
- LAST_NODE;
- F_NODE(nd_else, RNODE_RESCUE, "rescue else clause");
- return;
-
- case NODE_RESBODY:
- ANN("rescue clause (cont'd)");
- ANN("format: rescue [nd_args]; [nd_body]; (rescue) [nd_head]");
- ANN("example: begin; foo; rescue; bar; else; baz; end");
- F_NODE(nd_args, RNODE_RESBODY, "rescue exceptions");
- F_NODE(nd_body, RNODE_RESBODY, "rescue clause");
- LAST_NODE;
- F_NODE(nd_head, RNODE_RESBODY, "next rescue clause");
- return;
-
- case NODE_ENSURE:
- ANN("ensure clause");
- ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
- ANN("example: begin; foo; ensure; bar; end");
- F_NODE(nd_head, RNODE_ENSURE, "body");
- LAST_NODE;
- F_NODE(nd_ensr, RNODE_ENSURE, "ensure clause");
- return;
-
- case NODE_AND:
- ANN("&& operator");
- ANN("format: [nd_1st] && [nd_2nd]");
- ANN("example: foo && bar");
- goto andor;
- case NODE_OR:
- ANN("|| operator");
- ANN("format: [nd_1st] || [nd_2nd]");
- ANN("example: foo || bar");
- andor:
- while (1) {
- F_NODE(nd_1st, RNODE_AND, "left expr");
- if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type))
- break;
- node = RNODE_AND(node)->nd_2nd;
- }
- LAST_NODE;
- F_NODE(nd_2nd, RNODE_AND, "right expr");
- return;
-
- case NODE_MASGN:
- ANN("multiple assignment");
- ANN("format: [nd_head], [nd_args] = [nd_value]");
- ANN("example: a, b = foo");
- F_NODE(nd_value, RNODE_MASGN, "rhsn");
- F_NODE(nd_head, RNODE_MASGN, "lhsn");
- if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) {
- LAST_NODE;
- F_NODE(nd_args, RNODE_MASGN, "splatn");
- }
- else {
- F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
- }
- return;
-
- case NODE_LASGN:
- ANN("local variable assignment");
- ANN("format: [nd_vid](lvar) = [nd_value]");
- ANN("example: x = foo");
- F_ID(nd_vid, RNODE_LASGN, "local variable");
- if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node)->nd_value)) {
- F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
- }
- else {
- LAST_NODE;
- F_NODE(nd_value, RNODE_LASGN, "rvalue");
- }
- return;
- case NODE_DASGN:
- ANN("dynamic variable assignment");
- ANN("format: [nd_vid](dvar) = [nd_value]");
- ANN("example: x = nil; 1.times { x = foo }");
- ANN("example: 1.times { x = foo }");
- F_ID(nd_vid, RNODE_DASGN, "local variable");
- if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node)->nd_value)) {
- F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
- }
- else {
- LAST_NODE;
- F_NODE(nd_value, RNODE_DASGN, "rvalue");
- }
- return;
- case NODE_IASGN:
- ANN("instance variable assignment");
- ANN("format: [nd_vid](ivar) = [nd_value]");
- ANN("example: @x = foo");
- F_ID(nd_vid, RNODE_IASGN, "instance variable");
- LAST_NODE;
- F_NODE(nd_value, RNODE_IASGN, "rvalue");
- return;
- case NODE_CVASGN:
- ANN("class variable assignment");
- ANN("format: [nd_vid](cvar) = [nd_value]");
- ANN("example: @@x = foo");
- F_ID(nd_vid, RNODE_CVASGN, "class variable");
- LAST_NODE;
- F_NODE(nd_value, RNODE_CVASGN, "rvalue");
- return;
- case NODE_GASGN:
- ANN("global variable assignment");
- ANN("format: [nd_vid](gvar) = [nd_value]");
- ANN("example: $x = foo");
- F_ID(nd_vid, RNODE_GASGN, "global variable");
- LAST_NODE;
- F_NODE(nd_value, RNODE_GASGN, "rvalue");
- return;
-
- case NODE_CDECL:
- ANN("constant declaration");
- ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
- ANN("example: X = foo");
- if (RNODE_CDECL(node)->nd_vid) {
- F_ID(nd_vid, RNODE_CDECL, "constant");
- F_MSG(nd_else, "extension", "not used");
- }
- else {
- F_MSG(nd_vid, "constant", "0 (see extension field)");
- F_NODE(nd_else, RNODE_CDECL, "extension");
- }
- LAST_NODE;
- F_NODE(nd_value, RNODE_CDECL, "rvalue");
- return;
-
- case NODE_OP_ASGN1:
- ANN("array assignment with operator");
- ANN("format: [nd_recv] [ [nd_index] ] [nd_mid]= [nd_rvalue]");
- ANN("example: ary[1] += foo");
- F_NODE(nd_recv, RNODE_OP_ASGN1, "receiver");
- F_ID(nd_mid, RNODE_OP_ASGN1, "operator");
- F_NODE(nd_index, RNODE_OP_ASGN1, "index");
- LAST_NODE;
- F_NODE(nd_rvalue, RNODE_OP_ASGN1, "rvalue");
- return;
-
- case NODE_OP_ASGN2:
- ANN("attr assignment with operator");
- ANN("format: [nd_recv].[nd_vid] [nd_mid]= [nd_value]");
- ANN("example: struct.field += foo");
- F_NODE(nd_recv, RNODE_OP_ASGN2, "receiver");
- F_CUSTOM1(nd_vid, "attr") {
- if (RNODE_OP_ASGN2(node)->nd_aid) A("? ");
- A_ID(RNODE_OP_ASGN2(node)->nd_vid);
- }
- F_ID(nd_mid, RNODE_OP_ASGN2, "operator");
- LAST_NODE;
- F_NODE(nd_value, RNODE_OP_ASGN2, "rvalue");
- return;
-
- case NODE_OP_ASGN_AND:
- ANN("assignment with && operator");
- ANN("format: [nd_head] &&= [nd_value]");
- ANN("example: foo &&= bar");
- goto asgn_andor;
- case NODE_OP_ASGN_OR:
- ANN("assignment with || operator");
- ANN("format: [nd_head] ||= [nd_value]");
- ANN("example: foo ||= bar");
- asgn_andor:
- F_NODE(nd_head, RNODE_OP_ASGN_AND, "variable");
- LAST_NODE;
- F_NODE(nd_value, RNODE_OP_ASGN_AND, "rvalue");
- return;
-
- case NODE_OP_CDECL:
- ANN("constant declaration with operator");
- ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
- ANN("example: A::B ||= 1");
- F_NODE(nd_head, RNODE_OP_CDECL, "constant");
- F_ID(nd_aid, RNODE_OP_CDECL, "operator");
- LAST_NODE;
- F_NODE(nd_value, RNODE_OP_CDECL, "rvalue");
- return;
-
- case NODE_CALL:
- ANN("method invocation");
- ANN("format: [nd_recv].[nd_mid]([nd_args])");
- ANN("example: obj.foo(1)");
- F_ID(nd_mid, RNODE_CALL, "method id");
- F_NODE(nd_recv, RNODE_CALL, "receiver");
- LAST_NODE;
- F_NODE(nd_args, RNODE_CALL, "arguments");
- return;
-
- case NODE_OPCALL:
- ANN("method invocation");
- ANN("format: [nd_recv] [nd_mid] [nd_args]");
- ANN("example: foo + bar");
- F_ID(nd_mid, RNODE_OPCALL, "method id");
- F_NODE(nd_recv, RNODE_OPCALL, "receiver");
- LAST_NODE;
- F_NODE(nd_args, RNODE_OPCALL, "arguments");
- return;
-
- case NODE_FCALL:
- ANN("function call");
- ANN("format: [nd_mid]([nd_args])");
- ANN("example: foo(1)");
- F_ID(nd_mid, RNODE_FCALL, "method id");
- LAST_NODE;
- F_NODE(nd_args, RNODE_FCALL, "arguments");
- return;
-
- case NODE_VCALL:
- ANN("function call with no argument");
- ANN("format: [nd_mid]");
- ANN("example: foo");
- F_ID(nd_mid, RNODE_VCALL, "method id");
- return;
-
- case NODE_QCALL:
- ANN("safe method invocation");
- ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
- ANN("example: obj&.foo(1)");
- F_ID(nd_mid, RNODE_QCALL, "method id");
- F_NODE(nd_recv, RNODE_QCALL, "receiver");
- LAST_NODE;
- F_NODE(nd_args, RNODE_QCALL, "arguments");
- return;
-
- case NODE_SUPER:
- ANN("super invocation");
- ANN("format: super [nd_args]");
- ANN("example: super 1");
- LAST_NODE;
- F_NODE(nd_args, RNODE_SUPER, "arguments");
- return;
-
- case NODE_ZSUPER:
- ANN("super invocation with no argument");
- ANN("format: super");
- ANN("example: super");
- return;
-
- case NODE_LIST:
- ANN("list constructor");
- ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
- ANN("example: [1, 2, 3]");
- dump_array(buf, indent, comment, node);
- return;
-
- case NODE_ZLIST:
- ANN("empty list constructor");
- ANN("format: []");
- ANN("example: []");
- return;
-
- case NODE_HASH:
- if (!RNODE_HASH(node)->nd_brace) {
- ANN("keyword arguments");
- ANN("format: [nd_head]");
- ANN("example: a: 1, b: 2");
- }
- else {
- ANN("hash constructor");
- ANN("format: { [nd_head] }");
- ANN("example: { 1 => 2, 3 => 4 }");
- }
- F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
- switch (RNODE_HASH(node)->nd_brace) {
- case 0: A("0 (keyword argument)"); break;
- case 1: A("1 (hash literal)"); break;
- }
- }
- LAST_NODE;
- F_NODE(nd_head, RNODE_HASH, "contents");
- return;
-
- case NODE_YIELD:
- ANN("yield invocation");
- ANN("format: yield [nd_head]");
- ANN("example: yield 1");
- LAST_NODE;
- F_NODE(nd_head, RNODE_YIELD, "arguments");
- return;
-
- case NODE_LVAR:
- ANN("local variable reference");
- ANN("format: [nd_vid](lvar)");
- ANN("example: x");
- F_ID(nd_vid, RNODE_LVAR, "local variable");
- return;
- case NODE_DVAR:
- ANN("dynamic variable reference");
- ANN("format: [nd_vid](dvar)");
- ANN("example: 1.times { x = 1; x }");
- F_ID(nd_vid, RNODE_DVAR, "local variable");
- return;
- case NODE_IVAR:
- ANN("instance variable reference");
- ANN("format: [nd_vid](ivar)");
- ANN("example: @x");
- F_ID(nd_vid, RNODE_IVAR, "instance variable");
- return;
- case NODE_CONST:
- ANN("constant reference");
- ANN("format: [nd_vid](constant)");
- ANN("example: X");
- F_ID(nd_vid, RNODE_CONST, "constant");
- return;
- case NODE_CVAR:
- ANN("class variable reference");
- ANN("format: [nd_vid](cvar)");
- ANN("example: @@x");
- F_ID(nd_vid, RNODE_CVAR, "class variable");
- return;
-
- case NODE_GVAR:
- ANN("global variable reference");
- ANN("format: [nd_vid](gvar)");
- ANN("example: $x");
- F_ID(nd_vid, RNODE_GVAR, "global variable");
- return;
-
- case NODE_NTH_REF:
- ANN("nth special variable reference");
- ANN("format: $[nd_nth]");
- ANN("example: $1, $2, ..");
- F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(RNODE_NTH_REF(node)->nd_nth); }
- return;
-
- case NODE_BACK_REF:
- ANN("back special variable reference");
- ANN("format: $[nd_nth]");
- ANN("example: $&, $`, $', $+");
- F_CUSTOM1(nd_nth, "variable") {
- char name[3] = "$ ";
- name[1] = (char)RNODE_BACK_REF(node)->nd_nth;
- A(name);
- }
- return;
-
- case NODE_MATCH:
- ANN("match expression (against $_ implicitly)");
- ANN("format: [nd_lit] (in condition)");
- ANN("example: if /foo/; foo; end");
- F_LIT(nd_lit, RNODE_MATCH, "regexp");
- return;
-
- case NODE_MATCH2:
- ANN("match expression (regexp first)");
- ANN("format: [nd_recv] =~ [nd_value]");
- ANN("example: /foo/ =~ 'foo'");
- F_NODE(nd_recv, RNODE_MATCH2, "regexp (receiver)");
- if (!RNODE_MATCH2(node)->nd_args) LAST_NODE;
- F_NODE(nd_value, RNODE_MATCH2, "string (argument)");
- if (RNODE_MATCH2(node)->nd_args) {
- LAST_NODE;
- F_NODE(nd_args, RNODE_MATCH2, "named captures");
- }
- return;
-
- case NODE_MATCH3:
- ANN("match expression (regexp second)");
- ANN("format: [nd_recv] =~ [nd_value]");
- ANN("example: 'foo' =~ /foo/");
- F_NODE(nd_recv, RNODE_MATCH3, "string (receiver)");
- LAST_NODE;
- F_NODE(nd_value, RNODE_MATCH3, "regexp (argument)");
- return;
-
- case NODE_LIT:
- ANN("literal");
- ANN("format: [nd_lit]");
- ANN("example: 1, /foo/");
- goto lit;
- case NODE_STR:
- ANN("string literal");
- ANN("format: [nd_lit]");
- ANN("example: 'foo'");
- goto lit;
- case NODE_XSTR:
- ANN("xstring literal");
- ANN("format: [nd_lit]");
- ANN("example: `foo`");
- lit:
- F_LIT(nd_lit, RNODE_LIT, "literal");
- return;
-
- case NODE_ONCE:
- ANN("once evaluation");
- ANN("format: [nd_body]");
- ANN("example: /foo#{ bar }baz/o");
- LAST_NODE;
- F_NODE(nd_body, RNODE_ONCE, "body");
- return;
-
- case NODE_DSTR:
- ANN("string literal with interpolation");
- ANN("format: [nd_lit]");
- ANN("example: \"foo#{ bar }baz\"");
- goto dlit;
- case NODE_DXSTR:
- ANN("xstring literal with interpolation");
- ANN("format: [nd_lit]");
- ANN("example: `foo#{ bar }baz`");
- goto dlit;
- case NODE_DREGX:
- ANN("regexp literal with interpolation");
- ANN("format: [nd_lit]");
- ANN("example: /foo#{ bar }baz/");
- goto dlit;
- case NODE_DSYM:
- ANN("symbol literal with interpolation");
- ANN("format: [nd_lit]");
- ANN("example: :\"foo#{ bar }baz\"");
- dlit:
- F_LIT(nd_lit, RNODE_DSTR, "preceding string");
- if (!RNODE_DSTR(node)->nd_next) return;
- F_NODE(nd_next->nd_head, RNODE_DSTR, "interpolation");
- LAST_NODE;
- F_NODE(nd_next->nd_next, RNODE_DSTR, "tailing strings");
- return;
-
- case NODE_EVSTR:
- ANN("interpolation expression");
- ANN("format: \"..#{ [nd_body] }..\"");
- ANN("example: \"foo#{ bar }baz\"");
- LAST_NODE;
- F_NODE(nd_body, RNODE_EVSTR, "body");
- return;
-
- case NODE_ARGSCAT:
- ANN("splat argument following arguments");
- ANN("format: ..(*[nd_head], [nd_body..])");
- ANN("example: foo(*ary, post_arg1, post_arg2)");
- F_NODE(nd_head, RNODE_ARGSCAT, "preceding array");
- LAST_NODE;
- F_NODE(nd_body, RNODE_ARGSCAT, "following array");
- return;
-
- case NODE_ARGSPUSH:
- ANN("splat argument following one argument");
- ANN("format: ..(*[nd_head], [nd_body])");
- ANN("example: foo(*ary, post_arg)");
- F_NODE(nd_head, RNODE_ARGSPUSH, "preceding array");
- LAST_NODE;
- F_NODE(nd_body, RNODE_ARGSPUSH, "following element");
- return;
-
- case NODE_SPLAT:
- ANN("splat argument");
- ANN("format: *[nd_head]");
- ANN("example: foo(*ary)");
- LAST_NODE;
- F_NODE(nd_head, RNODE_SPLAT, "splat'ed array");
- return;
-
- case NODE_BLOCK_PASS:
- ANN("arguments with block argument");
- ANN("format: ..([nd_head], &[nd_body])");
- ANN("example: foo(x, &blk)");
- F_NODE(nd_head, RNODE_BLOCK_PASS, "other arguments");
- LAST_NODE;
- F_NODE(nd_body, RNODE_BLOCK_PASS, "block argument");
- return;
-
- case NODE_DEFN:
- ANN("method definition");
- ANN("format: def [nd_mid] [nd_defn]; end");
- ANN("example: def foo; bar; end");
- F_ID(nd_mid, RNODE_DEFN, "method name");
- LAST_NODE;
- F_NODE(nd_defn, RNODE_DEFN, "method definition");
- return;
-
- case NODE_DEFS:
- ANN("singleton method definition");
- ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
- ANN("example: def obj.foo; bar; end");
- F_NODE(nd_recv, RNODE_DEFS, "receiver");
- F_ID(nd_mid, RNODE_DEFS, "method name");
- LAST_NODE;
- F_NODE(nd_defn, RNODE_DEFS, "method definition");
- return;
-
- case NODE_ALIAS:
- ANN("method alias statement");
- ANN("format: alias [nd_1st] [nd_2nd]");
- ANN("example: alias bar foo");
- F_NODE(nd_1st, RNODE_ALIAS, "new name");
- LAST_NODE;
- F_NODE(nd_2nd, RNODE_ALIAS, "old name");
- return;
-
- case NODE_VALIAS:
- ANN("global variable alias statement");
- ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
- ANN("example: alias $y $x");
- F_ID(nd_alias, RNODE_VALIAS, "new name");
- F_ID(nd_orig, RNODE_VALIAS, "old name");
- return;
-
- case NODE_UNDEF:
- ANN("method undef statement");
- ANN("format: undef [nd_undef]");
- ANN("example: undef foo");
- LAST_NODE;
- F_NODE(nd_undef, RNODE_UNDEF, "old name");
- return;
-
- case NODE_CLASS:
- ANN("class definition");
- ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
- ANN("example: class C2 < C; ..; end");
- F_NODE(nd_cpath, RNODE_CLASS, "class path");
- F_NODE(nd_super, RNODE_CLASS, "superclass");
- LAST_NODE;
- F_NODE(nd_body, RNODE_CLASS, "class definition");
- return;
-
- case NODE_MODULE:
- ANN("module definition");
- ANN("format: module [nd_cpath]; [nd_body]; end");
- ANN("example: module M; ..; end");
- F_NODE(nd_cpath, RNODE_MODULE, "module path");
- LAST_NODE;
- F_NODE(nd_body, RNODE_MODULE, "module definition");
- return;
-
- case NODE_SCLASS:
- ANN("singleton class definition");
- ANN("format: class << [nd_recv]; [nd_body]; end");
- ANN("example: class << obj; ..; end");
- F_NODE(nd_recv, RNODE_SCLASS, "receiver");
- LAST_NODE;
- F_NODE(nd_body, RNODE_SCLASS, "singleton class definition");
- return;
-
- case NODE_COLON2:
- ANN("scoped constant reference");
- ANN("format: [nd_head]::[nd_mid]");
- ANN("example: M::C");
- F_ID(nd_mid, RNODE_COLON2, "constant name");
- LAST_NODE;
- F_NODE(nd_head, RNODE_COLON2, "receiver");
- return;
-
- case NODE_COLON3:
- ANN("top-level constant reference");
- ANN("format: ::[nd_mid]");
- ANN("example: ::Object");
- F_ID(nd_mid, RNODE_COLON3, "constant name");
- return;
-
- case NODE_DOT2:
- ANN("range constructor (incl.)");
- ANN("format: [nd_beg]..[nd_end]");
- ANN("example: 1..5");
- goto dot;
- case NODE_DOT3:
- ANN("range constructor (excl.)");
- ANN("format: [nd_beg]...[nd_end]");
- ANN("example: 1...5");
- goto dot;
- case NODE_FLIP2:
- ANN("flip-flop condition (incl.)");
- ANN("format: [nd_beg]..[nd_end]");
- ANN("example: if (x==1)..(x==5); foo; end");
- goto dot;
- case NODE_FLIP3:
- ANN("flip-flop condition (excl.)");
- ANN("format: [nd_beg]...[nd_end]");
- ANN("example: if (x==1)...(x==5); foo; end");
- dot:
- F_NODE(nd_beg, RNODE_DOT2, "begin");
- LAST_NODE;
- F_NODE(nd_end, RNODE_DOT2, "end");
- return;
-
- case NODE_SELF:
- ANN("self");
- ANN("format: self");
- ANN("example: self");
- return;
-
- case NODE_NIL:
- ANN("nil");
- ANN("format: nil");
- ANN("example: nil");
- return;
-
- case NODE_TRUE:
- ANN("true");
- ANN("format: true");
- ANN("example: true");
- return;
-
- case NODE_FALSE:
- ANN("false");
- ANN("format: false");
- ANN("example: false");
- return;
-
- case NODE_ERRINFO:
- ANN("virtual reference to $!");
- ANN("format: rescue => id");
- ANN("example: rescue => id");
- return;
-
- case NODE_DEFINED:
- ANN("defined? expression");
- ANN("format: defined?([nd_head])");
- ANN("example: defined?(foo)");
- F_NODE(nd_head, RNODE_DEFINED, "expr");
- return;
-
- case NODE_POSTEXE:
- ANN("post-execution");
- ANN("format: END { [nd_body] }");
- ANN("example: END { foo }");
- LAST_NODE;
- F_NODE(nd_body, RNODE_POSTEXE, "END clause");
- return;
-
- case NODE_ATTRASGN:
- ANN("attr assignment");
- ANN("format: [nd_recv].[nd_mid] = [nd_args]");
- ANN("example: struct.field = foo");
- F_NODE(nd_recv, RNODE_ATTRASGN, "receiver");
- F_ID(nd_mid, RNODE_ATTRASGN, "method name");
- LAST_NODE;
- F_NODE(nd_args, RNODE_ATTRASGN, "arguments");
- return;
-
- case NODE_LAMBDA:
- ANN("lambda expression");
- ANN("format: -> [nd_body]");
- ANN("example: -> { foo }");
- LAST_NODE;
- F_NODE(nd_body, RNODE_LAMBDA, "lambda clause");
- return;
-
- case NODE_OPT_ARG:
- ANN("optional arguments");
- ANN("format: def method_name([nd_body=some], [nd_next..])");
- ANN("example: def foo(a, b=1, c); end");
- F_NODE(nd_body, RNODE_OPT_ARG, "body");
- LAST_NODE;
- F_NODE(nd_next, RNODE_OPT_ARG, "next");
- return;
-
- case NODE_KW_ARG:
- ANN("keyword arguments");
- ANN("format: def method_name([nd_body=some], [nd_next..])");
- ANN("example: def foo(a:1, b:2); end");
- F_NODE(nd_body, RNODE_KW_ARG, "body");
- LAST_NODE;
- F_NODE(nd_next, RNODE_KW_ARG, "next");
- return;
-
- case NODE_POSTARG:
- ANN("post arguments");
- ANN("format: *[nd_1st], [nd_2nd..] = ..");
- ANN("example: a, *rest, z = foo");
- if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) {
- F_NODE(nd_1st, RNODE_POSTARG, "rest argument");
- }
- else {
- F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
- }
- LAST_NODE;
- F_NODE(nd_2nd, RNODE_POSTARG, "post arguments");
- return;
-
- case NODE_ARGS:
- ANN("method parameters");
- ANN("format: def method_name(.., [nd_ainfo.nd_optargs], *[nd_ainfo.rest_arg], [nd_ainfo.first_post_arg], .., [nd_ainfo.kw_args], **[nd_ainfo.kw_rest_arg], &[nd_ainfo.block_arg])");
- ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, kw: 1, **kwrest, &blk); end");
- F_INT(nd_ainfo.pre_args_num, RNODE_ARGS, "count of mandatory (pre-)arguments");
- F_NODE(nd_ainfo.pre_init, RNODE_ARGS, "initialization of (pre-)arguments");
- F_INT(nd_ainfo.post_args_num, RNODE_ARGS, "count of mandatory post-arguments");
- F_NODE(nd_ainfo.post_init, RNODE_ARGS, "initialization of post-arguments");
- F_ID(nd_ainfo.first_post_arg, RNODE_ARGS, "first post argument");
- F_CUSTOM1(nd_ainfo.rest_arg, "rest argument") {
- if (RNODE_ARGS(node)->nd_ainfo.rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
- A("1 (excessed comma)");
- }
- else {
- A_ID(RNODE_ARGS(node)->nd_ainfo.rest_arg);
- }
- }
- F_ID(nd_ainfo.block_arg, RNODE_ARGS, "block argument");
- F_NODE(nd_ainfo.opt_args, RNODE_ARGS, "optional arguments");
- F_NODE(nd_ainfo.kw_args, RNODE_ARGS, "keyword arguments");
- LAST_NODE;
- F_NODE(nd_ainfo.kw_rest_arg, RNODE_ARGS, "keyword rest argument");
- return;
-
- case NODE_SCOPE:
- ANN("new scope");
- ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
- F_CUSTOM1(nd_tbl, "local table") {
- rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl;
- int i;
- int size = tbl ? tbl->size : 0;
- if (size == 0) A("(empty)");
- for (i = 0; i < size; i++) {
- A_ID(tbl->ids[i]); if (i < size - 1) A(",");
- }
- }
- F_NODE(nd_args, RNODE_SCOPE, "arguments");
- LAST_NODE;
- F_NODE(nd_body, RNODE_SCOPE, "body");
- return;
-
- case NODE_ARYPTN:
- ANN("array pattern");
- ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
- F_NODE(nd_pconst, RNODE_ARYPTN, "constant");
- F_NODE(pre_args, RNODE_ARYPTN, "pre arguments");
- if (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg)) {
- F_NODE(rest_arg, RNODE_ARYPTN, "rest argument");
- }
- else {
- F_MSG(rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
- }
- LAST_NODE;
- F_NODE(post_args, RNODE_ARYPTN, "post arguments");
- return;
-
- case NODE_FNDPTN:
- ANN("find pattern");
- ANN("format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])");
- F_NODE(nd_pconst, RNODE_FNDPTN, "constant");
- if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->pre_rest_arg)) {
- F_NODE(pre_rest_arg, RNODE_FNDPTN, "pre rest argument");
- }
- else {
- F_MSG(pre_rest_arg, "pre rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
- }
- F_NODE(args, RNODE_FNDPTN, "arguments");
-
- LAST_NODE;
- if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->post_rest_arg)) {
- F_NODE(post_rest_arg, RNODE_FNDPTN, "post rest argument");
- }
- else {
- F_MSG(post_rest_arg, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
- }
- return;
-
- case NODE_HSHPTN:
- ANN("hash pattern");
- ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
- F_NODE(nd_pconst, RNODE_HSHPTN, "constant");
- F_NODE(nd_pkwargs, RNODE_HSHPTN, "keyword arguments");
- LAST_NODE;
- if (RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
- F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
- }
- else {
- F_NODE(nd_pkwrestarg, RNODE_HSHPTN, "keyword rest argument");
- }
- return;
- case NODE_ERROR:
- ANN("Broken input recovered by Error Tolerant mode");
- return;
-
- case NODE_ARGS_AUX:
- case NODE_RIPPER:
- case NODE_RIPPER_VALUES:
- case NODE_LAST:
- break;
- }
-
- rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
-}
-
-VALUE
-rb_parser_dump_tree(const NODE *node, int comment)
-{
- VALUE buf = rb_str_new_cstr(
- "###########################################################\n"
- "## Do NOT use this node dump for any purpose other than ##\n"
- "## debug and research. Compatibility is not guaranteed. ##\n"
- "###########################################################\n\n"
- );
- dump_node(buf, rb_str_new_cstr("# "), comment, node);
- return buf;
-}
diff --git a/numeric.c b/numeric.c
index d56cf18ff2..6dd1ff6d2f 100644
--- a/numeric.c
+++ b/numeric.c
@@ -144,37 +144,31 @@ round_half_down(double x, double s)
static double
round_half_even(double x, double s)
{
- double u, v, us, vs, f, d, uf;
-
- v = modf(x, &u);
- us = u * s;
- vs = v * s;
+ double f, d, xs = x * s;
if (x > 0.0) {
- f = floor(vs);
- uf = us + f;
- d = vs - f;
+ f = floor(xs);
+ d = xs - f;
if (d > 0.5)
d = 1.0;
- else if (d == 0.5 || ((double)((uf + 0.5) / s) <= x))
- d = fmod(uf, 2.0);
+ else if (d == 0.5 || ((double)((f + 0.5) / s) <= x))
+ d = fmod(f, 2.0);
else
d = 0.0;
x = f + d;
}
else if (x < 0.0) {
- f = ceil(vs);
- uf = us + f;
- d = f - vs;
+ f = ceil(xs);
+ d = f - xs;
if (d > 0.5)
d = 1.0;
- else if (d == 0.5 || ((double)((uf - 0.5) / s) >= x))
- d = fmod(-uf, 2.0);
+ else if (d == 0.5 || ((double)((f - 0.5) / s) >= x))
+ d = fmod(-f, 2.0);
else
d = 0.0;
x = f - d;
}
- return us + x;
+ return x;
}
static VALUE fix_lshift(long, unsigned long);
@@ -671,7 +665,7 @@ num_div(VALUE x, VALUE y)
* Of the Core and Standard Library classes,
* only Rational uses this implementation.
*
- * For Rational +r+ and real number +n+, these expressions are equivalent:
+ * For \Rational +r+ and real number +n+, these expressions are equivalent:
*
* r % n
* r-n*(r/n).floor
@@ -694,6 +688,8 @@ num_div(VALUE x, VALUE y)
* (-r) % r2 # => (119/100)
* (-r) %-r2 # => (-21/100)
*
+ * Numeric#modulo is an alias for Numeric#%.
+ *
*/
static VALUE
@@ -738,9 +734,6 @@ num_modulo(VALUE x, VALUE y)
static VALUE
num_remainder(VALUE x, VALUE y)
{
- if (!rb_obj_is_kind_of(y, rb_cNumeric)) {
- do_coerce(&x, &y, TRUE);
- }
VALUE z = num_funcall1(x, '%', y);
if ((!rb_equal(z, INT2FIX(0))) &&
@@ -802,6 +795,8 @@ num_divmod(VALUE x, VALUE y)
* (-34.56).abs #=> 34.56
* -34.56.abs #=> 34.56
*
+ * Numeric#magnitude is an alias for Numeric#abs.
+ *
*/
static VALUE
@@ -948,7 +943,7 @@ num_negative_p(VALUE num)
* So you should know its esoteric system. See following:
*
* - https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
- * - https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#-why-are-rubys-floats-imprecise
+ * - https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#floats_imprecise
* - https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
*
* You can create a \Float object explicitly with:
@@ -999,10 +994,10 @@ num_negative_p(VALUE num)
* - #/: Returns the quotient of +self+ and the given value.
* - #ceil: Returns the smallest number greater than or equal to +self+.
* - #coerce: Returns a 2-element array containing the given value converted to a \Float
- * and +self+
+ and +self+
* - #divmod: Returns a 2-element array containing the quotient and remainder
* results of dividing +self+ by the given value.
- * - #fdiv: Returns the \Float result of dividing +self+ by the given value.
+ * - #fdiv: Returns the Float result of dividing +self+ by the given value.
* - #floor: Returns the greatest number smaller than or equal to +self+.
* - #next_float: Returns the next-larger representable \Float.
* - #prev_float: Returns the next-smaller representable \Float.
@@ -1018,7 +1013,7 @@ num_negative_p(VALUE num)
VALUE
rb_float_new_in_heap(double d)
{
- NEWOBJ_OF(flt, struct RFloat, rb_cFloat, T_FLOAT | (RGENGC_WB_PROTECTED_FLOAT ? FL_WB_PROTECTED : 0), sizeof(struct RFloat), 0);
+ NEWOBJ_OF(flt, struct RFloat, rb_cFloat, T_FLOAT | (RGENGC_WB_PROTECTED_FLOAT ? FL_WB_PROTECTED : 0));
#if SIZEOF_DOUBLE <= SIZEOF_VALUE
flt->float_value = d;
@@ -1078,7 +1073,7 @@ flo_to_s(VALUE flt)
s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
memcpy(buf, p, digs);
- free(p);
+ xfree(p);
if (decpt > 0) {
if (decpt < digs) {
memmove(buf + decpt + 1, buf + decpt, digs - decpt);
@@ -1152,7 +1147,7 @@ flo_coerce(VALUE x, VALUE y)
return rb_assoc_new(rb_Float(y), x);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_float_uminus(VALUE flt)
{
return DBL2NUM(-RFLOAT_VALUE(flt));
@@ -1265,7 +1260,7 @@ double_div_double(double x, double y)
}
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_flo_div_flo(VALUE x, VALUE y)
{
double num = RFLOAT_VALUE(x);
@@ -1324,6 +1319,8 @@ rb_float_div(VALUE x, VALUE y)
* f.quo(Rational(2, 1)) # => 1.57
* f.quo(Complex(2, 0)) # => (1.57+0.0i)
*
+ * Float#fdiv is an alias for Float#quo.
+ *
*/
static VALUE
@@ -1375,7 +1372,7 @@ flodivmod(double x, double y, double *divp, double *modp)
* An error will be raised if y == 0.
*/
-double
+MJIT_FUNC_EXPORTED double
ruby_float_mod(double x, double y)
{
double mod;
@@ -1410,6 +1407,8 @@ ruby_float_mod(double x, double y)
* 10.0 % 4.0 # => 2.0
* 10.0 % Rational(4, 1) # => 2.0
*
+ * Float#modulo is an alias for Float#%.
+ *
*/
static VALUE
@@ -1610,7 +1609,7 @@ num_equal(VALUE x, VALUE y)
*
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_float_equal(VALUE x, VALUE y)
{
volatile double a, b;
@@ -1683,12 +1682,12 @@ rb_dbl_cmp(double a, double b)
* Examples:
*
* 2.0 <=> 2 # => 0
- * 2.0 <=> 2.0 # => 0
- * 2.0 <=> Rational(2, 1) # => 0
- * 2.0 <=> Complex(2, 0) # => 0
- * 2.0 <=> 1.9 # => 1
- * 2.0 <=> 2.1 # => -1
- * 2.0 <=> 'foo' # => nil
+ 2.0 <=> 2.0 # => 0
+ 2.0 <=> Rational(2, 1) # => 0
+ 2.0 <=> Complex(2, 0) # => 0
+ 2.0 <=> 1.9 # => 1
+ 2.0 <=> 2.1 # => -1
+ 2.0 <=> 'foo' # => nil
*
* This is the basis for the tests in the Comparable module.
*
@@ -1728,7 +1727,7 @@ flo_cmp(VALUE x, VALUE y)
return rb_dbl_cmp(a, b);
}
-int
+MJIT_FUNC_EXPORTED int
rb_float_cmp(VALUE x, VALUE y)
{
return NUM2INT(ensure_cmp(flo_cmp(x, y), x, y));
@@ -1922,7 +1921,7 @@ flo_le(VALUE x, VALUE y)
* Related: Float#== (performs type conversions).
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_float_eql(VALUE x, VALUE y)
{
if (RB_FLOAT_TYPE_P(y)) {
@@ -1938,7 +1937,7 @@ rb_float_eql(VALUE x, VALUE y)
#define flo_eql rb_float_eql
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_float_abs(VALUE flt)
{
double val = fabs(RFLOAT_VALUE(flt));
@@ -2335,7 +2334,7 @@ int_half_p_half_down(VALUE num, VALUE n, VALUE f)
}
/*
- * Assumes num is an \Integer, ndigits <= 0
+ * Assumes num is an Integer, ndigits <= 0
*/
static VALUE
rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode)
@@ -2373,11 +2372,7 @@ rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode)
static VALUE
rb_int_floor(VALUE num, int ndigits)
{
- VALUE f;
-
- if (int_round_zero_p(num, ndigits))
- return INT2FIX(0);
- f = int_pow(10, -ndigits);
+ VALUE f = int_pow(10, -ndigits);
if (FIXNUM_P(num) && FIXNUM_P(f)) {
SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
int neg = x < 0;
@@ -2386,21 +2381,19 @@ rb_int_floor(VALUE num, int ndigits)
if (neg) x = -x;
return LONG2NUM(x);
}
- if (RB_FLOAT_TYPE_P(f)) {
- /* then int_pow overflow */
- return INT2FIX(0);
+ else {
+ bool neg = int_neg_p(num);
+ if (neg) num = rb_int_minus(rb_int_plus(rb_int_uminus(num), f), INT2FIX(1));
+ num = rb_int_mul(rb_int_div(num, f), f);
+ if (neg) num = rb_int_uminus(num);
+ return num;
}
- return rb_int_minus(num, rb_int_modulo(num, f));
}
static VALUE
rb_int_ceil(VALUE num, int ndigits)
{
- VALUE f;
-
- if (int_round_zero_p(num, ndigits))
- return INT2FIX(0);
- f = int_pow(10, -ndigits);
+ VALUE f = int_pow(10, -ndigits);
if (FIXNUM_P(num) && FIXNUM_P(f)) {
SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
int neg = x < 0;
@@ -2410,11 +2403,16 @@ rb_int_ceil(VALUE num, int ndigits)
if (neg) x = -x;
return LONG2NUM(x);
}
- if (RB_FLOAT_TYPE_P(f)) {
- /* then int_pow overflow */
- return INT2FIX(0);
+ else {
+ bool neg = int_neg_p(num);
+ if (neg)
+ num = rb_int_uminus(num);
+ else
+ num = rb_int_plus(num, rb_int_minus(f, INT2FIX(1)));
+ num = rb_int_mul(rb_int_div(num, f), f);
+ if (neg) num = rb_int_uminus(num);
+ return num;
}
- return rb_int_plus(num, rb_int_minus(f, rb_int_modulo(num, f)));
}
VALUE
@@ -2592,6 +2590,7 @@ float_round_underflow(int ndigits, int binexp)
*
* (0.3 / 0.1).to_i # => 2 (!)
*
+ * Float#to_int is an alias for Float#to_i.
*/
static VALUE
@@ -2834,7 +2833,7 @@ ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
}
if (RTEST(rb_funcall(from, cmp, 1, to))) return INT2FIX(0);
result = rb_funcall(rb_funcall(to, '-', 1, from), id_div, 1, step);
- if (!excl || RTEST(rb_funcall(to, cmp, 1, rb_funcall(from, '+', 1, rb_funcall(result, '*', 1, step))))) {
+ if (!excl || RTEST(rb_funcall(rb_funcall(from, '+', 1, rb_funcall(result, '*', 1, step)), cmp, 1, to))) {
result = rb_funcall(result, '+', 1, INT2FIX(1));
}
return result;
@@ -2960,11 +2959,11 @@ num_step_size(VALUE from, VALUE args, VALUE eobj)
* The generated sequence:
*
* - Begins with +self+.
- * - Continues at intervals of +by+ (which may not be zero).
- * - Ends with the last number that is within or equal to +to+;
- * that is, less than or equal to +to+ if +by+ is positive,
- * greater than or equal to +to+ if +by+ is negative.
- * If +to+ is +nil+, the sequence is of infinite length.
+ * - Continues at intervals of +step+ (which may not be zero).
+ * - Ends with the last number that is within or equal to +limit+;
+ * that is, less than or equal to +limit+ if +step+ is positive,
+ * greater than or equal to +limit+ if +step+ is negative.
+ * If +limit+ is not given, the sequence is of infinite length.
*
* If a block is given, calls the block with each number in the sequence;
* returns +self+. If no block is given, returns an Enumerator::ArithmeticSequence.
@@ -3006,7 +3005,7 @@ num_step_size(VALUE from, VALUE args, VALUE eobj)
*
* <b>Positional Arguments</b>
*
- * With optional positional arguments +to+ and +by+,
+ * With optional positional arguments +limit+ and +step+,
* their values (or defaults) determine the step and limit:
*
* squares = []
@@ -3165,7 +3164,7 @@ rb_num2ulong_internal(VALUE val, int *wrap_p)
{
again:
if (NIL_P(val)) {
- rb_raise(rb_eTypeError, "no implicit conversion of nil into Integer");
+ rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
}
if (FIXNUM_P(val)) {
@@ -3440,7 +3439,7 @@ unsigned LONG_LONG
rb_num2ull(VALUE val)
{
if (NIL_P(val)) {
- rb_raise(rb_eTypeError, "no implicit conversion of nil into Integer");
+ rb_raise(rb_eTypeError, "no implicit conversion from nil");
}
else if (FIXNUM_P(val)) {
return (LONG_LONG)FIX2LONG(val); /* this is FIX2LONG, intended */
@@ -3459,10 +3458,15 @@ rb_num2ull(VALUE val)
else if (RB_BIGNUM_TYPE_P(val)) {
return rb_big2ull(val);
}
- else {
- val = rb_to_int(val);
- return NUM2ULL(val);
+ else if (RB_TYPE_P(val, T_STRING)) {
+ rb_raise(rb_eTypeError, "no implicit conversion from string");
}
+ else if (RB_TYPE_P(val, T_TRUE) || RB_TYPE_P(val, T_FALSE)) {
+ rb_raise(rb_eTypeError, "no implicit conversion from boolean");
+ }
+
+ val = rb_to_int(val);
+ return NUM2ULL(val);
}
#endif /* HAVE_LONG_LONG */
@@ -3690,6 +3694,8 @@ int_nobits_p(VALUE num, VALUE mask)
* 1.succ #=> 2
* -1.succ #=> 0
*
+ * Integer#next is an alias for Integer#succ.
+ *
* Related: Integer#pred (predecessor value).
*/
@@ -3886,7 +3892,7 @@ rb_fix2str(VALUE x, int base)
static VALUE rb_fix_to_s_static[10];
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_fix_to_s(VALUE x)
{
long i = FIX2LONG(x);
@@ -3912,9 +3918,12 @@ rb_fix_to_s(VALUE x)
* 78546939656932.to_s(36) # => "rubyrules"
*
* Raises an exception if +base+ is out of range.
+ *
+ * Integer#inspect is an alias for Integer#to_s.
+ *
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_int_to_s(int argc, VALUE *argv, VALUE x)
{
int base;
@@ -4096,13 +4105,7 @@ static double
fix_fdiv_double(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
- long iy = FIX2LONG(y);
-#if SIZEOF_LONG * CHAR_BIT > DBL_MANT_DIG
- if ((iy < 0 ? -iy : iy) >= (1L << DBL_MANT_DIG)) {
- return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), rb_int2big(iy));
- }
-#endif
- return double_div_double(FIX2LONG(x), iy);
+ return double_div_double(FIX2LONG(x), FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), y);
@@ -4120,7 +4123,7 @@ rb_int_fdiv_double(VALUE x, VALUE y)
{
if (RB_INTEGER_TYPE_P(y) && !FIXNUM_ZERO_P(y)) {
VALUE gcd = rb_gcd(x, y);
- if (!FIXNUM_ZERO_P(gcd) && gcd != INT2FIX(1)) {
+ if (!FIXNUM_ZERO_P(gcd)) {
x = rb_int_idiv(x, gcd);
y = rb_int_idiv(y, gcd);
}
@@ -4311,6 +4314,8 @@ fix_mod(VALUE x, VALUE y)
* 10 % 3.0 # => 1.0
* 10 % Rational(3, 1) # => (1/1)
*
+ * Integer#modulo is an alias for Integer#%.
+ *
*/
VALUE
rb_int_modulo(VALUE x, VALUE y)
@@ -4351,22 +4356,12 @@ static VALUE
int_remainder(VALUE x, VALUE y)
{
if (FIXNUM_P(x)) {
- if (FIXNUM_P(y)) {
- VALUE z = fix_mod(x, y);
- assert(FIXNUM_P(z));
- if (z != INT2FIX(0) && (SIGNED_VALUE)(x ^ y) < 0)
- z = fix_minus(z, y);
- return z;
- }
- else if (!RB_BIGNUM_TYPE_P(y)) {
- return num_remainder(x, y);
- }
- x = rb_int2big(FIX2LONG(x));
+ return num_remainder(x, y);
}
- else if (!RB_BIGNUM_TYPE_P(x)) {
- return Qnil;
+ else if (RB_BIGNUM_TYPE_P(x)) {
+ return rb_big_remainder(x, y);
}
- return rb_big_remainder(x, y);
+ return Qnil;
}
static VALUE
@@ -4629,6 +4624,9 @@ fix_equal(VALUE x, VALUE y)
* 1 == 1.0 #=> true
*
* Related: Integer#eql? (requires +other+ to be an \Integer).
+ *
+ * Integer#=== is an alias for Integer#==.
+ *
*/
VALUE
@@ -5175,7 +5173,7 @@ rb_int_rshift(VALUE x, VALUE y)
return Qnil;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_fix_aref(VALUE fix, VALUE idx)
{
long val = FIX2LONG(fix);
@@ -5345,7 +5343,7 @@ int_aref(int const argc, VALUE * const argv, VALUE const num)
* 1.to_f # => 1.0
* -1.to_f # => -1.0
*
- * If the value of +self+ does not fit in a Float,
+ * If the value of +self+ does not fit in a \Float,
* the result is infinity:
*
* (10**400).to_f # => Infinity
@@ -5399,7 +5397,7 @@ fix_size(VALUE fix)
return INT2FIX(sizeof(long));
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_int_size(VALUE num)
{
if (FIXNUM_P(num)) {
@@ -5658,6 +5656,58 @@ int_downto(VALUE from, VALUE to)
return from;
}
+static VALUE
+int_dotimes_size(VALUE num, VALUE args, VALUE eobj)
+{
+ if (FIXNUM_P(num)) {
+ if (NUM2LONG(num) <= 0) return INT2FIX(0);
+ }
+ else {
+ if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) return INT2FIX(0);
+ }
+ return num;
+}
+
+/*
+ * call-seq:
+ * times {|i| ... } -> self
+ * times -> enumerator
+ *
+ * Calls the given block +self+ times with each integer in <tt>(0..self-1)</tt>:
+ *
+ * a = []
+ * 5.times {|i| a.push(i) } # => 5
+ * a # => [0, 1, 2, 3, 4]
+ *
+ * With no block given, returns an Enumerator.
+ *
+ */
+
+static VALUE
+int_dotimes(VALUE num)
+{
+ RETURN_SIZED_ENUMERATOR(num, 0, 0, int_dotimes_size);
+
+ if (FIXNUM_P(num)) {
+ long i, end;
+
+ end = FIX2LONG(num);
+ for (i=0; i<end; i++) {
+ rb_yield_1(LONG2FIX(i));
+ }
+ }
+ else {
+ VALUE i = INT2FIX(0);
+
+ for (;;) {
+ if (!RTEST(int_le(i, num))) break;
+ rb_yield(i);
+ i = rb_int_plus(i, INT2FIX(1));
+ }
+ }
+ return num;
+}
+
/*
* call-seq:
* round(ndigits= 0, half: :up) -> integer
@@ -5938,22 +5988,7 @@ rb_int_s_isqrt(VALUE self, VALUE num)
}
}
-/*
- * call-seq:
- * Integer.try_convert(object) -> object, integer, or nil
- *
- * If +object+ is an \Integer object, returns +object+.
- * Integer.try_convert(1) # => 1
- *
- * Otherwise if +object+ responds to <tt>:to_int</tt>,
- * calls <tt>object.to_int</tt> and returns the result.
- * Integer.try_convert(1.25) # => 1
- *
- * Returns +nil+ if +object+ does not respond to <tt>:to_int</tt>
- * Integer.try_convert([]) # => nil
- *
- * Raises an exception unless <tt>object.to_int</tt> returns an \Integer object.
- */
+/* :nodoc: */
static VALUE
int_s_try_convert(VALUE self, VALUE num)
{
@@ -5986,9 +6021,9 @@ int_s_try_convert(VALUE self, VALUE num)
/*
* Document-class: Numeric
*
- * \Numeric is the class from which all higher-level numeric classes should inherit.
+ * Numeric is the class from which all higher-level numeric classes should inherit.
*
- * \Numeric allows instantiation of heap-allocated objects. Other core numeric classes such as
+ * Numeric allows instantiation of heap-allocated objects. Other core numeric classes such as
* Integer are implemented as immediates, which means that each Integer is a single immutable
* object which is always passed by value.
*
@@ -6002,9 +6037,9 @@ int_s_try_convert(VALUE self, VALUE num)
* 1.dup #=> 1
* 1.object_id == 1.dup.object_id #=> true
*
- * For this reason, \Numeric should be used when defining other numeric classes.
+ * For this reason, Numeric should be used when defining other numeric classes.
*
- * Classes which inherit from \Numeric must implement +coerce+, which returns a two-member
+ * Classes which inherit from Numeric must implement +coerce+, which returns a two-member
* Array containing an object that has been coerced into an instance of the new class
* and +self+ (see #coerce).
*
@@ -6197,6 +6232,7 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
rb_define_method(rb_cInteger, "upto", int_upto, 1);
rb_define_method(rb_cInteger, "downto", int_downto, 1);
+ rb_define_method(rb_cInteger, "times", int_dotimes, 0);
rb_define_method(rb_cInteger, "succ", int_succ, 0);
rb_define_method(rb_cInteger, "next", int_succ, 0);
rb_define_method(rb_cInteger, "pred", int_pred, 0);
diff --git a/numeric.rb b/numeric.rb
index 3c059a58a4..f026679210 100644
--- a/numeric.rb
+++ b/numeric.rb
@@ -1,56 +1,62 @@
class Numeric
-
+ #
# call-seq:
- # real? -> true or false
+ # num.real? -> true or false
#
- # Returns +true+ if +self+ is a real number (i.e. not Complex).
+ # Returns +true+ if +num+ is a real number (i.e. not Complex).
#
def real?
true
end
+ #
# call-seq:
- # real -> self
+ # num.real -> self
#
- # Returns +self+.
+ # Returns self.
#
def real
self
end
+ #
# call-seq:
- # integer? -> true or false
+ # num.integer? -> true or false
#
- # Returns +true+ if +self+ is an Integer.
+ # Returns +true+ if +num+ is an Integer.
#
- # 1.0.integer? # => false
- # 1.integer? # => true
+ # 1.0.integer? #=> false
+ # 1.integer? #=> true
#
def integer?
false
end
+ #
# call-seq:
- # finite? -> true or false
+ # num.finite? -> true or false
#
- # Returns +true+ if +self+ is a finite number, +false+ otherwise.
+ # Returns +true+ if +num+ is a finite number, otherwise returns +false+.
#
def finite?
true
end
+ #
# call-seq:
- # infinite? -> -1, 1, or nil
+ # num.infinite? -> -1, 1, or nil
#
- # Returns +nil+, -1, or 1 depending on whether +self+ is
- # finite, <tt>-Infinity</tt>, or <tt>+Infinity</tt>.
+ # Returns +nil+, -1, or 1 depending on whether the value is
+ # finite, <code>-Infinity</code>, or <code>+Infinity</code>.
#
def infinite?
nil
end
+ #
# call-seq:
- # imag -> 0
+ # num.imag -> 0
+ # num.imaginary -> 0
#
# Returns zero.
#
@@ -60,10 +66,12 @@ class Numeric
alias imag imaginary
+ #
# call-seq:
- # conj -> self
+ # num.conj -> self
+ # num.conjugate -> self
#
- # Returns +self+.
+ # Returns self.
#
def conjugate
self
@@ -74,298 +82,323 @@ end
class Integer
# call-seq:
- # -int -> integer
+ # -int -> integer
#
- # Returns +self+, negated.
+ # Returns +int+, negated.
def -@
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_uminus(self)'
end
# call-seq:
- # ~int -> integer
+ # ~int -> integer
#
- # One's complement:
- # returns the value of +self+ with each bit inverted.
+ # One's complement: returns a number where each bit is flipped.
#
- # Because an integer value is conceptually of infinite length,
- # the result acts as if it had an infinite number of
- # one bits to the left.
- # In hex representations, this is displayed
- # as two periods to the left of the digits:
- #
- # sprintf("%X", ~0x1122334455) # => "..FEEDDCCBBAA"
+ # Inverts the bits in an Integer. As integers are conceptually of
+ # infinite length, the result acts as if it had an infinite number of
+ # one bits to the left. In hex representations, this is displayed
+ # as two periods to the left of the digits.
#
+ # sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
def ~
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_comp(self)'
end
# call-seq:
- # abs -> integer
+ # int.abs -> integer
+ # int.magnitude -> integer
#
- # Returns the absolute value of +self+.
+ # Returns the absolute value of +int+.
#
- # (-12345).abs # => 12345
- # -12345.abs # => 12345
- # 12345.abs # => 12345
+ # (-12345).abs #=> 12345
+ # -12345.abs #=> 12345
+ # 12345.abs #=> 12345
#
+ # Integer#magnitude is an alias for Integer#abs.
def abs
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_abs(self)'
end
# call-seq:
- # bit_length -> integer
+ # int.bit_length -> integer
#
- # Returns the number of bits of the value of +self+,
- # which is the bit position of the highest-order bit
- # that is different from the sign bit
- # (where the least significant bit has bit position 1).
- # If there is no such bit (zero or minus one), returns zero.
- #
- # This method returns <tt>ceil(log2(self < 0 ? -self : self + 1))</tt>>.
- #
- # (-2**1000-1).bit_length # => 1001
- # (-2**1000).bit_length # => 1000
- # (-2**1000+1).bit_length # => 1000
- # (-2**12-1).bit_length # => 13
- # (-2**12).bit_length # => 12
- # (-2**12+1).bit_length # => 12
- # -0x101.bit_length # => 9
- # -0x100.bit_length # => 8
- # -0xff.bit_length # => 8
- # -2.bit_length # => 1
- # -1.bit_length # => 0
- # 0.bit_length # => 0
- # 1.bit_length # => 1
- # 0xff.bit_length # => 8
- # 0x100.bit_length # => 9
- # (2**12-1).bit_length # => 12
- # (2**12).bit_length # => 13
- # (2**12+1).bit_length # => 13
- # (2**1000-1).bit_length # => 1000
- # (2**1000).bit_length # => 1001
- # (2**1000+1).bit_length # => 1001
- #
- # For \Integer _n_,
- # this method can be used to detect overflow in Array#pack:
- #
- # if n.bit_length < 32
- # [n].pack('l') # No overflow.
- # else
- # raise 'Overflow'
- # end
+ # Returns the number of bits of the value of +int+.
#
+ # "Number of bits" means the bit position of the highest bit
+ # which is different from the sign bit
+ # (where the least significant bit has bit position 1).
+ # If there is no such bit (zero or minus one), zero is returned.
+ #
+ # I.e. this method returns <i>ceil(log2(int < 0 ? -int : int+1))</i>.
+ #
+ # (-2**1000-1).bit_length #=> 1001
+ # (-2**1000).bit_length #=> 1000
+ # (-2**1000+1).bit_length #=> 1000
+ # (-2**12-1).bit_length #=> 13
+ # (-2**12).bit_length #=> 12
+ # (-2**12+1).bit_length #=> 12
+ # -0x101.bit_length #=> 9
+ # -0x100.bit_length #=> 8
+ # -0xff.bit_length #=> 8
+ # -2.bit_length #=> 1
+ # -1.bit_length #=> 0
+ # 0.bit_length #=> 0
+ # 1.bit_length #=> 1
+ # 0xff.bit_length #=> 8
+ # 0x100.bit_length #=> 9
+ # (2**12-1).bit_length #=> 12
+ # (2**12).bit_length #=> 13
+ # (2**12+1).bit_length #=> 13
+ # (2**1000-1).bit_length #=> 1000
+ # (2**1000).bit_length #=> 1001
+ # (2**1000+1).bit_length #=> 1001
+ #
+ # This method can be used to detect overflow in Array#pack as follows:
+ #
+ # if n.bit_length < 32
+ # [n].pack("l") # no overflow
+ # else
+ # raise "overflow"
+ # end
def bit_length
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_bit_length(self)'
end
# call-seq:
- # even? -> true or false
+ # int.even? -> true or false
#
- # Returns +true+ if +self+ is an even number, +false+ otherwise.
+ # Returns +true+ if +int+ is an even number.
def even?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_even_p(self)'
end
# call-seq:
- # integer? -> true
+ # int.integer? -> true
#
- # Since +self+ is already an \Integer, always returns +true+.
+ # Since +int+ is already an Integer, this always returns +true+.
def integer?
true
end
alias magnitude abs
+=begin
+ def magnitude
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_abs(self)'
+ end
+=end
# call-seq:
- # odd? -> true or false
+ # int.odd? -> true or false
#
- # Returns +true+ if +self+ is an odd number, +false+ otherwise.
+ # Returns +true+ if +int+ is an odd number.
def odd?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_odd_p(self)'
end
# call-seq:
- # ord -> self
+ # int.ord -> self
+ #
+ # Returns the +int+ itself.
#
- # Returns +self+;
- # intended for compatibility to character literals in Ruby 1.9.
+ # 97.ord #=> 97
+ #
+ # This method is intended for compatibility to character literals
+ # in Ruby 1.9.
+ #
+ # For example, <code>?a.ord</code> returns 97 both in 1.8 and 1.9.
def ord
self
end
+ #
+ # Document-method: Integer#size
# call-seq:
- # size -> integer
+ # int.size -> int
#
- # Returns the number of bytes in the machine representation of +self+;
- # the value is system-dependent:
+ # Returns the number of bytes in the machine representation of +int+
+ # (machine dependent).
#
- # 1.size # => 8
- # -1.size # => 8
- # 2147483647.size # => 8
- # (256**10 - 1).size # => 10
- # (256**20 - 1).size # => 20
- # (256**40 - 1).size # => 40
+ # 1.size #=> 8
+ # -1.size #=> 8
+ # 2147483647.size #=> 8
+ # (256**10 - 1).size #=> 10
+ # (256**20 - 1).size #=> 20
+ # (256**40 - 1).size #=> 40
#
def size
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_size(self)'
end
- # call-seq:
- # times {|i| ... } -> self
- # times -> enumerator
- #
- # Calls the given block +self+ times with each integer in <tt>(0..self-1)</tt>:
- #
- # a = []
- # 5.times {|i| a.push(i) } # => 5
- # a # => [0, 1, 2, 3, 4]
- #
- # With no block given, returns an Enumerator.
- def times
- unless block_given?
- return to_enum(:times) { self < 0 ? 0 : self }
- end
- i = 0
- while i < self
- yield i
- i = i.succ
- end
- self
- end
-
# call-seq:
- # to_i -> self
+ # int.to_i -> integer
+ #
+ # Since +int+ is already an Integer, returns +self+.
#
- # Returns +self+ (which is already an \Integer).
+ # #to_int is an alias for #to_i.
def to_i
self
end
# call-seq:
- # to_int -> self
+ # int.to_int -> integer
#
- # Returns +self+ (which is already an \Integer).
+ # Since +int+ is already an Integer, returns +self+.
def to_int
self
end
# call-seq:
- # zero? -> true or false
+ # int.zero? -> true or false
#
- # Returns +true+ if +self+ has a zero value, +false+ otherwise.
+ # Returns +true+ if +int+ has a zero value.
def zero?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_zero_p(self)'
end
# call-seq:
- # ceildiv(numeric) -> integer
+ # ceildiv(other) -> integer
#
- # Returns the result of division +self+ by +numeric+.
- # rounded up to the nearest integer.
+ # Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer.
#
- # 3.ceildiv(3) # => 1
- # 4.ceildiv(3) # => 2
+ # 3.ceildiv(3) # => 1
+ # 4.ceildiv(3) # => 2
#
- # 4.ceildiv(-3) # => -1
- # -4.ceildiv(3) # => -1
+ # 4.ceildiv(-3) # => -1
+ # -4.ceildiv(3) # => -1
# -4.ceildiv(-3) # => 2
#
# 3.ceildiv(1.2) # => 3
- #
def ceildiv(other)
- -div(0 - other)
+ -div(-other)
end
#
# call-seq:
- # numerator -> self
+ # int.numerator -> self
#
- # Returns +self+.
+ # Returns self.
#
def numerator
self
end
+ #
# call-seq:
- # denominator -> 1
+ # int.denominator -> 1
+ #
+ # Returns 1.
#
- # Returns +1+.
def denominator
1
end
end
-class Float
+# call-seq:
+# Integer.try_convert(object) -> object, integer, or nil
+#
+# If +object+ is an \Integer object, returns +object+.
+# Integer.try_convert(1) # => 1
+#
+# Otherwise if +object+ responds to <tt>:to_int</tt>,
+# calls <tt>object.to_int</tt> and returns the result.
+# Integer.try_convert(1.25) # => 1
+#
+# Returns +nil+ if +object+ does not respond to <tt>:to_int</tt>
+# Integer.try_convert([]) # => nil
+#
+# Raises an exception unless <tt>object.to_int</tt> returns an \Integer object.
+#
+def Integer.try_convert(num)
+=begin
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_check_integer_type(num)'
+=end
+end if false
+class Float
+ #
# call-seq:
- # to_f -> self
+ # float.to_f -> self
+ #
+ # Since +float+ is already a Float, returns +self+.
#
- # Returns +self+ (which is already a \Float).
def to_f
self
end
+ #
# call-seq:
- # float.abs -> float
+ # float.abs -> float
+ # float.magnitude -> float
+ #
+ # Returns the absolute value of +float+.
#
- # Returns the absolute value of +self+:
+ # (-34.56).abs #=> 34.56
+ # -34.56.abs #=> 34.56
+ # 34.56.abs #=> 34.56
#
- # (-34.56).abs # => 34.56
- # -34.56.abs # => 34.56
- # 34.56.abs # => 34.56
+ # Float#magnitude is an alias for Float#abs.
#
def abs
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_float_abs(self)'
end
def magnitude
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_float_abs(self)'
end
+ #
# call-seq:
- # -float -> float
+ # -float -> float
#
- # Returns +self+, negated.
+ # Returns +float+, negated.
#
def -@
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'rb_float_uminus(self)'
end
+ #
# call-seq:
- # zero? -> true or false
+ # float.zero? -> true or false
+ #
+ # Returns +true+ if +float+ is 0.0.
#
- # Returns +true+ if +self+ is 0.0, +false+ otherwise.
def zero?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'RBOOL(FLOAT_ZERO_P(self))'
end
+ #
# call-seq:
- # positive? -> true or false
+ # float.positive? -> true or false
+ #
+ # Returns +true+ if +float+ is greater than 0.
#
- # Returns +true+ if +self+ is greater than 0, +false+ otherwise.
def positive?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) > 0.0)'
end
+ #
# call-seq:
- # negative? -> true or false
+ # float.negative? -> true or false
+ #
+ # Returns +true+ if +float+ is less than 0.
#
- # Returns +true+ if +self+ is less than 0, +false+ otherwise.
def negative?
- Primitive.attr! :leaf
+ Primitive.attr! 'inline'
Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) < 0.0)'
end
diff --git a/object.c b/object.c
index b5decf0c24..e1fc72c89f 100644
--- a/object.c
+++ b/object.c
@@ -42,18 +42,6 @@
#include "builtin.h"
#include "shape.h"
-/* Flags of RObject
- *
- * 1: ROBJECT_EMBED
- * The object has its instance variables embedded (the array of
- * instance variables directly follow the object, rather than being
- * on a separately allocated buffer).
- * if !SHAPE_IN_BASIC_FLAGS
- * 4-19: SHAPE_FLAG_MASK
- * Shape ID for the object.
- * endif
- */
-
/*!
* \addtogroup object
* \{
@@ -92,12 +80,6 @@ static VALUE rb_cFalseClass_to_s;
/*! \endcond */
-size_t
-rb_obj_embedded_size(uint32_t numiv)
-{
- return offsetof(struct RObject, as.ary) + (sizeof(VALUE) * numiv);
-}
-
VALUE
rb_obj_hide(VALUE obj)
{
@@ -125,19 +107,13 @@ rb_obj_setup(VALUE obj, VALUE klass, VALUE type)
return obj;
}
-/*
- * call-seq:
- * true === other -> true or false
- * false === other -> true or false
- * nil === other -> true or false
- *
- * Returns +true+ or +false+.
- *
- * Like Object#==, if +object+ is an instance of Object
- * (and not an instance of one of its many subclasses).
+/**
+ * call-seq:
+ * obj === other -> true or false
*
- * This method is commonly overridden by those subclasses,
- * to provide meaningful semantics in +case+ statements.
+ * Case Equality -- For class Object, effectively the same as calling
+ * <code>#==</code>, but typically overridden by descendants to provide
+ * meaningful semantics in +case+ statements.
*/
#define case_equal rb_equal
/* The default implementation of #=== is
@@ -210,7 +186,7 @@ rb_eql(VALUE obj1, VALUE obj2)
* \private
*++
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
return RBOOL(obj1 == obj2);
@@ -228,7 +204,7 @@ VALUE rb_obj_hash(VALUE obj);
*++
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_not(VALUE obj)
{
return RBOOL(!RTEST(obj));
@@ -244,7 +220,7 @@ rb_obj_not(VALUE obj)
*++
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_not_equal(VALUE obj1, VALUE obj2)
{
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
@@ -291,7 +267,7 @@ rb_obj_singleton_class(VALUE obj)
}
/*! \private */
-void
+MJIT_FUNC_EXPORTED void
rb_obj_copy_ivar(VALUE dest, VALUE obj)
{
RUBY_ASSERT(!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE));
@@ -299,10 +275,13 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
RUBY_ASSERT(BUILTIN_TYPE(dest) == BUILTIN_TYPE(obj));
rb_shape_t * src_shape = rb_shape_get_shape(obj);
- if (rb_shape_obj_too_complex(obj)) {
- // obj is TOO_COMPLEX so we can copy its iv_hash
+ if (rb_shape_id(src_shape) == OBJ_TOO_COMPLEX_SHAPE_ID) {
st_table *table = st_copy(ROBJECT_IV_HASH(obj));
- rb_obj_convert_to_too_complex(dest, table);
+
+ rb_ivar_foreach(obj, rb_obj_evacuate_ivs_to_hash_table, (st_data_t)table);
+ rb_shape_set_too_complex(dest);
+
+ ROBJECT(dest)->as.heap.ivptr = (VALUE *)table;
return;
}
@@ -330,16 +309,9 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
RUBY_ASSERT(initial_shape->type == SHAPE_T_OBJECT);
shape_to_set_on_dest = rb_shape_rebuild_shape(initial_shape, src_shape);
- if (UNLIKELY(rb_shape_id(shape_to_set_on_dest) == OBJ_TOO_COMPLEX_SHAPE_ID)) {
- st_table * table = rb_st_init_numtable_with_size(src_num_ivs);
- rb_obj_copy_ivs_to_hash_table(obj, table);
- rb_obj_convert_to_too_complex(dest, table);
-
- return;
- }
}
- RUBY_ASSERT(src_num_ivs <= shape_to_set_on_dest->capacity || rb_shape_id(shape_to_set_on_dest) == OBJ_TOO_COMPLEX_SHAPE_ID);
+ RUBY_ASSERT(src_num_ivs <= shape_to_set_on_dest->capacity);
if (initial_shape->capacity < shape_to_set_on_dest->capacity) {
rb_ensure_iv_list_size(dest, initial_shape->capacity, shape_to_set_on_dest->capacity);
dest_buf = ROBJECT_IVPTR(dest);
@@ -453,12 +425,15 @@ immutable_obj_clone(VALUE obj, VALUE kwfreeze)
return obj;
}
-VALUE
-rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
+static VALUE
+mutable_obj_clone(VALUE obj, VALUE kwfreeze)
{
+ VALUE clone, singleton;
VALUE argv[2];
- VALUE singleton = rb_singleton_class_clone_and_attach(obj, clone);
+ clone = rb_obj_alloc(rb_obj_class(obj));
+
+ singleton = rb_singleton_class_clone_and_attach(obj, clone);
RBASIC_SET_CLASS(clone, singleton);
if (FL_TEST(singleton, FL_SINGLETON)) {
rb_singleton_class_attached(singleton, clone);
@@ -471,16 +446,11 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
rb_funcall(clone, id_init_clone, 1, obj);
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
if (RB_OBJ_FROZEN(obj)) {
- rb_shape_t * next_shape = rb_shape_transition_shape_frozen(clone);
- if (!rb_shape_obj_too_complex(clone) && next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
- rb_evict_ivars_to_hash(clone);
- }
- else {
- rb_shape_set_shape(clone, next_shape);
- }
+ rb_shape_transition_shape_frozen(clone);
}
break;
- case Qtrue: {
+ case Qtrue:
+ {
static VALUE freeze_true_hash;
if (!freeze_true_hash) {
freeze_true_hash = rb_hash_new();
@@ -493,18 +463,11 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
argv[1] = freeze_true_hash;
rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
RBASIC(clone)->flags |= FL_FREEZE;
- rb_shape_t * next_shape = rb_shape_transition_shape_frozen(clone);
- // If we're out of shapes, but we want to freeze, then we need to
- // evacuate this clone to a hash
- if (!rb_shape_obj_too_complex(clone) && next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
- rb_evict_ivars_to_hash(clone);
- }
- else {
- rb_shape_set_shape(clone, next_shape);
- }
+ rb_shape_transition_shape_frozen(clone);
break;
- }
- case Qfalse: {
+ }
+ case Qfalse:
+ {
static VALUE freeze_false_hash;
if (!freeze_false_hash) {
freeze_false_hash = rb_hash_new();
@@ -517,7 +480,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
argv[1] = freeze_false_hash;
rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
break;
- }
+ }
default:
rb_bug("invalid kwfreeze passed to mutable_obj_clone");
}
@@ -525,13 +488,6 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
return clone;
}
-static VALUE
-mutable_obj_clone(VALUE obj, VALUE kwfreeze)
-{
- VALUE clone = rb_obj_alloc(rb_obj_class(obj));
- return rb_obj_clone_setup(obj, clone, kwfreeze);
-}
-
VALUE
rb_obj_clone(VALUE obj)
{
@@ -539,15 +495,6 @@ rb_obj_clone(VALUE obj)
return mutable_obj_clone(obj, Qnil);
}
-VALUE
-rb_obj_dup_setup(VALUE obj, VALUE dup)
-{
- init_copy(dup, obj);
- rb_funcall(dup, id_init_dup, 1, obj);
-
- return dup;
-}
-
/*
* call-seq:
* obj.dup -> an_object
@@ -596,7 +543,10 @@ rb_obj_dup(VALUE obj)
return obj;
}
dup = rb_obj_alloc(rb_obj_class(obj));
- return rb_obj_dup_setup(obj, dup);
+ init_copy(dup, obj);
+ rb_funcall(dup, id_init_dup, 1, obj);
+
+ return dup;
}
/*
@@ -622,6 +572,12 @@ rb_obj_size(VALUE self, VALUE args, VALUE obj)
return LONG2FIX(1);
}
+static VALUE
+block_given_p(rb_execution_context_t *ec, VALUE self)
+{
+ return RBOOL(rb_block_given_p());
+}
+
/**
* :nodoc:
*--
@@ -718,8 +674,10 @@ rb_inspect(VALUE obj)
}
static int
-inspect_i(ID id, VALUE value, st_data_t a)
+inspect_i(st_data_t k, st_data_t v, st_data_t a)
{
+ ID id = (ID)k;
+ VALUE value = (VALUE)v;
VALUE str = (VALUE)a;
/* need not to show internal data */
@@ -1302,47 +1260,17 @@ rb_obj_frozen_p(VALUE obj)
/*
* Document-class: NilClass
*
- * The class of the singleton object +nil+.
- *
- * Several of its methods act as operators:
- *
- * - #&
- * - #|
- * - #===
- * - #=~
- * - #^
- *
- * Others act as converters, carrying the concept of _nullity_
- * to other classes:
- *
- * - #rationalize
- * - #to_a
- * - #to_c
- * - #to_h
- * - #to_r
- * - #to_s
- *
- * Another method provides inspection:
- *
- * - #inspect
- *
- * Finally, there is this query method:
- *
- * - #nil?
- *
+ * The class of the singleton object <code>nil</code>.
*/
/*
- * call-seq:
- * to_s -> ''
- *
- * Returns an empty String:
- *
- * nil.to_s # => ""
+ * call-seq:
+ * nil.to_s -> ""
*
+ * Always returns the empty string.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_nil_to_s(VALUE obj)
{
return rb_cNilClass_to_s;
@@ -1351,13 +1279,12 @@ rb_nil_to_s(VALUE obj)
/*
* Document-method: to_a
*
- * call-seq:
- * to_a -> []
- *
- * Returns an empty Array.
+ * call-seq:
+ * nil.to_a -> []
*
- * nil.to_a # => []
+ * Always returns an empty array.
*
+ * nil.to_a #=> []
*/
static VALUE
@@ -1369,13 +1296,12 @@ nil_to_a(VALUE obj)
/*
* Document-method: to_h
*
- * call-seq:
- * to_h -> {}
- *
- * Returns an empty Hash.
+ * call-seq:
+ * nil.to_h -> {}
*
- * nil.to_h #=> {}
+ * Always returns an empty hash.
*
+ * nil.to_h #=> {}
*/
static VALUE
@@ -1385,13 +1311,10 @@ nil_to_h(VALUE obj)
}
/*
- * call-seq:
- * inspect -> 'nil'
- *
- * Returns string <tt>'nil'</tt>:
- *
- * nil.inspect # => "nil"
+ * call-seq:
+ * nil.inspect -> "nil"
*
+ * Always returns the string "nil".
*/
static VALUE
@@ -1401,17 +1324,12 @@ nil_inspect(VALUE obj)
}
/*
- * call-seq:
- * nil =~ object -> nil
- *
- * Returns +nil+.
- *
- * This method makes it useful to write:
+ * call-seq:
+ * nil =~ other -> nil
*
- * while gets =~ /re/
- * # ...
- * end
+ * Dummy pattern matching -- always returns nil.
*
+ * This method makes it possible to `while gets =~ /re/ do`.
*/
static VALUE
@@ -1420,38 +1338,24 @@ nil_match(VALUE obj1, VALUE obj2)
return Qnil;
}
-/*
+/***********************************************************************
* Document-class: TrueClass
*
- * The class of the singleton object +true+.
- *
- * Several of its methods act as operators:
- *
- * - #&
- * - #|
- * - #===
- * - #^
- *
- * One other method:
- *
- * - #to_s and its alias #inspect.
- *
+ * The global value <code>true</code> is the only instance of class
+ * TrueClass and represents a logically true value in
+ * boolean expressions. The class provides operators allowing
+ * <code>true</code> to be used in logical expressions.
*/
/*
* call-seq:
- * true.to_s -> 'true'
- *
- * Returns string <tt>'true'</tt>:
- *
- * true.to_s # => "true"
- *
- * TrueClass#inspect is an alias for TrueClass#to_s.
+ * true.to_s -> "true"
*
+ * The string representation of <code>true</code> is "true".
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_true_to_s(VALUE obj)
{
return rb_cTrueClass_to_s;
@@ -1460,14 +1364,10 @@ rb_true_to_s(VALUE obj)
/*
* call-seq:
- * true & object -> true or false
- *
- * Returns +false+ if +object+ is +false+ or +nil+, +true+ otherwise:
- *
- * true & Object.new # => true
- * true & false # => false
- * true & nil # => false
+ * true & obj -> true or false
*
+ * And---Returns <code>false</code> if <i>obj</i> is
+ * <code>nil</code> or <code>false</code>, <code>true</code> otherwise.
*/
static VALUE
@@ -1478,21 +1378,18 @@ true_and(VALUE obj, VALUE obj2)
/*
* call-seq:
- * true | object -> true
+ * true | obj -> true
*
- * Returns +true+:
+ * Or---Returns <code>true</code>. As <i>obj</i> is an argument to
+ * a method call, it is always evaluated; there is no short-circuit
+ * evaluation in this case.
*
- * true | Object.new # => true
- * true | false # => true
- * true | nil # => true
+ * true | puts("or")
+ * true || puts("logical or")
*
- * Argument +object+ is evaluated.
- * This is different from +true+ with the short-circuit operator,
- * whose operand is evaluated only if necessary:
- *
- * true | raise # => Raises RuntimeError.
- * true || raise # => true
+ * <em>produces:</em>
*
+ * or
*/
static VALUE
@@ -1504,14 +1401,11 @@ true_or(VALUE obj, VALUE obj2)
/*
* call-seq:
- * true ^ object -> !object
- *
- * Returns +true+ if +object+ is +false+ or +nil+, +false+ otherwise:
- *
- * true ^ Object.new # => false
- * true ^ false # => true
- * true ^ nil # => true
+ * true ^ obj -> !obj
*
+ * Exclusive Or---Returns <code>true</code> if <i>obj</i> is
+ * <code>nil</code> or <code>false</code>, <code>false</code>
+ * otherwise.
*/
static VALUE
@@ -1538,27 +1432,22 @@ true_xor(VALUE obj, VALUE obj2)
* The string representation of <code>false</code> is "false".
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_false_to_s(VALUE obj)
{
return rb_cFalseClass_to_s;
}
/*
- * call-seq:
- * false & object -> false
- * nil & object -> false
- *
- * Returns +false+:
- *
- * false & true # => false
- * false & Object.new # => false
- *
- * Argument +object+ is evaluated:
- *
- * false & raise # Raises RuntimeError.
+ * call-seq:
+ * false & obj -> false
+ * nil & obj -> false
*
+ * And---Returns <code>false</code>. <i>obj</i> is always
+ * evaluated as it is the argument to a method call---there is no
+ * short-circuit evaluation in this case.
*/
+
static VALUE
false_and(VALUE obj, VALUE obj2)
{
@@ -1567,30 +1456,24 @@ false_and(VALUE obj, VALUE obj2)
/*
- * call-seq:
- * false | object -> true or false
- * nil | object -> true or false
- *
- * Returns +false+ if +object+ is +nil+ or +false+, +true+ otherwise:
- *
- * nil | nil # => false
- * nil | false # => false
- * nil | Object.new # => true
+ * call-seq:
+ * false | obj -> true or false
+ * nil | obj -> true or false
*
+ * Or---Returns <code>false</code> if <i>obj</i> is
+ * <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
*/
#define false_or true_and
/*
- * call-seq:
- * false ^ object -> true or false
- * nil ^ object -> true or false
- *
- * Returns +false+ if +object+ is +nil+ or +false+, +true+ otherwise:
+ * call-seq:
+ * false ^ obj -> true or false
+ * nil ^ obj -> true or false
*
- * nil ^ nil # => false
- * nil ^ false # => false
- * nil ^ Object.new # => true
+ * Exclusive Or---If <i>obj</i> is <code>nil</code> or
+ * <code>false</code>, returns <code>false</code>; otherwise, returns
+ * <code>true</code>.
*
*/
@@ -1598,10 +1481,9 @@ false_and(VALUE obj, VALUE obj2)
/*
* call-seq:
- * nil.nil? -> true
+ * nil.nil? -> true
*
- * Returns +true+.
- * For all other objects, method <tt>nil?</tt> returns +false+.
+ * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
*/
static VALUE
@@ -1621,7 +1503,7 @@ rb_true(VALUE obj)
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_false(VALUE obj)
{
return Qfalse;
@@ -1706,7 +1588,7 @@ rb_obj_cmp(VALUE obj1, VALUE obj2)
* show information on the thing we're attached to as well.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_mod_to_s(VALUE klass)
{
ID id_defined_at;
@@ -1714,7 +1596,7 @@ rb_mod_to_s(VALUE klass)
if (FL_TEST(klass, FL_SINGLETON)) {
VALUE s = rb_usascii_str_new2("#<Class:");
- VALUE v = RCLASS_ATTACHED_OBJECT(klass);
+ VALUE v = rb_ivar_get(klass, id__attached__);
if (CLASS_OR_MODULE_P(v)) {
rb_str_append(s, rb_inspect(v));
@@ -3180,7 +3062,7 @@ rb_check_convert_type(VALUE val, int type, const char *tname, const char *method
}
/*! \private */
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
{
VALUE v;
@@ -3345,17 +3227,121 @@ rb_opts_exception_p(VALUE opts, int default_value)
return default_value;
}
-static VALUE
-rb_f_integer1(rb_execution_context_t *ec, VALUE obj, VALUE arg)
-{
- return rb_convert_to_integer(arg, 0, TRUE);
-}
+#define opts_exception_p(opts) rb_opts_exception_p((opts), TRUE)
+
+/*
+ * call-seq:
+ * Integer(object, base = 0, exception: true) -> integer or nil
+ *
+ * Returns an integer converted from +object+.
+ *
+ * Tries to convert +object+ to an integer
+ * using +to_int+ first and +to_i+ second;
+ * see below for exceptions.
+ *
+ * With a non-zero +base+, +object+ must be a string or convertible
+ * to a string.
+ *
+ * ==== numeric objects
+ *
+ * With integer argument +object+ given, returns +object+:
+ *
+ * Integer(1) # => 1
+ * Integer(-1) # => -1
+ *
+ * With floating-point argument +object+ given,
+ * returns +object+ truncated to an intger:
+ *
+ * Integer(1.9) # => 1 # Rounds toward zero.
+ * Integer(-1.9) # => -1 # Rounds toward zero.
+ *
+ * ==== string objects
+ *
+ * With string argument +object+ and zero +base+ given,
+ * returns +object+ converted to an integer in base 10:
+ *
+ * Integer('100') # => 100
+ * Integer('-100') # => -100
+ *
+ * With +base+ zero, string +object+ may contain leading characters
+ * to specify the actual base (radix indicator):
+ *
+ * Integer('0100') # => 64 # Leading '0' specifies base 8.
+ * Integer('0b100') # => 4 # Leading '0b', specifies base 2.
+ * Integer('0x100') # => 256 # Leading '0x' specifies base 16.
+ *
+ * With a positive +base+ (in range 2..36) given, returns +object+
+ * converted to an integer in the given base:
+ *
+ * Integer('100', 2) # => 4
+ * Integer('100', 8) # => 64
+ * Integer('-100', 16) # => -256
+ *
+ * With a negative +base+ (in range -36..-2) given, returns +object+
+ * converted to an integer in the radix indicator if exists or
+ * +-base+:
+ *
+ * Integer('0x100', -2) # => 256
+ * Integer('100', -2) # => 4
+ * Integer('0b100', -8) # => 4
+ * Integer('100', -8) # => 64
+ * Integer('0o100', -10) # => 64
+ * Integer('100', -10) # => 100
+ *
+ * +base+ -1 is equal the -10 case.
+ *
+ * When converting strings, surrounding whitespace and embedded underscores
+ * are allowed and ignored:
+ *
+ * Integer(' 100 ') # => 100
+ * Integer('-1_0_0', 16) # => -256
+ *
+ * ==== other classes
+ *
+ * Examples with +object+ of various other classes:
+ *
+ * Integer(Rational(9, 10)) # => 0 # Rounds toward zero.
+ * Integer(Complex(2, 0)) # => 2 # Imaginary part must be zero.
+ * Integer(Time.now) # => 1650974042
+ *
+ * ==== keywords
+ *
+ * With optional keyword argument +exception+ given as +true+ (the default):
+ *
+ * - Raises TypeError if +object+ does not respond to +to_int+ or +to_i+.
+ * - Raises TypeError if +object+ is +nil+.
+ * - Raise ArgumentError if +object+ is an invalid string.
+ *
+ * With +exception+ given as +false+, an exception of any kind is suppressed
+ * and +nil+ is returned.
+ *
+ */
static VALUE
-rb_f_integer(rb_execution_context_t *ec, VALUE obj, VALUE arg, VALUE base, VALUE exception)
+rb_f_integer(int argc, VALUE *argv, VALUE obj)
{
- int exc = rb_bool_expected(exception, "exception", TRUE);
- return rb_convert_to_integer(arg, NUM2INT(base), exc);
+ VALUE arg = Qnil, opts = Qnil;
+ int base = 0;
+
+ if (argc > 1) {
+ int narg = 1;
+ VALUE vbase = rb_check_to_int(argv[1]);
+ if (!NIL_P(vbase)) {
+ base = NUM2INT(vbase);
+ narg = 2;
+ }
+ if (argc > narg) {
+ VALUE hash = rb_check_hash_type(argv[argc-1]);
+ if (!NIL_P(hash)) {
+ opts = rb_extract_keywords(&hash);
+ if (!hash) --argc;
+ }
+ }
+ }
+ rb_check_arity(argc, 1, 2);
+ arg = argv[0];
+
+ return rb_convert_to_integer(arg, base, opts_exception_p(opts));
}
static double
@@ -3489,6 +3475,7 @@ rb_str_to_dbl_raise(VALUE str, int badcheck, int raise, int *error)
VALUE v = 0;
StringValue(str);
+ rb_must_asciicompat(str);
s = RSTRING_PTR(str);
len = RSTRING_LEN(str);
if (s) {
@@ -3948,6 +3935,9 @@ rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound)
*
* For details on +format_string+, see
* {Format Specifications}[rdoc-ref:format_specifications.rdoc].
+ *
+ * Kernel#format is an alias for Kernel#sprintf.
+ *
*/
static VALUE
@@ -4173,7 +4163,7 @@ f_sprintf(int c, const VALUE *v, VALUE _)
* and frozen state.
* - #define_singleton_method: Defines a singleton method in +self+
* for the given symbol method-name and block or proc.
- * - #display: Prints +self+ to the given IO stream or <tt>$stdout</tt>.
+ * - #display: Prints +self+ to the given \IO stream or <tt>$stdout</tt>.
* - #dup: Returns a shallow unfrozen copy of +self+.
* - #enum_for (aliased as #to_enum): Returns an Enumerator for +self+
* using the using the given method, arguments, and block.
@@ -4189,6 +4179,27 @@ f_sprintf(int c, const VALUE *v, VALUE _)
*
*/
+/*!
+ *--
+ * \private
+ * Initializes the world of objects and classes.
+ *
+ * At first, the function bootstraps the class hierarchy.
+ * It initializes the most fundamental classes and their metaclasses.
+ * - \c BasicObject
+ * - \c Object
+ * - \c Module
+ * - \c Class
+ * After the bootstrap step, the class hierarchy becomes as the following
+ * diagram.
+ *
+ * \image html boottime-classes.png
+ *
+ * Then, the function defines classes, modules and methods as usual.
+ * \ingroup class
+ *++
+ */
+
void
InitVM_Object(void)
{
@@ -4404,6 +4415,8 @@ InitVM_Object(void)
rb_define_global_function("sprintf", f_sprintf, -1);
rb_define_global_function("format", f_sprintf, -1);
+ rb_define_global_function("Integer", rb_f_integer, -1);
+
rb_define_global_function("String", rb_f_string, 1);
rb_define_global_function("Array", rb_f_array, 1);
rb_define_global_function("Hash", rb_f_hash, 1);
@@ -4439,7 +4452,6 @@ InitVM_Object(void)
rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); /* in class.c */
rb_define_method(rb_cModule, "include?", rb_mod_include_p, 1); /* in class.c */
rb_define_method(rb_cModule, "name", rb_mod_name, 0); /* in variable.c */
- rb_define_method(rb_cModule, "set_temporary_name", rb_mod_set_temporary_name, 1); /* in variable.c */
rb_define_method(rb_cModule, "ancestors", rb_mod_ancestors, 0); /* in class.c */
rb_define_method(rb_cModule, "attr", rb_mod_attr, -1);
diff --git a/pack.c b/pack.c
index 4fdaf7fd89..3bdae01362 100644
--- a/pack.c
+++ b/pack.c
@@ -36,11 +36,10 @@
*/
#ifdef HAVE_TRUE_LONG_LONG
static const char natstr[] = "sSiIlLqQjJ";
-# define endstr natstr
#else
static const char natstr[] = "sSiIlLjJ";
-static const char endstr[] = "sSiIlLqQjJ";
#endif
+static const char endstr[] = "sSiIlLqQjJ";
#ifdef HAVE_TRUE_LONG_LONG
/* It is intentional to use long long instead of LONG_LONG. */
@@ -155,7 +154,6 @@ associated_pointer(VALUE associates, const char *t)
UNREACHABLE_RETURN(Qnil);
}
-RBIMPL_ATTR_NORETURN()
static void
unknown_directive(const char *mode, char type, VALUE fmt)
{
@@ -169,7 +167,7 @@ unknown_directive(const char *mode, char type, VALUE fmt)
snprintf(unknown, sizeof(unknown), "\\x%.2x", type & 0xff);
}
fmt = rb_str_quote_unprintable(fmt);
- rb_raise(rb_eArgError, "unknown %s directive '%s' in '%"PRIsVALUE"'",
+ rb_warn("unknown %s directive '%s' in '%"PRIsVALUE"'",
mode, unknown, fmt);
}
@@ -538,7 +536,7 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
bigendian_p = explicit_endian == '>';
}
if (integer_size > MAX_INTEGER_PACK_SIZE)
- rb_bug("unexpected integer size for pack: %d", integer_size);
+ rb_bug("unexpected intger size for pack: %d", integer_size);
while (len-- > 0) {
char intbuf[MAX_INTEGER_PACK_SIZE];
diff --git a/parse.y b/parse.y
index 3eadb0bdf5..1c808bd60e 100644
--- a/parse.y
+++ b/parse.y
@@ -22,29 +22,13 @@
#define YYLTYPE rb_code_location_t
#define YYLTYPE_IS_DECLARED 1
-/* For Ripper */
-#ifdef RUBY_EXTCONF_H
-# include RUBY_EXTCONF_H
-#endif
-
#include "ruby/internal/config.h"
+#include <ctype.h>
#include <errno.h>
+#include <stdio.h>
-#ifdef UNIVERSAL_PARSER
-
-#include "internal/ruby_parser.h"
-#include "parser_node.h"
-#include "universal_parser.c"
-
-#ifdef RIPPER
-#undef T_NODE
-#define T_NODE 0x1b
-#define STATIC_ID2SYM p->config->static_id2sym
-#define rb_str_coderange_scan_restartable p->config->str_coderange_scan_restartable
-#endif
-
-#else
+struct lex_context;
#include "internal.h"
#include "internal/compile.h"
@@ -59,12 +43,10 @@
#include "internal/parse.h"
#include "internal/rational.h"
#include "internal/re.h"
-#include "internal/ruby_parser.h"
#include "internal/symbol.h"
#include "internal/thread.h"
#include "internal/variable.h"
#include "node.h"
-#include "parser_node.h"
#include "probes.h"
#include "regenc.h"
#include "ruby/encoding.h"
@@ -75,177 +57,6 @@
#include "ruby/ractor.h"
#include "symbol.h"
-#ifndef RIPPER
-static void
-bignum_negate(VALUE b)
-{
- BIGNUM_NEGATE(b);
-}
-
-static void
-rational_set_num(VALUE r, VALUE n)
-{
- RATIONAL_SET_NUM(r, n);
-}
-
-static VALUE
-rational_get_num(VALUE obj)
-{
- return RRATIONAL(obj)->num;
-}
-
-static void
-rcomplex_set_real(VALUE cmp, VALUE r)
-{
- RCOMPLEX_SET_REAL(cmp, r);
-}
-
-static VALUE
-rcomplex_get_real(VALUE obj)
-{
- return RCOMPLEX(obj)->real;
-}
-
-static void
-rcomplex_set_imag(VALUE cmp, VALUE i)
-{
- RCOMPLEX_SET_IMAG(cmp, i);
-}
-
-static VALUE
-rcomplex_get_imag(VALUE obj)
-{
- return RCOMPLEX(obj)->imag;
-}
-
-static bool
-hash_literal_key_p(VALUE k)
-{
- switch (OBJ_BUILTIN_TYPE(k)) {
- case T_NODE:
- return false;
- default:
- return true;
- }
-}
-
-static int
-literal_cmp(VALUE val, VALUE lit)
-{
- if (val == lit) return 0;
- if (!hash_literal_key_p(val) || !hash_literal_key_p(lit)) return -1;
- return rb_iseq_cdhash_cmp(val, lit);
-}
-
-static st_index_t
-literal_hash(VALUE a)
-{
- if (!hash_literal_key_p(a)) return (st_index_t)a;
- return rb_iseq_cdhash_hash(a);
-}
-
-static VALUE
-syntax_error_new(void)
-{
- return rb_class_new_instance(0, 0, rb_eSyntaxError);
-}
-
-static NODE *reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc);
-#endif /* !RIPPER */
-
-#define compile_callback rb_suppress_tracing
-VALUE rb_io_gets_internal(VALUE io);
-
-VALUE rb_node_case_when_optimizable_literal(const NODE *const node);
-#endif /* !UNIVERSAL_PARSER */
-
-static inline int
-parse_isascii(int c)
-{
- return '\0' <= c && c <= '\x7f';
-}
-
-#undef ISASCII
-#define ISASCII parse_isascii
-
-static inline int
-parse_isspace(int c)
-{
- return c == ' ' || ('\t' <= c && c <= '\r');
-}
-
-#undef ISSPACE
-#define ISSPACE parse_isspace
-
-static inline int
-parse_iscntrl(int c)
-{
- return ('\0' <= c && c < ' ') || c == '\x7f';
-}
-
-#undef ISCNTRL
-#define ISCNTRL(c) parse_iscntrl(c)
-
-static inline int
-parse_isupper(int c)
-{
- return 'A' <= c && c <= 'Z';
-}
-
-static inline int
-parse_islower(int c)
-{
- return 'a' <= c && c <= 'z';
-}
-
-static inline int
-parse_isalpha(int c)
-{
- return parse_isupper(c) || parse_islower(c);
-}
-
-#undef ISALPHA
-#define ISALPHA(c) parse_isalpha(c)
-
-static inline int
-parse_isdigit(int c)
-{
- return '0' <= c && c <= '9';
-}
-
-#undef ISDIGIT
-#define ISDIGIT(c) parse_isdigit(c)
-
-static inline int
-parse_isalnum(int c)
-{
- return parse_isalpha(c) || parse_isdigit(c);
-}
-
-#undef ISALNUM
-#define ISALNUM(c) parse_isalnum(c)
-
-static inline int
-parse_isxdigit(int c)
-{
- return parse_isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
-}
-
-#undef ISXDIGIT
-#define ISXDIGIT(c) parse_isxdigit(c)
-
-#include "parser_st.h"
-
-#undef STRCASECMP
-#define STRCASECMP rb_parser_st_locale_insensitive_strcasecmp
-
-#undef STRNCASECMP
-#define STRNCASECMP rb_parser_st_locale_insensitive_strncasecmp
-
-#ifdef RIPPER
-#include "ripper_init.h"
-#endif
-
enum shareability {
shareable_none,
shareable_literal,
@@ -253,13 +64,6 @@ enum shareability {
shareable_everything,
};
-enum rescue_context {
- before_rescue,
- after_rescue,
- after_else,
- after_ensure,
-};
-
struct lex_context {
unsigned int in_defined: 1;
unsigned int in_kwarg: 1;
@@ -267,12 +71,8 @@ struct lex_context {
unsigned int in_def: 1;
unsigned int in_class: 1;
BITFIELD(enum shareability, shareable_constant_value, 2);
- BITFIELD(enum rescue_context, in_rescue, 2);
};
-typedef struct RNode_DEF_TEMP rb_node_def_temp_t;
-typedef struct RNode_EXITS rb_node_exits_t;
-
#if defined(__GNUC__) && !defined(__clang__)
// Suppress "parameter passing for argument of type 'struct
// lex_context' changed" notes. `struct lex_context` is file scope,
@@ -301,18 +101,18 @@ RBIMPL_WARNING_POP()
#define YYREALLOC(ptr, size) rb_parser_realloc(p, (ptr), (size))
#define YYCALLOC(nelem, size) rb_parser_calloc(p, (nelem), (size))
#define YYFREE(ptr) rb_parser_free(p, (ptr))
-#define YYFPRINTF(out, ...) rb_parser_printf(p, __VA_ARGS__)
-#define YY_LOCATION_PRINT(File, loc, p) \
+#define YYFPRINTF rb_parser_printf
+#define YY_LOCATION_PRINT(File, loc) \
rb_parser_printf(p, "%d.%d-%d.%d", \
- (loc).beg_pos.lineno, (loc).beg_pos.column,\
- (loc).end_pos.lineno, (loc).end_pos.column)
+ (loc).beg_pos.lineno, (loc).beg_pos.column,\
+ (loc).end_pos.lineno, (loc).end_pos.column)
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
if (N) \
- { \
- (Current).beg_pos = YYRHSLOC(Rhs, 1).beg_pos; \
- (Current).end_pos = YYRHSLOC(Rhs, N).end_pos; \
- } \
+ { \
+ (Current).beg_pos = YYRHSLOC(Rhs, 1).beg_pos; \
+ (Current).end_pos = YYRHSLOC(Rhs, N).end_pos; \
+ } \
else \
{ \
(Current).beg_pos = YYRHSLOC(Rhs, 0).end_pos; \
@@ -337,10 +137,48 @@ RBIMPL_WARNING_POP()
rb_parser_set_location(p, &(Current))
#define RUBY_INIT_YYLLOC() \
{ \
- {p->ruby_sourceline, (int)(p->lex.ptok - p->lex.pbeg)}, \
- {p->ruby_sourceline, (int)(p->lex.pcur - p->lex.pbeg)}, \
- }
-
+ {p->ruby_sourceline, (int)(p->lex.ptok - p->lex.pbeg)}, \
+ {p->ruby_sourceline, (int)(p->lex.pcur - p->lex.pbeg)}, \
+ }
+
+enum lex_state_bits {
+ EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
+ EXPR_END_bit, /* newline significant, +/- is an operator. */
+ EXPR_ENDARG_bit, /* ditto, and unbound braces. */
+ EXPR_ENDFN_bit, /* ditto, and unbound braces. */
+ EXPR_ARG_bit, /* newline significant, +/- is an operator. */
+ EXPR_CMDARG_bit, /* newline significant, +/- is an operator. */
+ EXPR_MID_bit, /* newline significant, +/- is an operator. */
+ EXPR_FNAME_bit, /* ignore newline, no reserved words. */
+ EXPR_DOT_bit, /* right after `.' or `::', no reserved words. */
+ EXPR_CLASS_bit, /* immediate after `class', no here document. */
+ EXPR_LABEL_bit, /* flag bit, label is allowed. */
+ EXPR_LABELED_bit, /* flag bit, just after a label. */
+ EXPR_FITEM_bit, /* symbol literal as FNAME. */
+ EXPR_MAX_STATE
+};
+/* examine combinations */
+enum lex_state_e {
+#define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
+ DEF_EXPR(BEG),
+ DEF_EXPR(END),
+ DEF_EXPR(ENDARG),
+ DEF_EXPR(ENDFN),
+ DEF_EXPR(ARG),
+ DEF_EXPR(CMDARG),
+ DEF_EXPR(MID),
+ DEF_EXPR(FNAME),
+ DEF_EXPR(DOT),
+ DEF_EXPR(CLASS),
+ DEF_EXPR(LABEL),
+ DEF_EXPR(LABELED),
+ DEF_EXPR(FITEM),
+ EXPR_VALUE = EXPR_BEG,
+ EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS),
+ EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
+ EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN),
+ EXPR_NONE = 0
+};
#define IS_lex_state_for(x, ls) ((x) & (ls))
#define IS_lex_state_all_for(x, ls) (((x) & (ls)) == (ls))
#define IS_lex_state(ls) IS_lex_state_for(p->lex.state, (ls))
@@ -391,7 +229,7 @@ struct local_vars {
struct local_vars *prev;
# ifndef RIPPER
struct {
- NODE *outer, *inner, *current;
+ NODE *outer, *inner, *current;
} numparam;
# endif
};
@@ -402,6 +240,18 @@ enum {
NUMPARAM_MAX = 9,
};
+#define NUMPARAM_ID_P(id) numparam_id_p(id)
+#define NUMPARAM_ID_TO_IDX(id) (unsigned int)(((id) >> ID_SCOPE_SHIFT) - (tNUMPARAM_1 - 1))
+#define NUMPARAM_IDX_TO_ID(idx) TOKEN2LOCALID((tNUMPARAM_1 - 1 + (idx)))
+static int
+numparam_id_p(ID id)
+{
+ if (!is_local_id(id) || id < (tNUMPARAM_1 << ID_SCOPE_SHIFT)) return 0;
+ unsigned int idx = NUMPARAM_ID_TO_IDX(id);
+ return idx > 0 && idx <= NUMPARAM_MAX;
+}
+static void numparam_name(struct parser_params *p, ID id);
+
#define DVARS_INHERIT ((void*)1)
#define DVARS_TOPSCOPE NULL
#define DVARS_TERMINAL_P(tbl) ((tbl) == DVARS_INHERIT || (tbl) == DVARS_TOPSCOPE)
@@ -414,6 +264,8 @@ typedef struct token_info {
struct token_info *next;
} token_info;
+typedef struct rb_strterm_struct rb_strterm_t;
+
/*
Structure of Lexer Buffer:
@@ -430,31 +282,32 @@ struct parser_params {
YYLTYPE *yylloc;
struct {
- rb_strterm_t *strterm;
- VALUE (*gets)(struct parser_params*,VALUE);
- VALUE input;
- VALUE lastline;
- VALUE nextline;
- const char *pbeg;
- const char *pcur;
- const char *pend;
- const char *ptok;
- union {
- long ptr;
- VALUE (*call)(VALUE, int);
- } gets_;
- enum lex_state_e state;
- /* track the nest level of any parens "()[]{}" */
- int paren_nest;
- /* keep p->lex.paren_nest at the beginning of lambda "->" to detect tLAMBEG and keyword_do_LAMBDA */
- int lpar_beg;
- /* track the nest level of only braces "{}" */
- int brace_nest;
+ rb_strterm_t *strterm;
+ VALUE (*gets)(struct parser_params*,VALUE);
+ VALUE input;
+ VALUE lastline;
+ VALUE nextline;
+ const char *pbeg;
+ const char *pcur;
+ const char *pend;
+ const char *ptok;
+ union {
+ long ptr;
+ VALUE (*call)(VALUE, int);
+ } gets_;
+ enum lex_state_e state;
+ /* track the nest level of any parens "()[]{}" */
+ int paren_nest;
+ /* keep p->lex.paren_nest at the beginning of lambda "->" to detect tLAMBEG and keyword_do_LAMBDA */
+ int lpar_beg;
+ /* track the nest level of only braces "{}" */
+ int brace_nest;
} lex;
stack_type cond_stack;
stack_type cmdarg_stack;
int tokidx;
int toksiz;
+ int tokline;
int heredoc_end;
int heredoc_indent;
int heredoc_line_indent;
@@ -469,17 +322,17 @@ struct parser_params {
rb_encoding *enc;
token_info *token_info;
VALUE case_labels;
- rb_node_exits_t *exits;
+ VALUE compile_option;
VALUE debug_buffer;
VALUE debug_output;
struct {
- VALUE token;
- int beg_line;
- int beg_col;
- int end_line;
- int end_col;
+ VALUE token;
+ int beg_line;
+ int beg_col;
+ int end_line;
+ int end_col;
} delayed;
ID cur_arg;
@@ -491,12 +344,6 @@ struct parser_params {
struct lex_context ctxt;
-#ifdef UNIVERSAL_PARSER
- rb_parser_config_t *config;
-#endif
- /* compile_option */
- signed int frozen_string_literal:2; /* -1: not specified, 0: false, 1: true */
-
unsigned int command_start:1;
unsigned int eofp: 1;
unsigned int ruby__end__seen: 1;
@@ -517,6 +364,7 @@ struct parser_params {
unsigned int do_loop: 1;
unsigned int do_chomp: 1;
unsigned int do_split: 1;
+ unsigned int keep_script_lines: 1;
unsigned int error_tolerant: 1;
unsigned int keep_tokens: 1;
@@ -540,32 +388,20 @@ struct parser_params {
#endif
};
-#define NUMPARAM_ID_P(id) numparam_id_p(p, id)
-#define NUMPARAM_ID_TO_IDX(id) (unsigned int)(((id) >> ID_SCOPE_SHIFT) - (tNUMPARAM_1 - 1))
-#define NUMPARAM_IDX_TO_ID(idx) TOKEN2LOCALID((tNUMPARAM_1 - 1 + (idx)))
-static int
-numparam_id_p(struct parser_params *p, ID id)
-{
- if (!is_local_id(id) || id < (tNUMPARAM_1 << ID_SCOPE_SHIFT)) return 0;
- unsigned int idx = NUMPARAM_ID_TO_IDX(id);
- return idx > 0 && idx <= NUMPARAM_MAX;
-}
-static void numparam_name(struct parser_params *p, ID id);
-
-
#define intern_cstr(n,l,en) rb_intern3(n,l,en)
#define STR_NEW(ptr,len) rb_enc_str_new((ptr),(len),p->enc)
#define STR_NEW0() rb_enc_str_new(0,0,p->enc)
#define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),p->enc)
-#define STR_NEW3(ptr,len,e,func) parser_str_new(p, (ptr),(len),(e),(func),p->enc)
+#define STR_NEW3(ptr,len,e,func) parser_str_new((ptr),(len),(e),(func),p->enc)
#define TOK_INTERN() intern_cstr(tok(p), toklen(p), p->enc)
-#define VALID_SYMNAME_P(s, l, enc, type) (rb_enc_symname_type(s, l, enc, (1U<<(type))) == (int)(type))
-static inline bool
-end_with_newline_p(struct parser_params *p, VALUE str)
+static st_table *
+push_pvtbl(struct parser_params *p)
{
- return RSTRING_LEN(str) > 0 && RSTRING_END(str)[-1] == '\n';
+ st_table *tbl = p->pvtbl;
+ p->pvtbl = st_init_numtable();
+ return tbl;
}
static void
@@ -575,6 +411,14 @@ pop_pvtbl(struct parser_params *p, st_table *tbl)
p->pvtbl = tbl;
}
+static st_table *
+push_pktbl(struct parser_params *p)
+{
+ st_table *tbl = p->pktbl;
+ p->pktbl = 0;
+ return tbl;
+}
+
static void
pop_pktbl(struct parser_params *p, st_table *tbl)
{
@@ -619,7 +463,7 @@ peek_end_expect_token_locations(struct parser_params *p)
}
static ID
-parser_token2id(struct parser_params *p, enum yytokentype tok)
+parser_token2id(enum yytokentype tok)
{
switch ((int) tok) {
#define TOKEN2ID(tok) case tok: return rb_intern(#tok);
@@ -651,7 +495,6 @@ parser_token2id(struct parser_params *p, enum yytokentype tok)
TOKEN2ID2(']', "]");
TOKEN2ID2('(', "(");
TOKEN2ID2(')', ")");
- TOKEN2ID2('\\', "backslash");
TOKEN2ID(keyword_class);
TOKEN2ID(keyword_module);
TOKEN2ID(keyword_def);
@@ -800,10 +643,8 @@ static int parser_yyerror0(struct parser_params*, const char*);
#define yyerror(yylloc, p, msg) parser_yyerror(p, yylloc, msg)
#define token_flush(ptr) ((ptr)->lex.ptok = (ptr)->lex.pcur)
#define lex_goto_eol(p) ((p)->lex.pcur = (p)->lex.pend)
-#define lex_eol_p(p) lex_eol_n_p(p, 0)
-#define lex_eol_n_p(p,n) lex_eol_ptr_n_p(p, (p)->lex.pcur, n)
-#define lex_eol_ptr_p(p,ptr) lex_eol_ptr_n_p(p,ptr,0)
-#define lex_eol_ptr_n_p(p,ptr,n) ((ptr)+(n) >= (p)->lex.pend)
+#define lex_eol_p(p) ((p)->lex.pcur >= (p)->lex.pend)
+#define lex_eol_n_p(p,n) ((p)->lex.pcur+(n) >= (p)->lex.pend)
static void token_info_setup(token_info *ptinfo, const char *ptr, const rb_code_location_t *loc);
static void token_info_push(struct parser_params*, const char *token, const rb_code_location_t *loc);
@@ -820,7 +661,8 @@ static void token_info_drop(struct parser_params *p, const char *token, rb_code_
#define token_column ((int)(p->lex.ptok - p->lex.pbeg))
#define CALL_Q_P(q) ((q) == TOKEN2VAL(tANDDOT))
-#define NEW_QCALL(q,r,m,a,loc) (CALL_Q_P(q) ? NEW_QCALL0(r,m,a,loc) : NEW_CALL(r,m,a,loc))
+#define NODE_CALL_Q(q) (CALL_Q_P(q) ? NODE_QCALL : NODE_CALL)
+#define NEW_QCALL(q,r,m,a,loc) NEW_NODE(NODE_CALL_Q(q),r,m,a,loc)
#define lambda_beginning_p() (p->lex.lpar_beg == p->lex.paren_nest)
@@ -839,282 +681,23 @@ static inline VALUE
add_mark_object(struct parser_params *p, VALUE obj)
{
if (!SPECIAL_CONST_P(obj)
- && !RB_TYPE_P(obj, T_NODE) /* Ripper jumbles NODE objects and other objects... */
+ && !RB_TYPE_P(obj, T_NODE) /* Ripper jumbles NODE objects and other objects... */
) {
- rb_ast_add_mark_object(p->ast, obj);
+ rb_ast_add_mark_object(p->ast, obj);
}
return obj;
}
-
-static rb_node_ripper_t *rb_node_ripper_new(struct parser_params *p, ID a, VALUE b, VALUE c, const YYLTYPE *loc);
-static rb_node_ripper_values_t *rb_node_ripper_values_new(struct parser_params *p, VALUE a, VALUE b, VALUE c, const YYLTYPE *loc);
-#define NEW_RIPPER(a,b,c,loc) (VALUE)rb_node_ripper_new(p,a,b,c,loc)
-#define NEW_RIPPER_VALUES(a,b,c,loc) (VALUE)rb_node_ripper_values_new(p,a,b,c,loc)
-
#else
-static rb_node_scope_t *rb_node_scope_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_scope_t *rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_block_t *rb_node_block_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_if_t *rb_node_if_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, NODE *nd_else, const YYLTYPE *loc);
-static rb_node_unless_t *rb_node_unless_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, NODE *nd_else, const YYLTYPE *loc);
-static rb_node_case_t *rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_case2_t *rb_node_case2_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_case3_t *rb_node_case3_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_when_t *rb_node_when_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_next, const YYLTYPE *loc);
-static rb_node_in_t *rb_node_in_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_next, const YYLTYPE *loc);
-static rb_node_while_t *rb_node_while_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc);
-static rb_node_until_t *rb_node_until_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc);
-static rb_node_iter_t *rb_node_iter_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_for_t *rb_node_for_new(struct parser_params *p, NODE *nd_iter, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_for_masgn_t *rb_node_for_masgn_new(struct parser_params *p, NODE *nd_var, const YYLTYPE *loc);
-static rb_node_retry_t *rb_node_retry_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_begin_t *rb_node_begin_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_rescue_t *rb_node_rescue_new(struct parser_params *p, NODE *nd_head, NODE *nd_resq, NODE *nd_else, const YYLTYPE *loc);
-static rb_node_resbody_t *rb_node_resbody_new(struct parser_params *p, NODE *nd_args, NODE *nd_body, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_ensure_t *rb_node_ensure_new(struct parser_params *p, NODE *nd_head, NODE *nd_ensr, const YYLTYPE *loc);
-static rb_node_and_t *rb_node_and_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc);
-static rb_node_or_t *rb_node_or_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc);
-static rb_node_masgn_t *rb_node_masgn_new(struct parser_params *p, NODE *nd_head, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_lasgn_t *rb_node_lasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_dasgn_t *rb_node_dasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_gasgn_t *rb_node_gasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_iasgn_t *rb_node_iasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_cdecl_t *rb_node_cdecl_new(struct parser_params *p, ID nd_vid, NODE *nd_value, NODE *nd_else, const YYLTYPE *loc);
-static rb_node_cvasgn_t *rb_node_cvasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_op_asgn1_t *rb_node_op_asgn1_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *index, NODE *rvalue, const YYLTYPE *loc);
-static rb_node_op_asgn2_t *rb_node_op_asgn2_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, ID nd_vid, ID nd_mid, bool nd_aid, const YYLTYPE *loc);
-static rb_node_op_asgn_or_t *rb_node_op_asgn_or_new(struct parser_params *p, NODE *nd_head, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_op_asgn_and_t *rb_node_op_asgn_and_new(struct parser_params *p, NODE *nd_head, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_op_cdecl_t *rb_node_op_cdecl_new(struct parser_params *p, NODE *nd_head, NODE *nd_value, ID nd_aid, const YYLTYPE *loc);
-static rb_node_call_t *rb_node_call_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_opcall_t *rb_node_opcall_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_fcall_t *rb_node_fcall_new(struct parser_params *p, ID nd_mid, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_vcall_t *rb_node_vcall_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc);
-static rb_node_qcall_t *rb_node_qcall_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_super_t *rb_node_super_new(struct parser_params *p, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_zsuper_t * rb_node_zsuper_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_list_t *rb_node_list_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_list_t *rb_node_list_new2(struct parser_params *p, NODE *nd_head, long nd_alen, NODE *nd_next, const YYLTYPE *loc);
-static rb_node_zlist_t *rb_node_zlist_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_hash_t *rb_node_hash_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_return_t *rb_node_return_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc);
-static rb_node_yield_t *rb_node_yield_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_lvar_t *rb_node_lvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc);
-static rb_node_dvar_t *rb_node_dvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc);
-static rb_node_gvar_t *rb_node_gvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc);
-static rb_node_ivar_t *rb_node_ivar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc);
-static rb_node_const_t *rb_node_const_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc);
-static rb_node_cvar_t *rb_node_cvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc);
-static rb_node_nth_ref_t *rb_node_nth_ref_new(struct parser_params *p, long nd_nth, const YYLTYPE *loc);
-static rb_node_back_ref_t *rb_node_back_ref_new(struct parser_params *p, long nd_nth, const YYLTYPE *loc);
-static rb_node_match2_t *rb_node_match2_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_match3_t *rb_node_match3_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, const YYLTYPE *loc);
-static rb_node_lit_t *rb_node_lit_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
-static rb_node_str_t *rb_node_str_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
-static rb_node_dstr_t *rb_node_dstr_new0(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc);
-static rb_node_dstr_t *rb_node_dstr_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
-static rb_node_xstr_t *rb_node_xstr_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
-static rb_node_dxstr_t *rb_node_dxstr_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc);
-static rb_node_evstr_t *rb_node_evstr_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_once_t *rb_node_once_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_args_t *rb_node_args_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_args_aux_t *rb_node_args_aux_new(struct parser_params *p, ID nd_pid, long nd_plen, const YYLTYPE *loc);
-static rb_node_opt_arg_t *rb_node_opt_arg_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_kw_arg_t *rb_node_kw_arg_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_postarg_t *rb_node_postarg_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc);
-static rb_node_argscat_t *rb_node_argscat_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_argspush_t *rb_node_argspush_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_splat_t *rb_node_splat_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_block_pass_t *rb_node_block_pass_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_defn_t *rb_node_defn_new(struct parser_params *p, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc);
-static rb_node_defs_t *rb_node_defs_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc);
-static rb_node_alias_t *rb_node_alias_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc);
-static rb_node_valias_t *rb_node_valias_new(struct parser_params *p, ID nd_alias, ID nd_orig, const YYLTYPE *loc);
-static rb_node_undef_t *rb_node_undef_new(struct parser_params *p, NODE *nd_undef, const YYLTYPE *loc);
-static rb_node_class_t *rb_node_class_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, NODE *nd_super, const YYLTYPE *loc);
-static rb_node_module_t *rb_node_module_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_sclass_t *rb_node_sclass_new(struct parser_params *p, NODE *nd_recv, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_colon2_t *rb_node_colon2_new(struct parser_params *p, NODE *nd_head, ID nd_mid, const YYLTYPE *loc);
-static rb_node_colon3_t *rb_node_colon3_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc);
-static rb_node_dot2_t *rb_node_dot2_new(struct parser_params *p, NODE *nd_beg, NODE *nd_end, const YYLTYPE *loc);
-static rb_node_dot3_t *rb_node_dot3_new(struct parser_params *p, NODE *nd_beg, NODE *nd_end, const YYLTYPE *loc);
-static rb_node_self_t *rb_node_self_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_nil_t *rb_node_nil_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_true_t *rb_node_true_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_false_t *rb_node_false_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_errinfo_t *rb_node_errinfo_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_defined_t *rb_node_defined_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
-static rb_node_postexe_t *rb_node_postexe_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_dsym_t *rb_node_dsym_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc);
-static rb_node_attrasgn_t *rb_node_attrasgn_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc);
-static rb_node_lambda_t *rb_node_lambda_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
-static rb_node_aryptn_t *rb_node_aryptn_new(struct parser_params *p, NODE *pre_args, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc);
-static rb_node_hshptn_t *rb_node_hshptn_new(struct parser_params *p, NODE *nd_pconst, NODE *nd_pkwargs, NODE *nd_pkwrestarg, const YYLTYPE *loc);
-static rb_node_fndptn_t *rb_node_fndptn_new(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc);
-static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE *loc);
-
-#define NEW_SCOPE(a,b,loc) (NODE *)rb_node_scope_new(p,a,b,loc)
-#define NEW_SCOPE2(t,a,b,loc) (NODE *)rb_node_scope_new2(p,t,a,b,loc)
-#define NEW_BLOCK(a,loc) (NODE *)rb_node_block_new(p,a,loc)
-#define NEW_IF(c,t,e,loc) (NODE *)rb_node_if_new(p,c,t,e,loc)
-#define NEW_UNLESS(c,t,e,loc) (NODE *)rb_node_unless_new(p,c,t,e,loc)
-#define NEW_CASE(h,b,loc) (NODE *)rb_node_case_new(p,h,b,loc)
-#define NEW_CASE2(b,loc) (NODE *)rb_node_case2_new(p,b,loc)
-#define NEW_CASE3(h,b,loc) (NODE *)rb_node_case3_new(p,h,b,loc)
-#define NEW_WHEN(c,t,e,loc) (NODE *)rb_node_when_new(p,c,t,e,loc)
-#define NEW_IN(c,t,e,loc) (NODE *)rb_node_in_new(p,c,t,e,loc)
-#define NEW_WHILE(c,b,n,loc) (NODE *)rb_node_while_new(p,c,b,n,loc)
-#define NEW_UNTIL(c,b,n,loc) (NODE *)rb_node_until_new(p,c,b,n,loc)
-#define NEW_ITER(a,b,loc) (NODE *)rb_node_iter_new(p,a,b,loc)
-#define NEW_FOR(i,b,loc) (NODE *)rb_node_for_new(p,i,b,loc)
-#define NEW_FOR_MASGN(v,loc) (NODE *)rb_node_for_masgn_new(p,v,loc)
-#define NEW_RETRY(loc) (NODE *)rb_node_retry_new(p,loc)
-#define NEW_BEGIN(b,loc) (NODE *)rb_node_begin_new(p,b,loc)
-#define NEW_RESCUE(b,res,e,loc) (NODE *)rb_node_rescue_new(p,b,res,e,loc)
-#define NEW_RESBODY(a,ex,n,loc) (NODE *)rb_node_resbody_new(p,a,ex,n,loc)
-#define NEW_ENSURE(b,en,loc) (NODE *)rb_node_ensure_new(p,b,en,loc)
-#define NEW_AND(f,s,loc) (NODE *)rb_node_and_new(p,f,s,loc)
-#define NEW_OR(f,s,loc) (NODE *)rb_node_or_new(p,f,s,loc)
-#define NEW_MASGN(l,r,loc) rb_node_masgn_new(p,l,r,loc)
-#define NEW_LASGN(v,val,loc) (NODE *)rb_node_lasgn_new(p,v,val,loc)
-#define NEW_DASGN(v,val,loc) (NODE *)rb_node_dasgn_new(p,v,val,loc)
-#define NEW_GASGN(v,val,loc) (NODE *)rb_node_gasgn_new(p,v,val,loc)
-#define NEW_IASGN(v,val,loc) (NODE *)rb_node_iasgn_new(p,v,val,loc)
-#define NEW_CDECL(v,val,path,loc) (NODE *)rb_node_cdecl_new(p,v,val,path,loc)
-#define NEW_CVASGN(v,val,loc) (NODE *)rb_node_cvasgn_new(p,v,val,loc)
-#define NEW_OP_ASGN1(r,id,idx,rval,loc) (NODE *)rb_node_op_asgn1_new(p,r,id,idx,rval,loc)
-#define NEW_OP_ASGN2(r,t,i,o,val,loc) (NODE *)rb_node_op_asgn2_new(p,r,val,i,o,t,loc)
-#define NEW_OP_ASGN_OR(i,val,loc) (NODE *)rb_node_op_asgn_or_new(p,i,val,loc)
-#define NEW_OP_ASGN_AND(i,val,loc) (NODE *)rb_node_op_asgn_and_new(p,i,val,loc)
-#define NEW_OP_CDECL(v,op,val,loc) (NODE *)rb_node_op_cdecl_new(p,v,val,op,loc)
-#define NEW_CALL(r,m,a,loc) (NODE *)rb_node_call_new(p,r,m,a,loc)
-#define NEW_OPCALL(r,m,a,loc) (NODE *)rb_node_opcall_new(p,r,m,a,loc)
-#define NEW_FCALL(m,a,loc) rb_node_fcall_new(p,m,a,loc)
-#define NEW_VCALL(m,loc) (NODE *)rb_node_vcall_new(p,m,loc)
-#define NEW_QCALL0(r,m,a,loc) (NODE *)rb_node_qcall_new(p,r,m,a,loc)
-#define NEW_SUPER(a,loc) (NODE *)rb_node_super_new(p,a,loc)
-#define NEW_ZSUPER(loc) (NODE *)rb_node_zsuper_new(p,loc)
-#define NEW_LIST(a,loc) (NODE *)rb_node_list_new(p,a,loc)
-#define NEW_LIST2(h,l,n,loc) (NODE *)rb_node_list_new2(p,h,l,n,loc)
-#define NEW_ZLIST(loc) (NODE *)rb_node_zlist_new(p,loc)
-#define NEW_HASH(a,loc) (NODE *)rb_node_hash_new(p,a,loc)
-#define NEW_RETURN(s,loc) (NODE *)rb_node_return_new(p,s,loc)
-#define NEW_YIELD(a,loc) (NODE *)rb_node_yield_new(p,a,loc)
-#define NEW_LVAR(v,loc) (NODE *)rb_node_lvar_new(p,v,loc)
-#define NEW_DVAR(v,loc) (NODE *)rb_node_dvar_new(p,v,loc)
-#define NEW_GVAR(v,loc) (NODE *)rb_node_gvar_new(p,v,loc)
-#define NEW_IVAR(v,loc) (NODE *)rb_node_ivar_new(p,v,loc)
-#define NEW_CONST(v,loc) (NODE *)rb_node_const_new(p,v,loc)
-#define NEW_CVAR(v,loc) (NODE *)rb_node_cvar_new(p,v,loc)
-#define NEW_NTH_REF(n,loc) (NODE *)rb_node_nth_ref_new(p,n,loc)
-#define NEW_BACK_REF(n,loc) (NODE *)rb_node_back_ref_new(p,n,loc)
-#define NEW_MATCH2(n1,n2,loc) (NODE *)rb_node_match2_new(p,n1,n2,loc)
-#define NEW_MATCH3(r,n2,loc) (NODE *)rb_node_match3_new(p,r,n2,loc)
-#define NEW_LIT(l,loc) (NODE *)rb_node_lit_new(p,l,loc)
-#define NEW_STR(s,loc) (NODE *)rb_node_str_new(p,s,loc)
-#define NEW_DSTR0(s,l,n,loc) (NODE *)rb_node_dstr_new0(p,s,l,n,loc)
-#define NEW_DSTR(s,loc) (NODE *)rb_node_dstr_new(p,s,loc)
-#define NEW_XSTR(s,loc) (NODE *)rb_node_xstr_new(p,s,loc)
-#define NEW_DXSTR(s,l,n,loc) (NODE *)rb_node_dxstr_new(p,s,l,n,loc)
-#define NEW_EVSTR(n,loc) (NODE *)rb_node_evstr_new(p,n,loc)
-#define NEW_ONCE(b,loc) (NODE *)rb_node_once_new(p,b,loc)
-#define NEW_ARGS(loc) rb_node_args_new(p,loc)
-#define NEW_ARGS_AUX(r,b,loc) rb_node_args_aux_new(p,r,b,loc)
-#define NEW_OPT_ARG(v,loc) rb_node_opt_arg_new(p,v,loc)
-#define NEW_KW_ARG(v,loc) rb_node_kw_arg_new(p,v,loc)
-#define NEW_POSTARG(i,v,loc) (NODE *)rb_node_postarg_new(p,i,v,loc)
-#define NEW_ARGSCAT(a,b,loc) (NODE *)rb_node_argscat_new(p,a,b,loc)
-#define NEW_ARGSPUSH(a,b,loc) (NODE *)rb_node_argspush_new(p,a,b,loc)
-#define NEW_SPLAT(a,loc) (NODE *)rb_node_splat_new(p,a,loc)
-#define NEW_BLOCK_PASS(b,loc) rb_node_block_pass_new(p,b,loc)
-#define NEW_DEFN(i,s,loc) (NODE *)rb_node_defn_new(p,i,s,loc)
-#define NEW_DEFS(r,i,s,loc) (NODE *)rb_node_defs_new(p,r,i,s,loc)
-#define NEW_ALIAS(n,o,loc) (NODE *)rb_node_alias_new(p,n,o,loc)
-#define NEW_VALIAS(n,o,loc) (NODE *)rb_node_valias_new(p,n,o,loc)
-#define NEW_UNDEF(i,loc) (NODE *)rb_node_undef_new(p,i,loc)
-#define NEW_CLASS(n,b,s,loc) (NODE *)rb_node_class_new(p,n,b,s,loc)
-#define NEW_MODULE(n,b,loc) (NODE *)rb_node_module_new(p,n,b,loc)
-#define NEW_SCLASS(r,b,loc) (NODE *)rb_node_sclass_new(p,r,b,loc)
-#define NEW_COLON2(c,i,loc) (NODE *)rb_node_colon2_new(p,c,i,loc)
-#define NEW_COLON3(i,loc) (NODE *)rb_node_colon3_new(p,i,loc)
-#define NEW_DOT2(b,e,loc) (NODE *)rb_node_dot2_new(p,b,e,loc)
-#define NEW_DOT3(b,e,loc) (NODE *)rb_node_dot3_new(p,b,e,loc)
-#define NEW_SELF(loc) (NODE *)rb_node_self_new(p,loc)
-#define NEW_NIL(loc) (NODE *)rb_node_nil_new(p,loc)
-#define NEW_TRUE(loc) (NODE *)rb_node_true_new(p,loc)
-#define NEW_FALSE(loc) (NODE *)rb_node_false_new(p,loc)
-#define NEW_ERRINFO(loc) (NODE *)rb_node_errinfo_new(p,loc)
-#define NEW_DEFINED(e,loc) (NODE *)rb_node_defined_new(p,e,loc)
-#define NEW_POSTEXE(b,loc) (NODE *)rb_node_postexe_new(p,b,loc)
-#define NEW_DSYM(s,l,n,loc) (NODE *)rb_node_dsym_new(p,s,l,n,loc)
-#define NEW_ATTRASGN(r,m,a,loc) (NODE *)rb_node_attrasgn_new(p,r,m,a,loc)
-#define NEW_LAMBDA(a,b,loc) (NODE *)rb_node_lambda_new(p,a,b,loc)
-#define NEW_ARYPTN(pre,r,post,loc) (NODE *)rb_node_aryptn_new(p,pre,r,post,loc)
-#define NEW_HSHPTN(c,kw,kwrest,loc) (NODE *)rb_node_hshptn_new(p,c,kw,kwrest,loc)
-#define NEW_FNDPTN(pre,a,post,loc) (NODE *)rb_node_fndptn_new(p,pre,a,post,loc)
-#define NEW_ERROR(loc) (NODE *)rb_node_error_new(p,loc)
-
+static NODE* node_newnode_with_locals(struct parser_params *, enum node_type, VALUE, VALUE, const rb_code_location_t*);
#endif
-enum internal_node_type {
- NODE_INTERNAL_ONLY = NODE_LAST,
- NODE_DEF_TEMP,
- NODE_EXITS,
- NODE_INTERNAL_LAST
-};
-
-static const char *
-parser_node_name(int node)
-{
- switch (node) {
- case NODE_DEF_TEMP:
- return "NODE_DEF_TEMP";
- case NODE_EXITS:
- return "NODE_EXITS";
- default:
- return ruby_node_name(node);
- }
-}
-
-/* This node is parse.y internal */
-struct RNode_DEF_TEMP {
- NODE node;
+static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE, const rb_code_location_t*);
+#define rb_node_newnode(type, a1, a2, a3, loc) node_newnode(p, (type), (a1), (a2), (a3), (loc))
- /* for NODE_DEFN/NODE_DEFS */
-#ifndef RIPPER
- struct RNode *nd_def;
- ID nd_mid;
-#else
- VALUE nd_recv;
- VALUE nd_mid;
- VALUE dot_or_colon;
-#endif
-
- struct {
- ID cur_arg;
- int max_numparam;
- NODE *numparam_save;
- struct lex_context ctxt;
- } save;
-};
-
-#define RNODE_DEF_TEMP(node) ((struct RNode_DEF_TEMP *)(node))
-
-static rb_node_break_t *rb_node_break_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc);
-static rb_node_next_t *rb_node_next_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc);
-static rb_node_redo_t *rb_node_redo_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_def_temp_t *rb_node_def_temp_new(struct parser_params *p, const YYLTYPE *loc);
-static rb_node_def_temp_t *def_head_save(struct parser_params *p, rb_node_def_temp_t *n);
-
-#define NEW_BREAK(s,loc) (NODE *)rb_node_break_new(p,s,loc)
-#define NEW_NEXT(s,loc) (NODE *)rb_node_next_new(p,s,loc)
-#define NEW_REDO(loc) (NODE *)rb_node_redo_new(p,loc)
-#define NEW_DEF_TEMP(loc) rb_node_def_temp_new(p,loc)
-
-/* Make a new internal node, which should not be appeared in the
+/* Make a new temporal node, which should not be appeared in the
* result AST and does not have node_id and location. */
-static NODE* node_new_internal(struct parser_params *p, enum node_type type, size_t size, size_t alignment);
-#define NODE_NEW_INTERNAL(ndtype, type) (type *)node_new_internal(p, (enum node_type)(ndtype), sizeof(type), RUBY_ALIGNOF(type))
+static NODE* node_new_temporal(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2);
+#define NODE_NEW_TEMPORAL(t,a0,a1,a2) node_new_temporal(p, (t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
static NODE *nd_set_loc(NODE *nd, const YYLTYPE *loc);
@@ -1126,14 +709,6 @@ parser_get_node_id(struct parser_params *p)
return node_id;
}
-static void
-anddot_multiple_assignment_check(struct parser_params* p, const YYLTYPE *loc, ID id)
-{
- if (id == tANDDOT) {
- yyerror1(loc, "&. inside multiple assignment destination");
- }
-}
-
#ifndef RIPPER
static inline void
set_line_body(NODE *body, int line)
@@ -1142,34 +717,10 @@ set_line_body(NODE *body, int line)
switch (nd_type(body)) {
case NODE_RESCUE:
case NODE_ENSURE:
- nd_set_line(body, line);
+ nd_set_line(body, line);
}
}
-static void
-set_embraced_location(NODE *node, const rb_code_location_t *beg, const rb_code_location_t *end)
-{
- RNODE_ITER(node)->nd_body->nd_loc = code_loc_gen(beg, end);
- nd_set_line(node, beg->end_pos.lineno);
-}
-
-static NODE *
-last_expr_node(NODE *expr)
-{
- while (expr) {
- if (nd_type_p(expr, NODE_BLOCK)) {
- expr = RNODE_BLOCK(RNODE_BLOCK(expr)->nd_end)->nd_head;
- }
- else if (nd_type_p(expr, NODE_BEGIN)) {
- expr = RNODE_BEGIN(expr)->nd_body;
- }
- else {
- break;
- }
- }
- return expr;
-}
-
#define yyparse ruby_yyparse
static NODE* cond(struct parser_params *p, NODE *node, const YYLTYPE *loc);
@@ -1186,6 +737,7 @@ static void fixpos(NODE*,NODE*);
static int value_expr_gen(struct parser_params*,NODE*);
static void void_expr(struct parser_params*,NODE*);
static NODE *remove_begin(NODE*);
+static NODE *remove_begin_all(NODE*);
#define value_expr(node) value_expr_gen(p, (node))
static NODE *void_stmts(struct parser_params*,NODE*);
static void reduce_nodes(struct parser_params*,NODE**);
@@ -1200,7 +752,6 @@ static NODE *rest_arg_append(struct parser_params *p, NODE *args, NODE *rest_arg
static NODE *literal_concat(struct parser_params*,NODE*,NODE*,const YYLTYPE*);
static NODE *new_evstr(struct parser_params*,NODE*,const YYLTYPE*);
static NODE *new_dstr(struct parser_params*,NODE*,const YYLTYPE*);
-static NODE *str2dstr(struct parser_params*,NODE*);
static NODE *evstr2dstr(struct parser_params*,NODE*);
static NODE *splat_array(NODE*);
static void mark_lvar_used(struct parser_params *p, NODE *rhs);
@@ -1209,24 +760,24 @@ static NODE *call_bin_op(struct parser_params*,NODE*,ID,NODE*,const YYLTYPE*,con
static NODE *call_uni_op(struct parser_params*,NODE*,ID,const YYLTYPE*,const YYLTYPE*);
static NODE *new_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, const YYLTYPE *op_loc, const YYLTYPE *loc);
static NODE *new_command_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, NODE *block, const YYLTYPE *op_loc, const YYLTYPE *loc);
-static NODE *method_add_block(struct parser_params*p, NODE *m, NODE *b, const YYLTYPE *loc) {RNODE_ITER(b)->nd_iter = m; b->nd_loc = *loc; return b;}
+static NODE *method_add_block(struct parser_params*p, NODE *m, NODE *b, const YYLTYPE *loc) {b->nd_iter = m; b->nd_loc = *loc; return b;}
static bool args_info_empty_p(struct rb_args_info *args);
-static rb_node_args_t *new_args(struct parser_params*,rb_node_args_aux_t*,rb_node_opt_arg_t*,ID,rb_node_args_aux_t*,rb_node_args_t*,const YYLTYPE*);
-static rb_node_args_t *new_args_tail(struct parser_params*,rb_node_kw_arg_t*,ID,ID,const YYLTYPE*);
+static NODE *new_args(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYLTYPE*);
+static NODE *new_args_tail(struct parser_params*,NODE*,ID,ID,const YYLTYPE*);
static NODE *new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *aryptn, const YYLTYPE *loc);
-static NODE *new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc);
+static NODE *new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID rest_arg, NODE *post_args, const YYLTYPE *loc);
static NODE *new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YYLTYPE *loc);
-static NODE *new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc);
+static NODE *new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc);
static NODE *new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc);
static NODE *new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, const YYLTYPE *loc);
-static rb_node_kw_arg_t *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc);
-static rb_node_args_t *args_with_numbered(struct parser_params*,rb_node_args_t*,int);
+static NODE *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc);
+static NODE *args_with_numbered(struct parser_params*,NODE*,int);
static VALUE negate_lit(struct parser_params*, VALUE);
static NODE *ret_args(struct parser_params*,NODE*);
-static NODE *arg_blk_pass(NODE*,rb_node_block_pass_t*);
+static NODE *arg_blk_pass(NODE*,NODE*);
static NODE *new_yield(struct parser_params*,NODE*,const YYLTYPE*);
static NODE *dsym_node(struct parser_params*,NODE*,const YYLTYPE*);
@@ -1247,8 +798,8 @@ static NODE *new_bodystmt(struct parser_params *p, NODE *head, NODE *rescue, NOD
static NODE *const_decl(struct parser_params *p, NODE* path, const YYLTYPE *loc);
-static rb_node_opt_arg_t *opt_arg_append(rb_node_opt_arg_t*, rb_node_opt_arg_t*);
-static rb_node_kw_arg_t *kwd_append(rb_node_kw_arg_t*, rb_node_kw_arg_t*);
+static NODE *opt_arg_append(NODE*, NODE*);
+static NODE *kwd_append(NODE*, NODE*);
static NODE *new_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc);
static NODE *new_unique_key_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc);
@@ -1270,6 +821,7 @@ static rb_ast_id_table_t *local_tbl(struct parser_params*);
static VALUE reg_compile(struct parser_params*, VALUE, int);
static void reg_fragment_setenc(struct parser_params*, VALUE, int);
static int reg_fragment_check(struct parser_params*, VALUE, int);
+static NODE *reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc);
static int literal_concat0(struct parser_params *p, VALUE head, VALUE tail);
static NODE *heredoc_dedent(struct parser_params*,NODE*);
@@ -1280,29 +832,22 @@ static void check_literal_when(struct parser_params *p, NODE *args, const YYLTYP
#define get_value(val) (val)
#define get_num(num) (num)
#else /* RIPPER */
+#define NODE_RIPPER NODE_CDECL
+#define NEW_RIPPER(a,b,c,loc) (VALUE)NEW_CDECL(a,b,c,loc)
-static inline int ripper_is_node_yylval(struct parser_params *p, VALUE n);
+static inline int ripper_is_node_yylval(VALUE n);
static inline VALUE
ripper_new_yylval(struct parser_params *p, ID a, VALUE b, VALUE c)
{
- if (ripper_is_node_yylval(p, c)) c = RNODE_RIPPER(c)->nd_cval;
+ if (ripper_is_node_yylval(c)) c = RNODE(c)->nd_cval;
add_mark_object(p, b);
add_mark_object(p, c);
return NEW_RIPPER(a, b, c, &NULL_LOC);
}
-static inline VALUE
-ripper_new_yylval2(struct parser_params *p, VALUE a, VALUE b, VALUE c)
-{
- add_mark_object(p, a);
- add_mark_object(p, b);
- add_mark_object(p, c);
- return NEW_RIPPER_VALUES(a, b, c, &NULL_LOC);
-}
-
static inline int
-ripper_is_node_yylval(struct parser_params *p, VALUE n)
+ripper_is_node_yylval(VALUE n)
{
return RB_TYPE_P(n, T_NODE) && nd_type_p(RNODE(n), NODE_RIPPER);
}
@@ -1310,11 +855,11 @@ ripper_is_node_yylval(struct parser_params *p, VALUE n)
#define value_expr(node) ((void)(node))
#define remove_begin(node) (node)
#define void_stmts(p,x) (x)
-#undef rb_dvar_defined
#define rb_dvar_defined(id, base) 0
-#undef rb_local_defined
#define rb_local_defined(id, base) 0
+static ID ripper_get_id(VALUE);
#define get_id(id) ripper_get_id(id)
+static VALUE ripper_get_value(VALUE);
#define get_value(val) ripper_get_value(val)
#define get_num(num) (int)get_id(num)
static VALUE assignable(struct parser_params*,VALUE);
@@ -1340,11 +885,14 @@ static VALUE parser_reg_compile(struct parser_params*, VALUE, int, VALUE *);
static VALUE backref_error(struct parser_params*, NODE *, VALUE);
#endif /* !RIPPER */
+/* forward declaration */
+typedef struct rb_strterm_heredoc_struct rb_strterm_heredoc_t;
+
RUBY_SYMBOL_EXPORT_BEGIN
VALUE rb_parser_reg_compile(struct parser_params* p, VALUE str, int options);
int rb_reg_fragment_setenc(struct parser_params*, VALUE, int);
enum lex_state_e rb_parser_trace_lex_state(struct parser_params *, enum lex_state_e, enum lex_state_e, int);
-VALUE rb_parser_lex_state_name(struct parser_params *p, enum lex_state_e state);
+VALUE rb_parser_lex_state_name(enum lex_state_e state);
void rb_parser_show_bitstack(struct parser_params *, stack_type, const char *, int);
PRINTF_ARGS(void rb_parser_fatal(struct parser_params *p, const char *fmt, ...), 2, 3);
YYLTYPE *rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_heredoc_t *here, YYLTYPE *yylloc);
@@ -1377,7 +925,6 @@ static NODE *new_args_forward_call(struct parser_params*, NODE*, const YYLTYPE*,
#endif
static int check_forwarding_args(struct parser_params*);
static void add_forwarding_args(struct parser_params *p);
-static void forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var);
static const struct vtable *dyna_push(struct parser_params *);
static void dyna_pop(struct parser_params*, const struct vtable *);
@@ -1402,11 +949,6 @@ static void numparam_pop(struct parser_params *p, NODE *prev_inner);
#define idFWD_KWREST idPow /* Use simple "**", as tDSTAR is "**arg" */
#define idFWD_BLOCK '&'
#define idFWD_ALL idDot3
-#ifdef RIPPER
-#define arg_FWD_BLOCK Qnone
-#else
-#define arg_FWD_BLOCK idFWD_BLOCK
-#endif
#define FORWARD_ARGS_WITH_RUBY2_KEYWORDS
#define RE_OPTION_ONCE (1<<16)
@@ -1417,6 +959,72 @@ static void numparam_pop(struct parser_params *p, NODE *prev_inner);
#define RE_OPTION_MASK 0xff
#define RE_OPTION_ARG_ENCODING_NONE 32
+/* structs for managing terminator of string literal and heredocment */
+typedef struct rb_strterm_literal_struct {
+ union {
+ VALUE dummy;
+ long nest;
+ } u0;
+ union {
+ VALUE dummy;
+ long func; /* STR_FUNC_* (e.g., STR_FUNC_ESCAPE and STR_FUNC_EXPAND) */
+ } u1;
+ union {
+ VALUE dummy;
+ long paren; /* '(' of `%q(...)` */
+ } u2;
+ union {
+ VALUE dummy;
+ long term; /* ')' of `%q(...)` */
+ } u3;
+} rb_strterm_literal_t;
+
+#define HERETERM_LENGTH_BITS ((SIZEOF_VALUE - 1) * CHAR_BIT - 1)
+
+struct rb_strterm_heredoc_struct {
+ VALUE lastline; /* the string of line that contains `<<"END"` */
+ long offset; /* the column of END in `<<"END"` */
+ int sourceline; /* lineno of the line that contains `<<"END"` */
+ unsigned length /* the length of END in `<<"END"` */
+#if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
+ : HERETERM_LENGTH_BITS
+# define HERETERM_LENGTH_MAX ((1U << HERETERM_LENGTH_BITS) - 1)
+#else
+# define HERETERM_LENGTH_MAX UINT_MAX
+#endif
+ ;
+#if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
+ unsigned quote: 1;
+ unsigned func: 8;
+#else
+ uint8_t quote;
+ uint8_t func;
+#endif
+};
+STATIC_ASSERT(rb_strterm_heredoc_t, sizeof(rb_strterm_heredoc_t) <= 4 * SIZEOF_VALUE);
+
+#define STRTERM_HEREDOC IMEMO_FL_USER0
+
+struct rb_strterm_struct {
+ VALUE flags;
+ union {
+ rb_strterm_literal_t literal;
+ rb_strterm_heredoc_t heredoc;
+ } u;
+};
+
+#ifndef RIPPER
+void
+rb_strterm_mark(VALUE obj)
+{
+ rb_strterm_t *strterm = (rb_strterm_t*)obj;
+ if (RBASIC(obj)->flags & STRTERM_HEREDOC) {
+ rb_strterm_heredoc_t *heredoc = &strterm->u.heredoc;
+ rb_gc_mark(heredoc->lastline);
+ }
+}
+#endif
+
#define yytnamerr(yyres, yystr) (YYSIZE_T)rb_yytnamerr(p, yyres, yystr)
size_t rb_yytnamerr(struct parser_params *p, char *yyres, const char *yystr);
@@ -1432,11 +1040,12 @@ size_t rb_yytnamerr(struct parser_params *p, char *yyres, const char *yystr);
/****** Ripper *******/
#ifdef RIPPER
+#define RIPPER_VERSION "0.1.0"
-#include "eventids1.h"
-#include "eventids2.h"
+static inline VALUE intern_sym(const char *name);
-extern const struct ripper_parser_ids ripper_parser_ids;
+#include "eventids1.c"
+#include "eventids2.c"
static VALUE ripper_dispatch0(struct parser_params*,ID);
static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
@@ -1445,7 +1054,7 @@ static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
-void ripper_error(struct parser_params *p);
+static void ripper_error(struct parser_params *p);
#define dispatch0(n) ripper_dispatch0(p, TOKEN_PASTE(ripper_id_, n))
#define dispatch1(n,a) ripper_dispatch1(p, TOKEN_PASTE(ripper_id_, n), (a))
@@ -1464,18 +1073,24 @@ void ripper_error(struct parser_params *p);
#define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
+#define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
+
static inline VALUE
new_args(struct parser_params *p, VALUE pre_args, VALUE opt_args, VALUE rest_arg, VALUE post_args, VALUE tail, YYLTYPE *loc)
{
- struct RNode_RIPPER_VALUES *t = RNODE_RIPPER_VALUES(tail);
- VALUE kw_args = t->nd_val1, kw_rest_arg = t->nd_val2, block = t->nd_val3;
- return params_new(pre_args, opt_args, rest_arg, post_args, kw_args, kw_rest_arg, block);
+ NODE *t = (NODE *)tail;
+ VALUE kw_args = t->u1.value, kw_rest_arg = t->u2.value, block = t->u3.value;
+ return params_new(pre_args, opt_args, rest_arg, post_args, kw_args, kw_rest_arg, escape_Qundef(block));
}
static inline VALUE
new_args_tail(struct parser_params *p, VALUE kw_args, VALUE kw_rest_arg, VALUE block, YYLTYPE *loc)
{
- return ripper_new_yylval2(p, kw_args, kw_rest_arg, block);
+ NODE *t = rb_node_newnode(NODE_ARGS_AUX, kw_args, kw_rest_arg, block, &NULL_LOC);
+ add_mark_object(p, kw_args);
+ add_mark_object(p, kw_rest_arg);
+ add_mark_object(p, block);
+ return (VALUE)t;
}
static inline VALUE
@@ -1487,16 +1102,16 @@ args_with_numbered(struct parser_params *p, VALUE args, int max_numparam)
static VALUE
new_array_pattern(struct parser_params *p, VALUE constant, VALUE pre_arg, VALUE aryptn, const YYLTYPE *loc)
{
- struct RNode_RIPPER_VALUES *t = RNODE_RIPPER_VALUES(aryptn);
- VALUE pre_args = t->nd_val1, rest_arg = t->nd_val2, post_args = t->nd_val3;
+ NODE *t = (NODE *)aryptn;
+ VALUE pre_args = t->u1.value, rest_arg = t->u2.value, post_args = t->u3.value;
if (!NIL_P(pre_arg)) {
- if (!NIL_P(pre_args)) {
- rb_ary_unshift(pre_args, pre_arg);
- }
- else {
- pre_args = rb_ary_new_from_args(1, pre_arg);
- }
+ if (!NIL_P(pre_args)) {
+ rb_ary_unshift(pre_args, pre_arg);
+ }
+ else {
+ pre_args = rb_ary_new_from_args(1, pre_arg);
+ }
}
return dispatch4(aryptn, constant, pre_args, rest_arg, post_args);
}
@@ -1504,14 +1119,27 @@ new_array_pattern(struct parser_params *p, VALUE constant, VALUE pre_arg, VALUE
static VALUE
new_array_pattern_tail(struct parser_params *p, VALUE pre_args, VALUE has_rest, VALUE rest_arg, VALUE post_args, const YYLTYPE *loc)
{
- return ripper_new_yylval2(p, pre_args, rest_arg, post_args);
+ NODE *t;
+
+ if (has_rest) {
+ rest_arg = dispatch1(var_field, rest_arg ? rest_arg : Qnil);
+ }
+ else {
+ rest_arg = Qnil;
+ }
+
+ t = rb_node_newnode(NODE_ARYPTN, pre_args, rest_arg, post_args, &NULL_LOC);
+ add_mark_object(p, pre_args);
+ add_mark_object(p, rest_arg);
+ add_mark_object(p, post_args);
+ return (VALUE)t;
}
static VALUE
new_find_pattern(struct parser_params *p, VALUE constant, VALUE fndptn, const YYLTYPE *loc)
{
- struct RNode_RIPPER_VALUES *t = RNODE_RIPPER_VALUES(fndptn);
- VALUE pre_rest_arg = t->nd_val1, args = t->nd_val2, post_rest_arg = t->nd_val3;
+ NODE *t = (NODE *)fndptn;
+ VALUE pre_rest_arg = t->u1.value, args = t->u2.value, post_rest_arg = t->u3.value;
return dispatch4(fndptn, constant, pre_rest_arg, args, post_rest_arg);
}
@@ -1519,7 +1147,16 @@ new_find_pattern(struct parser_params *p, VALUE constant, VALUE fndptn, const YY
static VALUE
new_find_pattern_tail(struct parser_params *p, VALUE pre_rest_arg, VALUE args, VALUE post_rest_arg, const YYLTYPE *loc)
{
- return ripper_new_yylval2(p, pre_rest_arg, args, post_rest_arg);
+ NODE *t;
+
+ pre_rest_arg = dispatch1(var_field, pre_rest_arg ? pre_rest_arg : Qnil);
+ post_rest_arg = dispatch1(var_field, post_rest_arg ? post_rest_arg : Qnil);
+
+ t = rb_node_newnode(NODE_FNDPTN, pre_rest_arg, args, post_rest_arg, &NULL_LOC);
+ add_mark_object(p, pre_rest_arg);
+ add_mark_object(p, args);
+ add_mark_object(p, post_rest_arg);
+ return (VALUE)t;
}
#define new_hash(p,h,l) rb_ary_new_from_args(0)
@@ -1533,21 +1170,26 @@ new_unique_key_hash(struct parser_params *p, VALUE ary, const YYLTYPE *loc)
static VALUE
new_hash_pattern(struct parser_params *p, VALUE constant, VALUE hshptn, const YYLTYPE *loc)
{
- struct RNode_RIPPER_VALUES *t = RNODE_RIPPER_VALUES(hshptn);
- VALUE kw_args = t->nd_val1, kw_rest_arg = t->nd_val2;
+ NODE *t = (NODE *)hshptn;
+ VALUE kw_args = t->u1.value, kw_rest_arg = t->u2.value;
return dispatch3(hshptn, constant, kw_args, kw_rest_arg);
}
static VALUE
new_hash_pattern_tail(struct parser_params *p, VALUE kw_args, VALUE kw_rest_arg, const YYLTYPE *loc)
{
+ NODE *t;
if (kw_rest_arg) {
- kw_rest_arg = dispatch1(var_field, kw_rest_arg);
+ kw_rest_arg = dispatch1(var_field, kw_rest_arg);
}
else {
- kw_rest_arg = Qnil;
+ kw_rest_arg = Qnil;
}
- return ripper_new_yylval2(p, kw_args, kw_rest_arg, Qnil);
+ t = rb_node_newnode(NODE_HSHPTN, kw_args, kw_rest_arg, 0, &NULL_LOC);
+
+ add_mark_object(p, kw_args);
+ add_mark_object(p, kw_rest_arg);
+ return (VALUE)t;
}
#define new_defined(p,expr,loc) dispatch1(defined, (expr))
@@ -1560,19 +1202,20 @@ static VALUE heredoc_dedent(struct parser_params*,VALUE);
#define KWD2EID(t, v) keyword_##t
static NODE *
-new_scope_body(struct parser_params *p, rb_node_args_t *args, NODE *body, const YYLTYPE *loc)
+set_defun_body(struct parser_params *p, NODE *n, NODE *args, NODE *body, const YYLTYPE *loc)
{
body = remove_begin(body);
reduce_nodes(p, &body);
- NODE *n = NEW_SCOPE(args, body, loc);
- nd_set_line(n, loc->end_pos.lineno);
+ n->nd_defn = NEW_SCOPE(args, body, loc);
+ n->nd_loc = *loc;
+ nd_set_line(n->nd_defn, loc->end_pos.lineno);
set_line_body(body, loc->beg_pos.lineno);
return n;
}
static NODE *
rescued_expr(struct parser_params *p, NODE *arg, NODE *rescue,
- const YYLTYPE *arg_loc, const YYLTYPE *mod_loc, const YYLTYPE *res_loc)
+ const YYLTYPE *arg_loc, const YYLTYPE *mod_loc, const YYLTYPE *res_loc)
{
YYLTYPE loc = code_loc_gen(mod_loc, res_loc);
rescue = NEW_RESBODY(0, remove_begin(rescue), 0, &loc);
@@ -1582,62 +1225,32 @@ rescued_expr(struct parser_params *p, NODE *arg, NODE *rescue,
#endif /* RIPPER */
-static NODE *add_block_exit(struct parser_params *p, NODE *node);
-static rb_node_exits_t *init_block_exit(struct parser_params *p);
-static rb_node_exits_t *allow_block_exit(struct parser_params *p);
-static void restore_block_exit(struct parser_params *p, rb_node_exits_t *exits);
-static void clear_block_exit(struct parser_params *p, bool error);
-
-static void
-next_rescue_context(struct lex_context *next, const struct lex_context *outer, enum rescue_context def)
-{
- next->in_rescue = outer->in_rescue == after_rescue ? after_rescue : def;
-}
-
static void
-restore_defun(struct parser_params *p, rb_node_def_temp_t *temp)
+restore_defun(struct parser_params *p, NODE *name)
{
- /* See: def_name action */
- struct lex_context ctxt = temp->save.ctxt;
- p->cur_arg = temp->save.cur_arg;
- p->ctxt.in_def = ctxt.in_def;
- p->ctxt.shareable_constant_value = ctxt.shareable_constant_value;
- p->ctxt.in_rescue = ctxt.in_rescue;
- p->max_numparam = temp->save.max_numparam;
- numparam_pop(p, temp->save.numparam_save);
- clear_block_exit(p, true);
+ NODE *save = name->nd_next;
+ YYSTYPE c = {.val = save->nd_cval};
+ p->cur_arg = name->nd_vid;
+ p->ctxt.in_def = c.ctxt.in_def;
+ p->ctxt.shareable_constant_value = c.ctxt.shareable_constant_value;
+ p->max_numparam = (int)save->nd_nth;
+ numparam_pop(p, save->nd_head);
}
static void
-endless_method_name(struct parser_params *p, ID mid, const YYLTYPE *loc)
+endless_method_name(struct parser_params *p, NODE *defn, const YYLTYPE *loc)
{
+#ifdef RIPPER
+ defn = defn->nd_defn;
+#endif
+ ID mid = defn->nd_mid;
if (is_attrset_id(mid)) {
- yyerror1(loc, "setter method cannot be defined in an endless method definition");
+ yyerror1(loc, "setter method cannot be defined in an endless method definition");
}
token_info_drop(p, "def", loc->beg_pos);
}
-#define debug_token_line(p, name, line) do { \
- if (p->debug) { \
- const char *const pcur = p->lex.pcur; \
- const char *const ptok = p->lex.ptok; \
- rb_parser_printf(p, name ":%d (%d: %"PRIdPTRDIFF"|%"PRIdPTRDIFF"|%"PRIdPTRDIFF")\n", \
- line, p->ruby_sourceline, \
- ptok - p->lex.pbeg, pcur - ptok, p->lex.pend - pcur); \
- } \
- } while (0)
-
-#define begin_definition(k, loc_beg, loc_end) \
- do { \
- if (!(p->ctxt.in_class = (k)[0] != 0)) { \
- p->ctxt.in_def = 0; \
- } \
- else if (p->ctxt.in_def) { \
- YYLTYPE loc = code_loc_gen(loc_beg, loc_end); \
- yyerror1(&loc, k " definition in method body"); \
- } \
- local_push(p, 0); \
- } while (0)
+#define debug_token_line(p, name, line) if (p->debug) rb_parser_printf(p, name ":%d (%d: %ld|%ld|%ld)\n", line, p->ruby_sourceline, p->lex.ptok - p->lex.pbeg, p->lex.pcur - p->lex.ptok, p->lex.pend - p->lex.pcur)
#ifndef RIPPER
# define Qnone 0
@@ -1670,7 +1283,7 @@ endless_method_name(struct parser_params *p, ID mid, const YYLTYPE *loc)
# define rb_warning3L(l,fmt,a,b,c) WARNING_CALL(WARNING_ARGS_L(l, fmt, 4), (a), (b), (c))
# define rb_warning4L(l,fmt,a,b,c,d) WARNING_CALL(WARNING_ARGS_L(l, fmt, 5), (a), (b), (c), (d))
#ifdef RIPPER
-extern const ID id_warn, id_warning, id_gets, id_assoc;
+static ID id_warn, id_warning, id_gets, id_assoc;
# define ERR_MESG() STR_NEW2(mesg) /* to bypass Ripper DSL */
# define WARN_S_L(s,l) STR_NEW(s,l)
# define WARN_S(s) STR_NEW2(s)
@@ -1693,6 +1306,7 @@ extern const ID id_warn, id_warning, id_gets, id_assoc;
# else
# define WARNING_CALL rb_funcall
# endif
+PRINTF_ARGS(static void ripper_compile_error(struct parser_params*, const char *fmt, ...), 2, 3);
# define compile_error ripper_compile_error
#else
# define WARN_S_L(s,l) s
@@ -1708,205 +1322,15 @@ extern const ID id_warn, id_warning, id_gets, id_assoc;
# define WARNING_ARGS(fmt,n) WARN_ARGS(fmt,n)
# define WARNING_ARGS_L(l,fmt,n) WARN_ARGS_L(l,fmt,n)
# define WARNING_CALL rb_compile_warning
-PRINTF_ARGS(static void parser_compile_error(struct parser_params*, const rb_code_location_t *loc, const char *fmt, ...), 3, 4);
-# define compile_error(p, ...) parser_compile_error(p, NULL, __VA_ARGS__)
+PRINTF_ARGS(static void parser_compile_error(struct parser_params*, const char *fmt, ...), 2, 3);
+# define compile_error parser_compile_error
#endif
-struct RNode_EXITS {
- NODE node;
-
- NODE *nd_chain; /* Assume NODE_BREAK, NODE_NEXT, NODE_REDO have nd_chain here */
- NODE *nd_end;
-};
-
-#define RNODE_EXITS(node) ((rb_node_exits_t*)(node))
-
-static NODE *
-add_block_exit(struct parser_params *p, NODE *node)
-{
- if (!node) {
- compile_error(p, "unexpected null node");
- return 0;
- }
- switch (nd_type(node)) {
- case NODE_BREAK: case NODE_NEXT: case NODE_REDO: break;
- default:
- compile_error(p, "unexpected node: %s", parser_node_name(nd_type(node)));
- return node;
- }
- if (!p->ctxt.in_defined) {
- rb_node_exits_t *exits = p->exits;
- if (exits) {
- RNODE_EXITS(exits->nd_end)->nd_chain = node;
- exits->nd_end = node;
- }
- }
- return node;
-}
-
-static rb_node_exits_t *
-init_block_exit(struct parser_params *p)
-{
- rb_node_exits_t *old = p->exits;
- rb_node_exits_t *exits = NODE_NEW_INTERNAL(NODE_EXITS, rb_node_exits_t);
- exits->nd_chain = 0;
- exits->nd_end = RNODE(exits);
- p->exits = exits;
- return old;
-}
-
-static rb_node_exits_t *
-allow_block_exit(struct parser_params *p)
-{
- rb_node_exits_t *exits = p->exits;
- p->exits = 0;
- return exits;
-}
-
-static void
-restore_block_exit(struct parser_params *p, rb_node_exits_t *exits)
-{
- p->exits = exits;
-}
-
-static void
-clear_block_exit(struct parser_params *p, bool error)
-{
- rb_node_exits_t *exits = p->exits;
- if (!exits) return;
- if (error && !compile_for_eval) {
- for (NODE *e = RNODE(exits); (e = RNODE_EXITS(e)->nd_chain) != 0; ) {
- switch (nd_type(e)) {
- case NODE_BREAK:
- yyerror1(&e->nd_loc, "Invalid break");
- break;
- case NODE_NEXT:
- yyerror1(&e->nd_loc, "Invalid next");
- break;
- case NODE_REDO:
- yyerror1(&e->nd_loc, "Invalid redo");
- break;
- default:
- yyerror1(&e->nd_loc, "unexpected node");
- goto end_checks; /* no nd_chain */
- }
- }
- end_checks:;
- }
- exits->nd_end = RNODE(exits);
- exits->nd_chain = 0;
-}
-
#define WARN_EOL(tok) \
(looking_at_eol_p(p) ? \
(void)rb_warning0("`" tok "' at the end of line without an expression") : \
(void)0)
static int looking_at_eol_p(struct parser_params *p);
-
-#ifndef RIPPER
-static NODE *
-get_nd_value(struct parser_params *p, NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_GASGN:
- return RNODE_GASGN(node)->nd_value;
- case NODE_IASGN:
- return RNODE_IASGN(node)->nd_value;
- case NODE_LASGN:
- return RNODE_LASGN(node)->nd_value;
- case NODE_DASGN:
- return RNODE_DASGN(node)->nd_value;
- case NODE_MASGN:
- return RNODE_MASGN(node)->nd_value;
- case NODE_CVASGN:
- return RNODE_CVASGN(node)->nd_value;
- case NODE_CDECL:
- return RNODE_CDECL(node)->nd_value;
- default:
- compile_error(p, "unexpected node: %s", parser_node_name(nd_type(node)));
- return 0;
- }
-}
-
-static void
-set_nd_value(struct parser_params *p, NODE *node, NODE *rhs)
-{
- switch (nd_type(node)) {
- case NODE_CDECL:
- RNODE_CDECL(node)->nd_value = rhs;
- break;
- case NODE_GASGN:
- RNODE_GASGN(node)->nd_value = rhs;
- break;
- case NODE_IASGN:
- RNODE_IASGN(node)->nd_value = rhs;
- break;
- case NODE_LASGN:
- RNODE_LASGN(node)->nd_value = rhs;
- break;
- case NODE_DASGN:
- RNODE_DASGN(node)->nd_value = rhs;
- break;
- case NODE_MASGN:
- RNODE_MASGN(node)->nd_value = rhs;
- break;
- case NODE_CVASGN:
- RNODE_CVASGN(node)->nd_value = rhs;
- break;
- default:
- compile_error(p, "unexpected node: %s", parser_node_name(nd_type(node)));
- break;
- }
-}
-
-static ID
-get_nd_vid(struct parser_params *p, NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_CDECL:
- return RNODE_CDECL(node)->nd_vid;
- case NODE_GASGN:
- return RNODE_GASGN(node)->nd_vid;
- case NODE_IASGN:
- return RNODE_IASGN(node)->nd_vid;
- case NODE_LASGN:
- return RNODE_LASGN(node)->nd_vid;
- case NODE_DASGN:
- return RNODE_DASGN(node)->nd_vid;
- case NODE_CVASGN:
- return RNODE_CVASGN(node)->nd_vid;
- default:
- compile_error(p, "unexpected node: %s", parser_node_name(nd_type(node)));
- return 0;
- }
-}
-
-static NODE *
-get_nd_args(struct parser_params *p, NODE *node)
-{
- switch (nd_type(node)) {
- case NODE_CALL:
- return RNODE_CALL(node)->nd_args;
- case NODE_OPCALL:
- return RNODE_OPCALL(node)->nd_args;
- case NODE_FCALL:
- return RNODE_FCALL(node)->nd_args;
- case NODE_QCALL:
- return RNODE_QCALL(node)->nd_args;
- case NODE_VCALL:
- case NODE_SUPER:
- case NODE_ZSUPER:
- case NODE_YIELD:
- case NODE_RETURN:
- case NODE_BREAK:
- case NODE_NEXT:
- return 0;
- default:
- compile_error(p, "unexpected node: %s", parser_node_name(nd_type(node)));
- return 0;
- }
-}
-#endif
%}
%expect 0
@@ -1914,39 +1338,36 @@ get_nd_args(struct parser_params *p, NODE *node)
%define parse.error verbose
%printer {
#ifndef RIPPER
- if ((NODE *)$$ == (NODE *)-1) {
- rb_parser_printf(p, "NODE_SPECIAL");
- }
- else if ($$) {
- rb_parser_printf(p, "%s", parser_node_name(nd_type(RNODE($$))));
+ if ($$) {
+ rb_parser_printf(p, "%s", ruby_node_name(nd_type($$)));
}
#else
#endif
-} <node> <node_fcall> <node_args> <node_args_aux> <node_opt_arg> <node_kw_arg> <node_block_pass>
+} <node>
%printer {
#ifndef RIPPER
rb_parser_printf(p, "%"PRIsVALUE, rb_id2str($$));
#else
- rb_parser_printf(p, "%"PRIsVALUE, RNODE_RIPPER($$)->nd_rval);
+ rb_parser_printf(p, "%"PRIsVALUE, RNODE($$)->nd_rval);
#endif
} tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tOP_ASGN
%printer {
#ifndef RIPPER
- rb_parser_printf(p, "%+"PRIsVALUE, RNODE_LIT($$)->nd_lit);
+ rb_parser_printf(p, "%+"PRIsVALUE, $$->nd_lit);
#else
rb_parser_printf(p, "%+"PRIsVALUE, get_value($$));
#endif
} tINTEGER tFLOAT tRATIONAL tIMAGINARY tSTRING_CONTENT tCHAR
%printer {
#ifndef RIPPER
- rb_parser_printf(p, "$%ld", RNODE_NTH_REF($$)->nd_nth);
+ rb_parser_printf(p, "$%ld", $$->nd_nth);
#else
rb_parser_printf(p, "%"PRIsVALUE, $$);
#endif
} tNTH_REF
%printer {
#ifndef RIPPER
- rb_parser_printf(p, "$%c", (int)RNODE_BACK_REF($$)->nd_nth);
+ rb_parser_printf(p, "$%c", (int)$$->nd_nth);
#else
rb_parser_printf(p, "%"PRIsVALUE, $$);
#endif
@@ -1962,15 +1383,6 @@ get_nd_args(struct parser_params *p, NODE *node)
%union {
VALUE val;
NODE *node;
- rb_node_fcall_t *node_fcall;
- rb_node_args_t *node_args;
- rb_node_args_aux_t *node_args_aux;
- rb_node_opt_arg_t *node_opt_arg;
- rb_node_kw_arg_t *node_kw_arg;
- rb_node_block_pass_t *node_block_pass;
- rb_node_masgn_t *node_masgn;
- rb_node_def_temp_t *node_def_temp;
- rb_node_exits_t *node_exits;
ID id;
int num;
st_table *tbl;
@@ -2051,56 +1463,39 @@ get_nd_args(struct parser_params *p, NODE *node)
%type <node> singleton strings string string1 xstring regexp
%type <node> string_contents xstring_contents regexp_contents string_content
%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
-%type <node> literal numeric simple_numeric ssym dsym symbol cpath
-/*ripper*/ %type <node_def_temp> defn_head defs_head k_def
-/*ripper*/ %type <node_exits> block_open k_while k_until k_for allow_exits
-%type <node> top_compstmt top_stmts top_stmt begin_block endless_arg endless_command
+%type <node> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head
+%type <node> top_compstmt top_stmts top_stmt begin_block
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
-%type <node> expr_value expr_value_do arg_value primary_value rel_expr
-%type <node_fcall> fcall
+%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
-%type <node> args arg_splat call_args opt_call_args
-%type <node> paren_args opt_paren_args
-%type <node_args> args_tail opt_args_tail block_args_tail opt_block_args_tail
-%type <node> command_args aref_args
-%type <node_block_pass> opt_block_arg block_arg
-%type <node> var_ref var_lhs
+%type <node> args call_args opt_call_args
+%type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
+%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> command_rhs arg_rhs
%type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
-%type <node_opt_arg> f_block_optarg f_block_opt
-%type <node_args> f_arglist f_opt_paren_args f_paren_args f_args
-%type <node_args_aux> f_arg f_arg_item
-%type <node_opt_arg> f_optarg
-%type <node> f_marg f_marg_list f_rest_marg
-%type <node_masgn> f_margs
+%type <node> f_block_optarg f_block_opt
+%type <node> f_arglist f_opt_paren_args f_paren_args f_args f_arg f_arg_item
+%type <node> f_optarg f_marg f_marg_list f_margs f_rest_marg
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
-%type <node_args> block_param opt_block_param block_param_def
-%type <node_opt_arg> f_opt
-%type <node_kw_arg> f_kwarg f_kw f_block_kwarg f_block_kw
+%type <node> block_param opt_block_param block_param_def f_opt
+%type <node> f_kwarg f_kw f_block_kwarg f_block_kw
%type <node> bv_decls opt_bv_decl bvar
-%type <node> lambda lambda_body brace_body do_body
-%type <node_args> f_larglist
+%type <node> lambda f_larglist lambda_body brace_body do_body
%type <node> brace_block cmd_brace_block do_block lhs none fitem
-%type <node> mlhs_head mlhs_item mlhs_node mlhs_post
-%type <node_masgn> mlhs mlhs_basic mlhs_inner
+%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
%type <node> p_case_body p_cases p_top_expr p_top_expr_body
%type <node> p_expr p_as p_alt p_expr_basic p_find
-%type <node> p_args p_args_head p_args_tail p_args_post p_arg p_rest
+%type <node> p_args p_args_head p_args_tail p_args_post p_arg
%type <node> p_value p_primitive p_variable p_var_ref p_expr_ref p_const
%type <node> p_kwargs p_kwarg p_kw
%type <id> keyword_variable user_variable sym operation operation2 operation3
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
%type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
-%type <id> p_kwrest p_kwnorest p_any_kwrest p_kw_label
-%type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var def_name
-%type <ctxt> lex_ctxt begin_defined k_class k_module k_END k_rescue k_ensure after_rescue
-%type <ctxt> p_in_kwarg
-%type <tbl> p_lparen p_lbracket p_pktbl p_pvtbl
-/* ripper */ %type <num> max_numparam
-/* ripper */ %type <node> numparam
+%type <id> p_rest p_kwrest p_kwnorest p_any_kwrest p_kw_label
+%type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var
+ %type <ctxt> lex_ctxt /* keep <ctxt> in ripper */
%token END_OF_INPUT 0 "end-of-input"
%token <id> '.'
-
/* escaped chars, should be ignored otherwise */
%token <id> '\\' "backslash"
%token tSP "escaped space"
@@ -2191,3400 +1586,3379 @@ get_nd_args(struct parser_params *p, NODE *node)
%%
program : {
- SET_LEX_STATE(EXPR_BEG);
- local_push(p, ifndef_ripper(1)+0);
- /* jumps are possible in the top-level loop. */
- if (!ifndef_ripper(p->do_loop) + 0) init_block_exit(p);
- }
- top_compstmt
- {
- /*%%%*/
- if ($2 && !compile_for_eval) {
- NODE *node = $2;
- /* last expression should not be void */
- if (nd_type_p(node, NODE_BLOCK)) {
- while (RNODE_BLOCK(node)->nd_next) {
- node = RNODE_BLOCK(node)->nd_next;
- }
- node = RNODE_BLOCK(node)->nd_head;
- }
- node = remove_begin(node);
- void_expr(p, node);
- }
- p->eval_tree = NEW_SCOPE(0, block_append(p, p->eval_tree, $2), &@$);
- /*% %*/
- /*% ripper[final]: program!($2) %*/
- local_pop(p);
- }
- ;
+ SET_LEX_STATE(EXPR_BEG);
+ local_push(p, ifndef_ripper(1)+0);
+ }
+ top_compstmt
+ {
+ /*%%%*/
+ if ($2 && !compile_for_eval) {
+ NODE *node = $2;
+ /* last expression should not be void */
+ if (nd_type_p(node, NODE_BLOCK)) {
+ while (node->nd_next) {
+ node = node->nd_next;
+ }
+ node = node->nd_head;
+ }
+ node = remove_begin(node);
+ void_expr(p, node);
+ }
+ p->eval_tree = NEW_SCOPE(0, block_append(p, p->eval_tree, $2), &@$);
+ /*% %*/
+ /*% ripper[final]: program!($2) %*/
+ local_pop(p);
+ }
+ ;
top_compstmt : top_stmts opt_terms
- {
- $$ = void_stmts(p, $1);
- }
- ;
+ {
+ $$ = void_stmts(p, $1);
+ }
+ ;
top_stmts : none
{
- /*%%%*/
- $$ = NEW_BEGIN(0, &@$);
- /*% %*/
- /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
- }
- | top_stmt
- {
- /*%%%*/
- $$ = newline_node($1);
- /*% %*/
- /*% ripper: stmts_add!(stmts_new!, $1) %*/
- }
- | top_stmts terms top_stmt
- {
- /*%%%*/
- $$ = block_append(p, $1, newline_node($3));
- /*% %*/
- /*% ripper: stmts_add!($1, $3) %*/
- }
- ;
+ /*%%%*/
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
+ }
+ | top_stmt
+ {
+ /*%%%*/
+ $$ = newline_node($1);
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, $1) %*/
+ }
+ | top_stmts terms top_stmt
+ {
+ /*%%%*/
+ $$ = block_append(p, $1, newline_node($3));
+ /*% %*/
+ /*% ripper: stmts_add!($1, $3) %*/
+ }
+ ;
top_stmt : stmt
- {
- clear_block_exit(p, true);
- $$ = $1;
- }
- | keyword_BEGIN begin_block
- {
- $$ = $2;
- }
- ;
-
-block_open : '{' {$$ = init_block_exit(p);};
-
-begin_block : block_open top_compstmt '}'
- {
- restore_block_exit(p, $block_open);
- /*%%%*/
- p->eval_tree_begin = block_append(p, p->eval_tree_begin,
- NEW_BEGIN($2, &@$));
- $$ = NEW_BEGIN(0, &@$);
- /*% %*/
- /*% ripper: BEGIN!($2) %*/
- }
- ;
-
-bodystmt : compstmt[body]
- lex_ctxt[ctxt]
- opt_rescue
- k_else
- {
- if (!$opt_rescue) yyerror1(&@k_else, "else without rescue is useless");
- next_rescue_context(&p->ctxt, &$ctxt, after_else);
- }
- compstmt[elsebody]
- {
- next_rescue_context(&p->ctxt, &$ctxt, after_ensure);
- }
- opt_ensure
- {
- /*%%%*/
- $$ = new_bodystmt(p, $body, $opt_rescue, $elsebody, $opt_ensure, &@$);
- /*% %*/
- /*% ripper: bodystmt!($body, $opt_rescue, $elsebody, $opt_ensure) %*/
- }
- | compstmt[body]
- lex_ctxt[ctxt]
- opt_rescue
- {
- next_rescue_context(&p->ctxt, &$ctxt, after_ensure);
- }
- opt_ensure
- {
- /*%%%*/
- $$ = new_bodystmt(p, $body, $opt_rescue, 0, $opt_ensure, &@$);
- /*% %*/
- /*% ripper: bodystmt!($body, $opt_rescue, Qnil, $opt_ensure) %*/
- }
- ;
+ | keyword_BEGIN begin_block
+ {
+ $$ = $2;
+ }
+ ;
+
+begin_block : '{' top_compstmt '}'
+ {
+ /*%%%*/
+ p->eval_tree_begin = block_append(p, p->eval_tree_begin,
+ NEW_BEGIN($2, &@$));
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: BEGIN!($2) %*/
+ }
+ ;
+
+bodystmt : compstmt
+ opt_rescue
+ k_else {if (!$2) {yyerror1(&@3, "else without rescue is useless");}}
+ compstmt
+ opt_ensure
+ {
+ /*%%%*/
+ $$ = new_bodystmt(p, $1, $2, $5, $6, &@$);
+ /*% %*/
+ /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), escape_Qundef($5), escape_Qundef($6)) %*/
+ }
+ | compstmt
+ opt_rescue
+ opt_ensure
+ {
+ /*%%%*/
+ $$ = new_bodystmt(p, $1, $2, 0, $3, &@$);
+ /*% %*/
+ /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), Qnil, escape_Qundef($3)) %*/
+ }
+ ;
compstmt : stmts opt_terms
- {
- $$ = void_stmts(p, $1);
- }
- ;
+ {
+ $$ = void_stmts(p, $1);
+ }
+ ;
stmts : none
{
- /*%%%*/
- $$ = NEW_BEGIN(0, &@$);
- /*% %*/
- /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
- }
- | stmt_or_begin
- {
- /*%%%*/
- $$ = newline_node($1);
- /*% %*/
- /*% ripper: stmts_add!(stmts_new!, $1) %*/
- }
- | stmts terms stmt_or_begin
- {
- /*%%%*/
- $$ = block_append(p, $1, newline_node($3));
- /*% %*/
- /*% ripper: stmts_add!($1, $3) %*/
- }
- ;
+ /*%%%*/
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
+ }
+ | stmt_or_begin
+ {
+ /*%%%*/
+ $$ = newline_node($1);
+ /*% %*/
+ /*% ripper: stmts_add!(stmts_new!, $1) %*/
+ }
+ | stmts terms stmt_or_begin
+ {
+ /*%%%*/
+ $$ = block_append(p, $1, newline_node($3));
+ /*% %*/
+ /*% ripper: stmts_add!($1, $3) %*/
+ }
+ ;
stmt_or_begin : stmt
{
- $$ = $1;
- }
+ $$ = $1;
+ }
| keyword_BEGIN
- {
- yyerror1(&@1, "BEGIN is permitted only at toplevel");
- }
- begin_block
- {
- $$ = $3;
- }
- ;
-
-allow_exits : {$$ = allow_block_exit(p);};
-
-k_END : keyword_END lex_ctxt
- {
- $$ = $2;
- p->ctxt.in_rescue = before_rescue;
- };
+ {
+ yyerror1(&@1, "BEGIN is permitted only at toplevel");
+ }
+ begin_block
+ {
+ $$ = $3;
+ }
+ ;
stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
- {
- /*%%%*/
- $$ = NEW_ALIAS($2, $4, &@$);
- /*% %*/
- /*% ripper: alias!($2, $4) %*/
- }
- | keyword_alias tGVAR tGVAR
- {
- /*%%%*/
- $$ = NEW_VALIAS($2, $3, &@$);
- /*% %*/
- /*% ripper: var_alias!($2, $3) %*/
- }
- | keyword_alias tGVAR tBACK_REF
- {
- /*%%%*/
- char buf[2];
- buf[0] = '$';
- buf[1] = (char)RNODE_BACK_REF($3)->nd_nth;
- $$ = NEW_VALIAS($2, rb_intern2(buf, 2), &@$);
- /*% %*/
- /*% ripper: var_alias!($2, $3) %*/
- }
- | keyword_alias tGVAR tNTH_REF
- {
- static const char mesg[] = "can't make alias for the number variables";
- /*%%%*/
- yyerror1(&@3, mesg);
- $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper[error]: alias_error!(ERR_MESG(), $3) %*/
- }
- | keyword_undef undef_list
- {
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: undef!($2) %*/
- }
- | stmt modifier_if expr_value
- {
- /*%%%*/
- $$ = new_if(p, $3, remove_begin($1), 0, &@$);
- fixpos($$, $3);
- /*% %*/
- /*% ripper: if_mod!($3, $1) %*/
- }
- | stmt modifier_unless expr_value
- {
- /*%%%*/
- $$ = new_unless(p, $3, remove_begin($1), 0, &@$);
- fixpos($$, $3);
- /*% %*/
- /*% ripper: unless_mod!($3, $1) %*/
- }
- | stmt modifier_while expr_value
- {
- clear_block_exit(p, false);
- /*%%%*/
- if ($1 && nd_type_p($1, NODE_BEGIN)) {
- $$ = NEW_WHILE(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$);
- }
- else {
- $$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$);
- }
- /*% %*/
- /*% ripper: while_mod!($3, $1) %*/
- }
- | stmt modifier_until expr_value
- {
- clear_block_exit(p, false);
- /*%%%*/
- if ($1 && nd_type_p($1, NODE_BEGIN)) {
- $$ = NEW_UNTIL(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$);
- }
- else {
- $$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$);
- }
- /*% %*/
- /*% ripper: until_mod!($3, $1) %*/
- }
- | stmt modifier_rescue after_rescue stmt
- {
- p->ctxt.in_rescue = $3.in_rescue;
- /*%%%*/
- NODE *resq;
- YYLTYPE loc = code_loc_gen(&@2, &@4);
- resq = NEW_RESBODY(0, remove_begin($4), 0, &loc);
- $$ = NEW_RESCUE(remove_begin($1), resq, 0, &@$);
- /*% %*/
- /*% ripper: rescue_mod!($1, $4) %*/
- }
- | k_END allow_exits '{' compstmt '}'
- {
- if (p->ctxt.in_def) {
- rb_warn0("END in method; use at_exit");
- }
- restore_block_exit(p, $allow_exits);
- p->ctxt = $k_END;
- /*%%%*/
- {
- NODE *scope = NEW_SCOPE2(0 /* tbl */, 0 /* args */, $compstmt /* body */, &@$);
- $$ = NEW_POSTEXE(scope, &@$);
- }
- /*% %*/
- /*% ripper: END!($compstmt) %*/
- }
- | command_asgn
- | mlhs '=' lex_ctxt command_call
- {
- /*%%%*/
- value_expr($4);
- $$ = node_assign(p, (NODE *)$1, $4, $3, &@$);
- /*% %*/
- /*% ripper: massign!($1, $4) %*/
- }
- | lhs '=' lex_ctxt mrhs
- {
- /*%%%*/
- $$ = node_assign(p, $1, $4, $3, &@$);
- /*% %*/
- /*% ripper: assign!($1, $4) %*/
- }
- | mlhs '=' lex_ctxt mrhs_arg modifier_rescue
- after_rescue stmt[resbody]
- {
- p->ctxt.in_rescue = $3.in_rescue;
- /*%%%*/
- YYLTYPE loc = code_loc_gen(&@modifier_rescue, &@resbody);
- $resbody = NEW_RESBODY(0, remove_begin($resbody), 0, &loc);
- loc.beg_pos = @mrhs_arg.beg_pos;
- $mrhs_arg = NEW_RESCUE($mrhs_arg, $resbody, 0, &loc);
- $$ = node_assign(p, (NODE *)$mlhs, $mrhs_arg, $lex_ctxt, &@$);
- /*% %*/
- /*% ripper: massign!($1, rescue_mod!($4, $7)) %*/
- }
- | mlhs '=' lex_ctxt mrhs_arg
- {
- /*%%%*/
- $$ = node_assign(p, (NODE *)$1, $4, $3, &@$);
- /*% %*/
- /*% ripper: massign!($1, $4) %*/
- }
- | expr
- | error
- {
- (void)yynerrs;
- /*%%%*/
- $$ = NEW_ERROR(&@$);
- /*% %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_ALIAS($2, $4, &@$);
+ /*% %*/
+ /*% ripper: alias!($2, $4) %*/
+ }
+ | keyword_alias tGVAR tGVAR
+ {
+ /*%%%*/
+ $$ = NEW_VALIAS($2, $3, &@$);
+ /*% %*/
+ /*% ripper: var_alias!($2, $3) %*/
+ }
+ | keyword_alias tGVAR tBACK_REF
+ {
+ /*%%%*/
+ char buf[2];
+ buf[0] = '$';
+ buf[1] = (char)$3->nd_nth;
+ $$ = NEW_VALIAS($2, rb_intern2(buf, 2), &@$);
+ /*% %*/
+ /*% ripper: var_alias!($2, $3) %*/
+ }
+ | keyword_alias tGVAR tNTH_REF
+ {
+ static const char mesg[] = "can't make alias for the number variables";
+ /*%%%*/
+ yyerror1(&@3, mesg);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: alias_error!(ERR_MESG(), $3) %*/
+ }
+ | keyword_undef undef_list
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: undef!($2) %*/
+ }
+ | stmt modifier_if expr_value
+ {
+ /*%%%*/
+ $$ = new_if(p, $3, remove_begin($1), 0, &@$);
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: if_mod!($3, $1) %*/
+ }
+ | stmt modifier_unless expr_value
+ {
+ /*%%%*/
+ $$ = new_unless(p, $3, remove_begin($1), 0, &@$);
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: unless_mod!($3, $1) %*/
+ }
+ | stmt modifier_while expr_value
+ {
+ /*%%%*/
+ if ($1 && nd_type_p($1, NODE_BEGIN)) {
+ $$ = NEW_WHILE(cond(p, $3, &@3), $1->nd_body, 0, &@$);
+ }
+ else {
+ $$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$);
+ }
+ /*% %*/
+ /*% ripper: while_mod!($3, $1) %*/
+ }
+ | stmt modifier_until expr_value
+ {
+ /*%%%*/
+ if ($1 && nd_type_p($1, NODE_BEGIN)) {
+ $$ = NEW_UNTIL(cond(p, $3, &@3), $1->nd_body, 0, &@$);
+ }
+ else {
+ $$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$);
+ }
+ /*% %*/
+ /*% ripper: until_mod!($3, $1) %*/
+ }
+ | stmt modifier_rescue stmt
+ {
+ /*%%%*/
+ NODE *resq;
+ YYLTYPE loc = code_loc_gen(&@2, &@3);
+ resq = NEW_RESBODY(0, remove_begin($3), 0, &loc);
+ $$ = NEW_RESCUE(remove_begin($1), resq, 0, &@$);
+ /*% %*/
+ /*% ripper: rescue_mod!($1, $3) %*/
+ }
+ | keyword_END '{' compstmt '}'
+ {
+ if (p->ctxt.in_def) {
+ rb_warn0("END in method; use at_exit");
+ }
+ /*%%%*/
+ {
+ NODE *scope = NEW_NODE(
+ NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */, &@$);
+ $$ = NEW_POSTEXE(scope, &@$);
+ }
+ /*% %*/
+ /*% ripper: END!($3) %*/
+ }
+ | command_asgn
+ | mlhs '=' lex_ctxt command_call
+ {
+ /*%%%*/
+ value_expr($4);
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: massign!($1, $4) %*/
+ }
+ | lhs '=' lex_ctxt mrhs
+ {
+ /*%%%*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: assign!($1, $4) %*/
+ }
+ | mlhs '=' lex_ctxt mrhs_arg modifier_rescue stmt
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@5, &@6);
+ $$ = node_assign(p, $1, NEW_RESCUE($4, NEW_RESBODY(0, remove_begin($6), 0, &loc), 0, &@$), $3, &@$);
+ /*% %*/
+ /*% ripper: massign!($1, rescue_mod!($4, $6)) %*/
+ }
+ | mlhs '=' lex_ctxt mrhs_arg
+ {
+ /*%%%*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: massign!($1, $4) %*/
+ }
+ | expr
+ | error
+ {
+ /*%%%*/
+ $$ = NEW_ERROR(&@$);
+ /*% %*/
+ }
+ ;
command_asgn : lhs '=' lex_ctxt command_rhs
- {
- /*%%%*/
- $$ = node_assign(p, $1, $4, $3, &@$);
- /*% %*/
- /*% ripper: assign!($1, $4) %*/
- }
- | var_lhs tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- $$ = new_op_assign(p, $1, $2, $4, $3, &@$);
- /*% %*/
- /*% ripper: opassign!($1, $2, $4) %*/
- }
- | primary_value '[' opt_call_args rbracket tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$);
- /*% %*/
- /*% ripper: opassign!(aref_field!($1, $3), $5, $7) %*/
-
- }
- | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
- /*% %*/
- /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
- }
- | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
- /*% %*/
- /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- YYLTYPE loc = code_loc_gen(&@1, &@3);
- $$ = new_const_op_assign(p, NEW_COLON2($1, $3, &loc), $4, $6, $5, &@$);
- /*% %*/
- /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $6, &@$);
- /*% %*/
- /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
- }
- | defn_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt]
- {
- endless_method_name(p, get_id($head->nd_mid), &@head);
- restore_defun(p, $head);
- /*%%%*/
- $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
- ($$ = $head->nd_def)->nd_loc = @$;
- RNODE_DEFN($$)->nd_defn = $bodystmt;
- /*% %*/
- /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
- /*% ripper: def!($head->nd_mid, $args, $bodystmt) %*/
- local_pop(p);
- }
- | defs_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt]
- {
- endless_method_name(p, get_id($head->nd_mid), &@head);
- restore_defun(p, $head);
- /*%%%*/
- $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
- ($$ = $head->nd_def)->nd_loc = @$;
- RNODE_DEFS($$)->nd_defn = $bodystmt;
- /*% %*/
- /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
- /*% ripper: defs!($head->nd_recv, $head->dot_or_colon, $head->nd_mid, $args, $bodystmt) %*/
- local_pop(p);
- }
- | backref tOP_ASGN lex_ctxt command_rhs
- {
- /*%%%*/
- rb_backref_error(p, $1);
- $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper[error]: backref_error(p, RNODE($1), assign!(var_field(p, $1), $4)) %*/
- }
- ;
-
-endless_command : command
- | endless_command modifier_rescue after_rescue arg
- {
- p->ctxt.in_rescue = $3.in_rescue;
- /*%%%*/
- $$ = rescued_expr(p, $1, $4, &@1, &@2, &@4);
- /*% %*/
- /*% ripper: rescue_mod!($1, $4) %*/
- }
- | keyword_not opt_nl endless_command
- {
- $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
- }
- ;
+ {
+ /*%%%*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: assign!($1, $4) %*/
+ }
+ | var_lhs tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ $$ = new_op_assign(p, $1, $2, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: opassign!($1, $2, $4) %*/
+ }
+ | primary_value '[' opt_call_args rbracket tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$);
+ /*% %*/
+ /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
+
+ }
+ | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
+ }
+ | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
+ }
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ $$ = new_const_op_assign(p, NEW_COLON2($1, $3, &loc), $4, $6, $5, &@$);
+ /*% %*/
+ /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
+ }
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
+ }
+ | defn_head f_opt_paren_args '=' command
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
+ /*% ripper: def!(get_value($1), $2, $4) %*/
+ local_pop(p);
+ }
+ | defn_head f_opt_paren_args '=' command modifier_rescue arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
+ /*% ripper: def!(get_value($1), $2, $4) %*/
+ local_pop(p);
+ }
+ | defs_head f_opt_paren_args '=' command
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*%
+ $1 = get_value($1);
+ %*/
+ /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
+ local_pop(p);
+ }
+ | defs_head f_opt_paren_args '=' command modifier_rescue arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*%
+ $1 = get_value($1);
+ %*/
+ /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
+ local_pop(p);
+ }
+ | backref tOP_ASGN lex_ctxt command_rhs
+ {
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), assign!(var_field(p, $1), $4)) %*/
+ }
+ ;
command_rhs : command_call %prec tOP_ASGN
- {
- value_expr($1);
- $$ = $1;
- }
- | command_call modifier_rescue after_rescue stmt
- {
- p->ctxt.in_rescue = $3.in_rescue;
- /*%%%*/
- YYLTYPE loc = code_loc_gen(&@2, &@4);
- value_expr($1);
- $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($4), 0, &loc), 0, &@$);
- /*% %*/
- /*% ripper: rescue_mod!($1, $4) %*/
- }
- | command_asgn
- ;
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ | command_call modifier_rescue stmt
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@2, &@3);
+ value_expr($1);
+ $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($3), 0, &loc), 0, &@$);
+ /*% %*/
+ /*% ripper: rescue_mod!($1, $3) %*/
+ }
+ | command_asgn
+ ;
expr : command_call
- | expr keyword_and expr
- {
- $$ = logop(p, idAND, $1, $3, &@2, &@$);
- }
- | expr keyword_or expr
- {
- $$ = logop(p, idOR, $1, $3, &@2, &@$);
- }
- | keyword_not opt_nl expr
- {
- $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
- }
- | '!' command_call
- {
- $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
- }
- | arg tASSOC
- {
- value_expr($arg);
- }
- p_in_kwarg[ctxt] p_pvtbl p_pktbl
- p_top_expr_body[body]
- {
- pop_pktbl(p, $p_pktbl);
- pop_pvtbl(p, $p_pvtbl);
- p->ctxt.in_kwarg = $ctxt.in_kwarg;
- /*%%%*/
- $$ = NEW_CASE3($arg, NEW_IN($body, 0, 0, &@body), &@$);
- /*% %*/
- /*% ripper: case!($arg, in!($body, Qnil, Qnil)) %*/
- }
- | arg keyword_in
- {
- value_expr($arg);
- }
- p_in_kwarg[ctxt] p_pvtbl p_pktbl
- p_top_expr_body[body]
- {
- pop_pktbl(p, $p_pktbl);
- pop_pvtbl(p, $p_pvtbl);
- p->ctxt.in_kwarg = $ctxt.in_kwarg;
- /*%%%*/
- $$ = NEW_CASE3($arg, NEW_IN($body, NEW_TRUE(&@body), NEW_FALSE(&@body), &@body), &@$);
- /*% %*/
- /*% ripper: case!($arg, in!($body, Qnil, Qnil)) %*/
- }
- | arg %prec tLBRACE_ARG
- ;
-
-def_name : fname
+ | expr keyword_and expr
+ {
+ $$ = logop(p, idAND, $1, $3, &@2, &@$);
+ }
+ | expr keyword_or expr
+ {
+ $$ = logop(p, idOR, $1, $3, &@2, &@$);
+ }
+ | keyword_not opt_nl expr
+ {
+ $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
+ }
+ | '!' command_call
+ {
+ $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
+ }
+ | arg tASSOC
+ {
+ value_expr($1);
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>2 = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ $<tbl>$ = push_pvtbl(p);
+ }
+ {
+ $<tbl>$ = push_pktbl(p);
+ }
+ p_top_expr_body
+ {
+ pop_pktbl(p, $<tbl>4);
+ pop_pvtbl(p, $<tbl>3);
+ p->ctxt.in_kwarg = $<ctxt>2.in_kwarg;
+ /*%%%*/
+ $$ = NEW_CASE3($1, NEW_IN($5, 0, 0, &@5), &@$);
+ /*% %*/
+ /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/
+ }
+ | arg keyword_in
+ {
+ value_expr($1);
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>2 = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ $<tbl>$ = push_pvtbl(p);
+ }
+ {
+ $<tbl>$ = push_pktbl(p);
+ }
+ p_top_expr_body
+ {
+ pop_pktbl(p, $<tbl>4);
+ pop_pvtbl(p, $<tbl>3);
+ p->ctxt.in_kwarg = $<ctxt>2.in_kwarg;
+ /*%%%*/
+ $$ = NEW_CASE3($1, NEW_IN($5, NEW_TRUE(&@5), NEW_FALSE(&@5), &@5), &@$);
+ /*% %*/
+ /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/
+ }
+ | arg %prec tLBRACE_ARG
+ ;
+
+def_name : fname
{
ID fname = get_id($1);
+ ID cur_arg = p->cur_arg;
+ YYSTYPE c = {.ctxt = p->ctxt};
numparam_name(p, fname);
+ NODE *save =
+ NODE_NEW_TEMPORAL(NODE_SELF,
+ /*head*/numparam_push(p),
+ /*nth*/p->max_numparam,
+ /*cval*/c.val);
local_push(p, 0);
p->cur_arg = 0;
p->ctxt.in_def = 1;
- p->ctxt.in_rescue = before_rescue;
- $$ = $1;
- }
- ;
-
-defn_head : k_def def_name
- {
- $$ = def_head_save(p, $k_def);
- $$->nd_mid = $def_name;
+ $<node>$ = NEW_NODE(NODE_SELF, /*vid*/cur_arg, /*mid*/fname, /*args*/save, &@$);
/*%%%*/
- $$->nd_def = NEW_DEFN($def_name, 0, &@$);
/*%
- add_mark_object(p, $def_name);
- %*/
+ $$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC);
+ %*/
}
;
+defn_head : k_def def_name
+ {
+ $$ = $2;
+ /*%%%*/
+ $$ = NEW_NODE(NODE_DEFN, 0, $$->nd_mid, $$, &@$);
+ /*% %*/
+ }
+ ;
+
defs_head : k_def singleton dot_or_colon
- {
- SET_LEX_STATE(EXPR_FNAME);
- p->ctxt.in_argdef = 1;
- }
- def_name
- {
- SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */
- $$ = def_head_save(p, $k_def);
- $$->nd_mid = $def_name;
- /*%%%*/
- $$->nd_def = NEW_DEFS($singleton, $def_name, 0, &@$);
- /*%
- add_mark_object(p, $def_name);
- $$->nd_recv = add_mark_object(p, $singleton);
- $$->dot_or_colon = add_mark_object(p, $dot_or_colon);
- %*/
- }
- ;
+ {
+ SET_LEX_STATE(EXPR_FNAME);
+ p->ctxt.in_argdef = 1;
+ }
+ def_name
+ {
+ SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */
+ $$ = $5;
+ /*%%%*/
+ $$ = NEW_NODE(NODE_DEFS, $2, $$->nd_mid, $$, &@$);
+ /*%
+ VALUE ary = rb_ary_new_from_args(3, $2, $3, get_value($$));
+ add_mark_object(p, ary);
+ $<node>$->nd_rval = ary;
+ %*/
+ }
+ ;
expr_value : expr
- {
- value_expr($1);
- $$ = $1;
- }
- | error
- {
- /*%%%*/
- $$ = NEW_ERROR(&@$);
- /*% %*/
- }
- ;
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ | error
+ {
+ /*%%%*/
+ $$ = NEW_ERROR(&@$);
+ /*% %*/
+ }
+ ;
expr_value_do : {COND_PUSH(1);} expr_value do {COND_POP();}
- {
- $$ = $2;
- }
- ;
+ {
+ $$ = $2;
+ }
+ ;
command_call : command
- | block_command
- ;
+ | block_command
+ ;
block_command : block_call
- | block_call call_op2 operation2 command_args
- {
- /*%%%*/
- $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
- /*% %*/
- /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
- }
- ;
+ | block_call call_op2 operation2 command_args
+ {
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
+ }
+ ;
cmd_brace_block : tLBRACE_ARG brace_body '}'
- {
- $$ = $2;
- /*%%%*/
- set_embraced_location($$, &@1, &@3);
- /*% %*/
- }
- ;
+ {
+ $$ = $2;
+ /*%%%*/
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ }
+ ;
fcall : operation
- {
- /*%%%*/
- $$ = NEW_FCALL($1, 0, &@$);
- /*% %*/
- /*% ripper: $1 %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_FCALL($1, 0, &@$);
+ nd_set_line($$, p->tokline);
+ /*% %*/
+ /*% ripper: $1 %*/
+ }
+ ;
command : fcall command_args %prec tLOWEST
- {
- /*%%%*/
- $1->nd_args = $2;
- nd_set_last_loc($1, @2.end_pos);
- $$ = (NODE *)$1;
- /*% %*/
- /*% ripper: command!($1, $2) %*/
- }
- | fcall command_args cmd_brace_block
- {
- /*%%%*/
- block_dup_check(p, $2, $3);
- $1->nd_args = $2;
- $$ = method_add_block(p, (NODE *)$1, $3, &@$);
- fixpos($$, RNODE($1));
- nd_set_last_loc($1, @2.end_pos);
- /*% %*/
- /*% ripper: method_add_block!(command!($1, $2), $3) %*/
- }
- | primary_value call_op operation2 command_args %prec tLOWEST
- {
- /*%%%*/
- $$ = new_command_qcall(p, $2, $1, $3, $4, Qnull, &@3, &@$);
- /*% %*/
- /*% ripper: command_call!($1, $2, $3, $4) %*/
- }
- | primary_value call_op operation2 command_args cmd_brace_block
- {
- /*%%%*/
- $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
- /*% %*/
- /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
- }
- | primary_value tCOLON2 operation2 command_args %prec tLOWEST
- {
- /*%%%*/
- $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, Qnull, &@3, &@$);
- /*% %*/
- /*% ripper: command_call!($1, $2, $3, $4) %*/
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- /*%%%*/
- $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, $5, &@3, &@$);
- /*% %*/
- /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
- }
- | primary_value tCOLON2 tCONSTANT '{' brace_body '}'
- {
- /*%%%*/
- set_embraced_location($5, &@4, &@6);
- $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, Qnull, $5, &@3, &@$);
- /*% %*/
- /*% ripper: method_add_block!(command_call!($1, $2, $3, Qnull), $5) %*/
- }
- | keyword_super command_args
- {
- /*%%%*/
- $$ = NEW_SUPER($2, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: super!($2) %*/
- }
- | k_yield command_args
- {
- /*%%%*/
- $$ = new_yield(p, $2, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: yield!($2) %*/
- }
- | k_return call_args
- {
- /*%%%*/
- $$ = NEW_RETURN(ret_args(p, $2), &@$);
- /*% %*/
- /*% ripper: return!($2) %*/
- }
- | keyword_break call_args
- {
- NODE *args = 0;
- /*%%%*/
- args = ret_args(p, $2);
- /*% %*/
- $<node>$ = add_block_exit(p, NEW_BREAK(args, &@$));
- /*% ripper: break!($2) %*/
- }
- | keyword_next call_args
- {
- NODE *args = 0;
- /*%%%*/
- args = ret_args(p, $2);
- /*% %*/
- $<node>$ = add_block_exit(p, NEW_NEXT(args, &@$));
- /*% ripper: next!($2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $1->nd_args = $2;
+ nd_set_last_loc($1, @2.end_pos);
+ $$ = $1;
+ /*% %*/
+ /*% ripper: command!($1, $2) %*/
+ }
+ | fcall command_args cmd_brace_block
+ {
+ /*%%%*/
+ block_dup_check(p, $2, $3);
+ $1->nd_args = $2;
+ $$ = method_add_block(p, $1, $3, &@$);
+ fixpos($$, $1);
+ nd_set_last_loc($1, @2.end_pos);
+ /*% %*/
+ /*% ripper: method_add_block!(command!($1, $2), $3) %*/
+ }
+ | primary_value call_op operation2 command_args %prec tLOWEST
+ {
+ /*%%%*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, Qnull, &@3, &@$);
+ /*% %*/
+ /*% ripper: command_call!($1, $2, $3, $4) %*/
+ }
+ | primary_value call_op operation2 command_args cmd_brace_block
+ {
+ /*%%%*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
+ }
+ | primary_value tCOLON2 operation2 command_args %prec tLOWEST
+ {
+ /*%%%*/
+ $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, Qnull, &@3, &@$);
+ /*% %*/
+ /*% ripper: command_call!($1, $2, $3, $4) %*/
+ }
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
+ {
+ /*%%%*/
+ $$ = new_command_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
+ }
+ | keyword_super command_args
+ {
+ /*%%%*/
+ $$ = NEW_SUPER($2, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: super!($2) %*/
+ }
+ | keyword_yield command_args
+ {
+ /*%%%*/
+ $$ = new_yield(p, $2, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: yield!($2) %*/
+ }
+ | k_return call_args
+ {
+ /*%%%*/
+ $$ = NEW_RETURN(ret_args(p, $2), &@$);
+ /*% %*/
+ /*% ripper: return!($2) %*/
+ }
+ | keyword_break call_args
+ {
+ /*%%%*/
+ $$ = NEW_BREAK(ret_args(p, $2), &@$);
+ /*% %*/
+ /*% ripper: break!($2) %*/
+ }
+ | keyword_next call_args
+ {
+ /*%%%*/
+ $$ = NEW_NEXT(ret_args(p, $2), &@$);
+ /*% %*/
+ /*% ripper: next!($2) %*/
+ }
+ ;
mlhs : mlhs_basic
- | tLPAREN mlhs_inner rparen
- {
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: mlhs_paren!($2) %*/
- }
- ;
+ | tLPAREN mlhs_inner rparen
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
+ }
+ ;
mlhs_inner : mlhs_basic
- | tLPAREN mlhs_inner rparen
- {
- /*%%%*/
- $$ = NEW_MASGN(NEW_LIST((NODE *)$2, &@$), 0, &@$);
- /*% %*/
- /*% ripper: mlhs_paren!($2) %*/
- }
- ;
+ | tLPAREN mlhs_inner rparen
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(NEW_LIST($2, &@$), 0, &@$);
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
+ }
+ ;
mlhs_basic : mlhs_head
- {
- /*%%%*/
- $$ = NEW_MASGN($1, 0, &@$);
- /*% %*/
- /*% ripper: $1 %*/
- }
- | mlhs_head mlhs_item
- {
- /*%%%*/
- $$ = NEW_MASGN(list_append(p, $1, $2), 0, &@$);
- /*% %*/
- /*% ripper: mlhs_add!($1, $2) %*/
- }
- | mlhs_head tSTAR mlhs_node
- {
- /*%%%*/
- $$ = NEW_MASGN($1, $3, &@$);
- /*% %*/
- /*% ripper: mlhs_add_star!($1, $3) %*/
- }
- | mlhs_head tSTAR mlhs_node ',' mlhs_post
- {
- /*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG($3,$5,&@$), &@$);
- /*% %*/
- /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
- }
- | mlhs_head tSTAR
- {
- /*%%%*/
- $$ = NEW_MASGN($1, NODE_SPECIAL_NO_NAME_REST, &@$);
- /*% %*/
- /*% ripper: mlhs_add_star!($1, Qnil) %*/
- }
- | mlhs_head tSTAR ',' mlhs_post
- {
- /*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG(NODE_SPECIAL_NO_NAME_REST, $4, &@$), &@$);
- /*% %*/
- /*% ripper: mlhs_add_post!(mlhs_add_star!($1, Qnil), $4) %*/
- }
- | tSTAR mlhs_node
- {
- /*%%%*/
- $$ = NEW_MASGN(0, $2, &@$);
- /*% %*/
- /*% ripper: mlhs_add_star!(mlhs_new!, $2) %*/
- }
- | tSTAR mlhs_node ',' mlhs_post
- {
- /*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG($2,$4,&@$), &@$);
- /*% %*/
- /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $2), $4) %*/
- }
- | tSTAR
- {
- /*%%%*/
- $$ = NEW_MASGN(0, NODE_SPECIAL_NO_NAME_REST, &@$);
- /*% %*/
- /*% ripper: mlhs_add_star!(mlhs_new!, Qnil) %*/
- }
- | tSTAR ',' mlhs_post
- {
- /*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG(NODE_SPECIAL_NO_NAME_REST, $3, &@$), &@$);
- /*% %*/
- /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, Qnil), $3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, 0, &@$);
+ /*% %*/
+ /*% ripper: $1 %*/
+ }
+ | mlhs_head mlhs_item
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(list_append(p, $1,$2), 0, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $2) %*/
+ }
+ | mlhs_head tSTAR mlhs_node
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, $3, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!($1, $3) %*/
+ }
+ | mlhs_head tSTAR mlhs_node ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, NEW_POSTARG($3,$5,&@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
+ }
+ | mlhs_head tSTAR
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, NODE_SPECIAL_NO_NAME_REST, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!($1, Qnil) %*/
+ }
+ | mlhs_head tSTAR ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, NEW_POSTARG(NODE_SPECIAL_NO_NAME_REST, $4, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!($1, Qnil), $4) %*/
+ }
+ | tSTAR mlhs_node
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, $2, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!(mlhs_new!, $2) %*/
+ }
+ | tSTAR mlhs_node ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG($2,$4,&@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $2), $4) %*/
+ }
+ | tSTAR
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NODE_SPECIAL_NO_NAME_REST, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!(mlhs_new!, Qnil) %*/
+ }
+ | tSTAR ',' mlhs_post
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG(NODE_SPECIAL_NO_NAME_REST, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, Qnil), $3) %*/
+ }
+ ;
mlhs_item : mlhs_node
- | tLPAREN mlhs_inner rparen
- {
- /*%%%*/
- $$ = (NODE *)$2;
- /*% %*/
- /*% ripper: mlhs_paren!($2) %*/
- }
- ;
+ | tLPAREN mlhs_inner rparen
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
+ }
+ ;
mlhs_head : mlhs_item ','
- {
- /*%%%*/
- $$ = NEW_LIST($1, &@1);
- /*% %*/
- /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
- }
- | mlhs_head mlhs_item ','
- {
- /*%%%*/
- $$ = list_append(p, $1, $2);
- /*% %*/
- /*% ripper: mlhs_add!($1, $2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1, &@1);
+ /*% %*/
+ /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
+ }
+ | mlhs_head mlhs_item ','
+ {
+ /*%%%*/
+ $$ = list_append(p, $1, $2);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $2) %*/
+ }
+ ;
mlhs_post : mlhs_item
- {
- /*%%%*/
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
- }
- | mlhs_post ',' mlhs_item
- {
- /*%%%*/
- $$ = list_append(p, $1, $3);
- /*% %*/
- /*% ripper: mlhs_add!($1, $3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
+ }
+ | mlhs_post ',' mlhs_item
+ {
+ /*%%%*/
+ $$ = list_append(p, $1, $3);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $3) %*/
+ }
+ ;
mlhs_node : user_variable
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- | keyword_variable
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- | primary_value '[' opt_call_args rbracket
- {
- /*%%%*/
- $$ = aryset(p, $1, $3, &@$);
- /*% %*/
- /*% ripper: aref_field!($1, $3) %*/
- }
- | primary_value call_op tIDENTIFIER
- {
- anddot_multiple_assignment_check(p, &@2, $2);
- /*%%%*/
- $$ = attrset(p, $1, $2, $3, &@$);
- /*% %*/
- /*% ripper: field!($1, $2, $3) %*/
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- /*%%%*/
- $$ = attrset(p, $1, idCOLON2, $3, &@$);
- /*% %*/
- /*% ripper: const_path_field!($1, $3) %*/
- }
- | primary_value call_op tCONSTANT
- {
- anddot_multiple_assignment_check(p, &@2, $2);
- /*%%%*/
- $$ = attrset(p, $1, $2, $3, &@$);
- /*% %*/
- /*% ripper: field!($1, $2, $3) %*/
- }
- | primary_value tCOLON2 tCONSTANT
- {
- /*%%%*/
- $$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
- /*% %*/
- /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
- }
- | tCOLON3 tCONSTANT
- {
- /*%%%*/
- $$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
- /*% %*/
- /*% ripper: const_decl(p, top_const_field!($2)) %*/
- }
- | backref
- {
- /*%%%*/
- rb_backref_error(p, $1);
- $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ | keyword_variable
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ | primary_value '[' opt_call_args rbracket
+ {
+ /*%%%*/
+ $$ = aryset(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
+ }
+ | primary_value call_op tIDENTIFIER
+ {
+ if ($2 == tANDDOT) {
+ yyerror1(&@2, "&. inside multiple assignment destination");
+ }
+ /*%%%*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
+ }
+ | primary_value tCOLON2 tIDENTIFIER
+ {
+ /*%%%*/
+ $$ = attrset(p, $1, idCOLON2, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_field!($1, $3) %*/
+ }
+ | primary_value call_op tCONSTANT
+ {
+ if ($2 == tANDDOT) {
+ yyerror1(&@2, "&. inside multiple assignment destination");
+ }
+ /*%%%*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
+ }
+ | primary_value tCOLON2 tCONSTANT
+ {
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
+ }
+ | tCOLON3 tCONSTANT
+ {
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, top_const_field!($2)) %*/
+ }
+ | backref
+ {
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
+ }
+ ;
lhs : user_variable
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- | keyword_variable
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- | primary_value '[' opt_call_args rbracket
- {
- /*%%%*/
- $$ = aryset(p, $1, $3, &@$);
- /*% %*/
- /*% ripper: aref_field!($1, $3) %*/
- }
- | primary_value call_op tIDENTIFIER
- {
- /*%%%*/
- $$ = attrset(p, $1, $2, $3, &@$);
- /*% %*/
- /*% ripper: field!($1, $2, $3) %*/
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- /*%%%*/
- $$ = attrset(p, $1, idCOLON2, $3, &@$);
- /*% %*/
- /*% ripper: field!($1, $2, $3) %*/
- }
- | primary_value call_op tCONSTANT
- {
- /*%%%*/
- $$ = attrset(p, $1, $2, $3, &@$);
- /*% %*/
- /*% ripper: field!($1, $2, $3) %*/
- }
- | primary_value tCOLON2 tCONSTANT
- {
- /*%%%*/
- $$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
- /*% %*/
- /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
- }
- | tCOLON3 tCONSTANT
- {
- /*%%%*/
- $$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
- /*% %*/
- /*% ripper: const_decl(p, top_const_field!($2)) %*/
- }
- | backref
- {
- /*%%%*/
- rb_backref_error(p, $1);
- $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ | keyword_variable
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ | primary_value '[' opt_call_args rbracket
+ {
+ /*%%%*/
+ $$ = aryset(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
+ }
+ | primary_value call_op tIDENTIFIER
+ {
+ /*%%%*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
+ }
+ | primary_value tCOLON2 tIDENTIFIER
+ {
+ /*%%%*/
+ $$ = attrset(p, $1, idCOLON2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
+ }
+ | primary_value call_op tCONSTANT
+ {
+ /*%%%*/
+ $$ = attrset(p, $1, $2, $3, &@$);
+ /*% %*/
+ /*% ripper: field!($1, $2, $3) %*/
+ }
+ | primary_value tCOLON2 tCONSTANT
+ {
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
+ }
+ | tCOLON3 tCONSTANT
+ {
+ /*%%%*/
+ $$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
+ /*% %*/
+ /*% ripper: const_decl(p, top_const_field!($2)) %*/
+ }
+ | backref
+ {
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
+ }
+ ;
cname : tIDENTIFIER
- {
- static const char mesg[] = "class/module name must be CONSTANT";
- /*%%%*/
- yyerror1(&@1, mesg);
- /*% %*/
- /*% ripper[error]: class_name_error!(ERR_MESG(), $1) %*/
- }
- | tCONSTANT
- ;
+ {
+ static const char mesg[] = "class/module name must be CONSTANT";
+ /*%%%*/
+ yyerror1(&@1, mesg);
+ /*% %*/
+ /*% ripper[error]: class_name_error!(ERR_MESG(), $1) %*/
+ }
+ | tCONSTANT
+ ;
cpath : tCOLON3 cname
- {
- /*%%%*/
- $$ = NEW_COLON3($2, &@$);
- /*% %*/
- /*% ripper: top_const_ref!($2) %*/
- }
- | cname
- {
- /*%%%*/
- $$ = NEW_COLON2(0, $1, &@$);
- /*% %*/
- /*% ripper: const_ref!($1) %*/
- }
- | primary_value tCOLON2 cname
- {
- /*%%%*/
- $$ = NEW_COLON2($1, $3, &@$);
- /*% %*/
- /*% ripper: const_path_ref!($1, $3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_COLON3($2, &@$);
+ /*% %*/
+ /*% ripper: top_const_ref!($2) %*/
+ }
+ | cname
+ {
+ /*%%%*/
+ $$ = NEW_COLON2(0, $$, &@$);
+ /*% %*/
+ /*% ripper: const_ref!($1) %*/
+ }
+ | primary_value tCOLON2 cname
+ {
+ /*%%%*/
+ $$ = NEW_COLON2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_ref!($1, $3) %*/
+ }
+ ;
fname : tIDENTIFIER
- | tCONSTANT
- | tFID
- | op
- {
- SET_LEX_STATE(EXPR_ENDFN);
- $$ = $1;
- }
- | reswords
- ;
+ | tCONSTANT
+ | tFID
+ | op
+ {
+ SET_LEX_STATE(EXPR_ENDFN);
+ $$ = $1;
+ }
+ | reswords
+ ;
fitem : fname
- {
- /*%%%*/
- $$ = NEW_LIT(ID2SYM($1), &@$);
- /*% %*/
- /*% ripper: symbol_literal!($1) %*/
- }
- | symbol
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIT(ID2SYM($1), &@$);
+ /*% %*/
+ /*% ripper: symbol_literal!($1) %*/
+ }
+ | symbol
+ ;
undef_list : fitem
- {
- /*%%%*/
- $$ = NEW_UNDEF($1, &@$);
- /*% %*/
- /*% ripper: rb_ary_new3(1, get_value($1)) %*/
- }
- | undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
- {
- /*%%%*/
- NODE *undef = NEW_UNDEF($4, &@4);
- $$ = block_append(p, $1, undef);
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($4)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_UNDEF($1, &@$);
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
+ }
+ | undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
+ {
+ /*%%%*/
+ NODE *undef = NEW_UNDEF($4, &@4);
+ $$ = block_append(p, $1, undef);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($4)) %*/
+ }
+ ;
op : '|' { ifndef_ripper($$ = '|'); }
- | '^' { ifndef_ripper($$ = '^'); }
- | '&' { ifndef_ripper($$ = '&'); }
- | tCMP { ifndef_ripper($$ = tCMP); }
- | tEQ { ifndef_ripper($$ = tEQ); }
- | tEQQ { ifndef_ripper($$ = tEQQ); }
- | tMATCH { ifndef_ripper($$ = tMATCH); }
- | tNMATCH { ifndef_ripper($$ = tNMATCH); }
- | '>' { ifndef_ripper($$ = '>'); }
- | tGEQ { ifndef_ripper($$ = tGEQ); }
- | '<' { ifndef_ripper($$ = '<'); }
- | tLEQ { ifndef_ripper($$ = tLEQ); }
- | tNEQ { ifndef_ripper($$ = tNEQ); }
- | tLSHFT { ifndef_ripper($$ = tLSHFT); }
- | tRSHFT { ifndef_ripper($$ = tRSHFT); }
- | '+' { ifndef_ripper($$ = '+'); }
- | '-' { ifndef_ripper($$ = '-'); }
- | '*' { ifndef_ripper($$ = '*'); }
- | tSTAR { ifndef_ripper($$ = '*'); }
- | '/' { ifndef_ripper($$ = '/'); }
- | '%' { ifndef_ripper($$ = '%'); }
- | tPOW { ifndef_ripper($$ = tPOW); }
- | tDSTAR { ifndef_ripper($$ = tDSTAR); }
- | '!' { ifndef_ripper($$ = '!'); }
- | '~' { ifndef_ripper($$ = '~'); }
- | tUPLUS { ifndef_ripper($$ = tUPLUS); }
- | tUMINUS { ifndef_ripper($$ = tUMINUS); }
- | tAREF { ifndef_ripper($$ = tAREF); }
- | tASET { ifndef_ripper($$ = tASET); }
- | '`' { ifndef_ripper($$ = '`'); }
- ;
+ | '^' { ifndef_ripper($$ = '^'); }
+ | '&' { ifndef_ripper($$ = '&'); }
+ | tCMP { ifndef_ripper($$ = tCMP); }
+ | tEQ { ifndef_ripper($$ = tEQ); }
+ | tEQQ { ifndef_ripper($$ = tEQQ); }
+ | tMATCH { ifndef_ripper($$ = tMATCH); }
+ | tNMATCH { ifndef_ripper($$ = tNMATCH); }
+ | '>' { ifndef_ripper($$ = '>'); }
+ | tGEQ { ifndef_ripper($$ = tGEQ); }
+ | '<' { ifndef_ripper($$ = '<'); }
+ | tLEQ { ifndef_ripper($$ = tLEQ); }
+ | tNEQ { ifndef_ripper($$ = tNEQ); }
+ | tLSHFT { ifndef_ripper($$ = tLSHFT); }
+ | tRSHFT { ifndef_ripper($$ = tRSHFT); }
+ | '+' { ifndef_ripper($$ = '+'); }
+ | '-' { ifndef_ripper($$ = '-'); }
+ | '*' { ifndef_ripper($$ = '*'); }
+ | tSTAR { ifndef_ripper($$ = '*'); }
+ | '/' { ifndef_ripper($$ = '/'); }
+ | '%' { ifndef_ripper($$ = '%'); }
+ | tPOW { ifndef_ripper($$ = tPOW); }
+ | tDSTAR { ifndef_ripper($$ = tDSTAR); }
+ | '!' { ifndef_ripper($$ = '!'); }
+ | '~' { ifndef_ripper($$ = '~'); }
+ | tUPLUS { ifndef_ripper($$ = tUPLUS); }
+ | tUMINUS { ifndef_ripper($$ = tUMINUS); }
+ | tAREF { ifndef_ripper($$ = tAREF); }
+ | tASET { ifndef_ripper($$ = tASET); }
+ | '`' { ifndef_ripper($$ = '`'); }
+ ;
reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
- | keyword_BEGIN | keyword_END
- | keyword_alias | keyword_and | keyword_begin
- | keyword_break | keyword_case | keyword_class | keyword_def
- | keyword_defined | keyword_do | keyword_else | keyword_elsif
- | keyword_end | keyword_ensure | keyword_false
- | keyword_for | keyword_in | keyword_module | keyword_next
- | keyword_nil | keyword_not | keyword_or | keyword_redo
- | keyword_rescue | keyword_retry | keyword_return | keyword_self
- | keyword_super | keyword_then | keyword_true | keyword_undef
- | keyword_when | keyword_yield | keyword_if | keyword_unless
- | keyword_while | keyword_until
- ;
+ | keyword_BEGIN | keyword_END
+ | keyword_alias | keyword_and | keyword_begin
+ | keyword_break | keyword_case | keyword_class | keyword_def
+ | keyword_defined | keyword_do | keyword_else | keyword_elsif
+ | keyword_end | keyword_ensure | keyword_false
+ | keyword_for | keyword_in | keyword_module | keyword_next
+ | keyword_nil | keyword_not | keyword_or | keyword_redo
+ | keyword_rescue | keyword_retry | keyword_return | keyword_self
+ | keyword_super | keyword_then | keyword_true | keyword_undef
+ | keyword_when | keyword_yield | keyword_if | keyword_unless
+ | keyword_while | keyword_until
+ ;
arg : lhs '=' lex_ctxt arg_rhs
- {
- /*%%%*/
- $$ = node_assign(p, $1, $4, $3, &@$);
- /*% %*/
- /*% ripper: assign!($1, $4) %*/
- }
- | var_lhs tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- $$ = new_op_assign(p, $1, $2, $4, $3, &@$);
- /*% %*/
- /*% ripper: opassign!($1, $2, $4) %*/
- }
- | primary_value '[' opt_call_args rbracket tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$);
- /*% %*/
- /*% ripper: opassign!(aref_field!($1, $3), $5, $7) %*/
- }
- | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
- /*% %*/
- /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
- }
- | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
- /*% %*/
- /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $6, &@$);
- /*% %*/
- /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- YYLTYPE loc = code_loc_gen(&@1, &@3);
- $$ = new_const_op_assign(p, NEW_COLON2($1, $3, &loc), $4, $6, $5, &@$);
- /*% %*/
- /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
- }
- | tCOLON3 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- YYLTYPE loc = code_loc_gen(&@1, &@2);
- $$ = new_const_op_assign(p, NEW_COLON3($2, &loc), $3, $5, $4, &@$);
- /*% %*/
- /*% ripper: opassign!(top_const_field!($2), $3, $5) %*/
- }
- | backref tOP_ASGN lex_ctxt arg_rhs
- {
- /*%%%*/
- rb_backref_error(p, $1);
- $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper[error]: backref_error(p, RNODE($1), opassign!(var_field(p, $1), $2, $4)) %*/
- }
- | arg tDOT2 arg
- {
- /*%%%*/
- value_expr($1);
- value_expr($3);
- $$ = NEW_DOT2($1, $3, &@$);
- /*% %*/
- /*% ripper: dot2!($1, $3) %*/
- }
- | arg tDOT3 arg
- {
- /*%%%*/
- value_expr($1);
- value_expr($3);
- $$ = NEW_DOT3($1, $3, &@$);
- /*% %*/
- /*% ripper: dot3!($1, $3) %*/
- }
- | arg tDOT2
- {
- /*%%%*/
- value_expr($1);
- $$ = NEW_DOT2($1, new_nil_at(p, &@2.end_pos), &@$);
- /*% %*/
- /*% ripper: dot2!($1, Qnil) %*/
- }
- | arg tDOT3
- {
- /*%%%*/
- value_expr($1);
- $$ = NEW_DOT3($1, new_nil_at(p, &@2.end_pos), &@$);
- /*% %*/
- /*% ripper: dot3!($1, Qnil) %*/
- }
- | tBDOT2 arg
- {
- /*%%%*/
- value_expr($2);
- $$ = NEW_DOT2(new_nil_at(p, &@1.beg_pos), $2, &@$);
- /*% %*/
- /*% ripper: dot2!(Qnil, $2) %*/
- }
- | tBDOT3 arg
- {
- /*%%%*/
- value_expr($2);
- $$ = NEW_DOT3(new_nil_at(p, &@1.beg_pos), $2, &@$);
- /*% %*/
- /*% ripper: dot3!(Qnil, $2) %*/
- }
- | arg '+' arg
- {
- $$ = call_bin_op(p, $1, '+', $3, &@2, &@$);
- }
- | arg '-' arg
- {
- $$ = call_bin_op(p, $1, '-', $3, &@2, &@$);
- }
- | arg '*' arg
- {
- $$ = call_bin_op(p, $1, '*', $3, &@2, &@$);
- }
- | arg '/' arg
- {
- $$ = call_bin_op(p, $1, '/', $3, &@2, &@$);
- }
- | arg '%' arg
- {
- $$ = call_bin_op(p, $1, '%', $3, &@2, &@$);
- }
- | arg tPOW arg
- {
- $$ = call_bin_op(p, $1, idPow, $3, &@2, &@$);
- }
- | tUMINUS_NUM simple_numeric tPOW arg
- {
- $$ = call_uni_op(p, call_bin_op(p, $2, idPow, $4, &@2, &@$), idUMinus, &@1, &@$);
- }
- | tUPLUS arg
- {
- $$ = call_uni_op(p, $2, idUPlus, &@1, &@$);
- }
- | tUMINUS arg
- {
- $$ = call_uni_op(p, $2, idUMinus, &@1, &@$);
- }
- | arg '|' arg
- {
- $$ = call_bin_op(p, $1, '|', $3, &@2, &@$);
- }
- | arg '^' arg
- {
- $$ = call_bin_op(p, $1, '^', $3, &@2, &@$);
- }
- | arg '&' arg
- {
- $$ = call_bin_op(p, $1, '&', $3, &@2, &@$);
- }
- | arg tCMP arg
- {
- $$ = call_bin_op(p, $1, idCmp, $3, &@2, &@$);
- }
- | rel_expr %prec tCMP
- | arg tEQ arg
- {
- $$ = call_bin_op(p, $1, idEq, $3, &@2, &@$);
- }
- | arg tEQQ arg
- {
- $$ = call_bin_op(p, $1, idEqq, $3, &@2, &@$);
- }
- | arg tNEQ arg
- {
- $$ = call_bin_op(p, $1, idNeq, $3, &@2, &@$);
- }
- | arg tMATCH arg
- {
- $$ = match_op(p, $1, $3, &@2, &@$);
- }
- | arg tNMATCH arg
- {
- $$ = call_bin_op(p, $1, idNeqTilde, $3, &@2, &@$);
- }
- | '!' arg
- {
- $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
- }
- | '~' arg
- {
- $$ = call_uni_op(p, $2, '~', &@1, &@$);
- }
- | arg tLSHFT arg
- {
- $$ = call_bin_op(p, $1, idLTLT, $3, &@2, &@$);
- }
- | arg tRSHFT arg
- {
- $$ = call_bin_op(p, $1, idGTGT, $3, &@2, &@$);
- }
- | arg tANDOP arg
- {
- $$ = logop(p, idANDOP, $1, $3, &@2, &@$);
- }
- | arg tOROP arg
- {
- $$ = logop(p, idOROP, $1, $3, &@2, &@$);
- }
- | keyword_defined opt_nl begin_defined arg
- {
- p->ctxt.in_defined = $3.in_defined;
- $$ = new_defined(p, $4, &@$);
- }
- | arg '?' arg opt_nl ':' arg
- {
- /*%%%*/
- value_expr($1);
- $$ = new_if(p, $1, $3, $6, &@$);
- fixpos($$, $1);
- /*% %*/
- /*% ripper: ifop!($1, $3, $6) %*/
- }
- | defn_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt]
- {
- endless_method_name(p, get_id($head->nd_mid), &@head);
- restore_defun(p, $head);
- /*%%%*/
- $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
- ($$ = $head->nd_def)->nd_loc = @$;
- RNODE_DEFN($$)->nd_defn = $bodystmt;
- /*% %*/
- /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
- /*% ripper: def!($head->nd_mid, $args, $bodystmt) %*/
- local_pop(p);
- }
- | defs_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt]
- {
- endless_method_name(p, get_id($head->nd_mid), &@head);
- restore_defun(p, $head);
- /*%%%*/
- $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
- ($$ = $head->nd_def)->nd_loc = @$;
- RNODE_DEFS($$)->nd_defn = $bodystmt;
- /*% %*/
- /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
- /*% ripper: defs!($head->nd_recv, $head->dot_or_colon, $head->nd_mid, $args, $bodystmt) %*/
- local_pop(p);
- }
- | primary
- {
- $$ = $1;
- }
- ;
-
-endless_arg : arg %prec modifier_rescue
- | endless_arg modifier_rescue after_rescue arg
- {
- p->ctxt.in_rescue = $3.in_rescue;
- /*%%%*/
- $$ = rescued_expr(p, $1, $4, &@1, &@2, &@4);
- /*% %*/
- /*% ripper: rescue_mod!($1, $4) %*/
- }
- | keyword_not opt_nl endless_arg
- {
- $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
- }
- ;
+ {
+ /*%%%*/
+ $$ = node_assign(p, $1, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: assign!($1, $4) %*/
+ }
+ | var_lhs tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ $$ = new_op_assign(p, $1, $2, $4, $3, &@$);
+ /*% %*/
+ /*% ripper: opassign!($1, $2, $4) %*/
+ }
+ | primary_value '[' opt_call_args rbracket tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$);
+ /*% %*/
+ /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
+ }
+ | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
+ }
+ | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, $2, $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
+ }
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $6, &@$);
+ /*% %*/
+ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
+ }
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ $$ = new_const_op_assign(p, NEW_COLON2($1, $3, &loc), $4, $6, $5, &@$);
+ /*% %*/
+ /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
+ }
+ | tCOLON3 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@1, &@2);
+ $$ = new_const_op_assign(p, NEW_COLON3($2, &loc), $3, $5, $4, &@$);
+ /*% %*/
+ /*% ripper: opassign!(top_const_field!($2), $3, $5) %*/
+ }
+ | backref tOP_ASGN lex_ctxt arg_rhs
+ {
+ /*%%%*/
+ rb_backref_error(p, $1);
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper[error]: backref_error(p, RNODE($1), opassign!(var_field(p, $1), $2, $4)) %*/
+ }
+ | arg tDOT2 arg
+ {
+ /*%%%*/
+ value_expr($1);
+ value_expr($3);
+ $$ = NEW_DOT2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, $3) %*/
+ }
+ | arg tDOT3 arg
+ {
+ /*%%%*/
+ value_expr($1);
+ value_expr($3);
+ $$ = NEW_DOT3($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, $3) %*/
+ }
+ | arg tDOT2
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT2($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, Qnil) %*/
+ }
+ | arg tDOT3
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT3($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, Qnil) %*/
+ }
+ | tBDOT2 arg
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT2(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot2!(Qnil, $2) %*/
+ }
+ | tBDOT3 arg
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT3(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot3!(Qnil, $2) %*/
+ }
+ | arg '+' arg
+ {
+ $$ = call_bin_op(p, $1, '+', $3, &@2, &@$);
+ }
+ | arg '-' arg
+ {
+ $$ = call_bin_op(p, $1, '-', $3, &@2, &@$);
+ }
+ | arg '*' arg
+ {
+ $$ = call_bin_op(p, $1, '*', $3, &@2, &@$);
+ }
+ | arg '/' arg
+ {
+ $$ = call_bin_op(p, $1, '/', $3, &@2, &@$);
+ }
+ | arg '%' arg
+ {
+ $$ = call_bin_op(p, $1, '%', $3, &@2, &@$);
+ }
+ | arg tPOW arg
+ {
+ $$ = call_bin_op(p, $1, idPow, $3, &@2, &@$);
+ }
+ | tUMINUS_NUM simple_numeric tPOW arg
+ {
+ $$ = call_uni_op(p, call_bin_op(p, $2, idPow, $4, &@2, &@$), idUMinus, &@1, &@$);
+ }
+ | tUPLUS arg
+ {
+ $$ = call_uni_op(p, $2, idUPlus, &@1, &@$);
+ }
+ | tUMINUS arg
+ {
+ $$ = call_uni_op(p, $2, idUMinus, &@1, &@$);
+ }
+ | arg '|' arg
+ {
+ $$ = call_bin_op(p, $1, '|', $3, &@2, &@$);
+ }
+ | arg '^' arg
+ {
+ $$ = call_bin_op(p, $1, '^', $3, &@2, &@$);
+ }
+ | arg '&' arg
+ {
+ $$ = call_bin_op(p, $1, '&', $3, &@2, &@$);
+ }
+ | arg tCMP arg
+ {
+ $$ = call_bin_op(p, $1, idCmp, $3, &@2, &@$);
+ }
+ | rel_expr %prec tCMP
+ | arg tEQ arg
+ {
+ $$ = call_bin_op(p, $1, idEq, $3, &@2, &@$);
+ }
+ | arg tEQQ arg
+ {
+ $$ = call_bin_op(p, $1, idEqq, $3, &@2, &@$);
+ }
+ | arg tNEQ arg
+ {
+ $$ = call_bin_op(p, $1, idNeq, $3, &@2, &@$);
+ }
+ | arg tMATCH arg
+ {
+ $$ = match_op(p, $1, $3, &@2, &@$);
+ }
+ | arg tNMATCH arg
+ {
+ $$ = call_bin_op(p, $1, idNeqTilde, $3, &@2, &@$);
+ }
+ | '!' arg
+ {
+ $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
+ }
+ | '~' arg
+ {
+ $$ = call_uni_op(p, $2, '~', &@1, &@$);
+ }
+ | arg tLSHFT arg
+ {
+ $$ = call_bin_op(p, $1, idLTLT, $3, &@2, &@$);
+ }
+ | arg tRSHFT arg
+ {
+ $$ = call_bin_op(p, $1, idGTGT, $3, &@2, &@$);
+ }
+ | arg tANDOP arg
+ {
+ $$ = logop(p, idANDOP, $1, $3, &@2, &@$);
+ }
+ | arg tOROP arg
+ {
+ $$ = logop(p, idOROP, $1, $3, &@2, &@$);
+ }
+ | keyword_defined opt_nl {p->ctxt.in_defined = 1;} arg
+ {
+ p->ctxt.in_defined = 0;
+ $$ = new_defined(p, $4, &@$);
+ }
+ | arg '?' arg opt_nl ':' arg
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = new_if(p, $1, $3, $6, &@$);
+ fixpos($$, $1);
+ /*% %*/
+ /*% ripper: ifop!($1, $3, $6) %*/
+ }
+ | defn_head f_opt_paren_args '=' arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
+ /*% ripper: def!(get_value($1), $2, $4) %*/
+ local_pop(p);
+ }
+ | defn_head f_opt_paren_args '=' arg modifier_rescue arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
+ /*% ripper: def!(get_value($1), $2, $4) %*/
+ local_pop(p);
+ }
+ | defs_head f_opt_paren_args '=' arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*%
+ $1 = get_value($1);
+ %*/
+ /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
+ local_pop(p);
+ }
+ | defs_head f_opt_paren_args '=' arg modifier_rescue arg
+ {
+ endless_method_name(p, $<node>1, &@1);
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*%
+ $1 = get_value($1);
+ %*/
+ /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
+ local_pop(p);
+ }
+ | primary
+ {
+ $$ = $1;
+ }
+ ;
relop : '>' {$$ = '>';}
- | '<' {$$ = '<';}
- | tGEQ {$$ = idGE;}
- | tLEQ {$$ = idLE;}
- ;
+ | '<' {$$ = '<';}
+ | tGEQ {$$ = idGE;}
+ | tLEQ {$$ = idLE;}
+ ;
rel_expr : arg relop arg %prec '>'
- {
- $$ = call_bin_op(p, $1, $2, $3, &@2, &@$);
- }
- | rel_expr relop arg %prec '>'
- {
- rb_warning1("comparison '%s' after comparison", WARN_ID($2));
- $$ = call_bin_op(p, $1, $2, $3, &@2, &@$);
- }
- ;
+ {
+ $$ = call_bin_op(p, $1, $2, $3, &@2, &@$);
+ }
+ | rel_expr relop arg %prec '>'
+ {
+ rb_warning1("comparison '%s' after comparison", WARN_ID($2));
+ $$ = call_bin_op(p, $1, $2, $3, &@2, &@$);
+ }
+ ;
lex_ctxt : none
- {
- $$ = p->ctxt;
- }
- ;
-
-begin_defined : lex_ctxt
- {
- p->ctxt.in_defined = 1;
- $$ = $1;
- }
- ;
-
-after_rescue : lex_ctxt
- {
- p->ctxt.in_rescue = after_rescue;
- $$ = $1;
- }
- ;
+ {
+ $$ = p->ctxt;
+ }
+ ;
arg_value : arg
- {
- value_expr($1);
- $$ = $1;
- }
- ;
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ ;
aref_args : none
- | args trailer
- {
- $$ = $1;
- }
- | args ',' assocs trailer
- {
- /*%%%*/
- $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
- /*% %*/
- /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
- }
- | assocs trailer
- {
- /*%%%*/
- $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@$) : 0;
- /*% %*/
- /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
- }
- ;
+ | args trailer
+ {
+ $$ = $1;
+ }
+ | args ',' assocs trailer
+ {
+ /*%%%*/
+ $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
+ /*% %*/
+ /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
+ }
+ | assocs trailer
+ {
+ /*%%%*/
+ $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@$) : 0;
+ /*% %*/
+ /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
+ }
+ ;
arg_rhs : arg %prec tOP_ASGN
- {
- value_expr($1);
- $$ = $1;
- }
- | arg modifier_rescue after_rescue arg
- {
- p->ctxt.in_rescue = $3.in_rescue;
- /*%%%*/
- value_expr($1);
- $$ = rescued_expr(p, $1, $4, &@1, &@2, &@4);
- /*% %*/
- /*% ripper: rescue_mod!($1, $4) %*/
- }
- ;
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ | arg modifier_rescue arg
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = rescued_expr(p, $1, $3, &@1, &@2, &@3);
+ /*% %*/
+ /*% ripper: rescue_mod!($1, $3) %*/
+ }
+ ;
paren_args : '(' opt_call_args rparen
- {
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: arg_paren!($2) %*/
- }
- | '(' args ',' args_forward rparen
- {
- if (!check_forwarding_args(p)) {
- $$ = Qnone;
- }
- else {
- /*%%%*/
- $$ = new_args_forward_call(p, $2, &@4, &@$);
- /*% %*/
- /*% ripper: arg_paren!(args_add!($2, $4)) %*/
- }
- }
- | '(' args_forward rparen
- {
- if (!check_forwarding_args(p)) {
- $$ = Qnone;
- }
- else {
- /*%%%*/
- $$ = new_args_forward_call(p, 0, &@2, &@$);
- /*% %*/
- /*% ripper: arg_paren!($2) %*/
- }
- }
- ;
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: arg_paren!(escape_Qundef($2)) %*/
+ }
+ | '(' args ',' args_forward rparen
+ {
+ if (!check_forwarding_args(p)) {
+ $$ = Qnone;
+ }
+ else {
+ /*%%%*/
+ $$ = new_args_forward_call(p, $2, &@4, &@$);
+ /*% %*/
+ /*% ripper: arg_paren!(args_add!($2, $4)) %*/
+ }
+ }
+ | '(' args_forward rparen
+ {
+ if (!check_forwarding_args(p)) {
+ $$ = Qnone;
+ }
+ else {
+ /*%%%*/
+ $$ = new_args_forward_call(p, 0, &@2, &@$);
+ /*% %*/
+ /*% ripper: arg_paren!($2) %*/
+ }
+ }
+ ;
opt_paren_args : none
- | paren_args
- ;
+ | paren_args
+ ;
opt_call_args : none
- | call_args
- | args ','
- {
- $$ = $1;
- }
- | args ',' assocs ','
- {
- /*%%%*/
- $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
- /*% %*/
- /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
- }
- | assocs ','
- {
- /*%%%*/
- $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@1) : 0;
- /*% %*/
- /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
- }
- ;
+ | call_args
+ | args ','
+ {
+ $$ = $1;
+ }
+ | args ',' assocs ','
+ {
+ /*%%%*/
+ $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
+ /*% %*/
+ /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
+ }
+ | assocs ','
+ {
+ /*%%%*/
+ $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@1) : 0;
+ /*% %*/
+ /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
+ }
+ ;
call_args : command
- {
- /*%%%*/
- value_expr($1);
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: args_add!(args_new!, $1) %*/
- }
- | args opt_block_arg
- {
- /*%%%*/
- $$ = arg_blk_pass($1, $2);
- /*% %*/
- /*% ripper: args_add_block!($1, $2) %*/
- }
- | assocs opt_block_arg
- {
- /*%%%*/
- $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@1) : 0;
- $$ = arg_blk_pass($$, $2);
- /*% %*/
- /*% ripper: args_add_block!(args_add!(args_new!, bare_assoc_hash!($1)), $2) %*/
- }
- | args ',' assocs opt_block_arg
- {
- /*%%%*/
- $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
- $$ = arg_blk_pass($$, $4);
- /*% %*/
- /*% ripper: args_add_block!(args_add!($1, bare_assoc_hash!($3)), $4) %*/
- }
- | block_arg
- /*% ripper[brace]: args_add_block!(args_new!, $1) %*/
- ;
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: args_add!(args_new!, $1) %*/
+ }
+ | args opt_block_arg
+ {
+ /*%%%*/
+ $$ = arg_blk_pass($1, $2);
+ /*% %*/
+ /*% ripper: args_add_block!($1, $2) %*/
+ }
+ | assocs opt_block_arg
+ {
+ /*%%%*/
+ $$ = $1 ? NEW_LIST(new_hash(p, $1, &@1), &@1) : 0;
+ $$ = arg_blk_pass($$, $2);
+ /*% %*/
+ /*% ripper: args_add_block!(args_add!(args_new!, bare_assoc_hash!($1)), $2) %*/
+ }
+ | args ',' assocs opt_block_arg
+ {
+ /*%%%*/
+ $$ = $3 ? arg_append(p, $1, new_hash(p, $3, &@3), &@$) : $1;
+ $$ = arg_blk_pass($$, $4);
+ /*% %*/
+ /*% ripper: args_add_block!(args_add!($1, bare_assoc_hash!($3)), $4) %*/
+ }
+ | block_arg
+ /*% ripper[brace]: args_add_block!(args_new!, $1) %*/
+ ;
command_args : {
- /* If call_args starts with a open paren '(' or '[',
- * look-ahead reading of the letters calls CMDARG_PUSH(0),
- * but the push must be done after CMDARG_PUSH(1).
- * So this code makes them consistent by first cancelling
- * the premature CMDARG_PUSH(0), doing CMDARG_PUSH(1),
- * and finally redoing CMDARG_PUSH(0).
- */
- int lookahead = 0;
- switch (yychar) {
- case '(': case tLPAREN: case tLPAREN_ARG: case '[': case tLBRACK:
- lookahead = 1;
- }
- if (lookahead) CMDARG_POP();
- CMDARG_PUSH(1);
- if (lookahead) CMDARG_PUSH(0);
- }
- call_args
- {
- /* call_args can be followed by tLBRACE_ARG (that does CMDARG_PUSH(0) in the lexer)
- * but the push must be done after CMDARG_POP() in the parser.
- * So this code does CMDARG_POP() to pop 0 pushed by tLBRACE_ARG,
- * CMDARG_POP() to pop 1 pushed by command_args,
- * and CMDARG_PUSH(0) to restore back the flag set by tLBRACE_ARG.
- */
- int lookahead = 0;
- switch (yychar) {
- case tLBRACE_ARG:
- lookahead = 1;
- }
- if (lookahead) CMDARG_POP();
- CMDARG_POP();
- if (lookahead) CMDARG_PUSH(0);
- $$ = $2;
- }
- ;
+ /* If call_args starts with a open paren '(' or '[',
+ * look-ahead reading of the letters calls CMDARG_PUSH(0),
+ * but the push must be done after CMDARG_PUSH(1).
+ * So this code makes them consistent by first cancelling
+ * the premature CMDARG_PUSH(0), doing CMDARG_PUSH(1),
+ * and finally redoing CMDARG_PUSH(0).
+ */
+ int lookahead = 0;
+ switch (yychar) {
+ case '(': case tLPAREN: case tLPAREN_ARG: case '[': case tLBRACK:
+ lookahead = 1;
+ }
+ if (lookahead) CMDARG_POP();
+ CMDARG_PUSH(1);
+ if (lookahead) CMDARG_PUSH(0);
+ }
+ call_args
+ {
+ /* call_args can be followed by tLBRACE_ARG (that does CMDARG_PUSH(0) in the lexer)
+ * but the push must be done after CMDARG_POP() in the parser.
+ * So this code does CMDARG_POP() to pop 0 pushed by tLBRACE_ARG,
+ * CMDARG_POP() to pop 1 pushed by command_args,
+ * and CMDARG_PUSH(0) to restore back the flag set by tLBRACE_ARG.
+ */
+ int lookahead = 0;
+ switch (yychar) {
+ case tLBRACE_ARG:
+ lookahead = 1;
+ }
+ if (lookahead) CMDARG_POP();
+ CMDARG_POP();
+ if (lookahead) CMDARG_PUSH(0);
+ $$ = $2;
+ }
+ ;
block_arg : tAMPER arg_value
- {
- /*%%%*/
- $$ = NEW_BLOCK_PASS($2, &@$);
- /*% %*/
- /*% ripper: $2 %*/
- }
+ {
+ /*%%%*/
+ $$ = NEW_BLOCK_PASS($2, &@$);
+ /*% %*/
+ /*% ripper: $2 %*/
+ }
| tAMPER
{
- forwarding_arg_check(p, idFWD_BLOCK, 0, "block");
+ if (!local_id(p, idFWD_BLOCK)) {
+ compile_error(p, "no anonymous block parameter");
+ }
/*%%%*/
$$ = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, &@1), &@$);
/*% %*/
/*% ripper: Qnil %*/
}
- ;
+ ;
opt_block_arg : ',' block_arg
- {
- $$ = $2;
- }
- | none
- {
- $$ = 0;
- }
- ;
+ {
+ $$ = $2;
+ }
+ | none
+ {
+ $$ = 0;
+ }
+ ;
/* value */
args : arg_value
- {
- /*%%%*/
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: args_add!(args_new!, $1) %*/
- }
- | arg_splat
- {
- /*%%%*/
- $$ = NEW_SPLAT($arg_splat, &@$);
- /*% %*/
- /*% ripper: args_add_star!(args_new!, $arg_splat) %*/
- }
- | args ',' arg_value
- {
- /*%%%*/
- $$ = last_arg_append(p, $1, $3, &@$);
- /*% %*/
- /*% ripper: args_add!($1, $3) %*/
- }
- | args ',' arg_splat
- {
- /*%%%*/
- $$ = rest_arg_append(p, $1, $3, &@$);
- /*% %*/
- /*% ripper: args_add_star!($1, $3) %*/
- }
- ;
-
-/* value */
-arg_splat : tSTAR arg_value
- {
- $$ = $2;
- }
- | tSTAR /* none */
- {
- forwarding_arg_check(p, idFWD_REST, idFWD_ALL, "rest");
- /*%%%*/
- $$ = NEW_LVAR(idFWD_REST, &@1);
- /*% %*/
- /*% ripper: Qnil %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: args_add!(args_new!, $1) %*/
+ }
+ | tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = NEW_SPLAT($2, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!(args_new!, $2) %*/
+ }
+ | tSTAR
+ {
+ if (!local_id(p, idFWD_REST) ||
+ local_id(p, idFWD_ALL)) {
+ compile_error(p, "no anonymous rest parameter");
+ }
+ /*%%%*/
+ $$ = NEW_SPLAT(NEW_LVAR(idFWD_REST, &@1), &@$);
+ /*% %*/
+ /*% ripper: args_add_star!(args_new!, Qnil) %*/
+ }
+ | args ',' arg_value
+ {
+ /*%%%*/
+ $$ = last_arg_append(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: args_add!($1, $3) %*/
+ }
+ | args ',' tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = rest_arg_append(p, $1, $4, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!($1, $4) %*/
+ }
+ | args ',' tSTAR
+ {
+ if (!local_id(p, idFWD_REST) ||
+ local_id(p, idFWD_ALL)) {
+ compile_error(p, "no anonymous rest parameter");
+ }
+ /*%%%*/
+ $$ = rest_arg_append(p, $1, NEW_LVAR(idFWD_REST, &@3), &@$);
+ /*% %*/
+ /*% ripper: args_add_star!($1, Qnil) %*/
+ }
+ ;
/* value */
mrhs_arg : mrhs
- | arg_value
- ;
+ | arg_value
+ ;
/* value */
mrhs : args ',' arg_value
- {
- /*%%%*/
- $$ = last_arg_append(p, $1, $3, &@$);
- /*% %*/
- /*% ripper: mrhs_add!(mrhs_new_from_args!($1), $3) %*/
- }
- | args ',' tSTAR arg_value
- {
- /*%%%*/
- $$ = rest_arg_append(p, $1, $4, &@$);
- /*% %*/
- /*% ripper: mrhs_add_star!(mrhs_new_from_args!($1), $4) %*/
- }
- | tSTAR arg_value
- {
- /*%%%*/
- $$ = NEW_SPLAT($2, &@$);
- /*% %*/
- /*% ripper: mrhs_add_star!(mrhs_new!, $2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = last_arg_append(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: mrhs_add!(mrhs_new_from_args!($1), $3) %*/
+ }
+ | args ',' tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = rest_arg_append(p, $1, $4, &@$);
+ /*% %*/
+ /*% ripper: mrhs_add_star!(mrhs_new_from_args!($1), $4) %*/
+ }
+ | tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = NEW_SPLAT($2, &@$);
+ /*% %*/
+ /*% ripper: mrhs_add_star!(mrhs_new!, $2) %*/
+ }
+ ;
primary : literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | symbols
- | qsymbols
- | var_ref
- | backref
- | tFID
- {
- /*%%%*/
- $$ = (NODE *)NEW_FCALL($1, 0, &@$);
- /*% %*/
- /*% ripper: method_add_arg!(fcall!($1), args_new!) %*/
- }
- | k_begin
- {
- CMDARG_PUSH(0);
- }
- bodystmt
- k_end
- {
- CMDARG_POP();
- /*%%%*/
- set_line_body($3, @1.end_pos.lineno);
- $$ = NEW_BEGIN($3, &@$);
- nd_set_line($$, @1.end_pos.lineno);
- /*% %*/
- /*% ripper: begin!($3) %*/
- }
- | tLPAREN_ARG compstmt {SET_LEX_STATE(EXPR_ENDARG);} ')'
- {
- /*%%%*/
- if (nd_type_p($2, NODE_SELF)) RNODE_SELF($2)->nd_state = 0;
- $$ = $2;
- /*% %*/
- /*% ripper: paren!($2) %*/
- }
- | tLPAREN compstmt ')'
- {
- /*%%%*/
- if (nd_type_p($2, NODE_SELF)) RNODE_SELF($2)->nd_state = 0;
- $$ = NEW_BLOCK($2, &@$);
- /*% %*/
- /*% ripper: paren!($2) %*/
- }
- | primary_value tCOLON2 tCONSTANT
- {
- /*%%%*/
- $$ = NEW_COLON2($1, $3, &@$);
- /*% %*/
- /*% ripper: const_path_ref!($1, $3) %*/
- }
- | tCOLON3 tCONSTANT
- {
- /*%%%*/
- $$ = NEW_COLON3($2, &@$);
- /*% %*/
- /*% ripper: top_const_ref!($2) %*/
- }
- | tLBRACK aref_args ']'
- {
- /*%%%*/
- $$ = make_list($2, &@$);
- /*% %*/
- /*% ripper: array!($2) %*/
- }
- | tLBRACE assoc_list '}'
- {
- /*%%%*/
- $$ = new_hash(p, $2, &@$);
- RNODE_HASH($$)->nd_brace = TRUE;
- /*% %*/
- /*% ripper: hash!($2) %*/
- }
- | k_return
- {
- /*%%%*/
- $$ = NEW_RETURN(0, &@$);
- /*% %*/
- /*% ripper: return0! %*/
- }
- | k_yield '(' call_args rparen
- {
- /*%%%*/
- $$ = new_yield(p, $3, &@$);
- /*% %*/
- /*% ripper: yield!(paren!($3)) %*/
- }
- | k_yield '(' rparen
- {
- /*%%%*/
- $$ = NEW_YIELD(0, &@$);
- /*% %*/
- /*% ripper: yield!(paren!(args_new!)) %*/
- }
- | k_yield
- {
- /*%%%*/
- $$ = NEW_YIELD(0, &@$);
- /*% %*/
- /*% ripper: yield0! %*/
- }
- | keyword_defined opt_nl '(' begin_defined expr rparen
- {
- p->ctxt.in_defined = $4.in_defined;
- $$ = new_defined(p, $5, &@$);
- }
- | keyword_not '(' expr rparen
- {
- $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
- }
- | keyword_not '(' rparen
- {
- $$ = call_uni_op(p, method_cond(p, new_nil(&@2), &@2), METHOD_NOT, &@1, &@$);
- }
- | fcall brace_block
- {
- /*%%%*/
- $$ = method_add_block(p, (NODE *)$1, $2, &@$);
- /*% %*/
- /*% ripper: method_add_block!(method_add_arg!(fcall!($1), args_new!), $2) %*/
- }
- | method_call
- | method_call brace_block
- {
- /*%%%*/
- block_dup_check(p, get_nd_args(p, $1), $2);
- $$ = method_add_block(p, $1, $2, &@$);
- /*% %*/
- /*% ripper: method_add_block!($1, $2) %*/
- }
- | lambda
- | k_if expr_value then
- compstmt
- if_tail
- k_end
- {
- /*%%%*/
- $$ = new_if(p, $2, $4, $5, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: if!($2, $4, $5) %*/
- }
- | k_unless expr_value then
- compstmt
- opt_else
- k_end
- {
- /*%%%*/
- $$ = new_unless(p, $2, $4, $5, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: unless!($2, $4, $5) %*/
- }
- | k_while expr_value_do
- compstmt
- k_end
- {
- restore_block_exit(p, $1);
- /*%%%*/
- $$ = NEW_WHILE(cond(p, $2, &@2), $3, 1, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: while!($2, $3) %*/
- }
- | k_until expr_value_do
- compstmt
- k_end
- {
- restore_block_exit(p, $1);
- /*%%%*/
- $$ = NEW_UNTIL(cond(p, $2, &@2), $3, 1, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: until!($2, $3) %*/
- }
- | k_case expr_value opt_terms
- {
- $<val>$ = p->case_labels;
- p->case_labels = Qnil;
- }
- case_body
- k_end
- {
- if (RTEST(p->case_labels)) rb_hash_clear(p->case_labels);
- p->case_labels = $<val>4;
- /*%%%*/
- $$ = NEW_CASE($2, $5, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: case!($2, $5) %*/
- }
- | k_case opt_terms
- {
- $<val>$ = p->case_labels;
- p->case_labels = 0;
- }
- case_body
- k_end
- {
- if (RTEST(p->case_labels)) rb_hash_clear(p->case_labels);
- p->case_labels = $<val>3;
- /*%%%*/
- $$ = NEW_CASE2($4, &@$);
- /*% %*/
- /*% ripper: case!(Qnil, $4) %*/
- }
- | k_case expr_value opt_terms
- p_case_body
- k_end
- {
- /*%%%*/
- $$ = NEW_CASE3($2, $4, &@$);
- /*% %*/
- /*% ripper: case!($2, $4) %*/
- }
- | k_for for_var keyword_in expr_value_do
- compstmt
- k_end
- {
- restore_block_exit(p, $1);
- /*%%%*/
- /*
- * for a, b, c in e
- * #=>
- * e.each{|*x| a, b, c = x}
- *
- * for a in e
- * #=>
- * e.each{|x| a, = x}
- */
- ID id = internal_id(p);
- rb_node_args_aux_t *m = NEW_ARGS_AUX(0, 0, &NULL_LOC);
- rb_node_args_t *args;
- NODE *scope, *internal_var = NEW_DVAR(id, &@2);
+ | strings
+ | xstring
+ | regexp
+ | words
+ | qwords
+ | symbols
+ | qsymbols
+ | var_ref
+ | backref
+ | tFID
+ {
+ /*%%%*/
+ $$ = NEW_FCALL($1, 0, &@$);
+ /*% %*/
+ /*% ripper: method_add_arg!(fcall!($1), args_new!) %*/
+ }
+ | k_begin
+ {
+ CMDARG_PUSH(0);
+ }
+ bodystmt
+ k_end
+ {
+ CMDARG_POP();
+ /*%%%*/
+ set_line_body($3, @1.end_pos.lineno);
+ $$ = NEW_BEGIN($3, &@$);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ /*% ripper: begin!($3) %*/
+ }
+ | tLPAREN_ARG {SET_LEX_STATE(EXPR_ENDARG);} rparen
+ {
+ /*%%%*/
+ $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: paren!(0) %*/
+ }
+ | tLPAREN_ARG stmt {SET_LEX_STATE(EXPR_ENDARG);} rparen
+ {
+ /*%%%*/
+ if (nd_type_p($2, NODE_SELF)) $2->nd_state = 0;
+ $$ = $2;
+ /*% %*/
+ /*% ripper: paren!($2) %*/
+ }
+ | tLPAREN compstmt ')'
+ {
+ /*%%%*/
+ if (nd_type_p($2, NODE_SELF)) $2->nd_state = 0;
+ $$ = $2;
+ /*% %*/
+ /*% ripper: paren!($2) %*/
+ }
+ | primary_value tCOLON2 tCONSTANT
+ {
+ /*%%%*/
+ $$ = NEW_COLON2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_ref!($1, $3) %*/
+ }
+ | tCOLON3 tCONSTANT
+ {
+ /*%%%*/
+ $$ = NEW_COLON3($2, &@$);
+ /*% %*/
+ /*% ripper: top_const_ref!($2) %*/
+ }
+ | tLBRACK aref_args ']'
+ {
+ /*%%%*/
+ $$ = make_list($2, &@$);
+ /*% %*/
+ /*% ripper: array!(escape_Qundef($2)) %*/
+ }
+ | tLBRACE assoc_list '}'
+ {
+ /*%%%*/
+ $$ = new_hash(p, $2, &@$);
+ $$->nd_brace = TRUE;
+ /*% %*/
+ /*% ripper: hash!(escape_Qundef($2)) %*/
+ }
+ | k_return
+ {
+ /*%%%*/
+ $$ = NEW_RETURN(0, &@$);
+ /*% %*/
+ /*% ripper: return0! %*/
+ }
+ | keyword_yield '(' call_args rparen
+ {
+ /*%%%*/
+ $$ = new_yield(p, $3, &@$);
+ /*% %*/
+ /*% ripper: yield!(paren!($3)) %*/
+ }
+ | keyword_yield '(' rparen
+ {
+ /*%%%*/
+ $$ = NEW_YIELD(0, &@$);
+ /*% %*/
+ /*% ripper: yield!(paren!(args_new!)) %*/
+ }
+ | keyword_yield
+ {
+ /*%%%*/
+ $$ = NEW_YIELD(0, &@$);
+ /*% %*/
+ /*% ripper: yield0! %*/
+ }
+ | keyword_defined opt_nl '(' {p->ctxt.in_defined = 1;} expr rparen
+ {
+ p->ctxt.in_defined = 0;
+ $$ = new_defined(p, $5, &@$);
+ }
+ | keyword_not '(' expr rparen
+ {
+ $$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
+ }
+ | keyword_not '(' rparen
+ {
+ $$ = call_uni_op(p, method_cond(p, new_nil(&@2), &@2), METHOD_NOT, &@1, &@$);
+ }
+ | fcall brace_block
+ {
+ /*%%%*/
+ $$ = method_add_block(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(method_add_arg!(fcall!($1), args_new!), $2) %*/
+ }
+ | method_call
+ | method_call brace_block
+ {
+ /*%%%*/
+ block_dup_check(p, $1->nd_args, $2);
+ $$ = method_add_block(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!($1, $2) %*/
+ }
+ | lambda
+ | k_if expr_value then
+ compstmt
+ if_tail
+ k_end
+ {
+ /*%%%*/
+ $$ = new_if(p, $2, $4, $5, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: if!($2, $4, escape_Qundef($5)) %*/
+ }
+ | k_unless expr_value then
+ compstmt
+ opt_else
+ k_end
+ {
+ /*%%%*/
+ $$ = new_unless(p, $2, $4, $5, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: unless!($2, $4, escape_Qundef($5)) %*/
+ }
+ | k_while expr_value_do
+ compstmt
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_WHILE(cond(p, $2, &@2), $3, 1, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: while!($2, $3) %*/
+ }
+ | k_until expr_value_do
+ compstmt
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_UNTIL(cond(p, $2, &@2), $3, 1, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: until!($2, $3) %*/
+ }
+ | k_case expr_value opt_terms
+ {
+ $<val>$ = p->case_labels;
+ p->case_labels = Qnil;
+ }
+ case_body
+ k_end
+ {
+ if (RTEST(p->case_labels)) rb_hash_clear(p->case_labels);
+ p->case_labels = $<val>4;
+ /*%%%*/
+ $$ = NEW_CASE($2, $5, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: case!($2, $5) %*/
+ }
+ | k_case opt_terms
+ {
+ $<val>$ = p->case_labels;
+ p->case_labels = 0;
+ }
+ case_body
+ k_end
+ {
+ if (RTEST(p->case_labels)) rb_hash_clear(p->case_labels);
+ p->case_labels = $<val>3;
+ /*%%%*/
+ $$ = NEW_CASE2($4, &@$);
+ /*% %*/
+ /*% ripper: case!(Qnil, $4) %*/
+ }
+ | k_case expr_value opt_terms
+ p_case_body
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_CASE3($2, $4, &@$);
+ /*% %*/
+ /*% ripper: case!($2, $4) %*/
+ }
+ | k_for for_var keyword_in expr_value_do
+ compstmt
+ k_end
+ {
+ /*%%%*/
+ /*
+ * for a, b, c in e
+ * #=>
+ * e.each{|*x| a, b, c = x}
+ *
+ * for a in e
+ * #=>
+ * e.each{|x| a, = x}
+ */
+ ID id = internal_id(p);
+ NODE *m = NEW_ARGS_AUX(0, 0, &NULL_LOC);
+ NODE *args, *scope, *internal_var = NEW_DVAR(id, &@2);
rb_ast_id_table_t *tbl = rb_ast_new_local_table(p->ast, 1);
- tbl->ids[0] = id; /* internal id */
-
- switch (nd_type($2)) {
- case NODE_LASGN:
- case NODE_DASGN: /* e.each {|internal_var| a = internal_var; ... } */
- set_nd_value(p, $2, internal_var);
- id = 0;
- m->nd_plen = 1;
- m->nd_next = $2;
- break;
- case NODE_MASGN: /* e.each {|*internal_var| a, b, c = (internal_var.length == 1 && Array === (tmp = internal_var[0]) ? tmp : internal_var); ... } */
- m->nd_next = node_assign(p, $2, NEW_FOR_MASGN(internal_var, &@2), NO_LEX_CTXT, &@2);
- break;
- default: /* e.each {|*internal_var| @a, B, c[1], d.attr = internal_val; ... } */
- m->nd_next = node_assign(p, (NODE *)NEW_MASGN(NEW_LIST($2, &@2), 0, &@2), internal_var, NO_LEX_CTXT, &@2);
- }
- /* {|*internal_id| <m> = internal_id; ... } */
- args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
- scope = NEW_SCOPE2(tbl, args, $5, &@$);
- $$ = NEW_FOR($4, scope, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: for!($2, $4, $5) %*/
- }
- | k_class cpath superclass
- {
- begin_definition("class", &@k_class, &@cpath);
- }
- bodystmt
- k_end
- {
- /*%%%*/
- $$ = NEW_CLASS($cpath, $bodystmt, $superclass, &@$);
- nd_set_line(RNODE_CLASS($$)->nd_body, @k_end.end_pos.lineno);
- set_line_body($bodystmt, @superclass.end_pos.lineno);
- nd_set_line($$, @superclass.end_pos.lineno);
- /*% %*/
- /*% ripper: class!($cpath, $superclass, $bodystmt) %*/
- local_pop(p);
- p->ctxt.in_class = $k_class.in_class;
- p->ctxt.shareable_constant_value = $k_class.shareable_constant_value;
- }
- | k_class tLSHFT expr_value
- {
- begin_definition("", &@k_class, &@tLSHFT);
- }
- term
- bodystmt
- k_end
- {
- /*%%%*/
- $$ = NEW_SCLASS($expr_value, $bodystmt, &@$);
- nd_set_line(RNODE_SCLASS($$)->nd_body, @k_end.end_pos.lineno);
- set_line_body($bodystmt, nd_line($expr_value));
- fixpos($$, $expr_value);
- /*% %*/
- /*% ripper: sclass!($expr_value, $bodystmt) %*/
- local_pop(p);
- p->ctxt.in_def = $k_class.in_def;
- p->ctxt.in_class = $k_class.in_class;
- p->ctxt.shareable_constant_value = $k_class.shareable_constant_value;
- }
- | k_module cpath
- {
- begin_definition("module", &@k_module, &@cpath);
- }
- bodystmt
- k_end
- {
- /*%%%*/
- $$ = NEW_MODULE($cpath, $bodystmt, &@$);
- nd_set_line(RNODE_MODULE($$)->nd_body, @k_end.end_pos.lineno);
- set_line_body($bodystmt, @cpath.end_pos.lineno);
- nd_set_line($$, @cpath.end_pos.lineno);
- /*% %*/
- /*% ripper: module!($cpath, $bodystmt) %*/
- local_pop(p);
- p->ctxt.in_class = $k_module.in_class;
- p->ctxt.shareable_constant_value = $k_module.shareable_constant_value;
- }
- | defn_head[head]
- f_arglist[args]
- {
- /*%%%*/
- push_end_expect_token_locations(p, &@head.beg_pos);
- /*% %*/
- }
- bodystmt
- k_end
- {
- restore_defun(p, $head);
- /*%%%*/
- $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
- ($$ = $head->nd_def)->nd_loc = @$;
- RNODE_DEFN($$)->nd_defn = $bodystmt;
- /*% %*/
- /*% ripper: def!($head->nd_mid, $args, $bodystmt) %*/
- local_pop(p);
- }
- | defs_head[head]
- f_arglist[args]
- {
- /*%%%*/
- push_end_expect_token_locations(p, &@head.beg_pos);
- /*% %*/
- }
- bodystmt
- k_end
- {
- restore_defun(p, $head);
- /*%%%*/
- $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
- ($$ = $head->nd_def)->nd_loc = @$;
- RNODE_DEFS($$)->nd_defn = $bodystmt;
- /*% %*/
- /*% ripper: defs!($head->nd_recv, $head->dot_or_colon, $head->nd_mid, $args, $bodystmt) %*/
- local_pop(p);
- }
- | keyword_break
- {
- $<node>$ = add_block_exit(p, NEW_BREAK(0, &@$));
- /*% ripper: break!(args_new!) %*/
- }
- | keyword_next
- {
- $<node>$ = add_block_exit(p, NEW_NEXT(0, &@$));
- /*% ripper: next!(args_new!) %*/
- }
- | keyword_redo
- {
- $<node>$ = add_block_exit(p, NEW_REDO(&@$));
- /*% ripper: redo! %*/
- }
- | keyword_retry
- {
- if (!p->ctxt.in_defined) {
- switch (p->ctxt.in_rescue) {
- case before_rescue: yyerror1(&@1, "Invalid retry without rescue"); break;
- case after_rescue: /* ok */ break;
- case after_else: yyerror1(&@1, "Invalid retry after else"); break;
- case after_ensure: yyerror1(&@1, "Invalid retry after ensure"); break;
- }
- }
- /*%%%*/
- $$ = NEW_RETRY(&@$);
- /*% %*/
- /*% ripper: retry! %*/
- }
- ;
+ tbl->ids[0] = id; /* internal id */
+
+ switch (nd_type($2)) {
+ case NODE_LASGN:
+ case NODE_DASGN: /* e.each {|internal_var| a = internal_var; ... } */
+ $2->nd_value = internal_var;
+ id = 0;
+ m->nd_plen = 1;
+ m->nd_next = $2;
+ break;
+ case NODE_MASGN: /* e.each {|*internal_var| a, b, c = (internal_var.length == 1 && Array === (tmp = internal_var[0]) ? tmp : internal_var); ... } */
+ m->nd_next = node_assign(p, $2, NEW_FOR_MASGN(internal_var, &@2), NO_LEX_CTXT, &@2);
+ break;
+ default: /* e.each {|*internal_var| @a, B, c[1], d.attr = internal_val; ... } */
+ m->nd_next = node_assign(p, NEW_MASGN(NEW_LIST($2, &@2), 0, &@2), internal_var, NO_LEX_CTXT, &@2);
+ }
+ /* {|*internal_id| <m> = internal_id; ... } */
+ args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
+ scope = NEW_NODE(NODE_SCOPE, tbl, $5, args, &@$);
+ $$ = NEW_FOR($4, scope, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: for!($2, $4, $5) %*/
+ }
+ | k_class cpath superclass
+ {
+ if (p->ctxt.in_def) {
+ YYLTYPE loc = code_loc_gen(&@1, &@2);
+ yyerror1(&loc, "class definition in method body");
+ }
+ p->ctxt.in_class = 1;
+ local_push(p, 0);
+ }
+ bodystmt
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_CLASS($2, $5, $3, &@$);
+ nd_set_line($$->nd_body, @6.end_pos.lineno);
+ set_line_body($5, @3.end_pos.lineno);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: class!($2, $3, $5) %*/
+ local_pop(p);
+ p->ctxt.in_class = $<ctxt>1.in_class;
+ p->ctxt.shareable_constant_value = $<ctxt>1.shareable_constant_value;
+ }
+ | k_class tLSHFT expr
+ {
+ p->ctxt.in_def = 0;
+ p->ctxt.in_class = 0;
+ local_push(p, 0);
+ }
+ term
+ bodystmt
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_SCLASS($3, $6, &@$);
+ nd_set_line($$->nd_body, @7.end_pos.lineno);
+ set_line_body($6, nd_line($3));
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: sclass!($3, $6) %*/
+ local_pop(p);
+ p->ctxt.in_def = $<ctxt>1.in_def;
+ p->ctxt.in_class = $<ctxt>1.in_class;
+ p->ctxt.shareable_constant_value = $<ctxt>1.shareable_constant_value;
+ }
+ | k_module cpath
+ {
+ if (p->ctxt.in_def) {
+ YYLTYPE loc = code_loc_gen(&@1, &@2);
+ yyerror1(&loc, "module definition in method body");
+ }
+ p->ctxt.in_class = 1;
+ local_push(p, 0);
+ }
+ bodystmt
+ k_end
+ {
+ /*%%%*/
+ $$ = NEW_MODULE($2, $4, &@$);
+ nd_set_line($$->nd_body, @5.end_pos.lineno);
+ set_line_body($4, @2.end_pos.lineno);
+ nd_set_line($$, @2.end_pos.lineno);
+ /*% %*/
+ /*% ripper: module!($2, $4) %*/
+ local_pop(p);
+ p->ctxt.in_class = $<ctxt>1.in_class;
+ p->ctxt.shareable_constant_value = $<ctxt>1.shareable_constant_value;
+ }
+ | defn_head
+ f_arglist
+ {
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ bodystmt
+ k_end
+ {
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*% %*/
+ /*% ripper: def!(get_value($1), $2, $4) %*/
+ local_pop(p);
+ }
+ | defs_head
+ f_arglist
+ {
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ bodystmt
+ k_end
+ {
+ restore_defun(p, $<node>1->nd_defn);
+ /*%%%*/
+ $$ = set_defun_body(p, $1, $2, $4, &@$);
+ /*%
+ $1 = get_value($1);
+ %*/
+ /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
+ local_pop(p);
+ }
+ | keyword_break
+ {
+ /*%%%*/
+ $$ = NEW_BREAK(0, &@$);
+ /*% %*/
+ /*% ripper: break!(args_new!) %*/
+ }
+ | keyword_next
+ {
+ /*%%%*/
+ $$ = NEW_NEXT(0, &@$);
+ /*% %*/
+ /*% ripper: next!(args_new!) %*/
+ }
+ | keyword_redo
+ {
+ /*%%%*/
+ $$ = NEW_REDO(&@$);
+ /*% %*/
+ /*% ripper: redo! %*/
+ }
+ | keyword_retry
+ {
+ /*%%%*/
+ $$ = NEW_RETRY(&@$);
+ /*% %*/
+ /*% ripper: retry! %*/
+ }
+ ;
primary_value : primary
- {
- value_expr($1);
- $$ = $1;
- }
- ;
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ ;
k_begin : keyword_begin
- {
- token_info_push(p, "begin", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "begin", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_if : keyword_if
- {
- WARN_EOL("if");
- token_info_push(p, "if", &@$);
- if (p->token_info && p->token_info->nonspc &&
- p->token_info->next && !strcmp(p->token_info->next->token, "else")) {
- const char *tok = p->lex.ptok - rb_strlen_lit("if");
- const char *beg = p->lex.pbeg + p->token_info->next->beg.column;
- beg += rb_strlen_lit("else");
- while (beg < tok && ISSPACE(*beg)) beg++;
- if (beg == tok) {
- p->token_info->nonspc = 0;
- }
- }
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ WARN_EOL("if");
+ token_info_push(p, "if", &@$);
+ if (p->token_info && p->token_info->nonspc &&
+ p->token_info->next && !strcmp(p->token_info->next->token, "else")) {
+ const char *tok = p->lex.ptok - rb_strlen_lit("if");
+ const char *beg = p->lex.pbeg + p->token_info->next->beg.column;
+ beg += rb_strlen_lit("else");
+ while (beg < tok && ISSPACE(*beg)) beg++;
+ if (beg == tok) {
+ p->token_info->nonspc = 0;
+ }
+ }
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_unless : keyword_unless
- {
- token_info_push(p, "unless", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
-
-k_while : keyword_while allow_exits
- {
- $$ = $allow_exits;
- token_info_push(p, "while", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
-
-k_until : keyword_until allow_exits
- {
- $$ = $allow_exits;
- token_info_push(p, "until", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "unless", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
+
+k_while : keyword_while
+ {
+ token_info_push(p, "while", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
+
+k_until : keyword_until
+ {
+ token_info_push(p, "until", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_case : keyword_case
- {
- token_info_push(p, "case", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
-
-k_for : keyword_for allow_exits
- {
- $$ = $allow_exits;
- token_info_push(p, "for", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "case", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
+
+k_for : keyword_for
+ {
+ token_info_push(p, "for", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_class : keyword_class
- {
- token_info_push(p, "class", &@$);
- $$ = p->ctxt;
- p->ctxt.in_rescue = before_rescue;
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "class", &@$);
+ $<ctxt>$ = p->ctxt;
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_module : keyword_module
- {
- token_info_push(p, "module", &@$);
- $$ = p->ctxt;
- p->ctxt.in_rescue = before_rescue;
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "module", &@$);
+ $<ctxt>$ = p->ctxt;
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_def : keyword_def
- {
- token_info_push(p, "def", &@$);
- $$ = NEW_DEF_TEMP(&@$);
- p->ctxt.in_argdef = 1;
- }
- ;
+ {
+ token_info_push(p, "def", &@$);
+ p->ctxt.in_argdef = 1;
+ }
+ ;
k_do : keyword_do
- {
- token_info_push(p, "do", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "do", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+
+ }
+ ;
k_do_block : keyword_do_block
- {
- token_info_push(p, "do", &@$);
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- ;
+ {
+ token_info_push(p, "do", &@$);
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ ;
k_rescue : keyword_rescue
- {
- token_info_warn(p, "rescue", p->token_info, 1, &@$);
- $$ = p->ctxt;
- p->ctxt.in_rescue = after_rescue;
- }
- ;
+ {
+ token_info_warn(p, "rescue", p->token_info, 1, &@$);
+ }
+ ;
k_ensure : keyword_ensure
- {
- token_info_warn(p, "ensure", p->token_info, 1, &@$);
- $$ = p->ctxt;
- }
- ;
+ {
+ token_info_warn(p, "ensure", p->token_info, 1, &@$);
+ }
+ ;
k_when : keyword_when
- {
- token_info_warn(p, "when", p->token_info, 0, &@$);
- }
- ;
+ {
+ token_info_warn(p, "when", p->token_info, 0, &@$);
+ }
+ ;
k_else : keyword_else
- {
- token_info *ptinfo_beg = p->token_info;
- int same = ptinfo_beg && strcmp(ptinfo_beg->token, "case") != 0;
- token_info_warn(p, "else", p->token_info, same, &@$);
- if (same) {
- token_info e;
- e.next = ptinfo_beg->next;
- e.token = "else";
- token_info_setup(&e, p->lex.pbeg, &@$);
- if (!e.nonspc) *ptinfo_beg = e;
- }
- }
- ;
+ {
+ token_info *ptinfo_beg = p->token_info;
+ int same = ptinfo_beg && strcmp(ptinfo_beg->token, "case") != 0;
+ token_info_warn(p, "else", p->token_info, same, &@$);
+ if (same) {
+ token_info e;
+ e.next = ptinfo_beg->next;
+ e.token = "else";
+ token_info_setup(&e, p->lex.pbeg, &@$);
+ if (!e.nonspc) *ptinfo_beg = e;
+ }
+ }
+ ;
k_elsif : keyword_elsif
- {
- WARN_EOL("elsif");
- token_info_warn(p, "elsif", p->token_info, 1, &@$);
- }
- ;
+ {
+ WARN_EOL("elsif");
+ token_info_warn(p, "elsif", p->token_info, 1, &@$);
+ }
+ ;
k_end : keyword_end
- {
- token_info_pop(p, "end", &@$);
- /*%%%*/
- pop_end_expect_token_locations(p);
- /*% %*/
- }
- | tDUMNY_END
- {
- compile_error(p, "syntax error, unexpected end-of-input");
- }
- ;
+ {
+ token_info_pop(p, "end", &@$);
+ /*%%%*/
+ pop_end_expect_token_locations(p);
+ /*% %*/
+ }
+ | tDUMNY_END
+ {
+ compile_error(p, "syntax error, unexpected end-of-input");
+ }
+ ;
k_return : keyword_return
- {
- if (p->ctxt.in_class && !p->ctxt.in_def && !dyna_in_block(p))
- yyerror1(&@1, "Invalid return in class/module body");
- }
- ;
-
-k_yield : keyword_yield
- {
- if (!p->ctxt.in_defined && !p->ctxt.in_def && !compile_for_eval)
- yyerror1(&@1, "Invalid yield");
- }
- ;
+ {
+ if (p->ctxt.in_class && !p->ctxt.in_def && !dyna_in_block(p))
+ yyerror1(&@1, "Invalid return in class/module body");
+ }
+ ;
then : term
- | keyword_then
- | term keyword_then
- ;
+ | keyword_then
+ | term keyword_then
+ ;
do : term
- | keyword_do_cond
- ;
+ | keyword_do_cond
+ ;
if_tail : opt_else
- | k_elsif expr_value then
- compstmt
- if_tail
- {
- /*%%%*/
- $$ = new_if(p, $2, $4, $5, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: elsif!($2, $4, $5) %*/
- }
- ;
+ | k_elsif expr_value then
+ compstmt
+ if_tail
+ {
+ /*%%%*/
+ $$ = new_if(p, $2, $4, $5, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: elsif!($2, $4, escape_Qundef($5)) %*/
+ }
+ ;
opt_else : none
- | k_else compstmt
- {
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: else!($2) %*/
- }
- ;
+ | k_else compstmt
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: else!($2) %*/
+ }
+ ;
for_var : lhs
- | mlhs
- ;
+ | mlhs
+ ;
f_marg : f_norm_arg
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- mark_lvar_used(p, $$);
- /*% %*/
- /*% ripper: assignable(p, $1) %*/
- }
- | tLPAREN f_margs rparen
- {
- /*%%%*/
- $$ = (NODE *)$2;
- /*% %*/
- /*% ripper: mlhs_paren!($2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ mark_lvar_used(p, $$);
+ /*% %*/
+ /*% ripper: assignable(p, $1) %*/
+ }
+ | tLPAREN f_margs rparen
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
+ }
+ ;
f_marg_list : f_marg
- {
- /*%%%*/
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
- }
- | f_marg_list ',' f_marg
- {
- /*%%%*/
- $$ = list_append(p, $1, $3);
- /*% %*/
- /*% ripper: mlhs_add!($1, $3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
+ }
+ | f_marg_list ',' f_marg
+ {
+ /*%%%*/
+ $$ = list_append(p, $1, $3);
+ /*% %*/
+ /*% ripper: mlhs_add!($1, $3) %*/
+ }
+ ;
f_margs : f_marg_list
- {
- /*%%%*/
- $$ = NEW_MASGN($1, 0, &@$);
- /*% %*/
- /*% ripper: $1 %*/
- }
- | f_marg_list ',' f_rest_marg
- {
- /*%%%*/
- $$ = NEW_MASGN($1, $3, &@$);
- /*% %*/
- /*% ripper: mlhs_add_star!($1, $3) %*/
- }
- | f_marg_list ',' f_rest_marg ',' f_marg_list
- {
- /*%%%*/
- $$ = NEW_MASGN($1, NEW_POSTARG($3, $5, &@$), &@$);
- /*% %*/
- /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
- }
- | f_rest_marg
- {
- /*%%%*/
- $$ = NEW_MASGN(0, $1, &@$);
- /*% %*/
- /*% ripper: mlhs_add_star!(mlhs_new!, $1) %*/
- }
- | f_rest_marg ',' f_marg_list
- {
- /*%%%*/
- $$ = NEW_MASGN(0, NEW_POSTARG($1, $3, &@$), &@$);
- /*% %*/
- /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $1), $3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, 0, &@$);
+ /*% %*/
+ /*% ripper: $1 %*/
+ }
+ | f_marg_list ',' f_rest_marg
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, $3, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!($1, $3) %*/
+ }
+ | f_marg_list ',' f_rest_marg ',' f_marg_list
+ {
+ /*%%%*/
+ $$ = NEW_MASGN($1, NEW_POSTARG($3, $5, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
+ }
+ | f_rest_marg
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, $1, &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_star!(mlhs_new!, $1) %*/
+ }
+ | f_rest_marg ',' f_marg_list
+ {
+ /*%%%*/
+ $$ = NEW_MASGN(0, NEW_POSTARG($1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $1), $3) %*/
+ }
+ ;
f_rest_marg : tSTAR f_norm_arg
- {
- /*%%%*/
- $$ = assignable(p, $2, 0, &@$);
- mark_lvar_used(p, $$);
- /*% %*/
- /*% ripper: assignable(p, $2) %*/
- }
- | tSTAR
- {
- /*%%%*/
- $$ = NODE_SPECIAL_NO_NAME_REST;
- /*% %*/
- /*% ripper: Qnil %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = assignable(p, $2, 0, &@$);
+ mark_lvar_used(p, $$);
+ /*% %*/
+ /*% ripper: assignable(p, $2) %*/
+ }
+ | tSTAR
+ {
+ /*%%%*/
+ $$ = NODE_SPECIAL_NO_NAME_REST;
+ /*% %*/
+ /*% ripper: Qnil %*/
+ }
+ ;
f_any_kwrest : f_kwrest
- | f_no_kwarg {$$ = ID2VAL(idNil);}
- ;
+ | f_no_kwarg {$$ = ID2VAL(idNil);}
+ ;
f_eq : {p->ctxt.in_argdef = 0;} '=';
block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
- {
- $$ = new_args_tail(p, $1, $3, $4, &@3);
- }
- | f_block_kwarg opt_f_block_arg
- {
- $$ = new_args_tail(p, $1, Qnone, $2, &@1);
- }
- | f_any_kwrest opt_f_block_arg
- {
- $$ = new_args_tail(p, Qnone, $1, $2, &@1);
- }
- | f_block_arg
- {
- $$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
- }
- ;
+ {
+ $$ = new_args_tail(p, $1, $3, $4, &@3);
+ }
+ | f_block_kwarg opt_f_block_arg
+ {
+ $$ = new_args_tail(p, $1, Qnone, $2, &@1);
+ }
+ | f_any_kwrest opt_f_block_arg
+ {
+ $$ = new_args_tail(p, Qnone, $1, $2, &@1);
+ }
+ | f_block_arg
+ {
+ $$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
+ }
+ ;
opt_block_args_tail : ',' block_args_tail
- {
- $$ = $2;
- }
- | /* none */
- {
- $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
- }
- ;
+ {
+ $$ = $2;
+ }
+ | /* none */
+ {
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
+ }
+ ;
excessed_comma : ','
- {
- /* magic number for rest_id in iseq_set_arguments() */
- /*%%%*/
- $$ = NODE_SPECIAL_EXCESSIVE_COMMA;
- /*% %*/
- /*% ripper: excessed_comma! %*/
- }
- ;
+ {
+ /* magic number for rest_id in iseq_set_arguments() */
+ /*%%%*/
+ $$ = NODE_SPECIAL_EXCESSIVE_COMMA;
+ /*% %*/
+ /*% ripper: excessed_comma! %*/
+ }
+ ;
block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
- {
- $$ = new_args(p, $1, $3, $5, Qnone, $6, &@$);
- }
- | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
- {
- $$ = new_args(p, $1, $3, $5, $7, $8, &@$);
- }
- | f_arg ',' f_block_optarg opt_block_args_tail
- {
- $$ = new_args(p, $1, $3, Qnone, Qnone, $4, &@$);
- }
- | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
- {
- $$ = new_args(p, $1, $3, Qnone, $5, $6, &@$);
- }
+ {
+ $$ = new_args(p, $1, $3, $5, Qnone, $6, &@$);
+ }
+ | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, $1, $3, $5, $7, $8, &@$);
+ }
+ | f_arg ',' f_block_optarg opt_block_args_tail
+ {
+ $$ = new_args(p, $1, $3, Qnone, Qnone, $4, &@$);
+ }
+ | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, $1, $3, Qnone, $5, $6, &@$);
+ }
| f_arg ',' f_rest_arg opt_block_args_tail
- {
- $$ = new_args(p, $1, Qnone, $3, Qnone, $4, &@$);
- }
- | f_arg excessed_comma
- {
- $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@2);
- $$ = new_args(p, $1, Qnone, $2, Qnone, $$, &@$);
- }
- | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
- {
- $$ = new_args(p, $1, Qnone, $3, $5, $6, &@$);
- }
- | f_arg opt_block_args_tail
- {
- $$ = new_args(p, $1, Qnone, Qnone, Qnone, $2, &@$);
- }
- | f_block_optarg ',' f_rest_arg opt_block_args_tail
- {
- $$ = new_args(p, Qnone, $1, $3, Qnone, $4, &@$);
- }
- | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
- {
- $$ = new_args(p, Qnone, $1, $3, $5, $6, &@$);
- }
- | f_block_optarg opt_block_args_tail
- {
- $$ = new_args(p, Qnone, $1, Qnone, Qnone, $2, &@$);
- }
- | f_block_optarg ',' f_arg opt_block_args_tail
- {
- $$ = new_args(p, Qnone, $1, Qnone, $3, $4, &@$);
- }
- | f_rest_arg opt_block_args_tail
- {
- $$ = new_args(p, Qnone, Qnone, $1, Qnone, $2, &@$);
- }
- | f_rest_arg ',' f_arg opt_block_args_tail
- {
- $$ = new_args(p, Qnone, Qnone, $1, $3, $4, &@$);
- }
- | block_args_tail
- {
- $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $1, &@$);
- }
- ;
+ {
+ $$ = new_args(p, $1, Qnone, $3, Qnone, $4, &@$);
+ }
+ | f_arg excessed_comma
+ {
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@2);
+ $$ = new_args(p, $1, Qnone, $2, Qnone, $$, &@$);
+ }
+ | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, $1, Qnone, $3, $5, $6, &@$);
+ }
+ | f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, $1, Qnone, Qnone, Qnone, $2, &@$);
+ }
+ | f_block_optarg ',' f_rest_arg opt_block_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, $3, Qnone, $4, &@$);
+ }
+ | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, $3, $5, $6, &@$);
+ }
+ | f_block_optarg opt_block_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, Qnone, Qnone, $2, &@$);
+ }
+ | f_block_optarg ',' f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, Qnone, $3, $4, &@$);
+ }
+ | f_rest_arg opt_block_args_tail
+ {
+ $$ = new_args(p, Qnone, Qnone, $1, Qnone, $2, &@$);
+ }
+ | f_rest_arg ',' f_arg opt_block_args_tail
+ {
+ $$ = new_args(p, Qnone, Qnone, $1, $3, $4, &@$);
+ }
+ | block_args_tail
+ {
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $1, &@$);
+ }
+ ;
opt_block_param : none
- | block_param_def
- {
- p->command_start = TRUE;
- }
- ;
+ | block_param_def
+ {
+ p->command_start = TRUE;
+ }
+ ;
block_param_def : '|' opt_bv_decl '|'
- {
- p->cur_arg = 0;
- p->max_numparam = ORDINAL_PARAM;
- p->ctxt.in_argdef = 0;
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil) %*/
- /*% ripper: block_var!($$, $2) %*/
- }
- | '|' block_param opt_bv_decl '|'
- {
- p->cur_arg = 0;
- p->max_numparam = ORDINAL_PARAM;
- p->ctxt.in_argdef = 0;
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: block_var!($2, $3) %*/
- }
- ;
+ {
+ p->cur_arg = 0;
+ p->max_numparam = ORDINAL_PARAM;
+ p->ctxt.in_argdef = 0;
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: block_var!(params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil), escape_Qundef($2)) %*/
+ }
+ | '|' block_param opt_bv_decl '|'
+ {
+ p->cur_arg = 0;
+ p->max_numparam = ORDINAL_PARAM;
+ p->ctxt.in_argdef = 0;
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: block_var!(escape_Qundef($2), escape_Qundef($3)) %*/
+ }
+ ;
opt_bv_decl : opt_nl
- {
- $$ = 0;
- }
- | opt_nl ';' bv_decls opt_nl
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: $3 %*/
- }
- ;
+ {
+ $$ = 0;
+ }
+ | opt_nl ';' bv_decls opt_nl
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: $3 %*/
+ }
+ ;
bv_decls : bvar
- /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
- | bv_decls ',' bvar
- /*% ripper[brace]: rb_ary_push($1, get_value($3)) %*/
- ;
+ /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
+ | bv_decls ',' bvar
+ /*% ripper[brace]: rb_ary_push($1, get_value($3)) %*/
+ ;
bvar : tIDENTIFIER
- {
- new_bv(p, get_id($1));
- /*% ripper: get_value($1) %*/
- }
- | f_bad_arg
- {
- $$ = 0;
- }
- ;
-
-max_numparam : {
- $$ = p->max_numparam;
- p->max_numparam = 0;
- }
- ;
-
-numparam : {
- $$ = numparam_push(p);
- }
- ;
-
-lambda : tLAMBDA[dyna]
- {
- token_info_push(p, "->", &@1);
- $<vars>dyna = dyna_push(p);
- $<num>$ = p->lex.lpar_beg;
- p->lex.lpar_beg = p->lex.paren_nest;
- }[lpar]
- max_numparam numparam allow_exits
- f_larglist[args]
- {
- CMDARG_PUSH(0);
- }
- lambda_body[body]
- {
- int max_numparam = p->max_numparam;
- p->lex.lpar_beg = $<num>lpar;
- p->max_numparam = $max_numparam;
- restore_block_exit(p, $allow_exits);
- CMDARG_POP();
- $args = args_with_numbered(p, $args, max_numparam);
- /*%%%*/
+ {
+ new_bv(p, get_id($1));
+ /*% ripper: get_value($1) %*/
+ }
+ | f_bad_arg
+ {
+ $$ = 0;
+ }
+ ;
+
+lambda : tLAMBDA
+ {
+ token_info_push(p, "->", &@1);
+ $<vars>1 = dyna_push(p);
+ $<num>$ = p->lex.lpar_beg;
+ p->lex.lpar_beg = p->lex.paren_nest;
+ }
+ {
+ $<num>$ = p->max_numparam;
+ p->max_numparam = 0;
+ }
+ {
+ $<node>$ = numparam_push(p);
+ }
+ f_larglist
+ {
+ CMDARG_PUSH(0);
+ }
+ lambda_body
+ {
+ int max_numparam = p->max_numparam;
+ p->lex.lpar_beg = $<num>2;
+ p->max_numparam = $<num>3;
+ CMDARG_POP();
+ $5 = args_with_numbered(p, $5, max_numparam);
+ /*%%%*/
{
- YYLTYPE loc = code_loc_gen(&@args, &@body);
- $$ = NEW_LAMBDA($args, $body, &loc);
- nd_set_line(RNODE_LAMBDA($$)->nd_body, @body.end_pos.lineno);
- nd_set_line($$, @args.end_pos.lineno);
- nd_set_first_loc($$, @1.beg_pos);
+ YYLTYPE loc = code_loc_gen(&@5, &@7);
+ $$ = NEW_LAMBDA($5, $7, &loc);
+ nd_set_line($$->nd_body, @7.end_pos.lineno);
+ nd_set_line($$, @5.end_pos.lineno);
+ nd_set_first_loc($$, @1.beg_pos);
}
- /*% %*/
- /*% ripper: lambda!($args, $body) %*/
- numparam_pop(p, $numparam);
- dyna_pop(p, $<vars>dyna);
- }
- ;
+ /*% %*/
+ /*% ripper: lambda!($5, $7) %*/
+ numparam_pop(p, $<node>4);
+ dyna_pop(p, $<vars>1);
+ }
+ ;
f_larglist : '(' f_args opt_bv_decl ')'
- {
- p->ctxt.in_argdef = 0;
- /*%%%*/
- $$ = $2;
- p->max_numparam = ORDINAL_PARAM;
- /*% %*/
- /*% ripper: paren!($2) %*/
- }
- | f_args
- {
- p->ctxt.in_argdef = 0;
- /*%%%*/
- if (!args_info_empty_p(&$1->nd_ainfo))
- p->max_numparam = ORDINAL_PARAM;
- /*% %*/
- $$ = $1;
- }
- ;
+ {
+ p->ctxt.in_argdef = 0;
+ /*%%%*/
+ $$ = $2;
+ p->max_numparam = ORDINAL_PARAM;
+ /*% %*/
+ /*% ripper: paren!($2) %*/
+ }
+ | f_args
+ {
+ p->ctxt.in_argdef = 0;
+ /*%%%*/
+ if (!args_info_empty_p($1->nd_ainfo))
+ p->max_numparam = ORDINAL_PARAM;
+ /*% %*/
+ $$ = $1;
+ }
+ ;
lambda_body : tLAMBEG compstmt '}'
- {
- token_info_pop(p, "}", &@3);
- $$ = $2;
- }
- | keyword_do_LAMBDA
- {
- /*%%%*/
- push_end_expect_token_locations(p, &@1.beg_pos);
- /*% %*/
- }
- bodystmt k_end
- {
- $$ = $3;
- }
- ;
+ {
+ token_info_pop(p, "}", &@3);
+ $$ = $2;
+ }
+ | keyword_do_LAMBDA
+ {
+ /*%%%*/
+ push_end_expect_token_locations(p, &@1.beg_pos);
+ /*% %*/
+ }
+ bodystmt k_end
+ {
+ $$ = $3;
+ }
+ ;
do_block : k_do_block do_body k_end
- {
- $$ = $2;
- /*%%%*/
- set_embraced_location($$, &@1, &@3);
- /*% %*/
- }
- ;
+ {
+ $$ = $2;
+ /*%%%*/
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ }
+ ;
block_call : command do_block
- {
- /*%%%*/
- if (nd_type_p($1, NODE_YIELD)) {
- compile_error(p, "block given to yield");
- }
- else {
- block_dup_check(p, get_nd_args(p, $1), $2);
- }
- $$ = method_add_block(p, $1, $2, &@$);
- fixpos($$, $1);
- /*% %*/
- /*% ripper: method_add_block!($1, $2) %*/
- }
- | block_call call_op2 operation2 opt_paren_args
- {
- /*%%%*/
- $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
- /*% %*/
- /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
- }
- | block_call call_op2 operation2 opt_paren_args brace_block
- {
- /*%%%*/
- $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
- /*% %*/
- /*% ripper: opt_event(:method_add_block!, command_call!($1, $2, $3, $4), $5) %*/
- }
- | block_call call_op2 operation2 command_args do_block
- {
- /*%%%*/
- $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
- /*% %*/
- /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
- }
- ;
+ {
+ /*%%%*/
+ if (nd_type_p($1, NODE_YIELD)) {
+ compile_error(p, "block given to yield");
+ }
+ else {
+ block_dup_check(p, $1->nd_args, $2);
+ }
+ $$ = method_add_block(p, $1, $2, &@$);
+ fixpos($$, $1);
+ /*% %*/
+ /*% ripper: method_add_block!($1, $2) %*/
+ }
+ | block_call call_op2 operation2 opt_paren_args
+ {
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
+ /*% %*/
+ /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
+ }
+ | block_call call_op2 operation2 opt_paren_args brace_block
+ {
+ /*%%%*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: opt_event(:method_add_block!, command_call!($1, $2, $3, $4), $5) %*/
+ }
+ | block_call call_op2 operation2 command_args do_block
+ {
+ /*%%%*/
+ $$ = new_command_qcall(p, $2, $1, $3, $4, $5, &@3, &@$);
+ /*% %*/
+ /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
+ }
+ ;
method_call : fcall paren_args
- {
- /*%%%*/
- $1->nd_args = $2;
- $$ = (NODE *)$1;
- nd_set_last_loc($1, @2.end_pos);
- /*% %*/
- /*% ripper: method_add_arg!(fcall!($1), $2) %*/
- }
- | primary_value call_op operation2 opt_paren_args
- {
- /*%%%*/
- $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
- nd_set_line($$, @3.end_pos.lineno);
- /*% %*/
- /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- /*%%%*/
- $$ = new_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, &@3, &@$);
- nd_set_line($$, @3.end_pos.lineno);
- /*% %*/
- /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
- }
- | primary_value tCOLON2 operation3
- {
- /*%%%*/
- $$ = new_qcall(p, ID2VAL(idCOLON2), $1, $3, Qnull, &@3, &@$);
- /*% %*/
- /*% ripper: call!($1, $2, $3) %*/
- }
- | primary_value call_op paren_args
- {
- /*%%%*/
- $$ = new_qcall(p, $2, $1, ID2VAL(idCall), $3, &@2, &@$);
- nd_set_line($$, @2.end_pos.lineno);
- /*% %*/
- /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
- }
- | primary_value tCOLON2 paren_args
- {
- /*%%%*/
- $$ = new_qcall(p, ID2VAL(idCOLON2), $1, ID2VAL(idCall), $3, &@2, &@$);
- nd_set_line($$, @2.end_pos.lineno);
- /*% %*/
- /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
- }
- | keyword_super paren_args
- {
- /*%%%*/
- $$ = NEW_SUPER($2, &@$);
- /*% %*/
- /*% ripper: super!($2) %*/
- }
- | keyword_super
- {
- /*%%%*/
- $$ = NEW_ZSUPER(&@$);
- /*% %*/
- /*% ripper: zsuper! %*/
- }
- | primary_value '[' opt_call_args rbracket
- {
- /*%%%*/
- $$ = NEW_CALL($1, tAREF, $3, &@$);
- fixpos($$, $1);
- /*% %*/
- /*% ripper: aref!($1, $3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = $1;
+ $$->nd_args = $2;
+ nd_set_last_loc($1, @2.end_pos);
+ /*% %*/
+ /*% ripper: method_add_arg!(fcall!($1), $2) %*/
+ }
+ | primary_value call_op operation2 opt_paren_args
+ {
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
+ }
+ | primary_value tCOLON2 operation2 paren_args
+ {
+ /*%%%*/
+ $$ = new_qcall(p, ID2VAL(idCOLON2), $1, $3, $4, &@3, &@$);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
+ }
+ | primary_value tCOLON2 operation3
+ {
+ /*%%%*/
+ $$ = new_qcall(p, ID2VAL(idCOLON2), $1, $3, Qnull, &@3, &@$);
+ /*% %*/
+ /*% ripper: call!($1, $2, $3) %*/
+ }
+ | primary_value call_op paren_args
+ {
+ /*%%%*/
+ $$ = new_qcall(p, $2, $1, ID2VAL(idCall), $3, &@2, &@$);
+ nd_set_line($$, @2.end_pos.lineno);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
+ }
+ | primary_value tCOLON2 paren_args
+ {
+ /*%%%*/
+ $$ = new_qcall(p, ID2VAL(idCOLON2), $1, ID2VAL(idCall), $3, &@2, &@$);
+ nd_set_line($$, @2.end_pos.lineno);
+ /*% %*/
+ /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
+ }
+ | keyword_super paren_args
+ {
+ /*%%%*/
+ $$ = NEW_SUPER($2, &@$);
+ /*% %*/
+ /*% ripper: super!($2) %*/
+ }
+ | keyword_super
+ {
+ /*%%%*/
+ $$ = NEW_ZSUPER(&@$);
+ /*% %*/
+ /*% ripper: zsuper! %*/
+ }
+ | primary_value '[' opt_call_args rbracket
+ {
+ /*%%%*/
+ if ($1 && nd_type_p($1, NODE_SELF))
+ $$ = NEW_FCALL(tAREF, $3, &@$);
+ else
+ $$ = NEW_CALL($1, tAREF, $3, &@$);
+ fixpos($$, $1);
+ /*% %*/
+ /*% ripper: aref!($1, escape_Qundef($3)) %*/
+ }
+ ;
brace_block : '{' brace_body '}'
- {
- $$ = $2;
- /*%%%*/
- set_embraced_location($$, &@1, &@3);
- /*% %*/
- }
- | k_do do_body k_end
- {
- $$ = $2;
- /*%%%*/
- set_embraced_location($$, &@1, &@3);
- /*% %*/
- }
- ;
-
-brace_body : {$<vars>$ = dyna_push(p);}[dyna]
- max_numparam numparam allow_exits
- opt_block_param[args] compstmt
- {
- int max_numparam = p->max_numparam;
- p->max_numparam = $max_numparam;
- $args = args_with_numbered(p, $args, max_numparam);
- /*%%%*/
- $$ = NEW_ITER($args, $compstmt, &@$);
- /*% %*/
- /*% ripper: brace_block!($args, $compstmt) %*/
- restore_block_exit(p, $allow_exits);
- numparam_pop(p, $numparam);
- dyna_pop(p, $<vars>dyna);
- }
- ;
-
-do_body : {
- $<vars>$ = dyna_push(p);
- CMDARG_PUSH(0);
- }[dyna]
- max_numparam numparam allow_exits
- opt_block_param[args] bodystmt
- {
- int max_numparam = p->max_numparam;
- p->max_numparam = $max_numparam;
- $args = args_with_numbered(p, $args, max_numparam);
- /*%%%*/
- $$ = NEW_ITER($args, $bodystmt, &@$);
- /*% %*/
- /*% ripper: do_block!($args, $bodystmt) %*/
- CMDARG_POP();
- restore_block_exit(p, $allow_exits);
- numparam_pop(p, $numparam);
- dyna_pop(p, $<vars>dyna);
- }
- ;
+ {
+ $$ = $2;
+ /*%%%*/
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ }
+ | k_do do_body k_end
+ {
+ $$ = $2;
+ /*%%%*/
+ $$->nd_body->nd_loc = code_loc_gen(&@1, &@3);
+ nd_set_line($$, @1.end_pos.lineno);
+ /*% %*/
+ }
+ ;
+
+brace_body : {$<vars>$ = dyna_push(p);}
+ {
+ $<num>$ = p->max_numparam;
+ p->max_numparam = 0;
+ }
+ {
+ $<node>$ = numparam_push(p);
+ }
+ opt_block_param compstmt
+ {
+ int max_numparam = p->max_numparam;
+ p->max_numparam = $<num>2;
+ $4 = args_with_numbered(p, $4, max_numparam);
+ /*%%%*/
+ $$ = NEW_ITER($4, $5, &@$);
+ /*% %*/
+ /*% ripper: brace_block!(escape_Qundef($4), $5) %*/
+ numparam_pop(p, $<node>3);
+ dyna_pop(p, $<vars>1);
+ }
+ ;
+
+do_body : {$<vars>$ = dyna_push(p);}
+ {
+ $<num>$ = p->max_numparam;
+ p->max_numparam = 0;
+ }
+ {
+ $<node>$ = numparam_push(p);
+ CMDARG_PUSH(0);
+ }
+ opt_block_param bodystmt
+ {
+ int max_numparam = p->max_numparam;
+ p->max_numparam = $<num>2;
+ $4 = args_with_numbered(p, $4, max_numparam);
+ /*%%%*/
+ $$ = NEW_ITER($4, $5, &@$);
+ /*% %*/
+ /*% ripper: do_block!(escape_Qundef($4), $5) %*/
+ CMDARG_POP();
+ numparam_pop(p, $<node>3);
+ dyna_pop(p, $<vars>1);
+ }
+ ;
case_args : arg_value
- {
- /*%%%*/
- check_literal_when(p, $1, &@1);
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: args_add!(args_new!, $1) %*/
- }
- | tSTAR arg_value
- {
- /*%%%*/
- $$ = NEW_SPLAT($2, &@$);
- /*% %*/
- /*% ripper: args_add_star!(args_new!, $2) %*/
- }
- | case_args ',' arg_value
- {
- /*%%%*/
- check_literal_when(p, $3, &@3);
- $$ = last_arg_append(p, $1, $3, &@$);
- /*% %*/
- /*% ripper: args_add!($1, $3) %*/
- }
- | case_args ',' tSTAR arg_value
- {
- /*%%%*/
- $$ = rest_arg_append(p, $1, $4, &@$);
- /*% %*/
- /*% ripper: args_add_star!($1, $4) %*/
- }
- ;
+ {
+ /*%%%*/
+ check_literal_when(p, $1, &@1);
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: args_add!(args_new!, $1) %*/
+ }
+ | tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = NEW_SPLAT($2, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!(args_new!, $2) %*/
+ }
+ | case_args ',' arg_value
+ {
+ /*%%%*/
+ check_literal_when(p, $3, &@3);
+ $$ = last_arg_append(p, $1, $3, &@$);
+ /*% %*/
+ /*% ripper: args_add!($1, $3) %*/
+ }
+ | case_args ',' tSTAR arg_value
+ {
+ /*%%%*/
+ $$ = rest_arg_append(p, $1, $4, &@$);
+ /*% %*/
+ /*% ripper: args_add_star!($1, $4) %*/
+ }
+ ;
case_body : k_when case_args then
- compstmt
- cases
- {
- /*%%%*/
- $$ = NEW_WHEN($2, $4, $5, &@$);
- fixpos($$, $2);
- /*% %*/
- /*% ripper: when!($2, $4, $5) %*/
- }
- ;
+ compstmt
+ cases
+ {
+ /*%%%*/
+ $$ = NEW_WHEN($2, $4, $5, &@$);
+ fixpos($$, $2);
+ /*% %*/
+ /*% ripper: when!($2, $4, escape_Qundef($5)) %*/
+ }
+ ;
cases : opt_else
- | case_body
- ;
-
-p_pvtbl : {$$ = p->pvtbl; p->pvtbl = st_init_numtable();};
-p_pktbl : {$$ = p->pktbl; p->pktbl = 0;};
-
-p_in_kwarg : {
- $$ = p->ctxt;
- SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
- p->command_start = FALSE;
- p->ctxt.in_kwarg = 1;
- }
- ;
+ | case_body
+ ;
p_case_body : keyword_in
- p_in_kwarg[ctxt] p_pvtbl p_pktbl
- p_top_expr[expr] then
- {
- pop_pktbl(p, $p_pktbl);
- pop_pvtbl(p, $p_pvtbl);
- p->ctxt.in_kwarg = $ctxt.in_kwarg;
- }
- compstmt
- p_cases[cases]
- {
- /*%%%*/
- $$ = NEW_IN($expr, $compstmt, $cases, &@$);
- /*% %*/
- /*% ripper: in!($expr, $compstmt, $cases) %*/
- }
- ;
+ {
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>1 = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ $<tbl>$ = push_pvtbl(p);
+ }
+ {
+ $<tbl>$ = push_pktbl(p);
+ }
+ p_top_expr then
+ {
+ pop_pktbl(p, $<tbl>3);
+ pop_pvtbl(p, $<tbl>2);
+ p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
+ }
+ compstmt
+ p_cases
+ {
+ /*%%%*/
+ $$ = NEW_IN($4, $7, $8, &@$);
+ /*% %*/
+ /*% ripper: in!($4, $7, escape_Qundef($8)) %*/
+ }
+ ;
p_cases : opt_else
- | p_case_body
- ;
+ | p_case_body
+ ;
p_top_expr : p_top_expr_body
- | p_top_expr_body modifier_if expr_value
- {
- /*%%%*/
- $$ = new_if(p, $3, $1, 0, &@$);
- fixpos($$, $3);
- /*% %*/
- /*% ripper: if_mod!($3, $1) %*/
- }
- | p_top_expr_body modifier_unless expr_value
- {
- /*%%%*/
- $$ = new_unless(p, $3, $1, 0, &@$);
- fixpos($$, $3);
- /*% %*/
- /*% ripper: unless_mod!($3, $1) %*/
- }
- ;
+ | p_top_expr_body modifier_if expr_value
+ {
+ /*%%%*/
+ $$ = new_if(p, $3, $1, 0, &@$);
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: if_mod!($3, $1) %*/
+ }
+ | p_top_expr_body modifier_unless expr_value
+ {
+ /*%%%*/
+ $$ = new_unless(p, $3, $1, 0, &@$);
+ fixpos($$, $3);
+ /*% %*/
+ /*% ripper: unless_mod!($3, $1) %*/
+ }
+ ;
p_top_expr_body : p_expr
- | p_expr ','
- {
- $$ = new_array_pattern_tail(p, Qnone, 1, Qnone, Qnone, &@$);
- $$ = new_array_pattern(p, Qnone, get_value($1), $$, &@$);
- }
- | p_expr ',' p_args
- {
- $$ = new_array_pattern(p, Qnone, get_value($1), $3, &@$);
- /*%%%*/
- nd_set_first_loc($$, @1.beg_pos);
- /*%
- %*/
- }
- | p_find
- {
- $$ = new_find_pattern(p, Qnone, $1, &@$);
- }
- | p_args_tail
- {
- $$ = new_array_pattern(p, Qnone, Qnone, $1, &@$);
- }
- | p_kwargs
- {
- $$ = new_hash_pattern(p, Qnone, $1, &@$);
- }
- ;
+ | p_expr ','
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 1, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, Qnone, get_value($1), $$, &@$);
+ }
+ | p_expr ',' p_args
+ {
+ $$ = new_array_pattern(p, Qnone, get_value($1), $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_find
+ {
+ $$ = new_find_pattern(p, Qnone, $1, &@$);
+ }
+ | p_args_tail
+ {
+ $$ = new_array_pattern(p, Qnone, Qnone, $1, &@$);
+ }
+ | p_kwargs
+ {
+ $$ = new_hash_pattern(p, Qnone, $1, &@$);
+ }
+ ;
p_expr : p_as
- ;
+ ;
p_as : p_expr tASSOC p_variable
- {
- /*%%%*/
- NODE *n = NEW_LIST($1, &@$);
- n = list_append(p, n, $3);
- $$ = new_hash(p, n, &@$);
- /*% %*/
- /*% ripper: binary!($1, STATIC_ID2SYM((id_assoc)), $3) %*/
- }
- | p_alt
- ;
+ {
+ /*%%%*/
+ NODE *n = NEW_LIST($1, &@$);
+ n = list_append(p, n, $3);
+ $$ = new_hash(p, n, &@$);
+ /*% %*/
+ /*% ripper: binary!($1, STATIC_ID2SYM((id_assoc)), $3) %*/
+ }
+ | p_alt
+ ;
p_alt : p_alt '|' p_expr_basic
- {
- /*%%%*/
- $$ = NEW_OR($1, $3, &@$);
- /*% %*/
- /*% ripper: binary!($1, STATIC_ID2SYM(idOr), $3) %*/
- }
- | p_expr_basic
- ;
-
-p_lparen : '(' p_pktbl { $$ = $2;};
-p_lbracket : '[' p_pktbl { $$ = $2;};
+ {
+ /*%%%*/
+ $$ = NEW_NODE(NODE_OR, $1, $3, 0, &@$);
+ /*% %*/
+ /*% ripper: binary!($1, STATIC_ID2SYM(idOr), $3) %*/
+ }
+ | p_expr_basic
+ ;
+
+p_lparen : '(' {$<tbl>$ = push_pktbl(p);};
+p_lbracket : '[' {$<tbl>$ = push_pktbl(p);};
p_expr_basic : p_value
- | p_variable
- | p_const p_lparen[p_pktbl] p_args rparen
- {
- pop_pktbl(p, $p_pktbl);
- $$ = new_array_pattern(p, $p_const, Qnone, $p_args, &@$);
- /*%%%*/
- nd_set_first_loc($$, @p_const.beg_pos);
- /*%
- %*/
- }
- | p_const p_lparen[p_pktbl] p_find rparen
- {
- pop_pktbl(p, $p_pktbl);
- $$ = new_find_pattern(p, $p_const, $p_find, &@$);
- /*%%%*/
- nd_set_first_loc($$, @p_const.beg_pos);
- /*%
- %*/
- }
- | p_const p_lparen[p_pktbl] p_kwargs rparen
- {
- pop_pktbl(p, $p_pktbl);
- $$ = new_hash_pattern(p, $p_const, $p_kwargs, &@$);
- /*%%%*/
- nd_set_first_loc($$, @p_const.beg_pos);
- /*%
- %*/
- }
- | p_const '(' rparen
- {
- $$ = new_array_pattern_tail(p, Qnone, 0, Qnone, Qnone, &@$);
- $$ = new_array_pattern(p, $p_const, Qnone, $$, &@$);
- }
- | p_const p_lbracket[p_pktbl] p_args rbracket
- {
- pop_pktbl(p, $p_pktbl);
- $$ = new_array_pattern(p, $p_const, Qnone, $p_args, &@$);
- /*%%%*/
- nd_set_first_loc($$, @p_const.beg_pos);
- /*%
- %*/
- }
- | p_const p_lbracket[p_pktbl] p_find rbracket
- {
- pop_pktbl(p, $p_pktbl);
- $$ = new_find_pattern(p, $p_const, $p_find, &@$);
- /*%%%*/
- nd_set_first_loc($$, @p_const.beg_pos);
- /*%
- %*/
- }
- | p_const p_lbracket[p_pktbl] p_kwargs rbracket
- {
- pop_pktbl(p, $p_pktbl);
- $$ = new_hash_pattern(p, $p_const, $p_kwargs, &@$);
- /*%%%*/
- nd_set_first_loc($$, @p_const.beg_pos);
- /*%
- %*/
- }
- | p_const '[' rbracket
- {
- $$ = new_array_pattern_tail(p, Qnone, 0, Qnone, Qnone, &@$);
- $$ = new_array_pattern(p, $1, Qnone, $$, &@$);
- }
- | tLBRACK p_args rbracket
- {
- $$ = new_array_pattern(p, Qnone, Qnone, $p_args, &@$);
- }
- | tLBRACK p_find rbracket
- {
- $$ = new_find_pattern(p, Qnone, $p_find, &@$);
- }
- | tLBRACK rbracket
- {
- $$ = new_array_pattern_tail(p, Qnone, 0, Qnone, Qnone, &@$);
- $$ = new_array_pattern(p, Qnone, Qnone, $$, &@$);
- }
- | tLBRACE p_pktbl lex_ctxt[ctxt]
- {
- p->ctxt.in_kwarg = 0;
- }
- p_kwargs rbrace
- {
- pop_pktbl(p, $p_pktbl);
- p->ctxt.in_kwarg = $ctxt.in_kwarg;
- $$ = new_hash_pattern(p, Qnone, $p_kwargs, &@$);
- }
- | tLBRACE rbrace
- {
- $$ = new_hash_pattern_tail(p, Qnone, 0, &@$);
- $$ = new_hash_pattern(p, Qnone, $$, &@$);
- }
- | tLPAREN p_pktbl p_expr rparen
- {
- pop_pktbl(p, $p_pktbl);
- $$ = $p_expr;
- }
- ;
+ | p_variable
+ | p_const p_lparen p_args rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_array_pattern(p, $1, Qnone, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const p_lparen p_find rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_find_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const p_lparen p_kwargs rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_hash_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const '(' rparen
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, $1, Qnone, $$, &@$);
+ }
+ | p_const p_lbracket p_args rbracket
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_array_pattern(p, $1, Qnone, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const p_lbracket p_find rbracket
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_find_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const p_lbracket p_kwargs rbracket
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = new_hash_pattern(p, $1, $3, &@$);
+ /*%%%*/
+ nd_set_first_loc($$, @1.beg_pos);
+ /*%
+ %*/
+ }
+ | p_const '[' rbracket
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, $1, Qnone, $$, &@$);
+ }
+ | tLBRACK p_args rbracket
+ {
+ $$ = new_array_pattern(p, Qnone, Qnone, $2, &@$);
+ }
+ | tLBRACK p_find rbracket
+ {
+ $$ = new_find_pattern(p, Qnone, $2, &@$);
+ }
+ | tLBRACK rbracket
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern(p, Qnone, Qnone, $$, &@$);
+ }
+ | tLBRACE
+ {
+ $<tbl>$ = push_pktbl(p);
+ $<ctxt>1 = p->ctxt;
+ p->ctxt.in_kwarg = 0;
+ }
+ p_kwargs rbrace
+ {
+ pop_pktbl(p, $<tbl>2);
+ p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
+ $$ = new_hash_pattern(p, Qnone, $3, &@$);
+ }
+ | tLBRACE rbrace
+ {
+ $$ = new_hash_pattern_tail(p, Qnone, 0, &@$);
+ $$ = new_hash_pattern(p, Qnone, $$, &@$);
+ }
+ | tLPAREN {$<tbl>$ = push_pktbl(p);} p_expr rparen
+ {
+ pop_pktbl(p, $<tbl>2);
+ $$ = $3;
+ }
+ ;
p_args : p_expr
- {
- /*%%%*/
- NODE *pre_args = NEW_LIST($1, &@$);
- $$ = new_array_pattern_tail(p, pre_args, 0, Qnone, Qnone, &@$);
- /*%
- $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, Qnone, Qnone, &@$);
- %*/
- }
- | p_args_head
- {
- $$ = new_array_pattern_tail(p, $1, 1, Qnone, Qnone, &@$);
- }
- | p_args_head p_arg
- {
- /*%%%*/
- $$ = new_array_pattern_tail(p, list_concat($1, $2), 0, Qnone, Qnone, &@$);
- /*%
- VALUE pre_args = rb_ary_concat($1, get_value($2));
- $$ = new_array_pattern_tail(p, pre_args, 0, Qnone, Qnone, &@$);
- %*/
- }
- | p_args_head p_rest
- {
- $$ = new_array_pattern_tail(p, $1, 1, $2, Qnone, &@$);
- }
- | p_args_head p_rest ',' p_args_post
- {
- $$ = new_array_pattern_tail(p, $1, 1, $2, $4, &@$);
- }
- | p_args_tail
- ;
+ {
+ /*%%%*/
+ NODE *pre_args = NEW_LIST($1, &@$);
+ $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
+ /*%
+ $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, 0, Qnone, &@$);
+ %*/
+ }
+ | p_args_head
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, 0, Qnone, &@$);
+ }
+ | p_args_head p_arg
+ {
+ /*%%%*/
+ $$ = new_array_pattern_tail(p, list_concat($1, $2), 0, 0, Qnone, &@$);
+ /*%
+ VALUE pre_args = rb_ary_concat($1, get_value($2));
+ $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
+ %*/
+ }
+ | p_args_head p_rest
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, $2, Qnone, &@$);
+ }
+ | p_args_head p_rest ',' p_args_post
+ {
+ $$ = new_array_pattern_tail(p, $1, 1, $2, $4, &@$);
+ }
+ | p_args_tail
+ ;
p_args_head : p_arg ','
- {
- $$ = $1;
- }
- | p_args_head p_arg ','
- {
- /*%%%*/
- $$ = list_concat($1, $2);
- /*% %*/
- /*% ripper: rb_ary_concat($1, get_value($2)) %*/
- }
- ;
+ {
+ $$ = $1;
+ }
+ | p_args_head p_arg ','
+ {
+ /*%%%*/
+ $$ = list_concat($1, $2);
+ /*% %*/
+ /*% ripper: rb_ary_concat($1, get_value($2)) %*/
+ }
+ ;
p_args_tail : p_rest
- {
- $$ = new_array_pattern_tail(p, Qnone, 1, $1, Qnone, &@$);
- }
- | p_rest ',' p_args_post
- {
- $$ = new_array_pattern_tail(p, Qnone, 1, $1, $3, &@$);
- }
- ;
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 1, $1, Qnone, &@$);
+ }
+ | p_rest ',' p_args_post
+ {
+ $$ = new_array_pattern_tail(p, Qnone, 1, $1, $3, &@$);
+ }
+ ;
p_find : p_rest ',' p_args_post ',' p_rest
- {
- $$ = new_find_pattern_tail(p, $1, $3, $5, &@$);
- }
- ;
+ {
+ $$ = new_find_pattern_tail(p, $1, $3, $5, &@$);
+ }
+ ;
p_rest : tSTAR tIDENTIFIER
- {
- /*%%%*/
- error_duplicate_pattern_variable(p, $2, &@2);
- $$ = assignable(p, $2, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $2)) %*/
- }
- | tSTAR
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: var_field(p, Qnil) %*/
- }
- ;
+ {
+ $$ = $2;
+ }
+ | tSTAR
+ {
+ $$ = 0;
+ }
+ ;
p_args_post : p_arg
- | p_args_post ',' p_arg
- {
- /*%%%*/
- $$ = list_concat($1, $3);
- /*% %*/
- /*% ripper: rb_ary_concat($1, get_value($3)) %*/
- }
- ;
+ | p_args_post ',' p_arg
+ {
+ /*%%%*/
+ $$ = list_concat($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_concat($1, get_value($3)) %*/
+ }
+ ;
p_arg : p_expr
- {
- /*%%%*/
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: rb_ary_new_from_args(1, get_value($1)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: rb_ary_new_from_args(1, get_value($1)) %*/
+ }
+ ;
p_kwargs : p_kwarg ',' p_any_kwrest
- {
- $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), $3, &@$);
- }
- | p_kwarg
- {
- $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), 0, &@$);
- }
- | p_kwarg ','
- {
- $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), 0, &@$);
- }
- | p_any_kwrest
- {
- $$ = new_hash_pattern_tail(p, new_hash(p, Qnone, &@$), $1, &@$);
- }
- ;
+ {
+ $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), $3, &@$);
+ }
+ | p_kwarg
+ {
+ $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), 0, &@$);
+ }
+ | p_kwarg ','
+ {
+ $$ = new_hash_pattern_tail(p, new_unique_key_hash(p, $1, &@$), 0, &@$);
+ }
+ | p_any_kwrest
+ {
+ $$ = new_hash_pattern_tail(p, new_hash(p, Qnone, &@$), $1, &@$);
+ }
+ ;
p_kwarg : p_kw
- /*% ripper[brace]: rb_ary_new_from_args(1, $1) %*/
- | p_kwarg ',' p_kw
- {
- /*%%%*/
- $$ = list_concat($1, $3);
- /*% %*/
- /*% ripper: rb_ary_push($1, $3) %*/
- }
- ;
+ /*% ripper[brace]: rb_ary_new_from_args(1, $1) %*/
+ | p_kwarg ',' p_kw
+ {
+ /*%%%*/
+ $$ = list_concat($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, $3) %*/
+ }
+ ;
p_kw : p_kw_label p_expr
- {
- error_duplicate_pattern_key(p, get_id($1), &@1);
- /*%%%*/
- $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2);
- /*% %*/
- /*% ripper: rb_ary_new_from_args(2, get_value($1), get_value($2)) %*/
- }
- | p_kw_label
- {
- error_duplicate_pattern_key(p, get_id($1), &@1);
- if ($1 && !is_local_id(get_id($1))) {
- yyerror1(&@1, "key must be valid as local variables");
- }
- error_duplicate_pattern_variable(p, get_id($1), &@1);
- /*%%%*/
- $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$), assignable(p, $1, 0, &@$));
- /*% %*/
- /*% ripper: rb_ary_new_from_args(2, get_value(assignable(p, $1)), Qnil) %*/
- }
- ;
+ {
+ error_duplicate_pattern_key(p, get_id($1), &@1);
+ /*%%%*/
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2);
+ /*% %*/
+ /*% ripper: rb_ary_new_from_args(2, get_value($1), get_value($2)) %*/
+ }
+ | p_kw_label
+ {
+ error_duplicate_pattern_key(p, get_id($1), &@1);
+ if ($1 && !is_local_id(get_id($1))) {
+ yyerror1(&@1, "key must be valid as local variables");
+ }
+ error_duplicate_pattern_variable(p, get_id($1), &@1);
+ /*%%%*/
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$), assignable(p, $1, 0, &@$));
+ /*% %*/
+ /*% ripper: rb_ary_new_from_args(2, get_value($1), Qnil) %*/
+ }
+ ;
p_kw_label : tLABEL
- | tSTRING_BEG string_contents tLABEL_END
- {
- YYLTYPE loc = code_loc_gen(&@1, &@3);
- /*%%%*/
- if (!$2 || nd_type_p($2, NODE_STR)) {
- NODE *node = dsym_node(p, $2, &loc);
- $$ = SYM2ID(RNODE_LIT(node)->nd_lit);
- }
- /*%
- if (ripper_is_node_yylval(p, $2) && RNODE_RIPPER($2)->nd_cval) {
- VALUE label = RNODE_RIPPER($2)->nd_cval;
- VALUE rval = RNODE_RIPPER($2)->nd_rval;
- $$ = ripper_new_yylval(p, rb_intern_str(label), rval, label);
- RNODE($$)->nd_loc = loc;
- }
- %*/
- else {
- yyerror1(&loc, "symbol literal with interpolation is not allowed");
- $$ = 0;
- }
- }
- ;
+ | tSTRING_BEG string_contents tLABEL_END
+ {
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ /*%%%*/
+ if (!$2 || nd_type_p($2, NODE_STR)) {
+ NODE *node = dsym_node(p, $2, &loc);
+ $$ = SYM2ID(node->nd_lit);
+ }
+ /*%
+ if (ripper_is_node_yylval($2) && RNODE($2)->nd_cval) {
+ VALUE label = RNODE($2)->nd_cval;
+ VALUE rval = RNODE($2)->nd_rval;
+ $$ = ripper_new_yylval(p, rb_intern_str(label), rval, label);
+ RNODE($$)->nd_loc = loc;
+ }
+ %*/
+ else {
+ yyerror1(&loc, "symbol literal with interpolation is not allowed");
+ $$ = 0;
+ }
+ }
+ ;
p_kwrest : kwrest_mark tIDENTIFIER
- {
- $$ = $2;
- }
- | kwrest_mark
- {
- $$ = 0;
- }
- ;
+ {
+ $$ = $2;
+ }
+ | kwrest_mark
+ {
+ $$ = 0;
+ }
+ ;
p_kwnorest : kwrest_mark keyword_nil
- {
- $$ = 0;
- }
- ;
+ {
+ $$ = 0;
+ }
+ ;
p_any_kwrest : p_kwrest
- | p_kwnorest {$$ = ID2VAL(idNil);}
- ;
+ | p_kwnorest {$$ = ID2VAL(idNil);}
+ ;
p_value : p_primitive
- | p_primitive tDOT2 p_primitive
- {
- /*%%%*/
- value_expr($1);
- value_expr($3);
- $$ = NEW_DOT2($1, $3, &@$);
- /*% %*/
- /*% ripper: dot2!($1, $3) %*/
- }
- | p_primitive tDOT3 p_primitive
- {
- /*%%%*/
- value_expr($1);
- value_expr($3);
- $$ = NEW_DOT3($1, $3, &@$);
- /*% %*/
- /*% ripper: dot3!($1, $3) %*/
- }
- | p_primitive tDOT2
- {
- /*%%%*/
- value_expr($1);
- $$ = NEW_DOT2($1, new_nil_at(p, &@2.end_pos), &@$);
- /*% %*/
- /*% ripper: dot2!($1, Qnil) %*/
- }
- | p_primitive tDOT3
- {
- /*%%%*/
- value_expr($1);
- $$ = NEW_DOT3($1, new_nil_at(p, &@2.end_pos), &@$);
- /*% %*/
- /*% ripper: dot3!($1, Qnil) %*/
- }
- | p_var_ref
- | p_expr_ref
- | p_const
- | tBDOT2 p_primitive
- {
- /*%%%*/
- value_expr($2);
- $$ = NEW_DOT2(new_nil_at(p, &@1.beg_pos), $2, &@$);
- /*% %*/
- /*% ripper: dot2!(Qnil, $2) %*/
- }
- | tBDOT3 p_primitive
- {
- /*%%%*/
- value_expr($2);
- $$ = NEW_DOT3(new_nil_at(p, &@1.beg_pos), $2, &@$);
- /*% %*/
- /*% ripper: dot3!(Qnil, $2) %*/
- }
- ;
+ | p_primitive tDOT2 p_primitive
+ {
+ /*%%%*/
+ value_expr($1);
+ value_expr($3);
+ $$ = NEW_DOT2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, $3) %*/
+ }
+ | p_primitive tDOT3 p_primitive
+ {
+ /*%%%*/
+ value_expr($1);
+ value_expr($3);
+ $$ = NEW_DOT3($1, $3, &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, $3) %*/
+ }
+ | p_primitive tDOT2
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT2($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot2!($1, Qnil) %*/
+ }
+ | p_primitive tDOT3
+ {
+ /*%%%*/
+ value_expr($1);
+ $$ = NEW_DOT3($1, new_nil_at(p, &@2.end_pos), &@$);
+ /*% %*/
+ /*% ripper: dot3!($1, Qnil) %*/
+ }
+ | p_var_ref
+ | p_expr_ref
+ | p_const
+ | tBDOT2 p_primitive
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT2(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot2!(Qnil, $2) %*/
+ }
+ | tBDOT3 p_primitive
+ {
+ /*%%%*/
+ value_expr($2);
+ $$ = NEW_DOT3(new_nil_at(p, &@1.beg_pos), $2, &@$);
+ /*% %*/
+ /*% ripper: dot3!(Qnil, $2) %*/
+ }
+ ;
p_primitive : literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | symbols
- | qsymbols
- | keyword_variable
- {
- /*%%%*/
- if (!($$ = gettable(p, $1, &@$))) $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper: var_ref!($1) %*/
- }
- | lambda
- ;
+ | strings
+ | xstring
+ | regexp
+ | words
+ | qwords
+ | symbols
+ | qsymbols
+ | keyword_variable
+ {
+ /*%%%*/
+ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ | lambda
+ ;
p_variable : tIDENTIFIER
- {
- /*%%%*/
- error_duplicate_pattern_variable(p, $1, &@1);
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- ;
+ {
+ /*%%%*/
+ error_duplicate_pattern_variable(p, $1, &@1);
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ ;
p_var_ref : '^' tIDENTIFIER
- {
- /*%%%*/
- NODE *n = gettable(p, $2, &@$);
- if (!(nd_type_p(n, NODE_LVAR) || nd_type_p(n, NODE_DVAR))) {
- compile_error(p, "%"PRIsVALUE": no such local variable", rb_id2str($2));
- }
- $$ = n;
- /*% %*/
- /*% ripper: var_ref!($2) %*/
- }
+ {
+ /*%%%*/
+ NODE *n = gettable(p, $2, &@$);
+ if (!(nd_type_p(n, NODE_LVAR) || nd_type_p(n, NODE_DVAR))) {
+ compile_error(p, "%"PRIsVALUE": no such local variable", rb_id2str($2));
+ }
+ $$ = n;
+ /*% %*/
+ /*% ripper: var_ref!($2) %*/
+ }
| '^' nonlocal_var
- {
- /*%%%*/
- if (!($$ = gettable(p, $2, &@$))) $$ = NEW_BEGIN(0, &@$);
- /*% %*/
- /*% ripper: var_ref!($2) %*/
+ {
+ /*%%%*/
+ if (!($$ = gettable(p, $2, &@$))) $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($2) %*/
}
- ;
+ ;
p_expr_ref : '^' tLPAREN expr_value rparen
- {
- /*%%%*/
- $$ = NEW_BLOCK($3, &@$);
- /*% %*/
- /*% ripper: begin!($3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_BEGIN($3, &@$);
+ /*% %*/
+ /*% ripper: begin!($3) %*/
+ }
+ ;
p_const : tCOLON3 cname
- {
- /*%%%*/
- $$ = NEW_COLON3($2, &@$);
- /*% %*/
- /*% ripper: top_const_ref!($2) %*/
- }
- | p_const tCOLON2 cname
- {
- /*%%%*/
- $$ = NEW_COLON2($1, $3, &@$);
- /*% %*/
- /*% ripper: const_path_ref!($1, $3) %*/
- }
- | tCONSTANT
- {
- /*%%%*/
- $$ = gettable(p, $1, &@$);
- /*% %*/
- /*% ripper: var_ref!($1) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = NEW_COLON3($2, &@$);
+ /*% %*/
+ /*% ripper: top_const_ref!($2) %*/
+ }
+ | p_const tCOLON2 cname
+ {
+ /*%%%*/
+ $$ = NEW_COLON2($1, $3, &@$);
+ /*% %*/
+ /*% ripper: const_path_ref!($1, $3) %*/
+ }
+ | tCONSTANT
+ {
+ /*%%%*/
+ $$ = gettable(p, $1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ ;
opt_rescue : k_rescue exc_list exc_var then
- compstmt
- opt_rescue
- {
- /*%%%*/
- NODE *body = $5;
- if ($3) {
- NODE *err = NEW_ERRINFO(&@3);
- err = node_assign(p, $3, err, NO_LEX_CTXT, &@3);
- body = block_append(p, err, body);
- }
- $$ = NEW_RESBODY($2, body, $6, &@$);
+ compstmt
+ opt_rescue
+ {
+ /*%%%*/
+ $$ = NEW_RESBODY($2,
+ $3 ? block_append(p, node_assign(p, $3, NEW_ERRINFO(&@3), NO_LEX_CTXT, &@3), $5) : $5,
+ $6, &@$);
+
if ($2) {
fixpos($$, $2);
}
@@ -5594,1082 +4968,1089 @@ opt_rescue : k_rescue exc_list exc_var then
else {
fixpos($$, $5);
}
- /*% %*/
- /*% ripper: rescue!($2, $3, $5, $6) %*/
- }
- | none
- ;
+ /*% %*/
+ /*% ripper: rescue!(escape_Qundef($2), escape_Qundef($3), escape_Qundef($5), escape_Qundef($6)) %*/
+ }
+ | none
+ ;
exc_list : arg_value
- {
- /*%%%*/
- $$ = NEW_LIST($1, &@$);
- /*% %*/
- /*% ripper: rb_ary_new3(1, get_value($1)) %*/
- }
- | mrhs
- {
- /*%%%*/
- if (!($$ = splat_array($1))) $$ = $1;
- /*% %*/
- /*% ripper: $1 %*/
- }
- | none
- ;
+ {
+ /*%%%*/
+ $$ = NEW_LIST($1, &@$);
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
+ }
+ | mrhs
+ {
+ /*%%%*/
+ if (!($$ = splat_array($1))) $$ = $1;
+ /*% %*/
+ /*% ripper: $1 %*/
+ }
+ | none
+ ;
exc_var : tASSOC lhs
- {
- $$ = $2;
- }
- | none
- ;
+ {
+ $$ = $2;
+ }
+ | none
+ ;
opt_ensure : k_ensure compstmt
- {
- p->ctxt.in_rescue = $1.in_rescue;
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: ensure!($2) %*/
- }
- | none
- ;
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: ensure!($2) %*/
+ }
+ | none
+ ;
literal : numeric
- | symbol
- ;
+ | symbol
+ ;
strings : string
- {
- /*%%%*/
- NODE *node = $1;
- if (!node) {
- node = NEW_STR(STR_NEW0(), &@$);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(node)->nd_lit);
- }
- else {
- node = evstr2dstr(p, node);
- }
- $$ = node;
- /*% %*/
- /*% ripper: $1 %*/
- }
- ;
+ {
+ /*%%%*/
+ NODE *node = $1;
+ if (!node) {
+ node = NEW_STR(STR_NEW0(), &@$);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit);
+ }
+ else {
+ node = evstr2dstr(p, node);
+ }
+ $$ = node;
+ /*% %*/
+ /*% ripper: $1 %*/
+ }
+ ;
string : tCHAR
- | string1
- | string string1
- {
- /*%%%*/
- $$ = literal_concat(p, $1, $2, &@$);
- /*% %*/
- /*% ripper: string_concat!($1, $2) %*/
- }
- ;
+ | string1
+ | string string1
+ {
+ /*%%%*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: string_concat!($1, $2) %*/
+ }
+ ;
string1 : tSTRING_BEG string_contents tSTRING_END
- {
- /*%%%*/
- $$ = heredoc_dedent(p, $2);
- if ($$) nd_set_loc($$, &@$);
- /*% %*/
- /*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = heredoc_dedent(p, $2);
+ if ($$) nd_set_loc($$, &@$);
+ /*% %*/
+ /*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
+ }
+ ;
xstring : tXSTRING_BEG xstring_contents tSTRING_END
- {
- /*%%%*/
- $$ = new_xstring(p, heredoc_dedent(p, $2), &@$);
- /*% %*/
- /*% ripper: xstring_literal!(heredoc_dedent(p, $2)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = new_xstring(p, heredoc_dedent(p, $2), &@$);
+ /*% %*/
+ /*% ripper: xstring_literal!(heredoc_dedent(p, $2)) %*/
+ }
+ ;
regexp : tREGEXP_BEG regexp_contents tREGEXP_END
- {
- $$ = new_regexp(p, $2, $3, &@$);
- }
- ;
-
-words_sep : ' ' {}
- | words_sep ' '
- ;
-
-words : tWORDS_BEG words_sep word_list tSTRING_END
- {
- /*%%%*/
- $$ = make_list($3, &@$);
- /*% %*/
- /*% ripper: array!($3) %*/
- }
- ;
+ {
+ $$ = new_regexp(p, $2, $3, &@$);
+ }
+ ;
+
+words : tWORDS_BEG ' ' word_list tSTRING_END
+ {
+ /*%%%*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
+ }
+ ;
word_list : /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: words_new! %*/
- }
- | word_list word words_sep
- {
- /*%%%*/
- $$ = list_append(p, $1, evstr2dstr(p, $2));
- /*% %*/
- /*% ripper: words_add!($1, $2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: words_new! %*/
+ }
+ | word_list word ' '
+ {
+ /*%%%*/
+ $$ = list_append(p, $1, evstr2dstr(p, $2));
+ /*% %*/
+ /*% ripper: words_add!($1, $2) %*/
+ }
+ ;
word : string_content
- /*% ripper[brace]: word_add!(word_new!, $1) %*/
- | word string_content
- {
- /*%%%*/
- $$ = literal_concat(p, $1, $2, &@$);
- /*% %*/
- /*% ripper: word_add!($1, $2) %*/
- }
- ;
-
-symbols : tSYMBOLS_BEG words_sep symbol_list tSTRING_END
- {
- /*%%%*/
- $$ = make_list($3, &@$);
- /*% %*/
- /*% ripper: array!($3) %*/
- }
- ;
+ /*% ripper[brace]: word_add!(word_new!, $1) %*/
+ | word string_content
+ {
+ /*%%%*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: word_add!($1, $2) %*/
+ }
+ ;
+
+symbols : tSYMBOLS_BEG ' ' symbol_list tSTRING_END
+ {
+ /*%%%*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
+ }
+ ;
symbol_list : /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: symbols_new! %*/
- }
- | symbol_list word words_sep
- {
- /*%%%*/
- $$ = symbol_append(p, $1, evstr2dstr(p, $2));
- /*% %*/
- /*% ripper: symbols_add!($1, $2) %*/
- }
- ;
-
-qwords : tQWORDS_BEG words_sep qword_list tSTRING_END
- {
- /*%%%*/
- $$ = make_list($3, &@$);
- /*% %*/
- /*% ripper: array!($3) %*/
- }
- ;
-
-qsymbols : tQSYMBOLS_BEG words_sep qsym_list tSTRING_END
- {
- /*%%%*/
- $$ = make_list($3, &@$);
- /*% %*/
- /*% ripper: array!($3) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: symbols_new! %*/
+ }
+ | symbol_list word ' '
+ {
+ /*%%%*/
+ $$ = symbol_append(p, $1, evstr2dstr(p, $2));
+ /*% %*/
+ /*% ripper: symbols_add!($1, $2) %*/
+ }
+ ;
+
+qwords : tQWORDS_BEG ' ' qword_list tSTRING_END
+ {
+ /*%%%*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
+ }
+ ;
+
+qsymbols : tQSYMBOLS_BEG ' ' qsym_list tSTRING_END
+ {
+ /*%%%*/
+ $$ = make_list($3, &@$);
+ /*% %*/
+ /*% ripper: array!($3) %*/
+ }
+ ;
qword_list : /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: qwords_new! %*/
- }
- | qword_list tSTRING_CONTENT words_sep
- {
- /*%%%*/
- $$ = list_append(p, $1, $2);
- /*% %*/
- /*% ripper: qwords_add!($1, $2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: qwords_new! %*/
+ }
+ | qword_list tSTRING_CONTENT ' '
+ {
+ /*%%%*/
+ $$ = list_append(p, $1, $2);
+ /*% %*/
+ /*% ripper: qwords_add!($1, $2) %*/
+ }
+ ;
qsym_list : /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: qsymbols_new! %*/
- }
- | qsym_list tSTRING_CONTENT words_sep
- {
- /*%%%*/
- $$ = symbol_append(p, $1, $2);
- /*% %*/
- /*% ripper: qsymbols_add!($1, $2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: qsymbols_new! %*/
+ }
+ | qsym_list tSTRING_CONTENT ' '
+ {
+ /*%%%*/
+ $$ = symbol_append(p, $1, $2);
+ /*% %*/
+ /*% ripper: qsymbols_add!($1, $2) %*/
+ }
+ ;
string_contents : /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: string_content! %*/
- /*%%%*/
- /*%
- $$ = ripper_new_yylval(p, 0, $$, 0);
- %*/
- }
- | string_contents string_content
- {
- /*%%%*/
- $$ = literal_concat(p, $1, $2, &@$);
- /*% %*/
- /*% ripper: string_add!($1, $2) %*/
- /*%%%*/
- /*%
- if (ripper_is_node_yylval(p, $1) && ripper_is_node_yylval(p, $2) &&
- !RNODE_RIPPER($1)->nd_cval) {
- RNODE_RIPPER($1)->nd_cval = RNODE_RIPPER($2)->nd_cval;
- RNODE_RIPPER($1)->nd_rval = add_mark_object(p, $$);
- $$ = $1;
- }
- %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: string_content! %*/
+ /*%%%*/
+ /*%
+ $$ = ripper_new_yylval(p, 0, $$, 0);
+ %*/
+ }
+ | string_contents string_content
+ {
+ /*%%%*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: string_add!($1, $2) %*/
+ /*%%%*/
+ /*%
+ if (ripper_is_node_yylval($1) && ripper_is_node_yylval($2) &&
+ !RNODE($1)->nd_cval) {
+ RNODE($1)->nd_cval = RNODE($2)->nd_cval;
+ RNODE($1)->nd_rval = add_mark_object(p, $$);
+ $$ = $1;
+ }
+ %*/
+ }
+ ;
xstring_contents: /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: xstring_new! %*/
- }
- | xstring_contents string_content
- {
- /*%%%*/
- $$ = literal_concat(p, $1, $2, &@$);
- /*% %*/
- /*% ripper: xstring_add!($1, $2) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: xstring_new! %*/
+ }
+ | xstring_contents string_content
+ {
+ /*%%%*/
+ $$ = literal_concat(p, $1, $2, &@$);
+ /*% %*/
+ /*% ripper: xstring_add!($1, $2) %*/
+ }
+ ;
regexp_contents: /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: regexp_new! %*/
- /*%%%*/
- /*%
- $$ = ripper_new_yylval(p, 0, $$, 0);
- %*/
- }
- | regexp_contents string_content
- {
- /*%%%*/
- NODE *head = $1, *tail = $2;
- if (!head) {
- $$ = tail;
- }
- else if (!tail) {
- $$ = head;
- }
- else {
- switch (nd_type(head)) {
- case NODE_STR:
- head = str2dstr(p, head);
- break;
- case NODE_DSTR:
- break;
- default:
- head = list_append(p, NEW_DSTR(Qnil, &@$), head);
- break;
- }
- $$ = list_append(p, head, tail);
- }
- /*%
- VALUE s1 = 1, s2 = 0, n1 = $1, n2 = $2;
- if (ripper_is_node_yylval(p, n1)) {
- s1 = RNODE_RIPPER(n1)->nd_cval;
- n1 = RNODE_RIPPER(n1)->nd_rval;
- }
- if (ripper_is_node_yylval(p, n2)) {
- s2 = RNODE_RIPPER(n2)->nd_cval;
- n2 = RNODE_RIPPER(n2)->nd_rval;
- }
- $$ = dispatch2(regexp_add, n1, n2);
- if (!s1 && s2) {
- $$ = ripper_new_yylval(p, 0, $$, s2);
- }
- %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: regexp_new! %*/
+ /*%%%*/
+ /*%
+ $$ = ripper_new_yylval(p, 0, $$, 0);
+ %*/
+ }
+ | regexp_contents string_content
+ {
+ /*%%%*/
+ NODE *head = $1, *tail = $2;
+ if (!head) {
+ $$ = tail;
+ }
+ else if (!tail) {
+ $$ = head;
+ }
+ else {
+ switch (nd_type(head)) {
+ case NODE_STR:
+ nd_set_type(head, NODE_DSTR);
+ break;
+ case NODE_DSTR:
+ break;
+ default:
+ head = list_append(p, NEW_DSTR(Qnil, &@$), head);
+ break;
+ }
+ $$ = list_append(p, head, tail);
+ }
+ /*%
+ VALUE s1 = 1, s2 = 0, n1 = $1, n2 = $2;
+ if (ripper_is_node_yylval(n1)) {
+ s1 = RNODE(n1)->nd_cval;
+ n1 = RNODE(n1)->nd_rval;
+ }
+ if (ripper_is_node_yylval(n2)) {
+ s2 = RNODE(n2)->nd_cval;
+ n2 = RNODE(n2)->nd_rval;
+ }
+ $$ = dispatch2(regexp_add, n1, n2);
+ if (!s1 && s2) {
+ $$ = ripper_new_yylval(p, 0, $$, s2);
+ }
+ %*/
+ }
+ ;
string_content : tSTRING_CONTENT
- /*% ripper[brace]: ripper_new_yylval(p, 0, get_value($1), $1) %*/
- | tSTRING_DVAR
- {
- /* need to backup p->lex.strterm so that a string literal `%&foo,#$&,bar&` can be parsed */
- $<strterm>$ = p->lex.strterm;
- p->lex.strterm = 0;
- SET_LEX_STATE(EXPR_BEG);
- }
- string_dvar
- {
- p->lex.strterm = $<strterm>2;
- /*%%%*/
- $$ = NEW_EVSTR($3, &@$);
- nd_set_line($$, @3.end_pos.lineno);
- /*% %*/
- /*% ripper: string_dvar!($3) %*/
- }
- | tSTRING_DBEG[term]
- {
- CMDARG_PUSH(0);
- COND_PUSH(0);
- /* need to backup p->lex.strterm so that a string literal `%!foo,#{ !0 },bar!` can be parsed */
- $<strterm>term = p->lex.strterm;
- p->lex.strterm = 0;
- $<num>$ = p->lex.state;
- SET_LEX_STATE(EXPR_BEG);
- }[state]
- {
- $<num>$ = p->lex.brace_nest;
- p->lex.brace_nest = 0;
- }[brace]
- {
- $<num>$ = p->heredoc_indent;
- p->heredoc_indent = 0;
- }[indent]
- compstmt string_dend
- {
- COND_POP();
- CMDARG_POP();
- p->lex.strterm = $<strterm>term;
- SET_LEX_STATE($<num>state);
- p->lex.brace_nest = $<num>brace;
- p->heredoc_indent = $<num>indent;
- p->heredoc_line_indent = -1;
- /*%%%*/
- if ($compstmt) nd_unset_fl_newline($compstmt);
- $$ = new_evstr(p, $compstmt, &@$);
- /*% %*/
- /*% ripper: string_embexpr!($compstmt) %*/
- }
- ;
-
-string_dend : tSTRING_DEND
- | END_OF_INPUT
- ;
-
-string_dvar : nonlocal_var
- {
- /*%%%*/
- if (!($$ = gettable(p, $1, &@$))) $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper: var_ref!($1) %*/
- }
- | backref
- ;
+ /*% ripper[brace]: ripper_new_yylval(p, 0, get_value($1), $1) %*/
+ | tSTRING_DVAR
+ {
+ /* need to backup p->lex.strterm so that a string literal `%&foo,#$&,bar&` can be parsed */
+ $<strterm>$ = p->lex.strterm;
+ p->lex.strterm = 0;
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ string_dvar
+ {
+ p->lex.strterm = $<strterm>2;
+ /*%%%*/
+ $$ = NEW_EVSTR($3, &@$);
+ nd_set_line($$, @3.end_pos.lineno);
+ /*% %*/
+ /*% ripper: string_dvar!($3) %*/
+ }
+ | tSTRING_DBEG
+ {
+ CMDARG_PUSH(0);
+ COND_PUSH(0);
+ }
+ {
+ /* need to backup p->lex.strterm so that a string literal `%!foo,#{ !0 },bar!` can be parsed */
+ $<strterm>$ = p->lex.strterm;
+ p->lex.strterm = 0;
+ }
+ {
+ $<num>$ = p->lex.state;
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ {
+ $<num>$ = p->lex.brace_nest;
+ p->lex.brace_nest = 0;
+ }
+ {
+ $<num>$ = p->heredoc_indent;
+ p->heredoc_indent = 0;
+ }
+ compstmt tSTRING_DEND
+ {
+ COND_POP();
+ CMDARG_POP();
+ p->lex.strterm = $<strterm>3;
+ SET_LEX_STATE($<num>4);
+ p->lex.brace_nest = $<num>5;
+ p->heredoc_indent = $<num>6;
+ p->heredoc_line_indent = -1;
+ /*%%%*/
+ if ($7) $7->flags &= ~NODE_FL_NEWLINE;
+ $$ = new_evstr(p, $7, &@$);
+ /*% %*/
+ /*% ripper: string_embexpr!($7) %*/
+ }
+ ;
+
+string_dvar : tGVAR
+ {
+ /*%%%*/
+ $$ = NEW_GVAR($1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ | tIVAR
+ {
+ /*%%%*/
+ $$ = NEW_IVAR($1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ | tCVAR
+ {
+ /*%%%*/
+ $$ = NEW_CVAR($1, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ | backref
+ ;
symbol : ssym
- | dsym
- ;
+ | dsym
+ ;
ssym : tSYMBEG sym
- {
- SET_LEX_STATE(EXPR_END);
- /*%%%*/
- $$ = NEW_LIT(ID2SYM($2), &@$);
- /*% %*/
- /*% ripper: symbol_literal!(symbol!($2)) %*/
- }
- ;
+ {
+ SET_LEX_STATE(EXPR_END);
+ /*%%%*/
+ $$ = NEW_LIT(ID2SYM($2), &@$);
+ /*% %*/
+ /*% ripper: symbol_literal!(symbol!($2)) %*/
+ }
+ ;
sym : fname
- | nonlocal_var
- ;
+ | nonlocal_var
+ ;
dsym : tSYMBEG string_contents tSTRING_END
- {
- SET_LEX_STATE(EXPR_END);
- /*%%%*/
- $$ = dsym_node(p, $2, &@$);
- /*% %*/
- /*% ripper: dyna_symbol!($2) %*/
- }
- ;
+ {
+ SET_LEX_STATE(EXPR_END);
+ /*%%%*/
+ $$ = dsym_node(p, $2, &@$);
+ /*% %*/
+ /*% ripper: dyna_symbol!($2) %*/
+ }
+ ;
numeric : simple_numeric
- | tUMINUS_NUM simple_numeric %prec tLOWEST
- {
- /*%%%*/
- $$ = $2;
- RB_OBJ_WRITE(p->ast, &RNODE_LIT($$)->nd_lit, negate_lit(p, RNODE_LIT($$)->nd_lit));
- /*% %*/
- /*% ripper: unary!(ID2VAL(idUMinus), $2) %*/
- }
- ;
+ | tUMINUS_NUM simple_numeric %prec tLOWEST
+ {
+ /*%%%*/
+ $$ = $2;
+ RB_OBJ_WRITE(p->ast, &$$->nd_lit, negate_lit(p, $$->nd_lit));
+ /*% %*/
+ /*% ripper: unary!(ID2VAL(idUMinus), $2) %*/
+ }
+ ;
simple_numeric : tINTEGER
- | tFLOAT
- | tRATIONAL
- | tIMAGINARY
- ;
+ | tFLOAT
+ | tRATIONAL
+ | tIMAGINARY
+ ;
nonlocal_var : tIVAR
- | tGVAR
- | tCVAR
- ;
+ | tGVAR
+ | tCVAR
+ ;
user_variable : tIDENTIFIER
- | tCONSTANT
- | nonlocal_var
- ;
+ | tCONSTANT
+ | nonlocal_var
+ ;
keyword_variable: keyword_nil {$$ = KWD2EID(nil, $1);}
- | keyword_self {$$ = KWD2EID(self, $1);}
- | keyword_true {$$ = KWD2EID(true, $1);}
- | keyword_false {$$ = KWD2EID(false, $1);}
- | keyword__FILE__ {$$ = KWD2EID(_FILE__, $1);}
- | keyword__LINE__ {$$ = KWD2EID(_LINE__, $1);}
- | keyword__ENCODING__ {$$ = KWD2EID(_ENCODING__, $1);}
- ;
+ | keyword_self {$$ = KWD2EID(self, $1);}
+ | keyword_true {$$ = KWD2EID(true, $1);}
+ | keyword_false {$$ = KWD2EID(false, $1);}
+ | keyword__FILE__ {$$ = KWD2EID(_FILE__, $1);}
+ | keyword__LINE__ {$$ = KWD2EID(_LINE__, $1);}
+ | keyword__ENCODING__ {$$ = KWD2EID(_ENCODING__, $1);}
+ ;
var_ref : user_variable
- {
- /*%%%*/
- if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
- /*%
- if (id_is_var(p, get_id($1))) {
- $$ = dispatch1(var_ref, $1);
- }
- else {
- $$ = dispatch1(vcall, $1);
- }
- %*/
- }
- | keyword_variable
- {
- /*%%%*/
- if (!($$ = gettable(p, $1, &@$))) $$ = NEW_ERROR(&@$);
- /*% %*/
- /*% ripper: var_ref!($1) %*/
- }
- ;
+ {
+ /*%%%*/
+ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
+ /*%
+ if (id_is_var(p, get_id($1))) {
+ $$ = dispatch1(var_ref, $1);
+ }
+ else {
+ $$ = dispatch1(vcall, $1);
+ }
+ %*/
+ }
+ | keyword_variable
+ {
+ /*%%%*/
+ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
+ /*% %*/
+ /*% ripper: var_ref!($1) %*/
+ }
+ ;
var_lhs : user_variable
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- | keyword_variable
- {
- /*%%%*/
- $$ = assignable(p, $1, 0, &@$);
- /*% %*/
- /*% ripper: assignable(p, var_field(p, $1)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ | keyword_variable
+ {
+ /*%%%*/
+ $$ = assignable(p, $1, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $1)) %*/
+ }
+ ;
backref : tNTH_REF
- | tBACK_REF
- ;
+ | tBACK_REF
+ ;
superclass : '<'
- {
- SET_LEX_STATE(EXPR_BEG);
- p->command_start = TRUE;
- }
- expr_value term
- {
- $$ = $3;
- }
- | /* none */
- {
- /*%%%*/
- $$ = 0;
- /*% %*/
- /*% ripper: Qnil %*/
- }
- ;
+ {
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ }
+ expr_value term
+ {
+ $$ = $3;
+ }
+ | /* none */
+ {
+ /*%%%*/
+ $$ = 0;
+ /*% %*/
+ /*% ripper: Qnil %*/
+ }
+ ;
f_opt_paren_args: f_paren_args
- | none
- {
- p->ctxt.in_argdef = 0;
- $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
- $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $$, &@0);
- }
- ;
+ | none
+ {
+ p->ctxt.in_argdef = 0;
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $$, &@0);
+ }
+ ;
f_paren_args : '(' f_args rparen
- {
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: paren!($2) %*/
- SET_LEX_STATE(EXPR_BEG);
- p->command_start = TRUE;
- p->ctxt.in_argdef = 0;
- }
+ {
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: paren!($2) %*/
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ p->ctxt.in_argdef = 0;
+ }
;
f_arglist : f_paren_args
- | {
- $<ctxt>$ = p->ctxt;
- p->ctxt.in_kwarg = 1;
- p->ctxt.in_argdef = 1;
- SET_LEX_STATE(p->lex.state|EXPR_LABEL); /* force for args */
- }
- f_args term
- {
- p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
- p->ctxt.in_argdef = 0;
- $$ = $2;
- SET_LEX_STATE(EXPR_BEG);
- p->command_start = TRUE;
- }
- ;
+ | {
+ $<ctxt>$ = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ p->ctxt.in_argdef = 1;
+ SET_LEX_STATE(p->lex.state|EXPR_LABEL); /* force for args */
+ }
+ f_args term
+ {
+ p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
+ p->ctxt.in_argdef = 0;
+ $$ = $2;
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ }
+ ;
args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
- {
- $$ = new_args_tail(p, $1, $3, $4, &@3);
- }
- | f_kwarg opt_f_block_arg
- {
- $$ = new_args_tail(p, $1, Qnone, $2, &@1);
- }
- | f_any_kwrest opt_f_block_arg
- {
- $$ = new_args_tail(p, Qnone, $1, $2, &@1);
- }
- | f_block_arg
- {
- $$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
- }
- | args_forward
- {
- add_forwarding_args(p);
- $$ = new_args_tail(p, Qnone, $1, arg_FWD_BLOCK, &@1);
- /*%%%*/
- $$->nd_ainfo.forwarding = 1;
- /*% %*/
- }
- ;
+ {
+ $$ = new_args_tail(p, $1, $3, $4, &@3);
+ }
+ | f_kwarg opt_f_block_arg
+ {
+ $$ = new_args_tail(p, $1, Qnone, $2, &@1);
+ }
+ | f_any_kwrest opt_f_block_arg
+ {
+ $$ = new_args_tail(p, Qnone, $1, $2, &@1);
+ }
+ | f_block_arg
+ {
+ $$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
+ }
+ | args_forward
+ {
+ add_forwarding_args(p);
+ $$ = new_args_tail(p, Qnone, $1, ID2VAL(idFWD_BLOCK), &@1);
+ /*%%%*/
+ ($$->nd_ainfo)->forwarding = 1;
+ /*% %*/
+ }
+ ;
opt_args_tail : ',' args_tail
- {
- $$ = $2;
- }
- | /* none */
- {
- $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
- }
- ;
+ {
+ $$ = $2;
+ }
+ | /* none */
+ {
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
+ }
+ ;
f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
- {
- $$ = new_args(p, $1, $3, $5, Qnone, $6, &@$);
- }
- | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
- {
- $$ = new_args(p, $1, $3, $5, $7, $8, &@$);
- }
- | f_arg ',' f_optarg opt_args_tail
- {
- $$ = new_args(p, $1, $3, Qnone, Qnone, $4, &@$);
- }
- | f_arg ',' f_optarg ',' f_arg opt_args_tail
- {
- $$ = new_args(p, $1, $3, Qnone, $5, $6, &@$);
- }
- | f_arg ',' f_rest_arg opt_args_tail
- {
- $$ = new_args(p, $1, Qnone, $3, Qnone, $4, &@$);
- }
- | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
- {
- $$ = new_args(p, $1, Qnone, $3, $5, $6, &@$);
- }
- | f_arg opt_args_tail
- {
- $$ = new_args(p, $1, Qnone, Qnone, Qnone, $2, &@$);
- }
- | f_optarg ',' f_rest_arg opt_args_tail
- {
- $$ = new_args(p, Qnone, $1, $3, Qnone, $4, &@$);
- }
- | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
- {
- $$ = new_args(p, Qnone, $1, $3, $5, $6, &@$);
- }
- | f_optarg opt_args_tail
- {
- $$ = new_args(p, Qnone, $1, Qnone, Qnone, $2, &@$);
- }
- | f_optarg ',' f_arg opt_args_tail
- {
- $$ = new_args(p, Qnone, $1, Qnone, $3, $4, &@$);
- }
- | f_rest_arg opt_args_tail
- {
- $$ = new_args(p, Qnone, Qnone, $1, Qnone, $2, &@$);
- }
- | f_rest_arg ',' f_arg opt_args_tail
- {
- $$ = new_args(p, Qnone, Qnone, $1, $3, $4, &@$);
- }
- | args_tail
- {
- $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $1, &@$);
- }
- | /* none */
- {
- $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
- $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $$, &@0);
- }
- ;
+ {
+ $$ = new_args(p, $1, $3, $5, Qnone, $6, &@$);
+ }
+ | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
+ {
+ $$ = new_args(p, $1, $3, $5, $7, $8, &@$);
+ }
+ | f_arg ',' f_optarg opt_args_tail
+ {
+ $$ = new_args(p, $1, $3, Qnone, Qnone, $4, &@$);
+ }
+ | f_arg ',' f_optarg ',' f_arg opt_args_tail
+ {
+ $$ = new_args(p, $1, $3, Qnone, $5, $6, &@$);
+ }
+ | f_arg ',' f_rest_arg opt_args_tail
+ {
+ $$ = new_args(p, $1, Qnone, $3, Qnone, $4, &@$);
+ }
+ | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
+ {
+ $$ = new_args(p, $1, Qnone, $3, $5, $6, &@$);
+ }
+ | f_arg opt_args_tail
+ {
+ $$ = new_args(p, $1, Qnone, Qnone, Qnone, $2, &@$);
+ }
+ | f_optarg ',' f_rest_arg opt_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, $3, Qnone, $4, &@$);
+ }
+ | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, $3, $5, $6, &@$);
+ }
+ | f_optarg opt_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, Qnone, Qnone, $2, &@$);
+ }
+ | f_optarg ',' f_arg opt_args_tail
+ {
+ $$ = new_args(p, Qnone, $1, Qnone, $3, $4, &@$);
+ }
+ | f_rest_arg opt_args_tail
+ {
+ $$ = new_args(p, Qnone, Qnone, $1, Qnone, $2, &@$);
+ }
+ | f_rest_arg ',' f_arg opt_args_tail
+ {
+ $$ = new_args(p, Qnone, Qnone, $1, $3, $4, &@$);
+ }
+ | args_tail
+ {
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $1, &@$);
+ }
+ | /* none */
+ {
+ $$ = new_args_tail(p, Qnone, Qnone, Qnone, &@0);
+ $$ = new_args(p, Qnone, Qnone, Qnone, Qnone, $$, &@0);
+ }
+ ;
args_forward : tBDOT3
- {
- /*%%%*/
+ {
+ /*%%%*/
#ifdef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
- $$ = 0;
+ $$ = 0;
#else
- $$ = idFWD_KWREST;
+ $$ = idFWD_KWREST;
#endif
- /*% %*/
- /*% ripper: args_forward! %*/
- }
- ;
+ /*% %*/
+ /*% ripper: args_forward! %*/
+ }
+ ;
f_bad_arg : tCONSTANT
- {
- static const char mesg[] = "formal argument cannot be a constant";
- /*%%%*/
- yyerror1(&@1, mesg);
- $$ = 0;
- /*% %*/
- /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
- }
- | tIVAR
- {
- static const char mesg[] = "formal argument cannot be an instance variable";
- /*%%%*/
- yyerror1(&@1, mesg);
- $$ = 0;
- /*% %*/
- /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
- }
- | tGVAR
- {
- static const char mesg[] = "formal argument cannot be a global variable";
- /*%%%*/
- yyerror1(&@1, mesg);
- $$ = 0;
- /*% %*/
- /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
- }
- | tCVAR
- {
- static const char mesg[] = "formal argument cannot be a class variable";
- /*%%%*/
- yyerror1(&@1, mesg);
- $$ = 0;
- /*% %*/
- /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
- }
- ;
+ {
+ static const char mesg[] = "formal argument cannot be a constant";
+ /*%%%*/
+ yyerror1(&@1, mesg);
+ $$ = 0;
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
+ }
+ | tIVAR
+ {
+ static const char mesg[] = "formal argument cannot be an instance variable";
+ /*%%%*/
+ yyerror1(&@1, mesg);
+ $$ = 0;
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
+ }
+ | tGVAR
+ {
+ static const char mesg[] = "formal argument cannot be a global variable";
+ /*%%%*/
+ yyerror1(&@1, mesg);
+ $$ = 0;
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
+ }
+ | tCVAR
+ {
+ static const char mesg[] = "formal argument cannot be a class variable";
+ /*%%%*/
+ yyerror1(&@1, mesg);
+ $$ = 0;
+ /*% %*/
+ /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
+ }
+ ;
f_norm_arg : f_bad_arg
- | tIDENTIFIER
- {
- formal_argument(p, $1);
- p->max_numparam = ORDINAL_PARAM;
- $$ = $1;
- }
- ;
+ | tIDENTIFIER
+ {
+ formal_argument(p, $1);
+ p->max_numparam = ORDINAL_PARAM;
+ $$ = $1;
+ }
+ ;
f_arg_asgn : f_norm_arg
- {
- ID id = get_id($1);
- arg_var(p, id);
- p->cur_arg = id;
- $$ = $1;
- }
- ;
+ {
+ ID id = get_id($1);
+ arg_var(p, id);
+ p->cur_arg = id;
+ $$ = $1;
+ }
+ ;
f_arg_item : f_arg_asgn
- {
- p->cur_arg = 0;
- /*%%%*/
- $$ = NEW_ARGS_AUX($1, 1, &NULL_LOC);
- /*% %*/
- /*% ripper: get_value($1) %*/
- }
- | tLPAREN f_margs rparen
- {
- /*%%%*/
- ID tid = internal_id(p);
- YYLTYPE loc;
- loc.beg_pos = @2.beg_pos;
- loc.end_pos = @2.beg_pos;
- arg_var(p, tid);
- if (dyna_in_block(p)) {
- $2->nd_value = NEW_DVAR(tid, &loc);
- }
- else {
- $2->nd_value = NEW_LVAR(tid, &loc);
- }
- $$ = NEW_ARGS_AUX(tid, 1, &NULL_LOC);
- $$->nd_next = (NODE *)$2;
- /*% %*/
- /*% ripper: mlhs_paren!($2) %*/
- }
- ;
+ {
+ p->cur_arg = 0;
+ /*%%%*/
+ $$ = NEW_ARGS_AUX($1, 1, &NULL_LOC);
+ /*% %*/
+ /*% ripper: get_value($1) %*/
+ }
+ | tLPAREN f_margs rparen
+ {
+ /*%%%*/
+ ID tid = internal_id(p);
+ YYLTYPE loc;
+ loc.beg_pos = @2.beg_pos;
+ loc.end_pos = @2.beg_pos;
+ arg_var(p, tid);
+ if (dyna_in_block(p)) {
+ $2->nd_value = NEW_DVAR(tid, &loc);
+ }
+ else {
+ $2->nd_value = NEW_LVAR(tid, &loc);
+ }
+ $$ = NEW_ARGS_AUX(tid, 1, &NULL_LOC);
+ $$->nd_next = $2;
+ /*% %*/
+ /*% ripper: mlhs_paren!($2) %*/
+ }
+ ;
f_arg : f_arg_item
- /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
- | f_arg ',' f_arg_item
- {
- /*%%%*/
- $$ = $1;
- $$->nd_plen++;
- $$->nd_next = block_append(p, $$->nd_next, $3->nd_next);
- rb_discard_node(p, (NODE *)$3);
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($3)) %*/
- }
- ;
+ /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
+ | f_arg ',' f_arg_item
+ {
+ /*%%%*/
+ $$ = $1;
+ $$->nd_plen++;
+ $$->nd_next = block_append(p, $$->nd_next, $3->nd_next);
+ rb_discard_node(p, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
+ }
+ ;
f_label : tLABEL
- {
- arg_var(p, formal_argument(p, $1));
- p->cur_arg = get_id($1);
- p->max_numparam = ORDINAL_PARAM;
- p->ctxt.in_argdef = 0;
- $$ = $1;
- }
- ;
+ {
+ arg_var(p, formal_argument(p, $1));
+ p->cur_arg = get_id($1);
+ p->max_numparam = ORDINAL_PARAM;
+ p->ctxt.in_argdef = 0;
+ $$ = $1;
+ }
+ ;
f_kw : f_label arg_value
- {
- p->cur_arg = 0;
- p->ctxt.in_argdef = 1;
- /*%%%*/
- $$ = new_kw_arg(p, assignable(p, $1, $2, &@$), &@$);
- /*% %*/
- /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
- }
- | f_label
- {
- p->cur_arg = 0;
- p->ctxt.in_argdef = 1;
- /*%%%*/
- $$ = new_kw_arg(p, assignable(p, $1, NODE_SPECIAL_REQUIRED_KEYWORD, &@$), &@$);
- /*% %*/
- /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
- }
- ;
+ {
+ p->cur_arg = 0;
+ p->ctxt.in_argdef = 1;
+ /*%%%*/
+ $$ = new_kw_arg(p, assignable(p, $1, $2, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
+ }
+ | f_label
+ {
+ p->cur_arg = 0;
+ p->ctxt.in_argdef = 1;
+ /*%%%*/
+ $$ = new_kw_arg(p, assignable(p, $1, NODE_SPECIAL_REQUIRED_KEYWORD, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
+ }
+ ;
f_block_kw : f_label primary_value
- {
- p->ctxt.in_argdef = 1;
- /*%%%*/
- $$ = new_kw_arg(p, assignable(p, $1, $2, &@$), &@$);
- /*% %*/
- /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
- }
- | f_label
- {
- p->ctxt.in_argdef = 1;
- /*%%%*/
- $$ = new_kw_arg(p, assignable(p, $1, NODE_SPECIAL_REQUIRED_KEYWORD, &@$), &@$);
- /*% %*/
- /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
- }
- ;
+ {
+ p->ctxt.in_argdef = 1;
+ /*%%%*/
+ $$ = new_kw_arg(p, assignable(p, $1, $2, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
+ }
+ | f_label
+ {
+ p->ctxt.in_argdef = 1;
+ /*%%%*/
+ $$ = new_kw_arg(p, assignable(p, $1, NODE_SPECIAL_REQUIRED_KEYWORD, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
+ }
+ ;
f_block_kwarg : f_block_kw
- {
- /*%%%*/
- $$ = $1;
- /*% %*/
- /*% ripper: rb_ary_new3(1, get_value($1)) %*/
- }
- | f_block_kwarg ',' f_block_kw
- {
- /*%%%*/
- $$ = kwd_append($1, $3);
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($3)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = $1;
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
+ }
+ | f_block_kwarg ',' f_block_kw
+ {
+ /*%%%*/
+ $$ = kwd_append($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
+ }
+ ;
f_kwarg : f_kw
- {
- /*%%%*/
- $$ = $1;
- /*% %*/
- /*% ripper: rb_ary_new3(1, get_value($1)) %*/
- }
- | f_kwarg ',' f_kw
- {
- /*%%%*/
- $$ = kwd_append($1, $3);
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($3)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = $1;
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
+ }
+ | f_kwarg ',' f_kw
+ {
+ /*%%%*/
+ $$ = kwd_append($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
+ }
+ ;
kwrest_mark : tPOW
- | tDSTAR
- ;
+ | tDSTAR
+ ;
f_no_kwarg : p_kwnorest
- {
- /*%%%*/
- /*% %*/
- /*% ripper: nokw_param!(Qnil) %*/
- }
- ;
+ {
+ /*%%%*/
+ /*% %*/
+ /*% ripper: nokw_param!(Qnil) %*/
+ }
+ ;
f_kwrest : kwrest_mark tIDENTIFIER
- {
- arg_var(p, shadowing_lvar(p, get_id($2)));
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: kwrest_param!($2) %*/
- }
- | kwrest_mark
- {
- arg_var(p, idFWD_KWREST);
- /*%%%*/
- $$ = idFWD_KWREST;
- /*% %*/
- /*% ripper: kwrest_param!(Qnil) %*/
- }
- ;
+ {
+ arg_var(p, shadowing_lvar(p, get_id($2)));
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: kwrest_param!($2) %*/
+ }
+ | kwrest_mark
+ {
+ arg_var(p, idFWD_KWREST);
+ /*%%%*/
+ $$ = idFWD_KWREST;
+ /*% %*/
+ /*% ripper: kwrest_param!(Qnil) %*/
+ }
+ ;
f_opt : f_arg_asgn f_eq arg_value
- {
- p->cur_arg = 0;
- p->ctxt.in_argdef = 1;
- /*%%%*/
- $$ = NEW_OPT_ARG(assignable(p, $1, $3, &@$), &@$);
- /*% %*/
- /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
- }
- ;
+ {
+ p->cur_arg = 0;
+ p->ctxt.in_argdef = 1;
+ /*%%%*/
+ $$ = NEW_OPT_ARG(0, assignable(p, $1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
+ }
+ ;
f_block_opt : f_arg_asgn f_eq primary_value
- {
- p->cur_arg = 0;
- p->ctxt.in_argdef = 1;
- /*%%%*/
- $$ = NEW_OPT_ARG(assignable(p, $1, $3, &@$), &@$);
- /*% %*/
- /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
- }
- ;
+ {
+ p->cur_arg = 0;
+ p->ctxt.in_argdef = 1;
+ /*%%%*/
+ $$ = NEW_OPT_ARG(0, assignable(p, $1, $3, &@$), &@$);
+ /*% %*/
+ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
+ }
+ ;
f_block_optarg : f_block_opt
- {
- /*%%%*/
- $$ = $1;
- /*% %*/
- /*% ripper: rb_ary_new3(1, get_value($1)) %*/
- }
- | f_block_optarg ',' f_block_opt
- {
- /*%%%*/
- $$ = opt_arg_append($1, $3);
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($3)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = $1;
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
+ }
+ | f_block_optarg ',' f_block_opt
+ {
+ /*%%%*/
+ $$ = opt_arg_append($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
+ }
+ ;
f_optarg : f_opt
- {
- /*%%%*/
- $$ = $1;
- /*% %*/
- /*% ripper: rb_ary_new3(1, get_value($1)) %*/
- }
- | f_optarg ',' f_opt
- {
- /*%%%*/
- $$ = opt_arg_append($1, $3);
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($3)) %*/
- }
- ;
+ {
+ /*%%%*/
+ $$ = $1;
+ /*% %*/
+ /*% ripper: rb_ary_new3(1, get_value($1)) %*/
+ }
+ | f_optarg ',' f_opt
+ {
+ /*%%%*/
+ $$ = opt_arg_append($1, $3);
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
+ }
+ ;
restarg_mark : '*'
- | tSTAR
- ;
+ | tSTAR
+ ;
f_rest_arg : restarg_mark tIDENTIFIER
- {
- arg_var(p, shadowing_lvar(p, get_id($2)));
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: rest_param!($2) %*/
- }
- | restarg_mark
- {
- arg_var(p, idFWD_REST);
- /*%%%*/
- $$ = idFWD_REST;
- /*% %*/
- /*% ripper: rest_param!(Qnil) %*/
- }
- ;
+ {
+ arg_var(p, shadowing_lvar(p, get_id($2)));
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: rest_param!($2) %*/
+ }
+ | restarg_mark
+ {
+ arg_var(p, idFWD_REST);
+ /*%%%*/
+ $$ = idFWD_REST;
+ /*% %*/
+ /*% ripper: rest_param!(Qnil) %*/
+ }
+ ;
blkarg_mark : '&'
- | tAMPER
- ;
+ | tAMPER
+ ;
f_block_arg : blkarg_mark tIDENTIFIER
- {
- arg_var(p, shadowing_lvar(p, get_id($2)));
- /*%%%*/
- $$ = $2;
- /*% %*/
- /*% ripper: blockarg!($2) %*/
- }
+ {
+ arg_var(p, shadowing_lvar(p, get_id($2)));
+ /*%%%*/
+ $$ = $2;
+ /*% %*/
+ /*% ripper: blockarg!($2) %*/
+ }
| blkarg_mark
{
- arg_var(p, idFWD_BLOCK);
+ arg_var(p, idFWD_BLOCK);
/*%%%*/
- $$ = idFWD_BLOCK;
+ $$ = idFWD_BLOCK;
/*% %*/
- /*% ripper: blockarg!(Qnil) %*/
+ /*% ripper: blockarg!(Qnil) %*/
}
- ;
+ ;
opt_f_block_arg : ',' f_block_arg
- {
- $$ = $2;
- }
- | none
- {
- $$ = Qnull;
- }
- ;
+ {
+ $$ = $2;
+ }
+ | none
+ {
+ $$ = Qnull;
+ }
+ ;
singleton : var_ref
- {
- value_expr($1);
- $$ = $1;
- }
- | '(' {SET_LEX_STATE(EXPR_BEG);} expr rparen
- {
- /*%%%*/
- NODE *expr = last_expr_node($3);
- switch (nd_type(expr)) {
- case NODE_STR:
- case NODE_DSTR:
- case NODE_XSTR:
- case NODE_DXSTR:
- case NODE_DREGX:
- case NODE_LIT:
- case NODE_DSYM:
- case NODE_LIST:
- case NODE_ZLIST:
- yyerror1(&expr->nd_loc, "can't define singleton method for literals");
- break;
- default:
- value_expr($3);
- break;
- }
- $$ = $3;
- /*% %*/
- /*% ripper: paren!($3) %*/
- }
- ;
+ {
+ value_expr($1);
+ $$ = $1;
+ }
+ | '(' {SET_LEX_STATE(EXPR_BEG);} expr rparen
+ {
+ /*%%%*/
+ switch (nd_type($3)) {
+ case NODE_STR:
+ case NODE_DSTR:
+ case NODE_XSTR:
+ case NODE_DXSTR:
+ case NODE_DREGX:
+ case NODE_LIT:
+ case NODE_LIST:
+ case NODE_ZLIST:
+ yyerror1(&@3, "can't define singleton method for literals");
+ break;
+ default:
+ value_expr($3);
+ break;
+ }
+ $$ = $3;
+ /*% %*/
+ /*% ripper: paren!($3) %*/
+ }
+ ;
assoc_list : none
- | assocs trailer
- {
- /*%%%*/
- $$ = $1;
- /*% %*/
- /*% ripper: assoclist_from_args!($1) %*/
- }
- ;
+ | assocs trailer
+ {
+ /*%%%*/
+ $$ = $1;
+ /*% %*/
+ /*% ripper: assoclist_from_args!($1) %*/
+ }
+ ;
assocs : assoc
- /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
- | assocs ',' assoc
- {
- /*%%%*/
- NODE *assocs = $1;
- NODE *tail = $3;
- if (!assocs) {
- assocs = tail;
- }
- else if (tail) {
- if (RNODE_LIST(assocs)->nd_head &&
- !RNODE_LIST(tail)->nd_head && nd_type_p(RNODE_LIST(tail)->nd_next, NODE_LIST) &&
- nd_type_p(RNODE_LIST(RNODE_LIST(tail)->nd_next)->nd_head, NODE_HASH)) {
+ /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
+ | assocs ',' assoc
+ {
+ /*%%%*/
+ NODE *assocs = $1;
+ NODE *tail = $3;
+ if (!assocs) {
+ assocs = tail;
+ }
+ else if (tail) {
+ if (assocs->nd_head &&
+ !tail->nd_head && nd_type_p(tail->nd_next, NODE_LIST) &&
+ nd_type_p(tail->nd_next->nd_head, NODE_HASH)) {
/* DSTAR */
- tail = RNODE_HASH(RNODE_LIST(RNODE_LIST(tail)->nd_next)->nd_head)->nd_head;
+ tail = tail->nd_next->nd_head->nd_head;
}
- assocs = list_concat(assocs, tail);
- }
- $$ = assocs;
- /*% %*/
- /*% ripper: rb_ary_push($1, get_value($3)) %*/
- }
- ;
+ assocs = list_concat(assocs, tail);
+ }
+ $$ = assocs;
+ /*% %*/
+ /*% ripper: rb_ary_push($1, get_value($3)) %*/
+ }
+ ;
assoc : arg_value tASSOC arg_value
- {
- /*%%%*/
- if (nd_type_p($1, NODE_STR)) {
- nd_set_type($1, NODE_LIT);
- RB_OBJ_WRITE(p->ast, &RNODE_LIT($1)->nd_lit, rb_fstring(RNODE_LIT($1)->nd_lit));
- }
- $$ = list_append(p, NEW_LIST($1, &@$), $3);
- /*% %*/
- /*% ripper: assoc_new!($1, $3) %*/
- }
- | tLABEL arg_value
- {
- /*%%%*/
- $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2);
- /*% %*/
- /*% ripper: assoc_new!($1, $2) %*/
- }
- | tLABEL
- {
- /*%%%*/
- NODE *val = gettable(p, $1, &@$);
- if (!val) val = NEW_ERROR(&@$);
- $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), val);
- /*% %*/
- /*% ripper: assoc_new!($1, Qnil) %*/
- }
- | tSTRING_BEG string_contents tLABEL_END arg_value
- {
- /*%%%*/
- YYLTYPE loc = code_loc_gen(&@1, &@3);
- $$ = list_append(p, NEW_LIST(dsym_node(p, $2, &loc), &loc), $4);
- /*% %*/
- /*% ripper: assoc_new!(dyna_symbol!($2), $4) %*/
- }
- | tDSTAR arg_value
- {
- /*%%%*/
+ {
+ /*%%%*/
+ if (nd_type_p($1, NODE_STR)) {
+ nd_set_type($1, NODE_LIT);
+ RB_OBJ_WRITE(p->ast, &$1->nd_lit, rb_fstring($1->nd_lit));
+ }
+ $$ = list_append(p, NEW_LIST($1, &@$), $3);
+ /*% %*/
+ /*% ripper: assoc_new!($1, $3) %*/
+ }
+ | tLABEL arg_value
+ {
+ /*%%%*/
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2);
+ /*% %*/
+ /*% ripper: assoc_new!($1, $2) %*/
+ }
+ | tLABEL
+ {
+ /*%%%*/
+ NODE *val = gettable(p, $1, &@$);
+ if (!val) val = NEW_BEGIN(0, &@$);
+ $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), val);
+ /*% %*/
+ /*% ripper: assoc_new!($1, Qnil) %*/
+ }
+ | tSTRING_BEG string_contents tLABEL_END arg_value
+ {
+ /*%%%*/
+ YYLTYPE loc = code_loc_gen(&@1, &@3);
+ $$ = list_append(p, NEW_LIST(dsym_node(p, $2, &loc), &loc), $4);
+ /*% %*/
+ /*% ripper: assoc_new!(dyna_symbol!($2), $4) %*/
+ }
+ | tDSTAR arg_value
+ {
+ /*%%%*/
if (nd_type_p($2, NODE_HASH) &&
- !(RNODE_HASH($2)->nd_head && RNODE_LIST(RNODE_HASH($2)->nd_head)->as.nd_alen)) {
+ !($2->nd_head && $2->nd_head->nd_alen)) {
static VALUE empty_hash;
if (!empty_hash) {
empty_hash = rb_obj_freeze(rb_hash_new());
@@ -6679,84 +6060,87 @@ assoc : arg_value tASSOC arg_value
}
else
$$ = list_append(p, NEW_LIST(0, &@$), $2);
- /*% %*/
- /*% ripper: assoc_splat!($2) %*/
- }
- | tDSTAR
- {
- forwarding_arg_check(p, idFWD_KWREST, idFWD_ALL, "keyword rest");
- /*%%%*/
+ /*% %*/
+ /*% ripper: assoc_splat!($2) %*/
+ }
+ | tDSTAR
+ {
+ if (!local_id(p, idFWD_KWREST) ||
+ local_id(p, idFWD_ALL)) {
+ compile_error(p, "no anonymous keyword rest parameter");
+ }
+ /*%%%*/
$$ = list_append(p, NEW_LIST(0, &@$),
NEW_LVAR(idFWD_KWREST, &@$));
- /*% %*/
- /*% ripper: assoc_splat!(Qnil) %*/
- }
- ;
+ /*% %*/
+ /*% ripper: assoc_splat!(Qnil) %*/
+ }
+ ;
operation : tIDENTIFIER
- | tCONSTANT
- | tFID
- ;
+ | tCONSTANT
+ | tFID
+ ;
operation2 : operation
- | op
- ;
+ | op
+ ;
operation3 : tIDENTIFIER
- | tFID
- | op
- ;
+ | tFID
+ | op
+ ;
dot_or_colon : '.'
- | tCOLON2
- ;
+ | tCOLON2
+ ;
call_op : '.'
- | tANDDOT
- ;
+ | tANDDOT
+ ;
call_op2 : call_op
- | tCOLON2
- ;
+ | tCOLON2
+ ;
opt_terms : /* none */
- | terms
- ;
+ | terms
+ ;
opt_nl : /* none */
- | '\n'
- ;
+ | '\n'
+ ;
rparen : opt_nl ')'
- ;
+ ;
rbracket : opt_nl ']'
- ;
+ ;
rbrace : opt_nl '}'
- ;
+ ;
trailer : opt_nl
- | ','
- ;
+ | ','
+ ;
term : ';' {yyerrok;token_flush(p);}
- | '\n'
- {
- @$.end_pos = @$.beg_pos;
- token_flush(p);
- }
- ;
+ | '\n'
+ {
+ @$.end_pos = @$.beg_pos;
+ token_flush(p);
+ }
+ ;
terms : term
- | terms ';' {yyerrok;}
- ;
+ | terms ';' {yyerrok;}
+ ;
none : /* none */
- {
- $$ = Qnull;
- }
- ;
+ {
+ $$ = Qnull;
+ }
+ ;
%%
# undef p
# undef yylex
@@ -6815,21 +6199,16 @@ ripper_yylval_id(struct parser_params *p, ID x)
static bool
parser_has_token(struct parser_params *p)
{
- const char *const pcur = p->lex.pcur;
- const char *const ptok = p->lex.ptok;
- if (p->keep_tokens && (pcur < ptok)) {
- rb_bug("lex.pcur < lex.ptok. (line: %d) %"PRIdPTRDIFF"|%"PRIdPTRDIFF"|%"PRIdPTRDIFF"",
- p->ruby_sourceline, ptok - p->lex.pbeg, pcur - ptok, p->lex.pend - pcur);
- }
- return pcur > ptok;
+ if (p->keep_tokens && (p->lex.pcur < p->lex.ptok)) rb_bug("lex.pcur < lex.ptok. (line: %d) %ld|%ld|%ld", p->ruby_sourceline, p->lex.ptok - p->lex.pbeg, p->lex.pcur - p->lex.ptok, p->lex.pend - p->lex.pcur);
+ return p->lex.pcur > p->lex.ptok;
}
static VALUE
-code_loc_to_ary(struct parser_params *p, const rb_code_location_t *loc)
+code_loc_to_ary(const rb_code_location_t *loc)
{
VALUE ary = rb_ary_new_from_args(4,
- INT2NUM(loc->beg_pos.lineno), INT2NUM(loc->beg_pos.column),
- INT2NUM(loc->end_pos.lineno), INT2NUM(loc->end_pos.column));
+ INT2NUM(loc->beg_pos.lineno), INT2NUM(loc->beg_pos.column),
+ INT2NUM(loc->end_pos.lineno), INT2NUM(loc->end_pos.column));
rb_obj_freeze(ary);
return ary;
@@ -6844,15 +6223,15 @@ parser_append_tokens(struct parser_params *p, VALUE str, enum yytokentype t, int
ary = rb_ary_new2(4);
token_id = p->token_id;
rb_ary_push(ary, INT2FIX(token_id));
- rb_ary_push(ary, ID2SYM(parser_token2id(p, t)));
+ rb_ary_push(ary, ID2SYM(parser_token2id(t)));
rb_ary_push(ary, str);
- rb_ary_push(ary, code_loc_to_ary(p, p->yylloc));
+ rb_ary_push(ary, code_loc_to_ary(p->yylloc));
rb_obj_freeze(ary);
rb_ary_push(p->tokens, ary);
p->token_id++;
if (p->debug) {
- rb_parser_printf(p, "Append tokens (line: %d) %"PRIsVALUE"\n", line, ary);
+ rb_parser_printf(p, "Append tokens (line: %d) %"PRIsVALUE"\n", line, ary);
}
}
@@ -6866,8 +6245,8 @@ parser_dispatch_scan_event(struct parser_params *p, enum yytokentype t, int line
RUBY_SET_YYLLOC(*p->yylloc);
if (p->keep_tokens) {
- VALUE str = STR_NEW(p->lex.ptok, p->lex.pcur - p->lex.ptok);
- parser_append_tokens(p, str, t, line);
+ VALUE str = STR_NEW(p->lex.ptok, p->lex.pcur - p->lex.ptok);
+ parser_append_tokens(p, str, t, line);
}
token_flush(p);
@@ -6877,6 +6256,9 @@ parser_dispatch_scan_event(struct parser_params *p, enum yytokentype t, int line
static void
parser_dispatch_delayed_token(struct parser_params *p, enum yytokentype t, int line)
{
+ int saved_line = p->ruby_sourceline;
+ const char *saved_tokp = p->lex.ptok;
+
debug_token_line(p, "parser_dispatch_delayed_token", line);
if (!has_delayed_token(p)) return;
@@ -6884,7 +6266,11 @@ parser_dispatch_delayed_token(struct parser_params *p, enum yytokentype t, int l
RUBY_SET_YYLLOC_OF_DELAYED_TOKEN(*p->yylloc);
if (p->keep_tokens) {
- parser_append_tokens(p, p->delayed.token, t, line);
+ p->ruby_sourceline = p->delayed.beg_line;
+ p->lex.ptok = p->lex.pbeg + p->delayed.beg_col;
+ parser_append_tokens(p, p->delayed.token, t, line);
+ p->ruby_sourceline = saved_line;
+ p->lex.ptok = saved_tokp;
}
p->delayed.token = Qnil;
@@ -6892,7 +6278,14 @@ parser_dispatch_delayed_token(struct parser_params *p, enum yytokentype t, int l
#else
#define literal_flush(p, ptr) ((void)(ptr))
-#define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &RNODE_RIPPER(yylval.node)->nd_rval : &yylval.val))
+#define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
+
+static inline VALUE
+intern_sym(const char *name)
+{
+ ID id = rb_intern_const(name);
+ return ID2SYM(id);
+}
static int
ripper_has_scan_event(struct parser_params *p)
@@ -6922,7 +6315,6 @@ ripper_dispatch_scan_event(struct parser_params *p, enum yytokentype t)
static void
ripper_dispatch_delayed_token(struct parser_params *p, enum yytokentype t)
{
- /* save and adjust the location to delayed token for callbacks */
int saved_line = p->ruby_sourceline;
const char *saved_tokp = p->lex.ptok;
@@ -6938,7 +6330,7 @@ ripper_dispatch_delayed_token(struct parser_params *p, enum yytokentype t)
#endif /* RIPPER */
static inline int
-is_identchar(struct parser_params *p, const char *ptr, const char *MAYBE_UNUSED(ptr_end), rb_encoding *enc)
+is_identchar(const char *ptr, const char *MAYBE_UNUSED(ptr_end), rb_encoding *enc)
{
return rb_enc_isalnum((unsigned char)*ptr, enc) || *ptr == '_' || !ISASCII(*ptr);
}
@@ -6946,7 +6338,7 @@ is_identchar(struct parser_params *p, const char *ptr, const char *MAYBE_UNUSED(
static inline int
parser_is_identchar(struct parser_params *p)
{
- return !(p)->eofp && is_identchar(p, p->lex.pcur-1, p->lex.pend, p->enc);
+ return !(p)->eofp && is_identchar(p->lex.pcur-1, p->lex.pend, p->enc);
}
static inline int
@@ -6960,13 +6352,13 @@ token_info_setup(token_info *ptinfo, const char *ptr, const rb_code_location_t *
{
int column = 1, nonspc = 0, i;
for (i = 0; i < loc->beg_pos.column; i++, ptr++) {
- if (*ptr == '\t') {
- column = (((column - 1) / TAB_WIDTH) + 1) * TAB_WIDTH;
- }
- column++;
- if (*ptr != ' ' && *ptr != '\t') {
- nonspc = 1;
- }
+ if (*ptr == '\t') {
+ column = (((column - 1) / TAB_WIDTH) + 1) * TAB_WIDTH;
+ }
+ column++;
+ if (*ptr != ' ' && *ptr != '\t') {
+ nonspc = 1;
+ }
}
ptinfo->beg = loc->beg_pos;
@@ -7010,12 +6402,12 @@ token_info_drop(struct parser_params *p, const char *token, rb_code_position_t b
p->token_info = ptinfo_beg->next;
if (ptinfo_beg->beg.lineno != beg_pos.lineno ||
- ptinfo_beg->beg.column != beg_pos.column ||
- strcmp(ptinfo_beg->token, token)) {
- compile_error(p, "token position mismatch: %d:%d:%s expected but %d:%d:%s",
- beg_pos.lineno, beg_pos.column, token,
- ptinfo_beg->beg.lineno, ptinfo_beg->beg.column,
- ptinfo_beg->token);
+ ptinfo_beg->beg.column != beg_pos.column ||
+ strcmp(ptinfo_beg->token, token)) {
+ compile_error(p, "token position mismatch: %d:%d:%s expected but %d:%d:%s",
+ beg_pos.lineno, beg_pos.column, token,
+ ptinfo_beg->beg.lineno, ptinfo_beg->beg.column,
+ ptinfo_beg->token);
}
ruby_sized_xfree(ptinfo_beg, sizeof(*ptinfo_beg));
@@ -7033,8 +6425,8 @@ token_info_warn(struct parser_params *p, const char *token, token_info *ptinfo_b
if (ptinfo_beg->indent == ptinfo_end->indent) return; /* the indents are matched */
if (!same && ptinfo_beg->indent < ptinfo_end->indent) return;
rb_warn3L(ptinfo_end->beg.lineno,
- "mismatched indentations at '%s' with '%s' at %d",
- WARN_S(token), WARN_S(ptinfo_beg->token), WARN_I(ptinfo_beg->beg.lineno));
+ "mismatched indentations at '%s' with '%s' at %d",
+ WARN_S(token), WARN_S(ptinfo_beg->token), WARN_I(ptinfo_beg->beg.lineno));
}
static int
@@ -7042,14 +6434,14 @@ parser_precise_mbclen(struct parser_params *p, const char *ptr)
{
int len = rb_enc_precise_mbclen(ptr, p->lex.pend, p->enc);
if (!MBCLEN_CHARFOUND_P(len)) {
- compile_error(p, "invalid multibyte char (%s)", rb_enc_name(p->enc));
- return -1;
+ compile_error(p, "invalid multibyte char (%s)", rb_enc_name(p->enc));
+ return -1;
}
return len;
}
#ifndef RIPPER
-static void ruby_show_error_line(struct parser_params *p, VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str);
+static void ruby_show_error_line(VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str);
static inline void
parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc)
@@ -7057,32 +6449,32 @@ parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc)
VALUE str;
int lineno = p->ruby_sourceline;
if (!yylloc) {
- return;
+ return;
}
else if (yylloc->beg_pos.lineno == lineno) {
- str = p->lex.lastline;
+ str = p->lex.lastline;
}
else {
- return;
+ return;
}
- ruby_show_error_line(p, p->error_buffer, yylloc, lineno, str);
+ ruby_show_error_line(p->error_buffer, yylloc, lineno, str);
}
static int
-parser_yyerror(struct parser_params *p, const rb_code_location_t *yylloc, const char *msg)
+parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
{
#if 0
YYLTYPE current;
if (!yylloc) {
- yylloc = RUBY_SET_YYLLOC(current);
+ yylloc = RUBY_SET_YYLLOC(current);
}
else if ((p->ruby_sourceline != yylloc->beg_pos.lineno &&
- p->ruby_sourceline != yylloc->end_pos.lineno)) {
- yylloc = 0;
+ p->ruby_sourceline != yylloc->end_pos.lineno)) {
+ yylloc = 0;
}
#endif
- parser_compile_error(p, yylloc, "%s", msg);
+ compile_error(p, "%s", msg);
parser_show_error_line(p, yylloc);
return 0;
}
@@ -7095,7 +6487,7 @@ parser_yyerror0(struct parser_params *p, const char *msg)
}
static void
-ruby_show_error_line(struct parser_params *p, VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str)
+ruby_show_error_line(VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str)
{
VALUE mesg;
const int max_line_margin = 30;
@@ -7111,13 +6503,13 @@ ruby_show_error_line(struct parser_params *p, VALUE errbuf, const YYLTYPE *yyllo
if (!yylloc) return;
pend = RSTRING_END(str);
if (pend > pbeg && pend[-1] == '\n') {
- if (--pend > pbeg && pend[-1] == '\r') --pend;
+ if (--pend > pbeg && pend[-1] == '\r') --pend;
}
pt = pend;
if (lineno == yylloc->end_pos.lineno &&
- (pend - pbeg) > yylloc->end_pos.column) {
- pt = pbeg + yylloc->end_pos.column;
+ (pend - pbeg) > yylloc->end_pos.column) {
+ pt = pbeg + yylloc->end_pos.column;
}
ptr = ptr_end = pt;
@@ -7129,72 +6521,72 @@ ruby_show_error_line(struct parser_params *p, VALUE errbuf, const YYLTYPE *yyllo
len = ptr_end - ptr;
if (len > 4) {
- if (ptr > pbeg) {
- ptr = rb_enc_prev_char(pbeg, ptr, pt, rb_enc_get(str));
- if (ptr > pbeg) pre = "...";
- }
- if (ptr_end < pend) {
- ptr_end = rb_enc_prev_char(pt, ptr_end, pend, rb_enc_get(str));
- if (ptr_end < pend) post = "...";
- }
+ if (ptr > pbeg) {
+ ptr = rb_enc_prev_char(pbeg, ptr, pt, rb_enc_get(str));
+ if (ptr > pbeg) pre = "...";
+ }
+ if (ptr_end < pend) {
+ ptr_end = rb_enc_prev_char(pt, ptr_end, pend, rb_enc_get(str));
+ if (ptr_end < pend) post = "...";
+ }
}
pb = pbeg;
if (lineno == yylloc->beg_pos.lineno) {
- pb += yylloc->beg_pos.column;
- if (pb > pt) pb = pt;
+ pb += yylloc->beg_pos.column;
+ if (pb > pt) pb = pt;
}
if (pb < ptr) pb = ptr;
if (len <= 4 && yylloc->beg_pos.lineno == yylloc->end_pos.lineno) {
- return;
+ return;
}
if (RTEST(errbuf)) {
- mesg = rb_attr_get(errbuf, idMesg);
- if (RSTRING_LEN(mesg) > 0 && *(RSTRING_END(mesg)-1) != '\n')
- rb_str_cat_cstr(mesg, "\n");
+ mesg = rb_attr_get(errbuf, idMesg);
+ if (RSTRING_LEN(mesg) > 0 && *(RSTRING_END(mesg)-1) != '\n')
+ rb_str_cat_cstr(mesg, "\n");
}
else {
- mesg = rb_enc_str_new(0, 0, rb_enc_get(str));
+ mesg = rb_enc_str_new(0, 0, rb_enc_get(str));
}
if (!errbuf && rb_stderr_tty_p()) {
#define CSI_BEGIN "\033["
#define CSI_SGR "m"
- rb_str_catf(mesg,
- CSI_BEGIN""CSI_SGR"%s" /* pre */
- CSI_BEGIN"1"CSI_SGR"%.*s"
- CSI_BEGIN"1;4"CSI_SGR"%.*s"
- CSI_BEGIN";1"CSI_SGR"%.*s"
- CSI_BEGIN""CSI_SGR"%s" /* post */
- "\n",
- pre,
- (int)(pb - ptr), ptr,
- (int)(pt - pb), pb,
- (int)(ptr_end - pt), pt,
- post);
+ rb_str_catf(mesg,
+ CSI_BEGIN""CSI_SGR"%s" /* pre */
+ CSI_BEGIN"1"CSI_SGR"%.*s"
+ CSI_BEGIN"1;4"CSI_SGR"%.*s"
+ CSI_BEGIN";1"CSI_SGR"%.*s"
+ CSI_BEGIN""CSI_SGR"%s" /* post */
+ "\n",
+ pre,
+ (int)(pb - ptr), ptr,
+ (int)(pt - pb), pb,
+ (int)(ptr_end - pt), pt,
+ post);
}
else {
- char *p2;
-
- len = ptr_end - ptr;
- lim = pt < pend ? pt : pend;
- i = (int)(lim - ptr);
- buf = ALLOCA_N(char, i+2);
- code = ptr;
- caret = p2 = buf;
- if (ptr <= pb) {
- while (ptr < pb) {
- *p2++ = *ptr++ == '\t' ? '\t' : ' ';
- }
- *p2++ = '^';
- ptr++;
- }
- if (lim > ptr) {
- memset(p2, '~', (lim - ptr));
- p2 += (lim - ptr);
- }
- *p2 = '\0';
- rb_str_catf(mesg, "%s%.*s%s\n""%s%s\n",
- pre, (int)len, code, post,
- pre, caret);
+ char *p2;
+
+ len = ptr_end - ptr;
+ lim = pt < pend ? pt : pend;
+ i = (int)(lim - ptr);
+ buf = ALLOCA_N(char, i+2);
+ code = ptr;
+ caret = p2 = buf;
+ if (ptr <= pb) {
+ while (ptr < pb) {
+ *p2++ = *ptr++ == '\t' ? '\t' : ' ';
+ }
+ *p2++ = '^';
+ ptr++;
+ }
+ if (lim > ptr) {
+ memset(p2, '~', (lim - ptr));
+ p2 += (lim - ptr);
+ }
+ *p2 = '\0';
+ rb_str_catf(mesg, "%s%.*s%s\n""%s%s\n",
+ pre, (int)len, code, post,
+ pre, caret);
}
if (!errbuf) rb_write_error_str(mesg);
}
@@ -7204,16 +6596,16 @@ parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
{
const char *pcur = 0, *ptok = 0;
if (p->ruby_sourceline == yylloc->beg_pos.lineno &&
- p->ruby_sourceline == yylloc->end_pos.lineno) {
- pcur = p->lex.pcur;
- ptok = p->lex.ptok;
- p->lex.ptok = p->lex.pbeg + yylloc->beg_pos.column;
- p->lex.pcur = p->lex.pbeg + yylloc->end_pos.column;
+ p->ruby_sourceline == yylloc->end_pos.lineno) {
+ pcur = p->lex.pcur;
+ ptok = p->lex.ptok;
+ p->lex.ptok = p->lex.pbeg + yylloc->beg_pos.column;
+ p->lex.pcur = p->lex.pbeg + yylloc->end_pos.column;
}
parser_yyerror0(p, msg);
if (pcur) {
- p->lex.ptok = ptok;
- p->lex.pcur = pcur;
+ p->lex.ptok = ptok;
+ p->lex.pcur = pcur;
}
return 0;
}
@@ -7237,10 +6629,10 @@ static int
vtable_size(const struct vtable *tbl)
{
if (!DVARS_TERMINAL_P(tbl)) {
- return tbl->pos;
+ return tbl->pos;
}
else {
- return 0;
+ return 0;
}
}
#endif
@@ -7255,7 +6647,7 @@ vtable_alloc_gen(struct parser_params *p, int line, struct vtable *prev)
tbl->prev = prev;
#ifndef RIPPER
if (p->debug) {
- rb_parser_printf(p, "vtable_alloc:%d: %p\n", line, (void *)tbl);
+ rb_parser_printf(p, "vtable_alloc:%d: %p\n", line, (void *)tbl);
}
#endif
return tbl;
@@ -7264,39 +6656,39 @@ vtable_alloc_gen(struct parser_params *p, int line, struct vtable *prev)
static void
vtable_free_gen(struct parser_params *p, int line, const char *name,
- struct vtable *tbl)
+ struct vtable *tbl)
{
#ifndef RIPPER
if (p->debug) {
- rb_parser_printf(p, "vtable_free:%d: %s(%p)\n", line, name, (void *)tbl);
+ rb_parser_printf(p, "vtable_free:%d: %s(%p)\n", line, name, (void *)tbl);
}
#endif
if (!DVARS_TERMINAL_P(tbl)) {
- if (tbl->tbl) {
- ruby_sized_xfree(tbl->tbl, tbl->capa * sizeof(ID));
- }
- ruby_sized_xfree(tbl, sizeof(*tbl));
+ if (tbl->tbl) {
+ ruby_sized_xfree(tbl->tbl, tbl->capa * sizeof(ID));
+ }
+ ruby_sized_xfree(tbl, sizeof(*tbl));
}
}
#define vtable_free(tbl) vtable_free_gen(p, __LINE__, #tbl, tbl)
static void
vtable_add_gen(struct parser_params *p, int line, const char *name,
- struct vtable *tbl, ID id)
+ struct vtable *tbl, ID id)
{
#ifndef RIPPER
if (p->debug) {
- rb_parser_printf(p, "vtable_add:%d: %s(%p), %s\n",
- line, name, (void *)tbl, rb_id2name(id));
+ rb_parser_printf(p, "vtable_add:%d: %s(%p), %s\n",
+ line, name, (void *)tbl, rb_id2name(id));
}
#endif
if (DVARS_TERMINAL_P(tbl)) {
- rb_parser_fatal(p, "vtable_add: vtable is not allocated (%p)", (void *)tbl);
- return;
+ rb_parser_fatal(p, "vtable_add: vtable is not allocated (%p)", (void *)tbl);
+ return;
}
if (tbl->pos == tbl->capa) {
- tbl->capa = tbl->capa * 2;
- SIZED_REALLOC_N(tbl->tbl, ID, tbl->capa, tbl->pos);
+ tbl->capa = tbl->capa * 2;
+ SIZED_REALLOC_N(tbl->tbl, ID, tbl->capa, tbl->pos);
}
tbl->tbl[tbl->pos++] = id;
}
@@ -7305,15 +6697,15 @@ vtable_add_gen(struct parser_params *p, int line, const char *name,
#ifndef RIPPER
static void
vtable_pop_gen(struct parser_params *p, int line, const char *name,
- struct vtable *tbl, int n)
+ struct vtable *tbl, int n)
{
if (p->debug) {
- rb_parser_printf(p, "vtable_pop:%d: %s(%p), %d\n",
- line, name, (void *)tbl, n);
+ rb_parser_printf(p, "vtable_pop:%d: %s(%p), %d\n",
+ line, name, (void *)tbl, n);
}
if (tbl->pos < n) {
- rb_parser_fatal(p, "vtable_pop: unreachable (%d < %d)", tbl->pos, n);
- return;
+ rb_parser_fatal(p, "vtable_pop: unreachable (%d < %d)", tbl->pos, n);
+ return;
}
tbl->pos -= n;
}
@@ -7326,11 +6718,11 @@ vtable_included(const struct vtable * tbl, ID id)
int i;
if (!DVARS_TERMINAL_P(tbl)) {
- for (i = 0; i < tbl->pos; i++) {
- if (tbl->tbl[i] == id) {
- return i+1;
- }
- }
+ for (i = 0; i < tbl->pos; i++) {
+ if (tbl->tbl[i] == id) {
+ return i+1;
+ }
+ }
}
return 0;
}
@@ -7340,6 +6732,22 @@ static void parser_prepare(struct parser_params *p);
#ifndef RIPPER
static NODE *parser_append_options(struct parser_params *p, NODE *node);
+static VALUE
+debug_lines(VALUE fname)
+{
+ ID script_lines;
+ CONST_ID(script_lines, "SCRIPT_LINES__");
+ if (rb_const_defined_at(rb_cObject, script_lines)) {
+ VALUE hash = rb_const_get_at(rb_cObject, script_lines);
+ if (RB_TYPE_P(hash, T_HASH)) {
+ VALUE lines = rb_ary_new();
+ rb_hash_aset(hash, fname, lines);
+ return lines;
+ }
+ }
+ return 0;
+}
+
static int
e_option_supplied(struct parser_params *p)
{
@@ -7352,30 +6760,35 @@ yycompile0(VALUE arg)
int n;
NODE *tree;
struct parser_params *p = (struct parser_params *)arg;
- int cov = FALSE;
+ VALUE cov = Qfalse;
if (!compile_for_eval && !NIL_P(p->ruby_sourcefile_string)) {
- if (p->debug_lines && p->ruby_sourceline > 0) {
- VALUE str = rb_default_rs;
- n = p->ruby_sourceline;
- do {
- rb_ary_push(p->debug_lines, str);
- } while (--n);
- }
+ p->debug_lines = debug_lines(p->ruby_sourcefile_string);
+ if (p->debug_lines && p->ruby_sourceline > 0) {
+ VALUE str = rb_default_rs;
+ n = p->ruby_sourceline;
+ do {
+ rb_ary_push(p->debug_lines, str);
+ } while (--n);
+ }
- if (!e_option_supplied(p)) {
- cov = TRUE;
- }
+ if (!e_option_supplied(p)) {
+ cov = Qtrue;
+ }
}
- if (p->debug_lines) {
+ if (p->keep_script_lines || ruby_vm_keep_script_lines) {
+ if (!p->debug_lines) {
+ p->debug_lines = rb_ary_new();
+ }
+
RB_OBJ_WRITE(p->ast, &p->ast->body.script_lines, p->debug_lines);
}
parser_prepare(p);
#define RUBY_DTRACE_PARSE_HOOK(name) \
if (RUBY_DTRACE_PARSE_##name##_ENABLED()) { \
- RUBY_DTRACE_PARSE_##name(p->ruby_sourcefile, p->ruby_sourceline); \
+ RUBY_DTRACE_PARSE_##name(p->ruby_sourcefile, p->ruby_sourceline); \
}
RUBY_DTRACE_PARSE_HOOK(BEGIN);
n = yyparse(p);
@@ -7385,31 +6798,33 @@ yycompile0(VALUE arg)
p->lex.strterm = 0;
p->lex.pcur = p->lex.pbeg = p->lex.pend = 0;
if (n || p->error_p) {
- VALUE mesg = p->error_buffer;
- if (!mesg) {
- mesg = syntax_error_new();
- }
- if (!p->error_tolerant) {
- rb_set_errinfo(mesg);
- return FALSE;
- }
+ VALUE mesg = p->error_buffer;
+ if (!mesg) {
+ mesg = rb_class_new_instance(0, 0, rb_eSyntaxError);
+ }
+ if (!p->error_tolerant) {
+ rb_set_errinfo(mesg);
+ return FALSE;
+ }
}
tree = p->eval_tree;
if (!tree) {
- tree = NEW_NIL(&NULL_LOC);
+ tree = NEW_NIL(&NULL_LOC);
}
else {
- VALUE tokens = p->tokens;
- NODE *prelude;
- NODE *body = parser_append_options(p, RNODE_SCOPE(tree)->nd_body);
- prelude = block_append(p, p->eval_tree_begin, body);
- RNODE_SCOPE(tree)->nd_body = prelude;
- p->ast->body.frozen_string_literal = p->frozen_string_literal;
- p->ast->body.coverage_enabled = cov;
- if (p->keep_tokens) {
- rb_obj_freeze(tokens);
- rb_ast_set_tokens(p->ast, tokens);
- }
+ VALUE opt = p->compile_option;
+ VALUE tokens = p->tokens;
+ NODE *prelude;
+ NODE *body = parser_append_options(p, tree->nd_body);
+ if (!opt) opt = rb_obj_hide(rb_ident_hash_new());
+ rb_hash_aset(opt, rb_sym_intern_ascii_cstr("coverage_enabled"), cov);
+ prelude = block_append(p, p->eval_tree_begin, body);
+ tree->nd_body = prelude;
+ RB_OBJ_WRITE(p->ast, &p->ast->body.compile_option, opt);
+ if (p->keep_tokens) {
+ rb_obj_freeze(tokens);
+ rb_ast_set_tokens(p->ast, tokens);
+ }
}
p->ast->body.root = tree;
if (!p->ast->body.script_lines) p->ast->body.script_lines = INT2FIX(p->line_count);
@@ -7417,24 +6832,25 @@ yycompile0(VALUE arg)
}
static rb_ast_t *
-yycompile(struct parser_params *p, VALUE fname, int line)
+yycompile(VALUE vparser, struct parser_params *p, VALUE fname, int line)
{
rb_ast_t *ast;
if (NIL_P(fname)) {
- p->ruby_sourcefile_string = Qnil;
- p->ruby_sourcefile = "(none)";
+ p->ruby_sourcefile_string = Qnil;
+ p->ruby_sourcefile = "(none)";
}
else {
- p->ruby_sourcefile_string = rb_fstring(fname);
- p->ruby_sourcefile = StringValueCStr(fname);
+ p->ruby_sourcefile_string = rb_fstring(fname);
+ p->ruby_sourcefile = StringValueCStr(fname);
}
p->ruby_sourceline = line - 1;
p->lvtbl = NULL;
p->ast = ast = rb_ast_new();
- compile_callback(yycompile0, (VALUE)p);
+ rb_suppress_tracing(yycompile0, (VALUE)p);
p->ast = 0;
+ RB_GC_GUARD(vparser); /* prohibit tail call optimization */
while (p->lvtbl) {
local_pop(p);
@@ -7445,11 +6861,11 @@ yycompile(struct parser_params *p, VALUE fname, int line)
#endif /* !RIPPER */
static rb_encoding *
-must_be_ascii_compatible(struct parser_params *p, VALUE s)
+must_be_ascii_compatible(VALUE s)
{
rb_encoding *enc = rb_enc_get(s);
if (!rb_enc_asciicompat(enc)) {
- rb_raise(rb_eArgError, "invalid source encoding");
+ rb_raise(rb_eArgError, "invalid source encoding");
}
return enc;
}
@@ -7464,9 +6880,9 @@ lex_get_str(struct parser_params *p, VALUE s)
len = RSTRING_LEN(s);
start = beg;
if (p->lex.gets_.ptr) {
- if (len == p->lex.gets_.ptr) return Qnil;
- beg += p->lex.gets_.ptr;
- len -= p->lex.gets_.ptr;
+ if (len == p->lex.gets_.ptr) return Qnil;
+ beg += p->lex.gets_.ptr;
+ len -= p->lex.gets_.ptr;
}
end = memchr(beg, '\n', len);
if (end) len = ++end - beg;
@@ -7479,37 +6895,45 @@ lex_getline(struct parser_params *p)
{
VALUE line = (*p->lex.gets)(p, p->lex.input);
if (NIL_P(line)) return line;
- must_be_ascii_compatible(p, line);
+ must_be_ascii_compatible(line);
if (RB_OBJ_FROZEN(line)) line = rb_str_dup(line); // needed for RubyVM::AST.of because script_lines in iseq is deep-frozen
p->line_count++;
return line;
}
+static const rb_data_type_t parser_data_type;
+
#ifndef RIPPER
static rb_ast_t*
-parser_compile_string(rb_parser_t *p, VALUE fname, VALUE s, int line)
+parser_compile_string(VALUE vparser, VALUE fname, VALUE s, int line)
{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+
p->lex.gets = lex_get_str;
p->lex.gets_.ptr = 0;
p->lex.input = rb_str_new_frozen(s);
p->lex.pbeg = p->lex.pcur = p->lex.pend = 0;
- return yycompile(p, fname, line);
+ return yycompile(vparser, p, fname, line);
}
rb_ast_t*
-rb_ruby_parser_compile_string_path(rb_parser_t *p, VALUE f, VALUE s, int line)
+rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
{
- must_be_ascii_compatible(p, s);
- return parser_compile_string(p, f, s, line);
+ return rb_parser_compile_string_path(vparser, rb_filesystem_str_new_cstr(f), s, line);
}
rb_ast_t*
-rb_ruby_parser_compile_string(rb_parser_t *p, const char *f, VALUE s, int line)
+rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
{
- return rb_ruby_parser_compile_string_path(p, rb_filesystem_str_new_cstr(f), s, line);
+ must_be_ascii_compatible(s);
+ return parser_compile_string(vparser, f, s, line);
}
+VALUE rb_io_gets_internal(VALUE io);
+
static VALUE
lex_io_gets(struct parser_params *p, VALUE io)
{
@@ -7517,13 +6941,17 @@ lex_io_gets(struct parser_params *p, VALUE io)
}
rb_ast_t*
-rb_ruby_parser_compile_file_path(rb_parser_t *p, VALUE fname, VALUE file, int start)
+rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+
p->lex.gets = lex_io_gets;
p->lex.input = file;
p->lex.pbeg = p->lex.pcur = p->lex.pend = 0;
- return yycompile(p, fname, start);
+ return yycompile(vparser, p, fname, start);
}
static VALUE
@@ -7533,14 +6961,18 @@ lex_generic_gets(struct parser_params *p, VALUE input)
}
rb_ast_t*
-rb_ruby_parser_compile_generic(rb_parser_t *p, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start)
+rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start)
{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
+
p->lex.gets = lex_generic_gets;
p->lex.gets_.call = lex_gets;
p->lex.input = input;
p->lex.pbeg = p->lex.pcur = p->lex.pend = 0;
- return yycompile(p, fname, start);
+ return yycompile(vparser, p, fname, start);
}
#endif /* !RIPPER */
@@ -7567,46 +6999,22 @@ enum string_type {
};
static VALUE
-parser_str_new(struct parser_params *p, const char *ptr, long len, rb_encoding *enc, int func, rb_encoding *enc0)
+parser_str_new(const char *ptr, long len, rb_encoding *enc, int func, rb_encoding *enc0)
{
VALUE str;
str = rb_enc_str_new(ptr, len, enc);
if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
- if (is_ascii_string(str)) {
- }
- else if (rb_is_usascii_enc((void *)enc0) && enc != rb_utf8_encoding()) {
- rb_enc_associate(str, rb_ascii8bit_encoding());
- }
+ if (is_ascii_string(str)) {
+ }
+ else if (rb_is_usascii_enc(enc0) && enc != rb_utf8_encoding()) {
+ rb_enc_associate(str, rb_ascii8bit_encoding());
+ }
}
return str;
}
-static int
-strterm_is_heredoc(rb_strterm_t *strterm)
-{
- return strterm->flags & STRTERM_HEREDOC;
-}
-
-static rb_strterm_t *
-new_strterm(struct parser_params *p, int func, int term, int paren)
-{
- rb_strterm_t *strterm = ZALLOC(rb_strterm_t);
- strterm->u.literal.func = func;
- strterm->u.literal.term = term;
- strterm->u.literal.paren = paren;
- return strterm;
-}
-
-static rb_strterm_t *
-new_heredoc(struct parser_params *p)
-{
- rb_strterm_t *strterm = ZALLOC(rb_strterm_t);
- strterm->flags |= STRTERM_HEREDOC;
- return strterm;
-}
-
#define peek(p,c) peek_n(p, (c), 0)
#define peek_n(p,c,n) (!lex_eol_n_p(p, n) && (c) == (unsigned char)(p)->lex.pcur[n])
#define peekc(p) peekc_n(p, 0)
@@ -7620,74 +7028,60 @@ add_delayed_token(struct parser_params *p, const char *tok, const char *end, int
#endif
if (tok < end) {
- if (has_delayed_token(p)) {
- bool next_line = end_with_newline_p(p, p->delayed.token);
- int end_line = (next_line ? 1 : 0) + p->delayed.end_line;
- int end_col = (next_line ? 0 : p->delayed.end_col);
- if (end_line != p->ruby_sourceline || end_col != tok - p->lex.pbeg) {
- dispatch_delayed_token(p, tSTRING_CONTENT);
- }
- }
- if (!has_delayed_token(p)) {
- p->delayed.token = rb_str_buf_new(end - tok);
- rb_enc_associate(p->delayed.token, p->enc);
- p->delayed.beg_line = p->ruby_sourceline;
- p->delayed.beg_col = rb_long2int(tok - p->lex.pbeg);
- }
- rb_str_buf_cat(p->delayed.token, tok, end - tok);
- p->delayed.end_line = p->ruby_sourceline;
- p->delayed.end_col = rb_long2int(end - p->lex.pbeg);
- p->lex.ptok = end;
+ if (!has_delayed_token(p)) {
+ p->delayed.token = rb_str_buf_new(end - tok);
+ rb_enc_associate(p->delayed.token, p->enc);
+ p->delayed.beg_line = p->ruby_sourceline;
+ p->delayed.beg_col = rb_long2int(tok - p->lex.pbeg);
+ }
+ rb_str_buf_cat(p->delayed.token, tok, end - tok);
+ p->delayed.end_line = p->ruby_sourceline;
+ p->delayed.end_col = rb_long2int(end - p->lex.pbeg);
+ p->lex.ptok = end;
}
}
-static void
-set_lastline(struct parser_params *p, VALUE v)
-{
- p->lex.pbeg = p->lex.pcur = RSTRING_PTR(v);
- p->lex.pend = p->lex.pcur + RSTRING_LEN(v);
- p->lex.lastline = v;
-}
-
static int
nextline(struct parser_params *p, int set_encoding)
{
VALUE v = p->lex.nextline;
p->lex.nextline = 0;
if (!v) {
- if (p->eofp)
- return -1;
-
- if (!lex_eol_ptr_p(p, p->lex.pbeg) && *(p->lex.pend-1) != '\n') {
- goto end_of_input;
- }
-
- if (!p->lex.input || NIL_P(v = lex_getline(p))) {
- end_of_input:
- p->eofp = 1;
- lex_goto_eol(p);
- return -1;
- }
+ if (p->eofp)
+ return -1;
+
+ if (p->lex.pend > p->lex.pbeg && *(p->lex.pend-1) != '\n') {
+ goto end_of_input;
+ }
+
+ if (!p->lex.input || NIL_P(v = lex_getline(p))) {
+ end_of_input:
+ p->eofp = 1;
+ lex_goto_eol(p);
+ return -1;
+ }
#ifndef RIPPER
- if (p->debug_lines) {
- if (set_encoding) rb_enc_associate(v, p->enc);
- rb_ary_push(p->debug_lines, v);
- }
+ if (p->debug_lines) {
+ if (set_encoding) rb_enc_associate(v, p->enc);
+ rb_ary_push(p->debug_lines, v);
+ }
#endif
- p->cr_seen = FALSE;
+ p->cr_seen = FALSE;
}
else if (NIL_P(v)) {
- /* after here-document without terminator */
- goto end_of_input;
+ /* after here-document without terminator */
+ goto end_of_input;
}
add_delayed_token(p, p->lex.ptok, p->lex.pend, __LINE__);
if (p->heredoc_end > 0) {
- p->ruby_sourceline = p->heredoc_end;
- p->heredoc_end = 0;
+ p->ruby_sourceline = p->heredoc_end;
+ p->heredoc_end = 0;
}
p->ruby_sourceline++;
- set_lastline(p, v);
+ p->lex.pbeg = p->lex.pcur = RSTRING_PTR(v);
+ p->lex.pend = p->lex.pcur + RSTRING_LEN(v);
token_flush(p);
+ p->lex.lastline = v;
return 0;
}
@@ -7695,8 +7089,8 @@ static int
parser_cr(struct parser_params *p, int c)
{
if (peek(p, '\n')) {
- p->lex.pcur++;
- c = '\n';
+ p->lex.pcur++;
+ c = '\n';
}
return c;
}
@@ -7706,12 +7100,12 @@ nextc0(struct parser_params *p, int set_encoding)
{
int c;
- if (UNLIKELY(lex_eol_p(p) || p->eofp || RTEST(p->lex.nextline))) {
- if (nextline(p, set_encoding)) return -1;
+ if (UNLIKELY((p->lex.pcur == p->lex.pend) || p->eofp || RTEST(p->lex.nextline))) {
+ if (nextline(p, set_encoding)) return -1;
}
c = (unsigned char)*p->lex.pcur++;
if (UNLIKELY(c == '\r')) {
- c = parser_cr(p, c);
+ c = parser_cr(p, c);
}
return c;
@@ -7722,10 +7116,9 @@ static void
pushback(struct parser_params *p, int c)
{
if (c == -1) return;
- p->eofp = 0;
p->lex.pcur--;
if (p->lex.pcur > p->lex.pbeg && p->lex.pcur[0] == '\n' && p->lex.pcur[-1] == '\r') {
- p->lex.pcur--;
+ p->lex.pcur--;
}
}
@@ -7739,12 +7132,12 @@ static int
looking_at_eol_p(struct parser_params *p)
{
const char *ptr = p->lex.pcur;
- while (!lex_eol_ptr_p(p, ptr)) {
- int c = (unsigned char)*ptr++;
- int eol = (c == '\n' || c == '#');
- if (eol || !ISSPACE(c)) {
- return eol;
- }
+ while (ptr < p->lex.pend) {
+ int c = (unsigned char)*ptr++;
+ int eol = (c == '\n' || c == '#');
+ if (eol || !ISSPACE(c)) {
+ return eol;
+ }
}
return TRUE;
}
@@ -7753,13 +7146,14 @@ static char*
newtok(struct parser_params *p)
{
p->tokidx = 0;
+ p->tokline = p->ruby_sourceline;
if (!p->tokenbuf) {
- p->toksiz = 60;
- p->tokenbuf = ALLOC_N(char, 60);
+ p->toksiz = 60;
+ p->tokenbuf = ALLOC_N(char, 60);
}
if (p->toksiz > 4096) {
- p->toksiz = 60;
- REALLOC_N(p->tokenbuf, char, 60);
+ p->toksiz = 60;
+ REALLOC_N(p->tokenbuf, char, 60);
}
return p->tokenbuf;
}
@@ -7770,8 +7164,8 @@ tokspace(struct parser_params *p, int n)
p->tokidx += n;
if (p->tokidx >= p->toksiz) {
- do {p->toksiz *= 2;} while (p->toksiz < p->tokidx);
- REALLOC_N(p->tokenbuf, char, p->toksiz);
+ do {p->toksiz *= 2;} while (p->toksiz < p->tokidx);
+ REALLOC_N(p->tokenbuf, char, p->toksiz);
}
return &p->tokenbuf[p->tokidx-n];
}
@@ -7781,8 +7175,8 @@ tokadd(struct parser_params *p, int c)
{
p->tokenbuf[p->tokidx++] = (char)c;
if (p->tokidx >= p->toksiz) {
- p->toksiz *= 2;
- REALLOC_N(p->tokenbuf, char, p->toksiz);
+ p->toksiz *= 2;
+ REALLOC_N(p->tokenbuf, char, p->toksiz);
}
}
@@ -7791,11 +7185,11 @@ tok_hex(struct parser_params *p, size_t *numlen)
{
int c;
- c = (int)ruby_scan_hex(p->lex.pcur, 2, numlen);
+ c = scan_hex(p->lex.pcur, 2, numlen);
if (!*numlen) {
- yyerror0("invalid hex escape");
- dispatch_scan_event(p, tSTRING_CONTENT);
- return 0;
+ yyerror0("invalid hex escape");
+ token_flush(p);
+ return 0;
}
p->lex.pcur += *numlen;
return c;
@@ -7809,23 +7203,23 @@ escaped_control_code(int c)
int c2 = 0;
switch (c) {
case ' ':
- c2 = 's';
- break;
+ c2 = 's';
+ break;
case '\n':
- c2 = 'n';
- break;
+ c2 = 'n';
+ break;
case '\t':
- c2 = 't';
- break;
+ c2 = 't';
+ break;
case '\v':
- c2 = 'v';
- break;
+ c2 = 'v';
+ break;
case '\r':
- c2 = 'r';
- break;
+ c2 = 'r';
+ break;
case '\f':
- c2 = 'f';
- break;
+ c2 = 'f';
+ break;
}
return c2;
}
@@ -7835,14 +7229,14 @@ escaped_control_code(int c)
static int
tokadd_codepoint(struct parser_params *p, rb_encoding **encp,
- int regexp_literal, int wide)
+ int regexp_literal, int wide)
{
size_t numlen;
- int codepoint = (int)ruby_scan_hex(p->lex.pcur, wide ? p->lex.pend - p->lex.pcur : 4, &numlen);
+ int codepoint = scan_hex(p->lex.pcur, wide ? p->lex.pend - p->lex.pcur : 4, &numlen);
p->lex.pcur += numlen;
if (p->lex.strterm == NULL ||
- strterm_is_heredoc(p->lex.strterm) ||
- (p->lex.strterm->u.literal.func != str_regexp)) {
+ (p->lex.strterm->flags & STRTERM_HEREDOC) ||
+ (p->lex.strterm->u.literal.u1.func != str_regexp)) {
if (wide ? (numlen == 0 || numlen > 6) : (numlen < 4)) {
literal_flush(p, p->lex.pcur);
yyerror0("invalid Unicode escape");
@@ -7860,21 +7254,21 @@ tokadd_codepoint(struct parser_params *p, rb_encoding **encp,
}
}
if (regexp_literal) {
- tokcopy(p, (int)numlen);
+ tokcopy(p, (int)numlen);
}
else if (codepoint >= 0x80) {
- rb_encoding *utf8 = rb_utf8_encoding();
- if (*encp && utf8 != *encp) {
- YYLTYPE loc = RUBY_INIT_YYLLOC();
- compile_error(p, "UTF-8 mixed within %s source", rb_enc_name(*encp));
- parser_show_error_line(p, &loc);
- return wide;
- }
- *encp = utf8;
- tokaddmbc(p, codepoint, *encp);
+ rb_encoding *utf8 = rb_utf8_encoding();
+ if (*encp && utf8 != *encp) {
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ compile_error(p, "UTF-8 mixed within %s source", rb_enc_name(*encp));
+ parser_show_error_line(p, &loc);
+ return wide;
+ }
+ *encp = utf8;
+ tokaddmbc(p, codepoint, *encp);
}
else {
- tokadd(p, codepoint);
+ tokadd(p, codepoint);
}
return TRUE;
}
@@ -7894,7 +7288,7 @@ tokskip_mbchar(struct parser_params *p)
/* return value is for ?\u3042 */
static void
tokadd_utf8(struct parser_params *p, rb_encoding **encp,
- int term, int symbol_literal, int regexp_literal)
+ int term, int symbol_literal, int regexp_literal)
{
/*
* If `term` is not -1, then we allow multiple codepoints in \u{}
@@ -7908,7 +7302,7 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
if (regexp_literal) { tokadd(p, '\\'); tokadd(p, 'u'); }
if (peek(p, open_brace)) { /* handle \u{...} form */
- if (regexp_literal && p->lex.strterm->u.literal.func == str_regexp) {
+ if (regexp_literal && p->lex.strterm->u.literal.u1.func == str_regexp) {
/*
* Skip parsing validation code and copy bytes as-is until term or
* closing brace, in order to correctly handle extended regexps where
@@ -7916,7 +7310,7 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
* does its own validation and will catch any issues.
*/
tokadd(p, open_brace);
- while (!lex_eol_ptr_p(p, ++p->lex.pcur)) {
+ while (++p->lex.pcur < p->lex.pend) {
int c = peekc(p);
if (c == close_brace) {
tokadd(p, c);
@@ -7926,7 +7320,7 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
else if (c == term) {
break;
}
- if (c == '\\' && !lex_eol_n_p(p, 1)) {
+ if (c == '\\' && p->lex.pcur + 1 < p->lex.pend) {
tokadd(p, c);
c = *++p->lex.pcur;
}
@@ -7936,8 +7330,8 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
else {
const char *second = NULL;
int c, last = nextc(p);
- if (lex_eol_p(p)) goto unterminated;
- while (ISSPACE(c = peekc(p)) && !lex_eol_ptr_p(p, ++p->lex.pcur));
+ if (p->lex.pcur >= p->lex.pend) goto unterminated;
+ while (ISSPACE(c = *p->lex.pcur) && ++p->lex.pcur < p->lex.pend);
while (c != close_brace) {
if (c == term) goto unterminated;
if (second == multiple_codepoints)
@@ -7946,8 +7340,8 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
if (!tokadd_codepoint(p, encp, regexp_literal, TRUE)) {
break;
}
- while (ISSPACE(c = peekc(p))) {
- if (lex_eol_ptr_p(p, ++p->lex.pcur)) goto unterminated;
+ while (ISSPACE(c = *p->lex.pcur)) {
+ if (++p->lex.pcur >= p->lex.pend) goto unterminated;
last = c;
}
if (term == -1 && !second)
@@ -7975,10 +7369,10 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
}
}
else { /* handle \uxxxx form */
- if (!tokadd_codepoint(p, encp, regexp_literal, FALSE)) {
- token_flush(p);
- return;
- }
+ if (!tokadd_codepoint(p, encp, regexp_literal, FALSE)) {
+ token_flush(p);
+ return;
+ }
}
}
@@ -7986,139 +7380,139 @@ tokadd_utf8(struct parser_params *p, rb_encoding **encp,
#define ESCAPE_META 2
static int
-read_escape(struct parser_params *p, int flags)
+read_escape(struct parser_params *p, int flags, rb_encoding **encp)
{
int c;
size_t numlen;
switch (c = nextc(p)) {
case '\\': /* Backslash */
- return c;
+ return c;
case 'n': /* newline */
- return '\n';
+ return '\n';
case 't': /* horizontal tab */
- return '\t';
+ return '\t';
case 'r': /* carriage-return */
- return '\r';
+ return '\r';
case 'f': /* form-feed */
- return '\f';
+ return '\f';
case 'v': /* vertical tab */
- return '\13';
+ return '\13';
case 'a': /* alarm(bell) */
- return '\007';
+ return '\007';
case 'e': /* escape */
- return 033;
+ return 033;
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
- pushback(p, c);
- c = (int)ruby_scan_oct(p->lex.pcur, 3, &numlen);
- p->lex.pcur += numlen;
- return c;
+ pushback(p, c);
+ c = scan_oct(p->lex.pcur, 3, &numlen);
+ p->lex.pcur += numlen;
+ return c;
case 'x': /* hex constant */
- c = tok_hex(p, &numlen);
- if (numlen == 0) return 0;
- return c;
+ c = tok_hex(p, &numlen);
+ if (numlen == 0) return 0;
+ return c;
case 'b': /* backspace */
- return '\010';
+ return '\010';
case 's': /* space */
- return ' ';
+ return ' ';
case 'M':
- if (flags & ESCAPE_META) goto eof;
- if ((c = nextc(p)) != '-') {
- goto eof;
- }
- if ((c = nextc(p)) == '\\') {
- switch (peekc(p)) {
- case 'u': case 'U':
- nextc(p);
- goto eof;
- }
- return read_escape(p, flags|ESCAPE_META) | 0x80;
- }
+ if (flags & ESCAPE_META) goto eof;
+ if ((c = nextc(p)) != '-') {
+ goto eof;
+ }
+ if ((c = nextc(p)) == '\\') {
+ switch (peekc(p)) {
+ case 'u': case 'U':
+ nextc(p);
+ goto eof;
+ }
+ return read_escape(p, flags|ESCAPE_META, encp) | 0x80;
+ }
else if (c == -1) goto eof;
else if (!ISASCII(c)) {
tokskip_mbchar(p);
goto eof;
}
- else {
- int c2 = escaped_control_code(c);
- if (c2) {
- if (ISCNTRL(c) || !(flags & ESCAPE_CONTROL)) {
- WARN_SPACE_CHAR(c2, "\\M-");
- }
- else {
- WARN_SPACE_CHAR(c2, "\\C-\\M-");
- }
- }
- else if (ISCNTRL(c)) goto eof;
- return ((c & 0xff) | 0x80);
- }
+ else {
+ int c2 = escaped_control_code(c);
+ if (c2) {
+ if (ISCNTRL(c) || !(flags & ESCAPE_CONTROL)) {
+ WARN_SPACE_CHAR(c2, "\\M-");
+ }
+ else {
+ WARN_SPACE_CHAR(c2, "\\C-\\M-");
+ }
+ }
+ else if (ISCNTRL(c)) goto eof;
+ return ((c & 0xff) | 0x80);
+ }
case 'C':
- if ((c = nextc(p)) != '-') {
- goto eof;
- }
+ if ((c = nextc(p)) != '-') {
+ goto eof;
+ }
case 'c':
- if (flags & ESCAPE_CONTROL) goto eof;
- if ((c = nextc(p))== '\\') {
- switch (peekc(p)) {
- case 'u': case 'U':
- nextc(p);
- goto eof;
- }
- c = read_escape(p, flags|ESCAPE_CONTROL);
- }
- else if (c == '?')
- return 0177;
+ if (flags & ESCAPE_CONTROL) goto eof;
+ if ((c = nextc(p))== '\\') {
+ switch (peekc(p)) {
+ case 'u': case 'U':
+ nextc(p);
+ goto eof;
+ }
+ c = read_escape(p, flags|ESCAPE_CONTROL, encp);
+ }
+ else if (c == '?')
+ return 0177;
else if (c == -1) goto eof;
else if (!ISASCII(c)) {
tokskip_mbchar(p);
goto eof;
}
- else {
- int c2 = escaped_control_code(c);
- if (c2) {
- if (ISCNTRL(c)) {
- if (flags & ESCAPE_META) {
- WARN_SPACE_CHAR(c2, "\\M-");
- }
- else {
- WARN_SPACE_CHAR(c2, "");
- }
- }
- else {
- if (flags & ESCAPE_META) {
- WARN_SPACE_CHAR(c2, "\\M-\\C-");
- }
- else {
- WARN_SPACE_CHAR(c2, "\\C-");
- }
- }
- }
- else if (ISCNTRL(c)) goto eof;
- }
- return c & 0x9f;
+ else {
+ int c2 = escaped_control_code(c);
+ if (c2) {
+ if (ISCNTRL(c)) {
+ if (flags & ESCAPE_META) {
+ WARN_SPACE_CHAR(c2, "\\M-");
+ }
+ else {
+ WARN_SPACE_CHAR(c2, "");
+ }
+ }
+ else {
+ if (flags & ESCAPE_META) {
+ WARN_SPACE_CHAR(c2, "\\M-\\C-");
+ }
+ else {
+ WARN_SPACE_CHAR(c2, "\\C-");
+ }
+ }
+ }
+ else if (ISCNTRL(c)) goto eof;
+ }
+ return c & 0x9f;
eof:
case -1:
yyerror0("Invalid escape character syntax");
dispatch_scan_event(p, tSTRING_CONTENT);
- return '\0';
+ return '\0';
default:
- return c;
+ return c;
}
}
@@ -8130,42 +7524,42 @@ tokaddmbc(struct parser_params *p, int c, rb_encoding *enc)
}
static int
-tokadd_escape(struct parser_params *p)
+tokadd_escape(struct parser_params *p, rb_encoding **encp)
{
int c;
size_t numlen;
switch (c = nextc(p)) {
case '\n':
- return 0; /* just ignore */
+ return 0; /* just ignore */
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
- {
- ruby_scan_oct(--p->lex.pcur, 3, &numlen);
- if (numlen == 0) goto eof;
- p->lex.pcur += numlen;
- tokcopy(p, (int)numlen + 1);
- }
- return 0;
+ {
+ ruby_scan_oct(--p->lex.pcur, 3, &numlen);
+ if (numlen == 0) goto eof;
+ p->lex.pcur += numlen;
+ tokcopy(p, (int)numlen + 1);
+ }
+ return 0;
case 'x': /* hex constant */
- {
- tok_hex(p, &numlen);
- if (numlen == 0) return -1;
- tokcopy(p, (int)numlen + 2);
- }
- return 0;
+ {
+ tok_hex(p, &numlen);
+ if (numlen == 0) return -1;
+ tokcopy(p, (int)numlen + 2);
+ }
+ return 0;
eof:
case -1:
yyerror0("Invalid escape character syntax");
- token_flush(p);
- return -1;
+ token_flush(p);
+ return -1;
default:
- tokadd(p, '\\');
- tokadd(p, c);
+ tokadd(p, '\\');
+ tokadd(p, c);
}
return 0;
}
@@ -8184,26 +7578,26 @@ regx_options(struct parser_params *p)
options |= RE_OPTION_ONCE;
}
else if (rb_char_to_option_kcode(c, &opt, &kc)) {
- if (kc >= 0) {
- if (kc != rb_ascii8bit_encindex()) kcode = c;
- kopt = opt;
- }
- else {
- options |= opt;
- }
+ if (kc >= 0) {
+ if (kc != rb_ascii8bit_encindex()) kcode = c;
+ kopt = opt;
+ }
+ else {
+ options |= opt;
+ }
}
else {
- tokadd(p, c);
+ tokadd(p, c);
}
}
options |= kopt;
pushback(p, c);
if (toklen(p)) {
- YYLTYPE loc = RUBY_INIT_YYLLOC();
- tokfix(p);
- compile_error(p, "unknown regexp option%s - %*s",
- toklen(p) > 1 ? "s" : "", toklen(p), tok(p));
- parser_show_error_line(p, &loc);
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ tokfix(p);
+ compile_error(p, "unknown regexp option%s - %*s",
+ toklen(p) > 1 ? "s" : "", toklen(p), tok(p));
+ parser_show_error_line(p, &loc);
}
return options | RE_OPTION_ENCODING(kcode);
}
@@ -8226,9 +7620,9 @@ simple_re_meta(int c)
case '$': case '*': case '+': case '.':
case '?': case '^': case '|':
case ')': case ']': case '}': case '>':
- return TRUE;
+ return TRUE;
default:
- return FALSE;
+ return FALSE;
}
}
@@ -8236,24 +7630,24 @@ static int
parser_update_heredoc_indent(struct parser_params *p, int c)
{
if (p->heredoc_line_indent == -1) {
- if (c == '\n') p->heredoc_line_indent = 0;
+ if (c == '\n') p->heredoc_line_indent = 0;
}
else {
- if (c == ' ') {
- p->heredoc_line_indent++;
- return TRUE;
- }
- else if (c == '\t') {
- int w = (p->heredoc_line_indent / TAB_WIDTH) + 1;
- p->heredoc_line_indent = w * TAB_WIDTH;
- return TRUE;
- }
- else if (c != '\n') {
- if (p->heredoc_indent > p->heredoc_line_indent) {
- p->heredoc_indent = p->heredoc_line_indent;
- }
- p->heredoc_line_indent = -1;
- }
+ if (c == ' ') {
+ p->heredoc_line_indent++;
+ return TRUE;
+ }
+ else if (c == '\t') {
+ int w = (p->heredoc_line_indent / TAB_WIDTH) + 1;
+ p->heredoc_line_indent = w * TAB_WIDTH;
+ return TRUE;
+ }
+ else if (c != '\n') {
+ if (p->heredoc_indent > p->heredoc_line_indent) {
+ p->heredoc_indent = p->heredoc_line_indent;
+ }
+ p->heredoc_line_indent = -1;
+ }
}
return FALSE;
}
@@ -8276,17 +7670,10 @@ parser_mixed_escape(struct parser_params *p, const char *beg, rb_encoding *enc1,
p->lex.pcur = pos;
}
-static inline char
-nibble_char_upper(unsigned int c)
-{
- c &= 0xf;
- return c + (c < 10 ? '0' : 'A' - 10);
-}
-
static int
tokadd_string(struct parser_params *p,
- int func, int term, int paren, long *nest,
- rb_encoding **encp, rb_encoding **enc)
+ int func, int term, int paren, long *nest,
+ rb_encoding **encp, rb_encoding **enc)
{
int c;
bool erred = false;
@@ -8301,9 +7688,9 @@ tokadd_string(struct parser_params *p,
(void)(erred || (parser_mixed_escape(p, beg, enc1, enc2), erred = true))
while ((c = nextc(p)) != -1) {
- if (p->heredoc_indent > 0) {
- parser_update_heredoc_indent(p, c);
- }
+ if (p->heredoc_indent > 0) {
+ parser_update_heredoc_indent(p, c);
+ }
#ifdef RIPPER
if (top_of_line && heredoc_end == p->ruby_sourceline) {
pushback(p, c);
@@ -8311,131 +7698,132 @@ tokadd_string(struct parser_params *p,
}
#endif
- if (paren && c == paren) {
- ++*nest;
- }
- else if (c == term) {
- if (!nest || !*nest) {
- pushback(p, c);
- break;
- }
- --*nest;
- }
- else if ((func & STR_FUNC_EXPAND) && c == '#' && !lex_eol_p(p)) {
- unsigned char c2 = *p->lex.pcur;
- if (c2 == '$' || c2 == '@' || c2 == '{') {
- pushback(p, c);
- break;
- }
- }
- else if (c == '\\') {
- c = nextc(p);
- switch (c) {
- case '\n':
- if (func & STR_FUNC_QWORDS) break;
- if (func & STR_FUNC_EXPAND) {
- if (!(func & STR_FUNC_INDENT) || (p->heredoc_indent < 0))
- continue;
- if (c == term) {
- c = '\\';
- goto terminate;
- }
- }
- tokadd(p, '\\');
- break;
-
- case '\\':
- if (func & STR_FUNC_ESCAPE) tokadd(p, c);
- break;
-
- case 'u':
- if ((func & STR_FUNC_EXPAND) == 0) {
- tokadd(p, '\\');
- break;
- }
- tokadd_utf8(p, enc, term,
- func & STR_FUNC_SYMBOL,
- func & STR_FUNC_REGEXP);
- continue;
-
- default:
- if (c == -1) return -1;
- if (!ISASCII(c)) {
- if ((func & STR_FUNC_EXPAND) == 0) tokadd(p, '\\');
- goto non_ascii;
- }
- if (func & STR_FUNC_REGEXP) {
+ if (paren && c == paren) {
+ ++*nest;
+ }
+ else if (c == term) {
+ if (!nest || !*nest) {
+ pushback(p, c);
+ break;
+ }
+ --*nest;
+ }
+ else if ((func & STR_FUNC_EXPAND) && c == '#' && p->lex.pcur < p->lex.pend) {
+ unsigned char c2 = *p->lex.pcur;
+ if (c2 == '$' || c2 == '@' || c2 == '{') {
+ pushback(p, c);
+ break;
+ }
+ }
+ else if (c == '\\') {
+ c = nextc(p);
+ switch (c) {
+ case '\n':
+ if (func & STR_FUNC_QWORDS) break;
+ if (func & STR_FUNC_EXPAND) {
+ if (!(func & STR_FUNC_INDENT) || (p->heredoc_indent < 0))
+ continue;
+ if (c == term) {
+ c = '\\';
+ goto terminate;
+ }
+ }
+ tokadd(p, '\\');
+ break;
+
+ case '\\':
+ if (func & STR_FUNC_ESCAPE) tokadd(p, c);
+ break;
+
+ case 'u':
+ if ((func & STR_FUNC_EXPAND) == 0) {
+ tokadd(p, '\\');
+ break;
+ }
+ tokadd_utf8(p, enc, term,
+ func & STR_FUNC_SYMBOL,
+ func & STR_FUNC_REGEXP);
+ continue;
+
+ default:
+ if (c == -1) return -1;
+ if (!ISASCII(c)) {
+ if ((func & STR_FUNC_EXPAND) == 0) tokadd(p, '\\');
+ goto non_ascii;
+ }
+ if (func & STR_FUNC_REGEXP) {
switch (c) {
case 'c':
case 'C':
case 'M': {
pushback(p, c);
- c = read_escape(p, 0);
+ c = read_escape(p, 0, enc);
- char *t = tokspace(p, rb_strlen_lit("\\x00"));
- *t++ = '\\';
- *t++ = 'x';
- *t++ = nibble_char_upper(c >> 4);
- *t++ = nibble_char_upper(c);
+ int i;
+ char escbuf[5];
+ snprintf(escbuf, sizeof(escbuf), "\\x%02X", c);
+ for (i = 0; i < 4; i++) {
+ tokadd(p, escbuf[i]);
+ }
continue;
}
}
- if (c == term && !simple_re_meta(c)) {
- tokadd(p, c);
- continue;
- }
- pushback(p, c);
- if ((c = tokadd_escape(p)) < 0)
- return -1;
- if (*enc && *enc != *encp) {
- mixed_escape(p->lex.ptok+2, *enc, *encp);
- }
- continue;
- }
- else if (func & STR_FUNC_EXPAND) {
- pushback(p, c);
- if (func & STR_FUNC_ESCAPE) tokadd(p, '\\');
- c = read_escape(p, 0);
- }
- else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
- /* ignore backslashed spaces in %w */
- }
- else if (c != term && !(paren && c == paren)) {
- tokadd(p, '\\');
- pushback(p, c);
- continue;
- }
- }
- }
- else if (!parser_isascii(p)) {
- non_ascii:
- if (!*enc) {
- *enc = *encp;
- }
- else if (*enc != *encp) {
- mixed_error(*enc, *encp);
- continue;
- }
- if (tokadd_mbchar(p, c) == -1) return -1;
- continue;
- }
- else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
- pushback(p, c);
- break;
- }
+ if (c == term && !simple_re_meta(c)) {
+ tokadd(p, c);
+ continue;
+ }
+ pushback(p, c);
+ if ((c = tokadd_escape(p, enc)) < 0)
+ return -1;
+ if (*enc && *enc != *encp) {
+ mixed_escape(p->lex.ptok+2, *enc, *encp);
+ }
+ continue;
+ }
+ else if (func & STR_FUNC_EXPAND) {
+ pushback(p, c);
+ if (func & STR_FUNC_ESCAPE) tokadd(p, '\\');
+ c = read_escape(p, 0, enc);
+ }
+ else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
+ /* ignore backslashed spaces in %w */
+ }
+ else if (c != term && !(paren && c == paren)) {
+ tokadd(p, '\\');
+ pushback(p, c);
+ continue;
+ }
+ }
+ }
+ else if (!parser_isascii(p)) {
+ non_ascii:
+ if (!*enc) {
+ *enc = *encp;
+ }
+ else if (*enc != *encp) {
+ mixed_error(*enc, *encp);
+ continue;
+ }
+ if (tokadd_mbchar(p, c) == -1) return -1;
+ continue;
+ }
+ else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
+ pushback(p, c);
+ break;
+ }
if (c & 0x80) {
- if (!*enc) {
- *enc = *encp;
- }
- else if (*enc != *encp) {
- mixed_error(*enc, *encp);
- continue;
- }
- }
- tokadd(p, c);
+ if (!*enc) {
+ *enc = *encp;
+ }
+ else if (*enc != *encp) {
+ mixed_error(*enc, *encp);
+ continue;
+ }
+ }
+ tokadd(p, c);
#ifdef RIPPER
- top_of_line = (c == '\n');
+ top_of_line = (c == '\n');
#endif
}
terminate:
@@ -8443,27 +7831,35 @@ tokadd_string(struct parser_params *p,
return c;
}
-#define NEW_STRTERM(func, term, paren) new_strterm(p, func, term, paren)
+static inline rb_strterm_t *
+new_strterm(VALUE v1, VALUE v2, VALUE v3, VALUE v0)
+{
+ return (rb_strterm_t*)rb_imemo_new(imemo_parser_strterm, v1, v2, v3, v0);
+}
+
+/* imemo_parser_strterm for literal */
+#define NEW_STRTERM(func, term, paren) \
+ new_strterm((VALUE)(func), (VALUE)(paren), (VALUE)(term), 0)
#ifdef RIPPER
static void
flush_string_content(struct parser_params *p, rb_encoding *enc)
{
VALUE content = yylval.val;
- if (!ripper_is_node_yylval(p, content))
- content = ripper_new_yylval(p, 0, 0, content);
+ if (!ripper_is_node_yylval(content))
+ content = ripper_new_yylval(p, 0, 0, content);
if (has_delayed_token(p)) {
- ptrdiff_t len = p->lex.pcur - p->lex.ptok;
- if (len > 0) {
- rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
- }
- dispatch_delayed_token(p, tSTRING_CONTENT);
- p->lex.ptok = p->lex.pcur;
- RNODE_RIPPER(content)->nd_rval = yylval.val;
+ ptrdiff_t len = p->lex.pcur - p->lex.ptok;
+ if (len > 0) {
+ rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
+ }
+ dispatch_delayed_token(p, tSTRING_CONTENT);
+ p->lex.ptok = p->lex.pcur;
+ RNODE(content)->nd_rval = yylval.val;
}
dispatch_scan_event(p, tSTRING_CONTENT);
if (yylval.val != content)
- RNODE_RIPPER(content)->nd_rval = yylval.val;
+ RNODE(content)->nd_rval = yylval.val;
yylval.val = content;
}
#else
@@ -8471,32 +7867,32 @@ static void
flush_string_content(struct parser_params *p, rb_encoding *enc)
{
if (has_delayed_token(p)) {
- ptrdiff_t len = p->lex.pcur - p->lex.ptok;
- if (len > 0) {
- rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
- p->delayed.end_line = p->ruby_sourceline;
- p->delayed.end_col = rb_long2int(p->lex.pcur - p->lex.pbeg);
- }
- dispatch_delayed_token(p, tSTRING_CONTENT);
- p->lex.ptok = p->lex.pcur;
+ ptrdiff_t len = p->lex.pcur - p->lex.ptok;
+ if (len > 0) {
+ rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
+ p->delayed.end_line = p->ruby_sourceline;
+ p->delayed.end_col = rb_long2int(p->lex.pcur - p->lex.pbeg);
+ }
+ dispatch_delayed_token(p, tSTRING_CONTENT);
+ p->lex.ptok = p->lex.pcur;
}
dispatch_scan_event(p, tSTRING_CONTENT);
}
#endif
-RUBY_FUNC_EXPORTED const uint_least32_t ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
+RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
/* this can be shared with ripper, since it's independent from struct
* parser_params. */
#ifndef RIPPER
#define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
#define SPECIAL_PUNCT(idx) ( \
- BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
- BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
- BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
- BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
- BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
- BIT('0', idx))
-const uint_least32_t ruby_global_name_punct_bits[] = {
+ BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
+ BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
+ BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
+ BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
+ BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
+ BIT('0', idx))
+const unsigned int ruby_global_name_punct_bits[] = {
SPECIAL_PUNCT(0),
SPECIAL_PUNCT(1),
SPECIAL_PUNCT(2),
@@ -8511,33 +7907,33 @@ parser_peek_variable_name(struct parser_params *p)
int c;
const char *ptr = p->lex.pcur;
- if (lex_eol_ptr_n_p(p, ptr, 1)) return 0;
+ if (ptr + 1 >= p->lex.pend) return 0;
c = *ptr++;
switch (c) {
case '$':
- if ((c = *ptr) == '-') {
- if (lex_eol_ptr_p(p, ++ptr)) return 0;
- c = *ptr;
- }
- else if (is_global_name_punct(c) || ISDIGIT(c)) {
- return tSTRING_DVAR;
- }
- break;
+ if ((c = *ptr) == '-') {
+ if (++ptr >= p->lex.pend) return 0;
+ c = *ptr;
+ }
+ else if (is_global_name_punct(c) || ISDIGIT(c)) {
+ return tSTRING_DVAR;
+ }
+ break;
case '@':
- if ((c = *ptr) == '@') {
- if (lex_eol_ptr_p(p, ++ptr)) return 0;
- c = *ptr;
- }
- break;
+ if ((c = *ptr) == '@') {
+ if (++ptr >= p->lex.pend) return 0;
+ c = *ptr;
+ }
+ break;
case '{':
- p->lex.pcur = ptr;
- p->command_start = TRUE;
- return tSTRING_DBEG;
+ p->lex.pcur = ptr;
+ p->command_start = TRUE;
+ return tSTRING_DBEG;
default:
- return 0;
+ return 0;
}
if (!ISASCII(c) || c == '_' || ISALPHA(c))
- return tSTRING_DVAR;
+ return tSTRING_DVAR;
return 0;
}
@@ -8546,26 +7942,25 @@ parser_peek_variable_name(struct parser_params *p)
#define IS_BEG() (IS_lex_state(EXPR_BEG_ANY) || IS_lex_state_all(EXPR_ARG|EXPR_LABELED))
#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
#define IS_LABEL_POSSIBLE() (\
- (IS_lex_state(EXPR_LABEL|EXPR_ENDFN) && !cmd_state) || \
- IS_ARG())
+ (IS_lex_state(EXPR_LABEL|EXPR_ENDFN) && !cmd_state) || \
+ IS_ARG())
#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
#define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
static inline enum yytokentype
parser_string_term(struct parser_params *p, int func)
{
- xfree(p->lex.strterm);
p->lex.strterm = 0;
if (func & STR_FUNC_REGEXP) {
- set_yylval_num(regx_options(p));
- dispatch_scan_event(p, tREGEXP_END);
- SET_LEX_STATE(EXPR_END);
- return tREGEXP_END;
+ set_yylval_num(regx_options(p));
+ dispatch_scan_event(p, tREGEXP_END);
+ SET_LEX_STATE(EXPR_END);
+ return tREGEXP_END;
}
if ((func & STR_FUNC_LABEL) && IS_LABEL_SUFFIX(0)) {
- nextc(p);
- SET_LEX_STATE(EXPR_ARG|EXPR_LABELED);
- return tLABEL_END;
+ nextc(p);
+ SET_LEX_STATE(EXPR_ARG|EXPR_LABELED);
+ return tLABEL_END;
}
SET_LEX_STATE(EXPR_END);
return tSTRING_END;
@@ -8574,76 +7969,74 @@ parser_string_term(struct parser_params *p, int func)
static enum yytokentype
parse_string(struct parser_params *p, rb_strterm_literal_t *quote)
{
- int func = quote->func;
- int term = quote->term;
- int paren = quote->paren;
+ int func = (int)quote->u1.func;
+ int term = (int)quote->u3.term;
+ int paren = (int)quote->u2.paren;
int c, space = 0;
rb_encoding *enc = p->enc;
rb_encoding *base_enc = 0;
VALUE lit;
if (func & STR_FUNC_TERM) {
- if (func & STR_FUNC_QWORDS) nextc(p); /* delayed term */
- SET_LEX_STATE(EXPR_END);
- xfree(p->lex.strterm);
- p->lex.strterm = 0;
- return func & STR_FUNC_REGEXP ? tREGEXP_END : tSTRING_END;
+ if (func & STR_FUNC_QWORDS) nextc(p); /* delayed term */
+ SET_LEX_STATE(EXPR_END);
+ p->lex.strterm = 0;
+ return func & STR_FUNC_REGEXP ? tREGEXP_END : tSTRING_END;
}
c = nextc(p);
if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
- while (c != '\n' && ISSPACE(c = nextc(p)));
- space = 1;
+ do {c = nextc(p);} while (ISSPACE(c));
+ space = 1;
}
if (func & STR_FUNC_LIST) {
- quote->func &= ~STR_FUNC_LIST;
- space = 1;
- }
- if (c == term && !quote->nest) {
- if (func & STR_FUNC_QWORDS) {
- quote->func |= STR_FUNC_TERM;
- pushback(p, c); /* dispatch the term at tSTRING_END */
- add_delayed_token(p, p->lex.ptok, p->lex.pcur, __LINE__);
- return ' ';
- }
- return parser_string_term(p, func);
+ quote->u1.func &= ~STR_FUNC_LIST;
+ space = 1;
+ }
+ if (c == term && !quote->u0.nest) {
+ if (func & STR_FUNC_QWORDS) {
+ quote->u1.func |= STR_FUNC_TERM;
+ pushback(p, c); /* dispatch the term at tSTRING_END */
+ add_delayed_token(p, p->lex.ptok, p->lex.pcur, __LINE__);
+ return ' ';
+ }
+ return parser_string_term(p, func);
}
if (space) {
- if (!ISSPACE(c)) pushback(p, c);
- add_delayed_token(p, p->lex.ptok, p->lex.pcur, __LINE__);
- return ' ';
+ pushback(p, c);
+ add_delayed_token(p, p->lex.ptok, p->lex.pcur, __LINE__);
+ return ' ';
}
newtok(p);
if ((func & STR_FUNC_EXPAND) && c == '#') {
- enum yytokentype t = parser_peek_variable_name(p);
- if (t) return t;
- tokadd(p, '#');
- c = nextc(p);
+ int t = parser_peek_variable_name(p);
+ if (t) return t;
+ tokadd(p, '#');
+ c = nextc(p);
}
pushback(p, c);
- if (tokadd_string(p, func, term, paren, &quote->nest,
- &enc, &base_enc) == -1) {
- if (p->eofp) {
+ if (tokadd_string(p, func, term, paren, &quote->u0.nest,
+ &enc, &base_enc) == -1) {
+ if (p->eofp) {
#ifndef RIPPER
# define unterminated_literal(mesg) yyerror0(mesg)
#else
# define unterminated_literal(mesg) compile_error(p, mesg)
#endif
- literal_flush(p, p->lex.pcur);
- if (func & STR_FUNC_QWORDS) {
- /* no content to add, bailing out here */
- unterminated_literal("unterminated list meets end of file");
- xfree(p->lex.strterm);
- p->lex.strterm = 0;
- return tSTRING_END;
- }
- if (func & STR_FUNC_REGEXP) {
- unterminated_literal("unterminated regexp meets end of file");
- }
- else {
- unterminated_literal("unterminated string meets end of file");
- }
- quote->func |= STR_FUNC_TERM;
- }
+ literal_flush(p, p->lex.pcur);
+ if (func & STR_FUNC_QWORDS) {
+ /* no content to add, bailing out here */
+ unterminated_literal("unterminated list meets end of file");
+ p->lex.strterm = 0;
+ return tSTRING_END;
+ }
+ if (func & STR_FUNC_REGEXP) {
+ unterminated_literal("unterminated regexp meets end of file");
+ }
+ else {
+ unterminated_literal("unterminated string meets end of file");
+ }
+ quote->u1.func |= STR_FUNC_TERM;
+ }
}
tokfix(p);
@@ -8667,71 +8060,70 @@ heredoc_identifier(struct parser_params *p)
int indent = 0;
if (c == '-') {
- c = nextc(p);
- func = STR_FUNC_INDENT;
- offset++;
+ c = nextc(p);
+ func = STR_FUNC_INDENT;
+ offset++;
}
else if (c == '~') {
- c = nextc(p);
- func = STR_FUNC_INDENT;
- offset++;
- indent = INT_MAX;
+ c = nextc(p);
+ func = STR_FUNC_INDENT;
+ offset++;
+ indent = INT_MAX;
}
switch (c) {
case '\'':
- func |= str_squote; goto quoted;
+ func |= str_squote; goto quoted;
case '"':
- func |= str_dquote; goto quoted;
+ func |= str_dquote; goto quoted;
case '`':
- token = tXSTRING_BEG;
- func |= str_xquote; goto quoted;
+ token = tXSTRING_BEG;
+ func |= str_xquote; goto quoted;
quoted:
- quote++;
- offset++;
- term = c;
- len = 0;
- while ((c = nextc(p)) != term) {
- if (c == -1 || c == '\r' || c == '\n') {
- yyerror0("unterminated here document identifier");
- return -1;
- }
- }
- break;
+ quote++;
+ offset++;
+ term = c;
+ len = 0;
+ while ((c = nextc(p)) != term) {
+ if (c == -1 || c == '\r' || c == '\n') {
+ yyerror0("unterminated here document identifier");
+ return -1;
+ }
+ }
+ break;
default:
- if (!parser_is_identchar(p)) {
- pushback(p, c);
- if (func & STR_FUNC_INDENT) {
- pushback(p, indent > 0 ? '~' : '-');
- }
- return 0;
- }
- func |= str_dquote;
- do {
- int n = parser_precise_mbclen(p, p->lex.pcur-1);
- if (n < 0) return 0;
- p->lex.pcur += --n;
- } while ((c = nextc(p)) != -1 && parser_is_identchar(p));
- pushback(p, c);
- break;
+ if (!parser_is_identchar(p)) {
+ pushback(p, c);
+ if (func & STR_FUNC_INDENT) {
+ pushback(p, indent > 0 ? '~' : '-');
+ }
+ return 0;
+ }
+ func |= str_dquote;
+ do {
+ int n = parser_precise_mbclen(p, p->lex.pcur-1);
+ if (n < 0) return 0;
+ p->lex.pcur += --n;
+ } while ((c = nextc(p)) != -1 && parser_is_identchar(p));
+ pushback(p, c);
+ break;
}
len = p->lex.pcur - (p->lex.pbeg + offset) - quote;
if ((unsigned long)len >= HERETERM_LENGTH_MAX)
- yyerror0("too long here document identifier");
+ yyerror0("too long here document identifier");
dispatch_scan_event(p, tHEREDOC_BEG);
lex_goto_eol(p);
- p->lex.strterm = new_heredoc(p);
+ p->lex.strterm = new_strterm(0, 0, 0, p->lex.lastline);
+ p->lex.strterm->flags |= STRTERM_HEREDOC;
rb_strterm_heredoc_t *here = &p->lex.strterm->u.heredoc;
here->offset = offset;
here->sourceline = p->ruby_sourceline;
- here->length = (unsigned)len;
+ here->length = (int)len;
here->quote = quote;
here->func = func;
- here->lastline = p->lex.lastline;
- rb_ast_add_mark_object(p->ast, p->lex.lastline);
token_flush(p);
p->heredoc_indent = indent;
@@ -8743,7 +8135,6 @@ static void
heredoc_restore(struct parser_params *p, rb_strterm_heredoc_t *here)
{
VALUE line;
- rb_strterm_t *term = p->lex.strterm;
p->lex.strterm = 0;
line = here->lastline;
@@ -8756,12 +8147,10 @@ heredoc_restore(struct parser_params *p, rb_strterm_heredoc_t *here)
p->ruby_sourceline = (int)here->sourceline;
if (p->eofp) p->lex.nextline = Qnil;
p->eofp = 0;
- xfree(term);
- rb_ast_delete_mark_object(p->ast, line);
}
static int
-dedent_string(struct parser_params *p, VALUE string, int width)
+dedent_string(VALUE string, int width)
{
char *str;
long len;
@@ -8769,23 +8158,23 @@ dedent_string(struct parser_params *p, VALUE string, int width)
RSTRING_GETMEM(string, str, len);
for (i = 0; i < len && col < width; i++) {
- if (str[i] == ' ') {
- col++;
- }
- else if (str[i] == '\t') {
- int n = TAB_WIDTH * (col / TAB_WIDTH + 1);
- if (n > width) break;
- col = n;
- }
- else {
- break;
- }
+ if (str[i] == ' ') {
+ col++;
+ }
+ else if (str[i] == '\t') {
+ int n = TAB_WIDTH * (col / TAB_WIDTH + 1);
+ if (n > width) break;
+ col = n;
+ }
+ else {
+ break;
+ }
}
if (!i) return 0;
rb_str_modify(string);
str = RSTRING_PTR(string);
if (RSTRING_LEN(string) != len)
- rb_fatal("literal string changed: %+"PRIsVALUE, string);
+ rb_fatal("literal string changed: %+"PRIsVALUE, string);
MEMMOVE(str, str + i, char, len - i);
rb_str_set_len(string, len - i);
return i;
@@ -8804,42 +8193,42 @@ heredoc_dedent(struct parser_params *p, NODE *root)
if (!root) return root;
prev_node = node = str_node = root;
- if (nd_type_p(root, NODE_LIST)) str_node = RNODE_LIST(root)->nd_head;
+ if (nd_type_p(root, NODE_LIST)) str_node = root->nd_head;
while (str_node) {
- VALUE lit = RNODE_LIT(str_node)->nd_lit;
- if (nd_fl_newline(str_node)) {
- dedent_string(p, lit, indent);
- }
- if (!prev_lit) {
- prev_lit = lit;
- }
- else if (!literal_concat0(p, prev_lit, lit)) {
- return 0;
- }
- else {
- NODE *end = RNODE_LIST(node)->as.nd_end;
- node = RNODE_LIST(prev_node)->nd_next = RNODE_LIST(node)->nd_next;
- if (!node) {
- if (nd_type_p(prev_node, NODE_DSTR))
- nd_set_type(prev_node, NODE_STR);
- break;
- }
- RNODE_LIST(node)->as.nd_end = end;
- goto next_str;
- }
-
- str_node = 0;
- while ((nd_type_p(node, NODE_LIST) || nd_type_p(node, NODE_DSTR)) && (node = RNODE_LIST(prev_node = node)->nd_next) != 0) {
- next_str:
- if (!nd_type_p(node, NODE_LIST)) break;
- if ((str_node = RNODE_LIST(node)->nd_head) != 0) {
- enum node_type type = nd_type(str_node);
- if (type == NODE_STR || type == NODE_DSTR) break;
- prev_lit = 0;
- str_node = 0;
- }
- }
+ VALUE lit = str_node->nd_lit;
+ if (str_node->flags & NODE_FL_NEWLINE) {
+ dedent_string(lit, indent);
+ }
+ if (!prev_lit) {
+ prev_lit = lit;
+ }
+ else if (!literal_concat0(p, prev_lit, lit)) {
+ return 0;
+ }
+ else {
+ NODE *end = node->nd_end;
+ node = prev_node->nd_next = node->nd_next;
+ if (!node) {
+ if (nd_type_p(prev_node, NODE_DSTR))
+ nd_set_type(prev_node, NODE_STR);
+ break;
+ }
+ node->nd_end = end;
+ goto next_str;
+ }
+
+ str_node = 0;
+ while ((node = (prev_node = node)->nd_next) != 0) {
+ next_str:
+ if (!nd_type_p(node, NODE_LIST)) break;
+ if ((str_node = node->nd_head) != 0) {
+ enum node_type type = nd_type(str_node);
+ if (type == NODE_STR || type == NODE_DSTR) break;
+ prev_lit = 0;
+ str_node = 0;
+ }
+ }
}
return root;
}
@@ -8854,31 +8243,51 @@ heredoc_dedent(struct parser_params *p, VALUE array)
dispatch2(heredoc_dedent, array, INT2NUM(indent));
return array;
}
+
+/*
+ * call-seq:
+ * Ripper.dedent_string(input, width) -> Integer
+ *
+ * USE OF RIPPER LIBRARY ONLY.
+ *
+ * Strips up to +width+ leading whitespaces from +input+,
+ * and returns the stripped column width.
+ */
+static VALUE
+parser_dedent_string(VALUE self, VALUE input, VALUE width)
+{
+ int wid, col;
+
+ StringValue(input);
+ wid = NUM2UINT(width);
+ col = dedent_string(input, wid);
+ return INT2NUM(col);
+}
#endif
static int
whole_match_p(struct parser_params *p, const char *eos, long len, int indent)
{
- const char *beg = p->lex.pbeg;
- const char *ptr = p->lex.pend;
+ const char *ptr = p->lex.pbeg;
+ long n;
- if (ptr - beg < len) return FALSE;
- if (ptr > beg && ptr[-1] == '\n') {
- if (--ptr > beg && ptr[-1] == '\r') --ptr;
- if (ptr - beg < len) return FALSE;
- }
- if (strncmp(eos, ptr -= len, len)) return FALSE;
if (indent) {
- while (beg < ptr && ISSPACE(*beg)) beg++;
+ while (*ptr && ISSPACE(*ptr)) ptr++;
+ }
+ n = p->lex.pend - (ptr + len);
+ if (n < 0) return FALSE;
+ if (n > 0 && ptr[len] != '\n') {
+ if (ptr[len] != '\r') return FALSE;
+ if (n <= 1 || ptr[len+1] != '\n') return FALSE;
}
- return beg == ptr;
+ return strncmp(eos, ptr, len) == 0;
}
static int
word_match_p(struct parser_params *p, const char *word, long len)
{
if (strncmp(p->lex.pcur, word, len)) return 0;
- if (lex_eol_n_p(p, len)) return 1;
+ if (p->lex.pcur + len == p->lex.pend) return 1;
int c = (unsigned char)p->lex.pcur[len];
if (ISSPACE(c)) return 1;
switch (c) {
@@ -8898,36 +8307,36 @@ number_literal_suffix(struct parser_params *p, int mask)
const char *lastp = p->lex.pcur;
while ((c = nextc(p)) != -1) {
- if ((mask & NUM_SUFFIX_I) && c == 'i') {
- result |= (mask & NUM_SUFFIX_I);
- mask &= ~NUM_SUFFIX_I;
- /* r after i, rational of complex is disallowed */
- mask &= ~NUM_SUFFIX_R;
- continue;
- }
- if ((mask & NUM_SUFFIX_R) && c == 'r') {
- result |= (mask & NUM_SUFFIX_R);
- mask &= ~NUM_SUFFIX_R;
- continue;
- }
- if (!ISASCII(c) || ISALPHA(c) || c == '_') {
- p->lex.pcur = lastp;
- literal_flush(p, p->lex.pcur);
- return 0;
- }
- pushback(p, c);
- break;
+ if ((mask & NUM_SUFFIX_I) && c == 'i') {
+ result |= (mask & NUM_SUFFIX_I);
+ mask &= ~NUM_SUFFIX_I;
+ /* r after i, rational of complex is disallowed */
+ mask &= ~NUM_SUFFIX_R;
+ continue;
+ }
+ if ((mask & NUM_SUFFIX_R) && c == 'r') {
+ result |= (mask & NUM_SUFFIX_R);
+ mask &= ~NUM_SUFFIX_R;
+ continue;
+ }
+ if (!ISASCII(c) || ISALPHA(c) || c == '_') {
+ p->lex.pcur = lastp;
+ literal_flush(p, p->lex.pcur);
+ return 0;
+ }
+ pushback(p, c);
+ break;
}
return result;
}
static enum yytokentype
set_number_literal(struct parser_params *p, VALUE v,
- enum yytokentype type, int suffix)
+ enum yytokentype type, int suffix)
{
if (suffix & NUM_SUFFIX_I) {
- v = rb_complex_raw(INT2FIX(0), v);
- type = tIMAGINARY;
+ v = rb_complex_raw(INT2FIX(0), v);
+ type = tIMAGINARY;
}
set_yylval_literal(v);
SET_LEX_STATE(EXPR_END);
@@ -8939,8 +8348,8 @@ set_integer_literal(struct parser_params *p, VALUE v, int suffix)
{
enum yytokentype type = tINTEGER;
if (suffix & NUM_SUFFIX_R) {
- v = rb_rational_raw1(v);
- type = tRATIONAL;
+ v = rb_rational_raw1(v);
+ type = tRATIONAL;
}
return set_number_literal(p, v, type, suffix);
}
@@ -8951,7 +8360,7 @@ dispatch_heredoc_end(struct parser_params *p)
{
VALUE str;
if (has_delayed_token(p))
- dispatch_delayed_token(p, tSTRING_CONTENT);
+ dispatch_delayed_token(p, tSTRING_CONTENT);
str = STR_NEW(p->lex.ptok, p->lex.pend - p->lex.ptok);
ripper_dispatch1(p, ripper_token2eventid(tHEREDOC_END), str);
RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(*p->yylloc);
@@ -8965,12 +8374,12 @@ static void
parser_dispatch_heredoc_end(struct parser_params *p, int line)
{
if (has_delayed_token(p))
- dispatch_delayed_token(p, tSTRING_CONTENT);
+ dispatch_delayed_token(p, tSTRING_CONTENT);
if (p->keep_tokens) {
- VALUE str = STR_NEW(p->lex.ptok, p->lex.pend - p->lex.ptok);
- RUBY_SET_YYLLOC_OF_HEREDOC_END(*p->yylloc);
- parser_append_tokens(p, str, tHEREDOC_END, line);
+ VALUE str = STR_NEW(p->lex.ptok, p->lex.pend - p->lex.ptok);
+ RUBY_SET_YYLLOC_OF_HEREDOC_END(*p->yylloc);
+ parser_append_tokens(p, str, tHEREDOC_END, line);
}
RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(*p->yylloc);
@@ -8997,148 +8406,150 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
if ((c = nextc(p)) == -1) {
error:
#ifdef RIPPER
- if (!has_delayed_token(p)) {
- dispatch_scan_event(p, tSTRING_CONTENT);
- }
- else {
- if ((len = p->lex.pcur - p->lex.ptok) > 0) {
- if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
- int cr = ENC_CODERANGE_UNKNOWN;
- rb_str_coderange_scan_restartable(p->lex.ptok, p->lex.pcur, enc, &cr);
- if (cr != ENC_CODERANGE_7BIT &&
- rb_is_usascii_enc(p->enc) &&
- enc != rb_utf8_encoding()) {
- enc = rb_ascii8bit_encoding();
- }
- }
- rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
- }
- dispatch_delayed_token(p, tSTRING_CONTENT);
- }
- lex_goto_eol(p);
+ if (!has_delayed_token(p)) {
+ dispatch_scan_event(p, tSTRING_CONTENT);
+ }
+ else {
+ if ((len = p->lex.pcur - p->lex.ptok) > 0) {
+ if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
+ int cr = ENC_CODERANGE_UNKNOWN;
+ rb_str_coderange_scan_restartable(p->lex.ptok, p->lex.pcur, enc, &cr);
+ if (cr != ENC_CODERANGE_7BIT &&
+ rb_is_usascii_enc(p->enc) &&
+ enc != rb_utf8_encoding()) {
+ enc = rb_ascii8bit_encoding();
+ }
+ }
+ rb_enc_str_buf_cat(p->delayed.token, p->lex.ptok, len, enc);
+ }
+ dispatch_delayed_token(p, tSTRING_CONTENT);
+ }
+ lex_goto_eol(p);
#endif
- heredoc_restore(p, &p->lex.strterm->u.heredoc);
- compile_error(p, "can't find string \"%.*s\" anywhere before EOF",
- (int)len, eos);
- token_flush(p);
- SET_LEX_STATE(EXPR_END);
- return tSTRING_END;
+ heredoc_restore(p, &p->lex.strterm->u.heredoc);
+ compile_error(p, "can't find string \"%.*s\" anywhere before EOF",
+ (int)len, eos);
+ token_flush(p);
+ p->lex.strterm = 0;
+ SET_LEX_STATE(EXPR_END);
+ return tSTRING_END;
}
bol = was_bol(p);
if (!bol) {
- /* not beginning of line, cannot be the terminator */
+ /* not beginning of line, cannot be the terminator */
}
else if (p->heredoc_line_indent == -1) {
- /* `heredoc_line_indent == -1` means
- * - "after an interpolation in the same line", or
- * - "in a continuing line"
- */
- p->heredoc_line_indent = 0;
+ /* `heredoc_line_indent == -1` means
+ * - "after an interpolation in the same line", or
+ * - "in a continuing line"
+ */
+ p->heredoc_line_indent = 0;
}
else if (whole_match_p(p, eos, len, indent)) {
- dispatch_heredoc_end(p);
+ dispatch_heredoc_end(p);
restore:
- heredoc_restore(p, &p->lex.strterm->u.heredoc);
- token_flush(p);
- SET_LEX_STATE(EXPR_END);
- return tSTRING_END;
+ heredoc_restore(p, &p->lex.strterm->u.heredoc);
+ token_flush(p);
+ p->lex.strterm = 0;
+ SET_LEX_STATE(EXPR_END);
+ return tSTRING_END;
}
if (!(func & STR_FUNC_EXPAND)) {
- do {
- ptr = RSTRING_PTR(p->lex.lastline);
- ptr_end = p->lex.pend;
- if (ptr_end > ptr) {
- switch (ptr_end[-1]) {
- case '\n':
- if (--ptr_end == ptr || ptr_end[-1] != '\r') {
- ptr_end++;
- break;
- }
- case '\r':
- --ptr_end;
- }
- }
-
- if (p->heredoc_indent > 0) {
- long i = 0;
- while (ptr + i < ptr_end && parser_update_heredoc_indent(p, ptr[i]))
- i++;
- p->heredoc_line_indent = 0;
- }
-
- if (str)
- rb_str_cat(str, ptr, ptr_end - ptr);
- else
- str = STR_NEW(ptr, ptr_end - ptr);
- if (!lex_eol_ptr_p(p, ptr_end)) rb_str_cat(str, "\n", 1);
- lex_goto_eol(p);
- if (p->heredoc_indent > 0) {
- goto flush_str;
- }
- if (nextc(p) == -1) {
- if (str) {
- str = 0;
- }
- goto error;
- }
- } while (!whole_match_p(p, eos, len, indent));
+ do {
+ ptr = RSTRING_PTR(p->lex.lastline);
+ ptr_end = p->lex.pend;
+ if (ptr_end > ptr) {
+ switch (ptr_end[-1]) {
+ case '\n':
+ if (--ptr_end == ptr || ptr_end[-1] != '\r') {
+ ptr_end++;
+ break;
+ }
+ case '\r':
+ --ptr_end;
+ }
+ }
+
+ if (p->heredoc_indent > 0) {
+ long i = 0;
+ while (ptr + i < ptr_end && parser_update_heredoc_indent(p, ptr[i]))
+ i++;
+ p->heredoc_line_indent = 0;
+ }
+
+ if (str)
+ rb_str_cat(str, ptr, ptr_end - ptr);
+ else
+ str = STR_NEW(ptr, ptr_end - ptr);
+ if (ptr_end < p->lex.pend) rb_str_cat(str, "\n", 1);
+ lex_goto_eol(p);
+ if (p->heredoc_indent > 0) {
+ goto flush_str;
+ }
+ if (nextc(p) == -1) {
+ if (str) {
+ str = 0;
+ }
+ goto error;
+ }
+ } while (!whole_match_p(p, eos, len, indent));
}
else {
- /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
- newtok(p);
- if (c == '#') {
- enum yytokentype t = parser_peek_variable_name(p);
- if (p->heredoc_line_indent != -1) {
- if (p->heredoc_indent > p->heredoc_line_indent) {
- p->heredoc_indent = p->heredoc_line_indent;
- }
- p->heredoc_line_indent = -1;
- }
- if (t) return t;
- tokadd(p, '#');
- c = nextc(p);
- }
- do {
- pushback(p, c);
- enc = p->enc;
- if ((c = tokadd_string(p, func, '\n', 0, NULL, &enc, &base_enc)) == -1) {
- if (p->eofp) goto error;
- goto restore;
- }
- if (c != '\n') {
- if (c == '\\') p->heredoc_line_indent = -1;
- flush:
- str = STR_NEW3(tok(p), toklen(p), enc, func);
- flush_str:
- set_yylval_str(str);
+ /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
+ newtok(p);
+ if (c == '#') {
+ int t = parser_peek_variable_name(p);
+ if (p->heredoc_line_indent != -1) {
+ if (p->heredoc_indent > p->heredoc_line_indent) {
+ p->heredoc_indent = p->heredoc_line_indent;
+ }
+ p->heredoc_line_indent = -1;
+ }
+ if (t) return t;
+ tokadd(p, '#');
+ c = nextc(p);
+ }
+ do {
+ pushback(p, c);
+ enc = p->enc;
+ if ((c = tokadd_string(p, func, '\n', 0, NULL, &enc, &base_enc)) == -1) {
+ if (p->eofp) goto error;
+ goto restore;
+ }
+ if (c != '\n') {
+ if (c == '\\') p->heredoc_line_indent = -1;
+ flush:
+ str = STR_NEW3(tok(p), toklen(p), enc, func);
+ flush_str:
+ set_yylval_str(str);
#ifndef RIPPER
- if (bol) nd_set_fl_newline(yylval.node);
+ if (bol) yylval.node->flags |= NODE_FL_NEWLINE;
#endif
- flush_string_content(p, enc);
- return tSTRING_CONTENT;
- }
- tokadd(p, nextc(p));
- if (p->heredoc_indent > 0) {
- lex_goto_eol(p);
- goto flush;
- }
- /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
- if ((c = nextc(p)) == -1) goto error;
- } while (!whole_match_p(p, eos, len, indent));
- str = STR_NEW3(tok(p), toklen(p), enc, func);
+ flush_string_content(p, enc);
+ return tSTRING_CONTENT;
+ }
+ tokadd(p, nextc(p));
+ if (p->heredoc_indent > 0) {
+ lex_goto_eol(p);
+ goto flush;
+ }
+ /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
+ if ((c = nextc(p)) == -1) goto error;
+ } while (!whole_match_p(p, eos, len, indent));
+ str = STR_NEW3(tok(p), toklen(p), enc, func);
}
dispatch_heredoc_end(p);
#ifdef RIPPER
str = ripper_new_yylval(p, ripper_token2eventid(tSTRING_CONTENT),
- yylval.val, str);
+ yylval.val, str);
#endif
heredoc_restore(p, &p->lex.strterm->u.heredoc);
token_flush(p);
p->lex.strterm = NEW_STRTERM(func | STR_FUNC_TERM, 0, 0);
set_yylval_str(str);
#ifndef RIPPER
- if (bol) nd_set_fl_newline(yylval.node);
+ if (bol) yylval.node->flags |= NODE_FL_NEWLINE;
#endif
return tSTRING_CONTENT;
}
@@ -9172,27 +8583,27 @@ formal_argument(struct parser_params *p, VALUE lhs)
switch (id_type(id)) {
case ID_LOCAL:
- break;
+ break;
#ifndef RIPPER
# define ERR(mesg) yyerror0(mesg)
#else
# define ERR(mesg) (dispatch2(param_error, WARN_S(mesg), lhs), ripper_error(p))
#endif
case ID_CONST:
- ERR("formal argument cannot be a constant");
- return 0;
+ ERR("formal argument cannot be a constant");
+ return 0;
case ID_INSTANCE:
- ERR("formal argument cannot be an instance variable");
- return 0;
+ ERR("formal argument cannot be an instance variable");
+ return 0;
case ID_GLOBAL:
- ERR("formal argument cannot be a global variable");
- return 0;
+ ERR("formal argument cannot be a global variable");
+ return 0;
case ID_CLASS:
- ERR("formal argument cannot be a class variable");
- return 0;
+ ERR("formal argument cannot be a class variable");
+ return 0;
default:
- ERR("formal argument must be local variable");
- return 0;
+ ERR("formal argument must be local variable");
+ return 0;
#undef ERR
}
shadowing_lvar(p, id);
@@ -9212,16 +8623,16 @@ parser_encode_length(struct parser_params *p, const char *name, long len)
long nlen;
if (len > 5 && name[nlen = len - 5] == '-') {
- if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
- return nlen;
+ if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
+ return nlen;
}
if (len > 4 && name[nlen = len - 4] == '-') {
- if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
- return nlen;
- if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
- !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
- /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
- return nlen;
+ if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
+ return nlen;
+ if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
+ !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
+ /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
+ return nlen;
}
return len;
}
@@ -9234,26 +8645,26 @@ parser_set_encode(struct parser_params *p, const char *name)
VALUE excargs[3];
if (idx < 0) {
- excargs[1] = rb_sprintf("unknown encoding name: %s", name);
+ excargs[1] = rb_sprintf("unknown encoding name: %s", name);
error:
- excargs[0] = rb_eArgError;
- excargs[2] = rb_make_backtrace();
- rb_ary_unshift(excargs[2], rb_sprintf("%"PRIsVALUE":%d", p->ruby_sourcefile_string, p->ruby_sourceline));
- rb_exc_raise(rb_make_exception(3, excargs));
+ excargs[0] = rb_eArgError;
+ excargs[2] = rb_make_backtrace();
+ rb_ary_unshift(excargs[2], rb_sprintf("%"PRIsVALUE":%d", p->ruby_sourcefile_string, p->ruby_sourceline));
+ rb_exc_raise(rb_make_exception(3, excargs));
}
enc = rb_enc_from_index(idx);
if (!rb_enc_asciicompat(enc)) {
- excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
- goto error;
+ excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
+ goto error;
}
p->enc = enc;
#ifndef RIPPER
if (p->debug_lines) {
- VALUE lines = p->debug_lines;
- long i, n = RARRAY_LEN(lines);
- for (i = 0; i < n; ++i) {
- rb_enc_associate_index(RARRAY_AREF(lines, i), idx);
- }
+ VALUE lines = p->debug_lines;
+ long i, n = RARRAY_LEN(lines);
+ for (i = 0; i < n; ++i) {
+ rb_enc_associate_index(RARRAY_AREF(lines, i), idx);
+ }
}
#endif
}
@@ -9264,8 +8675,8 @@ comment_at_top(struct parser_params *p)
const char *ptr = p->lex.pbeg, *ptr_end = p->lex.pcur - 1;
if (p->line_count != (p->has_shebang ? 2 : 1)) return 0;
while (ptr < ptr_end) {
- if (!ISSPACE(*ptr)) return 0;
- ptr++;
+ if (!ISSPACE(*ptr)) return 0;
+ ptr++;
}
return 1;
}
@@ -9279,7 +8690,7 @@ static void
magic_comment_encoding(struct parser_params *p, const char *name, const char *val)
{
if (!comment_at_top(p)) {
- return;
+ return;
}
parser_set_encode(p, val);
}
@@ -9289,15 +8700,15 @@ parser_get_bool(struct parser_params *p, const char *name, const char *val)
{
switch (*val) {
case 't': case 'T':
- if (STRCASECMP(val, "true") == 0) {
- return TRUE;
- }
- break;
+ if (STRCASECMP(val, "true") == 0) {
+ return TRUE;
+ }
+ break;
case 'f': case 'F':
- if (STRCASECMP(val, "false") == 0) {
- return FALSE;
- }
- break;
+ if (STRCASECMP(val, "false") == 0) {
+ return FALSE;
+ }
+ break;
}
return parser_invalid_pragma_value(p, name, val);
}
@@ -9317,54 +8728,57 @@ parser_set_token_info(struct parser_params *p, const char *name, const char *val
}
static void
-parser_set_frozen_string_literal(struct parser_params *p, const char *name, const char *val)
+parser_set_compile_option_flag(struct parser_params *p, const char *name, const char *val)
{
int b;
if (p->token_seen) {
- rb_warning1("`%s' is ignored after any tokens", WARN_S(name));
- return;
+ rb_warning1("`%s' is ignored after any tokens", WARN_S(name));
+ return;
}
b = parser_get_bool(p, name, val);
if (b < 0) return;
- p->frozen_string_literal = b;
+ if (!p->compile_option)
+ p->compile_option = rb_obj_hide(rb_ident_hash_new());
+ rb_hash_aset(p->compile_option, ID2SYM(rb_intern(name)),
+ RBOOL(b));
}
static void
parser_set_shareable_constant_value(struct parser_params *p, const char *name, const char *val)
{
for (const char *s = p->lex.pbeg, *e = p->lex.pcur; s < e; ++s) {
- if (*s == ' ' || *s == '\t') continue;
- if (*s == '#') break;
- rb_warning1("`%s' is ignored unless in comment-only line", WARN_S(name));
- return;
+ if (*s == ' ' || *s == '\t') continue;
+ if (*s == '#') break;
+ rb_warning1("`%s' is ignored unless in comment-only line", WARN_S(name));
+ return;
}
switch (*val) {
case 'n': case 'N':
- if (STRCASECMP(val, "none") == 0) {
- p->ctxt.shareable_constant_value = shareable_none;
- return;
- }
- break;
+ if (STRCASECMP(val, "none") == 0) {
+ p->ctxt.shareable_constant_value = shareable_none;
+ return;
+ }
+ break;
case 'l': case 'L':
- if (STRCASECMP(val, "literal") == 0) {
- p->ctxt.shareable_constant_value = shareable_literal;
- return;
- }
- break;
+ if (STRCASECMP(val, "literal") == 0) {
+ p->ctxt.shareable_constant_value = shareable_literal;
+ return;
+ }
+ break;
case 'e': case 'E':
- if (STRCASECMP(val, "experimental_copy") == 0) {
- p->ctxt.shareable_constant_value = shareable_copy;
- return;
- }
- if (STRCASECMP(val, "experimental_everything") == 0) {
- p->ctxt.shareable_constant_value = shareable_everything;
- return;
- }
- break;
+ if (STRCASECMP(val, "experimental_copy") == 0) {
+ p->ctxt.shareable_constant_value = shareable_copy;
+ return;
+ }
+ if (STRCASECMP(val, "experimental_everything") == 0) {
+ p->ctxt.shareable_constant_value = shareable_everything;
+ return;
+ }
+ break;
}
parser_invalid_pragma_value(p, name, val);
}
@@ -9387,7 +8801,7 @@ struct magic_comment {
static const struct magic_comment magic_comments[] = {
{"coding", magic_comment_encoding, parser_encode_length},
{"encoding", magic_comment_encoding, parser_encode_length},
- {"frozen_string_literal", parser_set_frozen_string_literal},
+ {"frozen_string_literal", parser_set_compile_option_flag},
{"shareable_constant_value", parser_set_shareable_constant_value},
{"warn_indent", parser_set_token_info},
# if WARN_PAST_SCOPE
@@ -9401,29 +8815,29 @@ magic_comment_marker(const char *str, long len)
long i = 2;
while (i < len) {
- switch (str[i]) {
- case '-':
- if (str[i-1] == '*' && str[i-2] == '-') {
- return str + i + 1;
- }
- i += 2;
- break;
- case '*':
- if (i + 1 >= len) return 0;
- if (str[i+1] != '-') {
- i += 4;
- }
- else if (str[i-1] != '-') {
- i += 2;
- }
- else {
- return str + i + 2;
- }
- break;
- default:
- i += 3;
- break;
- }
+ switch (str[i]) {
+ case '-':
+ if (str[i-1] == '*' && str[i-2] == '-') {
+ return str + i + 1;
+ }
+ i += 2;
+ break;
+ case '*':
+ if (i + 1 >= len) return 0;
+ if (str[i+1] != '-') {
+ i += 4;
+ }
+ else if (str[i-1] != '-') {
+ i += 2;
+ }
+ else {
+ return str + i + 2;
+ }
+ break;
+ default:
+ i += 3;
+ break;
+ }
}
return 0;
}
@@ -9435,97 +8849,97 @@ parser_magic_comment(struct parser_params *p, const char *str, long len)
VALUE name = 0, val = 0;
const char *beg, *end, *vbeg, *vend;
#define str_copy(_s, _p, _n) ((_s) \
- ? (void)(rb_str_resize((_s), (_n)), \
- MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
- : (void)((_s) = STR_NEW((_p), (_n))))
+ ? (void)(rb_str_resize((_s), (_n)), \
+ MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
+ : (void)((_s) = STR_NEW((_p), (_n))))
if (len <= 7) return FALSE;
if (!!(beg = magic_comment_marker(str, len))) {
- if (!(end = magic_comment_marker(beg, str + len - beg)))
- return FALSE;
- indicator = TRUE;
- str = beg;
- len = end - beg - 3;
+ if (!(end = magic_comment_marker(beg, str + len - beg)))
+ return FALSE;
+ indicator = TRUE;
+ str = beg;
+ len = end - beg - 3;
}
/* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
while (len > 0) {
- const struct magic_comment *mc = magic_comments;
- char *s;
- int i;
- long n = 0;
-
- for (; len > 0 && *str; str++, --len) {
- switch (*str) {
- case '\'': case '"': case ':': case ';':
- continue;
- }
- if (!ISSPACE(*str)) break;
- }
- for (beg = str; len > 0; str++, --len) {
- switch (*str) {
- case '\'': case '"': case ':': case ';':
- break;
- default:
- if (ISSPACE(*str)) break;
- continue;
- }
- break;
- }
- for (end = str; len > 0 && ISSPACE(*str); str++, --len);
- if (!len) break;
- if (*str != ':') {
- if (!indicator) return FALSE;
- continue;
- }
-
- do str++; while (--len > 0 && ISSPACE(*str));
- if (!len) break;
- if (*str == '"') {
- for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
- if (*str == '\\') {
- --len;
- ++str;
- }
- }
- vend = str;
- if (len) {
- --len;
- ++str;
- }
- }
- else {
- for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
- vend = str;
- }
- if (indicator) {
- while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
- }
- else {
- while (len > 0 && (ISSPACE(*str))) --len, str++;
- if (len) return FALSE;
- }
-
- n = end - beg;
- str_copy(name, beg, n);
- s = RSTRING_PTR(name);
- for (i = 0; i < n; ++i) {
- if (s[i] == '-') s[i] = '_';
- }
- do {
- if (STRNCASECMP(mc->name, s, n) == 0 && !mc->name[n]) {
- n = vend - vbeg;
- if (mc->length) {
- n = (*mc->length)(p, vbeg, n);
- }
- str_copy(val, vbeg, n);
- (*mc->func)(p, mc->name, RSTRING_PTR(val));
- break;
- }
- } while (++mc < magic_comments + numberof(magic_comments));
+ const struct magic_comment *mc = magic_comments;
+ char *s;
+ int i;
+ long n = 0;
+
+ for (; len > 0 && *str; str++, --len) {
+ switch (*str) {
+ case '\'': case '"': case ':': case ';':
+ continue;
+ }
+ if (!ISSPACE(*str)) break;
+ }
+ for (beg = str; len > 0; str++, --len) {
+ switch (*str) {
+ case '\'': case '"': case ':': case ';':
+ break;
+ default:
+ if (ISSPACE(*str)) break;
+ continue;
+ }
+ break;
+ }
+ for (end = str; len > 0 && ISSPACE(*str); str++, --len);
+ if (!len) break;
+ if (*str != ':') {
+ if (!indicator) return FALSE;
+ continue;
+ }
+
+ do str++; while (--len > 0 && ISSPACE(*str));
+ if (!len) break;
+ if (*str == '"') {
+ for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
+ if (*str == '\\') {
+ --len;
+ ++str;
+ }
+ }
+ vend = str;
+ if (len) {
+ --len;
+ ++str;
+ }
+ }
+ else {
+ for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
+ vend = str;
+ }
+ if (indicator) {
+ while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
+ }
+ else {
+ while (len > 0 && (ISSPACE(*str))) --len, str++;
+ if (len) return FALSE;
+ }
+
+ n = end - beg;
+ str_copy(name, beg, n);
+ s = RSTRING_PTR(name);
+ for (i = 0; i < n; ++i) {
+ if (s[i] == '-') s[i] = '_';
+ }
+ do {
+ if (STRNCASECMP(mc->name, s, n) == 0 && !mc->name[n]) {
+ n = vend - vbeg;
+ if (mc->length) {
+ n = (*mc->length)(p, vbeg, n);
+ }
+ str_copy(val, vbeg, n);
+ (*mc->func)(p, mc->name, RSTRING_PTR(val));
+ break;
+ }
+ } while (++mc < magic_comments + numberof(magic_comments));
#ifdef RIPPER
- str_copy(val, vbeg, vend - vbeg);
- dispatch2(magic_comment, name, val);
+ str_copy(val, vbeg, vend - vbeg);
+ dispatch2(magic_comment, name, val);
#endif
}
@@ -9540,34 +8954,34 @@ set_file_encoding(struct parser_params *p, const char *str, const char *send)
VALUE s;
for (;;) {
- if (send - str <= 6) return;
- switch (str[6]) {
- case 'C': case 'c': str += 6; continue;
- case 'O': case 'o': str += 5; continue;
- case 'D': case 'd': str += 4; continue;
- case 'I': case 'i': str += 3; continue;
- case 'N': case 'n': str += 2; continue;
- case 'G': case 'g': str += 1; continue;
- case '=': case ':':
- sep = 1;
- str += 6;
- break;
- default:
- str += 6;
- if (ISSPACE(*str)) break;
- continue;
- }
- if (STRNCASECMP(str-6, "coding", 6) == 0) break;
- sep = 0;
+ if (send - str <= 6) return;
+ switch (str[6]) {
+ case 'C': case 'c': str += 6; continue;
+ case 'O': case 'o': str += 5; continue;
+ case 'D': case 'd': str += 4; continue;
+ case 'I': case 'i': str += 3; continue;
+ case 'N': case 'n': str += 2; continue;
+ case 'G': case 'g': str += 1; continue;
+ case '=': case ':':
+ sep = 1;
+ str += 6;
+ break;
+ default:
+ str += 6;
+ if (ISSPACE(*str)) break;
+ continue;
+ }
+ if (STRNCASECMP(str-6, "coding", 6) == 0) break;
+ sep = 0;
}
for (;;) {
- do {
- if (++str >= send) return;
- } while (ISSPACE(*str));
- if (sep) break;
- if (*str != '=' && *str != ':') return;
- sep = 1;
- str++;
+ do {
+ if (++str >= send) return;
+ } while (ISSPACE(*str));
+ if (sep) break;
+ if (*str != '=' && *str != ':') return;
+ sep = 1;
+ str++;
}
beg = str;
while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
@@ -9583,26 +8997,25 @@ parser_prepare(struct parser_params *p)
p->token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
switch (c) {
case '#':
- if (peek(p, '!')) p->has_shebang = 1;
- break;
+ if (peek(p, '!')) p->has_shebang = 1;
+ break;
case 0xef: /* UTF-8 BOM marker */
- if (!lex_eol_n_p(p, 2) &&
- (unsigned char)p->lex.pcur[0] == 0xbb &&
- (unsigned char)p->lex.pcur[1] == 0xbf) {
- p->enc = rb_utf8_encoding();
- p->lex.pcur += 2;
+ if (p->lex.pend - p->lex.pcur >= 2 &&
+ (unsigned char)p->lex.pcur[0] == 0xbb &&
+ (unsigned char)p->lex.pcur[1] == 0xbf) {
+ p->enc = rb_utf8_encoding();
+ p->lex.pcur += 2;
#ifndef RIPPER
- if (p->debug_lines) {
- rb_enc_associate(p->lex.lastline, p->enc);
- }
+ if (p->debug_lines) {
+ rb_enc_associate(p->lex.lastline, p->enc);
+ }
#endif
- p->lex.pbeg = p->lex.pcur;
- token_flush(p);
- return;
- }
- break;
+ p->lex.pbeg = p->lex.pcur;
+ return;
+ }
+ break;
case EOF:
- return;
+ return;
}
pushback(p, c);
p->enc = rb_enc_get(p->lex.lastline);
@@ -9652,227 +9065,226 @@ parse_numeric(struct parser_params *p, int c)
SET_LEX_STATE(EXPR_END);
newtok(p);
if (c == '-' || c == '+') {
- tokadd(p, c);
- c = nextc(p);
+ tokadd(p, c);
+ c = nextc(p);
}
if (c == '0') {
- int start = toklen(p);
- c = nextc(p);
- if (c == 'x' || c == 'X') {
- /* hexadecimal */
- c = nextc(p);
- if (c != -1 && ISXDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISXDIGIT(c)) break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- return no_digits(p);
- }
- else if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
- return set_integer_literal(p, rb_cstr_to_inum(tok(p), 16, FALSE), suffix);
- }
- if (c == 'b' || c == 'B') {
- /* binary */
- c = nextc(p);
- if (c == '0' || c == '1') {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (c != '0' && c != '1') break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- return no_digits(p);
- }
- else if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
- return set_integer_literal(p, rb_cstr_to_inum(tok(p), 2, FALSE), suffix);
- }
- if (c == 'd' || c == 'D') {
- /* decimal */
- c = nextc(p);
- if (c != -1 && ISDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISDIGIT(c)) break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- return no_digits(p);
- }
- else if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
- return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
- }
- if (c == '_') {
- /* 0_0 */
- goto octal_number;
- }
- if (c == 'o' || c == 'O') {
- /* prefixed octal */
- c = nextc(p);
- if (c == -1 || c == '_' || !ISDIGIT(c)) {
- return no_digits(p);
- }
- }
- if (c >= '0' && c <= '7') {
- /* octal */
- octal_number:
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (c < '0' || c > '9') break;
- if (c > '7') goto invalid_octal;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- if (toklen(p) > start) {
- pushback(p, c);
- tokfix(p);
- if (nondigit) goto trailing_uc;
- suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
- return set_integer_literal(p, rb_cstr_to_inum(tok(p), 8, FALSE), suffix);
- }
- if (nondigit) {
- pushback(p, c);
- goto trailing_uc;
- }
- }
- if (c > '7' && c <= '9') {
- invalid_octal:
- yyerror0("Invalid octal digit");
- }
- else if (c == '.' || c == 'e' || c == 'E') {
- tokadd(p, '0');
- }
- else {
- pushback(p, c);
- suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
- return set_integer_literal(p, INT2FIX(0), suffix);
- }
+ int start = toklen(p);
+ c = nextc(p);
+ if (c == 'x' || c == 'X') {
+ /* hexadecimal */
+ c = nextc(p);
+ if (c != -1 && ISXDIGIT(c)) {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (!ISXDIGIT(c)) break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ return no_digits(p);
+ }
+ else if (nondigit) goto trailing_uc;
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 16, FALSE), suffix);
+ }
+ if (c == 'b' || c == 'B') {
+ /* binary */
+ c = nextc(p);
+ if (c == '0' || c == '1') {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (c != '0' && c != '1') break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ return no_digits(p);
+ }
+ else if (nondigit) goto trailing_uc;
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 2, FALSE), suffix);
+ }
+ if (c == 'd' || c == 'D') {
+ /* decimal */
+ c = nextc(p);
+ if (c != -1 && ISDIGIT(c)) {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (!ISDIGIT(c)) break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ return no_digits(p);
+ }
+ else if (nondigit) goto trailing_uc;
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
+ }
+ if (c == '_') {
+ /* 0_0 */
+ goto octal_number;
+ }
+ if (c == 'o' || c == 'O') {
+ /* prefixed octal */
+ c = nextc(p);
+ if (c == -1 || c == '_' || !ISDIGIT(c)) {
+ return no_digits(p);
+ }
+ }
+ if (c >= '0' && c <= '7') {
+ /* octal */
+ octal_number:
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (c < '0' || c > '9') break;
+ if (c > '7') goto invalid_octal;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ if (toklen(p) > start) {
+ pushback(p, c);
+ tokfix(p);
+ if (nondigit) goto trailing_uc;
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, rb_cstr_to_inum(tok(p), 8, FALSE), suffix);
+ }
+ if (nondigit) {
+ pushback(p, c);
+ goto trailing_uc;
+ }
+ }
+ if (c > '7' && c <= '9') {
+ invalid_octal:
+ yyerror0("Invalid octal digit");
+ }
+ else if (c == '.' || c == 'e' || c == 'E') {
+ tokadd(p, '0');
+ }
+ else {
+ pushback(p, c);
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ return set_integer_literal(p, INT2FIX(0), suffix);
+ }
}
for (;;) {
- switch (c) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- nondigit = 0;
- tokadd(p, c);
- break;
-
- case '.':
- if (nondigit) goto trailing_uc;
- if (seen_point || seen_e) {
- goto decode_num;
- }
- else {
- int c0 = nextc(p);
- if (c0 == -1 || !ISDIGIT(c0)) {
- pushback(p, c0);
- goto decode_num;
- }
- c = c0;
- }
- seen_point = toklen(p);
- tokadd(p, '.');
- tokadd(p, c);
- is_float++;
- nondigit = 0;
- break;
-
- case 'e':
- case 'E':
- if (nondigit) {
- pushback(p, c);
- c = nondigit;
- goto decode_num;
- }
- if (seen_e) {
- goto decode_num;
- }
- nondigit = c;
- c = nextc(p);
- if (c != '-' && c != '+' && !ISDIGIT(c)) {
- pushback(p, c);
- c = nondigit;
- nondigit = 0;
- goto decode_num;
- }
- tokadd(p, nondigit);
- seen_e++;
- is_float++;
- tokadd(p, c);
- nondigit = (c == '-' || c == '+') ? c : 0;
- break;
-
- case '_': /* `_' in number just ignored */
- if (nondigit) goto decode_num;
- nondigit = c;
- break;
-
- default:
- goto decode_num;
- }
- c = nextc(p);
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ nondigit = 0;
+ tokadd(p, c);
+ break;
+
+ case '.':
+ if (nondigit) goto trailing_uc;
+ if (seen_point || seen_e) {
+ goto decode_num;
+ }
+ else {
+ int c0 = nextc(p);
+ if (c0 == -1 || !ISDIGIT(c0)) {
+ pushback(p, c0);
+ goto decode_num;
+ }
+ c = c0;
+ }
+ seen_point = toklen(p);
+ tokadd(p, '.');
+ tokadd(p, c);
+ is_float++;
+ nondigit = 0;
+ break;
+
+ case 'e':
+ case 'E':
+ if (nondigit) {
+ pushback(p, c);
+ c = nondigit;
+ goto decode_num;
+ }
+ if (seen_e) {
+ goto decode_num;
+ }
+ nondigit = c;
+ c = nextc(p);
+ if (c != '-' && c != '+' && !ISDIGIT(c)) {
+ pushback(p, c);
+ nondigit = 0;
+ goto decode_num;
+ }
+ tokadd(p, nondigit);
+ seen_e++;
+ is_float++;
+ tokadd(p, c);
+ nondigit = (c == '-' || c == '+') ? c : 0;
+ break;
+
+ case '_': /* `_' in number just ignored */
+ if (nondigit) goto decode_num;
+ nondigit = c;
+ break;
+
+ default:
+ goto decode_num;
+ }
+ c = nextc(p);
}
decode_num:
pushback(p, c);
if (nondigit) {
trailing_uc:
- literal_flush(p, p->lex.pcur - 1);
- YYLTYPE loc = RUBY_INIT_YYLLOC();
- compile_error(p, "trailing `%c' in number", nondigit);
- parser_show_error_line(p, &loc);
+ literal_flush(p, p->lex.pcur - 1);
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ compile_error(p, "trailing `%c' in number", nondigit);
+ parser_show_error_line(p, &loc);
}
tokfix(p);
if (is_float) {
- enum yytokentype type = tFLOAT;
- VALUE v;
-
- suffix = number_literal_suffix(p, seen_e ? NUM_SUFFIX_I : NUM_SUFFIX_ALL);
- if (suffix & NUM_SUFFIX_R) {
- type = tRATIONAL;
- v = parse_rational(p, tok(p), toklen(p), seen_point);
- }
- else {
- double d = strtod(tok(p), 0);
- if (errno == ERANGE) {
- rb_warning1("Float %s out of range", WARN_S(tok(p)));
- errno = 0;
- }
- v = DBL2NUM(d);
- }
- return set_number_literal(p, v, type, suffix);
+ enum yytokentype type = tFLOAT;
+ VALUE v;
+
+ suffix = number_literal_suffix(p, seen_e ? NUM_SUFFIX_I : NUM_SUFFIX_ALL);
+ if (suffix & NUM_SUFFIX_R) {
+ type = tRATIONAL;
+ v = parse_rational(p, tok(p), toklen(p), seen_point);
+ }
+ else {
+ double d = strtod(tok(p), 0);
+ if (errno == ERANGE) {
+ rb_warning1("Float %s out of range", WARN_S(tok(p)));
+ errno = 0;
+ }
+ v = DBL2NUM(d);
+ }
+ return set_number_literal(p, v, type, suffix);
}
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
@@ -9886,63 +9298,63 @@ parse_qmark(struct parser_params *p, int space_seen)
VALUE lit;
if (IS_END()) {
- SET_LEX_STATE(EXPR_VALUE);
- return '?';
+ SET_LEX_STATE(EXPR_VALUE);
+ return '?';
}
c = nextc(p);
if (c == -1) {
- compile_error(p, "incomplete character syntax");
- return 0;
+ compile_error(p, "incomplete character syntax");
+ return 0;
}
if (rb_enc_isspace(c, p->enc)) {
- if (!IS_ARG()) {
- int c2 = escaped_control_code(c);
- if (c2) {
- WARN_SPACE_CHAR(c2, "?");
- }
- }
+ if (!IS_ARG()) {
+ int c2 = escaped_control_code(c);
+ if (c2) {
+ WARN_SPACE_CHAR(c2, "?");
+ }
+ }
ternary:
- pushback(p, c);
- SET_LEX_STATE(EXPR_VALUE);
- return '?';
+ pushback(p, c);
+ SET_LEX_STATE(EXPR_VALUE);
+ return '?';
}
newtok(p);
enc = p->enc;
if (!parser_isascii(p)) {
- if (tokadd_mbchar(p, c) == -1) return 0;
+ if (tokadd_mbchar(p, c) == -1) return 0;
}
else if ((rb_enc_isalnum(c, p->enc) || c == '_') &&
- !lex_eol_p(p) && is_identchar(p, p->lex.pcur, p->lex.pend, p->enc)) {
- if (space_seen) {
- const char *start = p->lex.pcur - 1, *ptr = start;
- do {
- int n = parser_precise_mbclen(p, ptr);
- if (n < 0) return -1;
- ptr += n;
- } while (!lex_eol_ptr_p(p, ptr) && is_identchar(p, ptr, p->lex.pend, p->enc));
- rb_warn2("`?' just followed by `%.*s' is interpreted as" \
- " a conditional operator, put a space after `?'",
- WARN_I((int)(ptr - start)), WARN_S_L(start, (ptr - start)));
- }
- goto ternary;
+ p->lex.pcur < p->lex.pend && is_identchar(p->lex.pcur, p->lex.pend, p->enc)) {
+ if (space_seen) {
+ const char *start = p->lex.pcur - 1, *ptr = start;
+ do {
+ int n = parser_precise_mbclen(p, ptr);
+ if (n < 0) return -1;
+ ptr += n;
+ } while (ptr < p->lex.pend && is_identchar(ptr, p->lex.pend, p->enc));
+ rb_warn2("`?' just followed by `%.*s' is interpreted as" \
+ " a conditional operator, put a space after `?'",
+ WARN_I((int)(ptr - start)), WARN_S_L(start, (ptr - start)));
+ }
+ goto ternary;
}
else if (c == '\\') {
- if (peek(p, 'u')) {
- nextc(p);
- enc = rb_utf8_encoding();
- tokadd_utf8(p, &enc, -1, 0, 0);
- }
+ if (peek(p, 'u')) {
+ nextc(p);
+ enc = rb_utf8_encoding();
+ tokadd_utf8(p, &enc, -1, 0, 0);
+ }
else if (!ISASCII(c = peekc(p))) {
- nextc(p);
- if (tokadd_mbchar(p, c) == -1) return 0;
- }
- else {
- c = read_escape(p, 0);
- tokadd(p, c);
- }
+ nextc(p);
+ if (tokadd_mbchar(p, c) == -1) return 0;
+ }
+ else {
+ c = read_escape(p, 0, &enc);
+ tokadd(p, c);
+ }
}
else {
- tokadd(p, c);
+ tokadd(p, c);
}
tokfix(p);
lit = STR_NEW3(tok(p), toklen(p), enc, 0);
@@ -9958,92 +9370,92 @@ parse_percent(struct parser_params *p, const int space_seen, const enum lex_stat
const char *ptok = p->lex.pcur;
if (IS_BEG()) {
- int term;
- int paren;
+ int term;
+ int paren;
- c = nextc(p);
+ c = nextc(p);
quotation:
- if (c == -1) goto unterminated;
- if (!ISALNUM(c)) {
- term = c;
- if (!ISASCII(c)) goto unknown;
- c = 'Q';
- }
- else {
- term = nextc(p);
- if (rb_enc_isalnum(term, p->enc) || !parser_isascii(p)) {
- unknown:
- pushback(p, term);
- c = parser_precise_mbclen(p, p->lex.pcur);
- if (c < 0) return 0;
- p->lex.pcur += c;
- yyerror0("unknown type of %string");
- return 0;
- }
- }
- if (term == -1) {
- unterminated:
- compile_error(p, "unterminated quoted string meets end of file");
- return 0;
- }
- paren = term;
- if (term == '(') term = ')';
- else if (term == '[') term = ']';
- else if (term == '{') term = '}';
- else if (term == '<') term = '>';
- else paren = 0;
-
- p->lex.ptok = ptok-1;
- switch (c) {
- case 'Q':
- p->lex.strterm = NEW_STRTERM(str_dquote, term, paren);
- return tSTRING_BEG;
-
- case 'q':
- p->lex.strterm = NEW_STRTERM(str_squote, term, paren);
- return tSTRING_BEG;
-
- case 'W':
- p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
- return tWORDS_BEG;
-
- case 'w':
- p->lex.strterm = NEW_STRTERM(str_sword, term, paren);
- return tQWORDS_BEG;
-
- case 'I':
- p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
- return tSYMBOLS_BEG;
-
- case 'i':
- p->lex.strterm = NEW_STRTERM(str_sword, term, paren);
- return tQSYMBOLS_BEG;
-
- case 'x':
- p->lex.strterm = NEW_STRTERM(str_xquote, term, paren);
- return tXSTRING_BEG;
-
- case 'r':
- p->lex.strterm = NEW_STRTERM(str_regexp, term, paren);
- return tREGEXP_BEG;
-
- case 's':
- p->lex.strterm = NEW_STRTERM(str_ssym, term, paren);
- SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);
- return tSYMBEG;
-
- default:
- yyerror0("unknown type of %string");
- return 0;
- }
+ if (c == -1) goto unterminated;
+ if (!ISALNUM(c)) {
+ term = c;
+ if (!ISASCII(c)) goto unknown;
+ c = 'Q';
+ }
+ else {
+ term = nextc(p);
+ if (rb_enc_isalnum(term, p->enc) || !parser_isascii(p)) {
+ unknown:
+ pushback(p, term);
+ c = parser_precise_mbclen(p, p->lex.pcur);
+ if (c < 0) return 0;
+ p->lex.pcur += c;
+ yyerror0("unknown type of %string");
+ return 0;
+ }
+ }
+ if (term == -1) {
+ unterminated:
+ compile_error(p, "unterminated quoted string meets end of file");
+ return 0;
+ }
+ paren = term;
+ if (term == '(') term = ')';
+ else if (term == '[') term = ']';
+ else if (term == '{') term = '}';
+ else if (term == '<') term = '>';
+ else paren = 0;
+
+ p->lex.ptok = ptok-1;
+ switch (c) {
+ case 'Q':
+ p->lex.strterm = NEW_STRTERM(str_dquote, term, paren);
+ return tSTRING_BEG;
+
+ case 'q':
+ p->lex.strterm = NEW_STRTERM(str_squote, term, paren);
+ return tSTRING_BEG;
+
+ case 'W':
+ p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
+ return tWORDS_BEG;
+
+ case 'w':
+ p->lex.strterm = NEW_STRTERM(str_sword, term, paren);
+ return tQWORDS_BEG;
+
+ case 'I':
+ p->lex.strterm = NEW_STRTERM(str_dword, term, paren);
+ return tSYMBOLS_BEG;
+
+ case 'i':
+ p->lex.strterm = NEW_STRTERM(str_sword, term, paren);
+ return tQSYMBOLS_BEG;
+
+ case 'x':
+ p->lex.strterm = NEW_STRTERM(str_xquote, term, paren);
+ return tXSTRING_BEG;
+
+ case 'r':
+ p->lex.strterm = NEW_STRTERM(str_regexp, term, paren);
+ return tREGEXP_BEG;
+
+ case 's':
+ p->lex.strterm = NEW_STRTERM(str_ssym, term, paren);
+ SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);
+ return tSYMBEG;
+
+ default:
+ yyerror0("unknown type of %string");
+ return 0;
+ }
}
if ((c = nextc(p)) == '=') {
- set_yylval_id('%');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
+ set_yylval_id('%');
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
}
if (IS_SPCARG(c) || (IS_lex_state(EXPR_FITEM) && c == 's')) {
- goto quotation;
+ goto quotation;
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
pushback(p, c);
@@ -10054,15 +9466,15 @@ static int
tokadd_ident(struct parser_params *p, int c)
{
do {
- if (tokadd_mbchar(p, c) == -1) return -1;
- c = nextc(p);
+ if (tokadd_mbchar(p, c) == -1) return -1;
+ c = nextc(p);
} while (parser_is_identchar(p));
pushback(p, c);
return 0;
}
static ID
-tokenize_ident(struct parser_params *p)
+tokenize_ident(struct parser_params *p, const enum lex_state_e last_state)
{
ID ident = TOK_INTERN();
@@ -10078,17 +9490,17 @@ parse_numvar(struct parser_params *p)
int overflow;
unsigned long n = ruby_scan_digits(tok(p)+1, toklen(p)-1, 10, &len, &overflow);
const unsigned long nth_ref_max =
- ((FIXNUM_MAX < INT_MAX) ? FIXNUM_MAX : INT_MAX) >> 1;
+ ((FIXNUM_MAX < INT_MAX) ? FIXNUM_MAX : INT_MAX) >> 1;
/* NTH_REF is left-shifted to be ORed with back-ref flag and
* turned into a Fixnum, in compile.c */
if (overflow || n > nth_ref_max) {
- /* compile_error()? */
- rb_warn1("`%s' is too big for a number variable, always nil", WARN_S(tok(p)));
- return 0; /* $0 is $PROGRAM_NAME, not NTH_REF */
+ /* compile_error()? */
+ rb_warn1("`%s' is too big for a number variable, always nil", WARN_S(tok(p)));
+ return 0; /* $0 is $PROGRAM_NAME, not NTH_REF */
}
else {
- return (int)n;
+ return (int)n;
}
}
@@ -10104,106 +9516,100 @@ parse_gvar(struct parser_params *p, const enum lex_state_e last_state)
c = nextc(p);
switch (c) {
case '_': /* $_: last read line string */
- c = nextc(p);
- if (parser_is_identchar(p)) {
- tokadd(p, '$');
- tokadd(p, '_');
- break;
- }
- pushback(p, c);
- c = '_';
- /* fall through */
- case '~': /* $~: match-data */
- case '*': /* $*: argv */
- case '$': /* $$: pid */
- case '?': /* $?: last status */
- case '!': /* $!: error string */
- case '@': /* $@: error position */
- case '/': /* $/: input record separator */
- case '\\': /* $\: output record separator */
- case ';': /* $;: field separator */
- case ',': /* $,: output field separator */
- case '.': /* $.: last read line number */
- case '=': /* $=: ignorecase */
- case ':': /* $:: load path */
- case '<': /* $<: reading filename */
- case '>': /* $>: default output handle */
- case '\"': /* $": already loaded files */
- tokadd(p, '$');
- tokadd(p, c);
- goto gvar;
+ c = nextc(p);
+ if (parser_is_identchar(p)) {
+ tokadd(p, '$');
+ tokadd(p, '_');
+ break;
+ }
+ pushback(p, c);
+ c = '_';
+ /* fall through */
+ case '~': /* $~: match-data */
+ case '*': /* $*: argv */
+ case '$': /* $$: pid */
+ case '?': /* $?: last status */
+ case '!': /* $!: error string */
+ case '@': /* $@: error position */
+ case '/': /* $/: input record separator */
+ case '\\': /* $\: output record separator */
+ case ';': /* $;: field separator */
+ case ',': /* $,: output field separator */
+ case '.': /* $.: last read line number */
+ case '=': /* $=: ignorecase */
+ case ':': /* $:: load path */
+ case '<': /* $<: reading filename */
+ case '>': /* $>: default output handle */
+ case '\"': /* $": already loaded files */
+ tokadd(p, '$');
+ tokadd(p, c);
+ goto gvar;
case '-':
- tokadd(p, '$');
- tokadd(p, c);
- c = nextc(p);
- if (parser_is_identchar(p)) {
- if (tokadd_mbchar(p, c) == -1) return 0;
- }
- else {
- pushback(p, c);
- pushback(p, '-');
- return '$';
- }
+ tokadd(p, '$');
+ tokadd(p, c);
+ c = nextc(p);
+ if (parser_is_identchar(p)) {
+ if (tokadd_mbchar(p, c) == -1) return 0;
+ }
+ else {
+ pushback(p, c);
+ pushback(p, '-');
+ return '$';
+ }
gvar:
- set_yylval_name(TOK_INTERN());
- return tGVAR;
-
- case '&': /* $&: last match */
- case '`': /* $`: string before last match */
- case '\'': /* $': string after last match */
- case '+': /* $+: string matches last paren. */
- if (IS_lex_state_for(last_state, EXPR_FNAME)) {
- tokadd(p, '$');
- tokadd(p, c);
- goto gvar;
- }
- set_yylval_node(NEW_BACK_REF(c, &_cur_loc));
- return tBACK_REF;
+ set_yylval_name(TOK_INTERN());
+ return tGVAR;
+
+ case '&': /* $&: last match */
+ case '`': /* $`: string before last match */
+ case '\'': /* $': string after last match */
+ case '+': /* $+: string matches last paren. */
+ if (IS_lex_state_for(last_state, EXPR_FNAME)) {
+ tokadd(p, '$');
+ tokadd(p, c);
+ goto gvar;
+ }
+ set_yylval_node(NEW_BACK_REF(c, &_cur_loc));
+ return tBACK_REF;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
- tokadd(p, '$');
- do {
- tokadd(p, c);
- c = nextc(p);
- } while (c != -1 && ISDIGIT(c));
- pushback(p, c);
- if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
- tokfix(p);
- c = parse_numvar(p);
- set_yylval_node(NEW_NTH_REF(c, &_cur_loc));
- return tNTH_REF;
+ tokadd(p, '$');
+ do {
+ tokadd(p, c);
+ c = nextc(p);
+ } while (c != -1 && ISDIGIT(c));
+ pushback(p, c);
+ if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
+ tokfix(p);
+ c = parse_numvar(p);
+ set_yylval_node(NEW_NTH_REF(c, &_cur_loc));
+ return tNTH_REF;
default:
- if (!parser_is_identchar(p)) {
- YYLTYPE loc = RUBY_INIT_YYLLOC();
- if (c == -1 || ISSPACE(c)) {
- compile_error(p, "`$' without identifiers is not allowed as a global variable name");
- }
- else {
- pushback(p, c);
- compile_error(p, "`$%c' is not allowed as a global variable name", c);
- }
- parser_show_error_line(p, &loc);
- set_yylval_noname();
- return tGVAR;
- }
- /* fall through */
+ if (!parser_is_identchar(p)) {
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ if (c == -1 || ISSPACE(c)) {
+ compile_error(p, "`$' without identifiers is not allowed as a global variable name");
+ }
+ else {
+ pushback(p, c);
+ compile_error(p, "`$%c' is not allowed as a global variable name", c);
+ }
+ parser_show_error_line(p, &loc);
+ set_yylval_noname();
+ return tGVAR;
+ }
+ /* fall through */
case '0':
- tokadd(p, '$');
+ tokadd(p, '$');
}
if (tokadd_ident(p, c)) return 0;
SET_LEX_STATE(EXPR_END);
- if (VALID_SYMNAME_P(tok(p), toklen(p), p->enc, ID_GLOBAL)) {
- tokenize_ident(p);
- }
- else {
- compile_error(p, "`%.*s' is not allowed as a global variable name", toklen(p), tok(p));
- set_yylval_noname();
- }
+ tokenize_ident(p, last_state);
return tGVAR;
}
@@ -10214,18 +9620,18 @@ parser_numbered_param(struct parser_params *p, int n)
if (n < 0) return false;
if (DVARS_TERMINAL_P(p->lvtbl->args) || DVARS_TERMINAL_P(p->lvtbl->args->prev)) {
- return false;
+ return false;
}
if (p->max_numparam == ORDINAL_PARAM) {
- compile_error(p, "ordinary parameter is defined");
- return false;
+ compile_error(p, "ordinary parameter is defined");
+ return false;
}
struct vtable *args = p->lvtbl->args;
if (p->max_numparam < n) {
- p->max_numparam = n;
+ p->max_numparam = n;
}
while (n > args->pos) {
- vtable_add(args, NUMPARAM_IDX_TO_ID(args->pos+1));
+ vtable_add(args, NUMPARAM_IDX_TO_ID(args->pos+1));
}
return true;
}
@@ -10243,42 +9649,42 @@ parse_atmark(struct parser_params *p, const enum lex_state_e last_state)
newtok(p);
tokadd(p, '@');
if (c == '@') {
- result = tCVAR;
- tokadd(p, '@');
- c = nextc(p);
+ result = tCVAR;
+ tokadd(p, '@');
+ c = nextc(p);
}
SET_LEX_STATE(IS_lex_state_for(last_state, EXPR_FNAME) ? EXPR_ENDFN : EXPR_END);
if (c == -1 || !parser_is_identchar(p)) {
- pushback(p, c);
- RUBY_SET_YYLLOC(loc);
- if (result == tIVAR) {
- compile_error(p, "`@' without identifiers is not allowed as an instance variable name");
- }
- else {
- compile_error(p, "`@@' without identifiers is not allowed as a class variable name");
- }
- parser_show_error_line(p, &loc);
- set_yylval_noname();
- SET_LEX_STATE(EXPR_END);
- return result;
+ pushback(p, c);
+ RUBY_SET_YYLLOC(loc);
+ if (result == tIVAR) {
+ compile_error(p, "`@' without identifiers is not allowed as an instance variable name");
+ }
+ else {
+ compile_error(p, "`@@' without identifiers is not allowed as a class variable name");
+ }
+ parser_show_error_line(p, &loc);
+ set_yylval_noname();
+ SET_LEX_STATE(EXPR_END);
+ return result;
}
else if (ISDIGIT(c)) {
- pushback(p, c);
- RUBY_SET_YYLLOC(loc);
- if (result == tIVAR) {
- compile_error(p, "`@%c' is not allowed as an instance variable name", c);
- }
- else {
- compile_error(p, "`@@%c' is not allowed as a class variable name", c);
- }
- parser_show_error_line(p, &loc);
- set_yylval_noname();
- SET_LEX_STATE(EXPR_END);
- return result;
+ pushback(p, c);
+ RUBY_SET_YYLLOC(loc);
+ if (result == tIVAR) {
+ compile_error(p, "`@%c' is not allowed as an instance variable name", c);
+ }
+ else {
+ compile_error(p, "`@@%c' is not allowed as a class variable name", c);
+ }
+ parser_show_error_line(p, &loc);
+ set_yylval_noname();
+ SET_LEX_STATE(EXPR_END);
+ return result;
}
if (tokadd_ident(p, c)) return 0;
- tokenize_ident(p);
+ tokenize_ident(p, last_state);
return result;
}
@@ -10292,112 +9698,112 @@ parse_ident(struct parser_params *p, int c, int cmd_state)
int enforce_keyword_end = 0;
do {
- if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
- if (tokadd_mbchar(p, c) == -1) return 0;
- c = nextc(p);
+ if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
+ if (tokadd_mbchar(p, c) == -1) return 0;
+ c = nextc(p);
} while (parser_is_identchar(p));
if ((c == '!' || c == '?') && !peek(p, '=')) {
- result = tFID;
- tokadd(p, c);
+ result = tFID;
+ tokadd(p, c);
}
else if (c == '=' && IS_lex_state(EXPR_FNAME) &&
- (!peek(p, '~') && !peek(p, '>') && (!peek(p, '=') || (peek_n(p, '>', 1))))) {
- result = tIDENTIFIER;
- tokadd(p, c);
+ (!peek(p, '~') && !peek(p, '>') && (!peek(p, '=') || (peek_n(p, '>', 1))))) {
+ result = tIDENTIFIER;
+ tokadd(p, c);
}
else {
- result = tCONSTANT; /* assume provisionally */
- pushback(p, c);
+ result = tCONSTANT; /* assume provisionally */
+ pushback(p, c);
}
tokfix(p);
if (IS_LABEL_POSSIBLE()) {
- if (IS_LABEL_SUFFIX(0)) {
- SET_LEX_STATE(EXPR_ARG|EXPR_LABELED);
- nextc(p);
- set_yylval_name(TOK_INTERN());
- return tLABEL;
- }
+ if (IS_LABEL_SUFFIX(0)) {
+ SET_LEX_STATE(EXPR_ARG|EXPR_LABELED);
+ nextc(p);
+ set_yylval_name(TOK_INTERN());
+ return tLABEL;
+ }
}
#ifndef RIPPER
if (!NIL_P(peek_end_expect_token_locations(p))) {
- VALUE end_loc;
- int lineno, column;
- int beg_pos = (int)(p->lex.ptok - p->lex.pbeg);
+ VALUE end_loc;
+ int lineno, column;
+ int beg_pos = (int)(p->lex.ptok - p->lex.pbeg);
- end_loc = peek_end_expect_token_locations(p);
- lineno = NUM2INT(rb_ary_entry(end_loc, 0));
- column = NUM2INT(rb_ary_entry(end_loc, 1));
+ end_loc = peek_end_expect_token_locations(p);
+ lineno = NUM2INT(rb_ary_entry(end_loc, 0));
+ column = NUM2INT(rb_ary_entry(end_loc, 1));
- if (p->debug) {
- rb_parser_printf(p, "enforce_keyword_end check. current: (%d, %d), peek: (%d, %d)\n",
- p->ruby_sourceline, beg_pos, lineno, column);
- }
+ if (p->debug) {
+ rb_parser_printf(p, "enforce_keyword_end check. current: (%d, %d), peek: (%d, %d)\n",
+ p->ruby_sourceline, beg_pos, lineno, column);
+ }
- if ((p->ruby_sourceline > lineno) && (beg_pos <= column)) {
- const struct kwtable *kw;
+ if ((p->ruby_sourceline > lineno) && (beg_pos <= column)) {
+ const struct kwtable *kw;
- if ((IS_lex_state(EXPR_DOT)) && (kw = rb_reserved_word(tok(p), toklen(p))) && (kw && kw->id[0] == keyword_end)) {
- if (p->debug) rb_parser_printf(p, "enforce_keyword_end is enabled\n");
- enforce_keyword_end = 1;
- }
- }
+ if ((IS_lex_state(EXPR_DOT)) && (kw = rb_reserved_word(tok(p), toklen(p))) && (kw && kw->id[0] == keyword_end)) {
+ if (p->debug) rb_parser_printf(p, "enforce_keyword_end is enabled\n");
+ enforce_keyword_end = 1;
+ }
+ }
}
#endif
if (mb == ENC_CODERANGE_7BIT && (!IS_lex_state(EXPR_DOT) || enforce_keyword_end)) {
- const struct kwtable *kw;
-
- /* See if it is a reserved word. */
- kw = rb_reserved_word(tok(p), toklen(p));
- if (kw) {
- enum lex_state_e state = p->lex.state;
- if (IS_lex_state_for(state, EXPR_FNAME)) {
- SET_LEX_STATE(EXPR_ENDFN);
- set_yylval_name(rb_intern2(tok(p), toklen(p)));
- return kw->id[0];
- }
- SET_LEX_STATE(kw->state);
- if (IS_lex_state(EXPR_BEG)) {
- p->command_start = TRUE;
- }
- if (kw->id[0] == keyword_do) {
- if (lambda_beginning_p()) {
- p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE in the body of "-> do ... end" */
- return keyword_do_LAMBDA;
- }
- if (COND_P()) return keyword_do_cond;
- if (CMDARG_P() && !IS_lex_state_for(state, EXPR_CMDARG))
- return keyword_do_block;
- return keyword_do;
- }
- if (IS_lex_state_for(state, (EXPR_BEG | EXPR_LABELED | EXPR_CLASS)))
- return kw->id[0];
- else {
- if (kw->id[0] != kw->id[1])
- SET_LEX_STATE(EXPR_BEG | EXPR_LABEL);
- return kw->id[1];
- }
- }
+ const struct kwtable *kw;
+
+ /* See if it is a reserved word. */
+ kw = rb_reserved_word(tok(p), toklen(p));
+ if (kw) {
+ enum lex_state_e state = p->lex.state;
+ if (IS_lex_state_for(state, EXPR_FNAME)) {
+ SET_LEX_STATE(EXPR_ENDFN);
+ set_yylval_name(rb_intern2(tok(p), toklen(p)));
+ return kw->id[0];
+ }
+ SET_LEX_STATE(kw->state);
+ if (IS_lex_state(EXPR_BEG)) {
+ p->command_start = TRUE;
+ }
+ if (kw->id[0] == keyword_do) {
+ if (lambda_beginning_p()) {
+ p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE in the body of "-> do ... end" */
+ return keyword_do_LAMBDA;
+ }
+ if (COND_P()) return keyword_do_cond;
+ if (CMDARG_P() && !IS_lex_state_for(state, EXPR_CMDARG))
+ return keyword_do_block;
+ return keyword_do;
+ }
+ if (IS_lex_state_for(state, (EXPR_BEG | EXPR_LABELED | EXPR_CLASS)))
+ return kw->id[0];
+ else {
+ if (kw->id[0] != kw->id[1])
+ SET_LEX_STATE(EXPR_BEG | EXPR_LABEL);
+ return kw->id[1];
+ }
+ }
}
if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
- if (cmd_state) {
- SET_LEX_STATE(EXPR_CMDARG);
- }
- else {
- SET_LEX_STATE(EXPR_ARG);
- }
+ if (cmd_state) {
+ SET_LEX_STATE(EXPR_CMDARG);
+ }
+ else {
+ SET_LEX_STATE(EXPR_ARG);
+ }
}
else if (p->lex.state == EXPR_FNAME) {
- SET_LEX_STATE(EXPR_ENDFN);
+ SET_LEX_STATE(EXPR_ENDFN);
}
else {
- SET_LEX_STATE(EXPR_END);
+ SET_LEX_STATE(EXPR_END);
}
- ident = tokenize_ident(p);
+ ident = tokenize_ident(p, last_state);
if (result == tCONSTANT && is_local_id(ident)) result = tIDENTIFIER;
if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
(result == tIDENTIFIER) && /* not EXPR_FNAME, not attrasgn */
@@ -10411,9 +9817,9 @@ static void
warn_cr(struct parser_params *p)
{
if (!p->cr_seen) {
- p->cr_seen = TRUE;
- /* carried over with p->lex.nextline for nextc() */
- rb_warn0("encountered \\r in middle of line, treated as a mere space");
+ p->cr_seen = TRUE;
+ /* carried over with p->lex.nextline for nextc() */
+ rb_warn0("encountered \\r in middle of line, treated as a mere space");
}
}
@@ -10429,14 +9835,14 @@ parser_yylex(struct parser_params *p)
int token_seen = p->token_seen;
if (p->lex.strterm) {
- if (strterm_is_heredoc(p->lex.strterm)) {
- token_flush(p);
- return here_document(p, &p->lex.strterm->u.heredoc);
- }
- else {
- token_flush(p);
- return parse_string(p, &p->lex.strterm->u.literal);
- }
+ if (p->lex.strterm->flags & STRTERM_HEREDOC) {
+ token_flush(p);
+ return here_document(p, &p->lex.strterm->u.heredoc);
+ }
+ else {
+ token_flush(p);
+ return parse_string(p, &p->lex.strterm->u.literal);
+ }
}
cmd_state = p->command_start;
p->command_start = FALSE;
@@ -10451,687 +9857,686 @@ parser_yylex(struct parser_params *p)
case '\004': /* ^D */
case '\032': /* ^Z */
case -1: /* end of script. */
- p->eofp = 1;
+ p->eofp = 1;
#ifndef RIPPER
- if (!NIL_P(p->end_expect_token_locations) && RARRAY_LEN(p->end_expect_token_locations) > 0) {
- pop_end_expect_token_locations(p);
- RUBY_SET_YYLLOC_OF_DUMMY_END(*p->yylloc);
- return tDUMNY_END;
- }
+ if (!NIL_P(p->end_expect_token_locations) && RARRAY_LEN(p->end_expect_token_locations) > 0) {
+ pop_end_expect_token_locations(p);
+ RUBY_SET_YYLLOC_OF_DUMMY_END(*p->yylloc);
+ return tDUMNY_END;
+ }
#endif
- /* Set location for end-of-input because dispatch_scan_event is not called. */
- RUBY_SET_YYLLOC(*p->yylloc);
- return END_OF_INPUT;
+ /* Set location for end-of-input because dispatch_scan_event is not called. */
+ RUBY_SET_YYLLOC(*p->yylloc);
+ return 0;
- /* white spaces */
+ /* white spaces */
case '\r':
- warn_cr(p);
- /* fall through */
+ warn_cr(p);
+ /* fall through */
case ' ': case '\t': case '\f':
case '\13': /* '\v' */
- space_seen = 1;
- while ((c = nextc(p))) {
- switch (c) {
- case '\r':
- warn_cr(p);
- /* fall through */
- case ' ': case '\t': case '\f':
- case '\13': /* '\v' */
- break;
- default:
- goto outofloop;
- }
- }
+ space_seen = 1;
+ while ((c = nextc(p))) {
+ switch (c) {
+ case '\r':
+ warn_cr(p);
+ /* fall through */
+ case ' ': case '\t': case '\f':
+ case '\13': /* '\v' */
+ break;
+ default:
+ goto outofloop;
+ }
+ }
outofloop:
- pushback(p, c);
- dispatch_scan_event(p, tSP);
+ pushback(p, c);
+ dispatch_scan_event(p, tSP);
#ifndef RIPPER
- token_flush(p);
+ token_flush(p);
#endif
- goto retry;
+ goto retry;
case '#': /* it's a comment */
- p->token_seen = token_seen;
- /* no magic_comment in shebang line */
- if (!parser_magic_comment(p, p->lex.pcur, p->lex.pend - p->lex.pcur)) {
- if (comment_at_top(p)) {
- set_file_encoding(p, p->lex.pcur, p->lex.pend);
- }
- }
- lex_goto_eol(p);
+ p->token_seen = token_seen;
+ /* no magic_comment in shebang line */
+ if (!parser_magic_comment(p, p->lex.pcur, p->lex.pend - p->lex.pcur)) {
+ if (comment_at_top(p)) {
+ set_file_encoding(p, p->lex.pcur, p->lex.pend);
+ }
+ }
+ lex_goto_eol(p);
dispatch_scan_event(p, tCOMMENT);
fallthru = TRUE;
- /* fall through */
+ /* fall through */
case '\n':
- p->token_seen = token_seen;
- VALUE prevline = p->lex.lastline;
- c = (IS_lex_state(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT) &&
- !IS_lex_state(EXPR_LABELED));
- if (c || IS_lex_state_all(EXPR_ARG|EXPR_LABELED)) {
+ p->token_seen = token_seen;
+ c = (IS_lex_state(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT) &&
+ !IS_lex_state(EXPR_LABELED));
+ if (c || IS_lex_state_all(EXPR_ARG|EXPR_LABELED)) {
if (!fallthru) {
dispatch_scan_event(p, tIGNORED_NL);
}
fallthru = FALSE;
- if (!c && p->ctxt.in_kwarg) {
- goto normal_newline;
- }
- goto retry;
- }
- while (1) {
- switch (c = nextc(p)) {
- case ' ': case '\t': case '\f': case '\r':
- case '\13': /* '\v' */
- space_seen = 1;
- break;
- case '#':
- pushback(p, c);
- if (space_seen) {
- dispatch_scan_event(p, tSP);
- token_flush(p);
- }
- goto retry;
- case '&':
- case '.': {
- dispatch_delayed_token(p, tIGNORED_NL);
- if (peek(p, '.') == (c == '&')) {
- pushback(p, c);
- dispatch_scan_event(p, tSP);
- goto retry;
- }
- }
- default:
- p->ruby_sourceline--;
- p->lex.nextline = p->lex.lastline;
- set_lastline(p, prevline);
- case -1: /* EOF no decrement*/
- lex_goto_eol(p);
- if (c != -1) {
- token_flush(p);
- RUBY_SET_YYLLOC(*p->yylloc);
- }
- goto normal_newline;
- }
- }
+ if (!c && p->ctxt.in_kwarg) {
+ goto normal_newline;
+ }
+ goto retry;
+ }
+ while (1) {
+ switch (c = nextc(p)) {
+ case ' ': case '\t': case '\f': case '\r':
+ case '\13': /* '\v' */
+ space_seen = 1;
+ break;
+ case '#':
+ pushback(p, c);
+ if (space_seen) {
+ dispatch_scan_event(p, tSP);
+ token_flush(p);
+ }
+ goto retry;
+ case '&':
+ case '.': {
+ dispatch_delayed_token(p, tIGNORED_NL);
+ if (peek(p, '.') == (c == '&')) {
+ pushback(p, c);
+ dispatch_scan_event(p, tSP);
+ goto retry;
+ }
+ }
+ default:
+ p->ruby_sourceline--;
+ p->lex.nextline = p->lex.lastline;
+ case -1: /* EOF no decrement*/
+ lex_goto_eol(p);
+ if (c != -1) {
+ p->lex.ptok = p->lex.pcur;
+ }
+ goto normal_newline;
+ }
+ }
normal_newline:
- p->command_start = TRUE;
- SET_LEX_STATE(EXPR_BEG);
- return '\n';
+ p->command_start = TRUE;
+ SET_LEX_STATE(EXPR_BEG);
+ return '\n';
case '*':
- if ((c = nextc(p)) == '*') {
- if ((c = nextc(p)) == '=') {
- set_yylval_id(idPow);
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- if (IS_SPCARG(c)) {
- rb_warning0("`**' interpreted as argument prefix");
- c = tDSTAR;
- }
- else if (IS_BEG()) {
- c = tDSTAR;
- }
- else {
- c = warn_balanced((enum ruby_method_ids)tPOW, "**", "argument prefix");
- }
- }
- else {
- if (c == '=') {
+ if ((c = nextc(p)) == '*') {
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idPow);
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ if (IS_SPCARG(c)) {
+ rb_warning0("`**' interpreted as argument prefix");
+ c = tDSTAR;
+ }
+ else if (IS_BEG()) {
+ c = tDSTAR;
+ }
+ else {
+ c = warn_balanced((enum ruby_method_ids)tPOW, "**", "argument prefix");
+ }
+ }
+ else {
+ if (c == '=') {
set_yylval_id('*');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- if (IS_SPCARG(c)) {
- rb_warning0("`*' interpreted as argument prefix");
- c = tSTAR;
- }
- else if (IS_BEG()) {
- c = tSTAR;
- }
- else {
- c = warn_balanced('*', "*", "argument prefix");
- }
- }
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- return c;
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ if (IS_SPCARG(c)) {
+ rb_warning0("`*' interpreted as argument prefix");
+ c = tSTAR;
+ }
+ else if (IS_BEG()) {
+ c = tSTAR;
+ }
+ else {
+ c = warn_balanced('*', "*", "argument prefix");
+ }
+ }
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
+ return c;
case '!':
- c = nextc(p);
- if (IS_AFTER_OPERATOR()) {
- SET_LEX_STATE(EXPR_ARG);
- if (c == '@') {
- return '!';
- }
- }
- else {
- SET_LEX_STATE(EXPR_BEG);
- }
- if (c == '=') {
- return tNEQ;
- }
- if (c == '~') {
- return tNMATCH;
- }
- pushback(p, c);
- return '!';
+ c = nextc(p);
+ if (IS_AFTER_OPERATOR()) {
+ SET_LEX_STATE(EXPR_ARG);
+ if (c == '@') {
+ return '!';
+ }
+ }
+ else {
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ if (c == '=') {
+ return tNEQ;
+ }
+ if (c == '~') {
+ return tNMATCH;
+ }
+ pushback(p, c);
+ return '!';
case '=':
- if (was_bol(p)) {
- /* skip embedded rd document */
- if (word_match_p(p, "begin", 5)) {
- int first_p = TRUE;
-
- lex_goto_eol(p);
- dispatch_scan_event(p, tEMBDOC_BEG);
- for (;;) {
- lex_goto_eol(p);
- if (!first_p) {
- dispatch_scan_event(p, tEMBDOC);
- }
- first_p = FALSE;
- c = nextc(p);
- if (c == -1) {
- compile_error(p, "embedded document meets end of file");
- return END_OF_INPUT;
- }
- if (c == '=' && word_match_p(p, "end", 3)) {
- break;
- }
- pushback(p, c);
- }
- lex_goto_eol(p);
- dispatch_scan_event(p, tEMBDOC_END);
- goto retry;
- }
- }
-
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- if ((c = nextc(p)) == '=') {
- if ((c = nextc(p)) == '=') {
- return tEQQ;
- }
- pushback(p, c);
- return tEQ;
- }
- if (c == '~') {
- return tMATCH;
- }
- else if (c == '>') {
- return tASSOC;
- }
- pushback(p, c);
- return '=';
+ if (was_bol(p)) {
+ /* skip embedded rd document */
+ if (word_match_p(p, "begin", 5)) {
+ int first_p = TRUE;
+
+ lex_goto_eol(p);
+ dispatch_scan_event(p, tEMBDOC_BEG);
+ for (;;) {
+ lex_goto_eol(p);
+ if (!first_p) {
+ dispatch_scan_event(p, tEMBDOC);
+ }
+ first_p = FALSE;
+ c = nextc(p);
+ if (c == -1) {
+ compile_error(p, "embedded document meets end of file");
+ return 0;
+ }
+ if (c == '=' && word_match_p(p, "end", 3)) {
+ break;
+ }
+ pushback(p, c);
+ }
+ lex_goto_eol(p);
+ dispatch_scan_event(p, tEMBDOC_END);
+ goto retry;
+ }
+ }
+
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
+ if ((c = nextc(p)) == '=') {
+ if ((c = nextc(p)) == '=') {
+ return tEQQ;
+ }
+ pushback(p, c);
+ return tEQ;
+ }
+ if (c == '~') {
+ return tMATCH;
+ }
+ else if (c == '>') {
+ return tASSOC;
+ }
+ pushback(p, c);
+ return '=';
case '<':
- c = nextc(p);
- if (c == '<' &&
- !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
- !IS_END() &&
- (!IS_ARG() || IS_lex_state(EXPR_LABELED) || space_seen)) {
- enum yytokentype token = heredoc_identifier(p);
- if (token) return token < 0 ? 0 : token;
- }
- if (IS_AFTER_OPERATOR()) {
- SET_LEX_STATE(EXPR_ARG);
- }
- else {
- if (IS_lex_state(EXPR_CLASS))
- p->command_start = TRUE;
- SET_LEX_STATE(EXPR_BEG);
- }
- if (c == '=') {
- if ((c = nextc(p)) == '>') {
- return tCMP;
- }
- pushback(p, c);
- return tLEQ;
- }
- if (c == '<') {
- if ((c = nextc(p)) == '=') {
- set_yylval_id(idLTLT);
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- return warn_balanced((enum ruby_method_ids)tLSHFT, "<<", "here document");
- }
- pushback(p, c);
- return '<';
+ c = nextc(p);
+ if (c == '<' &&
+ !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
+ !IS_END() &&
+ (!IS_ARG() || IS_lex_state(EXPR_LABELED) || space_seen)) {
+ int token = heredoc_identifier(p);
+ if (token) return token < 0 ? 0 : token;
+ }
+ if (IS_AFTER_OPERATOR()) {
+ SET_LEX_STATE(EXPR_ARG);
+ }
+ else {
+ if (IS_lex_state(EXPR_CLASS))
+ p->command_start = TRUE;
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ if (c == '=') {
+ if ((c = nextc(p)) == '>') {
+ return tCMP;
+ }
+ pushback(p, c);
+ return tLEQ;
+ }
+ if (c == '<') {
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idLTLT);
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ return warn_balanced((enum ruby_method_ids)tLSHFT, "<<", "here document");
+ }
+ pushback(p, c);
+ return '<';
case '>':
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- if ((c = nextc(p)) == '=') {
- return tGEQ;
- }
- if (c == '>') {
- if ((c = nextc(p)) == '=') {
- set_yylval_id(idGTGT);
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- return tRSHFT;
- }
- pushback(p, c);
- return '>';
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
+ if ((c = nextc(p)) == '=') {
+ return tGEQ;
+ }
+ if (c == '>') {
+ if ((c = nextc(p)) == '=') {
+ set_yylval_id(idGTGT);
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ return tRSHFT;
+ }
+ pushback(p, c);
+ return '>';
case '"':
- label = (IS_LABEL_POSSIBLE() ? str_label : 0);
- p->lex.strterm = NEW_STRTERM(str_dquote | label, '"', 0);
- p->lex.ptok = p->lex.pcur-1;
- return tSTRING_BEG;
+ label = (IS_LABEL_POSSIBLE() ? str_label : 0);
+ p->lex.strterm = NEW_STRTERM(str_dquote | label, '"', 0);
+ p->lex.ptok = p->lex.pcur-1;
+ return tSTRING_BEG;
case '`':
- if (IS_lex_state(EXPR_FNAME)) {
- SET_LEX_STATE(EXPR_ENDFN);
- return c;
- }
- if (IS_lex_state(EXPR_DOT)) {
- if (cmd_state)
- SET_LEX_STATE(EXPR_CMDARG);
- else
- SET_LEX_STATE(EXPR_ARG);
- return c;
- }
- p->lex.strterm = NEW_STRTERM(str_xquote, '`', 0);
- return tXSTRING_BEG;
+ if (IS_lex_state(EXPR_FNAME)) {
+ SET_LEX_STATE(EXPR_ENDFN);
+ return c;
+ }
+ if (IS_lex_state(EXPR_DOT)) {
+ if (cmd_state)
+ SET_LEX_STATE(EXPR_CMDARG);
+ else
+ SET_LEX_STATE(EXPR_ARG);
+ return c;
+ }
+ p->lex.strterm = NEW_STRTERM(str_xquote, '`', 0);
+ return tXSTRING_BEG;
case '\'':
- label = (IS_LABEL_POSSIBLE() ? str_label : 0);
- p->lex.strterm = NEW_STRTERM(str_squote | label, '\'', 0);
- p->lex.ptok = p->lex.pcur-1;
- return tSTRING_BEG;
+ label = (IS_LABEL_POSSIBLE() ? str_label : 0);
+ p->lex.strterm = NEW_STRTERM(str_squote | label, '\'', 0);
+ p->lex.ptok = p->lex.pcur-1;
+ return tSTRING_BEG;
case '?':
- return parse_qmark(p, space_seen);
+ return parse_qmark(p, space_seen);
case '&':
- if ((c = nextc(p)) == '&') {
- SET_LEX_STATE(EXPR_BEG);
- if ((c = nextc(p)) == '=') {
+ if ((c = nextc(p)) == '&') {
+ SET_LEX_STATE(EXPR_BEG);
+ if ((c = nextc(p)) == '=') {
set_yylval_id(idANDOP);
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- return tANDOP;
- }
- else if (c == '=') {
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ return tANDOP;
+ }
+ else if (c == '=') {
set_yylval_id('&');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- else if (c == '.') {
- set_yylval_id(idANDDOT);
- SET_LEX_STATE(EXPR_DOT);
- return tANDDOT;
- }
- pushback(p, c);
- if (IS_SPCARG(c)) {
- if ((c != ':') ||
- (c = peekc_n(p, 1)) == -1 ||
- !(c == '\'' || c == '"' ||
- is_identchar(p, (p->lex.pcur+1), p->lex.pend, p->enc))) {
- rb_warning0("`&' interpreted as argument prefix");
- }
- c = tAMPER;
- }
- else if (IS_BEG()) {
- c = tAMPER;
- }
- else {
- c = warn_balanced('&', "&", "argument prefix");
- }
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- return c;
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ else if (c == '.') {
+ set_yylval_id(idANDDOT);
+ SET_LEX_STATE(EXPR_DOT);
+ return tANDDOT;
+ }
+ pushback(p, c);
+ if (IS_SPCARG(c)) {
+ if ((c != ':') ||
+ (c = peekc_n(p, 1)) == -1 ||
+ !(c == '\'' || c == '"' ||
+ is_identchar((p->lex.pcur+1), p->lex.pend, p->enc))) {
+ rb_warning0("`&' interpreted as argument prefix");
+ }
+ c = tAMPER;
+ }
+ else if (IS_BEG()) {
+ c = tAMPER;
+ }
+ else {
+ c = warn_balanced('&', "&", "argument prefix");
+ }
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
+ return c;
case '|':
- if ((c = nextc(p)) == '|') {
- SET_LEX_STATE(EXPR_BEG);
- if ((c = nextc(p)) == '=') {
+ if ((c = nextc(p)) == '|') {
+ SET_LEX_STATE(EXPR_BEG);
+ if ((c = nextc(p)) == '=') {
set_yylval_id(idOROP);
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- if (IS_lex_state_for(last_state, EXPR_BEG)) {
- c = '|';
- pushback(p, '|');
- return c;
- }
- return tOROP;
- }
- if (c == '=') {
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ if (IS_lex_state_for(last_state, EXPR_BEG)) {
+ c = '|';
+ pushback(p, '|');
+ return c;
+ }
+ return tOROP;
+ }
+ if (c == '=') {
set_yylval_id('|');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL);
- pushback(p, c);
- return '|';
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL);
+ pushback(p, c);
+ return '|';
case '+':
- c = nextc(p);
- if (IS_AFTER_OPERATOR()) {
- SET_LEX_STATE(EXPR_ARG);
- if (c == '@') {
- return tUPLUS;
- }
- pushback(p, c);
- return '+';
- }
- if (c == '=') {
+ c = nextc(p);
+ if (IS_AFTER_OPERATOR()) {
+ SET_LEX_STATE(EXPR_ARG);
+ if (c == '@') {
+ return tUPLUS;
+ }
+ pushback(p, c);
+ return '+';
+ }
+ if (c == '=') {
set_yylval_id('+');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p, '+'))) {
- SET_LEX_STATE(EXPR_BEG);
- pushback(p, c);
- if (c != -1 && ISDIGIT(c)) {
- return parse_numeric(p, '+');
- }
- return tUPLUS;
- }
- SET_LEX_STATE(EXPR_BEG);
- pushback(p, c);
- return warn_balanced('+', "+", "unary operator");
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p, '+'))) {
+ SET_LEX_STATE(EXPR_BEG);
+ pushback(p, c);
+ if (c != -1 && ISDIGIT(c)) {
+ return parse_numeric(p, '+');
+ }
+ return tUPLUS;
+ }
+ SET_LEX_STATE(EXPR_BEG);
+ pushback(p, c);
+ return warn_balanced('+', "+", "unary operator");
case '-':
- c = nextc(p);
- if (IS_AFTER_OPERATOR()) {
- SET_LEX_STATE(EXPR_ARG);
- if (c == '@') {
- return tUMINUS;
- }
- pushback(p, c);
- return '-';
- }
- if (c == '=') {
+ c = nextc(p);
+ if (IS_AFTER_OPERATOR()) {
+ SET_LEX_STATE(EXPR_ARG);
+ if (c == '@') {
+ return tUMINUS;
+ }
+ pushback(p, c);
+ return '-';
+ }
+ if (c == '=') {
set_yylval_id('-');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- if (c == '>') {
- SET_LEX_STATE(EXPR_ENDFN);
- return tLAMBDA;
- }
- if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p, '-'))) {
- SET_LEX_STATE(EXPR_BEG);
- pushback(p, c);
- if (c != -1 && ISDIGIT(c)) {
- return tUMINUS_NUM;
- }
- return tUMINUS;
- }
- SET_LEX_STATE(EXPR_BEG);
- pushback(p, c);
- return warn_balanced('-', "-", "unary operator");
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ if (c == '>') {
+ SET_LEX_STATE(EXPR_ENDFN);
+ return tLAMBDA;
+ }
+ if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p, '-'))) {
+ SET_LEX_STATE(EXPR_BEG);
+ pushback(p, c);
+ if (c != -1 && ISDIGIT(c)) {
+ return tUMINUS_NUM;
+ }
+ return tUMINUS;
+ }
+ SET_LEX_STATE(EXPR_BEG);
+ pushback(p, c);
+ return warn_balanced('-', "-", "unary operator");
case '.': {
int is_beg = IS_BEG();
- SET_LEX_STATE(EXPR_BEG);
- if ((c = nextc(p)) == '.') {
- if ((c = nextc(p)) == '.') {
- if (p->ctxt.in_argdef) {
- SET_LEX_STATE(EXPR_ENDARG);
- return tBDOT3;
- }
- if (p->lex.paren_nest == 0 && looking_at_eol_p(p)) {
- rb_warn0("... at EOL, should be parenthesized?");
- }
- else if (p->lex.lpar_beg >= 0 && p->lex.lpar_beg+1 == p->lex.paren_nest) {
- if (IS_lex_state_for(last_state, EXPR_LABEL))
- return tDOT3;
- }
- return is_beg ? tBDOT3 : tDOT3;
- }
- pushback(p, c);
- return is_beg ? tBDOT2 : tDOT2;
- }
- pushback(p, c);
- if (c != -1 && ISDIGIT(c)) {
- char prev = p->lex.pcur-1 > p->lex.pbeg ? *(p->lex.pcur-2) : 0;
- parse_numeric(p, '.');
- if (ISDIGIT(prev)) {
- yyerror0("unexpected fraction part after numeric literal");
- }
- else {
- yyerror0("no .<digit> floating literal anymore; put 0 before dot");
- }
- SET_LEX_STATE(EXPR_END);
- p->lex.ptok = p->lex.pcur;
- goto retry;
- }
- set_yylval_id('.');
- SET_LEX_STATE(EXPR_DOT);
- return '.';
+ SET_LEX_STATE(EXPR_BEG);
+ if ((c = nextc(p)) == '.') {
+ if ((c = nextc(p)) == '.') {
+ if (p->ctxt.in_argdef) {
+ SET_LEX_STATE(EXPR_ENDARG);
+ return tBDOT3;
+ }
+ if (p->lex.paren_nest == 0 && looking_at_eol_p(p)) {
+ rb_warn0("... at EOL, should be parenthesized?");
+ }
+ else if (p->lex.lpar_beg >= 0 && p->lex.lpar_beg+1 == p->lex.paren_nest) {
+ if (IS_lex_state_for(last_state, EXPR_LABEL))
+ return tDOT3;
+ }
+ return is_beg ? tBDOT3 : tDOT3;
+ }
+ pushback(p, c);
+ return is_beg ? tBDOT2 : tDOT2;
+ }
+ pushback(p, c);
+ if (c != -1 && ISDIGIT(c)) {
+ char prev = p->lex.pcur-1 > p->lex.pbeg ? *(p->lex.pcur-2) : 0;
+ parse_numeric(p, '.');
+ if (ISDIGIT(prev)) {
+ yyerror0("unexpected fraction part after numeric literal");
+ }
+ else {
+ yyerror0("no .<digit> floating literal anymore; put 0 before dot");
+ }
+ SET_LEX_STATE(EXPR_END);
+ p->lex.ptok = p->lex.pcur;
+ goto retry;
+ }
+ set_yylval_id('.');
+ SET_LEX_STATE(EXPR_DOT);
+ return '.';
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- return parse_numeric(p, c);
+ return parse_numeric(p, c);
case ')':
- COND_POP();
- CMDARG_POP();
- SET_LEX_STATE(EXPR_ENDFN);
- p->lex.paren_nest--;
- return c;
+ COND_POP();
+ CMDARG_POP();
+ SET_LEX_STATE(EXPR_ENDFN);
+ p->lex.paren_nest--;
+ return c;
case ']':
- COND_POP();
- CMDARG_POP();
- SET_LEX_STATE(EXPR_END);
- p->lex.paren_nest--;
- return c;
+ COND_POP();
+ CMDARG_POP();
+ SET_LEX_STATE(EXPR_END);
+ p->lex.paren_nest--;
+ return c;
case '}':
- /* tSTRING_DEND does COND_POP and CMDARG_POP in the yacc's rule */
- if (!p->lex.brace_nest--) return tSTRING_DEND;
- COND_POP();
- CMDARG_POP();
- SET_LEX_STATE(EXPR_END);
- p->lex.paren_nest--;
- return c;
+ /* tSTRING_DEND does COND_POP and CMDARG_POP in the yacc's rule */
+ if (!p->lex.brace_nest--) return tSTRING_DEND;
+ COND_POP();
+ CMDARG_POP();
+ SET_LEX_STATE(EXPR_END);
+ p->lex.paren_nest--;
+ return c;
case ':':
- c = nextc(p);
- if (c == ':') {
- if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
- SET_LEX_STATE(EXPR_BEG);
- return tCOLON3;
- }
- set_yylval_id(idCOLON2);
- SET_LEX_STATE(EXPR_DOT);
- return tCOLON2;
- }
- if (IS_END() || ISSPACE(c) || c == '#') {
- pushback(p, c);
- c = warn_balanced(':', ":", "symbol literal");
- SET_LEX_STATE(EXPR_BEG);
- return c;
- }
- switch (c) {
- case '\'':
- p->lex.strterm = NEW_STRTERM(str_ssym, c, 0);
- break;
- case '"':
- p->lex.strterm = NEW_STRTERM(str_dsym, c, 0);
- break;
- default:
- pushback(p, c);
- break;
- }
- SET_LEX_STATE(EXPR_FNAME);
- return tSYMBEG;
+ c = nextc(p);
+ if (c == ':') {
+ if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
+ SET_LEX_STATE(EXPR_BEG);
+ return tCOLON3;
+ }
+ set_yylval_id(idCOLON2);
+ SET_LEX_STATE(EXPR_DOT);
+ return tCOLON2;
+ }
+ if (IS_END() || ISSPACE(c) || c == '#') {
+ pushback(p, c);
+ c = warn_balanced(':', ":", "symbol literal");
+ SET_LEX_STATE(EXPR_BEG);
+ return c;
+ }
+ switch (c) {
+ case '\'':
+ p->lex.strterm = NEW_STRTERM(str_ssym, c, 0);
+ break;
+ case '"':
+ p->lex.strterm = NEW_STRTERM(str_dsym, c, 0);
+ break;
+ default:
+ pushback(p, c);
+ break;
+ }
+ SET_LEX_STATE(EXPR_FNAME);
+ return tSYMBEG;
case '/':
- if (IS_BEG()) {
- p->lex.strterm = NEW_STRTERM(str_regexp, '/', 0);
- return tREGEXP_BEG;
- }
- if ((c = nextc(p)) == '=') {
+ if (IS_BEG()) {
+ p->lex.strterm = NEW_STRTERM(str_regexp, '/', 0);
+ return tREGEXP_BEG;
+ }
+ if ((c = nextc(p)) == '=') {
set_yylval_id('/');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- pushback(p, c);
- if (IS_SPCARG(c)) {
- arg_ambiguous(p, '/');
- p->lex.strterm = NEW_STRTERM(str_regexp, '/', 0);
- return tREGEXP_BEG;
- }
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- return warn_balanced('/', "/", "regexp literal");
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ pushback(p, c);
+ if (IS_SPCARG(c)) {
+ arg_ambiguous(p, '/');
+ p->lex.strterm = NEW_STRTERM(str_regexp, '/', 0);
+ return tREGEXP_BEG;
+ }
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
+ return warn_balanced('/', "/", "regexp literal");
case '^':
- if ((c = nextc(p)) == '=') {
+ if ((c = nextc(p)) == '=') {
set_yylval_id('^');
- SET_LEX_STATE(EXPR_BEG);
- return tOP_ASGN;
- }
- SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
- pushback(p, c);
- return '^';
+ SET_LEX_STATE(EXPR_BEG);
+ return tOP_ASGN;
+ }
+ SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG);
+ pushback(p, c);
+ return '^';
case ';':
- SET_LEX_STATE(EXPR_BEG);
- p->command_start = TRUE;
- return ';';
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ return ';';
case ',':
- SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
- return ',';
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ return ',';
case '~':
- if (IS_AFTER_OPERATOR()) {
- if ((c = nextc(p)) != '@') {
- pushback(p, c);
- }
- SET_LEX_STATE(EXPR_ARG);
- }
- else {
- SET_LEX_STATE(EXPR_BEG);
- }
- return '~';
+ if (IS_AFTER_OPERATOR()) {
+ if ((c = nextc(p)) != '@') {
+ pushback(p, c);
+ }
+ SET_LEX_STATE(EXPR_ARG);
+ }
+ else {
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ return '~';
case '(':
- if (IS_BEG()) {
- c = tLPAREN;
- }
- else if (!space_seen) {
- /* foo( ... ) => method call, no ambiguity */
- }
- else if (IS_ARG() || IS_lex_state_all(EXPR_END|EXPR_LABEL)) {
- c = tLPAREN_ARG;
- }
- else if (IS_lex_state(EXPR_ENDFN) && !lambda_beginning_p()) {
- rb_warning0("parentheses after method name is interpreted as "
- "an argument list, not a decomposed argument");
- }
- p->lex.paren_nest++;
- COND_PUSH(0);
- CMDARG_PUSH(0);
- SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
- return c;
+ if (IS_BEG()) {
+ c = tLPAREN;
+ }
+ else if (!space_seen) {
+ /* foo( ... ) => method call, no ambiguity */
+ }
+ else if (IS_ARG() || IS_lex_state_all(EXPR_END|EXPR_LABEL)) {
+ c = tLPAREN_ARG;
+ }
+ else if (IS_lex_state(EXPR_ENDFN) && !lambda_beginning_p()) {
+ rb_warning0("parentheses after method name is interpreted as "
+ "an argument list, not a decomposed argument");
+ }
+ p->lex.paren_nest++;
+ COND_PUSH(0);
+ CMDARG_PUSH(0);
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ return c;
case '[':
- p->lex.paren_nest++;
- if (IS_AFTER_OPERATOR()) {
- if ((c = nextc(p)) == ']') {
- p->lex.paren_nest--;
- SET_LEX_STATE(EXPR_ARG);
- if ((c = nextc(p)) == '=') {
- return tASET;
- }
- pushback(p, c);
- return tAREF;
- }
- pushback(p, c);
- SET_LEX_STATE(EXPR_ARG|EXPR_LABEL);
- return '[';
- }
- else if (IS_BEG()) {
- c = tLBRACK;
- }
- else if (IS_ARG() && (space_seen || IS_lex_state(EXPR_LABELED))) {
- c = tLBRACK;
- }
- SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
- COND_PUSH(0);
- CMDARG_PUSH(0);
- return c;
+ p->lex.paren_nest++;
+ if (IS_AFTER_OPERATOR()) {
+ if ((c = nextc(p)) == ']') {
+ p->lex.paren_nest--;
+ SET_LEX_STATE(EXPR_ARG);
+ if ((c = nextc(p)) == '=') {
+ return tASET;
+ }
+ pushback(p, c);
+ return tAREF;
+ }
+ pushback(p, c);
+ SET_LEX_STATE(EXPR_ARG|EXPR_LABEL);
+ return '[';
+ }
+ else if (IS_BEG()) {
+ c = tLBRACK;
+ }
+ else if (IS_ARG() && (space_seen || IS_lex_state(EXPR_LABELED))) {
+ c = tLBRACK;
+ }
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ COND_PUSH(0);
+ CMDARG_PUSH(0);
+ return c;
case '{':
- ++p->lex.brace_nest;
- if (lambda_beginning_p())
- c = tLAMBEG;
- else if (IS_lex_state(EXPR_LABELED))
- c = tLBRACE; /* hash */
- else if (IS_lex_state(EXPR_ARG_ANY | EXPR_END | EXPR_ENDFN))
- c = '{'; /* block (primary) */
- else if (IS_lex_state(EXPR_ENDARG))
- c = tLBRACE_ARG; /* block (expr) */
- else
- c = tLBRACE; /* hash */
- if (c != tLBRACE) {
- p->command_start = TRUE;
- SET_LEX_STATE(EXPR_BEG);
- }
- else {
- SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
- }
- ++p->lex.paren_nest; /* after lambda_beginning_p() */
- COND_PUSH(0);
- CMDARG_PUSH(0);
- return c;
+ ++p->lex.brace_nest;
+ if (lambda_beginning_p())
+ c = tLAMBEG;
+ else if (IS_lex_state(EXPR_LABELED))
+ c = tLBRACE; /* hash */
+ else if (IS_lex_state(EXPR_ARG_ANY | EXPR_END | EXPR_ENDFN))
+ c = '{'; /* block (primary) */
+ else if (IS_lex_state(EXPR_ENDARG))
+ c = tLBRACE_ARG; /* block (expr) */
+ else
+ c = tLBRACE; /* hash */
+ if (c != tLBRACE) {
+ p->command_start = TRUE;
+ SET_LEX_STATE(EXPR_BEG);
+ }
+ else {
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ }
+ ++p->lex.paren_nest; /* after lambda_beginning_p() */
+ COND_PUSH(0);
+ CMDARG_PUSH(0);
+ return c;
case '\\':
- c = nextc(p);
- if (c == '\n') {
- space_seen = 1;
- dispatch_scan_event(p, tSP);
- goto retry; /* skip \\n */
- }
- if (c == ' ') return tSP;
- if (ISSPACE(c)) return c;
- pushback(p, c);
- return '\\';
+ c = nextc(p);
+ if (c == '\n') {
+ space_seen = 1;
+ dispatch_scan_event(p, tSP);
+ goto retry; /* skip \\n */
+ }
+ if (c == ' ') return tSP;
+ if (ISSPACE(c)) return c;
+ pushback(p, c);
+ return '\\';
case '%':
- return parse_percent(p, space_seen, last_state);
+ return parse_percent(p, space_seen, last_state);
case '$':
- return parse_gvar(p, last_state);
+ return parse_gvar(p, last_state);
case '@':
- return parse_atmark(p, last_state);
+ return parse_atmark(p, last_state);
case '_':
- if (was_bol(p) && whole_match_p(p, "__END__", 7, 0)) {
- p->ruby__end__seen = 1;
- p->eofp = 1;
-#ifdef RIPPER
+ if (was_bol(p) && whole_match_p(p, "__END__", 7, 0)) {
+ p->ruby__end__seen = 1;
+ p->eofp = 1;
+#ifndef RIPPER
+ return -1;
+#else
lex_goto_eol(p);
dispatch_scan_event(p, k__END__);
+ return 0;
#endif
- return END_OF_INPUT;
- }
- newtok(p);
- break;
+ }
+ newtok(p);
+ break;
default:
- if (!parser_is_identchar(p)) {
- compile_error(p, "Invalid char `\\x%02X' in expression", c);
+ if (!parser_is_identchar(p)) {
+ compile_error(p, "Invalid char `\\x%02X' in expression", c);
token_flush(p);
- goto retry;
- }
+ goto retry;
+ }
- newtok(p);
- break;
+ newtok(p);
+ break;
}
return parse_ident(p, c, cmd_state);
@@ -11149,9 +10554,9 @@ yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p)
t = parser_yylex(p);
if (has_delayed_token(p))
- dispatch_delayed_token(p, t);
- else if (t != END_OF_INPUT)
- dispatch_scan_event(p, t);
+ dispatch_delayed_token(p, t);
+ else if (t != 0)
+ dispatch_scan_event(p, t);
return t;
}
@@ -11159,1121 +10564,30 @@ yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p)
#define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
static NODE*
-node_new_internal(struct parser_params *p, enum node_type type, size_t size, size_t alignment)
+node_new_temporal(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
- NODE *n = rb_ast_newnode(p->ast, type, size, alignment);
+ NODE *n = rb_ast_newnode(p->ast, type);
- rb_node_init(n, type);
+ rb_node_init(n, type, a0, a1, a2);
return n;
}
-static NODE *
-nd_set_loc(NODE *nd, const YYLTYPE *loc)
-{
- nd->nd_loc = *loc;
- nd_set_line(nd, loc->beg_pos.lineno);
- return nd;
-}
-
static NODE*
-node_newnode(struct parser_params *p, enum node_type type, size_t size, size_t alignment, const rb_code_location_t *loc)
+node_newnode(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2, const rb_code_location_t *loc)
{
- NODE *n = node_new_internal(p, type, size, alignment);
+ NODE *n = node_new_temporal(p, type, a0, a1, a2);
nd_set_loc(n, loc);
nd_set_node_id(n, parser_get_node_id(p));
return n;
}
-#define NODE_NEWNODE(node_type, type, loc) (type *)(node_newnode(p, node_type, sizeof(type), RUBY_ALIGNOF(type), loc))
-
-#ifndef RIPPER
-
-static rb_node_scope_t *
-rb_node_scope_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_ast_id_table_t *nd_tbl;
- nd_tbl = local_tbl(p);
- rb_node_scope_t *n = NODE_NEWNODE(NODE_SCOPE, rb_node_scope_t, loc);
- n->nd_tbl = nd_tbl;
- n->nd_body = nd_body;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_scope_t *
-rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_scope_t *n = NODE_NEWNODE(NODE_SCOPE, rb_node_scope_t, loc);
- n->nd_tbl = nd_tbl;
- n->nd_body = nd_body;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_defn_t *
-rb_node_defn_new(struct parser_params *p, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc)
-{
- rb_node_defn_t *n = NODE_NEWNODE(NODE_DEFN, rb_node_defn_t, loc);
- n->nd_mid = nd_mid;
- n->nd_defn = nd_defn;
-
- return n;
-}
-
-static rb_node_defs_t *
-rb_node_defs_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc)
-{
- rb_node_defs_t *n = NODE_NEWNODE(NODE_DEFS, rb_node_defs_t, loc);
- n->nd_recv = nd_recv;
- n->nd_mid = nd_mid;
- n->nd_defn = nd_defn;
-
- return n;
-}
-
-static rb_node_block_t *
-rb_node_block_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_block_t *n = NODE_NEWNODE(NODE_BLOCK, rb_node_block_t, loc);
- n->nd_head = nd_head;
- n->nd_end = (NODE *)n;
- n->nd_next = 0;
-
- return n;
-}
-
-static rb_node_for_t *
-rb_node_for_new(struct parser_params *p, NODE *nd_iter, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_for_t *n = NODE_NEWNODE(NODE_FOR, rb_node_for_t, loc);
- n->nd_body = nd_body;
- n->nd_iter = nd_iter;
-
- return n;
-}
-
-static rb_node_for_masgn_t *
-rb_node_for_masgn_new(struct parser_params *p, NODE *nd_var, const YYLTYPE *loc)
-{
- rb_node_for_masgn_t *n = NODE_NEWNODE(NODE_FOR_MASGN, rb_node_for_masgn_t, loc);
- n->nd_var = nd_var;
-
- return n;
-}
-
-static rb_node_retry_t *
-rb_node_retry_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_retry_t *n = NODE_NEWNODE(NODE_RETRY, rb_node_retry_t, loc);
-
- return n;
-}
-
-static rb_node_begin_t *
-rb_node_begin_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_begin_t *n = NODE_NEWNODE(NODE_BEGIN, rb_node_begin_t, loc);
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_rescue_t *
-rb_node_rescue_new(struct parser_params *p, NODE *nd_head, NODE *nd_resq, NODE *nd_else, const YYLTYPE *loc)
-{
- rb_node_rescue_t *n = NODE_NEWNODE(NODE_RESCUE, rb_node_rescue_t, loc);
- n->nd_head = nd_head;
- n->nd_resq = nd_resq;
- n->nd_else = nd_else;
-
- return n;
-}
-
-static rb_node_resbody_t *
-rb_node_resbody_new(struct parser_params *p, NODE *nd_args, NODE *nd_body, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_resbody_t *n = NODE_NEWNODE(NODE_RESBODY, rb_node_resbody_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_ensure_t *
-rb_node_ensure_new(struct parser_params *p, NODE *nd_head, NODE *nd_ensr, const YYLTYPE *loc)
-{
- rb_node_ensure_t *n = NODE_NEWNODE(NODE_ENSURE, rb_node_ensure_t, loc);
- n->nd_head = nd_head;
- n->nd_resq = 0;
- n->nd_ensr = nd_ensr;
-
- return n;
-}
-
-static rb_node_and_t *
-rb_node_and_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc)
-{
- rb_node_and_t *n = NODE_NEWNODE(NODE_AND, rb_node_and_t, loc);
- n->nd_1st = nd_1st;
- n->nd_2nd = nd_2nd;
-
- return n;
-}
-
-static rb_node_or_t *
-rb_node_or_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc)
-{
- rb_node_or_t *n = NODE_NEWNODE(NODE_OR, rb_node_or_t, loc);
- n->nd_1st = nd_1st;
- n->nd_2nd = nd_2nd;
-
- return n;
-}
-
-static rb_node_return_t *
-rb_node_return_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc)
-{
- rb_node_return_t *n = NODE_NEWNODE(NODE_RETURN, rb_node_return_t, loc);
- n->nd_stts = nd_stts;
- return n;
-}
-
-static rb_node_yield_t *
-rb_node_yield_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_yield_t *n = NODE_NEWNODE(NODE_YIELD, rb_node_yield_t, loc);
- n->nd_head = nd_head;
-
- return n;
-}
-
-static rb_node_if_t *
-rb_node_if_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, NODE *nd_else, const YYLTYPE *loc)
-{
- rb_node_if_t *n = NODE_NEWNODE(NODE_IF, rb_node_if_t, loc);
- n->nd_cond = nd_cond;
- n->nd_body = nd_body;
- n->nd_else = nd_else;
-
- return n;
-}
-
-static rb_node_unless_t *
-rb_node_unless_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, NODE *nd_else, const YYLTYPE *loc)
-{
- rb_node_unless_t *n = NODE_NEWNODE(NODE_UNLESS, rb_node_unless_t, loc);
- n->nd_cond = nd_cond;
- n->nd_body = nd_body;
- n->nd_else = nd_else;
-
- return n;
-}
-
-static rb_node_class_t *
-rb_node_class_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, NODE *nd_super, const YYLTYPE *loc)
-{
- /* Keep the order of node creation */
- NODE *scope = NEW_SCOPE(0, nd_body, loc);
- rb_node_class_t *n = NODE_NEWNODE(NODE_CLASS, rb_node_class_t, loc);
- n->nd_cpath = nd_cpath;
- n->nd_body = scope;
- n->nd_super = nd_super;
-
- return n;
-}
-
-static rb_node_sclass_t *
-rb_node_sclass_new(struct parser_params *p, NODE *nd_recv, NODE *nd_body, const YYLTYPE *loc)
-{
- /* Keep the order of node creation */
- NODE *scope = NEW_SCOPE(0, nd_body, loc);
- rb_node_sclass_t *n = NODE_NEWNODE(NODE_SCLASS, rb_node_sclass_t, loc);
- n->nd_recv = nd_recv;
- n->nd_body = scope;
-
- return n;
-}
-
-static rb_node_module_t *
-rb_node_module_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, const YYLTYPE *loc)
-{
- /* Keep the order of node creation */
- NODE *scope = NEW_SCOPE(0, nd_body, loc);
- rb_node_module_t *n = NODE_NEWNODE(NODE_MODULE, rb_node_module_t, loc);
- n->nd_cpath = nd_cpath;
- n->nd_body = scope;
-
- return n;
-}
-
-static rb_node_iter_t *
-rb_node_iter_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
-{
- /* Keep the order of node creation */
- NODE *scope = NEW_SCOPE(nd_args, nd_body, loc);
- rb_node_iter_t *n = NODE_NEWNODE(NODE_ITER, rb_node_iter_t, loc);
- n->nd_body = scope;
- n->nd_iter = 0;
-
- return n;
-}
-
-static rb_node_lambda_t *
-rb_node_lambda_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
-{
- /* Keep the order of node creation */
- NODE *scope = NEW_SCOPE(nd_args, nd_body, loc);
- rb_node_lambda_t *n = NODE_NEWNODE(NODE_LAMBDA, rb_node_lambda_t, loc);
- n->nd_body = scope;
-
- return n;
-}
-
-static rb_node_case_t *
-rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_case_t *n = NODE_NEWNODE(NODE_CASE, rb_node_case_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_case2_t *
-rb_node_case2_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_case2_t *n = NODE_NEWNODE(NODE_CASE2, rb_node_case2_t, loc);
- n->nd_head = 0;
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_case3_t *
-rb_node_case3_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_case3_t *n = NODE_NEWNODE(NODE_CASE3, rb_node_case3_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_when_t *
-rb_node_when_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_next, const YYLTYPE *loc)
-{
- rb_node_when_t *n = NODE_NEWNODE(NODE_WHEN, rb_node_when_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
- n->nd_next = nd_next;
-
- return n;
-}
-
-static rb_node_in_t *
-rb_node_in_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_next, const YYLTYPE *loc)
-{
- rb_node_in_t *n = NODE_NEWNODE(NODE_IN, rb_node_in_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
- n->nd_next = nd_next;
-
- return n;
-}
-
-static rb_node_while_t *
-rb_node_while_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc)
-{
- rb_node_while_t *n = NODE_NEWNODE(NODE_WHILE, rb_node_while_t, loc);
- n->nd_cond = nd_cond;
- n->nd_body = nd_body;
- n->nd_state = nd_state;
-
- return n;
-}
-
-static rb_node_until_t *
-rb_node_until_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc)
-{
- rb_node_until_t *n = NODE_NEWNODE(NODE_UNTIL, rb_node_until_t, loc);
- n->nd_cond = nd_cond;
- n->nd_body = nd_body;
- n->nd_state = nd_state;
-
- return n;
-}
-
-static rb_node_colon2_t *
-rb_node_colon2_new(struct parser_params *p, NODE *nd_head, ID nd_mid, const YYLTYPE *loc)
-{
- rb_node_colon2_t *n = NODE_NEWNODE(NODE_COLON2, rb_node_colon2_t, loc);
- n->nd_head = nd_head;
- n->nd_mid = nd_mid;
-
- return n;
-}
-
-static rb_node_colon3_t *
-rb_node_colon3_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc)
-{
- rb_node_colon3_t *n = NODE_NEWNODE(NODE_COLON3, rb_node_colon3_t, loc);
- n->nd_mid = nd_mid;
-
- return n;
-}
-
-static rb_node_dot2_t *
-rb_node_dot2_new(struct parser_params *p, NODE *nd_beg, NODE *nd_end, const YYLTYPE *loc)
-{
- rb_node_dot2_t *n = NODE_NEWNODE(NODE_DOT2, rb_node_dot2_t, loc);
- n->nd_beg = nd_beg;
- n->nd_end = nd_end;
-
- return n;
-}
-
-static rb_node_dot3_t *
-rb_node_dot3_new(struct parser_params *p, NODE *nd_beg, NODE *nd_end, const YYLTYPE *loc)
-{
- rb_node_dot3_t *n = NODE_NEWNODE(NODE_DOT3, rb_node_dot3_t, loc);
- n->nd_beg = nd_beg;
- n->nd_end = nd_end;
-
- return n;
-}
-
-static rb_node_self_t *
-rb_node_self_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_self_t *n = NODE_NEWNODE(NODE_SELF, rb_node_self_t, loc);
- n->nd_state = 1;
-
- return n;
-}
-
-static rb_node_nil_t *
-rb_node_nil_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_nil_t *n = NODE_NEWNODE(NODE_NIL, rb_node_nil_t, loc);
-
- return n;
-}
-
-static rb_node_true_t *
-rb_node_true_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_true_t *n = NODE_NEWNODE(NODE_TRUE, rb_node_true_t, loc);
-
- return n;
-}
-
-static rb_node_false_t *
-rb_node_false_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_false_t *n = NODE_NEWNODE(NODE_FALSE, rb_node_false_t, loc);
-
- return n;
-}
-
-static rb_node_super_t *
-rb_node_super_new(struct parser_params *p, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_super_t *n = NODE_NEWNODE(NODE_SUPER, rb_node_super_t, loc);
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_zsuper_t *
-rb_node_zsuper_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_zsuper_t *n = NODE_NEWNODE(NODE_ZSUPER, rb_node_zsuper_t, loc);
-
- return n;
-}
-
-static rb_node_match2_t *
-rb_node_match2_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_match2_t *n = NODE_NEWNODE(NODE_MATCH2, rb_node_match2_t, loc);
- n->nd_recv = nd_recv;
- n->nd_value = nd_value;
- n->nd_args = 0;
-
- return n;
-}
-
-static rb_node_match3_t *
-rb_node_match3_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_match3_t *n = NODE_NEWNODE(NODE_MATCH3, rb_node_match3_t, loc);
- n->nd_recv = nd_recv;
- n->nd_value = nd_value;
-
- return n;
-}
-
-/* TODO: Use union for NODE_LIST2 */
-static rb_node_list_t *
-rb_node_list_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_list_t *n = NODE_NEWNODE(NODE_LIST, rb_node_list_t, loc);
- n->nd_head = nd_head;
- n->as.nd_alen = 1;
- n->nd_next = 0;
-
- return n;
-}
-
-static rb_node_list_t *
-rb_node_list_new2(struct parser_params *p, NODE *nd_head, long nd_alen, NODE *nd_next, const YYLTYPE *loc)
-{
- rb_node_list_t *n = NODE_NEWNODE(NODE_LIST, rb_node_list_t, loc);
- n->nd_head = nd_head;
- n->as.nd_alen = nd_alen;
- n->nd_next = nd_next;
-
- return n;
-}
-
-static rb_node_zlist_t *
-rb_node_zlist_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_zlist_t *n = NODE_NEWNODE(NODE_ZLIST, rb_node_zlist_t, loc);
-
- return n;
-}
-
-static rb_node_hash_t *
-rb_node_hash_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_hash_t *n = NODE_NEWNODE(NODE_HASH, rb_node_hash_t, loc);
- n->nd_head = nd_head;
- n->nd_brace = 0;
-
- return n;
-}
-
-static rb_node_masgn_t *
-rb_node_masgn_new(struct parser_params *p, NODE *nd_head, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_masgn_t *n = NODE_NEWNODE(NODE_MASGN, rb_node_masgn_t, loc);
- n->nd_head = nd_head;
- n->nd_value = 0;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_gasgn_t *
-rb_node_gasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_gasgn_t *n = NODE_NEWNODE(NODE_GASGN, rb_node_gasgn_t, loc);
- n->nd_vid = nd_vid;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_lasgn_t *
-rb_node_lasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_lasgn_t *n = NODE_NEWNODE(NODE_LASGN, rb_node_lasgn_t, loc);
- n->nd_vid = nd_vid;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_dasgn_t *
-rb_node_dasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_dasgn_t *n = NODE_NEWNODE(NODE_DASGN, rb_node_dasgn_t, loc);
- n->nd_vid = nd_vid;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_iasgn_t *
-rb_node_iasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_iasgn_t *n = NODE_NEWNODE(NODE_IASGN, rb_node_iasgn_t, loc);
- n->nd_vid = nd_vid;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_cvasgn_t *
-rb_node_cvasgn_new(struct parser_params *p, ID nd_vid, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_cvasgn_t *n = NODE_NEWNODE(NODE_CVASGN, rb_node_cvasgn_t, loc);
- n->nd_vid = nd_vid;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_op_asgn1_t *
-rb_node_op_asgn1_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *index, NODE *rvalue, const YYLTYPE *loc)
-{
- rb_node_op_asgn1_t *n = NODE_NEWNODE(NODE_OP_ASGN1, rb_node_op_asgn1_t, loc);
- n->nd_recv = nd_recv;
- n->nd_mid = nd_mid;
- n->nd_index = index;
- n->nd_rvalue = rvalue;
-
- return n;
-}
-
-static rb_node_op_asgn2_t *
-rb_node_op_asgn2_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, ID nd_vid, ID nd_mid, bool nd_aid, const YYLTYPE *loc)
-{
- rb_node_op_asgn2_t *n = NODE_NEWNODE(NODE_OP_ASGN2, rb_node_op_asgn2_t, loc);
- n->nd_recv = nd_recv;
- n->nd_value = nd_value;
- n->nd_vid = nd_vid;
- n->nd_mid = nd_mid;
- n->nd_aid = nd_aid;
-
- return n;
-}
-
-static rb_node_op_asgn_or_t *
-rb_node_op_asgn_or_new(struct parser_params *p, NODE *nd_head, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_op_asgn_or_t *n = NODE_NEWNODE(NODE_OP_ASGN_OR, rb_node_op_asgn_or_t, loc);
- n->nd_head = nd_head;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_op_asgn_and_t *
-rb_node_op_asgn_and_new(struct parser_params *p, NODE *nd_head, NODE *nd_value, const YYLTYPE *loc)
-{
- rb_node_op_asgn_and_t *n = NODE_NEWNODE(NODE_OP_ASGN_AND, rb_node_op_asgn_and_t, loc);
- n->nd_head = nd_head;
- n->nd_value = nd_value;
-
- return n;
-}
-
-static rb_node_gvar_t *
-rb_node_gvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc)
-{
- rb_node_gvar_t *n = NODE_NEWNODE(NODE_GVAR, rb_node_gvar_t, loc);
- n->nd_vid = nd_vid;
-
- return n;
-}
-
-static rb_node_lvar_t *
-rb_node_lvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc)
-{
- rb_node_lvar_t *n = NODE_NEWNODE(NODE_LVAR, rb_node_lvar_t, loc);
- n->nd_vid = nd_vid;
-
- return n;
-}
-
-static rb_node_dvar_t *
-rb_node_dvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc)
-{
- rb_node_dvar_t *n = NODE_NEWNODE(NODE_DVAR, rb_node_dvar_t, loc);
- n->nd_vid = nd_vid;
-
- return n;
-}
-
-static rb_node_ivar_t *
-rb_node_ivar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc)
-{
- rb_node_ivar_t *n = NODE_NEWNODE(NODE_IVAR, rb_node_ivar_t, loc);
- n->nd_vid = nd_vid;
-
- return n;
-}
-
-static rb_node_const_t *
-rb_node_const_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc)
-{
- rb_node_const_t *n = NODE_NEWNODE(NODE_CONST, rb_node_const_t, loc);
- n->nd_vid = nd_vid;
-
- return n;
-}
-
-static rb_node_cvar_t *
-rb_node_cvar_new(struct parser_params *p, ID nd_vid, const YYLTYPE *loc)
-{
- rb_node_cvar_t *n = NODE_NEWNODE(NODE_CVAR, rb_node_cvar_t, loc);
- n->nd_vid = nd_vid;
-
- return n;
-}
-
-static rb_node_nth_ref_t *
-rb_node_nth_ref_new(struct parser_params *p, long nd_nth, const YYLTYPE *loc)
-{
- rb_node_nth_ref_t *n = NODE_NEWNODE(NODE_NTH_REF, rb_node_nth_ref_t, loc);
- n->nd_nth = nd_nth;
-
- return n;
-}
-
-static rb_node_back_ref_t *
-rb_node_back_ref_new(struct parser_params *p, long nd_nth, const YYLTYPE *loc)
-{
- rb_node_back_ref_t *n = NODE_NEWNODE(NODE_BACK_REF, rb_node_back_ref_t, loc);
- n->nd_nth = nd_nth;
-
- return n;
-}
-
-static rb_node_lit_t *
-rb_node_lit_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc)
-{
- rb_node_lit_t *n = NODE_NEWNODE(NODE_LIT, rb_node_lit_t, loc);
- n->nd_lit = nd_lit;
-
- return n;
-}
-
-static rb_node_str_t *
-rb_node_str_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc)
-{
- rb_node_str_t *n = NODE_NEWNODE(NODE_STR, rb_node_str_t, loc);
- n->nd_lit = nd_lit;
-
- return n;
-}
-
-/* TODO; Use union for NODE_DSTR2 */
-static rb_node_dstr_t *
-rb_node_dstr_new0(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc)
-{
- rb_node_dstr_t *n = NODE_NEWNODE(NODE_DSTR, rb_node_dstr_t, loc);
- n->nd_lit = nd_lit;
- n->as.nd_alen = nd_alen;
- n->nd_next = (rb_node_list_t *)nd_next;
-
- return n;
-}
-
-static rb_node_dstr_t *
-rb_node_dstr_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc)
-{
- return rb_node_dstr_new0(p, nd_lit, 1, 0, loc);
-}
-
-static rb_node_xstr_t *
-rb_node_xstr_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc)
-{
- rb_node_xstr_t *n = NODE_NEWNODE(NODE_XSTR, rb_node_xstr_t, loc);
- n->nd_lit = nd_lit;
-
- return n;
-}
-
-static rb_node_dxstr_t *
-rb_node_dxstr_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc)
-{
- rb_node_dxstr_t *n = NODE_NEWNODE(NODE_DXSTR, rb_node_dxstr_t, loc);
- n->nd_lit = nd_lit;
- n->nd_alen = nd_alen;
- n->nd_next = (rb_node_list_t *)nd_next;
-
- return n;
-}
-
-static rb_node_dsym_t *
-rb_node_dsym_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc)
-{
- rb_node_dsym_t *n = NODE_NEWNODE(NODE_DSYM, rb_node_dsym_t, loc);
- n->nd_lit = nd_lit;
- n->nd_alen = nd_alen;
- n->nd_next = (rb_node_list_t *)nd_next;
-
- return n;
-}
-
-static rb_node_evstr_t *
-rb_node_evstr_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_evstr_t *n = NODE_NEWNODE(NODE_EVSTR, rb_node_evstr_t, loc);
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_call_t *
-rb_node_call_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_call_t *n = NODE_NEWNODE(NODE_CALL, rb_node_call_t, loc);
- n->nd_recv = nd_recv;
- n->nd_mid = nd_mid;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_opcall_t *
-rb_node_opcall_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_opcall_t *n = NODE_NEWNODE(NODE_OPCALL, rb_node_opcall_t, loc);
- n->nd_recv = nd_recv;
- n->nd_mid = nd_mid;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_fcall_t *
-rb_node_fcall_new(struct parser_params *p, ID nd_mid, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_fcall_t *n = NODE_NEWNODE(NODE_FCALL, rb_node_fcall_t, loc);
- n->nd_mid = nd_mid;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_qcall_t *
-rb_node_qcall_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_qcall_t *n = NODE_NEWNODE(NODE_QCALL, rb_node_qcall_t, loc);
- n->nd_recv = nd_recv;
- n->nd_mid = nd_mid;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_vcall_t *
-rb_node_vcall_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc)
-{
- rb_node_vcall_t *n = NODE_NEWNODE(NODE_VCALL, rb_node_vcall_t, loc);
- n->nd_mid = nd_mid;
-
- return n;
-}
-
-static rb_node_once_t *
-rb_node_once_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_once_t *n = NODE_NEWNODE(NODE_ONCE, rb_node_once_t, loc);
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_args_t *
-rb_node_args_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_args_t *n = NODE_NEWNODE(NODE_ARGS, rb_node_args_t, loc);
- MEMZERO(&n->nd_ainfo, struct rb_args_info, 1);
-
- return n;
-}
-
-static rb_node_args_aux_t *
-rb_node_args_aux_new(struct parser_params *p, ID nd_pid, long nd_plen, const YYLTYPE *loc)
-{
- rb_node_args_aux_t *n = NODE_NEWNODE(NODE_ARGS_AUX, rb_node_args_aux_t, loc);
- n->nd_pid = nd_pid;
- n->nd_plen = nd_plen;
- n->nd_next = 0;
-
- return n;
-}
-
-static rb_node_opt_arg_t *
-rb_node_opt_arg_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_opt_arg_t *n = NODE_NEWNODE(NODE_OPT_ARG, rb_node_opt_arg_t, loc);
- n->nd_body = nd_body;
- n->nd_next = 0;
-
- return n;
-}
-
-static rb_node_kw_arg_t *
-rb_node_kw_arg_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_kw_arg_t *n = NODE_NEWNODE(NODE_KW_ARG, rb_node_kw_arg_t, loc);
- n->nd_body = nd_body;
- n->nd_next = 0;
-
- return n;
-}
-
-static rb_node_postarg_t *
-rb_node_postarg_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc)
-{
- rb_node_postarg_t *n = NODE_NEWNODE(NODE_POSTARG, rb_node_postarg_t, loc);
- n->nd_1st = nd_1st;
- n->nd_2nd = nd_2nd;
-
- return n;
-}
-
-static rb_node_argscat_t *
-rb_node_argscat_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_argscat_t *n = NODE_NEWNODE(NODE_ARGSCAT, rb_node_argscat_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_argspush_t *
-rb_node_argspush_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_argspush_t *n = NODE_NEWNODE(NODE_ARGSPUSH, rb_node_argspush_t, loc);
- n->nd_head = nd_head;
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_splat_t *
-rb_node_splat_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_splat_t *n = NODE_NEWNODE(NODE_SPLAT, rb_node_splat_t, loc);
- n->nd_head = nd_head;
-
- return n;
-}
-
-static rb_node_block_pass_t *
-rb_node_block_pass_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_block_pass_t *n = NODE_NEWNODE(NODE_BLOCK_PASS, rb_node_block_pass_t, loc);
- n->nd_head = 0;
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_alias_t *
-rb_node_alias_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc)
-{
- rb_node_alias_t *n = NODE_NEWNODE(NODE_ALIAS, rb_node_alias_t, loc);
- n->nd_1st = nd_1st;
- n->nd_2nd = nd_2nd;
-
- return n;
-}
-
-static rb_node_valias_t *
-rb_node_valias_new(struct parser_params *p, ID nd_alias, ID nd_orig, const YYLTYPE *loc)
-{
- rb_node_valias_t *n = NODE_NEWNODE(NODE_VALIAS, rb_node_valias_t, loc);
- n->nd_alias = nd_alias;
- n->nd_orig = nd_orig;
-
- return n;
-}
-
-static rb_node_undef_t *
-rb_node_undef_new(struct parser_params *p, NODE *nd_undef, const YYLTYPE *loc)
-{
- rb_node_undef_t *n = NODE_NEWNODE(NODE_UNDEF, rb_node_undef_t, loc);
- n->nd_undef = nd_undef;
-
- return n;
-}
-
-static rb_node_errinfo_t *
-rb_node_errinfo_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_errinfo_t *n = NODE_NEWNODE(NODE_ERRINFO, rb_node_errinfo_t, loc);
-
- return n;
-}
-
-static rb_node_defined_t *
-rb_node_defined_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc)
-{
- rb_node_defined_t *n = NODE_NEWNODE(NODE_DEFINED, rb_node_defined_t, loc);
- n->nd_head = nd_head;
-
- return n;
-}
-
-static rb_node_postexe_t *
-rb_node_postexe_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc)
-{
- rb_node_postexe_t *n = NODE_NEWNODE(NODE_POSTEXE, rb_node_postexe_t, loc);
- n->nd_body = nd_body;
-
- return n;
-}
-
-static rb_node_attrasgn_t *
-rb_node_attrasgn_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc)
-{
- rb_node_attrasgn_t *n = NODE_NEWNODE(NODE_ATTRASGN, rb_node_attrasgn_t, loc);
- n->nd_recv = nd_recv;
- n->nd_mid = nd_mid;
- n->nd_args = nd_args;
-
- return n;
-}
-
-static rb_node_aryptn_t *
-rb_node_aryptn_new(struct parser_params *p, NODE *pre_args, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc)
-{
- rb_node_aryptn_t *n = NODE_NEWNODE(NODE_ARYPTN, rb_node_aryptn_t, loc);
- n->nd_pconst = 0;
- n->pre_args = pre_args;
- n->rest_arg = rest_arg;
- n->post_args = post_args;
-
- return n;
-}
-
-static rb_node_hshptn_t *
-rb_node_hshptn_new(struct parser_params *p, NODE *nd_pconst, NODE *nd_pkwargs, NODE *nd_pkwrestarg, const YYLTYPE *loc)
-{
- rb_node_hshptn_t *n = NODE_NEWNODE(NODE_HSHPTN, rb_node_hshptn_t, loc);
- n->nd_pconst = nd_pconst;
- n->nd_pkwargs = nd_pkwargs;
- n->nd_pkwrestarg = nd_pkwrestarg;
-
- return n;
-}
-
-static rb_node_fndptn_t *
-rb_node_fndptn_new(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc)
-{
- rb_node_fndptn_t *n = NODE_NEWNODE(NODE_FNDPTN, rb_node_fndptn_t, loc);
- n->nd_pconst = 0;
- n->pre_rest_arg = pre_rest_arg;
- n->args = args;
- n->post_rest_arg = post_rest_arg;
-
- return n;
-}
-
-static rb_node_cdecl_t *
-rb_node_cdecl_new(struct parser_params *p, ID nd_vid, NODE *nd_value, NODE *nd_else, const YYLTYPE *loc)
-{
- rb_node_cdecl_t *n = NODE_NEWNODE(NODE_CDECL, rb_node_cdecl_t, loc);
- n->nd_vid = nd_vid;
- n->nd_value = nd_value;
- n->nd_else = nd_else;
-
- return n;
-}
-
-static rb_node_op_cdecl_t *
-rb_node_op_cdecl_new(struct parser_params *p, NODE *nd_head, NODE *nd_value, ID nd_aid, const YYLTYPE *loc)
-{
- rb_node_op_cdecl_t *n = NODE_NEWNODE(NODE_OP_CDECL, rb_node_op_cdecl_t, loc);
- n->nd_head = nd_head;
- n->nd_value = nd_value;
- n->nd_aid = nd_aid;
-
- return n;
-}
-
-static rb_node_error_t *
-rb_node_error_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_error_t *n = NODE_NEWNODE(NODE_ERROR, rb_node_error_t, loc);
-
- return n;
-}
-
-#else
-
-static rb_node_ripper_t *
-rb_node_ripper_new(struct parser_params *p, ID nd_vid, VALUE nd_rval, VALUE nd_cval, const YYLTYPE *loc)
-{
- rb_node_ripper_t *n = NODE_NEWNODE(NODE_RIPPER, rb_node_ripper_t, loc);
- n->nd_vid = nd_vid;
- n->nd_rval = nd_rval;
- n->nd_cval = nd_cval;
-
- return n;
-}
-
-static rb_node_ripper_values_t *
-rb_node_ripper_values_new(struct parser_params *p, VALUE nd_val1, VALUE nd_val2, VALUE nd_val3, const YYLTYPE *loc)
-{
- rb_node_ripper_values_t *n = NODE_NEWNODE(NODE_RIPPER_VALUES, rb_node_ripper_values_t, loc);
- n->nd_val1 = nd_val1;
- n->nd_val2 = nd_val2;
- n->nd_val3 = nd_val3;
-
- return n;
-}
-
-#endif
-
-static rb_node_break_t *
-rb_node_break_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc)
-{
- rb_node_break_t *n = NODE_NEWNODE(NODE_BREAK, rb_node_break_t, loc);
- n->nd_stts = nd_stts;
- n->nd_chain = 0;
-
- return n;
-}
-
-static rb_node_next_t *
-rb_node_next_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc)
-{
- rb_node_next_t *n = NODE_NEWNODE(NODE_NEXT, rb_node_next_t, loc);
- n->nd_stts = nd_stts;
- n->nd_chain = 0;
-
- return n;
-}
-
-static rb_node_redo_t *
-rb_node_redo_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_redo_t *n = NODE_NEWNODE(NODE_REDO, rb_node_redo_t, loc);
- n->nd_chain = 0;
-
- return n;
-}
-
-static rb_node_def_temp_t *
-rb_node_def_temp_new(struct parser_params *p, const YYLTYPE *loc)
-{
- rb_node_def_temp_t *n = NODE_NEWNODE((enum node_type)NODE_DEF_TEMP, rb_node_def_temp_t, loc);
- n->save.cur_arg = p->cur_arg;
- n->save.numparam_save = 0;
- n->save.max_numparam = 0;
- n->save.ctxt = p->ctxt;
-#ifdef RIPPER
- n->nd_recv = Qnil;
- n->nd_mid = Qnil;
- n->dot_or_colon = Qnil;
-#else
- n->nd_def = 0;
- n->nd_mid = 0;
-#endif
-
- return n;
-}
-
-static rb_node_def_temp_t *
-def_head_save(struct parser_params *p, rb_node_def_temp_t *n)
+static NODE *
+nd_set_loc(NODE *nd, const YYLTYPE *loc)
{
- n->save.numparam_save = numparam_push(p);
- n->save.max_numparam = p->max_numparam;
- return n;
+ nd->nd_loc = *loc;
+ nd_set_line(nd, loc->beg_pos.lineno);
+ return nd;
}
#ifndef RIPPER
@@ -12293,8 +10607,8 @@ static NODE*
newline_node(NODE *node)
{
if (node) {
- node = remove_begin(node);
- nd_set_fl_newline(node);
+ node = remove_begin(node);
+ node->flags |= NODE_FL_NEWLINE;
}
return node;
}
@@ -12328,36 +10642,46 @@ block_append(struct parser_params *p, NODE *head, NODE *tail)
if (h == 0) return tail;
switch (nd_type(h)) {
+ case NODE_LIT:
+ case NODE_STR:
+ case NODE_SELF:
+ case NODE_TRUE:
+ case NODE_FALSE:
+ case NODE_NIL:
+ parser_warning(p, h, "unused literal ignored");
+ return tail;
default:
- h = end = NEW_BLOCK(head, &head->nd_loc);
- head = end;
- break;
+ h = end = NEW_BLOCK(head, &head->nd_loc);
+ end->nd_end = end;
+ head = end;
+ break;
case NODE_BLOCK:
- end = RNODE_BLOCK(h)->nd_end;
- break;
+ end = h->nd_end;
+ break;
}
- nd = RNODE_BLOCK(end)->nd_head;
+ nd = end->nd_head;
switch (nd_type(nd)) {
case NODE_RETURN:
case NODE_BREAK:
case NODE_NEXT:
case NODE_REDO:
case NODE_RETRY:
- if (RTEST(ruby_verbose)) {
- parser_warning(p, tail, "statement not reached");
- }
- break;
+ if (RTEST(ruby_verbose)) {
+ parser_warning(p, tail, "statement not reached");
+ }
+ break;
default:
- break;
+ break;
}
if (!nd_type_p(tail, NODE_BLOCK)) {
- tail = NEW_BLOCK(tail, &tail->nd_loc);
+ tail = NEW_BLOCK(tail, &tail->nd_loc);
+ tail->nd_end = tail;
}
- RNODE_BLOCK(end)->nd_next = tail;
- RNODE_BLOCK(h)->nd_end = RNODE_BLOCK(tail)->nd_end;
+ end->nd_next = tail;
+ h->nd_end = tail->nd_end;
nd_set_last_loc(head, nd_last_loc(tail));
return head;
}
@@ -12369,16 +10693,16 @@ list_append(struct parser_params *p, NODE *list, NODE *item)
NODE *last;
if (list == 0) return NEW_LIST(item, &item->nd_loc);
- if (RNODE_LIST(list)->nd_next) {
- last = RNODE_LIST(RNODE_LIST(list)->nd_next)->as.nd_end;
+ if (list->nd_next) {
+ last = list->nd_next->nd_end;
}
else {
- last = list;
+ last = list;
}
- RNODE_LIST(list)->as.nd_alen += 1;
- RNODE_LIST(last)->nd_next = NEW_LIST(item, &item->nd_loc);
- RNODE_LIST(RNODE_LIST(list)->nd_next)->as.nd_end = RNODE_LIST(last)->nd_next;
+ list->nd_alen += 1;
+ last->nd_next = NEW_LIST(item, &item->nd_loc);
+ list->nd_next->nd_end = last->nd_next;
nd_set_last_loc(list, nd_last_loc(item));
@@ -12391,20 +10715,20 @@ list_concat(NODE *head, NODE *tail)
{
NODE *last;
- if (RNODE_LIST(head)->nd_next) {
- last = RNODE_LIST(RNODE_LIST(head)->nd_next)->as.nd_end;
+ if (head->nd_next) {
+ last = head->nd_next->nd_end;
}
else {
- last = head;
+ last = head;
}
- RNODE_LIST(head)->as.nd_alen += RNODE_LIST(tail)->as.nd_alen;
- RNODE_LIST(last)->nd_next = tail;
- if (RNODE_LIST(tail)->nd_next) {
- RNODE_LIST(RNODE_LIST(head)->nd_next)->as.nd_end = RNODE_LIST(RNODE_LIST(tail)->nd_next)->as.nd_end;
+ head->nd_alen += tail->nd_alen;
+ last->nd_next = tail;
+ if (tail->nd_next) {
+ head->nd_next->nd_end = tail->nd_next->nd_end;
}
else {
- RNODE_LIST(RNODE_LIST(head)->nd_next)->as.nd_end = tail;
+ head->nd_next->nd_end = tail;
}
nd_set_last_loc(head, nd_last_loc(tail));
@@ -12417,26 +10741,26 @@ literal_concat0(struct parser_params *p, VALUE head, VALUE tail)
{
if (NIL_P(tail)) return 1;
if (!rb_enc_compatible(head, tail)) {
- compile_error(p, "string literal encodings differ (%s / %s)",
- rb_enc_name(rb_enc_get(head)),
- rb_enc_name(rb_enc_get(tail)));
- rb_str_resize(head, 0);
- rb_str_resize(tail, 0);
- return 0;
+ compile_error(p, "string literal encodings differ (%s / %s)",
+ rb_enc_name(rb_enc_get(head)),
+ rb_enc_name(rb_enc_get(tail)));
+ rb_str_resize(head, 0);
+ rb_str_resize(tail, 0);
+ return 0;
}
rb_str_buf_append(head, tail);
return 1;
}
static VALUE
-string_literal_head(struct parser_params *p, enum node_type htype, NODE *head)
+string_literal_head(enum node_type htype, NODE *head)
{
if (htype != NODE_DSTR) return Qfalse;
- if (RNODE_DSTR(head)->nd_next) {
- head = RNODE_LIST(RNODE_LIST(RNODE_DSTR(head)->nd_next)->as.nd_end)->nd_head;
- if (!head || !nd_type_p(head, NODE_STR)) return Qfalse;
+ if (head->nd_next) {
+ head = head->nd_next->nd_end->nd_head;
+ if (!head || !nd_type_p(head, NODE_STR)) return Qfalse;
}
- const VALUE lit = RNODE_DSTR(head)->nd_lit;
+ const VALUE lit = head->nd_lit;
ASSUME(lit != Qfalse);
return lit;
}
@@ -12453,110 +10777,88 @@ literal_concat(struct parser_params *p, NODE *head, NODE *tail, const YYLTYPE *l
htype = nd_type(head);
if (htype == NODE_EVSTR) {
- head = new_dstr(p, head, loc);
- htype = NODE_DSTR;
+ head = new_dstr(p, head, loc);
+ htype = NODE_DSTR;
}
if (p->heredoc_indent > 0) {
- switch (htype) {
- case NODE_STR:
- head = str2dstr(p, head);
- case NODE_DSTR:
- return list_append(p, head, tail);
- default:
- break;
- }
+ switch (htype) {
+ case NODE_STR:
+ nd_set_type(head, NODE_DSTR);
+ case NODE_DSTR:
+ return list_append(p, head, tail);
+ default:
+ break;
+ }
}
switch (nd_type(tail)) {
case NODE_STR:
- if ((lit = string_literal_head(p, htype, head)) != Qfalse) {
- htype = NODE_STR;
- }
- else {
- lit = RNODE_DSTR(head)->nd_lit;
- }
- if (htype == NODE_STR) {
- if (!literal_concat0(p, lit, RNODE_STR(tail)->nd_lit)) {
- error:
- rb_discard_node(p, head);
- rb_discard_node(p, tail);
- return 0;
- }
- rb_discard_node(p, tail);
- }
- else {
- list_append(p, head, tail);
- }
- break;
+ if ((lit = string_literal_head(htype, head)) != Qfalse) {
+ htype = NODE_STR;
+ }
+ else {
+ lit = head->nd_lit;
+ }
+ if (htype == NODE_STR) {
+ if (!literal_concat0(p, lit, tail->nd_lit)) {
+ error:
+ rb_discard_node(p, head);
+ rb_discard_node(p, tail);
+ return 0;
+ }
+ rb_discard_node(p, tail);
+ }
+ else {
+ list_append(p, head, tail);
+ }
+ break;
case NODE_DSTR:
- if (htype == NODE_STR) {
- if (!literal_concat0(p, RNODE_STR(head)->nd_lit, RNODE_DSTR(tail)->nd_lit))
- goto error;
- RNODE_DSTR(tail)->nd_lit = RNODE_STR(head)->nd_lit;
- rb_discard_node(p, head);
- head = tail;
- }
- else if (NIL_P(RNODE_DSTR(tail)->nd_lit)) {
- append:
- RNODE_DSTR(head)->as.nd_alen += RNODE_DSTR(tail)->as.nd_alen - 1;
- if (!RNODE_DSTR(head)->nd_next) {
- RNODE_DSTR(head)->nd_next = RNODE_DSTR(tail)->nd_next;
- }
- else if (RNODE_DSTR(tail)->nd_next) {
- RNODE_DSTR(RNODE_DSTR(RNODE_DSTR(head)->nd_next)->as.nd_end)->nd_next = RNODE_DSTR(tail)->nd_next;
- RNODE_DSTR(RNODE_DSTR(head)->nd_next)->as.nd_end = RNODE_DSTR(RNODE_DSTR(tail)->nd_next)->as.nd_end;
- }
- rb_discard_node(p, tail);
- }
- else if ((lit = string_literal_head(p, htype, head)) != Qfalse) {
- if (!literal_concat0(p, lit, RNODE_DSTR(tail)->nd_lit))
- goto error;
- RNODE_DSTR(tail)->nd_lit = Qnil;
- goto append;
- }
- else {
- list_concat(head, NEW_LIST2(NEW_STR(RNODE_DSTR(tail)->nd_lit, loc), RNODE_DSTR(tail)->as.nd_alen, (NODE *)RNODE_DSTR(tail)->nd_next, loc));
- }
- break;
+ if (htype == NODE_STR) {
+ if (!literal_concat0(p, head->nd_lit, tail->nd_lit))
+ goto error;
+ tail->nd_lit = head->nd_lit;
+ rb_discard_node(p, head);
+ head = tail;
+ }
+ else if (NIL_P(tail->nd_lit)) {
+ append:
+ head->nd_alen += tail->nd_alen - 1;
+ if (!head->nd_next) {
+ head->nd_next = tail->nd_next;
+ }
+ else if (tail->nd_next) {
+ head->nd_next->nd_end->nd_next = tail->nd_next;
+ head->nd_next->nd_end = tail->nd_next->nd_end;
+ }
+ rb_discard_node(p, tail);
+ }
+ else if ((lit = string_literal_head(htype, head)) != Qfalse) {
+ if (!literal_concat0(p, lit, tail->nd_lit))
+ goto error;
+ tail->nd_lit = Qnil;
+ goto append;
+ }
+ else {
+ list_concat(head, NEW_NODE(NODE_LIST, NEW_STR(tail->nd_lit, loc), tail->nd_alen, tail->nd_next, loc));
+ }
+ break;
case NODE_EVSTR:
- if (htype == NODE_STR) {
- head = str2dstr(p, head);
- RNODE_DSTR(head)->as.nd_alen = 1;
- }
- list_append(p, head, tail);
- break;
+ if (htype == NODE_STR) {
+ nd_set_type(head, NODE_DSTR);
+ head->nd_alen = 1;
+ }
+ list_append(p, head, tail);
+ break;
}
return head;
}
-static void
-nd_copy_flag(NODE *new_node, NODE *old_node)
-{
- if (nd_fl_newline(old_node)) nd_set_fl_newline(new_node);
- nd_set_line(new_node, nd_line(old_node));
- new_node->nd_loc = old_node->nd_loc;
- new_node->node_id = old_node->node_id;
-}
-
-static NODE *
-str2dstr(struct parser_params *p, NODE *node)
-{
- NODE *new_node = (NODE *)NODE_NEW_INTERNAL(NODE_DSTR, rb_node_dstr_t);
- nd_copy_flag(new_node, node);
- RNODE_DSTR(new_node)->nd_lit = RNODE_STR(node)->nd_lit;
- RNODE_DSTR(new_node)->as.nd_alen = 0;
- RNODE_DSTR(new_node)->nd_next = 0;
- RNODE_STR(node)->nd_lit = 0;
-
- return new_node;
-}
-
static NODE *
evstr2dstr(struct parser_params *p, NODE *node)
{
if (nd_type_p(node, NODE_EVSTR)) {
- node = new_dstr(p, node, &node->nd_loc);
+ node = new_dstr(p, node, &node->nd_loc);
}
return node;
}
@@ -12567,14 +10869,15 @@ new_evstr(struct parser_params *p, NODE *node, const YYLTYPE *loc)
NODE *head = node;
if (node) {
- switch (nd_type(node)) {
- case NODE_STR:
- return str2dstr(p, node);
+ switch (nd_type(node)) {
+ case NODE_STR:
+ nd_set_type(node, NODE_DSTR);
+ return node;
case NODE_DSTR:
break;
case NODE_EVSTR:
- return node;
- }
+ return node;
+ }
}
return NEW_EVSTR(head, loc);
}
@@ -12590,7 +10893,7 @@ new_dstr(struct parser_params *p, NODE *node, const YYLTYPE *loc)
static NODE *
call_bin_op(struct parser_params *p, NODE *recv, ID id, NODE *arg1,
- const YYLTYPE *op_loc, const YYLTYPE *loc)
+ const YYLTYPE *op_loc, const YYLTYPE *loc)
{
NODE *expr;
value_expr(recv);
@@ -12629,15 +10932,7 @@ new_command_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *a
return ret;
}
-#define nd_once_body(node) (nd_type_p((node), NODE_ONCE) ? RNODE_ONCE(node)->nd_body : node)
-
-static NODE*
-last_expr_once_body(NODE *node)
-{
- if (!node) return 0;
- return nd_once_body(node);
-}
-
+#define nd_once_body(node) (nd_type_p((node), NODE_ONCE) ? (node)->nd_body : node)
static NODE*
match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_loc, const YYLTYPE *loc)
{
@@ -12646,38 +10941,37 @@ match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_lo
value_expr(node1);
value_expr(node2);
-
- if ((n = last_expr_once_body(node1)) != 0) {
- switch (nd_type(n)) {
- case NODE_DREGX:
- {
- NODE *match = NEW_MATCH2(node1, node2, loc);
- nd_set_line(match, line);
- return match;
- }
-
- case NODE_LIT:
- if (RB_TYPE_P(RNODE_LIT(n)->nd_lit, T_REGEXP)) {
- const VALUE lit = RNODE_LIT(n)->nd_lit;
- NODE *match = NEW_MATCH2(node1, node2, loc);
- RNODE_MATCH2(match)->nd_args = reg_named_capture_assign(p, lit, loc);
- nd_set_line(match, line);
- return match;
- }
- }
- }
-
- if ((n = last_expr_once_body(node2)) != 0) {
+ if (node1 && (n = nd_once_body(node1)) != 0) {
+ switch (nd_type(n)) {
+ case NODE_DREGX:
+ {
+ NODE *match = NEW_MATCH2(node1, node2, loc);
+ nd_set_line(match, line);
+ return match;
+ }
+
+ case NODE_LIT:
+ if (RB_TYPE_P(n->nd_lit, T_REGEXP)) {
+ const VALUE lit = n->nd_lit;
+ NODE *match = NEW_MATCH2(node1, node2, loc);
+ match->nd_args = reg_named_capture_assign(p, lit, loc);
+ nd_set_line(match, line);
+ return match;
+ }
+ }
+ }
+
+ if (node2 && (n = nd_once_body(node2)) != 0) {
NODE *match3;
- switch (nd_type(n)) {
- case NODE_LIT:
- if (!RB_TYPE_P(RNODE_LIT(n)->nd_lit, T_REGEXP)) break;
- /* fallthru */
- case NODE_DREGX:
- match3 = NEW_MATCH3(node2, node1, loc);
- return match3;
- }
+ switch (nd_type(n)) {
+ case NODE_LIT:
+ if (!RB_TYPE_P(n->nd_lit, T_REGEXP)) break;
+ /* fallthru */
+ case NODE_DREGX:
+ match3 = NEW_MATCH3(node2, node1, loc);
+ return match3;
+ }
}
n = NEW_CALL(node1, tMATCH, NEW_LIST(node2, &node2->nd_loc), loc);
@@ -12691,8 +10985,8 @@ past_dvar_p(struct parser_params *p, ID id)
{
struct vtable *past = p->lvtbl->past;
while (past) {
- if (vtable_included(past, id)) return 1;
- past = past->prev;
+ if (vtable_included(past, id)) return 1;
+ past = past->prev;
}
return 0;
}
@@ -12705,13 +10999,13 @@ numparam_nested_p(struct parser_params *p)
NODE *outer = local->numparam.outer;
NODE *inner = local->numparam.inner;
if (outer || inner) {
- NODE *used = outer ? outer : inner;
- compile_error(p, "numbered parameter is already used in\n"
- "%s:%d: %s block here",
- p->ruby_sourcefile, nd_line(used),
- outer ? "outer" : "inner");
- parser_show_error_line(p, &used->nd_loc);
- return 1;
+ NODE *used = outer ? outer : inner;
+ compile_error(p, "numbered parameter is already used in\n"
+ "%s:%d: %s block here",
+ p->ruby_sourcefile, nd_line(used),
+ outer ? "outer" : "inner");
+ parser_show_error_line(p, &used->nd_loc);
+ return 1;
}
return 0;
}
@@ -12723,107 +11017,101 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc)
NODE *node;
switch (id) {
case keyword_self:
- return NEW_SELF(loc);
+ return NEW_SELF(loc);
case keyword_nil:
- return NEW_NIL(loc);
+ return NEW_NIL(loc);
case keyword_true:
- return NEW_TRUE(loc);
+ return NEW_TRUE(loc);
case keyword_false:
- return NEW_FALSE(loc);
+ return NEW_FALSE(loc);
case keyword__FILE__:
- {
- VALUE file = p->ruby_sourcefile_string;
- if (NIL_P(file))
- file = rb_str_new(0, 0);
- else
- file = rb_str_dup(file);
- node = NEW_STR(file, loc);
+ {
+ VALUE file = p->ruby_sourcefile_string;
+ if (NIL_P(file))
+ file = rb_str_new(0, 0);
+ else
+ file = rb_str_dup(file);
+ node = NEW_STR(file, loc);
RB_OBJ_WRITTEN(p->ast, Qnil, file);
- }
- return node;
+ }
+ return node;
case keyword__LINE__:
- return NEW_LIT(INT2FIX(loc->beg_pos.lineno), loc);
+ return NEW_LIT(INT2FIX(p->tokline), loc);
case keyword__ENCODING__:
node = NEW_LIT(rb_enc_from_encoding(p->enc), loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit);
return node;
}
switch (id_type(id)) {
case ID_LOCAL:
- if (dyna_in_block(p) && dvar_defined_ref(p, id, &vidp)) {
- if (NUMPARAM_ID_P(id) && numparam_nested_p(p)) return 0;
- if (id == p->cur_arg) {
+ if (dyna_in_block(p) && dvar_defined_ref(p, id, &vidp)) {
+ if (NUMPARAM_ID_P(id) && numparam_nested_p(p)) return 0;
+ if (id == p->cur_arg) {
compile_error(p, "circular argument reference - %"PRIsWARN, rb_id2str(id));
return 0;
- }
- if (vidp) *vidp |= LVAR_USED;
- node = NEW_DVAR(id, loc);
- return node;
- }
- if (local_id_ref(p, id, &vidp)) {
- if (id == p->cur_arg) {
+ }
+ if (vidp) *vidp |= LVAR_USED;
+ node = NEW_DVAR(id, loc);
+ return node;
+ }
+ if (local_id_ref(p, id, &vidp)) {
+ if (id == p->cur_arg) {
compile_error(p, "circular argument reference - %"PRIsWARN, rb_id2str(id));
return 0;
- }
- if (vidp) *vidp |= LVAR_USED;
- node = NEW_LVAR(id, loc);
- return node;
- }
- if (dyna_in_block(p) && NUMPARAM_ID_P(id) &&
- parser_numbered_param(p, NUMPARAM_ID_TO_IDX(id))) {
- if (numparam_nested_p(p)) return 0;
- node = NEW_DVAR(id, loc);
- struct local_vars *local = p->lvtbl;
- if (!local->numparam.current) local->numparam.current = node;
- return node;
- }
+ }
+ if (vidp) *vidp |= LVAR_USED;
+ node = NEW_LVAR(id, loc);
+ return node;
+ }
+ if (dyna_in_block(p) && NUMPARAM_ID_P(id) &&
+ parser_numbered_param(p, NUMPARAM_ID_TO_IDX(id))) {
+ if (numparam_nested_p(p)) return 0;
+ node = NEW_DVAR(id, loc);
+ struct local_vars *local = p->lvtbl;
+ if (!local->numparam.current) local->numparam.current = node;
+ return node;
+ }
# if WARN_PAST_SCOPE
- if (!p->ctxt.in_defined && RTEST(ruby_verbose) && past_dvar_p(p, id)) {
- rb_warning1("possible reference to past scope - %"PRIsWARN, rb_id2str(id));
- }
+ if (!p->ctxt.in_defined && RTEST(ruby_verbose) && past_dvar_p(p, id)) {
+ rb_warning1("possible reference to past scope - %"PRIsWARN, rb_id2str(id));
+ }
# endif
- /* method call without arguments */
- if (dyna_in_block(p) && id == rb_intern("it")
- && !(DVARS_TERMINAL_P(p->lvtbl->args) || DVARS_TERMINAL_P(p->lvtbl->args->prev))
- && p->max_numparam != ORDINAL_PARAM) {
- rb_warn0("`it` calls without arguments will refer to the first block param in Ruby 3.4; use it() or self.it");
- }
- return NEW_VCALL(id, loc);
+ /* method call without arguments */
+ return NEW_VCALL(id, loc);
case ID_GLOBAL:
- return NEW_GVAR(id, loc);
+ return NEW_GVAR(id, loc);
case ID_INSTANCE:
- return NEW_IVAR(id, loc);
+ return NEW_IVAR(id, loc);
case ID_CONST:
- return NEW_CONST(id, loc);
+ return NEW_CONST(id, loc);
case ID_CLASS:
- return NEW_CVAR(id, loc);
+ return NEW_CVAR(id, loc);
}
compile_error(p, "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
return 0;
}
-static rb_node_opt_arg_t *
-opt_arg_append(rb_node_opt_arg_t *opt_list, rb_node_opt_arg_t *opt)
+static NODE *
+opt_arg_append(NODE *opt_list, NODE *opt)
{
- rb_node_opt_arg_t *opts = opt_list;
- RNODE(opts)->nd_loc.end_pos = RNODE(opt)->nd_loc.end_pos;
+ NODE *opts = opt_list;
+ opts->nd_loc.end_pos = opt->nd_loc.end_pos;
while (opts->nd_next) {
- opts = opts->nd_next;
- RNODE(opts)->nd_loc.end_pos = RNODE(opt)->nd_loc.end_pos;
+ opts = opts->nd_next;
+ opts->nd_loc.end_pos = opt->nd_loc.end_pos;
}
opts->nd_next = opt;
return opt_list;
}
-static rb_node_kw_arg_t *
-kwd_append(rb_node_kw_arg_t *kwlist, rb_node_kw_arg_t *kw)
+static NODE *
+kwd_append(NODE *kwlist, NODE *kw)
{
if (kwlist) {
- /* Assume rb_node_kw_arg_t and rb_node_opt_arg_t has same structure */
- opt_arg_append(RNODE_OPT_ARG(kwlist), RNODE_OPT_ARG(kw));
+ opt_arg_append(kwlist, kw);
}
return kwlist;
}
@@ -12831,49 +11119,23 @@ kwd_append(rb_node_kw_arg_t *kwlist, rb_node_kw_arg_t *kw)
static NODE *
new_defined(struct parser_params *p, NODE *expr, const YYLTYPE *loc)
{
- NODE *n = expr;
- while (n) {
- if (nd_type_p(n, NODE_BEGIN)) {
- n = RNODE_BEGIN(n)->nd_body;
- }
- else if (nd_type_p(n, NODE_BLOCK) && RNODE_BLOCK(n)->nd_end == n) {
- n = RNODE_BLOCK(n)->nd_head;
- }
- else {
- break;
- }
- }
- return NEW_DEFINED(n, loc);
-}
-
-static VALUE
-str_to_sym_check(struct parser_params *p, VALUE lit, const YYLTYPE *loc)
-{
- if (rb_enc_str_coderange(lit) == ENC_CODERANGE_BROKEN) {
- yyerror1(loc, "invalid symbol");
- lit = STR_NEW0();
- }
-
- return lit;
+ return NEW_DEFINED(remove_begin_all(expr), loc);
}
static NODE*
symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol)
{
- VALUE lit;
-
enum node_type type = nd_type(symbol);
switch (type) {
case NODE_DSTR:
- nd_set_type(symbol, NODE_DSYM);
- break;
+ nd_set_type(symbol, NODE_DSYM);
+ break;
case NODE_STR:
- nd_set_type(symbol, NODE_LIT);
- lit = str_to_sym_check(p, RNODE_LIT(symbol)->nd_lit, &RNODE(symbol)->nd_loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(symbol)->nd_lit = rb_str_intern(lit));
- break;
+ nd_set_type(symbol, NODE_LIT);
+ RB_OBJ_WRITTEN(p->ast, Qnil, symbol->nd_lit = rb_str_intern(symbol->nd_lit));
+ break;
default:
- compile_error(p, "unexpected node as symbol: %s", parser_node_name(type));
+ compile_error(p, "unexpected node as symbol: %s", ruby_node_name(type));
}
return list_append(p, symbols, symbol);
}
@@ -12881,99 +11143,98 @@ symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol)
static NODE *
new_regexp(struct parser_params *p, NODE *node, int options, const YYLTYPE *loc)
{
- struct RNode_LIST *list;
- NODE *prev;
+ NODE *list, *prev;
VALUE lit;
if (!node) {
- node = NEW_LIT(reg_compile(p, STR_NEW0(), options), loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit);
+ node = NEW_LIT(reg_compile(p, STR_NEW0(), options), loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit);
return node;
}
switch (nd_type(node)) {
case NODE_STR:
- {
- VALUE src = RNODE_STR(node)->nd_lit;
- nd_set_type(node, NODE_LIT);
- nd_set_loc(node, loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit = reg_compile(p, src, options));
- }
- break;
+ {
+ VALUE src = node->nd_lit;
+ nd_set_type(node, NODE_LIT);
+ nd_set_loc(node, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = reg_compile(p, src, options));
+ }
+ break;
default:
- lit = STR_NEW0();
- node = NEW_DSTR0(lit, 1, NEW_LIST(node, loc), loc);
+ lit = STR_NEW0();
+ node = NEW_NODE(NODE_DSTR, lit, 1, NEW_LIST(node, loc), loc);
RB_OBJ_WRITTEN(p->ast, Qnil, lit);
- /* fall through */
+ /* fall through */
case NODE_DSTR:
- nd_set_type(node, NODE_DREGX);
- nd_set_loc(node, loc);
- RNODE_DREGX(node)->nd_cflag = options & RE_OPTION_MASK;
- if (!NIL_P(RNODE_DREGX(node)->nd_lit)) reg_fragment_check(p, RNODE_DREGX(node)->nd_lit, options);
- for (list = RNODE_DREGX(prev = node)->nd_next; list; list = RNODE_LIST(list->nd_next)) {
- NODE *frag = list->nd_head;
- enum node_type type = nd_type(frag);
- if (type == NODE_STR || (type == NODE_DSTR && !RNODE_DSTR(frag)->nd_next)) {
- VALUE tail = RNODE_STR(frag)->nd_lit;
- if (reg_fragment_check(p, tail, options) && prev && !NIL_P(RNODE_DREGX(prev)->nd_lit)) {
- VALUE lit = prev == node ? RNODE_DREGX(prev)->nd_lit : RNODE_LIT(RNODE_LIST(prev)->nd_head)->nd_lit;
- if (!literal_concat0(p, lit, tail)) {
- return NEW_NIL(loc); /* dummy node on error */
- }
- rb_str_resize(tail, 0);
- RNODE_LIST(prev)->nd_next = list->nd_next;
- rb_discard_node(p, list->nd_head);
- rb_discard_node(p, (NODE *)list);
- list = RNODE_LIST(prev);
- }
- else {
- prev = (NODE *)list;
- }
- }
- else {
- prev = 0;
- }
- }
- if (!RNODE_DREGX(node)->nd_next) {
- VALUE src = RNODE_DREGX(node)->nd_lit;
- VALUE re = reg_compile(p, src, options);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_DREGX(node)->nd_lit = re);
- }
- if (options & RE_OPTION_ONCE) {
- node = NEW_ONCE(node, loc);
- }
- break;
+ nd_set_type(node, NODE_DREGX);
+ nd_set_loc(node, loc);
+ node->nd_cflag = options & RE_OPTION_MASK;
+ if (!NIL_P(node->nd_lit)) reg_fragment_check(p, node->nd_lit, options);
+ for (list = (prev = node)->nd_next; list; list = list->nd_next) {
+ NODE *frag = list->nd_head;
+ enum node_type type = nd_type(frag);
+ if (type == NODE_STR || (type == NODE_DSTR && !frag->nd_next)) {
+ VALUE tail = frag->nd_lit;
+ if (reg_fragment_check(p, tail, options) && prev && !NIL_P(prev->nd_lit)) {
+ VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
+ if (!literal_concat0(p, lit, tail)) {
+ return NEW_NIL(loc); /* dummy node on error */
+ }
+ rb_str_resize(tail, 0);
+ prev->nd_next = list->nd_next;
+ rb_discard_node(p, list->nd_head);
+ rb_discard_node(p, list);
+ list = prev;
+ }
+ else {
+ prev = list;
+ }
+ }
+ else {
+ prev = 0;
+ }
+ }
+ if (!node->nd_next) {
+ VALUE src = node->nd_lit;
+ nd_set_type(node, NODE_LIT);
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = reg_compile(p, src, options));
+ }
+ if (options & RE_OPTION_ONCE) {
+ node = NEW_NODE(NODE_ONCE, 0, node, 0, loc);
+ }
+ break;
}
return node;
}
-static rb_node_kw_arg_t *
+static NODE *
new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc)
{
if (!k) return 0;
- return NEW_KW_ARG((k), loc);
+ return NEW_KW_ARG(0, (k), loc);
}
static NODE *
new_xstring(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
if (!node) {
- VALUE lit = STR_NEW0();
- NODE *xstr = NEW_XSTR(lit, loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, lit);
- return xstr;
+ VALUE lit = STR_NEW0();
+ NODE *xstr = NEW_XSTR(lit, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, lit);
+ return xstr;
}
switch (nd_type(node)) {
case NODE_STR:
- nd_set_type(node, NODE_XSTR);
- nd_set_loc(node, loc);
- break;
+ nd_set_type(node, NODE_XSTR);
+ nd_set_loc(node, loc);
+ break;
case NODE_DSTR:
- nd_set_type(node, NODE_DXSTR);
- nd_set_loc(node, loc);
- break;
+ nd_set_type(node, NODE_DXSTR);
+ nd_set_loc(node, loc);
+ break;
default:
- node = NEW_DXSTR(Qnil, 1, NEW_LIST(node, loc), loc);
- break;
+ node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node, loc), loc);
+ break;
}
return node;
}
@@ -12988,19 +11249,19 @@ check_literal_when(struct parser_params *p, NODE *arg, const YYLTYPE *loc)
lit = rb_node_case_when_optimizable_literal(arg);
if (UNDEF_P(lit)) return;
if (nd_type_p(arg, NODE_STR)) {
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(arg)->nd_lit = lit);
+ RB_OBJ_WRITTEN(p->ast, Qnil, arg->nd_lit = lit);
}
if (NIL_P(p->case_labels)) {
- p->case_labels = rb_obj_hide(rb_hash_new());
+ p->case_labels = rb_obj_hide(rb_hash_new());
}
else {
- VALUE line = rb_hash_lookup(p->case_labels, lit);
- if (!NIL_P(line)) {
- rb_warning1("duplicated `when' clause with line %d is ignored",
- WARN_IVAL(line));
- return;
- }
+ VALUE line = rb_hash_lookup(p->case_labels, lit);
+ if (!NIL_P(line)) {
+ rb_warning1("duplicated `when' clause with line %d is ignored",
+ WARN_IVAL(line));
+ return;
+ }
}
rb_hash_aset(p->case_labels, lit, INT2NUM(p->ruby_sourceline));
}
@@ -13010,17 +11271,17 @@ static int
id_is_var(struct parser_params *p, ID id)
{
if (is_notop_id(id)) {
- switch (id & ID_SCOPE_MASK) {
- case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
- return 1;
- case ID_LOCAL:
- if (dyna_in_block(p)) {
- if (NUMPARAM_ID_P(id) || dvar_defined(p, id)) return 1;
- }
- if (local_id(p, id)) return 1;
- /* method call without arguments */
- return 0;
- }
+ switch (id & ID_SCOPE_MASK) {
+ case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
+ return 1;
+ case ID_LOCAL:
+ if (dyna_in_block(p)) {
+ if (NUMPARAM_ID_P(id) || dvar_defined(p, id)) return 1;
+ }
+ if (local_id(p, id)) return 1;
+ /* method call without arguments */
+ return 0;
+ }
}
compile_error(p, "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
return 0;
@@ -13029,18 +11290,18 @@ id_is_var(struct parser_params *p, ID id)
static VALUE
new_regexp(struct parser_params *p, VALUE re, VALUE opt, const YYLTYPE *loc)
{
- VALUE src = 0, err = 0;
+ VALUE src = 0, err;
int options = 0;
- if (ripper_is_node_yylval(p, re)) {
- src = RNODE_RIPPER(re)->nd_cval;
- re = RNODE_RIPPER(re)->nd_rval;
+ if (ripper_is_node_yylval(re)) {
+ src = RNODE(re)->nd_cval;
+ re = RNODE(re)->nd_rval;
}
- if (ripper_is_node_yylval(p, opt)) {
- options = (int)RNODE_RIPPER(opt)->nd_vid;
- opt = RNODE_RIPPER(opt)->nd_rval;
+ if (ripper_is_node_yylval(opt)) {
+ options = (int)RNODE(opt)->nd_tag;
+ opt = RNODE(opt)->nd_rval;
}
if (src && NIL_P(parser_reg_compile(p, src, options, &err))) {
- compile_error(p, "%"PRIsVALUE, err);
+ compile_error(p, "%"PRIsVALUE, err);
}
return dispatch2(regexp_literal, re, opt);
}
@@ -13050,7 +11311,7 @@ static inline enum lex_state_e
parser_set_lex_state(struct parser_params *p, enum lex_state_e ls, int line)
{
if (p->debug) {
- ls = rb_parser_trace_lex_state(p, p->lex.state, ls, line);
+ ls = rb_parser_trace_lex_state(p, p->lex.state, ls, line);
}
return p->lex.state = ls;
}
@@ -13063,23 +11324,23 @@ static const char rb_parser_lex_state_names[][8] = {
};
static VALUE
-append_lex_state_name(struct parser_params *p, enum lex_state_e state, VALUE buf)
+append_lex_state_name(enum lex_state_e state, VALUE buf)
{
int i, sep = 0;
unsigned int mask = 1;
static const char none[] = "NONE";
for (i = 0; i < EXPR_MAX_STATE; ++i, mask <<= 1) {
- if ((unsigned)state & mask) {
- if (sep) {
- rb_str_cat(buf, "|", 1);
- }
- sep = 1;
- rb_str_cat_cstr(buf, rb_parser_lex_state_names[i]);
- }
+ if ((unsigned)state & mask) {
+ if (sep) {
+ rb_str_cat(buf, "|", 1);
+ }
+ sep = 1;
+ rb_str_cat_cstr(buf, rb_parser_lex_state_names[i]);
+ }
}
if (!sep) {
- rb_str_cat(buf, none, sizeof(none)-1);
+ rb_str_cat(buf, none, sizeof(none)-1);
}
return buf;
}
@@ -13090,53 +11351,53 @@ flush_debug_buffer(struct parser_params *p, VALUE out, VALUE str)
VALUE mesg = p->debug_buffer;
if (!NIL_P(mesg) && RSTRING_LEN(mesg)) {
- p->debug_buffer = Qnil;
- rb_io_puts(1, &mesg, out);
+ p->debug_buffer = Qnil;
+ rb_io_puts(1, &mesg, out);
}
if (!NIL_P(str) && RSTRING_LEN(str)) {
- rb_io_write(p->debug_output, str);
+ rb_io_write(p->debug_output, str);
}
}
enum lex_state_e
rb_parser_trace_lex_state(struct parser_params *p, enum lex_state_e from,
- enum lex_state_e to, int line)
+ enum lex_state_e to, int line)
{
VALUE mesg;
mesg = rb_str_new_cstr("lex_state: ");
- append_lex_state_name(p, from, mesg);
+ append_lex_state_name(from, mesg);
rb_str_cat_cstr(mesg, " -> ");
- append_lex_state_name(p, to, mesg);
+ append_lex_state_name(to, mesg);
rb_str_catf(mesg, " at line %d\n", line);
flush_debug_buffer(p, p->debug_output, mesg);
return to;
}
VALUE
-rb_parser_lex_state_name(struct parser_params *p, enum lex_state_e state)
+rb_parser_lex_state_name(enum lex_state_e state)
{
- return rb_fstring(append_lex_state_name(p, state, rb_str_new(0, 0)));
+ return rb_fstring(append_lex_state_name(state, rb_str_new(0, 0)));
}
static void
-append_bitstack_value(struct parser_params *p, stack_type stack, VALUE mesg)
+append_bitstack_value(stack_type stack, VALUE mesg)
{
if (stack == 0) {
- rb_str_cat_cstr(mesg, "0");
+ rb_str_cat_cstr(mesg, "0");
}
else {
- stack_type mask = (stack_type)1U << (CHAR_BIT * sizeof(stack_type) - 1);
- for (; mask && !(stack & mask); mask >>= 1) continue;
- for (; mask; mask >>= 1) rb_str_cat(mesg, stack & mask ? "1" : "0", 1);
+ stack_type mask = (stack_type)1U << (CHAR_BIT * sizeof(stack_type) - 1);
+ for (; mask && !(stack & mask); mask >>= 1) continue;
+ for (; mask; mask >>= 1) rb_str_cat(mesg, stack & mask ? "1" : "0", 1);
}
}
void
rb_parser_show_bitstack(struct parser_params *p, stack_type stack,
- const char *name, int line)
+ const char *name, int line)
{
VALUE mesg = rb_sprintf("%s: ", name);
- append_bitstack_value(p, stack, mesg);
+ append_bitstack_value(stack, mesg);
rb_str_catf(mesg, " at line %d\n", line);
flush_debug_buffer(p, p->debug_output, mesg);
}
@@ -13154,16 +11415,16 @@ rb_parser_fatal(struct parser_params *p, const char *fmt, ...)
RB_GC_GUARD(mesg);
mesg = rb_str_new(0, 0);
- append_lex_state_name(p, p->lex.state, mesg);
+ append_lex_state_name(p->lex.state, mesg);
compile_error(p, "lex.state: %"PRIsVALUE, mesg);
rb_str_resize(mesg, 0);
- append_bitstack_value(p, p->cond_stack, mesg);
+ append_bitstack_value(p->cond_stack, mesg);
compile_error(p, "cond_stack: %"PRIsVALUE, mesg);
rb_str_resize(mesg, 0);
- append_bitstack_value(p, p->cmdarg_stack, mesg);
+ append_bitstack_value(p->cmdarg_stack, mesg);
compile_error(p, "cmdarg_stack: %"PRIsVALUE, mesg);
if (p->debug_output == rb_ractor_stdout())
- p->debug_output = rb_ractor_stderr();
+ p->debug_output = rb_ractor_stderr();
p->debug = TRUE;
}
@@ -13182,7 +11443,7 @@ rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_
{
int sourceline = here->sourceline;
int beg_pos = (int)here->offset - here->quote
- - (rb_strlen_lit("<<-") - !(here->func & STR_FUNC_INDENT));
+ - (rb_strlen_lit("<<-") - !(here->func & STR_FUNC_INDENT));
int end_pos = (int)here->offset + here->length + here->quote;
return rb_parser_set_pos(yylloc, sourceline, beg_pos, end_pos);
@@ -13241,55 +11502,55 @@ assignable0(struct parser_params *p, ID id, const char **err)
if (!id) return -1;
switch (id) {
case keyword_self:
- *err = "Can't change the value of self";
- return -1;
+ *err = "Can't change the value of self";
+ return -1;
case keyword_nil:
- *err = "Can't assign to nil";
- return -1;
+ *err = "Can't assign to nil";
+ return -1;
case keyword_true:
- *err = "Can't assign to true";
- return -1;
+ *err = "Can't assign to true";
+ return -1;
case keyword_false:
- *err = "Can't assign to false";
- return -1;
+ *err = "Can't assign to false";
+ return -1;
case keyword__FILE__:
- *err = "Can't assign to __FILE__";
- return -1;
+ *err = "Can't assign to __FILE__";
+ return -1;
case keyword__LINE__:
- *err = "Can't assign to __LINE__";
- return -1;
+ *err = "Can't assign to __LINE__";
+ return -1;
case keyword__ENCODING__:
- *err = "Can't assign to __ENCODING__";
- return -1;
+ *err = "Can't assign to __ENCODING__";
+ return -1;
}
switch (id_type(id)) {
case ID_LOCAL:
- if (dyna_in_block(p)) {
- if (p->max_numparam > NO_PARAM && NUMPARAM_ID_P(id)) {
- compile_error(p, "Can't assign to numbered parameter _%d",
- NUMPARAM_ID_TO_IDX(id));
- return -1;
- }
- if (dvar_curr(p, id)) return NODE_DASGN;
- if (dvar_defined(p, id)) return NODE_DASGN;
- if (local_id(p, id)) return NODE_LASGN;
- dyna_var(p, id);
- return NODE_DASGN;
- }
- else {
- if (!local_id(p, id)) local_var(p, id);
- return NODE_LASGN;
- }
- break;
+ if (dyna_in_block(p)) {
+ if (p->max_numparam > NO_PARAM && NUMPARAM_ID_P(id)) {
+ compile_error(p, "Can't assign to numbered parameter _%d",
+ NUMPARAM_ID_TO_IDX(id));
+ return -1;
+ }
+ if (dvar_curr(p, id)) return NODE_DASGN;
+ if (dvar_defined(p, id)) return NODE_DASGN;
+ if (local_id(p, id)) return NODE_LASGN;
+ dyna_var(p, id);
+ return NODE_DASGN;
+ }
+ else {
+ if (!local_id(p, id)) local_var(p, id);
+ return NODE_LASGN;
+ }
+ break;
case ID_GLOBAL: return NODE_GASGN;
case ID_INSTANCE: return NODE_IASGN;
case ID_CONST:
- if (!p->ctxt.in_def) return NODE_CDECL;
- *err = "dynamic constant assignment";
- return -1;
+ if (!p->ctxt.in_def) return NODE_CDECL;
+ *err = "dynamic constant assignment";
+ return -1;
case ID_CLASS: return NODE_CVASGN;
default:
- compile_error(p, "identifier %"PRIsVALUE" is not valid to set", rb_id2str(id));
+ compile_error(p, "identifier %"PRIsVALUE" is not valid to set", rb_id2str(id));
}
return -1;
}
@@ -13309,7 +11570,7 @@ assignable(struct parser_params *p, ID id, NODE *val, const YYLTYPE *loc)
case NODE_CVASGN: return NEW_CVASGN(id, val, loc);
}
if (err) yyerror1(loc, err);
- return NEW_ERROR(loc);
+ return NEW_BEGIN(0, loc);
}
#else
static VALUE
@@ -13323,7 +11584,7 @@ assignable(struct parser_params *p, VALUE lhs)
#endif
static int
-is_private_local_id(struct parser_params *p, ID name)
+is_private_local_id(ID name)
{
VALUE s;
if (name == idUScore) return 1;
@@ -13337,23 +11598,23 @@ static int
shadowing_lvar_0(struct parser_params *p, ID name)
{
if (dyna_in_block(p)) {
- if (dvar_curr(p, name)) {
- if (is_private_local_id(p, name)) return 1;
- yyerror0("duplicated argument name");
- }
- else if (dvar_defined(p, name) || local_id(p, name)) {
- vtable_add(p->lvtbl->vars, name);
- if (p->lvtbl->used) {
- vtable_add(p->lvtbl->used, (ID)p->ruby_sourceline | LVAR_USED);
- }
- return 0;
- }
+ if (dvar_curr(p, name)) {
+ if (is_private_local_id(name)) return 1;
+ yyerror0("duplicated argument name");
+ }
+ else if (dvar_defined(p, name) || local_id(p, name)) {
+ vtable_add(p->lvtbl->vars, name);
+ if (p->lvtbl->used) {
+ vtable_add(p->lvtbl->used, (ID)p->ruby_sourceline | LVAR_USED);
+ }
+ return 0;
+ }
}
else {
- if (local_id(p, name)) {
- if (is_private_local_id(p, name)) return 1;
- yyerror0("duplicated argument name");
- }
+ if (local_id(p, name)) {
+ if (is_private_local_id(name)) return 1;
+ yyerror0("duplicated argument name");
+ }
}
return 1;
}
@@ -13370,9 +11631,9 @@ new_bv(struct parser_params *p, ID name)
{
if (!name) return;
if (!is_local_id(name)) {
- compile_error(p, "invalid local variable - %"PRIsVALUE,
- rb_id2str(name));
- return;
+ compile_error(p, "invalid local variable - %"PRIsVALUE,
+ rb_id2str(name));
+ return;
}
if (!shadowing_lvar_0(p, name)) return;
dyna_var(p, name);
@@ -13389,7 +11650,7 @@ static void
block_dup_check(struct parser_params *p, NODE *node1, NODE *node2)
{
if (node2 && node1 && nd_type_p(node1, NODE_BLOCK_PASS)) {
- compile_error(p, "both block arg and actual block given");
+ compile_error(p, "both block arg and actual block given");
}
}
@@ -13405,11 +11666,11 @@ rb_backref_error(struct parser_params *p, NODE *node)
{
switch (nd_type(node)) {
case NODE_NTH_REF:
- compile_error(p, "Can't set variable $%ld", RNODE_NTH_REF(node)->nd_nth);
- break;
+ compile_error(p, "Can't set variable $%ld", node->nd_nth);
+ break;
case NODE_BACK_REF:
- compile_error(p, "Can't set variable $%c", (int)RNODE_BACK_REF(node)->nd_nth);
- break;
+ compile_error(p, "Can't set variable $%c", (int)node->nd_nth);
+ break;
}
}
#else
@@ -13417,7 +11678,7 @@ static VALUE
backref_error(struct parser_params *p, NODE *ref, VALUE expr)
{
VALUE mesg = rb_str_new_cstr("Can't set variable ");
- rb_str_append(mesg, RNODE_RIPPER(ref)->nd_cval);
+ rb_str_append(mesg, ref->nd_cval);
return dispatch2(assign_error, mesg, expr);
}
#endif
@@ -13429,20 +11690,20 @@ arg_append(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *loc
if (!node1) return NEW_LIST(node2, &node2->nd_loc);
switch (nd_type(node1)) {
case NODE_LIST:
- return list_append(p, node1, node2);
+ return list_append(p, node1, node2);
case NODE_BLOCK_PASS:
- RNODE_BLOCK_PASS(node1)->nd_head = arg_append(p, RNODE_BLOCK_PASS(node1)->nd_head, node2, loc);
- node1->nd_loc.end_pos = RNODE_BLOCK_PASS(node1)->nd_head->nd_loc.end_pos;
- return node1;
+ node1->nd_head = arg_append(p, node1->nd_head, node2, loc);
+ node1->nd_loc.end_pos = node1->nd_head->nd_loc.end_pos;
+ return node1;
case NODE_ARGSPUSH:
- RNODE_ARGSPUSH(node1)->nd_body = list_append(p, NEW_LIST(RNODE_ARGSPUSH(node1)->nd_body, &RNODE_ARGSPUSH(node1)->nd_body->nd_loc), node2);
- node1->nd_loc.end_pos = RNODE_ARGSPUSH(node1)->nd_body->nd_loc.end_pos;
- nd_set_type(node1, NODE_ARGSCAT);
- return node1;
+ node1->nd_body = list_append(p, NEW_LIST(node1->nd_body, &node1->nd_body->nd_loc), node2);
+ node1->nd_loc.end_pos = node1->nd_body->nd_loc.end_pos;
+ nd_set_type(node1, NODE_ARGSCAT);
+ return node1;
case NODE_ARGSCAT:
- if (!nd_type_p(RNODE_ARGSCAT(node1)->nd_body, NODE_LIST)) break;
- RNODE_ARGSCAT(node1)->nd_body = list_append(p, RNODE_ARGSCAT(node1)->nd_body, node2);
- node1->nd_loc.end_pos = RNODE_ARGSCAT(node1)->nd_body->nd_loc.end_pos;
+ if (!nd_type_p(node1->nd_body, NODE_LIST)) break;
+ node1->nd_body = list_append(p, node1->nd_body, node2);
+ node1->nd_loc.end_pos = node1->nd_body->nd_loc.end_pos;
return node1;
}
return NEW_ARGSPUSH(node1, node2, loc);
@@ -13454,21 +11715,21 @@ arg_concat(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *loc
if (!node2) return node1;
switch (nd_type(node1)) {
case NODE_BLOCK_PASS:
- if (RNODE_BLOCK_PASS(node1)->nd_head)
- RNODE_BLOCK_PASS(node1)->nd_head = arg_concat(p, RNODE_BLOCK_PASS(node1)->nd_head, node2, loc);
- else
- RNODE_LIST(node1)->nd_head = NEW_LIST(node2, loc);
- return node1;
+ if (node1->nd_head)
+ node1->nd_head = arg_concat(p, node1->nd_head, node2, loc);
+ else
+ node1->nd_head = NEW_LIST(node2, loc);
+ return node1;
case NODE_ARGSPUSH:
- if (!nd_type_p(node2, NODE_LIST)) break;
- RNODE_ARGSPUSH(node1)->nd_body = list_concat(NEW_LIST(RNODE_ARGSPUSH(node1)->nd_body, loc), node2);
- nd_set_type(node1, NODE_ARGSCAT);
- return node1;
+ if (!nd_type_p(node2, NODE_LIST)) break;
+ node1->nd_body = list_concat(NEW_LIST(node1->nd_body, loc), node2);
+ nd_set_type(node1, NODE_ARGSCAT);
+ return node1;
case NODE_ARGSCAT:
- if (!nd_type_p(node2, NODE_LIST) ||
- !nd_type_p(RNODE_ARGSCAT(node1)->nd_body, NODE_LIST)) break;
- RNODE_ARGSCAT(node1)->nd_body = list_concat(RNODE_ARGSCAT(node1)->nd_body, node2);
- return node1;
+ if (!nd_type_p(node2, NODE_LIST) ||
+ !nd_type_p(node1->nd_body, NODE_LIST)) break;
+ node1->nd_body = list_concat(node1->nd_body, node2);
+ return node1;
}
return NEW_ARGSCAT(node1, node2, loc);
}
@@ -13478,7 +11739,7 @@ last_arg_append(struct parser_params *p, NODE *args, NODE *last_arg, const YYLTY
{
NODE *n1;
if ((n1 = splat_array(args)) != 0) {
- return list_append(p, n1, last_arg);
+ return list_append(p, n1, last_arg);
}
return arg_append(p, args, last_arg, loc);
}
@@ -13488,7 +11749,7 @@ rest_arg_append(struct parser_params *p, NODE *args, NODE *rest_arg, const YYLTY
{
NODE *n1;
if ((nd_type_p(rest_arg, NODE_LIST)) && (n1 = splat_array(args)) != 0) {
- return list_concat(n1, rest_arg);
+ return list_concat(n1, rest_arg);
}
return arg_concat(p, args, rest_arg, loc);
}
@@ -13496,7 +11757,7 @@ rest_arg_append(struct parser_params *p, NODE *args, NODE *rest_arg, const YYLTY
static NODE *
splat_array(NODE* node)
{
- if (nd_type_p(node, NODE_SPLAT)) node = RNODE_SPLAT(node)->nd_head;
+ if (nd_type_p(node, NODE_SPLAT)) node = node->nd_head;
if (nd_type_p(node, NODE_LIST)) return node;
return 0;
}
@@ -13508,21 +11769,21 @@ mark_lvar_used(struct parser_params *p, NODE *rhs)
if (!rhs) return;
switch (nd_type(rhs)) {
case NODE_LASGN:
- if (local_id_ref(p, RNODE_LASGN(rhs)->nd_vid, &vidp)) {
- if (vidp) *vidp |= LVAR_USED;
- }
- break;
+ if (local_id_ref(p, rhs->nd_vid, &vidp)) {
+ if (vidp) *vidp |= LVAR_USED;
+ }
+ break;
case NODE_DASGN:
- if (dvar_defined_ref(p, RNODE_DASGN(rhs)->nd_vid, &vidp)) {
- if (vidp) *vidp |= LVAR_USED;
- }
- break;
+ if (dvar_defined_ref(p, rhs->nd_vid, &vidp)) {
+ if (vidp) *vidp |= LVAR_USED;
+ }
+ break;
#if 0
case NODE_MASGN:
- for (rhs = rhs->nd_head; rhs; rhs = rhs->nd_next) {
- mark_lvar_used(p, rhs->nd_head);
- }
- break;
+ for (rhs = rhs->nd_head; rhs; rhs = rhs->nd_next) {
+ mark_lvar_used(p, rhs->nd_head);
+ }
+ break;
#endif
}
}
@@ -13532,38 +11793,40 @@ const_decl_path(struct parser_params *p, NODE **dest)
{
NODE *n = *dest;
if (!nd_type_p(n, NODE_CALL)) {
- const YYLTYPE *loc = &n->nd_loc;
- VALUE path;
- if (RNODE_CDECL(n)->nd_vid) {
- path = rb_id2str(RNODE_CDECL(n)->nd_vid);
- }
- else {
- n = RNODE_CDECL(n)->nd_else;
- path = rb_ary_new();
- for (; n && nd_type_p(n, NODE_COLON2); n = RNODE_COLON2(n)->nd_head) {
- rb_ary_push(path, rb_id2str(RNODE_COLON2(n)->nd_mid));
- }
- if (n && nd_type_p(n, NODE_CONST)) {
- // Const::Name
- rb_ary_push(path, rb_id2str(RNODE_CONST(n)->nd_vid));
- }
- else if (n && nd_type_p(n, NODE_COLON3)) {
- // ::Const::Name
- rb_ary_push(path, rb_str_new(0, 0));
- }
- else {
- // expression::Name
- rb_ary_push(path, rb_str_new_cstr("..."));
- }
- path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::"));
- path = rb_fstring(path);
- }
- *dest = n = NEW_LIT(path, loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(n)->nd_lit);
+ const YYLTYPE *loc = &n->nd_loc;
+ VALUE path;
+ if (n->nd_vid) {
+ path = rb_id2str(n->nd_vid);
+ }
+ else {
+ n = n->nd_else;
+ path = rb_ary_new();
+ for (; n && nd_type_p(n, NODE_COLON2); n = n->nd_head) {
+ rb_ary_push(path, rb_id2str(n->nd_mid));
+ }
+ if (n && nd_type_p(n, NODE_CONST)) {
+ // Const::Name
+ rb_ary_push(path, rb_id2str(n->nd_vid));
+ }
+ else if (n && nd_type_p(n, NODE_COLON3)) {
+ // ::Const::Name
+ rb_ary_push(path, rb_str_new(0, 0));
+ }
+ else {
+ // expression::Name
+ rb_ary_push(path, rb_str_new_cstr("..."));
+ }
+ path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::"));
+ path = rb_fstring(path);
+ }
+ *dest = n = NEW_LIT(path, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, n->nd_lit);
}
return n;
}
+extern VALUE rb_mRubyVMFrozenCore;
+
static NODE *
make_shareable_node(struct parser_params *p, NODE *value, bool copy, const YYLTYPE *loc)
{
@@ -13591,21 +11854,21 @@ ensure_shareable_node(struct parser_params *p, NODE **dest, NODE *value, const Y
static int is_static_content(NODE *node);
static VALUE
-shareable_literal_value(struct parser_params *p, NODE *node)
+shareable_literal_value(NODE *node)
{
if (!node) return Qnil;
enum node_type type = nd_type(node);
switch (type) {
case NODE_TRUE:
- return Qtrue;
+ return Qtrue;
case NODE_FALSE:
- return Qfalse;
+ return Qfalse;
case NODE_NIL:
- return Qnil;
+ return Qnil;
case NODE_LIT:
- return RNODE_LIT(node)->nd_lit;
+ return node->nd_lit;
default:
- return Qundef;
+ return Qundef;
}
}
@@ -13615,7 +11878,7 @@ shareable_literal_value(struct parser_params *p, NODE *node)
static NODE *
shareable_literal_constant(struct parser_params *p, enum shareability shareable,
- NODE **dest, NODE *value, const YYLTYPE *loc, size_t level)
+ NODE **dest, NODE *value, const YYLTYPE *loc, size_t level)
{
# define shareable_literal_constant_next(n) \
shareable_literal_constant(p, shareable, dest, (n), &(n)->nd_loc, level+1)
@@ -13628,112 +11891,112 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
case NODE_FALSE:
case NODE_NIL:
case NODE_LIT:
- return value;
+ return value;
case NODE_DSTR:
- if (shareable == shareable_literal) {
- value = NEW_CALL(value, idUMinus, 0, loc);
- }
- return value;
+ if (shareable == shareable_literal) {
+ value = NEW_CALL(value, idUMinus, 0, loc);
+ }
+ return value;
case NODE_STR:
- lit = rb_fstring(RNODE_STR(value)->nd_lit);
- nd_set_type(value, NODE_LIT);
- RB_OBJ_WRITE(p->ast, &RNODE_LIT(value)->nd_lit, lit);
- return value;
+ lit = rb_fstring(value->nd_lit);
+ nd_set_type(value, NODE_LIT);
+ RB_OBJ_WRITE(p->ast, &value->nd_lit, lit);
+ return value;
case NODE_ZLIST:
- lit = rb_ary_new();
- OBJ_FREEZE_RAW(lit);
+ lit = rb_ary_new();
+ OBJ_FREEZE_RAW(lit);
NODE *n = NEW_LIT(lit, loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(n)->nd_lit);
+ RB_OBJ_WRITTEN(p->ast, Qnil, n->nd_lit);
return n;
case NODE_LIST:
- lit = rb_ary_new();
- for (NODE *n = value; n; n = RNODE_LIST(n)->nd_next) {
- NODE *elt = RNODE_LIST(n)->nd_head;
- if (elt) {
- elt = shareable_literal_constant_next(elt);
- if (elt) {
- RNODE_LIST(n)->nd_head = elt;
- }
- else if (RTEST(lit)) {
- rb_ary_clear(lit);
- lit = Qfalse;
- }
- }
- if (RTEST(lit)) {
- VALUE e = shareable_literal_value(p, elt);
- if (!UNDEF_P(e)) {
- rb_ary_push(lit, e);
- }
- else {
- rb_ary_clear(lit);
- lit = Qnil; /* make shareable at runtime */
- }
- }
- }
- break;
+ lit = rb_ary_new();
+ for (NODE *n = value; n; n = n->nd_next) {
+ NODE *elt = n->nd_head;
+ if (elt) {
+ elt = shareable_literal_constant_next(elt);
+ if (elt) {
+ n->nd_head = elt;
+ }
+ else if (RTEST(lit)) {
+ rb_ary_clear(lit);
+ lit = Qfalse;
+ }
+ }
+ if (RTEST(lit)) {
+ VALUE e = shareable_literal_value(elt);
+ if (!UNDEF_P(e)) {
+ rb_ary_push(lit, e);
+ }
+ else {
+ rb_ary_clear(lit);
+ lit = Qnil; /* make shareable at runtime */
+ }
+ }
+ }
+ break;
case NODE_HASH:
- if (!RNODE_HASH(value)->nd_brace) return 0;
- lit = rb_hash_new();
- for (NODE *n = RNODE_HASH(value)->nd_head; n; n = RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_next) {
- NODE *key = RNODE_LIST(n)->nd_head;
- NODE *val = RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_head;
- if (key) {
- key = shareable_literal_constant_next(key);
- if (key) {
- RNODE_LIST(n)->nd_head = key;
- }
- else if (RTEST(lit)) {
- rb_hash_clear(lit);
- lit = Qfalse;
- }
- }
- if (val) {
- val = shareable_literal_constant_next(val);
- if (val) {
- RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_head = val;
- }
- else if (RTEST(lit)) {
- rb_hash_clear(lit);
- lit = Qfalse;
- }
- }
- if (RTEST(lit)) {
- VALUE k = shareable_literal_value(p, key);
- VALUE v = shareable_literal_value(p, val);
- if (!UNDEF_P(k) && !UNDEF_P(v)) {
- rb_hash_aset(lit, k, v);
- }
- else {
- rb_hash_clear(lit);
- lit = Qnil; /* make shareable at runtime */
- }
- }
- }
- break;
+ if (!value->nd_brace) return 0;
+ lit = rb_hash_new();
+ for (NODE *n = value->nd_head; n; n = n->nd_next->nd_next) {
+ NODE *key = n->nd_head;
+ NODE *val = n->nd_next->nd_head;
+ if (key) {
+ key = shareable_literal_constant_next(key);
+ if (key) {
+ n->nd_head = key;
+ }
+ else if (RTEST(lit)) {
+ rb_hash_clear(lit);
+ lit = Qfalse;
+ }
+ }
+ if (val) {
+ val = shareable_literal_constant_next(val);
+ if (val) {
+ n->nd_next->nd_head = val;
+ }
+ else if (RTEST(lit)) {
+ rb_hash_clear(lit);
+ lit = Qfalse;
+ }
+ }
+ if (RTEST(lit)) {
+ VALUE k = shareable_literal_value(key);
+ VALUE v = shareable_literal_value(val);
+ if (!UNDEF_P(k) && !UNDEF_P(v)) {
+ rb_hash_aset(lit, k, v);
+ }
+ else {
+ rb_hash_clear(lit);
+ lit = Qnil; /* make shareable at runtime */
+ }
+ }
+ }
+ break;
default:
- if (shareable == shareable_literal &&
- (SHAREABLE_BARE_EXPRESSION || level > 0)) {
- return ensure_shareable_node(p, dest, value, loc);
- }
- return 0;
+ if (shareable == shareable_literal &&
+ (SHAREABLE_BARE_EXPRESSION || level > 0)) {
+ return ensure_shareable_node(p, dest, value, loc);
+ }
+ return 0;
}
/* Array or Hash */
if (!lit) return 0;
if (NIL_P(lit)) {
- // if shareable_literal, all elements should have been ensured
- // as shareable
- value = make_shareable_node(p, value, false, loc);
+ // if shareable_literal, all elements should have been ensured
+ // as shareable
+ value = make_shareable_node(p, value, false, loc);
}
else {
- value = NEW_LIT(rb_ractor_make_shareable(lit), loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(value)->nd_lit);
+ value = NEW_LIT(rb_ractor_make_shareable(lit), loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, value->nd_lit);
}
return value;
@@ -13742,32 +12005,32 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
static NODE *
shareable_constant_value(struct parser_params *p, enum shareability shareable,
- NODE *lhs, NODE *value, const YYLTYPE *loc)
+ NODE *lhs, NODE *value, const YYLTYPE *loc)
{
if (!value) return 0;
switch (shareable) {
case shareable_none:
- return value;
+ return value;
case shareable_literal:
- {
- NODE *lit = shareable_literal_constant(p, shareable, &lhs, value, loc, 0);
- if (lit) return lit;
- return value;
- }
- break;
+ {
+ NODE *lit = shareable_literal_constant(p, shareable, &lhs, value, loc, 0);
+ if (lit) return lit;
+ return value;
+ }
+ break;
case shareable_copy:
case shareable_everything:
- {
- NODE *lit = shareable_literal_constant(p, shareable, &lhs, value, loc, 0);
- if (lit) return lit;
- return make_shareable_node(p, value, shareable == shareable_copy, loc);
- }
- break;
+ {
+ NODE *lit = shareable_literal_constant(p, shareable, &lhs, value, loc, 0);
+ if (lit) return lit;
+ return make_shareable_node(p, value, shareable == shareable_copy, loc);
+ }
+ break;
default:
- UNREACHABLE_RETURN(0);
+ UNREACHABLE_RETURN(0);
}
}
@@ -13778,8 +12041,8 @@ node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, struct lex_context ct
switch (nd_type(lhs)) {
case NODE_CDECL:
- rhs = shareable_constant_value(p, ctxt.shareable_constant_value, lhs, rhs, loc);
- /* fallthru */
+ rhs = shareable_constant_value(p, ctxt.shareable_constant_value, lhs, rhs, loc);
+ /* fallthru */
case NODE_GASGN:
case NODE_IASGN:
@@ -13787,18 +12050,18 @@ node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, struct lex_context ct
case NODE_DASGN:
case NODE_MASGN:
case NODE_CVASGN:
- set_nd_value(p, lhs, rhs);
- nd_set_loc(lhs, loc);
- break;
+ lhs->nd_value = rhs;
+ nd_set_loc(lhs, loc);
+ break;
case NODE_ATTRASGN:
- RNODE_ATTRASGN(lhs)->nd_args = arg_append(p, RNODE_ATTRASGN(lhs)->nd_args, rhs, loc);
- nd_set_loc(lhs, loc);
- break;
+ lhs->nd_args = arg_append(p, lhs->nd_args, rhs, loc);
+ nd_set_loc(lhs, loc);
+ break;
default:
- /* should not happen */
- break;
+ /* should not happen */
+ break;
}
return lhs;
@@ -13810,67 +12073,67 @@ value_expr_check(struct parser_params *p, NODE *node)
NODE *void_node = 0, *vn;
if (!node) {
- rb_warning0("empty expression");
+ rb_warning0("empty expression");
}
while (node) {
- switch (nd_type(node)) {
- case NODE_RETURN:
- case NODE_BREAK:
- case NODE_NEXT:
- case NODE_REDO:
- case NODE_RETRY:
- return void_node ? void_node : node;
-
- case NODE_CASE3:
- if (!RNODE_CASE3(node)->nd_body || !nd_type_p(RNODE_CASE3(node)->nd_body, NODE_IN)) {
- compile_error(p, "unexpected node");
- return NULL;
- }
- if (RNODE_IN(RNODE_CASE3(node)->nd_body)->nd_body) {
- return NULL;
- }
- /* single line pattern matching with "=>" operator */
- return void_node ? void_node : node;
-
- case NODE_BLOCK:
- while (RNODE_BLOCK(node)->nd_next) {
- node = RNODE_BLOCK(node)->nd_next;
- }
- node = RNODE_BLOCK(node)->nd_head;
- break;
-
- case NODE_BEGIN:
- node = RNODE_BEGIN(node)->nd_body;
- break;
-
- case NODE_IF:
- case NODE_UNLESS:
- if (!RNODE_IF(node)->nd_body) {
- return NULL;
- }
- else if (!RNODE_IF(node)->nd_else) {
- return NULL;
- }
- vn = value_expr_check(p, RNODE_IF(node)->nd_body);
- if (!vn) return NULL;
- if (!void_node) void_node = vn;
- node = RNODE_IF(node)->nd_else;
- break;
-
- case NODE_AND:
- case NODE_OR:
- node = RNODE_AND(node)->nd_1st;
- break;
-
- case NODE_LASGN:
- case NODE_DASGN:
- case NODE_MASGN:
- mark_lvar_used(p, node);
- return NULL;
-
- default:
- return NULL;
- }
+ switch (nd_type(node)) {
+ case NODE_RETURN:
+ case NODE_BREAK:
+ case NODE_NEXT:
+ case NODE_REDO:
+ case NODE_RETRY:
+ return void_node ? void_node : node;
+
+ case NODE_CASE3:
+ if (!node->nd_body || !nd_type_p(node->nd_body, NODE_IN)) {
+ compile_error(p, "unexpected node");
+ return NULL;
+ }
+ if (node->nd_body->nd_body) {
+ return NULL;
+ }
+ /* single line pattern matching */
+ return void_node ? void_node : node;
+
+ case NODE_BLOCK:
+ while (node->nd_next) {
+ node = node->nd_next;
+ }
+ node = node->nd_head;
+ break;
+
+ case NODE_BEGIN:
+ node = node->nd_body;
+ break;
+
+ case NODE_IF:
+ case NODE_UNLESS:
+ if (!node->nd_body) {
+ return NULL;
+ }
+ else if (!node->nd_else) {
+ return NULL;
+ }
+ vn = value_expr_check(p, node->nd_body);
+ if (!vn) return NULL;
+ if (!void_node) void_node = vn;
+ node = node->nd_else;
+ break;
+
+ case NODE_AND:
+ case NODE_OR:
+ node = node->nd_1st;
+ break;
+
+ case NODE_LASGN:
+ case NODE_DASGN:
+ case NODE_MASGN:
+ mark_lvar_used(p, node);
+ return NULL;
+
+ default:
+ return NULL;
+ }
}
return NULL;
@@ -13881,13 +12144,12 @@ value_expr_gen(struct parser_params *p, NODE *node)
{
NODE *void_node = value_expr_check(p, node);
if (void_node) {
- yyerror1(&void_node->nd_loc, "void value expression");
- /* or "control never reach"? */
- return FALSE;
+ yyerror1(&void_node->nd_loc, "void value expression");
+ /* or "control never reach"? */
+ return FALSE;
}
return TRUE;
}
-
static void
void_expr(struct parser_params *p, NODE *node)
{
@@ -13898,29 +12160,29 @@ void_expr(struct parser_params *p, NODE *node)
if (!node || !(node = nd_once_body(node))) return;
switch (nd_type(node)) {
case NODE_OPCALL:
- switch (RNODE_OPCALL(node)->nd_mid) {
- case '+':
- case '-':
- case '*':
- case '/':
- case '%':
- case tPOW:
- case tUPLUS:
- case tUMINUS:
- case '|':
- case '^':
- case '&':
- case tCMP:
- case '>':
- case tGEQ:
- case '<':
- case tLEQ:
- case tEQ:
- case tNEQ:
- useless = rb_id2name(RNODE_OPCALL(node)->nd_mid);
- break;
- }
- break;
+ switch (node->nd_mid) {
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case tPOW:
+ case tUPLUS:
+ case tUMINUS:
+ case '|':
+ case '^':
+ case '&':
+ case tCMP:
+ case '>':
+ case tGEQ:
+ case '<':
+ case tLEQ:
+ case tEQ:
+ case tNEQ:
+ useless = rb_id2name(node->nd_mid);
+ break;
+ }
+ break;
case NODE_LVAR:
case NODE_DVAR:
@@ -13929,46 +12191,46 @@ void_expr(struct parser_params *p, NODE *node)
case NODE_CVAR:
case NODE_NTH_REF:
case NODE_BACK_REF:
- useless = "a variable";
- break;
+ useless = "a variable";
+ break;
case NODE_CONST:
- useless = "a constant";
- break;
+ useless = "a constant";
+ break;
case NODE_LIT:
case NODE_STR:
case NODE_DSTR:
case NODE_DREGX:
- useless = "a literal";
- break;
+ useless = "a literal";
+ break;
case NODE_COLON2:
case NODE_COLON3:
- useless = "::";
- break;
+ useless = "::";
+ break;
case NODE_DOT2:
- useless = "..";
- break;
+ useless = "..";
+ break;
case NODE_DOT3:
- useless = "...";
- break;
+ useless = "...";
+ break;
case NODE_SELF:
- useless = "self";
- break;
+ useless = "self";
+ break;
case NODE_NIL:
- useless = "nil";
- break;
+ useless = "nil";
+ break;
case NODE_TRUE:
- useless = "true";
- break;
+ useless = "true";
+ break;
case NODE_FALSE:
- useless = "false";
- break;
+ useless = "false";
+ break;
case NODE_DEFINED:
- useless = "defined?";
- break;
+ useless = "defined?";
+ break;
}
if (useless) {
- rb_warn1L(nd_line(node), "possibly useless use of %s in void context", WARN_S(useless));
+ rb_warn1L(nd_line(node), "possibly useless use of %s in void context", WARN_S(useless));
}
}
@@ -13980,9 +12242,9 @@ void_stmts(struct parser_params *p, NODE *node)
if (!node) return n;
if (!nd_type_p(node, NODE_BLOCK)) return n;
- while (RNODE_BLOCK(node)->nd_next) {
- void_expr(p, RNODE_BLOCK(node)->nd_head);
- node = RNODE_BLOCK(node)->nd_next;
+ while (node->nd_next) {
+ void_expr(p, node->nd_head);
+ node = node->nd_next;
}
return n;
}
@@ -13991,8 +12253,18 @@ static NODE *
remove_begin(NODE *node)
{
NODE **n = &node, *n1 = node;
- while (n1 && nd_type_p(n1, NODE_BEGIN) && RNODE_BEGIN(n1)->nd_body) {
- *n = n1 = RNODE_BEGIN(n1)->nd_body;
+ while (n1 && nd_type_p(n1, NODE_BEGIN) && n1->nd_body) {
+ *n = n1 = n1->nd_body;
+ }
+ return node;
+}
+
+static NODE *
+remove_begin_all(NODE *node)
+{
+ NODE **n = &node, *n1 = node;
+ while (n1 && nd_type_p(n1, NODE_BEGIN)) {
+ *n = n1 = n1->nd_body;
}
return node;
}
@@ -14003,58 +12275,57 @@ reduce_nodes(struct parser_params *p, NODE **body)
NODE *node = *body;
if (!node) {
- *body = NEW_NIL(&NULL_LOC);
- return;
+ *body = NEW_NIL(&NULL_LOC);
+ return;
}
-#define subnodes(type, n1, n2) \
- ((!type(node)->n1) ? (type(node)->n2 ? (body = &type(node)->n2, 1) : 0) : \
- (!type(node)->n2) ? (body = &type(node)->n1, 1) : \
- (reduce_nodes(p, &type(node)->n1), body = &type(node)->n2, 1))
+#define subnodes(n1, n2) \
+ ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
+ (!node->n2) ? (body = &node->n1, 1) : \
+ (reduce_nodes(p, &node->n1), body = &node->n2, 1))
while (node) {
- int newline = (int)(nd_fl_newline(node));
- switch (nd_type(node)) {
- end:
- case NODE_NIL:
- *body = 0;
- return;
- case NODE_RETURN:
- *body = node = RNODE_RETURN(node)->nd_stts;
- if (newline && node) nd_set_fl_newline(node);
- continue;
- case NODE_BEGIN:
- *body = node = RNODE_BEGIN(node)->nd_body;
- if (newline && node) nd_set_fl_newline(node);
- continue;
- case NODE_BLOCK:
- body = &RNODE_BLOCK(RNODE_BLOCK(node)->nd_end)->nd_head;
- break;
- case NODE_IF:
- case NODE_UNLESS:
- if (subnodes(RNODE_IF, nd_body, nd_else)) break;
- return;
- case NODE_CASE:
- body = &RNODE_CASE(node)->nd_body;
- break;
- case NODE_WHEN:
- if (!subnodes(RNODE_WHEN, nd_body, nd_next)) goto end;
- break;
- case NODE_ENSURE:
- if (!subnodes(RNODE_ENSURE, nd_head, nd_resq)) goto end;
- break;
- case NODE_RESCUE:
- newline = 0; // RESBODY should not be a NEWLINE
- if (RNODE_RESCUE(node)->nd_else) {
- body = &RNODE_RESCUE(node)->nd_resq;
- break;
- }
- if (!subnodes(RNODE_RESCUE, nd_head, nd_resq)) goto end;
- break;
- default:
- return;
- }
- node = *body;
- if (newline && node) nd_set_fl_newline(node);
+ int newline = (int)(node->flags & NODE_FL_NEWLINE);
+ switch (nd_type(node)) {
+ end:
+ case NODE_NIL:
+ *body = 0;
+ return;
+ case NODE_RETURN:
+ *body = node = node->nd_stts;
+ if (newline && node) node->flags |= NODE_FL_NEWLINE;
+ continue;
+ case NODE_BEGIN:
+ *body = node = node->nd_body;
+ if (newline && node) node->flags |= NODE_FL_NEWLINE;
+ continue;
+ case NODE_BLOCK:
+ body = &node->nd_end->nd_head;
+ break;
+ case NODE_IF:
+ case NODE_UNLESS:
+ if (subnodes(nd_body, nd_else)) break;
+ return;
+ case NODE_CASE:
+ body = &node->nd_body;
+ break;
+ case NODE_WHEN:
+ if (!subnodes(nd_body, nd_next)) goto end;
+ break;
+ case NODE_ENSURE:
+ if (!subnodes(nd_head, nd_resq)) goto end;
+ break;
+ case NODE_RESCUE:
+ if (node->nd_else) {
+ body = &node->nd_resq;
+ break;
+ }
+ if (!subnodes(nd_head, nd_resq)) goto end;
+ break;
+ default:
+ return;
+ }
+ node = *body;
+ if (newline && node) node->flags |= NODE_FL_NEWLINE;
}
#undef subnodes
@@ -14066,20 +12337,20 @@ is_static_content(NODE *node)
if (!node) return 1;
switch (nd_type(node)) {
case NODE_HASH:
- if (!(node = RNODE_HASH(node)->nd_head)) break;
+ if (!(node = node->nd_head)) break;
case NODE_LIST:
- do {
- if (!is_static_content(RNODE_LIST(node)->nd_head)) return 0;
- } while ((node = RNODE_LIST(node)->nd_next) != 0);
+ do {
+ if (!is_static_content(node->nd_head)) return 0;
+ } while ((node = node->nd_next) != 0);
case NODE_LIT:
case NODE_STR:
case NODE_NIL:
case NODE_TRUE:
case NODE_FALSE:
case NODE_ZLIST:
- break;
+ break;
default:
- return 0;
+ return 0;
}
return 1;
}
@@ -14093,18 +12364,16 @@ assign_in_cond(struct parser_params *p, NODE *node)
case NODE_DASGN:
case NODE_GASGN:
case NODE_IASGN:
- case NODE_CVASGN:
- case NODE_CDECL:
- break;
+ break;
default:
- return 0;
+ return 0;
}
- if (!get_nd_value(p, node)) return 1;
- if (is_static_content(get_nd_value(p, node))) {
- /* reports always */
- parser_warn(p, get_nd_value(p, node), "found `= literal' in conditional, should be ==");
+ if (!node->nd_value) return 1;
+ if (is_static_content(node->nd_value)) {
+ /* reports always */
+ parser_warn(p, node->nd_value, "found `= literal' in conditional, should be ==");
}
return 1;
}
@@ -14115,15 +12384,14 @@ enum cond_type {
COND_IN_FF
};
-#define SWITCH_BY_COND_TYPE(t, w, arg) do { \
+#define SWITCH_BY_COND_TYPE(t, w, arg) \
switch (t) { \
case COND_IN_OP: break; \
case COND_IN_COND: rb_##w##0(arg "literal in condition"); break; \
case COND_IN_FF: rb_##w##0(arg "literal in flip-flop"); break; \
- } \
-} while (0)
+ }
-static NODE *cond0(struct parser_params*,NODE*,enum cond_type,const YYLTYPE*,bool);
+static NODE *cond0(struct parser_params*,NODE*,enum cond_type,const YYLTYPE*);
static NODE*
range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
@@ -14134,83 +12402,69 @@ range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
type = nd_type(node);
value_expr(node);
- if (type == NODE_LIT && FIXNUM_P(RNODE_LIT(node)->nd_lit)) {
- if (!e_option_supplied(p)) parser_warn(p, node, "integer literal in flip-flop");
- ID lineno = rb_intern("$.");
- return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(lineno, loc), loc), loc);
+ if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
+ if (!e_option_supplied(p)) parser_warn(p, node, "integer literal in flip-flop");
+ ID lineno = rb_intern("$.");
+ return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(lineno, loc), loc), loc);
}
- return cond0(p, node, COND_IN_FF, loc, true);
+ return cond0(p, node, COND_IN_FF, loc);
}
static NODE*
-cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *loc, bool top)
+cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *loc)
{
if (node == 0) return 0;
if (!(node = nd_once_body(node))) return 0;
assign_in_cond(p, node);
switch (nd_type(node)) {
- case NODE_BEGIN:
- RNODE_BEGIN(node)->nd_body = cond0(p, RNODE_BEGIN(node)->nd_body, type, loc, top);
- break;
-
case NODE_DSTR:
case NODE_EVSTR:
case NODE_STR:
- SWITCH_BY_COND_TYPE(type, warn, "string ");
- break;
+ SWITCH_BY_COND_TYPE(type, warn, "string ")
+ break;
case NODE_DREGX:
- if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warning, "regex ");
-
- return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
+ if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warning, "regex ")
- case NODE_BLOCK:
- {
- NODE *end = RNODE_BLOCK(node)->nd_end;
- NODE **expr = &RNODE_BLOCK(end)->nd_head;
- if (top) top = node == end;
- *expr = cond0(p, *expr, type, loc, top);
- }
- break;
+ return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
case NODE_AND:
case NODE_OR:
- RNODE_AND(node)->nd_1st = cond0(p, RNODE_AND(node)->nd_1st, COND_IN_COND, loc, true);
- RNODE_AND(node)->nd_2nd = cond0(p, RNODE_AND(node)->nd_2nd, COND_IN_COND, loc, true);
- break;
+ node->nd_1st = cond0(p, node->nd_1st, COND_IN_COND, loc);
+ node->nd_2nd = cond0(p, node->nd_2nd, COND_IN_COND, loc);
+ break;
case NODE_DOT2:
case NODE_DOT3:
- if (!top) break;
- RNODE_DOT2(node)->nd_beg = range_op(p, RNODE_DOT2(node)->nd_beg, loc);
- RNODE_DOT2(node)->nd_end = range_op(p, RNODE_DOT2(node)->nd_end, loc);
- if (nd_type_p(node, NODE_DOT2)) nd_set_type(node,NODE_FLIP2);
- else if (nd_type_p(node, NODE_DOT3)) nd_set_type(node, NODE_FLIP3);
- break;
+ node->nd_beg = range_op(p, node->nd_beg, loc);
+ node->nd_end = range_op(p, node->nd_end, loc);
+ if (nd_type_p(node, NODE_DOT2)) nd_set_type(node,NODE_FLIP2);
+ else if (nd_type_p(node, NODE_DOT3)) nd_set_type(node, NODE_FLIP3);
+ break;
case NODE_DSYM:
warn_symbol:
- SWITCH_BY_COND_TYPE(type, warning, "symbol ");
- break;
+ SWITCH_BY_COND_TYPE(type, warning, "symbol ")
+ break;
case NODE_LIT:
- if (RB_TYPE_P(RNODE_LIT(node)->nd_lit, T_REGEXP)) {
- if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warn, "regex ");
- nd_set_type(node, NODE_MATCH);
- }
- else if (RNODE_LIT(node)->nd_lit == Qtrue ||
- RNODE_LIT(node)->nd_lit == Qfalse) {
- /* booleans are OK, e.g., while true */
- }
- else if (SYMBOL_P(RNODE_LIT(node)->nd_lit)) {
- goto warn_symbol;
- }
- else {
- SWITCH_BY_COND_TYPE(type, warning, "");
- }
+ if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
+ if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warn, "regex ")
+ nd_set_type(node, NODE_MATCH);
+ }
+ else if (node->nd_lit == Qtrue ||
+ node->nd_lit == Qfalse) {
+ /* booleans are OK, e.g., while true */
+ }
+ else if (SYMBOL_P(node->nd_lit)) {
+ goto warn_symbol;
+ }
+ else {
+ SWITCH_BY_COND_TYPE(type, warning, "")
+ }
default:
- break;
+ break;
}
return node;
}
@@ -14219,14 +12473,14 @@ static NODE*
cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
if (node == 0) return 0;
- return cond0(p, node, COND_IN_COND, loc, true);
+ return cond0(p, node, COND_IN_COND, loc);
}
static NODE*
method_cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
{
if (node == 0) return 0;
- return cond0(p, node, COND_IN_OP, loc, true);
+ return cond0(p, node, COND_IN_OP, loc);
}
static NODE*
@@ -14240,7 +12494,7 @@ static NODE*
new_if(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
{
if (!cc) return right;
- cc = cond0(p, cc, COND_IN_COND, loc, true);
+ cc = cond0(p, cc, COND_IN_COND, loc);
return newline_node(NEW_IF(cc, left, right, loc));
}
@@ -14248,41 +12502,37 @@ static NODE*
new_unless(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
{
if (!cc) return right;
- cc = cond0(p, cc, COND_IN_COND, loc, true);
+ cc = cond0(p, cc, COND_IN_COND, loc);
return newline_node(NEW_UNLESS(cc, left, right, loc));
}
-#define NEW_AND_OR(type, f, s, loc) (type == NODE_AND ? NEW_AND(f,s,loc) : NEW_OR(f,s,loc))
-
static NODE*
logop(struct parser_params *p, ID id, NODE *left, NODE *right,
- const YYLTYPE *op_loc, const YYLTYPE *loc)
+ const YYLTYPE *op_loc, const YYLTYPE *loc)
{
enum node_type type = id == idAND || id == idANDOP ? NODE_AND : NODE_OR;
NODE *op;
value_expr(left);
if (left && nd_type_p(left, type)) {
- NODE *node = left, *second;
- while ((second = RNODE_AND(node)->nd_2nd) != 0 && nd_type_p(second, type)) {
- node = second;
- }
- RNODE_AND(node)->nd_2nd = NEW_AND_OR(type, second, right, loc);
- nd_set_line(RNODE_AND(node)->nd_2nd, op_loc->beg_pos.lineno);
- left->nd_loc.end_pos = loc->end_pos;
- return left;
- }
- op = NEW_AND_OR(type, left, right, loc);
+ NODE *node = left, *second;
+ while ((second = node->nd_2nd) != 0 && nd_type_p(second, type)) {
+ node = second;
+ }
+ node->nd_2nd = NEW_NODE(type, second, right, 0, loc);
+ nd_set_line(node->nd_2nd, op_loc->beg_pos.lineno);
+ left->nd_loc.end_pos = loc->end_pos;
+ return left;
+ }
+ op = NEW_NODE(type, left, right, 0, loc);
nd_set_line(op, op_loc->beg_pos.lineno);
return op;
}
-#undef NEW_AND_OR
-
static void
no_blockarg(struct parser_params *p, NODE *node)
{
if (nd_type_p(node, NODE_BLOCK_PASS)) {
- compile_error(p, "block argument should not be given");
+ compile_error(p, "block argument should not be given");
}
}
@@ -14290,10 +12540,15 @@ static NODE *
ret_args(struct parser_params *p, NODE *node)
{
if (node) {
- no_blockarg(p, node);
- if (nd_type_p(node, NODE_LIST) && !RNODE_LIST(node)->nd_next) {
- node = RNODE_LIST(node)->nd_head;
- }
+ no_blockarg(p, node);
+ if (nd_type_p(node, NODE_LIST)) {
+ if (node->nd_next == 0) {
+ node = node->nd_head;
+ }
+ else {
+ nd_set_type(node, NODE_VALUES);
+ }
+ }
}
return node;
}
@@ -14310,49 +12565,49 @@ static VALUE
negate_lit(struct parser_params *p, VALUE lit)
{
if (FIXNUM_P(lit)) {
- return LONG2FIX(-FIX2LONG(lit));
+ return LONG2FIX(-FIX2LONG(lit));
}
if (SPECIAL_CONST_P(lit)) {
#if USE_FLONUM
- if (FLONUM_P(lit)) {
- return DBL2NUM(-RFLOAT_VALUE(lit));
- }
+ if (FLONUM_P(lit)) {
+ return DBL2NUM(-RFLOAT_VALUE(lit));
+ }
#endif
- goto unknown;
+ goto unknown;
}
switch (BUILTIN_TYPE(lit)) {
case T_BIGNUM:
- bignum_negate(lit);
- lit = rb_big_norm(lit);
- break;
+ BIGNUM_NEGATE(lit);
+ lit = rb_big_norm(lit);
+ break;
case T_RATIONAL:
- rational_set_num(lit, negate_lit(p, rational_get_num(lit)));
- break;
+ RATIONAL_SET_NUM(lit, negate_lit(p, RRATIONAL(lit)->num));
+ break;
case T_COMPLEX:
- rcomplex_set_real(lit, negate_lit(p, rcomplex_get_real(lit)));
- rcomplex_set_imag(lit, negate_lit(p, rcomplex_get_imag(lit)));
- break;
+ RCOMPLEX_SET_REAL(lit, negate_lit(p, RCOMPLEX(lit)->real));
+ RCOMPLEX_SET_IMAG(lit, negate_lit(p, RCOMPLEX(lit)->imag));
+ break;
case T_FLOAT:
- lit = DBL2NUM(-RFLOAT_VALUE(lit));
- break;
+ lit = DBL2NUM(-RFLOAT_VALUE(lit));
+ break;
unknown:
default:
- rb_parser_fatal(p, "unknown literal type (%s) passed to negate_lit",
- rb_builtin_class_name(lit));
- break;
+ rb_parser_fatal(p, "unknown literal type (%s) passed to negate_lit",
+ rb_builtin_class_name(lit));
+ break;
}
return lit;
}
static NODE *
-arg_blk_pass(NODE *node1, rb_node_block_pass_t *node2)
+arg_blk_pass(NODE *node1, NODE *node2)
{
if (node2) {
- if (!node1) return (NODE *)node2;
- node2->nd_head = node1;
- nd_set_first_lineno(node2, nd_first_lineno(node1));
- nd_set_first_column(node2, nd_first_column(node1));
- return (NODE *)node2;
+ if (!node1) return node2;
+ node2->nd_head = node1;
+ nd_set_first_lineno(node2, nd_first_lineno(node1));
+ nd_set_first_column(node2, nd_first_column(node1));
+ return node2;
}
return node1;
}
@@ -14370,17 +12625,18 @@ args_info_empty_p(struct rb_args_info *args)
return true;
}
-static rb_node_args_t *
-new_args(struct parser_params *p, rb_node_args_aux_t *pre_args, rb_node_opt_arg_t *opt_args, ID rest_arg, rb_node_args_aux_t *post_args, rb_node_args_t *tail, const YYLTYPE *loc)
+static NODE*
+new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, NODE *post_args, NODE *tail, const YYLTYPE *loc)
{
- struct rb_args_info *args = &tail->nd_ainfo;
+ int saved_line = p->ruby_sourceline;
+ struct rb_args_info *args = tail->nd_ainfo;
if (args->forwarding) {
- if (rest_arg) {
- yyerror1(&RNODE(tail)->nd_loc, "... after rest argument");
- return tail;
- }
- rest_arg = idFWD_REST;
+ if (rest_arg) {
+ yyerror1(&tail->nd_loc, "... after rest argument");
+ return tail;
+ }
+ rest_arg = idFWD_REST;
}
args->pre_args_num = pre_args ? rb_long2int(pre_args->nd_plen) : 0;
@@ -14400,78 +12656,87 @@ new_args(struct parser_params *p, rb_node_args_aux_t *pre_args, rb_node_opt_arg_
args->ruby2_keywords = 0;
#endif
- nd_set_loc(RNODE(tail), loc);
+ p->ruby_sourceline = saved_line;
+ nd_set_loc(tail, loc);
return tail;
}
-static rb_node_args_t *
-new_args_tail(struct parser_params *p, rb_node_kw_arg_t *kw_args, ID kw_rest_arg, ID block, const YYLTYPE *kw_rest_loc)
+static NODE*
+new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, const YYLTYPE *kw_rest_loc)
{
- rb_node_args_t *node = NEW_ARGS(&NULL_LOC);
- struct rb_args_info *args = &node->nd_ainfo;
+ int saved_line = p->ruby_sourceline;
+ NODE *node;
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ struct rb_args_info *args = ZALLOC(struct rb_args_info);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, args);
+ args->imemo = tmpbuf;
+ node = NEW_NODE(NODE_ARGS, 0, 0, args, &NULL_LOC);
+ RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
if (p->error_p) return node;
args->block_arg = block;
args->kw_args = kw_args;
if (kw_args) {
- /*
- * def foo(k1: 1, kr1:, k2: 2, **krest, &b)
- * variable order: k1, kr1, k2, &b, internal_id, krest
- * #=> <reorder>
- * variable order: kr1, k1, k2, internal_id, krest, &b
- */
- ID kw_bits = internal_id(p), *required_kw_vars, *kw_vars;
- struct vtable *vtargs = p->lvtbl->args;
- rb_node_kw_arg_t *kwn = kw_args;
+ /*
+ * def foo(k1: 1, kr1:, k2: 2, **krest, &b)
+ * variable order: k1, kr1, k2, &b, internal_id, krest
+ * #=> <reorder>
+ * variable order: kr1, k1, k2, internal_id, krest, &b
+ */
+ ID kw_bits = internal_id(p), *required_kw_vars, *kw_vars;
+ struct vtable *vtargs = p->lvtbl->args;
+ NODE *kwn = kw_args;
if (block) block = vtargs->tbl[vtargs->pos-1];
- vtable_pop(vtargs, !!block + !!kw_rest_arg);
- required_kw_vars = kw_vars = &vtargs->tbl[vtargs->pos];
- while (kwn) {
- if (!NODE_REQUIRED_KEYWORD_P(get_nd_value(p, kwn->nd_body)))
- --kw_vars;
- --required_kw_vars;
- kwn = kwn->nd_next;
- }
-
- for (kwn = kw_args; kwn; kwn = kwn->nd_next) {
- ID vid = get_nd_vid(p, kwn->nd_body);
- if (NODE_REQUIRED_KEYWORD_P(get_nd_value(p, kwn->nd_body))) {
- *required_kw_vars++ = vid;
- }
- else {
- *kw_vars++ = vid;
- }
- }
-
- arg_var(p, kw_bits);
- if (kw_rest_arg) arg_var(p, kw_rest_arg);
- if (block) arg_var(p, block);
-
- args->kw_rest_arg = NEW_DVAR(kw_rest_arg, kw_rest_loc);
+ vtable_pop(vtargs, !!block + !!kw_rest_arg);
+ required_kw_vars = kw_vars = &vtargs->tbl[vtargs->pos];
+ while (kwn) {
+ if (!NODE_REQUIRED_KEYWORD_P(kwn->nd_body))
+ --kw_vars;
+ --required_kw_vars;
+ kwn = kwn->nd_next;
+ }
+
+ for (kwn = kw_args; kwn; kwn = kwn->nd_next) {
+ ID vid = kwn->nd_body->nd_vid;
+ if (NODE_REQUIRED_KEYWORD_P(kwn->nd_body)) {
+ *required_kw_vars++ = vid;
+ }
+ else {
+ *kw_vars++ = vid;
+ }
+ }
+
+ arg_var(p, kw_bits);
+ if (kw_rest_arg) arg_var(p, kw_rest_arg);
+ if (block) arg_var(p, block);
+
+ args->kw_rest_arg = NEW_DVAR(kw_rest_arg, kw_rest_loc);
+ args->kw_rest_arg->nd_cflag = kw_bits;
}
else if (kw_rest_arg == idNil) {
- args->no_kwarg = 1;
+ args->no_kwarg = 1;
}
else if (kw_rest_arg) {
- args->kw_rest_arg = NEW_DVAR(kw_rest_arg, kw_rest_loc);
+ args->kw_rest_arg = NEW_DVAR(kw_rest_arg, kw_rest_loc);
}
+ p->ruby_sourceline = saved_line;
return node;
}
-static rb_node_args_t *
-args_with_numbered(struct parser_params *p, rb_node_args_t *args, int max_numparam)
+static NODE *
+args_with_numbered(struct parser_params *p, NODE *args, int max_numparam)
{
if (max_numparam > NO_PARAM) {
- if (!args) {
- YYLTYPE loc = RUBY_INIT_YYLLOC();
- args = new_args_tail(p, 0, 0, 0, 0);
- nd_set_loc(RNODE(args), &loc);
- }
- args->nd_ainfo.pre_args_num = max_numparam;
+ if (!args) {
+ YYLTYPE loc = RUBY_INIT_YYLLOC();
+ args = new_args_tail(p, 0, 0, 0, 0);
+ nd_set_loc(args, &loc);
+ }
+ args->nd_ainfo->pre_args_num = max_numparam;
}
return args;
}
@@ -14479,76 +12744,106 @@ args_with_numbered(struct parser_params *p, rb_node_args_t *args, int max_numpar
static NODE*
new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *aryptn, const YYLTYPE *loc)
{
- RNODE_ARYPTN(aryptn)->nd_pconst = constant;
+ struct rb_ary_pattern_info *apinfo = aryptn->nd_apinfo;
+
+ aryptn->nd_pconst = constant;
if (pre_arg) {
- NODE *pre_args = NEW_LIST(pre_arg, loc);
- if (RNODE_ARYPTN(aryptn)->pre_args) {
- RNODE_ARYPTN(aryptn)->pre_args = list_concat(pre_args, RNODE_ARYPTN(aryptn)->pre_args);
- }
- else {
- RNODE_ARYPTN(aryptn)->pre_args = pre_args;
- }
+ NODE *pre_args = NEW_LIST(pre_arg, loc);
+ if (apinfo->pre_args) {
+ apinfo->pre_args = list_concat(pre_args, apinfo->pre_args);
+ }
+ else {
+ apinfo->pre_args = pre_args;
+ }
}
return aryptn;
}
static NODE*
-new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc)
+new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID rest_arg, NODE *post_args, const YYLTYPE *loc)
{
+ int saved_line = p->ruby_sourceline;
+ NODE *node;
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ struct rb_ary_pattern_info *apinfo = ZALLOC(struct rb_ary_pattern_info);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, apinfo);
+ node = NEW_NODE(NODE_ARYPTN, 0, tmpbuf, apinfo, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+
+ apinfo->pre_args = pre_args;
+
if (has_rest) {
- rest_arg = rest_arg ? rest_arg : NODE_SPECIAL_NO_NAME_REST;
+ if (rest_arg) {
+ apinfo->rest_arg = assignable(p, rest_arg, 0, loc);
+ }
+ else {
+ apinfo->rest_arg = NODE_SPECIAL_NO_NAME_REST;
+ }
}
else {
- rest_arg = NULL;
+ apinfo->rest_arg = NULL;
}
- NODE *node = NEW_ARYPTN(pre_args, rest_arg, post_args, loc);
+ apinfo->post_args = post_args;
+
+ p->ruby_sourceline = saved_line;
return node;
}
static NODE*
new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YYLTYPE *loc)
{
- RNODE_FNDPTN(fndptn)->nd_pconst = constant;
+ fndptn->nd_pconst = constant;
return fndptn;
}
static NODE*
-new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc)
+new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc)
{
- pre_rest_arg = pre_rest_arg ? pre_rest_arg : NODE_SPECIAL_NO_NAME_REST;
- post_rest_arg = post_rest_arg ? post_rest_arg : NODE_SPECIAL_NO_NAME_REST;
- NODE *node = NEW_FNDPTN(pre_rest_arg, args, post_rest_arg, loc);
+ int saved_line = p->ruby_sourceline;
+ NODE *node;
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ struct rb_fnd_pattern_info *fpinfo = ZALLOC(struct rb_fnd_pattern_info);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, fpinfo);
+ node = NEW_NODE(NODE_FNDPTN, 0, tmpbuf, fpinfo, loc);
+ RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+
+ fpinfo->pre_rest_arg = pre_rest_arg ? assignable(p, pre_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
+ fpinfo->args = args;
+ fpinfo->post_rest_arg = post_rest_arg ? assignable(p, post_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
+ p->ruby_sourceline = saved_line;
return node;
}
static NODE*
new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc)
{
- RNODE_HSHPTN(hshptn)->nd_pconst = constant;
+ hshptn->nd_pconst = constant;
return hshptn;
}
static NODE*
new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, const YYLTYPE *loc)
{
+ int saved_line = p->ruby_sourceline;
NODE *node, *kw_rest_arg_node;
if (kw_rest_arg == idNil) {
- kw_rest_arg_node = NODE_SPECIAL_NO_REST_KEYWORD;
+ kw_rest_arg_node = NODE_SPECIAL_NO_REST_KEYWORD;
}
else if (kw_rest_arg) {
- kw_rest_arg_node = assignable(p, kw_rest_arg, 0, loc);
+ kw_rest_arg_node = assignable(p, kw_rest_arg, 0, loc);
}
else {
- kw_rest_arg_node = NULL;
+ kw_rest_arg_node = NULL;
}
- node = NEW_HSHPTN(0, kw_args, kw_rest_arg_node, loc);
+ node = NEW_NODE(NODE_HSHPTN, 0, kw_args, kw_rest_arg_node, loc);
+ p->ruby_sourceline = saved_line;
return node;
}
@@ -14558,23 +12853,23 @@ dsym_node(struct parser_params *p, NODE *node, const YYLTYPE *loc)
VALUE lit;
if (!node) {
- return NEW_LIT(ID2SYM(idNULL), loc);
+ return NEW_LIT(ID2SYM(idNULL), loc);
}
switch (nd_type(node)) {
case NODE_DSTR:
- nd_set_type(node, NODE_DSYM);
- nd_set_loc(node, loc);
- break;
+ nd_set_type(node, NODE_DSYM);
+ nd_set_loc(node, loc);
+ break;
case NODE_STR:
- lit = str_to_sym_check(p, RNODE_STR(node)->nd_lit, &RNODE(node)->nd_loc);
- RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(node)->nd_lit = ID2SYM(rb_intern_str(lit)));
- nd_set_type(node, NODE_LIT);
- nd_set_loc(node, loc);
- break;
+ lit = node->nd_lit;
+ RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = ID2SYM(rb_intern_str(lit)));
+ nd_set_type(node, NODE_LIT);
+ nd_set_loc(node, loc);
+ break;
default:
- node = NEW_DSYM(Qnil, 1, NEW_LIST(node, loc), loc);
- break;
+ node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node, loc), loc);
+ break;
}
return node;
}
@@ -14584,60 +12879,83 @@ append_literal_keys(st_data_t k, st_data_t v, st_data_t h)
{
NODE *node = (NODE *)v;
NODE **result = (NODE **)h;
- RNODE_LIST(node)->as.nd_alen = 2;
- RNODE_LIST(RNODE_LIST(node)->nd_next)->as.nd_end = RNODE_LIST(node)->nd_next;
- RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next = 0;
+ node->nd_alen = 2;
+ node->nd_next->nd_end = node->nd_next;
+ node->nd_next->nd_next = 0;
if (*result)
- list_concat(*result, node);
+ list_concat(*result, node);
else
- *result = node;
+ *result = node;
return ST_CONTINUE;
}
+static bool
+hash_literal_key_p(VALUE k)
+{
+ switch (OBJ_BUILTIN_TYPE(k)) {
+ case T_NODE:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static int
+literal_cmp(VALUE val, VALUE lit)
+{
+ if (val == lit) return 0;
+ if (!hash_literal_key_p(val) || !hash_literal_key_p(lit)) return -1;
+ return rb_iseq_cdhash_cmp(val, lit);
+}
+
+static st_index_t
+literal_hash(VALUE a)
+{
+ if (!hash_literal_key_p(a)) return (st_index_t)a;
+ return rb_iseq_cdhash_hash(a);
+}
+
+static const struct st_hash_type literal_type = {
+ literal_cmp,
+ literal_hash,
+};
+
static NODE *
remove_duplicate_keys(struct parser_params *p, NODE *hash)
{
- struct st_hash_type literal_type = {
- literal_cmp,
- literal_hash,
- };
-
- st_table *literal_keys = st_init_table_with_size(&literal_type, RNODE_LIST(hash)->as.nd_alen / 2);
+ st_table *literal_keys = st_init_table_with_size(&literal_type, hash->nd_alen / 2);
NODE *result = 0;
NODE *last_expr = 0;
rb_code_location_t loc = hash->nd_loc;
- while (hash && RNODE_LIST(hash)->nd_next) {
- NODE *head = RNODE_LIST(hash)->nd_head;
- NODE *value = RNODE_LIST(hash)->nd_next;
- NODE *next = RNODE_LIST(value)->nd_next;
- st_data_t key = (st_data_t)head;
- st_data_t data;
- RNODE_LIST(value)->nd_next = 0;
- if (!head) {
- key = (st_data_t)value;
- }
- else if (nd_type_p(head, NODE_LIT) &&
- st_delete(literal_keys, (key = (st_data_t)RNODE_LIT(head)->nd_lit, &key), &data)) {
- NODE *dup_value = (RNODE_LIST((NODE *)data))->nd_next;
- rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
- "key %+"PRIsVALUE" is duplicated and overwritten on line %d",
- RNODE_LIT(head)->nd_lit, nd_line(head));
- if (dup_value == last_expr) {
- RNODE_LIST(value)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(value)->nd_head);
- }
- else {
- RNODE_LIST(last_expr)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(last_expr)->nd_head);
- }
- }
- st_insert(literal_keys, (st_data_t)key, (st_data_t)hash);
- last_expr = !head || nd_type_p(head, NODE_LIT) ? value : head;
- hash = next;
+ while (hash && hash->nd_head && hash->nd_next) {
+ NODE *head = hash->nd_head;
+ NODE *value = hash->nd_next;
+ NODE *next = value->nd_next;
+ st_data_t key = (st_data_t)head;
+ st_data_t data;
+ value->nd_next = 0;
+ if (nd_type_p(head, NODE_LIT) &&
+ st_delete(literal_keys, (key = (st_data_t)head->nd_lit, &key), &data)) {
+ NODE *dup_value = ((NODE *)data)->nd_next;
+ rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
+ "key %+"PRIsVALUE" is duplicated and overwritten on line %d",
+ head->nd_lit, nd_line(head));
+ if (dup_value == last_expr) {
+ value->nd_head = block_append(p, dup_value->nd_head, value->nd_head);
+ }
+ else {
+ last_expr->nd_head = block_append(p, dup_value->nd_head, last_expr->nd_head);
+ }
+ }
+ st_insert(literal_keys, (st_data_t)key, (st_data_t)hash);
+ last_expr = nd_type_p(head, NODE_LIT) ? value : head;
+ hash = next;
}
st_foreach(literal_keys, append_literal_keys, (st_data_t)&result);
st_free_table(literal_keys);
if (hash) {
- if (!result) result = hash;
- else list_concat(result, hash);
+ if (!result) result = hash;
+ else list_concat(result, hash);
}
result->nd_loc = loc;
return result;
@@ -14654,14 +12972,14 @@ new_hash(struct parser_params *p, NODE *hash, const YYLTYPE *loc)
static void
error_duplicate_pattern_variable(struct parser_params *p, ID id, const YYLTYPE *loc)
{
- if (is_private_local_id(p, id)) {
- return;
+ if (is_private_local_id(id)) {
+ return;
}
if (st_is_member(p->pvtbl, id)) {
- yyerror1(loc, "duplicated variable name");
+ yyerror1(loc, "duplicated variable name");
}
else {
- st_insert(p->pvtbl, (st_data_t)id, 0);
+ st_insert(p->pvtbl, (st_data_t)id, 0);
}
}
@@ -14669,11 +12987,11 @@ static void
error_duplicate_pattern_key(struct parser_params *p, VALUE key, const YYLTYPE *loc)
{
if (!p->pktbl) {
- p->pktbl = st_init_numtable();
+ p->pktbl = st_init_numtable();
}
else if (st_is_member(p->pktbl, key)) {
- yyerror1(loc, "duplicated key name");
- return;
+ yyerror1(loc, "duplicated key name");
+ return;
}
st_insert(p->pktbl, (st_data_t)key, 0);
}
@@ -14693,65 +13011,79 @@ new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_c
NODE *asgn;
if (lhs) {
- ID vid = get_nd_vid(p, lhs);
- YYLTYPE lhs_loc = lhs->nd_loc;
- int shareable = ctxt.shareable_constant_value;
- if (shareable) {
- switch (nd_type(lhs)) {
- case NODE_CDECL:
- case NODE_COLON2:
- case NODE_COLON3:
- break;
- default:
- shareable = 0;
- break;
- }
- }
- if (op == tOROP) {
- rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
- set_nd_value(p, lhs, rhs);
- nd_set_loc(lhs, loc);
- asgn = NEW_OP_ASGN_OR(gettable(p, vid, &lhs_loc), lhs, loc);
- }
- else if (op == tANDOP) {
- if (shareable) {
- rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
- }
- set_nd_value(p, lhs, rhs);
- nd_set_loc(lhs, loc);
- asgn = NEW_OP_ASGN_AND(gettable(p, vid, &lhs_loc), lhs, loc);
- }
- else {
- asgn = lhs;
- rhs = NEW_CALL(gettable(p, vid, &lhs_loc), op, NEW_LIST(rhs, &rhs->nd_loc), loc);
- if (shareable) {
- rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
- }
- set_nd_value(p, asgn, rhs);
- nd_set_loc(asgn, loc);
- }
+ ID vid = lhs->nd_vid;
+ YYLTYPE lhs_loc = lhs->nd_loc;
+ int shareable = ctxt.shareable_constant_value;
+ if (shareable) {
+ switch (nd_type(lhs)) {
+ case NODE_CDECL:
+ case NODE_COLON2:
+ case NODE_COLON3:
+ break;
+ default:
+ shareable = 0;
+ break;
+ }
+ }
+ if (op == tOROP) {
+ rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
+ lhs->nd_value = rhs;
+ nd_set_loc(lhs, loc);
+ asgn = NEW_OP_ASGN_OR(gettable(p, vid, &lhs_loc), lhs, loc);
+ if (is_notop_id(vid)) {
+ switch (id_type(vid)) {
+ case ID_GLOBAL:
+ case ID_INSTANCE:
+ case ID_CLASS:
+ asgn->nd_aid = vid;
+ }
+ }
+ }
+ else if (op == tANDOP) {
+ if (shareable) {
+ rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
+ }
+ lhs->nd_value = rhs;
+ nd_set_loc(lhs, loc);
+ asgn = NEW_OP_ASGN_AND(gettable(p, vid, &lhs_loc), lhs, loc);
+ }
+ else {
+ asgn = lhs;
+ rhs = NEW_CALL(gettable(p, vid, &lhs_loc), op, NEW_LIST(rhs, &rhs->nd_loc), loc);
+ if (shareable) {
+ rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc);
+ }
+ asgn->nd_value = rhs;
+ nd_set_loc(asgn, loc);
+ }
}
else {
- asgn = NEW_ERROR(loc);
+ asgn = NEW_BEGIN(0, loc);
}
return asgn;
}
static NODE *
new_ary_op_assign(struct parser_params *p, NODE *ary,
- NODE *args, ID op, NODE *rhs, const YYLTYPE *args_loc, const YYLTYPE *loc)
+ NODE *args, ID op, NODE *rhs, const YYLTYPE *args_loc, const YYLTYPE *loc)
{
NODE *asgn;
args = make_list(args, args_loc);
- asgn = NEW_OP_ASGN1(ary, op, args, rhs, loc);
+ if (nd_type_p(args, NODE_BLOCK_PASS)) {
+ args = NEW_ARGSCAT(args, rhs, loc);
+ }
+ else {
+ args = arg_concat(p, args, rhs, loc);
+ }
+ asgn = NEW_OP_ASGN1(ary, op, args, loc);
fixpos(asgn, ary);
return asgn;
}
static NODE *
new_attr_op_assign(struct parser_params *p, NODE *lhs,
- ID atype, ID attr, ID op, NODE *rhs, const YYLTYPE *loc)
+ ID atype, ID attr, ID op, NODE *rhs, const YYLTYPE *loc)
{
NODE *asgn;
@@ -14766,11 +13098,11 @@ new_const_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct
NODE *asgn;
if (lhs) {
- rhs = shareable_constant_value(p, ctxt.shareable_constant_value, lhs, rhs, loc);
- asgn = NEW_OP_CDECL(lhs, op, rhs, loc);
+ rhs = shareable_constant_value(p, ctxt.shareable_constant_value, lhs, rhs, loc);
+ asgn = NEW_OP_CDECL(lhs, op, rhs, loc);
}
else {
- asgn = NEW_ERROR(loc);
+ asgn = NEW_BEGIN(0, loc);
}
fixpos(asgn, lhs);
return asgn;
@@ -14780,7 +13112,7 @@ static NODE *
const_decl(struct parser_params *p, NODE *path, const YYLTYPE *loc)
{
if (p->ctxt.in_def) {
- yyerror1(loc, "dynamic constant assignment");
+ yyerror1(loc, "dynamic constant assignment");
}
return NEW_CDECL(0, 0, (path), loc);
}
@@ -14789,7 +13121,7 @@ static VALUE
const_decl(struct parser_params *p, VALUE path)
{
if (p->ctxt.in_def) {
- path = assign_error(p, "dynamic constant assignment", path);
+ path = assign_error(p, "dynamic constant assignment", path);
}
return path;
}
@@ -14840,15 +13172,15 @@ warn_unused_var(struct parser_params *p, struct local_vars *local)
if (!local->used) return;
cnt = local->used->pos;
if (cnt != local->vars->pos) {
- rb_parser_fatal(p, "local->used->pos != local->vars->pos");
+ rb_parser_fatal(p, "local->used->pos != local->vars->pos");
}
#ifndef RIPPER
ID *v = local->vars->tbl;
ID *u = local->used->tbl;
for (int i = 0; i < cnt; ++i) {
- if (!v[i] || (u[i] & LVAR_USED)) continue;
- if (is_private_local_id(p, v[i])) continue;
- rb_warn1L((int)u[i], "assigned but unused variable - %"PRIsWARN, rb_id2str(v[i]));
+ if (!v[i] || (u[i] & LVAR_USED)) continue;
+ if (is_private_local_id(v[i])) continue;
+ rb_warn1L((int)u[i], "assigned but unused variable - %"PRIsWARN, rb_id2str(v[i]));
}
#endif
}
@@ -14936,10 +13268,10 @@ local_tbl(struct parser_params *p)
MEMCPY(tbl->ids, p->lvtbl->args->tbl, ID, cnt_args);
/* remove IDs duplicated to warn shadowing */
for (i = 0, j = cnt_args; i < cnt_vars; ++i) {
- ID id = p->lvtbl->vars->tbl[i];
- if (!vtable_included(p->lvtbl->args, id)) {
- tbl->ids[j++] = id;
- }
+ ID id = p->lvtbl->vars->tbl[i];
+ if (!vtable_included(p->lvtbl->args, id)) {
+ tbl->ids[j++] = id;
+ }
}
if (j < cnt) {
tbl = rb_ast_resize_latest_local_table(p->ast, j);
@@ -14948,6 +13280,17 @@ local_tbl(struct parser_params *p)
return tbl;
}
+static NODE*
+node_newnode_with_locals(struct parser_params *p, enum node_type type, VALUE a1, VALUE a2, const rb_code_location_t *loc)
+{
+ rb_ast_id_table_t *a0;
+ NODE *n;
+
+ a0 = local_tbl(p);
+ n = NEW_NODE(type, a0, a1, a2, loc);
+ return n;
+}
+
#endif
static void
@@ -14971,7 +13314,7 @@ local_var(struct parser_params *p, ID id)
numparam_name(p, id);
vtable_add(p->lvtbl->vars, id);
if (p->lvtbl->used) {
- vtable_add(p->lvtbl->used, (ID)p->ruby_sourceline);
+ vtable_add(p->lvtbl->used, (ID)p->ruby_sourceline);
}
}
@@ -14985,21 +13328,21 @@ local_id_ref(struct parser_params *p, ID id, ID **vidrefp)
used = p->lvtbl->used;
while (vars && !DVARS_TERMINAL_P(vars->prev)) {
- vars = vars->prev;
- args = args->prev;
- if (used) used = used->prev;
+ vars = vars->prev;
+ args = args->prev;
+ if (used) used = used->prev;
}
if (vars && vars->prev == DVARS_INHERIT) {
- return rb_local_defined(id, p->parent_iseq);
+ return rb_local_defined(id, p->parent_iseq);
}
else if (vtable_included(args, id)) {
- return 1;
+ return 1;
}
else {
- int i = vtable_included(vars, id);
- if (i && used && vidrefp) *vidrefp = &used->tbl[i-1];
- return i != 0;
+ int i = vtable_included(vars, id);
+ if (i && used && vidrefp) *vidrefp = &used->tbl[i-1];
+ return i != 0;
}
}
@@ -15028,40 +13371,6 @@ add_forwarding_args(struct parser_params *p)
arg_var(p, idFWD_ALL);
}
-static void
-forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
-{
- bool conflict = false;
-
- struct vtable *vars, *args;
-
- vars = p->lvtbl->vars;
- args = p->lvtbl->args;
-
- while (vars && !DVARS_TERMINAL_P(vars->prev)) {
- conflict |= (vtable_included(args, arg) && !(all && vtable_included(args, all)));
- vars = vars->prev;
- args = args->prev;
- }
-
- bool found = false;
- if (vars && vars->prev == DVARS_INHERIT && !found) {
- found = (rb_local_defined(arg, p->parent_iseq) &&
- !(all && rb_local_defined(all, p->parent_iseq)));
- }
- else {
- found = (vtable_included(args, arg) &&
- !(all && vtable_included(args, all)));
- }
-
- if (!found) {
- compile_error(p, "no anonymous %s parameter", var);
- }
- else if (conflict) {
- compile_error(p, "anonymous %s parameter is also used within block", var);
- }
-}
-
#ifndef RIPPER
static NODE *
new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc, const YYLTYPE *argsloc)
@@ -15070,7 +13379,7 @@ new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc
#ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
NODE *kwrest = list_append(p, NEW_LIST(0, loc), NEW_LVAR(idFWD_KWREST, loc));
#endif
- rb_node_block_pass_t *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), loc);
+ NODE *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), loc);
NODE *args = leading ? rest_arg_append(p, leading, rest, argsloc) : NEW_SPLAT(rest, loc);
#ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS
args = arg_append(p, args, new_hash(p, kwrest, loc), loc);
@@ -15086,7 +13395,7 @@ numparam_push(struct parser_params *p)
struct local_vars *local = p->lvtbl;
NODE *inner = local->numparam.inner;
if (!local->numparam.outer) {
- local->numparam.outer = local->numparam.current;
+ local->numparam.outer = local->numparam.current;
}
local->numparam.inner = 0;
local->numparam.current = 0;
@@ -15102,21 +13411,21 @@ numparam_pop(struct parser_params *p, NODE *prev_inner)
#ifndef RIPPER
struct local_vars *local = p->lvtbl;
if (prev_inner) {
- /* prefer first one */
- local->numparam.inner = prev_inner;
+ /* prefer first one */
+ local->numparam.inner = prev_inner;
}
else if (local->numparam.current) {
- /* current and inner are exclusive */
- local->numparam.inner = local->numparam.current;
+ /* current and inner are exclusive */
+ local->numparam.inner = local->numparam.current;
}
if (p->max_numparam > NO_PARAM) {
- /* current and outer are exclusive */
- local->numparam.current = local->numparam.outer;
- local->numparam.outer = 0;
+ /* current and outer are exclusive */
+ local->numparam.current = local->numparam.outer;
+ local->numparam.outer = 0;
}
else {
- /* no numbered parameter */
- local->numparam.current = 0;
+ /* no numbered parameter */
+ local->numparam.current = 0;
}
#endif
}
@@ -15127,7 +13436,7 @@ dyna_push(struct parser_params *p)
p->lvtbl->args = vtable_alloc(p->lvtbl->args);
p->lvtbl->vars = vtable_alloc(p->lvtbl->vars);
if (p->lvtbl->used) {
- p->lvtbl->used = vtable_alloc(p->lvtbl->used);
+ p->lvtbl->used = vtable_alloc(p->lvtbl->used);
}
return p->lvtbl->args;
}
@@ -15139,9 +13448,9 @@ dyna_pop_vtable(struct parser_params *p, struct vtable **vtblp)
*vtblp = tmp->prev;
# if WARN_PAST_SCOPE
if (p->past_scope_enabled) {
- tmp->prev = p->lvtbl->past;
- p->lvtbl->past = tmp;
- return;
+ tmp->prev = p->lvtbl->past;
+ p->lvtbl->past = tmp;
+ return;
}
# endif
vtable_free(tmp);
@@ -15153,9 +13462,9 @@ dyna_pop_1(struct parser_params *p)
struct vtable *tmp;
if ((tmp = p->lvtbl->used) != 0) {
- warn_unused_var(p, p->lvtbl);
- p->lvtbl->used = p->lvtbl->used->prev;
- vtable_free(tmp);
+ warn_unused_var(p, p->lvtbl);
+ p->lvtbl->used = p->lvtbl->used->prev;
+ vtable_free(tmp);
}
dyna_pop_vtable(p, &p->lvtbl->args);
dyna_pop_vtable(p, &p->lvtbl->vars);
@@ -15165,12 +13474,12 @@ static void
dyna_pop(struct parser_params *p, const struct vtable *lvargs)
{
while (p->lvtbl->args != lvargs) {
- dyna_pop_1(p);
- if (!p->lvtbl->args) {
- struct local_vars *local = p->lvtbl->prev;
- ruby_sized_xfree(p->lvtbl, sizeof(*p->lvtbl));
- p->lvtbl = local;
- }
+ dyna_pop_1(p);
+ if (!p->lvtbl->args) {
+ struct local_vars *local = p->lvtbl->prev;
+ ruby_sized_xfree(p->lvtbl, sizeof(*p->lvtbl));
+ p->lvtbl = local;
+ }
}
dyna_pop_1(p);
}
@@ -15192,17 +13501,17 @@ dvar_defined_ref(struct parser_params *p, ID id, ID **vidrefp)
used = p->lvtbl->used;
while (!DVARS_TERMINAL_P(vars)) {
- if (vtable_included(args, id)) {
- return 1;
- }
- if ((i = vtable_included(vars, id)) != 0) {
- if (used && vidrefp) *vidrefp = &used->tbl[i-1];
- return 1;
- }
- args = args->prev;
- vars = vars->prev;
- if (!vidrefp) used = 0;
- if (used) used = used->prev;
+ if (vtable_included(args, id)) {
+ return 1;
+ }
+ if ((i = vtable_included(vars, id)) != 0) {
+ if (used && vidrefp) *vidrefp = &used->tbl[i-1];
+ return 1;
+ }
+ args = args->prev;
+ vars = vars->prev;
+ if (!vidrefp) used = 0;
+ if (used) used = used->prev;
}
if (vars == DVARS_INHERIT && !NUMPARAM_ID_P(id)) {
@@ -15222,7 +13531,7 @@ static int
dvar_curr(struct parser_params *p, ID id)
{
return (vtable_included(p->lvtbl->args, id) ||
- vtable_included(p->lvtbl->vars, id));
+ vtable_included(p->lvtbl->vars, id));
}
static void
@@ -15240,13 +13549,13 @@ rb_reg_fragment_setenc(struct parser_params* p, VALUE str, int options)
int c = RE_OPTION_ENCODING_IDX(options);
if (c) {
- int opt, idx;
- rb_char_to_option_kcode(c, &opt, &idx);
- if (idx != ENCODING_GET(str) &&
- !is_ascii_string(str)) {
+ int opt, idx;
+ rb_char_to_option_kcode(c, &opt, &idx);
+ if (idx != ENCODING_GET(str) &&
+ !is_ascii_string(str)) {
goto error;
- }
- ENCODING_SET(str, idx);
+ }
+ ENCODING_SET(str, idx);
}
else if (RE_OPTION_ENCODING_NONE(options)) {
if (!ENCODING_IS_ASCII8BIT(str) &&
@@ -15254,16 +13563,16 @@ rb_reg_fragment_setenc(struct parser_params* p, VALUE str, int options)
c = 'n';
goto error;
}
- rb_enc_associate(str, rb_ascii8bit_encoding());
+ rb_enc_associate(str, rb_ascii8bit_encoding());
}
else if (rb_is_usascii_enc(p->enc)) {
- if (!is_ascii_string(str)) {
- /* raise in re.c */
- rb_enc_associate(str, rb_usascii_encoding());
- }
- else {
- rb_enc_associate(str, rb_ascii8bit_encoding());
- }
+ if (!is_ascii_string(str)) {
+ /* raise in re.c */
+ rb_enc_associate(str, rb_usascii_encoding());
+ }
+ else {
+ rb_enc_associate(str, rb_ascii8bit_encoding());
+ }
}
return 0;
@@ -15287,12 +13596,11 @@ reg_fragment_check(struct parser_params* p, VALUE str, int options)
if (err != Qnil) {
err = rb_obj_as_string(err);
compile_error(p, "%"PRIsVALUE, err);
- return 0;
+ return 0;
}
return 1;
}
-#ifndef UNIVERSAL_PARSER
typedef struct {
struct parser_params* parser;
rb_encoding *enc;
@@ -15309,8 +13617,23 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
rb_encoding *enc = arg->enc;
long len = name_end - name;
const char *s = (const char *)name;
+ ID var;
+ NODE *node, *succ;
- return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, arg->loc);
+ if (!len) return ST_CONTINUE;
+ if (rb_enc_symname_type(s, len, enc, (1U<<ID_LOCAL)) != ID_LOCAL)
+ return ST_CONTINUE;
+
+ var = intern_cstr(s, len, enc);
+ if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) {
+ if (!lvar_defined(p, var)) return ST_CONTINUE;
+ }
+ node = node_assign(p, assignable(p, var, 0, arg->loc), NEW_LIT(ID2SYM(var), arg->loc), NO_LEX_CTXT, arg->loc);
+ succ = arg->succ_block;
+ if (!succ) succ = NEW_BEGIN(0, arg->loc);
+ succ = block_append(p, succ, node);
+ arg->succ_block = succ;
+ return ST_CONTINUE;
}
static NODE *
@@ -15325,31 +13648,7 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *l
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
if (!arg.succ_block) return 0;
- return RNODE_BLOCK(arg.succ_block)->nd_next;
-}
-#endif
-
-int
-rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len,
- rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc)
-{
- ID var;
- NODE *node, *succ;
-
- if (!len) return ST_CONTINUE;
- if (!VALID_SYMNAME_P(s, len, enc, ID_LOCAL))
- return ST_CONTINUE;
-
- var = intern_cstr(s, len, enc);
- if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) {
- if (!lvar_defined(p, var)) return ST_CONTINUE;
- }
- node = node_assign(p, assignable(p, var, 0, loc), NEW_LIT(ID2SYM(var), loc), NO_LEX_CTXT, loc);
- succ = *succ_block;
- if (!succ) succ = NEW_ERROR(loc);
- succ = block_append(p, succ, node);
- *succ_block = succ;
- return ST_CONTINUE;
+ return arg.succ_block->nd_next;
}
static VALUE
@@ -15374,10 +13673,10 @@ reg_compile(struct parser_params* p, VALUE str, int options)
err = rb_errinfo();
re = parser_reg_compile(p, str, options);
if (NIL_P(re)) {
- VALUE m = rb_attr_get(rb_errinfo(), idMesg);
- rb_set_errinfo(err);
- compile_error(p, "%"PRIsVALUE, m);
- return Qnil;
+ VALUE m = rb_attr_get(rb_errinfo(), idMesg);
+ rb_set_errinfo(err);
+ compile_error(p, "%"PRIsVALUE, m);
+ return Qnil;
}
return re;
}
@@ -15387,13 +13686,13 @@ parser_reg_compile(struct parser_params* p, VALUE str, int options, VALUE *errms
{
VALUE err = rb_errinfo();
VALUE re;
- str = ripper_is_node_yylval(p, str) ? RNODE_RIPPER(str)->nd_cval : str;
+ str = ripper_is_node_yylval(str) ? RNODE(str)->nd_cval : str;
int c = rb_reg_fragment_setenc(p, str, options);
if (c) reg_fragment_enc_error(p, str, c);
re = rb_parser_reg_compile(p, str, options);
if (NIL_P(re)) {
- *errmsg = rb_attr_get(rb_errinfo(), idMesg);
- rb_set_errinfo(err);
+ *errmsg = rb_attr_get(rb_errinfo(), idMesg);
+ rb_set_errinfo(err);
}
return re;
}
@@ -15401,8 +13700,10 @@ parser_reg_compile(struct parser_params* p, VALUE str, int options, VALUE *errms
#ifndef RIPPER
void
-rb_ruby_parser_set_options(struct parser_params *p, int print, int loop, int chomp, int split)
+rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
{
+ struct parser_params *p;
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
p->do_print = print;
p->do_loop = loop;
p->do_chomp = chomp;
@@ -15416,32 +13717,32 @@ parser_append_options(struct parser_params *p, NODE *node)
const YYLTYPE *const LOC = &default_location;
if (p->do_print) {
- NODE *print = (NODE *)NEW_FCALL(rb_intern("print"),
- NEW_LIST(NEW_GVAR(idLASTLINE, LOC), LOC),
- LOC);
- node = block_append(p, node, print);
+ NODE *print = NEW_FCALL(rb_intern("print"),
+ NEW_LIST(NEW_GVAR(idLASTLINE, LOC), LOC),
+ LOC);
+ node = block_append(p, node, print);
}
if (p->do_loop) {
- NODE *irs = NEW_LIST(NEW_GVAR(rb_intern("$/"), LOC), LOC);
-
- if (p->do_split) {
- ID ifs = rb_intern("$;");
- ID fields = rb_intern("$F");
- NODE *args = NEW_LIST(NEW_GVAR(ifs, LOC), LOC);
- NODE *split = NEW_GASGN(fields,
- NEW_CALL(NEW_GVAR(idLASTLINE, LOC),
- rb_intern("split"), args, LOC),
- LOC);
- node = block_append(p, split, node);
- }
- if (p->do_chomp) {
- NODE *chomp = NEW_LIT(ID2SYM(rb_intern("chomp")), LOC);
- chomp = list_append(p, NEW_LIST(chomp, LOC), NEW_TRUE(LOC));
- irs = list_append(p, irs, NEW_HASH(chomp, LOC));
- }
-
- node = NEW_WHILE((NODE *)NEW_FCALL(idGets, irs, LOC), node, 1, LOC);
+ NODE *irs = NEW_LIST(NEW_GVAR(rb_intern("$/"), LOC), LOC);
+
+ if (p->do_split) {
+ ID ifs = rb_intern("$;");
+ ID fields = rb_intern("$F");
+ NODE *args = NEW_LIST(NEW_GVAR(ifs, LOC), LOC);
+ NODE *split = NEW_GASGN(fields,
+ NEW_CALL(NEW_GVAR(idLASTLINE, LOC),
+ rb_intern("split"), args, LOC),
+ LOC);
+ node = block_append(p, split, node);
+ }
+ if (p->do_chomp) {
+ NODE *chomp = NEW_LIT(ID2SYM(rb_intern("chomp")), LOC);
+ chomp = list_append(p, NEW_LIST(chomp, LOC), NEW_TRUE(LOC));
+ irs = list_append(p, irs, NEW_HASH(chomp, LOC));
+ }
+
+ node = NEW_WHILE(NEW_FCALL(idGets, irs, LOC), node, 1, LOC);
}
return node;
@@ -15471,7 +13772,6 @@ parser_initialize(struct parser_params *p)
p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE at first */
p->node_id = 0;
p->delayed.token = Qnil;
- p->frozen_string_literal = -1; /* not specified */
#ifdef RIPPER
p->result = Qnil;
p->parsing_thread = Qnil;
@@ -15484,17 +13784,15 @@ parser_initialize(struct parser_params *p)
p->debug_buffer = Qnil;
p->debug_output = rb_ractor_stdout();
p->enc = rb_utf8_encoding();
- p->exits = 0;
}
#ifdef RIPPER
-#define rb_ruby_parser_mark ripper_parser_mark
-#define rb_ruby_parser_free ripper_parser_free
-#define rb_ruby_parser_memsize ripper_parser_memsize
+#define parser_mark ripper_parser_mark
+#define parser_free ripper_parser_free
#endif
-void
-rb_ruby_parser_mark(void *ptr)
+static void
+parser_mark(void *ptr)
{
struct parser_params *p = (struct parser_params*)ptr;
@@ -15502,11 +13800,13 @@ rb_ruby_parser_mark(void *ptr)
rb_gc_mark(p->lex.lastline);
rb_gc_mark(p->lex.nextline);
rb_gc_mark(p->ruby_sourcefile_string);
+ rb_gc_mark((VALUE)p->lex.strterm);
rb_gc_mark((VALUE)p->ast);
rb_gc_mark(p->case_labels);
rb_gc_mark(p->delayed.token);
#ifndef RIPPER
rb_gc_mark(p->debug_lines);
+ rb_gc_mark(p->compile_option);
rb_gc_mark(p->error_buffer);
rb_gc_mark(p->end_expect_token_locations);
rb_gc_mark(p->tokens);
@@ -15522,14 +13822,11 @@ rb_ruby_parser_mark(void *ptr)
#endif
}
-void
-rb_ruby_parser_free(void *ptr)
+static void
+parser_free(void *ptr)
{
struct parser_params *p = (struct parser_params*)ptr;
struct local_vars *local, *prev;
-#ifdef UNIVERSAL_PARSER
- rb_parser_config_t *config = p->config;
-#endif
if (p->tokenbuf) {
ruby_sized_xfree(p->tokenbuf, p->toksiz);
@@ -15545,20 +13842,13 @@ rb_ruby_parser_free(void *ptr)
while ((ptinfo = p->token_info) != 0) {
p->token_info = ptinfo->next;
xfree(ptinfo);
- }
+ }
}
xfree(ptr);
-
-#ifdef UNIVERSAL_PARSER
- config->counter--;
- if (config->counter <= 0) {
- rb_ruby_parser_config_free(config);
- }
-#endif
}
-size_t
-rb_ruby_parser_memsize(const void *ptr)
+static size_t
+parser_memsize(const void *ptr)
{
struct parser_params *p = (struct parser_params*)ptr;
struct local_vars *local;
@@ -15566,39 +13856,25 @@ rb_ruby_parser_memsize(const void *ptr)
size += p->toksiz;
for (local = p->lvtbl; local; local = local->prev) {
- size += sizeof(*local);
- if (local->vars) size += local->vars->capa * sizeof(ID);
+ size += sizeof(*local);
+ if (local->vars) size += local->vars->capa * sizeof(ID);
}
return size;
}
-#ifdef UNIVERSAL_PARSER
-rb_parser_config_t *
-rb_ruby_parser_config_new(void *(*malloc)(size_t size))
-{
- return (rb_parser_config_t *)malloc(sizeof(rb_parser_config_t));
-}
-
-void
-rb_ruby_parser_config_free(rb_parser_config_t *config)
-{
- config->free(config);
-}
-#endif
-
-#ifndef UNIVERSAL_PARSER
-#ifndef RIPPER
static const rb_data_type_t parser_data_type = {
+#ifndef RIPPER
"parser",
+#else
+ "ripper",
+#endif
{
- rb_ruby_parser_mark,
- rb_ruby_parser_free,
- rb_ruby_parser_memsize,
+ parser_mark,
+ parser_free,
+ parser_memsize,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
-#endif
-#endif
#ifndef RIPPER
#undef rb_reserved_word
@@ -15609,361 +13885,180 @@ rb_reserved_word(const char *str, unsigned int len)
return reserved_word(str, len);
}
-#ifdef UNIVERSAL_PARSER
-rb_parser_t *
-rb_ruby_parser_allocate(rb_parser_config_t *config)
-{
- /* parser_initialize expects fields to be set to 0 */
- rb_parser_t *p = (rb_parser_t *)config->calloc(1, sizeof(rb_parser_t));
- p->config = config;
- p->config->counter++;
- return p;
-}
-
-rb_parser_t *
-rb_ruby_parser_new(rb_parser_config_t *config)
+VALUE
+rb_parser_new(void)
{
- /* parser_initialize expects fields to be set to 0 */
- rb_parser_t *p = rb_ruby_parser_allocate(config);
+ struct parser_params *p;
+ VALUE parser = TypedData_Make_Struct(0, struct parser_params,
+ &parser_data_type, p);
parser_initialize(p);
- return p;
+ return parser;
}
-#endif
-rb_parser_t *
-rb_ruby_parser_set_context(rb_parser_t *p, const struct rb_iseq_struct *base, int main)
+VALUE
+rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
p->error_buffer = main ? Qfalse : Qnil;
p->parent_iseq = base;
- return p;
-}
-
-void
-rb_ruby_parser_set_script_lines(rb_parser_t *p, VALUE lines)
-{
- if (!RTEST(lines)) {
- lines = Qfalse;
- }
- else if (lines == Qtrue) {
- lines = rb_ary_new();
- }
- else {
- Check_Type(lines, T_ARRAY);
- rb_ary_modify(lines);
- }
- p->debug_lines = lines;
-}
-
-void
-rb_ruby_parser_error_tolerant(rb_parser_t *p)
-{
- p->error_tolerant = 1;
- // TODO
- p->end_expect_token_locations = rb_ary_new();
+ return vparser;
}
void
-rb_ruby_parser_keep_tokens(rb_parser_t *p)
-{
- p->keep_tokens = 1;
- // TODO
- p->tokens = rb_ary_new();
-}
-
-#ifndef UNIVERSAL_PARSER
-rb_ast_t*
-rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
+rb_parser_keep_script_lines(VALUE vparser)
{
struct parser_params *p;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- RB_GC_GUARD(vparser); /* prohibit tail call optimization */
- return rb_ruby_parser_compile_file_path(p, fname, file, start);
+ p->keep_script_lines = 1;
}
-rb_ast_t*
-rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start)
+void
+rb_parser_error_tolerant(VALUE vparser)
{
struct parser_params *p;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- RB_GC_GUARD(vparser); /* prohibit tail call optimization */
- return rb_ruby_parser_compile_generic(p, lex_gets, fname, input, start);
+ p->error_tolerant = 1;
+ p->end_expect_token_locations = rb_ary_new();
}
-rb_ast_t*
-rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
+void
+rb_parser_keep_tokens(VALUE vparser)
{
struct parser_params *p;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- RB_GC_GUARD(vparser); /* prohibit tail call optimization */
- return rb_ruby_parser_compile_string(p, f, s, line);
+ p->keep_tokens = 1;
+ p->tokens = rb_ary_new();
}
-rb_ast_t*
-rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
-{
- struct parser_params *p;
+#endif
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- RB_GC_GUARD(vparser); /* prohibit tail call optimization */
- return rb_ruby_parser_compile_string_path(p, f, s, line);
-}
+#ifdef RIPPER
+#define rb_parser_end_seen_p ripper_parser_end_seen_p
+#define rb_parser_encoding ripper_parser_encoding
+#define rb_parser_get_yydebug ripper_parser_get_yydebug
+#define rb_parser_set_yydebug ripper_parser_set_yydebug
+#define rb_parser_get_debug_output ripper_parser_get_debug_output
+#define rb_parser_set_debug_output ripper_parser_set_debug_output
+static VALUE ripper_parser_end_seen_p(VALUE vparser);
+static VALUE ripper_parser_encoding(VALUE vparser);
+static VALUE ripper_parser_get_yydebug(VALUE self);
+static VALUE ripper_parser_set_yydebug(VALUE self, VALUE flag);
+static VALUE ripper_parser_get_debug_output(VALUE self);
+static VALUE ripper_parser_set_debug_output(VALUE self, VALUE output);
-VALUE
-rb_parser_encoding(VALUE vparser)
+/*
+ * call-seq:
+ * ripper.error? -> Boolean
+ *
+ * Return true if parsed source has errors.
+ */
+static VALUE
+ripper_error_p(VALUE vparser)
{
struct parser_params *p;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- return rb_ruby_parser_encoding(p);
+ return RBOOL(p->error_p);
}
+#endif
+/*
+ * call-seq:
+ * ripper.end_seen? -> Boolean
+ *
+ * Return true if parsed source ended by +\_\_END\_\_+.
+ */
VALUE
rb_parser_end_seen_p(VALUE vparser)
{
struct parser_params *p;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- return RBOOL(rb_ruby_parser_end_seen_p(p));
-}
-
-void
-rb_parser_error_tolerant(VALUE vparser)
-{
- struct parser_params *p;
-
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- rb_ruby_parser_error_tolerant(p);
-}
-
-void
-rb_parser_set_script_lines(VALUE vparser, VALUE lines)
-{
- struct parser_params *p;
-
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- rb_ruby_parser_set_script_lines(p, lines);
-}
-
-void
-rb_parser_keep_tokens(VALUE vparser)
-{
- struct parser_params *p;
-
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- rb_ruby_parser_keep_tokens(p);
-}
-
-VALUE
-rb_parser_new(void)
-{
- struct parser_params *p;
- VALUE parser = TypedData_Make_Struct(0, struct parser_params,
- &parser_data_type, p);
- parser_initialize(p);
- return parser;
+ return RBOOL(p->ruby__end__seen);
}
+/*
+ * call-seq:
+ * ripper.encoding -> encoding
+ *
+ * Return encoding of the source.
+ */
VALUE
-rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
+rb_parser_encoding(VALUE vparser)
{
struct parser_params *p;
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- rb_ruby_parser_set_context(p, base, main);
- return vparser;
+ return rb_enc_from_encoding(p->enc);
}
-void
-rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
+#ifdef RIPPER
+/*
+ * call-seq:
+ * ripper.yydebug -> true or false
+ *
+ * Get yydebug.
+ */
+VALUE
+rb_parser_get_yydebug(VALUE self)
{
struct parser_params *p;
- TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
- rb_ruby_parser_set_options(p, print, loop, chomp, split);
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ return RBOOL(p->debug);
}
+#endif
+/*
+ * call-seq:
+ * ripper.yydebug = flag
+ *
+ * Set yydebug.
+ */
VALUE
rb_parser_set_yydebug(VALUE self, VALUE flag)
{
struct parser_params *p;
TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
- rb_ruby_parser_set_yydebug(p, RTEST(flag));
+ p->debug = RTEST(flag);
return flag;
}
-#endif /* !UNIVERSAL_PARSER */
+/*
+ * call-seq:
+ * ripper.debug_output -> obj
+ *
+ * Get debug output.
+ */
VALUE
-rb_ruby_parser_encoding(rb_parser_t *p)
-{
- return rb_enc_from_encoding(p->enc);
-}
-
-int
-rb_ruby_parser_end_seen_p(rb_parser_t *p)
-{
- return p->ruby__end__seen;
-}
-
-int
-rb_ruby_parser_set_yydebug(rb_parser_t *p, int flag)
-{
- p->debug = flag;
- return flag;
-}
-#endif /* !RIPPER */
-
-#ifdef RIPPER
-int
-rb_ruby_parser_get_yydebug(rb_parser_t *p)
+rb_parser_get_debug_output(VALUE self)
{
- return p->debug;
-}
-
-void
-rb_ruby_parser_set_value(rb_parser_t *p, VALUE value)
-{
- p->value = value;
-}
-
-int
-rb_ruby_parser_error_p(rb_parser_t *p)
-{
- return p->error_p;
-}
+ struct parser_params *p;
-VALUE
-rb_ruby_parser_debug_output(rb_parser_t *p)
-{
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
return p->debug_output;
}
-void
-rb_ruby_parser_set_debug_output(rb_parser_t *p, VALUE output)
-{
- p->debug_output = output;
-}
-
-VALUE
-rb_ruby_parser_parsing_thread(rb_parser_t *p)
-{
- return p->parsing_thread;
-}
-
-void
-rb_ruby_parser_set_parsing_thread(rb_parser_t *p, VALUE parsing_thread)
-{
- p->parsing_thread = parsing_thread;
-}
-
-void
-rb_ruby_parser_ripper_initialize(rb_parser_t *p, VALUE (*gets)(struct parser_params*,VALUE), VALUE input, VALUE sourcefile_string, const char *sourcefile, int sourceline)
-{
- p->lex.gets = gets;
- p->lex.input = input;
- p->eofp = 0;
- p->ruby_sourcefile_string = sourcefile_string;
- p->ruby_sourcefile = sourcefile;
- p->ruby_sourceline = sourceline;
-}
-
-VALUE
-rb_ruby_parser_result(rb_parser_t *p)
-{
- return p->result;
-}
-
-rb_encoding *
-rb_ruby_parser_enc(rb_parser_t *p)
-{
- return p->enc;
-}
-
-VALUE
-rb_ruby_parser_ruby_sourcefile_string(rb_parser_t *p)
-{
- return p->ruby_sourcefile_string;
-}
-
-int
-rb_ruby_parser_ruby_sourceline(rb_parser_t *p)
-{
- return p->ruby_sourceline;
-}
-
-int
-rb_ruby_parser_lex_state(rb_parser_t *p)
-{
- return p->lex.state;
-}
-
-void
-rb_ruby_ripper_parse0(rb_parser_t *p)
-{
- parser_prepare(p);
- p->ast = rb_ast_new();
- ripper_yyparse((void*)p);
- rb_ast_dispose(p->ast);
- p->ast = 0;
-}
-
-int
-rb_ruby_ripper_dedent_string(rb_parser_t *p, VALUE string, int width)
-{
- return dedent_string(p, string, width);
-}
-
-VALUE
-rb_ruby_ripper_lex_get_str(rb_parser_t *p, VALUE s)
-{
- return lex_get_str(p, s);
-}
-
-int
-rb_ruby_ripper_initialized_p(rb_parser_t *p)
-{
- return p->lex.input != 0;
-}
-
-void
-rb_ruby_ripper_parser_initialize(rb_parser_t *p)
-{
- parser_initialize(p);
-}
-
-long
-rb_ruby_ripper_column(rb_parser_t *p)
-{
- return p->lex.ptok - p->lex.pbeg;
-}
-
-long
-rb_ruby_ripper_token_len(rb_parser_t *p)
-{
- return p->lex.pcur - p->lex.ptok;
-}
-
-VALUE
-rb_ruby_ripper_lex_lastline(rb_parser_t *p)
-{
- return p->lex.lastline;
-}
-
+/*
+ * call-seq:
+ * ripper.debug_output = obj
+ *
+ * Set debug output.
+ */
VALUE
-rb_ruby_ripper_lex_state_name(struct parser_params *p, int state)
+rb_parser_set_debug_output(VALUE self, VALUE output)
{
- return rb_parser_lex_state_name(p, (enum lex_state_e)state);
-}
+ struct parser_params *p;
-struct parser_params*
-rb_ruby_ripper_parser_allocate(void)
-{
- return (struct parser_params *)ruby_xcalloc(1, sizeof(struct parser_params));
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ return p->debug_output = output;
}
-#endif /* RIPPER */
#ifndef RIPPER
#ifdef YYMALLOC
@@ -15972,7 +14067,7 @@ rb_ruby_ripper_parser_allocate(void)
* potential memory leak */
#define NEWHEAP() rb_imemo_tmpbuf_parser_heap(0, p->heap, 0)
#define ADD2HEAP(new, cnt, ptr) ((p->heap = (new))->ptr = (ptr), \
- (new)->cnt = (cnt), (ptr))
+ (new)->cnt = (cnt), (ptr))
void *
rb_parser_malloc(struct parser_params *p, size_t size)
@@ -16001,13 +14096,13 @@ rb_parser_realloc(struct parser_params *p, void *ptr, size_t size)
size_t cnt = HEAPCNT(1, size);
if (ptr && (n = p->heap) != NULL) {
- do {
- if (n->ptr == ptr) {
- n->ptr = ptr = xrealloc(ptr, size);
- if (n->cnt) n->cnt = cnt;
- return ptr;
- }
- } while ((n = n->next) != NULL);
+ do {
+ if (n->ptr == ptr) {
+ n->ptr = ptr = xrealloc(ptr, size);
+ if (n->cnt) n->cnt = cnt;
+ return ptr;
+ }
+ } while ((n = n->next) != NULL);
}
n = NEWHEAP();
ptr = xrealloc(ptr, size);
@@ -16020,11 +14115,11 @@ rb_parser_free(struct parser_params *p, void *ptr)
rb_imemo_tmpbuf_t **prev = &p->heap, *n;
while ((n = *prev) != NULL) {
- if (n->ptr == ptr) {
- *prev = n->next;
- break;
- }
- prev = &n->next;
+ if (n->ptr == ptr) {
+ *prev = n->next;
+ break;
+ }
+ prev = &n->next;
}
}
#endif
@@ -16039,35 +14134,26 @@ rb_parser_printf(struct parser_params *p, const char *fmt, ...)
va_start(ap, fmt);
rb_str_vcatf(mesg, fmt, ap);
va_end(ap);
- if (end_with_newline_p(p, mesg)) {
- rb_io_write(p->debug_output, mesg);
- p->debug_buffer = Qnil;
+ if (RSTRING_END(mesg)[-1] == '\n') {
+ rb_io_write(p->debug_output, mesg);
+ p->debug_buffer = Qnil;
}
}
static void
-parser_compile_error(struct parser_params *p, const rb_code_location_t *loc, const char *fmt, ...)
+parser_compile_error(struct parser_params *p, const char *fmt, ...)
{
va_list ap;
- int lineno, column;
-
- if (loc) {
- lineno = loc->end_pos.lineno;
- column = loc->end_pos.column;
- }
- else {
- lineno = p->ruby_sourceline;
- column = rb_long2int(p->lex.pcur - p->lex.pbeg);
- }
rb_io_flush(p->debug_output);
p->error_p = 1;
va_start(ap, fmt);
p->error_buffer =
- rb_syntax_error_append(p->error_buffer,
- p->ruby_sourcefile_string,
- lineno, column,
- p->enc, fmt, ap);
+ rb_syntax_error_append(p->error_buffer,
+ p->ruby_sourcefile_string,
+ p->ruby_sourceline,
+ rb_long2int(p->lex.pcur - p->lex.pbeg),
+ p->enc, fmt, ap);
va_end(ap);
}
@@ -16089,58 +14175,58 @@ RUBY_FUNC_EXPORTED size_t
rb_yytnamerr(struct parser_params *p, char *yyres, const char *yystr)
{
if (*yystr == '"') {
- size_t yyn = 0, bquote = 0;
- const char *yyp = yystr;
-
- while (*++yyp) {
- switch (*yyp) {
- case '`':
- if (!bquote) {
- bquote = count_char(yyp+1, '`') + 1;
- if (yyres) memcpy(&yyres[yyn], yyp, bquote);
- yyn += bquote;
- yyp += bquote - 1;
- break;
- }
- goto default_char;
-
- case '\'':
- if (bquote && count_char(yyp+1, '\'') + 1 == bquote) {
- if (yyres) memcpy(yyres + yyn, yyp, bquote);
- yyn += bquote;
- yyp += bquote - 1;
- bquote = 0;
- break;
- }
- if (yyp[1] && yyp[1] != '\'' && yyp[2] == '\'') {
- if (yyres) memcpy(yyres + yyn, yyp, 3);
- yyn += 3;
- yyp += 2;
- break;
- }
- goto do_not_strip_quotes;
-
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default_char:
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- case '\0':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- }
+ size_t yyn = 0, bquote = 0;
+ const char *yyp = yystr;
+
+ while (*++yyp) {
+ switch (*yyp) {
+ case '`':
+ if (!bquote) {
+ bquote = count_char(yyp+1, '`') + 1;
+ if (yyres) memcpy(&yyres[yyn], yyp, bquote);
+ yyn += bquote;
+ yyp += bquote - 1;
+ break;
+ }
+ goto default_char;
+
+ case '\'':
+ if (bquote && count_char(yyp+1, '\'') + 1 == bquote) {
+ if (yyres) memcpy(yyres + yyn, yyp, bquote);
+ yyn += bquote;
+ yyp += bquote - 1;
+ bquote = 0;
+ break;
+ }
+ if (yyp[1] && yyp[1] != '\'' && yyp[2] == '\'') {
+ if (yyres) memcpy(yyres + yyn, yyp, 3);
+ yyn += 3;
+ yyp += 2;
+ break;
+ }
+ goto do_not_strip_quotes;
+
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default_char:
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ case '\0':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ }
do_not_strip_quotes: ;
}
@@ -16160,7 +14246,7 @@ ripper_validate_object(VALUE self, VALUE x)
if (x == Qtrue) return x;
if (NIL_P(x)) return x;
if (UNDEF_P(x))
- rb_raise(rb_eArgError, "Qundef given");
+ rb_raise(rb_eArgError, "Qundef given");
if (FIXNUM_P(x)) return x;
if (SYMBOL_P(x)) return x;
switch (BUILTIN_TYPE(x)) {
@@ -16171,20 +14257,20 @@ ripper_validate_object(VALUE self, VALUE x)
case T_FLOAT:
case T_COMPLEX:
case T_RATIONAL:
- break;
+ break;
case T_NODE:
- if (!nd_type_p((NODE *)x, NODE_RIPPER)) {
- rb_raise(rb_eArgError, "NODE given: %p", (void *)x);
- }
- x = ((NODE *)x)->nd_rval;
- break;
+ if (!nd_type_p((NODE *)x, NODE_RIPPER)) {
+ rb_raise(rb_eArgError, "NODE given: %p", (void *)x);
+ }
+ x = ((NODE *)x)->nd_rval;
+ break;
default:
- rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
- (void *)x, rb_obj_classname(x));
+ rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
+ (void *)x, rb_obj_classname(x));
}
if (!RBASIC_CLASS(x)) {
- rb_raise(rb_eArgError, "hidden ruby object: %p (%s)",
- (void *)x, rb_builtin_type_name(TYPE(x)));
+ rb_raise(rb_eArgError, "hidden ruby object: %p (%s)",
+ (void *)x, rb_builtin_type_name(TYPE(x)));
}
return x;
}
@@ -16256,21 +14342,377 @@ ripper_dispatch7(struct parser_params *p, ID mid, VALUE a, VALUE b, VALUE c, VAL
return rb_funcall(p->value, mid, 7, a, b, c, d, e, f, g);
}
-void
+static ID
+ripper_get_id(VALUE v)
+{
+ NODE *nd;
+ if (!RB_TYPE_P(v, T_NODE)) return 0;
+ nd = (NODE *)v;
+ if (!nd_type_p(nd, NODE_RIPPER)) return 0;
+ return nd->nd_vid;
+}
+
+static VALUE
+ripper_get_value(VALUE v)
+{
+ NODE *nd;
+ if (UNDEF_P(v)) return Qnil;
+ if (!RB_TYPE_P(v, T_NODE)) return v;
+ nd = (NODE *)v;
+ if (!nd_type_p(nd, NODE_RIPPER)) return Qnil;
+ return nd->nd_rval;
+}
+
+static void
ripper_error(struct parser_params *p)
{
p->error_p = TRUE;
}
-VALUE
-ripper_value(struct parser_params *p)
+static void
+ripper_compile_error(struct parser_params *p, const char *fmt, ...)
+{
+ VALUE str;
+ va_list args;
+
+ va_start(args, fmt);
+ str = rb_vsprintf(fmt, args);
+ va_end(args);
+ rb_funcall(p->value, rb_intern("compile_error"), 1, str);
+ ripper_error(p);
+}
+
+static VALUE
+ripper_lex_get_generic(struct parser_params *p, VALUE src)
{
+ VALUE line = rb_funcallv_public(src, id_gets, 0, 0);
+ if (!NIL_P(line) && !RB_TYPE_P(line, T_STRING)) {
+ rb_raise(rb_eTypeError,
+ "gets returned %"PRIsVALUE" (expected String or nil)",
+ rb_obj_class(line));
+ }
+ return line;
+}
+
+static VALUE
+ripper_lex_io_get(struct parser_params *p, VALUE src)
+{
+ return rb_io_gets(src);
+}
+
+static VALUE
+ripper_s_allocate(VALUE klass)
+{
+ struct parser_params *p;
+ VALUE self = TypedData_Make_Struct(klass, struct parser_params,
+ &parser_data_type, p);
+ p->value = self;
+ return self;
+}
+
+#define ripper_initialized_p(r) ((r)->lex.input != 0)
+
+/*
+ * call-seq:
+ * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
+ *
+ * Create a new Ripper object.
+ * _src_ must be a String, an IO, or an Object which has #gets method.
+ *
+ * This method does not starts parsing.
+ * See also Ripper#parse and Ripper.parse.
+ */
+static VALUE
+ripper_initialize(int argc, VALUE *argv, VALUE self)
+{
+ struct parser_params *p;
+ VALUE src, fname, lineno;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
+ if (RB_TYPE_P(src, T_FILE)) {
+ p->lex.gets = ripper_lex_io_get;
+ }
+ else if (rb_respond_to(src, id_gets)) {
+ p->lex.gets = ripper_lex_get_generic;
+ }
+ else {
+ StringValue(src);
+ p->lex.gets = lex_get_str;
+ }
+ p->lex.input = src;
+ p->eofp = 0;
+ if (NIL_P(fname)) {
+ fname = STR_NEW2("(ripper)");
+ OBJ_FREEZE(fname);
+ }
+ else {
+ StringValueCStr(fname);
+ fname = rb_str_new_frozen(fname);
+ }
+ parser_initialize(p);
+
+ p->ruby_sourcefile_string = fname;
+ p->ruby_sourcefile = RSTRING_PTR(fname);
+ p->ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
+
+ return Qnil;
+}
+
+static VALUE
+ripper_parse0(VALUE parser_v)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, p);
+ parser_prepare(p);
+ p->ast = rb_ast_new();
+ ripper_yyparse((void*)p);
+ rb_ast_dispose(p->ast);
+ p->ast = 0;
+ return p->result;
+}
+
+static VALUE
+ripper_ensure(VALUE parser_v)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, p);
+ p->parsing_thread = Qnil;
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * ripper.parse
+ *
+ * Start parsing and returns the value of the root action.
+ */
+static VALUE
+ripper_parse(VALUE self)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ if (!NIL_P(p->parsing_thread)) {
+ if (p->parsing_thread == rb_thread_current())
+ rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
+ else
+ rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
+ }
+ p->parsing_thread = rb_thread_current();
+ rb_ensure(ripper_parse0, self, ripper_ensure, self);
+
+ return p->result;
+}
+
+/*
+ * call-seq:
+ * ripper.column -> Integer
+ *
+ * Return column number of current parsing line.
+ * This number starts from 0.
+ */
+static VALUE
+ripper_column(VALUE self)
+{
+ struct parser_params *p;
+ long col;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ col = p->lex.ptok - p->lex.pbeg;
+ return LONG2NUM(col);
+}
+
+/*
+ * call-seq:
+ * ripper.filename -> String
+ *
+ * Return current parsing filename.
+ */
+static VALUE
+ripper_filename(VALUE self)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ return p->ruby_sourcefile_string;
+}
+
+/*
+ * call-seq:
+ * ripper.lineno -> Integer
+ *
+ * Return line number of current parsing line.
+ * This number starts from 1.
+ */
+static VALUE
+ripper_lineno(VALUE self)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ return INT2NUM(p->ruby_sourceline);
+}
+
+/*
+ * call-seq:
+ * ripper.state -> Integer
+ *
+ * Return scanner state of current token.
+ */
+static VALUE
+ripper_state(VALUE self)
+{
+ struct parser_params *p;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ return INT2NUM(p->lex.state);
+}
+
+/*
+ * call-seq:
+ * ripper.token -> String
+ *
+ * Return the current token string.
+ */
+static VALUE
+ripper_token(VALUE self)
+{
+ struct parser_params *p;
+ long pos, len;
+
+ TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p);
+ if (!ripper_initialized_p(p)) {
+ rb_raise(rb_eArgError, "method called for uninitialized object");
+ }
+ if (NIL_P(p->parsing_thread)) return Qnil;
+ pos = p->lex.ptok - p->lex.pbeg;
+ len = p->lex.pcur - p->lex.ptok;
+ return rb_str_subseq(p->lex.lastline, pos, len);
+}
+
+#ifdef RIPPER_DEBUG
+/* :nodoc: */
+static VALUE
+ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
+{
+ StringValue(msg);
+ if (UNDEF_P(obj)) {
+ rb_raise(rb_eArgError, "%"PRIsVALUE, msg);
+ }
+ return Qnil;
+}
+
+/* :nodoc: */
+static VALUE
+ripper_value(VALUE self, VALUE obj)
+{
+ return ULONG2NUM(obj);
+}
+#endif
+
+/*
+ * call-seq:
+ * Ripper.lex_state_name(integer) -> string
+ *
+ * Returns a string representation of lex_state.
+ */
+static VALUE
+ripper_lex_state_name(VALUE self, VALUE state)
+{
+ return rb_parser_lex_state_name(NUM2INT(state));
+}
+
+void
+Init_ripper(void)
+{
+ ripper_init_eventids1();
+ ripper_init_eventids2();
+ id_warn = rb_intern_const("warn");
+ id_warning = rb_intern_const("warning");
+ id_gets = rb_intern_const("gets");
+ id_assoc = rb_intern_const("=>");
+
(void)yystpcpy; /* may not used in newer bison */
- return p->value;
+ InitVM(ripper);
}
+void
+InitVM_ripper(void)
+{
+ VALUE Ripper;
+
+ Ripper = rb_define_class("Ripper", rb_cObject);
+ /* version of Ripper */
+ rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
+ rb_define_alloc_func(Ripper, ripper_s_allocate);
+ rb_define_method(Ripper, "initialize", ripper_initialize, -1);
+ rb_define_method(Ripper, "parse", ripper_parse, 0);
+ rb_define_method(Ripper, "column", ripper_column, 0);
+ rb_define_method(Ripper, "filename", ripper_filename, 0);
+ rb_define_method(Ripper, "lineno", ripper_lineno, 0);
+ rb_define_method(Ripper, "state", ripper_state, 0);
+ rb_define_method(Ripper, "token", ripper_token, 0);
+ rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
+ rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
+ rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
+ rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
+ rb_define_method(Ripper, "debug_output", rb_parser_get_debug_output, 0);
+ rb_define_method(Ripper, "debug_output=", rb_parser_set_debug_output, 1);
+ rb_define_method(Ripper, "error?", ripper_error_p, 0);
+#ifdef RIPPER_DEBUG
+ rb_define_method(Ripper, "assert_Qundef", ripper_assert_Qundef, 2);
+ rb_define_method(Ripper, "rawVALUE", ripper_value, 1);
+ rb_define_method(Ripper, "validate_object", ripper_validate_object, 1);
+#endif
+
+ rb_define_singleton_method(Ripper, "dedent_string", parser_dedent_string, 2);
+ rb_define_private_method(Ripper, "dedent_string", parser_dedent_string, 2);
+
+ rb_define_singleton_method(Ripper, "lex_state_name", ripper_lex_state_name, 1);
+
+<% @exprs.each do |expr, desc| -%>
+ /* <%=desc%> */
+ rb_define_const(Ripper, "<%=expr%>", INT2NUM(<%=expr%>));
+<% end %>
+ ripper_init_eventids1_table(Ripper);
+ ripper_init_eventids2_table(Ripper);
+
+# if 0
+ /* Hack to let RDoc document SCRIPT_LINES__ */
+
+ /*
+ * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
+ * after the assignment will be added as an Array of lines with the file
+ * name as the key.
+ */
+ rb_define_global_const("SCRIPT_LINES__", Qnil);
+#endif
+
+}
#endif /* RIPPER */
+
/*
* Local variables:
* mode: c
diff --git a/parser_bits.h b/parser_bits.h
deleted file mode 100644
index ca7535280e..0000000000
--- a/parser_bits.h
+++ /dev/null
@@ -1,564 +0,0 @@
-#ifndef INTERNAL_BITS2_H /*-*-C-*-vi:se ft=c:*/
-#define INTERNAL_BITS2_H
-/**
- * @author Ruby developers <ruby-core@ruby-lang.org>
- * @copyright This file is a part of the programming language Ruby.
- * Permission is hereby granted, to either redistribute and/or
- * modify this file, provided that the conditions mentioned in the
- * file COPYING are met. Consult the file for details.
- * @brief Internal header for bitwise integer algorithms.
- * @see Henry S. Warren Jr., "Hacker's Delight" (2nd ed.), 2013.
- * @see SEI CERT C Coding Standard INT32-C. "Ensure that operations on
- * signed integers do not result in overflow"
- * @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
- * @see https://clang.llvm.org/docs/LanguageExtensions.html#builtin-rotateleft
- * @see https://clang.llvm.org/docs/LanguageExtensions.html#builtin-rotateright
- * @see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/byteswap-uint64-byteswap-ulong-byteswap-ushort
- * @see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rotl-rotl64-rotr-rotr64
- * @see https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
- * @see https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64
- * @see https://docs.microsoft.com/en-us/cpp/intrinsics/lzcnt16-lzcnt-lzcnt64
- * @see https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64
- * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_lzcnt_u32
- * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_tzcnt_u32
- * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_rotl64
- * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_rotr64
- * @see https://stackoverflow.com/a/776523
- */
-#include "ruby/internal/config.h"
-#include <limits.h> /* for CHAR_BITS */
-#include <stdint.h> /* for uintptr_t */
-#include "internal/compilers.h" /* for MSC_VERSION_SINCE */
-
-#if MSC_VERSION_SINCE(1310)
-# include <stdlib.h> /* for _byteswap_uint64 */
-#endif
-
-#if defined(HAVE_X86INTRIN_H)
-# include <x86intrin.h> /* for _lzcnt_u64 */
-#elif MSC_VERSION_SINCE(1310)
-# include <intrin.h> /* for the following intrinsics */
-#endif
-
-#if defined(_MSC_VER) && defined(__AVX__)
-# pragma intrinsic(__popcnt)
-# pragma intrinsic(__popcnt64)
-#endif
-
-#if defined(_MSC_VER) && defined(__AVX2__)
-# pragma intrinsic(__lzcnt)
-# pragma intrinsic(__lzcnt64)
-#endif
-
-#if MSC_VERSION_SINCE(1310)
-# pragma intrinsic(_rotl)
-# pragma intrinsic(_rotr)
-# ifdef _WIN64
-# pragma intrinsic(_rotl64)
-# pragma intrinsic(_rotr64)
-# endif
-#endif
-
-#if MSC_VERSION_SINCE(1400)
-# pragma intrinsic(_BitScanForward)
-# pragma intrinsic(_BitScanReverse)
-# ifdef _WIN64
-# pragma intrinsic(_BitScanForward64)
-# pragma intrinsic(_BitScanReverse64)
-# endif
-#endif
-
-#include "parser_value.h" /* for VALUE */
-#include "internal/static_assert.h" /* for STATIC_ASSERT */
-
-/* The most significant bit of the lower part of half-long integer.
- * If sizeof(long) == 4, this is 0x8000.
- * If sizeof(long) == 8, this is 0x80000000.
- */
-#define HALF_LONG_MSB ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
-
-#define SIGNED_INTEGER_TYPE_P(T) (0 > ((T)0)-1)
-
-#define SIGNED_INTEGER_MIN(T) \
- ((sizeof(T) == sizeof(int8_t)) ? ((T)INT8_MIN) : \
- ((sizeof(T) == sizeof(int16_t)) ? ((T)INT16_MIN) : \
- ((sizeof(T) == sizeof(int32_t)) ? ((T)INT32_MIN) : \
- ((sizeof(T) == sizeof(int64_t)) ? ((T)INT64_MIN) : \
- 0))))
-
-#define SIGNED_INTEGER_MAX(T) ((T)(SIGNED_INTEGER_MIN(T) ^ ((T)~(T)0)))
-
-#define UNSIGNED_INTEGER_MAX(T) ((T)~(T)0)
-
-#if __has_builtin(__builtin_mul_overflow_p)
-# define MUL_OVERFLOW_P(a, b) \
- __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
-#elif __has_builtin(__builtin_mul_overflow)
-# define MUL_OVERFLOW_P(a, b) \
- __extension__ ({ __typeof__(a) c; __builtin_mul_overflow((a), (b), &c); })
-#endif
-
-#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
- (a) == 0 ? 0 : \
- (a) == -1 ? (b) < -(max) : \
- (a) > 0 ? \
- ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
- ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
-
-#if __has_builtin(__builtin_mul_overflow_p)
-/* __builtin_mul_overflow_p can take bitfield */
-/* and GCC permits bitfields for integers other than int */
-# define MUL_OVERFLOW_FIXNUM_P(a, b) \
- __extension__ ({ \
- struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \
- __builtin_mul_overflow_p((a), (b), c.fixnum); \
- })
-#else
-# define MUL_OVERFLOW_FIXNUM_P(a, b) \
- MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
-#endif
-
-#ifdef MUL_OVERFLOW_P
-# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
-# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
-# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b)
-#else
-# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
-# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
-# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
-#endif
-
-#ifdef HAVE_UINT128_T
-# define bit_length(x) \
- (unsigned int) \
- (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
- sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \
- 128 - nlz_int128((uint128_t)(x)))
-#else
-# define bit_length(x) \
- (unsigned int) \
- (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
- 64 - nlz_int64((uint64_t)(x)))
-#endif
-
-#ifndef swap16
-# define swap16 ruby_swap16
-#endif
-
-#ifndef swap32
-# define swap32 ruby_swap32
-#endif
-
-#ifndef swap64
-# define swap64 ruby_swap64
-#endif
-
-static inline uint16_t ruby_swap16(uint16_t);
-static inline uint32_t ruby_swap32(uint32_t);
-static inline uint64_t ruby_swap64(uint64_t);
-static inline unsigned nlz_int(unsigned x);
-static inline unsigned nlz_long(unsigned long x);
-static inline unsigned nlz_long_long(unsigned long long x);
-static inline unsigned nlz_intptr(uintptr_t x);
-static inline unsigned nlz_int32(uint32_t x);
-static inline unsigned nlz_int64(uint64_t x);
-#ifdef HAVE_UINT128_T
-static inline unsigned nlz_int128(uint128_t x);
-#endif
-static inline unsigned rb_popcount32(uint32_t x);
-static inline unsigned rb_popcount64(uint64_t x);
-static inline unsigned rb_popcount_intptr(uintptr_t x);
-static inline int ntz_int32(uint32_t x);
-static inline int ntz_int64(uint64_t x);
-static inline int ntz_intptr(uintptr_t x);
-static inline VALUE RUBY_BIT_ROTL(VALUE, int);
-static inline VALUE RUBY_BIT_ROTR(VALUE, int);
-
-static inline uint16_t
-ruby_swap16(uint16_t x)
-{
-#if __has_builtin(__builtin_bswap16)
- return __builtin_bswap16(x);
-
-#elif MSC_VERSION_SINCE(1310)
- return _byteswap_ushort(x);
-
-#else
- return (x << 8) | (x >> 8);
-
-#endif
-}
-
-static inline uint32_t
-ruby_swap32(uint32_t x)
-{
-#if __has_builtin(__builtin_bswap32)
- return __builtin_bswap32(x);
-
-#elif MSC_VERSION_SINCE(1310)
- return _byteswap_ulong(x);
-
-#else
- x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
- x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8);
- return x;
-
-#endif
-}
-
-static inline uint64_t
-ruby_swap64(uint64_t x)
-{
-#if __has_builtin(__builtin_bswap64)
- return __builtin_bswap64(x);
-
-#elif MSC_VERSION_SINCE(1310)
- return _byteswap_uint64(x);
-
-#else
- x = ((x & 0x00000000FFFFFFFFULL) << 32) | ((x & 0xFFFFFFFF00000000ULL) >> 32);
- x = ((x & 0x0000FFFF0000FFFFULL) << 16) | ((x & 0xFFFF0000FFFF0000ULL) >> 16);
- x = ((x & 0x00FF00FF00FF00FFULL) << 8) | ((x & 0xFF00FF00FF00FF00ULL) >> 8);
- return x;
-
-#endif
-}
-
-static inline unsigned int
-nlz_int32(uint32_t x)
-{
-#if defined(_MSC_VER) && defined(__AVX2__)
- /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC.
- * AMD CPUs have had this instruction for decades (since K10) but for
- * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum
- * safety. */
- return (unsigned int)__lzcnt(x);
-
-#elif defined(__x86_64__) && defined(__LZCNT__)
- return (unsigned int)_lzcnt_u32(x);
-
-#elif MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
- unsigned long r;
- return _BitScanReverse(&r, x) ? (31 - (int)r) : 32;
-
-#elif __has_builtin(__builtin_clz)
- STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
- return x ? (unsigned int)__builtin_clz(x) : 32;
-
-#else
- uint32_t y;
- unsigned n = 32;
- y = x >> 16; if (y) {n -= 16; x = y;}
- y = x >> 8; if (y) {n -= 8; x = y;}
- y = x >> 4; if (y) {n -= 4; x = y;}
- y = x >> 2; if (y) {n -= 2; x = y;}
- y = x >> 1; if (y) {return n - 2;}
- return (unsigned int)(n - x);
-#endif
-}
-
-static inline unsigned int
-nlz_int64(uint64_t x)
-{
-#if defined(_MSC_VER) && defined(__AVX2__)
- return (unsigned int)__lzcnt64(x);
-
-#elif defined(__x86_64__) && defined(__LZCNT__)
- return (unsigned int)_lzcnt_u64(x);
-
-#elif defined(_WIN64) && MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
- unsigned long r;
- return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
-
-#elif __has_builtin(__builtin_clzl)
- if (x == 0) {
- return 64;
- }
- else if (sizeof(long) * CHAR_BIT == 64) {
- return (unsigned int)__builtin_clzl((unsigned long)x);
- }
- else if (sizeof(long long) * CHAR_BIT == 64) {
- return (unsigned int)__builtin_clzll((unsigned long long)x);
- }
- else {
- /* :FIXME: Is there a way to make this branch a compile-time error? */
- UNREACHABLE_RETURN(~0);
- }
-
-#else
- uint64_t y;
- unsigned int n = 64;
- y = x >> 32; if (y) {n -= 32; x = y;}
- y = x >> 16; if (y) {n -= 16; x = y;}
- y = x >> 8; if (y) {n -= 8; x = y;}
- y = x >> 4; if (y) {n -= 4; x = y;}
- y = x >> 2; if (y) {n -= 2; x = y;}
- y = x >> 1; if (y) {return n - 2;}
- return (unsigned int)(n - x);
-
-#endif
-}
-
-#ifdef HAVE_UINT128_T
-static inline unsigned int
-nlz_int128(uint128_t x)
-{
- uint64_t y = (uint64_t)(x >> 64);
-
- if (x == 0) {
- return 128;
- }
- else if (y == 0) {
- return (unsigned int)nlz_int64(x) + 64;
- }
- else {
- return (unsigned int)nlz_int64(y);
- }
-}
-#endif
-
-static inline unsigned int
-nlz_int(unsigned int x)
-{
- if (sizeof(unsigned int) * CHAR_BIT == 32) {
- return nlz_int32((uint32_t)x);
- }
- else if (sizeof(unsigned int) * CHAR_BIT == 64) {
- return nlz_int64((uint64_t)x);
- }
- else {
- UNREACHABLE_RETURN(~0);
- }
-}
-
-static inline unsigned int
-nlz_long(unsigned long x)
-{
- if (sizeof(unsigned long) * CHAR_BIT == 32) {
- return nlz_int32((uint32_t)x);
- }
- else if (sizeof(unsigned long) * CHAR_BIT == 64) {
- return nlz_int64((uint64_t)x);
- }
- else {
- UNREACHABLE_RETURN(~0);
- }
-}
-
-static inline unsigned int
-nlz_long_long(unsigned long long x)
-{
- if (sizeof(unsigned long long) * CHAR_BIT == 64) {
- return nlz_int64((uint64_t)x);
- }
-#ifdef HAVE_UINT128_T
- else if (sizeof(unsigned long long) * CHAR_BIT == 128) {
- return nlz_int128((uint128_t)x);
- }
-#endif
- else {
- UNREACHABLE_RETURN(~0);
- }
-}
-
-static inline unsigned int
-nlz_intptr(uintptr_t x)
-{
- if (sizeof(uintptr_t) == sizeof(unsigned int)) {
- return nlz_int((unsigned int)x);
- }
- if (sizeof(uintptr_t) == sizeof(unsigned long)) {
- return nlz_long((unsigned long)x);
- }
- if (sizeof(uintptr_t) == sizeof(unsigned long long)) {
- return nlz_long_long((unsigned long long)x);
- }
- else {
- UNREACHABLE_RETURN(~0);
- }
-}
-
-static inline unsigned int
-rb_popcount32(uint32_t x)
-{
-#if defined(_MSC_VER) && defined(__AVX__)
- /* Note: CPUs since Nehalem and Barcelona have had this instruction so SSE
- * 4.2 should suffice, but it seems there is no such thing like __SSE_4_2__
- * predefined macro in MSVC. They do have __AVX__ so use it instead. */
- return (unsigned int)__popcnt(x);
-
-#elif __has_builtin(__builtin_popcount)
- STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT >= 32);
- return (unsigned int)__builtin_popcount(x);
-
-#else
- x = (x & 0x55555555) + (x >> 1 & 0x55555555);
- x = (x & 0x33333333) + (x >> 2 & 0x33333333);
- x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
- x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
- x = (x & 0x0000003f) + (x >>16 & 0x0000003f);
- return (unsigned int)x;
-
-#endif
-}
-
-static inline unsigned int
-rb_popcount64(uint64_t x)
-{
-#if defined(_MSC_VER) && defined(__AVX__)
- return (unsigned int)__popcnt64(x);
-
-#elif __has_builtin(__builtin_popcount)
- if (sizeof(long) * CHAR_BIT == 64) {
- return (unsigned int)__builtin_popcountl((unsigned long)x);
- }
- else if (sizeof(long long) * CHAR_BIT == 64) {
- return (unsigned int)__builtin_popcountll((unsigned long long)x);
- }
- else {
- /* :FIXME: Is there a way to make this branch a compile-time error? */
- UNREACHABLE_RETURN(~0);
- }
-
-#else
- x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
- x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
- x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
- x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
- x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
- x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f);
- return (unsigned int)x;
-
-#endif
-}
-
-static inline unsigned int
-rb_popcount_intptr(uintptr_t x)
-{
- if (sizeof(uintptr_t) * CHAR_BIT == 64) {
- return rb_popcount64((uint64_t)x);
- }
- else if (sizeof(uintptr_t) * CHAR_BIT == 32) {
- return rb_popcount32((uint32_t)x);
- }
- else {
- UNREACHABLE_RETURN(~0);
- }
-}
-
-static inline int
-ntz_int32(uint32_t x)
-{
-#if defined(__x86_64__) && defined(__BMI__)
- return (unsigned)_tzcnt_u32(x);
-
-#elif MSC_VERSION_SINCE(1400)
- /* :FIXME: Is there any way to issue TZCNT instead of BSF, apart from using
- * assembly? Because issuing LZCNT seems possible (see nlz.h). */
- unsigned long r;
- return _BitScanForward(&r, x) ? (int)r : 32;
-
-#elif __has_builtin(__builtin_ctz)
- STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
- return x ? (unsigned)__builtin_ctz(x) : 32;
-
-#else
- return rb_popcount32((~x) & (x-1));
-
-#endif
-}
-
-static inline int
-ntz_int64(uint64_t x)
-{
-#if defined(__x86_64__) && defined(__BMI__)
- return (unsigned)_tzcnt_u64(x);
-
-#elif defined(_WIN64) && MSC_VERSION_SINCE(1400)
- unsigned long r;
- return _BitScanForward64(&r, x) ? (int)r : 64;
-
-#elif __has_builtin(__builtin_ctzl)
- if (x == 0) {
- return 64;
- }
- else if (sizeof(long) * CHAR_BIT == 64) {
- return (unsigned)__builtin_ctzl((unsigned long)x);
- }
- else if (sizeof(long long) * CHAR_BIT == 64) {
- return (unsigned)__builtin_ctzll((unsigned long long)x);
- }
- else {
- /* :FIXME: Is there a way to make this branch a compile-time error? */
- UNREACHABLE_RETURN(~0);
- }
-
-#else
- return rb_popcount64((~x) & (x-1));
-
-#endif
-}
-
-static inline int
-ntz_intptr(uintptr_t x)
-{
- if (sizeof(uintptr_t) * CHAR_BIT == 64) {
- return ntz_int64((uint64_t)x);
- }
- else if (sizeof(uintptr_t) * CHAR_BIT == 32) {
- return ntz_int32((uint32_t)x);
- }
- else {
- UNREACHABLE_RETURN(~0);
- }
-}
-
-static inline VALUE
-RUBY_BIT_ROTL(VALUE v, int n)
-{
-#if __has_builtin(__builtin_rotateleft32) && (SIZEOF_VALUE * CHAR_BIT == 32)
- return __builtin_rotateleft32(v, n);
-
-#elif __has_builtin(__builtin_rotateleft64) && (SIZEOF_VALUE * CHAR_BIT == 64)
- return __builtin_rotateleft64(v, n);
-
-#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 32)
- return _rotl(v, n);
-
-#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 64)
- return _rotl64(v, n);
-
-#elif defined(_lrotl) && (SIZEOF_VALUE == SIZEOF_LONG)
- return _lrotl(v, n);
-
-#else
- const int m = (sizeof(VALUE) * CHAR_BIT) - 1;
- return (v << (n & m)) | (v >> (-n & m));
-#endif
-}
-
-static inline VALUE
-RUBY_BIT_ROTR(VALUE v, int n)
-{
-#if __has_builtin(__builtin_rotateright32) && (SIZEOF_VALUE * CHAR_BIT == 32)
- return __builtin_rotateright32(v, n);
-
-#elif __has_builtin(__builtin_rotateright64) && (SIZEOF_VALUE * CHAR_BIT == 64)
- return __builtin_rotateright64(v, n);
-
-#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 32)
- return _rotr(v, n);
-
-#elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 64)
- return _rotr64(v, n);
-
-#elif defined(_lrotr) && (SIZEOF_VALUE == SIZEOF_LONG)
- return _lrotr(v, n);
-
-#else
- const int m = (sizeof(VALUE) * CHAR_BIT) - 1;
- return (v << (-n & m)) | (v >> (n & m));
-#endif
-}
-
-#endif /* INTERNAL_BITS2_H */
diff --git a/parser_node.h b/parser_node.h
deleted file mode 100644
index 2955720676..0000000000
--- a/parser_node.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef RUBY_PARSER_NODE_H
-#define RUBY_PARSER_NODE_H 1
-/*
- * This is a header file used by only "parse.y"
- */
-#include "rubyparser.h"
-#include "internal/compilers.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-static inline rb_code_location_t
-code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2)
-{
- rb_code_location_t loc;
- loc.beg_pos = loc1->beg_pos;
- loc.end_pos = loc2->end_pos;
- return loc;
-}
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
-
-#endif /* RUBY_PARSER_NODE_H */
diff --git a/parser_st.c b/parser_st.c
deleted file mode 100644
index 17f669e763..0000000000
--- a/parser_st.c
+++ /dev/null
@@ -1,164 +0,0 @@
-#include "parser_st.h"
-#include "parser_bits.h"
-
-#ifndef TRUE
-# define TRUE 1
-#endif
-
-#ifndef FALSE
-# define FALSE 0
-#endif
-
-#undef NOT_RUBY
-#undef RUBY
-#undef RUBY_EXPORT
-
-#undef MEMCPY
-#define MEMCPY(p1,p2,type,n) nonempty_memcpy((p1), (p2), (sizeof(type) * (n)))
-/* The multiplication should not overflow since this macro is used
- * only with the already allocated size. */
-static inline void *
-nonempty_memcpy(void *dest, const void *src, size_t n)
-{
- if (n) {
- return memcpy(dest, src, n);
- }
- else {
- return dest;
- }
-}
-
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <assert.h>
-
-#ifdef __GNUC__
-#define PREFETCH(addr, write_p) __builtin_prefetch(addr, write_p)
-#define EXPECT(expr, val) __builtin_expect(expr, val)
-#define ATTRIBUTE_UNUSED __attribute__((unused))
-#else
-#define PREFETCH(addr, write_p)
-#define EXPECT(expr, val) (expr)
-#define ATTRIBUTE_UNUSED
-#endif
-
-
-#define st_index_t parser_st_index_t
-#define st_hash_t parser_st_hash_t
-#define st_data_t parser_st_data_t
-#define st_hash_type parser_st_hash_type
-#define st_table parser_st_table
-#define st_table_entry parser_st_table_entry
-#define st_update_callback_func parser_st_update_callback_func
-#define st_foreach_check_callback_func parser_st_foreach_check_callback_func
-#define st_foreach_callback_func parser_st_foreach_callback_func
-#define st_retval parser_st_retval
-
-#define ST_CONTINUE ST2_CONTINUE
-#define ST_STOP ST2_STOP
-#define ST_DELETE ST2_DELETE
-#define ST_CHECK ST2_CHECK
-#define ST_REPLACE ST2_REPLACE
-
-#undef st_numcmp
-#define st_numcmp rb_parser_st_numcmp
-#undef st_numhash
-#define st_numhash rb_parser_st_numhash
-#undef st_free_table
-#define st_free_table rb_parser_st_free_table
-#define rb_st_hash_start rb_parser_st_hash_start
-#undef st_delete
-#define st_delete rb_parser_st_delete
-#undef st_foreach
-#define st_foreach rb_parser_st_foreach
-#undef st_init_numtable
-#define st_init_numtable rb_parser_st_init_numtable
-#undef st_init_table_with_size
-#define st_init_table_with_size rb_parser_st_init_table_with_size
-#undef st_init_existing_table_with_size
-#define st_init_existing_table_with_size rb_parser_st_init_existing_table_with_size
-#undef st_insert
-#define st_insert rb_parser_st_insert
-#undef st_lookup
-#define st_lookup rb_parser_st_lookup
-
-#undef st_table_size
-#define st_table_size rb_parser_st_table_size
-#undef st_clear
-#define st_clear rb_parser_st_clear
-#undef st_init_strtable
-#define st_init_strtable rb_parser_st_init_strtable
-#undef st_init_table
-#define st_init_table rb_parser_st_init_table
-#undef st_init_strcasetable
-#define st_init_strcasetable rb_parser_st_init_strcasetable
-#undef st_init_strtable_with_size
-#define st_init_strtable_with_size rb_parser_st_init_strtable_with_size
-#undef st_init_numtable_with_size
-#define st_init_numtable_with_size rb_parser_st_init_numtable_with_size
-#undef st_init_strcasetable_with_size
-#define st_init_strcasetable_with_size rb_parser_st_init_strcasetable_with_size
-#undef st_memsize
-#define st_memsize rb_parser_st_memsize
-#undef st_get_key
-#define st_get_key rb_parser_st_get_key
-#undef st_add_direct
-#define st_add_direct rb_parser_st_add_direct
-#define rb_st_add_direct_with_hash rb_parser_st_add_direct_with_hash
-#undef st_insert2
-#define st_insert2 rb_parser_st_insert2
-#undef st_replace
-#define st_replace rb_parser_st_replace
-#undef st_copy
-#define st_copy rb_parser_st_copy
-#undef st_delete_safe
-#define st_delete_safe rb_parser_st_delete_safe
-#undef st_shift
-#define st_shift rb_parser_st_shift
-#undef st_cleanup_safe
-#define st_cleanup_safe rb_parser_st_cleanup_safe
-#undef st_update
-#define st_update rb_parser_st_update
-#undef st_foreach_with_replace
-#define st_foreach_with_replace rb_parser_st_foreach_with_replace
-#undef st_foreach_check
-#define st_foreach_check rb_parser_st_foreach_check
-#undef st_keys
-#define st_keys rb_parser_st_keys
-#undef st_keys_check
-#define st_keys_check rb_parser_st_keys_check
-#undef st_values
-#define st_values rb_parser_st_values
-#undef st_values_check
-#define st_values_check rb_parser_st_values_check
-#undef st_hash
-#define st_hash rb_parser_st_hash
-#undef st_hash_uint32
-#define st_hash_uint32 rb_parser_st_hash_uint32
-#undef st_hash_uint
-#define st_hash_uint rb_parser_st_hash_uint
-#undef st_hash_end
-#define st_hash_end rb_parser_st_hash_end
-#undef st_locale_insensitive_strcasecmp
-#define st_locale_insensitive_strcasecmp rb_parser_st_locale_insensitive_strcasecmp
-#undef st_locale_insensitive_strncasecmp
-#define st_locale_insensitive_strncasecmp rb_parser_st_locale_insensitive_strncasecmp
-
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-/* GCC warns about unknown sanitizer, which is annoying. */
-# undef NO_SANITIZE
-# define NO_SANITIZE(x, y) \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
- __attribute__((__no_sanitize__(x))) y; \
- _Pragma("GCC diagnostic pop")
-#endif
-
-#ifndef NO_SANITIZE
-# define NO_SANITIZE(x, y) y
-#endif
-
-#include "st.c"
diff --git a/parser_st.h b/parser_st.h
deleted file mode 100644
index 877b1e9051..0000000000
--- a/parser_st.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This is a public domain general purpose hash table package
- originally written by Peter Moore @ UCB.
-
- The hash table data structures were redesigned and the package was
- rewritten by Vladimir Makarov <vmakarov@redhat.com>. */
-
-#ifndef RUBY_ST2_H
-#define RUBY_ST2_H 1
-
-#if defined(__cplusplus)
-extern "C" {
-#if 0
-} /* satisfy cc-mode */
-#endif
-#endif
-
-#include <stddef.h>
-#include <stdint.h>
-#include "ruby/config.h"
-#include "ruby/backward/2/long_long.h"
-#include "ruby/defines.h"
-
-RUBY_SYMBOL_EXPORT_BEGIN
-
-#if SIZEOF_LONG == SIZEOF_VOIDP
-typedef unsigned long parser_st_data_t;
-#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
-typedef unsigned LONG_LONG parser_st_data_t;
-#else
-# error ---->> parser_st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
-#endif
-#define ST2_DATA_T_DEFINED
-
-#ifndef CHAR_BIT
-# ifdef HAVE_LIMITS_H
-# include <limits.h>
-# else
-# define CHAR_BIT 8
-# endif
-#endif
-#ifndef _
-# define _(args) args
-#endif
-#ifndef ANYARGS
-# ifdef __cplusplus
-# define ANYARGS ...
-# else
-# define ANYARGS
-# endif
-#endif
-
-typedef struct parser_st_table parser_st_table;
-
-typedef parser_st_data_t parser_st_index_t;
-
-/* Maximal value of unsigned integer type parser_st_index_t. */
-#define MAX_ST2_INDEX_VAL (~(parser_st_index_t) 0)
-
-typedef int parser_st_compare_func(parser_st_data_t, parser_st_data_t);
-typedef parser_st_index_t parser_st_hash_func(parser_st_data_t);
-
-typedef char st_check_for_sizeof_parser_st_index_t[SIZEOF_VOIDP == (int)sizeof(parser_st_index_t) ? 1 : -1];
-#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
-
-struct parser_st_hash_type {
- int (*compare)(parser_st_data_t, parser_st_data_t); /* parser_st_compare_func* */
- parser_st_index_t (*hash)(parser_st_data_t); /* parser_st_hash_func* */
-};
-
-#define ST_INDEX_BITS (SIZEOF_ST_INDEX_T * CHAR_BIT)
-
-#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
-# define ST2_DATA_COMPATIBLE_P(type) \
- __builtin_choose_expr(__builtin_types_compatible_p(type, parser_st_data_t), 1, 0)
-#else
-# define ST2_DATA_COMPATIBLE_P(type) 0
-#endif
-
-typedef struct parser_st_table_entry parser_st_table_entry;
-
-struct parser_st_table_entry; /* defined in parser_st.c */
-
-struct parser_st_table {
- /* Cached features of the table -- see st.c for more details. */
- unsigned char entry_power, bin_power, size_ind;
- /* How many times the table was rebuilt. */
- unsigned int rebuilds_num;
- const struct parser_st_hash_type *type;
- /* Number of entries currently in the table. */
- parser_st_index_t num_entries;
- /* Array of bins used for access by keys. */
- parser_st_index_t *bins;
- /* Start and bound index of entries in array entries.
- entries_starts and entries_bound are in interval
- [0,allocated_entries]. */
- parser_st_index_t entries_start, entries_bound;
- /* Array of size 2^entry_power. */
- parser_st_table_entry *entries;
-};
-
-#define parser_st_is_member(table,key) rb_parser_st_lookup((table),(key),(parser_st_data_t *)0)
-
-enum parser_st_retval {ST2_CONTINUE, ST2_STOP, ST2_DELETE, ST2_CHECK, ST2_REPLACE};
-
-size_t rb_parser_st_table_size(const struct parser_st_table *tbl);
-parser_st_table *rb_parser_st_init_table(const struct parser_st_hash_type *);
-parser_st_table *rb_parser_st_init_table_with_size(const struct parser_st_hash_type *, parser_st_index_t);
-parser_st_table *rb_parser_st_init_existing_table_with_size(parser_st_table *, const struct parser_st_hash_type *, parser_st_index_t);
-parser_st_table *rb_parser_st_init_numtable(void);
-parser_st_table *rb_parser_st_init_numtable_with_size(parser_st_index_t);
-parser_st_table *rb_parser_st_init_strtable(void);
-parser_st_table *rb_parser_st_init_strtable_with_size(parser_st_index_t);
-parser_st_table *rb_parser_st_init_strcasetable(void);
-parser_st_table *rb_parser_st_init_strcasetable_with_size(parser_st_index_t);
-int rb_parser_st_delete(parser_st_table *, parser_st_data_t *, parser_st_data_t *); /* returns 0:notfound 1:deleted */
-int rb_parser_st_delete_safe(parser_st_table *, parser_st_data_t *, parser_st_data_t *, parser_st_data_t);
-int rb_parser_st_shift(parser_st_table *, parser_st_data_t *, parser_st_data_t *); /* returns 0:notfound 1:deleted */
-int rb_parser_st_insert(parser_st_table *, parser_st_data_t, parser_st_data_t);
-int rb_parser_st_insert2(parser_st_table *, parser_st_data_t, parser_st_data_t, parser_st_data_t (*)(parser_st_data_t));
-int rb_parser_st_lookup(parser_st_table *, parser_st_data_t, parser_st_data_t *);
-int rb_parser_st_get_key(parser_st_table *, parser_st_data_t, parser_st_data_t *);
-typedef int parser_st_update_callback_func(parser_st_data_t *key, parser_st_data_t *value, parser_st_data_t arg, int existing);
-/* *key may be altered, but must equal to the old key, i.e., the
- * results of hash() are same and compare() returns 0, otherwise the
- * behavior is undefined */
-int rb_parser_st_update(parser_st_table *table, parser_st_data_t key, parser_st_update_callback_func *func, parser_st_data_t arg);
-typedef int parser_st_foreach_callback_func(parser_st_data_t, parser_st_data_t, parser_st_data_t);
-typedef int parser_st_foreach_check_callback_func(parser_st_data_t, parser_st_data_t, parser_st_data_t, int);
-int rb_parser_st_foreach_with_replace(parser_st_table *tab, parser_st_foreach_check_callback_func *func, parser_st_update_callback_func *replace, parser_st_data_t arg);
-int rb_parser_st_foreach(parser_st_table *, parser_st_foreach_callback_func *, parser_st_data_t);
-int rb_parser_st_foreach_check(parser_st_table *, parser_st_foreach_check_callback_func *, parser_st_data_t, parser_st_data_t);
-parser_st_index_t rb_parser_st_keys(parser_st_table *table, parser_st_data_t *keys, parser_st_index_t size);
-parser_st_index_t rb_parser_st_keys_check(parser_st_table *table, parser_st_data_t *keys, parser_st_index_t size, parser_st_data_t never);
-parser_st_index_t rb_parser_st_values(parser_st_table *table, parser_st_data_t *values, parser_st_index_t size);
-parser_st_index_t rb_parser_st_values_check(parser_st_table *table, parser_st_data_t *values, parser_st_index_t size, parser_st_data_t never);
-void rb_parser_st_add_direct(parser_st_table *, parser_st_data_t, parser_st_data_t);
-void rb_parser_st_free_table(parser_st_table *);
-void rb_parser_st_cleanup_safe(parser_st_table *, parser_st_data_t);
-void rb_parser_st_clear(parser_st_table *);
-parser_st_table *rb_parser_st_replace(parser_st_table *, parser_st_table *);
-parser_st_table *rb_parser_st_copy(parser_st_table *);
-CONSTFUNC(int rb_parser_st_numcmp(parser_st_data_t, parser_st_data_t));
-CONSTFUNC(parser_st_index_t rb_parser_st_numhash(parser_st_data_t));
-PUREFUNC(int rb_parser_st_locale_insensitive_strcasecmp(const char *s1, const char *s2));
-PUREFUNC(int rb_parser_st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n));
-PUREFUNC(size_t rb_parser_st_memsize(const parser_st_table *));
-PUREFUNC(parser_st_index_t rb_parser_st_hash(const void *ptr, size_t len, parser_st_index_t h));
-CONSTFUNC(parser_st_index_t rb_parser_st_hash_uint32(parser_st_index_t h, uint32_t i));
-CONSTFUNC(parser_st_index_t rb_parser_st_hash_uint(parser_st_index_t h, parser_st_index_t i));
-CONSTFUNC(parser_st_index_t rb_parser_st_hash_end(parser_st_index_t h));
-CONSTFUNC(parser_st_index_t rb_parser_st_hash_start(parser_st_index_t h));
-
-RUBY_SYMBOL_EXPORT_END
-
-#if defined(__cplusplus)
-#if 0
-{ /* satisfy cc-mode */
-#endif
-} /* extern "C" { */
-#endif
-
-#endif /* RUBY_ST2_H */
diff --git a/parser_value.h b/parser_value.h
deleted file mode 100644
index 4fe444e82f..0000000000
--- a/parser_value.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef EXTERNAL_VALUE_H
-#define EXTERNAL_VALUE_H
-
-#include "ruby/config.h"
-
-#if defined(__DOXYGEN__)
-
-/**
- * Type that represents a Ruby object. It is an unsigned integer of some kind,
- * depending on platforms.
- *
- * ```CXX
- * VALUE value = rb_eval_string("ARGF.readlines.map.with_index");
- * ```
- *
- * @warning ::VALUE is not a pointer.
- * @warning ::VALUE can be wider than `long`.
- */
-typedef uintptr_t VALUE;
-
-/**
- * Type that represents a Ruby identifier such as a variable name.
- *
- * ```CXX
- * ID method = rb_intern("method");
- * VALUE result = rb_funcall(obj, method, 0);
- * ```
- *
- * @note ::rb_cSymbol is a Ruby-level data type for the same thing.
- */
-typedef uintptr_t ID;
-
-/**
- * A signed integer type that has the same width with ::VALUE.
- *
- * @internal
- *
- * @shyouhei wonders: is it guaranteed that `uintptr_t` and `intptr_t` are the
- * same width? As far as I read ISO/IEC 9899:2018 section 7.20.1.4 paragraph 1
- * no such description is given... or defined elsewhere?
- */
-typedef intptr_t SIGNED_VALUE;
-
-/**
- * Identical to `sizeof(VALUE)`, except it is a macro that can also be used
- * inside of preprocessor directives such as `#if`. Handy on occasions.
- */
-#define SIZEOF_VALUE SIZEOF_UINTPTR_T
-
-/**
- * @private
- *
- * A compile-time constant of type ::VALUE whose value is 0.
- */
-#define RBIMPL_VALUE_NULL UINTPTR_C(0)
-
-/**
- * @private
- *
- * A compile-time constant of type ::VALUE whose value is 1.
- */
-#define RBIMPL_VALUE_ONE UINTPTR_C(1)
-
-/**
- * @private
- *
- * Maximum possible value that a ::VALUE can take.
- */
-#define RBIMPL_VALUE_FULL UINTPTR_MAX
-
-#elif defined HAVE_UINTPTR_T && 0
-typedef uintptr_t VALUE;
-typedef uintptr_t ID;
-# define SIGNED_VALUE intptr_t
-# define SIZEOF_VALUE SIZEOF_UINTPTR_T
-# undef PRI_VALUE_PREFIX
-# define RBIMPL_VALUE_NULL UINTPTR_C(0)
-# define RBIMPL_VALUE_ONE UINTPTR_C(1)
-# define RBIMPL_VALUE_FULL UINTPTR_MAX
-
-#elif SIZEOF_LONG == SIZEOF_VOIDP
-typedef unsigned long VALUE;
-typedef unsigned long ID;
-# define SIGNED_VALUE long
-# define SIZEOF_VALUE SIZEOF_LONG
-# define PRI_VALUE_PREFIX "l"
-# define RBIMPL_VALUE_NULL 0UL
-# define RBIMPL_VALUE_ONE 1UL
-# define RBIMPL_VALUE_FULL ULONG_MAX
-
-#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
-typedef unsigned LONG_LONG VALUE;
-typedef unsigned LONG_LONG ID;
-# define SIGNED_VALUE LONG_LONG
-# define LONG_LONG_VALUE 1
-# define SIZEOF_VALUE SIZEOF_LONG_LONG
-# define PRI_VALUE_PREFIX PRI_LL_PREFIX
-# define RBIMPL_VALUE_NULL 0ULL
-# define RBIMPL_VALUE_ONE 1ULL
-# define RBIMPL_VALUE_FULL ULLONG_MAX
-
-#else
-# error ---->> ruby requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
-#endif
-
-#endif /* EXTERNAL_VALUE_H */
diff --git a/prelude.rb b/prelude.rb
index ee78b44cc5..8fd6e6cb77 100644
--- a/prelude.rb
+++ b/prelude.rb
@@ -27,5 +27,5 @@ module Enumerable
# Makes a set from the enumerable object with given arguments.
def to_set(klass = Set, *args, &block)
klass.new(self, *args, &block)
- end unless instance_methods.include?(:to_set) # RJIT could already load this from builtin prelude
+ end
end
diff --git a/prism/api_pack.c b/prism/api_pack.c
deleted file mode 100644
index c9f0b18a39..0000000000
--- a/prism/api_pack.c
+++ /dev/null
@@ -1,267 +0,0 @@
-#include "prism/extension.h"
-
-static VALUE rb_cPrism;
-static VALUE rb_cPrismPack;
-static VALUE rb_cPrismPackDirective;
-static VALUE rb_cPrismPackFormat;
-
-static VALUE v3_2_0_symbol;
-static VALUE pack_symbol;
-static VALUE unpack_symbol;
-
-#if SIZEOF_UINT64_T == SIZEOF_LONG_LONG
-# define UINT64T2NUM(x) ULL2NUM(x)
-# define NUM2UINT64T(x) (uint64_t)NUM2ULL(x)
-#elif SIZEOF_UINT64_T == SIZEOF_LONG
-# define UINT64T2NUM(x) ULONG2NUM(x)
-# define NUM2UINT64T(x) (uint64_t)NUM2ULONG(x)
-#else
-// error No uint64_t conversion
-#endif
-
-static VALUE
-pack_type_to_symbol(pm_pack_type type) {
- switch (type) {
- case PM_PACK_SPACE:
- return ID2SYM(rb_intern("SPACE"));
- case PM_PACK_COMMENT:
- return ID2SYM(rb_intern("COMMENT"));
- case PM_PACK_INTEGER:
- return ID2SYM(rb_intern("INTEGER"));
- case PM_PACK_UTF8:
- return ID2SYM(rb_intern("UTF8"));
- case PM_PACK_BER:
- return ID2SYM(rb_intern("BER"));
- case PM_PACK_FLOAT:
- return ID2SYM(rb_intern("FLOAT"));
- case PM_PACK_STRING_SPACE_PADDED:
- return ID2SYM(rb_intern("STRING_SPACE_PADDED"));
- case PM_PACK_STRING_NULL_PADDED:
- return ID2SYM(rb_intern("STRING_NULL_PADDED"));
- case PM_PACK_STRING_NULL_TERMINATED:
- return ID2SYM(rb_intern("STRING_NULL_TERMINATED"));
- case PM_PACK_STRING_MSB:
- return ID2SYM(rb_intern("STRING_MSB"));
- case PM_PACK_STRING_LSB:
- return ID2SYM(rb_intern("STRING_LSB"));
- case PM_PACK_STRING_HEX_HIGH:
- return ID2SYM(rb_intern("STRING_HEX_HIGH"));
- case PM_PACK_STRING_HEX_LOW:
- return ID2SYM(rb_intern("STRING_HEX_LOW"));
- case PM_PACK_STRING_UU:
- return ID2SYM(rb_intern("STRING_UU"));
- case PM_PACK_STRING_MIME:
- return ID2SYM(rb_intern("STRING_MIME"));
- case PM_PACK_STRING_BASE64:
- return ID2SYM(rb_intern("STRING_BASE64"));
- case PM_PACK_STRING_FIXED:
- return ID2SYM(rb_intern("STRING_FIXED"));
- case PM_PACK_STRING_POINTER:
- return ID2SYM(rb_intern("STRING_POINTER"));
- case PM_PACK_MOVE:
- return ID2SYM(rb_intern("MOVE"));
- case PM_PACK_BACK:
- return ID2SYM(rb_intern("BACK"));
- case PM_PACK_NULL:
- return ID2SYM(rb_intern("NULL"));
- default:
- return Qnil;
- }
-}
-
-static VALUE
-pack_signed_to_symbol(pm_pack_signed signed_type) {
- switch (signed_type) {
- case PM_PACK_UNSIGNED:
- return ID2SYM(rb_intern("UNSIGNED"));
- case PM_PACK_SIGNED:
- return ID2SYM(rb_intern("SIGNED"));
- case PM_PACK_SIGNED_NA:
- return ID2SYM(rb_intern("SIGNED_NA"));
- default:
- return Qnil;
- }
-}
-
-static VALUE
-pack_endian_to_symbol(pm_pack_endian endian) {
- switch (endian) {
- case PM_PACK_AGNOSTIC_ENDIAN:
- return ID2SYM(rb_intern("AGNOSTIC_ENDIAN"));
- case PM_PACK_LITTLE_ENDIAN:
- return ID2SYM(rb_intern("LITTLE_ENDIAN"));
- case PM_PACK_BIG_ENDIAN:
- return ID2SYM(rb_intern("BIG_ENDIAN"));
- case PM_PACK_NATIVE_ENDIAN:
- return ID2SYM(rb_intern("NATIVE_ENDIAN"));
- case PM_PACK_ENDIAN_NA:
- return ID2SYM(rb_intern("ENDIAN_NA"));
- default:
- return Qnil;
- }
-}
-
-static VALUE
-pack_size_to_symbol(pm_pack_size size) {
- switch (size) {
- case PM_PACK_SIZE_SHORT:
- return ID2SYM(rb_intern("SIZE_SHORT"));
- case PM_PACK_SIZE_INT:
- return ID2SYM(rb_intern("SIZE_INT"));
- case PM_PACK_SIZE_LONG:
- return ID2SYM(rb_intern("SIZE_LONG"));
- case PM_PACK_SIZE_LONG_LONG:
- return ID2SYM(rb_intern("SIZE_LONG_LONG"));
- case PM_PACK_SIZE_8:
- return ID2SYM(rb_intern("SIZE_8"));
- case PM_PACK_SIZE_16:
- return ID2SYM(rb_intern("SIZE_16"));
- case PM_PACK_SIZE_32:
- return ID2SYM(rb_intern("SIZE_32"));
- case PM_PACK_SIZE_64:
- return ID2SYM(rb_intern("SIZE_64"));
- case PM_PACK_SIZE_P:
- return ID2SYM(rb_intern("SIZE_P"));
- case PM_PACK_SIZE_NA:
- return ID2SYM(rb_intern("SIZE_NA"));
- default:
- return Qnil;
- }
-}
-
-static VALUE
-pack_length_type_to_symbol(pm_pack_length_type length_type) {
- switch (length_type) {
- case PM_PACK_LENGTH_FIXED:
- return ID2SYM(rb_intern("LENGTH_FIXED"));
- case PM_PACK_LENGTH_MAX:
- return ID2SYM(rb_intern("LENGTH_MAX"));
- case PM_PACK_LENGTH_RELATIVE:
- return ID2SYM(rb_intern("LENGTH_RELATIVE"));
- case PM_PACK_LENGTH_NA:
- return ID2SYM(rb_intern("LENGTH_NA"));
- default:
- return Qnil;
- }
-}
-
-static VALUE
-pack_encoding_to_ruby(pm_pack_encoding encoding) {
- int index;
- switch (encoding) {
- case PM_PACK_ENCODING_ASCII_8BIT:
- index = rb_ascii8bit_encindex();
- break;
- case PM_PACK_ENCODING_US_ASCII:
- index = rb_usascii_encindex();
- break;
- case PM_PACK_ENCODING_UTF_8:
- index = rb_utf8_encindex();
- break;
- default:
- return Qnil;
- }
- return rb_enc_from_encoding(rb_enc_from_index(index));
-}
-
-/**
- * call-seq:
- * Pack::parse(version, variant, source) -> Format
- *
- * Parse the given source and return a format object.
- */
-static VALUE
-pack_parse(VALUE self, VALUE version_symbol, VALUE variant_symbol, VALUE format_string) {
- if (version_symbol != v3_2_0_symbol) {
- rb_raise(rb_eArgError, "invalid version");
- }
-
- pm_pack_variant variant;
- if (variant_symbol == pack_symbol) {
- variant = PM_PACK_VARIANT_PACK;
- } else if (variant_symbol == unpack_symbol) {
- variant = PM_PACK_VARIANT_UNPACK;
- } else {
- rb_raise(rb_eArgError, "invalid variant");
- }
-
- StringValue(format_string);
-
- const char *format = RSTRING_PTR(format_string);
- const char *format_end = format + RSTRING_LEN(format_string);
- pm_pack_encoding encoding = PM_PACK_ENCODING_START;
-
- VALUE directives_array = rb_ary_new();
-
- while (format < format_end) {
- pm_pack_type type;
- pm_pack_signed signed_type;
- pm_pack_endian endian;
- pm_pack_size size;
- pm_pack_length_type length_type;
- uint64_t length;
-
- const char *directive_start = format;
-
- pm_pack_result parse_result = pm_pack_parse(variant, &format, format_end, &type, &signed_type, &endian,
- &size, &length_type, &length, &encoding);
-
- const char *directive_end = format;
-
- switch (parse_result) {
- case PM_PACK_OK:
- break;
- case PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE:
- rb_raise(rb_eArgError, "unsupported directive");
- case PM_PACK_ERROR_UNKNOWN_DIRECTIVE:
- rb_raise(rb_eArgError, "unsupported directive");
- case PM_PACK_ERROR_LENGTH_TOO_BIG:
- rb_raise(rb_eRangeError, "pack length too big");
- case PM_PACK_ERROR_BANG_NOT_ALLOWED:
- rb_raise(rb_eRangeError, "bang not allowed");
- case PM_PACK_ERROR_DOUBLE_ENDIAN:
- rb_raise(rb_eRangeError, "double endian");
- default:
- rb_bug("parse result");
- }
-
- if (type == PM_PACK_END) {
- break;
- }
-
- VALUE directive_args[9] = {
- version_symbol,
- variant_symbol,
- rb_usascii_str_new(directive_start, directive_end - directive_start),
- pack_type_to_symbol(type),
- pack_signed_to_symbol(signed_type),
- pack_endian_to_symbol(endian),
- pack_size_to_symbol(size),
- pack_length_type_to_symbol(length_type),
- UINT64T2NUM(length)
- };
-
- rb_ary_push(directives_array, rb_class_new_instance(9, directive_args, rb_cPrismPackDirective));
- }
-
- VALUE format_args[2];
- format_args[0] = directives_array;
- format_args[1] = pack_encoding_to_ruby(encoding);
- return rb_class_new_instance(2, format_args, rb_cPrismPackFormat);
-}
-
-/**
- * The function that gets called when Ruby initializes the prism extension.
- */
-void
-Init_prism_pack(void) {
- rb_cPrism = rb_define_module("Prism");
- rb_cPrismPack = rb_define_module_under(rb_cPrism, "Pack");
- rb_cPrismPackDirective = rb_define_class_under(rb_cPrismPack, "Directive", rb_cObject);
- rb_cPrismPackFormat = rb_define_class_under(rb_cPrismPack, "Format", rb_cObject);
- rb_define_singleton_method(rb_cPrismPack, "parse", pack_parse, 3);
-
- v3_2_0_symbol = ID2SYM(rb_intern("v3_2_0"));
- pack_symbol = ID2SYM(rb_intern("pack"));
- unpack_symbol = ID2SYM(rb_intern("unpack"));
-}
diff --git a/prism/config.yml b/prism/config.yml
deleted file mode 100644
index d3b6b08709..0000000000
--- a/prism/config.yml
+++ /dev/null
@@ -1,2704 +0,0 @@
-tokens:
- - name: EOF
- value: 1
- comment: final token in the file
- - name: MISSING
- comment: "a token that was expected but not found"
- - name: NOT_PROVIDED
- comment: "a token that was not present but it is okay"
- - name: AMPERSAND
- comment: "&"
- - name: AMPERSAND_AMPERSAND
- comment: "&&"
- - name: AMPERSAND_AMPERSAND_EQUAL
- comment: "&&="
- - name: AMPERSAND_DOT
- comment: "&."
- - name: AMPERSAND_EQUAL
- comment: "&="
- - name: BACKTICK
- comment: "`"
- - name: BACK_REFERENCE
- comment: "a back reference"
- - name: BANG
- comment: "! or !@"
- - name: BANG_EQUAL
- comment: "!="
- - name: BANG_TILDE
- comment: "!~"
- - name: BRACE_LEFT
- comment: "{"
- - name: BRACE_RIGHT
- comment: "}"
- - name: BRACKET_LEFT
- comment: "["
- - name: BRACKET_LEFT_ARRAY
- comment: "[ for the beginning of an array"
- - name: BRACKET_LEFT_RIGHT
- comment: "[]"
- - name: BRACKET_LEFT_RIGHT_EQUAL
- comment: "[]="
- - name: BRACKET_RIGHT
- comment: "]"
- - name: CARET
- comment: "^"
- - name: CARET_EQUAL
- comment: "^="
- - name: CHARACTER_LITERAL
- comment: "a character literal"
- - name: CLASS_VARIABLE
- comment: "a class variable"
- - name: COLON
- comment: ":"
- - name: COLON_COLON
- comment: "::"
- - name: COMMA
- comment: ","
- - name: COMMENT
- comment: "a comment"
- - name: CONSTANT
- comment: "a constant"
- - name: DOT
- comment: "the . call operator"
- - name: DOT_DOT
- comment: "the .. range operator"
- - name: DOT_DOT_DOT
- comment: "the ... range operator or forwarding parameter"
- - name: EMBDOC_BEGIN
- comment: "=begin"
- - name: EMBDOC_END
- comment: "=end"
- - name: EMBDOC_LINE
- comment: "a line inside of embedded documentation"
- - name: EMBEXPR_BEGIN
- comment: "#{"
- - name: EMBEXPR_END
- comment: "}"
- - name: EMBVAR
- comment: "#"
- - name: EQUAL
- comment: "="
- - name: EQUAL_EQUAL
- comment: "=="
- - name: EQUAL_EQUAL_EQUAL
- comment: "==="
- - name: EQUAL_GREATER
- comment: "=>"
- - name: EQUAL_TILDE
- comment: "=~"
- - name: FLOAT
- comment: "a floating point number"
- - name: FLOAT_IMAGINARY
- comment: "a floating pointer number with an imaginary suffix"
- - name: FLOAT_RATIONAL
- comment: "a floating pointer number with a rational suffix"
- - name: FLOAT_RATIONAL_IMAGINARY
- comment: "a floating pointer number with a rational and imaginary suffix"
- - name: GLOBAL_VARIABLE
- comment: "a global variable"
- - name: GREATER
- comment: ">"
- - name: GREATER_EQUAL
- comment: ">="
- - name: GREATER_GREATER
- comment: ">>"
- - name: GREATER_GREATER_EQUAL
- comment: ">>="
- - name: HEREDOC_END
- comment: "the end of a heredoc"
- - name: HEREDOC_START
- comment: "the start of a heredoc"
- - name: IDENTIFIER
- comment: "an identifier"
- - name: IGNORED_NEWLINE
- comment: "an ignored newline"
- - name: INSTANCE_VARIABLE
- comment: "an instance variable"
- - name: INTEGER
- comment: "an integer (any base)"
- - name: INTEGER_IMAGINARY
- comment: "an integer with an imaginary suffix"
- - name: INTEGER_RATIONAL
- comment: "an integer with a rational suffix"
- - name: INTEGER_RATIONAL_IMAGINARY
- comment: "an integer with a rational and imaginary suffix"
- - name: KEYWORD_ALIAS
- comment: "alias"
- - name: KEYWORD_AND
- comment: "and"
- - name: KEYWORD_BEGIN
- comment: "begin"
- - name: KEYWORD_BEGIN_UPCASE
- comment: "BEGIN"
- - name: KEYWORD_BREAK
- comment: "break"
- - name: KEYWORD_CASE
- comment: "case"
- - name: KEYWORD_CLASS
- comment: "class"
- - name: KEYWORD_DEF
- comment: "def"
- - name: KEYWORD_DEFINED
- comment: "defined?"
- - name: KEYWORD_DO
- comment: "do"
- - name: KEYWORD_DO_LOOP
- comment: "do keyword for a predicate in a while, until, or for loop"
- - name: KEYWORD_ELSE
- comment: "else"
- - name: KEYWORD_ELSIF
- comment: "elsif"
- - name: KEYWORD_END
- comment: "end"
- - name: KEYWORD_END_UPCASE
- comment: "END"
- - name: KEYWORD_ENSURE
- comment: "ensure"
- - name: KEYWORD_FALSE
- comment: "false"
- - name: KEYWORD_FOR
- comment: "for"
- - name: KEYWORD_IF
- comment: "if"
- - name: KEYWORD_IF_MODIFIER
- comment: "if in the modifier form"
- - name: KEYWORD_IN
- comment: "in"
- - name: KEYWORD_MODULE
- comment: "module"
- - name: KEYWORD_NEXT
- comment: "next"
- - name: KEYWORD_NIL
- comment: "nil"
- - name: KEYWORD_NOT
- comment: "not"
- - name: KEYWORD_OR
- comment: "or"
- - name: KEYWORD_REDO
- comment: "redo"
- - name: KEYWORD_RESCUE
- comment: "rescue"
- - name: KEYWORD_RESCUE_MODIFIER
- comment: "rescue in the modifier form"
- - name: KEYWORD_RETRY
- comment: "retry"
- - name: KEYWORD_RETURN
- comment: "return"
- - name: KEYWORD_SELF
- comment: "self"
- - name: KEYWORD_SUPER
- comment: "super"
- - name: KEYWORD_THEN
- comment: "then"
- - name: KEYWORD_TRUE
- comment: "true"
- - name: KEYWORD_UNDEF
- comment: "undef"
- - name: KEYWORD_UNLESS
- comment: "unless"
- - name: KEYWORD_UNLESS_MODIFIER
- comment: "unless in the modifier form"
- - name: KEYWORD_UNTIL
- comment: "until"
- - name: KEYWORD_UNTIL_MODIFIER
- comment: "until in the modifier form"
- - name: KEYWORD_WHEN
- comment: "when"
- - name: KEYWORD_WHILE
- comment: "while"
- - name: KEYWORD_WHILE_MODIFIER
- comment: "while in the modifier form"
- - name: KEYWORD_YIELD
- comment: "yield"
- - name: KEYWORD___ENCODING__
- comment: "__ENCODING__"
- - name: KEYWORD___FILE__
- comment: "__FILE__"
- - name: KEYWORD___LINE__
- comment: "__LINE__"
- - name: LABEL
- comment: "a label"
- - name: LABEL_END
- comment: "the end of a label"
- - name: LAMBDA_BEGIN
- comment: "{"
- - name: LESS
- comment: "<"
- - name: LESS_EQUAL
- comment: "<="
- - name: LESS_EQUAL_GREATER
- comment: "<=>"
- - name: LESS_LESS
- comment: "<<"
- - name: LESS_LESS_EQUAL
- comment: "<<="
- - name: METHOD_NAME
- comment: "a method name"
- - name: MINUS
- comment: "-"
- - name: MINUS_EQUAL
- comment: "-="
- - name: MINUS_GREATER
- comment: "->"
- - name: NEWLINE
- comment: "a newline character outside of other tokens"
- - name: NUMBERED_REFERENCE
- comment: "a numbered reference to a capture group in the previous regular expression match"
- - name: PARENTHESIS_LEFT
- comment: "("
- - name: PARENTHESIS_LEFT_PARENTHESES
- comment: "( for a parentheses node"
- - name: PARENTHESIS_RIGHT
- comment: ")"
- - name: PERCENT
- comment: "%"
- - name: PERCENT_EQUAL
- comment: "%="
- - name: PERCENT_LOWER_I
- comment: "%i"
- - name: PERCENT_LOWER_W
- comment: "%w"
- - name: PERCENT_LOWER_X
- comment: "%x"
- - name: PERCENT_UPPER_I
- comment: "%I"
- - name: PERCENT_UPPER_W
- comment: "%W"
- - name: PIPE
- comment: "|"
- - name: PIPE_EQUAL
- comment: "|="
- - name: PIPE_PIPE
- comment: "||"
- - name: PIPE_PIPE_EQUAL
- comment: "||="
- - name: PLUS
- comment: "+"
- - name: PLUS_EQUAL
- comment: "+="
- - name: QUESTION_MARK
- comment: "?"
- - name: REGEXP_BEGIN
- comment: "the beginning of a regular expression"
- - name: REGEXP_END
- comment: "the end of a regular expression"
- - name: SEMICOLON
- comment: ";"
- - name: SLASH
- comment: "/"
- - name: SLASH_EQUAL
- comment: "/="
- - name: STAR
- comment: "*"
- - name: STAR_EQUAL
- comment: "*="
- - name: STAR_STAR
- comment: "**"
- - name: STAR_STAR_EQUAL
- comment: "**="
- - name: STRING_BEGIN
- comment: "the beginning of a string"
- - name: STRING_CONTENT
- comment: "the contents of a string"
- - name: STRING_END
- comment: "the end of a string"
- - name: SYMBOL_BEGIN
- comment: "the beginning of a symbol"
- - name: TILDE
- comment: "~ or ~@"
- - name: UAMPERSAND
- comment: "unary &"
- - name: UCOLON_COLON
- comment: "unary ::"
- - name: UDOT_DOT
- comment: "unary .. operator"
- - name: UDOT_DOT_DOT
- comment: "unary ... operator"
- - name: UMINUS
- comment: "-@"
- - name: UMINUS_NUM
- comment: "-@ for a number"
- - name: UPLUS
- comment: "+@"
- - name: USTAR
- comment: "unary *"
- - name: USTAR_STAR
- comment: "unary **"
- - name: WORDS_SEP
- comment: "a separator between words in a list"
- - name: __END__
- comment: "marker for the point in the file at which the parser should stop"
-flags:
- - name: ArgumentsNodeFlags
- values:
- - name: CONTAINS_KEYWORD_SPLAT
- comment: "if arguments contain keyword splat"
- comment: Flags for arguments nodes.
- - name: ArrayNodeFlags
- values:
- - name: CONTAINS_SPLAT
- comment: "if array contains splat nodes"
- comment: Flags for array nodes.
- - name: CallNodeFlags
- values:
- - name: SAFE_NAVIGATION
- comment: "&. operator"
- - name: VARIABLE_CALL
- comment: "a call that could have been a local variable"
- - name: ATTRIBUTE_WRITE
- comment: "a call that is an attribute write, so the value being written should be returned"
- comment: Flags for call nodes.
- - name: EncodingFlags
- values:
- - name: FORCED_UTF8_ENCODING
- comment: "internal bytes forced the encoding to UTF-8"
- - name: FORCED_BINARY_ENCODING
- comment: "internal bytes forced the encoding to binary"
- comment: Flags for nodes that have unescaped content.
- - name: IntegerBaseFlags
- values:
- - name: BINARY
- comment: "0b prefix"
- - name: DECIMAL
- comment: "0d or no prefix"
- - name: OCTAL
- comment: "0o or 0 prefix"
- - name: HEXADECIMAL
- comment: "0x prefix"
- comment: Flags for integer nodes that correspond to the base of the integer.
- - name: KeywordHashNodeFlags
- values:
- - name: STATIC_KEYS
- comment: "a keyword hash which only has `AssocNode` elements all with static literal keys, which means the elements can be treated as keyword arguments"
- comment: Flags for keyword hash nodes.
- - name: LoopFlags
- values:
- - name: BEGIN_MODIFIER
- comment: "a loop after a begin statement, so the body is executed first before the condition"
- comment: Flags for while and until loop nodes.
- - name: RangeFlags
- values:
- - name: EXCLUDE_END
- comment: "... operator"
- comment: Flags for range and flip-flop nodes.
- - name: RegularExpressionFlags
- values:
- - name: IGNORE_CASE
- comment: "i - ignores the case of characters when matching"
- - name: EXTENDED
- comment: "x - ignores whitespace and allows comments in regular expressions"
- - name: MULTI_LINE
- comment: "m - allows $ to match the end of lines within strings"
- - name: ONCE
- comment: "o - only interpolates values into the regular expression once"
- - name: EUC_JP
- comment: "e - forces the EUC-JP encoding"
- - name: ASCII_8BIT
- comment: "n - forces the ASCII-8BIT encoding"
- - name: WINDOWS_31J
- comment: "s - forces the Windows-31J encoding"
- - name: UTF_8
- comment: "u - forces the UTF-8 encoding"
- - name: FORCED_UTF8_ENCODING
- comment: "internal bytes forced the encoding to UTF-8"
- - name: FORCED_BINARY_ENCODING
- comment: "internal bytes forced the encoding to binary"
- - name: FORCED_US_ASCII_ENCODING
- comment: "internal bytes forced the encoding to US-ASCII"
- comment: Flags for regular expression and match last line nodes.
- - name: StringFlags
- values:
- - name: FORCED_UTF8_ENCODING
- comment: "internal bytes forced the encoding to UTF-8"
- - name: FORCED_BINARY_ENCODING
- comment: "internal bytes forced the encoding to binary"
- - name: FROZEN
- comment: "frozen by virtue of a `frozen_string_literal` comment"
- comment: Flags for string nodes.
- - name: SymbolFlags
- values:
- - name: FORCED_UTF8_ENCODING
- comment: "internal bytes forced the encoding to UTF-8"
- - name: FORCED_BINARY_ENCODING
- comment: "internal bytes forced the encoding to binary"
- - name: FORCED_US_ASCII_ENCODING
- comment: "internal bytes forced the encoding to US-ASCII"
- comment: Flags for symbol nodes.
-nodes:
- - name: AliasGlobalVariableNode
- fields:
- - name: new_name
- type: node
- - name: old_name
- type: node
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of the `alias` keyword to alias a global variable.
-
- alias $foo $bar
- ^^^^^^^^^^^^^^^
- - name: AliasMethodNode
- fields:
- - name: new_name
- type: node
- - name: old_name
- type: node
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of the `alias` keyword to alias a method.
-
- alias foo bar
- ^^^^^^^^^^^^^
- - name: AlternationPatternNode
- fields:
- - name: left
- type: node
- - name: right
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents an alternation pattern in pattern matching.
-
- foo => bar | baz
- ^^^^^^^^^
- - name: AndNode
- fields:
- - name: left
- type: node
- - name: right
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the `&&` operator or the `and` keyword.
-
- left and right
- ^^^^^^^^^^^^^^
- - name: ArgumentsNode
- fields:
- - name: flags
- type: flags
- kind: ArgumentsNodeFlags
- - name: arguments
- type: node[]
- comment: |
- Represents a set of arguments to a method or a keyword.
-
- return foo, bar, baz
- ^^^^^^^^^^^^^
- - name: ArrayNode
- fields:
- - name: flags
- type: flags
- kind: ArrayNodeFlags
- - name: elements
- type: node[]
- - name: opening_loc
- type: location?
- - name: closing_loc
- type: location?
- comment: |
- Represents an array literal. This can be a regular array using brackets or
- a special array using % like %w or %i.
-
- [1, 2, 3]
- ^^^^^^^^^
- - name: ArrayPatternNode
- fields:
- - name: constant
- type: node?
- - name: requireds
- type: node[]
- - name: rest
- type: node?
- - name: posts
- type: node[]
- - name: opening_loc
- type: location?
- - name: closing_loc
- type: location?
- comment: |
- Represents an array pattern in pattern matching.
-
- foo in 1, 2
- ^^^^^^^^^^^
-
- foo in [1, 2]
- ^^^^^^^^^^^^^
-
- foo in *1
- ^^^^^^^^^
-
- foo in Bar[]
- ^^^^^^^^^^^^
-
- foo in Bar[1, 2, 3]
- ^^^^^^^^^^^^^^^^^^^
- - name: AssocNode
- fields:
- - name: key
- type: node
- - name: value
- type: node?
- - name: operator_loc
- type: location?
- comment: |
- Represents a hash key/value pair.
-
- { a => b }
- ^^^^^^
- - name: AssocSplatNode
- fields:
- - name: value
- type: node?
- - name: operator_loc
- type: location
- comment: |
- Represents a splat in a hash literal.
-
- { **foo }
- ^^^^^
- - name: BackReferenceReadNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents reading a reference to a field in the previous match.
-
- $'
- ^^
- - name: BeginNode
- fields:
- - name: begin_keyword_loc
- type: location?
- - name: statements
- type: node?
- kind: StatementsNode
- - name: rescue_clause
- type: node?
- kind: RescueNode
- - name: else_clause
- type: node?
- kind: ElseNode
- - name: ensure_clause
- type: node?
- kind: EnsureNode
- - name: end_keyword_loc
- type: location?
- newline: false
- comment: |
- Represents a begin statement.
-
- begin
- foo
- end
- ^^^^^
- - name: BlockArgumentNode
- fields:
- - name: expression
- type: node?
- - name: operator_loc
- type: location
- comment: |
- Represents block method arguments.
-
- bar(&args)
- ^^^^^^^^^^
- - name: BlockLocalVariableNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents a block local variable.
-
- a { |; b| }
- ^
- - name: BlockNode
- fields:
- - name: locals
- type: constant[]
- - name: locals_body_index
- type: uint32
- - name: parameters
- type: node?
- - name: body
- type: node?
- - name: opening_loc
- type: location
- - name: closing_loc
- type: location
- comment: |
- Represents a block of ruby code.
-
- [1, 2, 3].each { |i| puts x }
- ^^^^^^^^^^^^^^
- - name: BlockParameterNode
- fields:
- - name: name
- type: constant?
- - name: name_loc
- type: location?
- - name: operator_loc
- type: location
- comment: |
- Represents a block parameter to a method, block, or lambda definition.
-
- def a(&b)
- ^^
- end
- - name: BlockParametersNode
- fields:
- - name: parameters
- type: node?
- kind: ParametersNode
- - name: locals
- type: node[]
- - name: opening_loc
- type: location?
- - name: closing_loc
- type: location?
- comment: |
- Represents a block's parameters declaration.
-
- -> (a, b = 1; local) { }
- ^^^^^^^^^^^^^^^^^
-
- foo do |a, b = 1; local|
- ^^^^^^^^^^^^^^^^^
- end
- - name: BreakNode
- fields:
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of the `break` keyword.
-
- break foo
- ^^^^^^^^^
- - name: CallAndWriteNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: message_loc
- type: location?
- - name: read_name
- type: constant
- - name: write_name
- type: constant
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator on a call.
-
- foo.bar &&= value
- ^^^^^^^^^^^^^^^^^
- - name: CallNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: name
- type: constant
- - name: message_loc
- type: location?
- - name: opening_loc
- type: location?
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: closing_loc
- type: location?
- - name: block
- type: node?
- comment: |
- Represents a method call, in all of the various forms that can take.
-
- foo
- ^^^
-
- foo()
- ^^^^^
-
- +foo
- ^^^^
-
- foo + bar
- ^^^^^^^^^
-
- foo.bar
- ^^^^^^^
-
- foo&.bar
- ^^^^^^^^
- - name: CallOperatorWriteNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: message_loc
- type: location?
- - name: read_name
- type: constant
- - name: write_name
- type: constant
- - name: operator
- type: constant
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of an assignment operator on a call.
-
- foo.bar += baz
- ^^^^^^^^^^^^^^
- - name: CallOrWriteNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: message_loc
- type: location?
- - name: read_name
- type: constant
- - name: write_name
- type: constant
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator on a call.
-
- foo.bar ||= value
- ^^^^^^^^^^^^^^^^^
- - name: CallTargetNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node
- - name: call_operator_loc
- type: location
- - name: name
- type: constant
- - name: message_loc
- type: location
- comment: |
- Represents assigning to a method call.
-
- foo.bar, = 1
- ^^^^^^^
-
- begin
- rescue => foo.bar
- ^^^^^^^
- end
-
- for foo.bar in baz do end
- ^^^^^^^
- - name: CapturePatternNode
- fields:
- - name: value
- type: node
- - name: target
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents assigning to a local variable in pattern matching.
-
- foo => [bar => baz]
- ^^^^^^^^^^^^
- - name: CaseMatchNode
- fields:
- - name: predicate
- type: node?
- - name: conditions
- type: node[]
- - name: consequent
- type: node?
- kind: ElseNode
- - name: case_keyword_loc
- type: location
- - name: end_keyword_loc
- type: location
- comment: |
- Represents the use of a case statement for pattern matching.
-
- case true
- in false
- end
- ^^^^^^^^^
- - name: CaseNode
- fields:
- - name: predicate
- type: node?
- - name: conditions
- type: node[]
- - name: consequent
- type: node?
- kind: ElseNode
- - name: case_keyword_loc
- type: location
- - name: end_keyword_loc
- type: location
- comment: |
- Represents the use of a case statement.
-
- case true
- when false
- end
- ^^^^^^^^^^
- - name: ClassNode
- fields:
- - name: locals
- type: constant[]
- - name: class_keyword_loc
- type: location
- - name: constant_path
- type: node
- - name: inheritance_operator_loc
- type: location?
- - name: superclass
- type: node?
- - name: body
- type: node?
- - name: end_keyword_loc
- type: location
- - name: name
- type: constant
- comment: |
- Represents a class declaration involving the `class` keyword.
-
- class Foo end
- ^^^^^^^^^^^^^
- - name: ClassVariableAndWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator for assignment to a class variable.
-
- @@target &&= value
- ^^^^^^^^^^^^^^^^^^
- - name: ClassVariableOperatorWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: operator
- type: constant
- comment: |
- Represents assigning to a class variable using an operator that isn't `=`.
-
- @@target += value
- ^^^^^^^^^^^^^^^^^
- - name: ClassVariableOrWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator for assignment to a class variable.
-
- @@target ||= value
- ^^^^^^^^^^^^^^^^^^
- - name: ClassVariableReadNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents referencing a class variable.
-
- @@foo
- ^^^^^
- - name: ClassVariableTargetNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents writing to a class variable in a context that doesn't have an explicit value.
-
- @@foo, @@bar = baz
- ^^^^^ ^^^^^
- - name: ClassVariableWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: value
- type: node
- - name: operator_loc
- type: location?
- comment: |
- Represents writing to a class variable.
-
- @@foo = 1
- ^^^^^^^^^
- - name: ConstantAndWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator for assignment to a constant.
-
- Target &&= value
- ^^^^^^^^^^^^^^^^
- - name: ConstantOperatorWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: operator
- type: constant
- comment: |
- Represents assigning to a constant using an operator that isn't `=`.
-
- Target += value
- ^^^^^^^^^^^^^^^
- - name: ConstantOrWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator for assignment to a constant.
-
- Target ||= value
- ^^^^^^^^^^^^^^^^
- - name: ConstantPathAndWriteNode
- fields:
- - name: target
- type: node
- kind: ConstantPathNode
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator for assignment to a constant path.
-
- Parent::Child &&= value
- ^^^^^^^^^^^^^^^^^^^^^^^
- - name: ConstantPathNode
- fields:
- - name: parent
- type: node?
- - name: child
- type: node
- - name: delimiter_loc
- type: location
- comment: |
- Represents accessing a constant through a path of `::` operators.
-
- Foo::Bar
- ^^^^^^^^
- - name: ConstantPathOperatorWriteNode
- fields:
- - name: target
- type: node
- kind: ConstantPathNode
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: operator
- type: constant
- comment: |
- Represents assigning to a constant path using an operator that isn't `=`.
-
- Parent::Child += value
- ^^^^^^^^^^^^^^^^^^^^^^
- - name: ConstantPathOrWriteNode
- fields:
- - name: target
- type: node
- kind: ConstantPathNode
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator for assignment to a constant path.
-
- Parent::Child ||= value
- ^^^^^^^^^^^^^^^^^^^^^^^
- - name: ConstantPathTargetNode
- fields:
- - name: parent
- type: node?
- - name: child
- type: node
- - name: delimiter_loc
- type: location
- comment: |
- Represents writing to a constant path in a context that doesn't have an explicit value.
-
- Foo::Foo, Bar::Bar = baz
- ^^^^^^^^ ^^^^^^^^
- - name: ConstantPathWriteNode
- fields:
- - name: target
- type: node
- kind: ConstantPathNode
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents writing to a constant path.
-
- ::Foo = 1
- ^^^^^^^^^
-
- Foo::Bar = 1
- ^^^^^^^^^^^^
-
- ::Foo::Bar = 1
- ^^^^^^^^^^^^^^
- - name: ConstantReadNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents referencing a constant.
-
- Foo
- ^^^
- - name: ConstantTargetNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents writing to a constant in a context that doesn't have an explicit value.
-
- Foo, Bar = baz
- ^^^ ^^^
- - name: ConstantWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: value
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents writing to a constant.
-
- Foo = 1
- ^^^^^^^
- - name: DefNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: receiver
- type: node?
- - name: parameters
- type: node?
- kind: ParametersNode
- - name: body
- type: node?
- - name: locals
- type: constant[]
- - name: locals_body_index
- type: uint32
- - name: def_keyword_loc
- type: location
- - name: operator_loc
- type: location?
- - name: lparen_loc
- type: location?
- - name: rparen_loc
- type: location?
- - name: equal_loc
- type: location?
- - name: end_keyword_loc
- type: location?
- comment: |
- Represents a method definition.
-
- def method
- end
- ^^^^^^^^^^
- - name: DefinedNode
- fields:
- - name: lparen_loc
- type: location?
- - name: value
- type: node
- - name: rparen_loc
- type: location?
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of the `defined?` keyword.
-
- defined?(a)
- ^^^^^^^^^^^
- - name: ElseNode
- fields:
- - name: else_keyword_loc
- type: location
- - name: statements
- type: node?
- kind: StatementsNode
- - name: end_keyword_loc
- type: location?
- comment: |
- Represents an `else` clause in a `case`, `if`, or `unless` statement.
-
- if a then b else c end
- ^^^^^^^^^^
- - name: EmbeddedStatementsNode
- fields:
- - name: opening_loc
- type: location
- - name: statements
- type: node?
- kind: StatementsNode
- - name: closing_loc
- type: location
- comment: |
- Represents an interpolated set of statements.
-
- "foo #{bar}"
- ^^^^^^
- - name: EmbeddedVariableNode
- fields:
- - name: operator_loc
- type: location
- - name: variable
- type: node
- comment: |
- Represents an interpolated variable.
-
- "foo #@bar"
- ^^^^^
- - name: EnsureNode
- fields:
- - name: ensure_keyword_loc
- type: location
- - name: statements
- type: node?
- kind: StatementsNode
- - name: end_keyword_loc
- type: location
- comment: |
- Represents an `ensure` clause in a `begin` statement.
-
- begin
- foo
- ensure
- ^^^^^^
- bar
- end
- - name: FalseNode
- comment: |
- Represents the use of the literal `false` keyword.
-
- false
- ^^^^^
- - name: FindPatternNode
- fields:
- - name: constant
- type: node?
- - name: left
- type: node
- - name: requireds
- type: node[]
- - name: right
- type: node
- - name: opening_loc
- type: location?
- - name: closing_loc
- type: location?
- comment: |
- Represents a find pattern in pattern matching.
-
- foo in *bar, baz, *qux
- ^^^^^^^^^^^^^^^
-
- foo in [*bar, baz, *qux]
- ^^^^^^^^^^^^^^^^^
-
- foo in Foo(*bar, baz, *qux)
- ^^^^^^^^^^^^^^^^^^^^
- - name: FlipFlopNode
- fields:
- - name: flags
- type: flags
- kind: RangeFlags
- - name: left
- type: node?
- - name: right
- type: node?
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the `..` or `...` operators to create flip flops.
-
- baz if foo .. bar
- ^^^^^^^^^^
- - name: FloatNode
- comment: |
- Represents a floating point number literal.
-
- 1.0
- ^^^
- - name: ForNode
- fields:
- - name: index
- type: node
- - name: collection
- type: node
- - name: statements
- type: node?
- kind: StatementsNode
- - name: for_keyword_loc
- type: location
- - name: in_keyword_loc
- type: location
- - name: do_keyword_loc
- type: location?
- - name: end_keyword_loc
- type: location
- comment: |
- Represents the use of the `for` keyword.
-
- for i in a end
- ^^^^^^^^^^^^^^
- - name: ForwardingArgumentsNode
- comment: |
- Represents forwarding all arguments to this method to another method.
-
- def foo(...)
- bar(...)
- ^^^
- end
- - name: ForwardingParameterNode
- comment: |
- Represents the use of the forwarding parameter in a method, block, or lambda declaration.
-
- def foo(...)
- ^^^
- end
- - name: ForwardingSuperNode
- fields:
- - name: block
- type: node?
- kind: BlockNode
- comment: |
- Represents the use of the `super` keyword without parentheses or arguments.
-
- super
- ^^^^^
- - name: GlobalVariableAndWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator for assignment to a global variable.
-
- $target &&= value
- ^^^^^^^^^^^^^^^^^
- - name: GlobalVariableOperatorWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: operator
- type: constant
- comment: |
- Represents assigning to a global variable using an operator that isn't `=`.
-
- $target += value
- ^^^^^^^^^^^^^^^^
- - name: GlobalVariableOrWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator for assignment to a global variable.
-
- $target ||= value
- ^^^^^^^^^^^^^^^^^
- - name: GlobalVariableReadNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents referencing a global variable.
-
- $foo
- ^^^^
- - name: GlobalVariableTargetNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents writing to a global variable in a context that doesn't have an explicit value.
-
- $foo, $bar = baz
- ^^^^ ^^^^
- - name: GlobalVariableWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: value
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents writing to a global variable.
-
- $foo = 1
- ^^^^^^^^
- - name: HashNode
- fields:
- - name: opening_loc
- type: location
- - name: elements
- type: node[]
- - name: closing_loc
- type: location
- comment: |
- Represents a hash literal.
-
- { a => b }
- ^^^^^^^^^^
- - name: HashPatternNode
- fields:
- - name: constant
- type: node?
- - name: elements
- type: node[]
- - name: rest
- type: node?
- - name: opening_loc
- type: location?
- - name: closing_loc
- type: location?
- comment: |
- Represents a hash pattern in pattern matching.
-
- foo => { a: 1, b: 2 }
- ^^^^^^^^^^^^^^
-
- foo => { a: 1, b: 2, **c }
- ^^^^^^^^^^^^^^^^^^^
- - name: IfNode
- fields:
- - name: if_keyword_loc
- type: location?
- - name: predicate
- type: node
- - name: then_keyword_loc
- type: location?
- - name: statements
- type: node?
- kind: StatementsNode
- - name: consequent
- type: node?
- - name: end_keyword_loc
- type: location?
- newline: predicate
- comment: |
- Represents the use of the `if` keyword, either in the block form or the modifier form.
-
- bar if foo
- ^^^^^^^^^^
-
- if foo then bar end
- ^^^^^^^^^^^^^^^^^^^
- - name: ImaginaryNode
- fields:
- - name: numeric
- type: node
- comment: |
- Represents an imaginary number literal.
-
- 1.0i
- ^^^^
- - name: ImplicitNode
- fields:
- - name: value
- type: node
- comment: |
- Represents a node that is implicitly being added to the tree but doesn't
- correspond directly to a node in the source.
-
- { foo: }
- ^^^^
-
- { Foo: }
- ^^^^
- - name: ImplicitRestNode
- comment: |
- Represents using a trailing comma to indicate an implicit rest parameter.
-
- foo { |bar,| }
- ^
-
- foo in [bar,]
- ^
-
- for foo, in bar do end
- ^
-
- foo, = bar
- ^
- - name: InNode
- fields:
- - name: pattern
- type: node
- - name: statements
- type: node?
- kind: StatementsNode
- - name: in_loc
- type: location
- - name: then_loc
- type: location?
- comment: |
- Represents the use of the `in` keyword in a case statement.
-
- case a; in b then c end
- ^^^^^^^^^^^
- - name: IndexAndWriteNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: opening_loc
- type: location
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: closing_loc
- type: location
- - name: block
- type: node?
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator on a call to the `[]` method.
-
- foo.bar[baz] &&= value
- ^^^^^^^^^^^^^^^^^^^^^^
- - name: IndexOperatorWriteNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: opening_loc
- type: location
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: closing_loc
- type: location
- - name: block
- type: node?
- - name: operator
- type: constant
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of an assignment operator on a call to `[]`.
-
- foo.bar[baz] += value
- ^^^^^^^^^^^^^^^^^^^^^
- - name: IndexOrWriteNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node?
- - name: call_operator_loc
- type: location?
- - name: opening_loc
- type: location
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: closing_loc
- type: location
- - name: block
- type: node?
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator on a call to `[]`.
-
- foo.bar[baz] ||= value
- ^^^^^^^^^^^^^^^^^^^^^^
- - name: IndexTargetNode
- fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- - name: receiver
- type: node
- - name: opening_loc
- type: location
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: closing_loc
- type: location
- - name: block
- type: node?
- comment: |
- Represents assigning to an index.
-
- foo[bar], = 1
- ^^^^^^^^
-
- begin
- rescue => foo[bar]
- ^^^^^^^^
- end
-
- for foo[bar] in baz do end
- ^^^^^^^^
- - name: InstanceVariableAndWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `&&=` operator for assignment to an instance variable.
-
- @target &&= value
- ^^^^^^^^^^^^^^^^^
- - name: InstanceVariableOperatorWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: operator
- type: constant
- comment: |
- Represents assigning to an instance variable using an operator that isn't `=`.
-
- @target += value
- ^^^^^^^^^^^^^^^^
- - name: InstanceVariableOrWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents the use of the `||=` operator for assignment to an instance variable.
-
- @target ||= value
- ^^^^^^^^^^^^^^^^^
- - name: InstanceVariableReadNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents referencing an instance variable.
-
- @foo
- ^^^^
- - name: InstanceVariableTargetNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents writing to an instance variable in a context that doesn't have an explicit value.
-
- @foo, @bar = baz
- ^^^^ ^^^^
- - name: InstanceVariableWriteNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: value
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents writing to an instance variable.
-
- @foo = 1
- ^^^^^^^^
- - name: IntegerNode
- fields:
- - name: flags
- type: flags
- kind: IntegerBaseFlags
- comment: |
- Represents an integer number literal.
-
- 1
- ^
- - name: InterpolatedMatchLastLineNode
- fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- - name: opening_loc
- type: location
- - name: parts
- type: node[]
- - name: closing_loc
- type: location
- newline: parts
- comment: |
- Represents a regular expression literal that contains interpolation that
- is being used in the predicate of a conditional to implicitly match
- against the last line read by an IO object.
-
- if /foo #{bar} baz/ then end
- ^^^^^^^^^^^^^^^^
- - name: InterpolatedRegularExpressionNode
- fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- - name: opening_loc
- type: location
- - name: parts
- type: node[]
- - name: closing_loc
- type: location
- newline: parts
- comment: |
- Represents a regular expression literal that contains interpolation.
-
- /foo #{bar} baz/
- ^^^^^^^^^^^^^^^^
- - name: InterpolatedStringNode
- fields:
- - name: opening_loc
- type: location?
- - name: parts
- type: node[]
- - name: closing_loc
- type: location?
- newline: parts
- comment: |
- Represents a string literal that contains interpolation.
-
- "foo #{bar} baz"
- ^^^^^^^^^^^^^^^^
- - name: InterpolatedSymbolNode
- fields:
- - name: opening_loc
- type: location?
- - name: parts
- type: node[]
- - name: closing_loc
- type: location?
- newline: parts
- comment: |
- Represents a symbol literal that contains interpolation.
-
- :"foo #{bar} baz"
- ^^^^^^^^^^^^^^^^^
- - name: InterpolatedXStringNode
- fields:
- - name: opening_loc
- type: location
- - name: parts
- type: node[]
- - name: closing_loc
- type: location
- newline: parts
- comment: |
- Represents an xstring literal that contains interpolation.
-
- `foo #{bar} baz`
- ^^^^^^^^^^^^^^^^
- - name: KeywordHashNode
- fields:
- - name: flags
- type: flags
- kind: KeywordHashNodeFlags
- - name: elements
- type: node[]
- comment: |
- Represents a hash literal without opening and closing braces.
-
- foo(a: b)
- ^^^^
- - name: KeywordRestParameterNode
- fields:
- - name: name
- type: constant?
- - name: name_loc
- type: location?
- - name: operator_loc
- type: location
- comment: |
- Represents a keyword rest parameter to a method, block, or lambda definition.
-
- def a(**b)
- ^^^
- end
- - name: LambdaNode
- fields:
- - name: locals
- type: constant[]
- - name: locals_body_index
- type: uint32
- - name: operator_loc
- type: location
- - name: opening_loc
- type: location
- - name: closing_loc
- type: location
- - name: parameters
- type: node?
- - name: body
- type: node?
- comment: |
- Represents using a lambda literal (not the lambda method call).
-
- ->(value) { value * 2 }
- ^^^^^^^^^^^^^^^^^^^^^^^
- - name: LocalVariableAndWriteNode
- fields:
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: name
- type: constant
- - name: depth
- type: uint32
- comment: |
- Represents the use of the `&&=` operator for assignment to a local variable.
-
- target &&= value
- ^^^^^^^^^^^^^^^^
- - name: LocalVariableOperatorWriteNode
- fields:
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: name
- type: constant
- - name: operator
- type: constant
- - name: depth
- type: uint32
- comment: |
- Represents assigning to a local variable using an operator that isn't `=`.
-
- target += value
- ^^^^^^^^^^^^^^^
- - name: LocalVariableOrWriteNode
- fields:
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- - name: name
- type: constant
- - name: depth
- type: uint32
- comment: |
- Represents the use of the `||=` operator for assignment to a local variable.
-
- target ||= value
- ^^^^^^^^^^^^^^^^
- - name: LocalVariableReadNode
- fields:
- - name: name
- type: constant
- - name: depth
- type: uint32
- comment: |
- Represents reading a local variable. Note that this requires that a local
- variable of the same name has already been written to in the same scope,
- otherwise it is parsed as a method call.
-
- foo
- ^^^
- - name: LocalVariableTargetNode
- fields:
- - name: name
- type: constant
- - name: depth
- type: uint32
- comment: |
- Represents writing to a local variable in a context that doesn't have an explicit value.
-
- foo, bar = baz
- ^^^ ^^^
- - name: LocalVariableWriteNode
- fields:
- - name: name
- type: constant
- - name: depth
- type: uint32
- - name: name_loc
- type: location
- - name: value
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents writing to a local variable.
-
- foo = 1
- ^^^^^^^
- - name: MatchLastLineNode
- fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- - name: opening_loc
- type: location
- - name: content_loc
- type: location
- - name: closing_loc
- type: location
- - name: unescaped
- type: string
- comment: |
- Represents a regular expression literal used in the predicate of a
- conditional to implicitly match against the last line read by an IO
- object.
-
- if /foo/i then end
- ^^^^^^
- - name: MatchPredicateNode
- fields:
- - name: value
- type: node
- - name: pattern
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the modifier `in` operator.
-
- foo in bar
- ^^^^^^^^^^
- - name: MatchRequiredNode
- fields:
- - name: value
- type: node
- - name: pattern
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the `=>` operator.
-
- foo => bar
- ^^^^^^^^^^
- - name: MatchWriteNode
- fields:
- - name: call
- type: node
- kind: CallNode
- - name: targets
- type: node[]
- comment: |
- Represents writing local variables using a regular expression match with
- named capture groups.
-
- /(?<foo>bar)/ =~ baz
- ^^^^^^^^^^^^^^^^^^^^
- - name: MissingNode
- comment: |
- Represents a node that is missing from the source and results in a syntax
- error.
- - name: ModuleNode
- fields:
- - name: locals
- type: constant[]
- - name: module_keyword_loc
- type: location
- - name: constant_path
- type: node
- - name: body
- type: node?
- - name: end_keyword_loc
- type: location
- - name: name
- type: constant
- comment: |
- Represents a module declaration involving the `module` keyword.
-
- module Foo end
- ^^^^^^^^^^^^^^
- - name: MultiTargetNode
- fields:
- - name: lefts
- type: node[]
- - name: rest
- type: node?
- - name: rights
- type: node[]
- - name: lparen_loc
- type: location?
- - name: rparen_loc
- type: location?
- comment: |
- Represents a multi-target expression.
-
- a, (b, c) = 1, 2, 3
- ^^^^^^
- - name: MultiWriteNode
- fields:
- - name: lefts
- type: node[]
- - name: rest
- type: node?
- - name: rights
- type: node[]
- - name: lparen_loc
- type: location?
- - name: rparen_loc
- type: location?
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents a write to a multi-target expression.
-
- a, b, c = 1, 2, 3
- ^^^^^^^^^^^^^^^^^
- - name: NextNode
- fields:
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of the `next` keyword.
-
- next 1
- ^^^^^^
- - name: NilNode
- comment: |
- Represents the use of the `nil` keyword.
-
- nil
- ^^^
- - name: NoKeywordsParameterNode
- fields:
- - name: operator_loc
- type: location
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of `**nil` inside method arguments.
-
- def a(**nil)
- ^^^^^
- end
- - name: NumberedParametersNode
- fields:
- - name: maximum
- type: uint8
- comment: |
- Represents an implicit set of parameters through the use of numbered
- parameters within a block or lambda.
-
- -> { _1 + _2 }
- ^^^^^^^^^^^^^^
- - name: NumberedReferenceReadNode
- fields:
- - name: number
- type: uint32
- comment: |
- Represents reading a numbered reference to a capture in the previous match.
-
- $1
- ^^
- - name: OptionalKeywordParameterNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents an optional keyword parameter to a method, block, or lambda definition.
-
- def a(b: 1)
- ^^^^
- end
- - name: OptionalParameterNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- - name: operator_loc
- type: location
- - name: value
- type: node
- comment: |
- Represents an optional parameter to a method, block, or lambda definition.
-
- def a(b = 1)
- ^^^^^
- end
- - name: OrNode
- fields:
- - name: left
- type: node
- - name: right
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the `||` operator or the `or` keyword.
-
- left or right
- ^^^^^^^^^^^^^
- - name: ParametersNode
- fields:
- - name: requireds
- type: node[]
- - name: optionals
- type: node[]
- - name: rest
- type: node?
- - name: posts
- type: node[]
- - name: keywords
- type: node[]
- - name: keyword_rest
- type: node?
- - name: block
- type: node?
- kind: BlockParameterNode
- comment: |
- Represents the list of parameters on a method, block, or lambda definition.
-
- def a(b, c, d)
- ^^^^^^^
- end
- - name: ParenthesesNode
- fields:
- - name: body
- type: node?
- - name: opening_loc
- type: location
- - name: closing_loc
- type: location
- newline: false
- comment: |
- Represents a parenthesized expression
-
- (10 + 34)
- ^^^^^^^^^
- - name: PinnedExpressionNode
- fields:
- - name: expression
- type: node
- - name: operator_loc
- type: location
- - name: lparen_loc
- type: location
- - name: rparen_loc
- type: location
- comment: |
- Represents the use of the `^` operator for pinning an expression in a
- pattern matching expression.
-
- foo in ^(bar)
- ^^^^^^
- - name: PinnedVariableNode
- fields:
- - name: variable
- type: node
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the `^` operator for pinning a variable in a pattern
- matching expression.
-
- foo in ^bar
- ^^^^
- - name: PostExecutionNode
- fields:
- - name: statements
- type: node?
- kind: StatementsNode
- - name: keyword_loc
- type: location
- - name: opening_loc
- type: location
- - name: closing_loc
- type: location
- comment: |
- Represents the use of the `END` keyword.
-
- END { foo }
- ^^^^^^^^^^^
- - name: PreExecutionNode
- fields:
- - name: statements
- type: node?
- kind: StatementsNode
- - name: keyword_loc
- type: location
- - name: opening_loc
- type: location
- - name: closing_loc
- type: location
- comment: |
- Represents the use of the `BEGIN` keyword.
-
- BEGIN { foo }
- ^^^^^^^^^^^^^
- - name: ProgramNode
- fields:
- - name: locals
- type: constant[]
- - name: statements
- type: node
- kind: StatementsNode
- comment: The top level node of any parse tree.
- - name: RangeNode
- fields:
- - name: flags
- type: flags
- kind: RangeFlags
- - name: left
- type: node?
- - name: right
- type: node?
- - name: operator_loc
- type: location
- comment: |
- Represents the use of the `..` or `...` operators.
-
- 1..2
- ^^^^
-
- c if a =~ /left/ ... b =~ /right/
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- - name: RationalNode
- fields:
- - name: numeric
- type: node
- comment: |
- Represents a rational number literal.
-
- 1.0r
- ^^^^
- - name: RedoNode
- comment: |
- Represents the use of the `redo` keyword.
-
- redo
- ^^^^
- - name: RegularExpressionNode
- fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- - name: opening_loc
- type: location
- - name: content_loc
- type: location
- - name: closing_loc
- type: location
- - name: unescaped
- type: string
- comment: |
- Represents a regular expression literal with no interpolation.
-
- /foo/i
- ^^^^^^
- - name: RequiredKeywordParameterNode
- fields:
- - name: name
- type: constant
- - name: name_loc
- type: location
- comment: |
- Represents a required keyword parameter to a method, block, or lambda definition.
-
- def a(b: )
- ^^
- end
- - name: RequiredParameterNode
- fields:
- - name: name
- type: constant
- comment: |
- Represents a required parameter to a method, block, or lambda definition.
-
- def a(b)
- ^
- end
- - name: RescueModifierNode
- fields:
- - name: expression
- type: node
- - name: keyword_loc
- type: location
- - name: rescue_expression
- type: node
- newline: expression
- comment: |
- Represents an expression modified with a rescue.
-
- foo rescue nil
- ^^^^^^^^^^^^^^
- - name: RescueNode
- fields:
- - name: keyword_loc
- type: location
- - name: exceptions
- type: node[]
- - name: operator_loc
- type: location?
- - name: reference
- type: node?
- - name: statements
- type: node?
- kind: StatementsNode
- - name: consequent
- type: node?
- kind: RescueNode
- comment: |
- Represents a rescue statement.
-
- begin
- rescue Foo, *splat, Bar => ex
- foo
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- end
-
- `Foo, *splat, Bar` are in the `exceptions` field.
- `ex` is in the `exception` field.
- - name: RestParameterNode
- fields:
- - name: name
- type: constant?
- - name: name_loc
- type: location?
- - name: operator_loc
- type: location
- comment: |
- Represents a rest parameter to a method, block, or lambda definition.
-
- def a(*b)
- ^^
- end
- - name: RetryNode
- comment: |
- Represents the use of the `retry` keyword.
-
- retry
- ^^^^^
- - name: ReturnNode
- fields:
- - name: keyword_loc
- type: location
- - name: arguments
- type: node?
- kind: ArgumentsNode
- comment: |
- Represents the use of the `return` keyword.
-
- return 1
- ^^^^^^^^
- - name: SelfNode
- comment: |
- Represents the `self` keyword.
-
- self
- ^^^^
- - name: SingletonClassNode
- fields:
- - name: locals
- type: constant[]
- - name: class_keyword_loc
- type: location
- - name: operator_loc
- type: location
- - name: expression
- type: node
- - name: body
- type: node?
- - name: end_keyword_loc
- type: location
- comment: |
- Represents a singleton class declaration involving the `class` keyword.
-
- class << self end
- ^^^^^^^^^^^^^^^^^
- - name: SourceEncodingNode
- comment: |
- Represents the use of the `__ENCODING__` keyword.
-
- __ENCODING__
- ^^^^^^^^^^^^
- - name: SourceFileNode
- fields:
- - name: filepath
- type: string
- comment: |
- Represents the use of the `__FILE__` keyword.
-
- __FILE__
- ^^^^^^^^
- - name: SourceLineNode
- comment: |
- Represents the use of the `__LINE__` keyword.
-
- __LINE__
- ^^^^^^^^
- - name: SplatNode
- fields:
- - name: operator_loc
- type: location
- - name: expression
- type: node?
- comment: |
- Represents the use of the splat operator.
-
- [*a]
- ^^
- - name: StatementsNode
- fields:
- - name: body
- type: node[]
- comment: |
- Represents a set of statements contained within some scope.
-
- foo; bar; baz
- ^^^^^^^^^^^^^
- - name: StringNode
- fields:
- - name: flags
- type: flags
- kind: StringFlags
- - name: opening_loc
- type: location?
- - name: content_loc
- type: location
- - name: closing_loc
- type: location?
- - name: unescaped
- type: string
- comment: |
- Represents a string literal, a string contained within a `%w` list, or
- plain string content within an interpolated string.
-
- "foo"
- ^^^^^
-
- %w[foo]
- ^^^
-
- "foo #{bar} baz"
- ^^^^ ^^^^
- - name: SuperNode
- fields:
- - name: keyword_loc
- type: location
- - name: lparen_loc
- type: location?
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: rparen_loc
- type: location?
- - name: block
- type: node?
- comment: |
- Represents the use of the `super` keyword with parentheses or arguments.
-
- super()
- ^^^^^^^
-
- super foo, bar
- ^^^^^^^^^^^^^^
- - name: SymbolNode
- fields:
- - name: flags
- type: flags
- kind: SymbolFlags
- - name: opening_loc
- type: location?
- - name: value_loc
- type: location?
- - name: closing_loc
- type: location?
- - name: unescaped
- type: string
- comment: |
- Represents a symbol literal or a symbol contained within a `%i` list.
-
- :foo
- ^^^^
-
- %i[foo]
- ^^^
- - name: TrueNode
- comment: |
- Represents the use of the literal `true` keyword.
-
- true
- ^^^^
- - name: UndefNode
- fields:
- - name: names
- type: node[]
- - name: keyword_loc
- type: location
- comment: |
- Represents the use of the `undef` keyword.
-
- undef :foo, :bar, :baz
- ^^^^^^^^^^^^^^^^^^^^^^
- - name: UnlessNode
- fields:
- - name: keyword_loc
- type: location
- - name: predicate
- type: node
- - name: then_keyword_loc
- type: location?
- - name: statements
- type: node?
- kind: StatementsNode
- - name: consequent
- type: node?
- kind: ElseNode
- - name: end_keyword_loc
- type: location?
- newline: predicate
- comment: |
- Represents the use of the `unless` keyword, either in the block form or the modifier form.
-
- bar unless foo
- ^^^^^^^^^^^^^^
-
- unless foo then bar end
- ^^^^^^^^^^^^^^^^^^^^^^^
- - name: UntilNode
- fields:
- - name: flags
- type: flags
- kind: LoopFlags
- - name: keyword_loc
- type: location
- - name: closing_loc
- type: location?
- - name: predicate
- type: node
- - name: statements
- type: node?
- kind: StatementsNode
- newline: predicate
- comment: |
- Represents the use of the `until` keyword, either in the block form or the modifier form.
-
- bar until foo
- ^^^^^^^^^^^^^
-
- until foo do bar end
- ^^^^^^^^^^^^^^^^^^^^
- - name: WhenNode
- fields:
- - name: keyword_loc
- type: location
- - name: conditions
- type: node[]
- - name: statements
- type: node?
- kind: StatementsNode
- comment: |
- Represents the use of the `when` keyword within a case statement.
-
- case true
- when true
- ^^^^^^^^^
- end
- - name: WhileNode
- fields:
- - name: flags
- type: flags
- kind: LoopFlags
- - name: keyword_loc
- type: location
- - name: closing_loc
- type: location?
- - name: predicate
- type: node
- - name: statements
- type: node?
- kind: StatementsNode
- newline: predicate
- comment: |
- Represents the use of the `while` keyword, either in the block form or the modifier form.
-
- bar while foo
- ^^^^^^^^^^^^^
-
- while foo do bar end
- ^^^^^^^^^^^^^^^^^^^^
- - name: XStringNode
- fields:
- - name: flags
- type: flags
- kind: EncodingFlags
- - name: opening_loc
- type: location
- - name: content_loc
- type: location
- - name: closing_loc
- type: location
- - name: unescaped
- type: string
- comment: |
- Represents an xstring literal with no interpolation.
-
- `foo`
- ^^^^^
- - name: YieldNode
- fields:
- - name: keyword_loc
- type: location
- - name: lparen_loc
- type: location?
- - name: arguments
- type: node?
- kind: ArgumentsNode
- - name: rparen_loc
- type: location?
- comment: |
- Represents the use of the `yield` keyword.
-
- yield 1
- ^^^^^^^
diff --git a/prism/defines.h b/prism/defines.h
deleted file mode 100644
index c9715c4eb0..0000000000
--- a/prism/defines.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * @file defines.h
- *
- * Macro definitions used throughout the prism library.
- *
- * This file should be included first by any *.h or *.c in prism for consistency
- * and to ensure that the macros are defined before they are used.
- */
-#ifndef PRISM_DEFINES_H
-#define PRISM_DEFINES_H
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-/**
- * By default, we compile with -fvisibility=hidden. When this is enabled, we
- * need to mark certain functions as being publically-visible. This macro does
- * that in a compiler-agnostic way.
- */
-#ifndef PRISM_EXPORTED_FUNCTION
-# ifdef PRISM_EXPORT_SYMBOLS
-# ifdef _WIN32
-# define PRISM_EXPORTED_FUNCTION __declspec(dllexport) extern
-# else
-# define PRISM_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern
-# endif
-# else
-# define PRISM_EXPORTED_FUNCTION
-# endif
-#endif
-
-/**
- * Certain compilers support specifying that a function accepts variadic
- * parameters that look like printf format strings to provide a better developer
- * experience when someone is using the function. This macro does that in a
- * compiler-agnostic way.
- */
-#if defined(__GNUC__)
-# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(printf, string_index, argument_index)))
-#elif defined(__clang__)
-# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((__format__(__printf__, string_index, argument_index)))
-#else
-# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index)
-#endif
-
-/**
- * GCC will warn if you specify a function or parameter that is unused at
- * runtime. This macro allows you to mark a function or parameter as unused in a
- * compiler-agnostic way.
- */
-#if defined(__GNUC__)
-# define PRISM_ATTRIBUTE_UNUSED __attribute__((unused))
-#else
-# define PRISM_ATTRIBUTE_UNUSED
-#endif
-
-/**
- * Old Visual Studio versions do not support the inline keyword, so we need to
- * define it to be __inline.
- */
-#if defined(_MSC_VER) && !defined(inline)
-# define inline __inline
-#endif
-
-/**
- * Old Visual Studio versions before 2015 do not implement sprintf, but instead
- * implement _snprintf. We standard that here.
- */
-#if !defined(snprintf) && defined(_MSC_VER) && (_MSC_VER < 1900)
-# define snprintf _snprintf
-#endif
-
-/**
- * A simple utility macro to concatenate two tokens together, necessary when one
- * of the tokens is itself a macro.
- */
-#define PM_CONCATENATE(left, right) left ## right
-
-/**
- * We want to be able to use static assertions, but they weren't standardized
- * until C11. As such, we polyfill it here by making a hacky typedef that will
- * fail to compile due to a negative array size if the condition is false.
- */
-#if defined(_Static_assert)
-# define PM_STATIC_ASSERT(line, condition, message) _Static_assert(condition, message)
-#else
-# define PM_STATIC_ASSERT(line, condition, message) typedef char PM_CONCATENATE(static_assert_, line)[(condition) ? 1 : -1]
-#endif
-
-#endif
diff --git a/prism/diagnostic.c b/prism/diagnostic.c
deleted file mode 100644
index 1fc8c50cb5..0000000000
--- a/prism/diagnostic.c
+++ /dev/null
@@ -1,355 +0,0 @@
-#include "prism/diagnostic.h"
-
-/**
- * ## Message composition
- *
- * When composing an error message, use sentence fragments.
- *
- * Try describing the property of the code that caused the error, rather than
- * the rule that is being violated. It may help to use a fragment that completes
- * a sentence beginning, "the parser encountered (a) ...". If appropriate, add a
- * description of the rule violation (or other helpful context) after a
- * semicolon.
- *
- * For example:, instead of "control escape sequence cannot be doubled", prefer:
- *
- * > "invalid control escape sequence; control cannot be repeated"
- *
- * In some cases, where the failure is more general or syntax expectations are
- * violated, it may make more sense to use a fragment that completes a sentence
- * beginning, "the parser ...".
- *
- * For example:
- *
- * > "expected an expression after `(`"
- * > "cannot parse the expression"
- *
- * ## Message style guide
- *
- * - Use articles like "a", "an", and "the" when appropriate.
- * - e.g., prefer "cannot parse the expression" to "cannot parse expression".
- * - Use the common name for tokens and nodes.
- * - e.g., prefer "keyword splat" to "assoc splat"
- * - e.g., prefer "embedded document" to "embdoc"
- * - Do not capitalize the initial word of the message.
- * - Use back ticks around token literals
- * - e.g., "Expected a `=>` between the hash key and value"
- * - Do not use `.` or other punctuation at the end of the message.
- * - Do not use contractions like "can't". Prefer "cannot" to "can not".
- * - For tokens that can have multiple meanings, reference the token and its meaning.
- * - e.g., "`*` splat argument" is clearer and more complete than "splat argument" or "`*` argument"
- *
- * ## Error names (PM_ERR_*)
- *
- * - When appropriate, prefer node name to token name.
- * - e.g., prefer "SPLAT" to "STAR" in the context of argument parsing.
- * - Prefer token name to common name.
- * - e.g., prefer "STAR" to "ASTERISK".
- * - Try to order the words in the name from more general to more specific,
- * - e.g., "INVALID_NUMBER_DECIMAL" is better than "DECIMAL_INVALID_NUMBER".
- * - When in doubt, look for similar patterns and name them so that they are grouped when lexically
- * sorted. See PM_ERR_ARGUMENT_NO_FORWARDING_* for an example.
- */
-static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
- [PM_ERR_ALIAS_ARGUMENT] = "invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable",
- [PM_ERR_AMPAMPEQ_MULTI_ASSIGN] = "unexpected `&&=` in a multiple assignment",
- [PM_ERR_ARGUMENT_AFTER_BLOCK] = "unexpected argument after a block argument",
- [PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES] = "unexpected argument after `...`",
- [PM_ERR_ARGUMENT_BARE_HASH] = "unexpected bare hash argument",
- [PM_ERR_ARGUMENT_BLOCK_MULTI] = "multiple block arguments; only one block is allowed",
- [PM_ERR_ARGUMENT_FORMAL_CLASS] = "invalid formal argument; formal argument cannot be a class variable",
- [PM_ERR_ARGUMENT_FORMAL_CONSTANT] = "invalid formal argument; formal argument cannot be a constant",
- [PM_ERR_ARGUMENT_FORMAL_GLOBAL] = "invalid formal argument; formal argument cannot be a global variable",
- [PM_ERR_ARGUMENT_FORMAL_IVAR] = "invalid formal argument; formal argument cannot be an instance variable",
- [PM_ERR_ARGUMENT_FORWARDING_UNBOUND] = "unexpected `...` in an non-parenthesized call",
- [PM_ERR_ARGUMENT_NO_FORWARDING_AMP] = "unexpected `&` when the parent method is not forwarding",
- [PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = "unexpected `...` when the parent method is not forwarding",
- [PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = "unexpected `*` when the parent method is not forwarding",
- [PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = "unexpected `*` splat argument after a `**` keyword splat argument",
- [PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT] = "unexpected `*` splat argument after a `*` splat argument",
- [PM_ERR_ARGUMENT_TERM_PAREN] = "expected a `)` to close the arguments",
- [PM_ERR_ARGUMENT_UNEXPECTED_BLOCK] = "unexpected `{` after a method call without parenthesis",
- [PM_ERR_ARRAY_ELEMENT] = "expected an element for the array",
- [PM_ERR_ARRAY_EXPRESSION] = "expected an expression for the array element",
- [PM_ERR_ARRAY_EXPRESSION_AFTER_STAR] = "expected an expression after `*` in the array",
- [PM_ERR_ARRAY_SEPARATOR] = "expected a `,` separator for the array elements",
- [PM_ERR_ARRAY_TERM] = "expected a `]` to close the array",
- [PM_ERR_BEGIN_LONELY_ELSE] = "unexpected `else` in `begin` block; a `rescue` clause must precede `else`",
- [PM_ERR_BEGIN_TERM] = "expected an `end` to close the `begin` statement",
- [PM_ERR_BEGIN_UPCASE_BRACE] = "expected a `{` after `BEGIN`",
- [PM_ERR_BEGIN_UPCASE_TERM] = "expected a `}` to close the `BEGIN` statement",
- [PM_ERR_BEGIN_UPCASE_TOPLEVEL] = "BEGIN is permitted only at toplevel",
- [PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE] = "expected a local variable name in the block parameters",
- [PM_ERR_BLOCK_PARAM_PIPE_TERM] = "expected the block parameters to end with `|`",
- [PM_ERR_BLOCK_TERM_BRACE] = "expected a block beginning with `{` to end with `}`",
- [PM_ERR_BLOCK_TERM_END] = "expected a block beginning with `do` to end with `end`",
- [PM_ERR_CANNOT_PARSE_EXPRESSION] = "cannot parse the expression",
- [PM_ERR_CANNOT_PARSE_STRING_PART] = "cannot parse the string part",
- [PM_ERR_CASE_EXPRESSION_AFTER_CASE] = "expected an expression after `case`",
- [PM_ERR_CASE_EXPRESSION_AFTER_WHEN] = "expected an expression after `when`",
- [PM_ERR_CASE_MATCH_MISSING_PREDICATE] = "expected a predicate for a case matching statement",
- [PM_ERR_CASE_MISSING_CONDITIONS] = "expected a `when` or `in` clause after `case`",
- [PM_ERR_CASE_TERM] = "expected an `end` to close the `case` statement",
- [PM_ERR_CLASS_IN_METHOD] = "unexpected class definition in a method definition",
- [PM_ERR_CLASS_NAME] = "expected a constant name after `class`",
- [PM_ERR_CLASS_SUPERCLASS] = "expected a superclass after `<`",
- [PM_ERR_CLASS_TERM] = "expected an `end` to close the `class` statement",
- [PM_ERR_CLASS_UNEXPECTED_END] = "unexpected `end`, expecting ';' or '\\n'",
- [PM_ERR_CONDITIONAL_ELSIF_PREDICATE] = "expected a predicate expression for the `elsif` statement",
- [PM_ERR_CONDITIONAL_IF_PREDICATE] = "expected a predicate expression for the `if` statement",
- [PM_ERR_CONDITIONAL_PREDICATE_TERM] = "expected `then` or `;` or '\\n'",
- [PM_ERR_CONDITIONAL_TERM] = "expected an `end` to close the conditional clause",
- [PM_ERR_CONDITIONAL_TERM_ELSE] = "expected an `end` to close the `else` clause",
- [PM_ERR_CONDITIONAL_UNLESS_PREDICATE] = "expected a predicate expression for the `unless` statement",
- [PM_ERR_CONDITIONAL_UNTIL_PREDICATE] = "expected a predicate expression for the `until` statement",
- [PM_ERR_CONDITIONAL_WHILE_PREDICATE] = "expected a predicate expression for the `while` statement",
- [PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = "expected a constant after the `::` operator",
- [PM_ERR_DEF_ENDLESS] = "could not parse the endless method body",
- [PM_ERR_DEF_ENDLESS_SETTER] = "invalid method name; a setter method cannot be defined in an endless method definition",
- [PM_ERR_DEF_NAME] = "expected a method name",
- [PM_ERR_DEF_NAME_AFTER_RECEIVER] = "expected a method name after the receiver",
- [PM_ERR_DEF_PARAMS_TERM] = "expected a delimiter to close the parameters",
- [PM_ERR_DEF_PARAMS_TERM_PAREN] = "expected a `)` to close the parameters",
- [PM_ERR_DEF_RECEIVER] = "expected a receiver for the method definition",
- [PM_ERR_DEF_RECEIVER_TERM] = "expected a `.` or `::` after the receiver in a method definition",
- [PM_ERR_DEF_TERM] = "expected an `end` to close the `def` statement",
- [PM_ERR_DEFINED_EXPRESSION] = "expected an expression after `defined?`",
- [PM_ERR_EMBDOC_TERM] = "could not find a terminator for the embedded document",
- [PM_ERR_EMBEXPR_END] = "expected a `}` to close the embedded expression",
- [PM_ERR_EMBVAR_INVALID] = "invalid embedded variable",
- [PM_ERR_END_UPCASE_BRACE] = "expected a `{` after `END`",
- [PM_ERR_END_UPCASE_TERM] = "expected a `}` to close the `END` statement",
- [PM_ERR_ESCAPE_INVALID_CONTROL] = "invalid control escape sequence",
- [PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = "invalid control escape sequence; control cannot be repeated",
- [PM_ERR_ESCAPE_INVALID_HEXADECIMAL] = "invalid hexadecimal escape sequence",
- [PM_ERR_ESCAPE_INVALID_META] = "invalid meta escape sequence",
- [PM_ERR_ESCAPE_INVALID_META_REPEAT] = "invalid meta escape sequence; meta cannot be repeated",
- [PM_ERR_ESCAPE_INVALID_UNICODE] = "invalid Unicode escape sequence",
- [PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = "invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags",
- [PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = "invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal",
- [PM_ERR_ESCAPE_INVALID_UNICODE_LONG] = "invalid Unicode escape sequence; maximum length is 6 digits",
- [PM_ERR_ESCAPE_INVALID_UNICODE_TERM] = "invalid Unicode escape sequence; needs closing `}`",
- [PM_ERR_EXPECT_ARGUMENT] = "expected an argument",
- [PM_ERR_EXPECT_EOL_AFTER_STATEMENT] = "expected a newline or semicolon after the statement",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = "expected an expression after `&&=`",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ] = "expected an expression after `||=`",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA] = "expected an expression after `,`",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL] = "expected an expression after `=`",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS] = "expected an expression after `<<`",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN] = "expected an expression after `(`",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR] = "expected an expression after the operator",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT] = "expected an expression after `*` splat in an argument",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH] = "expected an expression after `**` in a hash",
- [PM_ERR_EXPECT_EXPRESSION_AFTER_STAR] = "expected an expression after `*`",
- [PM_ERR_EXPECT_IDENT_REQ_PARAMETER] = "expected an identifier for the required parameter",
- [PM_ERR_EXPECT_LPAREN_REQ_PARAMETER] = "expected a `(` to start a required parameter",
- [PM_ERR_EXPECT_RBRACKET] = "expected a matching `]`",
- [PM_ERR_EXPECT_RPAREN] = "expected a matching `)`",
- [PM_ERR_EXPECT_RPAREN_AFTER_MULTI] = "expected a `)` after multiple assignment",
- [PM_ERR_EXPECT_RPAREN_REQ_PARAMETER] = "expected a `)` to end a required parameter",
- [PM_ERR_EXPECT_STRING_CONTENT] = "expected string content after opening string delimiter",
- [PM_ERR_EXPECT_WHEN_DELIMITER] = "expected a delimiter after the predicates of a `when` clause",
- [PM_ERR_EXPRESSION_BARE_HASH] = "unexpected bare hash in expression",
- [PM_ERR_FOR_COLLECTION] = "expected a collection after the `in` in a `for` statement",
- [PM_ERR_FOR_INDEX] = "expected an index after `for`",
- [PM_ERR_FOR_IN] = "expected an `in` after the index in a `for` statement",
- [PM_ERR_FOR_TERM] = "expected an `end` to close the `for` loop",
- [PM_ERR_HASH_EXPRESSION_AFTER_LABEL] = "expected an expression after the label in a hash",
- [PM_ERR_HASH_KEY] = "expected a key in the hash literal",
- [PM_ERR_HASH_ROCKET] = "expected a `=>` between the hash key and value",
- [PM_ERR_HASH_TERM] = "expected a `}` to close the hash literal",
- [PM_ERR_HASH_VALUE] = "expected a value in the hash literal",
- [PM_ERR_HEREDOC_TERM] = "could not find a terminator for the heredoc",
- [PM_ERR_INCOMPLETE_QUESTION_MARK] = "incomplete expression at `?`",
- [PM_ERR_INCOMPLETE_VARIABLE_CLASS] = "incomplete class variable",
- [PM_ERR_INCOMPLETE_VARIABLE_INSTANCE] = "incomplete instance variable",
- [PM_ERR_INVALID_ENCODING_MAGIC_COMMENT] = "unknown or invalid encoding in the magic comment",
- [PM_ERR_INVALID_FLOAT_EXPONENT] = "invalid exponent",
- [PM_ERR_INVALID_NUMBER_BINARY] = "invalid binary number",
- [PM_ERR_INVALID_NUMBER_DECIMAL] = "invalid decimal number",
- [PM_ERR_INVALID_NUMBER_HEXADECIMAL] = "invalid hexadecimal number",
- [PM_ERR_INVALID_NUMBER_OCTAL] = "invalid octal number",
- [PM_ERR_INVALID_NUMBER_UNDERSCORE] = "invalid underscore placement in number",
- [PM_ERR_INVALID_PERCENT] = "invalid `%` token", // TODO WHAT?
- [PM_ERR_INVALID_TOKEN] = "invalid token", // TODO WHAT?
- [PM_ERR_INVALID_VARIABLE_GLOBAL] = "invalid global variable",
- [PM_ERR_LAMBDA_OPEN] = "expected a `do` keyword or a `{` to open the lambda block",
- [PM_ERR_LAMBDA_TERM_BRACE] = "expected a lambda block beginning with `{` to end with `}`",
- [PM_ERR_LAMBDA_TERM_END] = "expected a lambda block beginning with `do` to end with `end`",
- [PM_ERR_LIST_I_LOWER_ELEMENT] = "expected a symbol in a `%i` list",
- [PM_ERR_LIST_I_LOWER_TERM] = "expected a closing delimiter for the `%i` list",
- [PM_ERR_LIST_I_UPPER_ELEMENT] = "expected a symbol in a `%I` list",
- [PM_ERR_LIST_I_UPPER_TERM] = "expected a closing delimiter for the `%I` list",
- [PM_ERR_LIST_W_LOWER_ELEMENT] = "expected a string in a `%w` list",
- [PM_ERR_LIST_W_LOWER_TERM] = "expected a closing delimiter for the `%w` list",
- [PM_ERR_LIST_W_UPPER_ELEMENT] = "expected a string in a `%W` list",
- [PM_ERR_LIST_W_UPPER_TERM] = "expected a closing delimiter for the `%W` list",
- [PM_ERR_MALLOC_FAILED] = "failed to allocate memory",
- [PM_ERR_MIXED_ENCODING] = "UTF-8 mixed within %s source",
- [PM_ERR_MODULE_IN_METHOD] = "unexpected module definition in a method definition",
- [PM_ERR_MODULE_NAME] = "expected a constant name after `module`",
- [PM_ERR_MODULE_TERM] = "expected an `end` to close the `module` statement",
- [PM_ERR_MULTI_ASSIGN_MULTI_SPLATS] = "multiple splats in multiple assignment",
- [PM_ERR_NOT_EXPRESSION] = "expected an expression after `not`",
- [PM_ERR_NUMBER_LITERAL_UNDERSCORE] = "number literal ending with a `_`",
- [PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED] = "numbered parameters are not allowed when an ordinary parameter is defined",
- [PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE] = "numbered parameter is already used in outer scope",
- [PM_ERR_OPERATOR_MULTI_ASSIGN] = "unexpected operator for a multiple assignment",
- [PM_ERR_OPERATOR_WRITE_ARGUMENTS] = "unexpected operator after a call with arguments",
- [PM_ERR_OPERATOR_WRITE_BLOCK] = "unexpected operator after a call with a block",
- [PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "unexpected multiple `**` splat parameters",
- [PM_ERR_PARAMETER_BLOCK_MULTI] = "multiple block parameters; only one block is allowed",
- [PM_ERR_PARAMETER_CIRCULAR] = "parameter default value references itself",
- [PM_ERR_PARAMETER_METHOD_NAME] = "unexpected name for a parameter",
- [PM_ERR_PARAMETER_NAME_REPEAT] = "repeated parameter name",
- [PM_ERR_PARAMETER_NO_DEFAULT] = "expected a default value for the parameter",
- [PM_ERR_PARAMETER_NO_DEFAULT_KW] = "expected a default value for the keyword parameter",
- [PM_ERR_PARAMETER_NUMBERED_RESERVED] = "%.2s is reserved for numbered parameters",
- [PM_ERR_PARAMETER_ORDER] = "unexpected parameter order",
- [PM_ERR_PARAMETER_SPLAT_MULTI] = "unexpected multiple `*` splat parameters",
- [PM_ERR_PARAMETER_STAR] = "unexpected parameter `*`",
- [PM_ERR_PARAMETER_UNEXPECTED_FWD] = "unexpected `...` in parameters",
- [PM_ERR_PARAMETER_WILD_LOOSE_COMMA] = "unexpected `,` in parameters",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = "expected a pattern expression after the `[` operator",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = "expected a pattern expression after `,`",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET] = "expected a pattern expression after `=>`",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_IN] = "expected a pattern expression after the `in` keyword",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_KEY] = "expected a pattern expression after the key",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN] = "expected a pattern expression after the `(` operator",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_PIN] = "expected a pattern expression after the `^` pin operator",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = "expected a pattern expression after the `|` operator",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = "expected a pattern expression after the range operator",
- [PM_ERR_PATTERN_EXPRESSION_AFTER_REST] = "unexpected pattern expression after the `**` expression",
- [PM_ERR_PATTERN_HASH_KEY] = "expected a key in the hash pattern",
- [PM_ERR_PATTERN_HASH_KEY_LABEL] = "expected a label as the key in the hash pattern", // TODO // THIS // AND // ABOVE // IS WEIRD
- [PM_ERR_PATTERN_IDENT_AFTER_HROCKET] = "expected an identifier after the `=>` operator",
- [PM_ERR_PATTERN_LABEL_AFTER_COMMA] = "expected a label after the `,` in the hash pattern",
- [PM_ERR_PATTERN_REST] = "unexpected rest pattern",
- [PM_ERR_PATTERN_TERM_BRACE] = "expected a `}` to close the pattern expression",
- [PM_ERR_PATTERN_TERM_BRACKET] = "expected a `]` to close the pattern expression",
- [PM_ERR_PATTERN_TERM_PAREN] = "expected a `)` to close the pattern expression",
- [PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN] = "unexpected `||=` in a multiple assignment",
- [PM_ERR_REGEXP_TERM] = "expected a closing delimiter for the regular expression",
- [PM_ERR_RESCUE_EXPRESSION] = "expected a rescued expression",
- [PM_ERR_RESCUE_MODIFIER_VALUE] = "expected a value after the `rescue` modifier",
- [PM_ERR_RESCUE_TERM] = "expected a closing delimiter for the `rescue` clause",
- [PM_ERR_RESCUE_VARIABLE] = "expected an exception variable after `=>` in a rescue statement",
- [PM_ERR_RETURN_INVALID] = "invalid `return` in a class or module body",
- [PM_ERR_STATEMENT_ALIAS] = "unexpected an `alias` at a non-statement position",
- [PM_ERR_STATEMENT_POSTEXE_END] = "unexpected an `END` at a non-statement position",
- [PM_ERR_STATEMENT_PREEXE_BEGIN] = "unexpected a `BEGIN` at a non-statement position",
- [PM_ERR_STATEMENT_UNDEF] = "unexpected an `undef` at a non-statement position",
- [PM_ERR_STRING_CONCATENATION] = "expected a string for concatenation",
- [PM_ERR_STRING_INTERPOLATED_TERM] = "expected a closing delimiter for the interpolated string",
- [PM_ERR_STRING_LITERAL_TERM] = "expected a closing delimiter for the string literal",
- [PM_ERR_SYMBOL_INVALID] = "invalid symbol", // TODO expected symbol? prism.c ~9719
- [PM_ERR_SYMBOL_TERM_DYNAMIC] = "expected a closing delimiter for the dynamic symbol",
- [PM_ERR_SYMBOL_TERM_INTERPOLATED] = "expected a closing delimiter for the interpolated symbol",
- [PM_ERR_TERNARY_COLON] = "expected a `:` after the true expression of a ternary operator",
- [PM_ERR_TERNARY_EXPRESSION_FALSE] = "expected an expression after `:` in the ternary operator",
- [PM_ERR_TERNARY_EXPRESSION_TRUE] = "expected an expression after `?` in the ternary operator",
- [PM_ERR_UNDEF_ARGUMENT] = "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument",
- [PM_ERR_UNARY_RECEIVER_BANG] = "expected a receiver for unary `!`",
- [PM_ERR_UNARY_RECEIVER_MINUS] = "expected a receiver for unary `-`",
- [PM_ERR_UNARY_RECEIVER_PLUS] = "expected a receiver for unary `+`",
- [PM_ERR_UNARY_RECEIVER_TILDE] = "expected a receiver for unary `~`",
- [PM_ERR_UNTIL_TERM] = "expected an `end` to close the `until` statement",
- [PM_ERR_VOID_EXPRESSION] = "unexpected void value expression",
- [PM_ERR_WHILE_TERM] = "expected an `end` to close the `while` statement",
- [PM_ERR_WRITE_TARGET_IN_METHOD] = "dynamic constant assignment",
- [PM_ERR_WRITE_TARGET_READONLY] = "immutable variable as a write target",
- [PM_ERR_WRITE_TARGET_UNEXPECTED] = "unexpected write target",
- [PM_ERR_XSTRING_TERM] = "expected a closing delimiter for the `%x` or backtick string",
- [PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS] = "ambiguous first argument; put parentheses or a space even after `-` operator",
- [PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = "ambiguous first argument; put parentheses or a space even after `+` operator",
- [PM_WARN_AMBIGUOUS_PREFIX_STAR] = "ambiguous `*` has been interpreted as an argument prefix",
- [PM_WARN_AMBIGUOUS_SLASH] = "ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator",
- [PM_WARN_END_IN_METHOD] = "END in method; use at_exit",
-};
-
-static const char*
-pm_diagnostic_message(pm_diagnostic_id_t diag_id) {
- assert(diag_id < PM_DIAGNOSTIC_ID_LEN);
-
- const char *message = diagnostic_messages[diag_id];
- assert(message);
-
- return message;
-}
-
-/**
- * Append an error to the given list of diagnostic.
- */
-bool
-pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) {
- pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) calloc(sizeof(pm_diagnostic_t), 1);
- if (diagnostic == NULL) return false;
-
- *diagnostic = (pm_diagnostic_t) {
- .location = { start, end },
- .message = pm_diagnostic_message(diag_id),
- .owned = false
- };
-
- pm_list_append(list, (pm_list_node_t *) diagnostic);
- return true;
-}
-
-/**
- * Append a diagnostic to the given list of diagnostics that is using a format
- * string for its message.
- */
-bool
-pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...) {
- va_list arguments;
- va_start(arguments, diag_id);
-
- const char *format = pm_diagnostic_message(diag_id);
- int result = vsnprintf(NULL, 0, format, arguments);
- va_end(arguments);
-
- if (result < 0) {
- return false;
- }
-
- pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) calloc(sizeof(pm_diagnostic_t), 1);
- if (diagnostic == NULL) {
- return false;
- }
-
- size_t length = (size_t) (result + 1);
- char *message = (char *) malloc(length);
- if (message == NULL) {
- free(diagnostic);
- return false;
- }
-
- va_start(arguments, diag_id);
- vsnprintf(message, length, format, arguments);
- va_end(arguments);
-
- *diagnostic = (pm_diagnostic_t) {
- .location = { start, end },
- .message = message,
- .owned = true
- };
-
- pm_list_append(list, (pm_list_node_t *) diagnostic);
- return true;
-}
-
-/**
- * Deallocate the internal state of the given diagnostic list.
- */
-void
-pm_diagnostic_list_free(pm_list_t *list) {
- pm_list_node_t *node, *next;
-
- for (node = list->head; node != NULL; node = next) {
- next = node->next;
- pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) node;
-
- if (diagnostic->owned) free((void *) diagnostic->message);
- free(diagnostic);
- }
-}
diff --git a/prism/diagnostic.h b/prism/diagnostic.h
deleted file mode 100644
index fc1f0c2b4b..0000000000
--- a/prism/diagnostic.h
+++ /dev/null
@@ -1,297 +0,0 @@
-/**
- * @file diagnostic.h
- *
- * A list of diagnostics generated during parsing.
- */
-#ifndef PRISM_DIAGNOSTIC_H
-#define PRISM_DIAGNOSTIC_H
-
-#include "prism/ast.h"
-#include "prism/defines.h"
-#include "prism/util/pm_list.h"
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <assert.h>
-
-/**
- * This struct represents a diagnostic generated during parsing.
- *
- * @extends pm_list_node_t
- */
-typedef struct {
- /** The embedded base node. */
- pm_list_node_t node;
-
- /** The location of the diagnostic in the source. */
- pm_location_t location;
-
- /** The message associated with the diagnostic. */
- const char *message;
-
- /**
- * Whether or not the memory related to the message of this diagnostic is
- * owned by this diagnostic. If it is, it needs to be freed when the
- * diagnostic is freed.
- */
- bool owned;
-} pm_diagnostic_t;
-
-/**
- * The diagnostic IDs of all of the diagnostics, used to communicate the types
- * of errors between the parser and the user.
- */
-typedef enum {
- PM_ERR_ALIAS_ARGUMENT,
- PM_ERR_AMPAMPEQ_MULTI_ASSIGN,
- PM_ERR_ARGUMENT_AFTER_BLOCK,
- PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES,
- PM_ERR_ARGUMENT_BARE_HASH,
- PM_ERR_ARGUMENT_BLOCK_MULTI,
- PM_ERR_ARGUMENT_FORMAL_CLASS,
- PM_ERR_ARGUMENT_FORMAL_CONSTANT,
- PM_ERR_ARGUMENT_FORMAL_GLOBAL,
- PM_ERR_ARGUMENT_FORMAL_IVAR,
- PM_ERR_ARGUMENT_FORWARDING_UNBOUND,
- PM_ERR_ARGUMENT_NO_FORWARDING_AMP,
- PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
- PM_ERR_ARGUMENT_NO_FORWARDING_STAR,
- PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT,
- PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT,
- PM_ERR_ARGUMENT_TERM_PAREN,
- PM_ERR_ARGUMENT_UNEXPECTED_BLOCK,
- PM_ERR_ARRAY_ELEMENT,
- PM_ERR_ARRAY_EXPRESSION,
- PM_ERR_ARRAY_EXPRESSION_AFTER_STAR,
- PM_ERR_ARRAY_SEPARATOR,
- PM_ERR_ARRAY_TERM,
- PM_ERR_BEGIN_LONELY_ELSE,
- PM_ERR_BEGIN_TERM,
- PM_ERR_BEGIN_UPCASE_BRACE,
- PM_ERR_BEGIN_UPCASE_TERM,
- PM_ERR_BEGIN_UPCASE_TOPLEVEL,
- PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE,
- PM_ERR_BLOCK_PARAM_PIPE_TERM,
- PM_ERR_BLOCK_TERM_BRACE,
- PM_ERR_BLOCK_TERM_END,
- PM_ERR_CANNOT_PARSE_EXPRESSION,
- PM_ERR_CANNOT_PARSE_STRING_PART,
- PM_ERR_CASE_EXPRESSION_AFTER_CASE,
- PM_ERR_CASE_EXPRESSION_AFTER_WHEN,
- PM_ERR_CASE_MATCH_MISSING_PREDICATE,
- PM_ERR_CASE_MISSING_CONDITIONS,
- PM_ERR_CASE_TERM,
- PM_ERR_CLASS_IN_METHOD,
- PM_ERR_CLASS_NAME,
- PM_ERR_CLASS_SUPERCLASS,
- PM_ERR_CLASS_TERM,
- PM_ERR_CLASS_UNEXPECTED_END,
- PM_ERR_CONDITIONAL_ELSIF_PREDICATE,
- PM_ERR_CONDITIONAL_IF_PREDICATE,
- PM_ERR_CONDITIONAL_PREDICATE_TERM,
- PM_ERR_CONDITIONAL_TERM,
- PM_ERR_CONDITIONAL_TERM_ELSE,
- PM_ERR_CONDITIONAL_UNLESS_PREDICATE,
- PM_ERR_CONDITIONAL_UNTIL_PREDICATE,
- PM_ERR_CONDITIONAL_WHILE_PREDICATE,
- PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT,
- PM_ERR_DEF_ENDLESS,
- PM_ERR_DEF_ENDLESS_SETTER,
- PM_ERR_DEF_NAME,
- PM_ERR_DEF_NAME_AFTER_RECEIVER,
- PM_ERR_DEF_PARAMS_TERM,
- PM_ERR_DEF_PARAMS_TERM_PAREN,
- PM_ERR_DEF_RECEIVER,
- PM_ERR_DEF_RECEIVER_TERM,
- PM_ERR_DEF_TERM,
- PM_ERR_DEFINED_EXPRESSION,
- PM_ERR_EMBDOC_TERM,
- PM_ERR_EMBEXPR_END,
- PM_ERR_EMBVAR_INVALID,
- PM_ERR_END_UPCASE_BRACE,
- PM_ERR_END_UPCASE_TERM,
- PM_ERR_ESCAPE_INVALID_CONTROL,
- PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT,
- PM_ERR_ESCAPE_INVALID_HEXADECIMAL,
- PM_ERR_ESCAPE_INVALID_META,
- PM_ERR_ESCAPE_INVALID_META_REPEAT,
- PM_ERR_ESCAPE_INVALID_UNICODE,
- PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS,
- PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL,
- PM_ERR_ESCAPE_INVALID_UNICODE_LONG,
- PM_ERR_ESCAPE_INVALID_UNICODE_TERM,
- PM_ERR_EXPECT_ARGUMENT,
- PM_ERR_EXPECT_EOL_AFTER_STATEMENT,
- PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ,
- PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ,
- PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA,
- PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL,
- PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS,
- PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN,
- PM_ERR_EXPECT_EXPRESSION_AFTER_QUESTION,
- PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR,
- PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT,
- PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH,
- PM_ERR_EXPECT_EXPRESSION_AFTER_STAR,
- PM_ERR_EXPECT_IDENT_REQ_PARAMETER,
- PM_ERR_EXPECT_LPAREN_REQ_PARAMETER,
- PM_ERR_EXPECT_RBRACKET,
- PM_ERR_EXPECT_RPAREN,
- PM_ERR_EXPECT_RPAREN_AFTER_MULTI,
- PM_ERR_EXPECT_RPAREN_REQ_PARAMETER,
- PM_ERR_EXPECT_STRING_CONTENT,
- PM_ERR_EXPECT_WHEN_DELIMITER,
- PM_ERR_EXPRESSION_BARE_HASH,
- PM_ERR_FOR_COLLECTION,
- PM_ERR_FOR_IN,
- PM_ERR_FOR_INDEX,
- PM_ERR_FOR_TERM,
- PM_ERR_HASH_EXPRESSION_AFTER_LABEL,
- PM_ERR_HASH_KEY,
- PM_ERR_HASH_ROCKET,
- PM_ERR_HASH_TERM,
- PM_ERR_HASH_VALUE,
- PM_ERR_HEREDOC_TERM,
- PM_ERR_INCOMPLETE_QUESTION_MARK,
- PM_ERR_INCOMPLETE_VARIABLE_CLASS,
- PM_ERR_INCOMPLETE_VARIABLE_INSTANCE,
- PM_ERR_INVALID_ENCODING_MAGIC_COMMENT,
- PM_ERR_INVALID_FLOAT_EXPONENT,
- PM_ERR_INVALID_NUMBER_BINARY,
- PM_ERR_INVALID_NUMBER_DECIMAL,
- PM_ERR_INVALID_NUMBER_HEXADECIMAL,
- PM_ERR_INVALID_NUMBER_OCTAL,
- PM_ERR_INVALID_NUMBER_UNDERSCORE,
- PM_ERR_INVALID_PERCENT,
- PM_ERR_INVALID_TOKEN,
- PM_ERR_INVALID_VARIABLE_GLOBAL,
- PM_ERR_LAMBDA_OPEN,
- PM_ERR_LAMBDA_TERM_BRACE,
- PM_ERR_LAMBDA_TERM_END,
- PM_ERR_LIST_I_LOWER_ELEMENT,
- PM_ERR_LIST_I_LOWER_TERM,
- PM_ERR_LIST_I_UPPER_ELEMENT,
- PM_ERR_LIST_I_UPPER_TERM,
- PM_ERR_LIST_W_LOWER_ELEMENT,
- PM_ERR_LIST_W_LOWER_TERM,
- PM_ERR_LIST_W_UPPER_ELEMENT,
- PM_ERR_LIST_W_UPPER_TERM,
- PM_ERR_MALLOC_FAILED,
- PM_ERR_MIXED_ENCODING,
- PM_ERR_MODULE_IN_METHOD,
- PM_ERR_MODULE_NAME,
- PM_ERR_MODULE_TERM,
- PM_ERR_MULTI_ASSIGN_MULTI_SPLATS,
- PM_ERR_NOT_EXPRESSION,
- PM_ERR_NUMBER_LITERAL_UNDERSCORE,
- PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED,
- PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE,
- PM_ERR_OPERATOR_MULTI_ASSIGN,
- PM_ERR_OPERATOR_WRITE_ARGUMENTS,
- PM_ERR_OPERATOR_WRITE_BLOCK,
- PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
- PM_ERR_PARAMETER_BLOCK_MULTI,
- PM_ERR_PARAMETER_CIRCULAR,
- PM_ERR_PARAMETER_METHOD_NAME,
- PM_ERR_PARAMETER_NAME_REPEAT,
- PM_ERR_PARAMETER_NO_DEFAULT,
- PM_ERR_PARAMETER_NO_DEFAULT_KW,
- PM_ERR_PARAMETER_NUMBERED_RESERVED,
- PM_ERR_PARAMETER_ORDER,
- PM_ERR_PARAMETER_SPLAT_MULTI,
- PM_ERR_PARAMETER_STAR,
- PM_ERR_PARAMETER_UNEXPECTED_FWD,
- PM_ERR_PARAMETER_WILD_LOOSE_COMMA,
- PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET,
- PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET,
- PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA,
- PM_ERR_PATTERN_EXPRESSION_AFTER_IN,
- PM_ERR_PATTERN_EXPRESSION_AFTER_KEY,
- PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN,
- PM_ERR_PATTERN_EXPRESSION_AFTER_PIN,
- PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE,
- PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE,
- PM_ERR_PATTERN_EXPRESSION_AFTER_REST,
- PM_ERR_PATTERN_HASH_KEY,
- PM_ERR_PATTERN_HASH_KEY_LABEL,
- PM_ERR_PATTERN_IDENT_AFTER_HROCKET,
- PM_ERR_PATTERN_LABEL_AFTER_COMMA,
- PM_ERR_PATTERN_REST,
- PM_ERR_PATTERN_TERM_BRACE,
- PM_ERR_PATTERN_TERM_BRACKET,
- PM_ERR_PATTERN_TERM_PAREN,
- PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN,
- PM_ERR_REGEXP_TERM,
- PM_ERR_RESCUE_EXPRESSION,
- PM_ERR_RESCUE_MODIFIER_VALUE,
- PM_ERR_RESCUE_TERM,
- PM_ERR_RESCUE_VARIABLE,
- PM_ERR_RETURN_INVALID,
- PM_ERR_STATEMENT_ALIAS,
- PM_ERR_STATEMENT_POSTEXE_END,
- PM_ERR_STATEMENT_PREEXE_BEGIN,
- PM_ERR_STATEMENT_UNDEF,
- PM_ERR_STRING_CONCATENATION,
- PM_ERR_STRING_INTERPOLATED_TERM,
- PM_ERR_STRING_LITERAL_TERM,
- PM_ERR_SYMBOL_INVALID,
- PM_ERR_SYMBOL_TERM_DYNAMIC,
- PM_ERR_SYMBOL_TERM_INTERPOLATED,
- PM_ERR_TERNARY_COLON,
- PM_ERR_TERNARY_EXPRESSION_FALSE,
- PM_ERR_TERNARY_EXPRESSION_TRUE,
- PM_ERR_UNARY_RECEIVER_BANG,
- PM_ERR_UNARY_RECEIVER_MINUS,
- PM_ERR_UNARY_RECEIVER_PLUS,
- PM_ERR_UNARY_RECEIVER_TILDE,
- PM_ERR_UNDEF_ARGUMENT,
- PM_ERR_UNTIL_TERM,
- PM_ERR_VOID_EXPRESSION,
- PM_ERR_WHILE_TERM,
- PM_ERR_WRITE_TARGET_IN_METHOD,
- PM_ERR_WRITE_TARGET_READONLY,
- PM_ERR_WRITE_TARGET_UNEXPECTED,
- PM_ERR_XSTRING_TERM,
- PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS,
- PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS,
- PM_WARN_AMBIGUOUS_PREFIX_STAR,
- PM_WARN_AMBIGUOUS_SLASH,
- PM_WARN_END_IN_METHOD,
-
- /* This must be the last member. */
- PM_DIAGNOSTIC_ID_LEN,
-} pm_diagnostic_id_t;
-
-/**
- * Append a diagnostic to the given list of diagnostics that is using shared
- * memory for its message.
- *
- * @param list The list to append to.
- * @param start The start of the diagnostic.
- * @param end The end of the diagnostic.
- * @param diag_id The diagnostic ID.
- * @return Whether the diagnostic was successfully appended.
- */
-bool pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id);
-
-/**
- * Append a diagnostic to the given list of diagnostics that is using a format
- * string for its message.
- *
- * @param list The list to append to.
- * @param start The start of the diagnostic.
- * @param end The end of the diagnostic.
- * @param diag_id The diagnostic ID.
- * @param ... The arguments to the format string for the message.
- * @return Whether the diagnostic was successfully appended.
- */
-bool pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...);
-
-/**
- * Deallocate the internal state of the given diagnostic list.
- *
- * @param list The list to deallocate.
- */
-void pm_diagnostic_list_free(pm_list_t *list);
-
-#endif
diff --git a/prism/encoding.c b/prism/encoding.c
deleted file mode 100644
index 2c6d7c9777..0000000000
--- a/prism/encoding.c
+++ /dev/null
@@ -1,5137 +0,0 @@
-#include "prism/encoding.h"
-
-typedef uint32_t pm_unicode_codepoint_t;
-
-#define UNICODE_ALPHA_CODEPOINTS_LENGTH 1450
-static const pm_unicode_codepoint_t unicode_alpha_codepoints[UNICODE_ALPHA_CODEPOINTS_LENGTH] = {
- 0x100, 0x2C1,
- 0x2C6, 0x2D1,
- 0x2E0, 0x2E4,
- 0x2EC, 0x2EC,
- 0x2EE, 0x2EE,
- 0x345, 0x345,
- 0x370, 0x374,
- 0x376, 0x377,
- 0x37A, 0x37D,
- 0x37F, 0x37F,
- 0x386, 0x386,
- 0x388, 0x38A,
- 0x38C, 0x38C,
- 0x38E, 0x3A1,
- 0x3A3, 0x3F5,
- 0x3F7, 0x481,
- 0x48A, 0x52F,
- 0x531, 0x556,
- 0x559, 0x559,
- 0x560, 0x588,
- 0x5B0, 0x5BD,
- 0x5BF, 0x5BF,
- 0x5C1, 0x5C2,
- 0x5C4, 0x5C5,
- 0x5C7, 0x5C7,
- 0x5D0, 0x5EA,
- 0x5EF, 0x5F2,
- 0x610, 0x61A,
- 0x620, 0x657,
- 0x659, 0x65F,
- 0x66E, 0x6D3,
- 0x6D5, 0x6DC,
- 0x6E1, 0x6E8,
- 0x6ED, 0x6EF,
- 0x6FA, 0x6FC,
- 0x6FF, 0x6FF,
- 0x710, 0x73F,
- 0x74D, 0x7B1,
- 0x7CA, 0x7EA,
- 0x7F4, 0x7F5,
- 0x7FA, 0x7FA,
- 0x800, 0x817,
- 0x81A, 0x82C,
- 0x840, 0x858,
- 0x860, 0x86A,
- 0x870, 0x887,
- 0x889, 0x88E,
- 0x8A0, 0x8C9,
- 0x8D4, 0x8DF,
- 0x8E3, 0x8E9,
- 0x8F0, 0x93B,
- 0x93D, 0x94C,
- 0x94E, 0x950,
- 0x955, 0x963,
- 0x971, 0x983,
- 0x985, 0x98C,
- 0x98F, 0x990,
- 0x993, 0x9A8,
- 0x9AA, 0x9B0,
- 0x9B2, 0x9B2,
- 0x9B6, 0x9B9,
- 0x9BD, 0x9C4,
- 0x9C7, 0x9C8,
- 0x9CB, 0x9CC,
- 0x9CE, 0x9CE,
- 0x9D7, 0x9D7,
- 0x9DC, 0x9DD,
- 0x9DF, 0x9E3,
- 0x9F0, 0x9F1,
- 0x9FC, 0x9FC,
- 0xA01, 0xA03,
- 0xA05, 0xA0A,
- 0xA0F, 0xA10,
- 0xA13, 0xA28,
- 0xA2A, 0xA30,
- 0xA32, 0xA33,
- 0xA35, 0xA36,
- 0xA38, 0xA39,
- 0xA3E, 0xA42,
- 0xA47, 0xA48,
- 0xA4B, 0xA4C,
- 0xA51, 0xA51,
- 0xA59, 0xA5C,
- 0xA5E, 0xA5E,
- 0xA70, 0xA75,
- 0xA81, 0xA83,
- 0xA85, 0xA8D,
- 0xA8F, 0xA91,
- 0xA93, 0xAA8,
- 0xAAA, 0xAB0,
- 0xAB2, 0xAB3,
- 0xAB5, 0xAB9,
- 0xABD, 0xAC5,
- 0xAC7, 0xAC9,
- 0xACB, 0xACC,
- 0xAD0, 0xAD0,
- 0xAE0, 0xAE3,
- 0xAF9, 0xAFC,
- 0xB01, 0xB03,
- 0xB05, 0xB0C,
- 0xB0F, 0xB10,
- 0xB13, 0xB28,
- 0xB2A, 0xB30,
- 0xB32, 0xB33,
- 0xB35, 0xB39,
- 0xB3D, 0xB44,
- 0xB47, 0xB48,
- 0xB4B, 0xB4C,
- 0xB56, 0xB57,
- 0xB5C, 0xB5D,
- 0xB5F, 0xB63,
- 0xB71, 0xB71,
- 0xB82, 0xB83,
- 0xB85, 0xB8A,
- 0xB8E, 0xB90,
- 0xB92, 0xB95,
- 0xB99, 0xB9A,
- 0xB9C, 0xB9C,
- 0xB9E, 0xB9F,
- 0xBA3, 0xBA4,
- 0xBA8, 0xBAA,
- 0xBAE, 0xBB9,
- 0xBBE, 0xBC2,
- 0xBC6, 0xBC8,
- 0xBCA, 0xBCC,
- 0xBD0, 0xBD0,
- 0xBD7, 0xBD7,
- 0xC00, 0xC0C,
- 0xC0E, 0xC10,
- 0xC12, 0xC28,
- 0xC2A, 0xC39,
- 0xC3D, 0xC44,
- 0xC46, 0xC48,
- 0xC4A, 0xC4C,
- 0xC55, 0xC56,
- 0xC58, 0xC5A,
- 0xC5D, 0xC5D,
- 0xC60, 0xC63,
- 0xC80, 0xC83,
- 0xC85, 0xC8C,
- 0xC8E, 0xC90,
- 0xC92, 0xCA8,
- 0xCAA, 0xCB3,
- 0xCB5, 0xCB9,
- 0xCBD, 0xCC4,
- 0xCC6, 0xCC8,
- 0xCCA, 0xCCC,
- 0xCD5, 0xCD6,
- 0xCDD, 0xCDE,
- 0xCE0, 0xCE3,
- 0xCF1, 0xCF3,
- 0xD00, 0xD0C,
- 0xD0E, 0xD10,
- 0xD12, 0xD3A,
- 0xD3D, 0xD44,
- 0xD46, 0xD48,
- 0xD4A, 0xD4C,
- 0xD4E, 0xD4E,
- 0xD54, 0xD57,
- 0xD5F, 0xD63,
- 0xD7A, 0xD7F,
- 0xD81, 0xD83,
- 0xD85, 0xD96,
- 0xD9A, 0xDB1,
- 0xDB3, 0xDBB,
- 0xDBD, 0xDBD,
- 0xDC0, 0xDC6,
- 0xDCF, 0xDD4,
- 0xDD6, 0xDD6,
- 0xDD8, 0xDDF,
- 0xDF2, 0xDF3,
- 0xE01, 0xE3A,
- 0xE40, 0xE46,
- 0xE4D, 0xE4D,
- 0xE81, 0xE82,
- 0xE84, 0xE84,
- 0xE86, 0xE8A,
- 0xE8C, 0xEA3,
- 0xEA5, 0xEA5,
- 0xEA7, 0xEB9,
- 0xEBB, 0xEBD,
- 0xEC0, 0xEC4,
- 0xEC6, 0xEC6,
- 0xECD, 0xECD,
- 0xEDC, 0xEDF,
- 0xF00, 0xF00,
- 0xF40, 0xF47,
- 0xF49, 0xF6C,
- 0xF71, 0xF83,
- 0xF88, 0xF97,
- 0xF99, 0xFBC,
- 0x1000, 0x1036,
- 0x1038, 0x1038,
- 0x103B, 0x103F,
- 0x1050, 0x108F,
- 0x109A, 0x109D,
- 0x10A0, 0x10C5,
- 0x10C7, 0x10C7,
- 0x10CD, 0x10CD,
- 0x10D0, 0x10FA,
- 0x10FC, 0x1248,
- 0x124A, 0x124D,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125A, 0x125D,
- 0x1260, 0x1288,
- 0x128A, 0x128D,
- 0x1290, 0x12B0,
- 0x12B2, 0x12B5,
- 0x12B8, 0x12BE,
- 0x12C0, 0x12C0,
- 0x12C2, 0x12C5,
- 0x12C8, 0x12D6,
- 0x12D8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135A,
- 0x1380, 0x138F,
- 0x13A0, 0x13F5,
- 0x13F8, 0x13FD,
- 0x1401, 0x166C,
- 0x166F, 0x167F,
- 0x1681, 0x169A,
- 0x16A0, 0x16EA,
- 0x16EE, 0x16F8,
- 0x1700, 0x1713,
- 0x171F, 0x1733,
- 0x1740, 0x1753,
- 0x1760, 0x176C,
- 0x176E, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17B3,
- 0x17B6, 0x17C8,
- 0x17D7, 0x17D7,
- 0x17DC, 0x17DC,
- 0x1820, 0x1878,
- 0x1880, 0x18AA,
- 0x18B0, 0x18F5,
- 0x1900, 0x191E,
- 0x1920, 0x192B,
- 0x1930, 0x1938,
- 0x1950, 0x196D,
- 0x1970, 0x1974,
- 0x1980, 0x19AB,
- 0x19B0, 0x19C9,
- 0x1A00, 0x1A1B,
- 0x1A20, 0x1A5E,
- 0x1A61, 0x1A74,
- 0x1AA7, 0x1AA7,
- 0x1ABF, 0x1AC0,
- 0x1ACC, 0x1ACE,
- 0x1B00, 0x1B33,
- 0x1B35, 0x1B43,
- 0x1B45, 0x1B4C,
- 0x1B80, 0x1BA9,
- 0x1BAC, 0x1BAF,
- 0x1BBA, 0x1BE5,
- 0x1BE7, 0x1BF1,
- 0x1C00, 0x1C36,
- 0x1C4D, 0x1C4F,
- 0x1C5A, 0x1C7D,
- 0x1C80, 0x1C88,
- 0x1C90, 0x1CBA,
- 0x1CBD, 0x1CBF,
- 0x1CE9, 0x1CEC,
- 0x1CEE, 0x1CF3,
- 0x1CF5, 0x1CF6,
- 0x1CFA, 0x1CFA,
- 0x1D00, 0x1DBF,
- 0x1DE7, 0x1DF4,
- 0x1E00, 0x1F15,
- 0x1F18, 0x1F1D,
- 0x1F20, 0x1F45,
- 0x1F48, 0x1F4D,
- 0x1F50, 0x1F57,
- 0x1F59, 0x1F59,
- 0x1F5B, 0x1F5B,
- 0x1F5D, 0x1F5D,
- 0x1F5F, 0x1F7D,
- 0x1F80, 0x1FB4,
- 0x1FB6, 0x1FBC,
- 0x1FBE, 0x1FBE,
- 0x1FC2, 0x1FC4,
- 0x1FC6, 0x1FCC,
- 0x1FD0, 0x1FD3,
- 0x1FD6, 0x1FDB,
- 0x1FE0, 0x1FEC,
- 0x1FF2, 0x1FF4,
- 0x1FF6, 0x1FFC,
- 0x2071, 0x2071,
- 0x207F, 0x207F,
- 0x2090, 0x209C,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210A, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211D,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212A, 0x212D,
- 0x212F, 0x2139,
- 0x213C, 0x213F,
- 0x2145, 0x2149,
- 0x214E, 0x214E,
- 0x2160, 0x2188,
- 0x24B6, 0x24E9,
- 0x2C00, 0x2CE4,
- 0x2CEB, 0x2CEE,
- 0x2CF2, 0x2CF3,
- 0x2D00, 0x2D25,
- 0x2D27, 0x2D27,
- 0x2D2D, 0x2D2D,
- 0x2D30, 0x2D67,
- 0x2D6F, 0x2D6F,
- 0x2D80, 0x2D96,
- 0x2DA0, 0x2DA6,
- 0x2DA8, 0x2DAE,
- 0x2DB0, 0x2DB6,
- 0x2DB8, 0x2DBE,
- 0x2DC0, 0x2DC6,
- 0x2DC8, 0x2DCE,
- 0x2DD0, 0x2DD6,
- 0x2DD8, 0x2DDE,
- 0x2DE0, 0x2DFF,
- 0x2E2F, 0x2E2F,
- 0x3005, 0x3007,
- 0x3021, 0x3029,
- 0x3031, 0x3035,
- 0x3038, 0x303C,
- 0x3041, 0x3096,
- 0x309D, 0x309F,
- 0x30A1, 0x30FA,
- 0x30FC, 0x30FF,
- 0x3105, 0x312F,
- 0x3131, 0x318E,
- 0x31A0, 0x31BF,
- 0x31F0, 0x31FF,
- 0x3400, 0x4DBF,
- 0x4E00, 0xA48C,
- 0xA4D0, 0xA4FD,
- 0xA500, 0xA60C,
- 0xA610, 0xA61F,
- 0xA62A, 0xA62B,
- 0xA640, 0xA66E,
- 0xA674, 0xA67B,
- 0xA67F, 0xA6EF,
- 0xA717, 0xA71F,
- 0xA722, 0xA788,
- 0xA78B, 0xA7CA,
- 0xA7D0, 0xA7D1,
- 0xA7D3, 0xA7D3,
- 0xA7D5, 0xA7D9,
- 0xA7F2, 0xA805,
- 0xA807, 0xA827,
- 0xA840, 0xA873,
- 0xA880, 0xA8C3,
- 0xA8C5, 0xA8C5,
- 0xA8F2, 0xA8F7,
- 0xA8FB, 0xA8FB,
- 0xA8FD, 0xA8FF,
- 0xA90A, 0xA92A,
- 0xA930, 0xA952,
- 0xA960, 0xA97C,
- 0xA980, 0xA9B2,
- 0xA9B4, 0xA9BF,
- 0xA9CF, 0xA9CF,
- 0xA9E0, 0xA9EF,
- 0xA9FA, 0xA9FE,
- 0xAA00, 0xAA36,
- 0xAA40, 0xAA4D,
- 0xAA60, 0xAA76,
- 0xAA7A, 0xAABE,
- 0xAAC0, 0xAAC0,
- 0xAAC2, 0xAAC2,
- 0xAADB, 0xAADD,
- 0xAAE0, 0xAAEF,
- 0xAAF2, 0xAAF5,
- 0xAB01, 0xAB06,
- 0xAB09, 0xAB0E,
- 0xAB11, 0xAB16,
- 0xAB20, 0xAB26,
- 0xAB28, 0xAB2E,
- 0xAB30, 0xAB5A,
- 0xAB5C, 0xAB69,
- 0xAB70, 0xABEA,
- 0xAC00, 0xD7A3,
- 0xD7B0, 0xD7C6,
- 0xD7CB, 0xD7FB,
- 0xF900, 0xFA6D,
- 0xFA70, 0xFAD9,
- 0xFB00, 0xFB06,
- 0xFB13, 0xFB17,
- 0xFB1D, 0xFB28,
- 0xFB2A, 0xFB36,
- 0xFB38, 0xFB3C,
- 0xFB3E, 0xFB3E,
- 0xFB40, 0xFB41,
- 0xFB43, 0xFB44,
- 0xFB46, 0xFBB1,
- 0xFBD3, 0xFD3D,
- 0xFD50, 0xFD8F,
- 0xFD92, 0xFDC7,
- 0xFDF0, 0xFDFB,
- 0xFE70, 0xFE74,
- 0xFE76, 0xFEFC,
- 0xFF21, 0xFF3A,
- 0xFF41, 0xFF5A,
- 0xFF66, 0xFFBE,
- 0xFFC2, 0xFFC7,
- 0xFFCA, 0xFFCF,
- 0xFFD2, 0xFFD7,
- 0xFFDA, 0xFFDC,
- 0x10000, 0x1000B,
- 0x1000D, 0x10026,
- 0x10028, 0x1003A,
- 0x1003C, 0x1003D,
- 0x1003F, 0x1004D,
- 0x10050, 0x1005D,
- 0x10080, 0x100FA,
- 0x10140, 0x10174,
- 0x10280, 0x1029C,
- 0x102A0, 0x102D0,
- 0x10300, 0x1031F,
- 0x1032D, 0x1034A,
- 0x10350, 0x1037A,
- 0x10380, 0x1039D,
- 0x103A0, 0x103C3,
- 0x103C8, 0x103CF,
- 0x103D1, 0x103D5,
- 0x10400, 0x1049D,
- 0x104B0, 0x104D3,
- 0x104D8, 0x104FB,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10570, 0x1057A,
- 0x1057C, 0x1058A,
- 0x1058C, 0x10592,
- 0x10594, 0x10595,
- 0x10597, 0x105A1,
- 0x105A3, 0x105B1,
- 0x105B3, 0x105B9,
- 0x105BB, 0x105BC,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10780, 0x10785,
- 0x10787, 0x107B0,
- 0x107B2, 0x107BA,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080A, 0x10835,
- 0x10837, 0x10838,
- 0x1083C, 0x1083C,
- 0x1083F, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089E,
- 0x108E0, 0x108F2,
- 0x108F4, 0x108F5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109B7,
- 0x109BE, 0x109BF,
- 0x10A00, 0x10A03,
- 0x10A05, 0x10A06,
- 0x10A0C, 0x10A13,
- 0x10A15, 0x10A17,
- 0x10A19, 0x10A35,
- 0x10A60, 0x10A7C,
- 0x10A80, 0x10A9C,
- 0x10AC0, 0x10AC7,
- 0x10AC9, 0x10AE4,
- 0x10B00, 0x10B35,
- 0x10B40, 0x10B55,
- 0x10B60, 0x10B72,
- 0x10B80, 0x10B91,
- 0x10C00, 0x10C48,
- 0x10C80, 0x10CB2,
- 0x10CC0, 0x10CF2,
- 0x10D00, 0x10D27,
- 0x10E80, 0x10EA9,
- 0x10EAB, 0x10EAC,
- 0x10EB0, 0x10EB1,
- 0x10F00, 0x10F1C,
- 0x10F27, 0x10F27,
- 0x10F30, 0x10F45,
- 0x10F70, 0x10F81,
- 0x10FB0, 0x10FC4,
- 0x10FE0, 0x10FF6,
- 0x11000, 0x11045,
- 0x11071, 0x11075,
- 0x11080, 0x110B8,
- 0x110C2, 0x110C2,
- 0x110D0, 0x110E8,
- 0x11100, 0x11132,
- 0x11144, 0x11147,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11180, 0x111BF,
- 0x111C1, 0x111C4,
- 0x111CE, 0x111CF,
- 0x111DA, 0x111DA,
- 0x111DC, 0x111DC,
- 0x11200, 0x11211,
- 0x11213, 0x11234,
- 0x11237, 0x11237,
- 0x1123E, 0x11241,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128A, 0x1128D,
- 0x1128F, 0x1129D,
- 0x1129F, 0x112A8,
- 0x112B0, 0x112E8,
- 0x11300, 0x11303,
- 0x11305, 0x1130C,
- 0x1130F, 0x11310,
- 0x11313, 0x11328,
- 0x1132A, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133D, 0x11344,
- 0x11347, 0x11348,
- 0x1134B, 0x1134C,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135D, 0x11363,
- 0x11400, 0x11441,
- 0x11443, 0x11445,
- 0x11447, 0x1144A,
- 0x1145F, 0x11461,
- 0x11480, 0x114C1,
- 0x114C4, 0x114C5,
- 0x114C7, 0x114C7,
- 0x11580, 0x115B5,
- 0x115B8, 0x115BE,
- 0x115D8, 0x115DD,
- 0x11600, 0x1163E,
- 0x11640, 0x11640,
- 0x11644, 0x11644,
- 0x11680, 0x116B5,
- 0x116B8, 0x116B8,
- 0x11700, 0x1171A,
- 0x1171D, 0x1172A,
- 0x11740, 0x11746,
- 0x11800, 0x11838,
- 0x118A0, 0x118DF,
- 0x118FF, 0x11906,
- 0x11909, 0x11909,
- 0x1190C, 0x11913,
- 0x11915, 0x11916,
- 0x11918, 0x11935,
- 0x11937, 0x11938,
- 0x1193B, 0x1193C,
- 0x1193F, 0x11942,
- 0x119A0, 0x119A7,
- 0x119AA, 0x119D7,
- 0x119DA, 0x119DF,
- 0x119E1, 0x119E1,
- 0x119E3, 0x119E4,
- 0x11A00, 0x11A32,
- 0x11A35, 0x11A3E,
- 0x11A50, 0x11A97,
- 0x11A9D, 0x11A9D,
- 0x11AB0, 0x11AF8,
- 0x11C00, 0x11C08,
- 0x11C0A, 0x11C36,
- 0x11C38, 0x11C3E,
- 0x11C40, 0x11C40,
- 0x11C72, 0x11C8F,
- 0x11C92, 0x11CA7,
- 0x11CA9, 0x11CB6,
- 0x11D00, 0x11D06,
- 0x11D08, 0x11D09,
- 0x11D0B, 0x11D36,
- 0x11D3A, 0x11D3A,
- 0x11D3C, 0x11D3D,
- 0x11D3F, 0x11D41,
- 0x11D43, 0x11D43,
- 0x11D46, 0x11D47,
- 0x11D60, 0x11D65,
- 0x11D67, 0x11D68,
- 0x11D6A, 0x11D8E,
- 0x11D90, 0x11D91,
- 0x11D93, 0x11D96,
- 0x11D98, 0x11D98,
- 0x11EE0, 0x11EF6,
- 0x11F00, 0x11F10,
- 0x11F12, 0x11F3A,
- 0x11F3E, 0x11F40,
- 0x11FB0, 0x11FB0,
- 0x12000, 0x12399,
- 0x12400, 0x1246E,
- 0x12480, 0x12543,
- 0x12F90, 0x12FF0,
- 0x13000, 0x1342F,
- 0x13441, 0x13446,
- 0x14400, 0x14646,
- 0x16800, 0x16A38,
- 0x16A40, 0x16A5E,
- 0x16A70, 0x16ABE,
- 0x16AD0, 0x16AED,
- 0x16B00, 0x16B2F,
- 0x16B40, 0x16B43,
- 0x16B63, 0x16B77,
- 0x16B7D, 0x16B8F,
- 0x16E40, 0x16E7F,
- 0x16F00, 0x16F4A,
- 0x16F4F, 0x16F87,
- 0x16F8F, 0x16F9F,
- 0x16FE0, 0x16FE1,
- 0x16FE3, 0x16FE3,
- 0x16FF0, 0x16FF1,
- 0x17000, 0x187F7,
- 0x18800, 0x18CD5,
- 0x18D00, 0x18D08,
- 0x1AFF0, 0x1AFF3,
- 0x1AFF5, 0x1AFFB,
- 0x1AFFD, 0x1AFFE,
- 0x1B000, 0x1B122,
- 0x1B132, 0x1B132,
- 0x1B150, 0x1B152,
- 0x1B155, 0x1B155,
- 0x1B164, 0x1B167,
- 0x1B170, 0x1B2FB,
- 0x1BC00, 0x1BC6A,
- 0x1BC70, 0x1BC7C,
- 0x1BC80, 0x1BC88,
- 0x1BC90, 0x1BC99,
- 0x1BC9E, 0x1BC9E,
- 0x1D400, 0x1D454,
- 0x1D456, 0x1D49C,
- 0x1D49E, 0x1D49F,
- 0x1D4A2, 0x1D4A2,
- 0x1D4A5, 0x1D4A6,
- 0x1D4A9, 0x1D4AC,
- 0x1D4AE, 0x1D4B9,
- 0x1D4BB, 0x1D4BB,
- 0x1D4BD, 0x1D4C3,
- 0x1D4C5, 0x1D505,
- 0x1D507, 0x1D50A,
- 0x1D50D, 0x1D514,
- 0x1D516, 0x1D51C,
- 0x1D51E, 0x1D539,
- 0x1D53B, 0x1D53E,
- 0x1D540, 0x1D544,
- 0x1D546, 0x1D546,
- 0x1D54A, 0x1D550,
- 0x1D552, 0x1D6A5,
- 0x1D6A8, 0x1D6C0,
- 0x1D6C2, 0x1D6DA,
- 0x1D6DC, 0x1D6FA,
- 0x1D6FC, 0x1D714,
- 0x1D716, 0x1D734,
- 0x1D736, 0x1D74E,
- 0x1D750, 0x1D76E,
- 0x1D770, 0x1D788,
- 0x1D78A, 0x1D7A8,
- 0x1D7AA, 0x1D7C2,
- 0x1D7C4, 0x1D7CB,
- 0x1DF00, 0x1DF1E,
- 0x1DF25, 0x1DF2A,
- 0x1E000, 0x1E006,
- 0x1E008, 0x1E018,
- 0x1E01B, 0x1E021,
- 0x1E023, 0x1E024,
- 0x1E026, 0x1E02A,
- 0x1E030, 0x1E06D,
- 0x1E08F, 0x1E08F,
- 0x1E100, 0x1E12C,
- 0x1E137, 0x1E13D,
- 0x1E14E, 0x1E14E,
- 0x1E290, 0x1E2AD,
- 0x1E2C0, 0x1E2EB,
- 0x1E4D0, 0x1E4EB,
- 0x1E7E0, 0x1E7E6,
- 0x1E7E8, 0x1E7EB,
- 0x1E7ED, 0x1E7EE,
- 0x1E7F0, 0x1E7FE,
- 0x1E800, 0x1E8C4,
- 0x1E900, 0x1E943,
- 0x1E947, 0x1E947,
- 0x1E94B, 0x1E94B,
- 0x1EE00, 0x1EE03,
- 0x1EE05, 0x1EE1F,
- 0x1EE21, 0x1EE22,
- 0x1EE24, 0x1EE24,
- 0x1EE27, 0x1EE27,
- 0x1EE29, 0x1EE32,
- 0x1EE34, 0x1EE37,
- 0x1EE39, 0x1EE39,
- 0x1EE3B, 0x1EE3B,
- 0x1EE42, 0x1EE42,
- 0x1EE47, 0x1EE47,
- 0x1EE49, 0x1EE49,
- 0x1EE4B, 0x1EE4B,
- 0x1EE4D, 0x1EE4F,
- 0x1EE51, 0x1EE52,
- 0x1EE54, 0x1EE54,
- 0x1EE57, 0x1EE57,
- 0x1EE59, 0x1EE59,
- 0x1EE5B, 0x1EE5B,
- 0x1EE5D, 0x1EE5D,
- 0x1EE5F, 0x1EE5F,
- 0x1EE61, 0x1EE62,
- 0x1EE64, 0x1EE64,
- 0x1EE67, 0x1EE6A,
- 0x1EE6C, 0x1EE72,
- 0x1EE74, 0x1EE77,
- 0x1EE79, 0x1EE7C,
- 0x1EE7E, 0x1EE7E,
- 0x1EE80, 0x1EE89,
- 0x1EE8B, 0x1EE9B,
- 0x1EEA1, 0x1EEA3,
- 0x1EEA5, 0x1EEA9,
- 0x1EEAB, 0x1EEBB,
- 0x1F130, 0x1F149,
- 0x1F150, 0x1F169,
- 0x1F170, 0x1F189,
- 0x20000, 0x2A6DF,
- 0x2A700, 0x2B739,
- 0x2B740, 0x2B81D,
- 0x2B820, 0x2CEA1,
- 0x2CEB0, 0x2EBE0,
- 0x2F800, 0x2FA1D,
- 0x30000, 0x3134A,
- 0x31350, 0x323AF,
-};
-
-#define UNICODE_ALNUM_CODEPOINTS_LENGTH 1528
-static const pm_unicode_codepoint_t unicode_alnum_codepoints[UNICODE_ALNUM_CODEPOINTS_LENGTH] = {
- 0x100, 0x2C1,
- 0x2C6, 0x2D1,
- 0x2E0, 0x2E4,
- 0x2EC, 0x2EC,
- 0x2EE, 0x2EE,
- 0x345, 0x345,
- 0x370, 0x374,
- 0x376, 0x377,
- 0x37A, 0x37D,
- 0x37F, 0x37F,
- 0x386, 0x386,
- 0x388, 0x38A,
- 0x38C, 0x38C,
- 0x38E, 0x3A1,
- 0x3A3, 0x3F5,
- 0x3F7, 0x481,
- 0x48A, 0x52F,
- 0x531, 0x556,
- 0x559, 0x559,
- 0x560, 0x588,
- 0x5B0, 0x5BD,
- 0x5BF, 0x5BF,
- 0x5C1, 0x5C2,
- 0x5C4, 0x5C5,
- 0x5C7, 0x5C7,
- 0x5D0, 0x5EA,
- 0x5EF, 0x5F2,
- 0x610, 0x61A,
- 0x620, 0x657,
- 0x659, 0x669,
- 0x66E, 0x6D3,
- 0x6D5, 0x6DC,
- 0x6E1, 0x6E8,
- 0x6ED, 0x6FC,
- 0x6FF, 0x6FF,
- 0x710, 0x73F,
- 0x74D, 0x7B1,
- 0x7C0, 0x7EA,
- 0x7F4, 0x7F5,
- 0x7FA, 0x7FA,
- 0x800, 0x817,
- 0x81A, 0x82C,
- 0x840, 0x858,
- 0x860, 0x86A,
- 0x870, 0x887,
- 0x889, 0x88E,
- 0x8A0, 0x8C9,
- 0x8D4, 0x8DF,
- 0x8E3, 0x8E9,
- 0x8F0, 0x93B,
- 0x93D, 0x94C,
- 0x94E, 0x950,
- 0x955, 0x963,
- 0x966, 0x96F,
- 0x971, 0x983,
- 0x985, 0x98C,
- 0x98F, 0x990,
- 0x993, 0x9A8,
- 0x9AA, 0x9B0,
- 0x9B2, 0x9B2,
- 0x9B6, 0x9B9,
- 0x9BD, 0x9C4,
- 0x9C7, 0x9C8,
- 0x9CB, 0x9CC,
- 0x9CE, 0x9CE,
- 0x9D7, 0x9D7,
- 0x9DC, 0x9DD,
- 0x9DF, 0x9E3,
- 0x9E6, 0x9F1,
- 0x9FC, 0x9FC,
- 0xA01, 0xA03,
- 0xA05, 0xA0A,
- 0xA0F, 0xA10,
- 0xA13, 0xA28,
- 0xA2A, 0xA30,
- 0xA32, 0xA33,
- 0xA35, 0xA36,
- 0xA38, 0xA39,
- 0xA3E, 0xA42,
- 0xA47, 0xA48,
- 0xA4B, 0xA4C,
- 0xA51, 0xA51,
- 0xA59, 0xA5C,
- 0xA5E, 0xA5E,
- 0xA66, 0xA75,
- 0xA81, 0xA83,
- 0xA85, 0xA8D,
- 0xA8F, 0xA91,
- 0xA93, 0xAA8,
- 0xAAA, 0xAB0,
- 0xAB2, 0xAB3,
- 0xAB5, 0xAB9,
- 0xABD, 0xAC5,
- 0xAC7, 0xAC9,
- 0xACB, 0xACC,
- 0xAD0, 0xAD0,
- 0xAE0, 0xAE3,
- 0xAE6, 0xAEF,
- 0xAF9, 0xAFC,
- 0xB01, 0xB03,
- 0xB05, 0xB0C,
- 0xB0F, 0xB10,
- 0xB13, 0xB28,
- 0xB2A, 0xB30,
- 0xB32, 0xB33,
- 0xB35, 0xB39,
- 0xB3D, 0xB44,
- 0xB47, 0xB48,
- 0xB4B, 0xB4C,
- 0xB56, 0xB57,
- 0xB5C, 0xB5D,
- 0xB5F, 0xB63,
- 0xB66, 0xB6F,
- 0xB71, 0xB71,
- 0xB82, 0xB83,
- 0xB85, 0xB8A,
- 0xB8E, 0xB90,
- 0xB92, 0xB95,
- 0xB99, 0xB9A,
- 0xB9C, 0xB9C,
- 0xB9E, 0xB9F,
- 0xBA3, 0xBA4,
- 0xBA8, 0xBAA,
- 0xBAE, 0xBB9,
- 0xBBE, 0xBC2,
- 0xBC6, 0xBC8,
- 0xBCA, 0xBCC,
- 0xBD0, 0xBD0,
- 0xBD7, 0xBD7,
- 0xBE6, 0xBEF,
- 0xC00, 0xC0C,
- 0xC0E, 0xC10,
- 0xC12, 0xC28,
- 0xC2A, 0xC39,
- 0xC3D, 0xC44,
- 0xC46, 0xC48,
- 0xC4A, 0xC4C,
- 0xC55, 0xC56,
- 0xC58, 0xC5A,
- 0xC5D, 0xC5D,
- 0xC60, 0xC63,
- 0xC66, 0xC6F,
- 0xC80, 0xC83,
- 0xC85, 0xC8C,
- 0xC8E, 0xC90,
- 0xC92, 0xCA8,
- 0xCAA, 0xCB3,
- 0xCB5, 0xCB9,
- 0xCBD, 0xCC4,
- 0xCC6, 0xCC8,
- 0xCCA, 0xCCC,
- 0xCD5, 0xCD6,
- 0xCDD, 0xCDE,
- 0xCE0, 0xCE3,
- 0xCE6, 0xCEF,
- 0xCF1, 0xCF3,
- 0xD00, 0xD0C,
- 0xD0E, 0xD10,
- 0xD12, 0xD3A,
- 0xD3D, 0xD44,
- 0xD46, 0xD48,
- 0xD4A, 0xD4C,
- 0xD4E, 0xD4E,
- 0xD54, 0xD57,
- 0xD5F, 0xD63,
- 0xD66, 0xD6F,
- 0xD7A, 0xD7F,
- 0xD81, 0xD83,
- 0xD85, 0xD96,
- 0xD9A, 0xDB1,
- 0xDB3, 0xDBB,
- 0xDBD, 0xDBD,
- 0xDC0, 0xDC6,
- 0xDCF, 0xDD4,
- 0xDD6, 0xDD6,
- 0xDD8, 0xDDF,
- 0xDE6, 0xDEF,
- 0xDF2, 0xDF3,
- 0xE01, 0xE3A,
- 0xE40, 0xE46,
- 0xE4D, 0xE4D,
- 0xE50, 0xE59,
- 0xE81, 0xE82,
- 0xE84, 0xE84,
- 0xE86, 0xE8A,
- 0xE8C, 0xEA3,
- 0xEA5, 0xEA5,
- 0xEA7, 0xEB9,
- 0xEBB, 0xEBD,
- 0xEC0, 0xEC4,
- 0xEC6, 0xEC6,
- 0xECD, 0xECD,
- 0xED0, 0xED9,
- 0xEDC, 0xEDF,
- 0xF00, 0xF00,
- 0xF20, 0xF29,
- 0xF40, 0xF47,
- 0xF49, 0xF6C,
- 0xF71, 0xF83,
- 0xF88, 0xF97,
- 0xF99, 0xFBC,
- 0x1000, 0x1036,
- 0x1038, 0x1038,
- 0x103B, 0x1049,
- 0x1050, 0x109D,
- 0x10A0, 0x10C5,
- 0x10C7, 0x10C7,
- 0x10CD, 0x10CD,
- 0x10D0, 0x10FA,
- 0x10FC, 0x1248,
- 0x124A, 0x124D,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125A, 0x125D,
- 0x1260, 0x1288,
- 0x128A, 0x128D,
- 0x1290, 0x12B0,
- 0x12B2, 0x12B5,
- 0x12B8, 0x12BE,
- 0x12C0, 0x12C0,
- 0x12C2, 0x12C5,
- 0x12C8, 0x12D6,
- 0x12D8, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x135A,
- 0x1380, 0x138F,
- 0x13A0, 0x13F5,
- 0x13F8, 0x13FD,
- 0x1401, 0x166C,
- 0x166F, 0x167F,
- 0x1681, 0x169A,
- 0x16A0, 0x16EA,
- 0x16EE, 0x16F8,
- 0x1700, 0x1713,
- 0x171F, 0x1733,
- 0x1740, 0x1753,
- 0x1760, 0x176C,
- 0x176E, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17B3,
- 0x17B6, 0x17C8,
- 0x17D7, 0x17D7,
- 0x17DC, 0x17DC,
- 0x17E0, 0x17E9,
- 0x1810, 0x1819,
- 0x1820, 0x1878,
- 0x1880, 0x18AA,
- 0x18B0, 0x18F5,
- 0x1900, 0x191E,
- 0x1920, 0x192B,
- 0x1930, 0x1938,
- 0x1946, 0x196D,
- 0x1970, 0x1974,
- 0x1980, 0x19AB,
- 0x19B0, 0x19C9,
- 0x19D0, 0x19D9,
- 0x1A00, 0x1A1B,
- 0x1A20, 0x1A5E,
- 0x1A61, 0x1A74,
- 0x1A80, 0x1A89,
- 0x1A90, 0x1A99,
- 0x1AA7, 0x1AA7,
- 0x1ABF, 0x1AC0,
- 0x1ACC, 0x1ACE,
- 0x1B00, 0x1B33,
- 0x1B35, 0x1B43,
- 0x1B45, 0x1B4C,
- 0x1B50, 0x1B59,
- 0x1B80, 0x1BA9,
- 0x1BAC, 0x1BE5,
- 0x1BE7, 0x1BF1,
- 0x1C00, 0x1C36,
- 0x1C40, 0x1C49,
- 0x1C4D, 0x1C7D,
- 0x1C80, 0x1C88,
- 0x1C90, 0x1CBA,
- 0x1CBD, 0x1CBF,
- 0x1CE9, 0x1CEC,
- 0x1CEE, 0x1CF3,
- 0x1CF5, 0x1CF6,
- 0x1CFA, 0x1CFA,
- 0x1D00, 0x1DBF,
- 0x1DE7, 0x1DF4,
- 0x1E00, 0x1F15,
- 0x1F18, 0x1F1D,
- 0x1F20, 0x1F45,
- 0x1F48, 0x1F4D,
- 0x1F50, 0x1F57,
- 0x1F59, 0x1F59,
- 0x1F5B, 0x1F5B,
- 0x1F5D, 0x1F5D,
- 0x1F5F, 0x1F7D,
- 0x1F80, 0x1FB4,
- 0x1FB6, 0x1FBC,
- 0x1FBE, 0x1FBE,
- 0x1FC2, 0x1FC4,
- 0x1FC6, 0x1FCC,
- 0x1FD0, 0x1FD3,
- 0x1FD6, 0x1FDB,
- 0x1FE0, 0x1FEC,
- 0x1FF2, 0x1FF4,
- 0x1FF6, 0x1FFC,
- 0x2071, 0x2071,
- 0x207F, 0x207F,
- 0x2090, 0x209C,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210A, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211D,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212A, 0x212D,
- 0x212F, 0x2139,
- 0x213C, 0x213F,
- 0x2145, 0x2149,
- 0x214E, 0x214E,
- 0x2160, 0x2188,
- 0x24B6, 0x24E9,
- 0x2C00, 0x2CE4,
- 0x2CEB, 0x2CEE,
- 0x2CF2, 0x2CF3,
- 0x2D00, 0x2D25,
- 0x2D27, 0x2D27,
- 0x2D2D, 0x2D2D,
- 0x2D30, 0x2D67,
- 0x2D6F, 0x2D6F,
- 0x2D80, 0x2D96,
- 0x2DA0, 0x2DA6,
- 0x2DA8, 0x2DAE,
- 0x2DB0, 0x2DB6,
- 0x2DB8, 0x2DBE,
- 0x2DC0, 0x2DC6,
- 0x2DC8, 0x2DCE,
- 0x2DD0, 0x2DD6,
- 0x2DD8, 0x2DDE,
- 0x2DE0, 0x2DFF,
- 0x2E2F, 0x2E2F,
- 0x3005, 0x3007,
- 0x3021, 0x3029,
- 0x3031, 0x3035,
- 0x3038, 0x303C,
- 0x3041, 0x3096,
- 0x309D, 0x309F,
- 0x30A1, 0x30FA,
- 0x30FC, 0x30FF,
- 0x3105, 0x312F,
- 0x3131, 0x318E,
- 0x31A0, 0x31BF,
- 0x31F0, 0x31FF,
- 0x3400, 0x4DBF,
- 0x4E00, 0xA48C,
- 0xA4D0, 0xA4FD,
- 0xA500, 0xA60C,
- 0xA610, 0xA62B,
- 0xA640, 0xA66E,
- 0xA674, 0xA67B,
- 0xA67F, 0xA6EF,
- 0xA717, 0xA71F,
- 0xA722, 0xA788,
- 0xA78B, 0xA7CA,
- 0xA7D0, 0xA7D1,
- 0xA7D3, 0xA7D3,
- 0xA7D5, 0xA7D9,
- 0xA7F2, 0xA805,
- 0xA807, 0xA827,
- 0xA840, 0xA873,
- 0xA880, 0xA8C3,
- 0xA8C5, 0xA8C5,
- 0xA8D0, 0xA8D9,
- 0xA8F2, 0xA8F7,
- 0xA8FB, 0xA8FB,
- 0xA8FD, 0xA92A,
- 0xA930, 0xA952,
- 0xA960, 0xA97C,
- 0xA980, 0xA9B2,
- 0xA9B4, 0xA9BF,
- 0xA9CF, 0xA9D9,
- 0xA9E0, 0xA9FE,
- 0xAA00, 0xAA36,
- 0xAA40, 0xAA4D,
- 0xAA50, 0xAA59,
- 0xAA60, 0xAA76,
- 0xAA7A, 0xAABE,
- 0xAAC0, 0xAAC0,
- 0xAAC2, 0xAAC2,
- 0xAADB, 0xAADD,
- 0xAAE0, 0xAAEF,
- 0xAAF2, 0xAAF5,
- 0xAB01, 0xAB06,
- 0xAB09, 0xAB0E,
- 0xAB11, 0xAB16,
- 0xAB20, 0xAB26,
- 0xAB28, 0xAB2E,
- 0xAB30, 0xAB5A,
- 0xAB5C, 0xAB69,
- 0xAB70, 0xABEA,
- 0xABF0, 0xABF9,
- 0xAC00, 0xD7A3,
- 0xD7B0, 0xD7C6,
- 0xD7CB, 0xD7FB,
- 0xF900, 0xFA6D,
- 0xFA70, 0xFAD9,
- 0xFB00, 0xFB06,
- 0xFB13, 0xFB17,
- 0xFB1D, 0xFB28,
- 0xFB2A, 0xFB36,
- 0xFB38, 0xFB3C,
- 0xFB3E, 0xFB3E,
- 0xFB40, 0xFB41,
- 0xFB43, 0xFB44,
- 0xFB46, 0xFBB1,
- 0xFBD3, 0xFD3D,
- 0xFD50, 0xFD8F,
- 0xFD92, 0xFDC7,
- 0xFDF0, 0xFDFB,
- 0xFE70, 0xFE74,
- 0xFE76, 0xFEFC,
- 0xFF10, 0xFF19,
- 0xFF21, 0xFF3A,
- 0xFF41, 0xFF5A,
- 0xFF66, 0xFFBE,
- 0xFFC2, 0xFFC7,
- 0xFFCA, 0xFFCF,
- 0xFFD2, 0xFFD7,
- 0xFFDA, 0xFFDC,
- 0x10000, 0x1000B,
- 0x1000D, 0x10026,
- 0x10028, 0x1003A,
- 0x1003C, 0x1003D,
- 0x1003F, 0x1004D,
- 0x10050, 0x1005D,
- 0x10080, 0x100FA,
- 0x10140, 0x10174,
- 0x10280, 0x1029C,
- 0x102A0, 0x102D0,
- 0x10300, 0x1031F,
- 0x1032D, 0x1034A,
- 0x10350, 0x1037A,
- 0x10380, 0x1039D,
- 0x103A0, 0x103C3,
- 0x103C8, 0x103CF,
- 0x103D1, 0x103D5,
- 0x10400, 0x1049D,
- 0x104A0, 0x104A9,
- 0x104B0, 0x104D3,
- 0x104D8, 0x104FB,
- 0x10500, 0x10527,
- 0x10530, 0x10563,
- 0x10570, 0x1057A,
- 0x1057C, 0x1058A,
- 0x1058C, 0x10592,
- 0x10594, 0x10595,
- 0x10597, 0x105A1,
- 0x105A3, 0x105B1,
- 0x105B3, 0x105B9,
- 0x105BB, 0x105BC,
- 0x10600, 0x10736,
- 0x10740, 0x10755,
- 0x10760, 0x10767,
- 0x10780, 0x10785,
- 0x10787, 0x107B0,
- 0x107B2, 0x107BA,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080A, 0x10835,
- 0x10837, 0x10838,
- 0x1083C, 0x1083C,
- 0x1083F, 0x10855,
- 0x10860, 0x10876,
- 0x10880, 0x1089E,
- 0x108E0, 0x108F2,
- 0x108F4, 0x108F5,
- 0x10900, 0x10915,
- 0x10920, 0x10939,
- 0x10980, 0x109B7,
- 0x109BE, 0x109BF,
- 0x10A00, 0x10A03,
- 0x10A05, 0x10A06,
- 0x10A0C, 0x10A13,
- 0x10A15, 0x10A17,
- 0x10A19, 0x10A35,
- 0x10A60, 0x10A7C,
- 0x10A80, 0x10A9C,
- 0x10AC0, 0x10AC7,
- 0x10AC9, 0x10AE4,
- 0x10B00, 0x10B35,
- 0x10B40, 0x10B55,
- 0x10B60, 0x10B72,
- 0x10B80, 0x10B91,
- 0x10C00, 0x10C48,
- 0x10C80, 0x10CB2,
- 0x10CC0, 0x10CF2,
- 0x10D00, 0x10D27,
- 0x10D30, 0x10D39,
- 0x10E80, 0x10EA9,
- 0x10EAB, 0x10EAC,
- 0x10EB0, 0x10EB1,
- 0x10F00, 0x10F1C,
- 0x10F27, 0x10F27,
- 0x10F30, 0x10F45,
- 0x10F70, 0x10F81,
- 0x10FB0, 0x10FC4,
- 0x10FE0, 0x10FF6,
- 0x11000, 0x11045,
- 0x11066, 0x1106F,
- 0x11071, 0x11075,
- 0x11080, 0x110B8,
- 0x110C2, 0x110C2,
- 0x110D0, 0x110E8,
- 0x110F0, 0x110F9,
- 0x11100, 0x11132,
- 0x11136, 0x1113F,
- 0x11144, 0x11147,
- 0x11150, 0x11172,
- 0x11176, 0x11176,
- 0x11180, 0x111BF,
- 0x111C1, 0x111C4,
- 0x111CE, 0x111DA,
- 0x111DC, 0x111DC,
- 0x11200, 0x11211,
- 0x11213, 0x11234,
- 0x11237, 0x11237,
- 0x1123E, 0x11241,
- 0x11280, 0x11286,
- 0x11288, 0x11288,
- 0x1128A, 0x1128D,
- 0x1128F, 0x1129D,
- 0x1129F, 0x112A8,
- 0x112B0, 0x112E8,
- 0x112F0, 0x112F9,
- 0x11300, 0x11303,
- 0x11305, 0x1130C,
- 0x1130F, 0x11310,
- 0x11313, 0x11328,
- 0x1132A, 0x11330,
- 0x11332, 0x11333,
- 0x11335, 0x11339,
- 0x1133D, 0x11344,
- 0x11347, 0x11348,
- 0x1134B, 0x1134C,
- 0x11350, 0x11350,
- 0x11357, 0x11357,
- 0x1135D, 0x11363,
- 0x11400, 0x11441,
- 0x11443, 0x11445,
- 0x11447, 0x1144A,
- 0x11450, 0x11459,
- 0x1145F, 0x11461,
- 0x11480, 0x114C1,
- 0x114C4, 0x114C5,
- 0x114C7, 0x114C7,
- 0x114D0, 0x114D9,
- 0x11580, 0x115B5,
- 0x115B8, 0x115BE,
- 0x115D8, 0x115DD,
- 0x11600, 0x1163E,
- 0x11640, 0x11640,
- 0x11644, 0x11644,
- 0x11650, 0x11659,
- 0x11680, 0x116B5,
- 0x116B8, 0x116B8,
- 0x116C0, 0x116C9,
- 0x11700, 0x1171A,
- 0x1171D, 0x1172A,
- 0x11730, 0x11739,
- 0x11740, 0x11746,
- 0x11800, 0x11838,
- 0x118A0, 0x118E9,
- 0x118FF, 0x11906,
- 0x11909, 0x11909,
- 0x1190C, 0x11913,
- 0x11915, 0x11916,
- 0x11918, 0x11935,
- 0x11937, 0x11938,
- 0x1193B, 0x1193C,
- 0x1193F, 0x11942,
- 0x11950, 0x11959,
- 0x119A0, 0x119A7,
- 0x119AA, 0x119D7,
- 0x119DA, 0x119DF,
- 0x119E1, 0x119E1,
- 0x119E3, 0x119E4,
- 0x11A00, 0x11A32,
- 0x11A35, 0x11A3E,
- 0x11A50, 0x11A97,
- 0x11A9D, 0x11A9D,
- 0x11AB0, 0x11AF8,
- 0x11C00, 0x11C08,
- 0x11C0A, 0x11C36,
- 0x11C38, 0x11C3E,
- 0x11C40, 0x11C40,
- 0x11C50, 0x11C59,
- 0x11C72, 0x11C8F,
- 0x11C92, 0x11CA7,
- 0x11CA9, 0x11CB6,
- 0x11D00, 0x11D06,
- 0x11D08, 0x11D09,
- 0x11D0B, 0x11D36,
- 0x11D3A, 0x11D3A,
- 0x11D3C, 0x11D3D,
- 0x11D3F, 0x11D41,
- 0x11D43, 0x11D43,
- 0x11D46, 0x11D47,
- 0x11D50, 0x11D59,
- 0x11D60, 0x11D65,
- 0x11D67, 0x11D68,
- 0x11D6A, 0x11D8E,
- 0x11D90, 0x11D91,
- 0x11D93, 0x11D96,
- 0x11D98, 0x11D98,
- 0x11DA0, 0x11DA9,
- 0x11EE0, 0x11EF6,
- 0x11F00, 0x11F10,
- 0x11F12, 0x11F3A,
- 0x11F3E, 0x11F40,
- 0x11F50, 0x11F59,
- 0x11FB0, 0x11FB0,
- 0x12000, 0x12399,
- 0x12400, 0x1246E,
- 0x12480, 0x12543,
- 0x12F90, 0x12FF0,
- 0x13000, 0x1342F,
- 0x13441, 0x13446,
- 0x14400, 0x14646,
- 0x16800, 0x16A38,
- 0x16A40, 0x16A5E,
- 0x16A60, 0x16A69,
- 0x16A70, 0x16ABE,
- 0x16AC0, 0x16AC9,
- 0x16AD0, 0x16AED,
- 0x16B00, 0x16B2F,
- 0x16B40, 0x16B43,
- 0x16B50, 0x16B59,
- 0x16B63, 0x16B77,
- 0x16B7D, 0x16B8F,
- 0x16E40, 0x16E7F,
- 0x16F00, 0x16F4A,
- 0x16F4F, 0x16F87,
- 0x16F8F, 0x16F9F,
- 0x16FE0, 0x16FE1,
- 0x16FE3, 0x16FE3,
- 0x16FF0, 0x16FF1,
- 0x17000, 0x187F7,
- 0x18800, 0x18CD5,
- 0x18D00, 0x18D08,
- 0x1AFF0, 0x1AFF3,
- 0x1AFF5, 0x1AFFB,
- 0x1AFFD, 0x1AFFE,
- 0x1B000, 0x1B122,
- 0x1B132, 0x1B132,
- 0x1B150, 0x1B152,
- 0x1B155, 0x1B155,
- 0x1B164, 0x1B167,
- 0x1B170, 0x1B2FB,
- 0x1BC00, 0x1BC6A,
- 0x1BC70, 0x1BC7C,
- 0x1BC80, 0x1BC88,
- 0x1BC90, 0x1BC99,
- 0x1BC9E, 0x1BC9E,
- 0x1D400, 0x1D454,
- 0x1D456, 0x1D49C,
- 0x1D49E, 0x1D49F,
- 0x1D4A2, 0x1D4A2,
- 0x1D4A5, 0x1D4A6,
- 0x1D4A9, 0x1D4AC,
- 0x1D4AE, 0x1D4B9,
- 0x1D4BB, 0x1D4BB,
- 0x1D4BD, 0x1D4C3,
- 0x1D4C5, 0x1D505,
- 0x1D507, 0x1D50A,
- 0x1D50D, 0x1D514,
- 0x1D516, 0x1D51C,
- 0x1D51E, 0x1D539,
- 0x1D53B, 0x1D53E,
- 0x1D540, 0x1D544,
- 0x1D546, 0x1D546,
- 0x1D54A, 0x1D550,
- 0x1D552, 0x1D6A5,
- 0x1D6A8, 0x1D6C0,
- 0x1D6C2, 0x1D6DA,
- 0x1D6DC, 0x1D6FA,
- 0x1D6FC, 0x1D714,
- 0x1D716, 0x1D734,
- 0x1D736, 0x1D74E,
- 0x1D750, 0x1D76E,
- 0x1D770, 0x1D788,
- 0x1D78A, 0x1D7A8,
- 0x1D7AA, 0x1D7C2,
- 0x1D7C4, 0x1D7CB,
- 0x1D7CE, 0x1D7FF,
- 0x1DF00, 0x1DF1E,
- 0x1DF25, 0x1DF2A,
- 0x1E000, 0x1E006,
- 0x1E008, 0x1E018,
- 0x1E01B, 0x1E021,
- 0x1E023, 0x1E024,
- 0x1E026, 0x1E02A,
- 0x1E030, 0x1E06D,
- 0x1E08F, 0x1E08F,
- 0x1E100, 0x1E12C,
- 0x1E137, 0x1E13D,
- 0x1E140, 0x1E149,
- 0x1E14E, 0x1E14E,
- 0x1E290, 0x1E2AD,
- 0x1E2C0, 0x1E2EB,
- 0x1E2F0, 0x1E2F9,
- 0x1E4D0, 0x1E4EB,
- 0x1E4F0, 0x1E4F9,
- 0x1E7E0, 0x1E7E6,
- 0x1E7E8, 0x1E7EB,
- 0x1E7ED, 0x1E7EE,
- 0x1E7F0, 0x1E7FE,
- 0x1E800, 0x1E8C4,
- 0x1E900, 0x1E943,
- 0x1E947, 0x1E947,
- 0x1E94B, 0x1E94B,
- 0x1E950, 0x1E959,
- 0x1EE00, 0x1EE03,
- 0x1EE05, 0x1EE1F,
- 0x1EE21, 0x1EE22,
- 0x1EE24, 0x1EE24,
- 0x1EE27, 0x1EE27,
- 0x1EE29, 0x1EE32,
- 0x1EE34, 0x1EE37,
- 0x1EE39, 0x1EE39,
- 0x1EE3B, 0x1EE3B,
- 0x1EE42, 0x1EE42,
- 0x1EE47, 0x1EE47,
- 0x1EE49, 0x1EE49,
- 0x1EE4B, 0x1EE4B,
- 0x1EE4D, 0x1EE4F,
- 0x1EE51, 0x1EE52,
- 0x1EE54, 0x1EE54,
- 0x1EE57, 0x1EE57,
- 0x1EE59, 0x1EE59,
- 0x1EE5B, 0x1EE5B,
- 0x1EE5D, 0x1EE5D,
- 0x1EE5F, 0x1EE5F,
- 0x1EE61, 0x1EE62,
- 0x1EE64, 0x1EE64,
- 0x1EE67, 0x1EE6A,
- 0x1EE6C, 0x1EE72,
- 0x1EE74, 0x1EE77,
- 0x1EE79, 0x1EE7C,
- 0x1EE7E, 0x1EE7E,
- 0x1EE80, 0x1EE89,
- 0x1EE8B, 0x1EE9B,
- 0x1EEA1, 0x1EEA3,
- 0x1EEA5, 0x1EEA9,
- 0x1EEAB, 0x1EEBB,
- 0x1F130, 0x1F149,
- 0x1F150, 0x1F169,
- 0x1F170, 0x1F189,
- 0x1FBF0, 0x1FBF9,
- 0x20000, 0x2A6DF,
- 0x2A700, 0x2B739,
- 0x2B740, 0x2B81D,
- 0x2B820, 0x2CEA1,
- 0x2CEB0, 0x2EBE0,
- 0x2F800, 0x2FA1D,
- 0x30000, 0x3134A,
- 0x31350, 0x323AF,
-};
-
-#define UNICODE_ISUPPER_CODEPOINTS_LENGTH 1296
-static const pm_unicode_codepoint_t unicode_isupper_codepoints[UNICODE_ISUPPER_CODEPOINTS_LENGTH] = {
- 0x100, 0x100,
- 0x102, 0x102,
- 0x104, 0x104,
- 0x106, 0x106,
- 0x108, 0x108,
- 0x10A, 0x10A,
- 0x10C, 0x10C,
- 0x10E, 0x10E,
- 0x110, 0x110,
- 0x112, 0x112,
- 0x114, 0x114,
- 0x116, 0x116,
- 0x118, 0x118,
- 0x11A, 0x11A,
- 0x11C, 0x11C,
- 0x11E, 0x11E,
- 0x120, 0x120,
- 0x122, 0x122,
- 0x124, 0x124,
- 0x126, 0x126,
- 0x128, 0x128,
- 0x12A, 0x12A,
- 0x12C, 0x12C,
- 0x12E, 0x12E,
- 0x130, 0x130,
- 0x132, 0x132,
- 0x134, 0x134,
- 0x136, 0x136,
- 0x139, 0x139,
- 0x13B, 0x13B,
- 0x13D, 0x13D,
- 0x13F, 0x13F,
- 0x141, 0x141,
- 0x143, 0x143,
- 0x145, 0x145,
- 0x147, 0x147,
- 0x14A, 0x14A,
- 0x14C, 0x14C,
- 0x14E, 0x14E,
- 0x150, 0x150,
- 0x152, 0x152,
- 0x154, 0x154,
- 0x156, 0x156,
- 0x158, 0x158,
- 0x15A, 0x15A,
- 0x15C, 0x15C,
- 0x15E, 0x15E,
- 0x160, 0x160,
- 0x162, 0x162,
- 0x164, 0x164,
- 0x166, 0x166,
- 0x168, 0x168,
- 0x16A, 0x16A,
- 0x16C, 0x16C,
- 0x16E, 0x16E,
- 0x170, 0x170,
- 0x172, 0x172,
- 0x174, 0x174,
- 0x176, 0x176,
- 0x178, 0x179,
- 0x17B, 0x17B,
- 0x17D, 0x17D,
- 0x181, 0x182,
- 0x184, 0x184,
- 0x186, 0x187,
- 0x189, 0x18B,
- 0x18E, 0x191,
- 0x193, 0x194,
- 0x196, 0x198,
- 0x19C, 0x19D,
- 0x19F, 0x1A0,
- 0x1A2, 0x1A2,
- 0x1A4, 0x1A4,
- 0x1A6, 0x1A7,
- 0x1A9, 0x1A9,
- 0x1AC, 0x1AC,
- 0x1AE, 0x1AF,
- 0x1B1, 0x1B3,
- 0x1B5, 0x1B5,
- 0x1B7, 0x1B8,
- 0x1BC, 0x1BC,
- 0x1C4, 0x1C4,
- 0x1C7, 0x1C7,
- 0x1CA, 0x1CA,
- 0x1CD, 0x1CD,
- 0x1CF, 0x1CF,
- 0x1D1, 0x1D1,
- 0x1D3, 0x1D3,
- 0x1D5, 0x1D5,
- 0x1D7, 0x1D7,
- 0x1D9, 0x1D9,
- 0x1DB, 0x1DB,
- 0x1DE, 0x1DE,
- 0x1E0, 0x1E0,
- 0x1E2, 0x1E2,
- 0x1E4, 0x1E4,
- 0x1E6, 0x1E6,
- 0x1E8, 0x1E8,
- 0x1EA, 0x1EA,
- 0x1EC, 0x1EC,
- 0x1EE, 0x1EE,
- 0x1F1, 0x1F1,
- 0x1F4, 0x1F4,
- 0x1F6, 0x1F8,
- 0x1FA, 0x1FA,
- 0x1FC, 0x1FC,
- 0x1FE, 0x1FE,
- 0x200, 0x200,
- 0x202, 0x202,
- 0x204, 0x204,
- 0x206, 0x206,
- 0x208, 0x208,
- 0x20A, 0x20A,
- 0x20C, 0x20C,
- 0x20E, 0x20E,
- 0x210, 0x210,
- 0x212, 0x212,
- 0x214, 0x214,
- 0x216, 0x216,
- 0x218, 0x218,
- 0x21A, 0x21A,
- 0x21C, 0x21C,
- 0x21E, 0x21E,
- 0x220, 0x220,
- 0x222, 0x222,
- 0x224, 0x224,
- 0x226, 0x226,
- 0x228, 0x228,
- 0x22A, 0x22A,
- 0x22C, 0x22C,
- 0x22E, 0x22E,
- 0x230, 0x230,
- 0x232, 0x232,
- 0x23A, 0x23B,
- 0x23D, 0x23E,
- 0x241, 0x241,
- 0x243, 0x246,
- 0x248, 0x248,
- 0x24A, 0x24A,
- 0x24C, 0x24C,
- 0x24E, 0x24E,
- 0x370, 0x370,
- 0x372, 0x372,
- 0x376, 0x376,
- 0x37F, 0x37F,
- 0x386, 0x386,
- 0x388, 0x38A,
- 0x38C, 0x38C,
- 0x38E, 0x38F,
- 0x391, 0x3A1,
- 0x3A3, 0x3AB,
- 0x3CF, 0x3CF,
- 0x3D2, 0x3D4,
- 0x3D8, 0x3D8,
- 0x3DA, 0x3DA,
- 0x3DC, 0x3DC,
- 0x3DE, 0x3DE,
- 0x3E0, 0x3E0,
- 0x3E2, 0x3E2,
- 0x3E4, 0x3E4,
- 0x3E6, 0x3E6,
- 0x3E8, 0x3E8,
- 0x3EA, 0x3EA,
- 0x3EC, 0x3EC,
- 0x3EE, 0x3EE,
- 0x3F4, 0x3F4,
- 0x3F7, 0x3F7,
- 0x3F9, 0x3FA,
- 0x3FD, 0x42F,
- 0x460, 0x460,
- 0x462, 0x462,
- 0x464, 0x464,
- 0x466, 0x466,
- 0x468, 0x468,
- 0x46A, 0x46A,
- 0x46C, 0x46C,
- 0x46E, 0x46E,
- 0x470, 0x470,
- 0x472, 0x472,
- 0x474, 0x474,
- 0x476, 0x476,
- 0x478, 0x478,
- 0x47A, 0x47A,
- 0x47C, 0x47C,
- 0x47E, 0x47E,
- 0x480, 0x480,
- 0x48A, 0x48A,
- 0x48C, 0x48C,
- 0x48E, 0x48E,
- 0x490, 0x490,
- 0x492, 0x492,
- 0x494, 0x494,
- 0x496, 0x496,
- 0x498, 0x498,
- 0x49A, 0x49A,
- 0x49C, 0x49C,
- 0x49E, 0x49E,
- 0x4A0, 0x4A0,
- 0x4A2, 0x4A2,
- 0x4A4, 0x4A4,
- 0x4A6, 0x4A6,
- 0x4A8, 0x4A8,
- 0x4AA, 0x4AA,
- 0x4AC, 0x4AC,
- 0x4AE, 0x4AE,
- 0x4B0, 0x4B0,
- 0x4B2, 0x4B2,
- 0x4B4, 0x4B4,
- 0x4B6, 0x4B6,
- 0x4B8, 0x4B8,
- 0x4BA, 0x4BA,
- 0x4BC, 0x4BC,
- 0x4BE, 0x4BE,
- 0x4C0, 0x4C1,
- 0x4C3, 0x4C3,
- 0x4C5, 0x4C5,
- 0x4C7, 0x4C7,
- 0x4C9, 0x4C9,
- 0x4CB, 0x4CB,
- 0x4CD, 0x4CD,
- 0x4D0, 0x4D0,
- 0x4D2, 0x4D2,
- 0x4D4, 0x4D4,
- 0x4D6, 0x4D6,
- 0x4D8, 0x4D8,
- 0x4DA, 0x4DA,
- 0x4DC, 0x4DC,
- 0x4DE, 0x4DE,
- 0x4E0, 0x4E0,
- 0x4E2, 0x4E2,
- 0x4E4, 0x4E4,
- 0x4E6, 0x4E6,
- 0x4E8, 0x4E8,
- 0x4EA, 0x4EA,
- 0x4EC, 0x4EC,
- 0x4EE, 0x4EE,
- 0x4F0, 0x4F0,
- 0x4F2, 0x4F2,
- 0x4F4, 0x4F4,
- 0x4F6, 0x4F6,
- 0x4F8, 0x4F8,
- 0x4FA, 0x4FA,
- 0x4FC, 0x4FC,
- 0x4FE, 0x4FE,
- 0x500, 0x500,
- 0x502, 0x502,
- 0x504, 0x504,
- 0x506, 0x506,
- 0x508, 0x508,
- 0x50A, 0x50A,
- 0x50C, 0x50C,
- 0x50E, 0x50E,
- 0x510, 0x510,
- 0x512, 0x512,
- 0x514, 0x514,
- 0x516, 0x516,
- 0x518, 0x518,
- 0x51A, 0x51A,
- 0x51C, 0x51C,
- 0x51E, 0x51E,
- 0x520, 0x520,
- 0x522, 0x522,
- 0x524, 0x524,
- 0x526, 0x526,
- 0x528, 0x528,
- 0x52A, 0x52A,
- 0x52C, 0x52C,
- 0x52E, 0x52E,
- 0x531, 0x556,
- 0x10A0, 0x10C5,
- 0x10C7, 0x10C7,
- 0x10CD, 0x10CD,
- 0x13A0, 0x13F5,
- 0x1C90, 0x1CBA,
- 0x1CBD, 0x1CBF,
- 0x1E00, 0x1E00,
- 0x1E02, 0x1E02,
- 0x1E04, 0x1E04,
- 0x1E06, 0x1E06,
- 0x1E08, 0x1E08,
- 0x1E0A, 0x1E0A,
- 0x1E0C, 0x1E0C,
- 0x1E0E, 0x1E0E,
- 0x1E10, 0x1E10,
- 0x1E12, 0x1E12,
- 0x1E14, 0x1E14,
- 0x1E16, 0x1E16,
- 0x1E18, 0x1E18,
- 0x1E1A, 0x1E1A,
- 0x1E1C, 0x1E1C,
- 0x1E1E, 0x1E1E,
- 0x1E20, 0x1E20,
- 0x1E22, 0x1E22,
- 0x1E24, 0x1E24,
- 0x1E26, 0x1E26,
- 0x1E28, 0x1E28,
- 0x1E2A, 0x1E2A,
- 0x1E2C, 0x1E2C,
- 0x1E2E, 0x1E2E,
- 0x1E30, 0x1E30,
- 0x1E32, 0x1E32,
- 0x1E34, 0x1E34,
- 0x1E36, 0x1E36,
- 0x1E38, 0x1E38,
- 0x1E3A, 0x1E3A,
- 0x1E3C, 0x1E3C,
- 0x1E3E, 0x1E3E,
- 0x1E40, 0x1E40,
- 0x1E42, 0x1E42,
- 0x1E44, 0x1E44,
- 0x1E46, 0x1E46,
- 0x1E48, 0x1E48,
- 0x1E4A, 0x1E4A,
- 0x1E4C, 0x1E4C,
- 0x1E4E, 0x1E4E,
- 0x1E50, 0x1E50,
- 0x1E52, 0x1E52,
- 0x1E54, 0x1E54,
- 0x1E56, 0x1E56,
- 0x1E58, 0x1E58,
- 0x1E5A, 0x1E5A,
- 0x1E5C, 0x1E5C,
- 0x1E5E, 0x1E5E,
- 0x1E60, 0x1E60,
- 0x1E62, 0x1E62,
- 0x1E64, 0x1E64,
- 0x1E66, 0x1E66,
- 0x1E68, 0x1E68,
- 0x1E6A, 0x1E6A,
- 0x1E6C, 0x1E6C,
- 0x1E6E, 0x1E6E,
- 0x1E70, 0x1E70,
- 0x1E72, 0x1E72,
- 0x1E74, 0x1E74,
- 0x1E76, 0x1E76,
- 0x1E78, 0x1E78,
- 0x1E7A, 0x1E7A,
- 0x1E7C, 0x1E7C,
- 0x1E7E, 0x1E7E,
- 0x1E80, 0x1E80,
- 0x1E82, 0x1E82,
- 0x1E84, 0x1E84,
- 0x1E86, 0x1E86,
- 0x1E88, 0x1E88,
- 0x1E8A, 0x1E8A,
- 0x1E8C, 0x1E8C,
- 0x1E8E, 0x1E8E,
- 0x1E90, 0x1E90,
- 0x1E92, 0x1E92,
- 0x1E94, 0x1E94,
- 0x1E9E, 0x1E9E,
- 0x1EA0, 0x1EA0,
- 0x1EA2, 0x1EA2,
- 0x1EA4, 0x1EA4,
- 0x1EA6, 0x1EA6,
- 0x1EA8, 0x1EA8,
- 0x1EAA, 0x1EAA,
- 0x1EAC, 0x1EAC,
- 0x1EAE, 0x1EAE,
- 0x1EB0, 0x1EB0,
- 0x1EB2, 0x1EB2,
- 0x1EB4, 0x1EB4,
- 0x1EB6, 0x1EB6,
- 0x1EB8, 0x1EB8,
- 0x1EBA, 0x1EBA,
- 0x1EBC, 0x1EBC,
- 0x1EBE, 0x1EBE,
- 0x1EC0, 0x1EC0,
- 0x1EC2, 0x1EC2,
- 0x1EC4, 0x1EC4,
- 0x1EC6, 0x1EC6,
- 0x1EC8, 0x1EC8,
- 0x1ECA, 0x1ECA,
- 0x1ECC, 0x1ECC,
- 0x1ECE, 0x1ECE,
- 0x1ED0, 0x1ED0,
- 0x1ED2, 0x1ED2,
- 0x1ED4, 0x1ED4,
- 0x1ED6, 0x1ED6,
- 0x1ED8, 0x1ED8,
- 0x1EDA, 0x1EDA,
- 0x1EDC, 0x1EDC,
- 0x1EDE, 0x1EDE,
- 0x1EE0, 0x1EE0,
- 0x1EE2, 0x1EE2,
- 0x1EE4, 0x1EE4,
- 0x1EE6, 0x1EE6,
- 0x1EE8, 0x1EE8,
- 0x1EEA, 0x1EEA,
- 0x1EEC, 0x1EEC,
- 0x1EEE, 0x1EEE,
- 0x1EF0, 0x1EF0,
- 0x1EF2, 0x1EF2,
- 0x1EF4, 0x1EF4,
- 0x1EF6, 0x1EF6,
- 0x1EF8, 0x1EF8,
- 0x1EFA, 0x1EFA,
- 0x1EFC, 0x1EFC,
- 0x1EFE, 0x1EFE,
- 0x1F08, 0x1F0F,
- 0x1F18, 0x1F1D,
- 0x1F28, 0x1F2F,
- 0x1F38, 0x1F3F,
- 0x1F48, 0x1F4D,
- 0x1F59, 0x1F59,
- 0x1F5B, 0x1F5B,
- 0x1F5D, 0x1F5D,
- 0x1F5F, 0x1F5F,
- 0x1F68, 0x1F6F,
- 0x1FB8, 0x1FBB,
- 0x1FC8, 0x1FCB,
- 0x1FD8, 0x1FDB,
- 0x1FE8, 0x1FEC,
- 0x1FF8, 0x1FFB,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210B, 0x210D,
- 0x2110, 0x2112,
- 0x2115, 0x2115,
- 0x2119, 0x211D,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212A, 0x212D,
- 0x2130, 0x2133,
- 0x213E, 0x213F,
- 0x2145, 0x2145,
- 0x2160, 0x216F,
- 0x2183, 0x2183,
- 0x24B6, 0x24CF,
- 0x2C00, 0x2C2F,
- 0x2C60, 0x2C60,
- 0x2C62, 0x2C64,
- 0x2C67, 0x2C67,
- 0x2C69, 0x2C69,
- 0x2C6B, 0x2C6B,
- 0x2C6D, 0x2C70,
- 0x2C72, 0x2C72,
- 0x2C75, 0x2C75,
- 0x2C7E, 0x2C80,
- 0x2C82, 0x2C82,
- 0x2C84, 0x2C84,
- 0x2C86, 0x2C86,
- 0x2C88, 0x2C88,
- 0x2C8A, 0x2C8A,
- 0x2C8C, 0x2C8C,
- 0x2C8E, 0x2C8E,
- 0x2C90, 0x2C90,
- 0x2C92, 0x2C92,
- 0x2C94, 0x2C94,
- 0x2C96, 0x2C96,
- 0x2C98, 0x2C98,
- 0x2C9A, 0x2C9A,
- 0x2C9C, 0x2C9C,
- 0x2C9E, 0x2C9E,
- 0x2CA0, 0x2CA0,
- 0x2CA2, 0x2CA2,
- 0x2CA4, 0x2CA4,
- 0x2CA6, 0x2CA6,
- 0x2CA8, 0x2CA8,
- 0x2CAA, 0x2CAA,
- 0x2CAC, 0x2CAC,
- 0x2CAE, 0x2CAE,
- 0x2CB0, 0x2CB0,
- 0x2CB2, 0x2CB2,
- 0x2CB4, 0x2CB4,
- 0x2CB6, 0x2CB6,
- 0x2CB8, 0x2CB8,
- 0x2CBA, 0x2CBA,
- 0x2CBC, 0x2CBC,
- 0x2CBE, 0x2CBE,
- 0x2CC0, 0x2CC0,
- 0x2CC2, 0x2CC2,
- 0x2CC4, 0x2CC4,
- 0x2CC6, 0x2CC6,
- 0x2CC8, 0x2CC8,
- 0x2CCA, 0x2CCA,
- 0x2CCC, 0x2CCC,
- 0x2CCE, 0x2CCE,
- 0x2CD0, 0x2CD0,
- 0x2CD2, 0x2CD2,
- 0x2CD4, 0x2CD4,
- 0x2CD6, 0x2CD6,
- 0x2CD8, 0x2CD8,
- 0x2CDA, 0x2CDA,
- 0x2CDC, 0x2CDC,
- 0x2CDE, 0x2CDE,
- 0x2CE0, 0x2CE0,
- 0x2CE2, 0x2CE2,
- 0x2CEB, 0x2CEB,
- 0x2CED, 0x2CED,
- 0x2CF2, 0x2CF2,
- 0xA640, 0xA640,
- 0xA642, 0xA642,
- 0xA644, 0xA644,
- 0xA646, 0xA646,
- 0xA648, 0xA648,
- 0xA64A, 0xA64A,
- 0xA64C, 0xA64C,
- 0xA64E, 0xA64E,
- 0xA650, 0xA650,
- 0xA652, 0xA652,
- 0xA654, 0xA654,
- 0xA656, 0xA656,
- 0xA658, 0xA658,
- 0xA65A, 0xA65A,
- 0xA65C, 0xA65C,
- 0xA65E, 0xA65E,
- 0xA660, 0xA660,
- 0xA662, 0xA662,
- 0xA664, 0xA664,
- 0xA666, 0xA666,
- 0xA668, 0xA668,
- 0xA66A, 0xA66A,
- 0xA66C, 0xA66C,
- 0xA680, 0xA680,
- 0xA682, 0xA682,
- 0xA684, 0xA684,
- 0xA686, 0xA686,
- 0xA688, 0xA688,
- 0xA68A, 0xA68A,
- 0xA68C, 0xA68C,
- 0xA68E, 0xA68E,
- 0xA690, 0xA690,
- 0xA692, 0xA692,
- 0xA694, 0xA694,
- 0xA696, 0xA696,
- 0xA698, 0xA698,
- 0xA69A, 0xA69A,
- 0xA722, 0xA722,
- 0xA724, 0xA724,
- 0xA726, 0xA726,
- 0xA728, 0xA728,
- 0xA72A, 0xA72A,
- 0xA72C, 0xA72C,
- 0xA72E, 0xA72E,
- 0xA732, 0xA732,
- 0xA734, 0xA734,
- 0xA736, 0xA736,
- 0xA738, 0xA738,
- 0xA73A, 0xA73A,
- 0xA73C, 0xA73C,
- 0xA73E, 0xA73E,
- 0xA740, 0xA740,
- 0xA742, 0xA742,
- 0xA744, 0xA744,
- 0xA746, 0xA746,
- 0xA748, 0xA748,
- 0xA74A, 0xA74A,
- 0xA74C, 0xA74C,
- 0xA74E, 0xA74E,
- 0xA750, 0xA750,
- 0xA752, 0xA752,
- 0xA754, 0xA754,
- 0xA756, 0xA756,
- 0xA758, 0xA758,
- 0xA75A, 0xA75A,
- 0xA75C, 0xA75C,
- 0xA75E, 0xA75E,
- 0xA760, 0xA760,
- 0xA762, 0xA762,
- 0xA764, 0xA764,
- 0xA766, 0xA766,
- 0xA768, 0xA768,
- 0xA76A, 0xA76A,
- 0xA76C, 0xA76C,
- 0xA76E, 0xA76E,
- 0xA779, 0xA779,
- 0xA77B, 0xA77B,
- 0xA77D, 0xA77E,
- 0xA780, 0xA780,
- 0xA782, 0xA782,
- 0xA784, 0xA784,
- 0xA786, 0xA786,
- 0xA78B, 0xA78B,
- 0xA78D, 0xA78D,
- 0xA790, 0xA790,
- 0xA792, 0xA792,
- 0xA796, 0xA796,
- 0xA798, 0xA798,
- 0xA79A, 0xA79A,
- 0xA79C, 0xA79C,
- 0xA79E, 0xA79E,
- 0xA7A0, 0xA7A0,
- 0xA7A2, 0xA7A2,
- 0xA7A4, 0xA7A4,
- 0xA7A6, 0xA7A6,
- 0xA7A8, 0xA7A8,
- 0xA7AA, 0xA7AE,
- 0xA7B0, 0xA7B4,
- 0xA7B6, 0xA7B6,
- 0xA7B8, 0xA7B8,
- 0xA7BA, 0xA7BA,
- 0xA7BC, 0xA7BC,
- 0xA7BE, 0xA7BE,
- 0xA7C0, 0xA7C0,
- 0xA7C2, 0xA7C2,
- 0xA7C4, 0xA7C7,
- 0xA7C9, 0xA7C9,
- 0xA7D0, 0xA7D0,
- 0xA7D6, 0xA7D6,
- 0xA7D8, 0xA7D8,
- 0xA7F5, 0xA7F5,
- 0xFF21, 0xFF3A,
- 0x10400, 0x10427,
- 0x104B0, 0x104D3,
- 0x10570, 0x1057A,
- 0x1057C, 0x1058A,
- 0x1058C, 0x10592,
- 0x10594, 0x10595,
- 0x10C80, 0x10CB2,
- 0x118A0, 0x118BF,
- 0x16E40, 0x16E5F,
- 0x1D400, 0x1D419,
- 0x1D434, 0x1D44D,
- 0x1D468, 0x1D481,
- 0x1D49C, 0x1D49C,
- 0x1D49E, 0x1D49F,
- 0x1D4A2, 0x1D4A2,
- 0x1D4A5, 0x1D4A6,
- 0x1D4A9, 0x1D4AC,
- 0x1D4AE, 0x1D4B5,
- 0x1D4D0, 0x1D4E9,
- 0x1D504, 0x1D505,
- 0x1D507, 0x1D50A,
- 0x1D50D, 0x1D514,
- 0x1D516, 0x1D51C,
- 0x1D538, 0x1D539,
- 0x1D53B, 0x1D53E,
- 0x1D540, 0x1D544,
- 0x1D546, 0x1D546,
- 0x1D54A, 0x1D550,
- 0x1D56C, 0x1D585,
- 0x1D5A0, 0x1D5B9,
- 0x1D5D4, 0x1D5ED,
- 0x1D608, 0x1D621,
- 0x1D63C, 0x1D655,
- 0x1D670, 0x1D689,
- 0x1D6A8, 0x1D6C0,
- 0x1D6E2, 0x1D6FA,
- 0x1D71C, 0x1D734,
- 0x1D756, 0x1D76E,
- 0x1D790, 0x1D7A8,
- 0x1D7CA, 0x1D7CA,
- 0x1E900, 0x1E921,
- 0x1F130, 0x1F149,
- 0x1F150, 0x1F169,
- 0x1F170, 0x1F189,
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding unicode codepoint. Note that
- * this table is different from other encodings where we used a lookup table
- * because the indices of those tables are the byte representations, not the
- * codepoints themselves.
- */
-const uint8_t pm_encoding_unicode_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Binary search through the given list of codepoints to see if the given
- * codepoint is in the list.
- */
-static bool
-pm_unicode_codepoint_match(pm_unicode_codepoint_t codepoint, const pm_unicode_codepoint_t *codepoints, size_t size) {
- size_t start = 0;
- size_t end = size;
-
- while (start < end) {
- size_t middle = start + (end - start) / 2;
- if ((middle % 2) != 0) middle--;
-
- if (codepoint >= codepoints[middle] && codepoint <= codepoints[middle + 1]) {
- return true;
- }
-
- if (codepoint < codepoints[middle]) {
- end = middle;
- } else {
- start = middle + 2;
- }
- }
-
- return false;
-}
-
-/**
- * A state transition table for decoding UTF-8.
- *
- * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
- *
- * 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.
- */
-static const uint8_t pm_utf_8_dfa[] = {
- 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,0,0,0,0, // 00..1f
- 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,0,0,0,0, // 20..3f
- 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,0,0,0,0, // 40..5f
- 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,0,0,0,0, // 60..7f
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
- 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
- 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
- 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
- 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
- 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
- 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
- 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
-};
-
-/**
- * Given a pointer to a string and the number of bytes remaining in the string,
- * decode the next UTF-8 codepoint and return it. The number of bytes consumed
- * is returned in the width out parameter.
- */
-static pm_unicode_codepoint_t
-pm_utf_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) {
- assert(n >= 1);
- size_t maximum = (size_t) n;
-
- uint32_t codepoint;
- uint32_t state = 0;
-
- for (size_t index = 0; index < 4 && index < maximum; index++) {
- uint32_t byte = b[index];
- uint32_t type = pm_utf_8_dfa[byte];
-
- codepoint = (state != 0) ?
- (byte & 0x3fu) | (codepoint << 6) :
- (0xffu >> type) & (byte);
-
- state = pm_utf_8_dfa[256 + (state * 16) + type];
- if (!state) {
- *width = index + 1;
- return (pm_unicode_codepoint_t) codepoint;
- }
- }
-
- *width = 0;
- return 0;
-}
-
-static size_t
-pm_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n) {
- size_t width;
- pm_utf_8_codepoint(b, n, &width);
- return width;
-}
-
-/**
- * Return the size of the next character in the UTF-8 encoding if it is an
- * alphabetical character.
- */
-size_t
-pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n) {
- if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) ? 1 : 0;
- }
-
- size_t width;
- pm_unicode_codepoint_t codepoint = pm_utf_8_codepoint(b, n, &width);
-
- if (codepoint <= 0xFF) {
- return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_ALPHABETIC_BIT) ? width : 0;
- } else {
- return pm_unicode_codepoint_match(codepoint, unicode_alpha_codepoints, UNICODE_ALPHA_CODEPOINTS_LENGTH) ? width : 0;
- }
-}
-
-/**
- * Return the size of the next character in the UTF-8 encoding if it is an
- * alphanumeric character.
- */
-size_t
-pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n) {
- if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0;
- }
-
- size_t width;
- pm_unicode_codepoint_t codepoint = pm_utf_8_codepoint(b, n, &width);
-
- if (codepoint <= 0xFF) {
- return (pm_encoding_unicode_table[(uint8_t) codepoint] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? width : 0;
- } else {
- return pm_unicode_codepoint_match(codepoint, unicode_alnum_codepoints, UNICODE_ALNUM_CODEPOINTS_LENGTH) ? width : 0;
- }
-}
-
-/**
- * Return true if the next character in the UTF-8 encoding if it is an uppercase
- * character.
- */
-bool
-pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n) {
- if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false;
- }
-
- size_t width;
- pm_unicode_codepoint_t codepoint = pm_utf_8_codepoint(b, n, &width);
-
- if (codepoint <= 0xFF) {
- return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false;
- } else {
- return pm_unicode_codepoint_match(codepoint, unicode_isupper_codepoints, UNICODE_ISUPPER_CODEPOINTS_LENGTH) ? true : false;
- }
-}
-
-static pm_unicode_codepoint_t
-pm_cesu_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) {
- if (b[0] < 0x80) {
- *width = 1;
- return (pm_unicode_codepoint_t) b[0];
- }
-
- if (n > 1 && b[0] >= 0xC2 && b[0] <= 0xDF && b[1] >= 0x80 && b[1] <= 0xBF) {
- *width = 2;
-
- // 110xxxxx 10xxxxxx
- return (pm_unicode_codepoint_t) (((b[0] & 0x1F) << 6) | (b[1] & 0x3F));
- }
-
- if (n > 5 && b[0] == 0xED && b[1] >= 0xA0 && b[1] <= 0xAF && b[2] >= 0x80 && b[2] <= 0xBF && b[3] == 0xED && b[4] >= 0xB0 && b[4] <= 0xBF && b[5] >= 0x80 && b[5] <= 0xBF) {
- *width = 6;
-
- // 11101101 1010xxxx 10xxxxxx 11101101 1011xxxx 10xxxxxx
- return (pm_unicode_codepoint_t) (0x10000 + (((b[1] & 0xF) << 16) | ((b[2] & 0x3F) << 10) | ((b[4] & 0xF) << 6) | (b[5] & 0x3F)));
- }
-
- if (n > 2 && b[0] == 0xED && b[1] >= 0xA0 && b[1] <= 0xBF) {
- *width = 3;
-
- // 11101101 1010xxxx 10xxxxx
- return (pm_unicode_codepoint_t) (0x10000 + (((b[0] & 0x03) << 16) | ((b[1] & 0x3F) << 10) | (b[2] & 0x3F)));
- }
-
- if (n > 2 && ((b[0] == 0xE0 && b[1] >= 0xA0) || (b[0] >= 0xE1 && b[0] <= 0xEF && b[1] >= 0x80)) && b[1] <= 0xBF && b[2] >= 0x80 && b[2] <= 0xBF) {
- *width = 3;
-
- // 1110xxxx 10xxxxxx 10xxxxx
- return (pm_unicode_codepoint_t) (((b[0] & 0xF) << 12) | ((b[1] & 0x3F) << 6) | (b[2] & 0x3F));
- }
-
- *width = 0;
- return 0;
-}
-
-static size_t
-pm_encoding_cesu_8_char_width(const uint8_t *b, ptrdiff_t n) {
- size_t width;
- pm_cesu_8_codepoint(b, n, &width);
- return width;
-}
-
-static size_t
-pm_encoding_cesu_8_alpha_char(const uint8_t *b, ptrdiff_t n) {
- if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) ? 1 : 0;
- }
-
- size_t width;
- pm_unicode_codepoint_t codepoint = pm_cesu_8_codepoint(b, n, &width);
-
- if (codepoint <= 0xFF) {
- return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_ALPHABETIC_BIT) ? width : 0;
- } else {
- return pm_unicode_codepoint_match(codepoint, unicode_alpha_codepoints, UNICODE_ALPHA_CODEPOINTS_LENGTH) ? width : 0;
- }
-}
-
-static size_t
-pm_encoding_cesu_8_alnum_char(const uint8_t *b, ptrdiff_t n) {
- if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0;
- }
-
- size_t width;
- pm_unicode_codepoint_t codepoint = pm_cesu_8_codepoint(b, n, &width);
-
- if (codepoint <= 0xFF) {
- return (pm_encoding_unicode_table[(uint8_t) codepoint] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? width : 0;
- } else {
- return pm_unicode_codepoint_match(codepoint, unicode_alnum_codepoints, UNICODE_ALNUM_CODEPOINTS_LENGTH) ? width : 0;
- }
-}
-
-static bool
-pm_encoding_cesu_8_isupper_char(const uint8_t *b, ptrdiff_t n) {
- if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false;
- }
-
- size_t width;
- pm_unicode_codepoint_t codepoint = pm_cesu_8_codepoint(b, n, &width);
-
- if (codepoint <= 0xFF) {
- return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false;
- } else {
- return pm_unicode_codepoint_match(codepoint, unicode_isupper_codepoints, UNICODE_ISUPPER_CODEPOINTS_LENGTH) ? true : false;
- }
-}
-
-#undef UNICODE_ALPHA_CODEPOINTS_LENGTH
-#undef UNICODE_ALNUM_CODEPOINTS_LENGTH
-#undef UNICODE_ISUPPER_CODEPOINTS_LENGTH
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ASCII character.
- */
-static const uint8_t pm_encoding_ascii_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding CP850 character.
- */
-static const uint8_t pm_encoding_cp850_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding CP852 character.
- */
-static const uint8_t pm_encoding_cp852_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding CP855 character.
- */
-static const uint8_t pm_encoding_cp855_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding GB1988 character.
- */
-static const uint8_t pm_encoding_gb1988_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM437 character.
- */
-static const uint8_t pm_encoding_ibm437_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM720 character.
- */
-static const uint8_t pm_encoding_ibm720_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM737 character.
- */
-static const uint8_t pm_encoding_ibm737_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM775 character.
- */
-static const uint8_t pm_encoding_ibm775_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM852 character.
- */
-static const uint8_t pm_encoding_ibm852_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM855 character.
- */
-static const uint8_t pm_encoding_ibm855_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM857 character.
- */
-static const uint8_t pm_encoding_ibm857_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM860 character.
- */
-static const uint8_t pm_encoding_ibm860_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM861 character.
- */
-static const uint8_t pm_encoding_ibm861_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM862 character.
- */
-static const uint8_t pm_encoding_ibm862_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM863 character.
- */
-static const uint8_t pm_encoding_ibm863_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM864 character.
- */
-static const uint8_t pm_encoding_ibm864_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM865 character.
- */
-static const uint8_t pm_encoding_ibm865_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM866 character.
- */
-static const uint8_t pm_encoding_ibm866_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding IBM869 character.
- */
-static const uint8_t pm_encoding_ibm869_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-1 character.
- */
-static const uint8_t pm_encoding_iso_8859_1_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-2 character.
- */
-static const uint8_t pm_encoding_iso_8859_2_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 0, 7, 0, 7, 7, 0, 0, 7, 7, 7, 7, 0, 7, 7, // Ax
- 0, 3, 0, 3, 0, 3, 3, 0, 0, 3, 3, 3, 3, 0, 3, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-3 character.
- */
-static const uint8_t pm_encoding_iso_8859_3_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 0, 0, 0, 0, 7, 0, 0, 7, 7, 7, 7, 0, 0, 7, // Ax
- 0, 3, 0, 0, 0, 3, 3, 0, 0, 3, 3, 3, 3, 0, 0, 3, // Bx
- 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 0, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-4 character.
- */
-static const uint8_t pm_encoding_iso_8859_4_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 3, 7, 0, 7, 7, 0, 0, 7, 7, 7, 7, 0, 7, 0, // Ax
- 0, 3, 0, 3, 0, 3, 3, 0, 0, 3, 3, 3, 3, 7, 3, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-5 character.
- */
-static const uint8_t pm_encoding_iso_8859_5_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, // Ax
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-6 character.
- */
-static const uint8_t pm_encoding_iso_8859_6_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-7 character.
- */
-static const uint8_t pm_encoding_iso_8859_7_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, // Bx
- 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-8 character.
- */
-static const uint8_t pm_encoding_iso_8859_8_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-9 character.
- */
-static const uint8_t pm_encoding_iso_8859_9_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-10 character.
- */
-static const uint8_t pm_encoding_iso_8859_10_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, // Ax
- 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-11 character.
- */
-static const uint8_t pm_encoding_iso_8859_11_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ax
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Bx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-13 character.
- */
-static const uint8_t pm_encoding_iso_8859_13_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 0, 0, 0, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-14 character.
- */
-static const uint8_t pm_encoding_iso_8859_14_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 3, 0, 7, 3, 7, 0, 7, 0, 7, 3, 7, 0, 0, 7, // Ax
- 7, 3, 7, 3, 7, 3, 0, 7, 3, 3, 3, 7, 3, 7, 3, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-15 character.
- */
-static const uint8_t pm_encoding_iso_8859_15_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 7, 0, 3, 0, 3, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 7, 3, 0, 0, 3, 0, 3, 0, 7, 3, 7, 0, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding ISO-8859-16 character.
- */
-static const uint8_t pm_encoding_iso_8859_16_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 7, 3, 7, 0, 0, 7, 0, 3, 0, 7, 0, 7, 0, 3, 7, // Ax
- 0, 0, 7, 3, 7, 0, 0, 0, 3, 3, 3, 0, 7, 3, 7, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding KOI8-R character.
- */
-static const uint8_t pm_encoding_koi8_r_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Dx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Ex
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding KOI8-U character.
- */
-static const uint8_t pm_encoding_koi8_u_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 3, 0, 0, // Ax
- 0, 0, 0, 7, 7, 0, 7, 7, 0, 0, 0, 0, 0, 7, 0, 0, // Bx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Dx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Ex
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macCentEuro character.
- */
-static const uint8_t pm_encoding_mac_cent_euro_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macCroatian character.
- */
-static const uint8_t pm_encoding_mac_croatian_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
- /**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macCyrillic character.
- */
-static const uint8_t pm_encoding_mac_cyrillic_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macGreek character.
- */
-static const uint8_t pm_encoding_mac_greek_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macIceland character.
- */
-static const uint8_t pm_encoding_mac_iceland_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macRoman character.
- */
-static const uint8_t pm_encoding_mac_roman_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macRomania character.
- */
-static const uint8_t pm_encoding_mac_romania_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macThai character.
- */
-static const uint8_t pm_encoding_mac_thai_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding TIS-620 character.
- */
-static const uint8_t pm_encoding_tis_620_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ax
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Bx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macTurkish character.
- */
-static const uint8_t pm_encoding_mac_turkish_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding macUkraine character.
- */
-static const uint8_t pm_encoding_mac_ukraine_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1250 character.
- */
-static const uint8_t pm_encoding_windows_1250_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, // 9x
- 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, 0, 0, 0, 0, 7, // Ax
- 0, 0, 0, 3, 0, 3, 0, 0, 0, 3, 3, 0, 7, 0, 3, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1251 character.
- */
-static const uint8_t pm_encoding_windows_1251_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 7, 7, 0, 3, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, // 8x
- 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, // 9x
- 0, 7, 3, 7, 0, 7, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, // Ax
- 0, 0, 7, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 7, 3, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1252 character.
- */
-static const uint8_t pm_encoding_windows_1252_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 7, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 7, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1253 character.
- */
-static const uint8_t pm_encoding_windows_1253_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, // Bx
- 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1254 character.
- */
-static const uint8_t pm_encoding_windows_1254_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 7, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1255 character.
- */
-static const uint8_t pm_encoding_windows_1255_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1256 character.
- */
-static const uint8_t pm_encoding_windows_1256_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1257 character.
- */
-static const uint8_t pm_encoding_windows_1257_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, // Ax
- 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 0, 0, 0, 3, // Bx
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx
- 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex
- 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-1258 character.
- */
-static const uint8_t pm_encoding_windows_1258_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-/**
- * Each element of the following table contains a bitfield that indicates a
- * piece of information about the corresponding windows-874 character.
- */
-static const uint8_t pm_encoding_windows_874_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x
- 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x
- 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-#define PRISM_ENCODING_TABLE(name) \
- static size_t pm_encoding_ ##name ## _alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \
- return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHABETIC_BIT); \
- } \
- static size_t pm_encoding_ ##name ## _alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \
- return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; \
- } \
- static bool pm_encoding_ ##name ## _isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \
- return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_UPPERCASE_BIT); \
- }
-
-PRISM_ENCODING_TABLE(cp850)
-PRISM_ENCODING_TABLE(cp852)
-PRISM_ENCODING_TABLE(cp855)
-PRISM_ENCODING_TABLE(gb1988)
-PRISM_ENCODING_TABLE(ibm437)
-PRISM_ENCODING_TABLE(ibm720)
-PRISM_ENCODING_TABLE(ibm737)
-PRISM_ENCODING_TABLE(ibm775)
-PRISM_ENCODING_TABLE(ibm852)
-PRISM_ENCODING_TABLE(ibm855)
-PRISM_ENCODING_TABLE(ibm857)
-PRISM_ENCODING_TABLE(ibm860)
-PRISM_ENCODING_TABLE(ibm861)
-PRISM_ENCODING_TABLE(ibm862)
-PRISM_ENCODING_TABLE(ibm863)
-PRISM_ENCODING_TABLE(ibm864)
-PRISM_ENCODING_TABLE(ibm865)
-PRISM_ENCODING_TABLE(ibm866)
-PRISM_ENCODING_TABLE(ibm869)
-PRISM_ENCODING_TABLE(iso_8859_1)
-PRISM_ENCODING_TABLE(iso_8859_2)
-PRISM_ENCODING_TABLE(iso_8859_3)
-PRISM_ENCODING_TABLE(iso_8859_4)
-PRISM_ENCODING_TABLE(iso_8859_5)
-PRISM_ENCODING_TABLE(iso_8859_6)
-PRISM_ENCODING_TABLE(iso_8859_7)
-PRISM_ENCODING_TABLE(iso_8859_8)
-PRISM_ENCODING_TABLE(iso_8859_9)
-PRISM_ENCODING_TABLE(iso_8859_10)
-PRISM_ENCODING_TABLE(iso_8859_11)
-PRISM_ENCODING_TABLE(iso_8859_13)
-PRISM_ENCODING_TABLE(iso_8859_14)
-PRISM_ENCODING_TABLE(iso_8859_15)
-PRISM_ENCODING_TABLE(iso_8859_16)
-PRISM_ENCODING_TABLE(koi8_r)
-PRISM_ENCODING_TABLE(koi8_u)
-PRISM_ENCODING_TABLE(mac_cent_euro)
-PRISM_ENCODING_TABLE(mac_croatian)
-PRISM_ENCODING_TABLE(mac_cyrillic)
-PRISM_ENCODING_TABLE(mac_greek)
-PRISM_ENCODING_TABLE(mac_iceland)
-PRISM_ENCODING_TABLE(mac_roman)
-PRISM_ENCODING_TABLE(mac_romania)
-PRISM_ENCODING_TABLE(mac_thai)
-PRISM_ENCODING_TABLE(mac_turkish)
-PRISM_ENCODING_TABLE(mac_ukraine)
-PRISM_ENCODING_TABLE(tis_620)
-PRISM_ENCODING_TABLE(windows_1250)
-PRISM_ENCODING_TABLE(windows_1251)
-PRISM_ENCODING_TABLE(windows_1252)
-PRISM_ENCODING_TABLE(windows_1253)
-PRISM_ENCODING_TABLE(windows_1254)
-PRISM_ENCODING_TABLE(windows_1255)
-PRISM_ENCODING_TABLE(windows_1256)
-PRISM_ENCODING_TABLE(windows_1257)
-PRISM_ENCODING_TABLE(windows_1258)
-PRISM_ENCODING_TABLE(windows_874)
-
-#undef PRISM_ENCODING_TABLE
-
-/**
- * Returns the size of the next character in the ASCII encoding. This basically
- * means that if the top bit is not set, the character is 1 byte long.
- */
-static size_t
-pm_encoding_ascii_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) {
- return *b < 0x80 ? 1 : 0;
-}
-
-/**
- * Return the size of the next character in the ASCII encoding if it is an
- * alphabetical character.
- */
-static size_t
-pm_encoding_ascii_alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) {
- return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT);
-}
-
-/**
- * Certain encodings are equivalent to ASCII below 0x80, so it works for our
- * purposes to have a function here that first checks the bounds and then falls
- * back to checking the ASCII lookup table.
- */
-static size_t
-pm_encoding_ascii_alpha_char_7bit(const uint8_t *b, ptrdiff_t n) {
- return (*b < 0x80) ? pm_encoding_ascii_alpha_char(b, n) : 0;
-}
-
-/**
- * Return the size of the next character in the ASCII encoding if it is an
- * alphanumeric character.
- */
-static size_t
-pm_encoding_ascii_alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) {
- return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0;
-}
-
-/**
- * Certain encodings are equivalent to ASCII below 0x80, so it works for our
- * purposes to have a function here that first checks the bounds and then falls
- * back to checking the ASCII lookup table.
- */
-static size_t
-pm_encoding_ascii_alnum_char_7bit(const uint8_t *b, ptrdiff_t n) {
- return (*b < 0x80) ? pm_encoding_ascii_alnum_char(b, n) : 0;
-}
-
-/**
- * Return true if the next character in the ASCII encoding if it is an uppercase
- * character.
- */
-static bool
-pm_encoding_ascii_isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) {
- return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_UPPERCASE_BIT);
-}
-
-/**
- * Certain encodings are equivalent to ASCII below 0x80, so it works for our
- * purposes to have a function here that first checks the bounds and then falls
- * back to checking the ASCII lookup table.
- */
-static bool
-pm_encoding_ascii_isupper_char_7bit(const uint8_t *b, ptrdiff_t n) {
- return (*b < 0x80) && pm_encoding_ascii_isupper_char(b, n);
-}
-
-/**
- * For a lot of encodings the default is that they are a single byte long no
- * matter what the codepoint, so this function is shared between them.
- */
-static size_t
-pm_encoding_single_char_width(PRISM_ATTRIBUTE_UNUSED const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) {
- return 1;
-}
-
-/**
- * Returns the size of the next character in the Big5 encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_big5_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters.
- if (*b < 0x80) {
- return 1;
- }
-
- // These are the double byte characters.
- if ((n > 1) && (b[0] >= 0xA1 && b[0] <= 0xFE) && ((b[1] >= 0x40 && b[1] <= 0x7E) || (b[1] >= 0xA1 && b[1] <= 0xFE))) {
- return 2;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the CP949 encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_cp949_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters
- if (*b <= 0x80) {
- return 1;
- }
-
- // These are the double byte characters
- if ((n > 1) && (b[0] >= 0x81 && b[0] <= 0xfe) && (b[1] >= 0x41 && b[1] <= 0xfe)) {
- return 2;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the Emacs MULE encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_emacs_mule_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the 1 byte characters.
- if (*b < 0x80) {
- return 1;
- }
-
- // These are the 2 byte characters.
- if ((n > 1) && (b[0] >= 0x81 && b[0] <= 0x8F) && (b[1] >= 0xA0)) {
- return 2;
- }
-
- // These are the 3 byte characters.
- if (
- (n > 2) &&
- (
- ((b[0] >= 0x90 && b[0] <= 0x99) && (b[1] >= 0xA0)) ||
- ((b[0] == 0x9A || b[0] == 0x9B) && (b[1] >= 0xE0 && b[1] <= 0xEF))
- ) &&
- (b[2] >= 0xA0)
- ) {
- return 3;
- }
-
- // These are the 4 byte characters.
- if (
- (n > 3) &&
- (
- ((b[0] == 0x9C) && (b[1] >= 0xF0) && (b[1] <= 0xF4)) ||
- ((b[0] == 0x9D) && (b[1] >= 0xF5) && (b[1] <= 0xFE))
- ) &&
- (b[2] >= 0xA0) && (b[3] >= 0xA0)
- ) {
- return 4;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the EUC-JP encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_euc_jp_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters.
- if (*b < 0x80) {
- return 1;
- }
-
- // These are the double byte characters.
- if ((n > 1) && ((b[0] == 0x8E) || (b[0] >= 0xA1 && b[0] <= 0xFE)) && (b[1] >= 0xA1 && b[1] <= 0xFE)) {
- return 2;
- }
-
- // These are the triple byte characters.
- if ((n > 2) && (b[0] == 0x8F) && (b[1] >= 0xA1 && b[2] <= 0xFE) && (b[2] >= 0xA1 && b[2] <= 0xFE)) {
- return 3;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the EUC-KR encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_euc_kr_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters.
- if (*b < 0x80) {
- return 1;
- }
-
- // These are the double byte characters.
- if ((n > 1) && (b[0] >= 0xA1 && b[0] <= 0xFE) && (b[1] >= 0xA1 && b[1] <= 0xFE)) {
- return 2;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the EUC-TW encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_euc_tw_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters.
- if (*b < 0x80) {
- return 1;
- }
-
- // These are the double byte characters.
- if ((n > 1) && (b[0] >= 0xA1) && (b[0] <= 0xFE) && (b[1] >= 0xA1) && (b[1] <= 0xFE)) {
- return 2;
- }
-
- // These are the quadruple byte characters.
- if ((n > 3) && (b[0] == 0x8E) && (b[1] >= 0xA1) && (b[1] <= 0xB0) && (b[2] >= 0xA1) && (b[2] <= 0xFE) && (b[3] >= 0xA1) && (b[3] <= 0xFE)) {
- return 4;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the GB18030 encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_gb18030_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the 1 byte characters.
- if (*b < 0x80) {
- return 1;
- }
-
- // These are the 2 byte characters.
- if ((n > 1) && (b[0] >= 0x81 && b[0] <= 0xFE) && (b[1] >= 0x40 && b[1] <= 0xFE && b[1] != 0x7F)) {
- return 2;
- }
-
- // These are the 4 byte characters.
- if ((n > 3) && ((b[0] >= 0x81 && b[0] <= 0xFE) && (b[1] >= 0x30 && b[1] <= 0x39) && (b[2] >= 0x81 && b[2] <= 0xFE) && (b[3] >= 0x30 && b[3] <= 0x39))) {
- return 4;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the GBK encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_gbk_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters.
- if (*b <= 0x80) {
- return 1;
- }
-
- // These are the double byte characters.
- if (
- (n > 1) &&
- (
- ((b[0] >= 0xA1 && b[0] <= 0xA9) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // GBK/1
- ((b[0] >= 0xB0 && b[0] <= 0xF7) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // GBK/2
- ((b[0] >= 0x81 && b[0] <= 0xA0) && (b[1] >= 0x40 && b[1] <= 0xFE) && (b[1] != 0x7F)) || // GBK/3
- ((b[0] >= 0xAA && b[0] <= 0xFE) && (b[1] >= 0x40 && b[1] <= 0xA0) && (b[1] != 0x7F)) || // GBK/4
- ((b[0] >= 0xA8 && b[0] <= 0xA9) && (b[1] >= 0x40 && b[1] <= 0xA0) && (b[1] != 0x7F)) || // GBK/5
- ((b[0] >= 0xAA && b[0] <= 0xAF) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // user-defined 1
- ((b[0] >= 0xF8 && b[0] <= 0xFE) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // user-defined 2
- ((b[0] >= 0xA1 && b[0] <= 0xA7) && (b[1] >= 0x40 && b[1] <= 0xA0) && (b[1] != 0x7F)) // user-defined 3
- )
- ) {
- return 2;
- }
-
- return 0;
-}
-
-/**
- * Returns the size of the next character in the KOI-8 encoding. This means
- * checking if it's a valid codepoint in KOI-8 and if it is returning 1.
- */
-static size_t
-pm_encoding_koi8_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) {
- return ((*b >= 0x20 && *b <= 0x7E) || (*b >= 0x80)) ? 1 : 0;
-}
-
-/**
- * Returns the size of the next character in the Shift_JIS encoding, or 0 if a
- * character cannot be decoded from the given bytes.
- */
-static size_t
-pm_encoding_shift_jis_char_width(const uint8_t *b, ptrdiff_t n) {
- // These are the single byte characters.
- if (*b < 0x80 || (*b >= 0xA1 && *b <= 0xDF)) {
- return 1;
- }
-
- // These are the double byte characters.
- if ((n > 1) && ((b[0] >= 0x81 && b[0] <= 0x9F) || (b[0] >= 0xE0 && b[0] <= 0xFC)) && (b[1] >= 0x40 && b[1] <= 0xFC)) {
- return 2;
- }
-
- return 0;
-}
-
-/**
- * This is the table of all of the encodings that prism supports.
- */
-const pm_encoding_t pm_encodings[] = {
- [PM_ENCODING_UTF_8] = {
- .name = "UTF-8",
- .char_width = pm_encoding_utf_8_char_width,
- .alnum_char = pm_encoding_utf_8_alnum_char,
- .alpha_char = pm_encoding_utf_8_alpha_char,
- .isupper_char = pm_encoding_utf_8_isupper_char,
- .multibyte = true
- },
- [PM_ENCODING_ASCII_8BIT] = {
- .name = "ASCII-8BIT",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char,
- .alpha_char = pm_encoding_ascii_alpha_char,
- .isupper_char = pm_encoding_ascii_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_BIG5] = {
- .name = "Big5",
- .char_width = pm_encoding_big5_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_BIG5_HKSCS] = {
- .name = "Big5-HKSCS",
- .char_width = pm_encoding_big5_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_BIG5_UAO] = {
- .name = "Big5-UAO",
- .char_width = pm_encoding_big5_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_CESU_8] = {
- .name = "CESU-8",
- .char_width = pm_encoding_cesu_8_char_width,
- .alnum_char = pm_encoding_cesu_8_alnum_char,
- .alpha_char = pm_encoding_cesu_8_alpha_char,
- .isupper_char = pm_encoding_cesu_8_isupper_char,
- .multibyte = true
- },
- [PM_ENCODING_CP51932] = {
- .name = "CP51932",
- .char_width = pm_encoding_euc_jp_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_CP850] = {
- .name = "CP850",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_cp850_alnum_char,
- .alpha_char = pm_encoding_cp850_alpha_char,
- .isupper_char = pm_encoding_cp850_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_CP852] = {
- .name = "CP852",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_cp852_alnum_char,
- .alpha_char = pm_encoding_cp852_alpha_char,
- .isupper_char = pm_encoding_cp852_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_CP855] = {
- .name = "CP855",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_cp855_alnum_char,
- .alpha_char = pm_encoding_cp855_alpha_char,
- .isupper_char = pm_encoding_cp855_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_CP949] = {
- .name = "CP949",
- .char_width = pm_encoding_cp949_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_CP950] = {
- .name = "CP950",
- .char_width = pm_encoding_big5_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_CP951] = {
- .name = "CP951",
- .char_width = pm_encoding_big5_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_EMACS_MULE] = {
- .name = "Emacs-Mule",
- .char_width = pm_encoding_emacs_mule_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_EUC_JP] = {
- .name = "EUC-JP",
- .char_width = pm_encoding_euc_jp_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_EUC_JP_MS] = {
- .name = "eucJP-ms",
- .char_width = pm_encoding_euc_jp_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_EUC_JIS_2004] = {
- .name = "EUC-JIS-2004",
- .char_width = pm_encoding_euc_jp_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_EUC_KR] = {
- .name = "EUC-KR",
- .char_width = pm_encoding_euc_kr_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_EUC_TW] = {
- .name = "EUC-TW",
- .char_width = pm_encoding_euc_tw_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_GB12345] = {
- .name = "GB12345",
- .char_width = pm_encoding_euc_kr_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_GB18030] = {
- .name = "GB18030",
- .char_width = pm_encoding_gb18030_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_GB1988] = {
- .name = "GB1988",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_gb1988_alnum_char,
- .alpha_char = pm_encoding_gb1988_alpha_char,
- .isupper_char = pm_encoding_gb1988_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_GB2312] = {
- .name = "GB2312",
- .char_width = pm_encoding_euc_kr_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_GBK] = {
- .name = "GBK",
- .char_width = pm_encoding_gbk_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_IBM437] = {
- .name = "IBM437",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm437_alnum_char,
- .alpha_char = pm_encoding_ibm437_alpha_char,
- .isupper_char = pm_encoding_ibm437_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM720] = {
- .name = "IBM720",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm720_alnum_char,
- .alpha_char = pm_encoding_ibm720_alpha_char,
- .isupper_char = pm_encoding_ibm720_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM737] = {
- .name = "IBM737",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm737_alnum_char,
- .alpha_char = pm_encoding_ibm737_alpha_char,
- .isupper_char = pm_encoding_ibm737_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM775] = {
- .name = "IBM775",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm775_alnum_char,
- .alpha_char = pm_encoding_ibm775_alpha_char,
- .isupper_char = pm_encoding_ibm775_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM852] = {
- .name = "IBM852",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm852_alnum_char,
- .alpha_char = pm_encoding_ibm852_alpha_char,
- .isupper_char = pm_encoding_ibm852_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM855] = {
- .name = "IBM855",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm855_alnum_char,
- .alpha_char = pm_encoding_ibm855_alpha_char,
- .isupper_char = pm_encoding_ibm855_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM857] = {
- .name = "IBM857",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm857_alnum_char,
- .alpha_char = pm_encoding_ibm857_alpha_char,
- .isupper_char = pm_encoding_ibm857_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM860] = {
- .name = "IBM860",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm860_alnum_char,
- .alpha_char = pm_encoding_ibm860_alpha_char,
- .isupper_char = pm_encoding_ibm860_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM861] = {
- .name = "IBM861",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm861_alnum_char,
- .alpha_char = pm_encoding_ibm861_alpha_char,
- .isupper_char = pm_encoding_ibm861_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM862] = {
- .name = "IBM862",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm862_alnum_char,
- .alpha_char = pm_encoding_ibm862_alpha_char,
- .isupper_char = pm_encoding_ibm862_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM863] = {
- .name = "IBM863",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm863_alnum_char,
- .alpha_char = pm_encoding_ibm863_alpha_char,
- .isupper_char = pm_encoding_ibm863_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM864] = {
- .name = "IBM864",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm864_alnum_char,
- .alpha_char = pm_encoding_ibm864_alpha_char,
- .isupper_char = pm_encoding_ibm864_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM865] = {
- .name = "IBM865",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm865_alnum_char,
- .alpha_char = pm_encoding_ibm865_alpha_char,
- .isupper_char = pm_encoding_ibm865_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM866] = {
- .name = "IBM866",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm866_alnum_char,
- .alpha_char = pm_encoding_ibm866_alpha_char,
- .isupper_char = pm_encoding_ibm866_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_IBM869] = {
- .name = "IBM869",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_ibm869_alnum_char,
- .alpha_char = pm_encoding_ibm869_alpha_char,
- .isupper_char = pm_encoding_ibm869_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_1] = {
- .name = "ISO-8859-1",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_1_alnum_char,
- .alpha_char = pm_encoding_iso_8859_1_alpha_char,
- .isupper_char = pm_encoding_iso_8859_1_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_2] = {
- .name = "ISO-8859-2",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_2_alnum_char,
- .alpha_char = pm_encoding_iso_8859_2_alpha_char,
- .isupper_char = pm_encoding_iso_8859_2_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_3] = {
- .name = "ISO-8859-3",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_3_alnum_char,
- .alpha_char = pm_encoding_iso_8859_3_alpha_char,
- .isupper_char = pm_encoding_iso_8859_3_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_4] = {
- .name = "ISO-8859-4",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_4_alnum_char,
- .alpha_char = pm_encoding_iso_8859_4_alpha_char,
- .isupper_char = pm_encoding_iso_8859_4_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_5] = {
- .name = "ISO-8859-5",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_5_alnum_char,
- .alpha_char = pm_encoding_iso_8859_5_alpha_char,
- .isupper_char = pm_encoding_iso_8859_5_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_6] = {
- .name = "ISO-8859-6",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_6_alnum_char,
- .alpha_char = pm_encoding_iso_8859_6_alpha_char,
- .isupper_char = pm_encoding_iso_8859_6_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_7] = {
- .name = "ISO-8859-7",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_7_alnum_char,
- .alpha_char = pm_encoding_iso_8859_7_alpha_char,
- .isupper_char = pm_encoding_iso_8859_7_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_8] = {
- .name = "ISO-8859-8",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_8_alnum_char,
- .alpha_char = pm_encoding_iso_8859_8_alpha_char,
- .isupper_char = pm_encoding_iso_8859_8_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_9] = {
- .name = "ISO-8859-9",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_9_alnum_char,
- .alpha_char = pm_encoding_iso_8859_9_alpha_char,
- .isupper_char = pm_encoding_iso_8859_9_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_10] = {
- .name = "ISO-8859-10",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_10_alnum_char,
- .alpha_char = pm_encoding_iso_8859_10_alpha_char,
- .isupper_char = pm_encoding_iso_8859_10_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_11] = {
- .name = "ISO-8859-11",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_11_alnum_char,
- .alpha_char = pm_encoding_iso_8859_11_alpha_char,
- .isupper_char = pm_encoding_iso_8859_11_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_13] = {
- .name = "ISO-8859-13",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_13_alnum_char,
- .alpha_char = pm_encoding_iso_8859_13_alpha_char,
- .isupper_char = pm_encoding_iso_8859_13_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_14] = {
- .name = "ISO-8859-14",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_14_alnum_char,
- .alpha_char = pm_encoding_iso_8859_14_alpha_char,
- .isupper_char = pm_encoding_iso_8859_14_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_15] = {
- .name = "ISO-8859-15",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_15_alnum_char,
- .alpha_char = pm_encoding_iso_8859_15_alpha_char,
- .isupper_char = pm_encoding_iso_8859_15_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_ISO_8859_16] = {
- .name = "ISO-8859-16",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_iso_8859_16_alnum_char,
- .alpha_char = pm_encoding_iso_8859_16_alpha_char,
- .isupper_char = pm_encoding_iso_8859_16_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_KOI8_R] = {
- .name = "KOI8-R",
- .char_width = pm_encoding_koi8_char_width,
- .alnum_char = pm_encoding_koi8_r_alnum_char,
- .alpha_char = pm_encoding_koi8_r_alpha_char,
- .isupper_char = pm_encoding_koi8_r_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_KOI8_U] = {
- .name = "KOI8-U",
- .char_width = pm_encoding_koi8_char_width,
- .alnum_char = pm_encoding_koi8_u_alnum_char,
- .alpha_char = pm_encoding_koi8_u_alpha_char,
- .isupper_char = pm_encoding_koi8_u_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_CENT_EURO] = {
- .name = "macCentEuro",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_cent_euro_alnum_char,
- .alpha_char = pm_encoding_mac_cent_euro_alpha_char,
- .isupper_char = pm_encoding_mac_cent_euro_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_CROATIAN] = {
- .name = "macCroatian",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_croatian_alnum_char,
- .alpha_char = pm_encoding_mac_croatian_alpha_char,
- .isupper_char = pm_encoding_mac_croatian_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_CYRILLIC] = {
- .name = "macCyrillic",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_cyrillic_alnum_char,
- .alpha_char = pm_encoding_mac_cyrillic_alpha_char,
- .isupper_char = pm_encoding_mac_cyrillic_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_GREEK] = {
- .name = "macGreek",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_greek_alnum_char,
- .alpha_char = pm_encoding_mac_greek_alpha_char,
- .isupper_char = pm_encoding_mac_greek_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_ICELAND] = {
- .name = "macIceland",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_iceland_alnum_char,
- .alpha_char = pm_encoding_mac_iceland_alpha_char,
- .isupper_char = pm_encoding_mac_iceland_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_JAPANESE] = {
- .name = "MacJapanese",
- .char_width = pm_encoding_shift_jis_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_MAC_ROMAN] = {
- .name = "macRoman",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_roman_alnum_char,
- .alpha_char = pm_encoding_mac_roman_alpha_char,
- .isupper_char = pm_encoding_mac_roman_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_ROMANIA] = {
- .name = "macRomania",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_romania_alnum_char,
- .alpha_char = pm_encoding_mac_romania_alpha_char,
- .isupper_char = pm_encoding_mac_romania_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_THAI] = {
- .name = "macThai",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_thai_alnum_char,
- .alpha_char = pm_encoding_mac_thai_alpha_char,
- .isupper_char = pm_encoding_mac_thai_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_TURKISH] = {
- .name = "macTurkish",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_turkish_alnum_char,
- .alpha_char = pm_encoding_mac_turkish_alpha_char,
- .isupper_char = pm_encoding_mac_turkish_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_MAC_UKRAINE] = {
- .name = "macUkraine",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_mac_ukraine_alnum_char,
- .alpha_char = pm_encoding_mac_ukraine_alpha_char,
- .isupper_char = pm_encoding_mac_ukraine_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_SHIFT_JIS] = {
- .name = "Shift_JIS",
- .char_width = pm_encoding_shift_jis_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_SJIS_DOCOMO] = {
- .name = "SJIS-DoCoMo",
- .char_width = pm_encoding_shift_jis_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_SJIS_KDDI] = {
- .name = "SJIS-KDDI",
- .char_width = pm_encoding_shift_jis_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_SJIS_SOFTBANK] = {
- .name = "SJIS-SoftBank",
- .char_width = pm_encoding_shift_jis_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_STATELESS_ISO_2022_JP] = {
- .name = "stateless-ISO-2022-JP",
- .char_width = pm_encoding_emacs_mule_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_STATELESS_ISO_2022_JP_KDDI] = {
- .name = "stateless-ISO-2022-JP-KDDI",
- .char_width = pm_encoding_emacs_mule_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_TIS_620] = {
- .name = "TIS-620",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_tis_620_alnum_char,
- .alpha_char = pm_encoding_tis_620_alpha_char,
- .isupper_char = pm_encoding_tis_620_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_US_ASCII] = {
- .name = "US-ASCII",
- .char_width = pm_encoding_ascii_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char,
- .alpha_char = pm_encoding_ascii_alpha_char,
- .isupper_char = pm_encoding_ascii_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_UTF8_MAC] = {
- .name = "UTF8-MAC",
- .char_width = pm_encoding_utf_8_char_width,
- .alnum_char = pm_encoding_utf_8_alnum_char,
- .alpha_char = pm_encoding_utf_8_alpha_char,
- .isupper_char = pm_encoding_utf_8_isupper_char,
- .multibyte = true
- },
- [PM_ENCODING_UTF8_DOCOMO] = {
- .name = "UTF8-DoCoMo",
- .char_width = pm_encoding_utf_8_char_width,
- .alnum_char = pm_encoding_utf_8_alnum_char,
- .alpha_char = pm_encoding_utf_8_alpha_char,
- .isupper_char = pm_encoding_utf_8_isupper_char,
- .multibyte = true
- },
- [PM_ENCODING_UTF8_KDDI] = {
- .name = "UTF8-KDDI",
- .char_width = pm_encoding_utf_8_char_width,
- .alnum_char = pm_encoding_utf_8_alnum_char,
- .alpha_char = pm_encoding_utf_8_alpha_char,
- .isupper_char = pm_encoding_utf_8_isupper_char,
- .multibyte = true
- },
- [PM_ENCODING_UTF8_SOFTBANK] = {
- .name = "UTF8-SoftBank",
- .char_width = pm_encoding_utf_8_char_width,
- .alnum_char = pm_encoding_utf_8_alnum_char,
- .alpha_char = pm_encoding_utf_8_alpha_char,
- .isupper_char = pm_encoding_utf_8_isupper_char,
- .multibyte = true
- },
- [PM_ENCODING_WINDOWS_1250] = {
- .name = "Windows-1250",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1250_alnum_char,
- .alpha_char = pm_encoding_windows_1250_alpha_char,
- .isupper_char = pm_encoding_windows_1250_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1251] = {
- .name = "Windows-1251",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1251_alnum_char,
- .alpha_char = pm_encoding_windows_1251_alpha_char,
- .isupper_char = pm_encoding_windows_1251_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1252] = {
- .name = "Windows-1252",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1252_alnum_char,
- .alpha_char = pm_encoding_windows_1252_alpha_char,
- .isupper_char = pm_encoding_windows_1252_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1253] = {
- .name = "Windows-1253",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1253_alnum_char,
- .alpha_char = pm_encoding_windows_1253_alpha_char,
- .isupper_char = pm_encoding_windows_1253_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1254] = {
- .name = "Windows-1254",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1254_alnum_char,
- .alpha_char = pm_encoding_windows_1254_alpha_char,
- .isupper_char = pm_encoding_windows_1254_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1255] = {
- .name = "Windows-1255",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1255_alnum_char,
- .alpha_char = pm_encoding_windows_1255_alpha_char,
- .isupper_char = pm_encoding_windows_1255_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1256] = {
- .name = "Windows-1256",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1256_alnum_char,
- .alpha_char = pm_encoding_windows_1256_alpha_char,
- .isupper_char = pm_encoding_windows_1256_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1257] = {
- .name = "Windows-1257",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1257_alnum_char,
- .alpha_char = pm_encoding_windows_1257_alpha_char,
- .isupper_char = pm_encoding_windows_1257_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_1258] = {
- .name = "Windows-1258",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_1258_alnum_char,
- .alpha_char = pm_encoding_windows_1258_alpha_char,
- .isupper_char = pm_encoding_windows_1258_isupper_char,
- .multibyte = false
- },
- [PM_ENCODING_WINDOWS_31J] = {
- .name = "Windows-31J",
- .char_width = pm_encoding_shift_jis_char_width,
- .alnum_char = pm_encoding_ascii_alnum_char_7bit,
- .alpha_char = pm_encoding_ascii_alpha_char_7bit,
- .isupper_char = pm_encoding_ascii_isupper_char_7bit,
- .multibyte = true
- },
- [PM_ENCODING_WINDOWS_874] = {
- .name = "Windows-874",
- .char_width = pm_encoding_single_char_width,
- .alnum_char = pm_encoding_windows_874_alnum_char,
- .alpha_char = pm_encoding_windows_874_alpha_char,
- .isupper_char = pm_encoding_windows_874_isupper_char,
- .multibyte = false
- }
-};
-
-/**
- * Parse the given name of an encoding and return a pointer to the corresponding
- * encoding struct if one can be found, otherwise return NULL.
- */
-const pm_encoding_t *
-pm_encoding_find(const uint8_t *start, const uint8_t *end) {
- size_t width = (size_t) (end - start);
-
- // First, we're going to check for UTF-8. This is the most common encoding.
- // UTF-8 can contain extra information at the end about the platform it is
- // encoded on, such as UTF-8-MAC or UTF-8-UNIX. We'll ignore those suffixes.
- if ((start + 5 <= end) && (pm_strncasecmp(start, (const uint8_t *) "UTF-8", 5) == 0)) {
- // We need to explicitly handle UTF-8-HFS, as that one needs to switch
- // over to being UTF8-MAC.
- if (width == 9 && (pm_strncasecmp(start + 5, (const uint8_t *) "-HFS", 4) == 0)) {
- return &pm_encodings[PM_ENCODING_UTF8_MAC];
- }
-
- // Otherwise we'll return the default UTF-8 encoding.
- return PM_ENCODING_UTF_8_ENTRY;
- }
-
- // Next, we're going to loop through each of the encodings that we handle
- // explicitly. If we found one that we understand, we'll use that value.
-#define ENCODING1(name, encoding) if (width == sizeof(name) - 1 && pm_strncasecmp(start, (const uint8_t *) name, width) == 0) return &pm_encodings[encoding];
-#define ENCODING2(name1, name2, encoding) ENCODING1(name1, encoding) ENCODING1(name2, encoding)
-
- if (width >= 3) {
- switch (*start) {
- case 'A': case 'a':
- ENCODING1("ASCII", PM_ENCODING_US_ASCII);
- ENCODING1("ASCII-8BIT", PM_ENCODING_ASCII_8BIT);
- ENCODING1("ANSI_X3.4-1968", PM_ENCODING_US_ASCII);
- break;
- case 'B': case 'b':
- ENCODING1("BINARY", PM_ENCODING_ASCII_8BIT);
- ENCODING1("Big5", PM_ENCODING_BIG5);
- ENCODING2("Big5-HKSCS", "Big5-HKSCS:2008", PM_ENCODING_BIG5_HKSCS);
- ENCODING1("Big5-UAO", PM_ENCODING_BIG5_UAO);
- break;
- case 'C': case 'c':
- ENCODING1("CESU-8", PM_ENCODING_CESU_8);
- ENCODING1("CP437", PM_ENCODING_IBM437);
- ENCODING1("CP720", PM_ENCODING_IBM720);
- ENCODING1("CP737", PM_ENCODING_IBM737);
- ENCODING1("CP775", PM_ENCODING_IBM775);
- ENCODING1("CP850", PM_ENCODING_CP850);
- ENCODING1("CP852", PM_ENCODING_CP852);
- ENCODING1("CP855", PM_ENCODING_CP855);
- ENCODING1("CP857", PM_ENCODING_IBM857);
- ENCODING1("CP860", PM_ENCODING_IBM860);
- ENCODING1("CP861", PM_ENCODING_IBM861);
- ENCODING1("CP862", PM_ENCODING_IBM862);
- ENCODING1("CP864", PM_ENCODING_IBM864);
- ENCODING1("CP865", PM_ENCODING_IBM865);
- ENCODING1("CP866", PM_ENCODING_IBM866);
- ENCODING1("CP869", PM_ENCODING_IBM869);
- ENCODING1("CP874", PM_ENCODING_WINDOWS_874);
- ENCODING1("CP878", PM_ENCODING_KOI8_R);
- ENCODING1("CP863", PM_ENCODING_IBM863);
- ENCODING2("CP932", "csWindows31J", PM_ENCODING_WINDOWS_31J);
- ENCODING1("CP936", PM_ENCODING_GBK);
- ENCODING1("CP949", PM_ENCODING_CP949);
- ENCODING1("CP950", PM_ENCODING_CP950);
- ENCODING1("CP951", PM_ENCODING_CP951);
- ENCODING1("CP1250", PM_ENCODING_WINDOWS_1250);
- ENCODING1("CP1251", PM_ENCODING_WINDOWS_1251);
- ENCODING1("CP1252", PM_ENCODING_WINDOWS_1252);
- ENCODING1("CP1253", PM_ENCODING_WINDOWS_1253);
- ENCODING1("CP1254", PM_ENCODING_WINDOWS_1254);
- ENCODING1("CP1255", PM_ENCODING_WINDOWS_1255);
- ENCODING1("CP1256", PM_ENCODING_WINDOWS_1256);
- ENCODING1("CP1257", PM_ENCODING_WINDOWS_1257);
- ENCODING1("CP1258", PM_ENCODING_WINDOWS_1258);
- ENCODING1("CP51932", PM_ENCODING_CP51932);
- ENCODING1("CP65001", PM_ENCODING_UTF_8);
- break;
- case 'E': case 'e':
- ENCODING2("EUC-JP", "eucJP", PM_ENCODING_EUC_JP);
- ENCODING2("eucJP-ms", "euc-jp-ms", PM_ENCODING_EUC_JP_MS);
- ENCODING2("EUC-JIS-2004", "EUC-JISX0213", PM_ENCODING_EUC_JIS_2004);
- ENCODING2("EUC-KR", "eucKR", PM_ENCODING_EUC_KR);
- ENCODING2("EUC-CN", "eucCN", PM_ENCODING_GB2312);
- ENCODING2("EUC-TW", "eucTW", PM_ENCODING_EUC_TW);
- ENCODING1("Emacs-Mule", PM_ENCODING_EMACS_MULE);
- ENCODING1("external", PM_ENCODING_UTF_8);
- break;
- case 'F': case 'f':
- ENCODING1("filesystem", PM_ENCODING_UTF_8);
- break;
- case 'G': case 'g':
- ENCODING1("GBK", PM_ENCODING_GBK);
- ENCODING1("GB12345", PM_ENCODING_GB12345);
- ENCODING1("GB18030", PM_ENCODING_GB18030);
- ENCODING1("GB1988", PM_ENCODING_GB1988);
- ENCODING1("GB2312", PM_ENCODING_GB2312);
- break;
- case 'I': case 'i':
- ENCODING1("IBM437", PM_ENCODING_IBM437);
- ENCODING1("IBM720", PM_ENCODING_IBM720);
- ENCODING1("IBM737", PM_ENCODING_IBM737);
- ENCODING1("IBM775", PM_ENCODING_IBM775);
- ENCODING1("IBM850", PM_ENCODING_CP850);
- ENCODING1("IBM852", PM_ENCODING_IBM852);
- ENCODING1("IBM855", PM_ENCODING_IBM855);
- ENCODING1("IBM857", PM_ENCODING_IBM857);
- ENCODING1("IBM860", PM_ENCODING_IBM860);
- ENCODING1("IBM861", PM_ENCODING_IBM861);
- ENCODING1("IBM862", PM_ENCODING_IBM862);
- ENCODING1("IBM863", PM_ENCODING_IBM863);
- ENCODING1("IBM864", PM_ENCODING_IBM864);
- ENCODING1("IBM865", PM_ENCODING_IBM865);
- ENCODING1("IBM866", PM_ENCODING_IBM866);
- ENCODING1("IBM869", PM_ENCODING_IBM869);
- ENCODING2("ISO-8859-1", "ISO8859-1", PM_ENCODING_ISO_8859_1);
- ENCODING2("ISO-8859-2", "ISO8859-2", PM_ENCODING_ISO_8859_2);
- ENCODING2("ISO-8859-3", "ISO8859-3", PM_ENCODING_ISO_8859_3);
- ENCODING2("ISO-8859-4", "ISO8859-4", PM_ENCODING_ISO_8859_4);
- ENCODING2("ISO-8859-5", "ISO8859-5", PM_ENCODING_ISO_8859_5);
- ENCODING2("ISO-8859-6", "ISO8859-6", PM_ENCODING_ISO_8859_6);
- ENCODING2("ISO-8859-7", "ISO8859-7", PM_ENCODING_ISO_8859_7);
- ENCODING2("ISO-8859-8", "ISO8859-8", PM_ENCODING_ISO_8859_8);
- ENCODING2("ISO-8859-9", "ISO8859-9", PM_ENCODING_ISO_8859_9);
- ENCODING2("ISO-8859-10", "ISO8859-10", PM_ENCODING_ISO_8859_10);
- ENCODING2("ISO-8859-11", "ISO8859-11", PM_ENCODING_ISO_8859_11);
- ENCODING2("ISO-8859-13", "ISO8859-13", PM_ENCODING_ISO_8859_13);
- ENCODING2("ISO-8859-14", "ISO8859-14", PM_ENCODING_ISO_8859_14);
- ENCODING2("ISO-8859-15", "ISO8859-15", PM_ENCODING_ISO_8859_15);
- ENCODING2("ISO-8859-16", "ISO8859-16", PM_ENCODING_ISO_8859_16);
- break;
- case 'K': case 'k':
- ENCODING1("KOI8-R", PM_ENCODING_KOI8_R);
- ENCODING1("KOI8-U", PM_ENCODING_KOI8_U);
- break;
- case 'L': case 'l':
- ENCODING1("locale", PM_ENCODING_UTF_8);
- break;
- case 'M': case 'm':
- ENCODING1("macCentEuro", PM_ENCODING_MAC_CENT_EURO);
- ENCODING1("macCroatian", PM_ENCODING_MAC_CROATIAN);
- ENCODING1("macCyrillic", PM_ENCODING_MAC_CYRILLIC);
- ENCODING1("macGreek", PM_ENCODING_MAC_GREEK);
- ENCODING1("macIceland", PM_ENCODING_MAC_ICELAND);
- ENCODING1("MacJapanese", PM_ENCODING_MAC_JAPANESE);
- ENCODING1("MacJapan", PM_ENCODING_MAC_JAPANESE);
- ENCODING1("macRoman", PM_ENCODING_MAC_ROMAN);
- ENCODING1("macRomania", PM_ENCODING_MAC_ROMANIA);
- ENCODING1("macThai", PM_ENCODING_MAC_THAI);
- ENCODING1("macTurkish", PM_ENCODING_MAC_TURKISH);
- ENCODING1("macUkraine", PM_ENCODING_MAC_UKRAINE);
- break;
- case 'P': case 'p':
- ENCODING1("PCK", PM_ENCODING_WINDOWS_31J);
- break;
- case 'S': case 's':
- ENCODING1("Shift_JIS", PM_ENCODING_SHIFT_JIS);
- ENCODING1("SJIS", PM_ENCODING_WINDOWS_31J);
- ENCODING1("SJIS-DoCoMo", PM_ENCODING_SJIS_DOCOMO);
- ENCODING1("SJIS-KDDI", PM_ENCODING_SJIS_KDDI);
- ENCODING1("SJIS-SoftBank", PM_ENCODING_SJIS_SOFTBANK);
- ENCODING1("stateless-ISO-2022-JP", PM_ENCODING_STATELESS_ISO_2022_JP);
- ENCODING1("stateless-ISO-2022-JP-KDDI", PM_ENCODING_STATELESS_ISO_2022_JP_KDDI);
- break;
- case 'T': case 't':
- ENCODING1("TIS-620", PM_ENCODING_TIS_620);
- break;
- case 'U': case 'u':
- ENCODING1("US-ASCII", PM_ENCODING_US_ASCII);
- ENCODING2("UTF8-MAC", "UTF-8-HFS", PM_ENCODING_UTF8_MAC);
- ENCODING1("UTF8-DoCoMo", PM_ENCODING_UTF8_DOCOMO);
- ENCODING1("UTF8-KDDI", PM_ENCODING_UTF8_KDDI);
- ENCODING1("UTF8-SoftBank", PM_ENCODING_UTF8_SOFTBANK);
- break;
- case 'W': case 'w':
- ENCODING1("Windows-31J", PM_ENCODING_WINDOWS_31J);
- ENCODING1("Windows-874", PM_ENCODING_WINDOWS_874);
- ENCODING1("Windows-1250", PM_ENCODING_WINDOWS_1250);
- ENCODING1("Windows-1251", PM_ENCODING_WINDOWS_1251);
- ENCODING1("Windows-1252", PM_ENCODING_WINDOWS_1252);
- ENCODING1("Windows-1253", PM_ENCODING_WINDOWS_1253);
- ENCODING1("Windows-1254", PM_ENCODING_WINDOWS_1254);
- ENCODING1("Windows-1255", PM_ENCODING_WINDOWS_1255);
- ENCODING1("Windows-1256", PM_ENCODING_WINDOWS_1256);
- ENCODING1("Windows-1257", PM_ENCODING_WINDOWS_1257);
- ENCODING1("Windows-1258", PM_ENCODING_WINDOWS_1258);
- break;
- case '6':
- ENCODING1("646", PM_ENCODING_US_ASCII);
- break;
- }
- }
-
-#undef ENCODING2
-#undef ENCODING1
-
- // If we didn't match any encodings, return NULL.
- return NULL;
-}
diff --git a/prism/encoding.h b/prism/encoding.h
deleted file mode 100644
index 8fe01aea69..0000000000
--- a/prism/encoding.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * @file encoding.h
- *
- * The encoding interface and implementations used by the parser.
- */
-#ifndef PRISM_ENCODING_H
-#define PRISM_ENCODING_H
-
-#include "prism/defines.h"
-#include "prism/util/pm_strncasecmp.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * This struct defines the functions necessary to implement the encoding
- * interface so we can determine how many bytes the subsequent character takes.
- * Each callback should return the number of bytes, or 0 if the next bytes are
- * invalid for the encoding and type.
- */
-typedef struct {
- /**
- * Return the number of bytes that the next character takes if it is valid
- * in the encoding. Does not read more than n bytes. It is assumed that n is
- * at least 1.
- */
- size_t (*char_width)(const uint8_t *b, ptrdiff_t n);
-
- /**
- * Return the number of bytes that the next character takes if it is valid
- * in the encoding and is alphabetical. Does not read more than n bytes. It
- * is assumed that n is at least 1.
- */
- size_t (*alpha_char)(const uint8_t *b, ptrdiff_t n);
-
- /**
- * Return the number of bytes that the next character takes if it is valid
- * in the encoding and is alphanumeric. Does not read more than n bytes. It
- * is assumed that n is at least 1.
- */
- size_t (*alnum_char)(const uint8_t *b, ptrdiff_t n);
-
- /**
- * Return true if the next character is valid in the encoding and is an
- * uppercase character. Does not read more than n bytes. It is assumed that
- * n is at least 1.
- */
- bool (*isupper_char)(const uint8_t *b, ptrdiff_t n);
-
- /**
- * The name of the encoding. This should correspond to a value that can be
- * passed to Encoding.find in Ruby.
- */
- const char *name;
-
- /**
- * Return true if the encoding is a multibyte encoding.
- */
- bool multibyte;
-} pm_encoding_t;
-
-/**
- * All of the lookup tables use the first bit of each embedded byte to indicate
- * whether the codepoint is alphabetical.
- */
-#define PRISM_ENCODING_ALPHABETIC_BIT 1 << 0
-
-/**
- * All of the lookup tables use the second bit of each embedded byte to indicate
- * whether the codepoint is alphanumeric.
- */
-#define PRISM_ENCODING_ALPHANUMERIC_BIT 1 << 1
-
-/**
- * All of the lookup tables use the third bit of each embedded byte to indicate
- * whether the codepoint is uppercase.
- */
-#define PRISM_ENCODING_UPPERCASE_BIT 1 << 2
-
-/**
- * Return the size of the next character in the UTF-8 encoding if it is an
- * alphabetical character.
- *
- * @param b The bytes to read.
- * @param n The number of bytes that can be read.
- * @returns The number of bytes that the next character takes if it is valid in
- * the encoding, or 0 if it is not.
- */
-size_t pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n);
-
-/**
- * Return the size of the next character in the UTF-8 encoding if it is an
- * alphanumeric character.
- *
- * @param b The bytes to read.
- * @param n The number of bytes that can be read.
- * @returns The number of bytes that the next character takes if it is valid in
- * the encoding, or 0 if it is not.
- */
-size_t pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n);
-
-/**
- * Return true if the next character in the UTF-8 encoding if it is an uppercase
- * character.
- *
- * @param b The bytes to read.
- * @param n The number of bytes that can be read.
- * @returns True if the next character is valid in the encoding and is an
- * uppercase character, or false if it is not.
- */
-bool pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n);
-
-/**
- * This lookup table is referenced in both the UTF-8 encoding file and the
- * parser directly in order to speed up the default encoding processing. It is
- * used to indicate whether a character is alphabetical, alphanumeric, or
- * uppercase in unicode mappings.
- */
-extern const uint8_t pm_encoding_unicode_table[256];
-
-/**
- * These are all of the encodings that prism supports.
- */
-typedef enum {
- PM_ENCODING_UTF_8 = 0,
- PM_ENCODING_ASCII_8BIT,
- PM_ENCODING_BIG5,
- PM_ENCODING_BIG5_HKSCS,
- PM_ENCODING_BIG5_UAO,
- PM_ENCODING_CESU_8,
- PM_ENCODING_CP51932,
- PM_ENCODING_CP850,
- PM_ENCODING_CP852,
- PM_ENCODING_CP855,
- PM_ENCODING_CP949,
- PM_ENCODING_CP950,
- PM_ENCODING_CP951,
- PM_ENCODING_EMACS_MULE,
- PM_ENCODING_EUC_JP,
- PM_ENCODING_EUC_JP_MS,
- PM_ENCODING_EUC_JIS_2004,
- PM_ENCODING_EUC_KR,
- PM_ENCODING_EUC_TW,
- PM_ENCODING_GB12345,
- PM_ENCODING_GB18030,
- PM_ENCODING_GB1988,
- PM_ENCODING_GB2312,
- PM_ENCODING_GBK,
- PM_ENCODING_IBM437,
- PM_ENCODING_IBM720,
- PM_ENCODING_IBM737,
- PM_ENCODING_IBM775,
- PM_ENCODING_IBM852,
- PM_ENCODING_IBM855,
- PM_ENCODING_IBM857,
- PM_ENCODING_IBM860,
- PM_ENCODING_IBM861,
- PM_ENCODING_IBM862,
- PM_ENCODING_IBM863,
- PM_ENCODING_IBM864,
- PM_ENCODING_IBM865,
- PM_ENCODING_IBM866,
- PM_ENCODING_IBM869,
- PM_ENCODING_ISO_8859_1,
- PM_ENCODING_ISO_8859_2,
- PM_ENCODING_ISO_8859_3,
- PM_ENCODING_ISO_8859_4,
- PM_ENCODING_ISO_8859_5,
- PM_ENCODING_ISO_8859_6,
- PM_ENCODING_ISO_8859_7,
- PM_ENCODING_ISO_8859_8,
- PM_ENCODING_ISO_8859_9,
- PM_ENCODING_ISO_8859_10,
- PM_ENCODING_ISO_8859_11,
- PM_ENCODING_ISO_8859_13,
- PM_ENCODING_ISO_8859_14,
- PM_ENCODING_ISO_8859_15,
- PM_ENCODING_ISO_8859_16,
- PM_ENCODING_KOI8_R,
- PM_ENCODING_KOI8_U,
- PM_ENCODING_MAC_CENT_EURO,
- PM_ENCODING_MAC_CROATIAN,
- PM_ENCODING_MAC_CYRILLIC,
- PM_ENCODING_MAC_GREEK,
- PM_ENCODING_MAC_ICELAND,
- PM_ENCODING_MAC_JAPANESE,
- PM_ENCODING_MAC_ROMAN,
- PM_ENCODING_MAC_ROMANIA,
- PM_ENCODING_MAC_THAI,
- PM_ENCODING_MAC_TURKISH,
- PM_ENCODING_MAC_UKRAINE,
- PM_ENCODING_SHIFT_JIS,
- PM_ENCODING_SJIS_DOCOMO,
- PM_ENCODING_SJIS_KDDI,
- PM_ENCODING_SJIS_SOFTBANK,
- PM_ENCODING_STATELESS_ISO_2022_JP,
- PM_ENCODING_STATELESS_ISO_2022_JP_KDDI,
- PM_ENCODING_TIS_620,
- PM_ENCODING_US_ASCII,
- PM_ENCODING_UTF8_MAC,
- PM_ENCODING_UTF8_DOCOMO,
- PM_ENCODING_UTF8_KDDI,
- PM_ENCODING_UTF8_SOFTBANK,
- PM_ENCODING_WINDOWS_1250,
- PM_ENCODING_WINDOWS_1251,
- PM_ENCODING_WINDOWS_1252,
- PM_ENCODING_WINDOWS_1253,
- PM_ENCODING_WINDOWS_1254,
- PM_ENCODING_WINDOWS_1255,
- PM_ENCODING_WINDOWS_1256,
- PM_ENCODING_WINDOWS_1257,
- PM_ENCODING_WINDOWS_1258,
- PM_ENCODING_WINDOWS_31J,
- PM_ENCODING_WINDOWS_874,
- PM_ENCODING_MAXIMUM
-} pm_encoding_type_t;
-
-/**
- * This is the table of all of the encodings that prism supports.
- */
-extern const pm_encoding_t pm_encodings[PM_ENCODING_MAXIMUM];
-
-/**
- * This is the default UTF-8 encoding. We need a reference to it to quickly
- * create parsers.
- */
-#define PM_ENCODING_UTF_8_ENTRY (&pm_encodings[PM_ENCODING_UTF_8])
-
-/**
- * This is the US-ASCII encoding. We need a reference to it to be able to
- * compare against it when a string is being created because it could possibly
- * need to fall back to ASCII-8BIT.
- */
-#define PM_ENCODING_US_ASCII_ENTRY (&pm_encodings[PM_ENCODING_US_ASCII])
-
-/**
- * Parse the given name of an encoding and return a pointer to the corresponding
- * encoding struct if one can be found, otherwise return NULL.
- *
- * @param start A pointer to the first byte of the name.
- * @param end A pointer to the last byte of the name.
- * @returns A pointer to the encoding struct if one is found, otherwise NULL.
- */
-const pm_encoding_t * pm_encoding_find(const uint8_t *start, const uint8_t *end);
-
-#endif
diff --git a/prism/extension.c b/prism/extension.c
deleted file mode 100644
index 6cf007b4df..0000000000
--- a/prism/extension.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-#include "prism/extension.h"
-
-// NOTE: this file should contain only bindings. All non-trivial logic should be
-// in libprism so it can be shared its the various callers.
-
-VALUE rb_cPrism;
-VALUE rb_cPrismNode;
-VALUE rb_cPrismSource;
-VALUE rb_cPrismToken;
-VALUE rb_cPrismLocation;
-
-VALUE rb_cPrismComment;
-VALUE rb_cPrismInlineComment;
-VALUE rb_cPrismEmbDocComment;
-VALUE rb_cPrismMagicComment;
-VALUE rb_cPrismParseError;
-VALUE rb_cPrismParseWarning;
-VALUE rb_cPrismParseResult;
-
-ID rb_option_id_filepath;
-ID rb_option_id_encoding;
-ID rb_option_id_line;
-ID rb_option_id_frozen_string_literal;
-ID rb_option_id_verbose;
-ID rb_option_id_scopes;
-
-/******************************************************************************/
-/* IO of Ruby code */
-/******************************************************************************/
-
-/**
- * Check if the given VALUE is a string. If it's nil, then return NULL. If it's
- * not a string, then raise a type error. Otherwise return the VALUE as a C
- * string.
- */
-static const char *
-check_string(VALUE value) {
- // If the value is nil, then we don't need to do anything.
- if (NIL_P(value)) {
- return NULL;
- }
-
- // Check if the value is a string. If it's not, then raise a type error.
- if (!RB_TYPE_P(value, T_STRING)) {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(value));
- }
-
- // Otherwise, return the value as a C string.
- return RSTRING_PTR(value);
-}
-
-/**
- * Load the contents and size of the given string into the given pm_string_t.
- */
-static void
-input_load_string(pm_string_t *input, VALUE string) {
- // Check if the string is a string. If it's not, then raise a type error.
- if (!RB_TYPE_P(string, T_STRING)) {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(string));
- }
-
- pm_string_constant_init(input, RSTRING_PTR(string), RSTRING_LEN(string));
-}
-
-/******************************************************************************/
-/* Building C options from Ruby options */
-/******************************************************************************/
-
-/**
- * Build the scopes associated with the provided Ruby keyword value.
- */
-static void
-build_options_scopes(pm_options_t *options, VALUE scopes) {
- // Check if the value is an array. If it's not, then raise a type error.
- if (!RB_TYPE_P(scopes, T_ARRAY)) {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(scopes));
- }
-
- // Initialize the scopes array.
- size_t scopes_count = RARRAY_LEN(scopes);
- pm_options_scopes_init(options, scopes_count);
-
- // Iterate over the scopes and add them to the options.
- for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) {
- VALUE scope = rb_ary_entry(scopes, scope_index);
-
- // Check that the scope is an array. If it's not, then raise a type
- // error.
- if (!RB_TYPE_P(scope, T_ARRAY)) {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(scope));
- }
-
- // Initialize the scope array.
- size_t locals_count = RARRAY_LEN(scope);
- pm_options_scope_t *options_scope = &options->scopes[scope_index];
- pm_options_scope_init(options_scope, locals_count);
-
- // Iterate over the locals and add them to the scope.
- for (size_t local_index = 0; local_index < locals_count; local_index++) {
- VALUE local = rb_ary_entry(scope, local_index);
-
- // Check that the local is a symbol. If it's not, then raise a
- // type error.
- if (!RB_TYPE_P(local, T_SYMBOL)) {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Symbol)", rb_obj_class(local));
- }
-
- // Add the local to the scope.
- pm_string_t *scope_local = &options_scope->locals[local_index];
- const char *name = rb_id2name(SYM2ID(local));
- pm_string_constant_init(scope_local, name, strlen(name));
- }
- }
-}
-
-/**
- * An iterator function that is called for each key-value in the keywords hash.
- */
-static int
-build_options_i(VALUE key, VALUE value, VALUE argument) {
- pm_options_t *options = (pm_options_t *) argument;
- ID key_id = SYM2ID(key);
-
- if (key_id == rb_option_id_filepath) {
- if (!NIL_P(value)) pm_options_filepath_set(options, check_string(value));
- } else if (key_id == rb_option_id_encoding) {
- if (!NIL_P(value)) pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value)));
- } else if (key_id == rb_option_id_line) {
- if (!NIL_P(value)) pm_options_line_set(options, NUM2INT(value));
- } else if (key_id == rb_option_id_frozen_string_literal) {
- if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, value == Qtrue);
- } else if (key_id == rb_option_id_verbose) {
- pm_options_suppress_warnings_set(options, value != Qtrue);
- } else if (key_id == rb_option_id_scopes) {
- if (!NIL_P(value)) build_options_scopes(options, value);
- } else {
- rb_raise(rb_eArgError, "unknown keyword: %"PRIsVALUE, key);
- }
-
- return ST_CONTINUE;
-}
-
-/**
- * We need a struct here to pass through rb_protect and it has to be a single
- * value. Because the sizeof(VALUE) == sizeof(void *), we're going to pass this
- * through as an opaque pointer and cast it on both sides.
- */
-struct build_options_data {
- pm_options_t *options;
- VALUE keywords;
-};
-
-/**
- * Build the set of options from the given keywords. Note that this can raise a
- * Ruby error if the options are not valid.
- */
-static VALUE
-build_options(VALUE argument) {
- struct build_options_data *data = (struct build_options_data *) argument;
- rb_hash_foreach(data->keywords, build_options_i, (VALUE) data->options);
- return Qnil;
-}
-
-/**
- * Extract the options from the given keyword arguments.
- */
-static void
-extract_options(pm_options_t *options, VALUE filepath, VALUE keywords) {
- options->line = 1; // default
- if (!NIL_P(keywords)) {
- struct build_options_data data = { .options = options, .keywords = keywords };
- struct build_options_data *argument = &data;
-
- int state = 0;
- rb_protect(build_options, (VALUE) argument, &state);
-
- if (state != 0) {
- pm_options_free(options);
- rb_jump_tag(state);
- }
- }
-
- if (!NIL_P(filepath)) {
- if (!RB_TYPE_P(filepath, T_STRING)) {
- pm_options_free(options);
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(filepath));
- }
-
- pm_options_filepath_set(options, RSTRING_PTR(filepath));
- }
-}
-
-/**
- * Read options for methods that look like (source, **options).
- */
-static void
-string_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options) {
- VALUE string;
- VALUE keywords;
- rb_scan_args(argc, argv, "1:", &string, &keywords);
-
- extract_options(options, Qnil, keywords);
- input_load_string(input, string);
-}
-
-/**
- * Read options for methods that look like (filepath, **options).
- */
-static bool
-file_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options) {
- VALUE filepath;
- VALUE keywords;
- rb_scan_args(argc, argv, "1:", &filepath, &keywords);
-
- extract_options(options, filepath, keywords);
-
- if (!pm_string_mapped_init(input, (const char *) pm_string_source(&options->filepath))) {
- pm_options_free(options);
- return false;
- }
-
- return true;
-}
-
-/******************************************************************************/
-/* Serializing the AST */
-/******************************************************************************/
-
-/**
- * Dump the AST corresponding to the given input to a string.
- */
-static VALUE
-dump_input(pm_string_t *input, const pm_options_t *options) {
- pm_buffer_t buffer;
- if (!pm_buffer_init(&buffer)) {
- rb_raise(rb_eNoMemError, "failed to allocate memory");
- }
-
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
-
- pm_node_t *node = pm_parse(&parser);
- pm_serialize(&parser, node, &buffer);
-
- VALUE result = rb_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer));
- pm_node_destroy(&parser, node);
- pm_buffer_free(&buffer);
- pm_parser_free(&parser);
-
- return result;
-}
-
-/**
- * call-seq:
- * Prism::dump(source, **options) -> String
- *
- * Dump the AST corresponding to the given string to a string. For supported
- * options, see Prism::parse.
- */
-static VALUE
-dump(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- string_options(argc, argv, &input, &options);
-
-#ifdef PRISM_DEBUG_MODE_BUILD
- size_t length = pm_string_length(&input);
- char* dup = malloc(length);
- memcpy(dup, pm_string_source(&input), length);
- pm_string_constant_init(&input, dup, length);
-#endif
-
- VALUE value = dump_input(&input, &options);
-
-#ifdef PRISM_DEBUG_MODE_BUILD
- free(dup);
-#endif
-
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/**
- * call-seq:
- * Prism::dump_file(filepath, **options) -> String
- *
- * Dump the AST corresponding to the given file to a string. For supported
- * options, see Prism::parse.
- */
-static VALUE
-dump_file(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- if (!file_options(argc, argv, &input, &options)) return Qnil;
-
- VALUE value = dump_input(&input, &options);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/******************************************************************************/
-/* Extracting values for the parse result */
-/******************************************************************************/
-
-/**
- * Extract the comments out of the parser into an array.
- */
-static VALUE
-parser_comments(pm_parser_t *parser, VALUE source) {
- VALUE comments = rb_ary_new();
-
- for (pm_comment_t *comment = (pm_comment_t *) parser->comment_list.head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
- VALUE location_argv[] = {
- source,
- LONG2FIX(comment->location.start - parser->start),
- LONG2FIX(comment->location.end - comment->location.start)
- };
-
- VALUE type = (comment->type == PM_COMMENT_EMBDOC) ? rb_cPrismEmbDocComment : rb_cPrismInlineComment;
- VALUE comment_argv[] = { rb_class_new_instance(3, location_argv, rb_cPrismLocation) };
- rb_ary_push(comments, rb_class_new_instance(1, comment_argv, type));
- }
-
- return comments;
-}
-
-/**
- * Extract the magic comments out of the parser into an array.
- */
-static VALUE
-parser_magic_comments(pm_parser_t *parser, VALUE source) {
- VALUE magic_comments = rb_ary_new();
-
- for (pm_magic_comment_t *magic_comment = (pm_magic_comment_t *) parser->magic_comment_list.head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
- VALUE key_loc_argv[] = {
- source,
- LONG2FIX(magic_comment->key_start - parser->start),
- LONG2FIX(magic_comment->key_length)
- };
-
- VALUE value_loc_argv[] = {
- source,
- LONG2FIX(magic_comment->value_start - parser->start),
- LONG2FIX(magic_comment->value_length)
- };
-
- VALUE magic_comment_argv[] = {
- rb_class_new_instance(3, key_loc_argv, rb_cPrismLocation),
- rb_class_new_instance(3, value_loc_argv, rb_cPrismLocation)
- };
-
- rb_ary_push(magic_comments, rb_class_new_instance(2, magic_comment_argv, rb_cPrismMagicComment));
- }
-
- return magic_comments;
-}
-
-/**
- * Extract out the data location from the parser into a Location instance if one
- * exists.
- */
-static VALUE
-parser_data_loc(const pm_parser_t *parser, VALUE source) {
- if (parser->data_loc.end == NULL) {
- return Qnil;
- } else {
- VALUE argv[] = {
- source,
- LONG2FIX(parser->data_loc.start - parser->start),
- LONG2FIX(parser->data_loc.end - parser->data_loc.start)
- };
-
- return rb_class_new_instance(3, argv, rb_cPrismLocation);
- }
-}
-
-/**
- * Extract the errors out of the parser into an array.
- */
-static VALUE
-parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
- VALUE errors = rb_ary_new();
- pm_diagnostic_t *error;
-
- for (error = (pm_diagnostic_t *) parser->error_list.head; error != NULL; error = (pm_diagnostic_t *) error->node.next) {
- VALUE location_argv[] = {
- source,
- LONG2FIX(error->location.start - parser->start),
- LONG2FIX(error->location.end - error->location.start)
- };
-
- VALUE error_argv[] = {
- rb_enc_str_new_cstr(error->message, encoding),
- rb_class_new_instance(3, location_argv, rb_cPrismLocation)
- };
-
- rb_ary_push(errors, rb_class_new_instance(2, error_argv, rb_cPrismParseError));
- }
-
- return errors;
-}
-
-/**
- * Extract the warnings out of the parser into an array.
- */
-static VALUE
-parser_warnings(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
- VALUE warnings = rb_ary_new();
- pm_diagnostic_t *warning;
-
- for (warning = (pm_diagnostic_t *) parser->warning_list.head; warning != NULL; warning = (pm_diagnostic_t *) warning->node.next) {
- VALUE location_argv[] = {
- source,
- LONG2FIX(warning->location.start - parser->start),
- LONG2FIX(warning->location.end - warning->location.start)
- };
-
- VALUE warning_argv[] = {
- rb_enc_str_new_cstr(warning->message, encoding),
- rb_class_new_instance(3, location_argv, rb_cPrismLocation)
- };
-
- rb_ary_push(warnings, rb_class_new_instance(2, warning_argv, rb_cPrismParseWarning));
- }
-
- return warnings;
-}
-
-/******************************************************************************/
-/* Lexing Ruby code */
-/******************************************************************************/
-
-/**
- * This struct gets stored in the parser and passed in to the lex callback any
- * time a new token is found. We use it to store the necessary information to
- * initialize a Token instance.
- */
-typedef struct {
- VALUE source;
- VALUE tokens;
- rb_encoding *encoding;
-} parse_lex_data_t;
-
-/**
- * This is passed as a callback to the parser. It gets called every time a new
- * token is found. Once found, we initialize a new instance of Token and push it
- * onto the tokens array.
- */
-static void
-parse_lex_token(void *data, pm_parser_t *parser, pm_token_t *token) {
- parse_lex_data_t *parse_lex_data = (parse_lex_data_t *) parser->lex_callback->data;
-
- VALUE yields = rb_ary_new_capa(2);
- rb_ary_push(yields, pm_token_new(parser, token, parse_lex_data->encoding, parse_lex_data->source));
- rb_ary_push(yields, INT2FIX(parser->lex_state));
-
- rb_ary_push(parse_lex_data->tokens, yields);
-}
-
-/**
- * This is called whenever the encoding changes based on the magic comment at
- * the top of the file. We use it to update the encoding that we are using to
- * create tokens.
- */
-static void
-parse_lex_encoding_changed_callback(pm_parser_t *parser) {
- parse_lex_data_t *parse_lex_data = (parse_lex_data_t *) parser->lex_callback->data;
- parse_lex_data->encoding = rb_enc_find(parser->encoding->name);
-
- // Since the encoding changed, we need to go back and change the encoding of
- // the tokens that were already lexed. This is only going to end up being
- // one or two tokens, since the encoding can only change at the top of the
- // file.
- VALUE tokens = parse_lex_data->tokens;
- for (long index = 0; index < RARRAY_LEN(tokens); index++) {
- VALUE yields = rb_ary_entry(tokens, index);
- VALUE token = rb_ary_entry(yields, 0);
-
- VALUE value = rb_ivar_get(token, rb_intern("@value"));
- rb_enc_associate(value, parse_lex_data->encoding);
- ENC_CODERANGE_CLEAR(value);
- }
-}
-
-/**
- * Parse the given input and return a ParseResult containing just the tokens or
- * the nodes and tokens.
- */
-static VALUE
-parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nodes) {
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
- pm_parser_register_encoding_changed_callback(&parser, parse_lex_encoding_changed_callback);
-
- VALUE offsets = rb_ary_new();
- VALUE source_argv[] = { rb_str_new((const char *) pm_string_source(input), pm_string_length(input)), ULONG2NUM(parser.start_line), offsets };
- VALUE source = rb_class_new_instance(3, source_argv, rb_cPrismSource);
-
- parse_lex_data_t parse_lex_data = {
- .source = source,
- .tokens = rb_ary_new(),
- .encoding = rb_utf8_encoding()
- };
-
- parse_lex_data_t *data = &parse_lex_data;
- pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
- .data = (void *) data,
- .callback = parse_lex_token,
- };
-
- parser.lex_callback = &lex_callback;
- pm_node_t *node = pm_parse(&parser);
-
- // Here we need to update the source range to have the correct newline
- // offsets. We do it here because we've already created the object and given
- // it over to all of the tokens.
- for (size_t index = 0; index < parser.newline_list.size; index++) {
- rb_ary_push(offsets, INT2FIX(parser.newline_list.offsets[index]));
- }
-
- VALUE value;
- if (return_nodes) {
- value = rb_ary_new_capa(2);
- rb_ary_push(value, pm_ast_new(&parser, node, parse_lex_data.encoding));
- rb_ary_push(value, parse_lex_data.tokens);
- } else {
- value = parse_lex_data.tokens;
- }
-
- VALUE result_argv[] = {
- value,
- parser_comments(&parser, source),
- parser_magic_comments(&parser, source),
- parser_data_loc(&parser, source),
- parser_errors(&parser, parse_lex_data.encoding, source),
- parser_warnings(&parser, parse_lex_data.encoding, source),
- source
- };
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
- return rb_class_new_instance(7, result_argv, rb_cPrismParseResult);
-}
-
-/**
- * call-seq:
- * Prism::lex(source, **options) -> Array
- *
- * Return an array of Token instances corresponding to the given string. For
- * supported options, see Prism::parse.
- */
-static VALUE
-lex(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- string_options(argc, argv, &input, &options);
-
- VALUE result = parse_lex_input(&input, &options, false);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return result;
-}
-
-/**
- * call-seq:
- * Prism::lex_file(filepath, **options) -> Array
- *
- * Return an array of Token instances corresponding to the given file. For
- * supported options, see Prism::parse.
- */
-static VALUE
-lex_file(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- if (!file_options(argc, argv, &input, &options)) return Qnil;
-
- VALUE value = parse_lex_input(&input, &options, false);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/******************************************************************************/
-/* Parsing Ruby code */
-/******************************************************************************/
-
-/**
- * Parse the given input and return a ParseResult instance.
- */
-static VALUE
-parse_input(pm_string_t *input, const pm_options_t *options) {
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
-
- pm_node_t *node = pm_parse(&parser);
- rb_encoding *encoding = rb_enc_find(parser.encoding->name);
-
- VALUE source = pm_source_new(&parser, encoding);
- VALUE result_argv[] = {
- pm_ast_new(&parser, node, encoding),
- parser_comments(&parser, source),
- parser_magic_comments(&parser, source),
- parser_data_loc(&parser, source),
- parser_errors(&parser, encoding, source),
- parser_warnings(&parser, encoding, source),
- source
- };
-
- VALUE result = rb_class_new_instance(7, result_argv, rb_cPrismParseResult);
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
-
- return result;
-}
-
-/**
- * call-seq:
- * Prism::parse(source, **options) -> ParseResult
- *
- * Parse the given string and return a ParseResult instance. The options that
- * are supported are:
- *
- * * `filepath` - the filepath of the source being parsed. This should be a
- * string or nil
- * * `encoding` - the encoding of the source being parsed. This should be an
- * encoding or nil
- * * `line` - the line number that the parse starts on. This should be an
- * integer or nil. Note that this is 1-indexed.
- * * `frozen_string_literal` - whether or not the frozen string literal pragma
- * has been set. This should be a boolean or nil.
- * * `verbose` - the current level of verbosity. This controls whether or not
- * the parser emits warnings. This should be a boolean or nil.
- * * `scopes` - the locals that are in scope surrounding the code that is being
- * parsed. This should be an array of arrays of symbols or nil.
- */
-static VALUE
-parse(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- string_options(argc, argv, &input, &options);
-
-#ifdef PRISM_DEBUG_MODE_BUILD
- size_t length = pm_string_length(&input);
- char* dup = malloc(length);
- memcpy(dup, pm_string_source(&input), length);
- pm_string_constant_init(&input, dup, length);
-#endif
-
- VALUE value = parse_input(&input, &options);
-
-#ifdef PRISM_DEBUG_MODE_BUILD
- free(dup);
-#endif
-
- pm_string_free(&input);
- pm_options_free(&options);
- return value;
-}
-
-/**
- * call-seq:
- * Prism::parse_file(filepath, **options) -> ParseResult
- *
- * Parse the given file and return a ParseResult instance. For supported
- * options, see Prism::parse.
- */
-static VALUE
-parse_file(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- if (!file_options(argc, argv, &input, &options)) return Qnil;
-
- VALUE value = parse_input(&input, &options);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/**
- * Parse the given input and return an array of Comment objects.
- */
-static VALUE
-parse_input_comments(pm_string_t *input, const pm_options_t *options) {
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
-
- pm_node_t *node = pm_parse(&parser);
- rb_encoding *encoding = rb_enc_find(parser.encoding->name);
-
- VALUE source = pm_source_new(&parser, encoding);
- VALUE comments = parser_comments(&parser, source);
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
-
- return comments;
-}
-
-/**
- * call-seq:
- * Prism::parse_comments(source, **options) -> Array
- *
- * Parse the given string and return an array of Comment objects. For supported
- * options, see Prism::parse.
- */
-static VALUE
-parse_comments(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- string_options(argc, argv, &input, &options);
-
- VALUE result = parse_input_comments(&input, &options);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return result;
-}
-
-/**
- * call-seq:
- * Prism::parse_file_comments(filepath, **options) -> Array
- *
- * Parse the given file and return an array of Comment objects. For supported
- * options, see Prism::parse.
- */
-static VALUE
-parse_file_comments(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- if (!file_options(argc, argv, &input, &options)) return Qnil;
-
- VALUE value = parse_input_comments(&input, &options);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/**
- * call-seq:
- * Prism::parse_lex(source, **options) -> ParseResult
- *
- * Parse the given string and return a ParseResult instance that contains a
- * 2-element array, where the first element is the AST and the second element is
- * an array of Token instances.
- *
- * This API is only meant to be used in the case where you need both the AST and
- * the tokens. If you only need one or the other, use either Prism::parse or
- * Prism::lex.
- *
- * For supported options, see Prism::parse.
- */
-static VALUE
-parse_lex(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- string_options(argc, argv, &input, &options);
-
- VALUE value = parse_lex_input(&input, &options, true);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/**
- * call-seq:
- * Prism::parse_lex_file(filepath, **options) -> ParseResult
- *
- * Parse the given file and return a ParseResult instance that contains a
- * 2-element array, where the first element is the AST and the second element is
- * an array of Token instances.
- *
- * This API is only meant to be used in the case where you need both the AST and
- * the tokens. If you only need one or the other, use either Prism::parse_file
- * or Prism::lex_file.
- *
- * For supported options, see Prism::parse.
- */
-static VALUE
-parse_lex_file(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- if (!file_options(argc, argv, &input, &options)) return Qnil;
-
- VALUE value = parse_lex_input(&input, &options, true);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return value;
-}
-
-/**
- * Parse the given input and return true if it parses without errors.
- */
-static VALUE
-parse_input_success_p(pm_string_t *input, const pm_options_t *options) {
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
-
- pm_node_t *node = pm_parse(&parser);
- pm_node_destroy(&parser, node);
-
- VALUE result = parser.error_list.size == 0 ? Qtrue : Qfalse;
- pm_parser_free(&parser);
-
- return result;
-}
-
-/**
- * call-seq:
- * Prism::parse_success?(source, **options) -> Array
- *
- * Parse the given string and return true if it parses without errors. For
- * supported options, see Prism::parse.
- */
-static VALUE
-parse_success_p(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- string_options(argc, argv, &input, &options);
-
- VALUE result = parse_input_success_p(&input, &options);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return result;
-}
-
-/**
- * call-seq:
- * Prism::parse_file_success?(filepath, **options) -> Array
- *
- * Parse the given file and return true if it parses without errors. For
- * supported options, see Prism::parse.
- */
-static VALUE
-parse_file_success_p(int argc, VALUE *argv, VALUE self) {
- pm_string_t input;
- pm_options_t options = { 0 };
- if (!file_options(argc, argv, &input, &options)) return Qnil;
-
- VALUE result = parse_input_success_p(&input, &options);
- pm_string_free(&input);
- pm_options_free(&options);
-
- return result;
-}
-
-/******************************************************************************/
-/* Utility functions exposed to make testing easier */
-/******************************************************************************/
-
-/**
- * call-seq:
- * Debug::named_captures(source) -> Array
- *
- * Returns an array of strings corresponding to the named capture groups in the
- * given source string. If prism was unable to parse the regular expression,
- * this function returns nil.
- */
-static VALUE
-named_captures(VALUE self, VALUE source) {
- pm_string_list_t string_list = { 0 };
-
- if (!pm_regexp_named_capture_group_names((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), &string_list, false, PM_ENCODING_UTF_8_ENTRY)) {
- pm_string_list_free(&string_list);
- return Qnil;
- }
-
- VALUE names = rb_ary_new();
- for (size_t index = 0; index < string_list.length; index++) {
- const pm_string_t *string = &string_list.strings[index];
- rb_ary_push(names, rb_str_new((const char *) pm_string_source(string), pm_string_length(string)));
- }
-
- pm_string_list_free(&string_list);
- return names;
-}
-
-/**
- * call-seq:
- * Debug::memsize(source) -> { length: xx, memsize: xx, node_count: xx }
- *
- * Return a hash of information about the given source string's memory usage.
- */
-static VALUE
-memsize(VALUE self, VALUE string) {
- pm_parser_t parser;
- size_t length = RSTRING_LEN(string);
- pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(string), length, NULL);
-
- pm_node_t *node = pm_parse(&parser);
- pm_memsize_t memsize;
- pm_node_memsize(node, &memsize);
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
-
- VALUE result = rb_hash_new();
- rb_hash_aset(result, ID2SYM(rb_intern("length")), INT2FIX(length));
- rb_hash_aset(result, ID2SYM(rb_intern("memsize")), INT2FIX(memsize.memsize));
- rb_hash_aset(result, ID2SYM(rb_intern("node_count")), INT2FIX(memsize.node_count));
- return result;
-}
-
-/**
- * call-seq:
- * Debug::profile_file(filepath) -> nil
- *
- * Parse the file, but do nothing with the result. This is used to profile the
- * parser for memory and speed.
- */
-static VALUE
-profile_file(VALUE self, VALUE filepath) {
- pm_string_t input;
-
- const char *checked = check_string(filepath);
- if (!pm_string_mapped_init(&input, checked)) return Qnil;
-
- pm_options_t options = { 0 };
- pm_options_filepath_set(&options, checked);
-
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
-
- pm_node_t *node = pm_parse(&parser);
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
- pm_options_free(&options);
- pm_string_free(&input);
-
- return Qnil;
-}
-
-/**
- * call-seq:
- * Debug::inspect_node(source) -> inspected
- *
- * Inspect the AST that represents the given source using the prism pretty print
- * as opposed to the Ruby implementation.
- */
-static VALUE
-inspect_node(VALUE self, VALUE source) {
- pm_string_t input;
- input_load_string(&input, source);
-
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), NULL);
-
- pm_node_t *node = pm_parse(&parser);
- pm_buffer_t buffer = { 0 };
-
- pm_prettyprint(&buffer, &parser, node);
-
- rb_encoding *encoding = rb_enc_find(parser.encoding->name);
- VALUE string = rb_enc_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer), encoding);
-
- pm_buffer_free(&buffer);
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
-
- return string;
-}
-
-/******************************************************************************/
-/* Initialization of the extension */
-/******************************************************************************/
-
-/**
- * The init function that Ruby calls when loading this extension.
- */
-RUBY_FUNC_EXPORTED void
-Init_prism(void) {
- // Make sure that the prism library version matches the expected version.
- // Otherwise something was compiled incorrectly.
- if (strcmp(pm_version(), EXPECTED_PRISM_VERSION) != 0) {
- rb_raise(
- rb_eRuntimeError,
- "The prism library version (%s) does not match the expected version (%s)",
- pm_version(),
- EXPECTED_PRISM_VERSION
- );
- }
-
- // Grab up references to all of the constants that we're going to need to
- // reference throughout this extension.
- rb_cPrism = rb_define_module("Prism");
- rb_cPrismNode = rb_define_class_under(rb_cPrism, "Node", rb_cObject);
- rb_cPrismSource = rb_define_class_under(rb_cPrism, "Source", rb_cObject);
- rb_cPrismToken = rb_define_class_under(rb_cPrism, "Token", rb_cObject);
- rb_cPrismLocation = rb_define_class_under(rb_cPrism, "Location", rb_cObject);
- rb_cPrismComment = rb_define_class_under(rb_cPrism, "Comment", rb_cObject);
- rb_cPrismInlineComment = rb_define_class_under(rb_cPrism, "InlineComment", rb_cPrismComment);
- rb_cPrismEmbDocComment = rb_define_class_under(rb_cPrism, "EmbDocComment", rb_cPrismComment);
- rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject);
- rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject);
- rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject);
- rb_cPrismParseResult = rb_define_class_under(rb_cPrism, "ParseResult", rb_cObject);
-
- // Intern all of the options that we support so that we don't have to do it
- // every time we parse.
- rb_option_id_filepath = rb_intern_const("filepath");
- rb_option_id_encoding = rb_intern_const("encoding");
- rb_option_id_line = rb_intern_const("line");
- rb_option_id_frozen_string_literal = rb_intern_const("frozen_string_literal");
- rb_option_id_verbose = rb_intern_const("verbose");
- rb_option_id_scopes = rb_intern_const("scopes");
-
- /**
- * The version of the prism library.
- */
- rb_define_const(rb_cPrism, "VERSION", rb_str_new2(EXPECTED_PRISM_VERSION));
-
- /**
- * The backend of the parser that prism is using to parse Ruby code. This
- * can be either :CEXT or :FFI. On runtimes that support C extensions, we
- * default to :CEXT. Otherwise we use :FFI.
- */
- rb_define_const(rb_cPrism, "BACKEND", ID2SYM(rb_intern("CEXT")));
-
- // First, the functions that have to do with lexing and parsing.
- rb_define_singleton_method(rb_cPrism, "dump", dump, -1);
- rb_define_singleton_method(rb_cPrism, "dump_file", dump_file, -1);
- rb_define_singleton_method(rb_cPrism, "lex", lex, -1);
- rb_define_singleton_method(rb_cPrism, "lex_file", lex_file, -1);
- rb_define_singleton_method(rb_cPrism, "parse", parse, -1);
- rb_define_singleton_method(rb_cPrism, "parse_file", parse_file, -1);
- rb_define_singleton_method(rb_cPrism, "parse_comments", parse_comments, -1);
- rb_define_singleton_method(rb_cPrism, "parse_file_comments", parse_file_comments, -1);
- rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1);
- rb_define_singleton_method(rb_cPrism, "parse_lex_file", parse_lex_file, -1);
- rb_define_singleton_method(rb_cPrism, "parse_success?", parse_success_p, -1);
- rb_define_singleton_method(rb_cPrism, "parse_file_success?", parse_file_success_p, -1);
-
- // Next, the functions that will be called by the parser to perform various
- // internal tasks. We expose these to make them easier to test.
- VALUE rb_cPrismDebug = rb_define_module_under(rb_cPrism, "Debug");
- rb_define_singleton_method(rb_cPrismDebug, "named_captures", named_captures, 1);
- rb_define_singleton_method(rb_cPrismDebug, "memsize", memsize, 1);
- rb_define_singleton_method(rb_cPrismDebug, "profile_file", profile_file, 1);
- rb_define_singleton_method(rb_cPrismDebug, "inspect_node", inspect_node, 1);
-
- // Next, initialize the other APIs.
- Init_prism_api_node();
- Init_prism_pack();
-}
diff --git a/prism/extension.h b/prism/extension.h
deleted file mode 100644
index a21370cfa4..0000000000
--- a/prism/extension.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef PRISM_EXT_NODE_H
-#define PRISM_EXT_NODE_H
-
-#define EXPECTED_PRISM_VERSION "0.19.0"
-
-#include <ruby.h>
-#include <ruby/encoding.h>
-#include "prism.h"
-
-VALUE pm_source_new(pm_parser_t *parser, rb_encoding *encoding);
-VALUE pm_token_new(pm_parser_t *parser, pm_token_t *token, rb_encoding *encoding, VALUE source);
-VALUE pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding);
-
-void Init_prism_api_node(void);
-void Init_prism_pack(void);
-PRISM_EXPORTED_FUNCTION void Init_prism(void);
-
-#endif
diff --git a/prism/node.h b/prism/node.h
deleted file mode 100644
index 3e15d18552..0000000000
--- a/prism/node.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file node.h
- *
- * Functions related to nodes in the AST.
- */
-#ifndef PRISM_NODE_H
-#define PRISM_NODE_H
-
-#include "prism/defines.h"
-#include "prism/parser.h"
-
-/**
- * Append a new node onto the end of the node list.
- *
- * @param list The list to append to.
- * @param node The node to append.
- */
-void pm_node_list_append(pm_node_list_t *list, pm_node_t *node);
-
-/**
- * Deallocate a node and all of its children.
- *
- * @param parser The parser that owns the node.
- * @param node The node to deallocate.
- */
-PRISM_EXPORTED_FUNCTION void pm_node_destroy(pm_parser_t *parser, struct pm_node *node);
-
-/**
- * This struct stores the information gathered by the pm_node_memsize function.
- * It contains both the memory footprint and additionally metadata about the
- * shape of the tree.
- */
-typedef struct {
- /** The total memory footprint of the node and all of its children. */
- size_t memsize;
-
- /** The number of children the node has. */
- size_t node_count;
-} pm_memsize_t;
-
-/**
- * Calculates the memory footprint of a given node.
- *
- * @param node The node to calculate the memory footprint of.
- * @param memsize The memory footprint of the node and all of its children.
- */
-PRISM_EXPORTED_FUNCTION void pm_node_memsize(pm_node_t *node, pm_memsize_t *memsize);
-
-/**
- * Returns a string representation of the given node type.
- *
- * @param node_type The node type to convert to a string.
- * @return A string representation of the given node type.
- */
-PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_type);
-
-#endif
diff --git a/prism/options.c b/prism/options.c
deleted file mode 100644
index 85d04d6272..0000000000
--- a/prism/options.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "prism/options.h"
-
-/**
- * Set the filepath option on the given options struct.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_filepath_set(pm_options_t *options, const char *filepath) {
- pm_string_constant_init(&options->filepath, filepath, strlen(filepath));
-}
-
-/**
- * Set the encoding option on the given options struct.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_encoding_set(pm_options_t *options, const char *encoding) {
- pm_string_constant_init(&options->encoding, encoding, strlen(encoding));
-}
-
-/**
- * Set the line option on the given options struct.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_line_set(pm_options_t *options, int32_t line) {
- options->line = line;
-}
-
-/**
- * Set the frozen string literal option on the given options struct.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal) {
- options->frozen_string_literal = frozen_string_literal;
-}
-
-/**
- * Set the suppress warnings option on the given options struct.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_suppress_warnings_set(pm_options_t *options, bool suppress_warnings) {
- options->suppress_warnings = suppress_warnings;
-}
-
-/**
- * Allocate and zero out the scopes array on the given options struct.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_scopes_init(pm_options_t *options, size_t scopes_count) {
- options->scopes_count = scopes_count;
- options->scopes = calloc(scopes_count, sizeof(pm_options_scope_t));
- if (options->scopes == NULL) abort();
-}
-
-/**
- * Return a pointer to the scope at the given index within the given options.
- */
-PRISM_EXPORTED_FUNCTION const pm_options_scope_t *
-pm_options_scope_get(const pm_options_t *options, size_t index) {
- return &options->scopes[index];
-}
-
-/**
- * Create a new options scope struct. This will hold a set of locals that are in
- * scope surrounding the code that is being parsed.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count) {
- scope->locals_count = locals_count;
- scope->locals = calloc(locals_count, sizeof(pm_string_t));
- if (scope->locals == NULL) abort();
-}
-
-/**
- * Return a pointer to the local at the given index within the given scope.
- */
-PRISM_EXPORTED_FUNCTION const pm_string_t *
-pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index) {
- return &scope->locals[index];
-}
-
-/**
- * Free the internal memory associated with the options.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_options_free(pm_options_t *options) {
- pm_string_free(&options->filepath);
- pm_string_free(&options->encoding);
-
- for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
- pm_options_scope_t *scope = &options->scopes[scope_index];
-
- for (size_t local_index = 0; local_index < scope->locals_count; local_index++) {
- pm_string_free(&scope->locals[local_index]);
- }
-
- free(scope->locals);
- }
-
- free(options->scopes);
-}
-
-/**
- * Read a 32-bit unsigned integer from a pointer. This function is used to read
- * the options that are passed into the parser from the Ruby implementation. It
- * handles aligned and unaligned reads.
- */
-static uint32_t
-pm_options_read_u32(const char *data) {
- if (((uintptr_t) data) % sizeof(uint32_t) == 0) {
- return *((uint32_t *) data);
- } else {
- uint32_t value;
- memcpy(&value, data, sizeof(uint32_t));
- return value;
- }
-}
-
-/**
- * Read a 32-bit signed integer from a pointer. This function is used to read
- * the options that are passed into the parser from the Ruby implementation. It
- * handles aligned and unaligned reads.
- */
-static int32_t
-pm_options_read_s32(const char *data) {
- if (((uintptr_t) data) % sizeof(int32_t) == 0) {
- return *((int32_t *) data);
- } else {
- int32_t value;
- memcpy(&value, data, sizeof(int32_t));
- return value;
- }
-}
-
-/**
- * Deserialize an options struct from the given binary string. This is used to
- * pass options to the parser from an FFI call so that consumers of the library
- * from an FFI perspective don't have to worry about the structure of our
- * options structs. Since the source of these calls will be from Ruby
- * implementation internals we assume it is from a trusted source.
- */
-void
-pm_options_read(pm_options_t *options, const char *data) {
- options->line = 1; // default
- if (data == NULL) return;
-
- uint32_t filepath_length = pm_options_read_u32(data);
- data += 4;
-
- if (filepath_length > 0) {
- pm_string_constant_init(&options->filepath, data, filepath_length);
- data += filepath_length;
- }
-
- options->line = pm_options_read_s32(data);
- data += 4;
-
- uint32_t encoding_length = pm_options_read_u32(data);
- data += 4;
-
- if (encoding_length > 0) {
- pm_string_constant_init(&options->encoding, data, encoding_length);
- data += encoding_length;
- }
-
- options->frozen_string_literal = *data++;
- options->suppress_warnings = *data++;
-
- uint32_t scopes_count = pm_options_read_u32(data);
- data += 4;
-
- if (scopes_count > 0) {
- pm_options_scopes_init(options, scopes_count);
-
- for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) {
- uint32_t locals_count = pm_options_read_u32(data);
- data += 4;
-
- pm_options_scope_t *scope = &options->scopes[scope_index];
- pm_options_scope_init(scope, locals_count);
-
- for (size_t local_index = 0; local_index < locals_count; local_index++) {
- uint32_t local_length = pm_options_read_u32(data);
- data += 4;
-
- pm_string_constant_init(&scope->locals[local_index], data, local_length);
- data += local_length;
- }
- }
- }
-}
diff --git a/prism/options.h b/prism/options.h
deleted file mode 100644
index 8608838da8..0000000000
--- a/prism/options.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * @file options.h
- *
- * The options that can be passed to parsing.
- */
-#ifndef PRISM_OPTIONS_H
-#define PRISM_OPTIONS_H
-
-#include "prism/defines.h"
-#include "prism/util/pm_string.h"
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * A scope of locals surrounding the code that is being parsed.
- */
-typedef struct pm_options_scope {
- /** The number of locals in the scope. */
- size_t locals_count;
-
- /** The names of the locals in the scope. */
- pm_string_t *locals;
-} pm_options_scope_t;
-
-/**
- * The options that can be passed to the parser.
- */
-typedef struct {
- /** The name of the file that is currently being parsed. */
- pm_string_t filepath;
-
- /**
- * The line within the file that the parse starts on. This value is
- * 0-indexed.
- */
- int32_t line;
-
- /**
- * The name of the encoding that the source file is in. Note that this must
- * correspond to a name that can be found with Encoding.find in Ruby.
- */
- pm_string_t encoding;
-
- /**
- * The number of scopes surrounding the code that is being parsed.
- */
- size_t scopes_count;
-
- /**
- * The scopes surrounding the code that is being parsed. For most parses
- * this will be NULL, but for evals it will be the locals that are in scope
- * surrounding the eval.
- */
- pm_options_scope_t *scopes;
-
- /** Whether or not the frozen string literal option has been set. */
- bool frozen_string_literal;
-
- /**
- * Whether or not we should suppress warnings. This is purposefully negated
- * so that the default is to not suppress warnings, which allows us to still
- * create an options struct with zeroed memory.
- */
- bool suppress_warnings;
-} pm_options_t;
-
-/**
- * Set the filepath option on the given options struct.
- *
- * @param options The options struct to set the filepath on.
- * @param filepath The filepath to set.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_filepath_set(pm_options_t *options, const char *filepath);
-
-/**
- * Set the line option on the given options struct.
- *
- * @param options The options struct to set the line on.
- * @param line The line to set.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_line_set(pm_options_t *options, int32_t line);
-
-/**
- * Set the encoding option on the given options struct.
- *
- * @param options The options struct to set the encoding on.
- * @param encoding The encoding to set.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_encoding_set(pm_options_t *options, const char *encoding);
-
-/**
- * Set the frozen string literal option on the given options struct.
- *
- * @param options The options struct to set the frozen string literal value on.
- * @param frozen_string_literal The frozen string literal value to set.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal);
-
-/**
- * Set the suppress warnings option on the given options struct.
- *
- * @param options The options struct to set the suppress warnings value on.
- * @param suppress_warnings The suppress warnings value to set.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_suppress_warnings_set(pm_options_t *options, bool suppress_warnings);
-
-/**
- * Allocate and zero out the scopes array on the given options struct.
- *
- * @param options The options struct to initialize the scopes array on.
- * @param scopes_count The number of scopes to allocate.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_scopes_init(pm_options_t *options, size_t scopes_count);
-
-/**
- * Return a pointer to the scope at the given index within the given options.
- *
- * @param options The options struct to get the scope from.
- * @param index The index of the scope to get.
- * @return A pointer to the scope at the given index.
- */
-PRISM_EXPORTED_FUNCTION const pm_options_scope_t * pm_options_scope_get(const pm_options_t *options, size_t index);
-
-/**
- * Create a new options scope struct. This will hold a set of locals that are in
- * scope surrounding the code that is being parsed.
- *
- * @param scope The scope struct to initialize.
- * @param locals_count The number of locals to allocate.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count);
-
-/**
- * Return a pointer to the local at the given index within the given scope.
- *
- * @param scope The scope struct to get the local from.
- * @param index The index of the local to get.
- * @return A pointer to the local at the given index.
- */
-PRISM_EXPORTED_FUNCTION const pm_string_t * pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index);
-
-/**
- * Free the internal memory associated with the options.
- *
- * @param options The options struct whose internal memory should be freed.
- */
-PRISM_EXPORTED_FUNCTION void pm_options_free(pm_options_t *options);
-
-/**
- * Deserialize an options struct from the given binary string. This is used to
- * pass options to the parser from an FFI call so that consumers of the library
- * from an FFI perspective don't have to worry about the structure of our
- * options structs. Since the source of these calls will be from Ruby
- * implementation internals we assume it is from a trusted source.
- *
- * `data` is assumed to be a valid pointer pointing to well-formed data. The
- * layout of this data should be the same every time, and is described below:
- *
- * | # bytes | field |
- * | ------- | -------------------------- |
- * | `4` | the length of the filepath |
- * | ... | the filepath bytes |
- * | `4` | the line number |
- * | `4` | the length the encoding |
- * | ... | the encoding bytes |
- * | `1` | frozen string literal |
- * | `1` | suppress warnings |
- * | `4` | the number of scopes |
- * | ... | the scopes |
- *
- * Each scope is layed out as follows:
- *
- * | # bytes | field |
- * | ------- | -------------------------- |
- * | `4` | the number of locals |
- * | ... | the locals |
- *
- * Each local is layed out as follows:
- *
- * | # bytes | field |
- * | ------- | -------------------------- |
- * | `4` | the length of the local |
- * | ... | the local bytes |
- *
- * Some additional things to note about this layout:
- *
- * * The filepath can have a length of 0, in which case we'll consider it an
- * empty string.
- * * The line number should be 0-indexed.
- * * The encoding can have a length of 0, in which case we'll use the default
- * encoding (UTF-8). If it's not 0, it should correspond to a name of an
- * encoding that can be passed to `Encoding.find` in Ruby.
- * * The frozen string literal and suppress warnings fields are booleans, so
- * their values should be either 0 or 1.
- * * The number of scopes can be 0.
- *
- * @param options The options struct to deserialize into.
- * @param data The binary string to deserialize from.
- */
-void pm_options_read(pm_options_t *options, const char *data);
-
-#endif
diff --git a/prism/pack.c b/prism/pack.c
deleted file mode 100644
index d5bfc4d6fd..0000000000
--- a/prism/pack.c
+++ /dev/null
@@ -1,493 +0,0 @@
-#include "prism/pack.h"
-
-#include <stdbool.h>
-#include <errno.h>
-
-static uintmax_t
-strtoumaxc(const char **format);
-
-PRISM_EXPORTED_FUNCTION pm_pack_result
-pm_pack_parse(pm_pack_variant variant, const char **format, const char *format_end,
- pm_pack_type *type, pm_pack_signed *signed_type, pm_pack_endian *endian, pm_pack_size *size,
- pm_pack_length_type *length_type, uint64_t *length, pm_pack_encoding *encoding) {
-
- if (*encoding == PM_PACK_ENCODING_START) {
- *encoding = PM_PACK_ENCODING_US_ASCII;
- }
-
- if (*format == format_end) {
- *type = PM_PACK_END;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- *length_type = PM_PACK_LENGTH_NA;
- return PM_PACK_OK;
- }
-
- *length_type = PM_PACK_LENGTH_FIXED;
- *length = 1;
- bool length_changed_allowed = true;
-
- char directive = **format;
- (*format)++;
- switch (directive) {
- case ' ':
- case '\t':
- case '\n':
- case '\v':
- case '\f':
- case '\r':
- *type = PM_PACK_SPACE;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- *length_type = PM_PACK_LENGTH_NA;
- *length = 0;
- return PM_PACK_OK;
- case '#':
- while ((*format < format_end) && (**format != '\n')) {
- (*format)++;
- }
- *type = PM_PACK_COMMENT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- *length_type = PM_PACK_LENGTH_NA;
- *length = 0;
- return PM_PACK_OK;
- case 'C':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_AGNOSTIC_ENDIAN;
- *size = PM_PACK_SIZE_8;
- break;
- case 'S':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_16;
- break;
- case 'L':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_32;
- break;
- case 'Q':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_64;
- break;
- case 'J':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_P;
- break;
- case 'c':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_SIGNED;
- *endian = PM_PACK_AGNOSTIC_ENDIAN;
- *size = PM_PACK_SIZE_8;
- break;
- case 's':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_SIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_16;
- break;
- case 'l':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_SIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_32;
- break;
- case 'q':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_SIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_64;
- break;
- case 'j':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_SIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_P;
- break;
- case 'I':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_INT;
- break;
- case 'i':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_SIGNED;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_INT;
- break;
- case 'n':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_BIG_ENDIAN;
- *size = PM_PACK_SIZE_16;
- length_changed_allowed = false;
- break;
- case 'N':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_BIG_ENDIAN;
- *size = PM_PACK_SIZE_32;
- length_changed_allowed = false;
- break;
- case 'v':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_LITTLE_ENDIAN;
- *size = PM_PACK_SIZE_16;
- length_changed_allowed = false;
- break;
- case 'V':
- *type = PM_PACK_INTEGER;
- *signed_type = PM_PACK_UNSIGNED;
- *endian = PM_PACK_LITTLE_ENDIAN;
- *size = PM_PACK_SIZE_32;
- length_changed_allowed = false;
- break;
- case 'U':
- *type = PM_PACK_UTF8;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'w':
- *type = PM_PACK_BER;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'D':
- case 'd':
- *type = PM_PACK_FLOAT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_64;
- break;
- case 'F':
- case 'f':
- *type = PM_PACK_FLOAT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_NATIVE_ENDIAN;
- *size = PM_PACK_SIZE_32;
- break;
- case 'E':
- *type = PM_PACK_FLOAT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_LITTLE_ENDIAN;
- *size = PM_PACK_SIZE_64;
- break;
- case 'e':
- *type = PM_PACK_FLOAT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_LITTLE_ENDIAN;
- *size = PM_PACK_SIZE_32;
- break;
- case 'G':
- *type = PM_PACK_FLOAT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_BIG_ENDIAN;
- *size = PM_PACK_SIZE_64;
- break;
- case 'g':
- *type = PM_PACK_FLOAT;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_BIG_ENDIAN;
- *size = PM_PACK_SIZE_32;
- break;
- case 'A':
- *type = PM_PACK_STRING_SPACE_PADDED;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'a':
- *type = PM_PACK_STRING_NULL_PADDED;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'Z':
- *type = PM_PACK_STRING_NULL_TERMINATED;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'B':
- *type = PM_PACK_STRING_MSB;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'b':
- *type = PM_PACK_STRING_LSB;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'H':
- *type = PM_PACK_STRING_HEX_HIGH;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'h':
- *type = PM_PACK_STRING_HEX_LOW;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'u':
- *type = PM_PACK_STRING_UU;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'M':
- *type = PM_PACK_STRING_MIME;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'm':
- *type = PM_PACK_STRING_BASE64;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'P':
- *type = PM_PACK_STRING_FIXED;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'p':
- *type = PM_PACK_STRING_POINTER;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case '@':
- *type = PM_PACK_MOVE;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'X':
- *type = PM_PACK_BACK;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case 'x':
- *type = PM_PACK_NULL;
- *signed_type = PM_PACK_SIGNED_NA;
- *endian = PM_PACK_ENDIAN_NA;
- *size = PM_PACK_SIZE_NA;
- break;
- case '%':
- return PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE;
- default:
- return PM_PACK_ERROR_UNKNOWN_DIRECTIVE;
- }
-
- bool explicit_endian = false;
-
- while (*format < format_end) {
- switch (**format) {
- case '_':
- case '!':
- (*format)++;
- if (*type != PM_PACK_INTEGER || !length_changed_allowed) {
- return PM_PACK_ERROR_BANG_NOT_ALLOWED;
- }
- switch (*size) {
- case PM_PACK_SIZE_SHORT:
- case PM_PACK_SIZE_INT:
- case PM_PACK_SIZE_LONG:
- case PM_PACK_SIZE_LONG_LONG:
- break;
- case PM_PACK_SIZE_16:
- *size = PM_PACK_SIZE_SHORT;
- break;
- case PM_PACK_SIZE_32:
- *size = PM_PACK_SIZE_LONG;
- break;
- case PM_PACK_SIZE_64:
- *size = PM_PACK_SIZE_LONG_LONG;
- break;
- case PM_PACK_SIZE_P:
- break;
- default:
- return PM_PACK_ERROR_BANG_NOT_ALLOWED;
- }
- break;
- case '<':
- (*format)++;
- if (explicit_endian) {
- return PM_PACK_ERROR_DOUBLE_ENDIAN;
- }
- *endian = PM_PACK_LITTLE_ENDIAN;
- explicit_endian = true;
- break;
- case '>':
- (*format)++;
- if (explicit_endian) {
- return PM_PACK_ERROR_DOUBLE_ENDIAN;
- }
- *endian = PM_PACK_BIG_ENDIAN;
- explicit_endian = true;
- break;
- default:
- goto exit_modifier_loop;
- }
- }
-
-exit_modifier_loop:
-
- if (variant == PM_PACK_VARIANT_UNPACK && *type == PM_PACK_MOVE) {
- *length = 0;
- }
-
- if (*format < format_end) {
- if (**format == '*') {
- switch (*type) {
- case PM_PACK_NULL:
- case PM_PACK_BACK:
- switch (variant) {
- case PM_PACK_VARIANT_PACK:
- *length_type = PM_PACK_LENGTH_FIXED;
- break;
- case PM_PACK_VARIANT_UNPACK:
- *length_type = PM_PACK_LENGTH_MAX;
- break;
- }
- *length = 0;
- break;
-
- case PM_PACK_MOVE:
- switch (variant) {
- case PM_PACK_VARIANT_PACK:
- *length_type = PM_PACK_LENGTH_FIXED;
- break;
- case PM_PACK_VARIANT_UNPACK:
- *length_type = PM_PACK_LENGTH_RELATIVE;
- break;
- }
- *length = 0;
- break;
-
- case PM_PACK_STRING_UU:
- *length_type = PM_PACK_LENGTH_FIXED;
- *length = 0;
- break;
-
- case PM_PACK_STRING_FIXED:
- switch (variant) {
- case PM_PACK_VARIANT_PACK:
- *length_type = PM_PACK_LENGTH_FIXED;
- *length = 1;
- break;
- case PM_PACK_VARIANT_UNPACK:
- *length_type = PM_PACK_LENGTH_MAX;
- *length = 0;
- break;
- }
- break;
-
- case PM_PACK_STRING_MIME:
- case PM_PACK_STRING_BASE64:
- *length_type = PM_PACK_LENGTH_FIXED;
- *length = 1;
- break;
-
- default:
- *length_type = PM_PACK_LENGTH_MAX;
- *length = 0;
- break;
- }
-
- (*format)++;
- } else if (**format >= '0' && **format <= '9') {
- errno = 0;
- *length_type = PM_PACK_LENGTH_FIXED;
- #if UINTMAX_MAX < UINT64_MAX
- #error "prism's design assumes uintmax_t is at least as large as uint64_t"
- #endif
- uintmax_t length_max = strtoumaxc(format);
- if (errno || length_max > UINT64_MAX) {
- return PM_PACK_ERROR_LENGTH_TOO_BIG;
- }
- *length = (uint64_t) length_max;
- }
- }
-
- switch (*type) {
- case PM_PACK_UTF8:
- /* if encoding is US-ASCII, upgrade to UTF-8 */
- if (*encoding == PM_PACK_ENCODING_US_ASCII) {
- *encoding = PM_PACK_ENCODING_UTF_8;
- }
- break;
- case PM_PACK_STRING_MIME:
- case PM_PACK_STRING_BASE64:
- case PM_PACK_STRING_UU:
- /* keep US-ASCII (do nothing) */
- break;
- default:
- /* fall back to BINARY */
- *encoding = PM_PACK_ENCODING_ASCII_8BIT;
- break;
- }
-
- return PM_PACK_OK;
-}
-
-PRISM_EXPORTED_FUNCTION size_t
-pm_size_to_native(pm_pack_size size) {
- switch (size) {
- case PM_PACK_SIZE_SHORT:
- return sizeof(short);
- case PM_PACK_SIZE_INT:
- return sizeof(int);
- case PM_PACK_SIZE_LONG:
- return sizeof(long);
- case PM_PACK_SIZE_LONG_LONG:
- return sizeof(long long);
- case PM_PACK_SIZE_8:
- return 1;
- case PM_PACK_SIZE_16:
- return 2;
- case PM_PACK_SIZE_32:
- return 4;
- case PM_PACK_SIZE_64:
- return 8;
- case PM_PACK_SIZE_P:
- return sizeof(void *);
- default:
- return 0;
- }
-}
-
-static uintmax_t
-strtoumaxc(const char **format) {
- uintmax_t value = 0;
- while (**format >= '0' && **format <= '9') {
- if (value > UINTMAX_MAX / 10) {
- errno = ERANGE;
- }
- value = value * 10 + ((uintmax_t) (**format - '0'));
- (*format)++;
- }
- return value;
-}
diff --git a/prism/pack.h b/prism/pack.h
deleted file mode 100644
index e494848389..0000000000
--- a/prism/pack.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * @file pack.h
- *
- * A pack template string parser.
- */
-#ifndef PRISM_PACK_H
-#define PRISM_PACK_H
-
-#include "prism/defines.h"
-
-#include <stdint.h>
-#include <stdlib.h>
-
-/** The version of the pack template language that we are parsing. */
-typedef enum pm_pack_version {
- PM_PACK_VERSION_3_2_0
-} pm_pack_version;
-
-/** The type of pack template we are parsing. */
-typedef enum pm_pack_variant {
- PM_PACK_VARIANT_PACK,
- PM_PACK_VARIANT_UNPACK
-} pm_pack_variant;
-
-/** A directive within the pack template. */
-typedef enum pm_pack_type {
- PM_PACK_SPACE,
- PM_PACK_COMMENT,
- PM_PACK_INTEGER,
- PM_PACK_UTF8,
- PM_PACK_BER,
- PM_PACK_FLOAT,
- PM_PACK_STRING_SPACE_PADDED,
- PM_PACK_STRING_NULL_PADDED,
- PM_PACK_STRING_NULL_TERMINATED,
- PM_PACK_STRING_MSB,
- PM_PACK_STRING_LSB,
- PM_PACK_STRING_HEX_HIGH,
- PM_PACK_STRING_HEX_LOW,
- PM_PACK_STRING_UU,
- PM_PACK_STRING_MIME,
- PM_PACK_STRING_BASE64,
- PM_PACK_STRING_FIXED,
- PM_PACK_STRING_POINTER,
- PM_PACK_MOVE,
- PM_PACK_BACK,
- PM_PACK_NULL,
- PM_PACK_END
-} pm_pack_type;
-
-/** The signness of a pack directive. */
-typedef enum pm_pack_signed {
- PM_PACK_UNSIGNED,
- PM_PACK_SIGNED,
- PM_PACK_SIGNED_NA
-} pm_pack_signed;
-
-/** The endianness of a pack directive. */
-typedef enum pm_pack_endian {
- PM_PACK_AGNOSTIC_ENDIAN,
- PM_PACK_LITTLE_ENDIAN, // aka 'VAX', or 'V'
- PM_PACK_BIG_ENDIAN, // aka 'network', or 'N'
- PM_PACK_NATIVE_ENDIAN,
- PM_PACK_ENDIAN_NA
-} pm_pack_endian;
-
-/** The size of an integer pack directive. */
-typedef enum pm_pack_size {
- PM_PACK_SIZE_SHORT,
- PM_PACK_SIZE_INT,
- PM_PACK_SIZE_LONG,
- PM_PACK_SIZE_LONG_LONG,
- PM_PACK_SIZE_8,
- PM_PACK_SIZE_16,
- PM_PACK_SIZE_32,
- PM_PACK_SIZE_64,
- PM_PACK_SIZE_P,
- PM_PACK_SIZE_NA
-} pm_pack_size;
-
-/** The type of length of a pack directive. */
-typedef enum pm_pack_length_type {
- PM_PACK_LENGTH_FIXED,
- PM_PACK_LENGTH_MAX,
- PM_PACK_LENGTH_RELATIVE, // special case for unpack @*
- PM_PACK_LENGTH_NA
-} pm_pack_length_type;
-
-/** The type of encoding for a pack template string. */
-typedef enum pm_pack_encoding {
- PM_PACK_ENCODING_START,
- PM_PACK_ENCODING_ASCII_8BIT,
- PM_PACK_ENCODING_US_ASCII,
- PM_PACK_ENCODING_UTF_8
-} pm_pack_encoding;
-
-/** The result of parsing a pack template. */
-typedef enum pm_pack_result {
- PM_PACK_OK,
- PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE,
- PM_PACK_ERROR_UNKNOWN_DIRECTIVE,
- PM_PACK_ERROR_LENGTH_TOO_BIG,
- PM_PACK_ERROR_BANG_NOT_ALLOWED,
- PM_PACK_ERROR_DOUBLE_ENDIAN
-} pm_pack_result;
-
-/**
- * Parse a single directive from a pack or unpack format string.
- *
- * @param variant (in) pack or unpack
- * @param format (in, out) the start of the next directive to parse on calling,
- * and advanced beyond the parsed directive on return, or as much of it as
- * was consumed until an error was encountered
- * @param format_end (in) the end of the format string
- * @param type (out) the type of the directive
- * @param signed_type (out) whether the value is signed
- * @param endian (out) the endianness of the value
- * @param size (out) the size of the value
- * @param length_type (out) what kind of length is specified
- * @param length (out) the length of the directive
- * @param encoding (in, out) takes the current encoding of the string which
- * would result from parsing the whole format string, and returns a possibly
- * changed directive - the encoding should be `PM_PACK_ENCODING_START` when
- * pm_pack_parse is called for the first directive in a format string
- *
- * @return `PM_PACK_OK` on success or `PM_PACK_ERROR_*` on error
- * @note Consult Ruby documentation for the meaning of directives.
- */
-PRISM_EXPORTED_FUNCTION pm_pack_result
-pm_pack_parse(
- pm_pack_variant variant,
- const char **format,
- const char *format_end,
- pm_pack_type *type,
- pm_pack_signed *signed_type,
- pm_pack_endian *endian,
- pm_pack_size *size,
- pm_pack_length_type *length_type,
- uint64_t *length,
- pm_pack_encoding *encoding
-);
-
-/**
- * Prism abstracts sizes away from the native system - this converts an abstract
- * size to a native size.
- *
- * @param size The abstract size to convert.
- * @return The native size.
- */
-PRISM_EXPORTED_FUNCTION size_t pm_size_to_native(pm_pack_size size);
-
-#endif
diff --git a/prism/parser.h b/prism/parser.h
deleted file mode 100644
index 7f26054f09..0000000000
--- a/prism/parser.h
+++ /dev/null
@@ -1,716 +0,0 @@
-/**
- * @file parser.h
- *
- * The parser used to parse Ruby source.
- */
-#ifndef PRISM_PARSER_H
-#define PRISM_PARSER_H
-
-#include "prism/ast.h"
-#include "prism/defines.h"
-#include "prism/encoding.h"
-#include "prism/util/pm_constant_pool.h"
-#include "prism/util/pm_list.h"
-#include "prism/util/pm_newline_list.h"
-#include "prism/util/pm_state_stack.h"
-#include "prism/util/pm_string.h"
-
-#include <stdbool.h>
-
-// TODO: remove this by renaming the original flag
-/**
- * Temporary alias for the PM_NODE_FLAG_STATIC_KEYS flag.
- */
-#define PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS PM_KEYWORD_HASH_NODE_FLAGS_STATIC_KEYS
-
-/**
- * This enum provides various bits that represent different kinds of states that
- * the lexer can track. This is used to determine which kind of token to return
- * based on the context of the parser.
- */
-typedef enum {
- PM_LEX_STATE_BIT_BEG,
- PM_LEX_STATE_BIT_END,
- PM_LEX_STATE_BIT_ENDARG,
- PM_LEX_STATE_BIT_ENDFN,
- PM_LEX_STATE_BIT_ARG,
- PM_LEX_STATE_BIT_CMDARG,
- PM_LEX_STATE_BIT_MID,
- PM_LEX_STATE_BIT_FNAME,
- PM_LEX_STATE_BIT_DOT,
- PM_LEX_STATE_BIT_CLASS,
- PM_LEX_STATE_BIT_LABEL,
- PM_LEX_STATE_BIT_LABELED,
- PM_LEX_STATE_BIT_FITEM
-} pm_lex_state_bit_t;
-
-/**
- * This enum combines the various bits from the above enum into individual
- * values that represent the various states of the lexer.
- */
-typedef enum {
- PM_LEX_STATE_NONE = 0,
- PM_LEX_STATE_BEG = (1 << PM_LEX_STATE_BIT_BEG),
- PM_LEX_STATE_END = (1 << PM_LEX_STATE_BIT_END),
- PM_LEX_STATE_ENDARG = (1 << PM_LEX_STATE_BIT_ENDARG),
- PM_LEX_STATE_ENDFN = (1 << PM_LEX_STATE_BIT_ENDFN),
- PM_LEX_STATE_ARG = (1 << PM_LEX_STATE_BIT_ARG),
- PM_LEX_STATE_CMDARG = (1 << PM_LEX_STATE_BIT_CMDARG),
- PM_LEX_STATE_MID = (1 << PM_LEX_STATE_BIT_MID),
- PM_LEX_STATE_FNAME = (1 << PM_LEX_STATE_BIT_FNAME),
- PM_LEX_STATE_DOT = (1 << PM_LEX_STATE_BIT_DOT),
- PM_LEX_STATE_CLASS = (1 << PM_LEX_STATE_BIT_CLASS),
- PM_LEX_STATE_LABEL = (1 << PM_LEX_STATE_BIT_LABEL),
- PM_LEX_STATE_LABELED = (1 << PM_LEX_STATE_BIT_LABELED),
- PM_LEX_STATE_FITEM = (1 << PM_LEX_STATE_BIT_FITEM),
- PM_LEX_STATE_BEG_ANY = PM_LEX_STATE_BEG | PM_LEX_STATE_MID | PM_LEX_STATE_CLASS,
- PM_LEX_STATE_ARG_ANY = PM_LEX_STATE_ARG | PM_LEX_STATE_CMDARG,
- PM_LEX_STATE_END_ANY = PM_LEX_STATE_END | PM_LEX_STATE_ENDARG | PM_LEX_STATE_ENDFN
-} pm_lex_state_t;
-
-/**
- * The type of quote that a heredoc uses.
- */
-typedef enum {
- PM_HEREDOC_QUOTE_NONE,
- PM_HEREDOC_QUOTE_SINGLE = '\'',
- PM_HEREDOC_QUOTE_DOUBLE = '"',
- PM_HEREDOC_QUOTE_BACKTICK = '`',
-} pm_heredoc_quote_t;
-
-/**
- * The type of indentation that a heredoc uses.
- */
-typedef enum {
- PM_HEREDOC_INDENT_NONE,
- PM_HEREDOC_INDENT_DASH,
- PM_HEREDOC_INDENT_TILDE,
-} pm_heredoc_indent_t;
-
-/**
- * When lexing Ruby source, the lexer has a small amount of state to tell which
- * kind of token it is currently lexing. For example, when we find the start of
- * a string, the first token that we return is a TOKEN_STRING_BEGIN token. After
- * that the lexer is now in the PM_LEX_STRING mode, and will return tokens that
- * are found as part of a string.
- */
-typedef struct pm_lex_mode {
- /** The type of this lex mode. */
- enum {
- /** This state is used when any given token is being lexed. */
- PM_LEX_DEFAULT,
-
- /**
- * This state is used when we're lexing as normal but inside an embedded
- * expression of a string.
- */
- PM_LEX_EMBEXPR,
-
- /**
- * This state is used when we're lexing a variable that is embedded
- * directly inside of a string with the # shorthand.
- */
- PM_LEX_EMBVAR,
-
- /** This state is used when you are inside the content of a heredoc. */
- PM_LEX_HEREDOC,
-
- /**
- * This state is used when we are lexing a list of tokens, as in a %w
- * word list literal or a %i symbol list literal.
- */
- PM_LEX_LIST,
-
- /**
- * This state is used when a regular expression has been begun and we
- * are looking for the terminator.
- */
- PM_LEX_REGEXP,
-
- /**
- * This state is used when we are lexing a string or a string-like
- * token, as in string content with either quote or an xstring.
- */
- PM_LEX_STRING
- } mode;
-
- /** The data associated with this type of lex mode. */
- union {
- struct {
- /** This keeps track of the nesting level of the list. */
- size_t nesting;
-
- /** Whether or not interpolation is allowed in this list. */
- bool interpolation;
-
- /**
- * When lexing a list, it takes into account balancing the
- * terminator if the terminator is one of (), [], {}, or <>.
- */
- uint8_t incrementor;
-
- /** This is the terminator of the list literal. */
- uint8_t terminator;
-
- /**
- * This is the character set that should be used to delimit the
- * tokens within the list.
- */
- uint8_t breakpoints[11];
- } list;
-
- struct {
- /**
- * This keeps track of the nesting level of the regular expression.
- */
- size_t nesting;
-
- /**
- * When lexing a regular expression, it takes into account balancing
- * the terminator if the terminator is one of (), [], {}, or <>.
- */
- uint8_t incrementor;
-
- /** This is the terminator of the regular expression. */
- uint8_t terminator;
-
- /**
- * This is the character set that should be used to delimit the
- * tokens within the regular expression.
- */
- uint8_t breakpoints[6];
- } regexp;
-
- struct {
- /** This keeps track of the nesting level of the string. */
- size_t nesting;
-
- /** Whether or not interpolation is allowed in this string. */
- bool interpolation;
-
- /**
- * Whether or not at the end of the string we should allow a :,
- * which would indicate this was a dynamic symbol instead of a
- * string.
- */
- bool label_allowed;
-
- /**
- * When lexing a string, it takes into account balancing the
- * terminator if the terminator is one of (), [], {}, or <>.
- */
- uint8_t incrementor;
-
- /**
- * This is the terminator of the string. It is typically either a
- * single or double quote.
- */
- uint8_t terminator;
-
- /**
- * This is the character set that should be used to delimit the
- * tokens within the string.
- */
- uint8_t breakpoints[6];
- } string;
-
- struct {
- /** A pointer to the start of the heredoc identifier. */
- const uint8_t *ident_start;
-
- /** The length of the heredoc identifier. */
- size_t ident_length;
-
- /** The type of quote that the heredoc uses. */
- pm_heredoc_quote_t quote;
-
- /** The type of indentation that the heredoc uses. */
- pm_heredoc_indent_t indent;
-
- /**
- * This is the pointer to the character where lexing should resume
- * once the heredoc has been completely processed.
- */
- const uint8_t *next_start;
-
- /**
- * This is used to track the amount of common whitespace on each
- * line so that we know how much to dedent each line in the case of
- * a tilde heredoc.
- */
- size_t common_whitespace;
- } heredoc;
- } as;
-
- /** The previous lex state so that it knows how to pop. */
- struct pm_lex_mode *prev;
-} pm_lex_mode_t;
-
-/**
- * We pre-allocate a certain number of lex states in order to avoid having to
- * call malloc too many times while parsing. You really shouldn't need more than
- * this because you only really nest deeply when doing string interpolation.
- */
-#define PM_LEX_STACK_SIZE 4
-
-/**
- * The parser used to parse Ruby source.
- */
-typedef struct pm_parser pm_parser_t;
-
-/**
- * While parsing, we keep track of a stack of contexts. This is helpful for
- * error recovery so that we can pop back to a previous context when we hit a
- * token that is understood by a parent context but not by the current context.
- */
-typedef enum {
- /** a begin statement */
- PM_CONTEXT_BEGIN,
-
- /** expressions in block arguments using braces */
- PM_CONTEXT_BLOCK_BRACES,
-
- /** expressions in block arguments using do..end */
- PM_CONTEXT_BLOCK_KEYWORDS,
-
- /** a case when statements */
- PM_CONTEXT_CASE_WHEN,
-
- /** a case in statements */
- PM_CONTEXT_CASE_IN,
-
- /** a class declaration */
- PM_CONTEXT_CLASS,
-
- /** a method definition */
- PM_CONTEXT_DEF,
-
- /** a method definition's parameters */
- PM_CONTEXT_DEF_PARAMS,
-
- /** a method definition's default parameter */
- PM_CONTEXT_DEFAULT_PARAMS,
-
- /** an else clause */
- PM_CONTEXT_ELSE,
-
- /** an elsif clause */
- PM_CONTEXT_ELSIF,
-
- /** an interpolated expression */
- PM_CONTEXT_EMBEXPR,
-
- /** an ensure statement */
- PM_CONTEXT_ENSURE,
-
- /** an ensure statement within a method definition */
- PM_CONTEXT_ENSURE_DEF,
-
- /** a for loop */
- PM_CONTEXT_FOR,
-
- /** a for loop's index */
- PM_CONTEXT_FOR_INDEX,
-
- /** an if statement */
- PM_CONTEXT_IF,
-
- /** a lambda expression with braces */
- PM_CONTEXT_LAMBDA_BRACES,
-
- /** a lambda expression with do..end */
- PM_CONTEXT_LAMBDA_DO_END,
-
- /** the top level context */
- PM_CONTEXT_MAIN,
-
- /** a module declaration */
- PM_CONTEXT_MODULE,
-
- /** a parenthesized expression */
- PM_CONTEXT_PARENS,
-
- /** an END block */
- PM_CONTEXT_POSTEXE,
-
- /** a predicate inside an if/elsif/unless statement */
- PM_CONTEXT_PREDICATE,
-
- /** a BEGIN block */
- PM_CONTEXT_PREEXE,
-
- /** a rescue else statement */
- PM_CONTEXT_RESCUE_ELSE,
-
- /** a rescue else statement within a method definition */
- PM_CONTEXT_RESCUE_ELSE_DEF,
-
- /** a rescue statement */
- PM_CONTEXT_RESCUE,
-
- /** a rescue statement within a method definition */
- PM_CONTEXT_RESCUE_DEF,
-
- /** a singleton class definition */
- PM_CONTEXT_SCLASS,
-
- /** an unless statement */
- PM_CONTEXT_UNLESS,
-
- /** an until statement */
- PM_CONTEXT_UNTIL,
-
- /** a while statement */
- PM_CONTEXT_WHILE,
-} pm_context_t;
-
-/** This is a node in a linked list of contexts. */
-typedef struct pm_context_node {
- /** The context that this node represents. */
- pm_context_t context;
-
- /** A pointer to the previous context in the linked list. */
- struct pm_context_node *prev;
-} pm_context_node_t;
-
-/** This is the type of a comment that we've found while parsing. */
-typedef enum {
- PM_COMMENT_INLINE,
- PM_COMMENT_EMBDOC
-} pm_comment_type_t;
-
-/**
- * This is a node in the linked list of comments that we've found while parsing.
- *
- * @extends pm_list_node_t
- */
-typedef struct pm_comment {
- /** The embedded base node. */
- pm_list_node_t node;
-
- /** The location of the comment in the source. */
- pm_location_t location;
-
- /** The type of comment that we've found. */
- pm_comment_type_t type;
-} pm_comment_t;
-
-/**
- * This is a node in the linked list of magic comments that we've found while
- * parsing.
- *
- * @extends pm_list_node_t
- */
-typedef struct {
- /** The embedded base node. */
- pm_list_node_t node;
-
- /** A pointer to the start of the key in the source. */
- const uint8_t *key_start;
-
- /** A pointer to the start of the value in the source. */
- const uint8_t *value_start;
-
- /** The length of the key in the source. */
- uint32_t key_length;
-
- /** The length of the value in the source. */
- uint32_t value_length;
-} pm_magic_comment_t;
-
-/**
- * When the encoding that is being used to parse the source is changed by prism,
- * we provide the ability here to call out to a user-defined function.
- */
-typedef void (*pm_encoding_changed_callback_t)(pm_parser_t *parser);
-
-/**
- * When you are lexing through a file, the lexer needs all of the information
- * that the parser additionally provides (for example, the local table). So if
- * you want to properly lex Ruby, you need to actually lex it in the context of
- * the parser. In order to provide this functionality, we optionally allow a
- * struct to be attached to the parser that calls back out to a user-provided
- * callback when each token is lexed.
- */
-typedef struct {
- /**
- * This opaque pointer is used to provide whatever information the user
- * deemed necessary to the callback. In our case we use it to pass the array
- * that the tokens get appended into.
- */
- void *data;
-
- /**
- * This is the callback that is called when a token is lexed. It is passed
- * the opaque data pointer, the parser, and the token that was lexed.
- */
- void (*callback)(void *data, pm_parser_t *parser, pm_token_t *token);
-} pm_lex_callback_t;
-
-/**
- * This struct represents a node in a linked list of scopes. Some scopes can see
- * into their parent scopes, while others cannot.
- */
-typedef struct pm_scope {
- /** The IDs of the locals in the given scope. */
- pm_constant_id_list_t locals;
-
- /** A pointer to the previous scope in the linked list. */
- struct pm_scope *previous;
-
- /**
- * A boolean indicating whether or not this scope can see into its parent.
- * If closed is true, then the scope cannot see into its parent.
- */
- bool closed;
-
- /**
- * A boolean indicating whether or not this scope has explicit parameters.
- * This is necessary to determine whether or not numbered parameters are
- * allowed.
- */
- bool explicit_params;
-
- /**
- * An integer indicating the number of numbered parameters on this scope.
- * This is necessary to determine if child blocks are allowed to use
- * numbered parameters, and to pass information to consumers of the AST
- * about how many numbered parameters exist.
- */
- uint8_t numbered_parameters;
-} pm_scope_t;
-
-/**
- * This struct represents the overall parser. It contains a reference to the
- * source file, as well as pointers that indicate where in the source it's
- * currently parsing. It also contains the most recent and current token that
- * it's considering.
- */
-struct pm_parser {
- /** The current state of the lexer. */
- pm_lex_state_t lex_state;
-
- /** Tracks the current nesting of (), [], and {}. */
- int enclosure_nesting;
-
- /**
- * Used to temporarily track the nesting of enclosures to determine if a {
- * is the beginning of a lambda following the parameters of a lambda.
- */
- int lambda_enclosure_nesting;
-
- /**
- * Used to track the nesting of braces to ensure we get the correct value
- * when we are interpolating blocks with braces.
- */
- int brace_nesting;
-
- /**
- * The stack used to determine if a do keyword belongs to the predicate of a
- * while, until, or for loop.
- */
- pm_state_stack_t do_loop_stack;
-
- /**
- * The stack used to determine if a do keyword belongs to the beginning of a
- * block.
- */
- pm_state_stack_t accepts_block_stack;
-
- /** A stack of lex modes. */
- struct {
- /** The current mode of the lexer. */
- pm_lex_mode_t *current;
-
- /** The stack of lexer modes. */
- pm_lex_mode_t stack[PM_LEX_STACK_SIZE];
-
- /** The current index into the lexer mode stack. */
- size_t index;
- } lex_modes;
-
- /** The pointer to the start of the source. */
- const uint8_t *start;
-
- /** The pointer to the end of the source. */
- const uint8_t *end;
-
- /** The previous token we were considering. */
- pm_token_t previous;
-
- /** The current token we're considering. */
- pm_token_t current;
-
- /**
- * This is a special field set on the parser when we need the parser to jump
- * to a specific location when lexing the next token, as opposed to just
- * using the end of the previous token. Normally this is NULL.
- */
- const uint8_t *next_start;
-
- /**
- * This field indicates the end of a heredoc whose identifier was found on
- * the current line. If another heredoc is found on the same line, then this
- * will be moved forward to the end of that heredoc. If no heredocs are
- * found on a line then this is NULL.
- */
- const uint8_t *heredoc_end;
-
- /** The list of comments that have been found while parsing. */
- pm_list_t comment_list;
-
- /** The list of magic comments that have been found while parsing. */
- pm_list_t magic_comment_list;
-
- /** The optional location of the __END__ keyword and its contents. */
- pm_location_t data_loc;
-
- /** The list of warnings that have been found while parsing. */
- pm_list_t warning_list;
-
- /** The list of errors that have been found while parsing. */
- pm_list_t error_list;
-
- /** The current local scope. */
- pm_scope_t *current_scope;
-
- /** The current parsing context. */
- pm_context_node_t *current_context;
-
- /**
- * The encoding functions for the current file is attached to the parser as
- * it's parsing so that it can change with a magic comment.
- */
- const pm_encoding_t *encoding;
-
- /**
- * When the encoding that is being used to parse the source is changed by
- * prism, we provide the ability here to call out to a user-defined
- * function.
- */
- pm_encoding_changed_callback_t encoding_changed_callback;
-
- /**
- * This pointer indicates where a comment must start if it is to be
- * considered an encoding comment.
- */
- const uint8_t *encoding_comment_start;
-
- /**
- * This is an optional callback that can be attached to the parser that will
- * be called whenever a new token is lexed by the parser.
- */
- pm_lex_callback_t *lex_callback;
-
- /**
- * This is the path of the file being parsed. We use the filepath when
- * constructing SourceFileNodes.
- */
- pm_string_t filepath_string;
-
- /**
- * This constant pool keeps all of the constants defined throughout the file
- * so that we can reference them later.
- */
- pm_constant_pool_t constant_pool;
-
- /** This is the list of newline offsets in the source file. */
- pm_newline_list_t newline_list;
-
- /**
- * We want to add a flag to integer nodes that indicates their base. We only
- * want to parse these once, but we don't have space on the token itself to
- * communicate this information. So we store it here and pass it through
- * when we find tokens that we need it for.
- */
- pm_node_flags_t integer_base;
-
- /**
- * This string is used to pass information from the lexer to the parser. It
- * is particularly necessary because of escape sequences.
- */
- pm_string_t current_string;
-
- /**
- * The line number at the start of the parse. This will be used to offset
- * the line numbers of all of the locations.
- */
- int32_t start_line;
-
- /**
- * When a string-like expression is being lexed, any byte or escape sequence
- * that resolves to a value whose top bit is set (i.e., >= 0x80) will
- * explicitly set the encoding to the same encoding as the source.
- * Alternatively, if a unicode escape sequence is used (e.g., \\u{80}) that
- * resolves to a value whose top bit is set, then the encoding will be
- * explicitly set to UTF-8.
- *
- * The _next_ time this happens, if the encoding that is about to become the
- * explicitly set encoding does not match the previously set explicit
- * encoding, a mixed encoding error will be emitted.
- *
- * When the expression is finished being lexed, the explicit encoding
- * controls the encoding of the expression. For the most part this means
- * that the expression will either be encoded in the source encoding or
- * UTF-8. This holds for all encodings except US-ASCII. If the source is
- * US-ASCII and an explicit encoding was set that was _not_ UTF-8, then the
- * expression will be encoded as ASCII-8BIT.
- *
- * Note that if the expression is a list, different elements within the same
- * list can have different encodings, so this will get reset between each
- * element. Furthermore all of this only applies to lists that support
- * interpolation, because otherwise escapes that could change the encoding
- * are ignored.
- *
- * At first glance, it may make more sense for this to live on the lexer
- * mode, but we need it here to communicate back to the parser for character
- * literals that do not push a new lexer mode.
- */
- const pm_encoding_t *explicit_encoding;
-
- /** Whether or not we're at the beginning of a command. */
- bool command_start;
-
- /** Whether or not we're currently recovering from a syntax error. */
- bool recovering;
-
- /**
- * Whether or not the encoding has been changed by a magic comment. We use
- * this to provide a fast path for the lexer instead of going through the
- * function pointer.
- */
- bool encoding_changed;
-
- /**
- * This flag indicates that we are currently parsing a pattern matching
- * expression and impacts that calculation of newlines.
- */
- bool pattern_matching_newlines;
-
- /** This flag indicates that we are currently parsing a keyword argument. */
- bool in_keyword_arg;
-
- /** The current parameter name id on parsing its default value. */
- pm_constant_id_t current_param_name;
-
- /**
- * Whether or not the parser has seen a token that has semantic meaning
- * (i.e., a token that is not a comment or whitespace).
- */
- bool semantic_token_seen;
-
- /**
- * Whether or not we have found a frozen_string_literal magic comment with
- * a true value.
- */
- bool frozen_string_literal;
-
- /**
- * Whether or not we should emit warnings. This will be set to false if the
- * consumer of the library specified it, usually because they are parsing
- * when $VERBOSE is nil.
- */
- bool suppress_warnings;
-};
-
-#endif
diff --git a/prism/prettyprint.h b/prism/prettyprint.h
deleted file mode 100644
index 351b92df39..0000000000
--- a/prism/prettyprint.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @file prettyprint.h
- *
- * An AST node pretty-printer.
- */
-#ifndef PRISM_PRETTYPRINT_H
-#define PRISM_PRETTYPRINT_H
-
-#include "prism/defines.h"
-
-#include <stdio.h>
-
-#include "prism/ast.h"
-#include "prism/parser.h"
-#include "prism/util/pm_buffer.h"
-
-/**
- * Pretty-prints the AST represented by the given node to the given buffer.
- *
- * @param output_buffer The buffer to write the pretty-printed AST to.
- * @param parser The parser that parsed the AST.
- * @param node The root node of the AST to pretty-print.
- */
-PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node);
-
-#endif
diff --git a/prism/prism.c b/prism/prism.c
deleted file mode 100644
index 79258386d6..0000000000
--- a/prism/prism.c
+++ /dev/null
@@ -1,17486 +0,0 @@
-#include "prism.h"
-
-/**
- * The prism version and the serialization format.
- */
-const char *
-pm_version(void) {
- return PRISM_VERSION;
-}
-
-/**
- * In heredocs, tabs automatically complete up to the next 8 spaces. This is
- * defined in CRuby as TAB_WIDTH.
- */
-#define PM_TAB_WHITESPACE_SIZE 8
-
-#ifndef PM_DEBUG_LOGGING
-/**
- * Debugging logging will provide you with additional debugging functions as
- * well as automatically replace some functions with their debugging
- * counterparts.
- */
-#define PM_DEBUG_LOGGING 0
-#endif
-
-#if PM_DEBUG_LOGGING
-
-/******************************************************************************/
-/* Debugging */
-/******************************************************************************/
-
-PRISM_ATTRIBUTE_UNUSED static const char *
-debug_context(pm_context_t context) {
- switch (context) {
- case PM_CONTEXT_BEGIN: return "BEGIN";
- case PM_CONTEXT_CLASS: return "CLASS";
- case PM_CONTEXT_CASE_IN: return "CASE_IN";
- case PM_CONTEXT_CASE_WHEN: return "CASE_WHEN";
- case PM_CONTEXT_DEF: return "DEF";
- case PM_CONTEXT_DEF_PARAMS: return "DEF_PARAMS";
- case PM_CONTEXT_DEFAULT_PARAMS: return "DEFAULT_PARAMS";
- case PM_CONTEXT_ENSURE: return "ENSURE";
- case PM_CONTEXT_ENSURE_DEF: return "ENSURE_DEF";
- case PM_CONTEXT_ELSE: return "ELSE";
- case PM_CONTEXT_ELSIF: return "ELSIF";
- case PM_CONTEXT_EMBEXPR: return "EMBEXPR";
- case PM_CONTEXT_BLOCK_BRACES: return "BLOCK_BRACES";
- case PM_CONTEXT_BLOCK_KEYWORDS: return "BLOCK_KEYWORDS";
- case PM_CONTEXT_FOR: return "FOR";
- case PM_CONTEXT_FOR_INDEX: return "FOR_INDEX";
- case PM_CONTEXT_IF: return "IF";
- case PM_CONTEXT_MAIN: return "MAIN";
- case PM_CONTEXT_MODULE: return "MODULE";
- case PM_CONTEXT_PARENS: return "PARENS";
- case PM_CONTEXT_POSTEXE: return "POSTEXE";
- case PM_CONTEXT_PREDICATE: return "PREDICATE";
- case PM_CONTEXT_PREEXE: return "PREEXE";
- case PM_CONTEXT_RESCUE: return "RESCUE";
- case PM_CONTEXT_RESCUE_ELSE: return "RESCUE_ELSE";
- case PM_CONTEXT_RESCUE_ELSE_DEF: return "RESCUE_ELSE_DEF";
- case PM_CONTEXT_RESCUE_DEF: return "RESCUE_DEF";
- case PM_CONTEXT_SCLASS: return "SCLASS";
- case PM_CONTEXT_UNLESS: return "UNLESS";
- case PM_CONTEXT_UNTIL: return "UNTIL";
- case PM_CONTEXT_WHILE: return "WHILE";
- case PM_CONTEXT_LAMBDA_BRACES: return "LAMBDA_BRACES";
- case PM_CONTEXT_LAMBDA_DO_END: return "LAMBDA_DO_END";
- }
- return NULL;
-}
-
-PRISM_ATTRIBUTE_UNUSED static void
-debug_contexts(pm_parser_t *parser) {
- pm_context_node_t *context_node = parser->current_context;
- fprintf(stderr, "CONTEXTS: ");
-
- if (context_node != NULL) {
- while (context_node != NULL) {
- fprintf(stderr, "%s", debug_context(context_node->context));
- context_node = context_node->prev;
- if (context_node != NULL) {
- fprintf(stderr, " <- ");
- }
- }
- } else {
- fprintf(stderr, "NONE");
- }
-
- fprintf(stderr, "\n");
-}
-
-PRISM_ATTRIBUTE_UNUSED static void
-debug_node(const pm_parser_t *parser, const pm_node_t *node) {
- pm_buffer_t output_buffer = { 0 };
- pm_prettyprint(&output_buffer, parser, node);
-
- fprintf(stderr, "%.*s", (int) output_buffer.length, output_buffer.value);
- pm_buffer_free(&output_buffer);
-}
-
-PRISM_ATTRIBUTE_UNUSED static void
-debug_lex_mode(pm_parser_t *parser) {
- pm_lex_mode_t *lex_mode = parser->lex_modes.current;
- bool first = true;
-
- while (lex_mode != NULL) {
- if (first) {
- first = false;
- } else {
- fprintf(stderr, " <- ");
- }
-
- switch (lex_mode->mode) {
- case PM_LEX_DEFAULT: fprintf(stderr, "DEFAULT"); break;
- case PM_LEX_EMBEXPR: fprintf(stderr, "EMBEXPR"); break;
- case PM_LEX_EMBVAR: fprintf(stderr, "EMBVAR"); break;
- case PM_LEX_HEREDOC: fprintf(stderr, "HEREDOC"); break;
- case PM_LEX_LIST: fprintf(stderr, "LIST (terminator=%c, interpolation=%d)", lex_mode->as.list.terminator, lex_mode->as.list.interpolation); break;
- case PM_LEX_REGEXP: fprintf(stderr, "REGEXP (terminator=%c)", lex_mode->as.regexp.terminator); break;
- case PM_LEX_STRING: fprintf(stderr, "STRING (terminator=%c, interpolation=%d)", lex_mode->as.string.terminator, lex_mode->as.string.interpolation); break;
- }
-
- lex_mode = lex_mode->prev;
- }
-
- fprintf(stderr, "\n");
-}
-
-PRISM_ATTRIBUTE_UNUSED static void
-debug_state(pm_parser_t *parser) {
- fprintf(stderr, "STATE: ");
- bool first = true;
-
- if (parser->lex_state == PM_LEX_STATE_NONE) {
- fprintf(stderr, "NONE\n");
- return;
- }
-
-#define CHECK_STATE(state) \
- if (parser->lex_state & state) { \
- if (!first) fprintf(stderr, "|"); \
- fprintf(stderr, "%s", #state); \
- first = false; \
- }
-
- CHECK_STATE(PM_LEX_STATE_BEG)
- CHECK_STATE(PM_LEX_STATE_END)
- CHECK_STATE(PM_LEX_STATE_ENDARG)
- CHECK_STATE(PM_LEX_STATE_ENDFN)
- CHECK_STATE(PM_LEX_STATE_ARG)
- CHECK_STATE(PM_LEX_STATE_CMDARG)
- CHECK_STATE(PM_LEX_STATE_MID)
- CHECK_STATE(PM_LEX_STATE_FNAME)
- CHECK_STATE(PM_LEX_STATE_DOT)
- CHECK_STATE(PM_LEX_STATE_CLASS)
- CHECK_STATE(PM_LEX_STATE_LABEL)
- CHECK_STATE(PM_LEX_STATE_LABELED)
- CHECK_STATE(PM_LEX_STATE_FITEM)
-
-#undef CHECK_STATE
-
- fprintf(stderr, "\n");
-}
-
-PRISM_ATTRIBUTE_UNUSED static void
-debug_token(pm_token_t * token) {
- fprintf(stderr, "%s: \"%.*s\"\n", pm_token_type_to_str(token->type), (int) (token->end - token->start), token->start);
-}
-
-#endif
-
-// Macros for min/max.
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-/******************************************************************************/
-/* Lex mode manipulations */
-/******************************************************************************/
-
-/**
- * Returns the incrementor character that should be used to increment the
- * nesting count if one is possible.
- */
-static inline uint8_t
-lex_mode_incrementor(const uint8_t start) {
- switch (start) {
- case '(':
- case '[':
- case '{':
- case '<':
- return start;
- default:
- return '\0';
- }
-}
-
-/**
- * Returns the matching character that should be used to terminate a list
- * beginning with the given character.
- */
-static inline uint8_t
-lex_mode_terminator(const uint8_t start) {
- switch (start) {
- case '(':
- return ')';
- case '[':
- return ']';
- case '{':
- return '}';
- case '<':
- return '>';
- default:
- return start;
- }
-}
-
-/**
- * Push a new lex state onto the stack. If we're still within the pre-allocated
- * space of the lex state stack, then we'll just use a new slot. Otherwise we'll
- * allocate a new pointer and use that.
- */
-static bool
-lex_mode_push(pm_parser_t *parser, pm_lex_mode_t lex_mode) {
- lex_mode.prev = parser->lex_modes.current;
- parser->lex_modes.index++;
-
- if (parser->lex_modes.index > PM_LEX_STACK_SIZE - 1) {
- parser->lex_modes.current = (pm_lex_mode_t *) malloc(sizeof(pm_lex_mode_t));
- if (parser->lex_modes.current == NULL) return false;
-
- *parser->lex_modes.current = lex_mode;
- } else {
- parser->lex_modes.stack[parser->lex_modes.index] = lex_mode;
- parser->lex_modes.current = &parser->lex_modes.stack[parser->lex_modes.index];
- }
-
- return true;
-}
-
-/**
- * Push on a new list lex mode.
- */
-static inline bool
-lex_mode_push_list(pm_parser_t *parser, bool interpolation, uint8_t delimiter) {
- uint8_t incrementor = lex_mode_incrementor(delimiter);
- uint8_t terminator = lex_mode_terminator(delimiter);
-
- pm_lex_mode_t lex_mode = {
- .mode = PM_LEX_LIST,
- .as.list = {
- .nesting = 0,
- .interpolation = interpolation,
- .incrementor = incrementor,
- .terminator = terminator
- }
- };
-
- // These are the places where we need to split up the content of the list.
- // We'll use strpbrk to find the first of these characters.
- uint8_t *breakpoints = lex_mode.as.list.breakpoints;
- memcpy(breakpoints, "\\ \t\f\r\v\n\0\0\0", sizeof(lex_mode.as.list.breakpoints));
-
- // Now we'll add the terminator to the list of breakpoints.
- size_t index = 7;
- breakpoints[index++] = terminator;
-
- // If interpolation is allowed, then we're going to check for the #
- // character. Otherwise we'll only look for escapes and the terminator.
- if (interpolation) {
- breakpoints[index++] = '#';
- }
-
- // If there is an incrementor, then we'll check for that as well.
- if (incrementor != '\0') {
- breakpoints[index++] = incrementor;
- }
-
- parser->explicit_encoding = NULL;
- return lex_mode_push(parser, lex_mode);
-}
-
-/**
- * Push on a new list lex mode that is only used for compatibility. This is
- * called when we're at the end of the file. We want the parser to be able to
- * perform its normal error tolerance.
- */
-static inline bool
-lex_mode_push_list_eof(pm_parser_t *parser) {
- return lex_mode_push_list(parser, false, '\0');
-}
-
-/**
- * Push on a new regexp lex mode.
- */
-static inline bool
-lex_mode_push_regexp(pm_parser_t *parser, uint8_t incrementor, uint8_t terminator) {
- pm_lex_mode_t lex_mode = {
- .mode = PM_LEX_REGEXP,
- .as.regexp = {
- .nesting = 0,
- .incrementor = incrementor,
- .terminator = terminator
- }
- };
-
- // These are the places where we need to split up the content of the
- // regular expression. We'll use strpbrk to find the first of these
- // characters.
- uint8_t *breakpoints = lex_mode.as.regexp.breakpoints;
- memcpy(breakpoints, "\n\\#\0\0", sizeof(lex_mode.as.regexp.breakpoints));
-
- // First we'll add the terminator.
- breakpoints[3] = terminator;
-
- // Next, if there is an incrementor, then we'll check for that as well.
- if (incrementor != '\0') {
- breakpoints[4] = incrementor;
- }
-
- return lex_mode_push(parser, lex_mode);
-}
-
-/**
- * Push on a new string lex mode.
- */
-static inline bool
-lex_mode_push_string(pm_parser_t *parser, bool interpolation, bool label_allowed, uint8_t incrementor, uint8_t terminator) {
- pm_lex_mode_t lex_mode = {
- .mode = PM_LEX_STRING,
- .as.string = {
- .nesting = 0,
- .interpolation = interpolation,
- .label_allowed = label_allowed,
- .incrementor = incrementor,
- .terminator = terminator
- }
- };
-
- // These are the places where we need to split up the content of the
- // string. We'll use strpbrk to find the first of these characters.
- uint8_t *breakpoints = lex_mode.as.string.breakpoints;
- memcpy(breakpoints, "\n\\\0\0\0", sizeof(lex_mode.as.string.breakpoints));
-
- // Now add in the terminator.
- size_t index = 2;
- breakpoints[index++] = terminator;
-
- // If interpolation is allowed, then we're going to check for the #
- // character. Otherwise we'll only look for escapes and the terminator.
- if (interpolation) {
- breakpoints[index++] = '#';
- }
-
- // If we have an incrementor, then we'll add that in as a breakpoint as
- // well.
- if (incrementor != '\0') {
- breakpoints[index++] = incrementor;
- }
-
- parser->explicit_encoding = NULL;
- return lex_mode_push(parser, lex_mode);
-}
-
-/**
- * Push on a new string lex mode that is only used for compatibility. This is
- * called when we're at the end of the file. We want the parser to be able to
- * perform its normal error tolerance.
- */
-static inline bool
-lex_mode_push_string_eof(pm_parser_t *parser) {
- return lex_mode_push_string(parser, false, false, '\0', '\0');
-}
-
-/**
- * Pop the current lex state off the stack. If we're within the pre-allocated
- * space of the lex state stack, then we'll just decrement the index. Otherwise
- * we'll free the current pointer and use the previous pointer.
- */
-static void
-lex_mode_pop(pm_parser_t *parser) {
- if (parser->lex_modes.index == 0) {
- parser->lex_modes.current->mode = PM_LEX_DEFAULT;
- } else if (parser->lex_modes.index < PM_LEX_STACK_SIZE) {
- parser->lex_modes.index--;
- parser->lex_modes.current = &parser->lex_modes.stack[parser->lex_modes.index];
- } else {
- parser->lex_modes.index--;
- pm_lex_mode_t *prev = parser->lex_modes.current->prev;
- free(parser->lex_modes.current);
- parser->lex_modes.current = prev;
- }
-}
-
-/**
- * This is the equivalent of IS_lex_state is CRuby.
- */
-static inline bool
-lex_state_p(pm_parser_t *parser, pm_lex_state_t state) {
- return parser->lex_state & state;
-}
-
-typedef enum {
- PM_IGNORED_NEWLINE_NONE = 0,
- PM_IGNORED_NEWLINE_ALL,
- PM_IGNORED_NEWLINE_PATTERN
-} pm_ignored_newline_type_t;
-
-static inline pm_ignored_newline_type_t
-lex_state_ignored_p(pm_parser_t *parser) {
- bool ignored = lex_state_p(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_CLASS | PM_LEX_STATE_FNAME | PM_LEX_STATE_DOT) && !lex_state_p(parser, PM_LEX_STATE_LABELED);
-
- if (ignored) {
- return PM_IGNORED_NEWLINE_ALL;
- } else if ((parser->lex_state & ~((unsigned int) PM_LEX_STATE_LABEL)) == (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)) {
- return PM_IGNORED_NEWLINE_PATTERN;
- } else {
- return PM_IGNORED_NEWLINE_NONE;
- }
-}
-
-static inline bool
-lex_state_beg_p(pm_parser_t *parser) {
- return lex_state_p(parser, PM_LEX_STATE_BEG_ANY) || ((parser->lex_state & (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)) == (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED));
-}
-
-static inline bool
-lex_state_arg_p(pm_parser_t *parser) {
- return lex_state_p(parser, PM_LEX_STATE_ARG_ANY);
-}
-
-static inline bool
-lex_state_spcarg_p(pm_parser_t *parser, bool space_seen) {
- if (parser->current.end >= parser->end) {
- return false;
- }
- return lex_state_arg_p(parser) && space_seen && !pm_char_is_whitespace(*parser->current.end);
-}
-
-static inline bool
-lex_state_end_p(pm_parser_t *parser) {
- return lex_state_p(parser, PM_LEX_STATE_END_ANY);
-}
-
-/**
- * This is the equivalent of IS_AFTER_OPERATOR in CRuby.
- */
-static inline bool
-lex_state_operator_p(pm_parser_t *parser) {
- return lex_state_p(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_DOT);
-}
-
-/**
- * Set the state of the lexer. This is defined as a function to be able to put a
- * breakpoint in it.
- */
-static inline void
-lex_state_set(pm_parser_t *parser, pm_lex_state_t state) {
- parser->lex_state = state;
-}
-
-#if PM_DEBUG_LOGGING
-static inline void
-debug_lex_state_set(pm_parser_t *parser, pm_lex_state_t state, char const * caller_name, int line_number) {
- fprintf(stderr, "Caller: %s:%d\nPrevious: ", caller_name, line_number);
- debug_state(parser);
- lex_state_set(parser, state);
- fprintf(stderr, "Now: ");
- debug_state(parser);
- fprintf(stderr, "\n");
-}
-
-#define lex_state_set(parser, state) debug_lex_state_set(parser, state, __func__, __LINE__)
-#endif
-
-/******************************************************************************/
-/* Diagnostic-related functions */
-/******************************************************************************/
-
-/**
- * Append an error to the list of errors on the parser.
- */
-static inline void
-pm_parser_err(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) {
- pm_diagnostic_list_append(&parser->error_list, start, end, diag_id);
-}
-
-/**
- * Append an error to the list of errors on the parser using a format string.
- */
-#define PM_PARSER_ERR_FORMAT(parser, start, end, diag_id, ...) pm_diagnostic_list_append_format(&parser->error_list, start, end, diag_id, __VA_ARGS__)
-
-/**
- * Append an error to the list of errors on the parser using the location of the
- * current token.
- */
-static inline void
-pm_parser_err_current(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
- pm_parser_err(parser, parser->current.start, parser->current.end, diag_id);
-}
-
-/**
- * Append an error to the list of errors on the parser using the given location
- * using a format string.
- */
-#define PM_PARSER_ERR_LOCATION_FORMAT(parser, location, diag_id, ...) pm_diagnostic_list_append_format(&parser->error_list, (location)->start, (location)->end, diag_id, __VA_ARGS__)
-
-/**
- * Append an error to the list of errors on the parser using the location of the
- * given node.
- */
-static inline void
-pm_parser_err_node(pm_parser_t *parser, const pm_node_t *node, pm_diagnostic_id_t diag_id) {
- pm_parser_err(parser, node->location.start, node->location.end, diag_id);
-}
-
-/**
- * Append an error to the list of errors on the parser using the location of the
- * given node and a format string.
- */
-#define PM_PARSER_ERR_NODE_FORMAT(parser, node, diag_id, ...) pm_diagnostic_list_append_format(&parser->error_list, node->location.start, node->location.end, diag_id, __VA_ARGS__)
-
-/**
- * Append an error to the list of errors on the parser using the location of the
- * previous token.
- */
-static inline void
-pm_parser_err_previous(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
- pm_parser_err(parser, parser->previous.start, parser->previous.end, diag_id);
-}
-
-/**
- * Append an error to the list of errors on the parser using the location of the
- * given token.
- */
-static inline void
-pm_parser_err_token(pm_parser_t *parser, const pm_token_t *token, pm_diagnostic_id_t diag_id) {
- pm_parser_err(parser, token->start, token->end, diag_id);
-}
-
-/**
- * Append an error to the list of errors on the parser using the location of the
- * given token and a format string.
- */
-#define PM_PARSER_ERR_TOKEN_FORMAT(parser, token, diag_id, ...) pm_diagnostic_list_append_format(&parser->error_list, (token).start, (token).end, diag_id, __VA_ARGS__)
-
-/**
- * Append a warning to the list of warnings on the parser.
- */
-static inline void
-pm_parser_warn(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) {
- if (!parser->suppress_warnings) {
- pm_diagnostic_list_append(&parser->warning_list, start, end, diag_id);
- }
-}
-
-/**
- * Append a warning to the list of warnings on the parser using the location of
- * the given token.
- */
-static inline void
-pm_parser_warn_token(pm_parser_t *parser, const pm_token_t *token, pm_diagnostic_id_t diag_id) {
- pm_parser_warn(parser, token->start, token->end, diag_id);
-}
-
-/******************************************************************************/
-/* Node-related functions */
-/******************************************************************************/
-
-/**
- * Retrieve the constant pool id for the given location.
- */
-static inline pm_constant_id_t
-pm_parser_constant_id_location(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- return pm_constant_pool_insert_shared(&parser->constant_pool, start, (size_t) (end - start));
-}
-
-/**
- * Retrieve the constant pool id for the given string.
- */
-static inline pm_constant_id_t
-pm_parser_constant_id_owned(pm_parser_t *parser, const uint8_t *start, size_t length) {
- return pm_constant_pool_insert_owned(&parser->constant_pool, start, length);
-}
-
-/**
- * Retrieve the constant pool id for the given static literal C string.
- */
-static inline pm_constant_id_t
-pm_parser_constant_id_constant(pm_parser_t *parser, const char *start, size_t length) {
- return pm_constant_pool_insert_constant(&parser->constant_pool, (const uint8_t *) start, length);
-}
-
-/**
- * Retrieve the constant pool id for the given token.
- */
-static inline pm_constant_id_t
-pm_parser_constant_id_token(pm_parser_t *parser, const pm_token_t *token) {
- return pm_parser_constant_id_location(parser, token->start, token->end);
-}
-
-/**
- * Retrieve the constant pool id for the given token. If the token is not
- * provided, then return 0.
- */
-static inline pm_constant_id_t
-pm_parser_optional_constant_id_token(pm_parser_t *parser, const pm_token_t *token) {
- return token->type == PM_TOKEN_NOT_PROVIDED ? 0 : pm_parser_constant_id_token(parser, token);
-}
-
-/**
- * Check whether or not the given node is value expression.
- * If the node is value node, it returns NULL.
- * If not, it returns the pointer to the node to be inspected as "void expression".
- */
-static pm_node_t*
-pm_check_value_expression(pm_node_t *node) {
- pm_node_t* void_node = NULL;
-
- while (node != NULL) {
- switch (PM_NODE_TYPE(node)) {
- case PM_RETURN_NODE:
- case PM_BREAK_NODE:
- case PM_NEXT_NODE:
- case PM_REDO_NODE:
- case PM_RETRY_NODE:
- case PM_MATCH_REQUIRED_NODE:
- return void_node != NULL ? void_node : node;
- case PM_MATCH_PREDICATE_NODE:
- return NULL;
- case PM_BEGIN_NODE: {
- pm_begin_node_t *cast = (pm_begin_node_t *) node;
- node = (pm_node_t *) cast->statements;
- break;
- }
- case PM_PARENTHESES_NODE: {
- pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node;
- node = (pm_node_t *) cast->body;
- break;
- }
- case PM_STATEMENTS_NODE: {
- pm_statements_node_t *cast = (pm_statements_node_t *) node;
- node = cast->body.nodes[cast->body.size - 1];
- break;
- }
- case PM_IF_NODE: {
- pm_if_node_t *cast = (pm_if_node_t *) node;
- if (cast->statements == NULL || cast->consequent == NULL) {
- return NULL;
- }
- pm_node_t *vn = pm_check_value_expression((pm_node_t *) cast->statements);
- if (vn == NULL) {
- return NULL;
- }
- if (void_node == NULL) {
- void_node = vn;
- }
- node = cast->consequent;
- break;
- }
- case PM_UNLESS_NODE: {
- pm_unless_node_t *cast = (pm_unless_node_t *) node;
- if (cast->statements == NULL || cast->consequent == NULL) {
- return NULL;
- }
- pm_node_t *vn = pm_check_value_expression((pm_node_t *) cast->statements);
- if (vn == NULL) {
- return NULL;
- }
- if (void_node == NULL) {
- void_node = vn;
- }
- node = (pm_node_t *) cast->consequent;
- break;
- }
- case PM_ELSE_NODE: {
- pm_else_node_t *cast = (pm_else_node_t *) node;
- node = (pm_node_t *) cast->statements;
- break;
- }
- case PM_AND_NODE: {
- pm_and_node_t *cast = (pm_and_node_t *) node;
- node = cast->left;
- break;
- }
- case PM_OR_NODE: {
- pm_or_node_t *cast = (pm_or_node_t *) node;
- node = cast->left;
- break;
- }
- default:
- return NULL;
- }
- }
-
- return NULL;
-}
-
-static inline void
-pm_assert_value_expression(pm_parser_t *parser, pm_node_t *node) {
- pm_node_t *void_node = pm_check_value_expression(node);
- if (void_node != NULL) {
- pm_parser_err_node(parser, void_node, PM_ERR_VOID_EXPRESSION);
- }
-}
-
-/**
- * The predicate of conditional nodes can change what would otherwise be regular
- * nodes into specialized nodes. For example:
- *
- * if foo .. bar => RangeNode becomes FlipFlopNode
- * if foo and bar .. baz => RangeNode becomes FlipFlopNode
- * if /foo/ => RegularExpressionNode becomes MatchLastLineNode
- * if /foo #{bar}/ => InterpolatedRegularExpressionNode becomes InterpolatedMatchLastLineNode
- */
-static void
-pm_conditional_predicate(pm_node_t *node) {
- switch (PM_NODE_TYPE(node)) {
- case PM_AND_NODE: {
- pm_and_node_t *cast = (pm_and_node_t *) node;
- pm_conditional_predicate(cast->left);
- pm_conditional_predicate(cast->right);
- break;
- }
- case PM_OR_NODE: {
- pm_or_node_t *cast = (pm_or_node_t *) node;
- pm_conditional_predicate(cast->left);
- pm_conditional_predicate(cast->right);
- break;
- }
- case PM_PARENTHESES_NODE: {
- pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node;
-
- if ((cast->body != NULL) && PM_NODE_TYPE_P(cast->body, PM_STATEMENTS_NODE)) {
- pm_statements_node_t *statements = (pm_statements_node_t *) cast->body;
- if (statements->body.size == 1) pm_conditional_predicate(statements->body.nodes[0]);
- }
-
- break;
- }
- case PM_RANGE_NODE: {
- pm_range_node_t *cast = (pm_range_node_t *) node;
- if (cast->left) {
- pm_conditional_predicate(cast->left);
- }
- if (cast->right) {
- pm_conditional_predicate(cast->right);
- }
-
- // Here we change the range node into a flip flop node. We can do
- // this since the nodes are exactly the same except for the type.
- // We're only asserting against the size when we should probably
- // assert against the entire layout, but we'll assume tests will
- // catch this.
- assert(sizeof(pm_range_node_t) == sizeof(pm_flip_flop_node_t));
- node->type = PM_FLIP_FLOP_NODE;
-
- break;
- }
- case PM_REGULAR_EXPRESSION_NODE:
- // Here we change the regular expression node into a match last line
- // node. We can do this since the nodes are exactly the same except
- // for the type.
- assert(sizeof(pm_regular_expression_node_t) == sizeof(pm_match_last_line_node_t));
- node->type = PM_MATCH_LAST_LINE_NODE;
- break;
- case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE:
- // Here we change the interpolated regular expression node into an
- // interpolated match last line node. We can do this since the nodes
- // are exactly the same except for the type.
- assert(sizeof(pm_interpolated_regular_expression_node_t) == sizeof(pm_interpolated_match_last_line_node_t));
- node->type = PM_INTERPOLATED_MATCH_LAST_LINE_NODE;
- break;
- default:
- break;
- }
-}
-
-/**
- * In a lot of places in the tree you can have tokens that are not provided but
- * that do not cause an error. For example, in a method call without
- * parentheses. In these cases we set the token to the "not provided" type. For
- * example:
- *
- * pm_token_t token = not_provided(parser);
- */
-static inline pm_token_t
-not_provided(pm_parser_t *parser) {
- return (pm_token_t) { .type = PM_TOKEN_NOT_PROVIDED, .start = parser->start, .end = parser->start };
-}
-
-#define PM_LOCATION_NULL_VALUE(parser) ((pm_location_t) { .start = parser->start, .end = parser->start })
-#define PM_LOCATION_TOKEN_VALUE(token) ((pm_location_t) { .start = (token)->start, .end = (token)->end })
-#define PM_LOCATION_NODE_VALUE(node) ((pm_location_t) { .start = (node)->location.start, .end = (node)->location.end })
-#define PM_LOCATION_NODE_BASE_VALUE(node) ((pm_location_t) { .start = (node)->base.location.start, .end = (node)->base.location.end })
-#define PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE ((pm_location_t) { .start = NULL, .end = NULL })
-#define PM_OPTIONAL_LOCATION_TOKEN_VALUE(token) ((token)->type == PM_TOKEN_NOT_PROVIDED ? PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE : PM_LOCATION_TOKEN_VALUE(token))
-
-/**
- * This is a special out parameter to the parse_arguments_list function that
- * includes opening and closing parentheses in addition to the arguments since
- * it's so common. It is handy to use when passing argument information to one
- * of the call node creation functions.
- */
-typedef struct {
- /** The optional location of the opening parenthesis or bracket. */
- pm_location_t opening_loc;
-
- /** The lazily-allocated optional arguments node. */
- pm_arguments_node_t *arguments;
-
- /** The optional location of the closing parenthesis or bracket. */
- pm_location_t closing_loc;
-
- /** The optional block attached to the call. */
- pm_node_t *block;
-} pm_arguments_t;
-
-/**
- * Retrieve the end location of a `pm_arguments_t` object.
- */
-static inline const uint8_t *
-pm_arguments_end(pm_arguments_t *arguments) {
- if (arguments->block != NULL) {
- const uint8_t *end = arguments->block->location.end;
- if (arguments->closing_loc.start != NULL && arguments->closing_loc.end > end) {
- end = arguments->closing_loc.end;
- }
- return end;
- }
- if (arguments->closing_loc.start != NULL) {
- return arguments->closing_loc.end;
- }
- if (arguments->arguments != NULL) {
- return arguments->arguments->base.location.end;
- }
- return arguments->closing_loc.end;
-}
-
-/**
- * Check that we're not about to attempt to attach a brace block to a call that
- * has arguments without parentheses.
- */
-static void
-pm_arguments_validate_block(pm_parser_t *parser, pm_arguments_t *arguments, pm_block_node_t *block) {
- // First, check that we have arguments and that we don't have a closing
- // location for them.
- if (arguments->arguments == NULL || arguments->closing_loc.start != NULL) {
- return;
- }
-
- // Next, check that we don't have a single parentheses argument. This would
- // look like:
- //
- // foo (1) {}
- //
- // In this case, it's actually okay for the block to be attached to the
- // call, even though it looks like it's attached to the argument.
- if (arguments->arguments->arguments.size == 1 && PM_NODE_TYPE_P(arguments->arguments->arguments.nodes[0], PM_PARENTHESES_NODE)) {
- return;
- }
-
- // If we didn't hit a case before this check, then at this point we need to
- // add a syntax error.
- pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_UNEXPECTED_BLOCK);
-}
-
-/******************************************************************************/
-/* Node flag handling functions */
-/******************************************************************************/
-
-/**
- * Set the given flag on the given node.
- */
-static inline void
-pm_node_flag_set(pm_node_t *node, pm_node_flags_t flag) {
- node->flags |= flag;
-}
-
-/**
- * Remove the given flag from the given node.
- */
-static inline void
-pm_node_flag_unset(pm_node_t *node, pm_node_flags_t flag) {
- node->flags &= (pm_node_flags_t) ~flag;
-}
-
-
-/******************************************************************************/
-/* Node creation functions */
-/******************************************************************************/
-
-/**
- * Parse the decimal number represented by the range of bytes. returns
- * UINT32_MAX if the number fails to parse. This function assumes that the range
- * of bytes has already been validated to contain only decimal digits.
- */
-static uint32_t
-parse_decimal_number(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- ptrdiff_t diff = end - start;
- assert(diff > 0 && ((unsigned long) diff < SIZE_MAX));
- size_t length = (size_t) diff;
-
- char *digits = calloc(length + 1, sizeof(char));
- memcpy(digits, start, length);
- digits[length] = '\0';
-
- char *endptr;
- errno = 0;
- unsigned long value = strtoul(digits, &endptr, 10);
-
- if ((digits == endptr) || (*endptr != '\0') || (errno == ERANGE)) {
- pm_parser_err(parser, start, end, PM_ERR_INVALID_NUMBER_DECIMAL);
- value = UINT32_MAX;
- }
-
- free(digits);
-
- if (value > UINT32_MAX) {
- pm_parser_err(parser, start, end, PM_ERR_INVALID_NUMBER_DECIMAL);
- value = UINT32_MAX;
- }
-
- return (uint32_t) value;
-}
-
-/**
- * When you have an encoding flag on a regular expression, it takes precedence
- * over all of the previously set encoding flags. So we need to mask off any
- * previously set encoding flags before setting the new one.
- */
-#define PM_REGULAR_EXPRESSION_ENCODING_MASK ~(PM_REGULAR_EXPRESSION_FLAGS_EUC_JP | PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT | PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J | PM_REGULAR_EXPRESSION_FLAGS_UTF_8)
-
-/**
- * Parse out the options for a regular expression.
- */
-static inline pm_node_flags_t
-pm_regular_expression_flags_create(const pm_token_t *closing) {
- pm_node_flags_t flags = 0;
-
- if (closing->type == PM_TOKEN_REGEXP_END) {
- for (const uint8_t *flag = closing->start + 1; flag < closing->end; flag++) {
- switch (*flag) {
- case 'i': flags |= PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE; break;
- case 'm': flags |= PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE; break;
- case 'x': flags |= PM_REGULAR_EXPRESSION_FLAGS_EXTENDED; break;
- case 'o': flags |= PM_REGULAR_EXPRESSION_FLAGS_ONCE; break;
-
- case 'e': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_EUC_JP); break;
- case 'n': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT); break;
- case 's': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J); break;
- case 'u': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_UTF_8); break;
-
- default: assert(false && "unreachable");
- }
- }
- }
-
- return flags;
-}
-
-#undef PM_REGULAR_EXPRESSION_ENCODING_MASK
-
-static pm_statements_node_t *
-pm_statements_node_create(pm_parser_t *parser);
-
-static void
-pm_statements_node_body_append(pm_statements_node_t *node, pm_node_t *statement);
-
-static size_t
-pm_statements_node_body_length(pm_statements_node_t *node);
-
-/**
- * This function is here to allow us a place to extend in the future when we
- * implement our own arena allocation.
- */
-static inline void *
-pm_alloc_node(PRISM_ATTRIBUTE_UNUSED pm_parser_t *parser, size_t size) {
- void *memory = calloc(1, size);
- if (memory == NULL) {
- fprintf(stderr, "Failed to allocate %zu bytes\n", size);
- abort();
- }
- return memory;
-}
-
-#define PM_ALLOC_NODE(parser, type) (type *) pm_alloc_node(parser, sizeof(type))
-
-/**
- * Allocate a new MissingNode node.
- */
-static pm_missing_node_t *
-pm_missing_node_create(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- pm_missing_node_t *node = PM_ALLOC_NODE(parser, pm_missing_node_t);
- *node = (pm_missing_node_t) {{ .type = PM_MISSING_NODE, .location = { .start = start, .end = end } }};
- return node;
-}
-
-/**
- * Allocate and initialize a new AliasGlobalVariableNode node.
- */
-static pm_alias_global_variable_node_t *
-pm_alias_global_variable_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *new_name, pm_node_t *old_name) {
- assert(keyword->type == PM_TOKEN_KEYWORD_ALIAS);
- pm_alias_global_variable_node_t *node = PM_ALLOC_NODE(parser, pm_alias_global_variable_node_t);
-
- *node = (pm_alias_global_variable_node_t) {
- {
- .type = PM_ALIAS_GLOBAL_VARIABLE_NODE,
- .location = {
- .start = keyword->start,
- .end = old_name->location.end
- },
- },
- .new_name = new_name,
- .old_name = old_name,
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new AliasMethodNode node.
- */
-static pm_alias_method_node_t *
-pm_alias_method_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *new_name, pm_node_t *old_name) {
- assert(keyword->type == PM_TOKEN_KEYWORD_ALIAS);
- pm_alias_method_node_t *node = PM_ALLOC_NODE(parser, pm_alias_method_node_t);
-
- *node = (pm_alias_method_node_t) {
- {
- .type = PM_ALIAS_METHOD_NODE,
- .location = {
- .start = keyword->start,
- .end = old_name->location.end
- },
- },
- .new_name = new_name,
- .old_name = old_name,
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate a new AlternationPatternNode node.
- */
-static pm_alternation_pattern_node_t *
-pm_alternation_pattern_node_create(pm_parser_t *parser, pm_node_t *left, pm_node_t *right, const pm_token_t *operator) {
- pm_alternation_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_alternation_pattern_node_t);
-
- *node = (pm_alternation_pattern_node_t) {
- {
- .type = PM_ALTERNATION_PATTERN_NODE,
- .location = {
- .start = left->location.start,
- .end = right->location.end
- },
- },
- .left = left,
- .right = right,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new and node.
- */
-static pm_and_node_t *
-pm_and_node_create(pm_parser_t *parser, pm_node_t *left, const pm_token_t *operator, pm_node_t *right) {
- pm_assert_value_expression(parser, left);
-
- pm_and_node_t *node = PM_ALLOC_NODE(parser, pm_and_node_t);
-
- *node = (pm_and_node_t) {
- {
- .type = PM_AND_NODE,
- .location = {
- .start = left->location.start,
- .end = right->location.end
- },
- },
- .left = left,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .right = right
- };
-
- return node;
-}
-
-/**
- * Allocate an initialize a new arguments node.
- */
-static pm_arguments_node_t *
-pm_arguments_node_create(pm_parser_t *parser) {
- pm_arguments_node_t *node = PM_ALLOC_NODE(parser, pm_arguments_node_t);
-
- *node = (pm_arguments_node_t) {
- {
- .type = PM_ARGUMENTS_NODE,
- .location = PM_LOCATION_NULL_VALUE(parser)
- },
- .arguments = { 0 }
- };
-
- return node;
-}
-
-/**
- * Return the size of the given arguments node.
- */
-static size_t
-pm_arguments_node_size(pm_arguments_node_t *node) {
- return node->arguments.size;
-}
-
-/**
- * Append an argument to an arguments node.
- */
-static void
-pm_arguments_node_arguments_append(pm_arguments_node_t *node, pm_node_t *argument) {
- if (pm_arguments_node_size(node) == 0) {
- node->base.location.start = argument->location.start;
- }
-
- node->base.location.end = argument->location.end;
- pm_node_list_append(&node->arguments, argument);
-}
-
-/**
- * Allocate and initialize a new ArrayNode node.
- */
-static pm_array_node_t *
-pm_array_node_create(pm_parser_t *parser, const pm_token_t *opening) {
- pm_array_node_t *node = PM_ALLOC_NODE(parser, pm_array_node_t);
-
- *node = (pm_array_node_t) {
- {
- .type = PM_ARRAY_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(opening)
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .elements = { 0 }
- };
-
- return node;
-}
-
-/**
- * Return the size of the given array node.
- */
-static inline size_t
-pm_array_node_size(pm_array_node_t *node) {
- return node->elements.size;
-}
-
-/**
- * Append an argument to an array node.
- */
-static inline void
-pm_array_node_elements_append(pm_array_node_t *node, pm_node_t *element) {
- if (!node->elements.size && !node->opening_loc.start) {
- node->base.location.start = element->location.start;
- }
-
- pm_node_list_append(&node->elements, element);
- node->base.location.end = element->location.end;
-
- // If the element is not a static literal, then the array is not a static
- // literal. Turn that flag off.
- if (PM_NODE_TYPE_P(element, PM_ARRAY_NODE) || PM_NODE_TYPE_P(element, PM_HASH_NODE) || PM_NODE_TYPE_P(element, PM_RANGE_NODE) || !PM_NODE_FLAG_P(element, PM_NODE_FLAG_STATIC_LITERAL)) {
- pm_node_flag_unset((pm_node_t *)node, PM_NODE_FLAG_STATIC_LITERAL);
- }
-
- if (PM_NODE_TYPE_P(element, PM_SPLAT_NODE)) {
- pm_node_flag_set((pm_node_t *)node, PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT);
- }
-}
-
-/**
- * Set the closing token and end location of an array node.
- */
-static void
-pm_array_node_close_set(pm_array_node_t *node, const pm_token_t *closing) {
- assert(closing->type == PM_TOKEN_BRACKET_RIGHT || closing->type == PM_TOKEN_STRING_END || closing->type == PM_TOKEN_MISSING || closing->type == PM_TOKEN_NOT_PROVIDED);
- node->base.location.end = closing->end;
- node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing);
-}
-
-/**
- * Allocate and initialize a new array pattern node. The node list given in the
- * nodes parameter is guaranteed to have at least two nodes.
- */
-static pm_array_pattern_node_t *
-pm_array_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *nodes) {
- pm_array_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_array_pattern_node_t);
-
- *node = (pm_array_pattern_node_t) {
- {
- .type = PM_ARRAY_PATTERN_NODE,
- .location = {
- .start = nodes->nodes[0]->location.start,
- .end = nodes->nodes[nodes->size - 1]->location.end
- },
- },
- .constant = NULL,
- .rest = NULL,
- .requireds = { 0 },
- .posts = { 0 },
- .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- // For now we're going to just copy over each pointer manually. This could be
- // much more efficient, as we could instead resize the node list.
- bool found_rest = false;
- for (size_t index = 0; index < nodes->size; index++) {
- pm_node_t *child = nodes->nodes[index];
-
- if (!found_rest && (PM_NODE_TYPE_P(child, PM_SPLAT_NODE) || PM_NODE_TYPE_P(child, PM_IMPLICIT_REST_NODE))) {
- node->rest = child;
- found_rest = true;
- } else if (found_rest) {
- pm_node_list_append(&node->posts, child);
- } else {
- pm_node_list_append(&node->requireds, child);
- }
- }
-
- return node;
-}
-
-/**
- * Allocate and initialize a new array pattern node from a single rest node.
- */
-static pm_array_pattern_node_t *
-pm_array_pattern_node_rest_create(pm_parser_t *parser, pm_node_t *rest) {
- pm_array_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_array_pattern_node_t);
-
- *node = (pm_array_pattern_node_t) {
- {
- .type = PM_ARRAY_PATTERN_NODE,
- .location = rest->location,
- },
- .constant = NULL,
- .rest = rest,
- .requireds = { 0 },
- .posts = { 0 },
- .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new array pattern node from a constant and opening
- * and closing tokens.
- */
-static pm_array_pattern_node_t *
-pm_array_pattern_node_constant_create(pm_parser_t *parser, pm_node_t *constant, const pm_token_t *opening, const pm_token_t *closing) {
- pm_array_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_array_pattern_node_t);
-
- *node = (pm_array_pattern_node_t) {
- {
- .type = PM_ARRAY_PATTERN_NODE,
- .location = {
- .start = constant->location.start,
- .end = closing->end
- },
- },
- .constant = constant,
- .rest = NULL,
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
- .requireds = { 0 },
- .posts = { 0 }
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new array pattern node from an opening and closing
- * token.
- */
-static pm_array_pattern_node_t *
-pm_array_pattern_node_empty_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) {
- pm_array_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_array_pattern_node_t);
-
- *node = (pm_array_pattern_node_t) {
- {
- .type = PM_ARRAY_PATTERN_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end
- },
- },
- .constant = NULL,
- .rest = NULL,
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
- .requireds = { 0 },
- .posts = { 0 }
- };
-
- return node;
-}
-
-static inline void
-pm_array_pattern_node_requireds_append(pm_array_pattern_node_t *node, pm_node_t *inner) {
- pm_node_list_append(&node->requireds, inner);
-}
-
-/**
- * Allocate and initialize a new assoc node.
- */
-static pm_assoc_node_t *
-pm_assoc_node_create(pm_parser_t *parser, pm_node_t *key, const pm_token_t *operator, pm_node_t *value) {
- pm_assoc_node_t *node = PM_ALLOC_NODE(parser, pm_assoc_node_t);
- const uint8_t *end;
-
- if (value != NULL) {
- end = value->location.end;
- } else if (operator->type != PM_TOKEN_NOT_PROVIDED) {
- end = operator->end;
- } else {
- end = key->location.end;
- }
-
- // If the key and value of this assoc node are both static literals, then
- // we can mark this node as a static literal.
- pm_node_flags_t flags = 0;
- if (value && !PM_NODE_TYPE_P(value, PM_ARRAY_NODE) && !PM_NODE_TYPE_P(value, PM_HASH_NODE) && !PM_NODE_TYPE_P(value, PM_RANGE_NODE)) {
- flags = key->flags & value->flags & PM_NODE_FLAG_STATIC_LITERAL;
- }
-
- *node = (pm_assoc_node_t) {
- {
- .type = PM_ASSOC_NODE,
- .flags = flags,
- .location = {
- .start = key->location.start,
- .end = end
- },
- },
- .key = key,
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new assoc splat node.
- */
-static pm_assoc_splat_node_t *
-pm_assoc_splat_node_create(pm_parser_t *parser, pm_node_t *value, const pm_token_t *operator) {
- assert(operator->type == PM_TOKEN_USTAR_STAR);
- pm_assoc_splat_node_t *node = PM_ALLOC_NODE(parser, pm_assoc_splat_node_t);
-
- *node = (pm_assoc_splat_node_t) {
- {
- .type = PM_ASSOC_SPLAT_NODE,
- .location = {
- .start = operator->start,
- .end = value == NULL ? operator->end : value->location.end
- },
- },
- .value = value,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate a new BackReferenceReadNode node.
- */
-static pm_back_reference_read_node_t *
-pm_back_reference_read_node_create(pm_parser_t *parser, const pm_token_t *name) {
- assert(name->type == PM_TOKEN_BACK_REFERENCE);
- pm_back_reference_read_node_t *node = PM_ALLOC_NODE(parser, pm_back_reference_read_node_t);
-
- *node = (pm_back_reference_read_node_t) {
- {
- .type = PM_BACK_REFERENCE_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(name),
- },
- .name = pm_parser_constant_id_token(parser, name)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize new a begin node.
- */
-static pm_begin_node_t *
-pm_begin_node_create(pm_parser_t *parser, const pm_token_t *begin_keyword, pm_statements_node_t *statements) {
- pm_begin_node_t *node = PM_ALLOC_NODE(parser, pm_begin_node_t);
-
- *node = (pm_begin_node_t) {
- {
- .type = PM_BEGIN_NODE,
- .location = {
- .start = begin_keyword->start,
- .end = statements == NULL ? begin_keyword->end : statements->base.location.end
- },
- },
- .begin_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(begin_keyword),
- .statements = statements,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-}
-
-/**
- * Set the rescue clause, optionally start, and end location of a begin node.
- */
-static void
-pm_begin_node_rescue_clause_set(pm_begin_node_t *node, pm_rescue_node_t *rescue_clause) {
- // If the begin keyword doesn't exist, we set the start on the begin_node
- if (!node->begin_keyword_loc.start) {
- node->base.location.start = rescue_clause->base.location.start;
- }
- node->base.location.end = rescue_clause->base.location.end;
- node->rescue_clause = rescue_clause;
-}
-
-/**
- * Set the else clause and end location of a begin node.
- */
-static void
-pm_begin_node_else_clause_set(pm_begin_node_t *node, pm_else_node_t *else_clause) {
- node->base.location.end = else_clause->base.location.end;
- node->else_clause = else_clause;
-}
-
-/**
- * Set the ensure clause and end location of a begin node.
- */
-static void
-pm_begin_node_ensure_clause_set(pm_begin_node_t *node, pm_ensure_node_t *ensure_clause) {
- node->base.location.end = ensure_clause->base.location.end;
- node->ensure_clause = ensure_clause;
-}
-
-/**
- * Set the end keyword and end location of a begin node.
- */
-static void
-pm_begin_node_end_keyword_set(pm_begin_node_t *node, const pm_token_t *end_keyword) {
- assert(end_keyword->type == PM_TOKEN_KEYWORD_END || end_keyword->type == PM_TOKEN_MISSING);
-
- node->base.location.end = end_keyword->end;
- node->end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword);
-}
-
-/**
- * Allocate and initialize a new BlockArgumentNode node.
- */
-static pm_block_argument_node_t *
-pm_block_argument_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *expression) {
- pm_block_argument_node_t *node = PM_ALLOC_NODE(parser, pm_block_argument_node_t);
-
- *node = (pm_block_argument_node_t) {
- {
- .type = PM_BLOCK_ARGUMENT_NODE,
- .location = {
- .start = operator->start,
- .end = expression == NULL ? operator->end : expression->location.end
- },
- },
- .expression = expression,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new BlockNode node.
- */
-static pm_block_node_t *
-pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, uint32_t locals_body_index, const pm_token_t *opening, pm_node_t *parameters, pm_node_t *body, const pm_token_t *closing) {
- pm_block_node_t *node = PM_ALLOC_NODE(parser, pm_block_node_t);
-
- *node = (pm_block_node_t) {
- {
- .type = PM_BLOCK_NODE,
- .location = { .start = opening->start, .end = closing->end },
- },
- .locals = *locals,
- .locals_body_index = locals_body_index,
- .parameters = parameters,
- .body = body,
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new BlockParameterNode node.
- */
-static pm_block_parameter_node_t *
-pm_block_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, const pm_token_t *operator) {
- assert(operator->type == PM_TOKEN_NOT_PROVIDED || operator->type == PM_TOKEN_UAMPERSAND || operator->type == PM_TOKEN_AMPERSAND);
- pm_block_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_block_parameter_node_t);
-
- *node = (pm_block_parameter_node_t) {
- {
- .type = PM_BLOCK_PARAMETER_NODE,
- .location = {
- .start = operator->start,
- .end = (name->type == PM_TOKEN_NOT_PROVIDED ? operator->end : name->end)
- },
- },
- .name = pm_parser_optional_constant_id_token(parser, name),
- .name_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(name),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new BlockParametersNode node.
- */
-static pm_block_parameters_node_t *
-pm_block_parameters_node_create(pm_parser_t *parser, pm_parameters_node_t *parameters, const pm_token_t *opening) {
- pm_block_parameters_node_t *node = PM_ALLOC_NODE(parser, pm_block_parameters_node_t);
-
- const uint8_t *start;
- if (opening->type != PM_TOKEN_NOT_PROVIDED) {
- start = opening->start;
- } else if (parameters != NULL) {
- start = parameters->base.location.start;
- } else {
- start = NULL;
- }
-
- const uint8_t *end;
- if (parameters != NULL) {
- end = parameters->base.location.end;
- } else if (opening->type != PM_TOKEN_NOT_PROVIDED) {
- end = opening->end;
- } else {
- end = NULL;
- }
-
- *node = (pm_block_parameters_node_t) {
- {
- .type = PM_BLOCK_PARAMETERS_NODE,
- .location = {
- .start = start,
- .end = end
- }
- },
- .parameters = parameters,
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .locals = { 0 }
- };
-
- return node;
-}
-
-/**
- * Set the closing location of a BlockParametersNode node.
- */
-static void
-pm_block_parameters_node_closing_set(pm_block_parameters_node_t *node, const pm_token_t *closing) {
- assert(closing->type == PM_TOKEN_PIPE || closing->type == PM_TOKEN_PARENTHESIS_RIGHT || closing->type == PM_TOKEN_MISSING);
-
- node->base.location.end = closing->end;
- node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing);
-}
-
-/**
- * Allocate and initialize a new BlockLocalVariableNode node.
- */
-static pm_block_local_variable_node_t *
-pm_block_local_variable_node_create(pm_parser_t *parser, const pm_token_t *name) {
- assert(name->type == PM_TOKEN_IDENTIFIER || name->type == PM_TOKEN_MISSING);
- pm_block_local_variable_node_t *node = PM_ALLOC_NODE(parser, pm_block_local_variable_node_t);
-
- *node = (pm_block_local_variable_node_t) {
- {
- .type = PM_BLOCK_LOCAL_VARIABLE_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(name),
- },
- .name = pm_parser_constant_id_token(parser, name)
- };
-
- return node;
-}
-
-/**
- * Append a new block-local variable to a BlockParametersNode node.
- */
-static void
-pm_block_parameters_node_append_local(pm_block_parameters_node_t *node, const pm_block_local_variable_node_t *local) {
- pm_node_list_append(&node->locals, (pm_node_t *) local);
-
- if (node->base.location.start == NULL) node->base.location.start = local->base.location.start;
- node->base.location.end = local->base.location.end;
-}
-
-/**
- * Allocate and initialize a new BreakNode node.
- */
-static pm_break_node_t *
-pm_break_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_node_t *arguments) {
- assert(keyword->type == PM_TOKEN_KEYWORD_BREAK);
- pm_break_node_t *node = PM_ALLOC_NODE(parser, pm_break_node_t);
-
- *node = (pm_break_node_t) {
- {
- .type = PM_BREAK_NODE,
- .location = {
- .start = keyword->start,
- .end = (arguments == NULL ? keyword->end : arguments->base.location.end)
- },
- },
- .arguments = arguments,
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node. This sets everything to NULL or
- * PM_TOKEN_NOT_PROVIDED as appropriate such that its values can be overridden
- * in the various specializations of this function.
- */
-static pm_call_node_t *
-pm_call_node_create(pm_parser_t *parser) {
- pm_call_node_t *node = PM_ALLOC_NODE(parser, pm_call_node_t);
-
- *node = (pm_call_node_t) {
- {
- .type = PM_CALL_NODE,
- .location = PM_LOCATION_NULL_VALUE(parser),
- },
- .receiver = NULL,
- .call_operator_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .message_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .arguments = NULL,
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .block = NULL,
- .name = 0
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from an aref or an aset
- * expression.
- */
-static pm_call_node_t *
-pm_call_node_aref_create(pm_parser_t *parser, pm_node_t *receiver, pm_arguments_t *arguments) {
- pm_assert_value_expression(parser, receiver);
-
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = receiver->location.start;
- node->base.location.end = pm_arguments_end(arguments);
-
- node->receiver = receiver;
- node->message_loc.start = arguments->opening_loc.start;
- node->message_loc.end = arguments->closing_loc.end;
-
- node->opening_loc = arguments->opening_loc;
- node->arguments = arguments->arguments;
- node->closing_loc = arguments->closing_loc;
- node->block = arguments->block;
-
- node->name = pm_parser_constant_id_constant(parser, "[]", 2);
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a binary expression.
- */
-static pm_call_node_t *
-pm_call_node_binary_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *operator, pm_node_t *argument) {
- pm_assert_value_expression(parser, receiver);
- pm_assert_value_expression(parser, argument);
-
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = MIN(receiver->location.start, argument->location.start);
- node->base.location.end = MAX(receiver->location.end, argument->location.end);
-
- node->receiver = receiver;
- node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator);
-
- pm_arguments_node_t *arguments = pm_arguments_node_create(parser);
- pm_arguments_node_arguments_append(arguments, argument);
- node->arguments = arguments;
-
- node->name = pm_parser_constant_id_token(parser, operator);
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a call expression.
- */
-static pm_call_node_t *
-pm_call_node_call_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *operator, pm_token_t *message, pm_arguments_t *arguments) {
- pm_assert_value_expression(parser, receiver);
-
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = receiver->location.start;
- const uint8_t *end = pm_arguments_end(arguments);
- if (end == NULL) {
- end = message->end;
- }
- node->base.location.end = end;
-
- node->receiver = receiver;
- node->call_operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator);
- node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message);
- node->opening_loc = arguments->opening_loc;
- node->arguments = arguments->arguments;
- node->closing_loc = arguments->closing_loc;
- node->block = arguments->block;
-
- if (operator->type == PM_TOKEN_AMPERSAND_DOT) {
- pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION);
- }
-
- node->name = pm_parser_constant_id_token(parser, message);
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a call to a method name
- * without a receiver that could not have been a local variable read.
- */
-static pm_call_node_t *
-pm_call_node_fcall_create(pm_parser_t *parser, pm_token_t *message, pm_arguments_t *arguments) {
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = message->start;
- node->base.location.end = pm_arguments_end(arguments);
-
- node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message);
- node->opening_loc = arguments->opening_loc;
- node->arguments = arguments->arguments;
- node->closing_loc = arguments->closing_loc;
- node->block = arguments->block;
-
- node->name = pm_parser_constant_id_token(parser, message);
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a not expression.
- */
-static pm_call_node_t *
-pm_call_node_not_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *message, pm_arguments_t *arguments) {
- pm_assert_value_expression(parser, receiver);
-
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = message->start;
- if (arguments->closing_loc.start != NULL) {
- node->base.location.end = arguments->closing_loc.end;
- } else {
- node->base.location.end = receiver->location.end;
- }
-
- node->receiver = receiver;
- node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message);
- node->opening_loc = arguments->opening_loc;
- node->arguments = arguments->arguments;
- node->closing_loc = arguments->closing_loc;
-
- node->name = pm_parser_constant_id_constant(parser, "!", 1);
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a call shorthand expression.
- */
-static pm_call_node_t *
-pm_call_node_shorthand_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *operator, pm_arguments_t *arguments) {
- pm_assert_value_expression(parser, receiver);
-
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = receiver->location.start;
- node->base.location.end = pm_arguments_end(arguments);
-
- node->receiver = receiver;
- node->call_operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator);
- node->opening_loc = arguments->opening_loc;
- node->arguments = arguments->arguments;
- node->closing_loc = arguments->closing_loc;
- node->block = arguments->block;
-
- if (operator->type == PM_TOKEN_AMPERSAND_DOT) {
- pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION);
- }
-
- node->name = pm_parser_constant_id_constant(parser, "call", 4);
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a unary operator expression.
- */
-static pm_call_node_t *
-pm_call_node_unary_create(pm_parser_t *parser, pm_token_t *operator, pm_node_t *receiver, const char *name) {
- pm_assert_value_expression(parser, receiver);
-
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location.start = operator->start;
- node->base.location.end = receiver->location.end;
-
- node->receiver = receiver;
- node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator);
-
- node->name = pm_parser_constant_id_constant(parser, name, strlen(name));
- return node;
-}
-
-/**
- * Allocate and initialize a new CallNode node from a call to a method name
- * without a receiver that could also have been a local variable read.
- */
-static pm_call_node_t *
-pm_call_node_variable_call_create(pm_parser_t *parser, pm_token_t *message) {
- pm_call_node_t *node = pm_call_node_create(parser);
-
- node->base.location = PM_LOCATION_TOKEN_VALUE(message);
- node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message);
-
- node->name = pm_parser_constant_id_token(parser, message);
- return node;
-}
-
-/**
- * Returns whether or not this call node is a "vcall" (a call to a method name
- * without a receiver that could also have been a local variable read).
- */
-static inline bool
-pm_call_node_variable_call_p(pm_call_node_t *node) {
- return PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_VARIABLE_CALL);
-}
-
-/**
- * Returns whether or not this call is to the [] method in the index form without a block (as
- * opposed to `foo.[]` and `foo[] { }`).
- */
-static inline bool
-pm_call_node_index_p(pm_call_node_t *node) {
- return (
- (node->call_operator_loc.start == NULL) &&
- (node->message_loc.start != NULL) &&
- (node->message_loc.start[0] == '[') &&
- (node->message_loc.end[-1] == ']') &&
- (node->block == NULL || PM_NODE_TYPE_P(node->block, PM_BLOCK_ARGUMENT_NODE))
- );
-}
-
-/**
- * Returns whether or not this call can be used on the left-hand side of an
- * operator assignment.
- */
-static inline bool
-pm_call_node_writable_p(pm_call_node_t *node) {
- return (
- (node->message_loc.start != NULL) &&
- (node->message_loc.end[-1] != '!') &&
- (node->message_loc.end[-1] != '?') &&
- (node->opening_loc.start == NULL) &&
- (node->arguments == NULL) &&
- (node->block == NULL)
- );
-}
-
-/**
- * Initialize the read name by reading the write name and chopping off the '='.
- */
-static void
-pm_call_write_read_name_init(pm_parser_t *parser, pm_constant_id_t *read_name, pm_constant_id_t *write_name) {
- pm_constant_t *write_constant = pm_constant_pool_id_to_constant(&parser->constant_pool, *write_name);
-
- if (write_constant->length > 0) {
- size_t length = write_constant->length - 1;
-
- void *memory = malloc(length);
- memcpy(memory, write_constant->start, length);
-
- *read_name = pm_constant_pool_insert_owned(&parser->constant_pool, (uint8_t *) memory, length);
- } else {
- // We can get here if the message was missing because of a syntax error.
- *read_name = pm_parser_constant_id_constant(parser, "", 0);
- }
-}
-
-/**
- * Allocate and initialize a new CallAndWriteNode node.
- */
-static pm_call_and_write_node_t *
-pm_call_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(target->block == NULL);
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_call_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_call_and_write_node_t);
-
- *node = (pm_call_and_write_node_t) {
- {
- .type = PM_CALL_AND_WRITE_NODE,
- .flags = target->base.flags,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .message_loc = target->message_loc,
- .read_name = 0,
- .write_name = target->name,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- pm_call_write_read_name_init(parser, &node->read_name, &node->write_name);
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IndexAndWriteNode node.
- */
-static pm_index_and_write_node_t *
-pm_index_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_index_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_index_and_write_node_t);
-
- *node = (pm_index_and_write_node_t) {
- {
- .type = PM_INDEX_AND_WRITE_NODE,
- .flags = target->base.flags,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .opening_loc = target->opening_loc,
- .arguments = target->arguments,
- .closing_loc = target->closing_loc,
- .block = target->block,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate a new CallOperatorWriteNode node.
- */
-static pm_call_operator_write_node_t *
-pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(target->block == NULL);
- pm_call_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_call_operator_write_node_t);
-
- *node = (pm_call_operator_write_node_t) {
- {
- .type = PM_CALL_OPERATOR_WRITE_NODE,
- .flags = target->base.flags,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .message_loc = target->message_loc,
- .read_name = 0,
- .write_name = target->name,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- pm_call_write_read_name_init(parser, &node->read_name, &node->write_name);
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate a new IndexOperatorWriteNode node.
- */
-static pm_index_operator_write_node_t *
-pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_index_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_index_operator_write_node_t);
-
- *node = (pm_index_operator_write_node_t) {
- {
- .type = PM_INDEX_OPERATOR_WRITE_NODE,
- .flags = target->base.flags,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .opening_loc = target->opening_loc,
- .arguments = target->arguments,
- .closing_loc = target->closing_loc,
- .block = target->block,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new CallOrWriteNode node.
- */
-static pm_call_or_write_node_t *
-pm_call_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(target->block == NULL);
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_call_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_call_or_write_node_t);
-
- *node = (pm_call_or_write_node_t) {
- {
- .type = PM_CALL_OR_WRITE_NODE,
- .flags = target->base.flags,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .message_loc = target->message_loc,
- .read_name = 0,
- .write_name = target->name,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- pm_call_write_read_name_init(parser, &node->read_name, &node->write_name);
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IndexOrWriteNode node.
- */
-static pm_index_or_write_node_t *
-pm_index_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_index_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_index_or_write_node_t);
-
- *node = (pm_index_or_write_node_t) {
- {
- .type = PM_INDEX_OR_WRITE_NODE,
- .flags = target->base.flags,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .opening_loc = target->opening_loc,
- .arguments = target->arguments,
- .closing_loc = target->closing_loc,
- .block = target->block,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new CallTargetNode node from an existing call
- * node.
- */
-static pm_call_target_node_t *
-pm_call_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
- pm_call_target_node_t *node = PM_ALLOC_NODE(parser, pm_call_target_node_t);
-
- *node = (pm_call_target_node_t) {
- {
- .type = PM_CALL_TARGET_NODE,
- .flags = target->base.flags,
- .location = target->base.location
- },
- .receiver = target->receiver,
- .call_operator_loc = target->call_operator_loc,
- .name = target->name,
- .message_loc = target->message_loc
- };
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IndexTargetNode node from an existing call
- * node.
- */
-static pm_index_target_node_t *
-pm_index_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
- pm_index_target_node_t *node = PM_ALLOC_NODE(parser, pm_index_target_node_t);
-
- *node = (pm_index_target_node_t) {
- {
- .type = PM_INDEX_TARGET_NODE,
- .flags = target->base.flags,
- .location = target->base.location
- },
- .receiver = target->receiver,
- .opening_loc = target->opening_loc,
- .arguments = target->arguments,
- .closing_loc = target->closing_loc,
- .block = target->block
- };
-
- // Here we're going to free the target, since it is no longer necessary.
- // However, we don't want to call `pm_node_destroy` because we want to keep
- // around all of its children since we just reused them.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new CapturePatternNode node.
- */
-static pm_capture_pattern_node_t *
-pm_capture_pattern_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t *target, const pm_token_t *operator) {
- pm_capture_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_capture_pattern_node_t);
-
- *node = (pm_capture_pattern_node_t) {
- {
- .type = PM_CAPTURE_PATTERN_NODE,
- .location = {
- .start = value->location.start,
- .end = target->location.end
- },
- },
- .value = value,
- .target = target,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new CaseNode node.
- */
-static pm_case_node_t *
-pm_case_node_create(pm_parser_t *parser, const pm_token_t *case_keyword, pm_node_t *predicate, const pm_token_t *end_keyword) {
- pm_case_node_t *node = PM_ALLOC_NODE(parser, pm_case_node_t);
-
- *node = (pm_case_node_t) {
- {
- .type = PM_CASE_NODE,
- .location = {
- .start = case_keyword->start,
- .end = end_keyword->end
- },
- },
- .predicate = predicate,
- .consequent = NULL,
- .case_keyword_loc = PM_LOCATION_TOKEN_VALUE(case_keyword),
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword),
- .conditions = { 0 }
- };
-
- return node;
-}
-
-/**
- * Append a new condition to a CaseNode node.
- */
-static void
-pm_case_node_condition_append(pm_case_node_t *node, pm_node_t *condition) {
- assert(PM_NODE_TYPE_P(condition, PM_WHEN_NODE));
-
- pm_node_list_append(&node->conditions, condition);
- node->base.location.end = condition->location.end;
-}
-
-/**
- * Set the consequent of a CaseNode node.
- */
-static void
-pm_case_node_consequent_set(pm_case_node_t *node, pm_else_node_t *consequent) {
- node->consequent = consequent;
- node->base.location.end = consequent->base.location.end;
-}
-
-/**
- * Set the end location for a CaseNode node.
- */
-static void
-pm_case_node_end_keyword_loc_set(pm_case_node_t *node, const pm_token_t *end_keyword) {
- node->base.location.end = end_keyword->end;
- node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword);
-}
-
-/**
- * Allocate and initialize a new CaseMatchNode node.
- */
-static pm_case_match_node_t *
-pm_case_match_node_create(pm_parser_t *parser, const pm_token_t *case_keyword, pm_node_t *predicate, const pm_token_t *end_keyword) {
- pm_case_match_node_t *node = PM_ALLOC_NODE(parser, pm_case_match_node_t);
-
- *node = (pm_case_match_node_t) {
- {
- .type = PM_CASE_MATCH_NODE,
- .location = {
- .start = case_keyword->start,
- .end = end_keyword->end
- },
- },
- .predicate = predicate,
- .consequent = NULL,
- .case_keyword_loc = PM_LOCATION_TOKEN_VALUE(case_keyword),
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword),
- .conditions = { 0 }
- };
-
- return node;
-}
-
-/**
- * Append a new condition to a CaseMatchNode node.
- */
-static void
-pm_case_match_node_condition_append(pm_case_match_node_t *node, pm_node_t *condition) {
- assert(PM_NODE_TYPE_P(condition, PM_IN_NODE));
-
- pm_node_list_append(&node->conditions, condition);
- node->base.location.end = condition->location.end;
-}
-
-/**
- * Set the consequent of a CaseMatchNode node.
- */
-static void
-pm_case_match_node_consequent_set(pm_case_match_node_t *node, pm_else_node_t *consequent) {
- node->consequent = consequent;
- node->base.location.end = consequent->base.location.end;
-}
-
-/**
- * Set the end location for a CaseMatchNode node.
- */
-static void
-pm_case_match_node_end_keyword_loc_set(pm_case_match_node_t *node, const pm_token_t *end_keyword) {
- node->base.location.end = end_keyword->end;
- node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword);
-}
-
-/**
- * Allocate a new ClassNode node.
- */
-static pm_class_node_t *
-pm_class_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *class_keyword, pm_node_t *constant_path, const pm_token_t *name, const pm_token_t *inheritance_operator, pm_node_t *superclass, pm_node_t *body, const pm_token_t *end_keyword) {
- pm_class_node_t *node = PM_ALLOC_NODE(parser, pm_class_node_t);
-
- *node = (pm_class_node_t) {
- {
- .type = PM_CLASS_NODE,
- .location = { .start = class_keyword->start, .end = end_keyword->end },
- },
- .locals = *locals,
- .class_keyword_loc = PM_LOCATION_TOKEN_VALUE(class_keyword),
- .constant_path = constant_path,
- .inheritance_operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(inheritance_operator),
- .superclass = superclass,
- .body = body,
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword),
- .name = pm_parser_constant_id_token(parser, name)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ClassVariableAndWriteNode node.
- */
-static pm_class_variable_and_write_node_t *
-pm_class_variable_and_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_class_variable_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_class_variable_and_write_node_t);
-
- *node = (pm_class_variable_and_write_node_t) {
- {
- .type = PM_CLASS_VARIABLE_AND_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ClassVariableOperatorWriteNode node.
- */
-static pm_class_variable_operator_write_node_t *
-pm_class_variable_operator_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_class_variable_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_class_variable_operator_write_node_t);
-
- *node = (pm_class_variable_operator_write_node_t) {
- {
- .type = PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ClassVariableOrWriteNode node.
- */
-static pm_class_variable_or_write_node_t *
-pm_class_variable_or_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_class_variable_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_class_variable_or_write_node_t);
-
- *node = (pm_class_variable_or_write_node_t) {
- {
- .type = PM_CLASS_VARIABLE_OR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ClassVariableReadNode node.
- */
-static pm_class_variable_read_node_t *
-pm_class_variable_read_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_CLASS_VARIABLE);
- pm_class_variable_read_node_t *node = PM_ALLOC_NODE(parser, pm_class_variable_read_node_t);
-
- *node = (pm_class_variable_read_node_t) {
- {
- .type = PM_CLASS_VARIABLE_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .name = pm_parser_constant_id_token(parser, token)
- };
-
- return node;
-}
-
-/**
- * Initialize a new ClassVariableWriteNode node from a ClassVariableRead node.
- */
-static pm_class_variable_write_node_t *
-pm_class_variable_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *read_node, pm_token_t *operator, pm_node_t *value) {
- pm_class_variable_write_node_t *node = PM_ALLOC_NODE(parser, pm_class_variable_write_node_t);
-
- *node = (pm_class_variable_write_node_t) {
- {
- .type = PM_CLASS_VARIABLE_WRITE_NODE,
- .location = {
- .start = read_node->base.location.start,
- .end = value->location.end
- },
- },
- .name = read_node->name,
- .name_loc = PM_LOCATION_NODE_VALUE((pm_node_t *) read_node),
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantPathAndWriteNode node.
- */
-static pm_constant_path_and_write_node_t *
-pm_constant_path_and_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_constant_path_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_path_and_write_node_t);
-
- *node = (pm_constant_path_and_write_node_t) {
- {
- .type = PM_CONSTANT_PATH_AND_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .target = target,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantPathOperatorWriteNode node.
- */
-static pm_constant_path_operator_write_node_t *
-pm_constant_path_operator_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_constant_path_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_path_operator_write_node_t);
-
- *node = (pm_constant_path_operator_write_node_t) {
- {
- .type = PM_CONSTANT_PATH_OPERATOR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .target = target,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantPathOrWriteNode node.
- */
-static pm_constant_path_or_write_node_t *
-pm_constant_path_or_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_constant_path_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_path_or_write_node_t);
-
- *node = (pm_constant_path_or_write_node_t) {
- {
- .type = PM_CONSTANT_PATH_OR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .target = target,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantPathNode node.
- */
-static pm_constant_path_node_t *
-pm_constant_path_node_create(pm_parser_t *parser, pm_node_t *parent, const pm_token_t *delimiter, pm_node_t *child) {
- pm_assert_value_expression(parser, parent);
-
- pm_constant_path_node_t *node = PM_ALLOC_NODE(parser, pm_constant_path_node_t);
-
- *node = (pm_constant_path_node_t) {
- {
- .type = PM_CONSTANT_PATH_NODE,
- .location = {
- .start = parent == NULL ? delimiter->start : parent->location.start,
- .end = child->location.end
- },
- },
- .parent = parent,
- .child = child,
- .delimiter_loc = PM_LOCATION_TOKEN_VALUE(delimiter)
- };
-
- return node;
-}
-
-/**
- * Allocate a new ConstantPathWriteNode node.
- */
-static pm_constant_path_write_node_t *
-pm_constant_path_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_constant_path_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_path_write_node_t);
-
- *node = (pm_constant_path_write_node_t) {
- {
- .type = PM_CONSTANT_PATH_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- },
- },
- .target = target,
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantAndWriteNode node.
- */
-static pm_constant_and_write_node_t *
-pm_constant_and_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_constant_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_and_write_node_t);
-
- *node = (pm_constant_and_write_node_t) {
- {
- .type = PM_CONSTANT_AND_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantOperatorWriteNode node.
- */
-static pm_constant_operator_write_node_t *
-pm_constant_operator_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_constant_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_operator_write_node_t);
-
- *node = (pm_constant_operator_write_node_t) {
- {
- .type = PM_CONSTANT_OPERATOR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantOrWriteNode node.
- */
-static pm_constant_or_write_node_t *
-pm_constant_or_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_constant_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_or_write_node_t);
-
- *node = (pm_constant_or_write_node_t) {
- {
- .type = PM_CONSTANT_OR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ConstantReadNode node.
- */
-static pm_constant_read_node_t *
-pm_constant_read_node_create(pm_parser_t *parser, const pm_token_t *name) {
- assert(name->type == PM_TOKEN_CONSTANT || name->type == PM_TOKEN_MISSING);
- pm_constant_read_node_t *node = PM_ALLOC_NODE(parser, pm_constant_read_node_t);
-
- *node = (pm_constant_read_node_t) {
- {
- .type = PM_CONSTANT_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(name)
- },
- .name = pm_parser_constant_id_token(parser, name)
- };
-
- return node;
-}
-
-/**
- * Allocate a new ConstantWriteNode node.
- */
-static pm_constant_write_node_t *
-pm_constant_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_constant_write_node_t *node = PM_ALLOC_NODE(parser, pm_constant_write_node_t);
-
- *node = (pm_constant_write_node_t) {
- {
- .type = PM_CONSTANT_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new DefNode node.
- */
-static pm_def_node_t *
-pm_def_node_create(
- pm_parser_t *parser,
- const pm_token_t *name,
- pm_node_t *receiver,
- pm_parameters_node_t *parameters,
- pm_node_t *body,
- pm_constant_id_list_t *locals,
- uint32_t locals_body_index,
- const pm_token_t *def_keyword,
- const pm_token_t *operator,
- const pm_token_t *lparen,
- const pm_token_t *rparen,
- const pm_token_t *equal,
- const pm_token_t *end_keyword
-) {
- pm_def_node_t *node = PM_ALLOC_NODE(parser, pm_def_node_t);
- const uint8_t *end;
-
- if (end_keyword->type == PM_TOKEN_NOT_PROVIDED) {
- end = body->location.end;
- } else {
- end = end_keyword->end;
- }
-
- *node = (pm_def_node_t) {
- {
- .type = PM_DEF_NODE,
- .location = { .start = def_keyword->start, .end = end },
- },
- .name = pm_parser_constant_id_token(parser, name),
- .name_loc = PM_LOCATION_TOKEN_VALUE(name),
- .receiver = receiver,
- .parameters = parameters,
- .body = body,
- .locals = *locals,
- .locals_body_index = locals_body_index,
- .def_keyword_loc = PM_LOCATION_TOKEN_VALUE(def_keyword),
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .lparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(lparen),
- .rparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(rparen),
- .equal_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(equal),
- .end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate a new DefinedNode node.
- */
-static pm_defined_node_t *
-pm_defined_node_create(pm_parser_t *parser, const pm_token_t *lparen, pm_node_t *value, const pm_token_t *rparen, const pm_location_t *keyword_loc) {
- pm_defined_node_t *node = PM_ALLOC_NODE(parser, pm_defined_node_t);
-
- *node = (pm_defined_node_t) {
- {
- .type = PM_DEFINED_NODE,
- .location = {
- .start = keyword_loc->start,
- .end = (rparen->type == PM_TOKEN_NOT_PROVIDED ? value->location.end : rparen->end)
- },
- },
- .lparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(lparen),
- .value = value,
- .rparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(rparen),
- .keyword_loc = *keyword_loc
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ElseNode node.
- */
-static pm_else_node_t *
-pm_else_node_create(pm_parser_t *parser, const pm_token_t *else_keyword, pm_statements_node_t *statements, const pm_token_t *end_keyword) {
- pm_else_node_t *node = PM_ALLOC_NODE(parser, pm_else_node_t);
- const uint8_t *end = NULL;
- if ((end_keyword->type == PM_TOKEN_NOT_PROVIDED) && (statements != NULL)) {
- end = statements->base.location.end;
- } else {
- end = end_keyword->end;
- }
-
- *node = (pm_else_node_t) {
- {
- .type = PM_ELSE_NODE,
- .location = {
- .start = else_keyword->start,
- .end = end,
- },
- },
- .else_keyword_loc = PM_LOCATION_TOKEN_VALUE(else_keyword),
- .statements = statements,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new EmbeddedStatementsNode node.
- */
-static pm_embedded_statements_node_t *
-pm_embedded_statements_node_create(pm_parser_t *parser, const pm_token_t *opening, pm_statements_node_t *statements, const pm_token_t *closing) {
- pm_embedded_statements_node_t *node = PM_ALLOC_NODE(parser, pm_embedded_statements_node_t);
-
- *node = (pm_embedded_statements_node_t) {
- {
- .type = PM_EMBEDDED_STATEMENTS_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end
- }
- },
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .statements = statements,
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new EmbeddedVariableNode node.
- */
-static pm_embedded_variable_node_t *
-pm_embedded_variable_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *variable) {
- pm_embedded_variable_node_t *node = PM_ALLOC_NODE(parser, pm_embedded_variable_node_t);
-
- *node = (pm_embedded_variable_node_t) {
- {
- .type = PM_EMBEDDED_VARIABLE_NODE,
- .location = {
- .start = operator->start,
- .end = variable->location.end
- }
- },
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .variable = variable
- };
-
- return node;
-}
-
-/**
- * Allocate a new EnsureNode node.
- */
-static pm_ensure_node_t *
-pm_ensure_node_create(pm_parser_t *parser, const pm_token_t *ensure_keyword, pm_statements_node_t *statements, const pm_token_t *end_keyword) {
- pm_ensure_node_t *node = PM_ALLOC_NODE(parser, pm_ensure_node_t);
-
- *node = (pm_ensure_node_t) {
- {
- .type = PM_ENSURE_NODE,
- .location = {
- .start = ensure_keyword->start,
- .end = end_keyword->end
- },
- },
- .ensure_keyword_loc = PM_LOCATION_TOKEN_VALUE(ensure_keyword),
- .statements = statements,
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new FalseNode node.
- */
-static pm_false_node_t *
-pm_false_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_FALSE);
- pm_false_node_t *node = PM_ALLOC_NODE(parser, pm_false_node_t);
-
- *node = (pm_false_node_t) {{
- .type = PM_FALSE_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate and initialize a new find pattern node. The node list given in the
- * nodes parameter is guaranteed to have at least two nodes.
- */
-static pm_find_pattern_node_t *
-pm_find_pattern_node_create(pm_parser_t *parser, pm_node_list_t *nodes) {
- pm_find_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_find_pattern_node_t);
-
- pm_node_t *left = nodes->nodes[0];
- pm_node_t *right;
-
- if (nodes->size == 1) {
- right = (pm_node_t *) pm_missing_node_create(parser, left->location.end, left->location.end);
- } else {
- right = nodes->nodes[nodes->size - 1];
- }
-
- *node = (pm_find_pattern_node_t) {
- {
- .type = PM_FIND_PATTERN_NODE,
- .location = {
- .start = left->location.start,
- .end = right->location.end,
- },
- },
- .constant = NULL,
- .left = left,
- .right = right,
- .requireds = { 0 },
- .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- // For now we're going to just copy over each pointer manually. This could be
- // much more efficient, as we could instead resize the node list to only point
- // to 1...-1.
- for (size_t index = 1; index < nodes->size - 1; index++) {
- pm_node_list_append(&node->requireds, nodes->nodes[index]);
- }
-
- return node;
-}
-
-/**
- * Allocate and initialize a new FloatNode node.
- */
-static pm_float_node_t *
-pm_float_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_FLOAT);
- pm_float_node_t *node = PM_ALLOC_NODE(parser, pm_float_node_t);
-
- *node = (pm_float_node_t) {{
- .type = PM_FLOAT_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate and initialize a new FloatNode node from a FLOAT_IMAGINARY token.
- */
-static pm_imaginary_node_t *
-pm_float_node_imaginary_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_FLOAT_IMAGINARY);
-
- pm_imaginary_node_t *node = PM_ALLOC_NODE(parser, pm_imaginary_node_t);
- *node = (pm_imaginary_node_t) {
- {
- .type = PM_IMAGINARY_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .numeric = (pm_node_t *) pm_float_node_create(parser, &((pm_token_t) {
- .type = PM_TOKEN_FLOAT,
- .start = token->start,
- .end = token->end - 1
- }))
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new FloatNode node from a FLOAT_RATIONAL token.
- */
-static pm_rational_node_t *
-pm_float_node_rational_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_FLOAT_RATIONAL);
-
- pm_rational_node_t *node = PM_ALLOC_NODE(parser, pm_rational_node_t);
- *node = (pm_rational_node_t) {
- {
- .type = PM_RATIONAL_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .numeric = (pm_node_t *) pm_float_node_create(parser, &((pm_token_t) {
- .type = PM_TOKEN_FLOAT,
- .start = token->start,
- .end = token->end - 1
- }))
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new FloatNode node from a FLOAT_RATIONAL_IMAGINARY
- * token.
- */
-static pm_imaginary_node_t *
-pm_float_node_rational_imaginary_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_FLOAT_RATIONAL_IMAGINARY);
-
- pm_imaginary_node_t *node = PM_ALLOC_NODE(parser, pm_imaginary_node_t);
- *node = (pm_imaginary_node_t) {
- {
- .type = PM_IMAGINARY_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .numeric = (pm_node_t *) pm_float_node_rational_create(parser, &((pm_token_t) {
- .type = PM_TOKEN_FLOAT_RATIONAL,
- .start = token->start,
- .end = token->end - 1
- }))
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ForNode node.
- */
-static pm_for_node_t *
-pm_for_node_create(
- pm_parser_t *parser,
- pm_node_t *index,
- pm_node_t *collection,
- pm_statements_node_t *statements,
- const pm_token_t *for_keyword,
- const pm_token_t *in_keyword,
- const pm_token_t *do_keyword,
- const pm_token_t *end_keyword
-) {
- pm_for_node_t *node = PM_ALLOC_NODE(parser, pm_for_node_t);
-
- *node = (pm_for_node_t) {
- {
- .type = PM_FOR_NODE,
- .location = {
- .start = for_keyword->start,
- .end = end_keyword->end
- },
- },
- .index = index,
- .collection = collection,
- .statements = statements,
- .for_keyword_loc = PM_LOCATION_TOKEN_VALUE(for_keyword),
- .in_keyword_loc = PM_LOCATION_TOKEN_VALUE(in_keyword),
- .do_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(do_keyword),
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ForwardingArgumentsNode node.
- */
-static pm_forwarding_arguments_node_t *
-pm_forwarding_arguments_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_UDOT_DOT_DOT);
- pm_forwarding_arguments_node_t *node = PM_ALLOC_NODE(parser, pm_forwarding_arguments_node_t);
- *node = (pm_forwarding_arguments_node_t) {{ .type = PM_FORWARDING_ARGUMENTS_NODE, .location = PM_LOCATION_TOKEN_VALUE(token) }};
- return node;
-}
-
-/**
- * Allocate and initialize a new ForwardingParameterNode node.
- */
-static pm_forwarding_parameter_node_t *
-pm_forwarding_parameter_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_UDOT_DOT_DOT);
- pm_forwarding_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_forwarding_parameter_node_t);
- *node = (pm_forwarding_parameter_node_t) {{ .type = PM_FORWARDING_PARAMETER_NODE, .location = PM_LOCATION_TOKEN_VALUE(token) }};
- return node;
-}
-
-/**
- * Allocate and initialize a new ForwardingSuper node.
- */
-static pm_forwarding_super_node_t *
-pm_forwarding_super_node_create(pm_parser_t *parser, const pm_token_t *token, pm_arguments_t *arguments) {
- assert(arguments->block == NULL || PM_NODE_TYPE_P(arguments->block, PM_BLOCK_NODE));
- assert(token->type == PM_TOKEN_KEYWORD_SUPER);
- pm_forwarding_super_node_t *node = PM_ALLOC_NODE(parser, pm_forwarding_super_node_t);
-
- pm_block_node_t *block = NULL;
- if (arguments->block != NULL) {
- block = (pm_block_node_t *) arguments->block;
- }
-
- *node = (pm_forwarding_super_node_t) {
- {
- .type = PM_FORWARDING_SUPER_NODE,
- .location = {
- .start = token->start,
- .end = block != NULL ? block->base.location.end : token->end
- },
- },
- .block = block
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new hash pattern node from an opening and closing
- * token.
- */
-static pm_hash_pattern_node_t *
-pm_hash_pattern_node_empty_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) {
- pm_hash_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_hash_pattern_node_t);
-
- *node = (pm_hash_pattern_node_t) {
- {
- .type = PM_HASH_PATTERN_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end
- },
- },
- .constant = NULL,
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
- .elements = { 0 },
- .rest = NULL
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new hash pattern node.
- */
-static pm_hash_pattern_node_t *
-pm_hash_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *elements, pm_node_t *rest) {
- pm_hash_pattern_node_t *node = PM_ALLOC_NODE(parser, pm_hash_pattern_node_t);
-
- const uint8_t *start;
- const uint8_t *end;
-
- if (elements->size > 0) {
- if (rest) {
- start = elements->nodes[0]->location.start;
- end = rest->location.end;
- } else {
- start = elements->nodes[0]->location.start;
- end = elements->nodes[elements->size - 1]->location.end;
- }
- } else {
- assert(rest != NULL);
- start = rest->location.start;
- end = rest->location.end;
- }
-
- *node = (pm_hash_pattern_node_t) {
- {
- .type = PM_HASH_PATTERN_NODE,
- .location = {
- .start = start,
- .end = end
- },
- },
- .constant = NULL,
- .elements = { 0 },
- .rest = rest,
- .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- for (size_t index = 0; index < elements->size; index++) {
- pm_node_t *element = elements->nodes[index];
- pm_node_list_append(&node->elements, element);
- }
-
- return node;
-}
-
-/**
- * Retrieve the name from a node that will become a global variable write node.
- */
-static pm_constant_id_t
-pm_global_variable_write_name(pm_parser_t *parser, const pm_node_t *target) {
- switch (PM_NODE_TYPE(target)) {
- case PM_GLOBAL_VARIABLE_READ_NODE:
- return ((pm_global_variable_read_node_t *) target)->name;
- case PM_BACK_REFERENCE_READ_NODE:
- return ((pm_back_reference_read_node_t *) target)->name;
- case PM_NUMBERED_REFERENCE_READ_NODE:
- // This will only ever happen in the event of a syntax error, but we
- // still need to provide something for the node.
- return pm_parser_constant_id_location(parser, target->location.start, target->location.end);
- default:
- assert(false && "unreachable");
- return (pm_constant_id_t) -1;
- }
-}
-
-/**
- * Allocate and initialize a new GlobalVariableAndWriteNode node.
- */
-static pm_global_variable_and_write_node_t *
-pm_global_variable_and_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_global_variable_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_global_variable_and_write_node_t);
-
- *node = (pm_global_variable_and_write_node_t) {
- {
- .type = PM_GLOBAL_VARIABLE_AND_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- }
- },
- .name = pm_global_variable_write_name(parser, target),
- .name_loc = target->location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new GlobalVariableOperatorWriteNode node.
- */
-static pm_global_variable_operator_write_node_t *
-pm_global_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_global_variable_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_global_variable_operator_write_node_t);
-
- *node = (pm_global_variable_operator_write_node_t) {
- {
- .type = PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- }
- },
- .name = pm_global_variable_write_name(parser, target),
- .name_loc = target->location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new GlobalVariableOrWriteNode node.
- */
-static pm_global_variable_or_write_node_t *
-pm_global_variable_or_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_global_variable_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_global_variable_or_write_node_t);
-
- *node = (pm_global_variable_or_write_node_t) {
- {
- .type = PM_GLOBAL_VARIABLE_OR_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- }
- },
- .name = pm_global_variable_write_name(parser, target),
- .name_loc = target->location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate a new GlobalVariableReadNode node.
- */
-static pm_global_variable_read_node_t *
-pm_global_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name) {
- pm_global_variable_read_node_t *node = PM_ALLOC_NODE(parser, pm_global_variable_read_node_t);
-
- *node = (pm_global_variable_read_node_t) {
- {
- .type = PM_GLOBAL_VARIABLE_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(name),
- },
- .name = pm_parser_constant_id_token(parser, name)
- };
-
- return node;
-}
-
-/**
- * Allocate a new GlobalVariableWriteNode node.
- */
-static pm_global_variable_write_node_t *
-pm_global_variable_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_global_variable_write_node_t *node = PM_ALLOC_NODE(parser, pm_global_variable_write_node_t);
-
- *node = (pm_global_variable_write_node_t) {
- {
- .type = PM_GLOBAL_VARIABLE_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- },
- },
- .name = pm_global_variable_write_name(parser, target),
- .name_loc = PM_LOCATION_NODE_VALUE(target),
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate a new HashNode node.
- */
-static pm_hash_node_t *
-pm_hash_node_create(pm_parser_t *parser, const pm_token_t *opening) {
- assert(opening != NULL);
- pm_hash_node_t *node = PM_ALLOC_NODE(parser, pm_hash_node_t);
-
- *node = (pm_hash_node_t) {
- {
- .type = PM_HASH_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(opening)
- },
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_NULL_VALUE(parser),
- .elements = { 0 }
- };
-
- return node;
-}
-
-/**
- * Append a new element to a hash node.
- */
-static inline void
-pm_hash_node_elements_append(pm_hash_node_t *hash, pm_node_t *element) {
- pm_node_list_append(&hash->elements, element);
-
- bool static_literal = PM_NODE_TYPE_P(element, PM_ASSOC_NODE);
- if (static_literal) {
- pm_assoc_node_t *assoc = (pm_assoc_node_t *) element;
- static_literal = !PM_NODE_TYPE_P(assoc->key, PM_ARRAY_NODE) && !PM_NODE_TYPE_P(assoc->key, PM_HASH_NODE) && !PM_NODE_TYPE_P(assoc->key, PM_RANGE_NODE);
- static_literal = static_literal && PM_NODE_FLAG_P(assoc->key, PM_NODE_FLAG_STATIC_LITERAL);
- static_literal = static_literal && PM_NODE_FLAG_P(assoc, PM_NODE_FLAG_STATIC_LITERAL);
- }
-
- if (!static_literal) {
- pm_node_flag_unset((pm_node_t *)hash, PM_NODE_FLAG_STATIC_LITERAL);
- }
-}
-
-static inline void
-pm_hash_node_closing_loc_set(pm_hash_node_t *hash, pm_token_t *token) {
- hash->base.location.end = token->end;
- hash->closing_loc = PM_LOCATION_TOKEN_VALUE(token);
-}
-
-/**
- * Allocate a new IfNode node.
- */
-static pm_if_node_t *
-pm_if_node_create(pm_parser_t *parser,
- const pm_token_t *if_keyword,
- pm_node_t *predicate,
- const pm_token_t *then_keyword,
- pm_statements_node_t *statements,
- pm_node_t *consequent,
- const pm_token_t *end_keyword
-) {
- pm_conditional_predicate(predicate);
- pm_if_node_t *node = PM_ALLOC_NODE(parser, pm_if_node_t);
-
- const uint8_t *end;
- if (end_keyword->type != PM_TOKEN_NOT_PROVIDED) {
- end = end_keyword->end;
- } else if (consequent != NULL) {
- end = consequent->location.end;
- } else if (pm_statements_node_body_length(statements) != 0) {
- end = statements->base.location.end;
- } else {
- end = predicate->location.end;
- }
-
- *node = (pm_if_node_t) {
- {
- .type = PM_IF_NODE,
- .flags = PM_NODE_FLAG_NEWLINE,
- .location = {
- .start = if_keyword->start,
- .end = end
- },
- },
- .if_keyword_loc = PM_LOCATION_TOKEN_VALUE(if_keyword),
- .predicate = predicate,
- .then_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword),
- .statements = statements,
- .consequent = consequent,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize new IfNode node in the modifier form.
- */
-static pm_if_node_t *
-pm_if_node_modifier_create(pm_parser_t *parser, pm_node_t *statement, const pm_token_t *if_keyword, pm_node_t *predicate) {
- pm_conditional_predicate(predicate);
- pm_if_node_t *node = PM_ALLOC_NODE(parser, pm_if_node_t);
-
- pm_statements_node_t *statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(statements, statement);
-
- *node = (pm_if_node_t) {
- {
- .type = PM_IF_NODE,
- .flags = PM_NODE_FLAG_NEWLINE,
- .location = {
- .start = statement->location.start,
- .end = predicate->location.end
- },
- },
- .if_keyword_loc = PM_LOCATION_TOKEN_VALUE(if_keyword),
- .predicate = predicate,
- .then_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .statements = statements,
- .consequent = NULL,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize an if node from a ternary expression.
- */
-static pm_if_node_t *
-pm_if_node_ternary_create(pm_parser_t *parser, pm_node_t *predicate, const pm_token_t *qmark, pm_node_t *true_expression, const pm_token_t *colon, pm_node_t *false_expression) {
- pm_assert_value_expression(parser, predicate);
- pm_conditional_predicate(predicate);
-
- pm_statements_node_t *if_statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(if_statements, true_expression);
-
- pm_statements_node_t *else_statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(else_statements, false_expression);
-
- pm_token_t end_keyword = not_provided(parser);
- pm_else_node_t *else_node = pm_else_node_create(parser, colon, else_statements, &end_keyword);
-
- pm_if_node_t *node = PM_ALLOC_NODE(parser, pm_if_node_t);
-
- *node = (pm_if_node_t) {
- {
- .type = PM_IF_NODE,
- .flags = PM_NODE_FLAG_NEWLINE,
- .location = {
- .start = predicate->location.start,
- .end = false_expression->location.end,
- },
- },
- .if_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .predicate = predicate,
- .then_keyword_loc = PM_LOCATION_TOKEN_VALUE(qmark),
- .statements = if_statements,
- .consequent = (pm_node_t *)else_node,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-
-}
-
-static inline void
-pm_if_node_end_keyword_loc_set(pm_if_node_t *node, const pm_token_t *keyword) {
- node->base.location.end = keyword->end;
- node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword);
-}
-
-static inline void
-pm_else_node_end_keyword_loc_set(pm_else_node_t *node, const pm_token_t *keyword) {
- node->base.location.end = keyword->end;
- node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword);
-}
-
-/**
- * Allocate and initialize a new ImplicitNode node.
- */
-static pm_implicit_node_t *
-pm_implicit_node_create(pm_parser_t *parser, pm_node_t *value) {
- pm_implicit_node_t *node = PM_ALLOC_NODE(parser, pm_implicit_node_t);
-
- *node = (pm_implicit_node_t) {
- {
- .type = PM_IMPLICIT_NODE,
- .location = value->location
- },
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ImplicitRestNode node.
- */
-static pm_implicit_rest_node_t *
-pm_implicit_rest_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_COMMA);
-
- pm_implicit_rest_node_t *node = PM_ALLOC_NODE(parser, pm_implicit_rest_node_t);
-
- *node = (pm_implicit_rest_node_t) {
- {
- .type = PM_IMPLICIT_REST_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IntegerNode node.
- */
-static pm_integer_node_t *
-pm_integer_node_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_INTEGER);
- pm_integer_node_t *node = PM_ALLOC_NODE(parser, pm_integer_node_t);
-
- *node = (pm_integer_node_t) {{
- .type = PM_INTEGER_NODE,
- .flags = base | PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IntegerNode node from an INTEGER_IMAGINARY
- * token.
- */
-static pm_imaginary_node_t *
-pm_integer_node_imaginary_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_INTEGER_IMAGINARY);
-
- pm_imaginary_node_t *node = PM_ALLOC_NODE(parser, pm_imaginary_node_t);
- *node = (pm_imaginary_node_t) {
- {
- .type = PM_IMAGINARY_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .numeric = (pm_node_t *) pm_integer_node_create(parser, base, &((pm_token_t) {
- .type = PM_TOKEN_INTEGER,
- .start = token->start,
- .end = token->end - 1
- }))
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IntegerNode node from an INTEGER_RATIONAL
- * token.
- */
-static pm_rational_node_t *
-pm_integer_node_rational_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_INTEGER_RATIONAL);
-
- pm_rational_node_t *node = PM_ALLOC_NODE(parser, pm_rational_node_t);
- *node = (pm_rational_node_t) {
- {
- .type = PM_RATIONAL_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .numeric = (pm_node_t *) pm_integer_node_create(parser, base, &((pm_token_t) {
- .type = PM_TOKEN_INTEGER,
- .start = token->start,
- .end = token->end - 1
- }))
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new IntegerNode node from an
- * INTEGER_RATIONAL_IMAGINARY token.
- */
-static pm_imaginary_node_t *
-pm_integer_node_rational_imaginary_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_INTEGER_RATIONAL_IMAGINARY);
-
- pm_imaginary_node_t *node = PM_ALLOC_NODE(parser, pm_imaginary_node_t);
- *node = (pm_imaginary_node_t) {
- {
- .type = PM_IMAGINARY_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .numeric = (pm_node_t *) pm_integer_node_rational_create(parser, base, &((pm_token_t) {
- .type = PM_TOKEN_INTEGER_RATIONAL,
- .start = token->start,
- .end = token->end - 1
- }))
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new InNode node.
- */
-static pm_in_node_t *
-pm_in_node_create(pm_parser_t *parser, pm_node_t *pattern, pm_statements_node_t *statements, const pm_token_t *in_keyword, const pm_token_t *then_keyword) {
- pm_in_node_t *node = PM_ALLOC_NODE(parser, pm_in_node_t);
-
- const uint8_t *end;
- if (statements != NULL) {
- end = statements->base.location.end;
- } else if (then_keyword->type != PM_TOKEN_NOT_PROVIDED) {
- end = then_keyword->end;
- } else {
- end = pattern->location.end;
- }
-
- *node = (pm_in_node_t) {
- {
- .type = PM_IN_NODE,
- .location = {
- .start = in_keyword->start,
- .end = end
- },
- },
- .pattern = pattern,
- .statements = statements,
- .in_loc = PM_LOCATION_TOKEN_VALUE(in_keyword),
- .then_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new InstanceVariableAndWriteNode node.
- */
-static pm_instance_variable_and_write_node_t *
-pm_instance_variable_and_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_instance_variable_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_instance_variable_and_write_node_t);
-
- *node = (pm_instance_variable_and_write_node_t) {
- {
- .type = PM_INSTANCE_VARIABLE_AND_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new InstanceVariableOperatorWriteNode node.
- */
-static pm_instance_variable_operator_write_node_t *
-pm_instance_variable_operator_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_instance_variable_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_instance_variable_operator_write_node_t);
-
- *node = (pm_instance_variable_operator_write_node_t) {
- {
- .type = PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new InstanceVariableOrWriteNode node.
- */
-static pm_instance_variable_or_write_node_t *
-pm_instance_variable_or_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_instance_variable_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_instance_variable_or_write_node_t);
-
- *node = (pm_instance_variable_or_write_node_t) {
- {
- .type = PM_INSTANCE_VARIABLE_OR_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .name = target->name,
- .name_loc = target->base.location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new InstanceVariableReadNode node.
- */
-static pm_instance_variable_read_node_t *
-pm_instance_variable_read_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_INSTANCE_VARIABLE);
- pm_instance_variable_read_node_t *node = PM_ALLOC_NODE(parser, pm_instance_variable_read_node_t);
-
- *node = (pm_instance_variable_read_node_t) {
- {
- .type = PM_INSTANCE_VARIABLE_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .name = pm_parser_constant_id_token(parser, token)
- };
-
- return node;
-}
-
-/**
- * Initialize a new InstanceVariableWriteNode node from an InstanceVariableRead
- * node.
- */
-static pm_instance_variable_write_node_t *
-pm_instance_variable_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *read_node, pm_token_t *operator, pm_node_t *value) {
- pm_instance_variable_write_node_t *node = PM_ALLOC_NODE(parser, pm_instance_variable_write_node_t);
- *node = (pm_instance_variable_write_node_t) {
- {
- .type = PM_INSTANCE_VARIABLE_WRITE_NODE,
- .location = {
- .start = read_node->base.location.start,
- .end = value->location.end
- }
- },
- .name = read_node->name,
- .name_loc = PM_LOCATION_NODE_BASE_VALUE(read_node),
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate a new InterpolatedRegularExpressionNode node.
- */
-static pm_interpolated_regular_expression_node_t *
-pm_interpolated_regular_expression_node_create(pm_parser_t *parser, const pm_token_t *opening) {
- pm_interpolated_regular_expression_node_t *node = PM_ALLOC_NODE(parser, pm_interpolated_regular_expression_node_t);
-
- *node = (pm_interpolated_regular_expression_node_t) {
- {
- .type = PM_INTERPOLATED_REGULAR_EXPRESSION_NODE,
- .location = {
- .start = opening->start,
- .end = NULL,
- },
- },
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .parts = { 0 }
- };
-
- return node;
-}
-
-static inline void
-pm_interpolated_regular_expression_node_append(pm_interpolated_regular_expression_node_t *node, pm_node_t *part) {
- if (node->base.location.start > part->location.start) {
- node->base.location.start = part->location.start;
- }
- if (node->base.location.end < part->location.end) {
- node->base.location.end = part->location.end;
- }
- pm_node_list_append(&node->parts, part);
-}
-
-static inline void
-pm_interpolated_regular_expression_node_closing_set(pm_interpolated_regular_expression_node_t *node, const pm_token_t *closing) {
- node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing);
- node->base.location.end = closing->end;
- pm_node_flag_set((pm_node_t *)node, pm_regular_expression_flags_create(closing));
-}
-
-/**
- * Allocate and initialize a new InterpolatedStringNode node.
- */
-static pm_interpolated_string_node_t *
-pm_interpolated_string_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_node_list_t *parts, const pm_token_t *closing) {
- pm_interpolated_string_node_t *node = PM_ALLOC_NODE(parser, pm_interpolated_string_node_t);
-
- *node = (pm_interpolated_string_node_t) {
- {
- .type = PM_INTERPOLATED_STRING_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end,
- },
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .parts = { 0 }
- };
-
- if (parts != NULL) {
- node->parts = *parts;
- }
-
- return node;
-}
-
-/**
- * Append a part to an InterpolatedStringNode node.
- */
-static inline void
-pm_interpolated_string_node_append(pm_interpolated_string_node_t *node, pm_node_t *part) {
- if (node->parts.size == 0 && node->opening_loc.start == NULL) {
- node->base.location.start = part->location.start;
- }
-
- pm_node_list_append(&node->parts, part);
- node->base.location.end = part->location.end;
-}
-
-/**
- * Set the closing token of the given InterpolatedStringNode node.
- */
-static void
-pm_interpolated_string_node_closing_set(pm_interpolated_string_node_t *node, const pm_token_t *closing) {
- node->closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing);
- node->base.location.end = closing->end;
-}
-
-/**
- * Allocate and initialize a new InterpolatedSymbolNode node.
- */
-static pm_interpolated_symbol_node_t *
-pm_interpolated_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_node_list_t *parts, const pm_token_t *closing) {
- pm_interpolated_symbol_node_t *node = PM_ALLOC_NODE(parser, pm_interpolated_symbol_node_t);
-
- *node = (pm_interpolated_symbol_node_t) {
- {
- .type = PM_INTERPOLATED_SYMBOL_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end,
- },
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .parts = { 0 }
- };
-
- if (parts != NULL) {
- node->parts = *parts;
- }
-
- return node;
-}
-
-static inline void
-pm_interpolated_symbol_node_append(pm_interpolated_symbol_node_t *node, pm_node_t *part) {
- if (node->parts.size == 0 && node->opening_loc.start == NULL) {
- node->base.location.start = part->location.start;
- }
-
- pm_node_list_append(&node->parts, part);
- node->base.location.end = part->location.end;
-}
-
-/**
- * Allocate a new InterpolatedXStringNode node.
- */
-static pm_interpolated_x_string_node_t *
-pm_interpolated_xstring_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) {
- pm_interpolated_x_string_node_t *node = PM_ALLOC_NODE(parser, pm_interpolated_x_string_node_t);
-
- *node = (pm_interpolated_x_string_node_t) {
- {
- .type = PM_INTERPOLATED_X_STRING_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end
- },
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .parts = { 0 }
- };
-
- return node;
-}
-
-static inline void
-pm_interpolated_xstring_node_append(pm_interpolated_x_string_node_t *node, pm_node_t *part) {
- pm_node_list_append(&node->parts, part);
- node->base.location.end = part->location.end;
-}
-
-static inline void
-pm_interpolated_xstring_node_closing_set(pm_interpolated_x_string_node_t *node, const pm_token_t *closing) {
- node->closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing);
- node->base.location.end = closing->end;
-}
-
-/**
- * Allocate a new KeywordHashNode node.
- */
-static pm_keyword_hash_node_t *
-pm_keyword_hash_node_create(pm_parser_t *parser) {
- pm_keyword_hash_node_t *node = PM_ALLOC_NODE(parser, pm_keyword_hash_node_t);
-
- *node = (pm_keyword_hash_node_t) {
- .base = {
- .type = PM_KEYWORD_HASH_NODE,
- .location = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .flags = PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS
- },
- .elements = { 0 }
- };
-
- return node;
-}
-
-/**
- * Append an element to a KeywordHashNode node.
- */
-static void
-pm_keyword_hash_node_elements_append(pm_keyword_hash_node_t *hash, pm_node_t *element) {
- // If the element being added is not an AssocNode or does not have a symbol key, then
- // we want to turn the STATIC_KEYS flag off.
- // TODO: Rename the flag to SYMBOL_KEYS instead.
- if (!PM_NODE_TYPE_P(element, PM_ASSOC_NODE) || !PM_NODE_TYPE_P(((pm_assoc_node_t *) element)->key, PM_SYMBOL_NODE)) {
- pm_node_flag_unset((pm_node_t *)hash, PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS);
- }
-
- pm_node_list_append(&hash->elements, element);
- if (hash->base.location.start == NULL) {
- hash->base.location.start = element->location.start;
- }
- hash->base.location.end = element->location.end;
-}
-
-/**
- * Allocate and initialize a new RequiredKeywordParameterNode node.
- */
-static pm_required_keyword_parameter_node_t *
-pm_required_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t *name) {
- pm_required_keyword_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_required_keyword_parameter_node_t);
-
- *node = (pm_required_keyword_parameter_node_t) {
- {
- .type = PM_REQUIRED_KEYWORD_PARAMETER_NODE,
- .location = {
- .start = name->start,
- .end = name->end
- },
- },
- .name = pm_parser_constant_id_location(parser, name->start, name->end - 1),
- .name_loc = PM_LOCATION_TOKEN_VALUE(name),
- };
-
- return node;
-}
-
-/**
- * Allocate a new OptionalKeywordParameterNode node.
- */
-static pm_optional_keyword_parameter_node_t *
-pm_optional_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, pm_node_t *value) {
- pm_optional_keyword_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_optional_keyword_parameter_node_t);
-
- *node = (pm_optional_keyword_parameter_node_t) {
- {
- .type = PM_OPTIONAL_KEYWORD_PARAMETER_NODE,
- .location = {
- .start = name->start,
- .end = value->location.end
- },
- },
- .name = pm_parser_constant_id_location(parser, name->start, name->end - 1),
- .name_loc = PM_LOCATION_TOKEN_VALUE(name),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate a new KeywordRestParameterNode node.
- */
-static pm_keyword_rest_parameter_node_t *
-pm_keyword_rest_parameter_node_create(pm_parser_t *parser, const pm_token_t *operator, const pm_token_t *name) {
- pm_keyword_rest_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_keyword_rest_parameter_node_t);
-
- *node = (pm_keyword_rest_parameter_node_t) {
- {
- .type = PM_KEYWORD_REST_PARAMETER_NODE,
- .location = {
- .start = operator->start,
- .end = (name->type == PM_TOKEN_NOT_PROVIDED ? operator->end : name->end)
- },
- },
- .name = pm_parser_optional_constant_id_token(parser, name),
- .name_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(name),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate a new LambdaNode node.
- */
-static pm_lambda_node_t *
-pm_lambda_node_create(
- pm_parser_t *parser,
- pm_constant_id_list_t *locals,
- uint32_t locals_body_index,
- const pm_token_t *operator,
- const pm_token_t *opening,
- const pm_token_t *closing,
- pm_node_t *parameters,
- pm_node_t *body
-) {
- pm_lambda_node_t *node = PM_ALLOC_NODE(parser, pm_lambda_node_t);
-
- *node = (pm_lambda_node_t) {
- {
- .type = PM_LAMBDA_NODE,
- .location = {
- .start = operator->start,
- .end = closing->end
- },
- },
- .locals = *locals,
- .locals_body_index = locals_body_index,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
- .parameters = parameters,
- .body = body
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new LocalVariableAndWriteNode node.
- */
-static pm_local_variable_and_write_node_t *
-pm_local_variable_and_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value, pm_constant_id_t name, uint32_t depth) {
- assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_READ_NODE) || PM_NODE_TYPE_P(target, PM_CALL_NODE));
- assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- pm_local_variable_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_and_write_node_t);
-
- *node = (pm_local_variable_and_write_node_t) {
- {
- .type = PM_LOCAL_VARIABLE_AND_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- }
- },
- .name_loc = target->location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .name = name,
- .depth = depth
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new LocalVariableOperatorWriteNode node.
- */
-static pm_local_variable_operator_write_node_t *
-pm_local_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value, pm_constant_id_t name, uint32_t depth) {
- pm_local_variable_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_operator_write_node_t);
-
- *node = (pm_local_variable_operator_write_node_t) {
- {
- .type = PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- }
- },
- .name_loc = target->location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .name = name,
- .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
- .depth = depth
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new LocalVariableOrWriteNode node.
- */
-static pm_local_variable_or_write_node_t *
-pm_local_variable_or_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value, pm_constant_id_t name, uint32_t depth) {
- assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_READ_NODE) || PM_NODE_TYPE_P(target, PM_CALL_NODE));
- assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
- pm_local_variable_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_or_write_node_t);
-
- *node = (pm_local_variable_or_write_node_t) {
- {
- .type = PM_LOCAL_VARIABLE_OR_WRITE_NODE,
- .location = {
- .start = target->location.start,
- .end = value->location.end
- }
- },
- .name_loc = target->location,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value,
- .name = name,
- .depth = depth
- };
-
- return node;
-}
-
-/**
- * Allocate a new LocalVariableReadNode node.
- */
-static pm_local_variable_read_node_t *
-pm_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) {
- pm_constant_id_t name_id = pm_parser_constant_id_token(parser, name);
-
- if (parser->current_param_name == name_id) {
- pm_parser_err_token(parser, name, PM_ERR_PARAMETER_CIRCULAR);
- }
-
- pm_local_variable_read_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_read_node_t);
-
- *node = (pm_local_variable_read_node_t) {
- {
- .type = PM_LOCAL_VARIABLE_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(name)
- },
- .name = name_id,
- .depth = depth
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new LocalVariableWriteNode node.
- */
-static pm_local_variable_write_node_t *
-pm_local_variable_write_node_create(pm_parser_t *parser, pm_constant_id_t name, uint32_t depth, pm_node_t *value, const pm_location_t *name_loc, const pm_token_t *operator) {
- pm_local_variable_write_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_write_node_t);
-
- *node = (pm_local_variable_write_node_t) {
- {
- .type = PM_LOCAL_VARIABLE_WRITE_NODE,
- .location = {
- .start = name_loc->start,
- .end = value->location.end
- }
- },
- .name = name,
- .depth = depth,
- .value = value,
- .name_loc = *name_loc,
- .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Returns true if the given bounds comprise a numbered parameter (i.e., they
- * are of the form /^_\d$/).
- */
-static inline bool
-pm_token_is_numbered_parameter(const uint8_t *start, const uint8_t *end) {
- return (end - start == 2) && (start[0] == '_') && (start[1] != '0') && (pm_char_is_decimal_digit(start[1]));
-}
-
-/**
- * Ensure the given bounds do not comprise a numbered parameter. If they do, add
- * an appropriate error message to the parser.
- */
-static inline void
-pm_refute_numbered_parameter(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- if (pm_token_is_numbered_parameter(start, end)) {
- PM_PARSER_ERR_FORMAT(parser, start, end, PM_ERR_PARAMETER_NUMBERED_RESERVED, start);
- }
-}
-
-/**
- * Allocate and initialize a new LocalVariableTargetNode node with the given
- * name and depth.
- */
-static pm_local_variable_target_node_t *
-pm_local_variable_target_node_create_values(pm_parser_t *parser, const pm_location_t *location, pm_constant_id_t name, uint32_t depth) {
- pm_local_variable_target_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_target_node_t);
-
- *node = (pm_local_variable_target_node_t) {
- {
- .type = PM_LOCAL_VARIABLE_TARGET_NODE,
- .location = *location
- },
- .name = name,
- .depth = depth
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new LocalVariableTargetNode node.
- */
-static pm_local_variable_target_node_t *
-pm_local_variable_target_node_create(pm_parser_t *parser, const pm_token_t *name) {
- pm_refute_numbered_parameter(parser, name->start, name->end);
-
- return pm_local_variable_target_node_create_values(
- parser,
- &(pm_location_t) { .start = name->start, .end = name->end },
- pm_parser_constant_id_token(parser, name),
- 0
- );
-}
-
-/**
- * Allocate and initialize a new LocalVariableTargetNode node with the given depth.
- */
-static pm_local_variable_target_node_t *
-pm_local_variable_target_node_create_depth(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) {
- pm_refute_numbered_parameter(parser, name->start, name->end);
-
- return pm_local_variable_target_node_create_values(
- parser,
- &(pm_location_t) { .start = name->start, .end = name->end },
- pm_parser_constant_id_token(parser, name),
- depth
- );
-}
-
-/**
- * Allocate and initialize a new MatchPredicateNode node.
- */
-static pm_match_predicate_node_t *
-pm_match_predicate_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t *pattern, const pm_token_t *operator) {
- pm_assert_value_expression(parser, value);
-
- pm_match_predicate_node_t *node = PM_ALLOC_NODE(parser, pm_match_predicate_node_t);
-
- *node = (pm_match_predicate_node_t) {
- {
- .type = PM_MATCH_PREDICATE_NODE,
- .location = {
- .start = value->location.start,
- .end = pattern->location.end
- }
- },
- .value = value,
- .pattern = pattern,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new MatchRequiredNode node.
- */
-static pm_match_required_node_t *
-pm_match_required_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t *pattern, const pm_token_t *operator) {
- pm_assert_value_expression(parser, value);
-
- pm_match_required_node_t *node = PM_ALLOC_NODE(parser, pm_match_required_node_t);
-
- *node = (pm_match_required_node_t) {
- {
- .type = PM_MATCH_REQUIRED_NODE,
- .location = {
- .start = value->location.start,
- .end = pattern->location.end
- }
- },
- .value = value,
- .pattern = pattern,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new MatchWriteNode node.
- */
-static pm_match_write_node_t *
-pm_match_write_node_create(pm_parser_t *parser, pm_call_node_t *call) {
- pm_match_write_node_t *node = PM_ALLOC_NODE(parser, pm_match_write_node_t);
-
- *node = (pm_match_write_node_t) {
- {
- .type = PM_MATCH_WRITE_NODE,
- .location = call->base.location
- },
- .call = call,
- .targets = { 0 }
- };
-
- return node;
-}
-
-/**
- * Allocate a new ModuleNode node.
- */
-static pm_module_node_t *
-pm_module_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *module_keyword, pm_node_t *constant_path, const pm_token_t *name, pm_node_t *body, const pm_token_t *end_keyword) {
- pm_module_node_t *node = PM_ALLOC_NODE(parser, pm_module_node_t);
-
- *node = (pm_module_node_t) {
- {
- .type = PM_MODULE_NODE,
- .location = {
- .start = module_keyword->start,
- .end = end_keyword->end
- }
- },
- .locals = (locals == NULL ? ((pm_constant_id_list_t) { .ids = NULL, .size = 0, .capacity = 0 }) : *locals),
- .module_keyword_loc = PM_LOCATION_TOKEN_VALUE(module_keyword),
- .constant_path = constant_path,
- .body = body,
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword),
- .name = pm_parser_constant_id_token(parser, name)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize new MultiTargetNode node.
- */
-static pm_multi_target_node_t *
-pm_multi_target_node_create(pm_parser_t *parser) {
- pm_multi_target_node_t *node = PM_ALLOC_NODE(parser, pm_multi_target_node_t);
-
- *node = (pm_multi_target_node_t) {
- {
- .type = PM_MULTI_TARGET_NODE,
- .location = { .start = NULL, .end = NULL }
- },
- .lefts = { 0 },
- .rest = NULL,
- .rights = { 0 },
- .lparen_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .rparen_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-}
-
-/**
- * Append a target to a MultiTargetNode node.
- */
-static void
-pm_multi_target_node_targets_append(pm_parser_t *parser, pm_multi_target_node_t *node, pm_node_t *target) {
- if (PM_NODE_TYPE_P(target, PM_SPLAT_NODE) || PM_NODE_TYPE_P(target, PM_IMPLICIT_REST_NODE)) {
- if (node->rest == NULL) {
- node->rest = target;
- } else {
- pm_parser_err_node(parser, target, PM_ERR_MULTI_ASSIGN_MULTI_SPLATS);
- pm_node_list_append(&node->rights, target);
- }
- } else if (node->rest == NULL) {
- pm_node_list_append(&node->lefts, target);
- } else {
- pm_node_list_append(&node->rights, target);
- }
-
- if (node->base.location.start == NULL || (node->base.location.start > target->location.start)) {
- node->base.location.start = target->location.start;
- }
-
- if (node->base.location.end == NULL || (node->base.location.end < target->location.end)) {
- node->base.location.end = target->location.end;
- }
-}
-
-/**
- * Set the opening of a MultiTargetNode node.
- */
-static void
-pm_multi_target_node_opening_set(pm_multi_target_node_t *node, const pm_token_t *lparen) {
- node->base.location.start = lparen->start;
- node->lparen_loc = PM_LOCATION_TOKEN_VALUE(lparen);
-}
-
-/**
- * Set the closing of a MultiTargetNode node.
- */
-static void
-pm_multi_target_node_closing_set(pm_multi_target_node_t *node, const pm_token_t *rparen) {
- node->base.location.end = rparen->end;
- node->rparen_loc = PM_LOCATION_TOKEN_VALUE(rparen);
-}
-
-/**
- * Allocate a new MultiWriteNode node.
- */
-static pm_multi_write_node_t *
-pm_multi_write_node_create(pm_parser_t *parser, pm_multi_target_node_t *target, const pm_token_t *operator, pm_node_t *value) {
- pm_multi_write_node_t *node = PM_ALLOC_NODE(parser, pm_multi_write_node_t);
-
- *node = (pm_multi_write_node_t) {
- {
- .type = PM_MULTI_WRITE_NODE,
- .location = {
- .start = target->base.location.start,
- .end = value->location.end
- }
- },
- .lefts = target->lefts,
- .rest = target->rest,
- .rights = target->rights,
- .lparen_loc = target->lparen_loc,
- .rparen_loc = target->rparen_loc,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- // Explicitly do not call pm_node_destroy here because we want to keep
- // around all of the information within the MultiWriteNode node.
- free(target);
-
- return node;
-}
-
-/**
- * Allocate and initialize a new NextNode node.
- */
-static pm_next_node_t *
-pm_next_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_node_t *arguments) {
- assert(keyword->type == PM_TOKEN_KEYWORD_NEXT);
- pm_next_node_t *node = PM_ALLOC_NODE(parser, pm_next_node_t);
-
- *node = (pm_next_node_t) {
- {
- .type = PM_NEXT_NODE,
- .location = {
- .start = keyword->start,
- .end = (arguments == NULL ? keyword->end : arguments->base.location.end)
- }
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .arguments = arguments
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new NilNode node.
- */
-static pm_nil_node_t *
-pm_nil_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_NIL);
- pm_nil_node_t *node = PM_ALLOC_NODE(parser, pm_nil_node_t);
-
- *node = (pm_nil_node_t) {{
- .type = PM_NIL_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate and initialize a new NoKeywordsParameterNode node.
- */
-static pm_no_keywords_parameter_node_t *
-pm_no_keywords_parameter_node_create(pm_parser_t *parser, const pm_token_t *operator, const pm_token_t *keyword) {
- assert(operator->type == PM_TOKEN_USTAR_STAR || operator->type == PM_TOKEN_STAR_STAR);
- assert(keyword->type == PM_TOKEN_KEYWORD_NIL);
- pm_no_keywords_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_no_keywords_parameter_node_t);
-
- *node = (pm_no_keywords_parameter_node_t) {
- {
- .type = PM_NO_KEYWORDS_PARAMETER_NODE,
- .location = {
- .start = operator->start,
- .end = keyword->end
- }
- },
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new NumberedParametersNode node.
- */
-static pm_numbered_parameters_node_t *
-pm_numbered_parameters_node_create(pm_parser_t *parser, const pm_location_t *location, uint8_t maximum) {
- pm_numbered_parameters_node_t *node = PM_ALLOC_NODE(parser, pm_numbered_parameters_node_t);
-
- *node = (pm_numbered_parameters_node_t) {
- {
- .type = PM_NUMBERED_PARAMETERS_NODE,
- .location = *location
- },
- .maximum = maximum
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new NthReferenceReadNode node.
- */
-static pm_numbered_reference_read_node_t *
-pm_numbered_reference_read_node_create(pm_parser_t *parser, const pm_token_t *name) {
- assert(name->type == PM_TOKEN_NUMBERED_REFERENCE);
- pm_numbered_reference_read_node_t *node = PM_ALLOC_NODE(parser, pm_numbered_reference_read_node_t);
-
- *node = (pm_numbered_reference_read_node_t) {
- {
- .type = PM_NUMBERED_REFERENCE_READ_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(name),
- },
- .number = parse_decimal_number(parser, name->start + 1, name->end)
- };
-
- return node;
-}
-
-/**
- * Allocate a new OptionalParameterNode node.
- */
-static pm_optional_parameter_node_t *
-pm_optional_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, const pm_token_t *operator, pm_node_t *value) {
- pm_optional_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_optional_parameter_node_t);
-
- *node = (pm_optional_parameter_node_t) {
- {
- .type = PM_OPTIONAL_PARAMETER_NODE,
- .location = {
- .start = name->start,
- .end = value->location.end
- }
- },
- .name = pm_parser_constant_id_token(parser, name),
- .name_loc = PM_LOCATION_TOKEN_VALUE(name),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .value = value
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new OrNode node.
- */
-static pm_or_node_t *
-pm_or_node_create(pm_parser_t *parser, pm_node_t *left, const pm_token_t *operator, pm_node_t *right) {
- pm_assert_value_expression(parser, left);
-
- pm_or_node_t *node = PM_ALLOC_NODE(parser, pm_or_node_t);
-
- *node = (pm_or_node_t) {
- {
- .type = PM_OR_NODE,
- .location = {
- .start = left->location.start,
- .end = right->location.end
- }
- },
- .left = left,
- .right = right,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new ParametersNode node.
- */
-static pm_parameters_node_t *
-pm_parameters_node_create(pm_parser_t *parser) {
- pm_parameters_node_t *node = PM_ALLOC_NODE(parser, pm_parameters_node_t);
-
- *node = (pm_parameters_node_t) {
- {
- .type = PM_PARAMETERS_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(&parser->current)
- },
- .rest = NULL,
- .keyword_rest = NULL,
- .block = NULL,
- .requireds = { 0 },
- .optionals = { 0 },
- .posts = { 0 },
- .keywords = { 0 }
- };
-
- return node;
-}
-
-/**
- * Set the location properly for the parameters node.
- */
-static void
-pm_parameters_node_location_set(pm_parameters_node_t *params, pm_node_t *param) {
- if (params->base.location.start == NULL) {
- params->base.location.start = param->location.start;
- } else {
- params->base.location.start = params->base.location.start < param->location.start ? params->base.location.start : param->location.start;
- }
-
- if (params->base.location.end == NULL) {
- params->base.location.end = param->location.end;
- } else {
- params->base.location.end = params->base.location.end > param->location.end ? params->base.location.end : param->location.end;
- }
-}
-
-/**
- * Append a required parameter to a ParametersNode node.
- */
-static void
-pm_parameters_node_requireds_append(pm_parameters_node_t *params, pm_node_t *param) {
- pm_parameters_node_location_set(params, param);
- pm_node_list_append(&params->requireds, param);
-}
-
-/**
- * Append an optional parameter to a ParametersNode node.
- */
-static void
-pm_parameters_node_optionals_append(pm_parameters_node_t *params, pm_optional_parameter_node_t *param) {
- pm_parameters_node_location_set(params, (pm_node_t *) param);
- pm_node_list_append(&params->optionals, (pm_node_t *) param);
-}
-
-/**
- * Append a post optional arguments parameter to a ParametersNode node.
- */
-static void
-pm_parameters_node_posts_append(pm_parameters_node_t *params, pm_node_t *param) {
- pm_parameters_node_location_set(params, param);
- pm_node_list_append(&params->posts, param);
-}
-
-/**
- * Set the rest parameter on a ParametersNode node.
- */
-static void
-pm_parameters_node_rest_set(pm_parameters_node_t *params, pm_node_t *param) {
- pm_parameters_node_location_set(params, param);
- params->rest = param;
-}
-
-/**
- * Append a keyword parameter to a ParametersNode node.
- */
-static void
-pm_parameters_node_keywords_append(pm_parameters_node_t *params, pm_node_t *param) {
- pm_parameters_node_location_set(params, param);
- pm_node_list_append(&params->keywords, param);
-}
-
-/**
- * Set the keyword rest parameter on a ParametersNode node.
- */
-static void
-pm_parameters_node_keyword_rest_set(pm_parameters_node_t *params, pm_node_t *param) {
- assert(params->keyword_rest == NULL);
- pm_parameters_node_location_set(params, param);
- params->keyword_rest = param;
-}
-
-/**
- * Set the block parameter on a ParametersNode node.
- */
-static void
-pm_parameters_node_block_set(pm_parameters_node_t *params, pm_block_parameter_node_t *param) {
- assert(params->block == NULL);
- pm_parameters_node_location_set(params, (pm_node_t *) param);
- params->block = param;
-}
-
-/**
- * Allocate a new ProgramNode node.
- */
-static pm_program_node_t *
-pm_program_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, pm_statements_node_t *statements) {
- pm_program_node_t *node = PM_ALLOC_NODE(parser, pm_program_node_t);
-
- *node = (pm_program_node_t) {
- {
- .type = PM_PROGRAM_NODE,
- .location = {
- .start = statements == NULL ? parser->start : statements->base.location.start,
- .end = statements == NULL ? parser->end : statements->base.location.end
- }
- },
- .locals = *locals,
- .statements = statements
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize new ParenthesesNode node.
- */
-static pm_parentheses_node_t *
-pm_parentheses_node_create(pm_parser_t *parser, const pm_token_t *opening, pm_node_t *body, const pm_token_t *closing) {
- pm_parentheses_node_t *node = PM_ALLOC_NODE(parser, pm_parentheses_node_t);
-
- *node = (pm_parentheses_node_t) {
- {
- .type = PM_PARENTHESES_NODE,
- .location = {
- .start = opening->start,
- .end = closing->end
- }
- },
- .body = body,
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new PinnedExpressionNode node.
- */
-static pm_pinned_expression_node_t *
-pm_pinned_expression_node_create(pm_parser_t *parser, pm_node_t *expression, const pm_token_t *operator, const pm_token_t *lparen, const pm_token_t *rparen) {
- pm_pinned_expression_node_t *node = PM_ALLOC_NODE(parser, pm_pinned_expression_node_t);
-
- *node = (pm_pinned_expression_node_t) {
- {
- .type = PM_PINNED_EXPRESSION_NODE,
- .location = {
- .start = operator->start,
- .end = rparen->end
- }
- },
- .expression = expression,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .lparen_loc = PM_LOCATION_TOKEN_VALUE(lparen),
- .rparen_loc = PM_LOCATION_TOKEN_VALUE(rparen)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new PinnedVariableNode node.
- */
-static pm_pinned_variable_node_t *
-pm_pinned_variable_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *variable) {
- pm_pinned_variable_node_t *node = PM_ALLOC_NODE(parser, pm_pinned_variable_node_t);
-
- *node = (pm_pinned_variable_node_t) {
- {
- .type = PM_PINNED_VARIABLE_NODE,
- .location = {
- .start = operator->start,
- .end = variable->location.end
- }
- },
- .variable = variable,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new PostExecutionNode node.
- */
-static pm_post_execution_node_t *
-pm_post_execution_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *opening, pm_statements_node_t *statements, const pm_token_t *closing) {
- pm_post_execution_node_t *node = PM_ALLOC_NODE(parser, pm_post_execution_node_t);
-
- *node = (pm_post_execution_node_t) {
- {
- .type = PM_POST_EXECUTION_NODE,
- .location = {
- .start = keyword->start,
- .end = closing->end
- }
- },
- .statements = statements,
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new PreExecutionNode node.
- */
-static pm_pre_execution_node_t *
-pm_pre_execution_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *opening, pm_statements_node_t *statements, const pm_token_t *closing) {
- pm_pre_execution_node_t *node = PM_ALLOC_NODE(parser, pm_pre_execution_node_t);
-
- *node = (pm_pre_execution_node_t) {
- {
- .type = PM_PRE_EXECUTION_NODE,
- .location = {
- .start = keyword->start,
- .end = closing->end
- }
- },
- .statements = statements,
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize new RangeNode node.
- */
-static pm_range_node_t *
-pm_range_node_create(pm_parser_t *parser, pm_node_t *left, const pm_token_t *operator, pm_node_t *right) {
- pm_assert_value_expression(parser, left);
- pm_assert_value_expression(parser, right);
-
- pm_range_node_t *node = PM_ALLOC_NODE(parser, pm_range_node_t);
- pm_node_flags_t flags = 0;
-
- // Indicate that this node an exclusive range if the operator is `...`.
- if (operator->type == PM_TOKEN_DOT_DOT_DOT || operator->type == PM_TOKEN_UDOT_DOT_DOT) {
- flags |= PM_RANGE_FLAGS_EXCLUDE_END;
- }
-
- // Indicate that this node is a static literal (i.e., can be compiled with
- // a putobject in CRuby) if the left and right are implicit nil, explicit
- // nil, or integers.
- if (
- (left == NULL || PM_NODE_TYPE_P(left, PM_NIL_NODE) || PM_NODE_TYPE_P(left, PM_INTEGER_NODE)) &&
- (right == NULL || PM_NODE_TYPE_P(right, PM_NIL_NODE) || PM_NODE_TYPE_P(right, PM_INTEGER_NODE))
- ) {
- flags |= PM_NODE_FLAG_STATIC_LITERAL;
- }
-
- *node = (pm_range_node_t) {
- {
- .type = PM_RANGE_NODE,
- .flags = flags,
- .location = {
- .start = (left == NULL ? operator->start : left->location.start),
- .end = (right == NULL ? operator->end : right->location.end)
- }
- },
- .left = left,
- .right = right,
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new RedoNode node.
- */
-static pm_redo_node_t *
-pm_redo_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_REDO);
- pm_redo_node_t *node = PM_ALLOC_NODE(parser, pm_redo_node_t);
-
- *node = (pm_redo_node_t) {{ .type = PM_REDO_NODE, .location = PM_LOCATION_TOKEN_VALUE(token) }};
- return node;
-}
-
-/**
- * Allocate a new initialize a new RegularExpressionNode node with the given
- * unescaped string.
- */
-static pm_regular_expression_node_t *
-pm_regular_expression_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, const pm_string_t *unescaped) {
- pm_regular_expression_node_t *node = PM_ALLOC_NODE(parser, pm_regular_expression_node_t);
-
- *node = (pm_regular_expression_node_t) {
- {
- .type = PM_REGULAR_EXPRESSION_NODE,
- .flags = pm_regular_expression_flags_create(closing) | PM_NODE_FLAG_STATIC_LITERAL,
- .location = {
- .start = MIN(opening->start, closing->start),
- .end = MAX(opening->end, closing->end)
- }
- },
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .content_loc = PM_LOCATION_TOKEN_VALUE(content),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
- .unescaped = *unescaped
- };
-
- return node;
-}
-
-/**
- * Allocate a new initialize a new RegularExpressionNode node.
- */
-static inline pm_regular_expression_node_t *
-pm_regular_expression_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) {
- return pm_regular_expression_node_create_unescaped(parser, opening, content, closing, &PM_STRING_EMPTY);
-}
-
-/**
- * Allocate a new RequiredParameterNode node.
- */
-static pm_required_parameter_node_t *
-pm_required_parameter_node_create(pm_parser_t *parser, const pm_token_t *token) {
- pm_required_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_required_parameter_node_t);
-
- *node = (pm_required_parameter_node_t) {
- {
- .type = PM_REQUIRED_PARAMETER_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- },
- .name = pm_parser_constant_id_token(parser, token)
- };
-
- return node;
-}
-
-/**
- * Allocate a new RescueModifierNode node.
- */
-static pm_rescue_modifier_node_t *
-pm_rescue_modifier_node_create(pm_parser_t *parser, pm_node_t *expression, const pm_token_t *keyword, pm_node_t *rescue_expression) {
- pm_rescue_modifier_node_t *node = PM_ALLOC_NODE(parser, pm_rescue_modifier_node_t);
-
- *node = (pm_rescue_modifier_node_t) {
- {
- .type = PM_RESCUE_MODIFIER_NODE,
- .location = {
- .start = expression->location.start,
- .end = rescue_expression->location.end
- }
- },
- .expression = expression,
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .rescue_expression = rescue_expression
- };
-
- return node;
-}
-
-/**
- * Allocate and initiliaze a new RescueNode node.
- */
-static pm_rescue_node_t *
-pm_rescue_node_create(pm_parser_t *parser, const pm_token_t *keyword) {
- pm_rescue_node_t *node = PM_ALLOC_NODE(parser, pm_rescue_node_t);
-
- *node = (pm_rescue_node_t) {
- {
- .type = PM_RESCUE_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(keyword)
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .operator_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .reference = NULL,
- .statements = NULL,
- .consequent = NULL,
- .exceptions = { 0 }
- };
-
- return node;
-}
-
-static inline void
-pm_rescue_node_operator_set(pm_rescue_node_t *node, const pm_token_t *operator) {
- node->operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator);
-}
-
-/**
- * Set the reference of a rescue node, and update the location of the node.
- */
-static void
-pm_rescue_node_reference_set(pm_rescue_node_t *node, pm_node_t *reference) {
- node->reference = reference;
- node->base.location.end = reference->location.end;
-}
-
-/**
- * Set the statements of a rescue node, and update the location of the node.
- */
-static void
-pm_rescue_node_statements_set(pm_rescue_node_t *node, pm_statements_node_t *statements) {
- node->statements = statements;
- if (pm_statements_node_body_length(statements) > 0) {
- node->base.location.end = statements->base.location.end;
- }
-}
-
-/**
- * Set the consequent of a rescue node, and update the location.
- */
-static void
-pm_rescue_node_consequent_set(pm_rescue_node_t *node, pm_rescue_node_t *consequent) {
- node->consequent = consequent;
- node->base.location.end = consequent->base.location.end;
-}
-
-/**
- * Append an exception node to a rescue node, and update the location.
- */
-static void
-pm_rescue_node_exceptions_append(pm_rescue_node_t *node, pm_node_t *exception) {
- pm_node_list_append(&node->exceptions, exception);
- node->base.location.end = exception->location.end;
-}
-
-/**
- * Allocate a new RestParameterNode node.
- */
-static pm_rest_parameter_node_t *
-pm_rest_parameter_node_create(pm_parser_t *parser, const pm_token_t *operator, const pm_token_t *name) {
- pm_rest_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_rest_parameter_node_t);
-
- *node = (pm_rest_parameter_node_t) {
- {
- .type = PM_REST_PARAMETER_NODE,
- .location = {
- .start = operator->start,
- .end = (name->type == PM_TOKEN_NOT_PROVIDED ? operator->end : name->end)
- }
- },
- .name = pm_parser_optional_constant_id_token(parser, name),
- .name_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(name),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new RetryNode node.
- */
-static pm_retry_node_t *
-pm_retry_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_RETRY);
- pm_retry_node_t *node = PM_ALLOC_NODE(parser, pm_retry_node_t);
-
- *node = (pm_retry_node_t) {{ .type = PM_RETRY_NODE, .location = PM_LOCATION_TOKEN_VALUE(token) }};
- return node;
-}
-
-/**
- * Allocate a new ReturnNode node.
- */
-static pm_return_node_t *
-pm_return_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_node_t *arguments) {
- pm_return_node_t *node = PM_ALLOC_NODE(parser, pm_return_node_t);
-
- *node = (pm_return_node_t) {
- {
- .type = PM_RETURN_NODE,
- .location = {
- .start = keyword->start,
- .end = (arguments == NULL ? keyword->end : arguments->base.location.end)
- }
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .arguments = arguments
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new SelfNode node.
- */
-static pm_self_node_t *
-pm_self_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_SELF);
- pm_self_node_t *node = PM_ALLOC_NODE(parser, pm_self_node_t);
-
- *node = (pm_self_node_t) {{
- .type = PM_SELF_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate a new SingletonClassNode node.
- */
-static pm_singleton_class_node_t *
-pm_singleton_class_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *class_keyword, const pm_token_t *operator, pm_node_t *expression, pm_node_t *body, const pm_token_t *end_keyword) {
- pm_singleton_class_node_t *node = PM_ALLOC_NODE(parser, pm_singleton_class_node_t);
-
- *node = (pm_singleton_class_node_t) {
- {
- .type = PM_SINGLETON_CLASS_NODE,
- .location = {
- .start = class_keyword->start,
- .end = end_keyword->end
- }
- },
- .locals = *locals,
- .class_keyword_loc = PM_LOCATION_TOKEN_VALUE(class_keyword),
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .expression = expression,
- .body = body,
- .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword)
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new SourceEncodingNode node.
- */
-static pm_source_encoding_node_t *
-pm_source_encoding_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD___ENCODING__);
- pm_source_encoding_node_t *node = PM_ALLOC_NODE(parser, pm_source_encoding_node_t);
-
- *node = (pm_source_encoding_node_t) {{
- .type = PM_SOURCE_ENCODING_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate and initialize a new SourceFileNode node.
- */
-static pm_source_file_node_t*
-pm_source_file_node_create(pm_parser_t *parser, const pm_token_t *file_keyword) {
- pm_source_file_node_t *node = PM_ALLOC_NODE(parser, pm_source_file_node_t);
- assert(file_keyword->type == PM_TOKEN_KEYWORD___FILE__);
-
- *node = (pm_source_file_node_t) {
- {
- .type = PM_SOURCE_FILE_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(file_keyword),
- },
- .filepath = parser->filepath_string,
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new SourceLineNode node.
- */
-static pm_source_line_node_t *
-pm_source_line_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD___LINE__);
- pm_source_line_node_t *node = PM_ALLOC_NODE(parser, pm_source_line_node_t);
-
- *node = (pm_source_line_node_t) {{
- .type = PM_SOURCE_LINE_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate a new SplatNode node.
- */
-static pm_splat_node_t *
-pm_splat_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *expression) {
- pm_splat_node_t *node = PM_ALLOC_NODE(parser, pm_splat_node_t);
-
- *node = (pm_splat_node_t) {
- {
- .type = PM_SPLAT_NODE,
- .location = {
- .start = operator->start,
- .end = (expression == NULL ? operator->end : expression->location.end)
- }
- },
- .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
- .expression = expression
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new StatementsNode node.
- */
-static pm_statements_node_t *
-pm_statements_node_create(pm_parser_t *parser) {
- pm_statements_node_t *node = PM_ALLOC_NODE(parser, pm_statements_node_t);
-
- *node = (pm_statements_node_t) {
- {
- .type = PM_STATEMENTS_NODE,
- .location = PM_LOCATION_NULL_VALUE(parser)
- },
- .body = { 0 }
- };
-
- return node;
-}
-
-/**
- * Get the length of the given StatementsNode node's body.
- */
-static size_t
-pm_statements_node_body_length(pm_statements_node_t *node) {
- return node && node->body.size;
-}
-
-/**
- * Set the location of the given StatementsNode.
- */
-static void
-pm_statements_node_location_set(pm_statements_node_t *node, const uint8_t *start, const uint8_t *end) {
- node->base.location = (pm_location_t) { .start = start, .end = end };
-}
-
-/**
- * Append a new node to the given StatementsNode node's body.
- */
-static void
-pm_statements_node_body_append(pm_statements_node_t *node, pm_node_t *statement) {
- if (pm_statements_node_body_length(node) == 0 || statement->location.start < node->base.location.start) {
- node->base.location.start = statement->location.start;
- }
- if (statement->location.end > node->base.location.end) {
- node->base.location.end = statement->location.end;
- }
-
- pm_node_list_append(&node->body, statement);
-
- // Every statement gets marked as a place where a newline can occur.
- pm_node_flag_set(statement, PM_NODE_FLAG_NEWLINE);
-}
-
-/**
- * Allocate a new StringNode node with the current string on the parser.
- */
-static inline pm_string_node_t *
-pm_string_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, const pm_string_t *string) {
- pm_string_node_t *node = PM_ALLOC_NODE(parser, pm_string_node_t);
- pm_node_flags_t flags = 0;
-
- if (parser->frozen_string_literal) {
- flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN;
- }
-
- *node = (pm_string_node_t) {
- {
- .type = PM_STRING_NODE,
- .flags = flags,
- .location = {
- .start = (opening->type == PM_TOKEN_NOT_PROVIDED ? content->start : opening->start),
- .end = (closing->type == PM_TOKEN_NOT_PROVIDED ? content->end : closing->end)
- }
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .content_loc = PM_LOCATION_TOKEN_VALUE(content),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .unescaped = *string
- };
-
- return node;
-}
-
-/**
- * Allocate a new StringNode node.
- */
-static pm_string_node_t *
-pm_string_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) {
- return pm_string_node_create_unescaped(parser, opening, content, closing, &PM_STRING_EMPTY);
-}
-
-/**
- * Allocate a new StringNode node and create it using the current string on the
- * parser.
- */
-static pm_string_node_t *
-pm_string_node_create_current_string(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) {
- pm_string_node_t *node = pm_string_node_create_unescaped(parser, opening, content, closing, &parser->current_string);
- parser->current_string = PM_STRING_EMPTY;
- return node;
-}
-
-/**
- * Allocate and initialize a new SuperNode node.
- */
-static pm_super_node_t *
-pm_super_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_t *arguments) {
- assert(keyword->type == PM_TOKEN_KEYWORD_SUPER);
- pm_super_node_t *node = PM_ALLOC_NODE(parser, pm_super_node_t);
-
- const uint8_t *end = pm_arguments_end(arguments);
- if (end == NULL) {
- assert(false && "unreachable");
- }
-
- *node = (pm_super_node_t) {
- {
- .type = PM_SUPER_NODE,
- .location = {
- .start = keyword->start,
- .end = end,
- }
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .lparen_loc = arguments->opening_loc,
- .arguments = arguments->arguments,
- .rparen_loc = arguments->closing_loc,
- .block = arguments->block
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new SymbolNode node with the given unescaped
- * string.
- */
-static pm_symbol_node_t *
-pm_symbol_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing, const pm_string_t *unescaped) {
- pm_symbol_node_t *node = PM_ALLOC_NODE(parser, pm_symbol_node_t);
-
- *node = (pm_symbol_node_t) {
- {
- .type = PM_SYMBOL_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = {
- .start = (opening->type == PM_TOKEN_NOT_PROVIDED ? value->start : opening->start),
- .end = (closing->type == PM_TOKEN_NOT_PROVIDED ? value->end : closing->end)
- }
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .value_loc = PM_LOCATION_TOKEN_VALUE(value),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .unescaped = *unescaped
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new SymbolNode node.
- */
-static inline pm_symbol_node_t *
-pm_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing) {
- return pm_symbol_node_create_unescaped(parser, opening, value, closing, &PM_STRING_EMPTY);
-}
-
-/**
- * Allocate and initialize a new SymbolNode node with the current string.
- */
-static pm_symbol_node_t *
-pm_symbol_node_create_current_string(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing) {
- pm_symbol_node_t *node = pm_symbol_node_create_unescaped(parser, opening, value, closing, &parser->current_string);
- parser->current_string = PM_STRING_EMPTY;
- return node;
-}
-
-/**
- * Allocate and initialize a new SymbolNode node from a label.
- */
-static pm_symbol_node_t *
-pm_symbol_node_label_create(pm_parser_t *parser, const pm_token_t *token) {
- pm_symbol_node_t *node;
-
- switch (token->type) {
- case PM_TOKEN_LABEL: {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = { .type = PM_TOKEN_LABEL_END, .start = token->end - 1, .end = token->end };
-
- pm_token_t label = { .type = PM_TOKEN_LABEL, .start = token->start, .end = token->end - 1 };
- node = pm_symbol_node_create(parser, &opening, &label, &closing);
-
- assert((label.end - label.start) >= 0);
- pm_string_shared_init(&node->unescaped, label.start, label.end);
- break;
- }
- case PM_TOKEN_MISSING: {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
-
- pm_token_t label = { .type = PM_TOKEN_LABEL, .start = token->start, .end = token->end };
- node = pm_symbol_node_create(parser, &opening, &label, &closing);
- break;
- }
- default:
- assert(false && "unreachable");
- node = NULL;
- break;
- }
-
- return node;
-}
-
-/**
- * Check if the given node is a label in a hash.
- */
-static bool
-pm_symbol_node_label_p(pm_node_t *node) {
- const uint8_t *end = NULL;
-
- switch (PM_NODE_TYPE(node)) {
- case PM_SYMBOL_NODE:
- end = ((pm_symbol_node_t *) node)->closing_loc.end;
- break;
- case PM_INTERPOLATED_SYMBOL_NODE:
- end = ((pm_interpolated_symbol_node_t *) node)->closing_loc.end;
- break;
- default:
- return false;
- }
-
- return (end != NULL) && (end[-1] == ':');
-}
-
-/**
- * Convert the given StringNode node to a SymbolNode node.
- */
-static pm_symbol_node_t *
-pm_string_node_to_symbol_node(pm_parser_t *parser, pm_string_node_t *node, const pm_token_t *opening, const pm_token_t *closing) {
- pm_symbol_node_t *new_node = PM_ALLOC_NODE(parser, pm_symbol_node_t);
-
- *new_node = (pm_symbol_node_t) {
- {
- .type = PM_SYMBOL_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = {
- .start = opening->start,
- .end = closing->end
- }
- },
- .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
- .value_loc = node->content_loc,
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .unescaped = node->unescaped
- };
-
- // We are explicitly _not_ using pm_node_destroy here because we don't want
- // to trash the unescaped string. We could instead copy the string if we
- // know that it is owned, but we're taking the fast path for now.
- free(node);
-
- return new_node;
-}
-
-/**
- * Convert the given SymbolNode node to a StringNode node.
- */
-static pm_string_node_t *
-pm_symbol_node_to_string_node(pm_parser_t *parser, pm_symbol_node_t *node) {
- pm_string_node_t *new_node = PM_ALLOC_NODE(parser, pm_string_node_t);
- pm_node_flags_t flags = 0;
-
- if (parser->frozen_string_literal) {
- flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN;
- }
-
- *new_node = (pm_string_node_t) {
- {
- .type = PM_STRING_NODE,
- .flags = flags,
- .location = node->base.location
- },
- .opening_loc = node->opening_loc,
- .content_loc = node->value_loc,
- .closing_loc = node->closing_loc,
- .unescaped = node->unescaped
- };
-
- // We are explicitly _not_ using pm_node_destroy here because we don't want
- // to trash the unescaped string. We could instead copy the string if we
- // know that it is owned, but we're taking the fast path for now.
- free(node);
-
- return new_node;
-}
-
-/**
- * Allocate and initialize a new TrueNode node.
- */
-static pm_true_node_t *
-pm_true_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_TRUE);
- pm_true_node_t *node = PM_ALLOC_NODE(parser, pm_true_node_t);
-
- *node = (pm_true_node_t) {{
- .type = PM_TRUE_NODE,
- .flags = PM_NODE_FLAG_STATIC_LITERAL,
- .location = PM_LOCATION_TOKEN_VALUE(token)
- }};
-
- return node;
-}
-
-/**
- * Allocate and initialize a new UndefNode node.
- */
-static pm_undef_node_t *
-pm_undef_node_create(pm_parser_t *parser, const pm_token_t *token) {
- assert(token->type == PM_TOKEN_KEYWORD_UNDEF);
- pm_undef_node_t *node = PM_ALLOC_NODE(parser, pm_undef_node_t);
-
- *node = (pm_undef_node_t) {
- {
- .type = PM_UNDEF_NODE,
- .location = PM_LOCATION_TOKEN_VALUE(token),
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(token),
- .names = { 0 }
- };
-
- return node;
-}
-
-/**
- * Append a name to an undef node.
- */
-static void
-pm_undef_node_append(pm_undef_node_t *node, pm_node_t *name) {
- node->base.location.end = name->location.end;
- pm_node_list_append(&node->names, name);
-}
-
-/**
- * Allocate a new UnlessNode node.
- */
-static pm_unless_node_t *
-pm_unless_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *predicate, const pm_token_t *then_keyword, pm_statements_node_t *statements) {
- pm_conditional_predicate(predicate);
- pm_unless_node_t *node = PM_ALLOC_NODE(parser, pm_unless_node_t);
-
- const uint8_t *end;
- if (statements != NULL) {
- end = statements->base.location.end;
- } else {
- end = predicate->location.end;
- }
-
- *node = (pm_unless_node_t) {
- {
- .type = PM_UNLESS_NODE,
- .flags = PM_NODE_FLAG_NEWLINE,
- .location = {
- .start = keyword->start,
- .end = end
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .predicate = predicate,
- .then_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword),
- .statements = statements,
- .consequent = NULL,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize new UnlessNode node in the modifier form.
- */
-static pm_unless_node_t *
-pm_unless_node_modifier_create(pm_parser_t *parser, pm_node_t *statement, const pm_token_t *unless_keyword, pm_node_t *predicate) {
- pm_conditional_predicate(predicate);
- pm_unless_node_t *node = PM_ALLOC_NODE(parser, pm_unless_node_t);
-
- pm_statements_node_t *statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(statements, statement);
-
- *node = (pm_unless_node_t) {
- {
- .type = PM_UNLESS_NODE,
- .flags = PM_NODE_FLAG_NEWLINE,
- .location = {
- .start = statement->location.start,
- .end = predicate->location.end
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(unless_keyword),
- .predicate = predicate,
- .then_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .statements = statements,
- .consequent = NULL,
- .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
- };
-
- return node;
-}
-
-static inline void
-pm_unless_node_end_keyword_loc_set(pm_unless_node_t *node, const pm_token_t *end_keyword) {
- node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword);
- node->base.location.end = end_keyword->end;
-}
-
-/**
- * Allocate a new UntilNode node.
- */
-static pm_until_node_t *
-pm_until_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *closing, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) {
- pm_until_node_t *node = PM_ALLOC_NODE(parser, pm_until_node_t);
-
- *node = (pm_until_node_t) {
- {
- .type = PM_UNTIL_NODE,
- .flags = flags,
- .location = {
- .start = keyword->start,
- .end = closing->end,
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .predicate = predicate,
- .statements = statements
- };
-
- return node;
-}
-
-/**
- * Allocate a new UntilNode node.
- */
-static pm_until_node_t *
-pm_until_node_modifier_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) {
- pm_until_node_t *node = PM_ALLOC_NODE(parser, pm_until_node_t);
-
- *node = (pm_until_node_t) {
- {
- .type = PM_UNTIL_NODE,
- .flags = flags,
- .location = {
- .start = statements->base.location.start,
- .end = predicate->location.end,
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .predicate = predicate,
- .statements = statements
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new WhenNode node.
- */
-static pm_when_node_t *
-pm_when_node_create(pm_parser_t *parser, const pm_token_t *keyword) {
- pm_when_node_t *node = PM_ALLOC_NODE(parser, pm_when_node_t);
-
- *node = (pm_when_node_t) {
- {
- .type = PM_WHEN_NODE,
- .location = {
- .start = keyword->start,
- .end = NULL
- }
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .statements = NULL,
- .conditions = { 0 }
- };
-
- return node;
-}
-
-/**
- * Append a new condition to a when node.
- */
-static void
-pm_when_node_conditions_append(pm_when_node_t *node, pm_node_t *condition) {
- node->base.location.end = condition->location.end;
- pm_node_list_append(&node->conditions, condition);
-}
-
-/**
- * Set the statements list of a when node.
- */
-static void
-pm_when_node_statements_set(pm_when_node_t *node, pm_statements_node_t *statements) {
- if (statements->base.location.end > node->base.location.end) {
- node->base.location.end = statements->base.location.end;
- }
-
- node->statements = statements;
-}
-
-/**
- * Allocate a new WhileNode node.
- */
-static pm_while_node_t *
-pm_while_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *closing, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) {
- pm_while_node_t *node = PM_ALLOC_NODE(parser, pm_while_node_t);
-
- *node = (pm_while_node_t) {
- {
- .type = PM_WHILE_NODE,
- .flags = flags,
- .location = {
- .start = keyword->start,
- .end = closing->end
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
- .predicate = predicate,
- .statements = statements
- };
-
- return node;
-}
-
-/**
- * Allocate a new WhileNode node.
- */
-static pm_while_node_t *
-pm_while_node_modifier_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) {
- pm_while_node_t *node = PM_ALLOC_NODE(parser, pm_while_node_t);
-
- *node = (pm_while_node_t) {
- {
- .type = PM_WHILE_NODE,
- .flags = flags,
- .location = {
- .start = statements->base.location.start,
- .end = predicate->location.end
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
- .predicate = predicate,
- .statements = statements
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new XStringNode node with the given unescaped
- * string.
- */
-static pm_x_string_node_t *
-pm_xstring_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, const pm_string_t *unescaped) {
- pm_x_string_node_t *node = PM_ALLOC_NODE(parser, pm_x_string_node_t);
-
- *node = (pm_x_string_node_t) {
- {
- .type = PM_X_STRING_NODE,
- .flags = PM_STRING_FLAGS_FROZEN,
- .location = {
- .start = opening->start,
- .end = closing->end
- },
- },
- .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
- .content_loc = PM_LOCATION_TOKEN_VALUE(content),
- .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
- .unescaped = *unescaped
- };
-
- return node;
-}
-
-/**
- * Allocate and initialize a new XStringNode node.
- */
-static inline pm_x_string_node_t *
-pm_xstring_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) {
- return pm_xstring_node_create_unescaped(parser, opening, content, closing, &PM_STRING_EMPTY);
-}
-
-/**
- * Allocate a new YieldNode node.
- */
-static pm_yield_node_t *
-pm_yield_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_location_t *lparen_loc, pm_arguments_node_t *arguments, const pm_location_t *rparen_loc) {
- pm_yield_node_t *node = PM_ALLOC_NODE(parser, pm_yield_node_t);
-
- const uint8_t *end;
- if (rparen_loc->start != NULL) {
- end = rparen_loc->end;
- } else if (arguments != NULL) {
- end = arguments->base.location.end;
- } else if (lparen_loc->start != NULL) {
- end = lparen_loc->end;
- } else {
- end = keyword->end;
- }
-
- *node = (pm_yield_node_t) {
- {
- .type = PM_YIELD_NODE,
- .location = {
- .start = keyword->start,
- .end = end
- },
- },
- .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword),
- .lparen_loc = *lparen_loc,
- .arguments = arguments,
- .rparen_loc = *rparen_loc
- };
-
- return node;
-}
-
-#undef PM_ALLOC_NODE
-
-/******************************************************************************/
-/* Scope-related functions */
-/******************************************************************************/
-
-/**
- * Allocate and initialize a new scope. Push it onto the scope stack.
- */
-static bool
-pm_parser_scope_push(pm_parser_t *parser, bool closed) {
- pm_scope_t *scope = (pm_scope_t *) malloc(sizeof(pm_scope_t));
- if (scope == NULL) return false;
-
- *scope = (pm_scope_t) {
- .previous = parser->current_scope,
- .closed = closed,
- .explicit_params = false,
- .numbered_parameters = 0,
- };
-
- pm_constant_id_list_init(&scope->locals);
- parser->current_scope = scope;
-
- return true;
-}
-
-/**
- * Check if any of the currently visible scopes contain a local variable
- * described by the given constant id.
- */
-static int
-pm_parser_local_depth_constant_id(pm_parser_t *parser, pm_constant_id_t constant_id) {
- pm_scope_t *scope = parser->current_scope;
- int depth = 0;
-
- while (scope != NULL) {
- if (pm_constant_id_list_includes(&scope->locals, constant_id)) return depth;
- if (scope->closed) break;
-
- scope = scope->previous;
- depth++;
- }
-
- return -1;
-}
-
-/**
- * Check if any of the currently visible scopes contain a local variable
- * described by the given token. This function implicitly inserts a constant
- * into the constant pool.
- */
-static inline int
-pm_parser_local_depth(pm_parser_t *parser, pm_token_t *token) {
- return pm_parser_local_depth_constant_id(parser, pm_parser_constant_id_token(parser, token));
-}
-
-/**
- * Add a constant id to the local table of the current scope.
- */
-static inline void
-pm_parser_local_add(pm_parser_t *parser, pm_constant_id_t constant_id) {
- if (!pm_constant_id_list_includes(&parser->current_scope->locals, constant_id)) {
- pm_constant_id_list_append(&parser->current_scope->locals, constant_id);
- }
-}
-
-/**
- * Set the numbered_parameters value of the current scope.
- */
-static inline void
-pm_parser_numbered_parameters_set(pm_parser_t *parser, uint8_t numbered_parameters) {
- parser->current_scope->numbered_parameters = numbered_parameters;
-}
-
-/**
- * Add a local variable from a location to the current scope.
- */
-static pm_constant_id_t
-pm_parser_local_add_location(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, start, end);
- if (constant_id != 0) pm_parser_local_add(parser, constant_id);
- return constant_id;
-}
-
-/**
- * Add a local variable from a token to the current scope.
- */
-static inline void
-pm_parser_local_add_token(pm_parser_t *parser, pm_token_t *token) {
- pm_parser_local_add_location(parser, token->start, token->end);
-}
-
-/**
- * Add a local variable from an owned string to the current scope.
- */
-static pm_constant_id_t
-pm_parser_local_add_owned(pm_parser_t *parser, const uint8_t *start, size_t length) {
- pm_constant_id_t constant_id = pm_parser_constant_id_owned(parser, start, length);
- if (constant_id != 0) pm_parser_local_add(parser, constant_id);
- return constant_id;
-}
-
-/**
- * Add a parameter name to the current scope and check whether the name of the
- * parameter is unique or not.
- */
-static void
-pm_parser_parameter_name_check(pm_parser_t *parser, const pm_token_t *name) {
- // We want to check whether the parameter name is a numbered parameter or
- // not.
- pm_refute_numbered_parameter(parser, name->start, name->end);
-
- // We want to ignore any parameter name that starts with an underscore.
- if ((name->start < name->end) && (*name->start == '_')) return;
-
- // Otherwise we'll fetch the constant id for the parameter name and check
- // whether it's already in the current scope.
- pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, name);
-
- if (pm_constant_id_list_includes(&parser->current_scope->locals, constant_id)) {
- pm_parser_err_token(parser, name, PM_ERR_PARAMETER_NAME_REPEAT);
- }
-}
-
-/**
- * Pop the current scope off the scope stack. Note that we specifically do not
- * free the associated constant list because we assume that we have already
- * transferred ownership of the list to the AST somewhere.
- */
-static void
-pm_parser_scope_pop(pm_parser_t *parser) {
- pm_scope_t *scope = parser->current_scope;
- parser->current_scope = scope->previous;
- free(scope);
-}
-
-/******************************************************************************/
-/* Basic character checks */
-/******************************************************************************/
-
-/**
- * This function is used extremely frequently to lex all of the identifiers in a
- * source file, so it's important that it be as fast as possible. For this
- * reason we have the encoding_changed boolean to check if we need to go through
- * the function pointer or can just directly use the UTF-8 functions.
- */
-static inline size_t
-char_is_identifier_start(pm_parser_t *parser, const uint8_t *b) {
- if (parser->encoding_changed) {
- size_t width;
- if ((width = parser->encoding->alpha_char(b, parser->end - b)) != 0) {
- return width;
- } else if (*b == '_') {
- return 1;
- } else if (*b >= 0x80) {
- return parser->encoding->char_width(b, parser->end - b);
- } else {
- return 0;
- }
- } else if (*b < 0x80) {
- return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT ? 1 : 0) || (*b == '_');
- } else {
- return (size_t) (pm_encoding_utf_8_alpha_char(b, parser->end - b) || 1u);
- }
-}
-
-/**
- * Similar to char_is_identifier but this function assumes that the encoding
- * has not been changed.
- */
-static inline size_t
-char_is_identifier_utf8(const uint8_t *b, const uint8_t *end) {
- if (*b < 0x80) {
- return (*b == '_') || (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT ? 1 : 0);
- } else {
- return (size_t) (pm_encoding_utf_8_alnum_char(b, end - b) || 1u);
- }
-}
-
-/**
- * Like the above, this function is also used extremely frequently to lex all of
- * the identifiers in a source file once the first character has been found. So
- * it's important that it be as fast as possible.
- */
-static inline size_t
-char_is_identifier(pm_parser_t *parser, const uint8_t *b) {
- if (parser->encoding_changed) {
- size_t width;
- if ((width = parser->encoding->alnum_char(b, parser->end - b)) != 0) {
- return width;
- } else if (*b == '_') {
- return 1;
- } else if (*b >= 0x80) {
- return parser->encoding->char_width(b, parser->end - b);
- } else {
- return 0;
- }
- }
- return char_is_identifier_utf8(b, parser->end);
-}
-
-// Here we're defining a perfect hash for the characters that are allowed in
-// global names. This is used to quickly check the next character after a $ to
-// see if it's a valid character for a global name.
-#define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
-#define PUNCT(idx) ( \
- BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
- BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
- BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
- BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
- BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
- BIT('0', idx))
-
-const unsigned int pm_global_name_punctuation_hash[(0x7e - 0x20 + 31) / 32] = { PUNCT(0), PUNCT(1), PUNCT(2) };
-
-#undef BIT
-#undef PUNCT
-
-static inline bool
-char_is_global_name_punctuation(const uint8_t b) {
- const unsigned int i = (const unsigned int) b;
- if (i <= 0x20 || 0x7e < i) return false;
-
- return (pm_global_name_punctuation_hash[(i - 0x20) / 32] >> (i % 32)) & 1;
-}
-
-static inline bool
-token_is_setter_name(pm_token_t *token) {
- return (
- (token->type == PM_TOKEN_IDENTIFIER) &&
- (token->end - token->start >= 2) &&
- (token->end[-1] == '=')
- );
-}
-
-/******************************************************************************/
-/* Stack helpers */
-/******************************************************************************/
-
-static inline void
-pm_accepts_block_stack_push(pm_parser_t *parser, bool value) {
- // Use the negation of the value to prevent stack overflow.
- pm_state_stack_push(&parser->accepts_block_stack, !value);
-}
-
-static inline void
-pm_accepts_block_stack_pop(pm_parser_t *parser) {
- pm_state_stack_pop(&parser->accepts_block_stack);
-}
-
-static inline bool
-pm_accepts_block_stack_p(pm_parser_t *parser) {
- return !pm_state_stack_p(&parser->accepts_block_stack);
-}
-
-static inline void
-pm_do_loop_stack_push(pm_parser_t *parser, bool value) {
- pm_state_stack_push(&parser->do_loop_stack, value);
-}
-
-static inline void
-pm_do_loop_stack_pop(pm_parser_t *parser) {
- pm_state_stack_pop(&parser->do_loop_stack);
-}
-
-static inline bool
-pm_do_loop_stack_p(pm_parser_t *parser) {
- return pm_state_stack_p(&parser->do_loop_stack);
-}
-
-/******************************************************************************/
-/* Lexer check helpers */
-/******************************************************************************/
-
-/**
- * Get the next character in the source starting from +cursor+. If that position
- * is beyond the end of the source then return '\0'.
- */
-static inline uint8_t
-peek_at(pm_parser_t *parser, const uint8_t *cursor) {
- if (cursor < parser->end) {
- return *cursor;
- } else {
- return '\0';
- }
-}
-
-/**
- * Get the next character in the source starting from parser->current.end and
- * adding the given offset. If that position is beyond the end of the source
- * then return '\0'.
- */
-static inline uint8_t
-peek_offset(pm_parser_t *parser, ptrdiff_t offset) {
- return peek_at(parser, parser->current.end + offset);
-}
-
-/**
- * Get the next character in the source starting from parser->current.end. If
- * that position is beyond the end of the source then return '\0'.
- */
-static inline uint8_t
-peek(pm_parser_t *parser) {
- return peek_at(parser, parser->current.end);
-}
-
-/**
- * If the character to be read matches the given value, then returns true and
- * advanced the current pointer.
- */
-static inline bool
-match(pm_parser_t *parser, uint8_t value) {
- if (peek(parser) == value) {
- parser->current.end++;
- return true;
- }
- return false;
-}
-
-/**
- * Return the length of the line ending string starting at +cursor+, or 0 if it
- * is not a line ending. This function is intended to be CRLF/LF agnostic.
- */
-static inline size_t
-match_eol_at(pm_parser_t *parser, const uint8_t *cursor) {
- if (peek_at(parser, cursor) == '\n') {
- return 1;
- }
- if (peek_at(parser, cursor) == '\r' && peek_at(parser, cursor + 1) == '\n') {
- return 2;
- }
- return 0;
-}
-
-/**
- * Return the length of the line ending string starting at
- * `parser->current.end + offset`, or 0 if it is not a line ending. This
- * function is intended to be CRLF/LF agnostic.
- */
-static inline size_t
-match_eol_offset(pm_parser_t *parser, ptrdiff_t offset) {
- return match_eol_at(parser, parser->current.end + offset);
-}
-
-/**
- * Return the length of the line ending string starting at parser->current.end,
- * or 0 if it is not a line ending. This function is intended to be CRLF/LF
- * agnostic.
- */
-static inline size_t
-match_eol(pm_parser_t *parser) {
- return match_eol_at(parser, parser->current.end);
-}
-
-/**
- * Skip to the next newline character or NUL byte.
- */
-static inline const uint8_t *
-next_newline(const uint8_t *cursor, ptrdiff_t length) {
- assert(length >= 0);
-
- // Note that it's okay for us to use memchr here to look for \n because none
- // of the encodings that we support have \n as a component of a multi-byte
- // character.
- return memchr(cursor, '\n', (size_t) length);
-}
-
-/**
- * Here we're going to check if this is a "magic" comment, and perform whatever
- * actions are necessary for it here.
- */
-static bool
-parser_lex_magic_comment_encoding_value(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- const pm_encoding_t *encoding = pm_encoding_find(start, end);
-
- if (encoding != NULL) {
- if (encoding != PM_ENCODING_UTF_8_ENTRY) {
- parser->encoding = encoding;
- parser->encoding_changed = true;
- if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser);
- }
-
- return true;
- }
-
- return false;
-}
-
-/**
- * Look for a specific pattern of "coding" and potentially set the encoding on
- * the parser.
- */
-static void
-parser_lex_magic_comment_encoding(pm_parser_t *parser) {
- const uint8_t *cursor = parser->current.start + 1;
- const uint8_t *end = parser->current.end;
-
- bool separator = false;
- while (true) {
- if (end - cursor <= 6) return;
- switch (cursor[6]) {
- case 'C': case 'c': cursor += 6; continue;
- case 'O': case 'o': cursor += 5; continue;
- case 'D': case 'd': cursor += 4; continue;
- case 'I': case 'i': cursor += 3; continue;
- case 'N': case 'n': cursor += 2; continue;
- case 'G': case 'g': cursor += 1; continue;
- case '=': case ':':
- separator = true;
- cursor += 6;
- break;
- default:
- cursor += 6;
- if (pm_char_is_whitespace(*cursor)) break;
- continue;
- }
- if (pm_strncasecmp(cursor - 6, (const uint8_t *) "coding", 6) == 0) break;
- separator = false;
- }
-
- while (true) {
- do {
- if (++cursor >= end) return;
- } while (pm_char_is_whitespace(*cursor));
-
- if (separator) break;
- if (*cursor != '=' && *cursor != ':') return;
-
- separator = true;
- cursor++;
- }
-
- const uint8_t *value_start = cursor;
- while ((*cursor == '-' || *cursor == '_' || parser->encoding->alnum_char(cursor, 1)) && ++cursor < end);
-
- if (!parser_lex_magic_comment_encoding_value(parser, value_start, cursor)) {
- // If we were unable to parse the encoding value, then we've got an
- // issue because we didn't understand the encoding that the user was
- // trying to use. In this case we'll keep using the default encoding but
- // add an error to the parser to indicate an unsuccessful parse.
- pm_parser_err(parser, value_start, cursor, PM_ERR_INVALID_ENCODING_MAGIC_COMMENT);
- }
-}
-
-/**
- * Check if this is a magic comment that includes the frozen_string_literal
- * pragma. If it does, set that field on the parser.
- */
-static void
-parser_lex_magic_comment_frozen_string_literal_value(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- if (start + 4 <= end && pm_strncasecmp(start, (const uint8_t *) "true", 4) == 0) {
- parser->frozen_string_literal = true;
- }
-}
-
-static inline bool
-pm_char_is_magic_comment_key_delimiter(const uint8_t b) {
- return b == '\'' || b == '"' || b == ':' || b == ';';
-}
-
-/**
- * Find an emacs magic comment marker (-*-) within the given bounds. If one is
- * found, it returns a pointer to the start of the marker. Otherwise it returns
- * NULL.
- */
-static inline const uint8_t *
-parser_lex_magic_comment_emacs_marker(pm_parser_t *parser, const uint8_t *cursor, const uint8_t *end) {
- while ((cursor + 3 <= end) && (cursor = pm_memchr(cursor, '-', (size_t) (end - cursor), parser->encoding_changed, parser->encoding)) != NULL) {
- if (cursor + 3 <= end && cursor[1] == '*' && cursor[2] == '-') {
- return cursor;
- }
- cursor++;
- }
- return NULL;
-}
-
-/**
- * Parse the current token on the parser to see if it's a magic comment and
- * potentially perform some action based on that. A regular expression that this
- * function is effectively matching is:
- *
- * %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*"
- *
- * It returns true if it consumes the entire comment. Otherwise it returns
- * false.
- */
-static inline bool
-parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) {
- bool result = true;
-
- const uint8_t *start = parser->current.start + 1;
- const uint8_t *end = parser->current.end;
- if (end - start <= 7) return false;
-
- const uint8_t *cursor;
- bool indicator = false;
-
- if ((cursor = parser_lex_magic_comment_emacs_marker(parser, start, end)) != NULL) {
- start = cursor + 3;
-
- if ((cursor = parser_lex_magic_comment_emacs_marker(parser, start, end)) != NULL) {
- end = cursor;
- indicator = true;
- } else {
- // If we have a start marker but not an end marker, then we cannot
- // have a magic comment.
- return false;
- }
- }
-
- cursor = start;
- while (cursor < end) {
- while (cursor < end && (pm_char_is_magic_comment_key_delimiter(*cursor) || pm_char_is_whitespace(*cursor))) cursor++;
-
- const uint8_t *key_start = cursor;
- while (cursor < end && (!pm_char_is_magic_comment_key_delimiter(*cursor) && !pm_char_is_whitespace(*cursor))) cursor++;
-
- const uint8_t *key_end = cursor;
- while (cursor < end && pm_char_is_whitespace(*cursor)) cursor++;
- if (cursor == end) break;
-
- if (*cursor == ':') {
- cursor++;
- } else {
- if (!indicator) return false;
- continue;
- }
-
- while (cursor < end && pm_char_is_whitespace(*cursor)) cursor++;
- if (cursor == end) break;
-
- const uint8_t *value_start;
- const uint8_t *value_end;
-
- if (*cursor == '"') {
- value_start = ++cursor;
- for (; cursor < end && *cursor != '"'; cursor++) {
- if (*cursor == '\\' && (cursor + 1 < end)) cursor++;
- }
- value_end = cursor;
- } else {
- value_start = cursor;
- while (cursor < end && *cursor != '"' && *cursor != ';' && !pm_char_is_whitespace(*cursor)) cursor++;
- value_end = cursor;
- }
-
- if (indicator) {
- while (cursor < end && (*cursor == ';' || pm_char_is_whitespace(*cursor))) cursor++;
- } else {
- while (cursor < end && pm_char_is_whitespace(*cursor)) cursor++;
- if (cursor != end) return false;
- }
-
- // Here, we need to do some processing on the key to swap out dashes for
- // underscores. We only need to do this if there _is_ a dash in the key.
- pm_string_t key;
- const size_t key_length = (size_t) (key_end - key_start);
- const uint8_t *dash = pm_memchr(key_start, '-', (size_t) key_length, parser->encoding_changed, parser->encoding);
-
- if (dash == NULL) {
- pm_string_shared_init(&key, key_start, key_end);
- } else {
- size_t width = (size_t) (key_end - key_start);
- uint8_t *buffer = malloc(width);
- if (buffer == NULL) break;
-
- memcpy(buffer, key_start, width);
- buffer[dash - key_start] = '_';
-
- while ((dash = pm_memchr(dash + 1, '-', (size_t) (key_end - dash - 1), parser->encoding_changed, parser->encoding)) != NULL) {
- buffer[dash - key_start] = '_';
- }
-
- pm_string_owned_init(&key, buffer, width);
- }
-
- // Finally, we can start checking the key against the list of known
- // magic comment keys, and potentially change state based on that.
- const uint8_t *key_source = pm_string_source(&key);
-
- // We only want to attempt to compare against encoding comments if it's
- // the first line in the file (or the second in the case of a shebang).
- if (parser->current.start == parser->encoding_comment_start) {
- if (
- (key_length == 8 && pm_strncasecmp(key_source, (const uint8_t *) "encoding", 8) == 0) ||
- (key_length == 6 && pm_strncasecmp(key_source, (const uint8_t *) "coding", 6) == 0)
- ) {
- result = parser_lex_magic_comment_encoding_value(parser, value_start, value_end);
- }
- }
-
- // We only want to handle frozen string literal comments if it's before
- // any semantic tokens have been seen.
- if (!semantic_token_seen) {
- if (key_length == 21 && pm_strncasecmp(key_source, (const uint8_t *) "frozen_string_literal", 21) == 0) {
- parser_lex_magic_comment_frozen_string_literal_value(parser, value_start, value_end);
- }
- }
-
- // When we're done, we want to free the string in case we had to
- // allocate memory for it.
- pm_string_free(&key);
-
- // Allocate a new magic comment node to append to the parser's list.
- pm_magic_comment_t *magic_comment;
- if ((magic_comment = (pm_magic_comment_t *) calloc(sizeof(pm_magic_comment_t), 1)) != NULL) {
- magic_comment->key_start = key_start;
- magic_comment->value_start = value_start;
- magic_comment->key_length = (uint32_t) key_length;
- magic_comment->value_length = (uint32_t) (value_end - value_start);
- pm_list_append(&parser->magic_comment_list, (pm_list_node_t *) magic_comment);
- }
- }
-
- return result;
-}
-
-/******************************************************************************/
-/* Context manipulations */
-/******************************************************************************/
-
-static bool
-context_terminator(pm_context_t context, pm_token_t *token) {
- switch (context) {
- case PM_CONTEXT_MAIN:
- case PM_CONTEXT_DEF_PARAMS:
- return token->type == PM_TOKEN_EOF;
- case PM_CONTEXT_DEFAULT_PARAMS:
- return token->type == PM_TOKEN_COMMA || token->type == PM_TOKEN_PARENTHESIS_RIGHT;
- case PM_CONTEXT_PREEXE:
- case PM_CONTEXT_POSTEXE:
- return token->type == PM_TOKEN_BRACE_RIGHT;
- case PM_CONTEXT_MODULE:
- case PM_CONTEXT_CLASS:
- case PM_CONTEXT_SCLASS:
- case PM_CONTEXT_LAMBDA_DO_END:
- case PM_CONTEXT_DEF:
- case PM_CONTEXT_BLOCK_KEYWORDS:
- return token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ENSURE;
- case PM_CONTEXT_WHILE:
- case PM_CONTEXT_UNTIL:
- case PM_CONTEXT_ELSE:
- case PM_CONTEXT_FOR:
- case PM_CONTEXT_ENSURE:
- case PM_CONTEXT_ENSURE_DEF:
- return token->type == PM_TOKEN_KEYWORD_END;
- case PM_CONTEXT_FOR_INDEX:
- return token->type == PM_TOKEN_KEYWORD_IN;
- case PM_CONTEXT_CASE_WHEN:
- return token->type == PM_TOKEN_KEYWORD_WHEN || token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_ELSE;
- case PM_CONTEXT_CASE_IN:
- return token->type == PM_TOKEN_KEYWORD_IN || token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_ELSE;
- case PM_CONTEXT_IF:
- case PM_CONTEXT_ELSIF:
- return token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_ELSIF || token->type == PM_TOKEN_KEYWORD_END;
- case PM_CONTEXT_UNLESS:
- return token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END;
- case PM_CONTEXT_EMBEXPR:
- return token->type == PM_TOKEN_EMBEXPR_END;
- case PM_CONTEXT_BLOCK_BRACES:
- return token->type == PM_TOKEN_BRACE_RIGHT;
- case PM_CONTEXT_PARENS:
- return token->type == PM_TOKEN_PARENTHESIS_RIGHT;
- case PM_CONTEXT_BEGIN:
- case PM_CONTEXT_RESCUE:
- case PM_CONTEXT_RESCUE_DEF:
- return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END;
- case PM_CONTEXT_RESCUE_ELSE:
- case PM_CONTEXT_RESCUE_ELSE_DEF:
- return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_END;
- case PM_CONTEXT_LAMBDA_BRACES:
- return token->type == PM_TOKEN_BRACE_RIGHT;
- case PM_CONTEXT_PREDICATE:
- return token->type == PM_TOKEN_KEYWORD_THEN || token->type == PM_TOKEN_NEWLINE || token->type == PM_TOKEN_SEMICOLON;
- }
-
- return false;
-}
-
-static bool
-context_recoverable(pm_parser_t *parser, pm_token_t *token) {
- pm_context_node_t *context_node = parser->current_context;
-
- while (context_node != NULL) {
- if (context_terminator(context_node->context, token)) return true;
- context_node = context_node->prev;
- }
-
- return false;
-}
-
-static bool
-context_push(pm_parser_t *parser, pm_context_t context) {
- pm_context_node_t *context_node = (pm_context_node_t *) malloc(sizeof(pm_context_node_t));
- if (context_node == NULL) return false;
-
- *context_node = (pm_context_node_t) { .context = context, .prev = NULL };
-
- if (parser->current_context == NULL) {
- parser->current_context = context_node;
- } else {
- context_node->prev = parser->current_context;
- parser->current_context = context_node;
- }
-
- return true;
-}
-
-static void
-context_pop(pm_parser_t *parser) {
- pm_context_node_t *prev = parser->current_context->prev;
- free(parser->current_context);
- parser->current_context = prev;
-}
-
-static bool
-context_p(pm_parser_t *parser, pm_context_t context) {
- pm_context_node_t *context_node = parser->current_context;
-
- while (context_node != NULL) {
- if (context_node->context == context) return true;
- context_node = context_node->prev;
- }
-
- return false;
-}
-
-static bool
-context_def_p(pm_parser_t *parser) {
- pm_context_node_t *context_node = parser->current_context;
-
- while (context_node != NULL) {
- switch (context_node->context) {
- case PM_CONTEXT_DEF:
- case PM_CONTEXT_DEF_PARAMS:
- case PM_CONTEXT_ENSURE_DEF:
- case PM_CONTEXT_RESCUE_DEF:
- case PM_CONTEXT_RESCUE_ELSE_DEF:
- return true;
- case PM_CONTEXT_CLASS:
- case PM_CONTEXT_MODULE:
- case PM_CONTEXT_SCLASS:
- return false;
- default:
- context_node = context_node->prev;
- }
- }
-
- return false;
-}
-
-/******************************************************************************/
-/* Specific token lexers */
-/******************************************************************************/
-
-static void
-pm_strspn_number_validate(pm_parser_t *parser, const uint8_t *invalid) {
- if (invalid != NULL) {
- pm_parser_err(parser, invalid, invalid + 1, PM_ERR_INVALID_NUMBER_UNDERSCORE);
- }
-}
-
-static size_t
-pm_strspn_binary_number_validate(pm_parser_t *parser, const uint8_t *string) {
- const uint8_t *invalid = NULL;
- size_t length = pm_strspn_binary_number(string, parser->end - string, &invalid);
- pm_strspn_number_validate(parser, invalid);
- return length;
-}
-
-static size_t
-pm_strspn_octal_number_validate(pm_parser_t *parser, const uint8_t *string) {
- const uint8_t *invalid = NULL;
- size_t length = pm_strspn_octal_number(string, parser->end - string, &invalid);
- pm_strspn_number_validate(parser, invalid);
- return length;
-}
-
-static size_t
-pm_strspn_decimal_number_validate(pm_parser_t *parser, const uint8_t *string) {
- const uint8_t *invalid = NULL;
- size_t length = pm_strspn_decimal_number(string, parser->end - string, &invalid);
- pm_strspn_number_validate(parser, invalid);
- return length;
-}
-
-static size_t
-pm_strspn_hexadecimal_number_validate(pm_parser_t *parser, const uint8_t *string) {
- const uint8_t *invalid = NULL;
- size_t length = pm_strspn_hexadecimal_number(string, parser->end - string, &invalid);
- pm_strspn_number_validate(parser, invalid);
- return length;
-}
-
-static pm_token_type_t
-lex_optional_float_suffix(pm_parser_t *parser, bool* seen_e) {
- pm_token_type_t type = PM_TOKEN_INTEGER;
-
- // Here we're going to attempt to parse the optional decimal portion of a
- // float. If it's not there, then it's okay and we'll just continue on.
- if (peek(parser) == '.') {
- if (pm_char_is_decimal_digit(peek_offset(parser, 1))) {
- parser->current.end += 2;
- parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end);
- type = PM_TOKEN_FLOAT;
- } else {
- // If we had a . and then something else, then it's not a float suffix on
- // a number it's a method call or something else.
- return type;
- }
- }
-
- // Here we're going to attempt to parse the optional exponent portion of a
- // float. If it's not there, it's okay and we'll just continue on.
- if (match(parser, 'e') || match(parser, 'E')) {
- (void) (match(parser, '+') || match(parser, '-'));
- *seen_e = true;
-
- if (pm_char_is_decimal_digit(peek(parser))) {
- parser->current.end++;
- parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end);
- type = PM_TOKEN_FLOAT;
- } else {
- pm_parser_err_current(parser, PM_ERR_INVALID_FLOAT_EXPONENT);
- type = PM_TOKEN_FLOAT;
- }
- }
-
- return type;
-}
-
-static pm_token_type_t
-lex_numeric_prefix(pm_parser_t *parser, bool* seen_e) {
- pm_token_type_t type = PM_TOKEN_INTEGER;
- *seen_e = false;
-
- if (peek_offset(parser, -1) == '0') {
- switch (*parser->current.end) {
- // 0d1111 is a decimal number
- case 'd':
- case 'D':
- parser->current.end++;
- if (pm_char_is_decimal_digit(peek(parser))) {
- parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end);
- } else {
- pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_DECIMAL);
- }
-
- break;
-
- // 0b1111 is a binary number
- case 'b':
- case 'B':
- parser->current.end++;
- if (pm_char_is_binary_digit(peek(parser))) {
- parser->current.end += pm_strspn_binary_number_validate(parser, parser->current.end);
- } else {
- pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_BINARY);
- }
-
- parser->integer_base = PM_INTEGER_BASE_FLAGS_BINARY;
- break;
-
- // 0o1111 is an octal number
- case 'o':
- case 'O':
- parser->current.end++;
- if (pm_char_is_octal_digit(peek(parser))) {
- parser->current.end += pm_strspn_octal_number_validate(parser, parser->current.end);
- } else {
- pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_OCTAL);
- }
-
- parser->integer_base = PM_INTEGER_BASE_FLAGS_OCTAL;
- break;
-
- // 01111 is an octal number
- case '_':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- parser->current.end += pm_strspn_octal_number_validate(parser, parser->current.end);
- parser->integer_base = PM_INTEGER_BASE_FLAGS_OCTAL;
- break;
-
- // 0x1111 is a hexadecimal number
- case 'x':
- case 'X':
- parser->current.end++;
- if (pm_char_is_hexadecimal_digit(peek(parser))) {
- parser->current.end += pm_strspn_hexadecimal_number_validate(parser, parser->current.end);
- } else {
- pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_HEXADECIMAL);
- }
-
- parser->integer_base = PM_INTEGER_BASE_FLAGS_HEXADECIMAL;
- break;
-
- // 0.xxx is a float
- case '.': {
- type = lex_optional_float_suffix(parser, seen_e);
- break;
- }
-
- // 0exxx is a float
- case 'e':
- case 'E': {
- type = lex_optional_float_suffix(parser, seen_e);
- break;
- }
- }
- } else {
- // If it didn't start with a 0, then we'll lex as far as we can into a
- // decimal number.
- parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end);
-
- // Afterward, we'll lex as far as we can into an optional float suffix.
- type = lex_optional_float_suffix(parser, seen_e);
- }
-
- return type;
-}
-
-static pm_token_type_t
-lex_numeric(pm_parser_t *parser) {
- pm_token_type_t type = PM_TOKEN_INTEGER;
- parser->integer_base = PM_INTEGER_BASE_FLAGS_DECIMAL;
-
- if (parser->current.end < parser->end) {
- bool seen_e = false;
- type = lex_numeric_prefix(parser, &seen_e);
-
- const uint8_t *end = parser->current.end;
- pm_token_type_t suffix_type = type;
-
- if (type == PM_TOKEN_INTEGER) {
- if (match(parser, 'r')) {
- suffix_type = PM_TOKEN_INTEGER_RATIONAL;
-
- if (match(parser, 'i')) {
- suffix_type = PM_TOKEN_INTEGER_RATIONAL_IMAGINARY;
- }
- } else if (match(parser, 'i')) {
- suffix_type = PM_TOKEN_INTEGER_IMAGINARY;
- }
- } else {
- if (!seen_e && match(parser, 'r')) {
- suffix_type = PM_TOKEN_FLOAT_RATIONAL;
-
- if (match(parser, 'i')) {
- suffix_type = PM_TOKEN_FLOAT_RATIONAL_IMAGINARY;
- }
- } else if (match(parser, 'i')) {
- suffix_type = PM_TOKEN_FLOAT_IMAGINARY;
- }
- }
-
- const uint8_t b = peek(parser);
- if (b != '\0' && (b >= 0x80 || ((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')) || b == '_')) {
- parser->current.end = end;
- } else {
- type = suffix_type;
- }
- }
-
- return type;
-}
-
-static pm_token_type_t
-lex_global_variable(pm_parser_t *parser) {
- if (parser->current.end >= parser->end) {
- pm_parser_err_current(parser, PM_ERR_INVALID_VARIABLE_GLOBAL);
- return PM_TOKEN_GLOBAL_VARIABLE;
- }
-
- switch (*parser->current.end) {
- case '~': // $~: match-data
- case '*': // $*: argv
- case '$': // $$: pid
- case '?': // $?: last status
- case '!': // $!: error string
- case '@': // $@: error position
- case '/': // $/: input record separator
- case '\\': // $\: output record separator
- case ';': // $;: field separator
- case ',': // $,: output field separator
- case '.': // $.: last read line number
- case '=': // $=: ignorecase
- case ':': // $:: load path
- case '<': // $<: reading filename
- case '>': // $>: default output handle
- case '\"': // $": already loaded files
- parser->current.end++;
- return PM_TOKEN_GLOBAL_VARIABLE;
-
- case '&': // $&: last match
- case '`': // $`: string before last match
- case '\'': // $': string after last match
- case '+': // $+: string matches last paren.
- parser->current.end++;
- return lex_state_p(parser, PM_LEX_STATE_FNAME) ? PM_TOKEN_GLOBAL_VARIABLE : PM_TOKEN_BACK_REFERENCE;
-
- case '0': {
- parser->current.end++;
- size_t width;
-
- if (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0) {
- do {
- parser->current.end += width;
- } while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0);
-
- // $0 isn't allowed to be followed by anything.
- pm_parser_err_current(parser, PM_ERR_INVALID_VARIABLE_GLOBAL);
- }
-
- return PM_TOKEN_GLOBAL_VARIABLE;
- }
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- parser->current.end += pm_strspn_decimal_digit(parser->current.end, parser->end - parser->current.end);
- return lex_state_p(parser, PM_LEX_STATE_FNAME) ? PM_TOKEN_GLOBAL_VARIABLE : PM_TOKEN_NUMBERED_REFERENCE;
-
- case '-':
- parser->current.end++;
- /* fallthrough */
- default: {
- size_t width;
-
- if ((width = char_is_identifier(parser, parser->current.end)) > 0) {
- do {
- parser->current.end += width;
- } while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0);
- } else {
- // If we get here, then we have a $ followed by something that isn't
- // recognized as a global variable.
- pm_parser_err_current(parser, PM_ERR_INVALID_VARIABLE_GLOBAL);
- }
-
- return PM_TOKEN_GLOBAL_VARIABLE;
- }
- }
-}
-
-/**
- * This function checks if the current token matches a keyword. If it does, it
- * returns the token type. Otherwise, it returns PM_TOKEN_EOF. The arguments are as follows:
- *
- * * `parser` - the parser object
- * * `current_start` - pointer to the start of the current token
- * * `value` - the literal string that we're checking for
- * * `vlen` - the length of the token
- * * `state` - the state that we should transition to if the token matches
- * * `type` - the expected token type
- * * `modifier_type` - the expected modifier token type
- */
-static inline pm_token_type_t
-lex_keyword(pm_parser_t *parser, const uint8_t *current_start, const char *value, size_t vlen, pm_lex_state_t state, pm_token_type_t type, pm_token_type_t modifier_type) {
- if (memcmp(current_start, value, vlen) == 0) {
- pm_lex_state_t last_state = parser->lex_state;
-
- if (parser->lex_state & PM_LEX_STATE_FNAME) {
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- } else {
- lex_state_set(parser, state);
- if (state == PM_LEX_STATE_BEG) {
- parser->command_start = true;
- }
-
- if ((modifier_type != PM_TOKEN_EOF) && !(last_state & (PM_LEX_STATE_BEG | PM_LEX_STATE_LABELED | PM_LEX_STATE_CLASS))) {
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- return modifier_type;
- }
- }
-
- return type;
- }
-
- return PM_TOKEN_EOF;
-}
-
-static pm_token_type_t
-lex_identifier(pm_parser_t *parser, bool previous_command_start) {
- // Lex as far as we can into the current identifier.
- size_t width;
- const uint8_t *end = parser->end;
- const uint8_t *current_start = parser->current.start;
- const uint8_t *current_end = parser->current.end;
- bool encoding_changed = parser->encoding_changed;
-
- if (encoding_changed) {
- while (current_end < end && (width = char_is_identifier(parser, current_end)) > 0) {
- current_end += width;
- }
- } else {
- while (current_end < end && (width = char_is_identifier_utf8(current_end, end)) > 0) {
- current_end += width;
- }
- }
- parser->current.end = current_end;
-
- // Now cache the length of the identifier so that we can quickly compare it
- // against known keywords.
- width = (size_t) (current_end - current_start);
-
- if (current_end < end) {
- if (((current_end + 1 >= end) || (current_end[1] != '=')) && (match(parser, '!') || match(parser, '?'))) {
- // First we'll attempt to extend the identifier by a ! or ?. Then we'll
- // check if we're returning the defined? keyword or just an identifier.
- width++;
-
- if (
- ((lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser)) &&
- (peek(parser) == ':') && (peek_offset(parser, 1) != ':')
- ) {
- // If we're in a position where we can accept a : at the end of an
- // identifier, then we'll optionally accept it.
- lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED);
- (void) match(parser, ':');
- return PM_TOKEN_LABEL;
- }
-
- if (parser->lex_state != PM_LEX_STATE_DOT) {
- if (width == 8 && (lex_keyword(parser, current_start, "defined?", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_DEFINED, PM_TOKEN_EOF) != PM_TOKEN_EOF)) {
- return PM_TOKEN_KEYWORD_DEFINED;
- }
- }
-
- return PM_TOKEN_METHOD_NAME;
- }
-
- if (lex_state_p(parser, PM_LEX_STATE_FNAME) && peek_offset(parser, 1) != '~' && peek_offset(parser, 1) != '>' && (peek_offset(parser, 1) != '=' || peek_offset(parser, 2) == '>') && match(parser, '=')) {
- // If we're in a position where we can accept a = at the end of an
- // identifier, then we'll optionally accept it.
- return PM_TOKEN_IDENTIFIER;
- }
-
- if (
- ((lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser)) &&
- peek(parser) == ':' && peek_offset(parser, 1) != ':'
- ) {
- // If we're in a position where we can accept a : at the end of an
- // identifier, then we'll optionally accept it.
- lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED);
- (void) match(parser, ':');
- return PM_TOKEN_LABEL;
- }
- }
-
- if (parser->lex_state != PM_LEX_STATE_DOT) {
- pm_token_type_t type;
- switch (width) {
- case 2:
- if (lex_keyword(parser, current_start, "do", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_DO, PM_TOKEN_EOF) != PM_TOKEN_EOF) {
- if (pm_do_loop_stack_p(parser)) {
- return PM_TOKEN_KEYWORD_DO_LOOP;
- }
- return PM_TOKEN_KEYWORD_DO;
- }
-
- if ((type = lex_keyword(parser, current_start, "if", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_IF, PM_TOKEN_KEYWORD_IF_MODIFIER)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "in", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_IN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "or", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_OR, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- break;
- case 3:
- if ((type = lex_keyword(parser, current_start, "and", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_AND, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "def", width, PM_LEX_STATE_FNAME, PM_TOKEN_KEYWORD_DEF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "end", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_END, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "END", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_END_UPCASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "for", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_FOR, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "nil", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_NIL, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "not", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_NOT, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- break;
- case 4:
- if ((type = lex_keyword(parser, current_start, "case", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_CASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "else", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "next", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_NEXT, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "redo", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_REDO, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "self", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_SELF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "then", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "true", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_TRUE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "when", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- break;
- case 5:
- if ((type = lex_keyword(parser, current_start, "alias", width, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM, PM_TOKEN_KEYWORD_ALIAS, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "begin", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_BEGIN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "BEGIN", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_BEGIN_UPCASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "break", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_BREAK, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "class", width, PM_LEX_STATE_CLASS, PM_TOKEN_KEYWORD_CLASS, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "elsif", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ELSIF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "false", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_FALSE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "retry", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_RETRY, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "super", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_SUPER, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "undef", width, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM, PM_TOKEN_KEYWORD_UNDEF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "until", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_UNTIL, PM_TOKEN_KEYWORD_UNTIL_MODIFIER)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "while", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_WHILE, PM_TOKEN_KEYWORD_WHILE_MODIFIER)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "yield", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_YIELD, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- break;
- case 6:
- if ((type = lex_keyword(parser, current_start, "ensure", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "module", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_MODULE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "rescue", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "return", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_RETURN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "unless", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_UNLESS, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) != PM_TOKEN_EOF) return type;
- break;
- case 8:
- if ((type = lex_keyword(parser, current_start, "__LINE__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___LINE__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- if ((type = lex_keyword(parser, current_start, "__FILE__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___FILE__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- break;
- case 12:
- if ((type = lex_keyword(parser, current_start, "__ENCODING__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___ENCODING__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type;
- break;
- }
- }
-
- if (encoding_changed) {
- return parser->encoding->isupper_char(current_start, end - current_start) ? PM_TOKEN_CONSTANT : PM_TOKEN_IDENTIFIER;
- }
- return pm_encoding_utf_8_isupper_char(current_start, end - current_start) ? PM_TOKEN_CONSTANT : PM_TOKEN_IDENTIFIER;
-}
-
-/**
- * Returns true if the current token that the parser is considering is at the
- * beginning of a line or the beginning of the source.
- */
-static bool
-current_token_starts_line(pm_parser_t *parser) {
- return (parser->current.start == parser->start) || (parser->current.start[-1] == '\n');
-}
-
-/**
- * When we hit a # while lexing something like a string, we need to potentially
- * handle interpolation. This function performs that check. It returns a token
- * type representing what it found. Those cases are:
- *
- * * PM_TOKEN_NOT_PROVIDED - No interpolation was found at this point. The
- * caller should keep lexing.
- * * PM_TOKEN_STRING_CONTENT - No interpolation was found at this point. The
- * caller should return this token type.
- * * PM_TOKEN_EMBEXPR_BEGIN - An embedded expression was found. The caller
- * should return this token type.
- * * PM_TOKEN_EMBVAR - An embedded variable was found. The caller should return
- * this token type.
- */
-static pm_token_type_t
-lex_interpolation(pm_parser_t *parser, const uint8_t *pound) {
- // If there is no content following this #, then we're at the end of
- // the string and we can safely return string content.
- if (pound + 1 >= parser->end) {
- parser->current.end = pound + 1;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- // Now we'll check against the character the follows the #. If it constitutes
- // valid interplation, we'll handle that, otherwise we'll return
- // PM_TOKEN_NOT_PROVIDED.
- switch (pound[1]) {
- case '@': {
- // In this case we may have hit an embedded instance or class variable.
- if (pound + 2 >= parser->end) {
- parser->current.end = pound + 1;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- // If we're looking at a @ and there's another @, then we'll skip past the
- // second @.
- const uint8_t *variable = pound + 2;
- if (*variable == '@' && pound + 3 < parser->end) variable++;
-
- if (char_is_identifier_start(parser, variable)) {
- // At this point we're sure that we've either hit an embedded instance
- // or class variable. In this case we'll first need to check if we've
- // already consumed content.
- if (pound > parser->current.start) {
- parser->current.end = pound;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- // Otherwise we need to return the embedded variable token
- // and then switch to the embedded variable lex mode.
- lex_mode_push(parser, (pm_lex_mode_t) { .mode = PM_LEX_EMBVAR });
- parser->current.end = pound + 1;
- return PM_TOKEN_EMBVAR;
- }
-
- // If we didn't get an valid interpolation, then this is just regular
- // string content. This is like if we get "#@-". In this case the caller
- // should keep lexing.
- parser->current.end = pound + 1;
- return PM_TOKEN_NOT_PROVIDED;
- }
- case '$':
- // In this case we may have hit an embedded global variable. If there's
- // not enough room, then we'll just return string content.
- if (pound + 2 >= parser->end) {
- parser->current.end = pound + 1;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- // This is the character that we're going to check to see if it is the
- // start of an identifier that would indicate that this is a global
- // variable.
- const uint8_t *check = pound + 2;
-
- if (pound[2] == '-') {
- if (pound + 3 >= parser->end) {
- parser->current.end = pound + 2;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- check++;
- }
-
- // If the character that we're going to check is the start of an
- // identifier, or we don't have a - and the character is a decimal number
- // or a global name punctuation character, then we've hit an embedded
- // global variable.
- if (
- char_is_identifier_start(parser, check) ||
- (pound[2] != '-' && (pm_char_is_decimal_digit(pound[2]) || char_is_global_name_punctuation(pound[2])))
- ) {
- // In this case we've hit an embedded global variable. First check to
- // see if we've already consumed content. If we have, then we need to
- // return that content as string content first.
- if (pound > parser->current.start) {
- parser->current.end = pound;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- // Otherwise, we need to return the embedded variable token and switch
- // to the embedded variable lex mode.
- lex_mode_push(parser, (pm_lex_mode_t) { .mode = PM_LEX_EMBVAR });
- parser->current.end = pound + 1;
- return PM_TOKEN_EMBVAR;
- }
-
- // In this case we've hit a #$ that does not indicate a global variable.
- // In this case we'll continue lexing past it.
- parser->current.end = pound + 1;
- return PM_TOKEN_NOT_PROVIDED;
- case '{':
- // In this case it's the start of an embedded expression. If we have
- // already consumed content, then we need to return that content as string
- // content first.
- if (pound > parser->current.start) {
- parser->current.end = pound;
- return PM_TOKEN_STRING_CONTENT;
- }
-
- parser->enclosure_nesting++;
-
- // Otherwise we'll skip past the #{ and begin lexing the embedded
- // expression.
- lex_mode_push(parser, (pm_lex_mode_t) { .mode = PM_LEX_EMBEXPR });
- parser->current.end = pound + 2;
- parser->command_start = true;
- pm_do_loop_stack_push(parser, false);
- return PM_TOKEN_EMBEXPR_BEGIN;
- default:
- // In this case we've hit a # that doesn't constitute interpolation. We'll
- // mark that by returning the not provided token type. This tells the
- // consumer to keep lexing forward.
- parser->current.end = pound + 1;
- return PM_TOKEN_NOT_PROVIDED;
- }
-}
-
-static const uint8_t PM_ESCAPE_FLAG_NONE = 0x0;
-static const uint8_t PM_ESCAPE_FLAG_CONTROL = 0x1;
-static const uint8_t PM_ESCAPE_FLAG_META = 0x2;
-static const uint8_t PM_ESCAPE_FLAG_SINGLE = 0x4;
-static const uint8_t PM_ESCAPE_FLAG_REGEXP = 0x8;
-
-/**
- * This is a lookup table for whether or not an ASCII character is printable.
- */
-static const bool ascii_printable_chars[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
-};
-
-static inline bool
-char_is_ascii_printable(const uint8_t b) {
- return (b < 0x80) && ascii_printable_chars[b];
-}
-
-/**
- * Return the value that a hexadecimal digit character represents. For example,
- * transform 'a' into 10, 'b' into 11, etc.
- */
-static inline uint8_t
-escape_hexadecimal_digit(const uint8_t value) {
- return (uint8_t) ((value <= '9') ? (value - '0') : (value & 0x7) + 9);
-}
-
-/**
- * Scan the 4 digits of a Unicode escape into the value. Returns the number of
- * digits scanned. This function assumes that the characters have already been
- * validated.
- */
-static inline uint32_t
-escape_unicode(const uint8_t *string, size_t length) {
- uint32_t value = 0;
- for (size_t index = 0; index < length; index++) {
- if (index != 0) value <<= 4;
- value |= escape_hexadecimal_digit(string[index]);
- }
- return value;
-}
-
-/**
- * Escape a single character value based on the given flags.
- */
-static inline uint8_t
-escape_byte(uint8_t value, const uint8_t flags) {
- if (flags & PM_ESCAPE_FLAG_CONTROL) value &= 0x1f;
- if (flags & PM_ESCAPE_FLAG_META) value |= 0x80;
- return value;
-}
-
-/**
- * Write a unicode codepoint to the given buffer.
- */
-static inline void
-escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t flags, const uint8_t *start, const uint8_t *end, uint32_t value) {
- // \u escape sequences in string-like structures implicitly change the
- // encoding to UTF-8 if they are >= 0x80 or if they are used in a character
- // literal.
- if (value >= 0x80 || flags & PM_ESCAPE_FLAG_SINGLE) {
- if (parser->explicit_encoding != NULL && parser->explicit_encoding != PM_ENCODING_UTF_8_ENTRY) {
- PM_PARSER_ERR_FORMAT(parser, start, end, PM_ERR_MIXED_ENCODING, parser->explicit_encoding->name);
- }
-
- parser->explicit_encoding = PM_ENCODING_UTF_8_ENTRY;
- }
-
- if (value <= 0x7F) { // 0xxxxxxx
- pm_buffer_append_byte(buffer, (uint8_t) value);
- } else if (value <= 0x7FF) { // 110xxxxx 10xxxxxx
- pm_buffer_append_byte(buffer, (uint8_t) (0xC0 | (value >> 6)));
- pm_buffer_append_byte(buffer, (uint8_t) (0x80 | (value & 0x3F)));
- } else if (value <= 0xFFFF) { // 1110xxxx 10xxxxxx 10xxxxxx
- pm_buffer_append_byte(buffer, (uint8_t) (0xE0 | (value >> 12)));
- pm_buffer_append_byte(buffer, (uint8_t) (0x80 | ((value >> 6) & 0x3F)));
- pm_buffer_append_byte(buffer, (uint8_t) (0x80 | (value & 0x3F)));
- } else if (value <= 0x10FFFF) { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- pm_buffer_append_byte(buffer, (uint8_t) (0xF0 | (value >> 18)));
- pm_buffer_append_byte(buffer, (uint8_t) (0x80 | ((value >> 12) & 0x3F)));
- pm_buffer_append_byte(buffer, (uint8_t) (0x80 | ((value >> 6) & 0x3F)));
- pm_buffer_append_byte(buffer, (uint8_t) (0x80 | (value & 0x3F)));
- } else {
- pm_parser_err(parser, start, end, PM_ERR_ESCAPE_INVALID_UNICODE);
- pm_buffer_append_byte(buffer, 0xEF);
- pm_buffer_append_byte(buffer, 0xBF);
- pm_buffer_append_byte(buffer, 0xBD);
- }
-}
-
-/**
- * When you're writing a byte to the unescape buffer, if the byte is non-ASCII
- * (i.e., the top bit is set) then it locks in the encoding.
- */
-static inline void
-escape_write_byte_encoded(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t byte) {
- if (byte >= 0x80) {
- if (parser->explicit_encoding != NULL && parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY && parser->encoding != PM_ENCODING_UTF_8_ENTRY) {
- PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_MIXED_ENCODING, parser->encoding->name);
- }
-
- parser->explicit_encoding = parser->encoding;
- }
-
- pm_buffer_append_byte(buffer, byte);
-}
-
-/**
- * The regular expression engine doesn't support the same escape sequences as
- * Ruby does. So first we have to read the escape sequence, and then we have to
- * format it like the regular expression engine expects it. For example, in Ruby
- * if we have:
- *
- * /\M-\C-?/
- *
- * then the first byte is actually 255, so we have to rewrite this as:
- *
- * /\xFF/
- *
- * Note that in this case there is a literal \ byte in the regular expression
- * source so that the regular expression engine will perform its own unescaping.
- */
-static inline void
-escape_write_byte(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags, uint8_t byte) {
- if (flags & PM_ESCAPE_FLAG_REGEXP) {
- pm_buffer_append_bytes(buffer, (const uint8_t *) "\\x", 2);
-
- uint8_t byte1 = (uint8_t) ((byte >> 4) & 0xF);
- uint8_t byte2 = (uint8_t) (byte & 0xF);
-
- if (byte1 >= 0xA) {
- pm_buffer_append_byte(buffer, (uint8_t) ((byte1 - 0xA) + 'A'));
- } else {
- pm_buffer_append_byte(buffer, (uint8_t) (byte1 + '0'));
- }
-
- if (byte2 >= 0xA) {
- pm_buffer_append_byte(buffer, (uint8_t) (byte2 - 0xA + 'A'));
- } else {
- pm_buffer_append_byte(buffer, (uint8_t) (byte2 + '0'));
- }
- } else {
- escape_write_byte_encoded(parser, buffer, byte);
- }
-}
-
-/**
- * Read the value of an escape into the buffer.
- */
-static void
-escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) {
- switch (peek(parser)) {
- case '\\': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\\', flags));
- return;
- }
- case '\'': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\'', flags));
- return;
- }
- case 'a': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\a', flags));
- return;
- }
- case 'b': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\b', flags));
- return;
- }
- case 'e': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\033', flags));
- return;
- }
- case 'f': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\f', flags));
- return;
- }
- case 'n': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\n', flags));
- return;
- }
- case 'r': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\r', flags));
- return;
- }
- case 's': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte(' ', flags));
- return;
- }
- case 't': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\t', flags));
- return;
- }
- case 'v': {
- parser->current.end++;
- escape_write_byte_encoded(parser, buffer, escape_byte('\v', flags));
- return;
- }
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': {
- uint8_t value = (uint8_t) (*parser->current.end - '0');
- parser->current.end++;
-
- if (pm_char_is_octal_digit(peek(parser))) {
- value = ((uint8_t) (value << 3)) | ((uint8_t) (*parser->current.end - '0'));
- parser->current.end++;
-
- if (pm_char_is_octal_digit(peek(parser))) {
- value = ((uint8_t) (value << 3)) | ((uint8_t) (*parser->current.end - '0'));
- parser->current.end++;
- }
- }
-
- escape_write_byte_encoded(parser, buffer, value);
- return;
- }
- case 'x': {
- const uint8_t *start = parser->current.end - 1;
-
- parser->current.end++;
- uint8_t byte = peek(parser);
-
- if (pm_char_is_hexadecimal_digit(byte)) {
- uint8_t value = escape_hexadecimal_digit(byte);
- parser->current.end++;
-
- byte = peek(parser);
- if (pm_char_is_hexadecimal_digit(byte)) {
- value = (uint8_t) ((value << 4) | escape_hexadecimal_digit(byte));
- parser->current.end++;
- }
-
- if (flags & PM_ESCAPE_FLAG_REGEXP) {
- pm_buffer_append_bytes(buffer, start, (size_t) (parser->current.end - start));
- } else {
- escape_write_byte_encoded(parser, buffer, value);
- }
- } else {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_HEXADECIMAL);
- }
-
- return;
- }
- case 'u': {
- const uint8_t *start = parser->current.end - 1;
- parser->current.end++;
-
- if (
- (parser->current.end + 4 <= parser->end) &&
- pm_char_is_hexadecimal_digit(parser->current.end[0]) &&
- pm_char_is_hexadecimal_digit(parser->current.end[1]) &&
- pm_char_is_hexadecimal_digit(parser->current.end[2]) &&
- pm_char_is_hexadecimal_digit(parser->current.end[3])
- ) {
- uint32_t value = escape_unicode(parser->current.end, 4);
-
- if (flags & PM_ESCAPE_FLAG_REGEXP) {
- pm_buffer_append_bytes(buffer, start, (size_t) (parser->current.end + 4 - start));
- } else {
- escape_write_unicode(parser, buffer, flags, start, parser->current.end + 4, value);
- }
-
- parser->current.end += 4;
- } else if (peek(parser) == '{') {
- const uint8_t *unicode_codepoints_start = parser->current.end - 2;
-
- parser->current.end++;
- parser->current.end += pm_strspn_whitespace(parser->current.end, parser->end - parser->current.end);
-
- const uint8_t *extra_codepoints_start = NULL;
- int codepoints_count = 0;
-
- while ((parser->current.end < parser->end) && (*parser->current.end != '}')) {
- const uint8_t *unicode_start = parser->current.end;
- size_t hexadecimal_length = pm_strspn_hexadecimal_digit(parser->current.end, parser->end - parser->current.end);
-
- if (hexadecimal_length > 6) {
- // \u{nnnn} character literal allows only 1-6 hexadecimal digits
- pm_parser_err(parser, unicode_start, unicode_start + hexadecimal_length, PM_ERR_ESCAPE_INVALID_UNICODE_LONG);
- } else if (hexadecimal_length == 0) {
- // there are not hexadecimal characters
- pm_parser_err(parser, unicode_start, unicode_start + hexadecimal_length, PM_ERR_ESCAPE_INVALID_UNICODE);
- return;
- }
-
- parser->current.end += hexadecimal_length;
- codepoints_count++;
- if (flags & PM_ESCAPE_FLAG_SINGLE && codepoints_count == 2) {
- extra_codepoints_start = unicode_start;
- }
-
- if (!(flags & PM_ESCAPE_FLAG_REGEXP)) {
- uint32_t value = escape_unicode(unicode_start, hexadecimal_length);
- escape_write_unicode(parser, buffer, flags, unicode_start, parser->current.end, value);
- }
-
- parser->current.end += pm_strspn_whitespace(parser->current.end, parser->end - parser->current.end);
- }
-
- // ?\u{nnnn} character literal should contain only one codepoint
- // and cannot be like ?\u{nnnn mmmm}.
- if (flags & PM_ESCAPE_FLAG_SINGLE && codepoints_count > 1) {
- pm_parser_err(parser, extra_codepoints_start, parser->current.end - 1, PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL);
- }
-
- if (peek(parser) == '}') {
- parser->current.end++;
- } else {
- pm_parser_err(parser, unicode_codepoints_start, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE_TERM);
- }
-
- if (flags & PM_ESCAPE_FLAG_REGEXP) {
- pm_buffer_append_bytes(buffer, unicode_codepoints_start, (size_t) (parser->current.end - unicode_codepoints_start));
- }
- } else {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_UNICODE);
- }
-
- return;
- }
- case 'c': {
- parser->current.end++;
- if (parser->current.end == parser->end) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL);
- return;
- }
-
- uint8_t peeked = peek(parser);
- switch (peeked) {
- case '?': {
- parser->current.end++;
- escape_write_byte(parser, buffer, flags, escape_byte(0x7f, flags));
- return;
- }
- case '\\':
- if (flags & PM_ESCAPE_FLAG_CONTROL) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT);
- return;
- }
- parser->current.end++;
- escape_read(parser, buffer, flags | PM_ESCAPE_FLAG_CONTROL);
- return;
- default: {
- if (!char_is_ascii_printable(peeked)) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL);
- return;
- }
-
- parser->current.end++;
- escape_write_byte(parser, buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL));
- return;
- }
- }
- }
- case 'C': {
- parser->current.end++;
- if (peek(parser) != '-') {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL);
- return;
- }
-
- parser->current.end++;
- if (parser->current.end == parser->end) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL);
- return;
- }
-
- uint8_t peeked = peek(parser);
- switch (peeked) {
- case '?': {
- parser->current.end++;
- escape_write_byte(parser, buffer, flags, escape_byte(0x7f, flags));
- return;
- }
- case '\\':
- if (flags & PM_ESCAPE_FLAG_CONTROL) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT);
- return;
- }
- parser->current.end++;
- escape_read(parser, buffer, flags | PM_ESCAPE_FLAG_CONTROL);
- return;
- default: {
- if (!char_is_ascii_printable(peeked)) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL);
- return;
- }
-
- parser->current.end++;
- escape_write_byte(parser, buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL));
- return;
- }
- }
- }
- case 'M': {
- parser->current.end++;
- if (peek(parser) != '-') {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_META);
- return;
- }
-
- parser->current.end++;
- if (parser->current.end == parser->end) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_META);
- return;
- }
-
- uint8_t peeked = peek(parser);
- if (peeked == '\\') {
- if (flags & PM_ESCAPE_FLAG_META) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_META_REPEAT);
- return;
- }
- parser->current.end++;
- escape_read(parser, buffer, flags | PM_ESCAPE_FLAG_META);
- return;
- }
-
- if (!char_is_ascii_printable(peeked)) {
- pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_META);
- return;
- }
-
- parser->current.end++;
- escape_write_byte(parser, buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META));
- return;
- }
- case '\r': {
- if (peek_offset(parser, 1) == '\n') {
- parser->current.end += 2;
- escape_write_byte_encoded(parser, buffer, escape_byte('\n', flags));
- return;
- }
- }
- /* fallthrough */
- default: {
- if (parser->current.end < parser->end) {
- escape_write_byte_encoded(parser, buffer, *parser->current.end++);
- }
- return;
- }
- }
-}
-
-/**
- * This function is responsible for lexing either a character literal or the ?
- * operator. The supported character literals are described below.
- *
- * \\a bell, ASCII 07h (BEL)
- * \\b backspace, ASCII 08h (BS)
- * \t horizontal tab, ASCII 09h (TAB)
- * \\n newline (line feed), ASCII 0Ah (LF)
- * \v vertical tab, ASCII 0Bh (VT)
- * \f form feed, ASCII 0Ch (FF)
- * \r carriage return, ASCII 0Dh (CR)
- * \\e escape, ASCII 1Bh (ESC)
- * \s space, ASCII 20h (SPC)
- * \\ backslash
- * \nnn octal bit pattern, where nnn is 1-3 octal digits ([0-7])
- * \xnn hexadecimal bit pattern, where nn is 1-2 hexadecimal digits ([0-9a-fA-F])
- * \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F])
- * \u{nnnn ...} Unicode character(s), where each nnnn is 1-6 hexadecimal digits ([0-9a-fA-F])
- * \cx or \C-x control character, where x is an ASCII printable character
- * \M-x meta character, where x is an ASCII printable character
- * \M-\C-x meta control character, where x is an ASCII printable character
- * \M-\cx same as above
- * \\c\M-x same as above
- * \\c? or \C-? delete, ASCII 7Fh (DEL)
- */
-static pm_token_type_t
-lex_question_mark(pm_parser_t *parser) {
- if (lex_state_end_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- return PM_TOKEN_QUESTION_MARK;
- }
-
- if (parser->current.end >= parser->end) {
- pm_parser_err_current(parser, PM_ERR_INCOMPLETE_QUESTION_MARK);
- pm_string_shared_init(&parser->current_string, parser->current.start + 1, parser->current.end);
- return PM_TOKEN_CHARACTER_LITERAL;
- }
-
- if (pm_char_is_whitespace(*parser->current.end)) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- return PM_TOKEN_QUESTION_MARK;
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
-
- if (match(parser, '\\')) {
- lex_state_set(parser, PM_LEX_STATE_END);
-
- pm_buffer_t buffer;
- pm_buffer_init_capacity(&buffer, 3);
-
- escape_read(parser, &buffer, PM_ESCAPE_FLAG_SINGLE);
- pm_string_owned_init(&parser->current_string, (uint8_t *) buffer.value, buffer.length);
-
- return PM_TOKEN_CHARACTER_LITERAL;
- } else {
- size_t encoding_width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
-
- // Ternary operators can have a ? immediately followed by an identifier
- // which starts with an underscore. We check for this case here.
- if (
- !(parser->encoding->alnum_char(parser->current.end, parser->end - parser->current.end) || peek(parser) == '_') ||
- (
- (parser->current.end + encoding_width >= parser->end) ||
- !char_is_identifier(parser, parser->current.end + encoding_width)
- )
- ) {
- lex_state_set(parser, PM_LEX_STATE_END);
- parser->current.end += encoding_width;
- pm_string_shared_init(&parser->current_string, parser->current.start + 1, parser->current.end);
- return PM_TOKEN_CHARACTER_LITERAL;
- }
- }
-
- return PM_TOKEN_QUESTION_MARK;
-}
-
-/**
- * Lex a variable that starts with an @ sign (either an instance or class
- * variable).
- */
-static pm_token_type_t
-lex_at_variable(pm_parser_t *parser) {
- pm_token_type_t type = match(parser, '@') ? PM_TOKEN_CLASS_VARIABLE : PM_TOKEN_INSTANCE_VARIABLE;
- size_t width;
-
- if (parser->current.end < parser->end && (width = char_is_identifier_start(parser, parser->current.end)) > 0) {
- parser->current.end += width;
-
- while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0) {
- parser->current.end += width;
- }
- } else if (type == PM_TOKEN_CLASS_VARIABLE) {
- pm_parser_err_current(parser, PM_ERR_INCOMPLETE_VARIABLE_CLASS);
- } else {
- pm_parser_err_current(parser, PM_ERR_INCOMPLETE_VARIABLE_INSTANCE);
- }
-
- // If we're lexing an embedded variable, then we need to pop back into the
- // parent lex context.
- if (parser->lex_modes.current->mode == PM_LEX_EMBVAR) {
- lex_mode_pop(parser);
- }
-
- return type;
-}
-
-/**
- * Optionally call out to the lex callback if one is provided.
- */
-static inline void
-parser_lex_callback(pm_parser_t *parser) {
- if (parser->lex_callback) {
- parser->lex_callback->callback(parser->lex_callback->data, parser, &parser->current);
- }
-}
-
-/**
- * Return a new comment node of the specified type.
- */
-static inline pm_comment_t *
-parser_comment(pm_parser_t *parser, pm_comment_type_t type) {
- pm_comment_t *comment = (pm_comment_t *) calloc(sizeof(pm_comment_t), 1);
- if (comment == NULL) return NULL;
-
- *comment = (pm_comment_t) {
- .type = type,
- .location = { parser->current.start, parser->current.end }
- };
-
- return comment;
-}
-
-/**
- * Lex out embedded documentation, and return when we have either hit the end of
- * the file or the end of the embedded documentation. This calls the callback
- * manually because only the lexer should see these tokens, not the parser.
- */
-static pm_token_type_t
-lex_embdoc(pm_parser_t *parser) {
- // First, lex out the EMBDOC_BEGIN token.
- const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end);
-
- if (newline == NULL) {
- parser->current.end = parser->end;
- } else {
- pm_newline_list_append(&parser->newline_list, newline);
- parser->current.end = newline + 1;
- }
-
- parser->current.type = PM_TOKEN_EMBDOC_BEGIN;
- parser_lex_callback(parser);
-
- // Now, create a comment that is going to be attached to the parser.
- pm_comment_t *comment = parser_comment(parser, PM_COMMENT_EMBDOC);
- if (comment == NULL) return PM_TOKEN_EOF;
-
- // Now, loop until we find the end of the embedded documentation or the end of
- // the file.
- while (parser->current.end + 4 <= parser->end) {
- parser->current.start = parser->current.end;
-
- // If we've hit the end of the embedded documentation then we'll return that
- // token here.
- if (memcmp(parser->current.end, "=end", 4) == 0 &&
- (parser->current.end + 4 == parser->end || pm_char_is_whitespace(parser->current.end[4]))) {
- const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end);
-
- if (newline == NULL) {
- parser->current.end = parser->end;
- } else {
- pm_newline_list_append(&parser->newline_list, newline);
- parser->current.end = newline + 1;
- }
-
- parser->current.type = PM_TOKEN_EMBDOC_END;
- parser_lex_callback(parser);
-
- comment->location.end = parser->current.end;
- pm_list_append(&parser->comment_list, (pm_list_node_t *) comment);
-
- return PM_TOKEN_EMBDOC_END;
- }
-
- // Otherwise, we'll parse until the end of the line and return a line of
- // embedded documentation.
- const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end);
-
- if (newline == NULL) {
- parser->current.end = parser->end;
- } else {
- pm_newline_list_append(&parser->newline_list, newline);
- parser->current.end = newline + 1;
- }
-
- parser->current.type = PM_TOKEN_EMBDOC_LINE;
- parser_lex_callback(parser);
- }
-
- pm_parser_err_current(parser, PM_ERR_EMBDOC_TERM);
-
- comment->location.end = parser->current.end;
- pm_list_append(&parser->comment_list, (pm_list_node_t *) comment);
-
- return PM_TOKEN_EOF;
-}
-
-/**
- * Set the current type to an ignored newline and then call the lex callback.
- * This happens in a couple places depending on whether or not we have already
- * lexed a comment.
- */
-static inline void
-parser_lex_ignored_newline(pm_parser_t *parser) {
- parser->current.type = PM_TOKEN_IGNORED_NEWLINE;
- parser_lex_callback(parser);
-}
-
-/**
- * This function will be called when a newline is encountered. In some newlines,
- * we need to check if there is a heredoc or heredocs that we have already lexed
- * the body of that we need to now skip past. That will be indicated by the
- * heredoc_end field on the parser.
- *
- * If it is set, then we need to skip past the heredoc body and then clear the
- * heredoc_end field.
- */
-static inline void
-parser_flush_heredoc_end(pm_parser_t *parser) {
- assert(parser->heredoc_end <= parser->end);
- parser->next_start = parser->heredoc_end;
- parser->heredoc_end = NULL;
-}
-
-/**
- * When we're lexing certain types (strings, symbols, lists, etc.) we have
- * string content associated with the tokens. For example:
- *
- * "foo"
- *
- * In this case, the string content is foo. Since there is no escaping, there's
- * no need to track additional information and the token can be returned as
- * normal. However, if we have escape sequences:
- *
- * "foo\n"
- *
- * then the bytes in the string are "f", "o", "o", "\", "n", but we want to
- * provide out consumers with the string content "f", "o", "o", "\n". In these
- * cases, when we find the first escape sequence, we initialize a pm_buffer_t
- * to keep track of the string content. Then in the parser, it will
- * automatically attach the string content to the node that it belongs to.
- */
-typedef struct {
- /**
- * The buffer that we're using to keep track of the string content. It will
- * only be initialized if we receive an escape sequence.
- */
- pm_buffer_t buffer;
-
- /**
- * The cursor into the source string that points to how far we have
- * currently copied into the buffer.
- */
- const uint8_t *cursor;
-} pm_token_buffer_t;
-
-/**
- * Push the given byte into the token buffer.
- */
-static inline void
-pm_token_buffer_push(pm_token_buffer_t *token_buffer, uint8_t byte) {
- pm_buffer_append_byte(&token_buffer->buffer, byte);
-}
-
-/**
- * When we're about to return from lexing the current token and we know for sure
- * that we have found an escape sequence, this function is called to copy the
- *
- * contents of the token buffer into the current string on the parser so that it
- * can be attached to the correct node.
- */
-static inline void
-pm_token_buffer_copy(pm_parser_t *parser, pm_token_buffer_t *token_buffer) {
- pm_string_owned_init(&parser->current_string, (uint8_t *) token_buffer->buffer.value, token_buffer->buffer.length);
-}
-
-/**
- * When we're about to return from lexing the current token, we need to flush
- * all of the content that we have pushed into the buffer into the current
- * string. If we haven't pushed anything into the buffer, this means that we
- * never found an escape sequence, so we can directly reference the bounds of
- * the current string. Either way, at the return of this function it is expected
- *
- * that parser->current_string is established in such a way that it can be
- * attached to a node.
- */
-static void
-pm_token_buffer_flush(pm_parser_t *parser, pm_token_buffer_t *token_buffer) {
- if (token_buffer->cursor == NULL) {
- pm_string_shared_init(&parser->current_string, parser->current.start, parser->current.end);
- } else {
- pm_buffer_append_bytes(&token_buffer->buffer, token_buffer->cursor, (size_t) (parser->current.end - token_buffer->cursor));
- pm_token_buffer_copy(parser, token_buffer);
- }
-}
-
-/**
- * When we've found an escape sequence, we need to copy everything up to this
- * point into the buffer because we're about to provide a string that has
- * different content than a direct slice of the source.
- *
- *
- * It is expected that the parser's current token end will be pointing at one
- * byte past the backslash that starts the escape sequence.
- */
-static void
-pm_token_buffer_escape(pm_parser_t *parser, pm_token_buffer_t *token_buffer) {
- const uint8_t *start;
- if (token_buffer->cursor == NULL) {
- pm_buffer_init_capacity(&token_buffer->buffer, 16);
- start = parser->current.start;
- } else {
- start = token_buffer->cursor;
- }
-
- const uint8_t *end = parser->current.end - 1;
- pm_buffer_append_bytes(&token_buffer->buffer, start, (size_t) (end - start));
-}
-
-/**
- * Effectively the same thing as pm_strspn_inline_whitespace, but in the case of
- * a tilde heredoc expands out tab characters to the nearest tab boundaries.
- */
-static inline size_t
-pm_heredoc_strspn_inline_whitespace(pm_parser_t *parser, const uint8_t **cursor, pm_heredoc_indent_t indent) {
- size_t whitespace = 0;
-
- switch (indent) {
- case PM_HEREDOC_INDENT_NONE:
- // Do nothing, we can't match a terminator with
- // indentation and there's no need to calculate common
- // whitespace.
- break;
- case PM_HEREDOC_INDENT_DASH:
- // Skip past inline whitespace.
- *cursor += pm_strspn_inline_whitespace(*cursor, parser->end - *cursor);
- break;
- case PM_HEREDOC_INDENT_TILDE:
- // Skip past inline whitespace and calculate common
- // whitespace.
- while (*cursor < parser->end && pm_char_is_inline_whitespace(**cursor)) {
- if (**cursor == '\t') {
- whitespace = (whitespace / PM_TAB_WHITESPACE_SIZE + 1) * PM_TAB_WHITESPACE_SIZE;
- } else {
- whitespace++;
- }
- (*cursor)++;
- }
-
- break;
- }
-
- return whitespace;
-}
-
-/**
- * This is a convenience macro that will set the current token type, call the
- * lex callback, and then return from the parser_lex function.
- */
-#define LEX(token_type) parser->current.type = token_type; parser_lex_callback(parser); return
-
-/**
- * Called when the parser requires a new token. The parser maintains a moving
- * window of two tokens at a time: parser.previous and parser.current. This
- * function will move the current token into the previous token and then
- * lex a new token into the current token.
- */
-static void
-parser_lex(pm_parser_t *parser) {
- assert(parser->current.end <= parser->end);
- parser->previous = parser->current;
-
- // This value mirrors cmd_state from CRuby.
- bool previous_command_start = parser->command_start;
- parser->command_start = false;
-
- // This is used to communicate to the newline lexing function that we've
- // already seen a comment.
- bool lexed_comment = false;
-
- // Here we cache the current value of the semantic token seen flag. This is
- // used to reset it in case we find a token that shouldn't flip this flag.
- unsigned int semantic_token_seen = parser->semantic_token_seen;
- parser->semantic_token_seen = true;
-
- switch (parser->lex_modes.current->mode) {
- case PM_LEX_DEFAULT:
- case PM_LEX_EMBEXPR:
- case PM_LEX_EMBVAR:
-
- // We have a specific named label here because we are going to jump back to
- // this location in the event that we have lexed a token that should not be
- // returned to the parser. This includes comments, ignored newlines, and
- // invalid tokens of some form.
- lex_next_token: {
- // If we have the special next_start pointer set, then we're going to jump
- // to that location and start lexing from there.
- if (parser->next_start != NULL) {
- parser->current.end = parser->next_start;
- parser->next_start = NULL;
- }
-
- // This value mirrors space_seen from CRuby. It tracks whether or not
- // space has been eaten before the start of the next token.
- bool space_seen = false;
-
- // First, we're going to skip past any whitespace at the front of the next
- // token.
- bool chomping = true;
- while (parser->current.end < parser->end && chomping) {
- switch (*parser->current.end) {
- case ' ':
- case '\t':
- case '\f':
- case '\v':
- parser->current.end++;
- space_seen = true;
- break;
- case '\r':
- if (match_eol_offset(parser, 1)) {
- chomping = false;
- } else {
- parser->current.end++;
- space_seen = true;
- }
- break;
- case '\\': {
- size_t eol_length = match_eol_offset(parser, 1);
- if (eol_length) {
- if (parser->heredoc_end) {
- parser->current.end = parser->heredoc_end;
- parser->heredoc_end = NULL;
- } else {
- parser->current.end += eol_length + 1;
- pm_newline_list_append(&parser->newline_list, parser->current.end - 1);
- space_seen = true;
- }
- } else if (pm_char_is_inline_whitespace(*parser->current.end)) {
- parser->current.end += 2;
- } else {
- chomping = false;
- }
-
- break;
- }
- default:
- chomping = false;
- break;
- }
- }
-
- // Next, we'll set to start of this token to be the current end.
- parser->current.start = parser->current.end;
-
- // We'll check if we're at the end of the file. If we are, then we
- // need to return the EOF token.
- if (parser->current.end >= parser->end) {
- LEX(PM_TOKEN_EOF);
- }
-
- // Finally, we'll check the current character to determine the next
- // token.
- switch (*parser->current.end++) {
- case '\0': // NUL or end of script
- case '\004': // ^D
- case '\032': // ^Z
- parser->current.end--;
- LEX(PM_TOKEN_EOF);
-
- case '#': { // comments
- const uint8_t *ending = next_newline(parser->current.end, parser->end - parser->current.end);
- parser->current.end = ending == NULL ? parser->end : ending;
-
- // If we found a comment while lexing, then we're going to
- // add it to the list of comments in the file and keep
- // lexing.
- pm_comment_t *comment = parser_comment(parser, PM_COMMENT_INLINE);
- pm_list_append(&parser->comment_list, (pm_list_node_t *) comment);
-
- if (ending) parser->current.end++;
- parser->current.type = PM_TOKEN_COMMENT;
- parser_lex_callback(parser);
-
- // Here, parse the comment to see if it's a magic comment
- // and potentially change state on the parser.
- if (!parser_lex_magic_comment(parser, semantic_token_seen) && (parser->current.start == parser->encoding_comment_start)) {
- ptrdiff_t length = parser->current.end - parser->current.start;
-
- // If we didn't find a magic comment within the first
- // pass and we're at the start of the file, then we need
- // to do another pass to potentially find other patterns
- // for encoding comments.
- if (length >= 10) parser_lex_magic_comment_encoding(parser);
- }
-
- lexed_comment = true;
- }
- /* fallthrough */
- case '\r':
- case '\n': {
- parser->semantic_token_seen = semantic_token_seen & 0x1;
- size_t eol_length = match_eol_at(parser, parser->current.end - 1);
-
- if (eol_length) {
- // The only way you can have carriage returns in this
- // particular loop is if you have a carriage return
- // followed by a newline. In that case we'll just skip
- // over the carriage return and continue lexing, in
- // order to make it so that the newline token
- // encapsulates both the carriage return and the
- // newline. Note that we need to check that we haven't
- // already lexed a comment here because that falls
- // through into here as well.
- if (!lexed_comment) {
- parser->current.end += eol_length - 1; // skip CR
- }
-
- if (parser->heredoc_end == NULL) {
- pm_newline_list_append(&parser->newline_list, parser->current.end - 1);
- }
- }
-
- if (parser->heredoc_end) {
- parser_flush_heredoc_end(parser);
- }
-
- // If this is an ignored newline, then we can continue lexing after
- // calling the callback with the ignored newline token.
- switch (lex_state_ignored_p(parser)) {
- case PM_IGNORED_NEWLINE_NONE:
- break;
- case PM_IGNORED_NEWLINE_PATTERN:
- if (parser->pattern_matching_newlines || parser->in_keyword_arg) {
- if (!lexed_comment) parser_lex_ignored_newline(parser);
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser->command_start = true;
- parser->current.type = PM_TOKEN_NEWLINE;
- return;
- }
- /* fallthrough */
- case PM_IGNORED_NEWLINE_ALL:
- if (!lexed_comment) parser_lex_ignored_newline(parser);
- lexed_comment = false;
- goto lex_next_token;
- }
-
- // Here we need to look ahead and see if there is a call operator
- // (either . or &.) that starts the next line. If there is, then this
- // is going to become an ignored newline and we're going to instead
- // return the call operator.
- const uint8_t *next_content = parser->next_start == NULL ? parser->current.end : parser->next_start;
- next_content += pm_strspn_inline_whitespace(next_content, parser->end - next_content);
-
- if (next_content < parser->end) {
- // If we hit a comment after a newline, then we're going to check
- // if it's ignored or if it's followed by a method call ('.').
- // If it is, then we're going to call the
- // callback with an ignored newline and then continue lexing.
- // Otherwise we'll return a regular newline.
- if (next_content[0] == '#') {
- // Here we look for a "." or "&." following a "\n".
- const uint8_t *following = next_newline(next_content, parser->end - next_content);
-
- while (following && (following + 1 < parser->end)) {
- following++;
- following += pm_strspn_inline_whitespace(following, parser->end - following);
-
- // If this is not followed by a comment, then we can break out
- // of this loop.
- if (peek_at(parser, following) != '#') break;
-
- // If there is a comment, then we need to find the end of the
- // comment and continue searching from there.
- following = next_newline(following, parser->end - following);
- }
-
- // If the lex state was ignored, or we hit a '.' or a '&.',
- // we will lex the ignored newline
- if (
- lex_state_ignored_p(parser) ||
- (following && (
- (peek_at(parser, following) == '.') ||
- (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
- ))
- ) {
- if (!lexed_comment) parser_lex_ignored_newline(parser);
- lexed_comment = false;
- goto lex_next_token;
- }
- }
-
- // If we hit a . after a newline, then we're in a call chain and
- // we need to return the call operator.
- if (next_content[0] == '.') {
- // To match ripper, we need to emit an ignored newline even though
- // its a real newline in the case that we have a beginless range
- // on a subsequent line.
- if (peek_at(parser, next_content + 1) == '.') {
- if (!lexed_comment) parser_lex_ignored_newline(parser);
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser->command_start = true;
- parser->current.type = PM_TOKEN_NEWLINE;
- return;
- }
-
- if (!lexed_comment) parser_lex_ignored_newline(parser);
- lex_state_set(parser, PM_LEX_STATE_DOT);
- parser->current.start = next_content;
- parser->current.end = next_content + 1;
- parser->next_start = NULL;
- LEX(PM_TOKEN_DOT);
- }
-
- // If we hit a &. after a newline, then we're in a call chain and
- // we need to return the call operator.
- if (peek_at(parser, next_content) == '&' && peek_at(parser, next_content + 1) == '.') {
- if (!lexed_comment) parser_lex_ignored_newline(parser);
- lex_state_set(parser, PM_LEX_STATE_DOT);
- parser->current.start = next_content;
- parser->current.end = next_content + 2;
- parser->next_start = NULL;
- LEX(PM_TOKEN_AMPERSAND_DOT);
- }
- }
-
- // At this point we know this is a regular newline, and we can set the
- // necessary state and return the token.
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser->command_start = true;
- parser->current.type = PM_TOKEN_NEWLINE;
- if (!lexed_comment) parser_lex_callback(parser);
- return;
- }
-
- // ,
- case ',':
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- LEX(PM_TOKEN_COMMA);
-
- // (
- case '(': {
- pm_token_type_t type = PM_TOKEN_PARENTHESIS_LEFT;
-
- if (space_seen && (lex_state_arg_p(parser) || parser->lex_state == (PM_LEX_STATE_END | PM_LEX_STATE_LABEL))) {
- type = PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES;
- }
-
- parser->enclosure_nesting++;
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- pm_do_loop_stack_push(parser, false);
- LEX(type);
- }
-
- // )
- case ')':
- parser->enclosure_nesting--;
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- pm_do_loop_stack_pop(parser);
- LEX(PM_TOKEN_PARENTHESIS_RIGHT);
-
- // ;
- case ';':
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser->command_start = true;
- LEX(PM_TOKEN_SEMICOLON);
-
- // [ [] []=
- case '[':
- parser->enclosure_nesting++;
- pm_token_type_t type = PM_TOKEN_BRACKET_LEFT;
-
- if (lex_state_operator_p(parser)) {
- if (match(parser, ']')) {
- parser->enclosure_nesting--;
- lex_state_set(parser, PM_LEX_STATE_ARG);
- LEX(match(parser, '=') ? PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL : PM_TOKEN_BRACKET_LEFT_RIGHT);
- }
-
- lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABEL);
- LEX(type);
- }
-
- if (lex_state_beg_p(parser) || (lex_state_arg_p(parser) && (space_seen || lex_state_p(parser, PM_LEX_STATE_LABELED)))) {
- type = PM_TOKEN_BRACKET_LEFT_ARRAY;
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- pm_do_loop_stack_push(parser, false);
- LEX(type);
-
- // ]
- case ']':
- parser->enclosure_nesting--;
- lex_state_set(parser, PM_LEX_STATE_END);
- pm_do_loop_stack_pop(parser);
- LEX(PM_TOKEN_BRACKET_RIGHT);
-
- // {
- case '{': {
- pm_token_type_t type = PM_TOKEN_BRACE_LEFT;
-
- if (parser->enclosure_nesting == parser->lambda_enclosure_nesting) {
- // This { begins a lambda
- parser->command_start = true;
- lex_state_set(parser, PM_LEX_STATE_BEG);
- type = PM_TOKEN_LAMBDA_BEGIN;
- } else if (lex_state_p(parser, PM_LEX_STATE_LABELED)) {
- // This { begins a hash literal
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- } else if (lex_state_p(parser, PM_LEX_STATE_ARG_ANY | PM_LEX_STATE_END | PM_LEX_STATE_ENDFN)) {
- // This { begins a block
- parser->command_start = true;
- lex_state_set(parser, PM_LEX_STATE_BEG);
- } else if (lex_state_p(parser, PM_LEX_STATE_ENDARG)) {
- // This { begins a block on a command
- parser->command_start = true;
- lex_state_set(parser, PM_LEX_STATE_BEG);
- } else {
- // This { begins a hash literal
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- }
-
- parser->enclosure_nesting++;
- parser->brace_nesting++;
- pm_do_loop_stack_push(parser, false);
-
- LEX(type);
- }
-
- // }
- case '}':
- parser->enclosure_nesting--;
- pm_do_loop_stack_pop(parser);
-
- if ((parser->lex_modes.current->mode == PM_LEX_EMBEXPR) && (parser->brace_nesting == 0)) {
- lex_mode_pop(parser);
- LEX(PM_TOKEN_EMBEXPR_END);
- }
-
- parser->brace_nesting--;
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(PM_TOKEN_BRACE_RIGHT);
-
- // * ** **= *=
- case '*': {
- if (match(parser, '*')) {
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_STAR_STAR_EQUAL);
- }
-
- pm_token_type_t type = PM_TOKEN_STAR_STAR;
-
- if (lex_state_spcarg_p(parser, space_seen) || lex_state_beg_p(parser)) {
- type = PM_TOKEN_USTAR_STAR;
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(type);
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_STAR_EQUAL);
- }
-
- pm_token_type_t type = PM_TOKEN_STAR;
-
- if (lex_state_spcarg_p(parser, space_seen)) {
- pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_STAR);
- type = PM_TOKEN_USTAR;
- } else if (lex_state_beg_p(parser)) {
- type = PM_TOKEN_USTAR;
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(type);
- }
-
- // ! != !~ !@
- case '!':
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- if (match(parser, '@')) {
- LEX(PM_TOKEN_BANG);
- }
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- if (match(parser, '=')) {
- LEX(PM_TOKEN_BANG_EQUAL);
- }
-
- if (match(parser, '~')) {
- LEX(PM_TOKEN_BANG_TILDE);
- }
-
- LEX(PM_TOKEN_BANG);
-
- // = => =~ == === =begin
- case '=':
- if (current_token_starts_line(parser) && (parser->current.end + 5 <= parser->end) && memcmp(parser->current.end, "begin", 5) == 0 && pm_char_is_whitespace(peek_offset(parser, 5))) {
- pm_token_type_t type = lex_embdoc(parser);
-
- if (type == PM_TOKEN_EOF) {
- LEX(type);
- }
-
- goto lex_next_token;
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- if (match(parser, '>')) {
- LEX(PM_TOKEN_EQUAL_GREATER);
- }
-
- if (match(parser, '~')) {
- LEX(PM_TOKEN_EQUAL_TILDE);
- }
-
- if (match(parser, '=')) {
- LEX(match(parser, '=') ? PM_TOKEN_EQUAL_EQUAL_EQUAL : PM_TOKEN_EQUAL_EQUAL);
- }
-
- LEX(PM_TOKEN_EQUAL);
-
- // < << <<= <= <=>
- case '<':
- if (match(parser, '<')) {
- if (
- !lex_state_p(parser, PM_LEX_STATE_DOT | PM_LEX_STATE_CLASS) &&
- !lex_state_end_p(parser) &&
- (!lex_state_p(parser, PM_LEX_STATE_ARG_ANY) || lex_state_p(parser, PM_LEX_STATE_LABELED) || space_seen)
- ) {
- const uint8_t *end = parser->current.end;
-
- pm_heredoc_quote_t quote = PM_HEREDOC_QUOTE_NONE;
- pm_heredoc_indent_t indent = PM_HEREDOC_INDENT_NONE;
-
- if (match(parser, '-')) {
- indent = PM_HEREDOC_INDENT_DASH;
- }
- else if (match(parser, '~')) {
- indent = PM_HEREDOC_INDENT_TILDE;
- }
-
- if (match(parser, '`')) {
- quote = PM_HEREDOC_QUOTE_BACKTICK;
- }
- else if (match(parser, '"')) {
- quote = PM_HEREDOC_QUOTE_DOUBLE;
- }
- else if (match(parser, '\'')) {
- quote = PM_HEREDOC_QUOTE_SINGLE;
- }
-
- const uint8_t *ident_start = parser->current.end;
- size_t width = 0;
-
- if (parser->current.end >= parser->end) {
- parser->current.end = end;
- } else if (quote == PM_HEREDOC_QUOTE_NONE && (width = char_is_identifier(parser, parser->current.end)) == 0) {
- parser->current.end = end;
- } else {
- if (quote == PM_HEREDOC_QUOTE_NONE) {
- parser->current.end += width;
-
- while ((parser->current.end < parser->end) && (width = char_is_identifier(parser, parser->current.end))) {
- parser->current.end += width;
- }
- } else {
- // If we have quotes, then we're going to go until we find the
- // end quote.
- while ((parser->current.end < parser->end) && quote != (pm_heredoc_quote_t) (*parser->current.end)) {
- parser->current.end++;
- }
- }
-
- size_t ident_length = (size_t) (parser->current.end - ident_start);
- if (quote != PM_HEREDOC_QUOTE_NONE && !match(parser, (uint8_t) quote)) {
- // TODO: handle unterminated heredoc
- }
-
- parser->explicit_encoding = NULL;
- lex_mode_push(parser, (pm_lex_mode_t) {
- .mode = PM_LEX_HEREDOC,
- .as.heredoc = {
- .ident_start = ident_start,
- .ident_length = ident_length,
- .next_start = parser->current.end,
- .quote = quote,
- .indent = indent,
- .common_whitespace = (size_t) -1
- }
- });
-
- if (parser->heredoc_end == NULL) {
- const uint8_t *body_start = next_newline(parser->current.end, parser->end - parser->current.end);
-
- if (body_start == NULL) {
- // If there is no newline after the heredoc identifier, then
- // this is not a valid heredoc declaration. In this case we
- // will add an error, but we will still return a heredoc
- // start.
- pm_parser_err_current(parser, PM_ERR_EMBDOC_TERM);
- body_start = parser->end;
- } else {
- // Otherwise, we want to indicate that the body of the
- // heredoc starts on the character after the next newline.
- pm_newline_list_append(&parser->newline_list, body_start);
- body_start++;
- }
-
- parser->next_start = body_start;
- } else {
- parser->next_start = parser->heredoc_end;
- }
-
- LEX(PM_TOKEN_HEREDOC_START);
- }
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_LESS_LESS_EQUAL);
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- if (lex_state_p(parser, PM_LEX_STATE_CLASS)) parser->command_start = true;
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(PM_TOKEN_LESS_LESS);
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- if (lex_state_p(parser, PM_LEX_STATE_CLASS)) parser->command_start = true;
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- if (match(parser, '=')) {
- if (match(parser, '>')) {
- LEX(PM_TOKEN_LESS_EQUAL_GREATER);
- }
-
- LEX(PM_TOKEN_LESS_EQUAL);
- }
-
- LEX(PM_TOKEN_LESS);
-
- // > >> >>= >=
- case '>':
- if (match(parser, '>')) {
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
- LEX(match(parser, '=') ? PM_TOKEN_GREATER_GREATER_EQUAL : PM_TOKEN_GREATER_GREATER);
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(match(parser, '=') ? PM_TOKEN_GREATER_EQUAL : PM_TOKEN_GREATER);
-
- // double-quoted string literal
- case '"': {
- bool label_allowed = (lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser);
- lex_mode_push_string(parser, true, label_allowed, '\0', '"');
- LEX(PM_TOKEN_STRING_BEGIN);
- }
-
- // xstring literal
- case '`': {
- if (lex_state_p(parser, PM_LEX_STATE_FNAME)) {
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- LEX(PM_TOKEN_BACKTICK);
- }
-
- if (lex_state_p(parser, PM_LEX_STATE_DOT)) {
- if (previous_command_start) {
- lex_state_set(parser, PM_LEX_STATE_CMDARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- }
-
- LEX(PM_TOKEN_BACKTICK);
- }
-
- lex_mode_push_string(parser, true, false, '\0', '`');
- LEX(PM_TOKEN_BACKTICK);
- }
-
- // single-quoted string literal
- case '\'': {
- bool label_allowed = (lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser);
- lex_mode_push_string(parser, false, label_allowed, '\0', '\'');
- LEX(PM_TOKEN_STRING_BEGIN);
- }
-
- // ? character literal
- case '?':
- LEX(lex_question_mark(parser));
-
- // & && &&= &=
- case '&': {
- if (match(parser, '&')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
-
- if (match(parser, '=')) {
- LEX(PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
- }
-
- LEX(PM_TOKEN_AMPERSAND_AMPERSAND);
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_AMPERSAND_EQUAL);
- }
-
- if (match(parser, '.')) {
- lex_state_set(parser, PM_LEX_STATE_DOT);
- LEX(PM_TOKEN_AMPERSAND_DOT);
- }
-
- pm_token_type_t type = PM_TOKEN_AMPERSAND;
- if (lex_state_spcarg_p(parser, space_seen) || lex_state_beg_p(parser)) {
- type = PM_TOKEN_UAMPERSAND;
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(type);
- }
-
- // | || ||= |=
- case '|':
- if (match(parser, '|')) {
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PIPE_PIPE_EQUAL);
- }
-
- if (lex_state_p(parser, PM_LEX_STATE_BEG)) {
- parser->current.end--;
- LEX(PM_TOKEN_PIPE);
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PIPE_PIPE);
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PIPE_EQUAL);
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- }
-
- LEX(PM_TOKEN_PIPE);
-
- // + += +@
- case '+': {
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
-
- if (match(parser, '@')) {
- LEX(PM_TOKEN_UPLUS);
- }
-
- LEX(PM_TOKEN_PLUS);
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PLUS_EQUAL);
- }
-
- bool spcarg = lex_state_spcarg_p(parser, space_seen);
- if (spcarg) {
- pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS);
- }
-
- if (lex_state_beg_p(parser) || spcarg) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
-
- if (pm_char_is_decimal_digit(peek(parser))) {
- parser->current.end++;
- pm_token_type_t type = lex_numeric(parser);
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(type);
- }
-
- LEX(PM_TOKEN_UPLUS);
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PLUS);
- }
-
- // - -= -@
- case '-': {
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
-
- if (match(parser, '@')) {
- LEX(PM_TOKEN_UMINUS);
- }
-
- LEX(PM_TOKEN_MINUS);
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_MINUS_EQUAL);
- }
-
- if (match(parser, '>')) {
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- LEX(PM_TOKEN_MINUS_GREATER);
- }
-
- bool spcarg = lex_state_spcarg_p(parser, space_seen);
- if (spcarg) {
- pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS);
- }
-
- if (lex_state_beg_p(parser) || spcarg) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(pm_char_is_decimal_digit(peek(parser)) ? PM_TOKEN_UMINUS_NUM : PM_TOKEN_UMINUS);
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_MINUS);
- }
-
- // . .. ...
- case '.': {
- bool beg_p = lex_state_beg_p(parser);
-
- if (match(parser, '.')) {
- if (match(parser, '.')) {
- // If we're _not_ inside a range within default parameters
- if (
- !context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) &&
- context_p(parser, PM_CONTEXT_DEF_PARAMS)
- ) {
- if (lex_state_p(parser, PM_LEX_STATE_END)) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_ENDARG);
- }
- LEX(PM_TOKEN_UDOT_DOT_DOT);
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(beg_p ? PM_TOKEN_UDOT_DOT_DOT : PM_TOKEN_DOT_DOT_DOT);
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(beg_p ? PM_TOKEN_UDOT_DOT : PM_TOKEN_DOT_DOT);
- }
-
- lex_state_set(parser, PM_LEX_STATE_DOT);
- LEX(PM_TOKEN_DOT);
- }
-
- // integer
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- pm_token_type_t type = lex_numeric(parser);
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(type);
- }
-
- // :: symbol
- case ':':
- if (match(parser, ':')) {
- if (lex_state_beg_p(parser) || lex_state_p(parser, PM_LEX_STATE_CLASS) || (lex_state_p(parser, PM_LEX_STATE_ARG_ANY) && space_seen)) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_UCOLON_COLON);
- }
-
- lex_state_set(parser, PM_LEX_STATE_DOT);
- LEX(PM_TOKEN_COLON_COLON);
- }
-
- if (lex_state_end_p(parser) || pm_char_is_whitespace(peek(parser)) || peek(parser) == '#') {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_COLON);
- }
-
- if (peek(parser) == '"' || peek(parser) == '\'') {
- lex_mode_push_string(parser, peek(parser) == '"', false, '\0', *parser->current.end);
- parser->current.end++;
- }
-
- lex_state_set(parser, PM_LEX_STATE_FNAME);
- LEX(PM_TOKEN_SYMBOL_BEGIN);
-
- // / /=
- case '/':
- if (lex_state_beg_p(parser)) {
- lex_mode_push_regexp(parser, '\0', '/');
- LEX(PM_TOKEN_REGEXP_BEGIN);
- }
-
- if (match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_SLASH_EQUAL);
- }
-
- if (lex_state_spcarg_p(parser, space_seen)) {
- pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_SLASH);
- lex_mode_push_regexp(parser, '\0', '/');
- LEX(PM_TOKEN_REGEXP_BEGIN);
- }
-
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(PM_TOKEN_SLASH);
-
- // ^ ^=
- case '^':
- if (lex_state_operator_p(parser)) {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
- LEX(match(parser, '=') ? PM_TOKEN_CARET_EQUAL : PM_TOKEN_CARET);
-
- // ~ ~@
- case '~':
- if (lex_state_operator_p(parser)) {
- (void) match(parser, '@');
- lex_state_set(parser, PM_LEX_STATE_ARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- }
-
- LEX(PM_TOKEN_TILDE);
-
- // % %= %i %I %q %Q %w %W
- case '%': {
- // If there is no subsequent character then we have an
- // invalid token. We're going to say it's the percent
- // operator because we don't want to move into the string
- // lex mode unnecessarily.
- if ((lex_state_beg_p(parser) || lex_state_arg_p(parser)) && (parser->current.end >= parser->end)) {
- pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
- LEX(PM_TOKEN_PERCENT);
- }
-
- if (!lex_state_beg_p(parser) && match(parser, '=')) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PERCENT_EQUAL);
- } else if (
- lex_state_beg_p(parser) ||
- (lex_state_p(parser, PM_LEX_STATE_FITEM) && (peek(parser) == 's')) ||
- lex_state_spcarg_p(parser, space_seen)
- ) {
- if (!parser->encoding->alnum_char(parser->current.end, parser->end - parser->current.end)) {
- if (*parser->current.end >= 0x80) {
- pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
- }
-
- lex_mode_push_string(parser, true, false, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
-
- size_t eol_length = match_eol(parser);
- if (eol_length) {
- parser->current.end += eol_length;
- pm_newline_list_append(&parser->newline_list, parser->current.end - 1);
- } else {
- parser->current.end++;
- }
-
- if (parser->current.end < parser->end) {
- LEX(PM_TOKEN_STRING_BEGIN);
- }
- }
-
- // Delimiters for %-literals cannot be alphanumeric. We
- // validate that here.
- uint8_t delimiter = peek_offset(parser, 1);
- if (delimiter >= 0x80 || parser->encoding->alnum_char(&delimiter, 1)) {
- pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
- goto lex_next_token;
- }
-
- switch (peek(parser)) {
- case 'i': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_list(parser, false, *parser->current.end++);
- } else {
- lex_mode_push_list_eof(parser);
- }
-
- LEX(PM_TOKEN_PERCENT_LOWER_I);
- }
- case 'I': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_list(parser, true, *parser->current.end++);
- } else {
- lex_mode_push_list_eof(parser);
- }
-
- LEX(PM_TOKEN_PERCENT_UPPER_I);
- }
- case 'r': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_regexp(parser, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
- pm_newline_list_check_append(&parser->newline_list, parser->current.end);
- parser->current.end++;
- } else {
- lex_mode_push_regexp(parser, '\0', '\0');
- }
-
- LEX(PM_TOKEN_REGEXP_BEGIN);
- }
- case 'q': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_string(parser, false, false, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
- pm_newline_list_check_append(&parser->newline_list, parser->current.end);
- parser->current.end++;
- } else {
- lex_mode_push_string_eof(parser);
- }
-
- LEX(PM_TOKEN_STRING_BEGIN);
- }
- case 'Q': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_string(parser, true, false, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
- pm_newline_list_check_append(&parser->newline_list, parser->current.end);
- parser->current.end++;
- } else {
- lex_mode_push_string_eof(parser);
- }
-
- LEX(PM_TOKEN_STRING_BEGIN);
- }
- case 's': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_string(parser, false, false, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
- lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM);
- parser->current.end++;
- } else {
- lex_mode_push_string_eof(parser);
- }
-
- LEX(PM_TOKEN_SYMBOL_BEGIN);
- }
- case 'w': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_list(parser, false, *parser->current.end++);
- } else {
- lex_mode_push_list_eof(parser);
- }
-
- LEX(PM_TOKEN_PERCENT_LOWER_W);
- }
- case 'W': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_list(parser, true, *parser->current.end++);
- } else {
- lex_mode_push_list_eof(parser);
- }
-
- LEX(PM_TOKEN_PERCENT_UPPER_W);
- }
- case 'x': {
- parser->current.end++;
-
- if (parser->current.end < parser->end) {
- lex_mode_push_string(parser, true, false, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
- parser->current.end++;
- } else {
- lex_mode_push_string_eof(parser);
- }
-
- LEX(PM_TOKEN_PERCENT_LOWER_X);
- }
- default:
- // If we get to this point, then we have a % that is completely
- // unparseable. In this case we'll just drop it from the parser
- // and skip past it and hope that the next token is something
- // that we can parse.
- pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
- goto lex_next_token;
- }
- }
-
- lex_state_set(parser, lex_state_operator_p(parser) ? PM_LEX_STATE_ARG : PM_LEX_STATE_BEG);
- LEX(PM_TOKEN_PERCENT);
- }
-
- // global variable
- case '$': {
- pm_token_type_t type = lex_global_variable(parser);
-
- // If we're lexing an embedded variable, then we need to pop back into
- // the parent lex context.
- if (parser->lex_modes.current->mode == PM_LEX_EMBVAR) {
- lex_mode_pop(parser);
- }
-
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(type);
- }
-
- // instance variable, class variable
- case '@':
- lex_state_set(parser, parser->lex_state & PM_LEX_STATE_FNAME ? PM_LEX_STATE_ENDFN : PM_LEX_STATE_END);
- LEX(lex_at_variable(parser));
-
- default: {
- if (*parser->current.start != '_') {
- size_t width = char_is_identifier_start(parser, parser->current.start);
-
- // If this isn't the beginning of an identifier, then it's an invalid
- // token as we've exhausted all of the other options. We'll skip past
- // it and return the next token.
- if (!width) {
- pm_parser_err_current(parser, PM_ERR_INVALID_TOKEN);
- goto lex_next_token;
- }
-
- parser->current.end = parser->current.start + width;
- }
-
- pm_token_type_t type = lex_identifier(parser, previous_command_start);
-
- // If we've hit a __END__ and it was at the start of the line or the
- // start of the file and it is followed by either a \n or a \r\n, then
- // this is the last token of the file.
- if (
- ((parser->current.end - parser->current.start) == 7) &&
- current_token_starts_line(parser) &&
- (memcmp(parser->current.start, "__END__", 7) == 0) &&
- (parser->current.end == parser->end || match_eol(parser))
- )
- {
- // Since we know we're about to add an __END__ comment, we know we
- // need at add all of the newlines to get the correct column
- // information for it.
- const uint8_t *cursor = parser->current.end;
- while ((cursor = next_newline(cursor, parser->end - cursor)) != NULL) {
- pm_newline_list_append(&parser->newline_list, cursor++);
- }
-
- parser->current.end = parser->end;
- parser->current.type = PM_TOKEN___END__;
- parser_lex_callback(parser);
-
- parser->data_loc.start = parser->current.start;
- parser->data_loc.end = parser->current.end;
-
- LEX(PM_TOKEN_EOF);
- }
-
- pm_lex_state_t last_state = parser->lex_state;
-
- if (type == PM_TOKEN_IDENTIFIER || type == PM_TOKEN_CONSTANT || type == PM_TOKEN_METHOD_NAME) {
- if (lex_state_p(parser, PM_LEX_STATE_BEG_ANY | PM_LEX_STATE_ARG_ANY | PM_LEX_STATE_DOT)) {
- if (previous_command_start) {
- lex_state_set(parser, PM_LEX_STATE_CMDARG);
- } else {
- lex_state_set(parser, PM_LEX_STATE_ARG);
- }
- } else if (parser->lex_state == PM_LEX_STATE_FNAME) {
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- } else {
- lex_state_set(parser, PM_LEX_STATE_END);
- }
- }
-
- if (
- !(last_state & (PM_LEX_STATE_DOT | PM_LEX_STATE_FNAME)) &&
- (type == PM_TOKEN_IDENTIFIER) &&
- ((pm_parser_local_depth(parser, &parser->current) != -1) ||
- pm_token_is_numbered_parameter(parser->current.start, parser->current.end))
- ) {
- lex_state_set(parser, PM_LEX_STATE_END | PM_LEX_STATE_LABEL);
- }
-
- LEX(type);
- }
- }
- }
- case PM_LEX_LIST: {
- if (parser->next_start != NULL) {
- parser->current.end = parser->next_start;
- parser->next_start = NULL;
- }
-
- // First we'll set the beginning of the token.
- parser->current.start = parser->current.end;
-
- // If there's any whitespace at the start of the list, then we're
- // going to trim it off the beginning and create a new token.
- size_t whitespace;
-
- if (parser->heredoc_end) {
- whitespace = pm_strspn_inline_whitespace(parser->current.end, parser->end - parser->current.end);
- if (peek_offset(parser, (ptrdiff_t)whitespace) == '\n') {
- whitespace += 1;
- }
- } else {
- whitespace = pm_strspn_whitespace_newlines(parser->current.end, parser->end - parser->current.end, &parser->newline_list);
- }
-
- if (whitespace > 0) {
- parser->current.end += whitespace;
- if (peek_offset(parser, -1) == '\n') {
- // mutates next_start
- parser_flush_heredoc_end(parser);
- }
- LEX(PM_TOKEN_WORDS_SEP);
- }
-
- // We'll check if we're at the end of the file. If we are, then we
- // need to return the EOF token.
- if (parser->current.end >= parser->end) {
- LEX(PM_TOKEN_EOF);
- }
-
- // Here we'll get a list of the places where strpbrk should break,
- // and then find the first one.
- pm_lex_mode_t *lex_mode = parser->lex_modes.current;
- const uint8_t *breakpoints = lex_mode->as.list.breakpoints;
- const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
-
- // If we haven't found an escape yet, then this buffer will be
- // unallocated since we can refer directly to the source string.
- pm_token_buffer_t token_buffer = { { 0 }, 0 };
-
- while (breakpoint != NULL) {
- // If we hit a null byte, skip directly past it.
- if (*breakpoint == '\0') {
- breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1));
- continue;
- }
-
- // If we hit whitespace, then we must have received content by
- // now, so we can return an element of the list.
- if (pm_char_is_whitespace(*breakpoint)) {
- parser->current.end = breakpoint;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // If we hit the terminator, we need to check which token to
- // return.
- if (*breakpoint == lex_mode->as.list.terminator) {
- // If this terminator doesn't actually close the list, then
- // we need to continue on past it.
- if (lex_mode->as.list.nesting > 0) {
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- lex_mode->as.list.nesting--;
- continue;
- }
-
- // If we've hit the terminator and we've already skipped
- // past content, then we can return a list node.
- if (breakpoint > parser->current.start) {
- parser->current.end = breakpoint;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // Otherwise, switch back to the default state and return
- // the end of the list.
- parser->current.end = breakpoint + 1;
- lex_mode_pop(parser);
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(PM_TOKEN_STRING_END);
- }
-
- // If we hit escapes, then we need to treat the next token
- // literally. In this case we'll skip past the next character
- // and find the next breakpoint.
- if (*breakpoint == '\\') {
- parser->current.end = breakpoint + 1;
-
- // If we've hit the end of the file, then break out of the
- // loop by setting the breakpoint to NULL.
- if (parser->current.end == parser->end) {
- breakpoint = NULL;
- continue;
- }
-
- pm_token_buffer_escape(parser, &token_buffer);
- uint8_t peeked = peek(parser);
-
- switch (peeked) {
- case ' ':
- case '\f':
- case '\t':
- case '\v':
- case '\\':
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- break;
- case '\r':
- parser->current.end++;
- if (peek(parser) != '\n') {
- pm_token_buffer_push(&token_buffer, '\r');
- break;
- }
- /* fallthrough */
- case '\n':
- pm_token_buffer_push(&token_buffer, '\n');
-
- if (parser->heredoc_end) {
- // ... if we are on the same line as a heredoc,
- // flush the heredoc and continue parsing after
- // heredoc_end.
- parser_flush_heredoc_end(parser);
- pm_token_buffer_copy(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- } else {
- // ... else track the newline.
- pm_newline_list_append(&parser->newline_list, parser->current.end);
- }
-
- parser->current.end++;
- break;
- default:
- if (peeked == lex_mode->as.list.incrementor || peeked == lex_mode->as.list.terminator) {
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- } else if (lex_mode->as.list.interpolation) {
- escape_read(parser, &token_buffer.buffer, PM_ESCAPE_FLAG_NONE);
- } else {
- pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- }
-
- break;
- }
-
- token_buffer.cursor = parser->current.end;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
-
- // If we hit a #, then we will attempt to lex interpolation.
- if (*breakpoint == '#') {
- pm_token_type_t type = lex_interpolation(parser, breakpoint);
-
- if (type == PM_TOKEN_NOT_PROVIDED) {
- // If we haven't returned at this point then we had something
- // that looked like an interpolated class or instance variable
- // like "#@" but wasn't actually. In this case we'll just skip
- // to the next breakpoint.
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
-
- if (type == PM_TOKEN_STRING_CONTENT) {
- pm_token_buffer_flush(parser, &token_buffer);
- }
-
- LEX(type);
- }
-
- // If we've hit the incrementor, then we need to skip past it
- // and find the next breakpoint.
- assert(*breakpoint == lex_mode->as.list.incrementor);
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- lex_mode->as.list.nesting++;
- continue;
- }
-
- if (parser->current.end > parser->current.start) {
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // If we were unable to find a breakpoint, then this token hits the
- // end of the file.
- parser->current.end = parser->end;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- case PM_LEX_REGEXP: {
- // First, we'll set to start of this token to be the current end.
- if (parser->next_start == NULL) {
- parser->current.start = parser->current.end;
- } else {
- parser->current.start = parser->next_start;
- parser->current.end = parser->next_start;
- parser->next_start = NULL;
- }
-
- // We'll check if we're at the end of the file. If we are, then we need to
- // return the EOF token.
- if (parser->current.end >= parser->end) {
- LEX(PM_TOKEN_EOF);
- }
-
- // Get a reference to the current mode.
- pm_lex_mode_t *lex_mode = parser->lex_modes.current;
-
- // These are the places where we need to split up the content of the
- // regular expression. We'll use strpbrk to find the first of these
- // characters.
- const uint8_t *breakpoints = lex_mode->as.regexp.breakpoints;
- const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- pm_token_buffer_t token_buffer = { { 0 }, 0 };
-
- while (breakpoint != NULL) {
- // If we hit a null byte, skip directly past it.
- if (*breakpoint == '\0') {
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
-
- // If we've hit a newline, then we need to track that in the
- // list of newlines.
- if (*breakpoint == '\n') {
- // For the special case of a newline-terminated regular expression, we will pass
- // through this branch twice -- once with PM_TOKEN_REGEXP_BEGIN and then again
- // with PM_TOKEN_STRING_CONTENT. Let's avoid tracking the newline twice, by
- // tracking it only in the REGEXP_BEGIN case.
- if (
- !(lex_mode->as.regexp.terminator == '\n' && parser->current.type != PM_TOKEN_REGEXP_BEGIN)
- && parser->heredoc_end == NULL
- ) {
- pm_newline_list_append(&parser->newline_list, breakpoint);
- }
-
- if (lex_mode->as.regexp.terminator != '\n') {
- // If the terminator is not a newline, then we can set
- // the next breakpoint and continue.
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
- }
-
- // If we hit the terminator, we need to determine what kind of
- // token to return.
- if (*breakpoint == lex_mode->as.regexp.terminator) {
- if (lex_mode->as.regexp.nesting > 0) {
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- lex_mode->as.regexp.nesting--;
- continue;
- }
-
- // Here we've hit the terminator. If we have already consumed
- // content then we need to return that content as string content
- // first.
- if (breakpoint > parser->current.start) {
- parser->current.end = breakpoint;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // Since we've hit the terminator of the regular expression,
- // we now need to parse the options.
- parser->current.end = breakpoint + 1;
- parser->current.end += pm_strspn_regexp_option(parser->current.end, parser->end - parser->current.end);
-
- lex_mode_pop(parser);
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(PM_TOKEN_REGEXP_END);
- }
-
- // If we hit escapes, then we need to treat the next token
- // literally. In this case we'll skip past the next character
- // and find the next breakpoint.
- if (*breakpoint == '\\') {
- parser->current.end = breakpoint + 1;
-
- // If we've hit the end of the file, then break out of the
- // loop by setting the breakpoint to NULL.
- if (parser->current.end == parser->end) {
- breakpoint = NULL;
- continue;
- }
-
- pm_token_buffer_escape(parser, &token_buffer);
- uint8_t peeked = peek(parser);
-
- switch (peeked) {
- case '\r':
- parser->current.end++;
- if (peek(parser) != '\n') {
- if (lex_mode->as.regexp.terminator != '\r') {
- pm_token_buffer_push(&token_buffer, '\\');
- }
- pm_token_buffer_push(&token_buffer, '\r');
- break;
- }
- /* fallthrough */
- case '\n':
- if (parser->heredoc_end) {
- // ... if we are on the same line as a heredoc,
- // flush the heredoc and continue parsing after
- // heredoc_end.
- parser_flush_heredoc_end(parser);
- pm_token_buffer_copy(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- } else {
- // ... else track the newline.
- pm_newline_list_append(&parser->newline_list, parser->current.end);
- }
-
- parser->current.end++;
- break;
- case 'c':
- case 'C':
- case 'M':
- case 'u':
- case 'x':
- escape_read(parser, &token_buffer.buffer, PM_ESCAPE_FLAG_REGEXP);
- break;
- default:
- if (lex_mode->as.regexp.terminator == peeked) {
- // Some characters when they are used as the
- // terminator also receive an escape. They are
- // enumerated here.
- switch (peeked) {
- case '$': case ')': case '*': case '+':
- case '.': case '>': case '?': case ']':
- case '^': case '|': case '}':
- pm_token_buffer_push(&token_buffer, '\\');
- break;
- default:
- break;
- }
-
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- break;
- }
-
- if (peeked < 0x80) pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- break;
- }
-
- token_buffer.cursor = parser->current.end;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
-
- // If we hit a #, then we will attempt to lex interpolation.
- if (*breakpoint == '#') {
- pm_token_type_t type = lex_interpolation(parser, breakpoint);
-
- if (type == PM_TOKEN_NOT_PROVIDED) {
- // If we haven't returned at this point then we had
- // something that looked like an interpolated class or
- // instance variable like "#@" but wasn't actually. In
- // this case we'll just skip to the next breakpoint.
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
-
- if (type == PM_TOKEN_STRING_CONTENT) {
- pm_token_buffer_flush(parser, &token_buffer);
- }
-
- LEX(type);
- }
-
- // If we've hit the incrementor, then we need to skip past it
- // and find the next breakpoint.
- assert(*breakpoint == lex_mode->as.regexp.incrementor);
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- lex_mode->as.regexp.nesting++;
- continue;
- }
-
- if (parser->current.end > parser->current.start) {
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // If we were unable to find a breakpoint, then this token hits the
- // end of the file.
- parser->current.end = parser->end;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- case PM_LEX_STRING: {
- // First, we'll set to start of this token to be the current end.
- if (parser->next_start == NULL) {
- parser->current.start = parser->current.end;
- } else {
- parser->current.start = parser->next_start;
- parser->current.end = parser->next_start;
- parser->next_start = NULL;
- }
-
- // We'll check if we're at the end of the file. If we are, then we need to
- // return the EOF token.
- if (parser->current.end >= parser->end) {
- LEX(PM_TOKEN_EOF);
- }
-
- // These are the places where we need to split up the content of the
- // string. We'll use strpbrk to find the first of these characters.
- pm_lex_mode_t *lex_mode = parser->lex_modes.current;
- const uint8_t *breakpoints = lex_mode->as.string.breakpoints;
- const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
-
- // If we haven't found an escape yet, then this buffer will be
- // unallocated since we can refer directly to the source string.
- pm_token_buffer_t token_buffer = { { 0 }, 0 };
-
- while (breakpoint != NULL) {
- // If we hit the incrementor, then we'll increment then nesting and
- // continue lexing.
- if (lex_mode->as.string.incrementor != '\0' && *breakpoint == lex_mode->as.string.incrementor) {
- lex_mode->as.string.nesting++;
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- }
-
- // Note that we have to check the terminator here first because we could
- // potentially be parsing a % string that has a # character as the
- // terminator.
- if (*breakpoint == lex_mode->as.string.terminator) {
- // If this terminator doesn't actually close the string, then we need
- // to continue on past it.
- if (lex_mode->as.string.nesting > 0) {
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- lex_mode->as.string.nesting--;
- continue;
- }
-
- // Here we've hit the terminator. If we have already consumed content
- // then we need to return that content as string content first.
- if (breakpoint > parser->current.start) {
- parser->current.end = breakpoint;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // Otherwise we need to switch back to the parent lex mode and
- // return the end of the string.
- size_t eol_length = match_eol_at(parser, breakpoint);
- if (eol_length) {
- parser->current.end = breakpoint + eol_length;
- pm_newline_list_append(&parser->newline_list, parser->current.end - 1);
- } else {
- parser->current.end = breakpoint + 1;
- }
-
- if (lex_mode->as.string.label_allowed && (peek(parser) == ':') && (peek_offset(parser, 1) != ':')) {
- parser->current.end++;
- lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED);
- lex_mode_pop(parser);
- LEX(PM_TOKEN_LABEL_END);
- }
-
- lex_state_set(parser, PM_LEX_STATE_END);
- lex_mode_pop(parser);
- LEX(PM_TOKEN_STRING_END);
- }
-
- // When we hit a newline, we need to flush any potential heredocs. Note
- // that this has to happen after we check for the terminator in case the
- // terminator is a newline character.
- if (*breakpoint == '\n') {
- if (parser->heredoc_end == NULL) {
- pm_newline_list_append(&parser->newline_list, breakpoint);
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- continue;
- } else {
- parser->current.end = breakpoint + 1;
- parser_flush_heredoc_end(parser);
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- }
-
- switch (*breakpoint) {
- case '\0':
- // Skip directly past the null character.
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- case '\\': {
- // Here we hit escapes.
- parser->current.end = breakpoint + 1;
-
- // If we've hit the end of the file, then break out of
- // the loop by setting the breakpoint to NULL.
- if (parser->current.end == parser->end) {
- breakpoint = NULL;
- continue;
- }
-
- pm_token_buffer_escape(parser, &token_buffer);
- uint8_t peeked = peek(parser);
-
- switch (peeked) {
- case '\\':
- pm_token_buffer_push(&token_buffer, '\\');
- parser->current.end++;
- break;
- case '\r':
- parser->current.end++;
- if (peek(parser) != '\n') {
- if (!lex_mode->as.string.interpolation) {
- pm_token_buffer_push(&token_buffer, '\\');
- }
- pm_token_buffer_push(&token_buffer, '\r');
- break;
- }
- /* fallthrough */
- case '\n':
- if (!lex_mode->as.string.interpolation) {
- pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, '\n');
- }
-
- if (parser->heredoc_end) {
- // ... if we are on the same line as a heredoc,
- // flush the heredoc and continue parsing after
- // heredoc_end.
- parser_flush_heredoc_end(parser);
- pm_token_buffer_copy(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- } else {
- // ... else track the newline.
- pm_newline_list_append(&parser->newline_list, parser->current.end);
- }
-
- parser->current.end++;
- break;
- default:
- if (lex_mode->as.string.incrementor != '\0' && peeked == lex_mode->as.string.incrementor) {
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- } else if (lex_mode->as.string.terminator != '\0' && peeked == lex_mode->as.string.terminator) {
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- } else if (lex_mode->as.string.interpolation) {
- escape_read(parser, &token_buffer.buffer, PM_ESCAPE_FLAG_NONE);
- } else {
- pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, peeked);
- parser->current.end++;
- }
-
- break;
- }
-
- token_buffer.cursor = parser->current.end;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- }
- case '#': {
- pm_token_type_t type = lex_interpolation(parser, breakpoint);
-
- if (type == PM_TOKEN_NOT_PROVIDED) {
- // If we haven't returned at this point then we had something that
- // looked like an interpolated class or instance variable like "#@"
- // but wasn't actually. In this case we'll just skip to the next
- // breakpoint.
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- }
-
- if (type == PM_TOKEN_STRING_CONTENT) {
- pm_token_buffer_flush(parser, &token_buffer);
- }
-
- LEX(type);
- }
- default:
- assert(false && "unreachable");
- }
- }
-
- if (parser->current.end > parser->current.start) {
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // If we've hit the end of the string, then this is an unterminated
- // string. In that case we'll return a string content token.
- parser->current.end = parser->end;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- case PM_LEX_HEREDOC: {
- // First, we'll set to start of this token.
- if (parser->next_start == NULL) {
- parser->current.start = parser->current.end;
- } else {
- parser->current.start = parser->next_start;
- parser->current.end = parser->next_start;
- parser->heredoc_end = NULL;
- parser->next_start = NULL;
- }
-
- // We'll check if we're at the end of the file. If we are, then we need to
- // return the EOF token.
- if (parser->current.end >= parser->end) {
- LEX(PM_TOKEN_EOF);
- }
-
- // Now let's grab the information about the identifier off of the current
- // lex mode.
- pm_lex_mode_t *lex_mode = parser->lex_modes.current;
- const uint8_t *ident_start = lex_mode->as.heredoc.ident_start;
- size_t ident_length = lex_mode->as.heredoc.ident_length;
-
- // If we are immediately following a newline and we have hit the
- // terminator, then we need to return the ending of the heredoc.
- if (current_token_starts_line(parser)) {
- const uint8_t *start = parser->current.start;
- if (start + ident_length <= parser->end) {
- const uint8_t *newline = next_newline(start, parser->end - start);
- const uint8_t *ident_end = newline;
- const uint8_t *terminator_end = newline;
-
- if (newline == NULL) {
- terminator_end = parser->end;
- ident_end = parser->end;
- } else {
- terminator_end++;
- if (newline[-1] == '\r') {
- ident_end--; // Remove \r
- }
- }
-
- const uint8_t *terminator_start = ident_end - ident_length;
- const uint8_t *cursor = start;
-
- if (
- lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_DASH ||
- lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE
- ) {
- while (cursor < terminator_start && pm_char_is_inline_whitespace(*cursor)) {
- cursor++;
- }
- }
-
- if (
- (cursor == terminator_start) &&
- (memcmp(terminator_start, ident_start, ident_length) == 0)
- ) {
- if (newline != NULL) {
- pm_newline_list_append(&parser->newline_list, newline);
- }
-
- parser->current.end = terminator_end;
- if (*lex_mode->as.heredoc.next_start == '\\') {
- parser->next_start = NULL;
- } else {
- parser->next_start = lex_mode->as.heredoc.next_start;
- parser->heredoc_end = parser->current.end;
- }
-
- lex_state_set(parser, PM_LEX_STATE_END);
- LEX(PM_TOKEN_HEREDOC_END);
- }
- }
-
- size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, lex_mode->as.heredoc.indent);
- if (
- lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE &&
- (lex_mode->as.heredoc.common_whitespace > whitespace) &&
- peek_at(parser, start) != '\n'
- ) {
- lex_mode->as.heredoc.common_whitespace = whitespace;
- }
- }
-
- // Otherwise we'll be parsing string content. These are the places
- // where we need to split up the content of the heredoc. We'll use
- // strpbrk to find the first of these characters.
- uint8_t breakpoints[] = "\n\\#";
-
- pm_heredoc_quote_t quote = lex_mode->as.heredoc.quote;
- if (quote == PM_HEREDOC_QUOTE_SINGLE) {
- breakpoints[2] = '\0';
- }
-
- const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- pm_token_buffer_t token_buffer = { { 0 }, 0 };
- bool was_escaped_newline = false;
-
- while (breakpoint != NULL) {
- switch (*breakpoint) {
- case '\0':
- // Skip directly past the null character.
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- case '\n': {
- if (parser->heredoc_end != NULL && (parser->heredoc_end > breakpoint)) {
- parser_flush_heredoc_end(parser);
- parser->current.end = breakpoint + 1;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- pm_newline_list_append(&parser->newline_list, breakpoint);
-
- // If we have a - or ~ heredoc, then we can match after
- // some leading whitespace.
- const uint8_t *start = breakpoint + 1;
-
- if (!was_escaped_newline && (start + ident_length <= parser->end)) {
- // We want to match the terminator starting from the end of the line in case
- // there is whitespace in the ident such as <<-' DOC' or <<~' DOC'.
- const uint8_t *newline = next_newline(start, parser->end - start);
-
- if (newline == NULL) {
- newline = parser->end;
- } else if (newline[-1] == '\r') {
- newline--; // Remove \r
- }
-
- // Start of a possible terminator.
- const uint8_t *terminator_start = newline - ident_length;
-
- // Cursor to check for the leading whitespace. We skip the
- // leading whitespace if we have a - or ~ heredoc.
- const uint8_t *cursor = start;
-
- if (lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_DASH ||
- lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) {
- while (cursor < terminator_start && pm_char_is_inline_whitespace(*cursor)) {
- cursor++;
- }
- }
-
- if (
- cursor == terminator_start &&
- (memcmp(terminator_start, ident_start, ident_length) == 0)
- ) {
- parser->current.end = breakpoint + 1;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- }
-
- size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, lex_mode->as.heredoc.indent);
-
- // If we have hit a newline that is followed by a valid
- // terminator, then we need to return the content of the
- // heredoc here as string content. Then, the next time a
- // token is lexed, it will match again and return the
- // end of the heredoc.
-
- if (lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) {
- if ((lex_mode->as.heredoc.common_whitespace > whitespace) && peek_at(parser, start) != '\n') {
- lex_mode->as.heredoc.common_whitespace = whitespace;
- }
-
- parser->current.end = breakpoint + 1;
-
- if (!was_escaped_newline) {
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- }
-
- // Otherwise we hit a newline and it wasn't followed by
- // a terminator, so we can continue parsing.
- parser->current.end = breakpoint + 1;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- }
- case '\\': {
- // If we hit an escape, then we need to skip past
- // however many characters the escape takes up. However
- // it's important that if \n or \r\n are escaped that we
- // stop looping before the newline and not after the
- // newline so that we can still potentially find the
- // terminator of the heredoc.
- parser->current.end = breakpoint + 1;
-
- // If we've hit the end of the file, then break out of
- // the loop by setting the breakpoint to NULL.
- if (parser->current.end == parser->end) {
- breakpoint = NULL;
- continue;
- }
-
- pm_token_buffer_escape(parser, &token_buffer);
- uint8_t peeked = peek(parser);
-
- if (quote == PM_HEREDOC_QUOTE_SINGLE) {
- switch (peeked) {
- case '\r':
- parser->current.end++;
- if (peek(parser) != '\n') {
- pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, '\r');
- break;
- }
- /* fallthrough */
- case '\n':
- pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, '\n');
- token_buffer.cursor = parser->current.end + 1;
- breakpoint = parser->current.end;
- continue;
- default:
- parser->current.end++;
- pm_token_buffer_push(&token_buffer, '\\');
- pm_token_buffer_push(&token_buffer, peeked);
- break;
- }
- } else {
- switch (peeked) {
- case '\r':
- parser->current.end++;
- if (peek(parser) != '\n') {
- pm_token_buffer_push(&token_buffer, '\r');
- break;
- }
- /* fallthrough */
- case '\n':
- was_escaped_newline = true;
- token_buffer.cursor = parser->current.end + 1;
- breakpoint = parser->current.end;
- continue;
- default:
- escape_read(parser, &token_buffer.buffer, PM_ESCAPE_FLAG_NONE);
- break;
- }
- }
-
- token_buffer.cursor = parser->current.end;
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- }
- case '#': {
- pm_token_type_t type = lex_interpolation(parser, breakpoint);
-
- if (type == PM_TOKEN_NOT_PROVIDED) {
- // If we haven't returned at this point then we had
- // something that looked like an interpolated class
- // or instance variable like "#@" but wasn't
- // actually. In this case we'll just skip to the
- // next breakpoint.
- breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
- break;
- }
-
- if (type == PM_TOKEN_STRING_CONTENT) {
- pm_token_buffer_flush(parser, &token_buffer);
- }
-
- LEX(type);
- }
- default:
- assert(false && "unreachable");
- }
-
- was_escaped_newline = false;
- }
-
- if (parser->current.end > parser->current.start) {
- parser->current.end = parser->end;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
-
- // If we've hit the end of the string, then this is an unterminated
- // heredoc. In that case we'll return a string content token.
- parser->current.end = parser->end;
- pm_token_buffer_flush(parser, &token_buffer);
- LEX(PM_TOKEN_STRING_CONTENT);
- }
- }
-
- assert(false && "unreachable");
-}
-
-#undef LEX
-
-/******************************************************************************/
-/* Parse functions */
-/******************************************************************************/
-
-/**
- * These are the various precedence rules. Because we are using a Pratt parser,
- * they are named binding power to represent the manner in which nodes are bound
- * together in the stack.
- *
- * We increment by 2 because we want to leave room for the infix operators to
- * specify their associativity by adding or subtracting one.
- */
-typedef enum {
- PM_BINDING_POWER_UNSET = 0, // used to indicate this token cannot be used as an infix operator
- PM_BINDING_POWER_STATEMENT = 2,
- PM_BINDING_POWER_MODIFIER = 4, // if unless until while
- PM_BINDING_POWER_MODIFIER_RESCUE = 6, // rescue
- PM_BINDING_POWER_COMPOSITION = 8, // and or
- PM_BINDING_POWER_NOT = 10, // not
- PM_BINDING_POWER_MATCH = 12, // => in
- PM_BINDING_POWER_DEFINED = 14, // defined?
- PM_BINDING_POWER_MULTI_ASSIGNMENT = 16, // =
- PM_BINDING_POWER_ASSIGNMENT = 18, // = += -= *= /= %= &= |= ^= &&= ||= <<= >>= **=
- PM_BINDING_POWER_TERNARY = 20, // ?:
- PM_BINDING_POWER_RANGE = 22, // .. ...
- PM_BINDING_POWER_LOGICAL_OR = 24, // ||
- PM_BINDING_POWER_LOGICAL_AND = 26, // &&
- PM_BINDING_POWER_EQUALITY = 28, // <=> == === != =~ !~
- PM_BINDING_POWER_COMPARISON = 30, // > >= < <=
- PM_BINDING_POWER_BITWISE_OR = 32, // | ^
- PM_BINDING_POWER_BITWISE_AND = 34, // &
- PM_BINDING_POWER_SHIFT = 36, // << >>
- PM_BINDING_POWER_TERM = 38, // + -
- PM_BINDING_POWER_FACTOR = 40, // * / %
- PM_BINDING_POWER_UMINUS = 42, // -@
- PM_BINDING_POWER_EXPONENT = 44, // **
- PM_BINDING_POWER_UNARY = 46, // ! ~ +@
- PM_BINDING_POWER_INDEX = 48, // [] []=
- PM_BINDING_POWER_CALL = 50, // :: .
- PM_BINDING_POWER_MAX = 52
-} pm_binding_power_t;
-
-/**
- * This struct represents a set of binding powers used for a given token. They
- * are combined in this way to make it easier to represent associativity.
- */
-typedef struct {
- /** The left binding power. */
- pm_binding_power_t left;
-
- /** The right binding power. */
- pm_binding_power_t right;
-
- /** Whether or not this token can be used as a binary operator. */
- bool binary;
-
- /**
- * Whether or not this token can be used as non-associative binary operator.
- * Non-associative operators (e.g. in and =>) need special treatment in parse_expression.
- */
- bool nonassoc;
-} pm_binding_powers_t;
-
-#define BINDING_POWER_ASSIGNMENT { PM_BINDING_POWER_UNARY, PM_BINDING_POWER_ASSIGNMENT, true, false }
-#define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, false }
-#define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true, false }
-#define NON_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, true }
-#define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false, false }
-
-pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = {
- // if unless until while
- [PM_TOKEN_KEYWORD_IF_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
- [PM_TOKEN_KEYWORD_UNLESS_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
- [PM_TOKEN_KEYWORD_UNTIL_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
- [PM_TOKEN_KEYWORD_WHILE_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
-
- // rescue
- [PM_TOKEN_KEYWORD_RESCUE_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER_RESCUE),
-
- // and or
- [PM_TOKEN_KEYWORD_AND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION),
- [PM_TOKEN_KEYWORD_OR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION),
-
- // => in
- [PM_TOKEN_EQUAL_GREATER] = NON_ASSOCIATIVE(PM_BINDING_POWER_MATCH),
- [PM_TOKEN_KEYWORD_IN] = NON_ASSOCIATIVE(PM_BINDING_POWER_MATCH),
-
- // &&= &= ^= = >>= <<= -= %= |= += /= *= **=
- [PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_CARET_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_GREATER_GREATER_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_LESS_LESS_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_MINUS_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_PERCENT_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_PIPE_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_PIPE_PIPE_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_PLUS_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_SLASH_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_STAR_EQUAL] = BINDING_POWER_ASSIGNMENT,
- [PM_TOKEN_STAR_STAR_EQUAL] = BINDING_POWER_ASSIGNMENT,
-
- // ?:
- [PM_TOKEN_QUESTION_MARK] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_TERNARY),
-
- // .. ...
- [PM_TOKEN_DOT_DOT] = NON_ASSOCIATIVE(PM_BINDING_POWER_RANGE),
- [PM_TOKEN_DOT_DOT_DOT] = NON_ASSOCIATIVE(PM_BINDING_POWER_RANGE),
- [PM_TOKEN_UDOT_DOT] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_LOGICAL_OR),
- [PM_TOKEN_UDOT_DOT_DOT] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_LOGICAL_OR),
-
- // ||
- [PM_TOKEN_PIPE_PIPE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_LOGICAL_OR),
-
- // &&
- [PM_TOKEN_AMPERSAND_AMPERSAND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_LOGICAL_AND),
-
- // != !~ == === =~ <=>
- [PM_TOKEN_BANG_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
- [PM_TOKEN_BANG_TILDE] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
- [PM_TOKEN_EQUAL_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
- [PM_TOKEN_EQUAL_EQUAL_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
- [PM_TOKEN_EQUAL_TILDE] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
- [PM_TOKEN_LESS_EQUAL_GREATER] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
-
- // > >= < <=
- [PM_TOKEN_GREATER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON),
- [PM_TOKEN_GREATER_EQUAL] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON),
- [PM_TOKEN_LESS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON),
- [PM_TOKEN_LESS_EQUAL] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON),
-
- // ^ |
- [PM_TOKEN_CARET] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_BITWISE_OR),
- [PM_TOKEN_PIPE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_BITWISE_OR),
-
- // &
- [PM_TOKEN_AMPERSAND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_BITWISE_AND),
-
- // >> <<
- [PM_TOKEN_GREATER_GREATER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_SHIFT),
- [PM_TOKEN_LESS_LESS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_SHIFT),
-
- // - +
- [PM_TOKEN_MINUS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_TERM),
- [PM_TOKEN_PLUS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_TERM),
-
- // % / *
- [PM_TOKEN_PERCENT] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR),
- [PM_TOKEN_SLASH] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR),
- [PM_TOKEN_STAR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR),
- [PM_TOKEN_USTAR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR),
-
- // -@
- [PM_TOKEN_UMINUS] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UMINUS),
- [PM_TOKEN_UMINUS_NUM] = { PM_BINDING_POWER_UMINUS, PM_BINDING_POWER_MAX, false, false },
-
- // **
- [PM_TOKEN_STAR_STAR] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_EXPONENT),
- [PM_TOKEN_USTAR_STAR] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY),
-
- // ! ~ +@
- [PM_TOKEN_BANG] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY),
- [PM_TOKEN_TILDE] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY),
- [PM_TOKEN_UPLUS] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY),
-
- // [
- [PM_TOKEN_BRACKET_LEFT] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_INDEX),
-
- // :: . &.
- [PM_TOKEN_COLON_COLON] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_CALL),
- [PM_TOKEN_DOT] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_CALL),
- [PM_TOKEN_AMPERSAND_DOT] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_CALL)
-};
-
-#undef BINDING_POWER_ASSIGNMENT
-#undef LEFT_ASSOCIATIVE
-#undef RIGHT_ASSOCIATIVE
-#undef RIGHT_ASSOCIATIVE_UNARY
-
-/**
- * Returns true if the current token is of the given type.
- */
-static inline bool
-match1(const pm_parser_t *parser, pm_token_type_t type) {
- return parser->current.type == type;
-}
-
-/**
- * Returns true if the current token is of either of the given types.
- */
-static inline bool
-match2(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2) {
- return match1(parser, type1) || match1(parser, type2);
-}
-
-/**
- * Returns true if the current token is any of the three given types.
- */
-static inline bool
-match3(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3) {
- return match1(parser, type1) || match1(parser, type2) || match1(parser, type3);
-}
-
-/**
- * Returns true if the current token is any of the four given types.
- */
-static inline bool
-match4(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4) {
- return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4);
-}
-
-/**
- * Returns true if the current token is any of the five given types.
- */
-static inline bool
-match5(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5) {
- return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5);
-}
-
-/**
- * Returns true if the current token is any of the six given types.
- */
-static inline bool
-match6(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5, pm_token_type_t type6) {
- return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5) || match1(parser, type6);
-}
-
-/**
- * Returns true if the current token is any of the seven given types.
- */
-static inline bool
-match7(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5, pm_token_type_t type6, pm_token_type_t type7) {
- return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5) || match1(parser, type6) || match1(parser, type7);
-}
-
-/**
- * Returns true if the current token is any of the eight given types.
- */
-static inline bool
-match8(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5, pm_token_type_t type6, pm_token_type_t type7, pm_token_type_t type8) {
- return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5) || match1(parser, type6) || match1(parser, type7) || match1(parser, type8);
-}
-
-/**
- * If the current token is of the specified type, lex forward by one token and
- * return true. Otherwise, return false. For example:
- *
- * if (accept1(parser, PM_TOKEN_COLON)) { ... }
- */
-static bool
-accept1(pm_parser_t *parser, pm_token_type_t type) {
- if (match1(parser, type)) {
- parser_lex(parser);
- return true;
- }
- return false;
-}
-
-/**
- * If the current token is either of the two given types, lex forward by one
- * token and return true. Otherwise return false.
- */
-static inline bool
-accept2(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2) {
- if (match2(parser, type1, type2)) {
- parser_lex(parser);
- return true;
- }
- return false;
-}
-
-/**
- * If the current token is any of the three given types, lex forward by one
- * token and return true. Otherwise return false.
- */
-static inline bool
-accept3(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3) {
- if (match3(parser, type1, type2, type3)) {
- parser_lex(parser);
- return true;
- }
- return false;
-}
-
-/**
- * This function indicates that the parser expects a token in a specific
- * position. For example, if you're parsing a BEGIN block, you know that a { is
- * expected immediately after the keyword. In that case you would call this
- * function to indicate that that token should be found.
- *
- * If we didn't find the token that we were expecting, then we're going to add
- * an error to the parser's list of errors (to indicate that the tree is not
- * valid) and create an artificial token instead. This allows us to recover from
- * the fact that the token isn't present and continue parsing.
- */
-static void
-expect1(pm_parser_t *parser, pm_token_type_t type, pm_diagnostic_id_t diag_id) {
- if (accept1(parser, type)) return;
-
- const uint8_t *location = parser->previous.end;
- pm_parser_err(parser, location, location, diag_id);
-
- parser->previous.start = location;
- parser->previous.type = PM_TOKEN_MISSING;
-}
-
-/**
- * This function is the same as expect1, but it expects either of two token
- * types.
- */
-static void
-expect2(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_diagnostic_id_t diag_id) {
- if (accept2(parser, type1, type2)) return;
-
- const uint8_t *location = parser->previous.end;
- pm_parser_err(parser, location, location, diag_id);
-
- parser->previous.start = location;
- parser->previous.type = PM_TOKEN_MISSING;
-}
-
-/**
- * This function is the same as expect2, but it expects one of three token types.
- */
-static void
-expect3(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_diagnostic_id_t diag_id) {
- if (accept3(parser, type1, type2, type3)) return;
-
- const uint8_t *location = parser->previous.end;
- pm_parser_err(parser, location, location, diag_id);
-
- parser->previous.start = location;
- parser->previous.type = PM_TOKEN_MISSING;
-}
-
-static pm_node_t *
-parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id);
-
-/**
- * This is a wrapper of parse_expression, which also checks whether the resulting node is value expression.
- */
-static pm_node_t *
-parse_value_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
- pm_node_t *node = parse_expression(parser, binding_power, accepts_command_call, diag_id);
- pm_assert_value_expression(parser, node);
- return node;
-}
-
-/**
- * This function controls whether or not we will attempt to parse an expression
- * beginning at the subsequent token. It is used when we are in a context where
- * an expression is optional.
- *
- * For example, looking at a range object when we've already lexed the operator,
- * we need to know if we should attempt to parse an expression on the right.
- *
- * For another example, if we've parsed an identifier or a method call and we do
- * not have parentheses, then the next token may be the start of an argument or
- * it may not.
- *
- * CRuby parsers that are generated would resolve this by using a lookahead and
- * potentially backtracking. We attempt to do this by just looking at the next
- * token and making a decision based on that. I am not sure if this is going to
- *
- * work in all cases, it may need to be refactored later. But it appears to work
- * for now.
- */
-static inline bool
-token_begins_expression_p(pm_token_type_t type) {
- switch (type) {
- case PM_TOKEN_EQUAL_GREATER:
- case PM_TOKEN_KEYWORD_IN:
- // We need to special case this because it is a binary operator that
- // should not be marked as beginning an expression.
- return false;
- case PM_TOKEN_BRACE_RIGHT:
- case PM_TOKEN_BRACKET_RIGHT:
- case PM_TOKEN_COLON:
- case PM_TOKEN_COMMA:
- case PM_TOKEN_EMBEXPR_END:
- case PM_TOKEN_EOF:
- case PM_TOKEN_LAMBDA_BEGIN:
- case PM_TOKEN_KEYWORD_DO:
- case PM_TOKEN_KEYWORD_DO_LOOP:
- case PM_TOKEN_KEYWORD_END:
- case PM_TOKEN_KEYWORD_ELSE:
- case PM_TOKEN_KEYWORD_ELSIF:
- case PM_TOKEN_KEYWORD_ENSURE:
- case PM_TOKEN_KEYWORD_THEN:
- case PM_TOKEN_KEYWORD_RESCUE:
- case PM_TOKEN_KEYWORD_WHEN:
- case PM_TOKEN_NEWLINE:
- case PM_TOKEN_PARENTHESIS_RIGHT:
- case PM_TOKEN_SEMICOLON:
- // The reason we need this short-circuit is because we're using the
- // binding powers table to tell us if the subsequent token could
- // potentially be the start of an expression . If there _is_ a binding
- // power for one of these tokens, then we should remove it from this list
- // and let it be handled by the default case below.
- assert(pm_binding_powers[type].left == PM_BINDING_POWER_UNSET);
- return false;
- case PM_TOKEN_UAMPERSAND:
- // This is a special case because this unary operator cannot appear
- // as a general operator, it only appears in certain circumstances.
- return false;
- case PM_TOKEN_UCOLON_COLON:
- case PM_TOKEN_UMINUS:
- case PM_TOKEN_UMINUS_NUM:
- case PM_TOKEN_UPLUS:
- case PM_TOKEN_BANG:
- case PM_TOKEN_TILDE:
- case PM_TOKEN_UDOT_DOT:
- case PM_TOKEN_UDOT_DOT_DOT:
- // These unary tokens actually do have binding power associated with them
- // so that we can correctly place them into the precedence order. But we
- // want them to be marked as beginning an expression, so we need to
- // special case them here.
- return true;
- default:
- return pm_binding_powers[type].left == PM_BINDING_POWER_UNSET;
- }
-}
-
-/**
- * Parse an expression with the given binding power that may be optionally
- * prefixed by the * operator.
- */
-static pm_node_t *
-parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
- if (accept1(parser, PM_TOKEN_USTAR)) {
- pm_token_t operator = parser->previous;
- pm_node_t *expression = parse_value_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
- return (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
- }
-
- return parse_value_expression(parser, binding_power, accepts_command_call, diag_id);
-}
-
-/**
- * Convert the name of a method into the corresponding write method name. For
- * example, foo would be turned into foo=.
- */
-static void
-parse_write_name(pm_parser_t *parser, pm_constant_id_t *name_field) {
- // The method name needs to change. If we previously had
- // foo, we now need foo=. In this case we'll allocate a new
- // owned string, copy the previous method name in, and
- // append an =.
- pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, *name_field);
- size_t length = constant->length;
- uint8_t *name = calloc(length + 1, sizeof(uint8_t));
- if (name == NULL) return;
-
- memcpy(name, constant->start, length);
- name[length] = '=';
-
- // Now switch the name to the new string.
- // This silences clang analyzer warning about leak of memory pointed by `name`.
- // NOLINTNEXTLINE(clang-analyzer-*)
- *name_field = pm_constant_pool_insert_owned(&parser->constant_pool, name, length + 1);
-}
-
-/**
- * Convert the given node into a valid target node.
- */
-static pm_node_t *
-parse_target(pm_parser_t *parser, pm_node_t *target) {
- switch (PM_NODE_TYPE(target)) {
- case PM_MISSING_NODE:
- return target;
- case PM_CLASS_VARIABLE_READ_NODE:
- assert(sizeof(pm_class_variable_target_node_t) == sizeof(pm_class_variable_read_node_t));
- target->type = PM_CLASS_VARIABLE_TARGET_NODE;
- return target;
- case PM_CONSTANT_PATH_NODE:
- assert(sizeof(pm_constant_path_target_node_t) == sizeof(pm_constant_path_node_t));
- target->type = PM_CONSTANT_PATH_TARGET_NODE;
- return target;
- case PM_CONSTANT_READ_NODE:
- assert(sizeof(pm_constant_target_node_t) == sizeof(pm_constant_read_node_t));
- target->type = PM_CONSTANT_TARGET_NODE;
- return target;
- case PM_BACK_REFERENCE_READ_NODE:
- case PM_NUMBERED_REFERENCE_READ_NODE:
- pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_READONLY);
- return target;
- case PM_GLOBAL_VARIABLE_READ_NODE:
- assert(sizeof(pm_global_variable_target_node_t) == sizeof(pm_global_variable_read_node_t));
- target->type = PM_GLOBAL_VARIABLE_TARGET_NODE;
- return target;
- case PM_LOCAL_VARIABLE_READ_NODE:
- if (pm_token_is_numbered_parameter(target->location.start, target->location.end)) {
- PM_PARSER_ERR_NODE_FORMAT(parser, target, PM_ERR_PARAMETER_NUMBERED_RESERVED, target->location.start);
- } else {
- assert(sizeof(pm_local_variable_target_node_t) == sizeof(pm_local_variable_read_node_t));
- target->type = PM_LOCAL_VARIABLE_TARGET_NODE;
- }
-
- return target;
- case PM_INSTANCE_VARIABLE_READ_NODE:
- assert(sizeof(pm_instance_variable_target_node_t) == sizeof(pm_instance_variable_read_node_t));
- target->type = PM_INSTANCE_VARIABLE_TARGET_NODE;
- return target;
- case PM_MULTI_TARGET_NODE:
- return target;
- case PM_SPLAT_NODE: {
- pm_splat_node_t *splat = (pm_splat_node_t *) target;
-
- if (splat->expression != NULL) {
- splat->expression = parse_target(parser, splat->expression);
- }
-
- return (pm_node_t *) splat;
- }
- case PM_CALL_NODE: {
- pm_call_node_t *call = (pm_call_node_t *) target;
-
- // If we have no arguments to the call node and we need this to be a
- // target then this is either a method call or a local variable write.
- if (
- (call->message_loc.start != NULL) &&
- (call->message_loc.end[-1] != '!') &&
- (call->message_loc.end[-1] != '?') &&
- (call->opening_loc.start == NULL) &&
- (call->arguments == NULL) &&
- (call->block == NULL)
- ) {
- if (call->receiver == NULL) {
- // When we get here, we have a local variable write, because it
- // was previously marked as a method call but now we have an =.
- // This looks like:
- //
- // foo = 1
- //
- // When it was parsed in the prefix position, foo was seen as a
- // method call with no receiver and no arguments. Now we have an
- // =, so we know it's a local variable write.
- const pm_location_t message = call->message_loc;
-
- pm_parser_local_add_location(parser, message.start, message.end);
- pm_node_destroy(parser, target);
-
- uint32_t depth = 0;
- const pm_token_t name = { .type = PM_TOKEN_IDENTIFIER, .start = message.start, .end = message.end };
- target = (pm_node_t *) pm_local_variable_read_node_create(parser, &name, depth);
-
- assert(sizeof(pm_local_variable_target_node_t) == sizeof(pm_local_variable_read_node_t));
- target->type = PM_LOCAL_VARIABLE_TARGET_NODE;
-
- pm_refute_numbered_parameter(parser, message.start, message.end);
- return target;
- }
-
- if (*call->message_loc.start == '_' || parser->encoding->alnum_char(call->message_loc.start, call->message_loc.end - call->message_loc.start)) {
- parse_write_name(parser, &call->name);
- return (pm_node_t *) pm_call_target_node_create(parser, call);
- }
- }
-
- // If there is no call operator and the message is "[]" then this is
- // an aref expression, and we can transform it into an aset
- // expression.
- if (pm_call_node_index_p(call)) {
- return (pm_node_t *) pm_index_target_node_create(parser, call);
- }
- }
- /* fallthrough */
- default:
- // In this case we have a node that we don't know how to convert
- // into a target. We need to treat it as an error. For now, we'll
- // mark it as an error and just skip right past it.
- pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_UNEXPECTED);
- return target;
- }
-}
-
-/**
- * Parse a write target and validate that it is in a valid position for
- * assignment.
- */
-static pm_node_t *
-parse_target_validate(pm_parser_t *parser, pm_node_t *target) {
- pm_node_t *result = parse_target(parser, target);
-
- // Ensure that we have one of an =, an 'in' in for indexes, and a ')' in parens after the targets.
- if (
- !match1(parser, PM_TOKEN_EQUAL) &&
- !(context_p(parser, PM_CONTEXT_FOR_INDEX) && match1(parser, PM_TOKEN_KEYWORD_IN)) &&
- !(context_p(parser, PM_CONTEXT_PARENS) && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT))
- ) {
- pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED);
- }
-
- return result;
-}
-
-/**
- * Convert the given node into a valid write node.
- */
-static pm_node_t *
-parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_node_t *value) {
- switch (PM_NODE_TYPE(target)) {
- case PM_MISSING_NODE:
- pm_node_destroy(parser, value);
- return target;
- case PM_CLASS_VARIABLE_READ_NODE: {
- pm_class_variable_write_node_t *node = pm_class_variable_write_node_create(parser, (pm_class_variable_read_node_t *) target, operator, value);
- pm_node_destroy(parser, target);
- return (pm_node_t *) node;
- }
- case PM_CONSTANT_PATH_NODE:
- return (pm_node_t *) pm_constant_path_write_node_create(parser, (pm_constant_path_node_t *) target, operator, value);
- case PM_CONSTANT_READ_NODE: {
- pm_constant_write_node_t *node = pm_constant_write_node_create(parser, (pm_constant_read_node_t *) target, operator, value);
- if (context_def_p(parser)) {
- pm_parser_err_node(parser, (pm_node_t *) node, PM_ERR_WRITE_TARGET_IN_METHOD);
- }
- pm_node_destroy(parser, target);
- return (pm_node_t *) node;
- }
- case PM_BACK_REFERENCE_READ_NODE:
- case PM_NUMBERED_REFERENCE_READ_NODE:
- pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_READONLY);
- /* fallthrough */
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- pm_global_variable_write_node_t *node = pm_global_variable_write_node_create(parser, target, operator, value);
- pm_node_destroy(parser, target);
- return (pm_node_t *) node;
- }
- case PM_LOCAL_VARIABLE_READ_NODE: {
- pm_refute_numbered_parameter(parser, target->location.start, target->location.end);
- pm_local_variable_read_node_t *local_read = (pm_local_variable_read_node_t *) target;
-
- pm_constant_id_t constant_id = local_read->name;
- uint32_t depth = local_read->depth;
-
- pm_location_t name_loc = target->location;
- pm_node_destroy(parser, target);
-
- return (pm_node_t *) pm_local_variable_write_node_create(parser, constant_id, depth, value, &name_loc, operator);
- }
- case PM_INSTANCE_VARIABLE_READ_NODE: {
- pm_node_t *write_node = (pm_node_t *) pm_instance_variable_write_node_create(parser, (pm_instance_variable_read_node_t *) target, operator, value);
- pm_node_destroy(parser, target);
- return write_node;
- }
- case PM_MULTI_TARGET_NODE:
- return (pm_node_t *) pm_multi_write_node_create(parser, (pm_multi_target_node_t *) target, operator, value);
- case PM_SPLAT_NODE: {
- pm_splat_node_t *splat = (pm_splat_node_t *) target;
-
- if (splat->expression != NULL) {
- splat->expression = parse_write(parser, splat->expression, operator, value);
- }
-
- pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser);
- pm_multi_target_node_targets_append(parser, multi_target, (pm_node_t *) splat);
-
- return (pm_node_t *) pm_multi_write_node_create(parser, multi_target, operator, value);
- }
- case PM_CALL_NODE: {
- pm_call_node_t *call = (pm_call_node_t *) target;
-
- // If we have no arguments to the call node and we need this to be a
- // target then this is either a method call or a local variable
- // write.
- if (
- (call->message_loc.start != NULL) &&
- (call->message_loc.end[-1] != '!') &&
- (call->message_loc.end[-1] != '?') &&
- (call->opening_loc.start == NULL) &&
- (call->arguments == NULL) &&
- (call->block == NULL)
- ) {
- if (call->receiver == NULL) {
- // When we get here, we have a local variable write, because it
- // was previously marked as a method call but now we have an =.
- // This looks like:
- //
- // foo = 1
- //
- // When it was parsed in the prefix position, foo was seen as a
- // method call with no receiver and no arguments. Now we have an
- // =, so we know it's a local variable write.
- const pm_location_t message = call->message_loc;
-
- pm_parser_local_add_location(parser, message.start, message.end);
- pm_node_destroy(parser, target);
-
- pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, message.start, message.end);
- target = (pm_node_t *) pm_local_variable_write_node_create(parser, constant_id, 0, value, &message, operator);
-
- pm_refute_numbered_parameter(parser, message.start, message.end);
- return target;
- }
-
- if (*call->message_loc.start == '_' || parser->encoding->alnum_char(call->message_loc.start, call->message_loc.end - call->message_loc.start)) {
- // When we get here, we have a method call, because it was
- // previously marked as a method call but now we have an =. This
- // looks like:
- //
- // foo.bar = 1
- //
- // When it was parsed in the prefix position, foo.bar was seen as a
- // method call with no arguments. Now we have an =, so we know it's
- // a method call with an argument. In this case we will create the
- // arguments node, parse the argument, and add it to the list.
- pm_arguments_node_t *arguments = pm_arguments_node_create(parser);
- call->arguments = arguments;
-
- pm_arguments_node_arguments_append(arguments, value);
- call->base.location.end = arguments->base.location.end;
-
- parse_write_name(parser, &call->name);
- pm_node_flag_set((pm_node_t *) call, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE);
- return (pm_node_t *) call;
- }
- }
-
- // If there is no call operator and the message is "[]" then this is
- // an aref expression, and we can transform it into an aset
- // expression.
- if (pm_call_node_index_p(call)) {
- if (call->arguments == NULL) {
- call->arguments = pm_arguments_node_create(parser);
- }
-
- pm_arguments_node_arguments_append(call->arguments, value);
- target->location.end = value->location.end;
-
- // Replace the name with "[]=".
- call->name = pm_parser_constant_id_constant(parser, "[]=", 3);
- pm_node_flag_set((pm_node_t *) call, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE);
- return target;
- }
-
- // If there are arguments on the call node, then it can't be a method
- // call ending with = or a local variable write, so it must be a
- // syntax error. In this case we'll fall through to our default
- // handling. We need to free the value that we parsed because there
- // is no way for us to attach it to the tree at this point.
- pm_node_destroy(parser, value);
- }
- /* fallthrough */
- default:
- // In this case we have a node that we don't know how to convert into a
- // target. We need to treat it as an error. For now, we'll mark it as an
- // error and just skip right past it.
- pm_parser_err_token(parser, operator, PM_ERR_WRITE_TARGET_UNEXPECTED);
- return target;
- }
-}
-
-/**
- * Parse a list of targets for assignment. This is used in the case of a for
- * loop or a multi-assignment. For example, in the following code:
- *
- * for foo, bar in baz
- * ^^^^^^^^
- *
- * The targets are `foo` and `bar`. This function will either return a single
- * target node or a multi-target node.
- */
-static pm_node_t *
-parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power) {
- bool has_rest = PM_NODE_TYPE_P(first_target, PM_SPLAT_NODE);
-
- pm_multi_target_node_t *result = pm_multi_target_node_create(parser);
- pm_multi_target_node_targets_append(parser, result, parse_target(parser, first_target));
-
- while (accept1(parser, PM_TOKEN_COMMA)) {
- if (accept1(parser, PM_TOKEN_USTAR)) {
- // Here we have a splat operator. It can have a name or be
- // anonymous. It can be the final target or be in the middle if
- // there haven't been any others yet.
- if (has_rest) {
- pm_parser_err_previous(parser, PM_ERR_MULTI_ASSIGN_MULTI_SPLATS);
- }
-
- pm_token_t star_operator = parser->previous;
- pm_node_t *name = NULL;
-
- if (token_begins_expression_p(parser->current.type)) {
- name = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
- name = parse_target(parser, name);
- }
-
- pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name);
- pm_multi_target_node_targets_append(parser, result, splat);
- has_rest = true;
- } else if (token_begins_expression_p(parser->current.type)) {
- pm_node_t *target = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
- target = parse_target(parser, target);
-
- pm_multi_target_node_targets_append(parser, result, target);
- } else if (!match1(parser, PM_TOKEN_EOF)) {
- // If we get here, then we have a trailing , in a multi target node.
- // We'll set the implicit rest flag to indicate this.
- pm_node_t *rest = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
- pm_multi_target_node_targets_append(parser, result, rest);
- break;
- }
- }
-
- return (pm_node_t *) result;
-}
-
-/**
- * Parse a list of targets and validate that it is in a valid position for
- * assignment.
- */
-static pm_node_t *
-parse_targets_validate(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power) {
- pm_node_t *result = parse_targets(parser, first_target, binding_power);
-
- // Ensure that we have either an = or a ) after the targets.
- if (!match2(parser, PM_TOKEN_EQUAL, PM_TOKEN_PARENTHESIS_RIGHT)) {
- pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED);
- }
-
- return result;
-}
-
-/**
- * Parse a list of statements separated by newlines or semicolons.
- */
-static pm_statements_node_t *
-parse_statements(pm_parser_t *parser, pm_context_t context) {
- // First, skip past any optional terminators that might be at the beginning of
- // the statements.
- while (accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE));
-
- // If we have a terminator, then we can just return NULL.
- if (context_terminator(context, &parser->current)) return NULL;
-
- pm_statements_node_t *statements = pm_statements_node_create(parser);
-
- // At this point we know we have at least one statement, and that it
- // immediately follows the current token.
- context_push(parser, context);
-
- while (true) {
- pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
- pm_statements_node_body_append(statements, node);
-
- // If we're recovering from a syntax error, then we need to stop parsing the
- // statements now.
- if (parser->recovering) {
- // If this is the level of context where the recovery has happened, then
- // we can mark the parser as done recovering.
- if (context_terminator(context, &parser->current)) parser->recovering = false;
- break;
- }
-
- // If we have a terminator, then we will parse all consequtive terminators
- // and then continue parsing the statements list.
- if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- // If we have a terminator, then we will continue parsing the statements
- // list.
- while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
- if (context_terminator(context, &parser->current)) break;
-
- // Now we can continue parsing the list of statements.
- continue;
- }
-
- // At this point we have a list of statements that are not terminated by a
- // newline or semicolon. At this point we need to check if we're at the end
- // of the statements list. If we are, then we should break out of the loop.
- if (context_terminator(context, &parser->current)) break;
-
- // At this point, we have a syntax error, because the statement was not
- // terminated by a newline or semicolon, and we're not at the end of the
- // statements list. Ideally we should scan forward to determine if we should
- // insert a missing terminator or break out of parsing the statements list
- // at this point.
- //
- // We don't have that yet, so instead we'll do a more naive approach. If we
- // were unable to parse an expression, then we will skip past this token and
- // continue parsing the statements list. Otherwise we'll add an error and
- // continue parsing the statements list.
- if (PM_NODE_TYPE_P(node, PM_MISSING_NODE)) {
- parser_lex(parser);
-
- while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
- if (context_terminator(context, &parser->current)) break;
- } else {
- expect1(parser, PM_TOKEN_NEWLINE, PM_ERR_EXPECT_EOL_AFTER_STATEMENT);
- }
- }
-
- context_pop(parser);
- return statements;
-}
-
-/**
- * Parse all of the elements of a hash. returns true if a double splat was found.
- */
-static bool
-parse_assocs(pm_parser_t *parser, pm_node_t *node) {
- assert(PM_NODE_TYPE_P(node, PM_HASH_NODE) || PM_NODE_TYPE_P(node, PM_KEYWORD_HASH_NODE));
- bool contains_keyword_splat = false;
-
- while (true) {
- pm_node_t *element;
-
- switch (parser->current.type) {
- case PM_TOKEN_USTAR_STAR: {
- parser_lex(parser);
- pm_token_t operator = parser->previous;
- pm_node_t *value = NULL;
-
- if (token_begins_expression_p(parser->current.type)) {
- value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
- } else if (pm_parser_local_depth(parser, &operator) == -1) {
- pm_parser_err_token(parser, &operator, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
- }
-
- element = (pm_node_t *) pm_assoc_splat_node_create(parser, value, &operator);
- contains_keyword_splat = true;
- break;
- }
- case PM_TOKEN_LABEL: {
- pm_token_t label = parser->current;
- parser_lex(parser);
-
- pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &label);
- pm_token_t operator = not_provided(parser);
- pm_node_t *value = NULL;
-
- if (token_begins_expression_p(parser->current.type)) {
- value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_EXPRESSION_AFTER_LABEL);
- } else {
- if (parser->encoding->isupper_char(label.start, (label.end - 1) - label.start)) {
- pm_token_t constant = { .type = PM_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
- value = (pm_node_t *) pm_constant_read_node_create(parser, &constant);
- } else {
- int depth = pm_parser_local_depth(parser, &((pm_token_t) { .type = PM_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 }));
- pm_token_t identifier = { .type = PM_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 };
-
- if (depth == -1) {
- value = (pm_node_t *) pm_call_node_variable_call_create(parser, &identifier);
- } else {
- value = (pm_node_t *) pm_local_variable_read_node_create(parser, &identifier, (uint32_t) depth);
- }
- }
-
- value->location.end++;
- value = (pm_node_t *) pm_implicit_node_create(parser, value);
- }
-
- element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
- break;
- }
- default: {
- pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_KEY);
- pm_token_t operator;
-
- if (pm_symbol_node_label_p(key)) {
- operator = not_provided(parser);
- } else {
- expect1(parser, PM_TOKEN_EQUAL_GREATER, PM_ERR_HASH_ROCKET);
- operator = parser->previous;
- }
-
- pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
- element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
- break;
- }
- }
-
- if (PM_NODE_TYPE_P(node, PM_HASH_NODE)) {
- pm_hash_node_elements_append((pm_hash_node_t *) node, element);
- } else {
- pm_keyword_hash_node_elements_append((pm_keyword_hash_node_t *) node, element);
- }
-
- // If there's no comma after the element, then we're done.
- if (!accept1(parser, PM_TOKEN_COMMA)) break;
-
- // If the next element starts with a label or a **, then we know we have
- // another element in the hash, so we'll continue parsing.
- if (match2(parser, PM_TOKEN_USTAR_STAR, PM_TOKEN_LABEL)) continue;
-
- // Otherwise we need to check if the subsequent token begins an expression.
- // If it does, then we'll continue parsing.
- if (token_begins_expression_p(parser->current.type)) continue;
-
- // Otherwise by default we will exit out of this loop.
- break;
- }
- return contains_keyword_splat;
-}
-
-/**
- * Append an argument to a list of arguments.
- */
-static inline void
-parse_arguments_append(pm_parser_t *parser, pm_arguments_t *arguments, pm_node_t *argument) {
- if (arguments->arguments == NULL) {
- arguments->arguments = pm_arguments_node_create(parser);
- }
-
- pm_arguments_node_arguments_append(arguments->arguments, argument);
-}
-
-/**
- * Parse a list of arguments.
- */
-static void
-parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_forwarding, pm_token_type_t terminator) {
- pm_binding_power_t binding_power = pm_binding_powers[parser->current.type].left;
-
- // First we need to check if the next token is one that could be the start of
- // an argument. If it's not, then we can just return.
- if (
- match2(parser, terminator, PM_TOKEN_EOF) ||
- (binding_power != PM_BINDING_POWER_UNSET && binding_power < PM_BINDING_POWER_RANGE) ||
- context_terminator(parser->current_context->context, &parser->current)
- ) {
- return;
- }
-
- bool parsed_first_argument = false;
- bool parsed_bare_hash = false;
- bool parsed_block_argument = false;
- bool parsed_forwarding_arguments = false;
-
- while (!match1(parser, PM_TOKEN_EOF)) {
- if (parsed_block_argument) {
- pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_BLOCK);
- }
- if (parsed_forwarding_arguments) {
- pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES);
- }
-
- pm_node_t *argument = NULL;
-
- switch (parser->current.type) {
- case PM_TOKEN_USTAR_STAR:
- case PM_TOKEN_LABEL: {
- if (parsed_bare_hash) {
- pm_parser_err_current(parser, PM_ERR_ARGUMENT_BARE_HASH);
- }
-
- pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser);
- argument = (pm_node_t *) hash;
-
- bool contains_keyword_splat = parse_assocs(parser, (pm_node_t *) hash);
- parsed_bare_hash = true;
- parse_arguments_append(parser, arguments, argument);
- if (contains_keyword_splat) {
- pm_node_flag_set((pm_node_t *)arguments->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
- }
- break;
- }
- case PM_TOKEN_UAMPERSAND: {
- parser_lex(parser);
- pm_token_t operator = parser->previous;
- pm_node_t *expression = NULL;
-
- if (token_begins_expression_p(parser->current.type)) {
- expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_ARGUMENT);
- } else {
- if (pm_parser_local_depth(parser, &operator) == -1) {
- // A block forwarding in a method having `...` parameter (e.g. `def foo(...); bar(&); end`) is available.
- pm_constant_id_t ellipsis_id = pm_parser_constant_id_constant(parser, "...", 3);
- if (pm_parser_local_depth_constant_id(parser, ellipsis_id) == -1) {
- pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_AMP);
- }
- }
- }
-
- argument = (pm_node_t *) pm_block_argument_node_create(parser, &operator, expression);
- if (parsed_block_argument) {
- parse_arguments_append(parser, arguments, argument);
- } else {
- arguments->block = argument;
- }
-
- parsed_block_argument = true;
- break;
- }
- case PM_TOKEN_USTAR: {
- parser_lex(parser);
- pm_token_t operator = parser->previous;
-
- if (match4(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_SEMICOLON, PM_TOKEN_BRACKET_RIGHT)) {
- if (pm_parser_local_depth(parser, &parser->previous) == -1) {
- pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_STAR);
- }
-
- argument = (pm_node_t *) pm_splat_node_create(parser, &operator, NULL);
- } else {
- pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
-
- if (parsed_bare_hash) {
- pm_parser_err(parser, operator.start, expression->location.end, PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT);
- }
-
- argument = (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
- }
-
- parse_arguments_append(parser, arguments, argument);
- break;
- }
- case PM_TOKEN_UDOT_DOT_DOT: {
- if (accepts_forwarding) {
- parser_lex(parser);
-
- if (token_begins_expression_p(parser->current.type)) {
- // If the token begins an expression then this ... was not actually
- // argument forwarding but was instead a range.
- pm_token_t operator = parser->previous;
- pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_RANGE, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- argument = (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
- } else {
- if (pm_parser_local_depth(parser, &parser->previous) == -1) {
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
- }
- if (parsed_first_argument && terminator == PM_TOKEN_EOF) {
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORWARDING_UNBOUND);
- }
-
- argument = (pm_node_t *) pm_forwarding_arguments_node_create(parser, &parser->previous);
- parse_arguments_append(parser, arguments, argument);
- parsed_forwarding_arguments = true;
- break;
- }
- }
- }
- /* fallthrough */
- default: {
- if (argument == NULL) {
- argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, !parsed_first_argument, PM_ERR_EXPECT_ARGUMENT);
- }
-
- bool contains_keyword_splat = false;
- if (pm_symbol_node_label_p(argument) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
- if (parsed_bare_hash) {
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_BARE_HASH);
- }
-
- pm_token_t operator;
- if (parser->previous.type == PM_TOKEN_EQUAL_GREATER) {
- operator = parser->previous;
- } else {
- operator = not_provided(parser);
- }
-
- pm_keyword_hash_node_t *bare_hash = pm_keyword_hash_node_create(parser);
-
- // Finish parsing the one we are part way through
- pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
-
- argument = (pm_node_t *) pm_assoc_node_create(parser, argument, &operator, value);
- pm_keyword_hash_node_elements_append(bare_hash, argument);
- argument = (pm_node_t *) bare_hash;
-
- // Then parse more if we have a comma
- if (accept1(parser, PM_TOKEN_COMMA) && (
- token_begins_expression_p(parser->current.type) ||
- match2(parser, PM_TOKEN_USTAR_STAR, PM_TOKEN_LABEL)
- )) {
- contains_keyword_splat = parse_assocs(parser, (pm_node_t *) bare_hash);
- }
-
- parsed_bare_hash = true;
- }
-
- parse_arguments_append(parser, arguments, argument);
- if (contains_keyword_splat) {
- pm_node_flag_set((pm_node_t *)arguments->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
- }
- break;
- }
- }
-
- parsed_first_argument = true;
-
- // If parsing the argument failed, we need to stop parsing arguments.
- if (PM_NODE_TYPE_P(argument, PM_MISSING_NODE) || parser->recovering) break;
-
- // If the terminator of these arguments is not EOF, then we have a specific
- // token we're looking for. In that case we can accept a newline here
- // because it is not functioning as a statement terminator.
- if (terminator != PM_TOKEN_EOF) accept1(parser, PM_TOKEN_NEWLINE);
-
- if (parser->previous.type == PM_TOKEN_COMMA && parsed_bare_hash) {
- // If we previously were on a comma and we just parsed a bare hash, then
- // we want to continue parsing arguments. This is because the comma was
- // grabbed up by the hash parser.
- } else {
- // If there is no comma at the end of the argument list then we're done
- // parsing arguments and can break out of this loop.
- if (!accept1(parser, PM_TOKEN_COMMA)) break;
- }
-
- // If we hit the terminator, then that means we have a trailing comma so we
- // can accept that output as well.
- if (match1(parser, terminator)) break;
- }
-}
-
-/**
- * Required parameters on method, block, and lambda declarations can be
- * destructured using parentheses. This looks like:
- *
- * def foo((bar, baz))
- * end
- *
- *
- * It can recurse infinitely down, and splats are allowed to group arguments.
- */
-static pm_multi_target_node_t *
-parse_required_destructured_parameter(pm_parser_t *parser) {
- expect1(parser, PM_TOKEN_PARENTHESIS_LEFT, PM_ERR_EXPECT_LPAREN_REQ_PARAMETER);
-
- pm_multi_target_node_t *node = pm_multi_target_node_create(parser);
- pm_multi_target_node_opening_set(node, &parser->previous);
-
- do {
- pm_node_t *param;
-
- // If we get here then we have a trailing comma, which isn't allowed in
- // the grammar. In other places, multi targets _do_ allow trailing
- // commas, so here we'll assume this is a mistake of the user not
- // knowing it's not allowed here.
- if (node->lefts.size > 0 && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
- pm_multi_target_node_targets_append(parser, node, param);
- pm_parser_err_current(parser, PM_ERR_PARAMETER_WILD_LOOSE_COMMA);
- break;
- }
-
- if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
- param = (pm_node_t *) parse_required_destructured_parameter(parser);
- } else if (accept1(parser, PM_TOKEN_USTAR)) {
- pm_token_t star = parser->previous;
- pm_node_t *value = NULL;
-
- if (accept1(parser, PM_TOKEN_IDENTIFIER)) {
- pm_token_t name = parser->previous;
- value = (pm_node_t *) pm_required_parameter_node_create(parser, &name);
- pm_parser_parameter_name_check(parser, &name);
- pm_parser_local_add_token(parser, &name);
- }
-
- param = (pm_node_t *) pm_splat_node_create(parser, &star, value);
- } else {
- expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_EXPECT_IDENT_REQ_PARAMETER);
- pm_token_t name = parser->previous;
-
- param = (pm_node_t *) pm_required_parameter_node_create(parser, &name);
- pm_parser_parameter_name_check(parser, &name);
- pm_parser_local_add_token(parser, &name);
- }
-
- pm_multi_target_node_targets_append(parser, node, param);
- } while (accept1(parser, PM_TOKEN_COMMA));
-
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN_REQ_PARAMETER);
- pm_multi_target_node_closing_set(node, &parser->previous);
-
- return node;
-}
-
-/**
- * This represents the different order states we can be in when parsing
- * method parameters.
- */
-typedef enum {
- PM_PARAMETERS_NO_CHANGE = 0, // Extra state for tokens that should not change the state
- PM_PARAMETERS_ORDER_NOTHING_AFTER = 1,
- PM_PARAMETERS_ORDER_KEYWORDS_REST,
- PM_PARAMETERS_ORDER_KEYWORDS,
- PM_PARAMETERS_ORDER_REST,
- PM_PARAMETERS_ORDER_AFTER_OPTIONAL,
- PM_PARAMETERS_ORDER_OPTIONAL,
- PM_PARAMETERS_ORDER_NAMED,
- PM_PARAMETERS_ORDER_NONE,
-
-} pm_parameters_order_t;
-
-/**
- * This matches parameters tokens with parameters state.
- */
-static pm_parameters_order_t parameters_ordering[PM_TOKEN_MAXIMUM] = {
- [0] = PM_PARAMETERS_NO_CHANGE,
- [PM_TOKEN_UAMPERSAND] = PM_PARAMETERS_ORDER_NOTHING_AFTER,
- [PM_TOKEN_AMPERSAND] = PM_PARAMETERS_ORDER_NOTHING_AFTER,
- [PM_TOKEN_UDOT_DOT_DOT] = PM_PARAMETERS_ORDER_NOTHING_AFTER,
- [PM_TOKEN_IDENTIFIER] = PM_PARAMETERS_ORDER_NAMED,
- [PM_TOKEN_PARENTHESIS_LEFT] = PM_PARAMETERS_ORDER_NAMED,
- [PM_TOKEN_EQUAL] = PM_PARAMETERS_ORDER_OPTIONAL,
- [PM_TOKEN_LABEL] = PM_PARAMETERS_ORDER_KEYWORDS,
- [PM_TOKEN_USTAR] = PM_PARAMETERS_ORDER_AFTER_OPTIONAL,
- [PM_TOKEN_STAR] = PM_PARAMETERS_ORDER_AFTER_OPTIONAL,
- [PM_TOKEN_USTAR_STAR] = PM_PARAMETERS_ORDER_KEYWORDS_REST,
- [PM_TOKEN_STAR_STAR] = PM_PARAMETERS_ORDER_KEYWORDS_REST
-};
-
-/**
- * Check if current parameter follows valid parameters ordering. If not it adds
- * an error to the list without stopping the parsing, otherwise sets the
- * parameters state to the one corresponding to the current parameter.
- */
-static void
-update_parameter_state(pm_parser_t *parser, pm_token_t *token, pm_parameters_order_t *current) {
- pm_parameters_order_t state = parameters_ordering[token->type];
- if (state == PM_PARAMETERS_NO_CHANGE) return;
-
- // If we see another ordered argument after a optional argument
- // we only continue parsing ordered arguments until we stop seeing ordered arguments
- if (*current == PM_PARAMETERS_ORDER_OPTIONAL && state == PM_PARAMETERS_ORDER_NAMED) {
- *current = PM_PARAMETERS_ORDER_AFTER_OPTIONAL;
- return;
- } else if (*current == PM_PARAMETERS_ORDER_AFTER_OPTIONAL && state == PM_PARAMETERS_ORDER_NAMED) {
- return;
- }
-
- if (token->type == PM_TOKEN_USTAR && *current == PM_PARAMETERS_ORDER_AFTER_OPTIONAL) {
- pm_parser_err_token(parser, token, PM_ERR_PARAMETER_STAR);
- }
-
- if (*current == PM_PARAMETERS_ORDER_NOTHING_AFTER || state > *current) {
- // We know what transition we failed on, so we can provide a better error here.
- pm_parser_err_token(parser, token, PM_ERR_PARAMETER_ORDER);
- } else if (state < *current) {
- *current = state;
- }
-}
-
-/**
- * Parse a list of parameters on a method definition.
- */
-static pm_parameters_node_t *
-parse_parameters(
- pm_parser_t *parser,
- pm_binding_power_t binding_power,
- bool uses_parentheses,
- bool allows_trailing_comma,
- bool allows_forwarding_parameters
-) {
- pm_parameters_node_t *params = pm_parameters_node_create(parser);
- bool looping = true;
-
- pm_do_loop_stack_push(parser, false);
- pm_parameters_order_t order = PM_PARAMETERS_ORDER_NONE;
-
- do {
- switch (parser->current.type) {
- case PM_TOKEN_PARENTHESIS_LEFT: {
- update_parameter_state(parser, &parser->current, &order);
- pm_node_t *param = (pm_node_t *) parse_required_destructured_parameter(parser);
-
- if (order > PM_PARAMETERS_ORDER_AFTER_OPTIONAL) {
- pm_parameters_node_requireds_append(params, param);
- } else {
- pm_parameters_node_posts_append(params, param);
- }
- break;
- }
- case PM_TOKEN_UAMPERSAND:
- case PM_TOKEN_AMPERSAND: {
- update_parameter_state(parser, &parser->current, &order);
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_token_t name;
-
- if (accept1(parser, PM_TOKEN_IDENTIFIER)) {
- name = parser->previous;
- pm_parser_parameter_name_check(parser, &name);
- pm_parser_local_add_token(parser, &name);
- } else {
- name = not_provided(parser);
-
- if (allows_forwarding_parameters) {
- pm_parser_local_add_token(parser, &operator);
- }
- }
-
- pm_block_parameter_node_t *param = pm_block_parameter_node_create(parser, &name, &operator);
- if (params->block == NULL) {
- pm_parameters_node_block_set(params, param);
- } else {
- pm_parser_err_node(parser, (pm_node_t *) param, PM_ERR_PARAMETER_BLOCK_MULTI);
- pm_parameters_node_posts_append(params, (pm_node_t *) param);
- }
-
- break;
- }
- case PM_TOKEN_UDOT_DOT_DOT: {
- if (!allows_forwarding_parameters) {
- pm_parser_err_current(parser, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
- }
-
- if (order > PM_PARAMETERS_ORDER_NOTHING_AFTER) {
- update_parameter_state(parser, &parser->current, &order);
- parser_lex(parser);
-
- if (allows_forwarding_parameters) {
- pm_parser_local_add_token(parser, &parser->previous);
- }
-
- pm_forwarding_parameter_node_t *param = pm_forwarding_parameter_node_create(parser, &parser->previous);
- if (params->keyword_rest != NULL) {
- // If we already have a keyword rest parameter, then we replace it with the
- // forwarding parameter and move the keyword rest parameter to the posts list.
- pm_node_t *keyword_rest = params->keyword_rest;
- pm_parameters_node_posts_append(params, keyword_rest);
- pm_parser_err_previous(parser, PM_ERR_PARAMETER_UNEXPECTED_FWD);
- params->keyword_rest = NULL;
- }
- pm_parameters_node_keyword_rest_set(params, (pm_node_t *)param);
- } else {
- update_parameter_state(parser, &parser->current, &order);
- parser_lex(parser);
- }
-
- break;
- }
- case PM_TOKEN_CLASS_VARIABLE:
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_INSTANCE_VARIABLE:
- case PM_TOKEN_GLOBAL_VARIABLE:
- case PM_TOKEN_METHOD_NAME: {
- parser_lex(parser);
- switch (parser->previous.type) {
- case PM_TOKEN_CONSTANT:
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_CONSTANT);
- break;
- case PM_TOKEN_INSTANCE_VARIABLE:
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_IVAR);
- break;
- case PM_TOKEN_GLOBAL_VARIABLE:
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_GLOBAL);
- break;
- case PM_TOKEN_CLASS_VARIABLE:
- pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_CLASS);
- break;
- case PM_TOKEN_METHOD_NAME:
- pm_parser_err_previous(parser, PM_ERR_PARAMETER_METHOD_NAME);
- break;
- default: break;
- }
-
- if (parser->current.type == PM_TOKEN_EQUAL) {
- update_parameter_state(parser, &parser->current, &order);
- } else {
- update_parameter_state(parser, &parser->previous, &order);
- }
-
- pm_token_t name = parser->previous;
- pm_parser_parameter_name_check(parser, &name);
- pm_parser_local_add_token(parser, &name);
-
- if (accept1(parser, PM_TOKEN_EQUAL)) {
- pm_token_t operator = parser->previous;
- context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
- pm_constant_id_t old_param_name = parser->current_param_name;
- parser->current_param_name = pm_parser_constant_id_token(parser, &name);
- pm_node_t *value = parse_value_expression(parser, binding_power, false, PM_ERR_PARAMETER_NO_DEFAULT);
-
- pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value);
- pm_parameters_node_optionals_append(params, param);
-
- parser->current_param_name = old_param_name;
- context_pop(parser);
-
- // If parsing the value of the parameter resulted in error recovery,
- // then we can put a missing node in its place and stop parsing the
- // parameters entirely now.
- if (parser->recovering) {
- looping = false;
- break;
- }
- } else if (order > PM_PARAMETERS_ORDER_AFTER_OPTIONAL) {
- pm_required_parameter_node_t *param = pm_required_parameter_node_create(parser, &name);
- pm_parameters_node_requireds_append(params, (pm_node_t *) param);
- } else {
- pm_required_parameter_node_t *param = pm_required_parameter_node_create(parser, &name);
- pm_parameters_node_posts_append(params, (pm_node_t *) param);
- }
-
- break;
- }
- case PM_TOKEN_LABEL: {
- if (!uses_parentheses) parser->in_keyword_arg = true;
- update_parameter_state(parser, &parser->current, &order);
- parser_lex(parser);
-
- pm_token_t name = parser->previous;
- pm_token_t local = name;
- local.end -= 1;
-
- pm_parser_parameter_name_check(parser, &local);
- pm_parser_local_add_token(parser, &local);
-
- switch (parser->current.type) {
- case PM_TOKEN_COMMA:
- case PM_TOKEN_PARENTHESIS_RIGHT:
- case PM_TOKEN_PIPE: {
- pm_node_t *param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name);
- pm_parameters_node_keywords_append(params, param);
- break;
- }
- case PM_TOKEN_SEMICOLON:
- case PM_TOKEN_NEWLINE: {
- if (uses_parentheses) {
- looping = false;
- break;
- }
-
- pm_node_t *param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name);
- pm_parameters_node_keywords_append(params, param);
- break;
- }
- default: {
- pm_node_t *param;
-
- if (token_begins_expression_p(parser->current.type)) {
- context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
- pm_constant_id_t old_param_name = parser->current_param_name;
- parser->current_param_name = pm_parser_constant_id_token(parser, &local);
- pm_node_t *value = parse_value_expression(parser, binding_power, false, PM_ERR_PARAMETER_NO_DEFAULT_KW);
- parser->current_param_name = old_param_name;
- context_pop(parser);
- param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
- }
- else {
- param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name);
- }
-
- pm_parameters_node_keywords_append(params, param);
-
- // If parsing the value of the parameter resulted in error recovery,
- // then we can put a missing node in its place and stop parsing the
- // parameters entirely now.
- if (parser->recovering) {
- looping = false;
- break;
- }
- }
- }
-
- parser->in_keyword_arg = false;
- break;
- }
- case PM_TOKEN_USTAR:
- case PM_TOKEN_STAR: {
- update_parameter_state(parser, &parser->current, &order);
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_token_t name;
-
- if (accept1(parser, PM_TOKEN_IDENTIFIER)) {
- name = parser->previous;
- pm_parser_parameter_name_check(parser, &name);
- pm_parser_local_add_token(parser, &name);
- } else {
- name = not_provided(parser);
-
- if (allows_forwarding_parameters) {
- pm_parser_local_add_token(parser, &operator);
- }
- }
-
- pm_node_t *param = (pm_node_t *) pm_rest_parameter_node_create(parser, &operator, &name);
- if (params->rest == NULL) {
- pm_parameters_node_rest_set(params, param);
- } else {
- pm_parser_err_node(parser, param, PM_ERR_PARAMETER_SPLAT_MULTI);
- pm_parameters_node_posts_append(params, param);
- }
-
- break;
- }
- case PM_TOKEN_STAR_STAR:
- case PM_TOKEN_USTAR_STAR: {
- update_parameter_state(parser, &parser->current, &order);
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *param;
-
- if (accept1(parser, PM_TOKEN_KEYWORD_NIL)) {
- param = (pm_node_t *) pm_no_keywords_parameter_node_create(parser, &operator, &parser->previous);
- } else {
- pm_token_t name;
-
- if (accept1(parser, PM_TOKEN_IDENTIFIER)) {
- name = parser->previous;
- pm_parser_parameter_name_check(parser, &name);
- pm_parser_local_add_token(parser, &name);
- } else {
- name = not_provided(parser);
-
- if (allows_forwarding_parameters) {
- pm_parser_local_add_token(parser, &operator);
- }
- }
-
- param = (pm_node_t *) pm_keyword_rest_parameter_node_create(parser, &operator, &name);
- }
-
- if (params->keyword_rest == NULL) {
- pm_parameters_node_keyword_rest_set(params, param);
- } else {
- pm_parser_err_node(parser, param, PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI);
- pm_parameters_node_posts_append(params, param);
- }
-
- break;
- }
- default:
- if (parser->previous.type == PM_TOKEN_COMMA) {
- if (allows_trailing_comma) {
- // If we get here, then we have a trailing comma in a
- // block parameter list.
- pm_node_t *param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
-
- if (params->rest == NULL) {
- pm_parameters_node_rest_set(params, param);
- } else {
- pm_parser_err_node(parser, (pm_node_t *) param, PM_ERR_PARAMETER_SPLAT_MULTI);
- pm_parameters_node_posts_append(params, (pm_node_t *) param);
- }
- } else {
- pm_parser_err_previous(parser, PM_ERR_PARAMETER_WILD_LOOSE_COMMA);
- }
- }
-
- looping = false;
- break;
- }
-
- if (looping && uses_parentheses) {
- accept1(parser, PM_TOKEN_NEWLINE);
- }
- } while (looping && accept1(parser, PM_TOKEN_COMMA));
-
- pm_do_loop_stack_pop(parser);
-
- // If we don't have any parameters, return `NULL` instead of an empty `ParametersNode`.
- if (params->base.location.start == params->base.location.end) {
- pm_node_destroy(parser, (pm_node_t *) params);
- return NULL;
- }
-
- return params;
-}
-
-/**
- * Parse any number of rescue clauses. This will form a linked list of if
- * nodes pointing to each other from the top.
- */
-static inline void
-parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, bool def_p) {
- pm_rescue_node_t *current = NULL;
-
- while (accept1(parser, PM_TOKEN_KEYWORD_RESCUE)) {
- pm_rescue_node_t *rescue = pm_rescue_node_create(parser, &parser->previous);
-
- switch (parser->current.type) {
- case PM_TOKEN_EQUAL_GREATER: {
- // Here we have an immediate => after the rescue keyword, in which case
- // we're going to have an empty list of exceptions to rescue (which
- // implies StandardError).
- parser_lex(parser);
- pm_rescue_node_operator_set(rescue, &parser->previous);
-
- pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
- reference = parse_target(parser, reference);
-
- pm_rescue_node_reference_set(rescue, reference);
- break;
- }
- case PM_TOKEN_NEWLINE:
- case PM_TOKEN_SEMICOLON:
- case PM_TOKEN_KEYWORD_THEN:
- // Here we have a terminator for the rescue keyword, in which case we're
- // going to just continue on.
- break;
- default: {
- if (token_begins_expression_p(parser->current.type) || match1(parser, PM_TOKEN_USTAR)) {
- // Here we have something that could be an exception expression, so
- // we'll attempt to parse it here and any others delimited by commas.
-
- do {
- pm_node_t *expression = parse_starred_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_RESCUE_EXPRESSION);
- pm_rescue_node_exceptions_append(rescue, expression);
-
- // If we hit a newline, then this is the end of the rescue expression. We
- // can continue on to parse the statements.
- if (match3(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_KEYWORD_THEN)) break;
-
- // If we hit a `=>` then we're going to parse the exception variable. Once
- // we've done that, we'll break out of the loop and parse the statements.
- if (accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
- pm_rescue_node_operator_set(rescue, &parser->previous);
-
- pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
- reference = parse_target(parser, reference);
-
- pm_rescue_node_reference_set(rescue, reference);
- break;
- }
- } while (accept1(parser, PM_TOKEN_COMMA));
- }
- }
- }
-
- if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- accept1(parser, PM_TOKEN_KEYWORD_THEN);
- } else {
- expect1(parser, PM_TOKEN_KEYWORD_THEN, PM_ERR_RESCUE_TERM);
- }
-
- if (!match3(parser, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- pm_statements_node_t *statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_DEF : PM_CONTEXT_RESCUE);
- if (statements) {
- pm_rescue_node_statements_set(rescue, statements);
- }
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
-
- if (current == NULL) {
- pm_begin_node_rescue_clause_set(parent_node, rescue);
- } else {
- pm_rescue_node_consequent_set(current, rescue);
- }
-
- current = rescue;
- }
-
- // The end node locations on rescue nodes will not be set correctly
- // since we won't know the end until we've found all consequent
- // clauses. This sets the end location on all rescues once we know it
- if (current) {
- const uint8_t *end_to_set = current->base.location.end;
- current = parent_node->rescue_clause;
- while (current) {
- current->base.location.end = end_to_set;
- current = current->consequent;
- }
- }
-
- if (accept1(parser, PM_TOKEN_KEYWORD_ELSE)) {
- pm_token_t else_keyword = parser->previous;
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
-
- pm_statements_node_t *else_statements = NULL;
- if (!match2(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_ENSURE)) {
- pm_accepts_block_stack_push(parser, true);
- else_statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_ELSE_DEF : PM_CONTEXT_RESCUE_ELSE);
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
-
- pm_else_node_t *else_clause = pm_else_node_create(parser, &else_keyword, else_statements, &parser->current);
- pm_begin_node_else_clause_set(parent_node, else_clause);
- }
-
- if (accept1(parser, PM_TOKEN_KEYWORD_ENSURE)) {
- pm_token_t ensure_keyword = parser->previous;
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
-
- pm_statements_node_t *ensure_statements = NULL;
- if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- ensure_statements = parse_statements(parser, def_p ? PM_CONTEXT_ENSURE_DEF : PM_CONTEXT_ENSURE);
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
-
- pm_ensure_node_t *ensure_clause = pm_ensure_node_create(parser, &ensure_keyword, ensure_statements, &parser->current);
- pm_begin_node_ensure_clause_set(parent_node, ensure_clause);
- }
-
- if (parser->current.type == PM_TOKEN_KEYWORD_END) {
- pm_begin_node_end_keyword_set(parent_node, &parser->current);
- } else {
- pm_token_t end_keyword = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- pm_begin_node_end_keyword_set(parent_node, &end_keyword);
- }
-}
-
-static inline pm_begin_node_t *
-parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements, bool def_p) {
- pm_token_t no_begin_token = not_provided(parser);
- pm_begin_node_t *begin_node = pm_begin_node_create(parser, &no_begin_token, statements);
- parse_rescues(parser, begin_node, def_p);
-
- // All nodes within a begin node are optional, so we look
- // for the earliest possible node that we can use to set
- // the BeginNode's start location
- const uint8_t *start = begin_node->base.location.start;
- if (begin_node->statements) {
- start = begin_node->statements->base.location.start;
- } else if (begin_node->rescue_clause) {
- start = begin_node->rescue_clause->base.location.start;
- } else if (begin_node->else_clause) {
- start = begin_node->else_clause->base.location.start;
- } else if (begin_node->ensure_clause) {
- start = begin_node->ensure_clause->base.location.start;
- }
-
- begin_node->base.location.start = start;
- return begin_node;
-}
-
-/**
- * Parse a list of parameters and local on a block definition.
- */
-static pm_block_parameters_node_t *
-parse_block_parameters(
- pm_parser_t *parser,
- bool allows_trailing_comma,
- const pm_token_t *opening,
- bool is_lambda_literal
-) {
- pm_parameters_node_t *parameters = NULL;
- if (!match1(parser, PM_TOKEN_SEMICOLON)) {
- parameters = parse_parameters(
- parser,
- is_lambda_literal ? PM_BINDING_POWER_DEFINED : PM_BINDING_POWER_INDEX,
- false,
- allows_trailing_comma,
- false
- );
- }
-
- pm_block_parameters_node_t *block_parameters = pm_block_parameters_node_create(parser, parameters, opening);
- if ((opening->type != PM_TOKEN_NOT_PROVIDED) && accept1(parser, PM_TOKEN_SEMICOLON)) {
- do {
- expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE);
- pm_parser_parameter_name_check(parser, &parser->previous);
- pm_parser_local_add_token(parser, &parser->previous);
-
- pm_block_local_variable_node_t *local = pm_block_local_variable_node_create(parser, &parser->previous);
- pm_block_parameters_node_append_local(block_parameters, local);
- } while (accept1(parser, PM_TOKEN_COMMA));
- }
-
- return block_parameters;
-}
-
-/**
- * Parse a block.
- */
-static pm_block_node_t *
-parse_block(pm_parser_t *parser) {
- pm_token_t opening = parser->previous;
- accept1(parser, PM_TOKEN_NEWLINE);
-
- pm_accepts_block_stack_push(parser, true);
- pm_parser_scope_push(parser, false);
- pm_block_parameters_node_t *block_parameters = NULL;
-
- if (accept1(parser, PM_TOKEN_PIPE)) {
- parser->current_scope->explicit_params = true;
- pm_token_t block_parameters_opening = parser->previous;
-
- if (match1(parser, PM_TOKEN_PIPE)) {
- block_parameters = pm_block_parameters_node_create(parser, NULL, &block_parameters_opening);
- parser->command_start = true;
- parser_lex(parser);
- } else {
- block_parameters = parse_block_parameters(parser, true, &block_parameters_opening, false);
- accept1(parser, PM_TOKEN_NEWLINE);
- parser->command_start = true;
- expect1(parser, PM_TOKEN_PIPE, PM_ERR_BLOCK_PARAM_PIPE_TERM);
- }
-
- pm_block_parameters_node_closing_set(block_parameters, &parser->previous);
- }
-
- uint32_t locals_body_index = 0;
-
- if (block_parameters) {
- locals_body_index = (uint32_t) parser->current_scope->locals.size;
- }
-
- accept1(parser, PM_TOKEN_NEWLINE);
- pm_node_t *statements = NULL;
-
- if (opening.type == PM_TOKEN_BRACE_LEFT) {
- if (!match1(parser, PM_TOKEN_BRACE_RIGHT)) {
- statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_BRACES);
- }
-
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE);
- } else {
- if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
- if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE)) {
- pm_accepts_block_stack_push(parser, true);
- statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_KEYWORDS);
- pm_accepts_block_stack_pop(parser);
- }
-
- if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
- }
- }
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END);
- }
-
- pm_node_t *parameters = (pm_node_t *) block_parameters;
- uint8_t maximum = parser->current_scope->numbered_parameters;
-
- if (parameters == NULL && (maximum > 0)) {
- parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = opening.start, .end = parser->previous.end }, maximum);
- locals_body_index = maximum;
- }
-
- pm_constant_id_list_t locals = parser->current_scope->locals;
- pm_parser_scope_pop(parser);
- pm_accepts_block_stack_pop(parser);
- return pm_block_node_create(parser, &locals, locals_body_index, &opening, parameters, statements, &parser->previous);
-}
-
-/**
- * Parse a list of arguments and their surrounding parentheses if they are
- * present. It returns true if it found any pieces of arguments (parentheses,
- * arguments, or blocks).
- */
-static bool
-parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_block, bool accepts_command_call) {
- bool found = false;
-
- if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
- found |= true;
- arguments->opening_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
-
- if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- arguments->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
- } else {
- pm_accepts_block_stack_push(parser, true);
- parse_arguments(parser, arguments, true, PM_TOKEN_PARENTHESIS_RIGHT);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_ARGUMENT_TERM_PAREN);
- pm_accepts_block_stack_pop(parser);
-
- arguments->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
- }
- } else if (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR, PM_TOKEN_UAMPERSAND)) && !match1(parser, PM_TOKEN_BRACE_LEFT)) {
- found |= true;
- pm_accepts_block_stack_push(parser, false);
-
- // If we get here, then the subsequent token cannot be used as an infix
- // operator. In this case we assume the subsequent token is part of an
- // argument to this method call.
- parse_arguments(parser, arguments, true, PM_TOKEN_EOF);
-
- // If we have done with the arguments and still not consumed the comma,
- // then we have a trailing comma where we need to check whether it is
- // allowed or not.
- if (parser->previous.type == PM_TOKEN_COMMA && !match1(parser, PM_TOKEN_SEMICOLON)) {
- pm_parser_err_previous(parser, PM_ERR_EXPECT_ARGUMENT);
- }
-
- pm_accepts_block_stack_pop(parser);
- }
-
- // If we're at the end of the arguments, we can now check if there is a block
- // node that starts with a {. If there is, then we can parse it and add it to
- // the arguments.
- if (accepts_block) {
- pm_block_node_t *block = NULL;
-
- if (accept1(parser, PM_TOKEN_BRACE_LEFT)) {
- found |= true;
- block = parse_block(parser);
- pm_arguments_validate_block(parser, arguments, block);
- } else if (pm_accepts_block_stack_p(parser) && accept1(parser, PM_TOKEN_KEYWORD_DO)) {
- found |= true;
- block = parse_block(parser);
- }
-
- if (block != NULL) {
- if (arguments->block == NULL) {
- arguments->block = (pm_node_t *) block;
- } else {
- pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_BLOCK_MULTI);
- if (arguments->arguments == NULL) {
- arguments->arguments = pm_arguments_node_create(parser);
- }
- pm_arguments_node_arguments_append(arguments->arguments, arguments->block);
- arguments->block = (pm_node_t *) block;
- }
- }
- }
-
- return found;
-}
-
-static inline pm_node_t *
-parse_predicate(pm_parser_t *parser, pm_binding_power_t binding_power, pm_context_t context, pm_token_t *then_keyword) {
- context_push(parser, PM_CONTEXT_PREDICATE);
- pm_diagnostic_id_t error_id = context == PM_CONTEXT_IF ? PM_ERR_CONDITIONAL_IF_PREDICATE : PM_ERR_CONDITIONAL_UNLESS_PREDICATE;
- pm_node_t *predicate = parse_value_expression(parser, binding_power, true, error_id);
-
- // Predicates are closed by a term, a "then", or a term and then a "then".
- bool predicate_closed = accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
-
- if (accept1(parser, PM_TOKEN_KEYWORD_THEN)) {
- predicate_closed = true;
- *then_keyword = parser->previous;
- }
-
- if (!predicate_closed) {
- pm_parser_err_current(parser, PM_ERR_CONDITIONAL_PREDICATE_TERM);
- }
-
- context_pop(parser);
- return predicate;
-}
-
-static inline pm_node_t *
-parse_conditional(pm_parser_t *parser, pm_context_t context) {
- pm_token_t keyword = parser->previous;
- pm_token_t then_keyword = not_provided(parser);
-
- pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, context, &then_keyword);
- pm_statements_node_t *statements = NULL;
-
- if (!match3(parser, PM_TOKEN_KEYWORD_ELSIF, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = parse_statements(parser, context);
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
-
- pm_token_t end_keyword = not_provided(parser);
- pm_node_t *parent = NULL;
-
- switch (context) {
- case PM_CONTEXT_IF:
- parent = (pm_node_t *) pm_if_node_create(parser, &keyword, predicate, &then_keyword, statements, NULL, &end_keyword);
- break;
- case PM_CONTEXT_UNLESS:
- parent = (pm_node_t *) pm_unless_node_create(parser, &keyword, predicate, &then_keyword, statements);
- break;
- default:
- assert(false && "unreachable");
- break;
- }
-
- pm_node_t *current = parent;
-
- // Parse any number of elsif clauses. This will form a linked list of if
- // nodes pointing to each other from the top.
- if (context == PM_CONTEXT_IF) {
- while (accept1(parser, PM_TOKEN_KEYWORD_ELSIF)) {
- pm_token_t elsif_keyword = parser->previous;
- pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, PM_CONTEXT_ELSIF, &then_keyword);
- pm_accepts_block_stack_push(parser, true);
- pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_ELSIF);
- pm_accepts_block_stack_pop(parser);
-
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
-
- pm_node_t *elsif = (pm_node_t *) pm_if_node_create(parser, &elsif_keyword, predicate, &then_keyword, statements, NULL, &end_keyword);
- ((pm_if_node_t *) current)->consequent = elsif;
- current = elsif;
- }
- }
-
- if (match1(parser, PM_TOKEN_KEYWORD_ELSE)) {
- parser_lex(parser);
- pm_token_t else_keyword = parser->previous;
-
- pm_accepts_block_stack_push(parser, true);
- pm_statements_node_t *else_statements = parse_statements(parser, PM_CONTEXT_ELSE);
- pm_accepts_block_stack_pop(parser);
-
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE);
-
- pm_else_node_t *else_node = pm_else_node_create(parser, &else_keyword, else_statements, &parser->previous);
-
- switch (context) {
- case PM_CONTEXT_IF:
- ((pm_if_node_t *) current)->consequent = (pm_node_t *) else_node;
- break;
- case PM_CONTEXT_UNLESS:
- ((pm_unless_node_t *) parent)->consequent = else_node;
- break;
- default:
- assert(false && "unreachable");
- break;
- }
- } else {
- // We should specialize this error message to refer to 'if' or 'unless' explicitly.
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM);
- }
-
- // Set the appropriate end location for all of the nodes in the subtree.
- switch (context) {
- case PM_CONTEXT_IF: {
- pm_node_t *current = parent;
- bool recursing = true;
-
- while (recursing) {
- switch (PM_NODE_TYPE(current)) {
- case PM_IF_NODE:
- pm_if_node_end_keyword_loc_set((pm_if_node_t *) current, &parser->previous);
- current = ((pm_if_node_t *) current)->consequent;
- recursing = current != NULL;
- break;
- case PM_ELSE_NODE:
- pm_else_node_end_keyword_loc_set((pm_else_node_t *) current, &parser->previous);
- recursing = false;
- break;
- default: {
- recursing = false;
- break;
- }
- }
- }
- break;
- }
- case PM_CONTEXT_UNLESS:
- pm_unless_node_end_keyword_loc_set((pm_unless_node_t *) parent, &parser->previous);
- break;
- default:
- assert(false && "unreachable");
- break;
- }
-
- return parent;
-}
-
-/**
- * This macro allows you to define a case statement for all of the keywords.
- * It's meant to be used in a switch statement.
- */
-#define PM_CASE_KEYWORD PM_TOKEN_KEYWORD___ENCODING__: case PM_TOKEN_KEYWORD___FILE__: case PM_TOKEN_KEYWORD___LINE__: \
- case PM_TOKEN_KEYWORD_ALIAS: case PM_TOKEN_KEYWORD_AND: case PM_TOKEN_KEYWORD_BEGIN: case PM_TOKEN_KEYWORD_BEGIN_UPCASE: \
- case PM_TOKEN_KEYWORD_BREAK: case PM_TOKEN_KEYWORD_CASE: case PM_TOKEN_KEYWORD_CLASS: case PM_TOKEN_KEYWORD_DEF: \
- case PM_TOKEN_KEYWORD_DEFINED: case PM_TOKEN_KEYWORD_DO: case PM_TOKEN_KEYWORD_DO_LOOP: case PM_TOKEN_KEYWORD_ELSE: \
- case PM_TOKEN_KEYWORD_ELSIF: case PM_TOKEN_KEYWORD_END: case PM_TOKEN_KEYWORD_END_UPCASE: case PM_TOKEN_KEYWORD_ENSURE: \
- case PM_TOKEN_KEYWORD_FALSE: case PM_TOKEN_KEYWORD_FOR: case PM_TOKEN_KEYWORD_IF: case PM_TOKEN_KEYWORD_IN: \
- case PM_TOKEN_KEYWORD_MODULE: case PM_TOKEN_KEYWORD_NEXT: case PM_TOKEN_KEYWORD_NIL: case PM_TOKEN_KEYWORD_NOT: \
- case PM_TOKEN_KEYWORD_OR: case PM_TOKEN_KEYWORD_REDO: case PM_TOKEN_KEYWORD_RESCUE: case PM_TOKEN_KEYWORD_RETRY: \
- case PM_TOKEN_KEYWORD_RETURN: case PM_TOKEN_KEYWORD_SELF: case PM_TOKEN_KEYWORD_SUPER: case PM_TOKEN_KEYWORD_THEN: \
- case PM_TOKEN_KEYWORD_TRUE: case PM_TOKEN_KEYWORD_UNDEF: case PM_TOKEN_KEYWORD_UNLESS: case PM_TOKEN_KEYWORD_UNTIL: \
- case PM_TOKEN_KEYWORD_WHEN: case PM_TOKEN_KEYWORD_WHILE: case PM_TOKEN_KEYWORD_YIELD
-
-/**
- * This macro allows you to define a case statement for all of the operators.
- * It's meant to be used in a switch statement.
- */
-#define PM_CASE_OPERATOR PM_TOKEN_AMPERSAND: case PM_TOKEN_BACKTICK: case PM_TOKEN_BANG_EQUAL: \
- case PM_TOKEN_BANG_TILDE: case PM_TOKEN_BANG: case PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL: \
- case PM_TOKEN_BRACKET_LEFT_RIGHT: case PM_TOKEN_CARET: case PM_TOKEN_EQUAL_EQUAL_EQUAL: case PM_TOKEN_EQUAL_EQUAL: \
- case PM_TOKEN_EQUAL_TILDE: case PM_TOKEN_GREATER_EQUAL: case PM_TOKEN_GREATER_GREATER: case PM_TOKEN_GREATER: \
- case PM_TOKEN_LESS_EQUAL_GREATER: case PM_TOKEN_LESS_EQUAL: case PM_TOKEN_LESS_LESS: case PM_TOKEN_LESS: \
- case PM_TOKEN_MINUS: case PM_TOKEN_PERCENT: case PM_TOKEN_PIPE: case PM_TOKEN_PLUS: case PM_TOKEN_SLASH: \
- case PM_TOKEN_STAR_STAR: case PM_TOKEN_STAR: case PM_TOKEN_TILDE: case PM_TOKEN_UAMPERSAND: case PM_TOKEN_UMINUS: \
- case PM_TOKEN_UMINUS_NUM: case PM_TOKEN_UPLUS: case PM_TOKEN_USTAR: case PM_TOKEN_USTAR_STAR
-
-/**
- * This macro allows you to define a case statement for all of the token types
- * that represent the beginning of nodes that are "primitives" in a pattern
- * matching expression.
- */
-#define PM_CASE_PRIMITIVE PM_TOKEN_INTEGER: case PM_TOKEN_INTEGER_IMAGINARY: case PM_TOKEN_INTEGER_RATIONAL: \
- case PM_TOKEN_INTEGER_RATIONAL_IMAGINARY: case PM_TOKEN_FLOAT: case PM_TOKEN_FLOAT_IMAGINARY: \
- case PM_TOKEN_FLOAT_RATIONAL: case PM_TOKEN_FLOAT_RATIONAL_IMAGINARY: case PM_TOKEN_SYMBOL_BEGIN: \
- case PM_TOKEN_REGEXP_BEGIN: case PM_TOKEN_BACKTICK: case PM_TOKEN_PERCENT_LOWER_X: case PM_TOKEN_PERCENT_LOWER_I: \
- case PM_TOKEN_PERCENT_LOWER_W: case PM_TOKEN_PERCENT_UPPER_I: case PM_TOKEN_PERCENT_UPPER_W: \
- case PM_TOKEN_STRING_BEGIN: case PM_TOKEN_KEYWORD_NIL: case PM_TOKEN_KEYWORD_SELF: case PM_TOKEN_KEYWORD_TRUE: \
- case PM_TOKEN_KEYWORD_FALSE: case PM_TOKEN_KEYWORD___FILE__: case PM_TOKEN_KEYWORD___LINE__: \
- case PM_TOKEN_KEYWORD___ENCODING__: case PM_TOKEN_MINUS_GREATER: case PM_TOKEN_HEREDOC_START: \
- case PM_TOKEN_UMINUS_NUM: case PM_TOKEN_CHARACTER_LITERAL
-
-/**
- * This macro allows you to define a case statement for all of the token types
- * that could begin a parameter.
- */
-#define PM_CASE_PARAMETER PM_TOKEN_UAMPERSAND: case PM_TOKEN_AMPERSAND: case PM_TOKEN_UDOT_DOT_DOT: \
- case PM_TOKEN_IDENTIFIER: case PM_TOKEN_LABEL: case PM_TOKEN_USTAR: case PM_TOKEN_STAR: case PM_TOKEN_STAR_STAR: \
- case PM_TOKEN_USTAR_STAR: case PM_TOKEN_CONSTANT: case PM_TOKEN_INSTANCE_VARIABLE: case PM_TOKEN_GLOBAL_VARIABLE: \
- case PM_TOKEN_CLASS_VARIABLE
-
-/**
- * This macro allows you to define a case statement for all of the nodes that
- * can be transformed into write targets.
- */
-#define PM_CASE_WRITABLE PM_CLASS_VARIABLE_READ_NODE: case PM_CONSTANT_PATH_NODE: \
- case PM_CONSTANT_READ_NODE: case PM_GLOBAL_VARIABLE_READ_NODE: case PM_LOCAL_VARIABLE_READ_NODE: \
- case PM_INSTANCE_VARIABLE_READ_NODE: case PM_MULTI_TARGET_NODE: case PM_BACK_REFERENCE_READ_NODE: \
- case PM_NUMBERED_REFERENCE_READ_NODE
-
-// Assert here that the flags are the same so that we can safely switch the type
-// of the node without having to move the flags.
-PM_STATIC_ASSERT(__LINE__, ((int) PM_STRING_FLAGS_FORCED_UTF8_ENCODING) == ((int) PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING), "Expected the flags to match.");
-
-/**
- * If the encoding was explicitly set through the lexing process, then we need
- * to potentially mark the string's flags to indicate how to encode it.
- */
-static inline pm_node_flags_t
-parse_unescaped_encoding(const pm_parser_t *parser) {
- if (parser->explicit_encoding != NULL) {
- if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) {
- return PM_STRING_FLAGS_FORCED_UTF8_ENCODING;
- } else if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) {
- return PM_STRING_FLAGS_FORCED_BINARY_ENCODING;
- }
- }
- return 0;
-}
-
-/**
- * Parse a node that is part of a string. If the subsequent tokens cannot be
- * parsed as a string part, then NULL is returned.
- */
-static pm_node_t *
-parse_string_part(pm_parser_t *parser) {
- switch (parser->current.type) {
- // Here the lexer has returned to us plain string content. In this case
- // we'll create a string node that has no opening or closing and return that
- // as the part. These kinds of parts look like:
- //
- // "aaa #{bbb} #@ccc ddd"
- // ^^^^ ^ ^^^^
- case PM_TOKEN_STRING_CONTENT: {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
-
- pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing);
- pm_node_flag_set(node, parse_unescaped_encoding(parser));
-
- parser_lex(parser);
- return node;
- }
- // Here the lexer has returned the beginning of an embedded expression. In
- // that case we'll parse the inner statements and return that as the part.
- // These kinds of parts look like:
- //
- // "aaa #{bbb} #@ccc ddd"
- // ^^^^^^
- case PM_TOKEN_EMBEXPR_BEGIN: {
- pm_lex_state_t state = parser->lex_state;
- int brace_nesting = parser->brace_nesting;
-
- parser->brace_nesting = 0;
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser_lex(parser);
-
- pm_token_t opening = parser->previous;
- pm_statements_node_t *statements = NULL;
-
- if (!match1(parser, PM_TOKEN_EMBEXPR_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = parse_statements(parser, PM_CONTEXT_EMBEXPR);
- pm_accepts_block_stack_pop(parser);
- }
-
- parser->brace_nesting = brace_nesting;
- lex_state_set(parser, state);
-
- expect1(parser, PM_TOKEN_EMBEXPR_END, PM_ERR_EMBEXPR_END);
- pm_token_t closing = parser->previous;
-
- return (pm_node_t *) pm_embedded_statements_node_create(parser, &opening, statements, &closing);
- }
-
- // Here the lexer has returned the beginning of an embedded variable.
- // In that case we'll parse the variable and create an appropriate node
- // for it and then return that node. These kinds of parts look like:
- //
- // "aaa #{bbb} #@ccc ddd"
- // ^^^^^
- case PM_TOKEN_EMBVAR: {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *variable;
-
- switch (parser->current.type) {
- // In this case a back reference is being interpolated. We'll
- // create a global variable read node.
- case PM_TOKEN_BACK_REFERENCE:
- parser_lex(parser);
- variable = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous);
- break;
- // In this case an nth reference is being interpolated. We'll
- // create a global variable read node.
- case PM_TOKEN_NUMBERED_REFERENCE:
- parser_lex(parser);
- variable = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous);
- break;
- // In this case a global variable is being interpolated. We'll
- // create a global variable read node.
- case PM_TOKEN_GLOBAL_VARIABLE:
- parser_lex(parser);
- variable = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous);
- break;
- // In this case an instance variable is being interpolated.
- // We'll create an instance variable read node.
- case PM_TOKEN_INSTANCE_VARIABLE:
- parser_lex(parser);
- variable = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous);
- break;
- // In this case a class variable is being interpolated. We'll
- // create a class variable read node.
- case PM_TOKEN_CLASS_VARIABLE:
- parser_lex(parser);
- variable = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous);
- break;
- // We can hit here if we got an invalid token. In that case
- // we'll not attempt to lex this token and instead just return a
- // missing node.
- default:
- expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_EMBVAR_INVALID);
- variable = (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
- break;
- }
-
- return (pm_node_t *) pm_embedded_variable_node_create(parser, &operator, variable);
- }
- default:
- parser_lex(parser);
- pm_parser_err_previous(parser, PM_ERR_CANNOT_PARSE_STRING_PART);
- return NULL;
- }
-}
-
-static pm_node_t *
-parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_state) {
- pm_token_t opening = parser->previous;
-
- if (lex_mode->mode != PM_LEX_STRING) {
- if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state);
-
- switch (parser->current.type) {
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_INSTANCE_VARIABLE:
- case PM_TOKEN_METHOD_NAME:
- case PM_TOKEN_CLASS_VARIABLE:
- case PM_TOKEN_GLOBAL_VARIABLE:
- case PM_TOKEN_NUMBERED_REFERENCE:
- case PM_TOKEN_BACK_REFERENCE:
- case PM_CASE_KEYWORD:
- parser_lex(parser);
- break;
- case PM_CASE_OPERATOR:
- lex_state_set(parser, next_state == PM_LEX_STATE_NONE ? PM_LEX_STATE_ENDFN : next_state);
- parser_lex(parser);
- break;
- default:
- expect2(parser, PM_TOKEN_IDENTIFIER, PM_TOKEN_METHOD_NAME, PM_ERR_SYMBOL_INVALID);
- break;
- }
-
- pm_token_t closing = not_provided(parser);
- pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing);
-
- pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end);
- return (pm_node_t *) symbol;
- }
-
- if (lex_mode->as.string.interpolation) {
- // If we have the end of the symbol, then we can return an empty symbol.
- if (match1(parser, PM_TOKEN_STRING_END)) {
- if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state);
- parser_lex(parser);
-
- pm_token_t content = not_provided(parser);
- pm_token_t closing = parser->previous;
- return (pm_node_t *) pm_symbol_node_create(parser, &opening, &content, &closing);
- }
-
- // Now we can parse the first part of the symbol.
- pm_node_t *part = parse_string_part(parser);
-
- // If we got a string part, then it's possible that we could transform
- // what looks like an interpolated symbol into a regular symbol.
- if (part && PM_NODE_TYPE_P(part, PM_STRING_NODE) && match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state);
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_INTERPOLATED);
-
- return (pm_node_t *) pm_string_node_to_symbol_node(parser, (pm_string_node_t *) part, &opening, &parser->previous);
- }
-
- // Create a node_list first. We'll use this to check if it should be an
- // InterpolatedSymbolNode or a SymbolNode.
- pm_node_list_t node_list = { 0 };
- if (part) pm_node_list_append(&node_list, part);
-
- while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- if ((part = parse_string_part(parser)) != NULL) {
- pm_node_list_append(&node_list, part);
- }
- }
-
- if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state);
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_SYMBOL_TERM_INTERPOLATED);
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_INTERPOLATED);
- }
-
- return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &node_list, &parser->previous);
- }
-
- pm_token_t content;
- pm_string_t unescaped;
-
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- content = parser->current;
- unescaped = parser->current_string;
- parser_lex(parser);
-
- // If we have two string contents in a row, then the content of this
- // symbol is split because of heredoc contents. This looks like:
- //
- // <<A; :'a
- // A
- // b'
- //
- // In this case, the best way we have to represent this is as an
- // interpolated string node, so that's what we'll do here.
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- pm_node_list_t parts = { 0 };
- pm_token_t bounds = not_provided(parser);
-
- pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &content, &bounds, &unescaped);
- pm_node_list_append(&parts, part);
-
- part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &parser->current, &bounds, &parser->current_string);
- pm_node_list_append(&parts, part);
-
- if (next_state != PM_LEX_STATE_NONE) {
- lex_state_set(parser, next_state);
- }
-
- parser_lex(parser);
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
- return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
- }
- } else {
- content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end };
- pm_string_shared_init(&unescaped, content.start, content.end);
- }
-
- if (next_state != PM_LEX_STATE_NONE) {
- lex_state_set(parser, next_state);
- }
-
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_SYMBOL_TERM_DYNAMIC);
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
- }
- return (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
-}
-
-/**
- * Parse an argument to undef which can either be a bare word, a symbol, a
- * constant, or an interpolated symbol.
- */
-static inline pm_node_t *
-parse_undef_argument(pm_parser_t *parser) {
- switch (parser->current.type) {
- case PM_CASE_KEYWORD:
- case PM_CASE_OPERATOR:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_METHOD_NAME: {
- parser_lex(parser);
-
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing);
-
- pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end);
- return (pm_node_t *) symbol;
- }
- case PM_TOKEN_SYMBOL_BEGIN: {
- pm_lex_mode_t lex_mode = *parser->lex_modes.current;
- parser_lex(parser);
-
- return parse_symbol(parser, &lex_mode, PM_LEX_STATE_NONE);
- }
- default:
- pm_parser_err_current(parser, PM_ERR_UNDEF_ARGUMENT);
- return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
- }
-}
-
-/**
- * Parse an argument to alias which can either be a bare word, a symbol, an
- * interpolated symbol or a global variable. If this is the first argument, then
- * we need to set the lex state to PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM
- * between the first and second arguments.
- */
-static inline pm_node_t *
-parse_alias_argument(pm_parser_t *parser, bool first) {
- switch (parser->current.type) {
- case PM_CASE_OPERATOR:
- case PM_CASE_KEYWORD:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_METHOD_NAME: {
- if (first) {
- lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM);
- }
-
- parser_lex(parser);
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing);
-
- pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end);
- return (pm_node_t *) symbol;
- }
- case PM_TOKEN_SYMBOL_BEGIN: {
- pm_lex_mode_t lex_mode = *parser->lex_modes.current;
- parser_lex(parser);
-
- return parse_symbol(parser, &lex_mode, first ? PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM : PM_LEX_STATE_NONE);
- }
- case PM_TOKEN_BACK_REFERENCE:
- parser_lex(parser);
- return (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous);
- case PM_TOKEN_NUMBERED_REFERENCE:
- parser_lex(parser);
- return (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous);
- case PM_TOKEN_GLOBAL_VARIABLE:
- parser_lex(parser);
- return (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous);
- default:
- pm_parser_err_current(parser, PM_ERR_ALIAS_ARGUMENT);
- return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
- }
-}
-
-/**
- * Return true if any of the visible scopes to the current context are using
- * numbered parameters.
- */
-static bool
-outer_scope_using_numbered_parameters_p(pm_parser_t *parser) {
- for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) {
- if (scope->numbered_parameters) return true;
- }
-
- return false;
-}
-
-/**
- * Parse an identifier into either a local variable read or a call.
- */
-static pm_node_t *
-parse_variable_call(pm_parser_t *parser) {
- pm_node_flags_t flags = 0;
-
- if (!match1(parser, PM_TOKEN_PARENTHESIS_LEFT) && (parser->previous.end[-1] != '!') && (parser->previous.end[-1] != '?')) {
- int depth;
- if ((depth = pm_parser_local_depth(parser, &parser->previous)) != -1) {
- return (pm_node_t *) pm_local_variable_read_node_create(parser, &parser->previous, (uint32_t) depth);
- }
-
- if (!parser->current_scope->closed && pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end)) {
- // Now that we know we have a numbered parameter, we need to check
- // if it's allowed in this context. If it is, then we will create a
- // local variable read. If it's not, then we'll create a normal call
- // node but add an error.
- if (parser->current_scope->explicit_params) {
- pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED);
- } else if (outer_scope_using_numbered_parameters_p(parser)) {
- pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE);
- } else {
- // Indicate that this scope is using numbered params so that child
- // scopes cannot.
- uint8_t number = parser->previous.start[1];
-
- // We subtract the value for the character '0' to get the actual
- // integer value of the number (only _1 through _9 are valid)
- uint8_t numbered_parameters = (uint8_t) (number - '0');
- if (numbered_parameters > parser->current_scope->numbered_parameters) {
- parser->current_scope->numbered_parameters = numbered_parameters;
- pm_parser_numbered_parameters_set(parser, numbered_parameters);
- }
-
- // When you use a numbered parameter, it implies the existence
- // of all of the locals that exist before it. For example,
- // referencing _2 means that _1 must exist. Therefore here we
- // loop through all of the possibilities and add them into the
- // constant pool.
- uint8_t current = '1';
- uint8_t *value;
-
- while (current < number) {
- value = malloc(2);
- value[0] = '_';
- value[1] = current++;
- pm_parser_local_add_owned(parser, value, 2);
- }
-
- // Now we can add the actual token that is being used. For
- // this one we can add a shared version since it is directly
- // referenced in the source.
- pm_parser_local_add_token(parser, &parser->previous);
- return (pm_node_t *) pm_local_variable_read_node_create(parser, &parser->previous, 0);
- }
- }
-
- flags |= PM_CALL_NODE_FLAGS_VARIABLE_CALL;
- }
-
- pm_call_node_t *node = pm_call_node_variable_call_create(parser, &parser->previous);
- pm_node_flag_set((pm_node_t *)node, flags);
-
- return (pm_node_t *) node;
-}
-
-/**
- * Parse the method definition name based on the current token available on the
- * parser. If it does not match a valid method definition name, then a missing
- * token is returned.
- */
-static inline pm_token_t
-parse_method_definition_name(pm_parser_t *parser) {
- switch (parser->current.type) {
- case PM_CASE_KEYWORD:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_METHOD_NAME:
- parser_lex(parser);
- return parser->previous;
- case PM_TOKEN_IDENTIFIER:
- pm_refute_numbered_parameter(parser, parser->current.start, parser->current.end);
- parser_lex(parser);
- return parser->previous;
- case PM_CASE_OPERATOR:
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- parser_lex(parser);
- return parser->previous;
- default:
- return (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->current.start, .end = parser->current.end };
- }
-}
-
-static void
-parse_heredoc_dedent_string(pm_string_t *string, size_t common_whitespace) {
- // Get a reference to the string struct that is being held by the string
- // node. This is the value we're going to actually manipulate.
- pm_string_ensure_owned(string);
-
- // Now get the bounds of the existing string. We'll use this as a
- // destination to move bytes into. We'll also use it for bounds checking
- // since we don't require that these strings be null terminated.
- size_t dest_length = pm_string_length(string);
- const uint8_t *source_cursor = (uint8_t *) string->source;
- const uint8_t *source_end = source_cursor + dest_length;
-
- // We're going to move bytes backward in the string when we get leading
- // whitespace, so we'll maintain a pointer to the current position in the
- // string that we're writing to.
- size_t trimmed_whitespace = 0;
-
- // While we haven't reached the amount of common whitespace that we need to
- // trim and we haven't reached the end of the string, we'll keep trimming
- // whitespace. Trimming in this context means skipping over these bytes such
- // that they aren't copied into the new string.
- while ((source_cursor < source_end) && pm_char_is_inline_whitespace(*source_cursor) && trimmed_whitespace < common_whitespace) {
- if (*source_cursor == '\t') {
- trimmed_whitespace = (trimmed_whitespace / PM_TAB_WHITESPACE_SIZE + 1) * PM_TAB_WHITESPACE_SIZE;
- if (trimmed_whitespace > common_whitespace) break;
- } else {
- trimmed_whitespace++;
- }
-
- source_cursor++;
- dest_length--;
- }
-
- memmove((uint8_t *) string->source, source_cursor, (size_t) (source_end - source_cursor));
- string->length = dest_length;
-}
-
-/**
- * Take a heredoc node that is indented by a ~ and trim the leading whitespace.
- */
-static void
-parse_heredoc_dedent(pm_parser_t *parser, pm_node_list_t *nodes, size_t common_whitespace) {
- // The next node should be dedented if it's the first node in the list or if
- // if follows a string node.
- bool dedent_next = true;
-
- // Iterate over all nodes, and trim whitespace accordingly. We're going to
- // keep around two indices: a read and a write. If we end up trimming all of
- // the whitespace from a node, then we'll drop it from the list entirely.
- size_t write_index = 0;
-
- for (size_t read_index = 0; read_index < nodes->size; read_index++) {
- pm_node_t *node = nodes->nodes[read_index];
-
- // We're not manipulating child nodes that aren't strings. In this case
- // we'll skip past it and indicate that the subsequent node should not
- // be dedented.
- if (!PM_NODE_TYPE_P(node, PM_STRING_NODE)) {
- nodes->nodes[write_index++] = node;
- dedent_next = false;
- continue;
- }
-
- pm_string_node_t *string_node = ((pm_string_node_t *) node);
- if (dedent_next) {
- parse_heredoc_dedent_string(&string_node->unescaped, common_whitespace);
- }
-
- if (string_node->unescaped.length == 0) {
- pm_node_destroy(parser, node);
- } else {
- nodes->nodes[write_index++] = node;
- }
-
- // We always dedent the next node if it follows a string node.
- dedent_next = true;
- }
-
- nodes->size = write_index;
-}
-
-static pm_node_t *
-parse_pattern(pm_parser_t *parser, bool top_pattern, pm_diagnostic_id_t diag_id);
-
-/**
- * Accept any number of constants joined by :: delimiters.
- */
-static pm_node_t *
-parse_pattern_constant_path(pm_parser_t *parser, pm_node_t *node) {
- // Now, if there are any :: operators that follow, parse them as constant
- // path nodes.
- while (accept1(parser, PM_TOKEN_COLON_COLON)) {
- pm_token_t delimiter = parser->previous;
- expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
-
- pm_node_t *child = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous);
- node = (pm_node_t *)pm_constant_path_node_create(parser, node, &delimiter, child);
- }
-
- // If there is a [ or ( that follows, then this is part of a larger pattern
- // expression. We'll parse the inner pattern here, then modify the returned
- // inner pattern with our constant path attached.
- if (!match2(parser, PM_TOKEN_BRACKET_LEFT, PM_TOKEN_PARENTHESIS_LEFT)) {
- return node;
- }
-
- pm_token_t opening;
- pm_token_t closing;
- pm_node_t *inner = NULL;
-
- if (accept1(parser, PM_TOKEN_BRACKET_LEFT)) {
- opening = parser->previous;
- accept1(parser, PM_TOKEN_NEWLINE);
-
- if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
- inner = parse_pattern(parser, true, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET);
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
- }
-
- closing = parser->previous;
- } else {
- parser_lex(parser);
- opening = parser->previous;
-
- if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- inner = parse_pattern(parser, true, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
- }
-
- closing = parser->previous;
- }
-
- if (!inner) {
- // If there was no inner pattern, then we have something like Foo() or
- // Foo[]. In that case we'll create an array pattern with no requireds.
- return (pm_node_t *) pm_array_pattern_node_constant_create(parser, node, &opening, &closing);
- }
-
- // Now that we have the inner pattern, check to see if it's an array, find,
- // or hash pattern. If it is, then we'll attach our constant path to it if
- // it doesn't already have a constant. If it's not one of those node types
- // or it does have a constant, then we'll create an array pattern.
- switch (PM_NODE_TYPE(inner)) {
- case PM_ARRAY_PATTERN_NODE: {
- pm_array_pattern_node_t *pattern_node = (pm_array_pattern_node_t *) inner;
-
- if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) {
- pattern_node->base.location.start = node->location.start;
- pattern_node->base.location.end = closing.end;
-
- pattern_node->constant = node;
- pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing);
-
- return (pm_node_t *) pattern_node;
- }
-
- break;
- }
- case PM_FIND_PATTERN_NODE: {
- pm_find_pattern_node_t *pattern_node = (pm_find_pattern_node_t *) inner;
-
- if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) {
- pattern_node->base.location.start = node->location.start;
- pattern_node->base.location.end = closing.end;
-
- pattern_node->constant = node;
- pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing);
-
- return (pm_node_t *) pattern_node;
- }
-
- break;
- }
- case PM_HASH_PATTERN_NODE: {
- pm_hash_pattern_node_t *pattern_node = (pm_hash_pattern_node_t *) inner;
-
- if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) {
- pattern_node->base.location.start = node->location.start;
- pattern_node->base.location.end = closing.end;
-
- pattern_node->constant = node;
- pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing);
-
- return (pm_node_t *) pattern_node;
- }
-
- break;
- }
- default:
- break;
- }
-
- // If we got here, then we didn't return one of the inner patterns by
- // attaching its constant. In this case we'll create an array pattern and
- // attach our constant to it.
- pm_array_pattern_node_t *pattern_node = pm_array_pattern_node_constant_create(parser, node, &opening, &closing);
- pm_array_pattern_node_requireds_append(pattern_node, inner);
- return (pm_node_t *) pattern_node;
-}
-
-/**
- * Parse a rest pattern.
- */
-static pm_splat_node_t *
-parse_pattern_rest(pm_parser_t *parser) {
- assert(parser->previous.type == PM_TOKEN_USTAR);
- pm_token_t operator = parser->previous;
- pm_node_t *name = NULL;
-
- // Rest patterns don't necessarily have a name associated with them. So we
- // will check for that here. If they do, then we'll add it to the local table
- // since this pattern will cause it to become a local variable.
- if (accept1(parser, PM_TOKEN_IDENTIFIER)) {
- pm_token_t identifier = parser->previous;
- pm_parser_local_add_token(parser, &identifier);
- name = (pm_node_t *) pm_local_variable_target_node_create(parser, &identifier);
- }
-
- // Finally we can return the created node.
- return pm_splat_node_create(parser, &operator, name);
-}
-
-/**
- * Parse a keyword rest node.
- */
-static pm_node_t *
-parse_pattern_keyword_rest(pm_parser_t *parser) {
- assert(parser->current.type == PM_TOKEN_USTAR_STAR);
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *value = NULL;
-
- if (accept1(parser, PM_TOKEN_KEYWORD_NIL)) {
- return (pm_node_t *) pm_no_keywords_parameter_node_create(parser, &operator, &parser->previous);
- }
-
- if (accept1(parser, PM_TOKEN_IDENTIFIER)) {
- pm_parser_local_add_token(parser, &parser->previous);
- value = (pm_node_t *) pm_local_variable_target_node_create(parser, &parser->previous);
- }
-
- return (pm_node_t *) pm_assoc_splat_node_create(parser, value, &operator);
-}
-
-/**
- * Parse a hash pattern.
- */
-static pm_hash_pattern_node_t *
-parse_pattern_hash(pm_parser_t *parser, pm_node_t *first_assoc) {
- pm_node_list_t assocs = { 0 };
- pm_node_t *rest = NULL;
-
- switch (PM_NODE_TYPE(first_assoc)) {
- case PM_ASSOC_NODE: {
- if (!match7(parser, PM_TOKEN_COMMA, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- // Here we have a value for the first assoc in the list, so we will
- // parse it now and update the first assoc.
- pm_node_t *value = parse_pattern(parser, false, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY);
-
- pm_assoc_node_t *assoc = (pm_assoc_node_t *) first_assoc;
- assoc->base.location.end = value->location.end;
- assoc->value = value;
- } else {
- pm_node_t *key = ((pm_assoc_node_t *) first_assoc)->key;
-
- if (PM_NODE_TYPE_P(key, PM_SYMBOL_NODE)) {
- const pm_location_t *value_loc = &((pm_symbol_node_t *) key)->value_loc;
- pm_parser_local_add_location(parser, value_loc->start, value_loc->end);
- }
- }
-
- pm_node_list_append(&assocs, first_assoc);
- break;
- }
- case PM_ASSOC_SPLAT_NODE:
- case PM_NO_KEYWORDS_PARAMETER_NODE:
- rest = first_assoc;
- break;
- default:
- assert(false);
- break;
- }
-
- // If there are any other assocs, then we'll parse them now.
- while (accept1(parser, PM_TOKEN_COMMA)) {
- // Here we need to break to support trailing commas.
- if (match6(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- break;
- }
-
- if (match1(parser, PM_TOKEN_USTAR_STAR)) {
- pm_node_t *assoc = parse_pattern_keyword_rest(parser);
-
- if (rest == NULL) {
- rest = assoc;
- } else {
- pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST);
- pm_node_list_append(&assocs, assoc);
- }
- } else {
- expect1(parser, PM_TOKEN_LABEL, PM_ERR_PATTERN_LABEL_AFTER_COMMA);
- pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous);
- pm_node_t *value = NULL;
-
- if (!match7(parser, PM_TOKEN_COMMA, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- value = parse_pattern(parser, false, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY);
- } else {
- const pm_location_t *value_loc = &((pm_symbol_node_t *) key)->value_loc;
- pm_parser_local_add_location(parser, value_loc->start, value_loc->end);
- }
-
- pm_token_t operator = not_provided(parser);
- pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
-
- if (rest != NULL) {
- pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST);
- }
-
- pm_node_list_append(&assocs, assoc);
- }
- }
-
- pm_hash_pattern_node_t *node = pm_hash_pattern_node_node_list_create(parser, &assocs, rest);
- free(assocs.nodes);
-
- return node;
-}
-
-/**
- * Parse a pattern expression primitive.
- */
-static pm_node_t *
-parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
- switch (parser->current.type) {
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_METHOD_NAME: {
- parser_lex(parser);
- pm_token_t name = parser->previous;
- int depth = pm_parser_local_depth(parser, &name);
- if (depth < 0) {
- depth = 0;
- pm_parser_local_add_token(parser, &name);
- }
- return (pm_node_t *) pm_local_variable_target_node_create_depth(parser, &name, (uint32_t) depth);
- }
- case PM_TOKEN_BRACKET_LEFT_ARRAY: {
- pm_token_t opening = parser->current;
- parser_lex(parser);
-
- if (accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
- // If we have an empty array pattern, then we'll just return a new
- // array pattern node.
- return (pm_node_t *)pm_array_pattern_node_empty_create(parser, &opening, &parser->previous);
- }
-
- // Otherwise, we'll parse the inner pattern, then deal with it depending
- // on the type it returns.
- pm_node_t *inner = parse_pattern(parser, true, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET);
-
- accept1(parser, PM_TOKEN_NEWLINE);
-
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
- pm_token_t closing = parser->previous;
-
- switch (PM_NODE_TYPE(inner)) {
- case PM_ARRAY_PATTERN_NODE: {
- pm_array_pattern_node_t *pattern_node = (pm_array_pattern_node_t *) inner;
- if (pattern_node->opening_loc.start == NULL) {
- pattern_node->base.location.start = opening.start;
- pattern_node->base.location.end = closing.end;
-
- pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing);
-
- return (pm_node_t *) pattern_node;
- }
-
- break;
- }
- case PM_FIND_PATTERN_NODE: {
- pm_find_pattern_node_t *pattern_node = (pm_find_pattern_node_t *) inner;
- if (pattern_node->opening_loc.start == NULL) {
- pattern_node->base.location.start = opening.start;
- pattern_node->base.location.end = closing.end;
-
- pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing);
-
- return (pm_node_t *) pattern_node;
- }
-
- break;
- }
- default:
- break;
- }
-
- pm_array_pattern_node_t *node = pm_array_pattern_node_empty_create(parser, &opening, &closing);
- pm_array_pattern_node_requireds_append(node, inner);
- return (pm_node_t *) node;
- }
- case PM_TOKEN_BRACE_LEFT: {
- bool previous_pattern_matching_newlines = parser->pattern_matching_newlines;
- parser->pattern_matching_newlines = false;
-
- pm_hash_pattern_node_t *node;
- pm_token_t opening = parser->current;
- parser_lex(parser);
-
- if (accept1(parser, PM_TOKEN_BRACE_RIGHT)) {
- // If we have an empty hash pattern, then we'll just return a new hash
- // pattern node.
- node = pm_hash_pattern_node_empty_create(parser, &opening, &parser->previous);
- } else {
- pm_node_t *first_assoc;
-
- switch (parser->current.type) {
- case PM_TOKEN_LABEL: {
- parser_lex(parser);
-
- pm_symbol_node_t *key = pm_symbol_node_label_create(parser, &parser->previous);
- pm_token_t operator = not_provided(parser);
-
- first_assoc = (pm_node_t *) pm_assoc_node_create(parser, (pm_node_t *) key, &operator, NULL);
- break;
- }
- case PM_TOKEN_USTAR_STAR:
- first_assoc = parse_pattern_keyword_rest(parser);
- break;
- case PM_TOKEN_STRING_BEGIN: {
- pm_node_t *key = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_HASH_KEY);
- pm_token_t operator = not_provided(parser);
-
- if (!pm_symbol_node_label_p(key)) {
- pm_parser_err_node(parser, key, PM_ERR_PATTERN_HASH_KEY_LABEL);
- }
-
- first_assoc = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, NULL);
- break;
- }
- default: {
- parser_lex(parser);
- pm_parser_err_previous(parser, PM_ERR_PATTERN_HASH_KEY);
-
- pm_missing_node_t *key = pm_missing_node_create(parser, parser->previous.start, parser->previous.end);
- pm_token_t operator = not_provided(parser);
-
- first_assoc = (pm_node_t *) pm_assoc_node_create(parser, (pm_node_t *) key, &operator, NULL);
- break;
- }
- }
-
- node = parse_pattern_hash(parser, first_assoc);
-
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE);
- pm_token_t closing = parser->previous;
-
- node->base.location.start = opening.start;
- node->base.location.end = closing.end;
-
- node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing);
- }
-
- parser->pattern_matching_newlines = previous_pattern_matching_newlines;
- return (pm_node_t *) node;
- }
- case PM_TOKEN_UDOT_DOT:
- case PM_TOKEN_UDOT_DOT_DOT: {
- pm_token_t operator = parser->current;
- parser_lex(parser);
-
- // Since we have a unary range operator, we need to parse the subsequent
- // expression as the right side of the range.
- switch (parser->current.type) {
- case PM_CASE_PRIMITIVE: {
- pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
- return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
- }
- default: {
- pm_parser_err_token(parser, &operator, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
- pm_node_t *right = (pm_node_t *) pm_missing_node_create(parser, operator.start, operator.end);
- return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
- }
- }
- }
- case PM_CASE_PRIMITIVE: {
- pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, false, diag_id);
-
- // Now that we have a primitive, we need to check if it's part of a range.
- if (accept2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) {
- pm_token_t operator = parser->previous;
-
- // Now that we have the operator, we need to check if this is followed
- // by another expression. If it is, then we will create a full range
- // node. Otherwise, we'll create an endless range.
- switch (parser->current.type) {
- case PM_CASE_PRIMITIVE: {
- pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
- return (pm_node_t *) pm_range_node_create(parser, node, &operator, right);
- }
- default:
- return (pm_node_t *) pm_range_node_create(parser, node, &operator, NULL);
- }
- }
-
- return node;
- }
- case PM_TOKEN_CARET: {
- parser_lex(parser);
- pm_token_t operator = parser->previous;
-
- // At this point we have a pin operator. We need to check the subsequent
- // expression to determine if it's a variable or an expression.
- switch (parser->current.type) {
- case PM_TOKEN_IDENTIFIER: {
- parser_lex(parser);
- pm_node_t *variable = (pm_node_t *) pm_local_variable_read_node_create(parser, &parser->previous, 0);
-
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- case PM_TOKEN_INSTANCE_VARIABLE: {
- parser_lex(parser);
- pm_node_t *variable = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous);
-
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- case PM_TOKEN_CLASS_VARIABLE: {
- parser_lex(parser);
- pm_node_t *variable = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous);
-
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- case PM_TOKEN_GLOBAL_VARIABLE: {
- parser_lex(parser);
- pm_node_t *variable = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous);
-
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- case PM_TOKEN_NUMBERED_REFERENCE: {
- parser_lex(parser);
- pm_node_t *variable = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous);
-
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- case PM_TOKEN_BACK_REFERENCE: {
- parser_lex(parser);
- pm_node_t *variable = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous);
-
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- case PM_TOKEN_PARENTHESIS_LEFT: {
- bool previous_pattern_matching_newlines = parser->pattern_matching_newlines;
- parser->pattern_matching_newlines = false;
-
- pm_token_t lparen = parser->current;
- parser_lex(parser);
-
- pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN);
- parser->pattern_matching_newlines = previous_pattern_matching_newlines;
-
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
- return (pm_node_t *) pm_pinned_expression_node_create(parser, expression, &operator, &lparen, &parser->previous);
- }
- default: {
- // If we get here, then we have a pin operator followed by something
- // not understood. We'll create a missing node and return that.
- pm_parser_err_token(parser, &operator, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN);
- pm_node_t *variable = (pm_node_t *) pm_missing_node_create(parser, operator.start, operator.end);
- return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable);
- }
- }
- }
- case PM_TOKEN_UCOLON_COLON: {
- pm_token_t delimiter = parser->current;
- parser_lex(parser);
-
- expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
- pm_node_t *child = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous);
- pm_constant_path_node_t *node = pm_constant_path_node_create(parser, NULL, &delimiter, child);
-
- return parse_pattern_constant_path(parser, (pm_node_t *)node);
- }
- case PM_TOKEN_CONSTANT: {
- pm_token_t constant = parser->current;
- parser_lex(parser);
-
- pm_node_t *node = (pm_node_t *) pm_constant_read_node_create(parser, &constant);
- return parse_pattern_constant_path(parser, node);
- }
- default:
- pm_parser_err_current(parser, diag_id);
- return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
- }
-}
-
-/**
- * Parse any number of primitives joined by alternation and ended optionally by
- * assignment.
- */
-static pm_node_t *
-parse_pattern_primitives(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
- pm_node_t *node = NULL;
-
- do {
- pm_token_t operator = parser->previous;
-
- switch (parser->current.type) {
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_BRACKET_LEFT_ARRAY:
- case PM_TOKEN_BRACE_LEFT:
- case PM_TOKEN_CARET:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_UCOLON_COLON:
- case PM_TOKEN_UDOT_DOT:
- case PM_TOKEN_UDOT_DOT_DOT:
- case PM_CASE_PRIMITIVE: {
- if (node == NULL) {
- node = parse_pattern_primitive(parser, diag_id);
- } else {
- pm_node_t *right = parse_pattern_primitive(parser, PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE);
- node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator);
- }
-
- break;
- }
- case PM_TOKEN_PARENTHESIS_LEFT: {
- parser_lex(parser);
- if (node != NULL) {
- pm_node_destroy(parser, node);
- }
- node = parse_pattern(parser, false, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
-
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
- break;
- }
- default: {
- pm_parser_err_current(parser, diag_id);
- pm_node_t *right = (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
-
- if (node == NULL) {
- node = right;
- } else {
- node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator);
- }
-
- break;
- }
- }
- } while (accept1(parser, PM_TOKEN_PIPE));
-
- // If we have an =>, then we are assigning this pattern to a variable.
- // In this case we should create an assignment node.
- while (accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
- pm_token_t operator = parser->previous;
-
- expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_PATTERN_IDENT_AFTER_HROCKET);
- pm_token_t identifier = parser->previous;
- int depth = pm_parser_local_depth(parser, &identifier);
- if (depth < 0) {
- depth = 0;
- pm_parser_local_add_token(parser, &identifier);
- }
-
- pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create_depth(parser, &identifier, (uint32_t) depth);
- node = (pm_node_t *) pm_capture_pattern_node_create(parser, node, target, &operator);
- }
-
- return node;
-}
-
-/**
- * Parse a pattern matching expression.
- */
-static pm_node_t *
-parse_pattern(pm_parser_t *parser, bool top_pattern, pm_diagnostic_id_t diag_id) {
- pm_node_t *node = NULL;
-
- bool leading_rest = false;
- bool trailing_rest = false;
-
- switch (parser->current.type) {
- case PM_TOKEN_LABEL: {
- parser_lex(parser);
- pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous);
- pm_token_t operator = not_provided(parser);
-
- return (pm_node_t *) parse_pattern_hash(parser, (pm_node_t *) pm_assoc_node_create(parser, key, &operator, NULL));
- }
- case PM_TOKEN_USTAR_STAR: {
- node = parse_pattern_keyword_rest(parser);
- return (pm_node_t *) parse_pattern_hash(parser, node);
- }
- case PM_TOKEN_USTAR: {
- if (top_pattern) {
- parser_lex(parser);
- node = (pm_node_t *) parse_pattern_rest(parser);
- leading_rest = true;
- break;
- }
- }
- /* fallthrough */
- default:
- node = parse_pattern_primitives(parser, diag_id);
- break;
- }
-
- // If we got a dynamic label symbol, then we need to treat it like the
- // beginning of a hash pattern.
- if (pm_symbol_node_label_p(node)) {
- pm_token_t operator = not_provided(parser);
- return (pm_node_t *) parse_pattern_hash(parser, (pm_node_t *) pm_assoc_node_create(parser, node, &operator, NULL));
- }
-
- if (top_pattern && match1(parser, PM_TOKEN_COMMA)) {
- // If we have a comma, then we are now parsing either an array pattern or a
- // find pattern. We need to parse all of the patterns, put them into a big
- // list, and then determine which type of node we have.
- pm_node_list_t nodes = { 0 };
- pm_node_list_append(&nodes, node);
-
- // Gather up all of the patterns into the list.
- while (accept1(parser, PM_TOKEN_COMMA)) {
- // Break early here in case we have a trailing comma.
- if (match5(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- node = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
- pm_node_list_append(&nodes, node);
- break;
- }
-
- if (accept1(parser, PM_TOKEN_USTAR)) {
- node = (pm_node_t *) parse_pattern_rest(parser);
-
- // If we have already parsed a splat pattern, then this is an error. We
- // will continue to parse the rest of the patterns, but we will indicate
- // it as an error.
- if (trailing_rest) {
- pm_parser_err_previous(parser, PM_ERR_PATTERN_REST);
- }
-
- trailing_rest = true;
- } else {
- node = parse_pattern_primitives(parser, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA);
- }
-
- pm_node_list_append(&nodes, node);
- }
-
- // If the first pattern and the last pattern are rest patterns, then we will
- // call this a find pattern, regardless of how many rest patterns are in
- // between because we know we already added the appropriate errors.
- // Otherwise we will create an array pattern.
- if (PM_NODE_TYPE_P(nodes.nodes[0], PM_SPLAT_NODE) && PM_NODE_TYPE_P(nodes.nodes[nodes.size - 1], PM_SPLAT_NODE)) {
- node = (pm_node_t *) pm_find_pattern_node_create(parser, &nodes);
- } else {
- node = (pm_node_t *) pm_array_pattern_node_node_list_create(parser, &nodes);
- }
-
- free(nodes.nodes);
- } else if (leading_rest) {
- // Otherwise, if we parsed a single splat pattern, then we know we have an
- // array pattern, so we can go ahead and create that node.
- node = (pm_node_t *) pm_array_pattern_node_rest_create(parser, node);
- }
-
- return node;
-}
-
-/**
- * Incorporate a negative sign into a numeric node by subtracting 1 character
- * from its start bounds. If it's a compound node, then we will recursively
- * apply this function to its value.
- */
-static inline void
-parse_negative_numeric(pm_node_t *node) {
- switch (PM_NODE_TYPE(node)) {
- case PM_INTEGER_NODE:
- case PM_FLOAT_NODE:
- node->location.start--;
- break;
- case PM_RATIONAL_NODE:
- node->location.start--;
- parse_negative_numeric(((pm_rational_node_t *) node)->numeric);
- break;
- case PM_IMAGINARY_NODE:
- node->location.start--;
- parse_negative_numeric(((pm_imaginary_node_t *) node)->numeric);
- break;
- default:
- assert(false && "unreachable");
- break;
- }
-}
-
-/**
- * Returns a string content token at a particular location that is empty.
- */
-static pm_token_t
-parse_strings_empty_content(const uint8_t *location) {
- return (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = location, .end = location };
-}
-
-/**
- * Parse a set of strings that could be concatenated together.
- */
-static inline pm_node_t *
-parse_strings(pm_parser_t *parser, pm_node_t *current) {
- assert(parser->current.type == PM_TOKEN_STRING_BEGIN);
-
- bool concating = false;
- bool state_is_arg_labeled = lex_state_p(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED);
-
- while (match1(parser, PM_TOKEN_STRING_BEGIN)) {
- pm_node_t *node = NULL;
-
- // Here we have found a string literal. We'll parse it and add it to
- // the list of strings.
- const pm_lex_mode_t *lex_mode = parser->lex_modes.current;
- assert(lex_mode->mode == PM_LEX_STRING);
- bool lex_interpolation = lex_mode->as.string.interpolation;
-
- pm_token_t opening = parser->current;
- parser_lex(parser);
-
- if (match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
- // If we get here, then we have an end immediately after a
- // start. In that case we'll create an empty content token and
- // return an uninterpolated string.
- pm_token_t content = parse_strings_empty_content(parser->previous.start);
- pm_string_node_t *string = pm_string_node_create(parser, &opening, &content, &parser->previous);
-
- pm_string_shared_init(&string->unescaped, content.start, content.end);
- node = (pm_node_t *) string;
- } else if (accept1(parser, PM_TOKEN_LABEL_END)) {
- // If we get here, then we have an end of a label immediately
- // after a start. In that case we'll create an empty symbol
- // node.
- pm_token_t opening = not_provided(parser);
- pm_token_t content = parse_strings_empty_content(parser->previous.start);
- pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &content, &parser->previous);
-
- pm_string_shared_init(&symbol->unescaped, content.start, content.end);
- node = (pm_node_t *) symbol;
- } else if (!lex_interpolation) {
- // If we don't accept interpolation then we expect the string to
- // start with a single string content node.
- pm_string_t unescaped;
- pm_token_t content;
- if (match1(parser, PM_TOKEN_EOF)) {
- unescaped = PM_STRING_EMPTY;
- content = not_provided(parser);
- } else {
- unescaped = parser->current_string;
- expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_EXPECT_STRING_CONTENT);
- content = parser->previous;
- }
-
- // It is unfortunately possible to have multiple string content
- // nodes in a row in the case that there's heredoc content in
- // the middle of the string, like this cursed example:
- //
- // <<-END+'b
- // a
- // END
- // c'+'d'
- //
- // In that case we need to switch to an interpolated string to
- // be able to contain all of the parts.
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- pm_node_list_t parts = { 0 };
-
- pm_token_t delimiters = not_provided(parser);
- pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &delimiters, &content, &delimiters, &unescaped);
- pm_node_list_append(&parts, part);
-
- do {
- part = (pm_node_t *) pm_string_node_create_current_string(parser, &delimiters, &parser->current, &delimiters);
- pm_node_list_append(&parts, part);
- parser_lex(parser);
- } while (match1(parser, PM_TOKEN_STRING_CONTENT));
-
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
- node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
- } else if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) {
- node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
- } else if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_STRING_LITERAL_TERM);
- node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
- node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
- }
- } else if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- // In this case we've hit string content so we know the string
- // at least has something in it. We'll need to check if the
- // following token is the end (in which case we can return a
- // plain string) or if it's not then it has interpolation.
- pm_token_t content = parser->current;
- pm_string_t unescaped = parser->current_string;
- parser_lex(parser);
-
- if (match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
- pm_node_flag_set(node, parse_unescaped_encoding(parser));
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
- } else if (accept1(parser, PM_TOKEN_LABEL_END)) {
- node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
- } else {
- // If we get here, then we have interpolation so we'll need
- // to create a string or symbol node with interpolation.
- pm_node_list_t parts = { 0 };
- pm_token_t string_opening = not_provided(parser);
- pm_token_t string_closing = not_provided(parser);
-
- pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &string_opening, &parser->previous, &string_closing, &unescaped);
- pm_node_flag_set(part, parse_unescaped_encoding(parser));
- pm_node_list_append(&parts, part);
-
- while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
- if ((part = parse_string_part(parser)) != NULL) {
- pm_node_list_append(&parts, part);
- }
- }
-
- if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) {
- node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
- } else if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM);
- node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current);
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM);
- node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
- }
- }
- } else {
- // If we get here, then the first part of the string is not plain
- // string content, in which case we need to parse the string as an
- // interpolated string.
- pm_node_list_t parts = { 0 };
- pm_node_t *part;
-
- while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
- if ((part = parse_string_part(parser)) != NULL) {
- pm_node_list_append(&parts, part);
- }
- }
-
- if (accept1(parser, PM_TOKEN_LABEL_END)) {
- node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
- } else if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM);
- node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current);
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM);
- node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
- }
- }
-
- if (current == NULL) {
- // If the node we just parsed is a symbol node, then we can't
- // concatenate it with anything else, so we can now return that
- // node.
- if (PM_NODE_TYPE_P(node, PM_SYMBOL_NODE) || PM_NODE_TYPE_P(node, PM_INTERPOLATED_SYMBOL_NODE)) {
- return node;
- }
-
- // If we don't already have a node, then it's fine and we can just
- // set the result to be the node we just parsed.
- current = node;
- } else {
- // Otherwise we need to check the type of the node we just parsed.
- // If it cannot be concatenated with the previous node, then we'll
- // need to add a syntax error.
- if (!PM_NODE_TYPE_P(node, PM_STRING_NODE) && !PM_NODE_TYPE_P(node, PM_INTERPOLATED_STRING_NODE)) {
- pm_parser_err_node(parser, node, PM_ERR_STRING_CONCATENATION);
- }
-
- // If we haven't already created our container for concatenation,
- // we'll do that now.
- if (!concating) {
- concating = true;
- pm_token_t bounds = not_provided(parser);
-
- pm_interpolated_string_node_t *container = pm_interpolated_string_node_create(parser, &bounds, NULL, &bounds);
- pm_interpolated_string_node_append(container, current);
- current = (pm_node_t *) container;
- }
-
- pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, node);
- }
- }
-
- return current;
-}
-
-/**
- * Parse an expression that begins with the previous node that we just lexed.
- */
-static inline pm_node_t *
-parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call) {
- switch (parser->current.type) {
- case PM_TOKEN_BRACKET_LEFT_ARRAY: {
- parser_lex(parser);
-
- pm_array_node_t *array = pm_array_node_create(parser, &parser->previous);
- pm_accepts_block_stack_push(parser, true);
- bool parsed_bare_hash = false;
-
- while (!match2(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_EOF)) {
- // Handle the case where we don't have a comma and we have a
- // newline followed by a right bracket.
- if (accept1(parser, PM_TOKEN_NEWLINE) && match1(parser, PM_TOKEN_BRACKET_RIGHT)) {
- break;
- }
-
- if (pm_array_node_size(array) != 0) {
- expect1(parser, PM_TOKEN_COMMA, PM_ERR_ARRAY_SEPARATOR);
- }
-
- // If we have a right bracket immediately following a comma,
- // this is allowed since it's a trailing comma. In this case we
- // can break out of the loop.
- if (match1(parser, PM_TOKEN_BRACKET_RIGHT)) break;
-
- pm_node_t *element;
-
- if (accept1(parser, PM_TOKEN_USTAR)) {
- pm_token_t operator = parser->previous;
- pm_node_t *expression = NULL;
-
- if (match3(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_EOF)) {
- if (pm_parser_local_depth(parser, &parser->previous) == -1) {
- pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_STAR);
- }
- } else {
- expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR);
- }
-
- element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
- } else if (match2(parser, PM_TOKEN_LABEL, PM_TOKEN_USTAR_STAR)) {
- if (parsed_bare_hash) {
- pm_parser_err_current(parser, PM_ERR_EXPRESSION_BARE_HASH);
- }
-
- pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser);
- element = (pm_node_t *)hash;
-
- if (!match8(parser, PM_TOKEN_EOF, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_KEYWORD_DO, PM_TOKEN_PARENTHESIS_RIGHT)) {
- parse_assocs(parser, (pm_node_t *) hash);
- }
-
- parsed_bare_hash = true;
- } else {
- element = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_ARRAY_EXPRESSION);
-
- if (pm_symbol_node_label_p(element) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
- if (parsed_bare_hash) {
- pm_parser_err_previous(parser, PM_ERR_EXPRESSION_BARE_HASH);
- }
-
- pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser);
-
- pm_token_t operator;
- if (parser->previous.type == PM_TOKEN_EQUAL_GREATER) {
- operator = parser->previous;
- } else {
- operator = not_provided(parser);
- }
-
- pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
- pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, element, &operator, value);
- pm_keyword_hash_node_elements_append(hash, assoc);
-
- element = (pm_node_t *)hash;
- if (accept1(parser, PM_TOKEN_COMMA) && !match1(parser, PM_TOKEN_BRACKET_RIGHT)) {
- parse_assocs(parser, (pm_node_t *) hash);
- }
-
- parsed_bare_hash = true;
- }
- }
-
- pm_array_node_elements_append(array, element);
- if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break;
- }
-
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_ARRAY_TERM);
- pm_array_node_close_set(array, &parser->previous);
- pm_accepts_block_stack_pop(parser);
-
- return (pm_node_t *) array;
- }
- case PM_TOKEN_PARENTHESIS_LEFT:
- case PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES: {
- pm_token_t opening = parser->current;
- parser_lex(parser);
- while (accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE));
-
- // If this is the end of the file or we match a right parenthesis, then
- // we have an empty parentheses node, and we can immediately return.
- if (match2(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_EOF)) {
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
- return (pm_node_t *) pm_parentheses_node_create(parser, &opening, NULL, &parser->previous);
- }
-
- // Otherwise, we're going to parse the first statement in the list
- // of statements within the parentheses.
- pm_accepts_block_stack_push(parser, true);
- context_push(parser, PM_CONTEXT_PARENS);
- pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
- context_pop(parser);
-
- // Determine if this statement is followed by a terminator. In the
- // case of a single statement, this is fine. But in the case of
- // multiple statements it's required.
- bool terminator_found = accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- if (terminator_found) {
- while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
- }
-
- // If we hit a right parenthesis, then we're done parsing the
- // parentheses node, and we can check which kind of node we should
- // return.
- if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- if (opening.type == PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES) {
- lex_state_set(parser, PM_LEX_STATE_ENDARG);
- }
- parser_lex(parser);
- pm_accepts_block_stack_pop(parser);
-
- if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE) || PM_NODE_TYPE_P(statement, PM_SPLAT_NODE)) {
- // If we have a single statement and are ending on a right
- // parenthesis, then we need to check if this is possibly a
- // multiple target node.
- pm_multi_target_node_t *multi_target;
-
- if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE) && ((pm_multi_target_node_t *) statement)->lparen_loc.start == NULL) {
- multi_target = (pm_multi_target_node_t *) statement;
- } else {
- multi_target = pm_multi_target_node_create(parser);
- pm_multi_target_node_targets_append(parser, multi_target, statement);
- }
-
- pm_location_t lparen_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- pm_location_t rparen_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
-
- multi_target->lparen_loc = lparen_loc;
- multi_target->rparen_loc = rparen_loc;
- multi_target->base.location.start = lparen_loc.start;
- multi_target->base.location.end = rparen_loc.end;
-
- if (match1(parser, PM_TOKEN_COMMA)) {
- if (binding_power == PM_BINDING_POWER_STATEMENT) {
- return parse_targets_validate(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX);
- }
- return (pm_node_t *) multi_target;
- }
-
- return parse_target_validate(parser, (pm_node_t *) multi_target);
- }
-
- // If we have a single statement and are ending on a right parenthesis
- // and we didn't return a multiple assignment node, then we can return a
- // regular parentheses node now.
- pm_statements_node_t *statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(statements, statement);
-
- return (pm_node_t *) pm_parentheses_node_create(parser, &opening, (pm_node_t *) statements, &parser->previous);
- }
-
- // If we have more than one statement in the set of parentheses,
- // then we are going to parse all of them as a list of statements.
- // We'll do that here.
- context_push(parser, PM_CONTEXT_PARENS);
- pm_statements_node_t *statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(statements, statement);
-
- // If we didn't find a terminator and we didn't find a right
- // parenthesis, then this is a syntax error.
- if (!terminator_found) {
- pm_parser_err(parser, parser->current.start, parser->current.start, PM_ERR_EXPECT_EOL_AFTER_STATEMENT);
- }
-
- // Parse each statement within the parentheses.
- while (true) {
- pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
- pm_statements_node_body_append(statements, node);
-
- // If we're recovering from a syntax error, then we need to stop
- // parsing the statements now.
- if (parser->recovering) {
- // If this is the level of context where the recovery has
- // happened, then we can mark the parser as done recovering.
- if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) parser->recovering = false;
- break;
- }
-
- // If we couldn't parse an expression at all, then we need to
- // bail out of the loop.
- if (PM_NODE_TYPE_P(node, PM_MISSING_NODE)) break;
-
- // If we successfully parsed a statement, then we are going to
- // need terminator to delimit them.
- if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
- if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) break;
- } else if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- break;
- } else {
- pm_parser_err(parser, parser->current.start, parser->current.start, PM_ERR_EXPECT_EOL_AFTER_STATEMENT);
- }
- }
-
- context_pop(parser);
- pm_accepts_block_stack_pop(parser);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
-
- return (pm_node_t *) pm_parentheses_node_create(parser, &opening, (pm_node_t *) statements, &parser->previous);
- }
- case PM_TOKEN_BRACE_LEFT: {
- pm_accepts_block_stack_push(parser, true);
- parser_lex(parser);
- pm_hash_node_t *node = pm_hash_node_create(parser, &parser->previous);
-
- if (!match2(parser, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_EOF)) {
- parse_assocs(parser, (pm_node_t *) node);
- accept1(parser, PM_TOKEN_NEWLINE);
- }
-
- pm_accepts_block_stack_pop(parser);
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_HASH_TERM);
- pm_hash_node_closing_loc_set(node, &parser->previous);
-
- return (pm_node_t *) node;
- }
- case PM_TOKEN_CHARACTER_LITERAL: {
- parser_lex(parser);
-
- pm_token_t opening = parser->previous;
- opening.type = PM_TOKEN_STRING_BEGIN;
- opening.end = opening.start + 1;
-
- pm_token_t content = parser->previous;
- content.type = PM_TOKEN_STRING_CONTENT;
- content.start = content.start + 1;
-
- pm_token_t closing = not_provided(parser);
- pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &content, &closing);
- pm_node_flag_set(node, parse_unescaped_encoding(parser));
-
- // Characters can be followed by strings in which case they are
- // automatically concatenated.
- if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
- return parse_strings(parser, node);
- }
-
- return node;
- }
- case PM_TOKEN_CLASS_VARIABLE: {
- parser_lex(parser);
- pm_node_t *node = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous);
-
- if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_CONSTANT: {
- parser_lex(parser);
- pm_token_t constant = parser->previous;
-
- // If a constant is immediately followed by parentheses, then this is in
- // fact a method call, not a constant read.
- if (
- match1(parser, PM_TOKEN_PARENTHESIS_LEFT) ||
- (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) ||
- (pm_accepts_block_stack_p(parser) && match2(parser, PM_TOKEN_KEYWORD_DO, PM_TOKEN_BRACE_LEFT))
- ) {
- pm_arguments_t arguments = { 0 };
- parse_arguments_list(parser, &arguments, true, accepts_command_call);
- return (pm_node_t *) pm_call_node_fcall_create(parser, &constant, &arguments);
- }
-
- pm_node_t *node = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous);
-
- if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) {
- // If we get here, then we have a comma immediately following a
- // constant, so we're going to parse this as a multiple assignment.
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_UCOLON_COLON: {
- parser_lex(parser);
-
- pm_token_t delimiter = parser->previous;
- expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
-
- pm_node_t *constant = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous);
- pm_node_t *node = (pm_node_t *)pm_constant_path_node_create(parser, NULL, &delimiter, constant);
-
- if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_UDOT_DOT:
- case PM_TOKEN_UDOT_DOT_DOT: {
- pm_token_t operator = parser->current;
- parser_lex(parser);
-
- pm_node_t *right = parse_expression(parser, pm_binding_powers[operator.type].left, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
- }
- case PM_TOKEN_FLOAT:
- parser_lex(parser);
- return (pm_node_t *) pm_float_node_create(parser, &parser->previous);
- case PM_TOKEN_FLOAT_IMAGINARY:
- parser_lex(parser);
- return (pm_node_t *) pm_float_node_imaginary_create(parser, &parser->previous);
- case PM_TOKEN_FLOAT_RATIONAL:
- parser_lex(parser);
- return (pm_node_t *) pm_float_node_rational_create(parser, &parser->previous);
- case PM_TOKEN_FLOAT_RATIONAL_IMAGINARY:
- parser_lex(parser);
- return (pm_node_t *) pm_float_node_rational_imaginary_create(parser, &parser->previous);
- case PM_TOKEN_NUMBERED_REFERENCE: {
- parser_lex(parser);
- pm_node_t *node = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous);
-
- if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_GLOBAL_VARIABLE: {
- parser_lex(parser);
- pm_node_t *node = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous);
-
- if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_BACK_REFERENCE: {
- parser_lex(parser);
- pm_node_t *node = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous);
-
- if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_METHOD_NAME: {
- parser_lex(parser);
- pm_token_t identifier = parser->previous;
- pm_node_t *node = parse_variable_call(parser);
-
- if (PM_NODE_TYPE_P(node, PM_CALL_NODE)) {
- // If parse_variable_call returned with a call node, then we
- // know the identifier is not in the local table. In that case
- // we need to check if there are arguments following the
- // identifier.
- pm_call_node_t *call = (pm_call_node_t *) node;
- pm_arguments_t arguments = { 0 };
-
- if (parse_arguments_list(parser, &arguments, true, accepts_command_call)) {
- // Since we found arguments, we need to turn off the
- // variable call bit in the flags.
- pm_node_flag_unset((pm_node_t *)call, PM_CALL_NODE_FLAGS_VARIABLE_CALL);
-
- call->opening_loc = arguments.opening_loc;
- call->arguments = arguments.arguments;
- call->closing_loc = arguments.closing_loc;
- call->block = arguments.block;
-
- if (arguments.block != NULL) {
- call->base.location.end = arguments.block->location.end;
- } else if (arguments.closing_loc.start == NULL) {
- if (arguments.arguments != NULL) {
- call->base.location.end = arguments.arguments->base.location.end;
- } else {
- call->base.location.end = call->message_loc.end;
- }
- } else {
- call->base.location.end = arguments.closing_loc.end;
- }
- }
- } else {
- // Otherwise, we know the identifier is in the local table. This
- // can still be a method call if it is followed by arguments or
- // a block, so we need to check for that here.
- if (
- (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) ||
- (pm_accepts_block_stack_p(parser) && match2(parser, PM_TOKEN_KEYWORD_DO, PM_TOKEN_BRACE_LEFT))
- ) {
- pm_arguments_t arguments = { 0 };
- parse_arguments_list(parser, &arguments, true, accepts_command_call);
-
- pm_call_node_t *fcall = pm_call_node_fcall_create(parser, &identifier, &arguments);
- pm_node_destroy(parser, node);
- return (pm_node_t *) fcall;
- }
- }
-
- if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_HEREDOC_START: {
- // Here we have found a heredoc. We'll parse it and add it to the
- // list of strings.
- pm_lex_mode_t *lex_mode = parser->lex_modes.current;
- assert(lex_mode->mode == PM_LEX_HEREDOC);
- pm_heredoc_quote_t quote = lex_mode->as.heredoc.quote;
- pm_heredoc_indent_t indent = lex_mode->as.heredoc.indent;
-
- parser_lex(parser);
- pm_token_t opening = parser->previous;
-
- pm_node_t *node;
- pm_node_t *part;
-
- if (match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) {
- // If we get here, then we have an empty heredoc. We'll create
- // an empty content token and return an empty string node.
- lex_mode_pop(parser);
- expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
- pm_token_t content = parse_strings_empty_content(parser->previous.start);
-
- if (quote == PM_HEREDOC_QUOTE_BACKTICK) {
- node = (pm_node_t *) pm_xstring_node_create_unescaped(parser, &opening, &content, &parser->previous, &PM_STRING_EMPTY);
- } else {
- node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->previous, &PM_STRING_EMPTY);
- }
-
- node->location.end = opening.end;
- } else if ((part = parse_string_part(parser)) == NULL) {
- // If we get here, then we tried to find something in the
- // heredoc but couldn't actually parse anything, so we'll just
- // return a missing node.
- node = (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end);
- } else if (PM_NODE_TYPE_P(part, PM_STRING_NODE) && match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) {
- // If we get here, then the part that we parsed was plain string
- // content and we're at the end of the heredoc, so we can return
- // just a string node with the heredoc opening and closing as
- // its opening and closing.
- pm_node_flag_set(part, parse_unescaped_encoding(parser));
- pm_string_node_t *cast = (pm_string_node_t *) part;
-
- cast->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
- cast->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->current);
- cast->base.location = cast->opening_loc;
-
- if (quote == PM_HEREDOC_QUOTE_BACKTICK) {
- assert(sizeof(pm_string_node_t) == sizeof(pm_x_string_node_t));
- cast->base.type = PM_X_STRING_NODE;
- }
-
- size_t common_whitespace = lex_mode->as.heredoc.common_whitespace;
- if (indent == PM_HEREDOC_INDENT_TILDE && (common_whitespace != (size_t) -1) && (common_whitespace != 0)) {
- parse_heredoc_dedent_string(&cast->unescaped, common_whitespace);
- }
-
- node = (pm_node_t *) cast;
- lex_mode_pop(parser);
- expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
- } else {
- // If we get here, then we have multiple parts in the heredoc,
- // so we'll need to create an interpolated string node to hold
- // them all.
- pm_node_list_t parts = { 0 };
- pm_node_list_append(&parts, part);
-
- while (!match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) {
- if ((part = parse_string_part(parser)) != NULL) {
- pm_node_list_append(&parts, part);
- }
- }
-
- size_t common_whitespace = lex_mode->as.heredoc.common_whitespace;
-
- // Now that we have all of the parts, create the correct type of
- // interpolated node.
- if (quote == PM_HEREDOC_QUOTE_BACKTICK) {
- pm_interpolated_x_string_node_t *cast = pm_interpolated_xstring_node_create(parser, &opening, &opening);
- cast->parts = parts;
-
- lex_mode_pop(parser);
- expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
-
- pm_interpolated_xstring_node_closing_set(cast, &parser->previous);
- cast->base.location = cast->opening_loc;
- node = (pm_node_t *) cast;
- } else {
- pm_interpolated_string_node_t *cast = pm_interpolated_string_node_create(parser, &opening, &parts, &opening);
-
- lex_mode_pop(parser);
- expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
-
- pm_interpolated_string_node_closing_set(cast, &parser->previous);
- cast->base.location = cast->opening_loc;
- node = (pm_node_t *) cast;
- }
-
- // If this is a heredoc that is indented with a ~, then we need
- // to dedent each line by the common leading whitespace.
- if (indent == PM_HEREDOC_INDENT_TILDE && (common_whitespace != (size_t) -1) && (common_whitespace != 0)) {
- pm_node_list_t *nodes;
- if (quote == PM_HEREDOC_QUOTE_BACKTICK) {
- nodes = &((pm_interpolated_x_string_node_t *) node)->parts;
- } else {
- nodes = &((pm_interpolated_string_node_t *) node)->parts;
- }
-
- parse_heredoc_dedent(parser, nodes, common_whitespace);
- }
- }
-
- if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
- return parse_strings(parser, node);
- }
-
- return node;
- }
- case PM_TOKEN_INSTANCE_VARIABLE: {
- parser_lex(parser);
- pm_node_t *node = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous);
-
- if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
- }
-
- return node;
- }
- case PM_TOKEN_INTEGER: {
- pm_node_flags_t base = parser->integer_base;
- parser_lex(parser);
- return (pm_node_t *) pm_integer_node_create(parser, base, &parser->previous);
- }
- case PM_TOKEN_INTEGER_IMAGINARY: {
- pm_node_flags_t base = parser->integer_base;
- parser_lex(parser);
- return (pm_node_t *) pm_integer_node_imaginary_create(parser, base, &parser->previous);
- }
- case PM_TOKEN_INTEGER_RATIONAL: {
- pm_node_flags_t base = parser->integer_base;
- parser_lex(parser);
- return (pm_node_t *) pm_integer_node_rational_create(parser, base, &parser->previous);
- }
- case PM_TOKEN_INTEGER_RATIONAL_IMAGINARY: {
- pm_node_flags_t base = parser->integer_base;
- parser_lex(parser);
- return (pm_node_t *) pm_integer_node_rational_imaginary_create(parser, base, &parser->previous);
- }
- case PM_TOKEN_KEYWORD___ENCODING__:
- parser_lex(parser);
- return (pm_node_t *) pm_source_encoding_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD___FILE__:
- parser_lex(parser);
- return (pm_node_t *) pm_source_file_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD___LINE__:
- parser_lex(parser);
- return (pm_node_t *) pm_source_line_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_ALIAS: {
- if (binding_power != PM_BINDING_POWER_STATEMENT) {
- pm_parser_err_current(parser, PM_ERR_STATEMENT_ALIAS);
- }
-
- parser_lex(parser);
- pm_token_t keyword = parser->previous;
-
- pm_node_t *new_name = parse_alias_argument(parser, true);
- pm_node_t *old_name = parse_alias_argument(parser, false);
-
- switch (PM_NODE_TYPE(new_name)) {
- case PM_BACK_REFERENCE_READ_NODE:
- case PM_NUMBERED_REFERENCE_READ_NODE:
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- if (PM_NODE_TYPE_P(old_name, PM_BACK_REFERENCE_READ_NODE) || PM_NODE_TYPE_P(old_name, PM_NUMBERED_REFERENCE_READ_NODE) || PM_NODE_TYPE_P(old_name, PM_GLOBAL_VARIABLE_READ_NODE)) {
- if (PM_NODE_TYPE_P(old_name, PM_NUMBERED_REFERENCE_READ_NODE)) {
- pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT);
- }
- } else {
- pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT);
- }
-
- return (pm_node_t *) pm_alias_global_variable_node_create(parser, &keyword, new_name, old_name);
- }
- case PM_SYMBOL_NODE:
- case PM_INTERPOLATED_SYMBOL_NODE: {
- if (!PM_NODE_TYPE_P(old_name, PM_SYMBOL_NODE) && !PM_NODE_TYPE_P(old_name, PM_INTERPOLATED_SYMBOL_NODE)) {
- pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT);
- }
- }
- /* fallthrough */
- default:
- return (pm_node_t *) pm_alias_method_node_create(parser, &keyword, new_name, old_name);
- }
- }
- case PM_TOKEN_KEYWORD_CASE: {
- parser_lex(parser);
- pm_token_t case_keyword = parser->previous;
- pm_node_t *predicate = NULL;
-
- if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
- predicate = NULL;
- } else if (match3(parser, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_KEYWORD_IN, PM_TOKEN_KEYWORD_END)) {
- predicate = NULL;
- } else if (!token_begins_expression_p(parser->current.type)) {
- predicate = NULL;
- } else {
- predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CASE_EXPRESSION_AFTER_CASE);
- while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
- }
-
- if (accept1(parser, PM_TOKEN_KEYWORD_END)) {
- pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MISSING_CONDITIONS);
- return (pm_node_t *) pm_case_node_create(parser, &case_keyword, predicate, &parser->previous);
- }
-
- // At this point we can create a case node, though we don't yet know if it
- // is a case-in or case-when node.
- pm_token_t end_keyword = not_provided(parser);
- pm_node_t *node;
-
- if (match1(parser, PM_TOKEN_KEYWORD_WHEN)) {
- pm_case_node_t *case_node = pm_case_node_create(parser, &case_keyword, predicate, &end_keyword);
-
- // At this point we've seen a when keyword, so we know this is a
- // case-when node. We will continue to parse the when nodes until we hit
- // the end of the list.
- while (accept1(parser, PM_TOKEN_KEYWORD_WHEN)) {
- pm_token_t when_keyword = parser->previous;
- pm_when_node_t *when_node = pm_when_node_create(parser, &when_keyword);
-
- do {
- if (accept1(parser, PM_TOKEN_USTAR)) {
- pm_token_t operator = parser->previous;
- pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
-
- pm_splat_node_t *splat_node = pm_splat_node_create(parser, &operator, expression);
- pm_when_node_conditions_append(when_node, (pm_node_t *) splat_node);
-
- if (PM_NODE_TYPE_P(expression, PM_MISSING_NODE)) break;
- } else {
- pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_CASE_EXPRESSION_AFTER_WHEN);
- pm_when_node_conditions_append(when_node, condition);
-
- if (PM_NODE_TYPE_P(condition, PM_MISSING_NODE)) break;
- }
- } while (accept1(parser, PM_TOKEN_COMMA));
-
- if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- accept1(parser, PM_TOKEN_KEYWORD_THEN);
- } else {
- expect1(parser, PM_TOKEN_KEYWORD_THEN, PM_ERR_EXPECT_WHEN_DELIMITER);
- }
-
- if (!match3(parser, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
- pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_CASE_WHEN);
- if (statements != NULL) {
- pm_when_node_statements_set(when_node, statements);
- }
- }
-
- pm_case_node_condition_append(case_node, (pm_node_t *) when_node);
- }
-
- // If we didn't parse any conditions (in or when) then we need
- // to indicate that we have an error.
- if (case_node->conditions.size == 0) {
- pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MISSING_CONDITIONS);
- }
-
- node = (pm_node_t *) case_node;
- } else {
- pm_case_match_node_t *case_node = pm_case_match_node_create(parser, &case_keyword, predicate, &end_keyword);
-
- // If this is a case-match node (i.e., it is a pattern matching
- // case statement) then we must have a predicate.
- if (predicate == NULL) {
- pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MATCH_MISSING_PREDICATE);
- }
-
- // At this point we expect that we're parsing a case-in node. We will
- // continue to parse the in nodes until we hit the end of the list.
- while (match1(parser, PM_TOKEN_KEYWORD_IN)) {
- bool previous_pattern_matching_newlines = parser->pattern_matching_newlines;
- parser->pattern_matching_newlines = true;
-
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
- parser->command_start = false;
- parser_lex(parser);
-
- pm_token_t in_keyword = parser->previous;
- pm_node_t *pattern = parse_pattern(parser, true, PM_ERR_PATTERN_EXPRESSION_AFTER_IN);
- parser->pattern_matching_newlines = previous_pattern_matching_newlines;
-
- // Since we're in the top-level of the case-in node we need to check
- // for guard clauses in the form of `if` or `unless` statements.
- if (accept1(parser, PM_TOKEN_KEYWORD_IF_MODIFIER)) {
- pm_token_t keyword = parser->previous;
- pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, true, PM_ERR_CONDITIONAL_IF_PREDICATE);
- pattern = (pm_node_t *) pm_if_node_modifier_create(parser, pattern, &keyword, predicate);
- } else if (accept1(parser, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) {
- pm_token_t keyword = parser->previous;
- pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, true, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
- pattern = (pm_node_t *) pm_unless_node_modifier_create(parser, pattern, &keyword, predicate);
- }
-
- // Now we need to check for the terminator of the in node's pattern.
- // It can be a newline or semicolon optionally followed by a `then`
- // keyword.
- pm_token_t then_keyword;
- if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
- if (accept1(parser, PM_TOKEN_KEYWORD_THEN)) {
- then_keyword = parser->previous;
- } else {
- then_keyword = not_provided(parser);
- }
- } else {
- expect1(parser, PM_TOKEN_KEYWORD_THEN, PM_ERR_EXPECT_WHEN_DELIMITER);
- then_keyword = parser->previous;
- }
-
- // Now we can actually parse the statements associated with the in
- // node.
- pm_statements_node_t *statements;
- if (match3(parser, PM_TOKEN_KEYWORD_IN, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
- statements = NULL;
- } else {
- statements = parse_statements(parser, PM_CONTEXT_CASE_IN);
- }
-
- // Now that we have the full pattern and statements, we can create the
- // node and attach it to the case node.
- pm_node_t *condition = (pm_node_t *) pm_in_node_create(parser, pattern, statements, &in_keyword, &then_keyword);
- pm_case_match_node_condition_append(case_node, condition);
- }
-
- // If we didn't parse any conditions (in or when) then we need
- // to indicate that we have an error.
- if (case_node->conditions.size == 0) {
- pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MISSING_CONDITIONS);
- }
-
- node = (pm_node_t *) case_node;
- }
-
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- if (accept1(parser, PM_TOKEN_KEYWORD_ELSE)) {
- pm_token_t else_keyword = parser->previous;
- pm_else_node_t *else_node;
-
- if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
- else_node = pm_else_node_create(parser, &else_keyword, parse_statements(parser, PM_CONTEXT_ELSE), &parser->current);
- } else {
- else_node = pm_else_node_create(parser, &else_keyword, NULL, &parser->current);
- }
-
- if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) {
- pm_case_node_consequent_set((pm_case_node_t *) node, else_node);
- } else {
- pm_case_match_node_consequent_set((pm_case_match_node_t *) node, else_node);
- }
- }
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM);
- if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) {
- pm_case_node_end_keyword_loc_set((pm_case_node_t *) node, &parser->previous);
- } else {
- pm_case_match_node_end_keyword_loc_set((pm_case_match_node_t *) node, &parser->previous);
- }
-
- return node;
- }
- case PM_TOKEN_KEYWORD_BEGIN: {
- parser_lex(parser);
-
- pm_token_t begin_keyword = parser->previous;
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- pm_statements_node_t *begin_statements = NULL;
-
- if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- begin_statements = parse_statements(parser, PM_CONTEXT_BEGIN);
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
-
- pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
- parse_rescues(parser, begin_node, false);
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM);
- begin_node->base.location.end = parser->previous.end;
- pm_begin_node_end_keyword_set(begin_node, &parser->previous);
-
- if ((begin_node->else_clause != NULL) && (begin_node->rescue_clause == NULL)) {
- pm_parser_err_node(parser, (pm_node_t *) begin_node->else_clause, PM_ERR_BEGIN_LONELY_ELSE);
- }
-
- return (pm_node_t *) begin_node;
- }
- case PM_TOKEN_KEYWORD_BEGIN_UPCASE: {
- if (binding_power != PM_BINDING_POWER_STATEMENT) {
- pm_parser_err_current(parser, PM_ERR_STATEMENT_PREEXE_BEGIN);
- }
-
- parser_lex(parser);
- pm_token_t keyword = parser->previous;
-
- expect1(parser, PM_TOKEN_BRACE_LEFT, PM_ERR_BEGIN_UPCASE_BRACE);
- pm_token_t opening = parser->previous;
- pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_PREEXE);
-
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM);
- pm_context_t context = parser->current_context->context;
- if ((context != PM_CONTEXT_MAIN) && (context != PM_CONTEXT_PREEXE)) {
- pm_parser_err_token(parser, &keyword, PM_ERR_BEGIN_UPCASE_TOPLEVEL);
- }
- return (pm_node_t *) pm_pre_execution_node_create(parser, &keyword, &opening, statements, &parser->previous);
- }
- case PM_TOKEN_KEYWORD_BREAK:
- case PM_TOKEN_KEYWORD_NEXT:
- case PM_TOKEN_KEYWORD_RETURN: {
- parser_lex(parser);
-
- pm_token_t keyword = parser->previous;
- pm_arguments_t arguments = { 0 };
-
- if (
- token_begins_expression_p(parser->current.type) ||
- match2(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR)
- ) {
- pm_binding_power_t binding_power = pm_binding_powers[parser->current.type].left;
-
- if (binding_power == PM_BINDING_POWER_UNSET || binding_power >= PM_BINDING_POWER_RANGE) {
- parse_arguments(parser, &arguments, false, PM_TOKEN_EOF);
- }
- }
-
- switch (keyword.type) {
- case PM_TOKEN_KEYWORD_BREAK:
- return (pm_node_t *) pm_break_node_create(parser, &keyword, arguments.arguments);
- case PM_TOKEN_KEYWORD_NEXT:
- return (pm_node_t *) pm_next_node_create(parser, &keyword, arguments.arguments);
- case PM_TOKEN_KEYWORD_RETURN: {
- if (
- (parser->current_context->context == PM_CONTEXT_CLASS) ||
- (parser->current_context->context == PM_CONTEXT_MODULE)
- ) {
- pm_parser_err_current(parser, PM_ERR_RETURN_INVALID);
- }
- return (pm_node_t *) pm_return_node_create(parser, &keyword, arguments.arguments);
- }
- default:
- assert(false && "unreachable");
- return (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end);
- }
- }
- case PM_TOKEN_KEYWORD_SUPER: {
- parser_lex(parser);
-
- pm_token_t keyword = parser->previous;
- pm_arguments_t arguments = { 0 };
- parse_arguments_list(parser, &arguments, true, accepts_command_call);
-
- if (
- arguments.opening_loc.start == NULL &&
- arguments.arguments == NULL &&
- ((arguments.block == NULL) || PM_NODE_TYPE_P(arguments.block, PM_BLOCK_NODE))
- ) {
- return (pm_node_t *) pm_forwarding_super_node_create(parser, &keyword, &arguments);
- }
-
- return (pm_node_t *) pm_super_node_create(parser, &keyword, &arguments);
- }
- case PM_TOKEN_KEYWORD_YIELD: {
- parser_lex(parser);
-
- pm_token_t keyword = parser->previous;
- pm_arguments_t arguments = { 0 };
- parse_arguments_list(parser, &arguments, false, accepts_command_call);
-
- return (pm_node_t *) pm_yield_node_create(parser, &keyword, &arguments.opening_loc, arguments.arguments, &arguments.closing_loc);
- }
- case PM_TOKEN_KEYWORD_CLASS: {
- parser_lex(parser);
- pm_token_t class_keyword = parser->previous;
- pm_do_loop_stack_push(parser, false);
-
- if (accept1(parser, PM_TOKEN_LESS_LESS)) {
- pm_token_t operator = parser->previous;
- pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_NOT, true, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS);
-
- pm_constant_id_t old_param_name = parser->current_param_name;
- parser->current_param_name = 0;
- pm_parser_scope_push(parser, true);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
-
- pm_node_t *statements = NULL;
- if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_SCLASS);
- pm_accepts_block_stack_pop(parser);
- }
-
- if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
- }
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
-
- pm_constant_id_list_t locals = parser->current_scope->locals;
- pm_parser_scope_pop(parser);
- parser->current_param_name = old_param_name;
- pm_do_loop_stack_pop(parser);
- return (pm_node_t *) pm_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous);
- }
-
- pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_CLASS_NAME);
- pm_token_t name = parser->previous;
- if (name.type != PM_TOKEN_CONSTANT) {
- pm_parser_err_token(parser, &name, PM_ERR_CLASS_NAME);
- }
-
- pm_token_t inheritance_operator;
- pm_node_t *superclass;
-
- if (match1(parser, PM_TOKEN_LESS)) {
- inheritance_operator = parser->current;
- lex_state_set(parser, PM_LEX_STATE_BEG);
-
- parser->command_start = true;
- parser_lex(parser);
-
- superclass = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CLASS_SUPERCLASS);
- } else {
- inheritance_operator = not_provided(parser);
- superclass = NULL;
- }
-
- pm_constant_id_t old_param_name = parser->current_param_name;
- parser->current_param_name = 0;
- pm_parser_scope_push(parser, true);
- if (inheritance_operator.type != PM_TOKEN_NOT_PROVIDED) {
- expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CLASS_UNEXPECTED_END);
- } else {
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
- pm_node_t *statements = NULL;
-
- if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_CLASS);
- pm_accepts_block_stack_pop(parser);
- }
-
- if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
- }
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
-
- if (context_def_p(parser)) {
- pm_parser_err_token(parser, &class_keyword, PM_ERR_CLASS_IN_METHOD);
- }
-
- pm_constant_id_list_t locals = parser->current_scope->locals;
- pm_parser_scope_pop(parser);
- parser->current_param_name = old_param_name;
- pm_do_loop_stack_pop(parser);
-
- if (!PM_NODE_TYPE_P(constant_path, PM_CONSTANT_PATH_NODE) && !(PM_NODE_TYPE_P(constant_path, PM_CONSTANT_READ_NODE))) {
- pm_parser_err_node(parser, constant_path, PM_ERR_CLASS_NAME);
- }
-
- return (pm_node_t *) pm_class_node_create(parser, &locals, &class_keyword, constant_path, &name, &inheritance_operator, superclass, statements, &parser->previous);
- }
- case PM_TOKEN_KEYWORD_DEF: {
- pm_token_t def_keyword = parser->current;
-
- pm_node_t *receiver = NULL;
- pm_token_t operator = not_provided(parser);
- pm_token_t name = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = def_keyword.end, .end = def_keyword.end };
-
- // This context is necessary for lexing `...` in a bare params correctly.
- // It must be pushed before lexing the first param, so it is here.
- context_push(parser, PM_CONTEXT_DEF_PARAMS);
- parser_lex(parser);
- pm_constant_id_t old_param_name = parser->current_param_name;
-
- switch (parser->current.type) {
- case PM_CASE_OPERATOR:
- pm_parser_scope_push(parser, true);
- parser->current_param_name = 0;
- lex_state_set(parser, PM_LEX_STATE_ENDFN);
- parser_lex(parser);
- name = parser->previous;
- break;
- case PM_TOKEN_IDENTIFIER: {
- parser_lex(parser);
-
- if (match2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON)) {
- receiver = parse_variable_call(parser);
-
- pm_parser_scope_push(parser, true);
- parser->current_param_name = 0;
- lex_state_set(parser, PM_LEX_STATE_FNAME);
- parser_lex(parser);
-
- operator = parser->previous;
- name = parse_method_definition_name(parser);
- } else {
- pm_refute_numbered_parameter(parser, parser->previous.start, parser->previous.end);
- pm_parser_scope_push(parser, true);
- parser->current_param_name = 0;
- name = parser->previous;
- }
-
- break;
- }
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_INSTANCE_VARIABLE:
- case PM_TOKEN_CLASS_VARIABLE:
- case PM_TOKEN_GLOBAL_VARIABLE:
- case PM_TOKEN_KEYWORD_NIL:
- case PM_TOKEN_KEYWORD_SELF:
- case PM_TOKEN_KEYWORD_TRUE:
- case PM_TOKEN_KEYWORD_FALSE:
- case PM_TOKEN_KEYWORD___FILE__:
- case PM_TOKEN_KEYWORD___LINE__:
- case PM_TOKEN_KEYWORD___ENCODING__: {
- pm_parser_scope_push(parser, true);
- parser->current_param_name = 0;
- parser_lex(parser);
- pm_token_t identifier = parser->previous;
-
- if (match2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON)) {
- lex_state_set(parser, PM_LEX_STATE_FNAME);
- parser_lex(parser);
- operator = parser->previous;
-
- switch (identifier.type) {
- case PM_TOKEN_CONSTANT:
- receiver = (pm_node_t *) pm_constant_read_node_create(parser, &identifier);
- break;
- case PM_TOKEN_INSTANCE_VARIABLE:
- receiver = (pm_node_t *) pm_instance_variable_read_node_create(parser, &identifier);
- break;
- case PM_TOKEN_CLASS_VARIABLE:
- receiver = (pm_node_t *) pm_class_variable_read_node_create(parser, &identifier);
- break;
- case PM_TOKEN_GLOBAL_VARIABLE:
- receiver = (pm_node_t *) pm_global_variable_read_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD_NIL:
- receiver = (pm_node_t *) pm_nil_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD_SELF:
- receiver = (pm_node_t *) pm_self_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD_TRUE:
- receiver = (pm_node_t *) pm_true_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD_FALSE:
- receiver = (pm_node_t *)pm_false_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD___FILE__:
- receiver = (pm_node_t *) pm_source_file_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD___LINE__:
- receiver = (pm_node_t *) pm_source_line_node_create(parser, &identifier);
- break;
- case PM_TOKEN_KEYWORD___ENCODING__:
- receiver = (pm_node_t *) pm_source_encoding_node_create(parser, &identifier);
- break;
- default:
- break;
- }
-
- name = parse_method_definition_name(parser);
- } else {
- name = identifier;
- }
- break;
- }
- case PM_TOKEN_PARENTHESIS_LEFT: {
- // The current context is `PM_CONTEXT_DEF_PARAMS`, however the inner expression
- // of this parenthesis should not be processed under this context.
- // Thus, the context is popped here.
- context_pop(parser);
- parser_lex(parser);
-
- pm_token_t lparen = parser->previous;
- pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_DEF_RECEIVER);
-
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
- pm_token_t rparen = parser->previous;
-
- lex_state_set(parser, PM_LEX_STATE_FNAME);
- expect2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON, PM_ERR_DEF_RECEIVER_TERM);
-
- operator = parser->previous;
- receiver = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, expression, &rparen);
-
- pm_parser_scope_push(parser, true);
- parser->current_param_name = 0;
-
- // To push `PM_CONTEXT_DEF_PARAMS` again is for the same reason as described the above.
- context_push(parser, PM_CONTEXT_DEF_PARAMS);
- name = parse_method_definition_name(parser);
- break;
- }
- default:
- pm_parser_scope_push(parser, true);
- parser->current_param_name = 0;
- name = parse_method_definition_name(parser);
- break;
- }
-
- // If, after all that, we were unable to find a method name, add an
- // error to the error list.
- if (name.type == PM_TOKEN_MISSING) {
- pm_parser_err_previous(parser, PM_ERR_DEF_NAME);
- }
-
- pm_token_t lparen;
- pm_token_t rparen;
- pm_parameters_node_t *params;
-
- switch (parser->current.type) {
- case PM_TOKEN_PARENTHESIS_LEFT: {
- parser_lex(parser);
- lparen = parser->previous;
-
- if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- params = NULL;
- } else {
- params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, true, false, true);
- }
-
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser->command_start = true;
-
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_DEF_PARAMS_TERM_PAREN);
- rparen = parser->previous;
- break;
- }
- case PM_CASE_PARAMETER: {
- // If we're about to lex a label, we need to add the label
- // state to make sure the next newline is ignored.
- if (parser->current.type == PM_TOKEN_LABEL) {
- lex_state_set(parser, parser->lex_state | PM_LEX_STATE_LABEL);
- }
-
- lparen = not_provided(parser);
- rparen = not_provided(parser);
- params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true);
- break;
- }
- default: {
- lparen = not_provided(parser);
- rparen = not_provided(parser);
- params = NULL;
- break;
- }
- }
-
- uint32_t locals_body_index = (uint32_t) parser->current_scope->locals.size;
-
- context_pop(parser);
- pm_node_t *statements = NULL;
- pm_token_t equal;
- pm_token_t end_keyword;
-
- if (accept1(parser, PM_TOKEN_EQUAL)) {
- if (token_is_setter_name(&name)) {
- pm_parser_err_token(parser, &name, PM_ERR_DEF_ENDLESS_SETTER);
- }
- equal = parser->previous;
-
- context_push(parser, PM_CONTEXT_DEF);
- pm_do_loop_stack_push(parser, false);
- statements = (pm_node_t *) pm_statements_node_create(parser);
-
- pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, binding_power < PM_BINDING_POWER_COMPOSITION, PM_ERR_DEF_ENDLESS);
-
- if (accept1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
- pm_token_t rescue_keyword = parser->previous;
- pm_node_t *value = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
- pm_rescue_modifier_node_t *rescue_node = pm_rescue_modifier_node_create(parser, statement, &rescue_keyword, value);
- statement = (pm_node_t *)rescue_node;
- }
-
- pm_statements_node_body_append((pm_statements_node_t *) statements, statement);
- pm_do_loop_stack_pop(parser);
- context_pop(parser);
- end_keyword = not_provided(parser);
- } else {
- equal = not_provided(parser);
-
- if (lparen.type == PM_TOKEN_NOT_PROVIDED) {
- lex_state_set(parser, PM_LEX_STATE_BEG);
- parser->command_start = true;
- expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_DEF_PARAMS_TERM);
- } else {
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- }
-
- pm_accepts_block_stack_push(parser, true);
- pm_do_loop_stack_push(parser, false);
-
- if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_DEF);
- pm_accepts_block_stack_pop(parser);
- }
-
- if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, true);
- }
-
- pm_accepts_block_stack_pop(parser);
- pm_do_loop_stack_pop(parser);
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_DEF_TERM);
- end_keyword = parser->previous;
- }
-
- pm_constant_id_list_t locals = parser->current_scope->locals;
- parser->current_param_name = old_param_name;
- pm_parser_scope_pop(parser);
-
- return (pm_node_t *) pm_def_node_create(
- parser,
- &name,
- receiver,
- params,
- statements,
- &locals,
- locals_body_index,
- &def_keyword,
- &operator,
- &lparen,
- &rparen,
- &equal,
- &end_keyword
- );
- }
- case PM_TOKEN_KEYWORD_DEFINED: {
- parser_lex(parser);
- pm_token_t keyword = parser->previous;
-
- pm_token_t lparen;
- pm_token_t rparen;
- pm_node_t *expression;
-
- if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
- lparen = parser->previous;
- expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_DEFINED_EXPRESSION);
-
- if (parser->recovering) {
- rparen = not_provided(parser);
- } else {
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
- rparen = parser->previous;
- }
- } else {
- lparen = not_provided(parser);
- rparen = not_provided(parser);
- expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_DEFINED_EXPRESSION);
- }
-
- return (pm_node_t *) pm_defined_node_create(
- parser,
- &lparen,
- expression,
- &rparen,
- &PM_LOCATION_TOKEN_VALUE(&keyword)
- );
- }
- case PM_TOKEN_KEYWORD_END_UPCASE: {
- if (binding_power != PM_BINDING_POWER_STATEMENT) {
- pm_parser_err_current(parser, PM_ERR_STATEMENT_POSTEXE_END);
- }
-
- parser_lex(parser);
- pm_token_t keyword = parser->previous;
-
- if (context_def_p(parser)) {
- pm_parser_warn_token(parser, &keyword, PM_WARN_END_IN_METHOD);
- }
-
- expect1(parser, PM_TOKEN_BRACE_LEFT, PM_ERR_END_UPCASE_BRACE);
- pm_token_t opening = parser->previous;
- pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_POSTEXE);
-
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM);
- return (pm_node_t *) pm_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous);
- }
- case PM_TOKEN_KEYWORD_FALSE:
- parser_lex(parser);
- return (pm_node_t *)pm_false_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_FOR: {
- parser_lex(parser);
- pm_token_t for_keyword = parser->previous;
- pm_node_t *index;
-
- context_push(parser, PM_CONTEXT_FOR_INDEX);
-
- // First, parse out the first index expression.
- if (accept1(parser, PM_TOKEN_USTAR)) {
- pm_token_t star_operator = parser->previous;
- pm_node_t *name = NULL;
-
- if (token_begins_expression_p(parser->current.type)) {
- name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
- }
-
- index = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name);
- } else if (token_begins_expression_p(parser->current.type)) {
- index = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
- } else {
- pm_parser_err_token(parser, &for_keyword, PM_ERR_FOR_INDEX);
- index = (pm_node_t *) pm_missing_node_create(parser, for_keyword.start, for_keyword.end);
- }
-
- // Now, if there are multiple index expressions, parse them out.
- if (match1(parser, PM_TOKEN_COMMA)) {
- index = parse_targets(parser, index, PM_BINDING_POWER_INDEX);
- } else {
- index = parse_target(parser, index);
- }
-
- context_pop(parser);
- pm_do_loop_stack_push(parser, true);
-
- expect1(parser, PM_TOKEN_KEYWORD_IN, PM_ERR_FOR_IN);
- pm_token_t in_keyword = parser->previous;
-
- pm_node_t *collection = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_FOR_COLLECTION);
- pm_do_loop_stack_pop(parser);
-
- pm_token_t do_keyword;
- if (accept1(parser, PM_TOKEN_KEYWORD_DO_LOOP)) {
- do_keyword = parser->previous;
- } else {
- do_keyword = not_provided(parser);
- }
-
- accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE);
- pm_statements_node_t *statements = NULL;
-
- if (!accept1(parser, PM_TOKEN_KEYWORD_END)) {
- statements = parse_statements(parser, PM_CONTEXT_FOR);
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM);
- }
-
- return (pm_node_t *) pm_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous);
- }
- case PM_TOKEN_KEYWORD_IF:
- parser_lex(parser);
- return parse_conditional(parser, PM_CONTEXT_IF);
- case PM_TOKEN_KEYWORD_UNDEF: {
- if (binding_power != PM_BINDING_POWER_STATEMENT) {
- pm_parser_err_current(parser, PM_ERR_STATEMENT_UNDEF);
- }
-
- parser_lex(parser);
- pm_undef_node_t *undef = pm_undef_node_create(parser, &parser->previous);
- pm_node_t *name = parse_undef_argument(parser);
-
- if (PM_NODE_TYPE_P(name, PM_MISSING_NODE)) {
- pm_node_destroy(parser, name);
- } else {
- pm_undef_node_append(undef, name);
-
- while (match1(parser, PM_TOKEN_COMMA)) {
- lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM);
- parser_lex(parser);
- name = parse_undef_argument(parser);
-
- if (PM_NODE_TYPE_P(name, PM_MISSING_NODE)) {
- pm_node_destroy(parser, name);
- break;
- }
-
- pm_undef_node_append(undef, name);
- }
- }
-
- return (pm_node_t *) undef;
- }
- case PM_TOKEN_KEYWORD_NOT: {
- parser_lex(parser);
-
- pm_token_t message = parser->previous;
- pm_arguments_t arguments = { 0 };
- pm_node_t *receiver = NULL;
-
- accept1(parser, PM_TOKEN_NEWLINE);
-
- if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
- arguments.opening_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
-
- if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
- } else {
- receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_NOT_EXPRESSION);
- pm_conditional_predicate(receiver);
-
- if (!parser->recovering) {
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
- arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
- }
- }
- } else {
- receiver = parse_expression(parser, PM_BINDING_POWER_NOT, true, PM_ERR_NOT_EXPRESSION);
- pm_conditional_predicate(receiver);
- }
-
- return (pm_node_t *) pm_call_node_not_create(parser, receiver, &message, &arguments);
- }
- case PM_TOKEN_KEYWORD_UNLESS:
- parser_lex(parser);
- return parse_conditional(parser, PM_CONTEXT_UNLESS);
- case PM_TOKEN_KEYWORD_MODULE: {
- parser_lex(parser);
-
- pm_token_t module_keyword = parser->previous;
- pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_MODULE_NAME);
- pm_token_t name;
-
- // If we can recover from a syntax error that occurred while parsing
- // the name of the module, then we'll handle that here.
- if (PM_NODE_TYPE_P(constant_path, PM_MISSING_NODE)) {
- pm_token_t missing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- return (pm_node_t *) pm_module_node_create(parser, NULL, &module_keyword, constant_path, &missing, NULL, &missing);
- }
-
- while (accept1(parser, PM_TOKEN_COLON_COLON)) {
- pm_token_t double_colon = parser->previous;
-
- expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
- pm_node_t *constant = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous);
-
- constant_path = (pm_node_t *) pm_constant_path_node_create(parser, constant_path, &double_colon, constant);
- }
-
- // Here we retrieve the name of the module. If it wasn't a constant,
- // then it's possible that `module foo` was passed, which is a
- // syntax error. We handle that here as well.
- name = parser->previous;
- if (name.type != PM_TOKEN_CONSTANT) {
- pm_parser_err_token(parser, &name, PM_ERR_MODULE_NAME);
- }
-
- pm_constant_id_t old_param_name = parser->current_param_name;
- parser->current_param_name = 0;
- pm_parser_scope_push(parser, true);
- accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE);
- pm_node_t *statements = NULL;
-
- if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_MODULE);
- pm_accepts_block_stack_pop(parser);
- }
-
- if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
- statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
- }
-
- pm_constant_id_list_t locals = parser->current_scope->locals;
- pm_parser_scope_pop(parser);
- parser->current_param_name = old_param_name;
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM);
-
- if (context_def_p(parser)) {
- pm_parser_err_token(parser, &module_keyword, PM_ERR_MODULE_IN_METHOD);
- }
-
- return (pm_node_t *) pm_module_node_create(parser, &locals, &module_keyword, constant_path, &name, statements, &parser->previous);
- }
- case PM_TOKEN_KEYWORD_NIL:
- parser_lex(parser);
- return (pm_node_t *) pm_nil_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_REDO:
- parser_lex(parser);
- return (pm_node_t *) pm_redo_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_RETRY:
- parser_lex(parser);
- return (pm_node_t *) pm_retry_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_SELF:
- parser_lex(parser);
- return (pm_node_t *) pm_self_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_TRUE:
- parser_lex(parser);
- return (pm_node_t *) pm_true_node_create(parser, &parser->previous);
- case PM_TOKEN_KEYWORD_UNTIL: {
- pm_do_loop_stack_push(parser, true);
- parser_lex(parser);
- pm_token_t keyword = parser->previous;
-
- pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
- pm_do_loop_stack_pop(parser);
-
- expect3(parser, PM_TOKEN_KEYWORD_DO_LOOP, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
- pm_statements_node_t *statements = NULL;
-
- if (!accept1(parser, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = parse_statements(parser, PM_CONTEXT_UNTIL);
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM);
- }
-
- return (pm_node_t *) pm_until_node_create(parser, &keyword, &parser->previous, predicate, statements, 0);
- }
- case PM_TOKEN_KEYWORD_WHILE: {
- pm_do_loop_stack_push(parser, true);
- parser_lex(parser);
- pm_token_t keyword = parser->previous;
-
- pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
- pm_do_loop_stack_pop(parser);
-
- expect3(parser, PM_TOKEN_KEYWORD_DO_LOOP, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
- pm_statements_node_t *statements = NULL;
-
- if (!accept1(parser, PM_TOKEN_KEYWORD_END)) {
- pm_accepts_block_stack_push(parser, true);
- statements = parse_statements(parser, PM_CONTEXT_WHILE);
- pm_accepts_block_stack_pop(parser);
- accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM);
- }
-
- return (pm_node_t *) pm_while_node_create(parser, &keyword, &parser->previous, predicate, statements, 0);
- }
- case PM_TOKEN_PERCENT_LOWER_I: {
- parser_lex(parser);
- pm_token_t opening = parser->previous;
- pm_array_node_t *array = pm_array_node_create(parser, &opening);
-
- while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- accept1(parser, PM_TOKEN_WORDS_SEP);
- if (match1(parser, PM_TOKEN_STRING_END)) break;
-
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_array_node_elements_append(array, (pm_node_t *) pm_symbol_node_create_current_string(parser, &opening, &parser->current, &closing));
- }
-
- expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_I_LOWER_ELEMENT);
- }
-
- pm_token_t closing = parser->current;
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_LIST_I_LOWER_TERM);
- closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_LOWER_TERM);
- }
- pm_array_node_close_set(array, &closing);
-
- return (pm_node_t *) array;
- }
- case PM_TOKEN_PERCENT_UPPER_I: {
- parser_lex(parser);
- pm_token_t opening = parser->previous;
- pm_array_node_t *array = pm_array_node_create(parser, &opening);
-
- // This is the current node that we are parsing that will be added to the
- // list of elements.
- pm_node_t *current = NULL;
-
- while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- switch (parser->current.type) {
- case PM_TOKEN_WORDS_SEP: {
- if (current == NULL) {
- // If we hit a separator before we have any content, then we don't
- // need to do anything.
- } else {
- // If we hit a separator after we've hit content, then we need to
- // append that content to the list and reset the current node.
- pm_array_node_elements_append(array, current);
- current = NULL;
- }
-
- parser_lex(parser);
- break;
- }
- case PM_TOKEN_STRING_CONTENT: {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
-
- if (current == NULL) {
- // If we hit content and the current node is NULL, then this is
- // the first string content we've seen. In that case we're going
- // to create a new string node and set that to the current.
- current = (pm_node_t *) pm_symbol_node_create_current_string(parser, &opening, &parser->current, &closing);
- parser_lex(parser);
- } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_SYMBOL_NODE)) {
- // If we hit string content and the current node is an
- // interpolated string, then we need to append the string content
- // to the list of child nodes.
- pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing);
- parser_lex(parser);
-
- pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, string);
- } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) {
- // If we hit string content and the current node is a string node,
- // then we need to convert the current node into an interpolated
- // string and add the string content to the list of child nodes.
- pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->previous, &closing);
- parser_lex(parser);
-
- pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing);
- pm_interpolated_symbol_node_append(interpolated, current);
- pm_interpolated_symbol_node_append(interpolated, string);
- current = (pm_node_t *) interpolated;
- } else {
- assert(false && "unreachable");
- }
-
- break;
- }
- case PM_TOKEN_EMBVAR: {
- bool start_location_set = false;
- if (current == NULL) {
- // If we hit an embedded variable and the current node is NULL,
- // then this is the start of a new string. We'll set the current
- // node to a new interpolated string.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- current = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing);
- } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) {
- // If we hit an embedded variable and the current node is a string
- // node, then we'll convert the current into an interpolated
- // string and add the string node to the list of parts.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing);
-
- current = (pm_node_t *) pm_symbol_node_to_string_node(parser, (pm_symbol_node_t *) current);
- pm_interpolated_symbol_node_append(interpolated, current);
- interpolated->base.location.start = current->location.start;
- start_location_set = true;
- current = (pm_node_t *) interpolated;
- } else {
- // If we hit an embedded variable and the current node is an
- // interpolated string, then we'll just add the embedded variable.
- }
-
- pm_node_t *part = parse_string_part(parser);
- pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part);
- if (!start_location_set) {
- current->location.start = part->location.start;
- }
- break;
- }
- case PM_TOKEN_EMBEXPR_BEGIN: {
- bool start_location_set = false;
- if (current == NULL) {
- // If we hit an embedded expression and the current node is NULL,
- // then this is the start of a new string. We'll set the current
- // node to a new interpolated string.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- current = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing);
- } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) {
- // If we hit an embedded expression and the current node is a
- // string node, then we'll convert the current into an
- // interpolated string and add the string node to the list of
- // parts.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing);
-
- current = (pm_node_t *) pm_symbol_node_to_string_node(parser, (pm_symbol_node_t *) current);
- pm_interpolated_symbol_node_append(interpolated, current);
- interpolated->base.location.start = current->location.start;
- start_location_set = true;
- current = (pm_node_t *) interpolated;
- } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_SYMBOL_NODE)) {
- // If we hit an embedded expression and the current node is an
- // interpolated string, then we'll just continue on.
- } else {
- assert(false && "unreachable");
- }
-
- pm_node_t *part = parse_string_part(parser);
- pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part);
- if (!start_location_set) {
- current->location.start = part->location.start;
- }
- break;
- }
- default:
- expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_I_UPPER_ELEMENT);
- parser_lex(parser);
- break;
- }
- }
-
- // If we have a current node, then we need to append it to the list.
- if (current) {
- pm_array_node_elements_append(array, current);
- }
-
- pm_token_t closing = parser->current;
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_LIST_I_UPPER_TERM);
- closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_UPPER_TERM);
- }
- pm_array_node_close_set(array, &closing);
-
- return (pm_node_t *) array;
- }
- case PM_TOKEN_PERCENT_LOWER_W: {
- parser_lex(parser);
- pm_token_t opening = parser->previous;
- pm_array_node_t *array = pm_array_node_create(parser, &opening);
-
- // skip all leading whitespaces
- accept1(parser, PM_TOKEN_WORDS_SEP);
-
- while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- accept1(parser, PM_TOKEN_WORDS_SEP);
- if (match1(parser, PM_TOKEN_STRING_END)) break;
-
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
-
- pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing);
- pm_array_node_elements_append(array, string);
- }
-
- expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_W_LOWER_ELEMENT);
- }
-
- pm_token_t closing = parser->current;
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_LIST_W_LOWER_TERM);
- closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_LOWER_TERM);
- }
-
- pm_array_node_close_set(array, &closing);
- return (pm_node_t *) array;
- }
- case PM_TOKEN_PERCENT_UPPER_W: {
- parser_lex(parser);
- pm_token_t opening = parser->previous;
- pm_array_node_t *array = pm_array_node_create(parser, &opening);
-
- // This is the current node that we are parsing that will be added
- // to the list of elements.
- pm_node_t *current = NULL;
-
- while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- switch (parser->current.type) {
- case PM_TOKEN_WORDS_SEP: {
- // Reset the explicit encoding if we hit a separator
- // since each element can have its own encoding.
- parser->explicit_encoding = NULL;
-
- if (current == NULL) {
- // If we hit a separator before we have any content,
- // then we don't need to do anything.
- } else {
- // If we hit a separator after we've hit content,
- // then we need to append that content to the list
- // and reset the current node.
- pm_array_node_elements_append(array, current);
- current = NULL;
- }
-
- parser_lex(parser);
- break;
- }
- case PM_TOKEN_STRING_CONTENT: {
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
-
- pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing);
- pm_node_flag_set(string, parse_unescaped_encoding(parser));
- parser_lex(parser);
-
- if (current == NULL) {
- // If we hit content and the current node is NULL,
- // then this is the first string content we've seen.
- // In that case we're going to create a new string
- // node and set that to the current.
- current = string;
- } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) {
- // If we hit string content and the current node is
- // an interpolated string, then we need to append
- // the string content to the list of child nodes.
- pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, string);
- } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) {
- // If we hit string content and the current node is
- // a string node, then we need to convert the
- // current node into an interpolated string and add
- // the string content to the list of child nodes.
- pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
- pm_interpolated_string_node_append(interpolated, current);
- pm_interpolated_string_node_append(interpolated, string);
- current = (pm_node_t *) interpolated;
- } else {
- assert(false && "unreachable");
- }
-
- break;
- }
- case PM_TOKEN_EMBVAR: {
- if (current == NULL) {
- // If we hit an embedded variable and the current
- // node is NULL, then this is the start of a new
- // string. We'll set the current node to a new
- // interpolated string.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- current = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
- } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) {
- // If we hit an embedded variable and the current
- // node is a string node, then we'll convert the
- // current into an interpolated string and add the
- // string node to the list of parts.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
- pm_interpolated_string_node_append(interpolated, current);
- current = (pm_node_t *) interpolated;
- } else {
- // If we hit an embedded variable and the current
- // node is an interpolated string, then we'll just
- // add the embedded variable.
- }
-
- pm_node_t *part = parse_string_part(parser);
- pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part);
- break;
- }
- case PM_TOKEN_EMBEXPR_BEGIN: {
- if (current == NULL) {
- // If we hit an embedded expression and the current
- // node is NULL, then this is the start of a new
- // string. We'll set the current node to a new
- // interpolated string.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- current = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
- } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) {
- // If we hit an embedded expression and the current
- // node is a string node, then we'll convert the
- // current into an interpolated string and add the
- // string node to the list of parts.
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
- pm_interpolated_string_node_append(interpolated, current);
- current = (pm_node_t *) interpolated;
- } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) {
- // If we hit an embedded expression and the current
- // node is an interpolated string, then we'll just
- // continue on.
- } else {
- assert(false && "unreachable");
- }
-
- pm_node_t *part = parse_string_part(parser);
- pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part);
- break;
- }
- default:
- expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_W_UPPER_ELEMENT);
- parser_lex(parser);
- break;
- }
- }
-
- // If we have a current node, then we need to append it to the list.
- if (current) {
- pm_array_node_elements_append(array, current);
- }
-
- pm_token_t closing = parser->current;
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_LIST_W_UPPER_TERM);
- closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_UPPER_TERM);
- }
-
- pm_array_node_close_set(array, &closing);
- return (pm_node_t *) array;
- }
- case PM_TOKEN_REGEXP_BEGIN: {
- pm_token_t opening = parser->current;
- parser_lex(parser);
-
- if (match1(parser, PM_TOKEN_REGEXP_END)) {
- // If we get here, then we have an end immediately after a start. In
- // that case we'll create an empty content token and return an
- // uninterpolated regular expression.
- pm_token_t content = (pm_token_t) {
- .type = PM_TOKEN_STRING_CONTENT,
- .start = parser->previous.end,
- .end = parser->previous.end
- };
-
- parser_lex(parser);
- return (pm_node_t *) pm_regular_expression_node_create(parser, &opening, &content, &parser->previous);
- }
-
- pm_interpolated_regular_expression_node_t *node;
-
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- // In this case we've hit string content so we know the regular
- // expression at least has something in it. We'll need to check if the
- // following token is the end (in which case we can return a plain
- // regular expression) or if it's not then it has interpolation.
- pm_string_t unescaped = parser->current_string;
- pm_token_t content = parser->current;
- parser_lex(parser);
-
- // If we hit an end, then we can create a regular expression node
- // without interpolation, which can be represented more succinctly and
- // more easily compiled.
- if (accept1(parser, PM_TOKEN_REGEXP_END)) {
- return (pm_node_t *) pm_regular_expression_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
- }
-
- // If we get here, then we have interpolation so we'll need to create
- // a regular expression node with interpolation.
- node = pm_interpolated_regular_expression_node_create(parser, &opening);
-
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
- pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &parser->previous, &closing, &unescaped);
- pm_interpolated_regular_expression_node_append(node, part);
- } else {
- // If the first part of the body of the regular expression is not a
- // string content, then we have interpolation and we need to create an
- // interpolated regular expression node.
- node = pm_interpolated_regular_expression_node_create(parser, &opening);
- }
-
- // Now that we're here and we have interpolation, we'll parse all of the
- // parts into the list.
- pm_node_t *part;
- while (!match2(parser, PM_TOKEN_REGEXP_END, PM_TOKEN_EOF)) {
- if ((part = parse_string_part(parser)) != NULL) {
- pm_interpolated_regular_expression_node_append(node, part);
- }
- }
-
- pm_token_t closing = parser->current;
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_REGEXP_TERM);
- closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- } else {
- expect1(parser, PM_TOKEN_REGEXP_END, PM_ERR_REGEXP_TERM);
- }
- pm_interpolated_regular_expression_node_closing_set(node, &closing);
-
- return (pm_node_t *) node;
- }
- case PM_TOKEN_BACKTICK:
- case PM_TOKEN_PERCENT_LOWER_X: {
- parser_lex(parser);
- pm_token_t opening = parser->previous;
-
- // When we get here, we don't know if this string is going to have
- // interpolation or not, even though it is allowed. Still, we want to be
- // able to return a string node without interpolation if we can since
- // it'll be faster.
- if (match1(parser, PM_TOKEN_STRING_END)) {
- // If we get here, then we have an end immediately after a start. In
- // that case we'll create an empty content token and return an
- // uninterpolated string.
- pm_token_t content = (pm_token_t) {
- .type = PM_TOKEN_STRING_CONTENT,
- .start = parser->previous.end,
- .end = parser->previous.end
- };
-
- parser_lex(parser);
- return (pm_node_t *) pm_xstring_node_create(parser, &opening, &content, &parser->previous);
- }
-
- pm_interpolated_x_string_node_t *node;
-
- if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- // In this case we've hit string content so we know the string
- // at least has something in it. We'll need to check if the
- // following token is the end (in which case we can return a
- // plain string) or if it's not then it has interpolation.
- pm_string_t unescaped = parser->current_string;
- pm_token_t content = parser->current;
- parser_lex(parser);
-
- if (match1(parser, PM_TOKEN_STRING_END)) {
- pm_node_t *node = (pm_node_t *) pm_xstring_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
- pm_node_flag_set(node, parse_unescaped_encoding(parser));
- parser_lex(parser);
- return node;
- }
-
- // If we get here, then we have interpolation so we'll need to
- // create a string node with interpolation.
- node = pm_interpolated_xstring_node_create(parser, &opening, &opening);
-
- pm_token_t opening = not_provided(parser);
- pm_token_t closing = not_provided(parser);
-
- pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &parser->previous, &closing, &unescaped);
- pm_node_flag_set(part, parse_unescaped_encoding(parser));
-
- pm_interpolated_xstring_node_append(node, part);
- } else {
- // If the first part of the body of the string is not a string
- // content, then we have interpolation and we need to create an
- // interpolated string node.
- node = pm_interpolated_xstring_node_create(parser, &opening, &opening);
- }
-
- pm_node_t *part;
- while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
- if ((part = parse_string_part(parser)) != NULL) {
- pm_interpolated_xstring_node_append(node, part);
- }
- }
-
- pm_token_t closing = parser->current;
- if (match1(parser, PM_TOKEN_EOF)) {
- pm_parser_err_token(parser, &opening, PM_ERR_XSTRING_TERM);
- closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- } else {
- expect1(parser, PM_TOKEN_STRING_END, PM_ERR_XSTRING_TERM);
- }
- pm_interpolated_xstring_node_closing_set(node, &closing);
-
- return (pm_node_t *) node;
- }
- case PM_TOKEN_USTAR: {
- parser_lex(parser);
-
- // * operators at the beginning of expressions are only valid in the
- // context of a multiple assignment. We enforce that here. We'll
- // still lex past it though and create a missing node place.
- if (binding_power != PM_BINDING_POWER_STATEMENT) {
- return (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end);
- }
-
- pm_token_t operator = parser->previous;
- pm_node_t *name = NULL;
-
- if (token_begins_expression_p(parser->current.type)) {
- name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
- }
-
- pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &operator, name);
-
- if (match1(parser, PM_TOKEN_COMMA)) {
- return parse_targets_validate(parser, splat, PM_BINDING_POWER_INDEX);
- } else {
- return parse_target_validate(parser, splat);
- }
- }
- case PM_TOKEN_BANG: {
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, binding_power < PM_BINDING_POWER_MATCH, PM_ERR_UNARY_RECEIVER_BANG);
- pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "!");
-
- pm_conditional_predicate(receiver);
- return (pm_node_t *) node;
- }
- case PM_TOKEN_TILDE: {
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_TILDE);
- pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "~");
-
- return (pm_node_t *) node;
- }
- case PM_TOKEN_UMINUS: {
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_MINUS);
- pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "-@");
-
- return (pm_node_t *) node;
- }
- case PM_TOKEN_UMINUS_NUM: {
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *node = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_MINUS);
-
- if (accept1(parser, PM_TOKEN_STAR_STAR)) {
- pm_token_t exponent_operator = parser->previous;
- pm_node_t *exponent = parse_expression(parser, pm_binding_powers[exponent_operator.type].right, false, PM_ERR_EXPECT_ARGUMENT);
- node = (pm_node_t *) pm_call_node_binary_create(parser, node, &exponent_operator, exponent);
- node = (pm_node_t *) pm_call_node_unary_create(parser, &operator, node, "-@");
- } else {
- switch (PM_NODE_TYPE(node)) {
- case PM_INTEGER_NODE:
- case PM_FLOAT_NODE:
- case PM_RATIONAL_NODE:
- case PM_IMAGINARY_NODE:
- parse_negative_numeric(node);
- break;
- default:
- node = (pm_node_t *) pm_call_node_unary_create(parser, &operator, node, "-@");
- break;
- }
- }
-
- return node;
- }
- case PM_TOKEN_MINUS_GREATER: {
- int previous_lambda_enclosure_nesting = parser->lambda_enclosure_nesting;
- parser->lambda_enclosure_nesting = parser->enclosure_nesting;
-
- pm_accepts_block_stack_push(parser, true);
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_parser_scope_push(parser, false);
- pm_block_parameters_node_t *block_parameters;
-
- switch (parser->current.type) {
- case PM_TOKEN_PARENTHESIS_LEFT: {
- parser->current_scope->explicit_params = true;
- pm_token_t opening = parser->current;
- parser_lex(parser);
-
- if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
- block_parameters = pm_block_parameters_node_create(parser, NULL, &opening);
- } else {
- block_parameters = parse_block_parameters(parser, false, &opening, true);
- }
-
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
-
- pm_block_parameters_node_closing_set(block_parameters, &parser->previous);
- break;
- }
- case PM_CASE_PARAMETER: {
- parser->current_scope->explicit_params = true;
- pm_accepts_block_stack_push(parser, false);
- pm_token_t opening = not_provided(parser);
- block_parameters = parse_block_parameters(parser, false, &opening, true);
- pm_accepts_block_stack_pop(parser);
- break;
- }
- default: {
- block_parameters = NULL;
- break;
- }
- }
-
- uint32_t locals_body_index = 0;
-
- if (block_parameters) {
- locals_body_index = (uint32_t) parser->current_scope->locals.size;
- }
-
- pm_token_t opening;
- pm_node_t *body = NULL;
- parser->lambda_enclosure_nesting = previous_lambda_enclosure_nesting;
-
- if (accept1(parser, PM_TOKEN_LAMBDA_BEGIN)) {
- opening = parser->previous;
-
- if (!accept1(parser, PM_TOKEN_BRACE_RIGHT)) {
- body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_BRACES);
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE);
- }
- } else {
- expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN);
- opening = parser->previous;
-
- if (!match3(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- pm_accepts_block_stack_push(parser, true);
- body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_DO_END);
- pm_accepts_block_stack_pop(parser);
- }
-
- if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
- assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE));
- body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body, false);
- }
-
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
- }
-
- pm_node_t *parameters = (pm_node_t *) block_parameters;
- uint8_t maximum = parser->current_scope->numbered_parameters;
-
- if (parameters == NULL && (maximum > 0)) {
- parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = operator.start, .end = parser->previous.end }, maximum);
- locals_body_index = maximum;
- }
-
- pm_constant_id_list_t locals = parser->current_scope->locals;
- pm_parser_scope_pop(parser);
- pm_accepts_block_stack_pop(parser);
- return (pm_node_t *) pm_lambda_node_create(parser, &locals, locals_body_index, &operator, &opening, &parser->previous, parameters, body);
- }
- case PM_TOKEN_UPLUS: {
- parser_lex(parser);
-
- pm_token_t operator = parser->previous;
- pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_PLUS);
- pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "+@");
-
- return (pm_node_t *) node;
- }
- case PM_TOKEN_STRING_BEGIN:
- return parse_strings(parser, NULL);
- case PM_TOKEN_SYMBOL_BEGIN: {
- pm_lex_mode_t lex_mode = *parser->lex_modes.current;
- parser_lex(parser);
-
- return parse_symbol(parser, &lex_mode, PM_LEX_STATE_END);
- }
- default:
- if (context_recoverable(parser, &parser->current)) {
- parser->recovering = true;
- }
-
- return (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end);
- }
-}
-
-static inline pm_node_t *
-parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
- pm_node_t *value = parse_value_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, diag_id);
-
- // Contradicting binding powers, the right-hand-side value of rthe assignment allows the `rescue` modifier.
- if (match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
- pm_token_t rescue = parser->current;
- parser_lex(parser);
- pm_node_t *right = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
-
- return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
- }
-
- return value;
-}
-
-
-static inline pm_node_t *
-parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
- pm_node_t *value = parse_starred_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, diag_id);
-
- bool is_single_value = true;
- if (previous_binding_power == PM_BINDING_POWER_STATEMENT && (PM_NODE_TYPE_P(value, PM_SPLAT_NODE) || match1(parser, PM_TOKEN_COMMA))) {
- is_single_value = false;
- pm_token_t opening = not_provided(parser);
- pm_array_node_t *array = pm_array_node_create(parser, &opening);
-
- pm_array_node_elements_append(array, value);
- value = (pm_node_t *) array;
-
- while (accept1(parser, PM_TOKEN_COMMA)) {
- pm_node_t *element = parse_starred_expression(parser, binding_power, false, PM_ERR_ARRAY_ELEMENT);
- pm_array_node_elements_append(array, element);
- if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break;
- }
- }
-
- // Contradicting binding powers, the right-hand-side value of the assignment allows the `rescue` modifier.
- if (is_single_value && match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
- pm_token_t rescue = parser->current;
- parser_lex(parser);
- pm_node_t *right = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
-
- return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
- }
-
- return value;
-}
-
-/**
- * Ensures a call node that is about to become a call operator node does not
- * have arguments or a block attached. If it does, then we'll need to add an
- * error message and destroy the arguments/block. Ideally we would keep the node
- * around so that consumers would still have access to it, but we don't have a
- * great structure for that at the moment.
- */
-static void
-parse_call_operator_write(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) {
- if (call_node->arguments != NULL) {
- pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_ARGUMENTS);
- pm_node_destroy(parser, (pm_node_t *) call_node->arguments);
- call_node->arguments = NULL;
- }
-
- if (call_node->block != NULL) {
- pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_BLOCK);
- pm_node_destroy(parser, (pm_node_t *) call_node->block);
- call_node->block = NULL;
- }
-}
-
-static bool
-name_is_identifier(pm_parser_t *parser, const uint8_t *source, size_t length) {
- if (length == 0) {
- return false;
- }
-
- size_t width = char_is_identifier_start(parser, source);
- if (!width) {
- return false;
- }
-
- uint8_t *cursor = ((uint8_t *)source) + width;
- while (cursor < source + length && (width = char_is_identifier(parser, cursor))) {
- cursor += width;
- }
-
- return cursor == source + length;
-}
-
-/**
- * Potentially change a =~ with a regular expression with named captures into a
- * match write node.
- */
-static pm_node_t *
-parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t *content, pm_call_node_t *call) {
- pm_string_list_t named_captures = { 0 };
- pm_node_t *result;
-
- if (pm_regexp_named_capture_group_names(pm_string_source(content), pm_string_length(content), &named_captures, parser->encoding_changed, parser->encoding) && (named_captures.length > 0)) {
- // Since we should not create a MatchWriteNode when all capture names
- // are invalid, creating a MatchWriteNode is delayed here.
- pm_match_write_node_t *match = NULL;
- pm_constant_id_list_t names = { 0 };
-
- for (size_t index = 0; index < named_captures.length; index++) {
- pm_string_t *string = &named_captures.strings[index];
-
- const uint8_t *source = pm_string_source(string);
- size_t length = pm_string_length(string);
-
- pm_location_t location;
- pm_constant_id_t name;
-
- // If the name of the capture group isn't a valid identifier, we do
- // not add it to the local table.
- if (!name_is_identifier(parser, source, length)) continue;
-
- if (content->type == PM_STRING_SHARED) {
- // If the unescaped string is a slice of the source, then we can
- // copy the names directly. The pointers will line up.
- location = (pm_location_t) { .start = source, .end = source + length };
- name = pm_parser_constant_id_location(parser, location.start, location.end);
- pm_refute_numbered_parameter(parser, source, source + length);
- } else {
- // Otherwise, the name is a slice of the malloc-ed owned string,
- // in which case we need to copy it out into a new string.
- location = call->receiver->location;
-
- void *memory = malloc(length);
- if (memory == NULL) abort();
-
- memcpy(memory, source, length);
- // This silences clang analyzer warning about leak of memory pointed by `memory`.
- // NOLINTNEXTLINE(clang-analyzer-*)
- name = pm_parser_constant_id_owned(parser, (const uint8_t *) memory, length);
-
- if (pm_token_is_numbered_parameter(source, source + length)) {
- const pm_location_t *location = &call->receiver->location;
- PM_PARSER_ERR_LOCATION_FORMAT(parser, location, PM_ERR_PARAMETER_NUMBERED_RESERVED, location->start);
- }
- }
-
- if (name != 0) {
- // We dont want to create duplicate targets if the capture name
- // is duplicated.
- if (pm_constant_id_list_includes(&names, name)) continue;
- pm_constant_id_list_append(&names, name);
-
- // Here we lazily create the MatchWriteNode since we know we're
- // about to add a target.
- if (match == NULL) match = pm_match_write_node_create(parser, call);
-
- // First, find the depth of the local that is being assigned.
- int depth;
- if ((depth = pm_parser_local_depth_constant_id(parser, name)) == -1) {
- pm_parser_local_add(parser, name);
- }
-
- // Next, create the local variable target and add it to the
- // list of targets for the match.
- pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create_values(parser, &location, name, depth == -1 ? 0 : (uint32_t) depth);
- pm_node_list_append(&match->targets, target);
- }
- }
-
- if (match != NULL) {
- result = (pm_node_t *) match;
- } else {
- result = (pm_node_t *) call;
- }
-
- pm_constant_id_list_free(&names);
- } else {
- result = (pm_node_t *) call;
- }
-
- pm_string_list_free(&named_captures);
- return result;
-}
-
-static inline pm_node_t *
-parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call) {
- pm_token_t token = parser->current;
-
- switch (token.type) {
- case PM_TOKEN_EQUAL: {
- switch (PM_NODE_TYPE(node)) {
- case PM_CALL_NODE: {
- // If we have no arguments to the call node and we need this
- // to be a target then this is either a method call or a
- // local variable write. This _must_ happen before the value
- // is parsed because it could be referenced in the value.
- pm_call_node_t *call_node = (pm_call_node_t *) node;
- if (pm_call_node_variable_call_p(call_node)) {
- pm_parser_local_add_location(parser, call_node->message_loc.start, call_node->message_loc.end);
- }
- }
- /* fallthrough */
- case PM_CASE_WRITABLE: {
- parser_lex(parser);
- pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_NODE_TYPE_P(node, PM_MULTI_TARGET_NODE) ? PM_BINDING_POWER_MULTI_ASSIGNMENT + 1 : binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
- return parse_write(parser, node, &token, value);
- }
- case PM_SPLAT_NODE: {
- pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser);
- pm_multi_target_node_targets_append(parser, multi_target, node);
-
- parser_lex(parser);
- pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_BINDING_POWER_MULTI_ASSIGNMENT + 1, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
- return parse_write(parser, (pm_node_t *) multi_target, &token, value);
- }
- default:
- parser_lex(parser);
-
- // In this case we have an = sign, but we don't know what it's for. We
- // need to treat it as an error. For now, we'll mark it as an error
- // and just skip right past it.
- pm_parser_err_token(parser, &token, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
- return node;
- }
- }
- case PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL: {
- switch (PM_NODE_TYPE(node)) {
- case PM_BACK_REFERENCE_READ_NODE:
- case PM_NUMBERED_REFERENCE_READ_NODE:
- pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_READONLY);
- /* fallthrough */
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- pm_node_t *result = (pm_node_t *) pm_global_variable_and_write_node_create(parser, node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CLASS_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- pm_node_t *result = (pm_node_t *) pm_class_variable_and_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CONSTANT_PATH_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- return (pm_node_t *) pm_constant_path_and_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
- }
- case PM_CONSTANT_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- pm_node_t *result = (pm_node_t *) pm_constant_and_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_INSTANCE_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- pm_node_t *result = (pm_node_t *) pm_instance_variable_and_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_LOCAL_VARIABLE_READ_NODE: {
- pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CALL_NODE: {
- parser_lex(parser);
- pm_call_node_t *cast = (pm_call_node_t *) node;
-
- // If we have a vcall (a method with no arguments and no
- // receiver that could have been a local variable) then we
- // will transform it into a local variable write.
- if (pm_call_node_variable_call_p(cast)) {
- pm_location_t *message_loc = &cast->message_loc;
- pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
-
- pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end);
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
-
- pm_node_destroy(parser, (pm_node_t *) cast);
- return result;
- }
-
- // If there is no call operator and the message is "[]" then
- // this is an aref expression, and we can transform it into
- // an aset expression.
- if (pm_call_node_index_p(cast)) {
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- return (pm_node_t *) pm_index_and_write_node_create(parser, cast, &token, value);
- }
-
- // If this node cannot be writable, then we have an error.
- if (pm_call_node_writable_p(cast)) {
- parse_write_name(parser, &cast->name);
- } else {
- pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED);
- }
-
- parse_call_operator_write(parser, cast, &token);
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- return (pm_node_t *) pm_call_and_write_node_create(parser, cast, &token, value);
- }
- case PM_MULTI_WRITE_NODE: {
- parser_lex(parser);
- pm_parser_err_token(parser, &token, PM_ERR_AMPAMPEQ_MULTI_ASSIGN);
- return node;
- }
- default:
- parser_lex(parser);
-
- // In this case we have an &&= sign, but we don't know what it's for.
- // We need to treat it as an error. For now, we'll mark it as an error
- // and just skip right past it.
- pm_parser_err_token(parser, &token, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
- return node;
- }
- }
- case PM_TOKEN_PIPE_PIPE_EQUAL: {
- switch (PM_NODE_TYPE(node)) {
- case PM_BACK_REFERENCE_READ_NODE:
- case PM_NUMBERED_REFERENCE_READ_NODE:
- pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_READONLY);
- /* fallthrough */
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- pm_node_t *result = (pm_node_t *) pm_global_variable_or_write_node_create(parser, node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CLASS_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- pm_node_t *result = (pm_node_t *) pm_class_variable_or_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CONSTANT_PATH_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- return (pm_node_t *) pm_constant_path_or_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
- }
- case PM_CONSTANT_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- pm_node_t *result = (pm_node_t *) pm_constant_or_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_INSTANCE_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- pm_node_t *result = (pm_node_t *) pm_instance_variable_or_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_LOCAL_VARIABLE_READ_NODE: {
- pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CALL_NODE: {
- parser_lex(parser);
- pm_call_node_t *cast = (pm_call_node_t *) node;
-
- // If we have a vcall (a method with no arguments and no
- // receiver that could have been a local variable) then we
- // will transform it into a local variable write.
- if (pm_call_node_variable_call_p(cast)) {
- pm_location_t *message_loc = &cast->message_loc;
- pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
-
- pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end);
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
-
- pm_node_destroy(parser, (pm_node_t *) cast);
- return result;
- }
-
- // If there is no call operator and the message is "[]" then
- // this is an aref expression, and we can transform it into
- // an aset expression.
- if (pm_call_node_index_p(cast)) {
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- return (pm_node_t *) pm_index_or_write_node_create(parser, cast, &token, value);
- }
-
- // If this node cannot be writable, then we have an error.
- if (pm_call_node_writable_p(cast)) {
- parse_write_name(parser, &cast->name);
- } else {
- pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED);
- }
-
- parse_call_operator_write(parser, cast, &token);
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- return (pm_node_t *) pm_call_or_write_node_create(parser, cast, &token, value);
- }
- case PM_MULTI_WRITE_NODE: {
- parser_lex(parser);
- pm_parser_err_token(parser, &token, PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN);
- return node;
- }
- default:
- parser_lex(parser);
-
- // In this case we have an ||= sign, but we don't know what it's for.
- // We need to treat it as an error. For now, we'll mark it as an error
- // and just skip right past it.
- pm_parser_err_token(parser, &token, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
- return node;
- }
- }
- case PM_TOKEN_AMPERSAND_EQUAL:
- case PM_TOKEN_CARET_EQUAL:
- case PM_TOKEN_GREATER_GREATER_EQUAL:
- case PM_TOKEN_LESS_LESS_EQUAL:
- case PM_TOKEN_MINUS_EQUAL:
- case PM_TOKEN_PERCENT_EQUAL:
- case PM_TOKEN_PIPE_EQUAL:
- case PM_TOKEN_PLUS_EQUAL:
- case PM_TOKEN_SLASH_EQUAL:
- case PM_TOKEN_STAR_EQUAL:
- case PM_TOKEN_STAR_STAR_EQUAL: {
- switch (PM_NODE_TYPE(node)) {
- case PM_BACK_REFERENCE_READ_NODE:
- case PM_NUMBERED_REFERENCE_READ_NODE:
- pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_READONLY);
- /* fallthrough */
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- pm_node_t *result = (pm_node_t *) pm_global_variable_operator_write_node_create(parser, node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CLASS_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- pm_node_t *result = (pm_node_t *) pm_class_variable_operator_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CONSTANT_PATH_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_constant_path_operator_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
- }
- case PM_CONSTANT_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- pm_node_t *result = (pm_node_t *) pm_constant_operator_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_INSTANCE_VARIABLE_READ_NODE: {
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- pm_node_t *result = (pm_node_t *) pm_instance_variable_operator_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_LOCAL_VARIABLE_READ_NODE: {
- pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
- parser_lex(parser);
-
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth);
-
- pm_node_destroy(parser, node);
- return result;
- }
- case PM_CALL_NODE: {
- parser_lex(parser);
- pm_call_node_t *cast = (pm_call_node_t *) node;
-
- // If we have a vcall (a method with no arguments and no
- // receiver that could have been a local variable) then we
- // will transform it into a local variable write.
- if (pm_call_node_variable_call_p(cast)) {
- pm_location_t *message_loc = &cast->message_loc;
- pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
-
- pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end);
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
-
- pm_node_destroy(parser, (pm_node_t *) cast);
- return result;
- }
-
- // If there is no call operator and the message is "[]" then
- // this is an aref expression, and we can transform it into
- // an aset expression.
- if (pm_call_node_index_p(cast)) {
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_index_operator_write_node_create(parser, cast, &token, value);
- }
-
- // If this node cannot be writable, then we have an error.
- if (pm_call_node_writable_p(cast)) {
- parse_write_name(parser, &cast->name);
- } else {
- pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED);
- }
-
- parse_call_operator_write(parser, cast, &token);
- pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_call_operator_write_node_create(parser, cast, &token, value);
- }
- case PM_MULTI_WRITE_NODE: {
- parser_lex(parser);
- pm_parser_err_token(parser, &token, PM_ERR_OPERATOR_MULTI_ASSIGN);
- return node;
- }
- default:
- parser_lex(parser);
-
- // In this case we have an operator but we don't know what it's for.
- // We need to treat it as an error. For now, we'll mark it as an error
- // and just skip right past it.
- pm_parser_err_previous(parser, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return node;
- }
- }
- case PM_TOKEN_AMPERSAND_AMPERSAND:
- case PM_TOKEN_KEYWORD_AND: {
- parser_lex(parser);
-
- pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_and_node_create(parser, node, &token, right);
- }
- case PM_TOKEN_KEYWORD_OR:
- case PM_TOKEN_PIPE_PIPE: {
- parser_lex(parser);
-
- pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_or_node_create(parser, node, &token, right);
- }
- case PM_TOKEN_EQUAL_TILDE: {
- // Note that we _must_ parse the value before adding the local
- // variables in order to properly mirror the behavior of Ruby. For
- // example,
- //
- // /(?<foo>bar)/ =~ foo
- //
- // In this case, `foo` should be a method call and not a local yet.
- parser_lex(parser);
- pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
-
- // By default, we're going to create a call node and then return it.
- pm_call_node_t *call = pm_call_node_binary_create(parser, node, &token, argument);
- pm_node_t *result = (pm_node_t *) call;
-
- // If the receiver of this =~ is a regular expression node, then we
- // need to introduce local variables for it based on its named
- // capture groups.
- if (PM_NODE_TYPE_P(node, PM_INTERPOLATED_REGULAR_EXPRESSION_NODE)) {
- // It's possible to have an interpolated regular expression node
- // that only contains strings. This is because it can be split
- // up by a heredoc. In this case we need to concat the unescaped
- // strings together and then parse them as a regular expression.
- pm_node_list_t *parts = &((pm_interpolated_regular_expression_node_t *) node)->parts;
-
- bool interpolated = false;
- size_t total_length = 0;
-
- for (size_t index = 0; index < parts->size; index++) {
- pm_node_t *part = parts->nodes[index];
-
- if (PM_NODE_TYPE_P(part, PM_STRING_NODE)) {
- total_length += pm_string_length(&((pm_string_node_t *) part)->unescaped);
- } else {
- interpolated = true;
- break;
- }
- }
-
- if (!interpolated && total_length > 0) {
- void *memory = malloc(total_length);
- if (!memory) abort();
-
- uint8_t *cursor = memory;
- for (size_t index = 0; index < parts->size; index++) {
- pm_string_t *unescaped = &((pm_string_node_t *) parts->nodes[index])->unescaped;
- size_t length = pm_string_length(unescaped);
-
- memcpy(cursor, pm_string_source(unescaped), length);
- cursor += length;
- }
-
- pm_string_t owned;
- pm_string_owned_init(&owned, (uint8_t *) memory, total_length);
-
- result = parse_regular_expression_named_captures(parser, &owned, call);
- pm_string_free(&owned);
- }
- } else if (PM_NODE_TYPE_P(node, PM_REGULAR_EXPRESSION_NODE)) {
- // If we have a regular expression node, then we can just parse
- // the named captures directly off the unescaped string.
- const pm_string_t *content = &((pm_regular_expression_node_t *) node)->unescaped;
- result = parse_regular_expression_named_captures(parser, content, call);
- }
-
- return result;
- }
- case PM_TOKEN_UAMPERSAND:
- case PM_TOKEN_USTAR:
- case PM_TOKEN_USTAR_STAR:
- // The only times this will occur are when we are in an error state,
- // but we'll put them in here so that errors can propagate.
- case PM_TOKEN_BANG_EQUAL:
- case PM_TOKEN_BANG_TILDE:
- case PM_TOKEN_EQUAL_EQUAL:
- case PM_TOKEN_EQUAL_EQUAL_EQUAL:
- case PM_TOKEN_LESS_EQUAL_GREATER:
- case PM_TOKEN_GREATER:
- case PM_TOKEN_GREATER_EQUAL:
- case PM_TOKEN_LESS:
- case PM_TOKEN_LESS_EQUAL:
- case PM_TOKEN_CARET:
- case PM_TOKEN_PIPE:
- case PM_TOKEN_AMPERSAND:
- case PM_TOKEN_GREATER_GREATER:
- case PM_TOKEN_LESS_LESS:
- case PM_TOKEN_MINUS:
- case PM_TOKEN_PLUS:
- case PM_TOKEN_PERCENT:
- case PM_TOKEN_SLASH:
- case PM_TOKEN_STAR:
- case PM_TOKEN_STAR_STAR: {
- parser_lex(parser);
-
- pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument);
- }
- case PM_TOKEN_AMPERSAND_DOT:
- case PM_TOKEN_DOT: {
- parser_lex(parser);
- pm_token_t operator = parser->previous;
- pm_arguments_t arguments = { 0 };
-
- // This if statement handles the foo.() syntax.
- if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
- parse_arguments_list(parser, &arguments, true, false);
- return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &operator, &arguments);
- }
-
- pm_token_t message;
-
- switch (parser->current.type) {
- case PM_CASE_OPERATOR:
- case PM_CASE_KEYWORD:
- case PM_TOKEN_CONSTANT:
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_METHOD_NAME: {
- parser_lex(parser);
- message = parser->previous;
- break;
- }
- default: {
- pm_parser_err_current(parser, PM_ERR_DEF_NAME);
- message = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- }
- }
-
- parse_arguments_list(parser, &arguments, true, accepts_command_call);
- pm_call_node_t *call = pm_call_node_call_create(parser, node, &operator, &message, &arguments);
-
- if (
- (previous_binding_power == PM_BINDING_POWER_STATEMENT) &&
- arguments.arguments == NULL &&
- arguments.opening_loc.start == NULL &&
- match1(parser, PM_TOKEN_COMMA)
- ) {
- return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX);
- } else {
- return (pm_node_t *) call;
- }
- }
- case PM_TOKEN_DOT_DOT:
- case PM_TOKEN_DOT_DOT_DOT: {
- parser_lex(parser);
-
- pm_node_t *right = NULL;
- if (token_begins_expression_p(parser->current.type)) {
- right = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
- }
-
- return (pm_node_t *) pm_range_node_create(parser, node, &token, right);
- }
- case PM_TOKEN_KEYWORD_IF_MODIFIER: {
- pm_token_t keyword = parser->current;
- parser_lex(parser);
-
- pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_IF_PREDICATE);
- return (pm_node_t *) pm_if_node_modifier_create(parser, node, &keyword, predicate);
- }
- case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: {
- pm_token_t keyword = parser->current;
- parser_lex(parser);
-
- pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
- return (pm_node_t *) pm_unless_node_modifier_create(parser, node, &keyword, predicate);
- }
- case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: {
- parser_lex(parser);
- pm_statements_node_t *statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(statements, node);
-
- pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
- return (pm_node_t *) pm_until_node_modifier_create(parser, &token, predicate, statements, PM_NODE_TYPE_P(node, PM_BEGIN_NODE) ? PM_LOOP_FLAGS_BEGIN_MODIFIER : 0);
- }
- case PM_TOKEN_KEYWORD_WHILE_MODIFIER: {
- parser_lex(parser);
- pm_statements_node_t *statements = pm_statements_node_create(parser);
- pm_statements_node_body_append(statements, node);
-
- pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
- return (pm_node_t *) pm_while_node_modifier_create(parser, &token, predicate, statements, PM_NODE_TYPE_P(node, PM_BEGIN_NODE) ? PM_LOOP_FLAGS_BEGIN_MODIFIER : 0);
- }
- case PM_TOKEN_QUESTION_MARK: {
- pm_token_t qmark = parser->current;
- parser_lex(parser);
- pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_TERNARY_EXPRESSION_TRUE);
-
- if (parser->recovering) {
- // If parsing the true expression of this ternary resulted in a syntax
- // error that we can recover from, then we're going to put missing nodes
- // and tokens into the remaining places. We want to be sure to do this
- // before the `expect` function call to make sure it doesn't
- // accidentally move past a ':' token that occurs after the syntax
- // error.
- pm_token_t colon = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
- pm_node_t *false_expression = (pm_node_t *) pm_missing_node_create(parser, colon.start, colon.end);
-
- return (pm_node_t *) pm_if_node_ternary_create(parser, node, &qmark, true_expression, &colon, false_expression);
- }
-
- accept1(parser, PM_TOKEN_NEWLINE);
- expect1(parser, PM_TOKEN_COLON, PM_ERR_TERNARY_COLON);
-
- pm_token_t colon = parser->previous;
- pm_node_t *false_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_TERNARY_EXPRESSION_FALSE);
-
- return (pm_node_t *) pm_if_node_ternary_create(parser, node, &qmark, true_expression, &colon, false_expression);
- }
- case PM_TOKEN_COLON_COLON: {
- parser_lex(parser);
- pm_token_t delimiter = parser->previous;
-
- switch (parser->current.type) {
- case PM_TOKEN_CONSTANT: {
- parser_lex(parser);
- pm_node_t *path;
-
- if (
- (parser->current.type == PM_TOKEN_PARENTHESIS_LEFT) ||
- (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))
- ) {
- // If we have a constant immediately following a '::' operator, then
- // this can either be a constant path or a method call, depending on
- // what follows the constant.
- //
- // If we have parentheses, then this is a method call. That would
- // look like Foo::Bar().
- pm_token_t message = parser->previous;
- pm_arguments_t arguments = { 0 };
-
- parse_arguments_list(parser, &arguments, true, accepts_command_call);
- path = (pm_node_t *) pm_call_node_call_create(parser, node, &delimiter, &message, &arguments);
- } else {
- // Otherwise, this is a constant path. That would look like Foo::Bar.
- pm_node_t *child = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous);
- path = (pm_node_t *)pm_constant_path_node_create(parser, node, &delimiter, child);
- }
-
- // If this is followed by a comma then it is a multiple assignment.
- if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- return parse_targets_validate(parser, path, PM_BINDING_POWER_INDEX);
- }
-
- return path;
- }
- case PM_CASE_OPERATOR:
- case PM_CASE_KEYWORD:
- case PM_TOKEN_IDENTIFIER:
- case PM_TOKEN_METHOD_NAME: {
- parser_lex(parser);
- pm_token_t message = parser->previous;
-
- // If we have an identifier following a '::' operator, then it is for
- // sure a method call.
- pm_arguments_t arguments = { 0 };
- parse_arguments_list(parser, &arguments, true, accepts_command_call);
- pm_call_node_t *call = pm_call_node_call_create(parser, node, &delimiter, &message, &arguments);
-
- // If this is followed by a comma then it is a multiple assignment.
- if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX);
- }
-
- return (pm_node_t *) call;
- }
- case PM_TOKEN_PARENTHESIS_LEFT: {
- // If we have a parenthesis following a '::' operator, then it is the
- // method call shorthand. That would look like Foo::(bar).
- pm_arguments_t arguments = { 0 };
- parse_arguments_list(parser, &arguments, true, false);
-
- return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &delimiter, &arguments);
- }
- default: {
- pm_parser_err_token(parser, &delimiter, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
- pm_node_t *child = (pm_node_t *) pm_missing_node_create(parser, delimiter.start, delimiter.end);
- return (pm_node_t *)pm_constant_path_node_create(parser, node, &delimiter, child);
- }
- }
- }
- case PM_TOKEN_KEYWORD_RESCUE_MODIFIER: {
- parser_lex(parser);
- accept1(parser, PM_TOKEN_NEWLINE);
- pm_node_t *value = parse_expression(parser, binding_power, true, PM_ERR_RESCUE_MODIFIER_VALUE);
-
- return (pm_node_t *) pm_rescue_modifier_node_create(parser, node, &token, value);
- }
- case PM_TOKEN_BRACKET_LEFT: {
- parser_lex(parser);
-
- pm_arguments_t arguments = { 0 };
- arguments.opening_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
-
- if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
- pm_accepts_block_stack_push(parser, true);
- parse_arguments(parser, &arguments, false, PM_TOKEN_BRACKET_RIGHT);
- pm_accepts_block_stack_pop(parser);
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_EXPECT_RBRACKET);
- }
-
- arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
-
- // If we have a comma after the closing bracket then this is a multiple
- // assignment and we should parse the targets.
- if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
- pm_call_node_t *aref = pm_call_node_aref_create(parser, node, &arguments);
- return parse_targets_validate(parser, (pm_node_t *) aref, PM_BINDING_POWER_INDEX);
- }
-
- // If we're at the end of the arguments, we can now check if there is a
- // block node that starts with a {. If there is, then we can parse it and
- // add it to the arguments.
- pm_block_node_t *block = NULL;
- if (accept1(parser, PM_TOKEN_BRACE_LEFT)) {
- block = parse_block(parser);
- pm_arguments_validate_block(parser, &arguments, block);
- } else if (pm_accepts_block_stack_p(parser) && accept1(parser, PM_TOKEN_KEYWORD_DO)) {
- block = parse_block(parser);
- }
-
- if (block != NULL) {
- if (arguments.block != NULL) {
- pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_AFTER_BLOCK);
- if (arguments.arguments == NULL) {
- arguments.arguments = pm_arguments_node_create(parser);
- }
- pm_arguments_node_arguments_append(arguments.arguments, arguments.block);
- }
-
- arguments.block = (pm_node_t *) block;
- }
-
- return (pm_node_t *) pm_call_node_aref_create(parser, node, &arguments);
- }
- case PM_TOKEN_KEYWORD_IN: {
- bool previous_pattern_matching_newlines = parser->pattern_matching_newlines;
- parser->pattern_matching_newlines = true;
-
- pm_token_t operator = parser->current;
- parser->command_start = false;
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
-
- parser_lex(parser);
-
- pm_node_t *pattern = parse_pattern(parser, true, PM_ERR_PATTERN_EXPRESSION_AFTER_IN);
- parser->pattern_matching_newlines = previous_pattern_matching_newlines;
-
- return (pm_node_t *) pm_match_predicate_node_create(parser, node, pattern, &operator);
- }
- case PM_TOKEN_EQUAL_GREATER: {
- bool previous_pattern_matching_newlines = parser->pattern_matching_newlines;
- parser->pattern_matching_newlines = true;
-
- pm_token_t operator = parser->current;
- parser->command_start = false;
- lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL);
-
- parser_lex(parser);
-
- pm_node_t *pattern = parse_pattern(parser, true, PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET);
- parser->pattern_matching_newlines = previous_pattern_matching_newlines;
-
- return (pm_node_t *) pm_match_required_node_create(parser, node, pattern, &operator);
- }
- default:
- assert(false && "unreachable");
- return NULL;
- }
-}
-
-/**
- * Parse an expression at the given point of the parser using the given binding
- * power to parse subsequent chains. If this function finds a syntax error, it
- * will append the error message to the parser's error list.
- *
- * Consumers of this function should always check parser->recovering to
- * determine if they need to perform additional cleanup.
- */
-static pm_node_t *
-parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
- pm_token_t recovery = parser->previous;
- pm_node_t *node = parse_expression_prefix(parser, binding_power, accepts_command_call);
-
- switch (PM_NODE_TYPE(node)) {
- case PM_MISSING_NODE:
- // If we found a syntax error, then the type of node returned by
- // parse_expression_prefix is going to be a missing node. In that
- // case we need to add the error message to the parser's error list.
- pm_parser_err(parser, recovery.end, recovery.end, diag_id);
- return node;
- case PM_PRE_EXECUTION_NODE:
- case PM_POST_EXECUTION_NODE:
- case PM_ALIAS_GLOBAL_VARIABLE_NODE:
- case PM_ALIAS_METHOD_NODE:
- case PM_UNDEF_NODE:
- // These expressions are statements, and cannot be followed by
- // operators (except modifiers).
- if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER_RESCUE) {
- return node;
- }
- break;
- case PM_RANGE_NODE:
- // Range operators are non-associative, so that it does not
- // associate with other range operators (i.e. `..1..` should be
- // rejected.) For this reason, we check such a case for unary ranges
- // here, and if so, it returns the node immediately,
- if ((((pm_range_node_t *) node)->left == NULL) && pm_binding_powers[parser->current.type].left >= PM_BINDING_POWER_RANGE) {
- return node;
- }
- break;
- default:
- break;
- }
-
- // Otherwise we'll look and see if the next token can be parsed as an infix
- // operator. If it can, then we'll parse it using parse_expression_infix.
- pm_binding_powers_t current_binding_powers;
- while (
- current_binding_powers = pm_binding_powers[parser->current.type],
- binding_power <= current_binding_powers.left &&
- current_binding_powers.binary
- ) {
- node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call);
- if (current_binding_powers.nonassoc) {
- bool endless_range_p = PM_NODE_TYPE_P(node, PM_RANGE_NODE) && ((pm_range_node_t *) node)->right == NULL;
- pm_binding_power_t left = endless_range_p ? PM_BINDING_POWER_TERM : current_binding_powers.left;
- if (
- left <= pm_binding_powers[parser->current.type].left ||
- // Exceptionally to operator precedences, '1.. & 2' is rejected.
- // '1.. || 2' is also an exception, but it is handled by the lexer.
- // (Here, parser->current is PM_TOKEN_PIPE, not PM_TOKEN_PIPE_PIPE).
- (endless_range_p && match1(parser, PM_TOKEN_AMPERSAND))
- ) {
- break;
- }
- }
- if (accepts_command_call) {
- // A command-style method call is only accepted on method chains.
- // Thus, we check whether the parsed node can continue method chains.
- // The method chain can continue if the parsed node is one of the following five kinds:
- // (1) index access: foo[1]
- // (2) attribute access: foo.bar
- // (3) method call with parenthesis: foo.bar(1)
- // (4) method call with a block: foo.bar do end
- // (5) constant path: foo::Bar
- switch (node->type) {
- case PM_CALL_NODE: {
- pm_call_node_t *cast = (pm_call_node_t *)node;
- if (
- // (1) foo[1]
- !(
- cast->call_operator_loc.start == NULL &&
- cast->message_loc.start != NULL &&
- cast->message_loc.start[0] == '[' &&
- cast->message_loc.end[-1] == ']'
- ) &&
- // (2) foo.bar
- !(
- cast->call_operator_loc.start != NULL &&
- cast->arguments == NULL &&
- cast->block == NULL &&
- cast->opening_loc.start == NULL
- ) &&
- // (3) foo.bar(1)
- !(
- cast->call_operator_loc.start != NULL &&
- cast->opening_loc.start != NULL
- ) &&
- // (4) foo.bar do end
- !(
- cast->block != NULL && PM_NODE_TYPE_P(cast->block, PM_BLOCK_NODE)
- )
- ) {
- accepts_command_call = false;
- }
- break;
- }
- // (5) foo::Bar
- case PM_CONSTANT_PATH_NODE:
- break;
- default:
- accepts_command_call = false;
- break;
- }
- }
- }
-
- return node;
-}
-
-static pm_node_t *
-parse_program(pm_parser_t *parser) {
- pm_parser_scope_push(parser, !parser->current_scope);
- parser_lex(parser);
-
- pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_MAIN);
- if (!statements) {
- statements = pm_statements_node_create(parser);
- }
- pm_constant_id_list_t locals = parser->current_scope->locals;
- pm_parser_scope_pop(parser);
-
- // If this is an empty file, then we're still going to parse all of the
- // statements in order to gather up all of the comments and such. Here we'll
- // correct the location information.
- if (pm_statements_node_body_length(statements) == 0) {
- pm_statements_node_location_set(statements, parser->start, parser->start);
- }
-
- return (pm_node_t *) pm_program_node_create(parser, &locals, statements);
-}
-
-/******************************************************************************/
-/* External functions */
-/******************************************************************************/
-
-/**
- * Initialize a parser with the given start and end pointers.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm_options_t *options) {
- assert(source != NULL);
-
- *parser = (pm_parser_t) {
- .lex_state = PM_LEX_STATE_BEG,
- .enclosure_nesting = 0,
- .lambda_enclosure_nesting = -1,
- .brace_nesting = 0,
- .do_loop_stack = 0,
- .accepts_block_stack = 0,
- .lex_modes = {
- .index = 0,
- .stack = {{ .mode = PM_LEX_DEFAULT }},
- .current = &parser->lex_modes.stack[0],
- },
- .start = source,
- .end = source + size,
- .previous = { .type = PM_TOKEN_EOF, .start = source, .end = source },
- .current = { .type = PM_TOKEN_EOF, .start = source, .end = source },
- .next_start = NULL,
- .heredoc_end = NULL,
- .comment_list = { 0 },
- .magic_comment_list = { 0 },
- .warning_list = { 0 },
- .error_list = { 0 },
- .current_scope = NULL,
- .current_context = NULL,
- .encoding = PM_ENCODING_UTF_8_ENTRY,
- .encoding_changed_callback = NULL,
- .encoding_comment_start = source,
- .lex_callback = NULL,
- .filepath_string = { 0 },
- .constant_pool = { 0 },
- .newline_list = { 0 },
- .integer_base = 0,
- .current_string = PM_STRING_EMPTY,
- .start_line = 1,
- .explicit_encoding = NULL,
- .command_start = true,
- .recovering = false,
- .encoding_changed = false,
- .pattern_matching_newlines = false,
- .in_keyword_arg = false,
- .current_param_name = 0,
- .semantic_token_seen = false,
- .frozen_string_literal = false,
- .suppress_warnings = false
- };
-
- // Initialize the constant pool. We're going to completely guess as to the
- // number of constants that we'll need based on the size of the input. The
- // ratio we chose here is actually less arbitrary than you might think.
- //
- // We took ~50K Ruby files and measured the size of the file versus the
- // number of constants that were found in those files. Then we found the
- // average and standard deviation of the ratios of constants/bytesize. Then
- // we added 1.34 standard deviations to the average to get a ratio that
- // would fit 75% of the files (for a two-tailed distribution). This works
- // because there was about a 0.77 correlation and the distribution was
- // roughly normal.
- //
- // This ratio will need to change if we add more constants to the constant
- // pool for another node type.
- uint32_t constant_size = ((uint32_t) size) / 95;
- pm_constant_pool_init(&parser->constant_pool, constant_size < 4 ? 4 : constant_size);
-
- // Initialize the newline list. Similar to the constant pool, we're going to
- // guess at the number of newlines that we'll need based on the size of the
- // input.
- size_t newline_size = size / 22;
- pm_newline_list_init(&parser->newline_list, source, newline_size < 4 ? 4 : newline_size);
-
- // If options were provided to this parse, establish them here.
- if (options != NULL) {
- // filepath option
- parser->filepath_string = options->filepath;
-
- // line option
- parser->start_line = options->line;
-
- // encoding option
- size_t encoding_length = pm_string_length(&options->encoding);
- if (encoding_length > 0) {
- const uint8_t *encoding_source = pm_string_source(&options->encoding);
- parser_lex_magic_comment_encoding_value(parser, encoding_source, encoding_source + encoding_length);
- }
-
- // frozen_string_literal option
- if (options->frozen_string_literal) {
- parser->frozen_string_literal = true;
- }
-
- // suppress_warnings option
- if (options->suppress_warnings) {
- parser->suppress_warnings = true;
- }
-
- // scopes option
- for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
- const pm_options_scope_t *scope = pm_options_scope_get(options, scope_index);
- pm_parser_scope_push(parser, scope_index == 0);
-
- for (size_t local_index = 0; local_index < scope->locals_count; local_index++) {
- const pm_string_t *local = pm_options_scope_local_get(scope, local_index);
-
- const uint8_t *source = pm_string_source(local);
- size_t length = pm_string_length(local);
-
- uint8_t *allocated = malloc(length);
- if (allocated == NULL) continue;
-
- memcpy((void *) allocated, source, length);
- pm_parser_local_add_owned(parser, allocated, length);
- }
- }
- }
-
- pm_accepts_block_stack_push(parser, true);
-
- // Skip past the UTF-8 BOM if it exists.
- if (size >= 3 && source[0] == 0xef && source[1] == 0xbb && source[2] == 0xbf) {
- parser->current.end += 3;
- parser->encoding_comment_start += 3;
- }
-
- // If the first two bytes of the source are a shebang, then we'll indicate
- // that the encoding comment is at the end of the shebang.
- if (peek(parser) == '#' && peek_offset(parser, 1) == '!') {
- const uint8_t *encoding_comment_start = next_newline(source, (ptrdiff_t) size);
- if (encoding_comment_start) {
- parser->encoding_comment_start = encoding_comment_start + 1;
- }
- }
-}
-
-/**
- * Register a callback that will be called whenever prism changes the encoding
- * it is using to parse based on the magic comment.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback) {
- parser->encoding_changed_callback = callback;
-}
-
-/**
- * Free all of the memory associated with the comment list.
- */
-static inline void
-pm_comment_list_free(pm_list_t *list) {
- pm_list_node_t *node, *next;
-
- for (node = list->head; node != NULL; node = next) {
- next = node->next;
-
- pm_comment_t *comment = (pm_comment_t *) node;
- free(comment);
- }
-}
-
-/**
- * Free all of the memory associated with the magic comment list.
- */
-static inline void
-pm_magic_comment_list_free(pm_list_t *list) {
- pm_list_node_t *node, *next;
-
- for (node = list->head; node != NULL; node = next) {
- next = node->next;
-
- pm_magic_comment_t *magic_comment = (pm_magic_comment_t *) node;
- free(magic_comment);
- }
-}
-
-/**
- * Free any memory associated with the given parser.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_parser_free(pm_parser_t *parser) {
- pm_string_free(&parser->filepath_string);
- pm_diagnostic_list_free(&parser->error_list);
- pm_diagnostic_list_free(&parser->warning_list);
- pm_comment_list_free(&parser->comment_list);
- pm_magic_comment_list_free(&parser->magic_comment_list);
- pm_constant_pool_free(&parser->constant_pool);
- pm_newline_list_free(&parser->newline_list);
-
- while (parser->current_scope != NULL) {
- // Normally, popping the scope doesn't free the locals since it is
- // assumed that ownership has transferred to the AST. However if we have
- // scopes while we're freeing the parser, it's likely they came from
- // eval scopes and we need to free them explicitly here.
- pm_constant_id_list_free(&parser->current_scope->locals);
- pm_parser_scope_pop(parser);
- }
-
- while (parser->lex_modes.index >= PM_LEX_STACK_SIZE) {
- lex_mode_pop(parser);
- }
-}
-
-/**
- * Parse the Ruby source associated with the given parser and return the tree.
- */
-PRISM_EXPORTED_FUNCTION pm_node_t *
-pm_parse(pm_parser_t *parser) {
- return parse_program(parser);
-}
-
-static inline void
-pm_serialize_header(pm_buffer_t *buffer) {
- pm_buffer_append_string(buffer, "PRISM", 5);
- pm_buffer_append_byte(buffer, PRISM_VERSION_MAJOR);
- pm_buffer_append_byte(buffer, PRISM_VERSION_MINOR);
- pm_buffer_append_byte(buffer, PRISM_VERSION_PATCH);
- pm_buffer_append_byte(buffer, PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS ? 1 : 0);
-}
-
-/**
- * Serialize the AST represented by the given node to the given buffer.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
- pm_serialize_header(buffer);
- pm_serialize_content(parser, node, buffer);
- pm_buffer_append_byte(buffer, '\0');
-}
-
-/**
- * Parse and serialize the AST represented by the given source to the given
- * buffer.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
- pm_options_t options = { 0 };
- pm_options_read(&options, data);
-
- pm_parser_t parser;
- pm_parser_init(&parser, source, size, &options);
-
- pm_node_t *node = pm_parse(&parser);
-
- pm_serialize_header(buffer);
- pm_serialize_content(&parser, node, buffer);
- pm_buffer_append_byte(buffer, '\0');
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
- pm_options_free(&options);
-}
-
-/**
- * Parse and serialize the comments in the given source to the given buffer.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
- pm_options_t options = { 0 };
- pm_options_read(&options, data);
-
- pm_parser_t parser;
- pm_parser_init(&parser, source, size, &options);
-
- pm_node_t *node = pm_parse(&parser);
- pm_serialize_header(buffer);
- pm_serialize_encoding(parser.encoding, buffer);
- pm_buffer_append_varsint(buffer, parser.start_line);
- pm_serialize_comment_list(&parser, &parser.comment_list, buffer);
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
- pm_options_free(&options);
-}
-
-#undef PM_CASE_KEYWORD
-#undef PM_CASE_OPERATOR
-#undef PM_CASE_WRITABLE
-#undef PM_STRING_EMPTY
-#undef PM_LOCATION_NODE_BASE_VALUE
-#undef PM_LOCATION_NODE_VALUE
-#undef PM_LOCATION_NULL_VALUE
-#undef PM_LOCATION_TOKEN_VALUE
diff --git a/prism/prism.h b/prism/prism.h
deleted file mode 100644
index 869d608c9a..0000000000
--- a/prism/prism.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/**
- * @file prism.h
- *
- * The main header file for the prism parser.
- */
-#ifndef PRISM_H
-#define PRISM_H
-
-#include "prism/defines.h"
-#include "prism/util/pm_buffer.h"
-#include "prism/util/pm_char.h"
-#include "prism/util/pm_memchr.h"
-#include "prism/util/pm_strncasecmp.h"
-#include "prism/util/pm_strpbrk.h"
-#include "prism/ast.h"
-#include "prism/diagnostic.h"
-#include "prism/node.h"
-#include "prism/options.h"
-#include "prism/pack.h"
-#include "prism/parser.h"
-#include "prism/prettyprint.h"
-#include "prism/regexp.h"
-#include "prism/version.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef _WIN32
-#include <strings.h>
-#endif
-
-/**
- * The prism version and the serialization format.
- *
- * @returns The prism version as a constant string.
- */
-PRISM_EXPORTED_FUNCTION const char * pm_version(void);
-
-/**
- * Initialize a parser with the given start and end pointers.
- *
- * @param parser The parser to initialize.
- * @param source The source to parse.
- * @param size The size of the source.
- * @param options The optional options to use when parsing.
- */
-PRISM_EXPORTED_FUNCTION void pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm_options_t *options);
-
-/**
- * Register a callback that will be called whenever prism changes the encoding
- * it is using to parse based on the magic comment.
- *
- * @param parser The parser to register the callback with.
- * @param callback The callback to register.
- */
-PRISM_EXPORTED_FUNCTION void pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback);
-
-/**
- * Free any memory associated with the given parser.
- *
- * @param parser The parser to free.
- */
-PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *parser);
-
-/**
- * Initiate the parser with the given parser.
- *
- * @param parser The parser to use.
- * @return The AST representing the source.
- */
-PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser);
-
-/**
- * Serialize the given list of comments to the given buffer.
- *
- * @param parser The parser to serialize.
- * @param list The list of comments to serialize.
- * @param buffer The buffer to serialize to.
- */
-void pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer);
-
-/**
- * Serialize the name of the encoding to the buffer.
- *
- * @param encoding The encoding to serialize.
- * @param buffer The buffer to serialize to.
- */
-void pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer);
-
-/**
- * Serialize the encoding, metadata, nodes, and constant pool.
- *
- * @param parser The parser to serialize.
- * @param node The node to serialize.
- * @param buffer The buffer to serialize to.
- */
-void pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
-
-/**
- * Serialize the AST represented by the given node to the given buffer.
- *
- * @param parser The parser to serialize.
- * @param node The node to serialize.
- * @param buffer The buffer to serialize to.
- */
-PRISM_EXPORTED_FUNCTION void pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
-
-/**
- * Parse the given source to the AST and dump the AST to the given buffer.
- *
- * @param buffer The buffer to serialize to.
- * @param source The source to parse.
- * @param size The size of the source.
- * @param data The optional data to pass to the parser.
- */
-PRISM_EXPORTED_FUNCTION void pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
-
-/**
- * Parse and serialize the comments in the given source to the given buffer.
- *
- * @param buffer The buffer to serialize to.
- * @param source The source to parse.
- * @param size The size of the source.
- * @param data The optional data to pass to the parser.
- */
-PRISM_EXPORTED_FUNCTION void pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
-
-/**
- * Lex the given source and serialize to the given buffer.
- *
- * @param source The source to lex.
- * @param size The size of the source.
- * @param buffer The buffer to serialize to.
- * @param data The optional data to pass to the lexer.
- */
-PRISM_EXPORTED_FUNCTION void pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
-
-/**
- * Parse and serialize both the AST and the tokens represented by the given
- * source to the given buffer.
- *
- * @param buffer The buffer to serialize to.
- * @param source The source to parse.
- * @param size The size of the source.
- * @param data The optional data to pass to the parser.
- */
-PRISM_EXPORTED_FUNCTION void pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
-
-/**
- * Parse the source and return true if it parses without errors or warnings.
- *
- * @param source The source to parse.
- * @param size The size of the source.
- * @param data The optional data to pass to the parser.
- * @return True if the source parses without errors or warnings.
- */
-PRISM_EXPORTED_FUNCTION bool pm_parse_success_p(const uint8_t *source, size_t size, const char *data);
-
-/**
- * Returns a string representation of the given token type.
- *
- * @param token_type The token type to convert to a string.
- * @return A string representation of the given token type.
- */
-PRISM_EXPORTED_FUNCTION const char * pm_token_type_to_str(pm_token_type_t token_type);
-
-/**
- * @mainpage
- *
- * Prism is a parser for the Ruby programming language. It is designed to be
- * portable, error tolerant, and maintainable. It is written in C99 and has no
- * dependencies. It is currently being integrated into
- * [CRuby](https://github.com/ruby/ruby),
- * [JRuby](https://github.com/jruby/jruby),
- * [TruffleRuby](https://github.com/oracle/truffleruby),
- * [Sorbet](https://github.com/sorbet/sorbet), and
- * [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree).
- *
- * @section getting-started Getting started
- *
- * If you're vendoring this project and compiling it statically then as long as
- * you have a C99 compiler you will be fine. If you're linking against it as
- * shared library, then you should compile with `-fvisibility=hidden` and
- * `-DPRISM_EXPORT_SYMBOLS` to tell prism to make only its public interface
- * visible.
- *
- * @section parsing Parsing
- *
- * In order to parse Ruby code, the structures and functions that you're going
- * to want to use and be aware of are:
- *
- * * `pm_parser_t` - the main parser structure
- * * `pm_parser_init` - initialize a parser
- * * `pm_parse` - parse and return the root node
- * * `pm_node_destroy` - deallocate the root node returned by `pm_parse`
- * * `pm_parser_free` - free the internal memory of the parser
- *
- * Putting all of this together would look something like:
- *
- * ```c
- * void parse(const uint8_t *source, size_t length) {
- * pm_parser_t parser;
- * pm_parser_init(&parser, source, length, NULL);
- *
- * pm_node_t *root = pm_parse(&parser);
- * printf("PARSED!\n");
- *
- * pm_node_destroy(&parser, root);
- * pm_parser_free(&parser);
- * }
- * ```
- *
- * All of the nodes "inherit" from `pm_node_t` by embedding those structures as
- * their first member. This means you can downcast and upcast any node in the
- * tree to a `pm_node_t`.
- *
- * @section serializing Serializing
- *
- * Prism provides the ability to serialize the AST and its related metadata into
- * a binary format. This format is designed to be portable to different
- * languages and runtimes so that you only need to make one FFI call in order to
- * parse Ruby code. The structures and functions that you're going to want to
- * use and be aware of are:
- *
- * * `pm_buffer_t` - a small buffer object that will hold the serialized AST
- * * `pm_buffer_free` - free the memory associated with the buffer
- * * `pm_serialize` - serialize the AST into a buffer
- * * `pm_serialize_parse` - parse and serialize the AST into a buffer
- *
- * Putting all of this together would look something like:
- *
- * ```c
- * void serialize(const uint8_t *source, size_t length) {
- * pm_buffer_t buffer = { 0 };
- *
- * pm_serialize_parse(&buffer, source, length, NULL);
- * printf("SERIALIZED!\n");
- *
- * pm_buffer_free(&buffer);
- * }
- * ```
- *
- * @section inspecting Inspecting
- *
- * Prism provides the ability to inspect the AST by pretty-printing nodes. You
- * can do this with the `pm_prettyprint` function, which you would use like:
- *
- * ```c
- * void prettyprint(const uint8_t *source, size_t length) {
- * pm_parser_t parser;
- * pm_parser_init(&parser, source, length, NULL);
- *
- * pm_node_t *root = pm_parse(&parser);
- * pm_buffer_t buffer = { 0 };
- *
- * pm_prettyprint(&buffer, &parser, root);
- * printf("*.s%\n", (int) buffer.length, buffer.value);
- *
- * pm_buffer_free(&buffer);
- * pm_node_destroy(&parser, root);
- * pm_parser_free(&parser);
- * }
- * ```
- */
-
-#endif
diff --git a/prism/regexp.c b/prism/regexp.c
deleted file mode 100644
index ba498ecc83..0000000000
--- a/prism/regexp.c
+++ /dev/null
@@ -1,638 +0,0 @@
-#include "prism/regexp.h"
-
-/**
- * This is the parser that is going to handle parsing regular expressions.
- */
-typedef struct {
- /** A pointer to the start of the source that we are parsing. */
- const uint8_t *start;
-
- /** A pointer to the current position in the source. */
- const uint8_t *cursor;
-
- /** A pointer to the end of the source that we are parsing. */
- const uint8_t *end;
-
- /** A list of named captures that we've found. */
- pm_string_list_t *named_captures;
-
- /** Whether the encoding has changed from the default. */
- bool encoding_changed;
-
- /** The encoding of the source. */
- const pm_encoding_t *encoding;
-} pm_regexp_parser_t;
-
-/**
- * This initializes a new parser with the given source.
- */
-static void
-pm_regexp_parser_init(pm_regexp_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_string_list_t *named_captures, bool encoding_changed, const pm_encoding_t *encoding) {
- *parser = (pm_regexp_parser_t) {
- .start = start,
- .cursor = start,
- .end = end,
- .named_captures = named_captures,
- .encoding_changed = encoding_changed,
- .encoding = encoding
- };
-}
-
-/**
- * This appends a new string to the list of named captures.
- */
-static void
-pm_regexp_parser_named_capture(pm_regexp_parser_t *parser, const uint8_t *start, const uint8_t *end) {
- pm_string_t string;
- pm_string_shared_init(&string, start, end);
- pm_string_list_append(parser->named_captures, &string);
- pm_string_free(&string);
-}
-
-/**
- * Returns true if the next character is the end of the source.
- */
-static inline bool
-pm_regexp_char_is_eof(pm_regexp_parser_t *parser) {
- return parser->cursor >= parser->end;
-}
-
-/**
- * Optionally accept a char and consume it if it exists.
- */
-static inline bool
-pm_regexp_char_accept(pm_regexp_parser_t *parser, uint8_t value) {
- if (!pm_regexp_char_is_eof(parser) && *parser->cursor == value) {
- parser->cursor++;
- return true;
- }
- return false;
-}
-
-/**
- * Expect a character to be present and consume it.
- */
-static inline bool
-pm_regexp_char_expect(pm_regexp_parser_t *parser, uint8_t value) {
- if (!pm_regexp_char_is_eof(parser) && *parser->cursor == value) {
- parser->cursor++;
- return true;
- }
- return false;
-}
-
-/**
- * This advances the current token to the next instance of the given character.
- */
-static bool
-pm_regexp_char_find(pm_regexp_parser_t *parser, uint8_t value) {
- if (pm_regexp_char_is_eof(parser)) {
- return false;
- }
-
- const uint8_t *end = (const uint8_t *) pm_memchr(parser->cursor, value, (size_t) (parser->end - parser->cursor), parser->encoding_changed, parser->encoding);
- if (end == NULL) {
- return false;
- }
-
- parser->cursor = end + 1;
- return true;
-}
-
-/**
- * Range quantifiers are a special class of quantifiers that look like
- *
- * * {digit}
- * * {digit,}
- * * {digit,digit}
- * * {,digit}
- *
- * Unfortunately, if there are any spaces in between, then this just becomes a
- * regular character match expression and we have to backtrack. So when this
- * function first starts running, we'll create a "save" point and then attempt
- * to parse the quantifier. If it fails, we'll restore the save point and
- * return.
- *
- * The properly track everything, we're going to build a little state machine.
- * It looks something like the following:
- *
- * +-------+ +---------+ ------------+
- * ---- lbrace ---> | start | ---- digit ---> | minimum | |
- * +-------+ +---------+ <--- digit -+
- * | | |
- * +-------+ | | rbrace
- * | comma | <----- comma +---- comma -------+ |
- * +-------+ V V
- * | +---------+ +---------+
- * +-- digit --> | maximum | -- rbrace --> || final ||
- * +---------+ +---------+
- * | ^
- * +- digit -+
- *
- * Note that by the time we've hit this function, the lbrace has already been
- * consumed so we're in the start state.
- */
-static bool
-pm_regexp_parse_range_quantifier(pm_regexp_parser_t *parser) {
- const uint8_t *savepoint = parser->cursor;
-
- enum {
- PM_REGEXP_RANGE_QUANTIFIER_STATE_START,
- PM_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM,
- PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM,
- PM_REGEXP_RANGE_QUANTIFIER_STATE_COMMA
- } state = PM_REGEXP_RANGE_QUANTIFIER_STATE_START;
-
- while (1) {
- switch (state) {
- case PM_REGEXP_RANGE_QUANTIFIER_STATE_START:
- switch (*parser->cursor) {
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
- parser->cursor++;
- state = PM_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM;
- break;
- case ',':
- parser->cursor++;
- state = PM_REGEXP_RANGE_QUANTIFIER_STATE_COMMA;
- break;
- default:
- parser->cursor = savepoint;
- return true;
- }
- break;
- case PM_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM:
- switch (*parser->cursor) {
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
- parser->cursor++;
- break;
- case ',':
- parser->cursor++;
- state = PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM;
- break;
- case '}':
- parser->cursor++;
- return true;
- default:
- parser->cursor = savepoint;
- return true;
- }
- break;
- case PM_REGEXP_RANGE_QUANTIFIER_STATE_COMMA:
- switch (*parser->cursor) {
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
- parser->cursor++;
- state = PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM;
- break;
- default:
- parser->cursor = savepoint;
- return true;
- }
- break;
- case PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM:
- switch (*parser->cursor) {
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
- parser->cursor++;
- break;
- case '}':
- parser->cursor++;
- return true;
- default:
- parser->cursor = savepoint;
- return true;
- }
- break;
- }
- }
-
- return true;
-}
-
-/**
- * quantifier : star-quantifier
- * | plus-quantifier
- * | optional-quantifier
- * | range-quantifier
- * | <empty>
- * ;
- */
-static bool
-pm_regexp_parse_quantifier(pm_regexp_parser_t *parser) {
- if (pm_regexp_char_is_eof(parser)) return true;
-
- switch (*parser->cursor) {
- case '*':
- case '+':
- case '?':
- parser->cursor++;
- return true;
- case '{':
- parser->cursor++;
- return pm_regexp_parse_range_quantifier(parser);
- default:
- // In this case there is no quantifier.
- return true;
- }
-}
-
-/**
- * match-posix-class : '[' '[' ':' '^'? CHAR+ ':' ']' ']'
- * ;
- */
-static bool
-pm_regexp_parse_posix_class(pm_regexp_parser_t *parser) {
- if (!pm_regexp_char_expect(parser, ':')) {
- return false;
- }
-
- pm_regexp_char_accept(parser, '^');
-
- return (
- pm_regexp_char_find(parser, ':') &&
- pm_regexp_char_expect(parser, ']') &&
- pm_regexp_char_expect(parser, ']')
- );
-}
-
-// Forward declaration because character sets can be nested.
-static bool
-pm_regexp_parse_lbracket(pm_regexp_parser_t *parser);
-
-/**
- * match-char-set : '[' '^'? (match-range | match-char)* ']'
- * ;
- */
-static bool
-pm_regexp_parse_character_set(pm_regexp_parser_t *parser) {
- pm_regexp_char_accept(parser, '^');
-
- while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ']') {
- switch (*parser->cursor++) {
- case '[':
- pm_regexp_parse_lbracket(parser);
- break;
- case '\\':
- if (!pm_regexp_char_is_eof(parser)) {
- parser->cursor++;
- }
- break;
- default:
- // do nothing, we've already advanced the cursor
- break;
- }
- }
-
- return pm_regexp_char_expect(parser, ']');
-}
-
-/**
- * A left bracket can either mean a POSIX class or a character set.
- */
-static bool
-pm_regexp_parse_lbracket(pm_regexp_parser_t *parser) {
- const uint8_t *reset = parser->cursor;
-
- if ((parser->cursor + 2 < parser->end) && parser->cursor[0] == '[' && parser->cursor[1] == ':') {
- parser->cursor++;
- if (pm_regexp_parse_posix_class(parser)) return true;
-
- parser->cursor = reset;
- }
-
- return pm_regexp_parse_character_set(parser);
-}
-
-// Forward declaration here since parsing groups needs to go back up the grammar
-// to parse expressions within them.
-static bool
-pm_regexp_parse_expression(pm_regexp_parser_t *parser);
-
-/**
- * These are the states of the options that are configurable on the regular
- * expression (or from within a group).
- */
-typedef enum {
- PM_REGEXP_OPTION_STATE_INVALID,
- PM_REGEXP_OPTION_STATE_TOGGLEABLE,
- PM_REGEXP_OPTION_STATE_ADDABLE,
- PM_REGEXP_OPTION_STATE_ADDED,
- PM_REGEXP_OPTION_STATE_REMOVED
-} pm_regexp_option_state_t;
-
-// These are the options that are configurable on the regular expression (or
-// from within a group).
-
-#define PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM 'a'
-#define PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM 'x'
-#define PRISM_REGEXP_OPTION_STATE_SLOTS (PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM + 1)
-
-/**
- * This is the set of options that are configurable on the regular expression.
- */
-typedef struct {
- /** The current state of each option. */
- uint8_t values[PRISM_REGEXP_OPTION_STATE_SLOTS];
-} pm_regexp_options_t;
-
-/**
- * Initialize a new set of options to their default values.
- */
-static void
-pm_regexp_options_init(pm_regexp_options_t *options) {
- memset(options, PM_REGEXP_OPTION_STATE_INVALID, sizeof(uint8_t) * PRISM_REGEXP_OPTION_STATE_SLOTS);
- options->values['i' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_TOGGLEABLE;
- options->values['m' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_TOGGLEABLE;
- options->values['x' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_TOGGLEABLE;
- options->values['d' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_ADDABLE;
- options->values['a' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_ADDABLE;
- options->values['u' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_ADDABLE;
-}
-
-/**
- * Attempt to add the given option to the set of options. Returns true if it was
- * added, false if it was already present.
- */
-static bool
-pm_regexp_options_add(pm_regexp_options_t *options, uint8_t key) {
- if (key >= PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM) {
- key = (uint8_t) (key - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM);
-
- switch (options->values[key]) {
- case PM_REGEXP_OPTION_STATE_INVALID:
- case PM_REGEXP_OPTION_STATE_REMOVED:
- return false;
- case PM_REGEXP_OPTION_STATE_TOGGLEABLE:
- case PM_REGEXP_OPTION_STATE_ADDABLE:
- options->values[key] = PM_REGEXP_OPTION_STATE_ADDED;
- return true;
- case PM_REGEXP_OPTION_STATE_ADDED:
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Attempt to remove the given option from the set of options. Returns true if
- * it was removed, false if it was already absent.
- */
-static bool
-pm_regexp_options_remove(pm_regexp_options_t *options, uint8_t key) {
- if (key >= PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM) {
- key = (uint8_t) (key - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM);
-
- switch (options->values[key]) {
- case PM_REGEXP_OPTION_STATE_INVALID:
- case PM_REGEXP_OPTION_STATE_ADDABLE:
- return false;
- case PM_REGEXP_OPTION_STATE_TOGGLEABLE:
- case PM_REGEXP_OPTION_STATE_ADDED:
- case PM_REGEXP_OPTION_STATE_REMOVED:
- options->values[key] = PM_REGEXP_OPTION_STATE_REMOVED;
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Groups can have quite a few different patterns for syntax. They basically
- * just wrap a set of expressions, but they can potentially have options after a
- * question mark. If there _isn't_ a question mark, then it's just a set of
- * expressions. If there _is_, then here are the options:
- *
- * * (?#...) - inline comments
- * * (?:subexp) - non-capturing group
- * * (?=subexp) - positive lookahead
- * * (?!subexp) - negative lookahead
- * * (?>subexp) - atomic group
- * * (?~subexp) - absence operator
- * * (?<=subexp) - positive lookbehind
- * * (?<!subexp) - negative lookbehind
- * * (?<name>subexp) - named capturing group
- * * (?'name'subexp) - named capturing group
- * * (?(cond)yes-subexp) - conditional expression
- * * (?(cond)yes-subexp|no-subexp) - conditional expression
- * * (?imxdau-imx) - turn on and off configuration
- * * (?imxdau-imx:subexp) - turn on and off configuration for an expression
- */
-static bool
-pm_regexp_parse_group(pm_regexp_parser_t *parser) {
- // First, parse any options for the group.
- if (pm_regexp_char_accept(parser, '?')) {
- if (pm_regexp_char_is_eof(parser)) {
- return false;
- }
- pm_regexp_options_t options;
- pm_regexp_options_init(&options);
-
- switch (*parser->cursor) {
- case '#': { // inline comments
- if (parser->encoding_changed && parser->encoding->multibyte) {
- bool escaped = false;
-
- // Here we're going to take a slow path and iterate through
- // each multibyte character to find the close paren. We do
- // this because \ can be a trailing byte in some encodings.
- while (parser->cursor < parser->end) {
- if (!escaped && *parser->cursor == ')') {
- parser->cursor++;
- return true;
- }
-
- size_t width = parser->encoding->char_width(parser->cursor, (ptrdiff_t) (parser->end - parser->cursor));
- if (width == 0) return false;
-
- escaped = (width == 1) && (*parser->cursor == '\\');
- parser->cursor += width;
- }
-
- return false;
- } else {
- // Here we can take the fast path and use memchr to find the
- // next ) because we are safe checking backward for \ since
- // it cannot be a trailing character.
- bool found = pm_regexp_char_find(parser, ')');
-
- while (found && (parser->start <= parser->cursor - 2) && (*(parser->cursor - 2) == '\\')) {
- found = pm_regexp_char_find(parser, ')');
- }
-
- return found;
- }
- }
- case ':': // non-capturing group
- case '=': // positive lookahead
- case '!': // negative lookahead
- case '>': // atomic group
- case '~': // absence operator
- parser->cursor++;
- break;
- case '<':
- parser->cursor++;
- if (pm_regexp_char_is_eof(parser)) {
- return false;
- }
-
- switch (*parser->cursor) {
- case '=': // positive lookbehind
- case '!': // negative lookbehind
- parser->cursor++;
- break;
- default: { // named capture group
- const uint8_t *start = parser->cursor;
- if (!pm_regexp_char_find(parser, '>')) {
- return false;
- }
- pm_regexp_parser_named_capture(parser, start, parser->cursor - 1);
- break;
- }
- }
- break;
- case '\'': { // named capture group
- const uint8_t *start = ++parser->cursor;
- if (!pm_regexp_char_find(parser, '\'')) {
- return false;
- }
-
- pm_regexp_parser_named_capture(parser, start, parser->cursor - 1);
- break;
- }
- case '(': // conditional expression
- if (!pm_regexp_char_find(parser, ')')) {
- return false;
- }
- break;
- case 'i': case 'm': case 'x': case 'd': case 'a': case 'u': // options
- while (!pm_regexp_char_is_eof(parser) && *parser->cursor != '-' && *parser->cursor != ':' && *parser->cursor != ')') {
- if (!pm_regexp_options_add(&options, *parser->cursor)) {
- return false;
- }
- parser->cursor++;
- }
-
- if (pm_regexp_char_is_eof(parser)) {
- return false;
- }
-
- // If we hit a -, then we're done parsing options.
- if (*parser->cursor != '-') break;
-
- // Otherwise, fallthrough to the - case.
- /* fallthrough */
- case '-':
- parser->cursor++;
- while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ':' && *parser->cursor != ')') {
- if (!pm_regexp_options_remove(&options, *parser->cursor)) {
- return false;
- }
- parser->cursor++;
- }
-
- if (pm_regexp_char_is_eof(parser)) {
- return false;
- }
- break;
- default:
- return false;
- }
- }
-
- // Now, parse the expressions within this group.
- while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ')') {
- if (!pm_regexp_parse_expression(parser)) {
- return false;
- }
- pm_regexp_char_accept(parser, '|');
- }
-
- // Finally, make sure we have a closing parenthesis.
- return pm_regexp_char_expect(parser, ')');
-}
-
-/**
- * item : anchor
- * | match-posix-class
- * | match-char-set
- * | match-char-class
- * | match-char-prop
- * | match-char
- * | match-any
- * | group
- * | quantified
- * ;
- */
-static bool
-pm_regexp_parse_item(pm_regexp_parser_t *parser) {
- switch (*parser->cursor++) {
- case '^':
- case '$':
- return true;
- case '\\':
- if (!pm_regexp_char_is_eof(parser)) {
- parser->cursor++;
- }
- return pm_regexp_parse_quantifier(parser);
- case '(':
- return pm_regexp_parse_group(parser) && pm_regexp_parse_quantifier(parser);
- case '[':
- return pm_regexp_parse_lbracket(parser) && pm_regexp_parse_quantifier(parser);
- default:
- return pm_regexp_parse_quantifier(parser);
- }
-}
-
-/**
- * expression : item+
- * ;
- */
-static bool
-pm_regexp_parse_expression(pm_regexp_parser_t *parser) {
- if (!pm_regexp_parse_item(parser)) {
- return false;
- }
-
- while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ')' && *parser->cursor != '|') {
- if (!pm_regexp_parse_item(parser)) {
- return false;
- }
- }
-
- return true;
-}
-
-/**
- * pattern : EOF
- * | expression EOF
- * | expression '|' pattern
- * ;
- */
-static bool
-pm_regexp_parse_pattern(pm_regexp_parser_t *parser) {
- return (
- (
- // Exit early if the pattern is empty.
- pm_regexp_char_is_eof(parser) ||
- // Parse the first expression in the pattern.
- pm_regexp_parse_expression(parser)
- ) &&
- (
- // Return now if we've parsed the entire pattern.
- pm_regexp_char_is_eof(parser) ||
- // Otherwise, we should have a pipe character.
- (pm_regexp_char_expect(parser, '|') && pm_regexp_parse_pattern(parser))
- )
- );
-}
-
-/**
- * Parse a regular expression and extract the names of all of the named capture
- * groups.
- */
-PRISM_EXPORTED_FUNCTION bool
-pm_regexp_named_capture_group_names(const uint8_t *source, size_t size, pm_string_list_t *named_captures, bool encoding_changed, const pm_encoding_t *encoding) {
- pm_regexp_parser_t parser;
- pm_regexp_parser_init(&parser, source, source + size, named_captures, encoding_changed, encoding);
- return pm_regexp_parse_pattern(&parser);
-}
diff --git a/prism/regexp.h b/prism/regexp.h
deleted file mode 100644
index c5ceab11f9..0000000000
--- a/prism/regexp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file regexp.h
- *
- * A regular expression parser.
- */
-#ifndef PRISM_REGEXP_H
-#define PRISM_REGEXP_H
-
-#include "prism/defines.h"
-#include "prism/parser.h"
-#include "prism/encoding.h"
-#include "prism/util/pm_memchr.h"
-#include "prism/util/pm_string_list.h"
-#include "prism/util/pm_string.h"
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <string.h>
-
-/**
- * Parse a regular expression and extract the names of all of the named capture
- * groups.
- *
- * @param source The source code to parse.
- * @param size The size of the source code.
- * @param named_captures The list to add the names of the named capture groups.
- * @param encoding_changed Whether or not the encoding changed from the default.
- * @param encoding The encoding of the source code.
- * @return Whether or not the parsing was successful.
- */
-PRISM_EXPORTED_FUNCTION bool pm_regexp_named_capture_group_names(const uint8_t *source, size_t size, pm_string_list_t *named_captures, bool encoding_changed, const pm_encoding_t *encoding);
-
-#endif
diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb
deleted file mode 100644
index 93f67f6551..0000000000
--- a/prism/templates/ext/prism/api_node.c.erb
+++ /dev/null
@@ -1,221 +0,0 @@
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
-#include "prism/extension.h"
-
-extern VALUE rb_cPrism;
-extern VALUE rb_cPrismNode;
-extern VALUE rb_cPrismSource;
-extern VALUE rb_cPrismToken;
-extern VALUE rb_cPrismLocation;
-
-<%- nodes.each do |node| -%>
-static VALUE rb_cPrism<%= node.name %>;
-<%- end -%>
-
-static VALUE
-pm_location_new(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, VALUE source) {
- VALUE argv[] = { source, LONG2FIX(start - parser->start), LONG2FIX(end - start) };
- return rb_class_new_instance(3, argv, rb_cPrismLocation);
-}
-
-VALUE
-pm_token_new(pm_parser_t *parser, pm_token_t *token, rb_encoding *encoding, VALUE source) {
- ID type = rb_intern(pm_token_type_to_str(token->type));
- VALUE location = pm_location_new(parser, token->start, token->end, source);
-
- VALUE argv[] = {
- ID2SYM(type),
- rb_enc_str_new((const char *) token->start, token->end - token->start, encoding),
- location
- };
-
- return rb_class_new_instance(3, argv, rb_cPrismToken);
-}
-
-static VALUE
-pm_string_new(pm_string_t *string, rb_encoding *encoding) {
- return rb_enc_str_new((const char *) pm_string_source(string), pm_string_length(string), encoding);
-}
-
-// Create a Prism::Source object from the given parser.
-VALUE
-pm_source_new(pm_parser_t *parser, rb_encoding *encoding) {
- VALUE source = rb_enc_str_new((const char *) parser->start, parser->end - parser->start, encoding);
- VALUE offsets = rb_ary_new_capa(parser->newline_list.size);
-
- for (size_t index = 0; index < parser->newline_list.size; index++) {
- rb_ary_push(offsets, INT2FIX(parser->newline_list.offsets[index]));
- }
-
- VALUE source_argv[] = { source, LONG2NUM(parser->start_line), offsets };
- return rb_class_new_instance(3, source_argv, rb_cPrismSource);
-}
-
-typedef struct pm_node_stack_node {
- struct pm_node_stack_node *prev;
- pm_node_t *visit;
- bool visited;
-} pm_node_stack_node_t;
-
-static void
-pm_node_stack_push(pm_node_stack_node_t **stack, pm_node_t *visit) {
- pm_node_stack_node_t *node = malloc(sizeof(pm_node_stack_node_t));
- node->prev = *stack;
- node->visit = visit;
- node->visited = false;
- *stack = node;
-}
-
-static pm_node_t *
-pm_node_stack_pop(pm_node_stack_node_t **stack) {
- pm_node_stack_node_t *current = *stack;
- pm_node_t *visit = current->visit;
-
- *stack = current->prev;
- free(current);
-
- return visit;
-}
-
-VALUE
-pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
- VALUE source = pm_source_new(parser, encoding);
- ID *constants = calloc(parser->constant_pool.size, sizeof(ID));
-
- for (uint32_t index = 0; index < parser->constant_pool.size; index++) {
- pm_constant_t *constant = &parser->constant_pool.constants[index];
- int state = 0;
-
- VALUE string = rb_enc_str_new((const char *) constant->start, constant->length, encoding);
- ID value = rb_protect(rb_intern_str, string, &state);
-
- if (state != 0) {
- value = rb_intern_const("?");
- rb_set_errinfo(Qnil);
- }
-
- constants[index] = value;
- }
-
- pm_node_stack_node_t *node_stack = NULL;
- pm_node_stack_push(&node_stack, node);
- VALUE value_stack = rb_ary_new();
-
- while (node_stack != NULL) {
- if (!node_stack->visited) {
- if (node_stack->visit == NULL) {
- pm_node_stack_pop(&node_stack);
- rb_ary_push(value_stack, Qnil);
- continue;
- }
-
- pm_node_t *node = node_stack->visit;
- node_stack->visited = true;
-
- switch (PM_NODE_TYPE(node)) {
- <%- nodes.each do |node| -%>
- <%- if node.fields.any? { |field| [Prism::NodeField, Prism::OptionalNodeField, Prism::NodeListField].include?(field.class) } -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- case <%= node.type %>: {
- pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
- <%- node.fields.each do |field| -%>
- <%- case field -%>
- <%- when Prism::NodeField, Prism::OptionalNodeField -%>
- pm_node_stack_push(&node_stack, (pm_node_t *) cast-><%= field.name %>);
- <%- when Prism::NodeListField -%>
- for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
- pm_node_stack_push(&node_stack, (pm_node_t *) cast-><%= field.name %>.nodes[index]);
- }
- <%- end -%>
- <%- end -%>
- break;
- }
- <%- end -%>
- <%- end -%>
- default:
- break;
- }
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- } else {
- pm_node_t *node = pm_node_stack_pop(&node_stack);
-
- switch (PM_NODE_TYPE(node)) {
- <%- nodes.each do |node| -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- case <%= node.type %>: {
- <%- if node.fields.any? { |field| ![Prism::NodeField, Prism::OptionalNodeField, Prism::FlagsField].include?(field.class) } -%>
- pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
- <%- end -%>
- VALUE argv[<%= node.fields.length + 1 %>];
- <%- node.fields.each_with_index do |field, index| -%>
-
- // <%= field.name %>
- <%- case field -%>
- <%- when Prism::NodeField, Prism::OptionalNodeField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = rb_ary_pop(value_stack);
- <%- when Prism::NodeListField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = rb_ary_new_capa(cast-><%= field.name %>.size);
- for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
- rb_ary_push(argv[<%= index %>], rb_ary_pop(value_stack));
- }
- <%- when Prism::StringField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = pm_string_new(&cast-><%= field.name %>, encoding);
- <%- when Prism::ConstantField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- assert(cast-><%= field.name %> != 0);
- argv[<%= index %>] = rb_id2sym(constants[cast-><%= field.name %> - 1]);
- <%- when Prism::OptionalConstantField -%>
- argv[<%= index %>] = cast-><%= field.name %> == 0 ? Qnil : rb_id2sym(constants[cast-><%= field.name %> - 1]);
- <%- when Prism::ConstantListField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = rb_ary_new_capa(cast-><%= field.name %>.size);
- for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
- assert(cast-><%= field.name %>.ids[index] != 0);
- rb_ary_push(argv[<%= index %>], rb_id2sym(constants[cast-><%= field.name %>.ids[index] - 1]));
- }
- <%- when Prism::LocationField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = pm_location_new(parser, cast-><%= field.name %>.start, cast-><%= field.name %>.end, source);
- <%- when Prism::OptionalLocationField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = cast-><%= field.name %>.start == NULL ? Qnil : pm_location_new(parser, cast-><%= field.name %>.start, cast-><%= field.name %>.end, source);
- <%- when Prism::UInt8Field -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = UINT2NUM(cast-><%= field.name %>);
- <%- when Prism::UInt32Field -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = ULONG2NUM(cast-><%= field.name %>);
- <%- when Prism::FlagsField -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- <%- end -%>
-
- // location
- argv[<%= node.fields.length %>] = pm_location_new(parser, node->location.start, node->location.end, source);
-
- rb_ary_push(value_stack, rb_class_new_instance(<%= node.fields.length + 1 %>, argv, rb_cPrism<%= node.name %>));
- break;
- }
- <%- end -%>
- default:
- rb_raise(rb_eRuntimeError, "unknown node type: %d", PM_NODE_TYPE(node));
- }
- }
- }
-
- VALUE result = rb_ary_pop(value_stack);
- free(constants);
- return result;
-}
-
-void
-Init_prism_api_node(void) {
- <%- nodes.each do |node| -%>
- rb_cPrism<%= node.name %> = rb_define_class_under(rb_cPrism, "<%= node.name %>", rb_cPrismNode);
- <%- end -%>
-}
diff --git a/prism/templates/include/prism/ast.h.erb b/prism/templates/include/prism/ast.h.erb
deleted file mode 100644
index c169fedf0a..0000000000
--- a/prism/templates/include/prism/ast.h.erb
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * @file ast.h
- *
- * The abstract syntax tree.
- */
-#ifndef PRISM_AST_H
-#define PRISM_AST_H
-
-#include "prism/defines.h"
-#include "prism/util/pm_constant_pool.h"
-#include "prism/util/pm_string.h"
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * This enum represents every type of token in the Ruby source.
- */
-typedef enum pm_token_type {
-<%- tokens.each do |token| -%>
- /** <%= token.comment %> */
- PM_TOKEN_<%= token.name %><%= " = #{token.value}" if token.value %>,
-
-<%- end -%>
- /** The maximum token value. */
- PM_TOKEN_MAXIMUM,
-} pm_token_type_t;
-
-/**
- * This struct represents a token in the Ruby source. We use it to track both
- * type and location information.
- */
-typedef struct {
- /** The type of the token. */
- pm_token_type_t type;
-
- /** A pointer to the start location of the token in the source. */
- const uint8_t *start;
-
- /** A pointer to the end location of the token in the source. */
- const uint8_t *end;
-} pm_token_t;
-
-/**
- * This represents a range of bytes in the source string to which a node or
- * token corresponds.
- */
-typedef struct {
- /** A pointer to the start location of the range in the source. */
- const uint8_t *start;
-
- /** A pointer to the end location of the range in the source. */
- const uint8_t *end;
-} pm_location_t;
-
-struct pm_node;
-
-/**
- * A list of nodes in the source, most often used for lists of children.
- */
-typedef struct pm_node_list {
- /** The number of nodes in the list. */
- size_t size;
-
- /** The capacity of the list that has been allocated. */
- size_t capacity;
-
- /** The nodes in the list. */
- struct pm_node **nodes;
-} pm_node_list_t;
-
-/**
- * This enum represents every type of node in the Ruby syntax tree.
- */
-enum pm_node_type {
-<%- nodes.each_with_index do |node, index| -%>
- /** <%= node.name %> */
- <%= node.type %> = <%= index + 1 %>,
-
-<%- end -%>
- /** A special kind of node used for compilation. */
- PM_SCOPE_NODE
-};
-
-/**
- * This is the type of node embedded in the node struct. We explicitly control
- * the size of it here to avoid having the variable-width enum.
- */
-typedef uint16_t pm_node_type_t;
-
-/**
- * These are the flags embedded in the node struct. We explicitly control the
- * size of it here to avoid having the variable-width enum.
- */
-typedef uint16_t pm_node_flags_t;
-
-/**
- * We store the flags enum in every node in the tree. Some flags are common to
- * all nodes (the ones listed below). Others are specific to certain node types.
- */
-#define PM_NODE_FLAG_BITS (sizeof(pm_node_flags_t) * 8)
-
-static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = (1 << (PM_NODE_FLAG_BITS - 1));
-static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = (1 << (PM_NODE_FLAG_BITS - 2));
-static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = (1 << (PM_NODE_FLAG_BITS - 1)) | (1 << (PM_NODE_FLAG_BITS - 2));
-
-/**
- * Cast the type to an enum to allow the compiler to provide exhaustiveness
- * checking.
- */
-#define PM_NODE_TYPE(node) ((enum pm_node_type) node->type)
-
-/**
- * Return true if the type of the given node matches the given type.
- */
-#define PM_NODE_TYPE_P(node, type) (PM_NODE_TYPE(node) == (type))
-
-/**
- * Return true if the given flag is set on the given node.
- */
-#define PM_NODE_FLAG_P(node, flag) ((((pm_node_t *)(node))->flags & (flag)) != 0)
-
-/**
- * This is the base structure that represents a node in the syntax tree. It is
- * embedded into every node type.
- */
-typedef struct pm_node {
- /**
- * This represents the type of the node. It somewhat maps to the nodes that
- * existed in the original grammar and ripper, but it's not a 1:1 mapping.
- */
- pm_node_type_t type;
-
- /**
- * This represents any flags on the node. Some are common to all nodes, and
- * some are specific to the type of node.
- */
- pm_node_flags_t flags;
-
- /**
- * This is the location of the node in the source. It's a range of bytes
- * containing a start and an end.
- */
- pm_location_t location;
-} pm_node_t;
-<%- nodes.each do |node| -%>
-
-/**
- * <%= node.name %>
- *
- * Type: <%= node.type %>
-<%- if (node_flags = node.fields.find { |field| field.is_a? Prism::FlagsField }) -%>
- * Flags:
-<%- found = flags.find { |flag| flag.name == node_flags.kind }.tap { |found| raise "Expected to find #{field.kind}" unless found } -%>
-<%- found.values.each do |value| -%>
- * PM_<%= found.human.upcase %>_<%= value.name %>
-<%- end -%>
-<%- end -%>
- *
- * @extends pm_node_t
- */
-typedef struct pm_<%= node.human %> {
- /** The embedded base node. */
- pm_node_t base;
-<%- node.fields.grep_v(Prism::FlagsField).each do |field| -%>
-
- /** <%= node.name %>#<%= field.name %> */
- <%= case field
- when Prism::NodeField, Prism::OptionalNodeField then "struct #{field.c_type} *#{field.name}"
- when Prism::NodeListField then "struct pm_node_list #{field.name}"
- when Prism::ConstantField, Prism::OptionalConstantField then "pm_constant_id_t #{field.name}"
- when Prism::ConstantListField then "pm_constant_id_list_t #{field.name}"
- when Prism::StringField then "pm_string_t #{field.name}"
- when Prism::LocationField, Prism::OptionalLocationField then "pm_location_t #{field.name}"
- when Prism::UInt8Field then "uint8_t #{field.name}"
- when Prism::UInt32Field then "uint32_t #{field.name}"
- else raise field.class.name
- end
- %>;
-<%- end -%>
-} pm_<%= node.human %>_t;
-<%- end -%>
-<%- flags.each do |flag| -%>
-
-/**
- * <%= flag.comment %>
- */
-typedef enum pm_<%= flag.human %> {
- <%- flag.values.each_with_index do |value, index| -%>
-<%= "\n" if index > 0 -%>
- /** <%= value.comment %> */
- PM_<%= flag.human.upcase %>_<%= value.name %> = <%= 1 << index %>,
- <%- end -%>
-} pm_<%= flag.human %>_t;
-<%- end -%>
-
-/**
- * When we're serializing to Java, we want to skip serializing the location
- * fields as they won't be used by JRuby or TruffleRuby. This boolean allows us
- * to specify that through the environment. It will never be true except for in
- * those build systems.
- */
-#define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS <%= Prism::SERIALIZE_ONLY_SEMANTICS_FIELDS %>
-
-#endif
diff --git a/prism/templates/lib/prism/compiler.rb.erb b/prism/templates/lib/prism/compiler.rb.erb
deleted file mode 100644
index 2c947f6ed2..0000000000
--- a/prism/templates/lib/prism/compiler.rb.erb
+++ /dev/null
@@ -1,41 +0,0 @@
-module Prism
- # A compiler is a visitor that returns the value of each node as it visits.
- # This is as opposed to a visitor which will only walk the tree. This can be
- # useful when you are trying to compile a tree into a different format.
- #
- # For example, to build a representation of the tree as s-expressions, you
- # could write:
- #
- # class SExpressions < Prism::Compiler
- # def visit_arguments_node(node) = [:arguments, super]
- # def visit_call_node(node) = [:call, super]
- # def visit_integer_node(node) = [:integer]
- # def visit_program_node(node) = [:program, super]
- # end
- #
- # Prism.parse("1 + 2").value.accept(SExpressions.new)
- # # => [:program, [[[:call, [[:integer], [:arguments, [[:integer]]]]]]]]
- #
- class Compiler
- # Visit an individual node.
- def visit(node)
- node&.accept(self)
- end
-
- # Visit a list of nodes.
- def visit_all(nodes)
- nodes.map { |node| node&.accept(self) }
- end
-
- # Visit the child nodes of the given node.
- def visit_child_nodes(node)
- node.compact_child_nodes.map { |node| node.accept(self) }
- end
-
- <%- nodes.each_with_index do |node, index| -%>
-<%= "\n" if index != 0 -%>
- # Compile a <%= node.name %> node
- alias visit_<%= node.human %> visit_child_nodes
- <%- end -%>
- end
-end
diff --git a/prism/templates/lib/prism/dispatcher.rb.erb b/prism/templates/lib/prism/dispatcher.rb.erb
deleted file mode 100644
index 1370ca7636..0000000000
--- a/prism/templates/lib/prism/dispatcher.rb.erb
+++ /dev/null
@@ -1,89 +0,0 @@
-module Prism
- # The dispatcher class fires events for nodes that are found while walking an
- # AST to all registered listeners. It's useful for performing different types
- # of analysis on the AST while only having to walk the tree once.
- #
- # To use the dispatcher, you would first instantiate it and register listeners
- # for the events you're interested in:
- #
- # class OctalListener
- # def on_integer_node_enter(node)
- # if node.octal? && !node.slice.start_with?("0o")
- # warn("Octal integers should be written with the 0o prefix")
- # end
- # end
- # end
- #
- # dispatcher = Dispatcher.new
- # dispatcher.register(listener, :on_integer_node_enter)
- #
- # Then, you can walk any number of trees and dispatch events to the listeners:
- #
- # result = Prism.parse("001 + 002 + 003")
- # dispatcher.dispatch(result.value)
- #
- # Optionally, you can also use `#dispatch_once` to dispatch enter and leave
- # events for a single node without recursing further down the tree. This can
- # be useful in circumstances where you want to reuse the listeners you already
- # have registers but want to stop walking the tree at a certain point.
- #
- # integer = result.value.statements.body.first.receiver.receiver
- # dispatcher.dispatch_once(integer)
- #
- class Dispatcher < Visitor
- # attr_reader listeners: Hash[Symbol, Array[Listener]]
- attr_reader :listeners
-
- # Initialize a new dispatcher.
- def initialize
- @listeners = {}
- end
-
- # Register a listener for one or more events.
- #
- # def register: (Listener, *Symbol) -> void
- def register(listener, *events)
- events.each { |event| (listeners[event] ||= []) << listener }
- end
-
- # Walks `root` dispatching events to all registered listeners.
- #
- # def dispatch: (Node) -> void
- alias dispatch visit
-
- # Dispatches a single event for `node` to all registered listeners.
- #
- # def dispatch_once: (Node) -> void
- def dispatch_once(node)
- node.accept(DispatchOnce.new(listeners))
- end
- <%- nodes.each do |node| -%>
-
- # Dispatch enter and leave events for <%= node.name %> nodes and continue
- # walking the tree.
- def visit_<%= node.human %>(node)
- listeners[:on_<%= node.human %>_enter]&.each { |listener| listener.on_<%= node.human %>_enter(node) }
- super
- listeners[:on_<%= node.human %>_leave]&.each { |listener| listener.on_<%= node.human %>_leave(node) }
- end
- <%- end -%>
-
- class DispatchOnce < Visitor # :nodoc:
- attr_reader :listeners
-
- def initialize(listeners)
- @listeners = listeners
- end
- <%- nodes.each do |node| -%>
-
- # Dispatch enter and leave events for <%= node.name %> nodes.
- def visit_<%= node.human %>(node)
- listeners[:on_<%= node.human %>_enter]&.each { |listener| listener.on_<%= node.human %>_enter(node) }
- listeners[:on_<%= node.human %>_leave]&.each { |listener| listener.on_<%= node.human %>_leave(node) }
- end
- <%- end -%>
- end
-
- private_constant :DispatchOnce
- end
-end
diff --git a/prism/templates/lib/prism/dot_visitor.rb.erb b/prism/templates/lib/prism/dot_visitor.rb.erb
deleted file mode 100644
index fc3dd4b223..0000000000
--- a/prism/templates/lib/prism/dot_visitor.rb.erb
+++ /dev/null
@@ -1,186 +0,0 @@
-require "cgi"
-
-module Prism
- # This visitor provides the ability to call Node#to_dot, which converts a
- # subtree into a graphviz dot graph.
- class DotVisitor < Visitor
- class Field # :nodoc:
- attr_reader :name, :value, :port
-
- def initialize(name, value, port)
- @name = name
- @value = value
- @port = port
- end
-
- def to_dot
- if port
- "<tr><td align=\"left\" colspan=\"2\" port=\"#{name}\">#{name}</td></tr>"
- else
- "<tr><td align=\"left\">#{name}</td><td>#{CGI.escapeHTML(value)}</td></tr>"
- end
- end
- end
-
- class Table # :nodoc:
- attr_reader :name, :fields
-
- def initialize(name)
- @name = name
- @fields = []
- end
-
- def field(name, value = nil, port: false)
- fields << Field.new(name, value, port)
- end
-
- def to_dot
- dot = <<~DOT
- <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
- <tr><td colspan="2"><b>#{name}</b></td></tr>
- DOT
-
- if fields.any?
- "#{dot} #{fields.map(&:to_dot).join("\n ")}\n</table>"
- else
- "#{dot}</table>"
- end
- end
- end
-
- class Digraph # :nodoc:
- attr_reader :nodes, :waypoints, :edges
-
- def initialize
- @nodes = []
- @waypoints = []
- @edges = []
- end
-
- def node(value)
- nodes << value
- end
-
- def waypoint(value)
- waypoints << value
- end
-
- def edge(value)
- edges << value
- end
-
- def to_dot
- <<~DOT
- digraph "Prism" {
- node [
- fontname=\"Courier New\"
- shape=plain
- style=filled
- fillcolor=gray95
- ];
-
- #{nodes.map { |node| node.gsub(/\n/, "\n ") }.join("\n ")}
- node [shape=point];
- #{waypoints.join("\n ")}
-
- #{edges.join("\n ")}
- }
- DOT
- end
- end
-
- private_constant :Field, :Table, :Digraph
-
- # The digraph that is being built.
- attr_reader :digraph
-
- # Initialize a new dot visitor.
- def initialize
- @digraph = Digraph.new
- end
-
- # Convert this visitor into a graphviz dot graph string.
- def to_dot
- digraph.to_dot
- end
- <%- nodes.each do |node| -%>
-
- # Visit a <%= node.name %> node.
- def visit_<%= node.human %>(node)
- table = Table.new("<%= node.name %>")
- id = node_id(node)
- <%- node.fields.each do |field| -%>
-
- # <%= field.name %>
- <%- case field -%>
- <%- when Prism::NodeField -%>
- table.field("<%= field.name %>", port: true)
- digraph.edge("#{id}:<%= field.name %> -> #{node_id(node.<%= field.name %>)};")
- <%- when Prism::OptionalNodeField -%>
- unless (<%= field.name %> = node.<%= field.name %>).nil?
- table.field("<%= field.name %>", port: true)
- digraph.edge("#{id}:<%= field.name %> -> #{node_id(<%= field.name %>)};")
- end
- <%- when Prism::NodeListField -%>
- if node.<%= field.name %>.any?
- table.field("<%= field.name %>", port: true)
-
- waypoint = "#{id}_<%= field.name %>"
- digraph.waypoint("#{waypoint};")
-
- digraph.edge("#{id}:<%= field.name %> -> #{waypoint};")
- node.<%= field.name %>.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
- else
- table.field("<%= field.name %>", "[]")
- end
- <%- when Prism::StringField, Prism::ConstantField, Prism::OptionalConstantField, Prism::UInt8Field, Prism::UInt32Field, Prism::ConstantListField -%>
- table.field("<%= field.name %>", node.<%= field.name %>.inspect)
- <%- when Prism::LocationField -%>
- table.field("<%= field.name %>", location_inspect(node.<%= field.name %>))
- <%- when Prism::OptionalLocationField -%>
- unless (<%= field.name %> = node.<%= field.name %>).nil?
- table.field("<%= field.name %>", location_inspect(<%= field.name %>))
- end
- <%- when Prism::FlagsField -%>
- <%- flag = flags.find { |flag| flag.name == field.kind }.tap { |flag| raise "Expected to find #{field.kind}" unless flag } -%>
- table.field("<%= field.name %>", <%= flag.human %>_inspect(node))
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- <%- end -%>
-
- digraph.nodes << <<~DOT
- #{id} [
- label=<#{table.to_dot.gsub(/\n/, "\n ")}>
- ];
- DOT
-
- super
- end
- <%- end -%>
-
- private
-
- # Generate a unique node ID for a node throughout the digraph.
- def node_id(node)
- "Node_#{node.object_id}"
- end
-
- # Inspect a location to display the start and end line and column numbers.
- def location_inspect(location)
- "(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})"
- end
- <%- flags.each do |flag| -%>
-
- # Inspect a node that has <%= flag.human %> flags to display the flags as a
- # comma-separated list.
- def <%= flag.human %>_inspect(node)
- flags = []
- <%- flag.values.each do |value| -%>
- flags << "<%= value.name.downcase %>" if node.<%= value.name.downcase %>?
- <%- end -%>
- flags.join(", ")
- end
- <%- end -%>
- end
-end
diff --git a/prism/templates/lib/prism/dsl.rb.erb b/prism/templates/lib/prism/dsl.rb.erb
deleted file mode 100644
index be18ad45ba..0000000000
--- a/prism/templates/lib/prism/dsl.rb.erb
+++ /dev/null
@@ -1,45 +0,0 @@
-module Prism
- # The DSL module provides a set of methods that can be used to create prism
- # nodes in a more concise manner. For example, instead of writing:
- #
- # source = Prism::Source.new("[1]")
- #
- # Prism::ArrayNode.new(
- # [
- # Prism::IntegerNode.new(
- # Prism::IntegerBaseFlags::DECIMAL,
- # Prism::Location.new(source, 1, 1),
- # )
- # ],
- # Prism::Location.new(source, 0, 1),
- # Prism::Location.new(source, 2, 1)
- # )
- #
- # you could instead write:
- #
- # source = Prism::Source.new("[1]")
- #
- # ArrayNode(
- # IntegerNode(Prism::IntegerBaseFlags::DECIMAL, Location(source, 1, 1))),
- # Location(source, 0, 1),
- # Location(source, 2, 1)
- # )
- #
- # This is mostly helpful in the context of writing tests, but can also be used
- # to generate trees programmatically.
- module DSL
- private
-
- # Create a new Location object
- def Location(source = nil, start_offset = 0, length = 0)
- Location.new(source, start_offset, length)
- end
- <%- nodes.each do |node| -%>
-
- # Create a new <%= node.name %> node
- def <%= node.name %>(<%= (node.fields.map(&:name) + ["location = Location()"]).join(", ") %>)
- <%= node.name %>.new(<%= (node.fields.map(&:name) + ["location"]).join(", ") %>)
- end
- <%- end -%>
- end
-end
diff --git a/prism/templates/lib/prism/mutation_compiler.rb.erb b/prism/templates/lib/prism/mutation_compiler.rb.erb
deleted file mode 100644
index 9a81b704eb..0000000000
--- a/prism/templates/lib/prism/mutation_compiler.rb.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-module Prism
- # This visitor walks through the tree and copies each node as it is being
- # visited. This is useful for consumers that want to mutate the tree, as you
- # can change subtrees in place without effecting the rest of the tree.
- class MutationCompiler < Compiler
- <%- nodes.each_with_index do |node, index| -%>
-<%= "\n" if index != 0 -%>
- # Copy a <%= node.name %> node
- def visit_<%= node.human %>(node)
- <%- fields = node.fields.select { |field| [Prism::NodeField, Prism::OptionalNodeField, Prism::NodeListField].include?(field.class) } -%>
- <%- if fields.any? -%>
- node.copy(<%= fields.map { |field| "#{field.name}: #{field.is_a?(Prism::NodeListField) ? "visit_all" : "visit"}(node.#{field.name})" }.join(", ") %>)
- <%- else -%>
- node.copy
- <%- end -%>
- end
- <%- end -%>
- end
-end
diff --git a/prism/templates/lib/prism/node.rb.erb b/prism/templates/lib/prism/node.rb.erb
deleted file mode 100644
index 87a94a0338..0000000000
--- a/prism/templates/lib/prism/node.rb.erb
+++ /dev/null
@@ -1,254 +0,0 @@
-module Prism
- # This represents a node in the tree. It is the parent class of all of the
- # various node types.
- class Node
- # A Location instance that represents the location of this node in the
- # source.
- attr_reader :location
-
- def newline? # :nodoc:
- @newline ? true : false
- end
-
- def set_newline_flag(newline_marked) # :nodoc:
- line = location.start_line
- unless newline_marked[line]
- newline_marked[line] = true
- @newline = true
- end
- end
-
- # Slice the location of the node from the source.
- def slice
- location.slice
- end
-
- # Similar to inspect, but respects the current level of indentation given by
- # the pretty print object.
- def pretty_print(q)
- q.seplist(inspect.chomp.each_line, -> { q.breakable }) do |line|
- q.text(line.chomp)
- end
- q.current_group.break
- end
-
- # Convert this node into a graphviz dot graph string.
- def to_dot
- DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot
- end
- end
- <%- nodes.each do |node| -%>
-
- <%- node.each_comment_line do |line| -%>
- #<%= line %>
- <%- end -%>
- class <%= node.name -%> < Node
- <%- node.fields.each do |field| -%>
- # attr_reader <%= field.name %>: <%= field.rbs_class %>
- <%= "private " if field.is_a?(Prism::FlagsField) %>attr_reader :<%= field.name %>
-
- <%- end -%>
- # def initialize: (<%= (node.fields.map { |field| "#{field.name}: #{field.rbs_class}" } + ["location: Location"]).join(", ") %>) -> void
- def initialize(<%= (node.fields.map(&:name) + ["location"]).join(", ") %>)
- <%- node.fields.each do |field| -%>
- @<%= field.name %> = <%= field.name %>
- <%- end -%>
- @location = location
- end
-
- # def accept: (visitor: Visitor) -> void
- def accept(visitor)
- visitor.visit_<%= node.human %>(self)
- end
- <%- if node.newline == false -%>
-
- def set_newline_flag(newline_marked) # :nodoc:
- # Never mark <%= node.name %> with a newline flag, mark children instead
- end
- <%- elsif node.newline.is_a?(String) -%>
-
- def set_newline_flag(newline_marked) # :nodoc:
- <%- field = node.fields.find { |f| f.name == node.newline } or raise node.newline -%>
- <%- case field -%>
- <%- when Prism::NodeField -%>
- <%= field.name %>.set_newline_flag(newline_marked)
- <%- when Prism::NodeListField -%>
- first = <%= field.name %>.first
- first.set_newline_flag(newline_marked) if first
- <%- else raise field.class.name -%>
- <%- end -%>
- end
- <%- end -%>
-
- # def child_nodes: () -> Array[nil | Node]
- def child_nodes
- [<%= node.fields.map { |field|
- case field
- when Prism::NodeField, Prism::OptionalNodeField then field.name
- when Prism::NodeListField then "*#{field.name}"
- end
- }.compact.join(", ") %>]
- end
-
- # def compact_child_nodes: () -> Array[Node]
- def compact_child_nodes
- <%- if node.fields.any? { |field| field.is_a?(Prism::OptionalNodeField) } -%>
- compact = []
- <%- node.fields.each do |field| -%>
- <%- case field -%>
- <%- when Prism::NodeField -%>
- compact << <%= field.name %>
- <%- when Prism::OptionalNodeField -%>
- compact << <%= field.name %> if <%= field.name %>
- <%- when Prism::NodeListField -%>
- compact.concat(<%= field.name %>)
- <%- end -%>
- <%- end -%>
- compact
- <%- else -%>
- [<%= node.fields.map { |field|
- case field
- when Prism::NodeField then field.name
- when Prism::NodeListField then "*#{field.name}"
- end
- }.compact.join(", ") %>]
- <%- end -%>
- end
-
- # def comment_targets: () -> Array[Node | Location]
- def comment_targets
- [<%= node.fields.map { |field|
- case field
- when Prism::NodeField, Prism::LocationField then field.name
- when Prism::OptionalNodeField, Prism::NodeListField, Prism::OptionalLocationField then "*#{field.name}"
- end
- }.compact.join(", ") %>]
- end
-
- # def copy: (**params) -> <%= node.name %>
- def copy(**params)
- <%= node.name %>.new(
- <%- (node.fields.map(&:name) + ["location"]).map do |name| -%>
- params.fetch(:<%= name %>) { <%= name %> },
- <%- end -%>
- )
- end
-
- # def deconstruct: () -> Array[nil | Node]
- alias deconstruct child_nodes
-
- # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
- def deconstruct_keys(keys)
- { <%= (node.fields.map { |field| "#{field.name}: #{field.name}" } + ["location: location"]).join(", ") %> }
- end
- <%- node.fields.each do |field| -%>
- <%- case field -%>
- <%- when Prism::LocationField -%>
- <%- raise unless field.name.end_with?("_loc") -%>
- <%- next if node.fields.any? { |other| other.name == field.name.delete_suffix("_loc") } -%>
-
- # def <%= field.name.delete_suffix("_loc") %>: () -> String
- def <%= field.name.delete_suffix("_loc") %>
- <%= field.name %>.slice
- end
- <%- when Prism::OptionalLocationField -%>
- <%- raise unless field.name.end_with?("_loc") -%>
- <%- next if node.fields.any? { |other| other.name == field.name.delete_suffix("_loc") } -%>
-
- # def <%= field.name.delete_suffix("_loc") %>: () -> String?
- def <%= field.name.delete_suffix("_loc") %>
- <%= field.name %>&.slice
- end
- <%- when Prism::FlagsField -%>
- <%- flags.find { |flag| flag.name == field.kind }.tap { |flag| raise "Expected to find #{field.kind}" unless flag }.values.each do |value| -%>
-
- # def <%= value.name.downcase %>?: () -> bool
- def <%= value.name.downcase %>?
- <%= field.name %>.anybits?(<%= field.kind %>::<%= value.name %>)
- end
- <%- end -%>
- <%- end -%>
- <%- end -%>
-
- # def inspect(inspector: NodeInspector) -> String
- def inspect(inspector = NodeInspector.new)
- inspector << inspector.header(self)
- <%- node.fields.each_with_index do |field, index| -%>
- <%- pointer, preadd = index == node.fields.length - 1 ? ["└── ", " "] : ["├── ", "│ "] -%>
- <%- case field -%>
- <%- when Prism::NodeListField -%>
- inspector << "<%= pointer %><%= field.name %>: #{inspector.list("#{inspector.prefix}<%= preadd %>", <%= field.name %>)}"
- <%- when Prism::ConstantListField -%>
- inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n"
- <%- when Prism::NodeField -%>
- inspector << "<%= pointer %><%= field.name %>:\n"
- inspector << inspector.child_node(<%= field.name %>, "<%= preadd %>")
- <%- when Prism::OptionalNodeField -%>
- if (<%= field.name %> = self.<%= field.name %>).nil?
- inspector << "<%= pointer %><%= field.name %>: ∅\n"
- else
- inspector << "<%= pointer %><%= field.name %>:\n"
- inspector << <%= field.name %>.inspect(inspector.child_inspector("<%= preadd %>")).delete_prefix(inspector.prefix)
- end
- <%- when Prism::ConstantField, Prism::StringField, Prism::UInt8Field, Prism::UInt32Field -%>
- inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n"
- <%- when Prism::OptionalConstantField -%>
- if (<%= field.name %> = self.<%= field.name %>).nil?
- inspector << "<%= pointer %><%= field.name %>: ∅\n"
- else
- inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n"
- end
- <%- when Prism::FlagsField -%>
- <%- flag = flags.find { |flag| flag.name == field.kind }.tap { |flag| raise unless flag } -%>
- flags = [<%= flag.values.map { |value| "(\"#{value.name.downcase}\" if #{value.name.downcase}?)" }.join(", ") %>].compact
- inspector << "<%= pointer %><%= field.name %>: #{flags.empty? ? "∅" : flags.join(", ")}\n"
- <%- when Prism::LocationField, Prism::OptionalLocationField -%>
- inspector << "<%= pointer %><%= field.name %>: #{inspector.location(<%= field.name %>)}\n"
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- <%- end -%>
- inspector.to_str
- end
-
- # Sometimes you want to check an instance of a node against a list of
- # classes to see what kind of behavior to perform. Usually this is done by
- # calling `[cls1, cls2].include?(node.class)` or putting the node into a
- # case statement and doing `case node; when cls1; when cls2; end`. Both of
- # these approaches are relatively slow because of the constant lookups,
- # method calls, and/or array allocations.
- #
- # Instead, you can call #type, which will return to you a symbol that you
- # can use for comparison. This is faster than the other approaches because
- # it uses a single integer comparison, but also because if you're on CRuby
- # you can take advantage of the fact that case statements with all symbol
- # keys will use a jump table.
- #
- # def type: () -> Symbol
- def type
- :<%= node.human %>
- end
-
- # Similar to #type, this method returns a symbol that you can use for
- # splitting on the type of the node without having to do a long === chain.
- # Note that like #type, it will still be slower than using == for a single
- # class, but should be faster in a case statement or an array comparison.
- #
- # def self.type: () -> Symbol
- def self.type
- :<%= node.human %>
- end
- end
- <%- end -%>
- <%- flags.each_with_index do |flag, flag_index| -%>
-
- # <%= flag.comment %>
- module <%= flag.name %>
- <%- flag.values.each_with_index do |value, index| -%>
- # <%= value.comment %>
- <%= value.name %> = 1 << <%= index %>
-<%= "\n" if value != flag.values.last -%>
- <%- end -%>
- end
- <%- end -%>
-end
diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb
deleted file mode 100644
index 7cbbfb63c5..0000000000
--- a/prism/templates/lib/prism/serialize.rb.erb
+++ /dev/null
@@ -1,310 +0,0 @@
-require "stringio"
-
-# Polyfill for String#unpack1 with the offset parameter.
-if String.instance_method(:unpack1).parameters.none? { |_, name| name == :offset }
- String.prepend(
- Module.new {
- def unpack1(format, offset: 0) # :nodoc:
- offset == 0 ? super(format) : self[offset..].unpack1(format)
- end
- }
- )
-end
-
-module Prism
- # A module responsible for deserializing parse results.
- module Serialize
- # The major version of prism that we are expecting to find in the serialized
- # strings.
- MAJOR_VERSION = 0
-
- # The minor version of prism that we are expecting to find in the serialized
- # strings.
- MINOR_VERSION = 19
-
- # The patch version of prism that we are expecting to find in the serialized
- # strings.
- PATCH_VERSION = 0
-
- # Deserialize the AST represented by the given string into a parse result.
- def self.load(input, serialized)
- input = input.dup
- source = Source.new(input)
- loader = Loader.new(source, serialized)
- result = loader.load_result
-
- input.force_encoding(loader.encoding)
- result
- end
-
- # Deserialize the tokens represented by the given string into a parse
- # result.
- def self.load_tokens(source, serialized)
- Loader.new(source, serialized).load_tokens_result
- end
-
- class Loader # :nodoc:
- attr_reader :encoding, :input, :serialized, :io
- attr_reader :constant_pool_offset, :constant_pool, :source
- attr_reader :start_line
-
- def initialize(source, serialized)
- @encoding = Encoding::UTF_8
-
- @input = source.source.dup
- @serialized = serialized
- @io = StringIO.new(serialized)
- @io.set_encoding(Encoding::BINARY)
-
- @constant_pool_offset = nil
- @constant_pool = nil
-
- @source = source
- define_load_node_lambdas unless RUBY_ENGINE == "ruby"
- end
-
- def load_header
- raise "Invalid serialization" if io.read(5) != "PRISM"
- raise "Invalid serialization" if io.read(3).unpack("C3") != [MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION]
- only_semantic_fields = io.read(1).unpack1("C")
- unless only_semantic_fields == 0
- raise "Invalid serialization (location fields must be included but are not)"
- end
- end
-
- def load_encoding
- @encoding = Encoding.find(io.read(load_varuint))
- @input = input.force_encoding(@encoding).freeze
- @encoding
- end
-
- def load_start_line
- source.start_line = load_varsint
- end
-
- def load_comments
- load_varuint.times.map do
- case load_varuint
- when 0 then InlineComment.new(load_location)
- when 1 then EmbDocComment.new(load_location)
- when 2 then DATAComment.new(load_location)
- end
- end
- end
-
- def load_metadata
- comments = load_comments
- magic_comments = load_varuint.times.map { MagicComment.new(load_location, load_location) }
- data_loc = load_optional_location
- errors = load_varuint.times.map { ParseError.new(load_embedded_string, load_location) }
- warnings = load_varuint.times.map { ParseWarning.new(load_embedded_string, load_location) }
- [comments, magic_comments, data_loc, errors, warnings]
- end
-
- def load_tokens
- tokens = []
- while type = TOKEN_TYPES.fetch(load_varuint)
- start = load_varuint
- length = load_varuint
- lex_state = load_varuint
- location = Location.new(@source, start, length)
- tokens << [Prism::Token.new(type, location.slice, location), lex_state]
- end
-
- tokens
- end
-
- def load_tokens_result
- tokens = load_tokens
- encoding = load_encoding
- load_start_line
- comments, magic_comments, data_loc, errors, warnings = load_metadata
- tokens.each { |token,| token.value.force_encoding(encoding) }
-
- raise "Expected to consume all bytes while deserializing" unless @io.eof?
- Prism::ParseResult.new(tokens, comments, magic_comments, data_loc, errors, warnings, @source)
- end
-
- def load_nodes
- load_header
- load_encoding
- load_start_line
-
- comments, magic_comments, data_loc, errors, warnings = load_metadata
-
- @constant_pool_offset = io.read(4).unpack1("L")
- @constant_pool = Array.new(load_varuint, nil)
-
- [load_node, comments, magic_comments, data_loc, errors, warnings]
- end
-
- def load_result
- node, comments, magic_comments, data_loc, errors, warnings = load_nodes
- Prism::ParseResult.new(node, comments, magic_comments, data_loc, errors, warnings, @source)
- end
-
- private
-
- # variable-length integer using https://en.wikipedia.org/wiki/LEB128
- # This is also what protobuf uses: https://protobuf.dev/programming-guides/encoding/#varints
- def load_varuint
- n = io.getbyte
- if n < 128
- n
- else
- n -= 128
- shift = 0
- while (b = io.getbyte) >= 128
- n += (b - 128) << (shift += 7)
- end
- n + (b << (shift + 7))
- end
- end
-
- def load_varsint
- n = load_varuint
- (n >> 1) ^ (-(n & 1))
- end
-
- def load_serialized_length
- io.read(4).unpack1("L")
- end
-
- def load_optional_node
- if io.getbyte != 0
- io.pos -= 1
- load_node
- end
- end
-
- def load_embedded_string
- io.read(load_varuint).force_encoding(encoding)
- end
-
- def load_string
- type = io.getbyte
- case type
- when 1
- input.byteslice(load_varuint, load_varuint).force_encoding(encoding)
- when 2
- load_embedded_string
- else
- raise "Unknown serialized string type: #{type}"
- end
- end
-
- def load_location
- Location.new(source, load_varuint, load_varuint)
- end
-
- def load_optional_location
- load_location if io.getbyte != 0
- end
-
- def load_constant(index)
- constant = constant_pool[index]
-
- unless constant
- offset = constant_pool_offset + index * 8
- start = serialized.unpack1("L", offset: offset)
- length = serialized.unpack1("L", offset: offset + 4)
-
- constant =
- if start.nobits?(1 << 31)
- input.byteslice(start, length).to_sym
- else
- serialized.byteslice(start & ((1 << 31) - 1), length).to_sym
- end
-
- constant_pool[index] = constant
- end
-
- constant
- end
-
- def load_required_constant
- load_constant(load_varuint - 1)
- end
-
- def load_optional_constant
- index = load_varuint
- load_constant(index - 1) if index != 0
- end
-
- if RUBY_ENGINE == 'ruby'
- def load_node
- type = io.getbyte
- location = load_location
-
- case type
- <%- nodes.each_with_index do |node, index| -%>
- when <%= index + 1 %> then
- <%- if node.needs_serialized_length? -%>
- load_serialized_length
- <%- end -%>
- <%= node.name %>.new(<%= (node.fields.map { |field|
- case field
- when Prism::NodeField then "load_node"
- when Prism::OptionalNodeField then "load_optional_node"
- when Prism::StringField then "load_string"
- when Prism::NodeListField then "Array.new(load_varuint) { load_node }"
- when Prism::ConstantField then "load_required_constant"
- when Prism::OptionalConstantField then "load_optional_constant"
- when Prism::ConstantListField then "Array.new(load_varuint) { load_required_constant }"
- when Prism::LocationField then "load_location"
- when Prism::OptionalLocationField then "load_optional_location"
- when Prism::UInt8Field then "io.getbyte"
- when Prism::UInt32Field, Prism::FlagsField then "load_varuint"
- else raise
- end
- } + ["location"]).join(", ") -%>)
- <%- end -%>
- end
- end
- else
- def load_node
- type = io.getbyte
- @load_node_lambdas[type].call
- end
-
- def define_load_node_lambdas
- @load_node_lambdas = [
- nil,
- <%- nodes.each do |node| -%>
- -> {
- location = load_location
- <%- if node.needs_serialized_length? -%>
- load_serialized_length
- <%- end -%>
- <%= node.name %>.new(<%= (node.fields.map { |field|
- case field
- when Prism::NodeField then "load_node"
- when Prism::OptionalNodeField then "load_optional_node"
- when Prism::StringField then "load_string"
- when Prism::NodeListField then "Array.new(load_varuint) { load_node }"
- when Prism::ConstantField then "load_required_constant"
- when Prism::OptionalConstantField then "load_optional_constant"
- when Prism::ConstantListField then "Array.new(load_varuint) { load_required_constant }"
- when Prism::LocationField then "load_location"
- when Prism::OptionalLocationField then "load_optional_location"
- when Prism::UInt8Field then "io.getbyte"
- when Prism::UInt32Field, Prism::FlagsField then "load_varuint"
- else raise
- end
- } + ["location"]).join(", ") -%>)
- },
- <%- end -%>
- ]
- end
- end
- end
-
- # The token types that can be indexed by their enum values.
- TOKEN_TYPES = [
- nil,
- <%- tokens.each do |token| -%>
- <%= token.name.to_sym.inspect %>,
- <%- end -%>
- ]
- end
-end
diff --git a/prism/templates/lib/prism/visitor.rb.erb b/prism/templates/lib/prism/visitor.rb.erb
deleted file mode 100644
index 04156cc7a9..0000000000
--- a/prism/templates/lib/prism/visitor.rb.erb
+++ /dev/null
@@ -1,50 +0,0 @@
-module Prism
- # A class that knows how to walk down the tree. None of the individual visit
- # methods are implemented on this visitor, so it forces the consumer to
- # implement each one that they need. For a default implementation that
- # continues walking the tree, see the Visitor class.
- class BasicVisitor
- # Calls `accept` on the given node if it is not `nil`, which in turn should
- # call back into this visitor by calling the appropriate `visit_*` method.
- def visit(node)
- node&.accept(self)
- end
-
- # Visits each node in `nodes` by calling `accept` on each one.
- def visit_all(nodes)
- nodes.each { |node| node&.accept(self) }
- end
-
- # Visits the child nodes of `node` by calling `accept` on each one.
- def visit_child_nodes(node)
- node.compact_child_nodes.each { |node| node.accept(self) }
- end
- end
-
- # A visitor is a class that provides a default implementation for every accept
- # method defined on the nodes. This means it can walk a tree without the
- # caller needing to define any special handling. This allows you to handle a
- # subset of the tree, while still walking the whole tree.
- #
- # For example, to find all of the method calls that call the `foo` method, you
- # could write:
- #
- # class FooCalls < Prism::Visitor
- # def visit_call_node(node)
- # if node.name == "foo"
- # # Do something with the node
- # end
- #
- # # Call super so that the visitor continues walking the tree
- # super
- # end
- # end
- #
- class Visitor < BasicVisitor
- <%- nodes.each_with_index do |node, index| -%>
-<%= "\n" if index != 0 -%>
- # Visit a <%= node.name %> node
- alias visit_<%= node.human %> visit_child_nodes
- <%- end -%>
- end
-end
diff --git a/prism/templates/src/node.c.erb b/prism/templates/src/node.c.erb
deleted file mode 100644
index 0552767f4d..0000000000
--- a/prism/templates/src/node.c.erb
+++ /dev/null
@@ -1,162 +0,0 @@
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
-#include "prism/node.h"
-
-static void
-pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize);
-
-/**
- * Calculate the size of the node list in bytes.
- */
-static size_t
-pm_node_list_memsize(pm_node_list_t *node_list, pm_memsize_t *memsize) {
- size_t size = sizeof(pm_node_list_t) + (node_list->capacity * sizeof(pm_node_t *));
- for (size_t index = 0; index < node_list->size; index++) {
- pm_node_memsize_node(node_list->nodes[index], memsize);
- }
- return size;
-}
-
-/**
- * Append a new node onto the end of the node list.
- */
-void
-pm_node_list_append(pm_node_list_t *list, pm_node_t *node) {
- if (list->size == list->capacity) {
- list->capacity = list->capacity == 0 ? 4 : list->capacity * 2;
- list->nodes = (pm_node_t **) realloc(list->nodes, sizeof(pm_node_t *) * list->capacity);
- }
- list->nodes[list->size++] = node;
-}
-
-PRISM_EXPORTED_FUNCTION void
-pm_node_destroy(pm_parser_t *parser, pm_node_t *node);
-
-/**
- * Deallocate the inner memory of a list of nodes. The parser argument is not
- * used, but is here for the future possibility of pre-allocating memory pools.
- */
-static void
-pm_node_list_free(pm_parser_t *parser, pm_node_list_t *list) {
- if (list->capacity > 0) {
- for (size_t index = 0; index < list->size; index++) {
- pm_node_destroy(parser, list->nodes[index]);
- }
- free(list->nodes);
- }
-}
-
-/**
- * Deallocate the space for a pm_node_t. Similarly to pm_node_alloc, we're not
- * using the parser argument, but it's there to allow for the future possibility
- * of pre-allocating larger memory pools.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
- switch (PM_NODE_TYPE(node)) {
- <%- nodes.each do |node| -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- case <%= node.type %>: {
- <%- if node.fields.any? { |field| ![Prism::LocationField, Prism::OptionalLocationField, Prism::UInt8Field, Prism::UInt32Field, Prism::FlagsField, Prism::ConstantField, Prism::OptionalConstantField].include?(field.class) } -%>
- pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
- <%- end -%>
- <%- node.fields.each do |field| -%>
- <%- case field -%>
- <%- when Prism::LocationField, Prism::OptionalLocationField, Prism::UInt8Field, Prism::UInt32Field, Prism::FlagsField, Prism::ConstantField, Prism::OptionalConstantField -%>
- <%- when Prism::NodeField -%>
- pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
- <%- when Prism::OptionalNodeField -%>
- if (cast-><%= field.name %> != NULL) {
- pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
- }
- <%- when Prism::StringField -%>
- pm_string_free(&cast-><%= field.name %>);
- <%- when Prism::NodeListField -%>
- pm_node_list_free(parser, &cast-><%= field.name %>);
- <%- when Prism::ConstantListField -%>
- pm_constant_id_list_free(&cast-><%= field.name %>);
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- <%- end -%>
- break;
- }
- <%- end -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- default:
- assert(false && "unreachable");
- break;
- }
- free(node);
-}
-
-static void
-pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
- memsize->node_count++;
-
- switch (PM_NODE_TYPE(node)) {
- // We do not calculate memsize of a ScopeNode
- // as it should never be generated
- case PM_SCOPE_NODE:
- return;
- <%- nodes.each do |node| -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- case <%= node.type %>: {
- pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
- memsize->memsize += sizeof(*cast);
- <%- if node.fields.any? { |f| f.is_a?(Prism::NodeListField) } -%>
- // Node lists will add in their own sizes below.
- memsize->memsize -= sizeof(pm_node_list_t) * <%= node.fields.count { |f| f.is_a?(Prism::NodeListField) } %>;
- <%- end -%>
- <%- if node.fields.any? { |f| f.is_a?(Prism::ConstantListField) } -%>
- // Constant id lists will add in their own sizes below.
- memsize->memsize -= sizeof(pm_constant_id_list_t) * <%= node.fields.count { |f| f.is_a?(Prism::ConstantListField) } %>;
- <%- end -%>
- <%- node.fields.each do |field| -%>
- <%- case field -%>
- <%- when Prism::ConstantField, Prism::OptionalConstantField, Prism::UInt8Field, Prism::UInt32Field, Prism::FlagsField, Prism::LocationField, Prism::OptionalLocationField -%>
- <%- when Prism::NodeField -%>
- pm_node_memsize_node((pm_node_t *)cast-><%= field.name %>, memsize);
- <%- when Prism::OptionalNodeField -%>
- if (cast-><%= field.name %> != NULL) {
- pm_node_memsize_node((pm_node_t *)cast-><%= field.name %>, memsize);
- }
- <%- when Prism::StringField -%>
- memsize->memsize += pm_string_memsize(&cast-><%= field.name %>);
- <%- when Prism::NodeListField -%>
- memsize->memsize += pm_node_list_memsize(&cast-><%= field.name %>, memsize);
- <%- when Prism::ConstantListField -%>
- memsize->memsize += pm_constant_id_list_memsize(&cast-><%= field.name %>);
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- <%- end -%>
- break;
- }
- <%- end -%>
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
- }
-}
-
-/**
- * Calculates the memory footprint of a given node.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_node_memsize(pm_node_t *node, pm_memsize_t *memsize) {
- *memsize = (pm_memsize_t) { .memsize = 0, .node_count = 0 };
- pm_node_memsize_node(node, memsize);
-}
-
-/**
- * Returns a string representation of the given node type.
- */
-PRISM_EXPORTED_FUNCTION const char *
-pm_node_type_to_str(pm_node_type_t node_type)
-{
- switch (node_type) {
-<%- nodes.each do |node| -%>
- case <%= node.type %>:
- return "<%= node.type %>";
-<%- end -%>
- }
- return "";
-}
diff --git a/prism/templates/src/prettyprint.c.erb b/prism/templates/src/prettyprint.c.erb
deleted file mode 100644
index 61831ce59b..0000000000
--- a/prism/templates/src/prettyprint.c.erb
+++ /dev/null
@@ -1,189 +0,0 @@
-<%# encoding: ASCII -%>
-#include "prism/prettyprint.h"
-
-static void
-prettyprint_source(pm_buffer_t *output_buffer, const uint8_t *source, size_t length) {
- for (size_t index = 0; index < length; index++) {
- const uint8_t byte = source[index];
-
- if ((byte <= 0x06) || (byte >= 0x0E && byte <= 0x1F) || (byte >= 0x7F)) {
- pm_buffer_append_format(output_buffer, "\\x%02X", byte);
- } else {
- switch (byte) {
- case '\a': pm_buffer_append_string(output_buffer, "\\a", 2); break;
- case '\b': pm_buffer_append_string(output_buffer, "\\b", 2); break;
- case '\t': pm_buffer_append_string(output_buffer, "\\t", 2); break;
- case '\n': pm_buffer_append_string(output_buffer, "\\n", 2); break;
- case '\v': pm_buffer_append_string(output_buffer, "\\v", 2); break;
- case '\f': pm_buffer_append_string(output_buffer, "\\f", 2); break;
- case '\r': pm_buffer_append_string(output_buffer, "\\r", 2); break;
- case '"': pm_buffer_append_string(output_buffer, "\\\"", 2); break;
- case '#': {
- if (index + 1 < length) {
- const uint8_t next_byte = source[index + 1];
- if (next_byte == '{' || next_byte == '@' || next_byte == '$') {
- pm_buffer_append_byte(output_buffer, '\\');
- }
- }
-
- pm_buffer_append_byte(output_buffer, '#');
- break;
- }
- case '\\': pm_buffer_append_string(output_buffer, "\\\\", 2); break;
- default: pm_buffer_append_byte(output_buffer, byte); break;
- }
- }
- }
-}
-
-static inline void
-prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) {
- pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start);
- pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end);
- pm_buffer_append_format(output_buffer, "(%lu,%lu)-(%lu,%lu)", (unsigned long) (start.line + 1), (unsigned long) start.column, (unsigned long) (end.line + 1), (unsigned long) end.column);
-}
-
-static inline void
-prettyprint_constant(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_constant_id_t constant_id) {
- pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
- pm_buffer_append_format(output_buffer, ":%.*s", (int) constant->length, constant->start);
-}
-
-static void
-prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node, pm_buffer_t *prefix_buffer) {
- switch (PM_NODE_TYPE(node)) {
- case PM_SCOPE_NODE:
- // We do not need to print a ScopeNode as it's not part of the AST.
- return;
- <%- nodes.each do |node| -%>
- case <%= node.type %>: {
- <%- if node.fields.any? -%>
- pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
- <%- end -%>
- pm_buffer_append_string(output_buffer, "@ <%= node.name %> (location: ", <%= node.name.length + 14 %>);
- prettyprint_location(output_buffer, parser, &node->location);
- pm_buffer_append_string(output_buffer, ")\n", 2);
- <%- node.fields.each_with_index do |field, index| -%>
- <%- pointer, preadd, preadd_bytesize = index == node.fields.length - 1 ? ["\\xe2\\x94\\x94\\xe2\\x94\\x80\\xe2\\x94\\x80 ", " ", 4] : ["\\xe2\\x94\\x9c\\xe2\\x94\\x80\\xe2\\x94\\x80 ", "\\xe2\\x94\\x82 ", 6] -%>
-
- // <%= field.name %>
- {
- pm_buffer_concat(output_buffer, prefix_buffer);
- pm_buffer_append_string(output_buffer, "<%= pointer %><%= field.name %>:", <%= 10 + field.name.length + 1 %>);
- <%- case field -%>
- <%- when Prism::NodeField -%>
- pm_buffer_append_byte(output_buffer, '\n');
-
- size_t prefix_length = prefix_buffer->length;
- pm_buffer_append_string(prefix_buffer, "<%= preadd %>", <%= preadd_bytesize %>);
- pm_buffer_concat(output_buffer, prefix_buffer);
- prettyprint_node(output_buffer, parser, (pm_node_t *) cast-><%= field.name %>, prefix_buffer);
- prefix_buffer->length = prefix_length;
- <%- when Prism::OptionalNodeField -%>
- if (cast-><%= field.name %> == NULL) {
- pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
- } else {
- pm_buffer_append_byte(output_buffer, '\n');
-
- size_t prefix_length = prefix_buffer->length;
- pm_buffer_append_string(prefix_buffer, "<%= preadd %>", <%= preadd_bytesize %>);
- pm_buffer_concat(output_buffer, prefix_buffer);
- prettyprint_node(output_buffer, parser, (pm_node_t *) cast-><%= field.name %>, prefix_buffer);
- prefix_buffer->length = prefix_length;
- }
- <%- when Prism::StringField -%>
- pm_buffer_append_string(output_buffer, " \"", 2);
- prettyprint_source(output_buffer, pm_string_source(&cast-><%= field.name %>), pm_string_length(&cast-><%= field.name %>));
- pm_buffer_append_string(output_buffer, "\"\n", 2);
- <%- when Prism::NodeListField -%>
- pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast-><%= field.name %>.size));
-
- size_t last_index = cast-><%= field.name %>.size;
- for (uint32_t index = 0; index < last_index; index++) {
- size_t prefix_length = prefix_buffer->length;
- pm_buffer_append_string(prefix_buffer, "<%= preadd %>", <%= preadd_bytesize %>);
- pm_buffer_concat(output_buffer, prefix_buffer);
-
- if (index == last_index - 1) {
- pm_buffer_append_string(output_buffer, "\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ", 10);
- pm_buffer_append_string(prefix_buffer, " ", 4);
- } else {
- pm_buffer_append_string(output_buffer, "\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ", 10);
- pm_buffer_append_string(prefix_buffer, "\xe2\x94\x82 ", 6);
- }
-
- prettyprint_node(output_buffer, parser, (pm_node_t *) cast-><%= field.name %>.nodes[index], prefix_buffer);
- prefix_buffer->length = prefix_length;
- }
- <%- when Prism::ConstantField -%>
- pm_buffer_append_byte(output_buffer, ' ');
- prettyprint_constant(output_buffer, parser, cast-><%= field.name %>);
- pm_buffer_append_byte(output_buffer, '\n');
- <%- when Prism::OptionalConstantField -%>
- if (cast-><%= field.name %> == 0) {
- pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
- } else {
- pm_buffer_append_byte(output_buffer, ' ');
- prettyprint_constant(output_buffer, parser, cast-><%= field.name %>);
- pm_buffer_append_byte(output_buffer, '\n');
- }
- <%- when Prism::ConstantListField -%>
- pm_buffer_append_string(output_buffer, " [", 2);
- for (uint32_t index = 0; index < cast-><%= field.name %>.size; index++) {
- if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
- prettyprint_constant(output_buffer, parser, cast-><%= field.name %>.ids[index]);
- }
- pm_buffer_append_string(output_buffer, "]\n", 2);
- <%- when Prism::LocationField -%>
- pm_location_t *location = &cast-><%= field.name %>;
- pm_buffer_append_byte(output_buffer, ' ');
- prettyprint_location(output_buffer, parser, location);
- pm_buffer_append_string(output_buffer, " = \"", 4);
- prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
- pm_buffer_append_string(output_buffer, "\"\n", 2);
- <%- when Prism::OptionalLocationField -%>
- pm_location_t *location = &cast-><%= field.name %>;
- if (location->start == NULL) {
- pm_buffer_append_string(output_buffer, " \xe2\x88\x85\n", 5);
- } else {
- pm_buffer_append_byte(output_buffer, ' ');
- prettyprint_location(output_buffer, parser, location);
- pm_buffer_append_string(output_buffer, " = \"", 4);
- prettyprint_source(output_buffer, location->start, (size_t) (location->end - location->start));
- pm_buffer_append_string(output_buffer, "\"\n", 2);
- }
- <%- when Prism::UInt8Field, Prism::UInt32Field -%>
- pm_buffer_append_format(output_buffer, " %d\n", cast-><%= field.name %>);
- <%- when Prism::FlagsField -%>
- bool found = false;
- <%- found = flags.find { |flag| flag.name == field.kind }.tap { |found| raise "Expected to find #{field.kind}" unless found } -%>
- <%- found.values.each do |value| -%>
- if (cast->base.<%= field.name %> & PM_<%= found.human.upcase %>_<%= value.name %>) {
- if (found) pm_buffer_append_byte(output_buffer, ',');
- pm_buffer_append_string(output_buffer, " <%= value.name.downcase %>", <%= value.name.bytesize + 1 %>);
- found = true;
- }
- <%- end -%>
- if (!found) pm_buffer_append_string(output_buffer, " \xe2\x88\x85", 4);
- pm_buffer_append_byte(output_buffer, '\n');
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- }
- <%- end -%>
-
- break;
- }
- <%- end -%>
- }
-}
-
-/**
- * Pretty-prints the AST represented by the given node to the given buffer.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) {
- pm_buffer_t prefix_buffer = { 0 };
- prettyprint_node(output_buffer, parser, node, &prefix_buffer);
- pm_buffer_free(&prefix_buffer);
-}
diff --git a/prism/templates/src/serialize.c.erb b/prism/templates/src/serialize.c.erb
deleted file mode 100644
index e9cdd1e82c..0000000000
--- a/prism/templates/src/serialize.c.erb
+++ /dev/null
@@ -1,380 +0,0 @@
-#include "prism.h"
-
-#include <stdio.h>
-
-static inline uint32_t
-pm_ptrdifft_to_u32(ptrdiff_t value) {
- assert(value >= 0 && ((unsigned long) value) < UINT32_MAX);
- return (uint32_t) value;
-}
-
-static inline uint32_t
-pm_sizet_to_u32(size_t value) {
- assert(value < UINT32_MAX);
- return (uint32_t) value;
-}
-
-static void
-pm_serialize_location(const pm_parser_t *parser, const pm_location_t *location, pm_buffer_t *buffer) {
- assert(location->start);
- assert(location->end);
- assert(location->start <= location->end);
-
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->start - parser->start));
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->end - location->start));
-}
-
-static void
-pm_serialize_string(pm_parser_t *parser, pm_string_t *string, pm_buffer_t *buffer) {
- switch (string->type) {
- case PM_STRING_SHARED: {
- pm_buffer_append_byte(buffer, 1);
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(pm_string_source(string) - parser->start));
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_string_length(string)));
- break;
- }
- case PM_STRING_OWNED:
- case PM_STRING_CONSTANT: {
- uint32_t length = pm_sizet_to_u32(pm_string_length(string));
- pm_buffer_append_byte(buffer, 2);
- pm_buffer_append_varuint(buffer, length);
- pm_buffer_append_bytes(buffer, pm_string_source(string), length);
- break;
- }
- case PM_STRING_MAPPED:
- assert(false && "Cannot serialize mapped strings.");
- break;
- }
-}
-
-static void
-pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
- pm_buffer_append_byte(buffer, (uint8_t) PM_NODE_TYPE(node));
-
- size_t offset = buffer->length;
-
- pm_serialize_location(parser, &node->location, buffer);
-
- switch (PM_NODE_TYPE(node)) {
- // We do not need to serialize a ScopeNode ever as
- // it is not part of the AST
- case PM_SCOPE_NODE:
- return;
- <%- nodes.each do |node| -%>
- case <%= node.type %>: {
- <%- if node.needs_serialized_length? -%>
- // serialize length
- // encoding of location u32s make us need to save this offset.
- size_t length_offset = buffer->length;
- pm_buffer_append_string(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */
- <%- end -%>
- <%- node.fields.each do |field| -%>
- <%- case field -%>
- <%- when Prism::NodeField -%>
- pm_serialize_node(parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
- <%- when Prism::OptionalNodeField -%>
- if (((pm_<%= node.human %>_t *)node)-><%= field.name %> == NULL) {
- pm_buffer_append_byte(buffer, 0);
- } else {
- pm_serialize_node(parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
- }
- <%- when Prism::StringField -%>
- pm_serialize_string(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
- <%- when Prism::NodeListField -%>
- uint32_t <%= field.name %>_size = pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.size);
- pm_buffer_append_varuint(buffer, <%= field.name %>_size);
- for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
- pm_serialize_node(parser, (pm_node_t *) ((pm_<%= node.human %>_t *)node)-><%= field.name %>.nodes[index], buffer);
- }
- <%- when Prism::ConstantField, Prism::OptionalConstantField -%>
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>));
- <%- when Prism::ConstantListField -%>
- uint32_t <%= field.name %>_size = pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.size);
- pm_buffer_append_varuint(buffer, <%= field.name %>_size);
- for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.ids[index]));
- }
- <%- when Prism::LocationField -%>
- <%- if field.should_be_serialized? -%>
- pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
- <%- end -%>
- <%- when Prism::OptionalLocationField -%>
- <%- if field.should_be_serialized? -%>
- if (((pm_<%= node.human %>_t *)node)-><%= field.name %>.start == NULL) {
- pm_buffer_append_byte(buffer, 0);
- } else {
- pm_buffer_append_byte(buffer, 1);
- pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
- }
- <%- end -%>
- <%- when Prism::UInt8Field -%>
- pm_buffer_append_byte(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
- <%- when Prism::UInt32Field -%>
- pm_buffer_append_varuint(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
- <%- when Prism::FlagsField -%>
- pm_buffer_append_varuint(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
- <%- else -%>
- <%- raise -%>
- <%- end -%>
- <%- end -%>
- <%- if node.needs_serialized_length? -%>
- // serialize length
- uint32_t length = pm_sizet_to_u32(buffer->length - offset - sizeof(uint32_t));
- memcpy(buffer->value + length_offset, &length, sizeof(uint32_t));
- <%- end -%>
- break;
- }
- <%- end -%>
- }
-}
-
-static void
-pm_serialize_comment(pm_parser_t *parser, pm_comment_t *comment, pm_buffer_t *buffer) {
- // serialize type
- pm_buffer_append_byte(buffer, (uint8_t) comment->type);
-
- // serialize location
- pm_serialize_location(parser, &comment->location, buffer);
-}
-
-/**
- * Serialize the given list of comments to the given buffer.
- */
-void
-pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
-
- pm_comment_t *comment;
- for (comment = (pm_comment_t *) list->head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
- pm_serialize_comment(parser, comment, buffer);
- }
-}
-
-static void
-pm_serialize_magic_comment(pm_parser_t *parser, pm_magic_comment_t *magic_comment, pm_buffer_t *buffer) {
- // serialize key location
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->key_start - parser->start));
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->key_length));
-
- // serialize value location
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->value_start - parser->start));
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->value_length));
-}
-
-static void
-pm_serialize_magic_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
-
- pm_magic_comment_t *magic_comment;
- for (magic_comment = (pm_magic_comment_t *) list->head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
- pm_serialize_magic_comment(parser, magic_comment, buffer);
- }
-}
-
-static void
-pm_serialize_data_loc(const pm_parser_t *parser, pm_buffer_t *buffer) {
- if (parser->data_loc.end == NULL) {
- pm_buffer_append_byte(buffer, 0);
- } else {
- pm_buffer_append_byte(buffer, 1);
- pm_serialize_location(parser, &parser->data_loc, buffer);
- }
-}
-
-static void
-pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
- // serialize message
- size_t message_length = strlen(diagnostic->message);
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(message_length));
- pm_buffer_append_string(buffer, diagnostic->message, message_length);
-
- // serialize location
- pm_serialize_location(parser, &diagnostic->location, buffer);
-}
-
-static void
-pm_serialize_diagnostic_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
-
- pm_diagnostic_t *diagnostic;
- for (diagnostic = (pm_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) {
- pm_serialize_diagnostic(parser, diagnostic, buffer);
- }
-}
-
-/**
- * Serialize the name of the encoding to the buffer.
- */
-void
-pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer) {
- size_t encoding_length = strlen(encoding->name);
- pm_buffer_append_varuint(buffer, pm_sizet_to_u32(encoding_length));
- pm_buffer_append_string(buffer, encoding->name, encoding_length);
-}
-
-#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
-/**
- * Serialize the encoding, metadata, nodes, and constant pool.
- */
-void
-pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
- pm_serialize_encoding(parser->encoding, buffer);
- pm_buffer_append_varsint(buffer, parser->start_line);
-<%- unless Prism::SERIALIZE_ONLY_SEMANTICS_FIELDS -%>
- pm_serialize_comment_list(parser, &parser->comment_list, buffer);
-<%- end -%>
- pm_serialize_magic_comment_list(parser, &parser->magic_comment_list, buffer);
- pm_serialize_data_loc(parser, buffer);
- pm_serialize_diagnostic_list(parser, &parser->error_list, buffer);
- pm_serialize_diagnostic_list(parser, &parser->warning_list, buffer);
-
- // Here we're going to leave space for the offset of the constant pool in
- // the buffer.
- size_t offset = buffer->length;
- pm_buffer_append_zeroes(buffer, 4);
-
- // Next, encode the length of the constant pool.
- pm_buffer_append_varuint(buffer, parser->constant_pool.size);
-
- // Now we're going to serialize the content of the node.
- pm_serialize_node(parser, node, buffer);
-
- // Now we're going to serialize the offset of the constant pool back where
- // we left space for it.
- uint32_t length = pm_sizet_to_u32(buffer->length);
- memcpy(buffer->value + offset, &length, sizeof(uint32_t));
-
- // Now we're going to serialize the constant pool.
- offset = buffer->length;
- pm_buffer_append_zeroes(buffer, parser->constant_pool.size * 8);
-
- for (uint32_t index = 0; index < parser->constant_pool.capacity; index++) {
- pm_constant_pool_bucket_t *bucket = &parser->constant_pool.buckets[index];
-
- // If we find a constant at this index, serialize it at the correct
- // index in the buffer.
- if (bucket->id != 0) {
- pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
- size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
-
- if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED || bucket->type == PM_CONSTANT_POOL_BUCKET_CONSTANT) {
- // Since this is an owned or constant constant, we are going to
- // write its contents into the buffer after the constant pool.
- // So effectively in place of the source offset, we have a
- // buffer offset. We will add a leading 1 to indicate that this
- // is a buffer offset.
- uint32_t content_offset = pm_sizet_to_u32(buffer->length);
- uint32_t owned_mask = (uint32_t) (1 << 31);
-
- assert(content_offset < owned_mask);
- content_offset |= owned_mask;
-
- memcpy(buffer->value + buffer_offset, &content_offset, 4);
- pm_buffer_append_bytes(buffer, constant->start, constant->length);
- } else {
- // Since this is a shared constant, we are going to write its
- // source offset directly into the buffer.
- uint32_t source_offset = pm_ptrdifft_to_u32(constant->start - parser->start);
- memcpy(buffer->value + buffer_offset, &source_offset, 4);
- }
-
- // Now we can write the length of the constant into the buffer.
- uint32_t constant_length = pm_sizet_to_u32(constant->length);
- memcpy(buffer->value + buffer_offset + 4, &constant_length, 4);
- }
- }
-}
-
-static void
-serialize_token(void *data, pm_parser_t *parser, pm_token_t *token) {
- pm_buffer_t *buffer = (pm_buffer_t *) data;
-
- pm_buffer_append_varuint(buffer, token->type);
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->start - parser->start));
- pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->end - token->start));
- pm_buffer_append_varuint(buffer, parser->lex_state);
-}
-
-/**
- * Lex the given source and serialize to the given buffer.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
- pm_options_t options = { 0 };
- pm_options_read(&options, data);
-
- pm_parser_t parser;
- pm_parser_init(&parser, source, size, &options);
-
- pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
- .data = (void *) buffer,
- .callback = serialize_token,
- };
-
- parser.lex_callback = &lex_callback;
- pm_node_t *node = pm_parse(&parser);
-
- // Append 0 to mark end of tokens.
- pm_buffer_append_byte(buffer, 0);
-
- pm_serialize_encoding(parser.encoding, buffer);
- pm_buffer_append_varsint(buffer, parser.start_line);
- pm_serialize_comment_list(&parser, &parser.comment_list, buffer);
- pm_serialize_magic_comment_list(&parser, &parser.magic_comment_list, buffer);
- pm_serialize_data_loc(&parser, buffer);
- pm_serialize_diagnostic_list(&parser, &parser.error_list, buffer);
- pm_serialize_diagnostic_list(&parser, &parser.warning_list, buffer);
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
- pm_options_free(&options);
-}
-
-/**
- * Parse and serialize both the AST and the tokens represented by the given
- * source to the given buffer.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
- pm_options_t options = { 0 };
- pm_options_read(&options, data);
-
- pm_parser_t parser;
- pm_parser_init(&parser, source, size, &options);
-
- pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
- .data = (void *) buffer,
- .callback = serialize_token,
- };
-
- parser.lex_callback = &lex_callback;
- pm_node_t *node = pm_parse(&parser);
-
- pm_buffer_append_byte(buffer, 0);
- pm_serialize(&parser, node, buffer);
-
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
- pm_options_free(&options);
-}
-
-/**
- * Parse the source and return true if it parses without errors or warnings.
- */
-PRISM_EXPORTED_FUNCTION bool
-pm_parse_success_p(const uint8_t *source, size_t size, const char *data) {
- pm_options_t options = { 0 };
- pm_options_read(&options, data);
-
- pm_parser_t parser;
- pm_parser_init(&parser, source, size, &options);
-
- pm_node_t *node = pm_parse(&parser);
- pm_node_destroy(&parser, node);
-
- bool result = parser.error_list.size == 0 && parser.warning_list.size == 0;
- pm_parser_free(&parser);
- pm_options_free(&options);
-
- return result;
-}
diff --git a/prism/templates/src/token_type.c.erb b/prism/templates/src/token_type.c.erb
deleted file mode 100644
index d3c1c3f1b8..0000000000
--- a/prism/templates/src/token_type.c.erb
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <string.h>
-
-#include "prism/ast.h"
-
-/**
- * Returns a string representation of the given token type.
- */
-PRISM_EXPORTED_FUNCTION const char *
-pm_token_type_to_str(pm_token_type_t token_type)
-{
- switch (token_type) {
-<%- tokens.each do |token| -%>
- case PM_TOKEN_<%= token.name %>:
- return "<%= token.name %>";
-<%- end -%>
- case PM_TOKEN_MAXIMUM:
- return "MAXIMUM";
- }
- return "\0";
-}
diff --git a/prism/templates/template.rb b/prism/templates/template.rb
deleted file mode 100755
index 8cbcf27d79..0000000000
--- a/prism/templates/template.rb
+++ /dev/null
@@ -1,472 +0,0 @@
-#!/usr/bin/env ruby
-
-require "erb"
-require "fileutils"
-require "yaml"
-
-module Prism
- SERIALIZE_ONLY_SEMANTICS_FIELDS = ENV.fetch("PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS", false)
-
- JAVA_BACKEND = ENV["PRISM_JAVA_BACKEND"] || "truffleruby"
- JAVA_STRING_TYPE = JAVA_BACKEND == "jruby" ? "org.jruby.RubySymbol" : "String"
-
- # This represents a field on a node. It contains all of the necessary
- # information to template out the code for that field.
- class Field
- attr_reader :name, :options
-
- def initialize(name:, type:, **options)
- @name, @type, @options = name, type, options
- end
-
- def semantic_field?
- true
- end
-
- def should_be_serialized?
- SERIALIZE_ONLY_SEMANTICS_FIELDS ? semantic_field? : true
- end
- end
-
- # Some node fields can be specialized if they point to a specific kind of
- # node and not just a generic node.
- class NodeKindField < Field
- def c_type
- if options[:kind]
- "pm_#{options[:kind].gsub(/(?<=.)[A-Z]/, "_\\0").downcase}"
- else
- "pm_node"
- end
- end
-
- def ruby_type
- options[:kind] || "Node"
- end
-
- def java_type
- options[:kind] || "Node"
- end
-
- def java_cast
- if options[:kind]
- "(Nodes.#{options[:kind]}) "
- else
- ""
- end
- end
- end
-
- # This represents a field on a node that is itself a node. We pass them as
- # references and store them as references.
- class NodeField < NodeKindField
- def rbs_class
- ruby_type
- end
-
- def rbi_class
- "Prism::#{ruby_type}"
- end
- end
-
- # This represents a field on a node that is itself a node and can be
- # optionally null. We pass them as references and store them as references.
- class OptionalNodeField < NodeKindField
- def rbs_class
- "#{ruby_type}?"
- end
-
- def rbi_class
- "T.nilable(Prism::#{ruby_type})"
- end
- end
-
- # This represents a field on a node that is a list of nodes. We pass them as
- # references and store them directly on the struct.
- class NodeListField < Field
- def rbs_class
- "Array[Node]"
- end
-
- def rbi_class
- "T::Array[Prism::Node]"
- end
-
- def java_type
- "Node[]"
- end
- end
-
- # This represents a field on a node that is the ID of a string interned
- # through the parser's constant pool.
- class ConstantField < Field
- def rbs_class
- "Symbol"
- end
-
- def rbi_class
- "Symbol"
- end
-
- def java_type
- JAVA_STRING_TYPE
- end
- end
-
- # This represents a field on a node that is the ID of a string interned
- # through the parser's constant pool and can be optionally null.
- class OptionalConstantField < Field
- def rbs_class
- "Symbol?"
- end
-
- def rbi_class
- "T.nilable(Symbol)"
- end
-
- def java_type
- JAVA_STRING_TYPE
- end
- end
-
- # This represents a field on a node that is a list of IDs that are associated
- # with strings interned through the parser's constant pool.
- class ConstantListField < Field
- def rbs_class
- "Array[Symbol]"
- end
-
- def rbi_class
- "T::Array[Symbol]"
- end
-
- def java_type
- "#{JAVA_STRING_TYPE}[]"
- end
- end
-
- # This represents a field on a node that is a string.
- class StringField < Field
- def rbs_class
- "String"
- end
-
- def rbi_class
- "String"
- end
-
- def java_type
- "byte[]"
- end
- end
-
- # This represents a field on a node that is a location.
- class LocationField < Field
- def semantic_field?
- false
- end
-
- def rbs_class
- "Location"
- end
-
- def rbi_class
- "Prism::Location"
- end
-
- def java_type
- "Location"
- end
- end
-
- # This represents a field on a node that is a location that is optional.
- class OptionalLocationField < Field
- def semantic_field?
- false
- end
-
- def rbs_class
- "Location?"
- end
-
- def rbi_class
- "T.nilable(Prism::Location)"
- end
-
- def java_type
- "Location"
- end
- end
-
- # This represents an integer field.
- class UInt8Field < Field
- def rbs_class
- "Integer"
- end
-
- def rbi_class
- "Integer"
- end
-
- def java_type
- "int"
- end
- end
-
- # This represents an integer field.
- class UInt32Field < Field
- def rbs_class
- "Integer"
- end
-
- def rbi_class
- "Integer"
- end
-
- def java_type
- "int"
- end
- end
-
- # This represents a set of flags. It is very similar to the UInt32Field, but
- # can be directly embedded into the flags field on the struct and provides
- # convenient methods for checking if a flag is set.
- class FlagsField < Field
- def rbs_class
- "Integer"
- end
-
- def rbi_class
- "Integer"
- end
-
- def java_type
- "short"
- end
-
- def kind
- options.fetch(:kind)
- end
- end
-
- # This class represents a node in the tree, configured by the config.yml file in
- # YAML format. It contains information about the name of the node and the
- # various child nodes it contains.
- class NodeType
- attr_reader :name, :type, :human, :fields, :newline, :comment
-
- def initialize(config)
- @name = config.fetch("name")
-
- type = @name.gsub(/(?<=.)[A-Z]/, "_\\0")
- @type = "PM_#{type.upcase}"
- @human = type.downcase
-
- @fields =
- config.fetch("fields", []).map do |field|
- field_type_for(field.fetch("type")).new(**field.transform_keys(&:to_sym))
- end
-
- @newline = config.fetch("newline", true)
- @comment = config.fetch("comment")
- end
-
- def each_comment_line
- comment.each_line { |line| yield line.prepend(" ").rstrip }
- end
-
- def semantic_fields
- @semantic_fields ||= @fields.select(&:semantic_field?)
- end
-
- # Should emit serialized length of node so implementations can skip
- # the node to enable lazy parsing.
- def needs_serialized_length?
- name == "DefNode"
- end
-
- private
-
- def field_type_for(name)
- case name
- when "node" then NodeField
- when "node?" then OptionalNodeField
- when "node[]" then NodeListField
- when "string" then StringField
- when "constant" then ConstantField
- when "constant?" then OptionalConstantField
- when "constant[]" then ConstantListField
- when "location" then LocationField
- when "location?" then OptionalLocationField
- when "uint8" then UInt8Field
- when "uint32" then UInt32Field
- when "flags" then FlagsField
- else raise("Unknown field type: #{name.inspect}")
- end
- end
- end
-
- # This represents a token in the lexer.
- class Token
- attr_reader :name, :value, :comment
-
- def initialize(config)
- @name = config.fetch("name")
- @value = config["value"]
- @comment = config.fetch("comment")
- end
- end
-
- # Represents a set of flags that should be internally represented with an enum.
- class Flags
- # Represents an individual flag within a set of flags.
- class Flag
- attr_reader :name, :camelcase, :comment
-
- def initialize(config)
- @name = config.fetch("name")
- @camelcase = @name.split("_").map(&:capitalize).join
- @comment = config.fetch("comment")
- end
- end
-
- attr_reader :name, :human, :values, :comment
-
- def initialize(config)
- @name = config.fetch("name")
- @human = @name.gsub(/(?<=.)[A-Z]/, "_\\0").downcase
- @values = config.fetch("values").map { |flag| Flag.new(flag) }
- @comment = config.fetch("comment")
- end
- end
-
- class << self
- # This templates out a file using ERB with the given locals. The locals are
- # derived from the config.yml file.
- def template(name, write_to: nil)
- filepath = "templates/#{name}.erb"
- template = File.expand_path("../#{filepath}", __dir__)
-
- erb = read_template(template)
- extension = File.extname(filepath.gsub(".erb", ""))
-
- heading = case extension
- when ".rb"
- <<~HEADING
- # frozen_string_literal: true
- =begin
- This file is generated by the templates/template.rb script and should not be
- modified manually. See #{filepath}
- if you are looking to modify the template
- =end
-
- HEADING
- when ".rbs"
- <<~HEADING
- # This file is generated by the templates/template.rb script and should not be
- # modified manually. See #{filepath}
- # if you are looking to modify the template
-
- HEADING
- when ".rbi"
- <<~HEADING
- =begin
- This file is generated by the templates/template.rb script and should not be
- modified manually. See #{filepath}
- if you are looking to modify the template
- =end
- HEADING
- else
- <<~HEADING
- /******************************************************************************/
- /* This file is generated by the templates/template.rb script and should not */
- /* be modified manually. See */
- /* #{filepath + " " * (74 - filepath.size) } */
- /* if you are looking to modify the */
- /* template */
- /******************************************************************************/
- HEADING
- end
-
- write_to ||= File.expand_path("../#{name}", __dir__)
- contents = heading + erb.result_with_hash(locals)
-
- if (extension == ".c" || extension == ".h") && !contents.ascii_only?
- # Enforce that we only have ASCII characters here. This is necessary
- # for non-UTF-8 locales that only allow ASCII characters in C source
- # files.
- contents.each_line.with_index(1) do |line, line_number|
- raise "Non-ASCII character on line #{line_number} of #{write_to}" unless line.ascii_only?
- end
- end
-
- FileUtils.mkdir_p(File.dirname(write_to))
- File.write(write_to, contents)
- end
-
- private
-
- def read_template(filepath)
- template = File.read(filepath, encoding: Encoding::UTF_8)
- erb = erb(template)
- erb.filename = filepath
- erb
- end
-
- if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
- def erb(template)
- ERB.new(template, trim_mode: "-")
- end
- else
- def erb(template)
- ERB.new(template, nil, "-")
- end
- end
-
- def locals
- @locals ||=
- begin
- config = YAML.load_file(File.expand_path("../config.yml", __dir__))
-
- {
- nodes: config.fetch("nodes").map { |node| NodeType.new(node) }.sort_by(&:name),
- tokens: config.fetch("tokens").map { |token| Token.new(token) },
- flags: config.fetch("flags").map { |flags| Flags.new(flags) }
- }
- end
- end
- end
-
- TEMPLATES = [
- "ext/prism/api_node.c",
- "include/prism/ast.h",
- "javascript/src/deserialize.js",
- "javascript/src/nodes.js",
- "javascript/src/visitor.js",
- "java/org/prism/Loader.java",
- "java/org/prism/Nodes.java",
- "java/org/prism/AbstractNodeVisitor.java",
- "lib/prism/compiler.rb",
- "lib/prism/dispatcher.rb",
- "lib/prism/dot_visitor.rb",
- "lib/prism/dsl.rb",
- "lib/prism/mutation_compiler.rb",
- "lib/prism/node.rb",
- "lib/prism/serialize.rb",
- "lib/prism/visitor.rb",
- "src/node.c",
- "src/prettyprint.c",
- "src/serialize.c",
- "src/token_type.c",
- "rbi/prism.rbi",
- "sig/prism.rbs",
- ]
-end
-
-if __FILE__ == $0
- if ARGV.empty?
- Prism::TEMPLATES.each { |filepath| Prism.template(filepath) }
- else # ruby/ruby
- name, write_to = ARGV
- Prism.template(name, write_to: write_to)
- end
-end
diff --git a/prism/util/pm_buffer.c b/prism/util/pm_buffer.c
deleted file mode 100644
index 307b55d030..0000000000
--- a/prism/util/pm_buffer.c
+++ /dev/null
@@ -1,179 +0,0 @@
-#include "prism/util/pm_buffer.h"
-
-/**
- * Return the size of the pm_buffer_t struct.
- */
-size_t
-pm_buffer_sizeof(void) {
- return sizeof(pm_buffer_t);
-}
-
-/**
- * Initialize a pm_buffer_t with the given capacity.
- */
-bool
-pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
- buffer->length = 0;
- buffer->capacity = capacity;
-
- buffer->value = (char *) malloc(capacity);
- return buffer->value != NULL;
-}
-
-/**
- * Initialize a pm_buffer_t with its default values.
- */
-bool
-pm_buffer_init(pm_buffer_t *buffer) {
- return pm_buffer_init_capacity(buffer, 1024);
-}
-
-/**
- * Return the value of the buffer.
- */
-char *
-pm_buffer_value(pm_buffer_t *buffer) {
- return buffer->value;
-}
-
-/**
- * Return the length of the buffer.
- */
-size_t
-pm_buffer_length(pm_buffer_t *buffer) {
- return buffer->length;
-}
-
-/**
- * Append the given amount of space to the buffer.
- */
-static inline void
-pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
- size_t next_length = buffer->length + length;
-
- if (next_length > buffer->capacity) {
- if (buffer->capacity == 0) {
- buffer->capacity = 1;
- }
-
- while (next_length > buffer->capacity) {
- buffer->capacity *= 2;
- }
-
- buffer->value = realloc(buffer->value, buffer->capacity);
- }
-
- buffer->length = next_length;
-}
-
-/**
- * Append a generic pointer to memory to the buffer.
- */
-static inline void
-pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
- size_t cursor = buffer->length;
- pm_buffer_append_length(buffer, length);
- memcpy(buffer->value + cursor, source, length);
-}
-
-/**
- * Append the given amount of space as zeroes to the buffer.
- */
-void
-pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) {
- size_t cursor = buffer->length;
- pm_buffer_append_length(buffer, length);
- memset(buffer->value + cursor, 0, length);
-}
-
-/**
- * Append a formatted string to the buffer.
- */
-void
-pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) {
- va_list arguments;
- va_start(arguments, format);
- int result = vsnprintf(NULL, 0, format, arguments);
- va_end(arguments);
-
- if (result < 0) return;
- size_t length = (size_t) (result + 1);
-
- size_t cursor = buffer->length;
- pm_buffer_append_length(buffer, length);
-
- va_start(arguments, format);
- vsnprintf(buffer->value + cursor, length, format, arguments);
- va_end(arguments);
-
- buffer->length--;
-}
-
-/**
- * Append a string to the buffer.
- */
-void
-pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) {
- pm_buffer_append(buffer, value, length);
-}
-
-/**
- * Append a list of bytes to the buffer.
- */
-void
-pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length) {
- pm_buffer_append(buffer, (const char *) value, length);
-}
-
-/**
- * Append a single byte to the buffer.
- */
-void
-pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) {
- const void *source = &value;
- pm_buffer_append(buffer, source, sizeof(uint8_t));
-}
-
-/**
- * Append a 32-bit unsigned integer to the buffer as a variable-length integer.
- */
-void
-pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value) {
- if (value < 128) {
- pm_buffer_append_byte(buffer, (uint8_t) value);
- } else {
- uint32_t n = value;
- while (n >= 128) {
- pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
- n >>= 7;
- }
- pm_buffer_append_byte(buffer, (uint8_t) n);
- }
-}
-
-/**
- * Append a 32-bit signed integer to the buffer as a variable-length integer.
- */
-void
-pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value) {
- uint32_t unsigned_int = ((uint32_t)(value) << 1) ^ ((uint32_t)(value >> 31));
- pm_buffer_append_varuint(buffer, unsigned_int);
-}
-
-/**
- * Concatenate one buffer onto another.
- */
-void
-pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) {
- if (source->length > 0) {
- pm_buffer_append(destination, source->value, source->length);
- }
-}
-
-/**
- * Free the memory associated with the buffer.
- */
-void
-pm_buffer_free(pm_buffer_t *buffer) {
- free(buffer->value);
-}
diff --git a/prism/util/pm_buffer.h b/prism/util/pm_buffer.h
deleted file mode 100644
index ec11d05e9b..0000000000
--- a/prism/util/pm_buffer.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * @file pm_buffer.h
- *
- * A wrapper around a contiguous block of allocated memory.
- */
-#ifndef PRISM_BUFFER_H
-#define PRISM_BUFFER_H
-
-#include "prism/defines.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-/**
- * A pm_buffer_t is a simple memory buffer that stores data in a contiguous
- * block of memory.
- */
-typedef struct {
- /** The length of the buffer in bytes. */
- size_t length;
-
- /** The capacity of the buffer in bytes that has been allocated. */
- size_t capacity;
-
- /** A pointer to the start of the buffer. */
- char *value;
-} pm_buffer_t;
-
-/**
- * Return the size of the pm_buffer_t struct.
- *
- * @returns The size of the pm_buffer_t struct.
- */
-PRISM_EXPORTED_FUNCTION size_t pm_buffer_sizeof(void);
-
-/**
- * Initialize a pm_buffer_t with the given capacity.
- *
- * @param buffer The buffer to initialize.
- * @param capacity The capacity of the buffer.
- * @returns True if the buffer was initialized successfully, false otherwise.
- */
-bool pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity);
-
-/**
- * Initialize a pm_buffer_t with its default values.
- *
- * @param buffer The buffer to initialize.
- * @returns True if the buffer was initialized successfully, false otherwise.
- */
-PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer);
-
-/**
- * Return the value of the buffer.
- *
- * @param buffer The buffer to get the value of.
- * @returns The value of the buffer.
- */
-PRISM_EXPORTED_FUNCTION char * pm_buffer_value(pm_buffer_t *buffer);
-
-/**
- * Return the length of the buffer.
- *
- * @param buffer The buffer to get the length of.
- * @returns The length of the buffer.
- */
-PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(pm_buffer_t *buffer);
-
-/**
- * Append the given amount of space as zeroes to the buffer.
- *
- * @param buffer The buffer to append to.
- * @param length The amount of space to append and zero.
- */
-void pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length);
-
-/**
- * Append a formatted string to the buffer.
- *
- * @param buffer The buffer to append to.
- * @param format The format string to append.
- * @param ... The arguments to the format string.
- */
-void pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) PRISM_ATTRIBUTE_FORMAT(2, 3);
-
-/**
- * Append a string to the buffer.
- *
- * @param buffer The buffer to append to.
- * @param value The string to append.
- * @param length The length of the string to append.
- */
-void pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length);
-
-/**
- * Append a list of bytes to the buffer.
- *
- * @param buffer The buffer to append to.
- * @param value The bytes to append.
- * @param length The length of the bytes to append.
- */
-void pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length);
-
-/**
- * Append a single byte to the buffer.
- *
- * @param buffer The buffer to append to.
- * @param value The byte to append.
- */
-void pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value);
-
-/**
- * Append a 32-bit unsigned integer to the buffer as a variable-length integer.
- *
- * @param buffer The buffer to append to.
- * @param value The integer to append.
- */
-void pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value);
-
-/**
- * Append a 32-bit signed integer to the buffer as a variable-length integer.
- *
- * @param buffer The buffer to append to.
- * @param value The integer to append.
- */
-void pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value);
-
-/**
- * Concatenate one buffer onto another.
- *
- * @param destination The buffer to concatenate onto.
- * @param source The buffer to concatenate.
- */
-void pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source);
-
-/**
- * Free the memory associated with the buffer.
- *
- * @param buffer The buffer to free.
- */
-PRISM_EXPORTED_FUNCTION void pm_buffer_free(pm_buffer_t *buffer);
-
-#endif
diff --git a/prism/util/pm_char.c b/prism/util/pm_char.c
deleted file mode 100644
index 13eddbba48..0000000000
--- a/prism/util/pm_char.c
+++ /dev/null
@@ -1,318 +0,0 @@
-#include "prism/util/pm_char.h"
-
-#define PRISM_CHAR_BIT_WHITESPACE (1 << 0)
-#define PRISM_CHAR_BIT_INLINE_WHITESPACE (1 << 1)
-#define PRISM_CHAR_BIT_REGEXP_OPTION (1 << 2)
-
-#define PRISM_NUMBER_BIT_BINARY_DIGIT (1 << 0)
-#define PRISM_NUMBER_BIT_BINARY_NUMBER (1 << 1)
-#define PRISM_NUMBER_BIT_OCTAL_DIGIT (1 << 2)
-#define PRISM_NUMBER_BIT_OCTAL_NUMBER (1 << 3)
-#define PRISM_NUMBER_BIT_DECIMAL_DIGIT (1 << 4)
-#define PRISM_NUMBER_BIT_DECIMAL_NUMBER (1 << 5)
-#define PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT (1 << 6)
-#define PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER (1 << 7)
-
-static const uint8_t pm_byte_table[256] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 0, 0, // 0x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5x
- 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 4, 4, // 6x
- 0, 0, 0, 4, 0, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, // 7x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
-};
-
-static const uint8_t pm_number_table[256] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2x
- 0xff, 0xff, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3x
- 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, // 5x
- 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 6x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 7x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9x
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ax
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Bx
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Cx
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Dx
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ex
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Fx
-};
-
-/**
- * Returns the number of characters at the start of the string that match the
- * given kind. Disallows searching past the given maximum number of characters.
- */
-static inline size_t
-pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
- if (length <= 0) return 0;
-
- size_t size = 0;
- size_t maximum = (size_t) length;
-
- while (size < maximum && (pm_byte_table[string[size]] & kind)) size++;
- return size;
-}
-
-/**
- * Returns the number of characters at the start of the string that are
- * whitespace. Disallows searching past the given maximum number of characters.
- */
-size_t
-pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
- return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_WHITESPACE);
-}
-
-/**
- * Returns the number of characters at the start of the string that are
- * whitespace while also tracking the location of each newline. Disallows
- * searching past the given maximum number of characters.
- */
-size_t
-pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list) {
- if (length <= 0) return 0;
-
- size_t size = 0;
- size_t maximum = (size_t) length;
-
- while (size < maximum && (pm_byte_table[string[size]] & PRISM_CHAR_BIT_WHITESPACE)) {
- if (string[size] == '\n') {
- pm_newline_list_append(newline_list, string + size);
- }
-
- size++;
- }
-
- return size;
-}
-
-/**
- * Returns the number of characters at the start of the string that are inline
- * whitespace. Disallows searching past the given maximum number of characters.
- */
-size_t
-pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) {
- return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_INLINE_WHITESPACE);
-}
-
-/**
- * Returns the number of characters at the start of the string that are regexp
- * options. Disallows searching past the given maximum number of characters.
- */
-size_t
-pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) {
- return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_REGEXP_OPTION);
-}
-
-/**
- * Returns true if the given character matches the given kind.
- */
-static inline bool
-pm_char_is_char_kind(const uint8_t b, uint8_t kind) {
- return (pm_byte_table[b] & kind) != 0;
-}
-
-/**
- * Returns true if the given character is a whitespace character.
- */
-bool
-pm_char_is_whitespace(const uint8_t b) {
- return pm_char_is_char_kind(b, PRISM_CHAR_BIT_WHITESPACE);
-}
-
-/**
- * Returns true if the given character is an inline whitespace character.
- */
-bool
-pm_char_is_inline_whitespace(const uint8_t b) {
- return pm_char_is_char_kind(b, PRISM_CHAR_BIT_INLINE_WHITESPACE);
-}
-
-/**
- * Scan through the string and return the number of characters at the start of
- * the string that match the given kind. Disallows searching past the given
- * maximum number of characters.
- */
-static inline size_t
-pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
- if (length <= 0) return 0;
-
- size_t size = 0;
- size_t maximum = (size_t) length;
-
- while (size < maximum && (pm_number_table[string[size]] & kind)) size++;
- return size;
-}
-
-/**
- * Scan through the string and return the number of characters at the start of
- * the string that match the given kind. Disallows searching past the given
- * maximum number of characters.
- *
- * Additionally, report the location of the last invalid underscore character
- * found in the string through the out invalid parameter.
- */
-static inline size_t
-pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) {
- if (length <= 0) return 0;
-
- size_t size = 0;
- size_t maximum = (size_t) length;
-
- bool underscore = false;
- while (size < maximum && (pm_number_table[string[size]] & kind)) {
- if (string[size] == '_') {
- if (underscore) *invalid = string + size;
- underscore = true;
- } else {
- underscore = false;
- }
-
- size++;
- }
-
- if (string[size - 1] == '_') *invalid = string + size - 1;
- return size;
-}
-
-/**
- * Returns the number of characters at the start of the string that are binary
- * digits or underscores. Disallows searching past the given maximum number of
- * characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- */
-size_t
-pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
- return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_BINARY_NUMBER);
-}
-
-/**
- * Returns the number of characters at the start of the string that are octal
- * digits or underscores. Disallows searching past the given maximum number of
- * characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- */
-size_t
-pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
- return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_OCTAL_NUMBER);
-}
-
-/**
- * Returns the number of characters at the start of the string that are decimal
- * digits. Disallows searching past the given maximum number of characters.
- */
-size_t
-pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) {
- return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
-}
-
-/**
- * Returns the number of characters at the start of the string that are decimal
- * digits or underscores. Disallows searching past the given maximum number of
- * characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore
- */
-size_t
-pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
- return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_DECIMAL_NUMBER);
-}
-
-/**
- * Returns the number of characters at the start of the string that are
- * hexadecimal digits. Disallows searching past the given maximum number of
- * characters.
- */
-size_t
-pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) {
- return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
-}
-
-/**
- * Returns the number of characters at the start of the string that are
- * hexadecimal digits or underscores. Disallows searching past the given maximum
- * number of characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- */
-size_t
-pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
- return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER);
-}
-
-/**
- * Returns true if the given character matches the given kind.
- */
-static inline bool
-pm_char_is_number_kind(const uint8_t b, uint8_t kind) {
- return (pm_number_table[b] & kind) != 0;
-}
-
-/**
- * Returns true if the given character is a binary digit.
- */
-bool
-pm_char_is_binary_digit(const uint8_t b) {
- return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_BINARY_DIGIT);
-}
-
-/**
- * Returns true if the given character is an octal digit.
- */
-bool
-pm_char_is_octal_digit(const uint8_t b) {
- return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_OCTAL_DIGIT);
-}
-
-/**
- * Returns true if the given character is a decimal digit.
- */
-bool
-pm_char_is_decimal_digit(const uint8_t b) {
- return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
-}
-
-/**
- * Returns true if the given character is a hexadecimal digit.
- */
-bool
-pm_char_is_hexadecimal_digit(const uint8_t b) {
- return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
-}
-
-#undef PRISM_CHAR_BIT_WHITESPACE
-#undef PRISM_CHAR_BIT_INLINE_WHITESPACE
-#undef PRISM_CHAR_BIT_REGEXP_OPTION
-
-#undef PRISM_NUMBER_BIT_BINARY_DIGIT
-#undef PRISM_NUMBER_BIT_BINARY_NUMBER
-#undef PRISM_NUMBER_BIT_OCTAL_DIGIT
-#undef PRISM_NUMBER_BIT_OCTAL_NUMBER
-#undef PRISM_NUMBER_BIT_DECIMAL_DIGIT
-#undef PRISM_NUMBER_BIT_DECIMAL_NUMBER
-#undef PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER
-#undef PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT
diff --git a/prism/util/pm_char.h b/prism/util/pm_char.h
deleted file mode 100644
index 32f698a42b..0000000000
--- a/prism/util/pm_char.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * @file pm_char.h
- *
- * Functions for working with characters and strings.
- */
-#ifndef PRISM_CHAR_H
-#define PRISM_CHAR_H
-
-#include "prism/defines.h"
-#include "prism/util/pm_newline_list.h"
-
-#include <stdbool.h>
-#include <stddef.h>
-
-/**
- * Returns the number of characters at the start of the string that are
- * whitespace. Disallows searching past the given maximum number of characters.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @return The number of characters at the start of the string that are
- * whitespace.
- */
-size_t pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length);
-
-/**
- * Returns the number of characters at the start of the string that are
- * whitespace while also tracking the location of each newline. Disallows
- * searching past the given maximum number of characters.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @param newline_list The list of newlines to populate.
- * @return The number of characters at the start of the string that are
- * whitespace.
- */
-size_t
-pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list);
-
-/**
- * Returns the number of characters at the start of the string that are inline
- * whitespace. Disallows searching past the given maximum number of characters.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @return The number of characters at the start of the string that are inline
- * whitespace.
- */
-size_t pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length);
-
-/**
- * Returns the number of characters at the start of the string that are decimal
- * digits. Disallows searching past the given maximum number of characters.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @return The number of characters at the start of the string that are decimal
- * digits.
- */
-size_t pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length);
-
-/**
- * Returns the number of characters at the start of the string that are
- * hexadecimal digits. Disallows searching past the given maximum number of
- * characters.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @return The number of characters at the start of the string that are
- * hexadecimal digits.
- */
-size_t pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length);
-
-/**
- * Returns the number of characters at the start of the string that are octal
- * digits or underscores. Disallows searching past the given maximum number of
- * characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @param invalid The pointer to set to the index of the first invalid
- * underscore.
- * @return The number of characters at the start of the string that are octal
- * digits or underscores.
- */
-size_t pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
-
-/**
- * Returns the number of characters at the start of the string that are decimal
- * digits or underscores. Disallows searching past the given maximum number of
- * characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @param invalid The pointer to set to the index of the first invalid
- * underscore.
- * @return The number of characters at the start of the string that are decimal
- * digits or underscores.
- */
-size_t pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
-
-/**
- * Returns the number of characters at the start of the string that are
- * hexadecimal digits or underscores. Disallows searching past the given maximum
- * number of characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @param invalid The pointer to set to the index of the first invalid
- * underscore.
- * @return The number of characters at the start of the string that are
- * hexadecimal digits or underscores.
- */
-size_t pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
-
-/**
- * Returns the number of characters at the start of the string that are regexp
- * options. Disallows searching past the given maximum number of characters.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @return The number of characters at the start of the string that are regexp
- * options.
- */
-size_t pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length);
-
-/**
- * Returns the number of characters at the start of the string that are binary
- * digits or underscores. Disallows searching past the given maximum number of
- * characters.
- *
- * If multiple underscores are found in a row or if an underscore is
- * found at the end of the number, then the invalid pointer is set to the index
- * of the first invalid underscore.
- *
- * @param string The string to search.
- * @param length The maximum number of characters to search.
- * @param invalid The pointer to set to the index of the first invalid
- * underscore.
- * @return The number of characters at the start of the string that are binary
- * digits or underscores.
- */
-size_t pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
-
-/**
- * Returns true if the given character is a whitespace character.
- *
- * @param b The character to check.
- * @return True if the given character is a whitespace character.
- */
-bool pm_char_is_whitespace(const uint8_t b);
-
-/**
- * Returns true if the given character is an inline whitespace character.
- *
- * @param b The character to check.
- * @return True if the given character is an inline whitespace character.
- */
-bool pm_char_is_inline_whitespace(const uint8_t b);
-
-/**
- * Returns true if the given character is a binary digit.
- *
- * @param b The character to check.
- * @return True if the given character is a binary digit.
- */
-bool pm_char_is_binary_digit(const uint8_t b);
-
-/**
- * Returns true if the given character is an octal digit.
- *
- * @param b The character to check.
- * @return True if the given character is an octal digit.
- */
-bool pm_char_is_octal_digit(const uint8_t b);
-
-/**
- * Returns true if the given character is a decimal digit.
- *
- * @param b The character to check.
- * @return True if the given character is a decimal digit.
- */
-bool pm_char_is_decimal_digit(const uint8_t b);
-
-/**
- * Returns true if the given character is a hexadecimal digit.
- *
- * @param b The character to check.
- * @return True if the given character is a hexadecimal digit.
- */
-bool pm_char_is_hexadecimal_digit(const uint8_t b);
-
-#endif
diff --git a/prism/util/pm_constant_pool.c b/prism/util/pm_constant_pool.c
deleted file mode 100644
index e06682eb48..0000000000
--- a/prism/util/pm_constant_pool.c
+++ /dev/null
@@ -1,296 +0,0 @@
-#include "prism/util/pm_constant_pool.h"
-
-/**
- * Initialize a list of constant ids.
- */
-void
-pm_constant_id_list_init(pm_constant_id_list_t *list) {
- list->ids = NULL;
- list->size = 0;
- list->capacity = 0;
-}
-
-/**
- * Append a constant id to a list of constant ids. Returns false if any
- * potential reallocations fail.
- */
-bool
-pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id) {
- if (list->size >= list->capacity) {
- list->capacity = list->capacity == 0 ? 8 : list->capacity * 2;
- list->ids = (pm_constant_id_t *) realloc(list->ids, sizeof(pm_constant_id_t) * list->capacity);
- if (list->ids == NULL) return false;
- }
-
- list->ids[list->size++] = id;
- return true;
-}
-
-/**
- * Checks if the current constant id list includes the given constant id.
- */
-bool
-pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id) {
- for (size_t index = 0; index < list->size; index++) {
- if (list->ids[index] == id) return true;
- }
- return false;
-}
-
-/**
- * Get the memory size of a list of constant ids.
- */
-size_t
-pm_constant_id_list_memsize(pm_constant_id_list_t *list) {
- return sizeof(pm_constant_id_list_t) + (list->capacity * sizeof(pm_constant_id_t));
-}
-
-/**
- * Free the memory associated with a list of constant ids.
- */
-void
-pm_constant_id_list_free(pm_constant_id_list_t *list) {
- if (list->ids != NULL) {
- free(list->ids);
- }
-}
-
-/**
- * A relatively simple hash function (djb2) that is used to hash strings. We are
- * optimizing here for simplicity and speed.
- */
-static inline uint32_t
-pm_constant_pool_hash(const uint8_t *start, size_t length) {
- // This is a prime number used as the initial value for the hash function.
- uint32_t value = 5381;
-
- for (size_t index = 0; index < length; index++) {
- value = ((value << 5) + value) + start[index];
- }
-
- return value;
-}
-
-/**
- * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
- */
-static uint32_t
-next_power_of_two(uint32_t v) {
- // Avoid underflow in subtraction on next line.
- if (v == 0) {
- // 1 is the nearest power of 2 to 0 (2^0)
- return 1;
- }
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v++;
- return v;
-}
-
-#ifndef NDEBUG
-static bool
-is_power_of_two(uint32_t size) {
- return (size & (size - 1)) == 0;
-}
-#endif
-
-/**
- * Resize a constant pool to a given capacity.
- */
-static inline bool
-pm_constant_pool_resize(pm_constant_pool_t *pool) {
- assert(is_power_of_two(pool->capacity));
-
- uint32_t next_capacity = pool->capacity * 2;
- if (next_capacity < pool->capacity) return false;
-
- const uint32_t mask = next_capacity - 1;
- const size_t element_size = sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t);
-
- void *next = calloc(next_capacity, element_size);
- if (next == NULL) return false;
-
- pm_constant_pool_bucket_t *next_buckets = next;
- pm_constant_t *next_constants = (void *)(((char *) next) + next_capacity * sizeof(pm_constant_pool_bucket_t));
-
- // For each bucket in the current constant pool, find the index in the
- // next constant pool, and insert it.
- for (uint32_t index = 0; index < pool->capacity; index++) {
- pm_constant_pool_bucket_t *bucket = &pool->buckets[index];
-
- // If an id is set on this constant, then we know we have content here.
- // In this case we need to insert it into the next constant pool.
- if (bucket->id != 0) {
- uint32_t next_index = bucket->hash & mask;
-
- // This implements linear scanning to find the next available slot
- // in case this index is already taken. We don't need to bother
- // comparing the values since we know that the hash is unique.
- while (next_buckets[next_index].id != 0) {
- next_index = (next_index + 1) & mask;
- }
-
- // Here we copy over the entire bucket, which includes the id so
- // that they are consistent between resizes.
- next_buckets[next_index] = *bucket;
- }
- }
-
- // The constants are stable with respect to hash table resizes.
- memcpy(next_constants, pool->constants, pool->size * sizeof(pm_constant_t));
-
- // pool->constants and pool->buckets are allocated out of the same chunk
- // of memory, with the buckets coming first.
- free(pool->buckets);
- pool->constants = next_constants;
- pool->buckets = next_buckets;
- pool->capacity = next_capacity;
- return true;
-}
-
-/**
- * Initialize a new constant pool with a given capacity.
- */
-bool
-pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) {
- const uint32_t maximum = (~((uint32_t) 0));
- if (capacity >= ((maximum / 2) + 1)) return false;
-
- capacity = next_power_of_two(capacity);
- const size_t element_size = sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t);
- void *memory = calloc(capacity, element_size);
- if (memory == NULL) return false;
-
- pool->buckets = memory;
- pool->constants = (void *)(((char *)memory) + capacity * sizeof(pm_constant_pool_bucket_t));
- pool->size = 0;
- pool->capacity = capacity;
- return true;
-}
-
-/**
- * Return a pointer to the constant indicated by the given constant id.
- */
-pm_constant_t *
-pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
- assert(constant_id > 0 && constant_id <= pool->size);
- return &pool->constants[constant_id - 1];
-}
-
-/**
- * Insert a constant into a constant pool and return its index in the pool.
- */
-static inline pm_constant_id_t
-pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) {
- if (pool->size >= (pool->capacity / 4 * 3)) {
- if (!pm_constant_pool_resize(pool)) return 0;
- }
-
- assert(is_power_of_two(pool->capacity));
- const uint32_t mask = pool->capacity - 1;
-
- uint32_t hash = pm_constant_pool_hash(start, length);
- uint32_t index = hash & mask;
- pm_constant_pool_bucket_t *bucket;
-
- while (bucket = &pool->buckets[index], bucket->id != 0) {
- // If there is a collision, then we need to check if the content is the
- // same as the content we are trying to insert. If it is, then we can
- // return the id of the existing constant.
- pm_constant_t *constant = &pool->constants[bucket->id - 1];
-
- if ((constant->length == length) && memcmp(constant->start, start, length) == 0) {
- // Since we have found a match, we need to check if this is
- // attempting to insert a shared or an owned constant. We want to
- // prefer shared constants since they don't require allocations.
- if (type == PM_CONSTANT_POOL_BUCKET_OWNED) {
- // If we're attempting to insert an owned constant and we have
- // an existing constant, then either way we don't want the given
- // memory. Either it's duplicated with the existing constant or
- // it's not necessary because we have a shared version.
- free((void *) start);
- } else if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
- // If we're attempting to insert a shared constant and the
- // existing constant is owned, then we can free the owned
- // constant and replace it with the shared constant.
- free((void *) constant->start);
- constant->start = start;
- bucket->type = (unsigned int) (PM_CONSTANT_POOL_BUCKET_DEFAULT & 0x3);
- }
-
- return bucket->id;
- }
-
- index = (index + 1) & mask;
- }
-
- // IDs are allocated starting at 1, since the value 0 denotes a non-existant
- // constant.
- uint32_t id = ++pool->size;
- assert(pool->size < ((uint32_t) (1 << 30)));
-
- *bucket = (pm_constant_pool_bucket_t) {
- .id = (unsigned int) (id & 0x3fffffff),
- .type = (unsigned int) (type & 0x3),
- .hash = hash
- };
-
- pool->constants[id - 1] = (pm_constant_t) {
- .start = start,
- .length = length,
- };
-
- return id;
-}
-
-/**
- * Insert a constant into a constant pool. Returns the id of the constant, or 0
- * if any potential calls to resize fail.
- */
-pm_constant_id_t
-pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
- return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT);
-}
-
-/**
- * Insert a constant into a constant pool from memory that is now owned by the
- * constant pool. Returns the id of the constant, or 0 if any potential calls to
- * resize fail.
- */
-pm_constant_id_t
-pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
- return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED);
-}
-
-/**
- * Insert a constant into a constant pool from memory that is constant. Returns
- * the id of the constant, or 0 if any potential calls to resize fail.
- */
-pm_constant_id_t
-pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
- return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT);
-}
-
-/**
- * Free the memory associated with a constant pool.
- */
-void
-pm_constant_pool_free(pm_constant_pool_t *pool) {
- // For each constant in the current constant pool, free the contents if the
- // contents are owned.
- for (uint32_t index = 0; index < pool->capacity; index++) {
- pm_constant_pool_bucket_t *bucket = &pool->buckets[index];
-
- // If an id is set on this constant, then we know we have content here.
- if (bucket->id != 0 && bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
- pm_constant_t *constant = &pool->constants[bucket->id - 1];
- free((void *) constant->start);
- }
- }
-
- free(pool->buckets);
-}
diff --git a/prism/util/pm_constant_pool.h b/prism/util/pm_constant_pool.h
deleted file mode 100644
index ae5a88fbde..0000000000
--- a/prism/util/pm_constant_pool.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * @file pm_constant_pool.h
- *
- * A data structure that stores a set of strings.
- *
- * Each string is assigned a unique id, which can be used to compare strings for
- * equality. This comparison ends up being much faster than strcmp, since it
- * only requires a single integer comparison.
- */
-#ifndef PRISM_CONSTANT_POOL_H
-#define PRISM_CONSTANT_POOL_H
-
-#include "prism/defines.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-/**
- * A constant id is a unique identifier for a constant in the constant pool.
- */
-typedef uint32_t pm_constant_id_t;
-
-/**
- * A list of constant IDs. Usually used to represent a set of locals.
- */
-typedef struct {
- /** The number of constant ids in the list. */
- size_t size;
-
- /** The number of constant ids that have been allocated in the list. */
- size_t capacity;
-
- /** The constant ids in the list. */
- pm_constant_id_t *ids;
-} pm_constant_id_list_t;
-
-/**
- * Initialize a list of constant ids.
- *
- * @param list The list to initialize.
- */
-void pm_constant_id_list_init(pm_constant_id_list_t *list);
-
-/**
- * Append a constant id to a list of constant ids. Returns false if any
- * potential reallocations fail.
- *
- * @param list The list to append to.
- * @param id The id to append.
- * @return Whether the append succeeded.
- */
-bool pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id);
-
-/**
- * Checks if the current constant id list includes the given constant id.
- *
- * @param list The list to check.
- * @param id The id to check for.
- * @return Whether the list includes the given id.
- */
-bool pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id);
-
-/**
- * Get the memory size of a list of constant ids.
- *
- * @param list The list to get the memory size of.
- * @return The memory size of the list.
- */
-size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list);
-
-/**
- * Free the memory associated with a list of constant ids.
- *
- * @param list The list to free.
- */
-void pm_constant_id_list_free(pm_constant_id_list_t *list);
-
-/**
- * The type of bucket in the constant pool hash map. This determines how the
- * bucket should be freed.
- */
-typedef unsigned int pm_constant_pool_bucket_type_t;
-
-/** By default, each constant is a slice of the source. */
-static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_DEFAULT = 0;
-
-/** An owned constant is one for which memory has been allocated. */
-static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_OWNED = 1;
-
-/** A constant constant is known at compile time. */
-static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_CONSTANT = 2;
-
-/** A bucket in the hash map. */
-typedef struct {
- /** The incremental ID used for indexing back into the pool. */
- unsigned int id: 30;
-
- /** The type of the bucket, which determines how to free it. */
- pm_constant_pool_bucket_type_t type: 2;
-
- /** The hash of the bucket. */
- uint32_t hash;
-} pm_constant_pool_bucket_t;
-
-/** A constant in the pool which effectively stores a string. */
-typedef struct {
- /** A pointer to the start of the string. */
- const uint8_t *start;
-
- /** The length of the string. */
- size_t length;
-} pm_constant_t;
-
-/** The overall constant pool, which stores constants found while parsing. */
-typedef struct {
- /** The buckets in the hash map. */
- pm_constant_pool_bucket_t *buckets;
-
- /** The constants that are stored in the buckets. */
- pm_constant_t *constants;
-
- /** The number of buckets in the hash map. */
- uint32_t size;
-
- /** The number of buckets that have been allocated in the hash map. */
- uint32_t capacity;
-} pm_constant_pool_t;
-
-/**
- * Initialize a new constant pool with a given capacity.
- *
- * @param pool The pool to initialize.
- * @param capacity The initial capacity of the pool.
- * @return Whether the initialization succeeded.
- */
-bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
-
-/**
- * Return a pointer to the constant indicated by the given constant id.
- *
- * @param pool The pool to get the constant from.
- * @param constant_id The id of the constant to get.
- * @return A pointer to the constant.
- */
-pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id);
-
-/**
- * Insert a constant into a constant pool that is a slice of a source string.
- * Returns the id of the constant, or 0 if any potential calls to resize fail.
- *
- * @param pool The pool to insert the constant into.
- * @param start A pointer to the start of the constant.
- * @param length The length of the constant.
- * @return The id of the constant.
- */
-pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
-
-/**
- * Insert a constant into a constant pool from memory that is now owned by the
- * constant pool. Returns the id of the constant, or 0 if any potential calls to
- * resize fail.
- *
- * @param pool The pool to insert the constant into.
- * @param start A pointer to the start of the constant.
- * @param length The length of the constant.
- * @return The id of the constant.
- */
-pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
-
-/**
- * Insert a constant into a constant pool from memory that is constant. Returns
- * the id of the constant, or 0 if any potential calls to resize fail.
- *
- * @param pool The pool to insert the constant into.
- * @param start A pointer to the start of the constant.
- * @param length The length of the constant.
- * @return The id of the constant.
- */
-pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
-
-/**
- * Free the memory associated with a constant pool.
- *
- * @param pool The pool to free.
- */
-void pm_constant_pool_free(pm_constant_pool_t *pool);
-
-#endif
diff --git a/prism/util/pm_list.c b/prism/util/pm_list.c
deleted file mode 100644
index 62cfe47cfa..0000000000
--- a/prism/util/pm_list.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "prism/util/pm_list.h"
-
-/**
- * Returns true if the given list is empty.
- */
-PRISM_EXPORTED_FUNCTION bool
-pm_list_empty_p(pm_list_t *list) {
- return list->head == NULL;
-}
-
-/**
- * Returns the size of the list.
- */
-PRISM_EXPORTED_FUNCTION size_t
-pm_list_size(pm_list_t *list) {
- return list->size;
-}
-
-/**
- * Append a node to the given list.
- */
-void
-pm_list_append(pm_list_t *list, pm_list_node_t *node) {
- if (list->head == NULL) {
- list->head = node;
- } else {
- list->tail->next = node;
- }
-
- list->tail = node;
- list->size++;
-}
-
-/**
- * Deallocate the internal state of the given list.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_list_free(pm_list_t *list) {
- pm_list_node_t *node = list->head;
- pm_list_node_t *next;
-
- while (node != NULL) {
- next = node->next;
- free(node);
- node = next;
- }
-
- list->size = 0;
-}
diff --git a/prism/util/pm_list.h b/prism/util/pm_list.h
deleted file mode 100644
index d29fe07c52..0000000000
--- a/prism/util/pm_list.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file pm_list.h
- *
- * An abstract linked list.
- */
-#ifndef PRISM_LIST_H
-#define PRISM_LIST_H
-
-#include "prism/defines.h"
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-/**
- * This struct represents an abstract linked list that provides common
- * functionality. It is meant to be used any time a linked list is necessary to
- * store data.
- *
- * The linked list itself operates off a set of pointers. Because the pointers
- * are not necessarily sequential, they can be of any size. We use this fact to
- * allow the consumer of this linked list to extend the node struct to include
- * any data they want. This is done by using the pm_list_node_t as the first
- * member of the struct.
- *
- * For example, if we want to store a list of integers, we can do the following:
- *
- * ```c
- * typedef struct {
- * pm_list_node_t node;
- * int value;
- * } pm_int_node_t;
- *
- * pm_list_t list = { 0 };
- * pm_int_node_t *node = malloc(sizeof(pm_int_node_t));
- * node->value = 5;
- *
- * pm_list_append(&list, &node->node);
- * ```
- *
- * The pm_list_t struct is used to represent the overall linked list. It
- * contains a pointer to the head and tail of the list. This allows for easy
- * iteration and appending of new nodes.
- */
-typedef struct pm_list_node {
- /** A pointer to the next node in the list. */
- struct pm_list_node *next;
-} pm_list_node_t;
-
-/**
- * This represents the overall linked list. It keeps a pointer to the head and
- * tail so that iteration is easy and pushing new nodes is easy.
- */
-typedef struct {
- /** The size of the list. */
- size_t size;
-
- /** A pointer to the head of the list. */
- pm_list_node_t *head;
-
- /** A pointer to the tail of the list. */
- pm_list_node_t *tail;
-} pm_list_t;
-
-/**
- * Returns true if the given list is empty.
- *
- * @param list The list to check.
- * @return True if the given list is empty, otherwise false.
- */
-PRISM_EXPORTED_FUNCTION bool pm_list_empty_p(pm_list_t *list);
-
-/**
- * Returns the size of the list.
- *
- * @param list The list to check.
- * @return The size of the list.
- */
-PRISM_EXPORTED_FUNCTION size_t pm_list_size(pm_list_t *list);
-
-/**
- * Append a node to the given list.
- *
- * @param list The list to append to.
- * @param node The node to append.
- */
-void pm_list_append(pm_list_t *list, pm_list_node_t *node);
-
-/**
- * Deallocate the internal state of the given list.
- *
- * @param list The list to free.
- */
-PRISM_EXPORTED_FUNCTION void pm_list_free(pm_list_t *list);
-
-#endif
diff --git a/prism/util/pm_memchr.c b/prism/util/pm_memchr.c
deleted file mode 100644
index 7ea20ace6d..0000000000
--- a/prism/util/pm_memchr.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "prism/util/pm_memchr.h"
-
-#define PRISM_MEMCHR_TRAILING_BYTE_MINIMUM 0x40
-
-/**
- * We need to roll our own memchr to handle cases where the encoding changes and
- * we need to search for a character in a buffer that could be the trailing byte
- * of a multibyte character.
- */
-void *
-pm_memchr(const void *memory, int character, size_t number, bool encoding_changed, const pm_encoding_t *encoding) {
- if (encoding_changed && encoding->multibyte && character >= PRISM_MEMCHR_TRAILING_BYTE_MINIMUM) {
- const uint8_t *source = (const uint8_t *) memory;
- size_t index = 0;
-
- while (index < number) {
- if (source[index] == character) {
- return (void *) (source + index);
- }
-
- size_t width = encoding->char_width(source + index, (ptrdiff_t) (number - index));
- if (width == 0) {
- return NULL;
- }
-
- index += width;
- }
-
- return NULL;
- } else {
- return memchr(memory, character, number);
- }
-}
-
-#undef PRISM_MEMCHR_TRAILING_BYTE_MINIMUM
diff --git a/prism/util/pm_memchr.h b/prism/util/pm_memchr.h
deleted file mode 100644
index e0671eaed3..0000000000
--- a/prism/util/pm_memchr.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file pm_memchr.h
- *
- * A custom memchr implementation.
- */
-#ifndef PRISM_MEMCHR_H
-#define PRISM_MEMCHR_H
-
-#include "prism/defines.h"
-#include "prism/encoding.h"
-
-#include <stddef.h>
-
-/**
- * We need to roll our own memchr to handle cases where the encoding changes and
- * we need to search for a character in a buffer that could be the trailing byte
- * of a multibyte character.
- *
- * @param source The source string.
- * @param character The character to search for.
- * @param number The maximum number of bytes to search.
- * @param encoding_changed Whether the encoding changed.
- * @param encoding A pointer to the encoding.
- * @return A pointer to the first occurrence of the character in the source
- * string, or NULL if no such character exists.
- */
-void * pm_memchr(const void *source, int character, size_t number, bool encoding_changed, const pm_encoding_t *encoding);
-
-#endif
diff --git a/prism/util/pm_newline_list.c b/prism/util/pm_newline_list.c
deleted file mode 100644
index f27bb75b63..0000000000
--- a/prism/util/pm_newline_list.c
+++ /dev/null
@@ -1,96 +0,0 @@
-#include "prism/util/pm_newline_list.h"
-
-/**
- * Initialize a new newline list with the given capacity. Returns true if the
- * allocation of the offsets succeeds, otherwise returns false.
- */
-bool
-pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capacity) {
- list->offsets = (size_t *) calloc(capacity, sizeof(size_t));
- if (list->offsets == NULL) return false;
-
- list->start = start;
-
- // This is 1 instead of 0 because we want to include the first line of the
- // file as having offset 0, which is set because of calloc.
- list->size = 1;
- list->capacity = capacity;
-
- return true;
-}
-
-/**
- * Append a new offset to the newline list. Returns true if the reallocation of
- * the offsets succeeds (if one was necessary), otherwise returns false.
- */
-bool
-pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor) {
- if (list->size == list->capacity) {
- size_t *original_offsets = list->offsets;
-
- list->capacity = (list->capacity * 3) / 2;
- list->offsets = (size_t *) calloc(list->capacity, sizeof(size_t));
- memcpy(list->offsets, original_offsets, list->size * sizeof(size_t));
- free(original_offsets);
- if (list->offsets == NULL) return false;
- }
-
- assert(*cursor == '\n');
- assert(cursor >= list->start);
- size_t newline_offset = (size_t) (cursor - list->start + 1);
-
- assert(list->size == 0 || newline_offset > list->offsets[list->size - 1]);
- list->offsets[list->size++] = newline_offset;
-
- return true;
-}
-
-/**
- * Conditionally append a new offset to the newline list, if the value passed in
- * is a newline.
- */
-bool
-pm_newline_list_check_append(pm_newline_list_t *list, const uint8_t *cursor) {
- if (*cursor != '\n') {
- return true;
- }
- return pm_newline_list_append(list, cursor);
-}
-
-/**
- * Returns the line and column of the given offset. If the offset is not in the
- * list, the line and column of the closest offset less than the given offset
- * are returned.
- */
-pm_line_column_t
-pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor) {
- assert(cursor >= list->start);
- size_t offset = (size_t) (cursor - list->start);
-
- size_t left = 0;
- size_t right = list->size - 1;
-
- while (left <= right) {
- size_t mid = left + (right - left) / 2;
-
- if (list->offsets[mid] == offset) {
- return ((pm_line_column_t) { mid, 0 });
- }
-
- if (list->offsets[mid] < offset) {
- left = mid + 1;
- } else {
- right = mid - 1;
- }
- }
-
- return ((pm_line_column_t) { left - 1, offset - list->offsets[left - 1] });
-}
-
-/**
- * Free the internal memory allocated for the newline list.
- */
-void
-pm_newline_list_free(pm_newline_list_t *list) {
- free(list->offsets);
-}
diff --git a/prism/util/pm_newline_list.h b/prism/util/pm_newline_list.h
deleted file mode 100644
index a31051f4e0..0000000000
--- a/prism/util/pm_newline_list.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * @file pm_newline_list.h
- *
- * A list of byte offsets of newlines in a string.
- *
- * When compiling the syntax tree, it's necessary to know the line and column
- * of many nodes. This is necessary to support things like error messages,
- * tracepoints, etc.
- *
- * It's possible that we could store the start line, start column, end line, and
- * end column on every node in addition to the offsets that we already store,
- * but that would be quite a lot of memory overhead.
- */
-#ifndef PRISM_NEWLINE_LIST_H
-#define PRISM_NEWLINE_LIST_H
-
-#include "prism/defines.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-/**
- * A list of offsets of newlines in a string. The offsets are assumed to be
- * sorted/inserted in ascending order.
- */
-typedef struct {
- /** A pointer to the start of the source string. */
- const uint8_t *start;
-
- /** The number of offsets in the list. */
- size_t size;
-
- /** The capacity of the list that has been allocated. */
- size_t capacity;
-
- /** The list of offsets. */
- size_t *offsets;
-} pm_newline_list_t;
-
-/**
- * A line and column in a string.
- */
-typedef struct {
- /** The line number. */
- size_t line;
-
- /** The column number. */
- size_t column;
-} pm_line_column_t;
-
-/**
- * Initialize a new newline list with the given capacity. Returns true if the
- * allocation of the offsets succeeds, otherwise returns false.
- *
- * @param list The list to initialize.
- * @param start A pointer to the start of the source string.
- * @param capacity The initial capacity of the list.
- * @return True if the allocation of the offsets succeeds, otherwise false.
- */
-bool pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capacity);
-
-/**
- * Append a new offset to the newline list. Returns true if the reallocation of
- * the offsets succeeds (if one was necessary), otherwise returns false.
- *
- * @param list The list to append to.
- * @param cursor A pointer to the offset to append.
- * @return True if the reallocation of the offsets succeeds (if one was
- * necessary), otherwise false.
- */
-bool pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor);
-
-/**
- * Conditionally append a new offset to the newline list, if the value passed in
- * is a newline.
- *
- * @param list The list to append to.
- * @param cursor A pointer to the offset to append.
- * @return True if the reallocation of the offsets succeeds (if one was
- * necessary), otherwise false.
- */
-bool pm_newline_list_check_append(pm_newline_list_t *list, const uint8_t *cursor);
-
-/**
- * Returns the line and column of the given offset. If the offset is not in the
- * list, the line and column of the closest offset less than the given offset
- * are returned.
- *
- * @param list The list to search.
- * @param cursor A pointer to the offset to search for.
- * @return The line and column of the given offset.
- */
-pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor);
-
-/**
- * Free the internal memory allocated for the newline list.
- *
- * @param list The list to free.
- */
-void pm_newline_list_free(pm_newline_list_t *list);
-
-#endif
diff --git a/prism/util/pm_state_stack.c b/prism/util/pm_state_stack.c
deleted file mode 100644
index 2a424b4c03..0000000000
--- a/prism/util/pm_state_stack.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "prism/util/pm_state_stack.h"
-
-/**
- * Pushes a value onto the stack.
- */
-void
-pm_state_stack_push(pm_state_stack_t *stack, bool value) {
- *stack = (*stack << 1) | (value & 1);
-}
-
-/**
- * Pops a value off the stack.
- */
-void
-pm_state_stack_pop(pm_state_stack_t *stack) {
- *stack >>= 1;
-}
-
-/**
- * Returns the value at the top of the stack.
- */
-bool
-pm_state_stack_p(pm_state_stack_t *stack) {
- return *stack & 1;
-}
diff --git a/prism/util/pm_state_stack.h b/prism/util/pm_state_stack.h
deleted file mode 100644
index 1ce57a2209..0000000000
--- a/prism/util/pm_state_stack.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * @file pm_state_stack.h
- *
- * A stack of boolean values.
- */
-#ifndef PRISM_STATE_STACK_H
-#define PRISM_STATE_STACK_H
-
-#include "prism/defines.h"
-
-#include <stdbool.h>
-#include <stdint.h>
-
-/**
- * A struct that represents a stack of boolean values.
- */
-typedef uint32_t pm_state_stack_t;
-
-/**
- * Pushes a value onto the stack.
- *
- * @param stack The stack to push the value onto.
- * @param value The value to push onto the stack.
- */
-void pm_state_stack_push(pm_state_stack_t *stack, bool value);
-
-/**
- * Pops a value off the stack.
- *
- * @param stack The stack to pop the value off of.
- */
-void pm_state_stack_pop(pm_state_stack_t *stack);
-
-/**
- * Returns the value at the top of the stack.
- *
- * @param stack The stack to get the value from.
- * @return The value at the top of the stack.
- */
-bool pm_state_stack_p(pm_state_stack_t *stack);
-
-#endif
diff --git a/prism/util/pm_string.c b/prism/util/pm_string.c
deleted file mode 100644
index f4d3033a1b..0000000000
--- a/prism/util/pm_string.c
+++ /dev/null
@@ -1,210 +0,0 @@
-#include "prism/util/pm_string.h"
-
-/**
- * Returns the size of the pm_string_t struct. This is necessary to allocate the
- * correct amount of memory in the FFI backend.
- */
-PRISM_EXPORTED_FUNCTION size_t
-pm_string_sizeof(void) {
- return sizeof(pm_string_t);
-}
-
-/**
- * Initialize a shared string that is based on initial input.
- */
-void
-pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end) {
- assert(start <= end);
-
- *string = (pm_string_t) {
- .type = PM_STRING_SHARED,
- .source = start,
- .length = (size_t) (end - start)
- };
-}
-
-/**
- * Initialize an owned string that is responsible for freeing allocated memory.
- */
-void
-pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length) {
- *string = (pm_string_t) {
- .type = PM_STRING_OWNED,
- .source = source,
- .length = length
- };
-}
-
-/**
- * Initialize a constant string that doesn't own its memory source.
- */
-void
-pm_string_constant_init(pm_string_t *string, const char *source, size_t length) {
- *string = (pm_string_t) {
- .type = PM_STRING_CONSTANT,
- .source = (const uint8_t *) source,
- .length = length
- };
-}
-
-/**
- * Read the file indicated by the filepath parameter into source and load its
- * contents and size into the given `pm_string_t`. The given `pm_string_t`
- * should be freed using `pm_string_free` when it is no longer used.
- *
- * We want to use demand paging as much as possible in order to avoid having to
- * read the entire file into memory (which could be detrimental to performance
- * for large files). This means that if we're on windows we'll use
- * `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use
- * `mmap`, and on other POSIX systems we'll use `read`.
- */
-bool
-pm_string_mapped_init(pm_string_t *string, const char *filepath) {
-#ifdef _WIN32
- // Open the file for reading.
- HANDLE file = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (file == INVALID_HANDLE_VALUE) {
- perror("CreateFile failed");
- return false;
- }
-
- // Get the file size.
- DWORD file_size = GetFileSize(file, NULL);
- if (file_size == INVALID_FILE_SIZE) {
- CloseHandle(file);
- perror("GetFileSize failed");
- return false;
- }
-
- // If the file is empty, then we don't need to do anything else, we'll set
- // the source to a constant empty string and return.
- if (file_size == 0) {
- CloseHandle(file);
- const uint8_t source[] = "";
- *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
- return true;
- }
-
- // Create a mapping of the file.
- HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
- if (mapping == NULL) {
- CloseHandle(file);
- perror("CreateFileMapping failed");
- return false;
- }
-
- // Map the file into memory.
- uint8_t *source = (uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
- CloseHandle(mapping);
- CloseHandle(file);
-
- if (source == NULL) {
- perror("MapViewOfFile failed");
- return false;
- }
-
- *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = (size_t) file_size };
- return true;
-#else
- // Open the file for reading
- int fd = open(filepath, O_RDONLY);
- if (fd == -1) {
- perror("open");
- return false;
- }
-
- // Stat the file to get the file size
- struct stat sb;
- if (fstat(fd, &sb) == -1) {
- close(fd);
- perror("fstat");
- return false;
- }
-
- // mmap the file descriptor to virtually get the contents
- size_t size = (size_t) sb.st_size;
- uint8_t *source = NULL;
-
- if (size == 0) {
- close(fd);
- const uint8_t source[] = "";
- *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
- return true;
- }
-
- source = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (source == MAP_FAILED) {
- perror("Map failed");
- return false;
- }
-
- close(fd);
- *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = size };
- return true;
-#endif
-}
-
-/**
- * Returns the memory size associated with the string.
- */
-size_t
-pm_string_memsize(const pm_string_t *string) {
- size_t size = sizeof(pm_string_t);
- if (string->type == PM_STRING_OWNED) {
- size += string->length;
- }
- return size;
-}
-
-/**
- * Ensure the string is owned. If it is not, then reinitialize it as owned and
- * copy over the previous source.
- */
-void
-pm_string_ensure_owned(pm_string_t *string) {
- if (string->type == PM_STRING_OWNED) return;
-
- size_t length = pm_string_length(string);
- const uint8_t *source = pm_string_source(string);
-
- uint8_t *memory = malloc(length);
- if (!memory) return;
-
- pm_string_owned_init(string, memory, length);
- memcpy((void *) string->source, source, length);
-}
-
-/**
- * Returns the length associated with the string.
- */
-PRISM_EXPORTED_FUNCTION size_t
-pm_string_length(const pm_string_t *string) {
- return string->length;
-}
-
-/**
- * Returns the start pointer associated with the string.
- */
-PRISM_EXPORTED_FUNCTION const uint8_t *
-pm_string_source(const pm_string_t *string) {
- return string->source;
-}
-
-/**
- * Free the associated memory of the given string.
- */
-PRISM_EXPORTED_FUNCTION void
-pm_string_free(pm_string_t *string) {
- void *memory = (void *) string->source;
-
- if (string->type == PM_STRING_OWNED) {
- free(memory);
- } else if (string->type == PM_STRING_MAPPED && string->length) {
-#if defined(_WIN32)
- UnmapViewOfFile(memory);
-#else
- munmap(memory, string->length);
-#endif
- }
-}
diff --git a/prism/util/pm_string.h b/prism/util/pm_string.h
deleted file mode 100644
index ddb153784f..0000000000
--- a/prism/util/pm_string.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * @file pm_string.h
- *
- * A generic string type that can have various ownership semantics.
- */
-#ifndef PRISM_STRING_H
-#define PRISM_STRING_H
-
-#include "prism/defines.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-// The following headers are necessary to read files using demand paging.
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#endif
-
-/**
- * A generic string type that can have various ownership semantics.
- */
-typedef struct {
- /** A pointer to the start of the string. */
- const uint8_t *source;
-
- /** The length of the string in bytes of memory. */
- size_t length;
-
- /** The type of the string. This field determines how the string should be freed. */
- enum {
- /** This string is a constant string, and should not be freed. */
- PM_STRING_CONSTANT,
-
- /** This is a slice of another string, and should not be freed. */
- PM_STRING_SHARED,
-
- /** This string owns its memory, and should be freed using `pm_string_free`. */
- PM_STRING_OWNED,
-
- /** This string is a memory-mapped file, and should be freed using `pm_string_free`. */
- PM_STRING_MAPPED
- } type;
-} pm_string_t;
-
-/**
- * Returns the size of the pm_string_t struct. This is necessary to allocate the
- * correct amount of memory in the FFI backend.
- *
- * @return The size of the pm_string_t struct.
- */
-PRISM_EXPORTED_FUNCTION size_t pm_string_sizeof(void);
-
-/**
- * Defines an empty string. This is useful for initializing a string that will
- * be filled in later.
- */
-#define PM_STRING_EMPTY ((pm_string_t) { .type = PM_STRING_CONSTANT, .source = NULL, .length = 0 })
-
-/**
- * Initialize a shared string that is based on initial input.
- *
- * @param string The string to initialize.
- * @param start The start of the string.
- * @param end The end of the string.
- */
-void pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end);
-
-/**
- * Initialize an owned string that is responsible for freeing allocated memory.
- *
- * @param string The string to initialize.
- * @param source The source of the string.
- * @param length The length of the string.
- */
-void pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length);
-
-/**
- * Initialize a constant string that doesn't own its memory source.
- *
- * @param string The string to initialize.
- * @param source The source of the string.
- * @param length The length of the string.
- */
-void pm_string_constant_init(pm_string_t *string, const char *source, size_t length);
-
-/**
- * Read the file indicated by the filepath parameter into source and load its
- * contents and size into the given `pm_string_t`. The given `pm_string_t`
- * should be freed using `pm_string_free` when it is no longer used.
- *
- * We want to use demand paging as much as possible in order to avoid having to
- * read the entire file into memory (which could be detrimental to performance
- * for large files). This means that if we're on windows we'll use
- * `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use
- * `mmap`, and on other POSIX systems we'll use `read`.
- *
- * @param string The string to initialize.
- * @param filepath The filepath to read.
- * @return Whether or not the file was successfully mapped.
- */
-PRISM_EXPORTED_FUNCTION bool pm_string_mapped_init(pm_string_t *string, const char *filepath);
-
-/**
- * Returns the memory size associated with the string.
- *
- * @param string The string to get the memory size of.
- * @return The size of the memory associated with the string.
- */
-size_t pm_string_memsize(const pm_string_t *string);
-
-/**
- * Ensure the string is owned. If it is not, then reinitialize it as owned and
- * copy over the previous source.
- *
- * @param string The string to ensure is owned.
- */
-void pm_string_ensure_owned(pm_string_t *string);
-
-/**
- * Returns the length associated with the string.
- *
- * @param string The string to get the length of.
- * @return The length of the string.
- */
-PRISM_EXPORTED_FUNCTION size_t pm_string_length(const pm_string_t *string);
-
-/**
- * Returns the start pointer associated with the string.
- *
- * @param string The string to get the start pointer of.
- * @return The start pointer of the string.
- */
-PRISM_EXPORTED_FUNCTION const uint8_t * pm_string_source(const pm_string_t *string);
-
-/**
- * Free the associated memory of the given string.
- *
- * @param string The string to free.
- */
-PRISM_EXPORTED_FUNCTION void pm_string_free(pm_string_t *string);
-
-#endif
diff --git a/prism/util/pm_string_list.c b/prism/util/pm_string_list.c
deleted file mode 100644
index d49e4ed734..0000000000
--- a/prism/util/pm_string_list.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "prism/util/pm_string_list.h"
-
-/**
- * Append a pm_string_t to the given string list.
- */
-void
-pm_string_list_append(pm_string_list_t *string_list, pm_string_t *string) {
- if (string_list->length + 1 > string_list->capacity) {
- if (string_list->capacity == 0) {
- string_list->capacity = 1;
- } else {
- string_list->capacity *= 2;
- }
-
- string_list->strings = realloc(string_list->strings, string_list->capacity * sizeof(pm_string_t));
- if (string_list->strings == NULL) abort();
- }
-
- string_list->strings[string_list->length++] = *string;
-}
-
-/**
- * Free the memory associated with the string list
- */
-void
-pm_string_list_free(pm_string_list_t *string_list) {
- free(string_list->strings);
-}
diff --git a/prism/util/pm_string_list.h b/prism/util/pm_string_list.h
deleted file mode 100644
index 0d406cc5d8..0000000000
--- a/prism/util/pm_string_list.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file pm_string_list.h
- *
- * A list of strings.
- */
-#ifndef PRISM_STRING_LIST_H
-#define PRISM_STRING_LIST_H
-
-#include "prism/defines.h"
-#include "prism/util/pm_string.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-/**
- * A list of strings.
- */
-typedef struct {
- /** The length of the string list. */
- size_t length;
-
- /** The capacity of the string list that has been allocated. */
- size_t capacity;
-
- /** A pointer to the start of the string list. */
- pm_string_t *strings;
-} pm_string_list_t;
-
-/**
- * Append a pm_string_t to the given string list.
- *
- * @param string_list The string list to append to.
- * @param string The string to append.
- */
-void pm_string_list_append(pm_string_list_t *string_list, pm_string_t *string);
-
-/**
- * Free the memory associated with the string list.
- *
- * @param string_list The string list to free.
- */
-PRISM_EXPORTED_FUNCTION void pm_string_list_free(pm_string_list_t *string_list);
-
-#endif
diff --git a/prism/util/pm_strncasecmp.c b/prism/util/pm_strncasecmp.c
deleted file mode 100644
index 2240bf8110..0000000000
--- a/prism/util/pm_strncasecmp.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "prism/util/pm_strncasecmp.h"
-
-/**
- * Compare two strings, ignoring case, up to the given length. Returns 0 if the
- * strings are equal, a negative number if string1 is less than string2, or a
- * positive number if string1 is greater than string2.
- *
- * Note that this is effectively our own implementation of strncasecmp, but it's
- * not available on all of the platforms we want to support so we're rolling it
- * here.
- */
-int
-pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length) {
- size_t offset = 0;
- int difference = 0;
-
- while (offset < length && string1[offset] != '\0') {
- if (string2[offset] == '\0') return string1[offset];
- if ((difference = tolower(string1[offset]) - tolower(string2[offset])) != 0) return difference;
- offset++;
- }
-
- return difference;
-}
diff --git a/prism/util/pm_strncasecmp.h b/prism/util/pm_strncasecmp.h
deleted file mode 100644
index 5cb88cb5eb..0000000000
--- a/prism/util/pm_strncasecmp.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file pm_strncasecmp.h
- *
- * A custom strncasecmp implementation.
- */
-#ifndef PRISM_STRNCASECMP_H
-#define PRISM_STRNCASECMP_H
-
-#include "prism/defines.h"
-
-#include <ctype.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * Compare two strings, ignoring case, up to the given length. Returns 0 if the
- * strings are equal, a negative number if string1 is less than string2, or a
- * positive number if string1 is greater than string2.
- *
- * Note that this is effectively our own implementation of strncasecmp, but it's
- * not available on all of the platforms we want to support so we're rolling it
- * here.
- *
- * @param string1 The first string to compare.
- * @param string2 The second string to compare
- * @param length The maximum number of characters to compare.
- * @return 0 if the strings are equal, a negative number if string1 is less than
- * string2, or a positive number if string1 is greater than string2.
- */
-int pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length);
-
-#endif
diff --git a/prism/util/pm_strpbrk.c b/prism/util/pm_strpbrk.c
deleted file mode 100644
index 115eba1fd2..0000000000
--- a/prism/util/pm_strpbrk.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "prism/util/pm_strpbrk.h"
-
-/**
- * This is the slow path that does care about the encoding.
- */
-static inline const uint8_t *
-pm_strpbrk_multi_byte(const pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, size_t maximum) {
- size_t index = 0;
-
- while (index < maximum) {
- if (strchr((const char *) charset, source[index]) != NULL) {
- return source + index;
- }
-
- size_t width = parser->encoding->char_width(source + index, (ptrdiff_t) (maximum - index));
- if (width == 0) {
- return NULL;
- }
-
- index += width;
- }
-
- return NULL;
-}
-
-/**
- * This is the fast path that does not care about the encoding.
- */
-static inline const uint8_t *
-pm_strpbrk_single_byte(const uint8_t *source, const uint8_t *charset, size_t maximum) {
- size_t index = 0;
-
- while (index < maximum) {
- if (strchr((const char *) charset, source[index]) != NULL) {
- return source + index;
- }
-
- index++;
- }
-
- return NULL;
-}
-
-/**
- * Here we have rolled our own version of strpbrk. The standard library strpbrk
- * has undefined behavior when the source string is not null-terminated. We want
- * to support strings that are not null-terminated because pm_parse does not
- * have the contract that the string is null-terminated. (This is desirable
- * because it means the extension can call pm_parse with the result of a call to
- * mmap).
- *
- * The standard library strpbrk also does not support passing a maximum length
- * to search. We want to support this for the reason mentioned above, but we
- * also don't want it to stop on null bytes. Ruby actually allows null bytes
- * within strings, comments, regular expressions, etc. So we need to be able to
- * skip past them.
- *
- * Finally, we want to support encodings wherein the charset could contain
- * characters that are trailing bytes of multi-byte characters. For example, in
- * Shift-JIS, the backslash character can be a trailing byte. In that case we
- * need to take a slower path and iterate one multi-byte character at a time.
- */
-const uint8_t *
-pm_strpbrk(const pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length) {
- if (length <= 0) {
- return NULL;
- } else if (parser->encoding_changed && parser->encoding->multibyte) {
- return pm_strpbrk_multi_byte(parser, source, charset, (size_t) length);
- } else {
- return pm_strpbrk_single_byte(source, charset, (size_t) length);
- }
-}
diff --git a/prism/util/pm_strpbrk.h b/prism/util/pm_strpbrk.h
deleted file mode 100644
index c1cf0d54db..0000000000
--- a/prism/util/pm_strpbrk.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file pm_strpbrk.h
- *
- * A custom strpbrk implementation.
- */
-#ifndef PRISM_STRPBRK_H
-#define PRISM_STRPBRK_H
-
-#include "prism/defines.h"
-#include "prism/parser.h"
-
-#include <stddef.h>
-#include <string.h>
-
-/**
- * Here we have rolled our own version of strpbrk. The standard library strpbrk
- * has undefined behavior when the source string is not null-terminated. We want
- * to support strings that are not null-terminated because pm_parse does not
- * have the contract that the string is null-terminated. (This is desirable
- * because it means the extension can call pm_parse with the result of a call to
- * mmap).
- *
- * The standard library strpbrk also does not support passing a maximum length
- * to search. We want to support this for the reason mentioned above, but we
- * also don't want it to stop on null bytes. Ruby actually allows null bytes
- * within strings, comments, regular expressions, etc. So we need to be able to
- * skip past them.
- *
- * Finally, we want to support encodings wherein the charset could contain
- * characters that are trailing bytes of multi-byte characters. For example, in
- * Shift-JIS, the backslash character can be a trailing byte. In that case we
- * need to take a slower path and iterate one multi-byte character at a time.
- *
- * @param parser The parser.
- * @param source The source to search.
- * @param charset The charset to search for.
- * @param length The maximum number of bytes to search.
- * @return A pointer to the first character in the source string that is in the
- * charset, or NULL if no such character exists.
- */
-const uint8_t * pm_strpbrk(const pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length);
-
-#endif
diff --git a/prism/version.h b/prism/version.h
deleted file mode 100644
index 1472c58be6..0000000000
--- a/prism/version.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file version.h
- *
- * The version of the Prism library.
- */
-#ifndef PRISM_VERSION_H
-#define PRISM_VERSION_H
-
-/**
- * The major version of the Prism library as an int.
- */
-#define PRISM_VERSION_MAJOR 0
-
-/**
- * The minor version of the Prism library as an int.
- */
-#define PRISM_VERSION_MINOR 19
-
-/**
- * The patch version of the Prism library as an int.
- */
-#define PRISM_VERSION_PATCH 0
-
-/**
- * The version of the Prism library as a constant string.
- */
-#define PRISM_VERSION "0.19.0"
-
-#endif
diff --git a/prism_compile.c b/prism_compile.c
deleted file mode 100644
index b60ca0ac68..0000000000
--- a/prism_compile.c
+++ /dev/null
@@ -1,6532 +0,0 @@
-#include "prism.h"
-
-#define OLD_ISEQ NEW_ISEQ
-#undef NEW_ISEQ
-
-#define NEW_ISEQ(node, name, type, line_no) \
- pm_new_child_iseq(iseq, (node), parser, rb_fstring(name), 0, (type), (line_no))
-
-#define OLD_CHILD_ISEQ NEW_CHILD_ISEQ
-#undef NEW_CHILD_ISEQ
-
-#define NEW_CHILD_ISEQ(node, name, type, line_no) \
- pm_new_child_iseq(iseq, (node), parser, rb_fstring(name), iseq, (type), (line_no))
-
-#define PM_COMPILE(node) \
- pm_compile_node(iseq, (node), ret, src, popped, scope_node)
-
-#define PM_COMPILE_INTO_ANCHOR(_ret, node) \
- pm_compile_node(iseq, (node), _ret, src, popped, scope_node)
-
-#define PM_COMPILE_POPPED(node) \
- pm_compile_node(iseq, (node), ret, src, true, scope_node)
-
-#define PM_COMPILE_NOT_POPPED(node) \
- pm_compile_node(iseq, (node), ret, src, false, scope_node)
-
-#define PM_POP \
- ADD_INSN(ret, &dummy_line_node, pop);
-
-#define PM_POP_IF_POPPED \
- if (popped) PM_POP;
-
-#define PM_POP_UNLESS_POPPED \
- if (!popped) PM_POP;
-
-#define PM_DUP \
- ADD_INSN(ret, &dummy_line_node, dup);
-
-#define PM_DUP_UNLESS_POPPED \
- if (!popped) PM_DUP;
-
-#define PM_PUTSELF \
- ADD_INSN(ret, &dummy_line_node, putself);
-
-#define PM_PUTNIL \
- ADD_INSN(ret, &dummy_line_node, putnil);
-
-#define PM_PUTNIL_UNLESS_POPPED \
- if (!popped) PM_PUTNIL;
-
-#define PM_SWAP \
- ADD_INSN(ret, &dummy_line_node, swap);
-
-#define PM_SWAP_UNLESS_POPPED \
- if (!popped) PM_SWAP;
-
-#define PM_NOP \
- ADD_INSN(ret, &dummy_line_node, nop);
-
-/**
- * We're using the top most bit of a pm_constant_id_t as a tag to represent an
- * anonymous local. When a child iseq is created and needs access to a value
- * that has yet to be defined, or is defined by the parent node's iseq. This can
- * be added to it's local table and then handled accordingly when compiling the
- * scope node associated with the child iseq.
- *
- * See the compilation process for PM_FOR_NODE: as an example, where the
- * variable referenced inside the StatementsNode is defined as part of the top
- * level ForLoop node.
-*/
-#define TEMP_CONSTANT_IDENTIFIER ((pm_constant_id_t)(1 << 31))
-
-rb_iseq_t *
-pm_iseq_new_with_opt(pm_scope_node_t *scope_node, pm_parser_t *parser, VALUE name, VALUE path, VALUE realpath,
- int first_lineno, const rb_iseq_t *parent, int isolated_depth,
- enum rb_iseq_type type, const rb_compile_option_t *option);
-
-static VALUE
-parse_integer(const pm_integer_node_t *node)
-{
- char *start = (char *) node->base.location.start;
- char *end = (char *) node->base.location.end;
-
- size_t length = end - start;
- int base = -10;
-
- switch (node->base.flags & (PM_INTEGER_BASE_FLAGS_BINARY | PM_INTEGER_BASE_FLAGS_DECIMAL | PM_INTEGER_BASE_FLAGS_OCTAL | PM_INTEGER_BASE_FLAGS_HEXADECIMAL)) {
- case PM_INTEGER_BASE_FLAGS_BINARY:
- base = 2;
- break;
- case PM_INTEGER_BASE_FLAGS_DECIMAL:
- base = 10;
- break;
- case PM_INTEGER_BASE_FLAGS_OCTAL:
- base = 8;
- break;
- case PM_INTEGER_BASE_FLAGS_HEXADECIMAL:
- base = 16;
- break;
- default:
- rb_bug("Unexpected integer base");
- }
-
- return rb_int_parse_cstr(start, length, &end, NULL, base, RB_INT_PARSE_DEFAULT);
-}
-
-static VALUE
-parse_float(const pm_node_t *node)
-{
- const uint8_t *start = node->location.start;
- const uint8_t *end = node->location.end;
- size_t length = end - start;
-
- char *buffer = malloc(length + 1);
- memcpy(buffer, start, length);
-
- buffer[length] = '\0';
- VALUE number = DBL2NUM(rb_cstr_to_dbl(buffer, 0));
-
- free(buffer);
- return number;
-}
-
-static VALUE
-parse_rational(const pm_node_t *node)
-{
- const uint8_t *start = node->location.start;
- const uint8_t *end = node->location.end - 1;
- size_t length = end - start;
-
- VALUE res;
- if (PM_NODE_TYPE_P(((pm_rational_node_t *)node)->numeric, PM_FLOAT_NODE)) {
- char *buffer = malloc(length + 1);
- memcpy(buffer, start, length);
-
- buffer[length] = '\0';
-
- char *decimal = memchr(buffer, '.', length);
- RUBY_ASSERT(decimal);
- size_t seen_decimal = decimal - buffer;
- size_t fraclen = length - seen_decimal - 1;
- memmove(decimal, decimal + 1, fraclen + 1);
-
- VALUE v = rb_cstr_to_inum(buffer, 10, false);
- res = rb_rational_new(v, rb_int_positive_pow(10, fraclen));
-
- free(buffer);
- }
- else {
- RUBY_ASSERT(PM_NODE_TYPE_P(((pm_rational_node_t *)node)->numeric, PM_INTEGER_NODE));
- VALUE number = rb_int_parse_cstr((const char *)start, length, NULL, NULL, -10, RB_INT_PARSE_DEFAULT);
- res = rb_rational_raw(number, INT2FIX(1));
- }
-
- return res;
-}
-
-static VALUE
-parse_imaginary(pm_imaginary_node_t *node)
-{
- VALUE imaginary_part;
- switch (PM_NODE_TYPE(node->numeric)) {
- case PM_FLOAT_NODE: {
- imaginary_part = parse_float(node->numeric);
- break;
- }
- case PM_INTEGER_NODE: {
- imaginary_part = parse_integer((pm_integer_node_t *) node->numeric);
- break;
- }
- case PM_RATIONAL_NODE: {
- imaginary_part = parse_rational(node->numeric);
- break;
- }
- default:
- rb_bug("Unexpected numeric type on imaginary number");
- }
-
- return rb_complex_raw(INT2FIX(0), imaginary_part);
-}
-
-static inline VALUE
-parse_string(pm_string_t *string, const pm_parser_t *parser)
-{
- rb_encoding *enc = rb_enc_from_index(rb_enc_find_index(parser->encoding->name));
- return rb_enc_str_new((const char *) pm_string_source(string), pm_string_length(string), enc);
-}
-
-/**
- * Certain strings can have their encoding differ from the parser's encoding due
- * to bytes or escape sequences that have the top bit set. This function handles
- * creating those strings based on the flags set on the owning node.
- */
-static inline VALUE
-parse_string_encoded(const pm_node_t *node, const pm_string_t *string, const pm_parser_t *parser) {
- rb_encoding *encoding;
-
- if (node->flags & PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING) {
- encoding = rb_ascii8bit_encoding();
- } else if (node->flags & PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING) {
- encoding = rb_utf8_encoding();
- } else {
- encoding = rb_enc_from_index(rb_enc_find_index(parser->encoding->name));
- }
-
- return rb_enc_str_new((const char *) pm_string_source(string), pm_string_length(string), encoding);
-}
-
-static inline ID
-parse_symbol(const uint8_t *start, const uint8_t *end, pm_parser_t *parser)
-{
- rb_encoding *enc = rb_enc_from_index(rb_enc_find_index(parser->encoding->name));
- return rb_intern3((const char *) start, end - start, enc);
-}
-
-static inline ID
-parse_string_symbol(const pm_string_t *string, pm_parser_t *parser)
-{
- const uint8_t *start = pm_string_source(string);
- return parse_symbol(start, start + pm_string_length(string), parser);
-}
-
-static inline ID
-parse_location_symbol(pm_location_t *location, pm_parser_t *parser)
-{
- return parse_symbol(location->start, location->end, parser);
-}
-
-static int
-pm_optimizable_range_item_p(pm_node_t *node)
-{
- return (!node || PM_NODE_TYPE_P(node, PM_INTEGER_NODE) || PM_NODE_TYPE_P(node, PM_NIL_NODE));
-}
-
-#define RE_OPTION_ENCODING_SHIFT 8
-
-/**
- * Check the prism flags of a regular expression-like node and return the flags
- * that are expected by the CRuby VM.
- */
-static int
-pm_reg_flags(const pm_node_t *node) {
- int flags = 0;
- int dummy = 0;
-
- // Check "no encoding" first so that flags don't get clobbered
- // We're calling `rb_char_to_option_kcode` in this case so that
- // we don't need to have access to `ARG_ENCODING_NONE`
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) {
- rb_char_to_option_kcode('n', &flags, &dummy);
- }
-
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) {
- rb_char_to_option_kcode('e', &flags, &dummy);
- flags |= ('e' << RE_OPTION_ENCODING_SHIFT);
- }
-
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) {
- rb_char_to_option_kcode('s', &flags, &dummy);
- flags |= ('s' << RE_OPTION_ENCODING_SHIFT);
- }
-
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) {
- rb_char_to_option_kcode('u', &flags, &dummy);
- flags |= ('u' << RE_OPTION_ENCODING_SHIFT);
- }
-
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) {
- flags |= ONIG_OPTION_IGNORECASE;
- }
-
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) {
- flags |= ONIG_OPTION_MULTILINE;
- }
-
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) {
- flags |= ONIG_OPTION_EXTEND;
- }
-
- return flags;
-}
-
-static rb_encoding *
-pm_reg_enc(const pm_regular_expression_node_t *node, const pm_parser_t *parser) {
- if (node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) {
- return rb_ascii8bit_encoding();
- }
-
- if (node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) {
- return rb_enc_get_from_index(ENCINDEX_EUC_JP);
- }
-
- if (node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) {
- return rb_enc_get_from_index(ENCINDEX_Windows_31J);
- }
-
- if (node->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) {
- return rb_utf8_encoding();
- }
-
- return rb_enc_from_index(rb_enc_find_index(parser->encoding->name));
-}
-
-/**
- * Certain nodes can be compiled literally, which can lead to further
- * optimizations. These nodes will all have the PM_NODE_FLAG_STATIC_LITERAL flag
- * set.
- */
-static inline bool
-pm_static_literal_p(const pm_node_t *node)
-{
- return node->flags & PM_NODE_FLAG_STATIC_LITERAL;
-}
-
-static VALUE
-pm_new_regex(pm_regular_expression_node_t * cast, const pm_parser_t * parser) {
- VALUE regex_str = parse_string(&cast->unescaped, parser);
- rb_encoding * enc = pm_reg_enc(cast, parser);
-
- return rb_enc_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), enc, pm_reg_flags((const pm_node_t *)cast));
-}
-
-/**
- * Certain nodes can be compiled literally. This function returns the literal
- * value described by the given node. For example, an array node with all static
- * literal values can be compiled into a literal array.
- */
-static inline VALUE
-pm_static_literal_value(const pm_node_t *node, pm_scope_node_t *scope_node, pm_parser_t *parser)
-{
- // Every node that comes into this function should already be marked as
- // static literal. If it's not, then we have a bug somewhere.
- assert(pm_static_literal_p(node));
-
- switch (PM_NODE_TYPE(node)) {
- case PM_ARRAY_NODE: {
- pm_array_node_t *cast = (pm_array_node_t *) node;
- pm_node_list_t *elements = &cast->elements;
-
- VALUE value = rb_ary_hidden_new(elements->size);
- for (size_t index = 0; index < elements->size; index++) {
- rb_ary_push(value, pm_static_literal_value(elements->nodes[index], scope_node, parser));
- }
-
- OBJ_FREEZE(value);
- return value;
- }
- case PM_FALSE_NODE:
- return Qfalse;
- case PM_FLOAT_NODE:
- return parse_float(node);
- case PM_HASH_NODE: {
- pm_hash_node_t *cast = (pm_hash_node_t *) node;
- pm_node_list_t *elements = &cast->elements;
-
- VALUE array = rb_ary_hidden_new(elements->size * 2);
- for (size_t index = 0; index < elements->size; index++) {
- assert(PM_NODE_TYPE_P(elements->nodes[index], PM_ASSOC_NODE));
- pm_assoc_node_t *cast = (pm_assoc_node_t *) elements->nodes[index];
- VALUE pair[2] = { pm_static_literal_value(cast->key, scope_node, parser), pm_static_literal_value(cast->value, scope_node, parser) };
- rb_ary_cat(array, pair, 2);
- }
-
- VALUE value = rb_hash_new_with_size(elements->size);
- rb_hash_bulk_insert(RARRAY_LEN(array), RARRAY_CONST_PTR(array), value);
-
- value = rb_obj_hide(value);
- OBJ_FREEZE(value);
- return value;
- }
- case PM_IMAGINARY_NODE:
- return parse_imaginary((pm_imaginary_node_t *) node);
- case PM_INTEGER_NODE:
- return parse_integer((pm_integer_node_t *) node);
- case PM_NIL_NODE:
- return Qnil;
- case PM_RATIONAL_NODE:
- return parse_rational(node);
- case PM_REGULAR_EXPRESSION_NODE: {
- pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
-
- return pm_new_regex(cast, parser);
- }
- case PM_SOURCE_ENCODING_NODE: {
- rb_encoding *encoding = rb_find_encoding(rb_str_new_cstr(scope_node->parser->encoding->name));
- if (!encoding) rb_bug("Encoding not found!");
- return rb_enc_from_encoding(encoding);
- }
- case PM_SOURCE_FILE_NODE: {
- pm_source_file_node_t *cast = (pm_source_file_node_t *)node;
- return cast->filepath.length ? parse_string(&cast->filepath, parser) : rb_fstring_lit("<compiled>");
- }
- case PM_SOURCE_LINE_NODE: {
- int source_line = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line;
- // Ruby treats file lines as 1-indexed
- // TODO: Incorporate options which allow for passing a line number
- source_line += 1;
- return INT2FIX(source_line);
- }
- case PM_STRING_NODE:
- return parse_string(&((pm_string_node_t *) node)->unescaped, parser);
- case PM_SYMBOL_NODE:
- return ID2SYM(parse_string_symbol(&((pm_symbol_node_t *) node)->unescaped, parser));
- case PM_TRUE_NODE:
- return Qtrue;
- default:
- rb_raise(rb_eArgError, "Don't have a literal value for this type");
- return Qfalse;
- }
-}
-
-/**
- * Currently, the ADD_INSN family of macros expects a NODE as the second
- * parameter. It uses this node to determine the line number and the node ID for
- * the instruction.
- *
- * Because prism does not use the NODE struct (or have node IDs for that matter)
- * we need to generate a dummy node to pass to these macros. We also need to use
- * the line number from the node to generate labels.
- *
- * We use this struct to store the dummy node and the line number together so
- * that we can use it while we're compiling code.
- *
- * In the future, we'll need to eventually remove this dependency and figure out
- * a more permanent solution. For the line numbers, this shouldn't be too much
- * of a problem, we can redefine the ADD_INSN family of macros. For the node ID,
- * we can probably replace it directly with the column information since we have
- * that at the time that we're generating instructions. In theory this could
- * make node ID unnecessary.
- */
-typedef struct {
- NODE node;
- int lineno;
-} pm_line_node_t;
-
-/**
- * The function generates a dummy node and stores the line number after it looks
- * it up for the given scope and node. (The scope in this case is just used
- * because it holds a reference to the parser, which holds a reference to the
- * newline list that we need to look up the line numbers.)
- */
-static void
-pm_line_node(pm_line_node_t *line_node, const pm_scope_node_t *scope_node, const pm_node_t *node)
-{
- // First, clear out the pointer.
- memset(line_node, 0, sizeof(pm_line_node_t));
-
- // Next, retrieve the line and column information from prism.
- pm_line_column_t line_column = pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start);
-
- // Next, use the line number for the dummy node.
- int lineno = (int) line_column.line;
-
- nd_set_line(&line_node->node, lineno);
- nd_set_node_id(&line_node->node, lineno);
- line_node->lineno = lineno;
-}
-
-static void
-pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond,
- LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_scope_node_t *scope_node);
-
-static void
-pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond,
- LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_scope_node_t *scope_node)
-{
- pm_parser_t *parser = scope_node->parser;
- pm_newline_list_t newline_list = parser->newline_list;
- int lineno = (int)pm_newline_list_line_column(&newline_list, cond->location.start).line;
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
-
- DECL_ANCHOR(seq);
- INIT_ANCHOR(seq);
- LABEL *label = NEW_LABEL(lineno);
- if (!then_label) then_label = label;
- else if (!else_label) else_label = label;
-
- pm_compile_branch_condition(iseq, seq, cond, then_label, else_label, src, popped, scope_node);
-
- if (LIST_INSN_SIZE_ONE(seq)) {
- INSN *insn = (INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(seq));
- if (insn->insn_id == BIN(jump) && (LABEL *)(insn->operands[0]) == label)
- return;
- }
- if (!label->refcnt) {
- PM_PUTNIL;
- }
- else {
- ADD_LABEL(seq, label);
- }
- ADD_SEQ(ret, seq);
- return;
-}
-
-static void pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node);
-
-static void
-pm_compile_flip_flop(pm_flip_flop_node_t *flip_flop_node, LABEL *else_label, LABEL *then_label, rb_iseq_t *iseq, const int lineno, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node)
-{
- NODE dummy_line_node = generate_dummy_line_node(ISEQ_BODY(iseq)->location.first_lineno, -1);
- LABEL *lend = NEW_LABEL(lineno);
-
- int again = !(flip_flop_node->base.flags & PM_RANGE_FLAGS_EXCLUDE_END);
-
- rb_num_t count = ISEQ_FLIP_CNT_INCREMENT(ISEQ_BODY(iseq)->local_iseq) + VM_SVAR_FLIPFLOP_START;
- VALUE key = INT2FIX(count);
-
- ADD_INSN2(ret, &dummy_line_node, getspecial, key, INT2FIX(0));
- ADD_INSNL(ret, &dummy_line_node, branchif, lend);
-
- if (flip_flop_node->left) {
- PM_COMPILE(flip_flop_node->left);
- }
- else {
- PM_PUTNIL;
- }
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, else_label);
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, setspecial, key);
- if (!again) {
- ADD_INSNL(ret, &dummy_line_node, jump, then_label);
- }
-
- ADD_LABEL(ret, lend);
- if (flip_flop_node->right) {
- PM_COMPILE(flip_flop_node->right);
- }
- else {
- PM_PUTNIL;
- }
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, then_label);
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
- ADD_INSN1(ret, &dummy_line_node, setspecial, key);
- ADD_INSNL(ret, &dummy_line_node, jump, then_label);
-}
-
-void pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *defined_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition);
-static void
-pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond,
- LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_scope_node_t *scope_node)
-{
- pm_parser_t *parser = scope_node->parser;
- pm_newline_list_t newline_list = parser->newline_list;
- int lineno = (int) pm_newline_list_line_column(&newline_list, cond->location.start).line;
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
-
-again:
- switch (PM_NODE_TYPE(cond)) {
- case PM_AND_NODE: {
- pm_and_node_t *and_node = (pm_and_node_t *)cond;
- pm_compile_logical(iseq, ret, and_node->left, NULL, else_label, src, popped, scope_node);
- cond = and_node->right;
- goto again;
- }
- case PM_OR_NODE: {
- pm_or_node_t *or_node = (pm_or_node_t *)cond;
- pm_compile_logical(iseq, ret, or_node->left, then_label, NULL, src, popped, scope_node);
- cond = or_node->right;
- goto again;
- }
- case PM_FALSE_NODE:
- case PM_NIL_NODE:
- ADD_INSNL(ret, &dummy_line_node, jump, else_label);
- return;
- case PM_FLOAT_NODE:
- case PM_IMAGINARY_NODE:
- case PM_INTEGER_NODE:
- case PM_LAMBDA_NODE:
- case PM_RATIONAL_NODE:
- case PM_REGULAR_EXPRESSION_NODE:
- case PM_STRING_NODE:
- case PM_SYMBOL_NODE:
- case PM_TRUE_NODE:
- ADD_INSNL(ret, &dummy_line_node, jump, then_label);
- return;
- case PM_FLIP_FLOP_NODE:
- pm_compile_flip_flop((pm_flip_flop_node_t *)cond, else_label, then_label, iseq, lineno, ret, src, popped, scope_node);
- return;
- // TODO: Several more nodes in this case statement
- case PM_DEFINED_NODE: {
- pm_defined_node_t *defined_node = (pm_defined_node_t *)cond;
- pm_compile_defined_expr(iseq, defined_node->value, ret, src, popped, scope_node, dummy_line_node, lineno, true);
- break;
- }
- default: {
- DECL_ANCHOR(cond_seq);
- INIT_ANCHOR(cond_seq);
-
- pm_compile_node(iseq, cond, cond_seq, src, false, scope_node);
- ADD_SEQ(ret, cond_seq);
- break;
- }
- }
- ADD_INSNL(ret, &dummy_line_node, branchunless, else_label);
- ADD_INSNL(ret, &dummy_line_node, jump, then_label);
- return;
-}
-
-static void
-pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, pm_node_t *node_else, pm_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node)
-{
- NODE dummy_line_node = generate_dummy_line_node(line, line);
-
- DECL_ANCHOR(cond_seq);
-
- LABEL *then_label, *else_label, *end_label;
-
- INIT_ANCHOR(cond_seq);
- then_label = NEW_LABEL(line);
- else_label = NEW_LABEL(line);
- end_label = 0;
-
- pm_compile_branch_condition(iseq, cond_seq, predicate, then_label, else_label, src, false, scope_node);
- ADD_SEQ(ret, cond_seq);
-
- if (then_label->refcnt) {
- ADD_LABEL(ret, then_label);
-
- DECL_ANCHOR(then_seq);
- INIT_ANCHOR(then_seq);
- if (node_body) {
- pm_compile_node(iseq, (pm_node_t *)node_body, then_seq, src, popped, scope_node);
- } else {
- PM_PUTNIL_UNLESS_POPPED;
- }
-
- if (else_label->refcnt) {
- end_label = NEW_LABEL(line);
- ADD_INSNL(then_seq, &dummy_line_node, jump, end_label);
- if (!popped) {
- ADD_INSN(then_seq, &dummy_line_node, pop);
- }
- }
- ADD_SEQ(ret, then_seq);
- }
-
- if (else_label->refcnt) {
- ADD_LABEL(ret, else_label);
-
- DECL_ANCHOR(else_seq);
- INIT_ANCHOR(else_seq);
- if (node_else) {
- pm_compile_node(iseq, (pm_node_t *)node_else, else_seq, src, popped, scope_node);
- }
- else {
- PM_PUTNIL_UNLESS_POPPED;
- }
-
- ADD_SEQ(ret, else_seq);
- }
-
- if (end_label) {
- ADD_LABEL(ret, end_label);
- }
-
- return;
-}
-
-static void
-pm_compile_while(rb_iseq_t *iseq, int lineno, pm_node_flags_t flags, enum pm_node_type type, pm_statements_node_t *statements, pm_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node)
-{
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
-
- LABEL *prev_start_label = ISEQ_COMPILE_DATA(iseq)->start_label;
- LABEL *prev_end_label = ISEQ_COMPILE_DATA(iseq)->end_label;
- LABEL *prev_redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label;
-
- // TODO: Deal with ensures in here
- LABEL *next_label = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(lineno); /* next */
- LABEL *redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label = NEW_LABEL(lineno); /* redo */
- LABEL *break_label = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(lineno); /* break */
- LABEL *end_label = NEW_LABEL(lineno);
- LABEL *adjust_label = NEW_LABEL(lineno);
-
- LABEL *next_catch_label = NEW_LABEL(lineno);
- LABEL *tmp_label = NULL;
-
- // begin; end while true
- if (flags & PM_LOOP_FLAGS_BEGIN_MODIFIER) {
- tmp_label = NEW_LABEL(lineno);
- ADD_INSNL(ret, &dummy_line_node, jump, tmp_label);
- }
- else {
- // while true; end
- ADD_INSNL(ret, &dummy_line_node, jump, next_label);
- }
-
- ADD_LABEL(ret, adjust_label);
- PM_PUTNIL;
- ADD_LABEL(ret, next_catch_label);
- PM_POP;
- ADD_INSNL(ret, &dummy_line_node, jump, next_label);
- if (tmp_label) ADD_LABEL(ret, tmp_label);
-
- ADD_LABEL(ret, redo_label);
- if (statements) {
- PM_COMPILE_POPPED((pm_node_t *)statements);
- }
-
- ADD_LABEL(ret, next_label);
-
- if (type == PM_WHILE_NODE) {
- pm_compile_branch_condition(iseq, ret, predicate, redo_label, end_label, src, popped, scope_node);
- } else if (type == PM_UNTIL_NODE) {
- pm_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, scope_node);
- }
-
- ADD_LABEL(ret, end_label);
- ADD_ADJUST_RESTORE(ret, adjust_label);
-
- PM_PUTNIL;
-
- ADD_LABEL(ret, break_label);
-
- PM_POP_IF_POPPED;
-
- ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label, NULL,
- break_label);
- ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, redo_label, break_label, NULL,
- next_catch_label);
- ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, NULL,
- ISEQ_COMPILE_DATA(iseq)->redo_label);
-
- ISEQ_COMPILE_DATA(iseq)->start_label = prev_start_label;
- ISEQ_COMPILE_DATA(iseq)->end_label = prev_end_label;
- ISEQ_COMPILE_DATA(iseq)->redo_label = prev_redo_label;
- return;
-}
-
-static void
-pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, pm_parser_t *parser)
-{
- size_t parts_size = parts->size;
-
- if (parts_size > 0) {
- for (size_t index = 0; index < parts_size; index++) {
- pm_node_t *part = parts->nodes[index];
-
- if (PM_NODE_TYPE_P(part, PM_STRING_NODE)) {
- pm_string_node_t *string_node = (pm_string_node_t *) part;
- ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&string_node->unescaped, parser));
- }
- else {
- PM_COMPILE_NOT_POPPED(part);
- PM_DUP;
- ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE));
- ADD_INSN(ret, &dummy_line_node, anytostring);
- }
- }
- }
- else {
- PM_PUTNIL;
- }
-}
-
-// This recurses through scopes and finds the local index at any scope level
-// It also takes a pointer to depth, and increments depth appropriately
-// according to the depth of the local
-static int
-pm_lookup_local_index_any_scope(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
-{
- if (!scope_node) {
- // We have recursed up all scope nodes
- // and have not found the local yet
- rb_bug("This local does not exist");
- }
-
- st_data_t local_index;
-
- if (!st_lookup(scope_node->index_lookup_table, constant_id, &local_index)) {
- // Local does not exist at this level, continue recursing up
- return pm_lookup_local_index_any_scope(iseq, scope_node->previous, constant_id);
- }
-
- return scope_node->local_table_for_iseq_size - (int)local_index;
-}
-
-static int
-pm_lookup_local_index(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
-{
- st_data_t local_index;
-
- if (!st_lookup(scope_node->index_lookup_table, constant_id, &local_index)) {
- rb_bug("This local does not exist");
- }
-
- return scope_node->local_table_for_iseq_size - (int)local_index;
-}
-
-static int
-pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id, uint32_t depth)
-{
- for(uint32_t i = 0; i < depth; i++) {
- scope_node = scope_node->previous;
- iseq = (rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq;
- }
-
- return pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
-}
-
-// This returns the CRuby ID which maps to the pm_constant_id_t
-//
-// Constant_ids in prism are indexes of the constants in prism's constant pool.
-// We add a constants mapping on the scope_node which is a mapping from
-// these constant_id indexes to the CRuby IDs that they represent.
-// This helper method allows easy access to those IDs
-static ID
-pm_constant_id_lookup(pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
-{
- if (constant_id < 1 || constant_id > scope_node->parser->constant_pool.size) {
- rb_bug("[PRISM] constant_id out of range: %u", (unsigned int)constant_id);
- }
- return scope_node->constants[constant_id - 1];
-}
-
-static rb_iseq_t *
-pm_new_child_iseq(rb_iseq_t *iseq, pm_scope_node_t node, pm_parser_t *parser,
- VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no)
-{
- debugs("[new_child_iseq]> ---------------------------------------\n");
- int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
- rb_iseq_t * ret_iseq = pm_iseq_new_with_opt(&node, parser, name,
- rb_iseq_path(iseq), rb_iseq_realpath(iseq),
- line_no, parent,
- isolated_depth ? isolated_depth + 1 : 0,
- type, ISEQ_COMPILE_DATA(iseq)->option);
- debugs("[new_child_iseq]< ---------------------------------------\n");
- return ret_iseq;
-}
-
-static int
-pm_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const pm_node_t *constant_path_node, const NODE *line_node, const uint8_t * src, bool popped, pm_scope_node_t *scope_node)
-{
- if (PM_NODE_TYPE_P(constant_path_node, PM_CONSTANT_PATH_NODE)) {
- pm_node_t *parent = ((pm_constant_path_node_t *)constant_path_node)->parent;
- if (parent) {
- /* Bar::Foo */
- PM_COMPILE(parent);
- return VM_DEFINECLASS_FLAG_SCOPED;
- }
- else {
- /* toplevel class ::Foo */
- ADD_INSN1(ret, line_node, putobject, rb_cObject);
- return VM_DEFINECLASS_FLAG_SCOPED;
- }
- }
- else {
- /* class at cbase Foo */
- ADD_INSN1(ret, line_node, putspecialobject,
- INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- return 0;
- }
-}
-
-static void
-pm_compile_call_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t *value, pm_constant_id_t write_name, pm_constant_id_t read_name, bool safe_nav, LINK_ANCHOR *const ret, rb_iseq_t *iseq, int lineno, const uint8_t * src, bool popped, pm_scope_node_t *scope_node)
-{
- LABEL *call_end_label = NEW_LABEL(lineno);
- LABEL *else_label = NEW_LABEL(lineno);
- LABEL *end_label = NEW_LABEL(lineno);
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
-
- int flag = 0;
-
- if (PM_NODE_TYPE_P(receiver, PM_SELF_NODE)) {
- flag = VM_CALL_FCALL;
- }
-
- PM_COMPILE_NOT_POPPED(receiver);
-
- if (safe_nav) {
- PM_DUP;
- ADD_INSNL(ret, &dummy_line_node, branchnil, else_label);
- }
-
- ID write_name_id = pm_constant_id_lookup(scope_node, write_name);
- ID read_name_id = pm_constant_id_lookup(scope_node, read_name);
- PM_DUP;
-
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, read_name_id, INT2FIX(0), INT2FIX(flag));
-
- PM_DUP_UNLESS_POPPED;
-
- if (and_node) {
- ADD_INSNL(ret, &dummy_line_node, branchunless, call_end_label);
- }
- else {
- // or_node
- ADD_INSNL(ret, &dummy_line_node, branchif, call_end_label);
- }
-
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(value);
- if (!popped) {
- PM_SWAP;
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- }
- ID aid = rb_id_attrset(write_name_id);
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, aid, INT2FIX(1), INT2FIX(flag));
- ADD_INSNL(ret, &dummy_line_node, jump, end_label);
- ADD_LABEL(ret, call_end_label);
-
- if (!popped) {
- PM_SWAP;
- }
-
- if (safe_nav) {
- ADD_LABEL(ret, else_label);
- }
-
- ADD_LABEL(ret, end_label);
- PM_POP;
- return;
-}
-
-static void
-pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE dummy_line_node, VALUE argc, int flag, int block_offset)
-{
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
- }
-
- if (flag & VM_CALL_ARGS_SPLAT) {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(1));
- if (block_offset > 0) {
- ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(3));
- PM_SWAP;
- PM_POP;
- }
- ADD_INSN(ret, &dummy_line_node, concatarray);
- if (block_offset > 0) {
- ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
- PM_POP;
- }
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc, INT2FIX(flag));
- }
- else {
- if (block_offset > 0) {
- PM_SWAP;
- }
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
- }
-
- PM_POP;
- return;
-}
-
-static int
-pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, pm_parser_t *parser)
-{
- int orig_argc = 0;
- if (arguments_node == NULL) {
- if (*flags & VM_CALL_FCALL) {
- *flags |= VM_CALL_VCALL;
- }
- }
- else {
- pm_node_list_t arguments_node_list = arguments_node->arguments;
-
- bool has_keyword_splat = (arguments_node->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
- bool has_splat = false;
-
- // We count the number of elements post the splat node that are not keyword elements to
- // eventually pass as an argument to newarray
- int post_splat_counter = 0;
-
- for (size_t index = 0; index < arguments_node_list.size; index++) {
- pm_node_t *argument = arguments_node_list.nodes[index];
-
- switch (PM_NODE_TYPE(argument)) {
- // A keyword hash node contains all keyword arguments as AssocNodes and AssocSplatNodes
- case PM_KEYWORD_HASH_NODE: {
- pm_keyword_hash_node_t *keyword_arg = (pm_keyword_hash_node_t *)argument;
- size_t len = keyword_arg->elements.size;
-
- if (has_keyword_splat) {
- int cur_hash_size = 0;
- orig_argc++;
-
- bool new_hash_emitted = false;
- for (size_t i = 0; i < len; i++) {
- pm_node_t *cur_node = keyword_arg->elements.nodes[i];
-
- pm_node_type_t cur_type = PM_NODE_TYPE(cur_node);
-
- switch (PM_NODE_TYPE(cur_node)) {
- case PM_ASSOC_NODE: {
- pm_assoc_node_t *assoc = (pm_assoc_node_t *)cur_node;
-
- PM_COMPILE_NOT_POPPED(assoc->key);
- PM_COMPILE_NOT_POPPED(assoc->value);
- cur_hash_size++;
-
- // If we're at the last keyword arg, or the last assoc node of this "set",
- // then we want to either construct a newhash or merge onto previous hashes
- if (i == (len - 1) || !PM_NODE_TYPE_P(keyword_arg->elements.nodes[i + 1], cur_type)) {
- if (new_hash_emitted) {
- ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_ptr, INT2FIX(cur_hash_size * 2 + 1));
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(cur_hash_size * 2));
- cur_hash_size = 0;
- new_hash_emitted = true;
- }
- }
-
- break;
- }
- case PM_ASSOC_SPLAT_NODE: {
- if (len > 1) {
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- if (i == 0) {
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(0));
- new_hash_emitted = true;
- }
- else {
- PM_SWAP;
- }
-
- *flags |= VM_CALL_KW_SPLAT_MUT;
- }
-
- pm_assoc_splat_node_t *assoc_splat = (pm_assoc_splat_node_t *)cur_node;
- PM_COMPILE_NOT_POPPED(assoc_splat->value);
-
- *flags |= VM_CALL_KW_SPLAT;
-
- if (len > 1) {
- ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd, INT2FIX(2));
- }
-
- if ((i < len - 1) && !PM_NODE_TYPE_P(keyword_arg->elements.nodes[i + 1], cur_type)) {
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- PM_SWAP;
- }
-
- cur_hash_size = 0;
- break;
- }
- default: {
- rb_bug("Unknown type");
- }
- }
- }
- break;
- }
- else {
- // We need to first figure out if all elements of the KeywordHashNode are AssocNodes
- // with symbol keys.
- if (PM_NODE_FLAG_P(keyword_arg, PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS)) {
- // If they are all symbol keys then we can pass them as keyword arguments.
- *kw_arg = rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
- *flags |= VM_CALL_KWARG;
- VALUE *keywords = (*kw_arg)->keywords;
- (*kw_arg)->references = 0;
- (*kw_arg)->keyword_len = (int)len;
-
- for (size_t i = 0; i < len; i++) {
- pm_assoc_node_t *assoc = (pm_assoc_node_t *)keyword_arg->elements.nodes[i];
- pm_node_t *key = assoc->key;
- keywords[i] = pm_static_literal_value(key, scope_node, parser);
- PM_COMPILE_NOT_POPPED(assoc->value);
- }
- } else {
- // If they aren't all symbol keys then we need to construct a new hash
- // and pass that as an argument.
- orig_argc++;
- *flags |= VM_CALL_KW_SPLAT;
- if (len > 1) {
- // A new hash will be created for the keyword arguments in this case,
- // so mark the method as passing mutable keyword splat.
- *flags |= VM_CALL_KW_SPLAT_MUT;
- }
-
- for (size_t i = 0; i < len; i++) {
- pm_assoc_node_t *assoc = (pm_assoc_node_t *)keyword_arg->elements.nodes[i];
- PM_COMPILE_NOT_POPPED(assoc->key);
- PM_COMPILE_NOT_POPPED(assoc->value);
- }
-
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(len * 2));
- }
- }
- break;
- }
- case PM_SPLAT_NODE: {
- *flags |= VM_CALL_ARGS_SPLAT;
- pm_splat_node_t *splat_node = (pm_splat_node_t *)argument;
- if (splat_node->expression) {
- orig_argc++;
- PM_COMPILE_NOT_POPPED(splat_node->expression);
- }
-
- ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
-
- has_splat = true;
- post_splat_counter = 0;
-
- break;
- }
- case PM_FORWARDING_ARGUMENTS_NODE: {
- orig_argc++;
- *flags |= VM_CALL_ARGS_BLOCKARG | VM_CALL_ARGS_SPLAT;
- ADD_GETLOCAL(ret, &dummy_line_node, 3, 0);
- ADD_INSN1(ret, &dummy_line_node, splatarray, RBOOL(arguments_node_list.size > 1));
- ADD_INSN2(ret, &dummy_line_node, getblockparamproxy, INT2FIX(4), INT2FIX(0));
- break;
- }
- default: {
- orig_argc++;
- post_splat_counter++;
- PM_COMPILE_NOT_POPPED(argument);
-
- if (has_splat) {
- // If the next node starts the keyword section of parameters
- if ((index < arguments_node_list.size - 1) && PM_NODE_TYPE_P(arguments_node_list.nodes[index + 1], PM_KEYWORD_HASH_NODE)) {
-
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(post_splat_counter));
- ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
- ADD_INSN(ret, &dummy_line_node, concatarray);
- }
- // If it's the final node
- else if (index == arguments_node_list.size - 1) {
- if (post_splat_counter > 1) {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(post_splat_counter));
- ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
- ADD_INSN(ret, &dummy_line_node, concatarray);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(post_splat_counter));
- ADD_INSN(ret, &dummy_line_node, concatarray);
- }
- orig_argc = 1;
- }
- }
- }
- }
- }
- }
- return orig_argc;
-}
-
-static void
-pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t *value, pm_arguments_node_t *arguments, pm_node_t *block, LINK_ANCHOR *const ret, rb_iseq_t *iseq, int lineno, const uint8_t * src, bool popped, pm_scope_node_t *scope_node, pm_parser_t *parser)
-{
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
- PM_PUTNIL_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(receiver);
-
- int flag = 0;
- int argc_int = 0;
-
- if (arguments) {
- // Get any arguments, and set the appropriate values for flag
- argc_int = pm_setup_args(arguments, &flag, NULL, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
- }
-
- VALUE argc = INT2FIX(argc_int);
- int block_offset = 0;
-
- if (block) {
- PM_COMPILE_NOT_POPPED(block);
- flag |= VM_CALL_ARGS_BLOCKARG;
- block_offset = 1;
- }
-
- ADD_INSN1(ret, &dummy_line_node, dupn, FIXNUM_INC(argc, 1 + block_offset));
-
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, argc, INT2FIX(flag));
-
- LABEL *label = NEW_LABEL(lineno);
- LABEL *lfin = NEW_LABEL(lineno);
-
- PM_DUP;
-
- if (and_node) {
- ADD_INSNL(ret, &dummy_line_node, branchunless, label);
- }
- else {
- // ornode
- ADD_INSNL(ret, &dummy_line_node, branchif, label);
- }
-
- PM_POP;
-
- PM_COMPILE_NOT_POPPED(value);
-
- pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset);
-
- ADD_INSNL(ret, &dummy_line_node, jump, lfin);
- ADD_LABEL(ret, label);
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
- }
- ADD_INSN1(ret, &dummy_line_node, adjuststack, FIXNUM_INC(argc, 2 + block_offset));
- ADD_LABEL(ret, lfin);
-
- return;
-}
-
-/**
- * In order to properly compile multiple-assignment, some preprocessing needs to
- * be performed in the case of call or constant path targets. This is when they
- * are read, the "parent" of each of these nodes should only be read once (the
- * receiver in the case of a call, the parent constant in the case of a constant
- * path).
- */
-static uint8_t
-pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const uint8_t *src, bool popped, const pm_node_t *node, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, uint8_t pushed, bool nested)
-{
- switch (PM_NODE_TYPE(node)) {
- case PM_INDEX_TARGET_NODE: {
- pm_index_target_node_t *cast = (pm_index_target_node_t *)node;
- PM_COMPILE_NOT_POPPED((pm_node_t *)cast->receiver);
- pushed++;
-
- if (cast->arguments) {
- for (size_t i = 0; i < cast->arguments->arguments.size; i++) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)cast->arguments->arguments.nodes[i]);
- }
- pushed += cast->arguments->arguments.size;
- }
- break;
- }
- case PM_CALL_TARGET_NODE: {
- pm_call_target_node_t *cast = (pm_call_target_node_t *)node;
- PM_COMPILE_NOT_POPPED((pm_node_t *)cast->receiver);
- pushed++;
- break;
- }
- case PM_MULTI_TARGET_NODE: {
- pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node;
- for (size_t index = 0; index < cast->lefts.size; index++) {
- pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->lefts.nodes[index], ret, scope_node, pushed, false);
- }
- break;
- }
- case PM_CONSTANT_PATH_TARGET_NODE: {
- pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *)node;
- if (cast->parent) {
- PM_PUTNIL;
- pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->parent, ret, scope_node, pushed, false);
- } else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
- break;
- }
- case PM_CONSTANT_PATH_NODE: {
- pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node;
- if (cast->parent) {
- pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->parent, ret, scope_node, pushed, false);
- } else {
- PM_POP;
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
- pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->child, ret, scope_node, pushed, cast->parent);
- break;
- }
- case PM_CONSTANT_READ_NODE: {
- pm_constant_read_node_t *cast = (pm_constant_read_node_t *) node;
- ADD_INSN1(ret, &dummy_line_node, putobject, RBOOL(!nested));
- ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, cast->name)));
- pushed = pushed + 2;
- break;
- }
- default:
- break;
- }
-
- return pushed;
-}
-
-// When we compile a pattern matching expression, we use the stack as a scratch
-// space to store lots of different values (consider it like we have a pattern
-// matching function and we need space for a bunch of different local
-// variables). The "base index" refers to the index on the stack where we
-// started compiling the pattern matching expression. These offsets from that
-// base index indicate the location of the various locals we need.
-#define PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE 0
-#define PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING 1
-#define PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P 2
-#define PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE 3
-#define PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY 4
-
-// A forward declaration because this is the recursive function that handles
-// compiling a pattern. It can be reentered by nesting patterns, as in the case
-// of arrays or hashes.
-static int pm_compile_pattern(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, LABEL *matched_label, LABEL *unmatched_label, bool in_single_pattern, bool in_alternation_pattern, bool use_deconstructed_cache, unsigned int base_index);
-
-/**
- * This function generates the code to set up the error string and error_p
- * locals depending on whether or not the pattern matched.
- */
-static int
-pm_compile_pattern_generic_error(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, VALUE message, unsigned int base_index)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
-
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, message);
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_SEND(ret, &line.node, id_core_sprintf, INT2FIX(2));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
-
- ADD_INSN1(ret, &line.node, putobject, Qfalse);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN(ret, &line.node, pop);
- ADD_LABEL(ret, match_succeeded_label);
-
- return COMPILE_OK;
-}
-
-/**
- * This function generates the code to set up the error string and error_p
- * locals depending on whether or not the pattern matched when the value needs
- * to match a specific deconstructed length.
- */
-static int
-pm_compile_pattern_length_error(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, VALUE message, VALUE length, unsigned int base_index)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
-
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, message);
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idLength, INT2FIX(0));
- ADD_INSN1(ret, &line.node, putobject, length);
- ADD_SEND(ret, &line.node, id_core_sprintf, INT2FIX(4));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
-
- ADD_INSN1(ret, &line.node, putobject, Qfalse);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN(ret, &line.node, pop);
- ADD_LABEL(ret, match_succeeded_label);
-
- return COMPILE_OK;
-}
-
-/**
- * This function generates the code to set up the error string and error_p
- * locals depending on whether or not the pattern matched when the value needs
- * to pass a specific #=== method call.
- */
-static int
-pm_compile_pattern_eqq_error(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, unsigned int base_index)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
-
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("%p === %p does not return true"));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(5));
- ADD_SEND(ret, &line.node, id_core_sprintf, INT2FIX(3));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
- ADD_INSN1(ret, &line.node, putobject, Qfalse);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN(ret, &line.node, pop);
-
- ADD_LABEL(ret, match_succeeded_label);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(2));
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN(ret, &line.node, pop);
-
- return COMPILE_OK;
-}
-
-/**
- * This is a variation on compiling a pattern matching expression that is used
- * to have the pattern matching instructions fall through to immediately after
- * the pattern if it passes. Otherwise it jumps to the given unmatched_label
- * label.
- */
-static int
-pm_compile_pattern_match(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, LABEL *unmatched_label, bool in_single_pattern, bool in_alternation_pattern, bool use_deconstructed_cache, unsigned int base_index)
-{
- LABEL *matched_label = NEW_LABEL(nd_line(node));
- CHECK(pm_compile_pattern(iseq, scope_node, node, ret, src, matched_label, unmatched_label, in_single_pattern, in_alternation_pattern, use_deconstructed_cache, base_index));
- ADD_LABEL(ret, matched_label);
- return COMPILE_OK;
-}
-
-/**
- * This function compiles in the code necessary to call #deconstruct on the
- * value to match against. It raises appropriate errors if the method does not
- * exist or if it returns the wrong type.
- */
-static int
-pm_compile_pattern_deconstruct(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, LABEL *deconstruct_label, LABEL *match_failed_label, LABEL *deconstructed_label, LABEL *type_error_label, bool in_single_pattern, bool use_deconstructed_cache, unsigned int base_index)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- if (use_deconstructed_cache) {
- ADD_INSN1(ret, &line.node, topn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE));
- ADD_INSNL(ret, &line.node, branchnil, deconstruct_label);
-
- ADD_INSN1(ret, &line.node, topn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE));
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN1(ret, &line.node, topn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE - 1));
- ADD_INSNL(ret, &line.node, jump, deconstructed_label);
- } else {
- ADD_INSNL(ret, &line.node, jump, deconstruct_label);
- }
-
- ADD_LABEL(ret, deconstruct_label);
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, putobject, ID2SYM(rb_intern("deconstruct")));
- ADD_SEND(ret, &line.node, idRespond_to, INT2FIX(1));
-
- if (use_deconstructed_cache) {
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE + 1));
- }
-
- if (in_single_pattern) {
- CHECK(pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit("%p does not respond to #deconstruct"), base_index + 1));
- }
-
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
- ADD_SEND(ret, &line.node, rb_intern("deconstruct"), INT2FIX(0));
-
- if (use_deconstructed_cache) {
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE));
- }
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, checktype, INT2FIX(T_ARRAY));
- ADD_INSNL(ret, &line.node, branchunless, type_error_label);
- ADD_LABEL(ret, deconstructed_label);
-
- return COMPILE_OK;
-}
-
-/**
- * This function compiles in the code necessary to match against the optional
- * constant path that is attached to an array, find, or hash pattern.
- */
-static int
-pm_compile_pattern_constant(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, LABEL *match_failed_label, bool in_single_pattern, unsigned int base_index)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- ADD_INSN(ret, &line.node, dup);
- PM_COMPILE_NOT_POPPED(node);
-
- if (in_single_pattern) {
- ADD_INSN1(ret, &line.node, dupn, INT2FIX(2));
- }
- ADD_INSN1(ret, &line.node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
- if (in_single_pattern) {
- CHECK(pm_compile_pattern_eqq_error(iseq, scope_node, node, ret, base_index + 3));
- }
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
- return COMPILE_OK;
-}
-
-/**
- * When matching fails, an appropriate error must be raised. This function is
- * responsible for compiling in those error raising instructions.
- */
-static void
-pm_compile_pattern_error_handler(rb_iseq_t *iseq, const pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, LABEL *done_label, bool popped)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- LABEL *key_error_label = NEW_LABEL(line.lineno);
- LABEL *cleanup_label = NEW_LABEL(line.lineno);
-
- struct rb_callinfo_kwarg *kw_arg = rb_xmalloc_mul_add(2, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
- kw_arg->references = 0;
- kw_arg->keyword_len = 2;
- kw_arg->keywords[0] = ID2SYM(rb_intern("matchee"));
- kw_arg->keywords[1] = ID2SYM(rb_intern("key"));
-
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
- ADD_INSNL(ret, &line.node, branchif, key_error_label);
-
- ADD_INSN1(ret, &line.node, putobject, rb_eNoMatchingPatternError);
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("%p: %s"));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(4));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 6));
- ADD_SEND(ret, &line.node, id_core_sprintf, INT2FIX(3));
- ADD_SEND(ret, &line.node, id_core_raise, INT2FIX(2));
- ADD_INSNL(ret, &line.node, jump, cleanup_label);
-
- ADD_LABEL(ret, key_error_label);
- ADD_INSN1(ret, &line.node, putobject, rb_eNoMatchingPatternKeyError);
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("%p: %s"));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(4));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 6));
- ADD_SEND(ret, &line.node, id_core_sprintf, INT2FIX(3));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE + 4));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY + 5));
- ADD_SEND_R(ret, &line.node, rb_intern("new"), INT2FIX(1), NULL, INT2FIX(VM_CALL_KWARG), kw_arg);
- ADD_SEND(ret, &line.node, id_core_raise, INT2FIX(1));
- ADD_LABEL(ret, cleanup_label);
-
- ADD_INSN1(ret, &line.node, adjuststack, INT2FIX(7));
- if (!popped) ADD_INSN(ret, &line.node, putnil);
- ADD_INSNL(ret, &line.node, jump, done_label);
- ADD_INSN1(ret, &line.node, dupn, INT2FIX(5));
- if (popped) ADD_INSN(ret, &line.node, putnil);
-}
-
-/**
- * Compile a pattern matching expression.
- */
-static int
-pm_compile_pattern(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, LABEL *matched_label, LABEL *unmatched_label, bool in_single_pattern, bool in_alternation_pattern, bool use_deconstructed_cache, unsigned int base_index)
-{
- pm_line_node_t line;
- pm_line_node(&line, scope_node, node);
-
- switch (PM_NODE_TYPE(node)) {
- case PM_ARRAY_PATTERN_NODE: {
- // Array patterns in pattern matching are triggered by using commas in
- // a pattern or wrapping it in braces. They are represented by a
- // ArrayPatternNode. This looks like:
- //
- // foo => [1, 2, 3]
- //
- // It can optionally have a splat in the middle of it, which can
- // optionally have a name attached.
- const pm_array_pattern_node_t *cast = (const pm_array_pattern_node_t *) node;
-
- const size_t requireds_size = cast->requireds.size;
- const size_t posts_size = cast->posts.size;
- const size_t minimum_size = requireds_size + posts_size;
-
- bool use_rest_size = (
- cast->rest != NULL &&
- PM_NODE_TYPE_P(cast->rest, PM_SPLAT_NODE) &&
- ((((const pm_splat_node_t *) cast->rest)->expression != NULL) || posts_size > 0)
- );
-
- LABEL *match_failed_label = NEW_LABEL(line.lineno);
- LABEL *type_error_label = NEW_LABEL(line.lineno);
- LABEL *deconstruct_label = NEW_LABEL(line.lineno);
- LABEL *deconstructed_label = NEW_LABEL(line.lineno);
-
- if (use_rest_size) {
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(0));
- ADD_INSN(ret, &line.node, swap);
- base_index++;
- }
-
- if (cast->constant != NULL) {
- CHECK(pm_compile_pattern_constant(iseq, scope_node, cast->constant, ret, src, match_failed_label, in_single_pattern, base_index));
- }
-
- CHECK(pm_compile_pattern_deconstruct(iseq, scope_node, node, ret, src, deconstruct_label, match_failed_label, deconstructed_label, type_error_label, in_single_pattern, use_deconstructed_cache, base_index));
-
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idLength, INT2FIX(0));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(minimum_size));
- ADD_SEND(ret, &line.node, cast->rest == NULL ? idEq : idGE, INT2FIX(1));
- if (in_single_pattern) {
- VALUE message = cast->rest == NULL ? rb_fstring_lit("%p length mismatch (given %p, expected %p)") : rb_fstring_lit("%p length mismatch (given %p, expected %p+)");
- CHECK(pm_compile_pattern_length_error(iseq, scope_node, node, ret, message, INT2FIX(minimum_size), base_index + 1));
- }
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
-
- for (size_t index = 0; index < requireds_size; index++) {
- const pm_node_t *required = cast->requireds.nodes[index];
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(index));
- ADD_SEND(ret, &line.node, idAREF, INT2FIX(1));
- CHECK(pm_compile_pattern_match(iseq, scope_node, required, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 1));
- }
-
- if (cast->rest != NULL) {
- if (((const pm_splat_node_t *) cast->rest)->expression != NULL) {
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(requireds_size));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(1));
- ADD_SEND(ret, &line.node, idLength, INT2FIX(0));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(minimum_size));
- ADD_SEND(ret, &line.node, idMINUS, INT2FIX(1));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(4));
- ADD_SEND(ret, &line.node, idAREF, INT2FIX(2));
- CHECK(pm_compile_pattern_match(iseq, scope_node, ((const pm_splat_node_t *) cast->rest)->expression, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 1));
- } else if (posts_size > 0) {
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idLength, INT2FIX(0));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(minimum_size));
- ADD_SEND(ret, &line.node, idMINUS, INT2FIX(1));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(2));
- ADD_INSN(ret, &line.node, pop);
- }
- }
-
- for (size_t index = 0; index < posts_size; index++) {
- const pm_node_t *post = cast->posts.nodes[index];
- ADD_INSN(ret, &line.node, dup);
-
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(requireds_size + index));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_SEND(ret, &line.node, idPLUS, INT2FIX(1));
- ADD_SEND(ret, &line.node, idAREF, INT2FIX(1));
- CHECK(pm_compile_pattern_match(iseq, scope_node, post, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 1));
- }
-
- ADD_INSN(ret, &line.node, pop);
- if (use_rest_size) {
- ADD_INSN(ret, &line.node, pop);
- }
-
- ADD_INSNL(ret, &line.node, jump, matched_label);
- ADD_INSN(ret, &line.node, putnil);
- if (use_rest_size) {
- ADD_INSN(ret, &line.node, putnil);
- }
-
- ADD_LABEL(ret, type_error_label);
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_eTypeError);
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("deconstruct must return Array"));
- ADD_SEND(ret, &line.node, id_core_raise, INT2FIX(2));
- ADD_INSN(ret, &line.node, pop);
-
- ADD_LABEL(ret, match_failed_label);
- ADD_INSN(ret, &line.node, pop);
- if (use_rest_size) {
- ADD_INSN(ret, &line.node, pop);
- }
-
- ADD_INSNL(ret, &line.node, jump, unmatched_label);
- break;
- }
- case PM_FIND_PATTERN_NODE: {
- // Find patterns in pattern matching are triggered by using commas in
- // a pattern or wrapping it in braces and using a splat on both the left
- // and right side of the pattern. This looks like:
- //
- // foo => [*, 1, 2, 3, *]
- //
- // There can be any number of requireds in the middle. The splats on
- // both sides can optionally have names attached.
- const pm_find_pattern_node_t *cast = (const pm_find_pattern_node_t *) node;
- const size_t size = cast->requireds.size;
-
- LABEL *match_failed_label = NEW_LABEL(line.lineno);
- LABEL *type_error_label = NEW_LABEL(line.lineno);
- LABEL *deconstruct_label = NEW_LABEL(line.lineno);
- LABEL *deconstructed_label = NEW_LABEL(line.lineno);
-
- if (cast->constant) {
- CHECK(pm_compile_pattern_constant(iseq, scope_node, cast->constant, ret, src, match_failed_label, in_single_pattern, base_index));
- }
-
- CHECK(pm_compile_pattern_deconstruct(iseq, scope_node, node, ret, src, deconstruct_label, match_failed_label, deconstructed_label, type_error_label, in_single_pattern, use_deconstructed_cache, base_index));
-
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idLength, INT2FIX(0));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(size));
- ADD_SEND(ret, &line.node, idGE, INT2FIX(1));
- if (in_single_pattern) {
- CHECK(pm_compile_pattern_length_error(iseq, scope_node, node, ret, rb_fstring_lit("%p length mismatch (given %p, expected %p+)"), INT2FIX(size), base_index + 1));
- }
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
-
- {
- LABEL *while_begin_label = NEW_LABEL(line.lineno);
- LABEL *next_loop_label = NEW_LABEL(line.lineno);
- LABEL *find_succeeded_label = NEW_LABEL(line.lineno);
- LABEL *find_failed_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idLength, INT2FIX(0));
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(size));
- ADD_SEND(ret, &line.node, idMINUS, INT2FIX(1));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(0));
- ADD_LABEL(ret, while_begin_label);
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, topn, INT2FIX(2));
- ADD_SEND(ret, &line.node, idLE, INT2FIX(1));
- ADD_INSNL(ret, &line.node, branchunless, find_failed_label);
-
- for (size_t index = 0; index < size; index++) {
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(1));
-
- if (index != 0) {
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(index));
- ADD_SEND(ret, &line.node, idPLUS, INT2FIX(1));
- }
-
- ADD_SEND(ret, &line.node, idAREF, INT2FIX(1));
- CHECK(pm_compile_pattern_match(iseq, scope_node, cast->requireds.nodes[index], ret, src, next_loop_label, in_single_pattern, in_alternation_pattern, false, base_index + 4));
- }
-
- assert(PM_NODE_TYPE_P(cast->left, PM_SPLAT_NODE));
- const pm_splat_node_t *left = (const pm_splat_node_t *) cast->left;
-
- if (left->expression != NULL) {
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(0));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(2));
- ADD_SEND(ret, &line.node, idAREF, INT2FIX(2));
- CHECK(pm_compile_pattern_match(iseq, scope_node, left->expression, ret, src, find_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 4));
- }
-
- assert(PM_NODE_TYPE_P(cast->right, PM_SPLAT_NODE));
- const pm_splat_node_t *right = (const pm_splat_node_t *) cast->right;
-
- if (right->expression != NULL) {
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(1));
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(size));
- ADD_SEND(ret, &line.node, idPLUS, INT2FIX(1));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_SEND(ret, &line.node, idAREF, INT2FIX(2));
- pm_compile_pattern_match(iseq, scope_node, right->expression, ret, src, find_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 4);
- }
-
- ADD_INSNL(ret, &line.node, jump, find_succeeded_label);
-
- ADD_LABEL(ret, next_loop_label);
- ADD_INSN1(ret, &line.node, putobject, INT2FIX(1));
- ADD_SEND(ret, &line.node, idPLUS, INT2FIX(1));
- ADD_INSNL(ret, &line.node, jump, while_begin_label);
-
- ADD_LABEL(ret, find_failed_label);
- ADD_INSN1(ret, &line.node, adjuststack, INT2FIX(3));
- if (in_single_pattern) {
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("%p does not match to find pattern"));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(2));
- ADD_SEND(ret, &line.node, id_core_sprintf, INT2FIX(2));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
-
- ADD_INSN1(ret, &line.node, putobject, Qfalse);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN(ret, &line.node, pop);
- }
- ADD_INSNL(ret, &line.node, jump, match_failed_label);
- ADD_INSN1(ret, &line.node, dupn, INT2FIX(3));
-
- ADD_LABEL(ret, find_succeeded_label);
- ADD_INSN1(ret, &line.node, adjuststack, INT2FIX(3));
- }
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSNL(ret, &line.node, jump, matched_label);
- ADD_INSN(ret, &line.node, putnil);
-
- ADD_LABEL(ret, type_error_label);
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_eTypeError);
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("deconstruct must return Array"));
- ADD_SEND(ret, &line.node, id_core_raise, INT2FIX(2));
- ADD_INSN(ret, &line.node, pop);
-
- ADD_LABEL(ret, match_failed_label);
- ADD_INSN(ret, &line.node, pop);
- ADD_INSNL(ret, &line.node, jump, unmatched_label);
-
- break;
- }
- case PM_HASH_PATTERN_NODE: {
- // Hash patterns in pattern matching are triggered by using labels and
- // values in a pattern or by using the ** operator. They are represented
- // by the HashPatternNode. This looks like:
- //
- // foo => { a: 1, b: 2, **bar }
- //
- // It can optionally have an assoc splat in the middle of it, which can
- // optionally have a name.
- const pm_hash_pattern_node_t *cast = (const pm_hash_pattern_node_t *) node;
-
- // We don't consider it a "rest" parameter if it's a ** that is unnamed.
- bool has_rest = cast->rest != NULL && !(PM_NODE_TYPE_P(cast->rest, PM_ASSOC_SPLAT_NODE) && ((const pm_assoc_splat_node_t *) cast->rest)->value == NULL);
- bool has_keys = cast->elements.size > 0 || cast->rest != NULL;
-
- LABEL *match_failed_label = NEW_LABEL(line.lineno);
- LABEL *type_error_label = NEW_LABEL(line.lineno);
- VALUE keys = Qnil;
-
- if (has_keys && !has_rest) {
- keys = rb_ary_new_capa(cast->elements.size);
-
- for (size_t index = 0; index < cast->elements.size; index++) {
- const pm_node_t *element = cast->elements.nodes[index];
- assert(PM_NODE_TYPE_P(element, PM_ASSOC_NODE));
-
- const pm_node_t *key = ((const pm_assoc_node_t *) element)->key;
- assert(PM_NODE_TYPE_P(key, PM_SYMBOL_NODE));
-
- VALUE symbol = ID2SYM(parse_string_symbol(&((const pm_symbol_node_t *) key)->unescaped, scope_node->parser));
- rb_ary_push(keys, symbol);
- }
- }
-
- if (cast->constant) {
- CHECK(pm_compile_pattern_constant(iseq, scope_node, cast->constant, ret, src, match_failed_label, in_single_pattern, base_index));
- }
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, putobject, ID2SYM(rb_intern("deconstruct_keys")));
- ADD_SEND(ret, &line.node, idRespond_to, INT2FIX(1));
- if (in_single_pattern) {
- CHECK(pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit("%p does not respond to #deconstruct_keys"), base_index + 1));
- }
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
-
- if (NIL_P(keys)) {
- ADD_INSN(ret, &line.node, putnil);
- } else {
- ADD_INSN1(ret, &line.node, duparray, keys);
- RB_OBJ_WRITTEN(iseq, Qundef, rb_obj_hide(keys));
- }
- ADD_SEND(ret, &line.node, rb_intern("deconstruct_keys"), INT2FIX(1));
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, checktype, INT2FIX(T_HASH));
- ADD_INSNL(ret, &line.node, branchunless, type_error_label);
-
- if (has_rest) {
- ADD_SEND(ret, &line.node, rb_intern("dup"), INT2FIX(0));
- }
-
- if (has_keys) {
- DECL_ANCHOR(match_values);
- INIT_ANCHOR(match_values);
-
- for (size_t index = 0; index < cast->elements.size; index++) {
- const pm_node_t *element = cast->elements.nodes[index];
- assert(PM_NODE_TYPE_P(element, PM_ASSOC_NODE));
-
- const pm_assoc_node_t *assoc = (const pm_assoc_node_t *) element;
- const pm_node_t *key = assoc->key;
- assert(PM_NODE_TYPE_P(key, PM_SYMBOL_NODE));
-
- VALUE symbol = ID2SYM(parse_string_symbol(&((const pm_symbol_node_t *) key)->unescaped, scope_node->parser));
- ADD_INSN(ret, &line.node, dup);
- ADD_INSN1(ret, &line.node, putobject, symbol);
- ADD_SEND(ret, &line.node, rb_intern("key?"), INT2FIX(1));
-
- if (in_single_pattern) {
- LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
-
- ADD_INSN1(ret, &line.node, putobject, rb_str_freeze(rb_sprintf("key not found: %+"PRIsVALUE, symbol)));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 2));
- ADD_INSN1(ret, &line.node, putobject, Qtrue);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 3));
- ADD_INSN1(ret, &line.node, topn, INT2FIX(3));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE + 4));
- ADD_INSN1(ret, &line.node, putobject, symbol);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY + 5));
-
- ADD_INSN1(ret, &line.node, adjuststack, INT2FIX(4));
- ADD_LABEL(ret, match_succeeded_label);
- }
-
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
- ADD_INSN(match_values, &line.node, dup);
- ADD_INSN1(match_values, &line.node, putobject, symbol);
- ADD_SEND(match_values, &line.node, has_rest ? rb_intern("delete") : idAREF, INT2FIX(1));
-
- CHECK(pm_compile_pattern_match(iseq, scope_node, assoc->value, match_values, src, match_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 1));
- }
-
- ADD_SEQ(ret, match_values);
- } else {
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idEmptyP, INT2FIX(0));
- if (in_single_pattern) {
- CHECK(pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit("%p is not empty"), base_index + 1));
- }
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
- }
-
- if (has_rest) {
- switch (PM_NODE_TYPE(cast->rest)) {
- case PM_NO_KEYWORDS_PARAMETER_NODE: {
- ADD_INSN(ret, &line.node, dup);
- ADD_SEND(ret, &line.node, idEmptyP, INT2FIX(0));
- if (in_single_pattern) {
- pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit("rest of %p is not empty"), base_index + 1);
- }
- ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
- break;
- }
- case PM_ASSOC_SPLAT_NODE: {
- const pm_assoc_splat_node_t *splat = (const pm_assoc_splat_node_t *) cast->rest;
- ADD_INSN(ret, &line.node, dup);
- pm_compile_pattern_match(iseq, scope_node, splat->value, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern, false, base_index + 1);
- break;
- }
- default:
- rb_bug("unreachable");
- break;
- }
- }
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSNL(ret, &line.node, jump, matched_label);
- ADD_INSN(ret, &line.node, putnil);
-
- ADD_LABEL(ret, type_error_label);
- ADD_INSN1(ret, &line.node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &line.node, putobject, rb_eTypeError);
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("deconstruct_keys must return Hash"));
- ADD_SEND(ret, &line.node, id_core_raise, INT2FIX(2));
- ADD_INSN(ret, &line.node, pop);
-
- ADD_LABEL(ret, match_failed_label);
- ADD_INSN(ret, &line.node, pop);
- ADD_INSNL(ret, &line.node, jump, unmatched_label);
- break;
- }
- case PM_CAPTURE_PATTERN_NODE: {
- // Capture patterns allow you to pattern match against an element in a
- // pattern and also capture the value into a local variable. This looks
- // like:
- //
- // [1] => [Integer => foo]
- //
- // In this case the `Integer => foo` will be represented by a
- // CapturePatternNode, which has both a value (the pattern to match
- // against) and a target (the place to write the variable into).
- const pm_capture_pattern_node_t *cast = (const pm_capture_pattern_node_t *) node;
-
- LABEL *match_failed_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- CHECK(pm_compile_pattern_match(iseq, scope_node, cast->value, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern, use_deconstructed_cache, base_index + 1));
- CHECK(pm_compile_pattern(iseq, scope_node, cast->target, ret, src, matched_label, match_failed_label, in_single_pattern, in_alternation_pattern, false, base_index));
- ADD_INSN(ret, &line.node, putnil);
-
- ADD_LABEL(ret, match_failed_label);
- ADD_INSN(ret, &line.node, pop);
- ADD_INSNL(ret, &line.node, jump, unmatched_label);
-
- break;
- }
- case PM_LOCAL_VARIABLE_TARGET_NODE: {
- // Local variables can be targetted by placing identifiers in the place
- // of a pattern. For example, foo in bar. This results in the value
- // being matched being written to that local variable.
- pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node;
- int index = pm_lookup_local_index(iseq, scope_node, cast->name);
-
- // If this local variable is being written from within an alternation
- // pattern, then it cannot actually be added to the local table since
- // it's ambiguous which value should be used. So instead we indicate
- // this with a compile error.
- if (in_alternation_pattern) {
- ID id = pm_constant_id_lookup(scope_node, cast->name);
- const char *name = rb_id2name(id);
-
- if (name && strlen(name) > 0 && name[0] != '_') {
- COMPILE_ERROR(ERROR_ARGS "illegal variable in alternative pattern (%"PRIsVALUE")", rb_id2str(id));
- return COMPILE_NG;
- }
- }
-
- ADD_SETLOCAL(ret, &line.node, index, (int) cast->depth);
- ADD_INSNL(ret, &line.node, jump, matched_label);
- break;
- }
- case PM_ALTERNATION_PATTERN_NODE: {
- // Alternation patterns allow you to specify multiple patterns in a
- // single expression using the | operator.
- pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node;
-
- LABEL *matched_left_label = NEW_LABEL(line.lineno);
- LABEL *unmatched_left_label = NEW_LABEL(line.lineno);
-
- // First, we're going to attempt to match against the left pattern. If
- // that pattern matches, then we'll skip matching the right pattern.
- ADD_INSN(ret, &line.node, dup);
- CHECK(pm_compile_pattern(iseq, scope_node, cast->left, ret, src, matched_left_label, unmatched_left_label, in_single_pattern, true, true, base_index + 1));
-
- // If we get here, then we matched on the left pattern. In this case we
- // should pop out the duplicate value that we preemptively added to
- // match against the right pattern and then jump to the match label.
- ADD_LABEL(ret, matched_left_label);
- ADD_INSN(ret, &line.node, pop);
- ADD_INSNL(ret, &line.node, jump, matched_label);
- ADD_INSN(ret, &line.node, putnil);
-
- // If we get here, then we didn't match on the left pattern. In this
- // case we attempt to match against the right pattern.
- ADD_LABEL(ret, unmatched_left_label);
- CHECK(pm_compile_pattern(iseq, scope_node, cast->right, ret, src, matched_label, unmatched_label, in_single_pattern, true, true, base_index));
- break;
- }
- case PM_ARRAY_NODE:
- case PM_CLASS_VARIABLE_READ_NODE:
- case PM_CONSTANT_PATH_NODE:
- case PM_CONSTANT_READ_NODE:
- case PM_FALSE_NODE:
- case PM_FLOAT_NODE:
- case PM_GLOBAL_VARIABLE_READ_NODE:
- case PM_IMAGINARY_NODE:
- case PM_INSTANCE_VARIABLE_READ_NODE:
- case PM_INTEGER_NODE:
- case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE:
- case PM_INTERPOLATED_STRING_NODE:
- case PM_INTERPOLATED_SYMBOL_NODE:
- case PM_INTERPOLATED_X_STRING_NODE:
- case PM_LAMBDA_NODE:
- case PM_LOCAL_VARIABLE_READ_NODE:
- case PM_NIL_NODE:
- case PM_RANGE_NODE:
- case PM_RATIONAL_NODE:
- case PM_REGULAR_EXPRESSION_NODE:
- case PM_SELF_NODE:
- case PM_STRING_NODE:
- case PM_SYMBOL_NODE:
- case PM_TRUE_NODE:
- case PM_X_STRING_NODE: {
- // These nodes are all simple patterns, which means we'll use the
- // checkmatch instruction to match against them, which is effectively a
- // VM-level === operator.
- PM_COMPILE_NOT_POPPED(node);
- if (in_single_pattern) {
- ADD_INSN1(ret, &line.node, dupn, INT2FIX(2));
- }
-
- ADD_INSN1(ret, &line.node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
-
- if (in_single_pattern) {
- pm_compile_pattern_eqq_error(iseq, scope_node, node, ret, base_index + 2);
- }
-
- ADD_INSNL(ret, &line.node, branchif, matched_label);
- ADD_INSNL(ret, &line.node, jump, unmatched_label);
- break;
- }
- case PM_PINNED_VARIABLE_NODE: {
- // Pinned variables are a way to match against the value of a variable
- // without it looking like you're trying to write to the variable. This
- // looks like: foo in ^@bar. To compile these, we compile the variable
- // that they hold.
- pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node;
- CHECK(pm_compile_pattern(iseq, scope_node, cast->variable, ret, src, matched_label, unmatched_label, in_single_pattern, in_alternation_pattern, true, base_index));
- break;
- }
- case PM_PINNED_EXPRESSION_NODE: {
- // Pinned expressions are a way to match against the value of an
- // expression that should be evaluated at runtime. This looks like:
- // foo in ^(bar). To compile these, we compile the expression that they
- // hold.
- pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node;
- CHECK(pm_compile_pattern(iseq, scope_node, cast->expression, ret, src, matched_label, unmatched_label, in_single_pattern, in_alternation_pattern, true, base_index));
- break;
- }
- case PM_IF_NODE:
- case PM_UNLESS_NODE: {
- // If and unless nodes can show up here as guards on `in` clauses. This
- // looks like:
- //
- // case foo
- // in bar if baz?
- // qux
- // end
- //
- // Because we know they're in the modifier form and they can't have any
- // variation on this pattern, we compile them differently (more simply)
- // here than we would in the normal compilation path.
- const pm_node_t *predicate;
- const pm_node_t *statement;
-
- if (PM_NODE_TYPE_P(node, PM_IF_NODE)) {
- const pm_if_node_t *cast = (const pm_if_node_t *) node;
- predicate = cast->predicate;
-
- assert(cast->statements != NULL && cast->statements->body.size == 1);
- statement = cast->statements->body.nodes[0];
- } else {
- const pm_unless_node_t *cast = (const pm_unless_node_t *) node;
- predicate = cast->predicate;
-
- assert(cast->statements != NULL && cast->statements->body.size == 1);
- statement = cast->statements->body.nodes[0];
- }
-
- CHECK(pm_compile_pattern_match(iseq, scope_node, statement, ret, src, unmatched_label, in_single_pattern, in_alternation_pattern, use_deconstructed_cache, base_index));
- PM_COMPILE_NOT_POPPED(predicate);
-
- if (in_single_pattern) {
- LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
-
- ADD_INSN(ret, &line.node, dup);
- if (PM_NODE_TYPE_P(node, PM_IF_NODE)) {
- ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
- } else {
- ADD_INSNL(ret, &line.node, branchunless, match_succeeded_label);
- }
-
- ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit("guard clause does not return true"));
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
- ADD_INSN1(ret, &line.node, putobject, Qfalse);
- ADD_INSN1(ret, &line.node, setn, INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
-
- ADD_INSN(ret, &line.node, pop);
- ADD_INSN(ret, &line.node, pop);
-
- ADD_LABEL(ret, match_succeeded_label);
- }
-
- if (PM_NODE_TYPE_P(node, PM_IF_NODE)) {
- ADD_INSNL(ret, &line.node, branchunless, unmatched_label);
- } else {
- ADD_INSNL(ret, &line.node, branchif, unmatched_label);
- }
-
- ADD_INSNL(ret, &line.node, jump, matched_label);
- break;
- }
- default:
- // If we get here, then we have a node type that should not be in this
- // position. This would be a bug in the parser, because a different node
- // type should never have been created in this position in the tree.
- rb_bug("Unexpected node type in pattern matching expression: %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
- break;
- }
-
- return COMPILE_OK;
-}
-
-#undef PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE
-#undef PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING
-#undef PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P
-#undef PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE
-#undef PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY
-
-// Generate a scope node from the given node.
-void
-pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser)
-{
- scope->base.type = PM_SCOPE_NODE;
- scope->base.location.start = node->location.start;
- scope->base.location.end = node->location.end;
-
- scope->previous = previous;
- scope->parser = parser;
- scope->ast_node = (pm_node_t *)node;
- scope->parameters = NULL;
- scope->body = NULL;
- scope->constants = NULL;
- scope->local_depth_offset = 0;
- scope->local_table_for_iseq_size = 0;
-
- if (previous) {
- scope->constants = previous->constants;
- scope->local_depth_offset = previous->local_depth_offset;
- }
- scope->index_lookup_table = NULL;
-
- pm_constant_id_list_init(&scope->locals);
-
- switch (PM_NODE_TYPE(node)) {
- case PM_BLOCK_NODE: {
- pm_block_node_t *cast = (pm_block_node_t *) node;
- scope->body = cast->body;
- scope->locals = cast->locals;
- scope->local_depth_offset = 0;
- scope->parameters = cast->parameters;
- break;
- }
- case PM_CLASS_NODE: {
- pm_class_node_t *cast = (pm_class_node_t *) node;
- scope->body = cast->body;
- scope->locals = cast->locals;
- break;
- }
- case PM_DEF_NODE: {
- pm_def_node_t *cast = (pm_def_node_t *) node;
- scope->parameters = (pm_node_t *)cast->parameters;
- scope->body = cast->body;
- scope->locals = cast->locals;
- break;
- }
- case PM_ENSURE_NODE: {
- scope->body = (pm_node_t *)node;
- scope->local_depth_offset += 1;
- break;
- }
- case PM_FOR_NODE: {
- pm_for_node_t *cast = (pm_for_node_t *)node;
- scope->body = (pm_node_t *)cast->statements;
- scope->local_depth_offset += 1;
- break;
- }
- case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
- RUBY_ASSERT(node->flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE);
- scope->body = (pm_node_t *)node;
- scope->local_depth_offset += 1;
- break;
- }
- case PM_LAMBDA_NODE: {
- pm_lambda_node_t *cast = (pm_lambda_node_t *) node;
- scope->parameters = cast->parameters;
- scope->body = cast->body;
- scope->locals = cast->locals;
- break;
- }
- case PM_MODULE_NODE: {
- pm_module_node_t *cast = (pm_module_node_t *) node;
- scope->body = cast->body;
- scope->locals = cast->locals;
- break;
- }
- case PM_POST_EXECUTION_NODE: {
- pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node;
- scope->body = (pm_node_t *) cast->statements;
- scope->local_depth_offset += 2;
- break;
- }
- case PM_PROGRAM_NODE: {
- pm_program_node_t *cast = (pm_program_node_t *) node;
- scope->body = (pm_node_t *) cast->statements;
- scope->locals = cast->locals;
- break;
- }
- case PM_RESCUE_NODE: {
- pm_rescue_node_t *cast = (pm_rescue_node_t *)node;
- scope->body = (pm_node_t *)cast->statements;
- scope->local_depth_offset += 1;
- break;
- }
- case PM_RESCUE_MODIFIER_NODE: {
- pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *)node;
- scope->body = (pm_node_t *)cast->rescue_expression;
- scope->local_depth_offset += 1;
- break;
- }
- case PM_SINGLETON_CLASS_NODE: {
- pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node;
- scope->body = cast->body;
- scope->locals = cast->locals;
- break;
- }
- case PM_STATEMENTS_NODE: {
- pm_statements_node_t *cast = (pm_statements_node_t *) node;
- scope->body = (pm_node_t *)cast;
- break;
- }
- default:
- assert(false && "unreachable");
- break;
- }
-}
-
-static void pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start);
-
-void
-pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition, LABEL **lfinish, bool explicit_receiver)
-{
- // in_condition is the same as compile.c's needstr
- enum defined_type dtype = DEFINED_NOT_DEFINED;
- switch (PM_NODE_TYPE(node)) {
- case PM_ARGUMENTS_NODE: {
- const pm_arguments_node_t *cast = (pm_arguments_node_t *) node;
- const pm_node_list_t *arguments = &cast->arguments;
- for (size_t idx = 0; idx < arguments->size; idx++) {
- const pm_node_t *argument = arguments->nodes[idx];
- pm_compile_defined_expr0(iseq, argument, ret, src, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, explicit_receiver);
-
- if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(lineno);
- }
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
- }
- dtype = DEFINED_TRUE;
- break;
- }
- case PM_NIL_NODE:
- dtype = DEFINED_NIL;
- break;
- case PM_PARENTHESES_NODE: {
- pm_parentheses_node_t *parentheses_node = (pm_parentheses_node_t *) node;
-
- if (parentheses_node->body == NULL) {
- dtype = DEFINED_NIL;
- } else {
- dtype = DEFINED_EXPR;
- }
- break;
- }
- case PM_SELF_NODE:
- dtype = DEFINED_SELF;
- break;
- case PM_TRUE_NODE:
- dtype = DEFINED_TRUE;
- break;
- case PM_FALSE_NODE:
- dtype = DEFINED_FALSE;
- break;
- case PM_ARRAY_NODE: {
- pm_array_node_t *array_node = (pm_array_node_t *) node;
- if (!(array_node->base.flags & PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT)) {
- for (size_t index = 0; index < array_node->elements.size; index++) {
- pm_compile_defined_expr0(iseq, array_node->elements.nodes[index], ret, src, popped, scope_node, dummy_line_node, lineno, true, lfinish, false);
- if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(lineno);
- }
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
- }
- }
- }
- case PM_AND_NODE:
- case PM_FLOAT_NODE:
- case PM_HASH_NODE:
- case PM_IMAGINARY_NODE:
- case PM_INTEGER_NODE:
- case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE:
- case PM_INTERPOLATED_STRING_NODE:
- case PM_KEYWORD_HASH_NODE:
- case PM_LAMBDA_NODE:
- case PM_MATCH_PREDICATE_NODE:
- case PM_OR_NODE:
- case PM_RANGE_NODE:
- case PM_REGULAR_EXPRESSION_NODE:
- case PM_SOURCE_ENCODING_NODE:
- case PM_SOURCE_FILE_NODE:
- case PM_SOURCE_LINE_NODE:
- case PM_STRING_NODE:
- case PM_SYMBOL_NODE:
- case PM_X_STRING_NODE:
- dtype = DEFINED_EXPR;
- break;
- case PM_LOCAL_VARIABLE_READ_NODE:
- dtype = DEFINED_LVAR;
- break;
-#define PUSH_VAL(type) (in_condition ? Qtrue : rb_iseq_defined_string(type))
- case PM_INSTANCE_VARIABLE_READ_NODE: {
- pm_instance_variable_read_node_t *instance_variable_read_node = (pm_instance_variable_read_node_t *)node;
- ID id = pm_constant_id_lookup(scope_node, instance_variable_read_node->name);
- ADD_INSN3(ret, &dummy_line_node, definedivar,
- ID2SYM(id), get_ivar_ic_value(iseq, id), PUSH_VAL(DEFINED_IVAR));
- return;
- }
- case PM_BACK_REFERENCE_READ_NODE: {
- char *char_ptr = (char *)(node->location.start) + 1;
- ID backref_val = INT2FIX(rb_intern2(char_ptr, 1)) << 1 | 1;
-
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_REF),
- backref_val,
- PUSH_VAL(DEFINED_GVAR));
-
- return;
- }
- case PM_NUMBERED_REFERENCE_READ_NODE: {
- uint32_t reference_number = ((pm_numbered_reference_read_node_t *)node)->number;
-
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_REF),
- INT2FIX(reference_number << 1),
- PUSH_VAL(DEFINED_GVAR));
-
- return;
- }
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- pm_global_variable_read_node_t *glabal_variable_read_node = (pm_global_variable_read_node_t *)node;
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_GVAR),
- ID2SYM(pm_constant_id_lookup(scope_node, glabal_variable_read_node->name)), PUSH_VAL(DEFINED_GVAR));
- return;
- }
- case PM_CLASS_VARIABLE_READ_NODE: {
- pm_class_variable_read_node_t *class_variable_read_node = (pm_class_variable_read_node_t *)node;
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CVAR),
- ID2SYM(pm_constant_id_lookup(scope_node, class_variable_read_node->name)), PUSH_VAL(DEFINED_CVAR));
-
- return;
- }
- case PM_CONSTANT_READ_NODE: {
- pm_constant_read_node_t *constant_node = (pm_constant_read_node_t *)node;
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST),
- ID2SYM(pm_constant_id_lookup(scope_node, constant_node->name)), PUSH_VAL(DEFINED_CONST));
- return;
- }
- case PM_CONSTANT_PATH_NODE: {
- pm_constant_path_node_t *constant_path_node = ((pm_constant_path_node_t *)node);
- if (constant_path_node->parent) {
- if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(lineno);
- }
- pm_compile_defined_expr0(iseq, constant_path_node->parent, ret, src, popped, scope_node, dummy_line_node, lineno, true, lfinish, false);
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
- PM_COMPILE(constant_path_node->parent);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST_FROM),
- ID2SYM(pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t *)constant_path_node->child)->name)), PUSH_VAL(DEFINED_CONST));
- return;
- }
-
- case PM_CALL_NODE: {
- pm_call_node_t *call_node = ((pm_call_node_t *)node);
- ID method_id = pm_constant_id_lookup(scope_node, call_node->name);
-
- if (call_node->receiver || call_node->arguments) {
- if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(lineno);
- }
- if (!lfinish[2]) {
- lfinish[2] = NEW_LABEL(lineno);
- }
- }
-
- if (call_node->arguments) {
- pm_compile_defined_expr0(iseq, (const pm_node_t *)call_node->arguments, ret, src, popped, scope_node, dummy_line_node, lineno, true, lfinish, false);
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
- }
-
- if (call_node->receiver) {
- pm_compile_defined_expr0(iseq, call_node->receiver, ret, src, popped, scope_node, dummy_line_node, lineno, true, lfinish, true);
- if (PM_NODE_TYPE_P(call_node->receiver, PM_CALL_NODE)) {
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[2]);
- ID method_id = pm_constant_id_lookup(scope_node, call_node->name);
- pm_compile_call(iseq, (const pm_call_node_t *)call_node->receiver, ret, src, popped, scope_node, method_id, NULL);
- }
- else {
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
- PM_COMPILE(call_node->receiver);
- }
-
- if (explicit_receiver) {
- PM_DUP;
- }
-
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_METHOD), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD));
- }
- else {
- PM_PUTSELF;
- if (explicit_receiver) {
- PM_DUP;
- }
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_FUNC), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD));
- }
- return;
- }
-
- case PM_YIELD_NODE:
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_YIELD), 0,
- PUSH_VAL(DEFINED_YIELD));
- return;
- case PM_SUPER_NODE:
- case PM_FORWARDING_SUPER_NODE:
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_ZSUPER), 0,
- PUSH_VAL(DEFINED_ZSUPER));
- return;
- case PM_CONSTANT_WRITE_NODE:
- case PM_CONSTANT_OPERATOR_WRITE_NODE:
- case PM_CONSTANT_AND_WRITE_NODE:
- case PM_CONSTANT_OR_WRITE_NODE:
-
- case PM_GLOBAL_VARIABLE_WRITE_NODE:
- case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE:
- case PM_GLOBAL_VARIABLE_AND_WRITE_NODE:
- case PM_GLOBAL_VARIABLE_OR_WRITE_NODE:
-
- case PM_CLASS_VARIABLE_WRITE_NODE:
- case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE:
- case PM_CLASS_VARIABLE_AND_WRITE_NODE:
- case PM_CLASS_VARIABLE_OR_WRITE_NODE:
-
- case PM_INSTANCE_VARIABLE_WRITE_NODE:
- case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE:
- case PM_INSTANCE_VARIABLE_AND_WRITE_NODE:
- case PM_INSTANCE_VARIABLE_OR_WRITE_NODE:
-
- case PM_LOCAL_VARIABLE_WRITE_NODE:
- case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE:
- case PM_LOCAL_VARIABLE_AND_WRITE_NODE:
- case PM_LOCAL_VARIABLE_OR_WRITE_NODE:
-
- case PM_MULTI_WRITE_NODE:
- dtype = DEFINED_ASGN;
- break;
- default:
- rb_bug("Unsupported node %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
- }
-
- assert(dtype != DEFINED_NOT_DEFINED);
-
- ADD_INSN1(ret, &dummy_line_node, putobject, PUSH_VAL(dtype));
-#undef PUSH_VAL
-}
-
-static void
-pm_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition, LABEL **lfinish, bool explicit_receiver)
-{
- LINK_ELEMENT *lcur = ret->last;
-
- pm_compile_defined_expr0(iseq, node, ret, src, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, false);
-
- if (lfinish[1]) {
- LABEL *lstart = NEW_LABEL(lineno);
- LABEL *lend = NEW_LABEL(lineno);
-
- struct rb_iseq_new_with_callback_callback_func *ifunc =
- rb_iseq_new_with_callback_new_callback(build_defined_rescue_iseq, NULL);
-
- const rb_iseq_t *rescue = new_child_iseq_with_callback(iseq, ifunc,
- rb_str_concat(rb_str_new2("defined guard in "),
- ISEQ_BODY(iseq)->location.label),
- iseq, ISEQ_TYPE_RESCUE, 0);
-
- lstart->rescued = LABEL_RESCUE_BEG;
- lend->rescued = LABEL_RESCUE_END;
-
- APPEND_LABEL(ret, lcur, lstart);
- ADD_LABEL(ret, lend);
- ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]);
- }
-}
-
-void
-pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition)
-{
- LABEL *lfinish[3];
- LINK_ELEMENT *last = ret->last;
-
- lfinish[0] = NEW_LABEL(lineno);
- lfinish[1] = 0;
- lfinish[2] = 0;
-
- if (!popped) {
- pm_defined_expr(iseq, node, ret, src, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, false);
- }
-
- if (lfinish[1]) {
- ELEM_INSERT_NEXT(last, &new_insn_body(iseq, &dummy_line_node, BIN(putnil), 0)->link);
- PM_SWAP;
- if (lfinish[2]) {
- ADD_LABEL(ret, lfinish[2]);
- }
- PM_POP;
- ADD_LABEL(ret, lfinish[1]);
-
- }
- ADD_LABEL(ret, lfinish[0]);
-}
-
-static void
-pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start)
-{
- pm_parser_t *parser = scope_node->parser;
- pm_newline_list_t newline_list = parser->newline_list;
- int lineno = (int)pm_newline_list_line_column(&newline_list, ((pm_node_t *)call_node)->location.start).line;
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
- LABEL *else_label = NEW_LABEL(lineno);
- LABEL *end_label = NEW_LABEL(lineno);
-
- pm_node_t *pm_node = (pm_node_t *)call_node;
-
- if (call_node->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
- PM_DUP;
- ADD_INSNL(ret, &dummy_line_node, branchnil, else_label);
- }
-
- int flags = 0;
- struct rb_callinfo_kwarg *kw_arg = NULL;
-
- int orig_argc = pm_setup_args(call_node->arguments, &flags, &kw_arg, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
-
- const rb_iseq_t *block_iseq = NULL;
- if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) {
- // Scope associated with the block
- pm_scope_node_t next_scope_node;
- pm_scope_node_init(call_node->block, &next_scope_node, scope_node, parser);
-
- block_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- if (ISEQ_BODY(block_iseq)->catch_table) {
- ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, start, end_label, block_iseq, end_label);
- }
- ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq;
- }
- else {
- if (pm_node->flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) {
- flags |= VM_CALL_VCALL;
- }
-
- if (call_node->block != NULL) {
- PM_COMPILE_NOT_POPPED(call_node->block);
- flags |= VM_CALL_ARGS_BLOCKARG;
- }
-
- if (!flags) {
- flags |= VM_CALL_ARGS_SIMPLE;
- }
- }
-
- if (call_node->receiver == NULL || PM_NODE_TYPE_P(call_node->receiver, PM_SELF_NODE)) {
- flags |= VM_CALL_FCALL;
- }
-
- if (pm_node->flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(orig_argc + 1));
- }
- ADD_SEND_R(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg);
- PM_POP_UNLESS_POPPED;
- }
- else {
- ADD_SEND_R(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg);
- }
-
- if (call_node->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) {
- ADD_INSNL(ret, &dummy_line_node, jump, end_label);
- ADD_LABEL(ret, else_label);
- }
- ADD_LABEL(ret, end_label);
-
- PM_POP_IF_POPPED;
-}
-
-// This is exactly the same as add_ensure_iseq, except it compiled
-// the node as a Prism node, and not a CRuby node
-static void
-pm_add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return, const uint8_t *src, pm_scope_node_t *scope_node)
-{
- assert(can_add_ensure_iseq(iseq));
-
- struct iseq_compile_data_ensure_node_stack *enlp =
- ISEQ_COMPILE_DATA(iseq)->ensure_node_stack;
- struct iseq_compile_data_ensure_node_stack *prev_enlp = enlp;
- DECL_ANCHOR(ensure);
-
- INIT_ANCHOR(ensure);
- while (enlp) {
- if (enlp->erange != NULL) {
- DECL_ANCHOR(ensure_part);
- LABEL *lstart = NEW_LABEL(0);
- LABEL *lend = NEW_LABEL(0);
- INIT_ANCHOR(ensure_part);
-
- add_ensure_range(iseq, enlp->erange, lstart, lend);
-
- ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enlp->prev;
- ADD_LABEL(ensure_part, lstart);
- bool popped = true;
- PM_COMPILE_INTO_ANCHOR(ensure_part, (pm_node_t *)enlp->ensure_node);
- ADD_LABEL(ensure_part, lend);
- ADD_SEQ(ensure, ensure_part);
- }
- else {
- if (!is_return) {
- break;
- }
- }
- enlp = enlp->prev;
- }
- ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = prev_enlp;
- ADD_SEQ(ret, ensure);
-}
-
-static void
-pm_insert_local_index(pm_constant_id_t constant_id, int local_index, st_table *index_lookup_table, rb_ast_id_table_t *local_table_for_iseq, pm_scope_node_t *scope_node)
-{
- ID local = pm_constant_id_lookup(scope_node, constant_id);
- local_table_for_iseq->ids[local_index] = local;
- st_insert(index_lookup_table, constant_id, local_index);
-}
-
-static int
-pm_compile_multi_assign_params(pm_multi_target_node_t *multi, st_table *index_lookup_table, rb_ast_id_table_t *local_table_for_iseq, pm_scope_node_t *scope_node, int local_index)
-{
- for (size_t m = 0; m < multi->lefts.size; m++) {
- pm_node_t *multi_node = multi->lefts.nodes[m];
-
- switch (PM_NODE_TYPE(multi_node)) {
- case PM_REQUIRED_PARAMETER_NODE: {
- pm_required_parameter_node_t *req = (pm_required_parameter_node_t *)multi_node;
- pm_insert_local_index(req->name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- local_index++;
- break;
- }
- case PM_MULTI_TARGET_NODE: {
- local_index = pm_compile_multi_assign_params((pm_multi_target_node_t *)multi_node, index_lookup_table, local_table_for_iseq, scope_node, local_index);
- break;
- }
- default: {
- rb_bug("Parameter within a MultiTargetNode isn't allowed");
- }
- }
- }
-
- if (multi->rest && PM_NODE_TYPE_P(multi->rest, PM_SPLAT_NODE)) {
- pm_splat_node_t *rest = (pm_splat_node_t *)multi->rest;
- if (rest->expression && PM_NODE_TYPE_P(rest->expression, PM_REQUIRED_PARAMETER_NODE)) {
- pm_required_parameter_node_t *req = (pm_required_parameter_node_t *)rest->expression;
- pm_insert_local_index(req->name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- local_index++;
- }
- }
-
- for (size_t m = 0; m < multi->rights.size; m++) {
- pm_node_t *multi_node = multi->rights.nodes[m];
-
- switch (PM_NODE_TYPE(multi_node)) {
- case PM_REQUIRED_PARAMETER_NODE: {
- pm_required_parameter_node_t *req = (pm_required_parameter_node_t *)multi_node;
- pm_insert_local_index(req->name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- local_index++;
- break;
- }
- case PM_MULTI_TARGET_NODE: {
- local_index = pm_compile_multi_assign_params((pm_multi_target_node_t *)multi_node, index_lookup_table, local_table_for_iseq, scope_node, local_index);
- break;
- }
- default: {
- rb_bug("Parameter within a MultiTargetNode isn't allowed");
- }
- }
- }
-
- return local_index;
-}
-
-/*
- * Compiles a prism node into instruction sequences
- *
- * iseq - The current instruction sequence object (used for locals)
- * node - The prism node to compile
- * ret - The linked list of instructions to append instructions onto
- * popped - True if compiling something with no side effects, so instructions don't
- * need to be added
- * scope_node - Stores parser and local information
- */
-static void
-pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node)
-{
- pm_parser_t *parser = scope_node->parser;
- pm_newline_list_t newline_list = parser->newline_list;
- int lineno = (int)pm_newline_list_line_column(&newline_list, node->location.start).line;
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
-
- if (node->flags & PM_NODE_FLAG_NEWLINE &&
- ISEQ_COMPILE_DATA(iseq)->last_line != lineno) {
- int event = RUBY_EVENT_LINE;
-
- ISEQ_COMPILE_DATA(iseq)->last_line = lineno;
- if (ISEQ_COVERAGE(iseq) && ISEQ_LINE_COVERAGE(iseq)) {
- event |= RUBY_EVENT_COVERAGE_LINE;
- }
- ADD_TRACE(ret, event);
- }
-
- switch (PM_NODE_TYPE(node)) {
- case PM_ALIAS_GLOBAL_VARIABLE_NODE: {
- pm_alias_global_variable_node_t *alias_node = (pm_alias_global_variable_node_t *) node;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
-
- ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(parse_location_symbol(&alias_node->new_name->location, parser)));
- ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(parse_location_symbol(&alias_node->old_name->location, parser)));
-
- ADD_SEND(ret, &dummy_line_node, id_core_set_variable_alias, INT2FIX(2));
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_ALIAS_METHOD_NODE: {
- pm_alias_method_node_t *alias_node = (pm_alias_method_node_t *) node;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
-
- PM_COMPILE_NOT_POPPED(alias_node->new_name);
- PM_COMPILE_NOT_POPPED(alias_node->old_name);
-
- ADD_SEND(ret, &dummy_line_node, id_core_set_method_alias, INT2FIX(3));
-
- PM_POP_IF_POPPED;
-
- return;
- }
- case PM_AND_NODE: {
- pm_and_node_t *and_node = (pm_and_node_t *) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
- PM_COMPILE_NOT_POPPED(and_node->left);
- PM_DUP_UNLESS_POPPED;
- ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
-
- PM_POP_UNLESS_POPPED;
- PM_COMPILE(and_node->right);
- ADD_LABEL(ret, end_label);
- return;
- }
- case PM_ARGUMENTS_NODE: {
- // These are ArgumentsNodes that are not compiled directly by their
- // parent call nodes, used in the cases of NextNodes, ReturnNodes
- // and BreakNodes
- pm_arguments_node_t *arguments_node = (pm_arguments_node_t *) node;
- pm_node_list_t node_list = arguments_node->arguments;
- for (size_t index = 0; index < node_list.size; index++) {
- PM_COMPILE(node_list.nodes[index]);
- }
- if (node_list.size > 1) {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(node_list.size));
- }
- return;
- }
- case PM_ARRAY_NODE: {
- // If every node in the array is static, then we can compile the entire
- // array now instead of later.
- if (pm_static_literal_p(node)) {
- // We're only going to compile this node if it's not popped. If it
- // is popped, then we know we don't need to do anything since it's
- // statically known.
- if (!popped) {
- pm_array_node_t *cast = (pm_array_node_t *) node;
- if (cast->elements.size) {
- VALUE value = pm_static_literal_value(node, scope_node, parser);
- ADD_INSN1(ret, &dummy_line_node, duparray, value);
- RB_OBJ_WRITTEN(iseq, Qundef, value);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(0));
- }
- }
- } else {
- // Here since we know there are possible side-effects inside the
- // array contents, we're going to build it entirely at runtime.
- // We'll do this by pushing all of the elements onto the stack and
- // then combining them with newarray.
- //
- // If this hash is popped, then this serves only to ensure we enact
- // all side-effects (like method calls) that are contained within
- // the hash contents.
- pm_array_node_t *cast = (pm_array_node_t *) node;
- pm_node_list_t *elements = &cast->elements;
-
- // In the case that there is a splat node within the array,
- // the array gets compiled slightly differently.
- if (node->flags & PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT) {
- if (elements->size == 1) {
- // If the only nodes is a SplatNode, we never
- // need to emit the newarray or concatarray
- // instructions
- PM_COMPILE_NOT_POPPED(elements->nodes[0]);
- }
- else {
- // We treat all sequences of non-splat elements as their
- // own arrays, followed by a newarray, and then continually
- // concat the arrays with the SplatNodes
- int new_array_size = 0;
- bool need_to_concat_array = false;
- for (size_t index = 0; index < elements->size; index++) {
- pm_node_t *array_element = elements->nodes[index];
- if (PM_NODE_TYPE_P(array_element, PM_SPLAT_NODE)) {
- pm_splat_node_t *splat_element = (pm_splat_node_t *)array_element;
-
- // If we already have non-splat elements, we need to emit a newarray
- // instruction
- if (new_array_size) {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(new_array_size));
-
- // We don't want to emit a concat array in the case where
- // we're seeing our first splat, and already have elements
- if (need_to_concat_array) {
- ADD_INSN(ret, &dummy_line_node, concatarray);
- }
-
- new_array_size = 0;
- }
-
- PM_COMPILE_NOT_POPPED(splat_element->expression);
-
- if (index > 0) {
- ADD_INSN(ret, &dummy_line_node, concatarray);
- }
- else {
- // If this is the first element, we need to splatarray
- ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
- }
-
- need_to_concat_array = true;
- }
- else {
- new_array_size++;
- PM_COMPILE_NOT_POPPED(array_element);
- }
- }
-
- if (new_array_size) {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(new_array_size));
- if (need_to_concat_array) {
- ADD_INSN(ret, &dummy_line_node, concatarray);
- }
- }
- }
-
- PM_POP_IF_POPPED;
- }
- else {
- for (size_t index = 0; index < elements->size; index++) {
- PM_COMPILE(elements->nodes[index]);
- }
-
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(elements->size));
- }
- }
- }
- return;
- }
- case PM_ASSOC_NODE: {
- pm_assoc_node_t *assoc_node = (pm_assoc_node_t *) node;
- PM_COMPILE(assoc_node->key);
- if (assoc_node->value) {
- PM_COMPILE(assoc_node->value);
- }
- return;
- }
- case PM_ASSOC_SPLAT_NODE: {
- pm_assoc_splat_node_t *assoc_splat_node = (pm_assoc_splat_node_t *)node;
-
- PM_COMPILE(assoc_splat_node->value);
- return;
- }
- case PM_BACK_REFERENCE_READ_NODE: {
- if (!popped) {
- // Since a back reference is `$<char>`, ruby represents the ID as the
- // an rb_intern on the value after the `$`.
- char *char_ptr = (char *)(node->location.start) + 1;
- ID backref_val = INT2FIX(rb_intern2(char_ptr, 1)) << 1 | 1;
- ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(1), backref_val);
- }
- return;
- }
- case PM_BEGIN_NODE: {
- pm_begin_node_t *begin_node = (pm_begin_node_t *) node;
- rb_iseq_t *child_iseq;
- LABEL *lstart = NEW_LABEL(lineno);
- LABEL *lend = NEW_LABEL(lineno);
- LABEL *lcont = NEW_LABEL(lineno);
-
-
- if (begin_node->rescue_clause) {
- pm_scope_node_t rescue_scope_node;
- pm_scope_node_init((pm_node_t *)begin_node->rescue_clause, &rescue_scope_node, scope_node, parser);
-
- rb_iseq_t *rescue_iseq = NEW_CHILD_ISEQ(rescue_scope_node,
- rb_str_concat(rb_str_new2("rescue in"),
- ISEQ_BODY(iseq)->location.label),
- ISEQ_TYPE_RESCUE, 1);
- lstart->rescued = LABEL_RESCUE_BEG;
- lend->rescued = LABEL_RESCUE_END;
- ADD_LABEL(ret, lstart);
- bool prev_in_rescue = ISEQ_COMPILE_DATA(iseq)->in_rescue;
- ISEQ_COMPILE_DATA(iseq)->in_rescue = true;
- if (begin_node->statements) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)begin_node->statements);
- }
- else {
- PM_PUTNIL;
- }
- ISEQ_COMPILE_DATA(iseq)->in_rescue = prev_in_rescue;
-
- if (begin_node->else_clause) {
- PM_POP_UNLESS_POPPED;
- PM_COMPILE((pm_node_t *)begin_node->else_clause);
- }
-
- ADD_LABEL(ret, lend);
- PM_NOP;
- ADD_LABEL(ret, lcont);
-
- PM_POP_IF_POPPED;
- ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue_iseq, lcont);
- ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, NULL, lstart);
- }
- if (begin_node->ensure_clause) {
- LABEL *estart = NEW_LABEL(lineno);
- LABEL *eend = NEW_LABEL(lineno);
- LABEL *econt = NEW_LABEL(lineno);
- ADD_LABEL(ret, estart);
- if (!begin_node->rescue_clause) {
- if (begin_node->statements) {
- PM_COMPILE((pm_node_t *)begin_node->statements);
- }
- else {
- PM_PUTNIL_UNLESS_POPPED;
- }
- }
- ADD_LABEL(ret, eend);
- if (!popped) {
- PM_NOP;
- }
- pm_statements_node_t *statements = begin_node->ensure_clause->statements;
- if (statements) {
- PM_COMPILE((pm_node_t *)statements);
- ADD_LABEL(ret, econt);
- PM_POP_UNLESS_POPPED;
- }
-
- struct ensure_range er;
- struct iseq_compile_data_ensure_node_stack enl;
- struct ensure_range *erange;
-
- er.begin = estart;
- er.end = eend;
- er.next = 0;
- push_ensure_entry(iseq, &enl, &er, (void *)begin_node->ensure_clause);
-
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)begin_node->ensure_clause, &next_scope_node, scope_node, parser);
-
- child_iseq = NEW_CHILD_ISEQ(next_scope_node,
- rb_str_new2("ensure in"),
- ISEQ_TYPE_ENSURE, lineno);
- ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq;
-
-
- erange = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack->erange;
- if (estart->link.next != &eend->link) {
- while (erange) {
- ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end, child_iseq, econt);
- erange = erange->next;
- }
- }
- }
-
- if (!begin_node->rescue_clause && !begin_node->ensure_clause) {
- ADD_LABEL(ret, lstart);
- if (begin_node->statements) {
- PM_COMPILE((pm_node_t *)begin_node->statements);
- }
- else {
- PM_PUTNIL_UNLESS_POPPED;
- }
- ADD_LABEL(ret, lend);
- }
- return;
- }
- case PM_BLOCK_ARGUMENT_NODE: {
- pm_block_argument_node_t *block_argument_node = (pm_block_argument_node_t *) node;
- if (block_argument_node->expression) {
- PM_COMPILE(block_argument_node->expression);
- }
- return;
- }
- case PM_BREAK_NODE: {
- pm_break_node_t *break_node = (pm_break_node_t *) node;
- unsigned long throw_flag = 0;
- if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0 && can_add_ensure_iseq(iseq)) {
- /* while/until */
- LABEL *splabel = NEW_LABEL(0);
- ADD_LABEL(ret, splabel);
- ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
- if (break_node->arguments) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)break_node->arguments);
- }
- else {
- PM_PUTNIL;
- }
- ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
- ADD_ADJUST_RESTORE(ret, splabel);
-
- PM_PUTNIL_UNLESS_POPPED;
- } else {
- const rb_iseq_t *ip = iseq;
-
- while (ip) {
- if (!ISEQ_COMPILE_DATA(ip)) {
- ip = 0;
- break;
- }
-
- if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
- throw_flag = VM_THROW_NO_ESCAPE_FLAG;
- }
- else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_BLOCK) {
- throw_flag = 0;
- }
- else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_EVAL) {
- COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with break");
- rb_bug("Can't escape from eval with break");
- }
- else {
- ip = ISEQ_BODY(ip)->parent_iseq;
- continue;
- }
-
- /* escape from block */
- if (break_node->arguments) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)break_node->arguments);
- }
- else {
- PM_PUTNIL;
- }
-
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(throw_flag | TAG_BREAK));
- PM_POP_IF_POPPED;
-
- return;
- }
- COMPILE_ERROR(ERROR_ARGS "Invalid break");
- rb_bug("Invalid break");
- }
- return;
- }
- case PM_CALL_NODE: {
- pm_call_node_t *call_node = (pm_call_node_t *) node;
- LABEL *start = NEW_LABEL(lineno);
-
- if (call_node->block) {
- ADD_LABEL(ret, start);
- }
-
- ID method_id = pm_constant_id_lookup(scope_node, call_node->name);
- if (node->flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) {
- if (!popped) {
- PM_PUTNIL;
- }
- }
-
- if (call_node->receiver == NULL) {
- PM_PUTSELF;
- } else {
- PM_COMPILE_NOT_POPPED(call_node->receiver);
- }
-
- pm_compile_call(iseq, call_node, ret, src, popped, scope_node, method_id, start);
- return;
- }
- case PM_CALL_AND_WRITE_NODE: {
- pm_call_and_write_node_t *call_and_write_node = (pm_call_and_write_node_t*) node;
-
- bool safe_nav = node->flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION;
-
- pm_compile_call_and_or_write_node(true, call_and_write_node->receiver, call_and_write_node->value, call_and_write_node->write_name, call_and_write_node->read_name, safe_nav, ret, iseq, lineno, src, popped, scope_node);
-
- return;
- }
- case PM_CALL_OR_WRITE_NODE: {
- pm_call_or_write_node_t *call_or_write_node = (pm_call_or_write_node_t*) node;
- bool safe_nav = node->flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION;
-
- pm_compile_call_and_or_write_node(false, call_or_write_node->receiver, call_or_write_node->value, call_or_write_node->write_name, call_or_write_node->read_name, safe_nav, ret, iseq, lineno, src, popped, scope_node);
-
- return;
- }
- case PM_CALL_OPERATOR_WRITE_NODE: {
- pm_call_operator_write_node_t *call_operator_write_node = (pm_call_operator_write_node_t*) node;
-
- NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
-
- int flag = 0;
-
- if (PM_NODE_TYPE_P(call_operator_write_node->receiver, PM_SELF_NODE)) {
- flag = VM_CALL_FCALL;
- }
-
- PM_COMPILE_NOT_POPPED(call_operator_write_node->receiver);
-
- ID write_name_id = pm_constant_id_lookup(scope_node, call_operator_write_node->write_name);
- ID read_name_id = pm_constant_id_lookup(scope_node, call_operator_write_node->read_name);
- ID operator_id = pm_constant_id_lookup(scope_node, call_operator_write_node->operator);
- PM_DUP;
-
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, read_name_id, INT2FIX(0), INT2FIX(flag));
-
- PM_COMPILE_NOT_POPPED(call_operator_write_node->value);
- ADD_SEND(ret, &dummy_line_node, operator_id, INT2FIX(1));
-
- if (!popped) {
- PM_SWAP;
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- }
-
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, write_name_id, INT2FIX(1), INT2FIX(flag));
- PM_POP;
-
- return;
- }
- case PM_CASE_NODE: {
- pm_case_node_t *case_node = (pm_case_node_t *)node;
- bool has_predicate = case_node->predicate;
- if (has_predicate) {
- PM_COMPILE_NOT_POPPED(case_node->predicate);
- }
- LABEL *end_label = NEW_LABEL(lineno);
-
- pm_node_list_t conditions = case_node->conditions;
-
- LABEL **conditions_labels = (LABEL **)ALLOC_N(VALUE, conditions.size + 1);
- LABEL *label;
-
- for (size_t i = 0; i < conditions.size; i++) {
- label = NEW_LABEL(lineno);
- conditions_labels[i] = label;
- if (has_predicate) {
- pm_when_node_t *when_node = (pm_when_node_t *)conditions.nodes[i];
-
- for (size_t i = 0; i < when_node->conditions.size; i++) {
- PM_COMPILE_NOT_POPPED(when_node->conditions.nodes[i]);
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idEqq, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
- ADD_INSNL(ret, &dummy_line_node, branchif, label);
- }
- }
- else {
- ADD_INSNL(ret, &dummy_line_node, jump, label);
- PM_PUTNIL;
- }
- }
-
- if (has_predicate) {
- PM_POP;
-
- if (case_node->consequent) {
- PM_COMPILE((pm_node_t *)case_node->consequent);
- }
- else {
- PM_PUTNIL_UNLESS_POPPED;
- }
- }
-
- ADD_INSNL(ret, &dummy_line_node, jump, end_label);
-
- for (size_t i = 0; i < conditions.size; i++) {
- label = conditions_labels[i];
- ADD_LABEL(ret, label);
- if (has_predicate) {
- PM_POP;
- }
-
- pm_while_node_t *condition_node = (pm_while_node_t *)conditions.nodes[i];
- if (condition_node->statements) {
- PM_COMPILE((pm_node_t *)condition_node->statements);
- }
- else {
- PM_PUTNIL_UNLESS_POPPED;
- }
-
- ADD_INSNL(ret, &dummy_line_node, jump, end_label);
- }
-
- ADD_LABEL(ret, end_label);
- return;
- }
- case PM_CASE_MATCH_NODE: {
- // If you use the `case` keyword to create a case match node, it will
- // match against all of the `in` clauses until it finds one that
- // matches. If it doesn't find one, it can optionally fall back to an
- // `else` clause. If none is present and a match wasn't found, it will
- // raise an appropriate error.
- const pm_case_match_node_t *cast = (const pm_case_match_node_t *) node;
-
- // This is the anchor that we will compile the bodies of the various
- // `in` nodes into. We'll make sure that the patterns that are compiled
- // jump into the correct spots within this anchor.
- DECL_ANCHOR(body_seq);
- INIT_ANCHOR(body_seq);
-
- // This is the anchor that we will compile the patterns of the various
- // `in` nodes into. If a match is found, they will need to jump into the
- // body_seq anchor to the correct spot.
- DECL_ANCHOR(cond_seq);
- INIT_ANCHOR(cond_seq);
-
- // This label is used to indicate the end of the entire node. It is
- // jumped to after the entire stack is cleaned up.
- LABEL *end_label = NEW_LABEL(lineno);
-
- // This label is used as the fallback for the case match. If no match is
- // found, then we jump to this label. This is either an `else` clause or
- // an error handler.
- LABEL *else_label = NEW_LABEL(lineno);
-
- // We're going to use this to uniquely identify each branch so that we
- // can track coverage information.
- int branch_id = 0;
- // VALUE branches = 0;
-
- // If there is only one pattern, then the behavior changes a bit. It
- // effectively gets treated as a match required node (this is how it is
- // represented in the other parser).
- bool in_single_pattern = cast->consequent == NULL && cast->conditions.size == 1;
-
- // First, we're going to push a bunch of stuff onto the stack that is
- // going to serve as our scratch space.
- if (in_single_pattern) {
- ADD_INSN(ret, &dummy_line_node, putnil); // key error key
- ADD_INSN(ret, &dummy_line_node, putnil); // key error matchee
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); // key error?
- ADD_INSN(ret, &dummy_line_node, putnil); // error string
- }
-
- // Now we're going to compile the value to match against.
- ADD_INSN(ret, &dummy_line_node, putnil); // deconstruct cache
- PM_COMPILE_NOT_POPPED(cast->predicate);
-
- // Next, we'll loop through every in clause and compile its body into
- // the body_seq anchor and its pattern into the cond_seq anchor. We'll
- // make sure the pattern knows how to jump correctly into the body if it
- // finds a match.
- for (size_t index = 0; index < cast->conditions.size; index++) {
- const pm_node_t *condition = cast->conditions.nodes[index];
- assert(PM_NODE_TYPE_P(condition, PM_IN_NODE));
-
- const pm_in_node_t *in_node = (const pm_in_node_t *) condition;
-
- pm_line_node_t in_line;
- pm_line_node(&in_line, scope_node, (const pm_node_t *) in_node);
-
- pm_line_node_t pattern_line;
- pm_line_node(&pattern_line, scope_node, (const pm_node_t *) in_node->pattern);
-
- if (branch_id) {
- ADD_INSN(body_seq, &in_line.node, putnil);
- }
-
- LABEL *body_label = NEW_LABEL(in_line.lineno);
- ADD_LABEL(body_seq, body_label);
- ADD_INSN1(body_seq, &in_line.node, adjuststack, INT2FIX(in_single_pattern ? 6 : 2));
-
- // TODO: We need to come back to this and enable trace branch
- // coverage. At the moment we can't call this function because it
- // accepts a NODE* and not a pm_node_t*.
- // add_trace_branch_coverage(iseq, body_seq, in_node->statements || in, branch_id++, "in", branches);
-
- branch_id++;
- if (in_node->statements != NULL) {
- PM_COMPILE_INTO_ANCHOR(body_seq, (const pm_node_t *) in_node->statements);
- } else if (!popped) {
- ADD_INSN(body_seq, &in_line.node, putnil);
- }
-
- ADD_INSNL(body_seq, &in_line.node, jump, end_label);
- LABEL *next_pattern_label = NEW_LABEL(pattern_line.lineno);
-
- ADD_INSN(cond_seq, &pattern_line.node, dup);
- pm_compile_pattern(iseq, scope_node, in_node->pattern, cond_seq, src, body_label, next_pattern_label, in_single_pattern, false, true, 2);
- ADD_LABEL(cond_seq, next_pattern_label);
- LABEL_UNREMOVABLE(next_pattern_label);
- }
-
- if (cast->consequent != NULL) {
- // If we have an `else` clause, then this becomes our fallback (and
- // there is no need to compile in code to potentially raise an
- // error).
- const pm_else_node_t *else_node = (const pm_else_node_t *) cast->consequent;
-
- ADD_LABEL(cond_seq, else_label);
- ADD_INSN(cond_seq, &dummy_line_node, pop);
- ADD_INSN(cond_seq, &dummy_line_node, pop);
-
- // TODO: trace branch coverage
- // add_trace_branch_coverage(iseq, cond_seq, cast->consequent, branch_id, "else", branches);
-
- if (else_node->statements != NULL) {
- PM_COMPILE_INTO_ANCHOR(cond_seq, (const pm_node_t *) else_node->statements);
- } else if (!popped) {
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
- }
-
- ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
- if (popped) {
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
- }
- } else {
- // Otherwise, if we do not have an `else` clause, we will compile in
- // the code to handle raising an appropriate error.
- ADD_LABEL(cond_seq, else_label);
-
- // TODO: trace branch coverage
- // add_trace_branch_coverage(iseq, cond_seq, orig_node, branch_id, "else", branches);
-
- if (in_single_pattern) {
- pm_compile_pattern_error_handler(iseq, scope_node, node, cond_seq, src, end_label, popped);
- } else {
- ADD_INSN1(cond_seq, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(cond_seq, &dummy_line_node, putobject, rb_eNoMatchingPatternError);
- ADD_INSN1(cond_seq, &dummy_line_node, topn, INT2FIX(2));
- ADD_SEND(cond_seq, &dummy_line_node, id_core_raise, INT2FIX(2));
-
- ADD_INSN1(cond_seq, &dummy_line_node, adjuststack, INT2FIX(3));
- if (!popped) ADD_INSN(cond_seq, &dummy_line_node, putnil);
- ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
- ADD_INSN1(cond_seq, &dummy_line_node, dupn, INT2FIX(1));
- if (popped) ADD_INSN(cond_seq, &dummy_line_node, putnil);
- }
- }
-
- // At the end of all of this compilation, we will add the code for the
- // conditions first, then the various bodies, then mark the end of the
- // entire sequence with the end label.
- ADD_SEQ(ret, cond_seq);
- ADD_SEQ(ret, body_seq);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_CLASS_NODE: {
- pm_class_node_t *class_node = (pm_class_node_t *)node;
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)class_node, &next_scope_node, scope_node, parser);
-
- ID class_id = pm_constant_id_lookup(scope_node, class_node->name);
-
- VALUE class_name = rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(class_id)));
-
- const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(next_scope_node, class_name, ISEQ_TYPE_CLASS, lineno);
-
- // TODO: Once we merge constant path nodes correctly, fix this flag
- const int flags = VM_DEFINECLASS_TYPE_CLASS |
- (class_node->superclass ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
- pm_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, false, scope_node);
-
- if (class_node->superclass) {
- PM_COMPILE_NOT_POPPED(class_node->superclass);
- }
- else {
- PM_PUTNIL;
- }
-
- ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(class_id), class_iseq, INT2FIX(flags));
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq);
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_CLASS_VARIABLE_AND_WRITE_NODE: {
- pm_class_variable_and_write_node_t *class_variable_and_write_node = (pm_class_variable_and_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
-
- ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_and_write_node->name);
- VALUE class_variable_name_val = ID2SYM(class_variable_name_id);
-
- ADD_INSN2(ret, &dummy_line_node, getclassvariable,
- class_variable_name_val,
- get_cvar_ic_value(iseq, class_variable_name_id));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(class_variable_and_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN2(ret, &dummy_line_node, setclassvariable,
- class_variable_name_val,
- get_cvar_ic_value(iseq, class_variable_name_id));
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: {
- pm_class_variable_operator_write_node_t *class_variable_operator_write_node = (pm_class_variable_operator_write_node_t*) node;
-
- ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_operator_write_node->name);
- VALUE class_variable_name_val = ID2SYM(class_variable_name_id);
-
- ADD_INSN2(ret, &dummy_line_node, getclassvariable,
- class_variable_name_val,
- get_cvar_ic_value(iseq, class_variable_name_id));
-
- PM_COMPILE_NOT_POPPED(class_variable_operator_write_node->value);
- ID method_id = pm_constant_id_lookup(scope_node, class_variable_operator_write_node->operator);
-
- int flags = VM_CALL_ARGS_SIMPLE;
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN2(ret, &dummy_line_node, setclassvariable,
- class_variable_name_val,
- get_cvar_ic_value(iseq, class_variable_name_id));
-
- return;
- }
- case PM_CLASS_VARIABLE_OR_WRITE_NODE: {
- pm_class_variable_or_write_node_t *class_variable_or_write_node = (pm_class_variable_or_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
- LABEL *start_label = NEW_LABEL(lineno);
-
- ADD_INSN(ret, &dummy_line_node, putnil);
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CVAR),
- ID2SYM(pm_constant_id_lookup(scope_node, class_variable_or_write_node->name)), Qtrue);
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, start_label);
-
- ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_or_write_node->name);
- VALUE class_variable_name_val = ID2SYM(class_variable_name_id);
-
- ADD_INSN2(ret, &dummy_line_node, getclassvariable,
- class_variable_name_val,
- get_cvar_ic_value(iseq, class_variable_name_id));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
-
- PM_POP_UNLESS_POPPED;
- ADD_LABEL(ret, start_label);
-
- PM_COMPILE_NOT_POPPED(class_variable_or_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN2(ret, &dummy_line_node, setclassvariable,
- class_variable_name_val,
- get_cvar_ic_value(iseq, class_variable_name_id));
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_CLASS_VARIABLE_READ_NODE: {
- if (!popped) {
- pm_class_variable_read_node_t *class_variable_read_node = (pm_class_variable_read_node_t *) node;
- ID cvar_name = pm_constant_id_lookup(scope_node, class_variable_read_node->name);
- ADD_INSN2(ret, &dummy_line_node, getclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
- }
- return;
- }
- case PM_CLASS_VARIABLE_TARGET_NODE: {
- pm_class_variable_target_node_t *write_node = (pm_class_variable_target_node_t *) node;
- ID cvar_name = pm_constant_id_lookup(scope_node, write_node->name);
- ADD_INSN2(ret, &dummy_line_node, setclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
- return;
- }
- case PM_CLASS_VARIABLE_WRITE_NODE: {
- pm_class_variable_write_node_t *write_node = (pm_class_variable_write_node_t *) node;
- PM_COMPILE_NOT_POPPED(write_node->value);
- PM_DUP_UNLESS_POPPED;
-
- ID cvar_name = pm_constant_id_lookup(scope_node, write_node->name);
- ADD_INSN2(ret, &dummy_line_node, setclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
- return;
- }
- case PM_CONSTANT_PATH_NODE: {
- pm_constant_path_node_t *constant_path_node = (pm_constant_path_node_t*) node;
- if (constant_path_node->parent) {
- PM_COMPILE_NOT_POPPED(constant_path_node->parent);
- } else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
-
- assert(PM_NODE_TYPE_P(constant_path_node->child, PM_CONSTANT_READ_NODE));
- pm_constant_read_node_t *child = (pm_constant_read_node_t *) constant_path_node->child;
-
- ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, child->name)));
- PM_POP_IF_POPPED;
- return;
- }
- case PM_CONSTANT_PATH_AND_WRITE_NODE: {
- pm_constant_path_and_write_node_t *constant_path_and_write_node = (pm_constant_path_and_write_node_t*) node;
-
- LABEL *lfin = NEW_LABEL(lineno);
-
- pm_constant_path_node_t *target = constant_path_and_write_node->target;
- if (target->parent) {
- PM_COMPILE_NOT_POPPED(target->parent);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
-
- pm_constant_read_node_t *child = (pm_constant_read_node_t *)target->child;
- VALUE child_name = ID2SYM(pm_constant_id_lookup(scope_node, child->name));
-
- PM_DUP;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, getconstant, child_name);
-
- PM_DUP_UNLESS_POPPED;
- ADD_INSNL(ret, &dummy_line_node, branchunless, lfin);
-
- PM_POP_UNLESS_POPPED;
- PM_COMPILE_NOT_POPPED(constant_path_and_write_node->value);
-
- if (popped) {
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(2));
- PM_SWAP;
- }
-
- ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
- ADD_LABEL(ret, lfin);
-
- PM_SWAP_UNLESS_POPPED;
- PM_POP;
-
- return;
- }
- case PM_CONSTANT_PATH_OR_WRITE_NODE: {
- pm_constant_path_or_write_node_t *constant_path_or_write_node = (pm_constant_path_or_write_node_t*) node;
-
- LABEL *lassign = NEW_LABEL(lineno);
- LABEL *lfin = NEW_LABEL(lineno);
-
- pm_constant_path_node_t *target = constant_path_or_write_node->target;
- if (target->parent) {
- PM_COMPILE_NOT_POPPED(target->parent);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
-
- pm_constant_read_node_t *child = (pm_constant_read_node_t *)target->child;
- VALUE child_name = ID2SYM(pm_constant_id_lookup(scope_node, child->name));
-
- PM_DUP;
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST_FROM), child_name, Qtrue);
- ADD_INSNL(ret, &dummy_line_node, branchunless, lassign);
-
- PM_DUP;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, getconstant, child_name);
-
- PM_DUP_UNLESS_POPPED;
- ADD_INSNL(ret, &dummy_line_node, branchif, lfin);
-
- PM_POP_UNLESS_POPPED;
- ADD_LABEL(ret, lassign);
- PM_COMPILE_NOT_POPPED(constant_path_or_write_node->value);
-
- if (popped) {
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(2));
- PM_SWAP;
- }
-
- ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
- ADD_LABEL(ret, lfin);
-
- PM_SWAP_UNLESS_POPPED;
- PM_POP;
-
- return;
- }
- case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
- pm_constant_path_operator_write_node_t *constant_path_operator_write_node = (pm_constant_path_operator_write_node_t*) node;
-
- pm_constant_path_node_t *target = constant_path_operator_write_node->target;
- if (target->parent) {
- PM_COMPILE_NOT_POPPED(target->parent);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
-
- PM_DUP;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
-
- pm_constant_read_node_t *child = (pm_constant_read_node_t *)target->child;
- VALUE child_name = ID2SYM(pm_constant_id_lookup(scope_node, child->name));
- ADD_INSN1(ret, &dummy_line_node, getconstant, child_name);
-
- PM_COMPILE_NOT_POPPED(constant_path_operator_write_node->value);
- ID method_id = pm_constant_id_lookup(scope_node, constant_path_operator_write_node->operator);
- ADD_CALL(ret, &dummy_line_node, method_id, INT2FIX(1));
- PM_SWAP;
-
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- PM_SWAP;
- }
-
- ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
- return ;
- }
- case PM_CONSTANT_PATH_TARGET_NODE: {
- pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *)node;
-
- if (cast->parent) {
- PM_COMPILE(cast->parent);
- }
-
- return;
- }
- case PM_CONSTANT_PATH_WRITE_NODE: {
- pm_constant_path_write_node_t *constant_path_write_node = (pm_constant_path_write_node_t*) node;
- if (constant_path_write_node->target->parent) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)constant_path_write_node->target->parent);
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
- }
- PM_COMPILE_NOT_POPPED(constant_path_write_node->value);
- if (!popped) {
- PM_SWAP;
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
- }
- PM_SWAP;
- VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node,
- ((pm_constant_read_node_t *)constant_path_write_node->target->child)->name));
- ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
- return;
- }
- case PM_CONSTANT_READ_NODE: {
- pm_constant_read_node_t *constant_read_node = (pm_constant_read_node_t *) node;
- PM_PUTNIL;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_read_node->name)));
- PM_POP_IF_POPPED;
- return;
- }
- case PM_CONSTANT_AND_WRITE_NODE: {
- pm_constant_and_write_node_t *constant_and_write_node = (pm_constant_and_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
-
- VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, constant_and_write_node->name));
-
- PM_PUTNIL;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(constant_and_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_CONSTANT_OPERATOR_WRITE_NODE: {
- pm_constant_operator_write_node_t *constant_operator_write_node = (pm_constant_operator_write_node_t*) node;
-
- ID constant_name = pm_constant_id_lookup(scope_node, constant_operator_write_node->name);
- PM_PUTNIL;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(constant_name));
-
- PM_COMPILE_NOT_POPPED(constant_operator_write_node->value);
- ID method_id = pm_constant_id_lookup(scope_node, constant_operator_write_node->operator);
-
- int flags = VM_CALL_ARGS_SIMPLE;
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(constant_name));
-
- return;
- }
- case PM_CONSTANT_OR_WRITE_NODE: {
- pm_constant_or_write_node_t *constant_or_write_node = (pm_constant_or_write_node_t*) node;
-
- LABEL *set_label= NEW_LABEL(lineno);
- LABEL *end_label = NEW_LABEL(lineno);
-
- PM_PUTNIL;
- VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, constant_or_write_node->name));
-
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST), constant_name, Qtrue);
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
-
- PM_PUTNIL;
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- ADD_LABEL(ret, set_label);
- PM_COMPILE_NOT_POPPED(constant_or_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_CONSTANT_TARGET_NODE: {
- pm_constant_target_node_t *constant_write_node = (pm_constant_target_node_t *) node;
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_write_node->name)));
- return;
- }
- case PM_CONSTANT_WRITE_NODE: {
- pm_constant_write_node_t *constant_write_node = (pm_constant_write_node_t *) node;
- PM_COMPILE_NOT_POPPED(constant_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
- ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_write_node->name)));
- return;
- }
- case PM_DEF_NODE: {
- pm_def_node_t *def_node = (pm_def_node_t *) node;
- ID method_name = pm_constant_id_lookup(scope_node, def_node->name);
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)def_node, &next_scope_node, scope_node, parser);
- rb_iseq_t *method_iseq = NEW_ISEQ(next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno);
-
- if (def_node->receiver) {
- PM_COMPILE_NOT_POPPED(def_node->receiver);
- ADD_INSN2(ret, &dummy_line_node, definesmethod, ID2SYM(method_name), method_iseq);
- }
- else {
- ADD_INSN2(ret, &dummy_line_node, definemethod, ID2SYM(method_name), method_iseq);
- }
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)method_iseq);
-
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(method_name));
- }
- return;
- }
- case PM_DEFINED_NODE: {
- pm_defined_node_t *defined_node = (pm_defined_node_t *)node;
- pm_compile_defined_expr(iseq, defined_node->value, ret, src, popped, scope_node, dummy_line_node, lineno, false);
- return;
- }
- case PM_EMBEDDED_STATEMENTS_NODE: {
- pm_embedded_statements_node_t *embedded_statements_node = (pm_embedded_statements_node_t *)node;
-
- if (embedded_statements_node->statements) {
- PM_COMPILE((pm_node_t *) (embedded_statements_node->statements));
- }
- else {
- PM_PUTNIL;
- }
-
- PM_POP_IF_POPPED;
- // TODO: Concatenate the strings that exist here
- return;
- }
- case PM_EMBEDDED_VARIABLE_NODE: {
- pm_embedded_variable_node_t *embedded_node = (pm_embedded_variable_node_t *)node;
- PM_COMPILE(embedded_node->variable);
- return;
- }
- case PM_FALSE_NODE:
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
- }
- return;
- case PM_ENSURE_NODE: {
- pm_ensure_node_t *ensure_node = (pm_ensure_node_t *)node;
-
- LABEL *start = NEW_LABEL(lineno);
- LABEL *end = NEW_LABEL(lineno);
- ADD_LABEL(ret, start);
- if (ensure_node->statements) {
- ISEQ_COMPILE_DATA(iseq)->end_label = end;
- PM_COMPILE((pm_node_t *)ensure_node->statements);
- }
- ADD_LABEL(ret, end);
- }
- case PM_ELSE_NODE: {
- pm_else_node_t *cast = (pm_else_node_t *)node;
- if (cast->statements) {
- PM_COMPILE((pm_node_t *)cast->statements);
- }
- else {
- PM_PUTNIL_UNLESS_POPPED;
- }
- return;
- }
- case PM_FLIP_FLOP_NODE: {
- pm_flip_flop_node_t *flip_flop_node = (pm_flip_flop_node_t *)node;
-
- LABEL *final_label = NEW_LABEL(lineno);
- LABEL *then_label = NEW_LABEL(lineno);
- LABEL *else_label = NEW_LABEL(lineno);
-
- pm_compile_flip_flop(flip_flop_node, else_label, then_label, iseq, lineno, ret, src, popped, scope_node);
-
- ADD_LABEL(ret, then_label);
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSNL(ret, &dummy_line_node, jump, final_label);
- ADD_LABEL(ret, else_label);
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
- ADD_LABEL(ret, final_label);
- return;
- }
- case PM_FLOAT_NODE: {
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, parse_float(node));
- }
- return;
- }
- case PM_FOR_NODE: {
- pm_for_node_t *for_node = (pm_for_node_t *)node;
-
- ISEQ_COMPILE_DATA(iseq)->catch_except_p = true;
-
- const rb_iseq_t *child_iseq;
- const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
-
- LABEL *retry_label = NEW_LABEL(lineno);
- LABEL *retry_end_l = NEW_LABEL(lineno);
-
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)for_node, &next_scope_node, scope_node, parser);
-
- pm_constant_id_list_t locals;
- pm_constant_id_list_init(&locals);
-
- ADD_LABEL(ret, retry_label);
-
- PM_COMPILE_NOT_POPPED(for_node->collection);
-
- child_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq;
- ADD_SEND_WITH_BLOCK(ret, &dummy_line_node, idEach, INT2FIX(0), child_iseq);
-
- ADD_LABEL(ret, retry_end_l);
- PM_POP_IF_POPPED;
-
- ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
- ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l);
- return;
- }
- case PM_FORWARDING_ARGUMENTS_NODE: {
- rb_bug("Should never hit the forwarding arguments case directly\n");
- return;
- }
- case PM_FORWARDING_SUPER_NODE: {
- pm_forwarding_super_node_t *forwarding_super_node = (pm_forwarding_super_node_t *) node;
- const rb_iseq_t *block = NULL;
- PM_PUTSELF;
- int flag = VM_CALL_ZSUPER | VM_CALL_SUPER | VM_CALL_FCALL;
-
- if (forwarding_super_node->block) {
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)forwarding_super_node->block, &next_scope_node, scope_node, parser);
- block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block);
- }
-
- DECL_ANCHOR(args);
- INIT_ANCHOR(args);
-
- struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
-
- const rb_iseq_t *local_iseq = body->local_iseq;
- const struct rb_iseq_constant_body *const local_body = ISEQ_BODY(local_iseq);
-
- int argc = 0;
- int depth = get_lvar_level(iseq);
-
- if (local_body->param.flags.has_lead) {
- /* required arguments */
- for (int i = 0; i < local_body->param.lead_num; i++) {
- int idx = local_body->local_table_size - i;
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- }
- argc += local_body->param.lead_num;
- }
-
-
- if (local_body->param.flags.has_opt) {
- /* optional arguments */
- for (int j = 0; j < local_body->param.opt_num; j++) {
- int idx = local_body->local_table_size - (argc + j);
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- }
- argc += local_body->param.opt_num;
- }
-
- if (local_body->param.flags.has_rest) {
- /* rest argument */
- int idx = local_body->local_table_size - local_body->param.rest_start;
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- ADD_INSN1(args, &dummy_line_node, splatarray, Qfalse);
-
- argc = local_body->param.rest_start + 1;
- flag |= VM_CALL_ARGS_SPLAT;
- }
-
- if (local_body->param.flags.has_post) {
- /* post arguments */
- int post_len = local_body->param.post_num;
- int post_start = local_body->param.post_start;
-
- int j = 0;
- for (; j < post_len; j++) {
- int idx = local_body->local_table_size - (post_start + j);
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- }
-
- if (local_body->param.flags.has_rest) {
- // argc remains unchanged from rest branch
- ADD_INSN1(args, &dummy_line_node, newarray, INT2FIX(j));
- ADD_INSN (args, &dummy_line_node, concatarray);
- }
- else {
- argc = post_len + post_start;
- }
- }
-
- const struct rb_iseq_param_keyword *const local_keyword = local_body->param.keyword;
- if (local_body->param.flags.has_kw) {
- int local_size = local_body->local_table_size;
- argc++;
-
- ADD_INSN1(args, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
-
- if (local_body->param.flags.has_kwrest) {
- int idx = local_body->local_table_size - local_keyword->rest_start;
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- if (local_keyword->num > 0) {
- ADD_SEND(args, &dummy_line_node, rb_intern("dup"), INT2FIX(0));
- flag |= VM_CALL_KW_SPLAT_MUT;
- }
- }
- else {
- ADD_INSN1(args, &dummy_line_node, newhash, INT2FIX(0));
- flag |= VM_CALL_KW_SPLAT_MUT;
- }
- int i = 0;
- for (; i < local_keyword->num; ++i) {
- ID id = local_keyword->table[i];
- int idx = local_size - get_local_var_idx(local_iseq, id);
- ADD_INSN1(args, &dummy_line_node, putobject, ID2SYM(id));
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- }
- ADD_SEND(args, &dummy_line_node, id_core_hash_merge_ptr, INT2FIX(i * 2 + 1));
- flag |= VM_CALL_KW_SPLAT;
- }
- else if (local_body->param.flags.has_kwrest) {
- int idx = local_body->local_table_size - local_keyword->rest_start;
- ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
- argc++;
- flag |= VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT;
- }
-
- ADD_SEQ(ret, args);
- ADD_INSN2(ret, &dummy_line_node, invokesuper, new_callinfo(iseq, 0, argc, flag, NULL, block != NULL), block);
- PM_POP_IF_POPPED;
- return;
- }
- case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: {
- pm_global_variable_and_write_node_t *global_variable_and_write_node = (pm_global_variable_and_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
-
- VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_and_write_node->name));
-
- ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(global_variable_and_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: {
- pm_global_variable_operator_write_node_t *global_variable_operator_write_node = (pm_global_variable_operator_write_node_t*) node;
-
- VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_operator_write_node->name));
- ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
-
- PM_COMPILE_NOT_POPPED(global_variable_operator_write_node->value);
- ID method_id = pm_constant_id_lookup(scope_node, global_variable_operator_write_node->operator);
-
- int flags = VM_CALL_ARGS_SIMPLE;
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
-
- return;
- }
- case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: {
- pm_global_variable_or_write_node_t *global_variable_or_write_node = (pm_global_variable_or_write_node_t*) node;
-
- LABEL *set_label= NEW_LABEL(lineno);
- LABEL *end_label = NEW_LABEL(lineno);
-
- PM_PUTNIL;
- VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_or_write_node->name));
-
- ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_GVAR), global_variable_name, Qtrue);
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
-
- ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- ADD_LABEL(ret, set_label);
- PM_COMPILE_NOT_POPPED(global_variable_or_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_GLOBAL_VARIABLE_READ_NODE: {
- pm_global_variable_read_node_t *global_variable_read_node = (pm_global_variable_read_node_t *)node;
- VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_read_node->name));
- ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
- PM_POP_IF_POPPED;
- return;
- }
- case PM_GLOBAL_VARIABLE_TARGET_NODE: {
- pm_global_variable_target_node_t *write_node = (pm_global_variable_target_node_t *) node;
-
- ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name);
- ADD_INSN1(ret, &dummy_line_node, setglobal, ID2SYM(ivar_name));
- return;
- }
- case PM_GLOBAL_VARIABLE_WRITE_NODE: {
- pm_global_variable_write_node_t *write_node = (pm_global_variable_write_node_t *) node;
- PM_COMPILE_NOT_POPPED(write_node->value);
- PM_DUP_UNLESS_POPPED;
- ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name);
- ADD_INSN1(ret, &dummy_line_node, setglobal, ID2SYM(ivar_name));
- return;
- }
- case PM_HASH_NODE: {
- // If every node in the hash is static, then we can compile the entire
- // hash now instead of later.
- if (pm_static_literal_p(node)) {
- // We're only going to compile this node if it's not popped. If it
- // is popped, then we know we don't need to do anything since it's
- // statically known.
- if (!popped) {
- VALUE value = pm_static_literal_value(node, scope_node, parser);
- ADD_INSN1(ret, &dummy_line_node, duphash, value);
- RB_OBJ_WRITTEN(iseq, Qundef, value);
- }
- } else {
- // Here since we know there are possible side-effects inside the
- // hash contents, we're going to build it entirely at runtime. We'll
- // do this by pushing all of the key-value pairs onto the stack and
- // then combining them with newhash.
- //
- // If this hash is popped, then this serves only to ensure we enact
- // all side-effects (like method calls) that are contained within
- // the hash contents.
- pm_hash_node_t *cast = (pm_hash_node_t *) node;
- // Elements must be non-empty, otherwise it would be static literal
- pm_node_list_t *elements = &cast->elements;
-
- pm_node_t *cur_node = elements->nodes[0];
- pm_node_type_t cur_type = PM_NODE_TYPE(cur_node);
- int elements_of_cur_type = 0;
- int allocated_hashes = 0;
-
- if (!PM_NODE_TYPE_P(cur_node, PM_ASSOC_NODE) && !popped) {
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(0));
- allocated_hashes++;
- }
-
- for (size_t index = 0; index < elements->size; index++) {
- pm_node_t *cur_node = elements->nodes[index];
- if (!popped) {
- if (!PM_NODE_TYPE_P(cur_node, cur_type)) {
- if (!allocated_hashes) {
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements_of_cur_type * 2));
- }
- else {
- if (cur_type == PM_ASSOC_NODE) {
- ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_ptr, INT2FIX(3));
- }
- else {
- ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd, INT2FIX(2));
- }
- }
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- PM_SWAP;
- PM_COMPILE(elements->nodes[index]);
-
- allocated_hashes++;
- elements_of_cur_type = 0;
- cur_type = PM_NODE_TYPE(cur_node);
- }
- else {
- elements_of_cur_type++;
- PM_COMPILE(elements->nodes[index]);
- }
- }
- else {
- PM_COMPILE(elements->nodes[index]);
- }
- }
-
- if (!popped) {
- if (!allocated_hashes) {
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements_of_cur_type * 2));
- }
- else {
- if (cur_type == PM_ASSOC_NODE) {
- ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_ptr, INT2FIX(3));
- }
- else {
- ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd, INT2FIX(2));
- }
- }
- }
- }
-
- return;
- }
- case PM_IF_NODE: {
- const int line = (int)pm_newline_list_line_column(&(parser->newline_list), node->location.start).line;
- pm_if_node_t *if_node = (pm_if_node_t *)node;
- pm_statements_node_t *node_body = if_node->statements;
- pm_node_t *node_else = if_node->consequent;
- pm_node_t *predicate = if_node->predicate;
-
- pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, scope_node);
- return;
- }
- case PM_IMAGINARY_NODE: {
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, parse_imaginary((pm_imaginary_node_t *)node));
- }
- return;
- }
- case PM_IMPLICIT_NODE: {
- // Implicit nodes mark places in the syntax tree where explicit syntax
- // was omitted, but implied. For example,
- //
- // { foo: }
- //
- // In this case a method call/local variable read is implied by virtue
- // of the missing value. To compile these nodes, we simply compile the
- // value that is implied, which is helpfully supplied by the parser.
- pm_implicit_node_t *cast = (pm_implicit_node_t *)node;
- PM_COMPILE(cast->value);
- return;
- }
- case PM_IN_NODE: {
- // In nodes are handled by the case match node directly, so we should
- // never end up hitting them through this path.
- rb_bug("Should not ever enter an in node directly");
- return;
- }
- case PM_INDEX_AND_WRITE_NODE: {
- pm_index_and_write_node_t *index_and_write_node = (pm_index_and_write_node_t *)node;
-
- pm_compile_index_and_or_write_node(true, index_and_write_node->receiver, index_and_write_node->value, index_and_write_node->arguments, index_and_write_node->block, ret, iseq, lineno, src, popped, scope_node, parser);
- return;
- }
- case PM_INDEX_OR_WRITE_NODE: {
- pm_index_or_write_node_t *index_or_write_node = (pm_index_or_write_node_t *)node;
-
- pm_compile_index_and_or_write_node(false, index_or_write_node->receiver, index_or_write_node->value, index_or_write_node->arguments, index_or_write_node->block, ret, iseq, lineno, src, popped, scope_node, parser);
- return;
- }
- case PM_INDEX_OPERATOR_WRITE_NODE: {
- pm_index_operator_write_node_t *index_operator_write_node = (pm_index_operator_write_node_t *)node;
-
- PM_PUTNIL_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(index_operator_write_node->receiver);
-
- int flag = 0;
- struct rb_callinfo_kwarg *keywords = NULL;
- int argc_int = 0;
-
- if (index_operator_write_node->arguments) {
- argc_int = pm_setup_args(index_operator_write_node->arguments, &flag, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
- }
-
- VALUE argc = INT2FIX(argc_int);
-
- int block_offset = 0;
-
- if (index_operator_write_node->block) {
- PM_COMPILE_NOT_POPPED(index_operator_write_node->block);
- flag |= VM_CALL_ARGS_BLOCKARG;
- block_offset = 1;
- }
-
- ADD_INSN1(ret, &dummy_line_node, dupn, FIXNUM_INC(argc, 1 + block_offset));
-
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, argc, INT2FIX(flag));
-
- PM_COMPILE_NOT_POPPED(index_operator_write_node->value);
-
- ID method_id = pm_constant_id_lookup(scope_node, index_operator_write_node->operator);
- ADD_SEND(ret, &dummy_line_node, method_id, INT2FIX(1));
-
- pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset);
-
- return;
- }
- case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
- pm_instance_variable_and_write_node_t *instance_variable_and_write_node = (pm_instance_variable_and_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
- ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_and_write_node->name);
- VALUE instance_variable_name_val = ID2SYM(instance_variable_name_id);
-
- ADD_INSN2(ret, &dummy_line_node, getinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(instance_variable_and_write_node->value);
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN2(ret, &dummy_line_node, setinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: {
- pm_instance_variable_operator_write_node_t *instance_variable_operator_write_node = (pm_instance_variable_operator_write_node_t*) node;
-
- ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_operator_write_node->name);
- VALUE instance_variable_name_val = ID2SYM(instance_variable_name_id);
-
- ADD_INSN2(ret, &dummy_line_node, getinstancevariable,
- instance_variable_name_val,
- get_ivar_ic_value(iseq, instance_variable_name_id));
-
- PM_COMPILE_NOT_POPPED(instance_variable_operator_write_node->value);
- ID method_id = pm_constant_id_lookup(scope_node, instance_variable_operator_write_node->operator);
-
- int flags = VM_CALL_ARGS_SIMPLE;
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
- instance_variable_name_val,
- get_ivar_ic_value(iseq, instance_variable_name_id));
-
- return;
- }
- case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: {
- pm_instance_variable_or_write_node_t *instance_variable_or_write_node = (pm_instance_variable_or_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
-
- ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_or_write_node->name);
- VALUE instance_variable_name_val = ID2SYM(instance_variable_name_id);
-
- ADD_INSN2(ret, &dummy_line_node, getinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(instance_variable_or_write_node->value);
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSN2(ret, &dummy_line_node, setinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_INSTANCE_VARIABLE_READ_NODE: {
- if (!popped) {
- pm_instance_variable_read_node_t *instance_variable_read_node = (pm_instance_variable_read_node_t *) node;
- ID ivar_name = pm_constant_id_lookup(scope_node, instance_variable_read_node->name);
- ADD_INSN2(ret, &dummy_line_node, getinstancevariable, ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name));
- }
- return;
- }
- case PM_INSTANCE_VARIABLE_TARGET_NODE: {
- pm_instance_variable_target_node_t *write_node = (pm_instance_variable_target_node_t *) node;
-
- ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name);
- ADD_INSN2(ret, &dummy_line_node, setinstancevariable, ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name));
- return;
- }
- case PM_INSTANCE_VARIABLE_WRITE_NODE: {
- pm_instance_variable_write_node_t *write_node = (pm_instance_variable_write_node_t *) node;
- PM_COMPILE_NOT_POPPED(write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name);
- ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
- ID2SYM(ivar_name),
- get_ivar_ic_value(iseq, ivar_name));
- return;
- }
- case PM_INTEGER_NODE: {
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, parse_integer((pm_integer_node_t *) node));
- }
- return;
- }
- case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: {
- pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node;
-
- int parts_size = (int)cast->parts.size;
- if (parts_size > 0 && !PM_NODE_TYPE_P(cast->parts.nodes[0], PM_STRING_NODE)) {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_str_new(0, 0));
- parts_size++;
- }
-
- pm_interpolated_node_compile(&cast->parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
-
- ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX(parts_size));
-
- ADD_INSN1(ret, &dummy_line_node, getglobal, rb_id2sym(idLASTLINE));
- ADD_SEND(ret, &dummy_line_node, idEqTilde, INT2NUM(1));
- PM_POP_IF_POPPED;
-
- return;
- }
- case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
- if (node->flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) {
- const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
- const rb_iseq_t *block_iseq = NULL;
- int ic_index = ISEQ_BODY(iseq)->ise_size++;
-
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t*)node, &next_scope_node, scope_node, parser);
-
- block_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq;
-
- ADD_INSN2(ret, &dummy_line_node, once, block_iseq, INT2FIX(ic_index));
-
- ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
- return;
- }
-
- pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node;
-
- int parts_size = (int)cast->parts.size;
- if (cast->parts.size > 0 && !PM_NODE_TYPE_P(cast->parts.nodes[0], PM_STRING_NODE)) {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_str_new(0, 0));
- parts_size++;
- }
-
- pm_interpolated_node_compile(&cast->parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
-
- ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX(parts_size));
- PM_POP_IF_POPPED;
- return;
- }
- case PM_INTERPOLATED_STRING_NODE: {
- pm_interpolated_string_node_t *interp_string_node = (pm_interpolated_string_node_t *) node;
- pm_interpolated_node_compile(&interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
-
- size_t parts_size = interp_string_node->parts.size;
- if (parts_size > 1) {
- ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
- }
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_INTERPOLATED_SYMBOL_NODE: {
- pm_interpolated_symbol_node_t *interp_symbol_node = (pm_interpolated_symbol_node_t *) node;
- pm_interpolated_node_compile(&interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
-
- size_t parts_size = interp_symbol_node->parts.size;
- if (parts_size > 1) {
- ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
- }
-
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, intern);
- }
- else {
- PM_POP;
- }
-
- return;
- }
- case PM_INTERPOLATED_X_STRING_NODE: {
- pm_interpolated_x_string_node_t *interp_x_string_node = (pm_interpolated_x_string_node_t *) node;
- PM_PUTSELF;
- pm_interpolated_node_compile(&interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, scope_node, parser);
-
- size_t parts_size = interp_x_string_node->parts.size;
- if (parts_size > 1) {
- ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
- }
-
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idBackquote, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
- PM_POP_IF_POPPED;
- return;
- }
- case PM_KEYWORD_HASH_NODE: {
- pm_keyword_hash_node_t *keyword_hash_node = (pm_keyword_hash_node_t *) node;
- pm_node_list_t elements = keyword_hash_node->elements;
-
- for (size_t index = 0; index < elements.size; index++) {
- PM_COMPILE(elements.nodes[index]);
- }
-
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements.size * 2));
- }
- return;
- }
- case PM_LAMBDA_NODE: {
- pm_scope_node_t next_scope_node;
- pm_scope_node_init(node, &next_scope_node, scope_node, parser);
-
- const rb_iseq_t *block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- VALUE argc = INT2FIX(0);
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_CALL_WITH_BLOCK(ret, &dummy_line_node, idLambda, argc, block);
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block);
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_LOCAL_VARIABLE_AND_WRITE_NODE: {
- pm_local_variable_and_write_node_t *local_variable_and_write_node = (pm_local_variable_and_write_node_t*) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
-
- pm_constant_id_t constant_id = local_variable_and_write_node->name;
- int depth = local_variable_and_write_node->depth + scope_node->local_depth_offset;
- int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
- ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- PM_COMPILE_NOT_POPPED(local_variable_and_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: {
- pm_local_variable_operator_write_node_t *local_variable_operator_write_node = (pm_local_variable_operator_write_node_t*) node;
-
- pm_constant_id_t constant_id = local_variable_operator_write_node->name;
-
- int depth = local_variable_operator_write_node->depth + scope_node->local_depth_offset;
- int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
- ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
-
- PM_COMPILE_NOT_POPPED(local_variable_operator_write_node->value);
- ID method_id = pm_constant_id_lookup(scope_node, local_variable_operator_write_node->operator);
-
- int flags = VM_CALL_ARGS_SIMPLE | VM_CALL_FCALL | VM_CALL_VCALL;
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
-
- return;
- }
- case PM_LOCAL_VARIABLE_OR_WRITE_NODE: {
- pm_local_variable_or_write_node_t *local_variable_or_write_node = (pm_local_variable_or_write_node_t*) node;
-
- LABEL *set_label= NEW_LABEL(lineno);
- LABEL *end_label = NEW_LABEL(lineno);
-
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
-
- pm_constant_id_t constant_id = local_variable_or_write_node->name;
- int depth = local_variable_or_write_node->depth + scope_node->local_depth_offset;
- int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
- ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
-
- PM_POP_UNLESS_POPPED;
-
- ADD_LABEL(ret, set_label);
- PM_COMPILE_NOT_POPPED(local_variable_or_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_LOCAL_VARIABLE_READ_NODE: {
- pm_local_variable_read_node_t *local_read_node = (pm_local_variable_read_node_t *) node;
-
- if (!popped) {
- int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_read_node->name, local_read_node->depth);
- ADD_GETLOCAL(ret, &dummy_line_node, index, local_read_node->depth + scope_node->local_depth_offset);
- }
- return;
- }
- case PM_LOCAL_VARIABLE_TARGET_NODE: {
- pm_local_variable_target_node_t *local_write_node = (pm_local_variable_target_node_t *) node;
-
- pm_constant_id_t constant_id = local_write_node->name;
- int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
-
- ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth + scope_node->local_depth_offset);
- return;
- }
- case PM_LOCAL_VARIABLE_WRITE_NODE: {
- pm_local_variable_write_node_t *local_write_node = (pm_local_variable_write_node_t *) node;
- PM_COMPILE_NOT_POPPED(local_write_node->value);
-
- PM_DUP_UNLESS_POPPED;
-
- pm_constant_id_t constant_id = local_write_node->name;
-
- int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
-
- ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->depth + scope_node->local_depth_offset);
- return;
- }
- case PM_MATCH_LAST_LINE_NODE: {
- if (!popped) {
- pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node;
-
- VALUE regex_str = parse_string(&cast->unescaped, parser);
- VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
-
- ADD_INSN1(ret, &dummy_line_node, putobject, regex);
- ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(0), INT2FIX(0));
- ADD_SEND(ret, &dummy_line_node, idEqTilde, INT2NUM(1));
- }
-
- return;
- }
- case PM_MATCH_PREDICATE_NODE: {
- pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node;
-
- // First, allocate some stack space for the cached return value of any
- // calls to #deconstruct.
- PM_PUTNIL;
-
- // Next, compile the expression that we're going to match against.
- PM_COMPILE_NOT_POPPED(cast->value);
- PM_DUP;
-
- // Now compile the pattern that is going to be used to match against the
- // expression.
- LABEL *matched_label = NEW_LABEL(lineno);
- LABEL *unmatched_label = NEW_LABEL(lineno);
- LABEL *done_label = NEW_LABEL(lineno);
- pm_compile_pattern(iseq, scope_node, cast->pattern, ret, src, matched_label, unmatched_label, false, false, true, 2);
-
- // If the pattern did not match, then compile the necessary instructions
- // to handle pushing false onto the stack, then jump to the end.
- ADD_LABEL(ret, unmatched_label);
- PM_POP;
- PM_POP;
-
- if (!popped) ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
- ADD_INSNL(ret, &dummy_line_node, jump, done_label);
- PM_PUTNIL;
-
- // If the pattern did match, then compile the necessary instructions to
- // handle pushing true onto the stack, then jump to the end.
- ADD_LABEL(ret, matched_label);
- ADD_INSN1(ret, &dummy_line_node, adjuststack, INT2FIX(2));
- if (!popped) ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- ADD_INSNL(ret, &dummy_line_node, jump, done_label);
-
- ADD_LABEL(ret, done_label);
- return;
- }
- case PM_MATCH_REQUIRED_NODE: {
- // A match required node represents pattern matching against a single
- // pattern using the => operator. For example,
- //
- // foo => bar
- //
- // This is somewhat analogous to compiling a case match statement with a
- // single pattern. In both cases, if the pattern fails it should
- // immediately raise an error.
- const pm_match_required_node_t *cast = (const pm_match_required_node_t *) node;
-
- LABEL *matched_label = NEW_LABEL(lineno);
- LABEL *unmatched_label = NEW_LABEL(lineno);
- LABEL *done_label = NEW_LABEL(lineno);
-
- // First, we're going to push a bunch of stuff onto the stack that is
- // going to serve as our scratch space.
- ADD_INSN(ret, &dummy_line_node, putnil); // key error key
- ADD_INSN(ret, &dummy_line_node, putnil); // key error matchee
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); // key error?
- ADD_INSN(ret, &dummy_line_node, putnil); // error string
- ADD_INSN(ret, &dummy_line_node, putnil); // deconstruct cache
-
- // Next we're going to compile the value expression such that it's on
- // the stack.
- PM_COMPILE_NOT_POPPED(cast->value);
-
- // Here we'll dup it so that it can be used for comparison, but also be
- // used for error handling.
- ADD_INSN(ret, &dummy_line_node, dup);
-
- // Next we'll compile the pattern. We indicate to the pm_compile_pattern
- // function that this is the only pattern that will be matched against
- // through the in_single_pattern parameter. We also indicate that the
- // value to compare against is 2 slots from the top of the stack (the
- // base_index parameter).
- pm_compile_pattern(iseq, scope_node, cast->pattern, ret, src, matched_label, unmatched_label, true, false, true, 2);
-
- // If the pattern did not match the value, then we're going to compile
- // in our error handler code. This will determine which error to raise
- // and raise it.
- ADD_LABEL(ret, unmatched_label);
- pm_compile_pattern_error_handler(iseq, scope_node, node, ret, src, done_label, popped);
-
- // If the pattern did match, we'll clean up the values we've pushed onto
- // the stack and then push nil onto the stack if it's not popped.
- ADD_LABEL(ret, matched_label);
- ADD_INSN1(ret, &dummy_line_node, adjuststack, INT2FIX(6));
- if (!popped) ADD_INSN(ret, &dummy_line_node, putnil);
- ADD_INSNL(ret, &dummy_line_node, jump, done_label);
-
- ADD_LABEL(ret, done_label);
- return;
- }
- case PM_MATCH_WRITE_NODE: {
- // Match write nodes are specialized call nodes that have a regular
- // expression with valid named capture groups on the left, the =~
- // operator, and some value on the right. The nodes themselves simply
- // wrap the call with the local variable targets that will be written
- // when the call is executed.
- pm_match_write_node_t *cast = (pm_match_write_node_t *) node;
- LABEL *fail_label = NEW_LABEL(lineno);
- LABEL *end_label = NEW_LABEL(lineno);
-
- // First, we'll compile the call so that all of its instructions are
- // present. Then we'll compile all of the local variable targets.
- PM_COMPILE_NOT_POPPED((pm_node_t *) cast->call);
-
- // Now, check if the match was successful. If it was, then we'll
- // continue on and assign local variables. Otherwise we'll skip over the
- // assignment code.
- ADD_INSN1(ret, &dummy_line_node, getglobal, rb_id2sym(idBACKREF));
- PM_DUP;
- ADD_INSNL(ret, &dummy_line_node, branchunless, fail_label);
-
- // If there's only a single local variable target, we can skip some of
- // the bookkeeping, so we'll put a special branch here.
- size_t targets_count = cast->targets.size;
-
- if (targets_count == 1) {
- pm_node_t *target = cast->targets.nodes[0];
- assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_TARGET_NODE));
-
- pm_local_variable_target_node_t *local_target = (pm_local_variable_target_node_t *) target;
- int index = pm_lookup_local_index(iseq, scope_node, local_target->name);
-
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, local_target->name)));
- ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1));
- ADD_LABEL(ret, fail_label);
- ADD_SETLOCAL(ret, &dummy_line_node, index, (int) local_target->depth);
- PM_POP_IF_POPPED;
- return;
- }
-
- // Otherwise there is more than one local variable target, so we'll need
- // to do some bookkeeping.
- for (size_t targets_index = 0; targets_index < targets_count; targets_index++) {
- pm_node_t *target = cast->targets.nodes[targets_index];
- assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_TARGET_NODE));
-
- pm_local_variable_target_node_t *local_target = (pm_local_variable_target_node_t *) target;
- int index = pm_lookup_local_index(iseq, scope_node, local_target->name);
-
- if (((size_t) targets_index) < (targets_count - 1)) {
- PM_DUP;
- }
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, local_target->name)));
- ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1));
- ADD_SETLOCAL(ret, &dummy_line_node, index, (int) local_target->depth);
- }
-
- // Since we matched successfully, now we'll jump to the end.
- ADD_INSNL(ret, &dummy_line_node, jump, end_label);
-
- // In the case that the match failed, we'll loop through each local
- // variable target and set all of them to `nil`.
- ADD_LABEL(ret, fail_label);
- PM_POP;
-
- for (size_t targets_index = 0; targets_index < targets_count; targets_index++) {
- pm_node_t *target = cast->targets.nodes[targets_index];
- assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_TARGET_NODE));
-
- pm_local_variable_target_node_t *local_target = (pm_local_variable_target_node_t *) target;
- int index = pm_lookup_local_index(iseq, scope_node, local_target->name);
-
- PM_PUTNIL;
- ADD_SETLOCAL(ret, &dummy_line_node, index, (int) local_target->depth);
- }
-
- // Finally, we can push the end label for either case.
- PM_POP_IF_POPPED;
- ADD_LABEL(ret, end_label);
- return;
- }
- case PM_MISSING_NODE: {
- rb_bug("A pm_missing_node_t should not exist in prism's AST.");
- return;
- }
- case PM_MODULE_NODE: {
- pm_module_node_t *module_node = (pm_module_node_t *)node;
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)module_node, &next_scope_node, scope_node, parser);
-
- ID module_id = pm_constant_id_lookup(scope_node, module_node->name);
- VALUE module_name = rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(module_id)));
-
- const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(next_scope_node, module_name, ISEQ_TYPE_CLASS, lineno);
-
- const int flags = VM_DEFINECLASS_TYPE_MODULE |
- pm_compile_class_path(ret, iseq, module_node->constant_path, &dummy_line_node, src, false, scope_node);
-
- PM_PUTNIL;
- ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(module_id), module_iseq, INT2FIX(flags));
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq);
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_REQUIRED_PARAMETER_NODE: {
- pm_required_parameter_node_t *required_parameter_node = (pm_required_parameter_node_t *)node;
- int index = pm_lookup_local_index(iseq, scope_node, required_parameter_node->name);
-
- ADD_SETLOCAL(ret, &dummy_line_node, index, 0);
- return;
- }
- case PM_MULTI_TARGET_NODE: {
- pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node;
- bool has_rest_expression = (cast->rest &&
- PM_NODE_TYPE_P(cast->rest, PM_SPLAT_NODE) &&
- (((pm_splat_node_t *)cast->rest)->expression));
-
- if (cast->lefts.size) {
- int flag = (int) (bool) cast->rights.size || has_rest_expression;
- ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(cast->lefts.size), INT2FIX(flag));
- for (size_t index = 0; index < cast->lefts.size; index++) {
- PM_COMPILE_NOT_POPPED(cast->lefts.nodes[index]);
- }
- }
-
- if (has_rest_expression) {
- if (cast->rights.size) {
- ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(cast->rights.size), INT2FIX(3));
- }
- pm_node_t *expression = ((pm_splat_node_t *)cast->rest)->expression;
- PM_COMPILE_NOT_POPPED(expression);
- }
-
- if (cast->rights.size) {
- if (!has_rest_expression) {
- ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(cast->rights.size), INT2FIX(2));
- }
- for (size_t index = 0; index < cast->rights.size; index++) {
- PM_COMPILE_NOT_POPPED(cast->rights.nodes[index]);
- }
- }
- return;
- }
- case PM_MULTI_WRITE_NODE: {
- pm_multi_write_node_t *multi_write_node = (pm_multi_write_node_t *)node;
- pm_node_list_t *lefts = &multi_write_node->lefts;
- pm_node_list_t *rights = &multi_write_node->rights;
- size_t argc = 1;
-
- // pre-process the left hand side of multi-assignments.
- uint8_t pushed = 0;
- for (size_t index = 0; index < lefts->size; index++) {
- pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, lefts->nodes[index], ret, scope_node, pushed, false);
- }
-
- PM_COMPILE_NOT_POPPED(multi_write_node->value);
- PM_DUP_UNLESS_POPPED;
-
- pm_node_t *rest_expression = NULL;
- if (multi_write_node->rest && PM_NODE_TYPE_P(multi_write_node->rest, PM_SPLAT_NODE)) {
- pm_splat_node_t *rest_splat = ((pm_splat_node_t *)multi_write_node->rest);
- rest_expression = rest_splat->expression;
- }
-
- size_t remainder = pushed;
- if (popped) remainder--;
-
- if (lefts->size) {
- ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(lefts->size), INT2FIX((int) (bool) (rights->size || rest_expression)));
- for (size_t index = 0; index < lefts->size; index++) {
- pm_node_t *considered_node = lefts->nodes[index];
-
- if (PM_NODE_TYPE_P(considered_node, PM_CONSTANT_PATH_TARGET_NODE) && pushed > 0) {
- pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) considered_node;
- ID name = pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t * ) cast->child)->name);
-
- pushed -= 2;
-
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(pushed));
- ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(name));
- } else if (PM_NODE_TYPE_P(considered_node, PM_INDEX_TARGET_NODE)) {
- pm_index_target_node_t *cast = (pm_index_target_node_t *)considered_node;
-
- if (cast->arguments) {
- pm_arguments_node_t *args = (pm_arguments_node_t *)cast->arguments;
- argc = args->arguments.size + 1;
- }
-
- if (argc == 1) {
- ADD_INSN(ret, &dummy_line_node, swap);
- }
- else {
- VALUE vals = INT2FIX(remainder + (lefts->size - index));
- ADD_INSN1(ret, &dummy_line_node, topn, vals);
- for (size_t i = 1; i < argc; i++) {
- ADD_INSN1(ret, &dummy_line_node, topn, vals);
- }
- ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(argc));
- }
-
- ADD_SEND(ret, &dummy_line_node, idASET, INT2FIX(argc));
- PM_POP;
- PM_POP;
- remainder -= argc;
-
- } else if (PM_NODE_TYPE_P(considered_node, PM_CALL_TARGET_NODE)) {
- pm_call_target_node_t *cast = (pm_call_target_node_t *)considered_node;
-
- VALUE vals = INT2FIX(remainder + (lefts->size - index));
- ADD_INSN1(ret, &dummy_line_node, topn, vals);
- ADD_INSN(ret, &dummy_line_node, swap);
-
- ID method_id = pm_constant_id_lookup(scope_node, cast->name);
- ADD_SEND(ret, &dummy_line_node, method_id, INT2FIX(argc));
- PM_POP;
- remainder -= argc;
- } else {
- PM_COMPILE(lefts->nodes[index]);
- }
- }
- }
-
- if ((pushed)) {
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(pushed));
- }
- for (uint8_t index = 0; index < (pushed); index++) {
- PM_POP;
- }
- }
-
- if (rights->size) {
- if (rest_expression) {
- ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(rights->size), INT2FIX(3));
- PM_COMPILE(rest_expression);
- }
- else {
- ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(rights->size), INT2FIX(2));
- }
-
- for (size_t index = 0; index < rights->size; index++) {
- PM_COMPILE(rights->nodes[index]);
- }
- }
- else if (rest_expression) {
- PM_COMPILE(rest_expression);
- }
-
- return;
- }
- case PM_NEXT_NODE: {
- pm_next_node_t *next_node = (pm_next_node_t *) node;
-
- if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0 && can_add_ensure_iseq(iseq)) {
- LABEL *splabel = NEW_LABEL(0);
-
- ADD_LABEL(ret, splabel);
-
- if (next_node->arguments) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)next_node->arguments);
- }
- else {
- PM_PUTNIL;
- }
- pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
-
- ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
- ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
-
- ADD_ADJUST_RESTORE(ret, splabel);
- PM_PUTNIL_UNLESS_POPPED;
- }
- else if (ISEQ_COMPILE_DATA(iseq)->end_label && can_add_ensure_iseq(iseq)) {
- LABEL *splabel = NEW_LABEL(0);
-
- ADD_LABEL(ret, splabel);
- ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->start_label);
-
- if (next_node->arguments) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)next_node->arguments);
- }
- else {
- PM_PUTNIL;
- }
-
- pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
- ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
- ADD_ADJUST_RESTORE(ret, splabel);
- splabel->unremovable = FALSE;
-
- PM_PUTNIL_UNLESS_POPPED;
- }
- else {
- const rb_iseq_t *ip = iseq;
-
- unsigned long throw_flag = 0;
- while (ip) {
- if (!ISEQ_COMPILE_DATA(ip)) {
- ip = 0;
- break;
- }
-
- throw_flag = VM_THROW_NO_ESCAPE_FLAG;
- if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
- /* while loop */
- break;
- }
- else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_BLOCK) {
- break;
- }
- else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_EVAL) {
- rb_raise(rb_eArgError, "Can't escape from eval with next");
- return;
- }
-
- ip = ISEQ_BODY(ip)->parent_iseq;
- }
- if (ip != 0) {
- if (next_node->arguments) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)next_node->arguments);
- }
- else {
- PM_PUTNIL;
- }
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(throw_flag | TAG_NEXT));
-
- PM_POP_IF_POPPED;
- }
- else {
- rb_raise(rb_eArgError, "Invalid next");
- return;
- }
- }
-
- return;
- }
- case PM_NIL_NODE:
- PM_PUTNIL_UNLESS_POPPED
- return;
- case PM_NO_KEYWORDS_PARAMETER_NODE: {
- ISEQ_BODY(iseq)->param.flags.accepts_no_kwarg = TRUE;
- return;
- }
- case PM_NUMBERED_REFERENCE_READ_NODE: {
- if (!popped) {
- uint32_t reference_number = ((pm_numbered_reference_read_node_t *)node)->number;
- ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(1), INT2FIX(reference_number << 1));
- }
- return;
- }
- case PM_OR_NODE: {
- pm_or_node_t *or_node = (pm_or_node_t *) node;
-
- LABEL *end_label = NEW_LABEL(lineno);
- PM_COMPILE_NOT_POPPED(or_node->left);
-
- PM_DUP_UNLESS_POPPED;
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
-
- PM_POP_UNLESS_POPPED;
- PM_COMPILE(or_node->right);
- ADD_LABEL(ret, end_label);
-
- return;
- }
- case PM_OPTIONAL_PARAMETER_NODE: {
- pm_optional_parameter_node_t *optional_parameter_node = (pm_optional_parameter_node_t *)node;
- PM_COMPILE_NOT_POPPED(optional_parameter_node->value);
-
- int index = pm_lookup_local_index(iseq, scope_node, optional_parameter_node->name);
-
- ADD_SETLOCAL(ret, &dummy_line_node, index, 0);
-
- return;
- }
- case PM_PARAMETERS_NODE: {
- rb_bug("Should not ever enter a parameters node directly");
-
- return;
- }
- case PM_PARENTHESES_NODE: {
- pm_parentheses_node_t *parentheses_node = (pm_parentheses_node_t *) node;
-
- if (parentheses_node->body == NULL) {
- PM_PUTNIL_UNLESS_POPPED;
- } else {
- PM_COMPILE(parentheses_node->body);
- }
-
- return;
- }
- case PM_PRE_EXECUTION_NODE: {
- pm_pre_execution_node_t *pre_execution_node = (pm_pre_execution_node_t *) node;
-
- DECL_ANCHOR(pre_ex);
- INIT_ANCHOR(pre_ex);
-
- if (pre_execution_node->statements) {
- pm_node_list_t node_list = pre_execution_node->statements->body;
- for (size_t index = 0; index < node_list.size; index++) {
- pm_compile_node(iseq, node_list.nodes[index], pre_ex, src, true, scope_node);
- }
- }
-
- if (!popped) {
- ADD_INSN(pre_ex, &dummy_line_node, putnil);
- }
-
- pre_ex->last->next = ret->anchor.next;
- ret->anchor.next = pre_ex->anchor.next;
- ret->anchor.next->prev = pre_ex->anchor.next;
-
- if (ret->last == (LINK_ELEMENT *)ret) {
- ret->last = pre_ex->last;
- }
-
- return;
- }
- case PM_POST_EXECUTION_NODE: {
- const rb_iseq_t *child_iseq;
- const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
-
- pm_scope_node_t next_scope_node;
- pm_scope_node_init(node, &next_scope_node, scope_node, parser);
-
- child_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq;
-
- int is_index = ISEQ_BODY(iseq)->ise_size++;
-
- ADD_INSN2(ret, &dummy_line_node, once, child_iseq, INT2FIX(is_index));
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)child_iseq);
-
- PM_POP_IF_POPPED;
-
- ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
-
- return;
- }
- case PM_PROGRAM_NODE: {
- rb_bug("Should not ever enter a program node directly");
-
- return;
- }
- case PM_RANGE_NODE: {
- pm_range_node_t *range_node = (pm_range_node_t *) node;
- bool exclusive = (range_node->operator_loc.end - range_node->operator_loc.start) == 3;
-
- if (pm_optimizable_range_item_p(range_node->left) && pm_optimizable_range_item_p(range_node->right)) {
- if (!popped) {
- pm_node_t *left = range_node->left;
- pm_node_t *right = range_node->right;
- VALUE val = rb_range_new(
- left && PM_NODE_TYPE_P(left, PM_INTEGER_NODE) ? parse_integer((pm_integer_node_t *) left) : Qnil,
- right && PM_NODE_TYPE_P(right, PM_INTEGER_NODE) ? parse_integer((pm_integer_node_t *) right) : Qnil,
- exclusive
- );
- ADD_INSN1(ret, &dummy_line_node, putobject, val);
- RB_OBJ_WRITTEN(iseq, Qundef, val);
- }
- }
- else {
- if (range_node->left == NULL) {
- PM_PUTNIL;
- } else {
- PM_COMPILE(range_node->left);
- }
-
- if (range_node->right == NULL) {
- PM_PUTNIL;
- } else {
- PM_COMPILE(range_node->right);
- }
-
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, newrange, INT2FIX(exclusive));
- }
- }
- return;
- }
- case PM_RATIONAL_NODE: {
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, parse_rational(node));
- }
- return;
- }
- case PM_REDO_NODE: {
- if (ISEQ_COMPILE_DATA(iseq)->redo_label && can_add_ensure_iseq(iseq)) {
- LABEL *splabel = NEW_LABEL(0);
-
- ADD_LABEL(ret, splabel);
-
- ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
-
- pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
- ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label);
- ADD_ADJUST_RESTORE(ret, splabel);
- PM_PUTNIL_UNLESS_POPPED;
- }
- else if (ISEQ_BODY(iseq)->type != ISEQ_TYPE_EVAL && ISEQ_COMPILE_DATA(iseq)->start_label && can_add_ensure_iseq(iseq)) {
- LABEL *splabel = NEW_LABEL(0);
-
- ADD_LABEL(ret, splabel);
- pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
- ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->start_label);
- ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
- ADD_ADJUST_RESTORE(ret, splabel);
-
- PM_PUTNIL_UNLESS_POPPED;
- }
- else {
- const rb_iseq_t *ip = iseq;
-
- while (ip) {
- if (!ISEQ_COMPILE_DATA(ip)) {
- ip = 0;
- break;
- }
-
- if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
- break;
- }
- else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_BLOCK) {
- break;
- }
- else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_EVAL) {
- rb_bug("Invalid redo\n");
- }
-
- ip = ISEQ_BODY(ip)->parent_iseq;
- }
- if (ip != 0) {
- PM_PUTNIL;
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(VM_THROW_NO_ESCAPE_FLAG | TAG_REDO));
-
- PM_POP_IF_POPPED;
- }
- else {
- rb_bug("Invalid redo\n");
- }
- }
- return;
- }
- case PM_REGULAR_EXPRESSION_NODE: {
- if (!popped) {
- pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
-
- VALUE regex = pm_new_regex(cast, parser);
-
- ADD_INSN1(ret, &dummy_line_node, putobject, regex);
- }
- return;
- }
- case PM_RESCUE_NODE: {
- LABEL *excep_match = NEW_LABEL(lineno);
- LABEL *rescue_end = NEW_LABEL(lineno);
-
- ISEQ_COMPILE_DATA(iseq)->end_label = rescue_end;
-
- pm_rescue_node_t *rescue_node = (pm_rescue_node_t *)node;
- iseq_set_exception_local_table(iseq);
-
- pm_node_list_t exception_list = rescue_node->exceptions;
- if (exception_list.size > 0) {
- for (size_t i = 0; i < exception_list.size; i++) {
- ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- PM_COMPILE(exception_list.nodes[i]);
- ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
- ADD_INSN1(ret, &dummy_line_node, branchif, excep_match);
- }
- } else {
- ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_eStandardError);
- ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
- ADD_INSN1(ret, &dummy_line_node, branchif, excep_match);
- }
- ADD_INSN1(ret, &dummy_line_node, jump, rescue_end);
-
- ADD_LABEL(ret, excep_match);
- ADD_TRACE(ret, RUBY_EVENT_RESCUE);
- if (rescue_node->reference) {
- ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- PM_COMPILE((pm_node_t *)rescue_node->reference);
- }
-
- if (rescue_node->statements) {
- PM_COMPILE((pm_node_t *)rescue_node->statements);
- }
- else {
- PM_PUTNIL;
- }
-
- ADD_INSN(ret, &dummy_line_node, leave);
- ADD_LABEL(ret, rescue_end);
-
- if (rescue_node->consequent) {
- PM_COMPILE((pm_node_t *)rescue_node->consequent);
- } else {
- ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
- }
-
- return;
- }
- case PM_RESCUE_MODIFIER_NODE: {
- pm_scope_node_t rescue_scope_node;
- pm_rescue_modifier_node_t *rescue_node = (pm_rescue_modifier_node_t *)node;
- pm_scope_node_init((pm_node_t *)rescue_node, &rescue_scope_node, scope_node, parser);
-
- rb_iseq_t *rescue_iseq = NEW_CHILD_ISEQ(rescue_scope_node,
- rb_str_concat(rb_str_new2("rescue in"),
- ISEQ_BODY(iseq)->location.label),
- ISEQ_TYPE_RESCUE, 1);
-
- LABEL *lstart = NEW_LABEL(lineno);
- LABEL *lend = NEW_LABEL(lineno);
- LABEL *lcont = NEW_LABEL(lineno);
-
- lstart->rescued = LABEL_RESCUE_BEG;
- lend->rescued = LABEL_RESCUE_END;
- ADD_LABEL(ret, lstart);
- PM_COMPILE_NOT_POPPED((pm_node_t *)rescue_node->expression);
- ADD_LABEL(ret, lend);
- PM_NOP;
- ADD_LABEL(ret, lcont);
-
- PM_POP_IF_POPPED;
-
- ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue_iseq, lcont);
- ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, NULL, lstart);
- return;
- }
- case PM_RETURN_NODE: {
- pm_arguments_node_t *arguments = ((pm_return_node_t *)node)->arguments;
-
- if (iseq) {
- enum rb_iseq_type type = ISEQ_BODY(iseq)->type;
- LABEL *splabel = 0;
-
- const rb_iseq_t *parent_iseq = iseq;
- enum rb_iseq_type parent_type = ISEQ_BODY(parent_iseq)->type;
- while (parent_type == ISEQ_TYPE_RESCUE || parent_type == ISEQ_TYPE_ENSURE) {
- if (!(parent_iseq = ISEQ_BODY(parent_iseq)->parent_iseq)) break;
- parent_type = ISEQ_BODY(parent_iseq)->type;
- }
-
- switch (parent_type) {
- case ISEQ_TYPE_TOP:
- case ISEQ_TYPE_MAIN:
- if (arguments) {
- rb_warn("argument of top-level return is ignored");
- }
- if (parent_iseq == iseq) {
- type = ISEQ_TYPE_METHOD;
- }
- break;
- default:
- break;
- }
-
- if (type == ISEQ_TYPE_METHOD) {
- splabel = NEW_LABEL(0);
- ADD_LABEL(ret, splabel);
- ADD_ADJUST(ret, &dummy_line_node, 0);
- }
-
- if (arguments) {
- PM_COMPILE_NOT_POPPED((pm_node_t *)arguments);
- }
- else {
- PM_PUTNIL;
- }
-
- if (type == ISEQ_TYPE_METHOD && can_add_ensure_iseq(iseq)) {
- pm_add_ensure_iseq(ret, iseq, 1, src, scope_node);
- ADD_TRACE(ret, RUBY_EVENT_RETURN);
- ADD_INSN(ret, &dummy_line_node, leave);
- ADD_ADJUST_RESTORE(ret, splabel);
-
- PM_PUTNIL_UNLESS_POPPED;
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(TAG_RETURN));
- PM_POP_IF_POPPED;
- }
- }
-
- return;
- }
- case PM_RETRY_NODE: {
- if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_RESCUE) {
- PM_PUTNIL;
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(TAG_RETRY));
-
- PM_POP_IF_POPPED;
- } else {
- COMPILE_ERROR(ERROR_ARGS "Invalid retry");
- rb_bug("Invalid retry");
- }
- return;
- }
- case PM_SCOPE_NODE: {
- pm_scope_node_t *scope_node = (pm_scope_node_t *)node;
- pm_constant_id_list_t *locals = &scope_node->locals;
-
- pm_parameters_node_t *parameters_node = NULL;
- pm_node_list_t *keywords_list = NULL;
- pm_node_list_t *optionals_list = NULL;
- pm_node_list_t *posts_list = NULL;
- pm_node_list_t *requireds_list = NULL;
- pm_node_list_t *block_locals = NULL;
- pm_node_t *block_param_keyword_rest = NULL;
-
- struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
-
- if (scope_node->parameters) {
- switch (PM_NODE_TYPE(scope_node->parameters)) {
- case PM_BLOCK_PARAMETERS_NODE: {
- pm_block_parameters_node_t *block_parameters_node = (pm_block_parameters_node_t *)scope_node->parameters;
- parameters_node = block_parameters_node->parameters;
- block_locals = &block_parameters_node->locals;
- if (parameters_node) {
- block_param_keyword_rest = parameters_node->keyword_rest;
- }
- break;
- }
- case PM_PARAMETERS_NODE: {
- parameters_node = (pm_parameters_node_t *) scope_node->parameters;
- break;
- }
- case PM_NUMBERED_PARAMETERS_NODE: {
- body->param.lead_num = ((pm_numbered_parameters_node_t *) scope_node->parameters)->maximum;
- break;
- }
- default:
- rb_bug("Unexpected node type for parameters: %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
- }
- }
-
- struct rb_iseq_param_keyword *keyword = NULL;
-
- if (parameters_node) {
- optionals_list = &parameters_node->optionals;
- requireds_list = &parameters_node->requireds;
- keywords_list = &parameters_node->keywords;
- posts_list = &parameters_node->posts;
- } else if (scope_node->parameters && PM_NODE_TYPE_P(scope_node->parameters, PM_NUMBERED_PARAMETERS_NODE)) {
- body->param.opt_num = 0;
- }
- else {
- body->param.lead_num = 0;
- body->param.opt_num = 0;
- }
-
- //********STEP 1**********
- // Goal: calculate the table size for the locals, accounting for
- // hidden variables and multi target nodes
- size_t locals_size = locals->size;
-
- // Index lookup table buffer size is only the number of the locals
- st_table *index_lookup_table = st_init_numtable();
-
- int table_size = (int) locals_size;
-
- if (PM_NODE_TYPE_P(scope_node->ast_node, PM_FOR_NODE)) {
- body->param.lead_num = 1;
- table_size++;
- }
-
- if (keywords_list && keywords_list->size) {
- table_size++;
- }
-
- if (requireds_list) {
- int number_of_anonymous_locals = 0;
- for (size_t i = 0; i < requireds_list->size; i++) {
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *required = requireds_list->nodes[i];
- if (PM_NODE_TYPE_P(required, PM_MULTI_TARGET_NODE)) {
- table_size++;
- }
- else if (PM_NODE_TYPE_P(required, PM_REQUIRED_PARAMETER_NODE)) {
- if (pm_constant_id_lookup(scope_node, ((pm_required_parameter_node_t *)required)->name) == rb_intern("_")) {
- number_of_anonymous_locals++;
- }
- }
- }
-
- // For each anonymous local we also want to increase the size
- // of the locals table. Prism's locals table accounts for all
- // anonymous locals as 1, so we need to increase the table size
- // by the number of anonymous locals - 1
- if (number_of_anonymous_locals > 1) {
- table_size += (number_of_anonymous_locals - 1);
- }
- }
-
- if (posts_list) {
- for (size_t i = 0; i < posts_list->size; i++) {
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *required = posts_list->nodes[i];
- if (PM_NODE_TYPE_P(required, PM_MULTI_TARGET_NODE)) {
- table_size++;
- }
- }
- }
-
- if (block_param_keyword_rest) {
- table_size++;
- }
-
- // When we have a `...` as the keyword_rest, it's a forwarding_parameter_node and
- // we need to leave space for 2 more locals on the locals table (`*` and `&`)
- if (parameters_node && parameters_node->keyword_rest &&
- PM_NODE_TYPE_P(parameters_node->keyword_rest, PM_FORWARDING_PARAMETER_NODE)) {
- table_size += 2;
- }
-
- // We can create local_table_for_iseq with the correct size
- VALUE idtmp = 0;
- rb_ast_id_table_t *local_table_for_iseq = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + table_size * sizeof(ID));
- local_table_for_iseq->size = table_size;
-
- //********END OF STEP 1**********
-
- //********STEP 2**********
- // Goal: populate iv index table as well as local table, keeping the
- // layout of the local table consistent with the layout of the
- // stack when calling the method
- //
- // Do a first pass on all of the parameters, setting their values in
- // the local_table_for_iseq, _except_ for Multis who get a hidden
- // variable in this step, and will get their names inserted in step 3
-
- // local_index is a cursor that keeps track of the current
- // index into local_table_for_iseq. The local table is actually a list,
- // and the order of that list must match the order of the items pushed
- // on the stack. We need to take in to account things pushed on the
- // stack that _might not have a name_ (for example array destructuring).
- // This index helps us know which item we're dealing with and also give
- // those anonymous items temporary names (as below)
- int local_index = 0;
-
- // We will assign these values now, if applicable, and use them for
- // the ISEQs on these multis
- int required_multis_hidden_index = 0;
- int post_multis_hidden_index = 0;
-
- // Here we figure out local table indices and insert them in to the
- // index lookup table and local tables.
- //
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^^^^^^^^^^
- if (requireds_list && requireds_list->size) {
- for (size_t i = 0; i < requireds_list->size; i++, local_index++) {
- ID local;
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *required = requireds_list->nodes[i];
- switch (PM_NODE_TYPE(required)) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^^^^^^^
- case PM_MULTI_TARGET_NODE: {
- required_multis_hidden_index = local_index;
- local = rb_make_temporary_id(local_index);
- local_table_for_iseq->ids[local_index] = local;
- break;
- }
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^
- case PM_REQUIRED_PARAMETER_NODE: {
- pm_required_parameter_node_t * param = (pm_required_parameter_node_t *)required;
-
- pm_insert_local_index(param->name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- break;
- }
- default: {
- rb_bug("Unsupported node %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
- }
- }
- }
-
- body->param.lead_num = (int) requireds_list->size;
- body->param.flags.has_lead = true;
- }
-
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^^
- if (optionals_list && optionals_list->size) {
- body->param.opt_num = (int) optionals_list->size;
- body->param.flags.has_opt = true;
-
- for (size_t i = 0; i < optionals_list->size; i++, local_index++) {
- pm_constant_id_t name = ((pm_optional_parameter_node_t *)optionals_list->nodes[i])->name;
- pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- }
- }
-
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^
- if (parameters_node && parameters_node->rest) {
- body->param.rest_start = local_index;
- // If there's a trailing comma, we'll have an implicit rest node,
- // and we don't want it to impact the rest variables on param
- if (!(PM_NODE_TYPE_P(parameters_node->rest, PM_IMPLICIT_REST_NODE))) {
- body->param.flags.has_rest = true;
- assert(body->param.rest_start != -1);
-
- pm_constant_id_t name = ((pm_rest_parameter_node_t *)parameters_node->rest)->name;
- if (name) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^
- pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- }
- else {
- // def foo(a, (b, *c, d), e = 1, *, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^
- local_table_for_iseq->ids[local_index] = idMULT;
- }
- local_index++;
- }
- }
-
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^^^^^^^^^^
- if (posts_list && posts_list->size) {
- body->param.post_num = (int) posts_list->size;
- body->param.post_start = local_index;
- body->param.flags.has_post = true;
-
- for (size_t i = 0; i < posts_list->size; i++, local_index++) {
- ID local;
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *post_node = posts_list->nodes[i];
- switch (PM_NODE_TYPE(post_node)) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^^^^^^^
- case PM_MULTI_TARGET_NODE: {
- post_multis_hidden_index = local_index;
- local = rb_make_temporary_id(local_index);
- local_table_for_iseq->ids[local_index] = local;
- break;
- }
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^
- case PM_REQUIRED_PARAMETER_NODE: {
- pm_required_parameter_node_t * param = (pm_required_parameter_node_t *)post_node;
-
- pm_insert_local_index(param->name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- break;
- }
- default: {
- rb_bug("Unsupported node %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
- }
- }
- }
- }
-
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^^^^^
- // Keywords create an internal variable on the parse tree
- if (keywords_list && keywords_list->size) {
- body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
- keyword->num = (int) keywords_list->size;
-
- body->param.flags.has_kw = true;
- const VALUE default_values = rb_ary_hidden_new(1);
- const VALUE complex_mark = rb_str_tmp_new(0);
-
- ID *ids = xcalloc(keywords_list->size, sizeof(ID));
-
- for (size_t i = 0; i < keywords_list->size; i++, local_index++) {
- pm_node_t *keyword_parameter_node = keywords_list->nodes[i];
- pm_constant_id_t name;
-
- switch (PM_NODE_TYPE(keyword_parameter_node)) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^
- case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
- pm_optional_keyword_parameter_node_t *cast = ((pm_optional_keyword_parameter_node_t *)keyword_parameter_node);
-
- pm_node_t *value = cast->value;
- name = cast->name;
-
- if (pm_static_literal_p(value) &&
- !(PM_NODE_TYPE_P(value, PM_ARRAY_NODE) ||
- PM_NODE_TYPE_P(value, PM_HASH_NODE) ||
- PM_NODE_TYPE_P(value, PM_RANGE_NODE))) {
-
- rb_ary_push(default_values, pm_static_literal_value(value, scope_node, parser));
- }
- else {
- rb_ary_push(default_values, complex_mark);
- }
-
- break;
- }
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^
- case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
- name = ((pm_required_keyword_parameter_node_t *)keyword_parameter_node)->name;
- keyword->required_num++;
- break;
- }
- default: {
- rb_bug("Unexpected keyword parameter node type");
- }
- }
-
- ID local = pm_constant_id_lookup(scope_node, name);
- pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- ids[i] = local;
- }
-
- keyword->bits_start = local_index;
- keyword->table = ids;
-
- VALUE *dvs = ALLOC_N(VALUE, RARRAY_LEN(default_values));
-
- for (int i = 0; i < RARRAY_LEN(default_values); i++) {
- VALUE dv = RARRAY_AREF(default_values, i);
- if (dv == complex_mark) dv = Qundef;
- if (!SPECIAL_CONST_P(dv)) {
- RB_OBJ_WRITTEN(iseq, Qundef, dv);
- }
- dvs[i] = dv;
- }
-
- keyword->default_values = dvs;
-
- // Hidden local for keyword arguments
- ID local = rb_make_temporary_id(local_index);
- local_table_for_iseq->ids[local_index] = local;
- local_index++;
- }
-
- if (body->type == ISEQ_TYPE_BLOCK && local_index == 1 && requireds_list && requireds_list->size == 1) {
- body->param.flags.ambiguous_param0 = true;
- }
-
- if (parameters_node) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^
- if (parameters_node->keyword_rest) {
- switch (PM_NODE_TYPE(parameters_node->keyword_rest)) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **nil, &n)
- // ^^^^^
- case PM_NO_KEYWORDS_PARAMETER_NODE: {
-
- body->param.flags.accepts_no_kwarg = true;
- break;
- }
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^
- case PM_KEYWORD_REST_PARAMETER_NODE: {
- pm_keyword_rest_parameter_node_t *kw_rest_node = (pm_keyword_rest_parameter_node_t *)parameters_node->keyword_rest;
- if (!body->param.flags.has_kw) {
- body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
- }
-
- keyword->rest_start = local_index;
- body->param.flags.has_kwrest = true;
-
- pm_constant_id_t constant_id = kw_rest_node->name;
- if (constant_id) {
- pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- }
- else {
- local_table_for_iseq->ids[local_index] = idPow;
- }
- local_index++;
- break;
- }
- // def foo(...)
- // ^^^
- case PM_FORWARDING_PARAMETER_NODE: {
- body->param.rest_start = local_index;
- body->param.flags.has_rest = true;
- ID local = idMULT;
- local_table_for_iseq->ids[local_index] = local;
- local_index++;
-
- body->param.block_start = local_index;
- body->param.flags.has_block = true;
- local = idAnd;
- local_table_for_iseq->ids[local_index] = local;
- local_index++;
-
- local = idDot3;
- local_table_for_iseq->ids[local_index] = local;
- local_index++;
- break;
- }
- default: {
- rb_raise(rb_eArgError, "node type %s not expected as keyword_rest", pm_node_type_to_str(PM_NODE_TYPE(parameters_node->keyword_rest)));
- }
- }
- }
-
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^
- if (parameters_node->block) {
- body->param.block_start = local_index;
- body->param.flags.has_block = true;
-
- pm_constant_id_t name = ((pm_block_parameter_node_t *)parameters_node->block)->name;
- pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- local_index++;
- }
- }
-
- //********END OF STEP 2**********
- // The local table is now consistent with expected
- // stack layout
-
- // If there's only one required element in the parameters
- // CRuby needs to recognize it as an ambiguous parameter
-
- //********STEP 3**********
- // Goal: fill in the names of the parameters in MultiTargetNodes
- //
- // Go through requireds again to set the multis
-
- if (requireds_list && requireds_list->size) {
- for (size_t i = 0; i < requireds_list->size; i++) {
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *required = requireds_list->nodes[i];
- if (PM_NODE_TYPE_P(required, PM_MULTI_TARGET_NODE)) {
- local_index = pm_compile_multi_assign_params((pm_multi_target_node_t *)required, index_lookup_table, local_table_for_iseq, scope_node, local_index);
- }
- }
- }
-
- // Go through posts again to set the multis
- if (posts_list && posts_list->size) {
- for (size_t i = 0; i < posts_list->size; i++) {
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *post= posts_list->nodes[i];
- if (PM_NODE_TYPE_P(post, PM_MULTI_TARGET_NODE)) {
- local_index = pm_compile_multi_assign_params((pm_multi_target_node_t *)post, index_lookup_table, local_table_for_iseq, scope_node, local_index);
- }
- }
- }
-
- // Set any anonymous locals for the for node
- if (PM_NODE_TYPE_P(scope_node->ast_node, PM_FOR_NODE)) {
- ID local = rb_make_temporary_id(local_index);
- local_table_for_iseq->ids[local_index] = local;
- local_index++;
- }
-
- // Fill in any NumberedParameters, if they exist
- if (scope_node->parameters && PM_NODE_TYPE_P(scope_node->parameters, PM_NUMBERED_PARAMETERS_NODE)) {
- int maximum = ((pm_numbered_parameters_node_t *)scope_node->parameters)->maximum;
- for (int i = 0; i < maximum; i++, local_index++) {
- pm_constant_id_t constant_id = locals->ids[i];
- pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- }
- }
- //********END OF STEP 3**********
-
- //********STEP 4**********
- // Goal: fill in the method body locals
- // To be explicit, these are the non-parameter locals
- uint32_t locals_body_index = 0;
-
- switch (PM_NODE_TYPE(scope_node->ast_node)) {
- case PM_BLOCK_NODE: {
- locals_body_index = ((pm_block_node_t *)scope_node->ast_node)->locals_body_index;
- break;
- }
- case PM_DEF_NODE: {
- locals_body_index = ((pm_def_node_t *)scope_node->ast_node)->locals_body_index;
- break;
- }
- case PM_LAMBDA_NODE: {
- locals_body_index = ((pm_lambda_node_t *)scope_node->ast_node)->locals_body_index;
- break;
- }
- default: {
- }
- }
-
- if (scope_node->locals.size) {
- for (size_t i = locals_body_index; i < scope_node->locals.size; i++) {
- pm_constant_id_t constant_id = locals->ids[i];
- if (constant_id) {
- pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- local_index++;
- }
- }
- }
-
- // We fill in the block_locals, if they exist
- // lambda { |x; y| y }
- // ^
- if (block_locals && block_locals->size) {
- for (size_t i = 0; i < block_locals->size; i++, local_index++) {
- pm_constant_id_t constant_id = ((pm_block_local_variable_node_t *)block_locals->nodes[i])->name;
- pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
- }
- }
-
- //********END OF STEP 4**********
-
- // We set the index_lookup_table on the scope node so we can
- // refer to the parameters correctly
- scope_node->index_lookup_table = index_lookup_table;
- iseq_calc_param_size(iseq);
- iseq_set_local_table(iseq, local_table_for_iseq);
- scope_node->local_table_for_iseq_size = local_table_for_iseq->size;
-
- //********STEP 5************
- // Goal: compile anything that needed to be compiled
- if (keywords_list && keywords_list->size) {
- for (size_t i = 0; i < keywords_list->size; i++, local_index++) {
- pm_node_t *keyword_parameter_node = keywords_list->nodes[i];
- pm_constant_id_t name;
-
- switch (PM_NODE_TYPE(keyword_parameter_node)) {
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^^^
- case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
- pm_optional_keyword_parameter_node_t *cast = ((pm_optional_keyword_parameter_node_t *)keyword_parameter_node);
-
- pm_node_t *value = cast->value;
- name = cast->name;
-
- if (!(pm_static_literal_p(value)) ||
- PM_NODE_TYPE_P(value, PM_ARRAY_NODE) ||
- PM_NODE_TYPE_P(value, PM_HASH_NODE) ||
- PM_NODE_TYPE_P(value, PM_RANGE_NODE)) {
- LABEL *end_label = NEW_LABEL(nd_line(&dummy_line_node));
-
- int index = pm_lookup_local_index(iseq, scope_node, name);
- int kw_bits_idx = table_size - body->param.keyword->bits_start;
- ADD_INSN2(ret, &dummy_line_node, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(i));
- ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- PM_COMPILE(value);
- ADD_SETLOCAL(ret, &dummy_line_node, index, 0);
-
- ADD_LABEL(ret, end_label);
- }
- break;
- }
- // def foo(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m, &n)
- // ^^
- case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
- break;
- }
- default: {
- rb_bug("Unexpected keyword parameter node type");
- }
- }
- }
- }
-
- if (optionals_list && optionals_list->size) {
- LABEL **opt_table = (LABEL **)ALLOC_N(VALUE, optionals_list->size + 1);
- LABEL *label;
-
- // TODO: Should we make an api for NEW_LABEL where you can pass
- // a pointer to the label it should fill out? We already
- // have a list of labels allocated above so it seems wasteful
- // to do the copies.
- for (size_t i = 0; i < optionals_list->size; i++, local_index++) {
- label = NEW_LABEL(lineno);
- opt_table[i] = label;
- ADD_LABEL(ret, label);
- pm_node_t *optional_node = optionals_list->nodes[i];
- PM_COMPILE_NOT_POPPED(optional_node);
- }
-
- // Set the last label
- label = NEW_LABEL(lineno);
- opt_table[optionals_list->size] = label;
- ADD_LABEL(ret, label);
-
- body->param.opt_table = (const VALUE *)opt_table;
- }
-
- if (requireds_list && requireds_list->size) {
- for (size_t i = 0; i < requireds_list->size; i++) {
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *required = requireds_list->nodes[i];
- if (PM_NODE_TYPE_P(required, PM_MULTI_TARGET_NODE)) {
- ADD_GETLOCAL(ret, &dummy_line_node, table_size - required_multis_hidden_index, 0);
- PM_COMPILE(required);
- }
- }
- }
-
- if (posts_list && posts_list->size) {
- for (size_t i = 0; i < posts_list->size; i++) {
- // For each MultiTargetNode, we're going to have one
- // additional anonymous local not represented in the locals table
- // We want to account for this in our table size
- pm_node_t *post = posts_list->nodes[i];
- if (PM_NODE_TYPE_P(post, PM_MULTI_TARGET_NODE)) {
- ADD_GETLOCAL(ret, &dummy_line_node, table_size - post_multis_hidden_index, 0);
- PM_COMPILE(post);
- }
- }
- }
-
- switch (body->type) {
- case ISEQ_TYPE_BLOCK: {
- LABEL *start = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(0);
- LABEL *end = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(0);
-
- start->rescued = LABEL_RESCUE_BEG;
- end->rescued = LABEL_RESCUE_END;
-
- ADD_TRACE(ret, RUBY_EVENT_B_CALL);
- NODE dummy_line_node = generate_dummy_line_node(body->location.first_lineno, -1);
- if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0) {
- PM_NOP;
- }
- ADD_LABEL(ret, start);
-
- if (scope_node->body) {
- switch (PM_NODE_TYPE(scope_node->ast_node)) {
- case PM_POST_EXECUTION_NODE: {
- pm_post_execution_node_t *post_execution_node = (pm_post_execution_node_t *)scope_node->ast_node;
-
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
-
- // We create another ScopeNode from the statements within the PostExecutionNode
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)post_execution_node->statements, &next_scope_node, scope_node, parser);
-
- const rb_iseq_t *block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(body->parent_iseq), ISEQ_TYPE_BLOCK, lineno);
-
- ADD_CALL_WITH_BLOCK(ret, &dummy_line_node, id_core_set_postexe, INT2FIX(0), block);
- break;
- }
- case PM_FOR_NODE: {
- pm_for_node_t *for_node = (pm_for_node_t *)scope_node->ast_node;
- LABEL *target = NEW_LABEL(lineno);
- LABEL *old_start = ISEQ_COMPILE_DATA(iseq)->start_label;
-
- ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
- PM_COMPILE(for_node->index);
- PM_NOP;
- ADD_LABEL(ret, target);
- ISEQ_COMPILE_DATA(iseq)->start_label = target;
- pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, scope_node);
- ISEQ_COMPILE_DATA(iseq)->start_label = old_start;
- break;
- }
- case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
- pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) scope_node->ast_node;
-
- int parts_size = (int)cast->parts.size;
- if (parts_size > 0 && !PM_NODE_TYPE_P(cast->parts.nodes[0], PM_STRING_NODE)) {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_str_new(0, 0));
- parts_size++;
- }
-
- pm_interpolated_node_compile(&cast->parts, iseq, dummy_line_node, ret, src, false, scope_node, parser);
- ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags((pm_node_t *)cast)), INT2FIX(parts_size));
- break;
- }
- default: {
- pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, scope_node);
- }
- }
- }
- else {
- PM_PUTNIL;
- }
-
- ADD_LABEL(ret, end);
- ADD_TRACE(ret, RUBY_EVENT_B_RETURN);
- ISEQ_COMPILE_DATA(iseq)->last_line = body->location.code_location.end_pos.lineno;
-
- /* wide range catch handler must put at last */
- ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, NULL, start);
- ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, end, NULL, end);
- break;
- }
- case ISEQ_TYPE_ENSURE: {
- iseq_set_exception_local_table(iseq);
-
- if (scope_node->body) {
- PM_COMPILE_POPPED((pm_node_t *)scope_node->body);
- }
-
- ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(0));
- return;
- }
- case ISEQ_TYPE_RESCUE: {
- iseq_set_exception_local_table(iseq);
- if (PM_NODE_TYPE_P(scope_node->ast_node, PM_RESCUE_MODIFIER_NODE)) {
- LABEL *lab = NEW_LABEL(lineno);
- LABEL *rescue_end = NEW_LABEL(lineno);
- ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_eStandardError);
- ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
- ADD_INSN1(ret, &dummy_line_node, branchif, lab);
- ADD_INSN1(ret, &dummy_line_node, jump, rescue_end);
- ADD_LABEL(ret, lab);
- PM_COMPILE((pm_node_t *)scope_node->body);
- ADD_INSN(ret, &dummy_line_node, leave);
- ADD_LABEL(ret, rescue_end);
- ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- }
- else {
- PM_COMPILE((pm_node_t *)scope_node->ast_node);
- }
- ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(0));
-
- return;
- }
- default:
- if (scope_node->body) {
- PM_COMPILE((pm_node_t *)scope_node->body);
- }
- else {
- PM_PUTNIL;
- }
- }
-
- st_free_table(index_lookup_table);
-
- if (!PM_NODE_TYPE_P(scope_node->ast_node, PM_ENSURE_NODE)) {
- ADD_INSN(ret, &dummy_line_node, leave);
- }
- return;
- }
- case PM_SELF_NODE:
- if (!popped) {
- PM_PUTSELF;
- }
- return;
- case PM_SINGLETON_CLASS_NODE: {
- pm_singleton_class_node_t *singleton_class_node = (pm_singleton_class_node_t *)node;
- pm_scope_node_t next_scope_node;
- pm_scope_node_init((pm_node_t *)singleton_class_node, &next_scope_node, scope_node, parser);
-
- const rb_iseq_t *singleton_class = NEW_ISEQ(next_scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, lineno);
-
- PM_COMPILE_NOT_POPPED(singleton_class_node->expression);
- PM_PUTNIL;
- ID singletonclass;
- CONST_ID(singletonclass, "singletonclass");
-
- ADD_INSN3(ret, &dummy_line_node, defineclass,
- ID2SYM(singletonclass), singleton_class,
- INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS));
- PM_POP_IF_POPPED;
- RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_class);
-
- return;
- }
- case PM_SOURCE_ENCODING_NODE: {
- // Source encoding nodes are generated by the __ENCODING__ syntax. They
- // reference the encoding object corresponding to the encoding of the
- // source file, and can be changed by a magic encoding comment.
- if (!popped) {
- VALUE value = pm_static_literal_value(node, scope_node, parser);
- ADD_INSN1(ret, &dummy_line_node, putobject, value);
- RB_OBJ_WRITTEN(iseq, Qundef, value);
- }
- return;
- }
- case PM_SOURCE_FILE_NODE: {
- // Source file nodes are generated by the __FILE__ syntax. They
- // reference the file name of the source file.
- if (!popped) {
- VALUE value = pm_static_literal_value(node, scope_node, parser);
- ADD_INSN1(ret, &dummy_line_node, putstring, value);
- RB_OBJ_WRITTEN(iseq, Qundef, value);
- }
- return;
- }
- case PM_SOURCE_LINE_NODE: {
- // Source line nodes are generated by the __LINE__ syntax. They
- // reference the line number where they occur in the source file.
- if (!popped) {
- VALUE value = pm_static_literal_value(node, scope_node, parser);
- ADD_INSN1(ret, &dummy_line_node, putobject, value);
- RB_OBJ_WRITTEN(iseq, Qundef, value);
- }
- return;
- }
- case PM_SPLAT_NODE: {
- pm_splat_node_t *splat_node = (pm_splat_node_t *)node;
- if (splat_node->expression) {
- PM_COMPILE(splat_node->expression);
- }
-
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
- }
- return;
- }
- case PM_STATEMENTS_NODE: {
- pm_statements_node_t *statements_node = (pm_statements_node_t *) node;
- pm_node_list_t node_list = statements_node->body;
- if (node_list.size > 0) {
- for (size_t index = 0; index < node_list.size - 1; index++) {
- PM_COMPILE_POPPED(node_list.nodes[index]);
- }
- PM_COMPILE(node_list.nodes[node_list.size - 1]);
- }
- else {
- PM_PUTNIL;
- }
- return;
- }
- case PM_STRING_NODE: {
- if (!popped) {
- pm_string_node_t *cast = (pm_string_node_t *) node;
- VALUE value = parse_string_encoded(node, &cast->unescaped, parser);
- if (node->flags & PM_STRING_FLAGS_FROZEN) {
- ADD_INSN1(ret, &dummy_line_node, putobject, rb_str_freeze(value));
- }
- else {
- ADD_INSN1(ret, &dummy_line_node, putstring, value);
- }
- }
- return;
- }
- case PM_SUPER_NODE: {
- pm_super_node_t *super_node = (pm_super_node_t *) node;
-
- DECL_ANCHOR(args);
-
- int flags = 0;
- struct rb_callinfo_kwarg *keywords = NULL;
- const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
-
- INIT_ANCHOR(args);
- ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
-
- PM_PUTSELF;
-
- int argc = pm_setup_args(super_node->arguments, &flags, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
-
- flags |= VM_CALL_SUPER | VM_CALL_FCALL;
-
- if (super_node->block) {
- switch (PM_NODE_TYPE(super_node->block)) {
- case PM_BLOCK_ARGUMENT_NODE: {
- PM_COMPILE_NOT_POPPED(super_node->block);
- flags |= VM_CALL_ARGS_BLOCKARG;
- break;
- }
- case PM_BLOCK_NODE: {
- pm_scope_node_t next_scope_node;
- pm_scope_node_init(super_node->block, &next_scope_node, scope_node, parser);
- parent_block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
- break;
- }
- default: {
- rb_bug("This node type should never occur on a SuperNode's block");
- }
- }
- }
-
- ADD_SEQ(ret, args);
- ADD_INSN2(ret, &dummy_line_node, invokesuper,
- new_callinfo(iseq, 0, argc, flags, keywords, parent_block != NULL),
- parent_block);
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_SYMBOL_NODE: {
- // Symbols nodes are symbol literals with no interpolation. They are
- // always marked as static literals.
- if (!popped) {
- VALUE value = pm_static_literal_value(node, scope_node, parser);
- ADD_INSN1(ret, &dummy_line_node, putobject, value);
- RB_OBJ_WRITTEN(iseq, Qundef, value);
- }
- return;
- }
- case PM_TRUE_NODE:
- if (!popped) {
- ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
- }
- return;
- case PM_UNDEF_NODE: {
- pm_undef_node_t *undef_node = (pm_undef_node_t *) node;
-
- for (size_t index = 0; index < undef_node->names.size; index++) {
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
-
- PM_COMPILE_NOT_POPPED(undef_node->names.nodes[index]);
-
- ADD_SEND(ret, &dummy_line_node, id_core_undef_method, INT2NUM(2));
-
- if (index < undef_node->names.size - 1) {
- PM_POP;
- }
- }
-
- PM_POP_IF_POPPED;
-
- return;
- }
- case PM_UNLESS_NODE: {
- const int line = (int)pm_newline_list_line_column(&(parser->newline_list), node->location.start).line;
- pm_unless_node_t *unless_node = (pm_unless_node_t *)node;
- pm_node_t *node_body = (pm_node_t *)(unless_node->statements);
- pm_statements_node_t *node_else = NULL;
- if (unless_node->consequent != NULL) {
- node_else = ((pm_else_node_t *)unless_node->consequent)->statements;
- }
- pm_node_t *predicate = unless_node->predicate;
-
- pm_compile_if(iseq, line, node_else, node_body, predicate, ret, src, popped, scope_node);
- return;
- }
- case PM_UNTIL_NODE: {
- pm_until_node_t *until_node = (pm_until_node_t *)node;
- pm_statements_node_t *statements = until_node->statements;
- pm_node_t *predicate = until_node->predicate;
- pm_node_flags_t flags = node->flags;
-
- pm_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, scope_node);
- return;
- }
- case PM_WHEN_NODE: {
- rb_bug("Should not ever enter a when node directly");
- return;
- }
- case PM_WHILE_NODE: {
- pm_while_node_t *while_node = (pm_while_node_t *)node;
- pm_statements_node_t *statements = while_node->statements;
- pm_node_t *predicate = while_node->predicate;
- pm_node_flags_t flags = node->flags;
-
- pm_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, scope_node);
- return;
- }
- case PM_X_STRING_NODE: {
- pm_x_string_node_t *cast = (pm_x_string_node_t *) node;
- VALUE value = parse_string_encoded(node, &cast->unescaped, parser);
-
- PM_PUTSELF;
- ADD_INSN1(ret, &dummy_line_node, putobject, value);
- ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idBackquote, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
-
- PM_POP_IF_POPPED;
- return;
- }
- case PM_YIELD_NODE: {
- pm_yield_node_t *yield_node = (pm_yield_node_t *)node;
-
- int flags = 0;
- struct rb_callinfo_kwarg *keywords = NULL;
-
- int argc = 0;
-
- if (yield_node->arguments) {
- argc = pm_setup_args(yield_node->arguments, &flags, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
- }
-
- ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE));
-
- PM_POP_IF_POPPED;
-
- int level = 0;
- const rb_iseq_t *tmp_iseq = iseq;
- for (; tmp_iseq != ISEQ_BODY(iseq)->local_iseq; level++ ) {
- tmp_iseq = ISEQ_BODY(tmp_iseq)->parent_iseq;
- }
-
- if (level > 0) access_outer_variables(iseq, level, rb_intern("yield"), true);
-
- return;
- }
- default:
- rb_raise(rb_eNotImpError, "node type %s not implemented", pm_node_type_to_str(PM_NODE_TYPE(node)));
- return;
- }
-}
-
-static VALUE
-rb_translate_prism(pm_parser_t *parser, rb_iseq_t *iseq, pm_scope_node_t *scope_node, LINK_ANCHOR *const ret)
-{
- RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq));
-
- ID *constants = calloc(parser->constant_pool.size, sizeof(ID));
- rb_encoding *encoding = rb_enc_find(parser->encoding->name);
- for (uint32_t index = 0; index < parser->constant_pool.size; index++) {
- pm_constant_t *constant = &parser->constant_pool.constants[index];
- constants[index] = rb_intern3((const char *) constant->start, constant->length, encoding);
- }
-
- st_table *index_lookup_table = st_init_numtable();
- pm_constant_id_list_t *locals = &scope_node->locals;
- for (size_t i = 0; i < locals->size; i++) {
- st_insert(index_lookup_table, locals->ids[i], i);
- }
- scope_node->constants = constants;
- scope_node->index_lookup_table = index_lookup_table;
-
- pm_compile_node(iseq, (pm_node_t *)scope_node, ret, scope_node->base.location.start, false, (pm_scope_node_t *)scope_node);
- iseq_set_sequence(iseq, ret);
-
- free(constants);
- return Qnil;
-}
-
-#undef NEW_ISEQ
-#define NEW_ISEQ OLD_ISEQ
-
-#undef NEW_CHILD_ISEQ
-#define NEW_CHILD_ISEQ OLD_CHILD_ISEQ
diff --git a/prism_compile.h b/prism_compile.h
deleted file mode 100644
index ed0c7b4c91..0000000000
--- a/prism_compile.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "prism/prism.h"
-
-// ScopeNodes are helper nodes, and will never be part of the AST. We manually
-// declare them here to avoid generating them.
-typedef struct pm_scope_node {
- pm_node_t base;
- struct pm_scope_node *previous;
- pm_node_t *ast_node;
- pm_node_t *parameters;
- pm_node_t *body;
- pm_constant_id_list_t locals;
- pm_parser_t *parser;
-
- // The size of the local table
- // on the iseq which includes
- // locals and hidden variables
- int local_table_for_iseq_size;
-
- ID *constants;
- st_table *index_lookup_table;
-
- // Some locals are defined at higher scopes than they are used. We can use
- // this offset to control which parent scopes local table we should be
- // referencing from the current scope.
- unsigned int local_depth_offset;
-} pm_scope_node_t;
-
-void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser);
-bool *rb_ruby_prism_ptr(void);
diff --git a/prism_init.c b/prism_init.c
deleted file mode 100644
index ddc87fad85..0000000000
--- a/prism_init.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "prism/extension.h"
-
-void ruby_init_ext(const char *name, void (*init)(void));
-
-void
-Init_Prism(void)
-{
- ruby_init_ext("prism/prism.so", Init_prism);
-}
diff --git a/probes_helper.h b/probes_helper.h
index 16d81b9ffb..0003e96dd8 100644
--- a/probes_helper.h
+++ b/probes_helper.h
@@ -12,7 +12,9 @@ struct ruby_dtrace_method_hook_args {
volatile VALUE name;
};
+MJIT_SYMBOL_EXPORT_BEGIN
NOINLINE(int rb_dtrace_setup(rb_execution_context_t *, VALUE, ID, struct ruby_dtrace_method_hook_args *));
+MJIT_SYMBOL_EXPORT_END
#define RUBY_DTRACE_METHOD_HOOK(name, ec, klazz, id) \
do { \
diff --git a/proc.c b/proc.c
index 54b6ce85c1..bb0ad89851 100644
--- a/proc.c
+++ b/proc.c
@@ -10,11 +10,12 @@
**********************************************************************/
#include "eval_intern.h"
+#include "gc.h"
#include "internal.h"
#include "internal/class.h"
#include "internal/error.h"
#include "internal/eval.h"
-#include "internal/gc.h"
+#include "internal/hash.h"
#include "internal/object.h"
#include "internal/proc.h"
#include "internal/symbol.h"
@@ -23,6 +24,15 @@
#include "vm_core.h"
#include "yjit.h"
+#if !defined(__GNUC__) || __GNUC__ < 5 || defined(__MINGW32__)
+# define NO_CLOBBERED(v) (*(volatile VALUE *)&(v))
+#else
+# define NO_CLOBBERED(v) (v)
+#endif
+
+#define UPDATE_TYPED_REFERENCE(_type, _ref) *(_type*)&_ref = (_type)rb_gc_location((VALUE)_ref)
+#define UPDATE_REFERENCE(_ref) UPDATE_TYPED_REFERENCE(VALUE, _ref)
+
const rb_cref_t *rb_vm_cref_in_context(VALUE self, VALUE cbase);
struct METHOD {
@@ -47,39 +57,87 @@ static int method_arity(VALUE);
static int method_min_max_arity(VALUE, int *max);
static VALUE proc_binding(VALUE self);
+#define attached id__attached__
+
/* Proc */
#define IS_METHOD_PROC_IFUNC(ifunc) ((ifunc)->func == bmcall)
+/* :FIXME: The way procs are cloned has been historically different from the
+ * way everything else are. @shyouhei is not sure for the intention though.
+ */
+#undef CLONESETUP
+static inline void
+CLONESETUP(VALUE clone, VALUE obj)
+{
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
+ RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(clone));
+
+ const VALUE flags = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1 | RUBY_FL_FINALIZE;
+ rb_obj_setup(clone, rb_singleton_class_clone(obj),
+ RB_FL_TEST_RAW(obj, ~flags));
+ rb_singleton_class_attached(RBASIC_CLASS(clone), clone);
+ if (RB_FL_TEST(obj, RUBY_FL_EXIVAR)) rb_copy_generic_ivar(clone, obj);
+}
+
+static void
+block_mark(const struct rb_block *block)
+{
+ switch (vm_block_type(block)) {
+ case block_type_iseq:
+ case block_type_ifunc:
+ {
+ const struct rb_captured_block *captured = &block->as.captured;
+ RUBY_MARK_MOVABLE_UNLESS_NULL(captured->self);
+ RUBY_MARK_MOVABLE_UNLESS_NULL((VALUE)captured->code.val);
+ if (captured->ep && !UNDEF_P(captured->ep[VM_ENV_DATA_INDEX_ENV]) /* cfunc_proc_t */) {
+ rb_gc_mark(VM_ENV_ENVVAL(captured->ep));
+ }
+ }
+ break;
+ case block_type_symbol:
+ RUBY_MARK_MOVABLE_UNLESS_NULL(block->as.symbol);
+ break;
+ case block_type_proc:
+ RUBY_MARK_MOVABLE_UNLESS_NULL(block->as.proc);
+ break;
+ }
+}
+
static void
-block_mark_and_move(struct rb_block *block)
+block_compact(struct rb_block *block)
{
switch (block->type) {
case block_type_iseq:
case block_type_ifunc:
{
struct rb_captured_block *captured = &block->as.captured;
- rb_gc_mark_and_move(&captured->self);
- rb_gc_mark_and_move(&captured->code.val);
- if (captured->ep) {
- rb_gc_mark_and_move((VALUE *)&captured->ep[VM_ENV_DATA_INDEX_ENV]);
- }
+ captured->self = rb_gc_location(captured->self);
+ captured->code.val = rb_gc_location(captured->code.val);
}
break;
case block_type_symbol:
- rb_gc_mark_and_move(&block->as.symbol);
+ block->as.symbol = rb_gc_location(block->as.symbol);
break;
case block_type_proc:
- rb_gc_mark_and_move(&block->as.proc);
+ block->as.proc = rb_gc_location(block->as.proc);
break;
}
}
static void
-proc_mark_and_move(void *ptr)
+proc_compact(void *ptr)
+{
+ rb_proc_t *proc = ptr;
+ block_compact((struct rb_block *)&proc->block);
+}
+
+static void
+proc_mark(void *ptr)
{
rb_proc_t *proc = ptr;
- block_mark_and_move((struct rb_block *)&proc->block);
+ block_mark(&proc->block);
+ RUBY_MARK_LEAVE("proc");
}
typedef struct {
@@ -99,10 +157,10 @@ proc_memsize(const void *ptr)
static const rb_data_type_t proc_data_type = {
"proc",
{
- proc_mark_and_move,
+ proc_mark,
RUBY_TYPED_DEFAULT_FREE,
proc_memsize,
- proc_mark_and_move,
+ proc_compact,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
};
@@ -125,15 +183,8 @@ static VALUE
proc_clone(VALUE self)
{
VALUE procval = rb_proc_dup(self);
- return rb_obj_clone_setup(self, procval, Qnil);
-}
-
-/* :nodoc: */
-static VALUE
-proc_dup(VALUE self)
-{
- VALUE procval = rb_proc_dup(self);
- return rb_obj_dup_setup(self, procval);
+ CLONESETUP(procval, self);
+ return procval;
}
/*
@@ -259,12 +310,23 @@ binding_free(void *ptr)
}
static void
-binding_mark_and_move(void *ptr)
+binding_mark(void *ptr)
{
rb_binding_t *bind = ptr;
- block_mark_and_move((struct rb_block *)&bind->block);
- rb_gc_mark_and_move((VALUE *)&bind->pathobj);
+ RUBY_MARK_ENTER("binding");
+ block_mark(&bind->block);
+ rb_gc_mark_movable(bind->pathobj);
+ RUBY_MARK_LEAVE("binding");
+}
+
+static void
+binding_compact(void *ptr)
+{
+ rb_binding_t *bind = ptr;
+
+ block_compact((struct rb_block *)&bind->block);
+ UPDATE_REFERENCE(bind->pathobj);
}
static size_t
@@ -276,10 +338,10 @@ binding_memsize(const void *ptr)
const rb_data_type_t ruby_binding_data_type = {
"binding",
{
- binding_mark_and_move,
+ binding_mark,
binding_free,
binding_memsize,
- binding_mark_and_move,
+ binding_compact,
},
0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -308,7 +370,7 @@ binding_dup(VALUE self)
rb_vm_block_copy(bindval, &dst->block, &src->block);
RB_OBJ_WRITE(bindval, &dst->pathobj, src->pathobj);
dst->first_lineno = src->first_lineno;
- return rb_obj_dup_setup(self, bindval);
+ return bindval;
}
/* :nodoc: */
@@ -316,7 +378,8 @@ static VALUE
binding_clone(VALUE self)
{
VALUE bindval = binding_dup(self);
- return rb_obj_clone_setup(self, bindval, Qnil);
+ CLONESETUP(bindval, self);
+ return bindval;
}
VALUE
@@ -330,44 +393,16 @@ rb_binding_new(void)
* call-seq:
* binding -> a_binding
*
- * Returns a Binding object, describing the variable and
+ * Returns a +Binding+ object, describing the variable and
* method bindings at the point of call. This object can be used when
- * calling Binding#eval to execute the evaluated command in this
- * environment, or extracting its local variables.
+ * calling +eval+ to execute the evaluated command in this
+ * environment. See also the description of class +Binding+.
*
- * class User
- * def initialize(name, position)
- * @name = name
- * @position = position
- * end
- *
- * def get_binding
- * binding
- * end
- * end
- *
- * user = User.new('Joan', 'manager')
- * template = '{name: @name, position: @position}'
- *
- * # evaluate template in context of the object
- * eval(template, user.get_binding)
- * #=> {:name=>"Joan", :position=>"manager"}
- *
- * Binding#local_variable_get can be used to access the variables
- * whose names are reserved Ruby keywords:
- *
- * # This is valid parameter declaration, but `if` parameter can't
- * # be accessed by name, because it is a reserved word.
- * def validate(field, validation, if: nil)
- * condition = binding.local_variable_get('if')
- * return unless condition
- *
- * # ...Some implementation ...
+ * def get_binding(param)
+ * binding
* end
- *
- * validate(:name, :empty?, if: false) # skips validation
- * validate(:name, :empty?, if: true) # performs validation
- *
+ * b = get_binding("hello")
+ * eval("param", b) #=> "hello"
*/
static VALUE
@@ -718,19 +753,18 @@ rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int m
}
arity.argc.min = min_argc;
arity.argc.max = max_argc;
- rb_execution_context_t *ec = GET_EC();
- VALUE ret = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)data, arity.packed, (VALUE)rb_vm_svar_lep(ec, ec->cfp));
+ VALUE ret = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)data, arity.packed, 0);
return (struct vm_ifunc *)ret;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_func_proc_new(rb_block_call_func_t func, VALUE val)
{
struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(func, (void *)val);
return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc)
{
struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (void *)val, min_argc, max_argc);
@@ -740,7 +774,7 @@ rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_a
static const char proc_without_block[] = "tried to create Proc object without a block";
static VALUE
-proc_new(VALUE klass, int8_t is_lambda)
+proc_new(VALUE klass, int8_t is_lambda, int8_t kernel)
{
VALUE procval;
const rb_execution_context_t *ec = GET_EC();
@@ -773,8 +807,16 @@ proc_new(VALUE klass, int8_t is_lambda)
break;
case block_handler_type_ifunc:
- case block_handler_type_iseq:
return rb_vm_make_proc_lambda(ec, VM_BH_TO_CAPT_BLOCK(block_handler), klass, is_lambda);
+ case block_handler_type_iseq:
+ {
+ const struct rb_captured_block *captured = VM_BH_TO_CAPT_BLOCK(block_handler);
+ rb_control_frame_t *last_ruby_cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
+ if (is_lambda && last_ruby_cfp && vm_cfp_forwarded_bh_p(last_ruby_cfp, block_handler)) {
+ is_lambda = false;
+ }
+ return rb_vm_make_proc_lambda(ec, captured, klass, is_lambda);
+ }
}
VM_UNREACHABLE(proc_new);
return Qnil;
@@ -797,7 +839,7 @@ proc_new(VALUE klass, int8_t is_lambda)
static VALUE
rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
{
- VALUE block = proc_new(klass, FALSE);
+ VALUE block = proc_new(klass, FALSE, FALSE);
rb_obj_call_init_kw(block, argc, argv, RB_PASS_CALLED_KEYWORDS);
return block;
@@ -806,7 +848,7 @@ rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
VALUE
rb_block_proc(void)
{
- return proc_new(rb_cProc, FALSE);
+ return proc_new(rb_cProc, FALSE, FALSE);
}
/*
@@ -819,44 +861,41 @@ rb_block_proc(void)
static VALUE
f_proc(VALUE _)
{
- return proc_new(rb_cProc, FALSE);
+ return proc_new(rb_cProc, FALSE, TRUE);
}
VALUE
rb_block_lambda(void)
{
- return proc_new(rb_cProc, TRUE);
+ return proc_new(rb_cProc, TRUE, FALSE);
}
static void
-f_lambda_filter_non_literal(void)
+f_lambda_warn(void)
{
rb_control_frame_t *cfp = GET_EC()->cfp;
VALUE block_handler = rb_vm_frame_block_handler(cfp);
- if (block_handler == VM_BLOCK_HANDLER_NONE) {
- // no block erorr raised else where
- return;
- }
-
- switch (vm_block_handler_type(block_handler)) {
- case block_handler_type_iseq:
- if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
- return;
- }
- break;
- case block_handler_type_symbol:
- return;
- case block_handler_type_proc:
- if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
+ if (block_handler != VM_BLOCK_HANDLER_NONE) {
+ switch (vm_block_handler_type(block_handler)) {
+ case block_handler_type_iseq:
+ if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
+ return;
+ }
+ break;
+ case block_handler_type_symbol:
return;
+ case block_handler_type_proc:
+ if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
+ return;
+ }
+ break;
+ case block_handler_type_ifunc:
+ break;
}
- break;
- case block_handler_type_ifunc:
- break;
}
- rb_raise(rb_eArgError, "the lambda method requires a literal block");
+ rb_warn_deprecated("lambda without a literal block", "the proc without lambda");
}
/*
@@ -870,7 +909,7 @@ f_lambda_filter_non_literal(void)
static VALUE
f_lambda(VALUE _)
{
- f_lambda_filter_non_literal();
+ f_lambda_warn();
return rb_block_lambda();
}
@@ -1334,7 +1373,7 @@ iseq_location(const rb_iseq_t *iseq)
return rb_ary_new4(2, loc);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_iseq_location(const rb_iseq_t *iseq)
{
return iseq_location(iseq);
@@ -1426,8 +1465,24 @@ rb_hash_proc(st_index_t hash, VALUE prc)
{
rb_proc_t *proc;
GetProcPtr(prc, proc);
- hash = rb_hash_uint(hash, (st_index_t)proc->block.as.captured.code.val);
- hash = rb_hash_uint(hash, (st_index_t)proc->block.as.captured.self);
+
+ switch (vm_block_type(&proc->block)) {
+ case block_type_iseq:
+ hash = rb_st_hash_uint(hash, (st_index_t)proc->block.as.captured.code.iseq->body);
+ break;
+ case block_type_ifunc:
+ hash = rb_st_hash_uint(hash, (st_index_t)proc->block.as.captured.code.ifunc->func);
+ break;
+ case block_type_symbol:
+ hash = rb_st_hash_uint(hash, rb_any_hash(proc->block.as.symbol));
+ break;
+ case block_type_proc:
+ hash = rb_st_hash_uint(hash, rb_any_hash(proc->block.as.proc));
+ break;
+ default:
+ rb_bug("rb_hash_proc: unknown block type %d", vm_block_type(&proc->block));
+ }
+
return rb_hash_uint(hash, (st_index_t)proc->block.as.captured.ep);
}
@@ -1446,7 +1501,7 @@ rb_hash_proc(st_index_t hash, VALUE prc)
*
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_sym_to_proc(VALUE sym)
{
static VALUE sym_proc_cache = Qfalse;
@@ -1557,25 +1612,42 @@ proc_to_proc(VALUE self)
}
static void
-bm_mark_and_move(void *ptr)
+bm_mark(void *ptr)
{
struct METHOD *data = ptr;
- rb_gc_mark_and_move((VALUE *)&data->recv);
- rb_gc_mark_and_move((VALUE *)&data->klass);
- rb_gc_mark_and_move((VALUE *)&data->iclass);
- rb_gc_mark_and_move((VALUE *)&data->owner);
- rb_gc_mark_and_move_ptr((rb_method_entry_t **)&data->me);
+ rb_gc_mark_movable(data->recv);
+ rb_gc_mark_movable(data->klass);
+ rb_gc_mark_movable(data->iclass);
+ rb_gc_mark_movable(data->owner);
+ rb_gc_mark_movable((VALUE)data->me);
+}
+
+static void
+bm_compact(void *ptr)
+{
+ struct METHOD *data = ptr;
+ UPDATE_REFERENCE(data->recv);
+ UPDATE_REFERENCE(data->klass);
+ UPDATE_REFERENCE(data->iclass);
+ UPDATE_REFERENCE(data->owner);
+ UPDATE_TYPED_REFERENCE(rb_method_entry_t *, data->me);
+}
+
+static size_t
+bm_memsize(const void *ptr)
+{
+ return sizeof(struct METHOD);
}
static const rb_data_type_t method_data_type = {
"method",
{
- bm_mark_and_move,
+ bm_mark,
RUBY_TYPED_DEFAULT_FREE,
- NULL, // No external memory to report,
- bm_mark_and_move,
+ bm_memsize,
+ bm_compact,
},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
VALUE
@@ -1769,8 +1841,8 @@ method_eq(VALUE method, VALUE other)
return Qfalse;
Check_TypedStruct(method, &method_data_type);
- m1 = (struct METHOD *)RTYPEDDATA_GET_DATA(method);
- m2 = (struct METHOD *)RTYPEDDATA_GET_DATA(other);
+ m1 = (struct METHOD *)DATA_PTR(method);
+ m2 = (struct METHOD *)DATA_PTR(other);
klass1 = method_entry_defined_class(m1->me);
klass2 = method_entry_defined_class(m2->me);
@@ -1941,7 +2013,7 @@ rb_method_name_error(VALUE klass, VALUE str)
VALUE s = Qundef;
if (FL_TEST(c, FL_SINGLETON)) {
- VALUE obj = RCLASS_ATTACHED_OBJECT(klass);
+ VALUE obj = rb_ivar_get(klass, attached);
switch (BUILTIN_TYPE(obj)) {
case T_MODULE:
@@ -2065,9 +2137,10 @@ rb_obj_singleton_method(VALUE obj, VALUE vid)
VALUE klass = rb_singleton_class_get(obj);
ID id = rb_check_id(&vid);
- if (NIL_P(klass) ||
- NIL_P(klass = RCLASS_ORIGIN(klass)) ||
- !NIL_P(rb_special_singleton_class(obj))) {
+ if (NIL_P(klass)) {
+ /* goto undef; */
+ }
+ else if (NIL_P(klass = RCLASS_ORIGIN(klass))) {
/* goto undef; */
}
else if (! id) {
@@ -2186,7 +2259,7 @@ rb_mod_define_method_with_visibility(int argc, VALUE *argv, VALUE mod, const str
if (!id) id = rb_to_id(name);
if (is_method) {
- struct METHOD *method = (struct METHOD *)RTYPEDDATA_GET_DATA(body);
+ struct METHOD *method = (struct METHOD *)DATA_PTR(body);
if (method->me->owner != mod && !RB_TYPE_P(method->me->owner, T_MODULE) &&
!RTEST(rb_class_inherited_p(mod, method->me->owner))) {
if (FL_TEST(method->me->owner, FL_SINGLETON)) {
@@ -2354,25 +2427,7 @@ method_clone(VALUE self)
TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
- rb_obj_clone_setup(self, clone, Qnil);
- RB_OBJ_WRITE(clone, &data->recv, orig->recv);
- RB_OBJ_WRITE(clone, &data->klass, orig->klass);
- RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
- RB_OBJ_WRITE(clone, &data->owner, orig->owner);
- RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
- return clone;
-}
-
-/* :nodoc: */
-static VALUE
-method_dup(VALUE self)
-{
- VALUE clone;
- struct METHOD *orig, *data;
-
- TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
- clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
- rb_obj_dup_setup(self, clone);
+ CLONESETUP(clone, self);
RB_OBJ_WRITE(clone, &data->recv, orig->recv);
RB_OBJ_WRITE(clone, &data->klass, orig->klass);
RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
@@ -3118,7 +3173,7 @@ method_inspect(VALUE method)
rb_str_buf_append(str, rb_inspect(defined_class));
}
else if (FL_TEST(mklass, FL_SINGLETON)) {
- VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
+ VALUE v = rb_ivar_get(mklass, attached);
if (UNDEF_P(data->recv)) {
rb_str_buf_append(str, rb_inspect(mklass));
@@ -3138,7 +3193,7 @@ method_inspect(VALUE method)
else {
mklass = data->klass;
if (FL_TEST(mklass, FL_SINGLETON)) {
- VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
+ VALUE v = rb_ivar_get(mklass, attached);
if (!(RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE))) {
do {
mklass = RCLASS_SUPER(mklass);
@@ -3397,15 +3452,9 @@ env_clone(const rb_env_t *env, const rb_cref_t *cref)
}
new_body = ALLOC_N(VALUE, env->env_size);
+ MEMCPY(new_body, env->env, VALUE, env->env_size);
new_ep = &new_body[env->ep - env->env];
new_env = vm_env_new(new_ep, new_body, env->env_size, env->iseq);
-
- /* The memcpy has to happen after the vm_env_new because it can trigger a
- * GC compaction which can move the objects in the env. */
- MEMCPY(new_body, env->env, VALUE, env->env_size);
- /* VM_ENV_DATA_INDEX_ENV is set in vm_env_new but will get overwritten
- * by the memcpy above. */
- new_ep[VM_ENV_DATA_INDEX_ENV] = (VALUE)new_env;
RB_OBJ_WRITE(new_env, &new_ep[VM_ENV_DATA_INDEX_ME_CREF], (VALUE)cref);
VM_ASSERT(VM_ENV_ESCAPED_P(new_ep));
return new_env;
@@ -4246,7 +4295,7 @@ Init_Proc(void)
rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
rb_define_method(rb_cProc, "arity", proc_arity, 0);
rb_define_method(rb_cProc, "clone", proc_clone, 0);
- rb_define_method(rb_cProc, "dup", proc_dup, 0);
+ rb_define_method(rb_cProc, "dup", rb_proc_dup, 0);
rb_define_method(rb_cProc, "hash", proc_hash, 0);
rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
rb_define_alias(rb_cProc, "inspect", "to_s");
@@ -4282,7 +4331,6 @@ Init_Proc(void)
rb_define_method(rb_cMethod, "eql?", method_eq, 1);
rb_define_method(rb_cMethod, "hash", method_hash, 0);
rb_define_method(rb_cMethod, "clone", method_clone, 0);
- rb_define_method(rb_cMethod, "dup", method_dup, 0);
rb_define_method(rb_cMethod, "call", rb_method_call_pass_called_kw, -1);
rb_define_method(rb_cMethod, "===", rb_method_call_pass_called_kw, -1);
rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
@@ -4313,7 +4361,6 @@ Init_Proc(void)
rb_define_method(rb_cUnboundMethod, "eql?", unbound_method_eq, 1);
rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
- rb_define_method(rb_cUnboundMethod, "dup", method_dup, 0);
rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
diff --git a/process.c b/process.c
index aff350331b..c317a4cc2c 100644
--- a/process.c
+++ b/process.c
@@ -103,20 +103,18 @@ int initgroups(const char *, rb_gid_t);
#include "internal/error.h"
#include "internal/eval.h"
#include "internal/hash.h"
-#include "internal/io.h"
#include "internal/numeric.h"
#include "internal/object.h"
#include "internal/process.h"
#include "internal/thread.h"
#include "internal/variable.h"
#include "internal/warnings.h"
-#include "rjit.h"
+#include "mjit.h"
#include "ruby/io.h"
#include "ruby/st.h"
#include "ruby/thread.h"
#include "ruby/util.h"
#include "vm_core.h"
-#include "vm_sync.h"
#include "ruby/ractor.h"
/* define system APIs */
@@ -361,8 +359,6 @@ static ID id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC;
#endif
static ID id_hertz;
-static rb_pid_t cached_pid;
-
/* execv and execl are async-signal-safe since SUSv4 (POSIX.1-2008, XPG7) */
#if defined(__sun) && !defined(_XPG7) /* Solaris 10, 9, ... */
#define execv(path, argv) (rb_async_bug_errno("unreachable: async-signal-unsafe execv() is called", 0))
@@ -498,32 +494,38 @@ parent_redirect_close(int fd)
#define parent_redirect_close(fd) close_unless_reserved(fd)
#endif
+/*
+ * Document-module: Process
+ *
+ * The module contains several groups of functionality for handling OS processes:
+ *
+ * * Low-level property introspection and management of the current process, like
+ * Process.argv0, Process.pid;
+ * * Low-level introspection of other processes, like Process.getpgid, Process.getpriority;
+ * * Management of the current process: Process.abort, Process.exit, Process.daemon, etc.
+ * (for convenience, most of those are also available as global functions
+ * and module functions of Kernel);
+ * * Creation and management of child processes: Process.fork, Process.spawn, and
+ * related methods;
+ * * Management of low-level system clock: Process.times and Process.clock_gettime,
+ * which could be important for proper benchmarking and other elapsed
+ * time measurement tasks.
+ */
+
static VALUE
get_pid(void)
{
- if (UNLIKELY(!cached_pid)) { /* 0 is not a valid pid */
- cached_pid = getpid();
- }
- /* pid should be likely POSFIXABLE() */
- return PIDT2NUM(cached_pid);
+ return PIDT2NUM(getpid());
}
-#if defined HAVE_WORKING_FORK || defined HAVE_DAEMON
-static void
-clear_pid_cache(void)
-{
- cached_pid = 0;
-}
-#endif
-
/*
* call-seq:
- * Process.pid -> integer
+ * Process.pid -> integer
*
- * Returns the process ID of the current process:
- *
- * Process.pid # => 15668
+ * Returns the process id of this process. Not available on all
+ * platforms.
*
+ * Process.pid #=> 27415
*/
static VALUE
@@ -540,19 +542,18 @@ get_ppid(void)
/*
* call-seq:
- * Process.ppid -> integer
- *
- * Returns the process ID of the parent of the current process:
+ * Process.ppid -> integer
*
- * puts "Pid is #{Process.pid}."
- * fork { puts "Parent pid is #{Process.ppid}." }
+ * Returns the process id of the parent of this process. Returns
+ * untrustworthy value on Win32/64. Not available on all platforms.
*
- * Output:
+ * puts "I am #{Process.pid}"
+ * Process.fork { puts "Dad is #{Process.ppid}" }
*
- * Pid is 271290.
- * Parent pid is 271290.
+ * <em>produces:</em>
*
- * May not return a trustworthy value on certain platforms.
+ * I am 27417
+ * Dad is 27417
*/
static VALUE
@@ -566,20 +567,30 @@ proc_get_ppid(VALUE _)
*
* Document-class: Process::Status
*
- * A Process::Status contains information about a system process.
- *
- * Thread-local variable <tt>$?</tt> is initially +nil+.
- * Some methods assign to it a Process::Status object
- * that represents a system process (either running or terminated):
- *
- * `ruby -e "exit 99"`
- * stat = $? # => #<Process::Status: pid 1262862 exit 99>
- * stat.class # => Process::Status
- * stat.to_i # => 25344
- * stat.stopped? # => false
- * stat.exited? # => true
- * stat.exitstatus # => 99
- *
+ * Process::Status encapsulates the information on the
+ * status of a running or terminated system process. The built-in
+ * variable <code>$?</code> is either +nil+ or a
+ * Process::Status object.
+ *
+ * fork { exit 99 } #=> 26557
+ * Process.wait #=> 26557
+ * $?.class #=> Process::Status
+ * $?.to_i #=> 25344
+ * $? >> 8 #=> 99
+ * $?.stopped? #=> false
+ * $?.exited? #=> true
+ * $?.exitstatus #=> 99
+ *
+ * Posix systems record information on processes using a 16-bit
+ * integer. The lower bits record the process status (stopped,
+ * exited, signaled) and the upper bits possibly contain additional
+ * information (for example the program's return code in the case of
+ * exited processes). Pre Ruby 1.8, these bits were exposed directly
+ * to the Ruby program. Ruby now encapsulates these in a
+ * Process::Status object. To maximize compatibility,
+ * however, these objects retain a bit-oriented interface. In the
+ * descriptions that follow, when we talk about the integer value of
+ * _stat_, we're referring to this 16 bit value.
*/
static VALUE rb_cProcessStatus;
@@ -593,17 +604,17 @@ struct rb_process_status {
static const rb_data_type_t rb_process_status_type = {
.wrap_struct_name = "Process::Status",
.function = {
- .dmark = NULL,
.dfree = RUBY_DEFAULT_FREE,
- .dsize = NULL,
},
- .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE,
+ .data = NULL,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE
rb_process_status_allocate(VALUE klass)
{
- struct rb_process_status *data;
+ struct rb_process_status *data = NULL;
+
return TypedData_Make_Struct(klass, struct rb_process_status, &rb_process_status_type, data);
}
@@ -615,25 +626,18 @@ rb_last_status_get(void)
/*
* call-seq:
- * Process.last_status -> Process::Status or nil
+ * Process.last_status -> Process::Status or nil
*
- * Returns a Process::Status object representing the most recently exited
- * child process in the current thread, or +nil+ if none:
+ * Returns the status of the last executed child process in the
+ * current thread.
*
- * Process.spawn('ruby', '-e', 'exit 13')
- * Process.wait
- * Process.last_status # => #<Process::Status: pid 14396 exit 13>
+ * Process.wait Process.spawn("ruby", "-e", "exit 13")
+ * Process.last_status #=> #<Process::Status: pid 4825 exit 13>
*
- * Process.spawn('ruby', '-e', 'exit 14')
- * Process.wait
- * Process.last_status # => #<Process::Status: pid 4692 exit 14>
- *
- * Process.spawn('ruby', '-e', 'exit 15')
- * # 'exit 15' has not been reaped by #wait.
- * Process.last_status # => #<Process::Status: pid 4692 exit 14>
- * Process.wait
- * Process.last_status # => #<Process::Status: pid 1380 exit 15>
+ * If no child process has ever been executed in the current
+ * thread, this returns +nil+.
*
+ * Process.last_status #=> nil
*/
static VALUE
proc_s_last_status(VALUE mod)
@@ -645,7 +649,8 @@ VALUE
rb_process_status_new(rb_pid_t pid, int status, int error)
{
VALUE last_status = rb_process_status_allocate(rb_cProcessStatus);
- struct rb_process_status *data = RTYPEDDATA_GET_DATA(last_status);
+
+ struct rb_process_status *data = RTYPEDDATA_DATA(last_status);
data->pid = pid;
data->status = status;
data->error = error;
@@ -658,8 +663,7 @@ static VALUE
process_status_dump(VALUE status)
{
VALUE dump = rb_class_new_instance(0, 0, rb_cObject);
- struct rb_process_status *data;
- TypedData_Get_Struct(status, struct rb_process_status, &rb_process_status_type, data);
+ struct rb_process_status *data = RTYPEDDATA_DATA(status);
if (data->pid) {
rb_ivar_set(dump, id_status, INT2NUM(data->status));
rb_ivar_set(dump, id_pid, PIDT2NUM(data->pid));
@@ -684,42 +688,36 @@ rb_last_status_set(int status, rb_pid_t pid)
GET_THREAD()->last_status = rb_process_status_new(pid, status, 0);
}
-static void
-last_status_clear(rb_thread_t *th)
-{
- th->last_status = Qnil;
-}
-
void
rb_last_status_clear(void)
{
- last_status_clear(GET_THREAD());
+ GET_THREAD()->last_status = Qnil;
}
static rb_pid_t
-pst_pid(VALUE status)
+pst_pid(VALUE pst)
{
- struct rb_process_status *data;
- TypedData_Get_Struct(status, struct rb_process_status, &rb_process_status_type, data);
+ struct rb_process_status *data = RTYPEDDATA_DATA(pst);
return data->pid;
}
static int
-pst_status(VALUE status)
+pst_status(VALUE pst)
{
- struct rb_process_status *data;
- TypedData_Get_Struct(status, struct rb_process_status, &rb_process_status_type, data);
+ struct rb_process_status *data = RTYPEDDATA_DATA(pst);
return data->status;
}
/*
* call-seq:
- * to_i -> integer
+ * stat.to_i -> integer
*
- * Returns the system-dependent integer status of +self+:
+ * Returns the bits in _stat_ as an Integer. Poking
+ * around in these bits is platform dependent.
*
- * `cat /nop`
- * $?.to_i # => 256
+ * fork { exit 0xab } #=> 26566
+ * Process.wait #=> 26566
+ * sprintf('%04x', $?.to_i) #=> "ab00"
*/
static VALUE
@@ -733,13 +731,13 @@ pst_to_i(VALUE self)
/*
* call-seq:
- * pid -> integer
+ * stat.pid -> integer
*
- * Returns the process ID of the process:
- *
- * system("false")
- * $?.pid # => 1247002
+ * Returns the process ID that this status object represents.
*
+ * fork { exit } #=> 26569
+ * Process.wait #=> 26569
+ * $?.pid #=> 26569
*/
static VALUE
@@ -795,13 +793,12 @@ pst_message_status(VALUE str, int status)
/*
* call-seq:
- * to_s -> string
+ * stat.to_s -> string
*
- * Returns a string representation of +self+:
- *
- * `cat /nop`
- * $?.to_s # => "pid 1262141 exit 1"
+ * Show pid and exit status as a string.
*
+ * system("false")
+ * p $?.to_s #=> "pid 12766 exit 1"
*
*/
@@ -823,12 +820,12 @@ pst_to_s(VALUE st)
/*
* call-seq:
- * inspect -> string
+ * stat.inspect -> string
*
- * Returns a string representation of +self+:
+ * Override the inspection method.
*
* system("false")
- * $?.inspect # => "#<Process::Status: pid 1303494 exit 1>"
+ * p $?.inspect #=> "#<Process::Status: pid 12861 exit 1>"
*
*/
@@ -854,15 +851,10 @@ pst_inspect(VALUE st)
/*
* call-seq:
- * stat == other -> true or false
- *
- * Returns whether the value of #to_i == +other+:
- *
- * `cat /nop`
- * stat = $? # => #<Process::Status: pid 1170366 exit 1>
- * sprintf('%x', stat.to_i) # => "100"
- * stat == 0x100 # => true
+ * stat == other -> true or false
*
+ * Returns +true+ if the integer value of _stat_
+ * equals <em>other</em>.
*/
static VALUE
@@ -875,53 +867,20 @@ pst_equal(VALUE st1, VALUE st2)
/*
* call-seq:
- * stat & mask -> integer
- *
- * This method is deprecated as #to_i value is system-specific; use
- * predicate methods like #exited? or #stopped?, or getters like #exitstatus
- * or #stopsig.
- *
- * Returns the logical AND of the value of #to_i with +mask+:
+ * stat & num -> integer
*
- * `cat /nop`
- * stat = $? # => #<Process::Status: pid 1155508 exit 1>
- * sprintf('%x', stat.to_i) # => "100"
- * stat & 0x00 # => 0
+ * Logical AND of the bits in _stat_ with <em>num</em>.
*
- * ArgumentError is raised if +mask+ is negative.
+ * fork { exit 0x37 }
+ * Process.wait
+ * sprintf('%04x', $?.to_i) #=> "3700"
+ * sprintf('%04x', $? & 0x1e00) #=> "1600"
*/
static VALUE
pst_bitand(VALUE st1, VALUE st2)
{
- int status = PST2INT(st1);
- int mask = NUM2INT(st2);
-
- if (mask < 0) {
- rb_raise(rb_eArgError, "negative mask value: %d", mask);
- }
-#define WARN_SUGGEST(suggest) \
- rb_warn_deprecated_to_remove_at(3.4, "Process::Status#&", suggest)
-
- switch (mask) {
- case 0x80:
- WARN_SUGGEST("Process::Status#coredump?");
- break;
- case 0x7f:
- WARN_SUGGEST("Process::Status#signaled? or Process::Status#termsig");
- break;
- case 0xff:
- WARN_SUGGEST("Process::Status#exited?, Process::Status#stopped? or Process::Status#coredump?");
- break;
- case 0xff00:
- WARN_SUGGEST("Process::Status#exitstatus or Process::Status#stopsig");
- break;
- default:
- WARN_SUGGEST("other Process::Status predicates");
- break;
- }
-#undef WARN_SUGGEST
- status &= mask;
+ int status = PST2INT(st1) & NUM2INT(st2);
return INT2NUM(status);
}
@@ -929,48 +888,20 @@ pst_bitand(VALUE st1, VALUE st2)
/*
* call-seq:
- * stat >> places -> integer
- *
- * This method is deprecated as #to_i value is system-specific; use
- * predicate methods like #exited? or #stopped?, or getters like #exitstatus
- * or #stopsig.
- *
- * Returns the value of #to_i, shifted +places+ to the right:
+ * stat >> num -> integer
*
- * `cat /nop`
- * stat = $? # => #<Process::Status: pid 1155508 exit 1>
- * stat.to_i # => 256
- * stat >> 1 # => 128
- * stat >> 2 # => 64
+ * Shift the bits in _stat_ right <em>num</em> places.
*
- * ArgumentError is raised if +places+ is negative.
+ * fork { exit 99 } #=> 26563
+ * Process.wait #=> 26563
+ * $?.to_i #=> 25344
+ * $? >> 8 #=> 99
*/
static VALUE
pst_rshift(VALUE st1, VALUE st2)
{
- int status = PST2INT(st1);
- int places = NUM2INT(st2);
-
- if (places < 0) {
- rb_raise(rb_eArgError, "negative shift value: %d", places);
- }
-#define WARN_SUGGEST(suggest) \
- rb_warn_deprecated_to_remove_at(3.4, "Process::Status#>>", suggest)
-
- switch (places) {
- case 7:
- WARN_SUGGEST("Process::Status#coredump?");
- break;
- case 8:
- WARN_SUGGEST("Process::Status#exitstatus or Process::Status#stopsig");
- break;
- default:
- WARN_SUGGEST("other Process::Status attributes");
- break;
- }
-#undef WARN_SUGGEST
- status >>= places;
+ int status = PST2INT(st1) >> NUM2INT(st2);
return INT2NUM(status);
}
@@ -978,11 +909,11 @@ pst_rshift(VALUE st1, VALUE st2)
/*
* call-seq:
- * stopped? -> true or false
+ * stat.stopped? -> true or false
*
- * Returns +true+ if this process is stopped,
- * and if the corresponding #wait call had the Process::WUNTRACED flag set,
- * +false+ otherwise.
+ * Returns +true+ if this process is stopped. This is only returned
+ * if the corresponding #wait call had the Process::WUNTRACED flag
+ * set.
*/
static VALUE
@@ -996,10 +927,10 @@ pst_wifstopped(VALUE st)
/*
* call-seq:
- * stopsig -> integer or nil
+ * stat.stopsig -> integer or nil
*
- * Returns the number of the signal that caused the process to stop,
- * or +nil+ if the process is not stopped.
+ * Returns the number of the signal that caused _stat_ to stop
+ * (or +nil+ if self is not stopped).
*/
static VALUE
@@ -1015,10 +946,10 @@ pst_wstopsig(VALUE st)
/*
* call-seq:
- * signaled? -> true or false
+ * stat.signaled? -> true or false
*
- * Returns +true+ if the process terminated because of an uncaught signal,
- * +false+ otherwise.
+ * Returns +true+ if _stat_ terminated because of
+ * an uncaught signal.
*/
static VALUE
@@ -1032,10 +963,11 @@ pst_wifsignaled(VALUE st)
/*
* call-seq:
- * termsig -> integer or nil
+ * stat.termsig -> integer or nil
*
- * Returns the number of the signal that caused the process to terminate
- * or +nil+ if the process was not terminated by an uncaught signal.
+ * Returns the number of the signal that caused _stat_ to
+ * terminate (or +nil+ if self was not terminated by an
+ * uncaught signal).
*/
static VALUE
@@ -1051,11 +983,11 @@ pst_wtermsig(VALUE st)
/*
* call-seq:
- * exited? -> true or false
+ * stat.exited? -> true or false
*
- * Returns +true+ if the process exited normally
- * (for example using an <code>exit()</code> call or finishing the
- * program), +false+ if not.
+ * Returns +true+ if _stat_ exited normally (for
+ * example using an <code>exit()</code> call or finishing the
+ * program).
*/
static VALUE
@@ -1069,15 +1001,20 @@ pst_wifexited(VALUE st)
/*
* call-seq:
- * exitstatus -> integer or nil
+ * stat.exitstatus -> integer or nil
*
- * Returns the least significant eight bits of the return code
- * of the process if it has exited;
- * +nil+ otherwise:
+ * Returns the least significant eight bits of the return code of
+ * _stat_. Only available if #exited? is +true+.
*
- * `exit 99`
- * $?.exitstatus # => 99
+ * fork { } #=> 26572
+ * Process.wait #=> 26572
+ * $?.exited? #=> true
+ * $?.exitstatus #=> 0
*
+ * fork { exit 99 } #=> 26573
+ * Process.wait #=> 26573
+ * $?.exited? #=> true
+ * $?.exitstatus #=> 99
*/
static VALUE
@@ -1093,14 +1030,10 @@ pst_wexitstatus(VALUE st)
/*
* call-seq:
- * success? -> true, false, or nil
- *
- * Returns:
- *
- * - +true+ if the process has completed successfully and exited.
- * - +false+ if the process has completed unsuccessfully and exited.
- * - +nil+ if the process has not exited.
+ * stat.success? -> true, false or nil
*
+ * Returns +true+ if _stat_ is successful, +false+ if not.
+ * Returns +nil+ if #exited? is not +true+.
*/
static VALUE
@@ -1116,12 +1049,10 @@ pst_success_p(VALUE st)
/*
* call-seq:
- * coredump? -> true or false
+ * stat.coredump? -> true or false
*
- * Returns +true+ if the process generated a coredump
- * when it terminated, +false+ if not.
- *
- * Not available on all platforms.
+ * Returns +true+ if _stat_ generated a coredump
+ * when it terminated. Not available on all platforms.
*/
static VALUE
@@ -1148,6 +1079,8 @@ do_waitpid(rb_pid_t pid, int *st, int flags)
#endif
}
+#define WAITPID_LOCK_ONLY ((struct waitpid_state *)-1)
+
struct waitpid_state {
struct ccan_list_node wnode;
rb_execution_context_t *ec;
@@ -1159,6 +1092,129 @@ struct waitpid_state {
int errnum;
};
+int rb_sigwait_fd_get(const rb_thread_t *);
+void rb_sigwait_sleep(const rb_thread_t *, int fd, const rb_hrtime_t *);
+void rb_sigwait_fd_put(const rb_thread_t *, int fd);
+void rb_thread_sleep_interruptible(void);
+
+#if USE_MJIT
+static struct waitpid_state mjit_waitpid_state;
+
+// variables shared with thread.c
+// TODO: implement the same thing with postponed_job and obviate these variables
+bool mjit_waitpid_finished = false;
+int mjit_waitpid_status = 0;
+#endif
+
+static int
+waitpid_signal(struct waitpid_state *w)
+{
+ if (w->ec) { /* rb_waitpid */
+ rb_threadptr_interrupt(rb_ec_thread_ptr(w->ec));
+ return TRUE;
+ }
+#if USE_MJIT
+ else if (w == &mjit_waitpid_state && w->ret) { /* mjit_add_waiting_pid */
+ mjit_waitpid_finished = true;
+ mjit_waitpid_status = w->status;
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+// Used for VM memsize reporting. Returns the size of a list of waitpid_state
+// structs. Defined here because the struct definition lives here as well.
+size_t
+rb_vm_memsize_waiting_list(struct ccan_list_head *waiting_list)
+{
+ struct waitpid_state *waitpid = 0;
+ size_t size = 0;
+
+ ccan_list_for_each(waiting_list, waitpid, wnode) {
+ size += sizeof(struct waitpid_state);
+ }
+
+ return size;
+}
+
+/*
+ * When a thread is done using sigwait_fd and there are other threads
+ * sleeping on waitpid, we must kick one of the threads out of
+ * rb_native_cond_wait so it can switch to rb_sigwait_sleep
+ */
+static void
+sigwait_fd_migrate_sleeper(rb_vm_t *vm)
+{
+ struct waitpid_state *w = 0;
+
+ ccan_list_for_each(&vm->waiting_pids, w, wnode) {
+ if (waitpid_signal(w)) return;
+ }
+ ccan_list_for_each(&vm->waiting_grps, w, wnode) {
+ if (waitpid_signal(w)) return;
+ }
+}
+
+void
+rb_sigwait_fd_migrate(rb_vm_t *vm)
+{
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ sigwait_fd_migrate_sleeper(vm);
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+}
+
+#if RUBY_SIGCHLD
+extern volatile unsigned int ruby_nocldwait; /* signal.c */
+/* called by timer thread or thread which acquired sigwait_fd */
+static void
+waitpid_each(rb_vm_t *vm, struct ccan_list_head *head)
+{
+ struct waitpid_state *w = 0, *next;
+
+ ccan_list_for_each_safe(head, w, next, wnode) {
+ rb_pid_t ret = do_waitpid(w->pid, &w->status, w->options | WNOHANG);
+
+ if (!ret) continue;
+ if (ret == -1) w->errnum = errno;
+
+ if (w->pid <= 0) {
+ /* when waiting for a group of processes, make sure a waiter for a
+ * specific pid is given that event in preference */
+ struct waitpid_state *w_inner = 0, *next_inner;
+ ccan_list_for_each_safe(&vm->waiting_pids, w_inner, next_inner, wnode) {
+ if (w_inner->pid == ret) {
+ /* signal this one instead */
+ w = w_inner;
+ }
+ }
+ }
+
+ w->ret = ret;
+ ccan_list_del_init(&w->wnode);
+ waitpid_signal(w);
+ }
+}
+#else
+# define ruby_nocldwait 0
+#endif
+
+void
+ruby_waitpid_all(rb_vm_t *vm)
+{
+#if RUBY_SIGCHLD
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ waitpid_each(vm, &vm->waiting_pids);
+ waitpid_each(vm, &vm->waiting_grps);
+ /* emulate SA_NOCLDWAIT */
+ if (ccan_list_empty(&vm->waiting_pids) && ccan_list_empty(&vm->waiting_grps)) {
+ while (ruby_nocldwait && do_waitpid(-1, 0, WNOHANG) > 0)
+ ; /* keep looping */
+ }
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+#endif
+}
+
static void
waitpid_state_init(struct waitpid_state *w, rb_pid_t pid, int options)
{
@@ -1169,6 +1225,99 @@ waitpid_state_init(struct waitpid_state *w, rb_pid_t pid, int options)
w->status = 0;
}
+#if USE_MJIT
+/*
+ * must be called with vm->waitpid_lock held, this is not interruptible
+ */
+void
+mjit_add_waiting_pid(rb_vm_t *vm, rb_pid_t pid)
+{
+ waitpid_state_init(&mjit_waitpid_state, pid, 0);
+ mjit_waitpid_state.ec = 0; // switch the behavior of waitpid_signal
+ ccan_list_add(&vm->waiting_pids, &mjit_waitpid_state.wnode);
+}
+#endif
+
+static VALUE
+waitpid_sleep(VALUE x)
+{
+ struct waitpid_state *w = (struct waitpid_state *)x;
+
+ while (!w->ret) {
+ rb_thread_sleep_interruptible();
+ }
+
+ return Qfalse;
+}
+
+static VALUE
+waitpid_cleanup(VALUE x)
+{
+ struct waitpid_state *w = (struct waitpid_state *)x;
+
+ /*
+ * XXX w->ret is sometimes set but ccan_list_del is still needed, here,
+ * Not sure why, so we unconditionally do ccan_list_del here:
+ */
+ if (TRUE || w->ret == 0) {
+ rb_vm_t *vm = rb_ec_vm_ptr(w->ec);
+
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ ccan_list_del(&w->wnode);
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+ }
+
+ return Qfalse;
+}
+
+#if RUBY_SIGCHLD
+static void
+waitpid_wait(struct waitpid_state *w)
+{
+ rb_vm_t *vm = rb_ec_vm_ptr(w->ec);
+ int need_sleep = FALSE;
+
+ /*
+ * Lock here to prevent do_waitpid from stealing work from the
+ * ruby_waitpid_locked done by mjit workers since mjit works
+ * outside of GVL
+ */
+ rb_native_mutex_lock(&vm->waitpid_lock);
+
+ if (w->options & WNOHANG && w->pid <= 0) {
+ /* In the case of WNOHANG wait for a group, make sure there isn't a zombie child
+ * whose PID we are directly waiting for in another call to waitpid. If there is,
+ * we will reap it via a call to waitpid($pid) with this call to waitpid_each. */
+ waitpid_each(vm, &vm->waiting_pids);
+ /* _now_ it's safe to call do_waitpid, without risk of stealing the wait from
+ * another directed call. */
+ }
+
+ w->ret = do_waitpid(w->pid, &w->status, w->options | WNOHANG);
+
+ if (w->ret) {
+ if (w->ret == -1) w->errnum = errno;
+ }
+ else if (w->options & WNOHANG) {
+ }
+ else {
+ need_sleep = TRUE;
+ }
+
+ if (need_sleep) {
+ w->cond = 0;
+ /* order matters, favor specified PIDs rather than -1 or 0 */
+ ccan_list_add(w->pid > 0 ? &vm->waiting_pids : &vm->waiting_grps, &w->wnode);
+ }
+
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+
+ if (need_sleep) {
+ rb_ensure(waitpid_sleep, (VALUE)w, waitpid_cleanup, (VALUE)w);
+ }
+}
+#endif
+
static void *
waitpid_blocking_no_SIGCHLD(void *x)
{
@@ -1187,7 +1336,8 @@ waitpid_no_SIGCHLD(struct waitpid_state *w)
}
else {
do {
- rb_thread_call_without_gvl(waitpid_blocking_no_SIGCHLD, w, RUBY_UBF_PROCESS, 0);
+ rb_thread_call_without_gvl(waitpid_blocking_no_SIGCHLD, w,
+ RUBY_UBF_PROCESS, 0);
} while (w->ret < 0 && errno == EINTR && (RUBY_VM_CHECK_INTS(w->ec),1));
}
if (w->ret == -1)
@@ -1209,44 +1359,67 @@ rb_process_status_wait(rb_pid_t pid, int flags)
waitpid_state_init(&waitpid_state, pid, flags);
waitpid_state.ec = GET_EC();
+#if WAITPID_USE_SIGCHLD
+ waitpid_wait(&waitpid_state);
+#else
waitpid_no_SIGCHLD(&waitpid_state);
+#endif
if (waitpid_state.ret == 0) return Qnil;
+ if (waitpid_state.ret > 0 && ruby_nocldwait) {
+ waitpid_state.ret = -1;
+ waitpid_state.errnum = ECHILD;
+ }
+
return rb_process_status_new(waitpid_state.ret, waitpid_state.status, waitpid_state.errnum);
}
/*
* call-seq:
- * Process::Status.wait(pid = -1, flags = 0) -> Process::Status
+ * Process::Status.wait(pid=-1, flags=0) -> Process::Status
*
- * Like Process.wait, but returns a Process::Status object
- * (instead of an integer pid or nil);
- * see Process.wait for the values of +pid+ and +flags+.
+ * Waits for a child process to exit and returns a Process::Status object
+ * containing information on that process. Which child it waits on
+ * depends on the value of _pid_:
*
- * If there are child processes,
- * waits for a child process to exit and returns a Process::Status object
- * containing information on that process;
- * sets thread-local variable <tt>$?</tt>:
+ * > 0:: Waits for the child whose process ID equals _pid_.
*
- * Process.spawn('cat /nop') # => 1155880
- * Process::Status.wait # => #<Process::Status: pid 1155880 exit 1>
- * $? # => #<Process::Status: pid 1155508 exit 1>
+ * 0:: Waits for any child whose process group ID equals that of the
+ * calling process.
*
- * If there is no child process,
- * returns an "empty" Process::Status object
- * that does not represent an actual process;
- * does not set thread-local variable <tt>$?</tt>:
+ * -1:: Waits for any child process (the default if no _pid_ is
+ * given).
*
- * Process::Status.wait # => #<Process::Status: pid -1 exit 0>
- * $? # => #<Process::Status: pid 1155508 exit 1> # Unchanged.
+ * < -1:: Waits for any child whose process group ID equals the absolute
+ * value of _pid_.
*
- * May invoke the scheduler hook Fiber::Scheduler#process_wait.
+ * The _flags_ argument may be a logical or of the flag values
+ * Process::WNOHANG (do not block if no child available)
+ * or Process::WUNTRACED (return stopped children that
+ * haven't been reported). Not all flags are available on all
+ * platforms, but a flag value of zero will work on all platforms.
*
+ * Returns +nil+ if there are no child processes.
* Not available on all platforms.
+ *
+ * May invoke the scheduler hook _process_wait_.
+ *
+ * fork { exit 99 } #=> 27429
+ * Process::Status.wait #=> pid 27429 exit 99
+ * $? #=> nil
+ *
+ * pid = fork { sleep 3 } #=> 27440
+ * Time.now #=> 2008-03-08 19:56:16 +0900
+ * Process::Status.wait(pid, Process::WNOHANG) #=> nil
+ * Time.now #=> 2008-03-08 19:56:16 +0900
+ * Process::Status.wait(pid, 0) #=> pid 27440 exit 99
+ * Time.now #=> 2008-03-08 19:56:19 +0900
+ *
+ * This is an EXPERIMENTAL FEATURE.
*/
-static VALUE
+VALUE
rb_process_status_waitv(int argc, VALUE *argv, VALUE _)
{
rb_check_arity(argc, 0, 2);
@@ -1331,155 +1504,69 @@ proc_wait(int argc, VALUE *argv)
/*
* call-seq:
- * Process.wait(pid = -1, flags = 0) -> integer
- *
- * Waits for a suitable child process to exit, returns its process ID,
- * and sets <tt>$?</tt> to a Process::Status object
- * containing information on that process.
- * Which child it waits for depends on the value of the given +pid+:
- *
- * - Positive integer: Waits for the child process whose process ID is +pid+:
- *
- * pid0 = Process.spawn('ruby', '-e', 'exit 13') # => 230866
- * pid1 = Process.spawn('ruby', '-e', 'exit 14') # => 230891
- * Process.wait(pid0) # => 230866
- * $? # => #<Process::Status: pid 230866 exit 13>
- * Process.wait(pid1) # => 230891
- * $? # => #<Process::Status: pid 230891 exit 14>
- * Process.wait(pid0) # Raises Errno::ECHILD
- *
- * - <tt>0</tt>: Waits for any child process whose group ID
- * is the same as that of the current process:
- *
- * parent_pgpid = Process.getpgid(Process.pid)
- * puts "Parent process group ID is #{parent_pgpid}."
- * child0_pid = fork do
- * puts "Child 0 pid is #{Process.pid}"
- * child0_pgid = Process.getpgid(Process.pid)
- * puts "Child 0 process group ID is #{child0_pgid} (same as parent's)."
- * end
- * child1_pid = fork do
- * puts "Child 1 pid is #{Process.pid}"
- * Process.setpgid(0, Process.pid)
- * child1_pgid = Process.getpgid(Process.pid)
- * puts "Child 1 process group ID is #{child1_pgid} (different from parent's)."
- * end
- * retrieved_pid = Process.wait(0)
- * puts "Process.wait(0) returned pid #{retrieved_pid}, which is child 0 pid."
- * begin
- * Process.wait(0)
- * rescue Errno::ECHILD => x
- * puts "Raised #{x.class}, because child 1 process group ID differs from parent process group ID."
- * end
- *
- * Output:
- *
- * Parent process group ID is 225764.
- * Child 0 pid is 225788
- * Child 0 process group ID is 225764 (same as parent's).
- * Child 1 pid is 225789
- * Child 1 process group ID is 225789 (different from parent's).
- * Process.wait(0) returned pid 225788, which is child 0 pid.
- * Raised Errno::ECHILD, because child 1 process group ID differs from parent process group ID.
- *
- * - <tt>-1</tt> (default): Waits for any child process:
- *
- * parent_pgpid = Process.getpgid(Process.pid)
- * puts "Parent process group ID is #{parent_pgpid}."
- * child0_pid = fork do
- * puts "Child 0 pid is #{Process.pid}"
- * child0_pgid = Process.getpgid(Process.pid)
- * puts "Child 0 process group ID is #{child0_pgid} (same as parent's)."
- * end
- * child1_pid = fork do
- * puts "Child 1 pid is #{Process.pid}"
- * Process.setpgid(0, Process.pid)
- * child1_pgid = Process.getpgid(Process.pid)
- * puts "Child 1 process group ID is #{child1_pgid} (different from parent's)."
- * sleep 3 # To force child 1 to exit later than child 0 exit.
- * end
- * child_pids = [child0_pid, child1_pid]
- * retrieved_pid = Process.wait(-1)
- * puts child_pids.include?(retrieved_pid)
- * retrieved_pid = Process.wait(-1)
- * puts child_pids.include?(retrieved_pid)
- *
- * Output:
- *
- * Parent process group ID is 228736.
- * Child 0 pid is 228758
- * Child 0 process group ID is 228736 (same as parent's).
- * Child 1 pid is 228759
- * Child 1 process group ID is 228759 (different from parent's).
- * true
- * true
- *
- * - Less than <tt>-1</tt>: Waits for any child whose process group ID is <tt>-pid</tt>:
- *
- * parent_pgpid = Process.getpgid(Process.pid)
- * puts "Parent process group ID is #{parent_pgpid}."
- * child0_pid = fork do
- * puts "Child 0 pid is #{Process.pid}"
- * child0_pgid = Process.getpgid(Process.pid)
- * puts "Child 0 process group ID is #{child0_pgid} (same as parent's)."
- * end
- * child1_pid = fork do
- * puts "Child 1 pid is #{Process.pid}"
- * Process.setpgid(0, Process.pid)
- * child1_pgid = Process.getpgid(Process.pid)
- * puts "Child 1 process group ID is #{child1_pgid} (different from parent's)."
- * end
- * sleep 1
- * retrieved_pid = Process.wait(-child1_pid)
- * puts "Process.wait(-child1_pid) returned pid #{retrieved_pid}, which is child 1 pid."
- * begin
- * Process.wait(-child1_pid)
- * rescue Errno::ECHILD => x
- * puts "Raised #{x.class}, because there's no longer a child with process group id #{child1_pid}."
- * end
- *
- * Output:
- *
- * Parent process group ID is 230083.
- * Child 0 pid is 230108
- * Child 0 process group ID is 230083 (same as parent's).
- * Child 1 pid is 230109
- * Child 1 process group ID is 230109 (different from parent's).
- * Process.wait(-child1_pid) returned pid 230109, which is child 1 pid.
- * Raised Errno::ECHILD, because there's no longer a child with process group id 230109.
- *
- * Argument +flags+ should be given as one of the following constants,
- * or as the logical OR of both:
- *
- * - Process::WNOHANG: Does not block if no child process is available.
- * - Process:WUNTRACED: May return a stopped child process, even if not yet reported.
- *
- * Not all flags are available on all platforms.
- *
- * Raises Errno::ECHILD if there is no suitable child process.
- *
- * Not available on all platforms.
- *
- * Process.waitpid is an alias for Process.wait.
+ * Process.wait() -> integer
+ * Process.wait(pid=-1, flags=0) -> integer
+ * Process.waitpid(pid=-1, flags=0) -> integer
+ *
+ * Waits for a child process to exit, returns its process id, and
+ * sets <code>$?</code> to a Process::Status object
+ * containing information on that process. Which child it waits on
+ * depends on the value of _pid_:
+ *
+ * > 0:: Waits for the child whose process ID equals _pid_.
+ *
+ * 0:: Waits for any child whose process group ID equals that of the
+ * calling process.
+ *
+ * -1:: Waits for any child process (the default if no _pid_ is
+ * given).
+ *
+ * < -1:: Waits for any child whose process group ID equals the absolute
+ * value of _pid_.
+ *
+ * The _flags_ argument may be a logical or of the flag values
+ * Process::WNOHANG (do not block if no child available)
+ * or Process::WUNTRACED (return stopped children that
+ * haven't been reported). Not all flags are available on all
+ * platforms, but a flag value of zero will work on all platforms.
+ *
+ * Calling this method raises a SystemCallError if there are no child
+ * processes. Not available on all platforms.
+ *
+ * include Process
+ * fork { exit 99 } #=> 27429
+ * wait #=> 27429
+ * $?.exitstatus #=> 99
+ *
+ * pid = fork { sleep 3 } #=> 27440
+ * Time.now #=> 2008-03-08 19:56:16 +0900
+ * waitpid(pid, Process::WNOHANG) #=> nil
+ * Time.now #=> 2008-03-08 19:56:16 +0900
+ * waitpid(pid, 0) #=> 27440
+ * Time.now #=> 2008-03-08 19:56:19 +0900
*/
+
static VALUE
proc_m_wait(int c, VALUE *v, VALUE _)
{
return proc_wait(c, v);
}
+
/*
* call-seq:
- * Process.wait2(pid = -1, flags = 0) -> [pid, status]
- *
- * Like Process.waitpid, but returns an array
- * containing the child process +pid+ and Process::Status +status+:
- *
- * pid = Process.spawn('ruby', '-e', 'exit 13') # => 309581
- * Process.wait2(pid)
- * # => [309581, #<Process::Status: pid 309581 exit 13>]
- *
- * Process.waitpid2 is an alias for Process.waitpid.
+ * Process.wait2(pid=-1, flags=0) -> [pid, status]
+ * Process.waitpid2(pid=-1, flags=0) -> [pid, status]
+ *
+ * Waits for a child process to exit (see Process::waitpid for exact
+ * semantics) and returns an array containing the process id and the
+ * exit status (a Process::Status object) of that
+ * child. Raises a SystemCallError if there are no child processes.
+ *
+ * Process.fork { exit 99 } #=> 27437
+ * pid, status = Process.wait2
+ * pid #=> 27437
+ * status.exitstatus #=> 99
*/
static VALUE
@@ -1493,17 +1580,22 @@ proc_wait2(int argc, VALUE *argv, VALUE _)
/*
* call-seq:
- * Process.waitall -> array
+ * Process.waitall -> [ [pid1,status1], ...]
*
- * Waits for all children, returns an array of 2-element arrays;
- * each subarray contains the integer pid and Process::Status status
- * for one of the reaped child processes:
+ * Waits for all children, returning an array of
+ * _pid_/_status_ pairs (where _status_ is a
+ * Process::Status object).
*
- * pid0 = Process.spawn('ruby', '-e', 'exit 13') # => 325470
- * pid1 = Process.spawn('ruby', '-e', 'exit 14') # => 325495
- * Process.waitall
- * # => [[325470, #<Process::Status: pid 325470 exit 13>], [325495, #<Process::Status: pid 325495 exit 14>]]
+ * fork { sleep 0.2; exit 2 } #=> 27432
+ * fork { sleep 0.1; exit 1 } #=> 27433
+ * fork { exit 0 } #=> 27434
+ * p Process.waitall
*
+ * <em>produces</em>:
+ *
+ * [[30982, #<Process::Status: pid 30982 exit 0>],
+ * [30979, #<Process::Status: pid 30979 exit 1>],
+ * [30976, #<Process::Status: pid 30976 exit 2>]]
*/
static VALUE
@@ -1561,41 +1653,48 @@ rb_detach_process(rb_pid_t pid)
/*
* call-seq:
- * Process.detach(pid) -> thread
- *
- * Avoids the potential for a child process to become a
- * {zombie process}[https://en.wikipedia.org/wiki/Zombie_process].
- * Process.detach prevents this by setting up a separate Ruby thread
- * whose sole job is to reap the status of the process _pid_ when it terminates.
+ * Process.detach(pid) -> thread
*
- * This method is needed only when the parent process will never wait
- * for the child process.
+ * Some operating systems retain the status of terminated child
+ * processes until the parent collects that status (normally using
+ * some variant of <code>wait()</code>). If the parent never collects
+ * this status, the child stays around as a <em>zombie</em> process.
+ * Process::detach prevents this by setting up a separate Ruby thread
+ * whose sole job is to reap the status of the process _pid_ when it
+ * terminates. Use #detach only when you do not intend to explicitly
+ * wait for the child to terminate.
*
- * This example does not reap the second child process;
- * that process appears as a zombie in the process status (+ps+) output:
+ * The waiting thread returns the exit status of the detached process
+ * when it terminates, so you can use Thread#join to
+ * know the result. If specified _pid_ is not a valid child process
+ * ID, the thread returns +nil+ immediately.
*
- * pid = Process.spawn('ruby', '-e', 'exit 13') # => 312691
- * sleep(1)
- * # Find zombies.
- * system("ps -ho pid,state -p #{pid}")
+ * The waiting thread has #pid method which returns the pid.
*
- * Output:
+ * In this first example, we don't reap the first child process, so
+ * it appears as a zombie in the process status display.
*
- * 312716 Z
+ * p1 = fork { sleep 0.1 }
+ * p2 = fork { sleep 0.2 }
+ * Process.waitpid(p2)
+ * sleep 2
+ * system("ps -ho pid,state -p #{p1}")
*
- * This example also does not reap the second child process,
- * but it does detach the process so that it does not become a zombie:
+ * <em>produces:</em>
*
- * pid = Process.spawn('ruby', '-e', 'exit 13') # => 313213
- * thread = Process.detach(pid)
- * sleep(1)
- * # => #<Process::Waiter:0x00007f038f48b838 run>
- * system("ps -ho pid,state -p #{pid}") # Finds no zombies.
+ * 27389 Z
*
- * The waiting thread can return the pid of the detached child process:
+ * In the next example, Process::detach is used to reap
+ * the child automatically.
*
- * thread.join.pid # => 313262
+ * p1 = fork { sleep 0.1 }
+ * p2 = fork { sleep 0.2 }
+ * Process.detach(p1)
+ * Process.waitpid(p2)
+ * sleep 2
+ * system("ps -ho pid,state -p #{p1}")
*
+ * <em>(produces no output)</em>
*/
static VALUE
@@ -1665,13 +1764,26 @@ before_exec(void)
before_exec_async_signal_safe();
}
+/* This function should be async-signal-safe. Actually it is. */
static void
-after_exec(void)
+after_exec_async_signal_safe(void)
+{
+}
+
+static void
+after_exec_non_async_signal_safe(void)
{
rb_thread_reset_timer_thread();
rb_thread_start_timer_thread();
}
+static void
+after_exec(void)
+{
+ after_exec_async_signal_safe();
+ after_exec_non_async_signal_safe();
+}
+
#if defined HAVE_WORKING_FORK || defined HAVE_DAEMON
static void
before_fork_ruby(void)
@@ -1680,33 +1792,14 @@ before_fork_ruby(void)
}
static void
-after_fork_ruby(rb_pid_t pid)
+after_fork_ruby(void)
{
- if (pid == 0) {
- // child
- clear_pid_cache();
- rb_thread_atfork();
- }
- else {
- // parent
- after_exec();
- }
+ after_exec();
}
#endif
#if defined(HAVE_WORKING_FORK)
-COMPILER_WARNING_PUSH
-#if __has_warning("-Wdeprecated-declarations") || RBIMPL_COMPILER_IS(GCC)
-COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
-#endif
-static inline rb_pid_t
-rb_fork(void)
-{
- return fork();
-}
-COMPILER_WARNING_POP
-
/* try_with_sh and exec_with_sh should be async-signal-safe. Actually it is.*/
#define try_with_sh(err, prog, argv, envp) ((err == ENOEXEC) ? exec_with_sh((prog), (argv), (envp)) : (void)0)
static void
@@ -1838,7 +1931,7 @@ memsize_exec_arg(const void *ptr)
static const rb_data_type_t exec_arg_data_type = {
"exec_arg",
{mark_exec_arg, RUBY_TYPED_DEFAULT_FREE, memsize_exec_arg},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
#ifdef _WIN32
@@ -2782,7 +2875,6 @@ rb_execarg_setenv(VALUE execarg_obj, VALUE env)
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
env = !NIL_P(env) ? rb_check_exec_env(env, &eargp->path_env) : Qfalse;
eargp->env_modification = env;
- RB_GC_GUARD(execarg_obj);
}
static int
@@ -2980,7 +3072,6 @@ execarg_parent_end(VALUE execarg_obj)
}
errno = err;
- RB_GC_GUARD(execarg_obj);
return execarg_obj;
}
@@ -3022,6 +3113,7 @@ rb_f_exec(int argc, const VALUE *argv)
execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj);
+ if (mjit_enabled) mjit_finish(false); // avoid leaking resources, and do not leave files. XXX: JIT-ed handle can leak after exec error is rescued.
before_exec(); /* stop timer thread before redirects */
rb_protect(rb_execarg_parent_start1, execarg_obj, &state);
@@ -3046,89 +3138,77 @@ NORETURN(static VALUE f_exec(int c, const VALUE *a, VALUE _));
/*
* call-seq:
- * exec([env, ] command_line, options = {})
- * exec([env, ] exe_path, *args, options = {})
- *
- * Replaces the current process by doing one of the following:
- *
- * - Passing string +command_line+ to the shell.
- * - Invoking the executable at +exe_path+.
- *
- * This method has potential security vulnerabilities if called with untrusted input;
- * see {Command Injection}[rdoc-ref:command_injection.rdoc].
- *
- * The new process is created using the
- * {exec system call}[https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/execve.html];
- * it may inherit some of its environment from the calling program
- * (possibly including open file descriptors).
- *
- * Argument +env+, if given, is a hash that affects +ENV+ for the new process;
- * see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- *
- * Argument +options+ is a hash of options for the new process;
- * see {Execution Options}[rdoc-ref:Process@Execution+Options].
- *
- * The first required argument is one of the following:
- *
- * - +command_line+ if it is a string,
- * and if it begins with a shell reserved word or special built-in,
- * or if it contains one or more meta characters.
- * - +exe_path+ otherwise.
- *
- * <b>Argument +command_line+</b>
+ * exec([env,] command... [,options])
*
- * \String argument +command_line+ is a command line to be passed to a shell;
- * it must begin with a shell reserved word, begin with a special built-in,
- * or contain meta characters:
+ * Replaces the current process by running the given external _command_, which
+ * can take one of the following forms:
*
- * exec('if true; then echo "Foo"; fi') # Shell reserved word.
- * exec('echo') # Built-in.
- * exec('date > date.tmp') # Contains meta character.
+ * [<code>exec(commandline)</code>]
+ * command line string which is passed to the standard shell
+ * [<code>exec(cmdname, arg1, ...)</code>]
+ * command name and one or more arguments (no shell)
+ * [<code>exec([cmdname, argv0], arg1, ...)</code>]
+ * command name, +argv[0]+ and zero or more arguments (no shell)
*
- * The command line may also contain arguments and options for the command:
+ * In the first form, the string is taken as a command line that is subject to
+ * shell expansion before being executed.
*
- * exec('echo "Foo"')
+ * The standard shell always means <code>"/bin/sh"</code> on Unix-like systems,
+ * otherwise, <code>ENV["RUBYSHELL"]</code> or <code>ENV["COMSPEC"]</code> on
+ * Windows and similar. The command is passed as an argument to the
+ * <code>"-c"</code> switch to the shell, except in the case of +COMSPEC+.
*
- * Output:
+ * If the string from the first form (<code>exec("command")</code>) follows
+ * these simple rules:
*
- * Foo
+ * * no meta characters,
+ * * not starting with shell reserved word or special built-in,
*
- * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell.
+ * Ruby invokes the command directly without shell.
*
- * Raises an exception if the new process could not execute.
+ * You can force shell invocation by adding ";" to the string (because ";" is
+ * a meta character).
*
- * <b>Argument +exe_path+</b>
+ * Note that this behavior is observable by pid obtained
+ * (return value of spawn() and IO#pid for IO.popen) is the pid of the invoked
+ * command, not shell.
*
- * Argument +exe_path+ is one of the following:
+ * In the second form (<code>exec("command1", "arg1", ...)</code>), the first
+ * is taken as a command name and the rest are passed as parameters to command
+ * with no shell expansion.
*
- * - The string path to an executable to be called.
- * - A 2-element array containing the path to an executable
- * and the string to be used as the name of the executing process.
+ * In the third form (<code>exec(["command", "argv0"], "arg1", ...)</code>),
+ * starting a two-element array at the beginning of the command, the first
+ * element is the command to be executed, and the second argument is used as
+ * the <code>argv[0]</code> value, which may show up in process listings.
*
- * Example:
+ * In order to execute the command, one of the <code>exec(2)</code> system
+ * calls are used, so the running command may inherit some of the environment
+ * of the original program (including open file descriptors).
*
- * exec('/usr/bin/date')
+ * This behavior is modified by the given +env+ and +options+ parameters. See
+ * ::spawn for details.
*
- * Output:
+ * If the command fails to execute (typically Errno::ENOENT when
+ * it was not found) a SystemCallError exception is raised.
*
- * Sat Aug 26 09:38:00 AM CDT 2023
+ * This method modifies process attributes according to given +options+ before
+ * <code>exec(2)</code> system call. See ::spawn for more details about the
+ * given +options+.
*
- * Ruby invokes the executable directly, with no shell and no shell expansion:
+ * The modified attributes may be retained when <code>exec(2)</code> system
+ * call fails.
*
- * exec('doesnt_exist') # Raises Errno::ENOENT
+ * For example, hard resource limits are not restorable.
*
- * If one or more +args+ is given, each is an argument or option
- * to be passed to the executable:
+ * Consider to create a child process using ::spawn or Kernel#system if this
+ * is not acceptable.
*
- * exec('echo', 'C*')
- * exec('echo', 'hello', 'world')
+ * exec "echo *" # echoes list of files in current directory
+ * # never get here
*
- * Output:
- *
- * C*
- * hello world
- *
- * Raises an exception if the new process could not execute.
+ * exec "echo", "*" # echoes an asterisk
+ * # never get here
*/
static VALUE
@@ -3353,13 +3433,6 @@ run_exec_dup2(VALUE ary, VALUE tmpbuf, struct rb_execarg *sargp, char *errmsg, s
ERRMSG("dup");
goto fail;
}
- // without this, kqueue timer_th.event_fd fails with a reserved FD did not have close-on-exec
- // in #assert_close_on_exec because the FD_CLOEXEC is not dup'd by default
- if (fd_get_cloexec(pairs[i].oldfd, errmsg, errmsg_buflen)) {
- if (fd_set_cloexec(extra_fd, errmsg, errmsg_buflen)) {
- goto fail;
- }
- }
rb_update_max_fd(extra_fd);
}
else {
@@ -4098,10 +4171,16 @@ retry_fork_async_signal_safe(struct rb_process_status *status, int *ep,
volatile int try_gc = 1;
struct child_handler_disabler_state old;
int err;
+ rb_nativethread_lock_t *const volatile waitpid_lock_init =
+ (w && WAITPID_USE_SIGCHLD) ? &GET_VM()->waitpid_lock : 0;
while (1) {
+ rb_nativethread_lock_t *waitpid_lock = waitpid_lock_init;
prefork();
disable_child_handler_before_fork(&old);
+ if (waitpid_lock) {
+ rb_native_mutex_lock(waitpid_lock);
+ }
#ifdef HAVE_WORKING_VFORK
if (!has_privilege())
pid = vfork();
@@ -4126,6 +4205,14 @@ retry_fork_async_signal_safe(struct rb_process_status *status, int *ep,
#endif
}
err = errno;
+ waitpid_lock = waitpid_lock_init;
+ if (waitpid_lock) {
+ if (pid > 0 && w != WAITPID_LOCK_ONLY) {
+ w->pid = pid;
+ ccan_list_add(&GET_VM()->waiting_pids, &w->wnode);
+ }
+ rb_native_mutex_unlock(waitpid_lock);
+ }
disable_child_handler_fork_parent(&old);
if (0 < pid) /* fork succeed, parent process */
return pid;
@@ -4135,6 +4222,30 @@ retry_fork_async_signal_safe(struct rb_process_status *status, int *ep,
}
}
+#if USE_MJIT
+// This is used to create MJIT's child Ruby process
+pid_t
+rb_mjit_fork(void)
+{
+ struct child_handler_disabler_state old;
+ rb_vm_t *vm = GET_VM();
+ prefork();
+ disable_child_handler_before_fork(&old);
+ before_fork_ruby();
+
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ pid_t pid = rb_fork();
+ if (pid > 0) mjit_add_waiting_pid(vm, pid);
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+
+ after_fork_ruby();
+ disable_child_handler_fork_parent(&old);
+ if (pid == 0) rb_thread_atfork();
+
+ return pid;
+}
+#endif
+
static rb_pid_t
fork_check_err(struct rb_process_status *status, int (*chfunc)(void*, char *, size_t), void *charg,
VALUE fds, char *errmsg, size_t errmsg_buflen,
@@ -4170,12 +4281,13 @@ fork_check_err(struct rb_process_status *status, int (*chfunc)(void*, char *, si
int state = 0;
status->error = err;
- VM_ASSERT((w == 0) && "only used by extensions");
+ VM_ASSERT((w == 0 || w == WAITPID_LOCK_ONLY) &&
+ "only used by extensions");
rb_protect(proc_syswait, (VALUE)pid, &state);
status->status = state;
}
- else if (!w) {
+ else if (!w || w == WAITPID_LOCK_ONLY) {
rb_syswait(pid);
}
@@ -4190,7 +4302,7 @@ fork_check_err(struct rb_process_status *status, int (*chfunc)(void*, char *, si
* The "async_signal_safe" name is a lie, but it is used by pty.c and
* maybe other exts. fork() is not async-signal-safe due to pthread_atfork
* and future POSIX revisions will remove it from a list of signal-safe
- * functions. rb_waitpid is not async-signal-safe since RJIT, either.
+ * functions. rb_waitpid is not async-signal-safe since MJIT, either.
* For our purposes, we do not need async-signal-safety, here
*/
rb_pid_t
@@ -4220,21 +4332,22 @@ rb_fork_ruby2(struct rb_process_status *status)
while (1) {
prefork();
-
- before_fork_ruby();
+ if (mjit_enabled) mjit_pause(false); // Don't leave locked mutex to child. Note: child_handler must be enabled to pause MJIT.
disable_child_handler_before_fork(&old);
- {
- pid = rb_fork();
- err = errno;
- if (status) {
- status->pid = pid;
- status->error = err;
- }
+ before_fork_ruby();
+ pid = rb_fork();
+ err = errno;
+ if (status) {
+ status->pid = pid;
+ status->error = err;
}
+ after_fork_ruby();
disable_child_handler_fork_parent(&old); /* yes, bad name */
- after_fork_ruby(pid);
+
+ if (mjit_enabled && pid > 0) mjit_resume(); /* child (pid == 0) is cared by rb_thread_atfork */
if (pid >= 0) { /* fork succeed */
+ if (pid == 0) rb_thread_atfork();
return pid;
}
@@ -4313,62 +4426,27 @@ rb_proc__fork(VALUE _obj)
/*
* call-seq:
- * Process.fork { ... } -> integer or nil
- * Process.fork -> integer or nil
- *
- * Creates a child process.
- *
- * With a block given, runs the block in the child process;
- * on block exit, the child terminates with a status of zero:
- *
- * puts "Before the fork: #{Process.pid}"
- * fork do
- * puts "In the child process: #{Process.pid}"
- * end # => 382141
- * puts "After the fork: #{Process.pid}"
- *
- * Output:
- *
- * Before the fork: 420496
- * After the fork: 420496
- * In the child process: 420520
- *
- * With no block given, the +fork+ call returns twice:
- *
- * - Once in the parent process, returning the pid of the child process.
- * - Once in the child process, returning +nil+.
- *
- * Example:
- *
- * puts "This is the first line before the fork (pid #{Process.pid})"
- * puts fork
- * puts "This is the second line after the fork (pid #{Process.pid})"
- *
- * Output:
- *
- * This is the first line before the fork (pid 420199)
- * 420223
- * This is the second line after the fork (pid 420199)
- *
- * This is the second line after the fork (pid 420223)
- *
- * In either case, the child process may exit using
- * Kernel.exit! to avoid the call to Kernel#at_exit.
- *
- * To avoid zombie processes, the parent process should call either:
- *
- * - Process.wait, to collect the termination statuses of its children.
- * - Process.detach, to register disinterest in their status.
- *
- * The thread calling +fork+ is the only thread in the created child process;
- * +fork+ doesn't copy other threads.
- *
- * Note that method +fork+ is available on some platforms,
- * but not on others:
- *
- * Process.respond_to?(:fork) # => true # Would be false on some.
- *
- * If not, you may use ::spawn instead of +fork+.
+ * Kernel.fork [{ block }] -> integer or nil
+ * Process.fork [{ block }] -> integer or nil
+ *
+ * Creates a subprocess. If a block is specified, that block is run
+ * in the subprocess, and the subprocess terminates with a status of
+ * zero. Otherwise, the +fork+ call returns twice, once in the
+ * parent, returning the process ID of the child, and once in the
+ * child, returning _nil_. The child process can exit using
+ * Kernel.exit! to avoid running any <code>at_exit</code>
+ * functions. The parent process should use Process.wait to collect
+ * the termination statuses of its children or use Process.detach to
+ * register disinterest in their status; otherwise, the operating
+ * system may accumulate zombie processes.
+ *
+ * The thread calling fork is the only thread in the created child process.
+ * fork doesn't copy other threads.
+ *
+ * If fork is not usable, Process.respond_to?(:fork) returns false.
+ *
+ * Note that fork(2) is not available on some platforms like Windows and NetBSD 4.
+ * Therefore you should use spawn() instead of fork().
*/
static VALUE
@@ -4420,18 +4498,13 @@ exit_status_code(VALUE status)
NORETURN(static VALUE rb_f_exit_bang(int argc, VALUE *argv, VALUE obj));
/*
* call-seq:
- * exit!(status = false)
- * Process.exit!(status = false)
+ * Process.exit!(status=false)
*
- * Exits the process immediately; no exit handlers are called.
- * Returns exit status +status+ to the underlying operating system.
+ * Exits the process immediately. No exit handlers are
+ * run. <em>status</em> is returned to the underlying system as the
+ * exit status.
*
* Process.exit!(true)
- *
- * Values +true+ and +false+ for argument +status+
- * indicate, respectively, success and failure;
- * The meanings of integer values are system-dependent.
- *
*/
static VALUE
@@ -4482,47 +4555,43 @@ rb_f_exit(int argc, const VALUE *argv)
NORETURN(static VALUE f_exit(int c, const VALUE *a, VALUE _));
/*
* call-seq:
- * exit(status = true)
- * Process.exit(status = true)
- *
- * Initiates termination of the Ruby script by raising SystemExit;
- * the exception may be caught.
- * Returns exit status +status+ to the underlying operating system.
- *
- * Values +true+ and +false+ for argument +status+
- * indicate, respectively, success and failure;
- * The meanings of integer values are system-dependent.
- *
- * Example:
- *
- * begin
- * exit
- * puts 'Never get here.'
- * rescue SystemExit
- * puts 'Rescued a SystemExit exception.'
- * end
- * puts 'After begin block.'
- *
- * Output:
- *
- * Rescued a SystemExit exception.
- * After begin block.
- *
- * Just prior to final termination,
- * Ruby executes any at-exit procedures (see Kernel::at_exit)
- * and any object finalizers (see ObjectSpace::define_finalizer).
- *
- * Example:
- *
- * at_exit { puts 'In at_exit function.' }
- * ObjectSpace.define_finalizer('string', proc { puts 'In finalizer.' })
- * exit
- *
- * Output:
- *
- * In at_exit function.
- * In finalizer.
- *
+ * exit(status=true)
+ * Kernel::exit(status=true)
+ * Process::exit(status=true)
+ *
+ * Initiates the termination of the Ruby script by raising the
+ * SystemExit exception. This exception may be caught. The
+ * optional parameter is used to return a status code to the invoking
+ * environment.
+ * +true+ and +FALSE+ of _status_ means success and failure
+ * respectively. The interpretation of other integer values are
+ * system dependent.
+ *
+ * begin
+ * exit
+ * puts "never get here"
+ * rescue SystemExit
+ * puts "rescued a SystemExit exception"
+ * end
+ * puts "after begin block"
+ *
+ * <em>produces:</em>
+ *
+ * rescued a SystemExit exception
+ * after begin block
+ *
+ * Just prior to termination, Ruby executes any <code>at_exit</code>
+ * functions (see Kernel::at_exit) and runs any object finalizers
+ * (see ObjectSpace::define_finalizer).
+ *
+ * at_exit { puts "at_exit function" }
+ * ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
+ * exit
+ *
+ * <em>produces:</em>
+ *
+ * at_exit function
+ * in finalizer
*/
static VALUE
@@ -4561,16 +4630,13 @@ NORETURN(static VALUE f_abort(int c, const VALUE *a, VALUE _));
/*
* call-seq:
- * abort
- * Process.abort(msg = nil)
+ * abort
+ * Kernel::abort([msg])
+ * Process.abort([msg])
*
- * Terminates execution immediately, effectively by calling
- * <tt>Kernel.exit(false)</tt>.
- *
- * If string argument +msg+ is given,
- * it is written to STDERR prior to termination;
- * otherwise, if an exception was raised,
- * prints its message and backtrace.
+ * Terminate execution immediately, effectively by calling
+ * <code>Kernel.exit(false)</code>. If _msg_ is given, it is written
+ * to STDERR prior to terminating.
*/
static VALUE
@@ -4654,7 +4720,7 @@ rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
rb_last_status_set((status & 0xff) << 8, pid);
# endif
- if (eargp->waitpid_state) {
+ if (eargp->waitpid_state && eargp->waitpid_state != WAITPID_LOCK_ONLY) {
eargp->waitpid_state->pid = pid;
}
@@ -4676,28 +4742,30 @@ static VALUE
do_spawn_process(VALUE arg)
{
struct spawn_args *argp = (struct spawn_args *)arg;
-
rb_execarg_parent_start1(argp->execarg);
-
- return (VALUE)rb_spawn_process(rb_execarg_get(argp->execarg),
+ return (VALUE)rb_spawn_process(DATA_PTR(argp->execarg),
argp->errmsg.ptr, argp->errmsg.buflen);
}
-NOINLINE(static rb_pid_t
- rb_execarg_spawn(VALUE execarg_obj, char *errmsg, size_t errmsg_buflen));
-
static rb_pid_t
rb_execarg_spawn(VALUE execarg_obj, char *errmsg, size_t errmsg_buflen)
{
struct spawn_args args;
+ struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
+
+ /*
+ * Prevent a race with MJIT where the compiler process where
+ * can hold an FD of ours in between vfork + execve
+ */
+ if (!eargp->waitpid_state && mjit_enabled) {
+ eargp->waitpid_state = WAITPID_LOCK_ONLY;
+ }
args.execarg = execarg_obj;
args.errmsg.ptr = errmsg;
args.errmsg.buflen = errmsg_buflen;
-
- rb_pid_t r = (rb_pid_t)rb_ensure(do_spawn_process, (VALUE)&args,
- execarg_parent_end, execarg_obj);
- return r;
+ return (rb_pid_t)rb_ensure(do_spawn_process, (VALUE)&args,
+ execarg_parent_end, execarg_obj);
}
static rb_pid_t
@@ -4723,131 +4791,68 @@ rb_spawn(int argc, const VALUE *argv)
/*
* call-seq:
- * system([env, ] command_line, options = {}, exception: false) -> true, false, or nil
- * system([env, ] exe_path, *args, options = {}, exception: false) -> true, false, or nil
- *
- * Creates a new child process by doing one of the following
- * in that process:
+ * system([env,] command... [,options], exception: false) -> true, false or nil
*
- * - Passing string +command_line+ to the shell.
- * - Invoking the executable at +exe_path+.
+ * Executes _command..._ in a subshell.
+ * _command..._ is one of following forms.
*
* This method has potential security vulnerabilities if called with untrusted input;
* see {Command Injection}[rdoc-ref:command_injection.rdoc].
*
- * Returns:
- *
- * - +true+ if the command exits with status zero.
- * - +false+ if the exit status is a non-zero integer.
- * - +nil+ if the command could not execute.
- *
- * Raises an exception (instead of returning +false+ or +nil+)
- * if keyword argument +exception+ is set to +true+.
- *
- * Assigns the command's error status to <tt>$?</tt>.
- *
- * The new process is created using the
- * {system system call}[https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/system.html];
- * it may inherit some of its environment from the calling program
- * (possibly including open file descriptors).
- *
- * Argument +env+, if given, is a hash that affects +ENV+ for the new process;
- * see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- *
- * Argument +options+ is a hash of options for the new process;
- * see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ * [<code>commandline</code>]
+ * command line string which is passed to the standard shell
+ * [<code>cmdname, arg1, ...</code>]
+ * command name and one or more arguments (no shell)
+ * [<code>[cmdname, argv0], arg1, ...</code>]
+ * command name, <code>argv[0]</code> and zero or more arguments (no shell)
*
- * The first required argument is one of the following:
+ * system returns +true+ if the command gives zero exit status,
+ * +false+ for non zero exit status.
+ * Returns +nil+ if command execution fails.
+ * An error status is available in <code>$?</code>.
*
- * - +command_line+ if it is a string,
- * and if it begins with a shell reserved word or special built-in,
- * or if it contains one or more meta characters.
- * - +exe_path+ otherwise.
+ * If the <code>exception: true</code> argument is passed, the method
+ * raises an exception instead of returning +false+ or +nil+.
*
- * <b>Argument +command_line+</b>
+ * The arguments are processed in the same way as
+ * for Kernel#spawn.
*
- * \String argument +command_line+ is a command line to be passed to a shell;
- * it must begin with a shell reserved word, begin with a special built-in,
- * or contain meta characters:
+ * The hash arguments, env and options, are same as #exec and #spawn.
+ * See Kernel#spawn for details.
*
- * system('if true; then echo "Foo"; fi') # => true # Shell reserved word.
- * system('echo') # => true # Built-in.
- * system('date > /tmp/date.tmp') # => true # Contains meta character.
- * system('date > /nop/date.tmp') # => false
- * system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.
+ * system("echo *")
+ * system("echo", "*")
*
- * Assigns the command's error status to <tt>$?</tt>:
+ * <em>produces:</em>
*
- * system('echo') # => true # Built-in.
- * $? # => #<Process::Status: pid 640610 exit 0>
- * system('date > /nop/date.tmp') # => false
- * $? # => #<Process::Status: pid 640742 exit 2>
+ * config.h main.rb
+ * *
*
- * The command line may also contain arguments and options for the command:
+ * Error handling:
*
- * system('echo "Foo"') # => true
+ * system("cat nonexistent.txt")
+ * # => false
+ * system("catt nonexistent.txt")
+ * # => nil
*
- * Output:
+ * system("cat nonexistent.txt", exception: true)
+ * # RuntimeError (Command failed with exit 1: cat)
+ * system("catt nonexistent.txt", exception: true)
+ * # Errno::ENOENT (No such file or directory - catt)
*
- * Foo
- *
- * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell.
- *
- * Raises an exception if the new process could not execute.
- *
- * <b>Argument +exe_path+</b>
- *
- * Argument +exe_path+ is one of the following:
- *
- * - The string path to an executable to be called.
- * - A 2-element array containing the path to an executable
- * and the string to be used as the name of the executing process.
- *
- * Example:
- *
- * system('/usr/bin/date') # => true # Path to date on Unix-style system.
- * system('foo') # => nil # Command failed.
- *
- * Output:
- *
- * Mon Aug 28 11:43:10 AM CDT 2023
- *
- * Assigns the command's error status to <tt>$?</tt>:
- *
- * system('/usr/bin/date') # => true
- * $? # => #<Process::Status: pid 645605 exit 0>
- * system('foo') # => nil
- * $? # => #<Process::Status: pid 645608 exit 127>
- *
- * Ruby invokes the executable directly, with no shell and no shell expansion:
- *
- * system('doesnt_exist') # => nil
- *
- * If one or more +args+ is given, each is an argument or option
- * to be passed to the executable:
- *
- * system('echo', 'C*') # => true
- * system('echo', 'hello', 'world') # => true
- *
- * Output:
- *
- * C*
- * hello world
- *
- * Raises an exception if the new process could not execute.
+ * See Kernel#exec for the standard shell.
*/
static VALUE
rb_f_system(int argc, VALUE *argv, VALUE _)
{
- rb_thread_t *th = GET_THREAD();
VALUE execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE);
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
struct rb_process_status status = {0};
eargp->status = &status;
- last_status_clear(th);
+ rb_last_status_clear();
// This function can set the thread's last status.
// May be different from waitpid_state.pid on exec failure.
@@ -4855,10 +4860,12 @@ rb_f_system(int argc, VALUE *argv, VALUE _)
if (pid > 0) {
VALUE status = rb_process_status_wait(pid, 0);
+
struct rb_process_status *data = rb_check_typeddata(status, &rb_process_status_type);
+
// Set the last status:
rb_obj_freeze(status);
- th->last_status = status;
+ GET_THREAD()->last_status = status;
if (data->status == EXIT_SUCCESS) {
return Qtrue;
@@ -4901,111 +4908,271 @@ rb_f_system(int argc, VALUE *argv, VALUE _)
/*
* call-seq:
- * spawn([env, ] command_line, options = {}) -> pid
- * spawn([env, ] exe_path, *args, options = {}) -> pid
- *
- * Creates a new child process by doing one of the following
- * in that process:
- *
- * - Passing string +command_line+ to the shell.
- * - Invoking the executable at +exe_path+.
- *
- * This method has potential security vulnerabilities if called with untrusted input;
- * see {Command Injection}[rdoc-ref:command_injection.rdoc].
- *
- * Returns the process ID (pid) of the new process,
- * without waiting for it to complete.
- *
- * To avoid zombie processes, the parent process should call either:
- *
- * - Process.wait, to collect the termination statuses of its children.
- * - Process.detach, to register disinterest in their status.
- *
- * The new process is created using the
- * {exec system call}[https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/execve.html];
- * it may inherit some of its environment from the calling program
- * (possibly including open file descriptors).
- *
- * Argument +env+, if given, is a hash that affects +ENV+ for the new process;
- * see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
+ * spawn([env,] command... [,options]) -> pid
+ * Process.spawn([env,] command... [,options]) -> pid
+ *
+ * spawn executes specified command and return its pid.
+ *
+ * pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
+ * Process.wait pid
+ *
+ * pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
+ * Process.wait pid
+ *
+ * This method is similar to Kernel#system but it doesn't wait for the command
+ * to finish.
+ *
+ * The parent process should
+ * use Process.wait to collect
+ * the termination status of its child or
+ * use Process.detach to register
+ * disinterest in their status;
+ * otherwise, the operating system may accumulate zombie processes.
+ *
+ * spawn has bunch of options to specify process attributes:
+ *
+ * env: hash
+ * name => val : set the environment variable
+ * name => nil : unset the environment variable
+ *
+ * the keys and the values except for +nil+ must be strings.
+ * command...:
+ * commandline : command line string which is passed to the standard shell
+ * cmdname, arg1, ... : command name and one or more arguments (This form does not use the shell. See below for caveats.)
+ * [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
+ * options: hash
+ * clearing environment variables:
+ * :unsetenv_others => true : clear environment variables except specified by env
+ * :unsetenv_others => false : don't clear (default)
+ * process group:
+ * :pgroup => true or 0 : make a new process group
+ * :pgroup => pgid : join the specified process group
+ * :pgroup => nil : don't change the process group (default)
+ * create new process group: Windows only
+ * :new_pgroup => true : the new process is the root process of a new process group
+ * :new_pgroup => false : don't create a new process group (default)
+ * resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit.
+ * :rlimit_resourcename => limit
+ * :rlimit_resourcename => [cur_limit, max_limit]
+ * umask:
+ * :umask => int
+ * redirection:
+ * key:
+ * FD : single file descriptor in child process
+ * [FD, FD, ...] : multiple file descriptor in child process
+ * value:
+ * FD : redirect to the file descriptor in parent process
+ * string : redirect to file with open(string, "r" or "w")
+ * [string] : redirect to file with open(string, File::RDONLY)
+ * [string, open_mode] : redirect to file with open(string, open_mode, 0644)
+ * [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
+ * [:child, FD] : redirect to the redirected file descriptor
+ * :close : close the file descriptor in child process
+ * FD is one of follows
+ * :in : the file descriptor 0 which is the standard input
+ * :out : the file descriptor 1 which is the standard output
+ * :err : the file descriptor 2 which is the standard error
+ * integer : the file descriptor of specified the integer
+ * io : the file descriptor specified as io.fileno
+ * file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
+ * :close_others => false : inherit
+ * current directory:
+ * :chdir => str
+ *
+ * The <code>cmdname, arg1, ...</code> form does not use the shell.
+ * However, on different OSes, different things are provided as
+ * built-in commands. An example of this is +'echo'+, which is a
+ * built-in on Windows, but is a normal program on Linux and Mac OS X.
+ * This means that <code>Process.spawn 'echo', '%Path%'</code> will
+ * display the contents of the <tt>%Path%</tt> environment variable
+ * on Windows, but <code>Process.spawn 'echo', '$PATH'</code> prints
+ * the literal <tt>$PATH</tt>.
+ *
+ * If a hash is given as +env+, the environment is
+ * updated by +env+ before <code>exec(2)</code> in the child process.
+ * If a pair in +env+ has nil as the value, the variable is deleted.
+ *
+ * # set FOO as BAR and unset BAZ.
+ * pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)
+ *
+ * If a hash is given as +options+,
+ * it specifies
+ * process group,
+ * create new process group,
+ * resource limit,
+ * current directory,
+ * umask and
+ * redirects for the child process.
+ * Also, it can be specified to clear environment variables.
+ *
+ * The <code>:unsetenv_others</code> key in +options+ specifies
+ * to clear environment variables, other than specified by +env+.
+ *
+ * pid = spawn(command, :unsetenv_others=>true) # no environment variable
+ * pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only
+ *
+ * The <code>:pgroup</code> key in +options+ specifies a process group.
+ * The corresponding value should be true, zero, a positive integer, or nil.
+ * true and zero cause the process to be a process leader of a new process group.
+ * A non-zero positive integer causes the process to join the provided process group.
+ * The default value, nil, causes the process to remain in the same process group.
+ *
+ * pid = spawn(command, :pgroup=>true) # process leader
+ * pid = spawn(command, :pgroup=>10) # belongs to the process group 10
+ *
+ * The <code>:new_pgroup</code> key in +options+ specifies to pass
+ * +CREATE_NEW_PROCESS_GROUP+ flag to <code>CreateProcessW()</code> that is
+ * Windows API. This option is only for Windows.
+ * true means the new process is the root process of the new process group.
+ * The new process has CTRL+C disabled. This flag is necessary for
+ * <code>Process.kill(:SIGINT, pid)</code> on the subprocess.
+ * :new_pgroup is false by default.
+ *
+ * pid = spawn(command, :new_pgroup=>true) # new process group
+ * pid = spawn(command, :new_pgroup=>false) # same process group
+ *
+ * The <code>:rlimit_</code><em>foo</em> key specifies a resource limit.
+ * <em>foo</em> should be one of resource types such as <code>core</code>.
+ * The corresponding value should be an integer or an array which have one or
+ * two integers: same as cur_limit and max_limit arguments for
+ * Process.setrlimit.
+ *
+ * cur, max = Process.getrlimit(:CORE)
+ * pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
+ * pid = spawn(command, :rlimit_core=>max) # enable core dump
+ * pid = spawn(command, :rlimit_core=>0) # never dump core.
+ *
+ * The <code>:umask</code> key in +options+ specifies the umask.
+ *
+ * pid = spawn(command, :umask=>077)
+ *
+ * The :in, :out, :err, an integer, an IO and an array key specifies a redirection.
+ * The redirection maps a file descriptor in the child process.
+ *
+ * For example, stderr can be merged into stdout as follows:
+ *
+ * pid = spawn(command, :err=>:out)
+ * pid = spawn(command, 2=>1)
+ * pid = spawn(command, STDERR=>:out)
+ * pid = spawn(command, STDERR=>STDOUT)
+ *
+ * The hash keys specifies a file descriptor in the child process
+ * started by #spawn.
+ * :err, 2 and STDERR specifies the standard error stream (stderr).
+ *
+ * The hash values specifies a file descriptor in the parent process
+ * which invokes #spawn.
+ * :out, 1 and STDOUT specifies the standard output stream (stdout).
+ *
+ * In the above example,
+ * the standard output in the child process is not specified.
+ * So it is inherited from the parent process.
+ *
+ * The standard input stream (stdin) can be specified by :in, 0 and STDIN.
+ *
+ * A filename can be specified as a hash value.
+ *
+ * pid = spawn(command, :in=>"/dev/null") # read mode
+ * pid = spawn(command, :out=>"/dev/null") # write mode
+ * pid = spawn(command, :err=>"log") # write mode
+ * pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
+ * pid = spawn(command, 3=>"/dev/null") # read mode
*
- * Argument +options+ is a hash of options for the new process;
- * see {Execution Options}[rdoc-ref:Process@Execution+Options].
+ * For stdout and stderr (and combination of them),
+ * it is opened in write mode.
+ * Otherwise read mode is used.
*
- * The first required argument is one of the following:
+ * For specifying flags and permission of file creation explicitly,
+ * an array is used instead.
*
- * - +command_line+ if it is a string,
- * and if it begins with a shell reserved word or special built-in,
- * or if it contains one or more meta characters.
- * - +exe_path+ otherwise.
+ * pid = spawn(command, :in=>["file"]) # read mode is assumed
+ * pid = spawn(command, :in=>["file", "r"])
+ * pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
+ * pid = spawn(command, :out=>["log", "w", 0600])
+ * pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])
*
- * <b>Argument +command_line+</b>
+ * The array specifies a filename, flags and permission.
+ * The flags can be a string or an integer.
+ * If the flags is omitted or nil, File::RDONLY is assumed.
+ * The permission should be an integer.
+ * If the permission is omitted or nil, 0644 is assumed.
*
- * \String argument +command_line+ is a command line to be passed to a shell;
- * it must begin with a shell reserved word, begin with a special built-in,
- * or contain meta characters:
+ * If an array of IOs and integers are specified as a hash key,
+ * all the elements are redirected.
*
- * spawn('if true; then echo "Foo"; fi') # => 798847 # Shell reserved word.
- * Process.wait # => 798847
- * spawn('echo') # => 798848 # Built-in.
- * Process.wait # => 798848
- * spawn('date > /tmp/date.tmp') # => 798879 # Contains meta character.
- * Process.wait # => 798849
- * spawn('date > /nop/date.tmp') # => 798882 # Issues error message.
- * Process.wait # => 798882
+ * # stdout and stderr is redirected to log file.
+ * # The file "log" is opened just once.
+ * pid = spawn(command, [:out, :err]=>["log", "w"])
*
- * The command line may also contain arguments and options for the command:
+ * Another way to merge multiple file descriptors is [:child, fd].
+ * \[:child, fd] means the file descriptor in the child process.
+ * This is different from fd.
+ * For example, :err=>:out means redirecting child stderr to parent stdout.
+ * But :err=>[:child, :out] means redirecting child stderr to child stdout.
+ * They differ if stdout is redirected in the child process as follows.
*
- * spawn('echo "Foo"') # => 799031
- * Process.wait # => 799031
+ * # stdout and stderr is redirected to log file.
+ * # The file "log" is opened just once.
+ * pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])
*
- * Output:
+ * \[:child, :out] can be used to merge stderr into stdout in IO.popen.
+ * In this case, IO.popen redirects stdout to a pipe in the child process
+ * and [:child, :out] refers the redirected stdout.
*
- * Foo
+ * io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
+ * p io.read #=> "out\nerr\n"
*
- * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell.
+ * The <code>:chdir</code> key in +options+ specifies the current directory.
*
- * Raises an exception if the new process could not execute.
+ * pid = spawn(command, :chdir=>"/var/tmp")
*
- * <b>Argument +exe_path+</b>
+ * spawn closes all non-standard unspecified descriptors by default.
+ * The "standard" descriptors are 0, 1 and 2.
+ * This behavior is specified by :close_others option.
+ * :close_others doesn't affect the standard descriptors which are
+ * closed only if :close is specified explicitly.
*
- * Argument +exe_path+ is one of the following:
+ * pid = spawn(command, :close_others=>true) # close 3,4,5,... (default)
+ * pid = spawn(command, :close_others=>false) # don't close 3,4,5,...
*
- * - The string path to an executable to be called:
+ * :close_others is false by default for spawn and IO.popen.
*
- * spawn('/usr/bin/date') # Path to date on Unix-style system.
- * Process.wait
+ * Note that fds which close-on-exec flag is already set are closed
+ * regardless of :close_others option.
*
- * Output:
+ * So IO.pipe and spawn can be used as IO.popen.
*
- * Thu Aug 31 10:06:48 AM CDT 2023
+ * # similar to r = IO.popen(command)
+ * r, w = IO.pipe
+ * pid = spawn(command, :out=>w) # r, w is closed in the child process.
+ * w.close
*
- * - A 2-element array containing the path to an executable
- * and the string to be used as the name of the executing process:
+ * :close is specified as a hash value to close a fd individually.
*
- * pid = spawn(['sleep', 'Hello!'], '1') # 2-element array.
- * p `ps -p #{pid} -o command=`
+ * f = open(foo)
+ * system(command, f=>:close) # don't inherit f.
*
- * Output:
+ * If a file descriptor need to be inherited,
+ * io=>io can be used.
*
- * "Hello! 1\n"
+ * # valgrind has --log-fd option for log destination.
+ * # log_w=>log_w indicates log_w.fileno inherits to child process.
+ * log_r, log_w = IO.pipe
+ * pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
+ * log_w.close
+ * p log_r.read
*
- * Ruby invokes the executable directly, with no shell and no shell expansion.
+ * It is also possible to exchange file descriptors.
*
- * If one or more +args+ is given, each is an argument or option
- * to be passed to the executable:
+ * pid = spawn(command, :out=>:err, :err=>:out)
*
- * spawn('echo', 'C*') # => 799392
- * Process.wait # => 799392
- * spawn('echo', 'hello', 'world') # => 799393
- * Process.wait # => 799393
+ * The hash keys specify file descriptors in the child process.
+ * The hash values specifies file descriptors in the parent process.
+ * So the above specifies exchanging stdout and stderr.
+ * Internally, +spawn+ uses an extra file descriptor to resolve such cyclic
+ * file descriptor mapping.
*
- * Output:
- *
- * C*
- * hello world
- *
- * Raises an exception if the new process could not execute.
+ * See Kernel.exec for the standard shell.
*/
static VALUE
@@ -5037,18 +5204,19 @@ rb_f_spawn(int argc, VALUE *argv, VALUE _)
/*
* call-seq:
- * sleep(secs = nil) -> slept_secs
- *
- * Suspends execution of the current thread for the number of seconds
- * specified by numeric argument +secs+, or forever if +secs+ is +nil+;
- * returns the integer number of seconds suspended (rounded).
- *
- * Time.new # => 2008-03-08 19:56:19 +0900
- * sleep 1.2 # => 1
- * Time.new # => 2008-03-08 19:56:20 +0900
- * sleep 1.9 # => 2
- * Time.new # => 2008-03-08 19:56:22 +0900
- *
+ * sleep([duration]) -> integer
+ *
+ * Suspends the current thread for _duration_ seconds (which may be any number,
+ * including a +Float+ with fractional seconds). Returns the actual number of
+ * seconds slept (rounded), which may be less than that asked for if another
+ * thread calls Thread#run. Called without an argument, sleep()
+ * will sleep forever.
+ *
+ * Time.new #=> 2008-03-08 19:56:19 +0900
+ * sleep 1.2 #=> 1
+ * Time.new #=> 2008-03-08 19:56:20 +0900
+ * sleep 1.9 #=> 2
+ * Time.new #=> 2008-03-08 19:56:22 +0900
*/
static VALUE
@@ -5061,7 +5229,7 @@ rb_f_sleep(int argc, VALUE *argv, VALUE _)
rb_fiber_scheduler_kernel_sleepv(scheduler, argc, argv);
}
else {
- if (argc == 0 || (argc == 1 && NIL_P(argv[0]))) {
+ if (argc == 0) {
rb_thread_sleep_forever();
}
else {
@@ -5079,13 +5247,13 @@ rb_f_sleep(int argc, VALUE *argv, VALUE _)
#if (defined(HAVE_GETPGRP) && defined(GETPGRP_VOID)) || defined(HAVE_GETPGID)
/*
* call-seq:
- * Process.getpgrp -> integer
- *
- * Returns the process group ID for the current process:
+ * Process.getpgrp -> integer
*
- * Process.getpgid(0) # => 25527
- * Process.getpgrp # => 25527
+ * Returns the process group ID for this process. Not available on
+ * all platforms.
*
+ * Process.getpgid(0) #=> 25527
+ * Process.getpgrp #=> 25527
*/
static VALUE
@@ -5111,11 +5279,10 @@ proc_getpgrp(VALUE _)
#if defined(HAVE_SETPGID) || (defined(HAVE_SETPGRP) && defined(SETPGRP_VOID))
/*
* call-seq:
- * Process.setpgrp -> 0
+ * Process.setpgrp -> 0
*
- * Equivalent to <tt>setpgid(0, 0)</tt>.
- *
- * Not available on all platforms.
+ * Equivalent to <code>setpgid(0,0)</code>. Not available on all
+ * platforms.
*/
static VALUE
@@ -5140,13 +5307,12 @@ proc_setpgrp(VALUE _)
#if defined(HAVE_GETPGID)
/*
* call-seq:
- * Process.getpgid(pid) -> integer
+ * Process.getpgid(pid) -> integer
*
- * Returns the process group ID for the given process ID +pid+:
- *
- * Process.getpgid(Process.ppid) # => 25527
+ * Returns the process group ID for the given process id. Not
+ * available on all platforms.
*
- * Not available on all platforms.
+ * Process.getpgid(Process.ppid()) #=> 25527
*/
static VALUE
@@ -5166,12 +5332,10 @@ proc_getpgid(VALUE obj, VALUE pid)
#ifdef HAVE_SETPGID
/*
* call-seq:
- * Process.setpgid(pid, pgid) -> 0
+ * Process.setpgid(pid, integer) -> 0
*
- * Sets the process group ID for the process given by process ID +pid+
- * to +pgid+.
- *
- * Not available on all platforms.
+ * Sets the process group ID of _pid_ (0 indicates this
+ * process) to <em>integer</em>. Not available on all platforms.
*/
static VALUE
@@ -5193,16 +5357,15 @@ proc_setpgid(VALUE obj, VALUE pid, VALUE pgrp)
#ifdef HAVE_GETSID
/*
* call-seq:
- * Process.getsid(pid = nil) -> integer
+ * Process.getsid() -> integer
+ * Process.getsid(pid) -> integer
*
- * Returns the session ID of the given process ID +pid+,
- * or of the current process if not given:
+ * Returns the session ID for the given process id. If not given,
+ * return current process sid. Not available on all platforms.
*
- * Process.getsid # => 27422
- * Process.getsid(0) # => 27422
- * Process.getsid(Process.pid()) # => 27422
- *
- * Not available on all platforms.
+ * Process.getsid() #=> 27422
+ * Process.getsid(0) #=> 27422
+ * Process.getsid(Process.pid()) #=> 27422
*/
static VALUE
proc_getsid(int argc, VALUE *argv, VALUE _)
@@ -5229,15 +5392,13 @@ static rb_pid_t ruby_setsid(void);
#endif
/*
* call-seq:
- * Process.setsid -> integer
+ * Process.setsid -> integer
*
- * Establishes the current process as a new session and process group leader,
- * with no controlling tty;
- * returns the session ID:
- *
- * Process.setsid # => 27422
+ * Establishes this process as a new session and process group
+ * leader, with no controlling tty. Returns the session id. Not
+ * available on all platforms.
*
- * Not available on all platforms.
+ * Process.setsid #=> 27422
*/
static VALUE
@@ -5285,26 +5446,19 @@ ruby_setsid(void)
#ifdef HAVE_GETPRIORITY
/*
* call-seq:
- * Process.getpriority(kind, id) -> integer
- *
- * Returns the scheduling priority for specified process, process group,
- * or user.
- *
- * Argument +kind+ is one of:
- *
- * - Process::PRIO_PROCESS: return priority for process.
- * - Process::PRIO_PGRP: return priority for process group.
- * - Process::PRIO_USER: return priority for user.
- *
- * Argument +id+ is the ID for the process, process group, or user;
- * zero specified the current ID for +kind+.
- *
- * Examples:
- *
- * Process.getpriority(Process::PRIO_USER, 0) # => 19
- * Process.getpriority(Process::PRIO_PROCESS, 0) # => 19
- *
- * Not available on all platforms.
+ * Process.getpriority(kind, integer) -> integer
+ *
+ * Gets the scheduling priority for specified process, process group,
+ * or user. <em>kind</em> indicates the kind of entity to find: one
+ * of Process::PRIO_PGRP,
+ * Process::PRIO_USER, or
+ * Process::PRIO_PROCESS. _integer_ is an id
+ * indicating the particular process, process group, or user (an id
+ * of 0 means _current_). Lower priorities are more favorable
+ * for scheduling. Not available on all platforms.
+ *
+ * Process.getpriority(Process::PRIO_USER, 0) #=> 19
+ * Process.getpriority(Process::PRIO_PROCESS, 0) #=> 19
*/
static VALUE
@@ -5328,18 +5482,14 @@ proc_getpriority(VALUE obj, VALUE which, VALUE who)
#ifdef HAVE_GETPRIORITY
/*
* call-seq:
- * Process.setpriority(kind, integer, priority) -> 0
+ * Process.setpriority(kind, integer, priority) -> 0
*
* See Process.getpriority.
*
- * Examples:
- *
- * Process.setpriority(Process::PRIO_USER, 0, 19) # => 0
- * Process.setpriority(Process::PRIO_PROCESS, 0, 19) # => 0
- * Process.getpriority(Process::PRIO_USER, 0) # => 19
- * Process.getpriority(Process::PRIO_PROCESS, 0) # => 19
- *
- * Not available on all platforms.
+ * Process.setpriority(Process::PRIO_USER, 0, 19) #=> 0
+ * Process.setpriority(Process::PRIO_PROCESS, 0, 19) #=> 0
+ * Process.getpriority(Process::PRIO_USER, 0) #=> 19
+ * Process.getpriority(Process::PRIO_PROCESS, 0) #=> 19
*/
static VALUE
@@ -5587,24 +5737,22 @@ rlimit_resource_value(VALUE rval)
#if defined(HAVE_GETRLIMIT) && defined(RLIM2NUM)
/*
* call-seq:
- * Process.getrlimit(resource) -> [cur_limit, max_limit]
- *
- * Returns a 2-element array of the current (soft) limit
- * and maximum (hard) limit for the given +resource+.
- *
- * Argument +resource+ specifies the resource whose limits are to be returned;
- * see Process.setrlimit.
- *
- * Each of the returned values +cur_limit+ and +max_limit+ is an integer;
- * see Process.setrlimit.
- *
- * Example:
- *
- * Process.getrlimit(:CORE) # => [0, 18446744073709551615]
- *
- * See Process.setrlimit.
- *
- * Not available on all platforms.
+ * Process.getrlimit(resource) -> [cur_limit, max_limit]
+ *
+ * Gets the resource limit of the process.
+ * _cur_limit_ means current (soft) limit and
+ * _max_limit_ means maximum (hard) limit.
+ *
+ * _resource_ indicates the kind of resource to limit.
+ * It is specified as a symbol such as <code>:CORE</code>,
+ * a string such as <code>"CORE"</code> or
+ * a constant such as Process::RLIMIT_CORE.
+ * See Process.setrlimit for details.
+ *
+ * _cur_limit_ and _max_limit_ may be Process::RLIM_INFINITY,
+ * Process::RLIM_SAVED_MAX or
+ * Process::RLIM_SAVED_CUR.
+ * See Process.setrlimit and the system getrlimit(2) manual for details.
*/
static VALUE
@@ -5624,54 +5772,54 @@ proc_getrlimit(VALUE obj, VALUE resource)
#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
/*
* call-seq:
- * Process.setrlimit(resource, cur_limit, max_limit = cur_limit) -> nil
- *
- * Sets limits for the current process for the given +resource+
- * to +cur_limit+ (soft limit) and +max_limit+ (hard limit);
- * returns +nil+.
- *
- * Argument +resource+ specifies the resource whose limits are to be set;
- * the argument may be given as a symbol, as a string, or as a constant
- * beginning with <tt>Process::RLIMIT_</tt>
- * (e.g., +:CORE+, <tt>'CORE'</tt>, or <tt>Process::RLIMIT_CORE</tt>.
- *
- * The resources available and supported are system-dependent,
- * and may include (here expressed as symbols):
- *
- * - +:AS+: Total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD except 4.4BSD-Lite).
- * - +:CORE+: Core size (bytes) (SUSv3).
- * - +:CPU+: CPU time (seconds) (SUSv3).
- * - +:DATA+: Data segment (bytes) (SUSv3).
- * - +:FSIZE+: File size (bytes) (SUSv3).
- * - +:MEMLOCK+: Total size for mlock(2) (bytes) (4.4BSD, GNU/Linux).
- * - +:MSGQUEUE+: Allocation for POSIX message queues (bytes) (GNU/Linux).
- * - +:NICE+: Ceiling on process's nice(2) value (number) (GNU/Linux).
- * - +:NOFILE+: File descriptors (number) (SUSv3).
- * - +:NPROC+: Number of processes for the user (number) (4.4BSD, GNU/Linux).
- * - +:NPTS+: Number of pseudo terminals (number) (FreeBSD).
- * - +:RSS+: Resident memory size (bytes) (4.2BSD, GNU/Linux).
- * - +:RTPRIO+: Ceiling on the process's real-time priority (number) (GNU/Linux).
- * - +:RTTIME+: CPU time for real-time process (us) (GNU/Linux).
- * - +:SBSIZE+: All socket buffers (bytes) (NetBSD, FreeBSD).
- * - +:SIGPENDING+: Number of queued signals allowed (signals) (GNU/Linux).
- * - +:STACK+: Stack size (bytes) (SUSv3).
- *
- * Arguments +cur_limit+ and +max_limit+ may be:
- *
- * - Integers (+max_limit+ should not be smaller than +cur_limit+).
- * - Symbol +:SAVED_MAX+, string <tt>'SAVED_MAX'</tt>,
- * or constant <tt>Process::RLIM_SAVED_MAX</tt>: saved maximum limit.
- * - Symbol +:SAVED_CUR+, string <tt>'SAVED_CUR'</tt>,
- * or constant <tt>Process::RLIM_SAVED_CUR</tt>: saved current limit.
- * - Symbol +:INFINITY+, string <tt>'INFINITY'</tt>,
- * or constant <tt>Process::RLIM_INFINITY</tt>: no limit on resource.
- *
- * This example raises the soft limit of core size to
- * the hard limit to try to make core dump possible:
+ * Process.setrlimit(resource, cur_limit, max_limit) -> nil
+ * Process.setrlimit(resource, cur_limit) -> nil
+ *
+ * Sets the resource limit of the process.
+ * _cur_limit_ means current (soft) limit and
+ * _max_limit_ means maximum (hard) limit.
+ *
+ * If _max_limit_ is not given, _cur_limit_ is used.
+ *
+ * _resource_ indicates the kind of resource to limit.
+ * It should be a symbol such as <code>:CORE</code>,
+ * a string such as <code>"CORE"</code> or
+ * a constant such as Process::RLIMIT_CORE.
+ * The available resources are OS dependent.
+ * Ruby may support following resources.
+ *
+ * [AS] total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but 4.4BSD-Lite)
+ * [CORE] core size (bytes) (SUSv3)
+ * [CPU] CPU time (seconds) (SUSv3)
+ * [DATA] data segment (bytes) (SUSv3)
+ * [FSIZE] file size (bytes) (SUSv3)
+ * [MEMLOCK] total size for mlock(2) (bytes) (4.4BSD, GNU/Linux)
+ * [MSGQUEUE] allocation for POSIX message queues (bytes) (GNU/Linux)
+ * [NICE] ceiling on process's nice(2) value (number) (GNU/Linux)
+ * [NOFILE] file descriptors (number) (SUSv3)
+ * [NPROC] number of processes for the user (number) (4.4BSD, GNU/Linux)
+ * [NPTS] number of pseudo terminals (number) (FreeBSD)
+ * [RSS] resident memory size (bytes) (4.2BSD, GNU/Linux)
+ * [RTPRIO] ceiling on the process's real-time priority (number) (GNU/Linux)
+ * [RTTIME] CPU time for real-time process (us) (GNU/Linux)
+ * [SBSIZE] all socket buffers (bytes) (NetBSD, FreeBSD)
+ * [SIGPENDING] number of queued signals allowed (signals) (GNU/Linux)
+ * [STACK] stack size (bytes) (SUSv3)
+ *
+ * _cur_limit_ and _max_limit_ may be
+ * <code>:INFINITY</code>, <code>"INFINITY"</code> or
+ * Process::RLIM_INFINITY,
+ * which means that the resource is not limited.
+ * They may be Process::RLIM_SAVED_MAX,
+ * Process::RLIM_SAVED_CUR and
+ * corresponding symbols and strings too.
+ * See system setrlimit(2) manual for details.
+ *
+ * The following example raises the soft limit of core size to
+ * the hard limit to try to make core dump possible.
*
* Process.setrlimit(:CORE, Process.getrlimit(:CORE)[1])
*
- * Not available on all platforms.
*/
static VALUE
@@ -6250,14 +6398,13 @@ p_sys_setresuid(VALUE obj, VALUE rid, VALUE eid, VALUE sid)
/*
* call-seq:
- * Process.uid -> integer
- * Process::UID.rid -> integer
- * Process::Sys.getuid -> integer
- *
- * Returns the (real) user ID of the current process.
+ * Process.uid -> integer
+ * Process::UID.rid -> integer
+ * Process::Sys.getuid -> integer
*
- * Process.uid # => 1000
+ * Returns the (real) user ID of this process.
*
+ * Process.uid #=> 501
*/
static VALUE
@@ -6271,13 +6418,10 @@ proc_getuid(VALUE obj)
#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRUID) || defined(HAVE_SETUID)
/*
* call-seq:
- * Process.uid = new_uid -> new_uid
- *
- * Sets the (user) user ID for the current process to +new_uid+:
- *
- * Process.uid = 1000 # => 1000
+ * Process.uid= user -> numeric
*
- * Not available on all platforms.
+ * Sets the (user) user ID for this process. Not available on all
+ * platforms.
*/
static VALUE
@@ -6652,14 +6796,13 @@ p_sys_issetugid(VALUE obj)
/*
* call-seq:
- * Process.gid -> integer
- * Process::GID.rid -> integer
- * Process::Sys.getgid -> integer
- *
- * Returns the (real) group ID for the current process:
+ * Process.gid -> integer
+ * Process::GID.rid -> integer
+ * Process::Sys.getgid -> integer
*
- * Process.gid # => 1000
+ * Returns the (real) group ID for this process.
*
+ * Process.gid #=> 500
*/
static VALUE
@@ -6673,12 +6816,9 @@ proc_getgid(VALUE obj)
#if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETRGID) || defined(HAVE_SETGID)
/*
* call-seq:
- * Process.gid = new_gid -> new_gid
- *
- * Sets the group ID for the current process to +new_gid+:
- *
- * Process.gid = 1000 # => 1000
+ * Process.gid= integer -> integer
*
+ * Sets the group ID for this process.
*/
static VALUE
@@ -6762,23 +6902,26 @@ maxgroups(void)
#ifdef HAVE_GETGROUPS
/*
* call-seq:
- * Process.groups -> array
+ * Process.groups -> array
*
- * Returns an array of the group IDs
- * in the supplemental group access list for the current process:
+ * Get an Array of the group IDs in the
+ * supplemental group access list for this process.
*
- * Process.groups # => [4, 24, 27, 30, 46, 122, 135, 136, 1000]
+ * Process.groups #=> [27, 6, 10, 11]
*
- * These properties of the returned array are system-dependent:
+ * Note that this method is just a wrapper of getgroups(2).
+ * This means that the following characteristics of
+ * the result completely depend on your system:
*
- * - Whether (and how) the array is sorted.
- * - Whether the array includes effective group IDs.
- * - Whether the array includes duplicate group IDs.
- * - Whether the array size exceeds the value of Process.maxgroups.
+ * - the result is sorted
+ * - the result includes effective GIDs
+ * - the result does not include duplicated GIDs
+ * - the result size does not exceed the value of Process.maxgroups
*
- * Use this call to get a sorted and unique array:
+ * You can make sure to get a sorted unique GID list of
+ * the current process by this expression:
*
- * Process.groups.uniq.sort
+ * Process.groups.uniq.sort
*
*/
@@ -6815,14 +6958,14 @@ proc_getgroups(VALUE obj)
#ifdef HAVE_SETGROUPS
/*
* call-seq:
- * Process.groups = new_groups -> new_groups
+ * Process.groups= array -> array
*
- * Sets the supplemental group access list to the given
- * array of group IDs.
+ * Set the supplemental group access list to the given
+ * Array of group IDs.
*
- * Process.groups # => [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
- * Process.groups = [27, 6, 10, 11] # => [27, 6, 10, 11]
- * Process.groups # => [27, 6, 10, 11]
+ * Process.groups #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
+ * Process.groups = [27, 6, 10, 11] #=> [27, 6, 10, 11]
+ * Process.groups #=> [27, 6, 10, 11]
*
*/
@@ -6864,21 +7007,19 @@ proc_setgroups(VALUE obj, VALUE ary)
#ifdef HAVE_INITGROUPS
/*
* call-seq:
- * Process.initgroups(username, gid) -> array
+ * Process.initgroups(username, gid) -> array
*
- * Sets the supplemental group access list;
- * the new list includes:
+ * Initializes the supplemental group access list by reading the
+ * system group database and using all groups of which the given user
+ * is a member. The group with the specified _gid_ is also added to
+ * the list. Returns the resulting Array of the GIDs of all the
+ * groups in the supplementary group access list. Not available on
+ * all platforms.
*
- * - The group IDs of those groups to which the user given by +username+ belongs.
- * - The group ID +gid+.
+ * Process.groups #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
+ * Process.initgroups( "mgranger", 30 ) #=> [30, 6, 10, 11]
+ * Process.groups #=> [30, 6, 10, 11]
*
- * Example:
- *
- * Process.groups # => [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]
- * Process.initgroups('me', 30) # => [30, 6, 10, 11]
- * Process.groups # => [30, 6, 10, 11]
- *
- * Not available on all platforms.
*/
static VALUE
@@ -6896,13 +7037,12 @@ proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp)
#if defined(_SC_NGROUPS_MAX) || defined(NGROUPS_MAX)
/*
* call-seq:
- * Process.maxgroups -> integer
- *
- * Returns the maximum number of group IDs allowed
- * in the supplemental group access list:
+ * Process.maxgroups -> integer
*
- * Process.maxgroups # => 32
+ * Returns the maximum number of GIDs allowed in the supplemental
+ * group access list.
*
+ * Process.maxgroups #=> 32
*/
static VALUE
@@ -6917,10 +7057,10 @@ proc_getmaxgroups(VALUE obj)
#ifdef HAVE_SETGROUPS
/*
* call-seq:
- * Process.maxgroups = new_max -> new_max
+ * Process.maxgroups= integer -> integer
*
- * Sets the maximum number of group IDs allowed
- * in the supplemental group access list.
+ * Sets the maximum number of GIDs allowed in the supplemental group
+ * access list.
*/
static VALUE
@@ -6951,22 +7091,16 @@ static int rb_daemon(int nochdir, int noclose);
/*
* call-seq:
- * Process.daemon(nochdir = nil, noclose = nil) -> 0
- *
- * Detaches the current process from its controlling terminal
- * and runs it in the background as system daemon;
- * returns zero.
- *
- * By default:
- *
- * - Changes the current working directory to the root directory.
- * - Redirects $stdin, $stdout, and $stderr to the null device.
- *
- * If optional argument +nochdir+ is +true+,
- * does not change the current working directory.
- *
- * If optional argument +noclose+ is +true+,
- * does not redirect $stdin, $stdout, or $stderr.
+ * Process.daemon() -> 0
+ * Process.daemon(nochdir=nil,noclose=nil) -> 0
+ *
+ * Detach the process from controlling terminal and run in
+ * the background as system daemon. Unless the argument
+ * nochdir is true (i.e. non false), it changes the current
+ * working directory to the root ("/"). Unless the argument
+ * noclose is true, daemon() will redirect standard input,
+ * standard output and standard error to /dev/null.
+ * Return zero on success, or raise one of Errno::*.
*/
static VALUE
@@ -6985,16 +7119,16 @@ proc_daemon(int argc, VALUE *argv, VALUE _)
return INT2FIX(n);
}
-extern const char ruby_null_device[];
-
static int
rb_daemon(int nochdir, int noclose)
{
int err = 0;
#ifdef HAVE_DAEMON
+ if (mjit_enabled) mjit_pause(false); // Don't leave locked mutex to child.
before_fork_ruby();
err = daemon(nochdir, noclose);
- after_fork_ruby(0);
+ after_fork_ruby();
+ rb_thread_atfork(); /* calls mjit_resume() */
#else
int n;
@@ -7010,7 +7144,7 @@ rb_daemon(int nochdir, int noclose)
if (!nochdir)
err = chdir("/");
- if (!noclose && (n = rb_cloexec_open(ruby_null_device, O_RDWR, 0)) != -1) {
+ if (!noclose && (n = rb_cloexec_open("/dev/null", O_RDWR, 0)) != -1) {
rb_update_max_fd(n);
(void)dup2(n, 0);
(void)dup2(n, 1);
@@ -7223,14 +7357,13 @@ p_gid_change_privilege(VALUE obj, VALUE id)
/*
* call-seq:
- * Process.euid -> integer
- * Process::UID.eid -> integer
- * Process::Sys.geteuid -> integer
+ * Process.euid -> integer
+ * Process::UID.eid -> integer
+ * Process::Sys.geteuid -> integer
*
- * Returns the effective user ID for the current process.
- *
- * Process.euid # => 501
+ * Returns the effective user ID for this process.
*
+ * Process.euid #=> 501
*/
static VALUE
@@ -7266,11 +7399,10 @@ proc_seteuid(rb_uid_t uid)
#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID) || defined(HAVE_SETUID)
/*
* call-seq:
- * Process.euid = new_euid -> new_euid
- *
- * Sets the effective user ID for the current process.
+ * Process.euid= user
*
- * Not available on all platforms.
+ * Sets the effective user ID for this process. Not available on all
+ * platforms.
*/
static VALUE
@@ -7348,15 +7480,14 @@ p_uid_grant_privilege(VALUE obj, VALUE id)
/*
* call-seq:
- * Process.egid -> integer
- * Process::GID.eid -> integer
- * Process::Sys.geteid -> integer
- *
- * Returns the effective group ID for the current process:
+ * Process.egid -> integer
+ * Process::GID.eid -> integer
+ * Process::Sys.geteid -> integer
*
- * Process.egid # => 500
+ * Returns the effective group ID for this process. Not available on
+ * all platforms.
*
- * Not available on all platforms.
+ * Process.egid #=> 500
*/
static VALUE
@@ -7370,11 +7501,10 @@ proc_getegid(VALUE obj)
#if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID) || defined(_POSIX_SAVED_IDS)
/*
* call-seq:
- * Process.egid = new_egid -> new_egid
- *
- * Sets the effective group ID for the current process.
+ * Process.egid = integer -> integer
*
- * Not available on all platforms.
+ * Sets the effective group ID for this process. Not available on all
+ * platforms.
*/
static VALUE
@@ -7847,15 +7977,14 @@ get_clk_tck(void)
/*
* call-seq:
- * Process.times -> process_tms
- *
- * Returns a Process::Tms structure that contains user and system CPU times
- * for the current process, and for its children processes:
+ * Process.times -> aProcessTms
*
- * Process.times
- * # => #<struct Process::Tms utime=55.122118, stime=35.533068, cutime=0.0, cstime=0.002846>
+ * Returns a <code>Tms</code> structure (see Process::Tms)
+ * that contains user and system CPU times for this process,
+ * and also for children processes.
*
- * The precision is platform-defined.
+ * t = Process.times
+ * [ t.utime, t.stime, t.cutime, t.cstime ] #=> [0.0, 0.02, 0.00, 0.00]
*/
VALUE
@@ -8110,174 +8239,132 @@ ruby_real_ms_time(void)
# define NUM2CLOCKID(x) 0
#endif
-#define clock_failed(name, err, arg) do { \
- int clock_error = (err); \
- rb_syserr_fail_str(clock_error, rb_sprintf("clock_" name "(%+"PRIsVALUE")", (arg))); \
- } while (0)
-
/*
* call-seq:
- * Process.clock_gettime(clock_id, unit = :float_second) -> number
- *
- * Returns a clock time as determined by POSIX function
- * {clock_gettime()}[https://man7.org/linux/man-pages/man3/clock_gettime.3.html]:
- *
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID) # => 198.650379677
- *
- * Argument +clock_id+ should be a symbol or a constant that specifies
- * the clock whose time is to be returned;
- * see below.
- *
- * Optional argument +unit+ should be a symbol that specifies
- * the unit to be used in the returned clock time;
- * see below.
- *
- * <b>Argument +clock_id+</b>
- *
- * Argument +clock_id+ specifies the clock whose time is to be returned;
- * it may be a constant such as <tt>Process::CLOCK_REALTIME</tt>,
- * or a symbol shorthand such as +:CLOCK_REALTIME+.
- *
- * The supported clocks depend on the underlying operating system;
- * this method supports the following clocks on the indicated platforms
- * (raises Errno::EINVAL if called with an unsupported clock):
- *
- * - +:CLOCK_BOOTTIME+: Linux 2.6.39.
- * - +:CLOCK_BOOTTIME_ALARM+: Linux 3.0.
- * - +:CLOCK_MONOTONIC+: SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12, Windows-2000.
- * - +:CLOCK_MONOTONIC_COARSE+: Linux 2.6.32.
- * - +:CLOCK_MONOTONIC_FAST+: FreeBSD 8.1.
- * - +:CLOCK_MONOTONIC_PRECISE+: FreeBSD 8.1.
- * - +:CLOCK_MONOTONIC_RAW+: Linux 2.6.28, macOS 10.12.
- * - +:CLOCK_MONOTONIC_RAW_APPROX+: macOS 10.12.
- * - +:CLOCK_PROCESS_CPUTIME_ID+: SUSv3 to 4, Linux 2.5.63, FreeBSD 9.3, OpenBSD 5.4, macOS 10.12.
- * - +:CLOCK_PROF+: FreeBSD 3.0, OpenBSD 2.1.
- * - +:CLOCK_REALTIME+: SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12, Windows-8/Server-2012.
- * Time.now is recommended over +:CLOCK_REALTIME:.
- * - +:CLOCK_REALTIME_ALARM+: Linux 3.0.
- * - +:CLOCK_REALTIME_COARSE+: Linux 2.6.32.
- * - +:CLOCK_REALTIME_FAST+: FreeBSD 8.1.
- * - +:CLOCK_REALTIME_PRECISE+: FreeBSD 8.1.
- * - +:CLOCK_SECOND+: FreeBSD 8.1.
- * - +:CLOCK_TAI+: Linux 3.10.
- * - +:CLOCK_THREAD_CPUTIME_ID+: SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12.
- * - +:CLOCK_UPTIME+: FreeBSD 7.0, OpenBSD 5.5.
- * - +:CLOCK_UPTIME_FAST+: FreeBSD 8.1.
- * - +:CLOCK_UPTIME_PRECISE+: FreeBSD 8.1.
- * - +:CLOCK_UPTIME_RAW+: macOS 10.12.
- * - +:CLOCK_UPTIME_RAW_APPROX+: macOS 10.12.
- * - +:CLOCK_VIRTUAL+: FreeBSD 3.0, OpenBSD 2.1.
+ * Process.clock_gettime(clock_id [, unit]) -> number
+ *
+ * Returns a time returned by POSIX clock_gettime() function.
+ *
+ * p Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ * #=> 896053.968060096
+ *
+ * +clock_id+ specifies a kind of clock.
+ * It is specified as a constant which begins with <code>Process::CLOCK_</code>
+ * such as Process::CLOCK_REALTIME and Process::CLOCK_MONOTONIC.
+ *
+ * The supported constants depends on OS and version.
+ * Ruby provides following types of +clock_id+ if available.
+ *
+ * [CLOCK_REALTIME] SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12, Windows-8/Server-2012
+ * [CLOCK_MONOTONIC] SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12, Windows-2000
+ * [CLOCK_PROCESS_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, FreeBSD 9.3, OpenBSD 5.4, macOS 10.12
+ * [CLOCK_THREAD_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12
+ * [CLOCK_VIRTUAL] FreeBSD 3.0, OpenBSD 2.1
+ * [CLOCK_PROF] FreeBSD 3.0, OpenBSD 2.1
+ * [CLOCK_REALTIME_FAST] FreeBSD 8.1
+ * [CLOCK_REALTIME_PRECISE] FreeBSD 8.1
+ * [CLOCK_REALTIME_COARSE] Linux 2.6.32
+ * [CLOCK_REALTIME_ALARM] Linux 3.0
+ * [CLOCK_MONOTONIC_FAST] FreeBSD 8.1
+ * [CLOCK_MONOTONIC_PRECISE] FreeBSD 8.1
+ * [CLOCK_MONOTONIC_COARSE] Linux 2.6.32
+ * [CLOCK_MONOTONIC_RAW] Linux 2.6.28, macOS 10.12
+ * [CLOCK_MONOTONIC_RAW_APPROX] macOS 10.12
+ * [CLOCK_BOOTTIME] Linux 2.6.39
+ * [CLOCK_BOOTTIME_ALARM] Linux 3.0
+ * [CLOCK_UPTIME] FreeBSD 7.0, OpenBSD 5.5
+ * [CLOCK_UPTIME_FAST] FreeBSD 8.1
+ * [CLOCK_UPTIME_RAW] macOS 10.12
+ * [CLOCK_UPTIME_RAW_APPROX] macOS 10.12
+ * [CLOCK_UPTIME_PRECISE] FreeBSD 8.1
+ * [CLOCK_SECOND] FreeBSD 8.1
+ * [CLOCK_TAI] Linux 3.10
*
* Note that SUS stands for Single Unix Specification.
* SUS contains POSIX and clock_gettime is defined in the POSIX part.
- * SUS defines +:CLOCK_REALTIME+ as mandatory but
- * +:CLOCK_MONOTONIC+, +:CLOCK_PROCESS_CPUTIME_ID+,
- * and +:CLOCK_THREAD_CPUTIME_ID+ are optional.
- *
- * Certain emulations are used when the given +clock_id+
- * is not supported directly:
- *
- * - Emulations for +:CLOCK_REALTIME+:
- *
- * - +:GETTIMEOFDAY_BASED_CLOCK_REALTIME+:
- * Use gettimeofday() defined by SUS (deprecated in SUSv4).
- * The resolution is 1 microsecond.
- * - +:TIME_BASED_CLOCK_REALTIME+:
- * Use time() defined by ISO C.
- * The resolution is 1 second.
- *
- * - Emulations for +:CLOCK_MONOTONIC+:
- *
- * - +:MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC+:
- * Use mach_absolute_time(), available on Darwin.
- * The resolution is CPU dependent.
- * - +:TIMES_BASED_CLOCK_MONOTONIC+:
- * Use the result value of times() defined by POSIX, thus:
- * >>>
- * Upon successful completion, times() shall return the elapsed real time,
- * in clock ticks, since an arbitrary point in the past
- * (for example, system start-up time).
- *
- * For example, GNU/Linux returns a value based on jiffies and it is monotonic.
- * However, 4.4BSD uses gettimeofday() and it is not monotonic.
- * (FreeBSD uses +:CLOCK_MONOTONIC+ instead, though.)
- *
- * The resolution is the clock tick.
- * "getconf CLK_TCK" command shows the clock ticks per second.
- * (The clock ticks-per-second is defined by HZ macro in older systems.)
- * If it is 100 and clock_t is 32 bits integer type,
- * the resolution is 10 millisecond and cannot represent over 497 days.
- *
- * - Emulations for +:CLOCK_PROCESS_CPUTIME_ID+:
- *
- * - +:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID+:
- * Use getrusage() defined by SUS.
- * getrusage() is used with RUSAGE_SELF to obtain the time only for
- * the calling process (excluding the time for child processes).
- * The result is addition of user time (ru_utime) and system time (ru_stime).
- * The resolution is 1 microsecond.
- * - +:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID+:
- * Use times() defined by POSIX.
- * The result is addition of user time (tms_utime) and system time (tms_stime).
- * tms_cutime and tms_cstime are ignored to exclude the time for child processes.
- * The resolution is the clock tick.
- * "getconf CLK_TCK" command shows the clock ticks per second.
- * (The clock ticks per second is defined by HZ macro in older systems.)
- * If it is 100, the resolution is 10 millisecond.
- * - +:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID+:
- * Use clock() defined by ISO C.
- * The resolution is <tt>1/CLOCKS_PER_SEC</tt>.
- * +CLOCKS_PER_SEC+ is the C-level macro defined by time.h.
- * SUS defines +CLOCKS_PER_SEC+ as 1000000;
- * other systems may define it differently.
- * If +CLOCKS_PER_SEC+ is 1000000 (as in SUS),
- * the resolution is 1 microsecond.
- * If +CLOCKS_PER_SEC+ is 1000000 and clock_t is a 32-bit integer type,
- * it cannot represent over 72 minutes.
- *
- * <b>Argument +unit+</b>
- *
- * Optional argument +unit+ (default +:float_second+)
- * specifies the unit for the returned value.
- *
- * - +:float_microsecond+: Number of microseconds as a float.
- * - +:float_millisecond+: Number of milliseconds as a float.
- * - +:float_second+: Number of seconds as a float.
- * - +:microsecond+: Number of microseconds as an integer.
- * - +:millisecond+: Number of milliseconds as an integer.
- * - +:nanosecond+: Number of nanoseconds as an integer.
- * - +::second+: Number of seconds as an integer.
- *
- * Examples:
- *
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_microsecond)
- * # => 203605054.825
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_millisecond)
- * # => 203643.696848
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_second)
- * # => 203.762181929
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :microsecond)
- * # => 204123212
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :millisecond)
- * # => 204298
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :nanosecond)
- * # => 204602286036
- * Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :second)
- * # => 204
+ * SUS defines CLOCK_REALTIME mandatory but
+ * CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID are optional.
+ *
+ * Also, several symbols are accepted as +clock_id+.
+ * There are emulations for clock_gettime().
+ *
+ * For example, Process::CLOCK_REALTIME is defined as
+ * +:GETTIMEOFDAY_BASED_CLOCK_REALTIME+ when clock_gettime() is not available.
+ *
+ * Emulations for +CLOCK_REALTIME+:
+ * [:GETTIMEOFDAY_BASED_CLOCK_REALTIME]
+ * Use gettimeofday() defined by SUS.
+ * (SUSv4 obsoleted it, though.)
+ * The resolution is 1 microsecond.
+ * [:TIME_BASED_CLOCK_REALTIME]
+ * Use time() defined by ISO C.
+ * The resolution is 1 second.
+ *
+ * Emulations for +CLOCK_MONOTONIC+:
+ * [:MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC]
+ * Use mach_absolute_time(), available on Darwin.
+ * The resolution is CPU dependent.
+ * [:TIMES_BASED_CLOCK_MONOTONIC]
+ * Use the result value of times() defined by POSIX.
+ * POSIX defines it as "times() shall return the elapsed real time, in clock ticks, since an arbitrary point in the past (for example, system start-up time)".
+ * For example, GNU/Linux returns a value based on jiffies and it is monotonic.
+ * However, 4.4BSD uses gettimeofday() and it is not monotonic.
+ * (FreeBSD uses clock_gettime(CLOCK_MONOTONIC) instead, though.)
+ * The resolution is the clock tick.
+ * "getconf CLK_TCK" command shows the clock ticks per second.
+ * (The clock ticks per second is defined by HZ macro in older systems.)
+ * If it is 100 and clock_t is 32 bits integer type, the resolution is 10 millisecond and
+ * cannot represent over 497 days.
+ *
+ * Emulations for +CLOCK_PROCESS_CPUTIME_ID+:
+ * [:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID]
+ * Use getrusage() defined by SUS.
+ * getrusage() is used with RUSAGE_SELF to obtain the time only for
+ * the calling process (excluding the time for child processes).
+ * The result is addition of user time (ru_utime) and system time (ru_stime).
+ * The resolution is 1 microsecond.
+ * [:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID]
+ * Use times() defined by POSIX.
+ * The result is addition of user time (tms_utime) and system time (tms_stime).
+ * tms_cutime and tms_cstime are ignored to exclude the time for child processes.
+ * The resolution is the clock tick.
+ * "getconf CLK_TCK" command shows the clock ticks per second.
+ * (The clock ticks per second is defined by HZ macro in older systems.)
+ * If it is 100, the resolution is 10 millisecond.
+ * [:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID]
+ * Use clock() defined by ISO C.
+ * The resolution is 1/CLOCKS_PER_SEC.
+ * CLOCKS_PER_SEC is the C-level macro defined by time.h.
+ * SUS defines CLOCKS_PER_SEC is 1000000.
+ * Non-Unix systems may define it a different value, though.
+ * If CLOCKS_PER_SEC is 1000000 as SUS, the resolution is 1 microsecond.
+ * If CLOCKS_PER_SEC is 1000000 and clock_t is 32 bits integer type, it cannot represent over 72 minutes.
+ *
+ * If the given +clock_id+ is not supported, Errno::EINVAL is raised.
+ *
+ * +unit+ specifies a type of the return value.
+ *
+ * [:float_second] number of seconds as a float (default)
+ * [:float_millisecond] number of milliseconds as a float
+ * [:float_microsecond] number of microseconds as a float
+ * [:second] number of seconds as an integer
+ * [:millisecond] number of milliseconds as an integer
+ * [:microsecond] number of microseconds as an integer
+ * [:nanosecond] number of nanoseconds as an integer
*
* The underlying function, clock_gettime(), returns a number of nanoseconds.
* Float object (IEEE 754 double) is not enough to represent
- * the return value for +:CLOCK_REALTIME+.
+ * the return value for CLOCK_REALTIME.
* If the exact nanoseconds value is required, use +:nanosecond+ as the +unit+.
*
- * The origin (time zero) of the returned value is system-dependent,
- * and may be, for example, system start up time,
- * process start up time, the Epoch, etc.
+ * The origin (zero) of the returned value varies.
+ * For example, system start up time, process start up time, the Epoch, etc.
*
- * The origin in +:CLOCK_REALTIME+ is defined as the Epoch:
- * <tt>1970-01-01 00:00:00 UTC</tt>;
- * some systems count leap seconds and others don't,
- * so the result may vary across systems.
+ * The origin in CLOCK_REALTIME is defined as the Epoch
+ * (1970-01-01 00:00:00 UTC).
+ * But some systems count leap seconds and others doesn't.
+ * So the result can be interpreted differently across systems.
+ * Time.now is recommended over CLOCK_REALTIME.
*/
static VALUE
rb_clock_gettime(int argc, VALUE *argv, VALUE _)
@@ -8454,17 +8541,15 @@ rb_clock_gettime(int argc, VALUE *argv, VALUE _)
gettime:
ret = clock_gettime(c, &ts);
if (ret == -1)
- clock_failed("gettime", errno, clk_id);
+ rb_sys_fail("clock_gettime");
tt.count = (int32_t)ts.tv_nsec;
tt.giga_count = ts.tv_sec;
denominators[num_denominators++] = 1000000000;
goto success;
#endif
}
- else {
- rb_unexpected_type(clk_id, T_SYMBOL);
- }
- clock_failed("gettime", EINVAL, clk_id);
+ /* EINVAL emulates clock_gettime behavior when clock_id is invalid. */
+ rb_syserr_fail(EINVAL, 0);
success:
return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
@@ -8472,39 +8557,45 @@ rb_clock_gettime(int argc, VALUE *argv, VALUE _)
/*
* call-seq:
- * Process.clock_getres(clock_id, unit = :float_second) -> number
+ * Process.clock_getres(clock_id [, unit]) -> number
+ *
+ * Returns an estimate of the resolution of a +clock_id+ using the POSIX
+ * <code>clock_getres()</code> function.
+ *
+ * Note the reported resolution is often inaccurate on most platforms due to
+ * underlying bugs for this function and therefore the reported resolution
+ * often differs from the actual resolution of the clock in practice.
+ * Inaccurate reported resolutions have been observed for various clocks including
+ * CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW when using Linux, macOS, BSD or AIX
+ * platforms, when using ARM processors, or when using virtualization.
*
- * Returns a clock resolution as determined by POSIX function
- * {clock_getres()}[https://man7.org/linux/man-pages/man3/clock_getres.3.html]:
+ * +clock_id+ specifies a kind of clock.
+ * See the document of +Process.clock_gettime+ for details.
+ * +clock_id+ can be a symbol as for +Process.clock_gettime+.
*
- * Process.clock_getres(:CLOCK_REALTIME) # => 1.0e-09
+ * If the given +clock_id+ is not supported, Errno::EINVAL is raised.
*
- * See Process.clock_gettime for the values of +clock_id+ and +unit+.
+ * +unit+ specifies the type of the return value.
+ * +Process.clock_getres+ accepts +unit+ as +Process.clock_gettime+.
+ * The default value, +:float_second+, is also the same as
+ * +Process.clock_gettime+.
*
- * Examples:
+ * +Process.clock_getres+ also accepts +:hertz+ as +unit+.
+ * +:hertz+ means the reciprocal of +:float_second+.
*
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_microsecond) # => 0.001
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_millisecond) # => 1.0e-06
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_second) # => 1.0e-09
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :microsecond) # => 0
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :millisecond) # => 0
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :nanosecond) # => 1
- * Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :second) # => 0
+ * +:hertz+ can be used to obtain the exact value of
+ * the clock ticks per second for the times() function and
+ * CLOCKS_PER_SEC for the clock() function.
*
- * In addition to the values for +unit+ supported in Process.clock_gettime,
- * this method supports +:hertz+, the integer number of clock ticks per second
- * (which is the reciprocal of +:float_second+):
+ * <code>Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)</code>
+ * returns the clock ticks per second.
*
- * Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz) # => 100.0
- * Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :float_second) # => 0.01
+ * <code>Process.clock_getres(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)</code>
+ * returns CLOCKS_PER_SEC.
+ *
+ * p Process.clock_getres(Process::CLOCK_MONOTONIC)
+ * #=> 1.0e-09
*
- * <b>Accuracy</b>:
- * Note that the returned resolution may be inaccurate on some platforms
- * due to underlying bugs.
- * Inaccurate resolutions have been reported for various clocks including
- * +:CLOCK_MONOTONIC+ and +:CLOCK_MONOTONIC_RAW+
- * on Linux, macOS, BSD or AIX platforms, when using ARM processors,
- * or when using virtualization.
*/
static VALUE
rb_clock_getres(int argc, VALUE *argv, VALUE _)
@@ -8625,17 +8716,15 @@ rb_clock_getres(int argc, VALUE *argv, VALUE _)
getres:
ret = clock_getres(c, &ts);
if (ret == -1)
- clock_failed("getres", errno, clk_id);
+ rb_sys_fail("clock_getres");
tt.count = (int32_t)ts.tv_nsec;
tt.giga_count = ts.tv_sec;
denominators[num_denominators++] = 1000000000;
goto success;
#endif
}
- else {
- rb_unexpected_type(clk_id, T_SYMBOL);
- }
- clock_failed("getres", EINVAL, clk_id);
+ /* EINVAL emulates clock_getres behavior when clock_id is invalid. */
+ rb_syserr_fail(EINVAL, 0);
success:
if (unit == ID2SYM(id_hertz)) {
@@ -8660,82 +8749,38 @@ get_PROCESS_ID(ID _x, VALUE *_y)
/*
* call-seq:
- * Process.kill(signal, *ids) -> count
- *
- * Sends a signal to each process specified by +ids+
- * (which must specify at least one ID);
- * returns the count of signals sent.
- *
- * For each given +id+, if +id+ is:
- *
- * - Positive, sends the signal to the process whose process ID is +id+.
- * - Zero, send the signal to all processes in the current process group.
- * - Negative, sends the signal to a system-dependent collection of processes.
- *
- * Argument +signal+ specifies the signal to be sent;
- * the argument may be:
- *
- * - An integer signal number: e.g., +-29+, +0+, +29+.
- * - A signal name (string), with or without leading <tt>'SIG'</tt>,
- * and with or without a further prefixed minus sign (<tt>'-'</tt>):
- * e.g.:
- *
- * - <tt>'SIGPOLL'</tt>.
- * - <tt>'POLL'</tt>,
- * - <tt>'-SIGPOLL'</tt>.
- * - <tt>'-POLL'</tt>.
- *
- * - A signal symbol, with or without leading <tt>'SIG'</tt>,
- * and with or without a further prefixed minus sign (<tt>'-'</tt>):
- * e.g.:
- *
- * - +:SIGPOLL+.
- * - +:POLL+.
- * - <tt>:'-SIGPOLL'</tt>.
- * - <tt>:'-POLL'</tt>.
- *
- * If +signal+ is:
- *
- * - A non-negative integer, or a signal name or symbol
- * without prefixed <tt>'-'</tt>,
- * each process with process ID +id+ is signalled.
- * - A negative integer, or a signal name or symbol
- * with prefixed <tt>'-'</tt>,
- * each process group with group ID +id+ is signalled.
- *
- * Use method Signal.list to see which signals are supported
- * by Ruby on the underlying platform;
- * the method returns a hash of the string names
- * and non-negative integer values of the supported signals.
- * The size and content of the returned hash varies widely
- * among platforms.
- *
- * Additionally, signal +0+ is useful to determine if the process exists.
- *
- * Example:
- *
- * pid = fork do
- * Signal.trap('HUP') { puts 'Ouch!'; exit }
- * # ... do some work ...
- * end
- * # ...
- * Process.kill('HUP', pid)
- * Process.wait
- *
- * Output:
+ * Process.kill(signal, pid, *pids) -> integer
+ *
+ * Sends the given signal to the specified process id(s) if _pid_ is positive.
+ * If _pid_ is zero, _signal_ is sent to all processes whose group ID is equal
+ * to the group ID of the process. If _pid_ is negative, results are dependent
+ * on the operating system. _signal_ may be an integer signal number or
+ * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is
+ * negative (or starts with a minus sign), kills process groups instead of
+ * processes. Not all signals are available on all platforms.
+ * The keys and values of Signal.list are known signal names and numbers,
+ * respectively.
+ *
+ * pid = fork do
+ * Signal.trap("HUP") { puts "Ouch!"; exit }
+ * # ... do some work ...
+ * end
+ * # ...
+ * Process.kill("HUP", pid)
+ * Process.wait
+ *
+ * <em>produces:</em>
*
* Ouch!
*
- * Exceptions:
+ * If _signal_ is an integer but wrong for signal, Errno::EINVAL or
+ * RangeError will be raised. Otherwise unless _signal_ is a String
+ * or a Symbol, and a known signal name, ArgumentError will be
+ * raised.
*
- * - Raises Errno::EINVAL or RangeError if +signal+ is an integer
- * but invalid.
- * - Raises ArgumentError if +signal+ is a string or symbol
- * but invalid.
- * - Raises Errno::ESRCH or RangeError if one of +ids+ is invalid.
- * - Raises Errno::EPERM if needed permissions are not in force.
- *
- * In the last two cases, signals may have been sent to some processes.
+ * Also, Errno::ESRCH or RangeError for invalid _pid_, Errno::EPERM
+ * when failed because of no privilege, will be raised. In these
+ * cases, signals may have been sent to preceding processes.
*/
static VALUE
@@ -8749,363 +8794,10 @@ static VALUE rb_mProcUID;
static VALUE rb_mProcGID;
static VALUE rb_mProcID_Syscall;
-/*
- * call-seq:
- * Process.warmup -> true
- *
- * Notify the Ruby virtual machine that the boot sequence is finished,
- * and that now is a good time to optimize the application. This is useful
- * for long running applications.
- *
- * This method is expected to be called at the end of the application boot.
- * If the application is deployed using a pre-forking model, +Process.warmup+
- * should be called in the original process before the first fork.
- *
- * The actual optimizations performed are entirely implementation specific
- * and may change in the future without notice.
- *
- * On CRuby, +Process.warmup+:
- *
- * * Performs a major GC.
- * * Compacts the heap.
- * * Promotes all surviving objects to the old generation.
- * * Precomputes the coderange of all strings.
- * * Frees all empty heap pages and increments the allocatable pages counter
- * by the number of pages freed.
- * * Invoke +malloc_trim+ if available to free empty malloc pages.
- */
-
-static VALUE
-proc_warmup(VALUE _)
-{
- RB_VM_LOCK_ENTER();
- rb_gc_prepare_heap();
- RB_VM_LOCK_LEAVE();
- return Qtrue;
-}
/*
- * Document-module: Process
- *
- * \Module +Process+ represents a process in the underlying operating system.
- * Its methods support management of the current process and its child processes.
- *
- * == \Process Creation
- *
- * Each of the following methods executes a given command in a new process or subshell,
- * or multiple commands in new processes and/or subshells.
- * The choice of process or subshell depends on the form of the command;
- * see {Argument command_line or exe_path}[rdoc-ref:Process@Argument+command_line+or+exe_path].
- *
- * - Process.spawn, Kernel#spawn: Executes the command;
- * returns the new pid without waiting for completion.
- * - Process.exec: Replaces the current process by executing the command.
- *
- * In addition:
- *
- * - \Method Kernel#system executes a given command-line (string) in a subshell;
- * returns +true+, +false+, or +nil+.
- * - \Method Kernel#` executes a given command-line (string) in a subshell;
- * returns its $stdout string.
- * - \Module Open3 supports creating child processes
- * with access to their $stdin, $stdout, and $stderr streams.
- *
- * === Execution Environment
- *
- * Optional leading argument +env+ is a hash of name/value pairs,
- * where each name is a string and each value is a string or +nil+;
- * each name/value pair is added to ENV in the new process.
- *
- * Process.spawn( 'ruby -e "p ENV[\"Foo\"]"')
- * Process.spawn({'Foo' => '0'}, 'ruby -e "p ENV[\"Foo\"]"')
- *
- * Output:
- *
- * "0"
- *
- * The effect is usually similar to that of calling ENV#update with argument +env+,
- * where each named environment variable is created or updated
- * (if the value is non-+nil+),
- * or deleted (if the value is +nil+).
- *
- * However, some modifications to the calling process may remain
- * if the new process fails.
- * For example, hard resource limits are not restored.
- *
- * === Argument +command_line+ or +exe_path+
- *
- * The required string argument is one of the following:
- *
- * - +command_line+ if it begins with a shell reserved word or special built-in,
- * or if it contains one or more meta characters.
- * - +exe_path+ otherwise.
- *
- * <b>Argument +command_line+</b>
- *
- * \String argument +command_line+ is a command line to be passed to a shell;
- * it must begin with a shell reserved word, begin with a special built-in,
- * or contain meta characters:
- *
- * system('if true; then echo "Foo"; fi') # => true # Shell reserved word.
- * system('echo') # => true # Built-in.
- * system('date > /tmp/date.tmp') # => true # Contains meta character.
- * system('date > /nop/date.tmp') # => false
- * system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.
- *
- * The command line may also contain arguments and options for the command:
- *
- * system('echo "Foo"') # => true
- *
- * Output:
- *
- * Foo
- *
- * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell.
- *
- * <b>Argument +exe_path+</b>
- *
- * Argument +exe_path+ is one of the following:
- *
- * - The string path to an executable to be called.
- * - A 2-element array containing the path to an executable to be called,
- * and the string to be used as the name of the executing process.
- *
- * Example:
- *
- * system('/usr/bin/date') # => true # Path to date on Unix-style system.
- * system('foo') # => nil # Command failed.
- *
- * Output:
- *
- * Mon Aug 28 11:43:10 AM CDT 2023
- *
- * === Execution Options
- *
- * Optional trailing argument +options+ is a hash of execution options.
- *
- * ==== Working Directory (+:chdir+)
- *
- * By default, the working directory for the new process is the same as
- * that of the current process:
- *
- * Dir.chdir('/var')
- * Process.spawn('ruby -e "puts Dir.pwd"')
- *
- * Output:
- *
- * /var
- *
- * Use option +:chdir+ to set the working directory for the new process:
- *
- * Process.spawn('ruby -e "puts Dir.pwd"', {chdir: '/tmp'})
- *
- * Output:
- *
- * /tmp
- *
- * The working directory of the current process is not changed:
- *
- * Dir.pwd # => "/var"
- *
- * ==== \File Redirection (\File Descriptor)
- *
- * Use execution options for file redirection in the new process.
- *
- * The key for such an option may be an integer file descriptor (fd),
- * specifying a source,
- * or an array of fds, specifying multiple sources.
- *
- * An integer source fd may be specified as:
- *
- * - _n_: Specifies file descriptor _n_.
- *
- * There are these shorthand symbols for fds:
- *
- * - +:in+: Specifies file descriptor 0 (STDIN).
- * - +:out+: Specifies file descriptor 1 (STDOUT).
- * - +:err+: Specifies file descriptor 2 (STDERR).
- *
- * The value given with a source is one of:
- *
- * - _n_:
- * Redirects to fd _n_ in the parent process.
- * - +filepath+:
- * Redirects from or to the file at +filepath+ via <tt>open(filepath, mode, 0644)</tt>,
- * where +mode+ is <tt>'r'</tt> for source +:in+,
- * or <tt>'w'</tt> for source +:out+ or +:err+.
- * - <tt>[filepath]</tt>:
- * Redirects from the file at +filepath+ via <tt>open(filepath, 'r', 0644)</tt>.
- * - <tt>[filepath, mode]</tt>:
- * Redirects from or to the file at +filepath+ via <tt>open(filepath, mode, 0644)</tt>.
- * - <tt>[filepath, mode, perm]</tt>:
- * Redirects from or to the file at +filepath+ via <tt>open(filepath, mode, perm)</tt>.
- * - <tt>[:child, fd]</tt>:
- * Redirects to the redirected +fd+.
- * - +:close+: Closes the file descriptor in child process.
- *
- * See {Access Modes}[rdoc-ref:File@Access+Modes]
- * and {File Permissions}[rdoc-ref:File@File+Permissions].
- *
- * ==== Environment Variables (+:unsetenv_others+)
- *
- * By default, the new process inherits environment variables
- * from the parent process;
- * use execution option key +:unsetenv_others+ with value +true+
- * to clear environment variables in the new process.
- *
- * Any changes specified by execution option +env+ are made after the new process
- * inherits or clears its environment variables;
- * see {Execution Environment}[rdoc-ref:Process@Execution+Environment].
- *
- * ==== \File-Creation Access (+:umask+)
- *
- * Use execution option +:umask+ to set the file-creation access
- * for the new process;
- * see {Access Modes}[rdoc-ref:File@Access+Modes]:
- *
- * command = 'ruby -e "puts sprintf(\"0%o\", File.umask)"'
- * options = {:umask => 0644}
- * Process.spawn(command, options)
- *
- * Output:
- *
- * 0644
- *
- * ==== \Process Groups (+:pgroup+ and +:new_pgroup+)
- *
- * By default, the new process belongs to the same
- * {process group}[https://en.wikipedia.org/wiki/Process_group]
- * as the parent process.
- *
- * To specify a different process group.
- * use execution option +:pgroup+ with one of the following values:
- *
- * - +true+: Create a new process group for the new process.
- * - _pgid_: Create the new process in the process group
- * whose id is _pgid_.
- *
- * On Windows only, use execution option +:new_pgroup+ with value +true+
- * to create a new process group for the new process.
- *
- * ==== Resource Limits
- *
- * Use execution options to set resource limits.
- *
- * The keys for these options are symbols of the form
- * <tt>:rlimit_<i>resource_name</i></tt>,
- * where _resource_name_ is the downcased form of one of the string
- * resource names described at method Process.setrlimit.
- * For example, key +:rlimit_cpu+ corresponds to resource limit <tt>'CPU'</tt>.
- *
- * The value for such as key is one of:
- *
- * - An integer, specifying both the current and maximum limits.
- * - A 2-element array of integers, specifying the current and maximum limits.
- *
- * ==== \File Descriptor Inheritance
- *
- * By default, the new process inherits file descriptors from the parent process.
- *
- * Use execution option <tt>:close_others => true</tt> to modify that inheritance
- * by closing non-standard fds (3 and greater) that are not otherwise redirected.
- *
- * === Execution Shell
- *
- * On a Unix-like system, the shell invoked is <tt>/bin/sh</tt>;
- * otherwise the shell invoked is determined by environment variable
- * <tt>ENV['RUBYSHELL']</tt>, if defined, or <tt>ENV['COMSPEC']</tt> otherwise.
- *
- * Except for the +COMSPEC+ case,
- * the entire string +command_line+ is passed as an argument
- * to {shell option -c}[https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/sh.html].
- *
- * The shell performs normal shell expansion on the command line:
- *
- * spawn('echo C*') # => 799139
- * Process.wait # => 799139
- *
- * Output:
- *
- * CONTRIBUTING.md COPYING COPYING.ja
- *
- * == What's Here
- *
- * === Current-Process Getters
- *
- * - ::argv0: Returns the process name as a frozen string.
- * - ::egid: Returns the effective group ID.
- * - ::euid: Returns the effective user ID.
- * - ::getpgrp: Return the process group ID.
- * - ::getrlimit: Returns the resource limit.
- * - ::gid: Returns the (real) group ID.
- * - ::pid: Returns the process ID.
- * - ::ppid: Returns the process ID of the parent process.
- * - ::uid: Returns the (real) user ID.
- *
- * === Current-Process Setters
- *
- * - ::egid=: Sets the effective group ID.
- * - ::euid=: Sets the effective user ID.
- * - ::gid=: Sets the (real) group ID.
- * - ::setproctitle: Sets the process title.
- * - ::setpgrp: Sets the process group ID of the process to zero.
- * - ::setrlimit: Sets a resource limit.
- * - ::setsid: Establishes the process as a new session and process group leader,
- * with no controlling tty.
- * - ::uid=: Sets the user ID.
- *
- * === Current-Process Execution
- *
- * - ::abort: Immediately terminates the process.
- * - ::daemon: Detaches the process from its controlling terminal
- * and continues running it in the background as system daemon.
- * - ::exec: Replaces the process by running a given external command.
- * - ::exit: Initiates process termination by raising exception SystemExit
- * (which may be caught).
- * - ::exit!: Immediately exits the process.
- * - ::warmup: Notifies the Ruby virtual machine that the boot sequence
- * for the application is completed,
- * and that the VM may begin optimizing the application.
- *
- * === Child Processes
- *
- * - ::detach: Guards against a child process becoming a zombie.
- * - ::fork: Creates a child process.
- * - ::kill: Sends a given signal to processes.
- * - ::spawn: Creates a child process.
- * - ::wait, ::waitpid: Waits for a child process to exit; returns its process ID.
- * - ::wait2, ::waitpid2: Waits for a child process to exit; returns its process ID and status.
- * - ::waitall: Waits for all child processes to exit;
- * returns their process IDs and statuses.
- *
- * === \Process Groups
- *
- * - ::getpgid: Returns the process group ID for a process.
- * - ::getpriority: Returns the scheduling priority
- * for a process, process group, or user.
- * - ::getsid: Returns the session ID for a process.
- * - ::groups: Returns an array of the group IDs
- * in the supplemental group access list for this process.
- * - ::groups=: Sets the supplemental group access list
- * to the given array of group IDs.
- * - ::initgroups: Initializes the supplemental group access list.
- * - ::last_status: Returns the status of the last executed child process
- * in the current thread.
- * - ::maxgroups: Returns the maximum number of group IDs allowed
- * in the supplemental group access list.
- * - ::maxgroups=: Sets the maximum number of group IDs allowed
- * in the supplemental group access list.
- * - ::setpgid: Sets the process group ID of a process.
- * - ::setpriority: Sets the scheduling priority
- * for a process, process group, or user.
- *
- * === Timing
- *
- * - ::clock_getres: Returns the resolution of a system clock.
- * - ::clock_gettime: Returns the time from a system clock.
- * - ::times: Returns a Process::Tms object containing times
- * for the current process and its child processes.
- *
+ * The Process module is a collection of methods used to
+ * manipulate processes.
*/
void
@@ -9206,8 +8898,6 @@ InitVM_process(void)
rb_define_module_function(rb_mProcess, "getpriority", proc_getpriority, 2);
rb_define_module_function(rb_mProcess, "setpriority", proc_setpriority, 3);
- rb_define_module_function(rb_mProcess, "warmup", proc_warmup, 0);
-
#ifdef HAVE_GETPRIORITY
/* see Process.setpriority */
rb_define_const(rb_mProcess, "PRIO_PROCESS", INT2FIX(PRIO_PROCESS));
diff --git a/ractor.c b/ractor.c
index 5bf84c7c83..8fb563fa11 100644
--- a/ractor.c
+++ b/ractor.c
@@ -5,22 +5,21 @@
#include "ruby/ractor.h"
#include "ruby/thread_native.h"
#include "vm_core.h"
-#include "eval_intern.h"
#include "vm_sync.h"
#include "ractor_core.h"
#include "internal/complex.h"
#include "internal/error.h"
-#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/rational.h"
#include "internal/struct.h"
#include "internal/thread.h"
#include "variable.h"
+#include "gc.h"
+#include "transient_heap.h"
#include "yjit.h"
-#include "rjit.h"
+#include "mjit.h"
VALUE rb_cRactor;
-static VALUE rb_cRactorSelector;
VALUE rb_eRactorUnsafeError;
VALUE rb_eRactorIsolationError;
@@ -32,13 +31,11 @@ static VALUE rb_cRactorMovedObject;
static void vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *r, const char *file, int line);
-// Ractor locking
-
static void
ASSERT_ractor_unlocking(rb_ractor_t *r)
{
#if RACTOR_CHECK_MODE > 0
- // GET_EC is NULL in an RJIT worker
+ // GET_EC is NULL in an MJIT worker
if (rb_current_execution_context(false) != NULL && r->sync.locked_by == rb_ractor_self(GET_RACTOR())) {
rb_bug("recursive ractor locking");
}
@@ -49,7 +46,7 @@ static void
ASSERT_ractor_locking(rb_ractor_t *r)
{
#if RACTOR_CHECK_MODE > 0
- // GET_EC is NULL in an RJIT worker
+ // GET_EC is NULL in an MJIT worker
if (rb_current_execution_context(false) != NULL && r->sync.locked_by != rb_ractor_self(GET_RACTOR())) {
rp(r->sync.locked_by);
rb_bug("ractor lock is not acquired.");
@@ -60,19 +57,18 @@ ASSERT_ractor_locking(rb_ractor_t *r)
static void
ractor_lock(rb_ractor_t *r, const char *file, int line)
{
- RUBY_DEBUG_LOG2(file, line, "locking r:%u%s", r->pub.id, rb_current_ractor_raw(false) == r ? " (self)" : "");
+ RUBY_DEBUG_LOG2(file, line, "locking r:%u%s", r->pub.id, GET_RACTOR() == r ? " (self)" : "");
ASSERT_ractor_unlocking(r);
rb_native_mutex_lock(&r->sync.lock);
#if RACTOR_CHECK_MODE > 0
- if (rb_current_execution_context(false) != NULL) { // GET_EC is NULL in an RJIT worker
- rb_ractor_t *cr = rb_current_ractor_raw(false);
- r->sync.locked_by = cr ? rb_ractor_self(cr) : Qundef;
+ if (rb_current_execution_context(false) != NULL) { // GET_EC is NULL in an MJIT worker
+ r->sync.locked_by = rb_ractor_self(GET_RACTOR());
}
#endif
- RUBY_DEBUG_LOG2(file, line, "locked r:%u%s", r->pub.id, rb_current_ractor_raw(false) == r ? " (self)" : "");
+ RUBY_DEBUG_LOG2(file, line, "locked r:%u%s", r->pub.id, GET_RACTOR() == r ? " (self)" : "");
}
static void
@@ -94,7 +90,7 @@ ractor_unlock(rb_ractor_t *r, const char *file, int line)
#endif
rb_native_mutex_unlock(&r->sync.lock);
- RUBY_DEBUG_LOG2(file, line, "r:%u%s", r->pub.id, rb_current_ractor_raw(false) == r ? " (self)" : "");
+ RUBY_DEBUG_LOG2(file, line, "r:%u%s", r->pub.id, GET_RACTOR() == r ? " (self)" : "");
}
static void
@@ -112,20 +108,20 @@ ractor_unlock_self(rb_ractor_t *cr, const char *file, int line)
#define RACTOR_LOCK_SELF(r) ractor_lock_self(r, __FILE__, __LINE__)
#define RACTOR_UNLOCK_SELF(r) ractor_unlock_self(r, __FILE__, __LINE__)
-void
-rb_ractor_lock_self(rb_ractor_t *r)
+static void
+ractor_cond_wait(rb_ractor_t *r)
{
- RACTOR_LOCK_SELF(r);
-}
+#if RACTOR_CHECK_MODE > 0
+ VALUE locked_by = r->sync.locked_by;
+ r->sync.locked_by = Qnil;
+#endif
+ rb_native_cond_wait(&r->sync.cond, &r->sync.lock);
-void
-rb_ractor_unlock_self(rb_ractor_t *r)
-{
- RACTOR_UNLOCK_SELF(r);
+#if RACTOR_CHECK_MODE > 0
+ r->sync.locked_by = locked_by;
+#endif
}
-// Ractor status
-
static const char *
ractor_status_str(enum ractor_status status)
{
@@ -162,7 +158,7 @@ ractor_status_set(rb_ractor_t *r, enum ractor_status status)
VM_ASSERT(status == ractor_running);
break;
case ractor_terminated:
- rb_bug("unreachable");
+ VM_ASSERT(0); // unreachable
break;
}
@@ -175,40 +171,31 @@ ractor_status_p(rb_ractor_t *r, enum ractor_status status)
return rb_ractor_status_p(r, status);
}
-// Ractor data/mark/free
-
-static struct rb_ractor_basket *ractor_queue_at(rb_ractor_t *r, struct rb_ractor_queue *rq, int i);
-static void ractor_local_storage_mark(rb_ractor_t *r);
-static void ractor_local_storage_free(rb_ractor_t *r);
+static struct rb_ractor_basket *ractor_queue_at(struct rb_ractor_queue *rq, int i);
static void
ractor_queue_mark(struct rb_ractor_queue *rq)
{
for (int i=0; i<rq->cnt; i++) {
- struct rb_ractor_basket *b = ractor_queue_at(NULL, rq, i);
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ rb_gc_mark(b->v);
rb_gc_mark(b->sender);
-
- switch (b->type.e) {
- case basket_type_yielding:
- case basket_type_take_basket:
- case basket_type_deleted:
- case basket_type_reserved:
- // ignore
- break;
- default:
- rb_gc_mark(b->p.send.v);
- }
}
}
+static void ractor_local_storage_mark(rb_ractor_t *r);
+static void ractor_local_storage_free(rb_ractor_t *r);
+
static void
ractor_mark(void *ptr)
{
rb_ractor_t *r = (rb_ractor_t *)ptr;
- ractor_queue_mark(&r->sync.recv_queue);
- ractor_queue_mark(&r->sync.takers_queue);
-
+ ractor_queue_mark(&r->sync.incoming_queue);
+ rb_gc_mark(r->sync.wait.taken_basket.v);
+ rb_gc_mark(r->sync.wait.taken_basket.sender);
+ rb_gc_mark(r->sync.wait.yielded_basket.v);
+ rb_gc_mark(r->sync.wait.yielded_basket.sender);
rb_gc_mark(r->receiving_mutex);
rb_gc_mark(r->loc);
@@ -236,16 +223,19 @@ ractor_queue_free(struct rb_ractor_queue *rq)
}
static void
+ractor_waiting_list_free(struct rb_ractor_waiting_list *wl)
+{
+ free(wl->ractors);
+}
+
+static void
ractor_free(void *ptr)
{
rb_ractor_t *r = (rb_ractor_t *)ptr;
- RUBY_DEBUG_LOG("free r:%d", rb_ractor_id(r));
rb_native_mutex_destroy(&r->sync.lock);
-#ifdef RUBY_THREAD_WIN32_H
rb_native_cond_destroy(&r->sync.cond);
-#endif
- ractor_queue_free(&r->sync.recv_queue);
- ractor_queue_free(&r->sync.takers_queue);
+ ractor_queue_free(&r->sync.incoming_queue);
+ ractor_waiting_list_free(&r->sync.taking_ractors);
ractor_local_storage_free(r);
rb_hook_list_free(&r->pub.hooks);
ruby_xfree(r);
@@ -258,14 +248,20 @@ ractor_queue_memsize(const struct rb_ractor_queue *rq)
}
static size_t
+ractor_waiting_list_memsize(const struct rb_ractor_waiting_list *wl)
+{
+ return sizeof(rb_ractor_t *) * wl->size;
+}
+
+static size_t
ractor_memsize(const void *ptr)
{
rb_ractor_t *r = (rb_ractor_t *)ptr;
- // TODO: more correct?
+ // TODO
return sizeof(rb_ractor_t) +
- ractor_queue_memsize(&r->sync.recv_queue) +
- ractor_queue_memsize(&r->sync.takers_queue);
+ ractor_queue_memsize(&r->sync.incoming_queue) +
+ ractor_waiting_list_memsize(&r->sync.taking_ractors);
}
static const rb_data_type_t ractor_data_type = {
@@ -294,14 +290,16 @@ static inline rb_ractor_t *
RACTOR_PTR(VALUE self)
{
VM_ASSERT(rb_ractor_p(self));
+
rb_ractor_t *r = DATA_PTR(self);
+ // TODO: check
return r;
}
static rb_atomic_t ractor_last_id;
#if RACTOR_CHECK_MODE > 0
-uint32_t
+MJIT_FUNC_EXPORTED uint32_t
rb_ractor_current_id(void)
{
if (GET_THREAD()->ractor == NULL) {
@@ -313,8 +311,6 @@ rb_ractor_current_id(void)
}
#endif
-// Ractor queue
-
static void
ractor_queue_setup(struct rb_ractor_queue *rq)
{
@@ -325,23 +321,15 @@ ractor_queue_setup(struct rb_ractor_queue *rq)
}
static struct rb_ractor_basket *
-ractor_queue_head(rb_ractor_t *r, struct rb_ractor_queue *rq)
-{
- if (r != NULL) ASSERT_ractor_locking(r);
- return &rq->baskets[rq->start];
-}
-
-static struct rb_ractor_basket *
-ractor_queue_at(rb_ractor_t *r, struct rb_ractor_queue *rq, int i)
+ractor_queue_at(struct rb_ractor_queue *rq, int i)
{
- if (r != NULL) ASSERT_ractor_locking(r);
return &rq->baskets[(rq->start + i) % rq->size];
}
static void
-ractor_queue_advance(rb_ractor_t *r, struct rb_ractor_queue *rq)
+ractor_queue_advance(struct rb_ractor_queue *rq)
{
- ASSERT_ractor_locking(r);
+ ASSERT_ractor_locking(GET_RACTOR());
if (rq->reserved_cnt == 0) {
rq->cnt--;
@@ -349,16 +337,16 @@ ractor_queue_advance(rb_ractor_t *r, struct rb_ractor_queue *rq)
rq->serial++;
}
else {
- ractor_queue_at(r, rq, 0)->type.e = basket_type_deleted;
+ ractor_queue_at(rq, 0)->type = basket_type_deleted;
}
}
static bool
-ractor_queue_skip_p(rb_ractor_t *r, struct rb_ractor_queue *rq, int i)
+ractor_queue_skip_p(struct rb_ractor_queue *rq, int i)
{
- struct rb_ractor_basket *b = ractor_queue_at(r, rq, i);
- return basket_type_p(b, basket_type_deleted) ||
- basket_type_p(b, basket_type_reserved);
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ return b->type == basket_type_deleted ||
+ b->type == basket_type_reserved;
}
static void
@@ -366,8 +354,8 @@ ractor_queue_compact(rb_ractor_t *r, struct rb_ractor_queue *rq)
{
ASSERT_ractor_locking(r);
- while (rq->cnt > 0 && basket_type_p(ractor_queue_at(r, rq, 0), basket_type_deleted)) {
- ractor_queue_advance(r, rq);
+ while (rq->cnt > 0 && ractor_queue_at(rq, 0)->type == basket_type_deleted) {
+ ractor_queue_advance(rq);
}
}
@@ -383,7 +371,7 @@ ractor_queue_empty_p(rb_ractor_t *r, struct rb_ractor_queue *rq)
ractor_queue_compact(r, rq);
for (int i=0; i<rq->cnt; i++) {
- if (!ractor_queue_skip_p(r, rq, i)) {
+ if (!ractor_queue_skip_p(rq, i)) {
return false;
}
}
@@ -394,21 +382,28 @@ ractor_queue_empty_p(rb_ractor_t *r, struct rb_ractor_queue *rq)
static bool
ractor_queue_deq(rb_ractor_t *r, struct rb_ractor_queue *rq, struct rb_ractor_basket *basket)
{
- ASSERT_ractor_locking(r);
-
- for (int i=0; i<rq->cnt; i++) {
- if (!ractor_queue_skip_p(r, rq, i)) {
- struct rb_ractor_basket *b = ractor_queue_at(r, rq, i);
- *basket = *b;
+ bool found = false;
- // remove from queue
- b->type.e = basket_type_deleted;
- ractor_queue_compact(r, rq);
- return true;
+ RACTOR_LOCK(r);
+ {
+ if (!ractor_queue_empty_p(r, rq)) {
+ for (int i=0; i<rq->cnt; i++) {
+ if (!ractor_queue_skip_p(rq, i)) {
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
+ *basket = *b;
+
+ // remove from queue
+ b->type = basket_type_deleted;
+ ractor_queue_compact(r, rq);
+ found = true;
+ break;
+ }
+ }
}
}
+ RACTOR_UNLOCK(r);
- return false;
+ return found;
}
static void
@@ -428,32 +423,32 @@ ractor_queue_enq(rb_ractor_t *r, struct rb_ractor_queue *rq, struct rb_ractor_ba
}
static void
-ractor_queue_delete(rb_ractor_t *r, struct rb_ractor_queue *rq, struct rb_ractor_basket *basket)
+ractor_basket_clear(struct rb_ractor_basket *b)
{
- basket->type.e = basket_type_deleted;
+ b->type = basket_type_none;
+ b->v = Qfalse;
+ b->sender = Qfalse;
}
-// Ractor basket
-
static VALUE ractor_reset_belonging(VALUE obj); // in this file
static VALUE
ractor_basket_value(struct rb_ractor_basket *b)
{
- switch (b->type.e) {
+ switch (b->type) {
case basket_type_ref:
break;
case basket_type_copy:
case basket_type_move:
case basket_type_will:
- b->type.e = basket_type_ref;
- b->p.send.v = ractor_reset_belonging(b->p.send.v);
+ b->type = basket_type_ref;
+ b->v = ractor_reset_belonging(b->v);
break;
default:
rb_bug("unreachable");
}
- return b->p.send.v;
+ return b->v;
}
static VALUE
@@ -461,69 +456,46 @@ ractor_basket_accept(struct rb_ractor_basket *b)
{
VALUE v = ractor_basket_value(b);
- if (b->p.send.exception) {
+ if (b->exception) {
VALUE cause = v;
VALUE err = rb_exc_new_cstr(rb_eRactorRemoteError, "thrown by remote Ractor.");
rb_ivar_set(err, rb_intern("@ractor"), b->sender);
+ ractor_basket_clear(b);
rb_ec_setup_exception(NULL, err, cause);
rb_exc_raise(err);
}
+ ractor_basket_clear(b);
return v;
}
-// Ractor synchronizations
-
-#if USE_RUBY_DEBUG_LOG
-static const char *
-wait_status_str(enum rb_ractor_wait_status wait_status)
+static void
+ractor_recursive_receive_if(rb_ractor_t *r)
{
- switch ((int)wait_status) {
- case wait_none: return "none";
- case wait_receiving: return "receiving";
- case wait_taking: return "taking";
- case wait_yielding: return "yielding";
- case wait_receiving|wait_taking: return "receiving|taking";
- case wait_receiving|wait_yielding: return "receiving|yielding";
- case wait_taking|wait_yielding: return "taking|yielding";
- case wait_receiving|wait_taking|wait_yielding: return "receiving|taking|yielding";
+ if (r->receiving_mutex && rb_mutex_owned_p(r->receiving_mutex)) {
+ rb_raise(rb_eRactorError, "can not call receive/receive_if recursively");
}
- rb_bug("unreachable");
}
-static const char *
-wakeup_status_str(enum rb_ractor_wakeup_status wakeup_status)
+static VALUE
+ractor_try_receive(rb_execution_context_t *ec, rb_ractor_t *r)
{
- switch (wakeup_status) {
- case wakeup_none: return "none";
- case wakeup_by_send: return "by_send";
- case wakeup_by_yield: return "by_yield";
- case wakeup_by_take: return "by_take";
- case wakeup_by_close: return "by_close";
- case wakeup_by_interrupt: return "by_interrupt";
- case wakeup_by_retry: return "by_retry";
+ struct rb_ractor_queue *rq = &r->sync.incoming_queue;
+ struct rb_ractor_basket basket;
+
+ ractor_recursive_receive_if(r);
+
+ if (ractor_queue_deq(r, rq, &basket) == false) {
+ if (r->sync.incoming_port_closed) {
+ rb_raise(rb_eRactorClosedError, "The incoming port is already closed");
+ }
+ else {
+ return Qundef;
+ }
}
- rb_bug("unreachable");
-}
-static const char *
-basket_type_name(enum rb_ractor_basket_type type)
-{
- switch (type) {
- case basket_type_none: return "none";
- case basket_type_ref: return "ref";
- case basket_type_copy: return "copy";
- case basket_type_move: return "move";
- case basket_type_will: return "will";
- case basket_type_deleted: return "deleted";
- case basket_type_reserved: return "reserved";
- case basket_type_take_basket: return "take_basket";
- case basket_type_yielding: return "yielding";
- }
- VM_ASSERT(0);
- return NULL;
+ return ractor_basket_accept(&basket);
}
-#endif // USE_RUBY_DEBUG_LOG
static bool
ractor_sleeping_by(const rb_ractor_t *r, enum rb_ractor_wait_status wait_status)
@@ -531,33 +503,18 @@ ractor_sleeping_by(const rb_ractor_t *r, enum rb_ractor_wait_status wait_status)
return (r->sync.wait.status & wait_status) && r->sync.wait.wakeup_status == wakeup_none;
}
-#ifdef RUBY_THREAD_PTHREAD_H
-// thread_*.c
-void rb_ractor_sched_wakeup(rb_ractor_t *r);
-#else
-
-static void
-rb_ractor_sched_wakeup(rb_ractor_t *r)
-{
- rb_native_cond_broadcast(&r->sync.cond);
-}
-#endif
-
-
static bool
ractor_wakeup(rb_ractor_t *r, enum rb_ractor_wait_status wait_status, enum rb_ractor_wakeup_status wakeup_status)
{
ASSERT_ractor_locking(r);
- RUBY_DEBUG_LOG("r:%u wait_by:%s -> wait:%s wakeup:%s",
- rb_ractor_id(r),
- wait_status_str(r->sync.wait.status),
- wait_status_str(wait_status),
- wakeup_status_str(wakeup_status));
+ // fprintf(stderr, "%s r:%p status:%s/%s wakeup_status:%s/%s\n", RUBY_FUNCTION_NAME_STRING, (void *)r,
+ // wait_status_str(r->sync.wait.status), wait_status_str(wait_status),
+ // wakeup_status_str(r->sync.wait.wakeup_status), wakeup_status_str(wakeup_status));
if (ractor_sleeping_by(r, wait_status)) {
r->sync.wait.wakeup_status = wakeup_status;
- rb_ractor_sched_wakeup(r);
+ rb_native_cond_signal(&r->sync.cond);
return true;
}
else {
@@ -565,6 +522,22 @@ ractor_wakeup(rb_ractor_t *r, enum rb_ractor_wait_status wait_status, enum rb_ra
}
}
+static void *
+ractor_sleep_wo_gvl(void *ptr)
+{
+ rb_ractor_t *cr = ptr;
+ RACTOR_LOCK_SELF(cr);
+ {
+ VM_ASSERT(cr->sync.wait.status != wait_none);
+ if (cr->sync.wait.wakeup_status == wakeup_none) {
+ ractor_cond_wait(cr);
+ }
+ cr->sync.wait.status = wait_none;
+ }
+ RACTOR_UNLOCK_SELF(cr);
+ return NULL;
+}
+
static void
ractor_sleep_interrupt(void *ptr)
{
@@ -577,175 +550,174 @@ ractor_sleep_interrupt(void *ptr)
RACTOR_UNLOCK(r);
}
-typedef void (*ractor_sleep_cleanup_function)(rb_ractor_t *cr, void *p);
-
-static void
-ractor_check_ints(rb_execution_context_t *ec, rb_ractor_t *cr, ractor_sleep_cleanup_function cf_func, void *cf_data)
+#if USE_RUBY_DEBUG_LOG
+static const char *
+wait_status_str(enum rb_ractor_wait_status wait_status)
{
- if (cr->sync.wait.status != wait_none) {
- enum rb_ractor_wait_status prev_wait_status = cr->sync.wait.status;
- cr->sync.wait.status = wait_none;
- cr->sync.wait.wakeup_status = wakeup_by_interrupt;
-
- RACTOR_UNLOCK(cr);
- {
- if (cf_func) {
- int state;
- EC_PUSH_TAG(ec);
- if ((state = EC_EXEC_TAG()) == TAG_NONE) {
- rb_thread_check_ints();
- }
- EC_POP_TAG();
-
- if (state) {
- (*cf_func)(cr, cf_data);
- EC_JUMP_TAG(ec, state);
- }
- }
- else {
- rb_thread_check_ints();
- }
- }
-
- // reachable?
- RACTOR_LOCK(cr);
- cr->sync.wait.status = prev_wait_status;
+ switch ((int)wait_status) {
+ case wait_none: return "none";
+ case wait_receiving: return "receiving";
+ case wait_taking: return "taking";
+ case wait_yielding: return "yielding";
+ case wait_receiving|wait_taking: return "receiving|taking";
+ case wait_receiving|wait_yielding: return "receiving|yielding";
+ case wait_taking|wait_yielding: return "taking|yielding";
+ case wait_receiving|wait_taking|wait_yielding: return "receiving|taking|yielding";
}
+ rb_bug("unreachable");
}
-#ifdef RUBY_THREAD_PTHREAD_H
-void rb_ractor_sched_sleep(rb_execution_context_t *ec, rb_ractor_t *cr, rb_unblock_function_t *ubf);
-#else
-
-// win32
-static void
-ractor_cond_wait(rb_ractor_t *r)
-{
-#if RACTOR_CHECK_MODE > 0
- VALUE locked_by = r->sync.locked_by;
- r->sync.locked_by = Qnil;
-#endif
- rb_native_cond_wait(&r->sync.cond, &r->sync.lock);
-
-#if RACTOR_CHECK_MODE > 0
- r->sync.locked_by = locked_by;
-#endif
-}
-
-static void *
-ractor_sleep_wo_gvl(void *ptr)
+static const char *
+wakeup_status_str(enum rb_ractor_wakeup_status wakeup_status)
{
- rb_ractor_t *cr = ptr;
- RACTOR_LOCK_SELF(cr);
- {
- VM_ASSERT(cr->sync.wait.status != wait_none);
- if (cr->sync.wait.wakeup_status == wakeup_none) {
- ractor_cond_wait(cr);
- }
- cr->sync.wait.status = wait_none;
+ switch (wakeup_status) {
+ case wakeup_none: return "none";
+ case wakeup_by_send: return "by_send";
+ case wakeup_by_yield: return "by_yield";
+ case wakeup_by_take: return "by_take";
+ case wakeup_by_close: return "by_close";
+ case wakeup_by_interrupt: return "by_interrupt";
+ case wakeup_by_retry: return "by_retry";
}
- RACTOR_UNLOCK_SELF(cr);
- return NULL;
+ rb_bug("unreachable");
}
+#endif // USE_RUBY_DEBUG_LOG
static void
-rb_ractor_sched_sleep(rb_execution_context_t *ec, rb_ractor_t *cr, rb_unblock_function_t *ubf)
+ractor_sleep(rb_execution_context_t *ec, rb_ractor_t *cr)
{
+ VM_ASSERT(GET_RACTOR() == cr);
+ VM_ASSERT(cr->sync.wait.status != wait_none);
+ // fprintf(stderr, "%s r:%p status:%s, wakeup_status:%s\n", RUBY_FUNCTION_NAME_STRING, (void *)cr,
+ // wait_status_str(cr->sync.wait.status), wakeup_status_str(cr->sync.wait.wakeup_status));
+
RACTOR_UNLOCK(cr);
{
rb_nogvl(ractor_sleep_wo_gvl, cr,
- ubf, cr,
+ ractor_sleep_interrupt, cr,
RB_NOGVL_UBF_ASYNC_SAFE | RB_NOGVL_INTR_FAIL);
}
RACTOR_LOCK(cr);
-}
-#endif
-
-static enum rb_ractor_wakeup_status
-ractor_sleep_with_cleanup(rb_execution_context_t *ec, rb_ractor_t *cr, enum rb_ractor_wait_status wait_status,
- ractor_sleep_cleanup_function cf_func, void *cf_data)
-{
- enum rb_ractor_wakeup_status wakeup_status;
- VM_ASSERT(GET_RACTOR() == cr);
-
- // TODO: multi-threads
- VM_ASSERT(cr->sync.wait.status == wait_none);
- VM_ASSERT(wait_status != wait_none);
- cr->sync.wait.status = wait_status;
- cr->sync.wait.wakeup_status = wakeup_none;
-
- // fprintf(stderr, "%s r:%p status:%s, wakeup_status:%s\n", RUBY_FUNCTION_NAME_STRING, (void *)cr,
- // wait_status_str(cr->sync.wait.status), wakeup_status_str(cr->sync.wait.wakeup_status));
- RUBY_DEBUG_LOG("sleep by %s", wait_status_str(wait_status));
+ // rb_nogvl() can be canceled by interrupts
+ if (cr->sync.wait.status != wait_none) {
+ cr->sync.wait.status = wait_none;
+ cr->sync.wait.wakeup_status = wakeup_by_interrupt;
- while (cr->sync.wait.wakeup_status == wakeup_none) {
- rb_ractor_sched_sleep(ec, cr, ractor_sleep_interrupt);
- ractor_check_ints(ec, cr, cf_func, cf_data);
+ RACTOR_UNLOCK(cr);
+ rb_thread_check_ints();
+ RACTOR_LOCK(cr); // reachable?
}
+}
- cr->sync.wait.status = wait_none;
+static void
+ractor_register_taking(rb_ractor_t *r, rb_ractor_t *cr)
+{
+ VM_ASSERT(cr == GET_RACTOR());
+ bool retry_try = false;
- // TODO: multi-thread
- wakeup_status = cr->sync.wait.wakeup_status;
- cr->sync.wait.wakeup_status = wakeup_none;
+ RACTOR_LOCK(r);
+ {
+ if (ractor_sleeping_by(r, wait_yielding)) {
+ // already waiting for yielding. retry try_take.
+ retry_try = true;
+ }
+ else {
+ // insert cr into taking list
+ struct rb_ractor_waiting_list *wl = &r->sync.taking_ractors;
+
+ for (int i=0; i<wl->cnt; i++) {
+ if (wl->ractors[i] == cr) {
+ // TODO: make it clean code.
+ rb_native_mutex_unlock(&r->sync.lock);
+ rb_raise(rb_eRuntimeError, "Already another thread of same ractor is waiting.");
+ }
+ }
- RUBY_DEBUG_LOG("wakeup %s", wakeup_status_str(wakeup_status));
+ if (wl->size == 0) {
+ wl->size = 1;
+ wl->ractors = malloc(sizeof(rb_ractor_t *) * wl->size);
+ if (wl->ractors == NULL) rb_bug("can't allocate buffer");
+ }
+ else if (wl->size <= wl->cnt + 1) {
+ wl->size *= 2;
+ wl->ractors = realloc(wl->ractors, sizeof(rb_ractor_t *) * wl->size);
+ if (wl->ractors == NULL) rb_bug("can't re-allocate buffer");
+ }
+ wl->ractors[wl->cnt++] = cr;
+ }
+ }
+ RACTOR_UNLOCK(r);
- return wakeup_status;
-}
+ if (retry_try) {
+ RACTOR_LOCK(cr);
+ {
+ if (cr->sync.wait.wakeup_status == wakeup_none) {
+ VM_ASSERT(cr->sync.wait.status != wait_none);
-static enum rb_ractor_wakeup_status
-ractor_sleep(rb_execution_context_t *ec, rb_ractor_t *cr, enum rb_ractor_wait_status wait_status)
-{
- return ractor_sleep_with_cleanup(ec, cr, wait_status, 0, NULL);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ cr->sync.wait.status = wait_none;
+ }
+ }
+ RACTOR_UNLOCK(cr);
+ }
}
-// Ractor.receive
-
static void
-ractor_recursive_receive_if(rb_ractor_t *r)
+ractor_waiting_list_del(rb_ractor_t *r, struct rb_ractor_waiting_list *wl, rb_ractor_t *wr)
{
- if (r->receiving_mutex && rb_mutex_owned_p(r->receiving_mutex)) {
- rb_raise(rb_eRactorError, "can not call receive/receive_if recursively");
+ RACTOR_LOCK(r);
+ {
+ int pos = -1;
+ for (int i=0; i<wl->cnt; i++) {
+ if (wl->ractors[i] == wr) {
+ pos = i;
+ break;
+ }
+ }
+ if (pos >= 0) { // found
+ wl->cnt--;
+ for (int i=pos; i<wl->cnt; i++) {
+ wl->ractors[i] = wl->ractors[i+1];
+ }
+ }
}
+ RACTOR_UNLOCK(r);
}
-static VALUE
-ractor_try_receive(rb_execution_context_t *ec, rb_ractor_t *cr, struct rb_ractor_queue *rq)
+static rb_ractor_t *
+ractor_waiting_list_shift(rb_ractor_t *r, struct rb_ractor_waiting_list *wl)
{
- struct rb_ractor_basket basket;
- ractor_recursive_receive_if(cr);
- bool received = false;
-
- RACTOR_LOCK_SELF(cr);
- {
- RUBY_DEBUG_LOG("rq->cnt:%d", rq->cnt);
- received = ractor_queue_deq(cr, rq, &basket);
- }
- RACTOR_UNLOCK_SELF(cr);
+ ASSERT_ractor_locking(r);
+ VM_ASSERT(&r->sync.taking_ractors == wl);
- if (!received) {
- if (cr->sync.incoming_port_closed) {
- rb_raise(rb_eRactorClosedError, "The incoming port is already closed");
+ if (wl->cnt > 0) {
+ rb_ractor_t *tr = wl->ractors[0];
+ for (int i=1; i<wl->cnt; i++) {
+ wl->ractors[i-1] = wl->ractors[i];
}
- return Qundef;
+ wl->cnt--;
+ return tr;
}
else {
- return ractor_basket_accept(&basket);
+ return NULL;
}
}
static void
-ractor_wait_receive(rb_execution_context_t *ec, rb_ractor_t *cr, struct rb_ractor_queue *rq)
+ractor_receive_wait(rb_execution_context_t *ec, rb_ractor_t *cr)
{
VM_ASSERT(cr == rb_ec_ractor_ptr(ec));
ractor_recursive_receive_if(cr);
RACTOR_LOCK(cr);
{
- while (ractor_queue_empty_p(cr, rq)) {
- ractor_sleep(ec, cr, wait_receiving);
+ if (ractor_queue_empty_p(cr, &cr->sync.incoming_queue)) {
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ cr->sync.wait.status = wait_receiving;
+ cr->sync.wait.wakeup_status = wakeup_none;
+ ractor_sleep(ec, cr);
+ cr->sync.wait.wakeup_status = wakeup_none;
}
}
RACTOR_UNLOCK(cr);
@@ -756,25 +728,41 @@ ractor_receive(rb_execution_context_t *ec, rb_ractor_t *cr)
{
VM_ASSERT(cr == rb_ec_ractor_ptr(ec));
VALUE v;
- struct rb_ractor_queue *rq = &cr->sync.recv_queue;
- while (UNDEF_P(v = ractor_try_receive(ec, cr, rq))) {
- ractor_wait_receive(ec, cr, rq);
+ while (UNDEF_P(v = ractor_try_receive(ec, cr))) {
+ ractor_receive_wait(ec, cr);
}
return v;
}
#if 0
+// for debug
+static const char *
+basket_type_name(enum rb_ractor_basket_type type)
+{
+ switch (type) {
+#define T(t) case basket_type_##t: return #t
+ T(none);
+ T(ref);
+ T(copy);
+ T(move);
+ T(will);
+ T(deleted);
+ T(reserved);
+ default: rb_bug("unreachable");
+ }
+}
+
static void
rq_dump(struct rb_ractor_queue *rq)
{
bool bug = false;
for (int i=0; i<rq->cnt; i++) {
- struct rb_ractor_basket *b = ractor_queue_at(NULL, rq, i);
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
fprintf(stderr, "%d (start:%d) type:%s %p %s\n", i, rq->start, basket_type_name(b->type),
(void *)b, RSTRING_PTR(RARRAY_AREF(b->v, 1)));
- if (basket_type_p(b, basket_type_reserved) bug = true;
+ if (b->type == basket_type_reserved) bug = true;
}
if (bug) rb_bug("!!");
}
@@ -805,23 +793,22 @@ receive_if_body(VALUE ptr)
ractor_receive_if_lock(data->cr);
VALUE block_result = rb_yield(data->v);
- rb_ractor_t *cr = data->cr;
- RACTOR_LOCK_SELF(cr);
+ RACTOR_LOCK_SELF(data->cr);
{
- struct rb_ractor_basket *b = ractor_queue_at(cr, data->rq, data->index);
- VM_ASSERT(basket_type_p(b, basket_type_reserved));
+ struct rb_ractor_basket *b = ractor_queue_at(data->rq, data->index);
+ VM_ASSERT(b->type == basket_type_reserved);
data->rq->reserved_cnt--;
if (RTEST(block_result)) {
- ractor_queue_delete(cr, data->rq, b);
- ractor_queue_compact(cr, data->rq);
+ b->type = basket_type_deleted;
+ ractor_queue_compact(data->cr, data->rq);
}
else {
- b->type.e = basket_type_ref;
+ b->type = basket_type_ref;
}
}
- RACTOR_UNLOCK_SELF(cr);
+ RACTOR_UNLOCK_SELF(data->cr);
data->success = true;
@@ -837,20 +824,19 @@ static VALUE
receive_if_ensure(VALUE v)
{
struct receive_block_data *data = (struct receive_block_data *)v;
- rb_ractor_t *cr = data->cr;
if (!data->success) {
- RACTOR_LOCK_SELF(cr);
+ RACTOR_LOCK_SELF(data->cr);
{
- struct rb_ractor_basket *b = ractor_queue_at(cr, data->rq, data->index);
- VM_ASSERT(basket_type_p(b, basket_type_reserved));
- b->type.e = basket_type_deleted;
+ struct rb_ractor_basket *b = ractor_queue_at(data->rq, data->index);
+ VM_ASSERT(b->type == basket_type_reserved);
+ b->type = basket_type_deleted;
data->rq->reserved_cnt--;
}
- RACTOR_UNLOCK_SELF(cr);
+ RACTOR_UNLOCK_SELF(data->cr);
}
- rb_mutex_unlock(cr->receiving_mutex);
+ rb_mutex_unlock(data->cr->receiving_mutex);
return Qnil;
}
@@ -862,12 +848,12 @@ ractor_receive_if(rb_execution_context_t *ec, VALUE crv, VALUE b)
rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
unsigned int serial = (unsigned int)-1;
int index = 0;
- struct rb_ractor_queue *rq = &cr->sync.recv_queue;
+ struct rb_ractor_queue *rq = &cr->sync.incoming_queue;
while (1) {
VALUE v = Qundef;
- ractor_wait_receive(ec, cr, rq);
+ ractor_receive_wait(ec, cr);
RACTOR_LOCK_SELF(cr);
{
@@ -878,10 +864,10 @@ ractor_receive_if(rb_execution_context_t *ec, VALUE crv, VALUE b)
// check newer version
for (int i=index; i<rq->cnt; i++) {
- if (!ractor_queue_skip_p(cr, rq, i)) {
- struct rb_ractor_basket *b = ractor_queue_at(cr, rq, i);
+ if (!ractor_queue_skip_p(rq, i)) {
+ struct rb_ractor_basket *b = ractor_queue_at(rq, i);
v = ractor_basket_value(b);
- b->type.e = basket_type_reserved;
+ b->type = basket_type_reserved;
rq->reserved_cnt++;
index = i;
break;
@@ -914,6 +900,7 @@ static void
ractor_send_basket(rb_execution_context_t *ec, rb_ractor_t *r, struct rb_ractor_basket *b)
{
bool closed = false;
+ struct rb_ractor_queue *rq = &r->sync.incoming_queue;
RACTOR_LOCK(r);
{
@@ -921,8 +908,10 @@ ractor_send_basket(rb_execution_context_t *ec, rb_ractor_t *r, struct rb_ractor_
closed = true;
}
else {
- ractor_queue_enq(r, &r->sync.recv_queue, b);
- ractor_wakeup(r, wait_receiving, wakeup_by_send);
+ ractor_queue_enq(r, rq, b);
+ if (ractor_wakeup(r, wait_receiving, wakeup_by_send)) {
+ RUBY_DEBUG_LOG("wakeup");
+ }
}
}
RACTOR_UNLOCK(r);
@@ -932,896 +921,430 @@ ractor_send_basket(rb_execution_context_t *ec, rb_ractor_t *r, struct rb_ractor_
}
}
-// Ractor#send
-
static VALUE ractor_move(VALUE obj); // in this file
static VALUE ractor_copy(VALUE obj); // in this file
static void
-ractor_basket_prepare_contents(VALUE obj, VALUE move, volatile VALUE *pobj, enum rb_ractor_basket_type *ptype)
+ractor_basket_setup(rb_execution_context_t *ec, struct rb_ractor_basket *basket, VALUE obj, VALUE move, bool exc, bool is_will, bool is_yield)
{
- VALUE v;
- enum rb_ractor_basket_type type;
+ basket->sender = rb_ec_ractor_ptr(ec)->pub.self;
+ basket->exception = exc;
- if (rb_ractor_shareable_p(obj)) {
- type = basket_type_ref;
- v = obj;
+ if (is_will) {
+ basket->type = basket_type_will;
+ basket->v = obj;
+ }
+ else if (rb_ractor_shareable_p(obj)) {
+ basket->type = basket_type_ref;
+ basket->v = obj;
}
else if (!RTEST(move)) {
- v = ractor_copy(obj);
- type = basket_type_copy;
+ basket->v = ractor_copy(obj);
+ basket->type = basket_type_copy;
}
else {
- type = basket_type_move;
- v = ractor_move(obj);
- }
-
- *pobj = v;
- *ptype = type;
-}
-
-static void
-ractor_basket_fill_(rb_ractor_t *cr, struct rb_ractor_basket *basket, VALUE obj, bool exc)
-{
- VM_ASSERT(cr == GET_RACTOR());
-
- basket->sender = cr->pub.self;
- basket->p.send.exception = exc;
- basket->p.send.v = obj;
-}
-
-static void
-ractor_basket_fill(rb_ractor_t *cr, struct rb_ractor_basket *basket, VALUE obj, VALUE move, bool exc)
-{
- VALUE v;
- enum rb_ractor_basket_type type;
- ractor_basket_prepare_contents(obj, move, &v, &type);
- ractor_basket_fill_(cr, basket, v, exc);
- basket->type.e = type;
-}
+ basket->type = basket_type_move;
-static void
-ractor_basket_fill_will(rb_ractor_t *cr, struct rb_ractor_basket *basket, VALUE obj, bool exc)
-{
- ractor_basket_fill_(cr, basket, obj, exc);
- basket->type.e = basket_type_will;
+ if (is_yield) {
+ basket->v = obj; // call ractor_move() when yielding timing.
+ }
+ else {
+ basket->v = ractor_move(obj);
+ }
+ }
}
static VALUE
ractor_send(rb_execution_context_t *ec, rb_ractor_t *r, VALUE obj, VALUE move)
{
struct rb_ractor_basket basket;
- // TODO: Ractor local GC
- ractor_basket_fill(rb_ec_ractor_ptr(ec), &basket, obj, move, false);
+ ractor_basket_setup(ec, &basket, obj, move, false, false, false);
ractor_send_basket(ec, r, &basket);
return r->pub.self;
}
-// Ractor#take
-
-static bool
-ractor_take_has_will(rb_ractor_t *r)
-{
- ASSERT_ractor_locking(r);
-
- return basket_type_p(&r->sync.will_basket, basket_type_will);
-}
-
-static bool
-ractor_take_will(rb_ractor_t *r, struct rb_ractor_basket *b)
-{
- ASSERT_ractor_locking(r);
-
- if (ractor_take_has_will(r)) {
- *b = r->sync.will_basket;
- r->sync.will_basket.type.e = basket_type_none;
- return true;
- }
- else {
- VM_ASSERT(basket_type_p(&r->sync.will_basket, basket_type_none));
- return false;
- }
-}
-
-static bool
-ractor_take_will_lock(rb_ractor_t *r, struct rb_ractor_basket *b)
+static VALUE
+ractor_try_take(rb_execution_context_t *ec, rb_ractor_t *r)
{
- ASSERT_ractor_unlocking(r);
- bool taken;
-
- RACTOR_LOCK(r);
- {
- taken = ractor_take_will(r, b);
- }
- RACTOR_UNLOCK(r);
-
- return taken;
-}
-
-static bool
-ractor_register_take(rb_ractor_t *cr, rb_ractor_t *r, struct rb_ractor_basket *take_basket,
- bool is_take, struct rb_ractor_selector_take_config *config, bool ignore_error)
-{
- struct rb_ractor_basket b = {
- .type.e = basket_type_take_basket,
- .sender = cr->pub.self,
- .p = {
- .take = {
- .basket = take_basket,
- .config = config,
- },
- },
+ struct rb_ractor_basket basket = {
+ .type = basket_type_none,
};
bool closed = false;
RACTOR_LOCK(r);
{
- if (is_take && ractor_take_will(r, take_basket)) {
- RUBY_DEBUG_LOG("take over a will of r:%d", rb_ractor_id(r));
- }
- else if (!is_take && ractor_take_has_will(r)) {
- RUBY_DEBUG_LOG("has_will");
- VM_ASSERT(config != NULL);
- config->closed = true;
+ if (ractor_sleeping_by(r, wait_yielding)) {
+ MAYBE_UNUSED(bool) wakeup_result;
+ VM_ASSERT(r->sync.wait.yielded_basket.type != basket_type_none);
+
+ if (r->sync.wait.yielded_basket.type == basket_type_move) {
+ wakeup_result = ractor_wakeup(r, wait_yielding, wakeup_by_retry);
+ }
+ else {
+ wakeup_result = ractor_wakeup(r, wait_yielding, wakeup_by_take);
+ basket = r->sync.wait.yielded_basket;
+ ractor_basket_clear(&r->sync.wait.yielded_basket);
+ }
+ VM_ASSERT(wakeup_result);
}
else if (r->sync.outgoing_port_closed) {
closed = true;
}
- else {
- RUBY_DEBUG_LOG("register in r:%d", rb_ractor_id(r));
- ractor_queue_enq(r, &r->sync.takers_queue, &b);
-
- if (basket_none_p(take_basket)) {
- ractor_wakeup(r, wait_yielding, wakeup_by_take);
- }
- }
}
RACTOR_UNLOCK(r);
- if (closed) {
- if (!ignore_error) rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
- return false;
- }
- else {
- return true;
- }
-}
-
-static bool
-ractor_deregister_take(rb_ractor_t *r, struct rb_ractor_basket *take_basket)
-{
- struct rb_ractor_queue *ts = &r->sync.takers_queue;
- bool deleted = false;
-
- RACTOR_LOCK(r);
- {
- if (r->sync.outgoing_port_closed) {
- // ok
+ if (basket.type == basket_type_none) {
+ if (closed) {
+ rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
}
else {
- for (int i=0; i<ts->cnt; i++) {
- struct rb_ractor_basket *b = ractor_queue_at(r, ts, i);
- if (basket_type_p(b, basket_type_take_basket) && b->p.take.basket == take_basket) {
- ractor_queue_delete(r, ts, b);
- deleted = true;
- }
- }
- if (deleted) {
- ractor_queue_compact(r, ts);
- }
+ return Qundef;
}
}
- RACTOR_UNLOCK(r);
-
- return deleted;
+ else {
+ return ractor_basket_accept(&basket);
+ }
}
static VALUE
-ractor_try_take(rb_ractor_t *cr, rb_ractor_t *r, struct rb_ractor_basket *take_basket)
+ractor_yield_move_body(VALUE v)
{
- bool taken;
-
- RACTOR_LOCK_SELF(cr);
- {
- if (basket_none_p(take_basket) || basket_type_p(take_basket, basket_type_yielding)) {
- taken = false;
- }
- else {
- taken = true;
- }
- }
- RACTOR_UNLOCK_SELF(cr);
-
- if (taken) {
- RUBY_DEBUG_LOG("taken");
- if (basket_type_p(take_basket, basket_type_deleted)) {
- VM_ASSERT(r->sync.outgoing_port_closed);
- rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
- }
- return ractor_basket_accept(take_basket);
- }
- else {
- RUBY_DEBUG_LOG("not taken");
- return Qundef;
- }
+ return ractor_move(v);
}
-
-#if VM_CHECK_MODE > 0
static bool
-ractor_check_specific_take_basket_lock(rb_ractor_t *r, struct rb_ractor_basket *tb)
+ractor_try_yield(rb_execution_context_t *ec, rb_ractor_t *cr, struct rb_ractor_basket *basket)
{
- bool ret = false;
- struct rb_ractor_queue *ts = &r->sync.takers_queue;
-
- RACTOR_LOCK(r);
- {
- for (int i=0; i<ts->cnt; i++) {
- struct rb_ractor_basket *b = ractor_queue_at(r, ts, i);
- if (basket_type_p(b, basket_type_take_basket) && b->p.take.basket == tb) {
- ret = true;
- break;
- }
- }
- }
- RACTOR_UNLOCK(r);
-
- return ret;
-}
-#endif
+ ASSERT_ractor_unlocking(cr);
+ VM_ASSERT(basket->type != basket_type_none);
-static void
-ractor_take_cleanup(rb_ractor_t *cr, rb_ractor_t *r, struct rb_ractor_basket *tb)
-{
- retry:
- if (basket_none_p(tb)) { // not yielded yet
- if (!ractor_deregister_take(r, tb)) {
- // not in r's takers queue
- rb_thread_sleep(0);
- goto retry;
- }
- }
- else {
- VM_ASSERT(!ractor_check_specific_take_basket_lock(r, tb));
+ if (cr->sync.outgoing_port_closed) {
+ rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
}
-}
-struct take_wait_take_cleanup_data {
rb_ractor_t *r;
- struct rb_ractor_basket *tb;
-};
-static void
-ractor_wait_take_cleanup(rb_ractor_t *cr, void *ptr)
-{
- struct take_wait_take_cleanup_data *data = (struct take_wait_take_cleanup_data *)ptr;
- ractor_take_cleanup(cr, data->r, data->tb);
-}
-
-static void
-ractor_wait_take(rb_execution_context_t *ec, rb_ractor_t *cr, rb_ractor_t *r, struct rb_ractor_basket *take_basket)
-{
- struct take_wait_take_cleanup_data data = {
- .r = r,
- .tb = take_basket,
- };
-
- RACTOR_LOCK_SELF(cr);
+ retry_shift:
+ RACTOR_LOCK(cr);
{
- if (basket_none_p(take_basket) || basket_type_p(take_basket, basket_type_yielding)) {
- ractor_sleep_with_cleanup(ec, cr, wait_taking, ractor_wait_take_cleanup, &data);
- }
- }
- RACTOR_UNLOCK_SELF(cr);
-}
-
-static VALUE
-ractor_take(rb_execution_context_t *ec, rb_ractor_t *r)
-{
- RUBY_DEBUG_LOG("from r:%u", rb_ractor_id(r));
- VALUE v;
- rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
-
- struct rb_ractor_basket take_basket = {
- .type.e = basket_type_none,
- .sender = 0,
- };
-
- ractor_register_take(cr, r, &take_basket, true, NULL, false);
-
- while (UNDEF_P(v = ractor_try_take(cr, r, &take_basket))) {
- ractor_wait_take(ec, cr, r, &take_basket);
- }
-
- VM_ASSERT(!basket_none_p(&take_basket));
- VM_ASSERT(!ractor_check_specific_take_basket_lock(r, &take_basket));
-
- return v;
-}
-
-// Ractor.yield
-
-static bool
-ractor_check_take_basket(rb_ractor_t *cr, struct rb_ractor_queue *rs)
-{
- ASSERT_ractor_locking(cr);
-
- for (int i=0; i<rs->cnt; i++) {
- struct rb_ractor_basket *b = ractor_queue_at(cr, rs, i);
- if (basket_type_p(b, basket_type_take_basket) &&
- basket_none_p(b->p.take.basket)) {
- return true;
- }
+ r = ractor_waiting_list_shift(cr, &cr->sync.taking_ractors);
}
+ RACTOR_UNLOCK(cr);
- return false;
-}
+ if (r) {
+ bool retry_shift = false;
-static bool
-ractor_deq_take_basket(rb_ractor_t *cr, struct rb_ractor_queue *rs, struct rb_ractor_basket *b)
-{
- ASSERT_ractor_unlocking(cr);
- struct rb_ractor_basket *first_tb = NULL;
- bool found = false;
-
- RACTOR_LOCK_SELF(cr);
- {
- while (ractor_queue_deq(cr, rs, b)) {
- if (basket_type_p(b, basket_type_take_basket)) {
- struct rb_ractor_basket *tb = b->p.take.basket;
+ RACTOR_LOCK(r);
+ {
+ if (ractor_sleeping_by(r, wait_taking)) {
+ VM_ASSERT(r->sync.wait.taken_basket.type == basket_type_none);
+
+ if (basket->type == basket_type_move) {
+ enum rb_ractor_wait_status prev_wait_status = r->sync.wait.status;
+ r->sync.wait.status = wait_moving;
+
+ RACTOR_UNLOCK(r);
+ {
+ int state;
+ VALUE moved_value = rb_protect(ractor_yield_move_body, basket->v, &state);
+ if (state) {
+ r->sync.wait.status = prev_wait_status;
+ rb_jump_tag(state);
+ }
+ else {
+ basket->v = moved_value;
+ }
+ }
+ RACTOR_LOCK(r);
- if (RUBY_ATOMIC_CAS(tb->type.atomic, basket_type_none, basket_type_yielding) == basket_type_none) {
- found = true;
- break;
+ if (!ractor_wakeup(r, wait_moving, wakeup_by_yield)) {
+ // terminating?
+ }
}
else {
- ractor_queue_enq(cr, rs, b);
- if (first_tb == NULL) first_tb = tb;
- struct rb_ractor_basket *head = ractor_queue_head(cr, rs);
- VM_ASSERT(head != NULL);
- if (basket_type_p(head, basket_type_take_basket) && head->p.take.basket == first_tb) {
- break; // loop detected
- }
+ ractor_wakeup(r, wait_taking, wakeup_by_yield);
}
+ r->sync.wait.taken_basket = *basket;
}
else {
- VM_ASSERT(basket_none_p(b));
+ retry_shift = true;
}
}
+ RACTOR_UNLOCK(r);
- if (found && b->p.take.config && !b->p.take.config->oneshot) {
- ractor_queue_enq(cr, rs, b);
- }
- }
- RACTOR_UNLOCK_SELF(cr);
-
- return found;
-}
-
-static bool
-ractor_try_yield(rb_execution_context_t *ec, rb_ractor_t *cr, struct rb_ractor_queue *ts, volatile VALUE obj, VALUE move, bool exc, bool is_will)
-{
- ASSERT_ractor_unlocking(cr);
-
- struct rb_ractor_basket b;
-
- if (ractor_deq_take_basket(cr, ts, &b)) {
- VM_ASSERT(basket_type_p(&b, basket_type_take_basket));
- VM_ASSERT(basket_type_p(b.p.take.basket, basket_type_yielding));
-
- rb_ractor_t *tr = RACTOR_PTR(b.sender);
- struct rb_ractor_basket *tb = b.p.take.basket;
- enum rb_ractor_basket_type type;
-
- RUBY_DEBUG_LOG("basket from r:%u", rb_ractor_id(tr));
-
- if (is_will) {
- type = basket_type_will;
+ if (retry_shift) {
+ // get candidate take-waiting ractor, but already woke up by another reason.
+ // retry to check another ractor.
+ goto retry_shift;
}
else {
- int state;
-
- // begin
- EC_PUSH_TAG(ec);
- if ((state = EC_EXEC_TAG()) == TAG_NONE) {
- // TODO: Ractor local GC
- ractor_basket_prepare_contents(obj, move, &obj, &type);
- }
- EC_POP_TAG();
- // rescue
- if (state) {
- RACTOR_LOCK_SELF(cr);
- {
- b.p.take.basket->type.e = basket_type_none;
- ractor_queue_enq(cr, ts, &b);
- }
- RACTOR_UNLOCK_SELF(cr);
- EC_JUMP_TAG(ec, state);
- }
- }
-
- RACTOR_LOCK(tr);
- {
- VM_ASSERT(basket_type_p(tb, basket_type_yielding));
- // fill atomic
- RUBY_DEBUG_LOG("fill %sbasket from r:%u", is_will ? "will " : "", rb_ractor_id(tr));
- ractor_basket_fill_(cr, tb, obj, exc);
- if (RUBY_ATOMIC_CAS(tb->type.atomic, basket_type_yielding, type) != basket_type_yielding) {
- rb_bug("unreachable");
- }
- ractor_wakeup(tr, wait_taking, wakeup_by_yield);
+ return true;
}
- RACTOR_UNLOCK(tr);
-
- return true;
}
else {
- RUBY_DEBUG_LOG("no take basket");
return false;
}
}
-static void
-ractor_wait_yield(rb_execution_context_t *ec, rb_ractor_t *cr, struct rb_ractor_queue *ts)
-{
- RACTOR_LOCK_SELF(cr);
- {
- while (!ractor_check_take_basket(cr, ts)) {
- ractor_sleep(ec, cr, wait_yielding);
- }
- }
- RACTOR_UNLOCK_SELF(cr);
-}
-
+// select(r1, r2, r3, receive: true, yield: obj)
static VALUE
-ractor_yield(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE obj, VALUE move)
-{
- struct rb_ractor_queue *ts = &cr->sync.takers_queue;
-
- while (!ractor_try_yield(ec, cr, ts, obj, move, false, false)) {
- ractor_wait_yield(ec, cr, ts);
- }
-
- return Qnil;
-}
-
-// Ractor::Selector
-
-struct rb_ractor_selector {
- rb_ractor_t *r;
- struct rb_ractor_basket take_basket;
- st_table *take_ractors; // rb_ractor_t * => (struct rb_ractor_selector_take_config *)
-};
-
-static int
-ractor_selector_mark_ractors_i(st_data_t key, st_data_t value, st_data_t data)
-{
- const rb_ractor_t *r = (rb_ractor_t *)key;
- rb_gc_mark(r->pub.self);
- return ST_CONTINUE;
-}
-
-static void
-ractor_selector_mark(void *ptr)
-{
- struct rb_ractor_selector *s = ptr;
-
- if (s->take_ractors) {
- st_foreach(s->take_ractors, ractor_selector_mark_ractors_i, 0);
- }
-
- switch (s->take_basket.type.e) {
- case basket_type_ref:
- case basket_type_copy:
- case basket_type_move:
- case basket_type_will:
- rb_gc_mark(s->take_basket.sender);
- rb_gc_mark(s->take_basket.p.send.v);
- break;
- default:
- break;
- }
-}
-
-static int
-ractor_selector_release_i(st_data_t key, st_data_t val, st_data_t data)
-{
- struct rb_ractor_selector *s = (struct rb_ractor_selector *)data;
- struct rb_ractor_selector_take_config *config = (struct rb_ractor_selector_take_config *)val;
-
- if (!config->closed) {
- ractor_deregister_take((rb_ractor_t *)key, &s->take_basket);
- }
- free(config);
- return ST_CONTINUE;
-}
-
-static void
-ractor_selector_free(void *ptr)
+ractor_select(rb_execution_context_t *ec, const VALUE *rs, const int rs_len, VALUE yielded_value, bool move, VALUE *ret_r)
{
- struct rb_ractor_selector *s = ptr;
- st_foreach(s->take_ractors, ractor_selector_release_i, (st_data_t)s);
- st_free_table(s->take_ractors);
- ruby_xfree(ptr);
-}
-
-static size_t
-ractor_selector_memsize(const void *ptr)
-{
- const struct rb_ractor_selector *s = ptr;
- return sizeof(struct rb_ractor_selector) +
- st_memsize(s->take_ractors) +
- s->take_ractors->num_entries * sizeof(struct rb_ractor_selector_take_config);
-}
-
-static const rb_data_type_t ractor_selector_data_type = {
- "ractor/selector",
- {
- ractor_selector_mark,
- ractor_selector_free,
- ractor_selector_memsize,
- NULL, // update
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
-};
-
-static struct rb_ractor_selector *
-RACTOR_SELECTOR_PTR(VALUE selv)
-{
- VM_ASSERT(rb_typeddata_is_kind_of(selv, &ractor_selector_data_type));
-
- return (struct rb_ractor_selector *)DATA_PTR(selv);
-}
-
-// Ractor::Selector.new
-
-static VALUE
-ractor_selector_create(VALUE klass)
-{
- struct rb_ractor_selector *s;
- VALUE selv = TypedData_Make_Struct(klass, struct rb_ractor_selector, &ractor_selector_data_type, s);
- s->take_basket.type.e = basket_type_reserved;
- s->take_ractors = st_init_numtable(); // ractor (ptr) -> take_config
- return selv;
-}
-
-// Ractor::Selector#add(r)
-
-static VALUE
-ractor_selector_add(VALUE selv, VALUE rv)
-{
- if (!rb_ractor_p(rv)) {
- rb_raise(rb_eArgError, "Not a ractor object");
- }
-
- rb_ractor_t *r = RACTOR_PTR(rv);
- struct rb_ractor_selector *s = RACTOR_SELECTOR_PTR(selv);
-
- if (st_lookup(s->take_ractors, (st_data_t)r, NULL)) {
- rb_raise(rb_eArgError, "already added");
- }
-
- struct rb_ractor_selector_take_config *config = malloc(sizeof(struct rb_ractor_selector_take_config));
- VM_ASSERT(config != NULL);
- config->closed = false;
- config->oneshot = false;
-
- if (ractor_register_take(GET_RACTOR(), r, &s->take_basket, false, config, true)) {
- st_insert(s->take_ractors, (st_data_t)r, (st_data_t)config);
- }
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ VALUE crv = cr->pub.self;
+ VALUE ret = Qundef;
+ int i;
+ bool interrupted = false;
+ enum rb_ractor_wait_status wait_status = 0;
+ bool yield_p = !UNDEF_P(yielded_value) ? true : false;
+ const int alen = rs_len + (yield_p ? 1 : 0);
+
+ struct ractor_select_action {
+ enum ractor_select_action_type {
+ ractor_select_action_take,
+ ractor_select_action_receive,
+ ractor_select_action_yield,
+ } type;
+ VALUE v;
+ } *actions = ALLOCA_N(struct ractor_select_action, alen);
- return rv;
-}
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ VM_ASSERT(cr->sync.wait.wakeup_status == wakeup_none);
+ VM_ASSERT(cr->sync.wait.taken_basket.type == basket_type_none);
+ VM_ASSERT(cr->sync.wait.yielded_basket.type == basket_type_none);
-// Ractor::Selector#remove(r)
+ // setup actions
+ for (i=0; i<rs_len; i++) {
+ VALUE v = rs[i];
-static VALUE
-ractor_selector_remove(VALUE selv, VALUE rv)
-{
- if (!rb_ractor_p(rv)) {
- rb_raise(rb_eArgError, "Not a ractor object");
+ if (v == crv) {
+ actions[i].type = ractor_select_action_receive;
+ actions[i].v = Qnil;
+ wait_status |= wait_receiving;
+ }
+ else if (rb_ractor_p(v)) {
+ actions[i].type = ractor_select_action_take;
+ actions[i].v = v;
+ wait_status |= wait_taking;
+ }
+ else {
+ rb_raise(rb_eArgError, "should be a ractor object, but %"PRIsVALUE, v);
+ }
}
+ rs = NULL;
- rb_ractor_t *r = RACTOR_PTR(rv);
- struct rb_ractor_selector *s = RACTOR_SELECTOR_PTR(selv);
-
- RUBY_DEBUG_LOG("r:%u", rb_ractor_id(r));
+ restart:
- if (!st_lookup(s->take_ractors, (st_data_t)r, NULL)) {
- rb_raise(rb_eArgError, "not added yet");
+ if (yield_p) {
+ actions[rs_len].type = ractor_select_action_yield;
+ actions[rs_len].v = Qundef;
+ wait_status |= wait_yielding;
+ ractor_basket_setup(ec, &cr->sync.wait.yielded_basket, yielded_value, move, false, false, true);
}
- ractor_deregister_take(r, &s->take_basket);
- struct rb_ractor_selector_take_config *config;
- st_delete(s->take_ractors, (st_data_t *)&r, (st_data_t *)&config);
- free(config);
-
- return rv;
-}
-
-// Ractor::Selector#clear
-
-struct ractor_selector_clear_data {
- VALUE selv;
- rb_execution_context_t *ec;
-};
-
-static int
-ractor_selector_clear_i(st_data_t key, st_data_t val, st_data_t data)
-{
- VALUE selv = (VALUE)data;
- rb_ractor_t *r = (rb_ractor_t *)key;
- ractor_selector_remove(selv, r->pub.self);
- return ST_CONTINUE;
-}
-
-static VALUE
-ractor_selector_clear(VALUE selv)
-{
- struct rb_ractor_selector *s = RACTOR_SELECTOR_PTR(selv);
-
- st_foreach(s->take_ractors, ractor_selector_clear_i, (st_data_t)selv);
- st_clear(s->take_ractors);
- return selv;
-}
+ // TODO: shuffle actions
-static VALUE
-ractor_selector_empty_p(VALUE selv)
-{
- struct rb_ractor_selector *s = RACTOR_SELECTOR_PTR(selv);
- return s->take_ractors->num_entries == 0 ? Qtrue : Qfalse;
-}
-
-static int
-ractor_selector_wait_i(st_data_t key, st_data_t val, st_data_t dat)
-{
- rb_ractor_t *r = (rb_ractor_t *)key;
- struct rb_ractor_basket *tb = (struct rb_ractor_basket *)dat;
- int ret;
+ while (1) {
+ RUBY_DEBUG_LOG("try actions (%s)", wait_status_str(wait_status));
+
+ for (i=0; i<alen; i++) {
+ VALUE v, rv;
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ rv = actions[i].v;
+ v = ractor_try_take(ec, RACTOR_PTR(rv));
+ if (!UNDEF_P(v)) {
+ *ret_r = rv;
+ ret = v;
+ goto cleanup;
+ }
+ break;
+ case ractor_select_action_receive:
+ v = ractor_try_receive(ec, cr);
+ if (!UNDEF_P(v)) {
+ *ret_r = ID2SYM(rb_intern("receive"));
+ ret = v;
+ goto cleanup;
+ }
+ break;
+ case ractor_select_action_yield:
+ {
+ if (ractor_try_yield(ec, cr, &cr->sync.wait.yielded_basket)) {
+ *ret_r = ID2SYM(rb_intern("yield"));
+ ret = Qnil;
+ goto cleanup;
+ }
+ }
+ break;
+ }
+ }
- if (!basket_none_p(tb)) {
- RUBY_DEBUG_LOG("already taken:%s", basket_type_name(tb->type.e));
- return ST_STOP;
- }
+ RUBY_DEBUG_LOG("wait actions (%s)", wait_status_str(wait_status));
- RACTOR_LOCK(r);
- {
- if (basket_type_p(&r->sync.will_basket, basket_type_will)) {
- RUBY_DEBUG_LOG("r:%u has will", rb_ractor_id(r));
+ RACTOR_LOCK(cr);
+ {
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ cr->sync.wait.status = wait_status;
+ cr->sync.wait.wakeup_status = wakeup_none;
+ }
+ RACTOR_UNLOCK(cr);
- if (RUBY_ATOMIC_CAS(tb->type.atomic, basket_type_none, basket_type_will) == basket_type_none) {
- ractor_take_will(r, tb);
- ret = ST_STOP;
- }
- else {
- RUBY_DEBUG_LOG("has will, but already taken (%s)", basket_type_name(tb->type.e));
- ret = ST_CONTINUE;
+ // prepare waiting
+ for (i=0; i<alen; i++) {
+ rb_ractor_t *r;
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ r = RACTOR_PTR(actions[i].v);
+ ractor_register_taking(r, cr);
+ break;
+ case ractor_select_action_yield:
+ case ractor_select_action_receive:
+ break;
}
}
- else if (r->sync.outgoing_port_closed) {
- RUBY_DEBUG_LOG("r:%u is closed", rb_ractor_id(r));
- if (RUBY_ATOMIC_CAS(tb->type.atomic, basket_type_none, basket_type_deleted) == basket_type_none) {
- tb->sender = r->pub.self;
- ret = ST_STOP;
+ // wait
+ RACTOR_LOCK(cr);
+ {
+ if (cr->sync.wait.wakeup_status == wakeup_none) {
+ for (i=0; i<alen; i++) {
+ rb_ractor_t *r;
+
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ r = RACTOR_PTR(actions[i].v);
+ if (ractor_sleeping_by(r, wait_yielding)) {
+ RUBY_DEBUG_LOG("wakeup_none, but r:%u is waiting for yielding", r->pub.id);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ goto skip_sleep;
+ }
+ break;
+ case ractor_select_action_receive:
+ if (cr->sync.incoming_queue.cnt > 0) {
+ RUBY_DEBUG_LOG("wakeup_none, but incoming_queue has %u messages", cr->sync.incoming_queue.cnt);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ goto skip_sleep;
+ }
+ break;
+ case ractor_select_action_yield:
+ if (cr->sync.taking_ractors.cnt > 0) {
+ RUBY_DEBUG_LOG("wakeup_none, but %u taking_ractors are waiting", cr->sync.taking_ractors.cnt);
+ cr->sync.wait.wakeup_status = wakeup_by_retry;
+ goto skip_sleep;
+ }
+ else if (cr->sync.outgoing_port_closed) {
+ cr->sync.wait.wakeup_status = wakeup_by_close;
+ goto skip_sleep;
+ }
+ break;
+ }
+ }
+
+ RUBY_DEBUG_LOG("sleep %s", wait_status_str(cr->sync.wait.status));
+ ractor_sleep(ec, cr);
+ RUBY_DEBUG_LOG("awaken %s", wakeup_status_str(cr->sync.wait.wakeup_status));
}
else {
- RUBY_DEBUG_LOG("closed, but already taken (%s)", basket_type_name(tb->type.e));
- ret = ST_CONTINUE;
+ skip_sleep:
+ RUBY_DEBUG_LOG("no need to sleep %s->%s",
+ wait_status_str(cr->sync.wait.status),
+ wakeup_status_str(cr->sync.wait.wakeup_status));
+ cr->sync.wait.status = wait_none;
}
}
- else {
- RUBY_DEBUG_LOG("wakeup r:%u", rb_ractor_id(r));
- ractor_wakeup(r, wait_yielding, wakeup_by_take);
- ret = ST_CONTINUE;
- }
- }
- RACTOR_UNLOCK(r);
-
- return ret;
-}
-
-// Ractor::Selector#wait
-
-static void
-ractor_selector_wait_cleaup(rb_ractor_t *cr, void *ptr)
-{
- struct rb_ractor_basket *tb = (struct rb_ractor_basket *)ptr;
-
- RACTOR_LOCK_SELF(cr);
- {
- while (basket_type_p(tb, basket_type_yielding)) rb_thread_sleep(0);
- // if tb->type is not none, taking is succeeded, but interruption ignore it unfortunately.
- tb->type.e = basket_type_reserved;
- }
- RACTOR_UNLOCK_SELF(cr);
-}
-
-static VALUE
-ractor_selector__wait(VALUE selv, VALUE do_receivev, VALUE do_yieldv, VALUE yield_value, VALUE move)
-{
- rb_execution_context_t *ec = GET_EC();
- struct rb_ractor_selector *s = RACTOR_SELECTOR_PTR(selv);
- struct rb_ractor_basket *tb = &s->take_basket;
- struct rb_ractor_basket taken_basket;
- rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
- bool do_receive = !!RTEST(do_receivev);
- bool do_yield = !!RTEST(do_yieldv);
- VALUE ret_v, ret_r;
- enum rb_ractor_wait_status wait_status;
- struct rb_ractor_queue *rq = &cr->sync.recv_queue;
- struct rb_ractor_queue *ts = &cr->sync.takers_queue;
-
- RUBY_DEBUG_LOG("start");
-
- retry:
- RUBY_DEBUG_LOG("takers:%ld", s->take_ractors->num_entries);
-
- // setup wait_status
- wait_status = wait_none;
- if (s->take_ractors->num_entries > 0) wait_status |= wait_taking;
- if (do_receive) wait_status |= wait_receiving;
- if (do_yield) wait_status |= wait_yielding;
-
- RUBY_DEBUG_LOG("wait:%s", wait_status_str(wait_status));
-
- if (wait_status == wait_none) {
- rb_raise(rb_eRactorError, "no taking ractors");
- }
-
- // check recv_queue
- if (do_receive && (ret_v = ractor_try_receive(ec, cr, rq)) != Qundef) {
- ret_r = ID2SYM(rb_intern("receive"));
- goto success;
- }
-
- // check takers
- if (do_yield && ractor_try_yield(ec, cr, ts, yield_value, move, false, false)) {
- ret_v = Qnil;
- ret_r = ID2SYM(rb_intern("yield"));
- goto success;
- }
-
- // check take_basket
- VM_ASSERT(basket_type_p(&s->take_basket, basket_type_reserved));
- s->take_basket.type.e = basket_type_none;
- // kick all take target ractors
- st_foreach(s->take_ractors, ractor_selector_wait_i, (st_data_t)tb);
+ RACTOR_UNLOCK(cr);
- RACTOR_LOCK_SELF(cr);
- {
- retry_waiting:
- while (1) {
- if (!basket_none_p(tb)) {
- RUBY_DEBUG_LOG("taken:%s from r:%u", basket_type_name(tb->type.e),
- tb->sender ? rb_ractor_id(RACTOR_PTR(tb->sender)) : 0);
+ // cleanup waiting
+ for (i=0; i<alen; i++) {
+ rb_ractor_t *r;
+ switch (actions[i].type) {
+ case ractor_select_action_take:
+ r = RACTOR_PTR(actions[i].v);
+ ractor_waiting_list_del(r, &r->sync.taking_ractors, cr);
break;
- }
- if (do_receive && !ractor_queue_empty_p(cr, rq)) {
- RUBY_DEBUG_LOG("can receive (%d)", rq->cnt);
- break;
- }
- if (do_yield && ractor_check_take_basket(cr, ts)) {
- RUBY_DEBUG_LOG("can yield");
+ case ractor_select_action_receive:
+ case ractor_select_action_yield:
break;
}
-
- ractor_sleep_with_cleanup(ec, cr, wait_status, ractor_selector_wait_cleaup, tb);
}
- taken_basket = *tb;
+ // check results
+ enum rb_ractor_wakeup_status wakeup_status = cr->sync.wait.wakeup_status;
+ cr->sync.wait.wakeup_status = wakeup_none;
- // ensure
- // tb->type.e = basket_type_reserved # do it atomic in the following code
- if (taken_basket.type.e == basket_type_yielding ||
- RUBY_ATOMIC_CAS(tb->type.atomic, taken_basket.type.e, basket_type_reserved) != taken_basket.type.e) {
-
- if (basket_type_p(tb, basket_type_yielding)) {
- RACTOR_UNLOCK_SELF(cr);
- {
- rb_thread_sleep(0);
- }
- RACTOR_LOCK_SELF(cr);
- }
- goto retry_waiting;
+ switch (wakeup_status) {
+ case wakeup_none:
+ // OK. something happens.
+ // retry loop.
+ break;
+ case wakeup_by_retry:
+ // Retry request.
+ break;
+ case wakeup_by_send:
+ // OK.
+ // retry loop and try_receive will succss.
+ break;
+ case wakeup_by_yield:
+ // take was succeeded!
+ // cr.wait.taken_basket contains passed block
+ VM_ASSERT(cr->sync.wait.taken_basket.type != basket_type_none);
+ *ret_r = cr->sync.wait.taken_basket.sender;
+ VM_ASSERT(rb_ractor_p(*ret_r));
+ ret = ractor_basket_accept(&cr->sync.wait.taken_basket);
+ goto cleanup;
+ case wakeup_by_take:
+ *ret_r = ID2SYM(rb_intern("yield"));
+ ret = Qnil;
+ goto cleanup;
+ case wakeup_by_close:
+ // OK.
+ // retry loop and will get CloseError.
+ break;
+ case wakeup_by_interrupt:
+ ret = Qundef;
+ interrupted = true;
+ goto cleanup;
}
}
- RACTOR_UNLOCK_SELF(cr);
-
- // check the taken resutl
- switch (taken_basket.type.e) {
- case basket_type_none:
- VM_ASSERT(do_receive || do_yield);
- goto retry;
- case basket_type_yielding:
- rb_bug("unreachable");
- case basket_type_deleted: {
- ractor_selector_remove(selv, taken_basket.sender);
-
- rb_ractor_t *r = RACTOR_PTR(taken_basket.sender);
- if (ractor_take_will_lock(r, &taken_basket)) {
- RUBY_DEBUG_LOG("has_will");
- }
- else {
- RUBY_DEBUG_LOG("no will");
- // rb_raise(rb_eRactorClosedError, "The outgoing-port is already closed");
- // remove and retry wait
- goto retry;
- }
- break;
- }
- case basket_type_will:
- // no more messages
- ractor_selector_remove(selv, taken_basket.sender);
- break;
- default:
- break;
- }
- RUBY_DEBUG_LOG("taken_basket:%s", basket_type_name(taken_basket.type.e));
+ cleanup:
+ RUBY_DEBUG_LOG("cleanup actions (%s)", wait_status_str(wait_status));
- ret_v = ractor_basket_accept(&taken_basket);
- ret_r = taken_basket.sender;
- success:
- return rb_ary_new_from_args(2, ret_r, ret_v);
-}
+ if (cr->sync.wait.yielded_basket.type != basket_type_none) {
+ ractor_basket_clear(&cr->sync.wait.yielded_basket);
+ }
-static VALUE
-ractor_selector_wait(int argc, VALUE *argv, VALUE selector)
-{
- VALUE options;
- ID keywords[3];
- VALUE values[3];
+ VM_ASSERT(cr->sync.wait.status == wait_none);
+ VM_ASSERT(cr->sync.wait.wakeup_status == wakeup_none);
+ VM_ASSERT(cr->sync.wait.taken_basket.type == basket_type_none);
+ VM_ASSERT(cr->sync.wait.yielded_basket.type == basket_type_none);
- keywords[0] = rb_intern("receive");
- keywords[1] = rb_intern("yield_value");
- keywords[2] = rb_intern("move");
+ if (interrupted) {
+ rb_vm_check_ints_blocking(ec);
+ interrupted = false;
+ goto restart;
+ }
- rb_scan_args(argc, argv, "0:", &options);
- rb_get_kwargs(options, keywords, 0, numberof(values), values);
- return ractor_selector__wait(selector,
- values[0] == Qundef ? Qfalse : RTEST(values[0]),
- values[1] != Qundef, values[1], values[2]);
+ VM_ASSERT(!UNDEF_P(ret));
+ return ret;
}
static VALUE
-ractor_selector_new(int argc, VALUE *ractors, VALUE klass)
+ractor_yield(rb_execution_context_t *ec, rb_ractor_t *r, VALUE obj, VALUE move)
{
- VALUE selector = ractor_selector_create(klass);
-
- for (int i=0; i<argc; i++) {
- ractor_selector_add(selector, ractors[i]);
- }
-
- return selector;
+ VALUE ret_r;
+ ractor_select(ec, NULL, 0, obj, RTEST(move) ? true : false, &ret_r);
+ return Qnil;
}
static VALUE
-ractor_select_internal(rb_execution_context_t *ec, VALUE self, VALUE ractors, VALUE do_receive, VALUE do_yield, VALUE yield_value, VALUE move)
+ractor_take(rb_execution_context_t *ec, rb_ractor_t *r)
{
- VALUE selector = ractor_selector_new(RARRAY_LENINT(ractors), (VALUE *)RARRAY_CONST_PTR(ractors), rb_cRactorSelector);
- VALUE result;
- int state;
-
- EC_PUSH_TAG(ec);
- if ((state = EC_EXEC_TAG() == TAG_NONE)) {
- result = ractor_selector__wait(selector, do_receive, do_yield, yield_value, move);
- }
- else {
- // ensure
- ractor_selector_clear(selector);
-
- // jump
- EC_JUMP_TAG(ec, state);
- }
- EC_POP_TAG();
-
- RB_GC_GUARD(ractors);
- return result;
+ VALUE ret_r;
+ VALUE v = ractor_select(ec, &r->pub.self, 1, Qundef, false, &ret_r);
+ return v;
}
-// Ractor#close_incoming
-
static VALUE
ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r)
{
@@ -1833,7 +1356,7 @@ ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r)
prev = Qfalse;
r->sync.incoming_port_closed = true;
if (ractor_wakeup(r, wait_receiving, wakeup_by_close)) {
- VM_ASSERT(ractor_queue_empty_p(r, &r->sync.recv_queue));
+ VM_ASSERT(r->sync.incoming_queue.cnt == 0);
RUBY_DEBUG_LOG("cancel receiving");
}
}
@@ -1845,8 +1368,6 @@ ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r)
return prev;
}
-// Ractor#close_outgoing
-
static VALUE
ractor_close_outgoing(rb_execution_context_t *ec, rb_ractor_t *r)
{
@@ -1854,50 +1375,27 @@ ractor_close_outgoing(rb_execution_context_t *ec, rb_ractor_t *r)
RACTOR_LOCK(r);
{
- struct rb_ractor_queue *ts = &r->sync.takers_queue;
- rb_ractor_t *tr;
- struct rb_ractor_basket b;
-
if (!r->sync.outgoing_port_closed) {
prev = Qfalse;
r->sync.outgoing_port_closed = true;
}
else {
- VM_ASSERT(ractor_queue_empty_p(r, ts));
prev = Qtrue;
}
// wakeup all taking ractors
- while (ractor_queue_deq(r, ts, &b)) {
- if (basket_type_p(&b, basket_type_take_basket)) {
- tr = RACTOR_PTR(b.sender);
- struct rb_ractor_basket *tb = b.p.take.basket;
-
- if (RUBY_ATOMIC_CAS(tb->type.atomic, basket_type_none, basket_type_yielding) == basket_type_none) {
- b.p.take.basket->sender = r->pub.self;
- if (RUBY_ATOMIC_CAS(tb->type.atomic, basket_type_yielding, basket_type_deleted) != basket_type_yielding) {
- rb_bug("unreachable");
- }
- RUBY_DEBUG_LOG("set delete for r:%u", rb_ractor_id(RACTOR_PTR(b.sender)));
- }
-
- if (b.p.take.config) {
- b.p.take.config->closed = true;
- }
-
- // TODO: deadlock-able?
- RACTOR_LOCK(tr);
- {
- ractor_wakeup(tr, wait_taking, wakeup_by_close);
- }
- RACTOR_UNLOCK(tr);
- }
+ rb_ractor_t *taking_ractor;
+ while ((taking_ractor = ractor_waiting_list_shift(r, &r->sync.taking_ractors)) != NULL) {
+ RACTOR_LOCK(taking_ractor);
+ ractor_wakeup(taking_ractor, wait_taking, wakeup_by_close);
+ RACTOR_UNLOCK(taking_ractor);
}
// raising yielding Ractor
- ractor_wakeup(r, wait_yielding, wakeup_by_close);
-
- VM_ASSERT(ractor_queue_empty_p(r, ts));
+ if (!r->yield_atexit &&
+ ractor_wakeup(r, wait_yielding, wakeup_by_close)) {
+ RUBY_DEBUG_LOG("cancel yielding");
+ }
}
RACTOR_UNLOCK(r);
return prev;
@@ -1934,6 +1432,7 @@ cancel_single_ractor_mode(void)
VALUE was_disabled = rb_gc_enable();
rb_gc_start();
+ rb_transient_heap_evacuate();
if (was_disabled) {
rb_gc_disable();
@@ -2045,7 +1544,7 @@ rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th)
}
#endif
-void rb_thread_sched_init(struct rb_thread_sched *, bool atfork);
+void rb_thread_sched_init(struct rb_thread_sched *);
void
rb_ractor_living_threads_init(rb_ractor_t *r)
@@ -2058,18 +1557,13 @@ rb_ractor_living_threads_init(rb_ractor_t *r)
static void
ractor_init(rb_ractor_t *r, VALUE name, VALUE loc)
{
- ractor_queue_setup(&r->sync.recv_queue);
- ractor_queue_setup(&r->sync.takers_queue);
+ ractor_queue_setup(&r->sync.incoming_queue);
rb_native_mutex_initialize(&r->sync.lock);
- rb_native_cond_initialize(&r->barrier_wait_cond);
-
-#ifdef RUBY_THREAD_WIN32_H
rb_native_cond_initialize(&r->sync.cond);
rb_native_cond_initialize(&r->barrier_wait_cond);
-#endif
// thread management
- rb_thread_sched_init(&r->threads.sched, false);
+ rb_thread_sched_init(&r->threads.sched);
rb_ractor_living_threads_init(r);
// naming
@@ -2113,7 +1607,7 @@ ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VAL
r->debug = cr->debug;
rb_yjit_before_ractor_spawn();
- rb_rjit_before_ractor_spawn();
+ rb_mjit_before_ractor_spawn();
rb_thread_create_ractor(r, args, block);
RB_GC_GUARD(rv);
@@ -2129,23 +1623,28 @@ ractor_yield_atexit(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool e
ASSERT_ractor_unlocking(cr);
- struct rb_ractor_queue *ts = &cr->sync.takers_queue;
+ struct rb_ractor_basket basket;
+ ractor_basket_setup(ec, &basket, v, Qfalse, exc, true, true /* this flag is ignored because move is Qfalse */);
retry:
- if (ractor_try_yield(ec, cr, ts, v, Qfalse, exc, true)) {
+ if (ractor_try_yield(ec, cr, &basket)) {
// OK.
}
else {
bool retry = false;
RACTOR_LOCK(cr);
{
- if (!ractor_check_take_basket(cr, ts)) {
+ if (cr->sync.taking_ractors.cnt == 0) {
+ cr->sync.wait.yielded_basket = basket;
+
VM_ASSERT(cr->sync.wait.status == wait_none);
- RUBY_DEBUG_LOG("leave a will");
- ractor_basket_fill_will(cr, &cr->sync.will_basket, v, exc);
+ cr->sync.wait.status = wait_yielding;
+ cr->sync.wait.wakeup_status = wakeup_none;
+
+ VM_ASSERT(cr->yield_atexit == false);
+ cr->yield_atexit = true;
}
else {
- RUBY_DEBUG_LOG("rare timing!");
retry = true; // another ractor is waiting for the yield.
}
}
@@ -2156,20 +1655,6 @@ ractor_yield_atexit(rb_execution_context_t *ec, rb_ractor_t *cr, VALUE v, bool e
}
void
-rb_ractor_atexit(rb_execution_context_t *ec, VALUE result)
-{
- rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
- ractor_yield_atexit(ec, cr, result, false);
-}
-
-void
-rb_ractor_atexit_exception(rb_execution_context_t *ec)
-{
- rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
- ractor_yield_atexit(ec, cr, ec->errinfo, true);
-}
-
-void
rb_ractor_teardown(rb_execution_context_t *ec)
{
rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
@@ -2186,6 +1671,20 @@ rb_ractor_teardown(rb_execution_context_t *ec)
}
void
+rb_ractor_atexit(rb_execution_context_t *ec, VALUE result)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ractor_yield_atexit(ec, cr, result, false);
+}
+
+void
+rb_ractor_atexit_exception(rb_execution_context_t *ec)
+{
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ ractor_yield_atexit(ec, cr, ec->errinfo, true);
+}
+
+void
rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *r, int len, VALUE *ptr)
{
for (int i=0; i<len; i++) {
@@ -2202,7 +1701,7 @@ rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *r, VALUE args
}
}
-bool
+MJIT_FUNC_EXPORTED bool
rb_ractor_main_p_(void)
{
VM_ASSERT(rb_multi_ractor_p());
@@ -2224,24 +1723,35 @@ rb_ractor_living_thread_num(const rb_ractor_t *r)
return r->threads.cnt;
}
-// only for current ractor
VALUE
-rb_ractor_thread_list(void)
+rb_ractor_thread_list(rb_ractor_t *r)
{
- rb_ractor_t *r = GET_RACTOR();
rb_thread_t *th = 0;
- VALUE ary = rb_ary_new();
+ VALUE *ts;
+ int ts_cnt;
- ccan_list_for_each(&r->threads.set, th, lt_node) {
- switch (th->status) {
- case THREAD_RUNNABLE:
- case THREAD_STOPPED:
- case THREAD_STOPPED_FOREVER:
- rb_ary_push(ary, th->self);
- default:
- break;
+ RACTOR_LOCK(r);
+ {
+ ts = ALLOCA_N(VALUE, r->threads.cnt);
+ ts_cnt = 0;
+
+ ccan_list_for_each(&r->threads.set, th, lt_node) {
+ switch (th->status) {
+ case THREAD_RUNNABLE:
+ case THREAD_STOPPED:
+ case THREAD_STOPPED_FOREVER:
+ ts[ts_cnt++] = th->self;
+ default:
+ break;
+ }
}
}
+ RACTOR_UNLOCK(r);
+
+ VALUE ary = rb_ary_new();
+ for (int i=0; i<ts_cnt; i++) {
+ rb_ary_push(ary, ts[i]);
+ }
return ary;
}
@@ -2324,8 +1834,6 @@ ractor_check_blocking(rb_ractor_t *cr, unsigned int remained_thread_cnt, const c
}
}
-void rb_threadptr_remove(rb_thread_t *th);
-
void
rb_ractor_living_threads_remove(rb_ractor_t *cr, rb_thread_t *th)
{
@@ -2333,8 +1841,6 @@ rb_ractor_living_threads_remove(rb_ractor_t *cr, rb_thread_t *th)
RUBY_DEBUG_LOG("r->threads.cnt:%d--", cr->threads.cnt);
ractor_check_blocking(cr, cr->threads.cnt - 1, __FILE__, __LINE__);
- rb_threadptr_remove(th);
-
if (cr->threads.cnt == 1) {
vm_remove_ractor(th->vm, cr);
}
@@ -2430,31 +1936,23 @@ ractor_terminal_interrupt_all(rb_vm_t *vm)
rb_ractor_t *r = 0;
ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
if (r != vm->ractor.main_ractor) {
- RUBY_DEBUG_LOG("r:%d", rb_ractor_id(r));
rb_ractor_terminate_interrupt_main_thread(r);
}
}
}
}
-void rb_add_running_thread(rb_thread_t *th);
-void rb_del_running_thread(rb_thread_t *th);
-
void
rb_ractor_terminate_all(void)
{
rb_vm_t *vm = GET_VM();
rb_ractor_t *cr = vm->ractor.main_ractor;
- RUBY_DEBUG_LOG("ractor.cnt:%d", (int)vm->ractor.cnt);
-
VM_ASSERT(cr == GET_RACTOR()); // only main-ractor's main-thread should kick it.
if (vm->ractor.cnt > 1) {
RB_VM_LOCK();
- {
- ractor_terminal_interrupt_all(vm); // kill all ractors
- }
+ ractor_terminal_interrupt_all(vm); // kill all ractors
RB_VM_UNLOCK();
}
rb_thread_terminate_all(GET_THREAD()); // kill other threads in main-ractor and wait
@@ -2467,9 +1965,7 @@ rb_ractor_terminate_all(void)
// wait for 1sec
rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
- rb_del_running_thread(rb_ec_thread_ptr(cr->threads.running_ec));
rb_vm_cond_timedwait(vm, &vm->ractor.sync.terminate_cond, 1000 /* ms */);
- rb_add_running_thread(rb_ec_thread_ptr(cr->threads.running_ec));
rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
ractor_terminal_interrupt_all(vm);
@@ -2481,23 +1977,7 @@ rb_ractor_terminate_all(void)
rb_execution_context_t *
rb_vm_main_ractor_ec(rb_vm_t *vm)
{
- /* This code needs to carefully work around two bugs:
- * - Bug #20016: When M:N threading is enabled, running_ec is NULL if no thread is
- * actually currently running (as opposed to without M:N threading, when
- * running_ec will still point to the _last_ thread which ran)
- * - Bug #20197: If the main thread is sleeping, setting its postponed job
- * interrupt flag is pointless; it won't look at the flag until it stops sleeping
- * for some reason. It would be better to set the flag on the running ec, which
- * will presumably look at it soon.
- *
- * Solution: use running_ec if it's set, otherwise fall back to the main thread ec.
- * This is still susceptible to some rare race conditions (what if the last thread
- * to run just entered a long-running sleep?), but seems like the best balance of
- * robustness and complexity.
- */
- rb_execution_context_t *running_ec = vm->ractor.main_ractor->threads.running_ec;
- if (running_ec) { return running_ec; }
- return vm->ractor.main_thread->ec;
+ return vm->ractor.main_ractor->threads.running_ec;
}
static VALUE
@@ -2506,29 +1986,6 @@ ractor_moved_missing(int argc, VALUE *argv, VALUE self)
rb_raise(rb_eRactorMovedError, "can not send any methods to a moved object");
}
-#ifndef USE_RACTOR_SELECTOR
-#define USE_RACTOR_SELECTOR 0
-#endif
-
-RUBY_SYMBOL_EXPORT_BEGIN
-void rb_init_ractor_selector(void);
-RUBY_SYMBOL_EXPORT_END
-
-void
-rb_init_ractor_selector(void)
-{
- rb_cRactorSelector = rb_define_class_under(rb_cRactor, "Selector", rb_cObject);
- rb_undef_alloc_func(rb_cRactorSelector);
-
- rb_define_singleton_method(rb_cRactorSelector, "new", ractor_selector_new , -1);
- rb_define_method(rb_cRactorSelector, "add", ractor_selector_add, 1);
- rb_define_method(rb_cRactorSelector, "remove", ractor_selector_remove, 1);
- rb_define_method(rb_cRactorSelector, "clear", ractor_selector_clear, 0);
- rb_define_method(rb_cRactorSelector, "empty?", ractor_selector_empty_p, 0);
- rb_define_method(rb_cRactorSelector, "wait", ractor_selector_wait, -1);
- rb_define_method(rb_cRactorSelector, "_wait", ractor_selector__wait, 4);
-}
-
/*
* Document-class: Ractor::ClosedError
*
@@ -2648,10 +2105,6 @@ Init_Ractor(void)
rb_define_method(rb_cRactorMovedObject, "equal?", ractor_moved_missing, -1);
rb_define_method(rb_cRactorMovedObject, "instance_eval", ractor_moved_missing, -1);
rb_define_method(rb_cRactorMovedObject, "instance_exec", ractor_moved_missing, -1);
-
-#if USE_RACTOR_SELECTOR
- rb_init_ractor_selector();
-#endif
}
void
@@ -2797,6 +2250,19 @@ obj_hash_traverse_i(VALUE key, VALUE val, VALUE ptr)
return ST_CONTINUE;
}
+static int
+obj_hash_iv_traverse_i(st_data_t key, st_data_t val, st_data_t ptr)
+{
+ struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr;
+
+ if (obj_traverse_i((VALUE)val, d->data)) {
+ d->stop = true;
+ return ST_STOP;
+ }
+
+ return ST_CONTINUE;
+}
+
static void
obj_traverse_reachable_i(VALUE obj, void *ptr)
{
@@ -2812,25 +2278,12 @@ obj_traverse_rec(struct obj_traverse_data *data)
{
if (UNLIKELY(!data->rec)) {
data->rec_hash = rb_ident_hash_new();
- data->rec = RHASH_ST_TABLE(data->rec_hash);
+ data->rec = rb_hash_st_table(data->rec_hash);
}
return data->rec;
}
static int
-obj_traverse_ivar_foreach_i(ID key, VALUE val, st_data_t ptr)
-{
- struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr;
-
- if (obj_traverse_i(val, d->data)) {
- d->stop = true;
- return ST_STOP;
- }
-
- return ST_CONTINUE;
-}
-
-static int
obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
{
if (RB_SPECIAL_CONST_P(obj)) return 0;
@@ -2846,12 +2299,14 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
return 0;
}
- struct obj_traverse_callback_data d = {
- .stop = false,
- .data = data,
- };
- rb_ivar_foreach(obj, obj_traverse_ivar_foreach_i, (st_data_t)&d);
- if (d.stop) return 1;
+ if (UNLIKELY(FL_TEST_RAW(obj, FL_EXIVAR))) {
+ struct gen_ivtbl *ivtbl;
+ rb_ivar_generic_ivtbl_lookup(obj, &ivtbl);
+ for (uint32_t i = 0; i < ivtbl->numiv; i++) {
+ VALUE val = ivtbl->ivptr[i];
+ if (!UNDEF_P(val) && obj_traverse_i(val, data)) return 1;
+ }
+ }
switch (BUILTIN_TYPE(obj)) {
// no child node
@@ -2865,7 +2320,25 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
break;
case T_OBJECT:
- /* Instance variables already traversed. */
+ {
+ if (rb_shape_obj_too_complex(obj)) {
+ struct obj_traverse_callback_data d = {
+ .stop = false,
+ .data = data,
+ };
+ rb_st_foreach(ROBJECT_IV_HASH(obj), obj_hash_iv_traverse_i, (st_data_t)&d);
+ if (d.stop) return 1;
+ }
+ else {
+ uint32_t len = ROBJECT_IV_COUNT(obj);
+ VALUE *ptr = ROBJECT_IVPTR(obj);
+
+ for (uint32_t i=0; i<len; i++) {
+ VALUE val = ptr[i];
+ if (!UNDEF_P(val) && obj_traverse_i(val, data)) return 1;
+ }
+ }
+ }
break;
case T_ARRAY:
@@ -3058,7 +2531,10 @@ VALUE
rb_ractor_make_shareable_copy(VALUE obj)
{
VALUE copy = ractor_copy(obj);
- return rb_ractor_make_shareable(copy);
+ rb_obj_traverse(copy,
+ make_shareable_check_shareable,
+ null_leave, mark_shareable);
+ return copy;
}
VALUE
@@ -3101,7 +2577,7 @@ shareable_p_enter(VALUE obj)
return traverse_stop; // fail
}
-bool
+MJIT_FUNC_EXPORTED bool
rb_ractor_shareable_p_continue(VALUE obj)
{
if (rb_obj_traverse(obj,
@@ -3234,18 +2710,25 @@ obj_traverse_replace_rec(struct obj_traverse_replace_data *data)
{
if (UNLIKELY(!data->rec)) {
data->rec_hash = rb_ident_hash_new();
- data->rec = RHASH_ST_TABLE(data->rec_hash);
+ data->rec = rb_hash_st_table(data->rec_hash);
}
return data->rec;
}
+#if USE_TRANSIENT_HEAP
+void rb_ary_transient_heap_evacuate(VALUE ary, int promote);
+void rb_obj_transient_heap_evacuate(VALUE obj, int promote);
+void rb_hash_transient_heap_evacuate(VALUE hash, int promote);
+void rb_struct_transient_heap_evacuate(VALUE st, int promote);
+#endif
+
static void
obj_refer_only_shareables_p_i(VALUE obj, void *ptr)
{
int *pcnt = (int *)ptr;
if (!rb_ractor_shareable_p(obj)) {
- ++*pcnt;
+ *pcnt++;
}
}
@@ -3300,26 +2783,9 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
if (UNLIKELY(FL_TEST_RAW(obj, FL_EXIVAR))) {
struct gen_ivtbl *ivtbl;
rb_ivar_generic_ivtbl_lookup(obj, &ivtbl);
-
- if (UNLIKELY(rb_shape_obj_too_complex(obj))) {
- struct obj_traverse_replace_callback_data d = {
- .stop = false,
- .data = data,
- .src = obj,
- };
- rb_st_foreach_with_replace(
- ivtbl->as.complex.table,
- obj_iv_hash_traverse_replace_foreach_i,
- obj_iv_hash_traverse_replace_i,
- (st_data_t)&d
- );
- if (d.stop) return 1;
- }
- else {
- for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) {
- if (!UNDEF_P(ivtbl->as.shape.ivptr[i])) {
- CHECK_AND_REPLACE(ivtbl->as.shape.ivptr[i]);
- }
+ for (uint32_t i = 0; i < ivtbl->numiv; i++) {
+ if (!UNDEF_P(ivtbl->ivptr[i])) {
+ CHECK_AND_REPLACE(ivtbl->ivptr[i]);
}
}
}
@@ -3340,25 +2806,30 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
case T_OBJECT:
{
if (rb_shape_obj_too_complex(obj)) {
+ st_table * table = ROBJECT_IV_HASH(obj);
struct obj_traverse_replace_callback_data d = {
.stop = false,
.data = data,
.src = obj,
};
rb_st_foreach_with_replace(
- ROBJECT_IV_HASH(obj),
- obj_iv_hash_traverse_replace_foreach_i,
- obj_iv_hash_traverse_replace_i,
- (st_data_t)&d
- );
- if (d.stop) return 1;
+ table,
+ obj_iv_hash_traverse_replace_foreach_i,
+ obj_iv_hash_traverse_replace_i,
+ (st_data_t)&d);
}
else {
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_obj_transient_heap_evacuate(obj, TRUE);
+#endif
+
uint32_t len = ROBJECT_IV_COUNT(obj);
VALUE *ptr = ROBJECT_IVPTR(obj);
- for (uint32_t i = 0; i < len; i++) {
- CHECK_AND_REPLACE(ptr[i]);
+ for (uint32_t i=0; i<len; i++) {
+ if (!UNDEF_P(ptr[i])) {
+ CHECK_AND_REPLACE(ptr[i]);
+ }
}
}
}
@@ -3367,6 +2838,9 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
case T_ARRAY:
{
rb_ary_cancel_sharing(obj);
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_ary_transient_heap_evacuate(obj, TRUE);
+#endif
for (int i = 0; i < RARRAY_LENINT(obj); i++) {
VALUE e = rb_ary_entry(obj, i);
@@ -3381,8 +2855,12 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
RB_GC_GUARD(obj);
}
break;
+
case T_HASH:
{
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_hash_transient_heap_evacuate(obj, TRUE);
+#endif
struct obj_traverse_replace_callback_data d = {
.stop = false,
.data = data,
@@ -3407,6 +2885,9 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
case T_STRUCT:
{
+#if USE_TRANSIENT_HEAP
+ if (data->move) rb_struct_transient_heap_evacuate(obj, TRUE);
+#endif
long len = RSTRUCT_LEN(obj);
const VALUE *ptr = RSTRUCT_CONST_PTR(obj);
@@ -3507,8 +2988,6 @@ ractor_moved_bang(VALUE obj)
rv->v3 = 0;
rv->flags = rv->flags & ~fl_users;
- if (BUILTIN_TYPE(obj) == T_OBJECT) ROBJECT_SET_SHAPE_ID(obj, ROOT_SHAPE_ID);
-
// TODO: record moved location
}
diff --git a/ractor.rb b/ractor.rb
index d18062ca07..1031fe499b 100644
--- a/ractor.rb
+++ b/ractor.rb
@@ -1,56 +1,51 @@
-# \Ractor is an Actor-model abstraction for Ruby that provides thread-safe parallel execution.
+# Ractor is an Actor-model abstraction for Ruby that provides thread-safe parallel execution.
#
-# Ractor.new makes a new \Ractor, which can run in parallel.
+# Ractor.new can make a new Ractor, and it will run in parallel.
#
# # The simplest ractor
# r = Ractor.new {puts "I am in Ractor!"}
# r.take # wait for it to finish
-# # Here, "I am in Ractor!" is printed
+# # here "I am in Ractor!" would be printed
#
-# Ractors do not share all objects with each other. There are two main benefits to this: across ractors, thread-safety
-# concerns such as data-races and race-conditions are not possible. The other benefit is parallelism.
+# Ractors do not share usual objects, so the same kinds of thread-safety concerns such as data-race,
+# race-conditions are not available on multi-ractor programming.
#
-# To achieve this, object sharing is limited across ractors.
-# For example, unlike in threads, ractors can't access all the objects available in other ractors. Even objects normally
-# available through variables in the outer scope are prohibited from being used across ractors.
+# To achieve this, ractors severely limit object sharing between different ractors.
+# For example, unlike threads, ractors can't access each other's objects, nor any objects through
+# variables of the outer scope.
#
# a = 1
# r = Ractor.new {puts "I am in Ractor! a=#{a}"}
# # fails immediately with
# # ArgumentError (can not isolate a Proc because it accesses outer variables (a).)
#
-# The object must be explicitly shared:
-# a = 1
-# r = Ractor.new(a) { |a1| puts "I am in Ractor! a=#{a1}"}
-#
# On CRuby (the default implementation), Global Virtual Machine Lock (GVL) is held per ractor, so
-# ractors can perform in parallel without locking each other. This is unlike the situation with threads
-# on CRuby.
+# ractors are performed in parallel without locking each other.
#
-# Instead of accessing shared state, objects should be passed to and from ractors by
-# sending and receiving them as messages.
+# Instead of accessing the shared state, the objects should be passed to and from ractors via
+# sending and receiving objects as messages.
#
# a = 1
# r = Ractor.new do
-# a_in_ractor = receive # receive blocks until somebody passes a message
+# a_in_ractor = receive # receive blocks till somebody will pass message
# puts "I am in Ractor! a=#{a_in_ractor}"
# end
# r.send(a) # pass it
# r.take
-# # Here, "I am in Ractor! a=1" is printed
+# # here "I am in Ractor! a=1" would be printed
#
# There are two pairs of methods for sending/receiving messages:
#
# * Ractor#send and Ractor.receive for when the _sender_ knows the receiver (push);
# * Ractor.yield and Ractor#take for when the _receiver_ knows the sender (pull);
#
-# In addition to that, any arguments passed to Ractor.new are passed to the block and available there
-# as if received by Ractor.receive, and the last block value is sent outside of the
+# In addition to that, an argument to Ractor.new would be passed to block and available there
+# as if received by Ractor.receive, and the last block value would be sent outside of the
# ractor as if sent by Ractor.yield.
#
-# A little demonstration of a classic ping-pong:
+# A little demonstration on a classic ping-pong:
#
-# server = Ractor.new(name: "server") do
+# server = Ractor.new do
# puts "Server starts: #{self.inspect}"
# puts "Server sends: ping"
# Ractor.yield 'ping' # The server doesn't know the receiver and sends to whoever interested
@@ -58,48 +53,44 @@
# puts "Server received: #{received}"
# end
#
-# client = Ractor.new(server) do |srv| # The server is sent to the client, and available as srv
+# client = Ractor.new(server) do |srv| # The server is sent inside client, and available as srv
# puts "Client starts: #{self.inspect}"
-# received = srv.take # The client takes a message from the server
+# received = srv.take # The Client takes a message specifically from the server
# puts "Client received from " \
# "#{srv.inspect}: #{received}"
# puts "Client sends to " \
# "#{srv.inspect}: pong"
-# srv.send 'pong' # The client sends a message to the server
+# srv.send 'pong' # The client sends a message specifically to the server
# end
#
-# [client, server].each(&:take) # Wait until they both finish
+# [client, server].each(&:take) # Wait till they both finish
#
-# This will output something like:
+# This will output:
#
-# Server starts: #<Ractor:#2 server test.rb:1 running>
+# Server starts: #<Ractor:#2 test.rb:1 running>
# Server sends: ping
# Client starts: #<Ractor:#3 test.rb:8 running>
-# Client received from #<Ractor:#2 server test.rb:1 blocking>: ping
-# Client sends to #<Ractor:#2 server test.rb:1 blocking>: pong
+# Client received from #<Ractor:#2 rac.rb:1 blocking>: ping
+# Client sends to #<Ractor:#2 rac.rb:1 blocking>: pong
# Server received: pong
#
-# Ractors receive their messages via the <em>incoming port</em>, and send them
+# It is said that Ractor receives messages via the <em>incoming port</em>, and sends them
# to the <em>outgoing port</em>. Either one can be disabled with Ractor#close_incoming and
-# Ractor#close_outgoing, respectively. When a ractor terminates, its ports are closed
+# Ractor#close_outgoing respectively. If a ractor terminated, its ports will be closed
# automatically.
#
# == Shareable and unshareable objects
#
-# When an object is sent to and from a ractor, it's important to understand whether the
-# object is shareable or unshareable. Most Ruby objects are unshareable objects. Even
-# frozen objects can be unshareable if they contain (through their instance variables) unfrozen
-# objects.
+# When the object is sent to and from the ractor, it is important to understand whether the
+# object is shareable or unshareable. Most of objects are unshareable objects.
#
-# Shareable objects are those which can be used by several threads without compromising
-# thread-safety, for example numbers, +true+ and +false+. Ractor.shareable? allows you to check this,
-# and Ractor.make_shareable tries to make the object shareable if it's not already, and gives an error
-# if it can't do it.
+# Shareable objects are basically those which can be used by several threads without compromising
+# thread-safety; e.g. immutable ones. Ractor.shareable? allows to check this, and Ractor.make_shareable
+# tries to make object shareable if it is not.
#
-# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are shareable
-# Ractor.shareable?('foo') #=> false, unless the string is frozen due to # frozen_string_literal: true
+# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are
+# Ractor.shareable?('foo') #=> false, unless the string is frozen due to # freeze_string_literals: true
# Ractor.shareable?('foo'.freeze) #=> true
-# Ractor.shareable?([Object.new].freeze) #=> false, inner object is unfrozen
#
# ary = ['hello', 'world']
# ary.frozen? #=> false
@@ -109,10 +100,10 @@
# ary[0].frozen? #=> true
# ary[1].frozen? #=> true
#
-# When a shareable object is sent (via #send or Ractor.yield), no additional processing occurs
-# on it. It just becomes usable by both ractors. When an unshareable object is sent, it can be
-# either _copied_ or _moved_. The first is the default, and it copies the object fully by
-# deep cloning (Object#clone) the non-shareable parts of its structure.
+# When a shareable object is sent (via #send or Ractor.yield), no additional processing happens,
+# and it just becomes usable by both ractors. When an unshareable object is sent, it can be
+# either _copied_ or _moved_. The first is the default, and it makes the object's full copy by
+# deep cloning of non-shareable parts of its structure.
#
# data = ['foo', 'bar'.freeze]
# r = Ractor.new do
@@ -123,18 +114,18 @@
# r.take
# puts "Outside : #{data.object_id}, #{data[0].object_id}, #{data[1].object_id}"
#
-# This will output something like:
+# This will output:
#
# In ractor: 340, 360, 320
# Outside : 380, 400, 320
#
-# Note that the object ids of the array and the non-frozen string inside the array have changed in
-# the ractor because they are different objects. The second array's element, which is a
-# shareable frozen string, is the same object.
+# (Note that object id of both array and non-frozen string inside array have changed inside
+# the ractor, showing it is different objects. But the second array's element, which is a
+# shareable frozen string, has the same object_id.)
#
-# Deep cloning of objects may be slow, and sometimes impossible. Alternatively, <tt>move: true</tt> may
-# be used during sending. This will <em>move</em> the unshareable object to the receiving ractor, making it
-# inaccessible to the sending ractor.
+# Deep cloning of the objects may be slow, and sometimes impossible. Alternatively,
+# <tt>move: true</tt> may be used on sending. This will <em>move</em> the object to the
+# receiving ractor, making it inaccessible for a sending ractor.
#
# data = ['foo', 'bar']
# r = Ractor.new do
@@ -155,14 +146,13 @@
# Notice that even +inspect+ (and more basic methods like <tt>__id__</tt>) is inaccessible
# on a moved object.
#
-# Class and Module objects are shareable so the class/module definitions are shared between ractors.
-# \Ractor objects are also shareable. All operations on shareable objects are thread-safe, so the thread-safety property
+# Besides frozen objects, there are shareable objects. Class and Module objects are shareable so
+# the Class/Module definitions are shared between ractors. Ractor objects are also shareable objects.
+# All operations for the shareable mutable objects are thread-safe, so the thread-safety property
# will be kept. We can not define mutable shareable objects in Ruby, but C extensions can introduce them.
#
-# It is prohibited to access (get) instance variables of shareable objects in other ractors if the values of the
-# variables aren't shareable. This can occur because modules/classes are shareable, but they can have
-# instance variables whose values are not. In non-main ractors, it's also prohibited to set instance
-# variables on classes/modules (even if the value is shareable).
+# It is prohibited to access instance variables of mutable shareable objects (especially Modules and classes)
+# from ractors other than main:
#
# class C
# class << self
@@ -170,22 +160,21 @@
# end
# end
#
-# C.tricky = "unshareable".dup
+# C.tricky = 'test'
#
# r = Ractor.new(C) do |cls|
# puts "I see #{cls}"
# puts "I can't see #{cls.tricky}"
-# cls.tricky = true # doesn't get here, but this would also raise an error
# end
# r.take
# # I see C
# # can not access instance variables of classes/modules from non-main Ractors (RuntimeError)
#
-# Ractors can access constants if they are shareable. The main \Ractor is the only one that can
+# Ractors can access constants if they are shareable. The main Ractor is the only one that can
# access non-shareable constants.
#
# GOOD = 'good'.freeze
-# BAD = 'bad'.dup
+# BAD = 'bad'
#
# r = Ractor.new do
# puts "GOOD=#{GOOD}"
@@ -210,8 +199,8 @@
#
# == Ractors vs threads
#
-# Each ractor has its own main Thread. New threads can be created from inside ractors
-# (and, on CRuby, they share the GVL with other threads of this ractor).
+# Each ractor creates its own thread. New threads can be created from inside ractor
+# (and, on CRuby, sharing GVL with other threads of this ractor).
#
# r = Ractor.new do
# a = 1
@@ -222,15 +211,15 @@
#
# == Note on code examples
#
-# In the examples below, sometimes we use the following method to wait for ractors that
-# are not currently blocked to finish (or to make progress).
+# In examples below, sometimes we use the following method to wait till ractors that
+# are not currently blocked will finish (or process till next blocking) method.
#
# def wait
# sleep(0.1)
# end
#
# It is **only for demonstration purposes** and shouldn't be used in a real code.
-# Most of the time, #take is used to wait for ractors to finish.
+# Most of the times, just #take is used to wait till ractor will finish.
#
# == Reference
#
@@ -241,17 +230,17 @@ class Ractor
# call-seq:
# Ractor.new(*args, name: nil) {|*args| block } -> ractor
#
- # Create a new \Ractor with args and a block.
+ # Create a new Ractor with args and a block.
#
- # The given block (Proc) will be isolated (can't access any outer variables). +self+
- # inside the block will refer to the current \Ractor.
+ # A block (Proc) will be isolated (can't access to outer variables). +self+
+ # inside the block will refer to the current Ractor.
#
# r = Ractor.new { puts "Hi, I am #{self.inspect}" }
# r.take
# # Prints "Hi, I am #<Ractor:#2 test.rb:1 running>"
#
- # Any +args+ passed are propagated to the block arguments by the same rules as
- # objects sent via #send/Ractor.receive. If an argument in +args+ is not shareable, it
+ # +args+ passed to the method would be propagated to block args by the same rules as
+ # objects passed through #send/Ractor.receive: if +args+ are not shareable, they
# will be copied (via deep cloning, which might be inefficient).
#
# arg = [1, 2, 3]
@@ -266,7 +255,7 @@ class Ractor
#
# Ractor's +name+ can be set for debugging purposes:
#
- # r = Ractor.new(name: 'my ractor') {}; r.take
+ # r = Ractor.new(name: 'my ractor') {}
# p r
# #=> #<Ractor:#3 my ractor test.rb:1 terminated>
#
@@ -291,13 +280,13 @@ class Ractor
}
end
- # Returns the number of Ractors currently running or blocking (waiting).
+ # Returns total count of Ractors currently running.
#
# Ractor.count #=> 1
# r = Ractor.new(name: 'example') { Ractor.yield(1) }
# Ractor.count #=> 2 (main + example ractor)
# r.take # wait for Ractor.yield(1)
- # r.take # wait until r will finish
+ # r.take # wait till r will finish
# Ractor.count #=> 1
def self.count
__builtin_cexpr! %q{
@@ -309,8 +298,8 @@ class Ractor
# call-seq:
# Ractor.select(*ractors, [yield_value:, move: false]) -> [ractor or symbol, obj]
#
- # Wait for any ractor to have something in its outgoing port, read from this ractor, and
- # then return that ractor and the object received.
+ # Waits for the first ractor to have something in its outgoing port, reads from this ractor, and
+ # returns that ractor and the object received.
#
# r1 = Ractor.new {Ractor.yield 'from 1'}
# r2 = Ractor.new {Ractor.yield 'from 2'}
@@ -319,10 +308,9 @@ class Ractor
#
# puts "received #{obj.inspect} from #{r.inspect}"
# # Prints: received "from 1" from #<Ractor:#2 test.rb:1 running>
- # # But could just as well print "from r2" here, either prints could be first.
#
- # If one of the given ractors is the current ractor, and it is selected, +r+ will contain
- # the +:receive+ symbol instead of the ractor object.
+ # If one of the given ractors is the current ractor, and it would be selected, +r+ will contain
+ # +:receive+ symbol instead of the ractor object.
#
# r1 = Ractor.new(Ractor.current) do |main|
# main.send 'to main'
@@ -334,10 +322,10 @@ class Ractor
#
# r, obj = Ractor.select(r1, r2, Ractor.current)
# puts "received #{obj.inspect} from #{r.inspect}"
- # # Could print: received "to main" from :receive
+ # # Prints: received "to main" from :receive
#
- # If +yield_value+ is provided, that value may be yielded if another ractor is calling #take.
- # In this case, the pair <tt>[:yield, nil]</tt> is returned:
+ # If +yield_value+ is provided, that value may be yielded if another Ractor is calling #take.
+ # In this case, the pair <tt>[:yield, nil]</tt> would be returned:
#
# r1 = Ractor.new(Ractor.current) do |main|
# puts "Received from main: #{main.take}"
@@ -354,25 +342,26 @@ class Ractor
# Received from main: 123
# Received nil from :yield
#
- # +move+ boolean flag defines whether yielded value will be copied (default) or moved.
+ # +move+ boolean flag defines whether yielded value should be copied (default) or moved.
def self.select(*ractors, yield_value: yield_unspecified = true, move: false)
raise ArgumentError, 'specify at least one ractor or `yield_value`' if yield_unspecified && ractors.empty?
- if ractors.delete Ractor.current
- do_receive = true
- else
- do_receive = false
- end
-
- __builtin_ractor_select_internal ractors, do_receive, !yield_unspecified, yield_value, move
+ __builtin_cstmt! %q{
+ const VALUE *rs = RARRAY_CONST_PTR_TRANSIENT(ractors);
+ VALUE rv;
+ VALUE v = ractor_select(ec, rs, RARRAY_LENINT(ractors),
+ yield_unspecified == Qtrue ? Qundef : yield_value,
+ (bool)RTEST(move) ? true : false, &rv);
+ return rb_ary_new_from_args(2, rv, v);
+ }
end
#
# call-seq:
# Ractor.receive -> msg
#
- # Receive a message from the incoming port of the current ractor (which was
- # sent there by #send from another ractor).
+ # Receive an incoming message from the current Ractor's incoming port's queue, which was
+ # sent there by #send.
#
# r = Ractor.new do
# v1 = Ractor.receive
@@ -382,7 +371,7 @@ class Ractor
# r.take
# # Here will be printed: "Received: message1"
#
- # Alternatively, the private instance method +receive+ may be used:
+ # Alternatively, private instance method +receive+ may be used:
#
# r = Ractor.new do
# v1 = receive
@@ -390,7 +379,7 @@ class Ractor
# end
# r.send('message1')
# r.take
- # # This prints: "Received: message1"
+ # # Here will be printed: "Received: message1"
#
# The method blocks if the queue is empty.
#
@@ -418,7 +407,7 @@ class Ractor
# Received: message2
#
# If close_incoming was called on the ractor, the method raises Ractor::ClosedError
- # if there are no more messages in the incoming queue:
+ # if there are no more messages in incoming queue:
#
# Ractor.new do
# close_incoming
@@ -451,9 +440,8 @@ class Ractor
#
# Receive only a specific message.
#
- # Instead of Ractor.receive, Ractor.receive_if can be given a pattern (or any
- # filter) in a block and you can choose the messages to accept that are available in
- # your ractor's incoming queue.
+ # Instead of Ractor.receive, Ractor.receive_if can provide a pattern
+ # by a block and you can choose the receiving message.
#
# r = Ractor.new do
# p Ractor.receive_if{|msg| msg.match?(/foo/)} #=> "foo3"
@@ -471,10 +459,10 @@ class Ractor
# bar1
# baz2
#
- # If the block returns a truthy value, the message is removed from the incoming queue
+ # If the block returns a truthy value, the message will be removed from the incoming queue
# and returned.
- # Otherwise, the message remains in the incoming queue and the next messages are checked
- # by the given block.
+ # Otherwise, the message remains in the incoming queue and the following received
+ # messages are checked by the given block.
#
# If there are no messages left in the incoming queue, the method will
# block until new messages arrive.
@@ -500,7 +488,7 @@ class Ractor
# Received successfully: [1, 2, 3]
#
# Note that you can not call receive/receive_if in the given block recursively.
- # You should not do any tasks in the block other than message filtration.
+ # It means that you should not do any tasks in the block.
#
# Ractor.current << true
# Ractor.receive_if{|msg| Ractor.receive}
@@ -510,7 +498,6 @@ class Ractor
Primitive.ractor_receive_if b
end
- # same as Ractor.receive_if
private def receive_if &b
Primitive.ractor_receive_if b
end
@@ -519,7 +506,7 @@ class Ractor
# call-seq:
# ractor.send(msg, move: false) -> self
#
- # Send a message to a Ractor's incoming queue to be accepted by Ractor.receive.
+ # Send a message to a Ractor's incoming queue to be consumed by Ractor.receive.
#
# r = Ractor.new do
# value = Ractor.receive
@@ -536,7 +523,7 @@ class Ractor
# puts "Sent successfully"
# # Prints: "Sent successfully" immediately
#
- # An attempt to send to a ractor which already finished its execution will raise Ractor::ClosedError.
+ # Attempt to send to ractor which already finished its execution will raise Ractor::ClosedError.
#
# r = Ractor.new {}
# r.take
@@ -554,11 +541,11 @@ class Ractor
# r.close_incoming
# r.send('test')
# # Ractor::ClosedError (The incoming-port is already closed)
- # # The error is raised immediately, not when the ractor tries to receive
+ # # The error would be raised immediately, not when ractor will try to receive
#
- # If the +obj+ is unshareable, by default it will be copied into the receiving ractor by deep cloning.
- # If <tt>move: true</tt> is passed, the object is _moved_ into the receiving ractor and becomes
- # inaccessible to the sender.
+ # If the +obj+ is unshareable, by default it would be copied into ractor by deep cloning.
+ # If the <tt>move: true</tt> is passed, object is _moved_ into ractor and becomes
+ # inaccessible to sender.
#
# r = Ractor.new {puts "Received: #{receive}"}
# msg = 'message'
@@ -571,7 +558,7 @@ class Ractor
# Received: message
# in `p': undefined method `inspect' for #<Ractor::MovedObject:0x000055c99b9b69b8>
#
- # All references to the object and its parts will become invalid to the sender.
+ # All references to the object and its parts will become invalid in sender.
#
# r = Ractor.new {puts "Received: #{receive}"}
# s = 'message'
@@ -589,7 +576,7 @@ class Ractor
# # Ractor::MovedError (can not send any methods to a moved object)
# # ...but its item was still a reference to `s`, which was moved
#
- # If the object is shareable, <tt>move: true</tt> has no effect on it:
+ # If the object was shareable, <tt>move: true</tt> has no effect on it:
#
# r = Ractor.new {puts "Received: #{receive}"}
# s = 'message'.freeze
@@ -607,13 +594,13 @@ class Ractor
# call-seq:
# Ractor.yield(msg, move: false) -> nil
#
- # Send a message to the current ractor's outgoing port to be accepted by #take.
+ # Send a message to the current ractor's outgoing port to be consumed by #take.
#
# r = Ractor.new {Ractor.yield 'Hello from ractor'}
# puts r.take
# # Prints: "Hello from ractor"
#
- # This method is blocking, and will return only when somebody consumes the
+ # The method is blocking, and will return only when somebody consumes the
# sent message.
#
# r = Ractor.new do
@@ -639,7 +626,7 @@ class Ractor
# wait
# # `yield': The outgoing-port is already closed (Ractor::ClosedError)
#
- # The meaning of the +move+ argument is the same as for #send.
+ # The meaning of +move+ argument is the same as for #send.
def self.yield(obj, move: false)
__builtin_cexpr! %q{
ractor_yield(ec, rb_ec_ractor_ptr(ec), obj, move)
@@ -650,8 +637,8 @@ class Ractor
# call-seq:
# ractor.take -> msg
#
- # Get a message from the ractor's outgoing port, which was put there by Ractor.yield or at ractor's
- # termination.
+ # Take a message from ractor's outgoing port, which was put there by Ractor.yield or at ractor's
+ # finalization.
#
# r = Ractor.new do
# Ractor.yield 'explicit yield'
@@ -661,9 +648,9 @@ class Ractor
# puts r.take #=> 'last value'
# puts r.take # Ractor::ClosedError (The outgoing-port is already closed)
#
- # The fact that the last value is also sent to the outgoing port means that +take+ can be used
- # as an analog of Thread#join ("just wait until ractor finishes"). However, it will raise if
- # somebody has already consumed that message.
+ # The fact that the last value is also put to outgoing port means that +take+ can be used
+ # as some analog of Thread#join ("just wait till ractor finishes"), but don't forget it
+ # will raise if somebody had already consumed everything ractor have produced.
#
# If the outgoing port was closed with #close_outgoing, the method will raise Ractor::ClosedError.
#
@@ -676,7 +663,7 @@ class Ractor
# # Ractor::ClosedError (The outgoing-port is already closed)
# # The error would be raised immediately, not when ractor will try to receive
#
- # If an uncaught exception is raised in the Ractor, it is propagated by take as a
+ # If an uncaught exception is raised in the Ractor, it is propagated on take as a
# Ractor::RemoteError.
#
# r = Ractor.new {raise "Something weird happened"}
@@ -689,8 +676,8 @@ class Ractor
# p e.cause # => #<RuntimeError: Something weird happened>
# end
#
- # Ractor::ClosedError is a descendant of StopIteration, so the termination of the ractor will break
- # out of any loops that receive this message without propagating the error:
+ # Ractor::ClosedError is a descendant of StopIteration, so the closing of the ractor will break
+ # the loops without propagating the error:
#
# r = Ractor.new do
# 3.times {|i| Ractor.yield "message #{i}"}
@@ -738,8 +725,9 @@ class Ractor
# call-seq:
# ractor.close_incoming -> true | false
#
- # Closes the incoming port and returns whether it was already closed. All further attempts
- # to Ractor.receive in the ractor, and #send to the ractor will fail with Ractor::ClosedError.
+ # Closes the incoming port and returns its previous state.
+ # All further attempts to Ractor.receive in the ractor, and #send to the ractor
+ # will fail with Ractor::ClosedError.
#
# r = Ractor.new {sleep(500)}
# r.close_incoming #=> false
@@ -756,8 +744,9 @@ class Ractor
# call-seq:
# ractor.close_outgoing -> true | false
#
- # Closes the outgoing port and returns whether it was already closed. All further attempts
- # to Ractor.yield in the ractor, and #take from the ractor will fail with Ractor::ClosedError.
+ # Closes the outgoing port and returns its previous state.
+ # All further attempts to Ractor.yield in the ractor, and #take from the ractor
+ # will fail with Ractor::ClosedError.
#
# r = Ractor.new {sleep(500)}
# r.close_outgoing #=> false
@@ -777,10 +766,10 @@ class Ractor
# Checks if the object is shareable by ractors.
#
# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are frozen
- # Ractor.shareable?('foo') #=> false, unless the string is frozen due to # frozen_string_literal: true
+ # Ractor.shareable?('foo') #=> false, unless the string is frozen due to # freeze_string_literals: true
# Ractor.shareable?('foo'.freeze) #=> true
#
- # See also the "Shareable and unshareable objects" section in the \Ractor class docs.
+ # See also the "Shareable and unshareable objects" section in the Ractor class docs.
def self.shareable? obj
__builtin_cexpr! %q{
RBOOL(rb_ractor_shareable_p(obj));
@@ -796,8 +785,8 @@ class Ractor
# +obj+ and all the objects it refers to will be frozen, unless they are
# already shareable.
#
- # If +copy+ keyword is +true+, it will copy objects before freezing them, and will not
- # modify +obj+ or its internal objects.
+ # If +copy+ keyword is +true+, the method will copy objects before freezing them
+ # This is safer option but it can take be slower.
#
# Note that the specification and implementation of this method are not
# mature and may be changed in the future.
diff --git a/ractor_core.h b/ractor_core.h
index 36c0e91c7a..968c12d291 100644
--- a/ractor_core.h
+++ b/ractor_core.h
@@ -1,4 +1,3 @@
-#include "internal/gc.h"
#include "ruby/ruby.h"
#include "ruby/ractor.h"
#include "vm_core.h"
@@ -10,66 +9,22 @@
#endif
enum rb_ractor_basket_type {
- // basket is empty
basket_type_none,
-
- // value is available
basket_type_ref,
basket_type_copy,
basket_type_move,
basket_type_will,
-
- // basket should be deleted
basket_type_deleted,
-
- // basket is reserved
basket_type_reserved,
-
- // take_basket is available
- basket_type_take_basket,
-
- // basket is keeping by yielding ractor
- basket_type_yielding,
-};
-
-// per ractor taking configuration
-struct rb_ractor_selector_take_config {
- bool closed;
- bool oneshot;
};
struct rb_ractor_basket {
- union {
- enum rb_ractor_basket_type e;
- rb_atomic_t atomic;
- } type;
+ bool exception;
+ enum rb_ractor_basket_type type;
+ VALUE v;
VALUE sender;
-
- union {
- struct {
- VALUE v;
- bool exception;
- } send;
-
- struct {
- struct rb_ractor_basket *basket;
- struct rb_ractor_selector_take_config *config;
- } take;
- } p; // payload
};
-static inline bool
-basket_type_p(struct rb_ractor_basket *b, enum rb_ractor_basket_type type)
-{
- return b->type.e == type;
-}
-
-static inline bool
-basket_none_p(struct rb_ractor_basket *b)
-{
- return basket_type_p(b, basket_type_none);
-}
-
struct rb_ractor_queue {
struct rb_ractor_basket *baskets;
int start;
@@ -79,6 +34,12 @@ struct rb_ractor_queue {
unsigned int reserved_cnt;
};
+struct rb_ractor_waiting_list {
+ int cnt;
+ int size;
+ rb_ractor_t **ractors;
+};
+
enum rb_ractor_wait_status {
wait_none = 0x00,
wait_receiving = 0x01,
@@ -103,28 +64,21 @@ struct rb_ractor_sync {
#if RACTOR_CHECK_MODE > 0
VALUE locked_by;
#endif
+ rb_nativethread_cond_t cond;
+
+ // communication
+ struct rb_ractor_queue incoming_queue;
+ struct rb_ractor_waiting_list taking_ractors;
bool incoming_port_closed;
bool outgoing_port_closed;
- // All sent messages will be pushed into recv_queue
- struct rb_ractor_queue recv_queue;
-
- // The following ractors waiting for the yielding by this ractor
- struct rb_ractor_queue takers_queue;
-
- // Enabled if the ractor already terminated and not taken yet.
- struct rb_ractor_basket will_basket;
-
struct ractor_wait {
enum rb_ractor_wait_status status;
enum rb_ractor_wakeup_status wakeup_status;
- rb_thread_t *waiting_thread;
+ struct rb_ractor_basket yielded_basket;
+ struct rb_ractor_basket taken_basket;
} wait;
-
-#ifndef RUBY_THREAD_PTHREAD_H
- rb_nativethread_cond_t cond;
-#endif
};
// created
@@ -153,6 +107,7 @@ struct rb_ractor_struct {
struct rb_ractor_sync sync;
VALUE receiving_mutex;
+ bool yield_atexit;
// vm wide barrier synchronization
rb_nativethread_cond_t barrier_wait_cond;
@@ -214,7 +169,7 @@ void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE
VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc); // defined in thread.c
int rb_ractor_living_thread_num(const rb_ractor_t *);
-VALUE rb_ractor_thread_list(void);
+VALUE rb_ractor_thread_list(rb_ractor_t *r);
bool rb_ractor_p(VALUE rv);
void rb_ractor_living_threads_init(rb_ractor_t *r);
@@ -285,10 +240,6 @@ rb_ractor_sleeper_thread_num(rb_ractor_t *r)
static inline void
rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th)
{
- RUBY_DEBUG_LOG("th:%d->%u%s",
- cr->threads.running_ec ? (int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1,
- rb_th_serial(th), cr->threads.running_ec == th->ec ? " (same)" : "");
-
if (cr->threads.running_ec != th->ec) {
if (0) {
ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n",
@@ -314,18 +265,16 @@ static inline void
rb_ractor_set_current_ec_(rb_ractor_t *cr, rb_execution_context_t *ec, const char *file, int line)
{
#ifdef RB_THREAD_LOCAL_SPECIFIER
-
-# ifdef __APPLE__
+ #ifdef __APPLE__
rb_current_ec_set(ec);
-# else
+ #else
ruby_current_ec = ec;
-# endif
-
+ #endif
#else
native_tls_set(ruby_current_ec_key, ec);
#endif
RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec);
- VM_ASSERT(ec == NULL || cr->threads.running_ec != ec);
+ VM_ASSERT(cr->threads.running_ec != ec);
cr->threads.running_ec = ec;
}
diff --git a/random.c b/random.c
index 5cd2d917a4..4b5b7ab6c4 100644
--- a/random.c
+++ b/random.c
@@ -157,12 +157,6 @@ rand_start(rb_random_mt_t *r)
static rb_ractor_local_key_t default_rand_key;
-void
-rb_free_default_rand_key(void)
-{
- xfree(default_rand_key);
-}
-
static void
default_rand_mark(void *ptr)
{
diff --git a/range.c b/range.c
index f66d23d07b..dbc37c1410 100644
--- a/range.c
+++ b/range.c
@@ -607,10 +607,6 @@ double_as_int64(double d)
static int
is_integer_p(VALUE v)
{
- if (rb_integer_type_p(v)) {
- return true;
- }
-
ID id_integer_p;
VALUE is_int;
CONST_ID(id_integer_p, "integer?");
@@ -653,30 +649,27 @@ bsearch_integer_range(VALUE beg, VALUE end, int excl)
VALUE low = rb_to_int(beg);
VALUE high = rb_to_int(end);
- VALUE mid;
+ VALUE mid, org_high;
ID id_div;
CONST_ID(id_div, "div");
- if (!excl) high = rb_funcall(high, '+', 1, INT2FIX(1));
- low = rb_funcall(low, '-', 1, INT2FIX(1));
+ if (excl) high = rb_funcall(high, '-', 1, INT2FIX(1));
+ org_high = high;
- /*
- * This loop must continue while low + 1 < high.
- * Instead of checking low + 1 < high, check low < mid, where mid = (low + high) / 2.
- * This is to avoid the cost of calculating low + 1 on each iteration.
- * Note that this condition replacement is valid because Integer#div always rounds
- * towards negative infinity.
- */
- while (mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2)),
- rb_cmpint(rb_funcall(low, id_cmp, 1, mid), low, mid) < 0) {
+ while (rb_cmpint(rb_funcall(low, id_cmp, 1, high), low, high) < 0) {
+ mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2));
BSEARCH_CHECK(mid);
if (smaller) {
high = mid;
}
else {
- low = mid;
+ low = rb_funcall(mid, '+', 1, INT2FIX(1));
}
}
+ if (rb_equal(low, org_high)) {
+ BSEARCH_CHECK(low);
+ if (!smaller) return Qnil;
+ }
return satisfied;
}
@@ -703,58 +696,52 @@ range_bsearch(VALUE range)
* by the mantissa. This is true with or without implicit bit.
*
* Finding the average of two ints needs to be careful about
- * potential overflow (since float to long can use 64 bits).
- *
- * The half-open interval (low, high] indicates where the target is located.
- * The loop continues until low and high are adjacent.
- *
- * -1/2 can be either 0 or -1 in C89. However, when low and high are not adjacent,
- * the rounding direction of mid = (low + high) / 2 does not affect the result of
- * the binary search.
+ * potential overflow (since float to long can use 64 bits)
+ * as well as the fact that -1/2 can be 0 or -1 in C89.
*
* Note that -0.0 is mapped to the same int as 0.0 as we don't want
* (-1...0.0).bsearch to yield -0.0.
*/
-#define BSEARCH(conv, excl) \
+#define BSEARCH(conv) \
do { \
RETURN_ENUMERATOR(range, 0, 0); \
- if (!(excl)) high++; \
- low--; \
- while (low + 1 < high) { \
+ if (EXCL(range)) high--; \
+ org_high = high; \
+ while (low < high) { \
mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \
- : (low + high) / 2; \
+ : (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \
BSEARCH_CHECK(conv(mid)); \
if (smaller) { \
high = mid; \
} \
else { \
- low = mid; \
+ low = mid + 1; \
} \
} \
+ if (low == org_high) { \
+ BSEARCH_CHECK(conv(low)); \
+ if (!smaller) return Qnil; \
+ } \
return satisfied; \
} while (0)
-#define BSEARCH_FIXNUM(beg, end, excl) \
- do { \
- long low = FIX2LONG(beg); \
- long high = FIX2LONG(end); \
- long mid; \
- BSEARCH(INT2FIX, (excl)); \
- } while (0)
beg = RANGE_BEG(range);
end = RANGE_END(range);
if (FIXNUM_P(beg) && FIXNUM_P(end)) {
- BSEARCH_FIXNUM(beg, end, EXCL(range));
+ long low = FIX2LONG(beg);
+ long high = FIX2LONG(end);
+ long mid, org_high;
+ BSEARCH(INT2FIX);
}
#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
else if (RB_FLOAT_TYPE_P(beg) || RB_FLOAT_TYPE_P(end)) {
int64_t low = double_as_int64(NIL_P(beg) ? -HUGE_VAL : RFLOAT_VALUE(rb_Float(beg)));
int64_t high = double_as_int64(NIL_P(end) ? HUGE_VAL : RFLOAT_VALUE(rb_Float(end)));
- int64_t mid;
- BSEARCH(int64_as_double_to_num, EXCL(range));
+ int64_t mid, org_high;
+ BSEARCH(int64_as_double_to_num);
}
#endif
else if (is_integer_p(beg) && is_integer_p(end)) {
@@ -768,15 +755,9 @@ range_bsearch(VALUE range)
VALUE mid = rb_funcall(beg, '+', 1, diff);
BSEARCH_CHECK(mid);
if (smaller) {
- if (FIXNUM_P(beg) && FIXNUM_P(mid)) {
- BSEARCH_FIXNUM(beg, mid, false);
- }
- else {
- return bsearch_integer_range(beg, mid, false);
- }
+ return bsearch_integer_range(beg, mid, 0);
}
diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
- beg = mid;
}
}
else if (NIL_P(beg) && is_integer_p(end)) {
@@ -786,15 +767,9 @@ range_bsearch(VALUE range)
VALUE mid = rb_funcall(end, '+', 1, diff);
BSEARCH_CHECK(mid);
if (!smaller) {
- if (FIXNUM_P(mid) && FIXNUM_P(end)) {
- BSEARCH_FIXNUM(mid, end, false);
- }
- else {
- return bsearch_integer_range(mid, end, false);
- }
+ return bsearch_integer_range(mid, end, 0);
}
diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
- end = mid;
}
}
else {
@@ -864,6 +839,7 @@ range_size(VALUE range)
* (1...4).to_a # => [1, 2, 3]
* ('a'..'d').to_a # => ["a", "b", "c", "d"]
*
+ * Range#entries is an alias for Range#to_a.
*/
static VALUE
@@ -1024,144 +1000,6 @@ range_each(VALUE range)
return range;
}
-RBIMPL_ATTR_NORETURN()
-static void
-range_reverse_each_bignum_beginless(VALUE end)
-{
- RUBY_ASSERT(RBIGNUM_NEGATIVE_P(end));
-
- for (;; end = rb_big_minus(end, INT2FIX(1))) {
- rb_yield(end);
- }
- UNREACHABLE;
-}
-
-static void
-range_reverse_each_bignum(VALUE beg, VALUE end)
-{
- RUBY_ASSERT(RBIGNUM_POSITIVE_P(beg) == RBIGNUM_POSITIVE_P(end));
-
- VALUE c;
- while ((c = rb_big_cmp(beg, end)) != INT2FIX(1)) {
- rb_yield(end);
- if (c == INT2FIX(0)) break;
- end = rb_big_minus(end, INT2FIX(1));
- }
-}
-
-static void
-range_reverse_each_positive_bignum_section(VALUE beg, VALUE end)
-{
- RUBY_ASSERT(!NIL_P(end));
-
- if (FIXNUM_P(end) || RBIGNUM_NEGATIVE_P(end)) return;
-
- if (NIL_P(beg) || FIXNUM_P(beg) || RBIGNUM_NEGATIVE_P(beg)) {
- beg = LONG2NUM(FIXNUM_MAX + 1);
- }
-
- range_reverse_each_bignum(beg, end);
-}
-
-static void
-range_reverse_each_fixnum_section(VALUE beg, VALUE end)
-{
- RUBY_ASSERT(!NIL_P(end));
-
- if (!FIXNUM_P(beg)) {
- if (!NIL_P(beg) && RBIGNUM_POSITIVE_P(beg)) return;
-
- beg = LONG2FIX(FIXNUM_MIN);
- }
-
- if (!FIXNUM_P(end)) {
- if (RBIGNUM_NEGATIVE_P(end)) return;
-
- end = LONG2FIX(FIXNUM_MAX);
- }
-
- long b = FIX2LONG(beg);
- long e = FIX2LONG(end);
- for (long i = e; i >= b; --i) {
- rb_yield(LONG2FIX(i));
- }
-}
-
-static void
-range_reverse_each_negative_bignum_section(VALUE beg, VALUE end)
-{
- RUBY_ASSERT(!NIL_P(end));
-
- if (FIXNUM_P(end) || RBIGNUM_POSITIVE_P(end)) {
- end = LONG2NUM(FIXNUM_MIN - 1);
- }
-
- if (NIL_P(beg)) {
- range_reverse_each_bignum_beginless(end);
- }
-
- if (FIXNUM_P(beg) || RBIGNUM_POSITIVE_P(beg)) return;
-
- range_reverse_each_bignum(beg, end);
-}
-
-/*
- * call-seq:
- * reverse_each {|element| ... } -> self
- * reverse_each -> an_enumerator
- *
- * With a block given, passes each element of +self+ to the block in reverse order:
- *
- * a = []
- * (1..4).reverse_each {|element| a.push(element) } # => 1..4
- * a # => [4, 3, 2, 1]
- *
- * a = []
- * (1...4).reverse_each {|element| a.push(element) } # => 1...4
- * a # => [3, 2, 1]
- *
- * With no block given, returns an enumerator.
- *
- */
-
-static VALUE
-range_reverse_each(VALUE range)
-{
- RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
-
- VALUE beg = RANGE_BEG(range);
- VALUE end = RANGE_END(range);
- int excl = EXCL(range);
-
- if (NIL_P(end)) {
- rb_raise(rb_eTypeError, "can't iterate from %s",
- rb_obj_classname(end));
- }
-
- if (FIXNUM_P(beg) && FIXNUM_P(end)) {
- if (excl) {
- if (end == LONG2FIX(FIXNUM_MIN)) return range;
-
- end = rb_int_minus(end, INT2FIX(1));
- }
-
- range_reverse_each_fixnum_section(beg, end);
- }
- else if ((NIL_P(beg) || RB_INTEGER_TYPE_P(beg)) && RB_INTEGER_TYPE_P(end)) {
- if (excl) {
- end = rb_int_minus(end, INT2FIX(1));
- }
- range_reverse_each_positive_bignum_section(beg, end);
- range_reverse_each_fixnum_section(beg, end);
- range_reverse_each_negative_bignum_section(beg, end);
- }
- else {
- return rb_call_super(0, NULL);
- }
-
- return range;
-}
-
/*
* call-seq:
* self.begin -> object
@@ -1844,6 +1682,7 @@ range_inspect(VALUE range)
}
static VALUE range_include_internal(VALUE range, VALUE val);
+static VALUE range_string_cover_internal(VALUE range, VALUE val);
VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
/*
@@ -1888,6 +1727,8 @@ VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
static VALUE
range_eqq(VALUE range, VALUE val)
{
+ VALUE ret = range_string_cover_internal(range, val);
+ if (!UNDEF_P(ret)) return ret;
return r_cover_p(range, RANGE_BEG(range), RANGE_END(range), val);
}
@@ -1919,6 +1760,8 @@ range_eqq(VALUE range, VALUE val)
* ('a'..'d').cover?('cc') # => true
*
* Related: Range#cover?.
+ *
+ * Range#member? is an alias for Range#include?.
*/
static VALUE
@@ -1937,6 +1780,12 @@ range_integer_edge_p(VALUE beg, VALUE end)
}
static inline bool
+range_string_edge_p(VALUE beg, VALUE end)
+{
+ return RB_TYPE_P(beg, T_STRING) || RB_TYPE_P(end, T_STRING);
+}
+
+static inline bool
range_string_range_p(VALUE beg, VALUE end)
{
return RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING);
@@ -1957,6 +1806,48 @@ range_include_fallback(VALUE beg, VALUE end, VALUE val)
}
static VALUE
+range_string_cover_internal(VALUE range, VALUE val)
+{
+ VALUE beg = RANGE_BEG(range);
+ VALUE end = RANGE_END(range);
+ int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
+ linear_object_p(beg) || linear_object_p(end);
+
+ if (nv || range_integer_edge_p(beg, end)) {
+ return r_cover_p(range, beg, end, val);
+ }
+ else if (range_string_edge_p(beg, end)) {
+ if (range_string_range_p(beg, end)) {
+ return r_cover_p(range, beg, end, val);
+ }
+ if (NIL_P(beg)) {
+unbounded_begin:;
+ VALUE r = rb_funcall(val, id_cmp, 1, end);
+ if (NIL_P(r)) return Qfalse;
+ if (RANGE_EXCL(range)) {
+ return RBOOL(rb_cmpint(r, val, end) < 0);
+ }
+ return RBOOL(rb_cmpint(r, val, end) <= 0);
+ }
+ else if (NIL_P(end)) {
+unbounded_end:;
+ VALUE r = rb_funcall(beg, id_cmp, 1, val);
+ if (NIL_P(r)) return Qfalse;
+ return RBOOL(rb_cmpint(r, beg, val) <= 0);
+ }
+ }
+
+ if (!NIL_P(beg) && NIL_P(end)) {
+ goto unbounded_end;
+ }
+ if (NIL_P(beg) && !NIL_P(end)) {
+ goto unbounded_begin;
+ }
+
+ return range_include_fallback(beg, end, val);
+}
+
+static VALUE
range_include_internal(VALUE range, VALUE val)
{
VALUE beg = RANGE_BEG(range);
@@ -1998,7 +1889,7 @@ static int r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
* r.cover?(0) # => false
* r.cover?(5) # => false
* r.cover?('foo') # => false
- *
+
* r = ('a'..'d')
* r.cover?('a') # => true
* r.cover?('d') # => true
@@ -2019,7 +1910,7 @@ static int r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
* r.cover?(0) # => false
* r.cover?(4) # => false
* r.cover?('foo') # => false
- *
+
* r = ('a'...'d')
* r.cover?('a') # => true
* r.cover?('c') # => true
@@ -2035,7 +1926,7 @@ static int r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
* r.cover?(0..4) # => false
* r.cover?(1..5) # => false
* r.cover?('a'..'d') # => false
- *
+
* r = (1...4)
* r.cover?(1..3) # => true
* r.cover?(1..4) # => false
@@ -2257,137 +2148,17 @@ range_count(int argc, VALUE *argv, VALUE range)
* Infinity. Just let it loop. */
return rb_call_super(argc, argv);
}
-
- VALUE beg = RANGE_BEG(range), end = RANGE_END(range);
-
- if (NIL_P(beg) || NIL_P(end)) {
+ else if (NIL_P(RANGE_END(range))) {
/* We are confident that the answer is Infinity. */
return DBL2NUM(HUGE_VAL);
}
-
- if (is_integer_p(beg)) {
- VALUE size = range_size(range);
- if (!NIL_P(size)) {
- return size;
- }
- }
-
- return rb_call_super(argc, argv);
-}
-
-static bool
-empty_region_p(VALUE beg, VALUE end, int excl)
-{
- if (NIL_P(beg)) return false;
- if (NIL_P(end)) return false;
- int less = r_less(beg, end);
- /* empty range */
- if (less > 0) return true;
- if (excl && less == 0) return true;
- return false;
-}
-
-/*
- * call-seq:
- * overlap?(range) -> true or false
- *
- * Returns +true+ if +range+ overlaps with +self+, +false+ otherwise:
- *
- * (0..2).overlap?(1..3) #=> true
- * (0..2).overlap?(3..4) #=> false
- * (0..).overlap?(..0) #=> true
- *
- * With non-range argument, raises TypeError.
- *
- * (1..3).overlap?(1) # TypeError
- *
- * Returns +false+ if an internal call to <tt><=></tt> returns +nil+;
- * that is, the operands are not comparable.
- *
- * (1..3).overlap?('a'..'d') # => false
- *
- * Returns +false+ if +self+ or +range+ is empty. "Empty range" means
- * that its begin value is larger than, or equal for an exclusive
- * range, its end value.
- *
- * (4..1).overlap?(2..3) # => false
- * (4..1).overlap?(..3) # => false
- * (4..1).overlap?(2..) # => false
- * (2...2).overlap?(1..2) # => false
- *
- * (1..4).overlap?(3..2) # => false
- * (..4).overlap?(3..2) # => false
- * (1..).overlap?(3..2) # => false
- * (1..2).overlap?(2...2) # => false
- *
- * Returns +false+ if the begin value one of +self+ and +range+ is
- * larger than, or equal if the other is an exclusive range, the end
- * value of the other:
- *
- * (4..5).overlap?(2..3) # => false
- * (4..5).overlap?(2...4) # => false
- *
- * (1..2).overlap?(3..4) # => false
- * (1...3).overlap?(3..4) # => false
- *
- * Returns +false+ if the end value one of +self+ and +range+ is
- * larger than, or equal for an exclusive range, the end value of the
- * other:
- *
- * (4..5).overlap?(2..3) # => false
- * (4..5).overlap?(2...4) # => false
- *
- * (1..2).overlap?(3..4) # => false
- * (1...3).overlap?(3..4) # => false
- *
- * Note that the method wouldn't make any assumptions about the beginless
- * range being actually empty, even if its upper bound is the minimum
- * possible value of its type, so all this would return +true+:
- *
- * (...-Float::INFINITY).overlap?(...-Float::INFINITY) # => true
- * (..."").overlap?(..."") # => true
- * (...[]).overlap?(...[]) # => true
- *
- * Even if those ranges are effectively empty (no number can be smaller than
- * <tt>-Float::INFINITY</tt>), they are still considered overlapping
- * with themselves.
- *
- * Related: Range#cover?.
- */
-
-static VALUE
-range_overlap(VALUE range, VALUE other)
-{
- if (!rb_obj_is_kind_of(other, rb_cRange)) {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Range)",
- rb_class_name(rb_obj_class(other)));
- }
-
- VALUE self_beg = RANGE_BEG(range);
- VALUE self_end = RANGE_END(range);
- int self_excl = EXCL(range);
- VALUE other_beg = RANGE_BEG(other);
- VALUE other_end = RANGE_END(other);
- int other_excl = EXCL(other);
-
- if (empty_region_p(self_beg, other_end, other_excl)) return Qfalse;
- if (empty_region_p(other_beg, self_end, self_excl)) return Qfalse;
-
- if (!NIL_P(self_beg) && !NIL_P(other_beg)) {
- VALUE cmp = rb_funcall(self_beg, id_cmp, 1, other_beg);
- if (NIL_P(cmp)) return Qfalse;
- /* if both begin values are equal, no more comparisons needed */
- if (rb_cmpint(cmp, self_beg, other_beg) == 0) return Qtrue;
+ else if (NIL_P(RANGE_BEG(range))) {
+ /* We are confident that the answer is Infinity. */
+ return DBL2NUM(HUGE_VAL);
}
- else if (NIL_P(self_beg) && NIL_P(other_beg)) {
- VALUE cmp = rb_funcall(self_end, id_cmp, 1, other_end);
- return RBOOL(!NIL_P(cmp));
+ else {
+ return rb_call_super(argc, argv);
}
-
- if (empty_region_p(self_beg, self_end, self_excl)) return Qfalse;
- if (empty_region_p(other_beg, other_end, other_excl)) return Qfalse;
-
- return Qtrue;
}
/* A \Range object represents a collection of values
@@ -2570,7 +2341,6 @@ range_overlap(VALUE range, VALUE other)
* - {Comparing}[rdoc-ref:Range@Methods+for+Comparing]
* - {Iterating}[rdoc-ref:Range@Methods+for+Iterating]
* - {Converting}[rdoc-ref:Range@Methods+for+Converting]
- * - {Methods for Working with JSON}[rdoc-ref:Range@Methods+for+Working+with+JSON]
*
* === Methods for Creating a \Range
*
@@ -2605,7 +2375,7 @@ range_overlap(VALUE range, VALUE other)
* - #%: Requires argument +n+; calls the block with each +n+-th element of +self+.
* - #each: Calls the block with each element of +self+.
* - #step: Takes optional argument +n+ (defaults to 1);
- * calls the block with each +n+-th element of +self+.
+ calls the block with each +n+-th element of +self+.
*
* === Methods for Converting
*
@@ -2613,16 +2383,6 @@ range_overlap(VALUE range, VALUE other)
* - #to_a (aliased as #entries): Returns elements of +self+ in an array.
* - #to_s: Returns a string representation of +self+ (uses #to_s).
*
- * === Methods for Working with \JSON
- *
- * - ::json_create: Returns a new \Range object constructed from the given object.
- * - #as_json: Returns a 2-element hash representing +self+.
- * - #to_json: Returns a \JSON string representing +self+.
- *
- * To make these methods available:
- *
- * require 'json/add/range'
- *
*/
void
@@ -2647,7 +2407,6 @@ Init_Range(void)
rb_define_method(rb_cRange, "each", range_each, 0);
rb_define_method(rb_cRange, "step", range_step, -1);
rb_define_method(rb_cRange, "%", range_percent_step, 1);
- rb_define_method(rb_cRange, "reverse_each", range_reverse_each, 0);
rb_define_method(rb_cRange, "bsearch", range_bsearch, 0);
rb_define_method(rb_cRange, "begin", range_begin, 0);
rb_define_method(rb_cRange, "end", range_end, 0);
@@ -2668,5 +2427,4 @@ Init_Range(void)
rb_define_method(rb_cRange, "include?", range_include, 1);
rb_define_method(rb_cRange, "cover?", range_cover, 1);
rb_define_method(rb_cRange, "count", range_count, -1);
- rb_define_method(rb_cRange, "overlap?", range_overlap, 1);
}
diff --git a/rational.c b/rational.c
index c5ad7598f7..dfe2ad74eb 100644
--- a/rational.c
+++ b/rational.c
@@ -413,8 +413,7 @@ f_lcm(VALUE x, VALUE y)
inline static VALUE
nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
{
- NEWOBJ_OF(obj, struct RRational, klass, T_RATIONAL | (RGENGC_WB_PROTECTED_RATIONAL ? FL_WB_PROTECTED : 0),
- sizeof(struct RRational), 0);
+ NEWOBJ_OF(obj, struct RRational, klass, T_RATIONAL | (RGENGC_WB_PROTECTED_RATIONAL ? FL_WB_PROTECTED : 0));
RATIONAL_SET_NUM((VALUE)obj, num);
RATIONAL_SET_DEN((VALUE)obj, den);
@@ -1233,6 +1232,7 @@ nurat_negative_p(VALUE self)
* (1/2r).abs #=> (1/2)
* (-1/2r).abs #=> (1/2)
*
+ * Rational#magnitude is an alias for Rational#abs.
*/
VALUE
@@ -2104,12 +2104,9 @@ rb_float_denominator(VALUE self)
/*
* call-seq:
- * to_r -> (0/1)
- *
- * Returns zero as a Rational:
- *
- * nil.to_r # => (0/1)
+ * nil.to_r -> (0/1)
*
+ * Returns zero as a rational.
*/
static VALUE
nilclass_to_r(VALUE self)
@@ -2119,14 +2116,10 @@ nilclass_to_r(VALUE self)
/*
* call-seq:
- * rationalize(eps = nil) -> (0/1)
- *
- * Returns zero as a Rational:
- *
- * nil.rationalize # => (0/1)
- *
- * Argument +eps+ is ignored.
+ * nil.rationalize([eps]) -> (0/1)
*
+ * Returns zero as a rational. The optional argument +eps+ is always
+ * ignored.
*/
static VALUE
nilclass_rationalize(int argc, VALUE *argv, VALUE self)
diff --git a/re.c b/re.c
index a19dcb920d..f357d38c63 100644
--- a/re.c
+++ b/re.c
@@ -88,9 +88,6 @@ static const char casetable[] = {
# error >>> "You lose. You will need a translation table for your character set." <<<
#endif
-// The process-global timeout for regexp matching
-rb_hrtime_t rb_reg_match_time_limit = 0;
-
int
rb_memcicmp(const void *x, const void *y, long len)
{
@@ -285,6 +282,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)
return rb_memsearch_qs(x0, m, y0, n);
}
+#define REG_LITERAL FL_USER5
#define REG_ENCODING_NONE FL_USER6
#define KCODE_FIXED FL_USER4
@@ -453,7 +451,7 @@ rb_reg_expr_str(VALUE str, const char *s, long len,
}
static VALUE
-rb_reg_desc(VALUE re)
+rb_reg_desc(const char *s, long len, VALUE re)
{
rb_encoding *enc = rb_enc_get(re);
VALUE str = rb_str_buf_new2("/");
@@ -466,11 +464,7 @@ rb_reg_desc(VALUE re)
else {
rb_enc_associate(str, rb_usascii_encoding());
}
-
- VALUE src_str = RREGEXP_SRC(re);
- rb_reg_expr_str(str, RSTRING_PTR(src_str), RSTRING_LEN(src_str), enc, resenc, '/');
- RB_GC_GUARD(src_str);
-
+ rb_reg_expr_str(str, s, len, enc, resenc, '/');
rb_str_buf_cat2(str, "/");
if (re) {
char opts[OPTBUF_SIZE];
@@ -529,7 +523,7 @@ rb_reg_inspect(VALUE re)
if (!RREGEXP_PTR(re) || !RREGEXP_SRC(re) || !RREGEXP_SRC_PTR(re)) {
return rb_any_to_s(re);
}
- return rb_reg_desc(re);
+ return rb_reg_desc(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), re);
}
static VALUE rb_reg_str_with_term(VALUE re, int term);
@@ -545,7 +539,7 @@ static VALUE rb_reg_str_with_term(VALUE re, int term);
*
* The returned string may be used as an argument to Regexp.new,
* or as interpolated text for a
- * {Regexp interpolation}[rdoc-ref:Regexp@Interpolation+Mode]:
+ * {Regexp literal}[rdoc-ref:regexp.rdoc@Regexp+Literal]:
*
* r1 = Regexp.new(s0) # => /(?ix-m:ab+c)/
* r2 = /#{s0}/ # => /(?ix-m:ab+c)/
@@ -572,6 +566,8 @@ rb_reg_str_with_term(VALUE re, int term)
{
int options, opt;
const int embeddable = ONIG_OPTION_MULTILINE|ONIG_OPTION_IGNORECASE|ONIG_OPTION_EXTEND;
+ long len;
+ const UChar* ptr;
VALUE str = rb_str_buf_new2("(?");
char optbuf[OPTBUF_SIZE + 1]; /* for '-' */
rb_encoding *enc = rb_enc_get(re);
@@ -580,9 +576,8 @@ rb_reg_str_with_term(VALUE re, int term)
rb_enc_copy(str, re);
options = RREGEXP_PTR(re)->options;
- VALUE src_str = RREGEXP_SRC(re);
- const UChar *ptr = (UChar *)RSTRING_PTR(src_str);
- long len = RSTRING_LEN(src_str);
+ ptr = (UChar*)RREGEXP_SRC_PTR(re);
+ len = RREGEXP_SRC_LEN(re);
again:
if (len >= 4 && ptr[0] == '(' && ptr[1] == '?') {
int err = 1;
@@ -672,17 +667,15 @@ rb_reg_str_with_term(VALUE re, int term)
}
rb_enc_copy(str, re);
- RB_GC_GUARD(src_str);
-
return str;
}
-NORETURN(static void rb_reg_raise(const char *err, VALUE re));
+NORETURN(static void rb_reg_raise(const char *s, long len, const char *err, VALUE re));
static void
-rb_reg_raise(const char *err, VALUE re)
+rb_reg_raise(const char *s, long len, const char *err, VALUE re)
{
- VALUE desc = rb_reg_desc(re);
+ VALUE desc = rb_reg_desc(s, len, re);
rb_raise(rb_eRegexpError, "%s: %"PRIsVALUE, err, desc);
}
@@ -770,8 +763,8 @@ rb_reg_casefold_p(VALUE re)
* /foo/mix.options # => 7
*
* Note that additional bits may be set in the returned integer;
- * these are maintained internally in +self+, are ignored if passed
- * to Regexp.new, and may be ignored by the caller:
+ * these are maintained internally internally in +self+,
+ * are ignored if passed to Regexp.new, and may be ignored by the caller:
*
* Returns the set of bits corresponding to the options used when
* creating this regexp (see Regexp::new for details). Note that
@@ -969,13 +962,12 @@ VALUE rb_cMatch;
static VALUE
match_alloc(VALUE klass)
{
- size_t alloc_size = sizeof(struct RMatch) + sizeof(rb_matchext_t);
- VALUE flags = T_MATCH | (RGENGC_WB_PROTECTED_MATCH ? FL_WB_PROTECTED : 0);
- NEWOBJ_OF(match, struct RMatch, klass, flags, alloc_size, 0);
+ NEWOBJ_OF(match, struct RMatch, klass, T_MATCH);
- match->str = Qfalse;
- match->regexp = Qfalse;
- memset(RMATCH_EXT(match), 0, sizeof(rb_matchext_t));
+ match->str = 0;
+ match->rmatch = 0;
+ match->regexp = 0;
+ match->rmatch = ZALLOC(struct rmatch);
return (VALUE)match;
}
@@ -1010,7 +1002,7 @@ pair_byte_cmp(const void *pair1, const void *pair2)
static void
update_char_offset(VALUE match)
{
- rb_matchext_t *rm = RMATCH_EXT(match);
+ struct rmatch *rm = RMATCH(match)->rmatch;
struct re_registers *regs;
int i, num_regs, num_pos;
long c;
@@ -1088,23 +1080,23 @@ match_check(VALUE match)
static VALUE
match_init_copy(VALUE obj, VALUE orig)
{
- rb_matchext_t *rm;
+ struct rmatch *rm;
if (!OBJ_INIT_COPY(obj, orig)) return obj;
- RB_OBJ_WRITE(obj, &RMATCH(obj)->str, RMATCH(orig)->str);
- RB_OBJ_WRITE(obj, &RMATCH(obj)->regexp, RMATCH(orig)->regexp);
+ RMATCH(obj)->str = RMATCH(orig)->str;
+ RMATCH(obj)->regexp = RMATCH(orig)->regexp;
- rm = RMATCH_EXT(obj);
+ rm = RMATCH(obj)->rmatch;
if (rb_reg_region_copy(&rm->regs, RMATCH_REGS(orig)))
rb_memerror();
- if (RMATCH_EXT(orig)->char_offset_num_allocated) {
+ if (RMATCH(orig)->rmatch->char_offset_num_allocated) {
if (rm->char_offset_num_allocated < rm->regs.num_regs) {
REALLOC_N(rm->char_offset, struct rmatch_offset, rm->regs.num_regs);
rm->char_offset_num_allocated = rm->regs.num_regs;
}
- MEMCPY(rm->char_offset, RMATCH_EXT(orig)->char_offset,
+ MEMCPY(rm->char_offset, RMATCH(orig)->rmatch->char_offset,
struct rmatch_offset, rm->regs.num_regs);
RB_GC_GUARD(orig);
}
@@ -1133,7 +1125,7 @@ match_regexp(VALUE match)
if (NIL_P(regexp)) {
VALUE str = rb_reg_nth_match(0, match);
regexp = rb_reg_regcomp(rb_reg_quote(str));
- RB_OBJ_WRITE(match, &RMATCH(match)->regexp, regexp);
+ RMATCH(match)->regexp = regexp;
}
return regexp;
}
@@ -1178,6 +1170,8 @@ match_names(VALUE match)
* # => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
* m.size # => 5
*
+ * MatchData#length is an alias for MatchData.size.
+ *
*/
static VALUE
@@ -1259,8 +1253,8 @@ match_offset(VALUE match, VALUE n)
return rb_assoc_new(Qnil, Qnil);
update_char_offset(match);
- return rb_assoc_new(LONG2NUM(RMATCH_EXT(match)->char_offset[i].beg),
- LONG2NUM(RMATCH_EXT(match)->char_offset[i].end));
+ return rb_assoc_new(LONG2NUM(RMATCH(match)->rmatch->char_offset[i].beg),
+ LONG2NUM(RMATCH(match)->rmatch->char_offset[i].end));
}
/*
@@ -1318,7 +1312,7 @@ match_begin(VALUE match, VALUE n)
return Qnil;
update_char_offset(match);
- return LONG2NUM(RMATCH_EXT(match)->char_offset[i].beg);
+ return LONG2NUM(RMATCH(match)->rmatch->char_offset[i].beg);
}
@@ -1344,7 +1338,7 @@ match_end(VALUE match, VALUE n)
return Qnil;
update_char_offset(match);
- return LONG2NUM(RMATCH_EXT(match)->char_offset[i].end);
+ return LONG2NUM(RMATCH(match)->rmatch->char_offset[i].end);
}
/*
@@ -1431,7 +1425,7 @@ match_nth_length(VALUE match, VALUE n)
update_char_offset(match);
const struct rmatch_offset *const ofs =
- &RMATCH_EXT(match)->char_offset[i];
+ &RMATCH(match)->rmatch->char_offset[i];
return LONG2NUM(ofs->end - ofs->beg);
}
@@ -1459,14 +1453,31 @@ rb_match_count(VALUE match)
return regs->num_regs;
}
+int
+rb_match_nth_defined(int nth, VALUE match)
+{
+ struct re_registers *regs;
+ if (NIL_P(match)) return FALSE;
+ regs = RMATCH_REGS(match);
+ if (!regs) return FALSE;
+ if (nth >= regs->num_regs) {
+ return FALSE;
+ }
+ if (nth < 0) {
+ nth += regs->num_regs;
+ if (nth <= 0) return FALSE;
+ }
+ return (BEG(nth) != -1);
+}
+
static void
match_set_string(VALUE m, VALUE string, long pos, long len)
{
struct RMatch *match = (struct RMatch *)m;
- rb_matchext_t *rmatch = RMATCH_EXT(match);
+ struct rmatch *rmatch = match->rmatch;
- RB_OBJ_WRITE(match, &RMATCH(match)->str, string);
- RB_OBJ_WRITE(match, &RMATCH(match)->regexp, Qnil);
+ match->str = string;
+ match->regexp = Qnil;
int err = onig_region_resize(&rmatch->regs, 1);
if (err) rb_memerror();
rmatch->regs.beg[0] = pos;
@@ -1584,25 +1595,24 @@ rb_reg_prepare_enc(VALUE re, VALUE str, int warn)
}
regex_t *
-rb_reg_prepare_re(VALUE re, VALUE str)
+rb_reg_prepare_re0(VALUE re, VALUE str, onig_errmsg_buffer err)
{
+ regex_t *reg = RREGEXP_PTR(re);
int r;
OnigErrorInfo einfo;
+ const char *pattern;
VALUE unescaped;
rb_encoding *fixed_enc = 0;
rb_encoding *enc = rb_reg_prepare_enc(re, str, 1);
- regex_t *reg = RREGEXP_PTR(re);
if (reg->enc == enc) return reg;
rb_reg_check(re);
+ reg = RREGEXP_PTR(re);
+ pattern = RREGEXP_SRC_PTR(re);
- VALUE src_str = RREGEXP_SRC(re);
- const char *pattern = RSTRING_PTR(src_str);
-
- onig_errmsg_buffer err = "";
unescaped = rb_reg_preprocess(
- pattern, pattern + RSTRING_LEN(src_str), enc,
+ pattern, pattern + RREGEXP_SRC_LEN(re), enc,
&fixed_enc, err, 0);
if (NIL_P(unescaped)) {
@@ -1615,70 +1625,25 @@ rb_reg_prepare_re(VALUE re, VALUE str)
const char *ptr;
long len;
RSTRING_GETMEM(unescaped, ptr, len);
-
- /* If there are no other users of this regex, then we can directly overwrite it. */
- if (RREGEXP(re)->usecnt == 0) {
- regex_t tmp_reg;
- r = onig_new_without_alloc(&tmp_reg, (UChar *)ptr, (UChar *)(ptr + len),
- reg->options, enc,
- OnigDefaultSyntax, &einfo);
-
- if (r) {
- /* There was an error so perform cleanups. */
- onig_free_body(&tmp_reg);
- }
- else {
- onig_free_body(reg);
- /* There are no errors so set reg to tmp_reg. */
- *reg = tmp_reg;
- }
- }
- else {
- r = onig_new(&reg, (UChar *)ptr, (UChar *)(ptr + len),
- reg->options, enc,
- OnigDefaultSyntax, &einfo);
- }
-
+ r = onig_new(&reg, (UChar *)ptr, (UChar *)(ptr + len),
+ reg->options, enc,
+ OnigDefaultSyntax, &einfo);
if (r) {
onig_error_code_to_str((UChar*)err, r, &einfo);
- rb_reg_raise(err, re);
+ rb_reg_raise(pattern, RREGEXP_SRC_LEN(re), err, re);
}
reg->timelimit = timelimit;
RB_GC_GUARD(unescaped);
- RB_GC_GUARD(src_str);
return reg;
}
-OnigPosition
-rb_reg_onig_match(VALUE re, VALUE str,
- OnigPosition (*match)(regex_t *reg, VALUE str, struct re_registers *regs, void *args),
- void *args, struct re_registers *regs)
+regex_t *
+rb_reg_prepare_re(VALUE re, VALUE str)
{
- regex_t *reg = rb_reg_prepare_re(re, str);
-
- bool tmpreg = reg != RREGEXP_PTR(re);
- if (!tmpreg) RREGEXP(re)->usecnt++;
-
- OnigPosition result = match(reg, str, regs, args);
-
- if (!tmpreg) RREGEXP(re)->usecnt--;
- if (tmpreg) {
- onig_free(reg);
- }
-
- if (result < 0) {
- onig_region_free(regs, 0);
-
- if (result != ONIG_MISMATCH) {
- onig_errmsg_buffer err = "";
- onig_error_code_to_str((UChar*)err, (int)result);
- rb_reg_raise(err, re);
- }
- }
-
- return result;
+ onig_errmsg_buffer err = "";
+ return rb_reg_prepare_re0(re, str, err);
}
long
@@ -1712,91 +1677,68 @@ rb_reg_adjust_startpos(VALUE re, VALUE str, long pos, int reverse)
return pos;
}
-struct reg_onig_search_args {
- long pos;
- long range;
-};
-
-static OnigPosition
-reg_onig_search(regex_t *reg, VALUE str, struct re_registers *regs, void *args_ptr)
-{
- struct reg_onig_search_args *args = (struct reg_onig_search_args *)args_ptr;
- const char *ptr;
- long len;
- RSTRING_GETMEM(str, ptr, len);
-
- return onig_search(
- reg,
- (UChar *)ptr,
- (UChar *)(ptr + len),
- (UChar *)(ptr + args->pos),
- (UChar *)(ptr + args->range),
- regs,
- ONIG_OPTION_NONE);
-}
-
-struct rb_reg_onig_match_args {
- VALUE re;
- VALUE str;
- struct reg_onig_search_args args;
- struct re_registers regs;
-
- OnigPosition result;
-};
-
-static VALUE
-rb_reg_onig_match_try(VALUE value_args)
-{
- struct rb_reg_onig_match_args *args = (struct rb_reg_onig_match_args *)value_args;
- args->result = rb_reg_onig_match(args->re, args->str, reg_onig_search, &args->args, &args->regs);
- return Qnil;
-}
-
/* returns byte offset */
static long
rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_backref_str, VALUE *set_match)
{
- long len = RSTRING_LEN(str);
+ long result;
+ VALUE match;
+ struct re_registers regi, *regs = &regi;
+ char *start, *range;
+ long len;
+ regex_t *reg;
+ int tmpreg;
+ onig_errmsg_buffer err = "";
+
+ RSTRING_GETMEM(str, start, len);
+ range = start;
if (pos > len || pos < 0) {
rb_backref_set(Qnil);
return -1;
}
- struct rb_reg_onig_match_args args = {
- .re = re,
- .str = str,
- .args = {
- .pos = pos,
- .range = reverse ? 0 : len,
- },
- .regs = {0}
- };
-
- /* If there is a timeout set, then rb_reg_onig_match could raise a
- * Regexp::TimeoutError so we want to protect it from leaking memory. */
- if (rb_reg_match_time_limit) {
- int state;
- rb_protect(rb_reg_onig_match_try, (VALUE)&args, &state);
- if (state) {
- onig_region_free(&args.regs, false);
- rb_jump_tag(state);
- }
+ reg = rb_reg_prepare_re0(re, str, err);
+ tmpreg = reg != RREGEXP_PTR(re);
+ if (!tmpreg) RREGEXP(re)->usecnt++;
+
+ MEMZERO(regs, struct re_registers, 1);
+ if (!reverse) {
+ range += len;
}
- else {
- rb_reg_onig_match_try((VALUE)&args);
+ result = onig_search(reg,
+ (UChar*)start,
+ ((UChar*)(start + len)),
+ ((UChar*)(start + pos)),
+ ((UChar*)range),
+ regs, ONIG_OPTION_NONE);
+ if (!tmpreg) RREGEXP(re)->usecnt--;
+ if (tmpreg) {
+ if (RREGEXP(re)->usecnt) {
+ onig_free(reg);
+ }
+ else {
+ onig_free(RREGEXP_PTR(re));
+ RREGEXP_PTR(re) = reg;
+ }
}
-
- if (args.result == ONIG_MISMATCH) {
- rb_backref_set(Qnil);
- return ONIG_MISMATCH;
+ if (result < 0) {
+ if (regs == &regi)
+ onig_region_free(regs, 0);
+ if (result == ONIG_MISMATCH) {
+ rb_backref_set(Qnil);
+ return result;
+ }
+ else {
+ onig_error_code_to_str((UChar*)err, (int)result);
+ rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re);
+ }
}
- VALUE match = match_alloc(rb_cMatch);
- rb_matchext_t *rm = RMATCH_EXT(match);
- rm->regs = args.regs;
+ match = match_alloc(rb_cMatch);
+ memcpy(RMATCH_REGS(match), regs, sizeof(struct re_registers));
if (set_backref_str) {
- RB_OBJ_WRITE(match, &RMATCH(match)->str, rb_str_new4(str));
+ RMATCH(match)->str = rb_str_new4(str);
}
else {
/* Note that a MatchData object with RMATCH(match)->str == 0 is incomplete!
@@ -1806,11 +1748,11 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back
rb_obj_hide(match);
}
- RB_OBJ_WRITE(match, &RMATCH(match)->regexp, re);
+ RMATCH(match)->regexp = re;
rb_backref_set(match);
if (set_match) *set_match = match;
- return args.result;
+ return result;
}
long
@@ -1825,39 +1767,74 @@ rb_reg_search(VALUE re, VALUE str, long pos, int reverse)
return rb_reg_search0(re, str, pos, reverse, 1);
}
-static OnigPosition
-reg_onig_match(regex_t *reg, VALUE str, struct re_registers *regs, void *_)
+bool
+rb_reg_start_with_p(VALUE re, VALUE str)
{
+ long result;
+ VALUE match;
+ struct re_registers regi, *regs = &regi;
+ regex_t *reg;
+ int tmpreg;
+ onig_errmsg_buffer err = "";
+
+ reg = rb_reg_prepare_re0(re, str, err);
+ tmpreg = reg != RREGEXP_PTR(re);
+ if (!tmpreg) RREGEXP(re)->usecnt++;
+
+ match = rb_backref_get();
+ if (!NIL_P(match)) {
+ if (FL_TEST(match, MATCH_BUSY)) {
+ match = Qnil;
+ }
+ else {
+ regs = RMATCH_REGS(match);
+ }
+ }
+ if (NIL_P(match)) {
+ MEMZERO(regs, struct re_registers, 1);
+ }
const char *ptr;
long len;
RSTRING_GETMEM(str, ptr, len);
+ result = onig_match(reg,
+ (UChar*)(ptr),
+ ((UChar*)(ptr + len)),
+ (UChar*)(ptr),
+ regs, ONIG_OPTION_NONE);
+ if (!tmpreg) RREGEXP(re)->usecnt--;
+ if (tmpreg) {
+ if (RREGEXP(re)->usecnt) {
+ onig_free(reg);
+ }
+ else {
+ onig_free(RREGEXP_PTR(re));
+ RREGEXP_PTR(re) = reg;
+ }
+ }
+ if (result < 0) {
+ if (regs == &regi)
+ onig_region_free(regs, 0);
+ if (result == ONIG_MISMATCH) {
+ rb_backref_set(Qnil);
+ return false;
+ }
+ else {
+ onig_error_code_to_str((UChar*)err, (int)result);
+ rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re);
+ }
+ }
- return onig_match(
- reg,
- (UChar *)ptr,
- (UChar *)(ptr + len),
- (UChar *)ptr,
- regs,
- ONIG_OPTION_NONE);
-}
-
-bool
-rb_reg_start_with_p(VALUE re, VALUE str)
-{
- VALUE match = rb_backref_get();
- if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) {
+ if (NIL_P(match)) {
+ int err;
match = match_alloc(rb_cMatch);
+ err = rb_reg_region_copy(RMATCH_REGS(match), regs);
+ onig_region_free(regs, 0);
+ if (err) rb_memerror();
}
- struct re_registers *regs = RMATCH_REGS(match);
-
- if (rb_reg_onig_match(re, str, reg_onig_match, NULL, regs) == ONIG_MISMATCH) {
- rb_backref_set(Qnil);
- return false;
- }
+ RMATCH(match)->str = rb_str_new4(str);
- RB_OBJ_WRITE(match, &RMATCH(match)->str, rb_str_new4(str));
- RB_OBJ_WRITE(match, &RMATCH(match)->regexp, re);
+ RMATCH(match)->regexp = re;
rb_backref_set(match);
return true;
@@ -1979,37 +1956,21 @@ rb_reg_match_post(VALUE match)
return str;
}
-static int
-match_last_index(VALUE match)
+VALUE
+rb_reg_match_last(VALUE match)
{
int i;
struct re_registers *regs;
- if (NIL_P(match)) return -1;
+ if (NIL_P(match)) return Qnil;
match_check(match);
regs = RMATCH_REGS(match);
- if (BEG(0) == -1) return -1;
+ if (BEG(0) == -1) return Qnil;
for (i=regs->num_regs-1; BEG(i) == -1 && i > 0; i--)
;
- return i;
-}
-
-VALUE
-rb_reg_match_last(VALUE match)
-{
- int i = match_last_index(match);
- if (i <= 0) return Qnil;
- struct re_registers *regs = RMATCH_REGS(match);
- return rb_str_subseq(RMATCH(match)->str, BEG(i), END(i) - BEG(i));
-}
-
-VALUE
-rb_reg_last_defined(VALUE match)
-{
- int i = match_last_index(match);
- if (i < 0) return Qnil;
- return RBOOL(i);
+ if (i == 0) return Qnil;
+ return rb_reg_nth_match(i, match);
}
static VALUE
@@ -2197,17 +2158,6 @@ match_ary_aref(VALUE match, VALUE idx, VALUE result)
* m['foo'] # => "h"
* m[:bar] # => "ge"
*
- * If multiple captures have the same name, returns the last matched
- * substring.
- *
- * m = /(?<foo>.)(?<foo>.+)/.match("hoge")
- * # => #<MatchData "hoge" foo:"h" foo:"oge">
- * m[:foo] #=> "oge"
- *
- * m = /\W(?<foo>.+)|\w(?<foo>.+)|(?<foo>.+)/.match("hoge")
- * #<MatchData "hoge" foo:nil foo:"oge" foo:nil>
- * m[:foo] #=> "oge"
- *
*/
static VALUE
@@ -2370,7 +2320,7 @@ match_named_captures_iter(const OnigUChar *name, const OnigUChar *name_end,
/*
* call-seq:
- * named_captures(symbolize_names: false) -> hash
+ * named_captures -> hash
*
* Returns a hash of the named captures;
* each key is a capture name; each value is its captured string or +nil+:
@@ -2391,17 +2341,10 @@ match_named_captures_iter(const OnigUChar *name, const OnigUChar *name_end,
* # => #<MatchData "01" a:"0" a:"1">
* m.named_captures #=> {"a" => "1"}
*
- * If keyword argument +symbolize_names+ is given
- * a true value, the keys in the resulting hash are Symbols:
- *
- * m = /(?<a>.)(?<a>.)/.match("01")
- * # => #<MatchData "01" a:"0" a:"1">
- * m.named_captures(symbolize_names: true) #=> {:a => "1"}
- *
*/
static VALUE
-match_named_captures(int argc, VALUE *argv, VALUE match)
+match_named_captures(VALUE match)
{
VALUE hash;
struct MEMO *memo;
@@ -2410,27 +2353,8 @@ match_named_captures(int argc, VALUE *argv, VALUE match)
if (NIL_P(RMATCH(match)->regexp))
return rb_hash_new();
- VALUE opt;
- VALUE symbolize_names = 0;
-
- rb_scan_args(argc, argv, "0:", &opt);
-
- if (!NIL_P(opt)) {
- static ID keyword_ids[1];
-
- VALUE symbolize_names_val;
-
- if (!keyword_ids[0]) {
- keyword_ids[0] = rb_intern_const("symbolize_names");
- }
- rb_get_kwargs(opt, keyword_ids, 0, 1, &symbolize_names_val);
- if (!UNDEF_P(symbolize_names_val) && RTEST(symbolize_names_val)) {
- symbolize_names = 1;
- }
- }
-
hash = rb_hash_new();
- memo = MEMO_NEW(hash, match, symbolize_names);
+ memo = MEMO_NEW(hash, match, 0);
onig_foreach_name(RREGEXP(RMATCH(match)->regexp)->ptr, match_named_captures_iter, (void*)memo);
@@ -2447,7 +2371,7 @@ match_named_captures(int argc, VALUE *argv, VALUE match)
* m.deconstruct_keys([:hours, :minutes]) # => {:hours => "18", :minutes => "37"}
* m.deconstruct_keys(nil) # => {:hours => "18", :minutes => "37", :seconds => "22"}
*
- * Returns an empty hash if no named captures were defined:
+ * Returns an empty hash of no named captures were defined:
*
* m = /(\d{2}):(\d{2}):(\d{2})/.match("18:37:22")
* m.deconstruct_keys(nil) # => {}
@@ -2546,10 +2470,10 @@ match_inspect_name_iter(const OnigUChar *name, const OnigUChar *name_end,
}
/*
- * call-seq:
- * inspect -> string
+ * call-seq:
+ * inspect -> string
*
- * Returns a string representation of +self+:
+ * Returns a string representation of +self+:
*
* m = /.$/.match("foo")
* # => #<MatchData "o">
@@ -2564,6 +2488,7 @@ match_inspect_name_iter(const OnigUChar *name, const OnigUChar *name_end,
* m.inspect # => "#<MatchData \"fo\" 1:\"f\" 2:nil 3:\"o\">"
*
* Related: MatchData#to_s.
+ *
*/
static VALUE
@@ -3266,15 +3191,6 @@ rb_reg_preprocess_dregexp(VALUE ary, int options)
return result;
}
-static void
-rb_reg_initialize_check(VALUE obj)
-{
- rb_check_frozen(obj);
- if (RREGEXP_PTR(obj)) {
- rb_raise(rb_eTypeError, "already initialized regexp");
- }
-}
-
static int
rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,
int options, onig_errmsg_buffer err,
@@ -3285,7 +3201,12 @@ rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,
rb_encoding *fixed_enc = 0;
rb_encoding *a_enc = rb_ascii8bit_encoding();
- rb_reg_initialize_check(obj);
+ rb_check_frozen(obj);
+ if (FL_TEST(obj, REG_LITERAL))
+ rb_raise(rb_eSecurityError, "can't modify literal regexp");
+ if (re->ptr)
+ rb_raise(rb_eTypeError, "already initialized regexp");
+ re->ptr = 0;
if (rb_enc_dummy_p(enc)) {
errcpy(err, "can't make regexp with dummy encoding");
@@ -3362,7 +3283,7 @@ rb_reg_initialize_str(VALUE obj, VALUE str, int options, onig_errmsg_buffer err,
static VALUE
rb_reg_s_alloc(VALUE klass)
{
- NEWOBJ_OF(re, struct RRegexp, klass, T_REGEXP | (RGENGC_WB_PROTECTED_REGEXP ? FL_WB_PROTECTED : 0), sizeof(struct RRegexp), 0);
+ NEWOBJ_OF(re, struct RRegexp, klass, T_REGEXP | (RGENGC_WB_PROTECTED_REGEXP ? FL_WB_PROTECTED : 0));
re->ptr = 0;
RB_OBJ_WRITE(re, &re->src, 0);
@@ -3409,7 +3330,7 @@ rb_reg_init_str_enc(VALUE re, VALUE s, rb_encoding *enc, int options)
return re;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_reg_new_ary(VALUE ary, int opt)
{
VALUE re = rb_reg_new_str(rb_reg_preprocess_dregexp(ary, opt), opt);
@@ -3448,6 +3369,7 @@ rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline)
rb_set_errinfo(rb_reg_error_desc(str, options, err));
return Qnil;
}
+ FL_SET(re, REG_LITERAL);
rb_obj_freeze(re);
return re;
}
@@ -3507,6 +3429,8 @@ reg_hash(VALUE re)
* /foo/ == Regexp.new('food') # => false
* /foo/ == Regexp.new("abc".force_encoding("euc-jp")) # => false
*
+ * Regexp#eql? is an alias for Regexp#==.
+ *
*/
VALUE
@@ -3557,6 +3481,9 @@ match_hash(VALUE match)
* Returns +true+ if +object+ is another \MatchData object
* whose target string, regexp, match, and captures
* are the same as +self+, +false+ otherwise.
+ *
+ * MatchData#eql? is an alias for MatchData#==.
+ *
*/
static VALUE
@@ -3621,7 +3548,7 @@ reg_match_pos(VALUE re, VALUE *strp, long pos, VALUE* set_match)
* Returns the integer index (in characters) of the first match
* for +self+ and +string+, or +nil+ if none;
* also sets the
- * {rdoc-ref:Regexp global variables}[rdoc-ref:Regexp@Global+Variables]:
+ * {rdoc-ref:Regexp Global Variables}[rdoc-ref:Regexp@Regexp+Global+Variables]:
*
* /at/ =~ 'input data' # => 7
* $~ # => #<MatchData "at">
@@ -3634,7 +3561,7 @@ reg_match_pos(VALUE re, VALUE *strp, long pos, VALUE* set_match)
* - Is a regexp literal;
* see {Regexp Literals}[rdoc-ref:literals.rdoc@Regexp+Literals].
* - Does not contain interpolations;
- * see {Regexp interpolation}[rdoc-ref:Regexp@Interpolation+Mode].
+ * see {Regexp Interpolation}[rdoc-ref:Regexp@Regexp+Interpolation].
* - Is at the left of the expression.
*
* Example:
@@ -3837,6 +3764,12 @@ rb_reg_match_m_p(int argc, VALUE *argv, VALUE re)
VALUE
rb_reg_match_p(VALUE re, VALUE str, long pos)
{
+ regex_t *reg;
+ onig_errmsg_buffer err = "";
+ OnigPosition result;
+ const UChar *start, *end;
+ int tmpreg;
+
if (NIL_P(str)) return Qfalse;
str = SYMBOL_P(str) ? rb_sym2str(str) : StringValue(str);
if (pos) {
@@ -3851,13 +3784,33 @@ rb_reg_match_p(VALUE re, VALUE str, long pos)
pos = beg - RSTRING_PTR(str);
}
}
-
- struct reg_onig_search_args args = {
- .pos = pos,
- .range = RSTRING_LEN(str),
- };
-
- return rb_reg_onig_match(re, str, reg_onig_search, &args, NULL) == ONIG_MISMATCH ? Qfalse : Qtrue;
+ reg = rb_reg_prepare_re0(re, str, err);
+ tmpreg = reg != RREGEXP_PTR(re);
+ if (!tmpreg) RREGEXP(re)->usecnt++;
+ start = ((UChar*)RSTRING_PTR(str));
+ end = start + RSTRING_LEN(str);
+ result = onig_search(reg, start, end, start + pos, end,
+ NULL, ONIG_OPTION_NONE);
+ if (!tmpreg) RREGEXP(re)->usecnt--;
+ if (tmpreg) {
+ if (RREGEXP(re)->usecnt) {
+ onig_free(reg);
+ }
+ else {
+ onig_free(RREGEXP_PTR(re));
+ RREGEXP_PTR(re) = reg;
+ }
+ }
+ if (result < 0) {
+ if (result == ONIG_MISMATCH) {
+ return Qfalse;
+ }
+ else {
+ onig_error_code_to_str((UChar*)err, (int)result);
+ rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re);
+ }
+ }
+ return Qtrue;
}
/*
@@ -3895,26 +3848,6 @@ set_timeout(rb_hrtime_t *hrt, VALUE timeout)
double2hrtime(hrt, timeout_d);
}
-static VALUE
-reg_copy(VALUE copy, VALUE orig)
-{
- int r;
- regex_t *re;
-
- rb_reg_initialize_check(copy);
- if ((r = onig_reg_copy(&re, RREGEXP_PTR(orig))) != 0) {
- /* ONIGERR_MEMORY only */
- rb_raise(rb_eRegexpError, "%s", onig_error_code_to_format(r));
- }
- RREGEXP_PTR(copy) = re;
- RB_OBJ_WRITE(copy, &RREGEXP(copy)->src, RREGEXP(orig)->src);
- RREGEXP_PTR(copy)->timelimit = RREGEXP_PTR(orig)->timelimit;
- rb_enc_copy(copy, orig);
- FL_SET_RAW(copy, FL_TEST_RAW(orig, KCODE_FIXED|REG_ENCODING_NONE));
-
- return copy;
-}
-
struct reg_init_args {
VALUE str;
VALUE timeout;
@@ -3945,7 +3878,7 @@ void rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const ch
* Regexp.new('foo', 'i') # => /foo/i
* Regexp.new('foo', 'im') # => /foo/im
*
- * - The bit-wise OR of one or more of the constants
+ * - The logical OR of one or more of the constants
* Regexp::EXTENDED, Regexp::IGNORECASE, Regexp::MULTILINE, and
* Regexp::NOENCODING:
*
@@ -3957,8 +3890,6 @@ void rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const ch
* Regexp.new('foo', flags) # => /foo/mix
*
* - +nil+ or +false+, which is ignored.
- * - Any other truthy value, in which case the regexp will be
- * case-insensitive.
*
* If optional keyword argument +timeout+ is given,
* its float value overrides the timeout interval for the class,
@@ -3978,20 +3909,17 @@ void rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const ch
* r3 = Regexp.new(r, timeout: 3.14) # => /foo/m
* r3.timeout # => 3.14
*
+ * Regexp.compile is an alias for Regexp.new.
+ *
*/
static VALUE
rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
{
struct reg_init_args args;
- VALUE re = reg_extract_args(argc, argv, &args);
- if (NIL_P(re)) {
- reg_init_args(self, args.str, args.enc, args.flags);
- }
- else {
- reg_copy(self, re);
- }
+ reg_extract_args(argc, argv, &args);
+ reg_init_args(self, args.str, args.enc, args.flags);
set_timeout(&RREGEXP_PTR(self)->timelimit, args.timeout);
@@ -4003,10 +3931,10 @@ reg_extract_args(int argc, VALUE *argv, struct reg_init_args *args)
{
int flags = 0;
rb_encoding *enc = 0;
- VALUE str, src, opts = Qundef, kwargs;
+ VALUE str, src, opts = Qundef, n_flag = Qundef, kwargs;
VALUE re = Qnil;
- rb_scan_args(argc, argv, "11:", &src, &opts, &kwargs);
+ argc = rb_scan_args(argc, argv, "12:", &src, &opts, &n_flag, &kwargs);
args->timeout = Qnil;
if (!NIL_P(kwargs)) {
@@ -4017,6 +3945,10 @@ reg_extract_args(int argc, VALUE *argv, struct reg_init_args *args)
rb_get_kwargs(kwargs, keywords, 0, 1, &args->timeout);
}
+ if (argc == 3) {
+ rb_warn_deprecated_to_remove("3.3", "3rd argument to Regexp.new", "2nd argument");
+ }
+
if (RB_TYPE_P(src, T_REGEXP)) {
re = src;
@@ -4028,13 +3960,20 @@ reg_extract_args(int argc, VALUE *argv, struct reg_init_args *args)
str = RREGEXP_SRC(re);
}
else {
- if (!NIL_P(opts)) {
+ if (!UNDEF_P(opts)) {
int f;
if (FIXNUM_P(opts)) flags = FIX2INT(opts);
else if ((f = str_to_option(opts)) >= 0) flags = f;
- else if (rb_bool_expected(opts, "ignorecase", FALSE))
+ else if (!NIL_P(opts) && rb_bool_expected(opts, "ignorecase", FALSE))
flags = ONIG_OPTION_IGNORECASE;
}
+ if (!NIL_OR_UNDEF_P(n_flag)) {
+ char *kcode = StringValuePtr(n_flag);
+ if (kcode[0] == 'n' || kcode[0] == 'N') {
+ enc = rb_ascii8bit_encoding();
+ flags |= ARG_ENCODING_NONE;
+ }
+ }
str = StringValue(src);
}
args->str = str;
@@ -4165,6 +4104,8 @@ rb_reg_quote(VALUE str)
* r = Regexp.new(Regexp.escape(s)) # => /\\\\\\\*\\\?\\\{\\\}\\\./
* r.match(s) # => #<MatchData "\\\\\\*\\?\\{\\}\\.">
*
+ * Regexp.quote is an alias for Regexp.escape.
+ *
*/
static VALUE
@@ -4414,7 +4355,7 @@ rb_reg_init_copy(VALUE copy, VALUE re)
{
if (!OBJ_INIT_COPY(copy, re)) return copy;
rb_reg_check(re);
- return reg_copy(copy, re);
+ return rb_reg_init_str(copy, RREGEXP_SRC(re), rb_reg_options(re));
}
VALUE
@@ -4588,7 +4529,7 @@ match_setter(VALUE val, ID _x, VALUE *_y)
*
* With no argument, returns the value of <tt>$!</tt>,
* which is the result of the most recent pattern match
- * (see {Regexp global variables}[rdoc-ref:Regexp@Global+Variables]):
+ * (see {Regexp Global Variables}[rdoc-ref:Regexp@Regexp+Global+Variables]):
*
* /c(.)t/ =~ 'cat' # => 0
* Regexp.last_match # => #<MatchData "cat" 1:"a">
@@ -4637,9 +4578,12 @@ re_warn(const char *s)
rb_warn("%s", s);
}
+// The process-global timeout for regexp matching
+rb_hrtime_t rb_reg_match_time_limit = 0;
+
// This function is periodically called during regexp matching
-bool
-rb_reg_timeout_p(regex_t *reg, void *end_time_)
+void
+rb_reg_check_timeout(regex_t *reg, void *end_time_)
{
rb_hrtime_t *end_time = (rb_hrtime_t *)end_time_;
@@ -4664,18 +4608,10 @@ rb_reg_timeout_p(regex_t *reg, void *end_time_)
}
else {
if (*end_time < rb_hrtime_now()) {
- // Timeout has exceeded
- return true;
+ // timeout is exceeded
+ rb_raise(rb_eRegexpTimeoutError, "regexp match timeout");
}
}
-
- return false;
-}
-
-void
-rb_reg_raise_timeout(void)
-{
- rb_raise(rb_eRegexpTimeoutError, "regexp match timeout");
}
/*
@@ -4756,7 +4692,7 @@ rb_reg_timeout_get(VALUE re)
/*
* Document-class: Regexp
*
- * :include: doc/_regexp.rdoc
+ * :include: doc/regexp.rdoc
*/
void
@@ -4850,7 +4786,7 @@ Init_Regexp(void)
rb_define_method(rb_cMatch, "[]", match_aref, -1);
rb_define_method(rb_cMatch, "captures", match_captures, 0);
rb_define_alias(rb_cMatch, "deconstruct", "captures");
- rb_define_method(rb_cMatch, "named_captures", match_named_captures, -1);
+ rb_define_method(rb_cMatch, "named_captures", match_named_captures, 0);
rb_define_method(rb_cMatch, "deconstruct_keys", match_deconstruct_keys, 1);
rb_define_method(rb_cMatch, "values_at", match_values_at, -1);
rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
diff --git a/regcomp.c b/regcomp.c
index 7bba1455e3..be85d85f93 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -195,7 +195,8 @@ unset_addr_list_init(UnsetAddrList* uslist, int size)
static void
unset_addr_list_end(UnsetAddrList* uslist)
{
- xfree(uslist->us);
+ if (IS_NOT_NULL(uslist->us))
+ xfree(uslist->us);
}
static int
@@ -1273,10 +1274,6 @@ compile_length_enclose_node(EncloseNode* node, regex_t* reg)
break;
case ENCLOSE_STOP_BACKTRACK:
- /* Disable POP_STOP_BT optimization for simple repeat under the match cache */
- /* optimization because the match cache optimization pushes an extra item to */
- /* the stack and it breaks the assumption for this optimization. */
-#ifndef USE_MATCH_CACHE
if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
QtfrNode* qn = NQTFR(node->target);
tlen = compile_length_tree(qn->target, reg);
@@ -1286,11 +1283,8 @@ compile_length_enclose_node(EncloseNode* node, regex_t* reg)
+ SIZE_OP_PUSH + tlen + SIZE_OP_POP + SIZE_OP_JUMP;
}
else {
-#endif
len = SIZE_OP_PUSH_STOP_BT + tlen + SIZE_OP_POP_STOP_BT;
-#ifndef USE_MATCH_CACHE
}
-#endif
break;
case ENCLOSE_CONDITION:
@@ -1402,10 +1396,6 @@ compile_enclose_node(EncloseNode* node, regex_t* reg)
break;
case ENCLOSE_STOP_BACKTRACK:
- /* Disable POP_STOP_BT optimization for simple repeat under the match cache */
- /* optimization because the match cache optimization pushes an extra item to */
- /* the stack and it breaks the assumption for this optimization. */
-#ifndef USE_MATCH_CACHE
if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
QtfrNode* qn = NQTFR(node->target);
r = compile_tree_n_times(qn->target, qn->lower, reg);
@@ -1424,15 +1414,12 @@ compile_enclose_node(EncloseNode* node, regex_t* reg)
-((int )SIZE_OP_PUSH + len + (int )SIZE_OP_POP + (int )SIZE_OP_JUMP));
}
else {
-#endif
r = add_opcode(reg, OP_PUSH_STOP_BT);
if (r) return r;
r = compile_tree(node->target, reg);
if (r) return r;
r = add_opcode(reg, OP_POP_STOP_BT);
-#ifndef USE_MATCH_CACHE
}
-#endif
break;
case ENCLOSE_CONDITION:
@@ -3395,7 +3382,7 @@ next_setup(Node* node, Node* next_node, regex_t* reg)
}
else if (type == NT_ENCLOSE) {
EncloseNode* en = NENCLOSE(node);
- if (en->type == ENCLOSE_MEMORY && !IS_ENCLOSE_CALLED(en)) {
+ if (en->type == ENCLOSE_MEMORY) {
node = en->target;
goto retry;
}
@@ -5662,12 +5649,12 @@ extern void
onig_free_body(regex_t* reg)
{
if (IS_NOT_NULL(reg)) {
- xfree(reg->p);
- xfree(reg->exact);
- xfree(reg->int_map);
- xfree(reg->int_map_backward);
- xfree(reg->repeat_range);
- onig_free(reg->chain);
+ if (IS_NOT_NULL(reg->p)) xfree(reg->p);
+ if (IS_NOT_NULL(reg->exact)) xfree(reg->exact);
+ if (IS_NOT_NULL(reg->int_map)) xfree(reg->int_map);
+ if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward);
+ if (IS_NOT_NULL(reg->repeat_range)) xfree(reg->repeat_range);
+ if (IS_NOT_NULL(reg->chain)) onig_free(reg->chain);
#ifdef USE_NAMED_GROUP
onig_names_free(reg);
@@ -5684,80 +5671,6 @@ onig_free(regex_t* reg)
}
}
-static void*
-dup_copy(const void *ptr, size_t size)
-{
- void *newptr = xmalloc(size);
- if (IS_NOT_NULL(newptr)) {
- memcpy(newptr, ptr, size);
- }
- return newptr;
-}
-
-extern int
-onig_reg_copy(regex_t** nreg, regex_t* oreg)
-{
- if (IS_NOT_NULL(oreg)) {
- regex_t *reg = *nreg = (regex_t* )xmalloc(sizeof(regex_t));
- if (IS_NULL(reg)) return ONIGERR_MEMORY;
-
- *reg = *oreg;
-
-# define COPY_FAILED(mem, size) IS_NULL(reg->mem = dup_copy(reg->mem, size))
-
- if (IS_NOT_NULL(reg->exact)) {
- size_t exact_size = reg->exact_end - reg->exact;
- if (COPY_FAILED(exact, exact_size))
- goto err;
- (reg)->exact_end = (reg)->exact + exact_size;
- }
-
- if (IS_NOT_NULL(reg->int_map)) {
- if (COPY_FAILED(int_map, sizeof(int) * ONIG_CHAR_TABLE_SIZE))
- goto err_int_map;
- }
- if (IS_NOT_NULL(reg->int_map_backward)) {
- if (COPY_FAILED(int_map_backward, sizeof(int) * ONIG_CHAR_TABLE_SIZE))
- goto err_int_map_backward;
- }
- if (IS_NOT_NULL(reg->p)) {
- if (COPY_FAILED(p, reg->alloc))
- goto err_p;
- }
- if (IS_NOT_NULL(reg->repeat_range)) {
- if (COPY_FAILED(repeat_range, reg->repeat_range_alloc * sizeof(OnigRepeatRange)))
- goto err_repeat_range;
- }
- if (IS_NOT_NULL(reg->name_table)) {
- if (onig_names_copy(reg, oreg))
- goto err_name_table;
- }
- if (IS_NOT_NULL(reg->chain)) {
- if (onig_reg_copy(&reg->chain, reg->chain))
- goto err_chain;
- }
- return 0;
-# undef COPY_FAILED
-
- err_chain:
- onig_names_free(reg);
- err_name_table:
- xfree(reg->repeat_range);
- err_repeat_range:
- xfree(reg->p);
- err_p:
- xfree(reg->int_map_backward);
- err_int_map_backward:
- xfree(reg->int_map);
- err_int_map:
- xfree(reg->exact);
- err:
- xfree(reg);
- return ONIGERR_MEMORY;
- }
- return 0;
-}
-
#ifdef RUBY
size_t
onig_memsize(const regex_t *reg)
@@ -6014,8 +5927,8 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
}
onig_node_free(root);
- xfree(scan_env.mem_nodes_dynamic);
-
+ if (IS_NOT_NULL(scan_env.mem_nodes_dynamic))
+ xfree(scan_env.mem_nodes_dynamic);
return r;
}
@@ -6087,15 +6000,20 @@ onig_new(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax,
OnigErrorInfo* einfo)
{
+ int r;
+
*reg = (regex_t* )xmalloc(sizeof(regex_t));
if (IS_NULL(*reg)) return ONIGERR_MEMORY;
- int r = onig_new_without_alloc(*reg, pattern, pattern_end, option, enc, syntax, einfo);
+ r = onig_reg_init(*reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
+ if (r) goto err;
+
+ r = onig_compile(*reg, pattern, pattern_end, einfo);
if (r) {
+ err:
onig_free(*reg);
*reg = NULL;
}
-
return r;
}
diff --git a/regenc.c b/regenc.c
index fc131d2533..eb523e1ae5 100644
--- a/regenc.c
+++ b/regenc.c
@@ -57,7 +57,7 @@ onigenc_mbclen(const OnigUChar* p,const OnigUChar* e, OnigEncoding enc)
int ret = ONIGENC_PRECISE_MBC_ENC_LEN(enc, p, e);
if (ONIGENC_MBCLEN_CHARFOUND_P(ret)) {
ret = ONIGENC_MBCLEN_CHARFOUND_LEN(ret);
- if (ret > (int)(e - p)) ret = (int)(e - p); // just for case
+ if (p + ret > e) ret = (int)(e - p); // just for case
return ret;
}
else if (ONIGENC_MBCLEN_NEEDMORE_P(ret)) {
diff --git a/regenc.h b/regenc.h
index 352a8d7980..4b4d21a715 100644
--- a/regenc.h
+++ b/regenc.h
@@ -118,6 +118,11 @@ typedef struct {
typedef struct {
short int len;
+#if defined(__has_attribute)
+# if __has_attribute(nonstring)
+ __attribute__((nonstring))
+# endif
+#endif
const UChar name[6];
int ctype;
} PosixBracketEntryType;
diff --git a/regexec.c b/regexec.c
index 460d6e1821..47fc88c9c2 100644
--- a/regexec.c
+++ b/regexec.c
@@ -231,46 +231,22 @@ onig_get_capture_tree(OnigRegion* region)
}
#endif /* USE_CAPTURE_HISTORY */
-#ifdef USE_MATCH_CACHE
-
-/*
-Glossary for "match cache"
-
-"match cache" or "match cache optimization"
-The `Regexp#match` optimization by using a cache.
-
-"cache opcode"
-A cachable opcode (e.g. `OP_PUSH`, `OP_REPEAT`, etc).
-It is corresponding to some cache points.
-
-"cache point"
-A cachable point on matching.
-Usually, one-to-one corresponding between a cache opcode and a cache point exists,
-but cache opcodes between `OP_REPEAT` and `OP_REPEAT_INC` have some corresponding
-cache points depending on repetition counts.
-
-"match cache point"
-A pair of a cache point and a position on an input string.
-We encode a match cache point to an integer value by the following equation:
-"match cache point" = "position on input string" * "total number of cache points" + "cache point"
-
-"match cache buffer"
-A bit-array for memoizing (recording) match cache points once backtracked.
-*/
-
-static OnigPosition count_num_cache_opcodes_inner(
- const regex_t* reg,
- MemNumType current_repeat_mem, int lookaround_nesting,
- UChar** pp, long* num_cache_opcodes_ptr
-)
+#ifdef USE_CACHE_MATCH_OPT
+
+/* count number of jump-like opcodes for allocation of cache memory. */
+static OnigPosition
+count_num_cache_opcode(regex_t* reg, long* num, long* table_size)
{
- UChar* p = *pp;
- UChar* pend = reg->p + reg->used;
+ UChar* p = reg->p;
+ UChar* pend = p + reg->used;
LengthType len;
- MemNumType repeat_mem;
+ MemNumType mem;
+ MemNumType current_mem = -1;
+ long current_mem_num = 0;
OnigEncoding enc = reg->enc;
- long num_cache_opcodes = *num_cache_opcodes_ptr;
- OnigPosition result;
+
+ *num = 0;
+ *table_size = 0;
while (p < pend) {
switch (*p++) {
@@ -284,7 +260,7 @@ static OnigPosition count_num_cache_opcodes_inner(
case OP_EXACT4: p += 4; break;
case OP_EXACT5: p += 5; break;
case OP_EXACTN:
- GET_LENGTH_INC(len, p); p += len; break;
+ GET_LENGTH_INC(len, p); p += len; break;
case OP_EXACTMB2N1: p += 2; break;
case OP_EXACTMB2N2: p += 4; break;
case OP_EXACTMB2N3: p += 6; break;
@@ -299,7 +275,7 @@ static OnigPosition count_num_cache_opcodes_inner(
GET_LENGTH_INC(len, p);
p += mb_len * len;
}
- break;
+ break;
case OP_EXACT1_IC:
len = enclen(enc, p, pend); p += len; break;
@@ -308,7 +284,7 @@ static OnigPosition count_num_cache_opcodes_inner(
case OP_CCLASS:
case OP_CCLASS_NOT:
- p += SIZE_BITSET; break;
+ p += SIZE_BITSET; break;
case OP_CCLASS_MB:
case OP_CCLASS_MB_NOT:
GET_LENGTH_INC(len, p); p += len; break;
@@ -324,10 +300,10 @@ static OnigPosition count_num_cache_opcodes_inner(
break;
case OP_ANYCHAR_STAR:
case OP_ANYCHAR_ML_STAR:
- num_cache_opcodes++; break;
+ *num += 1; *table_size += 1; break;
case OP_ANYCHAR_STAR_PEEK_NEXT:
case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
- p++; num_cache_opcodes++; break;
+ p++; *num += 1; *table_size += 1; break;
case OP_WORD:
case OP_NOT_WORD:
@@ -360,7 +336,7 @@ static OnigPosition count_num_cache_opcodes_inner(
case OP_BACKREF_MULTI:
case OP_BACKREF_MULTI_IC:
case OP_BACKREF_WITH_LEVEL:
- goto impossible;
+ goto fail;
case OP_MEMORY_START:
case OP_MEMORY_START_PUSH:
@@ -368,12 +344,7 @@ static OnigPosition count_num_cache_opcodes_inner(
case OP_MEMORY_END_PUSH_REC:
case OP_MEMORY_END:
case OP_MEMORY_END_REC:
- p += SIZE_MEMNUM;
- // A memory (capture) in look-around is found.
- if (lookaround_nesting != 0) {
- goto impossible;
- }
- break;
+ p += SIZE_MEMNUM; break;
case OP_KEEP:
break;
@@ -381,131 +352,91 @@ static OnigPosition count_num_cache_opcodes_inner(
case OP_FAIL:
break;
case OP_JUMP:
- p += SIZE_RELADDR;
+ p += SIZE_RELADDR;
break;
case OP_PUSH:
- p += SIZE_RELADDR;
- num_cache_opcodes++;
+ p += SIZE_RELADDR;
+ *num += 1;
+ *table_size += 1;
break;
case OP_POP:
break;
case OP_PUSH_OR_JUMP_EXACT1:
case OP_PUSH_IF_PEEK_NEXT:
- p += SIZE_RELADDR + 1; num_cache_opcodes++; break;
+ p += SIZE_RELADDR + 1; *num += 1; *table_size += 1; break;
case OP_REPEAT:
case OP_REPEAT_NG:
- if (current_repeat_mem != -1) {
+ if (current_mem != -1) {
// A nested OP_REPEAT is not yet supported.
- goto impossible;
+ goto fail;
}
- GET_MEMNUM_INC(repeat_mem, p);
+ GET_MEMNUM_INC(mem, p);
p += SIZE_RELADDR;
- if (reg->repeat_range[repeat_mem].lower == 0) {
- num_cache_opcodes++;
- }
- result = count_num_cache_opcodes_inner(reg, repeat_mem, lookaround_nesting, &p, &num_cache_opcodes);
- if (result < 0 || num_cache_opcodes < 0) {
- goto fail;
+ if (reg->repeat_range[mem].lower == 0) {
+ *num += 1;
+ *table_size += 1;
}
- {
- OnigRepeatRange *repeat_range = &reg->repeat_range[repeat_mem];
- if (repeat_range->lower < repeat_range->upper) {
- num_cache_opcodes++;
- }
- }
+ reg->repeat_range[mem].base_num = *num;
+ current_mem = mem;
+ current_mem_num = *num;
break;
case OP_REPEAT_INC:
case OP_REPEAT_INC_NG:
- GET_MEMNUM_INC(repeat_mem, p);
- if (repeat_mem != current_repeat_mem) {
+ GET_MEMNUM_INC(mem, p);
+ if (mem != current_mem) {
// A lone or invalid OP_REPEAT_INC is found.
- goto impossible;
+ goto fail;
}
- goto exit;
+ {
+ long inner_num = *num - current_mem_num;
+ OnigRepeatRange *repeat_range = &reg->repeat_range[mem];
+ repeat_range->inner_num = inner_num;
+ *num -= inner_num;
+ *num += inner_num * repeat_range->lower + (inner_num + 1) * (repeat_range->upper == 0x7fffffff ? 1 : repeat_range->upper - repeat_range->lower);
+ if (repeat_range->lower < repeat_range->upper) {
+ *table_size += 1;
+ }
+ current_mem = -1;
+ current_mem_num = 0;
+ }
+ break;
case OP_REPEAT_INC_SG:
case OP_REPEAT_INC_NG_SG:
- goto impossible;
+ // TODO: Support nested OP_REPEAT.
+ goto fail;
case OP_NULL_CHECK_START:
- p += SIZE_MEMNUM;
- break;
case OP_NULL_CHECK_END:
- case OP_NULL_CHECK_END_MEMST_PUSH:
- p += SIZE_MEMNUM;
- break;
case OP_NULL_CHECK_END_MEMST:
- p += SIZE_MEMNUM;
- break;
+ case OP_NULL_CHECK_END_MEMST_PUSH:
+ p += SIZE_MEMNUM; break;
case OP_PUSH_POS:
- if (lookaround_nesting < 0) {
- // A look-around nested in a atomic grouping is found.
- goto impossible;
- }
- result = count_num_cache_opcodes_inner(reg, current_repeat_mem, lookaround_nesting + 1, &p, &num_cache_opcodes);
- if (result < 0 || num_cache_opcodes < 0) {
- goto fail;
- }
- break;
- case OP_PUSH_POS_NOT:
- if (lookaround_nesting < 0) {
- // A look-around nested in a atomic grouping is found.
- goto impossible;
- }
- p += SIZE_RELADDR;
- result = count_num_cache_opcodes_inner(reg, current_repeat_mem, lookaround_nesting + 1, &p, &num_cache_opcodes);
- if (result < 0 || num_cache_opcodes < 0) {
- goto fail;
- }
- break;
- case OP_PUSH_LOOK_BEHIND_NOT:
- if (lookaround_nesting < 0) {
- // A look-around nested in a atomic grouping is found.
- goto impossible;
- }
- p += SIZE_RELADDR;
- p += SIZE_LENGTH;
- result = count_num_cache_opcodes_inner(reg, current_repeat_mem, lookaround_nesting + 1, &p, &num_cache_opcodes);
- if (result < 0 || num_cache_opcodes < 0) {
- goto fail;
- }
- break;
- case OP_PUSH_STOP_BT:
- if (lookaround_nesting != 0) {
- // A nested atomic grouping is found.
- goto impossible;
- }
- result = count_num_cache_opcodes_inner(reg, current_repeat_mem, -1, &p, &num_cache_opcodes);
- if (result < 0 || num_cache_opcodes < 0) {
- goto fail;
- }
- break;
case OP_POP_POS:
+ case OP_PUSH_POS_NOT:
case OP_FAIL_POS:
- case OP_FAIL_LOOK_BEHIND_NOT:
+ case OP_PUSH_STOP_BT:
case OP_POP_STOP_BT:
- goto exit;
case OP_LOOK_BEHIND:
- p += SIZE_LENGTH;
- break;
-
+ case OP_PUSH_LOOK_BEHIND_NOT:
+ case OP_FAIL_LOOK_BEHIND_NOT:
case OP_PUSH_ABSENT_POS:
case OP_ABSENT_END:
case OP_ABSENT:
- goto impossible;
+ goto fail;
case OP_CALL:
case OP_RETURN:
- goto impossible;
+ goto fail;
case OP_CONDITION:
- goto impossible;
+ goto fail;
case OP_STATE_CHECK_PUSH:
case OP_STATE_CHECK_PUSH_OR_JUMP:
case OP_STATE_CHECK:
case OP_STATE_CHECK_ANYCHAR_STAR:
case OP_STATE_CHECK_ANYCHAR_ML_STAR:
- goto impossible;
+ goto fail;
case OP_SET_OPTION_PUSH:
case OP_SET_OPTION:
@@ -513,69 +444,32 @@ static OnigPosition count_num_cache_opcodes_inner(
break;
default:
- goto bytecode_error;
+ goto bytecode_error;
}
}
-exit:
- *pp = p;
- *num_cache_opcodes_ptr = num_cache_opcodes;
return 0;
fail:
- *num_cache_opcodes_ptr = num_cache_opcodes;
- return result;
-
-impossible:
- *num_cache_opcodes_ptr = NUM_CACHE_OPCODES_IMPOSSIBLE;
+ *num = NUM_CACHE_OPCODE_FAIL;
return 0;
bytecode_error:
return ONIGERR_UNDEFINED_BYTECODE;
}
-/* count the total number of cache opcodes for allocating a match cache buffer. */
-static OnigPosition
-count_num_cache_opcodes(const regex_t* reg, long* num_cache_opcodes_ptr)
-{
- UChar* p = reg->p;
- *num_cache_opcodes_ptr = 0;
- OnigPosition result = count_num_cache_opcodes_inner(reg, -1, 0, &p, num_cache_opcodes_ptr);
- if (result == 0 && *num_cache_opcodes_ptr >= 0 && p != reg->p + reg->used) {
- return ONIGERR_UNDEFINED_BYTECODE;
- }
-
- return result;
-}
-
static OnigPosition
-init_cache_opcodes_inner(
- const regex_t* reg,
- MemNumType current_repeat_mem, int lookaround_nesting,
- OnigCacheOpcode** cache_opcodes_ptr, UChar** pp, long* num_cache_points_ptr
-)
+init_cache_index_table(regex_t* reg, OnigCacheIndex *table)
{
- UChar* p = *pp;
- UChar* pend = reg->p + reg->used;
UChar* pbegin;
+ UChar* p = reg->p;
+ UChar* pend = p + reg->used;
LengthType len;
- MemNumType repeat_mem;
+ MemNumType mem;
+ MemNumType current_mem = -1;
+ long num = 0;
+ long current_mem_num = 0;
OnigEncoding enc = reg->enc;
- long cache_point = *num_cache_points_ptr;
- OnigCacheOpcode *cache_opcodes = *cache_opcodes_ptr;
- OnigPosition result;
-
-# define INC_CACHE_OPCODES do {\
- cache_opcodes->addr = pbegin;\
- cache_opcodes->cache_point = cache_point;\
- cache_opcodes->outer_repeat_mem = current_repeat_mem;\
- cache_opcodes->num_cache_points_at_outer_repeat = 0;\
- cache_opcodes->num_cache_points_in_outer_repeat = 0;\
- cache_opcodes->lookaround_nesting = lookaround_nesting;\
- cache_opcodes->match_addr = NULL;\
- cache_point += lookaround_nesting != 0 ? 2 : 1;\
- cache_opcodes++;\
- } while (0)
while (p < pend) {
pbegin = p;
@@ -590,7 +484,7 @@ init_cache_opcodes_inner(
case OP_EXACT4: p += 4; break;
case OP_EXACT5: p += 5; break;
case OP_EXACTN:
- GET_LENGTH_INC(len, p); p += len; break;
+ GET_LENGTH_INC(len, p); p += len; break;
case OP_EXACTMB2N1: p += 2; break;
case OP_EXACTMB2N2: p += 4; break;
case OP_EXACTMB2N3: p += 6; break;
@@ -605,7 +499,7 @@ init_cache_opcodes_inner(
GET_LENGTH_INC(len, p);
p += mb_len * len;
}
- break;
+ break;
case OP_EXACT1_IC:
len = enclen(enc, p, pend); p += len; break;
@@ -614,7 +508,7 @@ init_cache_opcodes_inner(
case OP_CCLASS:
case OP_CCLASS_NOT:
- p += SIZE_BITSET; break;
+ p += SIZE_BITSET; break;
case OP_CCLASS_MB:
case OP_CCLASS_MB_NOT:
GET_LENGTH_INC(len, p); p += len; break;
@@ -630,12 +524,20 @@ init_cache_opcodes_inner(
break;
case OP_ANYCHAR_STAR:
case OP_ANYCHAR_ML_STAR:
- INC_CACHE_OPCODES;
+ table->addr = pbegin;
+ table->num = num - current_mem_num;
+ table->outer_repeat = current_mem;
+ num++;
+ table++;
break;
case OP_ANYCHAR_STAR_PEEK_NEXT:
case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
p++;
- INC_CACHE_OPCODES;
+ table->addr = pbegin;
+ table->num = num - current_mem_num;
+ table->outer_repeat = current_mem;
+ num++;
+ table++;
break;
case OP_WORD:
@@ -677,11 +579,7 @@ init_cache_opcodes_inner(
case OP_MEMORY_END_PUSH_REC:
case OP_MEMORY_END:
case OP_MEMORY_END_REC:
- p += SIZE_MEMNUM;
- if (lookaround_nesting != 0) {
- goto unexpected_bytecode_error;
- }
- break;
+ p += SIZE_MEMNUM; break;
case OP_KEEP:
break;
@@ -689,112 +587,79 @@ init_cache_opcodes_inner(
case OP_FAIL:
break;
case OP_JUMP:
- p += SIZE_RELADDR;
+ p += SIZE_RELADDR;
break;
case OP_PUSH:
- p += SIZE_RELADDR;
- INC_CACHE_OPCODES;
+ p += SIZE_RELADDR;
+ table->addr = pbegin;
+ table->num = num - current_mem_num;
+ table->outer_repeat = current_mem;
+ num++;
+ table++;
break;
case OP_POP:
break;
case OP_PUSH_OR_JUMP_EXACT1:
case OP_PUSH_IF_PEEK_NEXT:
p += SIZE_RELADDR + 1;
- INC_CACHE_OPCODES;
+ table->addr = pbegin;
+ table->num = num - current_mem_num;
+ table->outer_repeat = current_mem;
+ num++;
+ table++;
break;
case OP_REPEAT:
case OP_REPEAT_NG:
- GET_MEMNUM_INC(repeat_mem, p);
+ GET_MEMNUM_INC(mem, p);
p += SIZE_RELADDR;
- if (reg->repeat_range[repeat_mem].lower == 0) {
- INC_CACHE_OPCODES;
+ if (reg->repeat_range[mem].lower == 0) {
+ table->addr = pbegin;
+ table->num = num - current_mem_num;
+ table->outer_repeat = -1;
+ num++;
+ table++;
}
+ current_mem = mem;
+ current_mem_num = num;
+ break;
+ case OP_REPEAT_INC:
+ case OP_REPEAT_INC_NG:
+ GET_MEMNUM_INC(mem, p);
{
- long num_cache_points_in_repeat = 0;
- long num_cache_points_at_repeat = cache_point;
- OnigCacheOpcode* cache_opcodes_in_repeat = cache_opcodes;
- result = init_cache_opcodes_inner(reg, repeat_mem, lookaround_nesting, &cache_opcodes, &p, &num_cache_points_in_repeat);
- if (result != 0) {
- goto fail;
- }
- OnigRepeatRange *repeat_range = &reg->repeat_range[repeat_mem];
+ long inner_num = num - current_mem_num;
+ OnigRepeatRange *repeat_range = &reg->repeat_range[mem];
if (repeat_range->lower < repeat_range->upper) {
- INC_CACHE_OPCODES;
- cache_point -= lookaround_nesting != 0 ? 2 : 1;
- }
- int repeat_bounds = repeat_range->upper == 0x7fffffff ? 1 : repeat_range->upper - repeat_range->lower;
- cache_point += num_cache_points_in_repeat * repeat_range->lower + (num_cache_points_in_repeat + (lookaround_nesting != 0 ? 2 : 1)) * repeat_bounds;
- for (; cache_opcodes_in_repeat < cache_opcodes; cache_opcodes_in_repeat++) {
- cache_opcodes_in_repeat->num_cache_points_at_outer_repeat = num_cache_points_at_repeat;
- cache_opcodes_in_repeat->num_cache_points_in_outer_repeat = num_cache_points_in_repeat;
+ table->addr = pbegin;
+ table->num = num - current_mem_num;
+ table->outer_repeat = mem;
+ table++;
}
+ num -= inner_num;
+ num += inner_num * repeat_range->lower + (inner_num + 1) * (repeat_range->upper == 0x7fffffff ? 1 : repeat_range->upper - repeat_range->lower);
+ current_mem = -1;
+ current_mem_num = 0;
}
break;
- case OP_REPEAT_INC:
- case OP_REPEAT_INC_NG:
- p += SIZE_MEMNUM;
- goto exit;
case OP_REPEAT_INC_SG:
case OP_REPEAT_INC_NG_SG:
+ // TODO: support OP_REPEAT opcodes.
goto unexpected_bytecode_error;
case OP_NULL_CHECK_START:
- p += SIZE_MEMNUM;
- break;
case OP_NULL_CHECK_END:
- case OP_NULL_CHECK_END_MEMST_PUSH:
- p += SIZE_MEMNUM;
- break;
case OP_NULL_CHECK_END_MEMST:
- p += SIZE_MEMNUM;
- break;
+ case OP_NULL_CHECK_END_MEMST_PUSH:
+ p += SIZE_MEMNUM; break;
case OP_PUSH_POS:
- lookaround:
- {
- OnigCacheOpcode* cache_opcodes_in_lookaround = cache_opcodes;
- result = init_cache_opcodes_inner(reg, current_repeat_mem, lookaround_nesting + 1, &cache_opcodes, &p, &cache_point);
- if (result != 0) {
- goto fail;
- }
- UChar* match_addr = p - 1;
- for (; cache_opcodes_in_lookaround < cache_opcodes; cache_opcodes_in_lookaround++) {
- if (cache_opcodes_in_lookaround->match_addr == NULL) {
- cache_opcodes_in_lookaround->match_addr = match_addr;
- }
- }
- }
- break;
- case OP_PUSH_POS_NOT:
- p += SIZE_RELADDR;
- goto lookaround;
- case OP_PUSH_LOOK_BEHIND_NOT:
- p += SIZE_RELADDR;
- p += SIZE_LENGTH;
- goto lookaround;
- case OP_PUSH_STOP_BT:
- {
- OnigCacheOpcode* cache_opcodes_in_atomic = cache_opcodes;
- result = init_cache_opcodes_inner(reg, current_repeat_mem, -1, &cache_opcodes, &p, &cache_point);
- if (result != 0) {
- goto fail;
- }
- UChar* match_addr = p - 1;
- for (; cache_opcodes_in_atomic < cache_opcodes; cache_opcodes_in_atomic++) {
- if (cache_opcodes_in_atomic->match_addr == NULL) {
- cache_opcodes_in_atomic->match_addr = match_addr;
- }
- }
- }
- break;
case OP_POP_POS:
+ case OP_PUSH_POS_NOT:
case OP_FAIL_POS:
- case OP_FAIL_LOOK_BEHIND_NOT:
+ case OP_PUSH_STOP_BT:
case OP_POP_STOP_BT:
- goto exit;
case OP_LOOK_BEHIND:
- p += SIZE_LENGTH;
- break;
-
+ case OP_PUSH_LOOK_BEHIND_NOT:
+ case OP_FAIL_LOOK_BEHIND_NOT:
+ case OP_PUSH_ABSENT_POS:
case OP_ABSENT_END:
case OP_ABSENT:
goto unexpected_bytecode_error;
@@ -819,54 +684,33 @@ init_cache_opcodes_inner(
break;
default:
- goto bytecode_error;
+ goto bytecode_error;
}
}
-exit:
- *cache_opcodes_ptr = cache_opcodes;
- *pp = p;
- *num_cache_points_ptr = cache_point;
return 0;
-fail:
- return result;
-
unexpected_bytecode_error:
return ONIGERR_UNEXPECTED_BYTECODE;
bytecode_error:
return ONIGERR_UNDEFINED_BYTECODE;
}
-
-/* collect cache opcodes from the given regex program, and compute the total number of cache points. */
-static OnigPosition
-init_cache_opcodes(const regex_t* reg, OnigCacheOpcode* cache_opcodes_ptr, long* num_cache_points_ptr)
-{
- UChar* p = reg->p;
- *num_cache_points_ptr = 0;
- OnigPosition result = init_cache_opcodes_inner(reg, -1, 0, &cache_opcodes_ptr, &p, num_cache_points_ptr);
- if (result == 0 && p != reg->p + reg->used) {
- return ONIGERR_UNDEFINED_BYTECODE;
- }
-
- return result;
-}
-#else
+#else /* USE_MATCH_CACHE */
static OnigPosition
-count_num_cache_opcodes(regex_t* reg, long* num_cache_opcodes)
+count_num_cache_opcode(regex_t* reg, long* num, long* table_size)
{
- *num_cache_opcodes = NUM_CACHE_OPCODES_IMPOSSIBLE;
+ *num = NUM_CACHE_OPCODE_FAIL;
return 0;
}
-#endif /* USE_MATCH_CACHE */
+#endif
extern int
onig_check_linear_time(OnigRegexType* reg)
{
- long num_cache_opcodes = 0;
- count_num_cache_opcodes(reg, &num_cache_opcodes);
- return num_cache_opcodes != NUM_CACHE_OPCODES_IMPOSSIBLE;
+ long num = 0, table_size = 0;
+ count_num_cache_opcode(reg, &num, &table_size);
+ return num != NUM_CACHE_OPCODE_FAIL;
}
extern void
@@ -982,18 +826,14 @@ onig_region_free(OnigRegion* r, int free_self)
{
if (r) {
if (r->allocated > 0) {
- xfree(r->beg);
- xfree(r->end);
+ if (r->beg) xfree(r->beg);
+ if (r->end) xfree(r->end);
+ r->allocated = 0;
}
#ifdef USE_CAPTURE_HISTORY
history_root_free(r);
#endif
- if (free_self) {
- xfree(r);
- }
- else {
- memset(r, 0, sizeof(OnigRegion));
- }
+ if (free_self) xfree(r);
}
}
@@ -1029,52 +869,48 @@ onig_region_copy(OnigRegion* to, const OnigRegion* from)
/* stack type */
/* used by normal-POP */
-#define STK_ALT 0x0001
-#define STK_LOOK_BEHIND_NOT 0x0002
-#define STK_POS_NOT 0x0003
+#define STK_ALT 0x0001
+#define STK_LOOK_BEHIND_NOT 0x0002
+#define STK_POS_NOT 0x0003
/* handled by normal-POP */
-#define STK_MEM_START 0x0100
-#define STK_MEM_END 0x8200
-#define STK_REPEAT_INC 0x0300
-#define STK_STATE_CHECK_MARK 0x1000
+#define STK_MEM_START 0x0100
+#define STK_MEM_END 0x8200
+#define STK_REPEAT_INC 0x0300
+#define STK_STATE_CHECK_MARK 0x1000
/* avoided by normal-POP */
-#define STK_NULL_CHECK_START 0x3000
-#define STK_NULL_CHECK_END 0x5000 /* for recursive call */
-#define STK_MEM_END_MARK 0x8400
-#define STK_POS 0x0500 /* used when POP-POS */
-#define STK_STOP_BT 0x0600 /* mark for "(?>...)" */
-#define STK_REPEAT 0x0700
-#define STK_CALL_FRAME 0x0800
-#define STK_RETURN 0x0900
-#define STK_VOID 0x0a00 /* for fill a blank */
-#define STK_ABSENT_POS 0x0b00 /* for absent */
-#define STK_ABSENT 0x0c00 /* absent inner loop marker */
-#define STK_MATCH_CACHE_POINT 0x0d00 /* for the match cache optimization */
-#define STK_ATOMIC_MATCH_CACHE_POINT 0x0e00
+#define STK_NULL_CHECK_START 0x3000
+#define STK_NULL_CHECK_END 0x5000 /* for recursive call */
+#define STK_MEM_END_MARK 0x8400
+#define STK_POS 0x0500 /* used when POP-POS */
+#define STK_STOP_BT 0x0600 /* mark for "(?>...)" */
+#define STK_REPEAT 0x0700
+#define STK_CALL_FRAME 0x0800
+#define STK_RETURN 0x0900
+#define STK_VOID 0x0a00 /* for fill a blank */
+#define STK_ABSENT_POS 0x0b00 /* for absent */
+#define STK_ABSENT 0x0c00 /* absent inner loop marker */
/* stack type check mask */
-#define STK_MASK_POP_USED 0x00ff
-#define STK_MASK_TO_VOID_TARGET 0x10ff
-#define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */
-
-#ifdef USE_MATCH_CACHE
-#define MATCH_ARG_INIT_MATCH_CACHE(msa) do {\
- (msa).match_cache_status = MATCH_CACHE_STATUS_UNINIT;\
- (msa).num_fails = 0;\
- (msa).num_cache_opcodes = NUM_CACHE_OPCODES_UNINIT;\
- (msa).cache_opcodes = (OnigCacheOpcode*)NULL;\
- (msa).num_cache_points = 0;\
- (msa).match_cache_buf = (uint8_t*)NULL;\
+#define STK_MASK_POP_USED 0x00ff
+#define STK_MASK_TO_VOID_TARGET 0x10ff
+#define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */
+
+#ifdef USE_CACHE_MATCH_OPT
+#define MATCH_ARG_INIT_CACHE_MATCH_OPT(msa) do {\
+ (msa).enable_cache_match_opt = 0;\
+ (msa).num_fail = 0;\
+ (msa).num_cache_opcode = NUM_CACHE_OPCODE_UNINIT;\
+ (msa).num_cache_table = 0;\
+ (msa).cache_index_table = (OnigCacheIndex *)0;\
+ (msa).match_cache = (uint8_t *)0;\
} while(0)
-#define MATCH_ARG_FREE_MATCH_CACHE(msa) do {\
- xfree((msa).cache_opcodes);\
- xfree((msa).match_cache_buf);\
- (msa).cache_opcodes = (OnigCacheOpcode*)NULL;\
- (msa).match_cache_buf = (uint8_t*)NULL;\
+#define MATCH_ARG_FREE_CACHE_MATCH_OPT(msa) do {\
+ if ((msa).cache_index_table) xfree((msa).cache_index_table);\
+ if ((msa).match_cache) xfree((msa).match_cache);\
} while(0)
#else
-#define MATCH_ARG_INIT_MATCH_CACHE(msa)
-#define MATCH_ARG_FREE_MATCH_CACHE(msa)
+#define MATCH_ARG_INIT_CACHE_MATCH_OPT(msa)
+#define MATCH_ARG_FREE_CACHE_MATCH_OPT(msa)
#endif
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
@@ -1087,7 +923,7 @@ onig_region_copy(OnigRegion* to, const OnigRegion* from)
(msa).best_len = ONIG_MISMATCH;\
(msa).counter = 0;\
(msa).end_time = 0;\
- MATCH_ARG_INIT_MATCH_CACHE(msa);\
+ MATCH_ARG_INIT_CACHE_MATCH_OPT(msa);\
} while(0)
#else
# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
@@ -1098,7 +934,7 @@ onig_region_copy(OnigRegion* to, const OnigRegion* from)
(msa).gpos = (arg_gpos);\
(msa).counter = 0;\
(msa).end_time = 0;\
- MATCH_ARG_INIT_MATCH_CACHE(msa);\
+ MATCH_ARG_INIT_CACHE_MATCH_OPT(msa);\
} while(0)
#endif
@@ -1133,16 +969,16 @@ onig_region_copy(OnigRegion* to, const OnigRegion* from)
} while(0)
# define MATCH_ARG_FREE(msa) do {\
- xfree((msa).stack_p);\
+ if ((msa).stack_p) xfree((msa).stack_p);\
if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
- xfree((msa).state_check_buff);\
+ if ((msa).state_check_buff) xfree((msa).state_check_buff);\
}\
- MATCH_ARG_FREE_MATCH_CACHE(msa);\
+ MATCH_ARG_FREE_CACHE_MATCH_OPT(msa);\
} while(0)
#else /* USE_COMBINATION_EXPLOSION_CHECK */
# define MATCH_ARG_FREE(msa) do {\
- xfree((msa).stack_p);\
- MATCH_ARG_FREE_MATCH_CACHE(msa);\
+ if ((msa).stack_p) xfree((msa).stack_p);\
+ MATCH_ARG_FREE_CACHE_MATCH_OPT(msa);\
} while (0)
#endif /* USE_COMBINATION_EXPLOSION_CHECK */
@@ -1253,7 +1089,7 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
if (r != 0) {\
STACK_SAVE;\
- xfree(xmalloc_base);\
+ if (xmalloc_base) xfree(xmalloc_base);\
return r;\
}\
}\
@@ -1359,6 +1195,129 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
#define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev,keep) \
STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev,keep)
+#ifdef USE_CACHE_MATCH_OPT
+
+#define DO_CACHE_MATCH_OPT(reg,stk,repeat_stk,enable,p,num_cache_table,num_cache_size,table,pos,match_cache) do {\
+ if (enable) {\
+ long cache_index = find_cache_index_table((reg), (stk), (repeat_stk), (table), (num_cache_table), (p));\
+ if (cache_index >= 0) {\
+ long key = (num_cache_size) * (long)(pos) + cache_index;\
+ long index = key >> 3;\
+ long mask = 1 << (key & 7);\
+ if ((match_cache)[index] & mask) {\
+ goto fail;\
+ }\
+ (match_cache)[index] |= mask;\
+ }\
+ }\
+} while (0)
+
+static long
+find_cache_index_table(regex_t* reg, OnigStackType *stk, OnigStackIndex *repeat_stk, OnigCacheIndex* table, long num_cache_table, UChar* p)
+{
+ long l = 0, r = num_cache_table - 1, m = 0;
+ OnigCacheIndex* item;
+ OnigRepeatRange* range;
+ OnigStackType *stkp;
+ int count = 0;
+ int is_inc = *p == OP_REPEAT_INC || *p == OP_REPEAT_INC_NG;
+
+ while (l <= r) {
+ m = (l + r) / 2;
+ if (table[m].addr == p) break;
+ if (table[m].addr < p) l = m + 1;
+ else r = m - 1;
+ }
+
+ if (!(0 <= m && m < num_cache_table && table[m].addr == p)) {
+ return -1;
+ }
+
+ item = &table[m];
+ if (item->outer_repeat == -1) {
+ return item->num;
+ }
+
+ range = &reg->repeat_range[item->outer_repeat];
+
+ stkp = &stk[repeat_stk[item->outer_repeat]];
+ count = is_inc ? stkp->u.repeat.count - 1 : stkp->u.repeat.count;
+
+ if (count < range->lower) {
+ return range->base_num + range->inner_num * count + item->num;
+ }
+
+ if (range->upper == 0x7fffffff) {
+ return range->base_num + range->inner_num * (range->lower - (is_inc ? 1 : 0)) + (is_inc ? 0 : 1) + item->num;
+ }
+
+ return range->base_num + range->inner_num * (range->lower - 1) + (range->inner_num + 1) * (count - range->lower + 1) + item->num;
+}
+
+static void
+reset_match_cache(regex_t* reg, UChar* pbegin, UChar* pend, long pos, uint8_t* match_cache, OnigCacheIndex *table, long num_cache_size, long num_cache_table)
+{
+ long l = 0, r = num_cache_table - 1, m1 = 0, m2 = 0;
+ int is_inc = *pend == OP_REPEAT_INC || *pend == OP_REPEAT_INC_NG;
+ OnigCacheIndex *item1, *item2;
+ long k1, k2, base;
+
+ while (l <= r) {
+ m1 = (l + r) / 2;
+ if (table[m1].addr == pbegin) break;
+ if (table[m1].addr < pbegin) l = m1 + 1;
+ else r = m1 - 1;
+ }
+
+ l = 0, r = num_cache_table - 1;
+ while (l <= r) {
+ m2 = (l + r) / 2;
+ if (table[m2].addr == pend) break;
+ if (table[m2].addr < pend) l = m2 + 1;
+ else r = m2 - 1;
+ }
+
+ if (table[m1].addr < pbegin && m1 + 1 < num_cache_table) m1++;
+ if (table[m2].addr > pend && m2 - 1 > 0) m2--;
+
+ item1 = &table[m1];
+ item2 = &table[m2];
+
+ if (item1->outer_repeat < 0) k1 = item1->num;
+ else k1 = reg->repeat_range[item1->outer_repeat].base_num + item1->num;
+
+ if (item2->outer_repeat < 0) k2 = item2->num;
+ else {
+ OnigRepeatRange *range = &reg->repeat_range[item2->outer_repeat];
+ if (range->upper == 0x7fffffff) k2 = range->base_num + range->inner_num * range->lower + (is_inc ? 0 : 1) + item2->num;
+ else k2 = range->base_num + range->inner_num * range->lower + (range->inner_num + 1) * (range->upper - range->lower - (is_inc ? 1 : 0)) + item2->num;
+ }
+
+ base = pos * num_cache_size;
+ k1 += base;
+ k2 += base;
+
+ if ((k1 >> 3) == (k2 >> 3)) {
+ match_cache[k1 >> 3] &= (((1 << (8 - (k2 & 7) - 1)) - 1) << ((k2 & 7) + 1)) | ((1 << (k1 & 7)) - 1);
+ } else {
+ long i = k1 >> 3;
+ if (k1 & 7) {
+ match_cache[k1 >> 3] &= (1 << ((k1 & 7) - 1)) - 1;
+ i++;
+ }
+ if (i < (k2 >> 3)) {
+ xmemset(&match_cache[i], 0, (k2 >> 3) - i);
+ if (k2 & 7) {
+ match_cache[k2 >> 3] &= (((1 << (8 - (k2 & 7) - 1)) - 1) << ((k2 & 7) + 1));
+ }
+ }
+ }
+}
+
+#else
+#define DO_CACHE_MATCH_OPT(reg,stk,repeat_stk,enable,p,num_cache_table,num_cache_size,table,pos,match_cache)
+#endif /* USE_CACHE_MATCH_OPT */
+
#define STACK_PUSH_REPEAT(id, pat) do {\
STACK_ENSURE(1);\
stk->type = STK_REPEAT;\
@@ -1485,15 +1444,6 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
STACK_INC;\
} while(0)
-#define STACK_PUSH_MATCH_CACHE_POINT(match_cache_point_index, match_cache_point_mask) do {\
- STACK_ENSURE(1);\
- stk->type = STK_MATCH_CACHE_POINT;\
- stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
- stk->u.match_cache_point.index = (match_cache_point_index);\
- stk->u.match_cache_point.mask = (match_cache_point_mask);\
- STACK_INC;\
-} while(0)
-
#ifdef ONIG_DEBUG
# define STACK_BASE_CHECK(p, at) \
@@ -1505,42 +1455,6 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
# define STACK_BASE_CHECK(p, at)
#endif
-#ifdef ONIG_DEBUG_MATCH_CACHE
-# define MATCH_CACHE_DEBUG_MEMOIZE(stkp) fprintf(stderr, "MATCH CACHE: memoize (index=%ld mask=%d)\n", stkp->u.match_cache_point.index, stkp->u.match_cache_point.mask);
-#else
-# define MATCH_CACHE_DEBUG_MEMOIZE(stkp) ((void) 0)
-#endif
-
-#ifdef USE_MATCH_CACHE
-# define INC_NUM_FAILS msa->num_fails++
-# define MEMOIZE_MATCH_CACHE_POINT do {\
- if (stk->type == STK_MATCH_CACHE_POINT) {\
- msa->match_cache_buf[stk->u.match_cache_point.index] |= stk->u.match_cache_point.mask;\
- MATCH_CACHE_DEBUG_MEMOIZE(stk);\
- } else if (stk->type == STK_ATOMIC_MATCH_CACHE_POINT) {\
- memoize_extended_match_cache_point(msa->match_cache_buf, stk->u.match_cache_point.index, stk->u.match_cache_point.mask);\
- MATCH_CACHE_DEBUG_MEMOIZE(stkp);\
- }\
- } while(0)
-# define MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT(stkp) do {\
- if (stkp->type == STK_MATCH_CACHE_POINT) {\
- stkp->type = STK_VOID;\
- memoize_extended_match_cache_point(msa->match_cache_buf, stkp->u.match_cache_point.index, stkp->u.match_cache_point.mask);\
- MATCH_CACHE_DEBUG_MEMOIZE(stkp);\
- }\
- } while(0)
-# define MEMOIZE_ATOMIC_MATCH_CACHE_POINT do {\
- if (stk->type == STK_MATCH_CACHE_POINT) {\
- memoize_extended_match_cache_point(msa->match_cache_buf, stk->u.match_cache_point.index, stk->u.match_cache_point.mask);\
- MATCH_CACHE_DEBUG_MEMOIZE(stkp);\
- }\
- } while(0)
-#else
-# define INC_NUM_FAILS ((void) 0)
-# define MEMOIZE_MATCH_CACHE_POINT ((void) 0)
-# define MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT ((void) 0)
-#endif
-
#define STACK_POP_ONE do {\
stk--;\
STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
@@ -1554,7 +1468,6 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
STACK_BASE_CHECK(stk, "STACK_POP"); \
if ((stk->type & STK_MASK_POP_USED) != 0) break;\
ELSE_IF_STATE_CHECK_MARK(stk);\
- MEMOIZE_MATCH_CACHE_POINT;\
}\
break;\
case STACK_POP_LEVEL_MEM_START:\
@@ -1567,7 +1480,6 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
}\
ELSE_IF_STATE_CHECK_MARK(stk);\
- MEMOIZE_MATCH_CACHE_POINT;\
}\
break;\
default:\
@@ -1587,7 +1499,6 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
}\
ELSE_IF_STATE_CHECK_MARK(stk);\
- MEMOIZE_MATCH_CACHE_POINT;\
}\
break;\
}\
@@ -1609,11 +1520,7 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
}\
- else if (IS_TO_VOID_TARGET(stk)) {\
- INC_NUM_FAILS;\
- }\
ELSE_IF_STATE_CHECK_MARK(stk);\
- MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT(stk);\
}\
} while(0)
@@ -1670,14 +1577,12 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
k--;\
STACK_BASE_CHECK(k, "STACK_POS_END"); \
if (IS_TO_VOID_TARGET(k)) {\
- INC_NUM_FAILS;\
k->type = STK_VOID;\
}\
else if (k->type == STK_POS) {\
k->type = STK_VOID;\
break;\
}\
- MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT(k);\
}\
} while(0)
@@ -1687,28 +1592,12 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
k--;\
STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
if (IS_TO_VOID_TARGET(k)) {\
- INC_NUM_FAILS;\
k->type = STK_VOID;\
}\
else if (k->type == STK_STOP_BT) {\
k->type = STK_VOID;\
break;\
}\
- else if (k->type == STK_MATCH_CACHE_POINT) {\
- k->type = STK_ATOMIC_MATCH_CACHE_POINT;\
- }\
- }\
-} while(0)
-
-#define STACK_STOP_BT_FAIL do {\
- while (1) {\
- stk--;\
- STACK_BASE_CHECK(stk, "STACK_STOP_BT_END"); \
- if (stk->type == STK_STOP_BT) {\
- stk->type = STK_VOID;\
- break;\
- }\
- MEMOIZE_ATOMIC_MATCH_CACHE_POINT;\
}\
} while(0)
@@ -1747,7 +1636,7 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
}\
} while(0)
-#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
+#define STACK_NULL_CHECK_MEMST(isnull,ischange,id,s,reg) do {\
OnigStackType* k = STACK_AT((stk-1)->null_check)+1;\
while (1) {\
k--;\
@@ -1764,14 +1653,14 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
while (k < stk) {\
if (k->type == STK_MEM_START) {\
if (k->u.mem.end == INVALID_STACK_INDEX) {\
- (isnull) = 0; break;\
+ (isnull) = 0; (ischange) = 1; break;\
}\
if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
else\
endp = (UChar* )k->u.mem.end;\
if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
- (isnull) = 0; break;\
+ (isnull) = 0; (ischange) = 1; break;\
}\
else if (endp != s) {\
(isnull) = -1; /* empty, but position changed */ \
@@ -2167,7 +2056,7 @@ onig_print_statistics(FILE* f)
#ifdef ONIG_DEBUG_MATCH
-static const char *
+static char *
stack_type_str(int stack_type)
{
switch (stack_type) {
@@ -2189,97 +2078,10 @@ stack_type_str(int stack_type)
case STK_VOID: return "Void ";
case STK_ABSENT_POS: return "AbsPos";
case STK_ABSENT: return "Absent";
- case STK_MATCH_CACHE_POINT: return "MCache";
default: return " ";
}
}
#endif
-#ifdef USE_MATCH_CACHE
-
-static long
-bsearch_cache_opcodes(const OnigCacheOpcode *cache_opcodes, long num_cache_opcodes, const UChar* p)
-{
- long l = 0, r = num_cache_opcodes - 1, m = 0;
-
- while (l <= r) {
- m = (l + r) / 2;
- if (cache_opcodes[m].addr == p) break;
- if (cache_opcodes[m].addr < p) l = m + 1;
- else r = m - 1;
- }
- return m;
-}
-
-static long
-find_cache_point(regex_t* reg, const OnigCacheOpcode* cache_opcodes, long num_cache_opcodes, const UChar* p, const OnigStackType *stk, const OnigStackIndex *repeat_stk, const OnigCacheOpcode **cache_opcode_ptr)
-{
- long m;
- const OnigCacheOpcode* cache_opcode;
- const OnigRepeatRange* range;
- const OnigStackType *stkp;
- int count = 0;
- int is_inc = *p == OP_REPEAT_INC || *p == OP_REPEAT_INC_NG;
- long cache_point;
- long num_cache_points_at_outer_repeat;
- long num_cache_points_in_outer_repeat;
-
- m = bsearch_cache_opcodes(cache_opcodes, num_cache_opcodes, p);
-
- if (!(0 <= m && m < num_cache_opcodes && cache_opcodes[m].addr == p)) {
- return -1;
- }
-
- cache_opcode = &cache_opcodes[m];
- *cache_opcode_ptr = &cache_opcodes[m];
- cache_point = cache_opcode->cache_point;
- if (cache_opcode->outer_repeat_mem == -1) {
- return cache_point;
- }
-
- num_cache_points_at_outer_repeat = cache_opcode->num_cache_points_at_outer_repeat;
- num_cache_points_in_outer_repeat = cache_opcode->num_cache_points_in_outer_repeat;
-
- range = &reg->repeat_range[cache_opcode->outer_repeat_mem];
-
- stkp = &stk[repeat_stk[cache_opcode->outer_repeat_mem]];
- count = is_inc ? stkp->u.repeat.count - 1 : stkp->u.repeat.count;
-
- if (count < range->lower) {
- return num_cache_points_at_outer_repeat +
- num_cache_points_in_outer_repeat * count +
- cache_point;
- }
-
- if (range->upper == 0x7fffffff) {
- return num_cache_points_at_outer_repeat +
- num_cache_points_in_outer_repeat * (range->lower - (is_inc ? 1 : 0)) + (is_inc ? 0 : 1) +
- cache_point;
- }
-
- return num_cache_points_at_outer_repeat +
- num_cache_points_in_outer_repeat * (range->lower - 1) +
- (num_cache_points_in_outer_repeat + 1) * (count - range->lower + 1) +
- cache_point;
-}
-
-static int check_extended_match_cache_point(uint8_t *match_cache_buf, long match_cache_point_index, uint8_t match_cache_point_mask) {
- if (match_cache_point_mask & 0x80) {
- return (match_cache_buf[match_cache_point_index + 1] & 0x01) > 0;
- } else {
- return (match_cache_buf[match_cache_point_index] & (match_cache_point_mask << 1)) > 0;
- }
-}
-
-static void memoize_extended_match_cache_point(uint8_t *match_cache_buf, long match_cache_point_index, uint8_t match_cache_point_mask) {
- match_cache_buf[match_cache_point_index] |= match_cache_point_mask;
- if (match_cache_point_mask & 0x80) {
- match_cache_buf[match_cache_point_index + 1] |= 0x01;
- } else {
- match_cache_buf[match_cache_point_index] |= match_cache_point_mask << 1;
- }
-}
-
-#endif /* USE_MATCH_CACHE */
/* match data(str - end) from position (sstart). */
/* if sstart == str then set sprev to NULL. */
@@ -2306,7 +2108,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
UChar *pkeep;
char *alloca_base;
char *xmalloc_base = NULL;
- OnigStackType *stk_alloc, *stk_base = NULL, *stk, *stk_end;
+ OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
OnigStackType *stkp; /* used as any purpose. */
OnigStackIndex si;
OnigStackIndex *repeat_stk;
@@ -2588,49 +2390,6 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
# define OPCODE_EXEC_HOOK ((void) 0)
#endif
-#ifdef USE_MATCH_CACHE
-#ifdef ONIG_DEBUG_MATCH_CACHE
-#define MATCH_CACHE_DEBUG fprintf(stderr, "MATCH CACHE: cache %ld (p=%p index=%ld mask=%d)\n", match_cache_point, pbegin, match_cache_point_index, match_cache_point_mask)
-#define MATCH_CACHE_DEBUG_HIT fprintf(stderr, "MATCH CACHE: cache hit\n")
-#else
-#define MATCH_CACHE_DEBUG ((void) 0)
-#define MATCH_CACHE_DEBUG_HIT ((void) 0)
-#endif
-
-#define MATCH_CACHE_HIT ((void) 0)
-
-# define CHECK_MATCH_CACHE do {\
- if (msa->match_cache_status == MATCH_CACHE_STATUS_ENABLED) {\
- const OnigCacheOpcode *cache_opcode;\
- long cache_point = find_cache_point(reg, msa->cache_opcodes, msa->num_cache_opcodes, pbegin, stk_base, repeat_stk, &cache_opcode);\
- if (cache_point >= 0) {\
- long match_cache_point = msa->num_cache_points * (long)(s - str) + cache_point;\
- long match_cache_point_index = match_cache_point >> 3;\
- uint8_t match_cache_point_mask = 1 << (match_cache_point & 7);\
- MATCH_CACHE_DEBUG;\
- if (msa->match_cache_buf[match_cache_point_index] & match_cache_point_mask) {\
- MATCH_CACHE_DEBUG_HIT; MATCH_CACHE_HIT;\
- if (cache_opcode->lookaround_nesting == 0) goto fail;\
- else if (cache_opcode->lookaround_nesting < 0) {\
- if (check_extended_match_cache_point(msa->match_cache_buf, match_cache_point_index, match_cache_point_mask)) {\
- STACK_STOP_BT_FAIL;\
- goto fail;\
- } else goto fail;\
- } else {\
- if (check_extended_match_cache_point(msa->match_cache_buf, match_cache_point_index, match_cache_point_mask)) {\
- p = cache_opcode->match_addr;\
- MOP_OUT;\
- JUMP;\
- } else goto fail;\
- }\
- }\
- STACK_PUSH_MATCH_CACHE_POINT(match_cache_point_index, match_cache_point_mask);\
- }\
- }\
-} while (0)
-#else
-# define CHECK_MATCH_CACHE ((void) 0)
-#endif
VM_LOOP {
CASE(OP_END) MOP_IN(OP_END);
@@ -3058,7 +2817,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_ANYCHAR_STAR) MOP_IN(OP_ANYCHAR_STAR);
while (DATA_ENSURE_CHECK1) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
STACK_PUSH_ALT(p, s, sprev, pkeep);
n = enclen_approx(encode, s, end);
DATA_ENSURE(n);
@@ -3071,7 +2830,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_ANYCHAR_ML_STAR) MOP_IN(OP_ANYCHAR_ML_STAR);
while (DATA_ENSURE_CHECK1) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
STACK_PUSH_ALT(p, s, sprev, pkeep);
n = enclen_approx(encode, s, end);
if (n > 1) {
@@ -3089,14 +2848,14 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_ANYCHAR_STAR_PEEK_NEXT) MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
while (DATA_ENSURE_CHECK1) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, end - s, msa->match_cache);
if (*p == *s) {
STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
} else {
-#ifdef USE_MATCH_CACHE
- /* We need to increment num_fails here, for invoking a cache optimization correctly. */
- /* Actually, the matching will be failed if we use `OP_ANYCHAR_STAR` simply in this case.*/
- msa->num_fails++;
+ /* We need to increment num_fail here, for invoking a cache optimization correctly. */
+ /* Actually, the matching will be failed if we use `OP_ANYCHAR_STAR` simply in this case.*/
+#ifdef USE_CACHE_MATCH_OPT
+ msa->num_fail++;
#endif
}
n = enclen_approx(encode, s, end);
@@ -3111,14 +2870,14 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_ANYCHAR_ML_STAR_PEEK_NEXT)MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
while (DATA_ENSURE_CHECK1) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
if (*p == *s) {
STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
} else {
-#ifdef USE_MATCH_CACHE
- /* We need to increment num_fails here, for invoking a cache optimization correctly. */
- /* Actually, the matching will be failed if we use `OP_ANYCHAR_STAR_ML` simply in this case.*/
- msa->num_fails++;
+ /* We need to increment num_fail here, for invoking a cache optimization correctly. */
+ /* Actually, the matching will be failed if we use `OP_ANYCHAR_STAR_ML` simply in this case.*/
+#ifdef USE_CACHE_MATCH_OPT
+ msa->num_fail++;
#endif
}
n = enclen_approx(encode, s, end);
@@ -3534,7 +3293,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
n = pend - pstart;
DATA_ENSURE(n);
sprev = s;
- STRING_CMP_IC(case_fold_flag, pstart, &s, (int)n, end);
+ STRING_CMP_IC(case_fold_flag, pstart, &s, n, end);
while (sprev + (len = enclen_approx(encode, sprev, end)) < s)
sprev += len;
@@ -3705,9 +3464,10 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_NULL_CHECK_END_MEMST) MOP_IN(OP_NULL_CHECK_END_MEMST);
{
int isnull;
+ int ischanged = 0; // set 1 when a loop is empty but memory status is changed.
GET_MEMNUM_INC(mem, p); /* mem: null check id */
- STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);
+ STACK_NULL_CHECK_MEMST(isnull, ischanged, mem, s, reg);
if (isnull) {
# ifdef ONIG_DEBUG_MATCH
fprintf(stderr, "NULL_CHECK_END_MEMST: skip id:%d, s:%"PRIuPTR" (%p)\n",
@@ -3716,6 +3476,29 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
if (isnull == -1) goto fail;
goto null_check_found;
}
+# ifdef USE_CACHE_MATCH_OPT
+ if (ischanged && msa->enable_cache_match_opt) {
+ RelAddrType rel;
+ OnigUChar *addr;
+ MemNumType mem;
+ UChar* tmp = p;
+ switch (*tmp++) {
+ case OP_JUMP:
+ case OP_PUSH:
+ GET_RELADDR_INC(rel, tmp);
+ addr = tmp + rel;
+ break;
+ case OP_REPEAT_INC:
+ case OP_REPEAT_INC_NG:
+ GET_MEMNUM_INC(mem, tmp);
+ addr = STACK_AT(repeat_stk[mem])->u.repeat.pcode;
+ break;
+ default:
+ goto unexpected_bytecode_error;
+ }
+ reset_match_cache(reg, addr, pbegin, (long)(s - str), msa->match_cache, msa->cache_index_table, msa->num_cache_opcode, msa->num_cache_table);
+ }
+# endif
}
MOP_OUT;
JUMP;
@@ -3758,7 +3541,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_PUSH) MOP_IN(OP_PUSH);
GET_RELADDR_INC(addr, p);
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
MOP_OUT;
JUMP;
@@ -3799,10 +3582,10 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_POP) MOP_IN(OP_POP);
STACK_POP_ONE;
-#ifdef USE_MATCH_CACHE
- /* We need to increment num_fails here, for invoking a cache optimization correctly, */
+ /* We need to increment num_fail here, for invoking a cache optimization correctly, */
/* because Onigmo makes a loop, which is pairwise disjoint to the following set, as atomic. */
- msa->num_fails++;
+#ifdef USE_CACHE_MATCH_OPT
+ msa->num_fail++;
#endif
MOP_OUT;
JUMP;
@@ -3812,7 +3595,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
GET_RELADDR_INC(addr, p);
if (*p == *s && DATA_ENSURE_CHECK1) {
p++;
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
MOP_OUT;
JUMP;
@@ -3824,15 +3607,14 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
CASE(OP_PUSH_IF_PEEK_NEXT) MOP_IN(OP_PUSH_IF_PEEK_NEXT);
GET_RELADDR_INC(addr, p);
- CHECK_MATCH_CACHE;
if (*p == *s) {
p++;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
MOP_OUT;
JUMP;
}
p++;
- INC_NUM_FAILS;
MOP_OUT;
JUMP;
@@ -3846,7 +3628,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
STACK_PUSH_REPEAT(mem, p);
if (reg->repeat_range[mem].lower == 0) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, end - s, msa->match_cache);
STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
}
}
@@ -3863,7 +3645,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
STACK_PUSH_REPEAT(mem, p);
if (reg->repeat_range[mem].lower == 0) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
STACK_PUSH_ALT(p, s, sprev, pkeep);
p += addr;
}
@@ -3882,15 +3664,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
/* end of repeat. Nothing to do. */
}
else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
-#ifdef USE_MATCH_CACHE
if (*pbegin == OP_REPEAT_INC) {
-#undef MATCH_CACHE_HIT
-#define MATCH_CACHE_HIT stkp->u.repeat.count--;
- CHECK_MATCH_CACHE;
-#undef MATCH_CACHE_HIT
-#define MATCH_CACHE_HIT ((void) 0)
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
}
-#endif
STACK_PUSH_ALT(p, s, sprev, pkeep);
p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */
}
@@ -3922,7 +3698,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
STACK_PUSH_REPEAT_INC(si);
if (*pbegin == OP_REPEAT_INC_NG) {
- CHECK_MATCH_CACHE;
+ DO_CACHE_MATCH_OPT(reg, stk_base, repeat_stk, msa->enable_cache_match_opt, pbegin, msa->num_cache_table, msa->num_cache_opcode, msa->cache_index_table, s - str, msa->match_cache);
}
STACK_PUSH_ALT(pcode, s, sprev, pkeep);
}
@@ -4116,67 +3892,47 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
sprev = stk->u.state.pstr_prev;
pkeep = stk->u.state.pkeep;
-#ifdef USE_MATCH_CACHE
- if (
- msa->match_cache_status != MATCH_CACHE_STATUS_DISABLED &&
- ++msa->num_fails >= (long)(end - str) * msa->num_cache_opcodes
- ) {
- if (msa->match_cache_status == MATCH_CACHE_STATUS_UNINIT) {
- msa->match_cache_status = MATCH_CACHE_STATUS_INIT;
- OnigPosition r = count_num_cache_opcodes(reg, &msa->num_cache_opcodes);
- if (r < 0) goto bytecode_error;
- }
- if (msa->num_cache_opcodes == NUM_CACHE_OPCODES_IMPOSSIBLE || msa->num_cache_opcodes == 0) {
- msa->match_cache_status = MATCH_CACHE_STATUS_DISABLED;
- goto fail_match_cache;
+#ifdef USE_CACHE_MATCH_OPT
+ if (++msa->num_fail >= (long)(end - str) + 1 && msa->num_cache_opcode == NUM_CACHE_OPCODE_UNINIT) {
+ msa->enable_cache_match_opt = 1;
+ if (msa->num_cache_opcode == NUM_CACHE_OPCODE_UNINIT) {
+ OnigPosition r = count_num_cache_opcode(reg, &msa->num_cache_opcode, &msa->num_cache_table);
+ if (r < 0) goto bytecode_error;
}
- if (msa->num_fails < (long)(end - str) * msa->num_cache_opcodes) {
- goto fail_match_cache;
+ if (msa->num_cache_opcode == NUM_CACHE_OPCODE_FAIL || msa->num_cache_opcode == 0) {
+ msa->enable_cache_match_opt = 0;
+ goto fail_match_cache_opt;
}
- if (msa->cache_opcodes == NULL) {
- msa->match_cache_status = MATCH_CACHE_STATUS_ENABLED;
- OnigCacheOpcode* cache_opcodes = (OnigCacheOpcode*)xmalloc(msa->num_cache_opcodes * sizeof(OnigCacheOpcode));
- if (cache_opcodes == NULL) {
+ if (msa->cache_index_table == NULL) {
+ OnigCacheIndex *table = (OnigCacheIndex *)xmalloc(msa->num_cache_table * sizeof(OnigCacheIndex));
+ if (table == NULL) {
return ONIGERR_MEMORY;
}
- OnigPosition r = init_cache_opcodes(reg, cache_opcodes, &msa->num_cache_points);
- if (r < 0) {
- if (r == ONIGERR_UNEXPECTED_BYTECODE) goto unexpected_bytecode_error;
- else goto bytecode_error;
- }
- msa->cache_opcodes = cache_opcodes;
-#ifdef ONIG_DEBUG_MATCH_CACHE
- fprintf(stderr, "MATCH CACHE: #cache opcodes = %ld\n", msa->num_cache_opcodes);
- fprintf(stderr, "MATCH CACHE: #cache points = %ld\n", msa->num_cache_points);
- fprintf(stderr, "MATCH CACHE: cache opcodes (%p):\n", msa->cache_opcodes);
- for (int i = 0; i < msa->num_cache_opcodes; i++) {
- fprintf(stderr, "MATCH CACHE: [%p] cache_point=%ld outer_repeat_mem=%d num_cache_opcodes_at_outer_repeat=%ld num_cache_opcodes_in_outer_repeat=%ld lookaround_nesting=%d match_addr=%p\n", msa->cache_opcodes[i].addr, msa->cache_opcodes[i].cache_point, msa->cache_opcodes[i].outer_repeat_mem, msa->cache_opcodes[i].num_cache_points_at_outer_repeat, msa->cache_opcodes[i].num_cache_points_in_outer_repeat, msa->cache_opcodes[i].lookaround_nesting, msa->cache_opcodes[i].match_addr);
- }
-#endif
+ OnigPosition r = init_cache_index_table(reg, table);
+ if (r < 0) {
+ if (r == ONIGERR_UNEXPECTED_BYTECODE) goto unexpected_bytecode_error;
+ else goto bytecode_error;
+ }
+ msa->cache_index_table = table;
}
- if (msa->match_cache_buf == NULL) {
- size_t length = (end - str) + 1;
- size_t num_match_cache_points = (size_t)msa->num_cache_points * length;
-#ifdef ONIG_DEBUG_MATCH_CACHE
- fprintf(stderr, "MATCH CACHE: #match cache points = %ld (length = %zu)\n", num_match_cache_points, length);
-#endif
- /* Overflow check */
- if (num_match_cache_points / length != (size_t)msa->num_cache_points) {
- return ONIGERR_MEMORY;
- }
- if (num_match_cache_points >= LONG_MAX_LIMIT) {
- return ONIGERR_MEMORY;
- }
- size_t match_cache_buf_length = (num_match_cache_points >> 3) + (num_match_cache_points & 7 ? 1 : 0) + 1;
- uint8_t* match_cache_buf = (uint8_t*)xmalloc(match_cache_buf_length * sizeof(uint8_t));
- if (match_cache_buf == NULL) {
- return ONIGERR_MEMORY;
- }
- xmemset(match_cache_buf, 0, match_cache_buf_length * sizeof(uint8_t));
- msa->match_cache_buf = match_cache_buf;
+ size_t len = (end - str) + 1;
+ size_t match_cache_size8 = (size_t)msa->num_cache_opcode * len;
+ /* overflow check */
+ if (match_cache_size8 / len != (size_t)msa->num_cache_opcode) {
+ return ONIGERR_MEMORY;
+ }
+ /* Currently, int is used for the key of match_cache */
+ if (match_cache_size8 >= LONG_MAX_LIMIT) {
+ return ONIGERR_MEMORY;
}
+ size_t match_cache_size = (match_cache_size8 >> 3) + (match_cache_size8 & 7 ? 1 : 0);
+ msa->match_cache = (uint8_t*)xmalloc(match_cache_size * sizeof(uint8_t));
+ if (msa->match_cache == NULL) {
+ return ONIGERR_MEMORY;
+ }
+ xmemset(msa->match_cache, 0, match_cache_size * sizeof(uint8_t));
}
- fail_match_cache:
+ fail_match_cache_opt:
#endif
#ifdef USE_COMBINATION_EXPLOSION_CHECK
@@ -4196,31 +3952,25 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
finish:
STACK_SAVE;
- xfree(xmalloc_base);
+ if (xmalloc_base) xfree(xmalloc_base);
return best_len;
#ifdef ONIG_DEBUG
stack_error:
STACK_SAVE;
- xfree(xmalloc_base);
+ if (xmalloc_base) xfree(xmalloc_base);
return ONIGERR_STACK_BUG;
#endif
bytecode_error:
STACK_SAVE;
- xfree(xmalloc_base);
+ if (xmalloc_base) xfree(xmalloc_base);
return ONIGERR_UNDEFINED_BYTECODE;
unexpected_bytecode_error:
STACK_SAVE;
- xfree(xmalloc_base);
+ if (xmalloc_base) xfree(xmalloc_base);
return ONIGERR_UNEXPECTED_BYTECODE;
-
- timeout:
- xfree(xmalloc_base);
- if (stk_base != stk_alloc || IS_NOT_NULL(msa->stack_p))
- xfree(stk_base);
- HANDLE_REG_TIMEOUT_IN_MATCH_AT;
}
diff --git a/regint.h b/regint.h
index 57cbb81654..cee766ad6e 100644
--- a/regint.h
+++ b/regint.h
@@ -35,15 +35,19 @@
/* #define ONIG_DEBUG_COMPILE */
/* #define ONIG_DEBUG_SEARCH */
/* #define ONIG_DEBUG_MATCH */
-/* #define ONIG_DEBUG_MATCH_CACHE */
/* #define ONIG_DEBUG_MEMLEAK */
/* #define ONIG_DONT_OPTIMIZE */
/* for byte-code statistical data. */
/* #define ONIG_DEBUG_STATISTICS */
-/* enable the match optimization by using a cache. */
-#define USE_MATCH_CACHE
+/* enable matching optimization by using cache. */
+#define USE_CACHE_MATCH_OPT
+
+#ifdef USE_CACHE_MATCH_OPT
+# define NUM_CACHE_OPCODE_FAIL -1
+# define NUM_CACHE_OPCODE_UNINIT -2
+#endif
#if defined(ONIG_DEBUG_PARSE_TREE) || defined(ONIG_DEBUG_MATCH) || \
defined(ONIG_DEBUG_SEARCH) || defined(ONIG_DEBUG_COMPILE) || \
@@ -154,18 +158,13 @@
#ifdef RUBY
# define CHECK_INTERRUPT_IN_MATCH_AT do { \
- msa->counter++; \
- if (msa->counter >= 128) { \
- msa->counter = 0; \
- if (rb_reg_timeout_p(reg, &msa->end_time)) { \
- goto timeout; \
- } \
- rb_thread_check_ints(); \
- } \
+ msa->counter++; \
+ if (msa->counter >= 128) { \
+ msa->counter = 0; \
+ rb_reg_check_timeout(reg, &msa->end_time); \
+ rb_thread_check_ints(); \
+ } \
} while(0)
-# define HANDLE_REG_TIMEOUT_IN_MATCH_AT do { \
- rb_reg_raise_timeout(); \
-} while (0)
# define onig_st_init_table st_init_table
# define onig_st_init_table_with_size st_init_table_with_size
# define onig_st_init_numtable st_init_numtable
@@ -878,25 +877,15 @@ typedef struct _OnigStackType {
UChar *abs_pstr; /* absent start position */
const UChar *end_pstr; /* end position */
} absent_pos;
-#ifdef USE_MATCH_CACHE
- struct {
- long index; /* index of the match cache buffer */
- uint8_t mask; /* bit-mask for the match cache buffer */
- } match_cache_point;
-#endif
} u;
} OnigStackType;
-#ifdef USE_MATCH_CACHE
+#ifdef USE_CACHE_MATCH_OPT
typedef struct {
UChar *addr;
- long cache_point;
- int outer_repeat_mem;
- long num_cache_points_at_outer_repeat;
- long num_cache_points_in_outer_repeat;
- int lookaround_nesting;
- UChar *match_addr;
-} OnigCacheOpcode;
+ long num;
+ int outer_repeat;
+} OnigCacheIndex;
#endif
typedef struct {
@@ -921,23 +910,16 @@ typedef struct {
#else
uint64_t end_time;
#endif
-#ifdef USE_MATCH_CACHE
- int match_cache_status;
- long num_fails;
- long num_cache_opcodes;
- OnigCacheOpcode* cache_opcodes;
- long num_cache_points;
- uint8_t* match_cache_buf;
+#ifdef USE_CACHE_MATCH_OPT
+ long num_fail;
+ int enable_cache_match_opt;
+ long num_cache_opcode;
+ long num_cache_table;
+ OnigCacheIndex* cache_index_table;
+ uint8_t* match_cache;
#endif
} OnigMatchArg;
-#define NUM_CACHE_OPCODES_UNINIT 1
-#define NUM_CACHE_OPCODES_IMPOSSIBLE -1
-
-#define MATCH_CACHE_STATUS_UNINIT 1
-#define MATCH_CACHE_STATUS_INIT 2
-#define MATCH_CACHE_STATUS_DISABLED -1
-#define MATCH_CACHE_STATUS_ENABLED 0
#define IS_CODE_SB_WORD(enc,code) \
(ONIGENC_IS_CODE_ASCII(code) && ONIGENC_IS_CODE_WORD(enc,code))
@@ -1001,8 +983,7 @@ extern int onig_st_insert_strend(hash_table_type* table, const UChar* str_key, c
#ifdef RUBY
extern size_t onig_memsize(const regex_t *reg);
extern size_t onig_region_memsize(const struct re_registers *regs);
-bool rb_reg_timeout_p(regex_t *reg, void *end_time);
-NORETURN(void rb_reg_raise_timeout(void));
+void rb_reg_check_timeout(regex_t *reg, void *end_time);
#endif
RUBY_SYMBOL_EXPORT_END
diff --git a/regparse.c b/regparse.c
index 57ecd78dee..33df0e06c7 100644
--- a/regparse.c
+++ b/regparse.c
@@ -142,7 +142,7 @@ static void
bbuf_free(BBuf* bbuf)
{
if (IS_NOT_NULL(bbuf)) {
- xfree(bbuf->p);
+ if (IS_NOT_NULL(bbuf->p)) xfree(bbuf->p);
xfree(bbuf);
}
}
@@ -251,7 +251,7 @@ bitset_copy(BitSetRef dest, BitSetRef bs)
#if defined(USE_NAMED_GROUP) && !defined(USE_ST_LIBRARY)
extern int
-onig_strncmp(const UChar* s1, const UChar* s2, size_t n)
+onig_strncmp(const UChar* s1, const UChar* s2, int n)
{
int x;
@@ -275,7 +275,7 @@ onig_strcpy(UChar* dest, const UChar* src, const UChar* end)
#ifdef USE_NAMED_GROUP
static UChar*
-strdup_with_null(OnigEncoding enc, const UChar* s, const UChar* end)
+strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
{
ptrdiff_t slen;
int term_len, i;
@@ -476,11 +476,8 @@ typedef st_data_t HashDataType; /* 1.6 st.h doesn't define st_data_t type */
# ifdef ONIG_DEBUG
static int
-i_print_name_entry(HashDataType key_, HashDataType e_, HashDataType arg_)
+i_print_name_entry(UChar* key, NameEntry* e, void* arg)
{
- UChar* key = (UChar *)key_;
- NameEntry* e = (NameEntry *)e_;
- void* arg = (void *)arg_;
int i;
FILE* fp = (FILE* )arg;
@@ -506,7 +503,7 @@ onig_print_names(FILE* fp, regex_t* reg)
if (IS_NOT_NULL(t)) {
fprintf(fp, "name table\n");
- onig_st_foreach(t, i_print_name_entry, (HashDataType )fp);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_print_name_entry, (HashDataType )fp);
fputs("\n", fp);
}
return 0;
@@ -514,12 +511,10 @@ onig_print_names(FILE* fp, regex_t* reg)
# endif /* ONIG_DEBUG */
static int
-i_free_name_entry(HashDataType key_, HashDataType e_, HashDataType arg_ ARG_UNUSED)
+i_free_name_entry(UChar* key, NameEntry* e, void* arg ARG_UNUSED)
{
- UChar* key = (UChar *)key_;
- NameEntry* e = (NameEntry *)e_;
xfree(e->name);
- xfree(e->back_refs);
+ if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
xfree(key);
xfree(e);
return ST_DELETE;
@@ -531,7 +526,7 @@ names_clear(regex_t* reg)
NameTable* t = (NameTable* )reg->name_table;
if (IS_NOT_NULL(t)) {
- onig_st_foreach(t, i_free_name_entry, 0);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_free_name_entry, 0);
}
return 0;
}
@@ -551,58 +546,6 @@ onig_names_free(regex_t* reg)
return 0;
}
-static int
-copy_named_captures_iter(const OnigUChar *name, const OnigUChar *name_end,
- int back_num, int *back_refs, OnigRegex regex, void *arg)
-{
- NameTable *copy_table = (NameTable *)arg;
- NameEntry *entry_copy = (NameEntry* )xmalloc(sizeof(NameEntry));
- if (IS_NULL(entry_copy)) return -1;
-
- entry_copy->name_len = name_end - name;
- entry_copy->back_num = back_num;
- entry_copy->back_alloc = back_num;
- entry_copy->back_ref1 = back_refs[0];
- entry_copy->back_refs = xmalloc(back_num * (sizeof(int*)));
- if (IS_NULL(entry_copy->back_refs)) {
- xfree(entry_copy);
- return -1;
- }
- memcpy(entry_copy->back_refs, back_refs, back_num * sizeof(back_refs[0]));
-
- UChar *new_name = strdup_with_null(regex->enc, name, name_end);
- if (IS_NULL(new_name)) {
- xfree(entry_copy->back_refs);
- xfree(entry_copy);
- return -1;
- }
- entry_copy->name = new_name;
-
- if (onig_st_insert_strend(copy_table, new_name, (new_name + entry_copy->name_len), (hash_data_type)entry_copy)) {
- xfree(entry_copy->name);
- xfree(entry_copy->back_refs);
- xfree(entry_copy);
- return -1;
- }
- return 0;
-}
-
-extern int
-onig_names_copy(regex_t* reg, regex_t* oreg)
-{
- NameTable* table = oreg->name_table;
- if (table) {
- NameTable * t = onig_st_init_strend_table_with_size(onig_number_of_names(oreg));
- CHECK_NULL_RETURN_MEMERR(t);
- if (onig_foreach_name(oreg, copy_named_captures_iter, (void*)t)) {
- onig_st_free_table(t);
- return ONIGERR_MEMORY;
- }
- reg->name_table = t;
- }
- return 0;
-}
-
static NameEntry*
name_find(regex_t* reg, const UChar* name, const UChar* name_end)
{
@@ -625,10 +568,8 @@ typedef struct {
} INamesArg;
static int
-i_names(HashDataType key_ ARG_UNUSED, HashDataType e_, HashDataType arg_)
+i_names(UChar* key ARG_UNUSED, NameEntry* e, INamesArg* arg)
{
- NameEntry* e = (NameEntry *)e_;
- INamesArg* arg = (INamesArg *)arg_;
int r = (*(arg->func))(e->name,
e->name + e->name_len,
e->back_num,
@@ -654,16 +595,14 @@ onig_foreach_name(regex_t* reg,
narg.reg = reg;
narg.arg = arg;
narg.enc = reg->enc; /* should be pattern encoding. */
- onig_st_foreach(t, i_names, (HashDataType )&narg);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_names, (HashDataType )&narg);
}
return narg.ret;
}
static int
-i_renumber_name(HashDataType key_ ARG_UNUSED, HashDataType e_, HashDataType map_)
+i_renumber_name(UChar* key ARG_UNUSED, NameEntry* e, GroupNumRemap* map)
{
- NameEntry* e = (NameEntry *)e_;
- GroupNumRemap* map = (GroupNumRemap *)map_;
int i;
if (e->back_num > 1) {
@@ -684,7 +623,7 @@ onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
NameTable* t = (NameTable* )reg->name_table;
if (IS_NOT_NULL(t)) {
- onig_st_foreach(t, i_renumber_name, (HashDataType )map);
+ onig_st_foreach(t, (st_foreach_callback_func *)i_renumber_name, (HashDataType )map);
}
return 0;
}
@@ -760,7 +699,7 @@ names_clear(regex_t* reg)
e->name_len = 0;
e->back_num = 0;
e->back_alloc = 0;
- xfree(e->back_refs);
+ if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
e->back_refs = (int* )NULL;
}
}
@@ -783,57 +722,15 @@ onig_names_free(regex_t* reg)
if (r) return r;
t = (NameTable* )reg->name_table;
- xfree(t);
+ if (IS_NOT_NULL(t)) xfree(t);
reg->name_table = NULL;
return 0;
}
-extern int
-onig_names_copy(regex_t* reg, regex_t* oreg)
-{
- NameTable* ot = oreg->name_table;
- if (ot) {
- OnigEncoding enc = oreg->enc;
- int i, num = ot->num;
- NameTable* t = xmalloc(sizeof(*t));
- CHECK_NULL_RETURN_MEMERR(t);
- *t = *ot;
- t->e = xmalloc(t->alloc * sizeof(t->e[0]));
- if (IS_NULL(t->e)) {
- xfree(t);
- return ONIGERR_MEMORY;
- }
- t->num = 0;
- reg->name_table = t;
- for (i = 0; i < num; t->num = ++i) {
- NameEntry* oe = &(ot->e[i]);
- NameEntry* e = &(t->e[i]);
- *e = *oe;
- e->name = NULL;
- e->back_refs = NULL;
- e->name = strdup_with_null(enc, oe->name, oe->name + e->name_len);
- if (IS_NULL(e->name)) {
- onig_names_free(reg);
- return ONIGERR_MEMORY;
- }
- e->back_refs = xmalloc(e->back_alloc * sizeof(e->back_refs[0]));
- if (IS_NULL(e->back_refs)) {
- xfree(e->name);
- onig_names_free(reg);
- return ONIGERR_MEMORY;
- }
- memcpy(e->back_refs, oe->back_refs, e->back_num * sizeof(e->back_refs[0]));
- e->back_ref1 = e->back_refs[0];
- }
- }
- return 0;
-}
-
static NameEntry*
name_find(regex_t* reg, const UChar* name, const UChar* name_end)
{
- int i;
- size_t len;
+ int i, len;
NameEntry* e;
NameTable* t = (NameTable* )reg->name_table;
@@ -869,30 +766,6 @@ onig_foreach_name(regex_t* reg,
}
extern int
-onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
-{
- int i, j;
- NameEntry* e;
- NameTable* t = (NameTable* )reg->name_table;
-
- if (IS_NOT_NULL(t)) {
- for (i = 0; i < t->num; i++) {
- e = &(t->e[i]);
-
- if (e->back_num > 1) {
- for (j = 0; j < e->back_num; j++) {
- e->back_refs[j] = map[e->back_refs[j]].new_val;
- }
- }
- else if (e->back_num == 1) {
- e->back_ref1 = map[e->back_ref1].new_val;
- }
- }
- }
- return 0;
-}
-
-extern int
onig_number_of_names(const regex_t* reg)
{
NameTable* t = (NameTable* )reg->name_table;
@@ -1094,12 +967,6 @@ onig_number_of_names(const regex_t* reg)
{
return 0;
}
-
-extern int
-onig_names_copy(regex_t* reg, regex_t* oreg)
-{
- return 0;
-}
#endif /* else USE_NAMED_GROUP */
extern int
@@ -1231,24 +1098,29 @@ onig_node_free(Node* node)
{
CClassNode* cc = NCCLASS(node);
- bbuf_free(cc->mbuf);
+ if (cc->mbuf)
+ bbuf_free(cc->mbuf);
}
break;
case NT_QTFR:
- onig_node_free(NQTFR(node)->target);
+ if (NQTFR(node)->target)
+ onig_node_free(NQTFR(node)->target);
break;
case NT_ENCLOSE:
- onig_node_free(NENCLOSE(node)->target);
+ if (NENCLOSE(node)->target)
+ onig_node_free(NENCLOSE(node)->target);
break;
case NT_BREF:
- xfree(NBREF(node)->back_dynamic);
+ if (IS_NOT_NULL(NBREF(node)->back_dynamic))
+ xfree(NBREF(node)->back_dynamic);
break;
case NT_ANCHOR:
- onig_node_free(NANCHOR(node)->target);
+ if (NANCHOR(node)->target)
+ onig_node_free(NANCHOR(node)->target);
break;
}
diff --git a/regparse.h b/regparse.h
index de980d0ac8..acdd3e2f5c 100644
--- a/regparse.h
+++ b/regparse.h
@@ -339,7 +339,7 @@ typedef struct {
extern int onig_renumber_name_table(regex_t* reg, GroupNumRemap* map);
#endif
-extern int onig_strncmp(const UChar* s1, const UChar* s2, size_t n);
+extern int onig_strncmp(const UChar* s1, const UChar* s2, int n);
extern void onig_strcpy(UChar* dest, const UChar* src, const UChar* end);
extern void onig_scan_env_set_error_string(ScanEnv* env, int ecode, UChar* arg, UChar* arg_end);
extern int onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc);
@@ -356,7 +356,6 @@ extern Node* onig_node_list_add(Node* list, Node* x);
extern Node* onig_node_new_alt(Node* left, Node* right);
extern void onig_node_str_clear(Node* node);
extern int onig_names_free(regex_t* reg);
-extern int onig_names_copy(regex_t* reg, regex_t* oreg);
extern int onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_t* reg, ScanEnv* env);
extern int onig_free_shared_cclass_table(void);
diff --git a/rjit.c b/rjit.c
deleted file mode 100644
index 82f17f7dbc..0000000000
--- a/rjit.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/**********************************************************************
-
- rjit.c - Ruby JIT compiler functions
-
- Copyright (C) 2023 Takashi Kokubun <k0kubun@ruby-lang.org>.
-
-**********************************************************************/
-
-#include "rjit.h" // defines USE_RJIT
-
-#if USE_RJIT
-
-#include "constant.h"
-#include "id_table.h"
-#include "internal.h"
-#include "internal/class.h"
-#include "internal/cmdlineopt.h"
-#include "internal/cont.h"
-#include "internal/file.h"
-#include "internal/hash.h"
-#include "internal/process.h"
-#include "internal/warnings.h"
-#include "vm_sync.h"
-#include "ractor_core.h"
-
-#ifdef __sun
-#define __EXTENSIONS__ 1
-#endif
-
-#include "vm_core.h"
-#include "vm_callinfo.h"
-#include "rjit_c.h"
-#include "ruby_assert.h"
-#include "ruby/debug.h"
-#include "ruby/thread.h"
-#include "ruby/version.h"
-#include "builtin.h"
-#include "insns.inc"
-#include "insns_info.inc"
-#include "internal/compile.h"
-#include "internal/gc.h"
-
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <dlfcn.h>
-#include <errno.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#include "dln.h"
-
-// For mmapp(), sysconf()
-#ifndef _WIN32
-#include <unistd.h>
-#include <sys/mman.h>
-#endif
-
-#include "ruby/util.h"
-
-// A copy of RJIT portion of MRI options since RJIT initialization. We
-// need them as RJIT threads still can work when the most MRI data were
-// freed.
-struct rb_rjit_options rb_rjit_opts;
-
-// true if RJIT is enabled.
-bool rb_rjit_enabled = false;
-// true if --rjit-stats (used before rb_rjit_opts is set)
-bool rb_rjit_stats_enabled = false;
-// true if --rjit-trace-exits (used before rb_rjit_opts is set)
-bool rb_rjit_trace_exits_enabled = false;
-// true if JIT-ed code should be called. When `ruby_vm_event_enabled_global_flags & ISEQ_TRACE_EVENTS`
-// and `rb_rjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
-bool rb_rjit_call_p = false;
-// A flag to communicate that rb_rjit_call_p should be disabled while it's temporarily false.
-static bool rjit_cancel_p = false;
-
-// `rb_ec_ractor_hooks(ec)->events` is moved to this variable during compilation.
-rb_event_flag_t rb_rjit_global_events = 0;
-
-// Basically rb_rjit_opts.stats, but this becomes false during RJIT compilation.
-static bool rjit_stats_p = false;
-
-// RubyVM::RJIT
-static VALUE rb_mRJIT = 0;
-// RubyVM::RJIT::C
-static VALUE rb_mRJITC = 0;
-// RubyVM::RJIT::Compiler
-static VALUE rb_RJITCompiler = 0;
-// RubyVM::RJIT::CPointer::Struct_rb_iseq_t
-static VALUE rb_cRJITIseqPtr = 0;
-// RubyVM::RJIT::CPointer::Struct_rb_control_frame_t
-static VALUE rb_cRJITCfpPtr = 0;
-// RubyVM::RJIT::Hooks
-static VALUE rb_mRJITHooks = 0;
-
-// Frames for --rjit-trace-exits
-VALUE rb_rjit_raw_samples = 0;
-// Line numbers for --rjit-trace-exits
-VALUE rb_rjit_line_samples = 0;
-
-// Postponed job handle for triggering rjit_iseq_update_references
-static rb_postponed_job_handle_t rjit_iseq_update_references_pjob;
-
-// A default threshold used to add iseq to JIT.
-#define DEFAULT_CALL_THRESHOLD 10
-// Size of executable memory block in MiB.
-#define DEFAULT_EXEC_MEM_SIZE 64
-
-#define opt_match_noarg(s, l, name) \
- opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --rjit-" name " is ignored"), 1) : 1)
-#define opt_match_arg(s, l, name) \
- opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--rjit-" name " needs an argument"), 0))
-
-void
-rb_rjit_setup_options(const char *s, struct rb_rjit_options *rjit_opt)
-{
- const size_t l = strlen(s);
- if (l == 0) {
- return;
- }
- else if (opt_match_arg(s, l, "exec-mem-size")) {
- rjit_opt->exec_mem_size = atoi(s + 1);
- }
- else if (opt_match_arg(s, l, "call-threshold")) {
- rjit_opt->call_threshold = atoi(s + 1);
- }
- else if (opt_match_noarg(s, l, "stats")) {
- rjit_opt->stats = true;
- }
- else if (opt_match_noarg(s, l, "disable")) {
- rjit_opt->disable = true;
- }
- else if (opt_match_noarg(s, l, "trace")) {
- rjit_opt->trace = true;
- }
- else if (opt_match_noarg(s, l, "trace-exits")) {
- rjit_opt->trace_exits = true;
- }
- else if (opt_match_noarg(s, l, "dump-disasm")) {
- rjit_opt->dump_disasm = true;
- }
- else if (opt_match_noarg(s, l, "verify-ctx")) {
- rjit_opt->verify_ctx = true;
- }
- else {
- rb_raise(rb_eRuntimeError,
- "invalid RJIT option `%s' (--help will show valid RJIT options)", s);
- }
-}
-
-#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc)
-const struct ruby_opt_message rb_rjit_option_messages[] = {
- M("--rjit-exec-mem-size=num", "", "Size of executable memory block in MiB (default: " STRINGIZE(DEFAULT_EXEC_MEM_SIZE) ")"),
- M("--rjit-call-threshold=num", "", "Number of calls to trigger JIT (default: " STRINGIZE(DEFAULT_CALL_THRESHOLD) ")"),
- M("--rjit-stats", "", "Enable collecting RJIT statistics"),
- M("--rjit-disable", "", "Disable RJIT for lazily enabling it with RubyVM::RJIT.enable"),
- M("--rjit-trace", "", "Allow TracePoint during JIT compilation"),
- M("--rjit-trace-exits", "", "Trace side exit locations"),
-#ifdef HAVE_LIBCAPSTONE
- M("--rjit-dump-disasm", "", "Dump all JIT code"),
-#endif
- {0}
-};
-#undef M
-
-struct rb_rjit_runtime_counters rb_rjit_counters = { 0 };
-
-extern VALUE rb_gc_enable(void);
-extern VALUE rb_gc_disable(void);
-extern uint64_t rb_vm_insns_count;
-
-// Disable GC, TracePoint, JIT, stats, and $!
-#define WITH_RJIT_ISOLATED_USING_PC(using_pc, stmt) do { \
- VALUE was_disabled = rb_gc_disable(); \
- \
- rb_hook_list_t *global_hooks = rb_ec_ractor_hooks(GET_EC()); \
- rb_rjit_global_events = global_hooks->events; \
- \
- const VALUE *pc = NULL; \
- if (rb_rjit_opts.trace) { \
- pc = GET_EC()->cfp->pc; \
- if (!using_pc) GET_EC()->cfp->pc = 0; /* avoid crashing on calc_lineno */ \
- } \
- else global_hooks->events = 0; \
- \
- bool original_call_p = rb_rjit_call_p; \
- rb_rjit_call_p = false; \
- \
- rjit_stats_p = false; \
- uint64_t insns_count = rb_vm_insns_count; \
- \
- VALUE err = rb_errinfo(); \
- \
- stmt; \
- \
- rb_set_errinfo(err); \
- \
- rb_vm_insns_count = insns_count; \
- rjit_stats_p = rb_rjit_opts.stats; \
- \
- rb_rjit_call_p = (rjit_cancel_p ? false : original_call_p); \
- \
- if (rb_rjit_opts.trace) GET_EC()->cfp->pc = pc; \
- else global_hooks->events = rb_rjit_global_events; \
- \
- if (!was_disabled) rb_gc_enable(); \
-} while (0);
-#define WITH_RJIT_ISOLATED(stmt) WITH_RJIT_ISOLATED_USING_PC(false, stmt)
-
-void
-rb_rjit_cancel_all(const char *reason)
-{
- if (!rb_rjit_enabled)
- return;
-
- rb_rjit_call_p = false;
- rjit_cancel_p = true;
-}
-
-void
-rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop)
-{
- if (!rb_rjit_call_p) return;
- rb_rjit_call_p = false;
-}
-
-static void
-rjit_cme_invalidate(void *data)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
- WITH_RJIT_ISOLATED({
- rb_funcall(rb_mRJITHooks, rb_intern("on_cme_invalidate"), 1, SIZET2NUM((size_t)data));
- });
-}
-
-extern int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t func, void *data);
-
-void
-rb_rjit_cme_invalidate(rb_callable_method_entry_t *cme)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
- // Asynchronously hook the Ruby code since running Ruby in the middle of cme invalidation is dangerous.
- rb_workqueue_register(0, rjit_cme_invalidate, (void *)cme);
-}
-
-void
-rb_rjit_before_ractor_spawn(void)
-{
- if (!rb_rjit_call_p) return;
- rb_rjit_call_p = false;
-}
-
-static void
-rjit_constant_state_changed(void *data)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
- RB_VM_LOCK_ENTER();
- rb_vm_barrier();
-
- WITH_RJIT_ISOLATED({
- rb_funcall(rb_mRJITHooks, rb_intern("on_constant_state_changed"), 1, SIZET2NUM((size_t)data));
- });
-
- RB_VM_LOCK_LEAVE();
-}
-
-void
-rb_rjit_constant_state_changed(ID id)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
- // Asynchronously hook the Ruby code since this is hooked during a "Ruby critical section".
- rb_workqueue_register(0, rjit_constant_state_changed, (void *)id);
-}
-
-void
-rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
-
- RB_VM_LOCK_ENTER();
- rb_vm_barrier();
-
- WITH_RJIT_ISOLATED({
- rb_funcall(rb_mRJITHooks, rb_intern("on_constant_ic_update"), 3,
- SIZET2NUM((size_t)iseq), SIZET2NUM((size_t)ic), UINT2NUM(insn_idx));
- });
-
- RB_VM_LOCK_LEAVE();
-}
-
-void
-rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
- WITH_RJIT_ISOLATED({
- rb_funcall(rb_mRJITHooks, rb_intern("on_tracing_invalidate_all"), 1, UINT2NUM(new_iseq_events));
- });
-}
-
-static void
-rjit_iseq_update_references(void *data)
-{
- if (!rb_rjit_enabled || !rb_rjit_call_p || !rb_mRJITHooks) return;
- WITH_RJIT_ISOLATED({
- rb_funcall(rb_mRJITHooks, rb_intern("on_update_references"), 0);
- });
-}
-
-void
-rb_rjit_iseq_update_references(struct rb_iseq_constant_body *const body)
-{
- if (!rb_rjit_enabled) return;
-
- if (body->rjit_blocks) {
- body->rjit_blocks = rb_gc_location(body->rjit_blocks);
- }
-
- // Asynchronously hook the Ruby code to avoid allocation during GC.compact.
- // Using _one because it's too slow to invalidate all for each ISEQ. Thus
- // not giving an ISEQ pointer.
- rb_postponed_job_trigger(rjit_iseq_update_references_pjob);
-}
-
-void
-rb_rjit_iseq_mark(VALUE rjit_blocks)
-{
- if (!rb_rjit_enabled) return;
-
- // Note: This wasn't enough for some reason.
- // We actually rely on RubyVM::RJIT::GC_REFS to mark this.
- if (rjit_blocks) {
- rb_gc_mark_movable(rjit_blocks);
- }
-}
-
-// Called by rb_vm_mark()
-void
-rb_rjit_mark(void)
-{
- if (!rb_rjit_enabled)
- return;
- RUBY_MARK_ENTER("rjit");
-
- // Pin object pointers used in this file
- rb_gc_mark(rb_RJITCompiler);
- rb_gc_mark(rb_cRJITIseqPtr);
- rb_gc_mark(rb_cRJITCfpPtr);
- rb_gc_mark(rb_mRJITHooks);
- rb_gc_mark(rb_rjit_raw_samples);
- rb_gc_mark(rb_rjit_line_samples);
-
- RUBY_MARK_LEAVE("rjit");
-}
-
-void
-rb_rjit_free_iseq(const rb_iseq_t *iseq)
-{
- // TODO: implement this. GC_REFS should remove this iseq's mjit_blocks
-}
-
-// TODO: Use this in more places
-VALUE
-rb_rjit_iseq_new(rb_iseq_t *iseq)
-{
- return rb_funcall(rb_cRJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
-}
-
-void
-rb_rjit_compile(const rb_iseq_t *iseq)
-{
- RB_VM_LOCK_ENTER();
- rb_vm_barrier();
-
- WITH_RJIT_ISOLATED_USING_PC(true, {
- VALUE iseq_ptr = rb_funcall(rb_cRJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
- VALUE cfp_ptr = rb_funcall(rb_cRJITCfpPtr, rb_intern("new"), 1, SIZET2NUM((size_t)GET_EC()->cfp));
- rb_funcall(rb_RJITCompiler, rb_intern("compile"), 2, iseq_ptr, cfp_ptr);
- });
-
- RB_VM_LOCK_LEAVE();
-}
-
-void *
-rb_rjit_entry_stub_hit(VALUE branch_stub)
-{
- VALUE result;
-
- RB_VM_LOCK_ENTER();
- rb_vm_barrier();
-
- rb_control_frame_t *cfp = GET_EC()->cfp;
-
- WITH_RJIT_ISOLATED_USING_PC(true, {
- VALUE cfp_ptr = rb_funcall(rb_cRJITCfpPtr, rb_intern("new"), 1, SIZET2NUM((size_t)cfp));
- result = rb_funcall(rb_RJITCompiler, rb_intern("entry_stub_hit"), 2, branch_stub, cfp_ptr);
- });
-
- RB_VM_LOCK_LEAVE();
-
- return (void *)NUM2SIZET(result);
-}
-
-void *
-rb_rjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p)
-{
- VALUE result;
-
- RB_VM_LOCK_ENTER();
- rb_vm_barrier();
-
- rb_control_frame_t *cfp = GET_EC()->cfp;
- cfp->sp += sp_offset; // preserve stack values, also using the actual sp_offset to make jit.peek_at_stack work
-
- WITH_RJIT_ISOLATED({
- VALUE cfp_ptr = rb_funcall(rb_cRJITCfpPtr, rb_intern("new"), 1, SIZET2NUM((size_t)cfp));
- result = rb_funcall(rb_RJITCompiler, rb_intern("branch_stub_hit"), 3, branch_stub, cfp_ptr, RBOOL(target0_p));
- });
-
- cfp->sp -= sp_offset; // reset for consistency with the code without the stub
-
- RB_VM_LOCK_LEAVE();
-
- return (void *)NUM2SIZET(result);
-}
-
-void
-rb_rjit_init(const struct rb_rjit_options *opts)
-{
- VM_ASSERT(rb_rjit_enabled);
-
- // Normalize options
- rb_rjit_opts = *opts;
- if (rb_rjit_opts.exec_mem_size == 0)
- rb_rjit_opts.exec_mem_size = DEFAULT_EXEC_MEM_SIZE;
- if (rb_rjit_opts.call_threshold == 0)
- rb_rjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD;
-#ifndef HAVE_LIBCAPSTONE
- if (rb_rjit_opts.dump_disasm)
- rb_warn("libcapstone has not been linked. Ignoring --rjit-dump-disasm.");
-#endif
-
- // RJIT doesn't support miniruby, but it might reach here by RJIT_FORCE_ENABLE.
- rb_mRJIT = rb_const_get(rb_cRubyVM, rb_intern("RJIT"));
- if (!rb_const_defined(rb_mRJIT, rb_intern("Compiler"))) {
- rb_warn("Disabling RJIT because RubyVM::RJIT::Compiler is not defined");
- rb_rjit_enabled = false;
- return;
- }
- rjit_iseq_update_references_pjob = rb_postponed_job_preregister(0, rjit_iseq_update_references, NULL);
- if (rjit_iseq_update_references_pjob == POSTPONED_JOB_HANDLE_INVALID) {
- rb_bug("Could not preregister postponed job for RJIT");
- }
- rb_mRJITC = rb_const_get(rb_mRJIT, rb_intern("C"));
- VALUE rb_cRJITCompiler = rb_const_get(rb_mRJIT, rb_intern("Compiler"));
- rb_RJITCompiler = rb_funcall(rb_cRJITCompiler, rb_intern("new"), 0);
- rb_cRJITIseqPtr = rb_funcall(rb_mRJITC, rb_intern("rb_iseq_t"), 0);
- rb_cRJITCfpPtr = rb_funcall(rb_mRJITC, rb_intern("rb_control_frame_t"), 0);
- rb_mRJITHooks = rb_const_get(rb_mRJIT, rb_intern("Hooks"));
- if (rb_rjit_opts.trace_exits) {
- rb_rjit_raw_samples = rb_ary_new();
- rb_rjit_line_samples = rb_ary_new();
- }
-
- // Enable RJIT and stats from here
- rb_rjit_call_p = !rb_rjit_opts.disable;
- rjit_stats_p = rb_rjit_opts.stats;
-}
-
-//
-// Primitive for rjit.rb
-//
-
-// Same as `rb_rjit_opts.stats`, but this is used before rb_rjit_opts is set.
-static VALUE
-rjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self)
-{
- return RBOOL(rb_rjit_stats_enabled);
-}
-
-// Same as `rb_rjit_opts.trace_exits`, but this is used before rb_rjit_opts is set.
-static VALUE
-rjit_trace_exits_enabled_p(rb_execution_context_t *ec, VALUE self)
-{
- return RBOOL(rb_rjit_trace_exits_enabled);
-}
-
-// Disable anything that could impact stats. It ends up disabling JIT calls as well.
-static VALUE
-rjit_stop_stats(rb_execution_context_t *ec, VALUE self)
-{
- rb_rjit_call_p = false;
- rjit_stats_p = false;
- return Qnil;
-}
-
-#include "rjit.rbinc"
-
-#endif // USE_RJIT
diff --git a/rjit.h b/rjit.h
deleted file mode 100644
index 26d1d67fb1..0000000000
--- a/rjit.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef RUBY_RJIT_H
-#define RUBY_RJIT_H 1
-/**********************************************************************
-
- rjit.h - Interface to RJIT
-
- Copyright (C) 2023 Takashi Kokubun <k0kubun@ruby-lang.org>.
-
-**********************************************************************/
-
-#include "ruby/internal/config.h" // defines USE_RJIT
-#include "ruby/internal/stdbool.h"
-#include "vm_core.h"
-
-# if USE_RJIT
-
-#include "ruby.h"
-#include "vm_core.h"
-
-// RJIT options which can be defined on the MRI command line.
-struct rb_rjit_options {
- // Converted from "rjit" feature flag to tell the enablement
- // information to ruby_show_version().
- bool on;
- // Size of executable memory block in MiB
- unsigned int exec_mem_size;
- // Number of calls to trigger JIT compilation
- unsigned int call_threshold;
- // Collect RJIT statistics
- bool stats;
- // Do not start RJIT until RJIT.enable is called
- bool disable;
- // Allow TracePoint during JIT compilation
- bool trace;
- // Trace side exit locations
- bool trace_exits;
- // Enable disasm of all JIT code
- bool dump_disasm;
- // Verify context objects
- bool verify_ctx;
-};
-
-RUBY_SYMBOL_EXPORT_BEGIN
-RUBY_EXTERN struct rb_rjit_options rb_rjit_opts;
-RUBY_EXTERN bool rb_rjit_call_p;
-
-#define rb_rjit_call_threshold() rb_rjit_opts.call_threshold
-
-extern void rb_rjit_compile(const rb_iseq_t *iseq);
-RUBY_SYMBOL_EXPORT_END
-
-extern void rb_rjit_cancel_all(const char *reason);
-extern void rb_rjit_init(const struct rb_rjit_options *opts);
-extern void rb_rjit_free_iseq(const rb_iseq_t *iseq);
-extern void rb_rjit_iseq_update_references(struct rb_iseq_constant_body *const body);
-extern void rb_rjit_mark(void);
-extern void rb_rjit_iseq_mark(VALUE rjit_blocks);
-extern void rjit_notify_waitpid(int exit_code);
-
-extern void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
-extern void rb_rjit_cme_invalidate(rb_callable_method_entry_t *cme);
-extern void rb_rjit_before_ractor_spawn(void);
-extern void rb_rjit_constant_state_changed(ID id);
-extern void rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx);
-extern void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
-
-extern void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
-extern void rb_rjit_before_ractor_spawn(void);
-extern void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
-extern void rb_rjit_collect_vm_usage_insn(int insn);
-
-extern bool rb_rjit_enabled;
-extern bool rb_rjit_stats_enabled;
-extern bool rb_rjit_trace_exits_enabled;
-
-# else // USE_RJIT
-
-static inline void rb_rjit_compile(const rb_iseq_t *iseq){}
-
-static inline void rb_rjit_cancel_all(const char *reason){}
-static inline void rb_rjit_free_iseq(const rb_iseq_t *iseq){}
-static inline void rb_rjit_mark(void){}
-
-static inline void rb_rjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
-static inline void rb_rjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
-static inline void rb_rjit_before_ractor_spawn(void) {}
-static inline void rb_rjit_constant_state_changed(ID id) {}
-static inline void rb_rjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx) {}
-static inline void rb_rjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events) {}
-
-#define rb_rjit_enabled false
-#define rb_rjit_call_p false
-#define rb_rjit_stats_enabled false
-#define rb_rjit_trace_exits_enabled false
-
-#define rb_rjit_call_threshold() UINT_MAX
-
-static inline void rb_rjit_collect_vm_usage_insn(int insn) {}
-
-# endif // USE_RJIT
-#endif // RUBY_RJIT_H
diff --git a/rjit.rb b/rjit.rb
deleted file mode 100644
index 12fc10c91e..0000000000
--- a/rjit.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-module RubyVM::RJIT
- # Return true if \RJIT is enabled.
- def self.enabled?
- Primitive.cexpr! 'RBOOL(rb_rjit_enabled)'
- end
-
- # Start JIT compilation after \--rjit-disable.
- def self.enable
- Primitive.cstmt! %{
- rb_rjit_call_p = true;
- return Qnil;
- }
- end
-
- if Primitive.rjit_stats_enabled_p
- at_exit do
- Primitive.rjit_stop_stats
- print_stats
- end
- end
- if Primitive.rjit_trace_exits_enabled_p
- at_exit do
- Primitive.rjit_stop_stats
- dump_trace_exits
- end
- end
-end
-
-if RubyVM::RJIT.enabled?
- begin
- require 'fiddle'
- require 'fiddle/import'
- rescue LoadError
- return # miniruby doesn't support RJIT
- end
-
- require 'ruby_vm/rjit/c_type'
- require 'ruby_vm/rjit/compiler'
- require 'ruby_vm/rjit/hooks'
- require 'ruby_vm/rjit/stats'
-end
diff --git a/rjit_c.c b/rjit_c.c
deleted file mode 100644
index e6d8d5da5c..0000000000
--- a/rjit_c.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/**********************************************************************
-
- rjit_c.c - C helpers for RJIT
-
- Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>.
-
-**********************************************************************/
-
-#include "rjit.h" // defines USE_RJIT
-
-#if USE_RJIT
-
-#include "rjit_c.h"
-#include "include/ruby/assert.h"
-#include "include/ruby/debug.h"
-#include "internal.h"
-#include "internal/compile.h"
-#include "internal/fixnum.h"
-#include "internal/hash.h"
-#include "internal/sanitizers.h"
-#include "internal/gc.h"
-#include "internal/proc.h"
-#include "yjit.h"
-#include "vm_insnhelper.h"
-#include "probes.h"
-#include "probes_helper.h"
-
-#include "insns.inc"
-#include "insns_info.inc"
-
-// For mmapp(), sysconf()
-#ifndef _WIN32
-#include <unistd.h>
-#include <sys/mman.h>
-#endif
-
-#include <errno.h>
-
-#if defined(MAP_FIXED_NOREPLACE) && defined(_SC_PAGESIZE)
-// Align the current write position to a multiple of bytes
-static uint8_t *
-align_ptr(uint8_t *ptr, uint32_t multiple)
-{
- // Compute the pointer modulo the given alignment boundary
- uint32_t rem = ((uint32_t)(uintptr_t)ptr) % multiple;
-
- // If the pointer is already aligned, stop
- if (rem == 0)
- return ptr;
-
- // Pad the pointer by the necessary amount to align it
- uint32_t pad = multiple - rem;
-
- return ptr + pad;
-}
-#endif
-
-// Address space reservation. Memory pages are mapped on an as needed basis.
-// See the Rust mm module for details.
-static uint8_t *
-rjit_reserve_addr_space(uint32_t mem_size)
-{
-#ifndef _WIN32
- uint8_t *mem_block;
-
- // On Linux
- #if defined(MAP_FIXED_NOREPLACE) && defined(_SC_PAGESIZE)
- uint32_t const page_size = (uint32_t)sysconf(_SC_PAGESIZE);
- uint8_t *const cfunc_sample_addr = (void *)&rjit_reserve_addr_space;
- uint8_t *const probe_region_end = cfunc_sample_addr + INT32_MAX;
- // Align the requested address to page size
- uint8_t *req_addr = align_ptr(cfunc_sample_addr, page_size);
-
- // Probe for addresses close to this function using MAP_FIXED_NOREPLACE
- // to improve odds of being in range for 32-bit relative call instructions.
- do {
- mem_block = mmap(
- req_addr,
- mem_size,
- PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE,
- -1,
- 0
- );
-
- // If we succeeded, stop
- if (mem_block != MAP_FAILED) {
- break;
- }
-
- // +4MB
- req_addr += 4 * 1024 * 1024;
- } while (req_addr < probe_region_end);
-
- // On MacOS and other platforms
- #else
- // Try to map a chunk of memory as executable
- mem_block = mmap(
- (void *)rjit_reserve_addr_space,
- mem_size,
- PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS,
- -1,
- 0
- );
- #endif
-
- // Fallback
- if (mem_block == MAP_FAILED) {
- // Try again without the address hint (e.g., valgrind)
- mem_block = mmap(
- NULL,
- mem_size,
- PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS,
- -1,
- 0
- );
- }
-
- // Check that the memory mapping was successful
- if (mem_block == MAP_FAILED) {
- perror("ruby: yjit: mmap:");
- if(errno == ENOMEM) {
- // No crash report if it's only insufficient memory
- exit(EXIT_FAILURE);
- }
- rb_bug("mmap failed");
- }
-
- return mem_block;
-#else
- // Windows not supported for now
- return NULL;
-#endif
-}
-
-static VALUE
-mprotect_write(rb_execution_context_t *ec, VALUE self, VALUE rb_mem_block, VALUE rb_mem_size)
-{
- void *mem_block = (void *)NUM2SIZET(rb_mem_block);
- uint32_t mem_size = NUM2UINT(rb_mem_size);
- return RBOOL(mprotect(mem_block, mem_size, PROT_READ | PROT_WRITE) == 0);
-}
-
-static VALUE
-mprotect_exec(rb_execution_context_t *ec, VALUE self, VALUE rb_mem_block, VALUE rb_mem_size)
-{
- void *mem_block = (void *)NUM2SIZET(rb_mem_block);
- uint32_t mem_size = NUM2UINT(rb_mem_size);
- if (mem_size == 0) return Qfalse; // Some platforms return an error for mem_size 0.
-
- if (mprotect(mem_block, mem_size, PROT_READ | PROT_EXEC)) {
- rb_bug("Couldn't make JIT page (%p, %lu bytes) executable, errno: %s",
- mem_block, (unsigned long)mem_size, strerror(errno));
- }
- return Qtrue;
-}
-
-static VALUE
-rjit_optimized_call(VALUE *recv, rb_execution_context_t *ec, int argc, VALUE *argv, int kw_splat, VALUE block_handler)
-{
- rb_proc_t *proc;
- GetProcPtr(recv, proc);
- return rb_vm_invoke_proc(ec, proc, argc, argv, kw_splat, block_handler);
-}
-
-static VALUE
-rjit_str_neq_internal(VALUE str1, VALUE str2)
-{
- return rb_str_eql_internal(str1, str2) == Qtrue ? Qfalse : Qtrue;
-}
-
-static VALUE
-rjit_str_simple_append(VALUE str1, VALUE str2)
-{
- return rb_str_cat(str1, RSTRING_PTR(str2), RSTRING_LEN(str2));
-}
-
-static VALUE
-rjit_rb_ary_subseq_length(VALUE ary, long beg)
-{
- long len = RARRAY_LEN(ary);
- return rb_ary_subseq(ary, beg, len);
-}
-
-static VALUE
-rjit_build_kwhash(const struct rb_callinfo *ci, VALUE *sp)
-{
- const struct rb_callinfo_kwarg *kw_arg = vm_ci_kwarg(ci);
- int kw_len = kw_arg->keyword_len;
- VALUE hash = rb_hash_new_with_size(kw_len);
-
- for (int i = 0; i < kw_len; i++) {
- VALUE key = kw_arg->keywords[i];
- VALUE val = *(sp - kw_len + i);
- rb_hash_aset(hash, key, val);
- }
- return hash;
-}
-
-// The code we generate in gen_send_cfunc() doesn't fire the c_return TracePoint event
-// like the interpreter. When tracing for c_return is enabled, we patch the code after
-// the C method return to call into this to fire the event.
-static void
-rjit_full_cfunc_return(rb_execution_context_t *ec, VALUE return_value)
-{
- rb_control_frame_t *cfp = ec->cfp;
- RUBY_ASSERT_ALWAYS(cfp == GET_EC()->cfp);
- const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
-
- RUBY_ASSERT_ALWAYS(RUBYVM_CFUNC_FRAME_P(cfp));
- RUBY_ASSERT_ALWAYS(me->def->type == VM_METHOD_TYPE_CFUNC);
-
- // CHECK_CFP_CONSISTENCY("full_cfunc_return"); TODO revive this
-
- // Pop the C func's frame and fire the c_return TracePoint event
- // Note that this is the same order as vm_call_cfunc_with_frame().
- rb_vm_pop_frame(ec);
- EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, cfp->self, me->def->original_id, me->called_id, me->owner, return_value);
- // Note, this deviates from the interpreter in that users need to enable
- // a c_return TracePoint for this DTrace hook to work. A reasonable change
- // since the Ruby return event works this way as well.
- RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec, me->owner, me->def->original_id);
-
- // Push return value into the caller's stack. We know that it's a frame that
- // uses cfp->sp because we are patching a call done with gen_send_cfunc().
- ec->cfp->sp[0] = return_value;
- ec->cfp->sp++;
-}
-
-static rb_proc_t *
-rjit_get_proc_ptr(VALUE procv)
-{
- rb_proc_t *proc;
- GetProcPtr(procv, proc);
- return proc;
-}
-
-// Use the same buffer size as Stackprof.
-#define BUFF_LEN 2048
-
-extern VALUE rb_rjit_raw_samples;
-extern VALUE rb_rjit_line_samples;
-
-static void
-rjit_record_exit_stack(const VALUE *exit_pc)
-{
- // Let Primitive.rjit_stop_stats stop this
- if (!rb_rjit_call_p) return;
-
- // Get the opcode from the encoded insn handler at this PC
- int insn = rb_vm_insn_addr2opcode((void *)*exit_pc);
-
- // Create 2 array buffers to be used to collect frames and lines.
- VALUE frames_buffer[BUFF_LEN] = { 0 };
- int lines_buffer[BUFF_LEN] = { 0 };
-
- // Records call frame and line information for each method entry into two
- // temporary buffers. Returns the number of times we added to the buffer (ie
- // the length of the stack).
- //
- // Call frame info is stored in the frames_buffer, line number information
- // in the lines_buffer. The first argument is the start point and the second
- // argument is the buffer limit, set at 2048.
- int stack_length = rb_profile_frames(0, BUFF_LEN, frames_buffer, lines_buffer);
- int samples_length = stack_length + 3; // 3: length, insn, count
-
- // If yjit_raw_samples is less than or equal to the current length of the samples
- // we might have seen this stack trace previously.
- int prev_stack_len_index = (int)RARRAY_LEN(rb_rjit_raw_samples) - samples_length;
- VALUE prev_stack_len_obj;
- if (RARRAY_LEN(rb_rjit_raw_samples) >= samples_length && FIXNUM_P(prev_stack_len_obj = RARRAY_AREF(rb_rjit_raw_samples, prev_stack_len_index))) {
- int prev_stack_len = NUM2INT(prev_stack_len_obj);
- int idx = stack_length - 1;
- int prev_frame_idx = 0;
- bool seen_already = true;
-
- // If the previous stack length and current stack length are equal,
- // loop and compare the current frame to the previous frame. If they are
- // not equal, set seen_already to false and break out of the loop.
- if (prev_stack_len == stack_length) {
- while (idx >= 0) {
- VALUE current_frame = frames_buffer[idx];
- VALUE prev_frame = RARRAY_AREF(rb_rjit_raw_samples, prev_stack_len_index + prev_frame_idx + 1);
-
- // If the current frame and previous frame are not equal, set
- // seen_already to false and break out of the loop.
- if (current_frame != prev_frame) {
- seen_already = false;
- break;
- }
-
- idx--;
- prev_frame_idx++;
- }
-
- // If we know we've seen this stack before, increment the counter by 1.
- if (seen_already) {
- int prev_idx = (int)RARRAY_LEN(rb_rjit_raw_samples) - 1;
- int prev_count = NUM2INT(RARRAY_AREF(rb_rjit_raw_samples, prev_idx));
- int new_count = prev_count + 1;
-
- rb_ary_store(rb_rjit_raw_samples, prev_idx, INT2NUM(new_count));
- rb_ary_store(rb_rjit_line_samples, prev_idx, INT2NUM(new_count));
- return;
- }
- }
- }
-
- rb_ary_push(rb_rjit_raw_samples, INT2NUM(stack_length));
- rb_ary_push(rb_rjit_line_samples, INT2NUM(stack_length));
-
- int idx = stack_length - 1;
-
- while (idx >= 0) {
- VALUE frame = frames_buffer[idx];
- int line = lines_buffer[idx];
-
- rb_ary_push(rb_rjit_raw_samples, frame);
- rb_ary_push(rb_rjit_line_samples, INT2NUM(line));
-
- idx--;
- }
-
- // Push the insn value into the yjit_raw_samples Vec.
- rb_ary_push(rb_rjit_raw_samples, INT2NUM(insn));
-
- // Push the current line onto the yjit_line_samples Vec. This
- // points to the line in insns.def.
- int line = (int)RARRAY_LEN(rb_rjit_line_samples) - 1;
- rb_ary_push(rb_rjit_line_samples, INT2NUM(line));
-
- // Push number of times seen onto the stack, which is 1
- // because it's the first time we've seen it.
- rb_ary_push(rb_rjit_raw_samples, INT2NUM(1));
- rb_ary_push(rb_rjit_line_samples, INT2NUM(1));
-}
-
-// For a given raw_sample (frame), set the hash with the caller's
-// name, file, and line number. Return the hash with collected frame_info.
-static void
-rjit_add_frame(VALUE hash, VALUE frame)
-{
- VALUE frame_id = SIZET2NUM(frame);
-
- if (RTEST(rb_hash_aref(hash, frame_id))) {
- return;
- }
- else {
- VALUE frame_info = rb_hash_new();
- // Full label for the frame
- VALUE name = rb_profile_frame_full_label(frame);
- // Absolute path of the frame from rb_iseq_realpath
- VALUE file = rb_profile_frame_absolute_path(frame);
- // Line number of the frame
- VALUE line = rb_profile_frame_first_lineno(frame);
-
- // If absolute path isn't available use the rb_iseq_path
- if (NIL_P(file)) {
- file = rb_profile_frame_path(frame);
- }
-
- rb_hash_aset(frame_info, ID2SYM(rb_intern("name")), name);
- rb_hash_aset(frame_info, ID2SYM(rb_intern("file")), file);
- rb_hash_aset(frame_info, ID2SYM(rb_intern("samples")), INT2NUM(0));
- rb_hash_aset(frame_info, ID2SYM(rb_intern("total_samples")), INT2NUM(0));
- rb_hash_aset(frame_info, ID2SYM(rb_intern("edges")), rb_hash_new());
- rb_hash_aset(frame_info, ID2SYM(rb_intern("lines")), rb_hash_new());
-
- if (line != INT2FIX(0)) {
- rb_hash_aset(frame_info, ID2SYM(rb_intern("line")), line);
- }
-
- rb_hash_aset(hash, frame_id, frame_info);
- }
-}
-
-static VALUE
-rjit_exit_traces(void)
-{
- int samples_len = (int)RARRAY_LEN(rb_rjit_raw_samples);
- RUBY_ASSERT(samples_len == RARRAY_LEN(rb_rjit_line_samples));
-
- VALUE result = rb_hash_new();
- VALUE raw_samples = rb_ary_new_capa(samples_len);
- VALUE line_samples = rb_ary_new_capa(samples_len);
- VALUE frames = rb_hash_new();
- int idx = 0;
-
- // While the index is less than samples_len, parse yjit_raw_samples and
- // yjit_line_samples, then add casted values to raw_samples and line_samples array.
- while (idx < samples_len) {
- int num = NUM2INT(RARRAY_AREF(rb_rjit_raw_samples, idx));
- int line_num = NUM2INT(RARRAY_AREF(rb_rjit_line_samples, idx));
- idx++;
-
- rb_ary_push(raw_samples, SIZET2NUM(num));
- rb_ary_push(line_samples, INT2NUM(line_num));
-
- // Loop through the length of samples_len and add data to the
- // frames hash. Also push the current value onto the raw_samples
- // and line_samples array respectively.
- for (int o = 0; o < num; o++) {
- rjit_add_frame(frames, RARRAY_AREF(rb_rjit_raw_samples, idx));
- rb_ary_push(raw_samples, SIZET2NUM(RARRAY_AREF(rb_rjit_raw_samples, idx)));
- rb_ary_push(line_samples, RARRAY_AREF(rb_rjit_line_samples, idx));
- idx++;
- }
-
- // insn BIN and lineno
- rb_ary_push(raw_samples, RARRAY_AREF(rb_rjit_raw_samples, idx));
- rb_ary_push(line_samples, RARRAY_AREF(rb_rjit_line_samples, idx));
- idx++;
-
- // Number of times seen
- rb_ary_push(raw_samples, RARRAY_AREF(rb_rjit_raw_samples, idx));
- rb_ary_push(line_samples, RARRAY_AREF(rb_rjit_line_samples, idx));
- idx++;
- }
-
- // Set add the raw_samples, line_samples, and frames to the results
- // hash.
- rb_hash_aset(result, ID2SYM(rb_intern("raw")), raw_samples);
- rb_hash_aset(result, ID2SYM(rb_intern("lines")), line_samples);
- rb_hash_aset(result, ID2SYM(rb_intern("frames")), frames);
-
- return result;
-}
-
-// An offsetof implementation that works for unnamed struct and union.
-// Multiplying 8 for compatibility with libclang's offsetof.
-#define OFFSETOF(ptr, member) RB_SIZE2NUM(((char *)&ptr.member - (char*)&ptr) * 8)
-
-#define SIZEOF(type) RB_SIZE2NUM(sizeof(type))
-#define SIGNED_TYPE_P(type) RBOOL((type)(-1) < (type)(1))
-
-// Insn side exit counters
-static size_t rjit_insn_exits[VM_INSTRUCTION_SIZE] = { 0 };
-
-// macOS: brew install capstone
-// Ubuntu/Debian: apt-get install libcapstone-dev
-// Fedora: dnf -y install capstone-devel
-#ifdef HAVE_LIBCAPSTONE
-#include <capstone/capstone.h>
-#endif
-
-// Return an array of [address, mnemonic, op_str]
-static VALUE
-dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to, VALUE test)
-{
- VALUE result = rb_ary_new();
-#ifdef HAVE_LIBCAPSTONE
- // Prepare for calling cs_disasm
- static csh handle;
- if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) {
- rb_raise(rb_eRuntimeError, "failed to make Capstone handle");
- }
- size_t from_addr = NUM2SIZET(from);
- size_t to_addr = NUM2SIZET(to);
-
- // Call cs_disasm and convert results to a Ruby array
- cs_insn *insns;
- size_t base_addr = RTEST(test) ? 0 : from_addr; // On tests, start from 0 for output stability.
- size_t count = cs_disasm(handle, (const uint8_t *)from_addr, to_addr - from_addr, base_addr, 0, &insns);
- for (size_t i = 0; i < count; i++) {
- VALUE vals = rb_ary_new_from_args(3, LONG2NUM(insns[i].address), rb_str_new2(insns[i].mnemonic), rb_str_new2(insns[i].op_str));
- rb_ary_push(result, vals);
- }
-
- // Free memory used by capstone
- cs_free(insns, count);
- cs_close(&handle);
-#endif
- return result;
-}
-
-// Same as `RubyVM::RJIT.enabled?`, but this is used before it's defined.
-static VALUE
-rjit_enabled_p(rb_execution_context_t *ec, VALUE self)
-{
- return RBOOL(rb_rjit_enabled);
-}
-
-static int
-for_each_iseq_i(void *vstart, void *vend, size_t stride, void *data)
-{
- VALUE block = (VALUE)data;
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- void *ptr = asan_poisoned_object_p(v);
- asan_unpoison_object(v, false);
-
- if (rb_obj_is_iseq(v)) {
- extern VALUE rb_rjit_iseq_new(rb_iseq_t *iseq);
- rb_iseq_t *iseq = (rb_iseq_t *)v;
- rb_funcall(block, rb_intern("call"), 1, rb_rjit_iseq_new(iseq));
- }
-
- asan_poison_object_if(ptr, v);
- }
- return 0;
-}
-
-static VALUE
-rjit_for_each_iseq(rb_execution_context_t *ec, VALUE self, VALUE block)
-{
- rb_objspace_each_objects(for_each_iseq_i, (void *)block);
- return Qnil;
-}
-
-// bindgen references
-extern ID rb_get_symbol_id(VALUE name);
-extern VALUE rb_fix_aref(VALUE fix, VALUE idx);
-extern VALUE rb_str_getbyte(VALUE str, VALUE index);
-extern VALUE rb_vm_concat_array(VALUE ary1, VALUE ary2st);
-extern VALUE rb_vm_get_ev_const(rb_execution_context_t *ec, VALUE orig_klass, ID id, VALUE allow_nil);
-extern VALUE rb_vm_getclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, ICVARC ic);
-extern VALUE rb_vm_opt_newarray_min(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr);
-extern VALUE rb_vm_opt_newarray_max(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr);
-extern VALUE rb_vm_opt_newarray_hash(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr);
-extern VALUE rb_vm_splat_array(VALUE flag, VALUE array);
-extern bool rb_simple_iseq_p(const rb_iseq_t *iseq);
-extern bool rb_vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE v);
-extern bool rb_vm_ic_hit_p(IC ic, const VALUE *reg_ep);
-extern rb_event_flag_t rb_rjit_global_events;
-extern void rb_vm_setinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, VALUE val, IVC ic);
-extern VALUE rb_vm_throw(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VALUE throwobj);
-extern VALUE rb_reg_new_ary(VALUE ary, int opt);
-extern void rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic);
-extern VALUE rb_str_bytesize(VALUE str);
-extern const rb_callable_method_entry_t *rb_callable_method_entry_or_negative(VALUE klass, ID mid);
-extern VALUE rb_vm_yield_with_cfunc(rb_execution_context_t *ec, const struct rb_captured_block *captured, int argc, const VALUE *argv);
-extern VALUE rb_vm_set_ivar_id(VALUE obj, ID id, VALUE val);
-extern VALUE rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary);
-extern void* rb_rjit_entry_stub_hit(VALUE branch_stub);
-extern void* rb_rjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p);
-extern uint64_t rb_vm_insns_count;
-
-#include "rjit_c.rbinc"
-
-#endif // USE_RJIT
diff --git a/rjit_c.h b/rjit_c.h
deleted file mode 100644
index 339dfc38fc..0000000000
--- a/rjit_c.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// This file is parsed by tool/rjit/generate.rb to generate rjit_c.rb
-#ifndef RJIT_C_H
-#define RJIT_C_H
-
-#include "ruby/internal/config.h"
-#include "internal/string.h"
-#include "internal/struct.h"
-#include "internal/variable.h"
-#include "vm_core.h"
-#include "vm_callinfo.h"
-#include "builtin.h"
-#include "ccan/list/list.h"
-#include "rjit.h"
-#include "shape.h"
-
-extern uint8_t *rb_rjit_mem_block;
-
-#define RJIT_RUNTIME_COUNTERS(...) struct rb_rjit_runtime_counters { size_t __VA_ARGS__; };
-RJIT_RUNTIME_COUNTERS(
- rjit_insns_count,
-
- send_args_splat_kw_splat,
- send_args_splat,
- send_args_splat_not_array,
- send_args_splat_length_not_equal,
- send_args_splat_cfunc_var_args,
- send_args_splat_arity_error,
- send_args_splat_ruby2_hash,
- send_args_splat_cfunc_zuper,
- send_args_splat_cfunc_ruby2_keywords,
- send_kw_splat,
- send_kwarg,
- send_klass_megamorphic,
- send_missing_cme,
- send_private,
- send_protected_check_failed,
- send_tailcall,
- send_notimplemented,
- send_missing,
- send_bmethod,
- send_alias,
- send_undef,
- send_zsuper,
- send_refined,
- send_stackoverflow,
- send_arity,
- send_c_tracing,
- send_is_a_class_mismatch,
- send_instance_of_class_mismatch,
- send_keywords,
-
- send_blockiseq,
- send_block_handler,
- send_block_setup,
- send_block_not_nil,
- send_block_not_proxy,
- send_block_arg,
-
- send_iseq_kwparam,
- send_iseq_accepts_no_kwarg,
- send_iseq_has_opt,
- send_iseq_has_kwrest,
- send_iseq_ruby2_keywords,
- send_iseq_has_rest_and_captured,
- send_iseq_has_rest_and_kw_supplied,
- send_iseq_has_no_kw,
- send_iseq_zsuper,
- send_iseq_materialized_block,
- send_iseq_has_rest,
- send_iseq_block_arg0_splat,
- send_iseq_kw_call,
- send_iseq_splat,
- send_iseq_has_rest_and_optional,
- send_iseq_arity_error,
- send_iseq_missing_optional_kw,
- send_iseq_too_many_kwargs,
- send_iseq_kwargs_mismatch,
- send_iseq_splat_with_kw,
- send_iseq_splat_arity_error,
- send_iseq_has_rest_and_splat_not_equal,
-
- send_cfunc_variadic,
- send_cfunc_too_many_args,
- send_cfunc_ruby_array_varg,
- send_cfunc_splat_with_kw,
- send_cfunc_tracing,
- send_cfunc_argc_mismatch,
- send_cfunc_toomany_args,
-
- send_attrset_splat,
- send_attrset_kwarg,
- send_attrset_method,
-
- send_ivar_splat,
- send_ivar_opt_send,
-
- send_optimized_send_no_args,
- send_optimized_send_not_sym_or_str,
- send_optimized_send_mid_class_changed,
- send_optimized_send_mid_id_changed,
- send_optimized_send_null_mid,
- send_optimized_send_send,
- send_optimized_call_block,
- send_optimized_call_kwarg,
- send_optimized_call_splat,
- send_optimized_struct_aref_error,
-
- send_optimized_block_call,
- send_optimized_struct_aset,
-
- send_bmethod_not_iseq,
- send_bmethod_blockarg,
-
- invokesuper_me_changed,
- invokesuper_block,
-
- invokeblock_none,
- invokeblock_symbol,
- invokeblock_proc,
- invokeblock_tag_changed,
- invokeblock_iseq_block_changed,
- invokeblock_iseq_arity,
- invokeblock_iseq_arg0_splat,
- invokeblock_ifunc_args_splat,
- invokeblock_ifunc_kw_splat,
- invokeblock_iseq_arg0_args_splat,
- invokeblock_iseq_arg0_has_kw,
-
- getivar_megamorphic,
- getivar_not_heap,
- getivar_special_const,
- getivar_too_complex,
-
- optaref_arg_not_fixnum,
- optaref_argc_not_one,
- optaref_recv_not_array,
- optaref_recv_not_hash,
- optaref_send,
-
- optgetconst_not_cached,
- optgetconst_cref,
- optgetconst_cache_miss,
-
- setivar_frozen,
- setivar_not_heap,
- setivar_megamorphic,
- setivar_too_complex,
-
- expandarray_splat,
- expandarray_postarg,
- expandarray_not_array,
- expandarray_rhs_too_small,
-
- getblockpp_block_param_modified,
- getblockpp_block_handler_none,
- getblockpp_not_gc_guarded,
- getblockpp_not_iseq_block,
-
- compiled_block_count
-)
-#undef RJIT_RUNTIME_COUNTERS
-extern struct rb_rjit_runtime_counters rb_rjit_counters;
-
-#endif /* RJIT_C_H */
diff --git a/rjit_c.rb b/rjit_c.rb
deleted file mode 100644
index 30a84abaa5..0000000000
--- a/rjit_c.rb
+++ /dev/null
@@ -1,1695 +0,0 @@
-# frozen_string_literal: true
-# Part of this file is generated by tool/rjit/bindgen.rb.
-# Run `make rjit-bindgen` to update code between "RJIT bindgen begin" and "RJIT bindgen end".
-module RubyVM::RJIT # :nodoc: all
- #
- # Main: Used by RJIT
- #
- # This `class << C` section is for calling C functions with Primitive.
- # For importing variables or macros, use tool/rjit/bindgen.rb instead.
- class << C = Module.new
- def mmap(mem_size)
- Primitive.cexpr! 'SIZET2NUM((size_t)rjit_reserve_addr_space(NUM2UINT(mem_size)))'
- end
-
- def mprotect_write(mem_block, mem_size)
- Primitive.mprotect_write(mem_block, mem_size)
- end
-
- def mprotect_exec(mem_block, mem_size)
- Primitive.mprotect_exec(mem_block, mem_size)
- end
-
- def rjit_insn_exits
- addr = Primitive.cexpr! 'SIZET2NUM((size_t)rjit_insn_exits)'
- CType::Immediate.parse("size_t").new(addr)
- end
-
- def rb_rjit_counters
- addr = Primitive.cexpr! 'SIZET2NUM((size_t)&rb_rjit_counters)'
- rb_rjit_runtime_counters.new(addr)
- end
-
- # @param from [Integer] - From address
- # @param to [Integer] - To address
- def dump_disasm(from, to, test: false)
- Primitive.dump_disasm(from, to, test)
- end
-
- # Convert a Ruby object to a VALUE in Integer
- def to_value(obj)
- Primitive.cexpr! 'SIZET2NUM((size_t)obj)'
- end
-
- def BASIC_OP_UNREDEFINED_P(op, klass)
- Primitive.cexpr! 'RBOOL(BASIC_OP_UNREDEFINED_P(NUM2INT(op), NUM2INT(klass)))'
- end
-
- def rb_iseq_line_no(iseq, pos)
- _iseq_addr = iseq.to_i
- Primitive.cexpr! 'UINT2NUM(rb_iseq_line_no((const rb_iseq_t *)NUM2SIZET(_iseq_addr), NUM2SIZET(pos)))'
- end
-
- def rb_class_of(obj)
- Primitive.cexpr! 'rb_class_of(obj)'
- end
-
- def rb_callable_method_entry(klass, mid)
- cme_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_callable_method_entry(klass, NUM2UINT(mid)))'
- return nil if cme_addr == 0
- rb_callable_method_entry_t.new(cme_addr)
- end
-
- def METHOD_ENTRY_VISI(cme)
- _cme_addr = cme.to_i
- Primitive.cexpr! 'UINT2NUM(METHOD_ENTRY_VISI((const rb_callable_method_entry_t *)NUM2SIZET(_cme_addr)))'
- end
-
- def rb_simple_iseq_p(iseq)
- _iseq_addr = iseq.to_i
- Primitive.cexpr! 'RBOOL(rb_simple_iseq_p((rb_iseq_t *)NUM2SIZET(_iseq_addr)))'
- end
-
- def SPECIAL_CONST_P(obj)
- _value = to_value(obj)
- Primitive.cexpr! 'RBOOL(SPECIAL_CONST_P((VALUE)NUM2SIZET(_value)))'
- end
-
- def BUILTIN_TYPE(obj)
- _value = to_value(obj)
- Primitive.cexpr! 'INT2NUM(BUILTIN_TYPE((VALUE)NUM2SIZET(_value)))'
- end
-
- def RB_TYPE_P(obj, type)
- Primitive.cexpr! 'RBOOL(RB_TYPE_P(obj, NUM2UINT(type)))'
- end
-
- def rb_shape_get_shape_id(obj)
- _value = to_value(obj)
- Primitive.cexpr! 'UINT2NUM((unsigned int)rb_shape_get_shape_id((VALUE)NUM2SIZET(_value)))'
- end
-
- def rb_shape_id_offset
- Primitive.cexpr! 'INT2NUM(rb_shape_id_offset())'
- end
-
- def rb_shape_get_iv_index(shape_id, ivar_id)
- Primitive.cstmt! %{
- rb_shape_t *shape = rb_shape_get_shape_by_id((shape_id_t)NUM2SIZET(shape_id));
- attr_index_t index;
- bool found = rb_shape_get_iv_index(shape, (ID)NUM2SIZET(ivar_id), &index);
- return found ? UINT2NUM(index) : Qnil;
- }
- end
-
- def FL_TEST_RAW(obj, flags)
- Primitive.cexpr! 'RBOOL(FL_TEST_RAW(obj, (VALUE)NUM2SIZET(flags)))'
- end
-
- def FL_TEST(obj, flags)
- Primitive.cexpr! 'RBOOL(FL_TEST(obj, (VALUE)NUM2SIZET(flags)))'
- end
-
- def rjit_for_each_iseq(&block)
- Primitive.rjit_for_each_iseq(block)
- end
-
- def get_symbol_id(name)
- Primitive.cexpr! 'SIZET2NUM((size_t)rb_get_symbol_id(name))'
- end
-
- def rb_vm_frame_method_entry(cfp)
- _cfp = cfp.to_i
- cme_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_vm_frame_method_entry((const rb_control_frame_t *)NUM2SIZET(_cfp)))'
- return nil if cme_addr == 0
- rb_callable_method_entry_t.new(cme_addr)
- end
-
- def rb_class_get_superclass(klass)
- Primitive.cexpr! 'rb_class_get_superclass(klass)'
- end
-
- def ID2SYM(id)
- Primitive.cexpr! 'ID2SYM((ID)NUM2SIZET(id))'
- end
-
- def obj_is_kind_of(obj, c)
- Primitive.cexpr! 'rb_obj_is_kind_of(obj, c)'
- end
-
- def imemo_type_p(ptr, type)
- _ptr = ptr.to_i
- Primitive.cexpr! 'RBOOL(imemo_type_p((VALUE)NUM2SIZET(_ptr), NUM2UINT(type)))'
- end
-
- def rb_iseq_only_optparam_p(iseq)
- _iseq = iseq.to_i
- Primitive.cstmt! %{
- extern bool rb_iseq_only_optparam_p(const rb_iseq_t *iseq);
- return RBOOL(rb_iseq_only_optparam_p((rb_iseq_t *)NUM2SIZET(_iseq)));
- }
- end
-
- def rb_iseq_only_kwparam_p(iseq)
- _iseq = iseq.to_i
- Primitive.cstmt! %{
- extern bool rb_iseq_only_kwparam_p(const rb_iseq_t *iseq);
- return RBOOL(rb_iseq_only_kwparam_p((rb_iseq_t *)NUM2SIZET(_iseq)));
- }
- end
-
- def rb_obj_frozen_p(obj)
- Primitive.cexpr! 'rb_obj_frozen_p(obj)'
- end
-
- def rb_intern(str)
- Primitive.cexpr! 'SIZET2NUM((size_t)rb_intern(RSTRING_PTR(str)))'
- end
-
- def rb_method_entry_at(klass, mid)
- me_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_method_entry_at(klass, (ID)NUM2SIZET(mid)))'
- me_addr == 0 ? nil : rb_method_entry_t.new(me_addr)
- end
-
- def rb_shape_get_next_no_warnings(shape, obj, id)
- _shape = shape.to_i
- shape_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_shape_get_next_no_warnings((rb_shape_t *)NUM2SIZET(_shape), obj, (ID)NUM2SIZET(id)))'
- rb_shape_t.new(shape_addr)
- end
-
- def rb_shape_id(shape)
- _shape = shape.to_i
- Primitive.cexpr! 'SIZET2NUM((size_t)rb_shape_id((rb_shape_t *)NUM2SIZET(_shape)))'
- end
-
- def rb_class_attached_object(klass)
- Primitive.cexpr! 'rb_class_attached_object(klass)'
- end
-
- def rb_singleton_class(obj)
- Primitive.cexpr! 'rb_singleton_class(obj)'
- end
-
- def rb_aliased_callable_method_entry(cme)
- _cme = cme.to_i
- cme_addr = Primitive.cstmt! %{
- extern const rb_callable_method_entry_t * rb_aliased_callable_method_entry(const rb_callable_method_entry_t *me);
- return SIZET2NUM((size_t)rb_aliased_callable_method_entry((const rb_callable_method_entry_t *)NUM2SIZET(_cme)));
- }
- rb_callable_method_entry_t.new(cme_addr)
- end
-
- def rb_yjit_get_proc_ptr(proc_addr)
- proc_t_addr = Primitive.cstmt! %{
- extern rb_proc_t * rjit_get_proc_ptr(VALUE procv);
- return SIZET2NUM((size_t)rjit_get_proc_ptr((VALUE)NUM2SIZET(proc_addr)));
- }
- rb_proc_t.new(proc_t_addr)
- end
-
- def rb_shape_get_shape_by_id(shape_id)
- _shape_id = shape_id.to_i
- shape_addr = Primitive.cexpr! 'SIZET2NUM((VALUE)rb_shape_get_shape_by_id((shape_id_t)NUM2UINT(_shape_id)))'
- rb_shape_t.new(shape_addr)
- end
-
- def rb_iseq_check(iseq)
- _iseq_addr = iseq.to_i
- iseq_addr = Primitive.cexpr! 'SIZET2NUM((VALUE)rb_iseq_check((rb_iseq_t *)NUM2SIZET(_iseq_addr)))'
- rb_iseq_t.new(iseq_addr)
- end
-
- def rb_iseq_path(iseq)
- _iseq_addr = iseq.to_i
- Primitive.cexpr! 'rb_iseq_path((rb_iseq_t *)NUM2SIZET(_iseq_addr))'
- end
-
- def vm_ci_argc(ci)
- _ci_addr = ci.to_i
- Primitive.cexpr! 'UINT2NUM(vm_ci_argc((CALL_INFO)NUM2SIZET(_ci_addr)))'
- end
-
- def vm_ci_flag(ci)
- _ci_addr = ci.to_i
- Primitive.cexpr! 'UINT2NUM(vm_ci_flag((CALL_INFO)NUM2SIZET(_ci_addr)))'
- end
-
- def vm_ci_kwarg(ci)
- _ci_addr = ci.to_i
- kwarg_addr = Primitive.cexpr! 'SIZET2NUM((size_t)vm_ci_kwarg((CALL_INFO)NUM2SIZET(_ci_addr)))'
- kwarg_addr == 0 ? nil : rb_callinfo_kwarg.new(kwarg_addr)
- end
-
- def vm_ci_mid(ci)
- _ci_addr = ci.to_i
- Primitive.cexpr! 'SIZET2NUM((size_t)vm_ci_mid((CALL_INFO)NUM2SIZET(_ci_addr)))'
- end
-
- def rjit_opts
- addr = Primitive.cexpr! 'SIZET2NUM((VALUE)&rb_rjit_opts)'
- rb_rjit_options.new(addr)
- end
-
- def rjit_cancel_all(reason)
- Primitive.cstmt! %{
- rb_rjit_cancel_all(RSTRING_PTR(reason));
- return Qnil;
- }
- end
-
- # Convert an encoded VM pointer to an insn BIN.
- def rb_vm_insn_decode(encoded)
- # Using rb_vm_insn_addr2opcode to return trace_ insns
- Primitive.cexpr! 'INT2NUM(rb_vm_insn_addr2opcode((void *)NUM2SIZET(encoded)))'
- end
-
- # Convert Integer VALUE to an actual Ruby object
- def to_ruby(value)
- Primitive.cexpr! '(VALUE)NUM2SIZET(value)'
- end
-
- def HAVE_LIBCAPSTONE
- Primitive.cstmt! %{
- #ifdef HAVE_LIBCAPSTONE
- return Qtrue;
- #else
- return Qfalse;
- #endif
- }
- end
-
- def rjit_exit_traces
- Primitive.cexpr! 'rjit_exit_traces()'
- end
-
- def rb_vm_ep_local_ep(ep)
- _ep = ep.to_i
- lep_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_vm_ep_local_ep((const VALUE *)NUM2SIZET(_ep)))'
- C.VALUE.new(lep_addr)
- end
-
- def rb_hash_keys(hash)
- Primitive.cexpr! 'rb_hash_keys(hash)'
- end
-
- def rb_hash_stlike_lookup(hash, key)
- Primitive.cstmt! %{
- VALUE result = Qnil;
- rb_hash_stlike_lookup(hash, key, &result);
- return result;
- }
- end
-
- def rb_obj_class(obj)
- Primitive.cexpr! 'rb_obj_class(obj)'
- end
-
- def rb_sym2id(sym)
- Primitive.cexpr! 'SIZET2NUM((size_t)rb_sym2id(sym))'
- end
-
- def rb_callable_method_entry_or_negative(klass, mid)
- cme_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_callable_method_entry_or_negative(klass, (ID)NUM2SIZET(mid)))'
- return nil if cme_addr == 0
- rb_callable_method_entry_t.new(cme_addr)
- end
-
- def rb_method_basic_definition_p(klass, mid)
- Primitive.cexpr! 'RBOOL(rb_method_basic_definition_p(klass, (ID)NUM2SIZET(mid)))'
- end
-
- def UNDEFINED_METHOD_ENTRY_P(cme)
- _cme_addr = cme.to_i
- Primitive.cexpr! 'RBOOL(UNDEFINED_METHOD_ENTRY_P((const rb_callable_method_entry_t *)NUM2SIZET(_cme_addr)))'
- end
-
- def RCLASS_ORIGIN(klass)
- Primitive.cexpr! 'RCLASS_ORIGIN(klass)'
- end
- end
-
- #
- # Utilities: Not used by RJIT, but useful for debugging
- #
- class << C
- # Convert insn BINs to encoded VM pointers.
- def rb_vm_insn_encode(bin)
- Primitive.cexpr! 'SIZET2NUM((VALUE)rb_vm_get_insns_address_table()[NUM2INT(bin)])'
- end
-
- # Convert RubyVM::InstructionSequence to C.rb_iseq_t.
- def rb_iseqw_to_iseq(iseqw)
- iseq_addr = Primitive.cexpr! 'SIZET2NUM((VALUE)rb_iseqw_to_iseq(iseqw))'
- rb_iseq_t.new(iseq_addr)
- end
- end
-
- ### RJIT bindgen begin ###
-
- C::UNLIMITED_ARGUMENTS = Primitive.cexpr! %q{ LONG2NUM(UNLIMITED_ARGUMENTS) }
- C::VM_ENV_DATA_INDEX_ME_CREF = Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_ME_CREF) }
- C::VM_ENV_DATA_INDEX_SPECVAL = Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_SPECVAL) }
- C::ARRAY_REDEFINED_OP_FLAG = Primitive.cexpr! %q{ SIZET2NUM(ARRAY_REDEFINED_OP_FLAG) }
- C::BOP_AND = Primitive.cexpr! %q{ SIZET2NUM(BOP_AND) }
- C::BOP_AREF = Primitive.cexpr! %q{ SIZET2NUM(BOP_AREF) }
- C::BOP_EQ = Primitive.cexpr! %q{ SIZET2NUM(BOP_EQ) }
- C::BOP_EQQ = Primitive.cexpr! %q{ SIZET2NUM(BOP_EQQ) }
- C::BOP_FREEZE = Primitive.cexpr! %q{ SIZET2NUM(BOP_FREEZE) }
- C::BOP_GE = Primitive.cexpr! %q{ SIZET2NUM(BOP_GE) }
- C::BOP_GT = Primitive.cexpr! %q{ SIZET2NUM(BOP_GT) }
- C::BOP_LE = Primitive.cexpr! %q{ SIZET2NUM(BOP_LE) }
- C::BOP_LT = Primitive.cexpr! %q{ SIZET2NUM(BOP_LT) }
- C::BOP_MINUS = Primitive.cexpr! %q{ SIZET2NUM(BOP_MINUS) }
- C::BOP_MOD = Primitive.cexpr! %q{ SIZET2NUM(BOP_MOD) }
- C::BOP_OR = Primitive.cexpr! %q{ SIZET2NUM(BOP_OR) }
- C::BOP_PLUS = Primitive.cexpr! %q{ SIZET2NUM(BOP_PLUS) }
- C::BUILTIN_ATTR_LEAF = Primitive.cexpr! %q{ SIZET2NUM(BUILTIN_ATTR_LEAF) }
- C::BUILTIN_ATTR_NO_GC = Primitive.cexpr! %q{ SIZET2NUM(BUILTIN_ATTR_NO_GC) }
- C::HASH_REDEFINED_OP_FLAG = Primitive.cexpr! %q{ SIZET2NUM(HASH_REDEFINED_OP_FLAG) }
- C::INTEGER_REDEFINED_OP_FLAG = Primitive.cexpr! %q{ SIZET2NUM(INTEGER_REDEFINED_OP_FLAG) }
- C::INVALID_SHAPE_ID = Primitive.cexpr! %q{ SIZET2NUM(INVALID_SHAPE_ID) }
- C::METHOD_VISI_PRIVATE = Primitive.cexpr! %q{ SIZET2NUM(METHOD_VISI_PRIVATE) }
- C::METHOD_VISI_PROTECTED = Primitive.cexpr! %q{ SIZET2NUM(METHOD_VISI_PROTECTED) }
- C::METHOD_VISI_PUBLIC = Primitive.cexpr! %q{ SIZET2NUM(METHOD_VISI_PUBLIC) }
- C::METHOD_VISI_UNDEF = Primitive.cexpr! %q{ SIZET2NUM(METHOD_VISI_UNDEF) }
- C::OBJ_TOO_COMPLEX_SHAPE_ID = Primitive.cexpr! %q{ SIZET2NUM(OBJ_TOO_COMPLEX_SHAPE_ID) }
- C::OPTIMIZED_METHOD_TYPE_BLOCK_CALL = Primitive.cexpr! %q{ SIZET2NUM(OPTIMIZED_METHOD_TYPE_BLOCK_CALL) }
- C::OPTIMIZED_METHOD_TYPE_CALL = Primitive.cexpr! %q{ SIZET2NUM(OPTIMIZED_METHOD_TYPE_CALL) }
- C::OPTIMIZED_METHOD_TYPE_SEND = Primitive.cexpr! %q{ SIZET2NUM(OPTIMIZED_METHOD_TYPE_SEND) }
- C::OPTIMIZED_METHOD_TYPE_STRUCT_AREF = Primitive.cexpr! %q{ SIZET2NUM(OPTIMIZED_METHOD_TYPE_STRUCT_AREF) }
- C::OPTIMIZED_METHOD_TYPE_STRUCT_ASET = Primitive.cexpr! %q{ SIZET2NUM(OPTIMIZED_METHOD_TYPE_STRUCT_ASET) }
- C::RARRAY_EMBED_FLAG = Primitive.cexpr! %q{ SIZET2NUM(RARRAY_EMBED_FLAG) }
- C::RARRAY_EMBED_LEN_MASK = Primitive.cexpr! %q{ SIZET2NUM(RARRAY_EMBED_LEN_MASK) }
- C::RARRAY_EMBED_LEN_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(RARRAY_EMBED_LEN_SHIFT) }
- C::RHASH_PASS_AS_KEYWORDS = Primitive.cexpr! %q{ SIZET2NUM(RHASH_PASS_AS_KEYWORDS) }
- C::RMODULE_IS_REFINEMENT = Primitive.cexpr! %q{ SIZET2NUM(RMODULE_IS_REFINEMENT) }
- C::ROBJECT_EMBED = Primitive.cexpr! %q{ SIZET2NUM(ROBJECT_EMBED) }
- C::RSTRUCT_EMBED_LEN_MASK = Primitive.cexpr! %q{ SIZET2NUM(RSTRUCT_EMBED_LEN_MASK) }
- C::RUBY_ENCODING_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_ENCODING_MASK) }
- C::RUBY_EVENT_CLASS = Primitive.cexpr! %q{ SIZET2NUM(RUBY_EVENT_CLASS) }
- C::RUBY_EVENT_C_CALL = Primitive.cexpr! %q{ SIZET2NUM(RUBY_EVENT_C_CALL) }
- C::RUBY_EVENT_C_RETURN = Primitive.cexpr! %q{ SIZET2NUM(RUBY_EVENT_C_RETURN) }
- C::RUBY_FIXNUM_FLAG = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FIXNUM_FLAG) }
- C::RUBY_FLONUM_FLAG = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FLONUM_FLAG) }
- C::RUBY_FLONUM_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FLONUM_MASK) }
- C::RUBY_FL_FREEZE = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FL_FREEZE) }
- C::RUBY_FL_SINGLETON = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FL_SINGLETON) }
- C::RUBY_IMMEDIATE_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_IMMEDIATE_MASK) }
- C::RUBY_SPECIAL_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(RUBY_SPECIAL_SHIFT) }
- C::RUBY_SYMBOL_FLAG = Primitive.cexpr! %q{ SIZET2NUM(RUBY_SYMBOL_FLAG) }
- C::RUBY_T_ARRAY = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_ARRAY) }
- C::RUBY_T_CLASS = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_CLASS) }
- C::RUBY_T_HASH = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_HASH) }
- C::RUBY_T_ICLASS = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_ICLASS) }
- C::RUBY_T_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_MASK) }
- C::RUBY_T_MODULE = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_MODULE) }
- C::RUBY_T_OBJECT = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_OBJECT) }
- C::RUBY_T_STRING = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_STRING) }
- C::RUBY_T_SYMBOL = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_SYMBOL) }
- C::SHAPE_FLAG_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FLAG_SHIFT) }
- C::SHAPE_FROZEN = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FROZEN) }
- C::SHAPE_ID_NUM_BITS = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_ID_NUM_BITS) }
- C::SHAPE_IVAR = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_IVAR) }
- C::SHAPE_MASK = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_MASK) }
- C::SHAPE_ROOT = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_ROOT) }
- C::STRING_REDEFINED_OP_FLAG = Primitive.cexpr! %q{ SIZET2NUM(STRING_REDEFINED_OP_FLAG) }
- C::T_OBJECT = Primitive.cexpr! %q{ SIZET2NUM(T_OBJECT) }
- C::VM_BLOCK_HANDLER_NONE = Primitive.cexpr! %q{ SIZET2NUM(VM_BLOCK_HANDLER_NONE) }
- C::VM_CALL_ARGS_BLOCKARG = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_ARGS_BLOCKARG) }
- C::VM_CALL_ARGS_SPLAT = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_ARGS_SPLAT) }
- C::VM_CALL_FCALL = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_FCALL) }
- C::VM_CALL_KWARG = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KWARG) }
- C::VM_CALL_KW_SPLAT = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KW_SPLAT) }
- C::VM_CALL_KW_SPLAT_MUT = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KW_SPLAT_MUT) }
- C::VM_CALL_KW_SPLAT_bit = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KW_SPLAT_bit) }
- C::VM_CALL_OPT_SEND = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_OPT_SEND) }
- C::VM_CALL_TAILCALL = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_TAILCALL) }
- C::VM_CALL_TAILCALL_bit = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_TAILCALL_bit) }
- C::VM_CALL_ZSUPER = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_ZSUPER) }
- C::VM_ENV_DATA_INDEX_FLAGS = Primitive.cexpr! %q{ SIZET2NUM(VM_ENV_DATA_INDEX_FLAGS) }
- C::VM_ENV_DATA_SIZE = Primitive.cexpr! %q{ SIZET2NUM(VM_ENV_DATA_SIZE) }
- C::VM_ENV_FLAG_LOCAL = Primitive.cexpr! %q{ SIZET2NUM(VM_ENV_FLAG_LOCAL) }
- C::VM_ENV_FLAG_WB_REQUIRED = Primitive.cexpr! %q{ SIZET2NUM(VM_ENV_FLAG_WB_REQUIRED) }
- C::VM_FRAME_FLAG_BMETHOD = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_FLAG_BMETHOD) }
- C::VM_FRAME_FLAG_CFRAME = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_FLAG_CFRAME) }
- C::VM_FRAME_FLAG_CFRAME_KW = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_FLAG_CFRAME_KW) }
- C::VM_FRAME_FLAG_LAMBDA = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_FLAG_LAMBDA) }
- C::VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM) }
- C::VM_FRAME_MAGIC_BLOCK = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_MAGIC_BLOCK) }
- C::VM_FRAME_MAGIC_CFUNC = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_MAGIC_CFUNC) }
- C::VM_FRAME_MAGIC_METHOD = Primitive.cexpr! %q{ SIZET2NUM(VM_FRAME_MAGIC_METHOD) }
- C::VM_METHOD_TYPE_ALIAS = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_ALIAS) }
- C::VM_METHOD_TYPE_ATTRSET = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_ATTRSET) }
- C::VM_METHOD_TYPE_BMETHOD = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_BMETHOD) }
- C::VM_METHOD_TYPE_CFUNC = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_CFUNC) }
- C::VM_METHOD_TYPE_ISEQ = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_ISEQ) }
- C::VM_METHOD_TYPE_IVAR = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_IVAR) }
- C::VM_METHOD_TYPE_MISSING = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_MISSING) }
- C::VM_METHOD_TYPE_NOTIMPLEMENTED = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_NOTIMPLEMENTED) }
- C::VM_METHOD_TYPE_OPTIMIZED = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_OPTIMIZED) }
- C::VM_METHOD_TYPE_REFINED = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_REFINED) }
- C::VM_METHOD_TYPE_UNDEF = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_UNDEF) }
- C::VM_METHOD_TYPE_ZSUPER = Primitive.cexpr! %q{ SIZET2NUM(VM_METHOD_TYPE_ZSUPER) }
- C::VM_SPECIAL_OBJECT_VMCORE = Primitive.cexpr! %q{ SIZET2NUM(VM_SPECIAL_OBJECT_VMCORE) }
-
- def C.block_type_iseq
- Primitive.cexpr! %q{ SIZET2NUM(block_type_iseq) }
- end
-
- def C.idRespond_to_missing
- Primitive.cexpr! %q{ SIZET2NUM(idRespond_to_missing) }
- end
-
- def C.imemo_callinfo
- Primitive.cexpr! %q{ SIZET2NUM(imemo_callinfo) }
- end
-
- def C.imemo_iseq
- Primitive.cexpr! %q{ SIZET2NUM(imemo_iseq) }
- end
-
- def C.rb_block_param_proxy
- Primitive.cexpr! %q{ SIZET2NUM(rb_block_param_proxy) }
- end
-
- def C.rb_cArray
- Primitive.cexpr! %q{ SIZET2NUM(rb_cArray) }
- end
-
- def C.rb_cFalseClass
- Primitive.cexpr! %q{ SIZET2NUM(rb_cFalseClass) }
- end
-
- def C.rb_cFloat
- Primitive.cexpr! %q{ SIZET2NUM(rb_cFloat) }
- end
-
- def C.rb_cInteger
- Primitive.cexpr! %q{ SIZET2NUM(rb_cInteger) }
- end
-
- def C.rb_cNilClass
- Primitive.cexpr! %q{ SIZET2NUM(rb_cNilClass) }
- end
-
- def C.rb_cString
- Primitive.cexpr! %q{ SIZET2NUM(rb_cString) }
- end
-
- def C.rb_cSymbol
- Primitive.cexpr! %q{ SIZET2NUM(rb_cSymbol) }
- end
-
- def C.rb_cTrueClass
- Primitive.cexpr! %q{ SIZET2NUM(rb_cTrueClass) }
- end
-
- def C.rb_mRubyVMFrozenCore
- Primitive.cexpr! %q{ SIZET2NUM(rb_mRubyVMFrozenCore) }
- end
-
- def C.rb_rjit_global_events
- Primitive.cexpr! %q{ SIZET2NUM(rb_rjit_global_events) }
- end
-
- def C.rb_vm_insns_count
- Primitive.cexpr! %q{ SIZET2NUM(rb_vm_insns_count) }
- end
-
- def C.rb_ary_clear
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_clear) }
- end
-
- def C.rb_ary_dup
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_dup) }
- end
-
- def C.rb_ary_entry_internal
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_entry_internal) }
- end
-
- def C.rb_ary_push
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_push) }
- end
-
- def C.rb_ary_resurrect
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_resurrect) }
- end
-
- def C.rb_ary_store
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_store) }
- end
-
- def C.rb_ary_tmp_new_from_values
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_tmp_new_from_values) }
- end
-
- def C.rb_ary_unshift_m
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_unshift_m) }
- end
-
- def C.rb_backref_get
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_backref_get) }
- end
-
- def C.rb_ec_ary_new_from_values
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ec_ary_new_from_values) }
- end
-
- def C.rb_ec_str_resurrect
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ec_str_resurrect) }
- end
-
- def C.rb_ensure_iv_list_size
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ensure_iv_list_size) }
- end
-
- def C.rb_fix_aref
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_fix_aref) }
- end
-
- def C.rb_fix_div_fix
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_fix_div_fix) }
- end
-
- def C.rb_fix_mod_fix
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_fix_mod_fix) }
- end
-
- def C.rb_fix_mul_fix
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_fix_mul_fix) }
- end
-
- def C.rb_gc_writebarrier
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_gc_writebarrier) }
- end
-
- def C.rb_get_symbol_id
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_get_symbol_id) }
- end
-
- def C.rb_gvar_get
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_gvar_get) }
- end
-
- def C.rb_hash_aref
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_hash_aref) }
- end
-
- def C.rb_hash_aset
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_hash_aset) }
- end
-
- def C.rb_hash_bulk_insert
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_hash_bulk_insert) }
- end
-
- def C.rb_hash_new
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_hash_new) }
- end
-
- def C.rb_hash_new_with_size
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_hash_new_with_size) }
- end
-
- def C.rb_hash_resurrect
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_hash_resurrect) }
- end
-
- def C.rb_ivar_defined
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ivar_defined) }
- end
-
- def C.rb_ivar_get
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ivar_get) }
- end
-
- def C.rb_obj_as_string_result
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_obj_as_string_result) }
- end
-
- def C.rb_obj_is_kind_of
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_obj_is_kind_of) }
- end
-
- def C.rb_range_new
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_range_new) }
- end
-
- def C.rb_reg_last_match
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_last_match) }
- end
-
- def C.rb_reg_match_last
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_last) }
- end
-
- def C.rb_reg_match_post
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_post) }
- end
-
- def C.rb_reg_match_pre
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_pre) }
- end
-
- def C.rb_reg_new_ary
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_new_ary) }
- end
-
- def C.rb_reg_nth_match
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_nth_match) }
- end
-
- def C.rb_rjit_branch_stub_hit
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_rjit_branch_stub_hit) }
- end
-
- def C.rb_rjit_entry_stub_hit
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_rjit_entry_stub_hit) }
- end
-
- def C.rb_str_buf_append
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_buf_append) }
- end
-
- def C.rb_str_bytesize
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_bytesize) }
- end
-
- def C.rb_str_concat_literals
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_concat_literals) }
- end
-
- def C.rb_str_dup
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_dup) }
- end
-
- def C.rb_str_eql_internal
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_eql_internal) }
- end
-
- def C.rb_str_getbyte
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_getbyte) }
- end
-
- def C.rb_str_intern
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_str_intern) }
- end
-
- def C.rb_sym_to_proc
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_sym_to_proc) }
- end
-
- def C.rb_vm_bh_to_procval
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_bh_to_procval) }
- end
-
- def C.rb_vm_concat_array
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_concat_array) }
- end
-
- def C.rb_vm_defined
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_defined) }
- end
-
- def C.rb_vm_get_ev_const
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_get_ev_const) }
- end
-
- def C.rb_vm_getclassvariable
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_getclassvariable) }
- end
-
- def C.rb_vm_ic_hit_p
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_ic_hit_p) }
- end
-
- def C.rb_vm_opt_newarray_hash
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_opt_newarray_hash) }
- end
-
- def C.rb_vm_opt_newarray_max
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_opt_newarray_max) }
- end
-
- def C.rb_vm_opt_newarray_min
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_opt_newarray_min) }
- end
-
- def C.rb_vm_set_ivar_id
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_set_ivar_id) }
- end
-
- def C.rb_vm_setclassvariable
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_setclassvariable) }
- end
-
- def C.rb_vm_setinstancevariable
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_setinstancevariable) }
- end
-
- def C.rb_vm_splat_array
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_splat_array) }
- end
-
- def C.rb_vm_throw
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_throw) }
- end
-
- def C.rb_vm_yield_with_cfunc
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_yield_with_cfunc) }
- end
-
- def C.rjit_build_kwhash
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_build_kwhash) }
- end
-
- def C.rjit_full_cfunc_return
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_full_cfunc_return) }
- end
-
- def C.rjit_optimized_call
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_optimized_call) }
- end
-
- def C.rjit_rb_ary_subseq_length
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_rb_ary_subseq_length) }
- end
-
- def C.rjit_record_exit_stack
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_record_exit_stack) }
- end
-
- def C.rjit_str_neq_internal
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_str_neq_internal) }
- end
-
- def C.rjit_str_simple_append
- Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_str_simple_append) }
- end
-
- def C.CALL_DATA
- @CALL_DATA ||= self.rb_call_data
- end
-
- def C.IC
- @IC ||= self.iseq_inline_constant_cache
- end
-
- def C.ID
- @ID ||= CType::Immediate.parse("unsigned long")
- end
-
- def C.IVC
- @IVC ||= self.iseq_inline_iv_cache_entry
- end
-
- def C.RArray
- @RArray ||= CType::Struct.new(
- "RArray", Primitive.cexpr!("SIZEOF(struct RArray)"),
- basic: [self.RBasic, Primitive.cexpr!("OFFSETOF((*((struct RArray *)NULL)), basic)")],
- as: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct RArray *)NULL)->as)"),
- heap: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct RArray *)NULL)->as.heap)"),
- len: [CType::Immediate.parse("long"), Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, len)")],
- aux: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct RArray *)NULL)->as.heap.aux)"),
- capa: CType::Immediate.parse("long"),
- shared_root: self.VALUE,
- ), Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, aux)")],
- ptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RArray *)NULL)->as.heap, ptr)")],
- ),
- ary: CType::Array.new { self.VALUE },
- ), Primitive.cexpr!("OFFSETOF((*((struct RArray *)NULL)), as)")],
- )
- end
-
- def C.RB_BUILTIN
- @RB_BUILTIN ||= self.rb_builtin_function
- end
-
- def C.RBasic
- @RBasic ||= CType::Struct.new(
- "RBasic", Primitive.cexpr!("SIZEOF(struct RBasic)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct RBasic *)NULL)), flags)")],
- klass: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct RBasic *)NULL)), klass)")],
- )
- end
-
- def C.RObject
- @RObject ||= CType::Struct.new(
- "RObject", Primitive.cexpr!("SIZEOF(struct RObject)"),
- basic: [self.RBasic, Primitive.cexpr!("OFFSETOF((*((struct RObject *)NULL)), basic)")],
- as: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct RObject *)NULL)->as)"),
- heap: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct RObject *)NULL)->as.heap)"),
- ivptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RObject *)NULL)->as.heap, ivptr)")],
- iv_index_tbl: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF(((struct RObject *)NULL)->as.heap, iv_index_tbl)")],
- ),
- ary: CType::Array.new { self.VALUE },
- ), Primitive.cexpr!("OFFSETOF((*((struct RObject *)NULL)), as)")],
- )
- end
-
- def C.RString
- @RString ||= CType::Struct.new(
- "RString", Primitive.cexpr!("SIZEOF(struct RString)"),
- basic: [self.RBasic, Primitive.cexpr!("OFFSETOF((*((struct RString *)NULL)), basic)")],
- len: [CType::Immediate.parse("long"), Primitive.cexpr!("OFFSETOF((*((struct RString *)NULL)), len)")],
- as: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as)"),
- heap: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.heap)"),
- ptr: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.heap, ptr)")],
- aux: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.heap.aux)"),
- capa: CType::Immediate.parse("long"),
- shared: self.VALUE,
- ), Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.heap, aux)")],
- ),
- embed: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.embed)"),
- ary: [CType::Array.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.embed, ary)")],
- ),
- ), Primitive.cexpr!("OFFSETOF((*((struct RString *)NULL)), as)")],
- )
- end
-
- def C.RStruct
- @RStruct ||= CType::Struct.new(
- "RStruct", Primitive.cexpr!("SIZEOF(struct RStruct)"),
- basic: [self.RBasic, Primitive.cexpr!("OFFSETOF((*((struct RStruct *)NULL)), basic)")],
- as: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct RStruct *)NULL)->as)"),
- heap: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct RStruct *)NULL)->as.heap)"),
- len: [CType::Immediate.parse("long"), Primitive.cexpr!("OFFSETOF(((struct RStruct *)NULL)->as.heap, len)")],
- ptr: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct RStruct *)NULL)->as.heap, ptr)")],
- ),
- ary: CType::Array.new { self.VALUE },
- ), Primitive.cexpr!("OFFSETOF((*((struct RStruct *)NULL)), as)")],
- )
- end
-
- def C.attr_index_t
- @attr_index_t ||= CType::Immediate.parse("uint32_t")
- end
-
- def C.iseq_inline_constant_cache
- @iseq_inline_constant_cache ||= CType::Struct.new(
- "iseq_inline_constant_cache", Primitive.cexpr!("SIZEOF(struct iseq_inline_constant_cache)"),
- entry: [CType::Pointer.new { self.iseq_inline_constant_cache_entry }, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache *)NULL)), entry)")],
- segments: [CType::Pointer.new { self.ID }, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache *)NULL)), segments)")],
- )
- end
-
- def C.iseq_inline_constant_cache_entry
- @iseq_inline_constant_cache_entry ||= CType::Struct.new(
- "iseq_inline_constant_cache_entry", Primitive.cexpr!("SIZEOF(struct iseq_inline_constant_cache_entry)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), flags)")],
- value: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), value)")],
- _unused1: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), _unused1)")],
- _unused2: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), _unused2)")],
- ic_cref: [CType::Pointer.new { self.rb_cref_t }, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_constant_cache_entry *)NULL)), ic_cref)")],
- )
- end
-
- def C.iseq_inline_iv_cache_entry
- @iseq_inline_iv_cache_entry ||= CType::Struct.new(
- "iseq_inline_iv_cache_entry", Primitive.cexpr!("SIZEOF(struct iseq_inline_iv_cache_entry)"),
- value: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_iv_cache_entry *)NULL)), value)")],
- iv_set_name: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_iv_cache_entry *)NULL)), iv_set_name)")],
- )
- end
-
- def C.iseq_inline_storage_entry
- @iseq_inline_storage_entry ||= CType::Union.new(
- "iseq_inline_storage_entry", Primitive.cexpr!("SIZEOF(union iseq_inline_storage_entry)"),
- once: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((union iseq_inline_storage_entry *)NULL)->once)"),
- running_thread: [CType::Pointer.new { self.rb_thread_struct }, Primitive.cexpr!("OFFSETOF(((union iseq_inline_storage_entry *)NULL)->once, running_thread)")],
- value: [self.VALUE, Primitive.cexpr!("OFFSETOF(((union iseq_inline_storage_entry *)NULL)->once, value)")],
- ),
- ic_cache: self.iseq_inline_constant_cache,
- iv_cache: self.iseq_inline_iv_cache_entry,
- )
- end
-
- def C.method_optimized_type
- @method_optimized_type ||= CType::Immediate.parse("int")
- end
-
- def C.rb_block
- @rb_block ||= CType::Struct.new(
- "rb_block", Primitive.cexpr!("SIZEOF(struct rb_block)"),
- as: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_block *)NULL)->as)"),
- captured: self.rb_captured_block,
- symbol: self.VALUE,
- proc: self.VALUE,
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_block *)NULL)), as)")],
- type: [self.rb_block_type, Primitive.cexpr!("OFFSETOF((*((struct rb_block *)NULL)), type)")],
- )
- end
-
- def C.rb_block_type
- @rb_block_type ||= CType::Immediate.parse("int")
- end
-
- def C.rb_builtin_function
- @rb_builtin_function ||= CType::Struct.new(
- "rb_builtin_function", Primitive.cexpr!("SIZEOF(struct rb_builtin_function)"),
- func_ptr: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), func_ptr)")],
- argc: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), argc)")],
- index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), index)")],
- name: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), name)")],
- )
- end
-
- def C.rb_call_data
- @rb_call_data ||= CType::Struct.new(
- "rb_call_data", Primitive.cexpr!("SIZEOF(struct rb_call_data)"),
- ci: [CType::Pointer.new { self.rb_callinfo }, Primitive.cexpr!("OFFSETOF((*((struct rb_call_data *)NULL)), ci)")],
- cc: [CType::Pointer.new { self.rb_callcache }, Primitive.cexpr!("OFFSETOF((*((struct rb_call_data *)NULL)), cc)")],
- )
- end
-
- def C.rb_callable_method_entry_struct
- @rb_callable_method_entry_struct ||= CType::Struct.new(
- "rb_callable_method_entry_struct", Primitive.cexpr!("SIZEOF(struct rb_callable_method_entry_struct)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), flags)")],
- defined_class: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), defined_class)"), true],
- def: [CType::Pointer.new { self.rb_method_definition_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), def)")],
- called_id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), called_id)")],
- owner: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), owner)")],
- )
- end
-
- def C.rb_callable_method_entry_t
- @rb_callable_method_entry_t ||= CType::Struct.new(
- "rb_callable_method_entry_struct", Primitive.cexpr!("SIZEOF(struct rb_callable_method_entry_struct)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), flags)")],
- defined_class: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), defined_class)"), true],
- def: [CType::Pointer.new { self.rb_method_definition_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), def)")],
- called_id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), called_id)")],
- owner: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callable_method_entry_struct *)NULL)), owner)")],
- )
- end
-
- def C.rb_callcache
- @rb_callcache ||= CType::Struct.new(
- "rb_callcache", Primitive.cexpr!("SIZEOF(struct rb_callcache)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), flags)")],
- klass: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), klass)")],
- cme_: [CType::Pointer.new { self.rb_callable_method_entry_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), cme_)")],
- call_: [self.vm_call_handler, Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), call_)")],
- aux_: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_callcache *)NULL)->aux_)"),
- attr: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_callcache *)NULL)->aux_.attr)"),
- value: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF(((struct rb_callcache *)NULL)->aux_.attr, value)")],
- ),
- method_missing_reason: self.method_missing_reason,
- v: self.VALUE,
- bf: CType::Pointer.new { self.rb_builtin_function },
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_callcache *)NULL)), aux_)")],
- )
- end
-
- def C.rb_callinfo
- @rb_callinfo ||= CType::Struct.new(
- "rb_callinfo", Primitive.cexpr!("SIZEOF(struct rb_callinfo)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), flags)")],
- kwarg: [CType::Pointer.new { self.rb_callinfo_kwarg }, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), kwarg)")],
- mid: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), mid)")],
- flag: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), flag)")],
- argc: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo *)NULL)), argc)")],
- )
- end
-
- def C.rb_callinfo_kwarg
- @rb_callinfo_kwarg ||= CType::Struct.new(
- "rb_callinfo_kwarg", Primitive.cexpr!("SIZEOF(struct rb_callinfo_kwarg)"),
- keyword_len: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo_kwarg *)NULL)), keyword_len)")],
- references: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo_kwarg *)NULL)), references)")],
- keywords: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo_kwarg *)NULL)), keywords)")],
- )
- end
-
- def C.rb_captured_block
- @rb_captured_block ||= CType::Struct.new(
- "rb_captured_block", Primitive.cexpr!("SIZEOF(struct rb_captured_block)"),
- self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_captured_block *)NULL)), self)")],
- ep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_captured_block *)NULL)), ep)")],
- code: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_captured_block *)NULL)->code)"),
- iseq: CType::Pointer.new { self.rb_iseq_t },
- ifunc: CType::Pointer.new { self.vm_ifunc },
- val: self.VALUE,
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_captured_block *)NULL)), code)")],
- )
- end
-
- def C.rb_control_frame_t
- @rb_control_frame_t ||= CType::Struct.new(
- "rb_control_frame_struct", Primitive.cexpr!("SIZEOF(struct rb_control_frame_struct)"),
- pc: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), pc)")],
- sp: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), sp)")],
- iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), iseq)")],
- self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), self)")],
- ep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), ep)")],
- block_code: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), block_code)")],
- jit_return: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), jit_return)")],
- )
- end
-
- def C.rb_cref_t
- @rb_cref_t ||= CType::Struct.new(
- "rb_cref_struct", Primitive.cexpr!("SIZEOF(struct rb_cref_struct)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), flags)")],
- refinements: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), refinements)")],
- klass_or_self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), klass_or_self)")],
- next: [CType::Pointer.new { self.rb_cref_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), next)")],
- scope_visi: [self.rb_scope_visibility_t, Primitive.cexpr!("OFFSETOF((*((struct rb_cref_struct *)NULL)), scope_visi)")],
- )
- end
-
- def C.rb_execution_context_struct
- @rb_execution_context_struct ||= CType::Struct.new(
- "rb_execution_context_struct", Primitive.cexpr!("SIZEOF(struct rb_execution_context_struct)"),
- vm_stack: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), vm_stack)")],
- vm_stack_size: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), vm_stack_size)")],
- cfp: [CType::Pointer.new { self.rb_control_frame_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), cfp)")],
- tag: [CType::Pointer.new { self.rb_vm_tag }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), tag)")],
- interrupt_flag: [self.rb_atomic_t, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), interrupt_flag)")],
- interrupt_mask: [self.rb_atomic_t, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), interrupt_mask)")],
- fiber_ptr: [CType::Pointer.new { self.rb_fiber_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), fiber_ptr)")],
- thread_ptr: [CType::Pointer.new { self.rb_thread_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), thread_ptr)")],
- local_storage: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), local_storage)")],
- local_storage_recursive_hash: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), local_storage_recursive_hash)")],
- local_storage_recursive_hash_for_trace: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), local_storage_recursive_hash_for_trace)")],
- storage: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), storage)")],
- root_lep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), root_lep)")],
- root_svar: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), root_svar)")],
- ensure_list: [CType::Pointer.new { self.rb_ensure_list_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), ensure_list)")],
- trace_arg: [CType::Pointer.new { self.rb_trace_arg_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), trace_arg)")],
- errinfo: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), errinfo)")],
- passed_block_handler: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), passed_block_handler)")],
- raised_flag: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), raised_flag)")],
- private_const_reference: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), private_const_reference)")],
- machine: [CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_execution_context_struct *)NULL)->machine)"),
- stack_start: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_start)")],
- stack_end: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_end)")],
- stack_maxsize: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF(((struct rb_execution_context_struct *)NULL)->machine, stack_maxsize)")],
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_execution_context_struct *)NULL)), machine)")],
- )
- end
-
- def C.rb_execution_context_t
- @rb_execution_context_t ||= self.rb_execution_context_struct
- end
-
- def C.rb_iseq_constant_body
- @rb_iseq_constant_body ||= CType::Struct.new(
- "rb_iseq_constant_body", Primitive.cexpr!("SIZEOF(struct rb_iseq_constant_body)"),
- type: [self.rb_iseq_type, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), type)")],
- iseq_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), iseq_size)")],
- iseq_encoded: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), iseq_encoded)")],
- param: [CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->param)"),
- flags: [CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->param.flags)"),
- has_lead: [CType::BitField.new(1, 0), 0],
- has_opt: [CType::BitField.new(1, 1), 1],
- has_rest: [CType::BitField.new(1, 2), 2],
- has_post: [CType::BitField.new(1, 3), 3],
- has_kw: [CType::BitField.new(1, 4), 4],
- has_kwrest: [CType::BitField.new(1, 5), 5],
- has_block: [CType::BitField.new(1, 6), 6],
- ambiguous_param0: [CType::BitField.new(1, 7), 7],
- accepts_no_kwarg: [CType::BitField.new(1, 0), 8],
- ruby2_keywords: [CType::BitField.new(1, 1), 9],
- ), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, flags)")],
- size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, size)")],
- lead_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, lead_num)")],
- opt_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, opt_num)")],
- rest_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, rest_start)")],
- post_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, post_start)")],
- post_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, post_num)")],
- block_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, block_start)")],
- opt_table: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, opt_table)")],
- keyword: [CType::Pointer.new { self.rb_iseq_param_keyword }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->param, keyword)")],
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), param)")],
- location: [self.rb_iseq_location_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), location)")],
- insns_info: [self.iseq_insn_info, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), insns_info)")],
- local_table: [CType::Pointer.new { self.ID }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), local_table)")],
- catch_table: [CType::Pointer.new { self.iseq_catch_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), catch_table)")],
- parent_iseq: [CType::Pointer.new { self.rb_iseq_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), parent_iseq)")],
- local_iseq: [CType::Pointer.new { self.rb_iseq_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), local_iseq)")],
- is_entries: [CType::Pointer.new { self.iseq_inline_storage_entry }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), is_entries)")],
- call_data: [CType::Pointer.new { self.rb_call_data }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), call_data)")],
- variable: [CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->variable)"),
- flip_count: [self.rb_snum_t, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, flip_count)")],
- script_lines: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, script_lines)")],
- coverage: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, coverage)")],
- pc2branchindex: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, pc2branchindex)")],
- original_iseq: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_constant_body *)NULL)->variable, original_iseq)")],
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), variable)")],
- local_table_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), local_table_size)")],
- ic_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ic_size)")],
- ise_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ise_size)")],
- ivc_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ivc_size)")],
- icvarc_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), icvarc_size)")],
- ci_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ci_size)")],
- stack_max: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), stack_max)")],
- builtin_attrs: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), builtin_attrs)")],
- mark_bits: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->mark_bits)"),
- list: CType::Pointer.new { self.iseq_bits_t },
- single: self.iseq_bits_t,
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mark_bits)")],
- outer_variables: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), outer_variables)")],
- mandatory_only_iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), mandatory_only_iseq)")],
- jit_entry: [self.rb_jit_func_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), jit_entry)")],
- jit_entry_calls: [CType::Immediate.parse("unsigned long"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), jit_entry_calls)")],
- rjit_blocks: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), rjit_blocks)"), true],
- )
- end
-
- def C.rb_iseq_location_t
- @rb_iseq_location_t ||= CType::Struct.new(
- "rb_iseq_location_struct", Primitive.cexpr!("SIZEOF(struct rb_iseq_location_struct)"),
- pathobj: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), pathobj)"), true],
- base_label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), base_label)"), true],
- label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), label)"), true],
- first_lineno: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), first_lineno)")],
- node_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), node_id)")],
- code_location: [self.rb_code_location_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), code_location)")],
- )
- end
-
- def C.rb_iseq_param_keyword
- @rb_iseq_param_keyword ||= CType::Struct.new(
- "rb_iseq_param_keyword", Primitive.cexpr!("SIZEOF(struct rb_iseq_param_keyword)"),
- num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_param_keyword *)NULL)), num)")],
- required_num: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_param_keyword *)NULL)), required_num)")],
- bits_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_param_keyword *)NULL)), bits_start)")],
- rest_start: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_param_keyword *)NULL)), rest_start)")],
- table: [CType::Pointer.new { self.ID }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_param_keyword *)NULL)), table)")],
- default_values: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_param_keyword *)NULL)), default_values)")],
- )
- end
-
- def C.rb_iseq_struct
- @rb_iseq_struct ||= CType::Struct.new(
- "rb_iseq_struct", Primitive.cexpr!("SIZEOF(struct rb_iseq_struct)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), flags)")],
- wrapper: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), wrapper)")],
- body: [CType::Pointer.new { self.rb_iseq_constant_body }, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), body)")],
- aux: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_struct *)NULL)->aux)"),
- compile_data: CType::Pointer.new { self.iseq_compile_data },
- loader: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_struct *)NULL)->aux.loader)"),
- obj: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.loader, obj)")],
- index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.loader, index)")],
- ),
- exec: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_struct *)NULL)->aux.exec)"),
- local_hooks: [CType::Pointer.new { self.rb_hook_list_struct }, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.exec, local_hooks)")],
- global_trace_events: [self.rb_event_flag_t, Primitive.cexpr!("OFFSETOF(((struct rb_iseq_struct *)NULL)->aux.exec, global_trace_events)")],
- ),
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_struct *)NULL)), aux)")],
- )
- end
-
- def C.rb_iseq_t
- @rb_iseq_t ||= self.rb_iseq_struct
- end
-
- def C.rb_jit_func_t
- @rb_jit_func_t ||= CType::Immediate.parse("void *")
- end
-
- def C.rb_method_attr_t
- @rb_method_attr_t ||= CType::Struct.new(
- "rb_method_attr_struct", Primitive.cexpr!("SIZEOF(struct rb_method_attr_struct)"),
- id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_method_attr_struct *)NULL)), id)")],
- location: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_attr_struct *)NULL)), location)")],
- )
- end
-
- def C.rb_method_bmethod_t
- @rb_method_bmethod_t ||= CType::Struct.new(
- "rb_method_bmethod_struct", Primitive.cexpr!("SIZEOF(struct rb_method_bmethod_struct)"),
- proc: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_bmethod_struct *)NULL)), proc)")],
- hooks: [CType::Pointer.new { self.rb_hook_list_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_method_bmethod_struct *)NULL)), hooks)")],
- defined_ractor: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_bmethod_struct *)NULL)), defined_ractor)")],
- )
- end
-
- def C.rb_method_cfunc_t
- @rb_method_cfunc_t ||= CType::Struct.new(
- "rb_method_cfunc_struct", Primitive.cexpr!("SIZEOF(struct rb_method_cfunc_struct)"),
- func: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_method_cfunc_struct *)NULL)), func)")],
- invoker: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_method_cfunc_struct *)NULL)), invoker)")],
- argc: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_method_cfunc_struct *)NULL)), argc)")],
- )
- end
-
- def C.rb_method_definition_struct
- @rb_method_definition_struct ||= CType::Struct.new(
- "rb_method_definition_struct", Primitive.cexpr!("SIZEOF(struct rb_method_definition_struct)"),
- type: [CType::BitField.new(4, 0), 0],
- iseq_overload: [CType::BitField.new(1, 4), 4],
- no_redef_warning: [CType::BitField.new(1, 5), 5],
- aliased: [CType::BitField.new(1, 6), 6],
- reference_count: [CType::BitField.new(28, 0), 32],
- body: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_method_definition_struct *)NULL)->body)"),
- iseq: self.rb_method_iseq_t,
- cfunc: self.rb_method_cfunc_t,
- attr: self.rb_method_attr_t,
- alias: self.rb_method_alias_t,
- refined: self.rb_method_refined_t,
- bmethod: self.rb_method_bmethod_t,
- optimized: self.rb_method_optimized_t,
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_method_definition_struct *)NULL)), body)")],
- original_id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_method_definition_struct *)NULL)), original_id)")],
- method_serial: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_method_definition_struct *)NULL)), method_serial)")],
- )
- end
-
- def C.rb_method_entry_t
- @rb_method_entry_t ||= CType::Struct.new(
- "rb_method_entry_struct", Primitive.cexpr!("SIZEOF(struct rb_method_entry_struct)"),
- flags: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_entry_struct *)NULL)), flags)")],
- defined_class: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_entry_struct *)NULL)), defined_class)")],
- def: [CType::Pointer.new { self.rb_method_definition_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_method_entry_struct *)NULL)), def)")],
- called_id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_method_entry_struct *)NULL)), called_id)")],
- owner: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_entry_struct *)NULL)), owner)")],
- )
- end
-
- def C.rb_method_iseq_t
- @rb_method_iseq_t ||= CType::Struct.new(
- "rb_method_iseq_struct", Primitive.cexpr!("SIZEOF(struct rb_method_iseq_struct)"),
- iseqptr: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_method_iseq_struct *)NULL)), iseqptr)")],
- cref: [CType::Pointer.new { self.rb_cref_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_method_iseq_struct *)NULL)), cref)")],
- )
- end
-
- def C.rb_method_optimized_t
- @rb_method_optimized_t ||= CType::Struct.new(
- "rb_method_optimized", Primitive.cexpr!("SIZEOF(struct rb_method_optimized)"),
- type: [self.method_optimized_type, Primitive.cexpr!("OFFSETOF((*((struct rb_method_optimized *)NULL)), type)")],
- index: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_method_optimized *)NULL)), index)")],
- )
- end
-
- def C.rb_method_type_t
- @rb_method_type_t ||= CType::Immediate.parse("int")
- end
-
- def C.rb_proc_t
- @rb_proc_t ||= CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(rb_proc_t)"),
- block: [self.rb_block, Primitive.cexpr!("OFFSETOF((*((rb_proc_t *)NULL)), block)")],
- )
- end
-
- def C.rb_rjit_options
- @rb_rjit_options ||= CType::Struct.new(
- "rb_rjit_options", Primitive.cexpr!("SIZEOF(struct rb_rjit_options)"),
- on: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), on)")],
- exec_mem_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), exec_mem_size)")],
- call_threshold: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), call_threshold)")],
- stats: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), stats)")],
- disable: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), disable)")],
- trace: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), trace)")],
- trace_exits: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), trace_exits)")],
- dump_disasm: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), dump_disasm)")],
- verify_ctx: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_options *)NULL)), verify_ctx)")],
- )
- end
-
- def C.rb_rjit_runtime_counters
- @rb_rjit_runtime_counters ||= CType::Struct.new(
- "rb_rjit_runtime_counters", Primitive.cexpr!("SIZEOF(struct rb_rjit_runtime_counters)"),
- rjit_insns_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), rjit_insns_count)")],
- send_args_splat_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_kw_splat)")],
- send_args_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat)")],
- send_args_splat_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_not_array)")],
- send_args_splat_length_not_equal: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_length_not_equal)")],
- send_args_splat_cfunc_var_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_cfunc_var_args)")],
- send_args_splat_arity_error: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_arity_error)")],
- send_args_splat_ruby2_hash: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_ruby2_hash)")],
- send_args_splat_cfunc_zuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_cfunc_zuper)")],
- send_args_splat_cfunc_ruby2_keywords: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_args_splat_cfunc_ruby2_keywords)")],
- send_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_kw_splat)")],
- send_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_kwarg)")],
- send_klass_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_klass_megamorphic)")],
- send_missing_cme: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_missing_cme)")],
- send_private: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_private)")],
- send_protected_check_failed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_protected_check_failed)")],
- send_tailcall: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_tailcall)")],
- send_notimplemented: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_notimplemented)")],
- send_missing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_missing)")],
- send_bmethod: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod)")],
- send_alias: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_alias)")],
- send_undef: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_undef)")],
- send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_zsuper)")],
- send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_refined)")],
- send_stackoverflow: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_stackoverflow)")],
- send_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_arity)")],
- send_c_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_c_tracing)")],
- send_is_a_class_mismatch: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_is_a_class_mismatch)")],
- send_instance_of_class_mismatch: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_instance_of_class_mismatch)")],
- send_keywords: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_keywords)")],
- send_blockiseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_blockiseq)")],
- send_block_handler: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_handler)")],
- send_block_setup: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_setup)")],
- send_block_not_nil: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_not_nil)")],
- send_block_not_proxy: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_not_proxy)")],
- send_block_arg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_arg)")],
- send_iseq_kwparam: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_kwparam)")],
- send_iseq_accepts_no_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_accepts_no_kwarg)")],
- send_iseq_has_opt: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_opt)")],
- send_iseq_has_kwrest: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_kwrest)")],
- send_iseq_ruby2_keywords: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_ruby2_keywords)")],
- send_iseq_has_rest_and_captured: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_rest_and_captured)")],
- send_iseq_has_rest_and_kw_supplied: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_rest_and_kw_supplied)")],
- send_iseq_has_no_kw: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_no_kw)")],
- send_iseq_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_zsuper)")],
- send_iseq_materialized_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_materialized_block)")],
- send_iseq_has_rest: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_rest)")],
- send_iseq_block_arg0_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_block_arg0_splat)")],
- send_iseq_kw_call: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_kw_call)")],
- send_iseq_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_splat)")],
- send_iseq_has_rest_and_optional: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_rest_and_optional)")],
- send_iseq_arity_error: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_arity_error)")],
- send_iseq_missing_optional_kw: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_missing_optional_kw)")],
- send_iseq_too_many_kwargs: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_too_many_kwargs)")],
- send_iseq_kwargs_mismatch: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_kwargs_mismatch)")],
- send_iseq_splat_with_kw: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_splat_with_kw)")],
- send_iseq_splat_arity_error: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_splat_arity_error)")],
- send_iseq_has_rest_and_splat_not_equal: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_has_rest_and_splat_not_equal)")],
- send_cfunc_variadic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_variadic)")],
- send_cfunc_too_many_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_too_many_args)")],
- send_cfunc_ruby_array_varg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_ruby_array_varg)")],
- send_cfunc_splat_with_kw: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_splat_with_kw)")],
- send_cfunc_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_tracing)")],
- send_cfunc_argc_mismatch: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_argc_mismatch)")],
- send_cfunc_toomany_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_toomany_args)")],
- send_attrset_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_attrset_splat)")],
- send_attrset_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_attrset_kwarg)")],
- send_attrset_method: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_attrset_method)")],
- send_ivar_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_ivar_splat)")],
- send_ivar_opt_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_ivar_opt_send)")],
- send_optimized_send_no_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_no_args)")],
- send_optimized_send_not_sym_or_str: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_not_sym_or_str)")],
- send_optimized_send_mid_class_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_mid_class_changed)")],
- send_optimized_send_mid_id_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_mid_id_changed)")],
- send_optimized_send_null_mid: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_null_mid)")],
- send_optimized_send_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_send_send)")],
- send_optimized_call_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_call_block)")],
- send_optimized_call_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_call_kwarg)")],
- send_optimized_call_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_call_splat)")],
- send_optimized_struct_aref_error: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_struct_aref_error)")],
- send_optimized_block_call: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_block_call)")],
- send_optimized_struct_aset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_struct_aset)")],
- send_bmethod_not_iseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_not_iseq)")],
- send_bmethod_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_blockarg)")],
- invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_me_changed)")],
- invokesuper_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_block)")],
- invokeblock_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_none)")],
- invokeblock_symbol: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_symbol)")],
- invokeblock_proc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_proc)")],
- invokeblock_tag_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_tag_changed)")],
- invokeblock_iseq_block_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_block_changed)")],
- invokeblock_iseq_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arity)")],
- invokeblock_iseq_arg0_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arg0_splat)")],
- invokeblock_ifunc_args_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_ifunc_args_splat)")],
- invokeblock_ifunc_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_ifunc_kw_splat)")],
- invokeblock_iseq_arg0_args_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arg0_args_splat)")],
- invokeblock_iseq_arg0_has_kw: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arg0_has_kw)")],
- getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_megamorphic)")],
- getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_not_heap)")],
- getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_special_const)")],
- getivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_too_complex)")],
- optaref_arg_not_fixnum: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_arg_not_fixnum)")],
- optaref_argc_not_one: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_argc_not_one)")],
- optaref_recv_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_recv_not_array)")],
- optaref_recv_not_hash: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_recv_not_hash)")],
- optaref_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optaref_send)")],
- optgetconst_not_cached: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optgetconst_not_cached)")],
- optgetconst_cref: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optgetconst_cref)")],
- optgetconst_cache_miss: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), optgetconst_cache_miss)")],
- setivar_frozen: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_frozen)")],
- setivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_not_heap)")],
- setivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_megamorphic)")],
- setivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), setivar_too_complex)")],
- expandarray_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_splat)")],
- expandarray_postarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_postarg)")],
- expandarray_not_array: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_not_array)")],
- expandarray_rhs_too_small: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), expandarray_rhs_too_small)")],
- getblockpp_block_param_modified: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_block_param_modified)")],
- getblockpp_block_handler_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_block_handler_none)")],
- getblockpp_not_gc_guarded: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_not_gc_guarded)")],
- getblockpp_not_iseq_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getblockpp_not_iseq_block)")],
- compiled_block_count: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), compiled_block_count)")],
- )
- end
-
- def C.rb_serial_t
- @rb_serial_t ||= CType::Immediate.parse("unsigned long long")
- end
-
- def C.rb_shape
- @rb_shape ||= CType::Struct.new(
- "rb_shape", Primitive.cexpr!("SIZEOF(struct rb_shape)"),
- edges: [CType::Pointer.new { self.rb_id_table }, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), edges)")],
- edge_name: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), edge_name)")],
- next_iv_index: [self.attr_index_t, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), next_iv_index)")],
- capacity: [CType::Immediate.parse("uint32_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), capacity)")],
- type: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), type)")],
- size_pool_index: [CType::Immediate.parse("uint8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), size_pool_index)")],
- parent_id: [self.shape_id_t, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), parent_id)")],
- ancestor_index: [CType::Pointer.new { self.redblack_node_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_shape *)NULL)), ancestor_index)")],
- )
- end
-
- def C.rb_shape_t
- @rb_shape_t ||= self.rb_shape
- end
-
- def C.rb_thread_struct
- @rb_thread_struct ||= CType::Struct.new(
- "rb_thread_struct", Primitive.cexpr!("SIZEOF(struct rb_thread_struct)"),
- lt_node: [self.ccan_list_node, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), lt_node)")],
- self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), self)")],
- ractor: [CType::Pointer.new { self.rb_ractor_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), ractor)")],
- vm: [CType::Pointer.new { self.rb_vm_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), vm)")],
- nt: [CType::Pointer.new { self.rb_native_thread }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), nt)")],
- ec: [CType::Pointer.new { self.rb_execution_context_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), ec)")],
- sched: [self.rb_thread_sched_item, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), sched)")],
- serial: [self.rb_atomic_t, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), serial)")],
- last_status: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), last_status)")],
- calling: [CType::Pointer.new { self.rb_calling_info }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), calling)")],
- top_self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), top_self)")],
- top_wrapper: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), top_wrapper)")],
- priority: [CType::Immediate.parse("int8_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), priority)")],
- running_time_us: [CType::Immediate.parse("uint32_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), running_time_us)")],
- blocking_region_buffer: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), blocking_region_buffer)")],
- thgroup: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), thgroup)")],
- value: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), value)")],
- pending_interrupt_queue: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), pending_interrupt_queue)")],
- pending_interrupt_mask_stack: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), pending_interrupt_mask_stack)")],
- interrupt_lock: [self.rb_nativethread_lock_t, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), interrupt_lock)")],
- unblock: [self.rb_unblock_callback, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), unblock)")],
- locking_mutex: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), locking_mutex)")],
- keeping_mutexes: [CType::Pointer.new { self.rb_mutex_struct }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), keeping_mutexes)")],
- join_list: [CType::Pointer.new { self.rb_waiting_list }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), join_list)")],
- invoke_arg: [CType::Union.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_thread_struct *)NULL)->invoke_arg)"),
- proc: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_thread_struct *)NULL)->invoke_arg.proc)"),
- proc: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_thread_struct *)NULL)->invoke_arg.proc, proc)")],
- args: [self.VALUE, Primitive.cexpr!("OFFSETOF(((struct rb_thread_struct *)NULL)->invoke_arg.proc, args)")],
- kw_splat: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF(((struct rb_thread_struct *)NULL)->invoke_arg.proc, kw_splat)")],
- ),
- func: CType::Struct.new(
- "", Primitive.cexpr!("SIZEOF(((struct rb_thread_struct *)NULL)->invoke_arg.func)"),
- func: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF(((struct rb_thread_struct *)NULL)->invoke_arg.func, func)")],
- arg: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF(((struct rb_thread_struct *)NULL)->invoke_arg.func, arg)")],
- ),
- ), Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), invoke_arg)")],
- invoke_type: [self.thread_invoke_type, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), invoke_type)")],
- stat_insn_usage: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), stat_insn_usage)")],
- root_fiber: [CType::Pointer.new { self.rb_fiber_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), root_fiber)")],
- scheduler: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), scheduler)")],
- blocking: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), blocking)")],
- name: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), name)")],
- specific_storage: [CType::Pointer.new { CType::Pointer.new { CType::Immediate.parse("void") } }, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), specific_storage)")],
- ext_config: [self.rb_ext_config, Primitive.cexpr!("OFFSETOF((*((struct rb_thread_struct *)NULL)), ext_config)")],
- )
- end
-
- def C.VALUE
- @VALUE ||= CType::Immediate.find(Primitive.cexpr!("SIZEOF(VALUE)"), Primitive.cexpr!("SIGNED_TYPE_P(VALUE)"))
- end
-
- def C.shape_id_t
- @shape_id_t ||= CType::Immediate.find(Primitive.cexpr!("SIZEOF(shape_id_t)"), Primitive.cexpr!("SIGNED_TYPE_P(shape_id_t)"))
- end
-
- def C.rb_id_table
- CType::Stub.new(:rb_id_table)
- end
-
- def C.vm_call_handler
- CType::Stub.new(:vm_call_handler)
- end
-
- def C.method_missing_reason
- CType::Stub.new(:method_missing_reason)
- end
-
- def C.vm_ifunc
- CType::Stub.new(:vm_ifunc)
- end
-
- def C.rb_cref_struct
- CType::Stub.new(:rb_cref_struct)
- end
-
- def C.rb_scope_visibility_t
- CType::Stub.new(:rb_scope_visibility_t)
- end
-
- def C.rb_vm_tag
- CType::Stub.new(:rb_vm_tag)
- end
-
- def C.rb_atomic_t
- CType::Stub.new(:rb_atomic_t)
- end
-
- def C.rb_fiber_t
- CType::Stub.new(:rb_fiber_t)
- end
-
- def C.rb_ensure_list_t
- CType::Stub.new(:rb_ensure_list_t)
- end
-
- def C.rb_trace_arg_struct
- CType::Stub.new(:rb_trace_arg_struct)
- end
-
- def C.rb_iseq_type
- CType::Stub.new(:rb_iseq_type)
- end
-
- def C.iseq_insn_info
- CType::Stub.new(:iseq_insn_info)
- end
-
- def C.iseq_catch_table
- CType::Stub.new(:iseq_catch_table)
- end
-
- def C.rb_snum_t
- CType::Stub.new(:rb_snum_t)
- end
-
- def C.iseq_bits_t
- CType::Stub.new(:iseq_bits_t)
- end
-
- def C.rb_code_location_t
- CType::Stub.new(:rb_code_location_t)
- end
-
- def C.iseq_compile_data
- CType::Stub.new(:iseq_compile_data)
- end
-
- def C.rb_hook_list_struct
- CType::Stub.new(:rb_hook_list_struct)
- end
-
- def C.rb_event_flag_t
- CType::Stub.new(:rb_event_flag_t)
- end
-
- def C.rb_method_alias_t
- CType::Stub.new(:rb_method_alias_t)
- end
-
- def C.rb_method_refined_t
- CType::Stub.new(:rb_method_refined_t)
- end
-
- def C._Bool
- CType::Bool.new
- end
-
- def C.redblack_node_t
- CType::Stub.new(:redblack_node_t)
- end
-
- def C.ccan_list_node
- CType::Stub.new(:ccan_list_node)
- end
-
- def C.rb_ractor_t
- CType::Stub.new(:rb_ractor_t)
- end
-
- def C.rb_vm_t
- CType::Stub.new(:rb_vm_t)
- end
-
- def C.rb_native_thread
- CType::Stub.new(:rb_native_thread)
- end
-
- def C.rb_thread_sched_item
- CType::Stub.new(:rb_thread_sched_item)
- end
-
- def C.rb_calling_info
- CType::Stub.new(:rb_calling_info)
- end
-
- def C.rb_nativethread_lock_t
- CType::Stub.new(:rb_nativethread_lock_t)
- end
-
- def C.rb_unblock_callback
- CType::Stub.new(:rb_unblock_callback)
- end
-
- def C.rb_mutex_struct
- CType::Stub.new(:rb_mutex_struct)
- end
-
- def C.rb_waiting_list
- CType::Stub.new(:rb_waiting_list)
- end
-
- def C.thread_invoke_type
- CType::Stub.new(:thread_invoke_type)
- end
-
- def C.rb_ext_config
- CType::Stub.new(:rb_ext_config)
- end
-
- ### RJIT bindgen end ###
-end if Primitive.rjit_enabled_p
diff --git a/ruby-runner.c b/ruby-runner.c
index 48acf4396e..e1a53d5236 100644
--- a/ruby-runner.c
+++ b/ruby-runner.c
@@ -7,12 +7,15 @@
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef _WIN32
-# error This feature is unnecessary on Windows in favor of SxS.
-#endif
-
#include "ruby-runner.h"
+#ifdef MAKE_MJIT_BUILD_DIR
+const char MJIT_HEADER[] = BUILDDIR "/" MJIT_MIN_HEADER;
+#else
+
+#define STRINGIZE(expr) STRINGIZE0(expr)
+#define STRINGIZE0(expr) #expr
+
static void
insert_env_path(const char *envname, const char *paths, size_t size, int prepend)
{
@@ -29,24 +32,12 @@ insert_env_path(const char *envname, const char *paths, size_t size, int prepend
char *e = malloc(size+n+1);
size_t pos = 0;
if (prepend) {
- if (size == n || (size < n && env[size] == PATH_SEP)) {
- if (strncmp(paths, env, size) == 0) {
- free(e);
- return;
- }
- }
memcpy(e, paths, pos = size-1);
e[pos++] = PATH_SEP;
}
memcpy(e+pos, env, n);
pos += n;
if (!prepend) {
- if (size == n || (size < n && env[n-size-1] == PATH_SEP)) {
- if (strncmp(paths, &env[n-size], size) == 0) {
- free(e);
- return;
- }
- }
e[pos++] = PATH_SEP;
memcpy(e+pos, paths, size-1);
pos += size-1;
@@ -73,6 +64,10 @@ main(int argc, char **argv)
PATH_SEPARATOR
EXTOUT_DIR"/"ARCH
;
+#ifndef LOAD_RELATIVE
+ static const char mjit_build_dir[] = BUILDDIR"/mjit_build_dir."SOEXT;
+ struct stat stbuf;
+#endif
const size_t dirsize = sizeof(builddir);
const size_t namesize = sizeof(rubypath) - dirsize;
const char *rubyname = rubypath + dirsize;
@@ -80,6 +75,12 @@ main(int argc, char **argv)
insert_env_path(LIBPATHENV, builddir, dirsize, 1);
insert_env_path("RUBYLIB", rubylib, sizeof(rubylib), 0);
+#ifndef LOAD_RELATIVE
+ if (PRELOADENV[0] && stat(mjit_build_dir, &stbuf) == 0) {
+ insert_env_path(PRELOADENV, mjit_build_dir, sizeof(mjit_build_dir), 1);
+ setenv("MJIT_SEARCH_BUILD_DIR", "true", 0);
+ }
+#endif
if (!(p = strrchr(arg0, '/'))) p = arg0; else p++;
if (strlen(p) < namesize - 1) {
@@ -93,3 +94,5 @@ main(int argc, char **argv)
perror(rubypath);
return -1;
}
+
+#endif /* MAKE_MJIT_BUILD_DIR */
diff --git a/ruby.c b/ruby.c
index fedb42c743..09c81db86c 100644
--- a/ruby.c
+++ b/ruby.c
@@ -22,7 +22,7 @@
# include <sys/cygwin.h>
#endif
-#if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR)
+#if (defined(LOAD_RELATIVE) || defined(__MACH__)) && defined(HAVE_DLADDR)
# include <dlfcn.h>
#endif
@@ -53,8 +53,8 @@
#include "internal/loadpath.h"
#include "internal/missing.h"
#include "internal/object.h"
-#include "internal/thread.h"
-#include "internal/ruby_parser.h"
+#include "internal/parse.h"
+#include "internal/process.h"
#include "internal/variable.h"
#include "ruby/encoding.h"
#include "ruby/thread.h"
@@ -105,7 +105,7 @@ void rb_warning_category_update(unsigned int mask, unsigned int bits);
SEP \
X(frozen_string_literal) \
SEP \
- X(rjit) \
+ X(mjit) \
SEP \
X(yjit) \
/* END OF FEATURES */
@@ -118,12 +118,12 @@ void rb_warning_category_update(unsigned int mask, unsigned int bits);
enum feature_flag_bits {
EACH_FEATURES(DEFINE_FEATURE, COMMA),
feature_debug_flag_first,
-#if defined(RJIT_FORCE_ENABLE) || !USE_YJIT
- DEFINE_FEATURE(jit) = feature_rjit,
+#if defined(MJIT_FORCE_ENABLE) || !USE_YJIT
+ DEFINE_FEATURE(jit) = feature_mjit,
#else
DEFINE_FEATURE(jit) = feature_yjit,
#endif
- feature_jit_mask = FEATURE_BIT(rjit) | FEATURE_BIT(yjit),
+ feature_jit_mask = FEATURE_BIT(mjit) | FEATURE_BIT(yjit),
feature_debug_flag_begin = feature_debug_flag_first - 1,
EACH_DEBUG_FEATURES(DEFINE_DEBUG_FEATURE, COMMA),
@@ -153,8 +153,6 @@ enum feature_flag_bits {
SEP \
X(parsetree_with_comment) \
SEP \
- X(prism_parsetree) \
- SEP \
X(insns) \
SEP \
X(insns_without_opt) \
@@ -168,7 +166,7 @@ enum dump_flag_bits {
DUMP_BIT(parsetree_with_comment)),
dump_exit_bits = (DUMP_BIT(yydebug) | DUMP_BIT(syntax) |
DUMP_BIT(parsetree) | DUMP_BIT(parsetree_with_comment) |
- DUMP_BIT(prism_parsetree) | DUMP_BIT(insns) | DUMP_BIT(insns_without_opt))
+ DUMP_BIT(insns) | DUMP_BIT(insns_without_opt))
};
static inline void
@@ -206,10 +204,6 @@ enum {
)
};
-#define BACKTRACE_LENGTH_LIMIT_VALID_P(n) ((n) >= -1)
-#define OPT_BACKTRACE_LENGTH_LIMIT_VALID_P(opt) \
- BACKTRACE_LENGTH_LIMIT_VALID_P((opt)->backtrace_length_limit)
-
static ruby_cmdline_options_t *
cmdline_options_init(ruby_cmdline_options_t *opt)
{
@@ -219,12 +213,11 @@ cmdline_options_init(ruby_cmdline_options_t *opt)
opt->ext.enc.index = -1;
opt->intern.enc.index = -1;
opt->features.set = DEFAULT_FEATURES;
-#ifdef RJIT_FORCE_ENABLE /* to use with: ./configure cppflags="-DRJIT_FORCE_ENABLE" */
- opt->features.set |= FEATURE_BIT(rjit);
+#ifdef MJIT_FORCE_ENABLE /* to use with: ./configure cppflags="-DMJIT_FORCE_ENABLE" */
+ opt->features.set |= FEATURE_BIT(mjit);
#elif defined(YJIT_FORCE_ENABLE)
opt->features.set |= FEATURE_BIT(yjit);
#endif
- opt->backtrace_length_limit = LONG_MIN;
return opt;
}
@@ -244,85 +237,35 @@ static const char esc_standout[] = "\n\033[1;7m";
static const char esc_bold[] = "\033[1m";
static const char esc_reset[] = "\033[0m";
static const char esc_none[] = "";
-#define USAGE_INDENT " " /* macro for concatenation */
static void
-show_usage_part(const char *str, const unsigned int namelen,
- const char *str2, const unsigned int secondlen,
- const char *desc,
- int help, int highlight, unsigned int w, int columns)
+show_usage_line(const char *str, unsigned int namelen, unsigned int secondlen, int help, int highlight, unsigned int w)
{
- static const int indent_width = (int)rb_strlen_lit(USAGE_INDENT);
const char *sb = highlight ? esc_bold : esc_none;
const char *se = highlight ? esc_reset : esc_none;
- unsigned int desclen = (unsigned int)strcspn(desc, "\n");
- if (help && (namelen + 1 > w) && /* a padding space */
- (int)(namelen + secondlen + indent_width) >= columns) {
- printf(USAGE_INDENT "%s" "%.*s" "%s\n", sb, namelen, str, se);
- if (secondlen > 0) {
- const int second_end = secondlen;
- int n = 0;
- if (str2[n] == ',') n++;
- if (str2[n] == ' ') n++;
- printf(USAGE_INDENT "%s" "%.*s" "%s\n", sb, second_end-n, str2+n, se);
- }
- printf("%-*s%.*s\n", w + indent_width, USAGE_INDENT, desclen, desc);
- }
- else {
- const int wrap = help && namelen + secondlen >= w;
- printf(USAGE_INDENT "%s%.*s%-*.*s%s%-*s%.*s\n", sb, namelen, str,
- (wrap ? 0 : w - namelen),
- (help ? secondlen : 0), str2, se,
- (wrap ? (int)(w + rb_strlen_lit("\n" USAGE_INDENT)) : 0),
- (wrap ? "\n" USAGE_INDENT : ""),
- desclen, desc);
- }
- if (help) {
- while (desc[desclen]) {
- desc += desclen + rb_strlen_lit("\n");
- desclen = (unsigned int)strcspn(desc, "\n");
- printf("%-*s%.*s\n", w + indent_width, USAGE_INDENT, desclen, desc);
- }
- }
-}
-
-static void
-show_usage_line(const struct ruby_opt_message *m,
- int help, int highlight, unsigned int w, int columns)
-{
- const char *str = m->str;
- const unsigned int namelen = m->namelen, secondlen = m->secondlen;
- const char *desc = str + namelen + secondlen;
- show_usage_part(str, namelen - 1, str + namelen, secondlen - 1, desc,
- help, highlight, w, columns);
-}
-
-void
-ruby_show_usage_line(const char *name, const char *secondary, const char *description,
- int help, int highlight, unsigned int width, int columns)
-{
- unsigned int namelen = (unsigned int)strlen(name);
- unsigned int secondlen = (secondary ? (unsigned int)strlen(secondary) : 0);
- show_usage_part(name, namelen, secondary, secondlen,
- description, help, highlight, width, columns);
+ const int wrap = help && namelen + secondlen - 1 > w;
+ printf(" %s%.*s%-*.*s%s%-*s%s\n", sb, namelen-1, str,
+ (wrap ? 0 : w - namelen + 1),
+ (help ? secondlen-1 : 0), str + namelen, se,
+ (wrap ? w + 3 : 0), (wrap ? "\n" : ""),
+ str + namelen + secondlen);
}
static void
usage(const char *name, int help, int highlight, int columns)
{
+ /* This message really ought to be max 23 lines.
+ * Removed -h because the user already knows that option. Others? */
+
#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc)
#if USE_YJIT
# define PLATFORM_JIT_OPTION "--yjit"
#else
-# define PLATFORM_JIT_OPTION "--rjit (experimental)"
+# define PLATFORM_JIT_OPTION "--mjit (experimental)"
#endif
-
- /* This message really ought to be max 23 lines.
- * Removed -h because the user already knows that option. Others? */
static const struct ruby_opt_message usage_msg[] = {
- M("-0[octal]", "", "specify record separator (\\0, if no argument)\n"
- "(-00 for paragraph mode, -0777 for slurp mode)"),
+ M("-0[octal]", "", "specify record separator (\\0, if no argument)"),
M("-a", "", "autosplit mode with -n or -p (splits $_ into $F)"),
M("-c", "", "check syntax only"),
M("-Cdirectory", "", "cd to directory before executing your script"),
@@ -343,31 +286,25 @@ usage(const char *name, int help, int highlight, int columns)
M("-W[level=2|:category]", "", "set warning level; 0=silence, 1=medium, 2=verbose"),
M("-x[directory]", "", "strip off text before #!ruby line and perhaps cd to directory"),
M("--jit", "", "enable JIT for the platform, same as " PLATFORM_JIT_OPTION),
+#if USE_MJIT
+ M("--mjit", "", "enable C compiler-based JIT compiler (experimental)"),
+#endif
#if USE_YJIT
M("--yjit", "", "enable in-process JIT compiler"),
#endif
-#if USE_RJIT
- M("--rjit", "", "enable pure-Ruby JIT compiler (experimental)"),
-#endif
M("-h", "", "show this message, --help for more info"),
};
- STATIC_ASSERT(usage_msg_size, numberof(usage_msg) < 25);
-
static const struct ruby_opt_message help_msg[] = {
M("--copyright", "", "print the copyright"),
- M("--dump={insns|parsetree|prism_parsetree|...}[,...]", "",
+ M("--dump={insns|parsetree|...}[,...]", "",
"dump debug information. see below for available dump list"),
M("--enable={jit|rubyopt|...}[,...]", ", --disable={jit|rubyopt|...}[,...]",
"enable or disable features. see below for available features"),
M("--external-encoding=encoding", ", --internal-encoding=encoding",
"specify the default external or internal character encoding"),
- M("--parser={parse.y|prism}", ", --parser=prism",
- "the parser used to parse Ruby code (experimental)"),
M("--backtrace-limit=num", "", "limit the maximum length of backtrace"),
M("--verbose", "", "turn on verbose mode and disable script from stdin"),
M("--version", "", "print the version number, then exit"),
- M("--crash-report=TEMPLATE", "", "template of crash report files"),
- M("-y", ", --yydebug", "print log of parser. Backward compatibility is not guaranteed"),
M("--help", "", "show this message, -h for short message"),
};
static const struct ruby_opt_message dumps[] = {
@@ -376,7 +313,6 @@ usage(const char *name, int help, int highlight, int columns)
M("yydebug(+error-tolerant)", "", "yydebug of yacc parser generator"),
M("parsetree(+error-tolerant)","", "AST"),
M("parsetree_with_comment(+error-tolerant)", "", "AST with comments"),
- M("prism_parsetree", "", "Prism AST with comments"),
};
static const struct ruby_opt_message features[] = {
M("gems", "", "rubygems (only for debugging, default: "DEFAULT_RUBYGEMS_ENABLED")"),
@@ -385,27 +321,35 @@ usage(const char *name, int help, int highlight, int columns)
M("syntax_suggest", "", "syntax_suggest (default: "DEFAULT_RUBYGEMS_ENABLED")"),
M("rubyopt", "", "RUBYOPT environment variable (default: enabled)"),
M("frozen-string-literal", "", "freeze all string literals (default: disabled)"),
+#if USE_MJIT
+ M("mjit", "", "C compiler-based JIT compiler (default: disabled)"),
+#endif
#if USE_YJIT
M("yjit", "", "in-process JIT compiler (default: disabled)"),
#endif
-#if USE_RJIT
- M("rjit", "", "pure-Ruby JIT compiler (experimental, default: disabled)"),
-#endif
};
static const struct ruby_opt_message warn_categories[] = {
M("deprecated", "", "deprecated features"),
M("experimental", "", "experimental features"),
- M("performance", "", "performance issues"),
};
-#if USE_RJIT
- extern const struct ruby_opt_message rb_rjit_option_messages[];
+#if USE_MJIT
+ extern const struct ruby_opt_message mjit_option_messages[];
+#endif
+#if USE_YJIT
+ static const struct ruby_opt_message yjit_options[] = {
+ M("--yjit-stats", "", "Enable collecting YJIT statistics"),
+ M("--yjit-exec-mem-size=num", "", "Size of executable memory block in MiB (default: 64)"),
+ M("--yjit-call-threshold=num", "", "Number of calls to trigger JIT (default: 10)"),
+ M("--yjit-max-versions=num", "", "Maximum number of versions per basic block (default: 4)"),
+ M("--yjit-greedy-versioning", "", "Greedy versioning mode (default: disabled)"),
+ };
#endif
int i;
const char *sb = highlight ? esc_standout+1 : esc_none;
const char *se = highlight ? esc_reset : esc_none;
const int num = numberof(usage_msg) - (help ? 1 : 0);
unsigned int w = (columns > 80 ? (columns - 79) / 2 : 0) + 16;
-#define SHOW(m) show_usage_line(&(m), help, highlight, w, columns)
+#define SHOW(m) show_usage_line((m).str, (m).namelen, (m).secondlen, help, highlight, w)
printf("%sUsage:%s %s [switches] [--] [programfile] [arguments]\n", sb, se, name);
for (i = 0; i < num; ++i)
@@ -426,14 +370,15 @@ usage(const char *name, int help, int highlight, int columns)
printf("%s""Warning categories:%s\n", sb, se);
for (i = 0; i < numberof(warn_categories); ++i)
SHOW(warn_categories[i]);
+#if USE_MJIT
+ printf("%s""MJIT options (experimental):%s\n", sb, se);
+ for (i = 0; mjit_option_messages[i].str; ++i)
+ SHOW(mjit_option_messages[i]);
+#endif
#if USE_YJIT
printf("%s""YJIT options:%s\n", sb, se);
- rb_yjit_show_usage(help, highlight, w, columns);
-#endif
-#if USE_RJIT
- printf("%s""RJIT options (experimental):%s\n", sb, se);
- for (i = 0; rb_rjit_option_messages[i].str; ++i)
- SHOW(rb_rjit_option_messages[i]);
+ for (i = 0; i < numberof(yjit_options); ++i)
+ SHOW(yjit_options[i]);
#endif
}
@@ -573,6 +518,8 @@ translit_char_bin(char *p, int from, int to)
#endif
#ifdef _WIN32
+# undef chdir
+# define chdir rb_w32_uchdir
# define UTF8_PATH 1
#endif
@@ -599,13 +546,17 @@ str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
void ruby_init_loadpath(void);
-#if defined(LOAD_RELATIVE)
+#if defined(LOAD_RELATIVE) || defined(__MACH__)
static VALUE
runtime_libruby_path(void)
{
#if defined _WIN32 || defined __CYGWIN__
- DWORD ret;
- DWORD len = 32;
+ DWORD len, ret;
+#if USE_RVARGC
+ len = 32;
+#else
+ len = RSTRING_EMBED_LEN_MAX;
+#endif
VALUE path;
VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
WCHAR *wlibpath;
@@ -676,6 +627,10 @@ runtime_libruby_path(void)
#define INITIAL_LOAD_PATH_MARK rb_intern_const("@gem_prelude_index")
VALUE ruby_archlibdir_path, ruby_prefix_path;
+#if defined(__MACH__)
+// A path to libruby.dylib itself or where it's statically linked to.
+VALUE rb_libruby_selfpath;
+#endif
void
ruby_init_loadpath(void)
@@ -683,6 +638,19 @@ ruby_init_loadpath(void)
VALUE load_path, archlibdir = 0;
ID id_initial_load_path_mark;
const char *paths = ruby_initial_load_paths;
+#if defined(LOAD_RELATIVE) || defined(__MACH__)
+ VALUE libruby_path = runtime_libruby_path();
+# if defined(__MACH__)
+ VALUE selfpath = libruby_path;
+# if defined(LOAD_RELATIVE)
+ selfpath = rb_str_dup(selfpath);
+# endif
+ rb_obj_hide(selfpath);
+ OBJ_FREEZE_RAW(selfpath);
+ rb_gc_register_address(&rb_libruby_selfpath);
+ rb_libruby_selfpath = selfpath;
+# endif
+#endif
#if defined LOAD_RELATIVE
#if !defined ENABLE_MULTIARCH
@@ -697,7 +665,7 @@ ruby_init_loadpath(void)
size_t baselen;
const char *p;
- sopath = runtime_libruby_path();
+ sopath = libruby_path;
libpath = RSTRING_PTR(sopath);
p = strrchr(libpath, '/');
@@ -818,10 +786,10 @@ toplevel_context(rb_binding_t *bind)
return &bind->block;
}
-static int
-process_sflag(int sflag)
+static void
+process_sflag(int *sflag)
{
- if (sflag > 0) {
+ if (*sflag > 0) {
long n;
const VALUE *args;
VALUE argv = rb_argv;
@@ -878,9 +846,8 @@ process_sflag(int sflag)
while (n--) {
rb_ary_shift(argv);
}
- return -1;
+ *sflag = -1;
}
- return sflag;
}
static long proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt);
@@ -894,26 +861,14 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
VALUE argstr, argary;
void *ptr;
- VALUE src_enc_name = opt->src.enc.name;
- VALUE ext_enc_name = opt->ext.enc.name;
- VALUE int_enc_name = opt->intern.enc.name;
- ruby_features_t feat = opt->features;
- ruby_features_t warn = opt->warn;
- long backtrace_length_limit = opt->backtrace_length_limit;
- const char *crash_report = opt->crash_report;
-
while (ISSPACE(*s)) s++;
if (!*s) return;
-
- opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0;
-
- const int hyphen = *s != '-';
- argstr = rb_str_tmp_new((len = strlen(s)) + hyphen);
+ argstr = rb_str_tmp_new((len = strlen(s)) + (envopt!=0));
argary = rb_str_tmp_new(0);
p = RSTRING_PTR(argstr);
- if (hyphen) *p = '-';
- memcpy(p + hyphen, s, len + 1);
+ if (envopt) *p++ = ' ';
+ memcpy(p, s, len + 1);
ap = 0;
rb_str_cat(argary, (char *)&ap, sizeof(ap));
while (*p) {
@@ -941,24 +896,6 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
}
}
- if (src_enc_name) {
- opt->src.enc.name = src_enc_name;
- }
- if (ext_enc_name) {
- opt->ext.enc.name = ext_enc_name;
- }
- if (int_enc_name) {
- opt->intern.enc.name = int_enc_name;
- }
- FEATURE_SET_RESTORE(opt->features, feat);
- FEATURE_SET_RESTORE(opt->warn, warn);
- if (BACKTRACE_LENGTH_LIMIT_VALID_P(backtrace_length_limit)) {
- opt->backtrace_length_limit = backtrace_length_limit;
- }
- if (crash_report) {
- opt->crash_report = crash_report;
- }
-
ruby_xfree(ptr);
/* get rid of GC */
rb_str_resize(argary, 0);
@@ -1022,7 +959,7 @@ feature_option(const char *str, int len, void *arg, const unsigned int enable)
goto found;
}
if (NAME_MATCH_P("all", str, len)) {
- // YJIT and RJIT cannot be enabled at the same time. We enable only one for --enable=all.
+ // YJIT and MJIT cannot be enabled at the same time. We enable only one for --enable=all.
mask &= ~feature_jit_mask | FEATURE_BIT(jit);
goto found;
}
@@ -1182,326 +1119,6 @@ setup_yjit_options(const char *s)
}
#endif
-/*
- * Following proc_*_option functions are tree kinds:
- *
- * - with a required argument, takes also `argc` and `argv`, and
- * returns the number of consumed argv including the option itself.
- *
- * - with a mandatory argument just after the option.
- *
- * - no required argument, this returns the address of
- * the next character after the last consumed character.
- */
-
-/* optional */
-static const char *
-proc_W_option(ruby_cmdline_options_t *opt, const char *s, int *warning)
-{
- if (s[1] == ':') {
- unsigned int bits = 0;
- static const char no_prefix[] = "no-";
- int enable = strncmp(s += 2, no_prefix, sizeof(no_prefix)-1) != 0;
- if (!enable) s += sizeof(no_prefix)-1;
- size_t len = strlen(s);
- if (NAME_MATCH_P("deprecated", s, len)) {
- bits = 1U << RB_WARN_CATEGORY_DEPRECATED;
- }
- else if (NAME_MATCH_P("experimental", s, len)) {
- bits = 1U << RB_WARN_CATEGORY_EXPERIMENTAL;
- }
- else if (NAME_MATCH_P("performance", s, len)) {
- bits = 1U << RB_WARN_CATEGORY_PERFORMANCE;
- }
- else {
- rb_warn("unknown warning category: `%s'", s);
- }
- if (bits) FEATURE_SET_TO(opt->warn, bits, enable ? bits : 0);
- return 0;
- }
- else {
- size_t numlen;
- int v = 2; /* -W as -W2 */
-
- if (*++s) {
- v = scan_oct(s, 1, &numlen);
- if (numlen == 0)
- v = 2;
- s += numlen;
- }
- if (!opt->warning) {
- switch (v) {
- case 0:
- ruby_verbose = Qnil;
- break;
- case 1:
- ruby_verbose = Qfalse;
- break;
- default:
- ruby_verbose = Qtrue;
- break;
- }
- }
- *warning = 1;
- switch (v) {
- case 0:
- FEATURE_SET_TO(opt->warn, RB_WARN_CATEGORY_DEFAULT_BITS, 0);
- break;
- case 1:
- FEATURE_SET_TO(opt->warn, 1U << RB_WARN_CATEGORY_DEPRECATED, 0);
- break;
- default:
- FEATURE_SET(opt->warn, RB_WARN_CATEGORY_DEFAULT_BITS);
- break;
- }
- return s;
- }
-}
-
-/* required */
-static long
-proc_e_option(ruby_cmdline_options_t *opt, const char *s, long argc, char **argv)
-{
- long n = 1;
- forbid_setid("-e");
- if (!*++s) {
- if (!--argc)
- rb_raise(rb_eRuntimeError, "no code specified for -e");
- s = *++argv;
- n++;
- }
- if (!opt->e_script) {
- opt->e_script = rb_str_new(0, 0);
- if (opt->script == 0)
- opt->script = "-e";
- }
- rb_str_cat2(opt->e_script, s);
- rb_str_cat2(opt->e_script, "\n");
- return n;
-}
-
-/* optional */
-static const char *
-proc_K_option(ruby_cmdline_options_t *opt, const char *s)
-{
- if (*++s) {
- const char *enc_name = 0;
- switch (*s) {
- case 'E': case 'e':
- enc_name = "EUC-JP";
- break;
- case 'S': case 's':
- enc_name = "Windows-31J";
- break;
- case 'U': case 'u':
- enc_name = "UTF-8";
- break;
- case 'N': case 'n': case 'A': case 'a':
- enc_name = "ASCII-8BIT";
- break;
- }
- if (enc_name) {
- opt->src.enc.name = rb_str_new2(enc_name);
- if (!opt->ext.enc.name)
- opt->ext.enc.name = opt->src.enc.name;
- }
- s++;
- }
- return s;
-}
-
-/* optional */
-static const char *
-proc_0_option(ruby_cmdline_options_t *opt, const char *s)
-{
- size_t numlen;
- int v;
- char c;
-
- v = scan_oct(s, 4, &numlen);
- s += numlen;
- if (v > 0377)
- rb_rs = Qnil;
- else if (v == 0 && numlen >= 2) {
- rb_rs = rb_str_new2("");
- }
- else {
- c = v & 0xff;
- rb_rs = rb_str_new(&c, 1);
- }
- return s;
-}
-
-/* mandatory */
-static void
-proc_encoding_option(ruby_cmdline_options_t *opt, const char *s, const char *opt_name)
-{
- char *p;
-# define set_encoding_part(type) \
- if (!(p = strchr(s, ':'))) { \
- set_##type##_encoding_once(opt, s, 0); \
- return; \
- } \
- else if (p > s) { \
- set_##type##_encoding_once(opt, s, p-s); \
- }
- set_encoding_part(external);
- if (!*(s = ++p)) return;
- set_encoding_part(internal);
- if (!*(s = ++p)) return;
-#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
- set_encoding_part(source);
- if (!*(s = ++p)) return;
-#endif
- rb_raise(rb_eRuntimeError, "extra argument for %s: %s", opt_name, s);
-# undef set_encoding_part
- UNREACHABLE;
-}
-
-static long
-proc_long_options(ruby_cmdline_options_t *opt, const char *s, long argc, char **argv, int envopt)
-{
- size_t n;
- long argc0 = argc;
-# define is_option_end(c, allow_hyphen) \
- (!(c) || ((allow_hyphen) && (c) == '-') || (c) == '=')
-# define check_envopt(name, allow_envopt) \
- (((allow_envopt) || !envopt) ? (void)0 : \
- rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
-# define need_argument(name, s, needs_arg, next_arg) \
- ((*(s) ? !*++(s) : (next_arg) && (!argc || !((s) = argv[1]) || (--argc, ++argv, 0))) && (needs_arg) ? \
- rb_raise(rb_eRuntimeError, "missing argument for --" name) \
- : (void)0)
-# define is_option_with_arg(name, allow_hyphen, allow_envopt) \
- is_option_with_optarg(name, allow_hyphen, allow_envopt, Qtrue, Qtrue)
-# define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg) \
- (strncmp((name), s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], (allow_hyphen)) && \
- (s[n] != '-' || s[n+1]) ? \
- (check_envopt(name, (allow_envopt)), s += n, \
- need_argument(name, s, needs_arg, next_arg), 1) : 0)
-
- if (strcmp("copyright", s) == 0) {
- if (envopt) goto noenvopt_long;
- opt->dump |= DUMP_BIT(copyright);
- }
- else if (is_option_with_optarg("debug", Qtrue, Qtrue, Qfalse, Qfalse)) {
- if (s && *s) {
- ruby_each_words(s, debug_option, &opt->features);
- }
- else {
- ruby_debug = Qtrue;
- ruby_verbose = Qtrue;
- }
- }
- else if (is_option_with_arg("enable", Qtrue, Qtrue)) {
- ruby_each_words(s, enable_option, &opt->features);
- }
- else if (is_option_with_arg("disable", Qtrue, Qtrue)) {
- ruby_each_words(s, disable_option, &opt->features);
- }
- else if (is_option_with_arg("encoding", Qfalse, Qtrue)) {
- proc_encoding_option(opt, s, "--encoding");
- }
- else if (is_option_with_arg("internal-encoding", Qfalse, Qtrue)) {
- set_internal_encoding_once(opt, s, 0);
- }
- else if (is_option_with_arg("external-encoding", Qfalse, Qtrue)) {
- set_external_encoding_once(opt, s, 0);
- }
- else if (is_option_with_arg("parser", Qfalse, Qtrue)) {
- if (strcmp("prism", s) == 0) {
- (*rb_ruby_prism_ptr()) = true;
- rb_warn("The compiler based on the Prism parser is currently experimental and "
- "compatibility with the compiler based on parse.y "
- "is not yet complete. Please report any issues you "
- "find on the `ruby/prism` issue tracker.");
- }
- else if (strcmp("parse.y", s) == 0) {
- // default behavior
- }
- else {
- rb_raise(rb_eRuntimeError, "unknown parser %s", s);
- }
- }
-#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
- else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
- set_source_encoding_once(opt, s, 0);
- }
-#endif
- else if (strcmp("version", s) == 0) {
- if (envopt) goto noenvopt_long;
- opt->dump |= DUMP_BIT(version);
- }
- else if (strcmp("verbose", s) == 0) {
- opt->verbose = 1;
- ruby_verbose = Qtrue;
- }
- else if (strcmp("jit", s) == 0) {
-#if USE_YJIT || USE_RJIT
- FEATURE_SET(opt->features, FEATURE_BIT(jit));
-#else
- rb_warn("Ruby was built without JIT support");
-#endif
- }
- else if (is_option_with_optarg("rjit", '-', true, false, false)) {
-#if USE_RJIT
- extern void rb_rjit_setup_options(const char *s, struct rb_rjit_options *rjit_opt);
- FEATURE_SET(opt->features, FEATURE_BIT(rjit));
- rb_rjit_setup_options(s, &opt->rjit);
-#else
- rb_warn("RJIT support is disabled.");
-#endif
- }
- else if (is_option_with_optarg("yjit", '-', true, false, false)) {
-#if USE_YJIT
- FEATURE_SET(opt->features, FEATURE_BIT(yjit));
- setup_yjit_options(s);
-#else
- rb_warn("Ruby was built without YJIT support."
- " You may need to install rustc to build Ruby with YJIT.");
-#endif
- }
- else if (strcmp("yydebug", s) == 0) {
- if (envopt) goto noenvopt_long;
- opt->dump |= DUMP_BIT(yydebug);
- }
- else if (is_option_with_arg("dump", Qfalse, Qfalse)) {
- ruby_each_words(s, dump_option, &opt->dump);
- }
- else if (strcmp("help", s) == 0) {
- if (envopt) goto noenvopt_long;
- opt->dump |= DUMP_BIT(help);
- return 0;
- }
- else if (is_option_with_arg("backtrace-limit", Qfalse, Qtrue)) {
- char *e;
- long n = strtol(s, &e, 10);
- if (errno == ERANGE || !BACKTRACE_LENGTH_LIMIT_VALID_P(n) || *e) {
- rb_raise(rb_eRuntimeError, "wrong limit for backtrace length");
- }
- else {
- opt->backtrace_length_limit = n;
- }
- }
- else if (is_option_with_arg("crash-report", true, true)) {
- opt->crash_report = s;
- }
- else {
- rb_raise(rb_eRuntimeError,
- "invalid option --%s (-h will show valid options)", s);
- }
- return argc0 - argc + 1;
-
- noenvopt_long:
- rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s);
-# undef is_option_end
-# undef check_envopt
-# undef need_argument
-# undef is_option_with_arg
-# undef is_option_with_optarg
- UNREACHABLE_RETURN(0);
-}
-
static long
proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
{
@@ -1560,12 +1177,65 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
warning = 1;
ruby_verbose = Qtrue;
}
- FEATURE_SET(opt->warn, RB_WARN_CATEGORY_DEFAULT_BITS);
+ FEATURE_SET(opt->warn, RB_WARN_CATEGORY_ALL_BITS);
s++;
goto reswitch;
case 'W':
- if (!(s = proc_W_option(opt, s, &warning))) break;
+ if (s[1] == ':') {
+ unsigned int bits = 0;
+ static const char no_prefix[] = "no-";
+ int enable = strncmp(s += 2, no_prefix, sizeof(no_prefix)-1) != 0;
+ if (!enable) s += sizeof(no_prefix)-1;
+ size_t len = strlen(s);
+ if (NAME_MATCH_P("deprecated", s, len)) {
+ bits = 1U << RB_WARN_CATEGORY_DEPRECATED;
+ }
+ else if (NAME_MATCH_P("experimental", s, len)) {
+ bits = 1U << RB_WARN_CATEGORY_EXPERIMENTAL;
+ }
+ else {
+ rb_warn("unknown warning category: `%s'", s);
+ }
+ if (bits) FEATURE_SET_TO(opt->warn, bits, enable ? bits : 0);
+ break;
+ }
+ {
+ size_t numlen;
+ int v = 2; /* -W as -W2 */
+
+ if (*++s) {
+ v = scan_oct(s, 1, &numlen);
+ if (numlen == 0)
+ v = 2;
+ s += numlen;
+ }
+ if (!opt->warning) {
+ switch (v) {
+ case 0:
+ ruby_verbose = Qnil;
+ break;
+ case 1:
+ ruby_verbose = Qfalse;
+ break;
+ default:
+ ruby_verbose = Qtrue;
+ break;
+ }
+ }
+ warning = 1;
+ switch (v) {
+ case 0:
+ FEATURE_SET_TO(opt->warn, RB_WARN_CATEGORY_ALL_BITS, 0);
+ break;
+ case 1:
+ FEATURE_SET_TO(opt->warn, 1U << RB_WARN_CATEGORY_DEPRECATED, 0);
+ break;
+ default:
+ FEATURE_SET(opt->warn, RB_WARN_CATEGORY_ALL_BITS);
+ break;
+ }
+ }
goto reswitch;
case 'c':
@@ -1602,10 +1272,19 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
case 'e':
if (envopt) goto noenvopt;
- if (!(n = proc_e_option(opt, s, argc, argv))) break;
- --n;
- argc -= n;
- argv += n;
+ forbid_setid("-e");
+ if (!*++s) {
+ if (!--argc)
+ rb_raise(rb_eRuntimeError, "no code specified for -e");
+ s = *++argv;
+ }
+ if (!opt->e_script) {
+ opt->e_script = rb_str_new(0, 0);
+ if (opt->script == 0)
+ opt->script = "-e";
+ }
+ rb_str_cat2(opt->e_script, s);
+ rb_str_cat2(opt->e_script, "\n");
break;
case 'r':
@@ -1657,8 +1336,7 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
if (!*++s && (!--argc || !(s = *++argv))) {
rb_raise(rb_eRuntimeError, "missing argument for -E");
}
- proc_encoding_option(opt, s, "-E");
- break;
+ goto encoding;
case 'U':
set_internal_encoding_once(opt, "UTF-8", 0);
@@ -1666,7 +1344,29 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
goto reswitch;
case 'K':
- if (!(s = proc_K_option(opt, s))) break;
+ if (*++s) {
+ const char *enc_name = 0;
+ switch (*s) {
+ case 'E': case 'e':
+ enc_name = "EUC-JP";
+ break;
+ case 'S': case 's':
+ enc_name = "Windows-31J";
+ break;
+ case 'U': case 'u':
+ enc_name = "UTF-8";
+ break;
+ case 'N': case 'n': case 'A': case 'a':
+ enc_name = "ASCII-8BIT";
+ break;
+ }
+ if (enc_name) {
+ opt->src.enc.name = rb_str_new2(enc_name);
+ if (!opt->ext.enc.name)
+ opt->ext.enc.name = opt->src.enc.name;
+ }
+ s++;
+ }
goto reswitch;
case 'I':
@@ -1681,7 +1381,23 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
case '0':
if (envopt) goto noenvopt;
- if (!(s = proc_0_option(opt, s))) break;
+ {
+ size_t numlen;
+ int v;
+ char c;
+
+ v = scan_oct(s, 4, &numlen);
+ s += numlen;
+ if (v > 0377)
+ rb_rs = Qnil;
+ else if (v == 0 && numlen >= 2) {
+ rb_rs = rb_str_new2("");
+ }
+ else {
+ c = v & 0xff;
+ rb_rs = rb_str_new(&c, 1);
+ }
+ }
goto reswitch;
case '-':
@@ -1691,10 +1407,133 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
}
s++;
- if (!(n = proc_long_options(opt, s, argc, argv, envopt))) goto switch_end;
- --n;
- argc -= n;
- argv += n;
+# define is_option_end(c, allow_hyphen) \
+ (!(c) || ((allow_hyphen) && (c) == '-') || (c) == '=')
+# define check_envopt(name, allow_envopt) \
+ (((allow_envopt) || !envopt) ? (void)0 : \
+ rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
+# define need_argument(name, s, needs_arg, next_arg) \
+ ((*(s) ? !*++(s) : (next_arg) && (!argc || !((s) = argv[1]) || (--argc, ++argv, 0))) && (needs_arg) ? \
+ rb_raise(rb_eRuntimeError, "missing argument for --" name) \
+ : (void)0)
+# define is_option_with_arg(name, allow_hyphen, allow_envopt) \
+ is_option_with_optarg(name, allow_hyphen, allow_envopt, Qtrue, Qtrue)
+# define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg) \
+ (strncmp((name), s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], (allow_hyphen)) && \
+ (s[n] != '-' || s[n+1]) ? \
+ (check_envopt(name, (allow_envopt)), s += n, \
+ need_argument(name, s, needs_arg, next_arg), 1) : 0)
+
+ if (strcmp("copyright", s) == 0) {
+ if (envopt) goto noenvopt_long;
+ opt->dump |= DUMP_BIT(copyright);
+ }
+ else if (is_option_with_optarg("debug", Qtrue, Qtrue, Qfalse, Qfalse)) {
+ if (s && *s) {
+ ruby_each_words(s, debug_option, &opt->features);
+ }
+ else {
+ ruby_debug = Qtrue;
+ ruby_verbose = Qtrue;
+ }
+ }
+ else if (is_option_with_arg("enable", Qtrue, Qtrue)) {
+ ruby_each_words(s, enable_option, &opt->features);
+ }
+ else if (is_option_with_arg("disable", Qtrue, Qtrue)) {
+ ruby_each_words(s, disable_option, &opt->features);
+ }
+ else if (is_option_with_arg("encoding", Qfalse, Qtrue)) {
+ char *p;
+ encoding:
+ do {
+# define set_encoding_part(type) \
+ if (!(p = strchr(s, ':'))) { \
+ set_##type##_encoding_once(opt, s, 0); \
+ break; \
+ } \
+ else if (p > s) { \
+ set_##type##_encoding_once(opt, s, p-s); \
+ }
+ set_encoding_part(external);
+ if (!*(s = ++p)) break;
+ set_encoding_part(internal);
+ if (!*(s = ++p)) break;
+#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
+ set_encoding_part(source);
+ if (!*(s = ++p)) break;
+#endif
+ rb_raise(rb_eRuntimeError, "extra argument for %s: %s",
+ (arg[1] == '-' ? "--encoding" : "-E"), s);
+# undef set_encoding_part
+ } while (0);
+ }
+ else if (is_option_with_arg("internal-encoding", Qfalse, Qtrue)) {
+ set_internal_encoding_once(opt, s, 0);
+ }
+ else if (is_option_with_arg("external-encoding", Qfalse, Qtrue)) {
+ set_external_encoding_once(opt, s, 0);
+ }
+#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
+ else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
+ set_source_encoding_once(opt, s, 0);
+ }
+#endif
+ else if (strcmp("version", s) == 0) {
+ if (envopt) goto noenvopt_long;
+ opt->dump |= DUMP_BIT(version);
+ }
+ else if (strcmp("verbose", s) == 0) {
+ opt->verbose = 1;
+ ruby_verbose = Qtrue;
+ }
+ else if (strcmp("jit", s) == 0) {
+#if !USE_MJIT
+ rb_warn("Ruby was built without JIT support");
+#else
+ FEATURE_SET(opt->features, FEATURE_BIT(jit));
+#endif
+ }
+ else if (is_option_with_optarg("mjit", '-', true, false, false)) {
+#if USE_MJIT
+ extern void mjit_setup_options(const char *s, struct mjit_options *mjit_opt);
+ FEATURE_SET(opt->features, FEATURE_BIT(mjit));
+ mjit_setup_options(s, &opt->mjit);
+#else
+ rb_warn("MJIT support is disabled.");
+#endif
+ }
+ else if (is_option_with_optarg("yjit", '-', true, false, false)) {
+#if USE_YJIT
+ FEATURE_SET(opt->features, FEATURE_BIT(yjit));
+ setup_yjit_options(s);
+#else
+ rb_warn("Ruby was built without YJIT support."
+ " You may need to install rustc to build Ruby with YJIT.");
+#endif
+ }
+ else if (strcmp("yydebug", s) == 0) {
+ if (envopt) goto noenvopt_long;
+ opt->dump |= DUMP_BIT(yydebug);
+ }
+ else if (is_option_with_arg("dump", Qfalse, Qfalse)) {
+ ruby_each_words(s, dump_option, &opt->dump);
+ }
+ else if (strcmp("help", s) == 0) {
+ if (envopt) goto noenvopt_long;
+ opt->dump |= DUMP_BIT(help);
+ goto switch_end;
+ }
+ else if (is_option_with_arg("backtrace-limit", Qfalse, Qfalse)) {
+ char *e;
+ long n = strtol(s, &e, 10);
+ if (errno == ERANGE || n < 0 || *e) rb_raise(rb_eRuntimeError, "wrong limit for backtrace length");
+ rb_backtrace_length_limit = n;
+ }
+ else {
+ rb_raise(rb_eRuntimeError,
+ "invalid option --%s (-h will show valid options)", s);
+ }
break;
case '\r':
@@ -1702,9 +1541,11 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
break;
default:
- rb_raise(rb_eRuntimeError,
- "invalid option -%c (-h will show valid options)",
- (int)(unsigned char)*s);
+ {
+ rb_raise(rb_eRuntimeError,
+ "invalid option -%c (-h will show valid options)",
+ (int)(unsigned char)*s);
+ }
goto switch_end;
noenvopt:
@@ -1712,8 +1553,17 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s);
break;
+ noenvopt_long:
+ rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s);
+ break;
+
case 0:
break;
+# undef is_option_end
+# undef check_envopt
+# undef need_argument
+# undef is_option_with_arg
+# undef is_option_with_optarg
}
}
@@ -1763,26 +1613,10 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
rb_warning_category_update(opt->warn.mask, opt->warn.set);
- /* [Feature #19785] Warning for removed GC environment variable.
- * Remove this in Ruby 3.4. */
- if (getenv("RUBY_GC_HEAP_INIT_SLOTS")) {
- rb_warn_deprecated("The environment variable RUBY_GC_HEAP_INIT_SLOTS",
- "environment variables RUBY_GC_HEAP_%d_INIT_SLOTS");
- }
-
- if (getenv("RUBY_FREE_AT_EXIT")) {
- rb_warn("Free at exit is experimental and may be unstable");
- rb_free_at_exit = true;
- }
-
-#if USE_RJIT
- // rb_call_builtin_inits depends on RubyVM::RJIT.enabled?
- if (opt->rjit.on)
- rb_rjit_enabled = true;
- if (opt->rjit.stats)
- rb_rjit_stats_enabled = true;
- if (opt->rjit.trace_exits)
- rb_rjit_trace_exits_enabled = true;
+#if USE_MJIT
+ // rb_call_builtin_inits depends on RubyVM::MJIT.enabled?
+ if (opt->mjit.on)
+ mjit_enabled = true;
#endif
Init_ext(); /* load statically linked extensions before rubygems */
@@ -1791,14 +1625,19 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
ruby_init_prelude();
// Initialize JITs after prelude because JITing prelude is typically not optimal.
-#if USE_RJIT
- // Also, rb_rjit_init is safe only after rb_call_builtin_inits() defines RubyVM::RJIT::Compiler.
- if (opt->rjit.on)
- rb_rjit_init(&opt->rjit);
+#if USE_MJIT
+ // Also, mjit_init is safe only after rb_call_builtin_inits() defines RubyVM::MJIT::Compiler.
+ if (opt->mjit.on)
+ mjit_init(&opt->mjit);
#endif
#if USE_YJIT
- rb_yjit_init(opt->yjit);
+ if (opt->yjit)
+ rb_yjit_init();
#endif
+ // rb_threadptr_root_fiber_setup for the initial thread is called before rb_yjit_enabled_p()
+ // or mjit_enabled becomes true, meaning jit_cont_new is skipped for the initial root fiber.
+ // Therefore we need to call this again here to set the initial root fiber's jit_cont.
+ rb_jit_cont_init(); // must be after mjit_enabled = true and rb_yjit_init()
ruby_set_script_name(opt->script_name);
require_libraries(&opt->req_list);
@@ -1930,10 +1769,7 @@ rb_f_chomp(int argc, VALUE *argv, VALUE _)
static void
setup_pager_env(void)
{
- if (!getenv("LESS")) {
- // Output "raw" control characters, and move per sections.
- ruby_setenv("LESS", "-R +/^[A-Z].*");
- }
+ if (!getenv("LESS")) ruby_setenv("LESS", "-R"); // Output "raw" control characters.
}
#ifdef _WIN32
@@ -1984,8 +1820,6 @@ env_var_truthy(const char *name)
}
#endif
-rb_pid_t rb_fork_ruby(int *status);
-
static VALUE
process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
{
@@ -2022,7 +1856,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
#ifdef HAVE_WORKING_FORK
int fds[2];
if (rb_pipe(fds) == 0) {
- rb_pid_t pid = rb_fork_ruby(NULL);
+ rb_pid_t pid = rb_fork();
if (pid > 0) {
/* exec PAGER with reading from child */
dup2(fds[0], 0);
@@ -2069,7 +1903,22 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
argv += i;
if (FEATURE_SET_P(opt->features, rubyopt) && (s = getenv("RUBYOPT"))) {
+ VALUE src_enc_name = opt->src.enc.name;
+ VALUE ext_enc_name = opt->ext.enc.name;
+ VALUE int_enc_name = opt->intern.enc.name;
+ ruby_features_t feat = opt->features;
+ ruby_features_t warn = opt->warn;
+
+ opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0;
moreswitches(s, opt, 1);
+ if (src_enc_name)
+ opt->src.enc.name = src_enc_name;
+ if (ext_enc_name)
+ opt->ext.enc.name = ext_enc_name;
+ if (int_enc_name)
+ opt->intern.enc.name = int_enc_name;
+ FEATURE_SET_RESTORE(opt->features, feat);
+ FEATURE_SET_RESTORE(opt->warn, warn);
}
if (opt->src.enc.name)
@@ -2086,25 +1935,21 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
#endif
}
if (MULTI_BITS_P(FEATURE_SET_BITS(opt->features) & feature_jit_mask)) {
- rb_warn("RJIT and YJIT cannot both be enabled at the same time. Exiting");
+ rb_warn("MJIT and YJIT cannot both be enabled at the same time. Exiting");
return Qfalse;
}
-#if USE_RJIT
- if (FEATURE_SET_P(opt->features, rjit)) {
- opt->rjit.on = true; // set opt->rjit.on for Init_ruby_description() and calling rb_rjit_init()
+#if USE_MJIT
+ if (FEATURE_SET_P(opt->features, mjit)) {
+ opt->mjit.on = true; // set opt->mjit.on for Init_ruby_description() and calling mjit_init()
}
#endif
#if USE_YJIT
if (FEATURE_SET_P(opt->features, yjit)) {
- bool rb_yjit_option_disable(void);
- opt->yjit = !rb_yjit_option_disable(); // set opt->yjit for Init_ruby_description() and calling rb_yjit_init()
+ opt->yjit = true; // set opt->yjit for Init_ruby_description() and calling rb_yjit_init()
}
#endif
-
- ruby_mn_threads_params();
Init_ruby_description(opt);
-
if (opt->dump & (DUMP_BIT(version) | DUMP_BIT(version_v))) {
ruby_show_version();
if (opt->dump & DUMP_BIT(version)) return Qtrue;
@@ -2259,43 +2104,39 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
#undef SET_COMPILE_OPTION
}
ruby_set_argv(argc, argv);
- opt->sflag = process_sflag(opt->sflag);
+ process_sflag(&opt->sflag);
- if (!(*rb_ruby_prism_ptr())) {
- if (opt->e_script) {
- VALUE progname = rb_progname;
- rb_encoding *eenc;
- rb_parser_set_context(parser, 0, TRUE);
+ if (opt->e_script) {
+ VALUE progname = rb_progname;
+ rb_encoding *eenc;
+ rb_parser_set_context(parser, 0, TRUE);
- if (opt->src.enc.index >= 0) {
- eenc = rb_enc_from_index(opt->src.enc.index);
- }
- else {
- eenc = lenc;
-#if UTF8_PATH
- if (ienc) eenc = ienc;
-#endif
- }
+ if (opt->src.enc.index >= 0) {
+ eenc = rb_enc_from_index(opt->src.enc.index);
+ }
+ else {
+ eenc = lenc;
#if UTF8_PATH
- if (eenc != uenc) {
- opt->e_script = str_conv_enc(opt->e_script, uenc, eenc);
- }
+ if (ienc) eenc = ienc;
#endif
- rb_enc_associate(opt->e_script, eenc);
- ruby_opt_init(opt);
- ruby_set_script_name(progname);
- rb_parser_set_options(parser, opt->do_print, opt->do_loop,
- opt->do_line, opt->do_split);
- ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
}
- else {
- VALUE f;
- int xflag = opt->xflag;
- f = open_load_file(script_name, &xflag);
- opt->xflag = xflag != 0;
- rb_parser_set_context(parser, 0, f == rb_stdin);
- ast = load_file(parser, opt->script_name, f, 1, opt);
+#if UTF8_PATH
+ if (eenc != uenc) {
+ opt->e_script = str_conv_enc(opt->e_script, uenc, eenc);
}
+#endif
+ rb_enc_associate(opt->e_script, eenc);
+ ruby_opt_init(opt);
+ ruby_set_script_name(progname);
+ rb_parser_set_options(parser, opt->do_print, opt->do_loop,
+ opt->do_line, opt->do_split);
+ ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
+ }
+ else {
+ VALUE f;
+ f = open_load_file(script_name, &opt->xflag);
+ rb_parser_set_context(parser, 0, f == rb_stdin);
+ ast = load_file(parser, opt->script_name, f, 1, opt);
}
ruby_set_script_name(opt->script_name);
if (dump & DUMP_BIT(yydebug)) {
@@ -2320,12 +2161,12 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_enc_set_default_internal(Qnil);
rb_stdio_set_default_encoding();
- if (!(*rb_ruby_prism_ptr()) && !ast->body.root) {
+ if (!ast->body.root) {
rb_ast_dispose(ast);
return Qfalse;
}
- opt->sflag = process_sflag(opt->sflag);
+ process_sflag(&opt->sflag);
opt->xflag = 0;
if (dump & DUMP_BIT(syntax)) {
@@ -2341,46 +2182,6 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_define_global_function("chomp", rb_f_chomp, -1);
}
- if (dump & (DUMP_BIT(prism_parsetree))) {
- pm_string_t input;
- pm_options_t options = { 0 };
-
- if (strcmp(opt->script, "-") == 0) {
- int xflag = opt->xflag;
- VALUE rb_source = open_load_file(opt->script_name, &xflag);
- opt->xflag = xflag != 0;
-
- rb_warn("Prism support for streaming code from stdin is not currently supported");
- pm_string_constant_init(&input, RSTRING_PTR(rb_source), RSTRING_LEN(rb_source));
- pm_options_filepath_set(&options, RSTRING_PTR(opt->script_name));
- }
- else if (opt->e_script) {
- pm_string_constant_init(&input, RSTRING_PTR(opt->e_script), RSTRING_LEN(opt->e_script));
- pm_options_filepath_set(&options, "-e");
- }
- else {
- pm_string_mapped_init(&input, RSTRING_PTR(opt->script_name));
- pm_options_filepath_set(&options, RSTRING_PTR(opt->script_name));
- }
-
- pm_parser_t parser;
- pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
-
- pm_node_t *node = pm_parse(&parser);
- pm_buffer_t output_buffer = { 0 };
-
- pm_prettyprint(&output_buffer, &parser, node);
- rb_io_write(rb_stdout, rb_str_new((const char *) output_buffer.value, output_buffer.length));
- rb_io_flush(rb_stdout);
-
- pm_buffer_free(&output_buffer);
- pm_node_destroy(&parser, node);
- pm_parser_free(&parser);
-
- pm_string_free(&input);
- pm_options_free(&options);
- }
-
if (dump & (DUMP_BIT(parsetree)|DUMP_BIT(parsetree_with_comment))) {
rb_io_write(rb_stdout, rb_parser_dump_tree(ast->body.root, dump & DUMP_BIT(parsetree_with_comment)));
rb_io_flush(rb_stdout);
@@ -2405,43 +2206,12 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
}
}
-
- if ((*rb_ruby_prism_ptr())) {
- pm_string_t input;
- pm_options_t options = { 0 };
-
- if (strcmp(opt->script, "-") == 0) {
- int xflag = opt->xflag;
- VALUE rb_source = open_load_file(opt->script_name, &xflag);
- opt->xflag = xflag != 0;
-
- rb_warn("Prism support for streaming code from stdin is not currently supported");
- pm_string_constant_init(&input, RSTRING_PTR(rb_source), RSTRING_LEN(rb_source));
- pm_options_filepath_set(&options, RSTRING_PTR(opt->script_name));
- }
- else if (opt->e_script) {
- pm_string_constant_init(&input, RSTRING_PTR(opt->e_script), RSTRING_LEN(opt->e_script));
- pm_options_filepath_set(&options, "-e");
- }
- else {
- pm_string_mapped_init(&input, RSTRING_PTR(opt->script_name));
- pm_options_filepath_set(&options, RSTRING_PTR(opt->script_name));
- }
-
- iseq = rb_iseq_new_main_prism(&input, &options, path);
- ruby_opt_init(opt);
-
- pm_string_free(&input);
- pm_options_free(&options);
- }
- else {
- rb_binding_t *toplevel_binding;
- GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
- toplevel_binding);
- const struct rb_block *base_block = toplevel_context(toplevel_binding);
- iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block), !(dump & DUMP_BIT(insns_without_opt)));
- rb_ast_dispose(ast);
- }
+ rb_binding_t *toplevel_binding;
+ GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
+ toplevel_binding);
+ const struct rb_block *base_block = toplevel_context(toplevel_binding);
+ iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block), !(dump & DUMP_BIT(insns_without_opt)));
+ rb_ast_dispose(ast);
}
if (dump & (DUMP_BIT(insns) | DUMP_BIT(insns_without_opt))) {
@@ -2452,10 +2222,6 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
}
if (opt->dump & dump_exit_bits) return Qtrue;
- if (OPT_BACKTRACE_LENGTH_LIMIT_VALID_P(opt)) {
- rb_backtrace_length_limit = opt->backtrace_length_limit;
- }
-
rb_define_readonly_boolean("$-p", opt->do_print);
rb_define_readonly_boolean("$-l", opt->do_line);
rb_define_readonly_boolean("$-a", opt->do_split);
@@ -2506,8 +2272,6 @@ struct load_file_arg {
VALUE f;
};
-VALUE rb_script_lines_for(VALUE path, bool add);
-
static VALUE
load_file_internal(VALUE argp_v)
{
@@ -2610,12 +2374,6 @@ load_file_internal(VALUE argp_v)
}
rb_parser_set_options(parser, opt->do_print, opt->do_loop,
opt->do_line, opt->do_split);
-
- VALUE lines = rb_script_lines_for(orig_fname, true);
- if (!NIL_P(lines)) {
- rb_parser_set_script_lines(parser, lines);
- }
-
if (NIL_P(f)) {
f = rb_str_new(0, 0);
rb_enc_associate(f, enc);
@@ -2779,9 +2537,7 @@ void *
rb_parser_load_file(VALUE parser, VALUE fname_v)
{
ruby_cmdline_options_t opt;
- int xflag = 0;
- VALUE f = open_load_file(fname_v, &xflag);
- cmdline_options_init(&opt)->xflag = xflag != 0;
+ VALUE f = open_load_file(fname_v, &cmdline_options_init(&opt)->xflag);
return load_file(parser, fname_v, f, 0, &opt);
}
@@ -2856,18 +2612,12 @@ external_str_new_cstr(const char *p)
#endif
}
-static void
-set_progname(VALUE name)
-{
- rb_orig_progname = rb_progname = name;
- rb_vm_set_progname(rb_progname);
-}
-
void
ruby_script(const char *name)
{
if (name) {
- set_progname(rb_str_freeze(external_str_new_cstr(name)));
+ rb_orig_progname = rb_progname = external_str_new_cstr(name);
+ rb_vm_set_progname(rb_progname);
}
}
@@ -2878,7 +2628,8 @@ ruby_script(const char *name)
void
ruby_set_script_name(VALUE name)
{
- set_progname(rb_str_new_frozen(name));
+ rb_orig_progname = rb_progname = rb_str_dup(name);
+ rb_vm_set_progname(rb_progname);
}
static void
@@ -2998,26 +2749,19 @@ ruby_process_options(int argc, char **argv)
VALUE iseq;
const char *script_name = (argc > 0 && argv[0]) ? argv[0] : ruby_engine;
- (*rb_ruby_prism_ptr()) = false;
-
if (!origarg.argv || origarg.argc <= 0) {
origarg.argc = argc;
origarg.argv = argv;
}
- set_progname(external_str_new_cstr(script_name)); /* for the time being */
+ ruby_script(script_name); /* for the time being */
rb_argv0 = rb_str_new4(rb_progname);
rb_gc_register_mark_object(rb_argv0);
+ iseq = process_options(argc, argv, cmdline_options_init(&opt));
#ifndef HAVE_SETPROCTITLE
ruby_init_setproctitle(argc, argv);
#endif
- iseq = process_options(argc, argv, cmdline_options_init(&opt));
-
- if (opt.crash_report && *opt.crash_report) {
- void ruby_set_crash_report(const char *template);
- ruby_set_crash_report(opt.crash_report);
- }
return (void*)(struct RData*)iseq;
}
diff --git a/ruby_parser.c b/ruby_parser.c
deleted file mode 100644
index 10286b51e7..0000000000
--- a/ruby_parser.c
+++ /dev/null
@@ -1,913 +0,0 @@
-/* This is a wrapper for parse.y */
-#ifdef UNIVERSAL_PARSER
-
-#include "internal.h"
-#include "internal/array.h"
-#include "internal/bignum.h"
-#include "internal/compile.h"
-#include "internal/complex.h"
-#include "internal/encoding.h"
-#include "internal/error.h"
-#include "internal/gc.h"
-#include "internal/hash.h"
-#include "internal/io.h"
-#include "internal/parse.h"
-#include "internal/rational.h"
-#include "internal/re.h"
-#include "internal/ruby_parser.h"
-#include "internal/string.h"
-#include "internal/symbol.h"
-#include "internal/thread.h"
-
-#include "ruby/ractor.h"
-#include "ruby/ruby.h"
-#include "ruby/util.h"
-#include "node.h"
-#include "internal.h"
-#include "vm_core.h"
-#include "symbol.h"
-
-struct ruby_parser {
- rb_parser_t *parser_params;
-};
-
-static void
-parser_mark(void *ptr)
-{
- struct ruby_parser *parser = (struct ruby_parser*)ptr;
- rb_ruby_parser_mark(parser->parser_params);
-}
-
-static void
-parser_free(void *ptr)
-{
- struct ruby_parser *parser = (struct ruby_parser*)ptr;
- rb_ruby_parser_free(parser->parser_params);
-}
-
-static size_t
-parser_memsize(const void *ptr)
-{
- struct ruby_parser *parser = (struct ruby_parser*)ptr;
- return rb_ruby_parser_memsize(parser->parser_params);
-}
-
-static const rb_data_type_t ruby_parser_data_type = {
- "parser",
- {
- parser_mark,
- parser_free,
- parser_memsize,
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
-};
-
-static void
-bignum_negate(VALUE b)
-{
- BIGNUM_NEGATE(b);
-}
-
-static int
-is_ascii_string2(VALUE str)
-{
- return is_ascii_string(str);
-}
-
-static void
-rational_set_num(VALUE r, VALUE n)
-{
- RATIONAL_SET_NUM(r, n);
-}
-
-static VALUE
-rational_get_num(VALUE obj)
-{
- return RRATIONAL(obj)->num;
-}
-
-static void
-rcomplex_set_real(VALUE cmp, VALUE r)
-{
- RCOMPLEX_SET_REAL(cmp, r);
-}
-
-static void
-rcomplex_set_imag(VALUE cmp, VALUE i)
-{
- RCOMPLEX_SET_IMAG(cmp, i);
-}
-
-static VALUE
-rcomplex_get_real(VALUE obj)
-{
- return RCOMPLEX(obj)->real;
-}
-
-static VALUE
-rcomplex_get_imag(VALUE obj)
-{
- return RCOMPLEX(obj)->imag;
-}
-
-RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
-static VALUE
-syntax_error_append(VALUE exc, VALUE file, int line, int column,
- void *enc, const char *fmt, va_list args)
-{
- return rb_syntax_error_append(exc, file, line, column, (rb_encoding *)enc, fmt, args);
-}
-
-static int
-local_defined(ID id, const void *p)
-{
- return rb_local_defined(id, (const rb_iseq_t *)p);
-}
-
-static int
-dvar_defined(ID id, const void *p)
-{
- return rb_dvar_defined(id, (const rb_iseq_t *)p);
-}
-
-static bool
-hash_literal_key_p(VALUE k)
-{
- switch (OBJ_BUILTIN_TYPE(k)) {
- case T_NODE:
- return false;
- default:
- return true;
- }
-}
-
-static int
-literal_cmp(VALUE val, VALUE lit)
-{
- if (val == lit) return 0;
- if (!hash_literal_key_p(val) || !hash_literal_key_p(lit)) return -1;
- return rb_iseq_cdhash_cmp(val, lit);
-}
-
-static st_index_t
-literal_hash(VALUE a)
-{
- if (!hash_literal_key_p(a)) return (st_index_t)a;
- return rb_iseq_cdhash_hash(a);
-}
-
-static int
-is_usascii_enc(void *enc)
-{
- return rb_is_usascii_enc((rb_encoding *)enc);
-}
-
-static int
-is_local_id2(ID id)
-{
- return is_local_id(id);
-}
-
-static int
-is_attrset_id2(ID id)
-{
- return is_attrset_id(id);
-}
-
-static int
-is_notop_id2(ID id)
-{
- return is_notop_id(id);
-}
-
-static VALUE
-enc_str_new(const char *ptr, long len, void *enc)
-{
- return rb_enc_str_new(ptr, len, (rb_encoding *)enc);
-}
-
-static int
-enc_isalnum(OnigCodePoint c, void *enc)
-{
- return rb_enc_isalnum(c, (rb_encoding *)enc);
-}
-
-static int
-enc_precise_mbclen(const char *p, const char *e, void *enc)
-{
- return rb_enc_precise_mbclen(p, e, (rb_encoding *)enc);
-}
-
-static int
-mbclen_charfound_p(int len)
-{
- return MBCLEN_CHARFOUND_P(len);
-}
-
-static const char *
-enc_name(void *enc)
-{
- return rb_enc_name((rb_encoding *)enc);
-}
-
-static char *
-enc_prev_char(const char *s, const char *p, const char *e, void *enc)
-{
- return rb_enc_prev_char(s, p, e, (rb_encoding *)enc);
-}
-
-static void *
-enc_get(VALUE obj)
-{
- return (void *)rb_enc_get(obj);
-}
-
-static int
-enc_asciicompat(void *enc)
-{
- return rb_enc_asciicompat((rb_encoding *)enc);
-}
-
-static void *
-utf8_encoding(void)
-{
- return (void *)rb_utf8_encoding();
-}
-
-static VALUE
-enc_associate(VALUE obj, void *enc)
-{
- return rb_enc_associate(obj, (rb_encoding *)enc);
-}
-
-static void *
-ascii8bit_encoding(void)
-{
- return (void *)rb_ascii8bit_encoding();
-}
-
-static int
-enc_codelen(int c, void *enc)
-{
- return rb_enc_codelen(c, (rb_encoding *)enc);
-}
-
-static VALUE
-enc_str_buf_cat(VALUE str, const char *ptr, long len, void *enc)
-{
- return rb_enc_str_buf_cat(str, ptr, len, (rb_encoding *)enc);
-}
-
-static int
-enc_mbcput(unsigned int c, void *buf, void *enc)
-{
- return rb_enc_mbcput(c, buf, (rb_encoding *)enc);
-}
-
-static void *
-enc_from_index(int idx)
-{
- return (void *)rb_enc_from_index(idx);
-}
-
-static int
-enc_isspace(OnigCodePoint c, void *enc)
-{
- return rb_enc_isspace(c, (rb_encoding *)enc);
-}
-
-static ID
-intern3(const char *name, long len, void *enc)
-{
- return rb_intern3(name, len, (rb_encoding *)enc);
-}
-
-static void *
-enc_compatible(VALUE str1, VALUE str2)
-{
- return (void *)rb_enc_compatible(str1, str2);
-}
-
-static VALUE
-enc_from_encoding(void *enc)
-{
- return rb_enc_from_encoding((rb_encoding *)enc);
-}
-
-static int
-encoding_get(VALUE obj)
-{
- return ENCODING_GET(obj);
-}
-
-static void
-encoding_set(VALUE obj, int encindex)
-{
- ENCODING_SET(obj, encindex);
-}
-
-static int
-encoding_is_ascii8bit(VALUE obj)
-{
- return ENCODING_IS_ASCII8BIT(obj);
-}
-
-static void *
-usascii_encoding(void)
-{
- return (void *)rb_usascii_encoding();
-}
-
-static int
-enc_symname_type(const char *name, long len, void *enc, unsigned int allowed_attrset)
-{
- return rb_enc_symname_type(name, len, (rb_encoding *)enc, allowed_attrset);
-}
-
-typedef struct {
- struct parser_params *parser;
- rb_encoding *enc;
- NODE *succ_block;
- const rb_code_location_t *loc;
-} reg_named_capture_assign_t;
-
-static int
-reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
- int back_num, int *back_refs, OnigRegex regex, void *arg0)
-{
- reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0;
- struct parser_params* p = arg->parser;
- rb_encoding *enc = arg->enc;
- const rb_code_location_t *loc = arg->loc;
- long len = name_end - name;
- const char *s = (const char *)name;
-
- return rb_reg_named_capture_assign_iter_impl(p, s, len, (void *)enc, &arg->succ_block, loc);
-}
-
-static NODE *
-reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc)
-{
- reg_named_capture_assign_t arg;
-
- arg.parser = p;
- arg.enc = rb_enc_get(regexp);
- arg.succ_block = 0;
- arg.loc = loc;
- onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
-
- if (!arg.succ_block) return 0;
- return RNODE_BLOCK(arg.succ_block)->nd_next;
-}
-
-static VALUE
-rbool(VALUE v)
-{
- return RBOOL(v);
-}
-
-static int
-undef_p(VALUE v)
-{
- return RB_UNDEF_P(v);
-}
-
-static int
-rtest(VALUE obj)
-{
- return (int)RB_TEST(obj);
-}
-
-static int
-nil_p(VALUE obj)
-{
- return (int)NIL_P(obj);
-}
-
-static int
-flonum_p(VALUE obj)
-{
- return (int)RB_FLONUM_P(obj);
-}
-
-static VALUE
-int2fix(long i)
-{
- return INT2FIX(i);
-}
-
-static VALUE
-syntax_error_new(void)
-{
- return rb_class_new_instance(0, 0, rb_eSyntaxError);
-}
-
-static int
-obj_frozen(VALUE obj)
-{
- return (int)RB_OBJ_FROZEN(obj);
-}
-
-static VALUE
-obj_write(VALUE old, VALUE *slot, VALUE young)
-{
- return RB_OBJ_WRITE(old, slot, young);
-}
-
-static VALUE
-obj_written(VALUE old, VALUE slot, VALUE young)
-{
- return RB_OBJ_WRITTEN(old, slot, young);
-}
-
-static VALUE
-default_rs(void)
-{
- return rb_default_rs;
-}
-
-static VALUE
-rational_raw1(VALUE x)
-{
- return rb_rational_raw1(x);
-}
-
-static void *
-memmove2(void *dest, const void *src, size_t t, size_t n)
-{
- return memmove(dest, src, rbimpl_size_mul_or_raise(t, n));
-}
-
-static void *
-nonempty_memcpy(void *dest, const void *src, size_t t, size_t n)
-{
- return ruby_nonempty_memcpy(dest, src, rbimpl_size_mul_or_raise(t, n));
-}
-
-static VALUE
-ruby_verbose2(void)
-{
- return ruby_verbose;
-}
-
-static int
-type_p(VALUE obj, int t)
-{
- return (int)RB_TYPE_P(obj, t);
-}
-
-static int
-fixnum_p(VALUE obj)
-{
- return (int)RB_FIXNUM_P(obj);
-}
-
-static int
-symbol_p(VALUE obj)
-{
- return (int)RB_SYMBOL_P(obj);
-}
-
-static void *
-zalloc(size_t elemsiz)
-{
- return ruby_xcalloc(1, elemsiz);
-}
-
-static void
-gc_guard(VALUE obj)
-{
- RB_GC_GUARD(obj);
-}
-
-static rb_imemo_tmpbuf_t *
-tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt)
-{
- return rb_imemo_tmpbuf_parser_heap(buf, old_heap, cnt);
-}
-
-static int
-special_const_p(VALUE obj)
-{
- return (int)RB_SPECIAL_CONST_P(obj);
-}
-
-static int
-builtin_type(VALUE obj)
-{
- return (int)RB_BUILTIN_TYPE(obj);
-}
-
-static rb_ast_t *
-ast_new(VALUE nb)
-{
- rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, nb);
- return ast;
-}
-
-static VALUE
-static_id2sym(ID id)
-{
- return (((VALUE)(id)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG);
-}
-
-static long
-str_coderange_scan_restartable(const char *s, const char *e, void *enc, int *cr)
-{
- return rb_str_coderange_scan_restartable(s, e, (rb_encoding *)enc, cr);
-}
-
-VALUE rb_io_gets_internal(VALUE io);
-extern VALUE rb_mRubyVMFrozenCore;
-VALUE rb_node_case_when_optimizable_literal(const NODE *const node);
-
-void
-rb_parser_config_initialize(rb_parser_config_t *config)
-{
- config->counter = 0;
-
- config->malloc = ruby_xmalloc;
- config->calloc = ruby_xcalloc;
- config->realloc = ruby_xrealloc;
- config->free = ruby_xfree;
- config->alloc_n = ruby_xmalloc2;
- config->alloc = ruby_xmalloc;
- config->realloc_n = ruby_xrealloc2;
- config->zalloc = zalloc;
- config->rb_memmove = memmove2;
- config->nonempty_memcpy = nonempty_memcpy;
- config->xmalloc_mul_add = rb_xmalloc_mul_add;
-
- config->tmpbuf_parser_heap = tmpbuf_parser_heap;
- config->ast_new = ast_new;
-
- config->compile_callback = rb_suppress_tracing;
- config->reg_named_capture_assign = reg_named_capture_assign;
-
- config->obj_freeze = rb_obj_freeze;
- config->obj_hide = rb_obj_hide;
- config->obj_frozen = obj_frozen;
- config->type_p = type_p;
- config->obj_freeze_raw = OBJ_FREEZE_RAW;
-
- config->fixnum_p = fixnum_p;
- config->symbol_p = symbol_p;
-
- config->attr_get = rb_attr_get;
-
- config->ary_new = rb_ary_new;
- config->ary_push = rb_ary_push;
- config->ary_new_from_args = rb_ary_new_from_args;
- config->ary_pop = rb_ary_pop;
- config->ary_last = rb_ary_last;
- config->ary_unshift = rb_ary_unshift;
- config->ary_new2 = rb_ary_new2;
- config->ary_entry = rb_ary_entry;
- config->ary_join = rb_ary_join;
- config->ary_reverse = rb_ary_reverse;
- config->ary_clear = rb_ary_clear;
- config->array_len = rb_array_len;
- config->array_aref = RARRAY_AREF;
-
- config->sym_intern_ascii_cstr = rb_sym_intern_ascii_cstr;
- config->make_temporary_id = rb_make_temporary_id;
- config->is_local_id = is_local_id2;
- config->is_attrset_id = is_attrset_id2;
- config->is_global_name_punct = is_global_name_punct;
- config->id_type = id_type;
- config->id_attrset = rb_id_attrset;
- config->intern = rb_intern;
- config->intern2 = rb_intern2;
- config->intern3 = intern3;
- config->intern_str = rb_intern_str;
- config->is_notop_id = is_notop_id2;
- config->enc_symname_type = enc_symname_type;
- config->str_intern = rb_str_intern;
- config->id2name = rb_id2name;
- config->id2str = rb_id2str;
- config->id2sym = rb_id2sym;
- config->sym2id = rb_sym2id;
-
- config->str_catf = rb_str_catf;
- config->str_cat_cstr = rb_str_cat_cstr;
- config->str_subseq = rb_str_subseq;
- config->str_dup = rb_str_dup;
- config->str_new_frozen = rb_str_new_frozen;
- config->str_buf_new = rb_str_buf_new;
- config->str_buf_cat = rb_str_buf_cat;
- config->str_modify = rb_str_modify;
- config->str_set_len = rb_str_set_len;
- config->str_cat = rb_str_cat;
- config->str_resize = rb_str_resize;
- config->str_new = rb_str_new;
- config->str_new_cstr = rb_str_new_cstr;
- config->fstring = rb_fstring;
- config->is_ascii_string = is_ascii_string2;
- config->enc_str_new = enc_str_new;
- config->enc_str_buf_cat = enc_str_buf_cat;
- config->str_buf_append = rb_str_buf_append;
- config->str_vcatf = rb_str_vcatf;
- config->string_value_cstr = rb_string_value_cstr;
- config->rb_sprintf = rb_sprintf;
- config->rstring_ptr = RSTRING_PTR;
- config->rstring_end = RSTRING_END;
- config->rstring_len = RSTRING_LEN;
- config->filesystem_str_new_cstr = rb_filesystem_str_new_cstr;
- config->obj_as_string = rb_obj_as_string;
-
- config->hash_clear = rb_hash_clear;
- config->hash_new = rb_hash_new;
- config->hash_aset = rb_hash_aset;
- config->hash_lookup = rb_hash_lookup;
- config->hash_delete = rb_hash_delete;
- config->ident_hash_new = rb_ident_hash_new;
-
- config->int2fix = int2fix;
-
- config->bignum_negate = bignum_negate;
- config->big_norm = rb_big_norm;
- config->cstr_to_inum = rb_cstr_to_inum;
-
- config->float_new = rb_float_new;
- config->float_value = rb_float_value;
-
- config->num2int = rb_num2int_inline;
- config->int_positive_pow = rb_int_positive_pow;
- config->int2num = rb_int2num_inline;
- config->fix2long = rb_fix2long;
-
- config->rational_new = rb_rational_new;
- config->rational_raw1 = rational_raw1;
- config->rational_set_num = rational_set_num;
- config->rational_get_num = rational_get_num;
-
- config->complex_raw = rb_complex_raw;
- config->rcomplex_set_real = rcomplex_set_real;
- config->rcomplex_set_imag = rcomplex_set_imag;
- config->rcomplex_get_real = rcomplex_get_real;
- config->rcomplex_get_imag = rcomplex_get_imag;
-
- config->stderr_tty_p = rb_stderr_tty_p;
- config->write_error_str = rb_write_error_str;
- config->default_rs = default_rs;
- config->io_write = rb_io_write;
- config->io_flush = rb_io_flush;
- config->io_puts = rb_io_puts;
- config->io_gets_internal= rb_io_gets_internal;
-
- config->debug_output_stdout = rb_ractor_stdout;
- config->debug_output_stderr = rb_ractor_stderr;
-
- config->is_usascii_enc = is_usascii_enc;
- config->enc_isalnum = enc_isalnum;
- config->enc_precise_mbclen = enc_precise_mbclen;
- config->mbclen_charfound_p = mbclen_charfound_p;
- config->enc_name = enc_name;
- config->enc_prev_char = enc_prev_char;
- config->enc_get = enc_get;
- config->enc_asciicompat = enc_asciicompat;
- config->utf8_encoding = utf8_encoding;
- config->enc_associate = enc_associate;
- config->ascii8bit_encoding = ascii8bit_encoding;
- config->enc_codelen = enc_codelen;
- config->enc_mbcput = enc_mbcput;
- config->char_to_option_kcode = rb_char_to_option_kcode;
- config->ascii8bit_encindex = rb_ascii8bit_encindex;
- config->enc_find_index = rb_enc_find_index;
- config->enc_from_index = enc_from_index;
- config->enc_associate_index = rb_enc_associate_index;
- config->enc_isspace = enc_isspace;
- config->enc_coderange_7bit = ENC_CODERANGE_7BIT;
- config->enc_coderange_unknown = ENC_CODERANGE_UNKNOWN;
- config->enc_coderange_broken = ENC_CODERANGE_BROKEN;
- config->enc_compatible = enc_compatible;
- config->enc_from_encoding = enc_from_encoding;
- config->encoding_get = encoding_get;
- config->encoding_set = encoding_set;
- config->encoding_is_ascii8bit = encoding_is_ascii8bit;
- config->usascii_encoding = usascii_encoding;
- config->enc_str_coderange = rb_enc_str_coderange;
-
- config->ractor_make_shareable = rb_ractor_make_shareable;
-
- config->local_defined = local_defined;
- config->dvar_defined = dvar_defined;
-
- config->literal_cmp = literal_cmp;
- config->literal_hash = literal_hash;
-
- config->builtin_class_name = rb_builtin_class_name;
- config->syntax_error_append = syntax_error_append;
- config->raise = rb_raise;
- config->syntax_error_new = syntax_error_new;
-
- config->errinfo = rb_errinfo;
- config->set_errinfo = rb_set_errinfo;
- config->exc_raise = rb_exc_raise;
- config->make_exception = rb_make_exception;
-
- config->sized_xfree = ruby_sized_xfree;
- config->sized_realloc_n = ruby_sized_realloc_n;
- config->obj_write = obj_write;
- config->obj_written = obj_written;
- config->gc_register_mark_object = rb_gc_register_mark_object;
- config->gc_guard = gc_guard;
- config->gc_mark = rb_gc_mark;
- config->gc_mark_movable = rb_gc_mark_movable;
- config->gc_location = rb_gc_location;
-
- config->reg_compile = rb_reg_compile;
- config->reg_check_preprocess = rb_reg_check_preprocess;
- config->memcicmp = rb_memcicmp;
-
- config->compile_warn = rb_compile_warn;
- config->compile_warning = rb_compile_warning;
- config->bug = rb_bug;
- config->fatal = rb_fatal;
- config->verbose = ruby_verbose2;
-
- config->make_backtrace = rb_make_backtrace;
-
- config->scan_hex = ruby_scan_hex;
- config->scan_oct = ruby_scan_oct;
- config->scan_digits = ruby_scan_digits;
- config->strtod = ruby_strtod;
-
- config->rbool = rbool;
- config->undef_p = undef_p;
- config->rtest = rtest;
- config->nil_p = nil_p;
- config->flonum_p = flonum_p;
- config->qnil = Qnil;
- config->qtrue = Qtrue;
- config->qfalse = Qfalse;
- config->qundef = Qundef;
- config->eArgError = rb_eArgError;
- config->mRubyVMFrozenCore = rb_mRubyVMFrozenCore;
- config->long2int = rb_long2int;
- config->special_const_p = special_const_p;
- config->builtin_type = builtin_type;
-
- config->node_case_when_optimizable_literal = rb_node_case_when_optimizable_literal;
-
- /* For Ripper */
- config->static_id2sym = static_id2sym;
- config->str_coderange_scan_restartable = str_coderange_scan_restartable;
-}
-
-VALUE
-rb_parser_new(void)
-{
- struct ruby_parser *parser;
- rb_parser_config_t *config;
- rb_parser_t *parser_params;
-
- config = rb_ruby_parser_config_new(ruby_xmalloc);
- rb_parser_config_initialize(config);
-
- /*
- * Create parser_params ahead of vparser because
- * rb_ruby_parser_new can run GC so if create vparser
- * first, parser_mark tries to mark not initialized parser_params.
- */
- parser_params = rb_ruby_parser_new(config);
- VALUE vparser = TypedData_Make_Struct(0, struct ruby_parser,
- &ruby_parser_data_type, parser);
- parser->parser_params = parser_params;
-
- return vparser;
-}
-
-void
-rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- rb_ruby_parser_set_options(parser->parser_params, print, loop, chomp, split);
-}
-
-VALUE
-rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- rb_ruby_parser_set_context(parser->parser_params, base, main);
- return vparser;
-}
-
-void
-rb_parser_set_script_lines(VALUE vparser, VALUE lines)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- rb_ruby_parser_set_script_lines(parser->parser_params, lines);
-}
-
-void
-rb_parser_error_tolerant(VALUE vparser)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- rb_ruby_parser_error_tolerant(parser->parser_params);
-}
-
-rb_ast_t*
-rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
-{
- struct ruby_parser *parser;
- rb_ast_t *ast;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- ast = rb_ruby_parser_compile_file_path(parser->parser_params, fname, file, start);
- RB_GC_GUARD(vparser);
-
- return ast;
-}
-
-void
-rb_parser_keep_tokens(VALUE vparser)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- rb_ruby_parser_keep_tokens(parser->parser_params);
-}
-
-rb_ast_t*
-rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start)
-{
- struct ruby_parser *parser;
- rb_ast_t *ast;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- ast = rb_ruby_parser_compile_generic(parser->parser_params, lex_gets, fname, input, start);
- RB_GC_GUARD(vparser);
-
- return ast;
-}
-
-rb_ast_t*
-rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
-{
- struct ruby_parser *parser;
- rb_ast_t *ast;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- ast = rb_ruby_parser_compile_string(parser->parser_params, f, s, line);
- RB_GC_GUARD(vparser);
-
- return ast;
-}
-
-rb_ast_t*
-rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
-{
- struct ruby_parser *parser;
- rb_ast_t *ast;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- ast = rb_ruby_parser_compile_string_path(parser->parser_params, f, s, line);
- RB_GC_GUARD(vparser);
-
- return ast;
-}
-
-VALUE
-rb_parser_encoding(VALUE vparser)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- return rb_ruby_parser_encoding(parser->parser_params);
-}
-
-VALUE
-rb_parser_end_seen_p(VALUE vparser)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- return RBOOL(rb_ruby_parser_end_seen_p(parser->parser_params));
-}
-
-VALUE
-rb_parser_set_yydebug(VALUE vparser, VALUE flag)
-{
- struct ruby_parser *parser;
-
- TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
- rb_ruby_parser_set_yydebug(parser->parser_params, RTEST(flag));
- return flag;
-}
-
-#else
-
-/* For "ISO C requires a translation unit to contain at least one declaration" */
-void
-rb_parser_dummy(void)
-{}
-#endif
diff --git a/rubyparser.h b/rubyparser.h
deleted file mode 100644
index d1f499a060..0000000000
--- a/rubyparser.h
+++ /dev/null
@@ -1,1405 +0,0 @@
-#ifndef RUBY_RUBYPARSER_H
-#define RUBY_RUBYPARSER_H 1
-/*
- * This is a header file for librubyparser interface
- */
-
-#include <stdarg.h> /* for va_list */
-#include <assert.h>
-
-#ifdef UNIVERSAL_PARSER
-
-#define rb_encoding void
-#define OnigCodePoint unsigned int
-#include "parser_st.h"
-#ifndef RUBY_RUBY_H
-#include "parser_value.h"
-#endif
-
-#else
-
-#include "ruby/encoding.h"
-
-#endif
-
-/*
- * AST Node
- */
-enum node_type {
- NODE_SCOPE,
- NODE_BLOCK,
- NODE_IF,
- NODE_UNLESS,
- NODE_CASE,
- NODE_CASE2,
- NODE_CASE3,
- NODE_WHEN,
- NODE_IN,
- NODE_WHILE,
- NODE_UNTIL,
- NODE_ITER,
- NODE_FOR,
- NODE_FOR_MASGN,
- NODE_BREAK,
- NODE_NEXT,
- NODE_REDO,
- NODE_RETRY,
- NODE_BEGIN,
- NODE_RESCUE,
- NODE_RESBODY,
- NODE_ENSURE,
- NODE_AND,
- NODE_OR,
- NODE_MASGN,
- NODE_LASGN,
- NODE_DASGN,
- NODE_GASGN,
- NODE_IASGN,
- NODE_CDECL,
- NODE_CVASGN,
- NODE_OP_ASGN1,
- NODE_OP_ASGN2,
- NODE_OP_ASGN_AND,
- NODE_OP_ASGN_OR,
- NODE_OP_CDECL,
- NODE_CALL,
- NODE_OPCALL,
- NODE_FCALL,
- NODE_VCALL,
- NODE_QCALL,
- NODE_SUPER,
- NODE_ZSUPER,
- NODE_LIST,
- NODE_ZLIST,
- NODE_HASH,
- NODE_RETURN,
- NODE_YIELD,
- NODE_LVAR,
- NODE_DVAR,
- NODE_GVAR,
- NODE_IVAR,
- NODE_CONST,
- NODE_CVAR,
- NODE_NTH_REF,
- NODE_BACK_REF,
- NODE_MATCH,
- NODE_MATCH2,
- NODE_MATCH3,
- NODE_LIT,
- NODE_STR,
- NODE_DSTR,
- NODE_XSTR,
- NODE_DXSTR,
- NODE_EVSTR,
- NODE_DREGX,
- NODE_ONCE,
- NODE_ARGS,
- NODE_ARGS_AUX,
- NODE_OPT_ARG,
- NODE_KW_ARG,
- NODE_POSTARG,
- NODE_ARGSCAT,
- NODE_ARGSPUSH,
- NODE_SPLAT,
- NODE_BLOCK_PASS,
- NODE_DEFN,
- NODE_DEFS,
- NODE_ALIAS,
- NODE_VALIAS,
- NODE_UNDEF,
- NODE_CLASS,
- NODE_MODULE,
- NODE_SCLASS,
- NODE_COLON2,
- NODE_COLON3,
- NODE_DOT2,
- NODE_DOT3,
- NODE_FLIP2,
- NODE_FLIP3,
- NODE_SELF,
- NODE_NIL,
- NODE_TRUE,
- NODE_FALSE,
- NODE_ERRINFO,
- NODE_DEFINED,
- NODE_POSTEXE,
- NODE_DSYM,
- NODE_ATTRASGN,
- NODE_LAMBDA,
- NODE_ARYPTN,
- NODE_HSHPTN,
- NODE_FNDPTN,
- NODE_ERROR,
- NODE_RIPPER,
- NODE_RIPPER_VALUES,
- NODE_LAST
-};
-
-#ifndef FLEX_ARY_LEN
-/* From internal/compilers.h */
-/* A macro for defining a flexible array, like: VALUE ary[FLEX_ARY_LEN]; */
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
-# define FLEX_ARY_LEN /* VALUE ary[]; */
-#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
-# define FLEX_ARY_LEN 0 /* VALUE ary[0]; */
-#else
-# define FLEX_ARY_LEN 1 /* VALUE ary[1]; */
-#endif
-#endif
-
-typedef struct rb_ast_id_table {
- int size;
- ID ids[FLEX_ARY_LEN];
-} rb_ast_id_table_t;
-
-typedef struct rb_code_position_struct {
- int lineno;
- int column;
-} rb_code_position_t;
-
-typedef struct rb_code_location_struct {
- rb_code_position_t beg_pos;
- rb_code_position_t end_pos;
-} rb_code_location_t;
-
-/* Header part of AST Node */
-typedef struct RNode {
- VALUE flags;
- rb_code_location_t nd_loc;
- int node_id;
-} NODE;
-
-typedef struct RNode_SCOPE {
- NODE node;
-
- rb_ast_id_table_t *nd_tbl;
- struct RNode *nd_body;
- struct RNode_ARGS *nd_args;
-} rb_node_scope_t;
-
-typedef struct RNode_BLOCK {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_end;
- struct RNode *nd_next;
-} rb_node_block_t;
-
-typedef struct RNode_IF {
- NODE node;
-
- struct RNode *nd_cond;
- struct RNode *nd_body;
- struct RNode *nd_else;
-} rb_node_if_t;
-
-typedef struct RNode_UNLESS {
- NODE node;
-
- struct RNode *nd_cond;
- struct RNode *nd_body;
- struct RNode *nd_else;
-} rb_node_unless_t;
-
-typedef struct RNode_CASE {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
-} rb_node_case_t;
-
-typedef struct RNode_CASE2 {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
-} rb_node_case2_t;
-
-typedef struct RNode_CASE3 {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
-} rb_node_case3_t;
-
-typedef struct RNode_WHEN {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
- struct RNode *nd_next;
-} rb_node_when_t;
-
-typedef struct RNode_IN {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
- struct RNode *nd_next;
-} rb_node_in_t;
-
-/* RNode_WHILE and RNode_UNTIL should be same structure */
-typedef struct RNode_WHILE {
- NODE node;
-
- struct RNode *nd_cond;
- struct RNode *nd_body;
- long nd_state;
-} rb_node_while_t;
-
-typedef struct RNode_UNTIL {
- NODE node;
-
- struct RNode *nd_cond;
- struct RNode *nd_body;
- long nd_state;
-} rb_node_until_t;
-
-/* RNode_ITER and RNode_FOR should be same structure */
-typedef struct RNode_ITER {
- NODE node;
-
- struct RNode *nd_body;
- struct RNode *nd_iter;
-} rb_node_iter_t;
-
-typedef struct RNode_FOR {
- NODE node;
-
- struct RNode *nd_body;
- struct RNode *nd_iter;
-} rb_node_for_t;
-
-typedef struct RNode_FOR_MASGN {
- NODE node;
-
- struct RNode *nd_var;
-} rb_node_for_masgn_t;
-
-/* RNode_BREAK, RNode_NEXT and RNode_REDO should be same structure */
-typedef struct RNode_BREAK {
- NODE node;
-
- struct RNode *nd_chain;
- struct RNode *nd_stts;
-} rb_node_break_t;
-
-typedef struct RNode_NEXT {
- NODE node;
-
- struct RNode *nd_chain;
- struct RNode *nd_stts;
-} rb_node_next_t;
-
-typedef struct RNode_REDO {
- NODE node;
-
- struct RNode *nd_chain;
-} rb_node_redo_t;
-
-typedef struct RNode_RETRY {
- NODE node;
-} rb_node_retry_t;
-
-typedef struct RNode_BEGIN {
- NODE node;
-
- struct RNode *nd_body;
-} rb_node_begin_t;
-
-typedef struct RNode_RESCUE {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_resq;
- struct RNode *nd_else;
-} rb_node_rescue_t;
-
-typedef struct RNode_RESBODY {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
- struct RNode *nd_args;
-} rb_node_resbody_t;
-
-typedef struct RNode_ENSURE {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_resq; /* Maybe not used other than reduce_nodes */
- struct RNode *nd_ensr;
-} rb_node_ensure_t;
-
-/* RNode_AND and RNode_OR should be same structure */
-typedef struct RNode_AND {
- NODE node;
-
- struct RNode *nd_1st;
- struct RNode *nd_2nd;
-} rb_node_and_t;
-
-typedef struct RNode_OR {
- NODE node;
-
- struct RNode *nd_1st;
- struct RNode *nd_2nd;
-} rb_node_or_t;
-
-typedef struct RNode_MASGN {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_value;
- struct RNode *nd_args;
-} rb_node_masgn_t;
-
-typedef struct RNode_LASGN {
- NODE node;
-
- ID nd_vid;
- struct RNode *nd_value;
-} rb_node_lasgn_t;
-
-typedef struct RNode_DASGN {
- NODE node;
-
- ID nd_vid;
- struct RNode *nd_value;
-} rb_node_dasgn_t;
-
-typedef struct RNode_GASGN {
- NODE node;
-
- ID nd_vid;
- struct RNode *nd_value;
-} rb_node_gasgn_t;
-
-typedef struct RNode_IASGN {
- NODE node;
-
- ID nd_vid;
- struct RNode *nd_value;
-} rb_node_iasgn_t;
-
-typedef struct RNode_CDECL {
- NODE node;
-
- ID nd_vid;
- struct RNode *nd_value;
- struct RNode *nd_else;
-} rb_node_cdecl_t;
-
-typedef struct RNode_CVASGN {
- NODE node;
-
- ID nd_vid;
- struct RNode *nd_value;
-} rb_node_cvasgn_t;
-
-typedef struct RNode_OP_ASGN1 {
- NODE node;
-
- struct RNode *nd_recv;
- ID nd_mid;
- struct RNode *nd_index;
- struct RNode *nd_rvalue;
-} rb_node_op_asgn1_t;
-
-typedef struct RNode_OP_ASGN2 {
- NODE node;
-
- struct RNode *nd_recv;
- struct RNode *nd_value;
- ID nd_vid;
- ID nd_mid;
- bool nd_aid;
-} rb_node_op_asgn2_t;
-
-typedef struct RNode_OP_ASGN_AND {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_value;
-} rb_node_op_asgn_and_t;
-
-typedef struct RNode_OP_ASGN_OR {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_value;
-} rb_node_op_asgn_or_t;
-
-typedef struct RNode_OP_CDECL {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_value;
- ID nd_aid;
-} rb_node_op_cdecl_t;
-
-typedef struct RNode_CALL {
- NODE node;
-
- struct RNode *nd_recv;
- ID nd_mid;
- struct RNode *nd_args;
-} rb_node_call_t;
-
-typedef struct RNode_OPCALL {
- NODE node;
-
- struct RNode *nd_recv;
- ID nd_mid;
- struct RNode *nd_args;
-} rb_node_opcall_t;
-
-typedef struct RNode_FCALL {
- NODE node;
-
- ID nd_mid;
- struct RNode *nd_args;
-} rb_node_fcall_t;
-
-typedef struct RNode_VCALL {
- NODE node;
-
- ID nd_mid;
-} rb_node_vcall_t;
-
-typedef struct RNode_QCALL {
- NODE node;
-
- struct RNode *nd_recv;
- ID nd_mid;
- struct RNode *nd_args;
-} rb_node_qcall_t;
-
-typedef struct RNode_SUPER {
- NODE node;
-
- struct RNode *nd_args;
-} rb_node_super_t;
-
-typedef struct RNode_ZSUPER {
- NODE node;
-} rb_node_zsuper_t;
-
-/*
-
- Structure of LIST:
-
- LIST +--> LIST
- * head --> element | * head
- * alen (length of list) | * nd_end (point to the last LIST)
- * next -----------------+ * next
-
-
- RNode_LIST and RNode_VALUES should be same structure
-*/
-typedef struct RNode_LIST {
- NODE node;
-
- struct RNode *nd_head; /* element */
- union {
- long nd_alen;
- struct RNode *nd_end; /* Second list node has this structure */
- } as;
- struct RNode *nd_next; /* next list node */
-} rb_node_list_t;
-
-typedef struct RNode_ZLIST {
- NODE node;
-} rb_node_zlist_t;
-
-typedef struct RNode_VALUES {
- NODE node;
-
- struct RNode *nd_head;
- long nd_alen;
- struct RNode *nd_next;
-} rb_node_values_t;
-
-typedef struct RNode_HASH {
- NODE node;
-
- struct RNode *nd_head;
- long nd_brace;
-} rb_node_hash_t;
-
-typedef struct RNode_RETURN {
- NODE node;
-
- struct RNode *nd_stts;
-} rb_node_return_t;
-
-typedef struct RNode_YIELD {
- NODE node;
-
- struct RNode *nd_head;
-} rb_node_yield_t;
-
-typedef struct RNode_LVAR {
- NODE node;
-
- ID nd_vid;
-} rb_node_lvar_t;
-
-typedef struct RNode_DVAR {
- NODE node;
-
- ID nd_vid;
-} rb_node_dvar_t;
-
-typedef struct RNode_GVAR {
- NODE node;
-
- ID nd_vid;
-} rb_node_gvar_t;
-
-typedef struct RNode_IVAR {
- NODE node;
-
- ID nd_vid;
-} rb_node_ivar_t;
-
-typedef struct RNode_CONST {
- NODE node;
-
- ID nd_vid;
-} rb_node_const_t;
-
-typedef struct RNode_CVAR {
- NODE node;
-
- ID nd_vid;
-} rb_node_cvar_t;
-
-typedef struct RNode_NTH_REF {
- NODE node;
-
- long nd_nth;
-} rb_node_nth_ref_t;
-
-typedef struct RNode_BACK_REF {
- NODE node;
-
- long nd_nth;
-} rb_node_back_ref_t;
-
-/* RNode_MATCH, RNode_LIT, RNode_STR and RNode_XSTR should be same structure */
-typedef struct RNode_MATCH {
- NODE node;
-
- VALUE nd_lit;
-} rb_node_match_t;
-
-typedef struct RNode_MATCH2 {
- NODE node;
-
- struct RNode *nd_recv;
- struct RNode *nd_value;
- struct RNode *nd_args;
-} rb_node_match2_t;
-
-typedef struct RNode_MATCH3 {
- NODE node;
-
- struct RNode *nd_recv;
- struct RNode *nd_value;
-} rb_node_match3_t;
-
-typedef struct RNode_LIT {
- NODE node;
-
- VALUE nd_lit;
-} rb_node_lit_t;
-
-typedef struct RNode_STR {
- NODE node;
-
- VALUE nd_lit;
-} rb_node_str_t;
-
-/* RNode_DSTR, RNode_DXSTR and RNode_DSYM should be same structure */
-typedef struct RNode_DSTR {
- NODE node;
-
- VALUE nd_lit;
- union {
- long nd_alen;
- struct RNode *nd_end; /* Second dstr node has this structure. See also RNode_LIST */
- } as;
- struct RNode_LIST *nd_next;
-} rb_node_dstr_t;
-
-typedef struct RNode_XSTR {
- NODE node;
-
- VALUE nd_lit;
-} rb_node_xstr_t;
-
-typedef struct RNode_DXSTR {
- NODE node;
-
- VALUE nd_lit;
- long nd_alen;
- struct RNode_LIST *nd_next;
-} rb_node_dxstr_t;
-
-typedef struct RNode_EVSTR {
- NODE node;
-
- struct RNode *nd_body;
-} rb_node_evstr_t;
-
-typedef struct RNode_DREGX {
- NODE node;
-
- VALUE nd_lit;
- ID nd_cflag;
- struct RNode_LIST *nd_next;
-} rb_node_dregx_t;
-
-typedef struct RNode_ONCE {
- NODE node;
-
- struct RNode *nd_body;
-} rb_node_once_t;
-
-struct rb_args_info {
- NODE *pre_init;
- NODE *post_init;
-
- int pre_args_num; /* count of mandatory pre-arguments */
- int post_args_num; /* count of mandatory post-arguments */
-
- ID first_post_arg;
-
- ID rest_arg;
- ID block_arg;
-
- struct RNode_KW_ARG *kw_args;
- NODE *kw_rest_arg;
-
- struct RNode_OPT_ARG *opt_args;
- unsigned int no_kwarg: 1;
- unsigned int ruby2_keywords: 1;
- unsigned int forwarding: 1;
-};
-
-typedef struct RNode_ARGS {
- NODE node;
-
- struct rb_args_info nd_ainfo;
-} rb_node_args_t;
-
-typedef struct RNode_ARGS_AUX {
- NODE node;
-
- ID nd_pid;
- long nd_plen;
- struct RNode *nd_next;
-} rb_node_args_aux_t;
-
-typedef struct RNode_OPT_ARG {
- NODE node;
-
- struct RNode *nd_body;
- struct RNode_OPT_ARG *nd_next;
-} rb_node_opt_arg_t;
-
-typedef struct RNode_KW_ARG {
- NODE node;
-
- struct RNode *nd_body;
- struct RNode_KW_ARG *nd_next;
-} rb_node_kw_arg_t;
-
-typedef struct RNode_POSTARG {
- NODE node;
-
- struct RNode *nd_1st;
- struct RNode *nd_2nd;
-} rb_node_postarg_t;
-
-typedef struct RNode_ARGSCAT {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
-} rb_node_argscat_t;
-
-typedef struct RNode_ARGSPUSH {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
-} rb_node_argspush_t;
-
-typedef struct RNode_SPLAT {
- NODE node;
-
- struct RNode *nd_head;
-} rb_node_splat_t;
-
-typedef struct RNode_BLOCK_PASS {
- NODE node;
-
- struct RNode *nd_head;
- struct RNode *nd_body;
-} rb_node_block_pass_t;
-
-typedef struct RNode_DEFN {
- NODE node;
-
- ID nd_mid;
- struct RNode *nd_defn;
-} rb_node_defn_t;
-
-typedef struct RNode_DEFS {
- NODE node;
-
- struct RNode *nd_recv;
- ID nd_mid;
- struct RNode *nd_defn;
-} rb_node_defs_t;
-
-typedef struct RNode_ALIAS {
- NODE node;
-
- struct RNode *nd_1st;
- struct RNode *nd_2nd;
-} rb_node_alias_t;
-
-typedef struct RNode_VALIAS {
- NODE node;
-
- ID nd_alias;
- ID nd_orig;
-} rb_node_valias_t;
-
-typedef struct RNode_UNDEF {
- NODE node;
-
- struct RNode *nd_undef;
-} rb_node_undef_t;
-
-typedef struct RNode_CLASS {
- NODE node;
-
- struct RNode *nd_cpath;
- struct RNode *nd_body;
- struct RNode *nd_super;
-} rb_node_class_t;
-
-typedef struct RNode_MODULE {
- NODE node;
-
- struct RNode *nd_cpath;
- struct RNode *nd_body;
-} rb_node_module_t;
-
-typedef struct RNode_SCLASS {
- NODE node;
-
- struct RNode *nd_recv;
- struct RNode *nd_body;
-} rb_node_sclass_t;
-
-typedef struct RNode_COLON2 {
- NODE node;
-
- struct RNode *nd_head;
- ID nd_mid;
-} rb_node_colon2_t;
-
-typedef struct RNode_COLON3 {
- NODE node;
-
- ID nd_mid;
-} rb_node_colon3_t;
-
-/* RNode_DOT2, RNode_DOT3, RNode_FLIP2 and RNode_FLIP3 should be same structure */
-typedef struct RNode_DOT2 {
- NODE node;
-
- struct RNode *nd_beg;
- struct RNode *nd_end;
-} rb_node_dot2_t;
-
-typedef struct RNode_DOT3 {
- NODE node;
-
- struct RNode *nd_beg;
- struct RNode *nd_end;
-} rb_node_dot3_t;
-
-typedef struct RNode_FLIP2 {
- NODE node;
-
- struct RNode *nd_beg;
- struct RNode *nd_end;
-} rb_node_flip2_t;
-
-typedef struct RNode_FLIP3 {
- NODE node;
-
- struct RNode *nd_beg;
- struct RNode *nd_end;
-} rb_node_flip3_t;
-
-typedef struct RNode_SELF {
- NODE node;
-
- long nd_state; /* Default 1. See NEW_SELF. */
-} rb_node_self_t;
-
-typedef struct RNode_NIL {
- NODE node;
-} rb_node_nil_t;
-
-typedef struct RNode_TRUE {
- NODE node;
-} rb_node_true_t;
-
-typedef struct RNode_FALSE {
- NODE node;
-} rb_node_false_t;
-
-typedef struct RNode_ERRINFO {
- NODE node;
-} rb_node_errinfo_t;
-
-typedef struct RNode_DEFINED {
- NODE node;
-
- struct RNode *nd_head;
-} rb_node_defined_t;
-
-typedef struct RNode_POSTEXE {
- NODE node;
-
- struct RNode *nd_body;
-} rb_node_postexe_t;
-
-typedef struct RNode_DSYM {
- NODE node;
-
- VALUE nd_lit;
- long nd_alen;
- struct RNode_LIST *nd_next;
-} rb_node_dsym_t;
-
-typedef struct RNode_ATTRASGN {
- NODE node;
-
- struct RNode *nd_recv;
- ID nd_mid;
- struct RNode *nd_args;
-} rb_node_attrasgn_t;
-
-typedef struct RNode_LAMBDA {
- NODE node;
-
- struct RNode *nd_body;
-} rb_node_lambda_t;
-
-typedef struct RNode_ARYPTN {
- NODE node;
-
- struct RNode *nd_pconst;
- NODE *pre_args;
- NODE *rest_arg;
- NODE *post_args;
-} rb_node_aryptn_t;
-
-typedef struct RNode_HSHPTN {
- NODE node;
-
- struct RNode *nd_pconst;
- struct RNode *nd_pkwargs;
- struct RNode *nd_pkwrestarg;
-} rb_node_hshptn_t;
-
-typedef struct RNode_FNDPTN {
- NODE node;
-
- struct RNode *nd_pconst;
- NODE *pre_rest_arg;
- NODE *args;
- NODE *post_rest_arg;
-} rb_node_fndptn_t;
-
-typedef struct RNode_ERROR {
- NODE node;
-} rb_node_error_t;
-
-#define RNODE(obj) ((struct RNode *)(obj))
-
-#define RNODE_SCOPE(node) ((struct RNode_SCOPE *)(node))
-#define RNODE_BLOCK(node) ((struct RNode_BLOCK *)(node))
-#define RNODE_IF(node) ((struct RNode_IF *)(node))
-#define RNODE_UNLESS(node) ((struct RNode_UNLESS *)(node))
-#define RNODE_CASE(node) ((struct RNode_CASE *)(node))
-#define RNODE_CASE2(node) ((struct RNode_CASE2 *)(node))
-#define RNODE_CASE3(node) ((struct RNode_CASE3 *)(node))
-#define RNODE_WHEN(node) ((struct RNode_WHEN *)(node))
-#define RNODE_IN(node) ((struct RNode_IN *)(node))
-#define RNODE_WHILE(node) ((struct RNode_WHILE *)(node))
-#define RNODE_UNTIL(node) ((struct RNode_UNTIL *)(node))
-#define RNODE_ITER(node) ((struct RNode_ITER *)(node))
-#define RNODE_FOR(node) ((struct RNode_FOR *)(node))
-#define RNODE_FOR_MASGN(node) ((struct RNode_FOR_MASGN *)(node))
-#define RNODE_BREAK(node) ((struct RNode_BREAK *)(node))
-#define RNODE_NEXT(node) ((struct RNode_NEXT *)(node))
-#define RNODE_REDO(node) ((struct RNode_REDO *)(node))
-#define RNODE_RETRY(node) ((struct RNode_RETRY *)(node))
-#define RNODE_BEGIN(node) ((struct RNode_BEGIN *)(node))
-#define RNODE_RESCUE(node) ((struct RNode_RESCUE *)(node))
-#define RNODE_RESBODY(node) ((struct RNode_RESBODY *)(node))
-#define RNODE_ENSURE(node) ((struct RNode_ENSURE *)(node))
-#define RNODE_AND(node) ((struct RNode_AND *)(node))
-#define RNODE_OR(node) ((struct RNode_OR *)(node))
-#define RNODE_MASGN(node) ((struct RNode_MASGN *)(node))
-#define RNODE_LASGN(node) ((struct RNode_LASGN *)(node))
-#define RNODE_DASGN(node) ((struct RNode_DASGN *)(node))
-#define RNODE_GASGN(node) ((struct RNode_GASGN *)(node))
-#define RNODE_IASGN(node) ((struct RNode_IASGN *)(node))
-#define RNODE_CDECL(node) ((struct RNode_CDECL *)(node))
-#define RNODE_CVASGN(node) ((struct RNode_CVASGN *)(node))
-#define RNODE_OP_ASGN1(node) ((struct RNode_OP_ASGN1 *)(node))
-#define RNODE_OP_ASGN2(node) ((struct RNode_OP_ASGN2 *)(node))
-#define RNODE_OP_ASGN_AND(node) ((struct RNode_OP_ASGN_AND *)(node))
-#define RNODE_OP_ASGN_OR(node) ((struct RNode_OP_ASGN_OR *)(node))
-#define RNODE_OP_CDECL(node) ((struct RNode_OP_CDECL *)(node))
-#define RNODE_CALL(node) ((struct RNode_CALL *)(node))
-#define RNODE_OPCALL(node) ((struct RNode_OPCALL *)(node))
-#define RNODE_FCALL(node) ((struct RNode_FCALL *)(node))
-#define RNODE_VCALL(node) ((struct RNode_VCALL *)(node))
-#define RNODE_QCALL(node) ((struct RNode_QCALL *)(node))
-#define RNODE_SUPER(node) ((struct RNode_SUPER *)(node))
-#define RNODE_ZSUPER(node) ((struct RNode_ZSUPER *)(node))
-#define RNODE_LIST(node) ((struct RNode_LIST *)(node))
-#define RNODE_ZLIST(node) ((struct RNode_ZLIST *)(node))
-#define RNODE_HASH(node) ((struct RNode_HASH *)(node))
-#define RNODE_RETURN(node) ((struct RNode_RETURN *)(node))
-#define RNODE_YIELD(node) ((struct RNode_YIELD *)(node))
-#define RNODE_LVAR(node) ((struct RNode_LVAR *)(node))
-#define RNODE_DVAR(node) ((struct RNode_DVAR *)(node))
-#define RNODE_GVAR(node) ((struct RNode_GVAR *)(node))
-#define RNODE_IVAR(node) ((struct RNode_IVAR *)(node))
-#define RNODE_CONST(node) ((struct RNode_CONST *)(node))
-#define RNODE_CVAR(node) ((struct RNode_CVAR *)(node))
-#define RNODE_NTH_REF(node) ((struct RNode_NTH_REF *)(node))
-#define RNODE_BACK_REF(node) ((struct RNode_BACK_REF *)(node))
-#define RNODE_MATCH(node) ((struct RNode_MATCH *)(node))
-#define RNODE_MATCH2(node) ((struct RNode_MATCH2 *)(node))
-#define RNODE_MATCH3(node) ((struct RNode_MATCH3 *)(node))
-#define RNODE_LIT(node) ((struct RNode_LIT *)(node))
-#define RNODE_STR(node) ((struct RNode_STR *)(node))
-#define RNODE_DSTR(node) ((struct RNode_DSTR *)(node))
-#define RNODE_XSTR(node) ((struct RNode_XSTR *)(node))
-#define RNODE_DXSTR(node) ((struct RNode_DXSTR *)(node))
-#define RNODE_EVSTR(node) ((struct RNode_EVSTR *)(node))
-#define RNODE_DREGX(node) ((struct RNode_DREGX *)(node))
-#define RNODE_ONCE(node) ((struct RNode_ONCE *)(node))
-#define RNODE_ARGS(node) ((struct RNode_ARGS *)(node))
-#define RNODE_ARGS_AUX(node) ((struct RNode_ARGS_AUX *)(node))
-#define RNODE_OPT_ARG(node) ((struct RNode_OPT_ARG *)(node))
-#define RNODE_KW_ARG(node) ((struct RNode_KW_ARG *)(node))
-#define RNODE_POSTARG(node) ((struct RNode_POSTARG *)(node))
-#define RNODE_ARGSCAT(node) ((struct RNode_ARGSCAT *)(node))
-#define RNODE_ARGSPUSH(node) ((struct RNode_ARGSPUSH *)(node))
-#define RNODE_SPLAT(node) ((struct RNode_SPLAT *)(node))
-#define RNODE_BLOCK_PASS(node) ((struct RNode_BLOCK_PASS *)(node))
-#define RNODE_DEFN(node) ((struct RNode_DEFN *)(node))
-#define RNODE_DEFS(node) ((struct RNode_DEFS *)(node))
-#define RNODE_ALIAS(node) ((struct RNode_ALIAS *)(node))
-#define RNODE_VALIAS(node) ((struct RNode_VALIAS *)(node))
-#define RNODE_UNDEF(node) ((struct RNode_UNDEF *)(node))
-#define RNODE_CLASS(node) ((struct RNode_CLASS *)(node))
-#define RNODE_MODULE(node) ((struct RNode_MODULE *)(node))
-#define RNODE_SCLASS(node) ((struct RNode_SCLASS *)(node))
-#define RNODE_COLON2(node) ((struct RNode_COLON2 *)(node))
-#define RNODE_COLON3(node) ((struct RNode_COLON3 *)(node))
-#define RNODE_DOT2(node) ((struct RNode_DOT2 *)(node))
-#define RNODE_DOT3(node) ((struct RNode_DOT3 *)(node))
-#define RNODE_FLIP2(node) ((struct RNode_FLIP2 *)(node))
-#define RNODE_FLIP3(node) ((struct RNode_FLIP3 *)(node))
-#define RNODE_SELF(node) ((struct RNode_SELF *)(node))
-#define RNODE_NIL(node) ((struct RNode_NIL *)(node))
-#define RNODE_TRUE(node) ((struct RNode_TRUE *)(node))
-#define RNODE_FALSE(node) ((struct RNode_FALSE *)(node))
-#define RNODE_ERRINFO(node) ((struct RNode_ERRINFO *)(node))
-#define RNODE_DEFINED(node) ((struct RNode_DEFINED *)(node))
-#define RNODE_POSTEXE(node) ((struct RNode_POSTEXE *)(node))
-#define RNODE_DSYM(node) ((struct RNode_DSYM *)(node))
-#define RNODE_ATTRASGN(node) ((struct RNode_ATTRASGN *)(node))
-#define RNODE_LAMBDA(node) ((struct RNode_LAMBDA *)(node))
-#define RNODE_ARYPTN(node) ((struct RNode_ARYPTN *)(node))
-#define RNODE_HSHPTN(node) ((struct RNode_HSHPTN *)(node))
-#define RNODE_FNDPTN(node) ((struct RNode_FNDPTN *)(node))
-
-#ifdef RIPPER
-typedef struct RNode_RIPPER {
- NODE node;
-
- ID nd_vid;
- VALUE nd_rval;
- VALUE nd_cval;
-} rb_node_ripper_t;
-
-typedef struct RNode_RIPPER_VALUES {
- NODE node;
-
- VALUE nd_val1;
- VALUE nd_val2;
- VALUE nd_val3;
-} rb_node_ripper_values_t;
-
-#define RNODE_RIPPER(node) ((struct RNode_RIPPER *)(node))
-#define RNODE_RIPPER_VALUES(node) ((struct RNode_RIPPER_VALUES *)(node))
-#endif
-
-/* FL : 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: FINALIZE, 8: UNUSED, 9: UNUSED, 10: EXIVAR, 11: FREEZE */
-/* NODE_FL: 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: NODE_FL_NEWLINE,
- * 8..14: nd_type,
- * 15..: nd_line
- */
-#define NODE_FL_NEWLINE (((VALUE)1)<<7)
-
-#define NODE_TYPESHIFT 8
-#define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT)
-
-#define nd_fl_newline(n) (n)->flags & NODE_FL_NEWLINE
-#define nd_set_fl_newline(n) (n)->flags |= NODE_FL_NEWLINE
-#define nd_unset_fl_newline(n) (n)->flags &= ~NODE_FL_NEWLINE
-
-#define nd_type(n) ((int) ((RNODE(n)->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
-#define nd_set_type(n,t) \
- rb_node_set_type(n, t)
-#define nd_init_type(n,t) \
- (n)->flags=(((n)->flags&~NODE_TYPEMASK)|((((unsigned long)(t))<<NODE_TYPESHIFT)&NODE_TYPEMASK))
-
-typedef struct node_buffer_struct node_buffer_t;
-/* T_IMEMO/ast */
-typedef struct rb_ast_body_struct {
- const NODE *root;
- VALUE script_lines;
- // script_lines is either:
- // - a Fixnum that represents the line count of the original source, or
- // - an Array that contains the lines of the original source
- signed int frozen_string_literal:2; /* -1: not specified, 0: false, 1: true */
- signed int coverage_enabled:2; /* -1: not specified, 0: false, 1: true */
-} rb_ast_body_t;
-typedef struct rb_ast_struct {
- VALUE flags;
- node_buffer_t *node_buffer;
- rb_ast_body_t body;
-} rb_ast_t;
-
-
-
-/*
- * Parser Interface
- */
-
-
-typedef struct parser_params rb_parser_t;
-#ifndef INTERNAL_IMEMO_H
-typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
-#endif
-
-#ifdef UNIVERSAL_PARSER
-typedef struct rb_parser_config_struct {
- /*
- * Reference counter.
- * This is needed because both parser and ast refer
- * same config pointer.
- * We can remove this, once decuple parser and ast from Ruby GC.
- */
- int counter;
-
- /* Memory */
- void *(*malloc)(size_t size);
- void *(*calloc)(size_t number, size_t size);
- void *(*realloc)(void *ptr, size_t newsiz);
- void (*free)(void *ptr);
- void *(*alloc_n)(size_t nelems, size_t elemsiz);
- void *(*alloc)(size_t elemsiz);
- void *(*realloc_n)(void *ptr, size_t newelems, size_t newsiz);
- void *(*zalloc)(size_t elemsiz);
- void *(*rb_memmove)(void *dest, const void *src, size_t t, size_t n);
- void *(*nonempty_memcpy)(void *dest, const void *src, size_t t, size_t n);
- void *(*xmalloc_mul_add)(size_t x, size_t y, size_t z);
-
- /* imemo */
- rb_imemo_tmpbuf_t *(*tmpbuf_parser_heap)(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
- rb_ast_t *(*ast_new)(VALUE nb);
-
- // VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
- VALUE (*compile_callback)(VALUE (*func)(VALUE), VALUE arg);
- NODE *(*reg_named_capture_assign)(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc);
-
- /* Object */
- VALUE (*obj_freeze)(VALUE obj);
- VALUE (*obj_hide)(VALUE obj);
- int (*obj_frozen)(VALUE obj);
- int (*type_p)(VALUE, int);
- void (*obj_freeze_raw)(VALUE obj);
-
- int (*fixnum_p)(VALUE);
- int (*symbol_p)(VALUE);
-
- /* Variable */
- VALUE (*attr_get)(VALUE obj, ID id);
-
- /* Array */
- VALUE (*ary_new)(void);
- VALUE (*ary_push)(VALUE ary, VALUE elem);
- VALUE (*ary_new_from_args)(long n, ...);
- VALUE (*ary_pop)(VALUE ary);
- VALUE (*ary_last)(int argc, const VALUE *argv, VALUE ary);
- VALUE (*ary_unshift)(VALUE ary, VALUE item);
- VALUE (*ary_new2)(long capa); // ary_new_capa
- VALUE (*ary_entry)(VALUE ary, long offset);
- VALUE (*ary_join)(VALUE ary, VALUE sep);
- VALUE (*ary_reverse)(VALUE ary);
- VALUE (*ary_clear)(VALUE ary);
- long (*array_len)(VALUE a);
- VALUE (*array_aref)(VALUE, long);
-
- /* Symbol */
- VALUE (*sym_intern_ascii_cstr)(const char *ptr);
- ID (*make_temporary_id)(size_t n);
- int (*is_local_id)(ID);
- int (*is_attrset_id)(ID);
- int (*is_global_name_punct)(const int c);
- int (*id_type)(ID id);
- ID (*id_attrset)(ID);
- ID (*intern)(const char *name);
- ID (*intern2)(const char *name, long len);
- ID (*intern3)(const char *name, long len, rb_encoding *enc);
- ID (*intern_str)(VALUE str);
- int (*is_notop_id)(ID);
- int (*enc_symname_type)(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset);
- VALUE (*str_intern)(VALUE str);
- const char *(*id2name)(ID id);
- VALUE (*id2str)(ID id);
- VALUE (*id2sym)(ID x);
- ID (*sym2id)(VALUE sym);
-
- /* String */
- RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
- VALUE (*str_catf)(VALUE str, const char *format, ...);
- VALUE (*str_cat_cstr)(VALUE str, const char *ptr);
- VALUE (*str_subseq)(VALUE str, long beg, long len);
- VALUE (*str_dup)(VALUE str);
- VALUE (*str_new_frozen)(VALUE orig);
- VALUE (*str_buf_new)(long capa);
- VALUE (*str_buf_cat)(VALUE, const char*, long);
- void (*str_modify)(VALUE str);
- void (*str_set_len)(VALUE str, long len);
- VALUE (*str_cat)(VALUE str, const char *ptr, long len);
- VALUE (*str_resize)(VALUE str, long len);
- VALUE (*str_new)(const char *ptr, long len);
- VALUE (*str_new_cstr)(const char *ptr);
- VALUE (*fstring)(VALUE);
- int (*is_ascii_string)(VALUE str);
- VALUE (*enc_str_new)(const char *ptr, long len, rb_encoding *enc);
- VALUE (*enc_str_buf_cat)(VALUE str, const char *ptr, long len, rb_encoding *enc);
- VALUE (*str_buf_append)(VALUE str, VALUE str2);
- RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
- VALUE (*str_vcatf)(VALUE str, const char *fmt, va_list ap);
- char *(*string_value_cstr)(volatile VALUE *ptr);
- RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
- VALUE (*rb_sprintf)(const char *format, ...);
- char *(*rstring_ptr)(VALUE str);
- char *(*rstring_end)(VALUE str);
- long (*rstring_len)(VALUE str);
- VALUE (*filesystem_str_new_cstr)(const char *ptr);
- VALUE (*obj_as_string)(VALUE);
-
- /* Hash */
- VALUE (*hash_clear)(VALUE hash);
- VALUE (*hash_new)(void);
- VALUE (*hash_aset)(VALUE hash, VALUE key, VALUE val);
- VALUE (*hash_delete)(VALUE hash, VALUE key);
- VALUE (*hash_lookup)(VALUE hash, VALUE key);
- VALUE (*ident_hash_new)(void);
-
- /* Fixnum */
- VALUE (*int2fix)(long i);
-
- /* Bignum */
- void (*bignum_negate)(VALUE b);
- VALUE (*big_norm)(VALUE x);
- VALUE (*cstr_to_inum)(const char *str, int base, int badcheck);
-
- /* Float */
- VALUE (*float_new)(double d);
- double (*float_value)(VALUE v);
-
- /* Numeric */
- int (*num2int)(VALUE val);
- VALUE (*int_positive_pow)(long x, unsigned long y);
- VALUE (*int2num)(int v);
- long (*fix2long)(VALUE val);
-
- /* Rational */
- VALUE (*rational_new)(VALUE x, VALUE y);
- VALUE (*rational_raw1)(VALUE x);
- void (*rational_set_num)(VALUE r, VALUE n);
- VALUE (*rational_get_num)(VALUE obj);
-
- /* Complex */
- VALUE (*complex_raw)(VALUE x, VALUE y);
- void (*rcomplex_set_real)(VALUE cmp, VALUE r);
- void (*rcomplex_set_imag)(VALUE cmp, VALUE i);
- VALUE (*rcomplex_get_real)(VALUE obj);
- VALUE (*rcomplex_get_imag)(VALUE obj);
-
- /* IO */
- int (*stderr_tty_p)(void);
- void (*write_error_str)(VALUE mesg);
- VALUE (*default_rs)(void);
- VALUE (*io_write)(VALUE io, VALUE str);
- VALUE (*io_flush)(VALUE io);
- VALUE (*io_puts)(int argc, const VALUE *argv, VALUE out);
- VALUE (*io_gets_internal)(VALUE io);
-
- /* IO (Ractor) */
- VALUE (*debug_output_stdout)(void);
- VALUE (*debug_output_stderr)(void);
-
- /* Encoding */
- int (*is_usascii_enc)(rb_encoding *enc);
- int (*enc_isalnum)(OnigCodePoint c, rb_encoding *enc);
- int (*enc_precise_mbclen)(const char *p, const char *e, rb_encoding *enc);
- int (*mbclen_charfound_p)(int len);
- const char *(*enc_name)(rb_encoding *enc);
- char *(*enc_prev_char)(const char *s, const char *p, const char *e, rb_encoding *enc);
- rb_encoding* (*enc_get)(VALUE obj);
- int (*enc_asciicompat)(rb_encoding *enc);
- rb_encoding *(*utf8_encoding)(void);
- VALUE (*enc_associate)(VALUE obj, rb_encoding *enc);
- rb_encoding *(*ascii8bit_encoding)(void);
- int (*enc_codelen)(int c, rb_encoding *enc);
- int (*enc_mbcput)(unsigned int c, void *buf, rb_encoding *enc);
- int (*char_to_option_kcode)(int c, int *option, int *kcode);
- int (*ascii8bit_encindex)(void);
- int (*enc_find_index)(const char *name);
- rb_encoding *(*enc_from_index)(int idx);
- VALUE (*enc_associate_index)(VALUE obj, int encindex);
- int (*enc_isspace)(OnigCodePoint c, rb_encoding *enc);
- int enc_coderange_7bit;
- int enc_coderange_unknown;
- int enc_coderange_broken;
- rb_encoding *(*enc_compatible)(VALUE str1, VALUE str2);
- VALUE (*enc_from_encoding)(rb_encoding *enc);
- int (*encoding_get)(VALUE obj);
- void (*encoding_set)(VALUE obj, int encindex);
- int (*encoding_is_ascii8bit)(VALUE obj);
- rb_encoding *(*usascii_encoding)(void);
- int (*enc_str_coderange)(VALUE str);
-
- /* Ractor */
- VALUE (*ractor_make_shareable)(VALUE obj);
-
- /* Compile */
- // int rb_local_defined(ID id, const rb_iseq_t *iseq);
- int (*local_defined)(ID, const void*);
- // int rb_dvar_defined(ID id, const rb_iseq_t *iseq);
- int (*dvar_defined)(ID, const void*);
-
- /* Compile (parse.y) */
- int (*literal_cmp)(VALUE val, VALUE lit);
- parser_st_index_t (*literal_hash)(VALUE a);
-
- /* Error (Exception) */
- const char *(*builtin_class_name)(VALUE x);
- RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
- VALUE (*syntax_error_append)(VALUE, VALUE, int, int, rb_encoding*, const char*, va_list);
- RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
- void (*raise)(VALUE exc, const char *fmt, ...);
- VALUE (*syntax_error_new)(void);
-
- /* Eval */
- VALUE (*errinfo)(void);
- void (*set_errinfo)(VALUE err);
- void (*exc_raise)(VALUE mesg);
- VALUE (*make_exception)(int argc, const VALUE *argv);
-
- /* GC */
- void (*sized_xfree)(void *x, size_t size);
- void *(*sized_realloc_n)(void *ptr, size_t new_count, size_t element_size, size_t old_count);
- VALUE (*obj_write)(VALUE, VALUE *, VALUE);
- VALUE (*obj_written)(VALUE, VALUE, VALUE);
- void (*gc_register_mark_object)(VALUE object);
- void (*gc_guard)(VALUE);
- void (*gc_mark)(VALUE);
- void (*gc_mark_movable)(VALUE ptr);
- VALUE (*gc_location)(VALUE value);
-
- /* Re */
- VALUE (*reg_compile)(VALUE str, int options, const char *sourcefile, int sourceline);
- VALUE (*reg_check_preprocess)(VALUE str);
- int (*memcicmp)(const void *x, const void *y, long len);
-
- /* Error */
- void (*compile_warn)(const char *file, int line, const char *fmt, ...);
- void (*compile_warning)(const char *file, int line, const char *fmt, ...);
- void (*bug)(const char *fmt, ...);
- void (*fatal)(const char *fmt, ...);
- VALUE (*verbose)(void);
-
- /* VM */
- VALUE (*make_backtrace)(void);
-
- /* Util */
- unsigned long (*scan_hex)(const char *start, size_t len, size_t *retlen);
- unsigned long (*scan_oct)(const char *start, size_t len, size_t *retlen);
- unsigned long (*scan_digits)(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
- double (*strtod)(const char *s00, char **se);
-
- /* Misc */
- VALUE (*rbool)(VALUE);
- int (*undef_p)(VALUE);
- int (*rtest)(VALUE obj);
- int (*nil_p)(VALUE obj);
- int (*flonum_p)(VALUE obj);
- VALUE qnil;
- VALUE qtrue;
- VALUE qfalse;
- VALUE qundef;
- VALUE eArgError;
- VALUE mRubyVMFrozenCore;
- int (*long2int)(long);
- int (*special_const_p)(VALUE);
- int (*builtin_type)(VALUE);
-
- VALUE (*node_case_when_optimizable_literal)(const NODE *const node);
-
- /* For Ripper */
- VALUE (*static_id2sym)(ID id);
- long (*str_coderange_scan_restartable)(const char *s, const char *e, rb_encoding *enc, int *cr);
-} rb_parser_config_t;
-
-#undef rb_encoding
-#undef OnigCodePoint
-#endif /* UNIVERSAL_PARSER */
-
-RUBY_SYMBOL_EXPORT_BEGIN
-void rb_ruby_parser_free(void *ptr);
-rb_ast_t* rb_ruby_parser_compile_string(rb_parser_t *p, const char *f, VALUE s, int line);
-
-#ifdef UNIVERSAL_PARSER
-rb_parser_config_t *rb_ruby_parser_config_new(void *(*malloc)(size_t size));
-void rb_ruby_parser_config_free(rb_parser_config_t *config);
-rb_parser_t *rb_ruby_parser_allocate(rb_parser_config_t *config);
-rb_parser_t *rb_ruby_parser_new(rb_parser_config_t *config);
-#endif
-RUBY_SYMBOL_EXPORT_END
-
-#endif /* RUBY_RUBYPARSER_H */
diff --git a/sample/all-ruby-quine.rb b/sample/all-ruby-quine.rb
deleted file mode 100644
index 7686121468..0000000000
--- a/sample/all-ruby-quine.rb
+++ /dev/null
@@ -1,24 +0,0 @@
- eval($s=("t='eval($s=('+d=34.chr;s=3
- 2.chr+$s*i=8;v=$VERSION||eval('begin;v=V
- ERSION;rescue;v||RUBY_VERSION;end');f=('?'*8
- +'A|'+'?'*20+'G?c'+'?'*15+'A@CXx@~@_`OpGxCxp@~pO
- xS|O~G?c?q?xC`AP|q?x_|C_xC_xO@H@cG?G?qA|_|_`GCpOxC|H
-NFccqq@`_|OF@`?q?x_@x_x_`GB`O``O~G?C@qCxCxP@D@|G~C?pO|C?
- pO|C?AP|A~HNN`ccxC|Q@L@B"+"GpGpc@p?x_`GB`???_@FO|OB@
- xC|P`@?c?q?HPx@~@_`G@`????@L^`?q?x?xq@|_|O~GC`
- xA~@_@GBD').unpack('c*');w=4+v.length*u=
- 15;r=10.chr;j=0;while-24+w*u>i=1+i
- ;x=i%w;x>0||t=t+d+'+'+r+d;k=
- i/w%12>2&&x%u>3&&x%u+i
- /w*11-34+('-._'.
- index(c=v[
- x/u,1]
- )||c.hex +3)*99|
- |0; k=f [k/6 ][k%
- 6]; t=t +s[
- k*j =k+ j,1
- ]end;pr int (t+
- d+' ).s pli
- t.j oin [0,
- 609 ])# Y.E. '+r)
- ").split .join)#
diff --git a/sample/dir.rb b/sample/dir.rb
index 81257cd917..0c55078973 100644
--- a/sample/dir.rb
+++ b/sample/dir.rb
@@ -1,7 +1,12 @@
# directory access
# list all files but .*/*~/*.o
-Dir.foreach(".") do |file|
- unless file.start_with?('.') or file.end_with?('~', '.o')
- puts file
+dirp = Dir.open(".")
+for f in dirp
+ case f
+ when /\A\./, /~\z/, /\.o\z/
+ # do not print
+ else
+ print f, "\n"
end
end
+dirp.close
diff --git a/scheduler.c b/scheduler.c
index 3159635dba..4be18e1799 100644
--- a/scheduler.c
+++ b/scheduler.c
@@ -403,7 +403,15 @@ rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
VM_ASSERT(rb_obj_is_fiber(fiber));
- return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
+ // `rb_fiber_scheduler_unblock` can be called from points where `errno` is expected to be preserved. Therefore, we should save and restore it. For example `io_binwrite` calls `rb_fiber_scheduler_unblock` and if `errno` is reset to 0 by user code, it will break the error handling in `io_write`.
+ // If we explicitly preserve `errno` in `io_binwrite` and other similar functions (e.g. by returning it), this code is no longer needed. I hope in the future we will be able to remove it.
+ int saved_errno = errno;
+
+ VALUE result = rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
+
+ errno = saved_errno;
+
+ return result;
}
/*
@@ -474,15 +482,15 @@ VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv)
/*
* Document-method: Fiber::Scheduler#io_read
- * call-seq: io_read(io, buffer, length, offset) -> read length or -errno
+ * call-seq: io_read(io, buffer, minimum_length) -> read length or -errno
*
* Invoked by IO#read or IO#Buffer.read to read +length+ bytes from +io+ into a
- * specified +buffer+ (see IO::Buffer) at the given +offset+.
+ * specified +buffer+ (see IO::Buffer).
*
- * The +length+ argument is the "minimum length to be read". If the IO buffer
- * size is 8KiB, but the +length+ is +1024+ (1KiB), up to 8KiB might be read,
- * but at least 1KiB will be. Generally, the only case where less data than
- * +length+ will be read is if there is an error reading the data.
+ * The +minimum_length+ argument is the "minimum length to be read". If the IO
+ * buffer size is 8KiB, but the +length+ is +1024+ (1KiB), up to 8KiB might be
+ * read, but at least 1KiB will be. Generally, the only case where less data
+ * than +length+ will be read is if there is an error reading the data.
*
* Specifying a +length+ of 0 is valid and means try reading at least once and
* return any available data.
@@ -508,19 +516,13 @@ rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t lengt
return rb_check_funcall(scheduler, id_io_read, 4, arguments);
}
+
/*
* Document-method: Fiber::Scheduler#io_read
* call-seq: io_pread(io, buffer, from, length, offset) -> read length or -errno
*
- * Invoked by IO#pread or IO::Buffer#pread to read +length+ bytes from +io+
- * at offset +from+ into a specified +buffer+ (see IO::Buffer) at the given
- * +offset+.
- *
- * This method is semantically the same as #io_read, but it allows to specify
- * the offset to read from and is often better for asynchronous IO on the same
- * file.
+ * Invoked by IO::Buffer#pread. See that method for description of arguments.
*
- * The method should be considered _experimental_.
*/
VALUE
rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset)
@@ -534,16 +536,16 @@ rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buff
/*
* Document-method: Scheduler#io_write
- * call-seq: io_write(io, buffer, length, offset) -> written length or -errno
+ * call-seq: io_write(io, buffer, minimum_length) -> written length or -errno
*
* Invoked by IO#write or IO::Buffer#write to write +length+ bytes to +io+ from
- * from a specified +buffer+ (see IO::Buffer) at the given +offset+.
+ * from a specified +buffer+ (see IO::Buffer).
*
- * The +length+ argument is the "minimum length to be written". If the IO
- * buffer size is 8KiB, but the +length+ specified is 1024 (1KiB), at most 8KiB
- * will be written, but at least 1KiB will be. Generally, the only case where
- * less data than +length+ will be written is if there is an error writing the
- * data.
+ * The +minimum_length+ argument is the "minimum length to be written". If the
+ * IO buffer size is 8KiB, but the +length+ specified is 1024 (1KiB), at most
+ * 8KiB will be written, but at least 1KiB will be. Generally, the only case
+ * where less data than +minimum_length+ will be written is if there is an
+ * error writing the data.
*
* Specifying a +length+ of 0 is valid and means try writing at least once, as
* much data as possible.
@@ -574,15 +576,7 @@ rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t leng
* Document-method: Fiber::Scheduler#io_pwrite
* call-seq: io_pwrite(io, buffer, from, length, offset) -> written length or -errno
*
- * Invoked by IO#pwrite or IO::Buffer#pwrite to write +length+ bytes to +io+
- * at offset +from+ into a specified +buffer+ (see IO::Buffer) at the given
- * +offset+.
- *
- * This method is semantically the same as #io_write, but it allows to specify
- * the offset to write to and is often better for asynchronous IO on the same
- * file.
- *
- * The method should be considered _experimental_.
+ * Invoked by IO::Buffer#pwrite. See that method for description of arguments.
*
*/
VALUE
@@ -602,7 +596,8 @@ rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *base, size_t
VALUE result = rb_fiber_scheduler_io_read(scheduler, io, buffer, length, 0);
- rb_io_buffer_free_locked(buffer);
+ rb_io_buffer_unlock(buffer);
+ rb_io_buffer_free(buffer);
return result;
}
@@ -614,31 +609,8 @@ rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *base,
VALUE result = rb_fiber_scheduler_io_write(scheduler, io, buffer, length, 0);
- rb_io_buffer_free_locked(buffer);
-
- return result;
-}
-
-VALUE
-rb_fiber_scheduler_io_pread_memory(VALUE scheduler, VALUE io, rb_off_t from, void *base, size_t size, size_t length)
-{
- VALUE buffer = rb_io_buffer_new(base, size, RB_IO_BUFFER_LOCKED);
-
- VALUE result = rb_fiber_scheduler_io_pread(scheduler, io, from, buffer, length, 0);
-
- rb_io_buffer_free_locked(buffer);
-
- return result;
-}
-
-VALUE
-rb_fiber_scheduler_io_pwrite_memory(VALUE scheduler, VALUE io, rb_off_t from, const void *base, size_t size, size_t length)
-{
- VALUE buffer = rb_io_buffer_new((void*)base, size, RB_IO_BUFFER_LOCKED|RB_IO_BUFFER_READONLY);
-
- VALUE result = rb_fiber_scheduler_io_pwrite(scheduler, io, from, buffer, length, 0);
-
- rb_io_buffer_free_locked(buffer);
+ rb_io_buffer_unlock(buffer);
+ rb_io_buffer_free(buffer);
return result;
}
diff --git a/shape.c b/shape.c
index d4e2c0f2bb..1dc08dcb60 100644
--- a/shape.c
+++ b/shape.c
@@ -1,333 +1,72 @@
#include "vm_core.h"
#include "vm_sync.h"
#include "shape.h"
+#include "gc.h"
#include "symbol.h"
#include "id_table.h"
#include "internal/class.h"
-#include "internal/error.h"
-#include "internal/gc.h"
-#include "internal/object.h"
#include "internal/symbol.h"
#include "internal/variable.h"
#include "variable.h"
#include <stdbool.h>
-#ifndef _WIN32
-#include <sys/mman.h>
-#endif
-
#ifndef SHAPE_DEBUG
#define SHAPE_DEBUG (VM_CHECK_MODE > 0)
#endif
-#if SIZEOF_SHAPE_T == 4
-#if RUBY_DEBUG
-#define SHAPE_BUFFER_SIZE 0x8000
-#else
-#define SHAPE_BUFFER_SIZE 0x80000
-#endif
-#else
-#define SHAPE_BUFFER_SIZE 0x8000
-#endif
-
-#define REDBLACK_CACHE_SIZE (SHAPE_BUFFER_SIZE * 32)
-
-#define SINGLE_CHILD_TAG 0x1
-#define TAG_SINGLE_CHILD(x) (struct rb_id_table *)((uintptr_t)x | SINGLE_CHILD_TAG)
-#define SINGLE_CHILD_MASK (~((uintptr_t)SINGLE_CHILD_TAG))
-#define SINGLE_CHILD_P(x) (((uintptr_t)x) & SINGLE_CHILD_TAG)
-#define SINGLE_CHILD(x) (rb_shape_t *)((uintptr_t)x & SINGLE_CHILD_MASK)
-#define ANCESTOR_CACHE_THRESHOLD 10
-#define MAX_SHAPE_ID (SHAPE_BUFFER_SIZE - 1)
-#define ANCESTOR_SEARCH_MAX_DEPTH 2
-
static ID id_frozen;
static ID id_t_object;
static ID size_pool_edge_names[SIZE_POOL_COUNT];
-#define LEAF 0
-#define BLACK 0x0
-#define RED 0x1
-
-static redblack_node_t *
-redblack_left(redblack_node_t * node)
-{
- if (node->l == LEAF) {
- return LEAF;
- }
- else {
- RUBY_ASSERT(node->l < GET_SHAPE_TREE()->cache_size);
- redblack_node_t * left = &GET_SHAPE_TREE()->shape_cache[node->l - 1];
- return left;
- }
-}
-
-static redblack_node_t *
-redblack_right(redblack_node_t * node)
-{
- if (node->r == LEAF) {
- return LEAF;
- }
- else {
- RUBY_ASSERT(node->r < GET_SHAPE_TREE()->cache_size);
- redblack_node_t * right = &GET_SHAPE_TREE()->shape_cache[node->r - 1];
- return right;
- }
-}
-
-static redblack_node_t *
-redblack_find(redblack_node_t * tree, ID key)
-{
- if (tree == LEAF) {
- return LEAF;
- }
- else {
- RUBY_ASSERT(redblack_left(tree) == LEAF || redblack_left(tree)->key < tree->key);
- RUBY_ASSERT(redblack_right(tree) == LEAF || redblack_right(tree)->key > tree->key);
-
- if (tree->key == key) {
- return tree;
- }
- else {
- if (key < tree->key) {
- return redblack_find(redblack_left(tree), key);
- }
- else {
- return redblack_find(redblack_right(tree), key);
- }
- }
- }
-}
-
-static inline char
-redblack_color(redblack_node_t * node)
-{
- return node && ((uintptr_t)node->value & RED);
-}
-
-static inline bool
-redblack_red_p(redblack_node_t * node)
-{
- return redblack_color(node) == RED;
-}
-
-static inline rb_shape_t *
-redblack_value(redblack_node_t * node)
-{
- // Color is stored in the bottom bit of the shape pointer
- // Mask away the bit so we get the actual pointer back
- return (rb_shape_t *)((uintptr_t)node->value & (((uintptr_t)-1) - 1));
-}
-
-static redblack_id_t
-redblack_id_for(redblack_node_t * node)
-{
- RUBY_ASSERT(node || node == LEAF);
- if (node == LEAF) {
- return 0;
- }
- else {
- redblack_node_t * redblack_nodes = GET_SHAPE_TREE()->shape_cache;
- redblack_id_t id = (redblack_id_t)(node - redblack_nodes);
- return id + 1;
- }
-}
-
-static redblack_node_t *
-redblack_new(char color, ID key, rb_shape_t * value, redblack_node_t * left, redblack_node_t * right)
-{
- if (GET_SHAPE_TREE()->cache_size + 1 >= REDBLACK_CACHE_SIZE) {
- // We're out of cache, just quit
- return LEAF;
- }
-
- RUBY_ASSERT(left == LEAF || left->key < key);
- RUBY_ASSERT(right == LEAF || right->key > key);
-
- redblack_node_t * redblack_nodes = GET_SHAPE_TREE()->shape_cache;
- redblack_node_t * node = &redblack_nodes[(GET_SHAPE_TREE()->cache_size)++];
- node->key = key;
- node->value = (rb_shape_t *)((uintptr_t)value | color);
- node->l = redblack_id_for(left);
- node->r = redblack_id_for(right);
- return node;
-}
-
-static redblack_node_t *
-redblack_balance(char color, ID key, rb_shape_t * value, redblack_node_t * left, redblack_node_t * right)
-{
- if (color == BLACK) {
- ID new_key, new_left_key, new_right_key;
- rb_shape_t *new_value, *new_left_value, *new_right_value;
- redblack_node_t *new_left_left, *new_left_right, *new_right_left, *new_right_right;
-
- if (redblack_red_p(left) && redblack_red_p(redblack_left(left))) {
- new_right_key = key;
- new_right_value = value;
- new_right_right = right;
-
- new_key = left->key;
- new_value = redblack_value(left);
- new_right_left = redblack_right(left);
-
- new_left_key = redblack_left(left)->key;
- new_left_value = redblack_value(redblack_left(left));
-
- new_left_left = redblack_left(redblack_left(left));
- new_left_right = redblack_right(redblack_left(left));
- }
- else if (redblack_red_p(left) && redblack_red_p(redblack_right(left))) {
- new_right_key = key;
- new_right_value = value;
- new_right_right = right;
-
- new_left_key = left->key;
- new_left_value = redblack_value(left);
- new_left_left = redblack_left(left);
-
- new_key = redblack_right(left)->key;
- new_value = redblack_value(redblack_right(left));
- new_left_right = redblack_left(redblack_right(left));
- new_right_left = redblack_right(redblack_right(left));
- }
- else if (redblack_red_p(right) && redblack_red_p(redblack_left(right))) {
- new_left_key = key;
- new_left_value = value;
- new_left_left = left;
-
- new_right_key = right->key;
- new_right_value = redblack_value(right);
- new_right_right = redblack_right(right);
-
- new_key = redblack_left(right)->key;
- new_value = redblack_value(redblack_left(right));
- new_left_right = redblack_left(redblack_left(right));
- new_right_left = redblack_right(redblack_left(right));
- }
- else if (redblack_red_p(right) && redblack_red_p(redblack_right(right))) {
- new_left_key = key;
- new_left_value = value;
- new_left_left = left;
-
- new_key = right->key;
- new_value = redblack_value(right);
- new_left_right = redblack_left(right);
-
- new_right_key = redblack_right(right)->key;
- new_right_value = redblack_value(redblack_right(right));
- new_right_left = redblack_left(redblack_right(right));
- new_right_right = redblack_right(redblack_right(right));
- }
- else {
- return redblack_new(color, key, value, left, right);
- }
-
- RUBY_ASSERT(new_left_key < new_key);
- RUBY_ASSERT(new_right_key > new_key);
- RUBY_ASSERT(new_left_left == LEAF || new_left_left->key < new_left_key);
- RUBY_ASSERT(new_left_right == LEAF || new_left_right->key > new_left_key);
- RUBY_ASSERT(new_left_right == LEAF || new_left_right->key < new_key);
- RUBY_ASSERT(new_right_left == LEAF || new_right_left->key < new_right_key);
- RUBY_ASSERT(new_right_left == LEAF || new_right_left->key > new_key);
- RUBY_ASSERT(new_right_right == LEAF || new_right_right->key > new_right_key);
-
- return redblack_new(
- RED, new_key, new_value,
- redblack_new(BLACK, new_left_key, new_left_value, new_left_left, new_left_right),
- redblack_new(BLACK, new_right_key, new_right_value, new_right_left, new_right_right));
- }
-
- return redblack_new(color, key, value, left, right);
-}
-
-static redblack_node_t *
-redblack_insert_aux(redblack_node_t * tree, ID key, rb_shape_t * value)
-{
- if (tree == LEAF) {
- return redblack_new(RED, key, value, LEAF, LEAF);
- }
- else {
- redblack_node_t *left, *right;
- if (key < tree->key) {
- left = redblack_insert_aux(redblack_left(tree), key, value);
- RUBY_ASSERT(left != LEAF);
- right = redblack_right(tree);
- RUBY_ASSERT(right == LEAF || right->key > tree->key);
- }
- else if (key > tree->key) {
- left = redblack_left(tree);
- RUBY_ASSERT(left == LEAF || left->key < tree->key);
- right = redblack_insert_aux(redblack_right(tree), key, value);
- RUBY_ASSERT(right != LEAF);
- }
- else {
- return tree;
- }
-
- return redblack_balance(
- redblack_color(tree),
- tree->key,
- redblack_value(tree),
- left,
- right
- );
- }
-}
-
-static redblack_node_t *
-redblack_force_black(redblack_node_t * node)
-{
- node->value = redblack_value(node);
- return node;
-}
-
-static redblack_node_t *
-redblack_insert(redblack_node_t * tree, ID key, rb_shape_t * value)
-{
- redblack_node_t * root = redblack_insert_aux(tree, key, value);
-
- if (redblack_red_p(root)) {
- return redblack_force_black(root);
- }
- else {
- return root;
- }
-}
-
-rb_shape_tree_t *rb_shape_tree_ptr = NULL;
-
/*
* Shape getters
*/
rb_shape_t *
rb_shape_get_root_shape(void)
{
- return GET_SHAPE_TREE()->root_shape;
+ return GET_VM()->root_shape;
}
shape_id_t
rb_shape_id(rb_shape_t * shape)
{
- return (shape_id_t)(shape - GET_SHAPE_TREE()->shape_list);
+ return (shape_id_t)(shape - GET_VM()->shape_list);
+}
+
+bool
+rb_shape_root_shape_p(rb_shape_t* shape)
+{
+ return shape == rb_shape_get_root_shape();
}
void
rb_shape_each_shape(each_shape_callback callback, void *data)
{
rb_shape_t *cursor = rb_shape_get_root_shape();
- rb_shape_t *end = rb_shape_get_shape_by_id(GET_SHAPE_TREE()->next_shape_id);
+ rb_shape_t *end = rb_shape_get_shape_by_id(GET_VM()->next_shape_id);
while (cursor < end) {
callback(cursor, data);
cursor += 1;
}
}
-RUBY_FUNC_EXPORTED rb_shape_t*
+rb_shape_t*
rb_shape_get_shape_by_id(shape_id_t shape_id)
{
RUBY_ASSERT(shape_id != INVALID_SHAPE_ID);
- rb_shape_t *shape = &GET_SHAPE_TREE()->shape_list[shape_id];
+ rb_vm_t *vm = GET_VM();
+ rb_shape_t *shape = &vm->shape_list[shape_id];
+ return shape;
+}
+
+rb_shape_t*
+rb_shape_get_shape_by_id_without_assertion(shape_id_t shape_id)
+{
+ RUBY_ASSERT(shape_id != INVALID_SHAPE_ID);
+
+ rb_vm_t *vm = GET_VM();
+ rb_shape_t *shape = &vm->shape_list[shape_id];
return shape;
}
@@ -338,10 +77,17 @@ rb_shape_get_parent(rb_shape_t * shape)
}
#if !SHAPE_IN_BASIC_FLAGS
+shape_id_t
+rb_rclass_shape_id(VALUE obj)
+{
+ RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
+ return RCLASS_EXT(obj)->shape_id;
+}
+
shape_id_t rb_generic_shape_id(VALUE obj);
#endif
-RUBY_FUNC_EXPORTED shape_id_t
+shape_id_t
rb_shape_get_shape_id(VALUE obj)
{
if (RB_SPECIAL_CONST_P(obj)) {
@@ -383,111 +129,8 @@ rb_shape_get_shape(VALUE obj)
return rb_shape_get_shape_by_id(rb_shape_get_shape_id(obj));
}
-static rb_shape_t *
-shape_alloc(void)
-{
- shape_id_t shape_id = GET_SHAPE_TREE()->next_shape_id;
- GET_SHAPE_TREE()->next_shape_id++;
-
- if (shape_id == (MAX_SHAPE_ID + 1)) {
- // TODO: Make an OutOfShapesError ??
- rb_bug("Out of shapes");
- }
-
- return &GET_SHAPE_TREE()->shape_list[shape_id];
-}
-
-static rb_shape_t *
-rb_shape_alloc_with_parent_id(ID edge_name, shape_id_t parent_id)
-{
- rb_shape_t * shape = shape_alloc();
-
- shape->edge_name = edge_name;
- shape->next_iv_index = 0;
- shape->parent_id = parent_id;
- shape->edges = NULL;
-
- return shape;
-}
-
-static rb_shape_t *
-rb_shape_alloc(ID edge_name, rb_shape_t * parent, enum shape_type type)
-{
- rb_shape_t * shape = rb_shape_alloc_with_parent_id(edge_name, rb_shape_id(parent));
- shape->type = (uint8_t)type;
- shape->size_pool_index = parent->size_pool_index;
- shape->capacity = parent->capacity;
- shape->edges = 0;
- return shape;
-}
-
-#ifdef HAVE_MMAP
-static redblack_node_t *
-redblack_cache_ancestors(rb_shape_t * shape)
-{
- if (!(shape->ancestor_index || shape->parent_id == INVALID_SHAPE_ID)) {
- redblack_node_t * parent_index;
-
- parent_index = redblack_cache_ancestors(rb_shape_get_parent(shape));
-
- if (shape->type == SHAPE_IVAR) {
- shape->ancestor_index = redblack_insert(parent_index, shape->edge_name, shape);
-
-#if RUBY_DEBUG
- if (shape->ancestor_index) {
- redblack_node_t *inserted_node = redblack_find(shape->ancestor_index, shape->edge_name);
- RUBY_ASSERT(inserted_node);
- RUBY_ASSERT(redblack_value(inserted_node) == shape);
- }
-#endif
- }
- else {
- shape->ancestor_index = parent_index;
- }
- }
-
- return shape->ancestor_index;
-}
-#else
-static redblack_node_t *
-redblack_cache_ancestors(rb_shape_t * shape)
-{
- return LEAF;
-}
-#endif
-
-static rb_shape_t *
-rb_shape_alloc_new_child(ID id, rb_shape_t * shape, enum shape_type shape_type)
-{
- rb_shape_t * new_shape = rb_shape_alloc(id, shape, shape_type);
-
- switch (shape_type) {
- case SHAPE_IVAR:
- if (UNLIKELY(shape->next_iv_index >= shape->capacity)) {
- RUBY_ASSERT(shape->next_iv_index == shape->capacity);
- new_shape->capacity = (uint32_t)rb_malloc_grow_capa(shape->capacity, sizeof(VALUE));
- }
- RUBY_ASSERT(new_shape->capacity > shape->next_iv_index);
- new_shape->next_iv_index = shape->next_iv_index + 1;
- if (new_shape->next_iv_index > ANCESTOR_CACHE_THRESHOLD) {
- redblack_cache_ancestors(new_shape);
- }
- break;
- case SHAPE_FROZEN:
- case SHAPE_T_OBJECT:
- new_shape->next_iv_index = shape->next_iv_index;
- break;
- case SHAPE_OBJ_TOO_COMPLEX:
- case SHAPE_ROOT:
- rb_bug("Unreachable");
- break;
- }
-
- return new_shape;
-}
-
static rb_shape_t*
-get_next_shape_internal(rb_shape_t * shape, ID id, enum shape_type shape_type, bool * variation_created, bool new_variations_allowed)
+get_next_shape_internal(rb_shape_t * shape, ID id, enum shape_type shape_type, bool * variation_created, bool new_shapes_allowed)
{
rb_shape_t *res = NULL;
@@ -496,71 +139,84 @@ get_next_shape_internal(rb_shape_t * shape, ID id, enum shape_type shape_type, b
*variation_created = false;
- RB_VM_LOCK_ENTER();
- {
- // If the current shape has children
- if (shape->edges) {
- // Check if it only has one child
- if (SINGLE_CHILD_P(shape->edges)) {
- rb_shape_t * child = SINGLE_CHILD(shape->edges);
- // If the one child has a matching edge name, then great,
- // we found what we want.
- if (child->edge_name == id) {
- res = child;
- }
- }
- else {
- // If it has more than one child, do a hash lookup to find it.
- VALUE lookup_result;
- if (rb_id_table_lookup(shape->edges, id, &lookup_result)) {
- res = (rb_shape_t *)lookup_result;
- }
+ if (new_shapes_allowed) {
+ RB_VM_LOCK_ENTER();
+ {
+ bool had_edges = !!shape->edges;
+
+ if (!shape->edges) {
+ shape->edges = rb_id_table_create(0);
}
- }
- // If we didn't find the shape we're looking for we create it.
- if (!res) {
- // If we're not allowed to create a new variation, of if we're out of shapes
- // we return TOO_COMPLEX_SHAPE.
- if (!new_variations_allowed || GET_SHAPE_TREE()->next_shape_id > MAX_SHAPE_ID) {
- res = rb_shape_get_shape_by_id(OBJ_TOO_COMPLEX_SHAPE_ID);
+ // Lookup the shape in edges - if there's already an edge and a corresponding shape for it,
+ // we can return that. Otherwise, we'll need to get a new shape
+ VALUE lookup_result;
+ if (rb_id_table_lookup(shape->edges, id, &lookup_result)) {
+ res = (rb_shape_t *)lookup_result;
}
else {
- rb_shape_t * new_shape = rb_shape_alloc_new_child(id, shape, shape_type);
-
- if (!shape->edges) {
- // If the shape had no edge yet, we can directly set the new child
- shape->edges = TAG_SINGLE_CHILD(new_shape);
- }
- else {
- // If the edge was single child we need to allocate a table.
- if (SINGLE_CHILD_P(shape->edges)) {
- rb_shape_t * old_child = SINGLE_CHILD(shape->edges);
- shape->edges = rb_id_table_create(2);
- rb_id_table_insert(shape->edges, old_child->edge_name, (VALUE)old_child);
- }
-
- rb_id_table_insert(shape->edges, new_shape->edge_name, (VALUE)new_shape);
- *variation_created = true;
+ *variation_created = had_edges;
+
+ rb_shape_t * new_shape = rb_shape_alloc(id, shape);
+
+ new_shape->type = (uint8_t)shape_type;
+ new_shape->capacity = shape->capacity;
+
+ switch (shape_type) {
+ case SHAPE_IVAR:
+ new_shape->next_iv_index = shape->next_iv_index + 1;
+ break;
+ case SHAPE_CAPACITY_CHANGE:
+ case SHAPE_FROZEN:
+ case SHAPE_T_OBJECT:
+ new_shape->next_iv_index = shape->next_iv_index;
+ break;
+ case SHAPE_OBJ_TOO_COMPLEX:
+ case SHAPE_INITIAL_CAPACITY:
+ case SHAPE_ROOT:
+ rb_bug("Unreachable");
+ break;
}
+ rb_id_table_insert(shape->edges, id, (VALUE)new_shape);
+
res = new_shape;
}
}
+ RB_VM_LOCK_LEAVE();
}
- RB_VM_LOCK_LEAVE();
-
return res;
}
-int
+MJIT_FUNC_EXPORTED int
rb_shape_frozen_shape_p(rb_shape_t* shape)
{
return SHAPE_FROZEN == (enum shape_type)shape->type;
}
+static void
+move_iv(VALUE obj, ID id, attr_index_t from, attr_index_t to)
+{
+ switch(BUILTIN_TYPE(obj)) {
+ case T_CLASS:
+ case T_MODULE:
+ RCLASS_IVPTR(obj)[to] = RCLASS_IVPTR(obj)[from];
+ break;
+ case T_OBJECT:
+ RUBY_ASSERT(!rb_shape_obj_too_complex(obj));
+ ROBJECT_IVPTR(obj)[to] = ROBJECT_IVPTR(obj)[from];
+ break;
+ default: {
+ struct gen_ivtbl *ivtbl;
+ rb_gen_ivtbl_get(obj, id, &ivtbl);
+ ivtbl->ivptr[to] = ivtbl->ivptr[from];
+ break;
+ }
+ }
+}
+
static rb_shape_t *
-remove_shape_recursive(rb_shape_t *shape, ID id, rb_shape_t **removed_shape)
+remove_shape_recursive(VALUE obj, ID id, rb_shape_t * shape, VALUE * removed)
{
if (shape->parent_id == INVALID_SHAPE_ID) {
// We've hit the top of the shape tree and couldn't find the
@@ -569,29 +225,41 @@ remove_shape_recursive(rb_shape_t *shape, ID id, rb_shape_t **removed_shape)
}
else {
if (shape->type == SHAPE_IVAR && shape->edge_name == id) {
- *removed_shape = shape;
-
+ // We've hit the edge we wanted to remove, return it's _parent_
+ // as the new parent while we go back down the stack.
+ attr_index_t index = shape->next_iv_index - 1;
+
+ switch(BUILTIN_TYPE(obj)) {
+ case T_CLASS:
+ case T_MODULE:
+ *removed = RCLASS_IVPTR(obj)[index];
+ break;
+ case T_OBJECT:
+ *removed = ROBJECT_IVPTR(obj)[index];
+ break;
+ default: {
+ struct gen_ivtbl *ivtbl;
+ rb_gen_ivtbl_get(obj, id, &ivtbl);
+ *removed = ivtbl->ivptr[index];
+ break;
+ }
+ }
return rb_shape_get_parent(shape);
}
else {
// This isn't the IV we want to remove, keep walking up.
- rb_shape_t *new_parent = remove_shape_recursive(rb_shape_get_parent(shape), id, removed_shape);
+ rb_shape_t * new_parent = remove_shape_recursive(obj, id, rb_shape_get_parent(shape), removed);
// We found a new parent. Create a child of the new parent that
// has the same attributes as this shape.
if (new_parent) {
- if (UNLIKELY(new_parent->type == SHAPE_OBJ_TOO_COMPLEX)) {
- return new_parent;
- }
-
bool dont_care;
- rb_shape_t *new_child = get_next_shape_internal(new_parent, shape->edge_name, shape->type, &dont_care, true);
- if (UNLIKELY(new_child->type == SHAPE_OBJ_TOO_COMPLEX)) {
- return new_child;
+ rb_shape_t * new_child = get_next_shape_internal(new_parent, shape->edge_name, shape->type, &dont_care, true);
+ new_child->capacity = shape->capacity;
+ if (new_child->type == SHAPE_IVAR) {
+ move_iv(obj, id, shape->next_iv_index - 1, new_child->next_iv_index - 1);
}
- RUBY_ASSERT(new_child->capacity <= shape->capacity);
-
return new_child;
}
else {
@@ -603,63 +271,16 @@ remove_shape_recursive(rb_shape_t *shape, ID id, rb_shape_t **removed_shape)
}
}
-bool
-rb_shape_transition_shape_remove_ivar(VALUE obj, ID id, rb_shape_t *shape, VALUE *removed)
+void
+rb_shape_transition_shape_remove_ivar(VALUE obj, ID id, rb_shape_t *shape, VALUE * removed)
{
- if (UNLIKELY(shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
- return false;
- }
-
- rb_shape_t *removed_shape = NULL;
- rb_shape_t *new_shape = remove_shape_recursive(shape, id, &removed_shape);
+ rb_shape_t * new_shape = remove_shape_recursive(obj, id, shape, removed);
if (new_shape) {
- RUBY_ASSERT(removed_shape != NULL);
-
- if (UNLIKELY(new_shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
- return false;
- }
-
- RUBY_ASSERT(new_shape->next_iv_index == shape->next_iv_index - 1);
-
- VALUE *ivptr;
- switch(BUILTIN_TYPE(obj)) {
- case T_CLASS:
- case T_MODULE:
- ivptr = RCLASS_IVPTR(obj);
- break;
- case T_OBJECT:
- ivptr = ROBJECT_IVPTR(obj);
- break;
- default: {
- struct gen_ivtbl *ivtbl;
- rb_gen_ivtbl_get(obj, id, &ivtbl);
- ivptr = ivtbl->as.shape.ivptr;
- break;
- }
- }
-
- *removed = ivptr[removed_shape->next_iv_index - 1];
-
- memmove(&ivptr[removed_shape->next_iv_index - 1], &ivptr[removed_shape->next_iv_index],
- ((new_shape->next_iv_index + 1) - removed_shape->next_iv_index) * sizeof(VALUE));
-
- // Re-embed objects when instances become small enough
- // This is necessary because YJIT assumes that objects with the same shape
- // have the same embeddedness for efficiency (avoid extra checks)
- if (BUILTIN_TYPE(obj) == T_OBJECT &&
- !RB_FL_TEST_RAW(obj, ROBJECT_EMBED) &&
- rb_obj_embedded_size(new_shape->next_iv_index) <= rb_gc_obj_slot_size(obj)) {
- RB_FL_SET_RAW(obj, ROBJECT_EMBED);
- memcpy(ROBJECT_IVPTR(obj), ivptr, new_shape->next_iv_index * sizeof(VALUE));
- xfree(ivptr);
- }
-
rb_shape_set_shape(obj, new_shape);
}
- return true;
}
-rb_shape_t *
+void
rb_shape_transition_shape_frozen(VALUE obj)
{
rb_shape_t* shape = rb_shape_get_shape(obj);
@@ -667,20 +288,21 @@ rb_shape_transition_shape_frozen(VALUE obj)
RUBY_ASSERT(RB_OBJ_FROZEN(obj));
if (rb_shape_frozen_shape_p(shape) || rb_shape_obj_too_complex(obj)) {
- return shape;
+ return;
}
rb_shape_t* next_shape;
if (shape == rb_shape_get_root_shape()) {
- return rb_shape_get_shape_by_id(SPECIAL_CONST_SHAPE_ID);
+ rb_shape_set_shape_id(obj, SPECIAL_CONST_SHAPE_ID);
+ return;
}
bool dont_care;
next_shape = get_next_shape_internal(shape, (ID)id_frozen, SHAPE_FROZEN, &dont_care, true);
RUBY_ASSERT(next_shape);
- return next_shape;
+ rb_shape_set_shape(obj, next_shape);
}
/*
@@ -695,20 +317,10 @@ rb_shape_get_next_iv_shape(rb_shape_t* shape, ID id)
return get_next_shape_internal(shape, id, SHAPE_IVAR, &dont_care, true);
}
-static inline rb_shape_t *
-shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
+rb_shape_t *
+rb_shape_get_next(rb_shape_t* shape, VALUE obj, ID id)
{
RUBY_ASSERT(!is_instance_id(id) || RTEST(rb_sym2str(ID2SYM(id))));
- if (UNLIKELY(shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
- return shape;
- }
-
-#if RUBY_DEBUG
- attr_index_t index;
- if (rb_shape_get_iv_index(shape, id, &index)) {
- rb_bug("rb_shape_get_next: trying to create ivar that already exists at index %u", index);
- }
-#endif
bool allow_new_shape = true;
@@ -718,7 +330,12 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
}
bool variation_created = false;
- rb_shape_t *new_shape = get_next_shape_internal(shape, id, SHAPE_IVAR, &variation_created, allow_new_shape);
+ rb_shape_t * new_shape = get_next_shape_internal(shape, id, SHAPE_IVAR, &variation_created, allow_new_shape);
+
+ if (!new_shape) {
+ RUBY_ASSERT(BUILTIN_TYPE(obj) == T_OBJECT);
+ new_shape = rb_shape_get_shape_by_id(OBJ_TOO_COMPLEX_SHAPE_ID);
+ }
// Check if we should update max_iv_count on the object's class
if (BUILTIN_TYPE(obj) == T_OBJECT) {
@@ -729,17 +346,6 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
if (variation_created) {
RCLASS_EXT(klass)->variation_count++;
- if (emit_warnings && rb_warning_category_enabled_p(RB_WARN_CATEGORY_PERFORMANCE)) {
- if (RCLASS_EXT(klass)->variation_count >= SHAPE_MAX_VARIATIONS) {
- rb_category_warn(
- RB_WARN_CATEGORY_PERFORMANCE,
- "The class %"PRIsVALUE" reached %d shape variations, instance variables accesses will be slower and memory usage increased.\n"
- "It is recommended to define instance variables in a consistent order, for instance by eagerly defining them all in the #initialize method.",
- rb_class_path(klass),
- SHAPE_MAX_VARIATIONS
- );
- }
- }
}
}
@@ -747,76 +353,22 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
}
rb_shape_t *
-rb_shape_get_next(rb_shape_t *shape, VALUE obj, ID id)
+rb_shape_transition_shape_capa(rb_shape_t* shape, uint32_t new_capacity)
{
- return shape_get_next(shape, obj, id, true);
-}
-
-rb_shape_t *
-rb_shape_get_next_no_warnings(rb_shape_t *shape, VALUE obj, ID id)
-{
- return shape_get_next(shape, obj, id, false);
+ ID edge_name = rb_make_temporary_id(new_capacity);
+ bool dont_care;
+ rb_shape_t * new_shape = get_next_shape_internal(shape, edge_name, SHAPE_CAPACITY_CHANGE, &dont_care, true);
+ new_shape->capacity = new_capacity;
+ return new_shape;
}
-// Same as rb_shape_get_iv_index, but uses a provided valid shape id and index
-// to return a result faster if branches of the shape tree are closely related.
bool
-rb_shape_get_iv_index_with_hint(shape_id_t shape_id, ID id, attr_index_t *value, shape_id_t *shape_id_hint)
+rb_shape_get_iv_index(rb_shape_t * shape, ID id, attr_index_t *value)
{
- attr_index_t index_hint = *value;
- rb_shape_t *shape = rb_shape_get_shape_by_id(shape_id);
- rb_shape_t *initial_shape = shape;
-
- if (*shape_id_hint == INVALID_SHAPE_ID) {
- *shape_id_hint = shape_id;
- return rb_shape_get_iv_index(shape, id, value);
- }
-
- rb_shape_t * shape_hint = rb_shape_get_shape_by_id(*shape_id_hint);
-
- // We assume it's likely shape_id_hint and shape_id have a close common
- // ancestor, so we check up to ANCESTOR_SEARCH_MAX_DEPTH ancestors before
- // eventually using the index, as in case of a match it will be faster.
- // However if the shape doesn't have an index, we walk the entire tree.
- int depth = INT_MAX;
- if (shape->ancestor_index && shape->next_iv_index >= ANCESTOR_CACHE_THRESHOLD) {
- depth = ANCESTOR_SEARCH_MAX_DEPTH;
- }
-
- while (depth > 0 && shape->next_iv_index > index_hint) {
- while (shape_hint->next_iv_index > shape->next_iv_index) {
- shape_hint = rb_shape_get_parent(shape_hint);
- }
-
- if (shape_hint == shape) {
- // We've found a common ancestor so use the index hint
- *value = index_hint;
- *shape_id_hint = rb_shape_id(shape);
- return true;
- }
- if (shape->edge_name == id) {
- // We found the matching id before a common ancestor
- *value = shape->next_iv_index - 1;
- *shape_id_hint = rb_shape_id(shape);
- return true;
- }
-
- shape = rb_shape_get_parent(shape);
- depth--;
- }
-
- // If the original shape had an index but its ancestor doesn't
- // we switch back to the original one as it will be faster.
- if (!shape->ancestor_index && initial_shape->ancestor_index) {
- shape = initial_shape;
- }
- *shape_id_hint = shape_id;
- return rb_shape_get_iv_index(shape, id, value);
-}
+ // It doesn't make sense to ask for the index of an IV that's stored
+ // on an object that is "too complex" as it uses a hash for storing IVs
+ RUBY_ASSERT(rb_shape_id(shape) != OBJ_TOO_COMPLEX_SHAPE_ID);
-static bool
-shape_get_iv_index(rb_shape_t *shape, ID id, attr_index_t *value)
-{
while (shape->parent_id != INVALID_SHAPE_ID) {
if (shape->edge_name == id) {
enum shape_type shape_type;
@@ -827,62 +379,64 @@ shape_get_iv_index(rb_shape_t *shape, ID id, attr_index_t *value)
RUBY_ASSERT(shape->next_iv_index > 0);
*value = shape->next_iv_index - 1;
return true;
+ case SHAPE_CAPACITY_CHANGE:
case SHAPE_ROOT:
+ case SHAPE_INITIAL_CAPACITY:
case SHAPE_T_OBJECT:
return false;
case SHAPE_OBJ_TOO_COMPLEX:
case SHAPE_FROZEN:
- rb_bug("Ivar should not exist on transition");
+ rb_bug("Ivar should not exist on transition\n");
}
}
-
shape = rb_shape_get_parent(shape);
}
-
return false;
}
-static bool
-shape_cache_get_iv_index(rb_shape_t *shape, ID id, attr_index_t *value)
+static rb_shape_t *
+shape_alloc(void)
{
- if (shape->ancestor_index && shape->next_iv_index >= ANCESTOR_CACHE_THRESHOLD) {
- redblack_node_t *node = redblack_find(shape->ancestor_index, id);
- if (node) {
- rb_shape_t *shape = redblack_value(node);
- *value = shape->next_iv_index - 1;
+ rb_vm_t *vm = GET_VM();
+ shape_id_t shape_id = vm->next_shape_id;
+ vm->next_shape_id++;
-#if RUBY_DEBUG
- attr_index_t shape_tree_index;
- RUBY_ASSERT(shape_get_iv_index(shape, id, &shape_tree_index));
- RUBY_ASSERT(shape_tree_index == *value);
-#endif
+ if (shape_id == MAX_SHAPE_ID) {
+ // TODO: Make an OutOfShapesError ??
+ rb_bug("Out of shapes\n");
+ }
- return true;
- }
+ return &GET_VM()->shape_list[shape_id];
+}
- /* Verify the cache is correct by checking that this instance variable
- * does not exist in the shape tree either. */
- RUBY_ASSERT(!shape_get_iv_index(shape, id, value));
- }
+rb_shape_t *
+rb_shape_alloc_with_parent_id(ID edge_name, shape_id_t parent_id)
+{
+ rb_shape_t * shape = shape_alloc();
- return false;
+ shape->edge_name = edge_name;
+ shape->next_iv_index = 0;
+ shape->parent_id = parent_id;
+
+ return shape;
}
-bool
-rb_shape_get_iv_index(rb_shape_t *shape, ID id, attr_index_t *value)
+rb_shape_t *
+rb_shape_alloc_with_size_pool_index(ID edge_name, rb_shape_t * parent, uint8_t size_pool_index)
{
- // It doesn't make sense to ask for the index of an IV that's stored
- // on an object that is "too complex" as it uses a hash for storing IVs
- RUBY_ASSERT(rb_shape_id(shape) != OBJ_TOO_COMPLEX_SHAPE_ID);
+ rb_shape_t * shape = rb_shape_alloc_with_parent_id(edge_name, rb_shape_id(parent));
+ shape->size_pool_index = size_pool_index;
+ return shape;
+}
- if (!shape_cache_get_iv_index(shape, id, value)) {
- return shape_get_iv_index(shape, id, value);
- }
- return true;
+rb_shape_t *
+rb_shape_alloc(ID edge_name, rb_shape_t * parent)
+{
+ return rb_shape_alloc_with_size_pool_index(edge_name, parent, parent->size_pool_index);
}
-void
+MJIT_FUNC_EXPORTED void
rb_shape_set_shape(VALUE obj, rb_shape_t* shape)
{
rb_shape_set_shape_id(obj, rb_shape_id(shape));
@@ -915,29 +469,20 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap
}
VALUE lookup_result;
- if (SINGLE_CHILD_P(next_shape->edges)) {
- rb_shape_t * child = SINGLE_CHILD(next_shape->edges);
- if (child->edge_name == dest_shape->edge_name) {
- return child;
- }
- else {
- return NULL;
- }
+ if (rb_id_table_lookup(next_shape->edges, dest_shape->edge_name, &lookup_result)) {
+ next_shape = (rb_shape_t *)lookup_result;
}
else {
- if (rb_id_table_lookup(next_shape->edges, dest_shape->edge_name, &lookup_result)) {
- next_shape = (rb_shape_t *)lookup_result;
- }
- else {
- return NULL;
- }
+ return NULL;
}
break;
case SHAPE_ROOT:
+ case SHAPE_CAPACITY_CHANGE:
+ case SHAPE_INITIAL_CAPACITY:
case SHAPE_T_OBJECT:
break;
case SHAPE_OBJ_TOO_COMPLEX:
- rb_bug("Unreachable");
+ rb_bug("Unreachable\n");
break;
}
@@ -947,18 +492,12 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap
rb_shape_t *
rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape)
{
- RUBY_ASSERT(rb_shape_id(initial_shape) != OBJ_TOO_COMPLEX_SHAPE_ID);
- RUBY_ASSERT(rb_shape_id(dest_shape) != OBJ_TOO_COMPLEX_SHAPE_ID);
-
rb_shape_t * midway_shape;
RUBY_ASSERT(initial_shape->type == SHAPE_T_OBJECT);
if (dest_shape->type != initial_shape->type) {
midway_shape = rb_shape_rebuild_shape(initial_shape, rb_shape_get_parent(dest_shape));
- if (UNLIKELY(rb_shape_id(midway_shape) == OBJ_TOO_COMPLEX_SHAPE_ID)) {
- return midway_shape;
- }
}
else {
midway_shape = initial_shape;
@@ -966,36 +505,46 @@ rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape)
switch ((enum shape_type)dest_shape->type) {
case SHAPE_IVAR:
+ if (midway_shape->capacity <= midway_shape->next_iv_index) {
+ // There isn't enough room to write this IV, so we need to increase the capacity
+ midway_shape = rb_shape_transition_shape_capa(midway_shape, midway_shape->capacity * 2);
+ }
+
midway_shape = rb_shape_get_next_iv_shape(midway_shape, dest_shape->edge_name);
break;
case SHAPE_ROOT:
case SHAPE_FROZEN:
+ case SHAPE_CAPACITY_CHANGE:
+ case SHAPE_INITIAL_CAPACITY:
case SHAPE_T_OBJECT:
break;
case SHAPE_OBJ_TOO_COMPLEX:
- rb_bug("Unreachable");
+ rb_bug("Unreachable\n");
break;
}
return midway_shape;
}
-RUBY_FUNC_EXPORTED bool
+bool
rb_shape_obj_too_complex(VALUE obj)
{
return rb_shape_get_shape_id(obj) == OBJ_TOO_COMPLEX_SHAPE_ID;
}
+void
+rb_shape_set_too_complex(VALUE obj)
+{
+ RUBY_ASSERT(BUILTIN_TYPE(obj) == T_OBJECT);
+ RUBY_ASSERT(!rb_shape_obj_too_complex(obj));
+ rb_shape_set_shape_id(obj, OBJ_TOO_COMPLEX_SHAPE_ID);
+}
+
size_t
rb_shape_edges_count(rb_shape_t *shape)
{
if (shape->edges) {
- if (SINGLE_CHILD_P(shape->edges)) {
- return 1;
- }
- else {
- return rb_id_table_size(shape->edges);
- }
+ return rb_id_table_size(shape->edges);
}
return 0;
}
@@ -1004,7 +553,7 @@ size_t
rb_shape_memsize(rb_shape_t *shape)
{
size_t memsize = sizeof(rb_shape_t);
- if (shape->edges && !SINGLE_CHILD_P(shape->edges)) {
+ if (shape->edges) {
memsize += rb_id_table_memsize(shape->edges);
}
return memsize;
@@ -1075,13 +624,7 @@ rb_shape_edges(VALUE self)
VALUE hash = rb_hash_new();
if (shape->edges) {
- if (SINGLE_CHILD_P(shape->edges)) {
- rb_shape_t * child = SINGLE_CHILD(shape->edges);
- rb_edges_to_hash(child->edge_name, (VALUE)child, &hash);
- }
- else {
- rb_id_table_foreach(shape->edges, rb_edges_to_hash, &hash);
- }
+ rb_id_table_foreach(shape->edges, rb_edges_to_hash, &hash);
}
return hash;
@@ -1136,23 +679,6 @@ rb_shape_root_shape(VALUE self)
return rb_shape_t_to_rb_cShape(rb_shape_get_root_shape());
}
-/* :nodoc: */
-static VALUE
-rb_shape_shapes_available(VALUE self)
-{
- return INT2NUM(MAX_SHAPE_ID - (GET_SHAPE_TREE()->next_shape_id - 1));
-}
-
-/* :nodoc: */
-static VALUE
-rb_shape_exhaust(int argc, VALUE *argv, VALUE self)
-{
- rb_check_arity(argc, 0, 1);
- int offset = argc == 1 ? NUM2INT(argv[0]) : 0;
- GET_SHAPE_TREE()->next_shape_id = MAX_SHAPE_ID - offset + 1;
- return Qnil;
-}
-
VALUE rb_obj_shape(rb_shape_t* shape);
static enum rb_id_table_iterator_result collect_keys_and_values(ID key, VALUE value, void *ref)
@@ -1164,13 +690,8 @@ static enum rb_id_table_iterator_result collect_keys_and_values(ID key, VALUE va
static VALUE edges(struct rb_id_table* edges)
{
VALUE hash = rb_hash_new();
- if (SINGLE_CHILD_P(edges)) {
- rb_shape_t * child = SINGLE_CHILD(edges);
- collect_keys_and_values(child->edge_name, (VALUE)child, &hash);
- }
- else {
+ if (edges)
rb_id_table_foreach(edges, collect_keys_and_values, &hash);
- }
return hash;
}
@@ -1206,74 +727,38 @@ static VALUE
rb_shape_find_by_id(VALUE mod, VALUE id)
{
shape_id_t shape_id = NUM2UINT(id);
- if (shape_id >= GET_SHAPE_TREE()->next_shape_id) {
+ if (shape_id >= GET_VM()->next_shape_id) {
rb_raise(rb_eArgError, "Shape ID %d is out of bounds\n", shape_id);
}
return rb_shape_t_to_rb_cShape(rb_shape_get_shape_by_id(shape_id));
}
#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-
void
Init_default_shapes(void)
{
- rb_shape_tree_t *st = ruby_mimmalloc(sizeof(rb_shape_tree_t));
- memset(st, 0, sizeof(rb_shape_tree_t));
- rb_shape_tree_ptr = st;
-
-#ifdef HAVE_MMAP
- rb_shape_tree_ptr->shape_list = (rb_shape_t *)mmap(NULL, rb_size_mul_or_raise(SHAPE_BUFFER_SIZE, sizeof(rb_shape_t), rb_eRuntimeError),
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (GET_SHAPE_TREE()->shape_list == MAP_FAILED) {
- GET_SHAPE_TREE()->shape_list = 0;
- }
-#else
- GET_SHAPE_TREE()->shape_list = xcalloc(SHAPE_BUFFER_SIZE, sizeof(rb_shape_t));
-#endif
-
- if (!GET_SHAPE_TREE()->shape_list) {
- rb_memerror();
- }
-
id_frozen = rb_make_internal_id();
id_t_object = rb_make_internal_id();
-#ifdef HAVE_MMAP
- rb_shape_tree_ptr->shape_cache = (redblack_node_t *)mmap(NULL, rb_size_mul_or_raise(REDBLACK_CACHE_SIZE, sizeof(redblack_node_t), rb_eRuntimeError),
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- rb_shape_tree_ptr->cache_size = 0;
-
- // If mmap fails, then give up on the redblack tree cache.
- // We set the cache size such that the redblack node allocators think
- // the cache is full.
- if (GET_SHAPE_TREE()->shape_cache == MAP_FAILED) {
- GET_SHAPE_TREE()->shape_cache = 0;
- GET_SHAPE_TREE()->cache_size = REDBLACK_CACHE_SIZE;
- }
-#endif
-
// Shapes by size pool
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
size_pool_edge_names[i] = rb_make_internal_id();
}
// Root shape
- rb_shape_t *root = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
- root->capacity = 0;
+ rb_shape_t * root = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
+ root->capacity = (uint32_t)((rb_size_pool_slot_size(0) - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
root->type = SHAPE_ROOT;
root->size_pool_index = 0;
- GET_SHAPE_TREE()->root_shape = root;
- RUBY_ASSERT(rb_shape_id(GET_SHAPE_TREE()->root_shape) == ROOT_SHAPE_ID);
+ GET_VM()->root_shape = root;
+ RUBY_ASSERT(rb_shape_id(GET_VM()->root_shape) == ROOT_SHAPE_ID);
// Shapes by size pool
for (int i = 1; i < SIZE_POOL_COUNT; i++) {
- rb_shape_t *new_shape = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
- new_shape->type = SHAPE_ROOT;
+ uint32_t capa = (uint32_t)((rb_size_pool_slot_size(i) - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
+ rb_shape_t * new_shape = rb_shape_transition_shape_capa(root, capa);
+ new_shape->type = SHAPE_INITIAL_CAPACITY;
new_shape->size_pool_index = i;
- new_shape->ancestor_index = LEAF;
RUBY_ASSERT(rb_shape_id(new_shape) == (shape_id_t)i);
}
@@ -1283,9 +768,7 @@ Init_default_shapes(void)
bool dont_care;
rb_shape_t * t_object_shape =
get_next_shape_internal(shape, id_t_object, SHAPE_T_OBJECT, &dont_care, true);
- t_object_shape->capacity = (uint32_t)((rb_size_pool_slot_size(i) - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
t_object_shape->edges = rb_id_table_create(0);
- t_object_shape->ancestor_index = LEAF;
RUBY_ASSERT(rb_shape_id(t_object_shape) == (shape_id_t)(i + SIZE_POOL_COUNT));
}
@@ -1296,13 +779,13 @@ Init_default_shapes(void)
#endif
get_next_shape_internal(root, (ID)id_frozen, SHAPE_FROZEN, &dont_care, true);
RUBY_ASSERT(rb_shape_id(special_const_shape) == SPECIAL_CONST_SHAPE_ID);
- RUBY_ASSERT(SPECIAL_CONST_SHAPE_ID == (GET_SHAPE_TREE()->next_shape_id - 1));
+ RUBY_ASSERT(SPECIAL_CONST_SHAPE_ID == (GET_VM()->next_shape_id - 1));
RUBY_ASSERT(rb_shape_frozen_shape_p(special_const_shape));
rb_shape_t * hash_fallback_shape = rb_shape_alloc_with_parent_id(0, ROOT_SHAPE_ID);
hash_fallback_shape->type = SHAPE_OBJ_TOO_COMPLEX;
hash_fallback_shape->size_pool_index = 0;
- RUBY_ASSERT(OBJ_TOO_COMPLEX_SHAPE_ID == (GET_SHAPE_TREE()->next_shape_id - 1));
+ RUBY_ASSERT(OBJ_TOO_COMPLEX_SHAPE_ID == (GET_VM()->next_shape_id - 1));
RUBY_ASSERT(rb_shape_id(hash_fallback_shape) == OBJ_TOO_COMPLEX_SHAPE_ID);
}
@@ -1333,16 +816,10 @@ Init_shape(void)
rb_define_const(rb_cShape, "SPECIAL_CONST_SHAPE_ID", INT2NUM(SPECIAL_CONST_SHAPE_ID));
rb_define_const(rb_cShape, "OBJ_TOO_COMPLEX_SHAPE_ID", INT2NUM(OBJ_TOO_COMPLEX_SHAPE_ID));
rb_define_const(rb_cShape, "SHAPE_MAX_VARIATIONS", INT2NUM(SHAPE_MAX_VARIATIONS));
- rb_define_const(rb_cShape, "SIZEOF_RB_SHAPE_T", INT2NUM(sizeof(rb_shape_t)));
- rb_define_const(rb_cShape, "SIZEOF_REDBLACK_NODE_T", INT2NUM(sizeof(redblack_node_t)));
- rb_define_const(rb_cShape, "SHAPE_BUFFER_SIZE", INT2NUM(sizeof(rb_shape_t) * SHAPE_BUFFER_SIZE));
- rb_define_const(rb_cShape, "REDBLACK_CACHE_SIZE", INT2NUM(sizeof(redblack_node_t) * REDBLACK_CACHE_SIZE));
rb_define_singleton_method(rb_cShape, "transition_tree", shape_transition_tree, 0);
rb_define_singleton_method(rb_cShape, "find_by_id", rb_shape_find_by_id, 1);
rb_define_singleton_method(rb_cShape, "of", rb_shape_debug_shape, 1);
rb_define_singleton_method(rb_cShape, "root_shape", rb_shape_root_shape, 0);
- rb_define_singleton_method(rb_cShape, "shapes_available", rb_shape_shapes_available, 0);
- rb_define_singleton_method(rb_cShape, "exhaust_shapes", rb_shape_exhaust, -1);
#endif
}
diff --git a/shape.h b/shape.h
index 5fee17ebd9..8f3451d492 100644
--- a/shape.h
+++ b/shape.h
@@ -3,43 +3,42 @@
#include "internal/gc.h"
-#if (SIZEOF_UINT64_T <= SIZEOF_VALUE)
-
+#if (SIZEOF_UINT64_T == SIZEOF_VALUE)
#define SIZEOF_SHAPE_T 4
#define SHAPE_IN_BASIC_FLAGS 1
typedef uint32_t attr_index_t;
-typedef uint32_t shape_id_t;
-# define SHAPE_ID_NUM_BITS 32
-
#else
-
#define SIZEOF_SHAPE_T 2
#define SHAPE_IN_BASIC_FLAGS 0
typedef uint16_t attr_index_t;
-typedef uint16_t shape_id_t;
-# define SHAPE_ID_NUM_BITS 16
-
#endif
-typedef uint32_t redblack_id_t;
-
#define MAX_IVARS (attr_index_t)(-1)
+#if SIZEOF_SHAPE_T == 4
+typedef uint32_t shape_id_t;
+# define SHAPE_ID_NUM_BITS 32
+#else
+typedef uint16_t shape_id_t;
+# define SHAPE_ID_NUM_BITS 16
+#endif
+
# define SHAPE_MASK (((uintptr_t)1 << SHAPE_ID_NUM_BITS) - 1)
# define SHAPE_FLAG_MASK (((VALUE)-1) >> SHAPE_ID_NUM_BITS)
# define SHAPE_FLAG_SHIFT ((SIZEOF_VALUE * 8) - SHAPE_ID_NUM_BITS)
+# define SHAPE_BITMAP_SIZE 16384
+
# define SHAPE_MAX_VARIATIONS 8
+# define MAX_SHAPE_ID (SHAPE_MASK - 1)
# define INVALID_SHAPE_ID SHAPE_MASK
# define ROOT_SHAPE_ID 0x0
# define SPECIAL_CONST_SHAPE_ID (SIZE_POOL_COUNT * 2)
# define OBJ_TOO_COMPLEX_SHAPE_ID (SPECIAL_CONST_SHAPE_ID + 1)
-typedef struct redblack_node redblack_node_t;
-
struct rb_shape {
struct rb_id_table * edges; // id_table from ID (ivar) to next shape
ID edge_name; // ID (ivar) for transition from parent to rb_shape
@@ -48,53 +47,30 @@ struct rb_shape {
uint8_t type;
uint8_t size_pool_index;
shape_id_t parent_id;
- redblack_node_t * ancestor_index;
};
typedef struct rb_shape rb_shape_t;
-struct redblack_node {
- ID key;
- rb_shape_t * value;
- redblack_id_t l;
- redblack_id_t r;
-};
-
enum shape_type {
SHAPE_ROOT,
SHAPE_IVAR,
SHAPE_FROZEN,
+ SHAPE_CAPACITY_CHANGE,
+ SHAPE_INITIAL_CAPACITY,
SHAPE_T_OBJECT,
SHAPE_OBJ_TOO_COMPLEX,
};
-typedef struct {
- /* object shapes */
- rb_shape_t *shape_list;
- rb_shape_t *root_shape;
- shape_id_t next_shape_id;
-
- redblack_node_t *shape_cache;
- unsigned int cache_size;
-} rb_shape_tree_t;
-RUBY_EXTERN rb_shape_tree_t *rb_shape_tree_ptr;
-
-static inline rb_shape_tree_t *
-rb_current_shape_tree(void)
-{
- return rb_shape_tree_ptr;
-}
-#define GET_SHAPE_TREE() rb_current_shape_tree()
-
+#if SHAPE_IN_BASIC_FLAGS
static inline shape_id_t
-get_shape_id_from_flags(VALUE obj)
+RBASIC_SHAPE_ID(VALUE obj)
{
RUBY_ASSERT(!RB_SPECIAL_CONST_P(obj));
return (shape_id_t)(SHAPE_MASK & ((RBASIC(obj)->flags) >> SHAPE_FLAG_SHIFT));
}
static inline void
-set_shape_id_in_flags(VALUE obj, shape_id_t shape_id)
+RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
// Ractors are occupying the upper 32 bits of flags, but only in debug mode
// Object shapes are occupying top bits
@@ -102,68 +78,77 @@ set_shape_id_in_flags(VALUE obj, shape_id_t shape_id)
RBASIC(obj)->flags |= ((VALUE)(shape_id) << SHAPE_FLAG_SHIFT);
}
-
-#if SHAPE_IN_BASIC_FLAGS
static inline shape_id_t
-RBASIC_SHAPE_ID(VALUE obj)
+ROBJECT_SHAPE_ID(VALUE obj)
{
- return get_shape_id_from_flags(obj);
+ RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+ return RBASIC_SHAPE_ID(obj);
}
static inline void
-RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
+ROBJECT_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
- set_shape_id_in_flags(obj, shape_id);
+ RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+ RBASIC_SET_SHAPE_ID(obj, shape_id);
+}
+
+static inline shape_id_t
+RCLASS_SHAPE_ID(VALUE obj)
+{
+ RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
+ return RBASIC_SHAPE_ID(obj);
}
-#endif
+
+#else
static inline shape_id_t
ROBJECT_SHAPE_ID(VALUE obj)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
- return get_shape_id_from_flags(obj);
+ return (shape_id_t)(SHAPE_MASK & (RBASIC(obj)->flags >> SHAPE_FLAG_SHIFT));
}
static inline void
ROBJECT_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
- RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
- set_shape_id_in_flags(obj, shape_id);
+ RBASIC(obj)->flags &= SHAPE_FLAG_MASK;
+ RBASIC(obj)->flags |= ((VALUE)(shape_id) << SHAPE_FLAG_SHIFT);
}
-static inline shape_id_t
-RCLASS_SHAPE_ID(VALUE obj)
-{
- RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
- return get_shape_id_from_flags(obj);
-}
+MJIT_SYMBOL_EXPORT_BEGIN
+shape_id_t rb_rclass_shape_id(VALUE obj);
+MJIT_SYMBOL_EXPORT_END
-static inline void
-RCLASS_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
+static inline shape_id_t RCLASS_SHAPE_ID(VALUE obj)
{
- RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
- set_shape_id_in_flags(obj, shape_id);
+ return rb_rclass_shape_id(obj);
}
+#endif
+
+bool rb_shape_root_shape_p(rb_shape_t* shape);
rb_shape_t * rb_shape_get_root_shape(void);
+uint8_t rb_shape_id_num_bits(void);
int32_t rb_shape_id_offset(void);
+rb_shape_t* rb_shape_get_shape_by_id_without_assertion(shape_id_t shape_id);
rb_shape_t * rb_shape_get_parent(rb_shape_t * shape);
+MJIT_SYMBOL_EXPORT_BEGIN
rb_shape_t* rb_shape_get_shape_by_id(shape_id_t shape_id);
shape_id_t rb_shape_get_shape_id(VALUE obj);
rb_shape_t * rb_shape_get_next_iv_shape(rb_shape_t * shape, ID id);
bool rb_shape_get_iv_index(rb_shape_t * shape, ID id, attr_index_t * value);
-bool rb_shape_get_iv_index_with_hint(shape_id_t shape_id, ID id, attr_index_t * value, shape_id_t *shape_id_hint);
bool rb_shape_obj_too_complex(VALUE obj);
+MJIT_SYMBOL_EXPORT_END
void rb_shape_set_shape(VALUE obj, rb_shape_t* shape);
rb_shape_t* rb_shape_get_shape(VALUE obj);
int rb_shape_frozen_shape_p(rb_shape_t* shape);
-rb_shape_t* rb_shape_transition_shape_frozen(VALUE obj);
-bool rb_shape_transition_shape_remove_ivar(VALUE obj, ID id, rb_shape_t *shape, VALUE * removed);
+void rb_shape_transition_shape_frozen(VALUE obj);
+void rb_shape_transition_shape_remove_ivar(VALUE obj, ID id, rb_shape_t *shape, VALUE * removed);
+rb_shape_t * rb_shape_transition_shape_capa(rb_shape_t * shape, uint32_t new_capacity);
rb_shape_t* rb_shape_get_next(rb_shape_t* shape, VALUE obj, ID id);
-rb_shape_t* rb_shape_get_next_no_warnings(rb_shape_t* shape, VALUE obj, ID id);
rb_shape_t * rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape);
@@ -173,7 +158,7 @@ ROBJECT_IV_CAPACITY(VALUE obj)
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
// Asking for capacity doesn't make sense when the object is using
// a hash table for storing instance variables
- RUBY_ASSERT(!rb_shape_obj_too_complex(obj));
+ RUBY_ASSERT(ROBJECT_SHAPE_ID(obj) != OBJ_TOO_COMPLEX_SHAPE_ID);
return rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj))->capacity;
}
@@ -181,15 +166,15 @@ static inline st_table *
ROBJECT_IV_HASH(VALUE obj)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
- RUBY_ASSERT(rb_shape_obj_too_complex(obj));
+ RUBY_ASSERT(ROBJECT_SHAPE_ID(obj) == OBJ_TOO_COMPLEX_SHAPE_ID);
return (st_table *)ROBJECT(obj)->as.heap.ivptr;
}
static inline void
-ROBJECT_SET_IV_HASH(VALUE obj, const st_table *tbl)
+ROBJECT_SET_IV_HASH(VALUE obj, const struct rb_id_table *tbl)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
- RUBY_ASSERT(rb_shape_obj_too_complex(obj));
+ RUBY_ASSERT(ROBJECT_SHAPE_ID(obj) == OBJ_TOO_COMPLEX_SHAPE_ID);
ROBJECT(obj)->as.heap.ivptr = (VALUE *)tbl;
}
@@ -198,12 +183,12 @@ size_t rb_id_table_size(const struct rb_id_table *tbl);
static inline uint32_t
ROBJECT_IV_COUNT(VALUE obj)
{
- if (rb_shape_obj_too_complex(obj)) {
+ if (ROBJECT_SHAPE_ID(obj) == OBJ_TOO_COMPLEX_SHAPE_ID) {
return (uint32_t)rb_st_table_size(ROBJECT_IV_HASH(obj));
}
else {
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
- RUBY_ASSERT(!rb_shape_obj_too_complex(obj));
+ RUBY_ASSERT(ROBJECT_SHAPE_ID(obj) != OBJ_TOO_COMPLEX_SHAPE_ID);
return rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj))->next_iv_index;
}
}
@@ -214,11 +199,25 @@ RBASIC_IV_COUNT(VALUE obj)
return rb_shape_get_shape_by_id(rb_shape_get_shape_id(obj))->next_iv_index;
}
+static inline uint32_t
+RCLASS_IV_COUNT(VALUE obj)
+{
+ RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
+ uint32_t ivc = rb_shape_get_shape_by_id(RCLASS_SHAPE_ID(obj))->next_iv_index;
+ return ivc;
+}
+
+rb_shape_t * rb_shape_alloc(ID edge_name, rb_shape_t * parent);
+rb_shape_t * rb_shape_alloc_with_size_pool_index(ID edge_name, rb_shape_t * parent, uint8_t size_pool_index);
+rb_shape_t * rb_shape_alloc_with_parent_id(ID edge_name, shape_id_t parent_id);
+
rb_shape_t *rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *orig_shape);
bool rb_shape_set_shape_id(VALUE obj, shape_id_t shape_id);
VALUE rb_obj_debug_shape(VALUE self, VALUE obj);
+VALUE rb_shape_flags_mask(void);
+void rb_shape_set_too_complex(VALUE obj);
// For ext/objspace
RUBY_SYMBOL_EXPORT_BEGIN
diff --git a/signal.c b/signal.c
index bef3b2e537..1072cb47f1 100644
--- a/signal.c
+++ b/signal.c
@@ -36,7 +36,6 @@
#include "debug_counter.h"
#include "eval_intern.h"
#include "internal.h"
-#include "internal/error.h"
#include "internal/eval.h"
#include "internal/sanitizers.h"
#include "internal/signal.h"
@@ -45,6 +44,7 @@
#include "ruby_atomic.h"
#include "vm_core.h"
#include "ractor_core.h"
+#include "ruby/internal/attr/nonstring.h"
#ifdef NEED_RUBY_ATOMIC_OPS
rb_atomic_t
@@ -133,7 +133,7 @@ static const struct signals {
#ifdef SIGCONT
{"CONT", SIGCONT},
#endif
-#ifdef RUBY_SIGCHLD
+#if RUBY_SIGCHLD
{"CHLD", RUBY_SIGCHLD },
{"CLD", RUBY_SIGCHLD },
#endif
@@ -403,9 +403,6 @@ interrupt_init(int argc, VALUE *argv, VALUE self)
}
void rb_malloc_info_show_results(void); /* gc.c */
-#if defined(USE_SIGALTSTACK) || defined(_WIN32)
-static void reset_sigmask(int sig);
-#endif
void
ruby_default_signal(int sig)
@@ -416,9 +413,6 @@ ruby_default_signal(int sig)
rb_malloc_info_show_results();
signal(sig, SIG_DFL);
-#if defined(USE_SIGALTSTACK) || defined(_WIN32)
- reset_sigmask(sig);
-#endif
raise(sig);
}
@@ -515,6 +509,9 @@ static struct {
rb_atomic_t cnt[RUBY_NSIG];
rb_atomic_t size;
} signal_buff;
+#if RUBY_SIGCHLD
+volatile unsigned int ruby_nocldwait;
+#endif
#define sighandler_t ruby_sighandler_t
@@ -612,6 +609,27 @@ ruby_signal(int signum, sighandler_t handler)
#endif
switch (signum) {
+#if RUBY_SIGCHLD
+ case RUBY_SIGCHLD:
+ if (handler == SIG_IGN) {
+ ruby_nocldwait = 1;
+# ifdef USE_SIGALTSTACK
+ if (sigact.sa_flags & SA_SIGINFO) {
+ sigact.sa_sigaction = (ruby_sigaction_t*)sighandler;
+ }
+ else {
+ sigact.sa_handler = sighandler;
+ }
+# else
+ sigact.sa_handler = handler;
+ sigact.sa_flags = 0;
+# endif
+ }
+ else {
+ ruby_nocldwait = 0;
+ }
+ break;
+#endif
#if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
case SIGSEGV:
#ifdef SIGBUS
@@ -634,7 +652,7 @@ ruby_signal(int signum, sighandler_t handler)
}
sighandler_t
-ruby_posix_signal(int signum, sighandler_t handler)
+posix_signal(int signum, sighandler_t handler)
{
return ruby_signal(signum, handler);
}
@@ -690,14 +708,35 @@ signal_enque(int sig)
ATOMIC_INC(signal_buff.size);
}
+#if RUBY_SIGCHLD
+static rb_atomic_t sigchld_hit;
+/* destructive getter than simple predicate */
+# define GET_SIGCHLD_HIT() ATOMIC_EXCHANGE(sigchld_hit, 0)
+#else
+# define GET_SIGCHLD_HIT() 0
+#endif
+
static void
sighandler(int sig)
{
int old_errnum = errno;
- signal_enque(sig);
- rb_thread_wakeup_timer_thread(sig);
+ /* the VM always needs to handle SIGCHLD for rb_waitpid */
+ if (sig == RUBY_SIGCHLD) {
+#if RUBY_SIGCHLD
+ rb_vm_t *vm = GET_VM();
+ ATOMIC_EXCHANGE(sigchld_hit, 1);
+ /* avoid spurious wakeup in main thread if and only if nobody uses trap(:CHLD) */
+ if (vm && ACCESS_ONCE(VALUE, vm->trap_list.cmd[sig])) {
+ signal_enque(sig);
+ }
+#endif
+ }
+ else {
+ signal_enque(sig);
+ }
+ rb_thread_wakeup_timer_thread(sig);
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
ruby_signal(sig, sighandler);
#endif
@@ -886,10 +925,10 @@ check_stack_overflow(int sig, const void *addr)
#endif
#if defined SIGSEGV || defined SIGBUS || defined SIGILL || defined SIGFPE
-NOINLINE(static void check_reserved_signal_(const char *name, size_t name_len, int signo));
+NOINLINE(static void check_reserved_signal_(const char *name, size_t name_len));
/* noinine to reduce stack usage in signal handers */
-#define check_reserved_signal(name) check_reserved_signal_(name, sizeof(name)-1, sig)
+#define check_reserved_signal(name) check_reserved_signal_(name, sizeof(name)-1)
#ifdef SIGBUS
@@ -961,38 +1000,33 @@ ruby_abort(void)
}
static void
-check_reserved_signal_(const char *name, size_t name_len, int signo)
+check_reserved_signal_(const char *name, size_t name_len)
{
const char *prev = ATOMIC_PTR_EXCHANGE(received_signal, name);
if (prev) {
ssize_t RB_UNUSED_VAR(err);
- static const int stderr_fd = 2;
-#define NOZ(name, str) name[sizeof(str)-1] = str
+#define NOZ(name, str) RBIMPL_ATTR_NONSTRING() name[sizeof(str)-1] = str
static const char NOZ(msg1, " received in ");
static const char NOZ(msg2, " handler\n");
#ifdef HAVE_WRITEV
struct iovec iov[4];
- int i = 0;
-# define W(str, len) \
- iov[i++] = (struct iovec){.iov_base = (void *)(str), .iov_len = (len)}
-#else
-# define W(str, len) err = write(stderr_fd, (str), (len))
-#endif
-#if __has_feature(address_sanitizer) || \
- __has_feature(memory_sanitizer) || \
- defined(HAVE_VALGRIND_MEMCHECK_H)
- ruby_posix_signal(signo, SIG_DFL);
-#endif
- W(name, name_len);
- W(msg1, sizeof(msg1));
- W(prev, strlen(prev));
- W(msg2, sizeof(msg2));
-# undef W
-#ifdef HAVE_WRITEV
- err = writev(stderr_fd, iov, i);
+ iov[0].iov_base = (void *)name;
+ iov[0].iov_len = name_len;
+ iov[1].iov_base = (void *)msg1;
+ iov[1].iov_len = sizeof(msg1);
+ iov[2].iov_base = (void *)prev;
+ iov[2].iov_len = strlen(prev);
+ iov[3].iov_base = (void *)msg2;
+ iov[3].iov_len = sizeof(msg2);
+ err = writev(2, iov, 4);
+#else
+ err = write(2, name, name_len);
+ err = write(2, msg1, sizeof(msg1));
+ err = write(2, prev, strlen(prev));
+ err = write(2, msg2, sizeof(msg2));
#endif
ruby_abort();
}
@@ -1052,6 +1086,16 @@ rb_vm_trap_exit(rb_vm_t *vm)
}
}
+void ruby_waitpid_all(rb_vm_t *); /* process.c */
+
+void
+ruby_sigchld_handler(rb_vm_t *vm)
+{
+ if (SIGCHLD_LOSSY || GET_SIGCHLD_HIT()) {
+ ruby_waitpid_all(vm);
+ }
+}
+
/* returns true if a trap handler was run, false otherwise */
int
rb_signal_exec(rb_thread_t *th, int sig)
@@ -1119,7 +1163,7 @@ default_handler(int sig)
#ifdef SIGUSR2
case SIGUSR2:
#endif
-#ifdef RUBY_SIGCHLD
+#if RUBY_SIGCHLD
case RUBY_SIGCHLD:
#endif
func = sighandler;
@@ -1187,6 +1231,9 @@ trap_handler(VALUE *cmd, int sig)
break;
case 14:
if (memcmp(cptr, "SYSTEM_DEFAULT", 14) == 0) {
+ if (sig == RUBY_SIGCHLD) {
+ goto sig_dfl;
+ }
func = SIG_DFL;
*cmd = 0;
}
@@ -1337,7 +1384,7 @@ reserved_signal_p(int signo)
* Signal.trap("CLD") { puts "Child died" }
* fork && Process.wait
*
- * <em>produces:</em>
+ * produces:
* Terminating: 27461
* Child died
* Terminating: 27460
@@ -1404,7 +1451,6 @@ sig_list(VALUE _)
if (reserved_signal_p(signum)) rb_bug(failed); \
perror(failed); \
} while (0)
-
static int
install_sighandler_core(int signum, sighandler_t handler, sighandler_t *old_handler)
{
@@ -1429,6 +1475,25 @@ install_sighandler_core(int signum, sighandler_t handler, sighandler_t *old_hand
# define force_install_sighandler(signum, handler, old_handler) \
INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, old_handler), #signum, signum)
+#if RUBY_SIGCHLD
+static int
+init_sigchld(int sig)
+{
+ sighandler_t oldfunc;
+ sighandler_t func = sighandler;
+
+ oldfunc = ruby_signal(sig, SIG_DFL);
+ if (oldfunc == SIG_ERR) return -1;
+ ruby_signal(sig, func);
+ ACCESS_ONCE(VALUE, GET_VM()->trap_list.cmd[sig]) = 0;
+
+ return 0;
+}
+
+# define init_sigchld(signum) \
+ INSTALL_SIGHANDLER(init_sigchld(signum), #signum, signum)
+#endif
+
void
ruby_sig_finalize(void)
{
@@ -1440,6 +1505,7 @@ ruby_sig_finalize(void)
}
}
+
int ruby_enable_coredump = 0;
/*
@@ -1470,10 +1536,10 @@ int ruby_enable_coredump = 0;
* # ...
* Process.kill("TERM", pid)
*
- * <em>produces:</em>
+ * produces:
* Debug now: true
* Debug now: false
- * Terminating...
+ * Terminating...
*
* The list of available signal names and their interpretation is
* system dependent. Signal delivery semantics may also vary between
@@ -1494,9 +1560,6 @@ Init_signal(void)
rb_alias(rb_eSignal, rb_intern_const("signm"), rb_intern_const("message"));
rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
- // It should be ready to call rb_signal_exec()
- VM_ASSERT(GET_THREAD()->pending_interrupt_queue);
-
/* At this time, there is no subthread. Then sigmask guarantee atomics. */
rb_disable_interrupt();
@@ -1539,8 +1602,8 @@ Init_signal(void)
install_sighandler(SIGSYS, sig_do_nothing);
#endif
-#ifdef RUBY_SIGCHLD
- install_sighandler(RUBY_SIGCHLD, sighandler);
+#if RUBY_SIGCHLD
+ init_sigchld(RUBY_SIGCHLD);
#endif
rb_enable_interrupt();
@@ -1561,5 +1624,33 @@ fake_grantfd(int masterfd)
int
rb_grantpt(int masterfd)
{
- return grantpt(masterfd);
+ if (RUBY_SIGCHLD) {
+ rb_vm_t *vm = GET_VM();
+ int ret, e;
+
+ /*
+ * Prevent waitpid calls from Ruby by taking waitpid_lock.
+ * Pedantically, grantpt(3) is undefined if a non-default
+ * SIGCHLD handler is defined, but preventing conflicting
+ * waitpid calls ought to be sufficient.
+ *
+ * We could install the default sighandler temporarily, but that
+ * could cause SIGCHLD to be missed by other threads. Blocking
+ * SIGCHLD won't work here, either, unless we stop and restart
+ * timer-thread (as only timer-thread sees SIGCHLD), but that
+ * seems like overkill.
+ */
+ rb_nativethread_lock_lock(&vm->waitpid_lock);
+ {
+ ret = grantpt(masterfd); /* may spawn `pt_chown' and wait on it */
+ if (ret < 0) e = errno;
+ }
+ rb_nativethread_lock_unlock(&vm->waitpid_lock);
+
+ if (ret < 0) errno = e;
+ return ret;
+ }
+ else {
+ return grantpt(masterfd);
+ }
}
diff --git a/siphash.c b/siphash.c
index 61b8604fc9..62de622778 100644
--- a/siphash.c
+++ b/siphash.c
@@ -140,6 +140,9 @@ xor64_to(uint64_t *v, const uint64_t s)
#endif
static const union {
+#if defined(__has_attribute) && __has_attribute(nonstring)
+ __attribute__((nonstring))
+#endif
char bin[32];
uint64_t u64[4];
} sip_init_state_bin = {"uespemos""modnarod""arenegyl""setybdet"};
diff --git a/spec/README.md b/spec/README.md
index 6a88c06e09..4fcf090759 100644
--- a/spec/README.md
+++ b/spec/README.md
@@ -91,24 +91,24 @@ To run all specs:
make test-spec
```
-Extra arguments can be added via `SPECOPTS`.
+Extra arguments can be added via `MSPECOPT`.
For instance, to show the help:
```bash
-make test-spec SPECOPTS=-h
+make test-spec MSPECOPT=-h
```
You can also run the specs in parallel, which is currently experimental.
It takes around 10s instead of 60s on a quad-core laptop.
```bash
-make test-spec SPECOPTS=-j
+make test-spec MSPECOPT=-j
```
To run a specific test, add its path to the command:
```bash
-make test-spec SPECOPTS=spec/ruby/language/for_spec.rb
+make test-spec MSPECOPT=spec/ruby/language/for_spec.rb
```
If ruby trunk is your current `ruby` in `$PATH`, you can also run `mspec` directly:
diff --git a/spec/bundler/bundler/bundler_spec.rb b/spec/bundler/bundler/bundler_spec.rb
index 6a2e435e54..54fedc8568 100644
--- a/spec/bundler/bundler/bundler_spec.rb
+++ b/spec/bundler/bundler/bundler_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Bundler do
describe "#load_marshal" do
it "is a private method and raises an error" do
data = Marshal.dump(Bundler)
- expect { Bundler.load_marshal(data) }.to raise_error(NoMethodError, /private method [`']load_marshal' called/)
+ expect { Bundler.load_marshal(data) }.to raise_error(NoMethodError, /private method `load_marshal' called/)
end
it "loads any data" do
@@ -23,7 +23,7 @@ RSpec.describe Bundler do
end
it "loads simple structure" do
- simple_structure = { "name" => [:development] }
+ simple_structure = { "name" => [:abc] }
data = Marshal.dump(simple_structure)
expect(Bundler.safe_load_marshal(data)).to eq(simple_structure)
end
@@ -76,7 +76,7 @@ RSpec.describe Bundler do
context "with incorrect YAML file" do
before do
File.open(app_gemspec_path, "wb") do |f|
- f.write <<~GEMSPEC
+ f.write strip_whitespace(<<-GEMSPEC)
---
{:!00 ao=gu\g1= 7~f
GEMSPEC
@@ -88,7 +88,7 @@ RSpec.describe Bundler do
end
end
- context "with correct YAML file", if: defined?(Encoding) do
+ context "with correct YAML file", :if => defined?(Encoding) do
it "can load a gemspec with unicode characters with default ruby encoding" do
# spec_helper forces the external encoding to UTF-8 but that's not the
# default until Ruby 2.0
@@ -99,7 +99,7 @@ RSpec.describe Bundler do
$VERBOSE = verbose
File.open(app_gemspec_path, "wb") do |file|
- file.puts <<~GEMSPEC
+ file.puts <<-GEMSPEC.gsub(/^\s+/, "")
# -*- encoding: utf-8 -*-
Gem::Specification.new do |gem|
gem.author = "André the Giant"
@@ -139,7 +139,7 @@ RSpec.describe Bundler do
end
GEMSPEC
end
- expect(Bundler.rubygems).to receive(:validate).with have_attributes(name: "validated")
+ expect(Bundler.rubygems).to receive(:validate).with have_attributes(:name => "validated")
subject
end
end
@@ -147,7 +147,7 @@ RSpec.describe Bundler do
context "with gemspec containing local variables" do
before do
File.open(app_gemspec_path, "wb") do |f|
- f.write <<~GEMSPEC
+ f.write strip_whitespace(<<-GEMSPEC)
must_not_leak = true
Gem::Specification.new do |gem|
gem.name = "leak check"
@@ -224,6 +224,24 @@ RSpec.describe Bundler do
end
end
+ describe "#rm_rf" do
+ context "the directory is world writable" do
+ let(:bundler_ui) { Bundler.ui }
+ it "should raise a friendly error" do
+ allow(File).to receive(:exist?).and_return(true)
+ allow(::Bundler::FileUtils).to receive(:remove_entry_secure).and_raise(ArgumentError)
+ allow(File).to receive(:world_writable?).and_return(true)
+ message = <<EOF
+It is a security vulnerability to allow your home directory to be world-writable, and bundler cannot continue.
+You should probably consider fixing this issue by running `chmod o-w ~` on *nix.
+Please refer to https://ruby-doc.org/stdlib-3.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
+EOF
+ expect(bundler_ui).to receive(:warn).with(message)
+ expect { Bundler.send(:rm_rf, bundled_app) }.to raise_error(Bundler::PathError)
+ end
+ end
+ end
+
describe "#mkdir_p" do
it "creates a folder at the given path" do
install_gemfile <<-G
diff --git a/spec/bundler/bundler/ci_detector_spec.rb b/spec/bundler/bundler/ci_detector_spec.rb
deleted file mode 100644
index 299d8005e8..0000000000
--- a/spec/bundler/bundler/ci_detector_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe Bundler::CIDetector do
- # This is properly tested in rubygems, under the name Gem::CIDetector
- # But the test that confirms that our version _stays in sync_ with that version
- # will live here.
-
- it "stays in sync with the rubygems implementation" do
- rubygems_implementation_path = File.join(git_root, "lib", "rubygems", "ci_detector.rb")
- expect(File.exist?(rubygems_implementation_path)).to be_truthy
- rubygems_code = File.read(rubygems_implementation_path)
- denamespaced_rubygems_code = rubygems_code.sub("Gem", "NAMESPACE")
-
- bundler_implementation_path = File.join(source_lib_dir, "bundler", "ci_detector.rb")
- expect(File.exist?(bundler_implementation_path)).to be_truthy
- bundler_code = File.read(bundler_implementation_path)
- denamespaced_bundler_code = bundler_code.sub("Bundler", "NAMESPACE")
-
- expect(denamespaced_bundler_code).to eq(denamespaced_rubygems_code)
- end
-end
diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb
index c71fc8e9e7..b752cd7e70 100644
--- a/spec/bundler/bundler/cli_spec.rb
+++ b/spec/bundler/bundler/cli_spec.rb
@@ -4,12 +4,12 @@ require "bundler/cli"
RSpec.describe "bundle executable" do
it "returns non-zero exit status when passed unrecognized options" do
- bundle "--invalid_argument", raise_on_error: false
+ bundle "--invalid_argument", :raise_on_error => false
expect(exitstatus).to_not be_zero
end
it "returns non-zero exit status when passed unrecognized task" do
- bundle "unrecognized-task", raise_on_error: false
+ bundle "unrecognized-task", :raise_on_error => false
expect(exitstatus).to_not be_zero
end
@@ -87,7 +87,7 @@ RSpec.describe "bundle executable" do
end
context "with no arguments" do
- it "prints a concise help message", bundler: "3" do
+ it "prints a concise help message", :bundler => "3" do
bundle ""
expect(err).to be_empty
expect(out).to include("Bundler version #{Bundler::VERSION}").
@@ -105,7 +105,7 @@ RSpec.describe "bundle executable" do
gem 'rack'
G
- bundle :install, env: { "BUNDLE_GEMFILE" => "" }
+ bundle :install, :env => { "BUNDLE_GEMFILE" => "" }
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -114,17 +114,17 @@ RSpec.describe "bundle executable" do
context "with --verbose" do
it "prints the running command" do
gemfile "source \"#{file_uri_for(gem_repo1)}\""
- bundle "info bundler", verbose: true
+ bundle "info bundler", :verbose => true
expect(out).to start_with("Running `bundle info bundler --verbose` with bundler #{Bundler::VERSION}")
end
it "doesn't print defaults" do
- install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", verbose: true
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", :verbose => true
expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}")
end
it "doesn't print defaults" do
- install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", verbose: true
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", :verbose => true
expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}")
end
end
@@ -133,7 +133,7 @@ RSpec.describe "bundle executable" do
let(:run_command) do
bundle "install"
- bundle "outdated #{flags}", raise_on_error: false
+ bundle "outdated #{flags}", :raise_on_error => false
end
before do
@@ -178,7 +178,7 @@ RSpec.describe "bundle executable" do
describe "printing the outdated warning" do
shared_examples_for "no warning" do
it "prints no warning" do
- bundle "fail", env: { "BUNDLER_VERSION" => bundler_version }, raise_on_error: false
+ bundle "fail", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
expect(last_command.stdboth).to eq("Could not find command \"fail\".")
end
end
@@ -213,7 +213,7 @@ RSpec.describe "bundle executable" do
context "when the latest version is greater than the current version" do
let(:latest_version) { "222.0" }
it "prints the version warning" do
- bundle "fail", env: { "BUNDLER_VERSION" => bundler_version }, raise_on_error: false
+ bundle "fail", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
expect(err).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
To update to the most recent version, run `bundle update --bundler`
@@ -221,16 +221,16 @@ To update to the most recent version, run `bundle update --bundler`
end
context "and disable_version_check is set" do
- before { bundle "config set disable_version_check true", env: { "BUNDLER_VERSION" => bundler_version } }
+ before { bundle "config set disable_version_check true", :env => { "BUNDLER_VERSION" => bundler_version } }
include_examples "no warning"
end
context "running a parseable command" do
it "prints no warning" do
- bundle "config get --parseable foo", env: { "BUNDLER_VERSION" => bundler_version }
+ bundle "config get --parseable foo", :env => { "BUNDLER_VERSION" => bundler_version }
expect(last_command.stdboth).to eq ""
- bundle "platform --ruby", env: { "BUNDLER_VERSION" => bundler_version }, raise_on_error: false
+ bundle "platform --ruby", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
expect(last_command.stdboth).to eq "Could not locate Gemfile"
end
end
@@ -238,7 +238,7 @@ To update to the most recent version, run `bundle update --bundler`
context "and is a pre-release" do
let(:latest_version) { "222.0.0.pre.4" }
it "prints the version warning" do
- bundle "fail", env: { "BUNDLER_VERSION" => bundler_version }, raise_on_error: false
+ bundle "fail", :env => { "BUNDLER_VERSION" => bundler_version }, :raise_on_error => false
expect(err).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
To update to the most recent version, run `bundle update --bundler`
@@ -250,12 +250,12 @@ To update to the most recent version, run `bundle update --bundler`
end
RSpec.describe "bundler executable" do
- it "shows the bundler version just as the `bundle` executable does", bundler: "< 3" do
+ it "shows the bundler version just as the `bundle` executable does", :bundler => "< 3" do
bundler "--version"
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
- it "shows the bundler version just as the `bundle` executable does", bundler: "3" do
+ it "shows the bundler version just as the `bundle` executable does", :bundler => "3" do
bundler "--version"
expect(out).to eq(Bundler::VERSION)
end
diff --git a/spec/bundler/bundler/compact_index_client/updater_spec.rb b/spec/bundler/bundler/compact_index_client/updater_spec.rb
index 6eed88ca9e..fe417e3920 100644
--- a/spec/bundler/bundler/compact_index_client/updater_spec.rb
+++ b/spec/bundler/bundler/compact_index_client/updater_spec.rb
@@ -1,224 +1,43 @@
# frozen_string_literal: true
-require "bundler/vendored_net_http"
+require "net/http"
require "bundler/compact_index_client"
require "bundler/compact_index_client/updater"
require "tmpdir"
RSpec.describe Bundler::CompactIndexClient::Updater do
- subject(:updater) { described_class.new(fetcher) }
-
let(:fetcher) { double(:fetcher) }
- let(:local_path) { Pathname.new(Dir.mktmpdir("localpath")).join("versions") }
- let(:etag_path) { Pathname.new(Dir.mktmpdir("localpath-etags")).join("versions.etag") }
+ let(:local_path) { Pathname.new Dir.mktmpdir("localpath") }
let(:remote_path) { double(:remote_path) }
- let(:full_body) { "abc123" }
- let(:response) { double(:response, body: full_body, is_a?: false) }
- let(:digest) { Digest::SHA256.base64digest(full_body) }
-
- context "when the local path does not exist" do
- before do
- allow(response).to receive(:[]).with("Repr-Digest") { nil }
- allow(response).to receive(:[]).with("Digest") { nil }
- allow(response).to receive(:[]).with("ETag") { '"thisisanetag"' }
- end
-
- it "downloads the file without attempting append" do
- expect(fetcher).to receive(:call).once.with(remote_path, {}) { response }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("thisisanetag")
- end
-
- it "fails immediately on bad checksum" do
- expect(fetcher).to receive(:call).once.with(remote_path, {}) { response }
- allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:baddigest:" }
-
- expect do
- updater.update(remote_path, local_path, etag_path)
- end.to raise_error(Bundler::CompactIndexClient::Updater::MismatchedChecksumError)
- end
- end
-
- context "when the local path exists" do
- let(:local_body) { "abc" }
-
- before do
- local_path.open("w") {|f| f.write(local_body) }
- end
-
- context "with an etag" do
- before do
- etag_path.open("w") {|f| f.write("LocalEtag") }
- end
-
- let(:headers) do
- {
- "If-None-Match" => '"LocalEtag"',
- "Range" => "bytes=2-",
- }
- end
-
- it "does nothing if etags match" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { false }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { true }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq("abc")
- expect(etag_path.read).to eq("LocalEtag")
- end
-
- it "appends the file if etags do not match" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:#{digest}:" }
- allow(response).to receive(:[]).with("ETag") { '"NewEtag"' }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { true }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { false }
- allow(response).to receive(:body) { "c123" }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("NewEtag")
- end
-
- it "replaces the file if response ignores range" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:#{digest}:" }
- allow(response).to receive(:[]).with("ETag") { '"NewEtag"' }
- allow(response).to receive(:body) { full_body }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("NewEtag")
- end
-
- it "tries the request again if the partial response fails digest check" do
- allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:baddigest:" }
- allow(response).to receive(:body) { "the beginning of the file changed" }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { true }
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
-
- full_response = double(:full_response, body: full_body, is_a?: false)
- allow(full_response).to receive(:[]).with("Repr-Digest") { "sha-256=:#{digest}:" }
- allow(full_response).to receive(:[]).with("ETag") { '"NewEtag"' }
- expect(fetcher).to receive(:call).once.with(remote_path, { "If-None-Match" => '"LocalEtag"' }).and_return(full_response)
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("NewEtag")
- end
- end
-
- context "without an etag file" do
- let(:headers) do
- {
- "Range" => "bytes=2-",
- # This MD5 feature should be deleted after sufficient time has passed since release.
- # From then on, requests that still don't have a saved etag will be made without this header.
- "If-None-Match" => %("#{Digest::MD5.hexdigest(local_body)}"),
- }
- end
-
- it "saves only the etag_path if generated etag matches" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { false }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { true }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq("abc")
- expect(%("#{etag_path.read}")).to eq(headers["If-None-Match"])
- end
-
- it "appends the file" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:#{digest}:" }
- allow(response).to receive(:[]).with("ETag") { '"OpaqueEtag"' }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { true }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { false }
- allow(response).to receive(:body) { "c123" }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("OpaqueEtag")
- end
-
- it "replaces the file on full file response that ignores range request" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:[]).with("Repr-Digest") { nil }
- allow(response).to receive(:[]).with("Digest") { nil }
- allow(response).to receive(:[]).with("ETag") { '"OpaqueEtag"' }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { false }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { false }
- allow(response).to receive(:body) { full_body }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("OpaqueEtag")
- end
-
- it "tries the request again if the partial response fails digest check" do
- allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:baddigest:" }
- allow(response).to receive(:body) { "the beginning of the file changed" }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { true }
- expect(fetcher).to receive(:call).once.with(remote_path, headers) do
- # During the failed first request, we simulate another process writing the etag.
- # This ensures the second request doesn't generate the md5 etag again but just uses whatever is written.
- etag_path.open("w") {|f| f.write("LocalEtag") }
- response
- end
-
- full_response = double(:full_response, body: full_body, is_a?: false)
- allow(full_response).to receive(:[]).with("Repr-Digest") { "sha-256=:#{digest}:" }
- allow(full_response).to receive(:[]).with("ETag") { '"NewEtag"' }
- expect(fetcher).to receive(:call).once.with(remote_path, { "If-None-Match" => '"LocalEtag"' }).and_return(full_response)
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq(full_body)
- expect(etag_path.read).to eq("NewEtag")
- end
- end
- end
+ let!(:updater) { described_class.new(fetcher) }
context "when the ETag header is missing" do
# Regression test for https://github.com/rubygems/bundler/issues/5463
- let(:response) { double(:response, body: full_body) }
+ let(:response) { double(:response, :body => "abc123") }
it "treats the response as an update" do
- allow(response).to receive(:[]).with("Repr-Digest") { nil }
- allow(response).to receive(:[]).with("Digest") { nil }
- allow(response).to receive(:[]).with("ETag") { nil }
+ expect(response).to receive(:[]).with("ETag") { nil }
expect(fetcher).to receive(:call) { response }
- updater.update(remote_path, local_path, etag_path)
+ updater.update(local_path, remote_path)
end
end
context "when the download is corrupt" do
- let(:response) { double(:response, body: "") }
+ let(:response) { double(:response, :body => "") }
it "raises HTTPError" do
expect(fetcher).to receive(:call).and_raise(Zlib::GzipFile::Error)
expect do
- updater.update(remote_path, local_path, etag_path)
+ updater.update(local_path, remote_path)
end.to raise_error(Bundler::HTTPError)
end
end
context "when receiving non UTF-8 data and default internal encoding set to ASCII" do
- let(:response) { double(:response, body: "\x8B".b) }
+ let(:response) { double(:response, :body => "\x8B".b) }
it "works just fine" do
old_verbose = $VERBOSE
@@ -227,12 +46,10 @@ RSpec.describe Bundler::CompactIndexClient::Updater do
begin
$VERBOSE = false
Encoding.default_internal = "ASCII"
- allow(response).to receive(:[]).with("Repr-Digest") { nil }
- allow(response).to receive(:[]).with("Digest") { nil }
- allow(response).to receive(:[]).with("ETag") { nil }
+ expect(response).to receive(:[]).with("ETag") { nil }
expect(fetcher).to receive(:call) { response }
- updater.update(remote_path, local_path, etag_path)
+ updater.update(local_path, remote_path)
ensure
Encoding.default_internal = previous_internal_encoding
$VERBOSE = old_verbose
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb
index 28c04e0860..59b958ae42 100644
--- a/spec/bundler/bundler/definition_spec.rb
+++ b/spec/bundler/bundler/definition_spec.rb
@@ -5,60 +5,58 @@ require "bundler/definition"
RSpec.describe Bundler::Definition do
describe "#lock" do
before do
- allow(Bundler::SharedHelpers).to receive(:find_gemfile) { bundled_app_gemfile }
- allow(Bundler).to receive(:ui) { double("UI", info: "", debug: "") }
+ allow(Bundler).to receive(:settings) { Bundler::Settings.new(".") }
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile) { Pathname.new("Gemfile") }
+ allow(Bundler).to receive(:ui) { double("UI", :info => "", :debug => "") }
end
-
- subject { Bundler::Definition.new(bundled_app_lock, [], Bundler::SourceList.new, {}) }
-
context "when it's not possible to write to the file" do
+ subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) }
+
it "raises an PermissionError with explanation" do
allow(File).to receive(:open).and_call_original
- expect(File).to receive(:open).with(bundled_app_lock, "wb").
+ expect(File).to receive(:open).with("Gemfile.lock", "wb").
and_raise(Errno::EACCES)
- expect { subject.lock }.
+ expect { subject.lock("Gemfile.lock") }.
to raise_error(Bundler::PermissionError, /Gemfile\.lock/)
end
end
context "when a temporary resource access issue occurs" do
+ subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) }
+
it "raises a TemporaryResourceError with explanation" do
allow(File).to receive(:open).and_call_original
- expect(File).to receive(:open).with(bundled_app_lock, "wb").
+ expect(File).to receive(:open).with("Gemfile.lock", "wb").
and_raise(Errno::EAGAIN)
- expect { subject.lock }.
+ expect { subject.lock("Gemfile.lock") }.
to raise_error(Bundler::TemporaryResourceError, /temporarily unavailable/)
end
end
context "when Bundler::Definition.no_lock is set to true" do
+ subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) }
before { Bundler::Definition.no_lock = true }
after { Bundler::Definition.no_lock = false }
it "does not create a lock file" do
- subject.lock
- expect(bundled_app_lock).not_to be_file
+ subject.lock("Gemfile.lock")
+ expect(File.file?("Gemfile.lock")).to eq false
end
end
end
describe "detects changes" do
it "for a path gem with changes" do
- build_lib "foo", "1.0", path: lib_path("foo")
+ build_lib "foo", "1.0", :path => lib_path("foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "1.0"
end
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo1, "rack", "1.0.0"
- end
-
- bundle :install, env: { "DEBUG" => "1" }
+ bundle :install, :env => { "DEBUG" => "1" }
expect(out).to match(/re-resolving dependencies/)
expect(lockfile).to eq <<~G
@@ -78,7 +76,7 @@ RSpec.describe Bundler::Definition do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -97,28 +95,26 @@ RSpec.describe Bundler::Definition do
bundle "lock --add-platform java"
- bundle "update ffi", env: { "DEBUG" => "1" }
+ bundle "update ffi", :env => { "DEBUG" => "1" }
expect(out).to match(/because bundler is unlocking gems: \(ffi\)/)
end
it "for a path gem with deps and no changes" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "1.0"
s.add_development_dependency "net-ssh", "1.0"
end
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo1, "rack", "1.0.0"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
G
- expected_lockfile = <<~G
+ bundle :check, :env => { "DEBUG" => "1" }
+
+ expect(out).to match(/using resolution from the lockfile/)
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
specs:
@@ -135,31 +131,20 @@ RSpec.describe Bundler::Definition do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
-
- expect(lockfile).to eq(expected_lockfile)
-
- bundle :check, env: { "DEBUG" => "1" }
-
- expect(out).to match(/using resolution from the lockfile/)
- expect(lockfile).to eq(expected_lockfile)
end
it "for a locked gem for another platform" do
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "only_java", "1.1", "java"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "only_java", platform: :jruby
G
bundle "lock --add-platform java"
- bundle :check, env: { "DEBUG" => "1" }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
expect(lockfile).to eq <<~G
@@ -173,23 +158,19 @@ RSpec.describe Bundler::Definition do
DEPENDENCIES
only_java
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "for a rubygems gem" do
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo1, "foo", "1.0"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo"
G
- bundle :check, env: { "DEBUG" => "1" }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
expect(lockfile).to eq <<~G
@@ -203,7 +184,7 @@ RSpec.describe Bundler::Definition do
DEPENDENCIES
foo
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -279,7 +260,7 @@ RSpec.describe Bundler::Definition do
bundled_app_lock,
updated_deps_in_gemfile,
source_list,
- gems: ["shared_owner_a"], conservative: true
+ :gems => ["shared_owner_a"], :conservative => true
)
locked = definition.send(:converge_locked_specs).map(&:name)
expect(locked).to eq %w[isolated_dep isolated_owner shared_dep shared_owner_b]
diff --git a/spec/bundler/bundler/dependency_spec.rb b/spec/bundler/bundler/dependency_spec.rb
index a953372742..6e346c36c1 100644
--- a/spec/bundler/bundler/dependency_spec.rb
+++ b/spec/bundler/bundler/dependency_spec.rb
@@ -40,128 +40,118 @@ RSpec.describe Bundler::Dependency do
# rubocop:disable Naming/VariableNumber
let(:platforms) do
- { ruby: Gem::Platform::RUBY,
- ruby_18: Gem::Platform::RUBY,
- ruby_19: Gem::Platform::RUBY,
- ruby_20: Gem::Platform::RUBY,
- ruby_21: Gem::Platform::RUBY,
- ruby_22: Gem::Platform::RUBY,
- ruby_23: Gem::Platform::RUBY,
- ruby_24: Gem::Platform::RUBY,
- ruby_25: Gem::Platform::RUBY,
- ruby_26: Gem::Platform::RUBY,
- ruby_27: Gem::Platform::RUBY,
- ruby_30: Gem::Platform::RUBY,
- ruby_31: Gem::Platform::RUBY,
- ruby_32: Gem::Platform::RUBY,
- ruby_33: Gem::Platform::RUBY,
- ruby_34: Gem::Platform::RUBY,
- mri: Gem::Platform::RUBY,
- mri_18: Gem::Platform::RUBY,
- mri_19: Gem::Platform::RUBY,
- mri_20: Gem::Platform::RUBY,
- mri_21: Gem::Platform::RUBY,
- mri_22: Gem::Platform::RUBY,
- mri_23: Gem::Platform::RUBY,
- mri_24: Gem::Platform::RUBY,
- mri_25: Gem::Platform::RUBY,
- mri_26: Gem::Platform::RUBY,
- mri_27: Gem::Platform::RUBY,
- mri_30: Gem::Platform::RUBY,
- mri_31: Gem::Platform::RUBY,
- mri_32: Gem::Platform::RUBY,
- mri_33: Gem::Platform::RUBY,
- mri_34: Gem::Platform::RUBY,
- rbx: Gem::Platform::RUBY,
- truffleruby: Gem::Platform::RUBY,
- jruby: Gem::Platform::JAVA,
- jruby_18: Gem::Platform::JAVA,
- jruby_19: Gem::Platform::JAVA,
- windows: Gem::Platform::WINDOWS,
- windows_18: Gem::Platform::WINDOWS,
- windows_19: Gem::Platform::WINDOWS,
- windows_20: Gem::Platform::WINDOWS,
- windows_21: Gem::Platform::WINDOWS,
- windows_22: Gem::Platform::WINDOWS,
- windows_23: Gem::Platform::WINDOWS,
- windows_24: Gem::Platform::WINDOWS,
- windows_25: Gem::Platform::WINDOWS,
- windows_26: Gem::Platform::WINDOWS,
- windows_27: Gem::Platform::WINDOWS,
- windows_30: Gem::Platform::WINDOWS,
- windows_31: Gem::Platform::WINDOWS,
- windows_32: Gem::Platform::WINDOWS,
- windows_33: Gem::Platform::WINDOWS,
- windows_34: Gem::Platform::WINDOWS }
- end
-
- let(:deprecated) do
- { mswin: Gem::Platform::MSWIN,
- mswin_18: Gem::Platform::MSWIN,
- mswin_19: Gem::Platform::MSWIN,
- mswin_20: Gem::Platform::MSWIN,
- mswin_21: Gem::Platform::MSWIN,
- mswin_22: Gem::Platform::MSWIN,
- mswin_23: Gem::Platform::MSWIN,
- mswin_24: Gem::Platform::MSWIN,
- mswin_25: Gem::Platform::MSWIN,
- mswin_26: Gem::Platform::MSWIN,
- mswin_27: Gem::Platform::MSWIN,
- mswin_30: Gem::Platform::MSWIN,
- mswin_31: Gem::Platform::MSWIN,
- mswin_32: Gem::Platform::MSWIN,
- mswin_33: Gem::Platform::MSWIN,
- mswin_34: Gem::Platform::MSWIN,
- mswin64: Gem::Platform::MSWIN64,
- mswin64_19: Gem::Platform::MSWIN64,
- mswin64_20: Gem::Platform::MSWIN64,
- mswin64_21: Gem::Platform::MSWIN64,
- mswin64_22: Gem::Platform::MSWIN64,
- mswin64_23: Gem::Platform::MSWIN64,
- mswin64_24: Gem::Platform::MSWIN64,
- mswin64_25: Gem::Platform::MSWIN64,
- mswin64_26: Gem::Platform::MSWIN64,
- mswin64_27: Gem::Platform::MSWIN64,
- mswin64_30: Gem::Platform::MSWIN64,
- mswin64_31: Gem::Platform::MSWIN64,
- mswin64_32: Gem::Platform::MSWIN64,
- mswin64_33: Gem::Platform::MSWIN64,
- mswin64_34: Gem::Platform::MSWIN64,
- mingw: Gem::Platform::MINGW,
- mingw_18: Gem::Platform::MINGW,
- mingw_19: Gem::Platform::MINGW,
- mingw_20: Gem::Platform::MINGW,
- mingw_21: Gem::Platform::MINGW,
- mingw_22: Gem::Platform::MINGW,
- mingw_23: Gem::Platform::MINGW,
- mingw_24: Gem::Platform::MINGW,
- mingw_25: Gem::Platform::MINGW,
- mingw_26: Gem::Platform::MINGW,
- mingw_27: Gem::Platform::MINGW,
- mingw_30: Gem::Platform::MINGW,
- mingw_31: Gem::Platform::MINGW,
- mingw_32: Gem::Platform::MINGW,
- mingw_33: Gem::Platform::MINGW,
- mingw_34: Gem::Platform::MINGW,
- x64_mingw: Gem::Platform::X64_MINGW,
- x64_mingw_20: Gem::Platform::X64_MINGW,
- x64_mingw_21: Gem::Platform::X64_MINGW,
- x64_mingw_22: Gem::Platform::X64_MINGW,
- x64_mingw_23: Gem::Platform::X64_MINGW,
- x64_mingw_24: Gem::Platform::X64_MINGW,
- x64_mingw_25: Gem::Platform::X64_MINGW,
- x64_mingw_26: Gem::Platform::X64_MINGW,
- x64_mingw_27: Gem::Platform::X64_MINGW,
- x64_mingw_30: Gem::Platform::X64_MINGW,
- x64_mingw_31: Gem::Platform::X64_MINGW,
- x64_mingw_32: Gem::Platform::X64_MINGW,
- x64_mingw_33: Gem::Platform::X64_MINGW,
- x64_mingw_34: Gem::Platform::X64_MINGW }
+ { :ruby => Gem::Platform::RUBY,
+ :ruby_18 => Gem::Platform::RUBY,
+ :ruby_19 => Gem::Platform::RUBY,
+ :ruby_20 => Gem::Platform::RUBY,
+ :ruby_21 => Gem::Platform::RUBY,
+ :ruby_22 => Gem::Platform::RUBY,
+ :ruby_23 => Gem::Platform::RUBY,
+ :ruby_24 => Gem::Platform::RUBY,
+ :ruby_25 => Gem::Platform::RUBY,
+ :ruby_26 => Gem::Platform::RUBY,
+ :ruby_27 => Gem::Platform::RUBY,
+ :ruby_30 => Gem::Platform::RUBY,
+ :ruby_31 => Gem::Platform::RUBY,
+ :ruby_32 => Gem::Platform::RUBY,
+ :ruby_33 => Gem::Platform::RUBY,
+ :mri => Gem::Platform::RUBY,
+ :mri_18 => Gem::Platform::RUBY,
+ :mri_19 => Gem::Platform::RUBY,
+ :mri_20 => Gem::Platform::RUBY,
+ :mri_21 => Gem::Platform::RUBY,
+ :mri_22 => Gem::Platform::RUBY,
+ :mri_23 => Gem::Platform::RUBY,
+ :mri_24 => Gem::Platform::RUBY,
+ :mri_25 => Gem::Platform::RUBY,
+ :mri_26 => Gem::Platform::RUBY,
+ :mri_27 => Gem::Platform::RUBY,
+ :mri_30 => Gem::Platform::RUBY,
+ :mri_31 => Gem::Platform::RUBY,
+ :mri_32 => Gem::Platform::RUBY,
+ :mri_33 => Gem::Platform::RUBY,
+ :rbx => Gem::Platform::RUBY,
+ :truffleruby => Gem::Platform::RUBY,
+ :jruby => Gem::Platform::JAVA,
+ :jruby_18 => Gem::Platform::JAVA,
+ :jruby_19 => Gem::Platform::JAVA,
+ :windows => Gem::Platform::WINDOWS,
+ :windows_18 => Gem::Platform::WINDOWS,
+ :windows_19 => Gem::Platform::WINDOWS,
+ :windows_20 => Gem::Platform::WINDOWS,
+ :windows_21 => Gem::Platform::WINDOWS,
+ :windows_22 => Gem::Platform::WINDOWS,
+ :windows_23 => Gem::Platform::WINDOWS,
+ :windows_24 => Gem::Platform::WINDOWS,
+ :windows_25 => Gem::Platform::WINDOWS,
+ :windows_26 => Gem::Platform::WINDOWS,
+ :windows_27 => Gem::Platform::WINDOWS,
+ :windows_30 => Gem::Platform::WINDOWS,
+ :windows_31 => Gem::Platform::WINDOWS,
+ :windows_32 => Gem::Platform::WINDOWS,
+ :windows_33 => Gem::Platform::WINDOWS,
+ :mswin => Gem::Platform::MSWIN,
+ :mswin_18 => Gem::Platform::MSWIN,
+ :mswin_19 => Gem::Platform::MSWIN,
+ :mswin_20 => Gem::Platform::MSWIN,
+ :mswin_21 => Gem::Platform::MSWIN,
+ :mswin_22 => Gem::Platform::MSWIN,
+ :mswin_23 => Gem::Platform::MSWIN,
+ :mswin_24 => Gem::Platform::MSWIN,
+ :mswin_25 => Gem::Platform::MSWIN,
+ :mswin_26 => Gem::Platform::MSWIN,
+ :mswin_27 => Gem::Platform::MSWIN,
+ :mswin_30 => Gem::Platform::MSWIN,
+ :mswin_31 => Gem::Platform::MSWIN,
+ :mswin_32 => Gem::Platform::MSWIN,
+ :mswin_33 => Gem::Platform::MSWIN,
+ :mswin64 => Gem::Platform::MSWIN64,
+ :mswin64_19 => Gem::Platform::MSWIN64,
+ :mswin64_20 => Gem::Platform::MSWIN64,
+ :mswin64_21 => Gem::Platform::MSWIN64,
+ :mswin64_22 => Gem::Platform::MSWIN64,
+ :mswin64_23 => Gem::Platform::MSWIN64,
+ :mswin64_24 => Gem::Platform::MSWIN64,
+ :mswin64_25 => Gem::Platform::MSWIN64,
+ :mswin64_26 => Gem::Platform::MSWIN64,
+ :mswin64_27 => Gem::Platform::MSWIN64,
+ :mswin64_30 => Gem::Platform::MSWIN64,
+ :mswin64_31 => Gem::Platform::MSWIN64,
+ :mswin64_32 => Gem::Platform::MSWIN64,
+ :mswin64_33 => Gem::Platform::MSWIN64,
+ :mingw => Gem::Platform::MINGW,
+ :mingw_18 => Gem::Platform::MINGW,
+ :mingw_19 => Gem::Platform::MINGW,
+ :mingw_20 => Gem::Platform::MINGW,
+ :mingw_21 => Gem::Platform::MINGW,
+ :mingw_22 => Gem::Platform::MINGW,
+ :mingw_23 => Gem::Platform::MINGW,
+ :mingw_24 => Gem::Platform::MINGW,
+ :mingw_25 => Gem::Platform::MINGW,
+ :mingw_26 => Gem::Platform::MINGW,
+ :mingw_27 => Gem::Platform::MINGW,
+ :mingw_30 => Gem::Platform::MINGW,
+ :mingw_31 => Gem::Platform::MINGW,
+ :mingw_32 => Gem::Platform::MINGW,
+ :mingw_33 => Gem::Platform::MINGW,
+ :x64_mingw => Gem::Platform::X64_MINGW,
+ :x64_mingw_20 => Gem::Platform::X64_MINGW,
+ :x64_mingw_21 => Gem::Platform::X64_MINGW,
+ :x64_mingw_22 => Gem::Platform::X64_MINGW,
+ :x64_mingw_23 => Gem::Platform::X64_MINGW,
+ :x64_mingw_24 => Gem::Platform::X64_MINGW,
+ :x64_mingw_25 => Gem::Platform::X64_MINGW,
+ :x64_mingw_26 => Gem::Platform::X64_MINGW,
+ :x64_mingw_27 => Gem::Platform::X64_MINGW,
+ :x64_mingw_30 => Gem::Platform::X64_MINGW,
+ :x64_mingw_31 => Gem::Platform::X64_MINGW,
+ :x64_mingw_32 => Gem::Platform::X64_MINGW,
+ :x64_mingw_33 => Gem::Platform::X64_MINGW }
end
# rubocop:enable Naming/VariableNumber
it "includes all platforms" do
- expect(subject).to eq(platforms.merge(deprecated))
+ expect(subject).to eq(platforms)
end
end
end
diff --git a/spec/bundler/bundler/digest_spec.rb b/spec/bundler/bundler/digest_spec.rb
index f876827964..841cc0259e 100644
--- a/spec/bundler/bundler/digest_spec.rb
+++ b/spec/bundler/bundler/digest_spec.rb
@@ -1,17 +1,17 @@
# frozen_string_literal: true
-require "openssl"
+require "digest"
require "bundler/digest"
RSpec.describe Bundler::Digest do
context "SHA1" do
subject { Bundler::Digest }
- let(:stdlib) { OpenSSL::Digest::SHA1 }
+ let(:stdlib) { ::Digest::SHA1 }
it "is compatible with stdlib" do
random_strings = ["foo", "skfjsdlkfjsdf", "3924m", "ldskfj"]
- # https://www.rfc-editor.org/rfc/rfc3174#section-7.3
+ # https://datatracker.ietf.org/doc/html/rfc3174#section-7.3
rfc3174_test_cases = ["abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "a", "01234567" * 8]
(random_strings + rfc3174_test_cases).each do |payload|
diff --git a/spec/bundler/bundler/dsl_spec.rb b/spec/bundler/bundler/dsl_spec.rb
index 3c3b6c26c3..8b5bf930f2 100644
--- a/spec/bundler/bundler/dsl_spec.rb
+++ b/spec/bundler/bundler/dsl_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Bundler::Dsl do
it "registers custom hosts" do
subject.git_source(:example) {|repo_name| "git@git.example.com:#{repo_name}.git" }
subject.git_source(:foobar) {|repo_name| "git@foobar.com:#{repo_name}.git" }
- subject.gem("dobry-pies", example: "strzalek/dobry-pies")
+ subject.gem("dobry-pies", :example => "strzalek/dobry-pies")
example_uri = "git@git.example.com:strzalek/dobry-pies.git"
expect(subject.dependencies.first.source.uri).to eq(example_uri)
end
@@ -26,136 +26,85 @@ RSpec.describe Bundler::Dsl do
end
it "converts :github PR to URI using https" do
- subject.gem("sparks", github: "https://github.com/indirect/sparks/pull/5")
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5")
github_uri = "https://github.com/indirect/sparks.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
expect(subject.dependencies.first.source.ref).to eq("refs/pull/5/head")
end
- it "converts :gitlab PR to URI using https" do
- subject.gem("sparks", gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5")
- gitlab_uri = "https://gitlab.com/indirect/sparks.git"
- expect(subject.dependencies.first.source.uri).to eq(gitlab_uri)
- expect(subject.dependencies.first.source.ref).to eq("refs/merge-requests/5/head")
- end
-
it "rejects :github PR URI with a branch, ref or tag" do
expect do
- subject.gem("sparks", github: "https://github.com/indirect/sparks/pull/5", branch: "foo")
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5", :branch => "foo")
end.to raise_error(
Bundler::GemfileError,
%(The :branch option can't be used with `github: "https://github.com/indirect/sparks/pull/5"`),
)
expect do
- subject.gem("sparks", github: "https://github.com/indirect/sparks/pull/5", ref: "foo")
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5", :ref => "foo")
end.to raise_error(
Bundler::GemfileError,
%(The :ref option can't be used with `github: "https://github.com/indirect/sparks/pull/5"`),
)
expect do
- subject.gem("sparks", github: "https://github.com/indirect/sparks/pull/5", tag: "foo")
+ subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5", :tag => "foo")
end.to raise_error(
Bundler::GemfileError,
%(The :tag option can't be used with `github: "https://github.com/indirect/sparks/pull/5"`),
)
end
- it "rejects :gitlab PR URI with a branch, ref or tag" do
- expect do
- subject.gem("sparks", gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5", branch: "foo")
- end.to raise_error(
- Bundler::GemfileError,
- %(The :branch option can't be used with `gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5"`),
- )
-
- expect do
- subject.gem("sparks", gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5", ref: "foo")
- end.to raise_error(
- Bundler::GemfileError,
- %(The :ref option can't be used with `gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5"`),
- )
-
- expect do
- subject.gem("sparks", gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5", tag: "foo")
- end.to raise_error(
- Bundler::GemfileError,
- %(The :tag option can't be used with `gitlab: "https://gitlab.com/indirect/sparks/-/merge_requests/5"`),
- )
- end
-
it "rejects :github with :git" do
expect do
- subject.gem("sparks", github: "indirect/sparks", git: "https://github.com/indirect/sparks.git")
+ subject.gem("sparks", :github => "indirect/sparks", :git => "https://github.com/indirect/sparks.git")
end.to raise_error(
Bundler::GemfileError,
%(The :git option can't be used with `github: "indirect/sparks"`),
)
end
- it "rejects :gitlab with :git" do
- expect do
- subject.gem("sparks", gitlab: "indirect/sparks", git: "https://gitlab.com/indirect/sparks.git")
- end.to raise_error(
- Bundler::GemfileError,
- %(The :git option can't be used with `gitlab: "indirect/sparks"`),
- )
- end
-
- context "default hosts", bundler: "< 3" do
+ context "default hosts", :bundler => "< 3" do
it "converts :github to URI using https" do
- subject.gem("sparks", github: "indirect/sparks")
+ subject.gem("sparks", :github => "indirect/sparks")
github_uri = "https://github.com/indirect/sparks.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
it "converts :github shortcut to URI using https" do
- subject.gem("sparks", github: "rails")
+ subject.gem("sparks", :github => "rails")
github_uri = "https://github.com/rails/rails.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
- it "converts :gitlab to URI using https" do
- subject.gem("sparks", gitlab: "indirect/sparks")
- gitlab_uri = "https://gitlab.com/indirect/sparks.git"
- expect(subject.dependencies.first.source.uri).to eq(gitlab_uri)
- end
-
- it "converts :gitlab shortcut to URI using https" do
- subject.gem("sparks", gitlab: "rails")
- gitlab_uri = "https://gitlab.com/rails/rails.git"
- expect(subject.dependencies.first.source.uri).to eq(gitlab_uri)
- end
-
it "converts numeric :gist to :git" do
- subject.gem("not-really-a-gem", gist: 2_859_988)
+ subject.gem("not-really-a-gem", :gist => 2_859_988)
github_uri = "https://gist.github.com/2859988.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
it "converts :gist to :git" do
- subject.gem("not-really-a-gem", gist: "2859988")
+ subject.gem("not-really-a-gem", :gist => "2859988")
github_uri = "https://gist.github.com/2859988.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri)
end
it "converts :bitbucket to :git" do
- subject.gem("not-really-a-gem", bitbucket: "mcorp/flatlab-rails")
+ subject.gem("not-really-a-gem", :bitbucket => "mcorp/flatlab-rails")
bitbucket_uri = "https://mcorp@bitbucket.org/mcorp/flatlab-rails.git"
expect(subject.dependencies.first.source.uri).to eq(bitbucket_uri)
end
it "converts 'mcorp' to 'mcorp/mcorp'" do
- subject.gem("not-really-a-gem", bitbucket: "mcorp")
+ subject.gem("not-really-a-gem", :bitbucket => "mcorp")
bitbucket_uri = "https://mcorp@bitbucket.org/mcorp/mcorp.git"
expect(subject.dependencies.first.source.uri).to eq(bitbucket_uri)
end
end
context "default git sources" do
- it "has bitbucket, gist, github, and gitlab" do
- expect(subject.instance_variable_get(:@git_sources).keys.sort).to eq(%w[bitbucket gist github gitlab])
+ it "has bitbucket, gist, and github" do
+ expect(subject.instance_variable_get(:@git_sources).keys.sort).to eq(%w[bitbucket gist github])
end
end
end
@@ -185,17 +134,6 @@ RSpec.describe Bundler::Dsl do
expect { subject.eval_gemfile("Gemfile") }.
to raise_error(Bundler::GemfileError, /There was an error evaluating `Gemfile`: ruby_version must match the :engine_version for MRI/)
end
-
- it "populates __dir__ and __FILE__ correctly" do
- abs_path = source_root.join("../fragment.rb").to_s
- expect(Bundler).to receive(:read_file).with(abs_path).and_return(<<~RUBY)
- @fragment_dir = __dir__
- @fragment_file = __FILE__
- RUBY
- subject.eval_gemfile("../fragment.rb")
- expect(subject.instance_variable_get(:@fragment_dir)).to eq(source_root.dirname.to_s)
- expect(subject.instance_variable_get(:@fragment_file)).to eq(abs_path)
- end
end
describe "#gem" do
@@ -204,18 +142,18 @@ RSpec.describe Bundler::Dsl do
:ruby_30, :ruby_31, :ruby_32, :ruby_33, :mri, :mri_18, :mri_19, :mri_20, :mri_21, :mri_22, :mri_23, :mri_24,
:mri_25, :mri_26, :mri_27, :mri_30, :mri_31, :mri_32, :mri_33, :jruby, :rbx, :truffleruby].each do |platform|
it "allows #{platform} as a valid platform" do
- subject.gem("foo", platform: platform)
+ subject.gem("foo", :platform => platform)
end
end
# rubocop:enable Naming/VariableNumber
it "allows platforms matching the running Ruby version" do
platform = "ruby_#{RbConfig::CONFIG["MAJOR"]}#{RbConfig::CONFIG["MINOR"]}"
- subject.gem("foo", platform: platform)
+ subject.gem("foo", :platform => platform)
end
it "rejects invalid platforms" do
- expect { subject.gem("foo", platform: :bogus) }.
+ expect { subject.gem("foo", :platform => :bogus) }.
to raise_error(Bundler::GemfileError, /is not a valid platform/)
end
@@ -265,19 +203,19 @@ RSpec.describe Bundler::Dsl do
end
it "rejects branch option on non-git gems" do
- expect { subject.gem("foo", branch: "test") }.
+ expect { subject.gem("foo", :branch => "test") }.
to raise_error(Bundler::GemfileError, /The `branch` option for `gem 'foo'` is not allowed. Only gems with a git source can specify a branch/)
end
it "allows specifying a branch on git gems" do
- subject.gem("foo", branch: "test", git: "http://mytestrepo")
+ subject.gem("foo", :branch => "test", :git => "http://mytestrepo")
dep = subject.dependencies.last
expect(dep.name).to eq "foo"
end
it "allows specifying a branch on git gems with a git_source" do
subject.git_source(:test_source) {|n| "https://github.com/#{n}" }
- subject.gem("foo", branch: "test", test_source: "bundler/bundler")
+ subject.gem("foo", :branch => "test", :test_source => "bundler/bundler")
dep = subject.dependencies.last
expect(dep.name).to eq "foo"
end
@@ -342,7 +280,7 @@ RSpec.describe Bundler::Dsl do
allow(Bundler).to receive(:default_gemfile).and_return(Pathname.new("./Gemfile"))
subject.source("https://other-source.org") do
- subject.gem("dobry-pies", path: "foo")
+ subject.gem("dobry-pies", :path => "foo")
subject.gem("foo")
end
@@ -354,7 +292,7 @@ RSpec.describe Bundler::Dsl do
describe "#check_primary_source_safety" do
context "when a global source is not defined implicitly" do
it "will raise a major deprecation warning" do
- not_a_global_source = double("not-a-global-source", no_remotes?: true)
+ not_a_global_source = double("not-a-global-source", :no_remotes? => true)
allow(Bundler::Source::Rubygems).to receive(:new).and_return(not_a_global_source)
warning = "This Gemfile does not include an explicit global source. " \
diff --git a/spec/bundler/bundler/endpoint_specification_spec.rb b/spec/bundler/bundler/endpoint_specification_spec.rb
index e7e10730cf..7dd6925007 100644
--- a/spec/bundler/bundler/endpoint_specification_spec.rb
+++ b/spec/bundler/bundler/endpoint_specification_spec.rb
@@ -60,21 +60,21 @@ RSpec.describe Bundler::EndpointSpecification do
it "should return the remote spec value when not set on endpoint specification and remote spec has one" do
remote_value = "remote_value"
- remote_spec = double(:remote_spec, required_ruby_version: remote_value, required_rubygems_version: nil)
+ remote_spec = double(:remote_spec, :required_ruby_version => remote_value, :required_rubygems_version => nil)
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)
expect(spec.required_ruby_version). eql?(remote_value)
end
it "should use the default Gem Requirement value when not set on endpoint specification and not set on remote spec" do
- remote_spec = double(:remote_spec, required_ruby_version: nil, required_rubygems_version: nil)
+ remote_spec = double(:remote_spec, :required_ruby_version => nil, :required_rubygems_version => nil)
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)
expect(spec.required_ruby_version). eql?(Gem::Requirement.default)
end
end
it "supports equality comparison" do
- remote_spec = double(:remote_spec, required_ruby_version: nil, required_rubygems_version: nil)
+ remote_spec = double(:remote_spec, :required_ruby_version => nil, :required_rubygems_version => nil)
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)
other_spec = described_class.new("bar", version, platform, spec_fetcher, dependencies, metadata)
expect(spec).to eql(spec)
diff --git a/spec/bundler/bundler/env_spec.rb b/spec/bundler/bundler/env_spec.rb
index 7997cb0c40..a00489d0e5 100644
--- a/spec/bundler/bundler/env_spec.rb
+++ b/spec/bundler/bundler/env_spec.rb
@@ -88,7 +88,7 @@ RSpec.describe Bundler::Env do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end
- let(:output) { described_class.report(print_gemfile: true) }
+ let(:output) { described_class.report(:print_gemfile => true) }
it "prints the Gemfile" do
expect(output).to include("Gemfile")
@@ -102,7 +102,7 @@ RSpec.describe Bundler::Env do
end
context "when there no Gemfile and print_gemfile is true" do
- let(:output) { described_class.report(print_gemfile: true) }
+ let(:output) { described_class.report(:print_gemfile => true) }
it "prints the environment" do
expect(output).to start_with("## Environment")
@@ -114,7 +114,7 @@ RSpec.describe Bundler::Env do
bundle "config set https://localgemserver.test/ user:pass"
end
- let(:output) { described_class.report(print_gemfile: true) }
+ let(:output) { described_class.report(:print_gemfile => true) }
it "prints the config with redacted values" do
expect(output).to include("https://localgemserver.test")
@@ -128,7 +128,7 @@ RSpec.describe Bundler::Env do
bundle "config set https://localgemserver.test/ api_token:x-oauth-basic"
end
- let(:output) { described_class.report(print_gemfile: true) }
+ let(:output) { described_class.report(:print_gemfile => true) }
it "prints the config with redacted values" do
expect(output).to include("https://localgemserver.test")
@@ -139,7 +139,7 @@ RSpec.describe Bundler::Env do
context "when Gemfile contains a gemspec and print_gemspecs is true" do
let(:gemspec) do
- <<~GEMSPEC
+ strip_whitespace(<<-GEMSPEC)
Gem::Specification.new do |gem|
gem.name = "foo"
gem.author = "Fumofu"
@@ -158,7 +158,7 @@ RSpec.describe Bundler::Env do
end
it "prints the gemspec" do
- output = described_class.report(print_gemspecs: true)
+ output = described_class.report(:print_gemspecs => true)
expect(output).to include("foo.gemspec")
expect(output).to include(gemspec)
@@ -177,8 +177,8 @@ RSpec.describe Bundler::Env do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app)
- output = described_class.report(print_gemspecs: true)
- expect(output).to include(<<~ENV)
+ output = described_class.report(:print_gemspecs => true)
+ expect(output).to include(strip_whitespace(<<-ENV))
## Gemfile
### Gemfile
diff --git a/spec/bundler/bundler/environment_preserver_spec.rb b/spec/bundler/bundler/environment_preserver_spec.rb
index 6c7066d0c6..530ca6f835 100644
--- a/spec/bundler/bundler/environment_preserver_spec.rb
+++ b/spec/bundler/bundler/environment_preserver_spec.rb
@@ -27,12 +27,8 @@ RSpec.describe Bundler::EnvironmentPreserver do
context "when a key is empty" do
let(:env) { { "foo" => "" } }
- it "should keep the original entry" do
- expect(subject["foo"]).to be_empty
- end
-
- it "should still create backup entries" do
- expect(subject).to have_key "BUNDLER_ORIG_foo"
+ it "should not create backup entries" do
+ expect(subject).not_to have_key "BUNDLER_ORIG_foo"
end
end
@@ -75,12 +71,8 @@ RSpec.describe Bundler::EnvironmentPreserver do
context "when the original key is empty" do
let(:env) { { "foo" => "my-foo", "BUNDLER_ORIG_foo" => "" } }
- it "should restore the original value" do
- expect(subject["foo"]).to be_empty
- end
-
- it "should delete the backup value" do
- expect(subject.key?("BUNDLER_ORIG_foo")).to eq(false)
+ it "should keep the current value" do
+ expect(subject["foo"]).to eq("my-foo")
end
end
end
diff --git a/spec/bundler/bundler/fetcher/base_spec.rb b/spec/bundler/bundler/fetcher/base_spec.rb
index b8c6b57b10..02506591f3 100644
--- a/spec/bundler/bundler/fetcher/base_spec.rb
+++ b/spec/bundler/bundler/fetcher/base_spec.rb
@@ -4,16 +4,15 @@ RSpec.describe Bundler::Fetcher::Base do
let(:downloader) { double(:downloader) }
let(:remote) { double(:remote) }
let(:display_uri) { "http://sample_uri.com" }
- let(:gem_remote_fetcher) { nil }
class TestClass < described_class; end
- subject { TestClass.new(downloader, remote, display_uri, gem_remote_fetcher) }
+ subject { TestClass.new(downloader, remote, display_uri) }
describe "#initialize" do
context "with the abstract Base class" do
it "should raise an error" do
- expect { described_class.new(downloader, remote, display_uri, gem_remote_fetcher) }.to raise_error(RuntimeError, "Abstract class")
+ expect { described_class.new(downloader, remote, display_uri) }.to raise_error(RuntimeError, "Abstract class")
end
end
@@ -37,7 +36,7 @@ RSpec.describe Bundler::Fetcher::Base do
end
describe "#fetch_uri" do
- let(:remote_uri_obj) { Gem::URI("http://rubygems.org") }
+ let(:remote_uri_obj) { Bundler::URI("http://rubygems.org") }
before { allow(subject).to receive(:remote_uri).and_return(remote_uri_obj) }
@@ -50,10 +49,10 @@ RSpec.describe Bundler::Fetcher::Base do
end
context "when the remote uri's host is not rubygems.org" do
- let(:remote_uri_obj) { Gem::URI("http://otherhost.org") }
+ let(:remote_uri_obj) { Bundler::URI("http://otherhost.org") }
it "should return the remote uri" do
- expect(subject.fetch_uri).to eq(Gem::URI("http://otherhost.org"))
+ expect(subject.fetch_uri).to eq(Bundler::URI("http://otherhost.org"))
end
end
diff --git a/spec/bundler/bundler/fetcher/compact_index_spec.rb b/spec/bundler/bundler/fetcher/compact_index_spec.rb
index a988171f34..00eb27edea 100644
--- a/spec/bundler/bundler/fetcher/compact_index_spec.rb
+++ b/spec/bundler/bundler/fetcher/compact_index_spec.rb
@@ -5,10 +5,9 @@ require "bundler/compact_index_client"
RSpec.describe Bundler::Fetcher::CompactIndex do
let(:downloader) { double(:downloader) }
- let(:display_uri) { Gem::URI("http://sampleuri.com") }
- let(:remote) { double(:remote, cache_slug: "lsjdf", uri: display_uri) }
- let(:gem_remote_fetcher) { nil }
- let(:compact_index) { described_class.new(downloader, remote, display_uri, gem_remote_fetcher) }
+ let(:display_uri) { Bundler::URI("http://sampleuri.com") }
+ let(:remote) { double(:remote, :cache_slug => "lsjdf", :uri => display_uri) }
+ let(:compact_index) { described_class.new(downloader, remote, display_uri) }
before do
allow(compact_index).to receive(:log_specs) {}
@@ -34,7 +33,7 @@ RSpec.describe Bundler::Fetcher::CompactIndex do
describe "#available?" do
before do
allow(compact_index).to receive(:compact_index_client).
- and_return(double(:compact_index_client, update_and_parse_checksums!: true))
+ and_return(double(:compact_index_client, :update_and_parse_checksums! => true))
end
it "returns true" do
diff --git a/spec/bundler/bundler/fetcher/dependency_spec.rb b/spec/bundler/bundler/fetcher/dependency_spec.rb
index c420b7c07f..20307f9c99 100644
--- a/spec/bundler/bundler/fetcher/dependency_spec.rb
+++ b/spec/bundler/bundler/fetcher/dependency_spec.rb
@@ -2,11 +2,10 @@
RSpec.describe Bundler::Fetcher::Dependency do
let(:downloader) { double(:downloader) }
- let(:remote) { double(:remote, uri: Gem::URI("http://localhost:5000")) }
+ let(:remote) { double(:remote, :uri => Bundler::URI("http://localhost:5000")) }
let(:display_uri) { "http://sample_uri.com" }
- let(:gem_remote_fetcher) { nil }
- subject { described_class.new(downloader, remote, display_uri, gem_remote_fetcher) }
+ subject { described_class.new(downloader, remote, display_uri) }
describe "#available?" do
let(:dependency_api_uri) { double(:dependency_api_uri) }
@@ -211,7 +210,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
let(:gem_names) { [%w[foo bar], %w[bundler rubocop]] }
let(:dep_api_uri) { double(:dep_api_uri) }
let(:unmarshalled_gems) { double(:unmarshalled_gems) }
- let(:fetch_response) { double(:fetch_response, body: double(:body)) }
+ let(:fetch_response) { double(:fetch_response, :body => double(:body)) }
let(:rubygems_limit) { 50 }
before { allow(subject).to receive(:dependency_api_uri).with(gem_names).and_return(dep_api_uri) }
@@ -228,20 +227,20 @@ RSpec.describe Bundler::Fetcher::Dependency do
let(:gem_list) do
[
{
- dependencies: {
+ :dependencies => {
"resque" => "req3,req4",
},
- name: "typhoeus",
- number: "1.0.1",
- platform: "ruby",
+ :name => "typhoeus",
+ :number => "1.0.1",
+ :platform => "ruby",
},
{
- dependencies: {
+ :dependencies => {
"faraday" => "req1,req2",
},
- name: "grape",
- number: "2.0.2",
- platform: "jruby",
+ :name => "grape",
+ :number => "2.0.2",
+ :platform => "jruby",
},
]
end
@@ -255,7 +254,7 @@ RSpec.describe Bundler::Fetcher::Dependency do
end
describe "#dependency_api_uri" do
- let(:uri) { Gem::URI("http://gem-api.com") }
+ let(:uri) { Bundler::URI("http://gem-api.com") }
context "with gem names" do
let(:gem_names) { %w[foo bar bundler rubocop] }
diff --git a/spec/bundler/bundler/fetcher/downloader_spec.rb b/spec/bundler/bundler/fetcher/downloader_spec.rb
index d5c32f4730..22aa3a8b0c 100644
--- a/spec/bundler/bundler/fetcher/downloader_spec.rb
+++ b/spec/bundler/bundler/fetcher/downloader_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe Bundler::Fetcher::Downloader do
let(:connection) { double(:connection) }
let(:redirect_limit) { 5 }
- let(:uri) { Gem::URI("http://www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://www.uri-to-fetch.com/api/v2/endpoint") }
let(:options) { double(:options) }
subject { described_class.new(connection, redirect_limit) }
@@ -27,7 +27,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "logging" do
- let(:http_response) { Gem::Net::HTTPSuccess.new("1.1", 200, "Success") }
+ let(:http_response) { Net::HTTPSuccess.new("1.1", 200, "Success") }
it "should log the HTTP response code and message to debug" do
expect(Bundler).to receive_message_chain(:ui, :debug).with("HTTP 200 Success #{uri}")
@@ -35,48 +35,48 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
end
- context "when the request response is a Gem::Net::HTTPRedirection" do
- let(:http_response) { Gem::Net::HTTPRedirection.new(httpv, 308, "Moved") }
+ context "when the request response is a Net::HTTPRedirection" do
+ let(:http_response) { Net::HTTPRedirection.new(httpv, 308, "Moved") }
before { http_response["location"] = "http://www.redirect-uri.com/api/v2/endpoint" }
it "should try to fetch the redirect uri and iterate the # requests counter" do
- expect(subject).to receive(:fetch).with(Gem::URI("http://www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
- expect(subject).to receive(:fetch).with(Gem::URI("http://www.redirect-uri.com/api/v2/endpoint"), options, 1)
+ expect(subject).to receive(:fetch).with(Bundler::URI("http://www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
+ expect(subject).to receive(:fetch).with(Bundler::URI("http://www.redirect-uri.com/api/v2/endpoint"), options, 1)
subject.fetch(uri, options, counter)
end
context "when the redirect uri and original uri are the same" do
- let(:uri) { Gem::URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
before { http_response["location"] = "ssh://www.uri-to-fetch.com/api/v1/endpoint" }
it "should set the same user and password for the redirect uri" do
- expect(subject).to receive(:fetch).with(Gem::URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
- expect(subject).to receive(:fetch).with(Gem::URI("ssh://username:password@www.uri-to-fetch.com/api/v1/endpoint"), options, 1)
+ expect(subject).to receive(:fetch).with(Bundler::URI("ssh://username:password@www.uri-to-fetch.com/api/v2/endpoint"), options, 0).and_call_original
+ expect(subject).to receive(:fetch).with(Bundler::URI("ssh://username:password@www.uri-to-fetch.com/api/v1/endpoint"), options, 1)
subject.fetch(uri, options, counter)
end
end
end
- context "when the request response is a Gem::Net::HTTPSuccess" do
- let(:http_response) { Gem::Net::HTTPSuccess.new("1.1", 200, "Success") }
+ context "when the request response is a Net::HTTPSuccess" do
+ let(:http_response) { Net::HTTPSuccess.new("1.1", 200, "Success") }
it "should return the response body" do
expect(subject.fetch(uri, options, counter)).to eq(http_response)
end
end
- context "when the request response is a Gem::Net::HTTPRequestEntityTooLarge" do
- let(:http_response) { Gem::Net::HTTPRequestEntityTooLarge.new("1.1", 413, "Too Big") }
+ context "when the request response is a Net::HTTPRequestEntityTooLarge" do
+ let(:http_response) { Net::HTTPRequestEntityTooLarge.new("1.1", 413, "Too Big") }
it "should raise a Bundler::Fetcher::FallbackError with the response body" do
expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::FallbackError, "Body with info")
end
end
- context "when the request response is a Gem::Net::HTTPUnauthorized" do
- let(:http_response) { Gem::Net::HTTPUnauthorized.new("1.1", 401, "Unauthorized") }
+ context "when the request response is a Net::HTTPUnauthorized" do
+ let(:http_response) { Net::HTTPUnauthorized.new("1.1", 401, "Unauthorized") }
it "should raise a Bundler::Fetcher::AuthenticationRequiredError with the uri host" do
expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
@@ -89,7 +89,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "when the there are credentials provided in the request" do
- let(:uri) { Gem::URI("http://user:password@www.uri-to-fetch.com") }
+ let(:uri) { Bundler::URI("http://user:password@www.uri-to-fetch.com") }
it "should raise a Bundler::Fetcher::BadAuthenticationError that doesn't contain the password" do
expect { subject.fetch(uri, options, counter) }.
@@ -98,9 +98,9 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
end
- context "when the request response is a Gem::Net::HTTPForbidden" do
- let(:http_response) { Gem::Net::HTTPForbidden.new("1.1", 403, "Forbidden") }
- let(:uri) { Gem::URI("http://user:password@www.uri-to-fetch.com") }
+ context "when the request response is a Net::HTTPForbidden" do
+ let(:http_response) { Net::HTTPForbidden.new("1.1", 403, "Forbidden") }
+ let(:uri) { Bundler::URI("http://user:password@www.uri-to-fetch.com") }
it "should raise a Bundler::Fetcher::AuthenticationForbiddenError with the uri host" do
expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::AuthenticationForbiddenError,
@@ -108,29 +108,29 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
end
- context "when the request response is a Gem::Net::HTTPNotFound" do
- let(:http_response) { Gem::Net::HTTPNotFound.new("1.1", 404, "Not Found") }
+ context "when the request response is a Net::HTTPNotFound" do
+ let(:http_response) { Net::HTTPNotFound.new("1.1", 404, "Not Found") }
- it "should raise a Bundler::Fetcher::FallbackError with Gem::Net::HTTPNotFound" do
+ it "should raise a Bundler::Fetcher::FallbackError with Net::HTTPNotFound" do
expect { subject.fetch(uri, options, counter) }.
- to raise_error(Bundler::Fetcher::FallbackError, "Gem::Net::HTTPNotFound: http://www.uri-to-fetch.com/api/v2/endpoint")
+ to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound: http://www.uri-to-fetch.com/api/v2/endpoint")
end
context "when the there are credentials provided in the request" do
- let(:uri) { Gem::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
it "should raise a Bundler::Fetcher::FallbackError that doesn't contain the password" do
expect { subject.fetch(uri, options, counter) }.
- to raise_error(Bundler::Fetcher::FallbackError, "Gem::Net::HTTPNotFound: http://username@www.uri-to-fetch.com/api/v2/endpoint")
+ to raise_error(Bundler::Fetcher::FallbackError, "Net::HTTPNotFound: http://username@www.uri-to-fetch.com/api/v2/endpoint")
end
end
end
context "when the request response is some other type" do
- let(:http_response) { Gem::Net::HTTPBadGateway.new("1.1", 500, "Fatal Error") }
+ let(:http_response) { Net::HTTPBadGateway.new("1.1", 500, "Fatal Error") }
it "should raise a Bundler::HTTPError with the response class and body" do
- expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::HTTPError, "Gem::Net::HTTPBadGateway: Body with info")
+ expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::HTTPError, "Net::HTTPBadGateway: Body with info")
end
end
end
@@ -140,7 +140,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
let(:response) { double(:response) }
before do
- allow(Gem::Net::HTTP::Get).to receive(:new).with("/api/v2/endpoint", options).and_return(net_http_get)
+ allow(Net::HTTP::Get).to receive(:new).with("/api/v2/endpoint", options).and_return(net_http_get)
allow(connection).to receive(:request).with(uri, net_http_get).and_return(response)
end
@@ -152,7 +152,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
context "when there is a user provided in the request" do
context "and there is also a password provided" do
context "that contains cgi escaped characters" do
- let(:uri) { Gem::URI("http://username:password%24@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password%24@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with the username and password" do
expect(net_http_get).to receive(:basic_auth).with("username", "password$")
@@ -161,7 +161,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "that is all unescaped characters" do
- let(:uri) { Gem::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with the username and proper cgi compliant password" do
expect(net_http_get).to receive(:basic_auth).with("username", "password")
subject.request(uri, options)
@@ -170,7 +170,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "and there is no password provided" do
- let(:uri) { Gem::URI("http://username@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with just the user" do
expect(net_http_get).to receive(:basic_auth).with("username", nil)
@@ -179,7 +179,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "that contains cgi escaped characters" do
- let(:uri) { Gem::URI("http://username%24@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username%24@www.uri-to-fetch.com/api/v2/endpoint") }
it "should request basic authentication with the proper cgi compliant password user" do
expect(net_http_get).to receive(:basic_auth).with("username$", nil)
@@ -230,7 +230,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
context "when the there are credentials provided in the request" do
- let(:uri) { Gem::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
+ let(:uri) { Bundler::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
before do
allow(net_http_get).to receive(:basic_auth).with("username", "password")
end
diff --git a/spec/bundler/bundler/fetcher/index_spec.rb b/spec/bundler/bundler/fetcher/index_spec.rb
index dff9ccc3cc..971b64ce8f 100644
--- a/spec/bundler/bundler/fetcher/index_spec.rb
+++ b/spec/bundler/bundler/fetcher/index_spec.rb
@@ -8,9 +8,8 @@ RSpec.describe Bundler::Fetcher::Index do
let(:display_uri) { "http://sample_uri.com" }
let(:rubygems) { double(:rubygems) }
let(:gem_names) { %w[foo bar] }
- let(:gem_remote_fetcher) { nil }
- subject { described_class.new(downloader, remote, display_uri, gem_remote_fetcher) }
+ subject { described_class.new(downloader, remote, display_uri) }
before { allow(Bundler).to receive(:rubygems).and_return(rubygems) }
@@ -20,7 +19,7 @@ RSpec.describe Bundler::Fetcher::Index do
end
context "error handling" do
- let(:remote_uri) { Gem::URI("http://remote-uri.org") }
+ let(:remote_uri) { Bundler::URI("http://remote-uri.org") }
before do
allow(rubygems).to receive(:fetch_all_remote_specs) { raise Gem::RemoteFetcher::FetchError.new(error_message, display_uri) }
allow(subject).to receive(:remote_uri).and_return(remote_uri)
@@ -73,7 +72,7 @@ RSpec.describe Bundler::Fetcher::Index do
context "any other message is returned" do
let(:error_message) { "You get an error, you get an error!" }
- before { allow(Bundler).to receive(:ui).and_return(double(trace: nil)) }
+ before { allow(Bundler).to receive(:ui).and_return(double(:trace => nil)) }
it "should raise a Bundler::HTTPError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::HTTPError, "Could not fetch specs from http://sample_uri.com due to underlying error <You get an error, you get an error! (http://sample_uri.com)>")
diff --git a/spec/bundler/bundler/fetcher_spec.rb b/spec/bundler/bundler/fetcher_spec.rb
index e20f7e7c48..27a63c476d 100644
--- a/spec/bundler/bundler/fetcher_spec.rb
+++ b/spec/bundler/bundler/fetcher_spec.rb
@@ -3,8 +3,8 @@
require "bundler/fetcher"
RSpec.describe Bundler::Fetcher do
- let(:uri) { Gem::URI("https://example.com") }
- let(:remote) { double("remote", uri: uri, original_uri: nil) }
+ let(:uri) { Bundler::URI("https://example.com") }
+ let(:remote) { double("remote", :uri => uri, :original_uri => nil) }
subject(:fetcher) { Bundler::Fetcher.new(remote) }
@@ -45,9 +45,9 @@ RSpec.describe Bundler::Fetcher do
end
context "when a rubygems source mirror is set" do
- let(:orig_uri) { Gem::URI("http://zombo.com") }
+ let(:orig_uri) { Bundler::URI("http://zombo.com") }
let(:remote_with_mirror) do
- double("remote", uri: uri, original_uri: orig_uri, anonymized_uri: uri)
+ double("remote", :uri => uri, :original_uri => orig_uri, :anonymized_uri => uri)
end
let(:fetcher) { Bundler::Fetcher.new(remote_with_mirror) }
@@ -61,7 +61,7 @@ RSpec.describe Bundler::Fetcher do
context "when there is no rubygems source mirror set" do
let(:remote_no_mirror) do
- double("remote", uri: uri, original_uri: nil, anonymized_uri: uri)
+ double("remote", :uri => uri, :original_uri => nil, :anonymized_uri => uri)
end
let(:fetcher) { Bundler::Fetcher.new(remote_no_mirror) }
@@ -114,9 +114,9 @@ RSpec.describe Bundler::Fetcher do
context "when gem ssl configuration is set" do
before do
allow(Gem.configuration).to receive_messages(
- http_proxy: nil,
- ssl_client_cert: "cert",
- ssl_ca_cert: "ca"
+ :http_proxy => nil,
+ :ssl_client_cert => "cert",
+ :ssl_ca_cert => "ca"
)
expect(File).to receive(:read).and_return("")
expect(OpenSSL::X509::Certificate).to receive(:new).and_return("cert")
@@ -143,20 +143,18 @@ RSpec.describe Bundler::Fetcher do
describe "include CI information" do
it "from one CI" do
- with_env_vars("CI" => nil, "JENKINS_URL" => "foo") do
+ with_env_vars("JENKINS_URL" => "foo") do
ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") }
- cis = ci_part.split("/").last.split(",")
- expect(cis).to include("jenkins")
- expect(cis).not_to include("ci")
+ expect(ci_part).to match("jenkins")
end
end
it "from many CI" do
- with_env_vars("CI" => "true", "SEMAPHORE" => nil, "TRAVIS" => "foo", "GITLAB_CI" => "gitlab", "CI_NAME" => "MY_ci") do
+ with_env_vars("TRAVIS" => "foo", "GITLAB_CI" => "gitlab", "CI_NAME" => "my_ci") do
ci_part = fetcher.user_agent.split(" ").find {|x| x.start_with?("ci/") }
- cis = ci_part.split("/").last.split(",")
- expect(cis).to include("ci", "gitlab", "my_ci", "travis")
- expect(cis).not_to include("semaphore")
+ expect(ci_part).to match("travis")
+ expect(ci_part).to match("gitlab")
+ expect(ci_part).to match("my_ci")
end
end
end
@@ -167,7 +165,7 @@ RSpec.describe Bundler::Fetcher do
let(:version) { "1.3.17" }
let(:platform) { "platform" }
let(:downloader) { double("downloader") }
- let(:body) { double(Gem::Net::HTTP::Get, body: downloaded_data) }
+ let(:body) { double(Net::HTTP::Get, :body => downloaded_data) }
context "when attempting to load a Gem::Specification" do
let(:spec) { Gem::Specification.new(name, version) }
@@ -191,70 +189,4 @@ RSpec.describe Bundler::Fetcher do
end
end
end
-
- describe "#specs_with_retry" do
- let(:downloader) { double(:downloader) }
- let(:remote) { double(:remote, cache_slug: "slug", uri: uri, original_uri: nil, anonymized_uri: uri) }
- let(:compact_index) { double(Bundler::Fetcher::CompactIndex, available?: true, api_fetcher?: true) }
- let(:dependency) { double(Bundler::Fetcher::Dependency, available?: true, api_fetcher?: true) }
- let(:index) { double(Bundler::Fetcher::Index, available?: true, api_fetcher?: false) }
-
- before do
- allow(Bundler::Fetcher::CompactIndex).to receive(:new).and_return(compact_index)
- allow(Bundler::Fetcher::Dependency).to receive(:new).and_return(dependency)
- allow(Bundler::Fetcher::Index).to receive(:new).and_return(index)
- end
-
- it "picks the first fetcher that works" do
- expect(compact_index).to receive(:specs).with("name").and_return([["name", "1.2.3", "ruby"]])
- expect(dependency).not_to receive(:specs)
- expect(index).not_to receive(:specs)
- fetcher.specs_with_retry("name", double(Bundler::Source::Rubygems))
- end
-
- context "when APIs are not available" do
- before do
- allow(compact_index).to receive(:available?).and_return(false)
- allow(dependency).to receive(:available?).and_return(false)
- end
-
- it "uses the index" do
- expect(compact_index).not_to receive(:specs)
- expect(dependency).not_to receive(:specs)
- expect(index).to receive(:specs).with("name").and_return([["name", "1.2.3", "ruby"]])
-
- fetcher.specs_with_retry("name", double(Bundler::Source::Rubygems))
- end
- end
- end
-
- describe "#api_fetcher?" do
- let(:downloader) { double(:downloader) }
- let(:remote) { double(:remote, cache_slug: "slug", uri: uri, original_uri: nil, anonymized_uri: uri) }
- let(:compact_index) { double(Bundler::Fetcher::CompactIndex, available?: false, api_fetcher?: true) }
- let(:dependency) { double(Bundler::Fetcher::Dependency, available?: false, api_fetcher?: true) }
- let(:index) { double(Bundler::Fetcher::Index, available?: true, api_fetcher?: false) }
-
- before do
- allow(Bundler::Fetcher::CompactIndex).to receive(:new).and_return(compact_index)
- allow(Bundler::Fetcher::Dependency).to receive(:new).and_return(dependency)
- allow(Bundler::Fetcher::Index).to receive(:new).and_return(index)
- end
-
- context "when an api fetcher is available" do
- before do
- allow(compact_index).to receive(:available?).and_return(true)
- end
-
- it "is truthy" do
- expect(fetcher).to be_api_fetcher
- end
- end
-
- context "when only the index fetcher is available" do
- it "is falsey" do
- expect(fetcher).not_to be_api_fetcher
- end
- end
- end
end
diff --git a/spec/bundler/bundler/friendly_errors_spec.rb b/spec/bundler/bundler/friendly_errors_spec.rb
index cda2ef31de..37afe488f3 100644
--- a/spec/bundler/bundler/friendly_errors_spec.rb
+++ b/spec/bundler/bundler/friendly_errors_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe Bundler, "friendly errors" do
gem "rack"
G
- bundle :install, env: { "DEBUG" => "true" }
+ bundle :install, :env => { "DEBUG" => "true" }
expect(err).to include("Failed to load #{home(".gemrc")}")
end
@@ -101,7 +101,7 @@ RSpec.describe Bundler, "friendly errors" do
context "BundlerError" do
it "Bundler.ui receive error" do
error = Bundler::BundlerError.new
- expect(Bundler.ui).to receive(:error).with(error.message, wrap: true)
+ expect(Bundler.ui).to receive(:error).with(error.message, :wrap => true)
Bundler::FriendlyErrors.log_error(error)
end
end
@@ -121,7 +121,7 @@ RSpec.describe Bundler, "friendly errors" do
context "Gem::InvalidSpecificationException" do
it "Bundler.ui receive error" do
error = Gem::InvalidSpecificationException.new
- expect(Bundler.ui).to receive(:error).with(error.message, wrap: true)
+ expect(Bundler.ui).to receive(:error).with(error.message, :wrap => true)
Bundler::FriendlyErrors.log_error(error)
end
end
diff --git a/spec/bundler/bundler/gem_helper_spec.rb b/spec/bundler/bundler/gem_helper_spec.rb
index 940e5df9de..7d955007ab 100644
--- a/spec/bundler/bundler/gem_helper_spec.rb
+++ b/spec/bundler/bundler/gem_helper_spec.rb
@@ -253,11 +253,11 @@ RSpec.describe Bundler::GemHelper do
end
before do
- sys_exec("git init", dir: app_path)
- sys_exec("git config user.email \"you@example.com\"", dir: app_path)
- sys_exec("git config user.name \"name\"", dir: app_path)
- sys_exec("git config commit.gpgsign false", dir: app_path)
- sys_exec("git config push.default simple", dir: app_path)
+ sys_exec("git init", :dir => app_path)
+ sys_exec("git config user.email \"you@example.com\"", :dir => app_path)
+ sys_exec("git config user.name \"name\"", :dir => app_path)
+ sys_exec("git config commit.gpgsign false", :dir => app_path)
+ sys_exec("git config push.default simple", :dir => app_path)
# silence messages
allow(Bundler.ui).to receive(:confirm)
@@ -271,23 +271,23 @@ RSpec.describe Bundler::GemHelper do
end
it "when there are uncommitted files" do
- sys_exec("git add .", dir: app_path)
+ sys_exec("git add .", :dir => app_path)
expect { Rake.application["release"].invoke }.
to raise_error("There are files that need to be committed first.")
end
it "when there is no git remote" do
- sys_exec("git commit -a -m \"initial commit\"", dir: app_path)
+ sys_exec("git commit -a -m \"initial commit\"", :dir => app_path)
expect { Rake.application["release"].invoke }.to raise_error(RuntimeError)
end
end
context "succeeds" do
- let(:repo) { build_git("foo", bare: true) }
+ let(:repo) { build_git("foo", :bare => true) }
before do
- sys_exec("git remote add origin #{file_uri_for(repo.path)}", dir: app_path)
- sys_exec('git commit -a -m "initial commit"', dir: app_path)
+ sys_exec("git remote add origin #{file_uri_for(repo.path)}", :dir => app_path)
+ sys_exec('git commit -a -m "initial commit"', :dir => app_path)
end
context "on releasing" do
@@ -296,7 +296,7 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message "Tagged v#{app_version}."
mock_confirm_message "Pushed git commits and release tag."
- sys_exec("git push -u origin main", dir: app_path)
+ sys_exec("git push -u origin main", :dir => app_path)
end
it "calls rubygem_push with proper arguments" do
@@ -314,8 +314,8 @@ RSpec.describe Bundler::GemHelper do
it "also works when releasing from an ambiguous reference" do
# Create a branch with the same name as the tag
- sys_exec("git checkout -b v#{app_version}", dir: app_path)
- sys_exec("git push -u origin v#{app_version}", dir: app_path)
+ sys_exec("git checkout -b v#{app_version}", :dir => app_path)
+ sys_exec("git push -u origin v#{app_version}", :dir => app_path)
expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
@@ -323,7 +323,7 @@ RSpec.describe Bundler::GemHelper do
end
it "also works with releasing from a branch not yet pushed" do
- sys_exec("git checkout -b module_function", dir: app_path)
+ sys_exec("git checkout -b module_function", :dir => app_path)
expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
@@ -337,7 +337,7 @@ RSpec.describe Bundler::GemHelper do
mock_build_message app_name, app_version
mock_confirm_message "Pushed git commits and release tag."
- sys_exec("git push -u origin main", dir: app_path)
+ sys_exec("git push -u origin main", :dir => app_path)
expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
end
@@ -353,7 +353,7 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message "Tag v#{app_version} has already been created."
expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s)
- sys_exec("git tag -a -m \"Version #{app_version}\" v#{app_version}", dir: app_path)
+ sys_exec("git tag -a -m \"Version #{app_version}\" v#{app_version}", :dir => app_path)
Rake.application["release"].invoke
end
@@ -374,10 +374,10 @@ RSpec.describe Bundler::GemHelper do
end
before do
- sys_exec("git init", dir: app_path)
- sys_exec("git config user.email \"you@example.com\"", dir: app_path)
- sys_exec("git config user.name \"name\"", dir: app_path)
- sys_exec("git config push.gpgsign simple", dir: app_path)
+ sys_exec("git init", :dir => app_path)
+ sys_exec("git config user.email \"you@example.com\"", :dir => app_path)
+ sys_exec("git config user.name \"name\"", :dir => app_path)
+ sys_exec("git config push.gpgsign simple", :dir => app_path)
# silence messages
allow(Bundler.ui).to receive(:confirm)
diff --git a/spec/bundler/bundler/gem_version_promoter_spec.rb b/spec/bundler/bundler/gem_version_promoter_spec.rb
index 917daba95d..8058412f32 100644
--- a/spec/bundler/bundler/gem_version_promoter_spec.rb
+++ b/spec/bundler/bundler/gem_version_promoter_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Bundler::GemVersionPromoter do
end
def build_package(name, version, locked = [])
- Bundler::Resolver::Package.new(name, [], locked_specs: Bundler::SpecSet.new(build_spec(name, version)), unlock: locked)
+ Bundler::Resolver::Package.new(name, [], :locked_specs => Bundler::SpecSet.new(build_spec(name, version)), :unlock => locked)
end
def sorted_versions(candidates:, current:, name: "foo", locked: [])
@@ -32,14 +32,14 @@ RSpec.describe Bundler::GemVersionPromoter do
end
it "numerically sorts versions" do
- versions = sorted_versions(candidates: %w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0], current: "1.7.8")
- expect(versions).to eq %w[1.8.0 1.7.15 1.7.9 1.7.8 1.7.7]
+ versions = sorted_versions(:candidates => %w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0], :current => "1.7.8")
+ expect(versions).to eq %w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0]
end
context "with no options" do
it "defaults to level=:major, strict=false, pre=false" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[2.1.0 2.0.1 1.0.0 0.9.0 0.3.1 0.3.0 0.2.0]
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0]
end
end
@@ -50,26 +50,26 @@ RSpec.describe Bundler::GemVersionPromoter do
before { gvp.level = :major }
it "keeps downgrades" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[2.1.0 2.0.1 1.0.0 0.9.0 0.3.1 0.3.0 0.2.0]
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0]
end
end
context "when level is minor" do
before { gvp.level = :minor }
- it "sorts highest minor within same major in first position" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[0.9.0 0.3.1 0.3.0 1.0.0 2.1.0 2.0.1 0.2.0]
+ it "removes downgrades and major upgrades" do
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.3.0 0.3.1 0.9.0]
end
end
context "when level is patch" do
before { gvp.level = :patch }
- it "sorts highest patch within same minor in first position" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[0.3.1 0.3.0 0.9.0 1.0.0 2.0.1 2.1.0 0.2.0]
+ it "removes downgrades and major and minor upgrades" do
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.3.0 0.3.1]
end
end
end
@@ -81,26 +81,26 @@ RSpec.describe Bundler::GemVersionPromoter do
before { gvp.level = :major }
it "orders by version" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[2.1.0 2.0.1 1.0.0 0.9.0 0.3.1 0.3.0 0.2.0]
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0]
end
end
context "when level is minor" do
before { gvp.level = :minor }
- it "favors minor upgrades, then patch upgrades, then major upgrades, then downgrades" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[0.9.0 0.3.1 0.3.0 1.0.0 2.1.0 2.0.1 0.2.0]
+ it "favors downgrades, then upgrades by major descending, minor ascending, patch ascending" do
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.2.0 2.0.1 2.1.0 1.0.0 0.3.0 0.3.1 0.9.0]
end
end
context "when level is patch" do
before { gvp.level = :patch }
- it "favors patch upgrades, then minor upgrades, then major upgrades, then downgrades" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], current: "0.3.0")
- expect(versions).to eq %w[0.3.1 0.3.0 0.9.0 1.0.0 2.0.1 2.1.0 0.2.0]
+ it "favors downgrades, then upgrades by major descending, minor descending, patch ascending" do
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
+ expect(versions).to eq %w[0.2.0 2.1.0 2.0.1 1.0.0 0.9.0 0.3.0 0.3.1]
end
end
end
@@ -109,8 +109,8 @@ RSpec.describe Bundler::GemVersionPromoter do
before { gvp.pre = true }
it "sorts regardless of prerelease status" do
- versions = sorted_versions(candidates: %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0], current: "1.8.0")
- expect(versions).to eq %w[2.0.0 2.0.0.pre 1.8.1 1.8.1.pre 1.8.0 1.7.7.pre]
+ versions = sorted_versions(:candidates => %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0], :current => "1.8.0")
+ expect(versions).to eq %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0]
end
end
@@ -118,17 +118,17 @@ RSpec.describe Bundler::GemVersionPromoter do
before { gvp.pre = false }
it "deprioritizes prerelease gems" do
- versions = sorted_versions(candidates: %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0], current: "1.8.0")
- expect(versions).to eq %w[2.0.0 1.8.1 1.8.0 2.0.0.pre 1.8.1.pre 1.7.7.pre]
+ versions = sorted_versions(:candidates => %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0], :current => "1.8.0")
+ expect(versions).to eq %w[1.7.7.pre 1.8.1.pre 2.0.0.pre 1.8.0 1.8.1 2.0.0]
end
end
context "when locking and not major" do
before { gvp.level = :minor }
- it "keeps the current version first" do
- versions = sorted_versions(candidates: %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.1.0 2.0.1], current: "0.3.0", locked: ["bar"])
- expect(versions.first).to eq("0.3.0")
+ it "keeps the current version last" do
+ versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.1.0 2.0.1], :current => "0.3.0", :locked => ["bar"])
+ expect(versions.last).to eq("0.3.0")
end
end
end
diff --git a/spec/bundler/bundler/installer/gem_installer_spec.rb b/spec/bundler/bundler/installer/gem_installer_spec.rb
index 4b6a07f344..e86bdf009a 100644
--- a/spec/bundler/bundler/installer/gem_installer_spec.rb
+++ b/spec/bundler/bundler/installer/gem_installer_spec.rb
@@ -3,10 +3,10 @@
require "bundler/installer/gem_installer"
RSpec.describe Bundler::GemInstaller do
- let(:definition) { instance_double("Definition", locked_gems: nil) }
- let(:installer) { instance_double("Installer", definition: definition) }
+ let(:definition) { instance_double("Definition", :locked_gems => nil) }
+ let(:installer) { instance_double("Installer", :definition => definition) }
let(:spec_source) { instance_double("SpecSource") }
- let(:spec) { instance_double("Specification", name: "dummy", version: "0.0.1", loaded_from: "dummy", source: spec_source) }
+ let(:spec) { instance_double("Specification", :name => "dummy", :version => "0.0.1", :loaded_from => "dummy", :source => spec_source) }
subject { described_class.new(spec, installer) }
@@ -14,7 +14,7 @@ RSpec.describe Bundler::GemInstaller do
it "invokes install method with empty build_args" do
allow(spec_source).to receive(:install).with(
spec,
- { force: false, ensure_builtin_gems_cached: false, build_args: [], previous_spec: nil }
+ { :force => false, :ensure_builtin_gems_cached => false, :build_args => [], :previous_spec => nil }
)
subject.install_from_spec
end
@@ -28,7 +28,7 @@ RSpec.describe Bundler::GemInstaller do
allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy")
expect(spec_source).to receive(:install).with(
spec,
- { force: false, ensure_builtin_gems_cached: false, build_args: ["--with-dummy-config=dummy"], previous_spec: nil }
+ { :force => false, :ensure_builtin_gems_cached => false, :build_args => ["--with-dummy-config=dummy"], :previous_spec => nil }
)
subject.install_from_spec
end
@@ -42,7 +42,7 @@ RSpec.describe Bundler::GemInstaller do
allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy --with-another-dummy-config")
expect(spec_source).to receive(:install).with(
spec,
- { force: false, ensure_builtin_gems_cached: false, build_args: ["--with-dummy-config=dummy", "--with-another-dummy-config"], previous_spec: nil }
+ { :force => false, :ensure_builtin_gems_cached => false, :build_args => ["--with-dummy-config=dummy", "--with-another-dummy-config"], :previous_spec => nil }
)
subject.install_from_spec
end
diff --git a/spec/bundler/bundler/installer/parallel_installer_spec.rb b/spec/bundler/bundler/installer/parallel_installer_spec.rb
new file mode 100644
index 0000000000..c8403a2e38
--- /dev/null
+++ b/spec/bundler/bundler/installer/parallel_installer_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require "bundler/installer/parallel_installer"
+
+RSpec.describe Bundler::ParallelInstaller do
+ let(:installer) { instance_double("Installer") }
+ let(:all_specs) { [] }
+ let(:size) { 1 }
+ let(:standalone) { false }
+ let(:force) { false }
+
+ subject { described_class.new(installer, all_specs, size, standalone, force) }
+
+ context "when the spec set is not a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.4.4"),
+ ].flatten
+ end
+
+ it "prints a warning" do
+ expect(Bundler.ui).to receive(:warn).with(<<-W.strip)
+Your lockfile doesn't include a valid resolution.
+You can fix this by regenerating your lockfile or manually editing the bad locked gems to a version that satisfies all dependencies.
+The unmet dependencies are:
+* diff-lcs (< 1.4), dependency of cucumber-4.1.0, unsatisfied by diff-lcs-1.4.4
+ W
+ subject.check_for_unmet_dependencies
+ end
+ end
+
+ context "when the spec set is a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.3"),
+ ].flatten
+ end
+
+ it "doesn't print a warning" do
+ expect(Bundler.ui).not_to receive(:warn)
+ subject.check_for_unmet_dependencies
+ end
+ end
+end
diff --git a/spec/bundler/bundler/installer/spec_installation_spec.rb b/spec/bundler/bundler/installer/spec_installation_spec.rb
index cbe2589b99..e63ef26cb3 100644
--- a/spec/bundler/bundler/installer/spec_installation_spec.rb
+++ b/spec/bundler/bundler/installer/spec_installation_spec.rb
@@ -42,26 +42,24 @@ RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
context "when all dependencies are installed" do
it "returns true" do
dependencies = []
- dependencies << instance_double("SpecInstallation", spec: "alpha", name: "alpha", installed?: true, all_dependencies: [], type: :production)
- dependencies << instance_double("SpecInstallation", spec: "beta", name: "beta", installed?: true, all_dependencies: [], type: :production)
- all_specs = dependencies + [instance_double("SpecInstallation", spec: "gamma", name: "gamma", installed?: false, all_dependencies: [], type: :production)]
+ dependencies << instance_double("SpecInstallation", :spec => "alpha", :name => "alpha", :installed? => true, :all_dependencies => [], :type => :production)
+ dependencies << instance_double("SpecInstallation", :spec => "beta", :name => "beta", :installed? => true, :all_dependencies => [], :type => :production)
+ all_specs = dependencies + [instance_double("SpecInstallation", :spec => "gamma", :name => "gamma", :installed? => false, :all_dependencies => [], :type => :production)]
spec = described_class.new(dep)
allow(spec).to receive(:all_dependencies).and_return(dependencies)
- installed_specs = all_specs.select(&:installed?).map {|s| [s.name, true] }.to_h
- expect(spec.dependencies_installed?(installed_specs)).to be_truthy
+ expect(spec.dependencies_installed?(all_specs)).to be_truthy
end
end
context "when all dependencies are not installed" do
it "returns false" do
dependencies = []
- dependencies << instance_double("SpecInstallation", spec: "alpha", name: "alpha", installed?: false, all_dependencies: [], type: :production)
- dependencies << instance_double("SpecInstallation", spec: "beta", name: "beta", installed?: true, all_dependencies: [], type: :production)
- all_specs = dependencies + [instance_double("SpecInstallation", spec: "gamma", name: "gamma", installed?: false, all_dependencies: [], type: :production)]
+ dependencies << instance_double("SpecInstallation", :spec => "alpha", :name => "alpha", :installed? => false, :all_dependencies => [], :type => :production)
+ dependencies << instance_double("SpecInstallation", :spec => "beta", :name => "beta", :installed? => true, :all_dependencies => [], :type => :production)
+ all_specs = dependencies + [instance_double("SpecInstallation", :spec => "gamma", :name => "gamma", :installed? => false, :all_dependencies => [], :type => :production)]
spec = described_class.new(dep)
allow(spec).to receive(:all_dependencies).and_return(dependencies)
- installed_specs = all_specs.select(&:installed?).map {|s| [s.name, true] }.to_h
- expect(spec.dependencies_installed?(installed_specs)).to be_falsey
+ expect(spec.dependencies_installed?(all_specs)).to be_falsey
end
end
end
diff --git a/spec/bundler/bundler/lockfile_parser_spec.rb b/spec/bundler/bundler/lockfile_parser_spec.rb
index 88932bf009..3a6d61336f 100644
--- a/spec/bundler/bundler/lockfile_parser_spec.rb
+++ b/spec/bundler/bundler/lockfile_parser_spec.rb
@@ -3,7 +3,7 @@
require "bundler/lockfile_parser"
RSpec.describe Bundler::LockfileParser do
- let(:lockfile_contents) { <<~L }
+ let(:lockfile_contents) { strip_whitespace(<<-L) }
GIT
remote: https://github.com/alloy/peiji-san.git
revision: eca485d8dc95f12aaec1a434b49d295c7e91844b
@@ -22,9 +22,6 @@ RSpec.describe Bundler::LockfileParser do
peiji-san!
rake
- CHECKSUMS
- rake (10.3.2) sha256=814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8
-
RUBY VERSION
ruby 2.1.3p242
@@ -36,13 +33,13 @@ RSpec.describe Bundler::LockfileParser do
it "returns the attributes" do
attributes = described_class.sections_in_lockfile(lockfile_contents)
expect(attributes).to contain_exactly(
- "BUNDLED WITH", "CHECKSUMS", "DEPENDENCIES", "GEM", "GIT", "PLATFORMS", "RUBY VERSION"
+ "BUNDLED WITH", "DEPENDENCIES", "GEM", "GIT", "PLATFORMS", "RUBY VERSION"
)
end
end
describe ".unknown_sections_in_lockfile" do
- let(:lockfile_contents) { <<~L }
+ let(:lockfile_contents) { strip_whitespace(<<-L) }
UNKNOWN ATTR
UNKNOWN ATTR 2
@@ -63,7 +60,7 @@ RSpec.describe Bundler::LockfileParser do
it "returns the same as > 1.0" do
expect(subject).to contain_exactly(
- described_class::BUNDLED, described_class::CHECKSUMS, described_class::RUBY, described_class::PLUGIN
+ described_class::BUNDLED, described_class::RUBY, described_class::PLUGIN
)
end
end
@@ -73,7 +70,7 @@ RSpec.describe Bundler::LockfileParser do
it "returns the same as for the release version" do
expect(subject).to contain_exactly(
- described_class::CHECKSUMS, described_class::RUBY, described_class::PLUGIN
+ described_class::RUBY, described_class::PLUGIN
)
end
end
@@ -118,14 +115,6 @@ RSpec.describe Bundler::LockfileParser do
let(:platforms) { [rb] }
let(:bundler_version) { Gem::Version.new("1.12.0.rc.2") }
let(:ruby_version) { "ruby 2.1.3p242" }
- let(:lockfile_path) { Bundler.default_lockfile.relative_path_from(Dir.pwd) }
- let(:rake_sha256_checksum) do
- Bundler::Checksum.from_lock(
- "sha256=814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8",
- "#{lockfile_path}:20:17"
- )
- end
- let(:rake_checksums) { [rake_sha256_checksum] }
shared_examples_for "parsing" do
it "parses correctly" do
@@ -136,9 +125,6 @@ RSpec.describe Bundler::LockfileParser do
expect(subject.platforms).to eq platforms
expect(subject.bundler_version).to eq bundler_version
expect(subject.ruby_version).to eq ruby_version
- rake_spec = specs.last
- checksums = subject.sources.last.checksum_store.to_lock(specs.last)
- expect(checksums).to eq("#{rake_spec.name_tuple.lock_name} #{rake_checksums.map(&:to_lock).sort.join(",")}")
end
end
@@ -163,59 +149,5 @@ RSpec.describe Bundler::LockfileParser do
let(:lockfile_contents) { super().sub("peiji-san!", "peiji-san!\n foo: bar") }
include_examples "parsing"
end
-
- context "when the checksum is urlsafe base64 encoded" do
- let(:lockfile_contents) do
- super().sub(
- "sha256=814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8",
- "sha256=gUgow08TFdfnt-gpUYRXfMTpabrWFWrAadAtY_WNgug="
- )
- end
- include_examples "parsing"
- end
-
- context "when the checksum is of an unknown algorithm" do
- let(:rake_sha512_checksum) do
- Bundler::Checksum.from_lock(
- "sha512=pVDn9GLmcFkz8vj1ueiVxj5uGKkAyaqYjEX8zG6L5O4BeVg3wANaKbQdpj/B82Nd/MHVszy6polHcyotUdwilQ==",
- "#{lockfile_path}:20:17"
- )
- end
- let(:lockfile_contents) do
- super().sub(
- "sha256=",
- "sha512=pVDn9GLmcFkz8vj1ueiVxj5uGKkAyaqYjEX8zG6L5O4BeVg3wANaKbQdpj/B82Nd/MHVszy6polHcyotUdwilQ==,sha256="
- )
- end
- let(:rake_checksums) { [rake_sha256_checksum, rake_sha512_checksum] }
- include_examples "parsing"
- end
-
- context "when CHECKSUMS has duplicate checksums in the lockfile that don't match" do
- let(:bad_checksum) { "sha256=c0ffee11c0ffee11c0ffee11c0ffee11c0ffee11c0ffee11c0ffee11c0ffee11" }
- let(:lockfile_contents) { super().split(/(?<=CHECKSUMS\n)/m).insert(1, " rake (10.3.2) #{bad_checksum}\n").join }
-
- it "raises a security error" do
- expect { subject }.to raise_error(Bundler::SecurityError) do |e|
- expect(e.message).to match <<~MESSAGE
- Bundler found mismatched checksums. This is a potential security risk.
- rake (10.3.2) #{bad_checksum}
- from the lockfile CHECKSUMS at #{lockfile_path}:20:17
- rake (10.3.2) #{rake_sha256_checksum.to_lock}
- from the lockfile CHECKSUMS at #{lockfile_path}:21:17
-
- To resolve this issue you can either:
- 1. remove the matching checksum in #{lockfile_path}:21:17
- 2. run `bundle install`
- or if you are sure that the new checksum from the lockfile CHECKSUMS at #{lockfile_path}:21:17 is correct:
- 1. remove the matching checksum in #{lockfile_path}:20:17
- 2. run `bundle install`
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- MESSAGE
- end
- end
- end
end
end
diff --git a/spec/bundler/bundler/mirror_spec.rb b/spec/bundler/bundler/mirror_spec.rb
index ba1c6ed413..1eaf1e9a8e 100644
--- a/spec/bundler/bundler/mirror_spec.rb
+++ b/spec/bundler/bundler/mirror_spec.rb
@@ -36,12 +36,12 @@ RSpec.describe Bundler::Settings::Mirror do
it "takes a string for the uri but returns an uri object" do
mirror.uri = "http://localhost:9292"
- expect(mirror.uri).to eq(Gem::URI("http://localhost:9292"))
+ expect(mirror.uri).to eq(Bundler::URI("http://localhost:9292"))
end
it "takes an uri object for the uri" do
- mirror.uri = Gem::URI("http://localhost:9293")
- expect(mirror.uri).to eq(Gem::URI("http://localhost:9293"))
+ mirror.uri = Bundler::URI("http://localhost:9293")
+ expect(mirror.uri).to eq(Bundler::URI("http://localhost:9293"))
end
context "without a uri" do
@@ -145,7 +145,7 @@ RSpec.describe Bundler::Settings::Mirror do
end
RSpec.describe Bundler::Settings::Mirrors do
- let(:localhost_uri) { Gem::URI("http://localhost:9292") }
+ let(:localhost_uri) { Bundler::URI("http://localhost:9292") }
context "with a just created mirror" do
let(:mirrors) do
@@ -260,7 +260,7 @@ RSpec.describe Bundler::Settings::Mirrors do
before { mirrors.parse("mirror.all.fallback_timeout", "true") }
it "returns the source uri, not localhost" do
- expect(mirrors.for("http://whatever.com").uri).to eq(Gem::URI("http://whatever.com/"))
+ expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/"))
end
end
end
@@ -270,7 +270,7 @@ RSpec.describe Bundler::Settings::Mirrors do
context "without a fallback timeout" do
it "returns the uri that is not mirrored" do
- expect(mirrors.for("http://whatever.com").uri).to eq(Gem::URI("http://whatever.com/"))
+ expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/"))
end
it "returns localhost for rubygems.org" do
@@ -282,11 +282,11 @@ RSpec.describe Bundler::Settings::Mirrors do
before { mirrors.parse("mirror.http://rubygems.org/.fallback_timeout", "true") }
it "returns the uri that is not mirrored" do
- expect(mirrors.for("http://whatever.com").uri).to eq(Gem::URI("http://whatever.com/"))
+ expect(mirrors.for("http://whatever.com").uri).to eq(Bundler::URI("http://whatever.com/"))
end
it "returns rubygems.org for rubygems.org" do
- expect(mirrors.for("http://rubygems.org/").uri).to eq(Gem::URI("http://rubygems.org/"))
+ expect(mirrors.for("http://rubygems.org/").uri).to eq(Bundler::URI("http://rubygems.org/"))
end
end
end
diff --git a/spec/bundler/bundler/plugin/api/source_spec.rb b/spec/bundler/bundler/plugin/api/source_spec.rb
index ae02e08bea..428ceb220a 100644
--- a/spec/bundler/bundler/plugin/api/source_spec.rb
+++ b/spec/bundler/bundler/plugin/api/source_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe Bundler::Plugin::API::Source do
context "to_lock" do
it "returns the string with remote and type" do
- expected = <<~L
+ expected = strip_whitespace <<-L
PLUGIN SOURCE
remote: #{uri}
type: #{type}
@@ -67,7 +67,7 @@ RSpec.describe Bundler::Plugin::API::Source do
end
it "includes them" do
- expected = <<~L
+ expected = strip_whitespace <<-L
PLUGIN SOURCE
remote: #{uri}
type: #{type}
diff --git a/spec/bundler/bundler/plugin/dsl_spec.rb b/spec/bundler/bundler/plugin/dsl_spec.rb
index 235a549735..00e39dca69 100644
--- a/spec/bundler/bundler/plugin/dsl_spec.rb
+++ b/spec/bundler/bundler/plugin/dsl_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe Bundler::Plugin::DSL do
it "adds #source with :type to list and also inferred_plugins list" do
expect(dsl).to receive(:plugin).with("bundler-source-news").once
- dsl.source("some_random_url", type: "news") {}
+ dsl.source("some_random_url", :type => "news") {}
expect(dsl.inferred_plugins).to eq(["bundler-source-news"])
end
@@ -31,8 +31,8 @@ RSpec.describe Bundler::Plugin::DSL do
it "registers a source type plugin only once for multiple declarations" do
expect(dsl).to receive(:plugin).with("bundler-source-news").and_call_original.once
- dsl.source("some_random_url", type: "news") {}
- dsl.source("another_random_url", type: "news") {}
+ dsl.source("some_random_url", :type => "news") {}
+ dsl.source("another_random_url", :type => "news") {}
end
end
end
diff --git a/spec/bundler/bundler/plugin/installer_spec.rb b/spec/bundler/bundler/plugin/installer_spec.rb
index ed40029f5a..2c50ee5afc 100644
--- a/spec/bundler/bundler/plugin/installer_spec.rb
+++ b/spec/bundler/bundler/plugin/installer_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Bundler::Plugin::Installer do
describe "cli install" do
it "uses Gem.sources when non of the source is provided" do
sources = double(:sources)
+ Bundler.settings # initialize it before we have to touch rubygems.ext_lock
allow(Gem).to receive(:sources) { sources }
allow(installer).to receive(:install_rubygems).
@@ -20,15 +21,15 @@ RSpec.describe Bundler::Plugin::Installer do
allow(installer).to receive(:install_git).
and_return("new-plugin" => spec)
- expect(installer.install(["new-plugin"], git: "https://some.ran/dom")).
+ expect(installer.install(["new-plugin"], :git => "https://some.ran/dom")).
to eq("new-plugin" => spec)
end
it "returns the installed spec after installing local git plugins" do
- allow(installer).to receive(:install_git).
+ allow(installer).to receive(:install_local_git).
and_return("new-plugin" => spec)
- expect(installer.install(["new-plugin"], git: "/phony/path/repo")).
+ expect(installer.install(["new-plugin"], :local_git => "/phony/path/repo")).
to eq("new-plugin" => spec)
end
@@ -36,7 +37,7 @@ RSpec.describe Bundler::Plugin::Installer do
allow(installer).to receive(:install_rubygems).
and_return("new-plugin" => spec)
- expect(installer.install(["new-plugin"], source: "https://some.ran/dom")).
+ expect(installer.install(["new-plugin"], :source => "https://some.ran/dom")).
to eq("new-plugin" => spec)
end
end
@@ -51,13 +52,13 @@ RSpec.describe Bundler::Plugin::Installer do
context "git plugins" do
before do
- build_git "ga-plugin", path: lib_path("ga-plugin") do |s|
+ build_git "ga-plugin", :path => lib_path("ga-plugin") do |s|
s.write "plugins.rb"
end
end
let(:result) do
- installer.install(["ga-plugin"], git: file_uri_for(lib_path("ga-plugin")))
+ installer.install(["ga-plugin"], :git => file_uri_for(lib_path("ga-plugin")))
end
it "returns the installed spec after installing" do
@@ -74,13 +75,13 @@ RSpec.describe Bundler::Plugin::Installer do
context "local git plugins" do
before do
- build_git "ga-plugin", path: lib_path("ga-plugin") do |s|
+ build_git "ga-plugin", :path => lib_path("ga-plugin") do |s|
s.write "plugins.rb"
end
end
let(:result) do
- installer.install(["ga-plugin"], git: lib_path("ga-plugin").to_s)
+ installer.install(["ga-plugin"], :local_git => lib_path("ga-plugin").to_s)
end
it "returns the installed spec after installing" do
@@ -97,7 +98,7 @@ RSpec.describe Bundler::Plugin::Installer do
context "rubygems plugins" do
let(:result) do
- installer.install(["re-plugin"], source: file_uri_for(gem_repo2))
+ installer.install(["re-plugin"], :source => file_uri_for(gem_repo2))
end
it "returns the installed spec after installing " do
@@ -112,7 +113,7 @@ RSpec.describe Bundler::Plugin::Installer do
context "multiple plugins" do
let(:result) do
- installer.install(["re-plugin", "ma-plugin"], source: file_uri_for(gem_repo2))
+ installer.install(["re-plugin", "ma-plugin"], :source => file_uri_for(gem_repo2))
end
it "returns the installed spec after installing " do
diff --git a/spec/bundler/bundler/plugin_spec.rb b/spec/bundler/bundler/plugin_spec.rb
index f41b4eff3a..d28479cf31 100644
--- a/spec/bundler/bundler/plugin_spec.rb
+++ b/spec/bundler/bundler/plugin_spec.rb
@@ -9,11 +9,11 @@ RSpec.describe Bundler::Plugin do
let(:spec2) { double(:spec2) }
before do
- build_lib "new-plugin", path: lib_path("new-plugin") do |s|
+ build_lib "new-plugin", :path => lib_path("new-plugin") do |s|
s.write "plugins.rb"
end
- build_lib "another-plugin", path: lib_path("another-plugin") do |s|
+ build_lib "another-plugin", :path => lib_path("another-plugin") do |s|
s.write "plugins.rb"
end
@@ -225,7 +225,7 @@ RSpec.describe Bundler::Plugin do
end
end
- describe "#from_lock" do
+ describe "#source_from_lock" do
it "returns instance of registered class initialized with locked opts" do
opts = { "type" => "l_source", "remote" => "xyz", "other" => "random" }
allow(index).to receive(:source_plugin).with("l_source") { "plugin_name" }
@@ -236,7 +236,7 @@ RSpec.describe Bundler::Plugin do
expect(SClass).to receive(:new).
with(hash_including("type" => "l_source", "uri" => "xyz", "other" => "random")) { s_instance }
- expect(subject.from_lock(opts)).to be(s_instance)
+ expect(subject.source_from_lock(opts)).to be(s_instance)
end
end
@@ -275,7 +275,7 @@ RSpec.describe Bundler::Plugin do
describe "#hook" do
before do
path = lib_path("foo-plugin")
- build_lib "foo-plugin", path: path do |s|
+ build_lib "foo-plugin", :path => path do |s|
s.write "plugins.rb", code
end
diff --git a/spec/bundler/bundler/remote_specification_spec.rb b/spec/bundler/bundler/remote_specification_spec.rb
index f35b231d58..921a47a2d3 100644
--- a/spec/bundler/bundler/remote_specification_spec.rb
+++ b/spec/bundler/bundler/remote_specification_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Bundler::RemoteSpecification do
end
describe "#fetch_platform" do
- let(:remote_spec) { double(:remote_spec, platform: "jruby") }
+ let(:remote_spec) { double(:remote_spec, :platform => "jruby") }
before { allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec) }
@@ -113,7 +113,7 @@ RSpec.describe Bundler::RemoteSpecification do
context "comparing a non sortable object" do
let(:other) { Object.new }
- let(:remote_spec) { double(:remote_spec, platform: "jruby") }
+ let(:remote_spec) { double(:remote_spec, :platform => "jruby") }
before do
allow(spec_fetcher).to receive(:fetch_spec).and_return(remote_spec)
@@ -127,8 +127,8 @@ RSpec.describe Bundler::RemoteSpecification do
end
describe "#__swap__" do
- let(:spec) { double(:spec, dependencies: []) }
- let(:new_spec) { double(:new_spec, dependencies: [], runtime_dependencies: []) }
+ let(:spec) { double(:spec, :dependencies => []) }
+ let(:new_spec) { double(:new_spec, :dependencies => [], :runtime_dependencies => []) }
before { subject.instance_variable_set(:@_remote_specification, spec) }
@@ -157,7 +157,7 @@ RSpec.describe Bundler::RemoteSpecification do
describe "method missing" do
context "and is present in Gem::Specification" do
- let(:remote_spec) { double(:remote_spec, authors: "abcd") }
+ let(:remote_spec) { double(:remote_spec, :authors => "abcd") }
before do
allow(subject).to receive(:_remote_specification).and_return(remote_spec)
@@ -172,7 +172,7 @@ RSpec.describe Bundler::RemoteSpecification do
describe "respond to missing?" do
context "and is present in Gem::Specification" do
- let(:remote_spec) { double(:remote_spec, authors: "abcd") }
+ let(:remote_spec) { double(:remote_spec, :authors => "abcd") }
before do
allow(subject).to receive(:_remote_specification).and_return(remote_spec)
diff --git a/spec/bundler/bundler/resolver/candidate_spec.rb b/spec/bundler/bundler/resolver/candidate_spec.rb
index f7b378d32b..cd52c867c4 100644
--- a/spec/bundler/bundler/resolver/candidate_spec.rb
+++ b/spec/bundler/bundler/resolver/candidate_spec.rb
@@ -2,7 +2,7 @@
RSpec.describe Bundler::Resolver::Candidate do
it "compares fine" do
- version1 = described_class.new("1.12.5", specs: [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }])
+ version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }])
version2 = described_class.new("1.12.5") # passing no specs creates a platform specific candidate, so sorts higher
expect(version2 >= version1).to be true
@@ -13,8 +13,8 @@ RSpec.describe Bundler::Resolver::Candidate do
expect(version1.platform_specific! >= version2.generic!).to be true
expect(version2.platform_specific! >= version1.generic!).to be true
- version1 = described_class.new("1.12.5", specs: [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }])
- version2 = described_class.new("1.12.5", specs: [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::X64_LINUX }])
+ version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }])
+ version2 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::X64_LINUX }])
expect(version2 >= version1).to be true
end
diff --git a/spec/bundler/bundler/ruby_dsl_spec.rb b/spec/bundler/bundler/ruby_dsl_spec.rb
index 384ac4b8b2..0ba55e949f 100644
--- a/spec/bundler/bundler/ruby_dsl_spec.rb
+++ b/spec/bundler/bundler/ruby_dsl_spec.rb
@@ -7,7 +7,6 @@ RSpec.describe Bundler::RubyDsl do
include Bundler::RubyDsl
attr_reader :ruby_version
- attr_accessor :gemfile
end
let(:dsl) { MockDSL.new }
@@ -18,18 +17,15 @@ RSpec.describe Bundler::RubyDsl do
let(:engine_version) { "9000" }
let(:patchlevel) { "100" }
let(:options) do
- { patchlevel: patchlevel,
- engine: engine,
- engine_version: engine_version }
+ { :patchlevel => patchlevel,
+ :engine => engine,
+ :engine_version => engine_version }
end
- let(:project_root) { Pathname.new("/path/to/project") }
- let(:gemfile) { project_root.join("Gemfile") }
- before { allow(Bundler).to receive(:root).and_return(project_root) }
let(:invoke) do
proc do
args = []
- args << ruby_version_arg if ruby_version_arg
+ args << Array(ruby_version_arg) if ruby_version_arg
args << options
dsl.ruby(*args)
@@ -37,7 +33,6 @@ RSpec.describe Bundler::RubyDsl do
end
subject do
- dsl.gemfile = gemfile
invoke.call
dsl.ruby_version
end
@@ -68,15 +63,6 @@ RSpec.describe Bundler::RubyDsl do
it_behaves_like "it stores the ruby version"
end
- context "with a preview version" do
- let(:ruby_version) { "3.3.0-preview2" }
-
- it "stores the version" do
- expect(subject.versions).to eq(Array("3.3.0.preview2"))
- expect(subject.gem_version.version).to eq("3.3.0.preview2")
- end
- end
-
context "with two requirements in the same string" do
let(:ruby_version) { ">= 2.0.0, < 3.0" }
it "raises an error" do
@@ -111,90 +97,22 @@ RSpec.describe Bundler::RubyDsl do
end
context "with a file option" do
- let(:file) { ".ruby-version" }
- let(:ruby_version_file_path) { gemfile.dirname.join(file) }
- let(:options) do
- { file: file,
- patchlevel: patchlevel,
- engine: engine,
- engine_version: engine_version }
- end
+ let(:options) { { :file => "foo" } }
+ let(:version) { "3.2.2" }
+ let(:ruby_version) { "3.2.2" }
let(:ruby_version_arg) { nil }
- let(:file_content) { "#{version}\n" }
-
- before do
- allow(Bundler).to receive(:read_file) do |path|
- raise Errno::ENOENT, <<~ERROR unless path == ruby_version_file_path
- #{file} not found in specs:
- expected: #{ruby_version_file_path}
- received: #{path}
- ERROR
- file_content
- end
- end
+ let(:engine_version) { version }
+ let(:patchlevel) { nil }
+ let(:engine) { "ruby" }
+ before { allow(Bundler).to receive(:read_file).with("foo").and_return("#{version}\n") }
it_behaves_like "it stores the ruby version"
- context "with the Gemfile ruby file: path is relative to the Gemfile in a subdir" do
- let(:gemfile) { project_root.join("subdir", "Gemfile") }
- let(:file) { "../.ruby-version" }
- let(:ruby_version_file_path) { gemfile.dirname.join(file) }
-
- it_behaves_like "it stores the ruby version"
- end
-
- context "with bundler root in a subdir of the project" do
- let(:project_root) { Pathname.new("/path/to/project/subdir") }
- let(:gemfile) { project_root.parent.join("Gemfile") }
-
- it_behaves_like "it stores the ruby version"
- end
-
- context "with the ruby- prefix in the file" do
- let(:file_content) { "ruby-#{version}\n" }
-
- it_behaves_like "it stores the ruby version"
- end
-
context "and a version" do
- let(:ruby_version_arg) { version }
-
- it "raises an error" do
- expect { subject }.to raise_error(Bundler::GemfileError, "Do not pass version argument when using :file option")
- end
- end
-
- context "with a @gemset" do
- let(:file_content) { "ruby-#{version}@gemset\n" }
+ let(:ruby_version_arg) { "2.0.0" }
it "raises an error" do
- expect { subject }.to raise_error(Gem::Requirement::BadRequirementError, "Illformed requirement [\"#{version}@gemset\"]")
- end
- end
-
- context "with a .tool-versions file format" do
- let(:file) { ".tool-versions" }
- let(:ruby_version_arg) { nil }
- let(:file_content) do
- <<~TOOLS
- nodejs 18.16.0
- ruby #{version} # This is a comment
- pnpm 8.6.12
- TOOLS
- end
-
- it_behaves_like "it stores the ruby version"
-
- context "with extra spaces and a very cozy comment" do
- let(:file_content) do
- <<~TOOLS
- nodejs 18.16.0
- ruby #{version}# This is a cozy comment
- pnpm 8.6.12
- TOOLS
- end
-
- it_behaves_like "it stores the ruby version"
+ expect { subject }.to raise_error(Bundler::GemfileError, "Cannot specify version when using the file option")
end
end
end
diff --git a/spec/bundler/bundler/rubygems_integration_spec.rb b/spec/bundler/bundler/rubygems_integration_spec.rb
index b6bda9f43e..182aa3646a 100644
--- a/spec/bundler/bundler/rubygems_integration_spec.rb
+++ b/spec/bundler/bundler/rubygems_integration_spec.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
RSpec.describe Bundler::RubygemsIntegration do
+ it "uses the same chdir lock as rubygems" do
+ expect(Bundler.rubygems.ext_lock).to eq(Gem::Ext::Builder::CHDIR_MONITOR)
+ end
+
context "#validate" do
let(:spec) do
Gem::Specification.new do |s|
@@ -32,7 +36,7 @@ RSpec.describe Bundler::RubygemsIntegration do
describe "#download_gem" do
let(:bundler_retry) { double(Bundler::Retry) }
- let(:uri) { Gem::URI.parse("https://foo.bar") }
+ let(:uri) { Bundler::URI.parse("https://foo.bar") }
let(:cache_dir) { "#{Gem.path.first}/cache" }
let(:spec) do
spec = Gem::Specification.new("Foo", Gem::Version.new("2.5.2"))
@@ -42,12 +46,14 @@ RSpec.describe Bundler::RubygemsIntegration do
let(:fetcher) { double("gem_remote_fetcher") }
it "successfully downloads gem with retries" do
+ expect(Bundler.rubygems).to receive(:gem_remote_fetcher).and_return(fetcher)
+ expect(fetcher).to receive(:headers=).with({ "X-Gemfile-Source" => "https://foo.bar" })
expect(Bundler::Retry).to receive(:new).with("download gem from #{uri}/").
and_return(bundler_retry)
expect(bundler_retry).to receive(:attempts).and_yield
expect(fetcher).to receive(:cache_update_path)
- Bundler.rubygems.download_gem(spec, uri, cache_dir, fetcher)
+ Bundler.rubygems.download_gem(spec, uri, cache_dir)
end
end
@@ -58,35 +64,40 @@ RSpec.describe Bundler::RubygemsIntegration do
let(:prerelease_specs_response) { Marshal.dump(["prerelease_specs"]) }
context "when a rubygems source mirror is set" do
- let(:orig_uri) { Gem::URI("http://zombo.com") }
- let(:remote_with_mirror) { double("remote", uri: uri, original_uri: orig_uri) }
+ let(:orig_uri) { Bundler::URI("http://zombo.com") }
+ let(:remote_with_mirror) { double("remote", :uri => uri, :original_uri => orig_uri) }
it "sets the 'X-Gemfile-Source' header containing the original source" do
+ expect(Bundler.rubygems).to receive(:gem_remote_fetcher).twice.and_return(fetcher)
+ expect(fetcher).to receive(:headers=).with({ "X-Gemfile-Source" => "http://zombo.com" }).twice
expect(fetcher).to receive(:fetch_path).with(uri + "specs.4.8.gz").and_return(specs_response)
expect(fetcher).to receive(:fetch_path).with(uri + "prerelease_specs.4.8.gz").and_return(prerelease_specs_response)
- result = Bundler.rubygems.fetch_all_remote_specs(remote_with_mirror, fetcher)
+ result = Bundler.rubygems.fetch_all_remote_specs(remote_with_mirror)
expect(result).to eq(%w[specs prerelease_specs])
end
end
context "when there is no rubygems source mirror set" do
- let(:remote_no_mirror) { double("remote", uri: uri, original_uri: nil) }
+ let(:remote_no_mirror) { double("remote", :uri => uri, :original_uri => nil) }
it "does not set the 'X-Gemfile-Source' header" do
+ expect(Bundler.rubygems).to receive(:gem_remote_fetcher).twice.and_return(fetcher)
+ expect(fetcher).to_not receive(:headers=)
expect(fetcher).to receive(:fetch_path).with(uri + "specs.4.8.gz").and_return(specs_response)
expect(fetcher).to receive(:fetch_path).with(uri + "prerelease_specs.4.8.gz").and_return(prerelease_specs_response)
- result = Bundler.rubygems.fetch_all_remote_specs(remote_no_mirror, fetcher)
+ result = Bundler.rubygems.fetch_all_remote_specs(remote_no_mirror)
expect(result).to eq(%w[specs prerelease_specs])
end
end
context "when loading an unexpected class" do
- let(:remote_no_mirror) { double("remote", uri: uri, original_uri: nil) }
+ let(:remote_no_mirror) { double("remote", :uri => uri, :original_uri => nil) }
let(:unexpected_specs_response) { Marshal.dump(3) }
it "raises a MarshalError error" do
+ expect(Bundler.rubygems).to receive(:gem_remote_fetcher).once.and_return(fetcher)
expect(fetcher).to receive(:fetch_path).with(uri + "specs.4.8.gz").and_return(unexpected_specs_response)
- expect { Bundler.rubygems.fetch_all_remote_specs(remote_no_mirror, fetcher) }.to raise_error(Bundler::MarshalError, /unexpected class/i)
+ expect { Bundler.rubygems.fetch_all_remote_specs(remote_no_mirror) }.to raise_error(Bundler::MarshalError, /unexpected class/i)
end
end
end
diff --git a/spec/bundler/bundler/settings/validator_spec.rb b/spec/bundler/bundler/settings/validator_spec.rb
index b252ba59a0..e4ffd89435 100644
--- a/spec/bundler/bundler/settings/validator_spec.rb
+++ b/spec/bundler/bundler/settings/validator_spec.rb
@@ -44,14 +44,14 @@ RSpec.describe Bundler::Settings::Validator do
validate!("without", "b:c", "BUNDLE_WITH" => "a")
end.not_to raise_error
- expect { validate!("with", "b:c", "BUNDLE_WITHOUT" => "c:d") }.to raise_error Bundler::InvalidOption, <<~EOS.strip
+ expect { validate!("with", "b:c", "BUNDLE_WITHOUT" => "c:d") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
Setting `with` to "b:c" failed:
- a group cannot be in both `with` & `without` simultaneously
- `without` is current set to [:c, :d]
- the `c` groups conflict
EOS
- expect { validate!("without", "b:c", "BUNDLE_WITH" => "c:d") }.to raise_error Bundler::InvalidOption, <<~EOS.strip
+ expect { validate!("without", "b:c", "BUNDLE_WITH" => "c:d") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
Setting `without` to "b:c" failed:
- a group cannot be in both `with` & `without` simultaneously
- `with` is current set to [:c, :d]
@@ -74,7 +74,7 @@ RSpec.describe Bundler::Settings::Validator do
describe "#fail!" do
it "raises with a helpful message" do
- expect { subject.fail!("key", "value", "reason1", "reason2") }.to raise_error Bundler::InvalidOption, <<~EOS.strip
+ expect { subject.fail!("key", "value", "reason1", "reason2") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
Setting `key` to "value" failed:
- rule description
- reason1
diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb
index 634e0faf91..4636993d9f 100644
--- a/spec/bundler/bundler/settings_spec.rb
+++ b/spec/bundler/bundler/settings_spec.rb
@@ -131,7 +131,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
Bundler.settings.set_command_option :no_install, true
- Bundler.settings.temporary(no_install: false) do
+ Bundler.settings.temporary(:no_install => false) do
expect(Bundler.settings[:no_install]).to eq false
end
@@ -147,12 +147,12 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
context "when called without a block" do
it "leaves the setting changed" do
- Bundler.settings.temporary(foo: :random)
+ Bundler.settings.temporary(:foo => :random)
expect(Bundler.settings[:foo]).to eq "random"
end
it "returns nil" do
- expect(Bundler.settings.temporary(foo: :bar)).to be_nil
+ expect(Bundler.settings.temporary(:foo => :bar)).to be_nil
end
end
end
@@ -179,7 +179,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
describe "#mirror_for" do
- let(:uri) { Gem::URI("https://rubygems.org/") }
+ let(:uri) { Bundler::URI("https://rubygems.org/") }
context "with no configured mirror" do
it "returns the original URI" do
@@ -192,7 +192,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
context "with a configured mirror" do
- let(:mirror_uri) { Gem::URI("https://rubygems-mirror.org/") }
+ let(:mirror_uri) { Bundler::URI("https://rubygems-mirror.org/") }
before { settings.set_local "mirror.https://rubygems.org/", mirror_uri.to_s }
@@ -213,7 +213,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
context "with a file URI" do
- let(:mirror_uri) { Gem::URI("file:/foo/BAR/baz/qUx/") }
+ let(:mirror_uri) { Bundler::URI("file:/foo/BAR/baz/qUx/") }
it "returns the mirror URI" do
expect(settings.mirror_for(uri)).to eq(mirror_uri)
@@ -231,7 +231,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
end
describe "#credentials_for" do
- let(:uri) { Gem::URI("https://gemserver.example.org/") }
+ let(:uri) { Bundler::URI("https://gemserver.example.org/") }
let(:credentials) { "username:password" }
context "with no configured credentials" do
@@ -291,7 +291,7 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
it "reads older keys without trailing slashes" do
settings.set_local "mirror.https://rubygems.org", "http://rubygems-mirror.org"
expect(settings.mirror_for("https://rubygems.org/")).to eq(
- Gem::URI("http://rubygems-mirror.org/")
+ Bundler::URI("http://rubygems-mirror.org/")
)
end
@@ -319,15 +319,6 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
expect(settings["mirror.https://rubygems.org/"]).to eq("http://rubygems-mirror.org")
end
- it "ignores commented out keys" do
- create_file bundled_app(".bundle/config"), <<~C
- # BUNDLE_MY-PERSONAL-SERVER__ORG: my-personal-server.org
- C
-
- expect(Bundler.ui).not_to receive(:warn)
- expect(settings.all).to be_empty
- end
-
it "converts older keys with dashes" do
config("BUNDLE_MY-PERSONAL-SERVER__ORG" => "my-personal-server.org")
expect(Bundler.ui).to receive(:warn).with(
diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb
index 918f73b337..3c6536c4eb 100644
--- a/spec/bundler/bundler/shared_helpers_spec.rb
+++ b/spec/bundler/bundler/shared_helpers_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
RSpec.describe Bundler::SharedHelpers do
+ let(:ext_lock_double) { double(:ext_lock) }
+
before do
pwd_stub
+ allow(Bundler.rubygems).to receive(:ext_lock).and_return(ext_lock_double)
+ allow(ext_lock_double).to receive(:synchronize) {|&block| block.call }
end
let(:pwd_stub) { allow(subject).to receive(:pwd).and_return(bundled_app) }
@@ -238,12 +242,14 @@ RSpec.describe Bundler::SharedHelpers do
shared_examples_for "ENV['RUBYOPT'] gets set correctly" do
it "ensures -rbundler/setup is at the beginning of ENV['RUBYOPT']" do
subject.set_bundle_environment
- expect(ENV["RUBYOPT"].split(" ")).to start_with("-r#{install_path}/bundler/setup")
+ expect(ENV["RUBYOPT"].split(" ")).to start_with("-r#{source_lib_dir}/bundler/setup")
end
end
shared_examples_for "ENV['BUNDLER_SETUP'] gets set correctly" do
it "ensures bundler/setup is set in ENV['BUNDLER_SETUP']" do
+ skip "Does not play well with DidYouMean being a bundled gem instead of a default gem in Ruby 2.6" if RUBY_VERSION < "2.7"
+
subject.set_bundle_environment
expect(ENV["BUNDLER_SETUP"]).to eq("#{source_lib_dir}/bundler/setup")
end
@@ -361,41 +367,20 @@ RSpec.describe Bundler::SharedHelpers do
end
end
- context "when bundler install path is standard" do
- let(:install_path) { source_lib_dir }
+ context "ENV['RUBYOPT'] does not exist" do
+ before { ENV.delete("RUBYOPT") }
- context "ENV['RUBYOPT'] does not exist" do
- before { ENV.delete("RUBYOPT") }
-
- it_behaves_like "ENV['RUBYOPT'] gets set correctly"
- end
-
- context "ENV['RUBYOPT'] exists without -rbundler/setup" do
- before { ENV["RUBYOPT"] = "-I/some_app_path/lib" }
-
- it_behaves_like "ENV['RUBYOPT'] gets set correctly"
- end
-
- context "ENV['RUBYOPT'] exists and contains -rbundler/setup" do
- before { ENV["RUBYOPT"] = "-rbundler/setup" }
-
- it_behaves_like "ENV['RUBYOPT'] gets set correctly"
- end
+ it_behaves_like "ENV['RUBYOPT'] gets set correctly"
end
- context "when bundler install path contains special characters" do
- let(:install_path) { "/opt/ruby3.3.0-preview2/lib/ruby/3.3.0+0" }
+ context "ENV['RUBYOPT'] exists without -rbundler/setup" do
+ before { ENV["RUBYOPT"] = "-I/some_app_path/lib" }
- before do
- ENV["RUBYOPT"] = "-r#{install_path}/bundler/setup"
- allow(File).to receive(:expand_path).and_return("#{install_path}/bundler/setup")
- allow(Gem).to receive(:bin_path).and_return("#{install_path}/bundler/setup")
- end
+ it_behaves_like "ENV['RUBYOPT'] gets set correctly"
+ end
- it "ensures -rbundler/setup is not duplicated" do
- subject.set_bundle_environment
- expect(ENV["RUBYOPT"].split(" ").grep(%r{-r.*/bundler/setup}).length).to eq(1)
- end
+ context "ENV['RUBYOPT'] exists and contains -rbundler/setup" do
+ before { ENV["RUBYOPT"] = "-rbundler/setup" }
it_behaves_like "ENV['RUBYOPT'] gets set correctly"
end
@@ -518,34 +503,4 @@ RSpec.describe Bundler::SharedHelpers do
end
end
end
-
- describe "#major_deprecation" do
- before { allow(Bundler).to receive(:bundler_major_version).and_return(37) }
- before { allow(Bundler.ui).to receive(:warn) }
-
- it "prints and raises nothing below the deprecated major version" do
- subject.major_deprecation(38, "Message")
- subject.major_deprecation(39, "Message", removed_message: "Removal", print_caller_location: true)
- expect(Bundler.ui).not_to have_received(:warn)
- end
-
- it "prints but does not raise _at_ the deprecated major version" do
- subject.major_deprecation(37, "Message")
- subject.major_deprecation(37, "Message", removed_message: "Removal")
- expect(Bundler.ui).to have_received(:warn).with("[DEPRECATED] Message").twice
-
- subject.major_deprecation(37, "Message", print_caller_location: true)
- expect(Bundler.ui).to have_received(:warn).
- with(a_string_matching(/^\[DEPRECATED\] Message \(called at .*:\d+\)$/))
- end
-
- it "raises the appropriate errors when _past_ the deprecated major version" do
- expect { subject.major_deprecation(36, "Message") }.
- to raise_error(Bundler::DeprecatedError, "[REMOVED] Message")
- expect { subject.major_deprecation(36, "Message", removed_message: "Removal") }.
- to raise_error(Bundler::DeprecatedError, "[REMOVED] Removal")
- expect { subject.major_deprecation(35, "Message", removed_message: "Removal", print_caller_location: true) }.
- to raise_error(Bundler::DeprecatedError, /^\[REMOVED\] Removal \(called at .*:\d+\)$/)
- end
- end
end
diff --git a/spec/bundler/bundler/source/git/git_proxy_spec.rb b/spec/bundler/bundler/source/git/git_proxy_spec.rb
index f7c883eed4..c79dd8ff71 100644
--- a/spec/bundler/bundler/source/git/git_proxy_spec.rb
+++ b/spec/bundler/bundler/source/git/git_proxy_spec.rb
@@ -3,84 +3,34 @@
RSpec.describe Bundler::Source::Git::GitProxy do
let(:path) { Pathname("path") }
let(:uri) { "https://github.com/rubygems/rubygems.git" }
- let(:ref) { nil }
- let(:branch) { nil }
- let(:tag) { nil }
- let(:options) { { "ref" => ref, "branch" => branch, "tag" => tag }.compact }
+ let(:ref) { "HEAD" }
let(:revision) { nil }
let(:git_source) { nil }
- let(:clone_result) { double(Process::Status, success?: true) }
+ let(:clone_result) { double(Process::Status, :success? => true) }
let(:base_clone_args) { ["clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch"] }
- subject(:git_proxy) { described_class.new(path, uri, options, revision, git_source) }
-
- context "with explicit ref" do
- context "with branch only" do
- let(:branch) { "main" }
- it "sets explicit ref to branch" do
- expect(git_proxy.explicit_ref).to eq(branch)
- end
- end
-
- context "with ref only" do
- let(:ref) { "HEAD" }
- it "sets explicit ref to ref" do
- expect(git_proxy.explicit_ref).to eq(ref)
- end
- end
-
- context "with tag only" do
- let(:tag) { "v1.0" }
- it "sets explicit ref to ref" do
- expect(git_proxy.explicit_ref).to eq(tag)
- end
- end
-
- context "with tag and branch" do
- let(:tag) { "v1.0" }
- let(:branch) { "main" }
- it "raises error" do
- expect { git_proxy }.to raise_error(Bundler::Source::Git::AmbiguousGitReference)
- end
- end
-
- context "with tag and ref" do
- let(:tag) { "v1.0" }
- let(:ref) { "HEAD" }
- it "raises error" do
- expect { git_proxy }.to raise_error(Bundler::Source::Git::AmbiguousGitReference)
- end
- end
-
- context "with branch and ref" do
- let(:branch) { "main" }
- let(:ref) { "HEAD" }
- it "honors ref over branch" do
- expect(git_proxy.explicit_ref).to eq(ref)
- end
- end
- end
+ subject { described_class.new(path, uri, ref, revision, git_source) }
context "with configured credentials" do
it "adds username and password to URI" do
Bundler.settings.temporary(uri => "u:p") do
- allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
- expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
+ expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
end
it "adds username and password to URI for host" do
Bundler.settings.temporary("github.com" => "u:p") do
- allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
- expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
+ expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:p@github.com/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
end
it "does not add username and password to mismatched URI" do
Bundler.settings.temporary("https://u:p@github.com/rubygems/rubygems-mismatch.git" => "u:p") do
- allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
- expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
+ expect(subject).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
end
@@ -88,10 +38,10 @@ RSpec.describe Bundler::Source::Git::GitProxy do
it "keeps original userinfo" do
Bundler.settings.temporary("github.com" => "u:p") do
original = "https://orig:info@github.com/rubygems/rubygems.git"
- git_proxy = described_class.new(Pathname("path"), original, options)
- allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
- expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", original, path.to_s], nil).and_return(["", "", clone_result])
- git_proxy.checkout
+ subject = described_class.new(Pathname("path"), original, "HEAD")
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
+ expect(subject).to receive(:capture).with([*base_clone_args, "--", original, path.to_s], nil).and_return(["", "", clone_result])
+ subject.checkout
end
end
end
@@ -99,46 +49,46 @@ RSpec.describe Bundler::Source::Git::GitProxy do
describe "#version" do
context "with a normal version number" do
before do
- expect(git_proxy).to receive(:git_local).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3")
end
it "returns the git version number" do
- expect(git_proxy.version).to eq("1.2.3")
+ expect(subject.version).to eq("1.2.3")
end
it "does not raise an error when passed into Gem::Version.create" do
- expect { Gem::Version.create git_proxy.version }.not_to raise_error
+ expect { Gem::Version.create subject.version }.not_to raise_error
end
end
context "with a OSX version number" do
before do
- expect(git_proxy).to receive(:git_local).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3 (Apple Git-BS)")
end
it "strips out OSX specific additions in the version string" do
- expect(git_proxy.version).to eq("1.2.3")
+ expect(subject.version).to eq("1.2.3")
end
it "does not raise an error when passed into Gem::Version.create" do
- expect { Gem::Version.create git_proxy.version }.not_to raise_error
+ expect { Gem::Version.create subject.version }.not_to raise_error
end
end
context "with a msysgit version number" do
before do
- expect(git_proxy).to receive(:git_local).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3.msysgit.0")
end
it "strips out msysgit specific additions in the version string" do
- expect(git_proxy.version).to eq("1.2.3")
+ expect(subject.version).to eq("1.2.3")
end
it "does not raise an error when passed into Gem::Version.create" do
- expect { Gem::Version.create git_proxy.version }.not_to raise_error
+ expect { Gem::Version.create subject.version }.not_to raise_error
end
end
end
@@ -146,34 +96,34 @@ RSpec.describe Bundler::Source::Git::GitProxy do
describe "#full_version" do
context "with a normal version number" do
before do
- expect(git_proxy).to receive(:git_local).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3")
end
it "returns the git version number" do
- expect(git_proxy.full_version).to eq("1.2.3")
+ expect(subject.full_version).to eq("1.2.3")
end
end
context "with a OSX version number" do
before do
- expect(git_proxy).to receive(:git_local).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3 (Apple Git-BS)")
end
it "does not strip out OSX specific additions in the version string" do
- expect(git_proxy.full_version).to eq("1.2.3 (Apple Git-BS)")
+ expect(subject.full_version).to eq("1.2.3 (Apple Git-BS)")
end
end
context "with a msysgit version number" do
before do
- expect(git_proxy).to receive(:git_local).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3.msysgit.0")
end
it "does not strip out msysgit specific additions in the version string" do
- expect(git_proxy.full_version).to eq("1.2.3.msysgit.0")
+ expect(subject.full_version).to eq("1.2.3.msysgit.0")
end
end
end
@@ -193,22 +143,8 @@ RSpec.describe Bundler::Source::Git::GitProxy do
FileUtils.chmod("+x", file)
- bundle :lock, raise_on_error: false
+ bundle :lock, :raise_on_error => false
expect(Pathname.new(bundled_app("canary"))).not_to exist
end
-
- context "URI is HTTP" do
- let(:uri) { "http://github.com/rubygems/rubygems.git" }
- let(:without_depth_arguments) { ["clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--single-branch"] }
- let(:fail_clone_result) { double(Process::Status, success?: false) }
-
- it "retries without --depth when git url is http and fails" do
- allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
- allow(git_proxy).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "dumb http transport does not support shallow capabilities", fail_clone_result])
- expect(git_proxy).to receive(:capture).with([*without_depth_arguments, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
-
- subject.checkout
- end
- end
end
diff --git a/spec/bundler/bundler/source/git_spec.rb b/spec/bundler/bundler/source/git_spec.rb
index feef54bbf4..ed6dc3cd29 100644
--- a/spec/bundler/bundler/source/git_spec.rb
+++ b/spec/bundler/bundler/source/git_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Bundler::Source::Git do
context "when the source has a reference" do
let(:git_proxy_stub) do
- instance_double(Bundler::Source::Git::GitProxy, revision: "123abc", branch: "v1.0.0")
+ instance_double(Bundler::Source::Git::GitProxy, :revision => "123abc", :branch => "v1.0.0")
end
let(:options) do
{ "uri" => uri, "ref" => "v1.0.0" }
@@ -55,7 +55,7 @@ RSpec.describe Bundler::Source::Git do
context "when the source has both reference and glob specifiers" do
let(:git_proxy_stub) do
- instance_double(Bundler::Source::Git::GitProxy, revision: "123abc", branch: "v1.0.0")
+ instance_double(Bundler::Source::Git::GitProxy, :revision => "123abc", :branch => "v1.0.0")
end
let(:options) do
{ "uri" => uri, "ref" => "v1.0.0", "glob" => "gems/foo/*.gemspec" }
diff --git a/spec/bundler/bundler/source/rubygems/remote_spec.rb b/spec/bundler/bundler/source/rubygems/remote_spec.rb
index 56f3bee459..07ce4f968e 100644
--- a/spec/bundler/bundler/source/rubygems/remote_spec.rb
+++ b/spec/bundler/bundler/source/rubygems/remote_spec.rb
@@ -11,8 +11,8 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
allow(Digest(:MD5)).to receive(:hexdigest).with(duck_type(:to_s)) {|string| "MD5HEX(#{string})" }
end
- let(:uri_no_auth) { Gem::URI("https://gems.example.com") }
- let(:uri_with_auth) { Gem::URI("https://#{credentials}@gems.example.com") }
+ let(:uri_no_auth) { Bundler::URI("https://gems.example.com") }
+ let(:uri_with_auth) { Bundler::URI("https://#{credentials}@gems.example.com") }
let(:credentials) { "username:password" }
context "when the original URI has no credentials" do
@@ -89,11 +89,11 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
context "when the original URI has only a username" do
- let(:uri) { Gem::URI("https://SeCrEt-ToKeN@gem.fury.io/me/") }
+ let(:uri) { Bundler::URI("https://SeCrEt-ToKeN@gem.fury.io/me/") }
describe "#anonymized_uri" do
it "returns the URI without username and password" do
- expect(remote(uri).anonymized_uri).to eq(Gem::URI("https://gem.fury.io/me/"))
+ expect(remote(uri).anonymized_uri).to eq(Bundler::URI("https://gem.fury.io/me/"))
end
end
@@ -105,9 +105,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
context "when a mirror with inline credentials is configured for the URI" do
- let(:uri) { Gem::URI("https://rubygems.org/") }
- let(:mirror_uri_with_auth) { Gem::URI("https://username:password@rubygems-mirror.org/") }
- let(:mirror_uri_no_auth) { Gem::URI("https://rubygems-mirror.org/") }
+ let(:uri) { Bundler::URI("https://rubygems.org/") }
+ let(:mirror_uri_with_auth) { Bundler::URI("https://username:password@rubygems-mirror.org/") }
+ let(:mirror_uri_no_auth) { Bundler::URI("https://rubygems-mirror.org/") }
before { Bundler.settings.temporary("mirror.https://rubygems.org/" => mirror_uri_with_auth.to_s) }
@@ -131,9 +131,9 @@ RSpec.describe Bundler::Source::Rubygems::Remote do
end
context "when a mirror with configured credentials is configured for the URI" do
- let(:uri) { Gem::URI("https://rubygems.org/") }
- let(:mirror_uri_with_auth) { Gem::URI("https://#{credentials}@rubygems-mirror.org/") }
- let(:mirror_uri_no_auth) { Gem::URI("https://rubygems-mirror.org/") }
+ let(:uri) { Bundler::URI("https://rubygems.org/") }
+ let(:mirror_uri_with_auth) { Bundler::URI("https://#{credentials}@rubygems-mirror.org/") }
+ let(:mirror_uri_no_auth) { Bundler::URI("https://rubygems-mirror.org/") }
before do
Bundler.settings.temporary("mirror.https://rubygems.org/" => mirror_uri_no_auth.to_s)
diff --git a/spec/bundler/bundler/source_list_spec.rb b/spec/bundler/bundler/source_list_spec.rb
index 13453cb2a3..f860e9ff58 100644
--- a/spec/bundler/bundler/source_list_spec.rb
+++ b/spec/bundler/bundler/source_list_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe Bundler::SourceList do
end
it "ignores git protocols on request" do
- Bundler.settings.temporary("git.allow_insecure": true)
+ Bundler.settings.temporary(:"git.allow_insecure" => true)
expect(Bundler.ui).to_not receive(:warn).with(msg)
source_list.add_git_source("uri" => "git://existing-git.org/path.git")
end
@@ -125,8 +125,8 @@ RSpec.describe Bundler::SourceList do
it "adds the provided remote to the beginning of the aggregate source" do
source_list.add_global_rubygems_remote("https://othersource.org")
expect(returned_source.remotes).to eq [
- Gem::URI("https://othersource.org/"),
- Gem::URI("https://rubygems.org/"),
+ Bundler::URI("https://othersource.org/"),
+ Bundler::URI("https://rubygems.org/"),
]
end
end
diff --git a/spec/bundler/bundler/source_spec.rb b/spec/bundler/bundler/source_spec.rb
index 3b49c37431..ceb369ecdb 100644
--- a/spec/bundler/bundler/source_spec.rb
+++ b/spec/bundler/bundler/source_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Bundler::Source do
end
describe "#version_message" do
- let(:spec) { double(:spec, name: "nokogiri", version: ">= 1.6", platform: rb) }
+ let(:spec) { double(:spec, :name => "nokogiri", :version => ">= 1.6", :platform => rb) }
shared_examples_for "the lockfile specs are not relevant" do
it "should return a string with the spec name and version" do
@@ -32,19 +32,19 @@ RSpec.describe Bundler::Source do
context "when there are locked gems" do
context "that contain the relevant gem spec" do
context "without a version" do
- let(:locked_gem) { double(:locked_gem, name: "nokogiri", version: nil) }
+ let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => nil) }
it_behaves_like "the lockfile specs are not relevant"
end
context "with the same version" do
- let(:locked_gem) { double(:locked_gem, name: "nokogiri", version: ">= 1.6") }
+ let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => ">= 1.6") }
it_behaves_like "the lockfile specs are not relevant"
end
context "with a different version" do
- let(:locked_gem) { double(:locked_gem, name: "nokogiri", version: "< 1.5") }
+ let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => "< 1.5") }
context "with color", :no_color_tty do
before do
@@ -70,8 +70,8 @@ RSpec.describe Bundler::Source do
end
context "with a more recent version" do
- let(:spec) { double(:spec, name: "nokogiri", version: "1.6.1", platform: rb) }
- let(:locked_gem) { double(:locked_gem, name: "nokogiri", version: "1.7.0") }
+ let(:spec) { double(:spec, :name => "nokogiri", :version => "1.6.1", :platform => rb) }
+ let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => "1.7.0") }
context "with color", :no_color_tty do
before do
@@ -97,8 +97,8 @@ RSpec.describe Bundler::Source do
end
context "with an older version" do
- let(:spec) { double(:spec, name: "nokogiri", version: "1.7.1", platform: rb) }
- let(:locked_gem) { double(:locked_gem, name: "nokogiri", version: "1.7.0") }
+ let(:spec) { double(:spec, :name => "nokogiri", :version => "1.7.1", :platform => rb) }
+ let(:locked_gem) { double(:locked_gem, :name => "nokogiri", :version => "1.7.0") }
context "with color", :no_color_tty do
before do
@@ -128,7 +128,7 @@ RSpec.describe Bundler::Source do
describe "#can_lock?" do
context "when the passed spec's source is equivalent" do
- let(:spec) { double(:spec, source: subject) }
+ let(:spec) { double(:spec, :source => subject) }
it "should return true" do
expect(subject.can_lock?(spec)).to be_truthy
@@ -136,7 +136,7 @@ RSpec.describe Bundler::Source do
end
context "when the passed spec's source is not equivalent" do
- let(:spec) { double(:spec, source: double(:other_source)) }
+ let(:spec) { double(:spec, :source => double(:other_source)) }
it "should return false" do
expect(subject.can_lock?(spec)).to be_falsey
diff --git a/spec/bundler/bundler/spec_set_spec.rb b/spec/bundler/bundler/spec_set_spec.rb
index c4b6676223..6fedd38b50 100644
--- a/spec/bundler/bundler/spec_set_spec.rb
+++ b/spec/bundler/bundler/spec_set_spec.rb
@@ -45,6 +45,24 @@ RSpec.describe Bundler::SpecSet do
end
end
+ describe "#merge" do
+ let(:other_specs) do
+ [
+ build_spec("f", "1.0"),
+ build_spec("g", "2.0"),
+ ].flatten
+ end
+
+ let(:other_spec_set) { described_class.new(other_specs) }
+
+ it "merges the items in each gemspec" do
+ new_spec_set = subject.merge(other_spec_set)
+ specs = new_spec_set.to_a.map(&:full_name)
+ expect(specs).to include("a-1.0")
+ expect(specs).to include("f-1.0")
+ end
+ end
+
describe "#to_a" do
it "returns the specs in order" do
expect(subject.to_a.map(&:full_name)).to eq %w[
diff --git a/spec/bundler/bundler/specifications/foo.gemspec b/spec/bundler/bundler/specifications/foo.gemspec
deleted file mode 100644
index 46eb068cd1..0000000000
--- a/spec/bundler/bundler/specifications/foo.gemspec
+++ /dev/null
@@ -1,13 +0,0 @@
-# rubocop:disable Style/FrozenStringLiteralComment
-# stub: foo 1.0.0 ruby lib
-
-# The first line would be '# -*- encoding: utf-8 -*-' in a real stub gemspec
-
-Gem::Specification.new do |s|
- s.name = "foo"
- s.version = "1.0.0"
- s.loaded_from = __FILE__
- s.extensions = "ext/foo"
- s.required_ruby_version = ">= 3.0.0"
-end
-# rubocop:enable Style/FrozenStringLiteralComment
diff --git a/spec/bundler/bundler/stub_specification_spec.rb b/spec/bundler/bundler/stub_specification_spec.rb
index dae9f3cfba..fb612813c2 100644
--- a/spec/bundler/bundler/stub_specification_spec.rb
+++ b/spec/bundler/bundler/stub_specification_spec.rb
@@ -19,17 +19,6 @@ RSpec.describe Bundler::StubSpecification do
end
end
- describe "#gem_build_complete_path" do
- it "StubSpecification should have equal gem_build_complete_path as Specification" do
- spec_path = File.join(File.dirname(__FILE__), "specifications", "foo.gemspec")
- spec = Gem::Specification.load(spec_path)
- gem_stub = Gem::StubSpecification.new(spec_path, File.dirname(__FILE__),"","")
-
- stub = described_class.from_stub(gem_stub)
- expect(stub.gem_build_complete_path).to eq spec.gem_build_complete_path
- end
- end
-
describe "#manually_installed?" do
it "returns true if installed_by_version is nil or 0" do
stub = described_class.from_stub(with_bundler_stub_spec)
diff --git a/spec/bundler/bundler/uri_credentials_filter_spec.rb b/spec/bundler/bundler/uri_credentials_filter_spec.rb
index ed24744a1c..466c1b8594 100644
--- a/spec/bundler/bundler/uri_credentials_filter_spec.rb
+++ b/spec/bundler/bundler/uri_credentials_filter_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe Bundler::URICredentialsFilter do
let(:credentials) { "oauth_token:x-oauth-basic@" }
it "returns the uri without the oauth token" do
- expect(subject.credential_filtered_uri(uri).to_s).to eq(Gem::URI("https://x-oauth-basic@github.com/company/private-repo").to_s)
+ expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://x-oauth-basic@github.com/company/private-repo").to_s)
end
it_behaves_like "original type of uri is maintained"
@@ -26,7 +26,7 @@ RSpec.describe Bundler::URICredentialsFilter do
let(:credentials) { "oauth_token:x@" }
it "returns the uri without the oauth token" do
- expect(subject.credential_filtered_uri(uri).to_s).to eq(Gem::URI("https://x@github.com/company/private-repo").to_s)
+ expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://x@github.com/company/private-repo").to_s)
end
it_behaves_like "original type of uri is maintained"
@@ -37,7 +37,7 @@ RSpec.describe Bundler::URICredentialsFilter do
let(:credentials) { "username1:hunter3@" }
it "returns the uri without the password" do
- expect(subject.credential_filtered_uri(uri).to_s).to eq(Gem::URI("https://username1@github.com/company/private-repo").to_s)
+ expect(subject.credential_filtered_uri(uri).to_s).to eq(Bundler::URI("https://username1@github.com/company/private-repo").to_s)
end
it_behaves_like "original type of uri is maintained"
@@ -55,7 +55,7 @@ RSpec.describe Bundler::URICredentialsFilter do
end
context "uri is a uri object" do
- let(:uri) { Gem::URI("https://#{credentials}github.com/company/private-repo") }
+ let(:uri) { Bundler::URI("https://#{credentials}github.com/company/private-repo") }
it_behaves_like "sensitive credentials in uri are filtered out"
end
@@ -90,7 +90,7 @@ RSpec.describe Bundler::URICredentialsFilter do
describe "#credential_filtered_string" do
let(:str_to_filter) { "This is a git message containing a uri #{uri}!" }
let(:credentials) { "" }
- let(:uri) { Gem::URI("https://#{credentials}github.com/company/private-repo") }
+ let(:uri) { Bundler::URI("https://#{credentials}github.com/company/private-repo") }
context "with a uri that contains credentials" do
let(:credentials) { "oauth_token:x-oauth-basic@" }
diff --git a/spec/bundler/bundler/yaml_serializer_spec.rb b/spec/bundler/bundler/yaml_serializer_spec.rb
index de437f764a..1241c74bbf 100644
--- a/spec/bundler/bundler/yaml_serializer_spec.rb
+++ b/spec/bundler/bundler/yaml_serializer_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Bundler::YAMLSerializer do
it "works for simple hash" do
hash = { "Q" => "Where does Thursday come before Wednesday? In the dictionary. :P" }
- expected = <<~YAML
+ expected = strip_whitespace <<-YAML
---
Q: "Where does Thursday come before Wednesday? In the dictionary. :P"
YAML
@@ -24,7 +24,7 @@ RSpec.describe Bundler::YAMLSerializer do
},
}
- expected = <<~YAML
+ expected = strip_whitespace <<-YAML
---
nice-one:
read_ahead: "All generalizations are false, including this one"
@@ -45,7 +45,7 @@ RSpec.describe Bundler::YAMLSerializer do
},
}
- expected = <<~YAML
+ expected = strip_whitespace <<-YAML
---
nested_hash:
contains_array:
@@ -57,24 +57,11 @@ RSpec.describe Bundler::YAMLSerializer do
expect(serializer.dump(hash)).to eq(expected)
end
-
- it "handles empty array" do
- hash = {
- "empty_array" => [],
- }
-
- expected = <<~YAML
- ---
- empty_array: []
- YAML
-
- expect(serializer.dump(hash)).to eq(expected)
- end
end
describe "#load" do
it "works for simple hash" do
- yaml = <<~YAML
+ yaml = strip_whitespace <<-YAML
---
Jon: "Air is free dude!"
Jack: "Yes.. until you buy a bag of chips!"
@@ -89,7 +76,7 @@ RSpec.describe Bundler::YAMLSerializer do
end
it "works for nested hash" do
- yaml = <<~YAML
+ yaml = strip_whitespace <<-YAML
---
baa:
baa: "black sheep"
@@ -111,7 +98,7 @@ RSpec.describe Bundler::YAMLSerializer do
end
it "handles colon in key/value" do
- yaml = <<~YAML
+ yaml = strip_whitespace <<-YAML
BUNDLE_MIRROR__HTTPS://RUBYGEMS__ORG/: http://rubygems-mirror.org
YAML
@@ -119,7 +106,7 @@ RSpec.describe Bundler::YAMLSerializer do
end
it "handles arrays inside hashes" do
- yaml = <<~YAML
+ yaml = strip_whitespace <<-YAML
---
nested_hash:
contains_array:
@@ -140,7 +127,7 @@ RSpec.describe Bundler::YAMLSerializer do
end
it "handles windows-style CRLF line endings" do
- yaml = <<~YAML.gsub("\n", "\r\n")
+ yaml = strip_whitespace(<<-YAML).gsub("\n", "\r\n")
---
nested_hash:
contains_array:
@@ -161,34 +148,6 @@ RSpec.describe Bundler::YAMLSerializer do
expect(serializer.load(yaml)).to eq(hash)
end
-
- it "handles empty array" do
- yaml = <<~YAML
- ---
- empty_array: []
- YAML
-
- hash = {
- "empty_array" => [],
- }
-
- expect(serializer.load(yaml)).to eq(hash)
- end
-
- it "skip commented out words" do
- yaml = <<~YAML
- ---
- foo: bar
- buzz: foo # bar
- YAML
-
- hash = {
- "foo" => "bar",
- "buzz" => "foo",
- }
-
- expect(serializer.load(yaml)).to eq(hash)
- end
end
describe "against yaml lib" do
diff --git a/spec/bundler/cache/gems_spec.rb b/spec/bundler/cache/gems_spec.rb
index abbc2c3cf2..63c00eba01 100644
--- a/spec/bundler/cache/gems_spec.rb
+++ b/spec/bundler/cache/gems_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe "bundle cache" do
gem 'rack'
G
- system_gems "rack-1.0.0", path: path
+ system_gems "rack-1.0.0", :path => path
bundle :cache
end
@@ -17,7 +17,7 @@ RSpec.describe "bundle cache" do
end
it "uses the cache as a source when installing gems" do
- build_gem "omg", path: bundled_app("vendor/cache")
+ build_gem "omg", :path => bundled_app("vendor/cache")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -28,14 +28,14 @@ RSpec.describe "bundle cache" do
end
it "uses the cache as a source when installing gems with --local" do
- system_gems [], path: default_bundle_path
+ system_gems [], :path => default_bundle_path
bundle "install --local"
expect(the_bundle).to include_gems("rack 1.0.0")
end
it "does not reinstall gems from the cache if they exist on the system" do
- build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s|
+ build_gem "rack", "1.0.0", :path => bundled_app("vendor/cache") do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
@@ -48,18 +48,18 @@ RSpec.describe "bundle cache" do
end
it "does not reinstall gems from the cache if they exist in the bundle" do
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s|
+ build_gem "rack", "1.0.0", :path => bundled_app("vendor/cache") do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
- bundle :install, local: true
+ bundle :install, :local => true
expect(the_bundle).to include_gems("rack 1.0.0")
end
@@ -97,12 +97,12 @@ RSpec.describe "bundle cache" do
build_gem "json", default_json_version
end
- build_gem "json", default_json_version, to_system: true, default: true
+ build_gem "json", default_json_version, :to_system => true, :default => true
end
it "uses builtin gems when installing to system gems" do
bundle "config set path.system true"
- install_gemfile %(source "#{file_uri_for(gem_repo1)}"; gem 'json', '#{default_json_version}'), verbose: true
+ install_gemfile %(source "#{file_uri_for(gem_repo1)}"; gem 'json', '#{default_json_version}'), :verbose => true
expect(out).to include("Using json #{default_json_version}")
end
@@ -131,7 +131,7 @@ RSpec.describe "bundle cache" do
end
it "doesn't make remote request after caching the gem" do
- build_gem "builtin_gem_2", "1.0.2", path: bundled_app("vendor/cache") do |s|
+ build_gem "builtin_gem_2", "1.0.2", :path => bundled_app("vendor/cache") do |s|
s.summary = "This builtin_gem is bundled with Ruby"
end
@@ -152,7 +152,7 @@ RSpec.describe "bundle cache" do
gem 'json', '#{default_json_version}'
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
expect(exitstatus).to_not eq(0)
expect(err).to include("json-#{default_json_version} is built in to Ruby, and can't be cached")
end
@@ -218,7 +218,7 @@ RSpec.describe "bundle cache" do
end
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(cached_gem("rack-1.2")).to exist
expect(cached_gem("rack-1.0.0")).not_to exist
end
@@ -279,61 +279,14 @@ RSpec.describe "bundle cache" do
it "doesn't remove gems with mismatched :rubygems_version or :date" do
cached_gem("rack-1.0.0").rmtree
build_gem "rack", "1.0.0",
- path: bundled_app("vendor/cache"),
- rubygems_version: "1.3.2"
- # This test is only really valid if the checksum isn't saved. It otherwise can't be the same gem. Tested below.
- bundled_app_lock.write remove_checksums_from_lockfile(bundled_app_lock.read, "rack (1.0.0)")
+ :path => bundled_app("vendor/cache"),
+ :rubygems_version => "1.3.2"
simulate_new_machine
bundle :install
expect(cached_gem("rack-1.0.0")).to exist
end
- it "raises an error when the gem is altered and produces a different checksum" do
- cached_gem("rack-1.0.0").rmtree
- build_gem "rack", "1.0.0", path: bundled_app("vendor/cache")
-
- checksums = checksums_section do |c|
- c.checksum gem_repo1, "rack", "1.0.0"
- end
-
- simulate_new_machine
-
- lockfile <<-L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- rack (1.0.0)
- #{checksums}
- L
-
- bundle :install, raise_on_error: false
- expect(exitstatus).to eq(37)
- expect(err).to include("Bundler found mismatched checksums.")
- expect(err).to include("1. remove the gem at #{cached_gem("rack-1.0.0")}")
-
- expect(cached_gem("rack-1.0.0")).to exist
- cached_gem("rack-1.0.0").rmtree
- bundle :install
- expect(cached_gem("rack-1.0.0")).to exist
- end
-
- it "installs a modified gem with a non-matching checksum when checksums is not opted in" do
- cached_gem("rack-1.0.0").rmtree
- build_gem "rack", "1.0.0", path: bundled_app("vendor/cache")
- simulate_new_machine
-
- lockfile <<-L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- rack (1.0.0)
- L
-
- bundle :install
- expect(cached_gem("rack-1.0.0")).to exist
- end
-
it "handles directories and non .gem files in the cache" do
bundled_app("vendor/cache/foo").mkdir
File.open(bundled_app("vendor/cache/bar"), "w") {|f| f.write("not a gem") }
@@ -361,7 +314,7 @@ RSpec.describe "bundle cache" do
it "should install gems with the name bundler in them (that aren't bundler)" do
build_gem "foo-bundler", "1.0",
- path: bundled_app("vendor/cache")
+ :path => bundled_app("vendor/cache")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
diff --git a/spec/bundler/cache/git_spec.rb b/spec/bundler/cache/git_spec.rb
index 4b3cd4d2eb..890ba88605 100644
--- a/spec/bundler/cache/git_spec.rb
+++ b/spec/bundler/cache/git_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe "bundle cache with git" do
ref = git.ref_for("main", 11)
expect(ref).not_to eq(old_ref)
- bundle "update", all: true
+ bundle "update", :all => true
bundle :cache
expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist
@@ -164,8 +164,8 @@ RSpec.describe "bundle cache with git" do
s.add_dependency "submodule"
end
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", dir: lib_path("has_submodule-1.0")
- sys_exec "git commit -m \"submodulator\"", dir: lib_path("has_submodule-1.0")
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -216,7 +216,7 @@ RSpec.describe "bundle cache with git" do
simulate_new_machine
with_path_as "" do
bundle "config set deployment true"
- bundle :install, local: true
+ bundle :install, :local => true
expect(the_bundle).to include_gem "foo 1.0"
end
end
@@ -266,8 +266,8 @@ RSpec.describe "bundle cache with git" do
# Verify that the compilation worked and the result is in $LOAD_PATH by simply attempting
# to require it; that should make sure this spec does not break if the load path behaviour
# is changed.
- bundle :install, local: true
- ruby <<~R, raise_on_error: false
+ bundle :install, :local => true
+ ruby <<~R, :raise_on_error => false
require 'bundler/setup'
require 'foo_c'
R
diff --git a/spec/bundler/cache/path_spec.rb b/spec/bundler/cache/path_spec.rb
index 2c8a52617a..2ad136a008 100644
--- a/spec/bundler/cache/path_spec.rb
+++ b/spec/bundler/cache/path_spec.rb
@@ -2,7 +2,7 @@
RSpec.describe "bundle cache with path" do
it "is no-op when the path is within the bundle" do
- build_lib "foo", path: bundled_app("lib/foo")
+ build_lib "foo", :path => bundled_app("lib/foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -35,7 +35,7 @@ RSpec.describe "bundle cache with path" do
libname = File.basename(bundled_app) + "_gem"
libpath = File.join(File.dirname(bundled_app), libname)
- build_lib libname, path: libpath
+ build_lib libname, :path => libpath
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -97,7 +97,7 @@ RSpec.describe "bundle cache with path" do
expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
end
- it "does not cache path gems by default", bundler: "< 3" do
+ it "does not cache path gems by default", :bundler => "< 3" do
build_lib "foo"
install_gemfile <<-G
@@ -110,7 +110,7 @@ RSpec.describe "bundle cache with path" do
expect(bundled_app("vendor/cache/foo-1.0")).not_to exist
end
- it "caches path gems by default", bundler: "3" do
+ it "caches path gems by default", :bundler => "3" do
build_lib "foo"
install_gemfile <<-G
@@ -163,7 +163,7 @@ RSpec.describe "bundle cache with path" do
gem "baz", :path => '#{lib_path("baz-1.0")}'
G
- bundle "cache --no-all", raise_on_error: false
+ bundle "cache --no-all", :raise_on_error => false
expect(bundled_app("vendor/cache/baz-1.0")).not_to exist
end
end
diff --git a/spec/bundler/cache/platform_spec.rb b/spec/bundler/cache/platform_spec.rb
index 36db954c79..128278956c 100644
--- a/spec/bundler/cache/platform_spec.rb
+++ b/spec/bundler/cache/platform_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe "bundle cache with multiple platforms" do
end
it "ensures that a successful bundle update does not delete gems for other platforms" do
- bundle "update", all: true
+ bundle "update", :all => true
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
expect(bundled_app("vendor/cache/activesupport-2.3.5.gem")).to exist
diff --git a/spec/bundler/commands/add_spec.rb b/spec/bundler/commands/add_spec.rb
index 36e286793b..5a5b534e8d 100644
--- a/spec/bundler/commands/add_spec.rb
+++ b/spec/bundler/commands/add_spec.rb
@@ -9,7 +9,6 @@ RSpec.describe "bundle add" do
build_gem "bar", "0.12.3"
build_gem "cat", "0.12.3.pre"
build_gem "dog", "1.1.3.pre"
- build_gem "lemur", "3.1.1.pre.2023.1.1"
end
build_git "foo", "2.0"
@@ -22,7 +21,7 @@ RSpec.describe "bundle add" do
context "when no gems are specified" do
it "shows error" do
- bundle "add", raise_on_error: false
+ bundle "add", :raise_on_error => false
expect(err).to include("Please specify gems to add")
end
@@ -52,13 +51,6 @@ RSpec.describe "bundle add" do
expect(bundled_app_gemfile.read).to match(/gem "dog", "~> 1.1.pre"/)
expect(the_bundle).to include_gems "dog 1.1.3.pre"
end
-
- it "version requirement becomes ~> major.minor.pre.tail when resolved version has a very long tail pre version" do
- bundle "add 'lemur'"
- # the trailing pre purposely matches the release version to ensure that subbing the release doesn't change the pre.version"
- expect(bundled_app_gemfile.read).to match(/gem "lemur", "~> 3.1.pre.2023.1.1"/)
- expect(the_bundle).to include_gems "lemur 3.1.1.pre.2023.1.1"
- end
end
describe "with --version" do
@@ -71,7 +63,7 @@ RSpec.describe "bundle add" do
it "adds multiple version constraints when specified" do
requirements = ["< 3.0", "> 1.0"]
bundle "add 'foo' --version='#{requirements.join(", ")}'"
- expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(", ")}/)
+ expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(', ')}/)
expect(the_bundle).to include_gems "foo 2.0"
end
end
@@ -131,7 +123,7 @@ RSpec.describe "bundle add" do
describe "with --git and --branch" do
before do
- update_git "foo", "2.0", branch: "test"
+ update_git "foo", "2.0", :branch => "test"
end
it "adds dependency with specified git source and branch" do
@@ -155,7 +147,7 @@ RSpec.describe "bundle add" do
it "adds dependency with specified github source", :realworld do
bundle "add rake --github=ruby/rake"
- expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake"})
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake"})
end
end
@@ -163,7 +155,7 @@ RSpec.describe "bundle add" do
it "adds dependency with specified github source and branch", :realworld do
bundle "add rake --github=ruby/rake --branch=master"
- expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :branch => "master"})
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :branch => "master"})
end
end
@@ -171,62 +163,7 @@ RSpec.describe "bundle add" do
it "adds dependency with specified github source and ref", :realworld do
bundle "add rake --github=ruby/rake --ref=5c60da8"
- expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :ref => "5c60da8"})
- end
- end
-
- describe "with --git and --glob" do
- it "adds dependency with specified git source" do
- bundle "add foo --git=#{lib_path("foo-2.0")} --glob='./*.gemspec'"
-
- expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}", :glob => "\./\*\.gemspec"})
- expect(the_bundle).to include_gems "foo 2.0"
- end
- end
-
- describe "with --git and --branch and --glob" do
- before do
- update_git "foo", "2.0", branch: "test"
- end
-
- it "adds dependency with specified git source and branch" do
- bundle "add foo --git=#{lib_path("foo-2.0")} --branch=test --glob='./*.gemspec'"
-
- expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}", :branch => "test", :glob => "\./\*\.gemspec"})
- expect(the_bundle).to include_gems "foo 2.0"
- end
- end
-
- describe "with --git and --ref and --glob" do
- it "adds dependency with specified git source and branch" do
- bundle "add foo --git=#{lib_path("foo-2.0")} --ref=#{revision_for(lib_path("foo-2.0"))} --glob='./*.gemspec'"
-
- expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2\.0", :git => "#{lib_path("foo-2.0")}", :ref => "#{revision_for(lib_path("foo-2.0"))}", :glob => "\./\*\.gemspec"})
- expect(the_bundle).to include_gems "foo 2.0"
- end
- end
-
- describe "with --github and --glob" do
- it "adds dependency with specified github source", :realworld do
- bundle "add rake --github=ruby/rake --glob='./*.gemspec'"
-
- expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :glob => "\.\/\*\.gemspec"})
- end
- end
-
- describe "with --github and --branch --and glob" do
- it "adds dependency with specified github source and branch", :realworld do
- bundle "add rake --github=ruby/rake --branch=master --glob='./*.gemspec'"
-
- expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :branch => "master", :glob => "\.\/\*\.gemspec"})
- end
- end
-
- describe "with --github and --ref and --glob" do
- it "adds dependency with specified github source and ref", :realworld do
- bundle "add rake --github=ruby/rake --ref=5c60da8 --glob='./*.gemspec'"
-
- expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :ref => "5c60da8", :glob => "\.\/\*\.gemspec"})
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :ref => "5c60da8"})
end
end
@@ -246,24 +183,24 @@ RSpec.describe "bundle add" do
end
it "shows error message when version is not formatted correctly" do
- bundle "add 'foo' -v='~>1 . 0'", raise_on_error: false
+ bundle "add 'foo' -v='~>1 . 0'", :raise_on_error => false
expect(err).to match("Invalid gem requirement pattern '~>1 . 0'")
end
it "shows error message when gem cannot be found" do
bundle "config set force_ruby_platform true"
- bundle "add 'werk_it'", raise_on_error: false
+ bundle "add 'werk_it'", :raise_on_error => false
expect(err).to match("Could not find gem 'werk_it' in")
- bundle "add 'werk_it' -s='#{file_uri_for(gem_repo2)}'", raise_on_error: false
+ bundle "add 'werk_it' -s='#{file_uri_for(gem_repo2)}'", :raise_on_error => false
expect(err).to match("Could not find gem 'werk_it' in rubygems repository")
end
it "shows error message when source cannot be reached" do
- bundle "add 'baz' --source='http://badhostasdf'", raise_on_error: false
+ bundle "add 'baz' --source='http://badhostasdf'", :raise_on_error => false
expect(err).to include("Could not reach host badhostasdf. Check your network connection and try again.")
- bundle "add 'baz' --source='file://does/not/exist'", raise_on_error: false
+ bundle "add 'baz' --source='file://does/not/exist'", :raise_on_error => false
expect(err).to include("Could not fetch specs from file://does/not/exist/")
end
@@ -293,7 +230,7 @@ RSpec.describe "bundle add" do
describe "with --optimistic and --strict" do
it "throws error" do
- bundle "add 'foo' --strict --optimistic", raise_on_error: false
+ bundle "add 'foo' --strict --optimistic", :raise_on_error => false
expect(err).to include("You can not specify `--strict` and `--optimistic` at the same time")
end
@@ -308,7 +245,7 @@ RSpec.describe "bundle add" do
end
it "throws error if any of the specified gems are present in the gemfile with different version" do
- bundle "add weakling bar", raise_on_error: false
+ bundle "add weakling bar", :raise_on_error => false
expect(err).to include("You cannot specify the same gem twice with different version requirements")
expect(err).to include("You specified: weakling (~> 0.0.1) and weakling (>= 0).")
@@ -322,7 +259,7 @@ RSpec.describe "bundle add" do
gem "rack", "1.0"
G
- bundle "add 'rack' --version=1.1", raise_on_error: false
+ bundle "add 'rack' --version=1.1", :raise_on_error => false
expect(err).to include("You cannot specify the same gem twice with different version requirements")
expect(err).to include("If you want to update the gem version, run `bundle update rack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive")
@@ -334,7 +271,7 @@ RSpec.describe "bundle add" do
gem "rack", "1.0"
G
- bundle "add 'rack'", raise_on_error: false
+ bundle "add 'rack'", :raise_on_error => false
expect(err).to include("Gem already added.")
expect(err).to include("You cannot specify the same gem twice with different version requirements")
@@ -349,7 +286,7 @@ RSpec.describe "bundle add" do
gem "rack"
G
- bundle "add 'rack' --version=1.1", raise_on_error: false
+ bundle "add 'rack' --version=1.1", :raise_on_error => false
expect(err).to include("You cannot specify the same gem twice with different version requirements")
expect(err).to include("If you want to update the gem version, run `bundle update rack`.")
diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb
index 6c3dc7bb2d..bfbef58181 100644
--- a/spec/bundler/commands/binstubs_spec.rb
+++ b/spec/bundler/commands/binstubs_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe "bundle binstubs <gem>" do
gem "rails"
G
- bundle :binstubs, all: true
+ bundle :binstubs, :all => true
expect(bundled_app("bin/rails")).to exist
expect(bundled_app("bin/rake")).to exist
@@ -69,7 +69,7 @@ RSpec.describe "bundle binstubs <gem>" do
gem "rack"
G
- bundle "binstubs", raise_on_error: false
+ bundle "binstubs", :raise_on_error => false
expect(exitstatus).to eq(1)
expect(err).to include("`bundle binstubs` needs at least one gem to run.")
end
@@ -80,7 +80,7 @@ RSpec.describe "bundle binstubs <gem>" do
gem "rack"
G
- bundle "binstubs rack", all: true, raise_on_error: false
+ bundle "binstubs rack", :all => true, :raise_on_error => false
expect(last_command).to be_failure
expect(err).to include("Cannot specify --all with specific gems")
end
@@ -98,7 +98,7 @@ RSpec.describe "bundle binstubs <gem>" do
file.print "OMG"
end
- sys_exec "bin/rackup", raise_on_error: false
+ sys_exec "bin/rackup", :raise_on_error => false
expect(err).to include("was not generated by Bundler")
end
@@ -132,13 +132,13 @@ RSpec.describe "bundle binstubs <gem>" do
let(:system_bundler_version) { Bundler::VERSION }
it "runs bundler" do
- sys_exec "bin/bundle install", env: { "DEBUG" => "1" }
+ sys_exec "bin/bundle install", :env => { "DEBUG" => "1" }
expect(out).to include %(Using bundler #{system_bundler_version}\n)
end
context "when BUNDLER_VERSION is set" do
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", env: { "BUNDLER_VERSION" => "999.999.999" }, raise_on_error: false
+ sys_exec "bin/bundle install", :env => { "BUNDLER_VERSION" => "999.999.999" }, :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (999.999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
@@ -147,7 +147,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "runs the correct version of bundler even if a higher version is installed" do
system_gems "bundler-999.999.998", "bundler-999.999.999"
- sys_exec "bin/bundle install", env: { "BUNDLER_VERSION" => "999.999.998", "DEBUG" => "1" }, raise_on_error: false
+ sys_exec "bin/bundle install", :env => { "BUNDLER_VERSION" => "999.999.998", "DEBUG" => "1" }, :raise_on_error => false
expect(out).to include %(Using bundler 999.999.998\n)
end
end
@@ -159,7 +159,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", raise_on_error: false
+ sys_exec "bin/bundle install", :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
@@ -173,7 +173,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false
+ sys_exec "bin/bundle install", :env => { "BUNDLE_GEMFILE" => "gems.rb" }, :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 999.999) failed:").
@@ -189,7 +189,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", raise_on_error: false
+ sys_exec "bin/bundle install", :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 44.0) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`")
@@ -205,7 +205,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false
+ sys_exec "bin/bundle install", :env => { "BUNDLE_GEMFILE" => "gems.rb" }, :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 44.0) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`")
@@ -219,15 +219,15 @@ RSpec.describe "bundle binstubs <gem>" do
lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.3.0")
end
- it "installs and runs the exact version of bundler", rubygems: ">= 3.3.0.dev", realworld: true do
- sys_exec "bin/bundle install --verbose", artifice: "vcr"
+ it "installs and runs the exact version of bundler", :rubygems => ">= 3.3.0.dev", :realworld => true do
+ sys_exec "bin/bundle install --verbose", :artifice => "vcr"
expect(exitstatus).not_to eq(42)
expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.")
expect(out).to include("Using bundler 2.3.0")
expect(err).not_to include("Activating bundler (~> 2.3.0) failed:")
end
- it "runs the available version of bundler", rubygems: "< 3.3.0.dev" do
+ it "runs the available version of bundler", :rubygems => "< 3.3.0.dev" do
sys_exec "bin/bundle install --verbose"
expect(exitstatus).not_to eq(42)
expect(out).not_to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.")
@@ -244,7 +244,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler when the version is a pre-release" do
- sys_exec "bin/bundle install", raise_on_error: false
+ sys_exec "bin/bundle install", :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 2.12.a) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 2.12.a'`")
@@ -256,7 +256,7 @@ RSpec.describe "bundle binstubs <gem>" do
before { lockfile.gsub(system_bundler_version, "1.1.1") }
it "calls through to the latest bundler version", :realworld do
- sys_exec "bin/bundle update --bundler", env: { "DEBUG" => "1" }
+ sys_exec "bin/bundle update --bundler", :env => { "DEBUG" => "1" }
using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out)
expect(using_bundler_line).to_not be_nil
latest_version = using_bundler_line[1]
@@ -264,7 +264,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "calls through to the explicit bundler version" do
- sys_exec "bin/bundle update --bundler=999.999.999", raise_on_error: false
+ sys_exec "bin/bundle update --bundler=999.999.999", :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (999.999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
@@ -274,7 +274,7 @@ RSpec.describe "bundle binstubs <gem>" do
context "without a lockfile" do
it "falls back to the latest installed bundler" do
FileUtils.rm bundled_app_lock
- sys_exec "bin/bundle install", env: { "DEBUG" => "1" }
+ sys_exec "bin/bundle install", :env => { "DEBUG" => "1" }
expect(out).to include "Using bundler #{system_bundler_version}\n"
end
end
@@ -289,7 +289,7 @@ RSpec.describe "bundle binstubs <gem>" do
before { lockfile lockfile.gsub(Bundler::VERSION, "999.999.999") }
it "attempts to load that version" do
- sys_exec bundled_app("bin/rackup").to_s, raise_on_error: false
+ sys_exec bundled_app("bin/rackup").to_s, :raise_on_error => false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
@@ -301,7 +301,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "installs binstubs from git gems" do
FileUtils.mkdir_p(lib_path("foo/bin"))
FileUtils.touch(lib_path("foo/bin/foo"))
- build_git "foo", "1.0", path: lib_path("foo") do |s|
+ build_git "foo", "1.0", :path => lib_path("foo") do |s|
s.executables = %w[foo]
end
install_gemfile <<-G
@@ -317,7 +317,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "installs binstubs from path gems" do
FileUtils.mkdir_p(lib_path("foo/bin"))
FileUtils.touch(lib_path("foo/bin/foo"))
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.executables = %w[foo]
end
install_gemfile <<-G
@@ -362,7 +362,7 @@ RSpec.describe "bundle binstubs <gem>" do
source "#{file_uri_for(gem_repo1)}"
G
- bundle "binstubs doesnt_exist", raise_on_error: false
+ bundle "binstubs doesnt_exist", :raise_on_error => false
expect(exitstatus).to eq(7)
expect(err).to include("Could not find gem 'doesnt_exist'.")
@@ -381,14 +381,14 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("exec/rackup")).to exist
end
- it "setting is saved for bundle install", bundler: "< 3" do
+ it "setting is saved for bundle install", :bundler => "< 3" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rails"
G
- bundle "binstubs rack", path: "exec"
+ bundle "binstubs rack", :path => "exec"
bundle :install
expect(bundled_app("exec/rails")).to exist
@@ -549,7 +549,7 @@ RSpec.describe "bundle binstubs <gem>" do
G
bundle "config set auto_install 1"
- bundle "binstubs rack", env: { "BUNDLE_INSTALL" => "1" }
+ bundle "binstubs rack", :env => { "BUNDLE_INSTALL" => "1" }
expect(out).not_to include("Installing rack 1.0.0")
end
end
diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb
index 37d8b3ac1a..a9ed389233 100644
--- a/spec/bundler/commands/cache_spec.rb
+++ b/spec/bundler/commands/cache_spec.rb
@@ -158,7 +158,7 @@ RSpec.describe "bundle cache" do
end
end
- context "with --path", bundler: "< 3" do
+ context "with --path", :bundler => "< 3" do
it "sets root directory for gems" do
gemfile <<-D
source "#{file_uri_for(gem_repo1)}"
@@ -211,17 +211,7 @@ RSpec.describe "bundle cache" do
end
context "with --all-platforms" do
- it "puts the gems in vendor/cache even for other rubies", bundler: ">= 2.4.0" do
- gemfile <<-D
- source "#{file_uri_for(gem_repo1)}"
- gem 'rack', :platforms => [:ruby_20, :windows_20]
- D
-
- bundle "cache --all-platforms"
- expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- end
-
- it "puts the gems in vendor/cache even for legacy windows rubies", bundler: ">= 2.4.0" do
+ it "puts the gems in vendor/cache even for other rubies" do
gemfile <<-D
source "#{file_uri_for(gem_repo1)}"
gem 'rack', :platforms => [:ruby_20, :x64_mingw_20]
@@ -272,7 +262,7 @@ RSpec.describe "bundle cache" do
end
G
- bundle :lock, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
+ bundle :lock, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
bundle :cache, "all-platforms" => true, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
end
@@ -289,7 +279,7 @@ RSpec.describe "bundle cache" do
subject do
bundle "config set --local frozen true"
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
end
it "tries to install with frozen" do
@@ -386,66 +376,6 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "uses cached gems for secondary sources when cache_all_platforms configured" do
- build_repo4 do
- build_gem "foo", "1.0.0" do |s|
- s.platform = "x86_64-linux"
- end
-
- build_gem "foo", "1.0.0" do |s|
- s.platform = "arm64-darwin"
- end
- end
-
- gemfile <<~G
- source "https://gems.repo2"
-
- source "https://gems.repo4" do
- gem "foo"
- end
- G
-
- lockfile <<~L
- GEM
- remote: https://gems.repo2/
- specs:
-
- GEM
- remote: https://gems.repo4/
- specs:
- foo (1.0.0-x86_64-linux)
- foo (1.0.0-arm64-darwin)
-
- PLATFORMS
- arm64-darwin
- ruby
- x86_64-linux
-
- DEPENDENCIES
- foo
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- simulate_platform "x86_64-linux" do
- bundle "config set cache_all_platforms true"
- bundle "config set path vendor/bundle"
- bundle :cache, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- build_repo4 do
- # simulate removal of all remote gems
- end
-
- # delete compact index cache
- FileUtils.rm_rf home(".bundle/cache/compact_index")
-
- bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- expect(the_bundle).to include_gems "foo 1.0.0 x86_64-linux"
- end
- end
-
it "does not reinstall already-installed gems" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -453,7 +383,7 @@ RSpec.describe "bundle install with gem sources" do
G
bundle :cache
- build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s|
+ build_gem "rack", "1.0.0", :path => bundled_app("vendor/cache") do |s|
s.write "lib/rack.rb", "raise 'omg'"
end
diff --git a/spec/bundler/commands/check_spec.rb b/spec/bundler/commands/check_spec.rb
index 02f9bb5b7a..99a858e9e9 100644
--- a/spec/bundler/commands/check_spec.rb
+++ b/spec/bundler/commands/check_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle "check --gemfile bundled_app/Gemfile", dir: tmp
+ bundle "check --gemfile bundled_app/Gemfile", :dir => tmp
expect(out).to include("The Gemfile's dependencies are satisfied")
end
@@ -55,7 +55,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
@@ -65,7 +65,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(exitstatus).to be > 0
expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
@@ -88,11 +88,11 @@ RSpec.describe "bundle check" do
gem "rails_pinned_to_old_activesupport"
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
- it "remembers --without option from install", bundler: "< 3" do
+ it "remembers --without option from install", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
group :foo do
@@ -132,7 +132,7 @@ RSpec.describe "bundle check" do
gem "rack"
G
- bundle "check", raise_on_error: false
+ bundle "check", :raise_on_error => false
expect(err).to include("* rack (1.0.0)")
expect(exitstatus).to eq(1)
end
@@ -146,9 +146,9 @@ RSpec.describe "bundle check" do
bundle "config set --local path vendor/bundle"
bundle :cache
- gem_command "uninstall rack", env: { "GEM_HOME" => vendored_gems.to_s }
+ gem_command "uninstall rack", :env => { "GEM_HOME" => vendored_gems.to_s }
- bundle "check", raise_on_error: false
+ bundle "check", :raise_on_error => false
expect(err).to include("* rack (1.0.0)")
expect(exitstatus).to eq(1)
end
@@ -162,7 +162,7 @@ RSpec.describe "bundle check" do
end
G
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
lockfile <<-G
GEM
@@ -193,7 +193,7 @@ RSpec.describe "bundle check" do
end
G
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
lockfile <<-G
GEM
@@ -216,13 +216,13 @@ RSpec.describe "bundle check" do
end
it "outputs an error when the default Gemfile is not found" do
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(exitstatus).to eq(10)
expect(err).to include("Could not locate Gemfile")
end
it "does not output fatal error message" do
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(exitstatus).to eq(10)
expect(err).not_to include("Unfortunately, a fatal error has occurred. ")
end
@@ -237,11 +237,11 @@ RSpec.describe "bundle check" do
bundle "install"
FileUtils.rm(bundled_app_lock)
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(last_command).to be_failure
end
- context "--path", bundler: "< 3" do
+ context "--path", :bundler => "< 3" do
context "after installing gems in the proper directory" do
before do
gemfile <<-G
@@ -271,7 +271,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle "check --path vendor/bundle", raise_on_error: false
+ bundle "check --path vendor/bundle", :raise_on_error => false
end
it "returns false" do
@@ -298,7 +298,7 @@ RSpec.describe "bundle check" do
it "shows what is missing with the current Gemfile if it is not satisfied" do
simulate_new_machine
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(err).to match(/The following gems are missing/)
expect(err).to include("* rack (1.0")
end
@@ -326,7 +326,7 @@ RSpec.describe "bundle check" do
end
it "shows what is missing with the current Gemfile without duplications" do
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(err).to match(/The following gems are missing/)
expect(err).to include("* rack (1.0").once
end
@@ -362,7 +362,7 @@ RSpec.describe "bundle check" do
end
it "shows what is missing with the current Gemfile without duplications" do
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
expect(err).to match(/The following gems are missing/)
expect(err).to include("* rack (1.0").once
end
@@ -379,7 +379,7 @@ RSpec.describe "bundle check" do
end
it "returns success when the Gemfile is satisfied" do
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
bundle :check
expect(out).to include("The Gemfile's dependencies are satisfied")
end
@@ -404,14 +404,8 @@ RSpec.describe "bundle check" do
end
it "returns success when the Gemfile is satisfied and generates a correct lockfile" do
- system_gems "depends_on_rack-1.0", "rack-1.0", gem_repo: gem_repo4, path: default_bundle_path
+ system_gems "depends_on_rack-1.0", "rack-1.0", :gem_repo => gem_repo4, :path => default_bundle_path
bundle :check
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "depends_on_rack", "1.0"
- c.no_checksum "rack", "1.0"
- end
-
expect(out).to include("The Gemfile's dependencies are satisfied")
expect(lockfile).to eq <<~L
GEM
@@ -430,7 +424,7 @@ RSpec.describe "bundle check" do
DEPENDENCIES
depends_on_rack!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -447,7 +441,7 @@ RSpec.describe "bundle check" do
build_gem "dex-dispatch-engine"
end
- build_lib("bundle-check-issue", path: tmp.join("bundle-check-issue")) do |s|
+ build_lib("bundle-check-issue", :path => tmp.join("bundle-check-issue")) do |s|
s.write "Gemfile", <<-G
source "https://localgemserver.test"
@@ -461,20 +455,14 @@ RSpec.describe "bundle check" do
s.add_dependency "awesome_print"
end
- bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, dir: tmp.join("bundle-check-issue")
+ bundle "install", :artifice => "compact_index_extra", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, :dir => tmp.join("bundle-check-issue")
end
it "does not corrupt lockfile when changing version" do
version_file = tmp.join("bundle-check-issue/bundle-check-issue.gemspec")
File.write(version_file, File.read(version_file).gsub(/s\.version = .+/, "s.version = '9999'"))
- bundle "check --verbose", dir: tmp.join("bundle-check-issue")
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "awesome_print", "1.0"
- c.no_checksum "bundle-check-issue", "9999"
- c.checksum gem_repo2, "dex-dispatch-engine", "1.0"
- end
+ bundle "check --verbose", :dir => tmp.join("bundle-check-issue")
expect(File.read(tmp.join("bundle-check-issue/Gemfile.lock"))).to eq <<~L
PATH
@@ -499,7 +487,7 @@ RSpec.describe "bundle check" do
DEPENDENCIES
bundle-check-issue!
dex-dispatch-engine!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
index 0b559a87c8..471cd6c354 100644
--- a/spec/bundler/commands/clean_spec.rb
+++ b/spec/bundler/commands/clean_spec.rb
@@ -156,7 +156,7 @@ RSpec.describe "bundle clean" do
end
it "removes unused git gems" do
- build_git "foo", path: lib_path("foo")
+ build_git "foo", :path => lib_path("foo")
git_path = lib_path("foo")
revision = revision_for(git_path)
@@ -194,7 +194,7 @@ RSpec.describe "bundle clean" do
end
it "keeps used git gems even if installed to a symlinked location" do
- build_git "foo", path: lib_path("foo")
+ build_git "foo", :path => lib_path("foo")
git_path = lib_path("foo")
revision = revision_for(git_path)
@@ -221,7 +221,7 @@ RSpec.describe "bundle clean" do
end
it "removes old git gems" do
- build_git "foo-bar", path: lib_path("foo-bar")
+ build_git "foo-bar", :path => lib_path("foo-bar")
revision = revision_for(lib_path("foo-bar"))
gemfile <<-G
@@ -236,10 +236,10 @@ RSpec.describe "bundle clean" do
bundle "config set path vendor/bundle"
bundle "install"
- update_git "foo-bar", path: lib_path("foo-bar")
+ update_git "foo-bar", :path => lib_path("foo-bar")
revision2 = revision_for(lib_path("foo-bar"))
- bundle "update", all: true
+ bundle "update", :all => true
bundle :clean
expect(out).to include("Removing foo-bar (#{revision[0..11]})")
@@ -254,8 +254,8 @@ RSpec.describe "bundle clean" do
end
it "does not remove nested gems in a git repo" do
- build_lib "activesupport", "3.0", path: lib_path("rails/activesupport")
- build_git "rails", "3.0", path: lib_path("rails") do |s|
+ build_lib "activesupport", "3.0", :path => lib_path("rails/activesupport")
+ build_git "rails", "3.0", :path => lib_path("rails") do |s|
s.add_dependency "activesupport", "= 3.0"
end
revision = revision_for(lib_path("rails"))
@@ -274,7 +274,7 @@ RSpec.describe "bundle clean" do
end
it "does not remove git sources that are in without groups" do
- build_git "foo", path: lib_path("foo")
+ build_git "foo", :path => lib_path("foo")
git_path = lib_path("foo")
revision = revision_for(git_path)
@@ -326,7 +326,7 @@ RSpec.describe "bundle clean" do
gem "rack", "1.0.0"
G
- bundle :clean, raise_on_error: false
+ bundle :clean, :raise_on_error => false
expect(exitstatus).to eq(15)
expect(err).to include("--force")
@@ -383,7 +383,7 @@ RSpec.describe "bundle clean" do
expect(out).to include("rack (1.0.0)").and include("thin (1.0)")
end
- it "--clean should override the bundle setting on install", bundler: "< 3" do
+ it "--clean should override the bundle setting on install", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -405,7 +405,7 @@ RSpec.describe "bundle clean" do
should_not_have_gems "thin-1.0"
end
- it "--clean should override the bundle setting on update", bundler: "< 3" do
+ it "--clean should override the bundle setting on update", :bundler => "< 3" do
build_repo2
gemfile <<-G
@@ -421,13 +421,13 @@ RSpec.describe "bundle clean" do
build_gem "foo", "1.0.1"
end
- bundle "update", all: true
+ bundle "update", :all => true
should_have_gems "foo-1.0.1"
should_not_have_gems "foo-1.0"
end
- it "automatically cleans when path has not been set", bundler: "3" do
+ it "automatically cleans when path has not been set", :bundler => "3" do
build_repo2
install_gemfile <<-G
@@ -440,7 +440,7 @@ RSpec.describe "bundle clean" do
build_gem "foo", "1.0.1"
end
- bundle "update", all: true
+ bundle "update", :all => true
files = Pathname.glob(bundled_app(".bundle", Bundler.ruby_scope, "*", "*"))
files.map! {|f| f.to_s.sub(bundled_app(".bundle", Bundler.ruby_scope).to_s, "") }
@@ -486,7 +486,7 @@ RSpec.describe "bundle clean" do
build_gem "foo", "1.0.1"
end
- bundle :update, all: true
+ bundle :update, :all => true
should_have_gems "foo-1.0", "foo-1.0.1"
end
@@ -505,7 +505,7 @@ RSpec.describe "bundle clean" do
update_repo2 do
build_gem "foo", "1.0.1"
end
- bundle :update, all: true
+ bundle :update, :all => true
gem_command :list
expect(out).to include("foo (1.0.1, 1.0)")
@@ -560,7 +560,7 @@ RSpec.describe "bundle clean" do
FileUtils.chmod(0o500, system_cache_path)
- bundle :clean, force: true, raise_on_error: false
+ bundle :clean, :force => true, :raise_on_error => false
expect(err).to include(system_gem_path.to_s)
expect(err).to include("grant write permissions")
@@ -626,11 +626,15 @@ RSpec.describe "bundle clean" do
end
it "when using --force, it doesn't remove default gem binaries", :realworld do
- default_irb_version = ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", raise_on_error: false
+ skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
+
+ skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
+
+ default_irb_version = ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", :raise_on_error => false
skip "irb isn't a default gem" if default_irb_version.empty?
# simulate executable for default gem
- build_gem "irb", default_irb_version, to_system: true, default: true do |s|
+ build_gem "irb", default_irb_version, :to_system => true, :default => true do |s|
s.executables = "irb"
end
@@ -640,7 +644,7 @@ RSpec.describe "bundle clean" do
source "#{file_uri_for(gem_repo2)}"
G
- bundle "clean --force", env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+ bundle "clean --force", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
expect(out).not_to include("Removing irb")
end
@@ -901,7 +905,7 @@ RSpec.describe "bundle clean" do
bundle :lock
bundle "config set without development"
bundle "config set path vendor/bundle"
- bundle "install", verbose: true
+ bundle "install"
bundle :clean
very_simple_binary_extensions_dir =
diff --git a/spec/bundler/commands/config_spec.rb b/spec/bundler/commands/config_spec.rb
index 547fd2d869..ede93f99eb 100644
--- a/spec/bundler/commands/config_spec.rb
+++ b/spec/bundler/commands/config_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe ".bundle/config" do
context "with env overwrite" do
it "prints config with env" do
- bundle "config list --parseable", env: { "BUNDLE_FOO" => "bar3" }
+ bundle "config list --parseable", :env => { "BUNDLE_FOO" => "bar3" }
expect(out).to include("foo=bar3")
end
end
@@ -64,11 +64,11 @@ RSpec.describe ".bundle/config" do
ENV["BUNDLE_APP_CONFIG"] = "../foo"
bundle "config set --local path vendor/bundle"
- bundle "install", dir: bundled_app("omg")
+ bundle "install", :dir => bundled_app("omg")
expect(bundled_app(".bundle")).not_to exist
expect(bundled_app("../foo/config")).to exist
- expect(the_bundle).to include_gems "rack 1.0.0", dir: bundled_app("omg")
+ expect(the_bundle).to include_gems "rack 1.0.0", :dir => bundled_app("omg")
end
end
@@ -96,8 +96,8 @@ RSpec.describe ".bundle/config" do
end
it "can be configured through BUNDLE_USER_CONFIG" do
- bundle "config set path vendor", env: { "BUNDLE_USER_CONFIG" => bundle_user_config }
- bundle "config get path", env: { "BUNDLE_USER_CONFIG" => bundle_user_config }
+ bundle "config set path vendor", :env => { "BUNDLE_USER_CONFIG" => bundle_user_config }
+ bundle "config get path", :env => { "BUNDLE_USER_CONFIG" => bundle_user_config }
expect(out).to include("Set for the current user (#{bundle_user_config}): \"vendor\"")
end
@@ -105,8 +105,8 @@ RSpec.describe ".bundle/config" do
let(:bundle_user_home) { bundled_app(".bundle").to_s }
it "uses the right location" do
- bundle "config set path vendor", env: { "BUNDLE_USER_HOME" => bundle_user_home }
- bundle "config get path", env: { "BUNDLE_USER_HOME" => bundle_user_home }
+ bundle "config set path vendor", :env => { "BUNDLE_USER_HOME" => bundle_user_home }
+ bundle "config get path", :env => { "BUNDLE_USER_HOME" => bundle_user_home }
expect(out).to include("Set for the current user (#{bundle_user_home}/config): \"vendor\"")
end
end
@@ -443,7 +443,7 @@ E
expect(err).to be_empty
ruby(<<~RUBY)
- require "bundler"
+ require "#{entrypoint}"
print Bundler.settings.mirror_for("https://rails-assets.org")
RUBY
expect(out).to eq("https://rails-assets.org/")
@@ -451,7 +451,7 @@ E
bundle "config set mirror.all http://localhost:9293"
ruby(<<~RUBY)
- require "bundler"
+ require "#{entrypoint}"
print Bundler.settings.mirror_for("https://rails-assets.org")
RUBY
expect(out).to eq("http://localhost:9293/")
@@ -461,26 +461,26 @@ E
describe "subcommands" do
it "list" do
- bundle "config list", env: { "BUNDLE_FOO" => "bar" }
+ bundle "config list", :env => { "BUNDLE_FOO" => "bar" }
expect(out).to eq "Settings are listed in order of priority. The top value will be used.\nfoo\nSet via BUNDLE_FOO: \"bar\""
- bundle "config list", env: { "BUNDLE_FOO" => "bar" }, parseable: true
+ bundle "config list", :env => { "BUNDLE_FOO" => "bar" }, :parseable => true
expect(out).to eq "foo=bar"
end
it "list with credentials" do
- bundle "config list", env: { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
+ bundle "config list", :env => { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"user:[REDACTED]\""
- bundle "config list", parseable: true, env: { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
+ bundle "config list", :parseable => true, :env => { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
expect(out).to eq "gems.myserver.com=user:password"
end
it "list with API token credentials" do
- bundle "config list", env: { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
+ bundle "config list", :env => { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"[REDACTED]:x-oauth-basic\""
- bundle "config list", parseable: true, env: { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
+ bundle "config list", :parseable => true, :env => { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
expect(out).to eq "gems.myserver.com=api_token:x-oauth-basic"
end
@@ -515,7 +515,7 @@ E
bundle "config set --local foo 4.1"
expect(out).to eq "You are replacing the current local value of foo, which is currently \"4\""
- bundle "config set --global --local foo 5", raise_on_error: false
+ bundle "config set --global --local foo 5", :raise_on_error => false
expect(last_command).to be_failure
expect(err).to eq "The options global and local were specified. Please only use one of the switches at a time."
end
@@ -555,7 +555,7 @@ E
expect(out).to eq ""
expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nYou have not configured a value for `foo`"
- bundle "config unset foo --local --global", raise_on_error: false
+ bundle "config unset foo --local --global", :raise_on_error => false
expect(last_command).to be_failure
expect(err).to eq "The options global and local were specified. Please only use one of the switches at a time."
end
diff --git a/spec/bundler/commands/console_spec.rb b/spec/bundler/commands/console_spec.rb
index a41432b88a..aa76096e3d 100644
--- a/spec/bundler/commands/console_spec.rb
+++ b/spec/bundler/commands/console_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle console", bundler: "< 3", readline: true do
+RSpec.describe "bundle console", :bundler => "< 3", :readline => true do
before :each do
build_repo2 do
# A minimal fake pry console
diff --git a/spec/bundler/commands/doctor_spec.rb b/spec/bundler/commands/doctor_spec.rb
index 666b23a141..1afac00923 100644
--- a/spec/bundler/commands/doctor_spec.rb
+++ b/spec/bundler/commands/doctor_spec.rb
@@ -38,11 +38,6 @@ RSpec.describe "bundle doctor" do
allow(stat).to receive(:uid) { Process.uid }
allow(File).to receive(:writable?).with(unwritable_file) { true }
allow(File).to receive(:readable?).with(unwritable_file) { true }
-
- # The following lines are for `Gem::PathSupport#initialize`.
- allow(File).to receive(:exist?).with(Gem.default_dir)
- allow(File).to receive(:writable?).with(Gem.default_dir)
- allow(File).to receive(:writable?).with(File.expand_path("..", Gem.default_dir))
end
it "exits with no message if the installed gem has no C extensions" do
@@ -64,7 +59,7 @@ RSpec.describe "bundle doctor" do
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"]
allow(Fiddle).to receive(:dlopen).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_raise(Fiddle::DLError)
- expect { doctor.run }.to raise_error(Bundler::ProductionError, <<~E.strip), @stdout.string
+ expect { doctor.run }.to raise_error(Bundler::ProductionError, strip_whitespace(<<-E).strip), @stdout.string
The following gems are missing OS dependencies:
* bundler: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
* rack: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb
index 9f5f12739a..099cdb39fa 100644
--- a/spec/bundler/commands/exec_spec.rb
+++ b/spec/bundler/commands/exec_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe "bundle exec" do
let(:system_gems_to_install) { %w[rack-1.0.0 rack-0.9.1] }
it "works with --gemfile flag" do
- system_gems(system_gems_to_install, path: default_bundle_path)
+ system_gems(system_gems_to_install, :path => default_bundle_path)
create_file "CustomGemfile", <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -16,7 +16,7 @@ RSpec.describe "bundle exec" do
end
it "activates the correct gem" do
- system_gems(system_gems_to_install, path: default_bundle_path)
+ system_gems(system_gems_to_install, :path => default_bundle_path)
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -28,14 +28,14 @@ RSpec.describe "bundle exec" do
end
it "works and prints no warnings when HOME is not writable" do
- system_gems(system_gems_to_install, path: default_bundle_path)
+ system_gems(system_gems_to_install, :path => default_bundle_path)
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
G
- bundle "exec rackup", env: { "HOME" => "/" }
+ bundle "exec rackup", :env => { "HOME" => "/" }
expect(out).to eq("0.9.1")
expect(err).to be_empty
end
@@ -108,7 +108,7 @@ RSpec.describe "bundle exec" do
2.1.4
L
- bundle "exec bundle cache", env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle "exec bundle cache", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(out).to include("Updating files in vendor/cache")
end
@@ -198,7 +198,7 @@ RSpec.describe "bundle exec" do
gem "rack", "0.9.1"
G
- install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2
+ install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
source "#{file_uri_for(gem_repo2)}"
gem "rack_two", "1.0.0"
G
@@ -207,12 +207,12 @@ RSpec.describe "bundle exec" do
expect(out).to eq("0.9.1")
- bundle "exec rackup", dir: bundled_app2
+ bundle "exec rackup", :dir => bundled_app2
expect(out).to eq("1.0.0")
end
context "with default gems" do
- let(:default_irb_version) { ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", raise_on_error: false }
+ let(:default_irb_version) { ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", :raise_on_error => false }
context "when not specified in Gemfile" do
before do
@@ -299,7 +299,7 @@ RSpec.describe "bundle exec" do
gem "rack", "0.9.1"
G
- install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2
+ install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
source "#{file_uri_for(gem_repo2)}"
gem "rack_two", "1.0.0"
G
@@ -344,7 +344,7 @@ RSpec.describe "bundle exec" do
bundle "exec 'echo $RUBYOPT'"
expect(out.split(" ").count(bundler_setup_opt)).to eq(1)
- bundle "exec 'echo $RUBYOPT'", env: { "RUBYOPT" => rubyopt }
+ bundle "exec 'echo $RUBYOPT'", :env => { "RUBYOPT" => rubyopt }
expect(out.split(" ").count(bundler_setup_opt)).to eq(1)
end
@@ -363,7 +363,7 @@ RSpec.describe "bundle exec" do
bundle "exec 'echo $RUBYLIB'"
expect(out).to include(rubylib)
- bundle "exec 'echo $RUBYLIB'", env: { "RUBYLIB" => rubylib }
+ bundle "exec 'echo $RUBYLIB'", :env => { "RUBYLIB" => rubylib }
expect(out).to include(rubylib)
end
@@ -373,7 +373,7 @@ RSpec.describe "bundle exec" do
gem "rack"
G
- bundle "exec foobarbaz", raise_on_error: false
+ bundle "exec foobarbaz", :raise_on_error => false
expect(exitstatus).to eq(127)
expect(err).to include("bundler: command not found: foobarbaz")
expect(err).to include("Install missing gem executables with `bundle install`")
@@ -386,7 +386,7 @@ RSpec.describe "bundle exec" do
G
bundle "exec touch foo"
- bundle "exec ./foo", raise_on_error: false
+ bundle "exec ./foo", :raise_on_error => false
expect(exitstatus).to eq(126)
expect(err).to include("bundler: not executable: ./foo")
end
@@ -397,13 +397,13 @@ RSpec.describe "bundle exec" do
gem "rack"
G
- bundle "exec", raise_on_error: false
+ bundle "exec", :raise_on_error => false
expect(exitstatus).to eq(128)
expect(err).to include("bundler: exec needs a command to run")
end
it "raises a helpful error when exec'ing to something outside of the bundle" do
- system_gems(system_gems_to_install, path: default_bundle_path)
+ system_gems(system_gems_to_install, :path => default_bundle_path)
bundle "config set clean false" # want to keep the rackup binstub
install_gemfile <<-G
@@ -412,7 +412,7 @@ RSpec.describe "bundle exec" do
G
[true, false].each do |l|
bundle "config set disable_exec_load #{l}"
- bundle "exec rackup", raise_on_error: false
+ bundle "exec rackup", :raise_on_error => false
expect(err).to include "can't find executable rackup for gem rack. rack is not currently included in the bundle, perhaps you meant to add it to your Gemfile?"
end
end
@@ -531,7 +531,7 @@ RSpec.describe "bundle exec" do
describe "from gems bundled via :path" do
before(:each) do
- build_lib "fizz", path: home("fizz") do |s|
+ build_lib "fizz", :path => home("fizz") do |s|
s.executables = "fizz"
end
@@ -580,7 +580,7 @@ RSpec.describe "bundle exec" do
describe "from gems bundled via :git with no gemspec" do
before(:each) do
- build_git "fizz_no_gemspec", gemspec: false do |s|
+ build_git "fizz_no_gemspec", :gemspec => false do |s|
s.executables = "fizz_no_gemspec"
end
@@ -615,25 +615,8 @@ RSpec.describe "bundle exec" do
expect(out).to include("Installing foo 1.0")
end
- it "performs an automatic bundle install with git gems" do
- build_git "foo" do |s|
- s.executables = "foo"
- end
- gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "rack", "0.9.1"
- gem "foo", :git => "#{lib_path("foo-1.0")}"
- G
-
- bundle "config set auto_install 1"
- bundle "exec foo"
- expect(out).to include("Fetching rack 0.9.1")
- expect(out).to include("Fetching #{lib_path("foo-1.0")}")
- expect(out.lines).to end_with("1.0")
- end
-
it "loads the correct optparse when `auto_install` is set, and optparse is a dependency" do
- if Gem.rubygems_version < Gem::Version.new("3.3.0.a")
+ if Gem.ruby_version >= Gem::Version.new("3.0.0") && Gem.rubygems_version < Gem::Version.new("3.3.0.a")
skip "optparse is a default gem, and rubygems loads it during install"
end
@@ -647,7 +630,7 @@ RSpec.describe "bundle exec" do
build_gem "optparse", "999.999.999"
end
- system_gems "optparse-999.999.998", gem_repo: gem_repo4
+ system_gems "optparse-999.999.998", :gem_repo => gem_repo4
bundle "config set auto_install 1"
bundle "config set --local path vendor/bundle"
@@ -683,7 +666,7 @@ RSpec.describe "bundle exec" do
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
- bundle "exec irb", raise_on_error: false
+ bundle "exec irb", :raise_on_error => false
expect(err).to match("The gemspec at #{lib_path("foo-1.0").join("foo.gemspec")} is not valid")
expect(err).to match('"TODO" is not a summary')
@@ -706,7 +689,7 @@ RSpec.describe "bundle exec" do
G
bundle "config set path.system true"
bundle "install"
- bundle "exec ruby -e '`bundle -v`; puts $?.success?'", env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle "exec ruby -e '`bundle -v`; puts $?.success?'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(out).to match("true")
end
end
@@ -714,7 +697,7 @@ RSpec.describe "bundle exec" do
context "`load`ing a ruby file instead of `exec`ing" do
let(:path) { bundled_app("ruby_executable") }
let(:shebang) { "#!/usr/bin/env ruby" }
- let(:executable) { <<~RUBY.strip }
+ let(:executable) { <<-RUBY.gsub(/^ */, "").strip }
#{shebang}
require "rack"
@@ -726,7 +709,7 @@ RSpec.describe "bundle exec" do
RUBY
before do
- system_gems(system_gems_to_install, path: default_bundle_path)
+ system_gems(system_gems_to_install, :path => default_bundle_path)
bundled_app(path).open("w") {|f| f << executable }
bundled_app(path).chmod(0o755)
@@ -749,7 +732,7 @@ RSpec.describe "bundle exec" do
let(:expected) { [exec, args, rack, process].join("\n") }
let(:expected_err) { "" }
- subject { bundle "exec #{path} arg1 arg2", raise_on_error: false }
+ subject { bundle "exec #{path} arg1 arg2", :raise_on_error => false }
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
@@ -831,7 +814,8 @@ RSpec.describe "bundle exec" do
let(:executable) { super() << "\nraise 'ERROR'" }
let(:exit_code) { 1 }
let(:expected_err) do
- /\Abundler: failed to load command: #{Regexp.quote(path.to_s)} \(#{Regexp.quote(path.to_s)}\)\n#{Regexp.quote(path.to_s)}:10:in [`']<top \(required\)>': ERROR \(RuntimeError\)/
+ "bundler: failed to load command: #{path} (#{path})" \
+ "\n#{path}:10:in `<top (required)>': ERROR (RuntimeError)"
end
it "runs like a normally executed executable" do
@@ -839,7 +823,7 @@ RSpec.describe "bundle exec" do
subject
expect(exitstatus).to eq(exit_code)
- expect(err).to match(expected_err)
+ expect(err).to start_with(expected_err)
expect(out).to eq(expected)
end
end
@@ -873,7 +857,7 @@ RSpec.describe "bundle exec" do
end
end
- context "when Bundler.setup fails", bundler: "< 3" do
+ context "when Bundler.setup fails", :bundler => "< 3" do
before do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -903,7 +887,7 @@ Run `bundle install` to install missing gems.
end
end
- context "when Bundler.setup fails", bundler: "3" do
+ context "when Bundler.setup fails", :bundler => "3" do
before do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1040,7 +1024,7 @@ __FILE__: #{path.to_s.inspect}
end
context "signals being trapped by bundler" do
- let(:executable) { <<~RUBY }
+ let(:executable) { strip_whitespace <<-RUBY }
#{shebang}
begin
Thread.new do
@@ -1067,7 +1051,7 @@ __FILE__: #{path.to_s.inspect}
end
context "signals not being trapped by bunder" do
- let(:executable) { <<~RUBY }
+ let(:executable) { strip_whitespace <<-RUBY }
#{shebang}
signals = #{test_signals.inspect}
@@ -1112,7 +1096,7 @@ __FILE__: #{path.to_s.inspect}
puts `bundle exec echo foo`
RUBY
file.chmod(0o777)
- bundle "exec #{file}", env: { "PATH" => path }
+ bundle "exec #{file}", :env => { "PATH" => path }
expect(out).to eq("foo")
end
end
@@ -1205,7 +1189,7 @@ __FILE__: #{path.to_s.inspect}
context "with a system gem that shadows a default gem" do
let(:openssl_version) { "99.9.9" }
- let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", artifice: nil, raise_on_error: false }
+ let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", :artifice => nil, :raise_on_error => false }
it "only leaves the default gem in the stdlib available" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
@@ -1221,7 +1205,7 @@ __FILE__: #{path.to_s.inspect}
end
end
- system_gems("openssl-#{openssl_version}", gem_repo: gem_repo4)
+ system_gems("openssl-#{openssl_version}", :gem_repo => gem_repo4)
file = bundled_app("require_openssl.rb")
create_file(file, <<-RUBY)
@@ -1234,15 +1218,15 @@ __FILE__: #{path.to_s.inspect}
env = { "PATH" => path }
aggregate_failures do
- expect(bundle("exec #{file}", artifice: nil, env: env)).to eq(expected)
- expect(bundle("exec bundle exec #{file}", artifice: nil, env: env)).to eq(expected)
- expect(bundle("exec ruby #{file}", artifice: nil, env: env)).to eq(expected)
- expect(run(file.read, artifice: nil, env: env)).to eq(expected)
+ expect(bundle("exec #{file}", :artifice => nil, :env => env)).to eq(expected)
+ expect(bundle("exec bundle exec #{file}", :artifice => nil, :env => env)).to eq(expected)
+ expect(bundle("exec ruby #{file}", :artifice => nil, :env => env)).to eq(expected)
+ expect(run(file.read, :artifice => nil, :env => env)).to eq(expected)
end
skip "ruby_core has openssl and rubygems in the same folder, and this test needs rubygems require but default openssl not in a directly added entry in $LOAD_PATH" if ruby_core?
# sanity check that we get the newer, custom version without bundler
- sys_exec "#{Gem.ruby} #{file}", env: env, raise_on_error: false
+ sys_exec "#{Gem.ruby} #{file}", :env => env, :raise_on_error => false
expect(err).to include("custom openssl should not be loaded")
end
end
diff --git a/spec/bundler/commands/help_spec.rb b/spec/bundler/commands/help_spec.rb
index 0c7031e813..409c49f9e1 100644
--- a/spec/bundler/commands/help_spec.rb
+++ b/spec/bundler/commands/help_spec.rb
@@ -15,13 +15,6 @@ RSpec.describe "bundle help" do
expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
- it "prexifes bundle commands with bundle- and resolves aliases when finding the man files" do
- with_fake_man do
- bundle "help package"
- end
- expect(out).to eq(%(["#{man_dir}/bundle-cache.1"]))
- end
-
it "simply outputs the human readable file when there is no man on the path" do
with_path_as("") do
bundle "help install"
@@ -78,7 +71,7 @@ RSpec.describe "bundle help" do
it "has helpful output when using --help flag for a non-existent command" do
with_fake_man do
- bundle "instill -h", raise_on_error: false
+ bundle "instill -h", :raise_on_error => false
end
expect(err).to include('Could not find command "instill".')
end
diff --git a/spec/bundler/commands/info_spec.rb b/spec/bundler/commands/info_spec.rb
index a5a09bc147..851f50240f 100644
--- a/spec/bundler/commands/info_spec.rb
+++ b/spec/bundler/commands/info_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe "bundle info" do
end
it "complains if gem not in bundle" do
- bundle "info missing", raise_on_error: false
+ bundle "info missing", :raise_on_error => false
expect(err).to eq("Could not find gem 'missing'.")
end
@@ -74,16 +74,16 @@ RSpec.describe "bundle info" do
bundle "info rails --path"
- expect(err).to include("The gem rails has been deleted.")
- expect(err).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to match(/The gem rails has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
bundle "info rail --path"
- expect(err).to include("The gem rails has been deleted.")
- expect(err).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to match(/The gem rails has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
bundle "info rails"
- expect(err).to include("The gem rails has been deleted.")
- expect(err).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to match(/The gem rails has been deleted/i)
+ expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
end
context "given a default gem shippped in ruby", :ruby_repo do
@@ -167,7 +167,7 @@ RSpec.describe "bundle info" do
end
it "prints out branch names other than main" do
- update_git "foo", branch: "omg" do |s|
+ update_git "foo", :branch => "omg" do |s|
s.write "lib/foo.rb", "FOO = '1.0.omg'"
end
@revision = revision_for(lib_path("foo-1.0"))[0...6]
@@ -194,7 +194,7 @@ RSpec.describe "bundle info" do
end
it "handles when a version is a '-' prerelease" do
- @git = build_git("foo", "1.0.0-beta.1", path: lib_path("foo"))
+ @git = build_git("foo", "1.0.0-beta.1", :path => lib_path("foo"))
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}"
@@ -228,7 +228,7 @@ RSpec.describe "bundle info" do
invalid_regexp = "[]"
- bundle "info #{invalid_regexp}", raise_on_error: false
+ bundle "info #{invalid_regexp}", :raise_on_error => false
expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
@@ -242,7 +242,7 @@ RSpec.describe "bundle info" do
gem "rails", group: :test
G
- bundle "info rails", raise_on_error: false
+ bundle "info rails", :raise_on_error => false
expect(err).to include("Could not find gem 'rails', because it's in the group 'test', configured to be ignored.")
end
end
diff --git a/spec/bundler/commands/init_spec.rb b/spec/bundler/commands/init_spec.rb
index 0a1336572a..6aa3e9edd1 100644
--- a/spec/bundler/commands/init_spec.rb
+++ b/spec/bundler/commands/init_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe "bundle init" do
it "honours the current process umask when generating from a template" do
FileUtils.mkdir(target_dir)
- bundle :init, dir: target_dir
+ bundle :init, :dir => target_dir
generated_mode = File.stat(File.join(target_dir, "Gemfile")).mode & 0o111
expect(generated_mode).to be_zero
end
@@ -38,11 +38,11 @@ RSpec.describe "bundle init" do
end
it "does not change existing Gemfiles" do
- expect { bundle :init, raise_on_error: false }.not_to change { File.read(bundled_app_gemfile) }
+ expect { bundle :init, :raise_on_error => false }.not_to change { File.read(bundled_app_gemfile) }
end
it "notifies the user that an existing Gemfile already exists" do
- bundle :init, raise_on_error: false
+ bundle :init, :raise_on_error => false
expect(err).to include("Gemfile already exists")
end
end
@@ -55,7 +55,7 @@ RSpec.describe "bundle init" do
FileUtils.mkdir bundled_app(subdir)
- bundle :init, dir: bundled_app(subdir)
+ bundle :init, :dir => bundled_app(subdir)
expect(out).to include("Writing new Gemfile")
expect(bundled_app("#{subdir}/Gemfile")).to be_file
@@ -71,7 +71,7 @@ RSpec.describe "bundle init" do
mode = File.stat(bundled_app(subdir)).mode ^ 0o222
FileUtils.chmod mode, bundled_app(subdir)
- bundle :init, dir: bundled_app(subdir), raise_on_error: false
+ bundle :init, :dir => bundled_app(subdir), :raise_on_error => false
expect(err).to include("directory is not writable")
expect(Dir[bundled_app("#{subdir}/*")]).to be_empty
@@ -92,7 +92,7 @@ RSpec.describe "bundle init" do
S
end
- bundle :init, gemspec: spec_file
+ bundle :init, :gemspec => spec_file
gemfile = bundled_app_gemfile.read
expect(gemfile).to match(%r{source 'https://rubygems.org'})
@@ -112,7 +112,7 @@ RSpec.describe "bundle init" do
S
end
- bundle :init, gemspec: spec_file, raise_on_error: false
+ bundle :init, :gemspec => spec_file, :raise_on_error => false
expect(err).to include("There was an error while loading `test.gemspec`")
end
end
@@ -135,11 +135,11 @@ RSpec.describe "bundle init" do
end
it "does not change existing Gemfiles" do
- expect { bundle :init, raise_on_error: false }.not_to change { File.read(bundled_app("gems.rb")) }
+ expect { bundle :init, :raise_on_error => false }.not_to change { File.read(bundled_app("gems.rb")) }
end
it "notifies the user that an existing gems.rb already exists" do
- bundle :init, raise_on_error: false
+ bundle :init, :raise_on_error => false
expect(err).to include("gems.rb already exists")
end
end
@@ -152,7 +152,7 @@ RSpec.describe "bundle init" do
FileUtils.mkdir bundled_app(subdir)
- bundle :init, dir: bundled_app(subdir)
+ bundle :init, :dir => bundled_app(subdir)
expect(out).to include("Writing new gems.rb")
expect(bundled_app("#{subdir}/gems.rb")).to be_file
@@ -175,7 +175,7 @@ RSpec.describe "bundle init" do
end
it "should generate from an existing gemspec" do
- bundle :init, gemspec: spec_file
+ bundle :init, :gemspec => spec_file
gemfile = bundled_app("gems.rb").read
expect(gemfile).to match(%r{source 'https://rubygems.org'})
@@ -185,7 +185,7 @@ RSpec.describe "bundle init" do
end
it "prints message to user" do
- bundle :init, gemspec: spec_file
+ bundle :init, :gemspec => spec_file
expect(out).to include("Writing new gems.rb")
end
@@ -196,7 +196,7 @@ RSpec.describe "bundle init" do
it "should use the --gemfile value to name the gemfile" do
custom_gemfile_name = "NiceGemfileName"
- bundle :init, gemfile: custom_gemfile_name
+ bundle :init, :gemfile => custom_gemfile_name
expect(out).to include("Writing new #{custom_gemfile_name}")
used_template = File.read("#{source_root}/lib/bundler/templates/Gemfile")
diff --git a/spec/bundler/commands/inject_spec.rb b/spec/bundler/commands/inject_spec.rb
index 255a03c135..d711fe010d 100644
--- a/spec/bundler/commands/inject_spec.rb
+++ b/spec/bundler/commands/inject_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle inject", bundler: "< 3" do
+RSpec.describe "bundle inject", :bundler => "< 3" do
before :each do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -36,14 +36,14 @@ RSpec.describe "bundle inject", bundler: "< 3" do
context "with injected gems already in the Gemfile" do
it "doesn't add existing gems" do
- bundle "inject 'rack' '> 0'", raise_on_error: false
+ bundle "inject 'rack' '> 0'", :raise_on_error => false
expect(err).to match(/cannot specify the same gem twice/i)
end
end
context "incorrect arguments" do
it "fails when more than 2 arguments are passed" do
- bundle "inject gem_name 1 v", raise_on_error: false
+ bundle "inject gem_name 1 v", :raise_on_error => false
expect(err).to eq(<<-E.strip)
ERROR: "bundle inject" was called with arguments ["gem_name", "1", "v"]
Usage: "bundle inject GEM VERSION"
@@ -108,7 +108,7 @@ Usage: "bundle inject GEM VERSION"
source "#{file_uri_for(gem_repo1)}"
gem "rack-obama"
G
- bundle "inject 'rack' '> 0'", raise_on_error: false
+ bundle "inject 'rack' '> 0'", :raise_on_error => false
expect(err).to match(/the lockfile can't be updated because frozen mode is set/)
expect(bundled_app_lock.read).not_to match(/rack-obama/)
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index edc5887d7b..f572bdf176 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not make a lockfile if the install fails" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
raise StandardError, "FAIL"
G
@@ -29,7 +29,7 @@ RSpec.describe "bundle install with gem sources" do
expect(bundled_app_lock).to exist
end
- it "does not create ./.bundle by default", bundler: "< 3" do
+ it "does not create ./.bundle by default", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -45,7 +45,7 @@ RSpec.describe "bundle install with gem sources" do
gem "rack"
G
- bundle :install, env: { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry
+ bundle :install, :env => { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry
expect(bundled_app(".bundle")).not_to exist
end
@@ -68,7 +68,7 @@ RSpec.describe "bundle install with gem sources" do
lockfile = File.read(bundled_app_lock)
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
raise StandardError, "FAIL"
G
@@ -130,7 +130,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "raises an appropriate error when gems are specified using symbols" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem :rack
G
@@ -197,7 +197,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not reinstall any gem that is already available locally" do
- system_gems "activesupport-2.3.2", path: default_bundle_path
+ system_gems "activesupport-2.3.2", :path => default_bundle_path
build_repo2 do
build_gem "activesupport", "2.3.2" do |s|
@@ -214,7 +214,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "works when the gemfile specifies gems that only exist in the system" do
- build_gem "foo", to_bundle: true
+ build_gem "foo", :to_bundle => true
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -225,7 +225,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "prioritizes local gems over remote gems" do
- build_gem "rack", "1.0.0", to_bundle: true do |s|
+ build_gem "rack", "1.0.0", :to_bundle => true do |s|
s.add_dependency "activesupport", "2.3.5"
end
@@ -241,7 +241,7 @@ RSpec.describe "bundle install with gem sources" do
plugin_msg = "hello from an env plugin!"
create_file "plugins/rubygems_plugin.rb", "puts '#{plugin_msg}'"
rubylib = ENV["RUBYLIB"].to_s.split(File::PATH_SEPARATOR).unshift(bundled_app("plugins").to_s).join(File::PATH_SEPARATOR)
- install_gemfile <<-G, env: { "RUBYLIB" => rubylib }
+ install_gemfile <<-G, :env => { "RUBYLIB" => rubylib }
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -311,14 +311,14 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "rack 1.0"
end
- it "allows running bundle install --system without deleting foo", bundler: "< 3" do
+ it "allows running bundle install --system without deleting foo", :bundler => "< 3" do
bundle "install --path vendor"
bundle "install --system"
FileUtils.rm_rf(bundled_app("vendor"))
expect(the_bundle).to include_gems "rack 1.0"
end
- it "allows running bundle install --system after deleting foo", bundler: "< 3" do
+ it "allows running bundle install --system after deleting foo", :bundler => "< 3" do
bundle "install --path vendor"
FileUtils.rm_rf(bundled_app("vendor"))
bundle "install --system"
@@ -326,7 +326,7 @@ RSpec.describe "bundle install with gem sources" do
end
end
- it "finds gems in multiple sources", bundler: "< 3" do
+ it "finds gems in multiple sources", :bundler => "< 3" do
build_repo2 do
build_gem "rack", "1.2" do |s|
s.executables = "rackup"
@@ -345,7 +345,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "gives a useful error if no sources are set" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
gem "rack"
G
@@ -408,7 +408,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not throw a warning if a gem is added once in Gemfile and also inside a gemspec as a development dependency" do
- build_lib "my-gem", path: bundled_app do |s|
+ build_lib "my-gem", :path => bundled_app do |s|
s.add_development_dependency "my-private-gem"
end
@@ -430,155 +430,8 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems("my-private-gem 1.0")
end
- it "throws a warning if a gem is added once in Gemfile and also inside a gemspec as a development dependency, with different requirements" do
- build_lib "my-gem", path: bundled_app do |s|
- s.add_development_dependency "rubocop", "~> 1.36.0"
- end
-
- build_repo4 do
- build_gem "rubocop", "1.36.0"
- build_gem "rubocop", "1.37.1"
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gemspec
-
- gem "rubocop", group: :development
- G
-
- bundle :install
-
- expect(err).to include("A gemspec development dependency (rubocop, ~> 1.36.0) is being overridden by a Gemfile dependency (rubocop, >= 0).")
- expect(err).to include("This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement")
-
- # This is not the best behavior I believe, it would be better if both
- # requirements are considered if they are compatible, and a version
- # satisfying both is chosen. But not sure about changing it right now, so
- # I went with a warning for the time being.
- expect(the_bundle).to include_gems("rubocop 1.37.1")
- end
-
- it "includes the gem without warning if two gemspecs add it with the same requirement" do
- gem1 = tmp.join("my-gem-1")
- gem2 = tmp.join("my-gem-2")
-
- build_lib "my-gem", path: gem1 do |s|
- s.add_development_dependency "rubocop", "~> 1.36.0"
- end
-
- build_lib "my-gem-2", path: gem2 do |s|
- s.add_development_dependency "rubocop", "~> 1.36.0"
- end
-
- build_repo4 do
- build_gem "rubocop", "1.36.0"
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gemspec path: "#{gem1}"
- gemspec path: "#{gem2}"
- G
-
- bundle :install
-
- expect(err).to be_empty
- expect(the_bundle).to include_gems("rubocop 1.36.0")
- end
-
- it "warns when a Gemfile dependency is overriding a gemspec development dependency, with different requirements" do
- build_lib "my-gem", path: bundled_app do |s|
- s.add_development_dependency "rails", ">= 5"
- end
-
- build_repo4 do
- build_gem "rails", "7.0.8"
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "rails", "~> 7.0.8"
-
- gemspec
- G
-
- bundle :install
-
- expect(err).to include("A gemspec development dependency (rails, >= 5) is being overridden by a Gemfile dependency (rails, ~> 7.0.8).")
- expect(err).to include("This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement")
-
- # This is not the best behavior I believe, it would be better if both
- # requirements are considered if they are compatible, and a version
- # satisfying both is chosen. But not sure about changing it right now, so
- # I went with a warning for the time being.
- expect(the_bundle).to include_gems("rails 7.0.8")
- end
-
- it "does not warn if a gem is added once in Gemfile and also inside a gemspec as a development dependency, with same requirements, and different sources" do
- build_lib "my-gem", path: bundled_app do |s|
- s.add_development_dependency "activesupport"
- end
-
- build_repo4 do
- build_gem "activesupport"
- end
-
- build_git "activesupport", "1.0", path: lib_path("activesupport")
-
- install_gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gemspec
-
- gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}"
- G
-
- expect(err).to be_empty
- expect(the_bundle).to include_gems "activesupport 1.0", source: "git@#{lib_path("activesupport")}"
-
- # if the Gemfile dependency is specified first
- install_gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}"
-
- gemspec
- G
-
- expect(err).to be_empty
- expect(the_bundle).to include_gems "activesupport 1.0", source: "git@#{lib_path("activesupport")}"
- end
-
- it "considers both dependencies for resolution if a gem is added once in Gemfile and also inside a local gemspec as a runtime dependency, with different requirements" do
- build_lib "my-gem", path: bundled_app do |s|
- s.add_dependency "rubocop", "~> 1.36.0"
- end
-
- build_repo4 do
- build_gem "rubocop", "1.36.0"
- build_gem "rubocop", "1.37.1"
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gemspec
-
- gem "rubocop"
- G
-
- bundle :install
-
- expect(err).to be_empty
- expect(the_bundle).to include_gems("rubocop 1.36.0")
- end
-
it "throws an error if a gem is added twice in Gemfile when version of one dependency is not specified" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "rack", "1.0"
@@ -589,7 +442,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "throws an error if a gem is added twice in Gemfile when different versions of both dependencies are specified" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rack", "1.0"
gem "rack", "1.1"
@@ -602,7 +455,7 @@ RSpec.describe "bundle install with gem sources" do
it "gracefully handles error when rubygems server is unavailable" do
skip "networking issue" if Gem.win_platform?
- install_gemfile <<-G, artifice: nil, raise_on_error: false
+ install_gemfile <<-G, :artifice => nil, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
source "http://0.0.0.0:9384" do
gem 'foo'
@@ -614,8 +467,8 @@ RSpec.describe "bundle install with gem sources" do
end
it "fails gracefully when downloading an invalid specification from the full index" do
- build_repo2(build_compact_index: false) do
- build_gem "ajp-rails", "0.0.0", gemspec: false, skip_validation: true do |s|
+ build_repo2 do
+ build_gem "ajp-rails", "0.0.0", :gemspec => false, :skip_validation => true do |s|
bad_deps = [["ruby-ajp", ">= 0.2.0"], ["rails", ">= 0.14"]]
s.
instance_variable_get(:@spec).
@@ -626,7 +479,7 @@ RSpec.describe "bundle install with gem sources" do
build_gem "ruby-ajp", "1.0.0"
end
- install_gemfile <<-G, full_index: true, raise_on_error: false
+ install_gemfile <<-G, :full_index => true, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "ajp-rails", "0.0.0"
@@ -661,9 +514,11 @@ RSpec.describe "bundle install with gem sources" do
end
describe "Ruby version in Gemfile.lock" do
+ include Bundler::GemHelpers
+
context "and using an unsupported Ruby version" do
it "prints an error" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
ruby '~> 1.2'
source "#{file_uri_for(gem_repo1)}"
G
@@ -680,7 +535,6 @@ RSpec.describe "bundle install with gem sources" do
end
it "writes current Ruby version to Gemfile.lock" do
- checksums = checksums_section_when_existing
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -690,7 +544,7 @@ RSpec.describe "bundle install with gem sources" do
#{lockfile_platforms}
DEPENDENCIES
- #{checksums}
+
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -705,8 +559,6 @@ RSpec.describe "bundle install with gem sources" do
source "#{file_uri_for(gem_repo1)}"
G
- checksums = checksums_section_when_existing
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -716,7 +568,7 @@ RSpec.describe "bundle install with gem sources" do
#{lockfile_platforms}
DEPENDENCIES
- #{checksums}
+
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -753,7 +605,7 @@ RSpec.describe "bundle install with gem sources" do
file.puts gemfile
end
- bundle :install, dir: root_dir
+ bundle :install, :dir => root_dir
end
it "doesn't blow up when using the `gemspec` DSL" do
@@ -761,7 +613,7 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.mkdir_p(root_dir)
- build_lib "foo", path: root_dir
+ build_lib "foo", :path => root_dir
gemfile = <<-G
source "#{file_uri_for(gem_repo1)}"
gemspec
@@ -770,7 +622,7 @@ RSpec.describe "bundle install with gem sources" do
file.puts gemfile
end
- bundle :install, dir: root_dir
+ bundle :install, :dir => root_dir
end
end
@@ -783,7 +635,7 @@ RSpec.describe "bundle install with gem sources" do
gem 'rack'
G
- bundle :install, quiet: true
+ bundle :install, :quiet => true
expect(out).to be_empty
expect(err).to be_empty
end
@@ -813,7 +665,7 @@ RSpec.describe "bundle install with gem sources" do
gem 'non-existing-gem'
G
- bundle :install, quiet: true, raise_on_error: false, env: { "RUBYOPT" => "-r#{bundled_app("install_with_warning.rb")}" }
+ bundle :install, :quiet => true, :raise_on_error => false, :env => { "RUBYOPT" => "-r#{bundled_app("install_with_warning.rb")}" }
expect(out).to be_empty
expect(err).to include("Could not find gem 'non-existing-gem'")
expect(err).to include("BOOOOO")
@@ -835,7 +687,7 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.chmod(0o500, bundle_path)
bundle "config set --local path vendor"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include(bundle_path.to_s)
expect(err).to include("grant write permissions")
end
@@ -857,7 +709,7 @@ RSpec.describe "bundle install with gem sources" do
bundle "config set --local path vendor"
begin
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
ensure
FileUtils.chmod("+x", gems_path)
end
@@ -887,7 +739,7 @@ RSpec.describe "bundle install with gem sources" do
bundle "config set --local path vendor"
begin
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
ensure
FileUtils.chmod("+x", extensions_path)
end
@@ -927,7 +779,7 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.chmod("-x", foo_path)
begin
- bundle "install --redownload", raise_on_error: false
+ bundle "install --redownload", :raise_on_error => false
ensure
FileUtils.chmod("+x", foo_path)
end
@@ -938,71 +790,6 @@ RSpec.describe "bundle install with gem sources" do
end
end
- describe "when gem home does not have the writable bit set, yet it's still writable", :permissions do
- let(:gem_home) { bundled_app("vendor/#{Bundler.ruby_scope}") }
-
- before do
- build_repo4 do
- build_gem "foo", "1.0.0" do |s|
- s.write "CHANGELOG.md", "foo"
- end
- end
-
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'foo'
- G
- end
-
- it "should display a proper message to explain the problem" do
- bundle "config set --local path vendor"
- bundle :install
- expect(out).to include("Bundle complete!")
- expect(err).to be_empty
-
- FileUtils.chmod("-w", gem_home)
-
- begin
- bundle "install --redownload"
- ensure
- FileUtils.chmod("+w", gem_home)
- end
-
- expect(out).to include("Bundle complete!")
- expect(err).to be_empty
- end
- end
-
- describe "when gems path is world writable (no sticky bit set)", :permissions do
- let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") }
-
- before do
- build_repo4 do
- build_gem "foo", "1.0.0" do |s|
- s.write "CHANGELOG.md", "foo"
- end
- end
-
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'foo'
- G
- end
-
- it "should display a proper message to explain the problem" do
- bundle "config set --local path vendor"
- bundle :install
- expect(out).to include("Bundle complete!")
- expect(err).to be_empty
-
- FileUtils.chmod(0o777, gems_path)
-
- bundle "install --redownload", raise_on_error: false
-
- expect(err).to include("The installation path is insecure. Bundler cannot continue.")
- end
- end
-
describe "when bundle cache path does not have write access", :permissions do
let(:cache_path) { bundled_app("vendor/#{Bundler.ruby_scope}/cache") }
@@ -1018,35 +805,12 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.chmod(0o500, cache_path)
bundle "config set --local path vendor"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include(cache_path.to_s)
expect(err).to include("grant write permissions")
end
end
- describe "when gemspecs are unreadable", :permissions do
- let(:gemspec_path) { vendored_gems("specifications/rack-1.0.0.gemspec") }
-
- before do
- gemfile <<~G
- source "#{file_uri_for(gem_repo1)}"
- gem 'rack'
- G
- bundle "config path vendor/bundle"
- bundle :install
- expect(out).to include("Bundle complete!")
- expect(err).to be_empty
-
- FileUtils.chmod("-r", gemspec_path)
- end
-
- it "shows a good error" do
- bundle :install, raise_on_error: false
- expect(err).to include(gemspec_path.to_s)
- expect(err).to include("grant read permissions")
- end
- end
-
context "after installing with --standalone" do
before do
install_gemfile <<-G
@@ -1054,11 +818,11 @@ RSpec.describe "bundle install with gem sources" do
gem "rack"
G
bundle "config set --local path bundle"
- bundle "install", standalone: true
+ bundle "install", :standalone => true
end
it "includes the standalone path" do
- bundle "binstubs rack", standalone: true
+ bundle "binstubs rack", :standalone => true
standalone_line = File.read(bundled_app("bin/rackup")).each_line.find {|line| line.include? "$:.unshift" }.strip
expect(standalone_line).to eq %($:.unshift File.expand_path "../bundle", __dir__)
end
@@ -1073,7 +837,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "should display a helpful message explaining how to fix it" do
- bundle :install, env: { "BUNDLE_RUBYGEMS__ORG" => "user:pass{word" }, raise_on_error: false
+ bundle :install, :env => { "BUNDLE_RUBYGEMS__ORG" => "user:pass{word" }, :raise_on_error => false
expect(exitstatus).to eq(17)
expect(err).to eq("Please CGI escape your usernames and passwords before " \
"setting them for authentication.")
@@ -1114,7 +878,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "should fail loudly if the lockfile platforms don't include the current platform" do
- simulate_platform(Gem::Platform.new("x86_64-linux")) { bundle "install", raise_on_error: false }
+ simulate_platform(Gem::Platform.new("x86_64-linux")) { bundle "install", :raise_on_error => false }
expect(err).to eq(
"Your bundle only supports platforms [\"x86_64-darwin-19\"] but your local platform is x86_64-linux. " \
@@ -1126,16 +890,16 @@ RSpec.describe "bundle install with gem sources" do
context "with missing platform specific gems in lockfile" do
before do
build_repo4 do
- build_gem "racca", "1.5.2"
+ build_gem "racc", "1.5.2"
build_gem "nokogiri", "1.12.4" do |s|
s.platform = "x86_64-darwin"
- s.add_runtime_dependency "racca", "~> 1.4"
+ s.add_runtime_dependency "racc", "~> 1.4"
end
build_gem "nokogiri", "1.12.4" do |s|
s.platform = "x86_64-linux"
- s.add_runtime_dependency "racca", "~> 1.4"
+ s.add_runtime_dependency "racc", "~> 1.4"
end
build_gem "crass", "1.0.6"
@@ -1154,13 +918,6 @@ RSpec.describe "bundle install with gem sources" do
gem "loofah", "~> 2.12.0"
G
- checksums = checksums_section do |c|
- c.checksum gem_repo4, "crass", "1.0.6"
- c.checksum gem_repo4, "loofah", "2.12.0"
- c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin"
- c.checksum gem_repo4, "racca", "1.5.2"
- end
-
lockfile <<-L
GEM
remote: https://gem.repo4/
@@ -1170,8 +927,8 @@ RSpec.describe "bundle install with gem sources" do
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
nokogiri (1.12.4-x86_64-darwin)
- racca (~> 1.4)
- racca (1.5.2)
+ racc (~> 1.4)
+ racc (1.5.2)
PLATFORMS
x86_64-darwin-20
@@ -1179,7 +936,7 @@ RSpec.describe "bundle install with gem sources" do
DEPENDENCIES
loofah (~> 2.12.0)
- #{checksums}
+
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -1192,15 +949,7 @@ RSpec.describe "bundle install with gem sources" do
bundle "config set --local path vendor/bundle"
simulate_platform "x86_64-linux" do
- bundle "install", artifice: "compact_index"
- end
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "crass", "1.0.6"
- c.checksum gem_repo4, "loofah", "2.12.0"
- c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin"
- c.checksum gem_repo4, "racca", "1.5.2"
- c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-linux"
+ bundle "install", :artifice => "compact_index"
end
expect(lockfile).to eq <<~L
@@ -1212,10 +961,10 @@ RSpec.describe "bundle install with gem sources" do
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
nokogiri (1.12.4-x86_64-darwin)
- racca (~> 1.4)
+ racc (~> 1.4)
nokogiri (1.12.4-x86_64-linux)
- racca (~> 1.4)
- racca (1.5.2)
+ racc (~> 1.4)
+ racc (1.5.2)
PLATFORMS
x86_64-darwin-20
@@ -1223,7 +972,7 @@ RSpec.describe "bundle install with gem sources" do
DEPENDENCIES
loofah (~> 2.12.0)
- #{checksums}
+
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -1235,11 +984,11 @@ RSpec.describe "bundle install with gem sources" do
context "with --local flag" do
before do
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
end
it "respects installed gems without fetching any remote sources" do
- install_gemfile <<-G, local: true
+ install_gemfile <<-G, :local => true
source "#{file_uri_for(gem_repo1)}"
source "https://not-existing-source" do
@@ -1279,11 +1028,11 @@ RSpec.describe "bundle install with gem sources" do
build_gem "bar", "1.0.0"
end
- system_gems "foo-1.0.0", path: default_bundle_path, gem_repo: gem_repo4
+ system_gems "foo-1.0.0", :path => default_bundle_path, :gem_repo => gem_repo4
end
it "fetches remote sources only when not available locally" do
- install_gemfile <<-G, "prefer-local": true, verbose: true
+ install_gemfile <<-G, :"prefer-local" => true, :verbose => true
source "#{file_uri_for(gem_repo4)}"
gem "foo"
@@ -1313,7 +1062,7 @@ RSpec.describe "bundle install with gem sources" do
File.symlink("../../README.markdown", File.join(man_path, "README.markdown"))
build_repo4 do
- build_gem "binman", path: gem_repo4("gems"), lib_path: binman_path, no_default: true do |s|
+ build_gem "binman", :path => gem_repo4("gems"), :lib_path => binman_path, :no_default => true do |s|
s.files = ["README.markdown", "man/man0/README.markdown"]
end
end
@@ -1348,92 +1097,10 @@ RSpec.describe "bundle install with gem sources" do
gem "autobuild", "1.10.rc2"
G
- bundle "install --jobs 1", raise_on_error: false
+ bundle "install --jobs 1", :raise_on_error => false
expect(err).not_to include("ERROR REPORT TEMPLATE")
expect(err).to include("Could not find compatible versions")
end
end
-
- context "when a lockfile has unmet dependencies, and the Gemfile has no resolution" do
- before do
- build_repo4 do
- build_gem "aaa", "0.2.0" do |s|
- s.add_dependency "zzz", "< 0.2.0"
- end
-
- build_gem "zzz", "0.2.0"
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "aaa"
- gem "zzz"
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- aaa (0.2.0)
- zzz (< 0.2.0)
- zzz (0.2.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- aaa!
- zzz!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "does not install, but raises a resolution error" do
- bundle "install", raise_on_error: false
- expect(err).to include("Could not find compatible versions")
- end
- end
-
- context "when --jobs option given" do
- before do
- install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", jobs: 1
- end
-
- it "does not save the flag to config" do
- expect(bundled_app(".bundle/config")).not_to exist
- end
- end
-
- context "when bundler installation is corrupt" do
- before do
- system_gems "bundler-9.99.8"
-
- replace_version_file("9.99.9", dir: system_gem_path("gems/bundler-9.99.8"))
- end
-
- it "shows a proper error" do
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo1)}/
- specs:
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
-
- BUNDLED WITH
- 9.99.8
- L
-
- install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", env: { "BUNDLER_VERSION" => "9.99.8" }, raise_on_error: false
-
- expect(err).not_to include("ERROR REPORT TEMPLATE")
- expect(err).to include("The running version of Bundler (9.99.9) does not match the version of the specification installed for it (9.99.8)")
- end
- end
end
diff --git a/spec/bundler/commands/list_spec.rb b/spec/bundler/commands/list_spec.rb
index 5ac2077d81..66930ded75 100644
--- a/spec/bundler/commands/list_spec.rb
+++ b/spec/bundler/commands/list_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe "bundle list" do
context "with name-only and paths option" do
it "raises an error" do
- bundle "list --name-only --paths", raise_on_error: false
+ bundle "list --name-only --paths", :raise_on_error => false
expect(err).to eq "The `--name-only` and `--paths` options cannot be used together"
end
@@ -11,7 +11,7 @@ RSpec.describe "bundle list" do
context "with without-group and only-group option" do
it "raises an error" do
- bundle "list --without-group dev --only-group test", raise_on_error: false
+ bundle "list --without-group dev --only-group test", :raise_on_error => false
expect(err).to eq "The `--only-group` and `--without-group` options cannot be used together"
end
@@ -40,7 +40,7 @@ RSpec.describe "bundle list" do
context "when group is not found" do
it "raises an error" do
- bundle "list --without-group random", raise_on_error: false
+ bundle "list --without-group random", :raise_on_error => false
expect(err).to eq "`random` group could not be found."
end
@@ -79,7 +79,7 @@ RSpec.describe "bundle list" do
context "when group is not found" do
it "raises an error" do
- bundle "list --only-group random", raise_on_error: false
+ bundle "list --only-group random", :raise_on_error => false
expect(err).to eq "`random` group could not be found."
end
@@ -124,9 +124,9 @@ RSpec.describe "bundle list" do
build_gem "bar"
end
- build_git "git_test", "1.0.0", path: lib_path("git_test")
+ build_git "git_test", "1.0.0", :path => lib_path("git_test")
- build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s|
+ build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
s.add_dependency "bar", "=1.0.0"
end
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index b0d6fa9134..491fa30949 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -1,6 +1,14 @@
# frozen_string_literal: true
RSpec.describe "bundle lock" do
+ def strip_lockfile(lockfile)
+ strip_whitespace(lockfile).sub(/\n\Z/, "")
+ end
+
+ def read_lockfile(file = "Gemfile.lock")
+ strip_lockfile bundled_app(file).read
+ end
+
let(:repo) { gem_repo1 }
before :each do
@@ -11,19 +19,7 @@ RSpec.describe "bundle lock" do
gem "foo"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum repo, "actionmailer", "2.3.2"
- c.checksum repo, "actionpack", "2.3.2"
- c.checksum repo, "activerecord", "2.3.2"
- c.checksum repo, "activeresource", "2.3.2"
- c.checksum repo, "activesupport", "2.3.2"
- c.checksum repo, "foo", "1.0"
- c.checksum repo, "rails", "2.3.2"
- c.checksum repo, "rake", rake_version
- c.checksum repo, "weakling", "0.0.3"
- end
-
- @lockfile = <<~L
+ @lockfile = strip_lockfile(<<-L)
GEM
remote: #{file_uri_for(repo)}/
specs:
@@ -42,8 +38,8 @@ RSpec.describe "bundle lock" do
actionpack (= 2.3.2)
activerecord (= 2.3.2)
activeresource (= 2.3.2)
- rake (= #{rake_version})
- rake (#{rake_version})
+ rake (= 13.0.1)
+ rake (13.0.1)
weakling (0.0.3)
PLATFORMS
@@ -53,7 +49,7 @@ RSpec.describe "bundle lock" do
foo
rails
weakling
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -62,23 +58,15 @@ RSpec.describe "bundle lock" do
it "prints a lockfile when there is no existing lockfile with --print" do
bundle "lock --print"
- expect(out).to eq(@lockfile.chomp)
+ expect(out).to eq(@lockfile)
end
it "prints a lockfile when there is an existing lockfile with --print" do
- lockfile remove_checksums_section_from_lockfile(@lockfile)
-
- bundle "lock --print"
-
- expect(out).to eq(remove_checksums_section_from_lockfile(@lockfile).chomp)
- end
-
- it "prints a lockfile when there is an existing checksums lockfile with --print" do
lockfile @lockfile
bundle "lock --print"
- expect(out).to eq(@lockfile.chomp)
+ expect(out).to eq(@lockfile)
end
it "writes a lockfile when there is no existing lockfile" do
@@ -87,39 +75,7 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(@lockfile)
end
- it "prints a lockfile without fetching new checksums if the existing lockfile had no checksums" do
- lockfile remove_checksums_from_lockfile(@lockfile)
-
- bundle "lock --print"
-
- expect(out).to eq(remove_checksums_from_lockfile(@lockfile).chomp)
- end
-
- it "touches the lockfile when there is an existing lockfile that does not need changes" do
- lockfile @lockfile
-
- expect do
- bundle "lock"
- end.to change { bundled_app_lock.mtime }
- end
-
- it "does not touch lockfile with --print" do
- lockfile @lockfile
-
- expect do
- bundle "lock --print"
- end.not_to change { bundled_app_lock.mtime }
- end
-
it "writes a lockfile when there is an outdated lockfile using --update" do
- lockfile remove_checksums_from_lockfile(@lockfile.gsub("2.3.2", "2.3.1"), " (2.3.1)")
-
- bundle "lock --update"
-
- expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile))
- end
-
- it "writes a lockfile with checksums on --update when checksums exist" do
lockfile @lockfile.gsub("2.3.2", "2.3.1")
bundle "lock --update"
@@ -127,39 +83,18 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(@lockfile)
end
- it "writes a lockfile when there is an outdated lockfile and bundle is frozen" do
- lockfile @lockfile.gsub("2.3.2", "2.3.1")
-
- bundle "lock --update", env: { "BUNDLE_FROZEN" => "true" }
-
- expect(read_lockfile).to eq(@lockfile)
- end
-
it "does not fetch remote specs when using the --local option" do
- bundle "lock --update --local", raise_on_error: false
+ bundle "lock --update --local", :raise_on_error => false
expect(err).to match(/locally installed gems/)
end
- it "does not fetch remote checksums with --local" do
- lockfile remove_checksums_from_lockfile(@lockfile)
-
- bundle "lock --print --local"
-
- # No checksums because --local prevents fetching them
- expect(out).to eq(remove_checksums_from_lockfile(@lockfile).chomp)
- end
-
it "works with --gemfile flag" do
create_file "CustomGemfile", <<-G
source "#{file_uri_for(repo)}"
gem "foo"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
- lockfile = <<~L
+ lockfile = strip_lockfile(<<-L)
GEM
remote: #{file_uri_for(repo)}/
specs:
@@ -170,7 +105,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
foo
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -185,7 +120,7 @@ RSpec.describe "bundle lock" do
bundle "lock --lockfile=lock"
expect(out).to match(/Writing lockfile to.+lock/)
- expect(read_lockfile("lock")).to eq(remove_checksums_from_lockfile(@lockfile))
+ expect(read_lockfile("lock")).to eq(@lockfile)
expect { read_lockfile }.to raise_error(Errno::ENOENT)
end
@@ -193,195 +128,16 @@ RSpec.describe "bundle lock" do
bundle "install"
bundle "lock --lockfile=lock"
- checksums = checksums_section_when_existing do |c|
- c.checksum repo, "actionmailer", "2.3.2"
- c.checksum repo, "actionpack", "2.3.2"
- c.checksum repo, "activerecord", "2.3.2"
- c.checksum repo, "activeresource", "2.3.2"
- c.checksum repo, "activesupport", "2.3.2"
- c.checksum repo, "foo", "1.0"
- c.checksum repo, "rails", "2.3.2"
- c.checksum repo, "rake", rake_version
- c.checksum repo, "weakling", "0.0.3"
- end
-
- lockfile = <<~L
- GEM
- remote: #{file_uri_for(repo)}/
- specs:
- actionmailer (2.3.2)
- activesupport (= 2.3.2)
- actionpack (2.3.2)
- activesupport (= 2.3.2)
- activerecord (2.3.2)
- activesupport (= 2.3.2)
- activeresource (2.3.2)
- activesupport (= 2.3.2)
- activesupport (2.3.2)
- foo (1.0)
- rails (2.3.2)
- actionmailer (= 2.3.2)
- actionpack (= 2.3.2)
- activerecord (= 2.3.2)
- activeresource (= 2.3.2)
- rake (= #{rake_version})
- rake (#{rake_version})
- weakling (0.0.3)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- foo
- rails
- weakling
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
expect(out).to match(/Writing lockfile to.+lock/)
- expect(read_lockfile("lock")).to eq(lockfile)
+ expect(read_lockfile("lock")).to eq(@lockfile)
end
it "update specific gems using --update" do
- lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub(rake_version, "10.0.1")
+ lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub("13.0.1", "10.0.1")
bundle "lock --update rails rake"
- expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile, "(2.3.2)", "(#{rake_version})"))
- end
-
- it "updates specific gems using --update, even if that requires unlocking other top level gems" do
- build_repo4 do
- build_gem "prism", "0.15.1"
- build_gem "prism", "0.24.0"
-
- build_gem "ruby-lsp", "0.12.0" do |s|
- s.add_dependency "prism", "< 0.24.0"
- end
-
- build_gem "ruby-lsp", "0.16.1" do |s|
- s.add_dependency "prism", ">= 0.24.0"
- end
-
- build_gem "tapioca", "0.11.10" do |s|
- s.add_dependency "prism", "< 0.24.0"
- end
-
- build_gem "tapioca", "0.13.1" do |s|
- s.add_dependency "prism", ">= 0.24.0"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "tapioca"
- gem "ruby-lsp"
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}
- specs:
- prism (0.15.1)
- ruby-lsp (0.12.0)
- prism (< 0.24.0)
- tapioca (0.11.10)
- prism (< 0.24.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- ruby-lsp
- tapioca
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- bundle "lock --update tapioca --verbose"
-
- expect(lockfile).to include("tapioca (0.13.1)")
- end
-
- it "updates specific gems using --update, even if that requires unlocking other top level gems, but only as few as possible" do
- build_repo4 do
- build_gem "prism", "0.15.1"
- build_gem "prism", "0.24.0"
-
- build_gem "ruby-lsp", "0.12.0" do |s|
- s.add_dependency "prism", "< 0.24.0"
- end
-
- build_gem "ruby-lsp", "0.16.1" do |s|
- s.add_dependency "prism", ">= 0.24.0"
- end
-
- build_gem "tapioca", "0.11.10" do |s|
- s.add_dependency "prism", "< 0.24.0"
- end
-
- build_gem "tapioca", "0.13.1" do |s|
- s.add_dependency "prism", ">= 0.24.0"
- end
-
- build_gem "other-prism-dependent", "1.0.0" do |s|
- s.add_dependency "prism", ">= 0.15.1"
- end
-
- build_gem "other-prism-dependent", "1.1.0" do |s|
- s.add_dependency "prism", ">= 0.15.1"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "tapioca"
- gem "ruby-lsp"
- gem "other-prism-dependent"
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}
- specs:
- other-prism-dependent (1.0.0)
- prism (>= 0.15.1)
- prism (0.15.1)
- ruby-lsp (0.12.0)
- prism (< 0.24.0)
- tapioca (0.11.10)
- prism (< 0.24.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- ruby-lsp
- tapioca
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- bundle "lock --update tapioca"
-
- expect(lockfile).to include("tapioca (0.13.1)")
- expect(lockfile).to include("other-prism-dependent (1.0.0)")
- end
-
- it "preserves unknown checksum algorithms" do
- lockfile @lockfile.gsub(/(sha256=[a-f0-9]+)$/, "constant=true,\\1,xyz=123")
-
- previous_lockfile = read_lockfile
-
- bundle "lock"
-
- expect(read_lockfile).to eq(previous_lockfile)
+ expect(read_lockfile).to eq(@lockfile)
end
it "does not unlock git sources when only uri shape changes" do
@@ -393,7 +149,7 @@ RSpec.describe "bundle lock" do
G
# Change uri format to end with "/" and reinstall
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}/"
G
@@ -437,13 +193,13 @@ RSpec.describe "bundle lock" do
bundle "lock --update rake --verbose"
expect(out).to match(/Writing lockfile to.+lock/)
- expect(lockfile).to include("rake (#{rake_version})")
+ expect(lockfile).to include("rake (13.0.1)")
end
it "errors when updating a missing specific gems using --update" do
lockfile @lockfile
- bundle "lock --update blahblah", raise_on_error: false
+ bundle "lock --update blahblah", :raise_on_error => false
expect(err).to eq("Could not find gem 'blahblah'.")
expect(read_lockfile).to eq(@lockfile)
@@ -458,7 +214,7 @@ RSpec.describe "bundle lock" do
G
bundle "config set without test"
bundle "config set path vendor/bundle"
- bundle "lock", verbose: true
+ bundle "lock"
expect(bundled_app("vendor/bundle")).not_to exist
end
@@ -514,22 +270,6 @@ RSpec.describe "bundle lock" do
expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-1.5.0 bar-2.1.1 qux-1.1.0].sort)
end
- it "shows proper error when Gemfile changes forbid patch upgrades, and --patch --strict is given" do
- # force next minor via Gemfile
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'foo', '1.5.0'
- gem 'qux'
- G
-
- bundle "lock --update foo --patch --strict", raise_on_error: false
-
- expect(err).to include(
- "foo is locked to 1.4.3, while Gemfile is requesting foo (= 1.5.0). " \
- "--strict --patch was specified, but there are no patch level upgrades from 1.4.3 satisfying foo (= 1.5.0), so version solving has failed"
- )
- end
-
context "pre" do
it "defaults to major" do
bundle "lock --update --pre"
@@ -557,67 +297,26 @@ RSpec.describe "bundle lock" do
end
end
- context "conservative updates when minor update adds a new dependency" do
- before do
- build_repo4 do
- build_gem "sequel", "5.71.0"
- build_gem "sequel", "5.72.0" do |s|
- s.add_dependency "bigdecimal", ">= 0"
- end
- build_gem "bigdecimal", %w[1.4.4 99.1.4]
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
- gem 'sequel'
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- sequel (5.71.0)
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
- sequel
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- end
-
- it "adds the latest version of the new dependency" do
- bundle "lock --minor --update sequel"
-
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[sequel-5.72.0 bigdecimal-99.1.4].sort)
- end
- end
-
it "updates the bundler version in the lockfile to the latest bundler version" do
build_repo4 do
build_gem "bundler", "55"
end
- system_gems "bundler-55", gem_repo: gem_repo4
+ system_gems "bundler-55", :gem_repo => gem_repo4
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
source "https://gems.repo4"
G
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2')
- bundle "lock --update --bundler --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "lock --update --bundler --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(lockfile).to end_with("BUNDLED WITH\n 55\n")
update_repo4 do
build_gem "bundler", "99"
end
- bundle "lock --update --bundler --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "lock --update --bundler --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(lockfile).to end_with("BUNDLED WITH\n 99\n")
end
@@ -626,7 +325,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32))
+ expect(lockfile.platforms).to match_array([java, x86_mingw32, local_platform].uniq)
end
it "supports adding new platforms with force_ruby_platform = true" do
@@ -658,7 +357,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(default_platform_list("ruby"))
+ expect(lockfile.platforms).to match_array(["ruby", local_platform].uniq)
end
it "warns when adding an unknown platform" do
@@ -671,12 +370,12 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32))
+ expect(lockfile.platforms).to match_array([java, x86_mingw32, local_platform].uniq)
bundle "lock --remove-platform java"
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(default_platform_list(x86_mingw32))
+ expect(lockfile.platforms).to match_array([x86_mingw32, local_platform].uniq)
end
it "also cleans up redundant platform gems when removing platforms" do
@@ -687,11 +386,6 @@ RSpec.describe "bundle lock" do
end
end
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "nokogiri", "1.12.0"
- c.checksum gem_repo4, "nokogiri", "1.12.0", "x86_64-darwin"
- end
-
simulate_platform "x86_64-darwin-22" do
install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
@@ -713,13 +407,11 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
nokogiri
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
- checksums.delete("nokogiri", Gem::Platform::RUBY)
-
simulate_platform "x86_64-darwin-22" do
bundle "lock --remove-platform ruby"
end
@@ -735,14 +427,14 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
nokogiri
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "errors when removing all platforms" do
- bundle "lock --remove-platform #{local_platform}", raise_on_error: false
+ bundle "lock --remove-platform #{local_platform}", :raise_on_error => false
expect(err).to include("Removing all platforms from the bundle is not allowed")
end
@@ -783,13 +475,6 @@ RSpec.describe "bundle lock" do
gem "gssapi"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "ffi", "1.9.14", "x86-mingw32"
- c.no_checksum "gssapi", "1.2.0"
- c.no_checksum "mixlib-shellout", "2.2.6", "universal-mingw32"
- c.no_checksum "win32-process", "0.8.3"
- end
-
simulate_platform(x86_mingw32) { bundle :lock }
expect(lockfile).to eq <<~G
@@ -810,7 +495,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
gssapi
mixlib-shellout
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -818,9 +503,6 @@ RSpec.describe "bundle lock" do
bundle "config set --local force_ruby_platform true"
bundle :lock
- checksums.no_checksum "ffi", "1.9.14"
- checksums.no_checksum "mixlib-shellout", "2.2.6"
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -842,7 +524,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
gssapi
mixlib-shellout
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -906,12 +588,7 @@ RSpec.describe "bundle lock" do
gem "libv8"
G
- simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock" }
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "libv8", "8.4.255.0", "x86_64-darwin-19"
- c.no_checksum "libv8", "8.4.255.0", "x86_64-darwin-20"
- end
+ simulate_platform(Gem::Platform.new("x86_64-darwin")) { bundle "lock" }
expect(lockfile).to eq <<~G
GEM
@@ -921,12 +598,11 @@ RSpec.describe "bundle lock" do
libv8 (8.4.255.0-x86_64-darwin-20)
PLATFORMS
- x86_64-darwin-19
- x86_64-darwin-20
+ x86_64-darwin
DEPENDENCIES
libv8
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -943,11 +619,6 @@ RSpec.describe "bundle lock" do
end
end
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-19"
- c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-20"
- end
-
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
@@ -966,7 +637,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
libv8
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -1029,7 +700,7 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
L
- bundle "lock --add-platform x86_64-linux", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "lock --add-platform x86_64-linux", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end
it "does not crash on conflicting ruby requirements between platform versions in two different gems" do
@@ -1085,7 +756,7 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
L
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "DEBUG_RESOLVER" => "1" }
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "DEBUG_RESOLVER" => "1" }
end
it "respects lower bound ruby requirements" do
@@ -1117,126 +788,30 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
L
- bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "install", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end
context "when an update is available" do
- let(:repo) do
- build_repo2 do
- build_gem "foo", "2.0"
- end
- gem_repo2
- end
+ let(:repo) { gem_repo2 }
before do
lockfile(@lockfile)
+ build_repo2 do
+ build_gem "foo", "2.0"
+ end
end
it "does not implicitly update" do
bundle "lock"
- checksums = checksums_section_when_existing do |c|
- c.checksum repo, "actionmailer", "2.3.2"
- c.checksum repo, "actionpack", "2.3.2"
- c.checksum repo, "activerecord", "2.3.2"
- c.checksum repo, "activeresource", "2.3.2"
- c.checksum repo, "activesupport", "2.3.2"
- c.checksum repo, "foo", "1.0"
- c.checksum repo, "rails", "2.3.2"
- c.checksum repo, "rake", rake_version
- c.checksum repo, "weakling", "0.0.3"
- end
-
- expected_lockfile = <<~L
- GEM
- remote: #{file_uri_for(repo)}/
- specs:
- actionmailer (2.3.2)
- activesupport (= 2.3.2)
- actionpack (2.3.2)
- activesupport (= 2.3.2)
- activerecord (2.3.2)
- activesupport (= 2.3.2)
- activeresource (2.3.2)
- activesupport (= 2.3.2)
- activesupport (2.3.2)
- foo (1.0)
- rails (2.3.2)
- actionmailer (= 2.3.2)
- actionpack (= 2.3.2)
- activerecord (= 2.3.2)
- activeresource (= 2.3.2)
- rake (= #{rake_version})
- rake (#{rake_version})
- weakling (0.0.3)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- foo
- rails
- weakling
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- expect(read_lockfile).to eq(expected_lockfile)
+ expect(read_lockfile).to eq(@lockfile)
end
it "accounts for changes in the gemfile" do
gemfile gemfile.gsub('"foo"', '"foo", "2.0"')
bundle "lock"
- checksums = checksums_section_when_existing do |c|
- c.checksum repo, "actionmailer", "2.3.2"
- c.checksum repo, "actionpack", "2.3.2"
- c.checksum repo, "activerecord", "2.3.2"
- c.checksum repo, "activeresource", "2.3.2"
- c.checksum repo, "activesupport", "2.3.2"
- c.no_checksum "foo", "2.0"
- c.checksum repo, "rails", "2.3.2"
- c.checksum repo, "rake", rake_version
- c.checksum repo, "weakling", "0.0.3"
- end
-
- expected_lockfile = <<~L
- GEM
- remote: #{file_uri_for(repo)}/
- specs:
- actionmailer (2.3.2)
- activesupport (= 2.3.2)
- actionpack (2.3.2)
- activesupport (= 2.3.2)
- activerecord (2.3.2)
- activesupport (= 2.3.2)
- activeresource (2.3.2)
- activesupport (= 2.3.2)
- activesupport (2.3.2)
- foo (2.0)
- rails (2.3.2)
- actionmailer (= 2.3.2)
- actionpack (= 2.3.2)
- activerecord (= 2.3.2)
- activeresource (= 2.3.2)
- rake (= #{rake_version})
- rake (#{rake_version})
- weakling (0.0.3)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- foo (= 2.0)
- rails
- weakling
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- expect(read_lockfile).to eq(expected_lockfile)
+ expect(read_lockfile).to eq(@lockfile.sub("foo (1.0)", "foo (2.0)").sub(/foo$/, "foo (= 2.0)"))
end
end
@@ -1250,8 +825,8 @@ RSpec.describe "bundle lock" do
build_gem "irb", "1.5.0"
end
- system_gems "irb-1.5.0", gem_repo: gem_repo4
- system_gems "debug-1.6.3", gem_repo: gem_repo4
+ system_gems "irb-1.5.0", :gem_repo => gem_repo4
+ system_gems "debug-1.6.3", :gem_repo => gem_repo4
# simulate gemspec with wrong empty dependencies
debug_gemspec_path = system_gem_path("specifications/debug-1.6.3.gemspec")
@@ -1280,7 +855,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
debug
- #{checksums_section}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1289,11 +864,6 @@ RSpec.describe "bundle lock" do
bundle "lock"
end
- checksums = checksums_section do |c|
- c.no_checksum "debug", "1.6.3"
- c.no_checksum "irb", "1.5.0"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -1308,7 +878,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
debug
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1341,7 +911,7 @@ RSpec.describe "bundle lock" do
gem "activeadmin", "2.13.1"
G
- bundle "lock", raise_on_error: false
+ bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
@@ -1406,7 +976,7 @@ RSpec.describe "bundle lock" do
activemodel (>= 6.0.4)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
activeadmin (= 2.13.1)
@@ -1416,7 +986,7 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
L
- bundle "lock", raise_on_error: false
+ bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
@@ -1442,9 +1012,9 @@ RSpec.describe "bundle lock" do
version solving has failed.
ERR
- lockfile lockfile.gsub(/PLATFORMS\n #{local_platform}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
+ lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
- bundle "lock", raise_on_error: false
+ bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
@@ -1537,7 +1107,7 @@ RSpec.describe "bundle lock" do
G
simulate_platform "universal-java-19" do
- bundle "lock", raise_on_error: false
+ bundle "lock", :raise_on_error => false
end
expect(err).to include("Could not find compatible versions")
@@ -1572,7 +1142,7 @@ RSpec.describe "bundle lock" do
context "when resolving platform specific gems as indirect dependencies on truffleruby", :truffleruby_only do
before do
- build_lib "foo", path: bundled_app do |s|
+ build_lib "foo", :path => bundled_app do |s|
s.add_dependency "nokogiri"
end
@@ -1590,11 +1160,6 @@ RSpec.describe "bundle lock" do
end
it "locks ruby specs" do
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.no_checksum "nokogiri", "1.14.2"
- end
-
simulate_platform "x86_64-linux" do
bundle "lock"
end
@@ -1612,11 +1177,11 @@ RSpec.describe "bundle lock" do
nokogiri (1.14.2)
PLATFORMS
- #{lockfile_platforms}
+ x86_64-linux
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1677,13 +1242,6 @@ RSpec.describe "bundle lock" do
end
it "does not downgrade top level dependencies" do
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "actionpack", "7.0.4.3"
- c.no_checksum "activesupport", "7.0.4.3"
- c.no_checksum "govuk_app_config", "4.13.0"
- c.no_checksum "railties", "7.0.4.3"
- end
-
simulate_platform "arm64-darwin-22" do
bundle "lock"
end
@@ -1706,7 +1264,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
activesupport (= 7.0.4.3)
govuk_app_config
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb
index 4c391b268c..ede1ff6b8e 100644
--- a/spec/bundler/commands/newgem_spec.rb
+++ b/spec/bundler/commands/newgem_spec.rb
@@ -12,14 +12,14 @@ RSpec.describe "bundle gem" do
def bundle_exec_rubocop
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
- bundle "config set path #{rubocop_gems}", dir: bundled_app(gem_name)
- bundle "exec rubocop --debug --config .rubocop.yml", dir: bundled_app(gem_name)
+ bundle "config set path #{rubocop_gems}", :dir => bundled_app(gem_name)
+ bundle "exec rubocop --debug --config .rubocop.yml", :dir => bundled_app(gem_name)
end
def bundle_exec_standardrb
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
- bundle "config set path #{standard_gems}", dir: bundled_app(gem_name)
- bundle "exec standardrb --debug", dir: bundled_app(gem_name)
+ bundle "config set path #{standard_gems}", :dir => bundled_app(gem_name)
+ bundle "exec standardrb --debug", :dir => bundled_app(gem_name)
end
let(:generated_gemspec) { Bundler.load_gemspec_uncached(bundled_app(gem_name).join("#{gem_name}.gemspec")) }
@@ -36,25 +36,22 @@ RSpec.describe "bundle gem" do
sys_exec("git config --global user.name 'Bundler User'")
sys_exec("git config --global user.email user@example.com")
sys_exec("git config --global github.user bundleuser")
-
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false",
- "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
end
describe "git repo initialization" do
- it "generates a gem skeleton with a .git folder" do
+ it "generates a gem skeleton with a .git folder", :readline do
bundle "gem #{gem_name}"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/.git")).to exist
end
- it "generates a gem skeleton with a .git folder when passing --git" do
+ it "generates a gem skeleton with a .git folder when passing --git", :readline do
bundle "gem #{gem_name} --git"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/.git")).to exist
end
- it "generates a gem skeleton without a .git folder when passing --no-git" do
+ it "generates a gem skeleton without a .git folder when passing --no-git", :readline do
bundle "gem #{gem_name} --no-git"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/.git")).not_to exist
@@ -65,10 +62,8 @@ RSpec.describe "bundle gem" do
Dir.mkdir(bundled_app("path with spaces"))
end
- it "properly initializes git repo" do
- skip "path with spaces needs special handling on Windows" if Gem.win_platform?
-
- bundle "gem #{gem_name}", dir: bundled_app("path with spaces")
+ it "properly initializes git repo", :readline do
+ bundle "gem #{gem_name}", :dir => bundled_app("path with spaces")
expect(bundled_app("path with spaces/#{gem_name}/.git")).to exist
end
end
@@ -108,7 +103,7 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/README.md").read).to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
end
- it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", git: ">= 2.28.0" do
+ it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", :git => ">= 2.28.0" do
sys_exec("git config --global init.defaultBranch main")
bundle "gem #{gem_name} --coc"
@@ -136,7 +131,7 @@ RSpec.describe "bundle gem" do
before do
bundle "gem #{gem_name} --changelog"
end
- it "generates a gem skeleton with a CHANGELOG" do
+ it "generates a gem skeleton with a CHANGELOG", :readline do
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/CHANGELOG.md")).to exist
end
@@ -146,16 +141,15 @@ RSpec.describe "bundle gem" do
before do
bundle "gem #{gem_name} --no-changelog"
end
- it "generates a gem skeleton without a CHANGELOG" do
+ it "generates a gem skeleton without a CHANGELOG", :readline do
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/CHANGELOG.md")).to_not exist
end
end
shared_examples_for "--rubocop flag" do
- context "is deprecated", bundler: "< 3" do
+ context "is deprecated", :bundler => "< 3" do
before do
- global_config "BUNDLE_GEM__LINTER" => nil
bundle "gem #{gem_name} --rubocop"
end
@@ -185,7 +179,7 @@ RSpec.describe "bundle gem" do
end
shared_examples_for "--no-rubocop flag" do
- context "is deprecated", bundler: "< 3" do
+ context "is deprecated", :bundler => "< 3" do
define_negated_matcher :exclude, :include
before do
@@ -309,49 +303,49 @@ RSpec.describe "bundle gem" do
end
end
- it "has no rubocop offenses when using --linter=rubocop flag" do
+ it "has no rubocop offenses when using --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=c and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --test=minitest --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --test=rspec --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --test=test-unit --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no standard offenses when using --linter=standard flag" do
+ it "has no standard offenses when using --linter=standard flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --linter=standard"
bundle_exec_standardrb
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -360,7 +354,7 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -369,7 +363,7 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -378,7 +372,7 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag" do
+ it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -405,7 +399,7 @@ RSpec.describe "bundle gem" do
end
end
- context "README.md" do
+ context "README.md", :readline do
context "git config github.user present" do
before do
bundle "gem #{gem_name}"
@@ -430,18 +424,18 @@ RSpec.describe "bundle gem" do
end
end
- it "creates a new git repository" do
+ it "creates a new git repository", :readline do
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.git")).to exist
end
- context "when git is not available" do
+ context "when git is not available", :readline do
# This spec cannot have `git` available in the test env
before do
load_paths = [lib_dir, spec_dir]
load_path_str = "-I#{load_paths.join(File::PATH_SEPARATOR)}"
- sys_exec "#{Gem.ruby} #{load_path_str} #{bindir.join("bundle")} gem #{gem_name}", env: { "PATH" => "" }
+ sys_exec "#{Gem.ruby} #{load_path_str} #{bindir.join("bundle")} gem #{gem_name}", :env => { "PATH" => "" }
end
it "creates the gem without the need for git" do
@@ -457,24 +451,24 @@ RSpec.describe "bundle gem" do
end
end
- it "generates a valid gemspec", :ruby_repo do
+ it "generates a valid gemspec", :readline, :ruby_repo do
bundle "gem newgem --bin"
prepare_gemspec(bundled_app("newgem", "newgem.gemspec"))
- gems = ["rake-#{rake_version}"]
- path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(base: bundled_app("newgem")) : system_gem_path
- system_gems gems, path: path
- bundle "exec rake build", dir: bundled_app("newgem")
+ gems = ["rake-13.0.1"]
+ path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(:base => bundled_app("newgem")) : system_gem_path
+ system_gems gems, :path => path
+ bundle "exec rake build", :dir => bundled_app("newgem")
expect(last_command.stdboth).not_to include("ERROR")
end
- context "gem naming with relative paths" do
+ context "gem naming with relative paths", :readline do
it "resolves ." do
create_temporary_dir("tmp")
- bundle "gem .", dir: bundled_app("tmp")
+ bundle "gem .", :dir => bundled_app("tmp")
expect(bundled_app("tmp/lib/tmp.rb")).to exist
end
@@ -482,7 +476,7 @@ RSpec.describe "bundle gem" do
it "resolves .." do
create_temporary_dir("temp/empty_dir")
- bundle "gem ..", dir: bundled_app("temp/empty_dir")
+ bundle "gem ..", :dir => bundled_app("temp/empty_dir")
expect(bundled_app("temp/lib/temp.rb")).to exist
end
@@ -490,7 +484,7 @@ RSpec.describe "bundle gem" do
it "resolves relative directory" do
create_temporary_dir("tmp/empty/tmp")
- bundle "gem ../../empty", dir: bundled_app("tmp/empty/tmp")
+ bundle "gem ../../empty", :dir => bundled_app("tmp/empty/tmp")
expect(bundled_app("tmp/empty/lib/empty.rb")).to exist
end
@@ -563,12 +557,8 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/bin/setup")).to exist
expect(bundled_app("#{gem_name}/bin/console")).to exist
-
- unless Gem.win_platform?
- expect(bundled_app("#{gem_name}/bin/setup")).to be_executable
- expect(bundled_app("#{gem_name}/bin/console")).to be_executable
- end
-
+ expect(bundled_app("#{gem_name}/bin/setup")).to be_executable
+ expect(bundled_app("#{gem_name}/bin/console")).to be_executable
expect(bundled_app("#{gem_name}/bin/setup").read).to start_with("#!")
expect(bundled_app("#{gem_name}/bin/console").read).to start_with("#!")
end
@@ -659,9 +649,9 @@ RSpec.describe "bundle gem" do
it "runs rake without problems" do
bundle "gem #{gem_name}"
- system_gems ["rake-#{rake_version}"]
+ system_gems ["rake-13.0.1"]
- rakefile = <<~RAKEFILE
+ rakefile = strip_whitespace <<-RAKEFILE
task :default do
puts 'SUCCESS'
end
@@ -670,7 +660,7 @@ RSpec.describe "bundle gem" do
file.puts rakefile
end
- sys_exec(rake, dir: bundled_app(gem_name))
+ sys_exec(rake, :dir => bundled_app(gem_name))
expect(out).to include("SUCCESS")
end
@@ -807,13 +797,17 @@ RSpec.describe "bundle gem" do
end
it "creates a default rake task to run the test suite" do
- rakefile = <<~RAKEFILE
+ rakefile = strip_whitespace <<-RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
- require "minitest/test_task"
+ require "rake/testtask"
- Minitest::TestTask.create
+ Rake::TestTask.new(:test) do |t|
+ t.libs << "test"
+ t.libs << "lib"
+ t.test_files = FileList["test/**/test_*.rb"]
+ end
task default: :test
RAKEFILE
@@ -861,7 +855,7 @@ RSpec.describe "bundle gem" do
end
it "creates a default rake task to run the test suite" do
- rakefile = <<~RAKEFILE
+ rakefile = strip_whitespace <<-RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -880,7 +874,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.test set to rspec and --test with no arguments" do
+ context "gem.test set to rspec and --test with no arguments", :hint_text do
before do
bundle "config set gem.test rspec"
bundle "gem #{gem_name} --test"
@@ -897,12 +891,10 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.test setting set to false and --test with no arguments", :readline do
+ context "gem.test setting set to false and --test with no arguments", :hint_text do
before do
bundle "config set gem.test false"
- bundle "gem #{gem_name} --test" do |input, _, _|
- input.puts
- end
+ bundle "gem #{gem_name} --test"
end
it "asks to generate test files" do
@@ -916,12 +908,9 @@ RSpec.describe "bundle gem" do
it_behaves_like "test framework is absent"
end
- context "gem.test setting not set and --test with no arguments", :readline do
+ context "gem.test setting not set and --test with no arguments", :hint_text do
before do
- global_config "BUNDLE_GEM__TEST" => nil
- bundle "gem #{gem_name} --test" do |input, _, _|
- input.puts
- end
+ bundle "gem #{gem_name} --test"
end
it "asks to generate test files" do
@@ -949,7 +938,7 @@ RSpec.describe "bundle gem" do
context "--ci set to travis" do
it "generates a GitHub Actions config file" do
- bundle "gem #{gem_name} --ci=travis", raise_on_error: false
+ bundle "gem #{gem_name} --ci=travis", :raise_on_error => false
expect(err).to include("Support for Travis CI was removed from gem skeleton generator.")
expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
@@ -958,7 +947,7 @@ RSpec.describe "bundle gem" do
context "--ci set to travis" do
it "generates a GitHub Actions config file" do
- bundle "gem #{gem_name} --ci=travis", raise_on_error: false
+ bundle "gem #{gem_name} --ci=travis", :raise_on_error => false
expect(err).to include("Support for Travis CI was removed from gem skeleton generator.")
expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
@@ -971,12 +960,6 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist
end
-
- it "contained .gitlab-ci.yml into ignore list" do
- bundle "gem #{gem_name} --ci=github"
-
- expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include(".git .github appveyor")
- end
end
context "--ci set to gitlab" do
@@ -985,12 +968,6 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to exist
end
-
- it "contained .gitlab-ci.yml into ignore list" do
- bundle "gem #{gem_name} --ci=gitlab"
-
- expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include(".git .gitlab-ci.yml appveyor")
- end
end
context "--ci set to circle" do
@@ -999,12 +976,6 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/.circleci/config.yml")).to exist
end
-
- it "contained .circleci into ignore list" do
- bundle "gem #{gem_name} --ci=circle"
-
- expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include(".git .circleci appveyor")
- end
end
context "gem.ci setting set to none" do
@@ -1018,7 +989,7 @@ RSpec.describe "bundle gem" do
context "gem.ci setting set to travis" do
it "errors with friendly message" do
bundle "config set gem.ci travis"
- bundle "gem #{gem_name}", raise_on_error: false
+ bundle "gem #{gem_name}", :raise_on_error => false
expect(err).to include("Support for Travis CI was removed from gem skeleton generator,")
expect(err).to include("bundle config unset gem.ci")
@@ -1054,7 +1025,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci set to github and --ci with no arguments" do
+ context "gem.ci set to github and --ci with no arguments", :hint_text do
before do
bundle "config set gem.ci github"
bundle "gem #{gem_name} --ci"
@@ -1069,12 +1040,10 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci setting set to false and --ci with no arguments", :readline do
+ context "gem.ci setting set to false and --ci with no arguments", :hint_text do
before do
bundle "config set gem.ci false"
- bundle "gem #{gem_name} --ci" do |input, _, _|
- input.puts "github"
- end
+ bundle "gem #{gem_name} --ci"
end
it "asks to setup CI" do
@@ -1086,12 +1055,9 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci setting not set and --ci with no arguments", :readline do
+ context "gem.ci setting not set and --ci with no arguments", :hint_text do
before do
- global_config "BUNDLE_GEM__CI" => nil
- bundle "gem #{gem_name} --ci" do |input, _, _|
- input.puts "github"
- end
+ bundle "gem #{gem_name} --ci"
end
it "asks to setup CI" do
@@ -1159,9 +1125,8 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.rubocop setting set to true", bundler: "< 3" do
+ context "gem.rubocop setting set to true", :bundler => "< 3" do
before do
- global_config "BUNDLE_GEM__LINTER" => nil
bundle "config set gem.rubocop true"
bundle "gem #{gem_name}"
end
@@ -1181,7 +1146,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.linter set to rubocop and --linter with no arguments" do
+ context "gem.linter set to rubocop and --linter with no arguments", :hint_text do
before do
bundle "config set gem.linter rubocop"
bundle "gem #{gem_name} --linter"
@@ -1196,12 +1161,10 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.linter setting set to false and --linter with no arguments", :readline do
+ context "gem.linter setting set to false and --linter with no arguments", :hint_text do
before do
bundle "config set gem.linter false"
- bundle "gem #{gem_name} --linter" do |input, _, _|
- input.puts "rubocop"
- end
+ bundle "gem #{gem_name} --linter"
end
it "asks to setup a linter" do
@@ -1213,12 +1176,9 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.linter setting not set and --linter with no arguments", :readline do
+ context "gem.linter setting not set and --linter with no arguments", :hint_text do
before do
- global_config "BUNDLE_GEM__LINTER" => nil
- bundle "gem #{gem_name} --linter" do |input, _, _|
- input.puts "rubocop"
- end
+ bundle "gem #{gem_name} --linter"
end
it "asks to setup a linter" do
@@ -1241,7 +1201,7 @@ RSpec.describe "bundle gem" do
end
end
- context "testing --mit and --coc options against bundle config settings" do
+ context "testing --mit and --coc options against bundle config settings", :readline do
let(:gem_name) { "test-gem" }
let(:require_path) { "test/gem" }
@@ -1344,7 +1304,7 @@ RSpec.describe "bundle gem" do
end
end
- context "testing --github-username option against git and bundle config settings" do
+ context "testing --github-username option against git and bundle config settings", :readline do
context "without git config set" do
before do
sys_exec("git config --global --unset github.user")
@@ -1381,7 +1341,7 @@ RSpec.describe "bundle gem" do
end
end
- context "testing github_username bundle config against git config settings" do
+ context "testing github_username bundle config against git config settings", :readline do
context "without git config set" do
before do
sys_exec("git config --global --unset github.user")
@@ -1395,7 +1355,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem naming with underscore" do
+ context "gem naming with underscore", :readline do
let(:gem_name) { "test_gem" }
let(:require_path) { "test_gem" }
@@ -1417,7 +1377,7 @@ RSpec.describe "bundle gem" do
include_examples "generating a gem"
context "--ext parameter with no value" do
- context "is deprecated", bundler: "< 3" do
+ context "is deprecated", :bundler => "< 3" do
it "prints deprecation when used after gem name" do
bundle ["gem", "--ext", gem_name].compact.join(" ")
expect(err).to include "[DEPRECATED]"
@@ -1459,7 +1419,7 @@ RSpec.describe "bundle gem" do
end
it "depends on compile task for build" do
- rakefile = <<~RAKEFILE
+ rakefile = strip_whitespace <<-RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -1467,9 +1427,7 @@ RSpec.describe "bundle gem" do
task build: :compile
- GEMSPEC = Gem::Specification.load("#{gem_name}.gemspec")
-
- Rake::ExtensionTask.new("#{gem_name}", GEMSPEC) do |ext|
+ Rake::ExtensionTask.new("#{gem_name}") do |ext|
ext.lib_dir = "lib/#{gem_name}"
end
@@ -1519,7 +1477,7 @@ RSpec.describe "bundle gem" do
end
it "depends on compile task for build" do
- rakefile = <<~RAKEFILE
+ rakefile = strip_whitespace <<-RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -1527,9 +1485,7 @@ RSpec.describe "bundle gem" do
task build: :compile
- GEMSPEC = Gem::Specification.load("#{gem_name}.gemspec")
-
- RbSys::ExtensionTask.new("#{gem_name}", GEMSPEC) do |ext|
+ RbSys::ExtensionTask.new("#{gem_name}") do |ext|
ext.lib_dir = "lib/#{gem_name}"
end
@@ -1541,7 +1497,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem naming with dashed" do
+ context "gem naming with dashed", :readline do
let(:gem_name) { "test-gem" }
let(:require_path) { "test/gem" }
@@ -1562,29 +1518,29 @@ RSpec.describe "bundle gem" do
end
describe "uncommon gem names" do
- it "can deal with two dashes" do
+ it "can deal with two dashes", :readline do
bundle "gem a--a"
expect(bundled_app("a--a/a--a.gemspec")).to exist
end
it "fails gracefully with a ." do
- bundle "gem foo.gemspec", raise_on_error: false
+ bundle "gem foo.gemspec", :raise_on_error => false
expect(err).to end_with("Invalid gem name foo.gemspec -- `Foo.gemspec` is an invalid constant name")
end
it "fails gracefully with a ^" do
- bundle "gem ^", raise_on_error: false
+ bundle "gem ^", :raise_on_error => false
expect(err).to end_with("Invalid gem name ^ -- `^` is an invalid constant name")
end
it "fails gracefully with a space" do
- bundle "gem 'foo bar'", raise_on_error: false
+ bundle "gem 'foo bar'", :raise_on_error => false
expect(err).to end_with("Invalid gem name foo bar -- `Foo bar` is an invalid constant name")
end
it "fails gracefully when multiple names are passed" do
- bundle "gem foo bar baz", raise_on_error: false
+ bundle "gem foo bar baz", :raise_on_error => false
expect(err).to eq(<<-E.strip)
ERROR: "bundle gem" was called with arguments ["foo", "bar", "baz"]
Usage: "bundle gem NAME [OPTIONS]"
@@ -1592,9 +1548,9 @@ Usage: "bundle gem NAME [OPTIONS]"
end
end
- describe "#ensure_safe_gem_name" do
+ describe "#ensure_safe_gem_name", :readline do
before do
- bundle "gem #{subject}", raise_on_error: false
+ bundle "gem #{subject}", :raise_on_error => false
end
context "with an existing const name" do
@@ -1620,14 +1576,14 @@ Usage: "bundle gem NAME [OPTIONS]"
context "on first run", :readline do
it "asks about test framework" do
- global_config "BUNDLE_GEM__TEST" => nil
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "rspec"
end
expect(bundled_app("foobar/spec/spec_helper.rb")).to exist
- rakefile = <<~RAKEFILE
+ rakefile = strip_whitespace <<-RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -1643,7 +1599,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CI service" do
- global_config "BUNDLE_GEM__CI" => nil
+ global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "github"
@@ -1653,7 +1609,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about MIT license" do
- global_config "BUNDLE_GEM__MIT" => nil
+ global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "config list"
@@ -1665,7 +1621,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CoC" do
- global_config "BUNDLE_GEM__COC" => nil
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -1675,7 +1631,8 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CHANGELOG" do
- global_config "BUNDLE_GEM__CHANGELOG" => nil
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false",
+ "BUNDLE_GEM__COC" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -1685,16 +1642,16 @@ Usage: "bundle gem NAME [OPTIONS]"
end
end
- context "on conflicts with a previously created file" do
+ context "on conflicts with a previously created file", :readline do
it "should fail gracefully" do
FileUtils.touch(bundled_app("conflict-foobar"))
- bundle "gem conflict-foobar", raise_on_error: false
+ bundle "gem conflict-foobar", :raise_on_error => false
expect(err).to eq("Couldn't create a new gem named `conflict-foobar` because there's an existing file named `conflict-foobar`.")
expect(exitstatus).to eql(32)
end
end
- context "on conflicts with a previously created directory" do
+ context "on conflicts with a previously created directory", :readline do
it "should succeed" do
FileUtils.mkdir_p(bundled_app("conflict-foobar/Gemfile"))
bundle "gem conflict-foobar"
diff --git a/spec/bundler/commands/open_spec.rb b/spec/bundler/commands/open_spec.rb
index 97374f30c3..e30ebfea5b 100644
--- a/spec/bundler/commands/open_spec.rb
+++ b/spec/bundler/commands/open_spec.rb
@@ -10,27 +10,27 @@ RSpec.describe "bundle open" do
end
it "opens the gem with BUNDLER_EDITOR as highest priority" do
- bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
expect(out).to include("bundler_editor #{default_bundle_path("gems", "rails-2.3.2")}")
end
it "opens the gem with VISUAL as 2nd highest priority" do
- bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "" }
expect(out).to include("visual #{default_bundle_path("gems", "rails-2.3.2")}")
end
it "opens the gem with EDITOR as 3rd highest priority" do
- bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "rails-2.3.2")}")
end
it "complains if no EDITOR is set" do
- bundle "open rails", env: { "EDITOR" => "", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", :env => { "EDITOR" => "", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to eq("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR")
end
it "complains if gem not in bundle" do
- bundle "open missing", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ bundle "open missing", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to match(/could not find gem 'missing'/i)
end
@@ -43,91 +43,91 @@ RSpec.describe "bundle open" do
gem 'foo', :git => "#{lib_path("foo-1.0")}"
G
- bundle "open foo", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to include("editor #{default_bundle_path.join("bundler", "gems", "foo-1.0-#{ref}")}")
+ bundle "open foo", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to match("editor #{default_bundle_path.join("bundler/gems/foo-1.0-#{ref}")}")
end
it "suggests alternatives for similar-sounding gems" do
- bundle "open Rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ bundle "open Rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to match(/did you mean rails\?/i)
end
it "opens the gem with short words" do
- bundle "open rec", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open rec", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
end
it "opens subpath of the gem" do
- bundle "open activerecord --path lib/activerecord", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open activerecord --path lib/activerecord", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord")
end
it "opens subpath file of the gem" do
- bundle "open activerecord --path lib/version.rb", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open activerecord --path lib/version.rb", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/version.rb")
end
it "opens deep subpath of the gem" do
- bundle "open activerecord --path lib/active_record", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open activerecord --path lib/active_record", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/active_record")
end
it "requires value for --path arg" do
- bundle "open activerecord --path", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ bundle "open activerecord --path", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to eq "Cannot specify `--path` option without a value"
end
it "suggests alternatives for similar-sounding gems when using subpath" do
- bundle "open Rails --path README.md", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ bundle "open Rails --path README.md", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to match(/did you mean rails\?/i)
end
it "suggests alternatives for similar-sounding gems when using deep subpath" do
- bundle "open Rails --path some/path/here", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ bundle "open Rails --path some/path/here", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to match(/did you mean rails\?/i)
end
it "opens subpath of the short worded gem" do
- bundle "open rec --path CHANGELOG.md", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rec --path CHANGELOG.md", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/CHANGELOG.md")
end
it "opens deep subpath of the short worded gem" do
- bundle "open rec --path lib/activerecord", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rec --path lib/activerecord", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord")
end
it "opens subpath of the selected matching gem", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active --path CHANGELOG.md", env: env do |input, _, _|
+ bundle "open active --path CHANGELOG.md", :env => env do |input, _, _|
input.puts "2"
end
- expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2").join("CHANGELOG.md")}")
+ expect(out).to match(%r{bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}/CHANGELOG\.md\z})
end
it "opens deep subpath of the selected matching gem", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active --path lib/activerecord/version.rb", env: env do |input, _, _|
+ bundle "open active --path lib/activerecord/version.rb", :env => env do |input, _, _|
input.puts "2"
end
- expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2").join("lib", "activerecord", "version.rb")}")
+ expect(out).to match(%r{bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}/lib/activerecord/version\.rb\z})
end
it "select the gem from many match gems", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active", env: env do |input, _, _|
+ bundle "open active", :env => env do |input, _, _|
input.puts "2"
end
- expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
+ expect(out).to match(/bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}\z/)
end
it "allows selecting exit from many match gems", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active", env: env do |input, _, _|
+ bundle "open active", :env => env do |input, _, _|
input.puts "0"
end
end
@@ -140,12 +140,12 @@ RSpec.describe "bundle open" do
G
bundle "config set auto_install 1"
- bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("Installing foo 1.0")
end
it "opens the editor with a clean env" do
- bundle "open", env: { "EDITOR" => "sh -c 'env'", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ bundle "open", :env => { "EDITOR" => "sh -c 'env'", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(out).not_to include("BUNDLE_GEMFILE=")
end
end
@@ -169,7 +169,7 @@ RSpec.describe "bundle open" do
end
it "throws proper error when trying to open default gem" do
- bundle "open json", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open json", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
expect(out).to include("Unable to open json because it's a default gem, so the directory it would normally be installed to does not exist.")
end
end
diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb
index e7edc67e57..bbc3cb54ae 100644
--- a/spec/bundler/commands/outdated_spec.rb
+++ b/spec/bundler/commands/outdated_spec.rb
@@ -4,8 +4,8 @@ RSpec.describe "bundle outdated" do
describe "with no arguments" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -23,11 +23,11 @@ RSpec.describe "bundle outdated" do
update_repo2 do
build_gem "activesupport", "3.0"
build_gem "weakling", "0.2"
- update_git "foo", path: lib_path("foo")
- update_git "zebra", path: lib_path("zebra")
+ update_git "foo", :path => lib_path("foo")
+ update_git "zebra", :path => lib_path("zebra")
end
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
Gem Current Latest Requested Groups
@@ -50,7 +50,7 @@ RSpec.describe "bundle outdated" do
gem "AAA", "1.0.0"
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE
Gem Current Latest Requested Groups
@@ -63,10 +63,10 @@ RSpec.describe "bundle outdated" do
it "returns non zero exit status if outdated gems present" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expect(exitstatus).to_not be_zero
end
@@ -89,7 +89,7 @@ RSpec.describe "bundle outdated" do
update_repo2 { build_gem "activesupport", "3.0" }
update_repo2 { build_gem "terranova", "9" }
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -104,8 +104,8 @@ RSpec.describe "bundle outdated" do
describe "with --verbose option" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -139,7 +139,7 @@ RSpec.describe "bundle outdated" do
gem 'activesupport', '2.3.5'
G
- bundle "outdated --verbose", raise_on_error: false
+ bundle "outdated --verbose", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups Path
@@ -151,7 +151,7 @@ RSpec.describe "bundle outdated" do
end
end
- describe "with multiple, duplicated sources, with lockfile in old format", bundler: "< 3" do
+ describe "with multiple, duplicated sources, with lockfile in old format", :bundler => "< 3" do
before do
build_repo2 do
build_gem "dotenv", "2.7.6"
@@ -205,8 +205,8 @@ RSpec.describe "bundle outdated" do
end
it "works" do
- bundle :install, artifice: "compact_index"
- bundle :outdated, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index"
+ bundle :outdated, :artifice => "compact_index", :raise_on_error => false
expected_output = <<~TABLE
Gem Current Latest Requested Groups
@@ -220,8 +220,8 @@ RSpec.describe "bundle outdated" do
describe "with --group option" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -243,7 +243,7 @@ RSpec.describe "bundle outdated" do
build_gem "duradura", "8.0"
end
- bundle "outdated --group #{group}", raise_on_error: false
+ bundle "outdated --group #{group}", :raise_on_error => false
end
it "works when the bundle is up to date" do
@@ -290,8 +290,8 @@ RSpec.describe "bundle outdated" do
describe "with --groups option and outdated transitive dependencies" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
build_gem "bar", %w[2.0.0]
@@ -312,7 +312,7 @@ RSpec.describe "bundle outdated" do
end
it "returns a sorted list of outdated gems" do
- bundle "outdated --groups", raise_on_error: false
+ bundle "outdated --groups", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -326,8 +326,8 @@ RSpec.describe "bundle outdated" do
describe "with --groups option" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -354,7 +354,7 @@ RSpec.describe "bundle outdated" do
build_gem "duradura", "8.0"
end
- bundle "outdated --groups", raise_on_error: false
+ bundle "outdated --groups", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -370,8 +370,8 @@ RSpec.describe "bundle outdated" do
describe "with --local option" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -398,7 +398,7 @@ RSpec.describe "bundle outdated" do
gem "activesupport", "2.3.4"
G
- bundle "outdated --local", raise_on_error: false
+ bundle "outdated --local", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -420,8 +420,8 @@ RSpec.describe "bundle outdated" do
context "and gems are outdated" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
build_gem "activesupport", "3.0"
build_gem "weakling", "0.2"
@@ -455,13 +455,13 @@ RSpec.describe "bundle outdated" do
end
describe "with --parseable option" do
- subject { bundle "outdated --parseable", raise_on_error: false }
+ subject { bundle "outdated --parseable", :raise_on_error => false }
it_behaves_like "a minimal output is desired"
end
describe "with aliased --porcelain option" do
- subject { bundle "outdated --porcelain", raise_on_error: false }
+ subject { bundle "outdated --porcelain", :raise_on_error => false }
it_behaves_like "a minimal output is desired"
end
@@ -469,8 +469,8 @@ RSpec.describe "bundle outdated" do
describe "with specified gems" do
it "returns list of outdated gems" do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -485,10 +485,10 @@ RSpec.describe "bundle outdated" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
- bundle "outdated foo", raise_on_error: false
+ bundle "outdated foo", :raise_on_error => false
expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
Gem Current Latest Requested Groups
@@ -502,8 +502,8 @@ RSpec.describe "bundle outdated" do
describe "pre-release gems" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -535,7 +535,7 @@ RSpec.describe "bundle outdated" do
build_gem "activesupport", "3.0.0.beta"
end
- bundle "outdated --pre", raise_on_error: false
+ bundle "outdated --pre", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -558,7 +558,7 @@ RSpec.describe "bundle outdated" do
gem "activesupport", "3.0.0.beta.1"
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -573,8 +573,8 @@ RSpec.describe "bundle outdated" do
describe "with --filter-strict option" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -594,7 +594,7 @@ RSpec.describe "bundle outdated" do
build_gem "weakling", "0.0.5"
end
- bundle :outdated, "filter-strict": true, raise_on_error: false
+ bundle :outdated, :"filter-strict" => true, :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -610,7 +610,7 @@ RSpec.describe "bundle outdated" do
build_gem "weakling", "0.0.5"
end
- bundle :outdated, strict: true, raise_on_error: false
+ bundle :outdated, :strict => true, :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -626,7 +626,7 @@ RSpec.describe "bundle outdated" do
gem "activesupport", platforms: [:ruby_22]
G
- bundle :outdated, "filter-strict": true
+ bundle :outdated, :"filter-strict" => true
expect(out).to end_with("Bundle up to date!")
end
@@ -637,7 +637,7 @@ RSpec.describe "bundle outdated" do
gem "rack_middleware", "1.0"
G
- bundle :outdated, "filter-strict": true
+ bundle :outdated, :"filter-strict" => true
expect(out).to end_with("Bundle up to date!")
end
@@ -714,8 +714,8 @@ RSpec.describe "bundle outdated" do
describe "with invalid gem name" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -730,12 +730,12 @@ RSpec.describe "bundle outdated" do
end
it "returns could not find gem name" do
- bundle "outdated invalid_gem_name", raise_on_error: false
+ bundle "outdated invalid_gem_name", :raise_on_error => false
expect(err).to include("Could not find gem 'invalid_gem_name'.")
end
it "returns non-zero exit code" do
- bundle "outdated invalid_gem_name", raise_on_error: false
+ bundle "outdated invalid_gem_name", :raise_on_error => false
expect(exitstatus).to_not be_zero
end
end
@@ -748,11 +748,11 @@ RSpec.describe "bundle outdated" do
G
bundle "config set auto_install 1"
- bundle :outdated, raise_on_error: false
+ bundle :outdated, :raise_on_error => false
expect(out).to include("Installing foo 1.0")
end
- context "after bundle install --deployment", bundler: "< 3" do
+ context "after bundle install --deployment", :bundler => "< 3" do
before do
build_repo2
@@ -763,13 +763,13 @@ RSpec.describe "bundle outdated" do
gem "foo"
G
bundle :lock
- bundle :install, deployment: true
+ bundle :install, :deployment => true
end
it "outputs a helpful message about being in deployment mode" do
update_repo2 { build_gem "activesupport", "3.0" }
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expect(last_command).to be_failure
expect(err).to include("You are trying to check outdated gems in deployment mode.")
expect(err).to include("Run `bundle outdated` elsewhere.")
@@ -781,8 +781,8 @@ RSpec.describe "bundle outdated" do
context "after bundle config set --local deployment true" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -797,7 +797,7 @@ RSpec.describe "bundle outdated" do
it "outputs a helpful message about being in deployment mode" do
update_repo2 { build_gem "activesupport", "3.0" }
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expect(last_command).to be_failure
expect(err).to include("You are trying to check outdated gems in deployment mode.")
expect(err).to include("Run `bundle outdated` elsewhere.")
@@ -843,7 +843,7 @@ RSpec.describe "bundle outdated" do
gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby]
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -867,8 +867,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "major version updates are detected" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -893,8 +893,8 @@ RSpec.describe "bundle outdated" do
context "when on a new machine" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -909,22 +909,22 @@ RSpec.describe "bundle outdated" do
simulate_new_machine
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
update_repo2 do
build_gem "activesupport", "3.3.5"
build_gem "weakling", "0.8.0"
end
end
- subject { bundle "outdated", raise_on_error: false }
+ subject { bundle "outdated", :raise_on_error => false }
it_behaves_like "version update is detected"
end
shared_examples_for "minor version updates are detected" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -949,8 +949,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "patch version updates are detected" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -982,8 +982,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "major version is ignored" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -1008,8 +1008,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "minor version is ignored" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -1034,8 +1034,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "patch version is ignored" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
- build_git "zebra", path: lib_path("zebra")
+ build_git "foo", :path => lib_path("foo")
+ build_git "zebra", :path => lib_path("zebra")
end
install_gemfile <<-G
@@ -1058,7 +1058,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major option" do
- subject { bundle "outdated --filter-major", raise_on_error: false }
+ subject { bundle "outdated --filter-major", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version is ignored"
@@ -1066,7 +1066,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-minor option" do
- subject { bundle "outdated --filter-minor", raise_on_error: false }
+ subject { bundle "outdated --filter-minor", :raise_on_error => false }
it_behaves_like "minor version updates are detected"
it_behaves_like "major version is ignored"
@@ -1074,7 +1074,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-patch option" do
- subject { bundle "outdated --filter-patch", raise_on_error: false }
+ subject { bundle "outdated --filter-patch", :raise_on_error => false }
it_behaves_like "patch version updates are detected"
it_behaves_like "major version is ignored"
@@ -1082,7 +1082,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-minor --filter-patch options" do
- subject { bundle "outdated --filter-minor --filter-patch", raise_on_error: false }
+ subject { bundle "outdated --filter-minor --filter-patch", :raise_on_error => false }
it_behaves_like "minor version updates are detected"
it_behaves_like "patch version updates are detected"
@@ -1090,7 +1090,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-minor options" do
- subject { bundle "outdated --filter-major --filter-minor", raise_on_error: false }
+ subject { bundle "outdated --filter-major --filter-minor", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version updates are detected"
@@ -1098,7 +1098,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-patch options" do
- subject { bundle "outdated --filter-major --filter-patch", raise_on_error: false }
+ subject { bundle "outdated --filter-major --filter-patch", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "patch version updates are detected"
@@ -1106,7 +1106,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-minor --filter-patch options" do
- subject { bundle "outdated --filter-major --filter-minor --filter-patch", raise_on_error: false }
+ subject { bundle "outdated --filter-major --filter-minor --filter-patch", :raise_on_error => false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version updates are detected"
@@ -1145,7 +1145,7 @@ RSpec.describe "bundle outdated" do
end
it "shows all gems when patching and filtering to patch" do
- bundle "outdated --patch --filter-patch", raise_on_error: false
+ bundle "outdated --patch --filter-patch", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1158,7 +1158,7 @@ RSpec.describe "bundle outdated" do
end
it "shows minor and major when updating to minor and filtering to patch and minor" do
- bundle "outdated --minor --filter-minor", raise_on_error: false
+ bundle "outdated --minor --filter-minor", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1170,7 +1170,7 @@ RSpec.describe "bundle outdated" do
end
it "shows minor when updating to major and filtering to minor with parseable" do
- bundle "outdated --major --filter-minor --parseable", raise_on_error: false
+ bundle "outdated --major --filter-minor --parseable", :raise_on_error => false
expect(out).not_to include("patch (newest")
expect(out).to include("minor (newest")
@@ -1212,7 +1212,7 @@ RSpec.describe "bundle outdated" do
end
it "shows gems updating to patch and filtering to patch" do
- bundle "outdated --patch --filter-patch", raise_on_error: false, env: { "DEBUG_RESOLVER" => "1" }
+ bundle "outdated --patch --filter-patch", :raise_on_error => false, :env => { "DEBUG_RESOLVER" => "1" }
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1224,7 +1224,7 @@ RSpec.describe "bundle outdated" do
end
it "shows gems updating to patch and filtering to patch, in debug mode" do
- bundle "outdated --patch --filter-patch", raise_on_error: false, env: { "DEBUG" => "1" }
+ bundle "outdated --patch --filter-patch", :raise_on_error => false, :env => { "DEBUG" => "1" }
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups Path
@@ -1256,7 +1256,7 @@ RSpec.describe "bundle outdated" do
gem 'weakling'
G
- bundle "outdated --only-explicit", raise_on_error: false
+ bundle "outdated --only-explicit", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1306,7 +1306,7 @@ RSpec.describe "bundle outdated" do
end
it "reports a single entry per gem" do
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1355,7 +1355,7 @@ RSpec.describe "bundle outdated" do
end
it "works" do
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
diff --git a/spec/bundler/commands/platform_spec.rb b/spec/bundler/commands/platform_spec.rb
index 61e615acae..688bf7b6df 100644
--- a/spec/bundler/commands/platform_spec.rb
+++ b/spec/bundler/commands/platform_spec.rb
@@ -164,7 +164,7 @@ G
gem "foo"
G
- bundle "platform", raise_on_error: false
+ bundle "platform", :raise_on_error => false
expect(exitstatus).not_to eq(0)
end
@@ -177,7 +177,7 @@ G
gem "foo"
G
- bundle "platform", raise_on_error: false
+ bundle "platform", :raise_on_error => false
expect(exitstatus).not_to eq(0)
end
@@ -190,7 +190,7 @@ G
gem "foo"
G
- bundle "platform", raise_on_error: false
+ bundle "platform", :raise_on_error => false
expect(exitstatus).not_to eq(0)
end
@@ -347,7 +347,7 @@ G
end
it "doesn't install when the ruby version doesn't match" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -359,7 +359,7 @@ G
end
it "doesn't install when engine doesn't match" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -371,7 +371,7 @@ G
end
it "doesn't install when engine version doesn't match", :jruby_only do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -383,7 +383,7 @@ G
end
it "doesn't install when patchlevel doesn't match" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -443,7 +443,7 @@ G
#{ruby_version_incorrect}
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -460,7 +460,7 @@ G
#{engine_incorrect}
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
should_be_engine_incorrect
end
@@ -477,7 +477,7 @@ G
#{engine_version_incorrect}
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
should_be_engine_version_incorrect
end
@@ -494,7 +494,7 @@ G
#{patchlevel_incorrect}
G
- bundle :check, raise_on_error: false
+ bundle :check, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -526,7 +526,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
@@ -546,7 +546,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
@@ -562,7 +562,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update, all: true, raise_on_error: false
+ bundle :update, :all => true, :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -578,7 +578,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update, all: true, raise_on_error: false
+ bundle :update, :all => true, :raise_on_error => false
should_be_engine_incorrect
end
@@ -594,7 +594,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update, all: true, raise_on_error: false
+ bundle :update, :all => true, :raise_on_error => false
should_be_engine_version_incorrect
end
@@ -609,7 +609,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle :update, all: true, raise_on_error: false
+ bundle :update, :all => true, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -646,7 +646,7 @@ G
expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
end
- it "fails if ruby version doesn't match", bundler: "< 3" do
+ it "fails if ruby version doesn't match", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rails"
@@ -654,11 +654,11 @@ G
#{ruby_version_incorrect}
G
- bundle "show rails", raise_on_error: false
+ bundle "show rails", :raise_on_error => false
should_be_ruby_version_incorrect
end
- it "fails if engine doesn't match", bundler: "< 3" do
+ it "fails if engine doesn't match", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rails"
@@ -666,11 +666,11 @@ G
#{engine_incorrect}
G
- bundle "show rails", raise_on_error: false
+ bundle "show rails", :raise_on_error => false
should_be_engine_incorrect
end
- it "fails if engine version doesn't match", bundler: "< 3", jruby_only: true do
+ it "fails if engine version doesn't match", :bundler => "< 3", :jruby_only => true do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rails"
@@ -678,11 +678,11 @@ G
#{engine_version_incorrect}
G
- bundle "show rails", raise_on_error: false
+ bundle "show rails", :raise_on_error => false
should_be_engine_version_incorrect
end
- it "fails when patchlevel doesn't match", bundler: "< 3" do
+ it "fails when patchlevel doesn't match", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -693,7 +693,7 @@ G
build_gem "activesupport", "3.0"
end
- bundle "show rails", raise_on_error: false
+ bundle "show rails", :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -738,7 +738,7 @@ G
#{ruby_version_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -750,7 +750,7 @@ G
#{engine_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_engine_incorrect
end
@@ -762,7 +762,7 @@ G
#{engine_version_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_engine_version_incorrect
end
@@ -774,7 +774,7 @@ G
#{patchlevel_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -819,7 +819,7 @@ G
#{ruby_version_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -831,7 +831,7 @@ G
#{engine_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_engine_incorrect
end
@@ -843,7 +843,7 @@ G
#{engine_version_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_engine_version_incorrect
end
@@ -855,7 +855,7 @@ G
#{patchlevel_incorrect}
G
- bundle :cache, raise_on_error: false
+ bundle :cache, :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -863,7 +863,7 @@ G
context "bundle exec" do
before do
ENV["BUNDLER_FORCE_TTY"] = "true"
- system_gems "rack-1.0.0", "rack-0.9.1", path: default_bundle_path
+ system_gems "rack-1.0.0", "rack-0.9.1", :path => default_bundle_path
end
it "activates the correct gem when ruby version matches" do
@@ -879,7 +879,7 @@ G
end
it "activates the correct gem when ruby version matches any engine", :jruby_only do
- system_gems "rack-1.0.0", "rack-0.9.1", path: default_bundle_path
+ system_gems "rack-1.0.0", "rack-0.9.1", :path => default_bundle_path
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack", "0.9.1"
@@ -899,7 +899,7 @@ G
#{ruby_version_incorrect}
G
- bundle "exec rackup", raise_on_error: false
+ bundle "exec rackup", :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -911,7 +911,7 @@ G
#{engine_incorrect}
G
- bundle "exec rackup", raise_on_error: false
+ bundle "exec rackup", :raise_on_error => false
should_be_engine_incorrect
end
@@ -934,12 +934,12 @@ G
#{patchlevel_incorrect}
G
- bundle "exec rackup", raise_on_error: false
+ bundle "exec rackup", :raise_on_error => false
should_be_patchlevel_incorrect
end
end
- context "bundle console", bundler: "< 3" do
+ context "bundle console", :bundler => "< 3" do
before do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -993,7 +993,7 @@ G
#{ruby_version_incorrect}
G
- bundle "console", raise_on_error: false
+ bundle "console", :raise_on_error => false
should_be_ruby_version_incorrect
end
@@ -1007,7 +1007,7 @@ G
#{engine_incorrect}
G
- bundle "console", raise_on_error: false
+ bundle "console", :raise_on_error => false
should_be_engine_incorrect
end
@@ -1021,7 +1021,7 @@ G
#{engine_version_incorrect}
G
- bundle "console", raise_on_error: false
+ bundle "console", :raise_on_error => false
should_be_engine_version_incorrect
end
@@ -1035,7 +1035,7 @@ G
#{patchlevel_incorrect}
G
- bundle "console", raise_on_error: false
+ bundle "console", :raise_on_error => false
should_be_patchlevel_incorrect
end
end
@@ -1082,7 +1082,7 @@ G
end
it "fails when ruby version doesn't match" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
@@ -1092,14 +1092,14 @@ G
FileUtils.rm(bundled_app_lock)
- ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
expect(bundled_app_lock).not_to exist
should_be_ruby_version_incorrect
end
it "fails when engine doesn't match" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
@@ -1109,14 +1109,14 @@ G
FileUtils.rm(bundled_app_lock)
- ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
expect(bundled_app_lock).not_to exist
should_be_engine_incorrect
end
it "fails when engine version doesn't match", :jruby_only do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
@@ -1126,14 +1126,14 @@ G
FileUtils.rm(bundled_app_lock)
- ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
expect(bundled_app_lock).not_to exist
should_be_engine_version_incorrect
end
it "fails when patchlevel doesn't match" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "yard"
gem "rack"
@@ -1143,7 +1143,7 @@ G
FileUtils.rm(bundled_app_lock)
- ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+ ruby "require 'bundler/setup'", :env => { "BUNDLER_VERSION" => Bundler::VERSION }, :raise_on_error => false
expect(bundled_app_lock).not_to exist
should_be_patchlevel_incorrect
@@ -1153,7 +1153,7 @@ G
context "bundle outdated" do
before do
build_repo2 do
- build_git "foo", path: lib_path("foo")
+ build_git "foo", :path => lib_path("foo")
end
install_gemfile <<-G
@@ -1166,7 +1166,7 @@ G
it "returns list of outdated gems when the ruby version matches" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1177,7 +1177,7 @@ G
#{ruby_version_correct}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
Gem Current Latest Requested Groups
@@ -1192,7 +1192,7 @@ G
bundle :install
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1203,7 +1203,7 @@ G
#{ruby_version_correct_engineless}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
Gem Current Latest Requested Groups
@@ -1217,7 +1217,7 @@ G
it "fails when the ruby version doesn't match" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1228,14 +1228,14 @@ G
#{ruby_version_incorrect}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
should_be_ruby_version_incorrect
end
it "fails when the engine doesn't match" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1246,14 +1246,14 @@ G
#{engine_incorrect}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
should_be_engine_incorrect
end
it "fails when the engine version doesn't match", :jruby_only do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1264,14 +1264,14 @@ G
#{engine_version_incorrect}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
should_be_engine_version_incorrect
end
it "fails when the patchlevel doesn't match", :jruby_only do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1282,14 +1282,14 @@ G
#{patchlevel_incorrect}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
should_be_patchlevel_incorrect
end
it "fails when the patchlevel is a fixnum", :jruby_only do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", path: lib_path("foo")
+ update_git "foo", :path => lib_path("foo")
end
gemfile <<-G
@@ -1300,7 +1300,7 @@ G
#{patchlevel_fixnum}
G
- bundle "outdated", raise_on_error: false
+ bundle "outdated", :raise_on_error => false
should_be_patchlevel_fixnum
end
end
diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb
index 3c7fd3486d..3050b87754 100644
--- a/spec/bundler/commands/post_bundle_message_spec.rb
+++ b/spec/bundler/commands/post_bundle_message_spec.rb
@@ -114,7 +114,7 @@ RSpec.describe "post bundle message" do
end
it "should report a helpful error message" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "not-a-gem", :group => :development
@@ -131,7 +131,7 @@ Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}
G
bundle :cache
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "not-a-gem", :group => :development
@@ -142,7 +142,7 @@ Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}
end
end
- describe "for second bundle install run", bundler: "< 3" do
+ describe "for second bundle install run", :bundler => "< 3" do
it "without any options" do
2.times { bundle :install }
expect(out).to include(bundle_show_message)
@@ -179,25 +179,25 @@ Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}
describe "for bundle update" do
it "shows proper messages according to the configured groups" do
- bundle :update, all: true
+ bundle :update, :all => true
expect(out).not_to include("Gems in the groups")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo"
bundle :install
- bundle :update, all: true
+ bundle :update, :all => true
expect(out).to include("Gems in the group 'emo' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo test"
bundle :install
- bundle :update, all: true
+ bundle :update, :all => true
expect(out).to include("Gems in the groups 'emo' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo obama test"
bundle :install
- bundle :update, all: true
+ bundle :update, :all => true
expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
end
diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb
index 1aec37f850..9e496dc91a 100644
--- a/spec/bundler/commands/pristine_spec.rb
+++ b/spec/bundler/commands/pristine_spec.rb
@@ -4,7 +4,7 @@ require "bundler/vendored_fileutils"
RSpec.describe "bundle pristine" do
before :each do
- build_lib "baz", path: bundled_app do |s|
+ build_lib "baz", :path => bundled_app do |s|
s.version = "1.0.0"
s.add_development_dependency "baz-dev", "=1.0.0"
end
@@ -13,9 +13,9 @@ RSpec.describe "bundle pristine" do
build_gem "weakling"
build_gem "baz-dev", "1.0.0"
build_gem "very_simple_binary", &:add_c_extension
- build_git "foo", path: lib_path("foo")
- build_git "git_with_ext", path: lib_path("git_with_ext"), &:add_c_extension
- build_lib "bar", path: lib_path("bar")
+ build_git "foo", :path => lib_path("foo")
+ build_git "git_with_ext", :path => lib_path("git_with_ext"), &:add_c_extension
+ build_lib "bar", :path => lib_path("bar")
end
install_gemfile <<-G
@@ -164,7 +164,7 @@ RSpec.describe "bundle pristine" do
end
it "raises when one of them is not in the lockfile" do
- bundle "pristine abcabcabc", raise_on_error: false
+ bundle "pristine abcabcabc", :raise_on_error => false
expect(err).to include("Could not find gem 'abcabcabc'.")
end
end
@@ -181,8 +181,8 @@ RSpec.describe "bundle pristine" do
bundle "pristine"
makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
- expect(makefile_contents).to match(/libpath =.*#{Regexp.escape(c_ext_dir.to_s)}/)
- expect(makefile_contents).to match(/LIBPATH =.*-L#{Regexp.escape(c_ext_dir.to_s)}/)
+ expect(makefile_contents).to match(/libpath =.*#{c_ext_dir}/)
+ expect(makefile_contents).to match(/LIBPATH =.*-L#{c_ext_dir}/)
end
end
@@ -198,14 +198,14 @@ RSpec.describe "bundle pristine" do
bundle "pristine"
makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
- expect(makefile_contents).to match(/libpath =.*#{Regexp.escape(c_ext_dir.to_s)}/)
- expect(makefile_contents).to match(/LIBPATH =.*-L#{Regexp.escape(c_ext_dir.to_s)}/)
+ expect(makefile_contents).to match(/libpath =.*#{c_ext_dir}/)
+ expect(makefile_contents).to match(/LIBPATH =.*-L#{c_ext_dir}/)
end
end
context "when BUNDLE_GEMFILE doesn't exist" do
before do
- bundle "pristine", env: { "BUNDLE_GEMFILE" => "does/not/exist" }, raise_on_error: false
+ bundle "pristine", :env => { "BUNDLE_GEMFILE" => "does/not/exist" }, :raise_on_error => false
end
it "shows a meaningful error" do
diff --git a/spec/bundler/commands/remove_spec.rb b/spec/bundler/commands/remove_spec.rb
index 197fcde091..d757e0be4b 100644
--- a/spec/bundler/commands/remove_spec.rb
+++ b/spec/bundler/commands/remove_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe "bundle remove" do
source "#{file_uri_for(gem_repo1)}"
G
- bundle "remove", raise_on_error: false
+ bundle "remove", :raise_on_error => false
expect(err).to include("Please specify gems to remove.")
end
@@ -43,7 +43,7 @@ RSpec.describe "bundle remove" do
end
end
- context "when --install flag is specified", bundler: "< 3" do
+ context "when --install flag is specified", :bundler => "< 3" do
it "removes gems from .bundle" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -109,7 +109,7 @@ RSpec.describe "bundle remove" do
source "#{file_uri_for(gem_repo1)}"
G
- bundle "remove rack", raise_on_error: false
+ bundle "remove rack", :raise_on_error => false
expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
end
@@ -146,7 +146,7 @@ RSpec.describe "bundle remove" do
gem "rspec"
G
- bundle "remove rails rack minitest", raise_on_error: false
+ bundle "remove rails rack minitest", :raise_on_error => false
expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
expect(gemfile).to eq <<~G
@@ -373,7 +373,7 @@ RSpec.describe "bundle remove" do
gem "rack"; gem "rails"
G
- bundle "remove rails", raise_on_error: false
+ bundle "remove rails", :raise_on_error => false
expect(err).to include("Gems could not be removed. rack (>= 0) would also have been removed.")
expect(gemfile).to eq <<~G
@@ -385,7 +385,7 @@ RSpec.describe "bundle remove" do
context "when some gems could not be removed" do
it "shows warning for gems not removed and success for those removed" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem"rack"
gem"rspec"
@@ -491,7 +491,7 @@ RSpec.describe "bundle remove" do
eval_gemfile "Gemfile-other"
G
- bundle "remove rack", raise_on_error: false
+ bundle "remove rack", :raise_on_error => false
expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
end
@@ -510,7 +510,7 @@ RSpec.describe "bundle remove" do
gem "rack"
G
- bundle "remove rack", raise_on_error: false
+ bundle "remove rack", :raise_on_error => false
expect(out).to include("rack was removed.")
expect(err).to include("`rack` is not specified in #{bundled_app("Gemfile-other")} so it could not be removed.")
@@ -535,7 +535,7 @@ RSpec.describe "bundle remove" do
gem "rack"
G
- bundle "remove rack", raise_on_error: false
+ bundle "remove rack", :raise_on_error => false
expect(out).to include("rack was removed.")
expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.")
@@ -560,7 +560,7 @@ RSpec.describe "bundle remove" do
gem "rails"; gem "rack"
G
- bundle "remove rack", raise_on_error: false
+ bundle "remove rack", :raise_on_error => false
expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.")
expect(bundled_app("Gemfile-other").read).to include("gem \"rack\"")
@@ -634,7 +634,7 @@ RSpec.describe "bundle remove" do
context "with gemspec" do
it "should not remove the gem" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("foo.gemspec", "")
s.add_dependency "rack"
end
diff --git a/spec/bundler/commands/show_spec.rb b/spec/bundler/commands/show_spec.rb
index 2b6d4d2d00..1c6244be41 100644
--- a/spec/bundler/commands/show_spec.rb
+++ b/spec/bundler/commands/show_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle show", bundler: "< 3" do
+RSpec.describe "bundle show", :bundler => "< 3" do
context "with a standard Gemfile" do
before :each do
install_gemfile <<-G
@@ -50,14 +50,14 @@ RSpec.describe "bundle show", bundler: "< 3" do
end
it "complains if gem not in bundle" do
- bundle "show missing", raise_on_error: false
+ bundle "show missing", :raise_on_error => false
expect(err).to match(/could not find gem 'missing'/i)
end
it "prints path of all gems in bundle sorted by name" do
bundle "show --paths"
- expect(out).to include(default_bundle_path("gems", "rake-#{rake_version}").to_s)
+ expect(out).to include(default_bundle_path("gems", "rake-13.0.1").to_s)
expect(out).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
# Gem names are the last component of their path.
@@ -104,7 +104,7 @@ RSpec.describe "bundle show", bundler: "< 3" do
end
it "prints out branch names other than main" do
- update_git "foo", branch: "omg" do |s|
+ update_git "foo", :branch => "omg" do |s|
s.write "lib/foo.rb", "FOO = '1.0.omg'"
end
@revision = revision_for(lib_path("foo-1.0"))[0...6]
@@ -129,7 +129,7 @@ RSpec.describe "bundle show", bundler: "< 3" do
end
it "handles when a version is a '-' prerelease" do
- @git = build_git("foo", "1.0.0-beta.1", path: lib_path("foo"))
+ @git = build_git("foo", "1.0.0-beta.1", :path => lib_path("foo"))
install_gemfile <<-G
gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}"
G
@@ -142,13 +142,13 @@ RSpec.describe "bundle show", bundler: "< 3" do
context "in a fresh gem in a blank git repo" do
before :each do
- build_git "foo", path: lib_path("foo")
+ build_git "foo", :path => lib_path("foo")
File.open(lib_path("foo/Gemfile"), "w") {|f| f.puts "gemspec" }
- sys_exec "rm -rf .git && git init", dir: lib_path("foo")
+ sys_exec "rm -rf .git && git init", :dir => lib_path("foo")
end
it "does not output git errors" do
- bundle :show, dir: lib_path("foo")
+ bundle :show, :dir => lib_path("foo")
expect(err_without_deprecations).to be_empty
end
end
@@ -186,7 +186,7 @@ RSpec.describe "bundle show", bundler: "< 3" do
invalid_regexp = "[]"
- bundle "show #{invalid_regexp}", raise_on_error: false
+ bundle "show #{invalid_regexp}", :raise_on_error => false
expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
@@ -219,6 +219,6 @@ RSpec.describe "bundle show", bundler: "< 3" do
end
end
-RSpec.describe "bundle show", bundler: "3" do
+RSpec.describe "bundle show", :bundler => "3" do
pending "shows a friendly error about the command removal"
end
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index 8565e27ebf..84042709bf 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe "bundle update" do
gem "rack-obama"
exit!
G
- bundle "update", raise_on_error: false
+ bundle "update", :raise_on_error => false
expect(bundled_app_lock).to exist
end
end
@@ -60,7 +60,7 @@ RSpec.describe "bundle update" do
build_gem "activesupport", "3.0"
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(out).to include("Bundle updated!")
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
@@ -74,7 +74,7 @@ RSpec.describe "bundle update" do
gem "rack-obama"
exit!
G
- bundle "update", all: true, raise_on_error: false
+ bundle "update", :all => true, :raise_on_error => false
expect(bundled_app_lock).to exist
end
end
@@ -86,7 +86,7 @@ RSpec.describe "bundle update" do
gem "rack", "1.0"
G
- bundle "update --gemfile OmgFile", all: true
+ bundle "update --gemfile OmgFile", :all => true
expect(bundled_app("OmgFile.lock")).to exist
end
@@ -97,13 +97,13 @@ RSpec.describe "bundle update" do
it "errors when passed nothing" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
- bundle :update, raise_on_error: false
+ bundle :update, :raise_on_error => false
expect(err).to eq("To update everything, pass the `--all` flag.")
end
it "errors when passed --all and another option" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
- bundle "update --all foo", raise_on_error: false
+ bundle "update --all foo", :raise_on_error => false
expect(err).to eq("Cannot specify --all along with specific options.")
end
@@ -171,11 +171,11 @@ RSpec.describe "bundle update" do
end
it "should inform the user" do
- bundle "update halting-problem-solver", raise_on_error: false
+ bundle "update halting-problem-solver", :raise_on_error => false
expect(err).to include "Could not find gem 'halting-problem-solver'"
end
it "should suggest alternatives" do
- bundle "update platformspecific", raise_on_error: false
+ bundle "update platformspecific", :raise_on_error => false
expect(err).to include "Did you mean platform_specific?"
end
end
@@ -236,7 +236,7 @@ RSpec.describe "bundle update" do
end
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
end
@@ -275,11 +275,6 @@ RSpec.describe "bundle update" do
gem "countries"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo4, "countries", "3.1.0")
- c.checksum(gem_repo4, "country_select", "5.1.0")
- end
-
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -294,14 +289,14 @@ RSpec.describe "bundle update" do
DEPENDENCIES
countries
country_select
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
previous_lockfile = lockfile
- bundle "lock --update", env: { "DEBUG" => "1" }, verbose: true
+ bundle "lock --update"
expect(lockfile).to eq(previous_lockfile)
end
@@ -439,7 +434,7 @@ RSpec.describe "bundle update" do
build_gem "c", "2.0"
end
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo4)}"
gem "a"
G
@@ -452,7 +447,7 @@ RSpec.describe "bundle update" do
end
end
- bundle "update", all: true, verbose: true
+ bundle "update", :all => true, :verbose => true
expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
end
@@ -510,11 +505,6 @@ RSpec.describe "bundle update" do
original_lockfile = lockfile
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "activesupport", "6.0.4.1"
- c.checksum gem_repo4, "tzinfo", "1.2.9"
- end
-
expected_lockfile = <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -528,7 +518,7 @@ RSpec.describe "bundle update" do
DEPENDENCIES
activesupport (~> 6.0.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -537,10 +527,6 @@ RSpec.describe "bundle update" do
expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
expect(lockfile).to eq(expected_lockfile)
- # needed because regressing to versions already present on the system
- # won't add a checksum
- expected_lockfile = remove_checksums_from_lockfile(expected_lockfile)
-
lockfile original_lockfile
bundle "update"
expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
@@ -557,36 +543,12 @@ RSpec.describe "bundle update" do
before do
build_repo2
- gemfile <<-G
+ install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
gem "platform_specific"
G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- activesupport (2.3.5)
- platform_specific (1.0-#{local_platform})
- rack (1.0.0)
- rack-obama (1.0)
- rack
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- activesupport
- platform_specific
- rack-obama
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- bundle "install"
end
it "doesn't hit repo2" do
@@ -639,7 +601,7 @@ RSpec.describe "bundle update" do
context "when there is a source with the same name as a gem in a group" do
before do
- build_git "foo", path: lib_path("activesupport")
+ build_git "foo", :path => lib_path("activesupport")
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport", :group => :development
@@ -649,7 +611,7 @@ RSpec.describe "bundle update" do
it "should not update the gems from that source" do
update_repo2 { build_gem "activesupport", "3.0" }
- update_git "foo", "2.0", path: lib_path("activesupport")
+ update_git "foo", "2.0", :path => lib_path("activesupport")
bundle "update --group development"
expect(the_bundle).to include_gems "activesupport 3.0"
@@ -691,9 +653,9 @@ RSpec.describe "bundle update" do
G
end
- it "should fail loudly", bundler: "< 3" do
+ it "should fail loudly", :bundler => "< 3" do
bundle "install --deployment"
- bundle "update", all: true, raise_on_error: false
+ bundle "update", :all => true, :raise_on_error => false
expect(last_command).to be_failure
expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/)
@@ -702,20 +664,20 @@ RSpec.describe "bundle update" do
it "should fail loudly when frozen is set globally" do
bundle "config set --global frozen 1"
- bundle "update", all: true, raise_on_error: false
+ bundle "update", :all => true, :raise_on_error => false
expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/).
and match(/freeze by running `bundle config set frozen false`./)
end
it "should fail loudly when deployment is set globally" do
bundle "config set --global deployment true"
- bundle "update", all: true, raise_on_error: false
+ bundle "update", :all => true, :raise_on_error => false
expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/).
and match(/freeze by running `bundle config set frozen false`./)
end
it "should not suggest any command to unfreeze bundler if frozen is set through ENV" do
- bundle "update", all: true, raise_on_error: false, env: { "BUNDLE_FROZEN" => "true" }
+ bundle "update", :all => true, :raise_on_error => false, :env => { "BUNDLE_FROZEN" => "true" }
expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/)
expect(err).not_to match(/by running/)
end
@@ -818,14 +780,14 @@ RSpec.describe "bundle update" do
gem "activesupport"
G
- bundle "update", all: true, verbose: true
+ bundle "update", :all => true, :verbose => true
expect(out).to include("Using activesupport 2.3.5")
update_repo2 do
build_gem "activesupport", "3.0"
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(out).to include("Installing activesupport 3.0 (was 2.3.5)")
end
@@ -841,14 +803,14 @@ RSpec.describe "bundle update" do
gem "foo"
G
- bundle "update", all: true
+ bundle "update", :all => true
expect(out).to match(/Resolving dependencies\.\.\.\.*\nBundle updated!/)
update_repo4 do
build_gem "foo", "2.0"
end
- bundle "update", all: true
+ bundle "update", :all => true
out.sub!("Removing foo (1.0)\n", "")
expect(out).to match(/Resolving dependencies\.\.\.\.*\nFetching foo 2\.0 \(was 1\.0\)\nInstalling foo 2\.0 \(was 1\.0\)\nBundle updated/)
end
@@ -859,96 +821,12 @@ RSpec.describe "bundle update" do
gem "activesupport"
G
- bundle "update nonexisting", raise_on_error: false
+ bundle "update nonexisting", :raise_on_error => false
expect(err).to include("This Bundle hasn't been installed yet. Run `bundle install` to update and install the bundled gems.")
expect(exitstatus).to eq(22)
end
- context "with multiple sources and caching enabled" do
- before do
- build_repo2 do
- build_gem "rack", "1.0.0"
-
- build_gem "request_store", "1.0.0" do |s|
- s.add_dependency "rack", "1.0.0"
- end
- end
-
- build_repo4 do
- # set up repo with no gems
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo2)}"
-
- gem "request_store"
-
- source "#{file_uri_for(gem_repo4)}" do
- end
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- rack (1.0.0)
- request_store (1.0.0)
- rack (= 1.0.0)
-
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- request_store
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "works" do
- bundle :install
- bundle :cache
-
- update_repo2 do
- build_gem "request_store", "1.1.0" do |s|
- s.add_dependency "rack", "1.0.0"
- end
- end
-
- bundle "update request_store"
-
- expect(out).to include("Bundle updated!")
-
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- rack (1.0.0)
- request_store (1.1.0)
- rack (= 1.0.0)
-
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- request_store
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
- context "with multiple, duplicated sources, with lockfile in old format", bundler: "< 3" do
+ context "with multiple, duplicated sources, with lockfile in old format", :bundler => "< 3" do
before do
build_repo2 do
build_gem "dotenv", "2.7.6"
@@ -1002,8 +880,8 @@ RSpec.describe "bundle update" do
end
it "works" do
- bundle :install, artifice: "compact_index"
- bundle "update oj", artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
+ bundle "update oj", :artifice => "compact_index"
expect(out).to include("Bundle updated!")
expect(the_bundle).to include_gems "oj 3.11.5"
@@ -1139,7 +1017,7 @@ RSpec.describe "bundle update in more complicated situations" do
end
it "allows updating" do
- bundle :update, all: true
+ bundle :update, :all => true
expect(the_bundle).to include_gem "a 1.1"
end
@@ -1195,7 +1073,7 @@ RSpec.describe "bundle update without a Gemfile.lock" do
gem "rack", "1.0"
G
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -1218,7 +1096,7 @@ RSpec.describe "bundle update when a gem depends on a newer version of bundler"
end
it "should explain that bundler conflicted and how to resolve the conflict" do
- bundle "update", all: true, raise_on_error: false
+ bundle "update", :all => true, :raise_on_error => false
expect(last_command.stdboth).not_to match(/in snapshot/i)
expect(err).to match(/current Bundler version/i).
and match(/Install the necessary version with `gem install bundler:#{Bundler::VERSION.succ}`/i)
@@ -1234,10 +1112,9 @@ RSpec.describe "bundle update --ruby" do
G
gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo1)}"
G
end
-
it "removes the Ruby from the Gemfile.lock" do
bundle "update --ruby"
@@ -1265,29 +1142,28 @@ RSpec.describe "bundle update --ruby" do
G
gemfile <<-G
- ruby '~> #{current_ruby_minor}'
- source "#{file_uri_for(gem_repo1)}"
+ ruby '~> #{current_ruby_minor}'
+ source "#{file_uri_for(gem_repo1)}"
G
end
-
it "updates the Gemfile.lock with the latest version" do
bundle "update --ruby"
expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo1)}/
- specs:
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
- PLATFORMS
- #{lockfile_platforms}
+ PLATFORMS
+ #{lockfile_platforms}
- DEPENDENCIES
+ DEPENDENCIES
- RUBY VERSION
- #{Bundler::RubyVersion.system}
+ RUBY VERSION
+ #{Bundler::RubyVersion.system}
- BUNDLED WITH
- #{Bundler::VERSION}
+ BUNDLED WITH
+ #{Bundler::VERSION}
L
end
end
@@ -1305,7 +1181,7 @@ RSpec.describe "bundle update --ruby" do
G
end
it "shows a helpful error message" do
- bundle "update --ruby", raise_on_error: false
+ bundle "update --ruby", :raise_on_error => false
expect(err).to include("Your Ruby version is #{Bundler::RubyVersion.system.gem_version}, but your Gemfile specified ~> 2.1.0")
end
@@ -1323,8 +1199,6 @@ RSpec.describe "bundle update --ruby" do
DEPENDENCIES
- CHECKSUMS
-
RUBY VERSION
ruby 2.1.4p222
@@ -1337,7 +1211,6 @@ RSpec.describe "bundle update --ruby" do
source "#{file_uri_for(gem_repo1)}"
G
end
-
it "updates the Gemfile.lock with the latest version" do
bundle "update --ruby"
@@ -1351,8 +1224,6 @@ RSpec.describe "bundle update --ruby" do
DEPENDENCIES
- CHECKSUMS
-
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -1369,32 +1240,13 @@ RSpec.describe "bundle update --bundler" do
build_gem "rack", "1.0"
end
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo4, "rack", "1.0")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "rack"
G
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- rack (1.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- rack
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2')
- bundle :update, bundler: true, artifice: "compact_index", verbose: true
+ bundle :update, :bundler => true, :artifice => "compact_index", :verbose => true
expect(out).to include("Using bundler #{Bundler::VERSION}")
expect(lockfile).to eq <<~L
@@ -1408,7 +1260,7 @@ RSpec.describe "bundle update --bundler" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1429,11 +1281,7 @@ RSpec.describe "bundle update --bundler" do
G
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo4, "rack", "1.0")
- end
-
- bundle :update, bundler: true, artifice: "compact_index", verbose: true
+ bundle :update, :bundler => true, :artifice => "compact_index", :verbose => true
expect(out).to include("Using bundler #{Bundler::VERSION}")
expect(lockfile).to eq <<~L
@@ -1447,7 +1295,7 @@ RSpec.describe "bundle update --bundler" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1455,28 +1303,26 @@ RSpec.describe "bundle update --bundler" do
expect(the_bundle).to include_gem "rack 1.0"
end
- it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo do
+ it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo, :realworld do
pristine_system_gems "bundler-2.3.9"
build_repo4 do
build_gem "rack", "1.0"
-
- build_bundler "999.0.0"
end
- install_gemfile <<-G, artifice: nil, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
+ install_gemfile <<-G, :env => { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
source "#{file_uri_for(gem_repo4)}"
gem "rack"
G
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
- bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle :update, :bundler => true, :artifice => "vcr", :verbose => true, :env => { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
# Only updates properly on modern RubyGems.
if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
- expect(out).to include("Updating bundler to 999.0.0")
- expect(out).to include("Using bundler 999.0.0")
+ expect(out).to include("Updating bundler to 2.3.10")
+ expect(out).to include("Using bundler 2.3.10")
expect(out).not_to include("Installing Bundler 2.3.9 and restarting using that version.")
expect(lockfile).to eq <<~L
@@ -1492,113 +1338,29 @@ RSpec.describe "bundle update --bundler" do
rack
BUNDLED WITH
- 999.0.0
+ 2.3.10
L
- expect(the_bundle).to include_gems "bundler 999.0.0"
- expect(the_bundle).to include_gems "rack 1.0"
- else
- # Old RubyGems versions do not trampoline but they still change BUNDLED
- # WITH to the latest bundler version. This means the below check fails
- # because it tries to use bundler 999.0.0 which did not get installed.
- # Workaround the bug by forcing the version we know is installed.
- expect(the_bundle).to include_gems "rack 1.0", env: { "BUNDLER_VERSION" => "2.3.9" }
- end
- end
-
- it "does not claim to update to Bundler version to a wrong version when cached gems are present" do
- pristine_system_gems "bundler-2.99.0"
-
- build_repo4 do
- build_gem "rack", "3.0.9.1"
-
- build_bundler "2.99.0"
+ expect(the_bundle).to include_gems "bundler 2.3.10"
end
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
- gem "rack"
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- rack (3.0.9.1)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- rack
-
- BUNDLED WITH
- 2.99.0
- L
-
- bundle :cache, verbose: true
-
- bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- expect(out).not_to include("Updating bundler to")
- end
-
- it "does not update the bundler version in the lockfile if the latest version is not compatible with current ruby", :ruby_repo do
- pristine_system_gems "bundler-2.3.9"
-
- build_repo4 do
- build_gem "rack", "1.0"
-
- build_bundler "2.3.9"
- build_bundler "999.0.0" do |s|
- s.required_ruby_version = "> #{Gem.ruby_version}"
- end
- end
-
- install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
- source "#{file_uri_for(gem_repo4)}"
- gem "rack"
- G
- lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
-
- bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
-
- expect(out).to include("Using bundler 2.3.9")
-
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- rack (1.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- rack
-
- BUNDLED WITH
- 2.3.9
- L
-
- expect(the_bundle).to include_gems "bundler 2.3.9"
expect(the_bundle).to include_gems "rack 1.0"
end
- it "errors if the explicit target version does not exist" do
+ it "errors if the explicit target version does not exist", :realworld do
pristine_system_gems "bundler-2.3.9"
build_repo4 do
build_gem "rack", "1.0"
end
- install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
+ install_gemfile <<-G, :env => { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
source "#{file_uri_for(gem_repo4)}"
gem "rack"
G
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
- bundle :update, bundler: "999.999.999", artifice: "compact_index", raise_on_error: false
+ bundle :update, :bundler => "999.999.999", :artifice => "vcr", :raise_on_error => false
# Only gives a meaningful error message on modern RubyGems.
@@ -1620,14 +1382,11 @@ RSpec.describe "bundle update --bundler" do
gem "rack"
G
- bundle :update, bundler: "2.3.0.dev", verbose: "true"
+ bundle :update, :bundler => "2.3.0.dev", :verbose => "true"
# Only updates properly on modern RubyGems.
- if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo4, "rack", "1.0")
- end
+ if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -1639,7 +1398,7 @@ RSpec.describe "bundle update --bundler" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
2.3.0.dev
L
@@ -1660,14 +1419,11 @@ RSpec.describe "bundle update --bundler" do
gem "rack"
G
- bundle :update, bundler: "2.3.9", verbose: true
+ bundle :update, :bundler => "2.3.9", :raise_on_error => false, :verbose => true
expect(out).not_to include("Fetching gem metadata from https://rubygems.org/")
# Only updates properly on modern RubyGems.
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo4, "rack", "1.0")
- end
if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
expect(lockfile).to eq <<~L
@@ -1681,7 +1437,7 @@ RSpec.describe "bundle update --bundler" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
2.3.9
L
@@ -1711,7 +1467,7 @@ RSpec.describe "bundle update --bundler" do
2.1.4
L
- bundle "update --bundler=2.3.9", env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
+ bundle "update --bundler=2.3.9", :env => { "BUNDLE_FROZEN" => "true" }, :raise_on_error => false
expect(err).to include("An update to the version of bundler itself was requested, but the lockfile can't be updated because frozen mode is set")
end
end
@@ -1771,7 +1527,7 @@ RSpec.describe "bundle update conservative" do
end
it "update all" do
- bundle "update --patch", all: true
+ bundle "update --patch", :all => true
expect(the_bundle).to include_gems "foo 1.4.5", "bar 2.1.1", "qux 1.0.1"
end
@@ -1793,7 +1549,7 @@ RSpec.describe "bundle update conservative" do
end
it "minor preferred" do
- bundle "update --minor --strict", all: true
+ bundle "update --minor --strict", :all => true
expect(the_bundle).to include_gems "foo 1.5.0", "bar 2.1.1", "qux 1.1.0"
end
@@ -1872,8 +1628,6 @@ RSpec.describe "bundle update conservative" do
shared_owner_a
shared_owner_b
- CHECKSUMS
-
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1927,13 +1681,6 @@ RSpec.describe "bundle update conservative" do
shared_owner_a
shared_owner_b
- CHECKSUMS
- isolated_dep (2.0.1)
- isolated_owner (1.0.2)
- shared_dep (5.0.1)
- shared_owner_a (3.0.2)
- shared_owner_b (4.0.2)
-
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1954,59 +1701,13 @@ RSpec.describe "bundle update conservative" do
end
end
- context "when Gemfile dependencies have changed" do
- before do
- build_repo4 do
- build_gem "nokogiri", "1.16.4" do |s|
- s.platform = "arm64-darwin"
- end
-
- build_gem "nokogiri", "1.16.4" do |s|
- s.platform = "x86_64-linux"
- end
-
- build_gem "prism", "0.25.0"
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
- gem "nokogiri", ">=1.16.4"
- gem "prism", ">=0.25.0"
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.16.4-arm64-darwin)
- nokogiri (1.16.4-x86_64-linux)
-
- PLATFORMS
- arm64-darwin
- x86_64-linux
-
- DEPENDENCIES
- nokogiri (>= 1.16.4)
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "still works" do
- simulate_platform "arm64-darwin-23" do
- bundle "update"
- end
- end
- end
-
context "error handling" do
before do
gemfile "source \"#{file_uri_for(gem_repo1)}\""
end
it "raises if too many flags are provided" do
- bundle "update --patch --minor", all: true, raise_on_error: false
+ bundle "update --patch --minor", :all => true, :raise_on_error => false
expect(err).to eq "Provide only one of the following options: minor, patch"
end
diff --git a/spec/bundler/commands/version_spec.rb b/spec/bundler/commands/version_spec.rb
index 307058a5dd..53d545f5fa 100644
--- a/spec/bundler/commands/version_spec.rb
+++ b/spec/bundler/commands/version_spec.rb
@@ -4,42 +4,42 @@ require_relative "../support/path"
RSpec.describe "bundle version" do
if Spec::Path.ruby_core?
- COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/
+ COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/.freeze
else
- COMMIT_HASH = /[a-fA-F0-9]{7,}/
+ COMMIT_HASH = /[a-fA-F0-9]{7,}/.freeze
end
context "with -v" do
- it "outputs the version", bundler: "< 3" do
+ it "outputs the version", :bundler => "< 3" do
bundle "-v"
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
- it "outputs the version", bundler: "3" do
+ it "outputs the version", :bundler => "3" do
bundle "-v"
expect(out).to eq(Bundler::VERSION)
end
end
context "with --version" do
- it "outputs the version", bundler: "< 3" do
+ it "outputs the version", :bundler => "< 3" do
bundle "--version"
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
- it "outputs the version", bundler: "3" do
+ it "outputs the version", :bundler => "3" do
bundle "--version"
expect(out).to eq(Bundler::VERSION)
end
end
context "with version" do
- it "outputs the version with build metadata", bundler: "< 3" do
+ it "outputs the version with build metadata", :bundler => "< 3" do
bundle "version"
expect(out).to match(/\ABundler version #{Regexp.escape(Bundler::VERSION)} \(\d{4}-\d{2}-\d{2} commit #{COMMIT_HASH}\)\z/)
end
- it "outputs the version with build metadata", bundler: "3" do
+ it "outputs the version with build metadata", :bundler => "3" do
bundle "version"
expect(out).to match(/\A#{Regexp.escape(Bundler::VERSION)} \(\d{4}-\d{2}-\d{2} commit #{COMMIT_HASH}\)\z/)
end
diff --git a/spec/bundler/commands/viz_spec.rb b/spec/bundler/commands/viz_spec.rb
index f8b5f7836e..cf612397ab 100644
--- a/spec/bundler/commands/viz_spec.rb
+++ b/spec/bundler/commands/viz_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld: true do
+RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot"), :realworld => true do
before do
realworld_system_gems "ruby-graphviz --version 1.2.5"
end
@@ -15,8 +15,8 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld
bundle "viz"
expect(out).to include("gem_graph.png")
- bundle "viz", format: "debug"
- expect(out).to eq(<<~DOT.strip)
+ bundle "viz", :format => "debug"
+ expect(out).to eq(strip_whitespace(<<-DOT).strip)
digraph Gemfile {
concentrate = "true";
normalize = "true";
@@ -49,8 +49,8 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld
bundle "viz"
expect(out).to include("gem_graph.png")
- bundle "viz", format: :debug, version: true
- expect(out).to eq(<<~EOS.strip)
+ bundle "viz", :format => :debug, :version => true
+ expect(out).to eq(strip_whitespace(<<-EOS).strip)
digraph Gemfile {
concentrate = "true";
normalize = "true";
@@ -77,7 +77,7 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld
end
end
- system_gems "graphviz-999", gem_repo: gem_repo4
+ system_gems "graphviz-999", :gem_repo => gem_repo4
end
it "loads the correct ruby-graphviz gem" do
@@ -87,8 +87,8 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld
gem "rack-obama"
G
- bundle "viz", format: "debug"
- expect(out).to eq(<<~DOT.strip)
+ bundle "viz", :format => "debug"
+ expect(out).to eq(strip_whitespace(<<-DOT).strip)
digraph Gemfile {
concentrate = "true";
normalize = "true";
diff --git a/spec/bundler/install/allow_offline_install_spec.rb b/spec/bundler/install/allow_offline_install_spec.rb
index 8da94718e0..4c6c77a61e 100644
--- a/spec/bundler/install/allow_offline_install_spec.rb
+++ b/spec/bundler/install/allow_offline_install_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe "bundle install with :allow_offline_install" do
context "with no cached data locally" do
it "still installs" do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "http://testgemserver.local"
gem "rack-obama"
G
@@ -15,7 +15,7 @@ RSpec.describe "bundle install with :allow_offline_install" do
end
it "still fails when the network is down" do
- install_gemfile <<-G, artifice: "fail", raise_on_error: false
+ install_gemfile <<-G, :artifice => "fail", :raise_on_error => false
source "http://testgemserver.local"
gem "rack-obama"
G
@@ -26,10 +26,10 @@ RSpec.describe "bundle install with :allow_offline_install" do
context "with cached data locally" do
it "will install from the compact index" do
- system_gems ["rack-1.0.0"], path: default_bundle_path
+ system_gems ["rack-1.0.0"], :path => default_bundle_path
bundle "config set clean false"
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "http://testgemserver.local"
gem "rack-obama"
gem "rack", "< 1.0"
@@ -42,7 +42,7 @@ RSpec.describe "bundle install with :allow_offline_install" do
gem "rack-obama"
G
- bundle :update, artifice: "fail", all: true
+ bundle :update, :artifice => "fail", :all => true
expect(last_command.stdboth).to include "Using the cached data for the new index because of a network error"
expect(the_bundle).to include_gems("rack-obama 1.0", "rack 1.0.0")
@@ -51,7 +51,7 @@ RSpec.describe "bundle install with :allow_offline_install" do
def break_git_remote_ops!
FileUtils.mkdir_p(tmp("broken_path"))
File.open(tmp("broken_path/git"), "w", 0o755) do |f|
- f.puts <<~RUBY
+ f.puts strip_whitespace(<<-RUBY)
#!/usr/bin/env ruby
fetch_args = %w(fetch --force --quiet)
clone_args = %w(clone --bare --no-hardlinks --quiet)
@@ -75,14 +75,14 @@ RSpec.describe "bundle install with :allow_offline_install" do
it "will install from a cached git repo" do
skip "doesn't print errors" if Gem.win_platform?
- git = build_git "a", "1.0.0", path: lib_path("a")
- update_git("a", path: git.path, branch: "new_branch")
+ git = build_git "a", "1.0.0", :path => lib_path("a")
+ update_git("a", :path => git.path, :branch => "new_branch")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "a", :git => #{git.path.to_s.dump}
G
- break_git_remote_ops! { bundle :update, all: true }
+ break_git_remote_ops! { bundle :update, :all => true }
expect(err).to include("Using cached git data because of network errors")
expect(the_bundle).to be_locked
diff --git a/spec/bundler/install/bundler_spec.rb b/spec/bundler/install/bundler_spec.rb
index 19911f1154..e7ec3bc7e7 100644
--- a/spec/bundler/install/bundler_spec.rb
+++ b/spec/bundler/install/bundler_spec.rb
@@ -30,13 +30,13 @@ RSpec.describe "bundle install" do
end
it "causes a conflict if explicitly requesting a different version of bundler" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
gem "bundler", "0.9.1"
G
- nice_error = <<~E.strip
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
Could not find compatible versions
Because the current Bundler version (#{Bundler::VERSION}) does not satisfy bundler = 0.9.1
@@ -50,13 +50,13 @@ RSpec.describe "bundle install" do
end
it "causes a conflict if explicitly requesting a non matching requirement on bundler" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
gem "bundler", "~> 0.8"
G
- nice_error = <<~E.strip
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
Could not find compatible versions
Because rails >= 3.0 depends on bundler >= 0.9.0.pre
@@ -73,13 +73,13 @@ RSpec.describe "bundle install" do
end
it "causes a conflict if explicitly requesting a version of bundler that doesn't exist" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rails", "3.0"
gem "bundler", "0.9.2"
G
- nice_error = <<~E.strip
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
Could not find compatible versions
Because the current Bundler version (#{Bundler::VERSION}) does not satisfy bundler = 0.9.2
@@ -143,13 +143,13 @@ RSpec.describe "bundle install" do
end
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "activemerchant"
gem "rails_pinned_to_old_activesupport"
G
- nice_error = <<~E.strip
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
Could not find compatible versions
Because every version of rails_pinned_to_old_activesupport depends on activesupport = 1.2.3
@@ -171,13 +171,13 @@ RSpec.describe "bundle install" do
end
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rails_pinned_to_old_activesupport"
gem "activesupport", "2.3.5"
G
- nice_error = <<~E.strip
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
Could not find compatible versions
Because every version of rails_pinned_to_old_activesupport depends on activesupport = 1.2.3
diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb
index d89fdea6f1..2a88ed5b06 100644
--- a/spec/bundler/install/deploy_spec.rb
+++ b/spec/bundler/install/deploy_spec.rb
@@ -8,26 +8,26 @@ RSpec.describe "install in deployment or frozen mode" do
G
end
- context "with CLI flags", bundler: "< 3" do
+ context "with CLI flags", :bundler => "< 3" do
it "fails without a lockfile and says that --deployment requires a lock" do
- bundle "install --deployment", raise_on_error: false
- expect(err).to include("The --deployment flag requires a lockfile")
+ bundle "install --deployment", :raise_on_error => false
+ expect(err).to include("The --deployment flag requires a Gemfile.lock")
end
it "fails without a lockfile and says that --frozen requires a lock" do
- bundle "install --frozen", raise_on_error: false
- expect(err).to include("The --frozen flag requires a lockfile")
+ bundle "install --frozen", :raise_on_error => false
+ expect(err).to include("The --frozen flag requires a Gemfile.lock")
end
it "disallows --deployment --system" do
- bundle "install --deployment --system", raise_on_error: false
+ bundle "install --deployment --system", :raise_on_error => false
expect(err).to include("You have specified both --deployment")
expect(err).to include("Please choose only one option")
expect(exitstatus).to eq(15)
end
it "disallows --deployment --path --system" do
- bundle "install --deployment --path . --system", raise_on_error: false
+ bundle "install --deployment --path . --system", :raise_on_error => false
expect(err).to include("You have specified both --path")
expect(err).to include("as well as --system")
expect(err).to include("Please choose only one option")
@@ -35,7 +35,7 @@ RSpec.describe "install in deployment or frozen mode" do
end
it "doesn't mess up a subsequent `bundle install` after you try to deploy without a lock" do
- bundle "install --deployment", raise_on_error: false
+ bundle "install --deployment", :raise_on_error => false
bundle :install
expect(the_bundle).to include_gems "rack 1.0"
end
@@ -65,7 +65,7 @@ RSpec.describe "install in deployment or frozen mode" do
gem "rack-obama"
G
- bundle "install --deployment", raise_on_error: false
+ bundle "install --deployment", :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).to include("You have added to the Gemfile")
expect(err).to include("* rack-obama")
@@ -79,7 +79,7 @@ RSpec.describe "install in deployment or frozen mode" do
simulate_new_machine
bundle "config set --local deployment true"
bundle "config set --local path vendor/bundle"
- bundle "install --gemfile #{tmp}/bundled_app/Gemfile", dir: tmp
+ bundle "install --gemfile #{tmp}/bundled_app/Gemfile", :dir => tmp
expect(the_bundle).to include_gems "rack 1.0"
end
@@ -103,12 +103,12 @@ RSpec.describe "install in deployment or frozen mode" do
bundle :install
bundle "config set --local deployment true"
bundle :install
- bundle "exec bundle check", env: { "PATH" => path }
+ bundle "exec bundle check", :env => { "PATH" => path }
end
it "works when using path gems from the same path and the version is specified" do
- build_lib "foo", path: lib_path("nested/foo")
- build_lib "bar", path: lib_path("nested/bar")
+ build_lib "foo", :path => lib_path("nested/foo")
+ build_lib "bar", :path => lib_path("nested/bar")
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0", :path => "#{lib_path("nested")}"
@@ -121,7 +121,7 @@ RSpec.describe "install in deployment or frozen mode" do
end
it "works when path gems are specified twice" do
- build_lib "foo", path: lib_path("nested/foo")
+ build_lib "foo", :path => lib_path("nested/foo")
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("nested/foo")}"
@@ -134,14 +134,14 @@ RSpec.describe "install in deployment or frozen mode" do
end
it "works when there are credentials in the source URL" do
- install_gemfile(<<-G, artifice: "endpoint_strict_basic_authentication", quiet: true)
+ install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
source "http://user:pass@localgemserver.test/"
gem "rack-obama", ">= 1.0"
G
bundle "config set --local deployment true"
- bundle :install, artifice: "endpoint_strict_basic_authentication"
+ bundle :install, :artifice => "endpoint_strict_basic_authentication"
end
it "works with sources given by a block" do
@@ -183,10 +183,50 @@ RSpec.describe "install in deployment or frozen mode" do
bundle "config set --local deployment true"
end
- it "allows the replace" do
- bundle :install
+ it "prevents the replace by default" do
+ bundle :install, :raise_on_error => false
+
+ expect(err).to match(/The list of sources changed/)
+ end
+
+ context "when allow_deployment_source_credential_changes is true" do
+ before { bundle "config set allow_deployment_source_credential_changes true" }
+
+ it "allows the replace" do
+ bundle :install
+
+ expect(out).to match(/Bundle complete!/)
+ end
+ end
+
+ context "when allow_deployment_source_credential_changes is false" do
+ before { bundle "config set allow_deployment_source_credential_changes false" }
- expect(out).to match(/Bundle complete!/)
+ it "prevents the replace" do
+ bundle :install, :raise_on_error => false
+
+ expect(err).to match(/The list of sources changed/)
+ end
+ end
+
+ context "when BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES env var is true" do
+ before { ENV["BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES"] = "true" }
+
+ it "allows the replace" do
+ bundle :install
+
+ expect(out).to match(/Bundle complete!/)
+ end
+ end
+
+ context "when BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES env var is false" do
+ before { ENV["BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES"] = "false" }
+
+ it "prevents the replace" do
+ bundle :install, :raise_on_error => false
+
+ expect(err).to match(/The list of sources changed/)
+ end
end
end
@@ -197,9 +237,7 @@ RSpec.describe "install in deployment or frozen mode" do
it "installs gems by default to vendor/bundle" do
bundle "config set deployment true"
- expect do
- bundle "install"
- end.not_to change { bundled_app_lock.mtime }
+ bundle "install"
expect(out).to include("vendor/bundle")
end
@@ -212,21 +250,17 @@ RSpec.describe "install in deployment or frozen mode" do
it "installs gems to custom path if specified, even when configured through ENV" do
bundle "config set deployment true"
- bundle "install", env: { "BUNDLE_PATH" => "vendor/bundle2" }
+ bundle "install", :env => { "BUNDLE_PATH" => "vendor/bundle2" }
expect(out).to include("vendor/bundle2")
end
it "works with the `frozen` setting" do
bundle "config set frozen true"
- expect do
- bundle "install"
- end.not_to change { bundled_app_lock.mtime }
+ bundle "install"
end
it "works with BUNDLE_FROZEN if you didn't change anything" do
- expect do
- bundle :install, env: { "BUNDLE_FROZEN" => "true" }
- end.not_to change { bundled_app_lock.mtime }
+ bundle :install, :env => { "BUNDLE_FROZEN" => "true" }
end
it "explodes with the `deployment` setting if you make a change and don't check in the lockfile" do
@@ -237,7 +271,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).to include("You have added to the Gemfile")
expect(err).to include("* rack-obama")
@@ -258,7 +292,7 @@ RSpec.describe "install in deployment or frozen mode" do
bundle "config set --local path .bundle"
bundle "config set --local without development"
bundle "config set --local deployment true"
- bundle :install, env: { "DEBUG" => "1" }
+ bundle :install, :env => { "DEBUG" => "1" }
run "puts :WIN"
expect(out).to eq("WIN")
end
@@ -274,7 +308,7 @@ RSpec.describe "install in deployment or frozen mode" do
end
G
- bundle :install, env: { "BUNDLE_FROZEN" => "true" }
+ bundle :install, :env => { "BUNDLE_FROZEN" => "true" }
expect(last_command).to be_success
end
@@ -308,7 +342,7 @@ RSpec.describe "install in deployment or frozen mode" do
#{Bundler::VERSION}
L
- bundle :install, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false, artifice: "compact_index"
+ bundle :install, :env => { "BUNDLE_FROZEN" => "true" }, :raise_on_error => false, :artifice => "compact_index"
expect(err).to include("Your lock file is missing \"bar\", but the lockfile can't be updated because frozen mode is set")
end
@@ -324,7 +358,7 @@ RSpec.describe "install in deployment or frozen mode" do
bundle "config set --local path .bundle"
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("The path `#{lib_path("path_gem-1.0")}` does not exist.")
end
@@ -336,7 +370,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
ENV["BUNDLE_FROZEN"] = "1"
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).to include("You have added to the Gemfile")
expect(err).to include("* rack-obama")
@@ -352,7 +386,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
ENV["BUNDLE_DEPLOYMENT"] = "true"
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).to include("You have added to the Gemfile")
expect(err).to include("* rack-obama")
@@ -395,7 +429,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).to include("You have added to the Gemfile:\n* activesupport\n\n")
expect(err).to include("You have deleted from the Gemfile:\n* rack")
@@ -409,7 +443,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).not_to include("You have added to the Gemfile")
expect(err).to include("You have changed in the Gemfile:\n* rack from `no specified source` to `git://hubz.com`")
@@ -429,7 +463,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).not_to include("You have deleted from the Gemfile")
expect(err).not_to include("You have added to the Gemfile")
@@ -437,8 +471,8 @@ RSpec.describe "install in deployment or frozen mode" do
end
it "explodes if you change a source" do
- build_lib "foo", path: lib_path("rack/foo")
- build_git "rack", path: lib_path("rack")
+ build_lib "foo", :path => lib_path("rack/foo")
+ build_git "rack", :path => lib_path("rack")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -453,7 +487,7 @@ RSpec.describe "install in deployment or frozen mode" do
G
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("frozen mode")
expect(err).to include("You have changed in the Gemfile:\n* rack from `#{lib_path("rack")}` to `no specified source`")
expect(err).not_to include("You have added to the Gemfile")
@@ -471,23 +505,23 @@ RSpec.describe "install in deployment or frozen mode" do
gem "rack-obama"
G
- run "require 'rack'", raise_on_error: false
- expect(err).to include <<~E.strip
- The dependencies in your gemfile changed, but the lockfile can't be updated because frozen mode is set (Bundler::ProductionError)
+ run "require 'rack'", :raise_on_error => false
+ expect(err).to include strip_whitespace(<<-E).strip
+The dependencies in your gemfile changed, but the lockfile can't be updated because frozen mode is set (Bundler::ProductionError)
- You have added to the Gemfile:
- * rack (= 1.0.0)
- * rack-obama
+You have added to the Gemfile:
+* rack (= 1.0.0)
+* rack-obama
- You have deleted from the Gemfile:
- * rack
+You have deleted from the Gemfile:
+* rack
E
end
end
context "with path in Gemfile and packed" do
it "works fine after bundle package and bundle install --local" do
- build_lib "foo", path: lib_path("foo")
+ build_lib "foo", :path => lib_path("foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo")}"
diff --git a/spec/bundler/install/failure_spec.rb b/spec/bundler/install/failure_spec.rb
index f972a37bf6..4a9c33754f 100644
--- a/spec/bundler/install/failure_spec.rb
+++ b/spec/bundler/install/failure_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe "bundle install" do
end
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rails"
G
@@ -39,7 +39,7 @@ In Gemfile:
end
it "removes the downloaded .gem" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo4)}"
gem "a"
G
diff --git a/spec/bundler/install/gemfile/eval_gemfile_spec.rb b/spec/bundler/install/gemfile/eval_gemfile_spec.rb
index cfa66e5986..02283291b4 100644
--- a/spec/bundler/install/gemfile/eval_gemfile_spec.rb
+++ b/spec/bundler/install/gemfile/eval_gemfile_spec.rb
@@ -2,7 +2,7 @@
RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
before do
- build_lib("gunks", path: bundled_app.join("gems/gunks")) do |s|
+ build_lib("gunks", :path => bundled_app.join("gems/gunks")) do |s|
s.name = "gunks"
s.version = "0.0.1"
end
@@ -24,7 +24,7 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
expect(out).to include("Resolving dependencies")
expect(out).to include("Bundle complete")
- expect(the_bundle).to include_gem "gunks 0.0.1", source: "path@#{bundled_app("gems", "gunks")}"
+ expect(the_bundle).to include_gem "gunks 0.0.1", :source => "path@#{bundled_app("gems", "gunks")}"
end
end
@@ -64,7 +64,7 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
context "eval-ed Gemfile has relative-path gems" do
before do
- build_lib("a", path: bundled_app("gems/a"))
+ build_lib("a", :path => bundled_app("gems/a"))
create_file bundled_app("nested/Gemfile-nested"), <<-G
source "#{file_uri_for(gem_repo1)}"
gem "a", :path => "../gems/a"
@@ -102,7 +102,7 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
expect(out).to include("Resolving dependencies")
expect(out).to include("Bundle complete")
- expect(the_bundle).to include_gem "gunks 0.0.1", source: "path@#{bundled_app("gems", "gunks")}"
+ expect(the_bundle).to include_gem "gunks 0.0.1", :source => "path@#{bundled_app("gems", "gunks")}"
end
end
diff --git a/spec/bundler/install/gemfile/force_ruby_platform_spec.rb b/spec/bundler/install/gemfile/force_ruby_platform_spec.rb
index a29b79ad62..0e9f1f0292 100644
--- a/spec/bundler/install/gemfile/force_ruby_platform_spec.rb
+++ b/spec/bundler/install/gemfile/force_ruby_platform_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do
end
it "still respects a global `force_ruby_platform` config" do
- install_gemfile <<-G, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
+ install_gemfile <<-G, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
source "#{file_uri_for(gem_repo4)}"
gem "platform_specific_forced", :force_ruby_platform => true
@@ -105,7 +105,7 @@ RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do
end
it "ignores ruby variants for the transitive dependencies" do
- install_gemfile <<-G, env: { "DEBUG_RESOLVER" => "true" }
+ install_gemfile <<-G, :env => { "DEBUG_RESOLVER" => "true" }
source "#{file_uri_for(gem_repo4)}"
gem "depends_on_platform_specific", :force_ruby_platform => true
@@ -114,33 +114,5 @@ RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do
expect(the_bundle).to include_gems "depends_on_platform_specific 1.0.0 RUBY"
expect(the_bundle).to include_gems "platform_specific 1.0.0 #{Bundler.local_platform}"
end
-
- it "reinstalls the ruby variant when a platform specific variant is already installed, the lockile has only RUBY platform, and :force_ruby_platform is used in the Gemfile" do
- lockfile <<-L
- GEM
- remote: #{file_uri_for(gem_repo4)}
- specs:
- platform_specific (1.0)
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
- platform_specific
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- system_gems "platform_specific-1.0-#{Gem::Platform.local}", path: default_bundle_path
-
- install_gemfile <<-G, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, artifice: "compact_index"
- source "#{file_uri_for(gem_repo4)}"
-
- gem "platform_specific", :force_ruby_platform => true
- G
-
- expect(the_bundle).to include_gems "platform_specific 1.0.0 RUBY"
- end
end
end
diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb
index 63778567cf..73f04f071d 100644
--- a/spec/bundler/install/gemfile/gemspec_spec.rb
+++ b/spec/bundler/install/gemfile/gemspec_spec.rb
@@ -28,18 +28,8 @@ RSpec.describe "bundle install from an existing gemspec" do
x64_mingw_archs.join("\n ")
end
- def x64_mingw_checksums(checksums)
- x64_mingw_archs.each do |arch|
- if arch == "x64-mingw-ucrt"
- checksums.no_checksum "platform_specific", "1.0", arch
- else
- checksums.checksum gem_repo2, "platform_specific", "1.0", arch
- end
- end
- end
-
it "should install runtime and development dependencies" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("Gemfile", "source :rubygems\ngemspec")
s.add_dependency "bar", "=1.0.0"
s.add_development_dependency "bar-dev", "=1.0.0"
@@ -50,11 +40,11 @@ RSpec.describe "bundle install from an existing gemspec" do
G
expect(the_bundle).to include_gems "bar 1.0.0"
- expect(the_bundle).to include_gems "bar-dev 1.0.0", groups: :development
+ expect(the_bundle).to include_gems "bar-dev 1.0.0", :groups => :development
end
it "that is hidden should install runtime and development dependencies" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("Gemfile", "source :rubygems\ngemspec")
s.add_dependency "bar", "=1.0.0"
s.add_development_dependency "bar-dev", "=1.0.0"
@@ -67,7 +57,7 @@ RSpec.describe "bundle install from an existing gemspec" do
G
expect(the_bundle).to include_gems "bar 1.0.0"
- expect(the_bundle).to include_gems "bar-dev 1.0.0", groups: :development
+ expect(the_bundle).to include_gems "bar-dev 1.0.0", :groups => :development
end
it "should handle a list of requirements" do
@@ -76,7 +66,7 @@ RSpec.describe "bundle install from an existing gemspec" do
build_gem "baz", "1.1"
end
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("Gemfile", "source :rubygems\ngemspec")
s.add_dependency "baz", ">= 1.0", "< 1.1"
end
@@ -89,29 +79,29 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "should raise if there are no gemspecs available" do
- build_lib("foo", path: tmp.join("foo"), gemspec: false)
+ build_lib("foo", :path => tmp.join("foo"), :gemspec => false)
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
- expect(err).to match(/There are no gemspecs at #{tmp.join("foo")}/)
+ expect(err).to match(/There are no gemspecs at #{tmp.join('foo')}/)
end
it "should raise if there are too many gemspecs available" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("foo2.gemspec", build_spec("foo", "4.0").first.to_ruby)
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gemspec :path => '#{tmp.join("foo")}'
G
- expect(err).to match(/There are multiple gemspecs at #{tmp.join("foo")}/)
+ expect(err).to match(/There are multiple gemspecs at #{tmp.join('foo')}/)
end
it "should pick a specific gemspec" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("foo2.gemspec", "")
s.add_dependency "bar", "=1.0.0"
s.add_development_dependency "bar-dev", "=1.0.0"
@@ -123,11 +113,11 @@ RSpec.describe "bundle install from an existing gemspec" do
G
expect(the_bundle).to include_gems "bar 1.0.0"
- expect(the_bundle).to include_gems "bar-dev 1.0.0", groups: :development
+ expect(the_bundle).to include_gems "bar-dev 1.0.0", :groups => :development
end
it "should use a specific group for development dependencies" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("foo2.gemspec", "")
s.add_dependency "bar", "=1.0.0"
s.add_development_dependency "bar-dev", "=1.0.0"
@@ -139,32 +129,32 @@ RSpec.describe "bundle install from an existing gemspec" do
G
expect(the_bundle).to include_gems "bar 1.0.0"
- expect(the_bundle).not_to include_gems "bar-dev 1.0.0", groups: :development
- expect(the_bundle).to include_gems "bar-dev 1.0.0", groups: :dev
+ expect(the_bundle).not_to include_gems "bar-dev 1.0.0", :groups => :development
+ expect(the_bundle).to include_gems "bar-dev 1.0.0", :groups => :dev
end
it "should match a lockfile even if the gemspec defines development dependencies" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("Gemfile", "source '#{file_uri_for(gem_repo1)}'\ngemspec")
s.add_dependency "actionpack", "=2.3.2"
- s.add_development_dependency "rake", rake_version
+ s.add_development_dependency "rake", "=13.0.1"
end
- bundle "install", dir: tmp.join("foo")
+ bundle "install", :dir => tmp.join("foo")
# This should really be able to rely on $stderr, but, it's not written
# right, so we can't. In fact, this is a bug negation test, and so it'll
# ghost pass in future, and will only catch a regression if the message
# doesn't change. Exit codes should be used correctly (they can be more
# than just 0 and 1).
bundle "config set --local deployment true"
- output = bundle("install", dir: tmp.join("foo"))
+ output = bundle("install", :dir => tmp.join("foo"))
expect(output).not_to match(/You have added to the Gemfile/)
expect(output).not_to match(/You have deleted from the Gemfile/)
expect(output).not_to match(/the lockfile can't be updated because frozen mode is set/)
end
it "should match a lockfile without needing to re-resolve" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack"
end
@@ -173,7 +163,7 @@ RSpec.describe "bundle install from an existing gemspec" do
gemspec :path => '#{tmp.join("foo")}'
G
- bundle "install", verbose: true
+ bundle "install", :verbose => true
message = "Found no changes, using resolution from the lockfile"
expect(out.scan(message).size).to eq(1)
@@ -182,7 +172,7 @@ RSpec.describe "bundle install from an existing gemspec" do
it "should match a lockfile without needing to re-resolve with development dependencies" do
simulate_platform java
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack"
s.add_development_dependency "thin"
end
@@ -192,34 +182,34 @@ RSpec.describe "bundle install from an existing gemspec" do
gemspec :path => '#{tmp.join("foo")}'
G
- bundle "install", verbose: true
+ bundle "install", :verbose => true
message = "Found no changes, using resolution from the lockfile"
expect(out.scan(message).size).to eq(1)
end
it "should match a lockfile on non-ruby platforms with a transitive platform dependency", :jruby_only do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "platform_specific"
end
- system_gems "platform_specific-1.0-java", path: default_bundle_path
+ system_gems "platform_specific-1.0-java", :path => default_bundle_path
install_gemfile <<-G
gemspec :path => '#{tmp.join("foo")}'
G
- bundle "update --bundler", artifice: "compact_index", verbose: true
+ bundle "update --bundler", :artifice => "compact_index", :verbose => true
expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 JAVA"
end
it "should evaluate the gemspec in its directory" do
- build_lib("foo", path: tmp.join("foo"))
+ build_lib("foo", :path => tmp.join("foo"))
File.open(tmp.join("foo/foo.gemspec"), "w") do |s|
s.write "raise 'ahh' unless Dir.pwd == '#{tmp.join("foo")}'"
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
gemspec :path => '#{tmp.join("foo")}'
G
expect(last_command.stdboth).not_to include("ahh")
@@ -233,7 +223,7 @@ RSpec.describe "bundle install from an existing gemspec" do
# so emulate that
system_gems %w[rack-1.0.0 rack-0.9.1 rack-obama-1.0]
- build_lib("foo", path: bundled_app)
+ build_lib("foo", :path => bundled_app)
gemspec = bundled_app("foo.gemspec").read
bundled_app("foo.gemspec").open("w") do |f|
f.write "#{gemspec.strip}.tap { gem 'rack-obama'; require 'rack/obama' }"
@@ -248,14 +238,14 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "allows conflicts" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.version = "1.0.0"
s.add_dependency "bar", "= 1.0.0"
end
- build_gem "deps", to_bundle: true do |s|
+ build_gem "deps", :to_bundle => true do |s|
s.add_dependency "foo", "= 0.0.1"
end
- build_gem "foo", "0.0.1", to_bundle: true
+ build_gem "foo", "0.0.1", :to_bundle => true
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
@@ -267,7 +257,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "does not break Gem.finish_resolve with conflicts" do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.version = "1.0.0"
s.add_dependency "bar", "= 1.0.0"
end
@@ -291,14 +281,14 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "handles downgrades" do
- build_lib "omg", "2.0", path: lib_path("omg")
+ build_lib "omg", "2.0", :path => lib_path("omg")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gemspec :path => "#{lib_path("omg")}"
G
- build_lib "omg", "1.0", path: lib_path("omg")
+ build_lib "omg", "1.0", :path => lib_path("omg")
bundle :install
@@ -308,7 +298,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "in deployment mode" do
context "when the lockfile was not updated after a change to the gemspec's dependencies" do
it "reports that installation failed" do
- build_lib "cocoapods", path: bundled_app do |s|
+ build_lib "cocoapods", :path => bundled_app do |s|
s.add_dependency "activesupport", ">= 1"
end
@@ -319,12 +309,12 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(the_bundle).to include_gems("cocoapods 1.0", "activesupport 2.3.5")
- build_lib "cocoapods", path: bundled_app do |s|
+ build_lib "cocoapods", :path => bundled_app do |s|
s.add_dependency "activesupport", ">= 1.0.1"
end
bundle "config set --local deployment true"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("changed")
end
@@ -334,13 +324,13 @@ RSpec.describe "bundle install from an existing gemspec" do
context "when child gemspecs conflict with a released gemspec" do
before do
# build the "parent" gem that depends on another gem in the same repo
- build_lib "source_conflict", path: bundled_app do |s|
+ build_lib "source_conflict", :path => bundled_app do |s|
s.add_dependency "rack_middleware"
end
# build the "child" gem that is the same version as a released gem, but
# has completely different and conflicting dependency requirements
- build_lib "rack_middleware", "1.0", path: bundled_app("rack_middleware") do |s|
+ build_lib "rack_middleware", "1.0", :path => bundled_app("rack_middleware") do |s|
s.add_dependency "rack", "1.0" # anything other than 0.9.1
end
end
@@ -359,7 +349,7 @@ RSpec.describe "bundle install from an existing gemspec" do
let(:source_uri) { "http://localgemserver.test" }
before do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack", "=1.0.0"
end
@@ -368,10 +358,6 @@ RSpec.describe "bundle install from an existing gemspec" do
gemspec :path => "../foo"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
lockfile <<-L
PATH
remote: ../foo
@@ -389,7 +375,7 @@ RSpec.describe "bundle install from an existing gemspec" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -408,14 +394,14 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "should install" do
- results = bundle "install", artifice: "endpoint"
+ results = bundle "install", :artifice => "endpoint"
expect(results).to include("Installing rack 1.0.0")
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
it "should install", :jruby do
- results = bundle "install", artifice: "endpoint"
+ results = bundle "install", :artifice => "endpoint"
expect(results).to include("Installing rack 1.0.0")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -430,7 +416,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end
end
- build_lib "foo", path: bundled_app do |s|
+ build_lib "foo", :path => bundled_app do |s|
if platform_specific_type == :runtime
s.add_runtime_dependency dependency
elsif platform_specific_type == :development
@@ -462,15 +448,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "as a runtime dependency" do
it "keeps all platform dependencies in the lockfile" do
expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY"
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo2, "platform_specific", "1.0"
- c.checksum gem_repo2, "platform_specific", "1.0", "java"
- x64_mingw_checksums(c)
- end
-
- expect(lockfile).to eq <<~L
+ expect(lockfile).to eq strip_whitespace(<<-L)
PATH
remote: .
specs:
@@ -491,7 +469,7 @@ RSpec.describe "bundle install from an existing gemspec" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -503,15 +481,7 @@ RSpec.describe "bundle install from an existing gemspec" do
it "keeps all platform dependencies in the lockfile" do
expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY"
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo2, "platform_specific", "1.0"
- c.checksum gem_repo2, "platform_specific", "1.0", "java"
- x64_mingw_checksums(c)
- end
-
- expect(lockfile).to eq <<~L
+ expect(lockfile).to eq strip_whitespace(<<-L)
PATH
remote: .
specs:
@@ -532,7 +502,7 @@ RSpec.describe "bundle install from an existing gemspec" do
DEPENDENCIES
foo!
platform_specific
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -545,16 +515,7 @@ RSpec.describe "bundle install from an existing gemspec" do
it "keeps all platform dependencies in the lockfile" do
expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY"
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo2, "indirect_platform_specific", "1.0"
- c.checksum gem_repo2, "platform_specific", "1.0"
- c.checksum gem_repo2, "platform_specific", "1.0", "java"
- x64_mingw_checksums(c)
- end
-
- expect(lockfile).to eq <<~L
+ expect(lockfile).to eq strip_whitespace(<<-L)
PATH
remote: .
specs:
@@ -577,7 +538,7 @@ RSpec.describe "bundle install from an existing gemspec" do
DEPENDENCIES
foo!
indirect_platform_specific
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -589,7 +550,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "with multiple platforms" do
before do
- build_lib("foo", path: tmp.join("foo")) do |s|
+ build_lib("foo", :path => tmp.join("foo")) do |s|
s.version = "1.0.0"
s.add_development_dependency "rack"
s.write "foo-universal-java.gemspec", build_spec("foo", "1.0.0", "universal-java") {|sj| sj.runtime "rack", "1.0.0" }.first.to_ruby
@@ -623,7 +584,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "with multiple platforms and resolving for more specific platforms" do
before do
- build_lib("chef", path: tmp.join("chef")) do |s|
+ build_lib("chef", :path => tmp.join("chef")) do |s|
s.version = "17.1.17"
s.write "chef-universal-mingw32.gemspec", build_spec("chef", "17.1.17", "universal-mingw32") {|sw| sw.runtime "win32-api", "~> 1.5.3" }.first.to_ruby
end
@@ -641,12 +602,6 @@ RSpec.describe "bundle install from an existing gemspec" do
gemspec :path => "../chef"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "chef", "17.1.17"
- c.no_checksum "chef", "17.1.17", "universal-mingw32"
- c.checksum gem_repo4, "win32-api", "1.5.3", "universal-mingw32"
- end
-
initial_lockfile = <<~L
PATH
remote: ../chef
@@ -667,7 +622,7 @@ RSpec.describe "bundle install from an existing gemspec" do
DEPENDENCIES
chef!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -682,7 +637,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "with multiple locked platforms" do
before do
- build_lib("activeadmin", path: tmp.join("activeadmin")) do |s|
+ build_lib("activeadmin", :path => tmp.join("activeadmin")) do |s|
s.version = "2.9.0"
s.add_dependency "railties", ">= 5.2", "< 6.2"
end
@@ -705,12 +660,6 @@ RSpec.describe "bundle install from an existing gemspec" do
end
it "does not remove the platform specific specs from the lockfile when re-resolving due to gemspec changes" do
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "activeadmin", "2.9.0"
- c.no_checksum "jruby-openssl", "0.10.7", "java"
- c.checksum gem_repo4, "railties", "6.1.4"
- end
-
expect(lockfile).to eq <<~L
PATH
remote: ../activeadmin
@@ -730,7 +679,7 @@ RSpec.describe "bundle install from an existing gemspec" do
DEPENDENCIES
activeadmin!
jruby-openssl
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb
index 24cf30eadb..910f96f4ab 100644
--- a/spec/bundler/install/gemfile/git_spec.rb
+++ b/spec/bundler/install/gemfile/git_spec.rb
@@ -26,8 +26,8 @@ RSpec.describe "bundle install with git sources" do
expect(out).to eq("WIN")
end
- it "caches the git repo", bundler: "< 3" do
- expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"]).to have_attributes size: 1
+ it "caches the git repo", :bundler => "< 3" do
+ expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"]).to have_attributes :size => 1
end
it "does not write to cache on bundler/setup" do
@@ -41,7 +41,7 @@ RSpec.describe "bundle install with git sources" do
simulate_new_machine
bundle "config set global_gem_cache true"
bundle :install
- expect(Dir["#{home}/.bundle/cache/git/foo-1.0-*"]).to have_attributes size: 1
+ expect(Dir["#{home}/.bundle/cache/git/foo-1.0-*"]).to have_attributes :size => 1
bundle "install --verbose"
expect(err).to be_empty
@@ -69,7 +69,7 @@ RSpec.describe "bundle install with git sources" do
it "does not update the git source implicitly" do
update_git "foo"
- install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2
+ install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem 'foo'
@@ -92,7 +92,7 @@ RSpec.describe "bundle install with git sources" do
it "complains if pinned specs don't exist in the git repo" do
build_git "foo"
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.1", :git => "#{lib_path("foo-1.0")}"
G
@@ -105,7 +105,7 @@ RSpec.describe "bundle install with git sources" do
s.platform = "java"
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
platforms :jruby do
gem "only_java", "1.2", :git => "#{lib_path("only_java-1.0-java")}"
@@ -125,7 +125,7 @@ RSpec.describe "bundle install with git sources" do
s.write "only_java1-0.gemspec", File.read("#{lib_path("only_java-1.0-java")}/only_java.gemspec")
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
platforms :jruby do
gem "only_java", "1.2", :git => "#{lib_path("only_java-1.1-java")}"
@@ -141,7 +141,7 @@ RSpec.describe "bundle install with git sources" do
FileUtils.mv bundled_app, tmp("bundled_app.bck")
- expect(the_bundle).to include_gems "foo 1.0", dir: tmp("bundled_app.bck")
+ expect(the_bundle).to include_gems "foo 1.0", :dir => tmp("bundled_app.bck")
end
it "can still install after moving the application directory" do
@@ -150,7 +150,7 @@ RSpec.describe "bundle install with git sources" do
FileUtils.mv bundled_app, tmp("bundled_app.bck")
- update_git "foo", "1.1", path: lib_path("foo-1.0")
+ update_git "foo", "1.1", :path => lib_path("foo-1.0")
gemfile tmp("bundled_app.bck/Gemfile"), <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -161,9 +161,9 @@ RSpec.describe "bundle install with git sources" do
gem "rack", "1.0"
G
- bundle "update foo", dir: tmp("bundled_app.bck")
+ bundle "update foo", :dir => tmp("bundled_app.bck")
- expect(the_bundle).to include_gems "foo 1.1", "rack 1.0", dir: tmp("bundled_app.bck")
+ expect(the_bundle).to include_gems "foo 1.1", "rack 1.0", :dir => tmp("bundled_app.bck")
end
end
@@ -245,9 +245,9 @@ RSpec.describe "bundle install with git sources" do
it "works when a tag that does not look like a commit hash is used as the value of :ref" do
build_git "foo"
- @remote = build_git("bar", bare: true)
- update_git "foo", remote: file_uri_for(@remote.path)
- update_git "foo", push: "main"
+ @remote = build_git("bar", :bare => true)
+ update_git "foo", :remote => file_uri_for(@remote.path)
+ update_git "foo", :push => "main"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -255,8 +255,8 @@ RSpec.describe "bundle install with git sources" do
G
# Create a new tag on the remote that needs fetching
- update_git "foo", tag: "v1.0.0"
- update_git "foo", push: "v1.0.0"
+ update_git "foo", :tag => "v1.0.0"
+ update_git "foo", :push => "v1.0.0"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -268,14 +268,14 @@ RSpec.describe "bundle install with git sources" do
it "works when the revision is a non-head ref" do
# want to ensure we don't fallback to main
- update_git "foo", path: lib_path("foo-1.0") do |s|
+ update_git "foo", :path => lib_path("foo-1.0") do |s|
s.write("lib/foo.rb", "raise 'FAIL'")
end
- sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", dir: lib_path("foo-1.0"))
+ sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0"))
# want to ensure we don't fallback to HEAD
- update_git "foo", path: lib_path("foo-1.0"), branch: "rando" do |s|
+ update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s|
s.write("lib/foo.rb", "raise 'FAIL_FROM_RANDO'")
end
@@ -304,14 +304,14 @@ RSpec.describe "bundle install with git sources" do
G
# want to ensure we don't fallback to main
- update_git "foo", path: lib_path("foo-1.0") do |s|
+ update_git "foo", :path => lib_path("foo-1.0") do |s|
s.write("lib/foo.rb", "raise 'FAIL'")
end
- sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", dir: lib_path("foo-1.0"))
+ sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0"))
# want to ensure we don't fallback to HEAD
- update_git "foo", path: lib_path("foo-1.0"), branch: "rando" do |s|
+ update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s|
s.write("lib/foo.rb", "raise 'FAIL_FROM_RANDO'")
end
@@ -332,7 +332,7 @@ RSpec.describe "bundle install with git sources" do
end
it "does not download random non-head refs" do
- sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", dir: lib_path("foo-1.0"))
+ sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0"))
bundle "config set global_gem_cache true"
@@ -344,9 +344,9 @@ RSpec.describe "bundle install with git sources" do
G
# ensure we also git fetch after cloning
- bundle :update, all: true
+ bundle :update, :all => true
- sys_exec("git ls-remote .", dir: Dir[home(".bundle/cache/git/foo-*")].first)
+ sys_exec("git ls-remote .", :dir => Dir[home(".bundle/cache/git/foo-*")].first)
expect(out).not_to include("refs/bundler/1")
end
@@ -357,7 +357,7 @@ RSpec.describe "bundle install with git sources" do
let(:repo) { build_git("foo").path }
it "works" do
- update_git("foo", path: repo, branch: branch)
+ update_git("foo", :path => repo, :branch => branch)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -374,7 +374,7 @@ RSpec.describe "bundle install with git sources" do
it "works" do
skip "git does not accept this" if Gem.win_platform?
- update_git("foo", path: repo, branch: branch)
+ update_git("foo", :path => repo, :branch => branch)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -392,7 +392,7 @@ RSpec.describe "bundle install with git sources" do
it "works" do
skip "git does not accept this" if Gem.win_platform?
- update_git("foo", path: repo, branch: branch)
+ update_git("foo", :path => repo, :branch => branch)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -411,7 +411,7 @@ RSpec.describe "bundle install with git sources" do
let(:repo) { build_git("foo").path }
it "works" do
- update_git("foo", path: repo, tag: tag)
+ update_git("foo", :path => repo, :tag => tag)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -428,7 +428,7 @@ RSpec.describe "bundle install with git sources" do
it "works" do
skip "git does not accept this" if Gem.win_platform?
- update_git("foo", path: repo, tag: tag)
+ update_git("foo", :path => repo, :tag => tag)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -446,7 +446,7 @@ RSpec.describe "bundle install with git sources" do
it "works" do
skip "git does not accept this" if Gem.win_platform?
- update_git("foo", path: repo, tag: tag)
+ update_git("foo", :path => repo, :tag => tag)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -462,7 +462,7 @@ RSpec.describe "bundle install with git sources" do
describe "when specifying local override" do
it "uses the local repository instead of checking a new one out" do
- build_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -483,7 +483,7 @@ RSpec.describe "bundle install with git sources" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
- update_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -502,7 +502,7 @@ RSpec.describe "bundle install with git sources" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
- update_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.write "rack.gemspec", build_spec("rack", "0.8") { runtime "rspec", "> 0" }.first.to_ruby
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -531,7 +531,7 @@ RSpec.describe "bundle install with git sources" do
lockfile0 = File.read(bundled_app_lock)
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
- update_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.add_dependency "nokogiri", "1.4.2"
end
@@ -553,7 +553,7 @@ RSpec.describe "bundle install with git sources" do
lockfile0 = File.read(bundled_app_lock)
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
- update_git "rack", "0.8", path: lib_path("local-rack")
+ update_git "rack", "0.8", :path => lib_path("local-rack")
bundle %(config set local.rack #{lib_path("local-rack")})
bundle :install
@@ -571,8 +571,8 @@ RSpec.describe "bundle install with git sources" do
G
bundle %(config set local.rack #{lib_path("local-rack")})
- bundle :install, raise_on_error: false
- expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path("local-rack").to_s)} does not exist/)
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
solution = "config unset local.rack"
expect(err).to match(/Run `bundle #{solution}` to remove the local override/)
@@ -593,8 +593,8 @@ RSpec.describe "bundle install with git sources" do
G
bundle %(config set local.rack #{lib_path("local-rack")})
- bundle :install, raise_on_error: false
- expect(err).to match(/Cannot use local override for rack-0.8 at #{Regexp.escape(lib_path("local-rack").to_s)} because :branch is not specified in Gemfile/)
+ bundle :install, :raise_on_error => false
+ expect(err).to match(/Cannot use local override for rack-0.8 at #{Regexp.escape(lib_path('local-rack').to_s)} because :branch is not specified in Gemfile/)
solution = "config unset local.rack"
expect(err).to match(/Specify a branch or run `bundle #{solution}` to remove the local override/)
@@ -625,7 +625,7 @@ RSpec.describe "bundle install with git sources" do
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
- update_git "rack", "0.8", path: lib_path("local-rack"), branch: "another" do |s|
+ update_git "rack", "0.8", :path => lib_path("local-rack"), :branch => "another" do |s|
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -635,14 +635,14 @@ RSpec.describe "bundle install with git sources" do
G
bundle %(config set local.rack #{lib_path("local-rack")})
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to match(/is using branch another but Gemfile specifies main/)
end
it "explodes on invalid revision on install" do
build_git "rack", "0.8"
- build_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -652,14 +652,14 @@ RSpec.describe "bundle install with git sources" do
G
bundle %(config set local.rack #{lib_path("local-rack")})
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to match(/The Gemfile lock is pointing to revision \w+/)
end
it "does not explode on invalid revision on install" do
build_git "rack", "0.8"
- build_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -706,11 +706,11 @@ RSpec.describe "bundle install with git sources" do
it "installs dependencies from git even if a newer gem is available elsewhere" do
system_gems "rack-1.0.0"
- build_lib "rack", "1.0", path: lib_path("nested/bar") do |s|
+ build_lib "rack", "1.0", :path => lib_path("nested/bar") do |s|
s.write "lib/rack.rb", "puts 'WIN OVERRIDE'"
end
- build_git "foo", path: lib_path("nested") do |s|
+ build_git "foo", :path => lib_path("nested") do |s|
s.add_dependency "rack", "= 1.0"
end
@@ -729,7 +729,7 @@ RSpec.describe "bundle install with git sources" do
gem "rack", "0.9.1"
G
- build_git "rack", path: lib_path("rack")
+ build_git "rack", :path => lib_path("rack")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -745,7 +745,7 @@ RSpec.describe "bundle install with git sources" do
gem "rack"
G
- build_git "rack", "1.2", path: lib_path("rack")
+ build_git "rack", "1.2", :path => lib_path("rack")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -758,8 +758,8 @@ RSpec.describe "bundle install with git sources" do
describe "block syntax" do
it "pulls all gems from a git block" do
- build_lib "omg", path: lib_path("hi2u/omg")
- build_lib "hi2u", path: lib_path("hi2u")
+ build_lib "omg", :path => lib_path("hi2u/omg")
+ build_lib "hi2u", :path => lib_path("hi2u")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -807,7 +807,7 @@ RSpec.describe "bundle install with git sources" do
end
it "runs the gemspec in the context of its parent directory" do
- build_lib "bar", path: lib_path("foo/bar"), gemspec: false do |s|
+ build_lib "bar", :path => lib_path("foo/bar"), :gemspec => false do |s|
s.write lib_path("foo/bar/lib/version.rb"), %(BAR_VERSION = '1.0')
s.write "bar.gemspec", <<-G
$:.unshift Dir.pwd
@@ -822,7 +822,7 @@ RSpec.describe "bundle install with git sources" do
G
end
- build_git "foo", path: lib_path("foo") do |s|
+ build_git "foo", :path => lib_path("foo") do |s|
s.write "bin/foo", ""
end
@@ -837,7 +837,7 @@ RSpec.describe "bundle install with git sources" do
end
it "installs from git even if a rubygems gem is present" do
- build_gem "foo", "1.0", path: lib_path("fake_foo"), to_system: true do |s|
+ build_gem "foo", "1.0", :path => lib_path("fake_foo"), :to_system => true do |s|
s.write "lib/foo.rb", "raise 'FAIL'"
end
@@ -852,7 +852,7 @@ RSpec.describe "bundle install with git sources" do
end
it "fakes the gem out if there is no gemspec" do
- build_git "foo", gemspec: false
+ build_git "foo", :gemspec => false
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -870,7 +870,7 @@ RSpec.describe "bundle install with git sources" do
gem "foo", "1.0", :git => "omgomg"
G
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("Git error:")
expect(err).to include("fatal")
@@ -878,7 +878,7 @@ RSpec.describe "bundle install with git sources" do
end
it "works when the gem path has spaces in it" do
- build_git "foo", path: lib_path("foo space-1.0")
+ build_git "foo", :path => lib_path("foo space-1.0")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -903,12 +903,12 @@ RSpec.describe "bundle install with git sources" do
s.write "lib/forced.rb", "FORCED = '1.1'"
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems "forced 1.1"
- sys_exec("git reset --hard HEAD^", dir: lib_path("forced-1.0"))
+ sys_exec("git reset --hard HEAD^", :dir => lib_path("forced-1.0"))
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems "forced 1.0"
end
@@ -920,10 +920,10 @@ RSpec.describe "bundle install with git sources" do
build_git "has_submodule", "1.0" do |s|
s.add_dependency "submodule"
end
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", dir: lib_path("has_submodule-1.0")
- sys_exec "git commit -m \"submodulator\"", dir: lib_path("has_submodule-1.0")
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("has_submodule-1.0")}" do
gem "has_submodule"
@@ -942,8 +942,8 @@ RSpec.describe "bundle install with git sources" do
build_git "has_submodule", "1.0" do |s|
s.add_dependency "submodule"
end
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", dir: lib_path("has_submodule-1.0")
- sys_exec "git commit -m \"submodulator\"", dir: lib_path("has_submodule-1.0")
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -962,8 +962,8 @@ RSpec.describe "bundle install with git sources" do
build_git "submodule", "1.0"
build_git "has_submodule", "1.0"
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", dir: lib_path("has_submodule-1.0")
- sys_exec "git commit -m \"submodulator\"", dir: lib_path("has_submodule-1.0")
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1037,7 +1037,7 @@ RSpec.describe "bundle install with git sources" do
FileUtils.mkdir_p(default_bundle_path)
FileUtils.touch(default_bundle_path("bundler"))
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
@@ -1049,11 +1049,11 @@ RSpec.describe "bundle install with git sources" do
end
it "does not duplicate git gem sources" do
- build_lib "foo", path: lib_path("nested/foo")
- build_lib "bar", path: lib_path("nested/bar")
+ build_lib "foo", :path => lib_path("nested/foo")
+ build_lib "bar", :path => lib_path("nested/bar")
- build_git "foo", path: lib_path("nested")
- build_git "bar", path: lib_path("nested")
+ build_git "foo", :path => lib_path("nested")
+ build_git "bar", :path => lib_path("nested")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1066,11 +1066,11 @@ RSpec.describe "bundle install with git sources" do
describe "switching sources" do
it "doesn't explode when switching Path to Git sources" do
- build_gem "foo", "1.0", to_system: true do |s|
+ build_gem "foo", "1.0", :to_system => true do |s|
s.write "lib/foo.rb", "raise 'fail'"
end
- build_lib "foo", "1.0", path: lib_path("bar/foo")
- build_git "bar", "1.0", path: lib_path("bar") do |s|
+ build_lib "foo", "1.0", :path => lib_path("bar/foo")
+ build_git "bar", "1.0", :path => lib_path("bar") do |s|
s.add_dependency "foo"
end
@@ -1145,7 +1145,7 @@ RSpec.describe "bundle install with git sources" do
G
expect(out).to_not match(/Revision.*does not exist/)
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :ref => "deadbeef"
G
@@ -1155,7 +1155,7 @@ RSpec.describe "bundle install with git sources" do
it "gives a helpful error message when the remote branch no longer exists" do
build_git "foo"
- install_gemfile <<-G, env: { "LANG" => "en" }, raise_on_error: false
+ install_gemfile <<-G, :env => { "LANG" => "en" }, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :branch => "deadbeef"
G
@@ -1166,7 +1166,7 @@ RSpec.describe "bundle install with git sources" do
describe "bundle install with deployment mode configured and git sources" do
it "works" do
- build_git "valim", path: lib_path("valim")
+ build_git "valim", :path => lib_path("valim")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1197,7 +1197,7 @@ RSpec.describe "bundle install with git sources" do
end
bundle :install,
- requires: [lib_path("install_hooks.rb")]
+ :requires => [lib_path("install_hooks.rb")]
expect(err_without_deprecations).to eq("Ran pre-install hook: foo-1.0")
end
@@ -1217,7 +1217,7 @@ RSpec.describe "bundle install with git sources" do
end
bundle :install,
- requires: [lib_path("install_hooks.rb")]
+ :requires => [lib_path("install_hooks.rb")]
expect(err_without_deprecations).to eq("Ran post-install hook: foo-1.0")
end
@@ -1236,7 +1236,7 @@ RSpec.describe "bundle install with git sources" do
H
end
- bundle :install, requires: [lib_path("install_hooks.rb")], raise_on_error: false
+ bundle :install, :requires => [lib_path("install_hooks.rb")], :raise_on_error => false
expect(err).to include("failed for foo-1.0")
end
end
@@ -1275,10 +1275,11 @@ RSpec.describe "bundle install with git sources" do
end
it "does not use old extension after ref changes" do
- git_reader = build_git "foo", no_default: true do |s|
+ git_reader = build_git "foo", :no_default => true do |s|
s.extensions = ["ext/extconf.rb"]
s.write "ext/extconf.rb", <<-RUBY
require "mkmf"
+ $extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
create_makefile("foo")
RUBY
s.write "ext/foo.c", "void Init_foo() {}"
@@ -1292,7 +1293,7 @@ RSpec.describe "bundle install with git sources" do
void Init_foo() { rb_define_global_function("foo", &foo, 0); }
C
end
- sys_exec("git commit -m \"commit for iteration #{i}\" ext/foo.c", dir: git_reader.path)
+ sys_exec("git commit -m \"commit for iteration #{i}\" ext/foo.c", :dir => git_reader.path)
git_commit_sha = git_reader.ref_for("HEAD")
@@ -1321,7 +1322,7 @@ RSpec.describe "bundle install with git sources" do
RUBY
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
@@ -1447,7 +1448,7 @@ In Gemfile:
installed_time = out
- update_git("foo", branch: "branch2")
+ update_git("foo", :branch => "branch2")
expect(installed_time).to match(/\A\d+\.\d+\z/)
@@ -1526,7 +1527,7 @@ In Gemfile:
L
with_path_as("") do
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
end
expect(err).
to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
@@ -1543,7 +1544,7 @@ In Gemfile:
G
with_path_as("") do
- bundle "update", all: true, raise_on_error: false
+ bundle "update", :all => true, :raise_on_error => false
end
expect(err).
to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
@@ -1562,7 +1563,7 @@ In Gemfile:
bundle :cache
simulate_new_machine
- bundle "install", env: { "PATH" => "" }
+ bundle "install", :env => { "PATH" => "" }
expect(out).to_not include("You need to install git to be able to use gems from git repositories.")
end
end
@@ -1580,7 +1581,7 @@ In Gemfile:
end
it "installs successfully" do
- build_git "foo", "1.0", path: lib_path("foo")
+ build_git "foo", "1.0", :path => lib_path("foo")
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1598,7 +1599,7 @@ In Gemfile:
let(:credentials) { "user1:password1" }
it "does not display the password" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
git "https://#{credentials}@github.com/company/private-repo" do
gem "foo"
@@ -1614,7 +1615,7 @@ In Gemfile:
let(:credentials) { "oauth_token" }
it "displays the oauth scheme but not the oauth token" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
git "https://#{credentials}:x-oauth-basic@github.com/company/private-repo" do
gem "foo"
diff --git a/spec/bundler/install/gemfile/groups_spec.rb b/spec/bundler/install/gemfile/groups_spec.rb
index f7907a9cad..734e012e84 100644
--- a/spec/bundler/install/gemfile/groups_spec.rb
+++ b/spec/bundler/install/gemfile/groups_spec.rb
@@ -88,32 +88,32 @@ RSpec.describe "bundle install with groups" do
it "installs gems in the default group" do
bundle "config set --local without emo"
bundle :install
- expect(the_bundle).to include_gems "rack 1.0.0", groups: [:default]
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
end
it "respects global `without` configuration, but does not save it locally" do
bundle "config set --global without emo"
bundle :install
- expect(the_bundle).to include_gems "rack 1.0.0", groups: [:default]
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
bundle "config list"
expect(out).not_to include("Set for your local app (#{bundled_app(".bundle/config")}): [:emo]")
expect(out).to include("Set for the current user (#{home(".bundle/config")}): [:emo]")
end
- it "allows running application where groups where configured by a different user", bundler: "< 3" do
+ it "allows running application where groups where configured by a different user", :bundler => "< 3" do
bundle "config set without emo"
bundle :install
- bundle "exec ruby -e 'puts 42'", env: { "BUNDLE_USER_HOME" => tmp("new_home").to_s }
+ bundle "exec ruby -e 'puts 42'", :env => { "BUNDLE_USER_HOME" => tmp("new_home").to_s }
expect(out).to include("42")
end
it "does not install gems from the excluded group" do
bundle "config set --local without emo"
bundle :install
- expect(the_bundle).not_to include_gems "activesupport 2.3.5", groups: [:default]
+ expect(the_bundle).not_to include_gems "activesupport 2.3.5", :groups => [:default]
end
- it "remembers previous exclusion with `--without`", bundler: "< 3" do
+ it "remembers previous exclusion with `--without`", :bundler => "< 3" do
bundle "install --without emo"
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
bundle :install
@@ -144,7 +144,7 @@ RSpec.describe "bundle install with groups" do
bundle "config set --local without emo"
bundle :install
- expect(the_bundle).to include_gems "activesupport 2.3.2", groups: [:default]
+ expect(the_bundle).to include_gems "activesupport 2.3.2", :groups => [:default]
end
it "still works when BUNDLE_WITHOUT is set" do
@@ -153,20 +153,20 @@ RSpec.describe "bundle install with groups" do
bundle :install
expect(out).not_to include("activesupport")
- expect(the_bundle).to include_gems "rack 1.0.0", groups: [:default]
- expect(the_bundle).not_to include_gems "activesupport 2.3.5", groups: [:default]
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => [:default]
+ expect(the_bundle).not_to include_gems "activesupport 2.3.5", :groups => [:default]
ENV["BUNDLE_WITHOUT"] = nil
end
- it "clears --without when passed an empty list", bundler: "< 3" do
+ it "clears --without when passed an empty list", :bundler => "< 3" do
bundle "install --without emo"
bundle "install --without ''"
expect(the_bundle).to include_gems "activesupport 2.3.5"
end
- it "doesn't clear without when nothing is passed", bundler: "< 3" do
+ it "doesn't clear without when nothing is passed", :bundler => "< 3" do
bundle "install --without emo"
bundle :install
@@ -184,7 +184,7 @@ RSpec.describe "bundle install with groups" do
expect(the_bundle).to include_gems "thin 1.0"
end
- it "installs gems from the previously requested group", bundler: "< 3" do
+ it "installs gems from the previously requested group", :bundler => "< 3" do
bundle "install --with debugging"
expect(the_bundle).to include_gems "thin 1.0"
bundle :install
@@ -198,26 +198,26 @@ RSpec.describe "bundle install with groups" do
ENV["BUNDLE_WITH"] = nil
end
- it "clears --with when passed an empty list", bundler: "< 3" do
+ it "clears --with when passed an empty list", :bundler => "< 3" do
bundle "install --with debugging"
bundle "install --with ''"
expect(the_bundle).not_to include_gems "thin 1.0"
end
- it "removes groups from without when passed at --with", bundler: "< 3" do
+ it "removes groups from without when passed at --with", :bundler => "< 3" do
bundle "config set --local without emo"
bundle "install --with emo"
expect(the_bundle).to include_gems "activesupport 2.3.5"
end
- it "removes groups from with when passed at --without", bundler: "< 3" do
+ it "removes groups from with when passed at --without", :bundler => "< 3" do
bundle "config set --local with debugging"
- bundle "install --without debugging", raise_on_error: false
+ bundle "install --without debugging", :raise_on_error => false
expect(the_bundle).not_to include_gem "thin 1.0"
end
- it "errors out when passing a group to with and without via CLI flags", bundler: "< 3" do
- bundle "install --with emo debugging --without emo", raise_on_error: false
+ it "errors out when passing a group to with and without via CLI flags", :bundler => "< 3" do
+ bundle "install --with emo debugging --without emo", :raise_on_error => false
expect(last_command).to be_failure
expect(err).to include("The offending groups are: emo")
end
@@ -235,7 +235,7 @@ RSpec.describe "bundle install with groups" do
expect(the_bundle).to include_gem "thin 1.0"
end
- it "can add and remove a group at the same time", bundler: "< 3" do
+ it "can add and remove a group at the same time", :bundler => "< 3" do
bundle "install --with debugging --without emo"
expect(the_bundle).to include_gems "thin 1.0"
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
@@ -349,7 +349,7 @@ RSpec.describe "bundle install with groups" do
G
ruby <<-R
- require "bundler"
+ require "#{entrypoint}"
Bundler.setup :default
Bundler.require :default
puts RACK
@@ -396,7 +396,7 @@ RSpec.describe "bundle install with groups" do
it "does not hit the remote a second time" do
FileUtils.rm_rf gem_repo2
bundle "config set --local without rack"
- bundle :install, verbose: true
+ bundle :install, :verbose => true
expect(last_command.stdboth).not_to match(/fetching/i)
end
end
diff --git a/spec/bundler/install/gemfile/install_if_spec.rb b/spec/bundler/install/gemfile/install_if_spec.rb
index c7640d07e1..3d2d15a698 100644
--- a/spec/bundler/install/gemfile/install_if_spec.rb
+++ b/spec/bundler/install/gemfile/install_if_spec.rb
@@ -18,13 +18,6 @@ RSpec.describe "bundle install with install_if conditionals" do
expect(the_bundle).not_to include_gems("thin")
expect(the_bundle).not_to include_gems("foo")
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo1, "activesupport", "2.3.5"
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo1, "rack", "1.0.0"
- c.no_checksum "thin", "1.0"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -43,7 +36,7 @@ RSpec.describe "bundle install with install_if conditionals" do
foo
rack
thin
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
diff --git a/spec/bundler/install/gemfile/lockfile_spec.rb b/spec/bundler/install/gemfile/lockfile_spec.rb
index 4601d3e2a8..313e99d0b8 100644
--- a/spec/bundler/install/gemfile/lockfile_spec.rb
+++ b/spec/bundler/install/gemfile/lockfile_spec.rb
@@ -11,11 +11,6 @@ RSpec.describe "bundle install with a lockfile present" do
install_gemfile(gf)
end
- it "touches the lockfile on install even when nothing has changed" do
- subject
- expect { bundle :install }.to change { bundled_app_lock.mtime }
- end
-
context "gemfile evaluation" do
let(:gf) { super() + "\n\n File.open('evals', 'a') {|f| f << %(1\n) } unless ENV['BUNDLER_SPEC_NO_APPEND']" }
diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb
index a57b7ee560..a5207036c3 100644
--- a/spec/bundler/install/gemfile/path_spec.rb
+++ b/spec/bundler/install/gemfile/path_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe "bundle install with explicit source paths" do
- it "fetches gems with a global path source", bundler: "< 3" do
+ it "fetches gems with a global path source", :bundler => "< 3" do
build_lib "foo"
install_gemfile <<-G
@@ -69,7 +69,7 @@ RSpec.describe "bundle install with explicit source paths" do
username = "some_unexisting_user"
relative_path = lib_path("foo-1.0").relative_path_from(Pathname.new("/home/#{username}").expand_path)
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "~#{username}/#{relative_path}"
G
@@ -78,19 +78,19 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "expands paths relative to Bundler.root" do
- build_lib "foo", path: bundled_app("foo-1.0")
+ build_lib "foo", :path => bundled_app("foo-1.0")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem 'foo', :path => "./foo-1.0"
G
- expect(the_bundle).to include_gems("foo 1.0", dir: bundled_app("subdir").mkpath)
+ expect(the_bundle).to include_gems("foo 1.0", :dir => bundled_app("subdir").mkpath)
end
it "sorts paths consistently on install and update when they start with ./" do
- build_lib "demo", path: lib_path("demo")
- build_lib "aaa", path: lib_path("demo/aaa")
+ build_lib "demo", :path => lib_path("demo")
+ build_lib "aaa", :path => lib_path("demo/aaa")
gemfile lib_path("demo/Gemfile"), <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -98,11 +98,6 @@ RSpec.describe "bundle install with explicit source paths" do
gem "aaa", :path => "./aaa"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "aaa", "1.0"
- c.no_checksum "demo", "1.0"
- end
-
lockfile = <<~L
PATH
remote: .
@@ -124,19 +119,19 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
aaa!
demo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
- bundle :install, dir: lib_path("demo")
+ bundle :install, :dir => lib_path("demo")
expect(lib_path("demo/Gemfile.lock")).to read_as(lockfile)
- bundle :update, all: true, dir: lib_path("demo")
+ bundle :update, :all => true, :dir => lib_path("demo")
expect(lib_path("demo/Gemfile.lock")).to read_as(lockfile)
end
it "expands paths when comparing locked paths to Gemfile paths" do
- build_lib "foo", path: bundled_app("foo-1.0")
+ build_lib "foo", :path => bundled_app("foo-1.0")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -150,11 +145,11 @@ RSpec.describe "bundle install with explicit source paths" do
it "installs dependencies from the path even if a newer gem is available elsewhere" do
system_gems "rack-1.0.0"
- build_lib "rack", "1.0", path: lib_path("nested/bar") do |s|
+ build_lib "rack", "1.0", :path => lib_path("nested/bar") do |s|
s.write "lib/rack.rb", "puts 'WIN OVERRIDE'"
end
- build_lib "foo", path: lib_path("nested") do |s|
+ build_lib "foo", :path => lib_path("nested") do |s|
s.add_dependency "rack", "= 1.0"
end
@@ -168,15 +163,15 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "works" do
- build_gem "foo", "1.0.0", to_system: true do |s|
+ build_gem "foo", "1.0.0", :to_system => true do |s|
s.write "lib/foo.rb", "puts 'FAIL'"
end
- build_lib "omg", "1.0", path: lib_path("omg") do |s|
+ build_lib "omg", "1.0", :path => lib_path("omg") do |s|
s.add_dependency "foo"
end
- build_lib "foo", "1.0.0", path: lib_path("omg/foo")
+ build_lib "foo", "1.0.0", :path => lib_path("omg/foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -187,7 +182,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "works when using prereleases of 0.0.0" do
- build_lib "foo", "0.0.0.dev", path: lib_path("foo")
+ build_lib "foo", "0.0.0.dev", :path => lib_path("foo")
gemfile <<~G
source "#{file_uri_for(gem_repo1)}"
@@ -220,7 +215,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "works when using uppercase prereleases of 0.0.0" do
- build_lib "foo", "0.0.0.SNAPSHOT", path: lib_path("foo")
+ build_lib "foo", "0.0.0.SNAPSHOT", :path => lib_path("foo")
gemfile <<~G
source "#{file_uri_for(gem_repo1)}"
@@ -253,14 +248,14 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "handles downgrades" do
- build_lib "omg", "2.0", path: lib_path("omg")
+ build_lib "omg", "2.0", :path => lib_path("omg")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "omg", :path => "#{lib_path("omg")}"
G
- build_lib "omg", "1.0", path: lib_path("omg")
+ build_lib "omg", "1.0", :path => lib_path("omg")
bundle :install
@@ -268,7 +263,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "prefers gemspecs closer to the path root" do
- build_lib "premailer", "1.0.0", path: lib_path("premailer") do |s|
+ build_lib "premailer", "1.0.0", :path => lib_path("premailer") do |s|
s.write "gemfiles/ruby187.gemspec", <<-G
Gem::Specification.new do |s|
s.name = 'premailer'
@@ -301,7 +296,7 @@ RSpec.describe "bundle install with explicit source paths" do
G
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
@@ -313,7 +308,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "supports gemspec syntax" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "1.0"
end
@@ -322,9 +317,9 @@ RSpec.describe "bundle install with explicit source paths" do
gemspec
G
- bundle "install", dir: lib_path("foo")
- expect(the_bundle).to include_gems "foo 1.0", dir: lib_path("foo")
- expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("foo")
+ bundle "install", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "foo 1.0", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("foo")
end
it "does not unlock dependencies of path sources" do
@@ -333,7 +328,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_gem "graphql", "2.0.16"
end
- build_lib "foo", "0.1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "0.1.0", :path => lib_path("foo") do |s|
s.add_dependency "graphql", "~> 2.0"
end
@@ -346,11 +341,6 @@ RSpec.describe "bundle install with explicit source paths" do
lockfile_path = lib_path("foo/Gemfile.lock")
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "0.1.0"
- c.checksum gem_repo4, "graphql", "2.0.15"
- end
-
original_lockfile = <<~L
PATH
remote: .
@@ -368,23 +358,23 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
lockfile lockfile_path, original_lockfile
- build_lib "foo", "0.1.1", path: lib_path("foo") do |s|
+ build_lib "foo", "0.1.1", :path => lib_path("foo") do |s|
s.add_dependency "graphql", "~> 2.0"
end
- bundle "install", dir: lib_path("foo")
+ bundle "install", :dir => lib_path("foo")
expect(lockfile_path).to read_as(original_lockfile.gsub("foo (0.1.0)", "foo (0.1.1)"))
end
it "supports gemspec syntax with an alternative path" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "1.0"
end
@@ -398,48 +388,48 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "doesn't automatically unlock dependencies when using the gemspec syntax" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", ">= 1.0"
end
- install_gemfile lib_path("foo/Gemfile"), <<-G, dir: lib_path("foo")
+ install_gemfile lib_path("foo/Gemfile"), <<-G, :dir => lib_path("foo")
source "#{file_uri_for(gem_repo1)}"
gemspec
G
- build_gem "rack", "1.0.1", to_system: true
+ build_gem "rack", "1.0.1", :to_system => true
- bundle "install", dir: lib_path("foo")
+ bundle "install", :dir => lib_path("foo")
- expect(the_bundle).to include_gems "foo 1.0", dir: lib_path("foo")
- expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("foo")
+ expect(the_bundle).to include_gems "foo 1.0", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("foo")
end
it "doesn't automatically unlock dependencies when using the gemspec syntax and the gem has development dependencies" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", ">= 1.0"
s.add_development_dependency "activesupport"
end
- install_gemfile lib_path("foo/Gemfile"), <<-G, dir: lib_path("foo")
+ install_gemfile lib_path("foo/Gemfile"), <<-G, :dir => lib_path("foo")
source "#{file_uri_for(gem_repo1)}"
gemspec
G
- build_gem "rack", "1.0.1", to_system: true
+ build_gem "rack", "1.0.1", :to_system => true
- bundle "install", dir: lib_path("foo")
+ bundle "install", :dir => lib_path("foo")
- expect(the_bundle).to include_gems "foo 1.0", dir: lib_path("foo")
- expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("foo")
+ expect(the_bundle).to include_gems "foo 1.0", :dir => lib_path("foo")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("foo")
end
it "raises if there are multiple gemspecs" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.write "bar.gemspec", build_spec("bar", "1.0").first.to_ruby
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gemspec :path => "#{lib_path("foo")}"
G
@@ -449,7 +439,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "allows :name to be specified to resolve ambiguity" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.write "bar.gemspec"
end
@@ -466,7 +456,7 @@ RSpec.describe "bundle install with explicit source paths" do
s.executables = "foobar"
end
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
path "#{lib_path("foo-1.0")}" do
gem 'foo'
@@ -520,9 +510,9 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "keeps source pinning" do
- build_lib "foo", "1.0", path: lib_path("foo")
- build_lib "omg", "1.0", path: lib_path("omg")
- build_lib "foo", "1.0", path: lib_path("omg/foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo")
+ build_lib "omg", "1.0", :path => lib_path("omg")
+ build_lib "foo", "1.0", :path => lib_path("omg/foo") do |s|
s.write "lib/foo.rb", "puts 'FAIL'"
end
@@ -536,7 +526,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "works when the path does not have a gemspec" do
- build_lib "foo", gemspec: false
+ build_lib "foo", :gemspec => false
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -574,17 +564,17 @@ RSpec.describe "bundle install with explicit source paths" do
gem 'net-ssh', '1.0'
G
- bundle :check, env: { "DEBUG" => "1" }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0"
end
it "source path gems w/deps don't re-resolve without changes" do
- build_lib "rack-obama", "1.0", path: lib_path("omg") do |s|
+ build_lib "rack-obama", "1.0", :path => lib_path("omg") do |s|
s.add_dependency "yard"
end
- build_lib "net-ssh", "1.0", path: lib_path("omg") do |s|
+ build_lib "net-ssh", "1.0", :path => lib_path("omg") do |s|
s.add_dependency "yard"
end
@@ -594,7 +584,7 @@ RSpec.describe "bundle install with explicit source paths" do
gem 'net-ssh', :path => "#{lib_path("omg")}"
G
- bundle :check, env: { "DEBUG" => "1" }
+ bundle :check, :env => { "DEBUG" => "1" }
expect(out).to match(/using resolution from the lockfile/)
expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0"
end
@@ -616,10 +606,10 @@ RSpec.describe "bundle install with explicit source paths" do
describe "when the gem version in the path is updated" do
before :each do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "bar"
end
- build_lib "bar", "1.0", path: lib_path("foo/bar")
+ build_lib "bar", "1.0", :path => lib_path("foo/bar")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -628,7 +618,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "unlocks all gems when the top level gem is updated" do
- build_lib "foo", "2.0", path: lib_path("foo") do |s|
+ build_lib "foo", "2.0", :path => lib_path("foo") do |s|
s.add_dependency "bar"
end
@@ -638,7 +628,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "unlocks all gems when a child dependency gem is updated" do
- build_lib "bar", "2.0", path: lib_path("foo/bar")
+ build_lib "bar", "2.0", :path => lib_path("foo/bar")
bundle "install"
@@ -648,7 +638,7 @@ RSpec.describe "bundle install with explicit source paths" do
describe "when dependencies in the path are updated" do
before :each do
- build_lib "foo", "1.0", path: lib_path("foo")
+ build_lib "foo", "1.0", :path => lib_path("foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -657,7 +647,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "gets dependencies that are updated in the path" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack"
end
@@ -667,7 +657,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "keeps using the same version if it's compatible" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "0.9.1"
end
@@ -675,11 +665,6 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "rack 0.9.1"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo1, "rack", "0.9.1"
- end
-
expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
@@ -697,12 +682,12 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack"
end
@@ -725,7 +710,7 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -734,7 +719,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "keeps using the same version even when another dependency is added" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "0.9.1"
end
@@ -742,11 +727,6 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "rack 0.9.1"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.checksum gem_repo1, "rack", "0.9.1"
- end
-
expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
@@ -764,40 +744,38 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack"
- s.add_dependency "rake", rake_version
+ s.add_dependency "rake", "13.0.1"
end
bundle "install"
- checksums.checksum gem_repo1, "rake", rake_version
-
expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
specs:
foo (1.0)
rack
- rake (= #{rake_version})
+ rake (= 13.0.1)
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
rack (0.9.1)
- rake (#{rake_version})
+ rake (13.0.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -806,14 +784,10 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "does not remove existing ruby platform" do
- build_lib "foo", "1.0", path: lib_path("foo") do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "0.9.1"
end
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
lockfile <<~L
PATH
remote: #{lib_path("foo")}
@@ -825,15 +799,13 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "lock"
- checksums.no_checksum "rack", "0.9.1"
-
expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo")}
@@ -851,7 +823,7 @@ RSpec.describe "bundle install with explicit source paths" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -860,11 +832,11 @@ RSpec.describe "bundle install with explicit source paths" do
describe "switching sources" do
it "doesn't switch pinned git sources to rubygems when pinning the parent gem to a path source" do
- build_gem "foo", "1.0", to_system: true do |s|
+ build_gem "foo", "1.0", :to_system => true do |s|
s.write "lib/foo.rb", "raise 'fail'"
end
- build_lib "foo", "1.0", path: lib_path("bar/foo")
- build_git "bar", "1.0", path: lib_path("bar") do |s|
+ build_lib "foo", "1.0", :path => lib_path("bar/foo")
+ build_git "bar", "1.0", :path => lib_path("bar") do |s|
s.add_dependency "foo"
end
@@ -882,8 +854,8 @@ RSpec.describe "bundle install with explicit source paths" do
end
it "switches the source when the gem existed in rubygems and the path was already being used for another gem" do
- build_lib "foo", "1.0", path: lib_path("foo")
- build_gem "bar", "1.0", to_bundle: true do |s|
+ build_lib "foo", "1.0", :path => lib_path("foo")
+ build_gem "bar", "1.0", :to_bundle => true do |s|
s.write "lib/bar.rb", "raise 'fail'"
end
@@ -895,7 +867,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
G
- build_lib "bar", "1.0", path: lib_path("foo/bar")
+ build_lib "bar", "1.0", :path => lib_path("foo/bar")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -911,17 +883,17 @@ RSpec.describe "bundle install with explicit source paths" do
describe "when there are both a gemspec and remote gems" do
it "doesn't query rubygems for local gemspec name" do
- build_lib "private_lib", "2.2", path: lib_path("private_lib")
+ build_lib "private_lib", "2.2", :path => lib_path("private_lib")
gemfile lib_path("private_lib/Gemfile"), <<-G
source "http://localgemserver.test"
gemspec
gem 'rack'
G
- bundle :install, env: { "DEBUG" => "1" }, artifice: "endpoint", dir: lib_path("private_lib")
+ bundle :install, :env => { "DEBUG" => "1" }, :artifice => "endpoint", :dir => lib_path("private_lib")
expect(out).to match(%r{^HTTP GET http://localgemserver\.test/api/v1/dependencies\?gems=rack$})
expect(out).not_to match(/^HTTP GET.*private_lib/)
- expect(the_bundle).to include_gems "private_lib 2.2", dir: lib_path("private_lib")
- expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("private_lib")
+ expect(the_bundle).to include_gems "private_lib 2.2", :dir => lib_path("private_lib")
+ expect(the_bundle).to include_gems "rack 1.0", :dir => lib_path("private_lib")
end
end
@@ -942,7 +914,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
bundle :install,
- requires: [lib_path("install_hooks.rb")]
+ :requires => [lib_path("install_hooks.rb")]
expect(err_without_deprecations).to eq("Ran pre-install hook: foo-1.0")
end
@@ -962,7 +934,7 @@ RSpec.describe "bundle install with explicit source paths" do
end
bundle :install,
- requires: [lib_path("install_hooks.rb")]
+ :requires => [lib_path("install_hooks.rb")]
expect(err_without_deprecations).to eq("Ran post-install hook: foo-1.0")
end
@@ -981,7 +953,7 @@ RSpec.describe "bundle install with explicit source paths" do
H
end
- bundle :install, requires: [lib_path("install_hooks.rb")], raise_on_error: false
+ bundle :install, :requires => [lib_path("install_hooks.rb")], :raise_on_error => false
expect(err).to include("failed for foo-1.0")
end
diff --git a/spec/bundler/install/gemfile/platform_spec.rb b/spec/bundler/install/gemfile/platform_spec.rb
index d90dacdc02..219ae6c2f4 100644
--- a/spec/bundler/install/gemfile/platform_spec.rb
+++ b/spec/bundler/install/gemfile/platform_spec.rb
@@ -203,15 +203,6 @@ RSpec.describe "bundle install across platforms" do
gem "pry"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "coderay", "1.1.2"
- c.checksum gem_repo4, "empyrean", "0.1.0"
- c.checksum gem_repo4, "ffi", "1.9.23", "java"
- c.checksum gem_repo4, "method_source", "0.9.0"
- c.checksum gem_repo4, "pry", "0.11.3", "java"
- c.checksum gem_repo4, "spoon", "0.0.6"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -233,7 +224,7 @@ RSpec.describe "bundle install across platforms" do
DEPENDENCIES
empyrean (= 0.1.0)
pry
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -265,7 +256,7 @@ RSpec.describe "bundle install across platforms" do
DEPENDENCIES
empyrean (= 0.1.0)
pry
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -298,30 +289,30 @@ RSpec.describe "bundle install across platforms" do
DEPENDENCIES
empyrean (= 0.1.0)
pry
- #{checksums}
+
BUNDLED WITH
1.16.1
L
aggregate_failures do
lockfile bad_lockfile
- bundle :install, env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle :install, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
- bundle :update, all: true, env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle :update, :all => true, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
- bundle "update ffi", env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle "update ffi", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
- bundle "update empyrean", env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle "update empyrean", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
- bundle :lock, env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ bundle :lock, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
end
end
@@ -372,11 +363,6 @@ RSpec.describe "bundle install across platforms" do
end
it "keeps existing platforms when installing with force_ruby_platform" do
- checksums = checksums_section do |c|
- c.no_checksum "platform_specific", "1.0"
- c.no_checksum "platform_specific", "1.0", "java"
- end
-
lockfile <<-G
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -388,7 +374,6 @@ RSpec.describe "bundle install across platforms" do
DEPENDENCIES
platform_specific
- #{checksums}
G
bundle "config set --local force_ruby_platform true"
@@ -398,8 +383,6 @@ RSpec.describe "bundle install across platforms" do
gem "platform_specific"
G
- checksums.checksum gem_repo1, "platform_specific", "1.0"
-
expect(the_bundle).to include_gem "platform_specific 1.0 RUBY"
expect(lockfile).to eq <<~G
@@ -415,7 +398,7 @@ RSpec.describe "bundle install across platforms" do
DEPENDENCIES
platform_specific
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -567,7 +550,7 @@ RSpec.describe "bundle install with platform conditionals" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
- gem "rack", :platform => [:windows, :mswin, :mswin64, :mingw, :x64_mingw, :jruby]
+ gem "rack", :platform => [:windows, :mingw, :mswin, :x64_mingw, :jruby]
G
bundle "install"
@@ -584,7 +567,7 @@ RSpec.describe "bundle install with platform conditionals" do
DEPENDENCIES
rack
- #{checksums_section_when_existing}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -629,7 +612,7 @@ RSpec.describe "when a gem has no architecture" do
gem "rcov"
G
- bundle :install, artifice: "windows", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ bundle :install, :artifice => "windows", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(the_bundle).to include_gems "rcov 1.0.0"
end
end
diff --git a/spec/bundler/install/gemfile/ruby_spec.rb b/spec/bundler/install/gemfile/ruby_spec.rb
index b64d633fd3..39f09031b7 100644
--- a/spec/bundler/install/gemfile/ruby_spec.rb
+++ b/spec/bundler/install/gemfile/ruby_spec.rb
@@ -112,7 +112,7 @@ RSpec.describe "ruby requirement" do
end
it "fails gracefully with malformed requirements" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
ruby ">= 0", "-.\\0"
gem "rack"
@@ -120,38 +120,4 @@ RSpec.describe "ruby requirement" do
expect(err).to include("There was an error parsing") # i.e. DSL error, not error template
end
-
- it "allows picking up ruby version from a file" do
- create_file ".ruby-version", Gem.ruby_version.to_s
-
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- ruby file: ".ruby-version"
- gem "rack"
- G
-
- expect(lockfile).to include("RUBY VERSION")
- end
-
- it "reads the ruby version file from the right folder when nested Gemfiles are involved" do
- create_file ".ruby-version", Gem.ruby_version.to_s
-
- gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- ruby file: ".ruby-version"
- gem "rack"
- G
-
- nested_dir = bundled_app(".ruby-lsp")
-
- FileUtils.mkdir nested_dir
-
- create_file ".ruby-lsp/Gemfile", <<-G
- eval_gemfile(File.expand_path("../Gemfile", __dir__))
- G
-
- bundle "install", dir: nested_dir
-
- expect(bundled_app(".ruby-lsp/Gemfile.lock").read).to include("RUBY VERSION")
- end
end
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index daee8a2744..dd86187a6b 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -27,72 +27,18 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
- it "refuses to install mismatched checksum because one gem has been tampered with", bundler: "< 3" do
- lockfile <<~L
- GEM
- remote: https://gem.repo3/
- remote: https://gem.repo1/
- specs:
- rack (1.0.0)
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- depends_on_rack!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- bundle :install, artifice: "compact_index", raise_on_error: false
+ it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
- expect(exitstatus).to eq(37)
- expect(err).to eq <<~E.strip
- [DEPRECATED] Your Gemfile contains multiple global sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source.
- Bundler found mismatched checksums. This is a potential security risk.
- #{checksum_to_lock(gem_repo1, "rack", "1.0.0")}
- from the API at https://gem.repo1/
- #{checksum_to_lock(gem_repo3, "rack", "1.0.0")}
- from the API at https://gem.repo3/
-
- Mismatched checksums each have an authoritative source:
- 1. the API at https://gem.repo1/
- 2. the API at https://gem.repo3/
- You may need to alter your Gemfile sources to resolve this issue.
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).to include("Installed from: https://gem.repo1")
+ expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", :source => "remote1")
end
- context "when checksum validation is disabled" do
- before do
- bundle "config set --local disable_checksum_validation true"
- end
-
- it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first", bundler: "< 3" do
- bundle :install, artifice: "compact_index"
-
- expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(err).to include("Installed from: https://gem.repo1")
- expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", source: "remote1")
- end
-
- it "does not use the full index unnecessarily", bundler: "< 3" do
- bundle :install, artifice: "compact_index", verbose: true
-
- expect(out).to include("https://gem.repo1/versions")
- expect(out).to include("https://gem.repo3/versions")
- expect(out).not_to include("https://gem.repo1/quick/Marshal.4.8/")
- expect(out).not_to include("https://gem.repo3/quick/Marshal.4.8/")
- end
-
- it "fails", bundler: "3" do
- bundle :install, artifice: "compact_index", raise_on_error: false
- expect(err).to include("Each source after the first must include a block")
- expect(exitstatus).to eq(4)
- end
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
end
end
@@ -108,49 +54,21 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
- it "warns about ambiguous gems, but installs anyway", bundler: "< 3" do
- bundle :install, artifice: "compact_index"
+ it "warns about ambiguous gems, but installs anyway", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).to include("Installed from: https://gem.repo1")
- expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", source: "remote1")
+ expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", :source => "remote1")
end
- it "fails", bundler: "3" do
- bundle :install, artifice: "compact_index", raise_on_error: false
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
end
- context "without source affinity, and a stdlib gem present in one of the sources", :ruby_repo do
- let(:default_json_version) { ruby "gem 'json'; require 'json'; puts JSON::VERSION" }
-
- before do
- build_repo2 do
- build_gem "json", default_json_version
- end
-
- build_repo4 do
- build_gem "foo" do |s|
- s.add_dependency "json", default_json_version
- end
- end
-
- gemfile <<-G
- source "https://gem.repo2"
- source "https://gem.repo4"
-
- gem "foo"
- G
- end
-
- it "works in standalone mode", bundler: "< 3" do
- gem_checksum = checksum_digest(gem_repo4, "foo", "1.0")
- bundle "install --standalone", artifice: "compact_index", env: { "BUNDLER_SPEC_FOO_CHECKSUM" => gem_checksum }
- end
- end
-
context "with source affinity" do
context "with sources given by a block" do
before do
@@ -177,20 +95,20 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the gems without any warning" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("rack-obama 1.0.0")
- expect(the_bundle).to include_gems("rack 1.0.0", source: "remote1")
+ expect(the_bundle).to include_gems("rack 1.0.0", :source => "remote1")
end
it "can cache and deploy" do
- bundle :cache, artifice: "compact_index"
+ bundle :cache, :artifice => "compact_index"
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
expect(bundled_app("vendor/cache/rack-obama-1.0.gem")).to exist
bundle "config set --local deployment true"
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0")
end
@@ -210,7 +128,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo3"
gem "rack-obama" # should come from repo3!
gem "rack", :source => "https://gem.repo1"
@@ -250,9 +168,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs from the same source without any warning" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
@@ -267,18 +185,18 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs from the same source without any warning" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
end
@@ -300,7 +218,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "and not in any other sources" do
before do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo2"
source "https://gem.repo3" do
gem "depends_on_rack"
@@ -325,63 +243,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
- it "fails when the two sources don't have the same checksum", bundler: "< 3" do
- bundle :install, artifice: "compact_index", raise_on_error: false
-
- expect(err).to eq(<<~E.strip)
- [DEPRECATED] Your Gemfile contains multiple global sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source.
- Bundler found mismatched checksums. This is a potential security risk.
- #{checksum_to_lock(gem_repo2, "rack", "1.0.0")}
- from the API at https://gem.repo2/
- #{checksum_to_lock(gem_repo1, "rack", "1.0.0")}
- from the API at https://gem.repo1/
-
- Mismatched checksums each have an authoritative source:
- 1. the API at https://gem.repo2/
- 2. the API at https://gem.repo1/
- You may need to alter your Gemfile sources to resolve this issue.
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
- expect(exitstatus).to eq(37)
- end
-
- it "fails when the two sources agree, but the local gem calculates a different checksum", bundler: "< 3" do
- rack_checksum = "c0ffee11" * 8
- bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => rack_checksum }, raise_on_error: false
-
- expect(err).to eq(<<~E.strip)
- [DEPRECATED] Your Gemfile contains multiple global sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source.
- Bundler found mismatched checksums. This is a potential security risk.
- rack (1.0.0) sha256=#{rack_checksum}
- from the API at https://gem.repo2/
- and the API at https://gem.repo1/
- #{checksum_to_lock(gem_repo2, "rack", "1.0.0")}
- from the gem at #{default_bundle_path("cache", "rack-1.0.0.gem")}
-
- If you trust the API at https://gem.repo2/, to resolve this issue you can:
- 1. remove the gem at #{default_bundle_path("cache", "rack-1.0.0.gem")}
- 2. run `bundle install`
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
- expect(exitstatus).to eq(37)
- end
-
- it "installs from the other source and warns about ambiguous gems when the sources have the same checksum", bundler: "< 3" do
- gem_checksum = checksum_digest(gem_repo2, "rack", "1.0.0")
- bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => gem_checksum, "DEBUG" => "1" }
-
+ it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).to include("Installed from: https://gem.repo2")
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo3, "depends_on_rack", "1.0.1"
- c.checksum gem_repo2, "rack", "1.0.0"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo1/
@@ -396,51 +262,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
depends_on_rack!
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- previous_lockfile = lockfile
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
- expect(lockfile).to eq(previous_lockfile)
- end
-
- it "installs from the other source and warns about ambiguous gems when checksum validation is disabled", bundler: "< 3" do
- bundle "config set --local disable_checksum_validation true"
- bundle :install, artifice: "compact_index"
-
- expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(err).to include("Installed from: https://gem.repo2")
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "depends_on_rack", "1.0.1"
- c.no_checksum "rack", "1.0.0"
- end
-
- expect(lockfile).to eq <<~L
- GEM
- remote: https://gem.repo1/
- remote: https://gem.repo2/
- specs:
- rack (1.0.0)
-
- GEM
- remote: https://gem.repo3/
- specs:
- depends_on_rack (1.0.1)
- rack
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- depends_on_rack!
- #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -450,8 +276,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(lockfile).to eq(previous_lockfile)
end
- it "fails", bundler: "3" do
- bundle :install, artifice: "compact_index", raise_on_error: false
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
@@ -475,8 +301,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
- it "installs the dependency from the pinned source without warning", bundler: "< 3" do
- bundle :install, artifice: "compact_index"
+ it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
@@ -484,14 +310,14 @@ RSpec.describe "bundle install with gems on multiple sources" do
# In https://github.com/rubygems/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
- it "fails", bundler: "3" do
- bundle :install, artifice: "compact_index", raise_on_error: false
+ it "fails", :bundler => "3" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
@@ -519,12 +345,12 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "fails" do
- bundle :install, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/ or installed locally.")
end
end
- context "when an indirect dependency can't be found in the aggregate rubygems source", bundler: "< 3" do
+ context "when an indirect dependency can't be found in the aggregate rubygems source", :bundler => "< 3" do
before do
build_repo2
@@ -544,7 +370,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "fails" do
- bundle :install, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to end_with <<~E.strip
Could not find compatible versions
@@ -588,11 +414,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the dependency from the top-level source without warning" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote2")
- expect(the_bundle).to include_gems("unrelated_gem 1.0.0", source: "remote3")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("unrelated_gem 1.0.0", :source => "remote3")
end
end
@@ -606,7 +432,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "does not find the dependency" do
- bundle :install, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to end_with <<~E.strip
Could not find compatible versions
@@ -633,12 +459,12 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the dependency from the top-level source without warning" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(run("require 'rack'; puts RACK")).to eq("1.0.0")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote2")
- expect(the_bundle).to include_gems("unrelated_gem 1.0.0", source: "remote3")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("unrelated_gem 1.0.0", :source => "remote3")
end
end
end
@@ -672,10 +498,10 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the dependency from the top-level source" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0")
- expect(the_bundle).to include_gems("rack 1.0.0", source: "remote2")
- expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", source: "remote3")
+ expect(the_bundle).to include_gems("rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", :source => "remote3")
end
end
@@ -689,8 +515,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the dependency from the pinned source" do
- bundle :install, artifice: "compact_index"
- expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3")
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
@@ -708,8 +534,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the dependency from the pinned source without warning" do
- bundle :install, artifice: "compact_index"
- expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3")
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
end
@@ -783,21 +609,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
G
- @locked_checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "activesupport", "6.0.3.4"
- c.checksum gem_repo2, "concurrent-ruby", "1.1.8"
- c.checksum gem_repo2, "connection_pool", "2.2.3"
- c.checksum gem_repo2, "i18n", "1.8.9"
- c.checksum gem_repo2, "minitest", "5.14.3"
- c.checksum gem_repo2, "rack", "2.2.3"
- c.checksum gem_repo2, "redis", "4.2.5"
- c.checksum gem_repo2, "sidekiq", "6.1.3"
- c.checksum gem_repo3, "sidekiq-pro", "5.2.1"
- c.checksum gem_repo2, "thread_safe", "0.3.6"
- c.checksum gem_repo2, "tzinfo", "1.2.9"
- c.checksum gem_repo2, "zeitwerk", "2.4.2"
- end
-
lockfile <<~L
GEM
remote: https://gem.repo2/
@@ -829,19 +640,19 @@ RSpec.describe "bundle install with gems on multiple sources" do
zeitwerk (2.4.2)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
- #{@locked_checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "does not install newer versions but updates the lockfile format when running bundle install in non frozen mode, and doesn't warn" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).to be_empty
expect(the_bundle).to include_gems("activesupport 6.0.3.4")
@@ -885,22 +696,22 @@ RSpec.describe "bundle install with gems on multiple sources" do
sidekiq (>= 6.1.0)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
- #{@locked_checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
- it "does not install newer versions or generate lockfile changes when running bundle install in frozen mode, and warns", bundler: "< 3" do
+ it "does not install newer versions or generate lockfile changes when running bundle install in frozen mode, and warns", :bundler => "< 3" do
initial_lockfile = lockfile
bundle "config set --local frozen true"
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
@@ -914,11 +725,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(lockfile).to eq(initial_lockfile)
end
- it "fails when running bundle install in frozen mode", bundler: "3" do
+ it "fails when running bundle install in frozen mode", :bundler => "3" do
initial_lockfile = lockfile
bundle "config set --local frozen true"
- bundle :install, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
@@ -926,21 +737,15 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
- bundle "update --all", artifice: "compact_index"
+ bundle "update --all", :artifice => "compact_index"
expect(err).to be_empty
expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
expect(the_bundle).to include_gems("activesupport 6.1.2.1")
- @locked_checksums.checksum gem_repo2, "activesupport", "6.1.2.1"
-
expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
expect(the_bundle).to include_gems("tzinfo 2.0.4")
- @locked_checksums.checksum gem_repo2, "tzinfo", "2.0.4"
- @locked_checksums.delete "thread_safe"
-
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
- @locked_checksums.checksum gem_repo2, "concurrent-ruby", "1.1.9"
expect(lockfile).to eq <<~L
GEM
@@ -975,19 +780,19 @@ RSpec.describe "bundle install with gems on multiple sources" do
sidekiq (>= 6.1.0)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
- #{@locked_checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "upgrades the lockfile format and upgrades the requested gem when running bundle update with an argument" do
- bundle "update concurrent-ruby", artifice: "compact_index"
+ bundle "update concurrent-ruby", :artifice => "compact_index"
expect(err).to be_empty
expect(the_bundle).to include_gems("activesupport 6.0.3.4")
@@ -997,8 +802,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
- @locked_checksums.checksum gem_repo2, "concurrent-ruby", "1.1.9"
-
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo2/
@@ -1033,12 +836,12 @@ RSpec.describe "bundle install with gems on multiple sources" do
sidekiq (>= 6.1.0)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
- #{@locked_checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1047,8 +850,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "when a top-level gem has an indirect dependency present in the default source, but with a different version from the one resolved" do
before do
- build_lib "activesupport", "7.0.0.alpha", path: lib_path("rails/activesupport")
- build_lib "rails", "7.0.0.alpha", path: lib_path("rails") do |s|
+ build_lib "activesupport", "7.0.0.alpha", :path => lib_path("rails/activesupport")
+ build_lib "rails", "7.0.0.alpha", :path => lib_path("rails") do |s|
s.add_dependency "activesupport", "= 7.0.0.alpha"
end
@@ -1070,11 +873,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs all gems without warning" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", "rails 7.0.0.alpha")
- expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", source: "path@#{lib_path("rails/activesupport")}")
- expect(the_bundle).to include_gems("rails 7.0.0.alpha", source: "path@#{lib_path("rails")}")
+ expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", :source => "path@#{lib_path("rails/activesupport")}")
+ expect(the_bundle).to include_gems("rails 7.0.0.alpha", :source => "path@#{lib_path("rails")}")
end
end
@@ -1106,12 +909,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs from the default source without any warnings or errors and generates a proper lockfile" do
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo3, "handsoap", "0.2.5.5"
- c.checksum gem_repo2, "nokogiri", "1.11.1"
- c.checksum gem_repo2, "racca", "1.5.2"
- end
-
expected_lockfile = <<~L
GEM
remote: https://gem.repo2/
@@ -1127,30 +924,30 @@ RSpec.describe "bundle install with gems on multiple sources" do
nokogiri (>= 1.2.3)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
handsoap!
nokogiri
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
- bundle "install --verbose", artifice: "compact_index"
+ bundle "install --verbose", :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
- expect(the_bundle).to include_gems("handsoap 0.2.5.5", source: "remote3")
- expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", source: "remote2")
+ expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
+ expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
expect(lockfile).to eq(expected_lockfile)
# Even if the gems are already installed
FileUtils.rm bundled_app_lock
- bundle "install --verbose", artifice: "compact_index"
+ bundle "install --verbose", :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
- expect(the_bundle).to include_gems("handsoap 0.2.5.5", source: "remote3")
- expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", source: "remote2")
+ expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
+ expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
expect(lockfile).to eq(expected_lockfile)
end
end
@@ -1161,7 +958,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "not_in_repo1", "1.0.0"
end
- install_gemfile <<-G, artifice: "compact_index", raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
source "https://gem.repo3"
gem "not_in_repo1", :source => "https://gem.repo1"
G
@@ -1174,7 +971,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "with an existing lockfile" do
before do
- system_gems "rack-0.9.1", "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-0.9.1", "rack-1.0.0", :path => default_bundle_path
lockfile <<-L
GEM
@@ -1187,7 +984,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack (0.9.1)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
rack!
@@ -1217,11 +1014,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack (0.9.1)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
rack!
- #{checksums_section}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1239,7 +1036,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack (0.9.1)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
rack!
@@ -1264,48 +1061,20 @@ RSpec.describe "bundle install with gems on multiple sources" do
lockfile aggregate_gem_section_lockfile
end
- it "installs the existing lockfile but prints a warning when checksum validation is disabled", bundler: "< 3" do
+ it "installs the existing lockfile but prints a warning", :bundler => "< 3" do
bundle "config set --local deployment true"
- bundle "config set --local disable_checksum_validation true"
- bundle "install", artifice: "compact_index"
+ bundle "install", :artifice => "compact_index"
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
- expect(the_bundle).to include_gems("rack 0.9.1", source: "remote3")
- end
-
- it "prints a checksum warning when the checksums from both sources do not match", bundler: "< 3" do
- bundle "config set --local deployment true"
-
- bundle "install", artifice: "compact_index", raise_on_error: false
-
- api_checksum1 = checksum_digest(gem_repo1, "rack", "0.9.1")
- api_checksum3 = checksum_digest(gem_repo3, "rack", "0.9.1")
-
- expect(exitstatus).to eq(37)
- expect(err).to eq(<<~E.strip)
- [DEPRECATED] Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure.
- Bundler found mismatched checksums. This is a potential security risk.
- rack (0.9.1) sha256=#{api_checksum3}
- from the API at https://gem.repo3/
- rack (0.9.1) sha256=#{api_checksum1}
- from the API at https://gem.repo1/
-
- Mismatched checksums each have an authoritative source:
- 1. the API at https://gem.repo3/
- 2. the API at https://gem.repo1/
- You may need to alter your Gemfile sources to resolve this issue.
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
+ expect(the_bundle).to include_gems("rack 0.9.1", :source => "remote3")
end
- it "refuses to install the existing lockfile and prints an error", bundler: "3" do
+ it "refuses to install the existing lockfile and prints an error", :bundler => "3" do
bundle "config set --local deployment true"
- bundle "install", artifice: "compact_index", raise_on_error: false
+ bundle "install", :artifice => "compact_index", :raise_on_error =>false
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
@@ -1325,7 +1094,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "does not unlock the non-path gem after install" do
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
bundle %(exec ruby -e 'puts "OK"')
@@ -1338,7 +1107,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
system_gems "rack-0.9.1"
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
gem "rack" # should come from repo1!
G
@@ -1367,7 +1136,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
bundle "config set --local path ../gems/system"
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
# And then we add some new versions...
update_repo4 do
@@ -1378,7 +1147,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "allows them to be unlocked separately" do
# And install this gemfile, updating only foo.
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source 'https://gem.repo1'
gem 'rack'
gem 'foo', '~> 0.2', :source => 'https://gem.repo4'
@@ -1402,7 +1171,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_git "git1"
build_git "git2"
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
gem "rails"
@@ -1418,7 +1187,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "does not re-resolve" do
- bundle :install, artifice: "compact_index", verbose: true
+ bundle :install, :artifice => "compact_index", :verbose => true
expect(out).to include("using resolution from the lockfile")
expect(out).not_to include("re-resolving dependencies")
end
@@ -1427,7 +1196,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "when a gem is installed to system gems" do
before do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
gem "rack"
G
@@ -1441,7 +1210,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
# When this gemfile is installed...
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
source "https://gem.repo4" do
@@ -1463,14 +1232,14 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
# But we should still be able to find rack 2.0.1.1.forked and install it
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
end
end
end
describe "source changed to one containing a higher version of a dependency" do
before do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
gem "rack"
@@ -1484,11 +1253,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "bar"
end
- build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s|
+ build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
s.add_dependency "bar", "=1.0.0"
end
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo2"
gem "rack"
gemspec :path => "#{tmp.join("gemspec_test")}"
@@ -1506,11 +1275,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "bar"
end
- build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s|
+ build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
s.add_development_dependency "bar"
end
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
source "https://gem.repo4" do
@@ -1535,7 +1304,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "example", "1.0.2"
end
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo4"
gem "example", :source => "https://gem.repo2"
@@ -1544,9 +1313,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
bundle "info example"
expect(out).to include("example (0.1.0)")
- system_gems "example-1.0.2", path: default_bundle_path, gem_repo: gem_repo4
+ system_gems "example-1.0.2", :path => default_bundle_path, :gem_repo => gem_repo4
- bundle "update example --verbose", artifice: "compact_index"
+ bundle "update example --verbose", :artifice => "compact_index"
expect(out).not_to include("Using example 1.0.2")
expect(out).to include("Using example 0.1.0")
end
@@ -1560,9 +1329,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
G
- ruby <<~R, raise_on_error: false
- require 'bundler/setup'
- R
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ ruby <<~R, :raise_on_error => false
+ require 'bundler/setup'
+ R
+ end
expect(last_command).to be_failure
expect(err).to include("Could not find gem 'example' in locally installed gems.")
@@ -1577,13 +1348,13 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
G
- bundle "install", artifice: nil, raise_on_error: false
+ bundle "install", :artifice => nil, :raise_on_error => false
expect(last_command).to be_failure
expect(err).to include("Could not reach host gem.repo4. Check your network connection and try again.")
end
- context "when an indirect dependency is available from multiple ambiguous sources", bundler: "< 3" do
+ context "when an indirect dependency is available from multiple ambiguous sources", :bundler => "< 3" do
it "succeeds but warns, suggesting a source block" do
build_repo4 do
build_gem "depends_on_rack" do |s|
@@ -1592,7 +1363,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "rack"
end
- install_gemfile <<-G, artifice: "compact_index", raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
source "https://gem.repo4" do
@@ -1603,7 +1374,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
gem "thin"
end
G
- expect(err).to eq <<~EOS.strip
+ expect(err).to eq strip_whitespace(<<-EOS).strip
Warning: The gem 'rack' was found in multiple relevant sources.
* rubygems repository https://gem.repo1/
* rubygems repository https://gem.repo4/
@@ -1614,7 +1385,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- context "when an indirect dependency is available from multiple ambiguous sources", bundler: "3" do
+ context "when an indirect dependency is available from multiple ambiguous sources", :bundler => "3" do
it "raises, suggesting a source block" do
build_repo4 do
build_gem "depends_on_rack" do |s|
@@ -1623,7 +1394,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "rack"
end
- install_gemfile <<-G, artifice: "compact_index", raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
source "https://gem.repo4" do
gem "depends_on_rack"
@@ -1633,7 +1404,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
G
expect(last_command).to be_failure
- expect(err).to eq <<~EOS.strip
+ expect(err).to eq strip_whitespace(<<-EOS).strip
The gem 'rack' was found in multiple relevant sources.
* rubygems repository https://gem.repo1/
* rubygems repository https://gem.repo4/
@@ -1677,23 +1448,16 @@ RSpec.describe "bundle install with gems on multiple sources" do
mime-types (3.3.1)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
capybara (~> 2.5.0)
mime-types (~> 3.0)!
-
- CHECKSUMS
L
end
it "upgrades the lockfile correctly" do
- bundle "lock --update", artifice: "compact_index"
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "capybara", "2.5.0"
- c.checksum gem_repo4, "mime-types", "3.0.0"
- end
+ bundle "lock --update", :artifice => "compact_index"
expect(lockfile).to eq <<~L
GEM
@@ -1708,12 +1472,12 @@ RSpec.describe "bundle install with gems on multiple sources" do
mime-types (3.0.0)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
capybara (~> 2.5.0)
mime-types (~> 3.0)!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1747,12 +1511,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "handles that fine" do
- bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "pdf-writer", "1.1.8"
- c.checksum gem_repo2, "ruport", "1.7.0.3"
- end
+ bundle "install", :artifice => "compact_index_extra", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(lockfile).to eq <<~L
GEM
@@ -1767,11 +1526,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
pdf-writer (= 1.1.8)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
ruport (= 1.7.0.3)!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1805,12 +1564,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "handles that fine" do
- bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "pdf-writer", "1.1.8"
- c.checksum gem_repo2, "ruport", "1.7.0.3"
- end
+ bundle "install", :artifice => "compact_index_extra", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(lockfile).to eq <<~L
GEM
@@ -1825,11 +1579,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
pdf-writer (= 1.1.8)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
ruport (= 1.7.0.3)!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1857,11 +1611,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "handles that fine" do
- bundle "install --verbose", artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "pdf-writer", "1.1.8"
- end
+ bundle "install --verbose", :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(lockfile).to eq <<~L
GEM
@@ -1870,11 +1620,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
pdf-writer (1.1.8)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
pdf-writer (= 1.1.8)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1893,7 +1643,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "example", "1.0.0"
end
- install_gemfile <<~G, artifice: "compact_index"
+ install_gemfile <<~G, :artifice => "compact_index"
source "https://gem.repo2"
source "https://gem.repo4" do
@@ -1913,7 +1663,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "shows a proper error message and does not generate a corrupted lockfile" do
expect do
- bundle :install, artifice: "compact_index", raise_on_error: false, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle :install, :artifice => "compact_index", :raise_on_error => false, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end.not_to change { lockfile }
expect(err).to include("Could not find gem 'example' in rubygems repository https://gem.repo4/")
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index 1a33053dc6..cab53a663a 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -11,11 +11,11 @@ RSpec.describe "bundle install with specific platforms" do
setup_multiplatform_gem
install_gemfile(google_protobuf)
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- expect(the_bundle.locked_gems.platforms).to include(pl("x86_64-darwin-15"))
+ expect(the_bundle.locked_gems.platforms).to eq([pl("x86_64-darwin-15")])
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to include(
- "google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin"
- )
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
+ google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
+ ])
end
end
@@ -26,9 +26,9 @@ RSpec.describe "bundle install with specific platforms" do
system_gems "bundler-2.1.4"
# Consistent location to install and look for gems
- bundle "config set --local path vendor/bundle", env: { "BUNDLER_VERSION" => "2.1.4" }
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
- install_gemfile(google_protobuf, env: { "BUNDLER_VERSION" => "2.1.4" })
+ install_gemfile(google_protobuf, :env => { "BUNDLER_VERSION" => "2.1.4" })
# simulate lockfile created with old bundler, which only locks for ruby platform
lockfile <<-L
@@ -48,7 +48,7 @@ RSpec.describe "bundle install with specific platforms" do
L
# force strict usage of the lock file by setting frozen mode
- bundle "config set --local frozen true", env: { "BUNDLER_VERSION" => "2.1.4" }
+ bundle "config set --local frozen true", :env => { "BUNDLER_VERSION" => "2.1.4" }
# make sure the platform that got actually installed with the old bundler is used
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
@@ -62,14 +62,10 @@ RSpec.describe "bundle install with specific platforms" do
system_gems "bundler-2.1.4"
# Consistent location to install and look for gems
- bundle "config set --local path vendor/bundle", env: { "BUNDLER_VERSION" => "2.1.4" }
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
gemfile google_protobuf
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "google-protobuf", "3.0.0.alpha.4.0"
- end
-
# simulate lockfile created with old bundler, which only locks for ruby platform
lockfile <<-L
GEM
@@ -82,14 +78,12 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
google-protobuf
- #{checksums}
+
BUNDLED WITH
2.1.4
L
- bundle "update", env: { "BUNDLER_VERSION" => Bundler::VERSION }
-
- checksums.checksum gem_repo2, "google-protobuf", "3.0.0.alpha.5.0.5.1"
+ bundle "update", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
# make sure the platform that the platform specific dependency is used, since we're only locked to ruby
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
@@ -106,7 +100,7 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
google-protobuf
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -149,12 +143,12 @@ RSpec.describe "bundle install with specific platforms" do
end
it "still installs the generic RUBY variant if necessary" do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(out).to include("Installing nokogiri 1.3.10")
end
it "still installs the generic RUBY variant if necessary, even in frozen mode" do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" }
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" }
expect(out).to include("Installing nokogiri 1.3.10")
end
end
@@ -173,7 +167,7 @@ RSpec.describe "bundle install with specific platforms" do
system_gems "bundler-2.1.4"
# Consistent location to install and look for gems
- bundle "config set --local path vendor/bundle", env: { "BUNDLER_VERSION" => "2.1.4" }
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
gemfile <<-G
source "https://localgemserver.test"
@@ -197,10 +191,10 @@ RSpec.describe "bundle install with specific platforms" do
2.1.4
L
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Installing libv8 8.4.255.0 (universal-darwin)")
- bundle "add mini_racer --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ bundle "add mini_racer --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)")
end
end
@@ -234,7 +228,7 @@ RSpec.describe "bundle install with specific platforms" do
#{Bundler::VERSION}
L
- bundle "install --verbose", artifice: "compact_index_precompiled_before", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "install --verbose", :artifice => "compact_index_precompiled_before", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(out).to include("Installing grpc 1.50.0 (universal-darwin)")
end
end
@@ -309,10 +303,10 @@ RSpec.describe "bundle install with specific platforms" do
G
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- expect(the_bundle.locked_gems.platforms).to include(pl("x86_64-darwin-15"))
+ expect(the_bundle.locked_gems.platforms).to eq([pl("x86_64-darwin-15")])
expect(the_bundle).to include_gems("facter 2.4.6 universal-darwin", "CFPropertyList 1.0")
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to include("CFPropertyList-1.0",
- "facter-2.4.6-universal-darwin")
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(["CFPropertyList-1.0",
+ "facter-2.4.6-universal-darwin"])
end
end
@@ -327,8 +321,8 @@ RSpec.describe "bundle install with specific platforms" do
install_gemfile(google_protobuf)
bundle "lock --add-platform=#{x64_mingw32}"
- expect(the_bundle.locked_gems.platforms).to include(x64_mingw32, pl("x86_64-darwin-15"))
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to include(*%w[
+ expect(the_bundle.locked_gems.platforms).to eq([x64_mingw32, pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
google-protobuf-3.0.0.alpha.5.0.5.1-x64-mingw32
])
@@ -341,11 +335,11 @@ RSpec.describe "bundle install with specific platforms" do
install_gemfile(google_protobuf)
bundle "lock --add-platform=#{java}"
- expect(the_bundle.locked_gems.platforms).to include(java, pl("x86_64-darwin-15"))
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to include(
- "google-protobuf-3.0.0.alpha.5.0.5.1",
- "google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin"
- )
+ expect(the_bundle.locked_gems.platforms).to eq([java, pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
+ google-protobuf-3.0.0.alpha.5.0.5.1
+ google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
+ ])
end
end
end
@@ -403,7 +397,7 @@ RSpec.describe "bundle install with specific platforms" do
ERROR
simulate_platform "arm64-darwin-21" do
- bundle "lock", raise_on_error: false
+ bundle "lock", :raise_on_error => false
end
expect(err).to include(error_message).once
@@ -411,7 +405,7 @@ RSpec.describe "bundle install with specific platforms" do
# Make sure it doesn't print error twice in verbose mode
simulate_platform "arm64-darwin-21" do
- bundle "lock --verbose", raise_on_error: false
+ bundle "lock --verbose", :raise_on_error => false
end
expect(err).to include(error_message).once
@@ -445,7 +439,7 @@ RSpec.describe "bundle install with specific platforms" do
ERROR
simulate_platform "arm64-darwin-21" do
- bundle "lock", raise_on_error: false
+ bundle "lock", :raise_on_error => false
end
expect(err).to include(error_message).once
@@ -453,7 +447,7 @@ RSpec.describe "bundle install with specific platforms" do
# Make sure it doesn't print error twice in verbose mode
simulate_platform "arm64-darwin-21" do
- bundle "lock --verbose", raise_on_error: false
+ bundle "lock --verbose", :raise_on_error => false
end
expect(err).to include(error_message).once
@@ -470,7 +464,7 @@ RSpec.describe "bundle install with specific platforms" do
gem "sorbet-static", "0.5.9889"
G
- bundle "lock", raise_on_error: false, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
+ bundle "lock", :raise_on_error => false, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
expect(err).to include <<~ERROR.rstrip
Could not find gem 'sorbet-static (= 0.5.9889)' with platform 'ruby' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
@@ -517,7 +511,7 @@ RSpec.describe "bundle install with specific platforms" do
sorbet-runtime (= 0.5.10160)
PLATFORMS
- #{lockfile_platforms}
+ #{lockfile_platforms("ruby")}
DEPENDENCIES
sorbet-static-and-runtime
@@ -528,13 +522,6 @@ RSpec.describe "bundle install with specific platforms" do
bundle "update"
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "sorbet", "0.5.10160"
- c.checksum gem_repo4, "sorbet-runtime", "0.5.10160"
- c.checksum gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local
- c.checksum gem_repo4, "sorbet-static-and-runtime", "0.5.10160"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -548,11 +535,11 @@ RSpec.describe "bundle install with specific platforms" do
sorbet-runtime (= 0.5.10160)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
sorbet-static-and-runtime
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -584,11 +571,6 @@ RSpec.describe "bundle install with specific platforms" do
G
end
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "nokogiri", "1.13.0", "x86_64-darwin"
- c.no_checksum "sorbet-static", "0.5.10601", "x86_64-darwin"
- end
-
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -603,8 +585,8 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
nokogiri
- sorbet-static
- #{checksums}
+ sorbet
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -626,7 +608,7 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
nokogiri
sorbet-static
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -680,13 +662,6 @@ RSpec.describe "bundle install with specific platforms" do
bundle "update"
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "sorbet", "0.5.10160"
- c.checksum gem_repo4, "sorbet-runtime", "0.5.10160"
- c.checksum gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local
- c.checksum gem_repo4, "sorbet-static-and-runtime", "0.5.10160"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -700,86 +675,16 @@ RSpec.describe "bundle install with specific platforms" do
sorbet-runtime (= 0.5.10160)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
sorbet-static-and-runtime
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
- it "automatically fixes the lockfile if multiple platforms locked, but no valid versions of direct dependencies for all of them" do
- simulate_platform "x86_64-linux" do
- build_repo4 do
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "x86_64-linux"
- end
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "arm-linux"
- end
-
- build_gem "sorbet-static", "0.5.10696" do |s|
- s.platform = "x86_64-linux"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "nokogiri"
- gem "sorbet-static"
- G
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.14.0-arm-linux)
- nokogiri (1.14.0-x86_64-linux)
- sorbet-static (0.5.10696-x86_64-linux)
-
- PLATFORMS
- aarch64-linux
- arm-linux
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
- sorbet-static
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- bundle "update"
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "nokogiri", "1.14.0", "x86_64-linux"
- c.checksum gem_repo4, "sorbet-static", "0.5.10696", "x86_64-linux"
- end
-
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.14.0-x86_64-linux)
- sorbet-static (0.5.10696-x86_64-linux)
-
- PLATFORMS
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
- sorbet-static
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
it "automatically fixes the lockfile without removing other variants if it's missing platform gems, but they are installed locally" do
simulate_platform "x86_64-darwin-21" do
build_repo4 do
@@ -799,11 +704,6 @@ RSpec.describe "bundle install with specific platforms" do
gem "sorbet-static", "= 0.5.10549"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "sorbet-static", "0.5.10549", "universal-darwin-20"
- c.checksum gem_repo4, "sorbet-static", "0.5.10549", "universal-darwin-21"
- end
-
# Make sure the lockfile is missing sorbet-static-0.5.10549-universal-darwin-21
lockfile <<~L
GEM
@@ -816,15 +716,13 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
sorbet-static (= 0.5.10549)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
- checksums.no_checksum "sorbet-static", "0.5.10549", "universal-darwin-21"
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -837,7 +735,7 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
sorbet-static (= 0.5.10549)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -874,8 +772,6 @@ RSpec.describe "bundle install with specific platforms" do
nokogiri
tzinfo (~> 1.2)
- CHECKSUMS
-
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -884,30 +780,7 @@ RSpec.describe "bundle install with specific platforms" do
bundle "lock --update"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "nokogiri", "1.13.8"
- c.no_checksum "nokogiri", "1.13.8", Gem::Platform.local
- end
-
- updated_lockfile = <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.13.8)
- nokogiri (1.13.8-#{Gem::Platform.local})
-
- PLATFORMS
- #{lockfile_platforms("ruby")}
-
- DEPENDENCIES
- nokogiri
- tzinfo (~> 1.2)
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- expect(lockfile).to eq(updated_lockfile)
+ expect(lockfile).to eq(original_lockfile)
end
it "does not remove ruby when adding a new gem to the Gemfile" do
@@ -923,11 +796,6 @@ RSpec.describe "bundle install with specific platforms" do
gem "rack"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "concurrent-ruby", "1.2.2"
- c.no_checksum "rack", "3.0.7"
- end
-
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -939,7 +807,7 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
concurrent-ruby
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -954,12 +822,12 @@ RSpec.describe "bundle install with specific platforms" do
rack (3.0.7)
PLATFORMS
- #{lockfile_platforms("ruby", generic_local_platform, defaults: [])}
+ #{formatted_lockfile_platforms(*["ruby", generic_local_platform].uniq)}
DEPENDENCIES
concurrent-ruby
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1022,10 +890,6 @@ RSpec.describe "bundle install with specific platforms" do
gem "nokogiri", "1.14.0"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "nokogiri", "1.14.0", "x86_64-linux"
- end
-
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -1037,17 +901,13 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
nokogiri (= 1.14.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
bundle :install
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "nokogiri", "1.14.0"
- end
-
expect(lockfile).to eq(<<~L)
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -1059,320 +919,6 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
nokogiri (= 1.14.0)
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
- it "locks specific platforms automatically" do
- simulate_platform "x86_64-linux" do
- build_repo4 do
- build_gem "nokogiri", "1.14.0"
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "x86_64-linux"
- end
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "arm-linux"
- end
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "x64-mingw32"
- end
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "java"
- end
-
- build_gem "sorbet-static", "0.5.10696" do |s|
- s.platform = "x86_64-linux"
- end
- build_gem "sorbet-static", "0.5.10696" do |s|
- s.platform = "universal-darwin-22"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "nokogiri"
- G
-
- bundle "lock"
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "nokogiri", "1.14.0"
- c.no_checksum "nokogiri", "1.14.0", "arm-linux"
- c.no_checksum "nokogiri", "1.14.0", "x86_64-linux"
- end
-
- # locks all compatible platforms, excluding Java and Windows
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.14.0)
- nokogiri (1.14.0-arm-linux)
- nokogiri (1.14.0-x86_64-linux)
-
- PLATFORMS
- arm-linux
- ruby
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "nokogiri"
- gem "sorbet-static"
- G
-
- FileUtils.rm bundled_app_lock
-
- bundle "lock"
-
- checksums.delete "nokogiri", "arm-linux"
- checksums.no_checksum "sorbet-static", "0.5.10696", "universal-darwin-22"
- checksums.no_checksum "sorbet-static", "0.5.10696", "x86_64-linux"
-
- # locks only platforms compatible with all gems in the bundle
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.14.0)
- nokogiri (1.14.0-x86_64-linux)
- sorbet-static (0.5.10696-universal-darwin-22)
- sorbet-static (0.5.10696-x86_64-linux)
-
- PLATFORMS
- universal-darwin-22
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
- sorbet-static
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
- it "does not fail when a platform variant is incompatible with the current ruby and another equivalent platform specific variant is part of the resolution", rubygems: ">= 3.3.21" do
- build_repo4 do
- build_gem "nokogiri", "1.15.5"
-
- build_gem "nokogiri", "1.15.5" do |s|
- s.platform = "x86_64-linux"
- s.required_ruby_version = "< #{current_ruby_minor}.dev"
- end
-
- build_gem "sass-embedded", "1.69.5"
-
- build_gem "sass-embedded", "1.69.5" do |s|
- s.platform = "x86_64-linux-gnu"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "nokogiri"
- gem "sass-embedded"
- G
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "nokogiri", "1.15.5"
- c.no_checksum "sass-embedded", "1.69.5"
- c.checksum gem_repo4, "sass-embedded", "1.69.5", "x86_64-linux-gnu"
- end
-
- simulate_platform "x86_64-linux" do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- # locks all compatible platforms, excluding Java and Windows
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.15.5)
- sass-embedded (1.69.5)
- sass-embedded (1.69.5-x86_64-linux-gnu)
-
- PLATFORMS
- ruby
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
- sass-embedded
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
- it "does not add ruby platform gem if it brings extra dependencies not resolved originally" do
- build_repo4 do
- build_gem "nokogiri", "1.15.5" do |s|
- s.add_dependency "mini_portile2", "~> 2.8.2"
- end
-
- build_gem "nokogiri", "1.15.5" do |s|
- s.platform = "x86_64-linux"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "nokogiri"
- G
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo4, "nokogiri", "1.15.5", "x86_64-linux"
- end
-
- simulate_platform "x86_64-linux" do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.15.5-x86_64-linux)
-
- PLATFORMS
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
- ["x86_64-linux", "x86_64-linux-musl"].each do |host_platform|
- describe "on host platform #{host_platform}" do
- it "adds current musl platform" do
- build_repo4 do
- build_gem "rcee_precompiled", "0.5.0" do |s|
- s.platform = "x86_64-linux"
- end
-
- build_gem "rcee_precompiled", "0.5.0" do |s|
- s.platform = "x86_64-linux-musl"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "rcee_precompiled", "0.5.0"
- G
-
- simulate_platform host_platform do
- bundle "lock", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- rcee_precompiled (0.5.0-x86_64-linux)
- rcee_precompiled (0.5.0-x86_64-linux-musl)
-
- PLATFORMS
- x86_64-linux
- x86_64-linux-musl
-
- DEPENDENCIES
- rcee_precompiled (= 0.5.0)
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
- end
- end
-
- it "adds current musl platform, when there are also gnu variants", rubygems: ">= 3.3.21" do
- build_repo4 do
- build_gem "rcee_precompiled", "0.5.0" do |s|
- s.platform = "x86_64-linux-gnu"
- end
-
- build_gem "rcee_precompiled", "0.5.0" do |s|
- s.platform = "x86_64-linux-musl"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "rcee_precompiled", "0.5.0"
- G
-
- simulate_platform "x86_64-linux-musl" do
- bundle "lock", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- rcee_precompiled (0.5.0-x86_64-linux-gnu)
- rcee_precompiled (0.5.0-x86_64-linux-musl)
-
- PLATFORMS
- x86_64-linux-gnu
- x86_64-linux-musl
-
- DEPENDENCIES
- rcee_precompiled (= 0.5.0)
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
- it "does not add current platform if there's an equivalent less specific platform among the ones resolved" do
- build_repo4 do
- build_gem "rcee_precompiled", "0.5.0" do |s|
- s.platform = "universal-darwin"
- end
- end
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "rcee_precompiled", "0.5.0"
- G
-
- simulate_platform "x86_64-darwin-15" do
- bundle "lock", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
-
- expect(lockfile).to eq(<<~L)
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- rcee_precompiled (0.5.0-universal-darwin)
-
- PLATFORMS
- universal-darwin
-
- DEPENDENCIES
- rcee_precompiled (= 0.5.0)
BUNDLED WITH
#{Bundler::VERSION}
diff --git a/spec/bundler/install/gemfile_spec.rb b/spec/bundler/install/gemfile_spec.rb
index 158645d3eb..e643573454 100644
--- a/spec/bundler/install/gemfile_spec.rb
+++ b/spec/bundler/install/gemfile_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe "bundle install" do
context "with duplicated gems" do
it "will display a warning" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem 'rails', '~> 4.0.0'
@@ -20,7 +20,7 @@ RSpec.describe "bundle install" do
gem 'rack'
G
- bundle :install, gemfile: bundled_app("NotGemfile")
+ bundle :install, :gemfile => bundled_app("NotGemfile")
# Specify BUNDLE_GEMFILE for `the_bundle`
# to retrieve the proper Gemfile
@@ -46,8 +46,8 @@ RSpec.describe "bundle install" do
end
it "uses the gemfile while in a subdirectory" do
bundled_app("subdir").mkpath
- bundle "install", dir: bundled_app("subdir")
- bundle "list", dir: bundled_app("subdir")
+ bundle "install", :dir => bundled_app("subdir")
+ bundle "list", :dir => bundled_app("subdir")
expect(out).to include("rack (1.0.0)")
end
@@ -61,7 +61,7 @@ RSpec.describe "bundle install" do
gem "rack", :lib => "rack"
G
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to match(/You passed :lib as an option for gem 'rack', but it is invalid/)
end
end
diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb
index 50add8743b..65be262748 100644
--- a/spec/bundler/install/gems/compact_index_spec.rb
+++ b/spec/bundler/install/gems/compact_index_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -21,7 +21,7 @@ RSpec.describe "compact index api" do
gem " sinatra"
G
- bundle :install, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("' sinatra' is not a valid gem name because it contains whitespace.")
end
@@ -31,7 +31,7 @@ RSpec.describe "compact index api" do
gem "rails"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems(
"rails 2.3.2",
@@ -44,14 +44,14 @@ RSpec.describe "compact index api" do
end
it "should handle case sensitivity conflicts" do
- build_repo4(build_compact_index: false) do
+ build_repo4 do
build_gem "rack", "1.0" do |s|
s.add_runtime_dependency("Rack", "0.1")
end
build_gem "Rack", "0.1"
end
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
source "#{source_uri}"
gem "rack", "1.0"
gem "Rack", "0.1"
@@ -69,7 +69,7 @@ RSpec.describe "compact index api" do
gem "net-sftp"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems "net-sftp 1.1.1"
end
@@ -78,11 +78,11 @@ RSpec.describe "compact index api" do
source "#{source_uri}"
gem "rack"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
bundle "config set --local deployment true"
bundle "config set --local path vendor/bundle"
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -100,7 +100,7 @@ RSpec.describe "compact index api" do
end
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("rails 2.3.2")
end
@@ -116,10 +116,10 @@ RSpec.describe "compact index api" do
gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
bundle "config set --local deployment true"
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("rails 2.3.2")
end
@@ -131,9 +131,9 @@ RSpec.describe "compact index api" do
gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
- bundle "install", artifice: "compact_index"
+ bundle "install", :artifice => "compact_index"
bundle "config set --local deployment true"
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("foo 1.0")
end
@@ -144,7 +144,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, verbose: true, artifice: "compact_index_forbidden"
+ bundle :install, :verbose => true, :artifice => "compact_index_forbidden"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -155,10 +155,11 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, verbose: true, artifice: "compact_index_checksum_mismatch"
+ bundle :install, :verbose => true, :artifice => "compact_index_checksum_mismatch"
expect(out).to include("Fetching gem metadata from #{source_uri}")
- expect(out).to include("The checksum of /versions does not match the checksum provided by the server!")
- expect(out).to include('Calculated checksums {"sha-256"=>"8KfZiM/fszVkqhP/m5s9lvE6M9xKu4I1bU4Izddp5Ms="} did not match expected {"sha-256"=>"ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="}')
+ expect(out).to include <<-'WARN'
+The checksum of /versions does not match the checksum provided by the server! Something is wrong (local checksum is "\"d41d8cd98f00b204e9800998ecf8427e\"", was expecting "\"123\"").
+ WARN
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -168,15 +169,13 @@ RSpec.describe "compact index api" do
gem "rack"
G
- versions = Pathname.new(Bundler.rubygems.user_home).join(
- ".bundle", "cache", "compact_index",
- "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions"
- )
- versions.dirname.mkpath
- versions.write("created_at")
+ versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
+ "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions")
+ FileUtils.mkdir_p(File.dirname(versions))
+ FileUtils.touch(versions)
FileUtils.chmod("-r", versions)
- bundle :install, artifice: "compact_index", raise_on_error: false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include(
"There was an error while trying to read from `#{versions}`. It is likely that you need to grant read permissions for that path."
@@ -191,7 +190,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -202,11 +201,11 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index_host_redirect"
+ bundle :install, :artifice => "compact_index_host_redirect"
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "handles host redirects without Gem::Net::HTTP::Persistent" do
+ it "handles host redirects without Net::HTTP::Persistent" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -225,7 +224,7 @@ RSpec.describe "compact index api" do
H
end
- bundle :install, artifice: "compact_index_host_redirect", requires: [lib_path("disable_net_http_persistent.rb")]
+ bundle :install, :artifice => "compact_index_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")]
expect(out).to_not match(/Too many redirects/)
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -236,7 +235,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index_redirects", raise_on_error: false
+ bundle :install, :artifice => "compact_index_redirects", :raise_on_error => false
expect(err).to match(/Too many redirects/)
end
@@ -247,7 +246,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle "install --full-index", artifice: "compact_index"
+ bundle "install --full-index", :artifice => "compact_index"
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -258,7 +257,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle "update --full-index", artifice: "compact_index", all: true
+ bundle "update --full-index", :artifice => "compact_index", :all => true
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -288,14 +287,14 @@ RSpec.describe "compact index api" do
end
end
- system_gems %w[rack-1.0.0 thin-1.0 net_a-1.0], gem_repo: gem_repo2
+ system_gems %w[rack-1.0.0 thin-1.0 net_a-1.0], :gem_repo => gem_repo2
bundle "config set --local path.system true"
- ENV["BUNDLER_SPEC_ALL_REQUESTS"] = <<~EOS.strip
+ ENV["BUNDLER_SPEC_ALL_REQUESTS"] = strip_whitespace(<<-EOS).strip
#{source_uri}/versions
#{source_uri}/info/rack
EOS
- install_gemfile <<-G, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ install_gemfile <<-G, :artifice => "compact_index", :verbose => true, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
source "#{source_uri}"
gem "rack"
G
@@ -303,7 +302,7 @@ RSpec.describe "compact index api" do
expect(last_command.stdboth).not_to include "Double checking"
end
- it "fetches again when more dependencies are found in subsequent sources", bundler: "< 3" do
+ it "fetches again when more dependencies are found in subsequent sources", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -317,7 +316,7 @@ RSpec.describe "compact index api" do
gem "back_deps"
G
- bundle :install, artifice: "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
end
@@ -329,7 +328,7 @@ RSpec.describe "compact index api" do
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end
- install_gemfile <<-G, artifice: "compact_index_extra", verbose: true
+ install_gemfile <<-G, :artifice => "compact_index_extra", :verbose => true
source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
@@ -344,7 +343,7 @@ RSpec.describe "compact index api" do
source "#{source_uri}"
gem "rack", "1.0.0"
G
- bundle :install, artifice: "compact_index_extra_api"
+ bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "rack 1.0.0"
build_repo4 do
@@ -358,11 +357,11 @@ RSpec.describe "compact index api" do
source "#{source_uri}/extra"
gem "rack", "1.2"
G
- bundle :install, artifice: "compact_index_extra_api"
+ bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "rack 1.2"
end
- it "considers all possible versions of dependencies from all api gem sources", bundler: "< 3" do
+ it "considers all possible versions of dependencies from all api gem sources", :bundler => "< 3" do
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
@@ -380,7 +379,7 @@ RSpec.describe "compact index api" do
gem 'somegem', '1.0.0'
G
- bundle :install, artifice: "compact_index_extra_api"
+ bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "somegem 1.0.0"
expect(the_bundle).to include_gems "activesupport 1.2.3"
@@ -401,7 +400,7 @@ RSpec.describe "compact index api" do
end
G
- bundle :install, artifice: "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
expect(out).to include("Fetching gem metadata from http://localgemserver.test/")
expect(out).to include("Fetching source index from http://localgemserver.test/extra")
@@ -417,7 +416,7 @@ RSpec.describe "compact index api" do
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end
- install_gemfile <<-G, artifice: "compact_index_extra_missing"
+ install_gemfile <<-G, :artifice => "compact_index_extra_missing", :env => env_for_missing_prerelease_default_gem_activation
source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
@@ -437,7 +436,7 @@ RSpec.describe "compact index api" do
FileUtils.rm_rf Dir[gem_repo4("gems/foo-*.gem")]
end
- install_gemfile <<-G, artifice: "compact_index_extra_api_missing"
+ install_gemfile <<-G, :artifice => "compact_index_extra_api_missing", :env => env_for_missing_prerelease_default_gem_activation
source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
@@ -454,11 +453,11 @@ RSpec.describe "compact index api" do
gem 'foo'
G
- bundle :install, artifice: "compact_index_api_missing"
+ bundle :install, :artifice => "compact_index_api_missing"
expect(the_bundle).to include_gems "foo 1.0"
end
- it "fetches again when more dependencies are found in subsequent sources using deployment mode", bundler: "< 3" do
+ it "fetches again when more dependencies are found in subsequent sources using deployment mode", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -472,9 +471,9 @@ RSpec.describe "compact index api" do
gem "back_deps"
G
- bundle :install, artifice: "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
bundle "config --set local deployment true"
- bundle :install, artifice: "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
@@ -493,9 +492,9 @@ RSpec.describe "compact index api" do
end
G
- bundle :install, artifice: "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
bundle "config set --local deployment true"
- bundle :install, artifice: "compact_index_extra"
+ bundle :install, :artifice => "compact_index_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
@@ -512,40 +511,40 @@ RSpec.describe "compact index api" do
gem "bundler_dep"
G
- bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ bundle :install, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Fetching gem metadata from #{source_uri}")
end
- it "installs the binstubs", bundler: "< 3" do
+ it "installs the binstubs", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle "install --binstubs", artifice: "compact_index"
+ bundle "install --binstubs", :artifice => "compact_index"
gembin "rackup"
expect(out).to eq("1.0.0")
end
- it "installs the bins when using --path and uses autoclean", bundler: "< 3" do
+ it "installs the bins when using --path and uses autoclean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle "install --path vendor/bundle", artifice: "compact_index"
+ bundle "install --path vendor/bundle", :artifice => "compact_index"
expect(vendored_gems("bin/rackup")).to exist
end
- it "installs the bins when using --path and uses bundle clean", bundler: "< 3" do
+ it "installs the bins when using --path and uses bundle clean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle "install --path vendor/bundle --no-clean", artifice: "compact_index"
+ bundle "install --path vendor/bundle --no-clean", :artifice => "compact_index"
expect(vendored_gems("bin/rackup")).to exist
end
@@ -556,7 +555,7 @@ RSpec.describe "compact index api" do
gem 'rack-obama'
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Post-install message from rack:")
end
@@ -566,7 +565,7 @@ RSpec.describe "compact index api" do
gem 'rack_middleware'
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
expect(out).to include("Post-install message from rack:")
expect(out).to include("Rack's post install message")
end
@@ -575,7 +574,7 @@ RSpec.describe "compact index api" do
let(:user) { "user" }
let(:password) { "pass" }
let(:basic_auth_source_uri) do
- uri = Gem::URI.parse(source_uri)
+ uri = Bundler::URI.parse(source_uri)
uri.user = user
uri.password = password
@@ -588,7 +587,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index_basic_authentication"
+ bundle :install, :artifice => "compact_index_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -599,19 +598,19 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, verbose: true, artifice: "compact_index_basic_authentication"
+ bundle :install, :verbose => true, :artifice => "compact_index_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "strips http basic auth creds when warning about ambiguous sources", bundler: "< 3" do
+ it "strips http basic auth creds when warning about ambiguous sources", :bundler => "< 3" do
gemfile <<-G
source "#{basic_auth_source_uri}"
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle :install, artifice: "compact_index_basic_authentication"
+ bundle :install, :artifice => "compact_index_basic_authentication"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -623,7 +622,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index_creds_diff_host"
+ bundle :install, :artifice => "compact_index_creds_diff_host"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -638,7 +637,7 @@ RSpec.describe "compact index api" do
it "reads authentication details by host name from bundle config" do
bundle "config set #{source_hostname} #{user}:#{password}"
- bundle :install, artifice: "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -648,7 +647,7 @@ RSpec.describe "compact index api" do
# The trailing slash is necessary here; Fetcher canonicalizes the URI.
bundle "config set #{source_uri}/ #{user}:#{password}"
- bundle :install, artifice: "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -656,7 +655,7 @@ RSpec.describe "compact index api" do
it "should use the API" do
bundle "config set #{source_hostname} #{user}:#{password}"
- bundle :install, artifice: "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -669,26 +668,26 @@ RSpec.describe "compact index api" do
bundle "config set #{source_hostname} otheruser:wrong"
- bundle :install, artifice: "compact_index_strict_basic_authentication"
+ bundle :install, :artifice => "compact_index_strict_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "shows instructions if auth is not provided for the source" do
- bundle :install, artifice: "compact_index_strict_basic_authentication", raise_on_error: false
+ bundle :install, :artifice => "compact_index_strict_basic_authentication", :raise_on_error => false
expect(err).to include("bundle config set --global #{source_hostname} username:password")
end
it "fails if authentication has already been provided, but failed" do
bundle "config set #{source_hostname} #{user}:wrong"
- bundle :install, artifice: "compact_index_strict_basic_authentication", raise_on_error: false
+ bundle :install, :artifice => "compact_index_strict_basic_authentication", :raise_on_error => false
expect(err).to include("Bad username or password")
end
it "does not fallback to old dependency API if bad authentication is provided" do
bundle "config set #{source_hostname} #{user}:wrong"
- bundle :install, artifice: "compact_index_strict_basic_authentication", raise_on_error: false, verbose: true
+ bundle :install, :artifice => "compact_index_strict_basic_authentication", :raise_on_error => false, :verbose => true
expect(err).to include("Bad username or password")
expect(out).to include("HTTP 401 Unauthorized http://user@localgemserver.test/versions")
expect(out).not_to include("HTTP 401 Unauthorized http://user@localgemserver.test/api/v1/dependencies")
@@ -704,7 +703,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, artifice: "compact_index_basic_authentication"
+ bundle :install, :artifice => "compact_index_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
@@ -729,7 +728,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false
+ bundle :install, :env => { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, :raise_on_error => false
expect(err).to include("OpenSSL")
end
end
@@ -739,7 +738,7 @@ RSpec.describe "compact index api" do
# Install a monkeypatch that reproduces the effects of openssl raising
# a certificate validation error when RubyGems tries to connect.
gemfile <<-G
- class Gem::Net::HTTP
+ class Net::HTTP
def start
raise OpenSSL::SSL::SSLError, "certificate verify failed"
end
@@ -749,7 +748,7 @@ RSpec.describe "compact index api" do
gem "rack"
G
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to match(/could not verify the SSL certificate/i)
end
end
@@ -757,7 +756,7 @@ RSpec.describe "compact index api" do
context ".gemrc with sources is present" do
it "uses other sources declared in the Gemfile" do
File.open(home(".gemrc"), "w") do |file|
- file.puts({ sources: ["https://rubygems.org"] }.to_yaml)
+ file.puts({ :sources => ["https://rubygems.org"] }.to_yaml)
end
begin
@@ -766,30 +765,21 @@ RSpec.describe "compact index api" do
gem 'rack'
G
- bundle :install, artifice: "compact_index_forbidden"
+ bundle :install, :artifice => "compact_index_forbidden"
ensure
home(".gemrc").rmtree
end
end
end
- it "performs update with etag not-modified" do
- versions_etag = Pathname.new(Bundler.rubygems.user_home).join(
- ".bundle", "cache", "compact_index",
- "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions.etag"
- )
- expect(versions_etag.file?).to eq(false)
-
+ it "performs partial update with a non-empty range" do
gemfile <<-G
source "#{source_uri}"
gem 'rack', '0.9.1'
G
- # Initial install creates the cached versions file and etag file
- bundle :install, artifice: "compact_index"
-
- expect(versions_etag.file?).to eq(true)
- previous_content = versions_etag.binread
+ # Initial install creates the cached versions file
+ bundle :install, :artifice => "compact_index"
# Update the Gemfile so we can check subsequent install was successful
gemfile <<-G
@@ -797,59 +787,8 @@ RSpec.describe "compact index api" do
gem 'rack', '1.0.0'
G
- # Second install should match etag
- bundle :install, artifice: "compact_index_etag_match"
-
- expect(versions_etag.binread).to eq(previous_content)
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- it "performs full update when range is ignored" do
- gemfile <<-G
- source "#{source_uri}"
- gem 'rack', '0.9.1'
- G
-
- # Initial install creates the cached versions file and etag file
- bundle :install, artifice: "compact_index"
-
- gemfile <<-G
- source "#{source_uri}"
- gem 'rack', '1.0.0'
- G
-
- versions = Pathname.new(Bundler.rubygems.user_home).join(
- ".bundle", "cache", "compact_index",
- "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions"
- )
- # Modify the cached file. The ranged request will be based on this but,
- # in this test, the range is ignored so this gets overwritten, allowing install.
- versions.write "ruining this file"
-
- bundle :install, artifice: "compact_index_range_ignored"
-
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- it "performs partial update with a non-empty range" do
- build_repo4 do
- build_gem "rack", "0.9.1"
- end
-
- # Initial install creates the cached versions file
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
- source "#{source_uri}"
- gem 'rack', '0.9.1'
- G
-
- update_repo4 do
- build_gem "rack", "1.0.0"
- end
-
- install_gemfile <<-G, artifice: "compact_index_partial_update", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
- source "#{source_uri}"
- gem 'rack', '1.0.0'
- G
+ # Second install should make only a partial request to /versions
+ bundle :install, :artifice => "compact_index_partial_update"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -860,48 +799,24 @@ RSpec.describe "compact index api" do
gem 'rack'
G
- # Create a partial cache versions file
- versions = Pathname.new(Bundler.rubygems.user_home).join(
- ".bundle", "cache", "compact_index",
- "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions"
- )
- versions.dirname.mkpath
- versions.write("created_at")
-
- bundle :install, artifice: "compact_index_concurrent_download"
-
- expect(versions.read).to start_with("created_at")
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
-
- it "performs a partial update that fails digest check, then a full update" do
- build_repo4 do
- build_gem "rack", "0.9.1"
- end
-
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
- source "#{source_uri}"
- gem 'rack', '0.9.1'
- G
-
- update_repo4 do
- build_gem "rack", "1.0.0"
- end
+ # Create an empty file to trigger a partial download
+ versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
+ "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions")
+ FileUtils.mkdir_p(File.dirname(versions))
+ FileUtils.touch(versions)
- install_gemfile <<-G, artifice: "compact_index_partial_update_bad_digest", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
- source "#{source_uri}"
- gem 'rack', '1.0.0'
- G
+ bundle :install, :artifice => "compact_index_concurrent_download"
+ expect(File.read(versions)).to start_with("created_at")
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "performs full update if server endpoints serve partial content responses but don't have incremental content and provide no digest" do
+ it "performs full update if server endpoints serve partial content responses but don't have incremental content and provide no Etag" do
build_repo4 do
build_gem "rack", "0.9.1"
end
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
source "#{source_uri}"
gem 'rack', '0.9.1'
G
@@ -910,7 +825,7 @@ RSpec.describe "compact index api" do
build_gem "rack", "1.0.0"
end
- install_gemfile <<-G, artifice: "compact_index_partial_update_no_digest_not_incremental", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ install_gemfile <<-G, :artifice => "compact_index_partial_update_no_etag_not_incremental", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
source "#{source_uri}"
gem 'rack', '1.0.0'
G
@@ -924,19 +839,15 @@ RSpec.describe "compact index api" do
gem 'rack', '0.9.1'
G
- bundle :install, artifice: "compact_index"
-
- # We must remove the etag so that we don't ignore the range and get a 304 Not Modified.
- rake_info_etag_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
- "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "info-etags", "rack-11690b09f16021ff06a6857d784a1870")
- File.unlink(rake_info_etag_path) if File.exist?(rake_info_etag_path)
-
rake_info_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
"localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "info", "rack")
+
+ bundle :install, :artifice => "compact_index"
+
expected_rack_info_content = File.read(rake_info_path)
- # Modify the cache files to make the range not satisfiable
- File.open(rake_info_path, "a") {|f| f << "0.9.2 |checksum:c55b525b421fd833a93171ad3d7f04528ca8e87d99ac273f8933038942a5888c" }
+ # Modify the cache files. We expect them to be reset to the normal ones when we re-run :install
+ File.open(rake_info_path, "w") {|f| f << (expected_rack_info_content + "this is different") }
# Update the Gemfile so the next install does its normal things
gemfile <<-G
@@ -946,7 +857,7 @@ RSpec.describe "compact index api" do
# The cache files now being longer means the requested range is going to be not satisfiable
# Bundler must end up requesting the whole file to fix things up.
- bundle :install, artifice: "compact_index_range_not_satisfiable"
+ bundle :install, :artifice => "compact_index_range_not_satisfiable"
resulting_rack_info_content = File.read(rake_info_path)
@@ -954,7 +865,7 @@ RSpec.describe "compact index api" do
end
it "fails gracefully when the source URI has an invalid scheme" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "htps://rubygems.org"
gem "rack"
G
@@ -965,76 +876,38 @@ RSpec.describe "compact index api" do
end
describe "checksum validation" do
- before do
- lockfile <<-L
- GEM
- remote: #{source_uri}
- specs:
- rack (1.0.0)
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
- #{checksums_section}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "handles checksums from the server in base64" do
- api_checksum = checksum_digest(gem_repo1, "rack", "1.0.0")
- rack_checksum = [[api_checksum].pack("H*")].pack("m0")
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => rack_checksum }
- source "#{source_uri}"
- gem "rack"
- G
-
- expect(out).to include("Fetching gem metadata from #{source_uri}")
- expect(the_bundle).to include_gems("rack 1.0.0")
- end
-
it "raises when the checksum does not match" do
- install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum", raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum", :raise_on_error => false
source "#{source_uri}"
gem "rack"
G
- gem_path = if Bundler.feature_flag.global_gem_cache?
- default_cache_path.dirname.join("cache", "gems", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "rack-1.0.0.gem")
- else
- default_cache_path.dirname.join("rack-1.0.0.gem")
- end
-
- expect(exitstatus).to eq(37)
- expect(err).to eq <<~E.strip
- Bundler found mismatched checksums. This is a potential security risk.
- rack (1.0.0) sha256=2222222222222222222222222222222222222222222222222222222222222222
- from the API at http://localgemserver.test/
- #{checksum_to_lock(gem_repo1, "rack", "1.0.0")}
- from the gem at #{gem_path}
-
- If you trust the API at http://localgemserver.test/, to resolve this issue you can:
- 1. remove the gem at #{gem_path}
- 2. run `bundle install`
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
+ expect(exitstatus).to eq(19)
+ expect(err).
+ to include("Bundler cannot continue installing rack (1.0.0).").
+ and include("The checksum for the downloaded `rack-1.0.0.gem` does not match the checksum given by the server.").
+ and include("This means the contents of the downloaded gem is different from what was uploaded to the server, and could be a potential security issue.").
+ and include("To resolve this issue:").
+ and include("1. delete the downloaded gem located at: `#{default_bundle_path}/gems/rack-1.0.0/rack-1.0.0.gem`").
+ and include("2. run `bundle install`").
+ and include("If you wish to continue installing the downloaded gem, and are certain it does not pose a security issue despite the mismatching checksum, do the following:").
+ and include("1. run `bundle config set --local disable_checksum_validation true` to turn off checksum verification").
+ and include("2. run `bundle install`").
+ and match(/\(More info: The expected SHA256 checksum was "#{"ab" * 22}", but the checksum for the downloaded gem was ".+?"\.\)/)
end
it "raises when the checksum is the wrong length" do
- install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => "checksum!", "DEBUG" => "1" }, verbose: true, raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum", :env => { "BUNDLER_SPEC_RACK_CHECKSUM" => "checksum!", "DEBUG" => "1" }, :verbose => true, :raise_on_error => false
source "#{source_uri}"
gem "rack"
G
- expect(exitstatus).to eq(14)
- expect(err).to include('Invalid checksum for rack-0.9.1: "checksum!" is not a valid SHA256 hex or base64 digest')
+ expect(exitstatus).to eq(5)
+ expect(err).to include("The given checksum for rack-1.0.0 (\"checksum!\") is not a valid SHA256 hexdigest nor base64digest")
end
it "does not raise when disable_checksum_validation is set" do
bundle "config set disable_checksum_validation true"
- install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum"
+ install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum"
source "#{source_uri}"
gem "rack"
G
@@ -1042,7 +915,7 @@ RSpec.describe "compact index api" do
end
it "works when cache dir is world-writable" do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
File.umask(0000)
source "#{source_uri}"
gem "rack"
@@ -1050,11 +923,11 @@ RSpec.describe "compact index api" do
end
it "doesn't explode when the API dependencies are wrong" do
- install_gemfile <<-G, artifice: "compact_index_wrong_dependencies", env: { "DEBUG" => "true" }, raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index_wrong_dependencies", :env => { "DEBUG" => "true" }, :raise_on_error => false
source "#{source_uri}"
gem "rails"
G
- deps = [Gem::Dependency.new("rake", "= #{rake_version}"),
+ deps = [Gem::Dependency.new("rake", "= 13.0.1"),
Gem::Dependency.new("actionpack", "= 2.3.2"),
Gem::Dependency.new("activerecord", "= 2.3.2"),
Gem::Dependency.new("actionmailer", "= 2.3.2"),
@@ -1067,7 +940,7 @@ Running `bundle update rails` should fix the problem.
end
it "does not duplicate specs in the lockfile when updating and a dependency is not installed" do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "#{file_uri_for(gem_repo1)}"
source "#{source_uri}" do
gem "rails"
@@ -1075,8 +948,7 @@ Running `bundle update rails` should fix the problem.
end
G
gem_command "uninstall activemerchant"
- bundle "update rails", artifice: "compact_index"
- count = lockfile.match?("CHECKSUMS") ? 2 : 1 # Once in the specs, and once in CHECKSUMS
- expect(lockfile.scan(/activemerchant \(/).size).to eq(count)
+ bundle "update rails", :artifice => "compact_index"
+ expect(lockfile.scan(/activemerchant \(/).size).to eq(1)
end
end
diff --git a/spec/bundler/install/gems/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_spec.rb
index 35468b3a1c..a54f1db772 100644
--- a/spec/bundler/install/gems/dependency_api_spec.rb
+++ b/spec/bundler/install/gems/dependency_api_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -21,7 +21,7 @@ RSpec.describe "gemcutter's dependency API" do
gem " sinatra"
G
- bundle :install, artifice: "endpoint", raise_on_error: false
+ bundle :install, :artifice => "endpoint", :raise_on_error => false
expect(err).to include("' sinatra' is not a valid gem name because it contains whitespace.")
end
@@ -31,7 +31,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rails"
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(out).to include("Fetching gem metadata from #{source_uri}/...")
expect(the_bundle).to include_gems(
"rails 2.3.2",
@@ -49,7 +49,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "net-sftp"
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(the_bundle).to include_gems "net-sftp 1.1.1"
end
@@ -58,11 +58,11 @@ RSpec.describe "gemcutter's dependency API" do
source "#{source_uri}"
gem "rack"
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
bundle "config set --local deployment true"
bundle "config set --local path vendor/bundle"
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -80,7 +80,7 @@ RSpec.describe "gemcutter's dependency API" do
end
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(the_bundle).to include_gems("rails 2.3.2")
end
@@ -96,10 +96,10 @@ RSpec.describe "gemcutter's dependency API" do
gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
bundle "config set --local deployment true"
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(the_bundle).to include_gems("rails 2.3.2")
end
@@ -111,9 +111,9 @@ RSpec.describe "gemcutter's dependency API" do
gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}"
G
- bundle "install", artifice: "endpoint"
+ bundle "install", :artifice => "endpoint"
bundle "config set --local deployment true"
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(the_bundle).to include_gems("foo 1.0")
end
@@ -134,7 +134,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rcov"
G
- bundle :install, artifice: "windows", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ bundle :install, :artifice => "windows", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rcov 1.0.0"
end
@@ -150,7 +150,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
gem "rails"
G
- bundle :install, artifice: "endpoint_fallback"
+ bundle :install, :artifice => "endpoint_fallback"
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems(
@@ -171,7 +171,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, verbose: true, artifice: "endpoint_marshal_fail"
+ bundle :install, :verbose => true, :artifice => "endpoint_marshal_fail"
expect(out).to include("could not fetch from the dependency API, trying the full index")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -182,7 +182,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, verbose: true, artifice: "endpoint_api_forbidden"
+ bundle :install, :verbose => true, :artifice => "endpoint_api_forbidden"
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -193,11 +193,11 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_host_redirect"
+ bundle :install, :artifice => "endpoint_host_redirect"
expect(the_bundle).to include_gems "rack 1.0.0"
end
- it "handles host redirects without Gem::Net::HTTP::Persistent" do
+ it "handles host redirects without Net::HTTP::Persistent" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
@@ -216,7 +216,7 @@ RSpec.describe "gemcutter's dependency API" do
H
end
- bundle :install, artifice: "endpoint_host_redirect", requires: [lib_path("disable_net_http_persistent.rb")]
+ bundle :install, :artifice => "endpoint_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")]
expect(out).to_not match(/Too many redirects/)
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -227,7 +227,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_redirect", raise_on_error: false
+ bundle :install, :artifice => "endpoint_redirect", :raise_on_error => false
expect(err).to match(/Too many redirects/)
end
@@ -238,7 +238,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle "install --full-index", artifice: "endpoint"
+ bundle "install --full-index", :artifice => "endpoint"
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -249,13 +249,13 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle "update --full-index", artifice: "endpoint", all: true
+ bundle "update --full-index", :artifice => "endpoint", :all => true
expect(out).to include("Fetching source index from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
- it "fetches again when more dependencies are found in subsequent sources", bundler: "< 3" do
+ it "fetches again when more dependencies are found in subsequent sources", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -269,7 +269,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "back_deps"
G
- bundle :install, artifice: "endpoint_extra"
+ bundle :install, :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
end
@@ -288,7 +288,7 @@ RSpec.describe "gemcutter's dependency API" do
end
G
- bundle :install, artifice: "endpoint_extra"
+ bundle :install, :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
end
@@ -297,7 +297,7 @@ RSpec.describe "gemcutter's dependency API" do
source "#{source_uri}"
gem "rack", "1.0.0"
G
- bundle :install, artifice: "endpoint_extra_api"
+ bundle :install, :artifice => "endpoint_extra_api"
build_repo4 do
build_gem "rack", "1.2" do |s|
@@ -310,11 +310,11 @@ RSpec.describe "gemcutter's dependency API" do
source "#{source_uri}/extra"
gem "rack", "1.2"
G
- bundle :install, artifice: "endpoint_extra_api"
+ bundle :install, :artifice => "endpoint_extra_api"
expect(the_bundle).to include_gems "rack 1.2"
end
- it "considers all possible versions of dependencies from all api gem sources", bundler: "< 3" do
+ it "considers all possible versions of dependencies from all api gem sources", :bundler => "< 3" do
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
@@ -332,7 +332,7 @@ RSpec.describe "gemcutter's dependency API" do
gem 'somegem', '1.0.0'
G
- bundle :install, artifice: "endpoint_extra_api"
+ bundle :install, :artifice => "endpoint_extra_api"
expect(the_bundle).to include_gems "somegem 1.0.0"
expect(the_bundle).to include_gems "activesupport 1.2.3"
@@ -353,13 +353,13 @@ RSpec.describe "gemcutter's dependency API" do
end
G
- bundle :install, artifice: "endpoint_extra"
+ bundle :install, :artifice => "endpoint_extra"
expect(out).to include("Fetching gem metadata from http://localgemserver.test/.")
expect(out).to include("Fetching source index from http://localgemserver.test/extra")
end
- it "does not fetch every spec when doing back deps", bundler: "< 3" do
+ it "does not fetch every spec when doing back deps", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -369,7 +369,7 @@ RSpec.describe "gemcutter's dependency API" do
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end
- install_gemfile <<-G, artifice: "endpoint_extra_missing"
+ install_gemfile <<-G, :artifice => "endpoint_extra_missing", :env => env_for_missing_prerelease_default_gem_activation
source "#{source_uri}"
source "#{source_uri}/extra"
gem "back_deps"
@@ -388,7 +388,7 @@ RSpec.describe "gemcutter's dependency API" do
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end
- install_gemfile <<-G, artifice: "endpoint_extra_missing"
+ install_gemfile <<-G, :artifice => "endpoint_extra_missing", :env => env_for_missing_prerelease_default_gem_activation
source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
@@ -398,7 +398,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "back_deps 1.0"
end
- it "fetches again when more dependencies are found in subsequent sources using deployment mode", bundler: "< 3" do
+ it "fetches again when more dependencies are found in subsequent sources using deployment mode", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@@ -412,9 +412,9 @@ RSpec.describe "gemcutter's dependency API" do
gem "back_deps"
G
- bundle :install, artifice: "endpoint_extra"
+ bundle :install, :artifice => "endpoint_extra"
bundle "config set --local deployment true"
- bundle :install, artifice: "endpoint_extra"
+ bundle :install, :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
@@ -433,9 +433,9 @@ RSpec.describe "gemcutter's dependency API" do
end
G
- bundle :install, artifice: "endpoint_extra"
+ bundle :install, :artifice => "endpoint_extra"
bundle "config set --local deployment true"
- bundle "install", artifice: "endpoint_extra"
+ bundle "install", :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
@@ -445,7 +445,7 @@ RSpec.describe "gemcutter's dependency API" do
build_gem "foo", "2.0"
end
- install_gemfile <<-G, artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, verbose: true
+ install_gemfile <<-G, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :verbose => true
source "#{source_uri}"
gem "foo"
@@ -468,40 +468,40 @@ RSpec.describe "gemcutter's dependency API" do
gem "bundler_dep"
G
- bundle :install, artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ bundle :install, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Fetching gem metadata from #{source_uri}")
end
- it "installs the binstubs", bundler: "< 3" do
+ it "installs the binstubs", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle "install --binstubs", artifice: "endpoint"
+ bundle "install --binstubs", :artifice => "endpoint"
gembin "rackup"
expect(out).to eq("1.0.0")
end
- it "installs the bins when using --path and uses autoclean", bundler: "< 3" do
+ it "installs the bins when using --path and uses autoclean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle "install --path vendor/bundle", artifice: "endpoint"
+ bundle "install --path vendor/bundle", :artifice => "endpoint"
expect(vendored_gems("bin/rackup")).to exist
end
- it "installs the bins when using --path and uses bundle clean", bundler: "< 3" do
+ it "installs the bins when using --path and uses bundle clean", :bundler => "< 3" do
gemfile <<-G
source "#{source_uri}"
gem "rack"
G
- bundle "install --path vendor/bundle --no-clean", artifice: "endpoint"
+ bundle "install --path vendor/bundle --no-clean", :artifice => "endpoint"
expect(vendored_gems("bin/rackup")).to exist
end
@@ -512,7 +512,7 @@ RSpec.describe "gemcutter's dependency API" do
gem 'rack-obama'
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(out).to include("Post-install message from rack:")
end
@@ -522,7 +522,7 @@ RSpec.describe "gemcutter's dependency API" do
gem 'rack_middleware'
G
- bundle :install, artifice: "endpoint"
+ bundle :install, :artifice => "endpoint"
expect(out).to include("Post-install message from rack:")
expect(out).to include("Rack's post install message")
end
@@ -531,7 +531,7 @@ RSpec.describe "gemcutter's dependency API" do
let(:user) { "user" }
let(:password) { "pass" }
let(:basic_auth_source_uri) do
- uri = Gem::URI.parse(source_uri)
+ uri = Bundler::URI.parse(source_uri)
uri.user = user
uri.password = password
@@ -544,7 +544,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_basic_authentication"
+ bundle :install, :artifice => "endpoint_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -555,7 +555,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, verbose: true, artifice: "endpoint_basic_authentication"
+ bundle :install, :verbose => true, :artifice => "endpoint_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -566,7 +566,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_marshal_fail_basic_authentication"
+ bundle :install, :artifice => "endpoint_marshal_fail_basic_authentication"
expect(out).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -577,18 +577,18 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_500", raise_on_error: false
+ bundle :install, :artifice => "endpoint_500", :raise_on_error => false
expect(out).not_to include("#{user}:#{password}")
end
- it "strips http basic auth creds when warning about ambiguous sources", bundler: "< 3" do
+ it "strips http basic auth creds when warning about ambiguous sources", :bundler => "< 3" do
gemfile <<-G
source "#{basic_auth_source_uri}"
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- bundle :install, artifice: "endpoint_basic_authentication"
+ bundle :install, :artifice => "endpoint_basic_authentication"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).not_to include("#{user}:#{password}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -600,7 +600,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_creds_diff_host"
+ bundle :install, :artifice => "endpoint_creds_diff_host"
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -613,7 +613,7 @@ RSpec.describe "gemcutter's dependency API" do
end
it "reads authentication details from a valid ENV variable" do
- bundle :install, artifice: "endpoint_strict_basic_authentication", env: { "BUNDLE_LOCAL___GEMSERVER__TEST" => "#{user}:#{password}" }
+ bundle :install, :artifice => "endpoint_strict_basic_authentication", :env => { "BUNDLE_LOCAL___GEMSERVER__TEST" => "#{user}:#{password}" }
expect(out).to include("Fetching gem metadata from http://local-gemserver.test")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -631,7 +631,7 @@ RSpec.describe "gemcutter's dependency API" do
it "reads authentication details by host name from bundle config" do
bundle "config set #{source_hostname} #{user}:#{password}"
- bundle :install, artifice: "endpoint_strict_basic_authentication"
+ bundle :install, :artifice => "endpoint_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -641,7 +641,7 @@ RSpec.describe "gemcutter's dependency API" do
# The trailing slash is necessary here; Fetcher canonicalizes the URI.
bundle "config set #{source_uri}/ #{user}:#{password}"
- bundle :install, artifice: "endpoint_strict_basic_authentication"
+ bundle :install, :artifice => "endpoint_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -649,7 +649,7 @@ RSpec.describe "gemcutter's dependency API" do
it "should use the API" do
bundle "config set #{source_hostname} #{user}:#{password}"
- bundle :install, artifice: "endpoint_strict_basic_authentication"
+ bundle :install, :artifice => "endpoint_strict_basic_authentication"
expect(out).to include("Fetching gem metadata from #{source_uri}")
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -662,19 +662,19 @@ RSpec.describe "gemcutter's dependency API" do
bundle "config set #{source_hostname} otheruser:wrong"
- bundle :install, artifice: "endpoint_strict_basic_authentication"
+ bundle :install, :artifice => "endpoint_strict_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "shows instructions if auth is not provided for the source" do
- bundle :install, artifice: "endpoint_strict_basic_authentication", raise_on_error: false
+ bundle :install, :artifice => "endpoint_strict_basic_authentication", :raise_on_error => false
expect(err).to include("bundle config set --global #{source_hostname} username:password")
end
it "fails if authentication has already been provided, but failed" do
bundle "config set #{source_hostname} #{user}:wrong"
- bundle :install, artifice: "endpoint_strict_basic_authentication", raise_on_error: false
+ bundle :install, :artifice => "endpoint_strict_basic_authentication", :raise_on_error => false
expect(err).to include("Bad username or password")
end
end
@@ -688,7 +688,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, artifice: "endpoint_basic_authentication"
+ bundle :install, :artifice => "endpoint_basic_authentication"
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
@@ -713,7 +713,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false
+ bundle :install, :env => { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, :raise_on_error => false
expect(err).to include("OpenSSL")
end
end
@@ -723,7 +723,7 @@ RSpec.describe "gemcutter's dependency API" do
# Install a monkeypatch that reproduces the effects of openssl raising
# a certificate validation error when RubyGems tries to connect.
gemfile <<-G
- class Gem::Net::HTTP
+ class Net::HTTP
def start
raise OpenSSL::SSL::SSLError, "certificate verify failed"
end
@@ -733,7 +733,7 @@ RSpec.describe "gemcutter's dependency API" do
gem "rack"
G
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to match(/could not verify the SSL certificate/i)
end
end
@@ -741,7 +741,7 @@ RSpec.describe "gemcutter's dependency API" do
context ".gemrc with sources is present" do
it "uses other sources declared in the Gemfile" do
File.open(home(".gemrc"), "w") do |file|
- file.puts({ sources: ["https://rubygems.org"] }.to_yaml)
+ file.puts({ :sources => ["https://rubygems.org"] }.to_yaml)
end
begin
@@ -750,7 +750,7 @@ RSpec.describe "gemcutter's dependency API" do
gem 'rack'
G
- bundle "install", artifice: "endpoint_marshal_fail"
+ bundle "install", :artifice => "endpoint_marshal_fail"
ensure
home(".gemrc").rmtree
end
diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb
index 5e0c88fc95..d5fa55be48 100644
--- a/spec/bundler/install/gems/flex_spec.rb
+++ b/spec/bundler/install/gems/flex_spec.rb
@@ -183,8 +183,8 @@ RSpec.describe "bundle flex_install" do
end
it "does not install gems whose dependencies are not met" do
- bundle :install, raise_on_error: false
- ruby <<-RUBY, raise_on_error: false
+ bundle :install, :raise_on_error => false
+ ruby <<-RUBY, :raise_on_error => false
require 'bundler/setup'
RUBY
expect(err).to match(/could not find gem 'rack-obama/i)
@@ -193,7 +193,7 @@ RSpec.describe "bundle flex_install" do
it "discards the locked gems when the Gemfile requires different versions than the lock" do
bundle "config set force_ruby_platform true"
- nice_error = <<~E.strip
+ nice_error = <<-E.strip.gsub(/^ {8}/, "")
Could not find compatible versions
Because rack-obama >= 2.0 depends on rack = 1.2
@@ -203,20 +203,20 @@ RSpec.describe "bundle flex_install" do
version solving has failed.
E
- bundle :install, retry: 0, raise_on_error: false
+ bundle :install, :retry => 0, :raise_on_error => false
expect(err).to end_with(nice_error)
end
it "does not include conflicts with a single requirement tree, because that can't possibly be a conflict" do
bundle "config set force_ruby_platform true"
- bad_error = <<~E.strip
+ bad_error = <<-E.strip.gsub(/^ {8}/, "")
Bundler could not find compatible versions for gem "rack-obama":
In Gemfile:
rack-obama (= 2.0)
E
- bundle "update rack_middleware", retry: 0, raise_on_error: false
+ bundle "update rack_middleware", :retry => 0, :raise_on_error => false
expect(err).not_to end_with(bad_error)
end
end
@@ -245,7 +245,7 @@ RSpec.describe "bundle flex_install" do
end
it "discards the conflicting lockfile information and resolves properly" do
- bundle :update, raise_on_error: false, all: true
+ bundle :update, :raise_on_error => false, :all => true
expect(err).to be_empty
end
end
@@ -268,11 +268,6 @@ RSpec.describe "bundle flex_install" do
it "should work when you install" do
bundle "install"
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo1, "rack", "0.9.1"
- c.checksum gem_repo1, "rack-obama", "1.0"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -287,7 +282,7 @@ RSpec.describe "bundle flex_install" do
DEPENDENCIES
rack (= 0.9.1)
rack-obama
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -313,10 +308,6 @@ RSpec.describe "bundle flex_install" do
gem "rack"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo1, "rack", "1.0.0"
- end
-
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -332,7 +323,7 @@ RSpec.describe "bundle flex_install" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
diff --git a/spec/bundler/install/gems/native_extensions_spec.rb b/spec/bundler/install/gems/native_extensions_spec.rb
index 907778a384..5c18d2cc51 100644
--- a/spec/bundler/install/gems/native_extensions_spec.rb
+++ b/spec/bundler/install/gems/native_extensions_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe "installing a gem with native extensions" do
s.extensions = ["ext/extconf.rb"]
s.write "ext/extconf.rb", <<-E
require "mkmf"
+ $extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
name = "c_extension_bundle"
dir_config(name)
raise "OMG" unless with_config("c_extension") == "hello"
@@ -51,6 +52,7 @@ RSpec.describe "installing a gem with native extensions" do
s.extensions = ["ext/extconf.rb"]
s.write "ext/extconf.rb", <<-E
require "mkmf"
+ $extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
name = "c_extension_bundle"
dir_config(name)
raise "OMG" unless with_config("c_extension") == "hello"
@@ -91,10 +93,11 @@ RSpec.describe "installing a gem with native extensions" do
it "installs correctly from git when multiple gems with extensions share one repository" do
build_repo2 do
["one", "two"].each do |n|
- build_lib "c_extension_#{n}", "1.0", path: lib_path("gems/c_extension_#{n}") do |s|
+ build_lib "c_extension_#{n}", "1.0", :path => lib_path("gems/c_extension_#{n}") do |s|
s.extensions = ["ext/extconf.rb"]
s.write "ext/extconf.rb", <<-E
require "mkmf"
+ $extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
name = "c_extension_bundle_#{n}"
dir_config(name)
raise "OMG" unless with_config("c_extension_#{n}") == "#{n}"
@@ -119,7 +122,7 @@ RSpec.describe "installing a gem with native extensions" do
C
end
end
- build_git "gems", path: lib_path("gems"), gemspec: false
+ build_git "gems", :path => lib_path("gems"), :gemspec => false
end
bundle "config set build.c_extension_one --with-c_extension_one=one"
@@ -147,6 +150,7 @@ RSpec.describe "installing a gem with native extensions" do
s.extensions = ["ext/extconf.rb"]
s.write "ext/extconf.rb", <<-E
require "mkmf"
+ $extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
name = "c_extension_bundle"
dir_config(name)
raise "OMG" unless with_config("c_extension") == "hello" && with_config("c_extension_bundle-dir") == "hola"
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb
index b54674898d..fb6dda2f88 100644
--- a/spec/bundler/install/gems/resolving_spec.rb
+++ b/spec/bundler/install/gems/resolving_spec.rb
@@ -106,7 +106,7 @@ RSpec.describe "bundle install with install-time dependencies" do
path = "#{gem_repo2}/#{Gem::MARSHAL_SPEC_DIR}/actionpack-2.3.2.gemspec.rz"
spec = Marshal.load(Bundler.rubygems.inflate(File.binread(path)))
spec.dependencies.each do |d|
- d.instance_variable_set(:@type, "fail")
+ d.instance_variable_set(:@type, :fail)
end
File.open(path, "wb") do |f|
f.write Gem.deflate(Marshal.dump(spec))
@@ -131,7 +131,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
it "installs plugins depended on by other plugins" do
- install_gemfile <<-G, env: { "DEBUG" => "1" }
+ install_gemfile <<-G, :env => { "DEBUG" => "1" }
source "#{file_uri_for(gem_repo2)}"
gem "net_a"
G
@@ -140,7 +140,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
it "installs multiple levels of dependencies" do
- install_gemfile <<-G, env: { "DEBUG" => "1" }
+ install_gemfile <<-G, :env => { "DEBUG" => "1" }
source "#{file_uri_for(gem_repo2)}"
gem "net_c"
gem "net_e"
@@ -157,7 +157,7 @@ RSpec.describe "bundle install with install-time dependencies" do
gem "net_e"
G
- bundle :install, env: { "BUNDLER_DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
+ bundle :install, :env => { "BUNDLER_DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
expect(out).to include("Resolving dependencies...")
end
@@ -171,7 +171,7 @@ RSpec.describe "bundle install with install-time dependencies" do
gem "net_e"
G
- bundle :install, env: { "DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
+ bundle :install, :env => { "DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
expect(out).to include("Resolving dependencies...")
end
@@ -185,7 +185,7 @@ RSpec.describe "bundle install with install-time dependencies" do
gem "net_e"
G
- bundle :install, env: { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" }
+ bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" }
expect(out).to include(" net_b").
and include("Resolving dependencies...").
@@ -208,7 +208,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
end
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
ruby "#{Gem.ruby_version}"
source "http://localgemserver.test/"
gem 'rack'
@@ -229,7 +229,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
end
- install_gemfile <<-G, artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ install_gemfile <<-G, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
ruby "#{Gem.ruby_version}"
source "http://localgemserver.test/"
gem 'rack'
@@ -256,10 +256,6 @@ RSpec.describe "bundle install with install-time dependencies" do
gem 'parallel_tests'
G
- checksums = checksums_section do |c|
- c.checksum gem_repo2, "parallel_tests", "3.8.0"
- end
-
lockfile <<~L
GEM
remote: http://localgemserver.test/
@@ -271,18 +267,14 @@ RSpec.describe "bundle install with install-time dependencies" do
DEPENDENCIES
parallel_tests
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically updates lockfile to use the older version" do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "parallel_tests", "3.7.0"
- end
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(lockfile).to eq <<~L
GEM
@@ -295,7 +287,7 @@ RSpec.describe "bundle install with install-time dependencies" do
DEPENDENCIES
parallel_tests
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -303,7 +295,7 @@ RSpec.describe "bundle install with install-time dependencies" do
it "gives a meaningful error if we're in frozen mode" do
expect do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s, "BUNDLE_FROZEN" => "true" }, raise_on_error: false
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s, "BUNDLE_FROZEN" => "true" }, :raise_on_error => false
end.not_to change { lockfile }
expect(err).to include("parallel_tests-3.8.0 requires ruby version >= #{next_ruby_minor}")
@@ -340,11 +332,6 @@ RSpec.describe "bundle install with install-time dependencies" do
gem 'rubocop'
G
- checksums = checksums_section do |c|
- c.checksum gem_repo2, "rubocop", "1.35.0"
- c.checksum gem_repo2, "rubocop-ast", "1.21.0"
- end
-
lockfile <<~L
GEM
remote: http://localgemserver.test/
@@ -358,19 +345,14 @@ RSpec.describe "bundle install with install-time dependencies" do
DEPENDENCIES
parallel_tests
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically updates lockfile to use the older compatible versions" do
- bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
-
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rubocop", "1.28.2"
- c.checksum gem_repo2, "rubocop-ast", "1.17.0"
- end
+ bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(lockfile).to eq <<~L
GEM
@@ -385,7 +367,7 @@ RSpec.describe "bundle install with install-time dependencies" do
DEPENDENCIES
rubocop
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -430,11 +412,11 @@ RSpec.describe "bundle install with install-time dependencies" do
it "raises a proper error" do
simulate_platform "aarch64-linux" do
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
end
- nice_error = <<~E.strip
- Could not find gems matching 'sorbet-static (= 0.5.10554)' valid for all resolution platforms (arm64-darwin-21, aarch64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
+ nice_error = strip_whitespace(<<-E).strip
+ Could not find gem 'sorbet-static (= 0.5.10554)' with platforms 'arm64-darwin-21', 'aarch64-linux' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.10554)':
* sorbet-static-0.5.10554-universal-darwin-21
@@ -443,62 +425,6 @@ RSpec.describe "bundle install with install-time dependencies" do
end
end
- context "when adding a new gem that does not resolve under all locked platforms" do
- before do
- simulate_platform "x86_64-linux" do
- build_repo4 do
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "x86_64-linux"
- end
- build_gem "nokogiri", "1.14.0" do |s|
- s.platform = "arm-linux"
- end
-
- build_gem "sorbet-static", "0.5.10696" do |s|
- s.platform = "x86_64-linux"
- end
- end
-
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- nokogiri (1.14.0-arm-linux)
- nokogiri (1.14.0-x86_64-linux)
-
- PLATFORMS
- arm-linux
- x86_64-linux
-
- DEPENDENCIES
- nokogiri
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- gemfile <<~G
- source "#{file_uri_for(gem_repo4)}"
-
- gem "nokogiri"
- gem "sorbet-static"
- G
-
- bundle "lock", raise_on_error: false
- end
- end
-
- it "raises a proper error" do
- nice_error = <<~E.strip
- Could not find gems matching 'sorbet-static' valid for all resolution platforms (arm-linux, x86_64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
-
- The source contains the following gems matching 'sorbet-static':
- * sorbet-static-0.5.10696-x86_64-linux
- E
- expect(err).to end_with(nice_error)
- end
- end
-
it "gives a meaningful error on ruby version mismatches between dependencies" do
build_repo4 do
build_gem "requires-old-ruby" do |s|
@@ -506,13 +432,13 @@ RSpec.describe "bundle install with install-time dependencies" do
end
end
- build_lib("foo", path: bundled_app) do |s|
+ build_lib("foo", :path => bundled_app) do |s|
s.required_ruby_version = ">= #{Gem.ruby_version}"
s.add_dependency "requires-old-ruby"
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo4)}"
gemspec
G
@@ -538,7 +464,7 @@ RSpec.describe "bundle install with install-time dependencies" do
build_gem "foo1", "1.0"
end
- install_gemfile <<-G, artifice: "compact_index_rate_limited", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ install_gemfile <<-G, :artifice => "compact_index_rate_limited", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
ruby "#{Gem.ruby_version}"
source "http://localgemserver.test/"
gem 'rack'
@@ -562,7 +488,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
simulate_platform x86_mingw32 do
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
ruby "#{Gem.ruby_version}"
source "http://localgemserver.test/"
gem 'rack'
@@ -588,14 +514,14 @@ RSpec.describe "bundle install with install-time dependencies" do
let(:error_message_requirement) { "= #{Gem.ruby_version}" }
it "raises a proper error that mentions the current Ruby version during resolution" do
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false
source "http://localgemserver.test/"
gem 'require_ruby'
G
expect(out).to_not include("Gem::InstallError: require_ruby requires Ruby version > 9000")
- nice_error = <<~E.strip
+ nice_error = strip_whitespace(<<-E).strip
Could not find compatible versions
Because every version of require_ruby depends on Ruby > 9000
@@ -609,7 +535,7 @@ RSpec.describe "bundle install with install-time dependencies" do
shared_examples_for "ruby version conflicts" do
it "raises an error during resolution" do
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false
source "http://localgemserver.test/"
ruby #{ruby_requirement}
gem 'require_ruby'
@@ -617,7 +543,7 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to_not include("Gem::InstallError: require_ruby requires Ruby version > 9000")
- nice_error = <<~E.strip
+ nice_error = strip_whitespace(<<-E).strip
Could not find compatible versions
Because every version of require_ruby depends on Ruby > 9000
@@ -655,13 +581,13 @@ RSpec.describe "bundle install with install-time dependencies" do
end
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem 'require_rubygems'
G
expect(err).to_not include("Gem::InstallError: require_rubygems requires RubyGems version > 9000")
- nice_error = <<~E.strip
+ nice_error = strip_whitespace(<<-E).strip
Because every version of require_rubygems depends on RubyGems > 9000
and Gemfile depends on require_rubygems >= 0,
RubyGems > 9000 is required.
diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb
index 46cab2dfeb..4d08752256 100644
--- a/spec/bundler/install/gems/standalone_spec.rb
+++ b/spec/bundler/install/gems/standalone_spec.rb
@@ -97,23 +97,7 @@ RSpec.shared_examples "bundle install --standalone" do
testrb << "\nrequire \"#{k}\""
testrb << "\nputs #{k.upcase}"
end
- ruby testrb, dir: "#{bundled_app}2"
-
- expect(out).to eq(expected_gems.values.join("\n"))
- end
-
- it "skips activating gems" do
- testrb = String.new <<-RUBY
- $:.unshift File.expand_path("bundle")
- require "bundler/setup"
-
- gem "do_not_activate_me"
- RUBY
- expected_gems.each do |k, _|
- testrb << "\nrequire \"#{k}\""
- testrb << "\nputs #{k.upcase}"
- end
- sys_exec %(#{Gem.ruby} -w -e #{testrb.shellescape})
+ ruby testrb, :dir => "#{bundled_app}2"
expect(out).to eq(expected_gems.values.join("\n"))
end
@@ -126,7 +110,7 @@ RSpec.shared_examples "bundle install --standalone" do
gem "rails"
G
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, dir: cwd
+ bundle :install, :standalone => true, :dir => cwd
end
let(:expected_gems) do
@@ -141,18 +125,21 @@ RSpec.shared_examples "bundle install --standalone" do
describe "with default gems and a lockfile", :ruby_repo do
before do
+ skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
+ skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
+
realworld_system_gems "tsort --version 0.1.0"
- necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.1.0"]
+ necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.1"]
necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.a")
necessary_system_gems += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a")
- realworld_system_gems(*necessary_system_gems, path: scoped_gem_path(bundled_app("bundle")))
+ realworld_system_gems(*necessary_system_gems, :path => scoped_gem_path(bundled_app("bundle")))
- build_gem "foo", "1.0.0", to_system: true, default: true do |s|
+ build_gem "foo", "1.0.0", :to_system => true, :default => true do |s|
s.add_dependency "bar"
end
- build_gem "bar", "1.0.0", to_system: true, default: true
+ build_gem "bar", "1.0.0", :to_system => true, :default => true
build_repo4 do
build_gem "foo", "1.0.0" do |s|
@@ -167,12 +154,12 @@ RSpec.shared_examples "bundle install --standalone" do
gem "foo"
G
- bundle "lock", dir: cwd, artifice: "compact_index"
+ bundle "lock", :dir => cwd, :artifice => "compact_index"
end
it "works and points to the vendored copies, not to the default copies", :realworld do
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, dir: cwd, artifice: "compact_index", env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+ bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") }
@@ -185,7 +172,7 @@ RSpec.shared_examples "bundle install --standalone" do
describe "with Gemfiles using absolute path sources and resulting bundle moved to a folder hierarchy with different nesting" do
before do
- build_lib "minitest", "1.0.0", path: lib_path("minitest")
+ build_lib "minitest", "1.0.0", :path => lib_path("minitest")
Dir.mkdir bundled_app("app")
@@ -194,14 +181,14 @@ RSpec.shared_examples "bundle install --standalone" do
gem "minitest", :path => "#{lib_path("minitest")}"
G
- bundle "install", standalone: true, dir: bundled_app("app")
+ bundle "install", :standalone => true, :dir => bundled_app("app")
Dir.mkdir tmp("one_more_level")
FileUtils.mv bundled_app, tmp("one_more_level")
end
it "also works" do
- ruby <<-RUBY, dir: tmp("one_more_level/bundled_app/app")
+ ruby <<-RUBY, :dir => tmp("one_more_level/bundled_app/app")
require "./bundle/bundler/setup"
require "minitest"
@@ -217,20 +204,20 @@ RSpec.shared_examples "bundle install --standalone" do
before do
FileUtils.mkdir_p bundled_app("app/vendor")
- build_lib "minitest", "1.0.0", path: bundled_app("app/vendor/minitest")
+ build_lib "minitest", "1.0.0", :path => bundled_app("app/vendor/minitest")
gemfile bundled_app("app/Gemfile"), <<-G
source "#{file_uri_for(gem_repo1)}"
gem "minitest", :path => "vendor/minitest"
G
- bundle "install", standalone: true, dir: bundled_app("app")
+ bundle "install", :standalone => true, :dir => bundled_app("app")
FileUtils.mv(bundled_app("app"), bundled_app2("app"))
end
it "also works" do
- ruby <<-RUBY, dir: bundled_app2("app")
+ ruby <<-RUBY, :dir => bundled_app2("app")
require "./bundle/bundler/setup"
require "minitest"
@@ -245,7 +232,7 @@ RSpec.shared_examples "bundle install --standalone" do
describe "with gems with native extension" do
before do
bundle "config set --local path #{bundled_app("bundle")}"
- install_gemfile <<-G, standalone: true, dir: cwd
+ install_gemfile <<-G, :standalone => true, :dir => cwd
source "#{file_uri_for(gem_repo1)}"
gem "very_simple_binary"
G
@@ -265,7 +252,7 @@ RSpec.shared_examples "bundle install --standalone" do
describe "with gem that has an invalid gemspec" do
before do
- build_git "bar", gemspec: false do |s|
+ build_git "bar", :gemspec => false do |s|
s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0')
s.write "bar.gemspec", <<-G
lib = File.expand_path('lib/', __dir__)
@@ -283,7 +270,7 @@ RSpec.shared_examples "bundle install --standalone" do
G
end
bundle "config set --local path #{bundled_app("bundle")}"
- install_gemfile <<-G, standalone: true, dir: cwd, raise_on_error: false
+ install_gemfile <<-G, :standalone => true, :dir => cwd, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
@@ -305,7 +292,7 @@ RSpec.shared_examples "bundle install --standalone" do
gem "devise", :git => "#{lib_path("devise-1.0")}"
G
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, dir: cwd
+ bundle :install, :standalone => true, :dir => cwd
end
let(:expected_gems) do
@@ -333,7 +320,7 @@ RSpec.shared_examples "bundle install --standalone" do
end
G
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, dir: cwd
+ bundle :install, :standalone => true, :dir => cwd
end
let(:expected_gems) do
@@ -347,7 +334,7 @@ RSpec.shared_examples "bundle install --standalone" do
it "allows creating a standalone file with limited groups" do
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: "default", dir: cwd
+ bundle :install, :standalone => "default", :dir => cwd
load_error_ruby <<-RUBY, "spec"
$:.unshift File.expand_path("bundle")
@@ -365,7 +352,7 @@ RSpec.shared_examples "bundle install --standalone" do
it "allows `without` configuration to limit the groups used in a standalone" do
bundle "config set --local path #{bundled_app("bundle")}"
bundle "config set --local without test"
- bundle :install, standalone: true, dir: cwd
+ bundle :install, :standalone => true, :dir => cwd
load_error_ruby <<-RUBY, "spec"
$:.unshift File.expand_path("bundle")
@@ -382,7 +369,7 @@ RSpec.shared_examples "bundle install --standalone" do
it "allows `path` configuration to change the location of the standalone bundle" do
bundle "config set --local path path/to/bundle"
- bundle "install", standalone: true, dir: cwd
+ bundle "install", :standalone => true, :dir => cwd
ruby <<-RUBY
$:.unshift File.expand_path("path/to/bundle")
@@ -397,9 +384,9 @@ RSpec.shared_examples "bundle install --standalone" do
it "allows `without` to limit the groups used in a standalone" do
bundle "config set --local without test"
- bundle :install, dir: cwd
+ bundle :install, :dir => cwd
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, dir: cwd
+ bundle :install, :standalone => true, :dir => cwd
load_error_ruby <<-RUBY, "spec"
$:.unshift File.expand_path("bundle")
@@ -425,7 +412,7 @@ RSpec.shared_examples "bundle install --standalone" do
gem "rails"
G
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, artifice: "endpoint", dir: cwd
+ bundle :install, :standalone => true, :artifice => "endpoint", :dir => cwd
end
let(:expected_gems) do
@@ -439,14 +426,14 @@ RSpec.shared_examples "bundle install --standalone" do
end
end
- describe "with --binstubs", bundler: "< 3" do
+ describe "with --binstubs", :bundler => "< 3" do
before do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rails"
G
bundle "config set --local path #{bundled_app("bundle")}"
- bundle :install, standalone: true, binstubs: true, dir: cwd
+ bundle :install, :standalone => true, :binstubs => true, :dir => cwd
end
let(:expected_gems) do
@@ -464,7 +451,7 @@ RSpec.shared_examples "bundle install --standalone" do
it "creates stubs that can be executed from anywhere" do
require "tmpdir"
- sys_exec(%(#{bundled_app("bin/rails")} -v), dir: Dir.tmpdir)
+ sys_exec(%(#{bundled_app("bin/rails")} -v), :dir => Dir.tmpdir)
expect(out).to eq("2.3.2")
end
@@ -506,7 +493,7 @@ RSpec.describe "bundle install --standalone --local" do
gem "rack"
G
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
end
it "generates script pointing to system gems" do
diff --git a/spec/bundler/install/gemspecs_spec.rb b/spec/bundler/install/gemspecs_spec.rb
index 51aa0ed14f..7b58ea9839 100644
--- a/spec/bundler/install/gemspecs_spec.rb
+++ b/spec/bundler/install/gemspecs_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe "bundle install" do
describe "when a gem has a YAML gemspec" do
before :each do
build_repo2 do
- build_gem "yaml_spec", gemspec: :yaml
+ build_gem "yaml_spec", :gemspec => :yaml
end
end
@@ -18,7 +18,7 @@ RSpec.describe "bundle install" do
end
it "still installs correctly when using path" do
- build_lib "yaml_spec", gemspec: :yaml
+ build_lib "yaml_spec", :gemspec => :yaml
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -34,7 +34,7 @@ RSpec.describe "bundle install" do
gem 'rack'
G
- system_gems "rack-1.0.0", path: default_bundle_path
+ system_gems "rack-1.0.0", :path => default_bundle_path
FileUtils.mkdir_p "#{default_bundle_path}/specifications"
File.open("#{default_bundle_path}/specifications/rack-1.0.0.gemspec", "w+") do |f|
@@ -45,7 +45,7 @@ RSpec.describe "bundle install" do
end
f.write spec.to_ruby
end
- bundle :install, artifice: "endpoint_marshal_fail" # force gemspec load
+ bundle :install, :artifice => "endpoint_marshal_fail" # force gemspec load
expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.2"
end
@@ -59,7 +59,7 @@ RSpec.describe "bundle install" do
end
G
- install_gemfile <<-G, env: { "LANG" => "C" }
+ install_gemfile <<-G, :env => { "LANG" => "C" }
source "#{file_uri_for(gem_repo1)}"
gemspec
G
@@ -95,8 +95,8 @@ RSpec.describe "bundle install" do
context "when ruby version is specified in gemspec and gemfile" do
it "installs when patch level is not specified and the version matches",
- if: RUBY_PATCHLEVEL >= 0 do
- build_lib("foo", path: bundled_app) do |s|
+ :if => RUBY_PATCHLEVEL >= 0 do
+ build_lib("foo", :path => bundled_app) do |s|
s.required_ruby_version = "~> #{RUBY_VERSION}.0"
end
@@ -109,12 +109,12 @@ RSpec.describe "bundle install" do
end
it "installs when patch level is specified and the version still matches the current version",
- if: RUBY_PATCHLEVEL >= 0 do
- build_lib("foo", path: bundled_app) do |s|
+ :if => RUBY_PATCHLEVEL >= 0 do
+ build_lib("foo", :path => bundled_app) do |s|
s.required_ruby_version = "#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby', :patchlevel => '#{RUBY_PATCHLEVEL}'
source "#{file_uri_for(gem_repo1)}"
gemspec
@@ -123,13 +123,13 @@ RSpec.describe "bundle install" do
end
it "fails and complains about patchlevel on patchlevel mismatch",
- if: RUBY_PATCHLEVEL >= 0 do
+ :if => RUBY_PATCHLEVEL >= 0 do
patchlevel = RUBY_PATCHLEVEL.to_i + 1
- build_lib("foo", path: bundled_app) do |s|
+ build_lib("foo", :path => bundled_app) do |s|
s.required_ruby_version = "#{RUBY_VERSION}.#{patchlevel}"
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby', :patchlevel => '#{patchlevel}'
source "#{file_uri_for(gem_repo1)}"
gemspec
@@ -143,11 +143,11 @@ RSpec.describe "bundle install" do
it "fails and complains about version on version mismatch" do
version = Gem::Requirement.create(RUBY_VERSION).requirements.first.last.bump.version
- build_lib("foo", path: bundled_app) do |s|
+ build_lib("foo", :path => bundled_app) do |s|
s.required_ruby_version = version
end
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
ruby '#{version}', :engine_version => '#{version}', :engine => 'ruby'
source "#{file_uri_for(gem_repo1)}"
gemspec
diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb
index c8d574baf3..882f2a2d42 100644
--- a/spec/bundler/install/git_spec.rb
+++ b/spec/bundler/install/git_spec.rb
@@ -3,51 +3,51 @@
RSpec.describe "bundle install" do
context "git sources" do
it "displays the revision hash of the gem repository" do
- build_git "foo", "1.0", path: lib_path("foo")
+ build_git "foo", "1.0", :path => lib_path("foo")
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{file_uri_for(lib_path("foo"))}"
G
expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{revision_for(lib_path("foo"))[0..6]})")
- expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}"
+ expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
end
- it "displays the correct default branch", git: ">= 2.28.0" do
- build_git "foo", "1.0", path: lib_path("foo"), default_branch: "main"
+ it "displays the correct default branch", :git => ">= 2.28.0" do
+ build_git "foo", "1.0", :path => lib_path("foo"), :default_branch => "main"
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{file_uri_for(lib_path("foo"))}"
G
expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{revision_for(lib_path("foo"))[0..6]})")
- expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}"
+ expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
end
it "displays the ref of the gem repository when using branch~num as a ref" do
skip "maybe branch~num notation doesn't work on Windows' git" if Gem.win_platform?
- build_git "foo", "1.0", path: lib_path("foo")
+ build_git "foo", "1.0", :path => lib_path("foo")
rev = revision_for(lib_path("foo"))[0..6]
- update_git "foo", "2.0", path: lib_path("foo"), gemspec: true
+ update_git "foo", "2.0", :path => lib_path("foo"), :gemspec => true
rev2 = revision_for(lib_path("foo"))[0..6]
- update_git "foo", "3.0", path: lib_path("foo"), gemspec: true
+ update_git "foo", "3.0", :path => lib_path("foo"), :gemspec => true
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{file_uri_for(lib_path("foo"))}", :ref => "main~2"
G
expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main~2@#{rev})")
- expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}"
+ expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
- update_git "foo", "4.0", path: lib_path("foo"), gemspec: true
+ update_git "foo", "4.0", :path => lib_path("foo"), :gemspec => true
- bundle :update, all: true, verbose: true
+ bundle :update, :all => true, :verbose => true
expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at main~2@#{rev2})")
- expect(the_bundle).to include_gems "foo 2.0", source: "git@#{lib_path("foo")}"
+ expect(the_bundle).to include_gems "foo 2.0", :source => "git@#{lib_path("foo")}"
end
it "should allows git repos that are missing but not being installed" do
@@ -81,9 +81,9 @@ RSpec.describe "bundle install" do
it "allows multiple gems from the same git source" do
build_repo2 do
- build_lib "foo", "1.0", path: lib_path("gems/foo")
- build_lib "zebra", "2.0", path: lib_path("gems/zebra")
- build_git "gems", path: lib_path("gems"), gemspec: false
+ build_lib "foo", "1.0", :path => lib_path("gems/foo")
+ build_lib "zebra", "2.0", :path => lib_path("gems/zebra")
+ build_git "gems", :path => lib_path("gems"), :gemspec => false
end
install_gemfile <<-G
@@ -106,8 +106,8 @@ RSpec.describe "bundle install" do
# NOTE: both gems MUST have the same path! It has to be two gems in one repo.
- test = build_git "test", "1.0.0", path: lib_path("test-and-other")
- other = build_git "other", "1.0.0", path: lib_path("test-and-other")
+ test = build_git "test", "1.0.0", :path => lib_path("test-and-other")
+ other = build_git "other", "1.0.0", :path => lib_path("test-and-other")
test_ref = test.ref_for("HEAD")
other_ref = other.ref_for("HEAD")
@@ -170,36 +170,5 @@ RSpec.describe "bundle install" do
expect(out).to include("Bundle complete!")
end
-
- it "allows older revisions of git source when clean true" do
- build_git "foo", "1.0", path: lib_path("foo")
- rev = revision_for(lib_path("foo"))
-
- bundle "config set path vendor/bundle"
- bundle "config set clean true"
- install_gemfile <<-G, verbose: true
- source "#{file_uri_for(gem_repo1)}"
- gem "foo", :git => "#{file_uri_for(lib_path("foo"))}"
- G
-
- expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{rev[0..6]})")
- expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}"
-
- old_lockfile = lockfile
-
- update_git "foo", "2.0", path: lib_path("foo"), gemspec: true
- rev2 = revision_for(lib_path("foo"))
-
- bundle :update, all: true, verbose: true
- expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at main@#{rev2[0..6]})")
- expect(out).to include("Removing foo (#{rev[0..11]})")
- expect(the_bundle).to include_gems "foo 2.0", source: "git@#{lib_path("foo")}"
-
- lockfile(old_lockfile)
-
- bundle :install, verbose: true
- expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{rev[0..6]})")
- expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}"
- end
end
end
diff --git a/spec/bundler/install/global_cache_spec.rb b/spec/bundler/install/global_cache_spec.rb
index 0da4de05b2..be34d8b5bc 100644
--- a/spec/bundler/install/global_cache_spec.rb
+++ b/spec/bundler/install/global_cache_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe "global gem caching" do
end
it "caches gems into the global cache on download" do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "#{source}"
gem "rack"
G
@@ -29,7 +29,7 @@ RSpec.describe "global gem caching" do
source_global_cache.mkpath
FileUtils.cp(gem_repo1("gems/rack-1.0.0.gem"), source_global_cache("rack-1.0.0.gem"))
- install_gemfile <<-G, artifice: "compact_index_no_gem"
+ install_gemfile <<-G, :artifice => "compact_index_no_gem"
source "#{source}"
gem "rack"
G
@@ -41,7 +41,7 @@ RSpec.describe "global gem caching" do
source_global_cache.mkpath
FileUtils.touch(source_global_cache("rack-1.0.0.gem"))
- install_gemfile <<-G, artifice: "compact_index_no_gem", raise_on_error: false
+ install_gemfile <<-G, :artifice => "compact_index_no_gem", :raise_on_error => false
source "#{source}"
gem "rack"
G
@@ -51,7 +51,7 @@ RSpec.describe "global gem caching" do
describe "when the same gem from different sources is installed" do
it "should use the appropriate one from the global cache" do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "#{source}"
gem "rack"
G
@@ -61,7 +61,7 @@ RSpec.describe "global gem caching" do
expect(source_global_cache("rack-1.0.0.gem")).to exist
# rack 1.0.0 is not installed and it is in the global cache
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "#{source2}"
gem "rack", "0.9.1"
G
@@ -76,7 +76,7 @@ RSpec.describe "global gem caching" do
gem "rack", "1.0.0"
G
- bundle :install, artifice: "compact_index_no_gem"
+ bundle :install, :artifice => "compact_index_no_gem"
# rack 1.0.0 is installed and rack 0.9.1 is not
expect(the_bundle).to include_gems "rack 1.0.0"
expect(the_bundle).not_to include_gems "rack 0.9.1"
@@ -87,7 +87,7 @@ RSpec.describe "global gem caching" do
gem "rack", "0.9.1"
G
- bundle :install, artifice: "compact_index_no_gem"
+ bundle :install, :artifice => "compact_index_no_gem"
# rack 0.9.1 is installed and rack 1.0.0 is not
expect(the_bundle).to include_gems "rack 0.9.1"
expect(the_bundle).not_to include_gems "rack 1.0.0"
@@ -99,7 +99,7 @@ RSpec.describe "global gem caching" do
gem "rack"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
simulate_new_machine
expect(the_bundle).not_to include_gems "rack 1.0.0"
expect(source_global_cache("rack-1.0.0.gem")).to exist
@@ -110,7 +110,7 @@ RSpec.describe "global gem caching" do
gem "rack", "0.9.1"
G
- bundle :install, artifice: "compact_index"
+ bundle :install, :artifice => "compact_index"
simulate_new_machine
expect(the_bundle).not_to include_gems "rack 0.9.1"
expect(source2_global_cache("rack-0.9.1.gem")).to exist
@@ -123,7 +123,7 @@ RSpec.describe "global gem caching" do
expect(source_global_cache("rack-1.0.0.gem")).to exist
expect(source2_global_cache("rack-0.9.1.gem")).to exist
- bundle :install, artifice: "compact_index_no_gem", raise_on_error: false
+ bundle :install, :artifice => "compact_index_no_gem", :raise_on_error => false
expect(err).to include("Internal Server Error 500")
expect(err).not_to include("ERROR REPORT TEMPLATE")
@@ -138,7 +138,7 @@ RSpec.describe "global gem caching" do
expect(source_global_cache("rack-1.0.0.gem")).to exist
expect(source2_global_cache("rack-0.9.1.gem")).to exist
- bundle :install, artifice: "compact_index_no_gem", raise_on_error: false
+ bundle :install, :artifice => "compact_index_no_gem", :raise_on_error => false
expect(err).to include("Internal Server Error 500")
expect(err).not_to include("ERROR REPORT TEMPLATE")
@@ -150,7 +150,7 @@ RSpec.describe "global gem caching" do
describe "when installing gems from a different directory" do
it "uses the global cache as a source" do
- install_gemfile <<-G, artifice: "compact_index"
+ install_gemfile <<-G, :artifice => "compact_index"
source "#{source}"
gem "rack"
gem "activesupport"
@@ -166,7 +166,7 @@ RSpec.describe "global gem caching" do
expect(the_bundle).not_to include_gems "rack 1.0.0"
expect(the_bundle).not_to include_gems "activesupport 2.3.5"
- install_gemfile <<-G, artifice: "compact_index_no_gem"
+ install_gemfile <<-G, :artifice => "compact_index_no_gem"
source "#{source}"
gem "rack"
G
@@ -183,18 +183,20 @@ RSpec.describe "global gem caching" do
G
# Neither gem is installed and both are in the global cache
- expect(the_bundle).not_to include_gems "rack 1.0.0", dir: bundled_app2
- expect(the_bundle).not_to include_gems "activesupport 2.3.5", dir: bundled_app2
+ expect(the_bundle).not_to include_gems "rack 1.0.0", :dir => bundled_app2
+ expect(the_bundle).not_to include_gems "activesupport 2.3.5", :dir => bundled_app2
expect(source_global_cache("rack-1.0.0.gem")).to exist
expect(source_global_cache("activesupport-2.3.5.gem")).to exist
# Install using the global cache instead of by downloading the .gem
# from the server
- bundle :install, artifice: "compact_index_no_gem", dir: bundled_app2
+ bundle :install, :artifice => "compact_index_no_gem", :dir => bundled_app2
# activesupport is installed and both are in the global cache
- expect(the_bundle).not_to include_gems "rack 1.0.0", dir: bundled_app2
- expect(the_bundle).to include_gems "activesupport 2.3.5", dir: bundled_app2
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ expect(the_bundle).not_to include_gems "rack 1.0.0", :dir => bundled_app2
+ expect(the_bundle).to include_gems "activesupport 2.3.5", :dir => bundled_app2
+ end
expect(source_global_cache("rack-1.0.0.gem")).to exist
expect(source_global_cache("activesupport-2.3.5.gem")).to exist
@@ -232,7 +234,7 @@ RSpec.describe "global gem caching" do
R
expect(out).to eq "VERY_SIMPLE_BINARY_IN_C\nVERY_SIMPLE_GIT_BINARY_IN_C"
- FileUtils.rm_rf Dir[home(".bundle", "cache", "extensions", "**", "*binary_c*")]
+ FileUtils.rm Dir[home(".bundle", "cache", "extensions", "**", "*binary_c*")]
gem_binary_cache.join("very_simple_binary_c.rb").open("w") {|f| f << "puts File.basename(__FILE__)" }
git_binary_cache.join("very_simple_git_binary_c.rb").open("w") {|f| f << "puts File.basename(__FILE__)" }
diff --git a/spec/bundler/install/path_spec.rb b/spec/bundler/install/path_spec.rb
index 0a30e402b7..bd5385b265 100644
--- a/spec/bundler/install/path_spec.rb
+++ b/spec/bundler/install/path_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe "bundle install" do
describe "with path configured" do
before :each do
- build_gem "rack", "1.0.0", to_system: true do |s|
+ build_gem "rack", "1.0.0", :to_system => true do |s|
s.write "lib/rack.rb", "puts 'FAIL'"
end
@@ -23,7 +23,7 @@ RSpec.describe "bundle install" do
bundle "config set --local path.system true"
bundle "config set --global path vendor/bundle"
bundle :install
- run "require 'rack'", raise_on_error: false
+ run "require 'rack'", :raise_on_error => false
expect(out).to include("FAIL")
end
@@ -32,7 +32,7 @@ RSpec.describe "bundle install" do
dir.mkpath
bundle "config set --local path #{dir.join("vendor/bundle")}"
- bundle :install, dir: dir
+ bundle :install, :dir => dir
expect(out).to include("installed into `./vendor/bundle`")
dir.rmtree
@@ -44,13 +44,13 @@ RSpec.describe "bundle install" do
expect(out).to include("gems are installed into `./vendor/bundle`")
end
- it "disallows --path vendor/bundle --system", bundler: "< 3" do
- bundle "install --path vendor/bundle --system", raise_on_error: false
+ it "disallows --path vendor/bundle --system", :bundler => "< 3" do
+ bundle "install --path vendor/bundle --system", :raise_on_error => false
expect(err).to include("Please choose only one option.")
expect(exitstatus).to eq(15)
end
- it "remembers to disable system gems after the first time with bundle --path vendor/bundle", bundler: "< 3" do
+ it "remembers to disable system gems after the first time with bundle --path vendor/bundle", :bundler => "< 3" do
bundle "install --path vendor/bundle"
FileUtils.rm_rf bundled_app("vendor")
bundle "install"
@@ -62,22 +62,22 @@ RSpec.describe "bundle install" do
context "with path_relative_to_cwd set to true" do
before { bundle "config set path_relative_to_cwd true" }
- it "installs the bundle relatively to current working directory", bundler: "< 3" do
- bundle "install --gemfile='#{bundled_app}/Gemfile' --path vendor/bundle", dir: bundled_app.parent
+ it "installs the bundle relatively to current working directory", :bundler => "< 3" do
+ bundle "install --gemfile='#{bundled_app}/Gemfile' --path vendor/bundle", :dir => bundled_app.parent
expect(out).to include("installed into `./vendor/bundle`")
expect(bundled_app("../vendor/bundle")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "installs the standalone bundle relative to the cwd" do
- bundle :install, gemfile: bundled_app_gemfile, standalone: true, dir: bundled_app.parent
+ bundle :install, :gemfile => bundled_app_gemfile, :standalone => true, :dir => bundled_app.parent
expect(out).to include("installed into `./bundled_app/bundle`")
expect(bundled_app("bundle")).to be_directory
expect(bundled_app("bundle/ruby")).to be_directory
bundle "config unset path"
- bundle :install, gemfile: bundled_app_gemfile, standalone: true, dir: bundled_app("subdir").tap(&:mkpath)
+ bundle :install, :gemfile => bundled_app_gemfile, :standalone => true, :dir => bundled_app("subdir").tap(&:mkpath)
expect(out).to include("installed into `../bundle`")
expect(bundled_app("bundle")).to be_directory
expect(bundled_app("bundle/ruby")).to be_directory
@@ -87,7 +87,7 @@ RSpec.describe "bundle install" do
describe "when BUNDLE_PATH or the global path config is set" do
before :each do
- build_lib "rack", "1.0.0", to_system: true do |s|
+ build_lib "rack", "1.0.0", :to_system => true do |s|
s.write "lib/rack.rb", "raise 'FAIL'"
end
@@ -141,7 +141,7 @@ RSpec.describe "bundle install" do
set_bundle_path(type, "vendor")
FileUtils.mkdir_p bundled_app("lol")
- bundle :install, dir: bundled_app("lol")
+ bundle :install, :dir => bundled_app("lol")
expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
@@ -168,7 +168,7 @@ RSpec.describe "bundle install" do
it "disables system gems when passing a path to install" do
# This is so that vendored gems can be distributed to others
- build_gem "rack", "1.1.0", to_system: true
+ build_gem "rack", "1.1.0", :to_system => true
bundle "config set --local path ./vendor/bundle"
bundle :install
@@ -177,7 +177,7 @@ RSpec.describe "bundle install" do
end
it "re-installs gems whose extensions have been deleted" do
- build_lib "very_simple_binary", "1.0.0", to_system: true do |s|
+ build_lib "very_simple_binary", "1.0.0", :to_system => true do |s|
s.write "lib/very_simple_binary.rb", "raise 'FAIL'"
end
@@ -191,11 +191,11 @@ RSpec.describe "bundle install" do
expect(vendored_gems("gems/very_simple_binary-1.0")).to be_directory
expect(vendored_gems("extensions")).to be_directory
- expect(the_bundle).to include_gems "very_simple_binary 1.0", source: "remote1"
+ expect(the_bundle).to include_gems "very_simple_binary 1.0", :source => "remote1"
vendored_gems("extensions").rmtree
- run "require 'very_simple_binary_c'", raise_on_error: false
+ run "require 'very_simple_binary_c'", :raise_on_error => false
expect(err).to include("Bundler::GemNotFound")
bundle "config set --local path ./vendor/bundle"
@@ -203,7 +203,7 @@ RSpec.describe "bundle install" do
expect(vendored_gems("gems/very_simple_binary-1.0")).to be_directory
expect(vendored_gems("extensions")).to be_directory
- expect(the_bundle).to include_gems "very_simple_binary 1.0", source: "remote1"
+ expect(the_bundle).to include_gems "very_simple_binary 1.0", :source => "remote1"
end
end
@@ -219,7 +219,7 @@ RSpec.describe "bundle install" do
G
bundle "config set --local path bundle"
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err).to include("file already exists")
end
end
diff --git a/spec/bundler/install/redownload_spec.rb b/spec/bundler/install/redownload_spec.rb
index 3a72c356d9..a936b2b536 100644
--- a/spec/bundler/install/redownload_spec.rb
+++ b/spec/bundler/install/redownload_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe "bundle install" do
end
end
- describe "with --force", bundler: 2 do
+ describe "with --force", :bundler => 2 do
it_behaves_like "an option to force redownloading gems" do
let(:flag) { "force" }
end
diff --git a/spec/bundler/install/security_policy_spec.rb b/spec/bundler/install/security_policy_spec.rb
index befeb81da5..43c3069c4e 100644
--- a/spec/bundler/install/security_policy_spec.rb
+++ b/spec/bundler/install/security_policy_spec.rb
@@ -16,23 +16,23 @@ RSpec.describe "policies with unsigned gems" do
end
it "will work after you try to deploy without a lock" do
- bundle "install --deployment", raise_on_error: false
+ bundle "install --deployment", :raise_on_error => false
bundle :install
expect(the_bundle).to include_gems "rack 1.0", "signed_gem 1.0"
end
it "will fail when given invalid security policy" do
- bundle "install --trust-policy=InvalidPolicyName", raise_on_error: false
+ bundle "install --trust-policy=InvalidPolicyName", :raise_on_error => false
expect(err).to include("RubyGems doesn't know about trust policy")
end
it "will fail with High Security setting due to presence of unsigned gem" do
- bundle "install --trust-policy=HighSecurity", raise_on_error: false
+ bundle "install --trust-policy=HighSecurity", :raise_on_error => false
expect(err).to include("security policy didn't allow")
end
it "will fail with Medium Security setting due to presence of unsigned gem" do
- bundle "install --trust-policy=MediumSecurity", raise_on_error: false
+ bundle "install --trust-policy=MediumSecurity", :raise_on_error => false
expect(err).to include("security policy didn't allow")
end
@@ -51,12 +51,12 @@ RSpec.describe "policies with signed gems and no CA" do
end
it "will fail with High Security setting, gem is self-signed" do
- bundle "install --trust-policy=HighSecurity", raise_on_error: false
+ bundle "install --trust-policy=HighSecurity", :raise_on_error => false
expect(err).to include("security policy didn't allow")
end
it "will fail with Medium Security setting, gem is self-signed" do
- bundle "install --trust-policy=MediumSecurity", raise_on_error: false
+ bundle "install --trust-policy=MediumSecurity", :raise_on_error => false
expect(err).to include("security policy didn't allow")
end
diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb
index 5aeabd2f23..dc054b50bb 100644
--- a/spec/bundler/install/yanked_spec.rb
+++ b/spec/bundler/install/yanked_spec.rb
@@ -22,7 +22,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do
L
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo4)}"
gem "foo", "10.0.0"
G
@@ -79,7 +79,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do
let(:source_uri) { file_uri_for(gem_repo4) }
it "reports the yanked gem properly" do
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
expect(err).to include("Your bundle is locked to nokogiri (1.13.8-#{Bundler.local_platform})")
end
@@ -89,7 +89,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do
let(:source_uri) { "https://gem.repo4" }
it "reports the yanked gem properly" do
- bundle "install", artifice: "compact_index", raise_on_error: false
+ bundle "install", :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Your bundle is locked to nokogiri (1.13.8-#{Bundler.local_platform})")
end
@@ -99,7 +99,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do
it "throws the original error when only the Gemfile specifies a gem version that doesn't exist" do
bundle "config set force_ruby_platform true"
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo4)}"
gem "foo", "10.0.0"
G
@@ -186,7 +186,7 @@ RSpec.context "when using gem before installing" do
rack (= 0.9.1)
L
- bundle :list, raise_on_error: false
+ bundle :list, :raise_on_error => false
expect(err).to include("Could not find rack-0.9.1 in locally installed gems")
expect(err).to_not include("Your bundle is locked to rack (0.9.1) from")
@@ -196,7 +196,7 @@ RSpec.context "when using gem before installing" do
# Check error message is still correct when multiple platforms are locked
lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
- bundle :list, raise_on_error: false
+ bundle :list, :raise_on_error => false
expect(err).to include("Could not find rack-0.9.1 in locally installed gems")
end
@@ -222,7 +222,7 @@ RSpec.context "when using gem before installing" do
rack_middleware (1.0)
L
- bundle :list, raise_on_error: false
+ bundle :list, :raise_on_error => false
expect(err).to include("Could not find rack-0.9.1, rack_middleware-1.0 in locally installed gems")
expect(err).to include("Install missing gems with `bundle install`.")
diff --git a/spec/bundler/lock/git_spec.rb b/spec/bundler/lock/git_spec.rb
index ad13e8ffc6..ac3d10223c 100644
--- a/spec/bundler/lock/git_spec.rb
+++ b/spec/bundler/lock/git_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe "bundle lock with git gems" do
gem 'foo', :git => "#{lib_path("foo-1.0")}", :branch => "bad"
G
- bundle "lock --update foo", env: { "LANG" => "en" }, raise_on_error: false
+ bundle "lock --update foo", :env => { "LANG" => "en" }, :raise_on_error => false
expect(err).to include("Revision bad does not exist in the repository")
end
@@ -55,7 +55,7 @@ RSpec.describe "bundle lock with git gems" do
#{Bundler::VERSION}
L
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
expect(err).to include("Revision #{"a" * 40} does not exist in the repository")
end
@@ -75,7 +75,7 @@ RSpec.describe "bundle lock with git gems" do
it "properly clones a git source locked to an out of date ref" do
update_git "foo"
- bundle :install, env: { "BUNDLE_PATH" => "foo" }
+ bundle :install, :env => { "BUNDLE_PATH" => "foo" }
expect(err).to be_empty
end
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index 4fd081e7d0..ccf23a9e3c 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -6,10 +6,6 @@ RSpec.describe "the lockfile format" do
end
it "generates a simple lockfile for a single source, gem" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "rack", "1.0.0")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
@@ -27,7 +23,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -58,7 +54,7 @@ RSpec.describe "the lockfile format" do
1.8.2
L
- install_gemfile <<-G, verbose: true, env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ install_gemfile <<-G, :verbose => true, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
source "#{file_uri_for(gem_repo2)}"
gem "rack"
@@ -84,7 +80,7 @@ RSpec.describe "the lockfile format" do
G
end
- it "does not update the lockfile's bundler version if nothing changed during bundle install, but uses the locked version", rubygems: ">= 3.3.0.a", realworld: true do
+ it "does not update the lockfile's bundler version if nothing changed during bundle install, but uses the locked version", :rubygems => ">= 3.3.0.a", :realworld => true do
version = "2.3.0"
lockfile <<-L
@@ -103,7 +99,7 @@ RSpec.describe "the lockfile format" do
#{version}
L
- install_gemfile <<-G, verbose: true, artifice: "vcr"
+ install_gemfile <<-G, :verbose => true, :artifice => "vcr"
source "#{file_uri_for(gem_repo2)}"
gem "rack"
@@ -129,13 +125,9 @@ RSpec.describe "the lockfile format" do
G
end
- it "does not update the lockfile's bundler version if nothing changed during bundle install, and uses the latest version", rubygems: "< 3.3.0.a" do
+ it "does not update the lockfile's bundler version if nothing changed during bundle install, and uses the latest version", :rubygems => "< 3.3.0.a" do
version = "#{Bundler::VERSION.split(".").first}.0.0.a"
- checksums = checksums_section do |c|
- c.checksum(gem_repo2, "rack", "1.0.0")
- end
-
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -147,12 +139,12 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{version}
L
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo2)}"
gem "rack"
@@ -172,7 +164,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{version}
G
@@ -237,7 +229,7 @@ RSpec.describe "the lockfile format" do
#{older_major}
L
- install_gemfile <<-G, env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ install_gemfile <<-G, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
@@ -269,11 +261,6 @@ RSpec.describe "the lockfile format" do
gem "rack-obama"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rack", "1.0.0"
- c.checksum gem_repo2, "rack-obama", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -287,7 +274,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -300,11 +287,6 @@ RSpec.describe "the lockfile format" do
gem "rack-obama", ">= 1.0"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rack", "1.0.0"
- c.checksum gem_repo2, "rack-obama", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -318,16 +300,16 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
- it "generates a lockfile without credentials" do
+ it "generates a lockfile without credentials for a configured source" do
bundle "config set http://localgemserver.test/ user:pass"
- install_gemfile(<<-G, artifice: "endpoint_strict_basic_authentication", quiet: true)
+ install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
source "#{file_uri_for(gem_repo1)}"
source "http://localgemserver.test/" do
@@ -339,11 +321,6 @@ RSpec.describe "the lockfile format" do
end
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rack", "1.0.0"
- c.checksum gem_repo2, "rack-obama", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -354,7 +331,7 @@ RSpec.describe "the lockfile format" do
specs:
GEM
- remote: http://othergemserver.test/
+ remote: http://user:pass@othergemserver.test/
specs:
rack (1.0.0)
rack-obama (1.0)
@@ -365,7 +342,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -377,11 +354,6 @@ RSpec.describe "the lockfile format" do
gem "net-sftp"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "net-sftp", "1.1.1"
- c.checksum gem_repo2, "net-ssh", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -395,7 +367,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
net-sftp
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -411,10 +383,6 @@ RSpec.describe "the lockfile format" do
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
@@ -431,14 +399,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not asplode when a platform specific dependency is present and the Gemfile has not been resolved on that platform" do
- build_lib "omg", path: lib_path("omg")
+ build_lib "omg", :path => lib_path("omg")
gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
@@ -479,10 +447,6 @@ RSpec.describe "the lockfile format" do
it "serializes global git sources" do
git = build_git "foo"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
@@ -506,7 +470,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -514,11 +478,7 @@ RSpec.describe "the lockfile format" do
it "generates a lockfile with a ref for a single pinned source, git gem with a branch requirement" do
git = build_git "foo"
- update_git "foo", branch: "omg"
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
+ update_git "foo", :branch => "omg"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -542,7 +502,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -550,11 +510,7 @@ RSpec.describe "the lockfile format" do
it "generates a lockfile with a ref for a single pinned source, git gem with a tag requirement" do
git = build_git "foo"
- update_git "foo", tag: "omg"
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
+ update_git "foo", :tag => "omg"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -578,7 +534,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -592,26 +548,26 @@ RSpec.describe "the lockfile format" do
FileUtils.mkdir_p lib_path("ckeditor/lib")
- @remote = build_git("ckeditor_remote", bare: true)
+ @remote = build_git("ckeditor_remote", :bare => true)
- build_git "ckeditor", path: lib_path("ckeditor") do |s|
+ build_git "ckeditor", :path => lib_path("ckeditor") do |s|
s.write "lib/ckeditor.rb", "CKEDITOR = '4.0.7'"
s.version = "4.0.7"
s.add_dependency "orm_adapter"
end
- update_git "ckeditor", path: lib_path("ckeditor"), remote: file_uri_for(@remote.path)
- update_git "ckeditor", path: lib_path("ckeditor"), tag: "v4.0.7"
- old_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.7"
+ update_git "ckeditor", :path => lib_path("ckeditor"), :remote => file_uri_for(@remote.path)
+ update_git "ckeditor", :path => lib_path("ckeditor"), :tag => "v4.0.7"
+ old_git = update_git "ckeditor", :path => lib_path("ckeditor"), :push => "v4.0.7"
- update_git "ckeditor", path: lib_path("ckeditor"), gemspec: true do |s|
+ update_git "ckeditor", :path => lib_path("ckeditor"), :gemspec => true do |s|
s.write "lib/ckeditor.rb", "CKEDITOR = '4.0.8'"
s.version = "4.0.8"
s.add_dependency "orm_adapter"
end
- update_git "ckeditor", path: lib_path("ckeditor"), tag: "v4.0.8"
+ update_git "ckeditor", :path => lib_path("ckeditor"), :tag => "v4.0.8"
- new_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.8"
+ new_git = update_git "ckeditor", :path => lib_path("ckeditor"), :push => "v4.0.8"
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
@@ -673,10 +629,6 @@ RSpec.describe "the lockfile format" do
it "serializes pinned path sources to the lockfile" do
build_lib "foo"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
@@ -697,7 +649,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -706,10 +658,6 @@ RSpec.describe "the lockfile format" do
it "serializes pinned path sources to the lockfile even when packaging" do
build_lib "foo"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
@@ -717,7 +665,7 @@ RSpec.describe "the lockfile format" do
bundle "config set cache_all true"
bundle :cache
- bundle :install, local: true
+ bundle :install, :local => true
expect(lockfile).to eq <<~G
PATH
@@ -734,7 +682,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -744,12 +692,6 @@ RSpec.describe "the lockfile format" do
build_lib "foo"
bar = build_git "bar"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- c.no_checksum "bar", "1.0"
- c.checksum gem_repo2, "rack", "1.0.0"
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
@@ -782,7 +724,7 @@ RSpec.describe "the lockfile format" do
bar!
foo!
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -795,10 +737,6 @@ RSpec.describe "the lockfile format" do
gem "rack", :source => "#{file_uri_for(gem_repo2)}/"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rack", "1.0.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -810,7 +748,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -825,14 +763,6 @@ RSpec.describe "the lockfile format" do
gem "rack-obama"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "actionpack", "2.3.2"
- c.checksum gem_repo2, "activesupport", "2.3.2"
- c.checksum gem_repo2, "rack", "1.0.0"
- c.checksum gem_repo2, "rack-obama", "1.0"
- c.checksum gem_repo2, "thin", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -853,7 +783,7 @@ RSpec.describe "the lockfile format" do
actionpack
rack-obama
thin
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -866,16 +796,6 @@ RSpec.describe "the lockfile format" do
gem "rails"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "actionmailer", "2.3.2"
- c.checksum gem_repo2, "actionpack", "2.3.2"
- c.checksum gem_repo2, "activerecord", "2.3.2"
- c.checksum gem_repo2, "activeresource", "2.3.2"
- c.checksum gem_repo2, "activesupport", "2.3.2"
- c.checksum gem_repo2, "rails", "2.3.2"
- c.checksum gem_repo2, "rake", rake_version
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -894,15 +814,15 @@ RSpec.describe "the lockfile format" do
actionpack (= 2.3.2)
activerecord (= 2.3.2)
activeresource (= 2.3.2)
- rake (= #{rake_version})
- rake (#{rake_version})
+ rake (= 13.0.1)
+ rake (13.0.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rails
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -913,7 +833,7 @@ RSpec.describe "the lockfile format" do
# Capistrano did this (at least until version 2.5.10)
# RubyGems 2.2 doesn't allow the specifying of a dependency twice
# See https://github.com/rubygems/rubygems/commit/03dbac93a3396a80db258d9bc63500333c25bd2f
- build_gem "double_deps", "1.0", skip_validation: true do |s|
+ build_gem "double_deps", "1.0", :skip_validation => true do |s|
s.add_dependency "net-ssh", ">= 1.0.0"
s.add_dependency "net-ssh"
end
@@ -924,11 +844,6 @@ RSpec.describe "the lockfile format" do
gem 'double_deps'
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "double_deps", "1.0"
- c.checksum gem_repo2, "net-ssh", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -943,7 +858,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
double_deps
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -956,11 +871,6 @@ RSpec.describe "the lockfile format" do
gem "rack-obama", ">= 1.0", :require => "rack/obama"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rack", "1.0.0"
- c.checksum gem_repo2, "rack-obama", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -974,7 +884,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -987,11 +897,6 @@ RSpec.describe "the lockfile format" do
gem "rack-obama", ">= 1.0", :group => :test
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "rack", "1.0.0"
- c.checksum gem_repo2, "rack-obama", "1.0"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -1005,18 +910,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided in a relative fashion and in Gemfile dir" do
- build_lib "foo", path: bundled_app("foo")
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
+ build_lib "foo", :path => bundled_app("foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1040,18 +941,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided in a relative fashion and is above Gemfile dir" do
- build_lib "foo", path: bundled_app(File.join("..", "foo"))
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
+ build_lib "foo", :path => bundled_app(File.join("..", "foo"))
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1075,18 +972,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided in an absolute fashion but is relative" do
- build_lib "foo", path: bundled_app("foo")
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
+ build_lib "foo", :path => bundled_app("foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1110,18 +1003,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided for gemspec" do
- build_lib("foo", path: tmp.join("foo"))
-
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "1.0"
- end
+ build_lib("foo", :path => tmp.join("foo"))
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1143,17 +1032,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "keeps existing platforms in the lockfile" do
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "rack", "1.0.0"
- end
-
lockfile <<-G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -1165,7 +1050,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -1176,8 +1061,6 @@ RSpec.describe "the lockfile format" do
gem "rack"
G
- checksums.checksum(gem_repo2, "rack", "1.0.0")
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -1185,56 +1068,16 @@ RSpec.describe "the lockfile format" do
rack (1.0.0)
PLATFORMS
- #{lockfile_platforms("java", local_platform, defaults: [])}
+ #{lockfile_platforms("java")}
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
- it "adds compatible platform specific variants to the lockfile, even if resolution fallback to RUBY due to some other incompatible platform specific variant" do
- simulate_platform "arm64-darwin-23" do
- build_repo4 do
- build_gem "google-protobuf", "3.25.1"
- build_gem "google-protobuf", "3.25.1" do |s|
- s.platform = "arm64-darwin-23"
- end
- build_gem "google-protobuf", "3.25.1" do |s|
- s.platform = "x64-mingw-ucrt"
- s.required_ruby_version = "> #{Gem.ruby_version}"
- end
- end
-
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem "google-protobuf"
- G
- bundle "lock --add-platform x64-mingw-ucrt"
-
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo4)}/
- specs:
- google-protobuf (3.25.1)
- google-protobuf (3.25.1-arm64-darwin-23)
-
- PLATFORMS
- arm64-darwin-23
- ruby
- x64-mingw-ucrt
-
- DEPENDENCIES
- google-protobuf
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
it "persists the spec's specific platform to the lockfile" do
build_repo2 do
build_gem "platform_specific", "1.0" do |s|
@@ -1249,10 +1092,6 @@ RSpec.describe "the lockfile format" do
gem "platform_specific"
G
- checksums = checksums_section_when_existing do |c|
- c.checksum gem_repo2, "platform_specific", "1.0", "universal-java-16"
- end
-
expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -1264,18 +1103,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
platform_specific
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate gems" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "activesupport", "2.3.5")
- c.checksum(gem_repo2, "rack", "1.0.0")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
@@ -1300,17 +1134,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
activesupport
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "rack", "1.0.0")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
@@ -1328,17 +1158,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies with versions" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "rack", "1.0.0")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0"
@@ -1356,17 +1182,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (= 1.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies in different groups" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "rack", "1.0.0")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0", :group => :one
@@ -1384,14 +1206,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (= 1.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "raises if two different versions are used" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0"
gem "rack", "1.1"
@@ -1402,7 +1224,7 @@ RSpec.describe "the lockfile format" do
end
it "raises if two different sources are used" do
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
gem "rack", :git => "git://hubz.com"
@@ -1413,10 +1235,6 @@ RSpec.describe "the lockfile format" do
end
it "works correctly with multiple version dependencies" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "rack", "0.9.1")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "> 0.9", "< 1.0"
@@ -1433,17 +1251,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (> 0.9, < 1.0)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "captures the Ruby version in the lockfile" do
- checksums = checksums_section_when_existing do |c|
- c.checksum(gem_repo2, "rack", "0.9.1")
- end
-
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
ruby '#{Gem.ruby_version}'
@@ -1461,7 +1275,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (> 0.9, < 1.0)
- #{checksums}
+
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -1484,7 +1298,7 @@ RSpec.describe "the lockfile format" do
rack_middleware
L
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}"
gem "rack_middleware"
G
@@ -1534,7 +1348,7 @@ RSpec.describe "the lockfile format" do
indirect_dependency (1.2.3)
PLATFORMS
- #{lockfile_platforms("ruby", generic_local_platform, defaults: [])}
+ #{formatted_lockfile_platforms(*["ruby", generic_local_platform].uniq)}
DEPENDENCIES
direct_dependency
@@ -1576,7 +1390,7 @@ RSpec.describe "the lockfile format" do
#{Bundler::VERSION}
L
- cache_gems "minitest-bisect-1.6.0", "path_expander-1.1.1", gem_repo: gem_repo4
+ cache_gems "minitest-bisect-1.6.0", "path_expander-1.1.1", :gem_repo => gem_repo4
bundle :install
expect(lockfile).to eq <<~L
@@ -1643,7 +1457,7 @@ RSpec.describe "the lockfile format" do
L
bundle "install --verbose"
- expect(out).to include("re-resolving dependencies because your lock file includes \"minitest-bisect\" but not some of its dependencies")
+ expect(out).to include("re-resolving dependencies because your lock file is missing \"minitest-bisect\"")
expect(lockfile).to eq <<~L
GEM
@@ -1692,7 +1506,7 @@ RSpec.describe "the lockfile format" do
end
end
- expect { bundle "update", all: true }.to change { File.mtime(bundled_app_lock) }
+ expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
expect(File.read(bundled_app_lock)).not_to match("\r\n")
expect(the_bundle).to include_gems "rack 1.2"
end
@@ -1710,10 +1524,12 @@ RSpec.describe "the lockfile format" do
File.open(bundled_app_lock, "wb") {|f| f.puts(win_lock) }
set_lockfile_mtime_to_known_value
- expect { bundle "update", all: true }.to change { File.mtime(bundled_app_lock) }
+ expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
expect(File.read(bundled_app_lock)).to match("\r\n")
- expect(the_bundle).to include_gems "rack 1.2"
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ expect(the_bundle).to include_gems "rack 1.2"
+ end
end
end
@@ -1734,7 +1550,7 @@ RSpec.describe "the lockfile format" do
expect do
ruby <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
Bundler.setup
RUBY
end.not_to change { File.mtime(bundled_app_lock) }
@@ -1763,7 +1579,7 @@ RSpec.describe "the lockfile format" do
#{Bundler::VERSION}
L
- install_gemfile <<-G, raise_on_error: false
+ install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
G
diff --git a/spec/bundler/other/cli_dispatch_spec.rb b/spec/bundler/other/cli_dispatch_spec.rb
index 48b285045a..2d6080296f 100644
--- a/spec/bundler/other/cli_dispatch_spec.rb
+++ b/spec/bundler/other/cli_dispatch_spec.rb
@@ -2,19 +2,19 @@
RSpec.describe "bundle command names" do
it "work when given fully" do
- bundle "install", raise_on_error: false
+ bundle "install", :raise_on_error => false
expect(err).to eq("Could not locate Gemfile")
expect(last_command.stdboth).not_to include("Ambiguous command")
end
it "work when not ambiguous" do
- bundle "ins", raise_on_error: false
+ bundle "ins", :raise_on_error => false
expect(err).to eq("Could not locate Gemfile")
expect(last_command.stdboth).not_to include("Ambiguous command")
end
it "print a friendly error when ambiguous" do
- bundle "in", raise_on_error: false
+ bundle "in", :raise_on_error => false
expect(err).to eq("Ambiguous command in matches [info, init, inject, install]")
end
end
diff --git a/spec/bundler/other/ext_spec.rb b/spec/bundler/other/ext_spec.rb
index 4d954b474f..9b829a2b36 100644
--- a/spec/bundler/other/ext_spec.rb
+++ b/spec/bundler/other/ext_spec.rb
@@ -59,27 +59,7 @@ RSpec.describe "Gem::SourceIndex#refresh!" do
end
it "does not explode when called" do
- run "Gem.source_index.refresh!", raise_on_error: false
- run "Gem::SourceIndex.new([]).refresh!", raise_on_error: false
- end
-end
-
-RSpec.describe "Gem::NameTuple" do
- describe "#initialize" do
- it "creates a Gem::NameTuple with equality regardless of platform type" do
- gem_platform = Gem::NameTuple.new "a", v("1"), pl("x86_64-linux")
- str_platform = Gem::NameTuple.new "a", v("1"), "x86_64-linux"
- expect(gem_platform).to eq(str_platform)
- expect(gem_platform.hash).to eq(str_platform.hash)
- expect(gem_platform.to_a).to eq(str_platform.to_a)
- end
- end
-
- describe "#lock_name" do
- it "returns the lock name" do
- expect(Gem::NameTuple.new("a", v("1.0.0"), pl("x86_64-linux")).lock_name).to eq("a (1.0.0-x86_64-linux)")
- expect(Gem::NameTuple.new("a", v("1.0.0"), "ruby").lock_name).to eq("a (1.0.0)")
- expect(Gem::NameTuple.new("a", v("1.0.0")).lock_name).to eq("a (1.0.0)")
- end
+ run "Gem.source_index.refresh!", :raise_on_error => false
+ run "Gem::SourceIndex.new([]).refresh!", :raise_on_error => false
end
end
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index e7577d38b4..7b7ceb4586 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -17,14 +17,14 @@ RSpec.describe "major deprecations" do
bundle "exec ruby -e #{source.dump}"
end
- it "is deprecated in favor of .unbundled_env", bundler: "< 3" do
+ it "is deprecated in favor of .unbundled_env", :bundler => "< 3" do
expect(deprecations).to include \
"`Bundler.clean_env` has been deprecated in favor of `Bundler.unbundled_env`. " \
"If you instead want the environment before bundler was originally loaded, use `Bundler.original_env` " \
"(called at -e:1)"
end
- pending "is removed and shows a helpful error message about it", bundler: "3"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
describe ".with_clean_env" do
@@ -33,7 +33,7 @@ RSpec.describe "major deprecations" do
bundle "exec ruby -e #{source.dump}"
end
- it "is deprecated in favor of .unbundled_env", bundler: "< 3" do
+ it "is deprecated in favor of .unbundled_env", :bundler => "< 3" do
expect(deprecations).to include(
"`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \
"If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env` " \
@@ -41,7 +41,7 @@ RSpec.describe "major deprecations" do
)
end
- pending "is removed and shows a helpful error message about it", bundler: "3"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
describe ".clean_system" do
@@ -50,7 +50,7 @@ RSpec.describe "major deprecations" do
bundle "exec ruby -e #{source.dump}"
end
- it "is deprecated in favor of .unbundled_system", bundler: "< 3" do
+ it "is deprecated in favor of .unbundled_system", :bundler => "< 3" do
expect(deprecations).to include(
"`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \
"If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system` " \
@@ -58,7 +58,7 @@ RSpec.describe "major deprecations" do
)
end
- pending "is removed and shows a helpful error message about it", bundler: "3"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
describe ".clean_exec" do
@@ -67,7 +67,7 @@ RSpec.describe "major deprecations" do
bundle "exec ruby -e #{source.dump}"
end
- it "is deprecated in favor of .unbundled_exec", bundler: "< 3" do
+ it "is deprecated in favor of .unbundled_exec", :bundler => "< 3" do
expect(deprecations).to include(
"`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \
"If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec` " \
@@ -75,7 +75,7 @@ RSpec.describe "major deprecations" do
)
end
- pending "is removed and shows a helpful error message about it", bundler: "3"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
describe ".environment" do
@@ -84,29 +84,29 @@ RSpec.describe "major deprecations" do
bundle "exec ruby -e #{source.dump}"
end
- it "is deprecated in favor of .load", bundler: "< 3" do
+ it "is deprecated in favor of .load", :bundler => "< 3" do
expect(deprecations).to include "Bundler.environment has been removed in favor of Bundler.load (called at -e:1)"
end
- pending "is removed and shows a helpful error message about it", bundler: "3"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
end
describe "bundle exec --no-keep-file-descriptors" do
before do
- bundle "exec --no-keep-file-descriptors -e 1", raise_on_error: false
+ bundle "exec --no-keep-file-descriptors -e 1", :raise_on_error => false
end
- it "is deprecated", bundler: "< 3" do
+ it "is deprecated", :bundler => "< 3" do
expect(deprecations).to include "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to"
end
- pending "is removed and shows a helpful error message about it", bundler: "3"
+ pending "is removed and shows a helpful error message about it", :bundler => "3"
end
describe "bundle update --quiet" do
it "does not print any deprecations" do
- bundle :update, quiet: true, raise_on_error: false
+ bundle :update, :quiet => true, :raise_on_error => false
expect(deprecations).to be_empty
end
end
@@ -118,19 +118,19 @@ RSpec.describe "major deprecations" do
gem "rack"
G
- bundle "check --path vendor/bundle", raise_on_error: false
+ bundle "check --path vendor/bundle", :raise_on_error => false
end
- it "should print a deprecation warning", bundler: "< 3" do
+ it "should print a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include(
"The `--path` flag is deprecated because it relies on being " \
"remembered across bundler invocations, which bundler will no " \
- "longer do in future versions. Instead please use `bundle config set " \
+ "longer do in future versions. Instead please use `bundle config set --local " \
"path 'vendor/bundle'`, and stop using this flag"
)
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "bundle check --path=" do
@@ -140,19 +140,19 @@ RSpec.describe "major deprecations" do
gem "rack"
G
- bundle "check --path=vendor/bundle", raise_on_error: false
+ bundle "check --path=vendor/bundle", :raise_on_error => false
end
- it "should print a deprecation warning", bundler: "< 3" do
+ it "should print a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include(
"The `--path` flag is deprecated because it relies on being " \
"remembered across bundler invocations, which bundler will no " \
- "longer do in future versions. Instead please use `bundle config set " \
+ "longer do in future versions. Instead please use `bundle config set --local " \
"path 'vendor/bundle'`, and stop using this flag"
)
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "bundle cache --all" do
@@ -162,10 +162,10 @@ RSpec.describe "major deprecations" do
gem "rack"
G
- bundle "cache --all", raise_on_error: false
+ bundle "cache --all", :raise_on_error => false
end
- it "should print a deprecation warning", bundler: "< 3" do
+ it "should print a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include(
"The `--all` flag is deprecated because it relies on being " \
"remembered across bundler invocations, which bundler will no " \
@@ -174,7 +174,7 @@ RSpec.describe "major deprecations" do
)
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "bundle cache --path" do
@@ -184,10 +184,10 @@ RSpec.describe "major deprecations" do
gem "rack"
G
- bundle "cache --path foo", raise_on_error: false
+ bundle "cache --path foo", :raise_on_error => false
end
- it "should print a deprecation warning", bundler: "< 3" do
+ it "should print a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include(
"The `--path` flag is deprecated because its semantics are unclear. " \
"Use `bundle config cache_path` to configure the path of your cache of gems, " \
@@ -196,7 +196,7 @@ RSpec.describe "major deprecations" do
)
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "bundle config" do
@@ -205,11 +205,11 @@ RSpec.describe "major deprecations" do
bundle "config"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config list` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old get interface" do
@@ -217,11 +217,11 @@ RSpec.describe "major deprecations" do
bundle "config waka"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config get waka` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old set interface" do
@@ -229,11 +229,11 @@ RSpec.describe "major deprecations" do
bundle "config waka wakapun"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set waka wakapun` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old set interface with --local" do
@@ -241,11 +241,11 @@ RSpec.describe "major deprecations" do
bundle "config --local waka wakapun"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set --local waka wakapun` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old set interface with --global" do
@@ -253,11 +253,11 @@ RSpec.describe "major deprecations" do
bundle "config --global waka wakapun"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config set --global waka wakapun` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old unset interface" do
@@ -265,11 +265,11 @@ RSpec.describe "major deprecations" do
bundle "config --delete waka"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset waka` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old unset interface with --local" do
@@ -277,11 +277,11 @@ RSpec.describe "major deprecations" do
bundle "config --delete --local waka"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset --local waka` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
describe "old unset interface with --global" do
@@ -289,11 +289,11 @@ RSpec.describe "major deprecations" do
bundle "config --delete --global waka"
end
- it "warns", bundler: "3" do
+ it "warns", :bundler => "3" do
expect(deprecations).to include("Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle config unset --global waka` instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
end
@@ -305,12 +305,12 @@ RSpec.describe "major deprecations" do
G
end
- it "warns when no options are given", bundler: "3" do
+ it "warns when no options are given", :bundler => "3" do
bundle "update"
expect(deprecations).to include("Pass --all to `bundle update` to update everything")
end
- pending "fails with a helpful error when no options are given", bundler: "3"
+ pending "fails with a helpful error when no options are given", :bundler => "3"
it "does not warn when --all is passed" do
bundle "update --all"
@@ -320,17 +320,17 @@ RSpec.describe "major deprecations" do
describe "bundle install --binstubs" do
before do
- install_gemfile <<-G, binstubs: true
+ install_gemfile <<-G, :binstubs => true
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
end
- it "should output a deprecation warning", bundler: "< 3" do
+ it "should output a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include("The --binstubs option will be removed in favor of `bundle binstubs --all`")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "bundle install with both gems.rb and Gemfile present" do
@@ -370,16 +370,16 @@ RSpec.describe "major deprecations" do
end
{
- "clean" => ["clean", "true"],
- "deployment" => ["deployment", "true"],
- "frozen" => ["frozen", "true"],
- "no-deployment" => ["deployment", "false"],
- "no-prune" => ["no_prune", "true"],
- "path" => ["path", "'vendor/bundle'"],
- "shebang" => ["shebang", "'ruby27'"],
- "system" => ["path.system", "true"],
- "without" => ["without", "'development'"],
- "with" => ["with", "'development'"],
+ "clean" => ["clean", true],
+ "deployment" => ["deployment", true],
+ "frozen" => ["frozen", true],
+ "no-deployment" => ["deployment", false],
+ "no-prune" => ["no_prune", true],
+ "path" => ["path", "vendor/bundle"],
+ "shebang" => ["shebang", "ruby27"],
+ "system" => ["system", true],
+ "without" => ["without", "development"],
+ "with" => ["with", "development"],
}.each do |name, expectations|
option_name, value = *expectations
flag_name = "--#{name}"
@@ -390,16 +390,16 @@ RSpec.describe "major deprecations" do
bundle "install #{flag_name} #{value}"
end
- it "should print a deprecation warning", bundler: "< 3" do
+ it "should print a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include(
"The `#{flag_name}` flag is deprecated because it relies on " \
"being remembered across bundler invocations, which bundler " \
"will no longer do in future versions. Instead please use " \
- "`bundle config set #{option_name} #{value}`, and stop using this flag"
+ "`bundle config set --local #{option_name} '#{value}'`, and stop using this flag"
)
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
end
end
@@ -412,7 +412,7 @@ RSpec.describe "major deprecations" do
G
end
- it "shows a deprecation", bundler: "< 3" do
+ it "shows a deprecation", :bundler => "< 3" do
expect(deprecations).to include(
"Your Gemfile contains multiple global sources. " \
"Using `source` more than once without a block is a security risk, and " \
@@ -421,7 +421,7 @@ RSpec.describe "major deprecations" do
)
end
- it "doesn't show lockfile deprecations if there's a lockfile", bundler: "< 3" do
+ it "doesn't show lockfile deprecations if there's a lockfile", :bundler => "< 3" do
bundle "install"
expect(deprecations).to include(
@@ -449,7 +449,7 @@ RSpec.describe "major deprecations" do
)
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "bundle install in frozen mode with a lockfile with a single rubygems section with multiple remotes" do
@@ -485,13 +485,13 @@ RSpec.describe "major deprecations" do
bundle "config set --local frozen true"
end
- it "shows a deprecation", bundler: "< 3" do
+ it "shows a deprecation", :bundler => "< 3" do
bundle "install"
expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "when Bundler.setup is run in a ruby script" do
@@ -503,7 +503,7 @@ RSpec.describe "major deprecations" do
G
ruby <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
Bundler.setup
Bundler.setup
@@ -519,19 +519,19 @@ RSpec.describe "major deprecations" do
context "when `bundler/deployment` is required in a ruby script" do
before do
- ruby <<-RUBY
+ ruby(<<-RUBY, :env => env_for_missing_prerelease_default_gem_activation)
require 'bundler/deployment'
RUBY
end
- it "should print a capistrano deprecation warning", bundler: "< 3" do
+ it "should print a capistrano deprecation warning", :bundler => "< 3" do
expect(deprecations).to include("Bundler no longer integrates " \
"with Capistrano, but Capistrano provides " \
"its own integration with Bundler via the " \
"capistrano-bundler gem. Use it instead.")
end
- pending "fails with a helpful error", bundler: "3"
+ pending "fails with a helpful error", :bundler => "3"
end
context "bundle show" do
@@ -547,11 +547,11 @@ RSpec.describe "major deprecations" do
bundle "show --outdated"
end
- it "prints a deprecation warning informing about its removal", bundler: "< 3" do
+ it "prints a deprecation warning informing about its removal", :bundler => "< 3" do
expect(deprecations).to include("the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement")
end
- pending "fails with a helpful message", bundler: "3"
+ pending "fails with a helpful message", :bundler => "3"
end
end
@@ -564,27 +564,27 @@ RSpec.describe "major deprecations" do
end
context "with --install" do
- it "shows a deprecation warning", bundler: "< 3" do
+ it "shows a deprecation warning", :bundler => "< 3" do
bundle "remove rack --install"
expect(err).to include "[DEPRECATED] The `--install` flag has been deprecated. `bundle install` is triggered by default."
end
- pending "fails with a helpful message", bundler: "3"
+ pending "fails with a helpful message", :bundler => "3"
end
end
context "bundle console" do
before do
- bundle "console", raise_on_error: false
+ bundle "console", :raise_on_error => false
end
- it "prints a deprecation warning", bundler: "< 3" do
+ it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"bundle console will be replaced by `bin/console` generated by `bundle gem <name>`"
end
- pending "fails with a helpful message", bundler: "3"
+ pending "fails with a helpful message", :bundler => "3"
end
context "bundle viz", :realworld do
@@ -594,42 +594,20 @@ RSpec.describe "major deprecations" do
bundle "viz"
end
- it "prints a deprecation warning", bundler: "< 3" do
+ it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
end
- pending "fails with a helpful message", bundler: "3"
+ pending "fails with a helpful message", :bundler => "3"
end
- context "bundle plugin install --local_git" do
- before do
- build_git "foo" do |s|
- s.write "plugins.rb"
- end
- end
-
- it "prints a deprecation warning", bundler: "< 3" do
- bundle "plugin install foo --local_git #{lib_path("foo-1.0")}"
-
- expect(out).to include("Installed plugin foo")
- expect(deprecations).to include "--local_git is deprecated, use --git"
- end
-
- pending "fails with a helpful message", bundler: "3"
- end
-
- describe "deprecating rubocop" do
- before do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false",
- "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
- end
-
+ describe "deprecating rubocop", :readline do
context "bundle gem --rubocop" do
before do
- bundle "gem my_new_gem --rubocop", raise_on_error: false
+ bundle "gem my_new_gem --rubocop", :raise_on_error => false
end
- it "prints a deprecation warning", bundler: "< 3" do
+ it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"--rubocop is deprecated, use --linter=rubocop"
end
@@ -637,10 +615,10 @@ RSpec.describe "major deprecations" do
context "bundle gem --no-rubocop" do
before do
- bundle "gem my_new_gem --no-rubocop", raise_on_error: false
+ bundle "gem my_new_gem --no-rubocop", :raise_on_error => false
end
- it "prints a deprecation warning", bundler: "< 3" do
+ it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"--no-rubocop is deprecated, use --linter"
end
@@ -648,10 +626,10 @@ RSpec.describe "major deprecations" do
context "bundle gem with gem.rubocop set to true" do
before do
- bundle "gem my_new_gem", env: { "BUNDLE_GEM__RUBOCOP" => "true" }, raise_on_error: false
+ bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "true" }, :raise_on_error => false
end
- it "prints a deprecation warning", bundler: "< 3" do
+ it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
end
@@ -659,10 +637,10 @@ RSpec.describe "major deprecations" do
context "bundle gem with gem.rubocop set to false" do
before do
- bundle "gem my_new_gem", env: { "BUNDLE_GEM__RUBOCOP" => "false" }, raise_on_error: false
+ bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "false" }, :raise_on_error => false
end
- it "prints a deprecation warning", bundler: "< 3" do
+ it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
end
diff --git a/spec/bundler/plugins/command_spec.rb b/spec/bundler/plugins/command_spec.rb
index af132d6550..3a7adf4b48 100644
--- a/spec/bundler/plugins/command_spec.rb
+++ b/spec/bundler/plugins/command_spec.rb
@@ -69,7 +69,7 @@ RSpec.describe "command plugins" do
end
end
- bundle "plugin install copycat --source #{file_uri_for(gem_repo2)}", raise_on_error: false
+ bundle "plugin install copycat --source #{file_uri_for(gem_repo2)}", :raise_on_error => false
expect(out).not_to include("Installed plugin copycat")
diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb
index 20c2f1fd26..aec131f2ee 100644
--- a/spec/bundler/plugins/install_spec.rb
+++ b/spec/bundler/plugins/install_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe "bundler plugin install" do
end
it "shows proper message when gem in not found in the source" do
- bundle "plugin install no-foo --source #{file_uri_for(gem_repo1)}", raise_on_error: false
+ bundle "plugin install no-foo --source #{file_uri_for(gem_repo1)}", :raise_on_error => false
expect(err).to include("Could not find")
plugin_should_not_be_installed("no-foo")
@@ -23,14 +23,14 @@ RSpec.describe "bundler plugin install" do
end
it "installs from rubygems source in frozen mode" do
- bundle "plugin install foo --source #{file_uri_for(gem_repo2)}", env: { "BUNDLE_DEPLOYMENT" => "true" }
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)}", :env => { "BUNDLE_DEPLOYMENT" => "true" }
expect(out).to include("Installed plugin foo")
plugin_should_be_installed("foo")
end
it "installs from sources configured as Gem.sources without any flags" do
- bundle "plugin install foo", env: { "BUNDLER_SPEC_GEM_SOURCES" => file_uri_for(gem_repo2).to_s }
+ bundle "plugin install foo", :env => { "BUNDLER_SPEC_GEM_SOURCES" => file_uri_for(gem_repo2).to_s }
expect(out).to include("Installed plugin foo")
plugin_should_be_installed("foo")
@@ -92,22 +92,20 @@ RSpec.describe "bundler plugin install" do
expect(out).to include("Using foo 1.1")
end
- it "raises an error when when --branch specified" do
- bundle "plugin install foo --branch main --source #{file_uri_for(gem_repo2)}", raise_on_error: false
+ it "installs when --branch specified" do
+ bundle "plugin install foo --branch main --source #{file_uri_for(gem_repo2)}"
- expect(out).not_to include("Installed plugin foo")
-
- expect(err).to include("--branch can only be used with git sources")
+ expect(out).to include("Installed plugin foo")
end
- it "raises an error when --ref specified" do
- bundle "plugin install foo --ref v1.2.3 --source #{file_uri_for(gem_repo2)}", raise_on_error: false
+ it "installs when --ref specified" do
+ bundle "plugin install foo --ref v1.2.3 --source #{file_uri_for(gem_repo2)}"
- expect(err).to include("--ref can only be used with git sources")
+ expect(out).to include("Installed plugin foo")
end
it "raises error when both --branch and --ref options are specified" do
- bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --branch main --ref v1.2.3", raise_on_error: false
+ bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --branch main --ref v1.2.3", :raise_on_error => false
expect(out).not_to include("Installed plugin foo")
@@ -154,7 +152,7 @@ RSpec.describe "bundler plugin install" do
build_gem "charlie"
end
- bundle "plugin install charlie --source #{file_uri_for(gem_repo2)}", raise_on_error: false
+ bundle "plugin install charlie --source #{file_uri_for(gem_repo2)}", :raise_on_error => false
expect(err).to include("Failed to install plugin `charlie`, due to Bundler::Plugin::MalformattedPlugin (plugins.rb was not found in the plugin.)")
@@ -173,7 +171,7 @@ RSpec.describe "bundler plugin install" do
end
end
- bundle "plugin install chaplin --source #{file_uri_for(gem_repo2)}", raise_on_error: false
+ bundle "plugin install chaplin --source #{file_uri_for(gem_repo2)}", :raise_on_error => false
expect(global_plugin_gem("chaplin-1.0")).not_to be_directory
@@ -198,58 +196,20 @@ RSpec.describe "bundler plugin install" do
s.write "plugins.rb"
end
- bundle "plugin install foo --git #{lib_path("foo-1.0")}"
+ bundle "plugin install foo --local_git #{lib_path("foo-1.0")}"
expect(out).to include("Installed plugin foo")
plugin_should_be_installed("foo")
end
- it "raises an error when both git and local git sources are specified", bundler: "< 3" do
- bundle "plugin install foo --git /phony/path/project --local_git git@gitphony.com:/repo/project", raise_on_error: false
+ it "raises an error when both git and local git sources are specified" do
+ bundle "plugin install foo --local_git /phony/path/project --git git@gitphony.com:/repo/project", :raise_on_error => false
expect(exitstatus).not_to eq(0)
expect(err).to eq("Remote and local plugin git sources can't be both specified")
end
end
- context "path plugins" do
- it "installs from a path source" do
- build_lib "path_plugin" do |s|
- s.write "plugins.rb"
- end
- bundle "plugin install path_plugin --path #{lib_path("path_plugin-1.0")}"
-
- expect(out).to include("Installed plugin path_plugin")
- plugin_should_be_installed("path_plugin")
- end
-
- it "installs from a relative path source" do
- build_lib "path_plugin" do |s|
- s.write "plugins.rb"
- end
- path = lib_path("path_plugin-1.0").relative_path_from(bundled_app)
- bundle "plugin install path_plugin --path #{path}"
-
- expect(out).to include("Installed plugin path_plugin")
- plugin_should_be_installed("path_plugin")
- end
-
- it "installs from a relative path source when inside an app" do
- allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- gemfile ""
-
- build_lib "ga-plugin" do |s|
- s.write "plugins.rb"
- end
-
- path = lib_path("ga-plugin-1.0").relative_path_from(bundled_app)
- bundle "plugin install ga-plugin --path #{path}"
-
- plugin_should_be_installed("ga-plugin")
- expect(local_plugin_gem("foo-1.0")).not_to be_directory
- end
- end
-
context "Gemfile eval" do
before do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
@@ -319,21 +279,6 @@ RSpec.describe "bundler plugin install" do
plugin_should_be_installed("ga-plugin")
end
- it "accepts relative path sources" do
- build_lib "ga-plugin" do |s|
- s.write "plugins.rb"
- end
-
- path = lib_path("ga-plugin-1.0").relative_path_from(bundled_app)
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- plugin 'ga-plugin', :path => "#{path}"
- G
-
- expect(out).to include("Installed plugin ga-plugin")
- plugin_should_be_installed("ga-plugin")
- end
-
context "in deployment mode" do
it "installs plugins" do
install_gemfile <<-G
@@ -369,7 +314,7 @@ RSpec.describe "bundler plugin install" do
end
RUBY
- ruby code, env: { "BUNDLER_VERSION" => Bundler::VERSION }
+ ruby code, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(local_plugin_gem("foo-1.0", "plugins.rb")).to exist
end
end
@@ -419,7 +364,7 @@ RSpec.describe "bundler plugin install" do
end
# outside the app
- bundle "plugin install fubar --source #{file_uri_for(gem_repo2)}", dir: tmp
+ bundle "plugin install fubar --source #{file_uri_for(gem_repo2)}", :dir => tmp
end
it "inside the app takes precedence over global plugin" do
@@ -428,7 +373,7 @@ RSpec.describe "bundler plugin install" do
end
it "outside the app global plugin is used" do
- bundle "shout", dir: tmp
+ bundle "shout", :dir => tmp
expect(out).to eq("global_one")
end
end
diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb
index e569f3e415..9d153b6063 100644
--- a/spec/bundler/plugins/source/example_spec.rb
+++ b/spec/bundler/plugins/source/example_spec.rb
@@ -70,10 +70,6 @@ RSpec.describe "real source plugins" do
it "writes to lock file" do
bundle "install"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "a-path-gem", "1.0"
- end
-
expect(lockfile).to eq <<~G
PLUGIN SOURCE
remote: #{lib_path("a-path-gem-1.0")}
@@ -90,7 +86,7 @@ RSpec.describe "real source plugins" do
DEPENDENCIES
a-path-gem!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -340,10 +336,6 @@ RSpec.describe "real source plugins" do
revision = revision_for(lib_path("ma-gitp-gem-1.0"))
bundle "install"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "ma-gitp-gem", "1.0"
- end
-
expect(lockfile).to eq <<~G
PLUGIN SOURCE
remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))}
@@ -361,7 +353,7 @@ RSpec.describe "real source plugins" do
DEPENDENCIES
ma-gitp-gem!
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -421,7 +413,7 @@ RSpec.describe "real source plugins" do
end
it "updates the deps on change in gemfile" do
- update_git "ma-gitp-gem", "1.1", path: lib_path("ma-gitp-gem-1.0"), gemspec: true
+ update_git "ma-gitp-gem", "1.1", :path => lib_path("ma-gitp-gem-1.0"), :gemspec => true
gemfile <<-G
source "#{file_uri_for(gem_repo2)}" # plugin source
source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do
diff --git a/spec/bundler/plugins/uninstall_spec.rb b/spec/bundler/plugins/uninstall_spec.rb
index 555c6a7002..8180241911 100644
--- a/spec/bundler/plugins/uninstall_spec.rb
+++ b/spec/bundler/plugins/uninstall_spec.rb
@@ -30,31 +30,6 @@ RSpec.describe "bundler plugin uninstall" do
plugin_should_not_be_installed("foo")
end
- it "doesn't wipe out path plugins" do
- build_lib "path_plugin" do |s|
- s.write "plugins.rb"
- end
- path = lib_path("path_plugin-1.0")
- expect(path).to be_a_directory
-
- allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
-
- install_gemfile <<-G
- source '#{file_uri_for(gem_repo2)}'
- plugin 'path_plugin', :path => "#{path}"
- gem 'rack', '1.0.0'
- G
-
- plugin_should_be_installed("path_plugin")
- expect(Bundler::Plugin.index.plugin_path("path_plugin")).to eq path
-
- bundle "plugin uninstall path_plugin"
- expect(out).to include("Uninstalled plugin path_plugin")
- plugin_should_not_be_installed("path_plugin")
- # the actual gem still exists though
- expect(path).to be_a_directory
- end
-
describe "with --all" do
it "uninstalls all installed plugins" do
bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}"
diff --git a/spec/bundler/quality_spec.rb b/spec/bundler/quality_spec.rb
index 7cdb993017..a98815158e 100644
--- a/spec/bundler/quality_spec.rb
+++ b/spec/bundler/quality_spec.rb
@@ -40,14 +40,16 @@ RSpec.describe "The library itself" do
"#{filename} has spaces on the EOL on lines #{failing_lines.join(", ")}"
end
- def check_for_extraneous_quotes(filename)
+ def check_for_straneous_quotes(filename)
+ return if File.expand_path(filename) == __FILE__
+
failing_lines = []
each_line(filename) do |line, number|
- failing_lines << number + 1 if /\u{2019}/.match?(line)
+ failing_lines << number + 1 if /’/.match?(line)
end
return if failing_lines.empty?
- "#{filename} has an extraneous quote on lines #{failing_lines.join(", ")}"
+ "#{filename} has an straneous quote on lines #{failing_lines.join(", ")}"
end
def check_for_expendable_words(filename)
@@ -94,12 +96,12 @@ RSpec.describe "The library itself" do
expect(error_messages.compact).to be_well_formed
end
- it "has no extraneous quotes" do
+ it "has no estraneous quotes" do
exempt = /vendor|vcr_cassettes|LICENSE|rbreadline\.diff/
error_messages = []
tracked_files.each do |filename|
next if filename&.match?(exempt)
- error_messages << check_for_extraneous_quotes(filename)
+ error_messages << check_for_straneous_quotes(filename)
end
expect(error_messages.compact).to be_well_formed
end
@@ -191,10 +193,9 @@ RSpec.describe "The library itself" do
end
it "ships the correct set of files" do
- git_list = tracked_files.reject {|f| f.start_with?("spec/") }
+ git_list = git_ls_files(ruby_core? ? "lib/bundler lib/bundler.rb libexec/bundle*" : "lib exe CHANGELOG.md LICENSE.md README.md bundler.gemspec")
gem_list = loaded_gemspec.files
- gem_list.map! {|f| f.sub(%r{\Aexe/}, "libexec/") } if ruby_core?
expect(git_list).to match_array(gem_list)
end
@@ -239,6 +240,6 @@ RSpec.describe "The library itself" do
private
def each_line(filename, &block)
- File.readlines(filename, encoding: "UTF-8").each_with_index(&block)
+ File.readlines(filename, :encoding => "UTF-8").each_with_index(&block)
end
end
diff --git a/spec/bundler/realworld/dependency_api_spec.rb b/spec/bundler/realworld/dependency_api_spec.rb
index ee5c0e3d0a..14f99bd262 100644
--- a/spec/bundler/realworld/dependency_api_spec.rb
+++ b/spec/bundler/realworld/dependency_api_spec.rb
@@ -2,7 +2,7 @@
require_relative "../support/silent_logger"
-RSpec.describe "gemcutter's dependency API", realworld: true do
+RSpec.describe "gemcutter's dependency API", :realworld => true do
context "when Gemcutter API takes too long to respond" do
before do
require_rack
@@ -13,12 +13,12 @@ RSpec.describe "gemcutter's dependency API", realworld: true do
require_relative "../support/artifice/endpoint_timeout"
@t = Thread.new do
- server = Rack::Server.start(app: EndpointTimeout,
- Host: "0.0.0.0",
- Port: port,
- server: "webrick",
- AccessLog: [],
- Logger: Spec::SilentLogger.new)
+ server = Rack::Server.start(:app => EndpointTimeout,
+ :Host => "0.0.0.0",
+ :Port => port,
+ :server => "webrick",
+ :AccessLog => [],
+ :Logger => Spec::SilentLogger.new)
server.start
end
@t.run
@@ -34,7 +34,7 @@ RSpec.describe "gemcutter's dependency API", realworld: true do
end
it "times out and falls back on the modern index" do
- install_gemfile <<-G, artifice: nil
+ install_gemfile <<-G, :artifice => nil
source "#{@server_uri}"
gem "rack"
G
diff --git a/spec/bundler/realworld/double_check_spec.rb b/spec/bundler/realworld/double_check_spec.rb
index 0741560395..d7f28d10bb 100644
--- a/spec/bundler/realworld/double_check_spec.rb
+++ b/spec/bundler/realworld/double_check_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "double checking sources", realworld: true do
+RSpec.describe "double checking sources", :realworld => true do
it "finds already-installed gems" do
create_file("rails.gemspec", <<-RUBY)
Gem::Specification.new do |s|
@@ -25,9 +25,9 @@ RSpec.describe "double checking sources", realworld: true do
RUBY
cmd = <<-RUBY
- require "bundler"
+ require "#{entrypoint}"
require "#{spec_dir}/support/artifice/vcr"
- require "bundler/inline"
+ require "#{entrypoint}/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails", path: "."
diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb
index 94ca3554b1..2f465b7b25 100644
--- a/spec/bundler/realworld/edgecases_spec.rb
+++ b/spec/bundler/realworld/edgecases_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "real world edgecases", realworld: true do
+RSpec.describe "real world edgecases", :realworld => true do
def rubygems_version(name, requirement)
ruby <<-RUBY
require "#{spec_dir}/support/artifice/vcr"
@@ -8,10 +8,9 @@ RSpec.describe "real world edgecases", realworld: true do
require "bundler/source/rubygems/remote"
require "bundler/fetcher"
rubygem = Bundler.ui.silence do
- remote = Bundler::Source::Rubygems::Remote.new(Gem::URI("https://rubygems.org"))
- source = Bundler::Source::Rubygems.new
- fetcher = Bundler::Fetcher.new(remote)
- index = fetcher.specs([#{name.dump}], source)
+ source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org"))
+ fetcher = Bundler::Fetcher.new(source)
+ index = fetcher.specs([#{name.dump}], nil)
requirement = Gem::Requirement.create(#{requirement.dump})
index.search(#{name.dump}).select {|spec| requirement.satisfied_by?(spec.version) }.last
end
@@ -193,13 +192,13 @@ RSpec.describe "real world edgecases", realworld: true do
rails (~> 4.2.7.1)
L
- bundle "lock --update paperclip", env: { "BUNDLER_VERSION" => "1.99.0" }
+ bundle "lock --update paperclip", :env => { "BUNDLER_VERSION" => "1.99.0" }
expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0"))
end
- it "outputs a helpful error message when gems have invalid gemspecs", rubygems: "< 3.3.16" do
- install_gemfile <<-G, standalone: true, raise_on_error: false, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" }
+ it "outputs a helpful error message when gems have invalid gemspecs", :rubygems => "< 3.3.16" do
+ install_gemfile <<-G, :standalone => true, :raise_on_error => false, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" }
source 'https://rubygems.org'
gem "resque-scheduler", "2.2.0"
gem "redis-namespace", "1.6.0" # for a consistent resolution including ruby 2.3.0
@@ -209,8 +208,8 @@ RSpec.describe "real world edgecases", realworld: true do
expect(err).to include("resque-scheduler 2.2.0 has an invalid gemspec")
end
- it "outputs a helpful warning when gems have a gemspec with invalid `require_paths`", rubygems: ">= 3.3.16" do
- install_gemfile <<-G, standalone: true, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" }
+ it "outputs a helpful warning when gems have a gemspec with invalid `require_paths`", :rubygems => ">= 3.3.16" do
+ install_gemfile <<-G, :standalone => true, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" }
source 'https://rubygems.org'
gem "resque-scheduler", "2.2.0"
gem "redis-namespace", "1.6.0" # for a consistent resolution including ruby 2.3.0
@@ -219,6 +218,140 @@ RSpec.describe "real world edgecases", realworld: true do
expect(err).to include("resque-scheduler 2.2.0 includes a gemspec with `require_paths` set to an array of arrays. Newer versions of this gem might've already fixed this").once
end
+ it "doesn't hang on big gemfile" do
+ skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7")
+
+ gemfile <<~G
+ # frozen_string_literal: true
+
+ source "https://rubygems.org"
+
+ ruby "~> 2.7.7"
+
+ gem "rails"
+ gem "pg", ">= 0.18", "< 2.0"
+ gem "goldiloader"
+ gem "awesome_nested_set"
+ gem "circuitbox"
+ gem "passenger"
+ gem "globalid"
+ gem "rack-cors"
+ gem "rails-pg-extras"
+ gem "linear_regression_trend"
+ gem "rack-protection"
+ gem "pundit"
+ gem "remote_ip_proxy_scrubber"
+ gem "bcrypt"
+ gem "searchkick"
+ gem "excon"
+ gem "faraday_middleware-aws-sigv4"
+ gem "typhoeus"
+ gem "sidekiq"
+ gem "sidekiq-undertaker"
+ gem "sidekiq-cron"
+ gem "storext"
+ gem "appsignal"
+ gem "fcm"
+ gem "business_time"
+ gem "tzinfo"
+ gem "holidays"
+ gem "bigdecimal"
+ gem "progress_bar"
+ gem "redis"
+ gem "hiredis"
+ gem "state_machines"
+ gem "state_machines-audit_trail"
+ gem "state_machines-activerecord"
+ gem "interactor"
+ gem "ar_transaction_changes"
+ gem "redis-rails"
+ gem "seed_migration"
+ gem "lograge"
+ gem "graphiql-rails", group: :development
+ gem "graphql"
+ gem "pusher"
+ gem "rbnacl"
+ gem "jwt"
+ gem "json-schema"
+ gem "discard"
+ gem "money"
+ gem "strip_attributes"
+ gem "validates_email_format_of"
+ gem "audited"
+ gem "concurrent-ruby"
+ gem "with_advisory_lock"
+
+ group :test do
+ gem "rspec-sidekiq"
+ gem "simplecov", require: false
+ end
+
+ group :development, :test do
+ gem "byebug", platform: :mri
+ gem "guard"
+ gem "guard-bundler"
+ gem "guard-rspec"
+ gem "rb-fsevent"
+ gem "rspec_junit_formatter"
+ gem "rspec-collection_matchers"
+ gem "rspec-rails"
+ gem "rspec-retry"
+ gem "state_machines-rspec"
+ gem "dotenv-rails"
+ gem "database_cleaner-active_record"
+ gem "database_cleaner-redis"
+ gem "timecop"
+ end
+
+ gem "factory_bot_rails"
+ gem "faker"
+
+ group :development do
+ gem "listen"
+ gem "sql_queries_count"
+ gem "rubocop"
+ gem "rubocop-performance"
+ gem "rubocop-rspec"
+ gem "rubocop-rails"
+ gem "brakeman"
+ gem "bundler-audit"
+ gem "solargraph"
+ gem "annotate"
+ end
+ G
+
+ if Bundler.feature_flag.bundler_3_mode?
+ # Conflicts on bundler version, so we count attempts differently
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }, :raise_on_error => false
+ expect(out.split("\n").grep(/backtracking to/).count).to eq(16)
+ else
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
+ expect(out).to include("Solution found after 7 attempts")
+ end
+ end
+
+ it "doesn't hang on tricky gemfile" do
+ skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7")
+
+ gemfile <<~G
+ source 'https://rubygems.org'
+
+ group :development do
+ gem "puppet-module-posix-default-r2.7", '~> 0.3'
+ gem "puppet-module-posix-dev-r2.7", '~> 0.3'
+ gem "beaker-rspec"
+ gem "beaker-puppet"
+ gem "beaker-docker"
+ gem "beaker-puppet_install_helper"
+ gem "beaker-module_install_helper"
+ end
+ G
+
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
+
+ expect(out).to include("Solution found after 6 attempts")
+ end
+
it "doesn't hang on nix gemfile" do
skip "Only for ruby 3.0" unless RUBY_VERSION.start_with?("3.0")
@@ -376,7 +509,7 @@ RSpec.describe "real world edgecases", realworld: true do
gem "zookeeper"
G
- bundle :lock, env: { "DEBUG_RESOLVER" => "1" }
+ bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
expect(out).to include("Solution found after 4 attempts")
end
diff --git a/spec/bundler/realworld/ffi_spec.rb b/spec/bundler/realworld/ffi_spec.rb
index 5f40b43a0f..fdefc14091 100644
--- a/spec/bundler/realworld/ffi_spec.rb
+++ b/spec/bundler/realworld/ffi_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "loading dynamically linked library on a bundle exec context", realworld: true do
+RSpec.describe "loading dynamically linked library on a bundle exec context", :realworld => true do
it "passes ENV right after argv in memory" do
create_file "foo.rb", <<~RUBY
require 'ffi'
diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile b/spec/bundler/realworld/fixtures/warbler/Gemfile
index a8dbb4911c..4fbf2d05a7 100644
--- a/spec/bundler/realworld/fixtures/warbler/Gemfile
+++ b/spec/bundler/realworld/fixtures/warbler/Gemfile
@@ -2,6 +2,6 @@
source "https://rubygems.org"
-gem "demo", path: "./demo"
+gem "demo", :path => "./demo"
gem "jruby-jars", "~> 9.2"
gem "warbler", "~> 2.0"
diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
index 5b476f8df2..8f29bd341f 100644
--- a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
+++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
@@ -27,4 +27,4 @@ DEPENDENCIES
warbler (~> 2.0)
BUNDLED WITH
- 2.5.0.dev
+ 2.4.0.dev
diff --git a/spec/bundler/realworld/gemfile_source_header_spec.rb b/spec/bundler/realworld/gemfile_source_header_spec.rb
index 45f5d0fd22..60c0055a62 100644
--- a/spec/bundler/realworld/gemfile_source_header_spec.rb
+++ b/spec/bundler/realworld/gemfile_source_header_spec.rb
@@ -2,7 +2,7 @@
require_relative "../support/silent_logger"
-RSpec.describe "fetching dependencies with a mirrored source", realworld: true do
+RSpec.describe "fetching dependencies with a mirrored source", :realworld => true do
let(:mirror) { "https://server.example.org" }
let(:original) { "http://127.0.0.1:#{@port}" }
@@ -17,13 +17,13 @@ RSpec.describe "fetching dependencies with a mirrored source", realworld: true d
@t.join
end
- it "sets the 'X-Gemfile-Source' and 'User-Agent' headers and bundles successfully" do
+ it "sets the 'X-Gemfile-Source' header and bundles successfully" do
gemfile <<-G
source "#{mirror}"
gem 'weakling'
G
- bundle :install, artifice: nil
+ bundle :install, :artifice => nil
expect(out).to include("Installing weakling")
expect(out).to include("Bundle complete")
@@ -40,12 +40,12 @@ RSpec.describe "fetching dependencies with a mirrored source", realworld: true d
require_relative "../support/artifice/endpoint_mirror_source"
@t = Thread.new do
- Rack::Server.start(app: EndpointMirrorSource,
- Host: "0.0.0.0",
- Port: @port,
- server: "webrick",
- AccessLog: [],
- Logger: Spec::SilentLogger.new)
+ Rack::Server.start(:app => EndpointMirrorSource,
+ :Host => "0.0.0.0",
+ :Port => @port,
+ :server => "webrick",
+ :AccessLog => [],
+ :Logger => Spec::SilentLogger.new)
end.run
wait_for_server("127.0.0.1", @port)
diff --git a/spec/bundler/realworld/git_spec.rb b/spec/bundler/realworld/git_spec.rb
index 9eff74f1c9..3d352626ea 100644
--- a/spec/bundler/realworld/git_spec.rb
+++ b/spec/bundler/realworld/git_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "github source", realworld: true do
+RSpec.describe "github source", :realworld => true do
it "properly fetches PRs" do
install_gemfile <<-G
source "https://rubygems.org"
diff --git a/spec/bundler/realworld/mirror_probe_spec.rb b/spec/bundler/realworld/mirror_probe_spec.rb
index fc97f92375..f2ce477c10 100644
--- a/spec/bundler/realworld/mirror_probe_spec.rb
+++ b/spec/bundler/realworld/mirror_probe_spec.rb
@@ -2,7 +2,7 @@
require_relative "../support/silent_logger"
-RSpec.describe "fetching dependencies with a not available mirror", realworld: true do
+RSpec.describe "fetching dependencies with a not available mirror", :realworld => true do
let(:mirror) { @mirror_uri }
let(:original) { @server_uri }
let(:server_port) { @server_port }
@@ -32,7 +32,7 @@ RSpec.describe "fetching dependencies with a not available mirror", realworld: t
gem 'weakling'
G
- bundle :install, artifice: nil
+ bundle :install, :artifice => nil
expect(out).to include("Installing weakling")
expect(out).to include("Bundle complete")
@@ -52,7 +52,7 @@ RSpec.describe "fetching dependencies with a not available mirror", realworld: t
gem 'weakling'
G
- bundle :install, artifice: nil
+ bundle :install, :artifice => nil
expect(out).to include("Installing weakling")
expect(out).to include("Bundle complete")
@@ -71,7 +71,7 @@ RSpec.describe "fetching dependencies with a not available mirror", realworld: t
gem 'weakling'
G
- bundle :install, artifice: nil, raise_on_error: false
+ bundle :install, :artifice => nil, :raise_on_error => false
expect(out).to include("Fetching source index from #{mirror}")
@@ -94,7 +94,7 @@ RSpec.describe "fetching dependencies with a not available mirror", realworld: t
gem 'weakling'
G
- bundle :install, artifice: nil, raise_on_error: false
+ bundle :install, :artifice => nil, :raise_on_error => false
expect(out).to include("Fetching source index from #{mirror}")
@@ -113,12 +113,12 @@ RSpec.describe "fetching dependencies with a not available mirror", realworld: t
require_relative "../support/artifice/endpoint"
@server_thread = Thread.new do
- Rack::Server.start(app: Endpoint,
- Host: host,
- Port: @server_port,
- server: "webrick",
- AccessLog: [],
- Logger: Spec::SilentLogger.new)
+ Rack::Server.start(:app => Endpoint,
+ :Host => host,
+ :Port => @server_port,
+ :server => "webrick",
+ :AccessLog => [],
+ :Logger => Spec::SilentLogger.new)
end.run
wait_for_server(host, @server_port)
diff --git a/spec/bundler/realworld/parallel_spec.rb b/spec/bundler/realworld/parallel_spec.rb
index b57fdfd0ee..a1e4f83909 100644
--- a/spec/bundler/realworld/parallel_spec.rb
+++ b/spec/bundler/realworld/parallel_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "parallel", realworld: true do
+RSpec.describe "parallel", :realworld => true do
it "installs" do
gemfile <<-G
source "https://rubygems.org"
@@ -9,7 +9,7 @@ RSpec.describe "parallel", realworld: true do
gem 'i18n', '~> 0.6.0' # Because 0.7+ requires Ruby 1.9.3+
G
- bundle :install, jobs: 4, env: { "DEBUG" => "1" }
+ bundle :install, :jobs => 4, :env => { "DEBUG" => "1" }
expect(out).to match(/[1-3]: /)
@@ -34,7 +34,7 @@ RSpec.describe "parallel", realworld: true do
gem 'i18n', '~> 0.6.0' # Because 0.7+ requires Ruby 1.9.3+
G
- bundle :update, jobs: 4, env: { "DEBUG" => "1" }, all: true
+ bundle :update, :jobs => 4, :env => { "DEBUG" => "1" }, :all => true
expect(out).to match(/[1-3]: /)
@@ -51,7 +51,7 @@ RSpec.describe "parallel", realworld: true do
gem "diff-lcs"
G
- bundle :install, standalone: true, jobs: 4
+ bundle :install, :standalone => true, :jobs => 4
ruby <<-RUBY
$:.unshift File.expand_path("bundle")
diff --git a/spec/bundler/realworld/slow_perf_spec.rb b/spec/bundler/realworld/slow_perf_spec.rb
index 32e266ff1b..aa8a48fcc7 100644
--- a/spec/bundler/realworld/slow_perf_spec.rb
+++ b/spec/bundler/realworld/slow_perf_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-RSpec.describe "bundle install with complex dependencies", realworld: true do
+RSpec.describe "bundle install with complex dependencies", :realworld => true do
it "resolves quickly" do
gemfile <<-G
source 'https://rubygems.org'
@@ -11,8 +11,7 @@ RSpec.describe "bundle install with complex dependencies", realworld: true do
gem "mongoid", ">= 0.10.2"
G
- bundle "lock", env: { "DEBUG_RESOLVER" => "1" }
- expect(out).to include("Solution found after 1 attempts")
+ expect { bundle "lock" }.to take_less_than(18) # seconds
end
it "resolves quickly (case 2)" do
@@ -29,116 +28,6 @@ RSpec.describe "bundle install with complex dependencies", realworld: true do
gem 'rspec-rails'
G
- bundle "lock", env: { "DEBUG_RESOLVER" => "1" }
- expect(out).to include("Solution found after 1 attempts")
- end
-
- it "resolves big gemfile quickly" do
- gemfile <<~G
- # frozen_string_literal: true
-
- source "https://rubygems.org"
-
- gem "rails"
- gem "pg", ">= 0.18", "< 2.0"
- gem "goldiloader"
- gem "awesome_nested_set"
- gem "circuitbox"
- gem "passenger"
- gem "globalid"
- gem "rack-cors"
- gem "rails-pg-extras"
- gem "linear_regression_trend"
- gem "rack-protection"
- gem "pundit"
- gem "remote_ip_proxy_scrubber"
- gem "bcrypt"
- gem "searchkick"
- gem "excon"
- gem "faraday_middleware-aws-sigv4"
- gem "typhoeus"
- gem "sidekiq"
- gem "sidekiq-undertaker"
- gem "sidekiq-cron"
- gem "storext"
- gem "appsignal"
- gem "fcm"
- gem "business_time"
- gem "tzinfo"
- gem "holidays"
- gem "bigdecimal"
- gem "progress_bar"
- gem "redis"
- gem "hiredis"
- gem "state_machines"
- gem "state_machines-audit_trail"
- gem "state_machines-activerecord"
- gem "interactor"
- gem "ar_transaction_changes"
- gem "redis-rails"
- gem "seed_migration"
- gem "lograge"
- gem "graphiql-rails", group: :development
- gem "graphql"
- gem "pusher"
- gem "rbnacl"
- gem "jwt"
- gem "json-schema"
- gem "discard"
- gem "money"
- gem "strip_attributes"
- gem "validates_email_format_of"
- gem "audited"
- gem "concurrent-ruby"
- gem "with_advisory_lock"
-
- group :test do
- gem "rspec-sidekiq"
- gem "simplecov", require: false
- end
-
- group :development, :test do
- gem "byebug", platform: :mri
- gem "guard"
- gem "guard-bundler"
- gem "guard-rspec"
- gem "rb-fsevent"
- gem "rspec_junit_formatter"
- gem "rspec-collection_matchers"
- gem "rspec-rails"
- gem "rspec-retry"
- gem "state_machines-rspec"
- gem "dotenv-rails"
- gem "database_cleaner-active_record"
- gem "database_cleaner-redis"
- gem "timecop"
- end
-
- gem "factory_bot_rails"
- gem "faker"
-
- group :development do
- gem "listen"
- gem "sql_queries_count"
- gem "rubocop"
- gem "rubocop-performance"
- gem "rubocop-rspec"
- gem "rubocop-rails"
- gem "brakeman"
- gem "bundler-audit"
- gem "solargraph"
- gem "annotate"
- end
- G
-
- if Bundler.feature_flag.bundler_3_mode?
- bundle "lock", env: { "DEBUG_RESOLVER" => "1" }, raise_on_error: false
-
- expect(out).to include("backtracking").exactly(26).times
- else
- bundle "lock", env: { "DEBUG_RESOLVER" => "1" }
-
- expect(out).to include("Solution found after 10 attempts")
- end
+ expect { bundle "lock" }.to take_less_than(30) # seconds
end
end
diff --git a/spec/bundler/resolver/basic_spec.rb b/spec/bundler/resolver/basic_spec.rb
index 4a0dd37bf9..f739f8c02b 100644
--- a/spec/bundler/resolver/basic_spec.rb
+++ b/spec/bundler/resolver/basic_spec.rb
@@ -100,22 +100,13 @@ RSpec.describe "Resolving" do
end
it "raises an exception if a child dependency is not resolved" do
- @index = a_unresolvable_child_index
+ @index = a_unresovable_child_index
dep "chef_app_error"
expect do
resolve
end.to raise_error(Bundler::SolveFailure)
end
- it "does not try to re-resolve including prereleases if gems involved don't have prereleases" do
- @index = a_unresolvable_child_index
- dep "chef_app_error"
- expect(Bundler.ui).not_to receive(:debug).with("Retrying resolution...", any_args)
- expect do
- resolve
- end.to raise_error(Bundler::SolveFailure)
- end
-
it "raises an exception with the minimal set of conflicting dependencies" do
@index = build_index do
%w[0.9 1.0 2.0].each {|v| gem("a", v) }
@@ -356,27 +347,4 @@ RSpec.describe "Resolving" do
should_resolve_as %w[rack-3.0.0 standalone_migrations-1.0.13]
end
-
- it "does not ignore versions that incorrectly depend on themselves when dependency_api is not available" do
- @index = build_index do
- gem "rack", "3.0.0"
-
- gem "standalone_migrations", "7.1.0" do
- dep "rack", "~> 2.0"
- end
-
- gem "standalone_migrations", "2.0.4" do
- dep "standalone_migrations", ">= 2.0.5"
- end
-
- gem "standalone_migrations", "1.0.13" do
- dep "rack", ">= 0"
- end
- end
-
- dep "rack", "~> 3.0"
- dep "standalone_migrations"
-
- should_resolve_without_dependency_api %w[rack-3.0.0 standalone_migrations-2.0.4]
- end
end
diff --git a/spec/bundler/resolver/platform_spec.rb b/spec/bundler/resolver/platform_spec.rb
index 3e959aeb89..a710dfcb28 100644
--- a/spec/bundler/resolver/platform_spec.rb
+++ b/spec/bundler/resolver/platform_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe "Resolving platform craziness" do
should_resolve_as %w[foo-1.0.0-x64-mingw32]
end
- describe "on a linux platform" do
+ describe "on a linux platform", :rubygems => ">= 3.1.0.pre.1" do
# Ruby's platform is *-linux => platform's libc is glibc, so not musl
# Ruby's platform is *-linux-musl => platform's libc is musl, so not glibc
# Gem's platform is *-linux => gem is glibc + maybe musl compatible
diff --git a/spec/bundler/runtime/executable_spec.rb b/spec/bundler/runtime/executable_spec.rb
index 36ce6dcf67..a11f547648 100644
--- a/spec/bundler/runtime/executable_spec.rb
+++ b/spec/bundler/runtime/executable_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe "Running bin/* commands" do
it "runs the bundled command when in the bundle" do
bundle "binstubs rack"
- build_gem "rack", "2.0", to_system: true do |s|
+ build_gem "rack", "2.0", :to_system => true do |s|
s.executables = "rackup"
end
@@ -20,7 +20,7 @@ RSpec.describe "Running bin/* commands" do
end
it "allows the location of the gem stubs to be specified" do
- bundle "binstubs rack", path: "gbin"
+ bundle "binstubs rack", :path => "gbin"
expect(bundled_app("bin")).not_to exist
expect(bundled_app("gbin/rackup")).to exist
@@ -30,7 +30,7 @@ RSpec.describe "Running bin/* commands" do
end
it "allows absolute paths as a specification of where to install bin stubs" do
- bundle "binstubs rack", path: tmp("bin")
+ bundle "binstubs rack", :path => tmp("bin")
gembin tmp("bin/rackup")
expect(out).to eq("1.0.0")
@@ -42,23 +42,23 @@ RSpec.describe "Running bin/* commands" do
end
it "allows the name of the shebang executable to be specified" do
- bundle "binstubs rack", shebang: "ruby-foo"
+ bundle "binstubs rack", :shebang => "ruby-foo"
expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env ruby-foo\n")
end
it "runs the bundled command when out of the bundle" do
bundle "binstubs rack"
- build_gem "rack", "2.0", to_system: true do |s|
+ build_gem "rack", "2.0", :to_system => true do |s|
s.executables = "rackup"
end
- gembin "rackup", dir: tmp
+ gembin "rackup", :dir => tmp
expect(out).to eq("1.0.0")
end
it "works with gems in path" do
- build_lib "rack", path: lib_path("rack") do |s|
+ build_lib "rack", :path => lib_path("rack") do |s|
s.executables = "rackup"
end
@@ -69,7 +69,7 @@ RSpec.describe "Running bin/* commands" do
bundle "binstubs rack"
- build_gem "rack", "2.0", to_system: true do |s|
+ build_gem "rack", "2.0", :to_system => true do |s|
s.executables = "rackup"
end
@@ -94,7 +94,7 @@ RSpec.describe "Running bin/* commands" do
expect(bundled_app("bin/rackup")).not_to exist
end
- it "allows you to stop installing binstubs", bundler: "< 3" do
+ it "allows you to stop installing binstubs", :bundler => "< 3" do
skip "delete permission error" if Gem.win_platform?
bundle "install --binstubs bin/"
@@ -107,13 +107,13 @@ RSpec.describe "Running bin/* commands" do
expect(out).to include("You have not configured a value for `bin`")
end
- it "remembers that the option was specified", bundler: "< 3" do
+ it "remembers that the option was specified", :bundler => "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "activesupport"
G
- bundle :install, binstubs: "bin"
+ bundle :install, :binstubs => "bin"
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
diff --git a/spec/bundler/runtime/gem_tasks_spec.rb b/spec/bundler/runtime/gem_tasks_spec.rb
index f7afc0eb92..b89fdf2cb1 100644
--- a/spec/bundler/runtime/gem_tasks_spec.rb
+++ b/spec/bundler/runtime/gem_tasks_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do
it "includes the relevant tasks" do
with_gem_path_as(base_system_gem_path.to_s) do
- sys_exec "#{rake} -T", env: { "GEM_HOME" => system_gem_path.to_s }
+ sys_exec "#{rake} -T", :env => { "GEM_HOME" => system_gem_path.to_s }
end
expect(err).to be_empty
@@ -45,7 +45,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do
it "defines a working `rake install` task", :ruby_repo do
with_gem_path_as(base_system_gem_path.to_s) do
- sys_exec "#{rake} install", env: { "GEM_HOME" => system_gem_path.to_s }
+ sys_exec "#{rake} install", :env => { "GEM_HOME" => system_gem_path.to_s }
end
expect(err).to be_empty
@@ -59,7 +59,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do
before do
spaced_bundled_app = tmp.join("bundled app")
FileUtils.cp_r bundled_app, spaced_bundled_app
- bundle "exec rake build", dir: spaced_bundled_app
+ bundle "exec rake build", :dir => spaced_bundled_app
end
it "still runs successfully" do
@@ -71,7 +71,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do
before do
bracketed_bundled_app = tmp.join("bundled[app")
FileUtils.cp_r bundled_app, bracketed_bundled_app
- bundle "exec rake build", dir: bracketed_bundled_app
+ bundle "exec rake build", :dir => bracketed_bundled_app
end
it "still runs successfully" do
@@ -99,7 +99,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do
it "adds 'pkg' to rake/clean's CLOBBER" do
with_gem_path_as(base_system_gem_path.to_s) do
- sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), env: { "GEM_HOME" => system_gem_path.to_s }
+ sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), :env => { "GEM_HOME" => system_gem_path.to_s }
end
expect(out).to eq '["pkg"]'
end
diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb
index 50a5258dc7..29ef036828 100644
--- a/spec/bundler/runtime/inline_spec.rb
+++ b/spec/bundler/runtime/inline_spec.rb
@@ -2,7 +2,7 @@
RSpec.describe "bundler/inline#gemfile" do
def script(code, options = {})
- requires = ["bundler/inline"]
+ requires = ["#{entrypoint}/inline"]
requires.unshift "#{spec_dir}/support/artifice/" + options.delete(:artifice) if options.key?(:artifice)
requires = requires.map {|r| "require '#{r}'" }.join("\n")
ruby("#{requires}\n\n" + code, options)
@@ -28,7 +28,7 @@ RSpec.describe "bundler/inline#gemfile" do
s.write "lib/four.rb", "puts 'four'"
end
- build_lib "five", "1.0.0", no_default: true do |s|
+ build_lib "five", "1.0.0", :no_default => true do |s|
s.write "lib/mofive.rb", "puts 'five'"
end
@@ -57,7 +57,7 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to eq("two")
- script <<-RUBY, raise_on_error: false
+ script <<-RUBY, :raise_on_error => false
gemfile do
source "#{file_uri_for(gem_repo1)}"
path "#{lib_path}" do
@@ -80,7 +80,7 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to include("Rack's post install message")
- script <<-RUBY, artifice: "endpoint"
+ script <<-RUBY, :artifice => "endpoint"
gemfile(true) do
source "https://notaserver.com"
gem "activesupport", :require => true
@@ -89,13 +89,13 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to include("Installing activesupport")
err_lines = err.split("\n")
- err_lines.reject! {|line| line =~ /\.rb:\d+: warning: / }
+ err_lines.reject! {|line| line =~ /\.rb:\d+: warning: / } unless RUBY_VERSION < "2.7"
expect(err_lines).to be_empty
end
it "lets me use my own ui object" do
- script <<-RUBY, artifice: "endpoint"
- require 'bundler'
+ script <<-RUBY, :artifice => "endpoint"
+ require '#{entrypoint}'
class MyBundlerUI < Bundler::UI::Shell
def confirm(msg, newline = nil)
puts "CONFIRMED!"
@@ -113,8 +113,8 @@ RSpec.describe "bundler/inline#gemfile" do
end
it "has an option for quiet installation" do
- script <<-RUBY, artifice: "endpoint"
- require 'bundler/inline'
+ script <<-RUBY, :artifice => "endpoint"
+ require '#{entrypoint}/inline'
gemfile(true, :quiet => true) do
source "https://notaserver.com"
@@ -126,7 +126,7 @@ RSpec.describe "bundler/inline#gemfile" do
end
it "raises an exception if passed unknown arguments" do
- script <<-RUBY, raise_on_error: false
+ script <<-RUBY, :raise_on_error => false
gemfile(true, :arglebargle => true) do
path "#{lib_path}"
gem "two"
@@ -140,7 +140,7 @@ RSpec.describe "bundler/inline#gemfile" do
it "does not mutate the option argument" do
script <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
options = { :ui => Bundler::UI::Shell.new }
gemfile(false, options) do
source "#{file_uri_for(gem_repo1)}"
@@ -259,7 +259,7 @@ RSpec.describe "bundler/inline#gemfile" do
system_gems "rack-1.0.0"
script <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
ui = Bundler::UI::Shell.new
ui.level = "confirm"
@@ -279,7 +279,7 @@ RSpec.describe "bundler/inline#gemfile" do
system_gems "rack-1.0.0"
script <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
ui = Bundler::UI::Shell.new
ui.level = "confirm"
gemfile(true, ui: ui) do
@@ -302,7 +302,7 @@ RSpec.describe "bundler/inline#gemfile" do
system_gems "rack-1.0.0"
script <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
ui = Bundler::UI::Shell.new
ui.level = "confirm"
gemfile(true, ui: ui) do
@@ -339,7 +339,7 @@ RSpec.describe "bundler/inline#gemfile" do
end
script <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
ui = Bundler::UI::Shell.new
ui.level = "confirm"
gemfile(true, ui: ui) do
@@ -421,17 +421,17 @@ RSpec.describe "bundler/inline#gemfile" do
script <<-RUBY
gemfile(true) do
source "#{file_uri_for(gem_repo1)}"
- gem "rake", "#{rake_version}"
+ gem "rake", "~> 13.0"
end
RUBY
- expect(out).to include("Installing rake #{rake_version}")
+ expect(out).to include("Installing rake 13.0")
expect(out).not_to include("was 11.3.0")
expect(err).to be_empty
end
it "installs inline gems when frozen is set" do
- script <<-RUBY, env: { "BUNDLE_FROZEN" => "true" }
+ script <<-RUBY, :env => { "BUNDLE_FROZEN" => "true" }
gemfile do
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -444,7 +444,7 @@ RSpec.describe "bundler/inline#gemfile" do
end
it "installs inline gems when deployment is set" do
- script <<-RUBY, env: { "BUNDLE_DEPLOYMENT" => "true" }
+ script <<-RUBY, :env => { "BUNDLE_DEPLOYMENT" => "true" }
gemfile do
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -488,7 +488,7 @@ RSpec.describe "bundler/inline#gemfile" do
context "when BUNDLE_PATH is set" do
it "installs inline gems to the system path regardless" do
- script <<-RUBY, env: { "BUNDLE_PATH" => "./vendor/inline" }
+ script <<-RUBY, :env => { "BUNDLE_PATH" => "./vendor/inline" }
gemfile(true) do
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -576,7 +576,7 @@ RSpec.describe "bundler/inline#gemfile" do
s.write "lib/foo.rb", foo_code
end
- script <<-RUBY, dir: tmp("path_without_gemfile")
+ script <<-RUBY, :dir => tmp("path_without_gemfile")
gemfile do
source "#{file_uri_for(gem_repo2)}"
path "#{lib_path}" do
@@ -592,16 +592,26 @@ RSpec.describe "bundler/inline#gemfile" do
end
it "when requiring fileutils after does not show redefinition warnings", :realworld do
+ dependency_installer_loads_fileutils = ruby "require 'rubygems/dependency_installer'; puts $LOADED_FEATURES.grep(/fileutils/)", :raise_on_error => false
+ skip "does not work if rubygems/dependency_installer loads fileutils, which happens until rubygems 3.2.0" unless dependency_installer_loads_fileutils.empty?
+
+ skip "pathname does not install cleanly on this ruby" if RUBY_VERSION < "2.7.0"
+
Dir.mkdir tmp("path_without_gemfile")
- default_fileutils_version = ruby "gem 'fileutils', '< 999999'; require 'fileutils'; puts FileUtils::VERSION", raise_on_error: false
+ default_fileutils_version = ruby "gem 'fileutils', '< 999999'; require 'fileutils'; puts FileUtils::VERSION", :raise_on_error => false
skip "fileutils isn't a default gem" if default_fileutils_version.empty?
realworld_system_gems "fileutils --version 1.4.1"
realworld_system_gems "pathname --version 0.2.0"
- script <<-RUBY, dir: tmp("path_without_gemfile"), env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+ realworld_system_gems "timeout uri" # this spec uses net/http which requires these default gems
+
+ # on prerelease rubies, a required_rubygems_version constraint is added by RubyGems to the resolution, causing Molinillo to load the `set` gem
+ realworld_system_gems "set --version 1.0.3" if Gem.ruby_version.prerelease?
+
+ script <<-RUBY, :dir => tmp("path_without_gemfile"), :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
require "bundler/inline"
gemfile(true) do
@@ -613,47 +623,4 @@ RSpec.describe "bundler/inline#gemfile" do
expect(err).to eq("The Gemfile specifies no dependencies")
end
-
- it "does not load default timeout" do
- default_timeout_version = ruby "gem 'timeout', '< 999999'; require 'timeout'; puts Timeout::VERSION", raise_on_error: false
- skip "timeout isn't a default gem" if default_timeout_version.empty?
-
- # This only works on RubyGems 3.5.0 or higher
- ruby "require 'rubygems/timeout'", raise_on_error: false
- skip "rubygems under test does not yet vendor timeout" unless last_command.success?
-
- build_repo4 do
- build_gem "timeout", "999"
- end
-
- script <<-RUBY
- require "bundler/inline"
-
- gemfile(true) do
- source "#{file_uri_for(gem_repo4)}"
-
- gem "timeout"
- end
- RUBY
-
- expect(out).to include("Installing timeout 999")
- end
-
- it "does not upcase ENV" do
- script <<-RUBY
- require 'bundler/inline'
-
- ENV['Test_Variable'] = 'value string'
- puts("before: \#{ENV.each_key.select { |key| key.match?(/test_variable/i) }}")
-
- gemfile do
- source "#{file_uri_for(gem_repo1)}"
- end
-
- puts("after: \#{ENV.each_key.select { |key| key.match?(/test_variable/i) }}")
- RUBY
-
- expect(out).to include("before: [\"Test_Variable\"]")
- expect(out).to include("after: [\"Test_Variable\"]")
- end
end
diff --git a/spec/bundler/runtime/load_spec.rb b/spec/bundler/runtime/load_spec.rb
index f28ffd9460..96a22a46cc 100644
--- a/spec/bundler/runtime/load_spec.rb
+++ b/spec/bundler/runtime/load_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe "Bundler.load" do
G
ruby <<-RUBY
- require "bundler"
+ require "#{entrypoint}"
Bundler.setup :default
Bundler.require :default
puts RACK
diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb
index 1925e9bf2e..a9933f90e9 100644
--- a/spec/bundler/runtime/platform_spec.rb
+++ b/spec/bundler/runtime/platform_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
ruby <<-R
begin
- require 'bundler'
+ require '#{entrypoint}'
Bundler.ui.silence { Bundler.setup }
rescue Bundler::GemNotFound => e
puts "WIN"
@@ -61,23 +61,16 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
build_repo4 do
build_gem "nokogiri", "1.11.1" do |s|
s.add_dependency "mini_portile2", "~> 2.5.0"
- s.add_dependency "racca", "~> 1.5.2"
+ s.add_dependency "racc", "~> 1.5.2"
end
build_gem "nokogiri", "1.11.1" do |s|
s.platform = Bundler.local_platform
- s.add_dependency "racca", "~> 1.4"
+ s.add_dependency "racc", "~> 1.4"
end
build_gem "mini_portile2", "2.5.0"
- build_gem "racca", "1.5.2"
- end
-
- checksums = checksums_section do |c|
- c.checksum gem_repo4, "mini_portile2", "2.5.0"
- c.checksum gem_repo4, "nokogiri", "1.11.1"
- c.checksum gem_repo4, "nokogiri", "1.11.1", Bundler.local_platform
- c.checksum gem_repo4, "racca", "1.5.2"
+ build_gem "racc", "1.5.2"
end
good_lockfile = <<~L
@@ -87,17 +80,17 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
mini_portile2 (2.5.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
- racca (~> 1.5.2)
+ racc (~> 1.5.2)
nokogiri (1.11.1-#{Bundler.local_platform})
- racca (~> 1.4)
- racca (1.5.2)
+ racc (~> 1.4)
+ racc (1.5.2)
PLATFORMS
#{lockfile_platforms("ruby")}
DEPENDENCIES
nokogiri (~> 1.11)
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -145,7 +138,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
#{Bundler::VERSION}
L
- bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "install", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(out).to include("Fetching nokogiri 1.11.1")
expect(the_bundle).to include_gems "nokogiri 1.11.1"
@@ -359,7 +352,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
end
simulate_platform "aarch64-linux-musl" do
- install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, verbose: true
+ install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, :verbose => true
source "https://gems.repo4"
gem "nokogiri"
G
@@ -372,7 +365,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
simulate_windows do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
- gem "nokogiri", :platforms => [:windows, :mswin, :mswin64, :mingw, :x64_mingw, :jruby]
+ gem "nokogiri", :platforms => [:mingw, :mswin, :x64_mingw, :jruby]
gem "platform_specific"
G
@@ -386,7 +379,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
end
it "allows specifying only-ruby-platform on windows with gemspec dependency" do
- build_lib("foo", "1.0", path: bundled_app) do |s|
+ build_lib("foo", "1.0", :path => bundled_app) do |s|
s.add_dependency "rack"
end
@@ -427,7 +420,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
requires_platform_specific
L
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo2)}"
gem "requires_platform_specific"
G
diff --git a/spec/bundler/runtime/require_spec.rb b/spec/bundler/runtime/require_spec.rb
index e630e902c9..e59fa564f6 100644
--- a/spec/bundler/runtime/require_spec.rb
+++ b/spec/bundler/runtime/require_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe "Bundler.require" do
s.write "lib/four.rb", "puts 'four'"
end
- build_lib "five", "1.0.0", no_default: true do |s|
+ build_lib "five", "1.0.0", :no_default => true do |s|
s.write "lib/mofive.rb", "puts 'five'"
end
@@ -138,7 +138,7 @@ RSpec.describe "Bundler.require" do
end
G
- run "Bundler.require", raise_on_error: false
+ run "Bundler.require", :raise_on_error => false
expect(err).to match("error while trying to load the gem 'faulty'")
expect(err).to match("Gem Internal Error Message")
end
@@ -187,7 +187,7 @@ RSpec.describe "Bundler.require" do
end
it "silently passes if the require fails" do
- build_lib "bcrypt-ruby", "1.0.0", no_default: true do |s|
+ build_lib "bcrypt-ruby", "1.0.0", :no_default => true do |s|
s.write "lib/brcrypt.rb", "BCrypt = '1.0.0'"
end
gemfile <<-G
@@ -199,7 +199,7 @@ RSpec.describe "Bundler.require" do
G
cmd = <<-RUBY
- require 'bundler'
+ require '#{entrypoint}'
Bundler.require
RUBY
ruby(cmd)
@@ -323,7 +323,7 @@ RSpec.describe "Bundler.require" do
describe "a gem with different requires for different envs" do
before(:each) do
- build_gem "multi_gem", to_bundle: true do |s|
+ build_gem "multi_gem", :to_bundle => true do |s|
s.write "lib/one.rb", "puts 'ONE'"
s.write "lib/two.rb", "puts 'TWO'"
end
@@ -366,7 +366,7 @@ RSpec.describe "Bundler.require" do
describe "with busted gems" do
it "should be busted" do
- build_gem "busted_require", to_bundle: true do |s|
+ build_gem "busted_require", :to_bundle => true do |s|
s.write "lib/busted_require.rb", "require 'no_such_file_omg'"
end
@@ -430,30 +430,6 @@ RSpec.describe "Bundler.require" do
expect(out).to eq("WIN")
end
-
- it "does not extract gemspecs from application cache packages" do
- gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "rack"
- G
-
- bundle :cache
-
- path = cached_gem("rack-1.0.0")
-
- run <<-R
- File.open("#{path}", "w") do |f|
- f.write "broken package"
- end
- R
-
- run <<-R
- Bundler.require
- puts "WIN"
- R
-
- expect(out).to eq("WIN")
- end
end
RSpec.describe "Bundler.require with platform specific dependencies" do
diff --git a/spec/bundler/runtime/requiring_spec.rb b/spec/bundler/runtime/requiring_spec.rb
deleted file mode 100644
index 1f32269622..0000000000
--- a/spec/bundler/runtime/requiring_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe "Requiring bundler" do
- it "takes care of requiring rubygems when entrypoint is bundler/setup" do
- sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", env: { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
-
- expect(last_command.stdboth).to eq("true")
- end
-
- it "takes care of requiring rubygems when requiring just bundler" do
- sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler -e'puts true'", env: { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
-
- expect(last_command.stdboth).to eq("true")
- end
-end
diff --git a/spec/bundler/runtime/self_management_spec.rb b/spec/bundler/runtime/self_management_spec.rb
index d15ca3189e..61cfc9b795 100644
--- a/spec/bundler/runtime/self_management_spec.rb
+++ b/spec/bundler/runtime/self_management_spec.rb
@@ -1,15 +1,11 @@
# frozen_string_literal: true
-RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do
+RSpec.describe "Self management", :rubygems => ">= 3.3.0.dev", :realworld => true do
describe "auto switching" do
let(:previous_minor) do
"2.3.0"
end
- let(:current_version) do
- "2.4.0"
- end
-
before do
build_repo2
@@ -24,19 +20,19 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do
lockfile_bundled_with(previous_minor)
bundle "config set --local path.system true"
- bundle "install", artifice: "vcr"
+ bundle "install", :artifice => "vcr"
expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
# It uninstalls the older system bundler
- bundle "clean --force", artifice: nil
+ bundle "clean --force"
expect(out).to eq("Removing bundler (#{Bundler::VERSION})")
# App now uses locked version
- bundle "-v", artifice: nil
+ bundle "-v"
expect(out).to end_with(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor)
# Subsequent installs use the locked version without reinstalling
- bundle "install --verbose", artifice: nil
+ bundle "install --verbose"
expect(out).to include("Using bundler #{previous_minor}")
expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
end
@@ -45,7 +41,7 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do
lockfile_bundled_with(previous_minor)
bundle "config set --local path vendor/bundle"
- bundle "install", artifice: "vcr"
+ bundle "install", :artifice => "vcr"
expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
expect(vendored_gems("gems/bundler-#{previous_minor}")).to exist
@@ -67,7 +63,7 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do
lockfile_bundled_with(previous_minor)
bundle "config set --local deployment true"
- bundle "install", artifice: "vcr"
+ bundle "install", :artifice => "vcr"
expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
expect(vendored_gems("gems/bundler-#{previous_minor}")).to exist
@@ -96,46 +92,17 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do
end
it "shows a discrete message if locked bundler does not exist" do
- missing_minor = "#{Bundler::VERSION[0]}.999.999"
+ missing_minor ="#{Bundler::VERSION[0]}.999.999"
lockfile_bundled_with(missing_minor)
- bundle "install", artifice: "vcr"
+ bundle "install", :artifice => "vcr"
expect(err).to eq("Your lockfile is locked to a version of bundler (#{missing_minor}) that doesn't exist at https://rubygems.org/. Going on using #{Bundler::VERSION}")
bundle "-v"
expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION)
end
- it "installs BUNDLE_VERSION version when using bundle config version x.y.z" do
- lockfile_bundled_with(current_version)
-
- bundle "config set --local version #{previous_minor}"
- bundle "install", artifice: "vcr"
- expect(out).to include("Bundler #{Bundler::VERSION} is running, but your configuration was #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
-
- bundle "-v"
- expect(out).to eq(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor)
- end
-
- it "does not try to install when using bundle config version global" do
- lockfile_bundled_with(previous_minor)
-
- bundle "config set version system"
- bundle "install", artifice: "vcr"
- expect(out).not_to match(/restarting using that version/)
-
- bundle "-v"
- expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION)
- end
-
- it "ignores malformed lockfile version" do
- lockfile_bundled_with("2.3.")
-
- bundle "install --verbose"
- expect(out).to include("Using bundler #{Bundler::VERSION}")
- end
-
private
def lockfile_bundled_with(version)
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index 8b8988063c..2d39d72937 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe "Bundler.setup" do
end
it "handles multiple non-additive invocations" do
- ruby <<-RUBY, raise_on_error: false
+ ruby <<-RUBY, :raise_on_error => false
require 'bundler'
Bundler.setup(:default, :test)
Bundler.setup(:default)
@@ -144,7 +144,6 @@ RSpec.describe "Bundler.setup" do
ruby <<-RUBY
require 'bundler'
- gem "bundler", "#{Bundler::VERSION}" if #{ruby_core?}
Bundler.setup
puts $LOAD_PATH
RUBY
@@ -158,7 +157,7 @@ RSpec.describe "Bundler.setup" do
"/gems/actionpack-2.3.2/lib",
"/gems/actionmailer-2.3.2/lib",
"/gems/activesupport-2.3.2/lib",
- "/gems/rake-#{rake_version}/lib"
+ "/gems/rake-13.0.1/lib"
)
end
@@ -194,7 +193,7 @@ RSpec.describe "Bundler.setup" do
G
ruby <<-R
- require 'bundler'
+ require '#{entrypoint}'
begin
Bundler.setup
@@ -213,7 +212,7 @@ RSpec.describe "Bundler.setup" do
gem "rack"
G
- ruby <<-R, raise_on_error: false
+ ruby <<-R, :raise_on_error => false
require 'bundler'
Bundler.setup
@@ -236,7 +235,7 @@ RSpec.describe "Bundler.setup" do
gem "nosuchgem", "10.0"
G
- ruby <<-R, raise_on_error: false
+ ruby <<-R, :raise_on_error => false
require 'bundler'
Bundler.setup
@@ -312,7 +311,7 @@ RSpec.describe "Bundler.setup" do
gem "rack", "1.0.0"
G
- build_gem "rack", "1.0", to_system: true do |s|
+ build_gem "rack", "1.0", :to_system => true do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
@@ -372,7 +371,7 @@ RSpec.describe "Bundler.setup" do
context "when the ruby stdlib is a substring of Gem.path" do
it "does not reject the stdlib from $LOAD_PATH" do
substring = "/" + $LOAD_PATH.find {|p| p.include?("vendor_ruby") }.split("/")[2]
- run "puts 'worked!'", env: { "GEM_PATH" => substring }
+ run "puts 'worked!'", :env => { "GEM_PATH" => substring }
expect(out).to eq("worked!")
end
end
@@ -410,8 +409,8 @@ RSpec.describe "Bundler.setup" do
end
it "provides a useful exception when the git repo is not checked out yet" do
- run "1", raise_on_error: false
- expect(err).to match(/the git source #{lib_path("rack-1.0.0")} is not yet checked out. Please run `bundle install`/i)
+ run "1", :raise_on_error => false
+ expect(err).to match(/the git source #{lib_path('rack-1.0.0')} is not yet checked out. Please run `bundle install`/i)
end
it "does not hit the git binary if the lockfile is available and up to date" do
@@ -441,7 +440,7 @@ RSpec.describe "Bundler.setup" do
break_git!
ruby <<-R
- require "bundler"
+ require "#{entrypoint}"
begin
Bundler.setup
@@ -451,7 +450,7 @@ RSpec.describe "Bundler.setup" do
end
R
- run "puts 'FAIL'", raise_on_error: false
+ run "puts 'FAIL'", :raise_on_error => false
expect(err).not_to include "This is not the git you are looking for"
end
@@ -497,8 +496,8 @@ RSpec.describe "Bundler.setup" do
bundle :install
FileUtils.rm_rf(lib_path("local-rack"))
- run "require 'rack'", raise_on_error: false
- expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path("local-rack").to_s)} does not exist/)
+ run "require 'rack'", :raise_on_error => false
+ expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
end
it "explodes if branch is not given on runtime" do
@@ -519,7 +518,7 @@ RSpec.describe "Bundler.setup" do
gem "rack", :git => "#{lib_path("rack-0.8")}"
G
- run "require 'rack'", raise_on_error: false
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/because :branch is not specified in Gemfile/)
end
@@ -541,7 +540,7 @@ RSpec.describe "Bundler.setup" do
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "changed"
G
- run "require 'rack'", raise_on_error: false
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/is using branch main but Gemfile specifies changed/)
end
@@ -561,7 +560,7 @@ RSpec.describe "Bundler.setup" do
G
bundle %(config set local.rack #{lib_path("local-rack")})
- run "require 'rack'", raise_on_error: false
+ run "require 'rack'", :raise_on_error => false
expect(err).to match(/is using branch main but Gemfile specifies nonexistent/)
end
end
@@ -580,7 +579,7 @@ RSpec.describe "Bundler.setup" do
system_gems "activesupport-2.3.5"
- expect(the_bundle).to include_gems "activesupport 2.3.2", groups: :default
+ expect(the_bundle).to include_gems "activesupport 2.3.2", :groups => :default
end
it "remembers --without and does not bail on bare Bundler.setup" do
@@ -603,7 +602,7 @@ RSpec.describe "Bundler.setup" do
bundle "config set --local without development"
path = bundled_app(File.join("vendor", "foo"))
- build_lib "foo", path: path
+ build_lib "foo", :path => path
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -613,7 +612,7 @@ RSpec.describe "Bundler.setup" do
FileUtils.rm_rf(path)
- ruby "require 'bundler'; Bundler.setup", env: { "DEBUG" => "1" }
+ ruby "require 'bundler'; Bundler.setup", :env => { "DEBUG" => "1" }
expect(out).to include("Assuming that source at `vendor/foo` has not changed since fetching its specs errored")
expect(out).to include("Found no changes, using resolution from the lockfile")
expect(err).to be_empty
@@ -633,7 +632,7 @@ RSpec.describe "Bundler.setup" do
gem "depends_on_bundler"
G
- ruby "require '#{system_gem_path("gems/bundler-9.99.9.beta1/lib/bundler.rb")}'; Bundler.setup", env: { "DEBUG" => "1" }
+ ruby "require '#{system_gem_path("gems/bundler-9.99.9.beta1/lib/bundler.rb")}'; Bundler.setup", :env => { "DEBUG" => "1" }
expect(out).to include("Found no changes, using resolution from the lockfile")
expect(out).not_to include("lockfile does not have all gems needed for the current platform")
expect(err).to be_empty
@@ -645,7 +644,7 @@ RSpec.describe "Bundler.setup" do
gem "bundler"
G
- bundle "install --verbose", env: { "BUNDLE_FROZEN" => "true" }
+ bundle "install --verbose", :env => { "BUNDLE_FROZEN" => "true" }
expect(err).to be_empty
end
@@ -656,7 +655,7 @@ RSpec.describe "Bundler.setup" do
gem "actionpack"
G
- install_gemfile <<-G, verbose: true
+ install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -680,15 +679,15 @@ RSpec.describe "Bundler.setup" do
end
G
- expect(the_bundle).not_to include_gems "activesupport 2.3.2", groups: :rack
- expect(the_bundle).to include_gems "rack 1.0.0", groups: :rack
+ expect(the_bundle).not_to include_gems "activesupport 2.3.2", :groups => :rack
+ expect(the_bundle).to include_gems "rack 1.0.0", :groups => :rack
end
end
# RubyGems returns loaded_from as a string
it "has loaded_from as a string on all specs" do
build_git "foo"
- build_git "no-gemspec", gemspec: false
+ build_git "no-gemspec", :gemspec => false
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -728,27 +727,6 @@ end
R
run <<-R
- File.open(File.join(Gem.dir, "specifications", "broken-ext.gemspec"), "w") do |f|
- f.write <<-RUBY
-# -*- encoding: utf-8 -*-
-# stub: broken-ext 1.0.0 ruby lib
-# stub: a.ext\\0b.ext
-
-Gem::Specification.new do |s|
- s.name = "broken-ext"
- s.version = "1.0.0"
- raise "BROKEN GEMSPEC EXT"
-end
- RUBY
- end
- # Need to write the gem.build_complete file,
- # otherwise the full spec is loaded to check the installed_by_version
- extensions_dir = Gem.default_ext_dir_for(Gem.dir) || File.join(Gem.dir, "extensions", Gem::Platform.local.to_s, Gem.extension_api_version)
- Bundler::FileUtils.mkdir_p(File.join(extensions_dir, "broken-ext-1.0.0"))
- File.open(File.join(extensions_dir, "broken-ext-1.0.0", "gem.build_complete"), "w") {}
- R
-
- run <<-R
puts "WIN"
R
@@ -767,18 +745,6 @@ end
expect(err).to be_empty
end
- it "can require rubygems without warnings, when using a local cache" do
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "rack"
- G
-
- bundle "package"
- bundle %(exec ruby -w -e "require 'rubygems'")
-
- expect(err).to be_empty
- end
-
context "when the user has `MANPATH` set", :man do
before { ENV["MANPATH"] = "/foo#{File::PATH_SEPARATOR}" }
@@ -919,7 +885,7 @@ end
it "should not remove itself from the LOAD_PATH and require a different copy of 'bundler/setup'" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
- ruby <<-R, env: { "GEM_PATH" => symlinked_gem_home }
+ ruby <<-R, :env => { "GEM_PATH" => symlinked_gem_home }
TracePoint.trace(:class) do |tp|
if tp.path.include?("bundler") && !tp.path.start_with?("#{source_root}")
puts "OMG. Defining a class from another bundler at \#{tp.path}:\#{tp.lineno}"
@@ -959,7 +925,7 @@ end
it "should resolve paths relative to the Gemfile" do
path = bundled_app(File.join("vendor", "foo"))
- build_lib "foo", path: path
+ build_lib "foo", :path => path
# If the .gemspec exists, then Bundler handles the path differently.
# See Source::Path.load_spec_files for details.
@@ -970,7 +936,7 @@ end
gem 'foo', '1.2.3', :path => 'vendor/foo'
G
- run <<-R, env: { "BUNDLE_GEMFILE" => bundled_app_gemfile.to_s }, dir: bundled_app.parent
+ run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app_gemfile.to_s }, :dir => bundled_app.parent
require 'foo'
R
expect(err).to be_empty
@@ -980,7 +946,7 @@ end
relative_path = File.join("vendor", Dir.pwd.gsub(/^#{filesystem_root}/, ""))
absolute_path = bundled_app(relative_path)
FileUtils.mkdir_p(absolute_path)
- build_lib "foo", path: absolute_path
+ build_lib "foo", :path => absolute_path
# If the .gemspec exists, then Bundler handles the path differently.
# See Source::Path.load_spec_files for details.
@@ -993,7 +959,7 @@ end
bundle :install
- run <<-R, env: { "BUNDLE_GEMFILE" => bundled_app_gemfile.to_s }, dir: bundled_app.parent
+ run <<-R, :env => { "BUNDLE_GEMFILE" => bundled_app_gemfile.to_s }, :dir => bundled_app.parent
require 'foo'
R
@@ -1003,7 +969,7 @@ end
describe "with git gems that don't have gemspecs" do
before :each do
- build_git "no_gemspec", gemspec: false
+ build_git "no_gemspec", :gemspec => false
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -1093,7 +1059,7 @@ end
describe "with a gemspec that requires other files" do
before :each do
- build_git "bar", gemspec: false do |s|
+ build_git "bar", :gemspec => false do |s|
s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0')
s.write "bar.gemspec", <<-G
require_relative 'lib/bar/version'
@@ -1123,10 +1089,10 @@ end
it "error intelligently if the gemspec has a LoadError" do
skip "whitespace issue?" if Gem.win_platform?
- ref = update_git "bar", gemspec: false do |s|
+ ref = update_git "bar", :gemspec => false do |s|
s.write "bar.gemspec", "require 'foobarbaz'"
end.ref_for("HEAD")
- bundle :install, raise_on_error: false
+ bundle :install, :raise_on_error => false
expect(err.lines.map(&:chomp)).to include(
a_string_starting_with("[!] There was an error while loading `bar.gemspec`:"),
@@ -1199,7 +1165,7 @@ end
context "is not present" do
it "does not change the lock" do
lockfile lock_with(nil)
- ruby "require 'bundler/setup'"
+ ruby "require '#{entrypoint}/setup'"
expect(lockfile).to eq lock_with(nil)
end
end
@@ -1218,7 +1184,7 @@ end
it "does not change the lock" do
system_gems "bundler-1.10.1"
lockfile lock_with("1.10.1")
- ruby "require 'bundler/setup'"
+ ruby "require '#{entrypoint}/setup'"
expect(lockfile).to eq lock_with("1.10.1")
end
end
@@ -1228,10 +1194,6 @@ end
let(:ruby_version) { nil }
def lock_with(ruby_version = nil)
- checksums = checksums_section do |c|
- c.checksum gem_repo1, "rack", "1.0.0"
- end
-
lock = <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -1243,7 +1205,6 @@ end
DEPENDENCIES
rack
- #{checksums}
L
if ruby_version
@@ -1293,7 +1254,9 @@ end
describe "with gemified standard libraries" do
it "does not load Digest", :ruby_repo do
- build_git "bar", gemspec: false do |s|
+ skip "Only for Ruby 3.0+" unless RUBY_VERSION >= "3.0"
+
+ build_git "bar", :gemspec => false do |s|
s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0')
s.write "bar.gemspec", <<-G
require_relative 'lib/bar/version'
@@ -1318,7 +1281,7 @@ end
bundle :install
ruby <<-RUBY
- require 'bundler/setup'
+ require '#{entrypoint}/setup'
puts defined?(::Digest) ? "Digest defined" : "Digest undefined"
require 'digest'
RUBY
@@ -1328,7 +1291,7 @@ end
it "does not load Psych" do
gemfile "source \"#{file_uri_for(gem_repo1)}\""
ruby <<-RUBY
- require 'bundler/setup'
+ require '#{entrypoint}/setup'
puts defined?(Psych::VERSION) ? Psych::VERSION : "undefined"
require 'psych'
puts Psych::VERSION
@@ -1349,37 +1312,11 @@ end
expect(out).to eq("undefined\nconstant")
end
- it "does not load uri while reading gemspecs", rubygems: ">= 3.6.0.dev" do
- Dir.mkdir bundled_app("test")
-
- create_file(bundled_app("test/test.gemspec"), <<-G)
- Gem::Specification.new do |s|
- s.name = "test"
- s.version = "1.0.0"
- s.summary = "test"
- s.authors = ['John Doe']
- s.homepage = 'https://example.com'
- end
- G
-
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "test", path: "#{bundled_app("test")}"
- G
-
- ruby <<-RUBY
- require "bundler/setup"
- puts defined?(URI) || "undefined"
- require "uri"
- puts defined?(URI) || "undefined"
- RUBY
- expect(out).to eq("undefined\nconstant")
- end
-
describe "default gem activation" do
let(:exemptions) do
- exempts = %w[did_you_mean bundler uri pathname]
- exempts << "etc" if Gem.ruby_version < Gem::Version.new("3.2") && Gem.win_platform?
+ exempts = %w[did_you_mean bundler]
+ exempts << "uri" if Gem.ruby_version >= Gem::Version.new("2.7")
+ exempts << "pathname" if Gem.ruby_version >= Gem::Version.new("3.0")
exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6")
exempts << "tsort" unless Gem.rubygems_version >= Gem::Version.new("3.2.31")
exempts << "error_highlight" # added in Ruby 3.1 as a default gem
@@ -1388,7 +1325,7 @@ end
exempts
end
- let(:activation_warning_hack) { <<~RUBY }
+ let(:activation_warning_hack) { strip_whitespace(<<-RUBY) }
require #{spec_dir.join("support/hax").to_s.dump}
Gem::Specification.send(:alias_method, :bundler_spec_activate, :activate)
@@ -1408,7 +1345,7 @@ end
"-r#{bundled_app("activation_warning_hack.rb")} #{ENV["RUBYOPT"]}"
end
- let(:code) { <<~RUBY }
+ let(:code) { strip_whitespace(<<-RUBY) }
require "pp"
loaded_specs = Gem.loaded_specs.dup
#{exemptions.inspect}.each {|s| loaded_specs.delete(s) }
@@ -1423,14 +1360,14 @@ end
it "activates no gems with -rbundler/setup" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
- ruby code, env: { "RUBYOPT" => activation_warning_hack_rubyopt + " -rbundler/setup" }
+ ruby code, :env => { "RUBYOPT" => activation_warning_hack_rubyopt + " -rbundler/setup" }
expect(out).to eq("{}")
end
it "activates no gems with bundle exec" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
create_file("script.rb", code)
- bundle "exec ruby ./script.rb", env: { "RUBYOPT" => activation_warning_hack_rubyopt }
+ bundle "exec ruby ./script.rb", :env => { "RUBYOPT" => activation_warning_hack_rubyopt }
expect(out).to eq("{}")
end
@@ -1440,7 +1377,7 @@ end
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
create_file("script.rb", "#!/usr/bin/env ruby\n\n#{code}")
FileUtils.chmod(0o777, bundled_app("script.rb"))
- bundle "exec ./script.rb", artifice: nil, env: { "RUBYOPT" => activation_warning_hack_rubyopt }
+ bundle "exec ./script.rb", :artifice => nil, :env => { "RUBYOPT" => activation_warning_hack_rubyopt }
expect(out).to eq("{}")
end
@@ -1449,7 +1386,7 @@ end
build_gem "net-http-pipeline", "1.0.1"
end
- system_gems "net-http-pipeline-1.0.1", gem_repo: gem_repo4
+ system_gems "net-http-pipeline-1.0.1", :gem_repo => gem_repo4
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
@@ -1478,7 +1415,7 @@ end
gem "#{g}", "999999"
G
- expect(the_bundle).to include_gem("#{g} 999999", env: { "RUBYOPT" => activation_warning_hack_rubyopt })
+ expect(the_bundle).to include_gem("#{g} 999999", :env => { "RUBYOPT" => activation_warning_hack_rubyopt })
end
it "activates older versions of #{g}", :ruby_repo do
@@ -1493,14 +1430,14 @@ end
gem "#{g}", "0.0.0.a"
G
- expect(the_bundle).to include_gem("#{g} 0.0.0.a", env: { "RUBYOPT" => activation_warning_hack_rubyopt })
+ expect(the_bundle).to include_gem("#{g} 0.0.0.a", :env => { "RUBYOPT" => activation_warning_hack_rubyopt })
end
end
end
end
describe "after setup" do
- it "allows calling #gem on random objects", bundler: "< 3" do
+ it "allows calling #gem on random objects", :bundler => "< 3" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -1515,13 +1452,13 @@ end
expect(out).to eq("rack-1.0.0")
end
- it "keeps Kernel#gem private", bundler: "3" do
+ it "keeps Kernel#gem private", :bundler => "3" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
- ruby <<-RUBY, raise_on_error: false
+ ruby <<-RUBY, :raise_on_error => false
require "bundler/setup"
Object.new.gem "rack"
puts "FAIL"
@@ -1537,14 +1474,20 @@ end
gem "rack"
G
- ruby <<-RUBY, raise_on_error: false
+ ruby <<-RUBY, :raise_on_error => false
require "bundler/setup"
Object.new.require "rack"
puts "FAIL"
RUBY
expect(last_command.stdboth).not_to include "FAIL"
- expect(err).to match(/private method [`']require'/)
+ expect(err).to include "private method `require'"
+ end
+
+ it "takes care of requiring rubygems" do
+ sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", :env => { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
+
+ expect(last_command.stdboth).to eq("true")
end
it "memoizes initial set of specs when requiring bundler/setup, so that even if further code mutates dependencies, Bundler.definition.specs is not affected" do
@@ -1554,7 +1497,7 @@ end
gem "rack", :group => :test
G
- ruby <<-RUBY, raise_on_error: false
+ ruby <<-RUBY, :raise_on_error => false
require "bundler/setup"
Bundler.require(:test).select! {|d| (d.groups & [:test]).any? }
puts Bundler.definition.specs.map(&:name).join(", ")
@@ -1574,7 +1517,7 @@ end
end
end
- system_gems "json-999.999.999", gem_repo: gem_repo2
+ system_gems "json-999.999.999", :gem_repo => gem_repo2
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
ruby <<-RUBY
@@ -1587,7 +1530,7 @@ end
end
end
- it "does not undo the Kernel.require decorations", rubygems: ">= 3.4.6" do
+ it "does not undo the Kernel.require decorations", :rubygems => ">= 3.4.6" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
script = bundled_app("bin/script")
create_file(script, <<~RUBY)
@@ -1608,22 +1551,7 @@ end
require "foo"
RUBY
- sys_exec "#{Gem.ruby} #{script}", raise_on_error: false
+ sys_exec "#{Gem.ruby} #{script}", :raise_on_error => false
expect(out).to include("requiring foo used the monkeypatch")
end
-
- it "performs an automatic bundle install" do
- gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "rack", :group => :test
- G
-
- bundle "config set auto_install 1"
-
- ruby <<-RUBY
- require 'bundler/setup'
- RUBY
- expect(err).to be_empty
- expect(out).to include("Installing rack 1.0.0")
- end
end
diff --git a/spec/bundler/runtime/with_unbundled_env_spec.rb b/spec/bundler/runtime/with_unbundled_env_spec.rb
index 135c71b0af..731a9921a2 100644
--- a/spec/bundler/runtime/with_unbundled_env_spec.rb
+++ b/spec/bundler/runtime/with_unbundled_env_spec.rb
@@ -90,7 +90,9 @@ RSpec.describe "Bundler.with_env helpers" do
RUBY
setup_require = "-r#{lib_dir}/bundler/setup"
ENV["BUNDLER_ORIG_RUBYOPT"] = "-W2 #{setup_require} #{ENV["RUBYOPT"]}"
- bundle_exec_ruby bundled_app("source.rb")
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ bundle_exec_ruby bundled_app("source.rb")
+ end
expect(last_command.stdboth).not_to include(setup_require)
end
@@ -99,7 +101,9 @@ RSpec.describe "Bundler.with_env helpers" do
print #{modified_env}['RUBYOPT']
RUBY
ENV["BUNDLER_ORIG_RUBYOPT"] = "-W2 -rbundler/setup #{ENV["RUBYOPT"]}"
- bundle_exec_ruby bundled_app("source.rb")
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ bundle_exec_ruby bundled_app("source.rb")
+ end
expect(last_command.stdboth).not_to include("-rbundler/setup")
end
@@ -130,7 +134,7 @@ RSpec.describe "Bundler.with_env helpers" do
it_behaves_like "an unbundling helper"
end
- describe "Bundler.clean_env", bundler: 2 do
+ describe "Bundler.clean_env", :bundler => 2 do
let(:modified_env) { "Bundler.clean_env" }
it_behaves_like "an unbundling helper"
@@ -139,7 +143,7 @@ RSpec.describe "Bundler.with_env helpers" do
describe "Bundler.with_original_env" do
it "should set ENV to original_env in the block" do
expected = Bundler.original_env
- actual = Bundler.with_original_env { ENV.to_hash }
+ actual = Bundler.with_original_env { Bundler::EnvironmentPreserver.env_to_hash(ENV) }
expect(actual).to eq(expected)
end
@@ -152,12 +156,12 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- describe "Bundler.with_clean_env", bundler: 2 do
+ describe "Bundler.with_clean_env", :bundler => 2 do
it "should set ENV to unbundled_env in the block" do
expected = Bundler.unbundled_env
actual = Bundler.ui.silence do
- Bundler.with_clean_env { ENV.to_hash }
+ Bundler.with_clean_env { Bundler::EnvironmentPreserver.env_to_hash(ENV) }
end
expect(actual).to eq(expected)
@@ -175,7 +179,7 @@ RSpec.describe "Bundler.with_env helpers" do
describe "Bundler.with_unbundled_env" do
it "should set ENV to unbundled_env in the block" do
expected = Bundler.unbundled_env
- actual = Bundler.with_unbundled_env { ENV.to_hash }
+ actual = Bundler.with_unbundled_env { Bundler::EnvironmentPreserver.env_to_hash(ENV) }
expect(actual).to eq(expected)
end
@@ -203,7 +207,7 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- describe "Bundler.clean_system", bundler: 2 do
+ describe "Bundler.clean_system", :bundler => 2 do
before do
create_file("source.rb", <<-'RUBY')
Bundler.ui.silence { Bundler.clean_system("ruby", "-e", "exit(42) unless ENV['BUNDLE_FOO'] == 'bar'") }
@@ -254,7 +258,7 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- describe "Bundler.clean_exec", bundler: 2 do
+ describe "Bundler.clean_exec", :bundler => 2 do
before do
create_file("source.rb", <<-'RUBY')
Process.fork do
diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb
index 66bdcfa028..6a7e2891a6 100644
--- a/spec/bundler/spec_helper.rb
+++ b/spec/bundler/spec_helper.rb
@@ -17,7 +17,6 @@ require "rspec/support/differ"
require_relative "support/builders"
require_relative "support/build_metadata"
-require_relative "support/checksums"
require_relative "support/filters"
require_relative "support/helpers"
require_relative "support/indexes"
@@ -35,7 +34,6 @@ end
RSpec.configure do |config|
config.include Spec::Builders
- config.include Spec::Checksums
config.include Spec::Helpers
config.include Spec::Indexes
config.include Spec::Matchers
@@ -48,9 +46,6 @@ RSpec.configure do |config|
config.silence_filter_announcements = !ENV["TEST_ENV_NUMBER"].nil?
- config.backtrace_exclusion_patterns <<
- %r{./spec/(spec_helper\.rb|support/.+)}
-
config.disable_monkey_patching!
# Since failures cause us to keep a bunch of long strings in memory, stop
@@ -77,6 +72,7 @@ RSpec.configure do |config|
require_relative "support/rubygems_ext"
Spec::Rubygems.test_setup
ENV["BUNDLER_SPEC_RUN"] = "true"
+ ENV["BUNDLER_NO_OLD_RUBYGEMS_WARNING"] = "true"
ENV["BUNDLE_USER_CONFIG"] = ENV["BUNDLE_USER_CACHE"] = ENV["BUNDLE_USER_PLUGIN"] = nil
ENV["BUNDLE_APP_CONFIG"] = nil
ENV["BUNDLE_SILENCE_ROOT_WARNING"] = nil
@@ -88,7 +84,7 @@ RSpec.configure do |config|
ENV["THOR_COLUMNS"] = "10000"
extend(Spec::Helpers)
- system_gems :bundler, path: pristine_system_gem_path
+ system_gems :bundler, :path => pristine_system_gem_path
end
config.before :all do
@@ -118,6 +114,6 @@ RSpec.configure do |config|
end
config.after :suite do
- FileUtils.rm_rf Spec::Path.pristine_system_gem_path
+ FileUtils.rm_r Spec::Path.pristine_system_gem_path
end
end
diff --git a/spec/bundler/support/activate.rb b/spec/bundler/support/activate.rb
deleted file mode 100644
index 143b77833d..0000000000
--- a/spec/bundler/support/activate.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-require "rubygems"
-Gem.instance_variable_set(:@ruby, ENV["RUBY"]) if ENV["RUBY"]
-
-require_relative "path"
-bundler_gemspec = Spec::Path.loaded_gemspec
-bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root.to_s)
-bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate)
diff --git a/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb b/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb
index 83b147d2ae..a6545b9ee4 100644
--- a/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb
+++ b/spec/bundler/support/artifice/compact_index_checksum_mismatch.rb
@@ -4,10 +4,10 @@ require_relative "helpers/compact_index"
class CompactIndexChecksumMismatch < CompactIndexAPI
get "/versions" do
- headers "Repr-Digest" => "sha-256=:ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=:"
+ headers "ETag" => quote("123")
headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
content_type "text/plain"
- body "content does not match the checksum"
+ body ""
end
end
diff --git a/spec/bundler/support/artifice/compact_index_concurrent_download.rb b/spec/bundler/support/artifice/compact_index_concurrent_download.rb
index 5d55b8a72b..35548f278c 100644
--- a/spec/bundler/support/artifice/compact_index_concurrent_download.rb
+++ b/spec/bundler/support/artifice/compact_index_concurrent_download.rb
@@ -7,12 +7,11 @@ class CompactIndexConcurrentDownload < CompactIndexAPI
versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
"localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions")
- # Verify the original content hasn't been deleted, e.g. on a retry
- data = File.binread(versions)
- data == "created_at" || raise("Original file should be present with expected content")
+ # Verify the original (empty) content hasn't been deleted, e.g. on a retry
+ File.binread(versions) == "" || raise("Original file should be present and empty")
# Verify this is only requested once for a partial download
- env["HTTP_RANGE"] == "bytes=#{data.bytesize - 1}-" || raise("Missing Range header for expected partial download")
+ env["HTTP_RANGE"] || raise("Missing Range header for expected partial download")
# Overwrite the file in parallel, which should be then overwritten
# after a successful download to prevent corruption
diff --git a/spec/bundler/support/artifice/compact_index_etag_match.rb b/spec/bundler/support/artifice/compact_index_etag_match.rb
deleted file mode 100644
index 08d7b5ec53..0000000000
--- a/spec/bundler/support/artifice/compact_index_etag_match.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "helpers/compact_index"
-
-class CompactIndexEtagMatch < CompactIndexAPI
- get "/versions" do
- raise "ETag header should be present" unless env["HTTP_IF_NONE_MATCH"]
- headers "ETag" => env["HTTP_IF_NONE_MATCH"]
- status 304
- body ""
- end
-end
-
-require_relative "helpers/artifice"
-
-Artifice.activate_with(CompactIndexEtagMatch)
diff --git a/spec/bundler/support/artifice/compact_index_host_redirect.rb b/spec/bundler/support/artifice/compact_index_host_redirect.rb
index 4f82bf3812..9a711186db 100644
--- a/spec/bundler/support/artifice/compact_index_host_redirect.rb
+++ b/spec/bundler/support/artifice/compact_index_host_redirect.rb
@@ -3,7 +3,7 @@
require_relative "helpers/compact_index"
class CompactIndexHostRedirect < CompactIndexAPI
- get "/fetch/actual/gem/:id", host_name: "localgemserver.test" do
+ get "/fetch/actual/gem/:id", :host_name => "localgemserver.test" do
redirect "http://bundler.localgemserver.test#{request.path_info}"
end
diff --git a/spec/bundler/support/artifice/compact_index_partial_update.rb b/spec/bundler/support/artifice/compact_index_partial_update.rb
index f111d91ef9..8c73011346 100644
--- a/spec/bundler/support/artifice/compact_index_partial_update.rb
+++ b/spec/bundler/support/artifice/compact_index_partial_update.rb
@@ -23,7 +23,7 @@ class CompactIndexPartialUpdate < CompactIndexAPI
# Verify that a partial request is made, starting from the index of the
# final byte of the cached file.
unless env["HTTP_RANGE"] == "bytes=#{File.binread(cached_versions_path).bytesize - 1}-"
- raise("Range header should be present, and start from the index of the final byte of the cache. #{env["HTTP_RANGE"].inspect}")
+ raise("Range header should be present, and start from the index of the final byte of the cache.")
end
etag_response do
diff --git a/spec/bundler/support/artifice/compact_index_partial_update_bad_digest.rb b/spec/bundler/support/artifice/compact_index_partial_update_bad_digest.rb
deleted file mode 100644
index ac04336636..0000000000
--- a/spec/bundler/support/artifice/compact_index_partial_update_bad_digest.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "helpers/compact_index"
-
-# The purpose of this Artifice is to test that an incremental response is invalidated
-# and a second request is issued for the full content.
-class CompactIndexPartialUpdateBadDigest < CompactIndexAPI
- def partial_update_bad_digest
- response_body = yield
- if request.env["HTTP_RANGE"]
- headers "Repr-Digest" => "sha-256=:#{Digest::SHA256.base64digest("wrong digest on ranged request")}:"
- else
- headers "Repr-Digest" => "sha-256=:#{Digest::SHA256.base64digest(response_body)}:"
- end
- headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
- content_type "text/plain"
- requested_range_for(response_body)
- end
-
- get "/versions" do
- partial_update_bad_digest do
- file = tmp("versions.list")
- FileUtils.rm_f(file)
- file = CompactIndex::VersionsFile.new(file.to_s)
- file.create(gems)
- file.contents([], calculate_info_checksums: true)
- end
- end
-
- get "/info/:name" do
- partial_update_bad_digest do
- gem = gems.find {|g| g.name == params[:name] }
- CompactIndex.info(gem ? gem.versions : [])
- end
- end
-end
-
-require_relative "helpers/artifice"
-
-Artifice.activate_with(CompactIndexPartialUpdateBadDigest)
diff --git a/spec/bundler/support/artifice/compact_index_partial_update_no_digest_not_incremental.rb b/spec/bundler/support/artifice/compact_index_partial_update_no_digest_not_incremental.rb
deleted file mode 100644
index 99bae039f0..0000000000
--- a/spec/bundler/support/artifice/compact_index_partial_update_no_digest_not_incremental.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "helpers/compact_index"
-
-# The purpose of this Artifice is to test that an incremental response is ignored
-# when the digest is not present to verify that the partial response is valid.
-class CompactIndexPartialUpdateNoDigestNotIncremental < CompactIndexAPI
- def partial_update_no_digest
- response_body = yield
- headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
- content_type "text/plain"
- requested_range_for(response_body)
- end
-
- get "/versions" do
- partial_update_no_digest do
- file = tmp("versions.list")
- FileUtils.rm_f(file)
- file = CompactIndex::VersionsFile.new(file.to_s)
- file.create(gems)
- lines = file.contents([], calculate_info_checksums: true).split("\n")
- name, versions, checksum = lines.last.split(" ")
-
- # shuffle versions so new versions are not appended to the end
- [*lines[0..-2], [name, versions.split(",").reverse.join(","), checksum].join(" ")].join("\n")
- end
- end
-
- get "/info/:name" do
- partial_update_no_digest do
- gem = gems.find {|g| g.name == params[:name] }
- lines = CompactIndex.info(gem ? gem.versions : []).split("\n")
-
- # shuffle versions so new versions are not appended to the end
- [lines.first, lines.last, *lines[1..-2]].join("\n")
- end
- end
-end
-
-require_relative "helpers/artifice"
-
-Artifice.activate_with(CompactIndexPartialUpdateNoDigestNotIncremental)
diff --git a/spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb b/spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb
new file mode 100644
index 0000000000..20546ba4c3
--- /dev/null
+++ b/spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require_relative "helpers/compact_index"
+
+class CompactIndexPartialUpdateNoEtagNotIncremental < CompactIndexAPI
+ def partial_update_no_etag
+ response_body = yield
+ headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
+ content_type "text/plain"
+ requested_range_for(response_body)
+ end
+
+ get "/versions" do
+ partial_update_no_etag do
+ file = tmp("versions.list")
+ FileUtils.rm_f(file)
+ file = CompactIndex::VersionsFile.new(file.to_s)
+ file.create(gems)
+ lines = file.contents([], :calculate_info_checksums => true).split("\n")
+ name, versions, checksum = lines.last.split(" ")
+
+ # shuffle versions so new versions are not appended to the end
+ [*lines[0..-2], [name, versions.split(",").reverse.join(","), checksum].join(" ")].join("\n")
+ end
+ end
+
+ get "/info/:name" do
+ partial_update_no_etag do
+ gem = gems.find {|g| g.name == params[:name] }
+ lines = CompactIndex.info(gem ? gem.versions : []).split("\n")
+
+ # shuffle versions so new versions are not appended to the end
+ [lines.first, lines.last, *lines[1..-2]].join("\n")
+ end
+ end
+end
+
+require_relative "helpers/artifice"
+
+Artifice.activate_with(CompactIndexPartialUpdateNoEtagNotIncremental)
diff --git a/spec/bundler/support/artifice/compact_index_range_ignored.rb b/spec/bundler/support/artifice/compact_index_range_ignored.rb
deleted file mode 100644
index 2303682c1f..0000000000
--- a/spec/bundler/support/artifice/compact_index_range_ignored.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "helpers/compact_index"
-
-class CompactIndexRangeIgnored < CompactIndexAPI
- # Stub the server to not return 304 so that we don't bypass all the logic
- def not_modified?(_checksum)
- false
- end
-
- get "/versions" do
- cached_versions_path = File.join(
- Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
- "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions"
- )
-
- # Verify a cached copy of the versions file exists
- unless File.binread(cached_versions_path).size > 0
- raise("Cached versions file should be present and have content")
- end
-
- # Verify that a partial request is made, starting from the index of the
- # final byte of the cached file.
- unless env.delete("HTTP_RANGE")
- raise("Expected client to write the full response on the first try")
- end
-
- etag_response do
- file = tmp("versions.list")
- FileUtils.rm_f(file)
- file = CompactIndex::VersionsFile.new(file.to_s)
- file.create(gems)
- file.contents
- end
- end
-end
-
-require_relative "helpers/artifice"
-
-Artifice.activate_with(CompactIndexRangeIgnored)
diff --git a/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb b/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb
index 9bd2ca0a9d..acc13a56ff 100644
--- a/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb
+++ b/spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb
@@ -7,8 +7,7 @@ class CompactIndexWrongGemChecksum < CompactIndexAPI
etag_response do
name = params[:name]
gem = gems.find {|g| g.name == name }
- # This generates the hexdigest "2222222222222222222222222222222222222222222222222222222222222222"
- checksum = ENV.fetch("BUNDLER_SPEC_#{name.upcase}_CHECKSUM") { "IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI=" }
+ checksum = ENV.fetch("BUNDLER_SPEC_#{name.upcase}_CHECKSUM") { "ab" * 22 }
versions = gem ? gem.versions : []
versions.each {|v| v.checksum = checksum }
CompactIndex.info(versions)
diff --git a/spec/bundler/support/artifice/endpoint_500.rb b/spec/bundler/support/artifice/endpoint_500.rb
index b1ed1964c8..d8ab6b65bc 100644
--- a/spec/bundler/support/artifice/endpoint_500.rb
+++ b/spec/bundler/support/artifice/endpoint_500.rb
@@ -2,7 +2,7 @@
require_relative "../path"
-$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{mustermann,rack,tilt,sinatra,ruby2_keywords,base64}-*/lib")].map(&:to_s))
+$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s))
require "sinatra/base"
diff --git a/spec/bundler/support/artifice/endpoint_host_redirect.rb b/spec/bundler/support/artifice/endpoint_host_redirect.rb
index 6ce51bed93..0efb6cda02 100644
--- a/spec/bundler/support/artifice/endpoint_host_redirect.rb
+++ b/spec/bundler/support/artifice/endpoint_host_redirect.rb
@@ -3,7 +3,7 @@
require_relative "helpers/endpoint"
class EndpointHostRedirect < Endpoint
- get "/fetch/actual/gem/:id", host_name: "localgemserver.test" do
+ get "/fetch/actual/gem/:id", :host_name => "localgemserver.test" do
redirect "http://bundler.localgemserver.test#{request.path_info}"
end
diff --git a/spec/bundler/support/artifice/endpoint_mirror_source.rb b/spec/bundler/support/artifice/endpoint_mirror_source.rb
index fed7a746b9..6ea1a77eca 100644
--- a/spec/bundler/support/artifice/endpoint_mirror_source.rb
+++ b/spec/bundler/support/artifice/endpoint_mirror_source.rb
@@ -4,7 +4,7 @@ require_relative "helpers/endpoint"
class EndpointMirrorSource < Endpoint
get "/gems/:id" do
- if request.env["HTTP_X_GEMFILE_SOURCE"] == "https://server.example.org/" && request.env["HTTP_USER_AGENT"].start_with?("bundler")
+ if request.env["HTTP_X_GEMFILE_SOURCE"] == "https://server.example.org/"
File.binread("#{gem_repo1}/gems/#{params[:id]}")
else
halt 500
diff --git a/spec/bundler/support/artifice/fail.rb b/spec/bundler/support/artifice/fail.rb
index 8822e5b8e2..6286e43fbd 100644
--- a/spec/bundler/support/artifice/fail.rb
+++ b/spec/bundler/support/artifice/fail.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require "bundler/vendored_net_http"
+require "net/http"
-class Fail < Gem::Net::HTTP
- # Gem::Net::HTTP uses a @newimpl instance variable to decide whether
+class Fail < Net::HTTP
+ # Net::HTTP uses a @newimpl instance variable to decide whether
# to use a legacy implementation. Since we are subclassing
- # Gem::Net::HTTP, we must set it
+ # Net::HTTP, we must set it
@newimpl = true
def request(req, body = nil, &block)
@@ -17,11 +17,13 @@ class Fail < Gem::Net::HTTP
end
def exception(req)
- Errno::ENETUNREACH.new("host down: Bundler spec artifice fail! #{req["PATH_INFO"]}")
+ name = ENV.fetch("BUNDLER_SPEC_EXCEPTION") { "Errno::ENETUNREACH" }
+ const = name.split("::").reduce(Object) {|mod, sym| mod.const_get(sym) }
+ const.new("host down: Bundler spec artifice fail! #{req["PATH_INFO"]}")
end
end
require_relative "helpers/artifice"
-# Replace Gem::Net::HTTP with our failing subclass
+# Replace Net::HTTP with our failing subclass
Artifice.replace_net_http(::Fail)
diff --git a/spec/bundler/support/artifice/helpers/artifice.rb b/spec/bundler/support/artifice/helpers/artifice.rb
index 788268295c..b8c78614fb 100644
--- a/spec/bundler/support/artifice/helpers/artifice.rb
+++ b/spec/bundler/support/artifice/helpers/artifice.rb
@@ -4,7 +4,7 @@
module Artifice
# Activate Artifice with a particular Rack endpoint.
#
- # Calling this method will replace the Gem::Net::HTTP system
+ # Calling this method will replace the Net::HTTP system
# with a replacement that routes all requests to the
# Rack endpoint.
#
@@ -18,11 +18,11 @@ module Artifice
# Deactivate the Artifice replacement.
def self.deactivate
- replace_net_http(::Gem::Net::HTTP)
+ replace_net_http(::Net::HTTP)
end
def self.replace_net_http(value)
- ::Gem::Net.class_eval do
+ ::Net.class_eval do
remove_const(:HTTP)
const_set(:HTTP, value)
end
diff --git a/spec/bundler/support/artifice/helpers/compact_index.rb b/spec/bundler/support/artifice/helpers/compact_index.rb
index a803a2d30a..4df47a9659 100644
--- a/spec/bundler/support/artifice/helpers/compact_index.rb
+++ b/spec/bundler/support/artifice/helpers/compact_index.rb
@@ -4,7 +4,6 @@ require_relative "endpoint"
$LOAD_PATH.unshift Dir[Spec::Path.base_system_gem_path.join("gems/compact_index*/lib")].first.to_s
require "compact_index"
-require "digest"
class CompactIndexAPI < Endpoint
helpers do
@@ -18,10 +17,9 @@ class CompactIndexAPI < Endpoint
def etag_response
response_body = yield
- etag = Digest::MD5.hexdigest(response_body)
- headers "ETag" => quote(etag)
- return if not_modified?(etag)
- headers "Repr-Digest" => "sha-256=:#{Digest::SHA256.base64digest(response_body)}:"
+ checksum = Digest(:MD5).hexdigest(response_body)
+ return if not_modified?(checksum)
+ headers "ETag" => quote(checksum)
headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60"
content_type "text/plain"
requested_range_for(response_body)
@@ -31,10 +29,11 @@ class CompactIndexAPI < Endpoint
raise
end
- def not_modified?(etag)
+ def not_modified?(checksum)
etags = parse_etags(request.env["HTTP_IF_NONE_MATCH"])
- return unless etags.include?(etag)
+ return unless etags.include?(checksum)
+ headers "ETag" => quote(checksum)
status 304
body ""
end
@@ -76,17 +75,15 @@ class CompactIndexAPI < Endpoint
specs.group_by(&:name).map do |name, versions|
gem_versions = versions.map do |spec|
- deps = spec.runtime_dependencies.map do |d|
+ deps = spec.dependencies.select {|d| d.type == :runtime }.map do |d|
reqs = d.requirement.requirements.map {|r| r.join(" ") }.join(", ")
CompactIndex::Dependency.new(d.name, reqs)
end
- begin
- checksum = ENV.fetch("BUNDLER_SPEC_#{name.upcase}_CHECKSUM") do
- Digest(:SHA256).file("#{gem_repo}/gems/#{spec.original_name}.gem").hexdigest
- end
- rescue StandardError
- checksum = nil
- end
+ checksum = begin
+ Digest(:SHA256).file("#{gem_repo}/gems/#{spec.original_name}.gem").base64digest
+ rescue StandardError
+ nil
+ end
CompactIndex::GemVersion.new(spec.version.version, spec.platform.to_s, checksum, nil,
deps, spec.required_ruby_version.to_s, spec.required_rubygems_version.to_s)
end
diff --git a/spec/bundler/support/artifice/helpers/endpoint.rb b/spec/bundler/support/artifice/helpers/endpoint.rb
index 83ba1be0fc..fc0381dc38 100644
--- a/spec/bundler/support/artifice/helpers/endpoint.rb
+++ b/spec/bundler/support/artifice/helpers/endpoint.rb
@@ -2,7 +2,7 @@
require_relative "../../path"
-$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{mustermann,rack,tilt,sinatra,ruby2_keywords,base64}-*/lib")].map(&:to_s))
+$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s))
require "sinatra/base"
@@ -69,10 +69,10 @@ class Endpoint < Sinatra::Base
spec = load_spec(name, version, platform, gem_repo)
next unless gem_names.include?(spec.name)
{
- name: spec.name,
- number: spec.version.version,
- platform: spec.platform.to_s,
- dependencies: spec.runtime_dependencies.map do |dep|
+ :name => spec.name,
+ :number => spec.version.version,
+ :platform => spec.platform.to_s,
+ :dependencies => spec.dependencies.select {|dep| dep.type == :runtime }.map do |dep|
[dep.name, dep.requirement.requirements.map {|a| a.join(" ") }.join(", ")]
end,
}
diff --git a/spec/bundler/support/artifice/helpers/rack_request.rb b/spec/bundler/support/artifice/helpers/rack_request.rb
index f419bacb8c..c4a07812a6 100644
--- a/spec/bundler/support/artifice/helpers/rack_request.rb
+++ b/spec/bundler/support/artifice/helpers/rack_request.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "rack/test"
-require "bundler/vendored_net_http"
+require "net/http"
module Artifice
module Net
@@ -16,25 +16,25 @@ module Artifice
end
end
- class HTTP < ::Gem::Net::HTTP
+ class HTTP < ::Net::HTTP
class << self
attr_accessor :endpoint
end
- # Gem::Net::HTTP uses a @newimpl instance variable to decide whether
+ # Net::HTTP uses a @newimpl instance variable to decide whether
# to use a legacy implementation. Since we are subclassing
- # Gem::Net::HTTP, we must set it
+ # Net::HTTP, we must set it
@newimpl = true
# We don't need to connect, so blank out this method
def connect
end
- # Replace the Gem::Net::HTTP request method with a method
+ # Replace the Net::HTTP request method with a method
# that converts the request into a Rack request and
# dispatches it to the Rack endpoint.
#
- # @param [Net::HTTPRequest] req A Gem::Net::HTTPRequest
+ # @param [Net::HTTPRequest] req A Net::HTTPRequest
# object, or one if its subclasses
# @param [optional, String, #read] body This should
# be sent as "rack.input". If it's a String, it will
@@ -42,7 +42,7 @@ module Artifice
# @return [Net::HTTPResponse]
#
# @yield [Net::HTTPResponse] If a block is provided,
- # this method will yield the Gem::Net::HTTPResponse to
+ # this method will yield the Net::HTTPResponse to
# it after the body is read.
def request(req, body = nil, &block)
rack_request = RackRequest.new(self.class.endpoint)
@@ -56,17 +56,17 @@ module Artifice
body_stream_contents = req.body_stream.read if req.body_stream
response = rack_request.request("#{prefix}#{req.path}",
- { method: req.method, input: body || req.body || body_stream_contents })
+ { :method => req.method, :input => body || req.body || body_stream_contents })
make_net_http_response(response, &block)
end
private
- # This method takes a Rack response and creates a Gem::Net::HTTPResponse
+ # This method takes a Rack response and creates a Net::HTTPResponse
# Instead of trying to mock HTTPResponse directly, we just convert
# the Rack response into a String that looks like a normal HTTP
- # response and call Gem::Net::HTTPResponse.read_new
+ # response and call Net::HTTPResponse.read_new
#
# @param [Array(#to_i, Hash, #each)] response a Rack response
# @return [Net::HTTPResponse]
@@ -86,8 +86,8 @@ module Artifice
response_string << "" << body
- response_io = ::Gem::Net::BufferedIO.new(StringIO.new(response_string.join("\n")))
- res = ::Gem::Net::HTTPResponse.read_new(response_io)
+ response_io = ::Net::BufferedIO.new(StringIO.new(response_string.join("\n")))
+ res = ::Net::HTTPResponse.read_new(response_io)
res.reading_body(response_io, true) do
yield res if block_given?
diff --git a/spec/bundler/support/artifice/used_cassettes.txt b/spec/bundler/support/artifice/used_cassettes.txt
new file mode 100644
index 0000000000..a96efc790d
--- /dev/null
+++ b/spec/bundler/support/artifice/used_cassettes.txt
@@ -0,0 +1,20908 @@
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ffi-1.15.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/capybara/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/selenium-webdriver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/xpath/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/culerity/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uglifier/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/matrix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyzip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/childprocess/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libwebsocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-active_record/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/therubyracer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gherkin3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-wire/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/event-bus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-formatter-dots/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-html-formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-gherkin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-cucumber-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-messages/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-create-meta/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-uname/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/database_cleaner-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libv8/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trollop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/c21e/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag_expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cucumber-tag-expressions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-protobuf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/protobuf-cucumber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/curses/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis-namespace/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/resque/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rufus-scheduler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mono_logger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/et-orbi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/vegas/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fugit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/raabro/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.2.3.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-4.5.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mono_logger-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/ruby2_keywords-0.0.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tilt-2.0.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/mustermann-1.1.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/redis-namespace-1.6.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/vegas-0.1.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-protection-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/sinatra-2.1.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/tzinfo-2.0.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-1.24.1.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rufus-scheduler-2.0.24.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/resque-scheduler-2.2.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/climate_control/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cocaine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/paperclip/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/terrapin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_aws/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mocha/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thoughtbot-shoulda/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metaclass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/right_http_connection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gxapi_rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-api-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sass-listen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/addressable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/extlib/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/signet/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpadapter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/liquid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/launchy/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/autoparse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sinatra/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uuidtools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jwt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/retriable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/googleauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hurley/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoist/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/representable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-generator/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sassc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fchange/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-fsevent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-inotify/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rb-kqueue/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_dep/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-io/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/public_suffix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/english/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-protection/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongrel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mustermann/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multipart-post/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_http/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-net_http_persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-em_synchrony/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-httpclient/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-patron/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday-rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/logging/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/os/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hooks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/uber/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/declarative-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/trailblazer-option/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrick/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/google-apis-discovery_v1/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gems/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/cgi_multipart_eof_fix/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/fastthread/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gem_plugin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/escape_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/excon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-http-persistent/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/flexmock/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/little-plugger/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hashie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faraday_middleware/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rash/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/oauth2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/roauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/httpauth/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongoid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongodb-mongo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/durran-validatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mislav-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mongo_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/leshill-will_paginate/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bson/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/origin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/moped/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby2_keywords/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pry/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/optionable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/connection_pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coderay/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spoon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coveralls/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/metasploit-erd/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/yard/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-graphviz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/choice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/webrat/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/railties/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-mocks/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-core/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-expectations/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-collection_matchers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-support/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov-html/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/docile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/lockfile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/colorize/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/simplecov_json_formatter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rest-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tins/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/term-ansicolor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activeresource/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionwebservice/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionview/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activejob/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actioncable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activestorage/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actiontext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/actionmailbox/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-ssl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rexml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nokogiri/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hpricot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-test/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/abstract/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rdoc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/treetop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-mount/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack-cache/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sprockets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/journey/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-deprecated_sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-dom-testing/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-html-sanitizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activerecord-deprecated_finders/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/arel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/netrc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-cookie/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/http-accept/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sync/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-format/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rails-observers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-serializers-xml/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/erubi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/marcel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_mime/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mimemagic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activemodel-globalid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-rails/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/em-hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faye-websocket/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-driver/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/redis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nio4r/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facets/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/polyglot/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/weakling/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mini_portile2/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pkg-config/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/racc/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multimap/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/loofah/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hike/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tilt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mime-types-data/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/domain_name/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-essentials/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sqlite3/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tlsmail/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hiredis/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/text-hyphen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/eventmachine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timers/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/facter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-extras/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-fsm/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-pool/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/nenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/celluloid-supervision/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rspec-logsplit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/websocket-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ftp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/crass/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake-compiler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hitimes/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/CFPropertyList/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sys-admin/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32console/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-dir/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-api/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/windows-pr/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hocon/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/win32-security/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/dotenv-deployment/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coffee-script-source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/daemons/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/execjs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/time/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/configuration/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/mkrf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-protocol/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unf_ext/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rainbow/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/backports/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/powerpack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-progressbar/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/astrolabe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jaro_winkler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/parallel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubocop-ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/regexp_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/psych/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/test-unit/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/libxml-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi-win32-extensions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/date/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/io-wait/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/timeout/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ast/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/slop/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jar-dependencies/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strscan/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/power_assert/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pattern-match/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/maven-tools/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby-maven-libs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/virtus/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/axiom-types/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/coercible/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equalizer/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/descendants_tracker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/adamantium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ice_nine/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memoizable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bundler/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/concurrent-ruby-1.1.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.9.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.12.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/activesupport/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/i18n/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/faker/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/builder/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/memcache-client/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tzinfo/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thread_safe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/minitest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/method_source/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/zeitwerk/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/concurrent-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/multi_json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/pastel/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/thor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-pager/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-screen/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-tree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/RubyInline/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/hoe/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ZenTest/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/atomic/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/functional-ruby/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ruby_parser/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/equatable/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-which/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/tty-color/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ref/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/verse/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rubyforge/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/gemcutter/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/sexp_processor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ParseTree/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode_utils/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/unicode-display_width/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/strings-ansi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rake/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-scp/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json_pure/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/SexpProcessor/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/spruz/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/net-ssh/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/jruby-pageant/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rbnacl-libsodium/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/bcrypt_pbkdf/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/needle/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/ffi/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/i18n-0.6.11.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/multi_json-1.15.0.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/activesupport-3.2.22.5.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/faker-1.1.2.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/diff-lcs/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/diff-lcs-1.4.4.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/rack/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/info/json/GET/response
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/request
+spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/rack-2.0.9.gem/GET/response
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/request
+spec/support/artifice/vcr_cassettes/realworld/index.rubygems.org/versions/GET/response
diff --git a/spec/bundler/support/artifice/vcr.rb b/spec/bundler/support/artifice/vcr.rb
index 7b9a8bdeaf..6a346f1ff9 100644
--- a/spec/bundler/support/artifice/vcr.rb
+++ b/spec/bundler/support/artifice/vcr.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: true
-require "bundler/vendored_net_http"
+require "net/http"
require_relative "../path"
-CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes".freeze
-USED_CASSETTES_PATH = "#{Spec::Path.spec_dir}/support/artifice/used_cassettes.txt".freeze
+CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes"
+USED_CASSETTES_PATH = "#{Spec::Path.spec_dir}/support/artifice/used_cassettes.txt"
CASSETTE_NAME = ENV.fetch("BUNDLER_SPEC_VCR_CASSETTE_NAME") { "realworld" }
-class BundlerVCRHTTP < Gem::Net::HTTP
+class BundlerVCRHTTP < Net::HTTP
class RequestHandler
attr_reader :http, :request, :body, :response_block
def initialize(http, request, body = nil, &response_block)
@@ -41,8 +41,8 @@ class BundlerVCRHTTP < Gem::Net::HTTP
def recorded_response
File.open(request_pair_paths.last, "rb:ASCII-8BIT") do |response_file|
- response_io = ::Gem::Net::BufferedIO.new(response_file)
- ::Gem::Net::HTTPResponse.read_new(response_io).tap do |response|
+ response_io = ::Net::BufferedIO.new(response_file)
+ ::Net::HTTPResponse.read_new(response_io).tap do |response|
response.decode_content = request.decode_content if request.respond_to?(:decode_content)
response.uri = request.uri
@@ -148,5 +148,5 @@ end
require_relative "helpers/artifice"
-# Replace Gem::Net::HTTP with our VCR subclass
+# Replace Net::HTTP with our VCR subclass
Artifice.replace_net_http(BundlerVCRHTTP)
diff --git a/spec/bundler/support/artifice/windows.rb b/spec/bundler/support/artifice/windows.rb
index fea991c071..4d90e0a426 100644
--- a/spec/bundler/support/artifice/windows.rb
+++ b/spec/bundler/support/artifice/windows.rb
@@ -2,7 +2,7 @@
require_relative "../path"
-$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{mustermann,rack,tilt,sinatra,ruby2_keywords,base64}-*/lib")].map(&:to_s))
+$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s))
require "sinatra/base"
diff --git a/spec/bundler/support/build_metadata.rb b/spec/bundler/support/build_metadata.rb
index 5898e7f3bd..98d8ac23c8 100644
--- a/spec/bundler/support/build_metadata.rb
+++ b/spec/bundler/support/build_metadata.rb
@@ -10,20 +10,20 @@ module Spec
def write_build_metadata(dir: source_root)
build_metadata = {
- git_commit_sha: git_commit_sha,
- built_at: loaded_gemspec.date.utc.strftime("%Y-%m-%d"),
- release: true,
+ :git_commit_sha => git_commit_sha,
+ :built_at => loaded_gemspec.date.utc.strftime("%Y-%m-%d"),
+ :release => true,
}
- replace_build_metadata(build_metadata, dir: dir)
+ replace_build_metadata(build_metadata, dir: dir) # rubocop:disable Style/HashSyntax
end
def reset_build_metadata(dir: source_root)
build_metadata = {
- release: false,
+ :release => false,
}
- replace_build_metadata(build_metadata, dir: dir)
+ replace_build_metadata(build_metadata, dir: dir) # rubocop:disable Style/HashSyntax
end
private
@@ -41,7 +41,7 @@ module Spec
end
def git_commit_sha
- ruby_core_tarball? ? "unknown" : sys_exec("git rev-parse --short HEAD", dir: source_root).strip
+ ruby_core_tarball? ? "unknown" : sys_exec("git rev-parse --short HEAD", :dir => source_root).strip
end
extend self
diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb
index 8f646b9358..dfc7139523 100644
--- a/spec/bundler/support/builders.rb
+++ b/spec/bundler/support/builders.rb
@@ -17,10 +17,6 @@ module Spec
Gem::Platform.new(platform)
end
- def rake_version
- "13.2.1"
- end
-
def build_repo1
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
@@ -53,7 +49,7 @@ module Spec
build_gem "rails", "2.3.2" do |s|
s.executables = "rails"
- s.add_dependency "rake", rake_version
+ s.add_dependency "rake", "13.0.1"
s.add_dependency "actionpack", "2.3.2"
s.add_dependency "activerecord", "2.3.2"
s.add_dependency "actionmailer", "2.3.2"
@@ -77,11 +73,11 @@ module Spec
s.add_dependency "activesupport", ">= 2.0.0"
end
- build_gem "rspec", "1.2.7", no_default: true do |s|
+ build_gem "rspec", "1.2.7", :no_default => true do |s|
s.write "lib/spec.rb", "SPEC = '1.2.7'"
end
- build_gem "rack-test", no_default: true do |s|
+ build_gem "rack-test", :no_default => true do |s|
s.write "lib/rack/test.rb", "RACK_TEST = '1.0'"
end
@@ -195,25 +191,25 @@ module Spec
end
end
- def build_repo2(**kwargs, &blk)
+ def build_repo2(&blk)
FileUtils.rm_rf gem_repo2
FileUtils.cp_r gem_repo1, gem_repo2
- update_repo2(**kwargs, &blk) if block_given?
+ update_repo2(&blk) if block_given?
end
# A repo that has no pre-installed gems included. (The caller completely
# determines the contents with the block.)
- def build_repo4(**kwargs, &blk)
+ def build_repo4(&blk)
FileUtils.rm_rf gem_repo4
- build_repo(gem_repo4, **kwargs, &blk)
+ build_repo(gem_repo4, &blk)
end
def update_repo4(&blk)
update_repo(gem_repo4, &blk)
end
- def update_repo2(**kwargs, &blk)
- update_repo(gem_repo2, **kwargs, &blk)
+ def update_repo2(&blk)
+ update_repo(gem_repo2, &blk)
end
def build_security_repo
@@ -231,12 +227,12 @@ module Spec
end
end
- def build_repo(path, **kwargs, &blk)
+ def build_repo(path, &blk)
return if File.directory?(path)
FileUtils.mkdir_p("#{path}/gems")
- update_repo(path,**kwargs, &blk)
+ update_repo(path, &blk)
end
def check_test_gems!
@@ -253,7 +249,7 @@ module Spec
end
end
- def update_repo(path, build_compact_index: true)
+ def update_repo(path)
if path == gem_repo1 && caller.first.split(" ").last == "`build_repo`"
raise "Updating gem_repo1 is unsupported -- use gem_repo2 instead"
end
@@ -262,12 +258,7 @@ module Spec
@_build_repo = File.basename(path)
yield
with_gem_path_as Path.base_system_gem_path do
- Dir[Spec::Path.base_system_gem_path.join("gems/rubygems-generate_index*/lib")].first ||
- raise("Could not find rubygems-generate_index lib directory in #{Spec::Path.base_system_gem_path}")
-
- command = "generate_index"
- command += " --no-compact" if !build_compact_index && gem_command(command + " --help").include?("--[no-]compact")
- gem_command command, dir: path
+ gem_command :generate_index, :dir => path
end
ensure
@_build_path = nil
@@ -297,10 +288,6 @@ module Spec
build_with(LibBuilder, name, args, &blk)
end
- def build_bundler(*args, &blk)
- build_with(BundlerBuilder, "bundler", args, &blk)
- end
-
def build_gem(name, *args, &blk)
build_with(GemBuilder, name, args, &blk)
end
@@ -406,49 +393,6 @@ module Spec
alias_method :dep, :runtime
end
- class BundlerBuilder
- attr_writer :required_ruby_version
-
- def initialize(context, name, version)
- raise "can only build bundler" unless name == "bundler"
-
- @context = context
- @version = version || Bundler::VERSION
- end
-
- def _build(options = {})
- full_name = "bundler-#{@version}"
- build_path = @context.tmp + full_name
- bundler_path = build_path + "#{full_name}.gem"
-
- FileUtils.mkdir_p build_path
-
- @context.shipped_files.each do |shipped_file|
- target_shipped_file = shipped_file
- target_shipped_file = shipped_file.sub(/\Alibexec/, "exe") if @context.ruby_core?
- target_shipped_file = build_path + target_shipped_file
- target_shipped_dir = File.dirname(target_shipped_file)
- FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir)
- FileUtils.cp shipped_file, target_shipped_file, preserve: true
- end
-
- @context.replace_version_file(@version, dir: build_path)
- @context.replace_required_ruby_version(@required_ruby_version, dir: build_path) if @required_ruby_version
-
- Spec::BuildMetadata.write_build_metadata(dir: build_path)
-
- @context.gem_command "build #{@context.relative_gemspec}", dir: build_path
-
- if block_given?
- yield(bundler_path)
- else
- FileUtils.mv bundler_path, options[:path]
- end
- ensure
- build_path.rmtree
- end
- end
-
class LibBuilder
def initialize(context, name, version)
@context = context
@@ -494,6 +438,8 @@ module Spec
write "ext/extconf.rb", <<-RUBY
require "mkmf"
+ $extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
+
extension_name = "#{name}_c"
if extra_lib_dir = with_config("ext-lib")
# add extra libpath if --with-ext-lib is
@@ -518,6 +464,7 @@ module Spec
if options[:rubygems_version]
@spec.rubygems_version = options[:rubygems_version]
+ def @spec.mark_version; end
def @spec.validate(*); end
end
@@ -574,7 +521,7 @@ module Spec
default_branch = options[:default_branch] || "main"
path = options[:path] || _default_path
source = options[:source] || "git@#{path}"
- super(options.merge(path: path, source: source))
+ super(options.merge(:path => path, :source => source))
@context.git("config --global init.defaultBranch #{default_branch}", path)
@context.git("init", path)
@context.git("add *", path)
@@ -588,7 +535,7 @@ module Spec
class GitBareBuilder < LibBuilder
def _build(options)
path = options[:path] || _default_path
- super(options.merge(path: path))
+ super(options.merge(:path => path))
@context.git("init --bare", path)
end
end
@@ -613,7 +560,7 @@ module Spec
_default_files.keys.each do |path|
_default_files[path] += "\n#{Builders.constantize(name)}_PREV_REF = '#{current_ref}'"
end
- super(options.merge(path: libpath, gemspec: update_gemspec, source: source))
+ super(options.merge(:path => libpath, :gemspec => update_gemspec, :source => source))
@context.git("commit -am BUMP", libpath)
end
end
@@ -636,7 +583,7 @@ module Spec
class GemBuilder < LibBuilder
def _build(opts)
lib_path = opts[:lib_path] || @context.tmp(".tmp/#{@spec.full_name}")
- lib_path = super(opts.merge(path: lib_path, no_default: opts[:no_default]))
+ lib_path = super(opts.merge(:path => lib_path, :no_default => opts[:no_default]))
destination = opts[:path] || _default_path
FileUtils.mkdir_p(lib_path.join(destination))
@@ -645,16 +592,16 @@ module Spec
Bundler.rubygems.build(@spec, opts[:skip_validation])
end
elsif opts[:skip_validation]
- @context.gem_command "build --force #{@spec.name}", dir: lib_path
+ @context.gem_command "build --force #{@spec.name}", :dir => lib_path
else
- @context.gem_command "build #{@spec.name}", dir: lib_path
+ @context.gem_command "build #{@spec.name}", :dir => lib_path
end
gem_path = File.expand_path("#{@spec.full_name}.gem", lib_path)
if opts[:to_system]
- @context.system_gems gem_path, default: opts[:default]
+ @context.system_gems gem_path, :default => opts[:default]
elsif opts[:to_bundle]
- @context.system_gems gem_path, path: @context.default_bundle_path
+ @context.system_gems gem_path, :path => @context.default_bundle_path
else
FileUtils.mv(gem_path, destination)
end
@@ -674,7 +621,7 @@ module Spec
end
end
- TEST_CERT = <<~CERT
+ TEST_CERT = <<-CERT.gsub(/^\s*/, "")
-----BEGIN CERTIFICATE-----
MIIDMjCCAhqgAwIBAgIBATANBgkqhkiG9w0BAQUFADAnMQwwCgYDVQQDDAN5b3Ux
FzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTE1MDIwODAwMTIyM1oXDTQyMDYy
@@ -697,7 +644,7 @@ module Spec
-----END CERTIFICATE-----
CERT
- TEST_PKEY = <<~PKEY
+ TEST_PKEY = <<-PKEY.gsub(/^\s*/, "")
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2W8V2k3jdzgMxL0mjTqbRruTdtDcdZDXKtiFkyLvsXUXvc2k
GSdgcjMOS1CkafqGz/hAUlPibjM0QEXjtQuMdTmdMrmuORLeeIZhSO+HdkTNV6j3
diff --git a/spec/bundler/support/bundle.rb b/spec/bundler/support/bundle.rb
index 5d6d658040..5f808531ff 100644
--- a/spec/bundler/support/bundle.rb
+++ b/spec/bundler/support/bundle.rb
@@ -1,5 +1,10 @@
# frozen_string_literal: true
-require_relative "activate"
+require "rubygems"
+Gem.instance_variable_set(:@ruby, ENV["RUBY"]) if ENV["RUBY"]
+require_relative "path"
+bundler_gemspec = Spec::Path.loaded_gemspec
+bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root)
+bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate)
load File.expand_path("bundle", Spec::Path.bindir)
diff --git a/spec/bundler/support/checksums.rb b/spec/bundler/support/checksums.rb
deleted file mode 100644
index f758559b3b..0000000000
--- a/spec/bundler/support/checksums.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-# frozen_string_literal: true
-
-module Spec
- module Checksums
- class ChecksumsBuilder
- def initialize(enabled = true, &block)
- @enabled = enabled
- @checksums = {}
- yield self if block_given?
- end
-
- def initialize_copy(original)
- super
- @checksums = @checksums.dup
- end
-
- def checksum(repo, name, version, platform = Gem::Platform::RUBY)
- name_tuple = Gem::NameTuple.new(name, version, platform)
- gem_file = File.join(repo, "gems", "#{name_tuple.full_name}.gem")
- File.open(gem_file, "rb") do |f|
- register(name_tuple, Bundler::Checksum.from_gem(f, "#{gem_file} (via ChecksumsBuilder#checksum)"))
- end
- end
-
- def no_checksum(name, version, platform = Gem::Platform::RUBY)
- name_tuple = Gem::NameTuple.new(name, version, platform)
- register(name_tuple, nil)
- end
-
- def delete(name, platform = nil)
- @checksums.reject! {|k, _| k.name == name && (platform.nil? || k.platform == platform) }
- end
-
- def to_s
- return "" unless @enabled
-
- locked_checksums = @checksums.map do |name_tuple, checksum|
- checksum &&= " #{checksum.to_lock}"
- " #{name_tuple.lock_name}#{checksum}\n"
- end
-
- "\nCHECKSUMS\n#{locked_checksums.sort.join}"
- end
-
- private
-
- def register(name_tuple, checksum)
- delete(name_tuple.name, name_tuple.platform)
- @checksums[name_tuple] = checksum
- end
- end
-
- def checksums_section(enabled = true, &block)
- ChecksumsBuilder.new(enabled, &block)
- end
-
- def checksums_section_when_existing(&block)
- begin
- enabled = lockfile.match?(/^CHECKSUMS$/)
- rescue Errno::ENOENT
- enabled = false
- end
- checksums_section(enabled, &block)
- end
-
- def checksum_to_lock(*args)
- checksums_section do |c|
- c.checksum(*args)
- end.to_s.sub(/^CHECKSUMS\n/, "").strip
- end
-
- def checksum_digest(*args)
- checksum_to_lock(*args).split(Bundler::Checksum::ALGO_SEPARATOR, 2).last
- end
-
- # if prefixes is given, removes all checksums where the line
- # has any of the prefixes on the line before the checksum
- # otherwise, removes all checksums from the lockfile
- def remove_checksums_from_lockfile(lockfile, *prefixes)
- head, remaining = lockfile.split(/^CHECKSUMS$/, 2)
- return lockfile unless remaining
- checksums, tail = remaining.split("\n\n", 2)
-
- prefixes =
- if prefixes.empty?
- nil
- else
- /(#{prefixes.map {|p| Regexp.escape(p) }.join("|")})/
- end
-
- checksums = checksums.each_line.map do |line|
- if prefixes.nil? || line.match?(prefixes)
- line.gsub(/ sha256=[a-f0-9]{64}/i, "")
- else
- line
- end
- end
-
- head.concat(
- "CHECKSUMS",
- checksums.join,
- "\n\n",
- tail
- )
- end
-
- def remove_checksums_section_from_lockfile(lockfile)
- head, remaining = lockfile.split(/^CHECKSUMS$/, 2)
- return lockfile unless remaining
- _checksums, tail = remaining.split("\n\n", 2)
- head.concat(tail)
- end
- end
-end
diff --git a/spec/bundler/support/command_execution.rb b/spec/bundler/support/command_execution.rb
index 5639fda3b6..68e5c56c75 100644
--- a/spec/bundler/support/command_execution.rb
+++ b/spec/bundler/support/command_execution.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Spec
- CommandExecution = Struct.new(:command, :working_directory, :exitstatus, :original_stdout, :original_stderr) do
+ CommandExecution = Struct.new(:command, :working_directory, :exitstatus, :stdout, :stderr) do
def to_s
"$ #{command}"
end
@@ -11,19 +11,6 @@ module Spec
@stdboth ||= [stderr, stdout].join("\n").strip
end
- def stdout
- original_stdout
- end
-
- # Can be removed once/if https://github.com/oneclick/rubyinstaller2/pull/369 is resolved
- def stderr
- return original_stderr unless Gem.win_platform?
-
- original_stderr.split("\n").reject do |l|
- l.include?("operating_system_defaults")
- end.join("\n")
- end
-
def to_s_verbose
[
to_s,
diff --git a/spec/bundler/support/filters.rb b/spec/bundler/support/filters.rb
index 8e164af756..78545d2e64 100644
--- a/spec/bundler/support/filters.rb
+++ b/spec/bundler/support/filters.rb
@@ -19,20 +19,20 @@ class RequirementChecker < Proc
end
RSpec.configure do |config|
- config.filter_run_excluding realworld: true
+ config.filter_run_excluding :realworld => true
git_version = Bundler::Source::Git::GitProxy.new(nil, nil).version
- config.filter_run_excluding git: RequirementChecker.against(git_version)
- config.filter_run_excluding bundler: RequirementChecker.against(Bundler::VERSION.split(".")[0])
- config.filter_run_excluding rubygems: RequirementChecker.against(Gem::VERSION)
- config.filter_run_excluding ruby_repo: !ENV["GEM_COMMAND"].nil?
- config.filter_run_excluding no_color_tty: Gem.win_platform? || !ENV["GITHUB_ACTION"].nil?
- config.filter_run_excluding permissions: Gem.win_platform?
- config.filter_run_excluding readline: Gem.win_platform?
- config.filter_run_excluding jruby_only: RUBY_ENGINE != "jruby"
- config.filter_run_excluding truffleruby_only: RUBY_ENGINE != "truffleruby"
- config.filter_run_excluding man: Gem.win_platform?
+ config.filter_run_excluding :git => RequirementChecker.against(git_version)
+ config.filter_run_excluding :bundler => RequirementChecker.against(Bundler::VERSION.split(".")[0])
+ config.filter_run_excluding :rubygems => RequirementChecker.against(Gem::VERSION)
+ config.filter_run_excluding :ruby_repo => !ENV["GEM_COMMAND"].nil?
+ config.filter_run_excluding :no_color_tty => Gem.win_platform? || !ENV["GITHUB_ACTION"].nil?
+ config.filter_run_excluding :permissions => Gem.win_platform?
+ config.filter_run_excluding :readline => Gem.win_platform?
+ config.filter_run_excluding :jruby_only => RUBY_ENGINE != "jruby"
+ config.filter_run_excluding :truffleruby_only => RUBY_ENGINE != "truffleruby"
+ config.filter_run_excluding :man => Gem.win_platform?
config.filter_run_when_matching :focus unless ENV["CI"]
end
diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb
index dbb8b8152b..7b8c56b6ad 100644
--- a/spec/bundler/support/helpers.rb
+++ b/spec/bundler/support/helpers.rb
@@ -43,7 +43,7 @@ module Spec
last_command.stderr
end
- MAJOR_DEPRECATION = /^\[DEPRECATED\]\s*/
+ MAJOR_DEPRECATION = /^\[DEPRECATED\]\s*/.freeze
def err_without_deprecations
err.gsub(/#{MAJOR_DEPRECATION}.+[\n]?/, "")
@@ -60,7 +60,7 @@ module Spec
def run(cmd, *args)
opts = args.last.is_a?(Hash) ? args.pop : {}
groups = args.map(&:inspect).join(", ")
- setup = "require 'bundler' ; Bundler.ui.silence { Bundler.setup(#{groups}) }"
+ setup = "require '#{entrypoint}' ; Bundler.ui.silence { Bundler.setup(#{groups}) }"
ruby([setup, cmd].join(" ; "), opts)
end
@@ -116,9 +116,9 @@ module Spec
end
end.join
- ruby_cmd = build_ruby_cmd({ load_path: load_path, requires: requires, env: env })
+ ruby_cmd = build_ruby_cmd({ :load_path => load_path, :requires => requires })
cmd = "#{ruby_cmd} #{bundle_bin} #{cmd}#{args}"
- sys_exec(cmd, { env: env, dir: dir, raise_on_error: raise_on_error }, &block)
+ sys_exec(cmd, { :env => env, :dir => dir, :raise_on_error => raise_on_error }, &block)
end
def bundler(cmd, options = {})
@@ -147,13 +147,7 @@ module Spec
lib_option = libs ? "-I#{libs.join(File::PATH_SEPARATOR)}" : []
requires = options.delete(:requires) || []
-
- hax_path = "#{Path.spec_dir}/support/hax.rb"
-
- # For specs that need to ignore the default Bundler gem, load hax before
- # anything else since other stuff may actually load bundler and not skip
- # the default version
- options[:env]&.include?("BUNDLER_IGNORE_DEFAULT_GEM") ? requires.prepend(hax_path) : requires.append(hax_path)
+ requires << "#{Path.spec_dir}/support/hax.rb"
require_option = requires.map {|r| "-r#{r}" }
[Gem.ruby, *lib_option, *require_option].compact.join(" ")
@@ -176,7 +170,7 @@ module Spec
end
def git(cmd, path, options = {})
- sys_exec("git #{cmd}", options.merge(dir: path))
+ sys_exec("git #{cmd}", options.merge(:dir => path))
end
def sys_exec(cmd, options = {})
@@ -187,14 +181,14 @@ module Spec
require "open3"
require "shellwords"
- Open3.popen3(env, *cmd.shellsplit, chdir: dir) do |stdin, stdout, stderr, wait_thr|
+ Open3.popen3(env, *cmd.shellsplit, :chdir => dir) do |stdin, stdout, stderr, wait_thr|
yield stdin, stdout, wait_thr if block_given?
stdin.close
stdout_read_thread = Thread.new { stdout.read }
stderr_read_thread = Thread.new { stderr.read }
- command_execution.original_stdout = stdout_read_thread.value.strip
- command_execution.original_stderr = stderr_read_thread.value.strip
+ command_execution.stdout = stdout_read_thread.value.strip
+ command_execution.stderr = stderr_read_thread.value.strip
status = wait_thr.value
command_execution.exitstatus = if status.exited?
@@ -226,20 +220,12 @@ module Spec
end
def config(config = nil, path = bundled_app(".bundle/config"))
- current = File.exist?(path) ? Psych.load_file(path) : {}
- return current unless config
-
- current = {} if current.empty?
-
+ return Psych.load_file(path) unless config
FileUtils.mkdir_p(File.dirname(path))
-
- new_config = current.merge(config).compact
-
- File.open(path, "w+") do |f|
- f.puts new_config.to_yaml
+ File.open(path, "w") do |f|
+ f.puts config.to_yaml
end
-
- new_config
+ config
end
def global_config(config = nil)
@@ -258,7 +244,7 @@ module Spec
contents = args.pop
if contents.nil?
- read_gemfile
+ File.open(bundled_app_gemfile, "r", &:read)
else
create_file(args.pop || "Gemfile", contents)
end
@@ -268,24 +254,12 @@ module Spec
contents = args.pop
if contents.nil?
- read_lockfile
+ File.open(bundled_app_lock, "r", &:read)
else
create_file(args.pop || "Gemfile.lock", contents)
end
end
- def read_gemfile(file = "Gemfile")
- read_bundled_app_file(file)
- end
-
- def read_lockfile(file = "Gemfile.lock")
- read_bundled_app_file(file)
- end
-
- def read_bundled_app_file(file)
- bundled_app(file).read
- end
-
def strip_whitespace(str)
# Trim the leading spaces
spaces = str[/\A\s+/, 0] || ""
@@ -307,35 +281,59 @@ module Spec
def system_gems(*gems)
gems = gems.flatten
options = gems.last.is_a?(Hash) ? gems.pop : {}
- install_dir = options.fetch(:path, system_gem_path)
+ path = options.fetch(:path, system_gem_path)
default = options.fetch(:default, false)
- with_gem_path_as(install_dir) do
+ with_gem_path_as(path) do
gem_repo = options.fetch(:gem_repo, gem_repo1)
gems.each do |g|
gem_name = g.to_s
if gem_name.start_with?("bundler")
version = gem_name.match(/\Abundler-(?<version>.*)\z/)[:version] if gem_name != "bundler"
- with_built_bundler(version) {|gem_path| install_gem(gem_path, install_dir, default) }
+ with_built_bundler(version) {|gem_path| install_gem(gem_path, default) }
elsif %r{\A(?:[a-zA-Z]:)?/.*\.gem\z}.match?(gem_name)
- install_gem(gem_name, install_dir, default)
+ install_gem(gem_name, default)
else
- install_gem("#{gem_repo}/gems/#{gem_name}.gem", install_dir, default)
+ install_gem("#{gem_repo}/gems/#{gem_name}.gem", default)
end
end
end
end
- def install_gem(path, install_dir, default = false)
+ def install_gem(path, default = false)
raise "OMG `#{path}` does not exist!" unless File.exist?(path)
- args = "--no-document --ignore-dependencies --verbose --local --install-dir #{install_dir}"
- args += " --default" if default
+ args = "--no-document --ignore-dependencies --verbose --local"
+ args += " --default --install-dir #{system_gem_path}" if default
gem_command "install #{args} '#{path}'"
end
- def with_built_bundler(version = nil, &block)
- Builders::BundlerBuilder.new(self, "bundler", version)._build(&block)
+ def with_built_bundler(version = nil)
+ version ||= Bundler::VERSION
+ full_name = "bundler-#{version}"
+ build_path = tmp + full_name
+ bundler_path = build_path + "#{full_name}.gem"
+
+ Dir.mkdir build_path
+
+ begin
+ shipped_files.each do |shipped_file|
+ target_shipped_file = build_path + shipped_file
+ target_shipped_dir = File.dirname(target_shipped_file)
+ FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir)
+ FileUtils.cp shipped_file, target_shipped_file, :preserve => true
+ end
+
+ replace_version_file(version, dir: build_path) # rubocop:disable Style/HashSyntax
+
+ Spec::BuildMetadata.write_build_metadata(dir: build_path) # rubocop:disable Style/HashSyntax
+
+ gem_command "build #{relative_gemspec}", :dir => build_path
+
+ yield(bundler_path)
+ ensure
+ build_path.rmtree
+ end
end
def with_gem_path_as(path)
@@ -454,12 +452,32 @@ module Spec
old = ENV["BUNDLER_SPEC_WINDOWS"]
ENV["BUNDLER_SPEC_WINDOWS"] = "true"
simulate_platform platform do
- yield
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ yield
+ end
end
ensure
ENV["BUNDLER_SPEC_WINDOWS"] = old
end
+ def simulate_bundler_version_when_missing_prerelease_default_gem_activation
+ return yield unless rubygems_version_failing_to_activate_bundler_prereleases
+
+ old = ENV["BUNDLER_VERSION"]
+ ENV["BUNDLER_VERSION"] = Bundler::VERSION
+ yield
+ ensure
+ ENV["BUNDLER_VERSION"] = old
+ end
+
+ def env_for_missing_prerelease_default_gem_activation
+ if rubygems_version_failing_to_activate_bundler_prereleases
+ { "BUNDLER_VERSION" => Bundler::VERSION }
+ else
+ {}
+ end
+ end
+
def current_ruby_minor
Gem.ruby_version.segments.tap {|s| s.delete_at(2) }.join(".")
end
@@ -478,8 +496,14 @@ module Spec
Gem.ruby_version.segments[0..1]
end
+ # versions not including
+ # https://github.com/rubygems/rubygems/commit/929e92d752baad3a08f3ac92eaec162cb96aedd1
+ def rubygems_version_failing_to_activate_bundler_prereleases
+ Gem.rubygems_version < Gem::Version.new("3.1.0.pre.1")
+ end
+
def revision_for(path)
- sys_exec("git rev-parse HEAD", dir: path).strip
+ sys_exec("git rev-parse HEAD", :dir => path).strip
end
def with_read_only(pattern)
diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb
index 086a311551..78372302f1 100644
--- a/spec/bundler/support/indexes.rb
+++ b/spec/bundler/support/indexes.rb
@@ -14,10 +14,10 @@ module Spec
alias_method :platforms, :platform
- def resolve(args = [], dependency_api_available: true)
+ def resolve(args = [])
@platforms ||= ["ruby"]
- default_source = instance_double("Bundler::Source::Rubygems", specs: @index, to_s: "locally install gems", dependency_api_available?: dependency_api_available)
- source_requirements = { default: default_source }
+ default_source = instance_double("Bundler::Source::Rubygems", :specs => @index, :to_s => "locally install gems")
+ source_requirements = { :default => default_source }
base = args[0] || Bundler::SpecSet.new([])
base.each {|ls| ls.source = default_source }
gem_version_promoter = args[1] || Bundler::GemVersionPromoter.new
@@ -27,7 +27,7 @@ module Spec
name = d.name
source_requirements[name] = d.source = default_source
end
- packages = Bundler::Resolver::Base.new(source_requirements, @deps, base, @platforms, locked_specs: originally_locked, unlock: unlock)
+ packages = Bundler::Resolver::Base.new(source_requirements, @deps, base, @platforms, :locked_specs => originally_locked, :unlock => unlock)
Bundler::Resolver.new(packages, gem_version_promoter).start
end
@@ -41,12 +41,6 @@ module Spec
expect(got).to eq(specs.sort)
end
- def should_resolve_without_dependency_api(specs)
- got = resolve(dependency_api_available: false)
- got = got.map(&:full_name).sort
- expect(got).to eq(specs.sort)
- end
-
def should_resolve_and_include(specs, args = [])
got = resolve(args)
got = got.map(&:full_name).sort
@@ -304,7 +298,7 @@ module Spec
end
end
- def a_unresolvable_child_index
+ def a_unresovable_child_index
build_index do
gem "json", %w[1.8.0]
diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb
index 0f027dcf04..ea7c784683 100644
--- a/spec/bundler/support/matchers.rb
+++ b/spec/bundler/support/matchers.rb
@@ -97,6 +97,18 @@ module Spec
end
end
+ RSpec::Matchers.define :take_less_than do |seconds|
+ match do |actual|
+ start_time = Time.now
+
+ actual.call
+
+ (Time.now - start_time).to_f < seconds
+ end
+
+ supports_block_expectations
+ end
+
define_compound_matcher :read_as, [exist] do |file_contents|
diffable
diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb
index 7352d5a353..8b9c0e1290 100644
--- a/spec/bundler/support/path.rb
+++ b/spec/bundler/support/path.rb
@@ -80,13 +80,7 @@ module Spec
end
def shipped_files
- @shipped_files ||= if ruby_core_tarball?
- loaded_gemspec.files.map {|f| f.gsub(%r{^exe/}, "libexec/") }
- elsif ruby_core?
- tracked_files
- else
- loaded_gemspec.files
- end
+ @shipped_files ||= loaded_gemspec.files
end
def lib_tracked_files
@@ -231,6 +225,13 @@ module Spec
root.join("lib")
end
+ # Sometimes rubygems version under test does not include
+ # https://github.com/rubygems/rubygems/pull/2728 and will not always end up
+ # activating the current bundler. In that case, require bundler absolutely.
+ def entrypoint
+ Gem.rubygems_version < Gem::Version.new("3.1.a") ? "#{lib_dir}/bundler" : "bundler"
+ end
+
def global_plugin_gem(*args)
home ".bundle", "plugin", "gems", *args
end
@@ -250,13 +251,6 @@ module Spec
File.open(version_file, "w") {|f| f << contents }
end
- def replace_required_ruby_version(version, dir:)
- gemspec_file = File.expand_path("bundler.gemspec", dir)
- contents = File.read(gemspec_file)
- contents.sub!(/(^\s+s\.required_ruby_version\s*=\s*)"[^"]+"/, %(\\1"#{version}"))
- File.open(gemspec_file, "w") {|f| f << contents }
- end
-
def ruby_core?
# avoid to warnings
@ruby_core ||= nil
@@ -277,11 +271,11 @@ module Spec
def git_ls_files(glob)
skip "Not running on a git context, since running tests from a tarball" if ruby_core_tarball?
- sys_exec("git ls-files -z -- #{glob}", dir: source_root).split("\x0")
+ sys_exec("git ls-files -z -- #{glob}", :dir => source_root).split("\x0")
end
def tracked_files_glob
- ruby_core? ? "libexec/bundle* lib/bundler lib/bundler.rb spec/bundler man/bundle*" : "lib exe spec CHANGELOG.md LICENSE.md README.md bundler.gemspec"
+ ruby_core? ? "lib/bundler lib/bundler.rb spec/bundler man/bundle*" : ""
end
def lib_tracked_files_glob
diff --git a/spec/bundler/support/platforms.rb b/spec/bundler/support/platforms.rb
index 526e1c09a9..eca1b2e60d 100644
--- a/spec/bundler/support/platforms.rb
+++ b/spec/bundler/support/platforms.rb
@@ -95,17 +95,12 @@ module Spec
9999
end
- def default_platform_list(*extra, defaults: default_locked_platforms)
- defaults.concat(extra).uniq
+ def lockfile_platforms(*extra)
+ formatted_lockfile_platforms(local_platform, *extra)
end
- def lockfile_platforms(*extra, defaults: default_locked_platforms)
- platforms = default_platform_list(*extra, defaults: defaults)
+ def formatted_lockfile_platforms(*platforms)
platforms.map(&:to_s).sort.join("\n ")
end
-
- def default_locked_platforms
- [local_platform, generic_local_platform]
- end
end
end
diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb
index 889ebc90c3..4553c0606e 100644
--- a/spec/bundler/support/rubygems_ext.rb
+++ b/spec/bundler/support/rubygems_ext.rb
@@ -24,9 +24,9 @@ module Spec
gem_load_activate_and_possibly_install(gem_name, bin_container)
end
- def gem_require(gem_name, entrypoint)
+ def gem_require(gem_name)
gem_activate(gem_name)
- require entrypoint
+ require gem_name
end
def test_setup
@@ -38,10 +38,6 @@ module Spec
FileUtils.mkdir_p(Path.tmpdir)
ENV["HOME"] = Path.home.to_s
- # 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"
ENV["TMPDIR"] = Path.tmpdir.to_s
require "rubygems/user_interaction"
@@ -90,7 +86,7 @@ module Spec
puts success_message
puts
else
- system("git diff")
+ system("git status --porcelain")
puts
puts error_message
@@ -122,7 +118,6 @@ module Spec
end
def gem_activate(gem_name)
- require_relative "activate"
require "bundler"
gem_requirement = Bundler::LockfileParser.new(File.read(dev_lockfile)).specs.find {|spec| spec.name == gem_name }.version
gem gem_name, gem_requirement
diff --git a/spec/bundler/support/rubygems_version_manager.rb b/spec/bundler/support/rubygems_version_manager.rb
index 88da14b67e..5653601ae8 100644
--- a/spec/bundler/support/rubygems_version_manager.rb
+++ b/spec/bundler/support/rubygems_version_manager.rb
@@ -30,10 +30,11 @@ class RubygemsVersionManager
rubygems_default_path = rubygems_path + "/defaults"
bundler_path = rubylibdir + "/bundler"
+ bundler_exemptions = Gem.rubygems_version < Gem::Version.new("3.2.0") ? [bundler_path + "/errors.rb"] : []
bad_loaded_features = $LOADED_FEATURES.select do |loaded_feature|
(loaded_feature.start_with?(rubygems_path) && !loaded_feature.start_with?(rubygems_default_path)) ||
- loaded_feature.start_with?(bundler_path)
+ (loaded_feature.start_with?(bundler_path) && !bundler_exemptions.any? {|bundler_exemption| loaded_feature.start_with?(bundler_exemption) })
end
errors = if bad_loaded_features.any?
@@ -65,7 +66,7 @@ class RubygemsVersionManager
def switch_local_copy_if_needed
return unless local_copy_switch_needed?
- sys_exec("git checkout #{target_tag}", dir: local_copy_path)
+ sys_exec("git checkout #{target_tag}", :dir => local_copy_path)
ENV["RGV"] = local_copy_path.to_s
end
@@ -84,7 +85,7 @@ class RubygemsVersionManager
end
def local_copy_tag
- sys_exec("git rev-parse --abbrev-ref HEAD", dir: local_copy_path)
+ sys_exec("git rev-parse --abbrev-ref HEAD", :dir => local_copy_path)
end
def local_copy_path
@@ -97,7 +98,7 @@ class RubygemsVersionManager
rubygems_path = source_root.join("tmp/rubygems")
unless rubygems_path.directory?
- sys_exec("git clone .. #{rubygems_path}", dir: source_root)
+ sys_exec("git clone .. #{rubygems_path}", :dir => source_root)
end
rubygems_path
diff --git a/spec/bundler/update/gemfile_spec.rb b/spec/bundler/update/gemfile_spec.rb
index d32a7945b0..1c5294101e 100644
--- a/spec/bundler/update/gemfile_spec.rb
+++ b/spec/bundler/update/gemfile_spec.rb
@@ -8,8 +8,8 @@ RSpec.describe "bundle update" do
gem 'rack'
G
- bundle :install, gemfile: bundled_app("NotGemfile")
- bundle :update, gemfile: bundled_app("NotGemfile"), all: true
+ bundle :install, :gemfile => bundled_app("NotGemfile")
+ bundle :update, :gemfile => bundled_app("NotGemfile"), :all => true
# Specify BUNDLE_GEMFILE for `the_bundle`
# to retrieve the proper Gemfile
@@ -30,7 +30,7 @@ RSpec.describe "bundle update" do
end
it "uses the gemfile to update" do
- bundle "update", all: true
+ bundle "update", :all => true
bundle "list"
expect(out).to include("rack (1.0.0)")
@@ -38,8 +38,8 @@ RSpec.describe "bundle update" do
it "uses the gemfile while in a subdirectory" do
bundled_app("subdir").mkpath
- bundle "update", all: true, dir: bundled_app("subdir")
- bundle "list", dir: bundled_app("subdir")
+ bundle "update", :all => true, :dir => bundled_app("subdir")
+ bundle "list", :dir => bundled_app("subdir")
expect(out).to include("rack (1.0.0)")
end
diff --git a/spec/bundler/update/gems/fund_spec.rb b/spec/bundler/update/gems/fund_spec.rb
index 4a87c16bf7..d80f4018f3 100644
--- a/spec/bundler/update/gems/fund_spec.rb
+++ b/spec/bundler/update/gems/fund_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe "bundle update" do
gem 'has_funding'
G
- bundle :update, all: true
+ bundle :update, :all => true
end
it "displays fund message" do
diff --git a/spec/bundler/update/gems/post_install_spec.rb b/spec/bundler/update/gems/post_install_spec.rb
index e3593387d4..3aaa659d57 100644
--- a/spec/bundler/update/gems/post_install_spec.rb
+++ b/spec/bundler/update/gems/post_install_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe "bundle update" do
gem 'thin'
G
- bundle :update, all: true
+ bundle :update, :all => true
end
it_behaves_like "a post-install message outputter"
@@ -67,7 +67,7 @@ RSpec.describe "bundle update" do
gem 'thin'
G
- bundle :update, all: true
+ bundle :update, :all => true
end
it_behaves_like "a post-install message outputter"
diff --git a/spec/bundler/update/git_spec.rb b/spec/bundler/update/git_spec.rb
index 3b7bbfd979..59e3d2f5fb 100644
--- a/spec/bundler/update/git_spec.rb
+++ b/spec/bundler/update/git_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe "bundle update" do
describe "git sources" do
it "floats on a branch when :branch is used" do
build_git "foo", "1.0"
- update_git "foo", branch: "omg"
+ update_git "foo", :branch => "omg"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -17,14 +17,14 @@ RSpec.describe "bundle update" do
s.write "lib/foo.rb", "FOO = '1.1'"
end
- bundle "update", all: true
+ bundle "update", :all => true
expect(the_bundle).to include_gems "foo 1.1"
end
it "updates correctly when you have like craziness" do
- build_lib "activesupport", "3.0", path: lib_path("rails/activesupport")
- build_git "rails", "3.0", path: lib_path("rails") do |s|
+ build_lib "activesupport", "3.0", :path => lib_path("rails/activesupport")
+ build_git "rails", "3.0", :path => lib_path("rails") do |s|
s.add_dependency "activesupport", "= 3.0"
end
@@ -38,8 +38,8 @@ RSpec.describe "bundle update" do
end
it "floats on a branch when :branch is used and the source is specified in the update" do
- build_git "foo", "1.0", path: lib_path("foo")
- update_git "foo", branch: "omg", path: lib_path("foo")
+ build_git "foo", "1.0", :path => lib_path("foo")
+ update_git "foo", :branch => "omg", :path => lib_path("foo")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -48,7 +48,7 @@ RSpec.describe "bundle update" do
end
G
- update_git "foo", path: lib_path("foo") do |s|
+ update_git "foo", :path => lib_path("foo") do |s|
s.write "lib/foo.rb", "FOO = '1.1'"
end
@@ -58,8 +58,8 @@ RSpec.describe "bundle update" do
end
it "floats on main when updating all gems that are pinned to the source even if you have child dependencies" do
- build_git "foo", path: lib_path("foo")
- build_gem "bar", to_bundle: true do |s|
+ build_git "foo", :path => lib_path("foo")
+ build_gem "bar", :to_bundle => true do |s|
s.add_dependency "foo"
end
@@ -69,7 +69,7 @@ RSpec.describe "bundle update" do
gem "bar"
G
- update_git "foo", path: lib_path("foo") do |s|
+ update_git "foo", :path => lib_path("foo") do |s|
s.write "lib/foo.rb", "FOO = '1.1'"
end
@@ -79,8 +79,8 @@ RSpec.describe "bundle update" do
end
it "notices when you change the repo url in the Gemfile" do
- build_git "foo", path: lib_path("foo_one")
- build_git "foo", path: lib_path("foo_two")
+ build_git "foo", :path => lib_path("foo_one")
+ build_git "foo", :path => lib_path("foo_two")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -101,9 +101,9 @@ RSpec.describe "bundle update" do
it "fetches tags from the remote" do
build_git "foo"
- @remote = build_git("bar", bare: true)
- update_git "foo", remote: file_uri_for(@remote.path)
- update_git "foo", push: "main"
+ @remote = build_git("bar", :bare => true)
+ update_git "foo", :remote => file_uri_for(@remote.path)
+ update_git "foo", :push => "main"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -111,15 +111,15 @@ RSpec.describe "bundle update" do
G
# Create a new tag on the remote that needs fetching
- update_git "foo", tag: "fubar"
- update_git "foo", push: "fubar"
+ update_git "foo", :tag => "fubar"
+ update_git "foo", :push => "fubar"
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => "#{@remote.path}", :tag => "fubar"
G
- bundle "update", all: true
+ bundle "update", :all => true
expect(err).to be_empty
end
@@ -142,8 +142,8 @@ RSpec.describe "bundle update" do
s.add_dependency "submodule"
end
- sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", dir: lib_path("has_submodule-1.0")
- sys_exec "git commit -m \"submodulator\"", dir: lib_path("has_submodule-1.0")
+ sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
+ sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
end
it "it unlocks the source when submodules are added to a git source" do
@@ -168,7 +168,7 @@ RSpec.describe "bundle update" do
expect(out).to eq("GIT")
end
- it "unlocks the source when submodules are removed from git source", git: ">= 2.9.0" do
+ it "unlocks the source when submodules are removed from git source", :git => ">= 2.9.0" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
git "#{lib_path("has_submodule-1.0")}", :submodules => true do
@@ -201,7 +201,7 @@ RSpec.describe "bundle update" do
lib_path("foo-1.0").join(".git").rmtree
- bundle :update, all: true, raise_on_error: false
+ bundle :update, :all => true, :raise_on_error => false
expect(err).to include(lib_path("foo-1.0").to_s).
and match(/Git error: command `git fetch.+has failed/)
end
@@ -209,7 +209,7 @@ RSpec.describe "bundle update" do
it "should not explode on invalid revision on update of gem by name" do
build_git "rack", "0.8"
- build_git "rack", "0.8", path: lib_path("local-rack") do |s|
+ build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
s.write "lib/rack.rb", "puts :LOCAL"
end
@@ -224,16 +224,16 @@ RSpec.describe "bundle update" do
end
it "shows the previous version of the gem" do
- build_git "rails", "2.3.2", path: lib_path("rails")
+ build_git "rails", "2.3.2", :path => lib_path("rails")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rails", :git => "#{file_uri_for(lib_path("rails"))}"
G
- update_git "rails", "3.0", path: lib_path("rails"), gemspec: true
+ update_git "rails", "3.0", :path => lib_path("rails"), :gemspec => true
- bundle "update", all: true
+ bundle "update", :all => true
expect(out).to include("Using rails 3.0 (was 2.3.2) from #{file_uri_for(lib_path("rails"))} (at main@#{revision_for(lib_path("rails"))[0..6]})")
end
end
@@ -241,7 +241,7 @@ RSpec.describe "bundle update" do
describe "with --source flag" do
before :each do
build_repo2
- @git = build_git "foo", path: lib_path("foo") do |s|
+ @git = build_git "foo", :path => lib_path("foo") do |s|
s.executables = "foobar"
end
@@ -255,7 +255,7 @@ RSpec.describe "bundle update" do
end
it "updates the source" do
- update_git "foo", path: @git.path
+ update_git "foo", :path => @git.path
bundle "update --source foo"
@@ -268,7 +268,7 @@ RSpec.describe "bundle update" do
end
it "unlocks gems that were originally pulled in by the source" do
- update_git "foo", "2.0", path: @git.path
+ update_git "foo", "2.0", :path => @git.path
bundle "update --source foo"
expect(the_bundle).to include_gems "foo 2.0"
@@ -276,7 +276,7 @@ RSpec.describe "bundle update" do
it "leaves all other gems frozen" do
update_repo2
- update_git "foo", path: @git.path
+ update_git "foo", :path => @git.path
bundle "update --source foo"
expect(the_bundle).to include_gems "rack 1.0"
@@ -286,7 +286,7 @@ RSpec.describe "bundle update" do
context "when the gem and the repository have different names" do
before :each do
build_repo2
- @git = build_git "foo", path: lib_path("bar")
+ @git = build_git "foo", :path => lib_path("bar")
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
@@ -301,7 +301,7 @@ RSpec.describe "bundle update" do
spec_lines = lib_path("bar/foo.gemspec").read.split("\n")
spec_lines[5] = "s.version = '2.0'"
- update_git "foo", "2.0", path: @git.path do |s|
+ update_git "foo", "2.0", :path => @git.path do |s|
s.write "foo.gemspec", spec_lines.join("\n")
end
@@ -309,11 +309,6 @@ RSpec.describe "bundle update" do
bundle "update --source bar"
- checksums = checksums_section_when_existing do |c|
- c.no_checksum "foo", "2.0"
- c.checksum gem_repo2, "rack", "1.0.0"
- end
-
expect(lockfile).to eq <<~G
GIT
remote: #{@git.path}
@@ -332,7 +327,7 @@ RSpec.describe "bundle update" do
DEPENDENCIES
foo!
rack
- #{checksums}
+
BUNDLED WITH
#{Bundler::VERSION}
G
diff --git a/spec/bundler/update/path_spec.rb b/spec/bundler/update/path_spec.rb
index 1f8992b33f..756770313b 100644
--- a/spec/bundler/update/path_spec.rb
+++ b/spec/bundler/update/path_spec.rb
@@ -3,14 +3,14 @@
RSpec.describe "path sources" do
describe "bundle update --source" do
it "shows the previous version of the gem when updated from path source" do
- build_lib "activesupport", "2.3.5", path: lib_path("rails/activesupport")
+ build_lib "activesupport", "2.3.5", :path => lib_path("rails/activesupport")
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "activesupport", :path => "#{lib_path("rails/activesupport")}"
G
- build_lib "activesupport", "3.0", path: lib_path("rails/activesupport")
+ build_lib "activesupport", "3.0", :path => lib_path("rails/activesupport")
bundle "update --source activesupport"
expect(out).to include("Using activesupport 3.0 (was 2.3.5) from source at `#{lib_path("rails/activesupport")}`")
diff --git a/spec/bundler/update/redownload_spec.rb b/spec/bundler/update/redownload_spec.rb
index 4a8c711bfa..147be823f5 100644
--- a/spec/bundler/update/redownload_spec.rb
+++ b/spec/bundler/update/redownload_spec.rb
@@ -9,12 +9,12 @@ RSpec.describe "bundle update" do
end
describe "with --force" do
- it "shows a deprecation when single flag passed", bundler: 2 do
+ it "shows a deprecation when single flag passed", :bundler => 2 do
bundle "update rack --force"
expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
end
- it "shows a deprecation when multiple flags passed", bundler: 2 do
+ it "shows a deprecation when multiple flags passed", :bundler => 2 do
bundle "update rack --no-color --force"
expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
end
@@ -30,15 +30,5 @@ RSpec.describe "bundle update" do
bundle "update rack --no-color --redownload"
expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`"
end
-
- it "re-installs installed gems" do
- rack_lib = default_bundle_path("gems/rack-1.0.0/lib/rack.rb")
- rack_lib.open("w") {|f| f.write("blah blah blah") }
- bundle :update, redownload: true
-
- expect(out).to include "Installing rack 1.0.0"
- expect(rack_lib.open(&:read)).to eq("RACK = '1.0.0'\n")
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
end
end
diff --git a/spec/default.mspec b/spec/default.mspec
index e2ad19e117..0dba98306c 100644
--- a/spec/default.mspec
+++ b/spec/default.mspec
@@ -4,7 +4,6 @@ if (opt = ENV["RUBYOPT"]) and (opt = opt.dup).sub!(/(?:\A|\s)-w(?=\z|\s)/, '')
ENV["RUBYOPT"] = opt
end
require "./rbconfig" unless defined?(RbConfig)
-require_relative "../tool/test-coverage" if ENV.key?("COVERAGE")
load File.dirname(__FILE__) + '/ruby/default.mspec'
OBJDIR = File.expand_path("spec/ruby/optional/capi/ext")
class MSpecScript
@@ -26,10 +25,6 @@ class MSpecScript
--
]
end
-
- if ENV.key?("COVERAGE")
- set :excludes, ["Coverage"]
- end
end
module MSpecScript::JobServer
@@ -70,72 +65,3 @@ end
class MSpecScript
prepend JobServer
end
-
-require 'mspec/runner/formatters/dotted'
-
-class DottedFormatter
- prepend Module.new {
- BASE = __dir__ + "/ruby/"
-
- def initialize(out = nil)
- super
- if out
- @columns = nil
- else
- columns = ENV["COLUMNS"]&.to_i
- @columns = columns&.nonzero? || 80
- end
- @dotted = 0
- @loaded = false
- @count = 0
- end
-
- def register
- super
- MSpec.register :load, self
- MSpec.register :unload, self
- end
-
- def after(*)
- if @columns
- if @dotted == 0
- s = sprintf("%6d ", @count)
- print(s)
- @dotted += s.size
- end
- @count +=1
- end
- super
- if @columns and (@dotted += 1) >= @columns
- print "\n"
- @dotted = 0
- end
- end
-
- def load(*)
- file = MSpec.file || MSpec.files_array.first
- @loaded = true
- s = "#{file.delete_prefix(BASE)}:"
- print s
- if @columns
- if (@dotted += s.size) >= @columns
- print "\n"
- @dotted = 0
- else
- print " "
- @dotted += 1
- end
- end
- @count = 0
- end
-
- def unload
- super
- if @loaded
- print "\n" if @dotted > 0
- @dotted = 0
- @loaded = nil
- end
- end
- }
-end
diff --git a/spec/lib/formatter_overrides.rb b/spec/lib/formatter_overrides.rb
deleted file mode 100644
index 4a61d425d1..0000000000
--- a/spec/lib/formatter_overrides.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module FormatterOverrides
- def example_pending(_); end
- def dump_pending(_); end
-end
-
-RSpec::Core::Formatters::ProgressFormatter.prepend FormatterOverrides
diff --git a/spec/lib/spec_coverage.rb b/spec/lib/spec_coverage.rb
deleted file mode 100644
index 34aed32f72..0000000000
--- a/spec/lib/spec_coverage.rb
+++ /dev/null
@@ -1 +0,0 @@
-require_relative "../../tool/test-coverage" if ENV.key?('COVERAGE')
diff --git a/spec/mspec/lib/mspec/commands/mspec.rb b/spec/mspec/lib/mspec/commands/mspec.rb
index f5341c699d..9c38cebcda 100755
--- a/spec/mspec/lib/mspec/commands/mspec.rb
+++ b/spec/mspec/lib/mspec/commands/mspec.rb
@@ -38,6 +38,11 @@ class MSpecMain < MSpecScript
options.targets
+ options.on("--warnings", "Don't suppress warnings") do
+ config[:flags] << '-w'
+ ENV['OUTPUT_WARNINGS'] = '1'
+ end
+
options.on("-j", "--multi", "Run multiple (possibly parallel) subprocesses") do
config[:multi] = true
end
diff --git a/spec/mspec/lib/mspec/helpers/io.rb b/spec/mspec/lib/mspec/helpers/io.rb
index 2ad14f47a1..29c6c37a1a 100644
--- a/spec/mspec/lib/mspec/helpers/io.rb
+++ b/spec/mspec/lib/mspec/helpers/io.rb
@@ -7,7 +7,7 @@ class IOStub
end
def write(*str)
- self << str.join('')
+ self << str.join
end
def << str
@@ -16,7 +16,7 @@ class IOStub
end
def print(*str)
- write(str.join('') + $\.to_s)
+ write(str.join + $\.to_s)
end
def method_missing(name, *args, &block)
diff --git a/spec/mspec/lib/mspec/helpers/ruby_exe.rb b/spec/mspec/lib/mspec/helpers/ruby_exe.rb
index 2e499d6f9a..7fde001cda 100644
--- a/spec/mspec/lib/mspec/helpers/ruby_exe.rb
+++ b/spec/mspec/lib/mspec/helpers/ruby_exe.rb
@@ -140,44 +140,28 @@ def ruby_exe(code = :not_given, opts = {})
expected_status = opts.fetch(:exit_status, 0)
begin
- command = ruby_cmd(code, opts)
-
- # Try to avoid the extra shell for 2>&1
- # This is notably useful for TimeoutAction which can then signal the ruby subprocess and not the shell
- popen_options = []
- if command.end_with?(' 2>&1')
- command = command[0...-5]
- popen_options = [{ err: [:child, :out] }]
- end
-
- output = IO.popen(command, *popen_options) do |io|
- pid = io.pid
- MSpec.subprocesses << pid
- begin
- io.read
- ensure
- MSpec.subprocesses.delete(pid)
+ platform_is_not :opal do
+ command = ruby_cmd(code, opts)
+ output = `#{command}`
+ status = Process.last_status
+
+ exit_status = if status.exited?
+ status.exitstatus
+ elsif status.signaled?
+ signame = Signal.signame status.termsig
+ raise "No signal name?" unless signame
+ :"SIG#{signame}"
+ else
+ raise SpecExpectationNotMetError, "#{exit_status.inspect} is neither exited? nor signaled?"
+ end
+ if exit_status != expected_status
+ formatted_output = output.lines.map { |line| " #{line}" }.join
+ raise SpecExpectationNotMetError,
+ "Expected exit status is #{expected_status.inspect} but actual is #{exit_status.inspect} for command ruby_exe(#{command.inspect})\nOutput:\n#{formatted_output}"
end
- end
- status = Process.last_status
-
- exit_status = if status.exited?
- status.exitstatus
- elsif status.signaled?
- signame = Signal.signame status.termsig
- raise "No signal name?" unless signame
- :"SIG#{signame}"
- else
- raise SpecExpectationNotMetError, "#{exit_status.inspect} is neither exited? nor signaled?"
- end
- if exit_status != expected_status
- formatted_output = output.lines.map { |line| " #{line}" }.join
- raise SpecExpectationNotMetError,
- "Expected exit status is #{expected_status.inspect} but actual is #{exit_status.inspect} for command ruby_exe(#{command.inspect})\nOutput:\n#{formatted_output}"
+ output
end
-
- output
ensure
saved_env.each { |key, value| ENV[key] = value }
env.keys.each do |key|
diff --git a/spec/mspec/lib/mspec/matchers/complain.rb b/spec/mspec/lib/mspec/matchers/complain.rb
index 19310c0bbb..887e72b4b0 100644
--- a/spec/mspec/lib/mspec/matchers/complain.rb
+++ b/spec/mspec/lib/mspec/matchers/complain.rb
@@ -19,6 +19,7 @@ class ComplainMatcher
@verbose = $VERBOSE
err = IOStub.new
+ Thread.current[:in_mspec_complain_matcher] = true
$stderr = err
$VERBOSE = @options.key?(:verbose) ? @options[:verbose] : false
begin
@@ -26,6 +27,7 @@ class ComplainMatcher
ensure
$VERBOSE = @verbose
$stderr = @saved_err
+ Thread.current[:in_mspec_complain_matcher] = false
end
@warning = err.to_s
diff --git a/spec/mspec/lib/mspec/runner/actions/timeout.rb b/spec/mspec/lib/mspec/runner/actions/timeout.rb
index 1200926872..543b7366d7 100644
--- a/spec/mspec/lib/mspec/runner/actions/timeout.rb
+++ b/spec/mspec/lib/mspec/runner/actions/timeout.rb
@@ -3,8 +3,6 @@ class TimeoutAction
@timeout = timeout
@queue = Queue.new
@started = now
- @fail = false
- @error_message = "took longer than the configured timeout of #{@timeout}s"
end
def register
@@ -39,26 +37,15 @@ class TimeoutAction
elapsed = now - @started
if elapsed > @timeout
if @current_state
- STDERR.puts "\nExample #{@error_message}:"
+ STDERR.puts "\nExample took longer than the configured timeout of #{@timeout}s:"
STDERR.puts "#{@current_state.description}"
else
- STDERR.puts "\nSome code outside an example #{@error_message}"
+ STDERR.puts "\nSome code outside an example took longer than the configured timeout of #{@timeout}s"
end
STDERR.flush
show_backtraces
- if MSpec.subprocesses.empty?
- exit! 2
- else
- # Do not exit but signal the subprocess so we can get their output
- MSpec.subprocesses.each do |pid|
- kill_wait_one_second :SIGTERM, pid
- hard_kill :SIGKILL, pid
- end
- @fail = true
- @current_state = nil
- break # stop this thread, will fail in #after
- end
+ exit 2
end
end
end
@@ -78,11 +65,6 @@ class TimeoutAction
@queue << -> do
@current_state = nil
end
-
- if @fail
- STDERR.puts "\n\nThe last example #{@error_message}. See above for the subprocess stacktrace."
- exit! 2
- end
end
def finish
@@ -90,54 +72,20 @@ class TimeoutAction
@thread.join
end
- private def hard_kill(signal, pid)
- begin
- Process.kill signal, pid
- rescue Errno::ESRCH
- # Process already terminated
- end
- end
-
- private def kill_wait_one_second(signal, pid)
- begin
- Process.kill signal, pid
+ private def show_backtraces
+ if RUBY_ENGINE == 'truffleruby'
+ STDERR.puts 'Java stacktraces:'
+ Process.kill :SIGQUIT, Process.pid
sleep 1
- rescue Errno::ESRCH
- # Process already terminated
end
- end
- private def show_backtraces
- java_stacktraces = -> pid {
- if RUBY_ENGINE == 'truffleruby' || RUBY_ENGINE == 'jruby'
- STDERR.puts 'Java stacktraces:'
- kill_wait_one_second :SIGQUIT, pid
- end
- }
-
- if MSpec.subprocesses.empty?
- java_stacktraces.call Process.pid
-
- STDERR.puts "\nRuby backtraces:"
- if defined?(Truffle::Debug.show_backtraces)
- Truffle::Debug.show_backtraces
- else
- Thread.list.each do |thread|
- unless thread == Thread.current
- STDERR.puts thread.inspect, thread.backtrace, ''
- end
- end
- end
+ STDERR.puts "\nRuby backtraces:"
+ if defined?(Truffle::Debug.show_backtraces)
+ Truffle::Debug.show_backtraces
else
- MSpec.subprocesses.each do |pid|
- STDERR.puts "\nFor subprocess #{pid}"
- java_stacktraces.call pid
-
- if RUBY_ENGINE == 'truffleruby'
- STDERR.puts "\nRuby backtraces:"
- kill_wait_one_second :SIGALRM, pid
- else
- STDERR.puts "Don't know how to print backtraces of a subprocess on #{RUBY_ENGINE}"
+ Thread.list.each do |thread|
+ unless thread == Thread.current
+ STDERR.puts thread.inspect, thread.backtrace, ''
end
end
end
diff --git a/spec/mspec/lib/mspec/runner/mspec.rb b/spec/mspec/lib/mspec/runner/mspec.rb
index 97c3f365bc..889e085175 100644
--- a/spec/mspec/lib/mspec/runner/mspec.rb
+++ b/spec/mspec/lib/mspec/runner/mspec.rb
@@ -38,10 +38,9 @@ module MSpec
@expectation = nil
@expectations = false
@skips = []
- @subprocesses = []
class << self
- attr_reader :file, :include, :exclude, :skips, :subprocesses
+ attr_reader :file, :include, :exclude, :skips
attr_writer :repeat, :randomize
attr_accessor :formatter
end
@@ -396,7 +395,7 @@ module MSpec
desc = tag.escape(tag.description)
file = tags_file
if File.exist? file
- lines = File.readlines(file)
+ lines = IO.readlines(file)
File.open(file, "w:utf-8") do |f|
lines.each do |line|
line = line.chomp
diff --git a/spec/mspec/lib/mspec/utils/options.rb b/spec/mspec/lib/mspec/utils/options.rb
index 3b5962dbe6..612caf6771 100644
--- a/spec/mspec/lib/mspec/utils/options.rb
+++ b/spec/mspec/lib/mspec/utils/options.rb
@@ -477,7 +477,7 @@ class MSpecOptions
def debug
on("-d", "--debug",
- "Disable MSpec backtrace filtering") do
+ "Set MSpec debugging flag for more verbose output") do
$MSPEC_DEBUG = true
end
end
diff --git a/spec/mspec/lib/mspec/utils/warnings.rb b/spec/mspec/lib/mspec/utils/warnings.rb
index 23efc696a5..0d3d36fada 100644
--- a/spec/mspec/lib/mspec/utils/warnings.rb
+++ b/spec/mspec/lib/mspec/utils/warnings.rb
@@ -8,3 +8,46 @@ if Object.const_defined?(:Warning) and Warning.respond_to?(:[]=)
Warning[:deprecated] = true
Warning[:experimental] = false
end
+
+if Object.const_defined?(:Warning) and Warning.respond_to?(:warn)
+ def Warning.warn(message, category: nil)
+ # Suppress any warning inside the method to prevent recursion
+ verbose = $VERBOSE
+ $VERBOSE = nil
+
+ if Thread.current[:in_mspec_complain_matcher]
+ return $stderr.write(message)
+ end
+
+ case message
+ # $VERBOSE = true warnings
+ when /(.+\.rb):(\d+):.+possibly useless use of (<|<=|==|>=|>) in void context/
+ # Make sure there is a .should otherwise it is missing
+ line_nb = Integer($2)
+ unless File.exist?($1) and /\.should(_not)? (<|<=|==|>=|>)/ === File.readlines($1)[line_nb-1]
+ $stderr.write message
+ end
+ when /possibly useless use of (\+|-) in void context/
+ when /assigned but unused variable/
+ when /method redefined/
+ when /previous definition of/
+ when /instance variable @.+ not initialized/
+ when /statement not reached/
+ when /shadowing outer local variable/
+ when /setting Encoding.default_(in|ex)ternal/
+ when /unknown (un)?pack directive/
+ when /(un)?trust(ed\?)? is deprecated/
+ when /\.exists\? is a deprecated name/
+ when /Float .+ out of range/
+ when /passing a block to String#(bytes|chars|codepoints|lines) is deprecated/
+ when /core\/string\/modulo_spec\.rb:\d+: warning: too many arguments for format string/
+ when /regexp\/shared\/new_ascii(_8bit)?\.rb:\d+: warning: Unknown escape .+ is ignored/
+ else
+ $stderr.write message
+ end
+ ensure
+ $VERBOSE = verbose
+ end
+else
+ $VERBOSE = nil unless ENV['OUTPUT_WARNINGS']
+end
diff --git a/spec/mspec/spec/commands/mspec_spec.rb b/spec/mspec/spec/commands/mspec_spec.rb
index d19bebb2d6..82201c2075 100644
--- a/spec/mspec/spec/commands/mspec_spec.rb
+++ b/spec/mspec/spec/commands/mspec_spec.rb
@@ -92,6 +92,33 @@ RSpec.describe MSpecMain, "#run" do
end
end
+RSpec.describe "The --warnings option" do
+ before :each do
+ @options, @config = new_option
+ allow(MSpecOptions).to receive(:new).and_return(@options)
+ @script = MSpecMain.new
+ allow(@script).to receive(:config).and_return(@config)
+ end
+
+ it "is enabled by #options" do
+ allow(@options).to receive(:on)
+ expect(@options).to receive(:on).with("--warnings", an_instance_of(String))
+ @script.options
+ end
+
+ it "sets flags to -w" do
+ @config[:flags] = []
+ @script.options ["--warnings"]
+ expect(@config[:flags]).to include("-w")
+ end
+
+ it "set OUTPUT_WARNINGS = '1' in the environment" do
+ ENV['OUTPUT_WARNINGS'] = '0'
+ @script.options ["--warnings"]
+ expect(ENV['OUTPUT_WARNINGS']).to eq('1')
+ end
+end
+
RSpec.describe "The -j, --multi option" do
before :each do
@options, @config = new_option
diff --git a/spec/mspec/spec/helpers/ruby_exe_spec.rb b/spec/mspec/spec/helpers/ruby_exe_spec.rb
index 56bade1ba9..61225a2756 100644
--- a/spec/mspec/spec/helpers/ruby_exe_spec.rb
+++ b/spec/mspec/spec/helpers/ruby_exe_spec.rb
@@ -145,7 +145,7 @@ RSpec.describe Object, "#ruby_exe" do
stub_const 'RUBY_EXE', 'ruby_spec_exe -w -Q'
@script = RubyExeSpecs.new
- allow(IO).to receive(:popen).and_return('OUTPUT')
+ allow(@script).to receive(:`).and_return('OUTPUT')
status_successful = double(Process::Status, exited?: true, exitstatus: 0)
allow(Process).to receive(:last_status).and_return(status_successful)
@@ -155,7 +155,7 @@ RSpec.describe Object, "#ruby_exe" do
code = "code"
options = {}
output = "output"
- expect(IO).to receive(:popen).and_return(output)
+ allow(@script).to receive(:`).and_return(output)
expect(@script.ruby_exe(code, options)).to eq output
end
@@ -168,7 +168,7 @@ RSpec.describe Object, "#ruby_exe" do
code = "code"
options = {}
expect(@script).to receive(:ruby_cmd).and_return("ruby_cmd")
- expect(IO).to receive(:popen).with("ruby_cmd")
+ expect(@script).to receive(:`).with("ruby_cmd")
@script.ruby_exe(code, options)
end
@@ -227,7 +227,7 @@ RSpec.describe Object, "#ruby_exe" do
expect(ENV).to receive(:[]=).with("ABC", "xyz")
expect(ENV).to receive(:[]=).with("ABC", "123")
- expect(IO).to receive(:popen).and_raise(Exception)
+ expect(@script).to receive(:`).and_raise(Exception)
expect do
@script.ruby_exe nil, :env => { :ABC => "xyz" }
end.to raise_error(Exception)
@@ -248,7 +248,7 @@ RSpec.describe Object, "#ruby_exe" do
it "does not raise exception when command ends with expected status" do
output = "output"
- expect(IO).to receive(:popen).and_return(output)
+ allow(@script).to receive(:`).and_return(output)
expect(@script.ruby_exe("path", exit_status: 4)).to eq output
end
diff --git a/spec/mspec/spec/runner/context_spec.rb b/spec/mspec/spec/runner/context_spec.rb
index 9ebc708c0c..a864428aec 100644
--- a/spec/mspec/spec/runner/context_spec.rb
+++ b/spec/mspec/spec/runner/context_spec.rb
@@ -914,7 +914,7 @@ RSpec.describe ContextState, "#it_should_behave_like" do
it "raises an Exception if unable to find the shared ContextState" do
expect(MSpec).to receive(:retrieve_shared).and_return(nil)
- expect { @state.it_should_behave_like :this }.to raise_error(Exception)
+ expect { @state.it_should_behave_like "this" }.to raise_error(Exception)
end
describe "for nested ContextState instances" do
diff --git a/spec/mspec/tool/check_require_spec_helper.rb b/spec/mspec/tool/check_require_spec_helper.rb
deleted file mode 100755
index 07126e68dc..0000000000
--- a/spec/mspec/tool/check_require_spec_helper.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env ruby
-
-# This script is used to check that each *_spec.rb file has
-# a relative_require for spec_helper which should live higher
-# up in the ruby/spec repo directory tree.
-#
-# Prints errors to $stderr and returns a non-zero exit code when
-# errors are found.
-#
-# Related to https://github.com/ruby/spec/pull/992
-
-def check_file(fn)
- File.foreach(fn) do |line|
- return $1 if line =~ /^\s*require_relative\s*['"](.*spec_helper)['"]/
- end
- nil
-end
-
-rootdir = ARGV[0] || "."
-fglob = File.join(rootdir, "**", "*_spec.rb")
-specfiles = Dir.glob(fglob)
-raise "No spec files found in #{fglob.inspect}. Give an argument to specify the root-directory of ruby/spec" if specfiles.empty?
-
-errors = 0
-specfiles.sort.each do |fn|
- result = check_file(fn)
- if result.nil?
- warn "Missing require_relative for *spec_helper for file: #{fn}"
- errors += 1
- end
-end
-
-puts "# Found #{errors} files with require_relative spec_helper issues."
-exit 1 if errors > 0
diff --git a/spec/mspec/tool/remove_old_guards.rb b/spec/mspec/tool/remove_old_guards.rb
index 3fd95e6b31..67485446bb 100644
--- a/spec/mspec/tool/remove_old_guards.rb
+++ b/spec/mspec/tool/remove_old_guards.rb
@@ -46,51 +46,6 @@ def remove_guards(guard, keep)
end
end
-def remove_empty_files
- each_spec_file do |file|
- unless file.include?("fixtures/")
- lines = File.readlines(file)
- if lines.all? { |line| line.chomp.empty? or line.start_with?('require', '#') }
- puts "Removing empty file #{file}"
- File.delete(file)
- end
- end
- end
-end
-
-def remove_unused_shared_specs
- shared_groups = {}
- # Dir["**/shared/**/*.rb"].each do |shared|
- each_spec_file do |shared|
- next if File.basename(shared) == 'constants.rb'
- contents = File.binread(shared)
- found = false
- contents.scan(/^\s*describe (:[\w_?]+), shared: true do$/) {
- shared_groups[$1] = 0
- found = true
- }
- if !found and shared.include?('shared/') and !shared.include?('fixtures/') and !shared.end_with?('/constants.rb')
- puts "no shared describe in #{shared} ?"
- end
- end
-
- each_spec_file do |file|
- contents = File.binread(file)
- contents.scan(/(?:it_behaves_like|it_should_behave_like) (:[\w_?]+)[,\s]/) do
- puts $1 unless shared_groups.key?($1)
- shared_groups[$1] += 1
- end
- end
-
- shared_groups.each_pair do |group, value|
- if value == 0
- puts "Shared describe #{group} seems unused"
- elsif value == 1
- puts "Shared describe #{group} seems used only once" if $VERBOSE
- end
- end
-end
-
def search(regexp)
each_spec_file do |file|
contents = File.binread(file)
@@ -109,11 +64,7 @@ version = Regexp.escape(ARGV.fetch(0))
version += "(?:\\.0)?" if version.count(".") < 2
remove_guards(/ruby_version_is (["'])#{version}\1 do/, true)
remove_guards(/ruby_version_is (["'])[0-9.]*\1 *... *(["'])#{version}\2 do/, false)
-remove_guards(/ruby_bug ["']#\d+["'], (["'])[0-9.]*\1 *... *(["'])#{version}\2 do/, true)
-
-remove_empty_files
-remove_unused_shared_specs
+remove_guards(/ruby_bug "#\d+", (["'])[0-9.]*\1 *... *(["'])#{version}\2 do/, true)
-puts "Search:"
search(/(["'])#{version}\1/)
search(/^\s*#.+#{version}/)
diff --git a/spec/mspec/tool/tag_from_output.rb b/spec/mspec/tool/tag_from_output.rb
index b6b4603855..a6e60945cd 100755
--- a/spec/mspec/tool/tag_from_output.rb
+++ b/spec/mspec/tool/tag_from_output.rb
@@ -3,8 +3,6 @@
# Adds tags based on error and failures output (e.g., from a CI log),
# without running any spec code.
-tag = ENV["TAG"] || "fails"
-
tags_dir = %w[
spec/tags
spec/tags/ruby
@@ -32,9 +30,9 @@ output.slice_before(NUMBER).select { |number, *rest|
if spec_file
spec_file = spec_file[SPEC_FILE, 1] or raise
else
- if error_line =~ /^([\w:]+)[#\.](\w+) /
- mod, method = $1, $2
- file = "#{mod.downcase.gsub('::', '/')}/#{method}_spec.rb"
+ if error_line =~ /^(\w+)[#\.](\w+) /
+ module_method = error_line.split(' ', 2).first
+ file = "#{$1.downcase}/#{$2}_spec.rb"
spec_file = ['spec/ruby/core', 'spec/ruby/library', *Dir.glob('spec/ruby/library/*')].find { |dir|
path = "#{dir}/#{file}"
break path if File.exist?(path)
@@ -56,7 +54,7 @@ output.slice_before(NUMBER).select { |number, *rest|
dir = File.dirname(tags_file)
Dir.mkdir(dir) unless Dir.exist?(dir)
- tag_line = "#{tag}:#{description}"
+ tag_line = "fails:#{description}"
lines = File.exist?(tags_file) ? File.readlines(tags_file, chomp: true) : []
unless lines.include?(tag_line)
puts tags_file
diff --git a/spec/ruby/.mspec.constants b/spec/ruby/.mspec.constants
index 6e09a44362..5dd477eb66 100644
--- a/spec/ruby/.mspec.constants
+++ b/spec/ruby/.mspec.constants
@@ -204,7 +204,6 @@ UserArray
UserCustomConstructorString
UserDefined
UserDefinedImmediate
-UserDefinedString
UserDefinedWithIvar
UserHash
UserHashInitParams
diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml
index 9ad57dd51c..82733c4b4d 100644
--- a/spec/ruby/.rubocop.yml
+++ b/spec/ruby/.rubocop.yml
@@ -1,7 +1,7 @@
inherit_from: .rubocop_todo.yml
AllCops:
- TargetRubyVersion: 3.0
+ TargetRubyVersion: 2.7
DisplayCopNames: true
Exclude:
- command_line/fixtures/bad_syntax.rb
@@ -33,10 +33,6 @@ Lint/AssignmentInCondition:
Lint/BooleanSymbol:
Enabled: false
-Lint/DeprecatedOpenSSLConstant:
- Exclude:
- - library/openssl/digest/**/*.rb
-
Lint/InterpolationCheck:
Enabled: false
diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml
index a59e64bd58..ac9cfae2bf 100644
--- a/spec/ruby/.rubocop_todo.yml
+++ b/spec/ruby/.rubocop_todo.yml
@@ -98,7 +98,6 @@ Lint/RescueException:
- 'core/dir/fileno_spec.rb'
- 'core/exception/cause_spec.rb'
- 'core/exception/no_method_error_spec.rb'
- - 'core/fiber/kill_spec.rb'
- 'core/kernel/fixtures/autoload_frozen.rb'
- 'core/kernel/raise_spec.rb'
- 'core/module/autoload_spec.rb'
diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md
index c82eb5ea4f..adfc2fb0ca 100644
--- a/spec/ruby/CONTRIBUTING.md
+++ b/spec/ruby/CONTRIBUTING.md
@@ -138,12 +138,12 @@ Here is a list of the most commonly-used guards:
#### Version guards
```ruby
-ruby_version_is ""..."3.2" do
- # Specs for RUBY_VERSION < 3.2
+ruby_version_is ""..."2.6" do
+ # Specs for RUBY_VERSION < 2.6
end
-ruby_version_is "3.2" do
- # Specs for RUBY_VERSION >= 3.2
+ruby_version_is "2.6" do
+ # Specs for RUBY_VERSION >= 2.6
end
```
@@ -179,7 +179,6 @@ In case there is a bug in MRI and the fix will be backported to previous version
If it is not backported or not likely, use `ruby_version_is` instead.
First, file a bug at https://bugs.ruby-lang.org/.
The problem is `ruby_bug` would make non-MRI implementations fail this spec while MRI itself does not pass it, so it should only be used if the bug is/will be fixed and backported.
-Otherwise, non-MRI implementations would have to choose between being incompatible with the latest release of MRI to pass the spec or fail the spec, both which make no sense.
```ruby
ruby_bug '#13669', ''...'3.2' do
@@ -192,11 +191,11 @@ end
#### Combining guards
```ruby
-guard -> { platform_is :windows and ruby_version_is ""..."3.2" } do
- # Windows and RUBY_VERSION < 3.2
+guard -> { platform_is :windows and ruby_version_is ""..."2.6" } do
+ # Windows and RUBY_VERSION < 2.6
end
-guard_not -> { platform_is :windows and ruby_version_is ""..."3.2" } do
+guard_not -> { platform_is :windows and ruby_version_is ""..."2.6" } do
# The opposite
end
```
diff --git a/spec/ruby/README.md b/spec/ruby/README.md
index 115392835f..018bf0ca3e 100644
--- a/spec/ruby/README.md
+++ b/spec/ruby/README.md
@@ -30,8 +30,8 @@ ruby/spec is known to be tested in these implementations for every commit:
* [Opal](https://github.com/opal/opal/tree/master/spec)
* [Artichoke](https://github.com/artichoke/spec/tree/artichoke-vendor)
-ruby/spec describes the behavior of Ruby 3.0 and more recent Ruby versions.
-More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (3.0.x, 3.1.x, 3.2.x, etc), and those are tested in CI.
+ruby/spec describes the behavior of Ruby 2.7 and more recent Ruby versions.
+More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (2.7.x, 3.0.x, 3.1.x, etc), and those are tested in CI.
### Synchronization with Ruby Implementations
@@ -61,7 +61,6 @@ For older specs try these commits:
* Ruby 2.4.10 - [Suite](https://github.com/ruby/spec/commit/bce4f2b81d6c31db67cf4d023a0625ceadde59bd) using [MSpec](https://github.com/ruby/mspec/commit/e7eb8aa4c26495b7b461e687d950b96eb08b3ff2)
* Ruby 2.5.9 - [Suite](https://github.com/ruby/spec/commit/c503335d3d9f6ec6ef24de60a0716c34af69b64f) using [MSpec](https://github.com/ruby/mspec/commit/0091e8a62e954717cd54641f935eaf1403692041)
* Ruby 2.6.10 - [Suite](https://github.com/ruby/spec/commit/aaf998fb8c92c4e63ad423a2e7ca6e6921818c6e) using [MSpec](https://github.com/ruby/mspec/commit/5e36c684e9e2b92b1187589bba1df22c640a8661)
-* Ruby 2.7.8 - [Suite](https://github.com/ruby/spec/commit/93787e6035c925b593a9c0c6fb0e7e07a6f1df1f) using [MSpec](https://github.com/ruby/mspec/commit/1d8cf64722d8a7529f7cd205be5f16a89b7a67fd)
### Running the specs
@@ -128,12 +127,6 @@ MSpec can automatically add new top-level constants in this file with:
$ CHECK_LEAKS=save mspec ../mspec/bin/mspec file
-### Running Specs on S390x CPU Architecture
-
-Run the specs with `DFLTCC=0` if you see failing specs related to the zlib library on s390x CPU architecture. The failures can happen with the zlib library applying the patch madler/zlib#410 to enable the deflate algorithm producing a different compressed byte stream.
-
- $ DFLTCC=0 ../mspec/bin/mspec
-
### Contributing and Writing Specs
See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md) for documentation about contributing and writing specs (guards, matchers, etc).
diff --git a/spec/ruby/command_line/backtrace_limit_spec.rb b/spec/ruby/command_line/backtrace_limit_spec.rb
index bc40a542a0..56afa8efef 100644
--- a/spec/ruby/command_line/backtrace_limit_spec.rb
+++ b/spec/ruby/command_line/backtrace_limit_spec.rb
@@ -1,46 +1,48 @@
require_relative '../spec_helper'
-describe "The --backtrace-limit command line option" do
- it "limits top-level backtraces to a given number of entries" do
- file = fixture(__FILE__ , "backtrace.rb")
- out = ruby_exe(file, options: "--backtrace-limit=2", args: "top 2>&1", exit_status: 1)
- out = out.gsub(__dir__, '')
+ruby_version_is "3.0" do
+ describe "The --backtrace-limit command line option" do
+ it "limits top-level backtraces to a given number of entries" do
+ file = fixture(__FILE__ , "backtrace.rb")
+ out = ruby_exe(file, options: "--backtrace-limit=2", args: "top 2>&1", exit_status: 1)
+ out = out.gsub(__dir__, '')
- out.should == <<-MSG
+ out.should == <<-MSG
top
/fixtures/backtrace.rb:2:in `a': oops (RuntimeError)
\tfrom /fixtures/backtrace.rb:6:in `b'
\tfrom /fixtures/backtrace.rb:10:in `c'
\t ... 2 levels...
- MSG
- end
+ MSG
+ end
- it "affects Exception#full_message" do
- file = fixture(__FILE__ , "backtrace.rb")
- out = ruby_exe(file, options: "--backtrace-limit=2", args: "full_message 2>&1")
- out = out.gsub(__dir__, '')
+ it "affects Exception#full_message" do
+ file = fixture(__FILE__ , "backtrace.rb")
+ out = ruby_exe(file, options: "--backtrace-limit=2", args: "full_message 2>&1")
+ out = out.gsub(__dir__, '')
- out.should == <<-MSG
+ out.should == <<-MSG
full_message
/fixtures/backtrace.rb:2:in `a': oops (RuntimeError)
\tfrom /fixtures/backtrace.rb:6:in `b'
\tfrom /fixtures/backtrace.rb:10:in `c'
\t ... 2 levels...
- MSG
- end
+ MSG
+ end
- it "does not affect Exception#backtrace" do
- file = fixture(__FILE__ , "backtrace.rb")
- out = ruby_exe(file, options: "--backtrace-limit=2", args: "backtrace 2>&1")
- out = out.gsub(__dir__, '')
+ it "does not affect Exception#backtrace" do
+ file = fixture(__FILE__ , "backtrace.rb")
+ out = ruby_exe(file, options: "--backtrace-limit=2", args: "backtrace 2>&1")
+ out = out.gsub(__dir__, '')
- out.should == <<-MSG
+ out.should == <<-MSG
backtrace
/fixtures/backtrace.rb:2:in `a'
/fixtures/backtrace.rb:6:in `b'
/fixtures/backtrace.rb:10:in `c'
/fixtures/backtrace.rb:14:in `d'
/fixtures/backtrace.rb:29:in `<main>'
- MSG
+ MSG
+ end
end
end
diff --git a/spec/ruby/command_line/dash_a_spec.rb b/spec/ruby/command_line/dash_a_spec.rb
index 43d923ce16..9ea135dc76 100644
--- a/spec/ruby/command_line/dash_a_spec.rb
+++ b/spec/ruby/command_line/dash_a_spec.rb
@@ -6,13 +6,13 @@ describe "The -a command line option" do
end
it "runs the code in loop conditional on Kernel.gets()" do
- ruby_exe("puts $F.last", options: "-n -a",
+ ruby_exe("puts $F.last", options: "-n -a", escape: true,
args: " < #{@names}").should ==
"jones\nfield\ngrey\n"
end
it "sets $-a" do
- ruby_exe("puts $-a", options: "-n -a",
+ ruby_exe("puts $-a", options: "-n -a", escape: true,
args: " < #{@names}").should ==
"true\ntrue\ntrue\n"
end
diff --git a/spec/ruby/command_line/dash_l_spec.rb b/spec/ruby/command_line/dash_l_spec.rb
index 44a98445f3..5c1d3cf4cd 100644
--- a/spec/ruby/command_line/dash_l_spec.rb
+++ b/spec/ruby/command_line/dash_l_spec.rb
@@ -6,25 +6,25 @@ describe "The -l command line option" do
end
it "chomps lines with default separator" do
- ruby_exe('puts $_.end_with?("\n")', options: "-n -l",
+ ruby_exe('puts $_.end_with?("\n")', options: "-n -l", escape: true,
args: " < #{@names}").should ==
"false\nfalse\nfalse\n"
end
it "chomps last line based on $/" do
- ruby_exe('BEGIN { $/ = "ones\n" }; puts $_', options: "-W0 -n -l",
+ ruby_exe('BEGIN { $/ = "ones\n" }; puts $_', options: "-W0 -n -l", escape: true,
args: " < #{@names}").should ==
"alice j\nbob field\njames grey\n"
end
it "sets $\\ to the value of $/" do
- ruby_exe("puts $\\ == $/", options: "-W0 -n -l",
+ ruby_exe("puts $\\ == $/", options: "-W0 -n -l", escape: true,
args: " < #{@names}").should ==
"true\ntrue\ntrue\n"
end
it "sets $-l" do
- ruby_exe("puts $-l", options: "-n -l",
+ ruby_exe("puts $-l", options: "-n -l", escape: true,
args: " < #{@names}").should ==
"true\ntrue\ntrue\n"
end
diff --git a/spec/ruby/command_line/dash_n_spec.rb b/spec/ruby/command_line/dash_n_spec.rb
index 1dd9379259..9d331d6065 100644
--- a/spec/ruby/command_line/dash_n_spec.rb
+++ b/spec/ruby/command_line/dash_n_spec.rb
@@ -6,19 +6,19 @@ describe "The -n command line option" do
end
it "runs the code in loop conditional on Kernel.gets()" do
- ruby_exe("puts $_", options: "-n",
+ ruby_exe("puts $_", options: "-n", escape: true,
args: " < #{@names}").should ==
"alice\nbob\njames\n"
end
it "only evaluates BEGIN blocks once" do
- ruby_exe("BEGIN { puts \"hi\" }; puts $_", options: "-n",
+ ruby_exe("BEGIN { puts \"hi\" }; puts $_", options: "-n", escape: true,
args: " < #{@names}").should ==
"hi\nalice\nbob\njames\n"
end
it "only evaluates END blocks once" do
- ruby_exe("puts $_; END {puts \"bye\"}", options: "-n",
+ ruby_exe("puts $_; END {puts \"bye\"}", options: "-n", escape: true,
args: " < #{@names}").should ==
"alice\nbob\njames\nbye\n"
end
@@ -29,7 +29,7 @@ describe "The -n command line option" do
$total += 1
END { puts $total }
script
- ruby_exe(script, options: "-n",
+ ruby_exe(script, options: "-n", escape: true,
args: " < #{@names}").should ==
"3\n"
end
diff --git a/spec/ruby/command_line/dash_p_spec.rb b/spec/ruby/command_line/dash_p_spec.rb
index 967e3796de..39827c3868 100644
--- a/spec/ruby/command_line/dash_p_spec.rb
+++ b/spec/ruby/command_line/dash_p_spec.rb
@@ -6,13 +6,13 @@ describe "The -p command line option" do
end
it "runs the code in loop conditional on Kernel.gets() and prints $_" do
- ruby_exe("$_ = $_.upcase", options: "-p",
+ ruby_exe("$_ = $_.upcase", options: "-p", escape: true,
args: " < #{@names}").should ==
"ALICE\nBOB\nJAMES\n"
end
it "sets $-p" do
- ruby_exe("$_ = $-p", options: "-p",
+ ruby_exe("$_ = $-p", options: "-p", escape: true,
args: " < #{@names}").should ==
"truetruetrue"
end
diff --git a/spec/ruby/command_line/dash_upper_f_spec.rb b/spec/ruby/command_line/dash_upper_f_spec.rb
index 5c10a7140d..967acc2ece 100644
--- a/spec/ruby/command_line/dash_upper_f_spec.rb
+++ b/spec/ruby/command_line/dash_upper_f_spec.rb
@@ -6,7 +6,7 @@ describe "the -F command line option" do
end
it "specifies the field separator pattern for -a" do
- ruby_exe("puts $F[0]", options: "-naF:",
+ ruby_exe("puts $F[0]", options: "-naF:", escape: true,
args: " < #{@passwd}").should ==
"nobody\nroot\ndaemon\n"
end
diff --git a/spec/ruby/command_line/dash_upper_u_spec.rb b/spec/ruby/command_line/dash_upper_u_spec.rb
index 15854e7b73..d62718b095 100644
--- a/spec/ruby/command_line/dash_upper_u_spec.rb
+++ b/spec/ruby/command_line/dash_upper_u_spec.rb
@@ -6,13 +6,6 @@ describe "ruby -U" do
options: '-U').should == 'UTF-8'
end
- it "sets Encoding.default_internal to UTF-8 when RUBYOPT is empty or only spaces" do
- ruby_exe('p Encoding.default_internal',
- options: '-U', env: { 'RUBYOPT' => '' }).should == "#<Encoding:UTF-8>\n"
- ruby_exe('p Encoding.default_internal',
- options: '-U', env: { 'RUBYOPT' => ' ' }).should == "#<Encoding:UTF-8>\n"
- end
-
it "does nothing different if specified multiple times" do
ruby_exe('print Encoding.default_internal.name',
options: '-U -U').should == 'UTF-8'
diff --git a/spec/ruby/command_line/dash_v_spec.rb b/spec/ruby/command_line/dash_v_spec.rb
index 7c7ca1bca6..a4f4dcd051 100644
--- a/spec/ruby/command_line/dash_v_spec.rb
+++ b/spec/ruby/command_line/dash_v_spec.rb
@@ -8,7 +8,6 @@ describe "The -v command line option" do
it "prints version and ends" do
ruby_exe(nil, args: '-v').should include(RUBY_DESCRIPTION)
end unless (defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?) ||
- (defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?) ||
- (ENV['RUBY_MN_THREADS'] == '1')
+ (defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?)
end
end
diff --git a/spec/ruby/command_line/fixtures/bin/embedded_ruby.txt b/spec/ruby/command_line/fixtures/bin/embedded_ruby.txt
index 1da779b1b9..c556bf0b71 100644
--- a/spec/ruby/command_line/fixtures/bin/embedded_ruby.txt
+++ b/spec/ruby/command_line/fixtures/bin/embedded_ruby.txt
@@ -1,3 +1,3 @@
@@@This line is not value Ruby
#!ruby
-puts 'success'
+puts 'success' \ No newline at end of file
diff --git a/spec/ruby/command_line/fixtures/freeze_flag_required_diff_enc.rb b/spec/ruby/command_line/fixtures/freeze_flag_required_diff_enc.rb
index df4b952c46..fa348d59e7 100644
--- a/spec/ruby/command_line/fixtures/freeze_flag_required_diff_enc.rb
+++ b/spec/ruby/command_line/fixtures/freeze_flag_required_diff_enc.rb
Binary files differ
diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb
index 734db8d519..bbea4d557d 100644
--- a/spec/ruby/command_line/rubyopt_spec.rb
+++ b/spec/ruby/command_line/rubyopt_spec.rb
@@ -11,14 +11,14 @@ describe "Processing RUBYOPT" do
it "adds the -I path to $LOAD_PATH" do
ENV["RUBYOPT"] = "-Ioptrubyspecincl"
- result = ruby_exe("puts $LOAD_PATH.grep(/byspecin/)")
+ result = ruby_exe("puts $LOAD_PATH.grep(/byspecin/)", escape: true)
result.chomp[-15..-1].should == "optrubyspecincl"
end
it "sets $DEBUG to true for '-d'" do
ENV["RUBYOPT"] = '-d'
command = %[puts "value of $DEBUG is \#{$DEBUG}"]
- result = ruby_exe(command, args: "2>&1")
+ result = ruby_exe(command, escape: true, args: "2>&1")
result.should =~ /value of \$DEBUG is true/
end
@@ -36,27 +36,27 @@ describe "Processing RUBYOPT" do
it "sets $VERBOSE to true for '-w'" do
ENV["RUBYOPT"] = '-w'
- ruby_exe("p $VERBOSE").chomp.should == "true"
+ ruby_exe("p $VERBOSE", escape: true).chomp.should == "true"
end
it "sets $VERBOSE to true for '-W'" do
ENV["RUBYOPT"] = '-W'
- ruby_exe("p $VERBOSE").chomp.should == "true"
+ ruby_exe("p $VERBOSE", escape: true).chomp.should == "true"
end
it "sets $VERBOSE to nil for '-W0'" do
ENV["RUBYOPT"] = '-W0'
- ruby_exe("p $VERBOSE").chomp.should == "nil"
+ ruby_exe("p $VERBOSE", escape: true).chomp.should == "nil"
end
it "sets $VERBOSE to false for '-W1'" do
ENV["RUBYOPT"] = '-W1'
- ruby_exe("p $VERBOSE").chomp.should == "false"
+ ruby_exe("p $VERBOSE", escape: true).chomp.should == "false"
end
it "sets $VERBOSE to true for '-W2'" do
ENV["RUBYOPT"] = '-W2'
- ruby_exe("p $VERBOSE").chomp.should == "true"
+ ruby_exe("p $VERBOSE", escape: true).chomp.should == "true"
end
it "suppresses deprecation warnings for '-W:no-deprecated'" do
diff --git a/spec/ruby/core/argf/bytes_spec.rb b/spec/ruby/core/argf/bytes_spec.rb
new file mode 100644
index 0000000000..bf35ded1db
--- /dev/null
+++ b/spec/ruby/core/argf/bytes_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_byte'
+
+ruby_version_is ''...'3.0' do
+ describe "ARGF.bytes" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :argf_each_byte, :bytes
+ end
+end
diff --git a/spec/ruby/core/argf/chars_spec.rb b/spec/ruby/core/argf/chars_spec.rb
new file mode 100644
index 0000000000..6af73cdabb
--- /dev/null
+++ b/spec/ruby/core/argf/chars_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_char'
+
+ruby_version_is ''...'3.0' do
+ describe "ARGF.chars" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :argf_each_char, :chars
+ end
+end
diff --git a/spec/ruby/core/argf/codepoints_spec.rb b/spec/ruby/core/argf/codepoints_spec.rb
new file mode 100644
index 0000000000..bb28c17fbb
--- /dev/null
+++ b/spec/ruby/core/argf/codepoints_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_codepoint'
+
+ruby_version_is ''...'3.0' do
+ describe "ARGF.codepoints" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :argf_each_codepoint, :codepoints
+ end
+end
diff --git a/spec/ruby/core/argf/lines_spec.rb b/spec/ruby/core/argf/lines_spec.rb
new file mode 100644
index 0000000000..e964dbd0d3
--- /dev/null
+++ b/spec/ruby/core/argf/lines_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+require_relative 'shared/each_line'
+
+ruby_version_is ''...'3.0' do
+ describe "ARGF.lines" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :argf_each_line, :lines
+ end
+end
diff --git a/spec/ruby/core/argf/readpartial_spec.rb b/spec/ruby/core/argf/readpartial_spec.rb
index bbc8831131..5e284b3423 100644
--- a/spec/ruby/core/argf/readpartial_spec.rb
+++ b/spec/ruby/core/argf/readpartial_spec.rb
@@ -69,7 +69,7 @@ describe "ARGF.readpartial" do
print ARGF.readpartial(#{@stdin.size})
ARGF.readpartial(1) rescue print $!.class
STR
- stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}")
+ stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}", escape: true)
stdin.should == @stdin + "EOFError"
end
end
diff --git a/spec/ruby/core/array/all_spec.rb b/spec/ruby/core/array/all_spec.rb
deleted file mode 100644
index 680e8c26fa..0000000000
--- a/spec/ruby/core/array/all_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
-
-describe "Array#all?" do
- @value_to_return = -> _ { true }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :all?
-
- it "ignores the block if there is an argument" do
- -> {
- ['bar', 'foobar'].all?(/bar/) { false }.should == true
- }.should complain(/given block not used/)
- end
-end
diff --git a/spec/ruby/core/array/any_spec.rb b/spec/ruby/core/array/any_spec.rb
index b51ce62f0f..09d949fe6e 100644
--- a/spec/ruby/core/array/any_spec.rb
+++ b/spec/ruby/core/array/any_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#any?" do
describe 'with no block given (a default block of { |x| x } is implicit)' do
@@ -20,9 +19,6 @@ describe "Array#any?" do
end
describe 'with a block given' do
- @value_to_return = -> _ { false }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :any?
-
it 'is false if the array is empty' do
empty_array = []
empty_array.any? {|v| 1 == 1 }.should == false
@@ -38,12 +34,4 @@ describe "Array#any?" do
array_with_members.any? {|v| v == 42 }.should == false
end
end
-
- describe 'when given a pattern argument' do
- it "ignores the block if there is an argument" do
- -> {
- ['bar', 'foobar'].any?(/bar/) { false }.should == true
- }.should complain(/given block not used/)
- end
- end
end
diff --git a/spec/ruby/core/array/assoc_spec.rb b/spec/ruby/core/array/assoc_spec.rb
index f0be3de795..f8479d763c 100644
--- a/spec/ruby/core/array/assoc_spec.rb
+++ b/spec/ruby/core/array/assoc_spec.rb
@@ -6,7 +6,7 @@ describe "Array#assoc" do
s1 = ["colors", "red", "blue", "green"]
s2 = [:letters, "a", "b", "c"]
s3 = [4]
- s4 = ["colors", "cyan", "yellow", "magenta"]
+ s4 = ["colors", "cyan", "yellow", "magenda"]
s5 = [:letters, "a", "i", "u"]
s_nil = [nil, nil]
a = [s1, s2, s3, s4, s5, s_nil]
@@ -37,16 +37,4 @@ describe "Array#assoc" do
a.assoc(s1.first).should equal(s1)
a.assoc(s2.first).should equal(s2)
end
-
- it "calls to_ary on non-array elements" do
- s1 = [1, 2]
- s2 = ArraySpecs::ArrayConvertible.new(2, 3)
- a = [s1, s2]
-
- s1.should_not_receive(:to_ary)
- a.assoc(s1.first).should equal(s1)
-
- a.assoc(2).should == [2, 3]
- s2.called.should equal(:to_ary)
- end
end
diff --git a/spec/ruby/core/array/bsearch_index_spec.rb b/spec/ruby/core/array/bsearch_index_spec.rb
index 94d85b37f3..df2c7c098e 100644
--- a/spec/ruby/core/array/bsearch_index_spec.rb
+++ b/spec/ruby/core/array/bsearch_index_spec.rb
@@ -63,6 +63,10 @@ describe "Array#bsearch_index" do
@array.bsearch_index { |x| -1 }.should be_nil
end
+ it "returns the middle element when block always returns zero" do
+ @array.bsearch_index { |x| 0 }.should == 2
+ end
+
context "magnitude does not effect the result" do
it "returns the index of any matched elements where element is between 4n <= xn < 8n" do
[1, 2].should include(@array.bsearch_index { |x| (1 - x / 4) * (2**100) })
diff --git a/spec/ruby/core/array/count_spec.rb b/spec/ruby/core/array/count_spec.rb
index e778233c16..eaf275aeb7 100644
--- a/spec/ruby/core/array/count_spec.rb
+++ b/spec/ruby/core/array/count_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#count" do
it "returns the number of elements" do
@@ -13,14 +12,4 @@ describe "Array#count" do
it "returns the number of element for which the block evaluates to true" do
[:a, :b, :c].count { |s| s != :b }.should == 2
end
-
- it "ignores the block if there is an argument" do
- -> {
- [:a, :b, :b, :c].count(:b) { |e| e.size > 10 }.should == 2
- }.should complain(/given block not used/)
- end
-
- context "when a block argument given" do
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :count
- end
end
diff --git a/spec/ruby/core/array/delete_if_spec.rb b/spec/ruby/core/array/delete_if_spec.rb
index 10972eee0e..1459cc8d04 100644
--- a/spec/ruby/core/array/delete_if_spec.rb
+++ b/spec/ruby/core/array/delete_if_spec.rb
@@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/enumeratorize'
require_relative 'shared/delete_if'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
require_relative '../enumerable/shared/enumeratorized'
describe "Array#delete_if" do
@@ -48,35 +47,6 @@ describe "Array#delete_if" do
-> { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(FrozenError)
end
- it "does not truncate the array is the block raises an exception" do
- a = [1, 2, 3]
- begin
- a.delete_if { raise StandardError, 'Oops' }
- rescue
- end
-
- a.should == [1, 2, 3]
- end
-
- it "only removes elements for which the block returns true, keeping the element which raised an error." do
- a = [1, 2, 3, 4]
- begin
- a.delete_if do |e|
- case e
- when 2 then true
- when 3 then raise StandardError, 'Oops'
- else false
- end
- end
- rescue StandardError
- end
-
- a.should == [1, 3, 4]
- end
-
it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3]
it_behaves_like :delete_if, :delete_if
-
- @value_to_return = -> _ { false }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :delete_if
end
diff --git a/spec/ruby/core/array/drop_spec.rb b/spec/ruby/core/array/drop_spec.rb
index 0ea748e47d..f911fd9018 100644
--- a/spec/ruby/core/array/drop_spec.rb
+++ b/spec/ruby/core/array/drop_spec.rb
@@ -50,7 +50,15 @@ describe "Array#drop" do
-> { [1, 2].drop(obj) }.should raise_error(TypeError)
end
- it 'returns a Array instance for Array subclasses' do
- ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(Array)
+ end
end
end
diff --git a/spec/ruby/core/array/drop_while_spec.rb b/spec/ruby/core/array/drop_while_spec.rb
index bd46e8b882..bb783d22a5 100644
--- a/spec/ruby/core/array/drop_while_spec.rb
+++ b/spec/ruby/core/array/drop_while_spec.rb
@@ -1,11 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#drop_while" do
- @value_to_return = -> _ { true }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :drop_while
-
it "removes elements from the start of the array while the block evaluates to true" do
[1, 2, 3, 4].drop_while { |n| n < 4 }.should == [4]
end
@@ -18,7 +14,15 @@ describe "Array#drop_while" do
[1, 2, 3, false, 5].drop_while { |n| n }.should == [false, 5]
end
- it 'returns a Array instance for Array subclasses' do
- ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(Array)
+ end
end
end
diff --git a/spec/ruby/core/array/each_index_spec.rb b/spec/ruby/core/array/each_index_spec.rb
index 3a4bca9251..51af5842c4 100644
--- a/spec/ruby/core/array/each_index_spec.rb
+++ b/spec/ruby/core/array/each_index_spec.rb
@@ -5,7 +5,7 @@ require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
-# https://blade.ruby-lang.org/ruby-core/23633
+# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633
describe "Array#each_index" do
before :each do
@@ -40,19 +40,3 @@ describe "Array#each_index" do
it_behaves_like :enumeratorize, :each_index
it_behaves_like :enumeratorized_with_origin_size, :each_index, [1,2,3]
end
-
-describe "Array#each_index" do
- it "tolerates increasing an array size during iteration" do
- array = [:a, :b, :c]
- ScratchPad.record []
- i = 0
-
- array.each_index do |index|
- ScratchPad << index
- array << i if i < 100
- i += 1
- end
-
- ScratchPad.recorded.should == (0..102).to_a # element indices
- end
-end
diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb
index 57d6082f01..cf8e9da6d8 100644
--- a/spec/ruby/core/array/each_spec.rb
+++ b/spec/ruby/core/array/each_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/enumeratorize'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
require_relative '../enumerable/shared/enumeratorized'
# Mutating the array while it is being iterated is discouraged as it can result in confusing behavior.
@@ -76,7 +75,3 @@ describe "Array#each" do
it_behaves_like :enumeratorize, :each
it_behaves_like :enumeratorized_with_origin_size, :each, [1,2,3]
end
-
-describe "Array#each" do
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :each
-end
diff --git a/spec/ruby/core/array/fill_spec.rb b/spec/ruby/core/array/fill_spec.rb
index 02360e550d..23728414be 100644
--- a/spec/ruby/core/array/fill_spec.rb
+++ b/spec/ruby/core/array/fill_spec.rb
@@ -52,9 +52,11 @@ describe "Array#fill" do
end
it "raises an ArgumentError if 4 or more arguments are passed when no block given" do
- [].fill('a').should == []
- [].fill('a', 1).should == []
- [].fill('a', 1, 2).should == [nil, 'a', 'a']
+ -> { [].fill('a') }.should_not raise_error(ArgumentError)
+
+ -> { [].fill('a', 1) }.should_not raise_error(ArgumentError)
+
+ -> { [].fill('a', 1, 2) }.should_not raise_error(ArgumentError)
-> { [].fill('a', 1, 2, true) }.should raise_error(ArgumentError)
end
@@ -63,52 +65,12 @@ describe "Array#fill" do
end
it "raises an ArgumentError if 3 or more arguments are passed when a block given" do
- [].fill() {|i|}.should == []
- [].fill(1) {|i|}.should == []
- [].fill(1, 2) {|i|}.should == [nil, nil, nil]
- -> { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError)
- end
-
- it "does not truncate the array is the block raises an exception" do
- a = [1, 2, 3]
- begin
- a.fill { raise StandardError, 'Oops' }
- rescue
- end
+ -> { [].fill() {|i|} }.should_not raise_error(ArgumentError)
- a.should == [1, 2, 3]
- end
-
- it "only changes elements before error is raised, keeping the element which raised an error." do
- a = [1, 2, 3, 4]
- begin
- a.fill do |i|
- case i
- when 0 then -1
- when 1 then -2
- when 2 then raise StandardError, 'Oops'
- else 0
- end
- end
- rescue StandardError
- end
-
- a.should == [-1, -2, 3, 4]
- end
-
- it "tolerates increasing an array size during iteration" do
- array = [:a, :b, :c]
- ScratchPad.record []
- i = 0
+ -> { [].fill(1) {|i|} }.should_not raise_error(ArgumentError)
- array.fill do |index|
- ScratchPad << index
- array << i if i < 100
- i++
- index
- end
-
- ScratchPad.recorded.should == [0, 1, 2]
+ -> { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError)
+ -> { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError)
end
end
@@ -207,25 +169,25 @@ describe "Array#fill with (filler, index, length)" do
[1, 2, 3, 4, 5].fill(-2, -2, &@never_passed).should == [1, 2, 3, 4, 5]
end
- # See: https://blade.ruby-lang.org/ruby-core/17481
+ # See: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17481
it "does not raise an exception if the given length is negative and its absolute value does not exceed the index" do
- [1, 2, 3, 4].fill('a', 3, -1).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill('a', 3, -2).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill('a', 3, -3).should == [1, 2, 3, 4]
+ -> { [1, 2, 3, 4].fill('a', 3, -1)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -2)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -3)}.should_not raise_error(ArgumentError)
- [1, 2, 3, 4].fill(3, -1, &@never_passed).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill(3, -2, &@never_passed).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill(3, -3, &@never_passed).should == [1, 2, 3, 4]
+ -> { [1, 2, 3, 4].fill(3, -1, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -2, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -3, &@never_passed)}.should_not raise_error(ArgumentError)
end
it "does not raise an exception even if the given length is negative and its absolute value exceeds the index" do
- [1, 2, 3, 4].fill('a', 3, -4).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill('a', 3, -5).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill('a', 3, -10000).should == [1, 2, 3, 4]
+ -> { [1, 2, 3, 4].fill('a', 3, -4)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -5)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill('a', 3, -10000)}.should_not raise_error(ArgumentError)
- [1, 2, 3, 4].fill(3, -4, &@never_passed).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill(3, -5, &@never_passed).should == [1, 2, 3, 4]
- [1, 2, 3, 4].fill(3, -10000, &@never_passed).should == [1, 2, 3, 4]
+ -> { [1, 2, 3, 4].fill(3, -4, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -5, &@never_passed)}.should_not raise_error(ArgumentError)
+ -> { [1, 2, 3, 4].fill(3, -10000, &@never_passed)}.should_not raise_error(ArgumentError)
end
it "tries to convert the second and third arguments to Integers using #to_int" do
diff --git a/spec/ruby/core/array/fixtures/classes.rb b/spec/ruby/core/array/fixtures/classes.rb
index 8596245fb8..aa5fecd96b 100644
--- a/spec/ruby/core/array/fixtures/classes.rb
+++ b/spec/ruby/core/array/fixtures/classes.rb
@@ -160,16 +160,6 @@ module ArraySpecs
end
end
- class ArrayMethodMissing
- def initialize(*values, &block)
- @values = values;
- end
-
- def method_missing(name, *args)
- @values
- end
- end
-
class SortSame
def <=>(other); 0; end
def ==(other); true; end
diff --git a/spec/ruby/core/array/flatten_spec.rb b/spec/ruby/core/array/flatten_spec.rb
index 8c97000c79..1770b5389a 100644
--- a/spec/ruby/core/array/flatten_spec.rb
+++ b/spec/ruby/core/array/flatten_spec.rb
@@ -75,12 +75,24 @@ describe "Array#flatten" do
[[obj]].flatten(1)
end
- it "returns Array instance for Array subclasses" do
- ArraySpecs::MyArray[].flatten.should be_an_instance_of(Array)
- ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(Array)
- ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(Array)
- ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == [1, 2, 3, 4]
- [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instance for Array subclasses" do
+ ArraySpecs::MyArray[].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+ ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+ ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+ ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == ArraySpecs::MyArray[1, 2, 3, 4]
+ [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns Array instance for Array subclasses" do
+ ArraySpecs::MyArray[].flatten.should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(Array)
+ ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == [1, 2, 3, 4]
+ [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+ end
end
it "is not destructive" do
diff --git a/spec/ruby/core/array/initialize_spec.rb b/spec/ruby/core/array/initialize_spec.rb
index b9fa77b16e..a8deed2b84 100644
--- a/spec/ruby/core/array/initialize_spec.rb
+++ b/spec/ruby/core/array/initialize_spec.rb
@@ -53,9 +53,7 @@ describe "Array#initialize with no arguments" do
end
it "does not use the given block" do
- -> {
- -> { [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
- }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)
+ ->{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error
end
end
diff --git a/spec/ruby/core/array/intersect_spec.rb b/spec/ruby/core/array/intersect_spec.rb
index 62ac157278..b8c5b1e69a 100644
--- a/spec/ruby/core/array/intersect_spec.rb
+++ b/spec/ruby/core/array/intersect_spec.rb
@@ -1,66 +1,17 @@
require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
describe 'Array#intersect?' do
ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/15198
describe 'when at least one element in two Arrays is the same' do
it 'returns true' do
- [1, 2].intersect?([2, 3, 4]).should == true
- [2, 3, 4].intersect?([1, 2]).should == true
+ [1, 2].intersect?([2, 3]).should == true
end
end
describe 'when there are no elements in common between two Arrays' do
it 'returns false' do
- [0, 1, 2].intersect?([3, 4]).should == false
- [3, 4].intersect?([0, 1, 2]).should == false
- [3, 4].intersect?([]).should == false
- [].intersect?([0, 1, 2]).should == false
+ [1, 2].intersect?([3, 4]).should == false
end
end
-
- it "tries to convert the passed argument to an Array using #to_ary" do
- obj = mock('[1,2,3]')
- obj.should_receive(:to_ary).and_return([1, 2, 3])
-
- [1, 2].intersect?(obj).should == true
- end
-
- it "determines equivalence between elements in the sense of eql?" do
- obj1 = mock('1')
- obj2 = mock('2')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.stub!(:eql?).and_return(true)
- obj2.stub!(:eql?).and_return(true)
-
- [obj1].intersect?([obj2]).should == true
-
- obj1 = mock('3')
- obj2 = mock('4')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.stub!(:eql?).and_return(false)
- obj2.stub!(:eql?).and_return(false)
-
- [obj1].intersect?([obj2]).should == false
- end
-
- it "does not call to_ary on array subclasses" do
- [5, 6].intersect?(ArraySpecs::ToAryArray[1, 2, 5, 6]).should == true
- end
-
- it "properly handles an identical item even when its #eql? isn't reflexive" do
- x = mock('x')
- x.stub!(:hash).and_return(42)
- x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
-
- [x].intersect?([x]).should == true
- end
-
- it "has semantic of !(a & b).empty?" do
- [].intersect?([]).should == false
- [nil].intersect?([nil]).should == true
- end
end
end
diff --git a/spec/ruby/core/array/multiply_spec.rb b/spec/ruby/core/array/multiply_spec.rb
index eca51142fb..23d5c99f3a 100644
--- a/spec/ruby/core/array/multiply_spec.rb
+++ b/spec/ruby/core/array/multiply_spec.rb
@@ -76,10 +76,20 @@ describe "Array#* with an integer" do
@array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
end
- it "returns an Array instance" do
- (@array * 0).should be_an_instance_of(Array)
- (@array * 1).should be_an_instance_of(Array)
- (@array * 2).should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance" do
+ (@array * 0).should be_an_instance_of(ArraySpecs::MyArray)
+ (@array * 1).should be_an_instance_of(ArraySpecs::MyArray)
+ (@array * 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns an Array instance" do
+ (@array * 0).should be_an_instance_of(Array)
+ (@array * 1).should be_an_instance_of(Array)
+ (@array * 2).should be_an_instance_of(Array)
+ end
end
it "does not call #initialize on the subclass instance" do
diff --git a/spec/ruby/core/array/new_spec.rb b/spec/ruby/core/array/new_spec.rb
index b50a4857b0..96ec6b8198 100644
--- a/spec/ruby/core/array/new_spec.rb
+++ b/spec/ruby/core/array/new_spec.rb
@@ -26,9 +26,7 @@ describe "Array.new with no arguments" do
end
it "does not use the given block" do
- -> {
- -> { Array.new { raise } }.should_not raise_error
- }.should complain(/warning: given block not used/, verbose: true)
+ ->{ Array.new { raise } }.should_not raise_error
end
end
diff --git a/spec/ruby/core/array/none_spec.rb b/spec/ruby/core/array/none_spec.rb
deleted file mode 100644
index 31cd8c46d6..0000000000
--- a/spec/ruby/core/array/none_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
-
-describe "Array#none?" do
- @value_to_return = -> _ { false }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :none?
-
- it "ignores the block if there is an argument" do
- -> {
- ['bar', 'foobar'].none?(/baz/) { true }.should == true
- }.should complain(/given block not used/)
- end
-end
diff --git a/spec/ruby/core/array/one_spec.rb b/spec/ruby/core/array/one_spec.rb
deleted file mode 100644
index 0c61907881..0000000000
--- a/spec/ruby/core/array/one_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
-
-describe "Array#one?" do
- @value_to_return = -> _ { false }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :one?
-
- it "ignores the block if there is an argument" do
- -> {
- ['bar', 'foobar'].one?(/foo/) { false }.should == true
- }.should complain(/given block not used/)
- end
-end
diff --git a/spec/ruby/core/array/pack/c_spec.rb b/spec/ruby/core/array/pack/c_spec.rb
index ac133ff9b6..be03551629 100644
--- a/spec/ruby/core/array/pack/c_spec.rb
+++ b/spec/ruby/core/array/pack/c_spec.rb
@@ -47,9 +47,7 @@ describe :array_pack_8bit, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [1, 2, 3].pack(pack_format("\000", 2)).should == "\x01\x02"
- end
+ [1, 2, 3].pack(pack_format("\000", 2)).should == "\x01\x02"
end
end
diff --git a/spec/ruby/core/array/pack/shared/basic.rb b/spec/ruby/core/array/pack/shared/basic.rb
index 5e3eea55f9..65fdaa45d8 100644
--- a/spec/ruby/core/array/pack/shared/basic.rb
+++ b/spec/ruby/core/array/pack/shared/basic.rb
@@ -31,7 +31,7 @@ describe :array_pack_basic_non_float, shared: true do
# 2 additional directives ('a') are required for the X directive
[@obj, @obj, @obj, @obj].pack("aa #{pack_format} # some comment \n#{pack_format}").should be_an_instance_of(String)
end
-
+
ruby_version_is ""..."3.2" do
it "warns in verbose mode that a directive is unknown" do
# additional directive ('a') is required for the X directive
diff --git a/spec/ruby/core/array/pack/shared/float.rb b/spec/ruby/core/array/pack/shared/float.rb
index 1780d7635e..9510cffed7 100644
--- a/spec/ruby/core/array/pack/shared/float.rb
+++ b/spec/ruby/core/array/pack/shared/float.rb
@@ -27,9 +27,7 @@ describe :array_pack_float_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [5.3, 9.2].pack(pack_format("\000", 2)).should == "\x9a\x99\xa9@33\x13A"
- end
+ [5.3, 9.2].pack(pack_format("\000", 2)).should == "\x9a\x99\xa9@33\x13A"
end
end
@@ -107,9 +105,7 @@ describe :array_pack_float_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [5.3, 9.2].pack(pack_format("\000", 2)).should == "@\xa9\x99\x9aA\x1333"
- end
+ [5.3, 9.2].pack(pack_format("\000", 2)).should == "@\xa9\x99\x9aA\x1333"
end
end
@@ -179,9 +175,7 @@ describe :array_pack_double_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [5.3, 9.2].pack(pack_format("\000", 2)).should == "333333\x15@ffffff\x22@"
- end
+ [5.3, 9.2].pack(pack_format("\000", 2)).should == "333333\x15@ffffff\x22@"
end
end
@@ -250,9 +244,7 @@ describe :array_pack_double_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [5.3, 9.2].pack(pack_format("\000", 2)).should == "@\x15333333@\x22ffffff"
- end
+ [5.3, 9.2].pack(pack_format("\000", 2)).should == "@\x15333333@\x22ffffff"
end
end
diff --git a/spec/ruby/core/array/pack/shared/integer.rb b/spec/ruby/core/array/pack/shared/integer.rb
index fd21b25b19..d3ce9b5792 100644
--- a/spec/ruby/core/array/pack/shared/integer.rb
+++ b/spec/ruby/core/array/pack/shared/integer.rb
@@ -43,10 +43,8 @@ describe :array_pack_16bit_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
- str.should == "\x78\x65\xcd\xab"
- end
+ str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+ str.should == "\x78\x65\xcd\xab"
end
end
@@ -107,10 +105,8 @@ describe :array_pack_16bit_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
- str.should == "\x65\x78\xab\xcd"
- end
+ str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+ str.should == "\x65\x78\xab\xcd"
end
end
@@ -171,10 +167,8 @@ describe :array_pack_32bit_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
- str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
- end
+ str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+ str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
end
end
@@ -235,10 +229,8 @@ describe :array_pack_32bit_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
- str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
- end
+ str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+ str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
end
end
@@ -359,10 +351,8 @@ describe :array_pack_64bit_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
- str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
- end
+ str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
+ str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
end
end
@@ -431,10 +421,8 @@ describe :array_pack_64bit_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
- str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
- end
+ str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
+ str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
end
end
diff --git a/spec/ruby/core/array/pack/shared/unicode.rb b/spec/ruby/core/array/pack/shared/unicode.rb
index 4d8eaef323..130c447bb7 100644
--- a/spec/ruby/core/array/pack/shared/unicode.rb
+++ b/spec/ruby/core/array/pack/shared/unicode.rb
@@ -69,9 +69,7 @@ describe :array_pack_unicode, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [1, 2, 3].pack("U\x00U").should == "\x01\x02"
- end
+ [1, 2, 3].pack("U\x00U").should == "\x01\x02"
end
end
diff --git a/spec/ruby/core/array/pack/w_spec.rb b/spec/ruby/core/array/pack/w_spec.rb
index 48ed4496a5..e241d1519c 100644
--- a/spec/ruby/core/array/pack/w_spec.rb
+++ b/spec/ruby/core/array/pack/w_spec.rb
@@ -26,9 +26,7 @@ describe "Array#pack with format 'w'" do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- [1, 2, 3].pack("w\x00w").should == "\x01\x02"
- end
+ [1, 2, 3].pack("w\x00w").should == "\x01\x02"
end
end
diff --git a/spec/ruby/core/array/plus_spec.rb b/spec/ruby/core/array/plus_spec.rb
index 635bd131c9..3962b05c39 100644
--- a/spec/ruby/core/array/plus_spec.rb
+++ b/spec/ruby/core/array/plus_spec.rb
@@ -14,23 +14,10 @@ describe "Array#+" do
(ary + ary).should == [1, 2, 3, 1, 2, 3]
end
- describe "converts the passed argument to an Array using #to_ary" do
- it "successfully concatenates the resulting array from the #to_ary call" do
- obj = mock('["x", "y"]')
- obj.should_receive(:to_ary).and_return(["x", "y"])
- ([1, 2, 3] + obj).should == [1, 2, 3, "x", "y"]
- end
-
- it "raises a Typeerror if the given argument can't be converted to an array" do
- -> { [1, 2, 3] + nil }.should raise_error(TypeError)
- -> { [1, 2, 3] + "abc" }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to an Array" do
- obj = mock("hello")
- obj.should_receive(:to_ary).and_raise(NoMethodError)
- -> { [1, 2, 3] + obj }.should raise_error(NoMethodError)
- end
+ it "tries to convert the passed argument to an Array using #to_ary" do
+ obj = mock('["x", "y"]')
+ obj.should_receive(:to_ary).and_return(["x", "y"])
+ ([1, 2, 3] + obj).should == [1, 2, 3, "x", "y"]
end
it "properly handles recursive arrays" do
diff --git a/spec/ruby/core/array/product_spec.rb b/spec/ruby/core/array/product_spec.rb
index 6fb3818508..07d2880a96 100644
--- a/spec/ruby/core/array/product_spec.rb
+++ b/spec/ruby/core/array/product_spec.rb
@@ -9,11 +9,6 @@ describe "Array#product" do
ar.called.should == :to_ary
end
- it "returns converted arguments using :method_missing" do
- ar = ArraySpecs::ArrayMethodMissing.new(2,3)
- [1].product(ar).should == [[1,2],[1,3]]
- end
-
it "returns the expected result" do
[1,2].product([3,4,5],[6,8]).should == [[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
[2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8]]
diff --git a/spec/ruby/core/array/rassoc_spec.rb b/spec/ruby/core/array/rassoc_spec.rb
index 632a05e8b3..62fbd40611 100644
--- a/spec/ruby/core/array/rassoc_spec.rb
+++ b/spec/ruby/core/array/rassoc_spec.rb
@@ -35,18 +35,4 @@ describe "Array#rassoc" do
[[1, :foobar, o], [2, o, 1], [3, mock('foo')]].rassoc(key).should == [2, o, 1]
end
-
- ruby_version_is "3.3" do
- it "calls to_ary on non-array elements" do
- s1 = [1, 2]
- s2 = ArraySpecs::ArrayConvertible.new(2, 3)
- a = [s1, s2]
-
- s1.should_not_receive(:to_ary)
- a.rassoc(2).should equal(s1)
-
- a.rassoc(3).should == [2, 3]
- s2.called.should equal(:to_ary)
- end
- end
end
diff --git a/spec/ruby/core/array/reject_spec.rb b/spec/ruby/core/array/reject_spec.rb
index 81a467e364..fcf43fabde 100644
--- a/spec/ruby/core/array/reject_spec.rb
+++ b/spec/ruby/core/array/reject_spec.rb
@@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/enumeratorize'
require_relative 'shared/delete_if'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
require_relative '../enumerable/shared/enumeratorized'
describe "Array#reject" do
@@ -48,10 +47,6 @@ describe "Array#reject" do
it_behaves_like :enumeratorized_with_origin_size, :reject, [1,2,3]
end
-describe "Array#reject" do
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :reject
-end
-
describe "Array#reject!" do
it "removes elements for which block is true" do
a = [3, 4, 5, 6, 7, 8, 9, 10, 11]
@@ -116,11 +111,6 @@ describe "Array#reject!" do
-> { ArraySpecs.empty_frozen_array.reject! {} }.should raise_error(FrozenError)
end
- it "raises a FrozenError on a frozen array only during iteration if called without a block" do
- enum = ArraySpecs.frozen_array.reject!
- -> { enum.each {} }.should raise_error(FrozenError)
- end
-
it "does not truncate the array is the block raises an exception" do
a = [1, 2, 3]
begin
@@ -151,8 +141,3 @@ describe "Array#reject!" do
it_behaves_like :enumeratorized_with_origin_size, :reject!, [1,2,3]
it_behaves_like :delete_if, :reject!
end
-
-describe "Array#reject!" do
- @value_to_return = -> _ { false }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :reject!
-end
diff --git a/spec/ruby/core/array/reverse_each_spec.rb b/spec/ruby/core/array/reverse_each_spec.rb
index 59dabcd33d..28b8bfcb34 100644
--- a/spec/ruby/core/array/reverse_each_spec.rb
+++ b/spec/ruby/core/array/reverse_each_spec.rb
@@ -5,7 +5,7 @@ require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
-# https://blade.ruby-lang.org/ruby-core/23633
+# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633
describe "Array#reverse_each" do
before :each do
@@ -38,20 +38,6 @@ describe "Array#reverse_each" do
[1, 2, 3].reverse_each.size.should == 3
end
- it "tolerates increasing an array size during iteration" do
- array = [:a, :b, :c]
- ScratchPad.record []
- i = 0
-
- array.reverse_each do |e|
- ScratchPad << e
- array.prepend i if i < 100
- i += 1
- end
-
- ScratchPad.recorded.should == [:c, :a, 1]
- end
-
it_behaves_like :enumeratorize, :reverse_each
it_behaves_like :enumeratorized_with_origin_size, :reverse_each, [1,2,3]
end
diff --git a/spec/ruby/core/array/rindex_spec.rb b/spec/ruby/core/array/rindex_spec.rb
index 13de88818c..175c7bcfe2 100644
--- a/spec/ruby/core/array/rindex_spec.rb
+++ b/spec/ruby/core/array/rindex_spec.rb
@@ -4,7 +4,7 @@ require_relative '../enumerable/shared/enumeratorized'
# Modifying a collection while the contents are being iterated
# gives undefined behavior. See
-# https://blade.ruby-lang.org/ruby-core/23633
+# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633
describe "Array#rindex" do
it "returns the first index backwards from the end where element == to object" do
@@ -68,21 +68,6 @@ describe "Array#rindex" do
seen.should == [3]
end
- it "tolerates increasing an array size during iteration" do
- array = [:a, :b, :c]
- ScratchPad.record []
- i = 0
-
- array.rindex do |e|
- ScratchPad << e
- array.prepend i if i < 100
- i += 1
- false
- end
-
- ScratchPad.recorded.should == [:c, :a, 1]
- end
-
describe "given no argument and no block" do
it "produces an Enumerator" do
enum = [4, 2, 1, 5, 1, 3].rindex
diff --git a/spec/ruby/core/array/sample_spec.rb b/spec/ruby/core/array/sample_spec.rb
index 6ef78594f0..5b3aac9aed 100644
--- a/spec/ruby/core/array/sample_spec.rb
+++ b/spec/ruby/core/array/sample_spec.rb
@@ -29,10 +29,6 @@ describe "Array#sample" do
[4].sample(random: Random.new(42)).should equal(4)
end
- it "returns a single value when not passed a count and a Random class is given" do
- [4].sample(random: Random).should equal(4)
- end
-
it "returns an empty Array when passed zero" do
[4].sample(0).should == []
end
diff --git a/spec/ruby/core/array/shared/collect.rb b/spec/ruby/core/array/shared/collect.rb
index 030302ced6..8d75f7db9a 100644
--- a/spec/ruby/core/array/shared/collect.rb
+++ b/spec/ruby/core/array/shared/collect.rb
@@ -1,5 +1,4 @@
require_relative '../../enumerable/shared/enumeratorized'
-require_relative '../shared/iterable_and_tolerating_size_increasing'
describe :array_collect, shared: true do
it "returns a copy of array with each element replaced by the value returned by block" do
@@ -47,8 +46,6 @@ describe :array_collect, shared: true do
@object = [1, 2, 3, 4]
end
it_should_behave_like :enumeratorized_with_origin_size
-
- it_should_behave_like :array_iterable_and_tolerating_size_increasing
end
describe :array_collect_b, shared: true do
@@ -105,37 +102,8 @@ describe :array_collect_b, shared: true do
end
end
- it "does not truncate the array is the block raises an exception" do
- a = [1, 2, 3]
- begin
- a.send(@method) { raise StandardError, 'Oops' }
- rescue
- end
-
- a.should == [1, 2, 3]
- end
-
- it "only changes elements before error is raised, keeping the element which raised an error." do
- a = [1, 2, 3, 4]
- begin
- a.send(@method) do |e|
- case e
- when 1 then -1
- when 2 then -2
- when 3 then raise StandardError, 'Oops'
- else 0
- end
- end
- rescue StandardError
- end
-
- a.should == [-1, -2, 3, 4]
- end
-
before :all do
@object = [1, 2, 3, 4]
end
it_should_behave_like :enumeratorized_with_origin_size
-
- it_should_behave_like :array_iterable_and_tolerating_size_increasing
end
diff --git a/spec/ruby/core/array/shared/index.rb b/spec/ruby/core/array/shared/index.rb
index a4a0adbab6..a9896554f2 100644
--- a/spec/ruby/core/array/shared/index.rb
+++ b/spec/ruby/core/array/shared/index.rb
@@ -1,5 +1,3 @@
-require_relative '../shared/iterable_and_tolerating_size_increasing'
-
describe :array_index, shared: true do
it "returns the index of the first element == to object" do
x = mock('3')
@@ -36,6 +34,4 @@ describe :array_index, shared: true do
[].send(@method).should be_an_instance_of(Enumerator)
end
end
-
- it_should_behave_like :array_iterable_and_tolerating_size_increasing
end
diff --git a/spec/ruby/core/array/shared/intersection.rb b/spec/ruby/core/array/shared/intersection.rb
index 0b4166ab63..49849b08c2 100644
--- a/spec/ruby/core/array/shared/intersection.rb
+++ b/spec/ruby/core/array/shared/intersection.rb
@@ -11,8 +11,7 @@ describe :array_intersection, shared: true do
end
it "creates an array with elements in order they are first encountered" do
- [ 1, 2, 3, 2, 5, 6, 7, 8 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5] # array > other
- [ 5, 2, 3, 4 ].send(@method, [ 1, 2, 3, 2, 5, 6, 7, 8 ]).should == [5, 2, 3] # array < other
+ [ 1, 2, 3, 2, 5 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5]
end
it "does not modify the original Array" do
diff --git a/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb b/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb
deleted file mode 100644
index 3e73bad44b..0000000000
--- a/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-describe :array_iterable_and_tolerating_size_increasing, shared: true do
- before do
- @value_to_return ||= -> _ { nil }
- end
-
- it "tolerates increasing an array size during iteration" do
- # The goal is to trigger potential reallocation of internal array storage, so we:
- # - use elements of different types, starting with the less generic (Integer)
- # - add reasonably big number of new elements (~ 100)
- array = [1, 2, 3] # to test some methods we need several uniq elements
- array_to_join = [:a, :b, :c] + (4..100).to_a
-
- ScratchPad.record []
- i = 0
-
- array.send(@method) do |e|
- ScratchPad << e
- array << array_to_join[i] if i < array_to_join.size
- i += 1
- @value_to_return.call(e)
- end
-
- ScratchPad.recorded.should == [1, 2, 3] + array_to_join
- end
-end
diff --git a/spec/ruby/core/array/shared/keep_if.rb b/spec/ruby/core/array/shared/keep_if.rb
index 43a047c0a7..f26aff028c 100644
--- a/spec/ruby/core/array/shared/keep_if.rb
+++ b/spec/ruby/core/array/shared/keep_if.rb
@@ -1,5 +1,4 @@
require_relative '../../enumerable/shared/enumeratorized'
-require_relative '../shared/iterable_and_tolerating_size_increasing'
describe :keep_if, shared: true do
it "deletes elements for which the block returns a false value" do
@@ -57,39 +56,5 @@ describe :keep_if, shared: true do
-> { @frozen.send(@method) { false } }.should raise_error(FrozenError)
end
end
-
- it "raises a FrozenError on a frozen array only during iteration if called without a block" do
- enum = @frozen.send(@method)
- -> { enum.each {} }.should raise_error(FrozenError)
- end
- end
-
- it "does not truncate the array is the block raises an exception" do
- a = [1, 2, 3]
- begin
- a.send(@method) { raise StandardError, 'Oops' }
- rescue
- end
-
- a.should == [1, 2, 3]
end
-
- it "only changes elements before error is raised, keeping the element which raised an error." do
- a = [1, 2, 3, 4]
- begin
- a.send(@method) do |e|
- case e
- when 2 then false
- when 3 then raise StandardError, 'Oops'
- else true
- end
- end
- rescue StandardError
- end
-
- a.should == [1, 3, 4]
- end
-
- @value_to_return = -> _ { true }
- it_should_behave_like :array_iterable_and_tolerating_size_increasing
end
diff --git a/spec/ruby/core/array/shared/select.rb b/spec/ruby/core/array/shared/select.rb
index 9c2cbf76c4..09101e8ab5 100644
--- a/spec/ruby/core/array/shared/select.rb
+++ b/spec/ruby/core/array/shared/select.rb
@@ -2,14 +2,11 @@ require_relative '../../../spec_helper'
require_relative '../fixtures/classes'
require_relative '../shared/enumeratorize'
require_relative '../shared/keep_if'
-require_relative '../shared/iterable_and_tolerating_size_increasing'
require_relative '../../enumerable/shared/enumeratorized'
describe :array_select, shared: true do
it_should_behave_like :enumeratorize
- it_should_behave_like :array_iterable_and_tolerating_size_increasing
-
before :each do
@object = [1,2,3]
end
diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb
index d2866970a5..8fb33738b9 100644
--- a/spec/ruby/core/array/shared/slice.rb
+++ b/spec/ruby/core/array/shared/slice.rb
@@ -397,28 +397,56 @@ describe :array_slice, shared: true do
@array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
end
- it "returns a Array instance with [n, m]" do
- @array.send(@method, 0, 2).should be_an_instance_of(Array)
- end
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance with [n, m]" do
+ @array.send(@method, 0, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a Array instance with [-n, m]" do
- @array.send(@method, -3, 2).should be_an_instance_of(Array)
- end
+ it "returns a subclass instance with [-n, m]" do
+ @array.send(@method, -3, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a Array instance with [n..m]" do
- @array.send(@method, 1..3).should be_an_instance_of(Array)
- end
+ it "returns a subclass instance with [n..m]" do
+ @array.send(@method, 1..3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a Array instance with [n...m]" do
- @array.send(@method, 1...3).should be_an_instance_of(Array)
- end
+ it "returns a subclass instance with [n...m]" do
+ @array.send(@method, 1...3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
- it "returns a Array instance with [-n..-m]" do
- @array.send(@method, -3..-1).should be_an_instance_of(Array)
+ it "returns a subclass instance with [-n..-m]" do
+ @array.send(@method, -3..-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n...-m]" do
+ @array.send(@method, -3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
end
- it "returns a Array instance with [-n...-m]" do
- @array.send(@method, -3...-1).should be_an_instance_of(Array)
+ ruby_version_is '3.0' do
+ it "returns a Array instance with [n, m]" do
+ @array.send(@method, 0, 2).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n, m]" do
+ @array.send(@method, -3, 2).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [n..m]" do
+ @array.send(@method, 1..3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [n...m]" do
+ @array.send(@method, 1...3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n..-m]" do
+ @array.send(@method, -3..-1).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n...-m]" do
+ @array.send(@method, -3...-1).should be_an_instance_of(Array)
+ end
end
it "returns an empty array when m == n with [m...n]" do
@@ -506,237 +534,239 @@ describe :array_slice, shared: true do
a.send(@method, eval("(-9...)")).should == nil
end
- describe "can be sliced with Enumerator::ArithmeticSequence" do
- before :each do
- @array = [0, 1, 2, 3, 4, 5]
- end
+ ruby_version_is "3.0" do
+ describe "can be sliced with Enumerator::ArithmeticSequence" do
+ before :each do
+ @array = [0, 1, 2, 3, 4, 5]
+ end
- it "has endless range and positive steps" do
- @array.send(@method, eval("(0..).step(1)")).should == [0, 1, 2, 3, 4, 5]
- @array.send(@method, eval("(0..).step(2)")).should == [0, 2, 4]
- @array.send(@method, eval("(0..).step(10)")).should == [0]
+ it "has endless range and positive steps" do
+ @array.send(@method, eval("(0..).step(1)")).should == [0, 1, 2, 3, 4, 5]
+ @array.send(@method, eval("(0..).step(2)")).should == [0, 2, 4]
+ @array.send(@method, eval("(0..).step(10)")).should == [0]
- @array.send(@method, eval("(2..).step(1)")).should == [2, 3, 4, 5]
- @array.send(@method, eval("(2..).step(2)")).should == [2, 4]
- @array.send(@method, eval("(2..).step(10)")).should == [2]
+ @array.send(@method, eval("(2..).step(1)")).should == [2, 3, 4, 5]
+ @array.send(@method, eval("(2..).step(2)")).should == [2, 4]
+ @array.send(@method, eval("(2..).step(10)")).should == [2]
- @array.send(@method, eval("(-3..).step(1)")).should == [3, 4, 5]
- @array.send(@method, eval("(-3..).step(2)")).should == [3, 5]
- @array.send(@method, eval("(-3..).step(10)")).should == [3]
- end
+ @array.send(@method, eval("(-3..).step(1)")).should == [3, 4, 5]
+ @array.send(@method, eval("(-3..).step(2)")).should == [3, 5]
+ @array.send(@method, eval("(-3..).step(10)")).should == [3]
+ end
- it "has beginless range and positive steps" do
- # end with zero index
- @array.send(@method, (..0).step(1)).should == [0]
- @array.send(@method, (...0).step(1)).should == []
+ it "has beginless range and positive steps" do
+ # end with zero index
+ @array.send(@method, (..0).step(1)).should == [0]
+ @array.send(@method, (...0).step(1)).should == []
- @array.send(@method, (..0).step(2)).should == [0]
- @array.send(@method, (...0).step(2)).should == []
+ @array.send(@method, (..0).step(2)).should == [0]
+ @array.send(@method, (...0).step(2)).should == []
- @array.send(@method, (..0).step(10)).should == [0]
- @array.send(@method, (...0).step(10)).should == []
+ @array.send(@method, (..0).step(10)).should == [0]
+ @array.send(@method, (...0).step(10)).should == []
- # end with positive index
- @array.send(@method, (..3).step(1)).should == [0, 1, 2, 3]
- @array.send(@method, (...3).step(1)).should == [0, 1, 2]
+ # end with positive index
+ @array.send(@method, (..3).step(1)).should == [0, 1, 2, 3]
+ @array.send(@method, (...3).step(1)).should == [0, 1, 2]
- @array.send(@method, (..3).step(2)).should == [0, 2]
- @array.send(@method, (...3).step(2)).should == [0, 2]
+ @array.send(@method, (..3).step(2)).should == [0, 2]
+ @array.send(@method, (...3).step(2)).should == [0, 2]
- @array.send(@method, (..3).step(10)).should == [0]
- @array.send(@method, (...3).step(10)).should == [0]
+ @array.send(@method, (..3).step(10)).should == [0]
+ @array.send(@method, (...3).step(10)).should == [0]
- # end with negative index
- @array.send(@method, (..-2).step(1)).should == [0, 1, 2, 3, 4,]
- @array.send(@method, (...-2).step(1)).should == [0, 1, 2, 3]
+ # end with negative index
+ @array.send(@method, (..-2).step(1)).should == [0, 1, 2, 3, 4,]
+ @array.send(@method, (...-2).step(1)).should == [0, 1, 2, 3]
- @array.send(@method, (..-2).step(2)).should == [0, 2, 4]
- @array.send(@method, (...-2).step(2)).should == [0, 2]
+ @array.send(@method, (..-2).step(2)).should == [0, 2, 4]
+ @array.send(@method, (...-2).step(2)).should == [0, 2]
- @array.send(@method, (..-2).step(10)).should == [0]
- @array.send(@method, (...-2).step(10)).should == [0]
- end
+ @array.send(@method, (..-2).step(10)).should == [0]
+ @array.send(@method, (...-2).step(10)).should == [0]
+ end
- it "has endless range and negative steps" do
- @array.send(@method, eval("(0..).step(-1)")).should == [0]
- @array.send(@method, eval("(0..).step(-2)")).should == [0]
- @array.send(@method, eval("(0..).step(-10)")).should == [0]
+ it "has endless range and negative steps" do
+ @array.send(@method, eval("(0..).step(-1)")).should == [0]
+ @array.send(@method, eval("(0..).step(-2)")).should == [0]
+ @array.send(@method, eval("(0..).step(-10)")).should == [0]
- @array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0]
- @array.send(@method, eval("(2..).step(-2)")).should == [2, 0]
+ @array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0]
+ @array.send(@method, eval("(2..).step(-2)")).should == [2, 0]
- @array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0]
- @array.send(@method, eval("(-3..).step(-2)")).should == [3, 1]
- end
+ @array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0]
+ @array.send(@method, eval("(-3..).step(-2)")).should == [3, 1]
+ end
- it "has closed range and positive steps" do
- # start and end with 0
- @array.send(@method, eval("(0..0).step(1)")).should == [0]
- @array.send(@method, eval("(0...0).step(1)")).should == []
+ it "has closed range and positive steps" do
+ # start and end with 0
+ @array.send(@method, eval("(0..0).step(1)")).should == [0]
+ @array.send(@method, eval("(0...0).step(1)")).should == []
- @array.send(@method, eval("(0..0).step(2)")).should == [0]
- @array.send(@method, eval("(0...0).step(2)")).should == []
+ @array.send(@method, eval("(0..0).step(2)")).should == [0]
+ @array.send(@method, eval("(0...0).step(2)")).should == []
- @array.send(@method, eval("(0..0).step(10)")).should == [0]
- @array.send(@method, eval("(0...0).step(10)")).should == []
+ @array.send(@method, eval("(0..0).step(10)")).should == [0]
+ @array.send(@method, eval("(0...0).step(10)")).should == []
- # start and end with positive index
- @array.send(@method, eval("(1..3).step(1)")).should == [1, 2, 3]
- @array.send(@method, eval("(1...3).step(1)")).should == [1, 2]
+ # start and end with positive index
+ @array.send(@method, eval("(1..3).step(1)")).should == [1, 2, 3]
+ @array.send(@method, eval("(1...3).step(1)")).should == [1, 2]
- @array.send(@method, eval("(1..3).step(2)")).should == [1, 3]
- @array.send(@method, eval("(1...3).step(2)")).should == [1]
+ @array.send(@method, eval("(1..3).step(2)")).should == [1, 3]
+ @array.send(@method, eval("(1...3).step(2)")).should == [1]
- @array.send(@method, eval("(1..3).step(10)")).should == [1]
- @array.send(@method, eval("(1...3).step(10)")).should == [1]
+ @array.send(@method, eval("(1..3).step(10)")).should == [1]
+ @array.send(@method, eval("(1...3).step(10)")).should == [1]
- # start with positive index, end with negative index
- @array.send(@method, eval("(1..-2).step(1)")).should == [1, 2, 3, 4]
- @array.send(@method, eval("(1...-2).step(1)")).should == [1, 2, 3]
+ # start with positive index, end with negative index
+ @array.send(@method, eval("(1..-2).step(1)")).should == [1, 2, 3, 4]
+ @array.send(@method, eval("(1...-2).step(1)")).should == [1, 2, 3]
- @array.send(@method, eval("(1..-2).step(2)")).should == [1, 3]
- @array.send(@method, eval("(1...-2).step(2)")).should == [1, 3]
+ @array.send(@method, eval("(1..-2).step(2)")).should == [1, 3]
+ @array.send(@method, eval("(1...-2).step(2)")).should == [1, 3]
- @array.send(@method, eval("(1..-2).step(10)")).should == [1]
- @array.send(@method, eval("(1...-2).step(10)")).should == [1]
+ @array.send(@method, eval("(1..-2).step(10)")).should == [1]
+ @array.send(@method, eval("(1...-2).step(10)")).should == [1]
- # start with negative index, end with positive index
- @array.send(@method, eval("(-4..4).step(1)")).should == [2, 3, 4]
- @array.send(@method, eval("(-4...4).step(1)")).should == [2, 3]
+ # start with negative index, end with positive index
+ @array.send(@method, eval("(-4..4).step(1)")).should == [2, 3, 4]
+ @array.send(@method, eval("(-4...4).step(1)")).should == [2, 3]
- @array.send(@method, eval("(-4..4).step(2)")).should == [2, 4]
- @array.send(@method, eval("(-4...4).step(2)")).should == [2]
+ @array.send(@method, eval("(-4..4).step(2)")).should == [2, 4]
+ @array.send(@method, eval("(-4...4).step(2)")).should == [2]
- @array.send(@method, eval("(-4..4).step(10)")).should == [2]
- @array.send(@method, eval("(-4...4).step(10)")).should == [2]
+ @array.send(@method, eval("(-4..4).step(10)")).should == [2]
+ @array.send(@method, eval("(-4...4).step(10)")).should == [2]
- # start with negative index, end with negative index
- @array.send(@method, eval("(-4..-2).step(1)")).should == [2, 3, 4]
- @array.send(@method, eval("(-4...-2).step(1)")).should == [2, 3]
+ # start with negative index, end with negative index
+ @array.send(@method, eval("(-4..-2).step(1)")).should == [2, 3, 4]
+ @array.send(@method, eval("(-4...-2).step(1)")).should == [2, 3]
- @array.send(@method, eval("(-4..-2).step(2)")).should == [2, 4]
- @array.send(@method, eval("(-4...-2).step(2)")).should == [2]
+ @array.send(@method, eval("(-4..-2).step(2)")).should == [2, 4]
+ @array.send(@method, eval("(-4...-2).step(2)")).should == [2]
- @array.send(@method, eval("(-4..-2).step(10)")).should == [2]
- @array.send(@method, eval("(-4...-2).step(10)")).should == [2]
- end
+ @array.send(@method, eval("(-4..-2).step(10)")).should == [2]
+ @array.send(@method, eval("(-4...-2).step(10)")).should == [2]
+ end
- it "has closed range and negative steps" do
- # start and end with 0
- @array.send(@method, eval("(0..0).step(-1)")).should == [0]
- @array.send(@method, eval("(0...0).step(-1)")).should == []
+ it "has closed range and negative steps" do
+ # start and end with 0
+ @array.send(@method, eval("(0..0).step(-1)")).should == [0]
+ @array.send(@method, eval("(0...0).step(-1)")).should == []
- @array.send(@method, eval("(0..0).step(-2)")).should == [0]
- @array.send(@method, eval("(0...0).step(-2)")).should == []
+ @array.send(@method, eval("(0..0).step(-2)")).should == [0]
+ @array.send(@method, eval("(0...0).step(-2)")).should == []
- @array.send(@method, eval("(0..0).step(-10)")).should == [0]
- @array.send(@method, eval("(0...0).step(-10)")).should == []
+ @array.send(@method, eval("(0..0).step(-10)")).should == [0]
+ @array.send(@method, eval("(0...0).step(-10)")).should == []
- # start and end with positive index
- @array.send(@method, eval("(1..3).step(-1)")).should == []
- @array.send(@method, eval("(1...3).step(-1)")).should == []
+ # start and end with positive index
+ @array.send(@method, eval("(1..3).step(-1)")).should == []
+ @array.send(@method, eval("(1...3).step(-1)")).should == []
- @array.send(@method, eval("(1..3).step(-2)")).should == []
- @array.send(@method, eval("(1...3).step(-2)")).should == []
+ @array.send(@method, eval("(1..3).step(-2)")).should == []
+ @array.send(@method, eval("(1...3).step(-2)")).should == []
- @array.send(@method, eval("(1..3).step(-10)")).should == []
- @array.send(@method, eval("(1...3).step(-10)")).should == []
+ @array.send(@method, eval("(1..3).step(-10)")).should == []
+ @array.send(@method, eval("(1...3).step(-10)")).should == []
- # start with positive index, end with negative index
- @array.send(@method, eval("(1..-2).step(-1)")).should == []
- @array.send(@method, eval("(1...-2).step(-1)")).should == []
+ # start with positive index, end with negative index
+ @array.send(@method, eval("(1..-2).step(-1)")).should == []
+ @array.send(@method, eval("(1...-2).step(-1)")).should == []
- @array.send(@method, eval("(1..-2).step(-2)")).should == []
- @array.send(@method, eval("(1...-2).step(-2)")).should == []
+ @array.send(@method, eval("(1..-2).step(-2)")).should == []
+ @array.send(@method, eval("(1...-2).step(-2)")).should == []
- @array.send(@method, eval("(1..-2).step(-10)")).should == []
- @array.send(@method, eval("(1...-2).step(-10)")).should == []
+ @array.send(@method, eval("(1..-2).step(-10)")).should == []
+ @array.send(@method, eval("(1...-2).step(-10)")).should == []
- # start with negative index, end with positive index
- @array.send(@method, eval("(-4..4).step(-1)")).should == []
- @array.send(@method, eval("(-4...4).step(-1)")).should == []
+ # start with negative index, end with positive index
+ @array.send(@method, eval("(-4..4).step(-1)")).should == []
+ @array.send(@method, eval("(-4...4).step(-1)")).should == []
- @array.send(@method, eval("(-4..4).step(-2)")).should == []
- @array.send(@method, eval("(-4...4).step(-2)")).should == []
+ @array.send(@method, eval("(-4..4).step(-2)")).should == []
+ @array.send(@method, eval("(-4...4).step(-2)")).should == []
- @array.send(@method, eval("(-4..4).step(-10)")).should == []
- @array.send(@method, eval("(-4...4).step(-10)")).should == []
+ @array.send(@method, eval("(-4..4).step(-10)")).should == []
+ @array.send(@method, eval("(-4...4).step(-10)")).should == []
- # start with negative index, end with negative index
- @array.send(@method, eval("(-4..-2).step(-1)")).should == []
- @array.send(@method, eval("(-4...-2).step(-1)")).should == []
+ # start with negative index, end with negative index
+ @array.send(@method, eval("(-4..-2).step(-1)")).should == []
+ @array.send(@method, eval("(-4...-2).step(-1)")).should == []
- @array.send(@method, eval("(-4..-2).step(-2)")).should == []
- @array.send(@method, eval("(-4...-2).step(-2)")).should == []
+ @array.send(@method, eval("(-4..-2).step(-2)")).should == []
+ @array.send(@method, eval("(-4...-2).step(-2)")).should == []
- @array.send(@method, eval("(-4..-2).step(-10)")).should == []
- @array.send(@method, eval("(-4...-2).step(-10)")).should == []
- end
+ @array.send(@method, eval("(-4..-2).step(-10)")).should == []
+ @array.send(@method, eval("(-4...-2).step(-10)")).should == []
+ end
- it "has inverted closed range and positive steps" do
- # start and end with positive index
- @array.send(@method, eval("(3..1).step(1)")).should == []
- @array.send(@method, eval("(3...1).step(1)")).should == []
+ it "has inverted closed range and positive steps" do
+ # start and end with positive index
+ @array.send(@method, eval("(3..1).step(1)")).should == []
+ @array.send(@method, eval("(3...1).step(1)")).should == []
- @array.send(@method, eval("(3..1).step(2)")).should == []
- @array.send(@method, eval("(3...1).step(2)")).should == []
+ @array.send(@method, eval("(3..1).step(2)")).should == []
+ @array.send(@method, eval("(3...1).step(2)")).should == []
- @array.send(@method, eval("(3..1).step(10)")).should == []
- @array.send(@method, eval("(3...1).step(10)")).should == []
+ @array.send(@method, eval("(3..1).step(10)")).should == []
+ @array.send(@method, eval("(3...1).step(10)")).should == []
- # start with negative index, end with positive index
- @array.send(@method, eval("(-2..1).step(1)")).should == []
- @array.send(@method, eval("(-2...1).step(1)")).should == []
+ # start with negative index, end with positive index
+ @array.send(@method, eval("(-2..1).step(1)")).should == []
+ @array.send(@method, eval("(-2...1).step(1)")).should == []
- @array.send(@method, eval("(-2..1).step(2)")).should == []
- @array.send(@method, eval("(-2...1).step(2)")).should == []
+ @array.send(@method, eval("(-2..1).step(2)")).should == []
+ @array.send(@method, eval("(-2...1).step(2)")).should == []
- @array.send(@method, eval("(-2..1).step(10)")).should == []
- @array.send(@method, eval("(-2...1).step(10)")).should == []
+ @array.send(@method, eval("(-2..1).step(10)")).should == []
+ @array.send(@method, eval("(-2...1).step(10)")).should == []
- # start with positive index, end with negative index
- @array.send(@method, eval("(4..-4).step(1)")).should == []
- @array.send(@method, eval("(4...-4).step(1)")).should == []
+ # start with positive index, end with negative index
+ @array.send(@method, eval("(4..-4).step(1)")).should == []
+ @array.send(@method, eval("(4...-4).step(1)")).should == []
- @array.send(@method, eval("(4..-4).step(2)")).should == []
- @array.send(@method, eval("(4...-4).step(2)")).should == []
+ @array.send(@method, eval("(4..-4).step(2)")).should == []
+ @array.send(@method, eval("(4...-4).step(2)")).should == []
- @array.send(@method, eval("(4..-4).step(10)")).should == []
- @array.send(@method, eval("(4...-4).step(10)")).should == []
+ @array.send(@method, eval("(4..-4).step(10)")).should == []
+ @array.send(@method, eval("(4...-4).step(10)")).should == []
- # start with negative index, end with negative index
- @array.send(@method, eval("(-2..-4).step(1)")).should == []
- @array.send(@method, eval("(-2...-4).step(1)")).should == []
+ # start with negative index, end with negative index
+ @array.send(@method, eval("(-2..-4).step(1)")).should == []
+ @array.send(@method, eval("(-2...-4).step(1)")).should == []
- @array.send(@method, eval("(-2..-4).step(2)")).should == []
- @array.send(@method, eval("(-2...-4).step(2)")).should == []
+ @array.send(@method, eval("(-2..-4).step(2)")).should == []
+ @array.send(@method, eval("(-2...-4).step(2)")).should == []
- @array.send(@method, eval("(-2..-4).step(10)")).should == []
- @array.send(@method, eval("(-2...-4).step(10)")).should == []
- end
+ @array.send(@method, eval("(-2..-4).step(10)")).should == []
+ @array.send(@method, eval("(-2...-4).step(10)")).should == []
+ end
- it "has range with bounds outside of array" do
- # end is equal to array's length
- @array.send(@method, (0..6).step(1)).should == [0, 1, 2, 3, 4, 5]
- -> { @array.send(@method, (0..6).step(2)) }.should raise_error(RangeError)
+ it "has range with bounds outside of array" do
+ # end is equal to array's length
+ @array.send(@method, (0..6).step(1)).should == [0, 1, 2, 3, 4, 5]
+ -> { @array.send(@method, (0..6).step(2)) }.should raise_error(RangeError)
- # end is greater than length with positive steps
- @array.send(@method, (1..6).step(2)).should == [1, 3, 5]
- @array.send(@method, (2..7).step(2)).should == [2, 4]
- -> { @array.send(@method, (2..8).step(2)) }.should raise_error(RangeError)
+ # end is greater than length with positive steps
+ @array.send(@method, (1..6).step(2)).should == [1, 3, 5]
+ @array.send(@method, (2..7).step(2)).should == [2, 4]
+ -> { @array.send(@method, (2..8).step(2)) }.should raise_error(RangeError)
- # begin is greater than length with negative steps
- @array.send(@method, (6..1).step(-2)).should == [5, 3, 1]
- @array.send(@method, (7..2).step(-2)).should == [5, 3]
- -> { @array.send(@method, (8..2).step(-2)) }.should raise_error(RangeError)
- end
+ # begin is greater than length with negative steps
+ @array.send(@method, (6..1).step(-2)).should == [5, 3, 1]
+ @array.send(@method, (7..2).step(-2)).should == [5, 3]
+ -> { @array.send(@method, (8..2).step(-2)) }.should raise_error(RangeError)
+ end
- it "has endless range with start outside of array's bounds" do
- @array.send(@method, eval("(6..).step(1)")).should == []
- @array.send(@method, eval("(7..).step(1)")).should == nil
+ it "has endless range with start outside of array's bounds" do
+ @array.send(@method, eval("(6..).step(1)")).should == []
+ @array.send(@method, eval("(7..).step(1)")).should == nil
- @array.send(@method, eval("(6..).step(2)")).should == []
- -> { @array.send(@method, eval("(7..).step(2)")) }.should raise_error(RangeError)
+ @array.send(@method, eval("(6..).step(2)")).should == []
+ -> { @array.send(@method, eval("(7..).step(2)")) }.should raise_error(RangeError)
+ end
end
end
diff --git a/spec/ruby/core/array/shuffle_spec.rb b/spec/ruby/core/array/shuffle_spec.rb
index 1d528c124f..b255147c75 100644
--- a/spec/ruby/core/array/shuffle_spec.rb
+++ b/spec/ruby/core/array/shuffle_spec.rb
@@ -47,10 +47,6 @@ describe "Array#shuffle" do
[1, 2].shuffle(random: random).should be_an_instance_of(Array)
end
- it "accepts a Random class for the value for random: argument" do
- [1, 2].shuffle(random: Random).should be_an_instance_of(Array)
- end
-
it "calls #to_int on the Object returned by #rand" do
value = mock("array_shuffle_random_value")
value.should_receive(:to_int).at_least(1).times.and_return(0)
@@ -97,14 +93,4 @@ describe "Array#shuffle!" do
-> { ArraySpecs.frozen_array.shuffle! }.should raise_error(FrozenError)
-> { ArraySpecs.empty_frozen_array.shuffle! }.should raise_error(FrozenError)
end
-
- it "matches CRuby with random:" do
- %w[a b c].shuffle(random: Random.new(1)).should == %w[a c b]
- (0..10).to_a.shuffle(random: Random.new(10)).should == [2, 6, 8, 5, 7, 10, 3, 1, 0, 4, 9]
- end
-
- it "matches CRuby with srand" do
- srand(123)
- %w[a b c d e f g h i j k].shuffle.should == %w[a e f h i j d b g k c]
- end
end
diff --git a/spec/ruby/core/array/slice_spec.rb b/spec/ruby/core/array/slice_spec.rb
index 731c129251..8e1499855a 100644
--- a/spec/ruby/core/array/slice_spec.rb
+++ b/spec/ruby/core/array/slice_spec.rb
@@ -187,28 +187,56 @@ describe "Array#slice!" do
@array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
end
- it "returns a Array instance with [n, m]" do
- @array.slice!(0, 2).should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance with [n, m]" do
+ @array.slice!(0, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n, m]" do
+ @array.slice!(-3, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [n..m]" do
+ @array.slice!(1..3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [n...m]" do
+ @array.slice!(1...3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n..-m]" do
+ @array.slice!(-3..-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n...-m]" do
+ @array.slice!(-3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
end
- it "returns a Array instance with [-n, m]" do
- @array.slice!(-3, 2).should be_an_instance_of(Array)
- end
+ ruby_version_is '3.0' do
+ it "returns a Array instance with [n, m]" do
+ @array.slice!(0, 2).should be_an_instance_of(Array)
+ end
- it "returns a Array instance with [n..m]" do
- @array.slice!(1..3).should be_an_instance_of(Array)
- end
+ it "returns a Array instance with [-n, m]" do
+ @array.slice!(-3, 2).should be_an_instance_of(Array)
+ end
- it "returns a Array instance with [n...m]" do
- @array.slice!(1...3).should be_an_instance_of(Array)
- end
+ it "returns a Array instance with [n..m]" do
+ @array.slice!(1..3).should be_an_instance_of(Array)
+ end
- it "returns a Array instance with [-n..-m]" do
- @array.slice!(-3..-1).should be_an_instance_of(Array)
- end
+ it "returns a Array instance with [n...m]" do
+ @array.slice!(1...3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n..-m]" do
+ @array.slice!(-3..-1).should be_an_instance_of(Array)
+ end
- it "returns a Array instance with [-n...-m]" do
- @array.slice!(-3...-1).should be_an_instance_of(Array)
+ it "returns a Array instance with [-n...-m]" do
+ @array.slice!(-3...-1).should be_an_instance_of(Array)
+ end
end
end
end
diff --git a/spec/ruby/core/array/sort_by_spec.rb b/spec/ruby/core/array/sort_by_spec.rb
index 0334f953f6..7cea6ec6d3 100644
--- a/spec/ruby/core/array/sort_by_spec.rb
+++ b/spec/ruby/core/array/sort_by_spec.rb
@@ -1,6 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
require_relative '../enumerable/shared/enumeratorized'
describe "Array#sort_by!" do
@@ -32,11 +31,6 @@ describe "Array#sort_by!" do
-> { ArraySpecs.empty_frozen_array.sort_by! {}}.should raise_error(FrozenError)
end
- it "raises a FrozenError on a frozen array only during iteration if called without a block" do
- enum = ArraySpecs.frozen_array.sort_by!
- -> { enum.each {} }.should raise_error(FrozenError)
- end
-
it "returns the specified value when it would break in the given block" do
[1, 2, 3].sort_by!{ break :a }.should == :a
end
@@ -54,32 +48,5 @@ describe "Array#sort_by!" do
[1].sort_by!(&:to_s).should == [1]
end
- it "does not truncate the array is the block raises an exception" do
- a = [1, 2, 3]
- begin
- a.sort_by! { raise StandardError, 'Oops' }
- rescue
- end
-
- a.should == [1, 2, 3]
- end
-
- it "doesn't change array if error is raised" do
- a = [4, 3, 2, 1]
- begin
- a.sort_by! do |e|
- raise StandardError, 'Oops' if e == 1
- e
- end
- rescue StandardError
- end
-
- a.should == [4, 3, 2, 1]
- end
-
it_behaves_like :enumeratorized_with_origin_size, :sort_by!, [1,2,3]
end
-
-describe "Array#sort_by!" do
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :sort_by!
-end
diff --git a/spec/ruby/core/array/sum_spec.rb b/spec/ruby/core/array/sum_spec.rb
index 06abe06135..8ca8353a67 100644
--- a/spec/ruby/core/array/sum_spec.rb
+++ b/spec/ruby/core/array/sum_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#sum" do
it "returns the sum of elements" do
@@ -10,12 +9,8 @@ describe "Array#sum" do
[1, 2, 3].sum { |i| i * 10 }.should == 60
end
- it "doesn't apply the block init" do
- [1, 2, 3].sum(1) { |i| i * 10 }.should == 61
- end
-
# https://bugs.ruby-lang.org/issues/12217
- # https://github.com/ruby/ruby/blob/master/doc/ChangeLog/ChangeLog-2.4.0#L6208-L6214
+ # https://github.com/ruby/ruby/blob/master/doc/ChangeLog-2.4.0#L6208-L6214
it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do
floats = [2.7800000000000002, 5.0, 2.5, 4.44, 3.89, 3.89, 4.44, 7.78, 5.0, 2.7800000000000002, 5.0, 2.5]
naive_sum = floats.reduce { |sum, e| sum + e }
@@ -73,18 +68,4 @@ describe "Array#sum" do
a.should_receive(:+).with(b).and_return(42)
[b].sum(a).should == 42
end
-
- ruby_bug '#19530', ''...'3.3' do
- it "calls + on the init value" do
- a = mock("a")
- b = mock("b")
- a.should_receive(:+).with(42).and_return(b)
- [42].sum(a).should == b
- end
- end
-end
-
-describe "Array#sum" do
- @value_to_return = -> _ { 1 }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :sum
end
diff --git a/spec/ruby/core/array/take_spec.rb b/spec/ruby/core/array/take_spec.rb
index c4f0ac9aa4..4fb6f0ce75 100644
--- a/spec/ruby/core/array/take_spec.rb
+++ b/spec/ruby/core/array/take_spec.rb
@@ -26,7 +26,15 @@ describe "Array#take" do
->{ [1].take(-3) }.should raise_error(ArgumentError)
end
- it 'returns a Array instance for Array subclasses' do
- ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(Array)
+ end
end
end
diff --git a/spec/ruby/core/array/take_while_spec.rb b/spec/ruby/core/array/take_while_spec.rb
index 8f50260b42..363419b265 100644
--- a/spec/ruby/core/array/take_while_spec.rb
+++ b/spec/ruby/core/array/take_while_spec.rb
@@ -1,6 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#take_while" do
it "returns all elements until the block returns false" do
@@ -15,12 +14,15 @@ describe "Array#take_while" do
[1, 2, false, 4].take_while{ |element| element }.should == [1, 2]
end
- it 'returns a Array instance for Array subclasses' do
- ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(ArraySpecs::MyArray)
+ end
end
-end
-describe "Array#take_while" do
- @value_to_return = -> _ { true }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :take_while
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(Array)
+ end
+ end
end
diff --git a/spec/ruby/core/array/to_h_spec.rb b/spec/ruby/core/array/to_h_spec.rb
index f4578211a1..f5a7e546e6 100644
--- a/spec/ruby/core/array/to_h_spec.rb
+++ b/spec/ruby/core/array/to_h_spec.rb
@@ -1,6 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#to_h" do
it "converts empty array to empty hash" do
@@ -78,8 +77,3 @@ describe "Array#to_h" do
end
end
end
-
-describe "Array#to_h" do
- @value_to_return = -> e { [e, e.to_s] }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :to_h
-end
diff --git a/spec/ruby/core/array/try_convert_spec.rb b/spec/ruby/core/array/try_convert_spec.rb
index bea8815006..47b4722d80 100644
--- a/spec/ruby/core/array/try_convert_spec.rb
+++ b/spec/ruby/core/array/try_convert_spec.rb
@@ -39,7 +39,7 @@ describe "Array.try_convert" do
it "sends #to_ary to the argument and raises TypeError if it's not a kind of Array" do
obj = mock("to_ary")
obj.should_receive(:to_ary).and_return(Object.new)
- -> { Array.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to Array (MockObject#to_ary gives Object)")
+ -> { Array.try_convert obj }.should raise_error(TypeError)
end
it "does not rescue exceptions raised by #to_ary" do
diff --git a/spec/ruby/core/array/uniq_spec.rb b/spec/ruby/core/array/uniq_spec.rb
index d5d826db15..4461cae16b 100644
--- a/spec/ruby/core/array/uniq_spec.rb
+++ b/spec/ruby/core/array/uniq_spec.rb
@@ -1,6 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative 'shared/iterable_and_tolerating_size_increasing'
describe "Array#uniq" do
it "returns an array with no duplicates" do
@@ -85,8 +84,16 @@ describe "Array#uniq" do
[false, nil, 42].uniq { :bar }.should == [false]
end
- it "returns Array instance on Array subclasses" do
- ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(Array)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instance on Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns Array instance on Array subclasses" do
+ ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(Array)
+ end
end
it "properly handles an identical item even when its #eql? isn't reflexive" do
@@ -124,11 +131,6 @@ describe "Array#uniq" do
end
end
-describe "Array#uniq" do
- @value_to_return = -> e { e }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :uniq
-end
-
describe "Array#uniq!" do
it "modifies the array in place" do
a = [ "a", "a", "b", "b", "c" ]
@@ -212,32 +214,4 @@ describe "Array#uniq!" do
a.uniq!
a.should == [x]
end
-
- it "does not truncate the array is the block raises an exception" do
- a = [1, 2, 3]
- begin
- a.send(@method) { raise StandardError, 'Oops' }
- rescue
- end
-
- a.should == [1, 2, 3]
- end
-
- it "doesn't change array if error is raised" do
- a = [1, 1, 2, 2, 3, 3, 4, 4]
- begin
- a.send(@method) do |e|
- raise StandardError, 'Oops' if e == 3
- e
- end
- rescue StandardError
- end
-
- a.should == [1, 1, 2, 2, 3, 3, 4, 4]
- end
-end
-
-describe "Array#uniq!" do
- @value_to_return = -> e { e }
- it_behaves_like :array_iterable_and_tolerating_size_increasing, :uniq!
end
diff --git a/spec/ruby/core/basicobject/fixtures/classes.rb b/spec/ruby/core/basicobject/fixtures/classes.rb
index ed5a2dda17..d1785afe31 100644
--- a/spec/ruby/core/basicobject/fixtures/classes.rb
+++ b/spec/ruby/core/basicobject/fixtures/classes.rb
@@ -15,231 +15,8 @@ module BasicObjectSpecs
include InstExec
end
- module InstEval
- module CVar
- module Get
- class ReceiverScope
- @@cvar = :value_defined_in_receiver_scope
- end
-
- class BlockDefinitionScope
- @@cvar = :value_defined_in_block_definition_scope
-
- def block
- -> * { @@cvar }
- end
- end
-
- class CallerScope
- @@cvar = :value_defined_in_caller_scope
-
- def get_class_variable_with_string(obj)
- obj.instance_eval("@@cvar")
- end
-
- def get_class_variable_with_block(obj, block)
- obj.instance_eval(&block)
- end
- end
-
- class CallerWithoutCVarScope
- def get_class_variable_with_string(obj)
- obj.instance_eval("@@cvar")
- end
- end
-
- ReceiverWithCVarDefinedInSingletonClass = Class.new.new.tap do |obj|
- obj.singleton_class.class_variable_set(:@@cvar, :value_defined_in_receiver_singleton_class)
- end
- end
-
- module Set
- class ReceiverScope
- end
-
- class BlockDefinitionScope
- def self.get_class_variable
- @@cvar
- end
-
- def block_to_assign(value)
- -> * { @@cvar = value }
- end
- end
-
- class CallerScope
- def self.get_class_variable
- @@cvar
- end
-
- def set_class_variable_with_string(obj, value)
- obj.instance_eval("@@cvar=#{value.inspect}")
- end
-
- def set_class_variable_with_block(obj, block)
- obj.instance_eval(&block)
- end
- end
- end
- end
- end
-
- module InstEval
- module Constants
- module ConstantInReceiverSingletonClass
- module ReceiverScope
- FOO = :ReceiverScope
-
- class ReceiverParent
- FOO = :ReceiverParent
- end
-
- class Receiver < ReceiverParent
- FOO = :Receiver
-
- def initialize
- self.singleton_class.const_set(:FOO, :singleton_class)
- end
- end
- end
-
- module CallerScope
- FOO = :CallerScope
-
- class CallerParent
- FOO = :CallerParent
- end
-
- class Caller < CallerParent
- FOO = :Caller
-
- def get_constant_with_string(receiver)
- receiver.instance_eval("FOO")
- end
- end
- end
- end
-
- module ConstantInReceiverClass
- module ReceiverScope
- FOO = :ReceiverScope
-
- class ReceiverParent
- FOO = :ReceiverParent
- end
-
- class Receiver < ReceiverParent
- FOO = :Receiver
- end
- end
-
- module CallerScope
- FOO = :CallerScope
-
- class CallerParent
- FOO = :CallerParent
- end
-
- class Caller < CallerParent
- FOO = :Caller
-
- def get_constant_with_string(receiver)
- receiver.instance_eval("FOO")
- end
- end
- end
- end
-
- module ConstantInCallerClass
- module ReceiverScope
- FOO = :ReceiverScope
-
- class ReceiverParent
- FOO = :ReceiverParent
- end
-
- class Receiver < ReceiverParent
- # FOO is not declared in a receiver class
- end
- end
-
- module CallerScope
- FOO = :CallerScope
-
- class CallerParent
- FOO = :CallerParent
- end
-
- class Caller < CallerParent
- FOO = :Caller
-
- def get_constant_with_string(receiver)
- receiver.instance_eval("FOO")
- end
- end
- end
- end
-
- module ConstantInCallerOuterScopes
- module ReceiverScope
- FOO = :ReceiverScope
-
- class ReceiverParent
- FOO = :ReceiverParent
- end
-
- class Receiver < ReceiverParent
- # FOO is not declared in a receiver class
- end
- end
-
- module CallerScope
- FOO = :CallerScope
-
- class CallerParent
- FOO = :CallerParent
- end
-
- class Caller < CallerParent
- # FOO is not declared in a caller class
-
- def get_constant_with_string(receiver)
- receiver.instance_eval("FOO")
- end
- end
- end
- end
-
- module ConstantInReceiverParentClass
- module ReceiverScope
- FOO = :ReceiverScope
-
- class ReceiverParent
- FOO = :ReceiverParent
- end
-
- class Receiver < ReceiverParent
- # FOO is not declared in a receiver class
- end
- end
-
- module CallerScope
- # FOO is not declared in a caller outer scopes
-
- class CallerParent
- FOO = :CallerParent
- end
-
- class Caller < CallerParent
- # FOO is not declared in a caller class
-
- def get_constant_with_string(receiver)
- receiver.instance_eval("FOO")
- end
- end
- end
- end
- end
+ module InstEvalCVar
+ instance_eval { @@count = 2 }
end
class InstEvalConst
@@ -249,6 +26,7 @@ module BasicObjectSpecs
module InstEvalOuter
module Inner
obj = InstEvalConst.new
+ X_BY_STR = obj.instance_eval("INST_EVAL_CONST_X") rescue nil
X_BY_BLOCK = obj.instance_eval { INST_EVAL_CONST_X } rescue nil
end
end
diff --git a/spec/ruby/core/basicobject/instance_eval_spec.rb b/spec/ruby/core/basicobject/instance_eval_spec.rb
index 1f3a43f341..350b08a30e 100644
--- a/spec/ruby/core/basicobject/instance_eval_spec.rb
+++ b/spec/ruby/core/basicobject/instance_eval_spec.rb
@@ -84,30 +84,11 @@ describe "BasicObject#instance_eval" do
end
- ruby_version_is "3.3" do
- it "uses the caller location as default location" do
- f = Object.new
- f.instance_eval("[__FILE__, __LINE__]").should == ["(eval at #{__FILE__}:#{__LINE__})", 1]
- end
- end
-
it "has access to receiver's instance variables" do
BasicObjectSpecs::IVars.new.instance_eval { @secret }.should == 99
BasicObjectSpecs::IVars.new.instance_eval("@secret").should == 99
end
- it "raises TypeError for frozen objects when tries to set receiver's instance variables" do
- -> { nil.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen NilClass: nil")
- -> { true.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen TrueClass: true")
- -> { false.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen FalseClass: false")
- -> { 1.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen Integer: 1")
- -> { :symbol.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen Symbol: :symbol")
-
- obj = Object.new
- obj.freeze
- -> { obj.instance_eval { @foo = 42 } }.should raise_error(FrozenError)
- end
-
it "treats block-local variables as local to the block" do
prc = instance_eval <<-CODE
proc do |x, prc|
@@ -124,6 +105,11 @@ describe "BasicObject#instance_eval" do
prc.call(false, prc).should == 1
end
+ it "sets class variables in the receiver" do
+ BasicObjectSpecs::InstEvalCVar.class_variables.should include(:@@count)
+ BasicObjectSpecs::InstEvalCVar.send(:class_variable_get, :@@count).should == 2
+ end
+
it "makes the receiver metaclass the scoped class when used with a string" do
obj = Object.new
obj.instance_eval %{
@@ -133,52 +119,8 @@ describe "BasicObject#instance_eval" do
obj.singleton_class.const_get(:B).should be_an_instance_of(Class)
end
- describe "constants lookup when a String given" do
- it "looks in the receiver singleton class first" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverSingletonClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverSingletonClass::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :singleton_class
- end
-
- ruby_version_is ""..."3.1" do
- it "looks in the caller scope next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :Caller
- end
- end
-
- ruby_version_is "3.1" do
- it "looks in the receiver class next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :Receiver
- end
- end
-
- it "looks in the caller class next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInCallerClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInCallerClass::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :Caller
- end
-
- it "looks in the caller outer scopes next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInCallerOuterScopes::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInCallerOuterScopes::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :CallerScope
- end
-
- it "looks in the receiver class hierarchy next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverParentClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverParentClass::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :ReceiverParent
- end
+ it "gets constants in the receiver if a string given" do
+ BasicObjectSpecs::InstEvalOuter::Inner::X_BY_STR.should == 2
end
it "doesn't get constants in the receiver if a block given" do
@@ -194,51 +136,17 @@ describe "BasicObject#instance_eval" do
end.should raise_error(TypeError)
end
- describe "class variables lookup" do
- it "gets class variables in the caller class when called with a String" do
- receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverScope.new
- caller = BasicObjectSpecs::InstEval::CVar::Get::CallerScope.new
-
- caller.get_class_variable_with_string(receiver).should == :value_defined_in_caller_scope
- end
-
- it "gets class variables in the block definition scope when called with a block" do
- receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverScope.new
- caller = BasicObjectSpecs::InstEval::CVar::Get::CallerScope.new
- block = BasicObjectSpecs::InstEval::CVar::Get::BlockDefinitionScope.new.block
-
- caller.get_class_variable_with_block(receiver, block).should == :value_defined_in_block_definition_scope
- end
+quarantine! do # Not clean, leaves cvars lying around to break other specs
+ it "scopes class var accesses in the caller when called on an Integer" do
+ # Integer can take instance vars
+ Integer.class_eval "@@__tmp_instance_eval_spec = 1"
+ (defined? @@__tmp_instance_eval_spec).should be_nil
- it "sets class variables in the caller class when called with a String" do
- receiver = BasicObjectSpecs::InstEval::CVar::Set::ReceiverScope.new
- caller = BasicObjectSpecs::InstEval::CVar::Set::CallerScope.new
-
- caller.set_class_variable_with_string(receiver, 1)
- BasicObjectSpecs::InstEval::CVar::Set::CallerScope.get_class_variable.should == 1
- end
-
- it "sets class variables in the block definition scope when called with a block" do
- receiver = BasicObjectSpecs::InstEval::CVar::Set::ReceiverScope.new
- caller = BasicObjectSpecs::InstEval::CVar::Set::CallerScope.new
- block = BasicObjectSpecs::InstEval::CVar::Set::BlockDefinitionScope.new.block_to_assign(1)
-
- caller.set_class_variable_with_block(receiver, block)
- BasicObjectSpecs::InstEval::CVar::Set::BlockDefinitionScope.get_class_variable.should == 1
- end
-
- it "does not have access to class variables in the receiver class when called with a String" do
- receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverScope.new
- caller = BasicObjectSpecs::InstEval::CVar::Get::CallerWithoutCVarScope.new
- -> { caller.get_class_variable_with_string(receiver) }.should raise_error(NameError, /uninitialized class variable @@cvar/)
- end
-
- it "does not have access to class variables in the receiver's singleton class when called with a String" do
- receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverWithCVarDefinedInSingletonClass
- caller = BasicObjectSpecs::InstEval::CVar::Get::CallerWithoutCVarScope.new
- -> { caller.get_class_variable_with_string(receiver) }.should raise_error(NameError, /uninitialized class variable @@cvar/)
- end
+ @@__tmp_instance_eval_spec = 2
+ 1.instance_eval { @@__tmp_instance_eval_spec }.should == 2
+ Integer.__send__(:remove_class_variable, :@@__tmp_instance_eval_spec)
end
+end
it "raises a TypeError when defining methods on numerics" do
-> do
diff --git a/spec/ruby/core/basicobject/method_missing_spec.rb b/spec/ruby/core/basicobject/method_missing_spec.rb
index a29d4375bc..b048780ee8 100644
--- a/spec/ruby/core/basicobject/method_missing_spec.rb
+++ b/spec/ruby/core/basicobject/method_missing_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/basicobject/method_missing'
describe "BasicObject#method_missing" do
diff --git a/spec/ruby/core/binding/clone_spec.rb b/spec/ruby/core/binding/clone_spec.rb
index f1769ac6de..ebd40f5377 100644
--- a/spec/ruby/core/binding/clone_spec.rb
+++ b/spec/ruby/core/binding/clone_spec.rb
@@ -4,10 +4,4 @@ require_relative 'shared/clone'
describe "Binding#clone" do
it_behaves_like :binding_clone, :clone
-
- it "preserves frozen status" do
- bind = binding.freeze
- bind.frozen?.should == true
- bind.clone.frozen?.should == true
- end
end
diff --git a/spec/ruby/core/binding/dup_spec.rb b/spec/ruby/core/binding/dup_spec.rb
index 55fac6e333..43968213c8 100644
--- a/spec/ruby/core/binding/dup_spec.rb
+++ b/spec/ruby/core/binding/dup_spec.rb
@@ -4,10 +4,4 @@ require_relative 'shared/clone'
describe "Binding#dup" do
it_behaves_like :binding_clone, :dup
-
- it "resets frozen status" do
- bind = binding.freeze
- bind.frozen?.should == true
- bind.dup.frozen?.should == false
- end
end
diff --git a/spec/ruby/core/binding/eval_spec.rb b/spec/ruby/core/binding/eval_spec.rb
index bb2036f739..4bb3da7a6c 100644
--- a/spec/ruby/core/binding/eval_spec.rb
+++ b/spec/ruby/core/binding/eval_spec.rb
@@ -23,29 +23,58 @@ describe "Binding#eval" do
bind2.local_variables.should == []
end
- it "starts with line 1 if single argument is given" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("__LINE__").should == 1
- end
+ ruby_version_is ""..."3.0" do
+ it "inherits __LINE__ from the enclosing scope" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+ end
- it "preserves __LINE__ across multiple calls to eval" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("__LINE__").should == 1
- bind.eval("__LINE__").should == 1
- end
+ it "preserves __LINE__ across multiple calls to eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+ suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+ end
- it "increments __LINE__ on each line of a multiline eval" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- bind.eval("#foo\n__LINE__").should == 2
+ it "increments __LINE__ on each line of a multiline eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning {bind.eval("#foo\n__LINE__")}.should == obj.get_line_of_binding + 1
+ end
+
+ it "inherits __LINE__ from the enclosing scope even if the Binding is created with #send" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, line = obj.get_binding_with_send_and_line
+ suppress_warning {bind.eval("__LINE__")}.should == line
+ end
end
- it "starts with line 1 if the Binding is created with #send" do
- obj = BindingSpecs::Demo.new(1)
- bind, line = obj.get_binding_with_send_and_line
- bind.eval("__LINE__").should == 1
+ ruby_version_is "3.0" do
+ it "starts with line 1 if single argument is given" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("__LINE__").should == 1
+ end
+
+ it "preserves __LINE__ across multiple calls to eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("__LINE__").should == 1
+ bind.eval("__LINE__").should == 1
+ end
+
+ it "increments __LINE__ on each line of a multiline eval" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ bind.eval("#foo\n__LINE__").should == 2
+ end
+
+ it "starts with line 1 if the Binding is created with #send" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, line = obj.get_binding_with_send_and_line
+ bind.eval("__LINE__").should == 1
+ end
end
it "starts with a __LINE__ of 1 if a filename is passed" do
@@ -60,18 +89,32 @@ describe "Binding#eval" do
bind.eval("#foo\n__LINE__", "(test)", 88).should == 89
end
- ruby_version_is ""..."3.3" do
+ ruby_version_is ""..."3.0" do
+ it "inherits __FILE__ from the enclosing scope" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning { bind.eval("__FILE__") }.should == obj.get_file_of_binding
+ end
+
+ it "inherits __LINE__ from the enclosing scope" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, line = obj.get_binding_and_line
+ suppress_warning { bind.eval("__LINE__") }.should == line
+ end
+ end
+
+ ruby_version_is "3.0" do
it "uses (eval) as __FILE__ if single argument given" do
obj = BindingSpecs::Demo.new(1)
bind = obj.get_binding
bind.eval("__FILE__").should == '(eval)'
end
- end
- it "uses 1 as __LINE__" do
- obj = BindingSpecs::Demo.new(1)
- bind = obj.get_binding
- suppress_warning { bind.eval("__LINE__") }.should == 1
+ it "uses 1 as __LINE__" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning { bind.eval("__LINE__") }.should == 1
+ end
end
it "uses the __FILE__ that is passed in" do
@@ -106,10 +149,4 @@ describe "Binding#eval" do
bind.eval("'bar'.foo").should == "foo"
end
-
- ruby_version_is "3.3" do
- it "uses the caller location as default filename" do
- binding.eval("[__FILE__, __LINE__]").should == ["(eval at #{__FILE__}:#{__LINE__})", 1]
- end
- end
end
diff --git a/spec/ruby/core/binding/shared/clone.rb b/spec/ruby/core/binding/shared/clone.rb
index 1224b8ec7d..0e934ac1b5 100644
--- a/spec/ruby/core/binding/shared/clone.rb
+++ b/spec/ruby/core/binding/shared/clone.rb
@@ -31,26 +31,4 @@ describe :binding_clone, shared: true do
b2.local_variable_defined?(:x).should == false
end
end
-
- ruby_version_is "3.4" do
- it "copies instance variables" do
- @b1.instance_variable_set(:@ivar, 1)
- cl = @b1.send(@method)
- cl.instance_variables.should == [:@ivar]
- end
-
- it "copies the finalizer" do
- code = <<-RUBY
- obj = binding
-
- ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized\n" })
-
- obj.clone
-
- exit 0
- RUBY
-
- ruby_exe(code).lines.sort.should == ["finalized\n", "finalized\n"]
- end
- end
end
diff --git a/spec/ruby/core/binding/source_location_spec.rb b/spec/ruby/core/binding/source_location_spec.rb
index d1c8191ea8..d439c3e399 100644
--- a/spec/ruby/core/binding/source_location_spec.rb
+++ b/spec/ruby/core/binding/source_location_spec.rb
@@ -6,9 +6,4 @@ describe "Binding#source_location" do
b = BindingSpecs::LocationMethod::TEST_BINDING
b.source_location.should == [BindingSpecs::LocationMethod::FILE_PATH, 4]
end
-
- it "works for eval with a given line" do
- b = eval('binding', nil, "foo", 100)
- b.source_location.should == ["foo", 100]
- end
end
diff --git a/spec/ruby/core/class/dup_spec.rb b/spec/ruby/core/class/dup_spec.rb
index c09ed71b31..701fd72e19 100644
--- a/spec/ruby/core/class/dup_spec.rb
+++ b/spec/ruby/core/class/dup_spec.rb
@@ -61,7 +61,4 @@ describe "Class#dup" do
CoreClassSpecs::RecordCopy.name.should == "CoreClassSpecs::RecordCopy"
end
- it "raises TypeError if called on BasicObject" do
- -> { BasicObject.dup }.should raise_error(TypeError, "can't copy the root class")
- end
end
diff --git a/spec/ruby/core/complex/inspect_spec.rb b/spec/ruby/core/complex/inspect_spec.rb
index 7a89ec6854..71aabde5be 100644
--- a/spec/ruby/core/complex/inspect_spec.rb
+++ b/spec/ruby/core/complex/inspect_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative '../numeric/fixtures/classes'
describe "Complex#inspect" do
it "returns (${real}+${image}i) for positive imaginary parts" do
@@ -14,22 +13,4 @@ describe "Complex#inspect" do
Complex(-1, -4).inspect.should == "(-1-4i)"
Complex(-7, -6.7).inspect.should == "(-7-6.7i)"
end
-
- it "calls #inspect on real and imaginary" do
- real = NumericSpecs::Subclass.new
- real.should_receive(:inspect).and_return("1")
- imaginary = NumericSpecs::Subclass.new
- imaginary.should_receive(:inspect).and_return("2")
- imaginary.should_receive(:<).any_number_of_times.and_return(false)
- Complex(real, imaginary).inspect.should == "(1+2i)"
- end
-
- it "adds an `*' before the `i' if the last character of the imaginary part is not numeric" do
- real = NumericSpecs::Subclass.new
- real.should_receive(:inspect).and_return("(1)")
- imaginary = NumericSpecs::Subclass.new
- imaginary.should_receive(:inspect).and_return("(2)")
- imaginary.should_receive(:<).any_number_of_times.and_return(false)
- Complex(real, imaginary).inspect.should == "((1)+(2)*i)"
- end
end
diff --git a/spec/ruby/core/complex/to_s_spec.rb b/spec/ruby/core/complex/to_s_spec.rb
index 7677dcd0b5..989a7ae0b7 100644
--- a/spec/ruby/core/complex/to_s_spec.rb
+++ b/spec/ruby/core/complex/to_s_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative '../numeric/fixtures/classes'
describe "Complex#to_s" do
describe "when self's real component is 0" do
@@ -42,13 +41,4 @@ describe "Complex#to_s" do
it "returns 1+NaN*i for Complex(1, NaN)" do
Complex(1, nan_value).to_s.should == "1+NaN*i"
end
-
- it "treats real and imaginary parts as strings" do
- real = NumericSpecs::Subclass.new
- real.should_receive(:to_s).and_return("1")
- imaginary = NumericSpecs::Subclass.new
- imaginary.should_receive(:to_s).and_return("2")
- imaginary.should_receive(:<).any_number_of_times.and_return(false)
- Complex(real, imaginary).to_s.should == "1+2i"
- end
end
diff --git a/spec/ruby/core/data/constants_spec.rb b/spec/ruby/core/data/constants_spec.rb
index 2eb43d501e..d9d55b50f9 100644
--- a/spec/ruby/core/data/constants_spec.rb
+++ b/spec/ruby/core/data/constants_spec.rb
@@ -1,6 +1,20 @@
require_relative '../../spec_helper'
-ruby_version_is ''...'3.2' do
+ruby_version_is ''...'3.0' do
+ describe "Data" do
+ it "is a subclass of Object" do
+ suppress_warning do
+ Data.superclass.should == Object
+ end
+ end
+
+ it "is deprecated" do
+ -> { Data }.should complain(/constant ::Data is deprecated/)
+ end
+ end
+end
+
+ruby_version_is '3.0'...'3.2' do
describe "Data" do
it "does not exist anymore" do
Object.should_not have_constant(:Data)
diff --git a/spec/ruby/core/data/define_spec.rb b/spec/ruby/core/data/define_spec.rb
deleted file mode 100644
index 2aa2c50d4c..0000000000
--- a/spec/ruby/core/data/define_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
-
-ruby_version_is "3.2" do
- describe "Data.define" do
- it "accepts no arguments" do
- empty_data = Data.define
- empty_data.members.should == []
- end
-
- it "accepts symbols" do
- movie = Data.define(:title, :year)
- movie.members.should == [:title, :year]
- end
-
- it "accepts strings" do
- movie = Data.define("title", "year")
- movie.members.should == [:title, :year]
- end
-
- it "accepts a mix of strings and symbols" do
- movie = Data.define("title", :year, "genre")
- movie.members.should == [:title, :year, :genre]
- end
-
- it "accepts a block" do
- movie = Data.define(:title, :year) do
- def title_with_year
- "#{title} (#{year})"
- end
- end
- movie.members.should == [:title, :year]
- movie.new("Matrix", 1999).title_with_year.should == "Matrix (1999)"
- end
- end
-end
diff --git a/spec/ruby/core/data/fixtures/classes.rb b/spec/ruby/core/data/fixtures/classes.rb
deleted file mode 100644
index 46a6b48bb2..0000000000
--- a/spec/ruby/core/data/fixtures/classes.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-module DataSpecs
- guard -> { ruby_version_is "3.2" and Data.respond_to?(:define) } do
- Measure = Data.define(:amount, :unit)
- end
-end
diff --git a/spec/ruby/core/data/initialize_spec.rb b/spec/ruby/core/data/initialize_spec.rb
deleted file mode 100644
index 94470cd108..0000000000
--- a/spec/ruby/core/data/initialize_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
-
-ruby_version_is "3.2" do
- describe "Data#initialize" do
- it "accepts positional arguments" do
- data = DataSpecs::Measure.new(42, "km")
-
- data.amount.should == 42
- data.unit.should == "km"
- end
-
- it "accepts alternative positional arguments" do
- data = DataSpecs::Measure[42, "km"]
-
- data.amount.should == 42
- data.unit.should == "km"
- end
-
- it "accepts keyword arguments" do
- data = DataSpecs::Measure.new(amount: 42, unit: "km")
-
- data.amount.should == 42
- data.unit.should == "km"
- end
-
- it "accepts alternative keyword arguments" do
- data = DataSpecs::Measure[amount: 42, unit: "km"]
-
- data.amount.should == 42
- data.unit.should == "km"
- end
-
- it "raises ArgumentError if no arguments are given" do
- -> {
- DataSpecs::Measure.new
- }.should raise_error(ArgumentError) { |e|
- e.message.should.include?("missing keywords: :amount, :unit")
- }
- end
-
- it "raises ArgumentError if at least one argument is missing" do
- -> {
- DataSpecs::Measure.new(unit: "km")
- }.should raise_error(ArgumentError) { |e|
- e.message.should.include?("missing keyword: :amount")
- }
- end
-
- it "raises ArgumentError if unknown keyword is given" do
- -> {
- DataSpecs::Measure.new(amount: 42, unit: "km", system: "metric")
- }.should raise_error(ArgumentError) { |e|
- e.message.should.include?("unknown keyword: :system")
- }
- end
- end
-end
diff --git a/spec/ruby/core/dir/exist_spec.rb b/spec/ruby/core/dir/exist_spec.rb
index 9023de533f..43987b0f32 100644
--- a/spec/ruby/core/dir/exist_spec.rb
+++ b/spec/ruby/core/dir/exist_spec.rb
@@ -13,11 +13,3 @@ describe "Dir.exist?" do
it_behaves_like :dir_exist, :exist?
end
-
-ruby_version_is "3.2" do
- describe "Dir.exists?" do
- it "has been removed" do
- Dir.should_not.respond_to?(:exists?)
- end
- end
-end
diff --git a/spec/ruby/core/dir/fchdir_spec.rb b/spec/ruby/core/dir/fchdir_spec.rb
deleted file mode 100644
index 429e569691..0000000000
--- a/spec/ruby/core/dir/fchdir_spec.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/common'
-
-ruby_version_is '3.3' do
- guard -> { Dir.respond_to? :fchdir } do
- describe "Dir.fchdir" do
- before :all do
- DirSpecs.create_mock_dirs
- end
-
- after :all do
- DirSpecs.delete_mock_dirs
- end
-
- before :each do
- @dirs = [Dir.new('.')]
- @original = @dirs.first.fileno
- end
-
- after :each do
- Dir.fchdir(@original)
- @dirs.each(&:close)
- end
-
- it "changes to the specified directory" do
- dir = Dir.new(DirSpecs.mock_dir)
- @dirs << dir
- Dir.fchdir dir.fileno
- Dir.pwd.should == DirSpecs.mock_dir
- end
-
- it "returns 0 when successfully changing directory" do
- Dir.fchdir(@original).should == 0
- end
-
- it "returns the value of the block when a block is given" do
- Dir.fchdir(@original) { :block_value }.should == :block_value
- end
-
- it "changes to the specified directory for the duration of the block" do
- pwd = Dir.pwd
- dir = Dir.new(DirSpecs.mock_dir)
- @dirs << dir
- Dir.fchdir(dir.fileno) { Dir.pwd }.should == DirSpecs.mock_dir
- Dir.pwd.should == pwd
- end
-
- it "raises a SystemCallError if the file descriptor given is not valid" do
- -> { Dir.fchdir(-1) }.should raise_error(SystemCallError)
- -> { Dir.fchdir(-1) { } }.should raise_error(SystemCallError)
- end
-
- it "raises a SystemCallError if the file descriptor given is not for a directory" do
- -> { Dir.fchdir $stdout.fileno }.should raise_error(SystemCallError)
- -> { Dir.fchdir($stdout.fileno) { } }.should raise_error(SystemCallError)
- end
- end
- end
-
- guard_not -> { Dir.respond_to? :fchdir } do
- describe "Dir.fchdir" do
- it "raises NotImplementedError" do
- -> { Dir.fchdir 1 }.should raise_error(NotImplementedError)
- -> { Dir.fchdir(1) { } }.should raise_error(NotImplementedError)
- end
- end
- end
-end
diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb
index 32f515c81d..06b52b90fb 100644
--- a/spec/ruby/core/dir/glob_spec.rb
+++ b/spec/ruby/core/dir/glob_spec.rb
@@ -106,11 +106,11 @@ describe "Dir.glob" do
ruby_version_is '3.1' do
it "recursively matches files and directories in nested dot subdirectory except . with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
expected = %w[
- nested/.
- nested/.dotsubir
- nested/.dotsubir/.dotfile
- nested/.dotsubir/nondotfile
- ]
+ nested/.
+ nested/.dotsubir
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
+ ]
Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
end
@@ -182,134 +182,6 @@ describe "Dir.glob" do
Dir.glob('**/**/**').should_not.empty?
end
- it "handles **/** with base keyword argument" do
- Dir.glob('**/**', base: "dir").should == ["filename_ordering"]
-
- expected = %w[
- nested
- nested/directory
- nested/directory/structure
- nested/directory/structure/bar
- nested/directory/structure/baz
- nested/directory/structure/file_one
- nested/directory/structure/file_one.ext
- nested/directory/structure/foo
- nondotfile
- ].sort
-
- Dir.glob('**/**', base: "deeply").sort.should == expected
- end
-
- it "handles **/ with base keyword argument" do
- expected = %w[
- /
- directory/
- directory/structure/
- ]
- Dir.glob('**/', base: "deeply/nested").sort.should == expected
- end
-
- it "handles **/nondotfile with base keyword argument" do
- expected = %w[
- deeply/nondotfile
- nondotfile
- subdir_one/nondotfile
- subdir_two/nondotfile
- ]
- Dir.glob('**/nondotfile', base: ".").sort.should == expected
- end
-
- it "handles **/nondotfile with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .dotsubdir/nondotfile
- deeply/nondotfile
- nested/.dotsubir/nondotfile
- nondotfile
- subdir_one/nondotfile
- subdir_two/nondotfile
- ]
- Dir.glob('**/nondotfile', File::FNM_DOTMATCH, base: ".").sort.should == expected
- end
-
- it "handles **/.dotfile with base keyword argument" do
- expected = %w[
- .dotfile
- deeply/.dotfile
- subdir_one/.dotfile
- ]
- Dir.glob('**/.dotfile', base: ".").sort.should == expected
- end
-
- it "handles **/.dotfile with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .dotfile
- .dotsubdir/.dotfile
- deeply/.dotfile
- nested/.dotsubir/.dotfile
- subdir_one/.dotfile
- ]
- Dir.glob('**/.dotfile', File::FNM_DOTMATCH, base: ".").sort.should == expected
- end
-
- it "handles **/.* with base keyword argument" do
- expected = %w[
- .dotfile.ext
- directory/structure/.ext
- ].sort
-
- Dir.glob('**/.*', base: "deeply/nested").sort.should == expected
- end
-
- # < 3.1 include a "." entry for every dir: ["directory/.", "directory/structure/.", ...]
- ruby_version_is '3.1' do
- it "handles **/.* with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .
- .dotfile.ext
- directory/structure/.ext
- ].sort
-
- Dir.glob('**/.*', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
- end
-
- it "handles **/** with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .
- .dotfile.ext
- directory
- directory/structure
- directory/structure/.ext
- directory/structure/bar
- directory/structure/baz
- directory/structure/file_one
- directory/structure/file_one.ext
- directory/structure/foo
- ].sort
-
- Dir.glob('**/**', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
- end
- end
-
- it "handles **/*pattern* with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .dotfile.ext
- directory/structure/file_one
- directory/structure/file_one.ext
- ]
-
- Dir.glob('**/*file*', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
- end
-
- it "handles **/glob with base keyword argument and FNM_EXTGLOB" do
- expected = %w[
- directory/structure/bar
- directory/structure/file_one
- directory/structure/file_one.ext
- ]
-
- Dir.glob('**/*{file,bar}*', File::FNM_EXTGLOB, base: "deeply/nested").sort.should == expected
- end
-
it "handles simple filename patterns" do
Dir.glob('.dotfile').should == ['.dotfile']
end
diff --git a/spec/ruby/core/dir/home_spec.rb b/spec/ruby/core/dir/home_spec.rb
index 3cf745ab46..bbe347ba9e 100644
--- a/spec/ruby/core/dir/home_spec.rb
+++ b/spec/ruby/core/dir/home_spec.rb
@@ -40,21 +40,22 @@ describe "Dir.home" do
home.should == "C:/rubyspäc/home"
home.encoding.should == Encoding::UTF_8
end
+ end
- it "retrieves the directory from HOME, USERPROFILE, HOMEDRIVE/HOMEPATH and the WinAPI in that order" do
- old_dirs = [ENV.delete('HOME'), ENV.delete('USERPROFILE'), ENV.delete('HOMEDRIVE'), ENV.delete('HOMEPATH')]
+ it "retrieves the directory from HOME, USERPROFILE, HOMEDRIVE/HOMEPATH and the WinAPI in that order" do
+ old_dirs = [ENV.delete('HOME'), ENV.delete('USERPROFILE'), ENV.delete('HOMEDRIVE'), ENV.delete('HOMEPATH')]
- Dir.home.should == old_dirs[1].gsub("\\", "/")
- ENV['HOMEDRIVE'] = "C:"
- ENV['HOMEPATH'] = "\\rubyspec\\home1"
- Dir.home.should == "C:/rubyspec/home1"
- ENV['USERPROFILE'] = "C:\\rubyspec\\home2"
- Dir.home.should == "C:/rubyspec/home2"
- ENV['HOME'] = "C:\\rubyspec\\home3"
- Dir.home.should == "C:/rubyspec/home3"
- ensure
- ENV['HOME'], ENV['USERPROFILE'], ENV['HOMEDRIVE'], ENV['HOMEPATH'] = *old_dirs
- end
+ Dir.home.should == old_dirs[1].gsub("\\", "/")
+ ENV['HOMEDRIVE'] = "C:"
+ ENV['HOMEPATH'] = "\\rubyspec\\home1"
+ Dir.home.should == "C:/rubyspec/home1"
+ ENV['USERPROFILE'] = "C:\\rubyspec\\home2"
+ # https://bugs.ruby-lang.org/issues/19244
+ # Dir.home.should == "C:/rubyspec/home2"
+ ENV['HOME'] = "C:\\rubyspec\\home3"
+ Dir.home.should == "C:/rubyspec/home3"
+ ensure
+ ENV['HOME'], ENV['USERPROFILE'], ENV['HOMEDRIVE'], ENV['HOMEPATH'] = *old_dirs
end
end
end
@@ -84,10 +85,4 @@ describe "Dir.home" do
it "raises an ArgumentError if the named user doesn't exist" do
-> { Dir.home('geuw2n288dh2k') }.should raise_error(ArgumentError)
end
-
- describe "when called with a nil user name" do
- it "returns the current user's home directory, reading $HOME first" do
- Dir.home(nil).should == "/rubyspec_home"
- end
- end
end
diff --git a/spec/ruby/core/dir/shared/chroot.rb b/spec/ruby/core/dir/shared/chroot.rb
index a8f7c10a19..8c0599fe3f 100644
--- a/spec/ruby/core/dir/shared/chroot.rb
+++ b/spec/ruby/core/dir/shared/chroot.rb
@@ -2,7 +2,7 @@ describe :dir_chroot_as_root, shared: true do
before :all do
DirSpecs.create_mock_dirs
- @real_root = "../" * (__dir__.count('/') - 1)
+ @real_root = "../" * (File.dirname(__FILE__).count('/') - 1)
@ref_dir = File.join("/", File.basename(Dir["/*"].first))
end
@@ -18,7 +18,7 @@ describe :dir_chroot_as_root, shared: true do
compilations_ci = ENV["GITHUB_WORKFLOW"] == "Compilations"
it "can be used to change the process' root directory" do
- -> { Dir.send(@method, __dir__) }.should_not raise_error
+ -> { Dir.send(@method, File.dirname(__FILE__)) }.should_not raise_error
File.should.exist?("/#{File.basename(__FILE__)}")
end unless compilations_ci
diff --git a/spec/ruby/core/dir/shared/exist.rb b/spec/ruby/core/dir/shared/exist.rb
index 2ea4f88a80..765d1b656c 100644
--- a/spec/ruby/core/dir/shared/exist.rb
+++ b/spec/ruby/core/dir/shared/exist.rb
@@ -1,6 +1,6 @@
describe :dir_exist, shared: true do
it "returns true if the given directory exists" do
- Dir.send(@method, __dir__).should be_true
+ Dir.send(@method, File.dirname(__FILE__)).should be_true
end
it "returns true for '.'" do
@@ -20,7 +20,7 @@ describe :dir_exist, shared: true do
end
it "understands relative paths" do
- Dir.send(@method, __dir__ + '/../').should be_true
+ Dir.send(@method, File.dirname(__FILE__) + '/../').should be_true
end
it "returns false if the given directory doesn't exist" do
@@ -28,7 +28,7 @@ describe :dir_exist, shared: true do
end
it "doesn't require the name to have a trailing slash" do
- dir = __dir__
+ dir = File.dirname(__FILE__)
dir.sub!(/\/$/,'')
Dir.send(@method, dir).should be_true
end
@@ -50,7 +50,7 @@ describe :dir_exist, shared: true do
it "calls #to_path on non String arguments" do
p = mock('path')
- p.should_receive(:to_path).and_return(__dir__)
+ p.should_receive(:to_path).and_return(File.dirname(__FILE__))
Dir.send(@method, p)
end
end
diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb
index 27ae0e3000..33b2828c27 100644
--- a/spec/ruby/core/dir/shared/glob.rb
+++ b/spec/ruby/core/dir/shared/glob.rb
@@ -27,22 +27,24 @@ describe :dir_glob, shared: true do
-> {Dir.send(@method, "file_o*\0file_t*")}.should raise_error ArgumentError, /nul-separated/
end
- it "result is sorted by default" do
- result = Dir.send(@method, '*')
- result.should == result.sort
- end
+ ruby_version_is "3.0" do
+ it "result is sorted by default" do
+ result = Dir.send(@method, '*')
+ result.should == result.sort
+ end
- it "result is sorted with sort: true" do
- result = Dir.send(@method, '*', sort: true)
- result.should == result.sort
- end
+ it "result is sorted with sort: true" do
+ result = Dir.send(@method, '*', sort: true)
+ result.should == result.sort
+ end
- it "sort: false returns same files" do
- result = Dir.send(@method,'*', sort: false)
- result.sort.should == Dir.send(@method, '*').sort
+ it "sort: false returns same files" do
+ result = Dir.send(@method,'*', sort: false)
+ result.sort.should == Dir.send(@method, '*').sort
+ end
end
- ruby_version_is ""..."3.1" do
+ ruby_version_is "3.0"..."3.1" do
it "result is sorted with any non false value of sort:" do
result = Dir.send(@method, '*', sort: 0)
result.should == result.sort
diff --git a/spec/ruby/core/encoding/converter/primitive_convert_spec.rb b/spec/ruby/core/encoding/converter/primitive_convert_spec.rb
index ab34ebf33f..802d8e7cb1 100644
--- a/spec/ruby/core/encoding/converter/primitive_convert_spec.rb
+++ b/spec/ruby/core/encoding/converter/primitive_convert_spec.rb
@@ -14,10 +14,6 @@ describe "Encoding::Converter#primitive_convert" do
-> { @ec.primitive_convert("","") }.should_not raise_error
end
- it "raises FrozenError when the destination buffer is a frozen String" do
- -> { @ec.primitive_convert("", "".freeze) }.should raise_error(FrozenError)
- end
-
it "accepts nil for the destination byte offset" do
-> { @ec.primitive_convert("","", nil) }.should_not raise_error
end
diff --git a/spec/ruby/core/encoding/default_external_spec.rb b/spec/ruby/core/encoding/default_external_spec.rb
index 9aae4976e0..682d49d37c 100644
--- a/spec/ruby/core/encoding/default_external_spec.rb
+++ b/spec/ruby/core/encoding/default_external_spec.rb
@@ -18,9 +18,11 @@ describe "Encoding.default_external" do
Encoding.default_external.should == Encoding::SHIFT_JIS
end
- platform_is :windows do
- it 'is UTF-8 by default on Windows' do
- Encoding.default_external.should == Encoding::UTF_8
+ ruby_version_is "3.0" do
+ platform_is :windows do
+ it 'is UTF-8 by default on Windows' do
+ Encoding.default_external.should == Encoding::UTF_8
+ end
end
end
end
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb
index 2b15fc1a0f..f5fa6f55e3 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::InvalidByteSequenceError#destination_encoding_name" do
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb
index c2ed6de1d8..43be3ddd71 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::InvalidByteSequenceError#destination_encoding" do
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
index d2fc360dce..a8f7354b16 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
@@ -1,5 +1,4 @@
# -*- encoding: binary -*-
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::InvalidByteSequenceError#error_bytes" do
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
index 9866310c25..93823b5db4 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
@@ -1,5 +1,4 @@
# -*- encoding: binary -*-
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::InvalidByteSequenceError#readagain_bytes" do
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb
index a9464114a8..bd3a51cbc5 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::UndefinedConversionError#source_encoding_name" do
diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb
index 7fdc0a122b..f43d6d5830 100644
--- a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb
+++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::InvalidByteSequenceError#source_encoding" do
diff --git a/spec/ruby/core/encoding/name_spec.rb b/spec/ruby/core/encoding/name_spec.rb
index dce9347978..5eadb1d2f5 100644
--- a/spec/ruby/core/encoding/name_spec.rb
+++ b/spec/ruby/core/encoding/name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/name'
describe "Encoding#name" do
diff --git a/spec/ruby/core/encoding/replicate_spec.rb b/spec/ruby/core/encoding/replicate_spec.rb
index 498d03581a..848415eeb4 100644
--- a/spec/ruby/core/encoding/replicate_spec.rb
+++ b/spec/ruby/core/encoding/replicate_spec.rb
@@ -67,14 +67,6 @@ describe "Encoding#replicate" do
end
end
- ruby_version_is "3.2"..."3.3" do
- it "warns about deprecation" do
- -> {
- Encoding::US_ASCII.replicate('MY-US-ASCII')
- }.should complain(/warning: Encoding#replicate is deprecated and will be removed in Ruby 3.3; use the original encoding instead/)
- end
- end
-
ruby_version_is "3.3" do
it "has been removed" do
Encoding::US_ASCII.should_not.respond_to?(:replicate, true)
diff --git a/spec/ruby/core/encoding/to_s_spec.rb b/spec/ruby/core/encoding/to_s_spec.rb
index bab394a888..82d282386b 100644
--- a/spec/ruby/core/encoding/to_s_spec.rb
+++ b/spec/ruby/core/encoding/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/name'
describe "Encoding#to_s" do
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb
index a51a9f46a0..106fc7ecac 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::UndefinedConversionError#destination_encoding_name" do
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb
index 905556407c..c6e24732fd 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::UndefinedConversionError#destination_encoding" do
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb
index 9cb55e6d95..780d81c1ee 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::UndefinedConversionError#error_char" do
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb
index d5e60e78db..3b697cb82f 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::UndefinedConversionError#source_encoding_name" do
diff --git a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb
index de456a4b5a..9101d51e11 100644
--- a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb
+++ b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative '../fixtures/classes'
describe "Encoding::UndefinedConversionError#source_encoding" do
diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb
index 160cd52628..0ded1e8eba 100644
--- a/spec/ruby/core/enumerable/all_spec.rb
+++ b/spec/ruby/core/enumerable/all_spec.rb
@@ -177,11 +177,5 @@ describe "Enumerable#all?" do
multi.all?(pattern).should == true
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
-
- it "ignores the block if there is an argument" do
- -> {
- EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).all?(String) { true }.should == false
- }.should complain(/given block not used/)
- end
end
end
diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb
index 243f8735d5..355cd0c290 100644
--- a/spec/ruby/core/enumerable/any_spec.rb
+++ b/spec/ruby/core/enumerable/any_spec.rb
@@ -190,11 +190,5 @@ describe "Enumerable#any?" do
multi.any?(pattern).should == false
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
-
- it "ignores the block if there is an argument" do
- -> {
- EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).any?(String) { true }.should == false
- }.should complain(/given block not used/)
- end
end
end
diff --git a/spec/ruby/core/enumerable/chunk_spec.rb b/spec/ruby/core/enumerable/chunk_spec.rb
index ed6304307f..c5579d67fa 100644
--- a/spec/ruby/core/enumerable/chunk_spec.rb
+++ b/spec/ruby/core/enumerable/chunk_spec.rb
@@ -29,11 +29,6 @@ describe "Enumerable#chunk" do
result.should == [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]]
end
- it "returns a partitioned Array of values" do
- e = EnumerableSpecs::Numerous.new(1,2,3)
- e.chunk { |x| x > 2 }.map(&:last).should == [[1, 2], [3]]
- end
-
it "returns elements for which the block returns :_alone in separate Arrays" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
result = e.chunk { |x| x < 2 && :_alone }.to_a
diff --git a/spec/ruby/core/enumerable/grep_spec.rb b/spec/ruby/core/enumerable/grep_spec.rb
index 989358f01b..b81075291f 100644
--- a/spec/ruby/core/enumerable/grep_spec.rb
+++ b/spec/ruby/core/enumerable/grep_spec.rb
@@ -40,28 +40,43 @@ describe "Enumerable#grep" do
$~.should == nil
end
- it "does not set $~ when given no block" do
- "z" =~ /z/ # Reset $~
- ["abc", "def"].grep(/b/).should == ["abc"]
- $&.should == "z"
- end
+ ruby_version_is ""..."3.0.0" do
+ it "sets $~ to the last match when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep(/b/).should == ["abc"]
+
+ # Set by the failed match of "def"
+ $~.should == nil
- it "does not modify Regexp.last_match without block" do
- "z" =~ /z/ # Reset last match
- ["abc", "def"].grep(/b/).should == ["abc"]
- Regexp.last_match[0].should == "z"
+ ["abc", "def"].grep(/e/)
+ $&.should == "e"
+ end
end
- it "correctly handles non-string elements" do
- 'set last match' =~ /set last (.*)/
- [:a, 'b', 'z', :c, 42, nil].grep(/[a-d]/).should == [:a, 'b', :c]
- $1.should == 'match'
+ ruby_version_is "3.0.0" do
+ it "does not set $~ when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep(/b/).should == ["abc"]
+ $&.should == "z"
+ end
- o = Object.new
- def o.to_str
- 'hello'
+ it "does not modify Regexp.last_match without block" do
+ "z" =~ /z/ # Reset last match
+ ["abc", "def"].grep(/b/).should == ["abc"]
+ Regexp.last_match[0].should == "z"
+ end
+
+ it "correctly handles non-string elements" do
+ 'set last match' =~ /set last (.*)/
+ [:a, 'b', 'z', :c, 42, nil].grep(/[a-d]/).should == [:a, 'b', :c]
+ $1.should == 'match'
+
+ o = Object.new
+ def o.to_str
+ 'hello'
+ end
+ [o].grep(/ll/).first.should.equal?(o)
end
- [o].grep(/ll/).first.should.equal?(o)
end
describe "with a block" do
diff --git a/spec/ruby/core/enumerable/grep_v_spec.rb b/spec/ruby/core/enumerable/grep_v_spec.rb
index ba19216968..35fde27eb6 100644
--- a/spec/ruby/core/enumerable/grep_v_spec.rb
+++ b/spec/ruby/core/enumerable/grep_v_spec.rb
@@ -20,28 +20,43 @@ describe "Enumerable#grep_v" do
$&.should == "e"
end
- it "does not set $~ when given no block" do
- "z" =~ /z/ # Reset $~
- ["abc", "def"].grep_v(/e/).should == ["abc"]
- $&.should == "z"
- end
+ ruby_version_is ""..."3.0.0" do
+ it "sets $~ to the last match when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep_v(/e/).should == ["abc"]
- it "does not modify Regexp.last_match without block" do
- "z" =~ /z/ # Reset last match
- ["abc", "def"].grep_v(/e/).should == ["abc"]
- Regexp.last_match[0].should == "z"
+ # Set by the match of "def"
+ $&.should == "e"
+
+ ["abc", "def"].grep_v(/b/)
+ $&.should == nil
+ end
end
- it "correctly handles non-string elements" do
- 'set last match' =~ /set last (.*)/
- [:a, 'b', 'z', :c, 42, nil].grep_v(/[a-d]/).should == ['z', 42, nil]
- $1.should == 'match'
+ ruby_version_is "3.0.0" do
+ it "does not set $~ when given no block" do
+ "z" =~ /z/ # Reset $~
+ ["abc", "def"].grep_v(/e/).should == ["abc"]
+ $&.should == "z"
+ end
+
+ it "does not modify Regexp.last_match without block" do
+ "z" =~ /z/ # Reset last match
+ ["abc", "def"].grep_v(/e/).should == ["abc"]
+ Regexp.last_match[0].should == "z"
+ end
+
+ it "correctly handles non-string elements" do
+ 'set last match' =~ /set last (.*)/
+ [:a, 'b', 'z', :c, 42, nil].grep_v(/[a-d]/).should == ['z', 42, nil]
+ $1.should == 'match'
- o = Object.new
- def o.to_str
- 'hello'
+ o = Object.new
+ def o.to_str
+ 'hello'
+ end
+ [o].grep_v(/mm/).first.should.equal?(o)
end
- [o].grep_v(/mm/).first.should.equal?(o)
end
describe "without block" do
diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb
index fb42f13386..99bb7f7a4e 100644
--- a/spec/ruby/core/enumerable/none_spec.rb
+++ b/spec/ruby/core/enumerable/none_spec.rb
@@ -143,11 +143,5 @@ describe "Enumerable#none?" do
multi.none?(pattern).should == true
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
-
- it "ignores the block if there is an argument" do
- -> {
- EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).none?(String) { true }.should == true
- }.should complain(/given block not used/)
- end
end
end
diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb
index 4bf8623d2e..47bfd65a0f 100644
--- a/spec/ruby/core/enumerable/one_spec.rb
+++ b/spec/ruby/core/enumerable/one_spec.rb
@@ -83,6 +83,7 @@ describe "Enumerable#one?" do
end
end
+
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 1 }
@@ -144,11 +145,5 @@ describe "Enumerable#one?" do
multi.one?(pattern).should == false
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
-
- it "ignores the block if there is an argument" do
- -> {
- EnumerableSpecs::Numerous.new(1, 2, 3, 4, "5").one?(String) { false }.should == true
- }.should complain(/given block not used/)
- end
end
end
diff --git a/spec/ruby/core/enumerable/shared/inject.rb b/spec/ruby/core/enumerable/shared/inject.rb
index 693d34d675..c5907f92d8 100644
--- a/spec/ruby/core/enumerable/shared/inject.rb
+++ b/spec/ruby/core/enumerable/shared/inject.rb
@@ -1,5 +1,3 @@
-require_relative '../../array/shared/iterable_and_tolerating_size_increasing'
-
describe :enumerable_inject, shared: true do
it "with argument takes a block with an accumulator (with argument as initial value) and the current element. Value of block becomes new accumulator" do
a = []
@@ -19,22 +17,8 @@ describe :enumerable_inject, shared: true do
end
it "ignores the block if two arguments" do
- -> {
- EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-) { raise "we never get here"}.should == 4
- }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)
-
- -> {
- [1, 2, 3].send(@method, 10, :-) { raise "we never get here"}.should == 4
- }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)
- end
-
- it "does not warn when given a Symbol with $VERBOSE true" do
- -> {
- [1, 2].send(@method, 0, :+)
- [1, 2].send(@method, :+)
- EnumerableSpecs::Numerous.new(1, 2).send(@method, 0, :+)
- EnumerableSpecs::Numerous.new(1, 2).send(@method, :+)
- }.should_not complain(verbose: true)
+ EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-) { raise "we never get here"}.should == 4
+ [].send(@method, 3, :+) { raise "we never get here"}.should == 3
end
it "can take a symbol argument" do
@@ -47,10 +31,10 @@ describe :enumerable_inject, shared: true do
a.should == [[2, 5], [5, 3], [3, 6], [6, 1], [1, 4]]
end
- it "gathers whole arrays as elements when each yields multiple" do
- multi = EnumerableSpecs::YieldsMulti.new
- multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
- end
+ it "gathers whole arrays as elements when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
+ end
it "with inject arguments(legacy rubycon)" do
# with inject argument
@@ -84,22 +68,6 @@ describe :enumerable_inject, shared: true do
EnumerableSpecs::EachDefiner.new().send(@method) {|acc,x| 999 }.should == nil
end
- it "tolerates increasing a collection size during iterating Array" do
- array = [:a, :b, :c]
- ScratchPad.record []
- i = 0
-
- array.send(@method, nil) do |_, e|
- ScratchPad << e
- array << i if i < 100
- i += 1
- end
-
- actual = ScratchPad.recorded
- expected = [:a, :b, :c] + (0..99).to_a
- actual.sort_by(&:to_s).should == expected.sort_by(&:to_s)
- end
-
ruby_bug '#18635', ''...'3.2' do
it "raises an ArgumentError when no parameters or block is given" do
-> { [1,2].send(@method) }.should raise_error(ArgumentError)
diff --git a/spec/ruby/core/enumerable/sum_spec.rb b/spec/ruby/core/enumerable/sum_spec.rb
index 2eb74db6ac..fc173e4173 100644
--- a/spec/ruby/core/enumerable/sum_spec.rb
+++ b/spec/ruby/core/enumerable/sum_spec.rb
@@ -40,7 +40,7 @@ describe 'Enumerable#sum' do
end
# https://bugs.ruby-lang.org/issues/12217
- # https://github.com/ruby/ruby/blob/master/doc/ChangeLog/ChangeLog-2.4.0#L6208-L6214
+ # https://github.com/ruby/ruby/blob/master/doc/ChangeLog-2.4.0#L6208-L6214
it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do
floats = [2.7800000000000002, 5.0, 2.5, 4.44, 3.89, 3.89, 4.44, 7.78, 5.0, 2.7800000000000002, 5.0, 2.5].to_enum
naive_sum = floats.reduce { |sum, e| sum + e }
diff --git a/spec/ruby/core/enumerable/tally_spec.rb b/spec/ruby/core/enumerable/tally_spec.rb
index e0edc8dc75..f09a8f533a 100644
--- a/spec/ruby/core/enumerable/tally_spec.rb
+++ b/spec/ruby/core/enumerable/tally_spec.rb
@@ -49,13 +49,6 @@ ruby_version_is "3.1" do
enum.tally(hash).should equal(hash)
end
- it "calls #to_hash to convert argument to Hash implicitly if passed not a Hash" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- object = Object.new
- def object.to_hash; { 'foo' => 1 }; end
- enum.tally(object).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1}
- end
-
it "raises a FrozenError and does not update the given hash when the hash is frozen" do
enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
hash = { 'foo' => 1 }.freeze
@@ -63,12 +56,6 @@ ruby_version_is "3.1" do
hash.should == { 'foo' => 1 }
end
- it "raises a FrozenError even if enumerable is empty" do
- enum = EnumerableSpecs::Numerous.new()
- hash = { 'foo' => 1 }.freeze
- -> { enum.tally(hash) }.should raise_error(FrozenError)
- end
-
it "does not call given block" do
enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
enum.tally({ 'foo' => 1 }) { |v| ScratchPad << v }
diff --git a/spec/ruby/core/enumerator/chain/initialize_spec.rb b/spec/ruby/core/enumerator/chain/initialize_spec.rb
index daa30351d7..69484dfcb4 100644
--- a/spec/ruby/core/enumerator/chain/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/chain/initialize_spec.rb
@@ -22,10 +22,10 @@ describe "Enumerator::Chain#initialize" do
end
describe "on frozen instance" do
- it "raises a FrozenError" do
+ it "raises a RuntimeError" do
-> {
@uninitialized.freeze.send(:initialize)
- }.should raise_error(FrozenError)
+ }.should raise_error(RuntimeError)
end
end
end
diff --git a/spec/ruby/core/enumerator/chain/inspect_spec.rb b/spec/ruby/core/enumerator/chain/inspect_spec.rb
index 9b5a442b75..a0450c808a 100644
--- a/spec/ruby/core/enumerator/chain/inspect_spec.rb
+++ b/spec/ruby/core/enumerator/chain/inspect_spec.rb
@@ -11,8 +11,4 @@ describe "Enumerator::Chain#inspect" do
obj.should_receive(:inspect).and_return('some desc')
Enumerator::Chain.new(obj).inspect.should == "#<Enumerator::Chain: [some desc]>"
end
-
- it "returns a not initialized representation if #initialized is not called yet" do
- Enumerator::Chain.allocate.inspect.should == "#<Enumerator::Chain: uninitialized>"
- end
end
diff --git a/spec/ruby/core/enumerator/each_spec.rb b/spec/ruby/core/enumerator/each_spec.rb
index 3af16e5587..99ac3120af 100644
--- a/spec/ruby/core/enumerator/each_spec.rb
+++ b/spec/ruby/core/enumerator/each_spec.rb
@@ -10,41 +10,41 @@ describe "Enumerator#each" do
@enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2)
- @enum_with_yielder = Enumerator.new { |y| y.yield :ok }
+ @enum_with_yielder = Enumerator.new {|y| y.yield :ok}
end
it "yields each element of self to the given block" do
acc = []
- [1, 2, 3].to_enum.each { |e| acc << e }
- acc.should == [1, 2, 3]
+ [1,2,3].to_enum.each {|e| acc << e }
+ acc.should == [1,2,3]
end
it "calls #each on the object given in the constructor by default" do
each = mock('each')
each.should_receive(:each)
- each.to_enum.each { |e| e }
+ each.to_enum.each {|e| e }
end
it "calls #each on the underlying object until it's exhausted" do
each = mock('each')
each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
acc = []
- each.to_enum.each { |e| acc << e }
- acc.should == [1, 2, 3]
+ each.to_enum.each {|e| acc << e }
+ acc.should == [1,2,3]
end
it "calls the method given in the constructor instead of #each" do
each = mock('peach')
each.should_receive(:peach)
- each.to_enum(:peach).each { |e| e }
+ each.to_enum(:peach).each {|e| e }
end
it "calls the method given in the constructor until it's exhausted" do
each = mock('peach')
each.should_receive(:peach).and_yield(1).and_yield(2).and_yield(3)
acc = []
- each.to_enum(:peach).each { |e| acc << e }
- acc.should == [1, 2, 3]
+ each.to_enum(:peach).each {|e| acc << e }
+ acc.should == [1,2,3]
end
it "raises a NoMethodError if the object doesn't respond to #each" do
diff --git a/spec/ruby/core/enumerator/generator/initialize_spec.rb b/spec/ruby/core/enumerator/generator/initialize_spec.rb
index acc1174253..f75c7d6f26 100644
--- a/spec/ruby/core/enumerator/generator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/generator/initialize_spec.rb
@@ -17,10 +17,10 @@ describe "Enumerator::Generator#initialize" do
end
describe "on frozen instance" do
- it "raises a FrozenError" do
+ it "raises a RuntimeError" do
-> {
@uninitialized.freeze.send(:initialize) {}
- }.should raise_error(FrozenError)
+ }.should raise_error(RuntimeError)
end
end
end
diff --git a/spec/ruby/core/enumerator/initialize_spec.rb b/spec/ruby/core/enumerator/initialize_spec.rb
index 5e0256ca46..217af1d3bc 100644
--- a/spec/ruby/core/enumerator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/initialize_spec.rb
@@ -11,6 +11,14 @@ describe "Enumerator#initialize" do
Enumerator.should have_private_instance_method(:initialize, false)
end
+ ruby_version_is ''...'3.0' do
+ it "returns self when given an object" do
+ suppress_warning do
+ @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ end
+ end
+ end
+
it "returns self when given a block" do
@uninitialized.send(:initialize) {}.should equal(@uninitialized)
end
@@ -48,10 +56,10 @@ describe "Enumerator#initialize" do
end
describe "on frozen instance" do
- it "raises a FrozenError" do
+ it "raises a RuntimeError" do
-> {
@uninitialized.freeze.send(:initialize) {}
- }.should raise_error(FrozenError)
+ }.should raise_error(RuntimeError)
end
end
end
diff --git a/spec/ruby/core/enumerator/inspect_spec.rb b/spec/ruby/core/enumerator/inspect_spec.rb
index 7e97864246..3bcf07e754 100644
--- a/spec/ruby/core/enumerator/inspect_spec.rb
+++ b/spec/ruby/core/enumerator/inspect_spec.rb
@@ -14,9 +14,4 @@ describe "Enumerator#inspect" do
(1..3).each.each_slice(2).inspect.should == "#<Enumerator: #<Enumerator: 1..3:each>:each_slice(2)>"
end
end
-
- it "returns a not initialized representation if #initialized is not called yet" do
- Enumerator.allocate.inspect.should == "#<Enumerator: uninitialized>"
- Enumerator::Lazy.allocate.inspect.should == "#<Enumerator::Lazy: uninitialized>"
- end
end
diff --git a/spec/ruby/core/enumerator/lazy/compact_spec.rb b/spec/ruby/core/enumerator/lazy/compact_spec.rb
index e678bc71eb..80b6f9481d 100644
--- a/spec/ruby/core/enumerator/lazy/compact_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/compact_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../../spec_helper'
-require_relative 'fixtures/classes'
ruby_version_is '3.1' do
describe "Enumerator::Lazy#compact" do
@@ -8,9 +7,5 @@ ruby_version_is '3.1' do
arr.should be_an_instance_of(Enumerator::Lazy)
arr.force.should == [1, 3, false, 5]
end
-
- it "sets #size to nil" do
- Enumerator::Lazy.new(Object.new, 100) {}.compact.size.should == nil
- end
end
end
diff --git a/spec/ruby/core/enumerator/lazy/initialize_spec.rb b/spec/ruby/core/enumerator/lazy/initialize_spec.rb
index e1e0b1d608..f23018d010 100644
--- a/spec/ruby/core/enumerator/lazy/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/initialize_spec.rb
@@ -56,8 +56,8 @@ describe "Enumerator::Lazy#initialize" do
end
describe "on frozen instance" do
- it "raises a FrozenError" do
- -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(FrozenError)
+ it "raises a RuntimeError" do
+ -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(RuntimeError)
end
end
end
diff --git a/spec/ruby/core/enumerator/new_spec.rb b/spec/ruby/core/enumerator/new_spec.rb
index 671912224f..c439469525 100644
--- a/spec/ruby/core/enumerator/new_spec.rb
+++ b/spec/ruby/core/enumerator/new_spec.rb
@@ -2,8 +2,51 @@ require_relative '../../spec_helper'
describe "Enumerator.new" do
context "no block given" do
- it "raises" do
- -> { Enumerator.new(1, :upto, 3) }.should raise_error(ArgumentError)
+ ruby_version_is '3.0' do
+ it "raises" do
+ -> { Enumerator.new(1, :upto, 3) }.should raise_error(ArgumentError)
+ end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "creates a new custom enumerator with the given object, iterator and arguments" do
+ enum = suppress_warning { Enumerator.new(1, :upto, 3) }
+ enum.should be_an_instance_of(Enumerator)
+ end
+
+ it "creates a new custom enumerator that responds to #each" do
+ enum = suppress_warning { Enumerator.new(1, :upto, 3) }
+ enum.respond_to?(:each).should == true
+ end
+
+ it "creates a new custom enumerator that runs correctly" do
+ suppress_warning { Enumerator.new(1, :upto, 3) }.map{ |x| x }.should == [1,2,3]
+ end
+
+ it "aliases the second argument to :each" do
+ suppress_warning { Enumerator.new(1..2) }.to_a.should ==
+ suppress_warning { Enumerator.new(1..2, :each) }.to_a
+ end
+
+ it "doesn't check for the presence of the iterator method" do
+ suppress_warning { Enumerator.new(nil) }.should be_an_instance_of(Enumerator)
+ end
+
+ it "uses the latest define iterator method" do
+ class StrangeEach
+ def each
+ yield :foo
+ end
+ end
+ enum = suppress_warning { Enumerator.new(StrangeEach.new) }
+ enum.to_a.should == [:foo]
+ class StrangeEach
+ def each
+ yield :bar
+ end
+ end
+ enum.to_a.should == [:bar]
+ end
end
end
diff --git a/spec/ruby/core/enumerator/product/each_spec.rb b/spec/ruby/core/enumerator/product/each_spec.rb
deleted file mode 100644
index 868a1ea6bf..0000000000
--- a/spec/ruby/core/enumerator/product/each_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../../enumerable/shared/enumeratorized'
-
-ruby_version_is "3.2" do
- describe "Enumerator::Product#each" do
- it_behaves_like :enumeratorized_with_origin_size, :each, Enumerator::Product.new([1, 2], [:a, :b])
-
- it "yields each element of Cartesian product of enumerators" do
- enum = Enumerator::Product.new([1, 2], [:a, :b])
- acc = []
- enum.each { |e| acc << e }
- acc.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "calls #each_entry method on enumerators" do
- object1 = Object.new
- def object1.each_entry
- yield 1
- yield 2
- end
-
- object2 = Object.new
- def object2.each_entry
- yield :a
- yield :b
- end
-
- enum = Enumerator::Product.new(object1, object2)
- acc = []
- enum.each { |e| acc << e }
- acc.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "raises a NoMethodError if the object doesn't respond to #each_entry" do
- -> {
- Enumerator::Product.new(Object.new).each {}
- }.should raise_error(NoMethodError, /undefined method `each_entry' for/)
- end
-
- it "returns enumerator if not given a block" do
- enum = Enumerator::Product.new([1, 2], [:a, :b])
- enum.each.should.kind_of?(Enumerator)
-
- enum = Enumerator::Product.new([1, 2], [:a, :b])
- enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "returns self if given a block" do
- enum = Enumerator::Product.new([1, 2], [:a, :b])
- enum.each {}.should.equal?(enum)
- end
-
- it "doesn't accept arguments" do
- Enumerator::Product.instance_method(:each).arity.should == 0
- end
-
- it "yields each element to a block that takes multiple arguments" do
- enum = Enumerator::Product.new([1, 2], [:a, :b])
-
- acc = []
- enum.each { |x, y| acc << x }
- acc.should == [1, 1, 2, 2]
-
- acc = []
- enum.each { |x, y| acc << y }
- acc.should == [:a, :b, :a, :b]
-
- acc = []
- enum.each { |x, y, z| acc << z }
- acc.should == [nil, nil, nil, nil]
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/product/initialize_copy_spec.rb b/spec/ruby/core/enumerator/product/initialize_copy_spec.rb
deleted file mode 100644
index 46e8421322..0000000000
--- a/spec/ruby/core/enumerator/product/initialize_copy_spec.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Enumerator::Product#initialize_copy" do
- it "replaces content of the receiver with content of the other object" do
- enum = Enumerator::Product.new([true, false])
- enum2 = Enumerator::Product.new([1, 2], [:a, :b])
-
- enum.send(:initialize_copy, enum2)
- enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "returns self" do
- enum = Enumerator::Product.new([true, false])
- enum2 = Enumerator::Product.new([1, 2], [:a, :b])
-
- enum.send(:initialize_copy, enum2).should.equal?(enum)
- end
-
- it "is a private method" do
- Enumerator::Product.should have_private_instance_method(:initialize_copy, false)
- end
-
- it "does nothing if the argument is the same as the receiver" do
- enum = Enumerator::Product.new(1..2)
- enum.send(:initialize_copy, enum).should.equal?(enum)
-
- enum.freeze
- enum.send(:initialize_copy, enum).should.equal?(enum)
- end
-
- it "raises FrozenError if the receiver is frozen" do
- enum = Enumerator::Product.new(1..2)
- enum2 = Enumerator::Product.new(3..4)
-
- -> { enum.freeze.send(:initialize_copy, enum2) }.should raise_error(FrozenError)
- end
-
- it "raises TypeError if the objects are of different class" do
- enum = Enumerator::Product.new(1..2)
- enum2 = Class.new(Enumerator::Product).new(3..4)
-
- -> { enum.send(:initialize_copy, enum2) }.should raise_error(TypeError, 'initialize_copy should take same class object')
- -> { enum2.send(:initialize_copy, enum) }.should raise_error(TypeError, 'initialize_copy should take same class object')
- end
-
- it "raises ArgumentError if the argument is not initialized yet" do
- enum = Enumerator::Product.new(1..2)
- enum2 = Enumerator::Product.allocate
-
- -> { enum.send(:initialize_copy, enum2) }.should raise_error(ArgumentError, 'uninitialized product')
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/product/initialize_spec.rb b/spec/ruby/core/enumerator/product/initialize_spec.rb
deleted file mode 100644
index 4b60564240..0000000000
--- a/spec/ruby/core/enumerator/product/initialize_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Enumerator::Product#initialize" do
- before :each do
- @uninitialized = Enumerator::Product.allocate
- end
-
- it "is a private method" do
- Enumerator::Product.should have_private_instance_method(:initialize, false)
- end
-
- it "returns self" do
- @uninitialized.send(:initialize).should equal(@uninitialized)
- end
-
- it "accepts many arguments" do
- @uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized)
- end
-
- it "accepts arguments that are not Enumerable nor responding to :each_entry" do
- @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
- end
-
- describe "on frozen instance" do
- it "raises a FrozenError" do
- -> {
- @uninitialized.freeze.send(:initialize, 0..1)
- }.should raise_error(FrozenError)
- end
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/product/inspect_spec.rb b/spec/ruby/core/enumerator/product/inspect_spec.rb
deleted file mode 100644
index 1ea8e9c49b..0000000000
--- a/spec/ruby/core/enumerator/product/inspect_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Enumerator::Product#inspect" do
- it "returns a String including enumerators" do
- enum = Enumerator::Product.new([1, 2], [:a, :b])
- enum.inspect.should == "#<Enumerator::Product: [[1, 2], [:a, :b]]>"
- end
-
- it "represents a recursive element with '[...]'" do
- enum = [1, 2]
- enum_recursive = Enumerator::Product.new(enum)
-
- enum << enum_recursive
- enum_recursive.inspect.should == "#<Enumerator::Product: [[1, 2, #<Enumerator::Product: ...>]]>"
- end
-
- it "returns a not initialized representation if #initialized is not called yet" do
- Enumerator::Product.allocate.inspect.should == "#<Enumerator::Product: uninitialized>"
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/product/rewind_spec.rb b/spec/ruby/core/enumerator/product/rewind_spec.rb
deleted file mode 100644
index e8ee730239..0000000000
--- a/spec/ruby/core/enumerator/product/rewind_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Enumerator::Product#rewind" do
- before :each do
- @enum = Enumerator::Product.new([1, 2].each.to_enum, [:a, :b].each.to_enum)
- end
-
- it "resets the enumerator to its initial state" do
- @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- @enum.rewind
- @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "returns self" do
- @enum.rewind.should.equal? @enum
- end
-
- it "has no effect on a new enumerator" do
- @enum.rewind
- @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "has no effect if called multiple, consecutive times" do
- @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- @enum.rewind
- @enum.rewind
- @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
- end
-
- it "calls the enclosed object's rewind method if one exists" do
- obj = mock('rewinder')
- enum = Enumerator::Product.new(obj.to_enum)
-
- obj.should_receive(:rewind)
- enum.rewind
- end
-
- it "does nothing if the object doesn't have a #rewind method" do
- obj = mock('rewinder')
- enum = Enumerator::Product.new(obj.to_enum)
-
- enum.rewind.should == enum
- end
-
- it "calls a rewind method on each enumerable in direct order" do
- ScratchPad.record []
-
- object1 = Object.new
- def object1.rewind; ScratchPad << :object1; end
-
- object2 = Object.new
- def object2.rewind; ScratchPad << :object2; end
-
- object3 = Object.new
- def object3.rewind; ScratchPad << :object3; end
-
- enum = Enumerator::Product.new(object1, object2, object3)
- enum.rewind
-
- ScratchPad.recorded.should == [:object1, :object2, :object3]
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/product/size_spec.rb b/spec/ruby/core/enumerator/product/size_spec.rb
deleted file mode 100644
index fb0efdf748..0000000000
--- a/spec/ruby/core/enumerator/product/size_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Enumerator::Product#size" do
- it "returns the total size of the enumerator product calculated by multiplying the sizes of enumerables in the product" do
- product = Enumerator::Product.new(1..2, 1..3, 1..4)
- product.size.should == 24 # 2 * 3 * 4
- end
-
- it "returns nil if any enumerable reports its size as nil" do
- enum = Object.new
- def enum.size; nil; end
-
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == nil
- end
-
- it "returns Float::INFINITY if any enumerable reports its size as Float::INFINITY" do
- enum = Object.new
- def enum.size; Float::INFINITY; end
-
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == Float::INFINITY
- end
-
- it "returns -Float::INFINITY if any enumerable reports its size as -Float::INFINITY" do
- enum = Object.new
- def enum.size; -Float::INFINITY; end
-
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == -Float::INFINITY
- end
-
- it "returns nil if any enumerable reports its size as Float::NAN" do
- enum = Object.new
- def enum.size; Float::NAN; end
-
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == nil
- end
-
- it "returns nil if any enumerable doesn't respond to #size" do
- enum = Object.new
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == nil
- end
-
- it "returns nil if any enumerable reports a not-convertible to Integer" do
- enum = Object.new
- def enum.size; :symbol; end
-
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == nil
- end
-
- it "returns nil if any enumerable reports a non-Integer but convertible to Integer size" do
- enum = Object.new
- def enum.size; 1.0; end
-
- product = Enumerator::Product.new(1..2, enum)
- product.size.should == nil
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/product_spec.rb b/spec/ruby/core/enumerator/product_spec.rb
deleted file mode 100644
index 0fb00fc7ee..0000000000
--- a/spec/ruby/core/enumerator/product_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-require_relative '../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Enumerator.product" do
- it "returns a Cartesian product of enumerators" do
- enum = Enumerator.product(1..2, ["A", "B"])
- enum.to_a.should == [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
- end
-
- it "accepts a list of enumerators of any length" do
- enum = Enumerator.product(1..2)
- enum.to_a.should == [[1], [2]]
-
- enum = Enumerator.product(1..2, ["A"])
- enum.to_a.should == [[1, "A"], [2, "A"]]
-
- enum = Enumerator.product(1..2, ["A"], ["B"])
- enum.to_a.should == [[1, "A", "B"], [2, "A", "B"]]
-
- enum = Enumerator.product(2..3, ["A"], ["B"], ["C"])
- enum.to_a.should == [[2, "A", "B", "C"], [3, "A", "B", "C"]]
- end
-
- it "returns an enumerator with an empty array when no arguments passed" do
- enum = Enumerator.product
- enum.to_a.should == [[]]
- end
-
- it "returns an instance of Enumerator::Product" do
- enum = Enumerator.product
- enum.class.should == Enumerator::Product
- end
-
- it "accepts infinite enumerators and returns infinite enumerator" do
- enum = Enumerator.product(1.., ["A", "B"])
- enum.take(5).should == [[1, "A"], [1, "B"], [2, "A"], [2, "B"], [3, "A"]]
- enum.size.should == Float::INFINITY
- end
-
- it "accepts a block" do
- elems = []
- enum = Enumerator.product(1..2, ["X", "Y"]) { elems << _1 }
-
- elems.should == [[1, "X"], [1, "Y"], [2, "X"], [2, "Y"]]
- end
-
- it "returns nil when a block passed" do
- Enumerator.product(1..2) {}.should == nil
- end
-
- # https://bugs.ruby-lang.org/issues/19829
- it "reject keyword arguments" do
- -> {
- Enumerator.product(1..3, foo: 1, bar: 2)
- }.should raise_error(ArgumentError, "unknown keywords: :foo, :bar")
- end
-
- it "calls only #each_entry method on arguments" do
- object = Object.new
- def object.each_entry
- yield 1
- yield 2
- end
-
- enum = Enumerator.product(object, ["A", "B"])
- enum.to_a.should == [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
- end
-
- it "raises NoMethodError when argument doesn't respond to #each_entry" do
- -> {
- Enumerator.product(Object.new).to_a
- }.should raise_error(NoMethodError, /undefined method `each_entry' for/)
- end
-
- it "calls #each_entry lazily" do
- Enumerator.product(Object.new).should be_kind_of(Enumerator)
- end
-
- it "iterates through consuming enumerator elements only once" do
- a = [1, 2, 3]
- i = 0
-
- enum = Enumerator.new do |y|
- while i < a.size
- y << a[i]
- i += 1
- end
- end
-
- Enumerator.product(['a', 'b'], enum).to_a.should == [["a", 1], ["a", 2], ["a", 3]]
- end
- end
-end
diff --git a/spec/ruby/core/enumerator/rewind_spec.rb b/spec/ruby/core/enumerator/rewind_spec.rb
index 6ba0edf174..a105f2c619 100644
--- a/spec/ruby/core/enumerator/rewind_spec.rb
+++ b/spec/ruby/core/enumerator/rewind_spec.rb
@@ -14,7 +14,7 @@ describe "Enumerator#rewind" do
end
it "returns self" do
- @enum.rewind.should.equal? @enum
+ @enum.rewind.should == @enum
end
it "has no effect on a new enumerator" do
@@ -49,7 +49,7 @@ describe "Enumerator#rewind" do
obj = mock('rewinder')
enum = obj.to_enum
obj.should_receive(:each).at_most(1)
- enum.rewind.should == enum
+ -> { enum.rewind.should == enum }.should_not raise_error
end
end
diff --git a/spec/ruby/core/env/clone_spec.rb b/spec/ruby/core/env/clone_spec.rb
deleted file mode 100644
index 991e4e6774..0000000000
--- a/spec/ruby/core/env/clone_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "ENV#clone" do
- it "raises ArgumentError when keyword argument 'freeze' is neither nil nor boolean" do
- -> {
- ENV.clone(freeze: 1)
- }.should raise_error(ArgumentError)
- end
-
- it "raises ArgumentError when keyword argument is not 'freeze'" do
- -> {
- ENV.clone(foo: nil)
- }.should raise_error(ArgumentError)
- end
-
- ruby_version_is "3.2" do
- it "raises TypeError" do
- -> {
- ENV.clone
- }.should raise_error(TypeError, /Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash/)
- end
- end
-end
diff --git a/spec/ruby/core/env/delete_spec.rb b/spec/ruby/core/env/delete_spec.rb
index f28ac97911..5e7891f74d 100644
--- a/spec/ruby/core/env/delete_spec.rb
+++ b/spec/ruby/core/env/delete_spec.rb
@@ -30,9 +30,11 @@ describe "ENV.delete" do
ScratchPad.recorded.should == "foo"
end
- it "returns the result of given block if the named environment variable does not exist" do
- ENV.delete("foo")
- ENV.delete("foo") { |name| "bar" }.should == "bar"
+ ruby_version_is "3.0" do
+ it "returns the result of given block if the named environment variable does not exist" do
+ ENV.delete("foo")
+ ENV.delete("foo") { |name| "bar" }.should == "bar"
+ end
end
it "does not evaluate the block if the environment variable exists" do
@@ -41,14 +43,6 @@ describe "ENV.delete" do
ENV["foo"].should == nil
end
- it "removes the variable coerced with #to_str" do
- ENV["foo"] = "bar"
- k = mock('key')
- k.should_receive(:to_str).and_return("foo")
- ENV.delete(k)
- ENV["foo"].should == nil
- end
-
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.delete(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
diff --git a/spec/ruby/core/env/dup_spec.rb b/spec/ruby/core/env/dup_spec.rb
deleted file mode 100644
index 46d125aca8..0000000000
--- a/spec/ruby/core/env/dup_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "ENV#dup" do
- ruby_version_is "3.1" do
- it "raises TypeError" do
- -> {
- ENV.dup
- }.should raise_error(TypeError, /Cannot dup ENV, use ENV.to_h to get a copy of ENV as a hash/)
- end
- end
-end
diff --git a/spec/ruby/core/env/except_spec.rb b/spec/ruby/core/env/except_spec.rb
index fb8f3b7536..cfe5865abe 100644
--- a/spec/ruby/core/env/except_spec.rb
+++ b/spec/ruby/core/env/except_spec.rb
@@ -1,34 +1,36 @@
require_relative 'spec_helper'
require_relative 'shared/to_hash'
-describe "ENV.except" do
- before do
- @orig_hash = ENV.to_hash
- end
+ruby_version_is "3.0" do
+ describe "ENV.except" do
+ before do
+ @orig_hash = ENV.to_hash
+ end
- after do
- ENV.replace @orig_hash
- end
+ after do
+ ENV.replace @orig_hash
+ end
- # Testing the method without arguments is covered via
- it_behaves_like :env_to_hash, :except
+ # Testing the method without arguments is covered via
+ it_behaves_like :env_to_hash, :except
- it "returns a hash without the requested subset" do
- ENV.clear
+ it "returns a hash without the requested subset" do
+ ENV.clear
- ENV['one'] = '1'
- ENV['two'] = '2'
- ENV['three'] = '3'
+ ENV['one'] = '1'
+ ENV['two'] = '2'
+ ENV['three'] = '3'
- ENV.except('one', 'three').should == { 'two' => '2' }
- end
+ ENV.except('one', 'three').should == { 'two' => '2' }
+ end
- it "ignores keys not present in the original hash" do
- ENV.clear
+ it "ignores keys not present in the original hash" do
+ ENV.clear
- ENV['one'] = '1'
- ENV['two'] = '2'
+ ENV['one'] = '1'
+ ENV['two'] = '2'
- ENV.except('one', 'three').should == { 'two' => '2' }
+ ENV.except('one', 'three').should == { 'two' => '2' }
+ end
end
end
diff --git a/spec/ruby/core/env/index_spec.rb b/spec/ruby/core/env/index_spec.rb
new file mode 100644
index 0000000000..301a66ab4e
--- /dev/null
+++ b/spec/ruby/core/env/index_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../spec_helper'
+require_relative 'shared/key'
+
+ruby_version_is ''...'3.0' do
+ describe "ENV.index" do
+ it_behaves_like :env_key, :index
+
+ it "warns about deprecation" do
+ -> do
+ ENV.index("foo")
+ end.should complain(/warning: ENV.index is deprecated; use ENV.key/)
+ end
+ end
+end
diff --git a/spec/ruby/core/env/indexes_spec.rb b/spec/ruby/core/env/indexes_spec.rb
new file mode 100644
index 0000000000..e724feaa39
--- /dev/null
+++ b/spec/ruby/core/env/indexes_spec.rb
@@ -0,0 +1 @@
+require_relative '../../spec_helper'
diff --git a/spec/ruby/core/env/indices_spec.rb b/spec/ruby/core/env/indices_spec.rb
new file mode 100644
index 0000000000..e724feaa39
--- /dev/null
+++ b/spec/ruby/core/env/indices_spec.rb
@@ -0,0 +1 @@
+require_relative '../../spec_helper'
diff --git a/spec/ruby/core/env/key_spec.rb b/spec/ruby/core/env/key_spec.rb
index cf70286409..82cfbefa39 100644
--- a/spec/ruby/core/env/key_spec.rb
+++ b/spec/ruby/core/env/key_spec.rb
@@ -1,39 +1,11 @@
require_relative '../../spec_helper'
require_relative 'shared/include'
+require_relative 'shared/key'
describe "ENV.key?" do
it_behaves_like :env_include, :key?
end
describe "ENV.key" do
- before :each do
- @saved_foo = ENV["foo"]
- end
-
- after :each do
- ENV["foo"] = @saved_foo
- end
-
- it "returns the index associated with the passed value" do
- ENV["foo"] = "bar"
- ENV.key("bar").should == "foo"
- end
-
- it "returns nil if the passed value is not found" do
- ENV.delete("foo")
- ENV.key("foo").should be_nil
- end
-
- it "coerces the key element with #to_str" do
- ENV["foo"] = "bar"
- k = mock('key')
- k.should_receive(:to_str).and_return("bar")
- ENV.key(k).should == "foo"
- end
-
- it "raises TypeError if the argument is not a String and does not respond to #to_str" do
- -> {
- ENV.key(Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into String")
- end
+ it_behaves_like :env_key, :key
end
diff --git a/spec/ruby/core/env/shared/include.rb b/spec/ruby/core/env/shared/include.rb
index 70aa555301..3efcd523d6 100644
--- a/spec/ruby/core/env/shared/include.rb
+++ b/spec/ruby/core/env/shared/include.rb
@@ -17,13 +17,6 @@ describe :env_include, shared: true do
ENV.send(@method, "foo").should == false
end
- it "coerces the key with #to_str" do
- ENV["foo"] = "bar"
- k = mock('key')
- k.should_receive(:to_str).and_return("foo")
- ENV.send(@method, k).should == true
- end
-
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.send(@method, Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
diff --git a/spec/ruby/core/env/shared/key.rb b/spec/ruby/core/env/shared/key.rb
new file mode 100644
index 0000000000..93396d2aca
--- /dev/null
+++ b/spec/ruby/core/env/shared/key.rb
@@ -0,0 +1,31 @@
+describe :env_key, shared: true do
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
+ it "returns the index associated with the passed value" do
+ ENV["foo"] = "bar"
+ suppress_warning {
+ ENV.send(@method, "bar").should == "foo"
+ }
+ end
+
+ it "returns nil if the passed value is not found" do
+ ENV.delete("foo")
+ suppress_warning {
+ ENV.send(@method, "foo").should be_nil
+ }
+ end
+
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> {
+ suppress_warning {
+ ENV.send(@method, Object.new)
+ }
+ }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
+end
diff --git a/spec/ruby/core/env/shared/value.rb b/spec/ruby/core/env/shared/value.rb
index c2b5025465..bef96b5fef 100644
--- a/spec/ruby/core/env/shared/value.rb
+++ b/spec/ruby/core/env/shared/value.rb
@@ -16,13 +16,6 @@ describe :env_value, shared: true do
ENV.send(@method, "foo").should == false
end
- it "coerces the value element with #to_str" do
- ENV["foo"] = "bar"
- v = mock('value')
- v.should_receive(:to_str).and_return("bar")
- ENV.send(@method, v).should == true
- end
-
it "returns nil if the argument is not a String and does not respond to #to_str" do
ENV.send(@method, Object.new).should == nil
end
diff --git a/spec/ruby/core/env/slice_spec.rb b/spec/ruby/core/env/slice_spec.rb
index 959239d2b2..e3b6020391 100644
--- a/spec/ruby/core/env/slice_spec.rb
+++ b/spec/ruby/core/env/slice_spec.rb
@@ -21,16 +21,6 @@ describe "ENV.slice" do
ENV.slice("foo", "boo", "bar").should == {"foo" => "0", "bar" => "1"}
end
- it "returns the values for the keys coerced with #to_str, but keeps the original objects as result keys" do
- foo = mock('key 1')
- foo.should_receive(:to_str).and_return("foo")
- boo = mock('key 2')
- boo.should_receive(:to_str).and_return("boo")
- bar = mock('key 3')
- bar.should_receive(:to_str).and_return("bar")
- ENV.slice(foo, boo, bar).should == {foo => "0", bar => "1"}
- end
-
it "raises TypeError if any argument is not a String and does not respond to #to_str" do
-> { ENV.slice(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
diff --git a/spec/ruby/core/env/to_a_spec.rb b/spec/ruby/core/env/to_a_spec.rb
index 2b1649281f..39e3877b48 100644
--- a/spec/ruby/core/env/to_a_spec.rb
+++ b/spec/ruby/core/env/to_a_spec.rb
@@ -6,10 +6,7 @@ describe "ENV.to_a" do
a = ENV.to_a
a.is_a?(Array).should == true
a.size.should == ENV.size
- a.each { |k,v| ENV[k].should == v }
-
- a.first.should.is_a?(Array)
- a.first.size.should == 2
+ ENV.each_pair { |k, v| a.should include([k, v])}
end
it "returns the entries in the locale encoding" do
diff --git a/spec/ruby/core/exception/case_compare_spec.rb b/spec/ruby/core/exception/case_compare_spec.rb
index 5fd11ae741..87b9dee3ca 100644
--- a/spec/ruby/core/exception/case_compare_spec.rb
+++ b/spec/ruby/core/exception/case_compare_spec.rb
@@ -26,11 +26,13 @@ describe "SystemCallError.===" do
end
it "returns true if receiver is generic and arg is kind of SystemCallError" do
+ unknown_error_number = Errno.constants.size
e = SystemCallError.new('foo', @example_errno)
SystemCallError.===(e).should == true
end
it "returns false if receiver is generic and arg is not kind of SystemCallError" do
+ unknown_error_number = Errno.constants.size
e = Object.new
SystemCallError.===(e).should == false
end
diff --git a/spec/ruby/core/exception/detailed_message_spec.rb b/spec/ruby/core/exception/detailed_message_spec.rb
deleted file mode 100644
index fbe4443daa..0000000000
--- a/spec/ruby/core/exception/detailed_message_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/common'
-
-describe "Exception#detailed_message" do
- ruby_version_is "3.2" do
- it "returns decorated message" do
- RuntimeError.new("new error").detailed_message.should == "new error (RuntimeError)"
- end
-
- it "is called by #full_message to allow message customization" do
- exception = Exception.new("new error")
- def exception.detailed_message(**)
- "<prefix>#{message}<suffix>"
- end
- exception.full_message(highlight: false).should.include? "<prefix>new error<suffix>"
- end
-
- it "accepts highlight keyword argument and adds escape control sequences" do
- RuntimeError.new("new error").detailed_message(highlight: true).should == "\e[1mnew error (\e[1;4mRuntimeError\e[m\e[1m)\e[m"
- end
-
- it "allows and ignores other keyword arguments" do
- RuntimeError.new("new error").detailed_message(foo: true).should == "new error (RuntimeError)"
- end
-
- it "returns just a message if exception class is anonymous" do
- Class.new(RuntimeError).new("message").detailed_message.should == "message"
- end
-
- it "returns 'unhandled exception' for an instance of RuntimeError with empty message" do
- RuntimeError.new("").detailed_message.should == "unhandled exception"
- end
-
- it "returns just class name for an instance of RuntimeError subclass with empty message" do
- DetailedMessageSpec::C.new("").detailed_message.should == "DetailedMessageSpec::C"
- end
-
- it "returns a generated class name for an instance of RuntimeError anonymous subclass with empty message" do
- klass = Class.new(RuntimeError)
- klass.new("").detailed_message.should =~ /\A#<Class:0x\h+>\z/
- end
- end
-end
diff --git a/spec/ruby/core/exception/equal_value_spec.rb b/spec/ruby/core/exception/equal_value_spec.rb
index e8f3ce0f8d..7f2065511a 100644
--- a/spec/ruby/core/exception/equal_value_spec.rb
+++ b/spec/ruby/core/exception/equal_value_spec.rb
@@ -22,18 +22,18 @@ describe "Exception#==" do
it "returns true if both exceptions have the same class, the same message, and the same backtrace" do
one = TypeError.new("message")
- one.set_backtrace [__dir__]
+ one.set_backtrace [File.dirname(__FILE__)]
two = TypeError.new("message")
- two.set_backtrace [__dir__]
+ two.set_backtrace [File.dirname(__FILE__)]
one.should == two
end
it "returns false if the two exceptions inherit from Exception but have different classes" do
one = RuntimeError.new("message")
- one.set_backtrace [__dir__]
+ one.set_backtrace [File.dirname(__FILE__)]
one.should be_kind_of(Exception)
two = TypeError.new("message")
- two.set_backtrace [__dir__]
+ two.set_backtrace [File.dirname(__FILE__)]
two.should be_kind_of(Exception)
one.should_not == two
end
@@ -52,7 +52,7 @@ describe "Exception#==" do
it "returns false if the two exceptions differ only in their backtrace" do
one = RuntimeError.new("message")
- one.set_backtrace [__dir__]
+ one.set_backtrace [File.dirname(__FILE__)]
two = RuntimeError.new("message")
two.set_backtrace nil
one.should_not == two
@@ -60,9 +60,9 @@ describe "Exception#==" do
it "returns false if the two exceptions differ only in their message" do
one = RuntimeError.new("message")
- one.set_backtrace [__dir__]
+ one.set_backtrace [File.dirname(__FILE__)]
two = RuntimeError.new("message2")
- two.set_backtrace [__dir__]
+ two.set_backtrace [File.dirname(__FILE__)]
one.should_not == two
end
end
diff --git a/spec/ruby/core/exception/fixtures/common.rb b/spec/ruby/core/exception/fixtures/common.rb
index 1e243098bd..0ffb3ed855 100644
--- a/spec/ruby/core/exception/fixtures/common.rb
+++ b/spec/ruby/core/exception/fixtures/common.rb
@@ -93,7 +93,3 @@ class NameErrorSpecs
end
end
end
-
-module DetailedMessageSpec
- C = Class.new(RuntimeError)
-end
diff --git a/spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb b/spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb
deleted file mode 100644
index c109ec6247..0000000000
--- a/spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-ready = false
-t = Thread.new do
- f = Fiber.new do
- begin
- Fiber.yield
- ensure
- STDERR.puts "suspended fiber ensure"
- end
- end
- f.resume
-
- begin
- ready = true
- sleep
- ensure
- STDERR.puts "current fiber ensure"
- end
-end
-
-Thread.pass until ready && t.stop?
-
-# let the program end, it's the same as #exit or an exception for this behavior
diff --git a/spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb b/spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb
deleted file mode 100644
index 3364ed06d0..0000000000
--- a/spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-ready = false
-t = Thread.new do
- f = Fiber.new do
- begin
- Fiber.yield
- ensure
- STDERR.puts "suspended fiber ensure"
- end
- end
- f.resume
-
- f2 = Fiber.new do
- begin
- ready = true
- sleep
- ensure
- STDERR.puts "current fiber ensure"
- end
- end
- f2.resume
-end
-
-Thread.pass until ready && t.stop?
-
-# let the program end, it's the same as #exit or an exception for this behavior
diff --git a/spec/ruby/core/exception/full_message_spec.rb b/spec/ruby/core/exception/full_message_spec.rb
index 4fad369936..9757a2f407 100644
--- a/spec/ruby/core/exception/full_message_spec.rb
+++ b/spec/ruby/core/exception/full_message_spec.rb
@@ -46,49 +46,6 @@ describe "Exception#full_message" do
full_message[0].should.end_with?("': Some runtime error (RuntimeError)\n")
end
- describe "includes details about whether an exception was handled" do
- describe "RuntimeError" do
- it "should report as unhandled if message is empty" do
- err = RuntimeError.new("")
-
- err.full_message.should =~ /unhandled exception/
- err.full_message(highlight: true).should =~ /unhandled exception/
- err.full_message(highlight: false).should =~ /unhandled exception/
- end
-
- it "should not report as unhandled if the message is not empty" do
- err = RuntimeError.new("non-empty")
-
- err.full_message.should !~ /unhandled exception/
- err.full_message(highlight: true).should !~ /unhandled exception/
- err.full_message(highlight: false).should !~ /unhandled exception/
- end
-
- it "should not report as unhandled if the message is nil" do
- err = RuntimeError.new(nil)
-
- err.full_message.should !~ /unhandled exception/
- err.full_message(highlight: true).should !~ /unhandled exception/
- err.full_message(highlight: false).should !~ /unhandled exception/
- end
-
- it "should not report as unhandled if the message is not specified" do
- err = RuntimeError.new()
-
- err.full_message.should !~ /unhandled exception/
- err.full_message(highlight: true).should !~ /unhandled exception/
- err.full_message(highlight: false).should !~ /unhandled exception/
- end
- end
-
- describe "generic Error" do
- it "should not report as unhandled in any event" do
- StandardError.new("").full_message.should !~ /unhandled exception/
- StandardError.new("non-empty").full_message.should !~ /unhandled exception/
- end
- end
- end
-
it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do
begin
line = __LINE__; raise "first line\nsecond line"
@@ -146,53 +103,4 @@ describe "Exception#full_message" do
exception.full_message.should include "intermediate exception"
exception.full_message.should include "origin exception"
end
-
- ruby_version_is "3.2" do
- it "relies on #detailed_message" do
- e = RuntimeError.new("new error")
- e.define_singleton_method(:detailed_message) { |**| "DETAILED MESSAGE" }
-
- e.full_message.lines.first.should =~ /DETAILED MESSAGE/
- end
-
- it "passes all its own keyword arguments (with :highlight default value and without :order default value) to #detailed_message" do
- e = RuntimeError.new("new error")
- options_passed = nil
- e.define_singleton_method(:detailed_message) do |**options|
- options_passed = options
- "DETAILED MESSAGE"
- end
-
- e.full_message(foo: "bar")
- options_passed.should == { foo: "bar", highlight: Exception.to_tty? }
- end
-
- it "converts #detailed_message returned value to String if it isn't a String" do
- message = Object.new
- def message.to_str; "DETAILED MESSAGE"; end
-
- e = RuntimeError.new("new error")
- e.define_singleton_method(:detailed_message) { |**| message }
-
- e.full_message.lines.first.should =~ /DETAILED MESSAGE/
- end
-
- it "uses class name if #detailed_message returns nil" do
- e = RuntimeError.new("new error")
- e.define_singleton_method(:detailed_message) { |**| nil }
-
- e.full_message(highlight: false).lines.first.should =~ /RuntimeError/
- e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/
- end
-
- it "uses class name if exception object doesn't respond to #detailed_message" do
- e = RuntimeError.new("new error")
- class << e
- undef :detailed_message
- end
-
- e.full_message(highlight: false).lines.first.should =~ /RuntimeError/
- e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/
- end
- end
end
diff --git a/spec/ruby/core/exception/no_method_error_spec.rb b/spec/ruby/core/exception/no_method_error_spec.rb
index 4621e36f44..8428ba0382 100644
--- a/spec/ruby/core/exception/no_method_error_spec.rb
+++ b/spec/ruby/core/exception/no_method_error_spec.rb
@@ -62,49 +62,26 @@ describe "NoMethodError#message" do
NoMethodErrorSpecs::NoMethodErrorC.new.a_private_method
rescue Exception => e
e.should be_kind_of(NoMethodError)
- e.message.lines[0].should =~ /private method `a_private_method' called for /
+ e.message.lines[0].should =~ /private method `a_private_method' called for #<NoMethodErrorSpecs::NoMethodErrorC:0x[\h]+>/
end
end
- ruby_version_is ""..."3.3" do
- it "calls receiver.inspect only when calling Exception#message" do
- ScratchPad.record []
- test_class = Class.new do
- def inspect
- ScratchPad << :inspect_called
- "<inspect>"
- end
- end
- instance = test_class.new
- begin
- instance.bar
- rescue Exception => e
- e.name.should == :bar
- ScratchPad.recorded.should == []
- e.message.should =~ /undefined method.+\bbar\b/
- ScratchPad.recorded.should == [:inspect_called]
+ it "calls receiver.inspect only when calling Exception#message" do
+ ScratchPad.record []
+ test_class = Class.new do
+ def inspect
+ ScratchPad << :inspect_called
+ "<inspect>"
end
end
- end
-
- ruby_version_is "3.3" do
- it "does not call receiver.inspect even when calling Exception#message" do
- ScratchPad.record []
- test_class = Class.new do
- def inspect
- ScratchPad << :inspect_called
- "<inspect>"
- end
- end
- instance = test_class.new
- begin
- instance.bar
- rescue Exception => e
- e.name.should == :bar
- ScratchPad.recorded.should == []
- e.message.should =~ /undefined method.+\bbar\b/
- ScratchPad.recorded.should == []
- end
+ instance = test_class.new
+ begin
+ instance.bar
+ rescue Exception => e
+ e.name.should == :bar
+ ScratchPad.recorded.should == []
+ e.message.should =~ /undefined method.+\bbar\b/
+ ScratchPad.recorded.should == [:inspect_called]
end
end
@@ -125,19 +102,21 @@ describe "NoMethodError#message" do
end
end
- it "uses #name to display the receiver if it is a class or a module" do
- klass = Class.new { def self.name; "MyClass"; end }
- begin
- klass.foo
- rescue NoMethodError => error
- error.message.lines.first.chomp.should =~ /^undefined method `foo' for /
- end
+ ruby_version_is "3.0" do
+ it "uses #name to display the receiver if it is a class or a module" do
+ klass = Class.new { def self.name; "MyClass"; end }
+ begin
+ klass.foo
+ rescue NoMethodError => error
+ error.message.lines.first.chomp.should == "undefined method `foo' for MyClass:Class"
+ end
- mod = Module.new { def self.name; "MyModule"; end }
- begin
- mod.foo
- rescue NoMethodError => error
- error.message.lines.first.chomp.should =~ /^undefined method `foo' for /
+ mod = Module.new { def self.name; "MyModule"; end }
+ begin
+ mod.foo
+ rescue NoMethodError => error
+ error.message.lines.first.chomp.should == "undefined method `foo' for MyModule:Module"
+ end
end
end
end
diff --git a/spec/ruby/core/exception/top_level_spec.rb b/spec/ruby/core/exception/top_level_spec.rb
index bcd09205b6..b47648425e 100644
--- a/spec/ruby/core/exception/top_level_spec.rb
+++ b/spec/ruby/core/exception/top_level_spec.rb
@@ -42,16 +42,4 @@ describe "An Exception reaching the top level" do
EOS
end
end
-
- describe "kills all threads and fibers, ensure clauses are only run for threads current fibers, not for suspended fibers" do
- it "with ensure on the root fiber" do
- file = fixture(__FILE__, "thread_fiber_ensure.rb")
- ruby_exe(file, args: "2>&1", exit_status: 0).should == "current fiber ensure\n"
- end
-
- it "with ensure on non-root fiber" do
- file = fixture(__FILE__, "thread_fiber_ensure_non_root_fiber.rb")
- ruby_exe(file, args: "2>&1", exit_status: 0).should == "current fiber ensure\n"
- end
- end
end
diff --git a/spec/ruby/core/false/singleton_method_spec.rb b/spec/ruby/core/false/singleton_method_spec.rb
deleted file mode 100644
index 738794b46c..0000000000
--- a/spec/ruby/core/false/singleton_method_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "FalseClass#singleton_method" do
- ruby_version_is '3.3' do
- it "raises regardless of whether FalseClass defines the method" do
- -> { false.singleton_method(:foo) }.should raise_error(NameError)
- begin
- def (false).foo; end
- -> { false.singleton_method(:foo) }.should raise_error(NameError)
- ensure
- FalseClass.send(:remove_method, :foo)
- end
- end
- end
-end
diff --git a/spec/ruby/core/fiber/blocking_spec.rb b/spec/ruby/core/fiber/blocking_spec.rb
index ebefa116af..eeee5a71c1 100644
--- a/spec/ruby/core/fiber/blocking_spec.rb
+++ b/spec/ruby/core/fiber/blocking_spec.rb
@@ -1,59 +1,61 @@
require_relative '../../spec_helper'
require_relative 'shared/blocking'
-require "fiber"
+ruby_version_is "3.0" do
+ require "fiber"
-describe "Fiber.blocking?" do
- it_behaves_like :non_blocking_fiber, -> { Fiber.blocking? }
+ describe "Fiber.blocking?" do
+ it_behaves_like :non_blocking_fiber, -> { Fiber.blocking? }
- context "when fiber is blocking" do
- context "root Fiber of the main thread" do
- it "returns 1 for blocking: true" do
- fiber = Fiber.new(blocking: true) { Fiber.blocking? }
- blocking = fiber.resume
-
- blocking.should == 1
- end
- end
-
- context "root Fiber of a new thread" do
- it "returns 1 for blocking: true" do
- thread = Thread.new do
+ context "when fiber is blocking" do
+ context "root Fiber of the main thread" do
+ it "returns 1 for blocking: true" do
fiber = Fiber.new(blocking: true) { Fiber.blocking? }
blocking = fiber.resume
blocking.should == 1
end
-
- thread.join
end
- end
- end
-end
-describe "Fiber#blocking?" do
- it_behaves_like :non_blocking_fiber, -> { Fiber.current.blocking? }
+ context "root Fiber of a new thread" do
+ it "returns 1 for blocking: true" do
+ thread = Thread.new do
+ fiber = Fiber.new(blocking: true) { Fiber.blocking? }
+ blocking = fiber.resume
- context "when fiber is blocking" do
- context "root Fiber of the main thread" do
- it "returns true for blocking: true" do
- fiber = Fiber.new(blocking: true) { Fiber.current.blocking? }
- blocking = fiber.resume
+ blocking.should == 1
+ end
- blocking.should == true
+ thread.join
+ end
end
end
+ end
- context "root Fiber of a new thread" do
- it "returns true for blocking: true" do
- thread = Thread.new do
+ describe "Fiber#blocking?" do
+ it_behaves_like :non_blocking_fiber, -> { Fiber.current.blocking? }
+
+ context "when fiber is blocking" do
+ context "root Fiber of the main thread" do
+ it "returns true for blocking: true" do
fiber = Fiber.new(blocking: true) { Fiber.current.blocking? }
blocking = fiber.resume
blocking.should == true
end
+ end
- thread.join
+ context "root Fiber of a new thread" do
+ it "returns true for blocking: true" do
+ thread = Thread.new do
+ fiber = Fiber.new(blocking: true) { Fiber.current.blocking? }
+ blocking = fiber.resume
+
+ blocking.should == true
+ end
+
+ thread.join
+ end
end
end
end
diff --git a/spec/ruby/core/fiber/inspect_spec.rb b/spec/ruby/core/fiber/inspect_spec.rb
deleted file mode 100644
index f20a153fc2..0000000000
--- a/spec/ruby/core/fiber/inspect_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require_relative '../../spec_helper'
-require 'fiber'
-
-describe "Fiber#inspect" do
- describe "status" do
- it "is resumed for the root Fiber of a Thread" do
- inspected = Thread.new { Fiber.current.inspect }.value
- inspected.should =~ /\A#<Fiber:0x\h+ .*\(resumed\)>\z/
- end
-
- it "is created for a Fiber which did not run yet" do
- inspected = Fiber.new {}.inspect
- inspected.should =~ /\A#<Fiber:0x\h+ .+ \(created\)>\z/
- end
-
- it "is resumed for a Fiber which was resumed" do
- inspected = Fiber.new { Fiber.current.inspect }.resume
- inspected.should =~ /\A#<Fiber:0x\h+ .+ \(resumed\)>\z/
- end
-
- it "is resumed for a Fiber which was transferred" do
- inspected = Fiber.new { Fiber.current.inspect }.transfer
- inspected.should =~ /\A#<Fiber:0x\h+ .+ \(resumed\)>\z/
- end
-
- it "is suspended for a Fiber which was resumed and yielded" do
- inspected = Fiber.new { Fiber.yield }.tap(&:resume).inspect
- inspected.should =~ /\A#<Fiber:0x\h+ .+ \(suspended\)>\z/
- end
-
- it "is terminated for a Fiber which has terminated" do
- inspected = Fiber.new {}.tap(&:resume).inspect
- inspected.should =~ /\A#<Fiber:0x\h+ .+ \(terminated\)>\z/
- end
- end
-end
diff --git a/spec/ruby/core/fiber/kill_spec.rb b/spec/ruby/core/fiber/kill_spec.rb
deleted file mode 100644
index 2f4c499280..0000000000
--- a/spec/ruby/core/fiber/kill_spec.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
-require_relative '../../shared/kernel/raise'
-
-ruby_version_is "3.3" do
- describe "Fiber#kill" do
- it "kills a non-resumed fiber" do
- fiber = Fiber.new{}
-
- fiber.alive?.should == true
-
- fiber.kill
- fiber.alive?.should == false
- end
-
- it "kills a resumed fiber" do
- fiber = Fiber.new{while true; Fiber.yield; end}
- fiber.resume
-
- fiber.alive?.should == true
-
- fiber.kill
- fiber.alive?.should == false
- end
-
- it "can kill itself" do
- fiber = Fiber.new do
- Fiber.current.kill
- end
-
- fiber.alive?.should == true
-
- fiber.resume
- fiber.alive?.should == false
- end
-
- it "kills a resumed fiber from a child" do
- parent = Fiber.new do
- child = Fiber.new do
- parent.kill
- parent.alive?.should == true
- end
-
- child.resume
- end
-
- parent.resume
- parent.alive?.should == false
- end
-
- it "executes the ensure block" do
- ensure_executed = false
-
- fiber = Fiber.new do
- while true; Fiber.yield; end
- ensure
- ensure_executed = true
- end
-
- fiber.resume
- fiber.kill
- ensure_executed.should == true
- end
-
- it "does not execute rescue block" do
- rescue_executed = false
-
- fiber = Fiber.new do
- while true; Fiber.yield; end
- rescue Exception
- rescue_executed = true
- end
-
- fiber.resume
- fiber.kill
- rescue_executed.should == false
- end
-
- it "repeatedly kills a fiber" do
- fiber = Fiber.new do
- while true; Fiber.yield; end
- ensure
- while true; Fiber.yield; end
- end
-
- fiber.kill
- fiber.alive?.should == false
- end
- end
-end
diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb
index b3e021e636..09c4c1b524 100644
--- a/spec/ruby/core/fiber/raise_spec.rb
+++ b/spec/ruby/core/fiber/raise_spec.rb
@@ -91,49 +91,29 @@ describe "Fiber#raise" do
fiber_two.resume.should == [:yield_one, :rescued]
end
+end
- ruby_version_is "3.4" do
- it "raises on the resumed fiber" do
- root_fiber = Fiber.current
- f1 = Fiber.new { root_fiber.transfer }
- f2 = Fiber.new { f1.resume }
- f2.transfer
-
- -> do
- f2.raise(RuntimeError, "Expected error")
- end.should raise_error(RuntimeError, "Expected error")
- end
- it "raises on itself" do
- -> do
- Fiber.current.raise(RuntimeError, "Expected error")
- end.should raise_error(RuntimeError, "Expected error")
- end
-
- it "should raise on parent fiber" do
- f2 = nil
- f1 = Fiber.new do
- # This is equivalent to Kernel#raise:
- f2.raise(RuntimeError, "Expected error")
- end
- f2 = Fiber.new do
- f1.resume
- end
-
- -> do
- f2.resume
- end.should raise_error(RuntimeError, "Expected error")
+ruby_version_is ""..."3.0" do
+ describe "Fiber#raise" do
+ it "raises a FiberError if invoked on a transferring Fiber" do
+ require "fiber"
+ root = Fiber.current
+ fiber = Fiber.new { root.transfer }
+ fiber.transfer
+ -> { fiber.raise }.should raise_error(FiberError, "cannot resume transferred Fiber")
end
end
end
-
-describe "Fiber#raise" do
- it "transfers and raises on a transferring fiber" do
- require "fiber"
- root = Fiber.current
- fiber = Fiber.new { root.transfer }
- fiber.transfer
- -> { fiber.raise "msg" }.should raise_error(RuntimeError, "msg")
+ruby_version_is "3.0" do
+ describe "Fiber#raise" do
+ it "transfers and raises on a transferring fiber" do
+ require "fiber"
+ root = Fiber.current
+ fiber = Fiber.new { root.transfer }
+ fiber.transfer
+ -> { fiber.raise "msg" }.should raise_error(RuntimeError, "msg")
+ end
end
end
diff --git a/spec/ruby/core/fiber/resume_spec.rb b/spec/ruby/core/fiber/resume_spec.rb
index ab9a6799ab..273bc866af 100644
--- a/spec/ruby/core/fiber/resume_spec.rb
+++ b/spec/ruby/core/fiber/resume_spec.rb
@@ -28,9 +28,18 @@ describe "Fiber#resume" do
fiber.resume :second
end
- it "raises a FiberError if the Fiber tries to resume itself" do
- fiber = Fiber.new { fiber.resume }
- -> { fiber.resume }.should raise_error(FiberError, /current fiber/)
+ ruby_version_is '3.0' do
+ it "raises a FiberError if the Fiber tries to resume itself" do
+ fiber = Fiber.new { fiber.resume }
+ -> { fiber.resume }.should raise_error(FiberError, /current fiber/)
+ end
+ end
+
+ ruby_version_is '' ... '3.0' do
+ it "raises a FiberError if the Fiber tries to resume itself" do
+ fiber = Fiber.new { fiber.resume }
+ -> { fiber.resume }.should raise_error(FiberError, /double resume/)
+ end
end
it "returns control to the calling Fiber if called from one" do
diff --git a/spec/ruby/core/fiber/storage_spec.rb b/spec/ruby/core/fiber/storage_spec.rb
index 5c87ed5d41..e2bf6da04c 100644
--- a/spec/ruby/core/fiber/storage_spec.rb
+++ b/spec/ruby/core/fiber/storage_spec.rb
@@ -1,7 +1,9 @@
require_relative '../../spec_helper'
-ruby_version_is "3.2" do
- describe "Fiber.new(storage:)" do
+require 'fiber'
+
+describe "Fiber.new(storage:)" do
+ ruby_version_is "3.2" do
it "creates a Fiber with the given storage" do
storage = {life: 42}
fiber = Fiber.new(storage: storage) { Fiber.current.storage }
@@ -9,7 +11,7 @@ ruby_version_is "3.2" do
end
it "creates a fiber with lazily initialized storage" do
- Fiber.new(storage: nil) { Fiber[:x] = 10; Fiber.current.storage }.resume.should == {x: 10}
+ Fiber.new(storage: nil) { Fiber.current.storage }.resume.should == {}
end
it "creates a fiber by inheriting the storage of the parent fiber" do
@@ -22,40 +24,24 @@ ruby_version_is "3.2" do
it "cannot create a fiber with non-hash storage" do
-> { Fiber.new(storage: 42) {} }.should raise_error(TypeError)
end
-
- it "cannot create a fiber with a frozen hash as storage" do
- -> { Fiber.new(storage: {life: 43}.freeze) {} }.should raise_error(FrozenError)
- end
-
- it "cannot create a fiber with a storage hash with non-symbol keys" do
- -> { Fiber.new(storage: {life: 43, Object.new => 44}) {} }.should raise_error(TypeError)
- end
- end
-
- describe "Fiber#storage" do
- it "cannot be accessed from a different fiber" do
- f = Fiber.new(storage: {life: 42}) { nil }
- -> {
- f.storage
- }.should raise_error(ArgumentError, /Fiber storage can only be accessed from the Fiber it belongs to/)
- end
end
+end
- describe "Fiber#storage=" do
+describe "Fiber#storage=" do
+ ruby_version_is "3.2" do
it "can clear the storage of the fiber" do
- fiber = Fiber.new(storage: {life: 42}) do
+ fiber = Fiber.new(storage: {life: 42}) {
Fiber.current.storage = nil
- Fiber[:x] = 10
Fiber.current.storage
- end
- fiber.resume.should == {x: 10}
+ }
+ fiber.resume.should == {}
end
it "can set the storage of the fiber" do
- fiber = Fiber.new(storage: {life: 42}) do
+ fiber = Fiber.new(storage: {life: 42}) {
Fiber.current.storage = {life: 43}
Fiber.current.storage
- end
+ }
fiber.resume.should == {life: 43}
end
@@ -71,8 +57,10 @@ ruby_version_is "3.2" do
-> { Fiber.current.storage = {life: 43, Object.new => 44} }.should raise_error(TypeError)
end
end
+end
- describe "Fiber.[]" do
+describe "Fiber.[]" do
+ ruby_version_is "3.2" do
it "returns the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:life] }.resume.should == 42
end
@@ -84,34 +72,25 @@ ruby_version_is "3.2" do
it "returns nil if the current fiber has no storage" do
Fiber.new { Fiber[:life] }.resume.should be_nil
end
+ end
- ruby_version_is "3.2.3" do
- it "can use dynamically defined keys" do
- key = :"#{self.class.name}#.#{self.object_id}"
- Fiber.new { Fiber[key] = 42; Fiber[key] }.resume.should == 42
- end
-
- it "can't use invalid keys" do
- invalid_keys = [Object.new, "Foo", 12]
- invalid_keys.each do |key|
- -> { Fiber[key] }.should raise_error(TypeError)
- end
- end
+ ruby_version_is "3.2.3" do
+ it "can use dynamically defined keys" do
+ key = :"#{self.class.name}#.#{self.object_id}"
+ Fiber.new { Fiber[key] = 42; Fiber[key] }.resume.should == 42
end
- it "can access the storage of the parent fiber" do
- f = Fiber.new(storage: {life: 42}) do
- Fiber.new { Fiber[:life] }.resume
+ it "can't use invalid keys" do
+ invalid_keys = [Object.new, "Foo", 12]
+ invalid_keys.each do |key|
+ -> { Fiber[key] }.should raise_error(TypeError)
end
- f.resume.should == 42
- end
-
- it "can't access the storage of the fiber with non-symbol keys" do
- -> { Fiber[Object.new] }.should raise_error(TypeError)
end
end
+end
- describe "Fiber.[]=" do
+describe "Fiber.[]=" do
+ ruby_version_is "3.2" do
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:life] = 43; Fiber[:life] }.resume.should == 43
end
@@ -123,31 +102,11 @@ ruby_version_is "3.2" do
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new { Fiber[:life] = 43; Fiber[:life] }.resume.should == 43
end
-
- it "does not overwrite the storage of the parent fiber" do
- f = Fiber.new(storage: {life: 42}) do
- Fiber.yield Fiber.new { Fiber[:life] = 43; Fiber[:life] }.resume
- Fiber[:life]
- end
- f.resume.should == 43 # Value of the inner fiber
- f.resume.should == 42 # Value of the outer fiber
- end
-
- it "can't access the storage of the fiber with non-symbol keys" do
- -> { Fiber[Object.new] = 44 }.should raise_error(TypeError)
- end
-
- ruby_version_is "3.3" do
- it "deletes the fiber storage key when assigning nil" do
- Fiber.new(storage: {life: 42}) {
- Fiber[:life] = nil
- Fiber.current.storage
- }.resume.should == {}
- end
- end
end
+end
- describe "Thread.new" do
+describe "Thread.new" do
+ ruby_version_is "3.2" do
it "creates a thread with the storage of the current fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Thread.new { Fiber.current.storage }.value
diff --git a/spec/ruby/core/file/absolute_path_spec.rb b/spec/ruby/core/file/absolute_path_spec.rb
index 315eead34f..e35c80ec3c 100644
--- a/spec/ruby/core/file/absolute_path_spec.rb
+++ b/spec/ruby/core/file/absolute_path_spec.rb
@@ -85,7 +85,7 @@ describe "File.absolute_path" do
end
it "accepts a second argument of a directory from which to resolve the path" do
- File.absolute_path(__FILE__, __dir__).should == @abs
+ File.absolute_path(__FILE__, File.dirname(__FILE__)).should == @abs
end
it "calls #to_path on its argument" do
diff --git a/spec/ruby/core/file/atime_spec.rb b/spec/ruby/core/file/atime_spec.rb
index 1b47576e6b..3df258016c 100644
--- a/spec/ruby/core/file/atime_spec.rb
+++ b/spec/ruby/core/file/atime_spec.rb
@@ -15,7 +15,7 @@ describe "File.atime" do
File.atime(@file).should be_kind_of(Time)
end
- platform_is :linux, :windows do
+ platform_is :linux do
unless ENV.key?('TRAVIS') # https://bugs.ruby-lang.org/issues/17926
## NOTE also that some Linux systems disable atime (e.g. via mount params) for better filesystem speed.
it "returns the last access time for the named file with microseconds" do
diff --git a/spec/ruby/core/file/ctime_spec.rb b/spec/ruby/core/file/ctime_spec.rb
index d17ba1a77f..9b7ab272ff 100644
--- a/spec/ruby/core/file/ctime_spec.rb
+++ b/spec/ruby/core/file/ctime_spec.rb
@@ -14,7 +14,7 @@ describe "File.ctime" do
File.ctime(@file).should be_kind_of(Time)
end
- platform_is :linux, :windows do
+ platform_is :linux do
it "returns the change time for the named file (the time at which directory information about the file was changed, not the file itself) with microseconds." do
supports_subseconds = Integer(`stat -c%z '#{__FILE__}'`[/\.(\d{1,6})/, 1], 10)
if supports_subseconds != 0
diff --git a/spec/ruby/core/file/dirname_spec.rb b/spec/ruby/core/file/dirname_spec.rb
index 8dd6c4ca88..cf0f909f59 100644
--- a/spec/ruby/core/file/dirname_spec.rb
+++ b/spec/ruby/core/file/dirname_spec.rb
@@ -12,33 +12,18 @@ describe "File.dirname" do
end
ruby_version_is '3.1' do
- context "when level is passed" do
- it "returns all the components of filename except the last parts by the level" do
- File.dirname('/home/jason', 2).should == '/'
- File.dirname('/home/jason/poot.txt', 2).should == '/home'
- end
-
- it "returns the same String if the level is 0" do
- File.dirname('poot.txt', 0).should == 'poot.txt'
- File.dirname('/', 0).should == '/'
- end
-
- it "raises ArgumentError if the level is negative" do
- -> {
- File.dirname('/home/jason', -1)
- }.should raise_error(ArgumentError, "negative level: -1")
- end
-
- it "returns '/' when level exceeds the number of segments in the path" do
- File.dirname("/home/jason", 100).should == '/'
- end
-
- it "calls #to_int if passed not numeric value" do
- object = Object.new
- def object.to_int; 2; end
-
- File.dirname("/a/b/c/d", object).should == '/a/b'
- end
+ it "returns all the components of filename except the last parts by the level" do
+ File.dirname('/home/jason', 2).should == '/'
+ File.dirname('/home/jason/poot.txt', 2).should == '/home'
+ end
+
+ it "returns the same string if the level is 0" do
+ File.dirname('poot.txt', 0).should == 'poot.txt'
+ File.dirname('/', 0).should == '/'
+ end
+
+ it "raises ArgumentError if the level is negative" do
+ -> {File.dirname('/home/jason', -1)}.should raise_error(ArgumentError)
end
end
diff --git a/spec/ruby/core/file/exist_spec.rb b/spec/ruby/core/file/exist_spec.rb
index 2633376880..ddb5febcba 100644
--- a/spec/ruby/core/file/exist_spec.rb
+++ b/spec/ruby/core/file/exist_spec.rb
@@ -4,11 +4,3 @@ require_relative '../../shared/file/exist'
describe "File.exist?" do
it_behaves_like :file_exist, :exist?, File
end
-
-ruby_version_is "3.2" do
- describe "File.exists?" do
- it "has been removed" do
- File.should_not.respond_to?(:exists?)
- end
- end
-end
diff --git a/spec/ruby/core/file/flock_spec.rb b/spec/ruby/core/file/flock_spec.rb
index 070d830bc4..751e99d994 100644
--- a/spec/ruby/core/file/flock_spec.rb
+++ b/spec/ruby/core/file/flock_spec.rb
@@ -30,7 +30,7 @@ describe "File#flock" do
it "returns false if trying to lock an exclusively locked file" do
@file.flock File::LOCK_EX
- ruby_exe(<<-END_OF_CODE).should == "false"
+ ruby_exe(<<-END_OF_CODE, escape: true).should == "false"
File.open('#{@name}', "w") do |f2|
print f2.flock(File::LOCK_EX | File::LOCK_NB).to_s
end
@@ -40,7 +40,7 @@ describe "File#flock" do
it "blocks if trying to lock an exclusively locked file" do
@file.flock File::LOCK_EX
- out = ruby_exe(<<-END_OF_CODE)
+ out = ruby_exe(<<-END_OF_CODE, escape: true)
running = false
t = Thread.new do
diff --git a/spec/ruby/core/file/mtime_spec.rb b/spec/ruby/core/file/mtime_spec.rb
index 5304bbf057..6c43265a2c 100644
--- a/spec/ruby/core/file/mtime_spec.rb
+++ b/spec/ruby/core/file/mtime_spec.rb
@@ -15,7 +15,7 @@ describe "File.mtime" do
File.mtime(@filename).should be_close(@mtime, TIME_TOLERANCE)
end
- platform_is :linux, :windows do
+ platform_is :linux do
unless ENV.key?('TRAVIS') # https://bugs.ruby-lang.org/issues/17926
it "returns the modification Time of the file with microseconds" do
supports_subseconds = Integer(`stat -c%y '#{__FILE__}'`[/\.(\d{1,6})/, 1], 10)
diff --git a/spec/ruby/core/file/new_spec.rb b/spec/ruby/core/file/new_spec.rb
index 1e82a070b1..004f78503a 100644
--- a/spec/ruby/core/file/new_spec.rb
+++ b/spec/ruby/core/file/new_spec.rb
@@ -78,29 +78,13 @@ describe "File.new" do
File.should.exist?(@file)
end
- it "returns a new read-only File when mode is not specified" do
- @fh = File.new(@file)
-
- -> { @fh.puts("test") }.should raise_error(IOError)
- @fh.read.should == ""
- File.should.exist?(@file)
- end
-
- it "returns a new read-only File when mode is not specified but flags option is present" do
- @fh = File.new(@file, flags: File::CREAT)
-
- -> { @fh.puts("test") }.should raise_error(IOError)
- @fh.read.should == ""
- File.should.exist?(@file)
- end
-
it "creates a new file when use File::EXCL mode" do
@fh = File.new(@file, File::EXCL)
@fh.should be_kind_of(File)
File.should.exist?(@file)
end
- it "raises an Errno::EEXIST if the file exists when create a new file with File::CREAT|File::EXCL" do
+ it "raises an Errorno::EEXIST if the file exists when create a new file with File::CREAT|File::EXCL" do
-> { @fh = File.new(@file, File::CREAT|File::EXCL) }.should raise_error(Errno::EEXIST)
end
@@ -128,32 +112,13 @@ describe "File.new" do
File.should.exist?(@file)
end
+
it "creates a new file when use File::WRONLY|File::TRUNC mode" do
@fh = File.new(@file, File::WRONLY|File::TRUNC)
@fh.should be_kind_of(File)
File.should.exist?(@file)
end
- it "returns a new read-only File when use File::RDONLY|File::CREAT mode" do
- @fh = File.new(@file, File::RDONLY|File::CREAT)
- @fh.should be_kind_of(File)
- File.should.exist?(@file)
-
- # it's read-only
- -> { @fh.puts("test") }.should raise_error(IOError)
- @fh.read.should == ""
- end
-
- it "returns a new read-only File when use File::CREAT mode" do
- @fh = File.new(@file, File::CREAT)
- @fh.should be_kind_of(File)
- File.should.exist?(@file)
-
- # it's read-only
- -> { @fh.puts("test") }.should raise_error(IOError)
- @fh.read.should == ""
- end
-
it "coerces filename using to_str" do
name = mock("file")
name.should_receive(:to_str).and_return(@file)
@@ -168,32 +133,6 @@ describe "File.new" do
File.should.exist?(@file)
end
- it "accepts options as a keyword argument" do
- @fh = File.new(@file, 'w', 0755, flags: @flags)
- @fh.should be_kind_of(File)
- @fh.close
-
- -> {
- @fh = File.new(@file, 'w', 0755, {flags: @flags})
- }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)")
- end
-
- it "bitwise-ORs mode and flags option" do
- -> {
- @fh = File.new(@file, 'w', flags: File::EXCL)
- }.should raise_error(Errno::EEXIST, /File exists/)
-
- -> {
- @fh = File.new(@file, mode: 'w', flags: File::EXCL)
- }.should raise_error(Errno::EEXIST, /File exists/)
- end
-
- it "does not use the given block and warns to use File::open" do
- -> {
- @fh = File.new(@file) { raise }
- }.should complain(/warning: File::new\(\) does not take block; use File::open\(\) instead/)
- end
-
it "raises a TypeError if the first parameter can't be coerced to a string" do
-> { File.new(true) }.should raise_error(TypeError)
-> { File.new(false) }.should raise_error(TypeError)
diff --git a/spec/ruby/core/file/open_spec.rb b/spec/ruby/core/file/open_spec.rb
index 6bfc16bbf9..1729780570 100644
--- a/spec/ruby/core/file/open_spec.rb
+++ b/spec/ruby/core/file/open_spec.rb
@@ -314,7 +314,7 @@ describe "File.open" do
end
end
- it "raises an IOError when write in a block opened with File::RDONLY|File::APPEND mode" do
+ it "raises an IOError when read in a block opened with File::RDONLY|File::APPEND mode" do
-> {
File.open(@file, File::RDONLY|File::APPEND ) do |f|
f.puts("writing")
@@ -354,7 +354,7 @@ describe "File.open" do
end
end
- it "raises an Errno::EEXIST if the file exists when open with File::CREAT|File::EXCL" do
+ it "raises an Errorno::EEXIST if the file exists when open with File::CREAT|File::EXCL" do
-> {
File.open(@file, File::CREAT|File::EXCL) do |f|
f.puts("writing")
@@ -423,7 +423,7 @@ describe "File.open" do
}.should raise_error(IOError)
end
- it "raises an Errno::EEXIST if the file exists when open with File::RDONLY|File::TRUNC" do
+ it "raises an Errorno::EEXIST if the file exists when open with File::RDONLY|File::TRUNC" do
-> {
File.open(@file, File::RDONLY|File::TRUNC) do |f|
f.puts("writing").should == nil
@@ -441,7 +441,7 @@ describe "File.open" do
}.should raise_error(Errno::EINVAL)
end
- it "raises an Errno::EEXIST if the file exists when open with File::RDONLY|File::TRUNC" do
+ it "raises an Errorno::EEXIST if the file exists when open with File::RDONLY|File::TRUNC" do
-> {
File.open(@file, File::RDONLY|File::TRUNC) do |f|
f.puts("writing").should == nil
@@ -565,15 +565,6 @@ describe "File.open" do
File.open(@file, 'wb+') {|f| f.external_encoding.should == Encoding::BINARY}
end
- it "accepts options as a keyword argument" do
- @fh = File.open(@file, 'w', 0755, flags: File::CREAT)
- @fh.should be_an_instance_of(File)
-
- -> {
- File.open(@file, 'w', 0755, {flags: File::CREAT})
- }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)")
- end
-
it "uses the second argument as an options Hash" do
@fh = File.open(@file, mode: "r")
@fh.should be_an_instance_of(File)
diff --git a/spec/ruby/core/file/realpath_spec.rb b/spec/ruby/core/file/realpath_spec.rb
index bd25bfdecf..bd27e09da6 100644
--- a/spec/ruby/core/file/realpath_spec.rb
+++ b/spec/ruby/core/file/realpath_spec.rb
@@ -54,10 +54,6 @@ platform_is_not :windows do
File.realpath(@relative_symlink).should == @file
end
- it "removes the file element when going one level up" do
- File.realpath('../', @file).should == @real_dir
- end
-
it "raises an Errno::ELOOP if the symlink points to itself" do
File.unlink @link
File.symlink(@link, @link)
diff --git a/spec/ruby/core/file/shared/fnmatch.rb b/spec/ruby/core/file/shared/fnmatch.rb
index db4b5c5d8c..94f22144b0 100644
--- a/spec/ruby/core/file/shared/fnmatch.rb
+++ b/spec/ruby/core/file/shared/fnmatch.rb
@@ -102,7 +102,6 @@ describe :file_fnmatch, shared: true do
it "matches ranges of characters using exclusive bracket expression (e.g. [^t] or [!t])" do
File.send(@method, 'ca[^t]', 'cat').should == false
- File.send(@method, 'ca[^t]', 'cas').should == true
File.send(@method, 'ca[!t]', 'cat').should == false
end
@@ -126,13 +125,6 @@ describe :file_fnmatch, shared: true do
end
end
- it "matches wildcard with characters when flags includes FNM_PATHNAME" do
- File.send(@method, '*a', 'aa', File::FNM_PATHNAME).should == true
- File.send(@method, 'a*', 'aa', File::FNM_PATHNAME).should == true
- File.send(@method, 'a*', 'aaa', File::FNM_PATHNAME).should == true
- File.send(@method, '*a', 'aaa', File::FNM_PATHNAME).should == true
- end
-
it "does not match '/' characters with ? or * when flags includes FNM_PATHNAME" do
File.send(@method, '?', '/', File::FNM_PATHNAME).should == false
File.send(@method, '*', '/', File::FNM_PATHNAME).should == false
@@ -173,19 +165,9 @@ describe :file_fnmatch, shared: true do
File.should_not.send(@method, '*/*', 'dave/.profile', File::FNM_PATHNAME)
end
- it "matches patterns with leading periods to dotfiles" do
+ it "matches patterns with leading periods to dotfiles by default" do
File.send(@method, '.*', '.profile').should == true
- File.send(@method, '.*', '.profile', File::FNM_PATHNAME).should == true
File.send(@method, ".*file", "nondotfile").should == false
- File.send(@method, ".*file", "nondotfile", File::FNM_PATHNAME).should == false
- end
-
- it "does not match directories with leading periods by default with FNM_PATHNAME" do
- File.send(@method, '.*', '.directory/nondotfile', File::FNM_PATHNAME).should == false
- File.send(@method, '.*', '.directory/.profile', File::FNM_PATHNAME).should == false
- File.send(@method, '.*', 'foo/.directory/nondotfile', File::FNM_PATHNAME).should == false
- File.send(@method, '.*', 'foo/.directory/.profile', File::FNM_PATHNAME).should == false
- File.send(@method, '**/.dotfile', '.dotsubdir/.dotfile', File::FNM_PATHNAME).should == false
end
it "matches leading periods in filenames when flags includes FNM_DOTMATCH" do
@@ -239,33 +221,6 @@ describe :file_fnmatch, shared: true do
File.send(@method, pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
end
- it "has special handling for ./ when using * and FNM_PATHNAME" do
- File.send(@method, './*', '.', File::FNM_PATHNAME).should be_false
- File.send(@method, './*', './', File::FNM_PATHNAME).should be_true
- File.send(@method, './*/', './', File::FNM_PATHNAME).should be_false
- File.send(@method, './**', './', File::FNM_PATHNAME).should be_true
- File.send(@method, './**/', './', File::FNM_PATHNAME).should be_true
- File.send(@method, './*', '.', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_false
- File.send(@method, './*', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
- File.send(@method, './*/', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_false
- File.send(@method, './**', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
- File.send(@method, './**/', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
- end
-
- it "matches **/* with FNM_PATHNAME to recurse directories" do
- File.send(@method, 'nested/**/*', 'nested/subdir', File::FNM_PATHNAME).should be_true
- File.send(@method, 'nested/**/*', 'nested/subdir/file', File::FNM_PATHNAME).should be_true
- File.send(@method, 'nested/**/*', 'nested/.dotsubdir', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
- File.send(@method, 'nested/**/*', 'nested/.dotsubir/.dotfile', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
- end
-
- it "matches ** with FNM_PATHNAME only in current directory" do
- File.send(@method, 'nested/**', 'nested/subdir', File::FNM_PATHNAME).should be_true
- File.send(@method, 'nested/**', 'nested/subdir/file', File::FNM_PATHNAME).should be_false
- File.send(@method, 'nested/**', 'nested/.dotsubdir', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
- File.send(@method, 'nested/**', 'nested/.dotsubir/.dotfile', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_false
- end
-
it "accepts an object that has a #to_path method" do
File.send(@method, '\*', mock_to_path('a')).should == false
end
diff --git a/spec/ruby/core/file/utime_spec.rb b/spec/ruby/core/file/utime_spec.rb
index 0b0e4f979c..cf7a0aec20 100644
--- a/spec/ruby/core/file/utime_spec.rb
+++ b/spec/ruby/core/file/utime_spec.rb
@@ -19,18 +19,20 @@ describe "File.utime" do
rm_r @file1, @file2
end
- it "sets the access and modification time of each file" do
- File.utime(@atime, @mtime, @file1, @file2)
- if @time_is_float
- File.atime(@file1).should be_close(@atime, 0.0001)
- File.mtime(@file1).should be_close(@mtime, 0.0001)
- File.atime(@file2).should be_close(@atime, 0.0001)
- File.mtime(@file2).should be_close(@mtime, 0.0001)
- else
- File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
- File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
- File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
- File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
+ platform_is_not :windows do
+ it "sets the access and modification time of each file" do
+ File.utime(@atime, @mtime, @file1, @file2)
+ if @time_is_float
+ File.atime(@file1).should be_close(@atime, 0.0001)
+ File.mtime(@file1).should be_close(@mtime, 0.0001)
+ File.atime(@file2).should be_close(@atime, 0.0001)
+ File.mtime(@file2).should be_close(@mtime, 0.0001)
+ else
+ File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
+ File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
+ File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
+ File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
+ end
end
end
diff --git a/spec/ruby/core/float/magnitude_spec.rb b/spec/ruby/core/float/magnitude_spec.rb
index 7cdd8ef28a..db577c15c5 100644
--- a/spec/ruby/core/float/magnitude_spec.rb
+++ b/spec/ruby/core/float/magnitude_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/abs'
describe "Float#magnitude" do
diff --git a/spec/ruby/core/float/round_spec.rb b/spec/ruby/core/float/round_spec.rb
index 9b4c307f9d..e5a8f534e7 100644
--- a/spec/ruby/core/float/round_spec.rb
+++ b/spec/ruby/core/float/round_spec.rb
@@ -136,7 +136,7 @@ describe "Float#round" do
-4.809999999999999.round(5, half: :even).should eql(-4.81)
end
- ruby_bug "#19318", ""..."3.3" do
+ ruby_bug "", ""..."3.3" do
# These numbers are neighbouring floating point numbers round a
# precise value. They test that the rounding modes work correctly
# round that value and precision is not lost which might cause
diff --git a/spec/ruby/core/gc/auto_compact_spec.rb b/spec/ruby/core/gc/auto_compact_spec.rb
index 33ad1cb56c..4f9d043171 100644
--- a/spec/ruby/core/gc/auto_compact_spec.rb
+++ b/spec/ruby/core/gc/auto_compact_spec.rb
@@ -1,24 +1,26 @@
require_relative '../../spec_helper'
-describe "GC.auto_compact" do
- it "can set and get a boolean value" do
- begin
- GC.auto_compact = GC.auto_compact
- rescue NotImplementedError # platform does not support autocompact
- skip
- end
+ruby_version_is "3.0" do
+ describe "GC.auto_compact" do
+ it "can set and get a boolean value" do
+ begin
+ GC.auto_compact = GC.auto_compact
+ rescue NotImplementedError # platform does not support autocompact
+ skip
+ end
- original = GC.auto_compact
- begin
- GC.auto_compact = !original
- rescue NotImplementedError # platform does not support autocompact
- skip
- end
+ original = GC.auto_compact
+ begin
+ GC.auto_compact = !original
+ rescue NotImplementedError # platform does not support autocompact
+ skip
+ end
- begin
- GC.auto_compact.should == !original
- ensure
- GC.auto_compact = original
+ begin
+ GC.auto_compact.should == !original
+ ensure
+ GC.auto_compact = original
+ end
end
end
end
diff --git a/spec/ruby/core/hash/compact_spec.rb b/spec/ruby/core/hash/compact_spec.rb
index 76aa43949d..2989afc8b7 100644
--- a/spec/ruby/core/hash/compact_spec.rb
+++ b/spec/ruby/core/hash/compact_spec.rb
@@ -18,30 +18,6 @@ describe "Hash#compact" do
@hash.compact
@hash.should == @initial_pairs
end
-
- ruby_version_is '3.3' do
- it "retains the default value" do
- hash = Hash.new(1)
- hash.compact.default.should == 1
- hash[:a] = 1
- hash.compact.default.should == 1
- end
-
- it "retains the default_proc" do
- pr = proc { |h, k| h[k] = [] }
- hash = Hash.new(&pr)
- hash.compact.default_proc.should == pr
- hash[:a] = 1
- hash.compact.default_proc.should == pr
- end
-
- it "retains compare_by_identity_flag" do
- hash = {}.compare_by_identity
- hash.compact.compare_by_identity?.should == true
- hash[:a] = 1
- hash.compact.compare_by_identity?.should == true
- end
- end
end
describe "Hash#compact!" do
diff --git a/spec/ruby/core/hash/constructor_spec.rb b/spec/ruby/core/hash/constructor_spec.rb
index 8d29773909..8fba47958f 100644
--- a/spec/ruby/core/hash/constructor_spec.rb
+++ b/spec/ruby/core/hash/constructor_spec.rb
@@ -103,26 +103,8 @@ describe "Hash.[]" do
HashSpecs::MyInitializerHash[Hash[1, 2]].should be_an_instance_of(HashSpecs::MyInitializerHash)
end
- it "removes the default value" do
- hash = Hash.new(1)
- Hash[hash].default.should be_nil
- hash[:a] = 1
- Hash[hash].default.should be_nil
- end
-
it "removes the default_proc" do
hash = Hash.new { |h, k| h[k] = [] }
Hash[hash].default_proc.should be_nil
- hash[:a] = 1
- Hash[hash].default_proc.should be_nil
- end
-
- ruby_version_is '3.3' do
- it "does not retain compare_by_identity_flag" do
- hash = {}.compare_by_identity
- Hash[hash].compare_by_identity?.should == false
- hash[:a] = 1
- Hash[hash].compare_by_identity?.should == false
- end
end
end
diff --git a/spec/ruby/core/hash/except_spec.rb b/spec/ruby/core/hash/except_spec.rb
index ac84f9975c..82cfced72f 100644
--- a/spec/ruby/core/hash/except_spec.rb
+++ b/spec/ruby/core/hash/except_spec.rb
@@ -1,32 +1,34 @@
require_relative '../../spec_helper'
-describe "Hash#except" do
- before :each do
- @hash = { a: 1, b: 2, c: 3 }
- end
+ruby_version_is "3.0" do
+ describe "Hash#except" do
+ before :each do
+ @hash = { a: 1, b: 2, c: 3 }
+ end
- it "returns a new duplicate hash without arguments" do
- ret = @hash.except
- ret.should_not equal(@hash)
- ret.should == @hash
- end
+ it "returns a new duplicate hash without arguments" do
+ ret = @hash.except
+ ret.should_not equal(@hash)
+ ret.should == @hash
+ end
- it "returns a hash without the requested subset" do
- @hash.except(:c, :a).should == { b: 2 }
- end
+ it "returns a hash without the requested subset" do
+ @hash.except(:c, :a).should == { b: 2 }
+ end
- it "ignores keys not present in the original hash" do
- @hash.except(:a, :chunky_bacon).should == { b: 2, c: 3 }
- end
+ it "ignores keys not present in the original hash" do
+ @hash.except(:a, :chunky_bacon).should == { b: 2, c: 3 }
+ end
- it "always returns a Hash without a default" do
- klass = Class.new(Hash)
- h = klass.new(:default)
- h[:bar] = 12
- h[:foo] = 42
- r = h.except(:foo)
- r.should == {bar: 12}
- r.class.should == Hash
- r.default.should == nil
+ it "always returns a Hash without a default" do
+ klass = Class.new(Hash)
+ h = klass.new(:default)
+ h[:bar] = 12
+ h[:foo] = 42
+ r = h.except(:foo)
+ r.should == {bar: 12}
+ r.class.should == Hash
+ r.default.should == nil
+ end
end
end
diff --git a/spec/ruby/core/hash/fetch_spec.rb b/spec/ruby/core/hash/fetch_spec.rb
index 6e0d207224..753167f709 100644
--- a/spec/ruby/core/hash/fetch_spec.rb
+++ b/spec/ruby/core/hash/fetch_spec.rb
@@ -4,7 +4,7 @@ require_relative '../../shared/hash/key_error'
describe "Hash#fetch" do
context "when the key is not found" do
- it_behaves_like :key_error, -> obj, key { obj.fetch(key) }, Hash.new({ a: 5 })
+ it_behaves_like :key_error, -> obj, key { obj.fetch(key) }, Hash.new(a: 5)
it_behaves_like :key_error, -> obj, key { obj.fetch(key) }, {}
it_behaves_like :key_error, -> obj, key { obj.fetch(key) }, Hash.new { 5 }
it_behaves_like :key_error, -> obj, key { obj.fetch(key) }, Hash.new(5)
diff --git a/spec/ruby/core/hash/fetch_values_spec.rb b/spec/ruby/core/hash/fetch_values_spec.rb
index 0cd48565af..af3673f6ef 100644
--- a/spec/ruby/core/hash/fetch_values_spec.rb
+++ b/spec/ruby/core/hash/fetch_values_spec.rb
@@ -19,7 +19,7 @@ describe "Hash#fetch_values" do
end
describe "with unmatched keys" do
- it_behaves_like :key_error, -> obj, key { obj.fetch_values(key) }, Hash.new({ a: 5 })
+ it_behaves_like :key_error, -> obj, key { obj.fetch_values(key) }, Hash.new(a: 5)
it "returns the default value from block" do
@hash.fetch_values(:z) { |key| "`#{key}' is not found" }.should == ["`z' is not found"]
diff --git a/spec/ruby/core/hash/hash_spec.rb b/spec/ruby/core/hash/hash_spec.rb
index 19eb806dc4..2ccb483120 100644
--- a/spec/ruby/core/hash/hash_spec.rb
+++ b/spec/ruby/core/hash/hash_spec.rb
@@ -43,7 +43,7 @@ describe "Hash#hash" do
end
ruby_version_is "3.1" do
- it "allows omitting values" do
+ it "allows ommiting values" do
a = 1
b = 2
diff --git a/spec/ruby/core/hash/index_spec.rb b/spec/ruby/core/hash/index_spec.rb
new file mode 100644
index 0000000000..be4e2cc6ab
--- /dev/null
+++ b/spec/ruby/core/hash/index_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/index'
+
+ruby_version_is ''...'3.0' do
+ describe "Hash#index" do
+ it_behaves_like :hash_index, :index
+ end
+end
diff --git a/spec/ruby/core/hash/new_spec.rb b/spec/ruby/core/hash/new_spec.rb
index 6279815fd6..6054b69bdd 100644
--- a/spec/ruby/core/hash/new_spec.rb
+++ b/spec/ruby/core/hash/new_spec.rb
@@ -33,17 +33,4 @@ describe "Hash.new" do
-> { Hash.new(5) { 0 } }.should raise_error(ArgumentError)
-> { Hash.new(nil) { 0 } }.should raise_error(ArgumentError)
end
-
- ruby_version_is "3.3" do
- it "emits a deprecation warning if keyword arguments are passed" do
- -> { Hash.new(unknown: true) }.should complain(
- Regexp.new(Regexp.escape("Calling Hash.new with keyword arguments is deprecated and will be removed in Ruby 3.4; use Hash.new({ key: value }) instead"))
- )
-
- -> { Hash.new(1, unknown: true) }.should raise_error(ArgumentError)
- -> { Hash.new(unknown: true) { 0 } }.should raise_error(ArgumentError)
-
- Hash.new({ unknown: true }).default.should == { unknown: true }
- end
- end
end
diff --git a/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb b/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb
index 7dbb9c0a98..e9337b9d1c 100644
--- a/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb
+++ b/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb
@@ -56,28 +56,4 @@ describe "Hash.ruby2_keywords_hash" do
it "raises TypeError for non-Hash" do
-> { Hash.ruby2_keywords_hash(nil) }.should raise_error(TypeError)
end
-
- it "retains the default value" do
- hash = Hash.new(1)
- Hash.ruby2_keywords_hash(hash).default.should == 1
- hash[:a] = 1
- Hash.ruby2_keywords_hash(hash).default.should == 1
- end
-
- it "retains the default_proc" do
- pr = proc { |h, k| h[k] = [] }
- hash = Hash.new(&pr)
- Hash.ruby2_keywords_hash(hash).default_proc.should == pr
- hash[:a] = 1
- Hash.ruby2_keywords_hash(hash).default_proc.should == pr
- end
-
- ruby_version_is '3.3' do
- it "retains compare_by_identity_flag" do
- hash = {}.compare_by_identity
- Hash.ruby2_keywords_hash(hash).compare_by_identity?.should == true
- hash[:a] = 1
- Hash.ruby2_keywords_hash(hash).compare_by_identity?.should == true
- end
- end
end
diff --git a/spec/ruby/core/hash/shared/each.rb b/spec/ruby/core/hash/shared/each.rb
index f9839ff58f..b2483c8116 100644
--- a/spec/ruby/core/hash/shared/each.rb
+++ b/spec/ruby/core/hash/shared/each.rb
@@ -21,18 +21,37 @@ describe :hash_each, shared: true do
ary.sort.should == ["a", "b", "c"]
end
- it "always yields an Array of 2 elements, even when given a callable of arity 2" do
- obj = Object.new
- def obj.foo(key, value)
- end
+ ruby_version_is ""..."3.0" do
+ it "yields 2 values and not an Array of 2 elements when given a callable of arity 2" do
+ obj = Object.new
+ def obj.foo(key, value)
+ ScratchPad << key << value
+ end
- -> {
+ ScratchPad.record([])
{ "a" => 1 }.send(@method, &obj.method(:foo))
- }.should raise_error(ArgumentError)
+ ScratchPad.recorded.should == ["a", 1]
- -> {
- { "a" => 1 }.send(@method, &-> key, value { })
- }.should raise_error(ArgumentError)
+ ScratchPad.record([])
+ { "a" => 1 }.send(@method, &-> key, value { ScratchPad << key << value })
+ ScratchPad.recorded.should == ["a", 1]
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "always yields an Array of 2 elements, even when given a callable of arity 2" do
+ obj = Object.new
+ def obj.foo(key, value)
+ end
+
+ -> {
+ { "a" => 1 }.send(@method, &obj.method(:foo))
+ }.should raise_error(ArgumentError)
+
+ -> {
+ { "a" => 1 }.send(@method, &-> key, value { })
+ }.should raise_error(ArgumentError)
+ end
end
it "yields an Array of 2 elements when given a callable of arity 1" do
diff --git a/spec/ruby/core/hash/shared/equal.rb b/spec/ruby/core/hash/shared/equal.rb
new file mode 100644
index 0000000000..43606437fe
--- /dev/null
+++ b/spec/ruby/core/hash/shared/equal.rb
@@ -0,0 +1,90 @@
+describe :hash_equal, shared: true do
+ it "does not compare values when keys don't match" do
+ value = mock('x')
+ value.should_not_receive(:==)
+ value.should_not_receive(:eql?)
+ { 1 => value }.send(@method, { 2 => value }).should be_false
+ end
+
+ it "returns false when the numbers of keys differ without comparing any elements" do
+ obj = mock('x')
+ h = { obj => obj }
+
+ obj.should_not_receive(:==)
+ obj.should_not_receive(:eql?)
+
+ {}.send(@method, h).should be_false
+ h.send(@method, {}).should be_false
+ end
+
+ it "first compares keys via hash" do
+ x = mock('x')
+ x.should_receive(:hash).and_return(0)
+ y = mock('y')
+ y.should_receive(:hash).and_return(0)
+
+ { x => 1 }.send(@method, { y => 1 }).should be_false
+ end
+
+ it "does not compare keys with different hash codes via eql?" do
+ x = mock('x')
+ y = mock('y')
+ x.should_not_receive(:eql?)
+ y.should_not_receive(:eql?)
+
+ x.should_receive(:hash).and_return(0)
+ y.should_receive(:hash).and_return(1)
+
+ def x.hash() 0 end
+ def y.hash() 1 end
+
+ { x => 1 }.send(@method, { y => 1 }).should be_false
+ end
+
+ it "computes equality for recursive hashes" do
+ h = {}
+ h[:a] = h
+ h.send(@method, h[:a]).should be_true
+ (h == h[:a]).should be_true
+ end
+
+ it "computes equality for complex recursive hashes" do
+ a, b = {}, {}
+ a.merge! self: a, other: b
+ b.merge! self: b, other: a
+ a.send(@method, b).should be_true # they both have the same structure!
+
+ c = {}
+ c.merge! other: c, self: c
+ c.send(@method, a).should be_true # subtle, but they both have the same structure!
+ a[:delta] = c[:delta] = a
+ c.send(@method, a).should be_false # not quite the same structure, as a[:other][:delta] = nil
+ c[:delta] = 42
+ c.send(@method, a).should be_false
+ a[:delta] = 42
+ c.send(@method, a).should be_false
+ b[:delta] = 42
+ c.send(@method, a).should be_true
+ end
+
+ it "computes equality for recursive hashes & arrays" do
+ x, y, z = [], [], []
+ a, b, c = {foo: x, bar: 42}, {foo: y, bar: 42}, {foo: z, bar: 42}
+ x << a
+ y << c
+ z << b
+ b.send(@method, c).should be_true # they clearly have the same structure!
+ y.send(@method, z).should be_true
+ a.send(@method, b).should be_true # subtle, but they both have the same structure!
+ x.send(@method, y).should be_true
+ y << x
+ y.send(@method, z).should be_false
+ z << x
+ y.send(@method, z).should be_true
+
+ a[:foo], a[:bar] = a[:bar], a[:foo]
+ a.send(@method, b).should be_false
+ b[:bar] = b[:foo]
+ b.send(@method, c).should be_false
+ end
+end
diff --git a/spec/ruby/core/hash/to_a_spec.rb b/spec/ruby/core/hash/to_a_spec.rb
index 5baf677929..8b7894a2ba 100644
--- a/spec/ruby/core/hash/to_a_spec.rb
+++ b/spec/ruby/core/hash/to_a_spec.rb
@@ -26,4 +26,14 @@ describe "Hash#to_a" do
ent.should be_kind_of(Array)
ent.should == pairs
end
+
+ ruby_version_is ''...'3.0' do
+ it "returns a not tainted array if self is tainted" do
+ {}.taint.to_a.tainted?.should be_false
+ end
+
+ it "returns a trusted array if self is untrusted" do
+ {}.untrust.to_a.untrusted?.should be_false
+ end
+ end
end
diff --git a/spec/ruby/core/hash/to_proc_spec.rb b/spec/ruby/core/hash/to_proc_spec.rb
index 9dbc79e5eb..8f5d21beb5 100644
--- a/spec/ruby/core/hash/to_proc_spec.rb
+++ b/spec/ruby/core/hash/to_proc_spec.rb
@@ -19,12 +19,20 @@ describe "Hash#to_proc" do
@proc = @hash.to_proc
end
- it "is a lambda" do
- @proc.should.lambda?
+ ruby_version_is ""..."3.0" do
+ it "is not a lambda" do
+ @proc.should_not.lambda?
+ end
end
- it "has an arity of 1" do
- @proc.arity.should == 1
+ ruby_version_is "3.0" do
+ it "is a lambda" do
+ @proc.should.lambda?
+ end
+
+ it "has an arity of 1" do
+ @proc.arity.should == 1
+ end
end
it "raises ArgumentError if not passed exactly one argument" do
diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb
index 2fbb17a8e2..361089ca97 100644
--- a/spec/ruby/core/hash/transform_keys_spec.rb
+++ b/spec/ruby/core/hash/transform_keys_spec.rb
@@ -43,16 +43,18 @@ describe "Hash#transform_keys" do
r.class.should == Hash
end
- it "allows a hash argument" do
- @hash.transform_keys({ a: :A, b: :B, c: :C }).should == { A: 1, B: 2, C: 3 }
- end
+ ruby_version_is "3.0" do
+ it "allows a hash argument" do
+ @hash.transform_keys({ a: :A, b: :B, c: :C }).should == { A: 1, B: 2, C: 3 }
+ end
- it "allows a partial transformation of keys when using a hash argument" do
- @hash.transform_keys({ a: :A, c: :C }).should == { A: 1, b: 2, C: 3 }
- end
+ it "allows a partial transformation of keys when using a hash argument" do
+ @hash.transform_keys({ a: :A, c: :C }).should == { A: 1, b: 2, C: 3 }
+ end
- it "allows a combination of hash and block argument" do
- @hash.transform_keys({ a: :A }, &:to_s).should == { A: 1, 'b' => 2, 'c' => 3 }
+ it "allows a combination of hash and block argument" do
+ @hash.transform_keys({ a: :A }, &:to_s).should == { A: 1, 'b' => 2, 'c' => 3 }
+ end
end
end
@@ -109,9 +111,11 @@ describe "Hash#transform_keys!" do
end
end
- it "allows a hash argument" do
- @hash.transform_keys!({ a: :A, b: :B, c: :C, d: :D })
- @hash.should == { A: 1, B: 2, C: 3, D: 4 }
+ ruby_version_is "3.0" do
+ it "allows a hash argument" do
+ @hash.transform_keys!({ a: :A, b: :B, c: :C, d: :D })
+ @hash.should == { A: 1, B: 2, C: 3, D: 4 }
+ end
end
describe "on frozen instance" do
@@ -128,8 +132,10 @@ describe "Hash#transform_keys!" do
@hash.should == @initial_pairs
end
- it "raises a FrozenError on hash argument" do
- ->{ @hash.transform_keys!({ a: :A, b: :B, c: :C }) }.should raise_error(FrozenError)
+ ruby_version_is "3.0" do
+ it "raises a FrozenError on hash argument" do
+ ->{ @hash.transform_keys!({ a: :A, b: :B, c: :C }) }.should raise_error(FrozenError)
+ end
end
context "when no block is given" do
diff --git a/spec/ruby/core/hash/try_convert_spec.rb b/spec/ruby/core/hash/try_convert_spec.rb
index d359ae49d8..44195c5010 100644
--- a/spec/ruby/core/hash/try_convert_spec.rb
+++ b/spec/ruby/core/hash/try_convert_spec.rb
@@ -39,7 +39,7 @@ describe "Hash.try_convert" do
it "sends #to_hash to the argument and raises TypeError if it's not a kind of Hash" do
obj = mock("to_hash")
obj.should_receive(:to_hash).and_return(Object.new)
- -> { Hash.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to Hash (MockObject#to_hash gives Object)")
+ -> { Hash.try_convert obj }.should raise_error(TypeError)
end
it "does not rescue exceptions raised by #to_hash" do
diff --git a/spec/ruby/core/integer/bit_and_spec.rb b/spec/ruby/core/integer/bit_and_spec.rb
index e7face39ac..8de5a14aaa 100644
--- a/spec/ruby/core/integer/bit_and_spec.rb
+++ b/spec/ruby/core/integer/bit_and_spec.rb
@@ -30,7 +30,7 @@ describe "Integer#&" do
it "coerces the rhs and calls #coerce" do
obj = mock("fixnum bit and")
- obj.should_receive(:coerce).with(6).and_return([6, 3])
+ obj.should_receive(:coerce).with(6).and_return([3, 6])
(6 & obj).should == 2
end
diff --git a/spec/ruby/core/integer/bit_or_spec.rb b/spec/ruby/core/integer/bit_or_spec.rb
index fdf8a191e5..6f4279c170 100644
--- a/spec/ruby/core/integer/bit_or_spec.rb
+++ b/spec/ruby/core/integer/bit_or_spec.rb
@@ -30,9 +30,9 @@ describe "Integer#|" do
end
it "coerces the rhs and calls #coerce" do
- obj = mock("fixnum bit or")
- obj.should_receive(:coerce).with(6).and_return([6, 3])
- (6 | obj).should == 7
+ obj = mock("fixnum bit and")
+ obj.should_receive(:coerce).with(6).and_return([3, 6])
+ (6 & obj).should == 2
end
it "raises a TypeError when passed a Float" do
diff --git a/spec/ruby/core/integer/bit_xor_spec.rb b/spec/ruby/core/integer/bit_xor_spec.rb
index 1f46bc52f3..f1150a20d5 100644
--- a/spec/ruby/core/integer/bit_xor_spec.rb
+++ b/spec/ruby/core/integer/bit_xor_spec.rb
@@ -28,8 +28,8 @@ describe "Integer#^" do
end
it "coerces the rhs and calls #coerce" do
- obj = mock("fixnum bit xor")
- obj.should_receive(:coerce).with(6).and_return([6, 3])
+ obj = mock("fixnum bit and")
+ obj.should_receive(:coerce).with(6).and_return([3, 6])
(6 ^ obj).should == 5
end
diff --git a/spec/ruby/core/integer/ceildiv_spec.rb b/spec/ruby/core/integer/ceildiv_spec.rb
deleted file mode 100644
index 18d07c66d0..0000000000
--- a/spec/ruby/core/integer/ceildiv_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Integer#ceildiv" do
- ruby_version_is '3.2' do
- it "returns a quotient of division which is rounded up to the nearest integer" do
- 0.ceildiv(3).should eql(0)
- 1.ceildiv(3).should eql(1)
- 3.ceildiv(3).should eql(1)
- 4.ceildiv(3).should eql(2)
-
- 4.ceildiv(-3).should eql(-1)
- -4.ceildiv(3).should eql(-1)
- -4.ceildiv(-3).should eql(2)
-
- 3.ceildiv(1.2).should eql(3)
- 3.ceildiv(6/5r).should eql(3)
-
- (10**100-11).ceildiv(10**99-1).should eql(10)
- (10**100-9).ceildiv(10**99-1).should eql(11)
- end
- end
-end
diff --git a/spec/ruby/core/integer/left_shift_spec.rb b/spec/ruby/core/integer/left_shift_spec.rb
index 0781371d93..135af90421 100644
--- a/spec/ruby/core/integer/left_shift_spec.rb
+++ b/spec/ruby/core/integer/left_shift_spec.rb
@@ -191,23 +191,21 @@ describe "Integer#<< (with n << m)" do
(0 << bignum_value).should == 0
end
- it "raises RangeError when m > 0 and n != 0" do
- # https://bugs.ruby-lang.org/issues/18518#note-9
- limit = RUBY_ENGINE == 'ruby' ? 2**67 : 2**32
-
- coerce_long = mock("long")
- coerce_long.stub!(:to_int).and_return(limit)
- coerce_bignum = mock("bignum")
- coerce_bignum.stub!(:to_int).and_return(bignum_value)
- exps = [limit, coerce_long]
- exps << bignum_value << coerce_bignum if bignum_value >= limit
-
- exps.each { |exp|
- -> { (1 << exp) }.should raise_error(RangeError, 'shift width too big')
- -> { (-1 << exp) }.should raise_error(RangeError, 'shift width too big')
- -> { (bignum_value << exp) }.should raise_error(RangeError, 'shift width too big')
- -> { (-bignum_value << exp) }.should raise_error(RangeError, 'shift width too big')
- }
+ ruby_bug "#18518", ""..."3.3" do
+ it "raises NoMemoryError when m > 0 and n != 0" do
+ coerce_long = mock("long")
+ coerce_long.stub!(:to_int).and_return(2**40)
+ coerce_bignum = mock("bignum")
+ coerce_bignum.stub!(:to_int).and_return(bignum_value)
+ exps = [2**40, bignum_value, coerce_long, coerce_bignum]
+
+ exps.each { |exp|
+ -> { (1 << exp) }.should raise_error(NoMemoryError)
+ -> { (-1 << exp) }.should raise_error(NoMemoryError)
+ -> { (bignum_value << exp) }.should raise_error(NoMemoryError)
+ -> { (-bignum_value << exp) }.should raise_error(NoMemoryError)
+ }
+ end
end
end
end
diff --git a/spec/ruby/core/integer/right_shift_spec.rb b/spec/ruby/core/integer/right_shift_spec.rb
index e91613d8d1..81405667b2 100644
--- a/spec/ruby/core/integer/right_shift_spec.rb
+++ b/spec/ruby/core/integer/right_shift_spec.rb
@@ -213,23 +213,21 @@ describe "Integer#>> (with n >> m)" do
(0 >> -bignum_value).should == 0
end
- it "raises RangeError when m < 0 and n != 0" do
- # https://bugs.ruby-lang.org/issues/18518#note-9
- limit = RUBY_ENGINE == 'ruby' ? 2**67 : 2**32
-
- coerce_long = mock("long")
- coerce_long.stub!(:to_int).and_return(-limit)
- coerce_bignum = mock("bignum")
- coerce_bignum.stub!(:to_int).and_return(-bignum_value)
- exps = [-limit, coerce_long]
- exps << -bignum_value << coerce_bignum if bignum_value >= limit
-
- exps.each { |exp|
- -> { (1 >> exp) }.should raise_error(RangeError, 'shift width too big')
- -> { (-1 >> exp) }.should raise_error(RangeError, 'shift width too big')
- -> { (bignum_value >> exp) }.should raise_error(RangeError, 'shift width too big')
- -> { (-bignum_value >> exp) }.should raise_error(RangeError, 'shift width too big')
- }
+ ruby_bug "#18518", ""..."3.3" do
+ it "raises NoMemoryError when m < 0 and n != 0" do
+ coerce_long = mock("long")
+ coerce_long.stub!(:to_int).and_return(-(2**40))
+ coerce_bignum = mock("bignum")
+ coerce_bignum.stub!(:to_int).and_return(-bignum_value)
+ exps = [-(2**40), -bignum_value, coerce_long, coerce_bignum]
+
+ exps.each { |exp|
+ -> { (1 >> exp) }.should raise_error(NoMemoryError)
+ -> { (-1 >> exp) }.should raise_error(NoMemoryError)
+ -> { (bignum_value >> exp) }.should raise_error(NoMemoryError)
+ -> { (-bignum_value >> exp) }.should raise_error(NoMemoryError)
+ }
+ end
end
end
end
diff --git a/spec/ruby/core/integer/shared/arithmetic_coerce.rb b/spec/ruby/core/integer/shared/arithmetic_coerce.rb
index 1260192df1..4c0cbcb999 100644
--- a/spec/ruby/core/integer/shared/arithmetic_coerce.rb
+++ b/spec/ruby/core/integer/shared/arithmetic_coerce.rb
@@ -1,5 +1,25 @@
require_relative '../fixtures/classes'
+describe :integer_arithmetic_coerce_rescue, shared: true do
+ it "rescues exception (StandardError and subclasses) raised in other#coerce and raises TypeError" do
+ b = mock("numeric with failed #coerce")
+ b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
+
+ # e.g. 1 + b
+ -> { 1.send(@method, b) }.should raise_error(TypeError, /MockObject can't be coerced into Integer/)
+ end
+
+ it "does not rescue Exception and StandardError siblings raised in other#coerce" do
+ [Exception, NoMemoryError].each do |exception|
+ b = mock("numeric with failed #coerce")
+ b.should_receive(:coerce).and_raise(exception)
+
+ # e.g. 1 + b
+ -> { 1.send(@method, b) }.should raise_error(exception)
+ end
+ end
+end
+
describe :integer_arithmetic_coerce_not_rescue, shared: true do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
diff --git a/spec/ruby/core/integer/try_convert_spec.rb b/spec/ruby/core/integer/try_convert_spec.rb
index 4bc7d3851a..45c66eec79 100644
--- a/spec/ruby/core/integer/try_convert_spec.rb
+++ b/spec/ruby/core/integer/try_convert_spec.rb
@@ -28,17 +28,7 @@ ruby_version_is "3.1" do
it "sends #to_int to the argument and raises TypeError if it's not a kind of Integer" do
obj = mock("to_int")
obj.should_receive(:to_int).and_return(Object.new)
- -> {
- Integer.try_convert obj
- }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives Object)")
- end
-
- it "responds with a different error message when it raises a TypeError, depending on the type of the non-Integer object :to_int returns" do
- obj = mock("to_int")
- obj.should_receive(:to_int).and_return("A String")
- -> {
- Integer.try_convert obj
- }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives String)")
+ -> { Integer.try_convert obj }.should raise_error(TypeError)
end
it "does not rescue exceptions raised by #to_int" do
diff --git a/spec/ruby/core/integer/zero_spec.rb b/spec/ruby/core/integer/zero_spec.rb
index bd362c4181..2dac50c406 100644
--- a/spec/ruby/core/integer/zero_spec.rb
+++ b/spec/ruby/core/integer/zero_spec.rb
@@ -7,7 +7,15 @@ describe "Integer#zero?" do
-1.should_not.zero?
end
- it "Integer#zero? overrides Numeric#zero?" do
- 42.method(:zero?).owner.should == Integer
+ ruby_version_is "3.0" do
+ it "Integer#zero? overrides Numeric#zero?" do
+ 42.method(:zero?).owner.should == Integer
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "Integer#zero? uses Numeric#zero?" do
+ 42.method(:zero?).owner.should == Numeric
+ end
end
end
diff --git a/spec/ruby/core/io/binread_spec.rb b/spec/ruby/core/io/binread_spec.rb
index 418e89213b..a3f752d8f9 100644
--- a/spec/ruby/core/io/binread_spec.rb
+++ b/spec/ruby/core/io/binread_spec.rb
@@ -44,14 +44,4 @@ describe "IO.binread" do
it "raises an Errno::EINVAL when not passed a valid offset" do
-> { IO.binread @fname, 0, -1 }.should raise_error(Errno::EINVAL)
end
-
- ruby_version_is "3.3" do
- # https://bugs.ruby-lang.org/issues/19630
- it "warns about deprecation given a path with a pipe" do
- cmd = "|echo ok"
- -> {
- IO.binread(cmd)
- }.should complain(/IO process creation with a leading '\|'/)
- end
- end
end
diff --git a/spec/ruby/core/io/bytes_spec.rb b/spec/ruby/core/io/bytes_spec.rb
new file mode 100644
index 0000000000..6e328983f2
--- /dev/null
+++ b/spec/ruby/core/io/bytes_spec.rb
@@ -0,0 +1,47 @@
+# -*- encoding: utf-8 -*-
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is ''...'3.0' do
+ describe "IO#bytes" do
+ before :each do
+ @io = IOSpecs.io_fixture "lines.txt"
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ @io.close unless @io.closed?
+ end
+
+ it "returns an enumerator of the next bytes from the stream" do
+ enum = @io.bytes
+ enum.should be_an_instance_of(Enumerator)
+ @io.readline.should == "Voici la ligne une.\n"
+ enum.first(5).should == [81, 117, 105, 32, 195]
+ end
+
+ it "yields each byte" do
+ count = 0
+ ScratchPad.record []
+ @io.each_byte do |byte|
+ ScratchPad << byte
+ break if 4 < count += 1
+ end
+
+ ScratchPad.recorded.should == [86, 111, 105, 99, 105]
+ end
+
+ it "raises an IOError on closed stream" do
+ enum = IOSpecs.closed_io.bytes
+ -> { enum.first }.should raise_error(IOError)
+ end
+
+ it "raises an IOError on an enumerator for a stream that has been closed" do
+ enum = @io.bytes
+ enum.first.should == 86
+ @io.close
+ -> { enum.first }.should raise_error(IOError)
+ end
+ end
+end
diff --git a/spec/ruby/core/io/chars_spec.rb b/spec/ruby/core/io/chars_spec.rb
new file mode 100644
index 0000000000..15db595aed
--- /dev/null
+++ b/spec/ruby/core/io/chars_spec.rb
@@ -0,0 +1,30 @@
+# -*- encoding: utf-8 -*-
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/chars'
+
+ruby_version_is ''...'3.0' do
+ describe "IO#chars" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :io_chars, :chars
+ end
+
+ describe "IO#chars" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :io_chars_empty, :chars
+ end
+end
diff --git a/spec/ruby/core/io/codepoints_spec.rb b/spec/ruby/core/io/codepoints_spec.rb
new file mode 100644
index 0000000000..04c115dd3f
--- /dev/null
+++ b/spec/ruby/core/io/codepoints_spec.rb
@@ -0,0 +1,38 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/codepoints'
+
+ruby_version_is ''...'3.0' do
+
+ # See redmine #1667
+ describe "IO#codepoints" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :io_codepoints, :codepoints
+ end
+
+ describe "IO#codepoints" do
+ before :each do
+ @io = IOSpecs.io_fixture "lines.txt"
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ @io.close unless @io.closed?
+ end
+
+ it "calls the given block" do
+ r = []
+ @io.codepoints { |c| r << c }
+ r[24].should == 232
+ r.last.should == 10
+ end
+ end
+end
diff --git a/spec/ruby/core/io/copy_stream_spec.rb b/spec/ruby/core/io/copy_stream_spec.rb
index ffa2ea992c..df9c5c7390 100644
--- a/spec/ruby/core/io/copy_stream_spec.rb
+++ b/spec/ruby/core/io/copy_stream_spec.rb
@@ -69,12 +69,9 @@ describe :io_copy_stream_to_io, shared: true do
end
it "raises an IOError if the destination IO is not open for writing" do
- to_io = new_io __FILE__, "r"
- begin
- -> { IO.copy_stream @object.from, to_io }.should raise_error(IOError)
- ensure
- to_io.close
- end
+ @to_io.close
+ @to_io = new_io @to_name, "r"
+ -> { IO.copy_stream @object.from, @to_io }.should raise_error(IOError)
end
it "does not close the destination IO" do
@@ -112,8 +109,7 @@ describe "IO.copy_stream" do
end
after :each do
- rm_r @to_name if @to_name
- rm_r @from_bigfile
+ rm_r @to_name, @from_bigfile
end
describe "from an IO" do
@@ -168,25 +164,6 @@ describe "IO.copy_stream" do
it_behaves_like :io_copy_stream_to_io, nil, IOSpecs::CopyStream
it_behaves_like :io_copy_stream_to_io_with_offset, nil, IOSpecs::CopyStream
end
-
- describe "to a Tempfile" do
- before :all do
- require 'tempfile'
- end
-
- before :each do
- @to_io = Tempfile.new("rubyspec_copy_stream", encoding: Encoding::BINARY, mode: File::RDONLY)
- @to_name = @to_io.path
- end
-
- after :each do
- @to_io.close!
- @to_name = nil # do not rm_r it, already done by Tempfile#close!
- end
-
- it_behaves_like :io_copy_stream_to_io, nil, IOSpecs::CopyStream
- it_behaves_like :io_copy_stream_to_io_with_offset, nil, IOSpecs::CopyStream
- end
end
describe "from a file name" do
@@ -300,8 +277,10 @@ describe "IO.copy_stream" do
@io.should_not_receive(:pos)
IO.copy_stream(@io, @to_name)
end
+
end
+
describe "with a destination that does partial reads" do
before do
@from_out, @from_in = IO.pipe
diff --git a/spec/ruby/core/io/eof_spec.rb b/spec/ruby/core/io/eof_spec.rb
index b4850df437..315345d942 100644
--- a/spec/ruby/core/io/eof_spec.rb
+++ b/spec/ruby/core/io/eof_spec.rb
@@ -76,7 +76,7 @@ describe "IO#eof?" do
end
it "returns true on one-byte stream after single-byte read" do
- File.open(__dir__ + '/fixtures/one_byte.txt') { |one_byte|
+ File.open(File.dirname(__FILE__) + '/fixtures/one_byte.txt') { |one_byte|
one_byte.read(1)
one_byte.should.eof?
}
diff --git a/spec/ruby/core/io/flush_spec.rb b/spec/ruby/core/io/flush_spec.rb
index f7d5ba77fc..34cf42c425 100644
--- a/spec/ruby/core/io/flush_spec.rb
+++ b/spec/ruby/core/io/flush_spec.rb
@@ -19,11 +19,11 @@ describe "IO#flush" do
end
end
- # [ruby-core:90895] RJIT worker may leave fd open in a forked child.
- # For instance, RJIT creates a worker before @r.close with fork(), @r.close happens,
- # and the RJIT worker keeps the pipe open until the worker execve().
- # TODO: consider acquiring GVL from RJIT worker.
- guard_not -> { defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? } do
+ # [ruby-core:90895] MJIT worker may leave fd open in a forked child.
+ # For instance, MJIT creates a worker before @r.close with fork(), @r.close happens,
+ # and the MJIT worker keeps the pipe open until the worker execve().
+ # TODO: consider acquiring GVL from MJIT worker.
+ guard_not -> { defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? } do
it "raises Errno::EPIPE if sync=false and the read end is closed" do
@w.sync = false
@w.write "foo"
diff --git a/spec/ruby/core/io/foreach_spec.rb b/spec/ruby/core/io/foreach_spec.rb
index c361d27879..c2276cf544 100644
--- a/spec/ruby/core/io/foreach_spec.rb
+++ b/spec/ruby/core/io/foreach_spec.rb
@@ -20,10 +20,7 @@ describe "IO.foreach" do
platform_is :windows do
cmd = "|cmd.exe /C echo hello&echo line2"
end
-
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- IO.foreach(cmd) { |l| ScratchPad << l }
- end
+ IO.foreach(cmd) { |l| ScratchPad << l }
ScratchPad.recorded.should == ["hello\n", "line2\n"]
end
@@ -31,9 +28,7 @@ describe "IO.foreach" do
it "gets data from a fork when passed -" do
parent_pid = $$
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- IO.foreach("|-") { |l| ScratchPad << l }
- end
+ IO.foreach("|-") { |l| ScratchPad << l }
if $$ == parent_pid
ScratchPad.recorded.should == ["hello\n", "from a fork\n"]
@@ -44,16 +39,6 @@ describe "IO.foreach" do
end
end
end
-
- ruby_version_is "3.3" do
- # https://bugs.ruby-lang.org/issues/19630
- it "warns about deprecation given a path with a pipe" do
- cmd = "|echo ok"
- -> {
- IO.foreach(cmd).to_a
- }.should complain(/IO process creation with a leading '\|'/)
- end
- end
end
end
diff --git a/spec/ruby/core/io/getbyte_spec.rb b/spec/ruby/core/io/getbyte_spec.rb
index b4351160e6..6ba8f0a3e0 100644
--- a/spec/ruby/core/io/getbyte_spec.rb
+++ b/spec/ruby/core/io/getbyte_spec.rb
@@ -40,19 +40,3 @@ describe "IO#getbyte" do
@io.getbyte.should == nil
end
end
-
-describe "IO#getbyte" do
- before :each do
- @name = tmp("io_getbyte.txt")
- @io = new_io(@name, 'w')
- end
-
- after :each do
- @io.close if @io
- rm_r @name if @name
- end
-
- it "raises an IOError if the stream is not readable" do
- -> { @io.getbyte }.should raise_error(IOError)
- end
-end
diff --git a/spec/ruby/core/io/gets_spec.rb b/spec/ruby/core/io/gets_spec.rb
index ca64bf860e..d0c91705af 100644
--- a/spec/ruby/core/io/gets_spec.rb
+++ b/spec/ruby/core/io/gets_spec.rb
@@ -24,12 +24,6 @@ describe "IO#gets" do
end
end
- it "sets $_ to nil after the last line has been read" do
- while @io.gets
- end
- $_.should be_nil
- end
-
it "returns nil if called at the end of the stream" do
IOSpecs.lines.length.times { @io.gets }
@io.gets.should == nil
@@ -119,35 +113,6 @@ describe "IO#gets" do
$..should == @count += 1
end
end
-
- describe "that consists of multiple bytes" do
- platform_is_not :windows do
- it "should match the separator even if the buffer is filled over successive reads" do
- IO.pipe do |read, write|
-
- # Write part of the string with the separator split between two write calls. We want
- # the read to intertwine such that when the read starts the full data isn't yet
- # available in the buffer.
- write.write("Aquí está la línea tres\r\n")
-
- t = Thread.new do
- # Continue reading until the separator is encountered or the pipe is closed.
- read.gets("\r\n\r\n")
- end
-
- # Write the other half of the separator, which should cause the `gets` call to now
- # match. Explicitly close the pipe for good measure so a bug in `gets` doesn't block forever.
- Thread.pass until t.stop?
-
- write.write("\r\nelse\r\n\r\n")
- write.close
-
- t.value.bytes.should == "Aquí está la línea tres\r\n\r\n".bytes
- read.read(8).bytes.should == "else\r\n\r\n".bytes
- end
- end
- end
- end
end
describe "when passed chomp" do
@@ -155,12 +120,14 @@ describe "IO#gets" do
@io.gets(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
end
- it "raises exception when options passed as Hash" do
- -> { @io.gets({ chomp: true }) }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises exception when options passed as Hash" do
+ -> { @io.gets({ chomp: true }) }.should raise_error(TypeError)
- -> {
- @io.gets("\n", 1, { chomp: true })
- }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ -> {
+ @io.gets("\n", 1, { chomp: true })
+ }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ end
end
end
end
@@ -338,23 +305,11 @@ describe "IO#gets" do
@io.gets.encoding.should == Encoding::BINARY
end
- ruby_version_is ''...'3.3' do
- it "transcodes to internal encoding if the IO object's external encoding is BINARY" do
- Encoding.default_external = Encoding::BINARY
- Encoding.default_internal = Encoding::UTF_8
- @io = new_io @name, 'r'
- @io.set_encoding Encoding::BINARY, Encoding::UTF_8
- @io.gets.encoding.should == Encoding::UTF_8
- end
- end
-
- ruby_version_is '3.3' do
- it "ignores the internal encoding if the IO object's external encoding is BINARY" do
- Encoding.default_external = Encoding::BINARY
- Encoding.default_internal = Encoding::UTF_8
- @io = new_io @name, 'r'
- @io.set_encoding Encoding::BINARY, Encoding::UTF_8
- @io.gets.encoding.should == Encoding::BINARY
- end
+ it "transcodes to internal encoding if the IO object's external encoding is BINARY" do
+ Encoding.default_external = Encoding::BINARY
+ Encoding.default_internal = Encoding::UTF_8
+ @io = new_io @name, 'r'
+ @io.set_encoding Encoding::BINARY, Encoding::UTF_8
+ @io.gets.encoding.should == Encoding::UTF_8
end
end
diff --git a/spec/ruby/core/io/initialize_spec.rb b/spec/ruby/core/io/initialize_spec.rb
index 026252a13d..ba5bc117b7 100644
--- a/spec/ruby/core/io/initialize_spec.rb
+++ b/spec/ruby/core/io/initialize_spec.rb
@@ -27,17 +27,6 @@ describe "IO#initialize" do
@io.fileno.should == fd
end
- it "accepts options as keyword arguments" do
- fd = new_fd @name, "w:utf-8"
-
- @io.send(:initialize, fd, "w", flags: File::CREAT)
- @io.fileno.should == fd
-
- -> {
- @io.send(:initialize, fd, "w", {flags: File::CREAT})
- }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 1..2)")
- end
-
it "raises a TypeError when passed an IO" do
-> { @io.send :initialize, STDOUT, 'w' }.should raise_error(TypeError)
end
diff --git a/spec/ruby/core/io/lines_spec.rb b/spec/ruby/core/io/lines_spec.rb
new file mode 100644
index 0000000000..5b29a1d07e
--- /dev/null
+++ b/spec/ruby/core/io/lines_spec.rb
@@ -0,0 +1,46 @@
+# -*- encoding: utf-8 -*-
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is ''...'3.0' do
+ describe "IO#lines" do
+ before :each do
+ @io = IOSpecs.io_fixture "lines.txt"
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ @io.close if @io
+ end
+
+ it "returns an Enumerator" do
+ @io.lines.should be_an_instance_of(Enumerator)
+ end
+
+ describe "when no block is given" do
+ it "returns an Enumerator" do
+ @io.lines.should be_an_instance_of(Enumerator)
+ end
+
+ describe "returned Enumerator" do
+ describe "size" do
+ it "should return nil" do
+ @io.lines.size.should == nil
+ end
+ end
+ end
+ end
+
+ it "returns a line when accessed" do
+ enum = @io.lines
+ enum.first.should == IOSpecs.lines[0]
+ end
+
+ it "yields each line to the passed block" do
+ ScratchPad.record []
+ @io.lines { |s| ScratchPad << s }
+ ScratchPad.recorded.should == IOSpecs.lines
+ end
+ end
+end
diff --git a/spec/ruby/core/io/new_spec.rb b/spec/ruby/core/io/new_spec.rb
index 979ac0efcb..0ef30991fd 100644
--- a/spec/ruby/core/io/new_spec.rb
+++ b/spec/ruby/core/io/new_spec.rb
@@ -1,16 +1,10 @@
require_relative '../../spec_helper'
require_relative 'shared/new'
-# NOTE: should be synchronized with library/stringio/initialize_spec.rb
+# NOTE: should be syncronized with library/stringio/initialize_spec.rb
describe "IO.new" do
it_behaves_like :io_new, :new
-
- it "does not use the given block and warns to use IO::open" do
- -> {
- @io = IO.send(@method, @fd) { raise }
- }.should complain(/warning: IO::new\(\) does not take block; use IO::open\(\) instead/)
- end
end
describe "IO.new" do
diff --git a/spec/ruby/core/io/nonblock_spec.rb b/spec/ruby/core/io/nonblock_spec.rb
index 99dc0cafd0..e81ac10c58 100644
--- a/spec/ruby/core/io/nonblock_spec.rb
+++ b/spec/ruby/core/io/nonblock_spec.rb
@@ -12,21 +12,43 @@ platform_is_not :windows do
end
end
- it "returns true for pipe by default" do
- r, w = IO.pipe
- begin
- r.nonblock?.should == true
- w.nonblock?.should == true
- ensure
- r.close
- w.close
+ ruby_version_is ""..."3.0" do
+ it "returns false for pipe by default" do
+ r, w = IO.pipe
+ begin
+ r.nonblock?.should == false
+ w.nonblock?.should == false
+ ensure
+ r.close
+ w.close
+ end
+ end
+
+ it "returns false for socket by default" do
+ require 'socket'
+ TCPServer.open(0) do |socket|
+ socket.nonblock?.should == false
+ end
end
end
- it "returns true for socket by default" do
- require 'socket'
- TCPServer.open(0) do |socket|
- socket.nonblock?.should == true
+ ruby_version_is "3.0" do
+ it "returns true for pipe by default" do
+ r, w = IO.pipe
+ begin
+ r.nonblock?.should == true
+ w.nonblock?.should == true
+ ensure
+ r.close
+ w.close
+ end
+ end
+
+ it "returns true for socket by default" do
+ require 'socket'
+ TCPServer.open(0) do |socket|
+ socket.nonblock?.should == true
+ end
end
end
end
diff --git a/spec/ruby/core/io/open_spec.rb b/spec/ruby/core/io/open_spec.rb
index d151da9ce5..d3a3961df7 100644
--- a/spec/ruby/core/io/open_spec.rb
+++ b/spec/ruby/core/io/open_spec.rb
@@ -37,19 +37,6 @@ describe "IO.open" do
ScratchPad.recorded.should == :called
end
- it "propagate an exception in the block after calling #close" do
- -> do
- IO.open(@fd, "w") do |io|
- IOSpecs.io_mock(io, :close) do
- super()
- ScratchPad.record :called
- end
- raise Exception
- end
- end.should raise_error(Exception)
- ScratchPad.recorded.should == :called
- end
-
it "propagates an exception raised by #close that is not a StandardError" do
-> do
IO.open(@fd, "w") do |io|
diff --git a/spec/ruby/core/io/pread_spec.rb b/spec/ruby/core/io/pread_spec.rb
index aa496ee803..43071d6a31 100644
--- a/spec/ruby/core/io/pread_spec.rb
+++ b/spec/ruby/core/io/pread_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
-guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
+platform_is_not :windows do
describe "IO#pread" do
before :each do
@fname = tmp("io_pread.txt")
@@ -26,88 +26,11 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
buffer.should == "567"
end
- it "shrinks the buffer in case of less bytes read" do
- buffer = "foo"
- @file.pread(1, 0, buffer)
- buffer.should == "1"
- end
-
- it "grows the buffer in case of more bytes read" do
- buffer = "foo"
- @file.pread(5, 0, buffer)
- buffer.should == "12345"
- end
-
it "does not advance the file pointer" do
@file.pread(4, 0).should == "1234"
@file.read.should == "1234567890"
end
- it "ignores the current offset" do
- @file.pos = 3
- @file.pread(4, 0).should == "1234"
- end
-
- it "returns an empty string for maxlen = 0" do
- @file.pread(0, 4).should == ""
- end
-
- it "ignores the offset for maxlen = 0, even if it is out of file bounds" do
- @file.pread(0, 400).should == ""
- end
-
- it "does not reset the buffer when reading with maxlen = 0" do
- buffer = "foo"
- @file.pread(0, 4, buffer)
- buffer.should == "foo"
-
- @file.pread(0, 400, buffer)
- buffer.should == "foo"
- end
-
- it "converts maxlen to Integer using #to_int" do
- maxlen = mock('maxlen')
- maxlen.should_receive(:to_int).and_return(4)
- @file.pread(maxlen, 0).should == "1234"
- end
-
- it "converts offset to Integer using #to_int" do
- offset = mock('offset')
- offset.should_receive(:to_int).and_return(0)
- @file.pread(4, offset).should == "1234"
- end
-
- it "converts a buffer to String using to_str" do
- buffer = mock('buffer')
- buffer.should_receive(:to_str).at_least(1).and_return("foo")
- @file.pread(4, 0, buffer)
- buffer.should_not.is_a?(String)
- buffer.to_str.should == "1234"
- end
-
- it "raises TypeError if maxlen is not an Integer and cannot be coerced into Integer" do
- maxlen = Object.new
- -> { @file.pread(maxlen, 0) }.should raise_error(TypeError, 'no implicit conversion of Object into Integer')
- end
-
- it "raises TypeError if offset is not an Integer and cannot be coerced into Integer" do
- offset = Object.new
- -> { @file.pread(4, offset) }.should raise_error(TypeError, 'no implicit conversion of Object into Integer')
- end
-
- it "raises ArgumentError for negative values of maxlen" do
- -> { @file.pread(-4, 0) }.should raise_error(ArgumentError, 'negative string size (or size too big)')
- end
-
- it "raised Errno::EINVAL for negative values of offset" do
- -> { @file.pread(4, -1) }.should raise_error(Errno::EINVAL, /Invalid argument/)
- end
-
- it "raises TypeError if the buffer is not a String and cannot be coerced into String" do
- buffer = Object.new
- -> { @file.pread(4, 0, buffer) }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
-
it "raises EOFError if end-of-file is reached" do
-> { @file.pread(1, 10) }.should raise_error(EOFError)
end
diff --git a/spec/ruby/core/io/pwrite_spec.rb b/spec/ruby/core/io/pwrite_spec.rb
index 00d40db28d..fe29d1e1f6 100644
--- a/spec/ruby/core/io/pwrite_spec.rb
+++ b/spec/ruby/core/io/pwrite_spec.rb
@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
-guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
+platform_is_not :windows do
describe "IO#pwrite" do
before :each do
@fname = tmp("io_pwrite.txt")
@@ -28,42 +28,16 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
@file.pread(6, 0).should == "foobar"
end
- it "calls #to_s on the object to be written" do
- object = mock("to_s")
- object.should_receive(:to_s).and_return("foo")
- @file.pwrite(object, 0)
- @file.pread(3, 0).should == "foo"
- end
-
- it "calls #to_int on the offset" do
- offset = mock("to_int")
- offset.should_receive(:to_int).and_return(2)
- @file.pwrite("foo", offset)
- @file.pread(3, 2).should == "foo"
- end
-
it "raises IOError when file is not open in write mode" do
File.open(@fname, "r") do |file|
- -> { file.pwrite("foo", 1) }.should raise_error(IOError, "not opened for writing")
+ -> { file.pwrite("foo", 1) }.should raise_error(IOError)
end
end
it "raises IOError when file is closed" do
file = File.open(@fname, "w+")
file.close
- -> { file.pwrite("foo", 1) }.should raise_error(IOError, "closed stream")
- end
-
- it "raises a NoMethodError if object does not respond to #to_s" do
- -> {
- @file.pwrite(BasicObject.new, 0)
- }.should raise_error(NoMethodError, /undefined method `to_s'/)
- end
-
- it "raises a TypeError if the offset cannot be converted to an Integer" do
- -> {
- @file.pwrite("foo", Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
+ -> { file.pwrite("foo", 1) }.should raise_error(IOError)
end
end
end
diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb
index db11468ea4..529afbf0ff 100644
--- a/spec/ruby/core/io/read_spec.rb
+++ b/spec/ruby/core/io/read_spec.rb
@@ -23,15 +23,6 @@ describe "IO.read" do
IO.read(p)
end
- # https://bugs.ruby-lang.org/issues/19354
- it "accepts options as keyword arguments" do
- IO.read(@fname, 3, 0, mode: "r+").should == @contents[0, 3]
-
- -> {
- IO.read(@fname, 3, 0, {mode: "r+"})
- }.should raise_error(ArgumentError, /wrong number of arguments/)
- end
-
it "accepts an empty options Hash" do
IO.read(@fname, **{}).should == @contents
end
@@ -64,33 +55,6 @@ describe "IO.read" do
IO.read(@fname, mode: "a+").should == @contents
end
- platform_is_not :windows do
- ruby_version_is ""..."3.3" do
- it "uses an :open_args option" do
- string = IO.read(@fname, nil, 0, open_args: ["r", nil, {encoding: Encoding::US_ASCII}])
- string.encoding.should == Encoding::US_ASCII
-
- string = IO.read(@fname, nil, 0, open_args: ["r", nil, {}])
- string.encoding.should == Encoding::UTF_8
- end
- end
- end
-
- it "disregards other options if :open_args is given" do
- string = IO.read(@fname,mode: "w", encoding: Encoding::UTF_32LE, open_args: ["r", encoding: Encoding::UTF_8])
- string.encoding.should == Encoding::UTF_8
- end
-
- it "doesn't require mode to be specified in :open_args" do
- string = IO.read(@fname, nil, 0, open_args: [{encoding: Encoding::US_ASCII}])
- string.encoding.should == Encoding::US_ASCII
- end
-
- it "doesn't require mode to be specified in :open_args even if flags option passed" do
- string = IO.read(@fname, nil, 0, open_args: [{encoding: Encoding::US_ASCII, flags: File::CREAT}])
- string.encoding.should == Encoding::US_ASCII
- end
-
it "treats second nil argument as no length limit" do
IO.read(@fname, nil).should == @contents
IO.read(@fname, nil, 5).should == IO.read(@fname, @contents.length, 5)
@@ -113,15 +77,6 @@ describe "IO.read" do
IO.read(@fname, 1, 10).should == nil
end
- it "returns an empty string when reading zero bytes" do
- IO.read(@fname, 0).should == ''
- end
-
- it "returns a String in BINARY when passed a size" do
- IO.read(@fname, 1).encoding.should == Encoding::BINARY
- IO.read(@fname, 0).encoding.should == Encoding::BINARY
- end
-
it "raises an Errno::ENOENT when the requested file does not exist" do
rm_r @fname
-> { IO.read @fname }.should raise_error(Errno::ENOENT)
@@ -135,18 +90,9 @@ describe "IO.read" do
-> { IO.read @fname, -1 }.should raise_error(ArgumentError)
end
- ruby_version_is ''...'3.3' do
- it "raises an Errno::EINVAL when not passed a valid offset" do
- -> { IO.read @fname, 0, -1 }.should raise_error(Errno::EINVAL)
- -> { IO.read @fname, -1, -1 }.should raise_error(Errno::EINVAL)
- end
- end
-
- ruby_version_is '3.3' do
- it "raises an ArgumentError when not passed a valid offset" do
- -> { IO.read @fname, 0, -1 }.should raise_error(ArgumentError)
- -> { IO.read @fname, -1, -1 }.should raise_error(ArgumentError)
- end
+ it "raises an Errno::EINVAL when not passed a valid offset" do
+ -> { IO.read @fname, 0, -1 }.should raise_error(Errno::EINVAL)
+ -> { IO.read @fname, -1, -1 }.should raise_error(Errno::EINVAL)
end
it "uses the external encoding specified via the :external_encoding option" do
@@ -174,19 +120,12 @@ describe "IO.read from a pipe" do
platform_is :windows do
cmd = "|cmd.exe /C echo hello"
end
-
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- IO.read(cmd).should == "hello\n"
- end
+ IO.read(cmd).should == "hello\n"
end
platform_is_not :windows do
it "opens a pipe to a fork if the rest is -" do
- str = nil
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- str = IO.read("|-")
- end
-
+ str = IO.read("|-")
if str # parent
str.should == "hello from child\n"
else #child
@@ -201,18 +140,13 @@ describe "IO.read from a pipe" do
platform_is :windows do
cmd = "|cmd.exe /C echo hello"
end
-
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- IO.read(cmd, 1).should == "h"
- end
+ IO.read(cmd, 1).should == "h"
end
platform_is_not :windows do
it "raises Errno::ESPIPE if passed an offset" do
-> {
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- IO.read("|sh -c 'echo hello'", 1, 1)
- end
+ IO.read("|sh -c 'echo hello'", 1, 1)
}.should raise_error(Errno::ESPIPE)
end
end
@@ -223,23 +157,11 @@ quarantine! do # The process tried to write to a nonexistent pipe.
# once https://bugs.ruby-lang.org/issues/12230 is fixed.
it "raises Errno::EINVAL if passed an offset" do
-> {
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- IO.read("|cmd.exe /C echo hello", 1, 1)
- end
+ IO.read("|cmd.exe /C echo hello", 1, 1)
}.should raise_error(Errno::EINVAL)
end
end
end
-
- ruby_version_is "3.3" do
- # https://bugs.ruby-lang.org/issues/19630
- it "warns about deprecation given a path with a pipe" do
- cmd = "|echo ok"
- -> {
- IO.read(cmd)
- }.should complain(/IO process creation with a leading '\|'/)
- end
- end
end
describe "IO.read on an empty file" do
@@ -283,14 +205,6 @@ describe "IO#read" do
@io.read(4).should == '7890'
end
- it "treats first nil argument as no length limit" do
- @io.read(nil).should == @contents
- end
-
- it "raises an ArgumentError when not passed a valid length" do
- -> { @io.read(-1) }.should raise_error(ArgumentError)
- end
-
it "clears the output buffer if there is nothing to read" do
@io.pos = 10
@@ -299,32 +213,6 @@ describe "IO#read" do
@io.read(10, buf).should == nil
buf.should == ''
-
- buf = 'non-empty string'
-
- @io.read(nil, buf).should == ""
-
- buf.should == ''
-
- buf = 'non-empty string'
-
- @io.read(0, buf).should == ""
-
- buf.should == ''
- end
-
- it "raise FrozenError if the output buffer is frozen" do
- @io.read
- -> { @io.read(0, 'frozen-string'.freeze) }.should raise_error(FrozenError)
- -> { @io.read(1, 'frozen-string'.freeze) }.should raise_error(FrozenError)
- -> { @io.read(nil, 'frozen-string'.freeze) }.should raise_error(FrozenError)
- end
-
- ruby_bug "", ""..."3.3" do
- it "raise FrozenError if the output buffer is frozen (2)" do
- @io.read
- -> { @io.read(1, ''.freeze) }.should raise_error(FrozenError)
- end
end
it "consumes zero bytes when reading zero bytes" do
@@ -608,7 +496,6 @@ describe :io_read_size_internal_encoding, shared: true do
it "returns a String in BINARY when passed a size" do
@io.read(4).encoding.should equal(Encoding::BINARY)
- @io.read(0).encoding.should equal(Encoding::BINARY)
end
it "does not change the buffer's encoding when passed a limit" do
diff --git a/spec/ruby/core/io/readline_spec.rb b/spec/ruby/core/io/readline_spec.rb
index a814c1be90..cf9f0dfc11 100644
--- a/spec/ruby/core/io/readline_spec.rb
+++ b/spec/ruby/core/io/readline_spec.rb
@@ -73,12 +73,14 @@ describe "IO#readline" do
@io.readline(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
end
- it "raises exception when options passed as Hash" do
- -> { @io.readline({ chomp: true }) }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises exception when options passed as Hash" do
+ -> { @io.readline({ chomp: true }) }.should raise_error(TypeError)
- -> {
- @io.readline("\n", 1, { chomp: true })
- }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ -> {
+ @io.readline("\n", 1, { chomp: true })
+ }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ end
end
end
end
diff --git a/spec/ruby/core/io/readlines_spec.rb b/spec/ruby/core/io/readlines_spec.rb
index 3a6ff3d0f3..496003002d 100644
--- a/spec/ruby/core/io/readlines_spec.rb
+++ b/spec/ruby/core/io/readlines_spec.rb
@@ -117,18 +117,14 @@ describe "IO#readlines" do
@io.readlines(chomp: true).should == IOSpecs.lines_without_newline_characters
end
- it "raises exception when options passed as Hash" do
- -> { @io.readlines({ chomp: true }) }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises exception when options passed as Hash" do
+ -> { @io.readlines({ chomp: true }) }.should raise_error(TypeError)
- -> {
- @io.readlines("\n", 1, { chomp: true })
- }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
- end
- end
-
- describe "when passed arbitrary keyword argument" do
- it "tolerates it" do
- @io.readlines(chomp: true, foo: :bar).should == IOSpecs.lines_without_newline_characters
+ -> {
+ @io.readlines("\n", 1, { chomp: true })
+ }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ end
end
end
end
@@ -180,20 +176,13 @@ describe "IO.readlines" do
platform_is :windows do
cmd = "|cmd.exe /C echo hello&echo line2"
end
-
- lines = nil
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- lines = IO.readlines(cmd)
- end
+ lines = IO.readlines(cmd)
lines.should == ["hello\n", "line2\n"]
end
platform_is_not :windows do
it "gets data from a fork when passed -" do
- lines = nil
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- lines = IO.readlines("|-")
- end
+ lines = IO.readlines("|-")
if lines # parent
lines.should == ["hello\n", "from a fork\n"]
@@ -206,16 +195,6 @@ describe "IO.readlines" do
end
end
- ruby_version_is "3.3" do
- # https://bugs.ruby-lang.org/issues/19630
- it "warns about deprecation given a path with a pipe" do
- cmd = "|echo ok"
- -> {
- IO.readlines(cmd)
- }.should complain(/IO process creation with a leading '\|'/)
- end
- end
-
it_behaves_like :io_readlines, :readlines
it_behaves_like :io_readlines_options_19, :readlines
end
diff --git a/spec/ruby/core/io/select_spec.rb b/spec/ruby/core/io/select_spec.rb
index 1e4e50a81b..4603c1fbbc 100644
--- a/spec/ruby/core/io/select_spec.rb
+++ b/spec/ruby/core/io/select_spec.rb
@@ -55,8 +55,8 @@ describe "IO.select" do
end
end
- it "returns supplied objects correctly when monitoring the same object in different arrays" do
- filename = tmp("IO_select_pipe_file")
+ it "returns supplied objects correctly even when monitoring the same object in different arrays" do
+ filename = tmp("IO_select_pipe_file") + $$.to_s
io = File.open(filename, 'w+')
result = IO.select [io], [io], nil, 0
result.should == [[io], [io], []]
@@ -64,17 +64,6 @@ describe "IO.select" do
rm_r filename
end
- it "returns the pipe read end in read set if the pipe write end is closed concurrently" do
- main = Thread.current
- t = Thread.new {
- Thread.pass until main.stop?
- @wr.close
- }
- IO.select([@rd]).should == [[@rd], [], []]
- ensure
- t.join
- end
-
it "invokes to_io on supplied objects that are not IO and returns the supplied objects" do
# make some data available
@wr.write("foobar")
diff --git a/spec/ruby/core/io/shared/binwrite.rb b/spec/ruby/core/io/shared/binwrite.rb
index e51093329b..3649bb47ff 100644
--- a/spec/ruby/core/io/shared/binwrite.rb
+++ b/spec/ruby/core/io/shared/binwrite.rb
@@ -21,14 +21,6 @@ describe :io_binwrite, shared: true do
IO.send(@method, @filename, "abcde").should == 5
end
- it "accepts options as a keyword argument" do
- IO.send(@method, @filename, "hi", 0, flags: File::CREAT).should == 2
-
- -> {
- IO.send(@method, @filename, "hi", 0, {flags: File::CREAT})
- }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 2..3)")
- end
-
it "creates a file if missing" do
fn = @filename + "xxx"
begin
@@ -75,11 +67,6 @@ describe :io_binwrite, shared: true do
File.read(@filename).should == "\0\0foo"
end
- it "accepts a :flags option without :mode one" do
- IO.send(@method, @filename, "hello, world!", flags: File::CREAT)
- File.read(@filename).should == "hello, world!"
- end
-
it "raises an error if readonly mode is specified" do
-> { IO.send(@method, @filename, "abcde", mode: "r") }.should raise_error(IOError)
end
diff --git a/spec/ruby/core/io/shared/each.rb b/spec/ruby/core/io/shared/each.rb
index aca622834f..02bbe19c1a 100644
--- a/spec/ruby/core/io/shared/each.rb
+++ b/spec/ruby/core/io/shared/each.rb
@@ -33,6 +33,10 @@ describe :io_each, shared: true do
$_.should == "test"
end
+ it "returns self" do
+ @io.send(@method) { |l| l }.should equal(@io)
+ end
+
it "raises an IOError when self is not readable" do
-> { IOSpecs.closed_io.send(@method) {} }.should raise_error(IOError)
end
@@ -176,14 +180,16 @@ describe :io_each, shared: true do
ScratchPad.recorded.should == IOSpecs.lines_without_newline_characters
end
- it "raises exception when options passed as Hash" do
- -> {
- @io.send(@method, { chomp: true }) { |s| }
- }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises exception when options passed as Hash" do
+ -> {
+ @io.send(@method, { chomp: true }) { |s| }
+ }.should raise_error(TypeError)
- -> {
- @io.send(@method, "\n", 1, { chomp: true }) { |s| }
- }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ -> {
+ @io.send(@method, "\n", 1, { chomp: true }) { |s| }
+ }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 0..2)")
+ end
end
end
diff --git a/spec/ruby/core/io/shared/new.rb b/spec/ruby/core/io/shared/new.rb
index cba5f33ebf..7677aada6e 100644
--- a/spec/ruby/core/io/shared/new.rb
+++ b/spec/ruby/core/io/shared/new.rb
@@ -1,6 +1,6 @@
require_relative '../fixtures/classes'
-# NOTE: should be synchronized with library/stringio/initialize_spec.rb
+# NOTE: should be syncronized with library/stringio/initialize_spec.rb
# This group of specs may ONLY contain specs that do successfully create
# an IO instance from the file descriptor returned by #new_fd helper.
@@ -64,15 +64,6 @@ describe :io_new, shared: true do
@io.should be_an_instance_of(IO)
end
- it "accepts options as keyword arguments" do
- @io = IO.send(@method, @fd, "w", flags: File::CREAT)
- @io.write("foo").should == 3
-
- -> {
- IO.send(@method, @fd, "w", {flags: File::CREAT})
- }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 1..2)")
- end
-
it "accepts a :mode option" do
@io = IO.send(@method, @fd, mode: "w")
@io.write("foo").should == 3
@@ -208,10 +199,21 @@ describe :io_new, shared: true do
@io.internal_encoding.to_s.should == 'IBM866'
end
- it "raises ArgumentError for nil options" do
- -> {
- IO.send(@method, @fd, 'w', nil)
- }.should raise_error(ArgumentError)
+ ruby_version_is ''...'3.0' do
+ it "accepts nil options" do
+ @io = suppress_keyword_warning do
+ IO.send(@method, @fd, 'w', nil)
+ end
+ @io.write("foo").should == 3
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "raises ArgumentError for nil options" do
+ -> {
+ IO.send(@method, @fd, 'w', nil)
+ }.should raise_error(ArgumentError)
+ end
end
it "coerces mode with #to_str" do
@@ -382,9 +384,21 @@ describe :io_new_errors, shared: true do
}.should raise_error(ArgumentError)
end
- it "raises ArgumentError if passed a hash for mode and nil for options" do
- -> {
- @io = IO.send(@method, @fd, {mode: 'w'}, nil)
- }.should raise_error(ArgumentError)
+ ruby_version_is ''...'3.0' do
+ it "raises TypeError if passed a hash for mode and nil for options" do
+ -> {
+ suppress_keyword_warning do
+ @io = IO.send(@method, @fd, {mode: 'w'}, nil)
+ end
+ }.should raise_error(TypeError)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "raises ArgumentError if passed a hash for mode and nil for options" do
+ -> {
+ @io = IO.send(@method, @fd, {mode: 'w'}, nil)
+ }.should raise_error(ArgumentError)
+ end
end
end
diff --git a/spec/ruby/core/io/shared/readlines.rb b/spec/ruby/core/io/shared/readlines.rb
index d2b604bba3..7681e1b5c1 100644
--- a/spec/ruby/core/io/shared/readlines.rb
+++ b/spec/ruby/core/io/shared/readlines.rb
@@ -105,10 +105,12 @@ describe :io_readlines_options_19, shared: true do
end
describe "when the object is an options Hash" do
- it "raises TypeError exception" do
- -> {
- IO.send(@method, @name, { chomp: true }, &@object)
- }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises TypeError exception" do
+ -> {
+ IO.send(@method, @name, { chomp: true }, &@object)
+ }.should raise_error(TypeError)
+ end
end
end
@@ -177,10 +179,12 @@ describe :io_readlines_options_19, shared: true do
end
describe "when the second object is an options Hash" do
- it "raises TypeError exception" do
- -> {
- IO.send(@method, @name, "", { chomp: true }, &@object)
- }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises TypeError exception" do
+ -> {
+ IO.send(@method, @name, "", { chomp: true }, &@object)
+ }.should raise_error(TypeError)
+ end
end
end
end
diff --git a/spec/ruby/core/io/shared/write.rb b/spec/ruby/core/io/shared/write.rb
index 964064746a..9503f94212 100644
--- a/spec/ruby/core/io/shared/write.rb
+++ b/spec/ruby/core/io/shared/write.rb
@@ -85,11 +85,11 @@ describe :io_write, shared: true do
@r.read.should == "foo"
end
- # [ruby-core:90895] RJIT worker may leave fd open in a forked child.
- # For instance, RJIT creates a worker before @r.close with fork(), @r.close happens,
- # and the RJIT worker keeps the pipe open until the worker execve().
- # TODO: consider acquiring GVL from RJIT worker.
- guard_not -> { defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? } do
+ # [ruby-core:90895] MJIT worker may leave fd open in a forked child.
+ # For instance, MJIT creates a worker before @r.close with fork(), @r.close happens,
+ # and the MJIT worker keeps the pipe open until the worker execve().
+ # TODO: consider acquiring GVL from MJIT worker.
+ guard_not -> { defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? } do
it "raises Errno::EPIPE if the read end is closed and does not die from SIGPIPE" do
@r.close
-> { @w.send(@method, "foo") }.should raise_error(Errno::EPIPE, /Broken pipe/)
@@ -97,58 +97,3 @@ describe :io_write, shared: true do
end
end
end
-
-describe :io_write_transcode, shared: true do
- before :each do
- @transcode_filename = tmp("io_write_transcode")
- end
-
- after :each do
- rm_r @transcode_filename
- end
-
- it "transcodes the given string when the external encoding is set and neither is BINARY" do
- utf8_str = "hello"
-
- File.open(@transcode_filename, "w", external_encoding: Encoding::UTF_16BE) do |file|
- file.external_encoding.should == Encoding::UTF_16BE
- file.send(@method, utf8_str)
- end
-
- result = File.binread(@transcode_filename)
- expected = [0, 104, 0, 101, 0, 108, 0, 108, 0, 111] # UTF-16BE bytes for "hello"
-
- result.bytes.should == expected
- end
-
- it "transcodes the given string when the external encoding is set and the string encoding is BINARY" do
- str = "été".b
-
- File.open(@transcode_filename, "w", external_encoding: Encoding::UTF_16BE) do |file|
- file.external_encoding.should == Encoding::UTF_16BE
- -> { file.send(@method, str) }.should raise_error(Encoding::UndefinedConversionError)
- end
- end
-end
-
-describe :io_write_no_transcode, shared: true do
- before :each do
- @transcode_filename = tmp("io_write_no_transcode")
- end
-
- after :each do
- rm_r @transcode_filename
- end
-
- it "does not transcode the given string even when the external encoding is set" do
- utf8_str = "hello"
-
- File.open(@transcode_filename, "w", external_encoding: Encoding::UTF_16BE) do |file|
- file.external_encoding.should == Encoding::UTF_16BE
- file.send(@method, utf8_str)
- end
-
- result = File.binread(@transcode_filename)
- result.bytes.should == utf8_str.bytes
- end
-end
diff --git a/spec/ruby/core/io/syswrite_spec.rb b/spec/ruby/core/io/syswrite_spec.rb
index 8bf61a27c3..eeb8d302a7 100644
--- a/spec/ruby/core/io/syswrite_spec.rb
+++ b/spec/ruby/core/io/syswrite_spec.rb
@@ -78,5 +78,4 @@ end
describe "IO#syswrite" do
it_behaves_like :io_write, :syswrite
- it_behaves_like :io_write_no_transcode, :syswrite
end
diff --git a/spec/ruby/core/io/try_convert_spec.rb b/spec/ruby/core/io/try_convert_spec.rb
index a9e99de7aa..5fbd10b6fa 100644
--- a/spec/ruby/core/io/try_convert_spec.rb
+++ b/spec/ruby/core/io/try_convert_spec.rb
@@ -38,7 +38,7 @@ describe "IO.try_convert" do
it "raises a TypeError if the object does not return an IO from #to_io" do
obj = mock("io")
obj.should_receive(:to_io).and_return("io")
- -> { IO.try_convert(obj) }.should raise_error(TypeError, "can't convert MockObject to IO (MockObject#to_io gives String)")
+ -> { IO.try_convert(obj) }.should raise_error(TypeError)
end
it "propagates an exception raised by #to_io" do
diff --git a/spec/ruby/core/io/ungetc_spec.rb b/spec/ruby/core/io/ungetc_spec.rb
index 47a4e99ebf..41a455c836 100644
--- a/spec/ruby/core/io/ungetc_spec.rb
+++ b/spec/ruby/core/io/ungetc_spec.rb
@@ -103,9 +103,19 @@ describe "IO#ungetc" do
-> { @io.sysread(1) }.should raise_error(IOError)
end
- it "raises TypeError if passed nil" do
- @io.getc.should == ?V
- proc{@io.ungetc(nil)}.should raise_error(TypeError)
+ ruby_version_is ""..."3.0" do
+ it "does not affect the stream and returns nil when passed nil" do
+ @io.getc.should == ?V
+ @io.ungetc(nil)
+ @io.getc.should == ?o
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "raises TypeError if passed nil" do
+ @io.getc.should == ?V
+ proc{@io.ungetc(nil)}.should raise_error(TypeError)
+ end
end
it "puts one or more characters back in the stream" do
diff --git a/spec/ruby/core/io/write_nonblock_spec.rb b/spec/ruby/core/io/write_nonblock_spec.rb
index c403c864fd..5532556d8a 100644
--- a/spec/ruby/core/io/write_nonblock_spec.rb
+++ b/spec/ruby/core/io/write_nonblock_spec.rb
@@ -50,7 +50,6 @@ platform_is_not :windows do
describe "IO#write_nonblock" do
it_behaves_like :io_write, :write_nonblock
- it_behaves_like :io_write_no_transcode, :write_nonblock
end
end
diff --git a/spec/ruby/core/io/write_spec.rb b/spec/ruby/core/io/write_spec.rb
index 4a26f8dbaf..bcc0582d9e 100644
--- a/spec/ruby/core/io/write_spec.rb
+++ b/spec/ruby/core/io/write_spec.rb
@@ -24,6 +24,10 @@ describe "IO#write on a file" do
-> { @readonly_file.write("") }.should_not raise_error
end
+ it "returns a length of 0 when writing a blank string" do
+ @file.write('').should == 0
+ end
+
before :each do
@external = Encoding.default_external
@internal = Encoding.default_internal
@@ -36,18 +40,6 @@ describe "IO#write on a file" do
Encoding.default_internal = @internal
end
- it "returns a length of 0 when writing a blank string" do
- @file.write('').should == 0
- end
-
- it "returns a length of 0 when writing blank strings" do
- @file.write('', '', '').should == 0
- end
-
- it "returns a length of 0 when passed no arguments" do
- @file.write().should == 0
- end
-
it "returns the number of bytes written" do
@file.write("hellø").should == 6
end
@@ -62,18 +54,6 @@ describe "IO#write on a file" do
File.binread(@filename).bytes.should == [159]
end
- it "does not modify arguments when passed multiple arguments and external encoding not set" do
- a, b = "a".freeze, "b".freeze
-
- File.open(@filename, "w") do |f|
- f.write(a, b)
- end
-
- File.binread(@filename).bytes.should == [97, 98]
- a.encoding.should == Encoding::UTF_8
- b.encoding.should == Encoding::UTF_8
- end
-
it "uses the encoding from the given option for non-ascii encoding" do
File.open(@filename, "w", encoding: Encoding::UTF_32LE) do |file|
file.write("hi").should == 8
@@ -81,25 +61,8 @@ describe "IO#write on a file" do
File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000"
end
- it "uses the encoding from the given option for non-ascii encoding even if in binary mode" do
- File.open(@filename, "w", encoding: Encoding::UTF_32LE, binmode: true) do |file|
- file.should.binmode?
- file.write("hi").should == 8
- end
- File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000"
-
- File.open(@filename, "wb", encoding: Encoding::UTF_32LE) do |file|
- file.should.binmode?
- file.write("hi").should == 8
- end
- File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000"
- end
-
- it "uses the encoding from the given option for non-ascii encoding when multiple arguments passes" do
- File.open(@filename, "w", encoding: Encoding::UTF_32LE) do |file|
- file.write("h", "i").should == 8
- end
- File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000"
+ it "uses an :open_args option" do
+ IO.write(@filename, 'hi', open_args: ["w", nil, {encoding: Encoding::UTF_32LE}]).should == 8
end
it "raises a invalid byte sequence error if invalid bytes are being written" do
@@ -119,20 +82,6 @@ describe "IO#write on a file" do
res = "H#{ë}ll#{ö}"
File.binread(@filename).should == res.force_encoding(Encoding::BINARY)
end
-
- platform_is_not :windows do
- it "writes binary data if no encoding is given and multiple arguments passed" do
- File.open(@filename, "w") do |file|
- file.write("\x87".b, "Ä…") # 0x87 isn't a valid UTF-8 binary representation of a character
- end
- File.binread(@filename).bytes.should == [0x87, 0xC4, 0x85]
-
- File.open(@filename, "w") do |file|
- file.write("\x61".encode("utf-32le"), "Ä…")
- end
- File.binread(@filename).bytes.should == [0x61, 0x00, 0x00, 0x00, 0xC4, 0x85]
- end
- end
end
describe "IO.write" do
@@ -147,38 +96,10 @@ describe "IO.write" do
File.read(@filename).should == "\0\0hi"
end
- it "requires mode to be specified in :open_args" do
- -> {
- IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true}])
- }.should raise_error(IOError, "not opened for writing")
-
- IO.write(@filename, 'hi', open_args: ["w", {encoding: Encoding::UTF_32LE, binmode: true}]).should == 8
- IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true, mode: "w"}]).should == 8
- end
-
- it "requires mode to be specified in :open_args even if flags option passed" do
- -> {
- IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true, flags: File::CREAT}])
- }.should raise_error(IOError, "not opened for writing")
-
- IO.write(@filename, 'hi', open_args: ["w", {encoding: Encoding::UTF_32LE, binmode: true, flags: File::CREAT}]).should == 8
- IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true, flags: File::CREAT, mode: "w"}]).should == 8
- end
-
it "uses the given encoding and returns the number of bytes written" do
IO.write(@filename, 'hi', mode: "w", encoding: Encoding::UTF_32LE).should == 8
end
- it "raises ArgumentError if encoding is specified in mode parameter and is given as :encoding option" do
- -> {
- IO.write(@filename, 'hi', mode: "w:UTF-16LE:UTF-16BE", encoding: Encoding::UTF_32LE)
- }.should raise_error(ArgumentError, "encoding specified twice")
-
- -> {
- IO.write(@filename, 'hi', mode: "w:UTF-16BE", encoding: Encoding::UTF_32LE)
- }.should raise_error(ArgumentError, "encoding specified twice")
- end
-
it "writes the file with the permissions in the :perm parameter" do
rm_r @filename
IO.write(@filename, 'write :perm spec', mode: "w", perm: 0o755).should == 16
@@ -203,31 +124,16 @@ describe "IO.write" do
rm_r @fifo
end
- # rb_cloexec_open() is currently missing a retry on EINTR.
- # @ioquatix is looking into fixing it. Quarantined until it's done.
- quarantine! do
- it "writes correctly" do
- thr = Thread.new do
- IO.read(@fifo)
- end
- begin
- string = "hi"
- IO.write(@fifo, string).should == string.length
- ensure
- thr.join
- end
+ it "writes correctly" do
+ thr = Thread.new do
+ IO.read(@fifo)
+ end
+ begin
+ string = "hi"
+ IO.write(@fifo, string).should == string.length
+ ensure
+ thr.join
end
- end
- end
-
- ruby_version_is "3.3" do
- # https://bugs.ruby-lang.org/issues/19630
- it "warns about deprecation given a path with a pipe" do
- -> {
- -> {
- IO.write("|cat", "xxx")
- }.should output_to_fd("xxx")
- }.should complain(/IO process creation with a leading '\|'/)
end
end
end
@@ -235,7 +141,6 @@ end
describe "IO#write" do
it_behaves_like :io_write, :write
- it_behaves_like :io_write_transcode, :write
it "accepts multiple arguments" do
IO.pipe do |r, w|
@@ -274,23 +179,25 @@ platform_is :windows do
end
end
-describe "IO#write on STDOUT" do
- # https://bugs.ruby-lang.org/issues/14413
- platform_is_not :windows do
- it "raises SignalException SIGPIPE if the stream is closed instead of Errno::EPIPE like other IOs" do
- stderr_file = tmp("stderr")
- begin
- IO.popen([*ruby_exe, "-e", "loop { puts :ok }"], "r", err: stderr_file) do |io|
- io.gets.should == "ok\n"
- io.close
+ruby_version_is "3.0" do
+ describe "IO#write on STDOUT" do
+ # https://bugs.ruby-lang.org/issues/14413
+ platform_is_not :windows do
+ it "raises SignalException SIGPIPE if the stream is closed instead of Errno::EPIPE like other IOs" do
+ stderr_file = tmp("stderr")
+ begin
+ IO.popen([*ruby_exe, "-e", "loop { puts :ok }"], "r", err: stderr_file) do |io|
+ io.gets.should == "ok\n"
+ io.close
+ end
+ status = $?
+ status.should_not.success?
+ status.should.signaled?
+ Signal.signame(status.termsig).should == 'PIPE'
+ File.read(stderr_file).should.empty?
+ ensure
+ rm_r stderr_file
end
- status = $?
- status.should_not.success?
- status.should.signaled?
- Signal.signame(status.termsig).should == 'PIPE'
- File.read(stderr_file).should.empty?
- ensure
- rm_r stderr_file
end
end
end
diff --git a/spec/ruby/core/kernel/Complex_spec.rb b/spec/ruby/core/kernel/Complex_spec.rb
index 346d50ab5e..cc8177fa02 100644
--- a/spec/ruby/core/kernel/Complex_spec.rb
+++ b/spec/ruby/core/kernel/Complex_spec.rb
@@ -269,8 +269,4 @@ describe "Kernel.Complex()" do
end
end
end
-
- it "freezes its result" do
- Complex(1).frozen?.should == true
- end
end
diff --git a/spec/ruby/core/kernel/Integer_spec.rb b/spec/ruby/core/kernel/Integer_spec.rb
index 74dd3e0dd2..2c78e27428 100644
--- a/spec/ruby/core/kernel/Integer_spec.rb
+++ b/spec/ruby/core/kernel/Integer_spec.rb
@@ -145,7 +145,7 @@ describe :kernel_integer, shared: true do
end
end
-describe :kernel_integer_string, shared: true do
+describe "Integer() given a String", shared: true do
it "raises an ArgumentError if the String is a null byte" do
-> { Integer("\0") }.should raise_error(ArgumentError)
end
@@ -348,7 +348,7 @@ describe :kernel_integer_string, shared: true do
end
end
-describe :kernel_integer_string_base, shared: true do
+describe "Integer() given a String and base", shared: true do
it "raises an ArgumentError if the String is a null byte" do
-> { Integer("\0", 2) }.should raise_error(ArgumentError)
end
@@ -573,31 +573,9 @@ describe :kernel_integer_string_base, shared: true do
-> { Integer("0#{d}1", base) }.should raise_error(ArgumentError)
end
end
- end
-
- it "raises an ArgumentError if a base is given for a non-String value" do
- -> { Integer(98, 15) }.should raise_error(ArgumentError)
- end
-
- it "tries to convert the base to an integer using to_int" do
- obj = mock('8')
- obj.should_receive(:to_int).and_return(8)
-
- Integer("777", obj).should == 0777
- end
-
- # https://bugs.ruby-lang.org/issues/19349
- ruby_version_is ''...'3.3' do
- it "ignores the base if it is not an integer and does not respond to #to_i" do
- Integer("777", "8").should == 777
- end
- end
- ruby_version_is '3.3' do
- it "raises a TypeError if it is not an integer and does not respond to #to_i" do
- -> {
- Integer("777", "8")
- }.should raise_error(TypeError, "no implicit conversion of String into Integer")
+ it "raises an ArgumentError if a base is given for a non-String value" do
+ -> { Integer(98, 15) }.should raise_error(ArgumentError)
end
end
@@ -799,9 +777,9 @@ describe "Kernel.Integer" do
# TODO: fix these specs
it_behaves_like :kernel_integer, :Integer, Kernel
- it_behaves_like :kernel_integer_string, :Integer
+ it_behaves_like "Integer() given a String", :Integer
- it_behaves_like :kernel_integer_string_base, :Integer
+ it_behaves_like "Integer() given a String and base", :Integer
it "is a public method" do
Kernel.Integer(10).should == 10
@@ -813,9 +791,9 @@ describe "Kernel#Integer" do
# TODO: fix these specs
it_behaves_like :kernel_integer, :Integer, Object.new
- it_behaves_like :kernel_integer_string, :Integer
+ it_behaves_like "Integer() given a String", :Integer
- it_behaves_like :kernel_integer_string_base, :Integer
+ it_behaves_like "Integer() given a String and base", :Integer
it "is a private method" do
Kernel.should have_private_instance_method(:Integer)
diff --git a/spec/ruby/core/kernel/__dir___spec.rb b/spec/ruby/core/kernel/__dir___spec.rb
index 242adbf48b..324792a408 100644
--- a/spec/ruby/core/kernel/__dir___spec.rb
+++ b/spec/ruby/core/kernel/__dir___spec.rb
@@ -19,9 +19,19 @@ describe "Kernel#__dir__" do
end
end
- context "when used in eval with top level binding" do
- it "returns nil" do
- eval("__dir__", binding).should == nil
+ ruby_version_is ""..."3.0" do
+ context "when used in eval with top level binding" do
+ it "returns the real name of the directory containing the currently-executing file" do
+ eval("__dir__", binding).should == File.realpath(File.dirname(__FILE__))
+ end
+ end
+ end
+
+ ruby_version_is "3.0" do
+ context "when used in eval with top level binding" do
+ it "returns nil" do
+ eval("__dir__", binding).should == nil
+ end
end
end
end
diff --git a/spec/ruby/core/kernel/at_exit_spec.rb b/spec/ruby/core/kernel/at_exit_spec.rb
index ebd9a71d15..a784c1ae17 100644
--- a/spec/ruby/core/kernel/at_exit_spec.rb
+++ b/spec/ruby/core/kernel/at_exit_spec.rb
@@ -1,16 +1,67 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative '../../shared/kernel/at_exit'
describe "Kernel.at_exit" do
- it_behaves_like :kernel_at_exit, :at_exit
-
it "is a private method" do
Kernel.should have_private_instance_method(:at_exit)
end
- it "raises ArgumentError if called without a block" do
- -> { at_exit }.should raise_error(ArgumentError, "called without a block")
+ it "runs after all other code" do
+ ruby_exe("at_exit {print 5}; print 6").should == "65"
+ end
+
+ it "runs in reverse order of registration" do
+ code = "at_exit {print 4};at_exit {print 5}; print 6; at_exit {print 7}"
+ ruby_exe(code).should == "6754"
+ end
+
+ it "allows calling exit inside at_exit handler" do
+ code = "at_exit {print 3}; at_exit {print 4; exit; print 5}; at_exit {print 6}"
+ ruby_exe(code).should == "643"
+ end
+
+ it "gives access to the last raised exception" do
+ code = <<-EOC
+ at_exit do
+ puts "The exception matches: \#{$! == $exception} (message=\#{$!.message})"
+ end
+
+ begin
+ raise "foo"
+ rescue => $exception
+ raise
+ end
+ EOC
+
+ result = ruby_exe(code, args: "2>&1", exit_status: 1)
+ result.lines.should.include?("The exception matches: true (message=foo)\n")
+ end
+
+ it "both exceptions in at_exit and in the main script are printed" do
+ code = 'at_exit { raise "at_exit_error" }; raise "main_script_error"'
+ result = ruby_exe(code, args: "2>&1", exit_status: 1)
+ result.should.include?('at_exit_error (RuntimeError)')
+ result.should.include?('main_script_error (RuntimeError)')
+ end
+
+ it "decides the exit status if both at_exit and the main script raise SystemExit" do
+ ruby_exe('at_exit { exit 43 }; exit 42', args: "2>&1", exit_status: 43)
+ $?.exitstatus.should == 43
+ end
+
+ it "runs all at_exit even if some raise exceptions" do
+ code = 'at_exit { STDERR.puts "last" }; at_exit { exit 43 }; at_exit { STDERR.puts "first" }; exit 42'
+ result = ruby_exe(code, args: "2>&1", exit_status: 43)
+ result.should == "first\nlast\n"
+ $?.exitstatus.should == 43
+ end
+
+ it "runs at_exit handlers even if the main script fails to parse" do
+ script = fixture(__FILE__, "at_exit.rb")
+ result = ruby_exe('{', options: "-r#{script}", args: "2>&1", exit_status: 1)
+ $?.should_not.success?
+ result.should.include?("at_exit ran\n")
+ result.should.include?("syntax error")
end
end
diff --git a/spec/ruby/core/kernel/clone_spec.rb b/spec/ruby/core/kernel/clone_spec.rb
index 5adcbbe603..a87c7544fe 100644
--- a/spec/ruby/core/kernel/clone_spec.rb
+++ b/spec/ruby/core/kernel/clone_spec.rb
@@ -45,18 +45,26 @@ describe "Kernel#clone" do
end
describe "with freeze: nil" do
- it "copies frozen state from the original, like #clone without arguments" do
- o2 = @obj.clone(freeze: nil)
- o2.should_not.frozen?
-
- @obj.freeze
- o3 = @obj.clone(freeze: nil)
- o3.should.frozen?
+ ruby_version_is ""..."3.0" do
+ it "raises ArgumentError" do
+ -> { @obj.clone(freeze: nil) }.should raise_error(ArgumentError, /unexpected value for freeze: NilClass/)
+ end
end
- it "copies frozen?" do
- o = "".freeze.clone(freeze: nil)
- o.frozen?.should be_true
+ ruby_version_is "3.0" do
+ it "copies frozen state from the original, like #clone without arguments" do
+ o2 = @obj.clone(freeze: nil)
+ o2.should_not.frozen?
+
+ @obj.freeze
+ o3 = @obj.clone(freeze: nil)
+ o3.should.frozen?
+ end
+
+ it "copies frozen?" do
+ o = "".freeze.clone(freeze: nil)
+ o.frozen?.should be_true
+ end
end
end
@@ -66,19 +74,33 @@ describe "Kernel#clone" do
@obj.clone(freeze: true).should.frozen?
end
- it 'freezes the copy even if the original was not frozen' do
- @obj.clone(freeze: true).should.frozen?
- end
+ ruby_version_is ''...'3.0' do
+ it 'does not freeze the copy even if the original is not frozen' do
+ @obj.clone(freeze: true).should_not.frozen?
+ end
- it "calls #initialize_clone with kwargs freeze: true" do
- obj = KernelSpecs::CloneFreeze.new
- obj.clone(freeze: true)
- ScratchPad.recorded.should == [obj, { freeze: true }]
+ it "calls #initialize_clone with no kwargs" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: true)
+ ScratchPad.recorded.should == [obj, {}]
+ end
end
- it "calls #initialize_clone with kwargs freeze: true even if #initialize_clone only takes a single argument" do
- obj = KernelSpecs::Clone.new
- -> { obj.clone(freeze: true) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
+ ruby_version_is '3.0' do
+ it 'freezes the copy even if the original was not frozen' do
+ @obj.clone(freeze: true).should.frozen?
+ end
+
+ it "calls #initialize_clone with kwargs freeze: true" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: true)
+ ScratchPad.recorded.should == [obj, { freeze: true }]
+ end
+
+ it "calls #initialize_clone with kwargs freeze: true even if #initialize_clone only takes a single argument" do
+ obj = KernelSpecs::Clone.new
+ -> { obj.clone(freeze: true) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
+ end
end
end
@@ -92,15 +114,25 @@ describe "Kernel#clone" do
@obj.clone(freeze: false).should_not.frozen?
end
- it "calls #initialize_clone with kwargs freeze: false" do
- obj = KernelSpecs::CloneFreeze.new
- obj.clone(freeze: false)
- ScratchPad.recorded.should == [obj, { freeze: false }]
+ ruby_version_is ''...'3.0' do
+ it "calls #initialize_clone with no kwargs" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: false)
+ ScratchPad.recorded.should == [obj, {}]
+ end
end
- it "calls #initialize_clone with kwargs freeze: false even if #initialize_clone only takes a single argument" do
- obj = KernelSpecs::Clone.new
- -> { obj.clone(freeze: false) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
+ ruby_version_is '3.0' do
+ it "calls #initialize_clone with kwargs freeze: false" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: false)
+ ScratchPad.recorded.should == [obj, { freeze: false }]
+ end
+
+ it "calls #initialize_clone with kwargs freeze: false even if #initialize_clone only takes a single argument" do
+ obj = KernelSpecs::Clone.new
+ -> { obj.clone(freeze: false) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
+ end
end
end
diff --git a/spec/ruby/core/kernel/define_singleton_method_spec.rb b/spec/ruby/core/kernel/define_singleton_method_spec.rb
index 24acec84f5..2d8b1bf413 100644
--- a/spec/ruby/core/kernel/define_singleton_method_spec.rb
+++ b/spec/ruby/core/kernel/define_singleton_method_spec.rb
@@ -111,10 +111,4 @@ describe "Kernel#define_singleton_method" do
cls.foo.should == :ok
}.should_not raise_error(NoMethodError)
end
-
- it "cannot define a singleton method with a frozen singleton class" do
- o = Object.new
- o.freeze
- -> { o.define_singleton_method(:foo) { 1 } }.should raise_error(FrozenError)
- end
end
diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb
index 3dfc863368..9be0f2dfd3 100644
--- a/spec/ruby/core/kernel/eval_spec.rb
+++ b/spec/ruby/core/kernel/eval_spec.rb
@@ -159,7 +159,24 @@ describe "Kernel#eval" do
end
end
- ruby_version_is ""..."3.3" do
+ ruby_version_is ""..."3.0" do
+ it "uses the filename of the binding if none is provided" do
+ eval("__FILE__").should == "(eval)"
+ suppress_warning {eval("__FILE__", binding)}.should == __FILE__
+ eval("__FILE__", binding, "success").should == "success"
+ suppress_warning {eval("eval '__FILE__', binding")}.should == "(eval)"
+ suppress_warning {eval("eval '__FILE__', binding", binding)}.should == __FILE__
+ suppress_warning {eval("eval '__FILE__', binding", binding, 'success')}.should == 'success'
+ end
+
+ it 'uses the given binding file and line for __FILE__ and __LINE__' do
+ suppress_warning {
+ eval("[__FILE__, __LINE__]", binding).should == [__FILE__, __LINE__]
+ }
+ end
+ end
+
+ ruby_version_is "3.0" do
it "uses (eval) filename if none is provided" do
eval("__FILE__").should == "(eval)"
eval("__FILE__", binding).should == "(eval)"
@@ -175,21 +192,6 @@ describe "Kernel#eval" do
end
end
- ruby_version_is "3.3" do
- it "uses (eval at __FILE__:__LINE__) if none is provided" do
- eval("__FILE__").should == "(eval at #{__FILE__}:#{__LINE__})"
- eval("__FILE__", binding).should == "(eval at #{__FILE__}:#{__LINE__})"
- eval("__FILE__", binding, "success").should == "success"
- eval("eval '__FILE__', binding").should == "(eval at (eval at #{__FILE__}:#{__LINE__}):1)"
- eval("eval '__FILE__', binding", binding).should == "(eval at (eval at #{__FILE__}:#{__LINE__}):1)"
- eval("eval '__FILE__', binding", binding, 'success').should == "(eval at success:1)"
- eval("eval '__FILE__', binding, 'success'", binding).should == 'success'
- end
-
- it 'uses (eval at __FILE__:__LINE__) for __FILE__ and 1 for __LINE__ with a binding argument' do
- eval("[__FILE__, __LINE__]", binding).should == ["(eval at #{__FILE__}:#{__LINE__})", 1]
- end
- end
# Found via Rubinius bug github:#149
it "does not alter the value of __FILE__ in the binding" do
first_time = EvalSpecs.call_eval
@@ -226,20 +228,6 @@ describe "Kernel#eval" do
-> { eval("return :eval") }.call.should == :eval
end
- it "returns from the method calling #eval when evaluating 'return'" do
- def eval_return(n)
- eval("return n*2")
- end
- -> { eval_return(3) }.call.should == 6
- end
-
- it "returns from the method calling #eval when evaluating 'return' in BEGIN" do
- def eval_return(n)
- eval("BEGIN {return n*3}")
- end
- -> { eval_return(4) }.call.should == 12
- end
-
it "unwinds through a Proc-style closure and returns from a lambda-style closure in the closure chain" do
code = fixture __FILE__, "eval_return_with_lambda.rb"
ruby_exe(code).chomp.should == "a,b,c,eval,f"
diff --git a/spec/ruby/core/kernel/exec_spec.rb b/spec/ruby/core/kernel/exec_spec.rb
index 3d9520ad67..1b4a7ae6f4 100644
--- a/spec/ruby/core/kernel/exec_spec.rb
+++ b/spec/ruby/core/kernel/exec_spec.rb
@@ -7,12 +7,12 @@ describe "Kernel#exec" do
end
it "runs the specified command, replacing current process" do
- ruby_exe('exec "echo hello"; puts "fail"').should == "hello\n"
+ ruby_exe('exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
end
end
describe "Kernel.exec" do
it "runs the specified command, replacing current process" do
- ruby_exe('Kernel.exec "echo hello"; puts "fail"').should == "hello\n"
+ ruby_exe('Kernel.exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
end
end
diff --git a/spec/ruby/core/kernel/exit_spec.rb b/spec/ruby/core/kernel/exit_spec.rb
index 93cec3fee5..f168cb375e 100644
--- a/spec/ruby/core/kernel/exit_spec.rb
+++ b/spec/ruby/core/kernel/exit_spec.rb
@@ -10,10 +10,6 @@ describe "Kernel#exit" do
it_behaves_like :process_exit, :exit, KernelSpecs::Method.new
end
-describe "Kernel.exit" do
- it_behaves_like :process_exit, :exit, Kernel
-end
-
describe "Kernel#exit!" do
it "is a private method" do
Kernel.should have_private_instance_method(:exit!)
@@ -22,6 +18,10 @@ describe "Kernel#exit!" do
it_behaves_like :process_exit!, :exit!, "self"
end
+describe "Kernel.exit" do
+ it_behaves_like :process_exit, :exit, Kernel
+end
+
describe "Kernel.exit!" do
- it_behaves_like :process_exit!, :exit!, "Kernel"
+ it_behaves_like :process_exit!, :exit!, Kernel
end
diff --git a/spec/ruby/core/kernel/fixtures/at_exit.rb b/spec/ruby/core/kernel/fixtures/at_exit.rb
new file mode 100644
index 0000000000..9c11a7ad6c
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/at_exit.rb
@@ -0,0 +1,3 @@
+at_exit do
+ STDERR.puts "at_exit ran"
+end
diff --git a/spec/ruby/core/kernel/initialize_clone_spec.rb b/spec/ruby/core/kernel/initialize_clone_spec.rb
index 21a90c19f0..2d889f5aad 100644
--- a/spec/ruby/core/kernel/initialize_clone_spec.rb
+++ b/spec/ruby/core/kernel/initialize_clone_spec.rb
@@ -18,9 +18,11 @@ describe "Kernel#initialize_clone" do
a.send(:initialize_clone, b)
end
- it "accepts a :freeze keyword argument for obj.clone(freeze: value)" do
- a = Object.new
- b = Object.new
- a.send(:initialize_clone, b, freeze: true).should == a
+ ruby_version_is "3.0" do
+ it "accepts a :freeze keyword argument for obj.clone(freeze: value)" do
+ a = Object.new
+ b = Object.new
+ a.send(:initialize_clone, b, freeze: true).should == a
+ end
end
end
diff --git a/spec/ruby/core/kernel/initialize_copy_spec.rb b/spec/ruby/core/kernel/initialize_copy_spec.rb
index d71ca9f60f..fe08d184ad 100644
--- a/spec/ruby/core/kernel/initialize_copy_spec.rb
+++ b/spec/ruby/core/kernel/initialize_copy_spec.rb
@@ -1,18 +1,11 @@
require_relative '../../spec_helper'
describe "Kernel#initialize_copy" do
- it "returns self" do
- obj = Object.new
- obj.send(:initialize_copy, obj).should.equal?(obj)
- end
-
it "does nothing if the argument is the same as the receiver" do
obj = Object.new
obj.send(:initialize_copy, obj).should.equal?(obj)
-
- obj = Object.new.freeze
+ obj.freeze
obj.send(:initialize_copy, obj).should.equal?(obj)
-
1.send(:initialize_copy, 1).should.equal?(1)
end
diff --git a/spec/ruby/core/kernel/iterator_spec.rb b/spec/ruby/core/kernel/iterator_spec.rb
new file mode 100644
index 0000000000..3fe8317f26
--- /dev/null
+++ b/spec/ruby/core/kernel/iterator_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is ""..."3.0" do
+ describe "Kernel#iterator?" do
+ it "is a private method" do
+ Kernel.should have_private_instance_method(:iterator?)
+ end
+ end
+
+ describe "Kernel.iterator?" do
+ it "needs to be reviewed for spec completeness"
+ end
+end
diff --git a/spec/ruby/core/kernel/lambda_spec.rb b/spec/ruby/core/kernel/lambda_spec.rb
index 565536ac0d..2aa4d4f2fb 100644
--- a/spec/ruby/core/kernel/lambda_spec.rb
+++ b/spec/ruby/core/kernel/lambda_spec.rb
@@ -26,44 +26,42 @@ describe "Kernel.lambda" do
l.lambda?.should be_true
end
- ruby_version_is ""..."3.3" do
- it "creates a lambda-style Proc if given a literal block via Kernel.public_send" do
- suppress_warning do
- l = Kernel.public_send(:lambda) { 42 }
- l.lambda?.should be_true
- end
+ it "creates a lambda-style Proc if given a literal block via Kernel.public_send" do
+ suppress_warning do
+ l = Kernel.public_send(:lambda) { 42 }
+ l.lambda?.should be_true
end
+ end
- it "returns the passed Proc if given an existing Proc" do
- some_proc = proc {}
- l = suppress_warning {lambda(&some_proc)}
- l.should equal(some_proc)
- l.lambda?.should be_false
- end
+ it "returns the passed Proc if given an existing Proc" do
+ some_proc = proc {}
+ l = suppress_warning {lambda(&some_proc)}
+ l.should equal(some_proc)
+ l.lambda?.should be_false
+ end
- it "creates a lambda-style Proc when called with zsuper" do
- suppress_warning do
- l = KernelSpecs::LambdaSpecs::ForwardBlockWithZSuper.new.lambda { 42 }
- l.lambda?.should be_true
- l.call.should == 42
+ it "creates a lambda-style Proc when called with zsuper" do
+ suppress_warning do
+ l = KernelSpecs::LambdaSpecs::ForwardBlockWithZSuper.new.lambda { 42 }
+ l.lambda?.should be_true
+ l.call.should == 42
- lambda { l.call(:extra) }.should raise_error(ArgumentError)
- end
+ lambda { l.call(:extra) }.should raise_error(ArgumentError)
end
+ end
- it "returns the passed Proc if given an existing Proc through super" do
- some_proc = proc { }
- l = KernelSpecs::LambdaSpecs::SuperAmpersand.new.lambda(&some_proc)
- l.should equal(some_proc)
- l.lambda?.should be_false
- end
+ it "returns the passed Proc if given an existing Proc through super" do
+ some_proc = proc { }
+ l = KernelSpecs::LambdaSpecs::SuperAmpersand.new.lambda(&some_proc)
+ l.should equal(some_proc)
+ l.lambda?.should be_false
+ end
- it "does not create lambda-style Procs when captured with #method" do
- kernel_lambda = method(:lambda)
- l = suppress_warning {kernel_lambda.call { 42 }}
- l.lambda?.should be_false
- l.call(:extra).should == 42
- end
+ it "does not create lambda-style Procs when captured with #method" do
+ kernel_lambda = method(:lambda)
+ l = suppress_warning {kernel_lambda.call { 42 }}
+ l.lambda?.should be_false
+ l.call(:extra).should == 42
end
it "checks the arity of the call when no args are specified" do
@@ -138,21 +136,15 @@ describe "Kernel.lambda" do
klass.new.ret.should == 1
end
- context "when called without a literal block" do
- ruby_version_is ""..."3.3" do
+ ruby_version_is "3.0" do
+ context "when called without a literal block" do
it "warns when proc isn't a lambda" do
-> { lambda(&proc{}) }.should complain("#{__FILE__}:#{__LINE__}: warning: lambda without a literal block is deprecated; use the proc without lambda instead\n")
end
- end
- ruby_version_is "3.3" do
- it "raises when proc isn't a lambda" do
- -> { lambda(&proc{}) }.should raise_error(ArgumentError, /the lambda method requires a literal block/)
+ it "doesn't warn when proc is lambda" do
+ -> { lambda(&lambda{}) }.should_not complain(verbose: true)
end
end
-
- it "doesn't warn when proc is lambda" do
- -> { lambda(&lambda{}) }.should_not complain(verbose: true)
- end
end
end
diff --git a/spec/ruby/core/kernel/method_spec.rb b/spec/ruby/core/kernel/method_spec.rb
index 3fc566d6a6..caf2ec948b 100644
--- a/spec/ruby/core/kernel/method_spec.rb
+++ b/spec/ruby/core/kernel/method_spec.rb
@@ -29,7 +29,7 @@ describe "Kernel#method" do
m.call.should == :defined
end
- it "can be called even if we only respond_to_missing? method, true" do
+ it "can be called even if we only repond_to_missing? method, true" do
m = KernelSpecs::RespondViaMissing.new.method(:handled_privately)
m.should be_an_instance_of(Method)
m.call(1, 2, 3).should == "Done handled_privately([1, 2, 3])"
@@ -58,23 +58,4 @@ describe "Kernel#method" do
m = cls.new.method(:bar)
m.call.should == :bar
end
-
- describe "converts the given name to a String using #to_str" do
- it "calls #to_str to convert the given name to a String" do
- name = mock("method-name")
- name.should_receive(:to_str).and_return("hash")
- Object.method(name).should == Object.method(:hash)
- end
-
- it "raises a TypeError if the given name can't be converted to a String" do
- -> { Object.method(nil) }.should raise_error(TypeError)
- -> { Object.method([]) }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to a String" do
- name = mock("method-name")
- name.should_receive(:to_str).and_raise(NoMethodError)
- -> { Object.method(name) }.should raise_error(NoMethodError)
- end
- end
end
diff --git a/spec/ruby/core/kernel/open_spec.rb b/spec/ruby/core/kernel/open_spec.rb
index bb42c31f31..fa9299f9d4 100644
--- a/spec/ruby/core/kernel/open_spec.rb
+++ b/spec/ruby/core/kernel/open_spec.rb
@@ -29,9 +29,7 @@ describe "Kernel#open" do
platform_is_not :windows, :wasi do
it "opens an io when path starts with a pipe" do
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- @io = open("|date")
- end
+ @io = open("|date")
begin
@io.should be_kind_of(IO)
@io.read
@@ -41,27 +39,21 @@ describe "Kernel#open" do
end
it "opens an io when called with a block" do
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- @output = open("|date") { |f| f.read }
- end
+ @output = open("|date") { |f| f.read }
@output.should_not == ''
end
it "opens an io for writing" do
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- -> {
- bytes = open("|cat", "w") { |io| io.write(".") }
- bytes.should == 1
- }.should output_to_fd(".")
- end
+ -> do
+ bytes = open("|cat", "w") { |io| io.write(".") }
+ bytes.should == 1
+ end.should output_to_fd(".")
end
end
platform_is :windows do
it "opens an io when path starts with a pipe" do
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- @io = open("|date /t")
- end
+ @io = open("|date /t")
begin
@io.should be_kind_of(IO)
@io.read
@@ -71,36 +63,15 @@ describe "Kernel#open" do
end
it "opens an io when called with a block" do
- suppress_warning do # https://bugs.ruby-lang.org/issues/19630
- @output = open("|date /t") { |f| f.read }
- end
+ @output = open("|date /t") { |f| f.read }
@output.should_not == ''
end
end
- ruby_version_is "3.3" do
- # https://bugs.ruby-lang.org/issues/19630
- it "warns about deprecation given a path with a pipe" do
- cmd = "|echo ok"
- -> {
- open(cmd) { |f| f.read }
- }.should complain(/Kernel#open with a leading '\|'/)
- end
- end
-
it "raises an ArgumentError if not passed one argument" do
-> { open }.should raise_error(ArgumentError)
end
- it "accepts options as keyword arguments" do
- @file = open(@name, "r", 0666, flags: File::CREAT)
- @file.should be_kind_of(File)
-
- -> {
- open(@name, "r", 0666, {flags: File::CREAT})
- }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)")
- end
-
describe "when given an object that responds to to_open" do
before :each do
ScratchPad.clear
@@ -138,19 +109,9 @@ describe "Kernel#open" do
it "passes its arguments onto #to_open" do
obj = mock('to_open')
- obj.should_receive(:to_open).with(1, 2, 3)
- open(obj, 1, 2, 3)
- end
-
- it "passes keyword arguments onto #to_open as keyword arguments if to_open accepts them" do
- obj = Object.new
- def obj.to_open(*args, **kw)
- ScratchPad << {args: args, kw: kw}
- end
+ obj.should_receive(:to_open).with(1,2,3)
- ScratchPad.record []
- open(obj, 1, 2, 3, a: "b")
- ScratchPad.recorded.should == [args: [1, 2, 3], kw: {a: "b"}]
+ open(obj, 1, 2, 3)
end
it "passes the return value from #to_open to a block" do
@@ -176,14 +137,28 @@ describe "Kernel#open" do
open(@name, nil, nil) { |f| f.gets }.should == @content
end
- it "is not redefined by open-uri" do
- code = <<~RUBY
- before = Kernel.instance_method(:open)
+ ruby_version_is ""..."3.0" do
+ it "works correctly when redefined by open-uri" do
+ code = <<~RUBY
require 'open-uri'
- after = Kernel.instance_method(:open)
- p before == after
- RUBY
- ruby_exe(code, args: "2>&1").should == "true\n"
+ obj = Object.new
+ def obj.to_open; self; end
+ p open(obj) == obj
+ RUBY
+ ruby_exe(code, args: "2>&1").should == "true\n"
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "is not redefined by open-uri" do
+ code = <<~RUBY
+ before = Kernel.instance_method(:open)
+ require 'open-uri'
+ after = Kernel.instance_method(:open)
+ p before == after
+ RUBY
+ ruby_exe(code, args: "2>&1").should == "true\n"
+ end
end
end
diff --git a/spec/ruby/core/kernel/printf_spec.rb b/spec/ruby/core/kernel/printf_spec.rb
index 61bf955c25..d8f93ce429 100644
--- a/spec/ruby/core/kernel/printf_spec.rb
+++ b/spec/ruby/core/kernel/printf_spec.rb
@@ -31,13 +31,6 @@ describe "Kernel.printf" do
object.should_receive(:write).with("string")
Kernel.printf(object, "%s", "string")
end
-
- it "calls #to_str to convert the format object to a String" do
- object = mock('format string')
- object.should_receive(:to_str).and_return("to_str: %i")
- $stdout.should_receive(:write).with("to_str: 42")
- Kernel.printf($stdout, object, 42)
- end
end
describe "Kernel.printf" do
diff --git a/spec/ruby/core/kernel/proc_spec.rb b/spec/ruby/core/kernel/proc_spec.rb
index 6553b8fd04..231c1f0dfb 100644
--- a/spec/ruby/core/kernel/proc_spec.rb
+++ b/spec/ruby/core/kernel/proc_spec.rb
@@ -40,9 +40,19 @@ describe "Kernel#proc" do
proc
end
- it "raises an ArgumentError when passed no block" do
- -> {
- some_method { "hello" }
- }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
+ ruby_version_is ""..."3.0" do
+ it "can be created when called with no block" do
+ -> {
+ some_method { "hello" }
+ }.should complain(/Capturing the given block using Kernel#proc is deprecated/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "raises an ArgumentError when passed no block" do
+ -> {
+ some_method { "hello" }
+ }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
+ end
end
end
diff --git a/spec/ruby/core/kernel/require_relative_spec.rb b/spec/ruby/core/kernel/require_relative_spec.rb
index 6188d13a4e..5999855de6 100644
--- a/spec/ruby/core/kernel/require_relative_spec.rb
+++ b/spec/ruby/core/kernel/require_relative_spec.rb
@@ -5,9 +5,9 @@ describe "Kernel#require_relative with a relative path" do
before :each do
CodeLoadingSpecs.spec_setup
@dir = "../../fixtures/code"
- @abs_dir = File.realpath(@dir, __dir__)
+ @abs_dir = File.realpath(@dir, File.dirname(__FILE__))
@path = "#{@dir}/load_fixture.rb"
- @abs_path = File.realpath(@path, __dir__)
+ @abs_path = File.realpath(@path, File.dirname(__FILE__))
end
after :each do
@@ -92,7 +92,7 @@ describe "Kernel#require_relative with a relative path" do
it "raises a LoadError that includes the missing path" do
missing_path = "#{@dir}/nonexistent.rb"
- expanded_missing_path = File.expand_path(missing_path, __dir__)
+ expanded_missing_path = File.expand_path(missing_path, File.dirname(__FILE__))
-> { require_relative(missing_path) }.should raise_error(LoadError) { |e|
e.message.should include(expanded_missing_path)
e.path.should == expanded_missing_path
@@ -277,7 +277,7 @@ end
describe "Kernel#require_relative with an absolute path" do
before :each do
CodeLoadingSpecs.spec_setup
- @dir = File.expand_path "../../fixtures/code", __dir__
+ @dir = File.expand_path "../../fixtures/code", File.dirname(__FILE__)
@abs_dir = @dir
@path = File.join @dir, "load_fixture.rb"
@abs_path = @path
diff --git a/spec/ruby/core/kernel/require_spec.rb b/spec/ruby/core/kernel/require_spec.rb
index 896afb840a..dc3da4b7e6 100644
--- a/spec/ruby/core/kernel/require_spec.rb
+++ b/spec/ruby/core/kernel/require_spec.rb
@@ -16,26 +16,6 @@ describe "Kernel#require" do
Kernel.should have_private_instance_method(:require)
end
- provided = %w[complex enumerator rational thread ruby2_keywords]
- ruby_version_is "3.1" do
- provided << "fiber"
- end
-
- it "#{provided.join(', ')} are already required" do
- out = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems --disable-did-you-mean')
- features = out.lines.map { |line| File.basename(line.chomp, '.*') }
-
- # Ignore CRuby internals
- features -= %w[encdb transdb windows_1252]
- features.reject! { |feature| feature.end_with?('-fake') }
-
- features.sort.should == provided.sort
-
- code = provided.map { |f| "puts require #{f.inspect}\n" }.join
- required = ruby_exe(code, options: '--disable-gems')
- required.should == "false\n" * provided.size
- end
-
it_behaves_like :kernel_require_basic, :require, CodeLoadingSpecs::Method.new
it_behaves_like :kernel_require, :require, CodeLoadingSpecs::Method.new
end
diff --git a/spec/ruby/core/kernel/shared/load.rb b/spec/ruby/core/kernel/shared/load.rb
index 0fe2d5ce16..5c41c19bf6 100644
--- a/spec/ruby/core/kernel/shared/load.rb
+++ b/spec/ruby/core/kernel/shared/load.rb
@@ -1,6 +1,5 @@
main = self
-# The big difference is Kernel#load does not attempt to add an extension to the passed path, unlike Kernel#require
describe :kernel_load, shared: true do
before :each do
CodeLoadingSpecs.spec_setup
@@ -11,31 +10,22 @@ describe :kernel_load, shared: true do
CodeLoadingSpecs.spec_cleanup
end
- describe "(path resolution)" do
- # This behavior is specific to Kernel#load, it differs for Kernel#require
- it "loads a non-extensioned file as a Ruby source file" do
- path = File.expand_path "load_fixture", CODE_LOADING_DIR
- @object.load(path).should be_true
- ScratchPad.recorded.should == [:no_ext]
- end
-
- it "loads a non .rb extensioned file as a Ruby source file" do
- path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR
- @object.load(path).should be_true
- ScratchPad.recorded.should == [:no_rb_ext]
- end
+ it "loads a non-extensioned file as a Ruby source file" do
+ path = File.expand_path "load_fixture", CODE_LOADING_DIR
+ @object.load(path).should be_true
+ ScratchPad.recorded.should == [:no_ext]
+ end
- it "loads from the current working directory" do
- Dir.chdir CODE_LOADING_DIR do
- @object.load("load_fixture.rb").should be_true
- ScratchPad.recorded.should == [:loaded]
- end
- end
+ it "loads a non .rb extensioned file as a Ruby source file" do
+ path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR
+ @object.load(path).should be_true
+ ScratchPad.recorded.should == [:no_rb_ext]
+ end
- # This behavior is specific to Kernel#load, it differs for Kernel#require
- it "does not look for a c-extension file when passed a path without extension (when no .rb is present)" do
- path = File.join CODE_LOADING_DIR, "a", "load_fixture"
- -> { @object.send(@method, path) }.should raise_error(LoadError)
+ it "loads from the current working directory" do
+ Dir.chdir CODE_LOADING_DIR do
+ @object.load("load_fixture.rb").should be_true
+ ScratchPad.recorded.should == [:loaded]
end
end
diff --git a/spec/ruby/core/kernel/shared/require.rb b/spec/ruby/core/kernel/shared/require.rb
index 250813191b..ae814aa317 100644
--- a/spec/ruby/core/kernel/shared/require.rb
+++ b/spec/ruby/core/kernel/shared/require.rb
@@ -212,34 +212,6 @@ end
describe :kernel_require, shared: true do
describe "(path resolution)" do
- it "loads .rb file when passed absolute path without extension" do
- path = File.expand_path "load_fixture", CODE_LOADING_DIR
- @object.send(@method, path).should be_true
- # This should _not_ be [:no_ext]
- ScratchPad.recorded.should == [:loaded]
- end
-
- platform_is :linux, :darwin do
- it "loads c-extension file when passed absolute path without extension when no .rb is present" do
- # the error message is specific to what dlerror() returns
- path = File.join CODE_LOADING_DIR, "a", "load_fixture"
- -> { @object.send(@method, path) }.should raise_error(Exception, /file too short|not a mach-o file/)
- end
- end
-
- platform_is :darwin do
- it "loads .bundle file when passed absolute path with .so" do
- # the error message is specific to what dlerror() returns
- path = File.join CODE_LOADING_DIR, "a", "load_fixture.so"
- -> { @object.send(@method, path) }.should raise_error(Exception, /load_fixture\.bundle.+(file too short|not a mach-o file)/)
- end
- end
-
- it "does not try an extra .rb if the path already ends in .rb" do
- path = File.join CODE_LOADING_DIR, "d", "load_fixture.rb"
- -> { @object.send(@method, path) }.should raise_error(LoadError)
- end
-
# For reference see [ruby-core:24155] in which matz confirms this feature is
# intentional for security reasons.
it "does not load a bare filename unless the current working directory is in $LOAD_PATH" do
@@ -290,11 +262,13 @@ describe :kernel_require, shared: true do
ScratchPad.recorded.should == [:loaded]
end
- it "does not load a feature twice when $LOAD_PATH has been modified" do
- $LOAD_PATH.replace [CODE_LOADING_DIR]
- @object.require("load_fixture").should be_true
- $LOAD_PATH.replace [File.expand_path("b", CODE_LOADING_DIR), CODE_LOADING_DIR]
- @object.require("load_fixture").should be_false
+ ruby_bug "#16926", ""..."3.0" do
+ it "does not load a feature twice when $LOAD_PATH has been modified" do
+ $LOAD_PATH.replace [CODE_LOADING_DIR]
+ @object.require("load_fixture").should be_true
+ $LOAD_PATH.replace [File.expand_path("b", CODE_LOADING_DIR), CODE_LOADING_DIR]
+ @object.require("load_fixture").should be_false
+ end
end
end
@@ -583,6 +557,20 @@ describe :kernel_require, shared: true do
ScratchPad.recorded.should == []
end
+ provided = %w[complex enumerator rational thread]
+ provided << 'ruby2_keywords'
+
+ it "#{provided.join(', ')} are already required" do
+ features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
+ provided.each { |feature|
+ features.should =~ /\b#{feature}\.(rb|so|jar)$/
+ }
+
+ code = provided.map { |f| "puts require #{f.inspect}\n" }.join
+ required = ruby_exe(code, options: '--disable-gems')
+ required.should == "false\n" * provided.size
+ end
+
it "unicode_normalize is part of core and not $LOADED_FEATURES" do
features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
features.lines.each { |feature|
@@ -592,21 +580,23 @@ describe :kernel_require, shared: true do
-> { @object.require("unicode_normalize") }.should raise_error(LoadError)
end
- it "does not load a file earlier on the $LOAD_PATH when other similar features were already loaded" do
- Dir.chdir CODE_LOADING_DIR do
- @object.send(@method, "../code/load_fixture").should be_true
- end
- ScratchPad.recorded.should == [:loaded]
+ ruby_version_is "3.0" do
+ it "does not load a file earlier on the $LOAD_PATH when other similar features were already loaded" do
+ Dir.chdir CODE_LOADING_DIR do
+ @object.send(@method, "../code/load_fixture").should be_true
+ end
+ ScratchPad.recorded.should == [:loaded]
- $LOAD_PATH.unshift "#{CODE_LOADING_DIR}/b"
- # This loads because the above load was not on the $LOAD_PATH
- @object.send(@method, "load_fixture").should be_true
- ScratchPad.recorded.should == [:loaded, :loaded]
+ $LOAD_PATH.unshift "#{CODE_LOADING_DIR}/b"
+ # This loads because the above load was not on the $LOAD_PATH
+ @object.send(@method, "load_fixture").should be_true
+ ScratchPad.recorded.should == [:loaded, :loaded]
- $LOAD_PATH.unshift "#{CODE_LOADING_DIR}/c"
- # This does not load because the above load was on the $LOAD_PATH
- @object.send(@method, "load_fixture").should be_false
- ScratchPad.recorded.should == [:loaded, :loaded]
+ $LOAD_PATH.unshift "#{CODE_LOADING_DIR}/c"
+ # This does not load because the above load was on the $LOAD_PATH
+ @object.send(@method, "load_fixture").should be_false
+ ScratchPad.recorded.should == [:loaded, :loaded]
+ end
end
end
diff --git a/spec/ruby/core/kernel/shared/sprintf.rb b/spec/ruby/core/kernel/shared/sprintf.rb
index 13dc6e97f0..2db50bd686 100644
--- a/spec/ruby/core/kernel/shared/sprintf.rb
+++ b/spec/ruby/core/kernel/shared/sprintf.rb
@@ -356,13 +356,13 @@ describe :kernel_sprintf, shared: true do
it "raises TypeError if converting to Integer with to_int returns non-Integer" do
obj = BasicObject.new
- def obj.to_int
+ def obj.to_str
:foo
end
-> {
@method.call("%c", obj)
- }.should raise_error(TypeError, /can't convert BasicObject to Integer/)
+ }.should raise_error(TypeError, /can't convert BasicObject to String/)
end
end
diff --git a/spec/ruby/core/kernel/singleton_class_spec.rb b/spec/ruby/core/kernel/singleton_class_spec.rb
index 23c400f9bd..c56fa08cc1 100644
--- a/spec/ruby/core/kernel/singleton_class_spec.rb
+++ b/spec/ruby/core/kernel/singleton_class_spec.rb
@@ -1,4 +1,3 @@
-# truffleruby_primitives: true
require_relative '../../spec_helper'
describe "Kernel#singleton_class" do
@@ -21,54 +20,10 @@ describe "Kernel#singleton_class" do
end
it "raises TypeError for Integer" do
- -> { 123.singleton_class }.should raise_error(TypeError, "can't define singleton")
- end
-
- it "raises TypeError for Float" do
- -> { 3.14.singleton_class }.should raise_error(TypeError, "can't define singleton")
+ -> { 123.singleton_class }.should raise_error(TypeError)
end
it "raises TypeError for Symbol" do
- -> { :foo.singleton_class }.should raise_error(TypeError, "can't define singleton")
- end
-
- it "raises TypeError for a frozen deduplicated String" do
- -> { (-"string").singleton_class }.should raise_error(TypeError, "can't define singleton")
- -> { a = -"string"; a.singleton_class }.should raise_error(TypeError, "can't define singleton")
- -> { a = "string"; (-a).singleton_class }.should raise_error(TypeError, "can't define singleton")
- end
-
- it "returns a frozen singleton class if object is frozen" do
- obj = Object.new
- obj.freeze
- obj.singleton_class.frozen?.should be_true
- end
-
- context "for an IO object with a replaced singleton class" do
- it "looks up singleton methods from the fresh singleton class after an object instance got a new one" do
- proxy = -> io { io.foo }
- if RUBY_ENGINE == 'truffleruby'
- # We need an inline cache with only this object seen, the best way to do that is to use a Primitive
- sclass = -> io { Primitive.singleton_class(io) }
- else
- sclass = -> io { io.singleton_class }
- end
-
- io = File.new(__FILE__)
- io.define_singleton_method(:foo) { "old" }
- sclass1 = sclass.call(io)
- proxy.call(io).should == "old"
-
- # IO#reopen is the only method which can replace an object's singleton class
- io2 = File.new(__FILE__)
- io.reopen(io2)
- io.define_singleton_method(:foo) { "new" }
- sclass2 = sclass.call(io)
- sclass2.should_not.equal?(sclass1)
- proxy.call(io).should == "new"
- ensure
- io2.close
- io.close
- end
+ -> { :foo.singleton_class }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb
index 0570629723..32da6344c1 100644
--- a/spec/ruby/core/kernel/sleep_spec.rb
+++ b/spec/ruby/core/kernel/sleep_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Kernel#sleep" do
it "is a private method" do
@@ -32,6 +33,10 @@ describe "Kernel#sleep" do
-> { sleep(-1) }.should raise_error(ArgumentError)
end
+ it "raises a TypeError when passed nil" do
+ -> { sleep(nil) }.should raise_error(TypeError)
+ end
+
it "raises a TypeError when passed a String" do
-> { sleep('2') }.should raise_error(TypeError)
end
@@ -50,29 +55,6 @@ describe "Kernel#sleep" do
t.wakeup
t.value.should == 5
end
-
- ruby_version_is ""..."3.3" do
- it "raises a TypeError when passed nil" do
- -> { sleep(nil) }.should raise_error(TypeError)
- end
- end
-
- ruby_version_is "3.3" do
- it "accepts a nil duration" do
- running = false
- t = Thread.new do
- running = true
- sleep(nil)
- 5
- end
-
- Thread.pass until running
- Thread.pass while t.status and t.status != "sleep"
-
- t.wakeup
- t.value.should == 5
- end
- end
end
describe "Kernel.sleep" do
diff --git a/spec/ruby/core/kernel/sprintf_spec.rb b/spec/ruby/core/kernel/sprintf_spec.rb
index 9ef7f86f16..7adf71be76 100644
--- a/spec/ruby/core/kernel/sprintf_spec.rb
+++ b/spec/ruby/core/kernel/sprintf_spec.rb
@@ -3,14 +3,6 @@ require_relative 'fixtures/classes'
require_relative 'shared/sprintf'
require_relative 'shared/sprintf_encoding'
-describe :kernel_sprintf_to_str, shared: true do
- it "calls #to_str to convert the format object to a String" do
- obj = mock('format string')
- obj.should_receive(:to_str).and_return("to_str: %i")
- @method.call(obj, 42).should == "to_str: 42"
- end
-end
-
describe "Kernel#sprintf" do
it_behaves_like :kernel_sprintf, -> format, *args {
sprintf(format, *args)
@@ -19,10 +11,6 @@ describe "Kernel#sprintf" do
it_behaves_like :kernel_sprintf_encoding, -> format, *args {
sprintf(format, *args)
}
-
- it_behaves_like :kernel_sprintf_to_str, -> format, *args {
- sprintf(format, *args)
- }
end
describe "Kernel.sprintf" do
@@ -33,8 +21,4 @@ describe "Kernel.sprintf" do
it_behaves_like :kernel_sprintf_encoding, -> format, *args {
Kernel.sprintf(format, *args)
}
-
- it_behaves_like :kernel_sprintf_to_str, -> format, *args {
- Kernel.sprintf(format, *args)
- }
end
diff --git a/spec/ruby/core/kernel/taint_spec.rb b/spec/ruby/core/kernel/taint_spec.rb
index 0c16b1dbbf..9a58bb5f04 100644
--- a/spec/ruby/core/kernel/taint_spec.rb
+++ b/spec/ruby/core/kernel/taint_spec.rb
@@ -2,13 +2,11 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#taint" do
- ruby_version_is ""..."3.2" do
+ ruby_version_is ""..."3.0" do
it "is a no-op" do
- suppress_warning do
- o = Object.new
- o.taint
- o.should_not.tainted?
- end
+ o = Object.new
+ o.taint
+ o.should_not.tainted?
end
it "warns in verbose mode" do
@@ -18,10 +16,4 @@ describe "Kernel#taint" do
}.should complain(/Object#taint is deprecated and will be removed in Ruby 3.2/, verbose: true)
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- Object.new.should_not.respond_to?(:taint)
- end
- end
end
diff --git a/spec/ruby/core/kernel/tainted_spec.rb b/spec/ruby/core/kernel/tainted_spec.rb
index fcae433069..7511c730c9 100644
--- a/spec/ruby/core/kernel/tainted_spec.rb
+++ b/spec/ruby/core/kernel/tainted_spec.rb
@@ -2,15 +2,13 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#tainted?" do
- ruby_version_is ""..."3.2" do
+ ruby_version_is ""..."3.0" do
it "is a no-op" do
- suppress_warning do
- o = mock('o')
- p = mock('p')
- p.taint
- o.should_not.tainted?
- p.should_not.tainted?
- end
+ o = mock('o')
+ p = mock('p')
+ p.taint
+ o.should_not.tainted?
+ p.should_not.tainted?
end
it "warns in verbose mode" do
@@ -20,10 +18,4 @@ describe "Kernel#tainted?" do
}.should complain(/Object#tainted\? is deprecated and will be removed in Ruby 3.2/, verbose: true)
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- Object.new.should_not.respond_to?(:tainted?)
- end
- end
end
diff --git a/spec/ruby/core/kernel/test_spec.rb b/spec/ruby/core/kernel/test_spec.rb
index d26dc06361..abb365aed2 100644
--- a/spec/ruby/core/kernel/test_spec.rb
+++ b/spec/ruby/core/kernel/test_spec.rb
@@ -3,8 +3,8 @@ require_relative 'fixtures/classes'
describe "Kernel#test" do
before :all do
- @file = __dir__ + '/fixtures/classes.rb'
- @dir = __dir__ + '/fixtures'
+ @file = File.dirname(__FILE__) + '/fixtures/classes.rb'
+ @dir = File.dirname(__FILE__) + '/fixtures'
end
it "is a private method" do
diff --git a/spec/ruby/core/kernel/trust_spec.rb b/spec/ruby/core/kernel/trust_spec.rb
index db6f17e0fb..4665036da6 100644
--- a/spec/ruby/core/kernel/trust_spec.rb
+++ b/spec/ruby/core/kernel/trust_spec.rb
@@ -2,14 +2,12 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#trust" do
- ruby_version_is ""..."3.2" do
+ ruby_version_is ""..."3.0" do
it "is a no-op" do
- suppress_warning do
- o = Object.new.untrust
- o.should_not.untrusted?
- o.trust
- o.should_not.untrusted?
- end
+ o = Object.new.untrust
+ o.should_not.untrusted?
+ o.trust
+ o.should_not.untrusted?
end
it "warns in verbose mode" do
@@ -19,10 +17,4 @@ describe "Kernel#trust" do
}.should complain(/Object#trust is deprecated and will be removed in Ruby 3.2/, verbose: true)
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- Object.new.should_not.respond_to?(:trust)
- end
- end
end
diff --git a/spec/ruby/core/kernel/untaint_spec.rb b/spec/ruby/core/kernel/untaint_spec.rb
index 26b2aabbe9..42fe8a4239 100644
--- a/spec/ruby/core/kernel/untaint_spec.rb
+++ b/spec/ruby/core/kernel/untaint_spec.rb
@@ -2,14 +2,12 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#untaint" do
- ruby_version_is ""..."3.2" do
+ ruby_version_is ""..."3.0" do
it "is a no-op" do
- suppress_warning do
- o = Object.new.taint
- o.should_not.tainted?
- o.untaint
- o.should_not.tainted?
- end
+ o = Object.new.taint
+ o.should_not.tainted?
+ o.untaint
+ o.should_not.tainted?
end
it "warns in verbose mode" do
@@ -19,10 +17,4 @@ describe "Kernel#untaint" do
}.should complain(/Object#untaint is deprecated and will be removed in Ruby 3.2/, verbose: true)
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- Object.new.should_not.respond_to?(:untaint)
- end
- end
end
diff --git a/spec/ruby/core/kernel/untrust_spec.rb b/spec/ruby/core/kernel/untrust_spec.rb
index 5310cd8eb4..ba0e073cf0 100644
--- a/spec/ruby/core/kernel/untrust_spec.rb
+++ b/spec/ruby/core/kernel/untrust_spec.rb
@@ -2,13 +2,11 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#untrust" do
- ruby_version_is ""..."3.2" do
+ ruby_version_is ""..."3.0" do
it "is a no-op" do
- suppress_warning do
- o = Object.new
- o.untrust
- o.should_not.untrusted?
- end
+ o = Object.new
+ o.untrust
+ o.should_not.untrusted?
end
it "warns in verbose mode" do
@@ -18,10 +16,4 @@ describe "Kernel#untrust" do
}.should complain(/Object#untrust is deprecated and will be removed in Ruby 3.2/, verbose: true)
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- Object.new.should_not.respond_to?(:untrust)
- end
- end
end
diff --git a/spec/ruby/core/kernel/untrusted_spec.rb b/spec/ruby/core/kernel/untrusted_spec.rb
index ea36d6c98c..517bd4711b 100644
--- a/spec/ruby/core/kernel/untrusted_spec.rb
+++ b/spec/ruby/core/kernel/untrusted_spec.rb
@@ -2,14 +2,12 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#untrusted?" do
- ruby_version_is ""..."3.2" do
+ ruby_version_is ""..."3.0" do
it "is a no-op" do
- suppress_warning do
- o = mock('o')
- o.should_not.untrusted?
- o.untrust
- o.should_not.untrusted?
- end
+ o = mock('o')
+ o.should_not.untrusted?
+ o.untrust
+ o.should_not.untrusted?
end
it "warns in verbose mode" do
@@ -19,10 +17,4 @@ describe "Kernel#untrusted?" do
}.should complain(/Object#untrusted\? is deprecated and will be removed in Ruby 3.2/, verbose: true)
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- Object.new.should_not.respond_to?(:untrusted?)
- end
- end
end
diff --git a/spec/ruby/core/kernel/warn_spec.rb b/spec/ruby/core/kernel/warn_spec.rb
index 00164ad90b..7df6fa72d1 100644
--- a/spec/ruby/core/kernel/warn_spec.rb
+++ b/spec/ruby/core/kernel/warn_spec.rb
@@ -128,34 +128,36 @@ describe "Kernel#warn" do
end
end
- it "accepts :category keyword with a symbol" do
- -> {
- $VERBOSE = true
- warn("message", category: :deprecated)
- }.should output(nil, "message\n")
- end
+ ruby_version_is "3.0" do
+ it "accepts :category keyword with a symbol" do
+ -> {
+ $VERBOSE = true
+ warn("message", category: :deprecated)
+ }.should output(nil, "message\n")
+ end
- it "accepts :category keyword with nil" do
- -> {
- $VERBOSE = true
- warn("message", category: nil)
- }.should output(nil, "message\n")
- end
+ it "accepts :category keyword with nil" do
+ -> {
+ $VERBOSE = true
+ warn("message", category: nil)
+ }.should output(nil, "message\n")
+ end
- it "accepts :category keyword with object convertible to symbol" do
- o = Object.new
- def o.to_sym; :deprecated; end
- -> {
- $VERBOSE = true
- warn("message", category: o)
- }.should output(nil, "message\n")
- end
+ it "accepts :category keyword with object convertible to symbol" do
+ o = Object.new
+ def o.to_sym; :deprecated; end
+ -> {
+ $VERBOSE = true
+ warn("message", category: o)
+ }.should output(nil, "message\n")
+ end
- it "raises if :category keyword is not nil and not convertible to symbol" do
- -> {
- $VERBOSE = true
- warn("message", category: Object.new)
- }.should raise_error(TypeError)
+ it "raises if :category keyword is not nil and not convertible to symbol" do
+ -> {
+ $VERBOSE = true
+ warn("message", category: Object.new)
+ }.should raise_error(TypeError)
+ end
end
it "converts first arg using to_s" do
@@ -210,52 +212,67 @@ describe "Kernel#warn" do
-> { warn('foo', **h) }.should complain("foo\n")
end
- it "calls Warning.warn without keyword arguments if Warning.warn does not accept keyword arguments" do
- verbose = $VERBOSE
- $VERBOSE = false
- class << Warning
- alias_method :_warn, :warn
- def warn(message)
- ScratchPad.record(message)
+ ruby_version_is '3.0' do
+ it "calls Warning.warn without keyword arguments if Warning.warn does not accept keyword arguments" do
+ verbose = $VERBOSE
+ $VERBOSE = false
+ class << Warning
+ alias_method :_warn, :warn
+ def warn(message)
+ ScratchPad.record(message)
+ end
end
- end
- begin
- ScratchPad.clear
- Kernel.warn("Chunky bacon!")
- ScratchPad.recorded.should == "Chunky bacon!\n"
+ begin
+ ScratchPad.clear
+ Kernel.warn("Chunky bacon!")
+ ScratchPad.recorded.should == "Chunky bacon!\n"
+
+ Kernel.warn("Deprecated bacon!", category: :deprecated)
+ ScratchPad.recorded.should == "Deprecated bacon!\n"
+ ensure
+ class << Warning
+ remove_method :warn
+ alias_method :warn, :_warn
+ remove_method :_warn
+ end
+ $VERBOSE = verbose
+ end
+ end
- Kernel.warn("Deprecated bacon!", category: :deprecated)
- ScratchPad.recorded.should == "Deprecated bacon!\n"
- ensure
- class << Warning
- remove_method :warn
- alias_method :warn, :_warn
- remove_method :_warn
+ it "calls Warning.warn with category: nil if Warning.warn accepts keyword arguments" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n", category: nil)
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!")
+ ensure
+ $VERBOSE = verbose
end
- $VERBOSE = verbose
end
- end
- it "calls Warning.warn with category: nil if Warning.warn accepts keyword arguments" do
- Warning.should_receive(:warn).with("Chunky bacon!\n", category: nil)
- verbose = $VERBOSE
- $VERBOSE = false
- begin
- Kernel.warn("Chunky bacon!")
- ensure
- $VERBOSE = verbose
+ it "calls Warning.warn with given category keyword converted to a symbol" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n", category: :deprecated)
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!", category: 'deprecated')
+ ensure
+ $VERBOSE = verbose
+ end
end
end
- it "calls Warning.warn with given category keyword converted to a symbol" do
- Warning.should_receive(:warn).with("Chunky bacon!\n", category: :deprecated)
- verbose = $VERBOSE
- $VERBOSE = false
- begin
- Kernel.warn("Chunky bacon!", category: 'deprecated')
- ensure
- $VERBOSE = verbose
+ ruby_version_is ''...'3.0' do
+ it "calls Warning.warn with no keyword arguments" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n")
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!")
+ ensure
+ $VERBOSE = verbose
+ end
end
end
diff --git a/spec/ruby/core/main/private_spec.rb b/spec/ruby/core/main/private_spec.rb
index e8c1f3f44c..cac0645b40 100644
--- a/spec/ruby/core/main/private_spec.rb
+++ b/spec/ruby/core/main/private_spec.rb
@@ -22,11 +22,13 @@ describe "main#private" do
end
end
- context "when single argument is passed and is an array" do
- it "sets the visibility of the given methods to private" do
- eval "private [:main_public_method, :main_public_method2]", TOPLEVEL_BINDING
- Object.should have_private_method(:main_public_method)
- Object.should have_private_method(:main_public_method2)
+ ruby_version_is "3.0" do
+ context "when single argument is passed and is an array" do
+ it "sets the visibility of the given methods to private" do
+ eval "private [:main_public_method, :main_public_method2]", TOPLEVEL_BINDING
+ Object.should have_private_method(:main_public_method)
+ Object.should have_private_method(:main_public_method2)
+ end
end
end
diff --git a/spec/ruby/core/main/public_spec.rb b/spec/ruby/core/main/public_spec.rb
index 31baad4583..91f045dbab 100644
--- a/spec/ruby/core/main/public_spec.rb
+++ b/spec/ruby/core/main/public_spec.rb
@@ -22,11 +22,13 @@ describe "main#public" do
end
end
- context "when single argument is passed and is an array" do
- it "sets the visibility of the given methods to public" do
- eval "public [:main_private_method, :main_private_method2]", TOPLEVEL_BINDING
- Object.should_not have_private_method(:main_private_method)
- Object.should_not have_private_method(:main_private_method2)
+ ruby_version_is "3.0" do
+ context "when single argument is passed and is an array" do
+ it "sets the visibility of the given methods to public" do
+ eval "public [:main_private_method, :main_private_method2]", TOPLEVEL_BINDING
+ Object.should_not have_private_method(:main_private_method)
+ Object.should_not have_private_method(:main_private_method2)
+ end
end
end
diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb
index eaf238bbd9..879ea287ce 100644
--- a/spec/ruby/core/marshal/dump_spec.rb
+++ b/spec/ruby/core/marshal/dump_spec.rb
@@ -104,42 +104,19 @@ describe "Marshal.dump" do
UserMarshal.should_not_receive(:name)
Marshal.dump(UserMarshal.new)
end
-
- it "raises TypeError if an Object is an instance of an anonymous class" do
- -> { Marshal.dump(Class.new(UserMarshal).new) }.should raise_error(TypeError, /can't dump anonymous class/)
- end
end
describe "with an object responding to #_dump" do
- it "dumps the String returned by #_dump" do
+ it "dumps the object returned by #_dump" do
Marshal.dump(UserDefined.new).should == "\004\bu:\020UserDefined\022\004\b[\a:\nstuff;\000"
end
- it "dumps the String in non US-ASCII and non UTF-8 encoding" do
- object = UserDefinedString.new("a".encode("windows-1251"))
- Marshal.dump(object).should == "\x04\bIu:\x16UserDefinedString\x06a\x06:\rencoding\"\x11Windows-1251"
- end
-
- it "dumps the String in multibyte encoding" do
- object = UserDefinedString.new("a".encode("utf-32le"))
- Marshal.dump(object).should == "\x04\bIu:\x16UserDefinedString\ta\x00\x00\x00\x06:\rencoding\"\rUTF-32LE"
- end
-
- it "ignores overridden name method" do
- obj = MarshalSpec::UserDefinedWithOverriddenName.new
- Marshal.dump(obj).should == "\x04\bu:/MarshalSpec::UserDefinedWithOverriddenName\x12\x04\b[\a:\nstuff;\x00"
- end
-
it "raises a TypeError if _dump returns a non-string" do
m = mock("marshaled")
m.should_receive(:_dump).and_return(0)
-> { Marshal.dump(m) }.should raise_error(TypeError)
end
- it "raises TypeError if an Object is an instance of an anonymous class" do
- -> { Marshal.dump(Class.new(UserDefined).new) }.should raise_error(TypeError, /can't dump anonymous class/)
- end
-
it "favors marshal_dump over _dump" do
m = mock("marshaled")
m.should_receive(:marshal_dump).and_return(0)
@@ -189,17 +166,8 @@ describe "Marshal.dump" do
Marshal.dump(UserDefined::Nested).should == "\004\bc\030UserDefined::Nested"
end
- it "ignores overridden name method" do
- Marshal.dump(MarshalSpec::ClassWithOverriddenName).should == "\x04\bc)MarshalSpec::ClassWithOverriddenName"
- end
-
- it "dumps a class with multibyte characters in name" do
- source_object = eval("MarshalSpec::Multibyteãã‚ãƒã„Class".force_encoding(Encoding::UTF_8))
- Marshal.dump(source_object).should == "\x04\bc,MarshalSpec::Multibyte\xE3\x81\x81\xE3\x81\x82\xE3\x81\x83\xE3\x81\x84Class"
- end
-
it "raises TypeError with an anonymous Class" do
- -> { Marshal.dump(Class.new) }.should raise_error(TypeError, /can't dump anonymous class/)
+ -> { Marshal.dump(Class.new) }.should raise_error(TypeError)
end
it "raises TypeError with a singleton Class" do
@@ -212,17 +180,8 @@ describe "Marshal.dump" do
Marshal.dump(Marshal).should == "\004\bm\fMarshal"
end
- it "ignores overridden name method" do
- Marshal.dump(MarshalSpec::ModuleWithOverriddenName).should == "\x04\bc*MarshalSpec::ModuleWithOverriddenName"
- end
-
- it "dumps a module with multibyte characters in name" do
- source_object = eval("MarshalSpec::Multibyteã‘ã’ã“ã”Module".force_encoding(Encoding::UTF_8))
- Marshal.dump(source_object).should == "\x04\bm-MarshalSpec::Multibyte\xE3\x81\x91\xE3\x81\x92\xE3\x81\x93\xE3\x81\x94Module"
- end
-
it "raises TypeError with an anonymous Module" do
- -> { Marshal.dump(Module.new) }.should raise_error(TypeError, /can't dump anonymous module/)
+ -> { Marshal.dump(Module.new) }.should raise_error(TypeError)
end
end
@@ -271,18 +230,6 @@ describe "Marshal.dump" do
end
end
- describe "with a Rational" do
- it "dumps a Rational" do
- Marshal.dump(Rational(2, 3)).should == "\x04\bU:\rRational[\ai\ai\b"
- end
- end
-
- describe "with a Complex" do
- it "dumps a Complex" do
- Marshal.dump(Complex(2, 3)).should == "\x04\bU:\fComplex[\ai\ai\b"
- end
- end
-
describe "with a String" do
it "dumps a blank String" do
Marshal.dump("".force_encoding("binary")).should == "\004\b\"\000"
@@ -308,11 +255,6 @@ describe "Marshal.dump" do
Marshal.dump(UserString.new.extend(Meths).force_encoding("binary")).should == "\004\be:\nMethsC:\017UserString\"\000"
end
- it "ignores overridden name method when dumps a String subclass" do
- obj = MarshalSpec::StringWithOverriddenName.new
- Marshal.dump(obj).should == "\x04\bC:*MarshalSpec::StringWithOverriddenName\"\x00"
- end
-
it "dumps a String with instance variables" do
str = ""
str.instance_variable_set("@foo", "bar")
@@ -368,42 +310,14 @@ describe "Marshal.dump" do
Marshal.dump(o).should == "\x04\b/\x00\x10"
end
- it "dumps an ascii-compatible Regexp" do
- o = Regexp.new("a".encode("us-ascii"), Regexp::FIXEDENCODING)
- Marshal.dump(o).should == "\x04\bI/\x06a\x10\x06:\x06EF"
-
- o = Regexp.new("a".encode("us-ascii"))
- Marshal.dump(o).should == "\x04\bI/\x06a\x00\x06:\x06EF"
-
- o = Regexp.new("a".encode("windows-1251"), Regexp::FIXEDENCODING)
- Marshal.dump(o).should == "\x04\bI/\x06a\x10\x06:\rencoding\"\x11Windows-1251"
-
- o = Regexp.new("a".encode("windows-1251"))
- Marshal.dump(o).should == "\x04\bI/\x06a\x00\x06:\x06EF"
- end
-
it "dumps a UTF-8 Regexp" do
o = Regexp.new("".force_encoding("utf-8"), Regexp::FIXEDENCODING)
Marshal.dump(o).should == "\x04\bI/\x00\x10\x06:\x06ET"
-
- o = Regexp.new("a".force_encoding("utf-8"), Regexp::FIXEDENCODING)
- Marshal.dump(o).should == "\x04\bI/\x06a\x10\x06:\x06ET"
-
- o = Regexp.new("\u3042".force_encoding("utf-8"), Regexp::FIXEDENCODING)
- Marshal.dump(o).should == "\x04\bI/\b\xE3\x81\x82\x10\x06:\x06ET"
end
it "dumps a Regexp in another encoding" do
o = Regexp.new("".force_encoding("utf-16le"), Regexp::FIXEDENCODING)
Marshal.dump(o).should == "\x04\bI/\x00\x10\x06:\rencoding\"\rUTF-16LE"
-
- o = Regexp.new("a".encode("utf-16le"), Regexp::FIXEDENCODING)
- Marshal.dump(o).should == "\x04\bI/\aa\x00\x10\x06:\rencoding\"\rUTF-16LE"
- end
-
- it "ignores overridden name method when dumps a Regexp subclass" do
- obj = MarshalSpec::RegexpWithOverriddenName.new("")
- Marshal.dump(obj).should == "\x04\bIC:*MarshalSpec::RegexpWithOverriddenName/\x00\x00\x06:\x06EF"
end
end
@@ -435,11 +349,6 @@ describe "Marshal.dump" do
it "dumps an extended Array" do
Marshal.dump([].extend(Meths)).should == "\004\be:\nMeths[\000"
end
-
- it "ignores overridden name method when dumps an Array subclass" do
- obj = MarshalSpec::ArrayWithOverriddenName.new
- Marshal.dump(obj).should == "\x04\bC:)MarshalSpec::ArrayWithOverriddenName[\x00"
- end
end
describe "with a Hash" do
@@ -447,10 +356,6 @@ describe "Marshal.dump" do
Marshal.dump({}).should == "\004\b{\000"
end
- it "dumps a non-empty Hash" do
- Marshal.dump({a: 1}).should == "\x04\b{\x06:\x06ai\x06"
- end
-
it "dumps a Hash subclass" do
Marshal.dump(UserHash.new).should == "\004\bC:\rUserHash{\000"
end
@@ -459,24 +364,8 @@ describe "Marshal.dump" do
Marshal.dump(Hash.new(1)).should == "\004\b}\000i\006"
end
- ruby_version_is "3.1" do
- it "dumps a Hash with compare_by_identity" do
- h = {}
- h.compare_by_identity
-
- Marshal.dump(h).should == "\004\bC:\tHash{\x00"
- end
-
- it "dumps a Hash subclass with compare_by_identity" do
- h = UserHash.new
- h.compare_by_identity
-
- Marshal.dump(h).should == "\x04\bC:\rUserHashC:\tHash{\x00"
- end
- end
-
it "raises a TypeError with hash having default proc" do
- -> { Marshal.dump(Hash.new {}) }.should raise_error(TypeError, "can't dump hash with default proc")
+ -> { Marshal.dump(Hash.new {}) }.should raise_error(TypeError)
end
it "dumps a Hash with instance variables" do
@@ -492,11 +381,6 @@ describe "Marshal.dump" do
it "dumps an Hash subclass with a parameter to initialize" do
Marshal.dump(UserHashInitParams.new(1)).should == "\004\bIC:\027UserHashInitParams{\000\006:\a@ai\006"
end
-
- it "ignores overridden name method when dumps a Hash subclass" do
- obj = MarshalSpec::HashWithOverriddenName.new
- Marshal.dump(obj).should == "\x04\bC:(MarshalSpec::HashWithOverriddenName{\x00"
- end
end
describe "with a Struct" do
@@ -525,15 +409,6 @@ describe "Marshal.dump" do
Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
Struct.send(:remove_const, :Extended)
end
-
- it "ignores overridden name method" do
- obj = MarshalSpec::StructWithOverriddenName.new("member")
- Marshal.dump(obj).should == "\x04\bS:*MarshalSpec::StructWithOverriddenName\x06:\x06a\"\vmember"
- end
-
- it "raises TypeError with an anonymous Struct" do
- -> { Marshal.dump(Struct.new(:a).new(1)) }.should raise_error(TypeError, /can't dump anonymous class/)
- end
end
describe "with an Object" do
@@ -565,18 +440,13 @@ describe "Marshal.dump" do
Marshal.dump(obj).should == "\004\bo:\x0BObject\x00"
end
- it "dumps an Object if it has a singleton class but no singleton methods and no singleton instance variables" do
+ it "dumps an Object if it has a singleton class but no singleton methods" do
obj = Object.new
obj.singleton_class
Marshal.dump(obj).should == "\004\bo:\x0BObject\x00"
end
- it "ignores overridden name method" do
- obj = MarshalSpec::ClassWithOverriddenName.new
- Marshal.dump(obj).should == "\x04\bo:)MarshalSpec::ClassWithOverriddenName\x00"
- end
-
- it "raises TypeError if an Object has a singleton class and singleton methods" do
+ it "raises if an Object has a singleton class and singleton methods" do
obj = Object.new
def obj.foo; end
-> {
@@ -584,45 +454,10 @@ describe "Marshal.dump" do
}.should raise_error(TypeError, "singleton can't be dumped")
end
- it "raises TypeError if an Object has a singleton class and singleton instance variables" do
- obj = Object.new
- class << obj
- @v = 1
- end
-
- -> {
- Marshal.dump(obj)
- }.should raise_error(TypeError, "singleton can't be dumped")
- end
-
- it "raises TypeError if an Object is an instance of an anonymous class" do
- anonymous_class = Class.new
- obj = anonymous_class.new
-
- -> { Marshal.dump(obj) }.should raise_error(TypeError, /can't dump anonymous class/)
- end
-
- it "raises TypeError if an Object extends an anonymous module" do
- anonymous_module = Module.new
- obj = Object.new
- obj.extend(anonymous_module)
-
- -> { Marshal.dump(obj) }.should raise_error(TypeError, /can't dump anonymous class/)
- end
-
it "dumps a BasicObject subclass if it defines respond_to?" do
obj = MarshalSpec::BasicObjectSubWithRespondToFalse.new
Marshal.dump(obj).should == "\x04\bo:2MarshalSpec::BasicObjectSubWithRespondToFalse\x00"
end
-
- it "dumps without marshaling any attached finalizer" do
- obj = Object.new
- finalizer = Object.new
- def finalizer.noop(_)
- end
- ObjectSpace.define_finalizer(obj, finalizer.method(:noop))
- Marshal.load(Marshal.dump(obj)).class.should == Object
- end
end
describe "with a Range" do
@@ -638,8 +473,15 @@ describe "Marshal.dump" do
load.should == (1...2)
end
- it "raises TypeError with an anonymous Range subclass" do
- -> { Marshal.dump(Class.new(Range).new(1, 2)) }.should raise_error(TypeError, /can't dump anonymous class/)
+ ruby_version_is ""..."3.0" do
+ it "dumps a Range with extra instance variables" do
+ range = (1...3)
+ range.instance_variable_set :@foo, 42
+ dump = Marshal.dump(range)
+ load = Marshal.load(dump)
+ load.should == range
+ load.instance_variable_get(:@foo).should == 42
+ end
end
end
@@ -678,20 +520,6 @@ describe "Marshal.dump" do
zone = ":\tzoneI\"\bUTC\x06:\x06EF" # Last is 'F' (US-ASCII)
dump.should == "\x04\bIu:\tTime\r#{@utc_dump}\x06#{zone}"
end
-
- it "ignores overridden name method" do
- obj = MarshalSpec::TimeWithOverriddenName.new
- Marshal.dump(obj).should include("MarshalSpec::TimeWithOverriddenName")
- end
-
- it "dumps a Time subclass with multibyte characters in name" do
- source_object = eval("MarshalSpec::Multibyteãã‚ãƒã„Time".force_encoding(Encoding::UTF_8))
- Marshal.dump(source_object).should == "\x04\bc+MarshalSpec::Multibyte\xE3\x81\x81\xE3\x81\x82\xE3\x81\x83\xE3\x81\x84Time"
- end
-
- it "raises TypeError with an anonymous Time subclass" do
- -> { Marshal.dump(Class.new(Time).now) }.should raise_error(TypeError)
- end
end
describe "with an Exception" do
@@ -732,23 +560,6 @@ describe "Marshal.dump" do
reloaded.cause.should be_an_instance_of(StandardError)
reloaded.cause.message.should == "the cause"
end
-
- # NoMethodError uses an exception formatter on TruffleRuby and computes a message lazily
- it "dumps the message for the raised NoMethodError exception" do
- begin
- "".foo
- rescue => e
- end
-
- Marshal.dump(e).should =~ /undefined method `foo' for ("":String|an instance of String)/
- end
-
- it "raises TypeError if an Object is an instance of an anonymous class" do
- anonymous_class = Class.new(Exception)
- obj = anonymous_class.new
-
- -> { Marshal.dump(obj) }.should raise_error(TypeError, /can't dump anonymous class/)
- end
end
it "dumps subsequent appearances of a symbol as a link" do
@@ -781,6 +592,7 @@ describe "Marshal.dump" do
end
describe "when passed an IO" do
+
it "writes the serialized data to the IO-Object" do
(obj = mock('test')).should_receive(:write).at_least(1)
Marshal.dump("test", obj)
@@ -803,6 +615,8 @@ describe "Marshal.dump" do
obj.should_receive(:binmode).at_least(1)
Marshal.dump("test", obj)
end
+
+
end
describe "when passed a StringIO" do
diff --git a/spec/ruby/core/marshal/fixtures/marshal_data.rb b/spec/ruby/core/marshal/fixtures/marshal_data.rb
index 680cb08ac7..9373ef7ba8 100644
--- a/spec/ruby/core/marshal/fixtures/marshal_data.rb
+++ b/spec/ruby/core/marshal/fixtures/marshal_data.rb
@@ -78,22 +78,6 @@ class UserDefinedImmediate
end
end
-class UserDefinedString
- attr_reader :string
-
- def initialize(string)
- @string = string
- end
-
- def _dump(depth)
- @string
- end
-
- def self._load(data)
- new(data)
- end
-end
-
class UserPreviouslyDefinedWithInitializedIvar
attr_accessor :field1, :field2
end
@@ -183,17 +167,12 @@ module MarshalSpec
end
end
- StructToDump = Struct.new(:a, :b)
-
class BasicObjectSubWithRespondToFalse < BasicObject
def respond_to?(method_name, include_all=false)
false
end
end
- module ModuleToExtendBy
- end
-
def self.random_data
randomizer = Random.new(42)
1000.times{randomizer.rand} # Make sure we exhaust his first state of 624 random words
@@ -213,81 +192,6 @@ module MarshalSpec
set_swapped_class(nil)
end
- class ClassWithOverriddenName
- def self.name
- "Foo"
- end
- end
-
- class ModuleWithOverriddenName
- def self.name
- "Foo"
- end
- end
-
- class TimeWithOverriddenName < Time
- def self.name
- "Foo"
- end
- end
-
- class StructWithOverriddenName < Struct.new(:a)
- def self.name
- "Foo"
- end
- end
-
- class UserDefinedWithOverriddenName < UserDefined
- def self.name
- "Foo"
- end
- end
-
- class StringWithOverriddenName < String
- def self.name
- "Foo"
- end
- end
-
- class ArrayWithOverriddenName < Array
- def self.name
- "Foo"
- end
- end
-
- class HashWithOverriddenName < Hash
- def self.name
- "Foo"
- end
- end
-
- class RegexpWithOverriddenName < Regexp
- def self.name
- "Foo"
- end
- end
-
- module_eval(<<~ruby.force_encoding(Encoding::UTF_8))
- class Multibyteãã‚ãƒã„Class
- end
-
- module Multibyteã‘ã’ã“ã”Module
- end
-
- class Multibyteãã‚ãƒã„Time < Time
- end
- ruby
-
- class ObjectWithFreezeRaisingException < Object
- def freeze
- raise
- end
- end
-
- class ObjectWithoutFreeze < Object
- undef freeze
- end
-
DATA = {
"nil" => [nil, "\004\b0"],
"1..2" => [(1..2),
diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb
index b70fb7a974..479c7477ec 100644
--- a/spec/ruby/core/marshal/shared/load.rb
+++ b/spec/ruby/core/marshal/shared/load.rb
@@ -8,11 +8,7 @@ describe :marshal_load, shared: true do
it "raises an ArgumentError when the dumped data is truncated" do
obj = {first: 1, second: 2, third: 3}
- -> { Marshal.send(@method, Marshal.dump(obj)[0, 5]) }.should raise_error(ArgumentError, "marshal data too short")
- end
-
- it "raises an ArgumentError when the argument is empty String" do
- -> { Marshal.send(@method, "") }.should raise_error(ArgumentError, "marshal data too short")
+ -> { Marshal.send(@method, Marshal.dump(obj)[0, 5]) }.should raise_error(ArgumentError)
end
it "raises an ArgumentError when the dumped class is missing" do
@@ -54,132 +50,25 @@ describe :marshal_load, shared: true do
regexp.should.frozen?
end
- it "returns frozen structs" do
- struct = Marshal.send(@method, Marshal.dump(MarshalSpec::StructToDump.new(1, 2)), freeze: true)
- struct.should == MarshalSpec::StructToDump.new(1, 2)
- struct.should.frozen?
- end
-
it "returns frozen objects" do
source_object = Object.new
+ source_object.instance_variable_set(:@foo, "bar")
object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
object.should.frozen?
- end
-
- describe "deep freezing" do
- it "returns hashes with frozen keys and values" do
- key = Object.new
- value = Object.new
- source_object = {key => value}
-
- hash = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- hash.size.should == 1
- hash.keys[0].should.frozen?
- hash.values[0].should.frozen?
- end
-
- it "returns arrays with frozen elements" do
- object = Object.new
- source_object = [object]
-
- array = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- array.size.should == 1
- array[0].should.frozen?
- end
-
- it "returns structs with frozen members" do
- object1 = Object.new
- object2 = Object.new
- source_object = MarshalSpec::StructToDump.new(object1, object2)
-
- struct = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- struct.a.should.frozen?
- struct.b.should.frozen?
- end
-
- it "returns objects with frozen instance variables" do
- source_object = Object.new
- instance_variable = Object.new
- source_object.instance_variable_set(:@a, instance_variable)
-
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- object.instance_variable_get(:@a).should != nil
- object.instance_variable_get(:@a).should.frozen?
- end
-
- it "deduplicates frozen strings" do
- source_object = ["foo" + "bar", "foobar"]
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
-
- object[0].should equal(object[1])
- end
+ object.instance_variable_get(:@foo).should.frozen?
end
it "does not freeze modules" do
- object = Marshal.send(@method, Marshal.dump(Kernel), freeze: true)
- object.should_not.frozen?
+ Marshal.send(@method, Marshal.dump(Kernel), freeze: true)
Kernel.should_not.frozen?
end
it "does not freeze classes" do
- object = Marshal.send(@method, Marshal.dump(Object), freeze: true)
- object.should_not.frozen?
+ Marshal.send(@method, Marshal.dump(Object), freeze: true)
Object.should_not.frozen?
end
- ruby_bug "#19427", ""..."3.3" do
- it "does freeze extended objects" do
- object = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x00", freeze: true)
- object.should.frozen?
- end
-
- it "does freeze extended objects with instance variables" do
- object = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x06:\n@ivarT", freeze: true)
- object.should.frozen?
- end
- end
-
- ruby_bug "#19427", "3.1"..."3.3" do
- it "returns frozen object having #_dump method" do
- object = Marshal.send(@method, Marshal.dump(UserDefined.new), freeze: true)
- object.should.frozen?
- end
-
- it "returns frozen object responding to #marshal_dump and #marshal_load" do
- object = Marshal.send(@method, Marshal.dump(UserMarshal.new), freeze: true)
- object.should.frozen?
- end
-
- it "returns frozen object extended by a module" do
- object = Object.new
- object.extend(MarshalSpec::ModuleToExtendBy)
-
- object = Marshal.send(@method, Marshal.dump(object), freeze: true)
- object.should.frozen?
- end
- end
-
- it "does not call freeze method" do
- object = MarshalSpec::ObjectWithFreezeRaisingException.new
- object = Marshal.send(@method, Marshal.dump(object), freeze: true)
- object.should.frozen?
- end
-
- it "returns frozen object even if object does not respond to freeze method" do
- object = MarshalSpec::ObjectWithoutFreeze.new
- object = Marshal.send(@method, Marshal.dump(object), freeze: true)
- object.should.frozen?
- end
-
- it "returns a frozen object when is an instance of String/Array/Regexp/Hash subclass and has instance variables" do
- source_object = UserString.new
- source_object.instance_variable_set(:@foo, "bar")
-
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- object.should.frozen?
- end
-
describe "when called with a proc" do
it "call the proc with frozen objects" do
arr = []
@@ -243,14 +132,6 @@ describe :marshal_load, shared: true do
end
end
- ruby_bug "#19427", ""..."3.3" do
- it "call the proc with extended objects" do
- objs = []
- obj = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x00", Proc.new { |o| objs << o; o })
- objs.should == [obj]
- end
- end
-
it "returns the value of the proc" do
Marshal.send(@method, Marshal.dump([1,2]), proc { [3,4] }).should == [3,4]
end
@@ -314,19 +195,7 @@ describe :marshal_load, shared: true do
marshaled_obj.field2.should be_nil
end
- it "loads the String in non US-ASCII and non UTF-8 encoding" do
- source_object = UserDefinedString.new("a".encode("windows-1251"))
- object = Marshal.send(@method, Marshal.dump(source_object))
- object.string.should == "a".encode("windows-1251")
- end
-
- it "loads the String in multibyte encoding" do
- source_object = UserDefinedString.new("a".encode("utf-32le"))
- object = Marshal.send(@method, Marshal.dump(source_object))
- object.string.should == "a".encode("utf-32le")
- end
-
- describe "that returns an immediate value" do
+ describe "that return an immediate value" do
it "loads an array containing an instance of the object, followed by multiple instances of another object" do
str = "string"
@@ -525,38 +394,6 @@ describe :marshal_load, shared: true do
unmarshalled.instance_variable_get(:@hash_ivar).should == 'hash ivar'
unmarshalled[:key].instance_variable_get(:@string_ivar).should == 'string ivar'
end
-
- ruby_version_is "3.1" do
- it "preserves compare_by_identity behaviour" do
- h = { a: 1 }
- h.compare_by_identity
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should.compare_by_identity?
-
- h = { a: 1 }
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should_not.compare_by_identity?
- end
-
- it "preserves compare_by_identity behaviour for a Hash subclass" do
- h = UserHash.new({ a: 1 })
- h.compare_by_identity
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should.compare_by_identity?
-
- h = UserHash.new({ a: 1 })
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should_not.compare_by_identity?
- end
- end
-
- it "allocates an instance of the proper class when Hash subclass with compare_by_identity behaviour" do
- h = UserHash.new({ a: 1 })
- h.compare_by_identity
-
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should.kind_of?(UserHash)
- end
end
describe "for a Symbol" do
@@ -623,14 +460,6 @@ describe :marshal_load, shared: true do
value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8, Encoding::UTF_8]
value.should == [*expected, expected[0]]
end
-
- it "raises ArgumentError when end of byte sequence reached before symbol characters end" do
- Marshal.dump(:hello).should == "\x04\b:\nhello"
-
- -> {
- Marshal.send(@method, "\x04\b:\nhel")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for a String" do
@@ -646,12 +475,6 @@ describe :marshal_load, shared: true do
Marshal.send(@method, StringIO.new(Marshal.dump(obj))).should == obj
end
- it "sets binmode if it is loading through StringIO stream" do
- io = StringIO.new("\004\b:\vsymbol")
- def io.binmode; raise "binmode"; end
- -> { Marshal.load(io) }.should raise_error(RuntimeError, "binmode")
- end
-
it "loads a string with an ivar" do
str = Marshal.send(@method, "\x04\bI\"\x00\x06:\t@fooI\"\bbar\x06:\x06EF")
str.instance_variable_get("@foo").should == "bar"
@@ -693,14 +516,6 @@ describe :marshal_load, shared: true do
result.encoding.should == Encoding::BINARY
result.should == str
end
-
- it "raises ArgumentError when end of byte sequence reached before string characters end" do
- Marshal.dump("hello").should == "\x04\b\"\nhello"
-
- -> {
- Marshal.send(@method, "\x04\b\"\nhel")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for a Struct" do
@@ -835,14 +650,6 @@ describe :marshal_load, shared: true do
Marshal.send(@method, "\x04\bo:\tFile\001\001:\001\005@path\"\x10/etc/passwd")
end.should raise_error(ArgumentError)
end
-
- it "raises ArgumentError when end of byte sequence reached before class name end" do
- Marshal.dump(Object.new).should == "\x04\bo:\vObject\x00"
-
- -> {
- Marshal.send(@method, "\x04\bo:\vObj")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for an object responding to #marshal_dump and #marshal_load" do
@@ -901,7 +708,7 @@ describe :marshal_load, shared: true do
[Meths, MethsMore, Regexp]
end
- it "loads a Regexp subclass instance variables when it is extended with a module" do
+ it "loads a extended_user_regexp having ivar" do
obj = UserRegexp.new('').extend(Meths)
obj.instance_variable_set(:@noise, 'much')
@@ -924,22 +731,6 @@ describe :marshal_load, shared: true do
new_obj.instance_variable_get(:@regexp_ivar).should == [42]
end
end
-
- it "preserves Regexp encoding" do
- source_object = Regexp.new("a".encode("utf-32le"))
- regexp = Marshal.send(@method, Marshal.dump(source_object))
-
- regexp.encoding.should == Encoding::UTF_32LE
- regexp.source.should == "a".encode("utf-32le")
- end
-
- it "raises ArgumentError when end of byte sequence reached before source string end" do
- Marshal.dump(/hello world/).should == "\x04\bI/\x10hello world\x00\x06:\x06EF"
-
- -> {
- Marshal.send(@method, "\x04\bI/\x10hel")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for a Float" do
@@ -961,14 +752,6 @@ describe :marshal_load, shared: true do
obj = 1.1867345e+22
Marshal.send(@method, "\004\bf\0361.1867344999999999e+22\000\344@").should == obj
end
-
- it "raises ArgumentError when end of byte sequence reached before float string representation end" do
- Marshal.dump(1.3).should == "\x04\bf\b1.3"
-
- -> {
- Marshal.send(@method, "\004\bf\v1")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for an Integer" do
@@ -1034,17 +817,13 @@ describe :marshal_load, shared: true do
describe "for a Rational" do
it "loads" do
- r = Marshal.send(@method, Marshal.dump(Rational(1, 3)))
- r.should == Rational(1, 3)
- r.should.frozen?
+ Marshal.send(@method, Marshal.dump(Rational(1, 3))).should == Rational(1, 3)
end
end
describe "for a Complex" do
it "loads" do
- c = Marshal.send(@method, Marshal.dump(Complex(4, 3)))
- c.should == Complex(4, 3)
- c.should.frozen?
+ Marshal.send(@method, Marshal.dump(Complex(4, 3))).should == Complex(4, 3)
end
end
@@ -1085,47 +864,17 @@ describe :marshal_load, shared: true do
t1.should equal t2
end
- it "keeps the local zone" do
+ it "loads the zone" do
with_timezone 'AST', 3 do
t = Time.local(2012, 1, 1)
Marshal.send(@method, Marshal.dump(t)).zone.should == t.zone
end
end
- it "keeps UTC zone" do
- t = Time.now.utc
- t2 = Marshal.send(@method, Marshal.dump(t))
- t2.should.utc?
- end
-
- it "keeps the zone" do
- t = nil
-
- with_timezone 'AST', 4 do
- t = Time.local(2012, 1, 1)
- end
-
- with_timezone 'EET', -2 do
- Marshal.send(@method, Marshal.dump(t)).zone.should == 'AST'
- end
- end
-
- it "keeps utc offset" do
- t = Time.new(2007,11,1,15,25,0, "+09:00")
- t2 = Marshal.send(@method, Marshal.dump(t))
- t2.utc_offset.should == 32400
- end
-
- it "keeps nanoseconds" do
+ it "loads nanoseconds" do
t = Time.now
Marshal.send(@method, Marshal.dump(t)).nsec.should == t.nsec
end
-
- it "does not add any additional instance variable" do
- t = Time.now
- t2 = Marshal.send(@method, Marshal.dump(t))
- t2.instance_variables.should.empty?
- end
end
describe "for nil" do
@@ -1158,14 +907,6 @@ describe :marshal_load, shared: true do
it "raises ArgumentError if given a nonexistent class" do
-> { Marshal.send(@method, "\x04\bc\vStrung") }.should raise_error(ArgumentError)
end
-
- it "raises ArgumentError when end of byte sequence reached before class name end" do
- Marshal.dump(String).should == "\x04\bc\vString"
-
- -> {
- Marshal.send(@method, "\x04\bc\vStr")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for a Module" do
@@ -1180,14 +921,6 @@ describe :marshal_load, shared: true do
it "loads an old module" do
Marshal.send(@method, "\x04\bM\vKernel").should == Kernel
end
-
- it "raises ArgumentError when end of byte sequence reached before module name end" do
- Marshal.dump(Kernel).should == "\x04\bm\vKernel"
-
- -> {
- Marshal.send(@method, "\x04\bm\vKer")
- }.should raise_error(ArgumentError, "marshal data too short")
- end
end
describe "for a wrapped C pointer" do
diff --git a/spec/ruby/core/matchdata/byteoffset_spec.rb b/spec/ruby/core/matchdata/byteoffset_spec.rb
deleted file mode 100644
index 6036097834..0000000000
--- a/spec/ruby/core/matchdata/byteoffset_spec.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "MatchData#byteoffset" do
- ruby_version_is "3.2" do
- it "returns beginning and ending byte-based offset of whole matched substring for 0 element" do
- m = /(.)(.)(\d+)(\d)/.match("THX1138.")
- m.byteoffset(0).should == [1, 7]
- end
-
- it "returns beginning and ending byte-based offset of n-th match, all the subsequent elements are capturing groups" do
- m = /(.)(.)(\d+)(\d)/.match("THX1138.")
-
- m.byteoffset(2).should == [2, 3]
- m.byteoffset(3).should == [3, 6]
- m.byteoffset(4).should == [6, 7]
- end
-
- it "accepts String as a reference to a named capture" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- m.byteoffset("f").should == [0, 3]
- m.byteoffset("b").should == [3, 6]
- end
-
- it "accepts Symbol as a reference to a named capture" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- m.byteoffset(:f).should == [0, 3]
- m.byteoffset(:b).should == [3, 6]
- end
-
- it "returns [nil, nil] if a capturing group is optional and doesn't match" do
- m = /(?<x>q..)?/.match("foobarbaz")
-
- m.byteoffset("x").should == [nil, nil]
- m.byteoffset(1).should == [nil, nil]
- end
-
- it "returns correct beginning and ending byte-based offset for multi-byte strings" do
- m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044")
-
- m.byteoffset(1).should == [3, 6]
- m.byteoffset(3).should == [6, 9]
- end
-
- it "returns [nil, nil] if a capturing group is optional and doesn't match for multi-byte string" do
- m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044")
-
- m.byteoffset(2).should == [nil, nil]
- end
-
- it "converts argument into integer if is not String nor Symbol" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- obj = Object.new
- def obj.to_int; 2; end
-
- m.byteoffset(1r).should == [0, 3]
- m.byteoffset(1.1).should == [0, 3]
- m.byteoffset(obj).should == [3, 6]
- end
-
- it "raises IndexError if there is no group with provided name" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- -> {
- m.byteoffset("y")
- }.should raise_error(IndexError, "undefined group name reference: y")
-
- -> {
- m.byteoffset(:y)
- }.should raise_error(IndexError, "undefined group name reference: y")
- end
-
- it "raises IndexError if index is out of matches" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- -> {
- m.byteoffset(-1)
- }.should raise_error(IndexError, "index -1 out of matches")
-
- -> {
- m.byteoffset(3)
- }.should raise_error(IndexError, "index 3 out of matches")
- end
-
- it "raises TypeError if can't convert argument into Integer" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- -> {
- m.byteoffset([])
- }.should raise_error(TypeError, "no implicit conversion of Array into Integer")
- end
- end
-end
diff --git a/spec/ruby/core/matchdata/captures_spec.rb b/spec/ruby/core/matchdata/captures_spec.rb
index f829a25481..58d4620709 100644
--- a/spec/ruby/core/matchdata/captures_spec.rb
+++ b/spec/ruby/core/matchdata/captures_spec.rb
@@ -1,6 +1,15 @@
require_relative '../../spec_helper'
-require_relative 'shared/captures'
+require_relative 'fixtures/classes'
describe "MatchData#captures" do
- it_behaves_like :matchdata_captures, :captures
+ it "returns an array of the match captures" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.").captures.should == ["H","X","113","8"]
+ end
+
+ ruby_version_is "3.0" do
+ it "returns instances of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138: The Movie")
+ /(.)(.)(\d+)(\d)/.match(str).captures.each { |c| c.should be_an_instance_of(String) }
+ end
+ end
end
diff --git a/spec/ruby/core/matchdata/deconstruct_keys_spec.rb b/spec/ruby/core/matchdata/deconstruct_keys_spec.rb
deleted file mode 100644
index 5b68f886c7..0000000000
--- a/spec/ruby/core/matchdata/deconstruct_keys_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "MatchData#deconstruct_keys" do
- ruby_version_is "3.2" do
- it "returns whole hash for nil as an argument" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- m.deconstruct_keys(nil).should == { f: "foo", b: "bar" }
- end
-
- it "returns only specified keys" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- m.deconstruct_keys([:f]).should == { f: "foo" }
- end
-
- it "requires one argument" do
- m = /l/.match("l")
-
- -> {
- m.deconstruct_keys
- }.should raise_error(ArgumentError, "wrong number of arguments (given 0, expected 1)")
- end
-
- it "it raises error when argument is neither nil nor array" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- -> { m.deconstruct_keys(1) }.should raise_error(TypeError, "wrong argument type Integer (expected Array)")
- -> { m.deconstruct_keys("asd") }.should raise_error(TypeError, "wrong argument type String (expected Array)")
- -> { m.deconstruct_keys(:x) }.should raise_error(TypeError, "wrong argument type Symbol (expected Array)")
- -> { m.deconstruct_keys({}) }.should raise_error(TypeError, "wrong argument type Hash (expected Array)")
- end
-
- it "returns {} when passed []" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- m.deconstruct_keys([]).should == {}
- end
-
- it "does not accept non-Symbol keys" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
-
- -> {
- m.deconstruct_keys(['year', :foo])
- }.should raise_error(TypeError, "wrong argument type String (expected Symbol)")
- end
-
- it "process keys till the first non-existing one" do
- m = /(?<f>foo)(?<b>bar)(?<c>baz)/.match("foobarbaz")
-
- m.deconstruct_keys([:f, :a, :b]).should == { f: "foo" }
- end
-
- it "returns {} when there are no named captured groups at all" do
- m = /foo.+/.match("foobar")
-
- m.deconstruct_keys(nil).should == {}
- end
-
- it "returns {} when passed more keys than named captured groups" do
- m = /(?<f>foo)(?<b>bar)/.match("foobar")
- m.deconstruct_keys([:f, :b, :c]).should == {}
- end
- end
-end
diff --git a/spec/ruby/core/matchdata/deconstruct_spec.rb b/spec/ruby/core/matchdata/deconstruct_spec.rb
deleted file mode 100644
index 6af55113b6..0000000000
--- a/spec/ruby/core/matchdata/deconstruct_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/captures'
-
-describe "MatchData#deconstruct" do
- ruby_version_is "3.2" do
- it_behaves_like :matchdata_captures, :deconstruct
- end
-end
diff --git a/spec/ruby/core/matchdata/element_reference_spec.rb b/spec/ruby/core/matchdata/element_reference_spec.rb
index 1be399cfe1..7c0f089bb4 100644
--- a/spec/ruby/core/matchdata/element_reference_spec.rb
+++ b/spec/ruby/core/matchdata/element_reference_spec.rb
@@ -22,11 +22,6 @@ describe "MatchData#[]" do
# length argument larger than number of match values is capped to match value length
/(.)(.)(\d+)(\d)/.match("THX1138.")[3, 10].should == %w|113 8|
-
- /(.)(.)(\d+)(\d)/.match("THX1138.")[3, 0].should == []
-
- /(.)(.)(\d+)(\d)/.match("THX1138.")[3, -1].should == nil
- /(.)(.)(\d+)(\d)/.match("THX1138.")[3, -30].should == nil
end
it "supports ranges [start..end]" do
@@ -48,9 +43,11 @@ describe "MatchData#[]" do
/(.)(.)(\d+)(\d)/.match("THX1138.")[nil..nil].should == %w|HX1138 H X 113 8|
end
- it "returns instances of String when given a String subclass" do
- str = MatchDataSpecs::MyString.new("THX1138.")
- /(.)(.)(\d+)(\d)/.match(str)[0..-1].each { |m| m.should be_an_instance_of(String) }
+ ruby_version_is "3.0" do
+ it "returns instances of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138.")
+ /(.)(.)(\d+)(\d)/.match(str)[0..-1].each { |m| m.should be_an_instance_of(String) }
+ end
end
end
diff --git a/spec/ruby/core/matchdata/named_captures_spec.rb b/spec/ruby/core/matchdata/named_captures_spec.rb
index 5e4693d62d..9b1e324a24 100644
--- a/spec/ruby/core/matchdata/named_captures_spec.rb
+++ b/spec/ruby/core/matchdata/named_captures_spec.rb
@@ -12,16 +12,4 @@ describe 'MatchData#named_captures' do
it 'returns the latest matched capture, even if a later one that does not match exists' do
/\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)?\z/.match('012').named_captures.should == { 'a' => '0', 'b' => '2' }
end
-
- ruby_version_is "3.3" do
- it 'returns a Hash with Symbol keys when symbolize_names is provided a true value' do
- /(?<a>.)(?<b>.)?/.match('0').named_captures(symbolize_names: true).should == { a: '0', b: nil }
- /(?<a>.)(?<b>.)?/.match('0').named_captures(symbolize_names: "truly").should == { a: '0', b: nil }
- end
-
- it 'returns a Hash with String keys when symbolize_names is provided a false value' do
- /(?<a>.)(?<b>.)?/.match('02').named_captures(symbolize_names: false).should == { 'a' => '0', 'b' => '2' }
- /(?<a>.)(?<b>.)?/.match('02').named_captures(symbolize_names: nil).should == { 'a' => '0', 'b' => '2' }
- end
- end
end
diff --git a/spec/ruby/core/matchdata/post_match_spec.rb b/spec/ruby/core/matchdata/post_match_spec.rb
index b8d1e032eb..d3aa4c8900 100644
--- a/spec/ruby/core/matchdata/post_match_spec.rb
+++ b/spec/ruby/core/matchdata/post_match_spec.rb
@@ -17,8 +17,10 @@ describe "MatchData#post_match" do
str.match(/c/).post_match.encoding.should equal(Encoding::ISO_8859_1)
end
- it "returns an instance of String when given a String subclass" do
- str = MatchDataSpecs::MyString.new("THX1138: The Movie")
- /(.)(.)(\d+)(\d)/.match(str).post_match.should be_an_instance_of(String)
+ ruby_version_is "3.0" do
+ it "returns an instance of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138: The Movie")
+ /(.)(.)(\d+)(\d)/.match(str).post_match.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/matchdata/pre_match_spec.rb b/spec/ruby/core/matchdata/pre_match_spec.rb
index 741cb6e923..b43be5fb41 100644
--- a/spec/ruby/core/matchdata/pre_match_spec.rb
+++ b/spec/ruby/core/matchdata/pre_match_spec.rb
@@ -17,8 +17,10 @@ describe "MatchData#pre_match" do
str.match(/a/).pre_match.encoding.should equal(Encoding::ISO_8859_1)
end
- it "returns an instance of String when given a String subclass" do
- str = MatchDataSpecs::MyString.new("THX1138: The Movie")
- /(.)(.)(\d+)(\d)/.match(str).pre_match.should be_an_instance_of(String)
+ ruby_version_is "3.0" do
+ it "returns an instance of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138: The Movie")
+ /(.)(.)(\d+)(\d)/.match(str).pre_match.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/matchdata/shared/captures.rb b/spec/ruby/core/matchdata/shared/captures.rb
deleted file mode 100644
index 33f834561a..0000000000
--- a/spec/ruby/core/matchdata/shared/captures.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../fixtures/classes'
-
-describe :matchdata_captures, shared: true do
- it "returns an array of the match captures" do
- /(.)(.)(\d+)(\d)/.match("THX1138.").send(@method).should == ["H","X","113","8"]
- end
-
- it "returns instances of String when given a String subclass" do
- str = MatchDataSpecs::MyString.new("THX1138: The Movie")
- /(.)(.)(\d+)(\d)/.match(str).send(@method).each { |c| c.should be_an_instance_of(String) }
- end
-end
diff --git a/spec/ruby/core/matchdata/to_a_spec.rb b/spec/ruby/core/matchdata/to_a_spec.rb
index 4fa11ff604..50f5a161a5 100644
--- a/spec/ruby/core/matchdata/to_a_spec.rb
+++ b/spec/ruby/core/matchdata/to_a_spec.rb
@@ -6,8 +6,10 @@ describe "MatchData#to_a" do
/(.)(.)(\d+)(\d)/.match("THX1138.").to_a.should == ["HX1138", "H", "X", "113", "8"]
end
- it "returns instances of String when given a String subclass" do
- str = MatchDataSpecs::MyString.new("THX1138.")
- /(.)(.)(\d+)(\d)/.match(str)[0..-1].to_a.each { |m| m.should be_an_instance_of(String) }
+ ruby_version_is "3.0" do
+ it "returns instances of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138.")
+ /(.)(.)(\d+)(\d)/.match(str)[0..-1].to_a.each { |m| m.should be_an_instance_of(String) }
+ end
end
end
diff --git a/spec/ruby/core/matchdata/to_s_spec.rb b/spec/ruby/core/matchdata/to_s_spec.rb
index cd1c4dbca2..aab0955ae1 100644
--- a/spec/ruby/core/matchdata/to_s_spec.rb
+++ b/spec/ruby/core/matchdata/to_s_spec.rb
@@ -6,8 +6,10 @@ describe "MatchData#to_s" do
/(.)(.)(\d+)(\d)/.match("THX1138.").to_s.should == "HX1138"
end
- it "returns an instance of String when given a String subclass" do
- str = MatchDataSpecs::MyString.new("THX1138.")
- /(.)(.)(\d+)(\d)/.match(str).to_s.should be_an_instance_of(String)
+ ruby_version_is "3.0" do
+ it "returns an instance of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138.")
+ /(.)(.)(\d+)(\d)/.match(str).to_s.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/matchdata/values_at_spec.rb b/spec/ruby/core/matchdata/values_at_spec.rb
index 535719a2ee..4fd0bfc42a 100644
--- a/spec/ruby/core/matchdata/values_at_spec.rb
+++ b/spec/ruby/core/matchdata/values_at_spec.rb
@@ -1,6 +1,6 @@
require_relative '../../spec_helper'
-describe "MatchData#values_at" do
+describe "Struct#values_at" do
# Should be synchronized with core/array/values_at_spec.rb and core/struct/values_at_spec.rb
#
# /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").to_a # => ["HX1138", "H", "X", "113", "8"]
@@ -34,7 +34,7 @@ describe "MatchData#values_at" do
end
it "supports beginningless Range" do
- /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(..2).should == ["HX1138", "H", "X"]
+ /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0..2).should == ["HX1138", "H", "X"]
end
it "returns an empty Array when Range is empty" do
diff --git a/spec/ruby/core/math/cos_spec.rb b/spec/ruby/core/math/cos_spec.rb
index 006afeb2cc..3ba7a54c38 100644
--- a/spec/ruby/core/math/cos_spec.rb
+++ b/spec/ruby/core/math/cos_spec.rb
@@ -15,6 +15,7 @@ describe "Math.cos" do
Math.cos(2*Math::PI).should be_close(1.0, TOLERANCE)
end
+
it "raises a TypeError unless the argument is Numeric and has #to_f" do
-> { Math.cos("test") }.should raise_error(TypeError)
end
@@ -23,23 +24,14 @@ describe "Math.cos" do
Math.cos(nan_value).nan?.should be_true
end
- describe "coerces its argument with #to_f" do
- it "coerces its argument with #to_f" do
- f = mock_numeric('8.2')
- f.should_receive(:to_f).and_return(8.2)
- Math.cos(f).should == Math.cos(8.2)
- end
-
- it "raises a TypeError if the given argument can't be converted to a Float" do
- -> { Math.cos(nil) }.should raise_error(TypeError)
- -> { Math.cos(:abc) }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to a Float" do
- object = mock_numeric('mock-float')
- object.should_receive(:to_f).and_raise(NoMethodError)
- -> { Math.cos(object) }.should raise_error(NoMethodError)
- end
+ it "raises a TypeError if the argument is nil" do
+ -> { Math.cos(nil) }.should raise_error(TypeError)
+ end
+
+ it "coerces its argument with #to_f" do
+ f = mock_numeric('8.2')
+ f.should_receive(:to_f).and_return(8.2)
+ Math.cos(f).should == Math.cos(8.2)
end
end
diff --git a/spec/ruby/core/method/clone_spec.rb b/spec/ruby/core/method/clone_spec.rb
index b0eb5751a9..3fe4000fb7 100644
--- a/spec/ruby/core/method/clone_spec.rb
+++ b/spec/ruby/core/method/clone_spec.rb
@@ -1,13 +1,14 @@
require_relative '../../spec_helper'
-require_relative 'shared/dup'
+require_relative 'fixtures/classes'
describe "Method#clone" do
- it_behaves_like :method_dup, :clone
+ it "returns a copy of the method" do
+ m1 = MethodSpecs::Methods.new.method(:foo)
+ m2 = m1.clone
- it "preserves frozen status" do
- method = Object.new.method(:method)
- method.freeze
- method.frozen?.should == true
- method.clone.frozen?.should == true
+ m1.should == m2
+ m1.should_not equal(m2)
+
+ m1.call.should == m2.call
end
end
diff --git a/spec/ruby/core/method/compose_spec.rb b/spec/ruby/core/method/compose_spec.rb
index 7506e33ea8..87cf61f7ad 100644
--- a/spec/ruby/core/method/compose_spec.rb
+++ b/spec/ruby/core/method/compose_spec.rb
@@ -38,7 +38,8 @@ describe "Method#<<" do
double = proc { |x| x + x }
(pow_2 << double).is_a?(Proc).should == true
- (pow_2 << double).should_not.lambda?
+ ruby_version_is(''...'3.0') { (pow_2 << double).should.lambda? }
+ ruby_version_is('3.0') { (pow_2 << double).should_not.lambda? }
end
it "may accept multiple arguments" do
diff --git a/spec/ruby/core/method/dup_spec.rb b/spec/ruby/core/method/dup_spec.rb
deleted file mode 100644
index e3e29d8a68..0000000000
--- a/spec/ruby/core/method/dup_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/dup'
-
-describe "Method#dup" do
- ruby_version_is "3.4" do
- it_behaves_like :method_dup, :dup
-
- it "resets frozen status" do
- method = Object.new.method(:method)
- method.freeze
- method.frozen?.should == true
- method.dup.frozen?.should == false
- end
- end
-end
diff --git a/spec/ruby/core/method/parameters_spec.rb b/spec/ruby/core/method/parameters_spec.rb
index 7d2b37fac7..e6d51d1b4d 100644
--- a/spec/ruby/core/method/parameters_spec.rb
+++ b/spec/ruby/core/method/parameters_spec.rb
@@ -7,7 +7,6 @@ describe "Method#parameters" do
def one_keyrest(**a); end
def one_keyreq(a:); end
- def one_nokey(**nil); end
def one_splat_one_req(*a,b); end
def one_splat_two_req(*a,b,c); end
@@ -16,14 +15,11 @@ describe "Method#parameters" do
def one_opt_with_stabby(a=-> b { true }); end
def one_unnamed_splat(*); end
- def one_unnamed_keyrest(**); end
def one_splat_one_block(*args, &block)
local_is_not_parameter = {}
end
- def underscore_parameters(_, _, _ = 1, *_, _:, _: 2, **_, &_); end
-
define_method(:one_optional_defined_method) {|x = 1|}
end
@@ -180,11 +176,6 @@ describe "Method#parameters" do
m.parameters.should == [[:keyreq,:a]]
end
- it "returns [[:nokey]] for a method with a single **nil parameter" do
- m = MethodSpecs::Methods.instance_method(:one_nokey)
- m.parameters.should == [[:nokey]]
- end
-
it "works with ->(){} as the value of an optional argument" do
m = MethodSpecs::Methods.instance_method(:one_opt_with_stabby)
m.parameters.should == [[:opt,:a]]
@@ -232,15 +223,10 @@ describe "Method#parameters" do
end
ruby_version_is '3.2' do
- it "adds rest arg with name * for \"star\" argument" do
+ it "adds * rest arg for \"star\" argument" do
m = MethodSpecs::Methods.new
m.method(:one_unnamed_splat).parameters.should == [[:rest, :*]]
end
-
- it "adds keyrest arg with ** as a name for \"double star\" argument" do
- m = MethodSpecs::Methods.new
- m.method(:one_unnamed_keyrest).parameters.should == [[:keyrest, :**]]
- end
end
ruby_version_is ''...'3.2' do
@@ -248,23 +234,6 @@ describe "Method#parameters" do
m = MethodSpecs::Methods.new
m.method(:one_unnamed_splat).parameters.should == [[:rest]]
end
-
- it "adds nameless keyrest arg for \"double star\" argument" do
- m = MethodSpecs::Methods.new
- m.method(:one_unnamed_keyrest).parameters.should == [[:keyrest]]
- end
- end
-
- ruby_version_is '3.1' do
- it "adds block arg with name & for anonymous block argument" do
- object = Object.new
-
- eval(<<~RUBY).should == [[:block, :&]]
- def object.foo(&)
- end
- object.method(:foo).parameters
- RUBY
- end
end
it "returns the args and block for a splat and block argument" do
@@ -282,20 +251,6 @@ describe "Method#parameters" do
m.method(:writer=).parameters.should == [[:req]]
end
- it "returns all parameters defined with the name _ as _" do
- m = MethodSpecs::Methods.instance_method(:underscore_parameters)
- m.parameters.should == [
- [:req, :_],
- [:req, :_],
- [:opt, :_],
- [:rest, :_],
- [:keyreq, :_],
- [:key, :_],
- [:keyrest, :_],
- [:block, :_]
- ]
- end
-
it "returns [[:rest]] for core methods with variable-length argument lists" do
# delete! takes rest args
"foo".method(:delete!).parameters.should == [[:rest]]
diff --git a/spec/ruby/core/method/private_spec.rb b/spec/ruby/core/method/private_spec.rb
index fd550036a3..230a4e9e81 100644
--- a/spec/ruby/core/method/private_spec.rb
+++ b/spec/ruby/core/method/private_spec.rb
@@ -1,8 +1,8 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "Method#private?" do
- ruby_version_is "3.1"..."3.2" do
+ruby_version_is "3.1"..."3.2" do
+ describe "Method#private?" do
it "returns false when the method is public" do
obj = MethodSpecs::Methods.new
obj.method(:my_public_method).private?.should == false
@@ -18,11 +18,4 @@ describe "Method#private?" do
obj.method(:my_private_method).private?.should == true
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- obj = MethodSpecs::Methods.new
- obj.method(:my_private_method).should_not.respond_to?(:private?)
- end
- end
end
diff --git a/spec/ruby/core/method/protected_spec.rb b/spec/ruby/core/method/protected_spec.rb
index 8423e8c64c..6ee85f7738 100644
--- a/spec/ruby/core/method/protected_spec.rb
+++ b/spec/ruby/core/method/protected_spec.rb
@@ -1,8 +1,8 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "Method#protected?" do
- ruby_version_is "3.1"..."3.2" do
+ruby_version_is "3.1"..."3.2" do
+ describe "Method#protected?" do
it "returns false when the method is public" do
obj = MethodSpecs::Methods.new
obj.method(:my_public_method).protected?.should == false
@@ -18,11 +18,4 @@ describe "Method#protected?" do
obj.method(:my_private_method).protected?.should == false
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- obj = MethodSpecs::Methods.new
- obj.method(:my_protected_method).should_not.respond_to?(:protected?)
- end
- end
end
diff --git a/spec/ruby/core/method/public_spec.rb b/spec/ruby/core/method/public_spec.rb
index 20d0081a27..3988468551 100644
--- a/spec/ruby/core/method/public_spec.rb
+++ b/spec/ruby/core/method/public_spec.rb
@@ -1,8 +1,8 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "Method#public?" do
- ruby_version_is "3.1"..."3.2" do
+ruby_version_is "3.1"..."3.2" do
+ describe "Method#public?" do
it "returns true when the method is public" do
obj = MethodSpecs::Methods.new
obj.method(:my_public_method).public?.should == true
@@ -18,11 +18,4 @@ describe "Method#public?" do
obj.method(:my_private_method).public?.should == false
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- obj = MethodSpecs::Methods.new
- obj.method(:my_public_method).should_not.respond_to?(:public?)
- end
- end
end
diff --git a/spec/ruby/core/method/shared/dup.rb b/spec/ruby/core/method/shared/dup.rb
deleted file mode 100644
index 1a10b90689..0000000000
--- a/spec/ruby/core/method/shared/dup.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-describe :method_dup, shared: true do
- it "returns a copy of self" do
- a = Object.new.method(:method)
- b = a.send(@method)
-
- a.should == b
- a.should_not equal(b)
- end
-
- ruby_version_is "3.4" do
- it "copies instance variables" do
- method = Object.new.method(:method)
- method.instance_variable_set(:@ivar, 1)
- cl = method.send(@method)
- cl.instance_variables.should == [:@ivar]
- end
-
- it "copies the finalizer" do
- code = <<-RUBY
- obj = Object.new.method(:method)
-
- ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized\n" })
-
- obj.clone
-
- exit 0
- RUBY
-
- ruby_exe(code).lines.sort.should == ["finalized\n", "finalized\n"]
- end
- end
-end
diff --git a/spec/ruby/core/method/shared/to_s.rb b/spec/ruby/core/method/shared/to_s.rb
index b2d27d370f..6fdeaaf99c 100644
--- a/spec/ruby/core/method/shared/to_s.rb
+++ b/spec/ruby/core/method/shared/to_s.rb
@@ -53,18 +53,20 @@ describe :method_to_s, shared: true do
MethodSpecs::A.new.method(:baz).send(@method).should.start_with? "#<Method: MethodSpecs::A#baz"
end
- it "returns a String containing the Module containing the method if object has a singleton class but method is not defined in the singleton class" do
- obj = MethodSpecs::MySub.new
- obj.singleton_class
- @m = obj.method(:bar)
- @string = @m.send(@method)
- @string.should.start_with? "#<Method: MethodSpecs::MySub(MethodSpecs::MyMod)#bar"
+ ruby_version_is '3.0' do
+ it "returns a String containing the Module containing the method if object has a singleton class but method is not defined in the singleton class" do
+ obj = MethodSpecs::MySub.new
+ obj.singleton_class
+ @m = obj.method(:bar)
+ @string = @m.send(@method)
+ @string.should.start_with? "#<Method: MethodSpecs::MySub(MethodSpecs::MyMod)#bar"
- c = MethodSpecs::MySub.dup
- m = Module.new{def bar; end}
- c.extend(m)
- @string = c.method(:bar).send(@method)
- @string.should.start_with? "#<Method: #<Class:#{c.inspect}>(#{m.inspect})#bar"
+ c = MethodSpecs::MySub.dup
+ m = Module.new{def bar; end}
+ c.extend(m)
+ @string = c.method(:bar).send(@method)
+ @string.should.start_with? "#<Method: #<Class:#{c.inspect}>(#{m.inspect})#bar"
+ end
end
it "returns a String containing the singleton class if method is defined in the singleton class" do
@@ -75,7 +77,9 @@ describe :method_to_s, shared: true do
@string.should.start_with? "#<Method: #<MethodSpecs::MySub:0xXXXXXX>.bar"
end
- it "shows the metaclass and the owner for a Module instance method retrieved from a class" do
- String.method(:include).inspect.should.start_with?("#<Method: #<Class:String>(Module)#include")
+ ruby_bug '#17428', ''...'3.0' do
+ it "shows the metaclass and the owner for a Module instance method retrieved from a class" do
+ String.method(:include).inspect.should.start_with?("#<Method: #<Class:String>(Module)#include")
+ end
end
end
diff --git a/spec/ruby/core/method/source_location_spec.rb b/spec/ruby/core/method/source_location_spec.rb
index c5b296f6e2..1f476aaa9b 100644
--- a/spec/ruby/core/method/source_location_spec.rb
+++ b/spec/ruby/core/method/source_location_spec.rb
@@ -13,7 +13,7 @@ describe "Method#source_location" do
it "sets the first value to the path of the file in which the method was defined" do
file = @method.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('fixtures/classes.rb', __dir__)
+ file.should == File.realpath('../fixtures/classes.rb', __FILE__)
end
it "sets the last value to an Integer representing the line on which the method was defined" do
@@ -104,13 +104,6 @@ describe "Method#source_location" do
end
end
- it "works for eval with a given line" do
- c = Class.new do
- eval('def self.m; end', nil, "foo", 100)
- end
- c.method(:m).source_location.should == ["foo", 100]
- end
-
describe "for a Method generated by respond_to_missing?" do
it "returns nil" do
m = MethodSpecs::Methods.new
diff --git a/spec/ruby/core/method/super_method_spec.rb b/spec/ruby/core/method/super_method_spec.rb
index c63a7aaa0f..f9a18f3878 100644
--- a/spec/ruby/core/method/super_method_spec.rb
+++ b/spec/ruby/core/method/super_method_spec.rb
@@ -55,10 +55,12 @@ describe "Method#super_method" do
end
end
- context "after aliasing an inherited method" do
- it "returns the expected super_method" do
- method = MethodSpecs::InheritedMethods::C.new.method(:meow)
- method.super_method.owner.should == MethodSpecs::InheritedMethods::A
+ ruby_version_is "2.7.3" do
+ context "after aliasing an inherited method" do
+ it "returns the expected super_method" do
+ method = MethodSpecs::InheritedMethods::C.new.method(:meow)
+ method.super_method.owner.should == MethodSpecs::InheritedMethods::A
+ end
end
end
end
diff --git a/spec/ruby/core/module/alias_method_spec.rb b/spec/ruby/core/module/alias_method_spec.rb
index c36dedd2d8..5d3d0c23d9 100644
--- a/spec/ruby/core/module/alias_method_spec.rb
+++ b/spec/ruby/core/module/alias_method_spec.rb
@@ -81,20 +81,22 @@ describe "Module#alias_method" do
-> { @class.make_alias mock('x'), :public_one }.should raise_error(TypeError)
end
- it "raises a NoMethodError if the given name raises a NoMethodError during type coercion using to_str" do
- obj = mock("mock-name")
- obj.should_receive(:to_str).and_raise(NoMethodError)
- -> { @class.make_alias obj, :public_one }.should raise_error(NoMethodError)
- end
-
it "is a public method" do
Module.should have_public_instance_method(:alias_method, false)
end
describe "returned value" do
- it "returns symbol of the defined method name" do
- @class.send(:alias_method, :checking_return_value, :public_one).should equal(:checking_return_value)
- @class.send(:alias_method, 'checking_return_value', :public_one).should equal(:checking_return_value)
+ ruby_version_is ""..."3.0" do
+ it "returns self" do
+ @class.send(:alias_method, :checking_return_value, :public_one).should equal(@class)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "returns symbol of the defined method name" do
+ @class.send(:alias_method, :checking_return_value, :public_one).should equal(:checking_return_value)
+ @class.send(:alias_method, 'checking_return_value', :public_one).should equal(:checking_return_value)
+ end
end
end
diff --git a/spec/ruby/core/module/attr_accessor_spec.rb b/spec/ruby/core/module/attr_accessor_spec.rb
index eea5b4b64b..ba5289cbea 100644
--- a/spec/ruby/core/module/attr_accessor_spec.rb
+++ b/spec/ruby/core/module/attr_accessor_spec.rb
@@ -80,9 +80,19 @@ describe "Module#attr_accessor" do
Module.should have_public_instance_method(:attr_accessor, false)
end
- it "returns an array of defined method names as symbols" do
- Class.new do
- (attr_accessor :foo, 'bar').should == [:foo, :foo=, :bar, :bar=]
+ ruby_version_is ""..."3.0" do
+ it "returns nil" do
+ Class.new do
+ (attr_accessor :foo, 'bar').should == nil
+ end
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "returns an array of defined method names as symbols" do
+ Class.new do
+ (attr_accessor :foo, 'bar').should == [:foo, :foo=, :bar, :bar=]
+ end
end
end
diff --git a/spec/ruby/core/module/attr_reader_spec.rb b/spec/ruby/core/module/attr_reader_spec.rb
index 0b6d996719..b0ae906ab5 100644
--- a/spec/ruby/core/module/attr_reader_spec.rb
+++ b/spec/ruby/core/module/attr_reader_spec.rb
@@ -62,9 +62,19 @@ describe "Module#attr_reader" do
Module.should have_public_instance_method(:attr_reader, false)
end
- it "returns an array of defined method names as symbols" do
- Class.new do
- (attr_reader :foo, 'bar').should == [:foo, :bar]
+ ruby_version_is ""..."3.0" do
+ it "returns nil" do
+ Class.new do
+ (attr_reader :foo, 'bar').should == nil
+ end
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "returns an array of defined method names as symbols" do
+ Class.new do
+ (attr_reader :foo, 'bar').should == [:foo, :bar]
+ end
end
end
end
diff --git a/spec/ruby/core/module/attr_spec.rb b/spec/ruby/core/module/attr_spec.rb
index 72a6646b1e..33e0eb8628 100644
--- a/spec/ruby/core/module/attr_spec.rb
+++ b/spec/ruby/core/module/attr_spec.rb
@@ -146,11 +146,23 @@ describe "Module#attr" do
Module.should have_public_instance_method(:attr, false)
end
- it "returns an array of defined method names as symbols" do
- Class.new do
- (attr :foo, 'bar').should == [:foo, :bar]
- (attr :baz, false).should == [:baz]
- (attr :qux, true).should == [:qux, :qux=]
+ ruby_version_is ""..."3.0" do
+ it "returns nil" do
+ Class.new do
+ (attr :foo, 'bar').should == nil
+ (attr :baz, false).should == nil
+ (attr :qux, true).should == nil
+ end
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "returns an array of defined method names as symbols" do
+ Class.new do
+ (attr :foo, 'bar').should == [:foo, :bar]
+ (attr :baz, false).should == [:baz]
+ (attr :qux, true).should == [:qux, :qux=]
+ end
end
end
end
diff --git a/spec/ruby/core/module/attr_writer_spec.rb b/spec/ruby/core/module/attr_writer_spec.rb
index aaea0ce43f..0e9d201317 100644
--- a/spec/ruby/core/module/attr_writer_spec.rb
+++ b/spec/ruby/core/module/attr_writer_spec.rb
@@ -72,9 +72,19 @@ describe "Module#attr_writer" do
Module.should have_public_instance_method(:attr_writer, false)
end
- it "returns an array of defined method names as symbols" do
- Class.new do
- (attr_writer :foo, 'bar').should == [:foo=, :bar=]
+ ruby_version_is ""..."3.0" do
+ it "returns nil" do
+ Class.new do
+ (attr_writer :foo, 'bar').should == nil
+ end
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "returns an array of defined method names as symbols" do
+ Class.new do
+ (attr_writer :foo, 'bar').should == [:foo=, :bar=]
+ end
end
end
end
diff --git a/spec/ruby/core/module/const_added_spec.rb b/spec/ruby/core/module/const_added_spec.rb
index f9edda3a07..31ac6eb105 100644
--- a/spec/ruby/core/module/const_added_spec.rb
+++ b/spec/ruby/core/module/const_added_spec.rb
@@ -121,40 +121,5 @@ describe "Module#const_added" do
ScratchPad.recorded.should == [line + 2, line + 4, line + 7, line + 11]
end
-
- it "is called when the constant is already assigned a value" do
- ScratchPad.record []
-
- mod = Module.new do
- def self.const_added(name)
- ScratchPad.record const_get(name)
- end
- end
-
- mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
- TEST = 123
- RUBY
-
- ScratchPad.recorded.should == 123
- end
-
- it "records re-definition of existing constants" do
- ScratchPad.record []
-
- mod = Module.new do
- def self.const_added(name)
- ScratchPad << const_get(name)
- end
- end
-
- -> {
- mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
- TEST = 123
- TEST = 456
- RUBY
- }.should complain(/warning: already initialized constant .+::TEST/)
-
- ScratchPad.recorded.should == [123, 456]
- end
end
end
diff --git a/spec/ruby/core/module/const_defined_spec.rb b/spec/ruby/core/module/const_defined_spec.rb
index 027cf5a245..0c15629c08 100644
--- a/spec/ruby/core/module/const_defined_spec.rb
+++ b/spec/ruby/core/module/const_defined_spec.rb
@@ -80,23 +80,10 @@ describe "Module#const_defined?" do
ConstantSpecs::ClassA.const_defined?(:CS_CONSTX).should == false
end
- describe "converts the given name to a String using #to_str" do
- it "calls #to_str to convert the given name to a String" do
- name = mock("ClassA")
- name.should_receive(:to_str).and_return("ClassA")
- ConstantSpecs.const_defined?(name).should == true
- end
-
- it "raises a TypeError if the given name can't be converted to a String" do
- -> { ConstantSpecs.const_defined?(nil) }.should raise_error(TypeError)
- -> { ConstantSpecs.const_defined?([]) }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to a String" do
- name = mock("classA")
- name.should_receive(:to_str).and_raise(NoMethodError)
- -> { ConstantSpecs.const_defined?(name) }.should raise_error(NoMethodError)
- end
+ it "calls #to_str to convert the given name to a String" do
+ name = mock("ClassA")
+ name.should_receive(:to_str).and_return("ClassA")
+ ConstantSpecs.const_defined?(name).should == true
end
it "special cases Object and checks it's included Modules" do
diff --git a/spec/ruby/core/module/const_get_spec.rb b/spec/ruby/core/module/const_get_spec.rb
index 0233118f4b..69f181cf51 100644
--- a/spec/ruby/core/module/const_get_spec.rb
+++ b/spec/ruby/core/module/const_get_spec.rb
@@ -105,7 +105,7 @@ describe "Module#const_get" do
-> { ConstantSpecs.const_get("CS_CONST1", false) }.should raise_error(NameError)
end
- it "returns a constant whose module is defined the toplevel" do
+ it "returns a constant whose module is defined the the toplevel" do
ConstantSpecs.const_get("ConstantSpecsTwo::Foo").should == :cs_two_foo
ConstantSpecsThree.const_get("ConstantSpecsTwo::Foo").should == :cs_three_foo
end
diff --git a/spec/ruby/core/module/const_set_spec.rb b/spec/ruby/core/module/const_set_spec.rb
index 5bdfd7b68f..ba7810d17b 100644
--- a/spec/ruby/core/module/const_set_spec.rb
+++ b/spec/ruby/core/module/const_set_spec.rb
@@ -20,10 +20,20 @@ describe "Module#const_set" do
m.name.should == "ConstantSpecs::CS_CONST1000"
end
- it "sets the name of a module scoped by an anonymous module" do
- a, b = Module.new, Module.new
- a.const_set :B, b
- b.name.should.end_with? '::B'
+ ruby_version_is ""..."3.0" do
+ it "does not set the name of a module scoped by an anonymous module" do
+ a, b = Module.new, Module.new
+ a.const_set :B, b
+ b.name.should be_nil
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "sets the name of a module scoped by an anonymous module" do
+ a, b = Module.new, Module.new
+ a.const_set :B, b
+ b.name.should.end_with? '::B'
+ end
end
it "sets the name of contained modules when assigning a toplevel anonymous module" do
diff --git a/spec/ruby/core/module/const_source_location_spec.rb b/spec/ruby/core/module/const_source_location_spec.rb
index ded2aa51d7..11a2e74756 100644
--- a/spec/ruby/core/module/const_source_location_spec.rb
+++ b/spec/ruby/core/module/const_source_location_spec.rb
@@ -67,11 +67,6 @@ describe "Module#const_source_location" do
end
describe "with statically assigned constants" do
- it "works for the module and class keywords" do
- ConstantSpecs.const_source_location(:ModuleB).should == [@constants_fixture_path, ConstantSpecs::ModuleB::LINE]
- ConstantSpecs.const_source_location(:ClassA).should == [@constants_fixture_path, ConstantSpecs::ClassA::LINE]
- end
-
it "searches location path the immediate class or module first" do
ConstantSpecs::ClassA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE]
ConstantSpecs::ModuleA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST10_LINE]
@@ -138,7 +133,7 @@ describe "Module#const_source_location" do
it "calls #to_str to convert the given name to a String" do
name = mock("ClassA")
name.should_receive(:to_str).and_return("ClassA")
- ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::LINE]
+ ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CLASS_A_LINE]
end
it "raises a TypeError if conversion to a String by calling #to_str fails" do
@@ -210,13 +205,6 @@ describe "Module#const_source_location" do
ConstantSpecs.const_source_location(:CS_PRIVATE).should == [@constants_fixture_path, ConstantSpecs::CS_PRIVATE_LINE]
end
- it "works for eval with a given line" do
- c = Class.new do
- eval('self::C = 1', nil, "foo", 100)
- end
- c.const_source_location(:C).should == ["foo", 100]
- end
-
context 'autoload' do
before :all do
ConstantSpecs.autoload :CSL_CONST1, "#{__dir__}/notexisting.rb"
diff --git a/spec/ruby/core/module/define_method_spec.rb b/spec/ruby/core/module/define_method_spec.rb
index e04bb87ceb..ce94436bfd 100644
--- a/spec/ruby/core/module/define_method_spec.rb
+++ b/spec/ruby/core/module/define_method_spec.rb
@@ -133,17 +133,6 @@ describe "Module#define_method when name is not a special private name" do
klass.should have_public_instance_method(:baz)
end
end
-
- it "sets the method owner for a dynamically added method with a different original owner" do
- mixin_module = Module.new do
- def bar; end
- end
-
- foo = Object.new
- foo.singleton_class.define_method(:bar, mixin_module.instance_method(:bar))
-
- foo.method(:bar).owner.should == foo.singleton_class
- end
end
describe "passed a block" do
@@ -499,33 +488,6 @@ describe "Module#define_method" do
Class.new { define_method :bar, m }
}.should raise_error(TypeError, /can't bind singleton method to a different class/)
end
-
- it "defines a new method with public visibility when a Method passed and the class/module of the context isn't equal to the receiver of #define_method" do
- c = Class.new do
- private def foo
- "public"
- end
- end
-
- object = c.new
- object.singleton_class.define_method(:bar, object.method(:foo))
-
- object.bar.should == "public"
- end
-
- it "defines the new method according to the scope visibility when a Method passed and the class/module of the context is equal to the receiver of #define_method" do
- c = Class.new do
- def foo; end
- end
-
- object = c.new
- object.singleton_class.class_eval do
- private
- define_method(:bar, c.new.method(:foo))
- end
-
- -> { object.bar }.should raise_error(NoMethodError)
- end
end
describe "Module#define_method" do
@@ -724,7 +686,7 @@ describe "Module#define_method" do
end
end
-describe "Module#define_method when passed a Method object" do
+describe "Method#define_method when passed a Method object" do
before :each do
@klass = Class.new do
def m(a, b, *c)
@@ -749,7 +711,7 @@ describe "Module#define_method when passed a Method object" do
end
end
-describe "Module#define_method when passed an UnboundMethod object" do
+describe "Method#define_method when passed an UnboundMethod object" do
before :each do
@klass = Class.new do
def m(a, b, *c)
@@ -774,7 +736,7 @@ describe "Module#define_method when passed an UnboundMethod object" do
end
end
-describe "Module#define_method when passed a Proc object" do
+describe "Method#define_method when passed a Proc object" do
describe "and a method is defined inside" do
it "defines the nested method in the default definee where the Proc was created" do
prc = nil
@@ -799,7 +761,7 @@ describe "Module#define_method when passed a Proc object" do
end
end
-describe "Module#define_method when passed a block" do
+describe "Method#define_method when passed a block" do
describe "behaves exactly like a lambda" do
it "for return" do
Class.new do
diff --git a/spec/ruby/core/module/fixtures/classes.rb b/spec/ruby/core/module/fixtures/classes.rb
index a434e7b0b8..bc6b940a6c 100644
--- a/spec/ruby/core/module/fixtures/classes.rb
+++ b/spec/ruby/core/module/fixtures/classes.rb
@@ -596,32 +596,6 @@ module ModuleSpecs
private :foo
end
EmptyFooMethod = m.instance_method(:foo)
-
- # for undefined_instance_methods spec
- module UndefinedInstanceMethods
- module Super
- def super_included_method; end
- end
-
- class Parent
- def undefed_method; end
- undef_method :undefed_method
-
- def parent_method; end
- def another_parent_method; end
- end
-
- class Child < Parent
- include Super
-
- undef_method :parent_method
- undef_method :another_parent_method
- end
-
- class Grandchild < Child
- undef_method :super_included_method
- end
- end
end
class Object
diff --git a/spec/ruby/core/module/fixtures/module.rb b/spec/ruby/core/module/fixtures/module.rb
index 34543ca2b4..9050a272ec 100644
--- a/spec/ruby/core/module/fixtures/module.rb
+++ b/spec/ruby/core/module/fixtures/module.rb
@@ -1,8 +1,4 @@
module ModuleSpecs
module Anonymous
- module Child
- end
-
- SameChild = Child
end
end
diff --git a/spec/ruby/core/module/method_added_spec.rb b/spec/ruby/core/module/method_added_spec.rb
index ec92cddc1e..b983c8da76 100644
--- a/spec/ruby/core/module/method_added_spec.rb
+++ b/spec/ruby/core/module/method_added_spec.rb
@@ -2,10 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Module#method_added" do
- before :each do
- ScratchPad.record []
- end
-
it "is a private instance method" do
Module.should have_private_instance_method(:method_added)
end
@@ -17,6 +13,8 @@ describe "Module#method_added" do
end
it "is called when a new instance method is defined in self" do
+ ScratchPad.record []
+
Module.new do
def self.method_added(name)
ScratchPad << name
@@ -34,6 +32,8 @@ describe "Module#method_added" do
it "is not called when a singleton method is added" do
# obj.singleton_method_added is called instead
+ ScratchPad.record []
+
klass = Class.new
def klass.method_added(name)
ScratchPad << name
@@ -60,71 +60,8 @@ describe "Module#method_added" do
m.should_not have_method(:method_to_undef)
end
- it "is not called when a method changes visibility" do
- Module.new do
- def public_method
- end
-
- def private_method
- end
-
- def self.method_added(name)
- ScratchPad << name
- end
-
- public :public_method
- private :public_method
-
- private :private_method
- public :private_method
- end
-
- ScratchPad.recorded.should == []
- end
-
- it "is called when using #private in a subclass" do
- parent = Class.new do
- def foo
- end
- end
-
- Class.new(parent) do
- def self.method_added(name)
- ScratchPad << name
- end
-
- # Create an instance as that might initialize some method lookup caches, which is interesting to test
- self.new.foo
-
- private :foo
- public :foo
- end
-
- ScratchPad.recorded.should == [:foo]
- end
-
- it "is not called when a method is copied via module_function, rather #singleton_method_added is called" do
- Module.new do
- def mod_function
- end
-
- def self.method_added(name)
- ScratchPad << [:method_added, name]
- end
-
- def self.singleton_method_added(name)
- ScratchPad << [:singleton_method_added, name]
- end
-
- ScratchPad.record []
-
- module_function :mod_function
- end
-
- ScratchPad.recorded.should == [[:singleton_method_added, :mod_function]]
- end
-
it "is called with a precise caller location with the line of the 'def'" do
+ ScratchPad.record []
line = nil
Module.new do
diff --git a/spec/ruby/core/module/module_function_spec.rb b/spec/ruby/core/module/module_function_spec.rb
index 1c3ec5471b..0602e95ca9 100644
--- a/spec/ruby/core/module/module_function_spec.rb
+++ b/spec/ruby/core/module/module_function_spec.rb
@@ -155,62 +155,15 @@ describe "Module#module_function with specific method names" do
m.foo.should == ["m", "super_m"]
end
-
- context "methods created with define_method" do
- context "passed a block" do
- it "creates duplicates of the given instance methods" do
- m = Module.new do
- define_method :test1 do; end
- module_function :test1
- end
-
- m.respond_to?(:test1).should == true
- end
- end
-
- context "passed a method" do
- it "creates duplicates of the given instance methods" do
- module_with_method = Module.new do
- def test1; end
- end
-
- c = Class.new do
- extend module_with_method
- end
-
- m = Module.new do
- define_method :test2, c.method(:test1)
- module_function :test2
- end
-
- m.respond_to?(:test2).should == true
- end
- end
-
- context "passed an unbound method" do
- it "creates duplicates of the given instance methods" do
- module_with_method = Module.new do
- def test1; end
- end
-
- m = Module.new do
- define_method :test2, module_with_method.instance_method(:test1)
- module_function :test2
- end
-
- m.respond_to?(:test2).should == true
- end
- end
- end
end
describe "Module#module_function as a toggle (no arguments) in a Module body" do
it "makes any subsequently defined methods module functions with the normal semantics" do
- m = Module.new do
+ m = Module.new {
module_function
def test1() end
def test2() end
- end
+ }
m.respond_to?(:test1).should == true
m.respond_to?(:test2).should == true
@@ -234,13 +187,13 @@ describe "Module#module_function as a toggle (no arguments) in a Module body" do
it "stops creating module functions if the body encounters another toggle " \
"like public/protected/private without arguments" do
- m = Module.new do
+ m = Module.new {
module_function
def test1() end
def test2() end
public
def test3() end
- end
+ }
m.respond_to?(:test1).should == true
m.respond_to?(:test2).should == true
@@ -249,14 +202,14 @@ describe "Module#module_function as a toggle (no arguments) in a Module body" do
it "does not stop creating module functions if the body encounters " \
"public/protected/private WITH arguments" do
- m = Module.new do
+ m = Module.new {
def foo() end
module_function
def test1() end
def test2() end
public :foo
def test3() end
- end
+ }
m.respond_to?(:test1).should == true
m.respond_to?(:test2).should == true
@@ -264,116 +217,69 @@ describe "Module#module_function as a toggle (no arguments) in a Module body" do
end
it "does not affect module_evaled method definitions also if outside the eval itself" do
- m = Module.new do
+ m = Module.new {
module_function
module_eval { def test1() end }
module_eval " def test2() end "
- end
+ }
m.respond_to?(:test1).should == false
m.respond_to?(:test2).should == false
end
it "has no effect if inside a module_eval if the definitions are outside of it" do
- m = Module.new do
+ m = Module.new {
module_eval { module_function }
def test1() end
def test2() end
- end
+ }
m.respond_to?(:test1).should == false
m.respond_to?(:test2).should == false
end
it "functions normally if both toggle and definitions inside a module_eval" do
- m = Module.new do
- module_eval do
+ m = Module.new {
+ module_eval {
module_function
def test1() end
def test2() end
- end
- end
+ }
+ }
m.respond_to?(:test1).should == true
m.respond_to?(:test2).should == true
end
- it "affects eval'ed method definitions also even when outside the eval itself" do
- m = Module.new do
+ it "affects evaled method definitions also even when outside the eval itself" do
+ m = Module.new {
module_function
eval "def test1() end"
- end
+ }
m.respond_to?(:test1).should == true
end
it "doesn't affect definitions when inside an eval even if the definitions are outside of it" do
- m = Module.new do
+ m = Module.new {
eval "module_function"
def test1() end
- end
+ }
m.respond_to?(:test1).should == false
end
it "functions normally if both toggle and definitions inside a eval" do
- m = Module.new do
+ m = Module.new {
eval <<-CODE
module_function
def test1() end
def test2() end
CODE
- end
+ }
m.respond_to?(:test1).should == true
m.respond_to?(:test2).should == true
end
-
- context "methods are defined with define_method" do
- context "passed a block" do
- it "makes any subsequently defined methods module functions with the normal semantics" do
- m = Module.new do
- module_function
- define_method :test1 do; end
- end
-
- m.respond_to?(:test1).should == true
- end
- end
-
- context "passed a method" do
- it "makes any subsequently defined methods module functions with the normal semantics" do
- module_with_method = Module.new do
- def test1; end
- end
-
- c = Class.new do
- extend module_with_method
- end
-
- m = Module.new do
- module_function
- define_method :test2, c.method(:test1)
- end
-
- m.respond_to?(:test2).should == true
- end
- end
-
- context "passed an unbound method" do
- it "makes any subsequently defined methods module functions with the normal semantics" do
- module_with_method = Module.new do
- def test1; end
- end
-
- m = Module.new do
- module_function
- define_method :test2, module_with_method.instance_method(:test1)
- end
-
- m.respond_to?(:test2).should == true
- end
- end
- end
end
diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb
index 0d1f4e24d5..b78bbfcc80 100644
--- a/spec/ruby/core/module/name_spec.rb
+++ b/spec/ruby/core/module/name_spec.rb
@@ -6,10 +6,20 @@ describe "Module#name" do
Module.new.name.should be_nil
end
- it "is not nil when assigned to a constant in an anonymous module" do
- m = Module.new
- m::N = Module.new
- m::N.name.should.end_with? '::N'
+ ruby_version_is ""..."3.0" do
+ it "is nil when assigned to a constant in an anonymous module" do
+ m = Module.new
+ m::N = Module.new
+ m::N.name.should be_nil
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "is not nil when assigned to a constant in an anonymous module" do
+ m = Module.new
+ m::N = Module.new
+ m::N.name.should.end_with? '::N'
+ end
end
it "is not nil for a nested module created with the module keyword" do
@@ -32,19 +42,6 @@ describe "Module#name" do
m::N.name.should == "ModuleSpecs::Anonymous::WasAnnon"
end
- it "may be the repeated in different module objects" do
- m = Module.new
- n = Module.new
-
- suppress_warning do
- ModuleSpecs::Anonymous::SameName = m
- ModuleSpecs::Anonymous::SameName = n
- end
-
- m.name.should == "ModuleSpecs::Anonymous::SameName"
- n.name.should == "ModuleSpecs::Anonymous::SameName"
- end
-
it "is set after it is removed from a constant" do
module ModuleSpecs
module ModuleToRemove
@@ -72,18 +69,12 @@ describe "Module#name" do
ModuleSpecs::Anonymous.name.should == "ModuleSpecs::Anonymous"
end
- it "is set when assigning to a constant (constant path matches outer module name)" do
+ it "is set when assigning to a constant" do
m = Module.new
ModuleSpecs::Anonymous::A = m
m.name.should == "ModuleSpecs::Anonymous::A"
end
- it "is set when assigning to a constant (constant path does not match outer module name)" do
- m = Module.new
- ModuleSpecs::Anonymous::SameChild::A = m
- m.name.should == "ModuleSpecs::Anonymous::Child::A"
- end
-
it "is not modified when assigning to a new constant after it has been accessed" do
m = Module.new
ModuleSpecs::Anonymous::B = m
@@ -120,26 +111,13 @@ describe "Module#name" do
ModuleSpecs::NameEncoding.new.name.encoding.should == Encoding::UTF_8
end
- it "is set when the anonymous outer module name is set (module in one single constant)" do
+ it "is set when the anonymous outer module name is set" do
m = Module.new
m::N = Module.new
ModuleSpecs::Anonymous::E = m
m::N.name.should == "ModuleSpecs::Anonymous::E::N"
end
- # https://bugs.ruby-lang.org/issues/19681
- it "is set when the anonymous outer module name is set (module in several constants)" do
- m = Module.new
- m::N = Module.new
- m::O = m::N
- ModuleSpecs::Anonymous::StoredInMultiplePlaces = m
- valid_names = [
- "ModuleSpecs::Anonymous::StoredInMultiplePlaces::N",
- "ModuleSpecs::Anonymous::StoredInMultiplePlaces::O"
- ]
- valid_names.should include(m::N.name) # You get one of the two, but you don't know which one.
- end
-
it "returns a frozen String" do
ModuleSpecs.name.should.frozen?
end
diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb
index 96598e7209..976b09b105 100644
--- a/spec/ruby/core/module/prepend_spec.rb
+++ b/spec/ruby/core/module/prepend_spec.rb
@@ -499,17 +499,34 @@ describe "Module#prepend" do
c.dup.new.should be_kind_of(m)
end
- it "uses only new module when dupping the module" do
- m1 = Module.new { def calc(x) x end }
- m2 = Module.new { prepend(m1) }
- c1 = Class.new { prepend(m2) }
- m2dup = m2.dup
- m2dup.ancestors.should == [m1,m2dup]
- c2 = Class.new { prepend(m2dup) }
- c1.ancestors[0,3].should == [m1,m2,c1]
- c1.new.should be_kind_of(m1)
- c2.ancestors[0,3].should == [m1,m2dup,c2]
- c2.new.should be_kind_of(m1)
+ ruby_version_is ''...'3.0' do
+ it "keeps the module in the chain when dupping an intermediate module" do
+ m1 = Module.new { def calc(x) x end }
+ m2 = Module.new { prepend(m1) }
+ c1 = Class.new { prepend(m2) }
+ m2dup = m2.dup
+ m2dup.ancestors.should == [m2dup,m1,m2]
+ c2 = Class.new { prepend(m2dup) }
+ c1.ancestors[0,3].should == [m1,m2,c1]
+ c1.new.should be_kind_of(m1)
+ c2.ancestors[0,4].should == [m2dup,m1,m2,c2]
+ c2.new.should be_kind_of(m1)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "uses only new module when dupping the module" do
+ m1 = Module.new { def calc(x) x end }
+ m2 = Module.new { prepend(m1) }
+ c1 = Class.new { prepend(m2) }
+ m2dup = m2.dup
+ m2dup.ancestors.should == [m1,m2dup]
+ c2 = Class.new { prepend(m2dup) }
+ c1.ancestors[0,3].should == [m1,m2,c1]
+ c1.new.should be_kind_of(m1)
+ c2.ancestors[0,3].should == [m1,m2dup,c2]
+ c2.new.should be_kind_of(m1)
+ end
end
it "depends on prepend_features to add the module" do
diff --git a/spec/ruby/core/module/private_class_method_spec.rb b/spec/ruby/core/module/private_class_method_spec.rb
index f899c71a57..407779cccc 100644
--- a/spec/ruby/core/module/private_class_method_spec.rb
+++ b/spec/ruby/core/module/private_class_method_spec.rb
@@ -79,13 +79,15 @@ describe "Module#private_class_method" do
end.should raise_error(NameError)
end
- context "when single argument is passed and is an array" do
- it "sets the visibility of the given methods to private" do
- c = Class.new do
- def self.foo() "foo" end
- private_class_method [:foo]
+ ruby_version_is "3.0" do
+ context "when single argument is passed and is an array" do
+ it "sets the visibility of the given methods to private" do
+ c = Class.new do
+ def self.foo() "foo" end
+ private_class_method [:foo]
+ end
+ -> { c.foo }.should raise_error(NoMethodError)
end
- -> { c.foo }.should raise_error(NoMethodError)
end
end
end
diff --git a/spec/ruby/core/module/public_class_method_spec.rb b/spec/ruby/core/module/public_class_method_spec.rb
index 71b20acda5..b5d76e7b7a 100644
--- a/spec/ruby/core/module/public_class_method_spec.rb
+++ b/spec/ruby/core/module/public_class_method_spec.rb
@@ -78,17 +78,19 @@ describe "Module#public_class_method" do
end.should raise_error(NameError)
end
- context "when single argument is passed and is an array" do
- it "makes a class method public" do
- c = Class.new do
- class << self
- private
- def foo() "foo" end
+ ruby_version_is "3.0" do
+ context "when single argument is passed and is an array" do
+ it "makes a class method public" do
+ c = Class.new do
+ class << self
+ private
+ def foo() "foo" end
+ end
+ public_class_method [:foo]
end
- public_class_method [:foo]
- end
- c.foo.should == "foo"
+ c.foo.should == "foo"
+ end
end
end
end
diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb
index 11085c325b..841900cf87 100644
--- a/spec/ruby/core/module/refine_spec.rb
+++ b/spec/ruby/core/module/refine_spec.rb
@@ -71,7 +71,7 @@ describe "Module#refine" do
Module.new do
refine("foo") {}
end
- end.should raise_error(TypeError, "wrong argument type String (expected Class or Module)")
+ end.should raise_error(TypeError)
end
it "accepts a module as argument" do
diff --git a/spec/ruby/core/module/refinements_spec.rb b/spec/ruby/core/module/refinements_spec.rb
deleted file mode 100644
index 5648fcbd6f..0000000000
--- a/spec/ruby/core/module/refinements_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Module#refinements" do
- ruby_version_is "3.2" do
- it "returns refinements defined in a module" do
- ScratchPad.record []
-
- m = Module.new do
- refine String do
- ScratchPad << self
- end
-
- refine Array do
- ScratchPad << self
- end
- end
-
- m.refinements.sort_by(&:object_id).should == ScratchPad.recorded.sort_by(&:object_id)
- end
-
- it "does not return refinements defined in the included module" do
- ScratchPad.record []
-
- m1 = Module.new do
- refine Integer do
- nil
- end
- end
-
- m2 = Module.new do
- include m1
-
- refine String do
- ScratchPad << self
- end
- end
-
- m2.refinements.should == ScratchPad.recorded
- end
-
- it "returns an empty array if no refinements defined in a module" do
- Module.new.refinements.should == []
- end
- end
-end
diff --git a/spec/ruby/core/module/ruby2_keywords_spec.rb b/spec/ruby/core/module/ruby2_keywords_spec.rb
index a72612a670..80a99e2624 100644
--- a/spec/ruby/core/module/ruby2_keywords_spec.rb
+++ b/spec/ruby/core/module/ruby2_keywords_spec.rb
@@ -22,6 +22,9 @@ describe "Module#ruby2_keywords" do
end
h = {a: 1}
+ ruby_version_is "3.0" do
+ obj.regular(**h).should.equal?(h)
+ end
last = mark(**h).last
Hash.ruby2_keywords_hash?(last).should == true
@@ -220,6 +223,25 @@ describe "Module#ruby2_keywords" do
Hash.ruby2_keywords_hash?(last).should == true
end
+ ruby_version_is ""..."3.0" do
+ it "fixes delegation warnings when calling a method accepting keywords" do
+ obj = Object.new
+
+ obj.singleton_class.class_exec do
+ def foo(*a) bar(*a) end
+ def bar(*a, **b) end
+ end
+
+ -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/)
+
+ obj.singleton_class.class_exec do
+ ruby2_keywords :foo
+ end
+
+ -> { obj.foo(1, 2, {a: "a"}) }.should_not complain
+ end
+ end
+
it "returns nil" do
obj = Object.new
diff --git a/spec/ruby/core/module/set_temporary_name_spec.rb b/spec/ruby/core/module/set_temporary_name_spec.rb
deleted file mode 100644
index f5886a3398..0000000000
--- a/spec/ruby/core/module/set_temporary_name_spec.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require_relative '../../spec_helper'
-
-ruby_version_is "3.3" do
- describe "Module#set_temporary_name" do
- it "can assign a temporary name" do
- m = Module.new
- m.name.should be_nil
-
- m.set_temporary_name("fake_name")
- m.name.should == "fake_name"
-
- m.set_temporary_name(nil)
- m.name.should be_nil
- end
-
- it "can assign a temporary name which is not a valid constant path" do
- m = Module.new
- m.set_temporary_name("a::B")
- m.name.should == "a::B"
-
- m.set_temporary_name("Template['foo.rb']")
- m.name.should == "Template['foo.rb']"
- end
-
- it "can't assign empty string as name" do
- m = Module.new
- -> { m.set_temporary_name("") }.should raise_error(ArgumentError, "empty class/module name")
- end
-
- it "can't assign a constant name as a temporary name" do
- m = Module.new
- -> { m.set_temporary_name("Object") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
- end
-
- it "can't assign a constant path as a temporary name" do
- m = Module.new
- -> { m.set_temporary_name("A::B") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
- -> { m.set_temporary_name("::A") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
- -> { m.set_temporary_name("::A::B") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
- end
-
- it "can't assign name to permanent module" do
- -> { Object.set_temporary_name("fake_name") }.should raise_error(RuntimeError, "can't change permanent name")
- end
-
- it "can assign a temporary name to a nested module" do
- m = Module.new
- module m::N; end
- m::N.name.should =~ /\A#<Module:0x\h+>::N\z/
-
- m::N.set_temporary_name("fake_name")
- m::N.name.should == "fake_name"
-
- m::N.set_temporary_name(nil)
- m::N.name.should be_nil
- end
-
- it "can update the name when assigned to a constant" do
- m = Module.new
- m::N = Module.new
- m::N.name.should =~ /\A#<Module:0x\h+>::N\z/
- m::N.set_temporary_name(nil)
-
- m::M = m::N
- m::M.name.should =~ /\A#<Module:0x\h+>::M\z/m
- end
- end
-end
diff --git a/spec/ruby/core/module/shared/class_eval.rb b/spec/ruby/core/module/shared/class_eval.rb
index b1d5cb3814..9ef7b5be44 100644
--- a/spec/ruby/core/module/shared/class_eval.rb
+++ b/spec/ruby/core/module/shared/class_eval.rb
@@ -52,12 +52,6 @@ describe :module_class_eval, shared: true do
ModuleSpecs.send(@method, "[__FILE__, __LINE__]", "test", 102).should == ["test", 102]
end
- ruby_version_is "3.3" do
- it "uses the caller location as default filename" do
- ModuleSpecs.send(@method, "[__FILE__, __LINE__]").should == ["(eval at #{__FILE__}:#{__LINE__})", 1]
- end
- end
-
it "converts a non-string filename to a string using to_str" do
(file = mock(__FILE__)).should_receive(:to_str).and_return(__FILE__)
ModuleSpecs.send(@method, "1+1", file)
diff --git a/spec/ruby/core/module/shared/set_visibility.rb b/spec/ruby/core/module/shared/set_visibility.rb
index a1586dd2bd..9f31e230ca 100644
--- a/spec/ruby/core/module/shared/set_visibility.rb
+++ b/spec/ruby/core/module/shared/set_visibility.rb
@@ -22,19 +22,21 @@ describe :set_visibility, shared: true do
end
end
- describe "array as a single argument" do
- it "sets visibility of given method names" do
- visibility = @method
- old_visibility = [:protected, :private].find {|vis| vis != visibility }
-
- mod = Module.new {
- send old_visibility
- def test1() end
- def test2() end
- send visibility, [:test1, :test2]
- }
- mod.should send(:"have_#{visibility}_instance_method", :test1, false)
- mod.should send(:"have_#{visibility}_instance_method", :test2, false)
+ ruby_version_is "3.0" do
+ describe "array as a single argument" do
+ it "sets visibility of given method names" do
+ visibility = @method
+ old_visibility = [:protected, :private].find {|vis| vis != visibility }
+
+ mod = Module.new {
+ send old_visibility
+ def test1() end
+ def test2() end
+ send visibility, [:test1, :test2]
+ }
+ mod.should send(:"have_#{visibility}_instance_method", :test1, false)
+ mod.should send(:"have_#{visibility}_instance_method", :test2, false)
+ end
end
end
diff --git a/spec/ruby/core/module/undefined_instance_methods_spec.rb b/spec/ruby/core/module/undefined_instance_methods_spec.rb
deleted file mode 100644
index 3be860d053..0000000000
--- a/spec/ruby/core/module/undefined_instance_methods_spec.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
-
-describe "Module#undefined_instance_methods" do
- ruby_version_is "3.2" do
- it "returns methods undefined in the class" do
- methods = ModuleSpecs::UndefinedInstanceMethods::Parent.undefined_instance_methods
- methods.should == [:undefed_method]
- end
-
- it "returns inherited methods undefined in the class" do
- methods = ModuleSpecs::UndefinedInstanceMethods::Child.undefined_instance_methods
- methods.should include(:parent_method, :another_parent_method)
- end
-
- it "returns methods from an included module that are undefined in the class" do
- methods = ModuleSpecs::UndefinedInstanceMethods::Grandchild.undefined_instance_methods
- methods.should include(:super_included_method)
- end
-
- it "does not returns ancestors undefined methods" do
- methods = ModuleSpecs::UndefinedInstanceMethods::Grandchild.undefined_instance_methods
- methods.should_not include(:parent_method, :another_parent_method)
- end
- end
-end
diff --git a/spec/ruby/core/module/used_refinements_spec.rb b/spec/ruby/core/module/used_refinements_spec.rb
deleted file mode 100644
index c16cab0e3c..0000000000
--- a/spec/ruby/core/module/used_refinements_spec.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Module.used_refinements" do
- ruby_version_is "3.2" do
- it "returns list of all refinements imported in the current scope" do
- refinement_int = nil
- refinement_str = nil
- ScratchPad.record []
-
- m1 = Module.new do
- refine Integer do
- refinement_int = self
- end
- end
-
- m2 = Module.new do
- refine String do
- refinement_str = self
- end
- end
-
- Module.new do
- using m1
- using m2
-
- Module.used_refinements.each { |r| ScratchPad << r }
- end
-
- ScratchPad.recorded.sort_by(&:object_id).should == [refinement_int, refinement_str].sort_by(&:object_id)
- end
-
- it "returns empty array if does not have any refinements imported" do
- used_refinements = nil
-
- Module.new do
- used_refinements = Module.used_refinements
- end
-
- used_refinements.should == []
- end
-
- it "ignores refinements imported in a module that is included into the current one" do
- used_refinements = nil
-
- m1 = Module.new do
- refine Integer do
- nil
- end
- end
-
- m2 = Module.new do
- using m1
- end
-
- Module.new do
- include m2
-
- used_refinements = Module.used_refinements
- end
-
- used_refinements.should == []
- end
-
- it "returns refinements even not defined directly in a module refinements are imported from" do
- used_refinements = nil
- ScratchPad.record []
-
- m1 = Module.new do
- refine Integer do
- ScratchPad << self
- end
- end
-
- m2 = Module.new do
- include m1
- end
-
- Module.new do
- using m2
-
- used_refinements = Module.used_refinements
- end
-
- used_refinements.should == ScratchPad.recorded
- end
- end
-end
diff --git a/spec/ruby/core/mutex/lock_spec.rb b/spec/ruby/core/mutex/lock_spec.rb
index e9d33f5fd9..7a39817b11 100644
--- a/spec/ruby/core/mutex/lock_spec.rb
+++ b/spec/ruby/core/mutex/lock_spec.rb
@@ -1,6 +1,10 @@
require_relative '../../spec_helper'
describe "Mutex#lock" do
+ before :each do
+ ScratchPad.clear
+ end
+
it "returns self" do
m = Mutex.new
m.lock.should == m
diff --git a/spec/ruby/core/mutex/owned_spec.rb b/spec/ruby/core/mutex/owned_spec.rb
index 7bfc7d8f83..1f843cd576 100644
--- a/spec/ruby/core/mutex/owned_spec.rb
+++ b/spec/ruby/core/mutex/owned_spec.rb
@@ -41,13 +41,15 @@ describe "Mutex#owned?" do
end
end
- it "is held per Fiber" do
- m = Mutex.new
- m.lock
-
- Fiber.new do
- m.locked?.should == true
- m.owned?.should == false
- end.resume
+ ruby_version_is "3.0" do
+ it "is held per Fiber" do
+ m = Mutex.new
+ m.lock
+
+ Fiber.new do
+ m.locked?.should == true
+ m.owned?.should == false
+ end.resume
+ end
end
end
diff --git a/spec/ruby/core/nil/singleton_method_spec.rb b/spec/ruby/core/nil/singleton_method_spec.rb
deleted file mode 100644
index 8d898b1cc9..0000000000
--- a/spec/ruby/core/nil/singleton_method_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "NilClass#singleton_method" do
- ruby_version_is '3.3' do
- it "raises regardless of whether NilClass defines the method" do
- -> { nil.singleton_method(:foo) }.should raise_error(NameError)
- begin
- def (nil).foo; end
- -> { nil.singleton_method(:foo) }.should raise_error(NameError)
- ensure
- NilClass.send(:remove_method, :foo)
- end
- end
- end
-end
diff --git a/spec/ruby/core/numeric/clone_spec.rb b/spec/ruby/core/numeric/clone_spec.rb
index 423cec85dd..c3b06ca0c9 100644
--- a/spec/ruby/core/numeric/clone_spec.rb
+++ b/spec/ruby/core/numeric/clone_spec.rb
@@ -14,7 +14,7 @@ describe "Numeric#clone" do
1.clone.frozen?.should == true
end
- it "accepts optional keyword argument :freeze" do
+ it "accepts optonal keyword argument :freeze" do
value = 1
value.clone(freeze: true).should equal(value)
end
@@ -23,8 +23,10 @@ describe "Numeric#clone" do
-> { 1.clone(freeze: false) }.should raise_error(ArgumentError, /can't unfreeze/)
end
- it "does not change frozen status if passed freeze: nil" do
- value = 1
- value.clone(freeze: nil).should equal(value)
+ ruby_version_is "3.0" do
+ it "does not change frozen status if passed freeze: nil" do
+ value = 1
+ value.clone(freeze: nil).should equal(value)
+ end
end
end
diff --git a/spec/ruby/core/numeric/fdiv_spec.rb b/spec/ruby/core/numeric/fdiv_spec.rb
index e97fa77f79..907e5d343c 100644
--- a/spec/ruby/core/numeric/fdiv_spec.rb
+++ b/spec/ruby/core/numeric/fdiv_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'shared/quo'
describe "Numeric#fdiv" do
it "coerces self with #to_f" do
diff --git a/spec/ruby/core/numeric/magnitude_spec.rb b/spec/ruby/core/numeric/magnitude_spec.rb
index 1371dff21f..7a3290b036 100644
--- a/spec/ruby/core/numeric/magnitude_spec.rb
+++ b/spec/ruby/core/numeric/magnitude_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/abs'
describe "Numeric#magnitude" do
diff --git a/spec/ruby/core/numeric/quo_spec.rb b/spec/ruby/core/numeric/quo_spec.rb
index 6e3ce7a374..67bacee9b5 100644
--- a/spec/ruby/core/numeric/quo_spec.rb
+++ b/spec/ruby/core/numeric/quo_spec.rb
@@ -1,5 +1,6 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
+require_relative 'shared/quo'
describe "Numeric#quo" do
it "returns the result of self divided by the given Integer as a Rational" do
diff --git a/spec/ruby/core/numeric/remainder_spec.rb b/spec/ruby/core/numeric/remainder_spec.rb
index 674fa22d8e..1e2f5f3a96 100644
--- a/spec/ruby/core/numeric/remainder_spec.rb
+++ b/spec/ruby/core/numeric/remainder_spec.rb
@@ -6,9 +6,6 @@ describe "Numeric#remainder" do
@obj = NumericSpecs::Subclass.new
@result = mock("Numeric#% result")
@other = mock("Passed Object")
- ruby_version_is "3.3" do
- @other.should_receive(:coerce).with(@obj).and_return([@obj, @other])
- end
end
it "returns the result of calling self#% with other if self is 0" do
diff --git a/spec/ruby/core/numeric/shared/quo.rb b/spec/ruby/core/numeric/shared/quo.rb
new file mode 100644
index 0000000000..2392636fe7
--- /dev/null
+++ b/spec/ruby/core/numeric/shared/quo.rb
@@ -0,0 +1,7 @@
+describe :numeric_quo_18, shared: true do
+ it "returns the result of calling self#/ with other" do
+ obj = mock_numeric('numeric')
+ obj.should_receive(:/).with(19).and_return(:result)
+ obj.send(@method, 19).should == :result
+ end
+end
diff --git a/spec/ruby/core/numeric/shared/step.rb b/spec/ruby/core/numeric/shared/step.rb
index 977ec6de02..8b1a7bf307 100644
--- a/spec/ruby/core/numeric/shared/step.rb
+++ b/spec/ruby/core/numeric/shared/step.rb
@@ -5,7 +5,7 @@ require_relative '../fixtures/classes'
# To be able to do it, the @step ivar must contain a Proc that transforms
# the step call arguments passed as positional arguments to the style of
# arguments pretended to test.
-describe :numeric_step, shared: true do
+describe :numeric_step, :shared => true do
before :each do
ScratchPad.record []
@prc = -> x { ScratchPad << x }
@@ -258,6 +258,12 @@ describe :numeric_step, shared: true do
describe "when no block is given" do
step_enum_class = Enumerator::ArithmeticSequence
+ ruby_version_is ""..."3.0" do
+ it "returns an #{step_enum_class} when step is 0" do
+ @step.call(1, 2, 0).should be_an_instance_of(step_enum_class)
+ end
+ end
+
it "returns an #{step_enum_class} when not passed a block and self > stop" do
@step.call(1, 0, 2).should be_an_instance_of(step_enum_class)
end
diff --git a/spec/ruby/core/numeric/step_spec.rb b/spec/ruby/core/numeric/step_spec.rb
index 1705fb1b4e..095c474fec 100644
--- a/spec/ruby/core/numeric/step_spec.rb
+++ b/spec/ruby/core/numeric/step_spec.rb
@@ -23,8 +23,30 @@ describe "Numeric#step" do
describe "when no block is given" do
step_enum_class = Enumerator::ArithmeticSequence
+ ruby_version_is ""..."3.0" do
+ it "returns an #{step_enum_class} when step is 0" do
+ 1.step(5, 0).should be_an_instance_of(step_enum_class)
+ end
+
+ it "returns an #{step_enum_class} when step is 0.0" do
+ 1.step(2, 0.0).should be_an_instance_of(step_enum_class)
+ end
+ end
+
describe "returned #{step_enum_class}" do
describe "size" do
+ ruby_version_is ""..."3.0" do
+ it "is infinity when step is 0" do
+ enum = 1.step(5, 0)
+ enum.size.should == Float::INFINITY
+ end
+
+ it "is infinity when step is 0.0" do
+ enum = 1.step(2, 0.0)
+ enum.size.should == Float::INFINITY
+ end
+ end
+
it "defaults to an infinite size" do
enum = 1.step
enum.size.should == Float::INFINITY
@@ -41,6 +63,22 @@ describe "Numeric#step" do
end
describe 'with keyword arguments' do
+ ruby_version_is ""..."3.0" do
+ it "doesn't raise an error when step is 0" do
+ -> { 1.step(to: 5, by: 0) { break } }.should_not raise_error
+ end
+
+ it "doesn't raise an error when step is 0.0" do
+ -> { 1.step(to: 2, by: 0.0) { break } }.should_not raise_error
+ end
+
+ it "should loop over self when step is 0 or 0.0" do
+ 1.step(to: 2, by: 0.0).take(5).should eql [1.0, 1.0, 1.0, 1.0, 1.0]
+ 1.step(to: 2, by: 0).take(5).should eql [1, 1, 1, 1, 1]
+ 1.1.step(to: 2, by: 0).take(5).should eql [1.1, 1.1, 1.1, 1.1, 1.1]
+ end
+ end
+
describe "when no block is given" do
describe "returned Enumerator" do
describe "size" do
@@ -48,6 +86,16 @@ describe "Numeric#step" do
1.step(by: 42).size.should == infinity_value
end
+ ruby_version_is ""..."3.0" do
+ it "should return infinity_value when step is 0" do
+ 1.step(to: 5, by: 0).size.should == infinity_value
+ end
+
+ it "should return infinity_value when step is 0.0" do
+ 1.step(to: 2, by: 0.0).size.should == infinity_value
+ end
+ end
+
it "should return infinity_value when ascending towards a limit of Float::INFINITY" do
1.step(to: Float::INFINITY, by: 42).size.should == infinity_value
end
@@ -80,12 +128,24 @@ describe "Numeric#step" do
end
describe 'with mixed arguments' do
- it " raises an ArgumentError when step is 0" do
- -> { 1.step(5, by: 0) { break } }.should raise_error(ArgumentError)
+ ruby_version_is ""..."3.0" do
+ it "doesn't raise an error when step is 0" do
+ -> { 1.step(5, by: 0) { break } }.should_not raise_error
+ end
+
+ it "doesn't raise an error when step is 0.0" do
+ -> { 1.step(2, by: 0.0) { break } }.should_not raise_error
+ end
end
- it "raises an ArgumentError when step is 0.0" do
- -> { 1.step(2, by: 0.0) { break } }.should raise_error(ArgumentError)
+ ruby_version_is "3.0" do
+ it " raises an ArgumentError when step is 0" do
+ -> { 1.step(5, by: 0) { break } }.should raise_error(ArgumentError)
+ end
+
+ it "raises an ArgumentError when step is 0.0" do
+ -> { 1.step(2, by: 0.0) { break } }.should raise_error(ArgumentError)
+ end
end
it "raises a ArgumentError when limit and to are defined" do
@@ -96,9 +156,26 @@ describe "Numeric#step" do
-> { 1.step(5, 1, by: 5) { break } }.should raise_error(ArgumentError)
end
+ ruby_version_is ""..."3.0" do
+ it "should loop over self when step is 0 or 0.0" do
+ 1.step(2, by: 0.0).take(5).should eql [1.0, 1.0, 1.0, 1.0, 1.0]
+ 1.step(2, by: 0).take(5).should eql [1, 1, 1, 1, 1]
+ 1.1.step(2, by: 0).take(5).should eql [1.1, 1.1, 1.1, 1.1, 1.1]
+ end
+ end
+
describe "when no block is given" do
describe "returned Enumerator" do
describe "size" do
+ ruby_version_is ""..."3.0" do
+ it "should return infinity_value when step is 0" do
+ 1.step(5, by: 0).size.should == infinity_value
+ end
+
+ it "should return infinity_value when step is 0.0" do
+ 1.step(2, by: 0.0).size.should == infinity_value
+ end
+ end
end
end
end
diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb
index 6be83e518e..d9db027e0b 100644
--- a/spec/ruby/core/objectspace/define_finalizer_spec.rb
+++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb
@@ -60,53 +60,55 @@ describe "ObjectSpace.define_finalizer" do
ruby_exe(code, :args => "2>&1").should include("finalizer run\n")
end
- it "warns if the finalizer has the object as the receiver" do
- code = <<-RUBY
- class CapturesSelf
- def initialize
- ObjectSpace.define_finalizer(self, proc {
- puts "finalizer run"
- })
+ ruby_version_is "3.0" do
+ it "warns if the finalizer has the object as the receiver" do
+ code = <<-RUBY
+ class CapturesSelf
+ def initialize
+ ObjectSpace.define_finalizer(self, proc {
+ puts "finalizer run"
+ })
+ end
end
- end
- CapturesSelf.new
- exit 0
- RUBY
+ CapturesSelf.new
+ exit 0
+ RUBY
- ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
- end
+ ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
+ end
- it "warns if the finalizer is a method bound to the receiver" do
- code = <<-RUBY
- class CapturesSelf
- def initialize
- ObjectSpace.define_finalizer(self, method(:finalize))
- end
- def finalize(id)
- puts "finalizer run"
+ it "warns if the finalizer is a method bound to the receiver" do
+ code = <<-RUBY
+ class CapturesSelf
+ def initialize
+ ObjectSpace.define_finalizer(self, method(:finalize))
+ end
+ def finalize(id)
+ puts "finalizer run"
+ end
end
- end
- CapturesSelf.new
- exit 0
- RUBY
+ CapturesSelf.new
+ exit 0
+ RUBY
- ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
- end
+ ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
+ end
- it "warns if the finalizer was a block in the receiver" do
- code = <<-RUBY
- class CapturesSelf
- def initialize
- ObjectSpace.define_finalizer(self) do
- puts "finalizer run"
+ it "warns if the finalizer was a block in the receiver" do
+ code = <<-RUBY
+ class CapturesSelf
+ def initialize
+ ObjectSpace.define_finalizer(self) do
+ puts "finalizer run"
+ end
end
end
- end
- CapturesSelf.new
- exit 0
- RUBY
+ CapturesSelf.new
+ exit 0
+ RUBY
- ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
+ ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
+ end
end
it "calls a finalizer at exit even if it is self-referencing" do
diff --git a/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb b/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb
deleted file mode 100644
index 6e534b8ea8..0000000000
--- a/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is '3.3' do
- describe "ObjectSpace::WeakKeyMap#delete" do
- it "removes the entry and returns the deleted value" do
- m = ObjectSpace::WeakKeyMap.new
- key = Object.new
- value = Object.new
- m[key] = value
-
- m.delete(key).should == value
- m.key?(key).should == false
- end
-
- it "uses equality semantic" do
- m = ObjectSpace::WeakKeyMap.new
- key = "foo".upcase
- value = Object.new
- m[key] = value
-
- m.delete("foo".upcase).should == value
- m.key?(key).should == false
- end
-
- it "calls supplied block if the key is not found" do
- key = Object.new
- m = ObjectSpace::WeakKeyMap.new
- return_value = m.delete(key) do |yielded_key|
- yielded_key.should == key
- 5
- end
- return_value.should == 5
- end
-
- it "returns nil if the key is not found when no block is given" do
- m = ObjectSpace::WeakMap.new
- m.delete(Object.new).should == nil
- end
- end
-end
diff --git a/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb b/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb
deleted file mode 100644
index 862480cd02..0000000000
--- a/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.3" do
- describe "ObjectSpace::WeakKeyMap#[]" do
- it "is faithful to the map's content" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2 = %w[a b].map(&:upcase)
- ref1, ref2 = %w[x y]
- map[key1] = ref1
- map[key1].should == ref1
- map[key1] = ref1
- map[key1].should == ref1
- map[key2] = ref2
- map[key1].should == ref1
- map[key2].should == ref2
- end
-
- it "matches using equality semantics" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2 = %w[a a].map(&:upcase)
- ref = "x"
- map[key1] = ref
- map[key2].should == ref
- end
- end
-end
diff --git a/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb b/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb
deleted file mode 100644
index 689509d820..0000000000
--- a/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.3" do
- describe "ObjectSpace::WeakKeyMap#[]=" do
- def should_accept(map, key, value)
- (map[key] = value).should == value
- map.should.key?(key)
- map[key].should == value
- end
-
- def should_not_accept(map, key, value)
- -> { map[key] = value }.should raise_error(ArgumentError)
- end
-
- it "is correct" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2 = %w[a b].map(&:upcase)
- ref1, ref2 = %w[x y]
- should_accept(map, key1, ref1)
- should_accept(map, key1, ref1)
- should_accept(map, key2, ref2)
- map[key1].should == ref1
- end
-
- it "requires the keys to implement #hash" do
- map = ObjectSpace::WeakKeyMap.new
- -> { map[BasicObject.new] = 1 }.should raise_error(NoMethodError, "undefined method `hash' for an instance of BasicObject")
- end
-
- it "accepts frozen keys or values" do
- map = ObjectSpace::WeakKeyMap.new
- x = Object.new
- should_accept(map, x, true)
- should_accept(map, x, false)
- should_accept(map, x, 42)
- should_accept(map, x, :foo)
-
- y = Object.new.freeze
- should_accept(map, x, y)
- should_accept(map, y, x)
- end
-
- it "rejects symbols as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, :foo, true)
- should_not_accept(map, rand.to_s.to_sym, true)
- end
-
- it "rejects integers as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, 42, true)
- should_not_accept(map, 2 ** 68, true)
- end
-
- it "rejects floats as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, 4.2, true)
- end
-
- it "rejects booleans as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, true, true)
- should_not_accept(map, false, true)
- end
-
- it "rejects nil as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, nil, true)
- end
- end
-end
diff --git a/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb b/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb
deleted file mode 100644
index 3af0186f27..0000000000
--- a/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.3" do
- describe "ObjectSpace::WeakKeyMap#getkey" do
- it "returns the existing equal key" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2 = %w[a a].map(&:upcase)
-
- map[key1] = true
- map.getkey(key2).should equal(key1)
- map.getkey("X").should == nil
- end
- end
-end
diff --git a/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb b/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb
deleted file mode 100644
index 557fbc8733..0000000000
--- a/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.3" do
- describe "ObjectSpace::WeakKeyMap#inspect" do
- it "only displays size in output" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2, key3 = "foo", "bar", "bar"
- map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=0>\z/
- map[key1] = 1
- map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=1>\z/
- map[key2] = 2
- map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=2>\z/
- map[key3] = 3
- map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=2>\z/
- end
- end
-end
diff --git a/spec/ruby/core/objectspace/weakkeymap/key_spec.rb b/spec/ruby/core/objectspace/weakkeymap/key_spec.rb
deleted file mode 100644
index 2af9c2b8e7..0000000000
--- a/spec/ruby/core/objectspace/weakkeymap/key_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is "3.3" do
- describe "ObjectSpace::WeakKeyMap#key?" do
- it "recognizes keys in use" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2 = %w[a b].map(&:upcase)
- ref1, ref2 = %w[x y]
-
- map[key1] = ref1
- map.key?(key1).should == true
- map[key1] = ref1
- map.key?(key1).should == true
- map[key2] = ref2
- map.key?(key2).should == true
- end
-
- it "matches using equality semantics" do
- map = ObjectSpace::WeakKeyMap.new
- key1, key2 = %w[a a].map(&:upcase)
- ref = "x"
- map[key1] = ref
- map.key?(key2).should == true
- end
-
- it "reports true if the pair exists and the value is nil" do
- map = ObjectSpace::WeakKeyMap.new
- key = Object.new
- map[key] = nil
- map.key?(key).should == true
- end
- end
-end
diff --git a/spec/ruby/core/objectspace/weakmap/delete_spec.rb b/spec/ruby/core/objectspace/weakmap/delete_spec.rb
deleted file mode 100644
index 302de264fb..0000000000
--- a/spec/ruby/core/objectspace/weakmap/delete_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require_relative '../../../spec_helper'
-
-ruby_version_is '3.3' do
- describe "ObjectSpace::WeakMap#delete" do
- it "removes the entry and returns the deleted value" do
- m = ObjectSpace::WeakMap.new
- key = Object.new
- value = Object.new
- m[key] = value
-
- m.delete(key).should == value
- m.key?(key).should == false
- end
-
- it "calls supplied block if the key is not found" do
- key = Object.new
- m = ObjectSpace::WeakMap.new
- return_value = m.delete(key) do |yielded_key|
- yielded_key.should == key
- 5
- end
- return_value.should == 5
- end
-
- it "returns nil if the key is not found when no block is given" do
- m = ObjectSpace::WeakMap.new
- m.delete(Object.new).should == nil
- end
- end
-end
diff --git a/spec/ruby/core/proc/clone_spec.rb b/spec/ruby/core/proc/clone_spec.rb
index 7eca9c561e..a1a1292654 100644
--- a/spec/ruby/core/proc/clone_spec.rb
+++ b/spec/ruby/core/proc/clone_spec.rb
@@ -3,13 +3,4 @@ require_relative 'shared/dup'
describe "Proc#clone" do
it_behaves_like :proc_dup, :clone
-
- ruby_bug "cloning a frozen proc is broken on Ruby 3.3", "3.3"..."3.4" do
- it "preserves frozen status" do
- proc = Proc.new { }
- proc.freeze
- proc.frozen?.should == true
- proc.clone.frozen?.should == true
- end
- end
end
diff --git a/spec/ruby/core/proc/compose_spec.rb b/spec/ruby/core/proc/compose_spec.rb
index 9e9b57e06f..94814d11bc 100644
--- a/spec/ruby/core/proc/compose_spec.rb
+++ b/spec/ruby/core/proc/compose_spec.rb
@@ -37,22 +37,42 @@ describe "Proc#<<" do
(f << g).should_not.lambda?
end
- it "is a lambda when parameter is lambda" do
- f = -> x { x * x }
- g = proc { |x| x + x }
- lambda_proc = -> x { x }
+ ruby_version_is(''...'3.0') do
+ it "is a Proc when other is lambda" do
+ f = proc { |x| x * x }
+ g = -> x { x + x }
+
+ (f << g).is_a?(Proc).should == true
+ (f << g).should_not.lambda?
+ end
+
+ it "is a lambda when self is lambda" do
+ f = -> x { x * x }
+ g = proc { |x| x + x }
+
+ (f << g).is_a?(Proc).should == true
+ (f << g).should.lambda?
+ end
+ end
- # lambda << proc
- (f << g).is_a?(Proc).should == true
- (f << g).should_not.lambda?
+ ruby_version_is('3.0') do
+ it "is a lambda when parameter is lambda" do
+ f = -> x { x * x }
+ g = proc { |x| x + x }
+ lambda_proc = -> x { x }
+
+ # lambda << proc
+ (f << g).is_a?(Proc).should == true
+ (f << g).should_not.lambda?
- # lambda << lambda
- (f << lambda_proc).is_a?(Proc).should == true
- (f << lambda_proc).should.lambda?
+ # lambda << lambda
+ (f << lambda_proc).is_a?(Proc).should == true
+ (f << lambda_proc).should.lambda?
- # proc << lambda
- (g << f).is_a?(Proc).should == true
- (g << f).should.lambda?
+ # proc << lambda
+ (g << f).is_a?(Proc).should == true
+ (g << f).should.lambda?
+ end
end
it "may accept multiple arguments" do
diff --git a/spec/ruby/core/proc/dup_spec.rb b/spec/ruby/core/proc/dup_spec.rb
index dd19b3c1e9..6da2f3080c 100644
--- a/spec/ruby/core/proc/dup_spec.rb
+++ b/spec/ruby/core/proc/dup_spec.rb
@@ -3,11 +3,4 @@ require_relative 'shared/dup'
describe "Proc#dup" do
it_behaves_like :proc_dup, :dup
-
- it "resets frozen status" do
- proc = Proc.new { }
- proc.freeze
- proc.frozen?.should == true
- proc.dup.frozen?.should == false
- end
end
diff --git a/spec/ruby/core/proc/eql_spec.rb b/spec/ruby/core/proc/eql_spec.rb
index ad8f6749fc..06aee272e5 100644
--- a/spec/ruby/core/proc/eql_spec.rb
+++ b/spec/ruby/core/proc/eql_spec.rb
@@ -2,5 +2,11 @@ require_relative '../../spec_helper'
require_relative 'shared/equal'
describe "Proc#eql?" do
- it_behaves_like :proc_equal, :eql?
+ ruby_version_is ""..."3.0" do
+ it_behaves_like :proc_equal_undefined, :eql?
+ end
+
+ ruby_version_is "3.0" do
+ it_behaves_like :proc_equal, :eql?
+ end
end
diff --git a/spec/ruby/core/proc/equal_value_spec.rb b/spec/ruby/core/proc/equal_value_spec.rb
index ec7f274732..ee88c0537d 100644
--- a/spec/ruby/core/proc/equal_value_spec.rb
+++ b/spec/ruby/core/proc/equal_value_spec.rb
@@ -2,5 +2,11 @@ require_relative '../../spec_helper'
require_relative 'shared/equal'
describe "Proc#==" do
- it_behaves_like :proc_equal, :==
+ ruby_version_is ""..."3.0" do
+ it_behaves_like :proc_equal_undefined, :==
+ end
+
+ ruby_version_is "3.0" do
+ it_behaves_like :proc_equal, :==
+ end
end
diff --git a/spec/ruby/core/proc/lambda_spec.rb b/spec/ruby/core/proc/lambda_spec.rb
index 5c3c38fc2a..b2d3f50350 100644
--- a/spec/ruby/core/proc/lambda_spec.rb
+++ b/spec/ruby/core/proc/lambda_spec.rb
@@ -14,11 +14,9 @@ describe "Proc#lambda?" do
Proc.new {}.lambda?.should be_false
end
- ruby_version_is ""..."3.3" do
- it "is preserved when passing a Proc with & to the lambda keyword" do
- suppress_warning {lambda(&->{})}.lambda?.should be_true
- suppress_warning {lambda(&proc{})}.lambda?.should be_false
- end
+ it "is preserved when passing a Proc with & to the lambda keyword" do
+ suppress_warning {lambda(&->{})}.lambda?.should be_true
+ suppress_warning {lambda(&proc{})}.lambda?.should be_false
end
it "is preserved when passing a Proc with & to the proc keyword" do
diff --git a/spec/ruby/core/proc/new_spec.rb b/spec/ruby/core/proc/new_spec.rb
index b2b7387756..cb52e94f44 100644
--- a/spec/ruby/core/proc/new_spec.rb
+++ b/spec/ruby/core/proc/new_spec.rb
@@ -166,13 +166,36 @@ describe "Proc.new without a block" do
-> { ProcSpecs.new_proc_subclass_in_method }.should raise_error(ArgumentError)
end
- it "raises an ArgumentError when passed no block" do
- def some_method
- Proc.new
+ ruby_version_is ""..."3.0" do
+ it "can be created if invoked from within a method with a block" do
+ -> { ProcSpecs.new_proc_in_method { "hello" } }.should complain(/Capturing the given block using Proc.new is deprecated/)
+ end
+
+ it "can be created if invoked on a subclass from within a method with a block" do
+ -> { ProcSpecs.new_proc_subclass_in_method { "hello" } }.should complain(/Capturing the given block using Proc.new is deprecated/)
+ end
+
+
+ it "can be create when called with no block" do
+ def some_method
+ Proc.new
+ end
+
+ -> {
+ some_method { "hello" }
+ }.should complain(/Capturing the given block using Proc.new is deprecated/)
end
+ end
- -> { ProcSpecs.new_proc_in_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
- -> { ProcSpecs.new_proc_subclass_in_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
- -> { some_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
+ ruby_version_is "3.0" do
+ it "raises an ArgumentError when passed no block" do
+ def some_method
+ Proc.new
+ end
+
+ -> { ProcSpecs.new_proc_in_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
+ -> { ProcSpecs.new_proc_subclass_in_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
+ -> { some_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
+ end
end
end
diff --git a/spec/ruby/core/proc/parameters_spec.rb b/spec/ruby/core/proc/parameters_spec.rb
index 2a4dcc36b3..3a56b613cd 100644
--- a/spec/ruby/core/proc/parameters_spec.rb
+++ b/spec/ruby/core/proc/parameters_spec.rb
@@ -21,7 +21,7 @@ describe "Proc#parameters" do
end
ruby_version_is "3.2" do
- it "sets the first element of each sub-Array to :req for required argument if lambda keyword used" do
+ it "sets the first element of each sub-Array to :req if argument would be required if a lambda if lambda keyword used" do
proc {|x| }.parameters(lambda: true).first.first.should == :req
proc {|y,*x| }.parameters(lambda: true).first.first.should == :req
end
@@ -91,33 +91,19 @@ describe "Proc#parameters" do
proc {|&block| }.parameters.first.last.should == :block
end
- it "ignores unnamed rest arguments" do
+ it "ignores unnamed rest args" do
-> x {}.parameters.should == [[:req, :x]]
end
ruby_version_is '3.2' do
- it "adds rest arg with name * for \"star\" argument" do
- -> * {}.parameters.should == [[:rest, :*]]
- end
-
- it "adds keyrest arg with ** as a name for \"double star\" argument" do
- -> ** {}.parameters.should == [[:keyrest, :**]]
+ it "adds * rest arg for \"star\" argument" do
+ -> x, * {}.parameters.should == [[:req, :x], [:rest, :*]]
end
end
ruby_version_is ''...'3.2' do
it "adds nameless rest arg for \"star\" argument" do
- -> * {}.parameters.should == [[:rest]]
- end
-
- it "adds nameless keyrest arg for \"double star\" argument" do
- -> ** {}.parameters.should == [[:keyrest]]
- end
- end
-
- ruby_version_is '3.1' do
- it "adds block arg with name & for anonymous block argument" do
- eval('-> & {}.parameters').should == [[:block, :&]]
+ -> x, * {}.parameters.should == [[:req, :x], [:rest]]
end
end
@@ -129,30 +115,4 @@ describe "Proc#parameters" do
local_is_not_parameter = {}
end.parameters.should == [[:rest, :args], [:block, :blk]]
end
-
- it "returns all parameters defined with the name _ as _" do
- proc = proc {|_, _, _ = 1, *_, _:, _: 2, **_, &_| }
- proc.parameters.should == [
- [:opt, :_],
- [:opt, :_],
- [:opt, :_],
- [:rest, :_],
- [:keyreq, :_],
- [:key, :_],
- [:keyrest, :_],
- [:block, :_]
- ]
-
- lambda = -> _, _, _ = 1, *_, _:, _: 2, **_, &_ {}
- lambda.parameters.should == [
- [:req, :_],
- [:req, :_],
- [:opt, :_],
- [:rest, :_],
- [:keyreq, :_],
- [:key, :_],
- [:keyrest, :_],
- [:block, :_]
- ]
- end
end
diff --git a/spec/ruby/core/proc/ruby2_keywords_spec.rb b/spec/ruby/core/proc/ruby2_keywords_spec.rb
index ab67302231..c6eb03e693 100644
--- a/spec/ruby/core/proc/ruby2_keywords_spec.rb
+++ b/spec/ruby/core/proc/ruby2_keywords_spec.rb
@@ -25,6 +25,28 @@ describe "Proc#ruby2_keywords" do
Hash.ruby2_keywords_hash?(f4.call(1, 2, a: "a")).should == true
end
+ ruby_version_is ""..."3.0" do
+ it "fixes delegation warnings when calling a method accepting keywords" do
+ obj = Object.new
+ def obj.foo(*a, **b) end
+
+ f = -> *a { obj.foo(*a) }
+
+ -> { f.call(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/)
+ f.ruby2_keywords
+ -> { f.call(1, 2, {a: "a"}) }.should_not complain
+ end
+
+ it "fixes delegation warnings when calling a proc accepting keywords" do
+ g = -> *a, **b { }
+ f = -> *a { g.call(*a) }
+
+ -> { f.call(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/)
+ f.ruby2_keywords
+ -> { f.call(1, 2, {a: "a"}) }.should_not complain
+ end
+ end
+
it "returns self" do
f = -> *a { }
f.ruby2_keywords.should equal f
diff --git a/spec/ruby/core/proc/shared/dup.rb b/spec/ruby/core/proc/shared/dup.rb
index c419a4078a..eda1d6929d 100644
--- a/spec/ruby/core/proc/shared/dup.rb
+++ b/spec/ruby/core/proc/shared/dup.rb
@@ -7,35 +7,4 @@ describe :proc_dup, shared: true do
a.call.should == b.call
end
-
- ruby_version_is "3.2" do
- it "returns an instance of subclass" do
- cl = Class.new(Proc)
-
- cl.new{}.send(@method).class.should == cl
- end
- end
-
- ruby_version_is "3.4" do
- it "copies instance variables" do
- proc = -> { "hello" }
- proc.instance_variable_set(:@ivar, 1)
- cl = proc.send(@method)
- cl.instance_variables.should == [:@ivar]
- end
-
- it "copies the finalizer" do
- code = <<-RUBY
- obj = Proc.new { }
-
- ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized\n" })
-
- obj.clone
-
- exit 0
- RUBY
-
- ruby_exe(code).lines.sort.should == ["finalized\n", "finalized\n"]
- end
- end
end
diff --git a/spec/ruby/core/proc/shared/equal.rb b/spec/ruby/core/proc/shared/equal.rb
index d0503fb064..0c0020ca7f 100644
--- a/spec/ruby/core/proc/shared/equal.rb
+++ b/spec/ruby/core/proc/shared/equal.rb
@@ -81,3 +81,20 @@ describe :proc_equal, shared: true do
p.send(@method, p2).should be_false
end
end
+
+describe :proc_equal_undefined, shared: true do
+ it "is not defined" do
+ Proc.should_not have_instance_method(@method, false)
+ end
+
+ it "returns false if other is a dup of the original" do
+ p = proc { :foo }
+ p.send(@method, p.dup).should be_false
+
+ p = Proc.new { :foo }
+ p.send(@method, p.dup).should be_false
+
+ p = -> { :foo }
+ p.send(@method, p.dup).should be_false
+ end
+end
diff --git a/spec/ruby/core/proc/source_location_spec.rb b/spec/ruby/core/proc/source_location_spec.rb
index a8b99287d5..f268499b82 100644
--- a/spec/ruby/core/proc/source_location_spec.rb
+++ b/spec/ruby/core/proc/source_location_spec.rb
@@ -19,19 +19,19 @@ describe "Proc#source_location" do
it "sets the first value to the path of the file in which the proc was defined" do
file = @proc.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('fixtures/source_location.rb', __dir__)
+ file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
file = @proc_new.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('fixtures/source_location.rb', __dir__)
+ file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
file = @lambda.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('fixtures/source_location.rb', __dir__)
+ file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
file = @method.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('fixtures/source_location.rb', __dir__)
+ file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
end
it "sets the last value to an Integer representing the line on which the proc was defined" do
@@ -83,9 +83,4 @@ describe "Proc#source_location" do
proc.source_location.should == nil
end
-
- it "works for eval with a given line" do
- proc = eval('-> {}', nil, "foo", 100)
- proc.source_location.should == ["foo", 100]
- end
end
diff --git a/spec/ruby/core/process/argv0_spec.rb b/spec/ruby/core/process/argv0_spec.rb
deleted file mode 100644
index f5aba719e9..0000000000
--- a/spec/ruby/core/process/argv0_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Process.argv0" do
- it "returns a String" do
- Process.argv0.should be_kind_of(String)
- end
-
- it "is the path given as the main script and the same as __FILE__" do
- script = "fixtures/argv0.rb"
-
- Dir.chdir(__dir__) do
- ruby_exe(script).should == "#{script}\n#{script}\nOK"
- end
- end
-
- ruby_bug "#19597", ""..."3.3" do
- it "returns a frozen object" do
- Process.argv0.should.frozen?
- end
- end
-
- it "returns every time the same object" do
- Process.argv0.should.equal?(Process.argv0)
- end
-end
diff --git a/spec/ruby/core/process/constants_spec.rb b/spec/ruby/core/process/constants_spec.rb
index 616c54b8e1..4130bb58a5 100644
--- a/spec/ruby/core/process/constants_spec.rb
+++ b/spec/ruby/core/process/constants_spec.rb
@@ -56,18 +56,12 @@ describe "Process::Constants" do
end
platform_is :netbsd, :freebsd do
- it "has the correct constant values on NetBSD and FreeBSD" do
+ it "Process::RLIMIT_SBSIZE" do
Process::RLIMIT_SBSIZE.should == 9 # FIXME: what's it equal?
Process::RLIMIT_AS.should == 10
end
end
- platform_is :freebsd do
- it "has the correct constant values on FreeBSD" do
- Process::RLIMIT_NPTS.should == 11
- end
- end
-
platform_is :windows do
it "does not define RLIMIT constants" do
%i[
diff --git a/spec/ruby/core/process/daemon_spec.rb b/spec/ruby/core/process/daemon_spec.rb
index 70ffd1b320..20b0d743b9 100644
--- a/spec/ruby/core/process/daemon_spec.rb
+++ b/spec/ruby/core/process/daemon_spec.rb
@@ -2,6 +2,9 @@ require_relative '../../spec_helper'
require_relative 'fixtures/common'
platform_is_not :windows do
+ # macOS 15 is not working this examples
+ return if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`
+
describe :process_daemon_keep_stdio_open_false, shared: true do
it "redirects stdout to /dev/null" do
@daemon.invoke("keep_stdio_open_false_stdout", @object).should == ""
diff --git a/spec/ruby/core/process/detach_spec.rb b/spec/ruby/core/process/detach_spec.rb
index f13bda1f5d..91661afcea 100644
--- a/spec/ruby/core/process/detach_spec.rb
+++ b/spec/ruby/core/process/detach_spec.rb
@@ -44,17 +44,11 @@ describe "Process.detach" do
end
it "tolerates not existing child process pid" do
- # Use a value that is close to the INT_MAX (pid usually is signed int).
- # It should (at least) be greater than allowed pid limit value that depends on OS.
- pid_not_existing = 2.pow(30)
+ # ensure there is no child process with this hardcoded pid
+ # `kill 0 pid` for existing process returns "1" and raises Errno::ESRCH if process doesn't exist
+ -> { Process.kill(0, 100500) }.should raise_error(Errno::ESRCH)
- # Check that there is no a child process with this hardcoded pid.
- # Command `kill 0 pid`:
- # - returns "1" if a process exists and
- # - raises Errno::ESRCH otherwise
- -> { Process.kill(0, pid_not_existing) }.should raise_error(Errno::ESRCH)
-
- thr = Process.detach(pid_not_existing)
+ thr = Process.detach(100500)
thr.join
thr.should be_kind_of(Thread)
diff --git a/spec/ruby/core/process/exec_spec.rb b/spec/ruby/core/process/exec_spec.rb
index 0f371b39c8..deb8913b6b 100644
--- a/spec/ruby/core/process/exec_spec.rb
+++ b/spec/ruby/core/process/exec_spec.rb
@@ -30,20 +30,20 @@ describe "Process.exec" do
end
it "raises Errno::EACCES when passed a directory" do
- -> { Process.exec __dir__ }.should raise_error(Errno::EACCES)
+ -> { Process.exec File.dirname(__FILE__) }.should raise_error(Errno::EACCES)
end
it "runs the specified command, replacing current process" do
- ruby_exe('Process.exec "echo hello"; puts "fail"').should == "hello\n"
+ ruby_exe('Process.exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
end
it "sets the current directory when given the :chdir option" do
tmpdir = tmp("")[0..-2]
platform_is_not :windows do
- ruby_exe("Process.exec(\"pwd\", chdir: #{tmpdir.inspect})").should == "#{tmpdir}\n"
+ ruby_exe("Process.exec(\"pwd\", chdir: #{tmpdir.inspect})", escape: true).should == "#{tmpdir}\n"
end
platform_is :windows do
- ruby_exe("Process.exec(\"cd\", chdir: #{tmpdir.inspect})").tr('\\', '/').should == "#{tmpdir}\n"
+ ruby_exe("Process.exec(\"cd\", chdir: #{tmpdir.inspect})", escape: true).tr('\\', '/').should == "#{tmpdir}\n"
end
end
@@ -73,13 +73,13 @@ describe "Process.exec" do
platform_is_not :windows do
it "subjects the specified command to shell expansion" do
result = Dir.chdir(@dir) do
- ruby_exe('Process.exec "echo *"')
+ ruby_exe('Process.exec "echo *"', escape: true)
end
result.chomp.should == @name
end
it "creates an argument array with shell parsing semantics for whitespace" do
- ruby_exe('Process.exec "echo a b c d"').should == "a b c d\n"
+ ruby_exe('Process.exec "echo a b c d"', escape: true).should == "a b c d\n"
end
end
@@ -87,13 +87,13 @@ describe "Process.exec" do
# There is no shell expansion on Windows
it "does not subject the specified command to shell expansion on Windows" do
result = Dir.chdir(@dir) do
- ruby_exe('Process.exec "echo *"')
+ ruby_exe('Process.exec "echo *"', escape: true)
end
result.should == "*\n"
end
it "does not create an argument array with shell parsing semantics for whitespace on Windows" do
- ruby_exe('Process.exec "echo a b c d"').should == "a b c d\n"
+ ruby_exe('Process.exec "echo a b c d"', escape: true).should == "a b c d\n"
end
end
@@ -105,7 +105,7 @@ describe "Process.exec" do
platform_is :windows do
cmd = '"cmd.exe", "/C", "echo", "*"'
end
- ruby_exe("Process.exec #{cmd}").should == "*\n"
+ ruby_exe("Process.exec #{cmd}", escape: true).should == "*\n"
end
end
@@ -124,29 +124,29 @@ describe "Process.exec" do
end
it "sets environment variables in the child environment" do
- ruby_exe('Process.exec({"FOO" => "BAR"}, "echo ' + var + '")').should == "BAR\n"
+ ruby_exe('Process.exec({"FOO" => "BAR"}, "echo ' + var + '")', escape: true).should == "BAR\n"
end
it "unsets environment variables whose value is nil" do
platform_is_not :windows do
- ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")').should == "\n"
+ ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")', escape: true).should == "\n"
end
platform_is :windows do
# On Windows, echo-ing a non-existent env var is treated as echo-ing any other string of text
- ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")').should == var + "\n"
+ ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")', escape: true).should == var + "\n"
end
end
it "coerces environment argument using to_hash" do
- ruby_exe('o = Object.new; def o.to_hash; {"FOO" => "BAR"}; end; Process.exec(o, "echo ' + var + '")').should == "BAR\n"
+ ruby_exe('o = Object.new; def o.to_hash; {"FOO" => "BAR"}; end; Process.exec(o, "echo ' + var + '")', escape: true).should == "BAR\n"
end
it "unsets other environment variables when given a true :unsetenv_others option" do
platform_is_not :windows do
- ruby_exe('Process.exec("echo ' + var + '", unsetenv_others: true)').should == "\n"
+ ruby_exe('Process.exec("echo ' + var + '", unsetenv_others: true)', escape: true).should == "\n"
end
platform_is :windows do
- ruby_exe('Process.exec("' + ENV['COMSPEC'].gsub('\\', '\\\\\\') + ' /C echo ' + var + '", unsetenv_others: true)').should == var + "\n"
+ ruby_exe('Process.exec("' + ENV['COMSPEC'].gsub('\\', '\\\\\\') + ' /C echo ' + var + '", unsetenv_others: true)', escape: true).should == var + "\n"
end
end
end
@@ -154,19 +154,19 @@ describe "Process.exec" do
describe "with a command array" do
it "uses the first element as the command name and the second as the argv[0] value" do
platform_is_not :windows do
- ruby_exe('Process.exec(["/bin/sh", "argv_zero"], "-c", "echo $0")').should == "argv_zero\n"
+ ruby_exe('Process.exec(["/bin/sh", "argv_zero"], "-c", "echo $0")', escape: true).should == "argv_zero\n"
end
platform_is :windows do
- ruby_exe('Process.exec(["cmd.exe", "/C"], "/C", "echo", "argv_zero")').should == "argv_zero\n"
+ ruby_exe('Process.exec(["cmd.exe", "/C"], "/C", "echo", "argv_zero")', escape: true).should == "argv_zero\n"
end
end
it "coerces the argument using to_ary" do
platform_is_not :windows do
- ruby_exe('o = Object.new; def o.to_ary; ["/bin/sh", "argv_zero"]; end; Process.exec(o, "-c", "echo $0")').should == "argv_zero\n"
+ ruby_exe('o = Object.new; def o.to_ary; ["/bin/sh", "argv_zero"]; end; Process.exec(o, "-c", "echo $0")', escape: true).should == "argv_zero\n"
end
platform_is :windows do
- ruby_exe('o = Object.new; def o.to_ary; ["cmd.exe", "/C"]; end; Process.exec(o, "/C", "echo", "argv_zero")').should == "argv_zero\n"
+ ruby_exe('o = Object.new; def o.to_ary; ["cmd.exe", "/C"]; end; Process.exec(o, "/C", "echo", "argv_zero")', escape: true).should == "argv_zero\n"
end
end
@@ -200,7 +200,7 @@ describe "Process.exec" do
end
EOC
- ruby_exe(cmd)
+ ruby_exe(cmd, escape: true)
child_fd = IO.read(@child_fd_file).to_i
child_fd.to_i.should > STDERR.fileno
@@ -216,7 +216,7 @@ describe "Process.exec" do
Process.exec("#{ruby_cmd(map_fd_fixture)} \#{f.fileno}", f.fileno => f.fileno)
EOC
- output = ruby_exe(cmd)
+ output = ruby_exe(cmd, escape: true)
child_fd, close_on_exec = output.split
child_fd.to_i.should > STDERR.fileno
@@ -232,7 +232,7 @@ describe "Process.exec" do
puts(f.close_on_exec?)
EOC
- output = ruby_exe(cmd)
+ output = ruby_exe(cmd, escape: true)
output.split.should == ['true', 'false']
end
end
diff --git a/spec/ruby/core/process/exit_spec.rb b/spec/ruby/core/process/exit_spec.rb
index 4f7dc94407..70d79d789d 100644
--- a/spec/ruby/core/process/exit_spec.rb
+++ b/spec/ruby/core/process/exit_spec.rb
@@ -6,5 +6,5 @@ describe "Process.exit" do
end
describe "Process.exit!" do
- it_behaves_like :process_exit!, :exit!, "Process"
+ it_behaves_like :process_exit!, :exit!, Process
end
diff --git a/spec/ruby/core/process/fixtures/argv0.rb b/spec/ruby/core/process/fixtures/argv0.rb
deleted file mode 100644
index 847a3e903e..0000000000
--- a/spec/ruby/core/process/fixtures/argv0.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-puts Process.argv0
-puts __FILE__
-
-if Process.argv0 == __FILE__
- print "OK"
-end
diff --git a/spec/ruby/core/process/spawn_spec.rb b/spec/ruby/core/process/spawn_spec.rb
index 283a7f033d..c8a58c4d04 100644
--- a/spec/ruby/core/process/spawn_spec.rb
+++ b/spec/ruby/core/process/spawn_spec.rb
@@ -714,7 +714,7 @@ describe "Process.spawn" do
end
it "raises an Errno::EACCES or Errno::EISDIR when passed a directory" do
- -> { Process.spawn __dir__ }.should raise_error(SystemCallError) { |e|
+ -> { Process.spawn File.dirname(__FILE__) }.should raise_error(SystemCallError) { |e|
[Errno::EACCES, Errno::EISDIR].should include(e.class)
}
end
diff --git a/spec/ruby/core/process/status/wait_spec.rb b/spec/ruby/core/process/status/wait_spec.rb
index 57d56209a9..b9d80e31f4 100644
--- a/spec/ruby/core/process/status/wait_spec.rb
+++ b/spec/ruby/core/process/status/wait_spec.rb
@@ -1,100 +1,102 @@
require_relative '../../../spec_helper'
require_relative '../fixtures/common'
-describe "Process::Status.wait" do
- ProcessSpecs.use_system_ruby(self)
-
- before :all do
- begin
- leaked = Process.waitall
- # Ruby-space should not see PIDs used by rjit
- raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
- rescue NotImplementedError
+ruby_version_is "3.0" do
+ describe "Process::Status.wait" do
+ ProcessSpecs.use_system_ruby(self)
+
+ before :all do
+ begin
+ leaked = Process.waitall
+ # Ruby-space should not see PIDs used by mjit
+ raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
+ rescue NotImplementedError
+ end
end
- end
-
- it "returns a status with pid -1 if there are no child processes" do
- Process::Status.wait.pid.should == -1
- end
- platform_is_not :windows do
- it "returns a status with its child pid" do
- pid = Process.spawn(ruby_cmd('exit'))
- status = Process::Status.wait
- status.should be_an_instance_of(Process::Status)
- status.pid.should == pid
+ it "returns a status with pid -1 if there are no child processes" do
+ Process::Status.wait.pid.should == -1
end
- it "should not set $? to the Process::Status" do
- pid = Process.spawn(ruby_cmd('exit'))
- status = Process::Status.wait
- $?.should_not equal(status)
- end
+ platform_is_not :windows do
+ it "returns a status with its child pid" do
+ pid = Process.spawn(ruby_cmd('exit'))
+ status = Process::Status.wait
+ status.should be_an_instance_of(Process::Status)
+ status.pid.should == pid
+ end
- it "should not change the value of $?" do
- pid = Process.spawn(ruby_cmd('exit'))
- Process.wait
- status = $?
- Process::Status.wait
- status.should equal($?)
- end
+ it "should not set $? to the Process::Status" do
+ pid = Process.spawn(ruby_cmd('exit'))
+ status = Process::Status.wait
+ $?.should_not equal(status)
+ end
- it "waits for any child process if no pid is given" do
- pid = Process.spawn(ruby_cmd('exit'))
- Process::Status.wait.pid.should == pid
- -> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
- end
+ it "should not change the value of $?" do
+ pid = Process.spawn(ruby_cmd('exit'))
+ Process.wait
+ status = $?
+ Process::Status.wait
+ status.should equal($?)
+ end
- it "waits for a specific child if a pid is given" do
- pid1 = Process.spawn(ruby_cmd('exit'))
- pid2 = Process.spawn(ruby_cmd('exit'))
- Process::Status.wait(pid2).pid.should == pid2
- Process::Status.wait(pid1).pid.should == pid1
- -> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH)
- -> { Process.kill(0, pid2) }.should raise_error(Errno::ESRCH)
- end
+ it "waits for any child process if no pid is given" do
+ pid = Process.spawn(ruby_cmd('exit'))
+ Process::Status.wait.pid.should == pid
+ -> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
+ end
- it "coerces the pid to an Integer" do
- pid1 = Process.spawn(ruby_cmd('exit'))
- Process::Status.wait(mock_int(pid1)).pid.should == pid1
- -> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH)
- end
+ it "waits for a specific child if a pid is given" do
+ pid1 = Process.spawn(ruby_cmd('exit'))
+ pid2 = Process.spawn(ruby_cmd('exit'))
+ Process::Status.wait(pid2).pid.should == pid2
+ Process::Status.wait(pid1).pid.should == pid1
+ -> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH)
+ -> { Process.kill(0, pid2) }.should raise_error(Errno::ESRCH)
+ end
- # This spec is probably system-dependent.
- it "waits for a child whose process group ID is that of the calling process" do
- pid1 = Process.spawn(ruby_cmd('exit'), pgroup: true)
- pid2 = Process.spawn(ruby_cmd('exit'))
+ it "coerces the pid to an Integer" do
+ pid1 = Process.spawn(ruby_cmd('exit'))
+ Process::Status.wait(mock_int(pid1)).pid.should == pid1
+ -> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH)
+ end
- Process::Status.wait(0).pid.should == pid2
- Process::Status.wait.pid.should == pid1
- end
+ # This spec is probably system-dependent.
+ it "waits for a child whose process group ID is that of the calling process" do
+ pid1 = Process.spawn(ruby_cmd('exit'), pgroup: true)
+ pid2 = Process.spawn(ruby_cmd('exit'))
- # This spec is probably system-dependent.
- it "doesn't block if no child is available when WNOHANG is used" do
- read, write = IO.pipe
- pid = Process.fork do
- read.close
- Signal.trap("TERM") { Process.exit! }
- write << 1
- write.close
- sleep
+ Process::Status.wait(0).pid.should == pid2
+ Process::Status.wait.pid.should == pid1
end
- Process::Status.wait(pid, Process::WNOHANG).should be_nil
+ # This spec is probably system-dependent.
+ it "doesn't block if no child is available when WNOHANG is used" do
+ read, write = IO.pipe
+ pid = Process.fork do
+ read.close
+ Signal.trap("TERM") { Process.exit! }
+ write << 1
+ write.close
+ sleep
+ end
- # wait for the child to setup its TERM handler
- write.close
- read.read(1)
- read.close
+ Process::Status.wait(pid, Process::WNOHANG).should be_nil
- Process.kill("TERM", pid)
- Process::Status.wait.pid.should == pid
- end
+ # wait for the child to setup its TERM handler
+ write.close
+ read.read(1)
+ read.close
- it "always accepts flags=0" do
- pid = Process.spawn(ruby_cmd('exit'))
- Process::Status.wait(-1, 0).pid.should == pid
- -> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
+ Process.kill("TERM", pid)
+ Process::Status.wait.pid.should == pid
+ end
+
+ it "always accepts flags=0" do
+ pid = Process.spawn(ruby_cmd('exit'))
+ Process::Status.wait(-1, 0).pid.should == pid
+ -> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
+ end
end
end
end
diff --git a/spec/ruby/core/process/times_spec.rb b/spec/ruby/core/process/times_spec.rb
index d3bff2cda9..6142cd257c 100644
--- a/spec/ruby/core/process/times_spec.rb
+++ b/spec/ruby/core/process/times_spec.rb
@@ -16,4 +16,24 @@ describe "Process.times" do
Process.times.utime.should > user
end
end
+
+ platform_is_not :windows do
+ it "uses getrusage when available to improve precision beyond milliseconds" do
+ max = 10_000
+ has_getrusage = max.times.find do
+ time = Process.clock_gettime(:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID)
+ ('%.6f' % time).end_with?('000')
+ end
+ unless has_getrusage
+ skip "getrusage is not supported on this environment"
+ end
+
+ found = (max * 100).times.find do
+ time = Process.times.utime
+ ('%.6f' % time).end_with?('000')
+ end
+
+ found.should_not == nil
+ end
+ end
end
diff --git a/spec/ruby/core/process/wait2_spec.rb b/spec/ruby/core/process/wait2_spec.rb
index 8ba429dc96..673d3cdb9d 100644
--- a/spec/ruby/core/process/wait2_spec.rb
+++ b/spec/ruby/core/process/wait2_spec.rb
@@ -4,14 +4,14 @@ describe "Process.wait2" do
before :all do
# HACK: this kludge is temporarily necessary because some
# misbehaving spec somewhere else does not clear processes
- # Note: background processes are unavoidable with RJIT,
+ # Note: background processes are unavoidable with MJIT,
# but we shouldn't reap them from Ruby-space
begin
Process.wait(-1, Process::WNOHANG)
$stderr.puts "Leaked process before wait2 specs! Waiting for it"
leaked = Process.waitall
$stderr.puts "leaked before wait2 specs: #{leaked}" unless leaked.empty?
- # Ruby-space should not see PIDs used by rjit
+ # Ruby-space should not see PIDs used by mjit
leaked.should be_empty
rescue Errno::ECHILD # No child processes
rescue NotImplementedError
diff --git a/spec/ruby/core/process/wait_spec.rb b/spec/ruby/core/process/wait_spec.rb
index 385acc9928..44c95d6304 100644
--- a/spec/ruby/core/process/wait_spec.rb
+++ b/spec/ruby/core/process/wait_spec.rb
@@ -7,7 +7,7 @@ describe "Process.wait" do
before :all do
begin
leaked = Process.waitall
- # Ruby-space should not see PIDs used by rjit
+ # Ruby-space should not see PIDs used by mjit
raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
rescue NotImplementedError
end
diff --git a/spec/ruby/core/process/warmup_spec.rb b/spec/ruby/core/process/warmup_spec.rb
deleted file mode 100644
index b562d52d22..0000000000
--- a/spec/ruby/core/process/warmup_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Process.warmup" do
- ruby_version_is "3.3" do
- # The behavior is entirely implementation specific.
- # Other implementations are free to just make it a noop
- it "is implemented" do
- Process.warmup.should == true
- end
- end
-end
diff --git a/spec/ruby/core/queue/deq_spec.rb b/spec/ruby/core/queue/deq_spec.rb
index f84d4220ea..9510978eac 100644
--- a/spec/ruby/core/queue/deq_spec.rb
+++ b/spec/ruby/core/queue/deq_spec.rb
@@ -1,13 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "Queue#deq" do
it_behaves_like :queue_deq, :deq, -> { Queue.new }
end
-
-describe "Queue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = Queue.new; q.push(1); q.deq(timeout: v) }
- end
-end
diff --git a/spec/ruby/core/queue/initialize_spec.rb b/spec/ruby/core/queue/initialize_spec.rb
index c6c1ae63c5..c45abcd29d 100644
--- a/spec/ruby/core/queue/initialize_spec.rb
+++ b/spec/ruby/core/queue/initialize_spec.rb
@@ -22,29 +22,16 @@ describe "Queue#initialize" do
q.should.empty?
end
- describe "converts the given argument to an Array using #to_a" do
- it "uses #to_a on the provided Enumerable" do
- enumerable = MockObject.new('mock-enumerable')
- enumerable.should_receive(:to_a).and_return([1, 2, 3])
- q = Queue.new(enumerable)
- q.size.should == 3
- q.should_not.empty?
- q.pop.should == 1
- q.pop.should == 2
- q.pop.should == 3
- q.should.empty?
- end
-
- it "raises a TypeError if the given argument can't be converted to an Array" do
- -> { Queue.new(42) }.should raise_error(TypeError)
- -> { Queue.new(:abc) }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to an Array" do
- enumerable = MockObject.new('mock-enumerable')
- enumerable.should_receive(:to_a).and_raise(NoMethodError)
- -> { Queue.new(enumerable) }.should raise_error(NoMethodError)
- end
+ it "uses #to_a on the provided Enumerable" do
+ enumerable = MockObject.new('mock-enumerable')
+ enumerable.should_receive(:to_a).and_return([1, 2, 3])
+ q = Queue.new(enumerable)
+ q.size.should == 3
+ q.should_not.empty?
+ q.pop.should == 1
+ q.pop.should == 2
+ q.pop.should == 3
+ q.should.empty?
end
it "raises TypeError if the provided Enumerable does not respond to #to_a" do
diff --git a/spec/ruby/core/queue/pop_spec.rb b/spec/ruby/core/queue/pop_spec.rb
index d344740834..1ce9231685 100644
--- a/spec/ruby/core/queue/pop_spec.rb
+++ b/spec/ruby/core/queue/pop_spec.rb
@@ -1,13 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "Queue#pop" do
it_behaves_like :queue_deq, :pop, -> { Queue.new }
end
-
-describe "Queue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = Queue.new; q.push(1); q.pop(timeout: v) }
- end
-end
diff --git a/spec/ruby/core/queue/shift_spec.rb b/spec/ruby/core/queue/shift_spec.rb
index 64165e0b61..f84058e1df 100644
--- a/spec/ruby/core/queue/shift_spec.rb
+++ b/spec/ruby/core/queue/shift_spec.rb
@@ -1,13 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "Queue#shift" do
it_behaves_like :queue_deq, :shift, -> { Queue.new }
end
-
-describe "Queue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = Queue.new; q.push(1); q.shift(timeout: v) }
- end
-end
diff --git a/spec/ruby/core/random/bytes_spec.rb b/spec/ruby/core/random/bytes_spec.rb
index b42dc61234..ed1b3a7b41 100644
--- a/spec/ruby/core/random/bytes_spec.rb
+++ b/spec/ruby/core/random/bytes_spec.rb
@@ -9,6 +9,7 @@ describe "Random#bytes" do
Random.new(33).bytes(2).should == Random.new(33).bytes(2)
end
+ # Should double check this is official spec
it "returns the same numeric output for a given seed across all implementations and platforms" do
rnd = Random.new(33)
rnd.bytes(2).should == "\x14\\"
diff --git a/spec/ruby/core/random/default_spec.rb b/spec/ruby/core/random/default_spec.rb
index 01d7430df8..b4ffcb81f4 100644
--- a/spec/ruby/core/random/default_spec.rb
+++ b/spec/ruby/core/random/default_spec.rb
@@ -14,16 +14,26 @@ describe "Random::DEFAULT" do
seed1.should != seed2
end
- it "refers to the Random class" do
- suppress_warning do
- Random::DEFAULT.should.equal?(Random)
+ ruby_version_is ''...'3.0' do
+ it "returns a Random instance" do
+ suppress_warning do
+ Random::DEFAULT.should be_an_instance_of(Random)
+ end
end
end
- it "is deprecated" do
- -> {
- Random::DEFAULT.should.equal?(Random)
- }.should complain(/constant Random::DEFAULT is deprecated/)
+ ruby_version_is '3.0' do
+ it "refers to the Random class" do
+ suppress_warning do
+ Random::DEFAULT.should.equal?(Random)
+ end
+ end
+
+ it "is deprecated" do
+ -> {
+ Random::DEFAULT.should.equal?(Random)
+ }.should complain(/constant Random::DEFAULT is deprecated/)
+ end
end
end
diff --git a/spec/ruby/core/random/new_spec.rb b/spec/ruby/core/random/new_spec.rb
index 90e2a9d6f2..4280b5b9c3 100644
--- a/spec/ruby/core/random/new_spec.rb
+++ b/spec/ruby/core/random/new_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
describe "Random.new" do
it "returns a new instance of Random" do
Random.new.should be_an_instance_of(Random)
diff --git a/spec/ruby/core/range/cover_spec.rb b/spec/ruby/core/range/cover_spec.rb
index eb7cddc967..fa881607e9 100644
--- a/spec/ruby/core/range/cover_spec.rb
+++ b/spec/ruby/core/range/cover_spec.rb
@@ -7,8 +7,4 @@ describe "Range#cover?" do
it_behaves_like :range_cover_and_include, :cover?
it_behaves_like :range_cover, :cover?
it_behaves_like :range_cover_subrange, :cover?
-
- it "covers U+9995 in the range U+0999..U+9999" do
- ("\u{999}".."\u{9999}").cover?("\u{9995}").should be_true
- end
end
diff --git a/spec/ruby/core/range/frozen_spec.rb b/spec/ruby/core/range/frozen_spec.rb
index 8dab5e5339..298ffc87cb 100644
--- a/spec/ruby/core/range/frozen_spec.rb
+++ b/spec/ruby/core/range/frozen_spec.rb
@@ -2,24 +2,26 @@ require_relative '../../spec_helper'
# There is no Range#frozen? method but this feels like the best place for these specs
describe "Range#frozen?" do
- it "is true for literal ranges" do
- (1..2).should.frozen?
- (1..).should.frozen?
- (..1).should.frozen?
- end
+ ruby_version_is "3.0" do
+ it "is true for literal ranges" do
+ (1..2).should.frozen?
+ (1..).should.frozen?
+ (..1).should.frozen?
+ end
- it "is true for Range.new" do
- Range.new(1, 2).should.frozen?
- Range.new(1, nil).should.frozen?
- Range.new(nil, 1).should.frozen?
- end
+ it "is true for Range.new" do
+ Range.new(1, 2).should.frozen?
+ Range.new(1, nil).should.frozen?
+ Range.new(nil, 1).should.frozen?
+ end
- it "is false for instances of a subclass of Range" do
- sub_range = Class.new(Range).new(1, 2)
- sub_range.should_not.frozen?
- end
+ it "is false for instances of a subclass of Range" do
+ sub_range = Class.new(Range).new(1, 2)
+ sub_range.should_not.frozen?
+ end
- it "is false for Range.allocate" do
- Range.allocate.should_not.frozen?
+ it "is false for Range.allocate" do
+ Range.allocate.should_not.frozen?
+ end
end
end
diff --git a/spec/ruby/core/range/include_spec.rb b/spec/ruby/core/range/include_spec.rb
index 277de205d1..b2c7a54545 100644
--- a/spec/ruby/core/range/include_spec.rb
+++ b/spec/ruby/core/range/include_spec.rb
@@ -7,8 +7,4 @@ require_relative 'shared/cover'
describe "Range#include?" do
it_behaves_like :range_cover_and_include, :include?
it_behaves_like :range_include, :include?
-
- it "does not include U+9995 in the range U+0999..U+9999" do
- ("\u{999}".."\u{9999}").include?("\u{9995}").should be_false
- end
end
diff --git a/spec/ruby/core/range/initialize_spec.rb b/spec/ruby/core/range/initialize_spec.rb
index c653caf0c6..8a6ca65daa 100644
--- a/spec/ruby/core/range/initialize_spec.rb
+++ b/spec/ruby/core/range/initialize_spec.rb
@@ -27,9 +27,18 @@ describe "Range#initialize" do
-> { @range.send(:initialize, 1, 3, 5, 7, 9) }.should raise_error(ArgumentError)
end
- it "raises a FrozenError if called on an already initialized Range" do
- -> { (0..1).send(:initialize, 1, 3) }.should raise_error(FrozenError)
- -> { (0..1).send(:initialize, 1, 3, true) }.should raise_error(FrozenError)
+ ruby_version_is ""..."3.0" do
+ it "raises a NameError if called on an already initialized Range" do
+ -> { (0..1).send(:initialize, 1, 3) }.should raise_error(NameError)
+ -> { (0..1).send(:initialize, 1, 3, true) }.should raise_error(NameError)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "raises a FrozenError if called on an already initialized Range" do
+ -> { (0..1).send(:initialize, 1, 3) }.should raise_error(FrozenError)
+ -> { (0..1).send(:initialize, 1, 3, true) }.should raise_error(FrozenError)
+ end
end
it "raises an ArgumentError if arguments don't respond to <=>" do
diff --git a/spec/ruby/core/range/max_spec.rb b/spec/ruby/core/range/max_spec.rb
index a3bbc31e7d..6c9ada2a3c 100644
--- a/spec/ruby/core/range/max_spec.rb
+++ b/spec/ruby/core/range/max_spec.rb
@@ -50,15 +50,17 @@ describe "Range#max" do
-> { eval("(1..)").max }.should raise_error(RangeError)
end
- it "returns the end point for beginless ranges" do
- (..1).max.should == 1
- (..1.0).max.should == 1.0
- end
+ ruby_version_is "3.0" do
+ it "returns the end point for beginless ranges" do
+ (..1).max.should == 1
+ (..1.0).max.should == 1.0
+ end
- it "raises for an exclusive beginless range" do
- -> {
- (...1).max
- }.should raise_error(TypeError, 'cannot exclude end value with non Integer begin value')
+ it "raises for an exclusive beginless range" do
+ -> {
+ (...1).max
+ }.should raise_error(TypeError, 'cannot exclude end value with non Integer begin value')
+ end
end
end
diff --git a/spec/ruby/core/range/minmax_spec.rb b/spec/ruby/core/range/minmax_spec.rb
index 6651ae3726..b2b4fd61a1 100644
--- a/spec/ruby/core/range/minmax_spec.rb
+++ b/spec/ruby/core/range/minmax_spec.rb
@@ -86,22 +86,24 @@ describe 'Range#minmax' do
/cannot get the maximum of beginless range with custom comparison method|cannot get the minimum of beginless range/)
end
- it 'should return nil pair if beginning and end are equal without iterating the range' do
- @x.should_not_receive(:succ)
+ ruby_bug "#17014", ""..."3.0" do
+ it 'should return nil pair if beginning and end are equal without iterating the range' do
+ @x.should_not_receive(:succ)
- (@x...@x).minmax.should == [nil, nil]
- end
+ (@x...@x).minmax.should == [nil, nil]
+ end
- it 'should return nil pair if beginning is greater than end without iterating the range' do
- @y.should_not_receive(:succ)
+ it 'should return nil pair if beginning is greater than end without iterating the range' do
+ @y.should_not_receive(:succ)
- (@y...@x).minmax.should == [nil, nil]
- end
+ (@y...@x).minmax.should == [nil, nil]
+ end
- it 'should return the minimum and maximum values for a non-numeric range by iterating the range' do
- @x.should_receive(:succ).once.and_return(@y)
+ it 'should return the minimum and maximum values for a non-numeric range by iterating the range' do
+ @x.should_receive(:succ).once.and_return(@y)
- (@x...@y).minmax.should == [@x, @x]
+ (@x...@y).minmax.should == [@x, @x]
+ end
end
it 'should return the minimum and maximum values for a numeric range' do
diff --git a/spec/ruby/core/range/new_spec.rb b/spec/ruby/core/range/new_spec.rb
index 3cab887799..40df914b83 100644
--- a/spec/ruby/core/range/new_spec.rb
+++ b/spec/ruby/core/range/new_spec.rb
@@ -66,12 +66,14 @@ describe "Range.new" do
range_exclude.should_not == range_include
end
- it "creates a frozen range if the class is Range.class" do
- Range.new(1, 2).should.frozen?
- end
-
- it "does not create a frozen range if the class is not Range.class" do
- Class.new(Range).new(1, 2).should_not.frozen?
+ ruby_version_is "3.0" do
+ it "creates a frozen range if the class is Range.class" do
+ Range.new(1, 2).should.frozen?
+ end
+
+ it "does not create a frozen range if the class is not Range.class" do
+ Class.new(Range).new(1, 2).should_not.frozen?
+ end
end
end
end
diff --git a/spec/ruby/core/range/shared/cover_and_include.rb b/spec/ruby/core/range/shared/cover_and_include.rb
index f36a2cef8b..7028afaa89 100644
--- a/spec/ruby/core/range/shared/cover_and_include.rb
+++ b/spec/ruby/core/range/shared/cover_and_include.rb
@@ -57,6 +57,7 @@ describe :range_cover_and_include, shared: true do
it "returns true if argument is less than the last value of the range and greater than the first value" do
(20..30).send(@method, 28).should be_true
('e'..'h').send(@method, 'g').should be_true
+ ("\u{999}".."\u{9999}").send @method, "\u{9995}"
end
it "returns true if argument is sole element in the range" do
diff --git a/spec/ruby/core/range/size_spec.rb b/spec/ruby/core/range/size_spec.rb
index 81ea5a3846..9b625c9963 100644
--- a/spec/ruby/core/range/size_spec.rb
+++ b/spec/ruby/core/range/size_spec.rb
@@ -44,12 +44,12 @@ describe "Range#size" do
end
ruby_version_is "3.2" do
- it 'returns Float::INFINITY for all beginless ranges if the end is numeric' do
+ it 'returns Float::INFINITY for all beginless ranges if the start is numeric' do
(..1).size.should == Float::INFINITY
(...0.5).size.should == Float::INFINITY
end
- it 'returns nil for all beginless ranges if the end is not numeric' do
+ it 'returns nil for all beginless ranges if the start is numeric' do
(...'o').size.should == nil
end
diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb
index 64ea3de4ed..61ddc5205d 100644
--- a/spec/ruby/core/range/step_spec.rb
+++ b/spec/ruby/core/range/step_spec.rb
@@ -377,21 +377,48 @@ describe "Range#step" do
end
describe "when no block is given" do
- it "raises an ArgumentError if step is 0" do
- -> { (-1..1).step(0) }.should raise_error(ArgumentError)
+ ruby_version_is "3.0" do
+ it "raises an ArgumentError if step is 0" do
+ -> { (-1..1).step(0) }.should raise_error(ArgumentError)
+ end
end
describe "returned Enumerator" do
describe "size" do
- it "raises a TypeError if step does not respond to #to_int" do
- obj = mock("Range#step non-integer")
- -> { (1..2).step(obj) }.should raise_error(TypeError)
+ ruby_version_is ""..."3.0" do
+ it "raises a TypeError if step does not respond to #to_int" do
+ obj = mock("Range#step non-integer")
+ enum = (1..2).step(obj)
+ -> { enum.size }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError if #to_int does not return an Integer" do
+ obj = mock("Range#step non-integer")
+ obj.should_receive(:to_int).and_return("1")
+ enum = (1..2).step(obj)
+
+ -> { enum.size }.should raise_error(TypeError)
+ end
end
- it "raises a TypeError if #to_int does not return an Integer" do
- obj = mock("Range#step non-integer")
- obj.should_receive(:to_int).and_return("1")
- -> { (1..2).step(obj) }.should raise_error(TypeError)
+ ruby_version_is "3.0" do
+ it "raises a TypeError if step does not respond to #to_int" do
+ obj = mock("Range#step non-integer")
+ -> { (1..2).step(obj) }.should raise_error(TypeError)
+ end
+
+ it "raises a TypeError if #to_int does not return an Integer" do
+ obj = mock("Range#step non-integer")
+ obj.should_receive(:to_int).and_return("1")
+ -> { (1..2).step(obj) }.should raise_error(TypeError)
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "returns Float::INFINITY for zero step" do
+ (-1..1).step(0).size.should == Float::INFINITY
+ (-1..1).step(0.0).size.should == Float::INFINITY
+ end
end
it "returns the ceil of range size divided by the number of steps" do
@@ -447,14 +474,10 @@ describe "Range#step" do
end
end
- # We use .take below to ensure the enumerator works
- # because that's an Enumerable method and so it uses the Enumerator behavior
- # not just a method overridden in Enumerator::ArithmeticSequence.
describe "type" do
context "when both begin and end are numerics" do
it "returns an instance of Enumerator::ArithmeticSequence" do
(1..10).step.class.should == Enumerator::ArithmeticSequence
- (1..10).step(3).take(4).should == [1, 4, 7, 10]
end
end
@@ -467,12 +490,10 @@ describe "Range#step" do
context "when range is endless" do
it "returns an instance of Enumerator::ArithmeticSequence when begin is numeric" do
(1..).step.class.should == Enumerator::ArithmeticSequence
- (1..).step(2).take(3).should == [1, 3, 5]
end
it "returns an instance of Enumerator when begin is not numeric" do
("a"..).step.class.should == Enumerator
- ("a"..).step(2).take(3).should == %w[a c e]
end
end
@@ -485,7 +506,6 @@ describe "Range#step" do
context "when begin and end are not numerics" do
it "returns an instance of Enumerator" do
("a".."z").step.class.should == Enumerator
- ("a".."z").step(3).take(4).should == %w[a d g j]
end
end
end
diff --git a/spec/ruby/core/rational/abs_spec.rb b/spec/ruby/core/rational/abs_spec.rb
index 7272ad2422..aed7713058 100644
--- a/spec/ruby/core/rational/abs_spec.rb
+++ b/spec/ruby/core/rational/abs_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/abs'
describe "Rational#abs" do
diff --git a/spec/ruby/core/rational/ceil_spec.rb b/spec/ruby/core/rational/ceil_spec.rb
index e736351604..5b0ca4a9d6 100644
--- a/spec/ruby/core/rational/ceil_spec.rb
+++ b/spec/ruby/core/rational/ceil_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/ceil'
describe "Rational#ceil" do
diff --git a/spec/ruby/core/rational/coerce_spec.rb b/spec/ruby/core/rational/coerce_spec.rb
index 9c0f05829b..3f78f0bcd6 100644
--- a/spec/ruby/core/rational/coerce_spec.rb
+++ b/spec/ruby/core/rational/coerce_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/coerce'
describe "Rational#coerce" do
diff --git a/spec/ruby/core/rational/comparison_spec.rb b/spec/ruby/core/rational/comparison_spec.rb
index 877069fb8f..9d8e7fd7ee 100644
--- a/spec/ruby/core/rational/comparison_spec.rb
+++ b/spec/ruby/core/rational/comparison_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/comparison'
describe "Rational#<=> when passed a Rational object" do
diff --git a/spec/ruby/core/rational/denominator_spec.rb b/spec/ruby/core/rational/denominator_spec.rb
index c2f49b4190..6214b40587 100644
--- a/spec/ruby/core/rational/denominator_spec.rb
+++ b/spec/ruby/core/rational/denominator_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/denominator'
describe "Rational#denominator" do
diff --git a/spec/ruby/core/rational/div_spec.rb b/spec/ruby/core/rational/div_spec.rb
index bee7d01a67..1cd8606b90 100644
--- a/spec/ruby/core/rational/div_spec.rb
+++ b/spec/ruby/core/rational/div_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/div'
describe "Rational#div" do
diff --git a/spec/ruby/core/rational/divide_spec.rb b/spec/ruby/core/rational/divide_spec.rb
index 14e8c4c195..d8e3a44dc2 100644
--- a/spec/ruby/core/rational/divide_spec.rb
+++ b/spec/ruby/core/rational/divide_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/divide'
require_relative '../../shared/rational/arithmetic_exception_in_coerce'
diff --git a/spec/ruby/core/rational/divmod_spec.rb b/spec/ruby/core/rational/divmod_spec.rb
index 7ffdde74f4..6be1f8bd73 100644
--- a/spec/ruby/core/rational/divmod_spec.rb
+++ b/spec/ruby/core/rational/divmod_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/divmod'
describe "Rational#divmod when passed a Rational" do
diff --git a/spec/ruby/core/rational/equal_value_spec.rb b/spec/ruby/core/rational/equal_value_spec.rb
index c6f7f4c6a2..8e7acb1354 100644
--- a/spec/ruby/core/rational/equal_value_spec.rb
+++ b/spec/ruby/core/rational/equal_value_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/equal_value'
describe "Rational#==" do
diff --git a/spec/ruby/core/rational/exponent_spec.rb b/spec/ruby/core/rational/exponent_spec.rb
index 7e35b4ebc1..622cf22782 100644
--- a/spec/ruby/core/rational/exponent_spec.rb
+++ b/spec/ruby/core/rational/exponent_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/exponent'
describe "Rational#**" do
diff --git a/spec/ruby/core/rational/fdiv_spec.rb b/spec/ruby/core/rational/fdiv_spec.rb
index b75f39abd5..bfb321abaa 100644
--- a/spec/ruby/core/rational/fdiv_spec.rb
+++ b/spec/ruby/core/rational/fdiv_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/fdiv'
describe "Rational#fdiv" do
diff --git a/spec/ruby/core/rational/floor_spec.rb b/spec/ruby/core/rational/floor_spec.rb
index 70db0499d0..752a2d8815 100644
--- a/spec/ruby/core/rational/floor_spec.rb
+++ b/spec/ruby/core/rational/floor_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/floor'
describe "Rational#floor" do
diff --git a/spec/ruby/core/rational/hash_spec.rb b/spec/ruby/core/rational/hash_spec.rb
index 7e8d30049b..84cd31518a 100644
--- a/spec/ruby/core/rational/hash_spec.rb
+++ b/spec/ruby/core/rational/hash_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/hash'
describe "Rational#hash" do
diff --git a/spec/ruby/core/rational/inspect_spec.rb b/spec/ruby/core/rational/inspect_spec.rb
index 2cbf6cadc1..ef337ef0ce 100644
--- a/spec/ruby/core/rational/inspect_spec.rb
+++ b/spec/ruby/core/rational/inspect_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/inspect'
describe "Rational#inspect" do
diff --git a/spec/ruby/core/rational/integer_spec.rb b/spec/ruby/core/rational/integer_spec.rb
index be7476a9dd..0f9a3bdead 100644
--- a/spec/ruby/core/rational/integer_spec.rb
+++ b/spec/ruby/core/rational/integer_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
describe "Rational#integer?" do
# Guard against the Mathn library
guard -> { !defined?(Math.rsqrt) } do
diff --git a/spec/ruby/core/rational/magnitude_spec.rb b/spec/ruby/core/rational/magnitude_spec.rb
index 27d9af6a81..878fc8f879 100644
--- a/spec/ruby/core/rational/magnitude_spec.rb
+++ b/spec/ruby/core/rational/magnitude_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/abs'
describe "Rational#abs" do
diff --git a/spec/ruby/core/rational/modulo_spec.rb b/spec/ruby/core/rational/modulo_spec.rb
index 7a60c176ac..c43f7788e3 100644
--- a/spec/ruby/core/rational/modulo_spec.rb
+++ b/spec/ruby/core/rational/modulo_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/modulo'
describe "Rational#%" do
diff --git a/spec/ruby/core/rational/multiply_spec.rb b/spec/ruby/core/rational/multiply_spec.rb
index 7413376bb1..ea644074e9 100644
--- a/spec/ruby/core/rational/multiply_spec.rb
+++ b/spec/ruby/core/rational/multiply_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/multiply'
require_relative '../../shared/rational/arithmetic_exception_in_coerce'
diff --git a/spec/ruby/core/rational/numerator_spec.rb b/spec/ruby/core/rational/numerator_spec.rb
index 6f9a9c0e3b..85b2ed9e86 100644
--- a/spec/ruby/core/rational/numerator_spec.rb
+++ b/spec/ruby/core/rational/numerator_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/numerator'
describe "Rational#numerator" do
diff --git a/spec/ruby/core/rational/plus_spec.rb b/spec/ruby/core/rational/plus_spec.rb
index 67c0ff63d2..e7ef3a8f92 100644
--- a/spec/ruby/core/rational/plus_spec.rb
+++ b/spec/ruby/core/rational/plus_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/plus'
require_relative '../../shared/rational/arithmetic_exception_in_coerce'
diff --git a/spec/ruby/core/rational/quo_spec.rb b/spec/ruby/core/rational/quo_spec.rb
index 181f091f7c..119aca1955 100644
--- a/spec/ruby/core/rational/quo_spec.rb
+++ b/spec/ruby/core/rational/quo_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/divide'
describe "Rational#quo" do
diff --git a/spec/ruby/core/rational/remainder_spec.rb b/spec/ruby/core/rational/remainder_spec.rb
index 1c0035e5f4..0f9442f6f5 100644
--- a/spec/ruby/core/rational/remainder_spec.rb
+++ b/spec/ruby/core/rational/remainder_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/remainder'
describe "Rational#remainder" do
diff --git a/spec/ruby/core/rational/to_f_spec.rb b/spec/ruby/core/rational/to_f_spec.rb
index a9cd1be3b5..15bf1e88dc 100644
--- a/spec/ruby/core/rational/to_f_spec.rb
+++ b/spec/ruby/core/rational/to_f_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/to_f'
describe "Rational#to_f" do
diff --git a/spec/ruby/core/rational/to_i_spec.rb b/spec/ruby/core/rational/to_i_spec.rb
index 22cf02b4da..3deb3664e1 100644
--- a/spec/ruby/core/rational/to_i_spec.rb
+++ b/spec/ruby/core/rational/to_i_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/to_i'
describe "Rational#to_i" do
diff --git a/spec/ruby/core/rational/to_r_spec.rb b/spec/ruby/core/rational/to_r_spec.rb
index 03f204daf1..cc704c965e 100644
--- a/spec/ruby/core/rational/to_r_spec.rb
+++ b/spec/ruby/core/rational/to_r_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/to_r'
describe "Rational#to_r" do
diff --git a/spec/ruby/core/rational/to_s_spec.rb b/spec/ruby/core/rational/to_s_spec.rb
index 5d90c7d80b..c5c419787c 100644
--- a/spec/ruby/core/rational/to_s_spec.rb
+++ b/spec/ruby/core/rational/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/to_s'
describe "Rational#to_s" do
diff --git a/spec/ruby/core/rational/truncate_spec.rb b/spec/ruby/core/rational/truncate_spec.rb
index 47a7cdf17c..4e72339752 100644
--- a/spec/ruby/core/rational/truncate_spec.rb
+++ b/spec/ruby/core/rational/truncate_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative '../../shared/rational/truncate'
describe "Rational#truncate" do
diff --git a/spec/ruby/core/rational/zero_spec.rb b/spec/ruby/core/rational/zero_spec.rb
index af7fb391ac..e6dd751922 100644
--- a/spec/ruby/core/rational/zero_spec.rb
+++ b/spec/ruby/core/rational/zero_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
describe "Rational#zero?" do
it "returns true if the numerator is 0" do
Rational(0,26).zero?.should be_true
diff --git a/spec/ruby/core/refinement/extend_object_spec.rb b/spec/ruby/core/refinement/extend_object_spec.rb
index 6c2a0af4f3..e44e9f46d8 100644
--- a/spec/ruby/core/refinement/extend_object_spec.rb
+++ b/spec/ruby/core/refinement/extend_object_spec.rb
@@ -11,10 +11,8 @@ describe "Refinement#extend_object" do
Module.new do
refine c do
called = false
- define_method(:extend_object) { called = true }
- -> {
- c.extend(self)
- }.should raise_error(TypeError)
+ define_method(:extend_object){called = true}
+ proc{c.extend(self)}.should raise_error(TypeError)
called.should == false
end
end
diff --git a/spec/ruby/core/refinement/fixtures/classes.rb b/spec/ruby/core/refinement/fixtures/classes.rb
deleted file mode 100644
index 94324db47c..0000000000
--- a/spec/ruby/core/refinement/fixtures/classes.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module RefinementSpec
-
- module ModuleWithAncestors
- include Module.new do
- def indent(level)
- " " * level + self
- end
- end
- end
-end
diff --git a/spec/ruby/core/refinement/import_methods_spec.rb b/spec/ruby/core/refinement/import_methods_spec.rb
index 05973b2380..1c526f5822 100644
--- a/spec/ruby/core/refinement/import_methods_spec.rb
+++ b/spec/ruby/core/refinement/import_methods_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
describe "Refinement#import_methods" do
ruby_version_is "3.1" do
@@ -18,229 +17,6 @@ describe "Refinement#import_methods" do
end
end
end
-
- it "throws an exception when argument is not a module" do
- Module.new do
- refine String do
- -> {
- import_methods Integer
- }.should raise_error(TypeError, "wrong argument type Class (expected Module)")
- end
- end
- end
-
- it "imports methods from multiple modules" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- str_utils_fancy = Module.new do
- def indent_star(level)
- "*" * level + self
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils, str_utils_fancy
- "foo".indent(3).should == " foo"
- "foo".indent_star(3).should == "***foo"
- end
- end
- end
-
- it "imports a method defined in the last module if method with same name is defined in multiple modules" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- str_utils_fancy = Module.new do
- def indent(level)
- "*" * level + self
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils, str_utils_fancy
- "foo".indent(3).should == "***foo"
- end
- end
- end
-
- it "still imports methods of modules listed before a module that contains method not defined in Ruby" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- string_refined = Module.new do
- refine String do
- -> {
- import_methods str_utils, Kernel
- }.should raise_error(ArgumentError)
- end
- end
-
- Module.new do
- using string_refined
- "foo".indent(3).should == " foo"
- end
- end
- end
-
- it "warns if a module includes/prepends some other module" do
- module1 = Module.new do
- end
-
- module2 = Module.new do
- include module1
- end
-
- Module.new do
- refine String do
- -> {
- import_methods module2
- }.should complain(/warning: #<Module:\w*> has ancestors, but Refinement#import_methods doesn't import their methods/)
- end
- end
-
- Module.new do
- refine String do
- -> {
- import_methods RefinementSpec::ModuleWithAncestors
- }.should complain(/warning: RefinementSpec::ModuleWithAncestors has ancestors, but Refinement#import_methods doesn't import their methods/)
- end
- end
- end
-
- it "doesn't import methods from included/prepended modules" do
- Module.new do
- refine String do
- suppress_warning { import_methods RefinementSpec::ModuleWithAncestors }
- end
-
- using self
- -> {
- "foo".indent(3)
- }.should raise_error(NoMethodError, /undefined method `indent' for ("foo":String|an instance of String)/)
- end
- end
-
- it "doesn't import any methods if one of the arguments is not a module" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- string_refined = Module.new do
- refine String do
- -> {
- import_methods str_utils, Integer
- }.should raise_error(TypeError)
- end
- end
-
- Module.new do
- using string_refined
- -> {
- "foo".indent(3)
- }.should raise_error(NoMethodError)
- end
- end
-
- it "imports methods from multiple modules so that methods see other's module's methods" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- str_utils_normal = Module.new do
- def indent_normal(level)
- self.indent(level)
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils, str_utils_normal
- end
-
- using self
- "foo".indent_normal(3).should == " foo"
- end
- end
-
- it "imports methods from module so that methods can see each other" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
-
- def indent_with_dot(level)
- self.indent(level) + "."
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils
- end
-
- using self
- "foo".indent_with_dot(3).should == " foo."
- end
- end
-
- it "doesn't import module's class methods" do
- str_utils = Module.new do
- def self.indent(level)
- " " * level + self
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils
- end
-
- using self
- -> {
- String.indent(3)
- }.should raise_error(NoMethodError, /undefined method `indent' for (String:Class|class String)/)
- end
- end
-
- it "imports module methods with super" do
- class_to_refine = Class.new do
- def foo(number)
- 2 * number
- end
- end
-
- extension = Module.new do
- def foo(number)
- super * 2
- end
- end
-
- refinement = Module.new do
- refine class_to_refine do
- import_methods extension
- end
- end
-
- Module.new do
- using refinement
- class_to_refine.new.foo(2).should == 8
- end
end
context "when methods are not defined in Ruby code" do
@@ -253,17 +29,6 @@ describe "Refinement#import_methods" do
end
end
end
-
- it "raises ArgumentError when importing methods from C extension" do
- require 'zlib'
- Module.new do
- refine String do
- -> {
- import_methods Zlib
- }.should raise_error(ArgumentError, /Can't import method which is not defined with Ruby code: Zlib#*/)
- end
- end
- end
end
end
end
diff --git a/spec/ruby/core/refinement/refined_class_spec.rb b/spec/ruby/core/refinement/refined_class_spec.rb
deleted file mode 100644
index 00b65d0895..0000000000
--- a/spec/ruby/core/refinement/refined_class_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Refinement#refined_class" do
- ruby_version_is "3.2"..."3.3" do
- it "returns the class refined by the receiver" do
- refinement_int = nil
-
- Module.new do
- refine Integer do
- refinement_int = self
- end
- end
-
- refinement_int.refined_class.should == Integer
- end
- end
-end
diff --git a/spec/ruby/core/regexp/initialize_spec.rb b/spec/ruby/core/regexp/initialize_spec.rb
index dd57292242..a1583384af 100644
--- a/spec/ruby/core/regexp/initialize_spec.rb
+++ b/spec/ruby/core/regexp/initialize_spec.rb
@@ -5,8 +5,16 @@ describe "Regexp#initialize" do
Regexp.should have_private_instance_method(:initialize)
end
- it "raises a FrozenError on a Regexp literal" do
- -> { //.send(:initialize, "") }.should raise_error(FrozenError)
+ ruby_version_is ""..."3.0" do
+ it "raises a SecurityError on a Regexp literal" do
+ -> { //.send(:initialize, "") }.should raise_error(SecurityError)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "raises a FrozenError on a Regexp literal" do
+ -> { //.send(:initialize, "") }.should raise_error(FrozenError)
+ end
end
it "raises a TypeError on an initialized non-literal Regexp" do
diff --git a/spec/ruby/core/regexp/linear_time_spec.rb b/spec/ruby/core/regexp/linear_time_spec.rb
deleted file mode 100644
index 4dc436264f..0000000000
--- a/spec/ruby/core/regexp/linear_time_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require_relative '../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Regexp.linear_time?" do
- it "returns true if matching can be done in linear time" do
- Regexp.linear_time?(/a/).should == true
- Regexp.linear_time?('a').should == true
- end
-
- it "return false if matching can't be done in linear time" do
- Regexp.linear_time?(/(a)\1/).should == false
- Regexp.linear_time?("(a)\\1").should == false
- end
-
- it "accepts flags for string argument" do
- Regexp.linear_time?('a', Regexp::IGNORECASE).should == true
- end
-
- it "warns about flags being ignored for regexp arguments" do
- -> {
- Regexp.linear_time?(/a/, Regexp::IGNORECASE)
- }.should complain(/warning: flags ignored/)
- end
- end
-end
diff --git a/spec/ruby/core/regexp/shared/new.rb b/spec/ruby/core/regexp/shared/new.rb
index 773882e495..058a51b1aa 100644
--- a/spec/ruby/core/regexp/shared/new.rb
+++ b/spec/ruby/core/regexp/shared/new.rb
@@ -432,10 +432,6 @@ describe :regexp_new_string, shared: true do
Regexp.send(@method, "\056\x42\u3042\x52\076").should == /#{"\x2e\x42\u3042\x52\x3e"}/
end
- it "accepts a multiple byte character which need not be escaped" do
- Regexp.send(@method, "\§").should == /#{"§"}/
- end
-
it "raises a RegexpError if less than four digits are given for \\uHHHH" do
-> { Regexp.send(@method, "\\" + "u304") }.should raise_error(RegexpError)
end
diff --git a/spec/ruby/core/regexp/try_convert_spec.rb b/spec/ruby/core/regexp/try_convert_spec.rb
index e775dbe971..be567e2130 100644
--- a/spec/ruby/core/regexp/try_convert_spec.rb
+++ b/spec/ruby/core/regexp/try_convert_spec.rb
@@ -18,10 +18,4 @@ describe "Regexp.try_convert" do
rex.should_receive(:to_regexp).and_return(/(p(a)t[e]rn)/)
Regexp.try_convert(rex).should == /(p(a)t[e]rn)/
end
-
- it "raises a TypeError if the object does not return an Regexp from #to_regexp" do
- obj = mock("regexp")
- obj.should_receive(:to_regexp).and_return("string")
- -> { Regexp.try_convert(obj) }.should raise_error(TypeError, "can't convert MockObject to Regexp (MockObject#to_regexp gives String)")
- end
end
diff --git a/spec/ruby/core/regexp/union_spec.rb b/spec/ruby/core/regexp/union_spec.rb
index ea5a5053f7..8076836471 100644
--- a/spec/ruby/core/regexp/union_spec.rb
+++ b/spec/ruby/core/regexp/union_spec.rb
@@ -43,27 +43,6 @@ describe "Regexp.union" do
Regexp.union("\u00A9".encode("ISO-8859-1"), "a".encode("UTF-8")).encoding.should == Encoding::ISO_8859_1
end
- it "returns ASCII-8BIT if the regexp encodings are ASCII-8BIT and at least one has non-ASCII characters" do
- us_ascii_implicit, us_ascii_explicit, binary = /abc/, /[\x00-\x7f]/n, /[\x80-\xBF]/n
- us_ascii_implicit.encoding.should == Encoding::US_ASCII
- us_ascii_explicit.encoding.should == Encoding::US_ASCII
- binary.encoding.should == Encoding::BINARY
-
- Regexp.union(us_ascii_implicit, us_ascii_explicit, binary).encoding.should == Encoding::BINARY
- Regexp.union(us_ascii_implicit, binary, us_ascii_explicit).encoding.should == Encoding::BINARY
- Regexp.union(us_ascii_explicit, us_ascii_implicit, binary).encoding.should == Encoding::BINARY
- Regexp.union(us_ascii_explicit, binary, us_ascii_implicit).encoding.should == Encoding::BINARY
- Regexp.union(binary, us_ascii_implicit, us_ascii_explicit).encoding.should == Encoding::BINARY
- Regexp.union(binary, us_ascii_explicit, us_ascii_implicit).encoding.should == Encoding::BINARY
- end
-
- it "return US-ASCII if all patterns are ASCII-only" do
- Regexp.union(/abc/e, /def/e).encoding.should == Encoding::US_ASCII
- Regexp.union(/abc/n, /def/n).encoding.should == Encoding::US_ASCII
- Regexp.union(/abc/s, /def/s).encoding.should == Encoding::US_ASCII
- Regexp.union(/abc/u, /def/u).encoding.should == Encoding::US_ASCII
- end
-
it "returns a Regexp with UTF-8 if one part is UTF-8" do
Regexp.union(/probl[éeè]me/i, /help/i).encoding.should == Encoding::UTF_8
end
@@ -75,83 +54,83 @@ describe "Regexp.union" do
it "raises ArgumentError if the arguments include conflicting ASCII-incompatible Strings" do
-> {
Regexp.union("a".encode("UTF-16LE"), "b".encode("UTF-16BE"))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and UTF-16BE')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include conflicting ASCII-incompatible Regexps" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")),
Regexp.new("b".encode("UTF-16BE")))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and UTF-16BE')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include conflicting fixed encoding Regexps" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-8"), Regexp::FIXEDENCODING),
Regexp.new("b".encode("US-ASCII"), Regexp::FIXEDENCODING))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-8 and US-ASCII')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include a fixed encoding Regexp and a String containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-8"), Regexp::FIXEDENCODING),
"\u00A9".encode("ISO-8859-1"))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-8 and ISO-8859-1')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include a String containing non-ASCII-compatible characters and a fixed encoding Regexp in a different encoding" do
-> {
Regexp.union("\u00A9".encode("ISO-8859-1"),
Regexp.new("a".encode("UTF-8"), Regexp::FIXEDENCODING))
- }.should raise_error(ArgumentError, 'incompatible encodings: ISO-8859-1 and UTF-8')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and an ASCII-only String" do
-> {
Regexp.union("a".encode("UTF-16LE"), "b".encode("UTF-8"))
- }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and an ASCII-only String" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), "b".encode("UTF-8"))
- }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and an ASCII-only Regexp" do
-> {
Regexp.union("a".encode("UTF-16LE"), Regexp.new("b".encode("UTF-8")))
- }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and an ASCII-only Regexp" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), Regexp.new("b".encode("UTF-8")))
- }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and a String containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union("a".encode("UTF-16LE"), "\u00A9".encode("ISO-8859-1"))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and a String containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), "\u00A9".encode("ISO-8859-1"))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and a Regexp containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union("a".encode("UTF-16LE"), Regexp.new("\u00A9".encode("ISO-8859-1")))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
+ }.should raise_error(ArgumentError)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and a Regexp containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), Regexp.new("\u00A9".encode("ISO-8859-1")))
- }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
+ }.should raise_error(ArgumentError)
end
it "uses to_str to convert arguments (if not Regexp)" do
@@ -175,8 +154,6 @@ describe "Regexp.union" do
not_supported_on :opal do
Regexp.union([/dogs/, /cats/i]).should == /(?-mix:dogs)|(?i-mx:cats)/
end
- -> {
- Regexp.union(["skiing", "sledding"], [/dogs/, /cats/i])
- }.should raise_error(TypeError, 'no implicit conversion of Array into String')
+ ->{Regexp.union(["skiing", "sledding"], [/dogs/, /cats/i])}.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/signal/signame_spec.rb b/spec/ruby/core/signal/signame_spec.rb
index adfe895d97..b66de9fc85 100644
--- a/spec/ruby/core/signal/signame_spec.rb
+++ b/spec/ruby/core/signal/signame_spec.rb
@@ -9,22 +9,10 @@ describe "Signal.signame" do
Signal.signame(-1).should == nil
end
- it "calls #to_int on an object to convert to an Integer" do
- obj = mock('signal')
- obj.should_receive(:to_int).and_return(0)
- Signal.signame(obj).should == "EXIT"
- end
-
it "raises a TypeError when the passed argument can't be coerced to Integer" do
-> { Signal.signame("hello") }.should raise_error(TypeError)
end
- it "raises a TypeError when the passed argument responds to #to_int but does not return an Integer" do
- obj = mock('signal')
- obj.should_receive(:to_int).and_return('not an int')
- -> { Signal.signame(obj) }.should raise_error(TypeError)
- end
-
platform_is_not :windows do
it "the original should take precedence over alias when looked up by number" do
Signal.signame(Signal.list["ABRT"]).should == "ABRT"
diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb
index b3186cda92..10e122e072 100644
--- a/spec/ruby/core/signal/trap_spec.rb
+++ b/spec/ruby/core/signal/trap_spec.rb
@@ -221,25 +221,6 @@ describe "Signal.trap" do
Signal.trap(:HUP, @saved_trap).should equal(@proc)
end
- it "calls #to_str on an object to convert to a String" do
- obj = mock("signal")
- obj.should_receive(:to_str).exactly(2).times.and_return("HUP")
- Signal.trap obj, @proc
- Signal.trap(obj, @saved_trap).should equal(@proc)
- end
-
- it "accepts Integer values" do
- hup = Signal.list["HUP"]
- Signal.trap hup, @proc
- Signal.trap(hup, @saved_trap).should equal(@proc)
- end
-
- it "does not call #to_int on an object to convert to an Integer" do
- obj = mock("signal")
- obj.should_not_receive(:to_int)
- -> { Signal.trap obj, @proc }.should raise_error(ArgumentError, /bad signal type/)
- end
-
it "raises ArgumentError when passed unknown signal" do
-> { Signal.trap(300) { } }.should raise_error(ArgumentError, "invalid signal number (300)")
-> { Signal.trap("USR10") { } }.should raise_error(ArgumentError, "unsupported signal `SIGUSR10'")
diff --git a/spec/ruby/core/sizedqueue/append_spec.rb b/spec/ruby/core/sizedqueue/append_spec.rb
index 6fffe2f272..ca79068930 100644
--- a/spec/ruby/core/sizedqueue/append_spec.rb
+++ b/spec/ruby/core/sizedqueue/append_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
require_relative '../../shared/sizedqueue/enque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "SizedQueue#<<" do
it_behaves_like :queue_enq, :<<, -> { SizedQueue.new(10) }
@@ -10,9 +9,3 @@ end
describe "SizedQueue#<<" do
it_behaves_like :sizedqueue_enq, :<<, -> n { SizedQueue.new(n) }
end
-
-describe "SizedQueue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = SizedQueue.new(1); q.send(:<<, 1, timeout: v) }
- end
-end
diff --git a/spec/ruby/core/sizedqueue/deq_spec.rb b/spec/ruby/core/sizedqueue/deq_spec.rb
index 985d654bb3..5e1bd9f746 100644
--- a/spec/ruby/core/sizedqueue/deq_spec.rb
+++ b/spec/ruby/core/sizedqueue/deq_spec.rb
@@ -1,13 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "SizedQueue#deq" do
it_behaves_like :queue_deq, :deq, -> { SizedQueue.new(10) }
end
-
-describe "SizedQueue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = SizedQueue.new(10); q.push(1); q.deq(timeout: v) }
- end
-end
diff --git a/spec/ruby/core/sizedqueue/enq_spec.rb b/spec/ruby/core/sizedqueue/enq_spec.rb
index 619373e46b..3821afac95 100644
--- a/spec/ruby/core/sizedqueue/enq_spec.rb
+++ b/spec/ruby/core/sizedqueue/enq_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
require_relative '../../shared/sizedqueue/enque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "SizedQueue#enq" do
it_behaves_like :queue_enq, :enq, -> { SizedQueue.new(10) }
@@ -10,9 +9,3 @@ end
describe "SizedQueue#enq" do
it_behaves_like :sizedqueue_enq, :enq, -> n { SizedQueue.new(n) }
end
-
-describe "SizedQueue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = SizedQueue.new(1); q.enq(1, timeout: v) }
- end
-end
diff --git a/spec/ruby/core/sizedqueue/pop_spec.rb b/spec/ruby/core/sizedqueue/pop_spec.rb
index 5e7cfea8fb..a0cf6f509c 100644
--- a/spec/ruby/core/sizedqueue/pop_spec.rb
+++ b/spec/ruby/core/sizedqueue/pop_spec.rb
@@ -1,13 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "SizedQueue#pop" do
it_behaves_like :queue_deq, :pop, -> { SizedQueue.new(10) }
end
-
-describe "SizedQueue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = SizedQueue.new(10); q.push(1); q.pop(timeout: v) }
- end
-end
diff --git a/spec/ruby/core/sizedqueue/push_spec.rb b/spec/ruby/core/sizedqueue/push_spec.rb
index ce61e89b53..bba9be9e3f 100644
--- a/spec/ruby/core/sizedqueue/push_spec.rb
+++ b/spec/ruby/core/sizedqueue/push_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
require_relative '../../shared/sizedqueue/enque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "SizedQueue#push" do
it_behaves_like :queue_enq, :push, -> { SizedQueue.new(10) }
@@ -10,9 +9,3 @@ end
describe "SizedQueue#push" do
it_behaves_like :sizedqueue_enq, :push, -> n { SizedQueue.new(n) }
end
-
-describe "SizedQueue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = SizedQueue.new(1); q.push(1, timeout: v) }
- end
-end
diff --git a/spec/ruby/core/sizedqueue/shift_spec.rb b/spec/ruby/core/sizedqueue/shift_spec.rb
index 3220801f3a..5138e68258 100644
--- a/spec/ruby/core/sizedqueue/shift_spec.rb
+++ b/spec/ruby/core/sizedqueue/shift_spec.rb
@@ -1,13 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
-require_relative '../../shared/types/rb_num2dbl_fails'
describe "SizedQueue#shift" do
it_behaves_like :queue_deq, :shift, -> { SizedQueue.new(10) }
end
-
-describe "SizedQueue operations with timeout" do
- ruby_version_is "3.2" do
- it_behaves_like :rb_num2dbl_fails, nil, -> v { q = SizedQueue.new(10); q.push(1); q.shift(timeout: v) }
- end
-end
diff --git a/spec/ruby/core/string/append_spec.rb b/spec/ruby/core/string/append_spec.rb
index 8497ce8262..e001257621 100644
--- a/spec/ruby/core/string/append_spec.rb
+++ b/spec/ruby/core/string/append_spec.rb
@@ -5,7 +5,6 @@ require_relative 'shared/concat'
describe "String#<<" do
it_behaves_like :string_concat, :<<
it_behaves_like :string_concat_encoding, :<<
- it_behaves_like :string_concat_type_coercion, :<<
it "raises an ArgumentError when given the incorrect number of arguments" do
-> { "hello".send(:<<) }.should raise_error(ArgumentError)
diff --git a/spec/ruby/core/string/byteindex_spec.rb b/spec/ruby/core/string/byteindex_spec.rb
index 7be0c7ec1e..af70c729e8 100644
--- a/spec/ruby/core/string/byteindex_spec.rb
+++ b/spec/ruby/core/string/byteindex_spec.rb
@@ -1,304 +1,16 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-require_relative 'shared/byte_index_common.rb'
-
-describe "String#byteindex" do
- ruby_version_is "3.2" do
- it "calls #to_str to convert the first argument" do
- char = mock("string index char")
- char.should_receive(:to_str).and_return("b")
- "abc".byteindex(char).should == 1
- end
-
- it "calls #to_int to convert the second argument" do
- offset = mock("string index offset")
- offset.should_receive(:to_int).and_return(1)
- "abc".byteindex("c", offset).should == 2
- end
-
- it "does not raise IndexError when byte offset is correct or on string boundary" do
- "ã‚".byteindex("").should == 0
- "ã‚".byteindex("", 0).should == 0
- "ã‚".byteindex("", 3).should == 3
- end
-
- it_behaves_like :byte_index_common, :byteindex
- end
-end
-
-describe "String#byteindex with String" do
- ruby_version_is "3.2" do
- it "behaves the same as String#byteindex(char) for one-character strings" do
- "blablabla hello cruel world...!".split("").uniq.each do |str|
- chr = str[0]
- str.byteindex(str).should == str.byteindex(chr)
-
- 0.upto(str.size + 1) do |start|
- str.byteindex(str, start).should == str.byteindex(chr, start)
- end
-
- (-str.size - 1).upto(-1) do |start|
- str.byteindex(str, start).should == str.byteindex(chr, start)
- end
- end
- end
-
- it "returns the byteindex of the first occurrence of the given substring" do
- "blablabla".byteindex("").should == 0
- "blablabla".byteindex("b").should == 0
- "blablabla".byteindex("bla").should == 0
- "blablabla".byteindex("blabla").should == 0
- "blablabla".byteindex("blablabla").should == 0
-
- "blablabla".byteindex("l").should == 1
- "blablabla".byteindex("la").should == 1
- "blablabla".byteindex("labla").should == 1
- "blablabla".byteindex("lablabla").should == 1
-
- "blablabla".byteindex("a").should == 2
- "blablabla".byteindex("abla").should == 2
- "blablabla".byteindex("ablabla").should == 2
- end
-
- it "treats the offset as a byteindex" do
- "aaaaa".byteindex("a", 0).should == 0
- "aaaaa".byteindex("a", 2).should == 2
- "aaaaa".byteindex("a", 4).should == 4
- end
-
- it "ignores string subclasses" do
- "blablabla".byteindex(StringSpecs::MyString.new("bla")).should == 0
- StringSpecs::MyString.new("blablabla").byteindex("bla").should == 0
- StringSpecs::MyString.new("blablabla").byteindex(StringSpecs::MyString.new("bla")).should == 0
- end
-
- it "starts the search at the given offset" do
- "blablabla".byteindex("bl", 0).should == 0
- "blablabla".byteindex("bl", 1).should == 3
- "blablabla".byteindex("bl", 2).should == 3
- "blablabla".byteindex("bl", 3).should == 3
-
- "blablabla".byteindex("bla", 0).should == 0
- "blablabla".byteindex("bla", 1).should == 3
- "blablabla".byteindex("bla", 2).should == 3
- "blablabla".byteindex("bla", 3).should == 3
-
- "blablabla".byteindex("blab", 0).should == 0
- "blablabla".byteindex("blab", 1).should == 3
- "blablabla".byteindex("blab", 2).should == 3
- "blablabla".byteindex("blab", 3).should == 3
-
- "blablabla".byteindex("la", 1).should == 1
- "blablabla".byteindex("la", 2).should == 4
- "blablabla".byteindex("la", 3).should == 4
- "blablabla".byteindex("la", 4).should == 4
-
- "blablabla".byteindex("lab", 1).should == 1
- "blablabla".byteindex("lab", 2).should == 4
- "blablabla".byteindex("lab", 3).should == 4
- "blablabla".byteindex("lab", 4).should == 4
-
- "blablabla".byteindex("ab", 2).should == 2
- "blablabla".byteindex("ab", 3).should == 5
- "blablabla".byteindex("ab", 4).should == 5
- "blablabla".byteindex("ab", 5).should == 5
-
- "blablabla".byteindex("", 0).should == 0
- "blablabla".byteindex("", 1).should == 1
- "blablabla".byteindex("", 2).should == 2
- "blablabla".byteindex("", 7).should == 7
- "blablabla".byteindex("", 8).should == 8
- "blablabla".byteindex("", 9).should == 9
- end
-
- it "starts the search at offset + self.length if offset is negative" do
- str = "blablabla"
-
- ["bl", "bla", "blab", "la", "lab", "ab", ""].each do |needle|
- (-str.length .. -1).each do |offset|
- str.byteindex(needle, offset).should ==
- str.byteindex(needle, offset + str.length)
- end
- end
- end
-
- it "returns nil if the substring isn't found" do
- "blablabla".byteindex("B").should == nil
- "blablabla".byteindex("z").should == nil
- "blablabla".byteindex("BLA").should == nil
- "blablabla".byteindex("blablablabla").should == nil
- "blablabla".byteindex("", 10).should == nil
-
- "hello".byteindex("he", 1).should == nil
- "hello".byteindex("he", 2).should == nil
- "I’ve got a multibyte character.\n".byteindex("\n\n").should == nil
- end
-
- it "returns the character byteindex of a multibyte character" do
- "ã‚りãŒã¨ã†".byteindex("ãŒ").should == 6
- end
-
- it "returns the character byteindex after offset" do
- "ã‚れã‚れ".byteindex("ã‚", 3).should == 6
- "ã‚りãŒã¨ã†ã‚りãŒã¨ã†".byteindex("ãŒ", 9).should == 21
- end
-
- it "returns the character byteindex after a partial first match" do
- "</</h".byteindex("</h").should == 2
- end
-
- it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
- char = "れ".encode Encoding::EUC_JP
- -> do
- "ã‚れ".byteindex(char)
- end.should raise_error(Encoding::CompatibilityError)
- end
-
- it "handles a substring in a superset encoding" do
- 'abc'.force_encoding(Encoding::US_ASCII).byteindex('é').should == nil
- end
-
- it "handles a substring in a subset encoding" do
- 'été'.byteindex('t'.force_encoding(Encoding::US_ASCII)).should == 2
- end
- end
-end
describe "String#byteindex with Regexp" do
ruby_version_is "3.2" do
- it "behaves the same as String#byteindex(string) for escaped string regexps" do
- ["blablabla", "hello cruel world...!"].each do |str|
- ["", "b", "bla", "lab", "o c", "d."].each do |needle|
- regexp = Regexp.new(Regexp.escape(needle))
- str.byteindex(regexp).should == str.byteindex(needle)
-
- 0.upto(str.size + 1) do |start|
- str.byteindex(regexp, start).should == str.byteindex(needle, start)
- end
-
- (-str.size - 1).upto(-1) do |start|
- str.byteindex(regexp, start).should == str.byteindex(needle, start)
- end
- end
- end
- end
-
- it "returns the byteindex of the first match of regexp" do
- "blablabla".byteindex(/bla/).should == 0
- "blablabla".byteindex(/BLA/i).should == 0
-
- "blablabla".byteindex(/.{0}/).should == 0
- "blablabla".byteindex(/.{6}/).should == 0
- "blablabla".byteindex(/.{9}/).should == 0
-
- "blablabla".byteindex(/.*/).should == 0
- "blablabla".byteindex(/.+/).should == 0
-
- "blablabla".byteindex(/lab|b/).should == 0
-
- not_supported_on :opal do
- "blablabla".byteindex(/\A/).should == 0
- "blablabla".byteindex(/\Z/).should == 9
- "blablabla".byteindex(/\z/).should == 9
- "blablabla\n".byteindex(/\Z/).should == 9
- "blablabla\n".byteindex(/\z/).should == 10
- end
-
- "blablabla".byteindex(/^/).should == 0
- "\nblablabla".byteindex(/^/).should == 0
- "b\nablabla".byteindex(/$/).should == 1
- "bl\nablabla".byteindex(/$/).should == 2
-
- "blablabla".byteindex(/.l./).should == 0
- end
-
- it "starts the search at the given offset" do
- "blablabla".byteindex(/.{0}/, 5).should == 5
- "blablabla".byteindex(/.{1}/, 5).should == 5
- "blablabla".byteindex(/.{2}/, 5).should == 5
- "blablabla".byteindex(/.{3}/, 5).should == 5
- "blablabla".byteindex(/.{4}/, 5).should == 5
-
- "blablabla".byteindex(/.{0}/, 3).should == 3
- "blablabla".byteindex(/.{1}/, 3).should == 3
- "blablabla".byteindex(/.{2}/, 3).should == 3
- "blablabla".byteindex(/.{5}/, 3).should == 3
- "blablabla".byteindex(/.{6}/, 3).should == 3
-
- "blablabla".byteindex(/.l./, 0).should == 0
- "blablabla".byteindex(/.l./, 1).should == 3
- "blablabla".byteindex(/.l./, 2).should == 3
- "blablabla".byteindex(/.l./, 3).should == 3
-
- "xblaxbla".byteindex(/x./, 0).should == 0
- "xblaxbla".byteindex(/x./, 1).should == 4
- "xblaxbla".byteindex(/x./, 2).should == 4
-
- not_supported_on :opal do
- "blablabla\n".byteindex(/\Z/, 9).should == 9
- end
- end
-
- it "starts the search at offset + self.length if offset is negative" do
- str = "blablabla"
-
- ["bl", "bla", "blab", "la", "lab", "ab", ""].each do |needle|
- (-str.length .. -1).each do |offset|
- str.byteindex(needle, offset).should ==
- str.byteindex(needle, offset + str.length)
- end
- end
- end
-
- it "returns nil if the substring isn't found" do
- "blablabla".byteindex(/BLA/).should == nil
-
- "blablabla".byteindex(/.{10}/).should == nil
- "blaxbla".byteindex(/.x/, 3).should == nil
- "blaxbla".byteindex(/..x/, 2).should == nil
- end
-
- it "returns nil if the Regexp matches the empty string and the offset is out of range" do
- "ruby".byteindex(//, 12).should be_nil
- end
-
- it "supports \\G which matches at the given start offset" do
- "helloYOU.".byteindex(/\GYOU/, 5).should == 5
- "helloYOU.".byteindex(/\GYOU/).should == nil
-
- re = /\G.+YOU/
- # The # marks where \G will match.
- [
- ["#hi!YOUall.", 0],
- ["h#i!YOUall.", 1],
- ["hi#!YOUall.", 2],
- ["hi!#YOUall.", nil]
- ].each do |spec|
-
- start = spec[0].byteindex("#")
- str = spec[0].delete("#")
-
- str.byteindex(re, start).should == spec[1]
- end
- end
-
- it "converts start_offset to an integer via to_int" do
- obj = mock('1')
- obj.should_receive(:to_int).and_return(1)
- "RWOARW".byteindex(/R./, obj).should == 4
- end
-
- it "returns the character byteindex of a multibyte character" do
- "ã‚りãŒã¨ã†".byteindex(/ãŒ/).should == 6
- end
-
- it "returns the character byteindex after offset" do
- "ã‚れã‚れ".byteindex(/ã‚/, 3).should == 6
- end
+ it "always clear $~" do
+ "a".byteindex(/a/)
+ $~.should_not == nil
- it "treats the offset as a byteindex" do
- "ã‚れã‚ã‚れ".byteindex(/ã‚/, 6).should == 6
+ string = "blablabla"
+ string.byteindex(/bla/, string.bytesize + 1)
+ $~.should == nil
end
end
end
diff --git a/spec/ruby/core/string/byterindex_spec.rb b/spec/ruby/core/string/byterindex_spec.rb
deleted file mode 100644
index 717708c97d..0000000000
--- a/spec/ruby/core/string/byterindex_spec.rb
+++ /dev/null
@@ -1,359 +0,0 @@
-# -*- encoding: utf-8 -*-
-require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
-require_relative 'shared/byte_index_common.rb'
-
-describe "String#byterindex with object" do
- ruby_version_is "3.2" do
- it "tries to convert obj to a string via to_str" do
- obj = mock('lo')
- def obj.to_str() "lo" end
- "hello".byterindex(obj).should == "hello".byterindex("lo")
-
- obj = mock('o')
- def obj.respond_to?(arg, *) true end
- def obj.method_missing(*args) "o" end
- "hello".byterindex(obj).should == "hello".byterindex("o")
- end
-
- it "calls #to_int to convert the second argument" do
- offset = mock("string index offset")
- offset.should_receive(:to_int).and_return(3)
- "abc".byterindex("c", offset).should == 2
- end
-
- it "does not raise IndexError when byte offset is correct or on string boundary" do
- "ã‚".byterindex("", 0).should == 0
- "ã‚".byterindex("", 3).should == 3
- "ã‚".byterindex("").should == 3
- end
-
- it_behaves_like :byte_index_common, :byterindex
- end
-end
-
-describe "String#byterindex with String" do
- ruby_version_is "3.2" do
- it "behaves the same as String#byterindex(char) for one-character strings" do
- "blablabla hello cruel world...!".split("").uniq.each do |str|
- chr = str[0]
- str.byterindex(str).should == str.byterindex(chr)
-
- 0.upto(str.size + 1) do |start|
- str.byterindex(str, start).should == str.byterindex(chr, start)
- end
-
- (-str.size - 1).upto(-1) do |start|
- str.byterindex(str, start).should == str.byterindex(chr, start)
- end
- end
- end
-
- it "behaves the same as String#byterindex(?char) for one-character strings" do
- "blablabla hello cruel world...!".split("").uniq.each do |str|
- chr = str[0] =~ / / ? str[0] : eval("?#{str[0]}")
- str.byterindex(str).should == str.byterindex(chr)
-
- 0.upto(str.size + 1) do |start|
- str.byterindex(str, start).should == str.byterindex(chr, start)
- end
-
- (-str.size - 1).upto(-1) do |start|
- str.byterindex(str, start).should == str.byterindex(chr, start)
- end
- end
- end
-
- it "returns the index of the last occurrence of the given substring" do
- "blablabla".byterindex("").should == 9
- "blablabla".byterindex("a").should == 8
- "blablabla".byterindex("la").should == 7
- "blablabla".byterindex("bla").should == 6
- "blablabla".byterindex("abla").should == 5
- "blablabla".byterindex("labla").should == 4
- "blablabla".byterindex("blabla").should == 3
- "blablabla".byterindex("ablabla").should == 2
- "blablabla".byterindex("lablabla").should == 1
- "blablabla".byterindex("blablabla").should == 0
-
- "blablabla".byterindex("l").should == 7
- "blablabla".byterindex("bl").should == 6
- "blablabla".byterindex("abl").should == 5
- "blablabla".byterindex("labl").should == 4
- "blablabla".byterindex("blabl").should == 3
- "blablabla".byterindex("ablabl").should == 2
- "blablabla".byterindex("lablabl").should == 1
- "blablabla".byterindex("blablabl").should == 0
-
- "blablabla".byterindex("b").should == 6
- "blablabla".byterindex("ab").should == 5
- "blablabla".byterindex("lab").should == 4
- "blablabla".byterindex("blab").should == 3
- "blablabla".byterindex("ablab").should == 2
- "blablabla".byterindex("lablab").should == 1
- "blablabla".byterindex("blablab").should == 0
- end
-
- it "ignores string subclasses" do
- "blablabla".byterindex(StringSpecs::MyString.new("bla")).should == 6
- StringSpecs::MyString.new("blablabla").byterindex("bla").should == 6
- StringSpecs::MyString.new("blablabla").byterindex(StringSpecs::MyString.new("bla")).should == 6
- end
-
- it "starts the search at the given offset" do
- "blablabla".byterindex("bl", 0).should == 0
- "blablabla".byterindex("bl", 1).should == 0
- "blablabla".byterindex("bl", 2).should == 0
- "blablabla".byterindex("bl", 3).should == 3
-
- "blablabla".byterindex("bla", 0).should == 0
- "blablabla".byterindex("bla", 1).should == 0
- "blablabla".byterindex("bla", 2).should == 0
- "blablabla".byterindex("bla", 3).should == 3
-
- "blablabla".byterindex("blab", 0).should == 0
- "blablabla".byterindex("blab", 1).should == 0
- "blablabla".byterindex("blab", 2).should == 0
- "blablabla".byterindex("blab", 3).should == 3
- "blablabla".byterindex("blab", 6).should == 3
- "blablablax".byterindex("blab", 6).should == 3
-
- "blablabla".byterindex("la", 1).should == 1
- "blablabla".byterindex("la", 2).should == 1
- "blablabla".byterindex("la", 3).should == 1
- "blablabla".byterindex("la", 4).should == 4
-
- "blablabla".byterindex("lab", 1).should == 1
- "blablabla".byterindex("lab", 2).should == 1
- "blablabla".byterindex("lab", 3).should == 1
- "blablabla".byterindex("lab", 4).should == 4
-
- "blablabla".byterindex("ab", 2).should == 2
- "blablabla".byterindex("ab", 3).should == 2
- "blablabla".byterindex("ab", 4).should == 2
- "blablabla".byterindex("ab", 5).should == 5
-
- "blablabla".byterindex("", 0).should == 0
- "blablabla".byterindex("", 1).should == 1
- "blablabla".byterindex("", 2).should == 2
- "blablabla".byterindex("", 7).should == 7
- "blablabla".byterindex("", 8).should == 8
- "blablabla".byterindex("", 9).should == 9
- "blablabla".byterindex("", 10).should == 9
- end
-
- it "starts the search at offset + self.length if offset is negative" do
- str = "blablabla"
-
- ["bl", "bla", "blab", "la", "lab", "ab", ""].each do |needle|
- (-str.length .. -1).each do |offset|
- str.byterindex(needle, offset).should ==
- str.byterindex(needle, offset + str.length)
- end
- end
- end
-
- it "returns nil if the substring isn't found" do
- "blablabla".byterindex("B").should == nil
- "blablabla".byterindex("z").should == nil
- "blablabla".byterindex("BLA").should == nil
- "blablabla".byterindex("blablablabla").should == nil
-
- "hello".byterindex("lo", 0).should == nil
- "hello".byterindex("lo", 1).should == nil
- "hello".byterindex("lo", 2).should == nil
-
- "hello".byterindex("llo", 0).should == nil
- "hello".byterindex("llo", 1).should == nil
-
- "hello".byterindex("el", 0).should == nil
- "hello".byterindex("ello", 0).should == nil
-
- "hello".byterindex("", -6).should == nil
- "hello".byterindex("", -7).should == nil
-
- "hello".byterindex("h", -6).should == nil
- end
-
- it "tries to convert start_offset to an integer via to_int" do
- obj = mock('5')
- def obj.to_int() 5 end
- "str".byterindex("st", obj).should == 0
-
- obj = mock('5')
- def obj.respond_to?(arg, *) true end
- def obj.method_missing(*args) 5 end
- "str".byterindex("st", obj).should == 0
- end
-
- it "raises a TypeError when given offset is nil" do
- -> { "str".byterindex("st", nil) }.should raise_error(TypeError)
- end
-
- it "handles a substring in a superset encoding" do
- 'abc'.force_encoding(Encoding::US_ASCII).byterindex('é').should == nil
- end
-
- it "handles a substring in a subset encoding" do
- 'été'.byterindex('t'.force_encoding(Encoding::US_ASCII)).should == 2
- end
- end
-end
-
-describe "String#byterindex with Regexp" do
- ruby_version_is "3.2" do
- it "behaves the same as String#byterindex(string) for escaped string regexps" do
- ["blablabla", "hello cruel world...!"].each do |str|
- ["", "b", "bla", "lab", "o c", "d."].each do |needle|
- regexp = Regexp.new(Regexp.escape(needle))
- str.byterindex(regexp).should == str.byterindex(needle)
-
- 0.upto(str.size + 1) do |start|
- str.byterindex(regexp, start).should == str.byterindex(needle, start)
- end
-
- (-str.size - 1).upto(-1) do |start|
- str.byterindex(regexp, start).should == str.byterindex(needle, start)
- end
- end
- end
- end
-
- it "returns the index of the first match from the end of string of regexp" do
- "blablabla".byterindex(/bla/).should == 6
- "blablabla".byterindex(/BLA/i).should == 6
-
- "blablabla".byterindex(/.{0}/).should == 9
- "blablabla".byterindex(/.{1}/).should == 8
- "blablabla".byterindex(/.{2}/).should == 7
- "blablabla".byterindex(/.{6}/).should == 3
- "blablabla".byterindex(/.{9}/).should == 0
-
- "blablabla".byterindex(/.*/).should == 9
- "blablabla".byterindex(/.+/).should == 8
-
- "blablabla".byterindex(/bla|a/).should == 8
-
- not_supported_on :opal do
- "blablabla".byterindex(/\A/).should == 0
- "blablabla".byterindex(/\Z/).should == 9
- "blablabla".byterindex(/\z/).should == 9
- "blablabla\n".byterindex(/\Z/).should == 10
- "blablabla\n".byterindex(/\z/).should == 10
- end
-
- "blablabla".byterindex(/^/).should == 0
- not_supported_on :opal do
- "\nblablabla".byterindex(/^/).should == 1
- "b\nlablabla".byterindex(/^/).should == 2
- end
- "blablabla".byterindex(/$/).should == 9
-
- "blablabla".byterindex(/.l./).should == 6
- end
-
- it "starts the search at the given offset" do
- "blablabla".byterindex(/.{0}/, 5).should == 5
- "blablabla".byterindex(/.{1}/, 5).should == 5
- "blablabla".byterindex(/.{2}/, 5).should == 5
- "blablabla".byterindex(/.{3}/, 5).should == 5
- "blablabla".byterindex(/.{4}/, 5).should == 5
-
- "blablabla".byterindex(/.{0}/, 3).should == 3
- "blablabla".byterindex(/.{1}/, 3).should == 3
- "blablabla".byterindex(/.{2}/, 3).should == 3
- "blablabla".byterindex(/.{5}/, 3).should == 3
- "blablabla".byterindex(/.{6}/, 3).should == 3
-
- "blablabla".byterindex(/.l./, 0).should == 0
- "blablabla".byterindex(/.l./, 1).should == 0
- "blablabla".byterindex(/.l./, 2).should == 0
- "blablabla".byterindex(/.l./, 3).should == 3
-
- "blablablax".byterindex(/.x/, 10).should == 8
- "blablablax".byterindex(/.x/, 9).should == 8
- "blablablax".byterindex(/.x/, 8).should == 8
-
- "blablablax".byterindex(/..x/, 10).should == 7
- "blablablax".byterindex(/..x/, 9).should == 7
- "blablablax".byterindex(/..x/, 8).should == 7
- "blablablax".byterindex(/..x/, 7).should == 7
-
- not_supported_on :opal do
- "blablabla\n".byterindex(/\Z/, 9).should == 9
- end
- end
-
- it "starts the search at offset + self.length if offset is negative" do
- str = "blablabla"
-
- ["bl", "bla", "blab", "la", "lab", "ab", ""].each do |needle|
- (-str.length .. -1).each do |offset|
- str.byterindex(needle, offset).should ==
- str.byterindex(needle, offset + str.length)
- end
- end
- end
-
- it "returns nil if the substring isn't found" do
- "blablabla".byterindex(/BLA/).should == nil
- "blablabla".byterindex(/.{10}/).should == nil
- "blablablax".byterindex(/.x/, 7).should == nil
- "blablablax".byterindex(/..x/, 6).should == nil
-
- not_supported_on :opal do
- "blablabla".byterindex(/\Z/, 5).should == nil
- "blablabla".byterindex(/\z/, 5).should == nil
- "blablabla\n".byterindex(/\z/, 9).should == nil
- end
- end
-
- not_supported_on :opal do
- it "supports \\G which matches at the given start offset" do
- "helloYOU.".byterindex(/YOU\G/, 8).should == 5
- "helloYOU.".byterindex(/YOU\G/).should == nil
-
- idx = "helloYOUall!".index("YOU")
- re = /YOU.+\G.+/
- # The # marks where \G will match.
- [
- ["helloYOU#all.", nil],
- ["helloYOUa#ll.", idx],
- ["helloYOUal#l.", idx],
- ["helloYOUall#.", idx],
- ["helloYOUall.#", nil]
- ].each do |i|
- start = i[0].index("#")
- str = i[0].delete("#")
-
- str.byterindex(re, start).should == i[1]
- end
- end
- end
-
- it "tries to convert start_offset to an integer" do
- obj = mock('5')
- def obj.to_int() 5 end
- "str".byterindex(/../, obj).should == 1
-
- obj = mock('5')
- def obj.respond_to?(arg, *) true end
- def obj.method_missing(*args); 5; end
- "str".byterindex(/../, obj).should == 1
- end
-
- it "raises a TypeError when given offset is nil" do
- -> { "str".byterindex(/../, nil) }.should raise_error(TypeError)
- end
-
- it "returns the reverse byte index of a multibyte character" do
- "ã‚りãŒã‚ŠãŒã¨ã†".byterindex("ãŒ").should == 12
- "ã‚りãŒã‚ŠãŒã¨ã†".byterindex(/ãŒ/).should == 12
- end
-
- it "returns the character index before the finish" do
- "ã‚りãŒã‚ŠãŒã¨ã†".byterindex("ãŒ", 9).should == 6
- "ã‚りãŒã‚ŠãŒã¨ã†".byterindex(/ãŒ/, 9).should == 6
- end
- end
-end
diff --git a/spec/ruby/core/string/bytesplice_spec.rb b/spec/ruby/core/string/bytesplice_spec.rb
deleted file mode 100644
index f13024a79b..0000000000
--- a/spec/ruby/core/string/bytesplice_spec.rb
+++ /dev/null
@@ -1,133 +0,0 @@
-# -*- encoding: utf-8 -*-
-require_relative '../../spec_helper'
-
-describe "String#bytesplice" do
- ruby_version_is "3.2" do
- it "raises IndexError when index is less than -bytesize" do
- -> { "hello".bytesplice(-6, 0, "xxx") }.should raise_error(IndexError, "index -6 out of string")
- end
-
- it "raises IndexError when index is greater than bytesize" do
- -> { "hello".bytesplice(6, 0, "xxx") }.should raise_error(IndexError, "index 6 out of string")
- end
-
- it "raises IndexError for negative length" do
- -> { "abc".bytesplice(0, -2, "") }.should raise_error(IndexError, "negative length -2")
- end
-
- it "replaces with integer indices" do
- "hello".bytesplice(-5, 0, "xxx").should == "xxxhello"
- "hello".bytesplice(0, 0, "xxx").should == "xxxhello"
- "hello".bytesplice(0, 1, "xxx").should == "xxxello"
- "hello".bytesplice(0, 5, "xxx").should == "xxx"
- "hello".bytesplice(0, 6, "xxx").should == "xxx"
- end
-
- it "raises RangeError when range left boundary is less than -bytesize" do
- -> { "hello".bytesplice(-6...-6, "xxx") }.should raise_error(RangeError, "-6...-6 out of range")
- end
-
- it "replaces with ranges" do
- "hello".bytesplice(-5...-5, "xxx").should == "xxxhello"
- "hello".bytesplice(0...0, "xxx").should == "xxxhello"
- "hello".bytesplice(0..0, "xxx").should == "xxxello"
- "hello".bytesplice(0...1, "xxx").should == "xxxello"
- "hello".bytesplice(0..1, "xxx").should == "xxxllo"
- "hello".bytesplice(0..-1, "xxx").should == "xxx"
- "hello".bytesplice(0...5, "xxx").should == "xxx"
- "hello".bytesplice(0...6, "xxx").should == "xxx"
- end
-
- it "raises TypeError when integer index is provided without length argument" do
- -> { "hello".bytesplice(0, "xxx") }.should raise_error(TypeError, "wrong argument type Integer (expected Range)")
- end
-
- it "replaces on an empty string" do
- "".bytesplice(0, 0, "").should == ""
- "".bytesplice(0, 0, "xxx").should == "xxx"
- end
-
- it "mutates self" do
- s = "hello"
- s.bytesplice(2, 1, "xxx").should.equal?(s)
- end
-
- it "raises when string is frozen" do
- s = "hello".freeze
- -> { s.bytesplice(2, 1, "xxx") }.should raise_error(FrozenError, "can't modify frozen String: \"hello\"")
- end
- end
-end
-
-describe "String#bytesplice with multibyte characters" do
- ruby_version_is "3.2" do
- it "raises IndexError when index is out of byte size boundary" do
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(-16, 0, "xxx") }.should raise_error(IndexError, "index -16 out of string")
- end
-
- it "raises IndexError when index is not on a codepoint boundary" do
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(1, 0, "xxx") }.should raise_error(IndexError, "offset 1 does not land on character boundary")
- end
-
- it "raises IndexError when length is not matching the codepoint boundary" do
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(0, 1, "xxx") }.should raise_error(IndexError, "offset 1 does not land on character boundary")
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(0, 2, "xxx") }.should raise_error(IndexError, "offset 2 does not land on character boundary")
- end
-
- it "replaces with integer indices" do
- "ã“ã‚“ã«ã¡ã¯".bytesplice(-15, 0, "xxx").should == "xxxã“ã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0, 0, "xxx").should == "xxxã“ã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0, 3, "xxx").should == "xxxã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(3, 3, "ã¯ã¯").should == "ã“ã¯ã¯ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(15, 0, "xxx").should == "ã“ã‚“ã«ã¡ã¯xxx"
- end
-
- it "replaces with range" do
- "ã“ã‚“ã«ã¡ã¯".bytesplice(-15...-16, "xxx").should == "xxxã“ã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0...0, "xxx").should == "xxxã“ã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0..2, "xxx").should == "xxxã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0...3, "xxx").should == "xxxã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0..5, "xxx").should == "xxxã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0..-1, "xxx").should == "xxx"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0...15, "xxx").should == "xxx"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0...18, "xxx").should == "xxx"
- end
-
- it "treats negative length for range as 0" do
- "ã“ã‚“ã«ã¡ã¯".bytesplice(0...-100, "xxx").should == "xxxã“ã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(3...-100, "xxx").should == "ã“xxxã‚“ã«ã¡ã¯"
- "ã“ã‚“ã«ã¡ã¯".bytesplice(-15...-100, "xxx").should == "xxxã“ã‚“ã«ã¡ã¯"
- end
-
- it "raises when ranges not match codepoint boundaries" do
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(0..0, "x") }.should raise_error(IndexError, "offset 1 does not land on character boundary")
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(0..1, "x") }.should raise_error(IndexError, "offset 2 does not land on character boundary")
- # Begin is incorrect
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(-4..-1, "x") }.should raise_error(IndexError, "offset 11 does not land on character boundary")
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(-5..-1, "x") }.should raise_error(IndexError, "offset 10 does not land on character boundary")
- # End is incorrect
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(-3..-2, "x") }.should raise_error(IndexError, "offset 14 does not land on character boundary")
- -> { "ã“ã‚“ã«ã¡ã¯".bytesplice(-3..-3, "x") }.should raise_error(IndexError, "offset 13 does not land on character boundary")
- end
-
- it "deals with a different encoded argument" do
- s = "ã“ã‚“ã«ã¡ã¯"
- s.encoding.should == Encoding::UTF_8
- sub = "xxxxxx"
- sub.force_encoding(Encoding::US_ASCII)
-
- result = s.bytesplice(0, 3, sub)
- result.should == "xxxxxxã‚“ã«ã¡ã¯"
- result.encoding.should == Encoding::UTF_8
-
- s = "xxxxxx"
- s.force_encoding(Encoding::US_ASCII)
- sub = "ã“ã‚“ã«ã¡ã¯"
- sub.encoding.should == Encoding::UTF_8
-
- result = s.bytesplice(0, 3, sub)
- result.should == "ã“ã‚“ã«ã¡ã¯xxx"
- result.encoding.should == Encoding::UTF_8
- end
- end
-end
diff --git a/spec/ruby/core/string/capitalize_spec.rb b/spec/ruby/core/string/capitalize_spec.rb
index b79e9cfdbd..3f85cf5ae4 100644
--- a/spec/ruby/core/string/capitalize_spec.rb
+++ b/spec/ruby/core/string/capitalize_spec.rb
@@ -78,9 +78,18 @@ describe "String#capitalize" do
-> { "abc".capitalize(:invalid_option) }.should raise_error(ArgumentError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("hello").capitalize.should be_an_instance_of(String)
- StringSpecs::MyString.new("Hello").capitalize.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").capitalize.should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("Hello").capitalize.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").capitalize.should be_an_instance_of(String)
+ StringSpecs::MyString.new("Hello").capitalize.should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/casecmp_spec.rb b/spec/ruby/core/string/casecmp_spec.rb
index 81ebea557c..986fbc8718 100644
--- a/spec/ruby/core/string/casecmp_spec.rb
+++ b/spec/ruby/core/string/casecmp_spec.rb
@@ -117,11 +117,6 @@ describe "String#casecmp independent of case" do
"B".casecmp(a).should == 1
end
end
-
- it "returns 0 for empty strings in different encodings" do
- ''.b.casecmp('').should == 0
- ''.b.casecmp(''.encode("UTF-32LE")).should == 0
- end
end
describe 'String#casecmp? independent of case' do
@@ -196,9 +191,4 @@ describe 'String#casecmp? independent of case' do
it "returns nil if other can't be converted to a string" do
"abc".casecmp?(mock('abc')).should be_nil
end
-
- it "returns true for empty strings in different encodings" do
- ''.b.should.casecmp?('')
- ''.b.should.casecmp?(''.encode("UTF-32LE"))
- end
end
diff --git a/spec/ruby/core/string/center_spec.rb b/spec/ruby/core/string/center_spec.rb
index a59dd2a91b..76da6e1e09 100644
--- a/spec/ruby/core/string/center_spec.rb
+++ b/spec/ruby/core/string/center_spec.rb
@@ -81,13 +81,26 @@ describe "String#center with length, padding" do
-> { "hello".center(0, "") }.should raise_error(ArgumentError)
end
- it "returns String instances when called on subclasses" do
- StringSpecs::MyString.new("").center(10).should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").center(10).should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on subclasses" do
+ StringSpecs::MyString.new("").center(10).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").center(10).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString)
+
+ "".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ end
+ end
- "".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
- "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on subclasses" do
+ StringSpecs::MyString.new("").center(10).should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").center(10).should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+
+ "".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ end
end
describe "with width" do
diff --git a/spec/ruby/core/string/chars_spec.rb b/spec/ruby/core/string/chars_spec.rb
index ee85430574..715e65dc90 100644
--- a/spec/ruby/core/string/chars_spec.rb
+++ b/spec/ruby/core/string/chars_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/chars'
describe "String#chars" do
diff --git a/spec/ruby/core/string/chomp_spec.rb b/spec/ruby/core/string/chomp_spec.rb
index ec0490220b..d0508d938f 100644
--- a/spec/ruby/core/string/chomp_spec.rb
+++ b/spec/ruby/core/string/chomp_spec.rb
@@ -44,9 +44,18 @@ describe "String#chomp" do
"abc\n\n".encode("US-ASCII").chomp.encoding.should == Encoding::US_ASCII
end
- it "returns String instances when called on a subclass" do
- str = StringSpecs::MyString.new("hello\n").chomp
- str.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ str = StringSpecs::MyString.new("hello\n").chomp
+ str.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ str = StringSpecs::MyString.new("hello\n").chomp
+ str.should be_an_instance_of(String)
+ end
end
it "removes trailing characters that match $/ when it has been assigned a value" do
diff --git a/spec/ruby/core/string/chop_spec.rb b/spec/ruby/core/string/chop_spec.rb
index 75f25b39cd..f598d34bc8 100644
--- a/spec/ruby/core/string/chop_spec.rb
+++ b/spec/ruby/core/string/chop_spec.rb
@@ -49,8 +49,16 @@ describe "String#chop" do
s.chop.should_not equal(s)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/concat_spec.rb b/spec/ruby/core/string/concat_spec.rb
index 6f487eaa3a..5f6daadad7 100644
--- a/spec/ruby/core/string/concat_spec.rb
+++ b/spec/ruby/core/string/concat_spec.rb
@@ -5,7 +5,6 @@ require_relative 'shared/concat'
describe "String#concat" do
it_behaves_like :string_concat, :concat
it_behaves_like :string_concat_encoding, :concat
- it_behaves_like :string_concat_type_coercion, :concat
it "takes multiple arguments" do
str = "hello "
diff --git a/spec/ruby/core/string/dedup_spec.rb b/spec/ruby/core/string/dedup_spec.rb
index 57d2be2cfd..919d440c51 100644
--- a/spec/ruby/core/string/dedup_spec.rb
+++ b/spec/ruby/core/string/dedup_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/dedup'
describe 'String#dedup' do
- ruby_version_is '3.2' do
+ ruby_version_is '3.2'do
it_behaves_like :string_dedup, :dedup
end
end
diff --git a/spec/ruby/core/string/delete_prefix_spec.rb b/spec/ruby/core/string/delete_prefix_spec.rb
index 4214fdecce..238de85f05 100644
--- a/spec/ruby/core/string/delete_prefix_spec.rb
+++ b/spec/ruby/core/string/delete_prefix_spec.rb
@@ -38,9 +38,18 @@ describe "String#delete_prefix" do
'hello'.delete_prefix(o).should == 'o'
end
- it "returns a String instance when called on a subclass instance" do
- s = StringSpecs::MyString.new('hello')
- s.delete_prefix('hell').should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance when called on a subclass instance" do
+ s = StringSpecs::MyString.new('hello')
+ s.delete_prefix('hell').should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a String instance when called on a subclass instance" do
+ s = StringSpecs::MyString.new('hello')
+ s.delete_prefix('hell').should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/delete_spec.rb b/spec/ruby/core/string/delete_spec.rb
index 3b9aa4fb75..87831a9d19 100644
--- a/spec/ruby/core/string/delete_spec.rb
+++ b/spec/ruby/core/string/delete_spec.rb
@@ -84,8 +84,16 @@ describe "String#delete" do
-> { "hello world".delete(mock('x')) }.should raise_error(TypeError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("oh no!!!").delete("!").should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("oh no!!!").delete("!").should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("oh no!!!").delete("!").should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/delete_suffix_spec.rb b/spec/ruby/core/string/delete_suffix_spec.rb
index 9381f4cee7..6883d6938c 100644
--- a/spec/ruby/core/string/delete_suffix_spec.rb
+++ b/spec/ruby/core/string/delete_suffix_spec.rb
@@ -38,9 +38,18 @@ describe "String#delete_suffix" do
'hello'.delete_suffix(o).should == 'h'
end
- it "returns a String instance when called on a subclass instance" do
- s = StringSpecs::MyString.new('hello')
- s.delete_suffix('ello').should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance when called on a subclass instance" do
+ s = StringSpecs::MyString.new('hello')
+ s.delete_suffix('ello').should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a String instance when called on a subclass instance" do
+ s = StringSpecs::MyString.new('hello')
+ s.delete_suffix('ello').should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/downcase_spec.rb b/spec/ruby/core/string/downcase_spec.rb
index 7ee9d6df1d..153b4ce191 100644
--- a/spec/ruby/core/string/downcase_spec.rb
+++ b/spec/ruby/core/string/downcase_spec.rb
@@ -76,8 +76,16 @@ describe "String#downcase" do
-> { "ABC".downcase(:invalid_option) }.should raise_error(ArgumentError)
end
- it "returns a String instance for subclasses" do
- StringSpecs::MyString.new("FOObar").downcase.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance for subclasses" do
+ StringSpecs::MyString.new("FOObar").downcase.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a String instance for subclasses" do
+ StringSpecs::MyString.new("FOObar").downcase.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/string/dump_spec.rb b/spec/ruby/core/string/dump_spec.rb
index cab8beff5a..81de0cfae4 100644
--- a/spec/ruby/core/string/dump_spec.rb
+++ b/spec/ruby/core/string/dump_spec.rb
@@ -7,8 +7,16 @@ describe "String#dump" do
"foo".freeze.dump.should_not.frozen?
end
- it "returns a String instance" do
- StringSpecs::MyString.new.dump.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance" do
+ StringSpecs::MyString.new.dump.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a String instance" do
+ StringSpecs::MyString.new.dump.should be_an_instance_of(String)
+ end
end
it "wraps string with \"" do
diff --git a/spec/ruby/core/string/each_char_spec.rb b/spec/ruby/core/string/each_char_spec.rb
index 36219f79db..aff98c0a5c 100644
--- a/spec/ruby/core/string/each_char_spec.rb
+++ b/spec/ruby/core/string/each_char_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/chars'
require_relative 'shared/each_char_without_block'
diff --git a/spec/ruby/core/string/each_grapheme_cluster_spec.rb b/spec/ruby/core/string/each_grapheme_cluster_spec.rb
index e1fa4ae67b..b45d89ecb0 100644
--- a/spec/ruby/core/string/each_grapheme_cluster_spec.rb
+++ b/spec/ruby/core/string/each_grapheme_cluster_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/chars'
require_relative 'shared/grapheme_clusters'
require_relative 'shared/each_char_without_block'
@@ -8,9 +7,11 @@ describe "String#each_grapheme_cluster" do
it_behaves_like :string_grapheme_clusters, :each_grapheme_cluster
it_behaves_like :string_each_char_without_block, :each_grapheme_cluster
- it "yields String instances for subclasses" do
- a = []
- StringSpecs::MyString.new("abc").each_grapheme_cluster { |s| a << s.class }
- a.should == [String, String, String]
+ ruby_version_is '3.0' do
+ it "yields String instances for subclasses" do
+ a = []
+ StringSpecs::MyString.new("abc").each_grapheme_cluster { |s| a << s.class }
+ a.should == [String, String, String]
+ end
end
end
diff --git a/spec/ruby/core/string/encode_spec.rb b/spec/ruby/core/string/encode_spec.rb
index 35ed27bb40..5604ab7210 100644
--- a/spec/ruby/core/string/encode_spec.rb
+++ b/spec/ruby/core/string/encode_spec.rb
@@ -79,10 +79,6 @@ describe "String#encode" do
encoded.encode("UTF-8").should == "ã¡foofoo"
end
- it "replace multiple invalid bytes at the end with a single replacement character" do
- "\xE3\x81\x93\xE3\x81".encode("UTF-8", invalid: :replace).should == "\u3053\ufffd"
- end
-
it "replaces invalid encoding in source using a specified replacement even when a fallback is given" do
encoded = "ã¡\xE3\x81\xFF".encode("UTF-16LE", invalid: :replace, replace: "foo", fallback: -> c { "bar" })
encoded.should == "\u3061foofoo".encode("UTF-16LE")
diff --git a/spec/ruby/core/string/grapheme_clusters_spec.rb b/spec/ruby/core/string/grapheme_clusters_spec.rb
index 380a245083..3046265a12 100644
--- a/spec/ruby/core/string/grapheme_clusters_spec.rb
+++ b/spec/ruby/core/string/grapheme_clusters_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/chars'
require_relative 'shared/grapheme_clusters'
diff --git a/spec/ruby/core/string/gsub_spec.rb b/spec/ruby/core/string/gsub_spec.rb
index 9e3b50322c..c87a566591 100644
--- a/spec/ruby/core/string/gsub_spec.rb
+++ b/spec/ruby/core/string/gsub_spec.rb
@@ -192,11 +192,22 @@ describe "String#gsub with pattern and replacement" do
-> { "hello".gsub(/[aeiou]/, nil) }.should raise_error(TypeError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("").gsub(//, "").should be_an_instance_of(String)
- StringSpecs::MyString.new("").gsub(/foo/, "").should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").gsub(/foo/, "").should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").gsub("foo", "").should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("").gsub(//, "").should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("").gsub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").gsub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").gsub("foo", "").should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("").gsub(//, "").should be_an_instance_of(String)
+ StringSpecs::MyString.new("").gsub(/foo/, "").should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").gsub(/foo/, "").should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").gsub("foo", "").should be_an_instance_of(String)
+ end
end
it "sets $~ to MatchData of last match and nil when there's none" do
diff --git a/spec/ruby/core/string/index_spec.rb b/spec/ruby/core/string/index_spec.rb
index b500cf6ca7..2eeee9be87 100644
--- a/spec/ruby/core/string/index_spec.rb
+++ b/spec/ruby/core/string/index_spec.rb
@@ -167,13 +167,6 @@ describe "String#index with String" do
it "handles a substring in a subset encoding" do
'été'.index('t'.force_encoding(Encoding::US_ASCII)).should == 1
end
-
- it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
- str = 'abc'.force_encoding("ISO-2022-JP")
- pattern = 'b'.force_encoding("EUC-JP")
-
- -> { str.index(pattern) }.should raise_error(Encoding::CompatibilityError, "incompatible character encodings: ISO-2022-JP and EUC-JP")
- end
end
describe "String#index with Regexp" do
@@ -319,17 +312,6 @@ describe "String#index with Regexp" do
"ã‚れã‚ã‚れ".index(/ã‚/, 3).should == 3
end
- ruby_bug "#19763", ""..."3.3.0" do
- it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
- re = Regexp.new "れ".encode(Encoding::EUC_JP)
- -> do
- "ã‚れ".index re
- end.should raise_error(Encoding::CompatibilityError, "incompatible encoding regexp match (EUC-JP regexp with UTF-8 string)")
- end
- end
-
- # The exception message was incorrectly "incompatible character encodings: UTF-8 and EUC-JP" before 3.3.0
- # Still test that the right exception class is used before that.
it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
re = Regexp.new "れ".encode(Encoding::EUC_JP)
-> do
diff --git a/spec/ruby/core/string/ljust_spec.rb b/spec/ruby/core/string/ljust_spec.rb
index 9208ec5897..9a25d3abd4 100644
--- a/spec/ruby/core/string/ljust_spec.rb
+++ b/spec/ruby/core/string/ljust_spec.rb
@@ -64,13 +64,26 @@ describe "String#ljust with length, padding" do
-> { "hello".ljust(10, '') }.should raise_error(ArgumentError)
end
- it "returns String instances when called on subclasses" do
- StringSpecs::MyString.new("").ljust(10).should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").ljust(10).should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on subclasses" do
+ StringSpecs::MyString.new("").ljust(10).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").ljust(10).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString)
+
+ "".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ "foo".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ end
+ end
- "".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
- "foo".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on subclasses" do
+ StringSpecs::MyString.new("").ljust(10).should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").ljust(10).should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+
+ "".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ "foo".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ end
end
describe "with width" do
diff --git a/spec/ruby/core/string/lstrip_spec.rb b/spec/ruby/core/string/lstrip_spec.rb
index 85685deb0a..75434613f1 100644
--- a/spec/ruby/core/string/lstrip_spec.rb
+++ b/spec/ruby/core/string/lstrip_spec.rb
@@ -20,9 +20,11 @@ describe "String#lstrip" do
" ã“ã«ã¡ã‚ "[1...-1].lstrip.should == "ã“ã«ã¡ã‚"
end
- it "strips leading \\0" do
- "\x00hello".lstrip.should == "hello"
- "\000 \000hello\000 \000".lstrip.should == "hello\000 \000"
+ ruby_version_is '3.0' do
+ it "strips leading \\0" do
+ "\x00hello".lstrip.should == "hello"
+ "\000 \000hello\000 \000".lstrip.should == "hello\000 \000"
+ end
end
end
@@ -45,10 +47,12 @@ describe "String#lstrip!" do
" ".lstrip.should == ""
end
- it "removes leading NULL bytes and whitespace" do
- a = "\000 \000hello\000 \000"
- a.lstrip!
- a.should == "hello\000 \000"
+ ruby_version_is '3.0' do
+ it "removes leading NULL bytes and whitespace" do
+ a = "\000 \000hello\000 \000"
+ a.lstrip!
+ a.should == "hello\000 \000"
+ end
end
it "raises a FrozenError on a frozen instance that is modified" do
diff --git a/spec/ruby/core/string/plus_spec.rb b/spec/ruby/core/string/plus_spec.rb
index 9da17451c6..5ff198f07e 100644
--- a/spec/ruby/core/string/plus_spec.rb
+++ b/spec/ruby/core/string/plus_spec.rb
@@ -3,9 +3,6 @@ require_relative 'fixtures/classes'
require_relative 'shared/concat'
describe "String#+" do
- it_behaves_like :string_concat_encoding, :+
- it_behaves_like :string_concat_type_coercion, :+
-
it "returns a new string containing the given string concatenated to self" do
("" + "").should == ""
("" + "Hello").should == "Hello"
@@ -34,4 +31,6 @@ describe "String#+" do
("hello" + StringSpecs::MyString.new("foo")).should be_an_instance_of(String)
("hello" + StringSpecs::MyString.new("")).should be_an_instance_of(String)
end
+
+ it_behaves_like :string_concat_encoding, :+
end
diff --git a/spec/ruby/core/string/reverse_spec.rb b/spec/ruby/core/string/reverse_spec.rb
index e67122c05c..73526256ef 100644
--- a/spec/ruby/core/string/reverse_spec.rb
+++ b/spec/ruby/core/string/reverse_spec.rb
@@ -10,10 +10,20 @@ describe "String#reverse" do
"".reverse.should == ""
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("stressed").reverse.should be_an_instance_of(String)
- StringSpecs::MyString.new("m").reverse.should be_an_instance_of(String)
- StringSpecs::MyString.new("").reverse.should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("stressed").reverse.should be_an_instance_of(String)
+ StringSpecs::MyString.new("m").reverse.should be_an_instance_of(String)
+ StringSpecs::MyString.new("").reverse.should be_an_instance_of(String)
+ end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("stressed").reverse.should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("m").reverse.should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("").reverse.should be_an_instance_of(StringSpecs::MyString)
+ end
end
it "reverses a string with multi byte characters" do
diff --git a/spec/ruby/core/string/rindex_spec.rb b/spec/ruby/core/string/rindex_spec.rb
index 45ff13a006..cd2aabba34 100644
--- a/spec/ruby/core/string/rindex_spec.rb
+++ b/spec/ruby/core/string/rindex_spec.rb
@@ -204,13 +204,6 @@ describe "String#rindex with String" do
it "handles a substring in a subset encoding" do
'été'.rindex('t'.force_encoding(Encoding::US_ASCII)).should == 1
end
-
- it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
- str = 'abc'.force_encoding("ISO-2022-JP")
- pattern = 'b'.force_encoding("EUC-JP")
-
- -> { str.rindex(pattern) }.should raise_error(Encoding::CompatibilityError, "incompatible character encodings: ISO-2022-JP and EUC-JP")
- end
end
describe "String#rindex with Regexp" do
@@ -272,6 +265,15 @@ describe "String#rindex with Regexp" do
$~.should == nil
end
+ it "always clear $~" do
+ "a".rindex(/a/)
+ $~.should_not == nil
+
+ string = "blablabla"
+ string.rindex(/bla/, -(string.length + 1))
+ $~.should == nil
+ end
+
it "starts the search at the given offset" do
"blablabla".rindex(/.{0}/, 5).should == 5
"blablabla".rindex(/.{1}/, 5).should == 5
@@ -380,6 +382,6 @@ describe "String#rindex with Regexp" do
re = Regexp.new "れ".encode(Encoding::EUC_JP)
-> do
"ã‚れ".rindex re
- end.should raise_error(Encoding::CompatibilityError, "incompatible encoding regexp match (EUC-JP regexp with UTF-8 string)")
+ end.should raise_error(Encoding::CompatibilityError)
end
end
diff --git a/spec/ruby/core/string/rjust_spec.rb b/spec/ruby/core/string/rjust_spec.rb
index fcbaf3b938..d067b7bdb3 100644
--- a/spec/ruby/core/string/rjust_spec.rb
+++ b/spec/ruby/core/string/rjust_spec.rb
@@ -64,13 +64,26 @@ describe "String#rjust with length, padding" do
-> { "hello".rjust(10, '') }.should raise_error(ArgumentError)
end
- it "returns String instances when called on subclasses" do
- StringSpecs::MyString.new("").rjust(10).should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").rjust(10).should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on subclasses" do
+ StringSpecs::MyString.new("").rjust(10).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").rjust(10).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString)
+
+ "".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ "foo".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ end
+ end
- "".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
- "foo".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on subclasses" do
+ StringSpecs::MyString.new("").rjust(10).should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").rjust(10).should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+
+ "".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ "foo".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
+ end
end
describe "with width" do
diff --git a/spec/ruby/core/string/rstrip_spec.rb b/spec/ruby/core/string/rstrip_spec.rb
index e4cf93315e..e96ce4120f 100644
--- a/spec/ruby/core/string/rstrip_spec.rb
+++ b/spec/ruby/core/string/rstrip_spec.rb
@@ -51,10 +51,12 @@ describe "String#rstrip!" do
" ".rstrip.should == ""
end
- it "removes trailing NULL bytes and whitespace" do
- a = "\000 goodbye \000"
- a.rstrip!
- a.should == "\000 goodbye"
+ ruby_version_is '3.0' do
+ it "removes trailing NULL bytes and whitespace" do
+ a = "\000 goodbye \000"
+ a.rstrip!
+ a.should == "\000 goodbye"
+ end
end
it "raises a FrozenError on a frozen instance that is modified" do
diff --git a/spec/ruby/core/string/scan_spec.rb b/spec/ruby/core/string/scan_spec.rb
index 70c3b7fb7b..a2d1815132 100644
--- a/spec/ruby/core/string/scan_spec.rb
+++ b/spec/ruby/core/string/scan_spec.rb
@@ -165,9 +165,11 @@ describe "String#scan with pattern and block" do
end
end
- it "yields String instances for subclasses" do
- a = []
- StringSpecs::MyString.new("abc").scan(/./) { |s| a << s.class }
- a.should == [String, String, String]
+ ruby_version_is '3.0' do
+ it "yields String instances for subclasses" do
+ a = []
+ StringSpecs::MyString.new("abc").scan(/./) { |s| a << s.class }
+ a.should == [String, String, String]
+ end
end
end
diff --git a/spec/ruby/core/string/scrub_spec.rb b/spec/ruby/core/string/scrub_spec.rb
index bcee4db463..a51fbd020a 100644
--- a/spec/ruby/core/string/scrub_spec.rb
+++ b/spec/ruby/core/string/scrub_spec.rb
@@ -36,10 +36,18 @@ describe "String#scrub with a default replacement" do
"abc\u3042#{x81}".scrub.encoding.should == Encoding::UTF_8
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("foo").scrub.should be_an_instance_of(String)
- input = [0x81].pack('C').force_encoding('utf-8')
- StringSpecs::MyString.new(input).scrub.should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("foo").scrub.should be_an_instance_of(String)
+ input = [0x81].pack('C').force_encoding('utf-8')
+ StringSpecs::MyString.new(input).scrub.should be_an_instance_of(String)
+ end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("foo").scrub.should be_an_instance_of(StringSpecs::MyString)
+ end
end
end
@@ -89,10 +97,12 @@ describe "String#scrub with a custom replacement" do
block.should raise_error(TypeError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("foo").scrub("*").should be_an_instance_of(String)
- input = [0x81].pack('C').force_encoding('utf-8')
- StringSpecs::MyString.new(input).scrub("*").should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("foo").scrub("*").should be_an_instance_of(String)
+ input = [0x81].pack('C').force_encoding('utf-8')
+ StringSpecs::MyString.new(input).scrub("*").should be_an_instance_of(String)
+ end
end
end
@@ -119,10 +129,12 @@ describe "String#scrub with a block" do
replaced.should == "€€"
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("foo").scrub { |b| "*" }.should be_an_instance_of(String)
- input = [0x81].pack('C').force_encoding('utf-8')
- StringSpecs::MyString.new(input).scrub { |b| "<#{b.unpack("H*")[0]}>" }.should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("foo").scrub { |b| "*" }.should be_an_instance_of(String)
+ input = [0x81].pack('C').force_encoding('utf-8')
+ StringSpecs::MyString.new(input).scrub { |b| "<#{b.unpack("H*")[0]}>" }.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/string/shared/byte_index_common.rb b/spec/ruby/core/string/shared/byte_index_common.rb
deleted file mode 100644
index 3de1453f4f..0000000000
--- a/spec/ruby/core/string/shared/byte_index_common.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# -*- encoding: utf-8 -*-
-require_relative '../../../spec_helper'
-
-describe :byte_index_common, shared: true do
- describe "raises on type errors" do
- it "raises a TypeError if passed nil" do
- -> { "abc".send(@method, nil) }.should raise_error(TypeError, "no implicit conversion of nil into String")
- end
-
- it "raises a TypeError if passed a boolean" do
- -> { "abc".send(@method, true) }.should raise_error(TypeError, "no implicit conversion of true into String")
- end
-
- it "raises a TypeError if passed a Symbol" do
- not_supported_on :opal do
- -> { "abc".send(@method, :a) }.should raise_error(TypeError, "no implicit conversion of Symbol into String")
- end
- end
-
- it "raises a TypeError if passed a Symbol" do
- obj = mock('x')
- obj.should_not_receive(:to_int)
- -> { "hello".send(@method, obj) }.should raise_error(TypeError, "no implicit conversion of MockObject into String")
- end
-
- it "raises a TypeError if passed an Integer" do
- -> { "abc".send(@method, 97) }.should raise_error(TypeError, "no implicit conversion of Integer into String")
- end
- end
-
- describe "with multibyte codepoints" do
- it "raises an IndexError when byte offset lands in the middle of a multibyte character" do
- -> { "ã‚".send(@method, "", 1) }.should raise_error(IndexError, "offset 1 does not land on character boundary")
- -> { "ã‚".send(@method, "", 2) }.should raise_error(IndexError, "offset 2 does not land on character boundary")
- -> { "ã‚".send(@method, "", -1) }.should raise_error(IndexError, "offset 2 does not land on character boundary")
- -> { "ã‚".send(@method, "", -2) }.should raise_error(IndexError, "offset 1 does not land on character boundary")
- end
-
- it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
- re = Regexp.new "れ".encode(Encoding::EUC_JP)
- -> do
- "ã‚れ".send(@method, re)
- end.should raise_error(Encoding::CompatibilityError, "incompatible encoding regexp match (EUC-JP regexp with UTF-8 string)")
- end
- end
-
- describe "with global variables" do
- it "doesn't set $~ for non regex search" do
- $~ = nil
-
- 'hello.'.send(@method, 'll')
- $~.should == nil
- end
-
- it "sets $~ to MatchData of match and nil when there's none" do
- 'hello.'.send(@method, /.e./)
- $~[0].should == 'hel'
-
- 'hello.'.send(@method, /not/)
- $~.should == nil
- end
- end
-end
diff --git a/spec/ruby/core/string/shared/concat.rb b/spec/ruby/core/string/shared/concat.rb
index ee5ef2a98f..54ac1035d3 100644
--- a/spec/ruby/core/string/shared/concat.rb
+++ b/spec/ruby/core/string/shared/concat.rb
@@ -5,6 +5,18 @@ describe :string_concat, shared: true do
str.should == "hello world"
end
+ it "converts the given argument to a String using to_str" do
+ obj = mock('world!')
+ obj.should_receive(:to_str).and_return("world!")
+ a = 'hello '.send(@method, obj)
+ a.should == 'hello world!'
+ end
+
+ it "raises a TypeError if the given argument can't be converted to a String" do
+ -> { 'hello '.send(@method, []) }.should raise_error(TypeError)
+ -> { 'hello '.send(@method, mock('x')) }.should raise_error(TypeError)
+ end
+
it "raises a FrozenError when self is frozen" do
a = "hello"
a.freeze
@@ -136,23 +148,3 @@ describe :string_concat_encoding, shared: true do
end
end
end
-
-describe :string_concat_type_coercion, shared: true do
- it "converts the given argument to a String using to_str" do
- obj = mock('world!')
- obj.should_receive(:to_str).and_return("world!")
- a = 'hello '.send(@method, obj)
- a.should == 'hello world!'
- end
-
- it "raises a TypeError if the given argument can't be converted to a String" do
- -> { 'hello '.send(@method, []) }.should raise_error(TypeError)
- -> { 'hello '.send(@method, mock('x')) }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to a String" do
- obj = mock('world!')
- obj.should_receive(:to_str).and_raise(NoMethodError)
- -> { 'hello '.send(@method, obj) }.should raise_error(NoMethodError)
- end
-end
diff --git a/spec/ruby/core/string/shared/dedup.rb b/spec/ruby/core/string/shared/dedup.rb
index 893fd1e360..6ffcb9b045 100644
--- a/spec/ruby/core/string/shared/dedup.rb
+++ b/spec/ruby/core/string/shared/dedup.rb
@@ -48,8 +48,10 @@ describe :string_dedup, shared: true do
dynamic.send(@method).should equal(dynamic)
end
- it "interns the provided string if it is frozen" do
- dynamic = "this string is unique and frozen #{rand}".freeze
- dynamic.send(@method).should equal(dynamic)
+ ruby_version_is "3.0" do
+ it "interns the provided string if it is frozen" do
+ dynamic = "this string is unique and frozen #{rand}".freeze
+ dynamic.send(@method).should equal(dynamic)
+ end
end
end
diff --git a/spec/ruby/core/string/shared/each_line.rb b/spec/ruby/core/string/shared/each_line.rb
index a14b4d7779..df78bd2186 100644
--- a/spec/ruby/core/string/shared/each_line.rb
+++ b/spec/ruby/core/string/shared/each_line.rb
@@ -85,10 +85,20 @@ describe :string_each_line, shared: true do
end
end
- it "yields String instances for subclasses" do
- a = []
- StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
- a.should == [String, String]
+ ruby_version_is ''...'3.0' do
+ it "yields subclass instances for subclasses" do
+ a = []
+ StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
+ a.should == [StringSpecs::MyString, StringSpecs::MyString]
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "yields String instances for subclasses" do
+ a = []
+ StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
+ a.should == [String, String]
+ end
end
it "returns self" do
diff --git a/spec/ruby/core/string/shared/partition.rb b/spec/ruby/core/string/shared/partition.rb
index 4cac149ce5..41b3c7e0c9 100644
--- a/spec/ruby/core/string/shared/partition.rb
+++ b/spec/ruby/core/string/shared/partition.rb
@@ -2,17 +2,35 @@ require_relative '../../../spec_helper'
require_relative '../fixtures/classes'
describe :string_partition, shared: true do
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("hello").send(@method, "l").each do |item|
- item.should be_an_instance_of(String)
- end
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").send(@method, "l").each do |item|
+ item.should be_an_instance_of(String)
+ end
+
+ StringSpecs::MyString.new("hello").send(@method, "x").each do |item|
+ item.should be_an_instance_of(String)
+ end
- StringSpecs::MyString.new("hello").send(@method, "x").each do |item|
- item.should be_an_instance_of(String)
+ StringSpecs::MyString.new("hello").send(@method, /l./).each do |item|
+ item.should be_an_instance_of(String)
+ end
end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").send(@method, StringSpecs::MyString.new("l")).each do |item|
+ item.should be_an_instance_of(StringSpecs::MyString)
+ end
+
+ StringSpecs::MyString.new("hello").send(@method, "x").each do |item|
+ item.should be_an_instance_of(StringSpecs::MyString)
+ end
- StringSpecs::MyString.new("hello").send(@method, /l./).each do |item|
- item.should be_an_instance_of(String)
+ StringSpecs::MyString.new("hello").send(@method, /l./).each do |item|
+ item.should be_an_instance_of(StringSpecs::MyString)
+ end
end
end
diff --git a/spec/ruby/core/string/shared/slice.rb b/spec/ruby/core/string/shared/slice.rb
index 3ef4bc50d7..a7c1d05b56 100644
--- a/spec/ruby/core/string/shared/slice.rb
+++ b/spec/ruby/core/string/shared/slice.rb
@@ -152,11 +152,22 @@ describe :string_slice_index_length, shared: true do
-> { "hello".send(@method, 0, bignum_value) }.should raise_error(RangeError)
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.send(@method, 0,0).should be_an_instance_of(String)
- s.send(@method, 0,4).should be_an_instance_of(String)
- s.send(@method, 1,4).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, 0,0).should be_an_instance_of(StringSpecs::MyString)
+ s.send(@method, 0,4).should be_an_instance_of(StringSpecs::MyString)
+ s.send(@method, 1,4).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, 0,0).should be_an_instance_of(String)
+ s.send(@method, 0,4).should be_an_instance_of(String)
+ s.send(@method, 1,4).should be_an_instance_of(String)
+ end
end
it "handles repeated application" do
@@ -231,11 +242,22 @@ describe :string_slice_range, shared: true do
"x".send(@method, 1...-1).should == ""
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.send(@method, 0...0).should be_an_instance_of(String)
- s.send(@method, 0..4).should be_an_instance_of(String)
- s.send(@method, 1..4).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, 0...0).should be_an_instance_of(StringSpecs::MyString)
+ s.send(@method, 0..4).should be_an_instance_of(StringSpecs::MyString)
+ s.send(@method, 1..4).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, 0...0).should be_an_instance_of(String)
+ s.send(@method, 0..4).should be_an_instance_of(String)
+ s.send(@method, 1..4).should be_an_instance_of(String)
+ end
end
it "calls to_int on range arguments" do
@@ -314,10 +336,20 @@ describe :string_slice_regexp, shared: true do
"hello there".encode("US-ASCII").send(@method, /[aeiou](.)\1/).encoding.should == Encoding::US_ASCII
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.send(@method, //).should be_an_instance_of(String)
- s.send(@method, /../).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, //).should be_an_instance_of(StringSpecs::MyString)
+ s.send(@method, /../).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, //).should be_an_instance_of(String)
+ s.send(@method, /../).should be_an_instance_of(String)
+ end
end
it "sets $~ to MatchData when there is a match and nil when there's none" do
@@ -386,10 +418,20 @@ describe :string_slice_regexp_index, shared: true do
-> { "hello".send(@method, /(.)(.)(.)/, nil) }.should raise_error(TypeError)
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.send(@method, /(.)(.)/, 0).should be_an_instance_of(String)
- s.send(@method, /(.)(.)/, 1).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, /(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
+ s.send(@method, /(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, /(.)(.)/, 0).should be_an_instance_of(String)
+ s.send(@method, /(.)(.)/, 1).should be_an_instance_of(String)
+ end
end
it "sets $~ to MatchData when there is a match and nil when there's none" do
@@ -428,11 +470,22 @@ describe :string_slice_string, shared: true do
-> { "hello".send(@method, o) }.should raise_error(TypeError)
end
- it "returns a String instance when given a subclass instance" do
- s = StringSpecs::MyString.new("el")
- r = "hello".send(@method, s)
- r.should == "el"
- r.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance when given a subclass instance" do
+ s = StringSpecs::MyString.new("el")
+ r = "hello".send(@method, s)
+ r.should == "el"
+ r.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a String instance when given a subclass instance" do
+ s = StringSpecs::MyString.new("el")
+ r = "hello".send(@method, s)
+ r.should == "el"
+ r.should be_an_instance_of(String)
+ end
end
end
@@ -478,9 +531,18 @@ describe :string_slice_regexp_group, shared: true do
-> { "hello".send(@method, /(?<q>)/, '') }.should raise_error(IndexError)
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(String)
+ end
end
it "sets $~ to MatchData when there is a match and nil when there's none" do
diff --git a/spec/ruby/core/string/shared/strip.rb b/spec/ruby/core/string/shared/strip.rb
index 3af77b50fe..0c0aae20f3 100644
--- a/spec/ruby/core/string/shared/strip.rb
+++ b/spec/ruby/core/string/shared/strip.rb
@@ -6,9 +6,19 @@ describe :string_strip, shared: true do
" hello ".encode("US-ASCII").send(@method).encoding.should == Encoding::US_ASCII
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new(" hello ").send(@method).should be_an_instance_of(String)
- StringSpecs::MyString.new(" ").send(@method).should be_an_instance_of(String)
- StringSpecs::MyString.new("").send(@method).should be_an_instance_of(String)
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new(" hello ").send(@method).should be_an_instance_of(String)
+ StringSpecs::MyString.new(" ").send(@method).should be_an_instance_of(String)
+ StringSpecs::MyString.new("").send(@method).should be_an_instance_of(String)
+ end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new(" hello ").send(@method).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new(" ").send(@method).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("").send(@method).should be_an_instance_of(StringSpecs::MyString)
+ end
end
end
diff --git a/spec/ruby/core/string/shared/succ.rb b/spec/ruby/core/string/shared/succ.rb
index 24a729ce26..3605fa99a2 100644
--- a/spec/ruby/core/string/shared/succ.rb
+++ b/spec/ruby/core/string/shared/succ.rb
@@ -59,10 +59,20 @@ describe :string_succ, shared: true do
"\xFF\xFF".send(@method).should == "\x01\x00\x00"
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("").send(@method).should be_an_instance_of(String)
- StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(String)
- StringSpecs::MyString.new("z").send(@method).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("").send(@method).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("z").send(@method).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("").send(@method).should be_an_instance_of(String)
+ StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(String)
+ StringSpecs::MyString.new("z").send(@method).should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/shared/to_a.rb b/spec/ruby/core/string/shared/to_a.rb
new file mode 100644
index 0000000000..bad3ea6584
--- /dev/null
+++ b/spec/ruby/core/string/shared/to_a.rb
@@ -0,0 +1,9 @@
+describe :string_to_a, shared: true do
+ it "returns an empty array for empty strings" do
+ "".send(@method).should == []
+ end
+
+ it "returns an array containing the string for non-empty strings" do
+ "hello".send(@method).should == ["hello"]
+ end
+end
diff --git a/spec/ruby/core/string/shared/to_sym.rb b/spec/ruby/core/string/shared/to_sym.rb
index 52d8314211..ef7c22bb6a 100644
--- a/spec/ruby/core/string/shared/to_sym.rb
+++ b/spec/ruby/core/string/shared/to_sym.rb
@@ -67,6 +67,6 @@ describe :string_to_sym, shared: true do
invalid_utf8.should_not.valid_encoding?
-> {
invalid_utf8.send(@method)
- }.should raise_error(EncodingError, 'invalid symbol in encoding UTF-8 :"\xC3"')
+ }.should raise_error(EncodingError, /invalid/)
end
end
diff --git a/spec/ruby/core/string/slice_spec.rb b/spec/ruby/core/string/slice_spec.rb
index 87c5a7ac37..c9e13ed1bc 100644
--- a/spec/ruby/core/string/slice_spec.rb
+++ b/spec/ruby/core/string/slice_spec.rb
@@ -132,10 +132,20 @@ describe "String#slice! with index, length" do
"hello".slice!(obj, obj).should == "ll"
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.slice!(0, 0).should be_an_instance_of(String)
- s.slice!(0, 4).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(0, 0).should be_an_instance_of(StringSpecs::MyString)
+ s.slice!(0, 4).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(0, 0).should be_an_instance_of(String)
+ s.slice!(0, 4).should be_an_instance_of(String)
+ end
end
it "returns the substring given by the character offsets" do
@@ -175,10 +185,20 @@ describe "String#slice! Range" do
b.should == "hello"
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.slice!(0...0).should be_an_instance_of(String)
- s.slice!(0..4).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(0...0).should be_an_instance_of(StringSpecs::MyString)
+ s.slice!(0..4).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(0...0).should be_an_instance_of(String)
+ s.slice!(0..4).should be_an_instance_of(String)
+ end
end
it "calls to_int on range arguments" do
@@ -254,10 +274,20 @@ describe "String#slice! with Regexp" do
s.should == "this is a string"
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.slice!(//).should be_an_instance_of(String)
- s.slice!(/../).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(//).should be_an_instance_of(StringSpecs::MyString)
+ s.slice!(/../).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(//).should be_an_instance_of(String)
+ s.slice!(/../).should be_an_instance_of(String)
+ end
end
it "returns the matching portion of self with a multi byte character" do
@@ -314,10 +344,20 @@ describe "String#slice! with Regexp, index" do
"har".slice!(/(.)(.)(.)/, obj).should == "a"
end
- it "returns String instances" do
- s = StringSpecs::MyString.new("hello")
- s.slice!(/(.)(.)/, 0).should be_an_instance_of(String)
- s.slice!(/(.)(.)/, 1).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(/(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
+ s.slice!(/(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ s = StringSpecs::MyString.new("hello")
+ s.slice!(/(.)(.)/, 0).should be_an_instance_of(String)
+ s.slice!(/(.)(.)/, 1).should be_an_instance_of(String)
+ end
end
it "returns the encoding aware capture for the given index" do
@@ -375,11 +415,22 @@ describe "String#slice! with String" do
-> { "hello".slice!(o) }.should raise_error(TypeError)
end
- it "returns a subclass instance when given a subclass instance" do
- s = StringSpecs::MyString.new("el")
- r = "hello".slice!(s)
- r.should == "el"
- r.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance when given a subclass instance" do
+ s = StringSpecs::MyString.new("el")
+ r = "hello".slice!(s)
+ r.should == "el"
+ r.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a subclass instance when given a subclass instance" do
+ s = StringSpecs::MyString.new("el")
+ r = "hello".slice!(s)
+ r.should == "el"
+ r.should be_an_instance_of(String)
+ end
end
it "raises a FrozenError if self is frozen" do
diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb
index c5cca651c2..519c5d845d 100644
--- a/spec/ruby/core/string/split_spec.rb
+++ b/spec/ruby/core/string/split_spec.rb
@@ -192,16 +192,44 @@ describe "String#split with String" do
"foo".split("bar", 3).should == ["foo"]
end
- it "returns String instances based on self" do
- ["", "x.y.z.", " x y "].each do |str|
- ["", ".", " "].each do |pat|
- [-1, 0, 1, 2].each do |limit|
- StringSpecs::MyString.new(str).split(pat, limit).each do |x|
- x.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances based on self" do
+ ["", "x.y.z.", " x y "].each do |str|
+ ["", ".", " "].each do |pat|
+ [-1, 0, 1, 2].each do |limit|
+ StringSpecs::MyString.new(str).split(pat, limit).each do |x|
+ x.should be_an_instance_of(StringSpecs::MyString)
+ end
+
+ str.split(StringSpecs::MyString.new(pat), limit).each do |x|
+ x.should be_an_instance_of(String)
+ end
end
+ end
+ end
+ end
+
+ it "does not call constructor on created subclass instances" do
+ # can't call should_not_receive on an object that doesn't yet exist
+ # so failure here is signalled by exception, not expectation failure
+
+ s = StringSpecs::StringWithRaisingConstructor.new('silly:string')
+ s.split(':').first.should == 'silly'
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances based on self" do
+ ["", "x.y.z.", " x y "].each do |str|
+ ["", ".", " "].each do |pat|
+ [-1, 0, 1, 2].each do |limit|
+ StringSpecs::MyString.new(str).split(pat, limit).each do |x|
+ x.should be_an_instance_of(String)
+ end
- str.split(StringSpecs::MyString.new(pat), limit).each do |x|
- x.should be_an_instance_of(String)
+ str.split(StringSpecs::MyString.new(pat), limit).each do |x|
+ x.should be_an_instance_of(String)
+ end
end
end
end
@@ -386,12 +414,36 @@ describe "String#split with Regexp" do
"foo".split(/bar/, 3).should == ["foo"]
end
- it "returns String instances based on self" do
- ["", "x:y:z:", " x y "].each do |str|
- [//, /:/, /\s+/].each do |pat|
- [-1, 0, 1, 2].each do |limit|
- StringSpecs::MyString.new(str).split(pat, limit).each do |x|
- x.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances based on self" do
+ ["", "x:y:z:", " x y "].each do |str|
+ [//, /:/, /\s+/].each do |pat|
+ [-1, 0, 1, 2].each do |limit|
+ StringSpecs::MyString.new(str).split(pat, limit).each do |x|
+ x.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+ end
+ end
+ end
+
+ it "does not call constructor on created subclass instances" do
+ # can't call should_not_receive on an object that doesn't yet exist
+ # so failure here is signalled by exception, not expectation failure
+
+ s = StringSpecs::StringWithRaisingConstructor.new('silly:string')
+ s.split(/:/).first.should == 'silly'
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances based on self" do
+ ["", "x:y:z:", " x y "].each do |str|
+ [//, /:/, /\s+/].each do |pat|
+ [-1, 0, 1, 2].each do |limit|
+ StringSpecs::MyString.new(str).split(pat, limit).each do |x|
+ x.should be_an_instance_of(String)
+ end
end
end
end
@@ -517,16 +569,32 @@ describe "String#split with Regexp" do
end
describe "for a String subclass" do
- it "yields instances of String" do
- a = []
- StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
- first, last = a
+ ruby_version_is ''...'3.0' do
+ it "yields instances of the same subclass" do
+ a = []
+ StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
+ first, last = a
- first.should be_an_instance_of(String)
- first.should == "a"
+ first.should be_an_instance_of(StringSpecs::MyString)
+ first.should == "a"
- last.should be_an_instance_of(String)
- last.should == "b"
+ last.should be_an_instance_of(StringSpecs::MyString)
+ last.should == "b"
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "yields instances of String" do
+ a = []
+ StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
+ first, last = a
+
+ first.should be_an_instance_of(String)
+ first.should == "a"
+
+ last.should be_an_instance_of(String)
+ last.should == "b"
+ end
end
end
diff --git a/spec/ruby/core/string/squeeze_spec.rb b/spec/ruby/core/string/squeeze_spec.rb
index 4796a170f2..2f3fa65745 100644
--- a/spec/ruby/core/string/squeeze_spec.rb
+++ b/spec/ruby/core/string/squeeze_spec.rb
@@ -75,8 +75,16 @@ describe "String#squeeze" do
-> { "hello world".squeeze(mock('x')) }.should raise_error(TypeError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("oh no!!!").squeeze("!").should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("oh no!!!").squeeze("!").should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("oh no!!!").squeeze("!").should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/string/start_with_spec.rb b/spec/ruby/core/string/start_with_spec.rb
index 35e33b46a6..3833289f96 100644
--- a/spec/ruby/core/string/start_with_spec.rb
+++ b/spec/ruby/core/string/start_with_spec.rb
@@ -7,21 +7,12 @@ describe "String#start_with?" do
it_behaves_like :start_with, :to_s
# Here and not in the shared examples because this is invalid as a Symbol
- it "matches part of a character with the same part" do
+ it "does not check that we are not starting to match at the head of a character" do
"\xA9".should.start_with?("\xA9") # A9 is not a character head for UTF-8
end
- ruby_version_is ""..."3.3" do
- it "does not check we are matching only part of a character" do
- "\xe3\x81\x82".size.should == 1
- "\xe3\x81\x82".should.start_with?("\xe3")
- end
- end
-
- ruby_version_is "3.3" do # #19784
- it "checks we are matching only part of a character" do
- "\xe3\x81\x82".size.should == 1
- "\xe3\x81\x82".should_not.start_with?("\xe3")
- end
+ it "does not check we are matching only part of a character" do
+ "\xe3\x81\x82".size.should == 1
+ "\xe3\x81\x82".should.start_with?("\xe3")
end
end
diff --git a/spec/ruby/core/string/strip_spec.rb b/spec/ruby/core/string/strip_spec.rb
index 5e90fe35d0..662f13b032 100644
--- a/spec/ruby/core/string/strip_spec.rb
+++ b/spec/ruby/core/string/strip_spec.rb
@@ -11,8 +11,10 @@ describe "String#strip" do
"\tgoodbye\r\v\n".strip.should == "goodbye"
end
- it "returns a copy of self without leading and trailing NULL bytes and whitespace" do
- " \x00 goodbye \x00 ".strip.should == "goodbye"
+ ruby_version_is '3.0' do
+ it "returns a copy of self without leading and trailing NULL bytes and whitespace" do
+ " \x00 goodbye \x00 ".strip.should == "goodbye"
+ end
end
end
@@ -39,10 +41,12 @@ describe "String#strip!" do
" ".strip.should == ""
end
- it "removes leading and trailing NULL bytes and whitespace" do
- a = "\000 goodbye \000"
- a.strip!
- a.should == "goodbye"
+ ruby_version_is '3.0' do
+ it "removes leading and trailing NULL bytes and whitespace" do
+ a = "\000 goodbye \000"
+ a.strip!
+ a.should == "goodbye"
+ end
end
it "raises a FrozenError on a frozen instance that is modified" do
diff --git a/spec/ruby/core/string/sub_spec.rb b/spec/ruby/core/string/sub_spec.rb
index 51920486f5..99dd7b45a8 100644
--- a/spec/ruby/core/string/sub_spec.rb
+++ b/spec/ruby/core/string/sub_spec.rb
@@ -170,11 +170,22 @@ describe "String#sub with pattern, replacement" do
-> { "hello".sub(/[aeiou]/, 99) }.should raise_error(TypeError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("").sub(//, "").should be_an_instance_of(String)
- StringSpecs::MyString.new("").sub(/foo/, "").should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").sub(/foo/, "").should be_an_instance_of(String)
- StringSpecs::MyString.new("foo").sub("foo", "").should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("").sub(//, "").should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("").sub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").sub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("foo").sub("foo", "").should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("").sub(//, "").should be_an_instance_of(String)
+ StringSpecs::MyString.new("").sub(/foo/, "").should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").sub(/foo/, "").should be_an_instance_of(String)
+ StringSpecs::MyString.new("foo").sub("foo", "").should be_an_instance_of(String)
+ end
end
it "sets $~ to MatchData of match and nil when there's none" do
diff --git a/spec/ruby/core/string/swapcase_spec.rb b/spec/ruby/core/string/swapcase_spec.rb
index d740fb86c6..d369ab3e4e 100644
--- a/spec/ruby/core/string/swapcase_spec.rb
+++ b/spec/ruby/core/string/swapcase_spec.rb
@@ -74,9 +74,18 @@ describe "String#swapcase" do
-> { "abc".swapcase(:invalid_option) }.should raise_error(ArgumentError)
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("").swapcase.should be_an_instance_of(String)
- StringSpecs::MyString.new("hello").swapcase.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("").swapcase.should be_an_instance_of(StringSpecs::MyString)
+ StringSpecs::MyString.new("hello").swapcase.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("").swapcase.should be_an_instance_of(String)
+ StringSpecs::MyString.new("hello").swapcase.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/string/to_c_spec.rb b/spec/ruby/core/string/to_c_spec.rb
index 9d24f1f56c..edc8a4f14f 100644
--- a/spec/ruby/core/string/to_c_spec.rb
+++ b/spec/ruby/core/string/to_c_spec.rb
@@ -38,16 +38,4 @@ describe "String#to_c" do
'79+4i'.encode("UTF-16").to_c
}.should raise_error(Encoding::CompatibilityError, "ASCII incompatible encoding: UTF-16")
end
-
- ruby_version_is "3.2" do
- it "treats a sequence of underscores as an end of Complex string" do
- "5+3_1i".to_c.should == Complex(5, 31)
- "5+3__1i".to_c.should == Complex(5)
- "5+3___1i".to_c.should == Complex(5)
-
- "12_3".to_c.should == Complex(123)
- "12__3".to_c.should == Complex(12)
- "12___3".to_c.should == Complex(12)
- end
- end
end
diff --git a/spec/ruby/core/string/tr_s_spec.rb b/spec/ruby/core/string/tr_s_spec.rb
index 3c31473044..e1bb20ce35 100644
--- a/spec/ruby/core/string/tr_s_spec.rb
+++ b/spec/ruby/core/string/tr_s_spec.rb
@@ -17,15 +17,6 @@ describe "String#tr_s" do
"hello ^--^".tr_s("---", "_").should == "hello ^_^"
end
- ruby_bug "#19769", ""..."3.3" do
- it "accepts c1-c1 notation to denote range of one character" do
- "hello".tr_s('e-e', 'x').should == "hxllo"
- "123456789".tr_s("2-23","xy").should == "1xy456789"
- "hello ^-^".tr_s("e-", "a-a_").should == "hallo ^_^"
- "hello ^-^".tr_s("---o", "_a").should == "hella ^_^"
- end
- end
-
it "pads to_str with its last char if it is shorter than from_string" do
"this".tr_s("this", "x").should == "x"
end
@@ -54,8 +45,16 @@ describe "String#tr_s" do
"bla".tr_s(from_str, to_str).should == "BlA"
end
- it "returns String instances when called on a subclass" do
- StringSpecs::MyString.new("hello").tr_s("e", "a").should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").tr_s("e", "a").should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").tr_s("e", "a").should be_an_instance_of(String)
+ end
end
# http://redmine.ruby-lang.org/issues/show/1839
diff --git a/spec/ruby/core/string/tr_spec.rb b/spec/ruby/core/string/tr_spec.rb
index d60480dc7e..72adb9f2eb 100644
--- a/spec/ruby/core/string/tr_spec.rb
+++ b/spec/ruby/core/string/tr_spec.rb
@@ -16,15 +16,6 @@ describe "String#tr" do
"hello ^-^".tr("---", "_").should == "hello ^_^"
end
- ruby_bug "#19769", ""..."3.3" do
- it "accepts c1-c1 notation to denote range of one character" do
- "hello".tr('e-e', 'x').should == "hxllo"
- "123456789".tr("2-23","xy").should == "1xy456789"
- "hello ^-^".tr("e-", "a-a_").should == "hallo ^_^"
- "hello ^-^".tr("---o", "_a").should == "hella ^_^"
- end
- end
-
it "pads to_str with its last char if it is shorter than from_string" do
"this".tr("this", "x").should == "xxxx"
"hello".tr("a-z", "A-H.").should == "HE..."
@@ -66,8 +57,16 @@ describe "String#tr" do
"bla".tr(from_str, to_str).should == "BlA"
end
- it "returns Stringinstances when called on a subclass" do
- StringSpecs::MyString.new("hello").tr("e", "a").should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances when called on a subclass" do
+ StringSpecs::MyString.new("hello").tr("e", "a").should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns Stringinstances when called on a subclass" do
+ StringSpecs::MyString.new("hello").tr("e", "a").should be_an_instance_of(String)
+ end
end
# http://redmine.ruby-lang.org/issues/show/1839
diff --git a/spec/ruby/core/string/try_convert_spec.rb b/spec/ruby/core/string/try_convert_spec.rb
index 72ce5dd8b2..84415c4a75 100644
--- a/spec/ruby/core/string/try_convert_spec.rb
+++ b/spec/ruby/core/string/try_convert_spec.rb
@@ -39,7 +39,7 @@ describe "String.try_convert" do
it "sends #to_str to the argument and raises TypeError if it's not a kind of String" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return(Object.new)
- -> { String.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to String (MockObject#to_str gives Object)")
+ -> { String.try_convert obj }.should raise_error(TypeError)
end
it "does not rescue exceptions raised by #to_str" do
diff --git a/spec/ruby/core/string/unpack/b_spec.rb b/spec/ruby/core/string/unpack/b_spec.rb
index 5c53eff721..2cf5ebad34 100644
--- a/spec/ruby/core/string/unpack/b_spec.rb
+++ b/spec/ruby/core/string/unpack/b_spec.rb
@@ -88,9 +88,7 @@ describe "String#unpack with format 'B'" do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "\x80\x00".unpack("B\x00B").should == ["1", "0"]
- end
+ "\x80\x00".unpack("B\x00B").should == ["1", "0"]
end
end
@@ -196,9 +194,7 @@ describe "String#unpack with format 'b'" do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "\x01\x00".unpack("b\x00b").should == ["1", "0"]
- end
+ "\x01\x00".unpack("b\x00b").should == ["1", "0"]
end
end
diff --git a/spec/ruby/core/string/unpack/c_spec.rb b/spec/ruby/core/string/unpack/c_spec.rb
index c2bf813954..dbcbacc74d 100644
--- a/spec/ruby/core/string/unpack/c_spec.rb
+++ b/spec/ruby/core/string/unpack/c_spec.rb
@@ -37,9 +37,7 @@ describe :string_unpack_8bit, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "abc".unpack(unpack_format("\000", 2)).should == [97, 98]
- end
+ "abc".unpack(unpack_format("\000", 2)).should == [97, 98]
end
end
diff --git a/spec/ruby/core/string/unpack/h_spec.rb b/spec/ruby/core/string/unpack/h_spec.rb
index 19c4d63664..ee08d20926 100644
--- a/spec/ruby/core/string/unpack/h_spec.rb
+++ b/spec/ruby/core/string/unpack/h_spec.rb
@@ -58,9 +58,7 @@ describe "String#unpack with format 'H'" do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "\x01\x10".unpack("H\x00H").should == ["0", "1"]
- end
+ "\x01\x10".unpack("H\x00H").should == ["0", "1"]
end
end
@@ -135,9 +133,7 @@ describe "String#unpack with format 'h'" do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "\x01\x10".unpack("h\x00h").should == ["1", "0"]
- end
+ "\x01\x10".unpack("h\x00h").should == ["1", "0"]
end
end
diff --git a/spec/ruby/core/string/unpack/shared/float.rb b/spec/ruby/core/string/unpack/shared/float.rb
index 93282bf4c9..ccddf94f99 100644
--- a/spec/ruby/core/string/unpack/shared/float.rb
+++ b/spec/ruby/core/string/unpack/shared/float.rb
@@ -58,10 +58,8 @@ describe :string_unpack_float_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- array = "\x9a\x999@33\xb3?".unpack(unpack_format("\000", 2))
- array.should == [2.9000000953674316, 1.399999976158142]
- end
+ array = "\x9a\x999@33\xb3?".unpack(unpack_format("\000", 2))
+ array.should == [2.9000000953674316, 1.399999976158142]
end
end
@@ -137,10 +135,8 @@ describe :string_unpack_float_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- array = "@9\x99\x9a?\xb333".unpack(unpack_format("\000", 2))
- array.should == [2.9000000953674316, 1.399999976158142]
- end
+ array = "@9\x99\x9a?\xb333".unpack(unpack_format("\000", 2))
+ array.should == [2.9000000953674316, 1.399999976158142]
end
end
@@ -219,9 +215,7 @@ describe :string_unpack_double_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "333333\x07@ffffff\xf6?".unpack(unpack_format("\000", 2)).should == [2.9, 1.4]
- end
+ "333333\x07@ffffff\xf6?".unpack(unpack_format("\000", 2)).should == [2.9, 1.4]
end
end
@@ -299,9 +293,7 @@ describe :string_unpack_double_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "@\x07333333?\xf6ffffff".unpack(unpack_format("\000", 2)).should == [2.9, 1.4]
- end
+ "@\x07333333?\xf6ffffff".unpack(unpack_format("\000", 2)).should == [2.9, 1.4]
end
end
diff --git a/spec/ruby/core/string/unpack/shared/integer.rb b/spec/ruby/core/string/unpack/shared/integer.rb
index d71a2cf00d..ba4f149dad 100644
--- a/spec/ruby/core/string/unpack/shared/integer.rb
+++ b/spec/ruby/core/string/unpack/shared/integer.rb
@@ -34,9 +34,7 @@ describe :string_unpack_16bit_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "abcd".unpack(unpack_format("\000", 2)).should == [25185, 25699]
- end
+ "abcd".unpack(unpack_format("\000", 2)).should == [25185, 25699]
end
end
@@ -99,9 +97,7 @@ describe :string_unpack_16bit_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "badc".unpack(unpack_format("\000", 2)).should == [25185, 25699]
- end
+ "badc".unpack(unpack_format("\000", 2)).should == [25185, 25699]
end
end
@@ -165,9 +161,7 @@ describe :string_unpack_32bit_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "abcdefgh".unpack(unpack_format("\000", 2)).should == [1684234849, 1751606885]
- end
+ "abcdefgh".unpack(unpack_format("\000", 2)).should == [1684234849, 1751606885]
end
end
@@ -231,9 +225,7 @@ describe :string_unpack_32bit_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "dcbahgfe".unpack(unpack_format("\000", 2)).should == [1684234849, 1751606885]
- end
+ "dcbahgfe".unpack(unpack_format("\000", 2)).should == [1684234849, 1751606885]
end
end
@@ -293,10 +285,8 @@ describe :string_unpack_64bit_le, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- array = "abcdefghabghefcd".unpack(unpack_format("\000", 2))
- array.should == [7523094288207667809, 7233738012216484449]
- end
+ array = "abcdefghabghefcd".unpack(unpack_format("\000", 2))
+ array.should == [7523094288207667809, 7233738012216484449]
end
end
@@ -367,10 +357,8 @@ describe :string_unpack_64bit_be, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- array = "hgfedcbadcfehgba".unpack(unpack_format("\000", 2))
- array.should == [7523094288207667809, 7233738012216484449]
- end
+ array = "hgfedcbadcfehgba".unpack(unpack_format("\000", 2))
+ array.should == [7523094288207667809, 7233738012216484449]
end
end
diff --git a/spec/ruby/core/string/unpack/shared/unicode.rb b/spec/ruby/core/string/unpack/shared/unicode.rb
index 9fe07f53ae..ce1f29fe87 100644
--- a/spec/ruby/core/string/unpack/shared/unicode.rb
+++ b/spec/ruby/core/string/unpack/shared/unicode.rb
@@ -52,9 +52,7 @@ describe :string_unpack_unicode, shared: true do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "\x01\x02".unpack("U\x00U").should == [1, 2]
- end
+ "\x01\x02".unpack("U\x00U").should == [1, 2]
end
end
diff --git a/spec/ruby/core/string/unpack/w_spec.rb b/spec/ruby/core/string/unpack/w_spec.rb
index 6a1cff1965..b213b32921 100644
--- a/spec/ruby/core/string/unpack/w_spec.rb
+++ b/spec/ruby/core/string/unpack/w_spec.rb
@@ -17,9 +17,7 @@ describe "String#unpack with directive 'w'" do
ruby_version_is ""..."3.3" do
it "ignores NULL bytes between directives" do
- suppress_warning do
- "\x01\x02\x03".unpack("w\x00w").should == [1, 2]
- end
+ "\x01\x02\x03".unpack("w\x00w").should == [1, 2]
end
end
diff --git a/spec/ruby/core/string/unpack_spec.rb b/spec/ruby/core/string/unpack_spec.rb
index 52b4af3a95..4ff7d07460 100644
--- a/spec/ruby/core/string/unpack_spec.rb
+++ b/spec/ruby/core/string/unpack_spec.rb
@@ -31,4 +31,4 @@ describe "String#unpack" do
-> { "a".unpack("C", offset: 2) }.should raise_error(ArgumentError, "offset outside of string")
end
end
-end
+end \ No newline at end of file
diff --git a/spec/ruby/core/string/upcase_spec.rb b/spec/ruby/core/string/upcase_spec.rb
index a2e34f5f40..5ce7b0b95f 100644
--- a/spec/ruby/core/string/upcase_spec.rb
+++ b/spec/ruby/core/string/upcase_spec.rb
@@ -73,8 +73,16 @@ describe "String#upcase" do
-> { "abc".upcase(:invalid_option) }.should raise_error(ArgumentError)
end
- it "returns a String instance for subclasses" do
- StringSpecs::MyString.new("fooBAR").upcase.should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance for subclasses" do
+ StringSpecs::MyString.new("fooBAR").upcase.should be_an_instance_of(StringSpecs::MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a String instance for subclasses" do
+ StringSpecs::MyString.new("fooBAR").upcase.should be_an_instance_of(String)
+ end
end
end
diff --git a/spec/ruby/core/string/uplus_spec.rb b/spec/ruby/core/string/uplus_spec.rb
index 65b66260dd..038b283c90 100644
--- a/spec/ruby/core/string/uplus_spec.rb
+++ b/spec/ruby/core/string/uplus_spec.rb
@@ -7,9 +7,6 @@ describe 'String#+@' do
output.should_not.frozen?
output.should == 'foo'
-
- output << 'bar'
- output.should == 'foobar'
end
it 'returns self if the String is not frozen' do
diff --git a/spec/ruby/core/string/upto_spec.rb b/spec/ruby/core/string/upto_spec.rb
index 3799e338e0..f8529b1d2b 100644
--- a/spec/ruby/core/string/upto_spec.rb
+++ b/spec/ruby/core/string/upto_spec.rb
@@ -80,12 +80,6 @@ describe "String#upto" do
a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"]
end
- it "raises Encoding::CompatibilityError when incompatible characters are given" do
- char1 = 'a'.force_encoding("EUC-JP")
- char2 = 'b'.force_encoding("ISO-2022-JP")
- -> { char1.upto(char2) {} }.should raise_error(Encoding::CompatibilityError, "incompatible character encodings: EUC-JP and ISO-2022-JP")
- end
-
describe "on sequence of numbers" do
it "calls the block as Integer#upto" do
"8".upto("11").to_a.should == 8.upto(11).map(&:to_s)
diff --git a/spec/ruby/core/string/valid_encoding_spec.rb b/spec/ruby/core/string/valid_encoding_spec.rb
index bb26062c0f..be7cef7a8e 100644
--- a/spec/ruby/core/string/valid_encoding_spec.rb
+++ b/spec/ruby/core/string/valid_encoding_spec.rb
@@ -100,10 +100,12 @@ describe "String#valid_encoding?" do
str.force_encoding('UTF8-MAC').valid_encoding?.should be_true
end
- it "returns true for IBM720 encoding self is valid in" do
- str = "\xE6\x9D\x94"
- str.force_encoding('IBM720').valid_encoding?.should be_true
- str.force_encoding('CP720').valid_encoding?.should be_true
+ ruby_version_is '3.0' do
+ it "returns true for IBM720 encoding self is valid in" do
+ str = "\xE6\x9D\x94"
+ str.force_encoding('IBM720').valid_encoding?.should be_true
+ str.force_encoding('CP720').valid_encoding?.should be_true
+ end
end
it "returns false if self is valid in one encoding, but invalid in the one it's tagged with" do
diff --git a/spec/ruby/core/struct/constants_spec.rb b/spec/ruby/core/struct/constants_spec.rb
deleted file mode 100644
index fa61a4b912..0000000000
--- a/spec/ruby/core/struct/constants_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require_relative '../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Struct::Group" do
- it "is no longer defined" do
- Struct.should_not.const_defined?(:Group)
- end
- end
-
- describe "Struct::Passwd" do
- it "is no longer defined" do
- Struct.should_not.const_defined?(:Passwd)
- end
- end
-end
diff --git a/spec/ruby/core/struct/deconstruct_keys_spec.rb b/spec/ruby/core/struct/deconstruct_keys_spec.rb
index b4c84c49df..088803d028 100644
--- a/spec/ruby/core/struct/deconstruct_keys_spec.rb
+++ b/spec/ruby/core/struct/deconstruct_keys_spec.rb
@@ -64,7 +64,7 @@ describe "Struct#deconstruct_keys" do
obj.deconstruct_keys(nil).should == {x: 1, y: 2}
end
- it "raise TypeError if passed anything except nil or array" do
+ it "raise TypeError if passed anything accept nil or array" do
struct = Struct.new(:x, :y)
s = struct.new(1, 2)
diff --git a/spec/ruby/core/struct/fixtures/classes.rb b/spec/ruby/core/struct/fixtures/classes.rb
index bf838d05df..6d620f9060 100644
--- a/spec/ruby/core/struct/fixtures/classes.rb
+++ b/spec/ruby/core/struct/fixtures/classes.rb
@@ -13,12 +13,6 @@ module StructClasses
end
end
- class StructWithOverriddenName < Struct.new(:a)
- def self.name
- "A"
- end
- end
-
class SubclassX < Struct
end
diff --git a/spec/ruby/core/struct/initialize_spec.rb b/spec/ruby/core/struct/initialize_spec.rb
index a5ebe9551c..cfb302209e 100644
--- a/spec/ruby/core/struct/initialize_spec.rb
+++ b/spec/ruby/core/struct/initialize_spec.rb
@@ -48,14 +48,4 @@ describe "Struct#initialize" do
}.should complain(/warning: Passing only keyword arguments/)
end
end
-
- ruby_version_is "3.2" do
- it "can be initialized with keyword arguments" do
- positional_args = StructClasses::Ruby.new("3.2", "OS")
- keyword_args = StructClasses::Ruby.new(version: "3.2", platform: "OS")
-
- positional_args.version.should == keyword_args.version
- positional_args.platform.should == keyword_args.platform
- end
- end
end
diff --git a/spec/ruby/core/struct/inspect_spec.rb b/spec/ruby/core/struct/inspect_spec.rb
index 657b06abc1..83e13597ba 100644
--- a/spec/ruby/core/struct/inspect_spec.rb
+++ b/spec/ruby/core/struct/inspect_spec.rb
@@ -3,5 +3,10 @@ require_relative 'fixtures/classes'
require_relative 'shared/inspect'
describe "Struct#inspect" do
+ it "returns a string representation showing members and values" do
+ car = StructClasses::Car.new('Ford', 'Ranger')
+ car.inspect.should == '#<struct StructClasses::Car make="Ford", model="Ranger", year=nil>'
+ end
+
it_behaves_like :struct_inspect, :inspect
end
diff --git a/spec/ruby/core/struct/keyword_init_spec.rb b/spec/ruby/core/struct/keyword_init_spec.rb
index 8de4c14351..061f4c56e0 100644
--- a/spec/ruby/core/struct/keyword_init_spec.rb
+++ b/spec/ruby/core/struct/keyword_init_spec.rb
@@ -17,24 +17,5 @@ ruby_version_is "3.1" do
struct = Struct.new(:arg)
struct.keyword_init?.should be_nil
end
-
- it "returns nil for a struct that does specify keyword_init to be nil" do
- struct = Struct.new(:arg, keyword_init: nil)
- struct.keyword_init?.should be_nil
- end
-
- it "returns true for any truthy value, not just for true" do
- struct = Struct.new(:arg, keyword_init: 1)
- struct.keyword_init?.should be_true
-
- struct = Struct.new(:arg, keyword_init: "")
- struct.keyword_init?.should be_true
-
- struct = Struct.new(:arg, keyword_init: [])
- struct.keyword_init?.should be_true
-
- struct = Struct.new(:arg, keyword_init: {})
- struct.keyword_init?.should be_true
- end
end
end
diff --git a/spec/ruby/core/struct/new_spec.rb b/spec/ruby/core/struct/new_spec.rb
index 8758051a81..7b4a4f7980 100644
--- a/spec/ruby/core/struct/new_spec.rb
+++ b/spec/ruby/core/struct/new_spec.rb
@@ -47,11 +47,6 @@ describe "Struct.new" do
Struct.const_defined?("Animal2").should be_false
end
- it "allows non-ASCII member name" do
- name = "r\xe9sum\xe9".force_encoding(Encoding::ISO_8859_1).to_sym
- struct = Struct.new(name)
- struct.new("foo").send(name).should == "foo"
- end
it "fails with invalid constant name as first argument" do
-> { Struct.new('animal', :name, :legs, :eyeballs) }.should raise_error(NameError)
@@ -83,20 +78,6 @@ describe "Struct.new" do
end
end
- ruby_version_is ""..."3.3" do
- it "raises ArgumentError if not provided any arguments" do
- -> { Struct.new }.should raise_error(ArgumentError)
- end
- end
-
- ruby_version_is "3.3" do
- it "works when not provided any arguments" do
- c = Struct.new
- c.should be_kind_of(Class)
- c.superclass.should == Struct
- end
- end
-
it "raises ArgumentError when there is a duplicate member" do
-> { Struct.new(:foo, :foo) }.should raise_error(ArgumentError, "duplicate member: foo")
end
diff --git a/spec/ruby/core/struct/shared/inspect.rb b/spec/ruby/core/struct/shared/inspect.rb
index 1a0fb6a6b2..90594a5452 100644
--- a/spec/ruby/core/struct/shared/inspect.rb
+++ b/spec/ruby/core/struct/shared/inspect.rb
@@ -1,40 +1,5 @@
describe :struct_inspect, shared: true do
- it "returns a string representation showing members and values" do
- car = StructClasses::Car.new('Ford', 'Ranger')
- car.send(@method).should == '#<struct StructClasses::Car make="Ford", model="Ranger", year=nil>'
- end
-
it "returns a string representation without the class name for anonymous structs" do
Struct.new(:a).new("").send(@method).should == '#<struct a="">'
end
-
- it "returns a string representation without the class name for structs nested in anonymous classes" do
- c = Class.new
- c.class_eval <<~DOC
- class Foo < Struct.new(:a); end
- DOC
-
- c::Foo.new("").send(@method).should == '#<struct a="">'
- end
-
- it "returns a string representation without the class name for structs nested in anonymous modules" do
- m = Module.new
- m.module_eval <<~DOC
- class Foo < Struct.new(:a); end
- DOC
-
- m::Foo.new("").send(@method).should == '#<struct a="">'
- end
-
- it "does not call #name method" do
- struct = StructClasses::StructWithOverriddenName.new("")
- struct.send(@method).should == '#<struct StructClasses::StructWithOverriddenName a="">'
- end
-
- it "does not call #name method when struct is anonymous" do
- struct = Struct.new(:a)
- def struct.name; "A"; end
-
- struct.new("").send(@method).should == '#<struct a="">'
- end
end
diff --git a/spec/ruby/core/symbol/casecmp_spec.rb b/spec/ruby/core/symbol/casecmp_spec.rb
index 662a29a284..80ea51e910 100644
--- a/spec/ruby/core/symbol/casecmp_spec.rb
+++ b/spec/ruby/core/symbol/casecmp_spec.rb
@@ -56,10 +56,6 @@ describe "Symbol#casecmp with Symbol" do
lower_a_tilde.casecmp(upper_a_tilde).should == 1
lower_a_umlaut.casecmp(upper_a_umlaut).should == 1
end
-
- it "returns 0 for empty strings in different encodings" do
- ''.to_sym.casecmp(''.encode("UTF-32LE").to_sym).should == 0
- end
end
describe "Symbol#casecmp" do
@@ -145,8 +141,4 @@ describe 'Symbol#casecmp?' do
upper_a_tilde.casecmp?(lower_a_tilde).should == nil
lower_a_tilde.casecmp?(upper_a_tilde).should == nil
end
-
- it "returns true for empty symbols in different encodings" do
- ''.to_sym.should.casecmp?(''.encode("UTF-32LE").to_sym)
- end
end
diff --git a/spec/ruby/core/symbol/inspect_spec.rb b/spec/ruby/core/symbol/inspect_spec.rb
index 6dbb36c2ad..58402ab261 100644
--- a/spec/ruby/core/symbol/inspect_spec.rb
+++ b/spec/ruby/core/symbol/inspect_spec.rb
@@ -5,8 +5,6 @@ describe "Symbol#inspect" do
fred: ":fred",
:fred? => ":fred?",
:fred! => ":fred!",
- :BAD! => ":BAD!",
- :_BAD! => ":_BAD!",
:$ruby => ":$ruby",
:@ruby => ":@ruby",
:@@ruby => ":@@ruby",
diff --git a/spec/ruby/core/symbol/name_spec.rb b/spec/ruby/core/symbol/name_spec.rb
index f9b631266c..15b9aa75e9 100644
--- a/spec/ruby/core/symbol/name_spec.rb
+++ b/spec/ruby/core/symbol/name_spec.rb
@@ -1,17 +1,19 @@
require_relative '../../spec_helper'
-describe "Symbol#name" do
- it "returns string" do
- :ruby.name.should == "ruby"
- :ルビー.name.should == "ルビー"
- end
+ruby_version_is "3.0" do
+ describe "Symbol#name" do
+ it "returns string" do
+ :ruby.name.should == "ruby"
+ :ルビー.name.should == "ルビー"
+ end
- it "returns same string instance" do
- :"ruby_3".name.should.equal?(:ruby_3.name)
- :"ruby_#{1+2}".name.should.equal?(:ruby_3.name)
- end
+ it "returns same string instance" do
+ :"ruby_3".name.should.equal?(:ruby_3.name)
+ :"ruby_#{1+2}".name.should.equal?(:ruby_3.name)
+ end
- it "returns frozen string" do
- :symbol.name.should.frozen?
+ it "returns frozen string" do
+ :symbol.name.should.frozen?
+ end
end
end
diff --git a/spec/ruby/core/symbol/to_proc_spec.rb b/spec/ruby/core/symbol/to_proc_spec.rb
index 2cd013696a..6d9c4bc622 100644
--- a/spec/ruby/core/symbol/to_proc_spec.rb
+++ b/spec/ruby/core/symbol/to_proc_spec.rb
@@ -12,19 +12,38 @@ describe "Symbol#to_proc" do
:to_s.to_proc.call(obj).should == "Received #to_s"
end
- it "returns a Proc with #lambda? true" do
- pr = :to_s.to_proc
- pr.should.lambda?
- end
+ ruby_version_is ""..."3.0" do
+ it "returns a Proc with #lambda? false" do
+ pr = :to_s.to_proc
+ pr.should_not.lambda?
+ end
- it "produces a Proc with arity -2" do
- pr = :to_s.to_proc
- pr.arity.should == -2
+ it "produces a Proc with arity -1" do
+ pr = :to_s.to_proc
+ pr.arity.should == -1
+ end
+
+ it "produces a Proc that always returns [[:rest]] for #parameters" do
+ pr = :to_s.to_proc
+ pr.parameters.should == [[:rest]]
+ end
end
- it "produces a Proc that always returns [[:req], [:rest]] for #parameters" do
- pr = :to_s.to_proc
- pr.parameters.should == [[:req], [:rest]]
+ ruby_version_is "3.0" do
+ it "returns a Proc with #lambda? true" do
+ pr = :to_s.to_proc
+ pr.should.lambda?
+ end
+
+ it "produces a Proc with arity -2" do
+ pr = :to_s.to_proc
+ pr.arity.should == -2
+ end
+
+ it "produces a Proc that always returns [[:req], [:rest]] for #parameters" do
+ pr = :to_s.to_proc
+ pr.parameters.should == [[:req], [:rest]]
+ end
end
ruby_version_is "3.2" do
diff --git a/spec/ruby/core/thread/backtrace/location/path_spec.rb b/spec/ruby/core/thread/backtrace/location/path_spec.rb
index 75f76833a9..7863c055d3 100644
--- a/spec/ruby/core/thread/backtrace/location/path_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/path_spec.rb
@@ -41,7 +41,7 @@ describe 'Thread::Backtrace::Location#path' do
context 'when using a relative script path' do
it 'returns a path relative to the working directory' do
path = 'fixtures/main.rb'
- directory = __dir__
+ directory = File.dirname(__FILE__)
Dir.chdir(directory) {
ruby_exe(path)
}.should == path
diff --git a/spec/ruby/core/thread/each_caller_location_spec.rb b/spec/ruby/core/thread/each_caller_location_spec.rb
deleted file mode 100644
index dbece06cd8..0000000000
--- a/spec/ruby/core/thread/each_caller_location_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "Thread.each_caller_location" do
- ruby_version_is "3.2" do
- it "iterates through the current execution stack and matches caller_locations content and type" do
- ScratchPad.record []
- Thread.each_caller_location { |l| ScratchPad << l; }
-
- ScratchPad.recorded.map(&:to_s).should == caller_locations.map(&:to_s)
- ScratchPad.recorded[0].should be_kind_of(Thread::Backtrace::Location)
- end
-
- it "returns subset of 'Thread.to_enum(:each_caller_location)' locations" do
- ar = []
- ecl = Thread.each_caller_location { |x| ar << x }
-
- (ar.map(&:to_s) - Thread.to_enum(:each_caller_location).to_a.map(&:to_s)).should.empty?
- end
-
- it "stops the backtrace iteration if 'break' occurs" do
- i = 0
- ar = []
- ecl = Thread.each_caller_location do |x|
- ar << x
- i += 1
- break x if i == 2
- end
-
- ar.map(&:to_s).should == caller_locations(1, 2).map(&:to_s)
- ecl.should be_kind_of(Thread::Backtrace::Location)
- end
-
- it "returns nil" do
- Thread.each_caller_location {}.should == nil
- end
-
- it "raises LocalJumpError when called without a block" do
- -> {
- Thread.each_caller_location
- }.should raise_error(LocalJumpError, "no block given")
- end
-
- it "doesn't accept positional and keyword arguments" do
- -> {
- Thread.each_caller_location(12, foo: 10) {}
- }.should raise_error(ArgumentError, "wrong number of arguments (given 2, expected 0)")
- end
- end
-end
diff --git a/spec/ruby/core/thread/exclusive_spec.rb b/spec/ruby/core/thread/exclusive_spec.rb
new file mode 100644
index 0000000000..37c4b19d1a
--- /dev/null
+++ b/spec/ruby/core/thread/exclusive_spec.rb
@@ -0,0 +1,49 @@
+require_relative '../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ describe "Thread.exclusive" do
+ before :each do
+ ScratchPad.clear
+ $VERBOSE, @verbose = nil, $VERBOSE
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it "yields to the block" do
+ Thread.exclusive { ScratchPad.record true }
+ ScratchPad.recorded.should == true
+ end
+
+ it "returns the result of yielding" do
+ Thread.exclusive { :result }.should == :result
+ end
+
+ it "blocks the caller if another thread is also in an exclusive block" do
+ m = Mutex.new
+ q1 = Queue.new
+ q2 = Queue.new
+
+ t = Thread.new {
+ Thread.exclusive {
+ q1.push :ready
+ q2.pop
+ }
+ }
+
+ q1.pop.should == :ready
+
+ -> { Thread.exclusive { } }.should block_caller
+
+ q2.push :done
+ t.join
+ end
+
+ it "is not recursive" do
+ Thread.exclusive do
+ -> { Thread.exclusive { } }.should raise_error(ThreadError)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/thread/ignore_deadlock_spec.rb b/spec/ruby/core/thread/ignore_deadlock_spec.rb
index b48bc9f9b0..53cc2a7f5b 100644
--- a/spec/ruby/core/thread/ignore_deadlock_spec.rb
+++ b/spec/ruby/core/thread/ignore_deadlock_spec.rb
@@ -1,19 +1,21 @@
require_relative '../../spec_helper'
-describe "Thread.ignore_deadlock" do
- it "returns false by default" do
- Thread.ignore_deadlock.should == false
+ruby_version_is "3.0" do
+ describe "Thread.ignore_deadlock" do
+ it "returns false by default" do
+ Thread.ignore_deadlock.should == false
+ end
end
-end
-describe "Thread.ignore_deadlock=" do
- it "changes the value of Thread.ignore_deadlock" do
- ignore_deadlock = Thread.ignore_deadlock
- Thread.ignore_deadlock = true
- begin
- Thread.ignore_deadlock.should == true
- ensure
- Thread.ignore_deadlock = ignore_deadlock
+ describe "Thread.ignore_deadlock=" do
+ it "changes the value of Thread.ignore_deadlock" do
+ ignore_deadlock = Thread.ignore_deadlock
+ Thread.ignore_deadlock = true
+ begin
+ Thread.ignore_deadlock.should == true
+ ensure
+ Thread.ignore_deadlock = ignore_deadlock
+ end
end
end
end
diff --git a/spec/ruby/core/thread/kill_spec.rb b/spec/ruby/core/thread/kill_spec.rb
index 4b62c686c7..f932bf5232 100644
--- a/spec/ruby/core/thread/kill_spec.rb
+++ b/spec/ruby/core/thread/kill_spec.rb
@@ -9,6 +9,10 @@ platform_is_not :mingw do
it_behaves_like :thread_exit, :kill
end
+ describe "Thread#kill!" do
+ it "needs to be reviewed for spec completeness"
+ end
+
describe "Thread.kill" do
it "causes the given thread to exit" do
thread = Thread.new { sleep }
diff --git a/spec/ruby/core/thread/native_thread_id_spec.rb b/spec/ruby/core/thread/native_thread_id_spec.rb
index 17a08c8a15..d6cc332bf6 100644
--- a/spec/ruby/core/thread/native_thread_id_spec.rb
+++ b/spec/ruby/core/thread/native_thread_id_spec.rb
@@ -1,37 +1,17 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- platform_is :linux, :darwin, :windows, :freebsd do
- describe "Thread#native_thread_id" do
- it "returns an integer when the thread is alive" do
- Thread.current.native_thread_id.should be_kind_of(Integer)
- end
+if ruby_version_is "3.1" and Thread.method_defined?(:native_thread_id)
+ # This method is very platform specific
- it "returns nil when the thread is not running" do
- t = Thread.new {}
- t.join
- t.native_thread_id.should == nil
- end
-
- it "each thread has different native thread id" do
- t = Thread.new { sleep }
- Thread.pass until t.stop?
- main_thread_id = Thread.current.native_thread_id
- t_thread_id = t.native_thread_id
-
- if ruby_version_is "3.3"
- # native_thread_id can be nil on a M:N scheduler
- t_thread_id.should be_kind_of(Integer) if t_thread_id != nil
- else
- t_thread_id.should be_kind_of(Integer)
- end
-
- main_thread_id.should_not == t_thread_id
+ describe "Thread#native_thread_id" do
+ it "returns an integer when the thread is alive" do
+ Thread.current.native_thread_id.should be_kind_of(Integer)
+ end
- t.run
- t.join
- t.native_thread_id.should == nil
- end
+ it "returns nil when the thread is not running" do
+ t = Thread.new {}
+ t.join
+ t.native_thread_id.should == nil
end
end
end
diff --git a/spec/ruby/core/thread/report_on_exception_spec.rb b/spec/ruby/core/thread/report_on_exception_spec.rb
index ab0af0972e..9279fa1da5 100644
--- a/spec/ruby/core/thread/report_on_exception_spec.rb
+++ b/spec/ruby/core/thread/report_on_exception_spec.rb
@@ -61,32 +61,34 @@ describe "Thread#report_on_exception=" do
}.should raise_error(RuntimeError, "Thread#report_on_exception specs")
end
- it "prints a backtrace on $stderr in the regular backtrace order" do
- line_raise = __LINE__ + 2
- def foo
- raise RuntimeError, "Thread#report_on_exception specs backtrace order"
- end
-
- line_call_foo = __LINE__ + 5
- go = false
- t = Thread.new {
- Thread.current.report_on_exception = true
- Thread.pass until go
- foo
- }
+ ruby_version_is "3.0" do
+ it "prints a backtrace on $stderr in the regular backtrace order" do
+ line_raise = __LINE__ + 2
+ def foo
+ raise RuntimeError, "Thread#report_on_exception specs backtrace order"
+ end
+
+ line_call_foo = __LINE__ + 5
+ go = false
+ t = Thread.new {
+ Thread.current.report_on_exception = true
+ Thread.pass until go
+ foo
+ }
- -> {
- go = true
- Thread.pass while t.alive?
- }.should output("", <<ERR)
+ -> {
+ go = true
+ Thread.pass while t.alive?
+ }.should output("", <<ERR)
#{t.inspect} terminated with exception (report_on_exception is true):
#{__FILE__}:#{line_raise}:in `foo': Thread#report_on_exception specs backtrace order (RuntimeError)
-\tfrom #{__FILE__}:#{line_call_foo}:in `block (4 levels) in <top (required)>'
+\tfrom #{__FILE__}:#{line_call_foo}:in `block (5 levels) in <top (required)>'
ERR
- -> {
- t.join
- }.should raise_error(RuntimeError, "Thread#report_on_exception specs backtrace order")
+ -> {
+ t.join
+ }.should raise_error(RuntimeError, "Thread#report_on_exception specs backtrace order")
+ end
end
it "prints the backtrace even if the thread was killed just after Thread#raise" do
diff --git a/spec/ruby/core/thread/shared/exit.rb b/spec/ruby/core/thread/shared/exit.rb
index 13e8832684..3663827579 100644
--- a/spec/ruby/core/thread/shared/exit.rb
+++ b/spec/ruby/core/thread/shared/exit.rb
@@ -113,25 +113,6 @@ describe :thread_exit, shared: true do
ScratchPad.recorded.should == nil
end
- it "kills other fibers of that thread without running their ensure clauses" do
- t = Thread.new do
- f = Fiber.new do
- ScratchPad.record :fiber_resumed
- begin
- Fiber.yield
- ensure
- ScratchPad.record :fiber_ensure
- end
- end
- f.resume
- sleep
- end
- Thread.pass until t.stop?
- t.send(@method)
- t.join
- ScratchPad.recorded.should == :fiber_resumed
- end
-
# This spec is a mess. It fails randomly, it hangs on MRI, it needs to be removed
quarantine! do
it "killing dying running does nothing" do
diff --git a/spec/ruby/core/time/deconstruct_keys_spec.rb b/spec/ruby/core/time/deconstruct_keys_spec.rb
deleted file mode 100644
index fbb0ec2164..0000000000
--- a/spec/ruby/core/time/deconstruct_keys_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-require_relative '../../spec_helper'
-
-ruby_version_is "3.2" do
- describe "Time#deconstruct_keys" do
- it "returns whole hash for nil as an argument" do
- d = Time.utc(2022, 10, 5, 13, 30)
- res = { year: 2022, month: 10, day: 5, yday: 278, wday: 3, hour: 13,
- min: 30, sec: 0, subsec: 0, dst: false, zone: "UTC" }
- d.deconstruct_keys(nil).should == res
- end
-
- it "returns only specified keys" do
- d = Time.utc(2022, 10, 5, 13, 39)
- d.deconstruct_keys([:zone, :subsec]).should == { zone: "UTC", subsec: 0 }
- end
-
- it "requires one argument" do
- -> {
- Time.new(2022, 10, 5, 13, 30).deconstruct_keys
- }.should raise_error(ArgumentError)
- end
-
- it "it raises error when argument is neither nil nor array" do
- d = Time.new(2022, 10, 5, 13, 30)
-
- -> { d.deconstruct_keys(1) }.should raise_error(TypeError, "wrong argument type Integer (expected Array or nil)")
- -> { d.deconstruct_keys("asd") }.should raise_error(TypeError, "wrong argument type String (expected Array or nil)")
- -> { d.deconstruct_keys(:x) }.should raise_error(TypeError, "wrong argument type Symbol (expected Array or nil)")
- -> { d.deconstruct_keys({}) }.should raise_error(TypeError, "wrong argument type Hash (expected Array or nil)")
- end
-
- it "returns {} when passed []" do
- Time.new(2022, 10, 5, 13, 30).deconstruct_keys([]).should == {}
- end
-
- it "ignores non-Symbol keys" do
- Time.new(2022, 10, 5, 13, 30).deconstruct_keys(['year', []]).should == {}
- end
-
- it "ignores not existing Symbol keys" do
- Time.new(2022, 10, 5, 13, 30).deconstruct_keys([:year, :a]).should == { year: 2022 }
- end
- end
-end
diff --git a/spec/ruby/core/time/new_spec.rb b/spec/ruby/core/time/new_spec.rb
index 18d7396269..727fdf92c2 100644
--- a/spec/ruby/core/time/new_spec.rb
+++ b/spec/ruby/core/time/new_spec.rb
@@ -58,7 +58,7 @@ describe "Time.new with a utc_offset argument" do
Time.new(2000, 1, 1, 0, 0, 0, "-04:10:43").utc_offset.should == -15043
end
- ruby_bug '#13669', ''...'3.1' do
+ ruby_bug '#13669', '3.0'...'3.1' do
it "returns a Time with a UTC offset specified as +HH" do
Time.new(2000, 1, 1, 0, 0, 0, "+05").utc_offset.should == 3600 * 5
end
@@ -200,8 +200,10 @@ describe "Time.new with a timezone argument" do
time.zone.should == zone
time.utc_offset.should == 5*3600+30*60
- time.wday.should == 6
- time.yday.should == 1
+ ruby_version_is "3.0" do
+ time.wday.should == 6
+ time.yday.should == 1
+ end
end
it "accepts timezone argument that must have #local_to_utc and #utc_to_local methods" do
@@ -429,10 +431,6 @@ describe "Time.new with a timezone argument" do
time.zone.should == nil
end
- it "returns a Time with UTC offset specified as a single letter military timezone" do
- Time.new(2000, 1, 1, 0, 0, 0, in: "W").utc_offset.should == 3600 * -10
- end
-
it "could be a timezone object" do
zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
@@ -447,199 +445,13 @@ describe "Time.new with a timezone argument" do
time.zone.should == zone
end
- it "allows omitting minor arguments" do
- Time.new(2000, 1, 1, 12, 1, 1, in: "+05:00").should == Time.new(2000, 1, 1, 12, 1, 1, "+05:00")
- Time.new(2000, 1, 1, 12, 1, in: "+05:00").should == Time.new(2000, 1, 1, 12, 1, 0, "+05:00")
- Time.new(2000, 1, 1, 12, in: "+05:00").should == Time.new(2000, 1, 1, 12, 0, 0, "+05:00")
- Time.new(2000, 1, 1, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
- Time.new(2000, 1, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
- Time.new(2000, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
- Time.new(in: "+05:00").should be_close(Time.now.getlocal("+05:00"), TIME_TOLERANCE)
- end
-
- it "converts to a provided timezone if all the positional arguments are omitted" do
- Time.new(in: "+05:00").utc_offset.should == 5*3600
- end
-
it "raises ArgumentError if format is invalid" do
-> { Time.new(2000, 1, 1, 12, 0, 0, in: "+09:99") }.should raise_error(ArgumentError)
-> { Time.new(2000, 1, 1, 12, 0, 0, in: "ABC") }.should raise_error(ArgumentError)
end
it "raises ArgumentError if two offset arguments are given" do
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, "+05:00", in: "+05:00")
- }.should raise_error(ArgumentError, "timezone argument given as positional and keyword arguments")
- end
- end
- end
-
- ruby_version_is "3.2" do
- describe "Time.new with a String argument" do
- it "parses an ISO-8601 like format" do
- t = Time.utc(2020, 12, 24, 15, 56, 17)
-
- Time.new("2020-12-24T15:56:17Z").should == t
- Time.new("2020-12-25 00:56:17 +09:00").should == t
- Time.new("2020-12-25 00:57:47 +09:01:30").should == t
- Time.new("2020-12-25 00:56:17 +0900").should == t
- Time.new("2020-12-25 00:57:47 +090130").should == t
- Time.new("2020-12-25T00:56:17+09:00").should == t
- end
-
- it "accepts precision keyword argument and truncates specified digits of sub-second part" do
- Time.new("2021-12-25 00:00:00.123456789876 +09:00").subsec.should == 0.123456789r
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: nil).subsec.should == 0.123456789876r
- Time.new("2021-12-25 00:00:00 +09:00", precision: 0).subsec.should == 0
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: -1).subsec.should == 0.123456789876r
- end
-
- it "returns Time in local timezone if not provided in the String argument" do
- Time.new("2021-12-25 00:00:00").zone.should == Time.new(2021, 12, 25).zone
- Time.new("2021-12-25 00:00:00").utc_offset.should == Time.new(2021, 12, 25).utc_offset
- end
-
- it "returns Time in timezone specified in the String argument" do
- Time.new("2021-12-25 00:00:00 +05:00").to_s.should == "2021-12-25 00:00:00 +0500"
- end
-
- it "returns Time in timezone specified in the String argument even if the in keyword argument provided" do
- Time.new("2021-12-25 00:00:00 +09:00", in: "-01:00").to_s.should == "2021-12-25 00:00:00 +0900"
- end
-
- it "returns Time in timezone specified with in keyword argument if timezone isn't provided in the String argument" do
- Time.new("2021-12-25 00:00:00", in: "-01:00").to_s.should == "2021-12-25 00:00:00 -0100"
- end
-
- it "converts precision keyword argument into Integer if is not nil" do
- obj = Object.new
- def obj.to_int; 3; end
-
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: 1.2).subsec.should == 0.1r
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: obj).subsec.should == 0.123r
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: 3r).subsec.should == 0.123r
- end
-
- ruby_version_is ""..."3.3" do
- it "raise TypeError is can't convert precision keyword argument into Integer" do
- -> {
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: "")
- }.should raise_error(TypeError, "no implicit conversion from string")
- end
- end
-
- ruby_version_is "3.3" do
- it "raise TypeError is can't convert precision keyword argument into Integer" do
- -> {
- Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: "")
- }.should raise_error(TypeError, "no implicit conversion of String into Integer")
- end
- end
-
- it "raises ArgumentError if part of time string is missing" do
- -> {
- Time.new("2020-12-25 00:56 +09:00")
- }.should raise_error(ArgumentError, "missing sec part: 00:56 ")
-
- -> {
- Time.new("2020-12-25 00 +09:00")
- }.should raise_error(ArgumentError, "missing min part: 00 ")
- end
-
- it "raises ArgumentError if subsecond is missing after dot" do
- -> {
- Time.new("2020-12-25 00:56:17. +0900")
- }.should raise_error(ArgumentError, "subsecond expected after dot: 00:56:17. ")
- end
-
- it "raises ArgumentError if String argument is not in the supported format" do
- -> {
- Time.new("021-12-25 00:00:00.123456 +09:00")
- }.should raise_error(ArgumentError, "year must be 4 or more digits: 021")
-
- -> {
- Time.new("2020-012-25 00:56:17 +0900")
- }.should raise_error(ArgumentError, "two digits mon is expected after `-': -012-25 00:")
-
- -> {
- Time.new("2020-2-25 00:56:17 +0900")
- }.should raise_error(ArgumentError, "two digits mon is expected after `-': -2-25 00:56")
-
- -> {
- Time.new("2020-12-215 00:56:17 +0900")
- }.should raise_error(ArgumentError, "two digits mday is expected after `-': -215 00:56:")
-
- -> {
- Time.new("2020-12-25 000:56:17 +0900")
- }.should raise_error(ArgumentError, "two digits hour is expected: 000:56:17 ")
-
- -> {
- Time.new("2020-12-25 0:56:17 +0900")
- }.should raise_error(ArgumentError, "two digits hour is expected: 0:56:17 +0")
-
- -> {
- Time.new("2020-12-25 00:516:17 +0900")
- }.should raise_error(ArgumentError, "two digits min is expected after `:': :516:17 +09")
-
- -> {
- Time.new("2020-12-25 00:6:17 +0900")
- }.should raise_error(ArgumentError, "two digits min is expected after `:': :6:17 +0900")
-
- -> {
- Time.new("2020-12-25 00:56:137 +0900")
- }.should raise_error(ArgumentError, "two digits sec is expected after `:': :137 +0900")
-
- -> {
- Time.new("2020-12-25 00:56:7 +0900")
- }.should raise_error(ArgumentError, "two digits sec is expected after `:': :7 +0900")
-
- -> {
- Time.new("2020-12-25 00:56. +0900")
- }.should raise_error(ArgumentError, "fraction min is not supported: 00:56.")
-
- -> {
- Time.new("2020-12-25 00. +0900")
- }.should raise_error(ArgumentError, "fraction hour is not supported: 00.")
- end
-
- it "raises ArgumentError if date/time parts values are not valid" do
- -> {
- Time.new("2020-13-25 00:56:17 +09:00")
- }.should raise_error(ArgumentError, "mon out of range")
-
- -> {
- Time.new("2020-12-32 00:56:17 +09:00")
- }.should raise_error(ArgumentError, "mday out of range")
-
- -> {
- Time.new("2020-12-25 25:56:17 +09:00")
- }.should raise_error(ArgumentError, "hour out of range")
-
- -> {
- Time.new("2020-12-25 00:61:17 +09:00")
- }.should raise_error(ArgumentError, "min out of range")
-
- -> {
- Time.new("2020-12-25 00:56:61 +09:00")
- }.should raise_error(ArgumentError, "sec out of range")
-
- -> {
- Time.new("2020-12-25 00:56:17 +23:59:60")
- }.should raise_error(ArgumentError, "utc_offset out of range")
-
- -> {
- Time.new("2020-12-25 00:56:17 +24:00")
- }.should raise_error(ArgumentError, "utc_offset out of range")
-
- -> {
- Time.new("2020-12-25 00:56:17 +23:61")
- }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +23:61')
- end
-
- it "raises ArgumentError if string has not ascii-compatible encoding" do
- -> {
- Time.new("2021-11-31 00:00:60 +09:00".encode("utf-32le"))
- }.should raise_error(ArgumentError, "time string should have ASCII compatible encoding")
+ -> { Time.new(2000, 1, 1, 12, 0, 0, "+05:00", in: "+05:00") }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/time/now_spec.rb b/spec/ruby/core/time/now_spec.rb
index d47f00723e..2b2e53a17c 100644
--- a/spec/ruby/core/time/now_spec.rb
+++ b/spec/ruby/core/time/now_spec.rb
@@ -4,54 +4,48 @@ require_relative 'shared/now'
describe "Time.now" do
it_behaves_like :time_now, :now
- ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/17485
- describe ":in keyword argument" do
- it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
- time = Time.now(in: "+05:00")
+ describe ":in keyword argument" do
+ it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
+ time = Time.now(in: "+05:00")
- time.utc_offset.should == 5*60*60
- time.zone.should == nil
+ time.utc_offset.should == 5*60*60
+ time.zone.should == nil
- time = Time.now(in: "-09:00")
+ time = Time.now(in: "-09:00")
- time.utc_offset.should == -9*60*60
- time.zone.should == nil
- end
-
- it "could be UTC offset as a number of seconds" do
- time = Time.now(in: 5*60*60)
+ time.utc_offset.should == -9*60*60
+ time.zone.should == nil
+ end
- time.utc_offset.should == 5*60*60
- time.zone.should == nil
+ it "could be UTC offset as a number of seconds" do
+ time = Time.now(in: 5*60*60)
- time = Time.now(in: -9*60*60)
+ time.utc_offset.should == 5*60*60
+ time.zone.should == nil
- time.utc_offset.should == -9*60*60
- time.zone.should == nil
- end
+ time = Time.now(in: -9*60*60)
- it "returns a Time with UTC offset specified as a single letter military timezone" do
- Time.now(in: "W").utc_offset.should == 3600 * -10
- end
+ time.utc_offset.should == -9*60*60
+ time.zone.should == nil
+ end
- it "could be a timezone object" do
- zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
- time = Time.now(in: zone)
+ it "could be a timezone object" do
+ zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
+ time = Time.now(in: zone)
- time.utc_offset.should == 5*3600+30*60
- time.zone.should == zone
+ time.utc_offset.should == 5*3600+30*60
+ time.zone.should == zone
- zone = TimeSpecs::TimezoneWithName.new(name: "PST")
- time = Time.now(in: zone)
+ zone = TimeSpecs::TimezoneWithName.new(name: "PST")
+ time = Time.now(in: zone)
- time.utc_offset.should == -9*60*60
- time.zone.should == zone
- end
+ time.utc_offset.should == -9*60*60
+ time.zone.should == zone
+ end
- it "raises ArgumentError if format is invalid" do
- -> { Time.now(in: "+09:99") }.should raise_error(ArgumentError)
- -> { Time.now(in: "ABC") }.should raise_error(ArgumentError)
- end
+ it "raises ArgumentError if format is invalid" do
+ -> { Time.now(in: "+09:99") }.should raise_error(ArgumentError)
+ -> { Time.now(in: "ABC") }.should raise_error(ArgumentError)
end
end
end
diff --git a/spec/ruby/core/time/succ_spec.rb b/spec/ruby/core/time/succ_spec.rb
new file mode 100644
index 0000000000..e8249059d1
--- /dev/null
+++ b/spec/ruby/core/time/succ_spec.rb
@@ -0,0 +1,39 @@
+ruby_version_is ""..."3.0" do
+ require_relative '../../spec_helper'
+ require_relative 'fixtures/classes'
+
+ describe "Time#succ" do
+ it "returns a new time one second later than time" do
+ suppress_warning {
+ @result = Time.at(100).succ
+ }
+
+ @result.should == Time.at(101)
+ end
+
+ it "returns a new instance" do
+ time = Time.at(100)
+
+ suppress_warning {
+ @result = time.succ
+ }
+
+ @result.should_not equal time
+ end
+
+ it "is obsolete" do
+ -> {
+ Time.at(100).succ
+ }.should complain(/Time#succ is obsolete/)
+ end
+
+ context "zone is a timezone object" do
+ it "preserves time zone" do
+ zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60))
+ time = Time.new(2012, 1, 1, 12, 0, 0, zone) - 1
+
+ time.zone.should == zone
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/time/utc_spec.rb b/spec/ruby/core/time/utc_spec.rb
index 566509fd33..809accc809 100644
--- a/spec/ruby/core/time/utc_spec.rb
+++ b/spec/ruby/core/time/utc_spec.rb
@@ -21,22 +21,12 @@ describe "Time#utc?" do
Time.new(2022, 1, 1, 0, 0, 0, "UTC").utc?.should == true
Time.now.localtime("UTC").utc?.should == true
Time.at(Time.now, in: 'UTC').utc?.should == true
-
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, in: "UTC").utc?.should == true
- Time.now(in: "UTC").utc?.should == true
- end
end
it "does treat time with Z offset as UTC" do
Time.new(2022, 1, 1, 0, 0, 0, "Z").utc?.should == true
Time.now.localtime("Z").utc?.should == true
Time.at(Time.now, in: 'Z').utc?.should == true
-
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, in: "Z").utc?.should == true
- Time.now(in: "Z").utc?.should == true
- end
end
ruby_version_is "3.1" do
diff --git a/spec/ruby/core/time/zone_spec.rb b/spec/ruby/core/time/zone_spec.rb
index 63c92602d1..cbb0977f24 100644
--- a/spec/ruby/core/time/zone_spec.rb
+++ b/spec/ruby/core/time/zone_spec.rb
@@ -74,17 +74,6 @@ describe "Time#zone" do
Time.now.localtime("-00:00").zone.should == "UTC"
Time.at(Time.now, in: '-00:00').zone.should == "UTC"
end
-
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, in: "UTC").zone.should == "UTC"
- Time.new(2022, 1, 1, 0, 0, 0, in: "Z").zone.should == "UTC"
-
- Time.now(in: 'UTC').zone.should == "UTC"
- Time.now(in: 'Z').zone.should == "UTC"
-
- Time.at(Time.now, in: 'UTC').zone.should == "UTC"
- Time.at(Time.now, in: 'Z').zone.should == "UTC"
- end
end
platform_is_not :aix, :windows do
diff --git a/spec/ruby/core/tracepoint/enable_spec.rb b/spec/ruby/core/tracepoint/enable_spec.rb
index 6cc8bb3897..24f6070b97 100644
--- a/spec/ruby/core/tracepoint/enable_spec.rb
+++ b/spec/ruby/core/tracepoint/enable_spec.rb
@@ -149,7 +149,13 @@ describe 'TracePoint#enable' do
describe "when nested" do
before do
- @path_prefix = ' '
+ ruby_version_is ""..."3.0" do
+ @path_prefix = '@'
+ end
+
+ ruby_version_is "3.0" do
+ @path_prefix = ' '
+ end
end
it "enables both TracePoints but only calls the respective callbacks" do
diff --git a/spec/ruby/core/tracepoint/inspect_spec.rb b/spec/ruby/core/tracepoint/inspect_spec.rb
index 21d62e9e26..151a08e7b4 100644
--- a/spec/ruby/core/tracepoint/inspect_spec.rb
+++ b/spec/ruby/core/tracepoint/inspect_spec.rb
@@ -3,7 +3,13 @@ require_relative 'fixtures/classes'
describe 'TracePoint#inspect' do
before do
- @path_prefix = ' '
+ ruby_version_is ""..."3.0" do
+ @path_prefix = '@'
+ end
+
+ ruby_version_is "3.0" do
+ @path_prefix = ' '
+ end
end
it 'returns a string containing a human-readable TracePoint status' do
diff --git a/spec/ruby/core/tracepoint/path_spec.rb b/spec/ruby/core/tracepoint/path_spec.rb
index dc2ca840b8..5b6c6d4cfc 100644
--- a/spec/ruby/core/tracepoint/path_spec.rb
+++ b/spec/ruby/core/tracepoint/path_spec.rb
@@ -13,29 +13,14 @@ describe 'TracePoint#path' do
path.should == "#{__FILE__}"
end
- ruby_version_is ""..."3.3" do
- it 'equals (eval) inside an eval for :end event' do
- path = nil
- TracePoint.new(:end) { |tp|
- next unless TracePointSpec.target_thread?
- path = tp.path
- }.enable do
- eval("module TracePointSpec; end")
- end
- path.should == '(eval)'
- end
- end
-
- ruby_version_is "3.3" do
- it 'equals "(eval at __FILE__:__LINE__)" inside an eval for :end event' do
- path = nil
- TracePoint.new(:end) { |tp|
- next unless TracePointSpec.target_thread?
- path = tp.path
- }.enable do
- eval("module TracePointSpec; end")
- end
- path.should == "(eval at #{__FILE__}:#{__LINE__ - 2})"
+ it 'equals (eval) inside an eval for :end event' do
+ path = nil
+ TracePoint.new(:end) { |tp|
+ next unless TracePointSpec.target_thread?
+ path = tp.path
+ }.enable do
+ eval("module TracePointSpec; end")
end
+ path.should == '(eval)'
end
end
diff --git a/spec/ruby/core/true/singleton_method_spec.rb b/spec/ruby/core/true/singleton_method_spec.rb
deleted file mode 100644
index c06793850f..0000000000
--- a/spec/ruby/core/true/singleton_method_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require_relative '../../spec_helper'
-
-describe "TrueClass#singleton_method" do
- ruby_version_is '3.3' do
- it "raises regardless of whether TrueClass defines the method" do
- -> { true.singleton_method(:foo) }.should raise_error(NameError)
- begin
- def (true).foo; end
- -> { true.singleton_method(:foo) }.should raise_error(NameError)
- ensure
- TrueClass.send(:remove_method, :foo)
- end
- end
- end
-end
diff --git a/spec/ruby/core/unboundmethod/bind_call_spec.rb b/spec/ruby/core/unboundmethod/bind_call_spec.rb
index 80b2095d86..8f25f8bd0d 100644
--- a/spec/ruby/core/unboundmethod/bind_call_spec.rb
+++ b/spec/ruby/core/unboundmethod/bind_call_spec.rb
@@ -7,8 +7,6 @@ describe "UnboundMethod#bind_call" do
@parent_um = UnboundMethodSpecs::Parent.new.method(:foo).unbind
@child1_um = UnboundMethodSpecs::Child1.new.method(:foo).unbind
@child2_um = UnboundMethodSpecs::Child2.new.method(:foo).unbind
- @normal_um_super = UnboundMethodSpecs::Mod.instance_method(:foo_super)
- @parent_um_super = UnboundMethodSpecs::Parent.new.method(:foo_super).unbind
end
it "raises TypeError if object is not kind_of? the Module the method defined in" do
@@ -49,10 +47,4 @@ describe "UnboundMethod#bind_call" do
um = p.method(:singleton_method).unbind
->{ um.bind_call(other) }.should raise_error(TypeError)
end
-
- it "allows calling super for module methods bound to hierarchies that do not already have that module" do
- p = UnboundMethodSpecs::Parent.new
-
- @normal_um_super.bind_call(p).should == true
- end
end
diff --git a/spec/ruby/core/unboundmethod/bind_spec.rb b/spec/ruby/core/unboundmethod/bind_spec.rb
index 7658b664e5..03aaa22e74 100644
--- a/spec/ruby/core/unboundmethod/bind_spec.rb
+++ b/spec/ruby/core/unboundmethod/bind_spec.rb
@@ -7,8 +7,6 @@ describe "UnboundMethod#bind" do
@parent_um = UnboundMethodSpecs::Parent.new.method(:foo).unbind
@child1_um = UnboundMethodSpecs::Child1.new.method(:foo).unbind
@child2_um = UnboundMethodSpecs::Child2.new.method(:foo).unbind
- @normal_um_super = UnboundMethodSpecs::Mod.instance_method(:foo_super)
- @parent_um_super = UnboundMethodSpecs::Parent.new.method(:foo_super).unbind
end
it "raises TypeError if object is not kind_of? the Module the method defined in" do
@@ -60,10 +58,4 @@ describe "UnboundMethod#bind" do
um = p.method(:singleton_method).unbind
->{ um.bind(other) }.should raise_error(TypeError)
end
-
- it "allows calling super for module methods bound to hierarchies that do not already have that module" do
- p = UnboundMethodSpecs::Parent.new
-
- @normal_um_super.bind(p).call.should == true
- end
end
diff --git a/spec/ruby/core/unboundmethod/clone_spec.rb b/spec/ruby/core/unboundmethod/clone_spec.rb
index 1e7fb18744..098ee61476 100644
--- a/spec/ruby/core/unboundmethod/clone_spec.rb
+++ b/spec/ruby/core/unboundmethod/clone_spec.rb
@@ -1,13 +1,12 @@
require_relative '../../spec_helper'
-require_relative 'shared/dup'
+require_relative 'fixtures/classes'
describe "UnboundMethod#clone" do
- it_behaves_like :unboundmethod_dup, :clone
+ it "returns a copy of the UnboundMethod" do
+ um1 = UnboundMethodSpecs::Methods.instance_method(:foo)
+ um2 = um1.clone
- it "preserves frozen status" do
- method = Class.instance_method(:instance_method)
- method.freeze
- method.frozen?.should == true
- method.clone.frozen?.should == true
+ (um1 == um2).should == true
+ um1.bind(UnboundMethodSpecs::Methods.new).call.should == um2.bind(UnboundMethodSpecs::Methods.new).call
end
end
diff --git a/spec/ruby/core/unboundmethod/dup_spec.rb b/spec/ruby/core/unboundmethod/dup_spec.rb
deleted file mode 100644
index 5a78dd8e36..0000000000
--- a/spec/ruby/core/unboundmethod/dup_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/dup'
-
-describe "UnboundMethod#dup" do
- ruby_version_is "3.4" do
- it_behaves_like :unboundmethod_dup, :dup
-
- it "resets frozen status" do
- method = Class.instance_method(:instance_method)
- method.freeze
- method.frozen?.should == true
- method.dup.frozen?.should == false
- end
- end
-end
diff --git a/spec/ruby/core/unboundmethod/fixtures/classes.rb b/spec/ruby/core/unboundmethod/fixtures/classes.rb
index 28d8e0a965..6ab958d447 100644
--- a/spec/ruby/core/unboundmethod/fixtures/classes.rb
+++ b/spec/ruby/core/unboundmethod/fixtures/classes.rb
@@ -22,7 +22,6 @@ module UnboundMethodSpecs
module Mod
def from_mod; end
- def foo_super; super; end
end
class Methods
@@ -64,9 +63,6 @@ module UnboundMethodSpecs
class Parent
def foo; end
- def foo_super
- true
- end
def self.class_method
"I am #{name}"
end
diff --git a/spec/ruby/core/unboundmethod/private_spec.rb b/spec/ruby/core/unboundmethod/private_spec.rb
index 8ea50bb5d4..fa735846bb 100644
--- a/spec/ruby/core/unboundmethod/private_spec.rb
+++ b/spec/ruby/core/unboundmethod/private_spec.rb
@@ -1,8 +1,8 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "UnboundMethod#private?" do
- ruby_version_is "3.1"..."3.2" do
+ruby_version_is "3.1"..."3.2" do
+ describe "UnboundMethod#private?" do
it "returns false when the method is public" do
obj = UnboundMethodSpecs::Methods.new
obj.method(:my_public_method).unbind.private?.should == false
@@ -18,11 +18,4 @@ describe "UnboundMethod#private?" do
obj.method(:my_private_method).unbind.private?.should == true
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- obj = UnboundMethodSpecs::Methods.new
- obj.method(:my_private_method).unbind.should_not.respond_to?(:private?)
- end
- end
end
diff --git a/spec/ruby/core/unboundmethod/protected_spec.rb b/spec/ruby/core/unboundmethod/protected_spec.rb
index 0c215d8638..db00e7ef43 100644
--- a/spec/ruby/core/unboundmethod/protected_spec.rb
+++ b/spec/ruby/core/unboundmethod/protected_spec.rb
@@ -1,8 +1,8 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "UnboundMethod#protected?" do
- ruby_version_is "3.1"..."3.2" do
+ruby_version_is "3.1"..."3.2" do
+ describe "UnboundMethod#protected?" do
it "returns false when the method is public" do
obj = UnboundMethodSpecs::Methods.new
obj.method(:my_public_method).unbind.protected?.should == false
@@ -18,11 +18,4 @@ describe "UnboundMethod#protected?" do
obj.method(:my_private_method).unbind.protected?.should == false
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- obj = UnboundMethodSpecs::Methods.new
- obj.method(:my_protected_method).unbind.should_not.respond_to?(:protected?)
- end
- end
end
diff --git a/spec/ruby/core/unboundmethod/public_spec.rb b/spec/ruby/core/unboundmethod/public_spec.rb
index 552bbf6eab..7b87a03b15 100644
--- a/spec/ruby/core/unboundmethod/public_spec.rb
+++ b/spec/ruby/core/unboundmethod/public_spec.rb
@@ -1,8 +1,8 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "UnboundMethod#public?" do
- ruby_version_is "3.1"..."3.2" do
+ruby_version_is "3.1"..."3.2" do
+ describe "UnboundMethod#public?" do
it "returns true when the method is public" do
obj = UnboundMethodSpecs::Methods.new
obj.method(:my_public_method).unbind.public?.should == true
@@ -18,11 +18,4 @@ describe "UnboundMethod#public?" do
obj.method(:my_private_method).unbind.public?.should == false
end
end
-
- ruby_version_is "3.2" do
- it "has been removed" do
- obj = UnboundMethodSpecs::Methods.new
- obj.method(:my_public_method).unbind.should_not.respond_to?(:public?)
- end
- end
end
diff --git a/spec/ruby/core/unboundmethod/shared/dup.rb b/spec/ruby/core/unboundmethod/shared/dup.rb
deleted file mode 100644
index 943a7faaa3..0000000000
--- a/spec/ruby/core/unboundmethod/shared/dup.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-describe :unboundmethod_dup, shared: true do
- it "returns a copy of self" do
- a = Class.instance_method(:instance_method)
- b = a.send(@method)
-
- a.should == b
- a.should_not equal(b)
- end
-
- ruby_version_is "3.4" do
- it "copies instance variables" do
- method = Class.instance_method(:instance_method)
- method.instance_variable_set(:@ivar, 1)
- cl = method.send(@method)
- cl.instance_variables.should == [:@ivar]
- end
-
- it "copies the finalizer" do
- code = <<-RUBY
- obj = Class.instance_method(:instance_method)
-
- ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized\n" })
-
- obj.clone
-
- exit 0
- RUBY
-
- ruby_exe(code).lines.sort.should == ["finalized\n", "finalized\n"]
- end
- end
-end
diff --git a/spec/ruby/core/unboundmethod/source_location_spec.rb b/spec/ruby/core/unboundmethod/source_location_spec.rb
index 5c2f14362c..96933a5d40 100644
--- a/spec/ruby/core/unboundmethod/source_location_spec.rb
+++ b/spec/ruby/core/unboundmethod/source_location_spec.rb
@@ -9,7 +9,7 @@ describe "UnboundMethod#source_location" do
it "sets the first value to the path of the file in which the method was defined" do
file = @method.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('fixtures/classes.rb', __dir__)
+ file.should == File.realpath('../fixtures/classes.rb', __FILE__)
end
it "sets the last value to an Integer representing the line on which the method was defined" do
@@ -49,11 +49,4 @@ describe "UnboundMethod#source_location" do
method.source_location[0].should =~ /#{__FILE__}/
method.source_location[1].should == line
end
-
- it "works for eval with a given line" do
- c = Class.new do
- eval('def m; end', nil, "foo", 100)
- end
- c.instance_method(:m).source_location.should == ["foo", 100]
- end
end
diff --git a/spec/ruby/core/unboundmethod/super_method_spec.rb b/spec/ruby/core/unboundmethod/super_method_spec.rb
index aa7c129377..101c83b8b3 100644
--- a/spec/ruby/core/unboundmethod/super_method_spec.rb
+++ b/spec/ruby/core/unboundmethod/super_method_spec.rb
@@ -40,10 +40,12 @@ describe "UnboundMethod#super_method" do
end
end
- context "after aliasing an inherited method" do
- it "returns the expected super_method" do
- method = MethodSpecs::InheritedMethods::C.instance_method(:meow)
- method.super_method.owner.should == MethodSpecs::InheritedMethods::A
+ ruby_version_is "2.7.3" do
+ context "after aliasing an inherited method" do
+ it "returns the expected super_method" do
+ method = MethodSpecs::InheritedMethods::C.instance_method(:meow)
+ method.super_method.owner.should == MethodSpecs::InheritedMethods::A
+ end
end
end
end
diff --git a/spec/ruby/core/warning/element_reference_spec.rb b/spec/ruby/core/warning/element_reference_spec.rb
index 8cb4018c20..67728ca0f6 100644
--- a/spec/ruby/core/warning/element_reference_spec.rb
+++ b/spec/ruby/core/warning/element_reference_spec.rb
@@ -1,15 +1,10 @@
require_relative '../../spec_helper'
describe "Warning.[]" do
- it "returns default values for categories :deprecated and :experimental" do
- ruby_exe('p [Warning[:deprecated], Warning[:experimental]]').chomp.should == "[false, true]"
- ruby_exe('p [Warning[:deprecated], Warning[:experimental]]', options: "-w").chomp.should == "[true, true]"
- end
-
- ruby_version_is '3.3' do
- it "returns default values for :performance category" do
- ruby_exe('p Warning[:performance]').chomp.should == "false"
- ruby_exe('p Warning[:performance]', options: "-w").chomp.should == "false"
+ ruby_version_is '2.7.2' do
+ it "returns default values for categories :deprecated and :experimental" do
+ ruby_exe('p Warning[:deprecated]').chomp.should == "false"
+ ruby_exe('p Warning[:experimental]').chomp.should == "true"
end
end
diff --git a/spec/ruby/core/warning/element_set_spec.rb b/spec/ruby/core/warning/element_set_spec.rb
index d59a7d4c9e..d20ee215ad 100644
--- a/spec/ruby/core/warning/element_set_spec.rb
+++ b/spec/ruby/core/warning/element_set_spec.rb
@@ -8,7 +8,13 @@ describe "Warning.[]=" do
describe ":experimental" do
before do
- @src = 'warn "This is experimental warning.", category: :experimental'
+ ruby_version_is ""..."3.0" do
+ @src = 'case [0, 1]; in [a, b]; end'
+ end
+
+ ruby_version_is "3.0" do
+ @src = 'warn "This is experimental warning.", category: :experimental'
+ end
end
it "emits and suppresses warnings for :experimental" do
@@ -17,18 +23,6 @@ describe "Warning.[]=" do
end
end
- ruby_version_is '3.3' do
- it "enables or disables performance warnings" do
- original = Warning[:performance]
- begin
- Warning[:performance] = !original
- Warning[:performance].should == !original
- ensure
- Warning[:performance] = original
- end
- end
- end
-
it "raises for unknown category" do
-> { Warning[:noop] = false }.should raise_error(ArgumentError, /unknown category: noop/)
end
diff --git a/spec/ruby/core/warning/warn_spec.rb b/spec/ruby/core/warning/warn_spec.rb
index 8f96fe9287..5ccff3aa2b 100644
--- a/spec/ruby/core/warning/warn_spec.rb
+++ b/spec/ruby/core/warning/warn_spec.rb
@@ -51,85 +51,40 @@ describe "Warning.warn" do
end
end
- it "is called by Kernel.warn with nil category keyword" do
- Warning.should_receive(:warn).with("Chunky bacon!\n", category: nil)
- verbose = $VERBOSE
- $VERBOSE = false
- begin
- Kernel.warn("Chunky bacon!")
- ensure
- $VERBOSE = verbose
- end
- end
-
- it "is called by Kernel.warn with given category keyword converted to a symbol" do
- Warning.should_receive(:warn).with("Chunky bacon!\n", category: :deprecated)
- verbose = $VERBOSE
- $VERBOSE = false
- begin
- Kernel.warn("Chunky bacon!", category: "deprecated")
- ensure
- $VERBOSE = verbose
- end
- end
-
- it "warns when category is :deprecated and Warning[:deprecated] is true" do
- warn_deprecated = Warning[:deprecated]
- Warning[:deprecated] = true
- begin
- -> {
- Warning.warn("foo", category: :deprecated)
- }.should complain("foo")
- ensure
- Warning[:deprecated] = warn_deprecated
- end
- end
-
- it "warns when category is :experimental and Warning[:experimental] is true" do
- warn_experimental = Warning[:experimental]
- Warning[:experimental] = true
- begin
- -> {
- Warning.warn("foo", category: :experimental)
- }.should complain("foo")
- ensure
- Warning[:experimental] = warn_experimental
+ ruby_version_is '3.0' do
+ it "is called by Kernel.warn with nil category keyword" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n", category: nil)
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!")
+ ensure
+ $VERBOSE = verbose
+ end
end
- end
- it "doesn't print message when category is :deprecated but Warning[:deprecated] is false" do
- warn_deprecated = Warning[:deprecated]
- Warning[:deprecated] = false
- begin
- -> {
- Warning.warn("foo", category: :deprecated)
- }.should_not complain
- ensure
- Warning[:deprecated] = warn_deprecated
+ it "is called by Kernel.warn with given category keyword converted to a symbol" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n", category: :deprecated)
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!", category: "deprecated")
+ ensure
+ $VERBOSE = verbose
+ end
end
end
- it "doesn't print message when category is :experimental but Warning[:experimental] is false" do
- warn_experimental = Warning[:experimental]
- Warning[:experimental] = false
- begin
- -> {
- Warning.warn("foo", category: :experimental)
- }.should_not complain
- ensure
- Warning[:experimental] = warn_experimental
+ ruby_version_is ''...'3.0' do
+ it "is called by Kernel.warn" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n")
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!")
+ ensure
+ $VERBOSE = verbose
+ end
end
end
-
- it "prints the message when VERBOSE is false" do
- -> { Warning.warn("foo") }.should complain("foo")
- end
-
- it "prints the message when VERBOSE is nil" do
- -> { Warning.warn("foo") }.should complain("foo", verbose: nil)
- end
-
- it "prints the message when VERBOSE is true" do
- -> { Warning.warn("foo") }.should complain("foo", verbose: true)
- end
end
diff --git a/spec/ruby/fixtures/code/d/load_fixture.rb.rb b/spec/ruby/fixtures/code/d/load_fixture.rb.rb
deleted file mode 100644
index 7e9217729a..0000000000
--- a/spec/ruby/fixtures/code/d/load_fixture.rb.rb
+++ /dev/null
@@ -1 +0,0 @@
-ScratchPad << :rbrb
diff --git a/spec/ruby/fixtures/constants.rb b/spec/ruby/fixtures/constants.rb
index ffe45fb1f6..47a8e87e56 100644
--- a/spec/ruby/fixtures/constants.rb
+++ b/spec/ruby/fixtures/constants.rb
@@ -44,7 +44,6 @@ module ConstantSpecs
# Included in ParentA
module ModuleB
- LINE = __LINE__ - 1
CS_CONST10 = :const10_9
CS_CONST11 = :const11_2
CS_CONST12 = :const12_1
@@ -88,7 +87,7 @@ module ConstantSpecs
# are run.
class ClassA
- LINE = __LINE__ - 1
+ CS_CLASS_A_LINE = __LINE__ - 1
CS_CONST10 = :const10_10
CS_CONST10_LINE = __LINE__ - 1
CS_CONST16 = :const16
diff --git a/spec/ruby/language/END_spec.rb b/spec/ruby/language/END_spec.rb
index c84f0cc9ac..762a8db0c0 100644
--- a/spec/ruby/language/END_spec.rb
+++ b/spec/ruby/language/END_spec.rb
@@ -1,33 +1,15 @@
require_relative '../spec_helper'
-require_relative '../shared/kernel/at_exit'
describe "The END keyword" do
- it_behaves_like :kernel_at_exit, :END
-
it "runs only once for multiple calls" do
ruby_exe("10.times { END { puts 'foo' }; } ").should == "foo\n"
end
- it "is affected by the toplevel assignment" do
- ruby_exe("foo = 'foo'; END { puts foo }").should == "foo\n"
- end
-
- it "warns when END is used in a method" do
- ruby_exe(<<~ruby, args: "2>&1").should =~ /warning: END in method; use at_exit/
- def foo
- END { }
- end
- ruby
+ it "runs last in a given code unit" do
+ ruby_exe("END { puts 'bar' }; puts'foo'; ").should == "foo\nbar\n"
end
- context "END blocks and at_exit callbacks are mixed" do
- it "runs them all in reverse order of registration" do
- ruby_exe(<<~ruby).should == "at_exit#2\nEND#2\nat_exit#1\nEND#1\n"
- END { puts 'END#1' }
- at_exit { puts 'at_exit#1' }
- END { puts 'END#2' }
- at_exit { puts 'at_exit#2' }
- ruby
- end
+ it "runs multiple ends in LIFO order" do
+ ruby_exe("END { puts 'foo' }; END { puts 'bar' }").should == "bar\nfoo\n"
end
end
diff --git a/spec/ruby/language/alias_spec.rb b/spec/ruby/language/alias_spec.rb
index 61fddb0184..c353390679 100644
--- a/spec/ruby/language/alias_spec.rb
+++ b/spec/ruby/language/alias_spec.rb
@@ -52,15 +52,6 @@ describe "The alias keyword" do
@obj.a.should == 5
end
- it "works with an interpolated symbol with non-literal embedded expression on the left-hand side" do
- @meta.class_eval do
- eval %Q{
- alias :"#{'a' + ''.to_s}" value
- }
- end
- @obj.a.should == 5
- end
-
it "works with a simple symbol on the right-hand side" do
@meta.class_eval do
alias a :value
@@ -89,15 +80,6 @@ describe "The alias keyword" do
@obj.a.should == 5
end
- it "works with an interpolated symbol with non-literal embedded expression on the right-hand side" do
- @meta.class_eval do
- eval %Q{
- alias a :"#{'value' + ''.to_s}"
- }
- end
- @obj.a.should == 5
- end
-
it "adds the new method to the list of methods" do
original_methods = @obj.methods
@meta.class_eval do
@@ -252,7 +234,7 @@ describe "The alias keyword" do
it "on top level defines the alias on Object" do
# because it defines on the default definee / current module
- ruby_exe("def foo; end; alias bla foo; print method(:bla).owner").should == "Object"
+ ruby_exe("def foo; end; alias bla foo; print method(:bla).owner", escape: true).should == "Object"
end
it "raises a NameError when passed a missing name" do
diff --git a/spec/ruby/language/block_spec.rb b/spec/ruby/language/block_spec.rb
index 90329e2f6f..8488b945d5 100644
--- a/spec/ruby/language/block_spec.rb
+++ b/spec/ruby/language/block_spec.rb
@@ -53,62 +53,170 @@ describe "A block yielded a single" do
end
end
- it "assigns elements to mixed argument types" do
- result = m([1, 2, 3, {x: 9}]) { |a, b=5, *c, d, e: 2, **k| [a, b, c, d, e, k] }
- result.should == [1, 2, [3], {x: 9}, 2, {}]
+ ruby_version_is ''..."3.0" do
+ it "assigns elements to mixed argument types" do
+ suppress_keyword_warning do
+ result = m([1, 2, 3, {x: 9}]) { |a, b=5, *c, d, e: 2, **k| [a, b, c, d, e, k] }
+ result.should == [1, 2, [], 3, 2, {x: 9}]
+ end
+ end
+
+ it "assigns symbol keys from a Hash to keyword arguments" do
+ suppress_keyword_warning do
+ result = m(["a" => 1, a: 10]) { |a=nil, **b| [a, b] }
+ result.should == [{"a" => 1}, a: 10]
+ end
+ end
+
+ it "assigns symbol keys from a Hash returned by #to_hash to keyword arguments" do
+ suppress_keyword_warning do
+ obj = mock("coerce block keyword arguments")
+ obj.should_receive(:to_hash).and_return({"a" => 1, b: 2})
+
+ result = m([obj]) { |a=nil, **b| [a, b] }
+ result.should == [{"a" => 1}, b: 2]
+ end
+ end
end
- it "does not treat final Hash as keyword arguments and does not autosplat" do
- result = m(["a" => 1, a: 10]) { |a=nil, **b| [a, b] }
- result.should == [[{"a" => 1, a: 10}], {}]
+ ruby_version_is "3.0" do
+ it "assigns elements to mixed argument types" do
+ result = m([1, 2, 3, {x: 9}]) { |a, b=5, *c, d, e: 2, **k| [a, b, c, d, e, k] }
+ result.should == [1, 2, [3], {x: 9}, 2, {}]
+ end
+
+ it "does not treat final Hash as keyword arguments and does not autosplat" do
+ result = m(["a" => 1, a: 10]) { |a=nil, **b| [a, b] }
+ result.should == [[{"a" => 1, a: 10}], {}]
+ end
+
+ it "does not call #to_hash on final argument to get keyword arguments and does not autosplat" do
+ suppress_keyword_warning do
+ obj = mock("coerce block keyword arguments")
+ obj.should_not_receive(:to_hash)
+
+ result = m([obj]) { |a=nil, **b| [a, b] }
+ result.should == [[obj], {}]
+ end
+ end
end
- it "does not call #to_hash on final argument to get keyword arguments and does not autosplat" do
- suppress_keyword_warning do
+ ruby_version_is ""...'3.0' do
+ it "calls #to_hash on the argument but ignores result when optional argument and keyword argument accepted" do
obj = mock("coerce block keyword arguments")
- obj.should_not_receive(:to_hash)
+ obj.should_receive(:to_hash).and_return({"a" => 1, "b" => 2})
result = m([obj]) { |a=nil, **b| [a, b] }
- result.should == [[obj], {}]
+ result.should == [obj, {}]
end
end
- it "does not call #to_hash on the argument when optional argument and keyword argument accepted and does not autosplat" do
- obj = mock("coerce block keyword arguments")
- obj.should_not_receive(:to_hash)
+ ruby_version_is "3.0" do
+ it "does not call #to_hash on the argument when optional argument and keyword argument accepted and does not autosplat" do
+ obj = mock("coerce block keyword arguments")
+ obj.should_not_receive(:to_hash)
- result = m([obj]) { |a=nil, **b| [a, b] }
- result.should == [[obj], {}]
+ result = m([obj]) { |a=nil, **b| [a, b] }
+ result.should == [[obj], {}]
+ end
end
describe "when non-symbol keys are in a keyword arguments Hash" do
- it "does not separate non-symbol keys and symbol keys and does not autosplat" do
- suppress_keyword_warning do
- result = m(["a" => 10, b: 2]) { |a=nil, **b| [a, b] }
- result.should == [[{"a" => 10, b: 2}], {}]
+ ruby_version_is ""..."3.0" do
+ it "separates non-symbol keys and symbol keys" do
+ suppress_keyword_warning do
+ result = m(["a" => 10, b: 2]) { |a=nil, **b| [a, b] }
+ result.should == [{"a" => 10}, {b: 2}]
+ end
+ end
+ end
+ ruby_version_is "3.0" do
+ it "does not separate non-symbol keys and symbol keys and does not autosplat" do
+ suppress_keyword_warning do
+ result = m(["a" => 10, b: 2]) { |a=nil, **b| [a, b] }
+ result.should == [[{"a" => 10, b: 2}], {}]
+ end
end
end
end
- it "does not treat hashes with string keys as keyword arguments and does not autosplat" do
- result = m(["a" => 10]) { |a = nil, **b| [a, b] }
- result.should == [[{"a" => 10}], {}]
+ ruby_version_is ""..."3.0" do
+ it "does not treat hashes with string keys as keyword arguments" do
+ result = m(["a" => 10]) { |a = nil, **b| [a, b] }
+ result.should == [{"a" => 10}, {}]
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "does not treat hashes with string keys as keyword arguments and does not autosplat" do
+ result = m(["a" => 10]) { |a = nil, **b| [a, b] }
+ result.should == [[{"a" => 10}], {}]
+ end
end
- it "does not call #to_hash on the last element if keyword arguments are present" do
- obj = mock("destructure block keyword arguments")
- obj.should_not_receive(:to_hash)
+ ruby_version_is ''...'3.0' do
+ it "calls #to_hash on the last element if keyword arguments are present" do
+ suppress_keyword_warning do
+ obj = mock("destructure block keyword arguments")
+ obj.should_receive(:to_hash).and_return({x: 9})
- result = m([1, 2, 3, obj]) { |a, *b, c, **k| [a, b, c, k] }
- result.should == [1, [2, 3], obj, {}]
+ result = m([1, 2, 3, obj]) { |a, *b, c, **k| [a, b, c, k] }
+ result.should == [1, [2], 3, {x: 9}]
+ end
+ end
+
+ it "assigns the last element to a non-keyword argument if #to_hash returns nil" do
+ suppress_keyword_warning do
+ obj = mock("destructure block keyword arguments")
+ obj.should_receive(:to_hash).and_return(nil)
+
+ result = m([1, 2, 3, obj]) { |a, *b, c, **k| [a, b, c, k] }
+ result.should == [1, [2, 3], obj, {}]
+ end
+ end
+
+ it "calls #to_hash on the last element when there are more arguments than parameters" do
+ suppress_keyword_warning do
+ x = mock("destructure matching block keyword argument")
+ x.should_receive(:to_hash).and_return({x: 9})
+
+ result = m([1, 2, 3, {y: 9}, 4, 5, x]) { |a, b=5, c, **k| [a, b, c, k] }
+ result.should == [1, 2, 3, {x: 9}]
+ end
+ end
+
+ it "raises a TypeError if #to_hash does not return a Hash" do
+ obj = mock("destructure block keyword arguments")
+ obj.should_receive(:to_hash).and_return(1)
+
+ -> { m([1, 2, 3, obj]) { |a, *b, c, **k| } }.should raise_error(TypeError)
+ end
+
+ it "raises the error raised inside #to_hash" do
+ obj = mock("destructure block keyword arguments")
+ error = RuntimeError.new("error while converting to a hash")
+ obj.should_receive(:to_hash).and_raise(error)
+
+ -> { m([1, 2, 3, obj]) { |a, *b, c, **k| } }.should raise_error(error)
+ end
end
- it "does not call #to_hash on the last element when there are more arguments than parameters" do
- x = mock("destructure matching block keyword argument")
- x.should_not_receive(:to_hash)
+ ruby_version_is '3.0' do
+ it "does not call #to_hash on the last element if keyword arguments are present" do
+ obj = mock("destructure block keyword arguments")
+ obj.should_not_receive(:to_hash)
- result = m([1, 2, 3, {y: 9}, 4, 5, x]) { |a, b=5, c, **k| [a, b, c, k] }
- result.should == [1, 2, 3, {}]
+ result = m([1, 2, 3, obj]) { |a, *b, c, **k| [a, b, c, k] }
+ result.should == [1, [2, 3], obj, {}]
+ end
+
+ it "does not call #to_hash on the last element when there are more arguments than parameters" do
+ x = mock("destructure matching block keyword argument")
+ x.should_not_receive(:to_hash)
+
+ result = m([1, 2, 3, {y: 9}, 4, 5, x]) { |a, b=5, c, **k| [a, b, c, k] }
+ result.should == [1, 2, 3, {}]
+ end
end
it "does not call #to_ary on the Array" do
diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb
index 1a3925c9c6..915c032a71 100644
--- a/spec/ruby/language/case_spec.rb
+++ b/spec/ruby/language/case_spec.rb
@@ -329,6 +329,49 @@ describe "The 'case'-construct" do
100
end.should == 100
end
+end
+
+describe "The 'case'-construct with no target expression" do
+ it "evaluates the body of the first clause when at least one of its condition expressions is true" do
+ case
+ when true, false; 'foo'
+ end.should == 'foo'
+ end
+
+ it "evaluates the body of the first when clause that is not false/nil" do
+ case
+ when false; 'foo'
+ when 2; 'bar'
+ when 1 == 1; 'baz'
+ end.should == 'bar'
+
+ case
+ when false; 'foo'
+ when nil; 'foo'
+ when 1 == 1; 'bar'
+ end.should == 'bar'
+ end
+
+ it "evaluates the body of the else clause if all when clauses are false/nil" do
+ case
+ when false; 'foo'
+ when nil; 'foo'
+ when 1 == 2; 'bar'
+ else 'baz'
+ end.should == 'baz'
+ end
+
+ it "evaluates multiple conditional expressions as a boolean disjunction" do
+ case
+ when true, false; 'foo'
+ else 'bar'
+ end.should == 'foo'
+
+ case
+ when false, true; 'foo'
+ else 'bar'
+ end.should == 'foo'
+ end
it "evaluates true as only 'true' when true is the first clause" do
case 1
@@ -391,58 +434,6 @@ describe "The 'case'-construct" do
end.should == :called
end
- it "only matches last value in complex expressions within ()" do
- case 'a'
- when ('a'; 'b')
- :wrong_called
- when ('b'; 'a')
- :called
- end.should == :called
- end
-end
-
-describe "The 'case'-construct with no target expression" do
- it "evaluates the body of the first clause when at least one of its condition expressions is true" do
- case
- when true, false; 'foo'
- end.should == 'foo'
- end
-
- it "evaluates the body of the first when clause that is not false/nil" do
- case
- when false; 'foo'
- when 2; 'bar'
- when 1 == 1; 'baz'
- end.should == 'bar'
-
- case
- when false; 'foo'
- when nil; 'foo'
- when 1 == 1; 'bar'
- end.should == 'bar'
- end
-
- it "evaluates the body of the else clause if all when clauses are false/nil" do
- case
- when false; 'foo'
- when nil; 'foo'
- when 1 == 2; 'bar'
- else 'baz'
- end.should == 'baz'
- end
-
- it "evaluates multiple conditional expressions as a boolean disjunction" do
- case
- when true, false; 'foo'
- else 'bar'
- end.should == 'foo'
-
- case
- when false, true; 'foo'
- else 'bar'
- end.should == 'foo'
- end
-
# Homogeneous cases are often optimized to avoid === using a jump table, and should be tested separately.
# See https://github.com/jruby/jruby/issues/6440
it "handles homogeneous cases" do
@@ -451,13 +442,4 @@ describe "The 'case'-construct with no target expression" do
when 2; 'bar'
end.should == 'foo'
end
-
- it "expands arrays to lists of values" do
- case
- when *[false]
- "foo"
- when *[true]
- "bar"
- end.should == "bar"
- end
end
diff --git a/spec/ruby/language/class_spec.rb b/spec/ruby/language/class_spec.rb
index eab3cd0651..877895bf15 100644
--- a/spec/ruby/language/class_spec.rb
+++ b/spec/ruby/language/class_spec.rb
@@ -308,10 +308,20 @@ describe "A class definition extending an object (sclass)" do
-> { class TestClass < BasicObject.new; end }.should raise_error(TypeError, error_msg)
end
- it "does not allow accessing the block of the original scope" do
- -> {
- ClassSpecs.sclass_with_block { 123 }
- }.should raise_error(SyntaxError)
+ ruby_version_is ""..."3.0" do
+ it "allows accessing the block of the original scope" do
+ suppress_warning do
+ ClassSpecs.sclass_with_block { 123 }.should == 123
+ end
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "does not allow accessing the block of the original scope" do
+ -> {
+ ClassSpecs.sclass_with_block { 123 }
+ }.should raise_error(SyntaxError)
+ end
end
it "can use return to cause the enclosing method to return" do
diff --git a/spec/ruby/language/class_variable_spec.rb b/spec/ruby/language/class_variable_spec.rb
index a26a3fb8de..f98deaa081 100644
--- a/spec/ruby/language/class_variable_spec.rb
+++ b/spec/ruby/language/class_variable_spec.rb
@@ -83,32 +83,34 @@ describe 'A class variable definition' do
end
end
-describe 'Accessing a class variable' do
- it "raises a RuntimeError when accessed from the toplevel scope (not in some module or class)" do
- -> {
- eval "@@cvar_toplevel1"
- }.should raise_error(RuntimeError, 'class variable access from toplevel')
- -> {
- eval "@@cvar_toplevel2 = 2"
- }.should raise_error(RuntimeError, 'class variable access from toplevel')
- end
-
- it "does not raise an error when checking if defined from the toplevel scope" do
- -> {
- eval "defined?(@@cvar_toplevel1)"
- }.should_not raise_error
- end
-
- it "raises a RuntimeError when a class variable is overtaken in an ancestor class" do
- parent = Class.new()
- subclass = Class.new(parent)
- subclass.class_variable_set(:@@cvar_overtaken, :subclass)
- parent.class_variable_set(:@@cvar_overtaken, :parent)
-
- -> {
- subclass.class_variable_get(:@@cvar_overtaken)
- }.should raise_error(RuntimeError, /class variable @@cvar_overtaken of .+ is overtaken by .+/)
-
- parent.class_variable_get(:@@cvar_overtaken).should == :parent
+ruby_version_is "3.0" do
+ describe 'Accessing a class variable' do
+ it "raises a RuntimeError when accessed from the toplevel scope (not in some module or class)" do
+ -> {
+ eval "@@cvar_toplevel1"
+ }.should raise_error(RuntimeError, 'class variable access from toplevel')
+ -> {
+ eval "@@cvar_toplevel2 = 2"
+ }.should raise_error(RuntimeError, 'class variable access from toplevel')
+ end
+
+ it "does not raise an error when checking if defined from the toplevel scope" do
+ -> {
+ eval "defined?(@@cvar_toplevel1)"
+ }.should_not raise_error
+ end
+
+ it "raises a RuntimeError when a class variable is overtaken in an ancestor class" do
+ parent = Class.new()
+ subclass = Class.new(parent)
+ subclass.class_variable_set(:@@cvar_overtaken, :subclass)
+ parent.class_variable_set(:@@cvar_overtaken, :parent)
+
+ -> {
+ subclass.class_variable_get(:@@cvar_overtaken)
+ }.should raise_error(RuntimeError, /class variable @@cvar_overtaken of .+ is overtaken by .+/)
+
+ parent.class_variable_get(:@@cvar_overtaken).should == :parent
+ end
end
end
diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb
index 08c534487e..8586e46158 100644
--- a/spec/ruby/language/constants_spec.rb
+++ b/spec/ruby/language/constants_spec.rb
@@ -170,32 +170,34 @@ describe "Literal (A::X) constant resolution" do
-> { ConstantSpecs::ParentA::CS_CONSTX }.should raise_error(NameError)
end
- it "uses the module or class #name to craft the error message" do
- mod = Module.new do
- def self.name
- "ModuleName"
- end
+ ruby_version_is "3.0" do
+ it "uses the module or class #name to craft the error message" do
+ mod = Module.new do
+ def self.name
+ "ModuleName"
+ end
- def self.inspect
- "<unusable info>"
+ def self.inspect
+ "<unusable info>"
+ end
end
+
+ -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant ModuleName::DOES_NOT_EXIST/)
end
- -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant ModuleName::DOES_NOT_EXIST/)
- end
+ it "uses the module or class #inspect to craft the error message if they are anonymous" do
+ mod = Module.new do
+ def self.name
+ nil
+ end
- it "uses the module or class #inspect to craft the error message if they are anonymous" do
- mod = Module.new do
- def self.name
- nil
+ def self.inspect
+ "<unusable info>"
+ end
end
- def self.inspect
- "<unusable info>"
- end
+ -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant <unusable info>::DOES_NOT_EXIST/)
end
-
- -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant <unusable info>::DOES_NOT_EXIST/)
end
it "sends #const_missing to the original class or module scope" do
diff --git a/spec/ruby/language/defined_spec.rb b/spec/ruby/language/defined_spec.rb
index b84fe9394a..ae2bf45bda 100644
--- a/spec/ruby/language/defined_spec.rb
+++ b/spec/ruby/language/defined_spec.rb
@@ -180,32 +180,6 @@ describe "The defined? keyword when called with a method name" do
ScratchPad.recorded.should == :defined_specs_fixnum_method
end
end
-
- describe "having a throw in the receiver" do
- it "escapes defined? and performs the throw semantics as normal" do
- defined_returned = false
- catch(:out) {
- # NOTE: defined? behaves differently if it is called in a void context, see below
- defined?(throw(:out, 42).foo).should == :unreachable
- defined_returned = true
- }.should == 42
- defined_returned.should == false
- end
- end
-
- describe "in a void context" do
- it "does not execute the receiver" do
- ScratchPad.record :not_executed
- defined?(DefinedSpecs.side_effects / 2)
- ScratchPad.recorded.should == :not_executed
- end
-
- it "warns about the void context when parsing it" do
- -> {
- eval "defined?(DefinedSpecs.side_effects / 2); 42"
- }.should complain(/warning: possibly useless use of defined\? in void context/, verbose: true)
- end
- end
end
describe "The defined? keyword for an expression" do
diff --git a/spec/ruby/language/delegation_spec.rb b/spec/ruby/language/delegation_spec.rb
index 020787aff6..3f24a79d5c 100644
--- a/spec/ruby/language/delegation_spec.rb
+++ b/spec/ruby/language/delegation_spec.rb
@@ -38,26 +38,28 @@ describe "delegation with def(...)" do
end
end
-describe "delegation with def(x, ...)" do
- it "delegates rest and kwargs" do
- a = Class.new(DelegationSpecs::Target)
- a.class_eval(<<-RUBY)
- def delegate(x, ...)
- target(...)
- end
- RUBY
+ruby_version_is "2.7.3" do
+ describe "delegation with def(x, ...)" do
+ it "delegates rest and kwargs" do
+ a = Class.new(DelegationSpecs::Target)
+ a.class_eval(<<-RUBY)
+ def delegate(x, ...)
+ target(...)
+ end
+ RUBY
- a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}]
- end
+ a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}]
+ end
- it "delegates block" do
- a = Class.new(DelegationSpecs::Target)
- a.class_eval(<<-RUBY)
- def delegate_block(x, ...)
- target_block(...)
- end
- RUBY
+ it "delegates block" do
+ a = Class.new(DelegationSpecs::Target)
+ a.class_eval(<<-RUBY)
+ def delegate_block(x, ...)
+ target_block(...)
+ end
+ RUBY
- a.new.delegate_block(0, 1, b: 2) { |x| x }.should == [{b: 2}, [1]]
+ a.new.delegate_block(0, 1, b: 2) { |x| x }.should == [{b: 2}, [1]]
+ end
end
end
diff --git a/spec/ruby/language/file_spec.rb b/spec/ruby/language/file_spec.rb
index 59563d9642..136b262d07 100644
--- a/spec/ruby/language/file_spec.rb
+++ b/spec/ruby/language/file_spec.rb
@@ -7,16 +7,8 @@ describe "The __FILE__ pseudo-variable" do
-> { eval("__FILE__ = 1") }.should raise_error(SyntaxError)
end
- ruby_version_is ""..."3.3" do
- it "equals (eval) inside an eval" do
- eval("__FILE__").should == "(eval)"
- end
- end
-
- ruby_version_is "3.3" do
- it "equals (eval at __FILE__:__LINE__) inside an eval" do
- eval("__FILE__").should == "(eval at #{__FILE__}:#{__LINE__})"
- end
+ it "equals (eval) inside an eval" do
+ eval("__FILE__").should == "(eval)"
end
end
diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb
index f72a32e879..d0558a2251 100644
--- a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb
+++ b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb
Binary files differ
diff --git a/spec/ruby/language/fixtures/super.rb b/spec/ruby/language/fixtures/super.rb
index 94a2a91be0..218f1e4970 100644
--- a/spec/ruby/language/fixtures/super.rb
+++ b/spec/ruby/language/fixtures/super.rb
@@ -556,20 +556,6 @@ module SuperSpecs
end
end
- module ZSuperInBlock
- class A
- def m(arg:)
- arg
- end
- end
-
- class B < A
- def m(arg:)
- proc { super }.call
- end
- end
- end
-
module Keywords
class Arguments
def foo(**args)
diff --git a/spec/ruby/language/fixtures/variables.rb b/spec/ruby/language/fixtures/variables.rb
index 527caa7a78..07265dbb2b 100644
--- a/spec/ruby/language/fixtures/variables.rb
+++ b/spec/ruby/language/fixtures/variables.rb
@@ -82,76 +82,4 @@ module VariablesSpecs
def self.false
false
end
-
- class EvalOrder
- attr_reader :order
-
- def initialize
- @order = []
- end
-
- def reset
- @order = []
- end
-
- def foo
- self << "foo"
- FooClass.new(self)
- end
-
- def bar
- self << "bar"
- BarClass.new(self)
- end
-
- def a
- self << "a"
- end
-
- def b
- self << "b"
- end
-
- def node
- self << "node"
-
- node = Node.new
- node.left = Node.new
- node.left.right = Node.new
-
- node
- end
-
- def <<(value)
- order << value
- end
-
- class FooClass
- attr_reader :evaluator
-
- def initialize(evaluator)
- @evaluator = evaluator
- end
-
- def []=(_index, _value)
- evaluator << "foo[]="
- end
- end
-
- class BarClass
- attr_reader :evaluator
-
- def initialize(evaluator)
- @evaluator = evaluator
- end
-
- def baz=(_value)
- evaluator << "bar.baz="
- end
- end
-
- class Node
- attr_accessor :left, :right
- end
- end
end
diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb
index 1a5b5d0a71..c84564d3ea 100644
--- a/spec/ruby/language/hash_spec.rb
+++ b/spec/ruby/language/hash_spec.rb
@@ -127,24 +127,11 @@ describe "Hash literal" do
{a: 1, **h, c: 4}.should == {a: 1, b: 2, c: 4}
end
- it "expands an '**{}' or '**obj' element with the last key/value pair taking precedence" do
+ it "expands an '**{}' element with the last key/value pair taking precedence" do
-> {
@h = eval "{a: 1, **{a: 2, b: 3, c: 1}, c: 3}"
}.should complain(/key :a is duplicated|duplicated key/)
@h.should == {a: 2, b: 3, c: 3}
-
- -> {
- h = {a: 2, b: 3, c: 1}
- @h = eval "{a: 1, **h, c: 3}"
- }.should_not complain
- @h.should == {a: 2, b: 3, c: 3}
- end
-
- it "expands an '**{}' and warns when finding an additional duplicate key afterwards" do
- -> {
- @h = eval "{d: 1, **{a: 2, b: 3, c: 1}, c: 3}"
- }.should complain(/key :c is duplicated|duplicated key/)
- @h.should == {a: 2, b: 3, c: 3, d: 1}
end
it "merges multiple nested '**obj' in Hash literals" do
@@ -190,24 +177,6 @@ describe "Hash literal" do
utf8_hash.keys.first.should == usascii_hash.keys.first
usascii_hash.keys.first.encoding.should == Encoding::US_ASCII
end
-
- ruby_bug "#20280", ""..."3.3" do
- it "raises a SyntaxError at parse time when Symbol key with invalid bytes" do
- ScratchPad.record []
- -> {
- eval 'ScratchPad << 1; {:"\xC3" => 1}'
- }.should raise_error(SyntaxError, /invalid symbol/)
- ScratchPad.recorded.should == []
- end
-
- it "raises a SyntaxError at parse time when Symbol key with invalid bytes and 'key: value' syntax used" do
- ScratchPad.record []
- -> {
- eval 'ScratchPad << 1; {"\xC3": 1}'
- }.should raise_error(SyntaxError, /invalid symbol/)
- ScratchPad.recorded.should == []
- end
- end
end
describe "The ** operator" do
@@ -222,8 +191,8 @@ describe "The ** operator" do
h.should == { one: 1, two: 2 }
end
- ruby_bug "#20012", ""..."3.3" do
- it "makes a copy when calling a method taking a positional Hash" do
+ ruby_version_is ""..."3.0" do
+ it "makes a caller-side copy when calling a method taking a positional Hash" do
def m(h)
h.delete(:one); h
end
@@ -235,6 +204,19 @@ describe "The ** operator" do
end
end
+ ruby_version_is "3.0" do
+ it "does not copy when calling a method taking a positional Hash" do
+ def m(h)
+ h.delete(:one); h
+ end
+
+ h = { one: 1, two: 2 }
+ m(**h).should == { two: 2 }
+ m(**h).should.equal?(h)
+ h.should == { two: 2 }
+ end
+ end
+
ruby_version_is "3.1" do
describe "hash with omitted value" do
it "accepts short notation 'key' for 'key: value' syntax" do
diff --git a/spec/ruby/language/if_spec.rb b/spec/ruby/language/if_spec.rb
index a5da696000..d1d95c1607 100644
--- a/spec/ruby/language/if_spec.rb
+++ b/spec/ruby/language/if_spec.rb
@@ -306,49 +306,6 @@ describe "The if expression" do
ScratchPad.recorded.should == [4, 5, 4, 5]
end
end
-
- describe "when a branch syntactically does not return a value" do
- it "raises SyntaxError if both do not return a value" do
- -> {
- eval <<~RUBY
- def m
- a = if rand
- return
- else
- return
- end
- a
- end
- RUBY
- }.should raise_error(SyntaxError, /void value expression/)
- end
-
- it "does not raise SyntaxError if one branch returns a value" do
- eval(<<~RUBY).should == 1
- def m
- a = if false # using false to make it clear that's not checked for
- 42
- else
- return 1
- end
- a
- end
- m
- RUBY
-
- eval(<<~RUBY).should == 1
- def m
- a = if true # using true to make it clear that's not checked for
- return 1
- else
- 42
- end
- a
- end
- m
- RUBY
- end
- end
end
describe "The postfix if form" do
diff --git a/spec/ruby/language/keyword_arguments_spec.rb b/spec/ruby/language/keyword_arguments_spec.rb
index ffb5b1fab0..c47b7b0ae9 100644
--- a/spec/ruby/language/keyword_arguments_spec.rb
+++ b/spec/ruby/language/keyword_arguments_spec.rb
@@ -1,353 +1,316 @@
require_relative '../spec_helper'
-describe "Keyword arguments" do
- def target(*args, **kwargs)
- [args, kwargs]
- end
-
- it "are separated from positional arguments" do
- def m(*args, **kwargs)
+ruby_version_is "3.0" do
+ describe "Keyword arguments" do
+ def target(*args, **kwargs)
[args, kwargs]
end
- empty = {}
- m(**empty).should == [[], {}]
- m(empty).should == [[{}], {}]
+ it "are separated from positional arguments" do
+ def m(*args, **kwargs)
+ [args, kwargs]
+ end
- m(a: 1).should == [[], {a: 1}]
- m({a: 1}).should == [[{a: 1}], {}]
- end
+ empty = {}
+ m(**empty).should == [[], {}]
+ m(empty).should == [[{}], {}]
- it "when the receiving method has not keyword parameters it treats kwargs as positional" do
- def m(*a)
- a
+ m(a: 1).should == [[], {a: 1}]
+ m({a: 1}).should == [[{a: 1}], {}]
end
- m(a: 1).should == [{a: 1}]
- m({a: 1}).should == [{a: 1}]
- end
-
- context "empty kwargs are treated as if they were not passed" do
- it "when calling a method" do
+ it "when the receiving method has not keyword parameters it treats kwargs as positional" do
def m(*a)
a
end
- empty = {}
- m(**empty).should == []
- m(empty).should == [{}]
+ m(a: 1).should == [{a: 1}]
+ m({a: 1}).should == [{a: 1}]
end
- it "when yielding to a block" do
- def y(*args, **kwargs)
- yield(*args, **kwargs)
+ context "empty kwargs are treated as if they were not passed" do
+ it "when calling a method" do
+ def m(*a)
+ a
+ end
+
+ empty = {}
+ m(**empty).should == []
+ m(empty).should == [{}]
end
- empty = {}
- y(**empty) { |*a| a }.should == []
- y(empty) { |*a| a }.should == [{}]
- end
- end
+ it "when yielding to a block" do
+ def y(*args, **kwargs)
+ yield(*args, **kwargs)
+ end
- it "extra keywords are not allowed without **kwrest" do
- def m(*a, kw:)
- a
+ empty = {}
+ y(**empty) { |*a| a }.should == []
+ y(empty) { |*a| a }.should == [{}]
+ end
end
- m(kw: 1).should == []
- -> { m(kw: 1, kw2: 2) }.should raise_error(ArgumentError, 'unknown keyword: :kw2')
- -> { m(kw: 1, true => false) }.should raise_error(ArgumentError, 'unknown keyword: true')
- -> { m(kw: 1, a: 1, b: 2, c: 3) }.should raise_error(ArgumentError, 'unknown keywords: :a, :b, :c')
- end
+ it "extra keywords are not allowed without **kwrest" do
+ def m(*a, kw:)
+ a
+ end
- it "raises ArgumentError exception when required keyword argument is not passed" do
- def m(a:, b:, c:)
- [a, b, c]
+ m(kw: 1).should == []
+ -> { m(kw: 1, kw2: 2) }.should raise_error(ArgumentError, 'unknown keyword: :kw2')
+ -> { m(kw: 1, true => false) }.should raise_error(ArgumentError, 'unknown keyword: true')
+ -> { m(kw: 1, a: 1, b: 2, c: 3) }.should raise_error(ArgumentError, 'unknown keywords: :a, :b, :c')
end
- -> { m(a: 1, b: 2) }.should raise_error(ArgumentError, /missing keyword: :c/)
- -> { m() }.should raise_error(ArgumentError, /missing keywords: :a, :b, :c/)
- end
+ it "raises ArgumentError exception when required keyword argument is not passed" do
+ def m(a:, b:, c:)
+ [a, b, c]
+ end
- it "raises ArgumentError for missing keyword arguments even if there are extra ones" do
- def m(a:)
- a
+ -> { m(a: 1, b: 2) }.should raise_error(ArgumentError, /missing keyword: :c/)
+ -> { m() }.should raise_error(ArgumentError, /missing keywords: :a, :b, :c/)
end
- -> { m(b: 1) }.should raise_error(ArgumentError, /missing keyword: :a/)
- end
+ it "raises ArgumentError for missing keyword arguments even if there are extra ones" do
+ def m(a:)
+ a
+ end
- it "handle * and ** at the same call site" do
- def m(*a)
- a
+ -> { m(b: 1) }.should raise_error(ArgumentError, /missing keyword: :a/)
end
- m(*[], **{}).should == []
- m(*[], 42, **{}).should == [42]
- end
+ it "handle * and ** at the same call site" do
+ def m(*a)
+ a
+ end
- context "**" do
- ruby_version_is "3.3" do
- it "copies a non-empty Hash for a method taking (*args)" do
+ m(*[], **{}).should == []
+ m(*[], 42, **{}).should == [42]
+ end
+
+ context "**" do
+ it "does not copy a non-empty Hash for a method taking (*args)" do
def m(*args)
args[0]
end
h = {a: 1}
- m(**h).should_not.equal?(h)
- h.should == {a: 1}
+ m(**h).should.equal?(h)
end
- end
- it "copies the given Hash for a method taking (**kwargs)" do
- def m(**kw)
- kw
- end
-
- empty = {}
- m(**empty).should == empty
- m(**empty).should_not.equal?(empty)
+ it "copies the given Hash for a method taking (**kwargs)" do
+ def m(**kw)
+ kw
+ end
- h = {a: 1}
- m(**h).should == h
- m(**h).should_not.equal?(h)
- end
- end
+ empty = {}
+ m(**empty).should == empty
+ m(**empty).should_not.equal?(empty)
- context "delegation" do
- it "works with (*args, **kwargs)" do
- def m(*args, **kwargs)
- target(*args, **kwargs)
+ h = {a: 1}
+ m(**h).should == h
+ m(**h).should_not.equal?(h)
end
+ end
- empty = {}
- m(**empty).should == [[], {}]
- m(empty).should == [[{}], {}]
+ context "delegation" do
+ it "works with (*args, **kwargs)" do
+ def m(*args, **kwargs)
+ target(*args, **kwargs)
+ end
- m(a: 1).should == [[], {a: 1}]
- m({a: 1}).should == [[{a: 1}], {}]
- end
+ empty = {}
+ m(**empty).should == [[], {}]
+ m(empty).should == [[{}], {}]
- it "works with proc { |*args, **kwargs| }" do
- m = proc do |*args, **kwargs|
- target(*args, **kwargs)
+ m(a: 1).should == [[], {a: 1}]
+ m({a: 1}).should == [[{a: 1}], {}]
end
- empty = {}
- m.(**empty).should == [[], {}]
- m.(empty).should == [[{}], {}]
+ it "works with proc { |*args, **kwargs| }" do
+ m = proc do |*args, **kwargs|
+ target(*args, **kwargs)
+ end
- m.(a: 1).should == [[], {a: 1}]
- m.({a: 1}).should == [[{a: 1}], {}]
+ empty = {}
+ m.(**empty).should == [[], {}]
+ m.(empty).should == [[{}], {}]
- # no autosplatting for |*args, **kwargs|
- m.([1, 2]).should == [[[1, 2]], {}]
- end
+ m.(a: 1).should == [[], {a: 1}]
+ m.({a: 1}).should == [[{a: 1}], {}]
- it "works with -> (*args, **kwargs) {}" do
- m = -> *args, **kwargs do
- target(*args, **kwargs)
+ # no autosplatting for |*args, **kwargs|
+ m.([1, 2]).should == [[[1, 2]], {}]
end
- empty = {}
- m.(**empty).should == [[], {}]
- m.(empty).should == [[{}], {}]
+ it "works with -> (*args, **kwargs) {}" do
+ m = -> *args, **kwargs do
+ target(*args, **kwargs)
+ end
- m.(a: 1).should == [[], {a: 1}]
- m.({a: 1}).should == [[{a: 1}], {}]
- end
+ empty = {}
+ m.(**empty).should == [[], {}]
+ m.(empty).should == [[{}], {}]
- it "works with (...)" do
- instance_eval <<~DEF
- def m(...)
- target(...)
+ m.(a: 1).should == [[], {a: 1}]
+ m.({a: 1}).should == [[{a: 1}], {}]
end
- DEF
- empty = {}
- m(**empty).should == [[], {}]
- m(empty).should == [[{}], {}]
+ it "works with (...)" do
+ instance_eval <<~DEF
+ def m(...)
+ target(...)
+ end
+ DEF
- m(a: 1).should == [[], {a: 1}]
- m({a: 1}).should == [[{a: 1}], {}]
- end
+ empty = {}
+ m(**empty).should == [[], {}]
+ m(empty).should == [[{}], {}]
- it "works with call(*ruby2_keyword_args)" do
- class << self
- ruby2_keywords def m(*args)
- target(*args)
- end
+ m(a: 1).should == [[], {a: 1}]
+ m({a: 1}).should == [[{a: 1}], {}]
end
- empty = {}
- m(**empty).should == [[], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
- m(empty).should == [[{}], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
+ it "works with call(*ruby2_keyword_args)" do
+ class << self
+ ruby2_keywords def m(*args)
+ target(*args)
+ end
+ end
- m(a: 1).should == [[], {a: 1}]
- m({a: 1}).should == [[{a: 1}], {}]
+ empty = {}
+ m(**empty).should == [[], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
+ m(empty).should == [[{}], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
- kw = {a: 1}
+ m(a: 1).should == [[], {a: 1}]
+ m({a: 1}).should == [[{a: 1}], {}]
- m(**kw).should == [[], {a: 1}]
- m(**kw)[1].should == kw
- m(**kw)[1].should_not.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false
+ kw = {a: 1}
- m(kw).should == [[{a: 1}], {}]
- m(kw)[0][0].should.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- end
+ m(**kw).should == [[], {a: 1}]
+ m(**kw)[1].should == kw
+ m(**kw)[1].should_not.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
+ Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false
- it "works with super(*ruby2_keyword_args)" do
- parent = Class.new do
- def m(*args, **kwargs)
- [args, kwargs]
- end
+ m(kw).should == [[{a: 1}], {}]
+ m(kw)[0][0].should.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
end
- child = Class.new(parent) do
- ruby2_keywords def m(*args)
- super(*args)
+ it "works with super(*ruby2_keyword_args)" do
+ parent = Class.new do
+ def m(*args, **kwargs)
+ [args, kwargs]
+ end
end
- end
- obj = child.new
+ child = Class.new(parent) do
+ ruby2_keywords def m(*args)
+ super(*args)
+ end
+ end
- empty = {}
- obj.m(**empty).should == [[], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
- obj.m(empty).should == [[{}], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
+ obj = child.new
- obj.m(a: 1).should == [[], {a: 1}]
- obj.m({a: 1}).should == [[{a: 1}], {}]
+ empty = {}
+ obj.m(**empty).should == [[], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
+ obj.m(empty).should == [[{}], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
- kw = {a: 1}
+ obj.m(a: 1).should == [[], {a: 1}]
+ obj.m({a: 1}).should == [[{a: 1}], {}]
- obj.m(**kw).should == [[], {a: 1}]
- obj.m(**kw)[1].should == kw
- obj.m(**kw)[1].should_not.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- Hash.ruby2_keywords_hash?(obj.m(**kw)[1]).should == false
+ kw = {a: 1}
- obj.m(kw).should == [[{a: 1}], {}]
- obj.m(kw)[0][0].should.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- end
+ obj.m(**kw).should == [[], {a: 1}]
+ obj.m(**kw)[1].should == kw
+ obj.m(**kw)[1].should_not.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
+ Hash.ruby2_keywords_hash?(obj.m(**kw)[1]).should == false
- it "works with zsuper" do
- parent = Class.new do
- def m(*args, **kwargs)
- [args, kwargs]
- end
+ obj.m(kw).should == [[{a: 1}], {}]
+ obj.m(kw)[0][0].should.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
end
- child = Class.new(parent) do
- ruby2_keywords def m(*args)
- super
+ it "works with zsuper" do
+ parent = Class.new do
+ def m(*args, **kwargs)
+ [args, kwargs]
+ end
end
- end
- obj = child.new
-
- empty = {}
- obj.m(**empty).should == [[], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
- obj.m(empty).should == [[{}], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
+ child = Class.new(parent) do
+ ruby2_keywords def m(*args)
+ super
+ end
+ end
- obj.m(a: 1).should == [[], {a: 1}]
- obj.m({a: 1}).should == [[{a: 1}], {}]
+ obj = child.new
- kw = {a: 1}
+ empty = {}
+ obj.m(**empty).should == [[], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
+ obj.m(empty).should == [[{}], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
- obj.m(**kw).should == [[], {a: 1}]
- obj.m(**kw)[1].should == kw
- obj.m(**kw)[1].should_not.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- Hash.ruby2_keywords_hash?(obj.m(**kw)[1]).should == false
+ obj.m(a: 1).should == [[], {a: 1}]
+ obj.m({a: 1}).should == [[{a: 1}], {}]
- obj.m(kw).should == [[{a: 1}], {}]
- obj.m(kw)[0][0].should.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- end
+ kw = {a: 1}
- it "works with yield(*ruby2_keyword_args)" do
- class << self
- def y(args)
- yield(*args)
- end
+ obj.m(**kw).should == [[], {a: 1}]
+ obj.m(**kw)[1].should == kw
+ obj.m(**kw)[1].should_not.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
+ Hash.ruby2_keywords_hash?(obj.m(**kw)[1]).should == false
- ruby2_keywords def m(*outer_args)
- y(outer_args, &-> *args, **kwargs { target(*args, **kwargs) })
- end
+ obj.m(kw).should == [[{a: 1}], {}]
+ obj.m(kw)[0][0].should.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
end
- empty = {}
- m(**empty).should == [[], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
- m(empty).should == [[{}], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
-
- m(a: 1).should == [[], {a: 1}]
- m({a: 1}).should == [[{a: 1}], {}]
-
- kw = {a: 1}
-
- m(**kw).should == [[], {a: 1}]
- m(**kw)[1].should == kw
- m(**kw)[1].should_not.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false
-
- m(kw).should == [[{a: 1}], {}]
- m(kw)[0][0].should.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- end
+ it "works with yield(*ruby2_keyword_args)" do
+ class << self
+ def y(args)
+ yield(*args)
+ end
- it "does not work with (*args)" do
- class << self
- def m(*args)
- target(*args)
+ ruby2_keywords def m(*outer_args)
+ y(outer_args, &-> *args, **kwargs { target(*args, **kwargs) })
+ end
end
- end
- empty = {}
- m(**empty).should == [[], {}]
- m(empty).should == [[{}], {}]
+ empty = {}
+ m(**empty).should == [[], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
+ m(empty).should == [[{}], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
- m(a: 1).should == [[{a: 1}], {}]
- m({a: 1}).should == [[{a: 1}], {}]
- end
+ m(a: 1).should == [[], {a: 1}]
+ m({a: 1}).should == [[{a: 1}], {}]
- ruby_version_is "3.1" do
- describe "omitted values" do
- it "accepts short notation 'key' for 'key: value' syntax" do
- def m(a:, b:)
- [a, b]
- end
+ kw = {a: 1}
- a = 1
- b = 2
+ m(**kw).should == [[], {a: 1}]
+ m(**kw)[1].should == kw
+ m(**kw)[1].should_not.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
+ Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false
- eval('m(a:, b:).should == [1, 2]')
- end
+ m(kw).should == [[{a: 1}], {}]
+ m(kw)[0][0].should.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
end
- end
- ruby_version_is "3.2" do
- it "does not work with call(*ruby2_keyword_args) with missing ruby2_keywords in between" do
+ it "does not work with (*args)" do
class << self
- def n(*args) # Note the missing ruby2_keywords here
+ def m(*args)
target(*args)
end
-
- ruby2_keywords def m(*args)
- n(*args)
- end
end
empty = {}
@@ -357,41 +320,77 @@ describe "Keyword arguments" do
m(a: 1).should == [[{a: 1}], {}]
m({a: 1}).should == [[{a: 1}], {}]
end
- end
- ruby_version_is ""..."3.2" do
- # https://bugs.ruby-lang.org/issues/18625
- it "works with call(*ruby2_keyword_args) with missing ruby2_keywords in between due to CRuby bug #18625" do
- class << self
- def n(*args) # Note the missing ruby2_keywords here
- target(*args)
+ ruby_version_is "3.1" do
+ describe "omitted values" do
+ it "accepts short notation 'key' for 'key: value' syntax" do
+ def m(a:, b:)
+ [a, b]
+ end
+
+ a = 1
+ b = 2
+
+ eval('m(a:, b:).should == [1, 2]')
end
+ end
+ end
- ruby2_keywords def m(*args)
- n(*args)
+ ruby_version_is "3.2" do
+ it "does not work with call(*ruby2_keyword_args) with missing ruby2_keywords in between" do
+ class << self
+ def n(*args) # Note the missing ruby2_keywords here
+ target(*args)
+ end
+
+ ruby2_keywords def m(*args)
+ n(*args)
+ end
end
+
+ empty = {}
+ m(**empty).should == [[], {}]
+ m(empty).should == [[{}], {}]
+
+ m(a: 1).should == [[{a: 1}], {}]
+ m({a: 1}).should == [[{a: 1}], {}]
end
+ end
- empty = {}
- m(**empty).should == [[], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
- m(empty).should == [[{}], {}]
- Hash.ruby2_keywords_hash?(empty).should == false
+ ruby_version_is ""..."3.2" do
+ # https://bugs.ruby-lang.org/issues/18625
+ it "works with call(*ruby2_keyword_args) with missing ruby2_keywords in between due to CRuby bug #18625" do
+ class << self
+ def n(*args) # Note the missing ruby2_keywords here
+ target(*args)
+ end
+
+ ruby2_keywords def m(*args)
+ n(*args)
+ end
+ end
- m(a: 1).should == [[], {a: 1}]
- m({a: 1}).should == [[{a: 1}], {}]
+ empty = {}
+ m(**empty).should == [[], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
+ m(empty).should == [[{}], {}]
+ Hash.ruby2_keywords_hash?(empty).should == false
- kw = {a: 1}
+ m(a: 1).should == [[], {a: 1}]
+ m({a: 1}).should == [[{a: 1}], {}]
- m(**kw).should == [[], {a: 1}]
- m(**kw)[1].should == kw
- m(**kw)[1].should_not.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
- Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false
+ kw = {a: 1}
- m(kw).should == [[{a: 1}], {}]
- m(kw)[0][0].should.equal?(kw)
- Hash.ruby2_keywords_hash?(kw).should == false
+ m(**kw).should == [[], {a: 1}]
+ m(**kw)[1].should == kw
+ m(**kw)[1].should_not.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
+ Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false
+
+ m(kw).should == [[{a: 1}], {}]
+ m(kw)[0][0].should.equal?(kw)
+ Hash.ruby2_keywords_hash?(kw).should == false
+ end
end
end
end
diff --git a/spec/ruby/language/lambda_spec.rb b/spec/ruby/language/lambda_spec.rb
index 3ab3569ebe..a3f01ec04b 100644
--- a/spec/ruby/language/lambda_spec.rb
+++ b/spec/ruby/language/lambda_spec.rb
@@ -177,16 +177,34 @@ describe "A lambda literal -> () { }" do
result.should == [1, 2, 3, [4, 5], 6, [7, 8], 9, 10, 11, 12]
end
- evaluate <<-ruby do
- @a = -> (*, **k) { k }
- ruby
+ ruby_version_is ''...'3.0' do
+ evaluate <<-ruby do
+ @a = -> (*, **k) { k }
+ ruby
+
+ @a.().should == {}
+ @a.(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+
+ suppress_keyword_warning do
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({a: 1})
+ @a.(h).should == {a: 1}
+ end
+ end
+ end
- @a.().should == {}
- @a.(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+ ruby_version_is '3.0' do
+ evaluate <<-ruby do
+ @a = -> (*, **k) { k }
+ ruby
+
+ @a.().should == {}
+ @a.(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
- h = mock("keyword splat")
- h.should_not_receive(:to_hash)
- @a.(h).should == {}
+ h = mock("keyword splat")
+ h.should_not_receive(:to_hash)
+ @a.(h).should == {}
+ end
end
evaluate <<-ruby do
@@ -496,16 +514,34 @@ describe "A lambda expression 'lambda { ... }'" do
result.should == [1, 2, 3, [4, 5], 6, [7, 8], 9, 10, 11, 12]
end
- evaluate <<-ruby do
- @a = lambda { |*, **k| k }
- ruby
+ ruby_version_is ''...'3.0' do
+ evaluate <<-ruby do
+ @a = lambda { |*, **k| k }
+ ruby
- @a.().should == {}
- @a.(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+ @a.().should == {}
+ @a.(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
- h = mock("keyword splat")
- h.should_not_receive(:to_hash)
- @a.(h).should == {}
+ suppress_keyword_warning do
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({a: 1})
+ @a.(h).should == {a: 1}
+ end
+ end
+ end
+
+ ruby_version_is '3.0' do
+ evaluate <<-ruby do
+ @a = lambda { |*, **k| k }
+ ruby
+
+ @a.().should == {}
+ @a.(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+
+ h = mock("keyword splat")
+ h.should_not_receive(:to_hash)
+ @a.(h).should == {}
+ end
end
evaluate <<-ruby do
diff --git a/spec/ruby/language/method_spec.rb b/spec/ruby/language/method_spec.rb
index 5f42c52341..b80b314f6f 100644
--- a/spec/ruby/language/method_spec.rb
+++ b/spec/ruby/language/method_spec.rb
@@ -749,31 +749,68 @@ describe "A method" do
end
end
- evaluate <<-ruby do
- def m(a, b: 1) [a, b] end
- ruby
+ ruby_version_is ""..."3.0" do
+ evaluate <<-ruby do
+ def m(a, b: 1) [a, b] end
+ ruby
- m(2).should == [2, 1]
- m(1, b: 2).should == [1, 2]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
- end
+ m(2).should == [2, 1]
+ m(1, b: 2).should == [1, 2]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [{"a" => 1, b: 2}, 1]
+ end
+ end
- evaluate <<-ruby do
- def m(a, **) a end
- ruby
+ evaluate <<-ruby do
+ def m(a, **) a end
+ ruby
- m(1).should == 1
- m(1, a: 2, b: 3).should == 1
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m(1).should == 1
+ m(1, a: 2, b: 3).should == 1
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == {"a" => 1, b: 2}
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(a, **k) [a, k] end
+ ruby
+
+ m(1).should == [1, {}]
+ m(1, a: 2, b: 3).should == [1, {a: 2, b: 3}]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [{"a" => 1, b: 2}, {}]
+ end
+ end
end
- evaluate <<-ruby do
- def m(a, **k) [a, k] end
- ruby
+ ruby_version_is "3.0" do
+ evaluate <<-ruby do
+ def m(a, b: 1) [a, b] end
+ ruby
+
+ m(2).should == [2, 1]
+ m(1, b: 2).should == [1, 2]
+ -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ end
- m(1).should == [1, {}]
- m(1, a: 2, b: 3).should == [1, {a: 2, b: 3}]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ evaluate <<-ruby do
+ def m(a, **) a end
+ ruby
+
+ m(1).should == 1
+ m(1, a: 2, b: 3).should == 1
+ -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ end
+
+ evaluate <<-ruby do
+ def m(a, **k) [a, k] end
+ ruby
+
+ m(1).should == [1, {}]
+ m(1, a: 2, b: 3).should == [1, {a: 2, b: 3}]
+ -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ end
end
evaluate <<-ruby do
@@ -884,23 +921,50 @@ describe "A method" do
result.should == [[1, 2, 3], 4, [5, 6], 7, [], 8]
end
- evaluate <<-ruby do
- def m(a=1, b:) [a, b] end
- ruby
+ ruby_version_is ""..."3.0" do
+ evaluate <<-ruby do
+ def m(a=1, b:) [a, b] end
+ ruby
+
+ m(b: 2).should == [1, 2]
+ m(2, b: 1).should == [2, 1]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [{"a" => 1}, 2]
+ end
+ end
- m(b: 2).should == [1, 2]
- m(2, b: 1).should == [2, 1]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ evaluate <<-ruby do
+ def m(a=1, b: 2) [a, b] end
+ ruby
+
+ m().should == [1, 2]
+ m(2).should == [2, 2]
+ m(b: 3).should == [1, 3]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [{"a" => 1}, 2]
+ end
+ end
end
- evaluate <<-ruby do
- def m(a=1, b: 2) [a, b] end
- ruby
+ ruby_version_is "3.0" do
+ evaluate <<-ruby do
+ def m(a=1, b:) [a, b] end
+ ruby
- m().should == [1, 2]
- m(2).should == [2, 2]
- m(b: 3).should == [1, 3]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m(b: 2).should == [1, 2]
+ m(2, b: 1).should == [2, 1]
+ -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ end
+
+ evaluate <<-ruby do
+ def m(a=1, b: 2) [a, b] end
+ ruby
+
+ m().should == [1, 2]
+ m(2).should == [2, 2]
+ m(b: 3).should == [1, 3]
+ -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ end
end
evaluate <<-ruby do
@@ -949,6 +1013,292 @@ describe "A method" do
m(1, 2, 3).should == [[1, 2], 3]
end
+ ruby_version_is ""...'3.0' do
+ evaluate <<-ruby do
+ def m(*, a:) a end
+ ruby
+
+ m(a: 1).should == 1
+ m(1, 2, a: 3).should == 3
+ suppress_keyword_warning do
+ m("a" => 1, a: 2).should == 2
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b:) [a, b] end
+ ruby
+
+ m(b: 1).should == [[], 1]
+ m(1, 2, b: 3).should == [[1, 2], 3]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [[{"a" => 1}], 2]
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*, a: 1) a end
+ ruby
+
+ m().should == 1
+ m(1, 2).should == 1
+ m(a: 2).should == 2
+ m(1, a: 2).should == 2
+ suppress_keyword_warning do
+ m("a" => 1, a: 2).should == 2
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b: 1) [a, b] end
+ ruby
+
+ m().should == [[], 1]
+ m(1, 2, 3, b: 4).should == [[1, 2, 3], 4]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [[{"a" => 1}], 2]
+ end
+
+ a = mock("splat")
+ a.should_not_receive(:to_ary)
+ m(*a).should == [[a], 1]
+ end
+
+ evaluate <<-ruby do
+ def m(*a, **) a end
+ ruby
+
+ m().should == []
+ m(1, 2, 3, a: 4, b: 5).should == [1, 2, 3]
+ m("a" => 1, a: 1).should == []
+ m(1, **{a: 2}).should == [1]
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash)
+ -> { m(**h) }.should raise_error(TypeError)
+ end
+
+ evaluate <<-ruby do
+ def m(*, **k) k end
+ ruby
+
+ m().should == {}
+ m(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+ m("a" => 1, a: 1).should == {"a" => 1, a: 1}
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({a: 1})
+ suppress_warning do
+ m(h).should == {a: 1}
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(a = nil, **k) [a, k] end
+ ruby
+
+ m().should == [nil, {}]
+ m("a" => 1).should == [nil, {"a" => 1}]
+ m(a: 1).should == [nil, {a: 1}]
+ m("a" => 1, a: 1).should == [nil, {"a" => 1, a: 1}]
+ m({ "a" => 1 }, a: 1).should == [{"a" => 1}, {a: 1}]
+ suppress_warning do
+ m({a: 1}, {}).should == [{a: 1}, {}]
+
+ h = {"a" => 1, b: 2}
+ m(h).should == [{"a" => 1}, {b: 2}]
+ h.should == {"a" => 1, b: 2}
+
+ h = {"a" => 1}
+ m(h).first.should == h
+
+ h = {}
+ r = m(h)
+ r.first.should be_nil
+ r.last.should == {}
+
+ hh = {}
+ h = mock("keyword splat empty hash")
+ h.should_receive(:to_hash).and_return(hh)
+ r = m(h)
+ r.first.should be_nil
+ r.last.should == {}
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({"a" => 1, a: 2})
+ m(h).should == [{"a" => 1}, {a: 2}]
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*a, **k) [a, k] end
+ ruby
+
+ m().should == [[], {}]
+ m(1).should == [[1], {}]
+ m(a: 1, b: 2).should == [[], {a: 1, b: 2}]
+ m(1, 2, 3, a: 2).should == [[1, 2, 3], {a: 2}]
+
+ m("a" => 1).should == [[], {"a" => 1}]
+ m(a: 1).should == [[], {a: 1}]
+ m("a" => 1, a: 1).should == [[], {"a" => 1, a: 1}]
+ m({ "a" => 1 }, a: 1).should == [[{"a" => 1}], {a: 1}]
+ suppress_warning do
+ m({a: 1}, {}).should == [[{a: 1}], {}]
+ end
+ m({a: 1}, {"a" => 1}).should == [[{a: 1}, {"a" => 1}], {}]
+
+ bo = BasicObject.new
+ def bo.to_a; [1, 2, 3]; end
+ def bo.to_hash; {:b => 2, :c => 3}; end
+
+ m(*bo, **bo).should == [[1, 2, 3], {:b => 2, :c => 3}]
+ end
+
+ evaluate <<-ruby do
+ def m(*, a:) a end
+ ruby
+
+ m(a: 1).should == 1
+ m(1, 2, a: 3).should == 3
+ suppress_keyword_warning do
+ m("a" => 1, a: 2).should == 2
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b:) [a, b] end
+ ruby
+
+ m(b: 1).should == [[], 1]
+ m(1, 2, b: 3).should == [[1, 2], 3]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [[{"a" => 1}], 2]
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*, a: 1) a end
+ ruby
+
+ m().should == 1
+ m(1, 2).should == 1
+ m(a: 2).should == 2
+ m(1, a: 2).should == 2
+ suppress_keyword_warning do
+ m("a" => 1, a: 2).should == 2
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b: 1) [a, b] end
+ ruby
+
+ m().should == [[], 1]
+ m(1, 2, 3, b: 4).should == [[1, 2, 3], 4]
+ suppress_keyword_warning do
+ m("a" => 1, b: 2).should == [[{"a" => 1}], 2]
+ end
+
+ a = mock("splat")
+ a.should_not_receive(:to_ary)
+ m(*a).should == [[a], 1]
+ end
+
+ evaluate <<-ruby do
+ def m(*a, **) a end
+ ruby
+
+ m().should == []
+ m(1, 2, 3, a: 4, b: 5).should == [1, 2, 3]
+ m("a" => 1, a: 1).should == []
+ m(1, **{a: 2}).should == [1]
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash)
+ -> { m(**h) }.should raise_error(TypeError)
+ end
+
+ evaluate <<-ruby do
+ def m(*, **k) k end
+ ruby
+
+ m().should == {}
+ m(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+ m("a" => 1, a: 1).should == {"a" => 1, a: 1}
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({a: 1})
+ suppress_keyword_warning do
+ m(h).should == {a: 1}
+ end
+ end
+
+ evaluate <<-ruby do
+ def m(a = nil, **k) [a, k] end
+ ruby
+
+ m().should == [nil, {}]
+ m("a" => 1).should == [nil, {"a" => 1}]
+ m(a: 1).should == [nil, {a: 1}]
+ m("a" => 1, a: 1).should == [nil, {"a" => 1, a: 1}]
+ m({ "a" => 1 }, a: 1).should == [{"a" => 1}, {a: 1}]
+ suppress_keyword_warning do
+ m({a: 1}, {}).should == [{a: 1}, {}]
+ end
+
+ h = {"a" => 1, b: 2}
+ suppress_keyword_warning do
+ m(h).should == [{"a" => 1}, {b: 2}]
+ end
+ h.should == {"a" => 1, b: 2}
+
+ h = {"a" => 1}
+ m(h).first.should == h
+
+ h = {}
+ suppress_keyword_warning do
+ m(h).should == [nil, {}]
+ end
+
+ hh = {}
+ h = mock("keyword splat empty hash")
+ h.should_receive(:to_hash).and_return({a: 1})
+ suppress_keyword_warning do
+ m(h).should == [nil, {a: 1}]
+ end
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({"a" => 1})
+ m(h).should == [h, {}]
+ end
+
+ evaluate <<-ruby do
+ def m(*a, **k) [a, k] end
+ ruby
+
+ m().should == [[], {}]
+ m(1).should == [[1], {}]
+ m(a: 1, b: 2).should == [[], {a: 1, b: 2}]
+ m(1, 2, 3, a: 2).should == [[1, 2, 3], {a: 2}]
+
+ m("a" => 1).should == [[], {"a" => 1}]
+ m(a: 1).should == [[], {a: 1}]
+ m("a" => 1, a: 1).should == [[], {"a" => 1, a: 1}]
+ m({ "a" => 1 }, a: 1).should == [[{"a" => 1}], {a: 1}]
+ suppress_keyword_warning do
+ m({a: 1}, {}).should == [[{a: 1}], {}]
+ end
+ m({a: 1}, {"a" => 1}).should == [[{a: 1}, {"a" => 1}], {}]
+
+ bo = BasicObject.new
+ def bo.to_a; [1, 2, 3]; end
+ def bo.to_hash; {:b => 2, :c => 3}; end
+
+ m(*bo, **bo).should == [[1, 2, 3], {:b => 2, :c => 3}]
+ end
+ end
+
evaluate <<-ruby do
def m(*, &b) b end
ruby
@@ -1107,25 +1457,47 @@ describe "A method" do
m({a: 1}).should == {a: 1}
m({"a" => 1}).should == {"a" => 1}
- -> { m(a: 1) }.should raise_error(ArgumentError, 'no keywords accepted')
- -> { m(**{a: 1}) }.should raise_error(ArgumentError, 'no keywords accepted')
- -> { m("a" => 1) }.should raise_error(ArgumentError, 'no keywords accepted')
+ -> { m(a: 1) }.should raise_error(ArgumentError)
+ -> { m(**{a: 1}) }.should raise_error(ArgumentError)
+ -> { m("a" => 1) }.should raise_error(ArgumentError)
end
- evaluate <<-ruby do
- def m(a, b = nil, c = nil, d, e: nil, **f)
- [a, b, c, d, e, f]
+ ruby_version_is ''...'3.0' do
+ evaluate <<-ruby do
+ def m(a, b = nil, c = nil, d, e: nil, **f)
+ [a, b, c, d, e, f]
+ end
+ ruby
+
+ result = m(1, 2)
+ result.should == [1, nil, nil, 2, nil, {}]
+
+ suppress_warning do
+ result = m(1, 2, {foo: :bar})
+ result.should == [1, nil, nil, 2, nil, {foo: :bar}]
end
- ruby
- result = m(1, 2)
- result.should == [1, nil, nil, 2, nil, {}]
+ result = m(1, {foo: :bar})
+ result.should == [1, nil, nil, {foo: :bar}, nil, {}]
+ end
+ end
+
+ ruby_version_is '3.0' do
+ evaluate <<-ruby do
+ def m(a, b = nil, c = nil, d, e: nil, **f)
+ [a, b, c, d, e, f]
+ end
+ ruby
+
+ result = m(1, 2)
+ result.should == [1, nil, nil, 2, nil, {}]
- result = m(1, 2, {foo: :bar})
- result.should == [1, 2, nil, {foo: :bar}, nil, {}]
+ result = m(1, 2, {foo: :bar})
+ result.should == [1, 2, nil, {foo: :bar}, nil, {}]
- result = m(1, {foo: :bar})
- result.should == [1, nil, nil, {foo: :bar}, nil, {}]
+ result = m(1, {foo: :bar})
+ result.should == [1, nil, nil, {foo: :bar}, nil, {}]
+ end
end
end
@@ -1139,27 +1511,60 @@ describe "A method" do
end
end
- context 'when passing an empty keyword splat to a method that does not accept keywords' do
- evaluate <<-ruby do
- def m(a); a; end
- ruby
- h = {}
+ ruby_version_is ''...'3.0' do
+ context 'when passing an empty keyword splat to a method that does not accept keywords' do
+ evaluate <<-ruby do
+ def m(a); a; end
+ ruby
+ h = {}
- -> do
- m(**h).should == {}
- end.should raise_error(ArgumentError)
+ -> do
+ m(**h).should == {}
+ end.should complain(/warning: Passing the keyword argument as the last hash parameter is deprecated/)
+ end
end
end
- context "raises ArgumentError if passing hash as keyword arguments" do
- evaluate <<-ruby do
- def m(a: nil); a; end
- ruby
+ ruby_version_is ''...'3.0' do
+ context "assigns keyword arguments from a passed Hash without modifying it" do
+ evaluate <<-ruby do
+ def m(a: nil); a; end
+ ruby
- options = {a: 1}.freeze
- -> do
- m(options)
- end.should raise_error(ArgumentError)
+ options = {a: 1}.freeze
+ -> do
+ suppress_warning do
+ m(options).should == 1
+ end
+ end.should_not raise_error
+ options.should == {a: 1}
+ end
+ end
+ end
+
+ ruby_version_is '3.0' do
+ context 'when passing an empty keyword splat to a method that does not accept keywords' do
+ evaluate <<-ruby do
+ def m(a); a; end
+ ruby
+ h = {}
+
+ -> do
+ m(**h).should == {}
+ end.should raise_error(ArgumentError)
+ end
+ end
+
+ context "raises ArgumentError if passing hash as keyword arguments" do
+ evaluate <<-ruby do
+ def m(a: nil); a; end
+ ruby
+
+ options = {a: 1}.freeze
+ -> do
+ m(options)
+ end.should raise_error(ArgumentError)
+ end
end
end
@@ -1193,42 +1598,14 @@ describe "A method call with a space between method name and parentheses" do
end
end
- context "when a single argument is provided" do
- it "assigns a simple expression" do
- args = m (1)
- args.should == [1]
- end
-
- it "assigns an expression consisting of multiple statements" do
- args = m ((0; 1))
- args.should == [1]
- end
-
- it "assigns one single statement, without the need of parentheses" do
+ context "when a single argument provided" do
+ it "assigns it" do
args = m (1 == 1 ? true : false)
args.should == [true]
end
-
- ruby_version_is "3.3" do
- it "supports multiple statements" do
- eval("m (1; 2)").should == [2]
- end
- end
end
- context "when multiple arguments are provided" do
- it "assigns simple expressions" do
- args = m (1), (2)
- args.should == [1, 2]
- end
-
- it "assigns expressions consisting of multiple statements" do
- args = m ((0; 1)), ((2; 3))
- args.should == [1, 3]
- end
- end
-
- context "when the argument looks like an argument list" do
+ context "when 2+ arguments provided" do
it "raises a syntax error" do
-> {
eval("m (1, 2)")
@@ -1293,107 +1670,105 @@ describe "An array-dereference method ([])" do
end
end
-describe "An endless method definition" do
- context "without arguments" do
- evaluate <<-ruby do
- def m() = 42
- ruby
-
- m.should == 42
- end
-
- context "without parenthesis" do
+ruby_version_is "3.0" do
+ describe "An endless method definition" do
+ context "without arguments" do
evaluate <<-ruby do
- def m = 42
- ruby
+ def m() = 42
+ ruby
m.should == 42
end
+
+ context "without parenthesis" do
+ evaluate <<-ruby do
+ def m = 42
+ ruby
+
+ m.should == 42
+ end
+ end
end
- end
- context "with arguments" do
- evaluate <<-ruby do
- def m(a, b) = a + b
- ruby
+ context "with arguments" do
+ evaluate <<-ruby do
+ def m(a, b) = a + b
+ ruby
- m(1, 4).should == 5
+ m(1, 4).should == 5
+ end
end
- end
- context "with multiline body" do
- evaluate <<-ruby do
- def m(n) =
- if n > 2
- m(n - 2) + m(n - 1)
- else
- 1
- end
- ruby
+ context "with multiline body" do
+ evaluate <<-ruby do
+ def m(n) =
+ if n > 2
+ m(n - 2) + m(n - 1)
+ else
+ 1
+ end
+ ruby
- m(6).should == 8
+ m(6).should == 8
+ end
end
- end
- context "with args forwarding" do
- evaluate <<-ruby do
- def mm(word, num:)
- word * num
- end
+ context "with args forwarding" do
+ evaluate <<-ruby do
+ def mm(word, num:)
+ word * num
+ end
- def m(...) = mm(...) + mm(...)
- ruby
+ def m(...) = mm(...) + mm(...)
+ ruby
- m("meow", num: 2).should == "meow" * 4
+ m("meow", num: 2).should == "meow" * 4
+ end
end
- end
-end
-describe "Keyword arguments are now separated from positional arguments" do
- context "when the method has only positional parameters" do
- it "treats incoming keyword arguments as positional for compatibility" do
- def foo(a, b, c, hsh)
- hsh[:key]
+ ruby_version_is ""..."3.0" do
+ context "inside 'endless' method definitions" do
+ it "does not allow method calls without parenthesis" do
+ -> {
+ eval("def greet(person) = 'Hi, '.concat person")
+ }.should raise_error(SyntaxError)
+ end
end
-
- foo(1, 2, 3, key: 42).should == 42
end
end
- context "when the method takes a ** parameter" do
- it "captures the passed literal keyword arguments" do
- def foo(a, b, c, **hsh)
- hsh[:key]
- end
+ describe "Keyword arguments are now separated from positional arguments" do
+ context "when the method has only positional parameters" do
+ it "treats incoming keyword arguments as positional for compatibility" do
+ def foo(a, b, c, hsh)
+ hsh[:key]
+ end
- foo(1, 2, 3, key: 42).should == 42
+ foo(1, 2, 3, key: 42).should == 42
+ end
end
- it "captures the passed ** keyword arguments" do
- def foo(a, b, c, **hsh)
- hsh[:key]
+ context "when the method takes a ** parameter" do
+ it "captures the passed literal keyword arguments" do
+ def foo(a, b, c, **hsh)
+ hsh[:key]
+ end
+
+ foo(1, 2, 3, key: 42).should == 42
end
- h = { key: 42 }
- foo(1, 2, 3, **h).should == 42
- end
+ it "captures the passed ** keyword arguments" do
+ def foo(a, b, c, **hsh)
+ hsh[:key]
+ end
- it "does not convert a positional Hash to keyword arguments" do
- def foo(a, b, c, **hsh)
- hsh[:key]
+ h = { key: 42 }
+ foo(1, 2, 3, **h).should == 42
end
- -> {
- foo(1, 2, 3, { key: 42 })
- }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)')
- end
- end
-
- context "when the method takes a key: parameter" do
- context "when it's called with a positional Hash and no **" do
- it "raises ArgumentError" do
- def foo(a, b, c, key: 1)
- key
+ it "does not convert a positional Hash to keyword arguments" do
+ def foo(a, b, c, **hsh)
+ hsh[:key]
end
-> {
@@ -1402,14 +1777,28 @@ describe "Keyword arguments are now separated from positional arguments" do
end
end
- context "when it's called with **" do
- it "captures the passed keyword arguments" do
- def foo(a, b, c, key: 1)
- key
+ context "when the method takes a key: parameter" do
+ context "when it's called with a positional Hash and no **" do
+ it "raises ArgumentError" do
+ def foo(a, b, c, key: 1)
+ key
+ end
+
+ -> {
+ foo(1, 2, 3, { key: 42 })
+ }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)')
end
+ end
- h = { key: 42 }
- foo(1, 2, 3, **h).should == 42
+ context "when it's called with **" do
+ it "captures the passed keyword arguments" do
+ def foo(a, b, c, key: 1)
+ key
+ end
+
+ h = { key: 42 }
+ foo(1, 2, 3, **h).should == 42
+ end
end
end
end
diff --git a/spec/ruby/language/module_spec.rb b/spec/ruby/language/module_spec.rb
index fffcf9c90d..e361bf58f5 100644
--- a/spec/ruby/language/module_spec.rb
+++ b/spec/ruby/language/module_spec.rb
@@ -78,10 +78,20 @@ describe "Assigning an anonymous module to a constant" do
mod.name.should == "ModuleSpecs_CS1"
end
- it "sets the name of a module scoped by an anonymous module" do
- a, b = Module.new, Module.new
- a::B = b
- b.name.should.end_with? '::B'
+ ruby_version_is ""..."3.0" do
+ it "does not set the name of a module scoped by an anonymous module" do
+ a, b = Module.new, Module.new
+ a::B = b
+ b.name.should be_nil
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "sets the name of a module scoped by an anonymous module" do
+ a, b = Module.new, Module.new
+ a::B = b
+ b.name.should.end_with? '::B'
+ end
end
it "sets the name of contained modules when assigning a toplevel anonymous module" do
diff --git a/spec/ruby/language/numbered_parameters_spec.rb b/spec/ruby/language/numbered_parameters_spec.rb
index 3a35cf1465..424d7a06e3 100644
--- a/spec/ruby/language/numbered_parameters_spec.rb
+++ b/spec/ruby/language/numbered_parameters_spec.rb
@@ -31,19 +31,38 @@ describe "Numbered parameters" do
}.should raise_error(SyntaxError, /numbered parameter is already used in/m)
end
- it "cannot be overwritten with local variable" do
- -> {
- eval <<~CODE
- _1 = 0
- proc { _1 }.call("a").should == 0
- CODE
- }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
+ ruby_version_is ''...'3.0' do
+ it "can be overwritten with local variable" do
+ suppress_warning do
+ eval <<~CODE
+ _1 = 0
+ proc { _1 }.call("a").should == 0
+ CODE
+ end
+ end
+
+ it "warns when numbered parameter is overwritten with local variable" do
+ -> {
+ eval("_1 = 0")
+ }.should complain(/warning: `_1' is reserved for numbered parameter; consider another name/)
+ end
end
- it "errors when numbered parameter is overwritten with local variable" do
- -> {
- eval("_1 = 0")
- }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
+ ruby_version_is '3.0' do
+ it "cannot be overwritten with local variable" do
+ -> {
+ eval <<~CODE
+ _1 = 0
+ proc { _1 }.call("a").should == 0
+ CODE
+ }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
+ end
+
+ it "errors when numbered parameter is overwritten with local variable" do
+ -> {
+ eval("_1 = 0")
+ }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
+ end
end
it "raises SyntaxError when block parameters are specified explicitly" do
@@ -61,8 +80,16 @@ describe "Numbered parameters" do
end
describe "assigning to a numbered parameter" do
- it "raises SyntaxError" do
- -> { eval("proc { _1 = 0 }") }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
+ ruby_version_is ''...'3.0' do
+ it "warns" do
+ -> { eval("proc { _1 = 0 }") }.should complain(/warning: `_1' is reserved for numbered parameter; consider another name/)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "raises SyntaxError" do
+ -> { eval("proc { _1 = 0 }") }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
+ end
end
end
@@ -82,19 +109,6 @@ describe "Numbered parameters" do
lambda { _9 }.arity.should == 9
end
- it "affects block parameters" do
- -> { _1 }.parameters.should == [[:req, :_1]]
- -> { _2 }.parameters.should == [[:req, :_1], [:req, :_2]]
-
- proc { _1 }.parameters.should == [[:opt, :_1]]
- proc { _2 }.parameters.should == [[:opt, :_1], [:opt, :_2]]
- end
-
- it "affects binding local variables" do
- -> { _1; binding.local_variables }.call("a").should == [:_1]
- -> { _2; binding.local_variables }.call("a", "b").should == [:_1, :_2]
- end
-
it "does not work in methods" do
obj = Object.new
def obj.foo; _1 end
diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb
index 050a8a052d..f3cc86fa0b 100644
--- a/spec/ruby/language/pattern_matching_spec.rb
+++ b/spec/ruby/language/pattern_matching_spec.rb
@@ -8,8 +8,8 @@ describe "Pattern matching" do
ScratchPad.record []
end
- describe "can be standalone assoc operator that" do
- it "deconstructs value" do
+ ruby_version_is "3.0" do
+ it "can be standalone assoc operator that deconstructs value" do
suppress_warning do
eval(<<-RUBY).should == [0, 1]
[0, 1] => [a, b]
@@ -18,117 +18,105 @@ describe "Pattern matching" do
end
end
- it "deconstructs value and properly scopes variables" do
- suppress_warning do
- eval(<<-RUBY).should == [0, nil]
- a = nil
- eval(<<-PATTERN)
- [0, 1] => [a, b]
- PATTERN
- [a, defined?(b)]
+ describe "find pattern" do
+ it "captures preceding elements to the pattern" do
+ eval(<<~RUBY).should == [0, 1]
+ case [0, 1, 2, 3]
+ in [*pre, 2, 3]
+ pre
+ else
+ false
+ end
RUBY
end
- end
- end
-
- describe "find pattern" do
- it "captures preceding elements to the pattern" do
- eval(<<~RUBY).should == [0, 1]
- case [0, 1, 2, 3]
- in [*pre, 2, 3]
- pre
- else
- false
- end
- RUBY
- end
- it "captures following elements to the pattern" do
- eval(<<~RUBY).should == [2, 3]
- case [0, 1, 2, 3]
- in [0, 1, *post]
- post
- else
- false
- end
- RUBY
- end
+ it "captures following elements to the pattern" do
+ eval(<<~RUBY).should == [2, 3]
+ case [0, 1, 2, 3]
+ in [0, 1, *post]
+ post
+ else
+ false
+ end
+ RUBY
+ end
- it "captures both preceding and following elements to the pattern" do
- eval(<<~RUBY).should == [[0, 1], [3, 4]]
- case [0, 1, 2, 3, 4]
- in [*pre, 2, *post]
- [pre, post]
- else
- false
- end
- RUBY
- end
+ it "captures both preceding and following elements to the pattern" do
+ eval(<<~RUBY).should == [[0, 1], [3, 4]]
+ case [0, 1, 2, 3, 4]
+ in [*pre, 2, *post]
+ [pre, post]
+ else
+ false
+ end
+ RUBY
+ end
- it "can capture the entirety of the pattern" do
- eval(<<~RUBY).should == [0, 1, 2, 3, 4]
- case [0, 1, 2, 3, 4]
- in [*everything]
- everything
- else
- false
- end
- RUBY
- end
+ it "can capture the entirety of the pattern" do
+ eval(<<~RUBY).should == [0, 1, 2, 3, 4]
+ case [0, 1, 2, 3, 4]
+ in [*everything]
+ everything
+ else
+ false
+ end
+ RUBY
+ end
- it "will match an empty Array-like structure" do
- eval(<<~RUBY).should == []
- case []
- in [*everything]
- everything
- else
- false
- end
- RUBY
- end
+ it "will match an empty Array-like structure" do
+ eval(<<~RUBY).should == []
+ case []
+ in [*everything]
+ everything
+ else
+ false
+ end
+ RUBY
+ end
- it "can be nested" do
- eval(<<~RUBY).should == [[0, [2, 4, 6]], [[4, 16, 64]], 27]
- case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]]
- in [*pre, [*, 9, a], *post]
- [pre, post, a]
- else
- false
- end
- RUBY
- end
+ it "can be nested" do
+ eval(<<~RUBY).should == [[0, [2, 4, 6]], [[4, 16, 64]], 27]
+ case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]]
+ in [*pre, [*, 9, a], *post]
+ [pre, post, a]
+ else
+ false
+ end
+ RUBY
+ end
- it "can be nested with an array pattern" do
- eval(<<~RUBY).should == [[4, 16, 64]]
- case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]]
- in [_, _, [*, 9, *], *post]
- post
- else
- false
- end
- RUBY
- end
+ it "can be nested with an array pattern" do
+ eval(<<~RUBY).should == [[4, 16, 64]]
+ case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]]
+ in [_, _, [*, 9, *], *post]
+ post
+ else
+ false
+ end
+ RUBY
+ end
- it "can be nested within a hash pattern" do
- eval(<<~RUBY).should == [27]
- case {a: [3, 9, 27]}
- in {a: [*, 9, *post]}
- post
- else
- false
- end
- RUBY
- end
+ it "can be nested within a hash pattern" do
+ eval(<<~RUBY).should == [27]
+ case {a: [3, 9, 27]}
+ in {a: [*, 9, *post]}
+ post
+ else
+ false
+ end
+ RUBY
+ end
- it "can nest hash and array patterns" do
- eval(<<~RUBY).should == [42, 2]
- case [0, {a: 42, b: [0, 1]}, {a: 42, b: [1, 2]}]
- in [*, {a:, b: [1, c]}, *]
- [a, c]
- else
- false
- end
- RUBY
+ it "can nest hash and array patterns" do
+ eval(<<~RUBY).should == [42, 2]
+ case [0, {a: 42, b: [0, 1]}, {a: 42, b: [1, 2]}]
+ in [*, {a:, b: [1, c]}, *]
+ [a, c]
+ else
+ false
+ end
+ RUBY
+ end
end
end
@@ -166,28 +154,38 @@ describe "Pattern matching" do
@src = 'case [0, 1]; in [a, b]; end'
end
- it "does not warn about pattern matching is experimental feature" do
- -> { eval @src }.should_not complain
- end
- end
-
- context 'when one-line form' do
- before :each do
- @src = '[0, 1] => [a, b]'
- end
-
- ruby_version_is ""..."3.1" do
+ ruby_version_is ""..."3.0" do
it "warns about pattern matching is experimental feature" do
-> { eval @src }.should complain(/pattern matching is experimental, and the behavior may change in future versions of Ruby!/i)
end
end
- ruby_version_is "3.1" do
+ ruby_version_is "3.0" do
it "does not warn about pattern matching is experimental feature" do
-> { eval @src }.should_not complain
end
end
end
+
+ context 'when one-line form' do
+ ruby_version_is '3.0' do
+ before :each do
+ @src = '[0, 1] => [a, b]'
+ end
+
+ ruby_version_is ""..."3.1" do
+ it "warns about pattern matching is experimental feature" do
+ -> { eval @src }.should complain(/pattern matching is experimental, and the behavior may change in future versions of Ruby!/i)
+ end
+ end
+
+ ruby_version_is "3.1" do
+ it "does not warn about pattern matching is experimental feature" do
+ -> { eval @src }.should_not complain
+ end
+ end
+ end
+ end
end
it "binds variables" do
@@ -207,7 +205,7 @@ describe "Pattern matching" do
in []
end
RUBY
- }.should raise_error(SyntaxError, /syntax error, unexpected `in'|\(eval\):3: syntax error, unexpected keyword_in/)
+ }.should raise_error(SyntaxError, /syntax error, unexpected `in'/)
-> {
eval <<~RUBY
@@ -216,7 +214,7 @@ describe "Pattern matching" do
when 1 == 1
end
RUBY
- }.should raise_error(SyntaxError, /syntax error, unexpected `when'|\(eval\):3: syntax error, unexpected keyword_when/)
+ }.should raise_error(SyntaxError, /syntax error, unexpected `when'/)
end
it "checks patterns until the first matching" do
@@ -253,18 +251,6 @@ describe "Pattern matching" do
}.should raise_error(NoMatchingPatternError, /\[0, 1\]/)
end
- it "raises NoMatchingPatternError if no pattern matches and evaluates the expression only once" do
- evals = 0
- -> {
- eval <<~RUBY
- case (evals += 1; [0, 1])
- in [0]
- end
- RUBY
- }.should raise_error(NoMatchingPatternError, /\[0, 1\]/)
- evals.should == 1
- end
-
it "does not allow calculation or method calls in a pattern" do
-> {
eval <<~RUBY
@@ -689,24 +675,26 @@ describe "Pattern matching" do
RUBY
end
- it "calls #deconstruct once for multiple patterns, caching the result" do
- obj = Object.new
+ ruby_version_is "3.0" do
+ it "calls #deconstruct once for multiple patterns, caching the result" do
+ obj = Object.new
- def obj.deconstruct
- ScratchPad << :deconstruct
- [0, 1]
- end
-
- eval(<<~RUBY).should == true
- case obj
- in [1, 2]
- false
- in [0, 1]
- true
+ def obj.deconstruct
+ ScratchPad << :deconstruct
+ [0, 1]
end
- RUBY
- ScratchPad.recorded.should == [:deconstruct]
+ eval(<<~RUBY).should == true
+ case obj
+ in [1, 2]
+ false
+ in [0, 1]
+ true
+ end
+ RUBY
+
+ ScratchPad.recorded.should == [:deconstruct]
+ end
end
it "calls #deconstruct even on objects that are already an array" do
diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb
index 965e916b3d..d1cda25918 100644
--- a/spec/ruby/language/predefined_spec.rb
+++ b/spec/ruby/language/predefined_spec.rb
@@ -887,7 +887,7 @@ describe "Execution variable $:" do
$:[idx..-1].all? { |p| p.instance_variable_defined?(:@gem_prelude_index) }.should be_true
$:[0...idx].all? { |p| !p.instance_variable_defined?(:@gem_prelude_index) }.should be_true
- end if false # no sense in ruby itself. skip is not working for rhel_zlinux for some reason
+ end
end
describe "Global variable $\"" do
@@ -979,10 +979,6 @@ describe "Global variable $VERBOSE" do
$VERBOSE = @verbose
end
- it "is false by default" do
- $VERBOSE.should be_false
- end
-
it "converts truthy values to true" do
[true, 1, 0, [], ""].each do |true_value|
$VERBOSE = true_value
@@ -1037,7 +1033,7 @@ describe "Global variable $0" do
it "is the path given as the main script and the same as __FILE__" do
script = "fixtures/dollar_zero.rb"
- Dir.chdir(__dir__) do
+ Dir.chdir(File.dirname(__FILE__)) do
ruby_exe(script).should == "#{script}\n#{script}\nOK"
end
end
@@ -1161,20 +1157,47 @@ end
describe "The predefined global constants" do
describe "TRUE" do
- it "is no longer defined" do
- Object.const_defined?(:TRUE).should == false
+ ruby_version_is "3.0" do
+ it "is no longer defined" do
+ Object.const_defined?(:TRUE).should == false
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "includes TRUE" do
+ Object.const_defined?(:TRUE).should == true
+ -> { TRUE }.should complain(/constant ::TRUE is deprecated/)
+ end
end
end
describe "FALSE" do
- it "is no longer defined" do
- Object.const_defined?(:FALSE).should == false
+ ruby_version_is "3.0" do
+ it "is no longer defined" do
+ Object.const_defined?(:FALSE).should == false
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "includes FALSE" do
+ Object.const_defined?(:FALSE).should == true
+ -> { FALSE }.should complain(/constant ::FALSE is deprecated/)
+ end
end
end
describe "NIL" do
- it "is no longer defined" do
- Object.const_defined?(:NIL).should == false
+ ruby_version_is "3.0" do
+ it "is no longer defined" do
+ Object.const_defined?(:NIL).should == false
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "includes NIL" do
+ Object.const_defined?(:NIL).should == true
+ -> { NIL }.should complain(/constant ::NIL is deprecated/)
+ end
end
end
diff --git a/spec/ruby/language/proc_spec.rb b/spec/ruby/language/proc_spec.rb
index cc69b7799c..f8a29962b0 100644
--- a/spec/ruby/language/proc_spec.rb
+++ b/spec/ruby/language/proc_spec.rb
@@ -161,18 +161,6 @@ describe "A Proc" do
end
end
- describe "taking |*a, b| arguments" do
- it "assigns [] to the argument when passed no values" do
- proc { |*a, b| [a, b] }.call.should == [[], nil]
- end
- end
-
- describe "taking |a, *b, c| arguments" do
- it "assigns [] to the argument when passed no values" do
- proc { |a, *b, c| [a, b, c] }.call.should == [nil, [], nil]
- end
- end
-
describe "taking |a, | arguments" do
before :each do
@l = lambda { |a, | a }
@@ -235,8 +223,18 @@ describe "A Proc" do
@p = proc { |*a, **kw| [a, kw] }
end
- it 'does not autosplat keyword arguments' do
- @p.call([1, {a: 1}]).should == [[[1, {a: 1}]], {}]
+ ruby_version_is ""..."3.0" do
+ it 'autosplats keyword arguments and warns' do
+ -> {
+ @p.call([1, {a: 1}]).should == [[1], {a: 1}]
+ }.should complain(/warning: Using the last argument as keyword parameters is deprecated; maybe \*\* should be added to the call/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it 'does not autosplat keyword arguments' do
+ @p.call([1, {a: 1}]).should == [[[1, {a: 1}]], {}]
+ end
end
end
diff --git a/spec/ruby/language/regexp/character_classes_spec.rb b/spec/ruby/language/regexp/character_classes_spec.rb
index 98d431a817..12a51178b2 100644
--- a/spec/ruby/language/regexp/character_classes_spec.rb
+++ b/spec/ruby/language/regexp/character_classes_spec.rb
@@ -610,12 +610,14 @@ describe "Regexp with character classes" do
end
it "supports negated property condition" do
- "a".match(eval("/\P{L}/")).should be_nil
- "1".match(eval("/\P{N}/")).should be_nil
+ "a".match(/\P{L}/).should be_nil
+ "1".match(/\P{N}/).should be_nil
end
- it "raises a RegexpError for an unterminated unicode property" do
- -> { Regexp.new('\p{') }.should raise_error(RegexpError)
+ ruby_bug "#17340", ''...'3.0' do
+ it "raises a RegexpError for an unterminated unicode property" do
+ -> { Regexp.new('\p{') }.should raise_error(RegexpError)
+ end
end
it "supports \\X (unicode 9.0 with UTR #51 workarounds)" do
diff --git a/spec/ruby/language/regexp/repetition_spec.rb b/spec/ruby/language/regexp/repetition_spec.rb
index d76619688f..9a191d74e2 100644
--- a/spec/ruby/language/regexp/repetition_spec.rb
+++ b/spec/ruby/language/regexp/repetition_spec.rb
@@ -87,7 +87,9 @@ describe "Regexps with repetition" do
/a+?*/.match("a")[0].should == "a"
/(a+?)*/.match("a")[0].should == "a"
- /a+?*/.match("aa")[0].should == "aa"
+ ruby_bug '#17341', ''...'3.0' do
+ /a+?*/.match("aa")[0].should == "aa"
+ end
/(a+?)*/.match("aa")[0].should == "aa"
# a+?+ should not be reduced, it should be equivalent to (a+?)+
@@ -98,7 +100,9 @@ describe "Regexps with repetition" do
/a+?+/.match("a")[0].should == "a"
/(a+?)+/.match("a")[0].should == "a"
- /a+?+/.match("aa")[0].should == "aa"
+ ruby_bug '#17341', ''...'3.0' do
+ /a+?+/.match("aa")[0].should == "aa"
+ end
/(a+?)+/.match("aa")[0].should == "aa"
# both a**? and a+*? should be equivalent to (a+)??
diff --git a/spec/ruby/language/regexp_spec.rb b/spec/ruby/language/regexp_spec.rb
index cdafd29f49..d49689349d 100644
--- a/spec/ruby/language/regexp_spec.rb
+++ b/spec/ruby/language/regexp_spec.rb
@@ -18,8 +18,10 @@ describe "Literal Regexps" do
/Hello/.should be_kind_of(Regexp)
end
- it "is frozen" do
- /Hello/.should.frozen?
+ ruby_version_is "3.0" do
+ it "is frozen" do
+ /Hello/.should.frozen?
+ end
end
it "caches the Regexp object" do
@@ -112,7 +114,7 @@ describe "Literal Regexps" do
/foo.(?<=\d)/.match("fooA foo1").to_a.should == ["foo1"]
end
- ruby_bug "#13671", ""..."3.4" do # https://bugs.ruby-lang.org/issues/13671
+ ruby_bug "#13671", ""..."3.3" do # https://bugs.ruby-lang.org/issues/13671
it "handles a lookbehind with ss characters" do
r = Regexp.new("(?<!dss)", Regexp::IGNORECASE)
r.should =~ "✨"
diff --git a/spec/ruby/language/safe_spec.rb b/spec/ruby/language/safe_spec.rb
index 03ae96148e..ee5c1b3ccc 100644
--- a/spec/ruby/language/safe_spec.rb
+++ b/spec/ruby/language/safe_spec.rb
@@ -1,11 +1,27 @@
require_relative '../spec_helper'
describe "The $SAFE variable" do
- it "$SAFE is a regular global variable" do
- $SAFE.should == nil
- $SAFE = 42
- $SAFE.should == 42
- ensure
- $SAFE = nil
+ ruby_version_is ""..."3.0" do
+ it "warn when access" do
+ -> {
+ $SAFE
+ }.should complain(/\$SAFE will become a normal global variable in Ruby 3.0/)
+ end
+
+ it "warn when set" do
+ -> {
+ $SAFE = 1
+ }.should complain(/\$SAFE will become a normal global variable in Ruby 3.0/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "$SAFE is a regular global variable" do
+ $SAFE.should == nil
+ $SAFE = 42
+ $SAFE.should == 42
+ ensure
+ $SAFE = nil
+ end
end
end
diff --git a/spec/ruby/language/send_spec.rb b/spec/ruby/language/send_spec.rb
index a1656559fe..5999079d58 100644
--- a/spec/ruby/language/send_spec.rb
+++ b/spec/ruby/language/send_spec.rb
@@ -411,18 +411,36 @@ describe "Invoking a method" do
specs.rest_len(0,*a,4,*5,6,7,*c,-1).should == 11
end
- it "expands the Array elements from the splat before applying block argument operations" do
- def self.m(*args, &block)
- [args, block]
+ ruby_version_is ""..."3.0" do
+ it "expands the Array elements from the splat after executing the arguments and block if no other arguments follow the splat" do
+ def self.m(*args, &block)
+ [args, block]
+ end
+
+ args = [1, nil]
+ m(*args, &args.pop).should == [[1], nil]
+
+ args = [1, nil]
+ order = []
+ m(*(order << :args; args), &(order << :block; args.pop)).should == [[1], nil]
+ order.should == [:args, :block]
end
+ end
- args = [1, nil]
- m(*args, &args.pop).should == [[1, nil], nil]
+ ruby_version_is "3.0" do
+ it "expands the Array elements from the splat before applying block argument operations" do
+ def self.m(*args, &block)
+ [args, block]
+ end
- args = [1, nil]
- order = []
- m(*(order << :args; args), &(order << :block; args.pop)).should == [[1, nil], nil]
- order.should == [:args, :block]
+ args = [1, nil]
+ m(*args, &args.pop).should == [[1, nil], nil]
+
+ args = [1, nil]
+ order = []
+ m(*(order << :args; args), &(order << :block; args.pop)).should == [[1, nil], nil]
+ order.should == [:args, :block]
+ end
end
it "evaluates the splatted arguments before the block if there are other arguments after the splat" do
diff --git a/spec/ruby/language/singleton_class_spec.rb b/spec/ruby/language/singleton_class_spec.rb
index 9d037717b2..c1fb682ea0 100644
--- a/spec/ruby/language/singleton_class_spec.rb
+++ b/spec/ruby/language/singleton_class_spec.rb
@@ -291,27 +291,3 @@ describe "Instantiating a singleton class" do
}.should raise_error(TypeError)
end
end
-
-describe "Frozen properties" do
- it "is frozen if the object it is created from is frozen" do
- o = Object.new
- o.freeze
- klass = o.singleton_class
- klass.frozen?.should == true
- end
-
- it "will be frozen if the object it is created from becomes frozen" do
- o = Object.new
- klass = o.singleton_class
- klass.frozen?.should == false
- o.freeze
- klass.frozen?.should == true
- end
-
- it "will be unfrozen if the frozen object is cloned with freeze set to false" do
- o = Object.new
- o.freeze
- o2 = o.clone(freeze: false)
- o2.singleton_class.frozen?.should == false
- end
-end
diff --git a/spec/ruby/language/source_encoding_spec.rb b/spec/ruby/language/source_encoding_spec.rb
index 7135bc0a70..19364fc676 100644
--- a/spec/ruby/language/source_encoding_spec.rb
+++ b/spec/ruby/language/source_encoding_spec.rb
@@ -15,7 +15,7 @@ describe "Source files" do
end
describe "encoded in UTF-16 LE without a BOM" do
- it "are parsed as empty because they contain a NUL byte before the encoding comment" do
+ it "are parsed because empty as they contain a NUL byte before the encoding comment" do
ruby_exe(fixture(__FILE__, "utf16-le-nobom.rb"), args: "2>&1").should == ""
end
end
diff --git a/spec/ruby/language/string_spec.rb b/spec/ruby/language/string_spec.rb
index 418dc2ca7d..02e3488a1f 100644
--- a/spec/ruby/language/string_spec.rb
+++ b/spec/ruby/language/string_spec.rb
@@ -277,11 +277,23 @@ describe "Ruby String interpolation" do
eval(code).should_not.frozen?
end
- it "creates a non-frozen String when # frozen-string-literal: true is used" do
- code = <<~'RUBY'
- # frozen-string-literal: true
- "a#{6*7}c"
- RUBY
- eval(code).should_not.frozen?
+ ruby_version_is "3.0" do
+ it "creates a non-frozen String when # frozen-string-literal: true is used" do
+ code = <<~'RUBY'
+ # frozen-string-literal: true
+ "a#{6*7}c"
+ RUBY
+ eval(code).should_not.frozen?
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "creates a frozen String when # frozen-string-literal: true is used" do
+ code = <<~'RUBY'
+ # frozen-string-literal: true
+ "a#{6*7}c"
+ RUBY
+ eval(code).should.frozen?
+ end
end
end
diff --git a/spec/ruby/language/super_spec.rb b/spec/ruby/language/super_spec.rb
index d22c603605..1ac5c5e1be 100644
--- a/spec/ruby/language/super_spec.rb
+++ b/spec/ruby/language/super_spec.rb
@@ -203,25 +203,6 @@ describe "The super keyword" do
-> { klass.new.a(:a_called) }.should raise_error(RuntimeError)
end
- it "is able to navigate to super, when a method is defined dynamically on the singleton class" do
- foo_class = Class.new do
- def bar
- "bar"
- end
- end
-
- mixin_module = Module.new do
- def bar
- "super_" + super
- end
- end
-
- foo = foo_class.new
- foo.singleton_class.define_method(:bar, mixin_module.instance_method(:bar))
-
- foo.bar.should == "super_bar"
- end
-
# Rubinius ticket github#157
it "calls method_missing when a superclass method is not found" do
SuperSpecs::MM_B.new.is_a?(Hash).should == false
@@ -341,10 +322,6 @@ describe "The super keyword" do
SuperSpecs::ZSuperWithUnderscores::B.new.m_modified(1, 2).should == [14, 2]
end
- it "should pass method arguments when called within a closure" do
- SuperSpecs::ZSuperInBlock::B.new.m(arg: 1).should == 1
- end
-
describe 'when using keyword arguments' do
before :each do
@req = SuperSpecs::Keywords::RequiredArguments.new
diff --git a/spec/ruby/language/symbol_spec.rb b/spec/ruby/language/symbol_spec.rb
index ea6d541b8b..d6a41d3059 100644
--- a/spec/ruby/language/symbol_spec.rb
+++ b/spec/ruby/language/symbol_spec.rb
@@ -96,13 +96,11 @@ describe "A Symbol literal" do
%I{a b #{"c"}}.should == [:a, :b, :c]
end
- ruby_bug "#20280", ""..."3.3" do
- it "raises a SyntaxError at parse time when Symbol with invalid bytes" do
- ScratchPad.record []
- -> {
- eval 'ScratchPad << 1; :"\xC3"'
- }.should raise_error(SyntaxError, /invalid symbol/)
- ScratchPad.recorded.should == []
- end
+ it "with invalid bytes raises an EncodingError at parse time" do
+ ScratchPad.record []
+ -> {
+ eval 'ScratchPad << 1; :"\xC3"'
+ }.should raise_error(EncodingError, /invalid/)
+ ScratchPad.recorded.should == []
end
end
diff --git a/spec/ruby/language/undef_spec.rb b/spec/ruby/language/undef_spec.rb
index 29dba4afb4..4e473b803f 100644
--- a/spec/ruby/language/undef_spec.rb
+++ b/spec/ruby/language/undef_spec.rb
@@ -38,19 +38,12 @@ describe "The undef keyword" do
-> { @obj.meth(5) }.should raise_error(NoMethodError)
end
- it "with an interpolated symbol" do
+ it "with a interpolated symbol" do
@undef_class.class_eval do
undef :"#{'meth'}"
end
-> { @obj.meth(5) }.should raise_error(NoMethodError)
end
-
- it "with an interpolated symbol when interpolated expression is not a String literal" do
- @undef_class.class_eval do
- undef :"#{'meth'.to_sym}"
- end
- -> { @obj.meth(5) }.should raise_error(NoMethodError)
- end
end
it "allows undefining multiple methods at a time" do
diff --git a/spec/ruby/language/variables_spec.rb b/spec/ruby/language/variables_spec.rb
index 23c2cdb557..c900c03d37 100644
--- a/spec/ruby/language/variables_spec.rb
+++ b/spec/ruby/language/variables_spec.rb
@@ -1,86 +1,6 @@
require_relative '../spec_helper'
require_relative 'fixtures/variables'
-describe "Evaluation order during assignment" do
- context "with single assignment" do
- it "evaluates from left to right" do
- obj = VariablesSpecs::EvalOrder.new
- obj.instance_eval do
- foo[0] = a
- end
-
- obj.order.should == ["foo", "a", "foo[]="]
- end
- end
-
- context "with multiple assignment" do
- ruby_version_is ""..."3.1" do
- it "does not evaluate from left to right" do
- obj = VariablesSpecs::EvalOrder.new
-
- obj.instance_eval do
- foo[0], bar.baz = a, b
- end
-
- obj.order.should == ["a", "b", "foo", "foo[]=", "bar", "bar.baz="]
- end
-
- it "cannot be used to swap variables with nested method calls" do
- node = VariablesSpecs::EvalOrder.new.node
-
- original_node = node
- original_node_left = node.left
- original_node_left_right = node.left.right
-
- node.left, node.left.right, node = node.left.right, node, node.left
- # Should evaluate in the order of:
- # RHS: node.left.right, node, node.left
- # LHS:
- # * node(original_node), original_node.left = original_node_left_right
- # * node(original_node), node.left(changed in the previous assignment to original_node_left_right),
- # original_node_left_right.right = original_node
- # * node = original_node_left
-
- node.should == original_node_left
- node.right.should_not == original_node
- node.right.left.should_not == original_node_left_right
- end
- end
-
- ruby_version_is "3.1" do
- it "evaluates from left to right, receivers first then methods" do
- obj = VariablesSpecs::EvalOrder.new
- obj.instance_eval do
- foo[0], bar.baz = a, b
- end
-
- obj.order.should == ["foo", "bar", "a", "b", "foo[]=", "bar.baz="]
- end
-
- it "can be used to swap variables with nested method calls" do
- node = VariablesSpecs::EvalOrder.new.node
-
- original_node = node
- original_node_left = node.left
- original_node_left_right = node.left.right
-
- node.left, node.left.right, node = node.left.right, node, node.left
- # Should evaluate in the order of:
- # LHS: node, node.left(original_node_left)
- # RHS: original_node_left_right, original_node, original_node_left
- # Ops:
- # * node(original_node), original_node.left = original_node_left_right
- # * original_node_left.right = original_node
- # * node = original_node_left
-
- node.should == original_node_left
- node.right.should == original_node
- node.right.left.should == original_node_left_right
- end
- end
- end
-end
-
describe "Multiple assignment" do
context "with a single RHS value" do
it "assigns a simple MLHS" do
@@ -904,11 +824,22 @@ end
describe "Instance variables" do
context "when instance variable is uninitialized" do
- it "doesn't warn about accessing uninitialized instance variable" do
- obj = Object.new
- def obj.foobar; a = @a; end
+ ruby_version_is ""..."3.0" do
+ it "warns about accessing uninitialized instance variable" do
+ obj = Object.new
+ def obj.foobar; a = @a; end
- -> { obj.foobar }.should_not complain(verbose: true)
+ -> { obj.foobar }.should complain(/warning: instance variable @a not initialized/, verbose: true)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "doesn't warn about accessing uninitialized instance variable" do
+ obj = Object.new
+ def obj.foobar; a = @a; end
+
+ -> { obj.foobar }.should_not complain(verbose: true)
+ end
end
it "doesn't warn at lazy initialization" do
diff --git a/spec/ruby/language/yield_spec.rb b/spec/ruby/language/yield_spec.rb
index 5283517636..05d713af70 100644
--- a/spec/ruby/language/yield_spec.rb
+++ b/spec/ruby/language/yield_spec.rb
@@ -186,14 +186,31 @@ describe "The yield call" do
end
describe "Using yield in a singleton class literal" do
- it 'raises a SyntaxError' do
- code = <<~RUBY
- class << Object.new
- yield
- end
- RUBY
+ ruby_version_is ""..."3.0" do
+ it 'emits a deprecation warning' do
+ code = <<~RUBY
+ def m
+ class << Object.new
+ yield
+ end
+ end
+ m { :ok }
+ RUBY
- -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/)
+ -> { eval(code) }.should complain(/warning: `yield' in class syntax will not be supported from Ruby 3.0/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it 'raises a SyntaxError' do
+ code = <<~RUBY
+ class << Object.new
+ yield
+ end
+ RUBY
+
+ -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/)
+ end
end
end
diff --git a/spec/ruby/library/English/English_spec.rb b/spec/ruby/library/English/English_spec.rb
index 4d615d1e25..480602d5e5 100644
--- a/spec/ruby/library/English/English_spec.rb
+++ b/spec/ruby/library/English/English_spec.rb
@@ -130,15 +130,13 @@ describe "English" do
$LAST_MATCH_INFO.should == $~
end
- ruby_version_is ""..."3.3" do
- it "aliases $IGNORECASE to $=" do
- $VERBOSE, verbose = nil, $VERBOSE
- begin
- $IGNORECASE.should_not be_nil
- $IGNORECASE.should == $=
- ensure
- $VERBOSE = verbose
- end
+ it "aliases $IGNORECASE to $=" do
+ $VERBOSE, verbose = nil, $VERBOSE
+ begin
+ $IGNORECASE.should_not be_nil
+ $IGNORECASE.should == $=
+ ensure
+ $VERBOSE = verbose
end
end
diff --git a/spec/ruby/library/bigdecimal/add_spec.rb b/spec/ruby/library/bigdecimal/add_spec.rb
index 542713011d..bea8b8f764 100644
--- a/spec/ruby/library/bigdecimal/add_spec.rb
+++ b/spec/ruby/library/bigdecimal/add_spec.rb
@@ -24,7 +24,7 @@ describe "BigDecimal#add" do
end
it "returns a + b with given precision" do
- # documentation states that precision is optional, but it ain't,
+ # documentation states, that precision ist optional, but it ain't,
@two.add(@one, 1).should == @three
@one .add(@two, 1).should == @three
@one.add(@one_minus, 1).should == @zero
@@ -60,7 +60,7 @@ describe "BigDecimal#add" do
end
# TODO:
-# https://blade.ruby-lang.org/ruby-core/17374
+# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17374
#
# This doesn't work on MRI and looks like a bug to me:
# one can use BigDecimal + Float, but not Bigdecimal.add(Float)
diff --git a/spec/ruby/library/bigdecimal/remainder_spec.rb b/spec/ruby/library/bigdecimal/remainder_spec.rb
index bac5f37ba9..1866f665cd 100644
--- a/spec/ruby/library/bigdecimal/remainder_spec.rb
+++ b/spec/ruby/library/bigdecimal/remainder_spec.rb
@@ -54,23 +54,21 @@ describe "BigDecimal#remainder" do
@nan.remainder(@infinity).should.nan?
end
- version_is BigDecimal::VERSION, ""..."3.1.4" do #ruby_version_is ""..."3.3" do
- it "returns NaN if Infinity is involved" do
- @infinity.remainder(@infinity).should.nan?
- @infinity.remainder(@one).should.nan?
- @infinity.remainder(@mixed).should.nan?
- @infinity.remainder(@one_minus).should.nan?
- @infinity.remainder(@frac_1).should.nan?
- @one.remainder(@infinity).should.nan?
+ it "returns NaN if Infinity is involved" do
+ @infinity.remainder(@infinity).should.nan?
+ @infinity.remainder(@one).should.nan?
+ @infinity.remainder(@mixed).should.nan?
+ @infinity.remainder(@one_minus).should.nan?
+ @infinity.remainder(@frac_1).should.nan?
+ @one.remainder(@infinity).should.nan?
- @infinity_minus.remainder(@infinity_minus).should.nan?
- @infinity_minus.remainder(@one).should.nan?
- @one.remainder(@infinity_minus).should.nan?
- @frac_2.remainder(@infinity_minus).should.nan?
+ @infinity_minus.remainder(@infinity_minus).should.nan?
+ @infinity_minus.remainder(@one).should.nan?
+ @one.remainder(@infinity_minus).should.nan?
+ @frac_2.remainder(@infinity_minus).should.nan?
- @infinity.remainder(@infinity_minus).should.nan?
- @infinity_minus.remainder(@infinity).should.nan?
- end
+ @infinity.remainder(@infinity_minus).should.nan?
+ @infinity_minus.remainder(@infinity).should.nan?
end
it "coerces arguments to BigDecimal if possible" do
diff --git a/spec/ruby/library/bigdecimal/round_spec.rb b/spec/ruby/library/bigdecimal/round_spec.rb
index fba52df65d..bfc6dbc763 100644
--- a/spec/ruby/library/bigdecimal/round_spec.rb
+++ b/spec/ruby/library/bigdecimal/round_spec.rb
@@ -228,13 +228,13 @@ describe "BigDecimal#round" do
-> { BigDecimal('-Infinity').round(2) }.should_not raise_error(FloatDomainError)
end
- version_is BigDecimal::VERSION, ''...'3.1.3' do #ruby_version_is ''...'3.2' do
+ ruby_version_is ''...'3.2' do
it 'raise for a non-existent round mode' do
-> { @p1_50.round(0, :nonsense) }.should raise_error(ArgumentError, "invalid rounding mode")
end
end
- version_is BigDecimal::VERSION, '3.1.3' do #ruby_version_is '3.2' do
+ ruby_version_is '3.2' do
it 'raise for a non-existent round mode' do
-> { @p1_50.round(0, :nonsense) }.should raise_error(ArgumentError, "invalid rounding mode (nonsense)")
end
diff --git a/spec/ruby/library/bigdecimal/shared/to_int.rb b/spec/ruby/library/bigdecimal/shared/to_int.rb
index 44b6a3c7b2..0f16251612 100644
--- a/spec/ruby/library/bigdecimal/shared/to_int.rb
+++ b/spec/ruby/library/bigdecimal/shared/to_int.rb
@@ -1,6 +1,6 @@
require 'bigdecimal'
-describe :bigdecimal_to_int, shared: true do
+describe :bigdecimal_to_int , shared: true do
it "raises FloatDomainError if BigDecimal is infinity or NaN" do
-> { BigDecimal("Infinity").send(@method) }.should raise_error(FloatDomainError)
-> { BigDecimal("NaN").send(@method) }.should raise_error(FloatDomainError)
diff --git a/spec/ruby/library/bigdecimal/to_s_spec.rb b/spec/ruby/library/bigdecimal/to_s_spec.rb
index ba9f960eb3..4f1054d38e 100644
--- a/spec/ruby/library/bigdecimal/to_s_spec.rb
+++ b/spec/ruby/library/bigdecimal/to_s_spec.rb
@@ -39,25 +39,20 @@ describe "BigDecimal#to_s" do
@bigneg.to_s("+").should_not =~ /^\+.*/
end
- it "inserts a space every n chars to fraction part, if integer n is supplied" do
+ it "inserts a space every n chars, if integer n is supplied" do
re =\
- /\A0\.314 159 265 358 979 323 846 264 338 327 950 288 419 716 939 937E1\z/i
+ /\A0\.314 159 265 358 979 323 846 264 338 327 950 288 419 716 939 937E1\z/i
@bigdec.to_s(3).should =~ re
str1 = '-123.45678 90123 45678 9'
BigDecimal("-123.45678901234567890").to_s('5F').should == str1
+ BigDecimal('1000010').to_s('5F').should == "10000 10.0"
# trailing zeroes removed
BigDecimal("1.00000000000").to_s('1F').should == "1.0"
# 0 is treated as no spaces
BigDecimal("1.2345").to_s('0F').should == "1.2345"
end
- version_is BigDecimal::VERSION, "3.1.5" do #ruby_version_is '3.3' do
- it "inserts a space every n chars to integer part, if integer n is supplied" do
- BigDecimal('1000010').to_s('5F').should == "10 00010.0"
- end
- end
-
it "can return a leading space for values > 0" do
@bigdec.to_s(" F").should =~ /\ .*/
@bigneg.to_s(" F").should_not =~ /\ .*/
@@ -88,13 +83,15 @@ describe "BigDecimal#to_s" do
end
end
- it "returns a String in US-ASCII encoding when Encoding.default_internal is nil" do
- Encoding.default_internal = nil
- BigDecimal('1.23').to_s.encoding.should equal(Encoding::US_ASCII)
- end
+ ruby_version_is "3.0" do
+ it "returns a String in US-ASCII encoding when Encoding.default_internal is nil" do
+ Encoding.default_internal = nil
+ BigDecimal('1.23').to_s.encoding.should equal(Encoding::US_ASCII)
+ end
- it "returns a String in US-ASCII encoding when Encoding.default_internal is not nil" do
- Encoding.default_internal = Encoding::IBM437
- BigDecimal('1.23').to_s.encoding.should equal(Encoding::US_ASCII)
+ it "returns a String in US-ASCII encoding when Encoding.default_internal is not nil" do
+ Encoding.default_internal = Encoding::IBM437
+ BigDecimal('1.23').to_s.encoding.should equal(Encoding::US_ASCII)
+ end
end
end
diff --git a/spec/ruby/library/cgi/escapeURIComponent_spec.rb b/spec/ruby/library/cgi/escapeURIComponent_spec.rb
deleted file mode 100644
index 2cf283c778..0000000000
--- a/spec/ruby/library/cgi/escapeURIComponent_spec.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require_relative '../../spec_helper'
-require 'cgi'
-
-ruby_version_is "3.2" do
- describe "CGI.escapeURIComponent" do
- it "escapes whitespace" do
- string = "&<>\" \xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93"
- CGI.escapeURIComponent(string).should == '%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93'
- end
-
- it "does not escape with unreserved characters" do
- string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
- CGI.escapeURIComponent(string).should == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
- end
-
- it "supports String with invalid encoding" do
- string = "\xC0\<\<".force_encoding("UTF-8")
- CGI.escapeURIComponent(string).should == "%C0%3C%3C"
- end
-
- it "processes String bytes one by one, not characters" do
- CGI.escapeURIComponent("β").should == "%CE%B2" # "β" bytes representation is CE B2
- end
-
- it "raises a TypeError with nil" do
- -> {
- CGI.escapeURIComponent(nil)
- }.should raise_error(TypeError, 'no implicit conversion of nil into String')
- end
-
- it "encodes empty string" do
- CGI.escapeURIComponent("").should == ""
- end
-
- it "encodes single whitespace" do
- CGI.escapeURIComponent(" ").should == "%20"
- end
-
- it "encodes double whitespace" do
- CGI.escapeURIComponent(" ").should == "%20%20"
- end
-
- it "preserves encoding" do
- string = "whatever".encode("ASCII-8BIT")
- CGI.escapeURIComponent(string).encoding.should == Encoding::ASCII_8BIT
- end
-
- it "uses implicit type conversion to String" do
- object = Object.new
- def object.to_str
- "a b"
- end
-
- CGI.escapeURIComponent(object).should == "a%20b"
- end
- end
-end
diff --git a/spec/ruby/library/cgi/initialize_spec.rb b/spec/ruby/library/cgi/initialize_spec.rb
index 61bc971d49..f794f157f0 100644
--- a/spec/ruby/library/cgi/initialize_spec.rb
+++ b/spec/ruby/library/cgi/initialize_spec.rb
@@ -29,8 +29,8 @@ describe "CGI#initialize when passed no arguments" do
it "does not extend self with any of the other HTML modules" do
@cgi.send(:initialize)
- @cgi.should_not be_kind_of(CGI::HtmlExtension)
@cgi.should_not be_kind_of(CGI::Html3)
+ @cgi.should_not be_kind_of(CGI::HtmlExtension)
@cgi.should_not be_kind_of(CGI::Html4)
@cgi.should_not be_kind_of(CGI::Html4Tr)
@cgi.should_not be_kind_of(CGI::Html4Fr)
diff --git a/spec/ruby/library/coverage/running_spec.rb b/spec/ruby/library/coverage/running_spec.rb
index e9cc7ada5a..745270164f 100644
--- a/spec/ruby/library/coverage/running_spec.rb
+++ b/spec/ruby/library/coverage/running_spec.rb
@@ -17,4 +17,4 @@ describe 'Coverage.running?' do
Coverage.result
Coverage.running?.should == false
end
-end
+end \ No newline at end of file
diff --git a/spec/ruby/library/coverage/supported_spec.rb b/spec/ruby/library/coverage/supported_spec.rb
deleted file mode 100644
index 78b3784ee0..0000000000
--- a/spec/ruby/library/coverage/supported_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require_relative '../../spec_helper'
-require 'coverage'
-
-describe "Coverage.supported?" do
- ruby_version_is "3.2" do
- it "returns true or false if coverage measurement is supported for the given mode" do
- [true, false].should.include?(Coverage.supported?(:lines))
- [true, false].should.include?(Coverage.supported?(:branches))
- [true, false].should.include?(Coverage.supported?(:methods))
- [true, false].should.include?(Coverage.supported?(:eval))
- end
-
- it "returns false for not existing modes" do
- Coverage.supported?(:foo).should == false
- Coverage.supported?(:bar).should == false
- end
-
- it "raise TypeError if argument is not Symbol" do
- -> {
- Coverage.supported?("lines")
- }.should raise_error(TypeError, "wrong argument type String (expected Symbol)")
-
- -> {
- Coverage.supported?([])
- }.should raise_error(TypeError, "wrong argument type Array (expected Symbol)")
-
- -> {
- Coverage.supported?(1)
- }.should raise_error(TypeError, "wrong argument type Integer (expected Symbol)")
- end
- end
-end
diff --git a/spec/ruby/library/date/deconstruct_keys_spec.rb b/spec/ruby/library/date/deconstruct_keys_spec.rb
deleted file mode 100644
index 92579e35c7..0000000000
--- a/spec/ruby/library/date/deconstruct_keys_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-require_relative '../../spec_helper'
-require 'date'
-date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
-
-version_is date_version, "3.3" do #ruby_version_is "3.2" do
- describe "Date#deconstruct_keys" do
- it "returns whole hash for nil as an argument" do
- d = Date.new(2022, 10, 5)
- d.deconstruct_keys(nil).should == { year: 2022, month: 10, day: 5, yday: 278, wday: 3 }
- end
-
- it "returns only specified keys" do
- d = Date.new(2022, 10, 5)
- d.deconstruct_keys([:year, :month]).should == { year: 2022, month: 10 }
- end
-
- it "requires one argument" do
- -> {
- Date.new(2022, 10, 5).deconstruct_keys
- }.should raise_error(ArgumentError)
- end
-
- it "it raises error when argument is neither nil nor array" do
- d = Date.new(2022, 10, 5)
-
- -> { d.deconstruct_keys(1) }.should raise_error(TypeError, "wrong argument type Integer (expected Array or nil)")
- -> { d.deconstruct_keys("asd") }.should raise_error(TypeError, "wrong argument type String (expected Array or nil)")
- -> { d.deconstruct_keys(:x) }.should raise_error(TypeError, "wrong argument type Symbol (expected Array or nil)")
- -> { d.deconstruct_keys({}) }.should raise_error(TypeError, "wrong argument type Hash (expected Array or nil)")
- end
-
- it "returns {} when passed []" do
- Date.new(2022, 10, 5).deconstruct_keys([]).should == {}
- end
-
- it "ignores non-Symbol keys" do
- Date.new(2022, 10, 5).deconstruct_keys(['year', []]).should == {}
- end
-
- it "ignores not existing Symbol keys" do
- Date.new(2022, 10, 5).deconstruct_keys([:year, :a]).should == { year: 2022 }
- end
- end
-end
diff --git a/spec/ruby/library/date/iso8601_spec.rb b/spec/ruby/library/date/iso8601_spec.rb
index af66845a6b..a29652014e 100644
--- a/spec/ruby/library/date/iso8601_spec.rb
+++ b/spec/ruby/library/date/iso8601_spec.rb
@@ -22,18 +22,6 @@ describe "Date.iso8601" do
d.should == Date.civil(-4712, 1, 1)
end
- it "raises a Date::Error if the argument is a invalid Date" do
- -> {
- Date.iso8601('invalid')
- }.should raise_error(Date::Error, "invalid date")
- end
-
- it "raises a Date::Error when passed a nil" do
- -> {
- Date.iso8601(nil)
- }.should raise_error(Date::Error, "invalid date")
- end
-
it "raises a TypeError when passed an Object" do
-> { Date.iso8601(Object.new) }.should raise_error(TypeError)
end
@@ -44,13 +32,4 @@ describe "Date._iso8601" do
h = Date._iso8601('invalid')
h.should == {}
end
-
- it "returns an empty hash if the argument is nil" do
- h = Date._iso8601(nil)
- h.should == {}
- end
-
- it "raises a TypeError when passed an Object" do
- -> { Date._iso8601(Object.new) }.should raise_error(TypeError)
- end
end
diff --git a/spec/ruby/library/date/new_spec.rb b/spec/ruby/library/date/new_spec.rb
index cb64cabce6..18120118c0 100644
--- a/spec/ruby/library/date/new_spec.rb
+++ b/spec/ruby/library/date/new_spec.rb
@@ -1,6 +1,7 @@
require 'date'
require_relative '../../spec_helper'
require_relative 'shared/civil'
+require_relative 'shared/new_bang'
describe "Date.new" do
it_behaves_like :date_civil, :new
diff --git a/spec/ruby/library/date/parse_spec.rb b/spec/ruby/library/date/parse_spec.rb
index 5ef4f6e9b5..bfbe86fbac 100644
--- a/spec/ruby/library/date/parse_spec.rb
+++ b/spec/ruby/library/date/parse_spec.rb
@@ -93,7 +93,7 @@ describe "Date#parse with '.' separator" do
@sep = '.'
end
- it_should_behave_like :date_parse
+ it_should_behave_like "date_parse"
end
describe "Date#parse with '/' separator" do
@@ -101,7 +101,7 @@ describe "Date#parse with '/' separator" do
@sep = '/'
end
- it_should_behave_like :date_parse
+ it_should_behave_like "date_parse"
end
describe "Date#parse with ' ' separator" do
@@ -109,7 +109,7 @@ describe "Date#parse with ' ' separator" do
@sep = ' '
end
- it_should_behave_like :date_parse
+ it_should_behave_like "date_parse"
end
describe "Date#parse with '/' separator US-style" do
@@ -117,7 +117,7 @@ describe "Date#parse with '/' separator US-style" do
@sep = '/'
end
- it_should_behave_like :date_parse_us
+ it_should_behave_like "date_parse_us"
end
describe "Date#parse with '-' separator EU-style" do
@@ -125,7 +125,7 @@ describe "Date#parse with '-' separator EU-style" do
@sep = '-'
end
- it_should_behave_like :date_parse_eu
+ it_should_behave_like "date_parse_eu"
end
describe "Date#parse(.)" do
diff --git a/spec/ruby/library/date/shared/new_bang.rb b/spec/ruby/library/date/shared/new_bang.rb
new file mode 100644
index 0000000000..90f1b432f0
--- /dev/null
+++ b/spec/ruby/library/date/shared/new_bang.rb
@@ -0,0 +1,14 @@
+describe :date_new_bang, shared: true do
+
+ it "returns a new Date object set to Astronomical Julian Day 0 if no arguments passed" do
+ d = Date.send(@method)
+ d.ajd.should == 0
+ end
+
+ it "accepts astronomical julian day number, offset as a fraction of a day and returns a new Date object" do
+ d = Date.send(@method, 10, 0.5)
+ d.ajd.should == 10
+ d.jd.should == 11
+ end
+
+end
diff --git a/spec/ruby/library/date/shared/parse.rb b/spec/ruby/library/date/shared/parse.rb
index 40af908386..1015285e04 100644
--- a/spec/ruby/library/date/shared/parse.rb
+++ b/spec/ruby/library/date/shared/parse.rb
@@ -13,7 +13,7 @@ describe :date_parse, shared: true do
d.day.should == 23
end
- it "can parse a 'DD mmm YYYY' string into a Date object" do
+ it "can parse a 'mmm DD YYYY' string into a Date object" do
d = Date.parse("23#{@sep}feb#{@sep}2008")
d.year.should == 2008
d.month.should == 2
@@ -42,7 +42,7 @@ describe :date_parse, shared: true do
d.should == Date.civil(2005, 11, 5)
end
- it "can parse a day, month name and year into a Date object" do
+ it "can parse a year, day and month name into a Date object" do
d = Date.parse("5th#{@sep}november#{@sep}2005")
d.should == Date.civil(2005, 11, 5)
end
diff --git a/spec/ruby/library/date/shared/parse_eu.rb b/spec/ruby/library/date/shared/parse_eu.rb
index 3819524a57..ecb15e3c0e 100644
--- a/spec/ruby/library/date/shared/parse_eu.rb
+++ b/spec/ruby/library/date/shared/parse_eu.rb
@@ -7,28 +7,28 @@ describe :date_parse_eu, shared: true do
d.day.should == 1
end
- it "can parse a DD-MM-YYYY string into a Date object" do
+ it "can parse a MM-DD-YYYY string into a Date object" do
d = Date.parse("10#{@sep}01#{@sep}2007")
d.year.should == 2007
d.month.should == 1
d.day.should == 10
end
- it "can parse a YY-MM-DD string into a Date object" do
+ it "can parse a MM-DD-YY string into a Date object" do
d = Date.parse("10#{@sep}01#{@sep}07")
d.year.should == 2010
d.month.should == 1
d.day.should == 7
end
- it "can parse a YY-MM-DD string into a Date object NOT using the year digits as 20XX" do
+ it "can parse a MM-DD-YY string into a Date object NOT using the year digits as 20XX" do
d = Date.parse("10#{@sep}01#{@sep}07", false)
d.year.should == 10
d.month.should == 1
d.day.should == 7
end
- it "can parse a YY-MM-DD string into a Date object using the year digits as 20XX" do
+ it "can parse a MM-DD-YY string into a Date object using the year digits as 20XX" do
d = Date.parse("10#{@sep}01#{@sep}07", true)
d.year.should == 2010
d.month.should == 1
diff --git a/spec/ruby/library/date/shared/parse_us.rb b/spec/ruby/library/date/shared/parse_us.rb
index 17e2fc96c1..7be62b1af1 100644
--- a/spec/ruby/library/date/shared/parse_us.rb
+++ b/spec/ruby/library/date/shared/parse_us.rb
@@ -6,28 +6,28 @@ describe :date_parse_us, shared: true do
d.day.should == 1
end
- it "parses a DD#{@sep}MM#{@sep}YYYY string into a Date object" do
+ it "parses a MM#{@sep}DD#{@sep}YYYY string into a Date object" do
d = Date.parse("10#{@sep}01#{@sep}2007")
d.year.should == 2007
d.month.should == 1
d.day.should == 10
end
- it "parses a YY#{@sep}MM#{@sep}DD string into a Date object" do
+ it "parses a MM#{@sep}DD#{@sep}YY string into a Date object" do
d = Date.parse("10#{@sep}01#{@sep}07")
d.year.should == 2010
d.month.should == 1
d.day.should == 7
end
- it "parses a YY#{@sep}MM#{@sep}DD string into a Date object NOT using the year digits as 20XX" do
+ it "parses a MM#{@sep}DD#{@sep}YY string into a Date object NOT using the year digits as 20XX" do
d = Date.parse("10#{@sep}01#{@sep}07", false)
d.year.should == 10
d.month.should == 1
d.day.should == 7
end
- it "parses a YY#{@sep}MM#{@sep}DD string into a Date object using the year digits as 20XX" do
+ it "parses a MM#{@sep}DD#{@sep}YY string into a Date object using the year digits as 20XX" do
d = Date.parse("10#{@sep}01#{@sep}07", true)
d.year.should == 2010
d.month.should == 1
diff --git a/spec/ruby/library/date/strftime_spec.rb b/spec/ruby/library/date/strftime_spec.rb
index b5232a2073..8b1ebe061c 100644
--- a/spec/ruby/library/date/strftime_spec.rb
+++ b/spec/ruby/library/date/strftime_spec.rb
@@ -1,7 +1,5 @@
-require_relative "../../spec_helper"
require 'date'
require_relative '../../shared/time/strftime_for_date'
-date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
describe "Date#strftime" do
before :all do
@@ -24,14 +22,14 @@ describe "Date#strftime" do
end
# %v is %e-%b-%Y for Date/DateTime
- version_is date_version, ""..."3.2" do #ruby_version_is ""..."3.1" do
+ ruby_version_is ""..."3.1" do
it "should be able to show the commercial week" do
@date.strftime("%v").should == " 9-Apr-2000"
@date.strftime("%v").should == @date.strftime('%e-%b-%Y')
end
end
- version_is date_version, "3.2" do #ruby_version_is "3.1" do
+ ruby_version_is "3.1" do
it "should be able to show the commercial week" do
@date.strftime("%v").should == " 9-APR-2000"
@date.strftime("%v").should != @date.strftime('%e-%b-%Y')
diff --git a/spec/ruby/library/datetime/deconstruct_keys_spec.rb b/spec/ruby/library/datetime/deconstruct_keys_spec.rb
deleted file mode 100644
index 77ceaa51c4..0000000000
--- a/spec/ruby/library/datetime/deconstruct_keys_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require_relative '../../spec_helper'
-require 'date'
-date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
-
-version_is date_version, "3.3" do #ruby_version_is "3.2" do
- describe "DateTime#deconstruct_keys" do
- it "returns whole hash for nil as an argument" do
- d = DateTime.new(2022, 10, 5, 13, 30)
- res = { year: 2022, month: 10, day: 5, yday: 278, wday: 3, hour: 13,
- min: 30, sec: 0, sec_fraction: (0/1), zone: "+00:00" }
- d.deconstruct_keys(nil).should == res
- end
-
- it "returns only specified keys" do
- d = DateTime.new(2022, 10, 5, 13, 39)
- d.deconstruct_keys([:zone, :hour]).should == { zone: "+00:00", hour: 13 }
- end
-
- it "requires one argument" do
- -> {
- DateTime.new(2022, 10, 5, 13, 30).deconstruct_keys
- }.should raise_error(ArgumentError)
- end
-
- it "it raises error when argument is neither nil nor array" do
- d = DateTime.new(2022, 10, 5, 13, 30)
-
- -> { d.deconstruct_keys(1) }.should raise_error(TypeError, "wrong argument type Integer (expected Array or nil)")
- -> { d.deconstruct_keys("asd") }.should raise_error(TypeError, "wrong argument type String (expected Array or nil)")
- -> { d.deconstruct_keys(:x) }.should raise_error(TypeError, "wrong argument type Symbol (expected Array or nil)")
- -> { d.deconstruct_keys({}) }.should raise_error(TypeError, "wrong argument type Hash (expected Array or nil)")
- end
-
- it "returns {} when passed []" do
- DateTime.new(2022, 10, 5, 13, 30).deconstruct_keys([]).should == {}
- end
-
- it "ignores non-Symbol keys" do
- DateTime.new(2022, 10, 5, 13, 30).deconstruct_keys(['year', []]).should == {}
- end
-
- it "ignores not existing Symbol keys" do
- DateTime.new(2022, 10, 5, 13, 30).deconstruct_keys([:year, :a]).should == { year: 2022 }
- end
- end
-end
diff --git a/spec/ruby/library/datetime/rfc2822_spec.rb b/spec/ruby/library/datetime/rfc2822_spec.rb
index 83f7fa8d5b..70bfca60b4 100644
--- a/spec/ruby/library/datetime/rfc2822_spec.rb
+++ b/spec/ruby/library/datetime/rfc2822_spec.rb
@@ -3,8 +3,4 @@ require 'date'
describe "DateTime.rfc2822" do
it "needs to be reviewed for spec completeness"
-
- it "raises DateError if passed nil" do
- -> { DateTime.rfc2822(nil) }.should raise_error(Date::Error, "invalid date")
- end
end
diff --git a/spec/ruby/library/datetime/strftime_spec.rb b/spec/ruby/library/datetime/strftime_spec.rb
index abb0838e8e..725bcafb0d 100644
--- a/spec/ruby/library/datetime/strftime_spec.rb
+++ b/spec/ruby/library/datetime/strftime_spec.rb
@@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require 'date'
require_relative '../../shared/time/strftime_for_date'
require_relative '../../shared/time/strftime_for_time'
-date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
describe "DateTime#strftime" do
before :all do
@@ -34,14 +33,14 @@ describe "DateTime#strftime" do
end
# %v is %e-%b-%Y for Date/DateTime
- version_is date_version, ""..."3.2" do #ruby_version_is ""..."3.1" do
+ ruby_version_is ""..."3.1" do
it "should be able to show the commercial week" do
@time.strftime("%v").should == " 3-Feb-2001"
@time.strftime("%v").should == @time.strftime('%e-%b-%Y')
end
end
- version_is date_version, "3.2" do #ruby_version_is "3.1" do
+ ruby_version_is "3.1" do
it "should be able to show the commercial week" do
@time.strftime("%v").should == " 3-FEB-2001"
@time.strftime("%v").should != @time.strftime('%e-%b-%Y')
diff --git a/spec/ruby/library/datetime/to_time_spec.rb b/spec/ruby/library/datetime/to_time_spec.rb
index 09e6192e7f..95eca864da 100644
--- a/spec/ruby/library/datetime/to_time_spec.rb
+++ b/spec/ruby/library/datetime/to_time_spec.rb
@@ -1,6 +1,5 @@
require_relative '../../spec_helper'
require 'date'
-date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
describe "DateTime#to_time" do
it "yields a new Time object" do
@@ -19,7 +18,8 @@ describe "DateTime#to_time" do
time.sec.should == 59
end
- version_is date_version, '3.2.3' do #ruby_version_is "3.2" do
+ date_version = defined?(Date::VERSION) ? Date::VERSION : '0.0.0'
+ version_is(date_version, '3.2.3') do
it "returns a Time representing the same instant before Gregorian" do
datetime = DateTime.civil(1582, 10, 4, 23, 58, 59)
time = datetime.to_time.utc
diff --git a/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb b/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb
index 3975e5208b..729cfc96c6 100644
--- a/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb
+++ b/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require 'delegate'
describe "DelegateClass#respond_to_missing?" do
diff --git a/spec/ruby/library/digest/instance/shared/update.rb b/spec/ruby/library/digest/instance/shared/update.rb
index 17779e54a4..dccc8f80df 100644
--- a/spec/ruby/library/digest/instance/shared/update.rb
+++ b/spec/ruby/library/digest/instance/shared/update.rb
@@ -3,6 +3,6 @@ describe :digest_instance_update, shared: true do
c = Class.new do
include Digest::Instance
end
- -> { c.new.send(@method, "test") }.should raise_error(RuntimeError)
+ -> { c.new.update("test") }.should raise_error(RuntimeError)
end
end
diff --git a/spec/ruby/library/digest/md5/shared/sample.rb b/spec/ruby/library/digest/md5/shared/sample.rb
new file mode 100644
index 0000000000..2bb4f658b1
--- /dev/null
+++ b/spec/ruby/library/digest/md5/shared/sample.rb
@@ -0,0 +1,17 @@
+# -*- encoding: binary -*-
+
+require 'digest/md5'
+
+module MD5Constants
+
+ Contents = "Ipsum is simply dummy text of the printing and typesetting industry. \nLorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. \nIt has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. \nIt was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
+
+ Klass = ::Digest::MD5
+ BlockLength = 64
+ DigestLength = 16
+ BlankDigest = "\324\035\214\331\217\000\262\004\351\200\t\230\354\370B~"
+ Digest = "\2473\267qw\276\364\343\345\320\304\350\313\314\217n"
+ BlankHexdigest = "d41d8cd98f00b204e9800998ecf8427e"
+ Hexdigest = "a733b77177bef4e3e5d0c4e8cbcc8f6e"
+
+end
diff --git a/spec/ruby/library/erb/new_spec.rb b/spec/ruby/library/erb/new_spec.rb
index a5aeeaeed1..4d7f7bf36a 100644
--- a/spec/ruby/library/erb/new_spec.rb
+++ b/spec/ruby/library/erb/new_spec.rb
@@ -140,7 +140,7 @@ END
end
describe "warning about arguments" do
- version_is ERB.version, "2.2.1" do #ruby_version_is "3.1" do
+ ruby_version_is "3.1" do
it "warns when passed safe_level and later arguments" do
-> {
ERB.new(@eruby_str, nil, '%')
diff --git a/spec/ruby/library/etc/confstr_spec.rb b/spec/ruby/library/etc/confstr_spec.rb
index 5b43461150..41a970a918 100644
--- a/spec/ruby/library/etc/confstr_spec.rb
+++ b/spec/ruby/library/etc/confstr_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../spec_helper'
+require File.expand_path('../../../spec_helper', __FILE__)
require 'etc'
platform_is_not :windows, :android do
diff --git a/spec/ruby/library/etc/passwd_spec.rb b/spec/ruby/library/etc/passwd_spec.rb
index 7157fd3f2e..d61dada451 100644
--- a/spec/ruby/library/etc/passwd_spec.rb
+++ b/spec/ruby/library/etc/passwd_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../spec_helper'
+require File.expand_path('../../../spec_helper', __FILE__)
require 'etc'
platform_is_not :windows do
diff --git a/spec/ruby/library/etc/sysconf_spec.rb b/spec/ruby/library/etc/sysconf_spec.rb
index 1f2c7a770f..e7d59d1b22 100644
--- a/spec/ruby/library/etc/sysconf_spec.rb
+++ b/spec/ruby/library/etc/sysconf_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../spec_helper'
+require File.expand_path('../../../spec_helper', __FILE__)
require 'etc'
platform_is_not :windows do
diff --git a/spec/ruby/library/etc/sysconfdir_spec.rb b/spec/ruby/library/etc/sysconfdir_spec.rb
index 8538faa65b..d54299c513 100644
--- a/spec/ruby/library/etc/sysconfdir_spec.rb
+++ b/spec/ruby/library/etc/sysconfdir_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../spec_helper'
+require File.expand_path('../../../spec_helper', __FILE__)
require 'etc'
describe "Etc.sysconfdir" do
diff --git a/spec/ruby/library/etc/systmpdir_spec.rb b/spec/ruby/library/etc/systmpdir_spec.rb
index 5b007aa9f9..99c82903f8 100644
--- a/spec/ruby/library/etc/systmpdir_spec.rb
+++ b/spec/ruby/library/etc/systmpdir_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../spec_helper'
+require File.expand_path('../../../spec_helper', __FILE__)
require 'etc'
describe "Etc.systmpdir" do
diff --git a/spec/ruby/library/etc/uname_spec.rb b/spec/ruby/library/etc/uname_spec.rb
deleted file mode 100644
index a42558f593..0000000000
--- a/spec/ruby/library/etc/uname_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-require_relative '../../spec_helper'
-require 'etc'
-
-describe "Etc.uname" do
- it "returns a Hash with the documented keys" do
- uname = Etc.uname
- uname.should be_kind_of(Hash)
- uname.should.key?(:sysname)
- uname.should.key?(:nodename)
- uname.should.key?(:release)
- uname.should.key?(:version)
- uname.should.key?(:machine)
- end
-end
diff --git a/spec/ruby/library/expect/expect_spec.rb b/spec/ruby/library/expect/expect_spec.rb
index 76ea3d5451..a7041d42ee 100644
--- a/spec/ruby/library/expect/expect_spec.rb
+++ b/spec/ruby/library/expect/expect_spec.rb
@@ -1,6 +1,5 @@
-require_relative '../../spec_helper'
-
platform_is_not :windows do
+ require_relative '../../spec_helper'
require 'expect'
describe "IO#expect" do
diff --git a/spec/ruby/library/fiber/current_spec.rb b/spec/ruby/library/fiber/current_spec.rb
index 1467a88d0d..e67d7d050a 100644
--- a/spec/ruby/library/fiber/current_spec.rb
+++ b/spec/ruby/library/fiber/current_spec.rb
@@ -3,12 +3,6 @@ require_relative '../../spec_helper'
require 'fiber'
describe "Fiber.current" do
- ruby_version_is "3.1" do
- it "is available without an extra require" do
- ruby_exe("print Fiber.current.class", options: '--disable-gems --disable-did-you-mean').should == "Fiber"
- end
- end
-
it "returns the root Fiber when called outside of a Fiber" do
root = Fiber.current
root.should be_an_instance_of(Fiber)
@@ -48,11 +42,22 @@ describe "Fiber.current" do
fiber3 = Fiber.new do
states << :fiber3
fiber2.transfer
- states << :fiber3_terminated
+ ruby_version_is '3.0' do
+ states << :fiber3_terminated
+ end
+ ruby_version_is '' ... '3.0' do
+ flunk
+ end
end
fiber3.resume
- states.should == [:fiber3, :fiber2, :fiber, :fiber3_terminated]
+ ruby_version_is "" ... "3.0" do
+ states.should == [:fiber3, :fiber2, :fiber]
+ end
+
+ ruby_version_is "3.0" do
+ states.should == [:fiber3, :fiber2, :fiber, :fiber3_terminated]
+ end
end
end
diff --git a/spec/ruby/library/fiber/resume_spec.rb b/spec/ruby/library/fiber/resume_spec.rb
index fd69d3ba99..8b7c104a6f 100644
--- a/spec/ruby/library/fiber/resume_spec.rb
+++ b/spec/ruby/library/fiber/resume_spec.rb
@@ -3,16 +3,33 @@ require_relative '../../spec_helper'
require 'fiber'
describe "Fiber#resume" do
- it "can work with Fiber#transfer" do
- fiber1 = Fiber.new { true }
- fiber2 = Fiber.new { fiber1.transfer; Fiber.yield 10 ; Fiber.yield 20; raise }
- fiber2.resume.should == 10
- fiber2.resume.should == 20
+ ruby_version_is '' ... '3.0' do
+ it "raises a FiberError if the Fiber has transferred control to another Fiber" do
+ fiber1 = Fiber.new { true }
+ fiber2 = Fiber.new { fiber1.transfer; Fiber.yield }
+ fiber2.resume
+ -> { fiber2.resume }.should raise_error(FiberError)
+ end
+
+ it "raises a FiberError if the Fiber attempts to resume a resuming fiber" do
+ root_fiber = Fiber.current
+ fiber1 = Fiber.new { root_fiber.resume }
+ -> { fiber1.resume }.should raise_error(FiberError, /double resume/)
+ end
end
- it "raises a FiberError if the Fiber attempts to resume a resuming fiber" do
- root_fiber = Fiber.current
- fiber1 = Fiber.new { root_fiber.resume }
- -> { fiber1.resume }.should raise_error(FiberError, /attempt to resume a resuming fiber/)
+ ruby_version_is '3.0' do
+ it "can work with Fiber#transfer" do
+ fiber1 = Fiber.new { true }
+ fiber2 = Fiber.new { fiber1.transfer; Fiber.yield 10 ; Fiber.yield 20; raise }
+ fiber2.resume.should == 10
+ fiber2.resume.should == 20
+ end
+
+ it "raises a FiberError if the Fiber attempts to resume a resuming fiber" do
+ root_fiber = Fiber.current
+ fiber1 = Fiber.new { root_fiber.resume }
+ -> { fiber1.resume }.should raise_error(FiberError, /attempt to resume a resuming fiber/)
+ end
end
end
diff --git a/spec/ruby/library/fiber/transfer_spec.rb b/spec/ruby/library/fiber/transfer_spec.rb
index e20d51352e..7af548da1a 100644
--- a/spec/ruby/library/fiber/transfer_spec.rb
+++ b/spec/ruby/library/fiber/transfer_spec.rb
@@ -11,7 +11,13 @@ describe "Fiber#transfer" do
it "transfers control from one Fiber to another when called from a Fiber" do
fiber1 = Fiber.new { :fiber1 }
fiber2 = Fiber.new { fiber1.transfer; :fiber2 }
- fiber2.resume.should == :fiber2
+
+ ruby_version_is '' ... '3.0' do
+ fiber2.resume.should == :fiber1
+ end
+ ruby_version_is '3.0' do
+ fiber2.resume.should == :fiber2
+ end
end
it "returns to the root Fiber when finished" do
@@ -34,12 +40,24 @@ describe "Fiber#transfer" do
states.should == [:start, :end]
end
- it "can not transfer control to a Fiber that has suspended by Fiber.yield" do
- states = []
- fiber1 = Fiber.new { states << :fiber1 }
- fiber2 = Fiber.new { states << :fiber2_start; Fiber.yield fiber1.transfer; states << :fiber2_end}
- fiber2.resume.should == [:fiber2_start, :fiber1]
- -> { fiber2.transfer }.should raise_error(FiberError)
+ ruby_version_is '' ... '3.0' do
+ it "can transfer control to a Fiber that has transferred to another Fiber" do
+ states = []
+ fiber1 = Fiber.new { states << :fiber1 }
+ fiber2 = Fiber.new { states << :fiber2_start; fiber1.transfer; states << :fiber2_end}
+ fiber2.resume.should == [:fiber2_start, :fiber1]
+ fiber2.transfer.should == [:fiber2_start, :fiber1, :fiber2_end]
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "can not transfer control to a Fiber that has suspended by Fiber.yield" do
+ states = []
+ fiber1 = Fiber.new { states << :fiber1 }
+ fiber2 = Fiber.new { states << :fiber2_start; Fiber.yield fiber1.transfer; states << :fiber2_end}
+ fiber2.resume.should == [:fiber2_start, :fiber1]
+ -> { fiber2.transfer }.should raise_error(FiberError)
+ end
end
it "raises a FiberError when transferring to a Fiber which resumes itself" do
@@ -83,4 +101,28 @@ describe "Fiber#transfer" do
thread.join
states.should == [0, 1, 2, 3]
end
+
+ ruby_version_is "" ... "3.0" do
+ it "runs until Fiber.yield" do
+ obj = mock('obj')
+ obj.should_not_receive(:do)
+ fiber = Fiber.new { 1 + 2; Fiber.yield; obj.do }
+ fiber.transfer
+ end
+
+ it "resumes from the last call to Fiber.yield on subsequent invocations" do
+ fiber = Fiber.new { Fiber.yield :first; :second }
+ fiber.transfer.should == :first
+ fiber.transfer.should == :second
+ end
+
+ it "sets the block parameters to its arguments on the first invocation" do
+ first = mock('first')
+ first.should_receive(:arg).with(:first).twice
+
+ fiber = Fiber.new { |arg| first.arg arg; Fiber.yield; first.arg arg; }
+ fiber.transfer :first
+ fiber.transfer :second
+ end
+ end
end
diff --git a/spec/ruby/library/io-wait/fixtures/classes.rb b/spec/ruby/library/io-wait/fixtures/classes.rb
deleted file mode 100644
index 837c7edd06..0000000000
--- a/spec/ruby/library/io-wait/fixtures/classes.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module IOWaitSpec
- def self.exhaust_write_buffer(io)
- written = 0
- buf = " " * 4096
-
- begin
- written += io.write_nonblock(buf)
- rescue Errno::EAGAIN, Errno::EWOULDBLOCK
- return written
- end while true
- end
-end
diff --git a/spec/ruby/library/io-wait/wait_spec.rb b/spec/ruby/library/io-wait/wait_spec.rb
deleted file mode 100644
index 3861281277..0000000000
--- a/spec/ruby/library/io-wait/wait_spec.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
-
-ruby_version_is ''...'3.2' do
- require 'io/wait'
-end
-
-describe "IO#wait" do
- before :each do
- @io = File.new(__FILE__ )
-
- if /mswin|mingw/ =~ RUBY_PLATFORM
- require 'socket'
- @r, @w = Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM, 0)
- else
- @r, @w = IO.pipe
- end
- end
-
- after :each do
- @io.close unless @io.closed?
-
- @r.close unless @r.closed?
- @w.close unless @w.closed?
- end
-
- context "[events, timeout] passed" do
- ruby_version_is ""..."3.2" do
- it "returns self when the READABLE event is ready during the timeout" do
- @w.write('data to read')
- @r.wait(IO::READABLE, 2).should.equal?(@r)
- end
-
- it "returns self when the WRITABLE event is ready during the timeout" do
- @w.wait(IO::WRITABLE, 0).should.equal?(@w)
- end
- end
-
- ruby_version_is "3.2" do
- it "returns events mask when the READABLE event is ready during the timeout" do
- @w.write('data to read')
- @r.wait(IO::READABLE, 2).should == IO::READABLE
- end
-
- it "returns events mask when the WRITABLE event is ready during the timeout" do
- @w.wait(IO::WRITABLE, 0).should == IO::WRITABLE
- end
- end
-
- it "waits for the READABLE event to be ready" do
- queue = Queue.new
- thread = Thread.new { queue.pop; sleep 1; @w.write('data to read') };
-
- queue.push('signal');
- @r.wait(IO::READABLE, 2).should_not == nil
-
- thread.join
- end
-
- it "waits for the WRITABLE event to be ready" do
- written_bytes = IOWaitSpec.exhaust_write_buffer(@w)
-
- queue = Queue.new
- thread = Thread.new { queue.pop; sleep 1; @r.read(written_bytes) };
-
- queue.push('signal');
- @w.wait(IO::WRITABLE, 2).should_not == nil
-
- thread.join
- end
-
- it "returns nil when the READABLE event is not ready during the timeout" do
- @w.wait(IO::READABLE, 0).should == nil
- end
-
- it "returns nil when the WRITABLE event is not ready during the timeout" do
- IOWaitSpec.exhaust_write_buffer(@w)
- @w.wait(IO::WRITABLE, 0).should == nil
- end
-
- it "raises IOError when io is closed (closed stream (IOError))" do
- @io.close
- -> { @io.wait(IO::READABLE, 0) }.should raise_error(IOError, "closed stream")
- end
-
- ruby_version_is "3.2" do
- it "raises ArgumentError when events is not positive" do
- -> { @w.wait(0, 0) }.should raise_error(ArgumentError, "Events must be positive integer!")
- -> { @w.wait(-1, 0) }.should raise_error(ArgumentError, "Events must be positive integer!")
- end
- end
- end
-
- context "[timeout, mode] passed" do
- it "accepts :r, :read, :readable mode to check READABLE event" do
- @io.wait(0, :r).should == @io
- @io.wait(0, :read).should == @io
- @io.wait(0, :readable).should == @io
- end
-
- it "accepts :w, :write, :writable mode to check WRITABLE event" do
- @io.wait(0, :w).should == @io
- @io.wait(0, :write).should == @io
- @io.wait(0, :writable).should == @io
- end
-
- it "accepts :rw, :read_write, :readable_writable mode to check READABLE and WRITABLE events" do
- @io.wait(0, :rw).should == @io
- @io.wait(0, :read_write).should == @io
- @io.wait(0, :readable_writable).should == @io
- end
-
- it "accepts a list of modes" do
- @io.wait(0, :r, :w, :rw).should == @io
- end
-
- # It works at least since 2.7 but by some reason may fail on 3.1
- ruby_version_is "3.2" do
- it "accepts timeout and mode in any order" do
- @io.wait(0, :r).should == @io
- @io.wait(:r, 0).should == @io
- @io.wait(:r, 0, :w).should == @io
- end
- end
-
- it "raises ArgumentError when passed wrong Symbol value as mode argument" do
- -> { @io.wait(0, :wrong) }.should raise_error(ArgumentError, "unsupported mode: wrong")
- end
-
- # It works since 3.0 but by some reason may fail on 3.1
- ruby_version_is "3.2" do
- it "raises ArgumentError when several Integer arguments passed" do
- -> { @w.wait(0, 10, :r) }.should raise_error(ArgumentError, "timeout given more than once")
- end
- end
-
- ruby_version_is "3.2" do
- it "raises IOError when io is closed (closed stream (IOError))" do
- @io.close
- -> { @io.wait(0, :r) }.should raise_error(IOError, "closed stream")
- end
- end
- end
-end
diff --git a/spec/ruby/library/ipaddr/new_spec.rb b/spec/ruby/library/ipaddr/new_spec.rb
index 714c1e2f1a..053928c3cf 100644
--- a/spec/ruby/library/ipaddr/new_spec.rb
+++ b/spec/ruby/library/ipaddr/new_spec.rb
@@ -77,13 +77,7 @@ describe "IPAddr#new" do
a.family.should == Socket::AF_INET6
end
- ipaddr_version = if defined?(IPAddr::VERSION) #ruby_version_is ""..."3.1" do
- IPAddr::VERSION
- else
- "1.2.2"
- end
-
- version_is ipaddr_version, ""..."1.2.3" do #ruby_version_is ""..."3.1" do
+ ruby_version_is ""..."3.1" do
it "raises on incorrect IPAddr strings" do
[
["fe80::1%fxp0"],
@@ -99,7 +93,7 @@ describe "IPAddr#new" do
end
end
- version_is ipaddr_version, "1.2.3" do #ruby_version_is "3.1" do
+ ruby_version_is "3.1" do
it "raises on incorrect IPAddr strings" do
[
["::1/255.255.255.0"],
diff --git a/spec/ruby/library/logger/device/close_spec.rb b/spec/ruby/library/logger/device/close_spec.rb
index 1db5d582a7..7c5e118d56 100644
--- a/spec/ruby/library/logger/device/close_spec.rb
+++ b/spec/ruby/library/logger/device/close_spec.rb
@@ -15,8 +15,17 @@ describe "Logger::LogDevice#close" do
rm_r @file_path
end
- it "closes the LogDevice's stream" do
- @device.close
- -> { @device.write("Test") }.should complain(/\Alog shifting failed\./)
+ version_is Logger::VERSION, ""..."1.4.0" do
+ it "closes the LogDevice's stream" do
+ @device.close
+ -> { @device.write("Test") }.should complain(/\Alog writing failed\./)
+ end
+ end
+
+ version_is Logger::VERSION, "1.4.0" do
+ it "closes the LogDevice's stream" do
+ @device.close
+ -> { @device.write("Test") }.should complain(/\Alog shifting failed\./)
+ end
end
end
diff --git a/spec/ruby/library/logger/device/write_spec.rb b/spec/ruby/library/logger/device/write_spec.rb
index 87ecf2ad6a..cd2d7e27a9 100644
--- a/spec/ruby/library/logger/device/write_spec.rb
+++ b/spec/ruby/library/logger/device/write_spec.rb
@@ -35,8 +35,17 @@ describe "Logger::LogDevice#write" do
rm_r path
end
- it "fails if the device is already closed" do
- @device.close
- -> { @device.write "foo" }.should complain(/\Alog shifting failed\./)
+ version_is Logger::VERSION, ""..."1.4.0" do
+ it "fails if the device is already closed" do
+ @device.close
+ -> { @device.write "foo" }.should complain(/\Alog writing failed\./)
+ end
+ end
+
+ version_is Logger::VERSION, "1.4.0" do
+ it "fails if the device is already closed" do
+ @device.close
+ -> { @device.write "foo" }.should complain(/\Alog shifting failed\./)
+ end
end
end
diff --git a/spec/ruby/library/matrix/unitary_spec.rb b/spec/ruby/library/matrix/unitary_spec.rb
index 04e6df8be0..b579cb244d 100644
--- a/spec/ruby/library/matrix/unitary_spec.rb
+++ b/spec/ruby/library/matrix/unitary_spec.rb
@@ -14,8 +14,10 @@ ruby_version_is ""..."3.1" do
Matrix[[0, Complex(0, 1)], [Complex(0, 1), 0]].should.unitary?
end
- it "returns true for unitary matrices with a Complex and a negative #imag" do
- Matrix[[0, Complex(0, 1)], [Complex(0, -1), 0]].should.unitary?
+ version_is((Matrix::const_defined?(:VERSION) ? Matrix::VERSION : "0.1.0"), "0.3.0") do
+ it "returns true for unitary matrices with a Complex and a negative #imag" do
+ Matrix[[0, Complex(0, 1)], [Complex(0, -1), 0]].should.unitary?
+ end
end
it "raises an error for rectangular matrices" do
diff --git a/spec/ruby/library/monitor/exit_spec.rb b/spec/ruby/library/monitor/exit_spec.rb
deleted file mode 100644
index 952ad9525d..0000000000
--- a/spec/ruby/library/monitor/exit_spec.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require_relative '../../spec_helper'
-require 'monitor'
-
-describe "Monitor#exit" do
- it "raises ThreadError when monitor is not entered" do
- m = Monitor.new
-
- -> { m.exit }.should raise_error(ThreadError)
- end
-end
diff --git a/spec/ruby/library/net/ftp/shared/getbinaryfile.rb b/spec/ruby/library/net/ftp/shared/getbinaryfile.rb
index ceec8e7cd5..f324f5b85d 100644
--- a/spec/ruby/library/net/ftp/shared/getbinaryfile.rb
+++ b/spec/ruby/library/net/ftp/shared/getbinaryfile.rb
@@ -1,6 +1,6 @@
-describe :net_ftp_getbinaryfile, shared: true do
+describe :net_ftp_getbinaryfile, shared: :true do
before :each do
- @fixture_file = __dir__ + "/../fixtures/getbinaryfile"
+ @fixture_file = File.dirname(__FILE__) + "/../fixtures/getbinaryfile"
@tmp_file = tmp("getbinaryfile")
@server = NetFTPSpecs::DummyFTP.new
diff --git a/spec/ruby/library/net/ftp/shared/gettextfile.rb b/spec/ruby/library/net/ftp/shared/gettextfile.rb
index 7fe14f7dfb..82bec2a4a7 100644
--- a/spec/ruby/library/net/ftp/shared/gettextfile.rb
+++ b/spec/ruby/library/net/ftp/shared/gettextfile.rb
@@ -1,4 +1,4 @@
-describe :net_ftp_gettextfile, shared: true do
+describe :net_ftp_gettextfile, shared: :true do
before :each do
@tmp_file = tmp("gettextfile")
diff --git a/spec/ruby/library/net/ftp/shared/putbinaryfile.rb b/spec/ruby/library/net/ftp/shared/putbinaryfile.rb
index 45f53adc2a..1163a1cfea 100644
--- a/spec/ruby/library/net/ftp/shared/putbinaryfile.rb
+++ b/spec/ruby/library/net/ftp/shared/putbinaryfile.rb
@@ -1,9 +1,9 @@
-describe :net_ftp_putbinaryfile, shared: true do
+describe :net_ftp_putbinaryfile, shared: :true do
before :each do
@server = NetFTPSpecs::DummyFTP.new
@server.serve_once
- @local_fixture_file = __dir__ + "/../fixtures/putbinaryfile"
+ @local_fixture_file = File.dirname(__FILE__) + "/../fixtures/putbinaryfile"
@remote_tmp_file = tmp("binaryfile", false)
@ftp = Net::FTP.new
diff --git a/spec/ruby/library/net/ftp/shared/puttextfile.rb b/spec/ruby/library/net/ftp/shared/puttextfile.rb
index 3836e954b8..50e8de28e6 100644
--- a/spec/ruby/library/net/ftp/shared/puttextfile.rb
+++ b/spec/ruby/library/net/ftp/shared/puttextfile.rb
@@ -3,7 +3,7 @@ describe :net_ftp_puttextfile, shared: true do
@server = NetFTPSpecs::DummyFTP.new
@server.serve_once
- @local_fixture_file = __dir__ + "/../fixtures/puttextfile"
+ @local_fixture_file = File.dirname(__FILE__) + "/../fixtures/puttextfile"
@remote_tmp_file = tmp("textfile", false)
@ftp = Net::FTP.new
diff --git a/spec/ruby/library/net/ftp/storbinary_spec.rb b/spec/ruby/library/net/ftp/storbinary_spec.rb
index 6f73344612..64c9090760 100644
--- a/spec/ruby/library/net/ftp/storbinary_spec.rb
+++ b/spec/ruby/library/net/ftp/storbinary_spec.rb
@@ -9,7 +9,7 @@ ruby_version_is ""..."3.1" do
@server = NetFTPSpecs::DummyFTP.new
@server.serve_once
- @local_fixture_file = __dir__ + "/fixtures/putbinaryfile"
+ @local_fixture_file = File.dirname(__FILE__) + "/fixtures/putbinaryfile"
@tmp_file = tmp("binaryfile", false)
@ftp = Net::FTP.new
diff --git a/spec/ruby/library/net/ftp/storlines_spec.rb b/spec/ruby/library/net/ftp/storlines_spec.rb
index 32b9448732..a4bb7af799 100644
--- a/spec/ruby/library/net/ftp/storlines_spec.rb
+++ b/spec/ruby/library/net/ftp/storlines_spec.rb
@@ -9,7 +9,7 @@ ruby_version_is ""..."3.1" do
@server = NetFTPSpecs::DummyFTP.new
@server.serve_once
- @local_fixture_file = __dir__ + "/fixtures/puttextfile"
+ @local_fixture_file = File.dirname(__FILE__) + "/fixtures/puttextfile"
@tmp_file = tmp("textfile", false)
@ftp = Net::FTP.new
diff --git a/spec/ruby/library/net/http/http/get_spec.rb b/spec/ruby/library/net/http/http/get_spec.rb
index a3b62e3754..9f6c45f26b 100644
--- a/spec/ruby/library/net/http/http/get_spec.rb
+++ b/spec/ruby/library/net/http/http/get_spec.rb
@@ -80,13 +80,15 @@ describe "Net::HTTP.get" do
end
end
- it "lets the kill Thread exception goes through and does not replace it with Zlib::BufError" do
- socket, client_thread = start_threads
- begin
- client_thread.kill
- client_thread.value.should == nil
- ensure
- socket.close
+ ruby_version_is "3.0" do # https://bugs.ruby-lang.org/issues/13882#note-6
+ it "lets the kill Thread exception goes through and does not replace it with Zlib::BufError" do
+ socket, client_thread = start_threads
+ begin
+ client_thread.kill
+ client_thread.value.should == nil
+ ensure
+ socket.close
+ end
end
end
end
diff --git a/spec/ruby/library/objectspace/dump_all_spec.rb b/spec/ruby/library/objectspace/dump_all_spec.rb
deleted file mode 100644
index e9b449a905..0000000000
--- a/spec/ruby/library/objectspace/dump_all_spec.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-require_relative '../../spec_helper'
-require 'objspace'
-
-describe "ObjectSpace.dump_all" do
- it "dumps Ruby heap to string when passed output: :string" do
- stdout = ruby_exe(<<~RUBY, options: "-robjspace")
- string = "abc"
- dump = ObjectSpace.dump_all(output: :string)
- puts dump.class
- puts dump.include?('"value":"abc"')
- RUBY
-
- stdout.should == "String\ntrue\n"
- end
-
- it "dumps Ruby heap to a temporary file when passed output: :file" do
- stdout = ruby_exe(<<~RUBY, options: "-robjspace")
- string = "abc"
- file = ObjectSpace.dump_all(output: :file)
-
- begin
- file.flush
- file.rewind
- content = file.read
-
- puts file.class
- puts content.include?('"value":"abc"')
- ensure
- file.close
- File.unlink file.path
- end
- RUBY
-
- stdout.should == "File\ntrue\n"
- end
-
- it "dumps Ruby heap to a temporary file when :output not specified" do
- stdout = ruby_exe(<<~RUBY, options: "-robjspace")
- string = "abc"
- file = ObjectSpace.dump_all
-
- begin
- file.flush
- file.rewind
- content = file.read
-
- puts file.class
- puts content.include?('"value":"abc"')
- ensure
- file.close
- File.unlink file.path
- end
- RUBY
-
- stdout.should == "File\ntrue\n"
- end
-
- it "dumps Ruby heap to a temporary file when passed output: :nil" do
- stdout = ruby_exe(<<~RUBY, options: "-robjspace")
- string = "abc"
- file = ObjectSpace.dump_all(output: nil)
-
- begin
- file.flush
- file.rewind
- content = file.read
-
- puts file.class
- puts content.include?('"value":"abc"')
- ensure
- file.close
- File.unlink file.path
- end
- RUBY
-
- stdout.should == "File\ntrue\n"
- end
-
- it "dumps Ruby heap to stdout when passed output: :stdout" do
- stdout = ruby_exe(<<~RUBY, options: "-robjspace")
- string = "abc"
- ObjectSpace.dump_all(output: :stdout)
- RUBY
-
- stdout.should include('"value":"abc"')
- end
-
- it "dumps Ruby heap to provided IO when passed output: IO" do
- stdout = ruby_exe(<<~RUBY, options: "-robjspace -rtempfile")
- string = "abc"
- io = Tempfile.create("object_space_dump_all")
-
- begin
- result = ObjectSpace.dump_all(output: io)
- io.rewind
- content = io.read
-
- puts result.equal?(io)
- puts content.include?('"value":"abc"')
- ensure
- io.close
- File.unlink io.path
- end
- RUBY
-
- stdout.should == "true\ntrue\n"
- end
-
- it "raises ArgumentError when passed not supported :output value" do
- -> { ObjectSpace.dump_all(output: Object.new) }.should raise_error(ArgumentError, /wrong output option/)
- end
-end
diff --git a/spec/ruby/library/objectspace/dump_spec.rb b/spec/ruby/library/objectspace/dump_spec.rb
deleted file mode 100644
index e22ee3df1e..0000000000
--- a/spec/ruby/library/objectspace/dump_spec.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-require_relative '../../spec_helper'
-require 'objspace'
-
-describe "ObjectSpace.dump" do
- it "dumps the content of object as JSON" do
- require 'json'
- string = ObjectSpace.dump("abc")
- dump = JSON.parse(string)
-
- dump['type'].should == "STRING"
- dump['value'].should == "abc"
- end
-
- it "dumps to string when passed output: :string" do
- string = ObjectSpace.dump("abc", output: :string)
- string.should be_kind_of(String)
- string.should include('"value":"abc"')
- end
-
- it "dumps to string when :output not specified" do
- string = ObjectSpace.dump("abc")
- string.should be_kind_of(String)
- string.should include('"value":"abc"')
- end
-
- it "dumps to a temporary file when passed output: :file" do
- file = ObjectSpace.dump("abc", output: :file)
- file.should be_kind_of(File)
-
- file.rewind
- content = file.read
- content.should include('"value":"abc"')
- ensure
- file.close
- File.unlink file.path
- end
-
- it "dumps to a temporary file when passed output: :nil" do
- file = ObjectSpace.dump("abc", output: nil)
- file.should be_kind_of(File)
-
- file.rewind
- file.read.should include('"value":"abc"')
- ensure
- file.close
- File.unlink file.path
- end
-
- it "dumps to stdout when passed output: :stdout" do
- stdout = ruby_exe('ObjectSpace.dump("abc", output: :stdout)', options: "-robjspace").chomp
- stdout.should include('"value":"abc"')
- end
-
- it "dumps to provided IO when passed output: IO" do
- filename = tmp("io_read.txt")
- io = File.open(filename, "w+")
- result = ObjectSpace.dump("abc", output: io)
- result.should.equal? io
-
- io.rewind
- io.read.should include('"value":"abc"')
- ensure
- io.close
- rm_r filename
- end
-
- it "raises ArgumentError when passed not supported :output value" do
- -> { ObjectSpace.dump("abc", output: Object.new) }.should raise_error(ArgumentError, /wrong output option/)
- end
-end
diff --git a/spec/ruby/library/openssl/config/freeze_spec.rb b/spec/ruby/library/openssl/config/freeze_spec.rb
new file mode 100644
index 0000000000..c814341b86
--- /dev/null
+++ b/spec/ruby/library/openssl/config/freeze_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+require_relative '../shared/constants'
+
+require 'openssl'
+
+version_is(OpenSSL::VERSION, ""..."2.2") do
+ describe "OpenSSL::Config#freeze" do
+ it "needs to be reviewed for completeness"
+
+ it "freezes" do
+ c = OpenSSL::Config.new
+ -> {
+ c['foo'] = [ ['key', 'value'] ]
+ }.should_not raise_error
+ c.freeze
+ c.frozen?.should be_true
+ -> {
+ c['foo'] = [ ['key', 'value'] ]
+ }.should raise_error(TypeError)
+ end
+ end
+end
diff --git a/spec/ruby/library/openssl/digest/append_spec.rb b/spec/ruby/library/openssl/digest/append_spec.rb
deleted file mode 100644
index 08802b7253..0000000000
--- a/spec/ruby/library/openssl/digest/append_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative 'shared/update'
-
-describe "OpenSSL::Digest#<<" do
- it_behaves_like :openssl_digest_update, :<<
-end
diff --git a/spec/ruby/library/openssl/digest/block_length_spec.rb b/spec/ruby/library/openssl/digest/block_length_spec.rb
deleted file mode 100644
index 444ed9d20d..0000000000
--- a/spec/ruby/library/openssl/digest/block_length_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../../../library/digest/sha1/shared/constants'
-require_relative '../../../library/digest/sha256/shared/constants'
-require_relative '../../../library/digest/sha384/shared/constants'
-require_relative '../../../library/digest/sha512/shared/constants'
-require 'openssl'
-
-describe "OpenSSL::Digest#block_length" do
- context "when the digest object is created via a name argument" do
- it "returns a SHA1 block length" do
- OpenSSL::Digest.new('sha1').block_length.should == SHA1Constants::BlockLength
- end
-
- it "returns a SHA256 block length" do
- OpenSSL::Digest.new('sha256').block_length.should == SHA256Constants::BlockLength
- end
-
- it "returns a SHA384 block length" do
- OpenSSL::Digest.new('sha384').block_length.should == SHA384Constants::BlockLength
- end
-
- it "returns a SHA512 block length" do
- OpenSSL::Digest.new('sha512').block_length.should == SHA512Constants::BlockLength
- end
- end
-
- context "when the digest object is created via a subclass" do
- it "returns a SHA1 block length" do
- OpenSSL::Digest::SHA1.new.block_length.should == SHA1Constants::BlockLength
- end
-
- it "returns a SHA256 block length" do
- OpenSSL::Digest::SHA256.new.block_length.should == SHA256Constants::BlockLength
- end
-
- it "returns a SHA384 block length" do
- OpenSSL::Digest::SHA384.new.block_length.should == SHA384Constants::BlockLength
- end
-
- it "returns a SHA512 block length" do
- OpenSSL::Digest::SHA512.new.block_length.should == SHA512Constants::BlockLength
- end
- end
-end
diff --git a/spec/ruby/library/openssl/digest/digest_length_spec.rb b/spec/ruby/library/openssl/digest/digest_length_spec.rb
deleted file mode 100644
index 37d1cba9a7..0000000000
--- a/spec/ruby/library/openssl/digest/digest_length_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../../../library/digest/sha1/shared/constants'
-require_relative '../../../library/digest/sha256/shared/constants'
-require_relative '../../../library/digest/sha384/shared/constants'
-require_relative '../../../library/digest/sha512/shared/constants'
-require 'openssl'
-
-describe "OpenSSL::Digest#digest_length" do
- context "when the digest object is created via a name argument" do
- it "returns a SHA1 digest length" do
- OpenSSL::Digest.new('sha1').digest_length.should == SHA1Constants::DigestLength
- end
-
- it "returns a SHA256 digest length" do
- OpenSSL::Digest.new('sha256').digest_length.should == SHA256Constants::DigestLength
- end
-
- it "returns a SHA384 digest length" do
- OpenSSL::Digest.new('sha384').digest_length.should == SHA384Constants::DigestLength
- end
-
- it "returns a SHA512 digest length" do
- OpenSSL::Digest.new('sha512').digest_length.should == SHA512Constants::DigestLength
- end
- end
-
- context "when the digest object is created via a subclass" do
- it "returns a SHA1 digest length" do
- OpenSSL::Digest::SHA1.new.digest_length.should == SHA1Constants::DigestLength
- end
-
- it "returns a SHA256 digest length" do
- OpenSSL::Digest::SHA256.new.digest_length.should == SHA256Constants::DigestLength
- end
-
- it "returns a SHA384 digest length" do
- OpenSSL::Digest::SHA384.new.digest_length.should == SHA384Constants::DigestLength
- end
-
- it "returns a SHA512 digest length" do
- OpenSSL::Digest::SHA512.new.digest_length.should == SHA512Constants::DigestLength
- end
- end
-end
diff --git a/spec/ruby/library/openssl/digest/digest_spec.rb b/spec/ruby/library/openssl/digest/digest_spec.rb
deleted file mode 100644
index cf27d01b6d..0000000000
--- a/spec/ruby/library/openssl/digest/digest_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../../../library/digest/sha1/shared/constants'
-require_relative '../../../library/digest/sha256/shared/constants'
-require_relative '../../../library/digest/sha384/shared/constants'
-require_relative '../../../library/digest/sha512/shared/constants'
-require 'openssl'
-
-describe "OpenSSL::Digest class methods" do
- describe ".digest" do
- it "returns a SHA1 digest" do
- OpenSSL::Digest.digest('sha1', SHA1Constants::Contents).should == SHA1Constants::Digest
- end
-
- it "returns a SHA256 digest" do
- OpenSSL::Digest.digest('sha256', SHA256Constants::Contents).should == SHA256Constants::Digest
- end
-
- it "returns a SHA384 digest" do
- OpenSSL::Digest.digest('sha384', SHA384Constants::Contents).should == SHA384Constants::Digest
- end
-
- it "returns a SHA512 digest" do
- OpenSSL::Digest.digest('sha512', SHA512Constants::Contents).should == SHA512Constants::Digest
- end
- end
-
- describe ".hexdigest" do
- it "returns a SHA1 hexdigest" do
- OpenSSL::Digest.hexdigest('sha1', SHA1Constants::Contents).should == SHA1Constants::Hexdigest
- end
-
- it "returns a SHA256 hexdigest" do
- OpenSSL::Digest.hexdigest('sha256', SHA256Constants::Contents).should == SHA256Constants::Hexdigest
- end
-
- it "returns a SHA384 hexdigest" do
- OpenSSL::Digest.hexdigest('sha384', SHA384Constants::Contents).should == SHA384Constants::Hexdigest
- end
-
- it "returns a SHA512 hexdigest" do
- OpenSSL::Digest.hexdigest('sha512', SHA512Constants::Contents).should == SHA512Constants::Hexdigest
- end
- end
-
- describe ".base64digest" do
- it "returns a SHA1 base64digest" do
- OpenSSL::Digest.base64digest('sha1', SHA1Constants::Contents).should == SHA1Constants::Base64digest
- end
-
- it "returns a SHA256 base64digest" do
- OpenSSL::Digest.base64digest('sha256', SHA256Constants::Contents).should == SHA256Constants::Base64digest
- end
-
- it "returns a SHA384 base64digest" do
- OpenSSL::Digest.base64digest('sha384', SHA384Constants::Contents).should == SHA384Constants::Base64digest
- end
-
- it "returns a SHA512 base64digest" do
- OpenSSL::Digest.base64digest('sha512', SHA512Constants::Contents).should == SHA512Constants::Base64digest
- end
- end
-end
diff --git a/spec/ruby/library/openssl/digest/initialize_spec.rb b/spec/ruby/library/openssl/digest/initialize_spec.rb
deleted file mode 100644
index 1cd0409c4d..0000000000
--- a/spec/ruby/library/openssl/digest/initialize_spec.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../../../library/digest/sha1/shared/constants'
-require_relative '../../../library/digest/sha256/shared/constants'
-require_relative '../../../library/digest/sha384/shared/constants'
-require_relative '../../../library/digest/sha512/shared/constants'
-require 'openssl'
-
-describe "OpenSSL::Digest#initialize" do
- describe "can be called with a digest name" do
- it "returns a SHA1 object" do
- OpenSSL::Digest.new("sha1").name.should == "SHA1"
- end
-
- it "returns a SHA256 object" do
- OpenSSL::Digest.new("sha256").name.should == "SHA256"
- end
-
- it "returns a SHA384 object" do
- OpenSSL::Digest.new("sha384").name.should == "SHA384"
- end
-
- it "returns a SHA512 object" do
- OpenSSL::Digest.new("sha512").name.should == "SHA512"
- end
-
- it "throws an error when called with an unknown digest" do
- -> { OpenSSL::Digest.new("wd40") }.should raise_error(RuntimeError, /Unsupported digest algorithm \(wd40\)/)
- end
-
- it "cannot be called with a symbol" do
- -> { OpenSSL::Digest.new(:SHA1) }.should raise_error(TypeError, /wrong argument type Symbol/)
- end
-
- it "does not call #to_str on the argument" do
- name = mock("digest name")
- name.should_not_receive(:to_str)
- -> { OpenSSL::Digest.new(name) }.should raise_error(TypeError, /wrong argument type/)
- end
- end
-
- describe "can be called with a digest object" do
- it "returns a SHA1 object" do
- OpenSSL::Digest.new(OpenSSL::Digest::SHA1.new).name.should == "SHA1"
- end
-
- it "returns a SHA256 object" do
- OpenSSL::Digest.new(OpenSSL::Digest::SHA256.new).name.should == "SHA256"
- end
-
- it "returns a SHA384 object" do
- OpenSSL::Digest.new(OpenSSL::Digest::SHA384.new).name.should == "SHA384"
- end
-
- it "returns a SHA512 object" do
- OpenSSL::Digest.new(OpenSSL::Digest::SHA512.new).name.should == "SHA512"
- end
-
- it "ignores the state of the digest object" do
- sha1 = OpenSSL::Digest.new('sha1', SHA1Constants::Contents)
- OpenSSL::Digest.new(sha1).digest.should == SHA1Constants::BlankDigest
- end
- end
-
- it "cannot be called with a digest class" do
- -> { OpenSSL::Digest.new(OpenSSL::Digest::SHA1) }.should raise_error(TypeError, /wrong argument type Class/)
- end
-
- context "when called without an initial String argument" do
- it "returns a SHA1 digest" do
- OpenSSL::Digest.new("sha1").digest.should == SHA1Constants::BlankDigest
- end
-
- it "returns a SHA256 digest" do
- OpenSSL::Digest.new("sha256").digest.should == SHA256Constants::BlankDigest
- end
-
- it "returns a SHA384 digest" do
- OpenSSL::Digest.new("sha384").digest.should == SHA384Constants::BlankDigest
- end
-
- it "returns a SHA512 digest" do
- OpenSSL::Digest.new("sha512").digest.should == SHA512Constants::BlankDigest
- end
- end
-
- context "when called with an initial String argument" do
- it "returns a SHA1 digest of that argument" do
- OpenSSL::Digest.new("sha1", SHA1Constants::Contents).digest.should == SHA1Constants::Digest
- end
-
- it "returns a SHA256 digest of that argument" do
- OpenSSL::Digest.new("sha256", SHA256Constants::Contents).digest.should == SHA256Constants::Digest
- end
-
- it "returns a SHA384 digest of that argument" do
- OpenSSL::Digest.new("sha384", SHA384Constants::Contents).digest.should == SHA384Constants::Digest
- end
-
- it "returns a SHA512 digest of that argument" do
- OpenSSL::Digest.new("sha512", SHA512Constants::Contents).digest.should == SHA512Constants::Digest
- end
- end
-
- context "can be called on subclasses" do
- describe "can be called without an initial String argument on subclasses" do
- it "returns a SHA1 digest" do
- OpenSSL::Digest::SHA1.new.digest.should == SHA1Constants::BlankDigest
- end
-
- it "returns a SHA256 digest" do
- OpenSSL::Digest::SHA256.new.digest.should == SHA256Constants::BlankDigest
- end
-
- it "returns a SHA384 digest" do
- OpenSSL::Digest::SHA384.new.digest.should == SHA384Constants::BlankDigest
- end
-
- it "returns a SHA512 digest" do
- OpenSSL::Digest::SHA512.new.digest.should == SHA512Constants::BlankDigest
- end
- end
-
- describe "can be called with an initial String argument on subclasses" do
- it "returns a SHA1 digest" do
- OpenSSL::Digest::SHA1.new(SHA1Constants::Contents).digest.should == SHA1Constants::Digest
- end
-
- it "returns a SHA256 digest" do
- OpenSSL::Digest::SHA256.new(SHA256Constants::Contents).digest.should == SHA256Constants::Digest
- end
-
- it "returns a SHA384 digest" do
- OpenSSL::Digest::SHA384.new(SHA384Constants::Contents).digest.should == SHA384Constants::Digest
- end
-
- it "returns a SHA512 digest" do
- OpenSSL::Digest::SHA512.new(SHA512Constants::Contents).digest.should == SHA512Constants::Digest
- end
- end
- end
-end
diff --git a/spec/ruby/library/openssl/digest/name_spec.rb b/spec/ruby/library/openssl/digest/name_spec.rb
deleted file mode 100644
index b379f35c1c..0000000000
--- a/spec/ruby/library/openssl/digest/name_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require_relative '../../../spec_helper'
-require 'openssl'
-
-describe "OpenSSL::Digest#name" do
- it "returns the name of digest" do
- OpenSSL::Digest.new('SHA1').name.should == 'SHA1'
- end
-
- it "converts the name to the internal representation of OpenSSL" do
- OpenSSL::Digest.new('sha1').name.should == 'SHA1'
- end
-
- it "works on subclasses too" do
- OpenSSL::Digest::SHA1.new.name.should == 'SHA1'
- end
-end
diff --git a/spec/ruby/library/openssl/digest/reset_spec.rb b/spec/ruby/library/openssl/digest/reset_spec.rb
deleted file mode 100644
index c19bf46633..0000000000
--- a/spec/ruby/library/openssl/digest/reset_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative '../../../library/digest/sha1/shared/constants'
-require_relative '../../../library/digest/sha256/shared/constants'
-require_relative '../../../library/digest/sha384/shared/constants'
-require_relative '../../../library/digest/sha512/shared/constants'
-require 'openssl'
-
-describe "OpenSSL::Digest#reset" do
- it "works for a SHA1 digest" do
- digest = OpenSSL::Digest.new('sha1', SHA1Constants::Contents)
- digest.reset
- digest.update(SHA1Constants::Contents)
- digest.digest.should == SHA1Constants::Digest
- end
-
- it "works for a SHA256 digest" do
- digest = OpenSSL::Digest.new('sha256', SHA256Constants::Contents)
- digest.reset
- digest.update(SHA256Constants::Contents)
- digest.digest.should == SHA256Constants::Digest
- end
-
- it "works for a SHA384 digest" do
- digest = OpenSSL::Digest.new('sha384', SHA384Constants::Contents)
- digest.reset
- digest.update(SHA384Constants::Contents)
- digest.digest.should == SHA384Constants::Digest
- end
-
- it "works for a SHA512 digest" do
- digest = OpenSSL::Digest.new('sha512', SHA512Constants::Contents)
- digest.reset
- digest.update(SHA512Constants::Contents)
- digest.digest.should == SHA512Constants::Digest
- end
-end
diff --git a/spec/ruby/library/openssl/digest/shared/update.rb b/spec/ruby/library/openssl/digest/shared/update.rb
deleted file mode 100644
index e5ff9dcb16..0000000000
--- a/spec/ruby/library/openssl/digest/shared/update.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-require_relative '../../../../library/digest/sha1/shared/constants'
-require_relative '../../../../library/digest/sha256/shared/constants'
-require_relative '../../../../library/digest/sha384/shared/constants'
-require_relative '../../../../library/digest/sha512/shared/constants'
-require 'openssl'
-
-describe :openssl_digest_update, shared: true do
- context "when given input as a single string" do
- it "returns a SHA1 digest" do
- digest = OpenSSL::Digest.new('sha1')
- digest.send(@method, SHA1Constants::Contents)
- digest.digest.should == SHA1Constants::Digest
- end
-
- it "returns a SHA256 digest" do
- digest = OpenSSL::Digest.new('sha256')
- digest.send(@method, SHA256Constants::Contents)
- digest.digest.should == SHA256Constants::Digest
- end
-
- it "returns a SHA384 digest" do
- digest = OpenSSL::Digest.new('sha384')
- digest.send(@method, SHA384Constants::Contents)
- digest.digest.should == SHA384Constants::Digest
- end
-
- it "returns a SHA512 digest" do
- digest = OpenSSL::Digest.new('sha512')
- digest.send(@method, SHA512Constants::Contents)
- digest.digest.should == SHA512Constants::Digest
- end
- end
-
- context "when given input as multiple smaller substrings" do
- it "returns a SHA1 digest" do
- digest = OpenSSL::Digest.new('sha1')
- SHA1Constants::Contents.each_char { |b| digest.send(@method, b) }
- digest.digest.should == SHA1Constants::Digest
- end
-
- it "returns a SHA256 digest" do
- digest = OpenSSL::Digest.new('sha256')
- SHA256Constants::Contents.each_char { |b| digest.send(@method, b) }
- digest.digest.should == SHA256Constants::Digest
- end
-
- it "returns a SHA384 digest" do
- digest = OpenSSL::Digest.new('sha384')
- SHA384Constants::Contents.each_char { |b| digest.send(@method, b) }
- digest.digest.should == SHA384Constants::Digest
- end
-
- it "returns a SHA512 digest" do
- digest = OpenSSL::Digest.new('sha512')
- SHA512Constants::Contents.each_char { |b| digest.send(@method, b) }
- digest.digest.should == SHA512Constants::Digest
- end
- end
-
- context "when input is not a String and responds to #to_str" do
- it "returns a SHA1 digest" do
- str = mock('str')
- str.should_receive(:to_str).and_return(SHA1Constants::Contents)
- digest = OpenSSL::Digest.new('sha1')
- digest.send(@method, str)
- digest.digest.should == SHA1Constants::Digest
- end
-
- it "returns a SHA256 digest" do
- str = mock('str')
- str.should_receive(:to_str).and_return(SHA256Constants::Contents)
- digest = OpenSSL::Digest.new('sha256')
- digest.send(@method, str)
- digest.digest.should == SHA256Constants::Digest
- end
-
- it "returns a SHA384 digest" do
- str = mock('str')
- str.should_receive(:to_str).and_return(SHA384Constants::Contents)
- digest = OpenSSL::Digest.new('sha384')
- digest.send(@method, str)
- digest.digest.should == SHA384Constants::Digest
- end
-
- it "returns a SHA512 digest" do
- str = mock('str')
- str.should_receive(:to_str).and_return(SHA512Constants::Contents)
- digest = OpenSSL::Digest.new('sha512')
- digest.send(@method, str)
- digest.digest.should == SHA512Constants::Digest
- end
- end
-
- context "when input is not a String and does not respond to #to_str" do
- it "raises a TypeError with SHA1" do
- digest = OpenSSL::Digest.new('sha1')
- -> {
- digest.send(@method, Object.new)
- }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
-
- it "raises a TypeError with SHA256" do
- digest = OpenSSL::Digest.new('sha256')
- -> {
- digest.send(@method, Object.new)
- }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
-
- it "raises a TypeError with SHA384" do
- digest = OpenSSL::Digest.new('sha384')
- -> {
- digest.send(@method, Object.new)
- }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
-
- it "raises a TypeError with SHA512" do
- digest = OpenSSL::Digest.new('sha512')
- -> {
- digest.send(@method, Object.new)
- }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
- end
-end
diff --git a/spec/ruby/library/openssl/digest/update_spec.rb b/spec/ruby/library/openssl/digest/update_spec.rb
deleted file mode 100644
index 3a90b06c6b..0000000000
--- a/spec/ruby/library/openssl/digest/update_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require_relative '../../../spec_helper'
-require_relative 'shared/update'
-
-describe "OpenSSL::Digest#update" do
- it_behaves_like :openssl_digest_update, :update
-end
diff --git a/spec/ruby/library/openssl/digest_spec.rb b/spec/ruby/library/openssl/digest_spec.rb
new file mode 100644
index 0000000000..b8e82d073f
--- /dev/null
+++ b/spec/ruby/library/openssl/digest_spec.rb
@@ -0,0 +1,63 @@
+require_relative '../../spec_helper'
+require_relative '../../library/digest/sha1/shared/constants'
+require_relative '../../library/digest/sha256/shared/constants'
+require_relative '../../library/digest/sha384/shared/constants'
+require_relative '../../library/digest/sha512/shared/constants'
+require 'openssl'
+
+describe "OpenSSL::Digest" do
+
+ describe ".digest" do
+ it "returns a SHA1 digest" do
+ OpenSSL::Digest.digest('sha1', SHA1Constants::Contents).should == SHA1Constants::Digest
+ end
+
+ it "returns a SHA256 digest" do
+ OpenSSL::Digest.digest('sha256', SHA256Constants::Contents).should == SHA256Constants::Digest
+ end
+
+ it "returns a SHA384 digest" do
+ OpenSSL::Digest.digest('sha384', SHA384Constants::Contents).should == SHA384Constants::Digest
+ end
+
+ it "returns a SHA512 digest" do
+ OpenSSL::Digest.digest('sha512', SHA512Constants::Contents).should == SHA512Constants::Digest
+ end
+ end
+
+ describe ".hexdigest" do
+ it "returns a SHA1 hexdigest" do
+ OpenSSL::Digest.hexdigest('sha1', SHA1Constants::Contents).should == SHA1Constants::Hexdigest
+ end
+
+ it "returns a SHA256 hexdigest" do
+ OpenSSL::Digest.hexdigest('sha256', SHA256Constants::Contents).should == SHA256Constants::Hexdigest
+ end
+
+ it "returns a SHA384 hexdigest" do
+ OpenSSL::Digest.hexdigest('sha384', SHA384Constants::Contents).should == SHA384Constants::Hexdigest
+ end
+
+ it "returns a SHA512 hexdigest" do
+ OpenSSL::Digest.hexdigest('sha512', SHA512Constants::Contents).should == SHA512Constants::Hexdigest
+ end
+ end
+
+ describe ".base64digest" do
+ it "returns a SHA1 base64digest" do
+ OpenSSL::Digest.base64digest('sha1', SHA1Constants::Contents).should == SHA1Constants::Base64digest
+ end
+
+ it "returns a SHA256 base64digest" do
+ OpenSSL::Digest.base64digest('sha256', SHA256Constants::Contents).should == SHA256Constants::Base64digest
+ end
+
+ it "returns a SHA384 base64digest" do
+ OpenSSL::Digest.base64digest('sha384', SHA384Constants::Contents).should == SHA384Constants::Base64digest
+ end
+
+ it "returns a SHA512 base64digest" do
+ OpenSSL::Digest.base64digest('sha512', SHA512Constants::Contents).should == SHA512Constants::Base64digest
+ end
+ end
+end
diff --git a/spec/ruby/library/openssl/fixed_length_secure_compare_spec.rb b/spec/ruby/library/openssl/fixed_length_secure_compare_spec.rb
deleted file mode 100644
index 5a2ca168b5..0000000000
--- a/spec/ruby/library/openssl/fixed_length_secure_compare_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-require_relative '../../spec_helper'
-require 'openssl'
-
-describe "OpenSSL.fixed_length_secure_compare" do
- it "returns true for two strings with the same content" do
- input1 = "the quick brown fox jumps over the lazy dog"
- input2 = "the quick brown fox jumps over the lazy dog"
- OpenSSL.fixed_length_secure_compare(input1, input2).should be_true
- end
-
- it "returns false for two strings of equal size with different content" do
- input1 = "the quick brown fox jumps over the lazy dog"
- input2 = "the lazy dog jumps over the quick brown fox"
- OpenSSL.fixed_length_secure_compare(input1, input2).should be_false
- end
-
- it "converts both arguments to strings using #to_str" do
- input1 = mock("input1")
- input1.should_receive(:to_str).and_return("the quick brown fox jumps over the lazy dog")
- input2 = mock("input2")
- input2.should_receive(:to_str).and_return("the quick brown fox jumps over the lazy dog")
- OpenSSL.fixed_length_secure_compare(input1, input2).should be_true
- end
-
- it "does not accept arguments that are not string and cannot be coerced into strings" do
- -> {
- OpenSSL.fixed_length_secure_compare("input1", :input2)
- }.should raise_error(TypeError, 'no implicit conversion of Symbol into String')
-
- -> {
- OpenSSL.fixed_length_secure_compare(Object.new, "input2")
- }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
-
- it "raises an ArgumentError for two strings of different size" do
- input1 = "the quick brown fox jumps over the lazy dog"
- input2 = "the quick brown fox"
- -> {
- OpenSSL.fixed_length_secure_compare(input1, input2)
- }.should raise_error(ArgumentError, 'inputs must be of equal length')
- end
-end
diff --git a/spec/ruby/library/openssl/kdf/pbkdf2_hmac_spec.rb b/spec/ruby/library/openssl/kdf/pbkdf2_hmac_spec.rb
deleted file mode 100644
index 40f8597275..0000000000
--- a/spec/ruby/library/openssl/kdf/pbkdf2_hmac_spec.rb
+++ /dev/null
@@ -1,168 +0,0 @@
-require_relative '../../../spec_helper'
-require 'openssl'
-
-describe "OpenSSL::KDF.pbkdf2_hmac" do
- before :each do
- @defaults = {
- salt: "\x00".b * 16,
- iterations: 20_000,
- length: 16,
- hash: "sha1"
- }
- end
-
- it "creates the same value with the same input" do
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0".b
- end
-
- it "supports nullbytes embedded in the password" do
- key = OpenSSL::KDF.pbkdf2_hmac("sec\x00ret".b, **@defaults)
- key.should == "\xB9\x7F\xB0\xC2\th\xC8<\x86\xF3\x94Ij7\xEF\xF1".b
- end
-
- it "coerces the password into a String using #to_str" do
- pass = mock("pass")
- pass.should_receive(:to_str).and_return("secret")
- key = OpenSSL::KDF.pbkdf2_hmac(pass, **@defaults)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0".b
- end
-
- it "coerces the salt into a String using #to_str" do
- salt = mock("salt")
- salt.should_receive(:to_str).and_return("\x00".b * 16)
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, salt: salt)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0".b
- end
-
- it "coerces the iterations into an Integer using #to_int" do
- iterations = mock("iterations")
- iterations.should_receive(:to_int).and_return(20_000)
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, iterations: iterations)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0".b
- end
-
- it "coerces the length into an Integer using #to_int" do
- length = mock("length")
- length.should_receive(:to_int).and_return(16)
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, length: length)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0".b
- end
-
- it "accepts a OpenSSL::Digest object as hash" do
- hash = OpenSSL::Digest.new("sha1")
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, hash: hash)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0".b
- end
-
- it "accepts an empty password" do
- key = OpenSSL::KDF.pbkdf2_hmac("", **@defaults)
- key.should == "k\x9F-\xB1\xF7\x9A\v\xA1(C\xF9\x85!P\xEF\x8C".b
- end
-
- it "accepts an empty salt" do
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, salt: "")
- key.should == "\xD5f\xE5\xEA\xF91\x1D\xD3evD\xED\xDB\xE80\x80".b
- end
-
- it "accepts an empty length" do
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, length: 0)
- key.should.empty?
- end
-
- it "accepts an arbitrary length" do
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, length: 19)
- key.should == "!\x99+\xF0^\xD0\x8BM\x158\xC4\xAC\x9C\xF1\xF0\xE0\xCF\xBB\x7F".b
- end
-
- it "accepts any hash function known to OpenSSL" do
- key = OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, hash: "sha512")
- key.should == "N\x12}D\xCE\x99\xDBC\x8E\xEC\xAAr\xEA1\xDF\xFF".b
- end
-
- it "raises a TypeError when password is not a String and does not respond to #to_str" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac(Object.new, **@defaults)
- }.should raise_error(TypeError, "no implicit conversion of Object into String")
- end
-
- it "raises a TypeError when salt is not a String and does not respond to #to_str" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, salt: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into String")
- end
-
- it "raises a TypeError when iterations is not an Integer and does not respond to #to_int" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, iterations: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
- end
-
- it "raises a TypeError when length is not an Integer and does not respond to #to_int" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, length: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
- end
-
- it "raises a TypeError when hash is neither a String nor an OpenSSL::Digest" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, hash: Object.new)
- }.should raise_error(TypeError, "wrong argument type Object (expected OpenSSL/Digest)")
- end
-
- it "raises a TypeError when hash is neither a String nor an OpenSSL::Digest, it does not try to call #to_str" do
- hash = mock("hash")
- hash.should_not_receive(:to_str)
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, hash: hash)
- }.should raise_error(TypeError, "wrong argument type MockObject (expected OpenSSL/Digest)")
- end
-
- it "raises a RuntimeError for unknown digest algorithms" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, hash: "wd40")
- }.should raise_error(RuntimeError, /Unsupported digest algorithm \(wd40\)/)
- end
-
- it "treats salt as a required keyword" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults.except(:salt))
- }.should raise_error(ArgumentError, 'missing keyword: :salt')
- end
-
- it "treats iterations as a required keyword" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults.except(:iterations))
- }.should raise_error(ArgumentError, 'missing keyword: :iterations')
- end
-
- it "treats length as a required keyword" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults.except(:length))
- }.should raise_error(ArgumentError, 'missing keyword: :length')
- end
-
- it "treats hash as a required keyword" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults.except(:hash))
- }.should raise_error(ArgumentError, 'missing keyword: :hash')
- end
-
- it "treats all keywords as required" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret")
- }.should raise_error(ArgumentError, 'missing keywords: :salt, :iterations, :length, :hash')
- end
-
- guard -> { OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000 } do
- it "raises an OpenSSL::KDF::KDFError for 0 or less iterations" do
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, iterations: 0)
- }.should raise_error(OpenSSL::KDF::KDFError, "PKCS5_PBKDF2_HMAC: invalid iteration count")
-
- -> {
- OpenSSL::KDF.pbkdf2_hmac("secret", **@defaults, iterations: -1)
- }.should raise_error(OpenSSL::KDF::KDFError, /PKCS5_PBKDF2_HMAC/)
- end
- end
-end
diff --git a/spec/ruby/library/openssl/kdf/scrypt_spec.rb b/spec/ruby/library/openssl/kdf/scrypt_spec.rb
deleted file mode 100644
index 5dc9f2f281..0000000000
--- a/spec/ruby/library/openssl/kdf/scrypt_spec.rb
+++ /dev/null
@@ -1,209 +0,0 @@
-require_relative '../../../spec_helper'
-require 'openssl'
-
-guard -> { OpenSSL::KDF.respond_to?(:scrypt) } do
- describe "OpenSSL::KDF.scrypt" do
- before :each do
- @defaults = {
- salt: "\x00".b * 16,
- N: 2**14,
- r: 8,
- p: 1,
- length: 32
- }
- end
-
- it "creates the same value with the same input" do
- key = OpenSSL::KDF.scrypt("secret", **@defaults)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "supports nullbytes embedded into the password" do
- key = OpenSSL::KDF.scrypt("sec\x00ret".b, **@defaults)
- key.should == "\xF9\xA4\xA0\xF1p\xF4\xF0\xCAT\xB4v\xEB\r7\x88N\xF7\x15]Ns\xFCwt4a\xC9\xC6\xA7\x13\x81&".b
- end
-
- it "coerces the password into a String using #to_str" do
- pass = mock("pass")
- pass.should_receive(:to_str).and_return("secret")
- key = OpenSSL::KDF.scrypt(pass, **@defaults)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "coerces the salt into a String using #to_str" do
- salt = mock("salt")
- salt.should_receive(:to_str).and_return("\x00".b * 16)
- key = OpenSSL::KDF.scrypt("secret", **@defaults, salt: salt)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "coerces the N into an Integer using #to_int" do
- n = mock("N")
- n.should_receive(:to_int).and_return(2**14)
- key = OpenSSL::KDF.scrypt("secret", **@defaults, N: n)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "coerces the r into an Integer using #to_int" do
- r = mock("r")
- r.should_receive(:to_int).and_return(8)
- key = OpenSSL::KDF.scrypt("secret", **@defaults, r: r)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "coerces the p into an Integer using #to_int" do
- p = mock("p")
- p.should_receive(:to_int).and_return(1)
- key = OpenSSL::KDF.scrypt("secret", **@defaults, p: p)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "coerces the length into an Integer using #to_int" do
- length = mock("length")
- length.should_receive(:to_int).and_return(32)
- key = OpenSSL::KDF.scrypt("secret", **@defaults, length: length)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D\x17}\xF2\x84T\xD4)\xC2>\xFE\x93\xE3\xF4".b
- end
-
- it "accepts an empty password" do
- key = OpenSSL::KDF.scrypt("", **@defaults)
- key.should == "\xAA\xFC\xF5^E\x94v\xFFk\xE6\xF0vR\xE7\x13\xA7\xF5\x15'\x9A\xE4C\x9Dn\x18F_E\xD2\v\e\xB3".b
- end
-
- it "accepts an empty salt" do
- key = OpenSSL::KDF.scrypt("secret", **@defaults, salt: "")
- key.should == "\x96\xACDl\xCB3/aN\xB0F\x8A#\xD7\x92\xD2O\x1E\v\xBB\xCE\xC0\xAA\xB9\x0F]\xB09\xEA8\xDD\e".b
- end
-
- it "accepts a zero length" do
- key = OpenSSL::KDF.scrypt("secret", **@defaults, length: 0)
- key.should.empty?
- end
-
- it "accepts an arbitrary length" do
- key = OpenSSL::KDF.scrypt("secret", **@defaults, length: 19)
- key.should == "h\xB2k\xDF]\xDA\xE1.-(\xCF\xAC\x91D\x8F\xC2a\x9C\x9D".b
- end
-
- it "raises a TypeError when password is not a String and does not respond to #to_str" do
- -> {
- OpenSSL::KDF.scrypt(Object.new, **@defaults)
- }.should raise_error(TypeError, "no implicit conversion of Object into String")
- end
-
- it "raises a TypeError when salt is not a String and does not respond to #to_str" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, salt: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into String")
- end
-
- it "raises a TypeError when N is not an Integer and does not respond to #to_int" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, N: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
- end
-
- it "raises a TypeError when r is not an Integer and does not respond to #to_int" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, r: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
- end
-
- it "raises a TypeError when p is not an Integer and does not respond to #to_int" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, p: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
- end
-
- it "raises a TypeError when length is not an Integer and does not respond to #to_int" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, length: Object.new)
- }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
- end
-
- it "treats salt as a required keyword" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults.except(:salt))
- }.should raise_error(ArgumentError, 'missing keyword: :salt')
- end
-
- it "treats N as a required keyword" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults.except(:N))
- }.should raise_error(ArgumentError, 'missing keyword: :N')
- end
-
- it "treats r as a required keyword" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults.except(:r))
- }.should raise_error(ArgumentError, 'missing keyword: :r')
- end
-
- it "treats p as a required keyword" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults.except(:p))
- }.should raise_error(ArgumentError, 'missing keyword: :p')
- end
-
- it "treats length as a required keyword" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults.except(:length))
- }.should raise_error(ArgumentError, 'missing keyword: :length')
- end
-
- it "treats all keywords as required" do
- -> {
- OpenSSL::KDF.scrypt("secret")
- }.should raise_error(ArgumentError, 'missing keywords: :salt, :N, :r, :p, :length')
- end
-
- it "requires N to be a power of 2" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, N: 2**14 - 1)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
- end
-
- it "requires N to be at least 2" do
- key = OpenSSL::KDF.scrypt("secret", **@defaults, N: 2)
- key.should == "\x06A$a\xA9!\xBE\x01\x85\xA7\x18\xBCEa\x82\xC5\xFEl\x93\xAB\xBD\xF7\x8B\x84\v\xFC\eN\xEBQ\xE6\xD2".b
-
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, N: 1)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
-
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, N: 0)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
-
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, N: -1)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
- end
-
- it "requires r to be positive" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, r: 0)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
-
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, r: -1)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
- end
-
- it "requires p to be positive" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, p: 0)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
-
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, p: -1)
- }.should raise_error(OpenSSL::KDF::KDFError, /EVP_PBE_scrypt/)
- end
-
- it "requires length to be not negative" do
- -> {
- OpenSSL::KDF.scrypt("secret", **@defaults, length: -1)
- }.should raise_error(ArgumentError, "negative string size (or size too big)")
- end
- end
-end
diff --git a/spec/ruby/library/openssl/random/shared/random_bytes.rb b/spec/ruby/library/openssl/random/shared/random_bytes.rb
index f97ccd9974..037f10d409 100644
--- a/spec/ruby/library/openssl/random/shared/random_bytes.rb
+++ b/spec/ruby/library/openssl/random/shared/random_bytes.rb
@@ -1,7 +1,7 @@
require_relative '../../../../spec_helper'
require 'openssl'
-describe :openssl_random_bytes, shared: true do
+describe :openssl_random_bytes, shared: true do |cmd|
it "generates a random binary string of specified length" do
(1..64).each do |idx|
bytes = OpenSSL::Random.send(@method, idx)
diff --git a/spec/ruby/library/openssl/secure_compare_spec.rb b/spec/ruby/library/openssl/secure_compare_spec.rb
deleted file mode 100644
index cec48e01e7..0000000000
--- a/spec/ruby/library/openssl/secure_compare_spec.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require_relative '../../spec_helper'
-require 'openssl'
-
-describe "OpenSSL.secure_compare" do
- it "returns true for two strings with the same content" do
- input1 = "the quick brown fox jumps over the lazy dog"
- input2 = "the quick brown fox jumps over the lazy dog"
- OpenSSL.secure_compare(input1, input2).should be_true
- end
-
- it "returns false for two strings with different content" do
- input1 = "the quick brown fox jumps over the lazy dog"
- input2 = "the lazy dog jumps over the quick brown fox"
- OpenSSL.secure_compare(input1, input2).should be_false
- end
-
- it "converts both arguments to strings using #to_str, but adds equality check for the original objects" do
- input1 = mock("input1")
- input1.should_receive(:to_str).and_return("the quick brown fox jumps over the lazy dog")
- input2 = mock("input2")
- input2.should_receive(:to_str).and_return("the quick brown fox jumps over the lazy dog")
- OpenSSL.secure_compare(input1, input2).should be_false
-
- input = mock("input")
- input.should_receive(:to_str).twice.and_return("the quick brown fox jumps over the lazy dog")
- OpenSSL.secure_compare(input, input).should be_true
- end
-
- it "does not accept arguments that are not string and cannot be coerced into strings" do
- -> {
- OpenSSL.secure_compare("input1", :input2)
- }.should raise_error(TypeError, 'no implicit conversion of Symbol into String')
-
- -> {
- OpenSSL.secure_compare(Object.new, "input2")
- }.should raise_error(TypeError, 'no implicit conversion of Object into String')
- end
-end
diff --git a/spec/ruby/library/openssl/x509/name/verify_spec.rb b/spec/ruby/library/openssl/x509/name/verify_spec.rb
new file mode 100644
index 0000000000..6dcfc99466
--- /dev/null
+++ b/spec/ruby/library/openssl/x509/name/verify_spec.rb
@@ -0,0 +1,78 @@
+require_relative '../../../../spec_helper'
+require 'openssl'
+
+describe "OpenSSL::X509::Name.verify" do
+ it "returns true for valid certificate" do
+ key = OpenSSL::PKey::RSA.new 2048
+ cert = OpenSSL::X509::Certificate.new
+ cert.version = 2
+ cert.serial = 1
+ cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby CA"
+ cert.issuer = cert.subject
+ cert.public_key = key.public_key
+ cert.not_before = Time.now - 10
+ cert.not_after = cert.not_before + 365 * 24 * 60 * 60
+ cert.sign key, OpenSSL::Digest.new('SHA256')
+ store = OpenSSL::X509::Store.new
+ store.add_cert(cert)
+ [store.verify(cert), store.error, store.error_string].should == [true, 0, "ok"]
+ end
+
+ it "returns false for an expired certificate" do
+ key = OpenSSL::PKey::RSA.new 2048
+ cert = OpenSSL::X509::Certificate.new
+ cert.version = 2
+ cert.serial = 1
+ cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby CA"
+ cert.issuer = cert.subject
+ cert.public_key = key.public_key
+ cert.not_before = Time.now - 10
+ cert.not_after = Time.now - 5
+ cert.sign key, OpenSSL::Digest.new('SHA256')
+ store = OpenSSL::X509::Store.new
+ store.add_cert(cert)
+ store.verify(cert).should == false
+ end
+
+ it "returns false for an expired root certificate" do
+ root_key = OpenSSL::PKey::RSA.new 2048
+ root_cert = OpenSSL::X509::Certificate.new
+ root_cert.version = 2
+ root_cert.serial = 1
+ root_cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby CA"
+ root_cert.issuer = root_cert.subject
+ root_cert.public_key = root_key.public_key
+ root_cert.not_before = Time.now - 10
+ root_cert.not_after = Time.now - 5
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.subject_certificate = root_cert
+ ef.issuer_certificate = root_cert
+ root_cert.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
+ root_cert.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
+ root_cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
+ root_cert.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
+ root_cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
+
+
+ key = OpenSSL::PKey::RSA.new 2048
+ cert = OpenSSL::X509::Certificate.new
+ cert.version = 2
+ cert.serial = 2
+ cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby certificate"
+ cert.issuer = root_cert.subject
+ cert.public_key = key.public_key
+ cert.not_before = Time.now
+ cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.subject_certificate = cert
+ ef.issuer_certificate = root_cert
+ cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
+ cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
+ cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
+
+ store = OpenSSL::X509::Store.new
+ store.add_cert(root_cert)
+ store.add_cert(cert)
+ store.verify(cert).should == false
+ end
+end
diff --git a/spec/ruby/library/openssl/x509/store/verify_spec.rb b/spec/ruby/library/openssl/x509/store/verify_spec.rb
deleted file mode 100644
index 6a6a53d992..0000000000
--- a/spec/ruby/library/openssl/x509/store/verify_spec.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-require_relative '../../../../spec_helper'
-require 'openssl'
-
-describe "OpenSSL::X509::Store#verify" do
- it "returns true for valid certificate" do
- key = OpenSSL::PKey::RSA.new 2048
- cert = OpenSSL::X509::Certificate.new
- cert.version = 2
- cert.serial = 1
- cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby CA"
- cert.issuer = cert.subject
- cert.public_key = key.public_key
- cert.not_before = Time.now - 10
- cert.not_after = cert.not_before + 365 * 24 * 60 * 60
- cert.sign key, OpenSSL::Digest.new('SHA256')
- store = OpenSSL::X509::Store.new
- store.add_cert(cert)
- [store.verify(cert), store.error, store.error_string].should == [true, 0, "ok"]
- end
-
- it "returns false for an expired certificate" do
- key = OpenSSL::PKey::RSA.new 2048
- cert = OpenSSL::X509::Certificate.new
- cert.version = 2
- cert.serial = 1
- cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby CA"
- cert.issuer = cert.subject
- cert.public_key = key.public_key
- cert.not_before = Time.now - 10
- cert.not_after = Time.now - 5
- cert.sign key, OpenSSL::Digest.new('SHA256')
- store = OpenSSL::X509::Store.new
- store.add_cert(cert)
- store.verify(cert).should == false
- end
-
- it "returns false for an expired root certificate" do
- root_key = OpenSSL::PKey::RSA.new 2048
- root_cert = OpenSSL::X509::Certificate.new
- root_cert.version = 2
- root_cert.serial = 1
- root_cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby CA"
- root_cert.issuer = root_cert.subject
- root_cert.public_key = root_key.public_key
- root_cert.not_before = Time.now - 10
- root_cert.not_after = Time.now - 5
- ef = OpenSSL::X509::ExtensionFactory.new
- ef.subject_certificate = root_cert
- ef.issuer_certificate = root_cert
- root_cert.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
- root_cert.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
- root_cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
- root_cert.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
- root_cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
-
-
- key = OpenSSL::PKey::RSA.new 2048
- cert = OpenSSL::X509::Certificate.new
- cert.version = 2
- cert.serial = 2
- cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=truffleruby/CN=TruffleRuby certificate"
- cert.issuer = root_cert.subject
- cert.public_key = key.public_key
- cert.not_before = Time.now
- cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60
- ef = OpenSSL::X509::ExtensionFactory.new
- ef.subject_certificate = cert
- ef.issuer_certificate = root_cert
- cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
- cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
- cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
-
- store = OpenSSL::X509::Store.new
- store.add_cert(root_cert)
- store.add_cert(cert)
- store.verify(cert).should == false
- end
-end
diff --git a/spec/ruby/library/pathname/relative_path_from_spec.rb b/spec/ruby/library/pathname/relative_path_from_spec.rb
index 133a149849..abe9c80a45 100644
--- a/spec/ruby/library/pathname/relative_path_from_spec.rb
+++ b/spec/ruby/library/pathname/relative_path_from_spec.rb
@@ -48,8 +48,4 @@ describe "Pathname#relative_path_from" do
relative_path_str('..', '..').should == '.'
relative_path_str('..', '.').should == '..'
end
-
- it 'converts string argument to Pathname' do
- Pathname.new('/usr/bin/ls').relative_path_from('/usr').to_s.should == 'bin/ls'
- end
end
diff --git a/spec/ruby/library/rexml/attribute/clone_spec.rb b/spec/ruby/library/rexml/attribute/clone_spec.rb
new file mode 100644
index 0000000000..5c86468d45
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/clone_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#clone" do
+ it "returns a copy of this Attribute" do
+ orig = REXML::Attribute.new("name", "value&&")
+ orig.should == orig.clone
+ orig.clone.to_s.should == orig.to_s
+ orig.clone.to_string.should == orig.to_string
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/element_spec.rb b/spec/ruby/library/rexml/attribute/element_spec.rb
new file mode 100644
index 0000000000..0e4ce46a4f
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/element_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#element" do
+ it "returns the parent element" do
+ e = REXML::Element.new "root"
+
+ REXML::Attribute.new("name", "value", e).element.should == e
+ REXML::Attribute.new("name", "default_constructor").element.should == nil
+ end
+ end
+
+ describe "REXML::Attribute#element=" do
+ it "sets the parent element" do
+ e = REXML::Element.new "root"
+ f = REXML::Element.new "temp"
+ a = REXML::Attribute.new("name", "value", e)
+ a.element.should == e
+
+ a.element = f
+ a.element.should == f
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/equal_value_spec.rb b/spec/ruby/library/rexml/attribute/equal_value_spec.rb
new file mode 100644
index 0000000000..1498bae624
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/equal_value_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#==" do
+ it "returns true if other has equal name and value" do
+ a1 = REXML::Attribute.new("foo", "bar")
+ a1.should == a1.clone
+
+ a2 = REXML::Attribute.new("foo", "bar")
+ a1.should == a2
+
+ a3 = REXML::Attribute.new("foo", "bla")
+ a1.should_not == a3
+
+ a4 = REXML::Attribute.new("baz", "bar")
+ a1.should_not == a4
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/hash_spec.rb b/spec/ruby/library/rexml/attribute/hash_spec.rb
new file mode 100644
index 0000000000..7e0cbcc1ea
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/hash_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#hash" do
+ # These are not really complete, any idea on how to make them more
+ # "testable" will be appreciated.
+ it "returns a hashcode made of the name and value of self" do
+ a = REXML::Attribute.new("name", "value")
+ a.hash.should be_kind_of(Numeric)
+ b = REXML::Attribute.new(a)
+ a.hash.should == b.hash
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/initialize_spec.rb b/spec/ruby/library/rexml/attribute/initialize_spec.rb
new file mode 100644
index 0000000000..35b87b0733
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/initialize_spec.rb
@@ -0,0 +1,32 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#initialize" do
+ before :each do
+ @e = REXML::Element.new "root"
+ @name = REXML::Attribute.new("name", "Nicko")
+ @e.add_attribute @name
+ end
+
+ it "receives two strings for name and value" do
+ @e.attributes["name"].should == "Nicko"
+ @e.add_attribute REXML::Attribute.new("last_name", nil)
+ @e.attributes["last_name"].should == ""
+ end
+
+ it "receives an Attribute and clones it" do
+ copy = REXML::Attribute.new(@name)
+ copy.should == @name
+ end
+
+ it "receives a parent node" do
+ last_name = REXML::Attribute.new("last_name", "McBrain", @e)
+ last_name.element.should == @e
+
+ last_name = REXML::Attribute.new(@name, @e)
+ last_name.element.should == @e
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/inspect_spec.rb b/spec/ruby/library/rexml/attribute/inspect_spec.rb
new file mode 100644
index 0000000000..ee5236b98e
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/inspect_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#inspect" do
+ it "returns the name and value as a string" do
+ a = REXML::Attribute.new("my_name", "my_value")
+ a.inspect.should == "my_name='my_value'"
+ end
+
+ it "accepts attributes with no value" do
+ a = REXML::Attribute.new("my_name")
+ a.inspect.should == "my_name=''"
+ end
+
+ it "does not escape text" do
+ a = REXML::Attribute.new("name", "<>")
+ a.inspect.should == "name='<>'"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/namespace_spec.rb b/spec/ruby/library/rexml/attribute/namespace_spec.rb
new file mode 100644
index 0000000000..645b3cd1b1
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/namespace_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#namespace" do
+ it "returns the namespace url" do
+ e = REXML::Element.new("root")
+ e.add_attribute REXML::Attribute.new("xmlns:ns", "http://some_uri")
+ e.namespace("ns").should == "http://some_uri"
+ end
+
+ it "returns nil if namespace is not defined" do
+ e = REXML::Element.new("root")
+ e.add_attribute REXML::Attribute.new("test", "value")
+ e.namespace("test").should == nil
+ e.namespace("ns").should == nil
+ end
+
+ it "defaults arg to nil" do
+ e = REXML::Element.new("root")
+ e.add_attribute REXML::Attribute.new("xmlns:ns", "http://some_uri")
+ e.namespace.should == ""
+ e.namespace("ns").should == "http://some_uri"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/node_type_spec.rb b/spec/ruby/library/rexml/attribute/node_type_spec.rb
new file mode 100644
index 0000000000..da055ae8f0
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/node_type_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#node_type" do
+ it "always returns :attribute" do
+ attr = REXML::Attribute.new("foo", "bar")
+ attr.node_type.should == :attribute
+ REXML::Attribute.new(attr).node_type.should == :attribute
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/prefix_spec.rb b/spec/ruby/library/rexml/attribute/prefix_spec.rb
new file mode 100644
index 0000000000..87bff4822b
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/prefix_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#prefix" do
+ it "returns the namespace of the Attribute" do
+ ans = REXML::Attribute.new("ns:someattr", "some_value")
+ out = REXML::Attribute.new("out:something", "some_other_value")
+
+ ans.prefix.should == "ns"
+ out.prefix.should == "out"
+ end
+
+ it "returns an empty string for Attributes with no prefixes" do
+ attr = REXML::Attribute.new("foo", "bar")
+
+ attr.prefix.should == ""
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/remove_spec.rb b/spec/ruby/library/rexml/attribute/remove_spec.rb
new file mode 100644
index 0000000000..5f928b1286
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/remove_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#remove" do
+ before :each do
+ @e = REXML::Element.new "Root"
+ @attr = REXML::Attribute.new("foo", "bar")
+ end
+
+ it "deletes this Attribute from parent" do
+ @e.add_attribute(@attr)
+ @e.attributes["foo"].should_not == nil
+ @attr.remove
+ @e.attributes["foo"].should == nil
+ end
+
+ it "does not anything if element has no parent" do
+ -> {@attr.remove}.should_not raise_error(Exception)
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/to_s_spec.rb b/spec/ruby/library/rexml/attribute/to_s_spec.rb
new file mode 100644
index 0000000000..e362cee8f1
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/to_s_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#to_s" do
+ it "returns the value of the Attribute" do
+ REXML::Attribute.new("name", "some_value").to_s.should == "some_value"
+ end
+
+ it "returns the escaped value if it was created from Attribute" do
+ orig = REXML::Attribute.new("name", "<&>")
+ copy = REXML::Attribute.new(orig)
+ copy.to_s.should == "&lt;&amp;&gt;"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/to_string_spec.rb b/spec/ruby/library/rexml/attribute/to_string_spec.rb
new file mode 100644
index 0000000000..a9d249f5bb
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/to_string_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#to_string" do
+ it "returns the attribute as XML" do
+ attr = REXML::Attribute.new("name", "value")
+ attr_empty = REXML::Attribute.new("name")
+ attr_ns = REXML::Attribute.new("xmlns:ns", "http://uri")
+
+ attr.to_string.should == "name='value'"
+ attr_empty.to_string.should == "name=''"
+ attr_ns.to_string.should == "xmlns:ns='http://uri'"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/value_spec.rb b/spec/ruby/library/rexml/attribute/value_spec.rb
new file mode 100644
index 0000000000..77071f6f70
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/value_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#value" do
+ it "returns the value of the Attribute unnormalized" do
+ attr = REXML::Attribute.new("name", "value")
+ attr_ents = REXML::Attribute.new("name", "<&>")
+ attr_empty = REXML::Attribute.new("name")
+
+ attr.value.should == "value"
+ attr_ents.value.should == "<&>"
+ attr_empty.value.should == ""
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/write_spec.rb b/spec/ruby/library/rexml/attribute/write_spec.rb
new file mode 100644
index 0000000000..0012b3cc77
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/write_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#write" do
+ before :each do
+ @attr = REXML::Attribute.new("name", "Charlotte")
+ @s = ""
+ end
+
+ it "writes the name and value to output" do
+ @attr.write(@s)
+ @s.should == "name='Charlotte'"
+ end
+
+ it "currently ignores the second argument" do
+ @attr.write(@s, 3)
+ @s.should == "name='Charlotte'"
+
+ @s = ""
+ @attr.write(@s, "foo")
+ @s.should == "name='Charlotte'"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attribute/xpath_spec.rb b/spec/ruby/library/rexml/attribute/xpath_spec.rb
new file mode 100644
index 0000000000..0a09046b01
--- /dev/null
+++ b/spec/ruby/library/rexml/attribute/xpath_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attribute#xpath" do
+
+ before :each do
+ @e = REXML::Element.new "root"
+ @attr = REXML::Attribute.new("year", "1989")
+ end
+
+ it "returns the path for Attribute" do
+ @e.add_attribute @attr
+ @attr.xpath.should == "root/@year"
+ end
+
+ it "raises an error if attribute has no parent" do
+ -> { @attr.xpath }.should raise_error(Exception)
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/add_spec.rb b/spec/ruby/library/rexml/attributes/add_spec.rb
new file mode 100644
index 0000000000..e24e9fabbc
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/add_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require_relative 'shared/add'
+ require 'rexml/document'
+
+ describe "REXML::Attributes#add" do
+ it_behaves_like :rexml_attribute_add, :add
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/append_spec.rb b/spec/ruby/library/rexml/attributes/append_spec.rb
new file mode 100644
index 0000000000..f96a727f47
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/append_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require_relative 'shared/add'
+ require 'rexml/document'
+
+ describe "REXML::Attributes#<<" do
+ it_behaves_like :rexml_attribute_add, :<<
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/delete_all_spec.rb b/spec/ruby/library/rexml/attributes/delete_all_spec.rb
new file mode 100644
index 0000000000..707baa235b
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/delete_all_spec.rb
@@ -0,0 +1,34 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#delete_all" do
+ before :each do
+ @e = REXML::Element.new("root")
+ end
+
+ it "deletes all attributes that match name" do
+ uri = REXML::Attribute.new("uri", "http://something")
+ @e.attributes << uri
+ @e.attributes.delete_all("uri")
+ @e.attributes.should be_empty
+ @e.attributes["uri"].should == nil
+ end
+
+ it "deletes all attributes that match name with a namespace" do
+ ns_uri = REXML::Attribute.new("xmlns:uri", "http://something_here_too")
+ @e.attributes << ns_uri
+ @e.attributes.delete_all("xmlns:uri")
+ @e.attributes.should be_empty
+ @e.attributes["xmlns:uri"].should == nil
+ end
+
+ it "returns the removed attribute" do
+ uri = REXML::Attribute.new("uri", "http://something_here_too")
+ @e.attributes << uri
+ attrs = @e.attributes.delete_all("uri")
+ attrs.first.should == uri
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/delete_spec.rb b/spec/ruby/library/rexml/attributes/delete_spec.rb
new file mode 100644
index 0000000000..723fa70751
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/delete_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#delete" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @name = REXML::Attribute.new("name", "Pepe")
+ end
+
+ it "takes an attribute name and deletes the attribute" do
+ @e.attributes.delete("name")
+ @e.attributes["name"].should be_nil
+ @e.attributes.should be_empty
+ end
+
+ it "takes an Attribute and deletes it" do
+ @e.attributes.delete(@name)
+ @e.attributes["name"].should be_nil
+ @e.attributes.should be_empty
+ end
+
+ it "returns the element with the attribute removed" do
+ ret_val = @e.attributes.delete(@name)
+ ret_val.should == @e
+ ret_val.attributes.should be_empty
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/each_attribute_spec.rb b/spec/ruby/library/rexml/attributes/each_attribute_spec.rb
new file mode 100644
index 0000000000..692cf4f943
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/each_attribute_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#each_attribute" do
+ it "iterates over the attributes yielding actual Attribute objects" do
+ e = REXML::Element.new("root")
+ name = REXML::Attribute.new("name", "Joe")
+ ns_uri = REXML::Attribute.new("xmlns:ns", "http://some_uri")
+ e.add_attribute name
+ e.add_attribute ns_uri
+
+ attributes = []
+
+ e.attributes.each_attribute do |attr|
+ attributes << attr
+ end
+
+ attributes = attributes.sort_by {|a| a.name }
+ attributes.first.should == name
+ attributes.last.should == ns_uri
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/each_spec.rb b/spec/ruby/library/rexml/attributes/each_spec.rb
new file mode 100644
index 0000000000..49add3b77b
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/each_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#each" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @name = REXML::Attribute.new("name", "Joe")
+ @ns_uri = REXML::Attribute.new("xmlns:ns", "http://some_uri")
+ @e.add_attribute @name
+ @e.add_attribute @ns_uri
+ end
+
+ it "iterates over the attributes yielding expanded-name/value" do
+ attributes = []
+ @e.attributes.each do |attr|
+ attr.should be_kind_of(Array)
+ attributes << attr
+ end
+ attributes = attributes.sort_by {|a| a.first }
+ attributes.first.should == ["name", "Joe"]
+ attributes.last.should == ["xmlns:ns", "http://some_uri"]
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/element_reference_spec.rb b/spec/ruby/library/rexml/attributes/element_reference_spec.rb
new file mode 100644
index 0000000000..0d089eaab2
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/element_reference_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#[]" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @lang = REXML::Attribute.new("language", "english")
+ @e.attributes << @lang
+ end
+
+ it "returns the value of an attribute" do
+ @e.attributes["language"].should == "english"
+ end
+
+ it "returns nil if the attribute does not exist" do
+ @e.attributes["chunky bacon"].should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/element_set_spec.rb b/spec/ruby/library/rexml/attributes/element_set_spec.rb
new file mode 100644
index 0000000000..834ad682a6
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/element_set_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#[]=" do
+ before :each do
+ @e = REXML::Element.new("song")
+ @name = REXML::Attribute.new("name", "Holy Smoke!")
+ @e.attributes << @name
+ end
+
+ it "sets an attribute" do
+ @e.attributes["author"] = "_why's foxes"
+ @e.attributes["author"].should == "_why's foxes"
+ end
+
+ it "overwrites an existing attribute" do
+ @e.attributes["name"] = "Chunky Bacon"
+ @e.attributes["name"].should == "Chunky Bacon"
+ end
+
+ it "deletes an attribute is value is nil" do
+ @e.attributes["name"] = nil
+ @e.attributes.length.should == 0
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb b/spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb
new file mode 100644
index 0000000000..1109ff519c
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#get_attribute_ns" do
+ it "returns an attribute by name and namespace" do
+ e = REXML::Element.new("root")
+ attr = REXML::Attribute.new("xmlns:ns", "http://some_url")
+ e.attributes << attr
+ attr.prefix.should == "xmlns"
+ # This might be a bug in Attribute, commenting until those specs
+ # are ready
+ # e.attributes.get_attribute_ns(attr.prefix, "name").should == "http://some_url"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/get_attribute_spec.rb b/spec/ruby/library/rexml/attributes/get_attribute_spec.rb
new file mode 100644
index 0000000000..cc94191729
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/get_attribute_spec.rb
@@ -0,0 +1,32 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#get_attribute" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @name = REXML::Attribute.new("name", "Dave")
+ @e.attributes << @name
+ end
+
+ it "fetches an attributes" do
+ @e.attributes.get_attribute("name").should == @name
+ end
+
+ it "fetches an namespaced attribute" do
+ ns_name = REXML::Attribute.new("im:name", "Murray")
+ @e.attributes << ns_name
+ @e.attributes.get_attribute("name").should == @name
+ @e.attributes.get_attribute("im:name").should == ns_name
+ end
+
+ it "returns an Attribute" do
+ @e.attributes.get_attribute("name").should be_kind_of(REXML::Attribute)
+ end
+
+ it "returns nil if it attribute does not exist" do
+ @e.attributes.get_attribute("fake").should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/initialize_spec.rb b/spec/ruby/library/rexml/attributes/initialize_spec.rb
new file mode 100644
index 0000000000..42ec742e60
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/initialize_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#initialize" do
+ it "is auto initialized by Element" do
+ e = REXML::Element.new "root"
+ e.attributes.should be_kind_of(REXML::Attributes)
+
+ e.attributes << REXML::Attribute.new("name", "Paul")
+ e.attributes["name"].should == "Paul"
+ end
+
+ it "receives a parent node" do
+ e = REXML::Element.new "root"
+ e.attributes << REXML::Attribute.new("name", "Vic")
+ e.attributes["name"].should == "Vic"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/length_spec.rb b/spec/ruby/library/rexml/attributes/length_spec.rb
new file mode 100644
index 0000000000..81733b4a96
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/length_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require_relative 'shared/length'
+ require 'rexml/document'
+
+ describe "REXML::Attributes#length" do
+ it_behaves_like :rexml_attribute_length, :length
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/namespaces_spec.rb b/spec/ruby/library/rexml/attributes/namespaces_spec.rb
new file mode 100644
index 0000000000..b88346854f
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/namespaces_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#namespaces" do
+ it "needs to be reviewed for spec completeness"
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/prefixes_spec.rb b/spec/ruby/library/rexml/attributes/prefixes_spec.rb
new file mode 100644
index 0000000000..574b7ffbaf
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/prefixes_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#prefixes" do
+ before :each do
+ @e = REXML::Element.new("root")
+ a1 = REXML::Attribute.new("xmlns:a", "bar")
+ a2 = REXML::Attribute.new("xmlns:b", "bla")
+ a3 = REXML::Attribute.new("xmlns:c", "baz")
+ @e.attributes << a1
+ @e.attributes << a2
+ @e.attributes << a3
+
+ @e.attributes << REXML::Attribute.new("xmlns", "foo")
+ end
+
+ it "returns an array with the prefixes of each attribute" do
+ @e.attributes.prefixes.sort.should == ["a", "b", "c"]
+ end
+
+ it "does not include the default namespace" do
+ @e.attributes.prefixes.include?("xmlns").should == false
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/shared/add.rb b/spec/ruby/library/rexml/attributes/shared/add.rb
new file mode 100644
index 0000000000..872f149f45
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/shared/add.rb
@@ -0,0 +1,17 @@
+describe :rexml_attribute_add, shared: true do
+ before :each do
+ @e = REXML::Element.new("root")
+ @attr = REXML::Attributes.new(@e)
+ @name = REXML::Attribute.new("name", "Joe")
+ end
+
+ it "adds an attribute" do
+ @attr.send(@method, @name)
+ @attr["name"].should == "Joe"
+ end
+
+ it "replaces an existing attribute" do
+ @attr.send(@method, REXML::Attribute.new("name", "Bruce"))
+ @attr["name"].should == "Bruce"
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/shared/length.rb b/spec/ruby/library/rexml/attributes/shared/length.rb
new file mode 100644
index 0000000000..7848f9bf33
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/shared/length.rb
@@ -0,0 +1,13 @@
+require_relative '../../../../spec_helper'
+require 'rexml/document'
+
+describe :rexml_attribute_length, shared: true do
+ it "returns the number of attributes" do
+ e = REXML::Element.new("root")
+ e.attributes.send(@method).should == 0
+
+ e.attributes << REXML::Attribute.new("name", "John")
+ e.attributes << REXML::Attribute.new("another_name", "Leo")
+ e.attributes.send(@method).should == 2
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/size_spec.rb b/spec/ruby/library/rexml/attributes/size_spec.rb
new file mode 100644
index 0000000000..13ef08f644
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/size_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require_relative 'shared/length'
+ require 'rexml/document'
+
+ describe "REXML::Attributes#size" do
+ it_behaves_like :rexml_attribute_length, :size
+ end
+end
diff --git a/spec/ruby/library/rexml/attributes/to_a_spec.rb b/spec/ruby/library/rexml/attributes/to_a_spec.rb
new file mode 100644
index 0000000000..902cd86a29
--- /dev/null
+++ b/spec/ruby/library/rexml/attributes/to_a_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Attributes#to_a" do
+ it "returns an array with the attributes" do
+ e = REXML::Element.new("root")
+ name = REXML::Attribute.new("name", "Dave")
+ last = REXML::Attribute.new("last_name", "Murray")
+
+ e.attributes << name
+ e.attributes << last
+
+ e.attributes.to_a.sort{|a,b|a.to_s<=>b.to_s}.should == [name, last]
+ end
+
+ it "returns an empty array if it has no attributes" do
+ REXML::Element.new("root").attributes.to_a.should == []
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/cdata/clone_spec.rb b/spec/ruby/library/rexml/cdata/clone_spec.rb
new file mode 100644
index 0000000000..abe1a0b062
--- /dev/null
+++ b/spec/ruby/library/rexml/cdata/clone_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::CData#clone" do
+ it "makes a copy of itself" do
+ c = REXML::CData.new("some text")
+ c.clone.to_s.should == c.to_s
+ c.clone.should == c
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/cdata/initialize_spec.rb b/spec/ruby/library/rexml/cdata/initialize_spec.rb
new file mode 100644
index 0000000000..1393d97f4a
--- /dev/null
+++ b/spec/ruby/library/rexml/cdata/initialize_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::CData#initialize" do
+ it "creates a new CData object" do
+ c = REXML::CData.new("some text")
+ c.should be_kind_of(REXML::CData)
+ c.should be_kind_of(REXML::Text)
+ end
+
+ it "respects whitespace if whitespace is true" do
+ c = REXML::CData.new("whitespace test", true)
+ c1 = REXML::CData.new("whitespace test", false)
+
+ c.to_s.should == "whitespace test"
+ c1.to_s.should == "whitespace test"
+ end
+
+ it "receives parent as third argument" do
+ e = REXML::Element.new("root")
+ REXML::CData.new("test", true, e)
+ e.to_s.should == "<root><![CDATA[test]]></root>"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/cdata/shared/to_s.rb b/spec/ruby/library/rexml/cdata/shared/to_s.rb
new file mode 100644
index 0000000000..f8c4951c95
--- /dev/null
+++ b/spec/ruby/library/rexml/cdata/shared/to_s.rb
@@ -0,0 +1,11 @@
+describe :rexml_cdata_to_s, shared: true do
+ it "returns the contents of the CData" do
+ c = REXML::CData.new("some text")
+ c.send(@method).should == "some text"
+ end
+
+ it "does not escape text" do
+ c1 = REXML::CData.new("some& text\n")
+ c1.send(@method).should == "some& text\n"
+ end
+end
diff --git a/spec/ruby/library/rexml/cdata/to_s_spec.rb b/spec/ruby/library/rexml/cdata/to_s_spec.rb
new file mode 100644
index 0000000000..a5c061f116
--- /dev/null
+++ b/spec/ruby/library/rexml/cdata/to_s_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require_relative 'shared/to_s'
+ require 'rexml/document'
+
+ describe "REXML::CData#to_s" do
+ it_behaves_like :rexml_cdata_to_s, :to_s
+ end
+end
diff --git a/spec/ruby/library/rexml/cdata/value_spec.rb b/spec/ruby/library/rexml/cdata/value_spec.rb
new file mode 100644
index 0000000000..9f36226976
--- /dev/null
+++ b/spec/ruby/library/rexml/cdata/value_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require_relative 'shared/to_s'
+ require 'rexml/document'
+
+ describe "REXML::CData#value" do
+ it_behaves_like :rexml_cdata_to_s, :value
+ end
+end
diff --git a/spec/ruby/library/rexml/document/add_element_spec.rb b/spec/ruby/library/rexml/document/add_element_spec.rb
new file mode 100644
index 0000000000..29dec0b24e
--- /dev/null
+++ b/spec/ruby/library/rexml/document/add_element_spec.rb
@@ -0,0 +1,34 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#add_element" do
+ it "adds arg1 with attributes arg2 as root node" do
+ d = REXML::Document.new
+ e = REXML::Element.new("root")
+ d.add_element e
+ d.root.should == e
+ end
+
+ it "sets arg2 as arg1's attributes" do
+ d = REXML::Document.new
+ e = REXML::Element.new("root")
+ attr = {"foo" => "bar"}
+ d.add_element(e,attr)
+ d.root.attributes["foo"].should == attr["foo"]
+ end
+
+ it "accepts a node name as arg1 and adds it as root" do
+ d = REXML::Document.new
+ d.add_element "foo"
+ d.root.name.should == "foo"
+ end
+
+ it "sets arg1's context to the root's context" do
+ d = REXML::Document.new("", {"foo" => "bar"})
+ d.add_element "foo"
+ d.root.context.should == d.context
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/add_spec.rb b/spec/ruby/library/rexml/document/add_spec.rb
new file mode 100644
index 0000000000..8666d3dbf9
--- /dev/null
+++ b/spec/ruby/library/rexml/document/add_spec.rb
@@ -0,0 +1,60 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ # This spec defines Document#add and Document#<<
+
+ describe :rexml_document_add, shared: true do
+ before :each do
+ @doc = REXML::Document.new("<root/>")
+ @decl = REXML::XMLDecl.new("1.0")
+ end
+
+ it "sets document's XML declaration" do
+ @doc.send(@method, @decl)
+ @doc.xml_decl.should == @decl
+ end
+
+ it "inserts XML declaration as first node" do
+ @doc.send(@method, @decl)
+ @doc.children[0].version.should == "1.0"
+ end
+
+ it "overwrites existing XML declaration" do
+ @doc.send(@method, @decl)
+ @doc.send(@method, REXML::XMLDecl.new("2.0"))
+ @doc.xml_decl.version.should == "2.0"
+ end
+
+ it "sets document DocType" do
+ @doc.send(@method, REXML::DocType.new("transitional"))
+ @doc.doctype.name.should == "transitional"
+ end
+
+ it "overwrites existing DocType" do
+ @doc.send(@method, REXML::DocType.new("transitional"))
+ @doc.send(@method, REXML::DocType.new("strict"))
+ @doc.doctype.name.should == "strict"
+ end
+
+ it "adds root node unless it exists" do
+ d = REXML::Document.new("")
+ elem = REXML::Element.new "root"
+ d.send(@method, elem)
+ d.root.should == elem
+ end
+
+ it "refuses to add second root" do
+ -> { @doc.send(@method, REXML::Element.new("foo")) }.should raise_error(RuntimeError)
+ end
+ end
+
+ describe "REXML::Document#add" do
+ it_behaves_like :rexml_document_add, :add
+ end
+
+ describe "REXML::Document#<<" do
+ it_behaves_like :rexml_document_add, :<<
+ end
+end
diff --git a/spec/ruby/library/rexml/document/clone_spec.rb b/spec/ruby/library/rexml/document/clone_spec.rb
new file mode 100644
index 0000000000..137fe8a073
--- /dev/null
+++ b/spec/ruby/library/rexml/document/clone_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ # According to the MRI documentation (http://www.ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html),
+ # clone's behavior "should be obvious". Apparently "obvious" means cloning
+ # only the attributes and the context of the document, not its children.
+ describe "REXML::Document#clone" do
+ it "clones document attributes" do
+ d = REXML::Document.new("foo")
+ d.attributes["foo"] = "bar"
+ e = d.clone
+ e.attributes.should == d.attributes
+ end
+
+ it "clones document context" do
+ d = REXML::Document.new("foo", {"foo" => "bar"})
+ e = d.clone
+ e.context.should == d.context
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/doctype_spec.rb b/spec/ruby/library/rexml/document/doctype_spec.rb
new file mode 100644
index 0000000000..e1b7ba4916
--- /dev/null
+++ b/spec/ruby/library/rexml/document/doctype_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#doctype" do
+ it "returns the doctype" do
+ d = REXML::Document.new
+ dt = REXML::DocType.new("foo")
+ d.add dt
+ d.doctype.should == dt
+ end
+
+ it "returns nil if there's no doctype" do
+ REXML::Document.new.doctype.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/encoding_spec.rb b/spec/ruby/library/rexml/document/encoding_spec.rb
new file mode 100644
index 0000000000..2cc947f06a
--- /dev/null
+++ b/spec/ruby/library/rexml/document/encoding_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#encoding" do
+ before :each do
+ @doc = REXML::Document.new
+ end
+
+ it "returns encoding from XML declaration" do
+ @doc.add REXML::XMLDecl.new(nil, "UTF-16", nil)
+ @doc.encoding.should == "UTF-16"
+ end
+
+ it "returns encoding from XML declaration (for UTF-16 as well)" do
+ @doc.add REXML::XMLDecl.new("1.0", "UTF-8", nil)
+ @doc.encoding.should == "UTF-8"
+ end
+
+ it "uses UTF-8 as default encoding" do
+ @doc.encoding.should == "UTF-8"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/expanded_name_spec.rb b/spec/ruby/library/rexml/document/expanded_name_spec.rb
new file mode 100644
index 0000000000..9d1025b5e0
--- /dev/null
+++ b/spec/ruby/library/rexml/document/expanded_name_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe :document_expanded_name, shared: true do
+ it "returns an empty string for root" do # root nodes have no expanded name
+ REXML::Document.new.send(@method).should == ""
+ end
+ end
+
+ describe "REXML::Document#expanded_name" do
+ it_behaves_like :document_expanded_name, :expanded_name
+ end
+
+ describe "REXML::Document#name" do
+ it_behaves_like :document_expanded_name, :name
+ end
+end
diff --git a/spec/ruby/library/rexml/document/new_spec.rb b/spec/ruby/library/rexml/document/new_spec.rb
new file mode 100644
index 0000000000..4e24b6f5a1
--- /dev/null
+++ b/spec/ruby/library/rexml/document/new_spec.rb
@@ -0,0 +1,39 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#new" do
+
+ it "initializes context of {} unless specified" do
+ d = REXML::Document.new("<foo />")
+ d.context.should == {}
+ end
+
+ it "has empty attributes if source is nil" do
+ d = REXML::Document.new(nil)
+ d.elements.should be_empty
+ end
+
+ it "can use other document context" do
+ s = REXML::Document.new("")
+ d = REXML::Document.new(s)
+ d.context.should == s.context
+ end
+
+ it "clones source attributes" do
+ s = REXML::Document.new("<root />")
+ s.attributes["some_attr"] = "some_val"
+ d = REXML::Document.new(s)
+ d.attributes.should == s.attributes
+ end
+
+ it "raises an error if source is not a Document, String or IO" do
+ -> {REXML::Document.new(3)}.should raise_error(RuntimeError)
+ end
+
+ it "does not perform XML validation" do
+ REXML::Document.new("Invalid document").should be_kind_of(REXML::Document)
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/node_type_spec.rb b/spec/ruby/library/rexml/document/node_type_spec.rb
new file mode 100644
index 0000000000..b6d7e7a7da
--- /dev/null
+++ b/spec/ruby/library/rexml/document/node_type_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#node_type" do
+ it "returns :document" do
+ REXML::Document.new.node_type.should == :document
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/root_spec.rb b/spec/ruby/library/rexml/document/root_spec.rb
new file mode 100644
index 0000000000..1a584a720b
--- /dev/null
+++ b/spec/ruby/library/rexml/document/root_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#root" do
+ it "returns document root tag name" do
+ REXML::Document.new("<foo/>").root.name.should == "foo"
+ end
+
+ it "returns nil if there is not root" do
+ REXML::Document.new.root.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/stand_alone_spec.rb b/spec/ruby/library/rexml/document/stand_alone_spec.rb
new file mode 100644
index 0000000000..e1c721e782
--- /dev/null
+++ b/spec/ruby/library/rexml/document/stand_alone_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#stand_alone?" do
+ it "returns the XMLDecl standalone value" do
+ d = REXML::Document.new
+ decl = REXML::XMLDecl.new("1.0", "UTF-8", "yes")
+ d.add decl
+ d.stand_alone?.should == "yes"
+ end
+
+ # According to the docs this should return the default XMLDecl but that
+ # will carry some more problems when printing the document. Currently, it
+ # returns nil. See http://www.ruby-forum.com/topic/146812#650061
+ it "returns the default value when no XML declaration present" do
+ REXML::Document.new.stand_alone?.should == nil
+ end
+
+ end
+end
diff --git a/spec/ruby/library/rexml/document/version_spec.rb b/spec/ruby/library/rexml/document/version_spec.rb
new file mode 100644
index 0000000000..4f6b40551b
--- /dev/null
+++ b/spec/ruby/library/rexml/document/version_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#version" do
+ it "returns XML version from declaration" do
+ d = REXML::Document.new
+ d.add REXML::XMLDecl.new("1.1")
+ d.version.should == "1.1"
+ end
+
+ it "returns the default version when declaration is not present" do
+ REXML::Document.new.version.should == REXML::XMLDecl::DEFAULT_VERSION
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/write_spec.rb b/spec/ruby/library/rexml/document/write_spec.rb
new file mode 100644
index 0000000000..00c22141b3
--- /dev/null
+++ b/spec/ruby/library/rexml/document/write_spec.rb
@@ -0,0 +1,38 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+ require 'rexml/formatters/transitive'
+
+ # Maybe this can be cleaned
+ describe "REXML::Document#write" do
+ before :each do
+ @d = REXML::Document.new
+ city = REXML::Element.new "Springfield"
+ street = REXML::Element.new "EvergreenTerrace"
+ address = REXML::Element.new "House742"
+ @d << city << street << address
+ @str = ""
+ end
+
+ it "returns document source as string" do
+ @d.write(@str)
+ @str.should == "<Springfield><EvergreenTerrace><House742/></EvergreenTerrace></Springfield>"
+ end
+
+ it "returns document indented" do
+ @d.write(@str, 2)
+ @str.should =~ /\s*<Springfield>\s*<EvergreenTerrace>\s*<House742\/>\s*<\/EvergreenTerrace>\s*<\/Springfield>/
+ end
+
+ it "returns document with transitive support" do
+ @d.write(@str, 2, true)
+ @str.should =~ /\s*<Springfield\s*><EvergreenTerrace\s*><House742\s*\/><\/EvergreenTerrace\s*><\/Springfield\s*>/
+ end
+
+ it "returns document with support for IE" do
+ @d.write(@str, -1, false, true)
+ @str.should == "<Springfield><EvergreenTerrace><House742 /></EvergreenTerrace></Springfield>"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/document/xml_decl_spec.rb b/spec/ruby/library/rexml/document/xml_decl_spec.rb
new file mode 100644
index 0000000000..8ac47510b0
--- /dev/null
+++ b/spec/ruby/library/rexml/document/xml_decl_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document#xml_decl" do
+ it "returns XML declaration of the document" do
+ d = REXML::Document.new
+ decl = REXML::XMLDecl.new("1.0", "UTF-16", "yes")
+ d.add decl
+ d.xml_decl.should == decl
+ end
+
+ it "returns default XML declaration unless present" do
+ REXML::Document.new.xml_decl.should == REXML::XMLDecl.new
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/add_attribute_spec.rb b/spec/ruby/library/rexml/element/add_attribute_spec.rb
new file mode 100644
index 0000000000..64f2ec84a3
--- /dev/null
+++ b/spec/ruby/library/rexml/element/add_attribute_spec.rb
@@ -0,0 +1,44 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#add_attribute" do
+ before :each do
+ @person = REXML::Element.new "person"
+ @person.attributes["name"] = "Bill"
+ end
+
+ it "adds a new attribute" do
+ @person.add_attribute("age", "17")
+ @person.attributes["age"].should == "17"
+ end
+
+ it "overwrites an existing attribute" do
+ @person.add_attribute("name", "Bill")
+ @person.attributes["name"].should == "Bill"
+ end
+
+ it "accepts a pair of strings" do
+ @person.add_attribute("male", "true")
+ @person.attributes["male"].should == "true"
+ end
+
+ it "accepts an Attribute for key" do
+ attr = REXML::Attribute.new("male", "true")
+ @person.add_attribute attr
+ @person.attributes["male"].should == "true"
+ end
+
+ it "ignores value if key is an Attribute" do
+ attr = REXML::Attribute.new("male", "true")
+ @person.add_attribute(attr, "false")
+ @person.attributes["male"].should == "true"
+ end
+
+ it "returns the attribute added" do
+ attr = REXML::Attribute.new("name", "Tony")
+ @person.add_attribute(attr).should == attr
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/add_attributes_spec.rb b/spec/ruby/library/rexml/element/add_attributes_spec.rb
new file mode 100644
index 0000000000..f331803dd8
--- /dev/null
+++ b/spec/ruby/library/rexml/element/add_attributes_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#add_attributes" do
+ before :each do
+ @person = REXML::Element.new "person"
+ @person.attributes["name"] = "Bill"
+ end
+
+ it "adds multiple attributes from a hash" do
+ @person.add_attributes({"name" => "Joe", "age" => "27"})
+ @person.attributes["name"].should == "Joe"
+ @person.attributes["age"].should == "27"
+ end
+
+ it "adds multiple attributes from an array" do
+ attrs = { "name" => "Joe", "age" => "27"}
+ @person.add_attributes attrs.to_a
+ @person.attributes["name"].should == "Joe"
+ @person.attributes["age"].should == "27"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/add_element_spec.rb b/spec/ruby/library/rexml/element/add_element_spec.rb
new file mode 100644
index 0000000000..8ba023f2c7
--- /dev/null
+++ b/spec/ruby/library/rexml/element/add_element_spec.rb
@@ -0,0 +1,41 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#add_element" do
+ before :each do
+ @root = REXML::Element.new("root")
+ end
+
+ it "adds a child without attributes" do
+ name = REXML::Element.new("name")
+ @root.add_element name
+ @root.elements["name"].name.should == name.name
+ @root.elements["name"].attributes.should == name.attributes
+ @root.elements["name"].context.should == name.context
+ end
+
+ it "adds a child with attributes" do
+ person = REXML::Element.new("person")
+ @root.add_element(person, {"name" => "Madonna"})
+ @root.elements["person"].name.should == person.name
+ @root.elements["person"].attributes.should == person.attributes
+ @root.elements["person"].context.should == person.context
+ end
+
+ it "adds a child with name" do
+ @root.add_element "name"
+ @root.elements["name"].name.should == "name"
+ @root.elements["name"].attributes.should == {}
+ @root.elements["name"].context.should == nil
+ end
+
+ it "returns the added child" do
+ name = @root.add_element "name"
+ @root.elements["name"].name.should == name.name
+ @root.elements["name"].attributes.should == name.attributes
+ @root.elements["name"].context.should == name.context
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/add_namespace_spec.rb b/spec/ruby/library/rexml/element/add_namespace_spec.rb
new file mode 100644
index 0000000000..44b074bac7
--- /dev/null
+++ b/spec/ruby/library/rexml/element/add_namespace_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#add_namespace" do
+ before :each do
+ @elem = REXML::Element.new("person")
+ end
+
+ it "adds a namespace to element" do
+ @elem.add_namespace("foo", "bar")
+ @elem.namespace("foo").should == "bar"
+ end
+
+ it "accepts a prefix string as prefix" do
+ @elem.add_namespace("xmlns:foo", "bar")
+ @elem.namespace("foo").should == "bar"
+ end
+
+ it "uses prefix as URI if uri is nil" do
+ @elem.add_namespace("some_uri", nil)
+ @elem.namespace.should == "some_uri"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/add_text_spec.rb b/spec/ruby/library/rexml/element/add_text_spec.rb
new file mode 100644
index 0000000000..3a0531ad42
--- /dev/null
+++ b/spec/ruby/library/rexml/element/add_text_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#add_text" do
+ before :each do
+ @name = REXML::Element.new "Name"
+ end
+
+ it "adds text to an element" do
+ @name.add_text "Ringo"
+ @name.to_s.should == "<Name>Ringo</Name>"
+ end
+
+ it "accepts a Text" do
+ @name.add_text(REXML::Text.new("Ringo"))
+ @name.to_s.should == "<Name>Ringo</Name>"
+ end
+
+ it "joins the new text with the old one" do
+ @name.add_text "Ringo"
+ @name.add_text " Starr"
+ @name.to_s.should == "<Name>Ringo Starr</Name>"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/attribute_spec.rb b/spec/ruby/library/rexml/element/attribute_spec.rb
new file mode 100644
index 0000000000..b223d3440c
--- /dev/null
+++ b/spec/ruby/library/rexml/element/attribute_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#attribute" do
+ it "returns an attribute by name" do
+ person = REXML::Element.new "Person"
+ attribute = REXML::Attribute.new("drink", "coffee")
+ person.add_attribute(attribute)
+ person.attribute("drink").should == attribute
+ end
+
+ it "supports attributes inside namespaces" do
+ e = REXML::Element.new("element")
+ e.add_attributes({"xmlns:ns" => "http://some_uri"})
+ e.attribute("ns", "ns").to_s.should == "http://some_uri"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/attributes_spec.rb b/spec/ruby/library/rexml/element/attributes_spec.rb
new file mode 100644
index 0000000000..92bcecc40a
--- /dev/null
+++ b/spec/ruby/library/rexml/element/attributes_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#attributes" do
+ it "returns element's Attributes" do
+ p = REXML::Element.new "Person"
+
+ name = REXML::Attribute.new("name", "John")
+ attrs = REXML::Attributes.new(p)
+ attrs.add name
+
+ p.add_attribute name
+ p.attributes.should == attrs
+ end
+
+ it "returns an empty hash if element has no attributes" do
+ REXML::Element.new("Person").attributes.should == {}
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/cdatas_spec.rb b/spec/ruby/library/rexml/element/cdatas_spec.rb
new file mode 100644
index 0000000000..988b2cb422
--- /dev/null
+++ b/spec/ruby/library/rexml/element/cdatas_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#cdatas" do
+ before :each do
+ @e = REXML::Element.new("Root")
+ end
+
+ it "returns the array of children cdatas" do
+ c = REXML::CData.new("Primary")
+ d = REXML::CData.new("Secondary")
+ @e << c
+ @e << d
+ @e.cdatas.should == [c, d]
+ end
+
+ it "freezes the returned array" do
+ @e.cdatas.should.frozen?
+ end
+
+ it "returns an empty array if element has no cdata" do
+ @e.cdatas.should == []
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/clone_spec.rb b/spec/ruby/library/rexml/element/clone_spec.rb
new file mode 100644
index 0000000000..490e43181f
--- /dev/null
+++ b/spec/ruby/library/rexml/element/clone_spec.rb
@@ -0,0 +1,32 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#clone" do
+ before :each do
+ @e = REXML::Element.new "a"
+ end
+ it "creates a copy of element" do
+ @e.clone.to_s.should == @e.to_s
+ end
+
+ it "copies the attributes" do
+ @e.add_attribute("foo", "bar")
+ @e.clone.to_s.should == @e.to_s
+ end
+
+ it "does not copy the text" do
+ @e.add_text "some text..."
+ @e.clone.to_s.should_not == @e
+ @e.clone.to_s.should == "<a/>"
+ end
+
+ it "does not copy the child elements" do
+ b = REXML::Element.new "b"
+ @e << b
+ @e.clone.should_not == @e
+ @e.clone.to_s.should == "<a/>"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/comments_spec.rb b/spec/ruby/library/rexml/element/comments_spec.rb
new file mode 100644
index 0000000000..84ab9a7469
--- /dev/null
+++ b/spec/ruby/library/rexml/element/comments_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#comments" do
+ before :each do
+ @e = REXML::Element.new "root"
+ @c1 = REXML::Comment.new "this is a comment"
+ @c2 = REXML::Comment.new "this is another comment"
+ @e << @c1
+ @e << @c2
+ end
+
+ it "returns the array of comments" do
+ @e.comments.should == [@c1, @c2]
+ end
+
+ it "returns a frozen object" do
+ @e.comments.should.frozen?
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/delete_attribute_spec.rb b/spec/ruby/library/rexml/element/delete_attribute_spec.rb
new file mode 100644
index 0000000000..e2ba81eb0d
--- /dev/null
+++ b/spec/ruby/library/rexml/element/delete_attribute_spec.rb
@@ -0,0 +1,42 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#delete_attribute" do
+ before :each do
+ @e = REXML::Element.new("Person")
+ @attr = REXML::Attribute.new("name", "Sean")
+ @e.add_attribute(@attr)
+ end
+
+ it "deletes an attribute from the element" do
+ @e.delete_attribute("name")
+ @e.attributes["name"].should be_nil
+ end
+
+ # Bug was filled with a patch in Ruby's tracker #20298
+ quarantine! do
+ it "receives an Attribute" do
+ @e.add_attribute(@attr)
+ @e.delete_attribute(@attr)
+ @e.attributes["name"].should be_nil
+ end
+ end
+
+ # Docs say that it returns the removed attribute but then examples
+ # show it returns the element with the attribute removed.
+ # Also fixed in #20298
+ it "returns the element with the attribute removed" do
+ elem = @e.delete_attribute("name")
+ elem.attributes.should be_empty
+ elem.to_s.should eql("<Person/>")
+ end
+
+ it "returns nil if the attribute does not exist" do
+ @e.delete_attribute("name")
+ at = @e.delete_attribute("name")
+ at.should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/delete_element_spec.rb b/spec/ruby/library/rexml/element/delete_element_spec.rb
new file mode 100644
index 0000000000..c0b486a6f7
--- /dev/null
+++ b/spec/ruby/library/rexml/element/delete_element_spec.rb
@@ -0,0 +1,52 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#delete_element" do
+ before :each do
+ @root = REXML::Element.new("root")
+ end
+
+ it "deletes the child element" do
+ node = REXML::Element.new("some_node")
+ @root.add_element node
+ @root.delete_element node
+ @root.elements.size.should == 0
+ end
+
+ it "deletes a child via XPath" do
+ @root.add_element "some_node"
+ @root.delete_element "some_node"
+ @root.elements.size.should == 0
+ end
+
+ it "deletes the child at index" do
+ @root.add_element "some_node"
+ @root.delete_element 1
+ @root.elements.size.should == 0
+ end
+
+ # According to the docs this should return the deleted element
+ # but it won't if it's an Element.
+ it "deletes Element and returns it" do
+ node = REXML::Element.new("some_node")
+ @root.add_element node
+ del_node = @root.delete_element node
+ del_node.should == node
+ end
+
+ # Note how passing the string will return the removed element
+ # but passing the Element as above won't.
+ it "deletes an element and returns it" do
+ node = REXML::Element.new("some_node")
+ @root.add_element node
+ del_node = @root.delete_element "some_node"
+ del_node.should == node
+ end
+
+ it "returns nil unless element exists" do
+ @root.delete_element("something").should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/delete_namespace_spec.rb b/spec/ruby/library/rexml/element/delete_namespace_spec.rb
new file mode 100644
index 0000000000..a7763d51e8
--- /dev/null
+++ b/spec/ruby/library/rexml/element/delete_namespace_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#delete_namespace" do
+
+ before :each do
+ @doc = REXML::Document.new "<a xmlns:foo='bar' xmlns='twiddle'/>"
+ end
+
+ it "deletes a namespace from the element" do
+ @doc.root.delete_namespace 'foo'
+ @doc.root.namespace("foo").should be_nil
+ @doc.root.to_s.should == "<a xmlns='twiddle'/>"
+ end
+
+ it "deletes default namespace when called with no args" do
+ @doc.root.delete_namespace
+ @doc.root.namespace.should be_empty
+ @doc.root.to_s.should == "<a xmlns:foo='bar'/>"
+ end
+
+ it "returns the element" do
+ @doc.root.delete_namespace.should == @doc.root
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/document_spec.rb b/spec/ruby/library/rexml/element/document_spec.rb
new file mode 100644
index 0000000000..754f27d8a0
--- /dev/null
+++ b/spec/ruby/library/rexml/element/document_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#document" do
+
+ it "returns the element's document" do
+ d = REXML::Document.new("<root><elem/></root>")
+ d << REXML::XMLDecl.new
+ d.root.document.should == d
+ d.root.document.to_s.should == d.to_s
+ end
+
+ it "returns nil if it belongs to no document" do
+ REXML::Element.new("standalone").document.should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb b/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb
new file mode 100644
index 0000000000..dcc6dbbf17
--- /dev/null
+++ b/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb
@@ -0,0 +1,38 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#each_element_with_attributes" do
+ before :each do
+ @document = REXML::Element.new("people")
+ @father = REXML::Element.new("Person")
+ @father.attributes["name"] = "Joe"
+ @son = REXML::Element.new("Child")
+ @son.attributes["name"] = "Fred"
+ @document.root << @father
+ @document.root << @son
+ @children = []
+ end
+
+ it "returns children with attribute" do
+ @document.each_element_with_attribute("name") { |elem| @children << elem }
+ @children[0].should == @father
+ @children[1].should == @son
+ end
+
+ it "takes attribute value as second argument" do
+ @document.each_element_with_attribute("name", "Fred"){ |elem| elem.should == @son }
+ end
+
+ it "takes max number of children as third argument" do
+ @document.each_element_with_attribute("name", nil, 1) { |elem| @children << elem }
+ @children.size.should == 1
+ @children[0].should == @father
+ end
+
+ it "takes XPath filter as fourth argument" do
+ @document.each_element_with_attribute("name", nil, 0, "Child"){ |elem| elem.should == @son}
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/each_element_with_text_spec.rb b/spec/ruby/library/rexml/element/each_element_with_text_spec.rb
new file mode 100644
index 0000000000..a4a200d237
--- /dev/null
+++ b/spec/ruby/library/rexml/element/each_element_with_text_spec.rb
@@ -0,0 +1,34 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#each_element_with_text" do
+ before :each do
+ @document = REXML::Element.new("people")
+
+ @joe = REXML::Element.new("Person")
+ @joe.text = "Joe"
+ @fred = REXML::Element.new("Person")
+ @fred.text = "Fred"
+ @another = REXML::Element.new("AnotherPerson")
+ @another.text = "Fred"
+ @document.root << @joe
+ @document.root << @fred
+ @document.root << @another
+ @children = []
+ end
+
+ it "returns children with text" do
+ @document.each_element_with_text("Joe"){|c| c.should == @joe}
+ end
+
+ it "takes max as second argument" do
+ @document.each_element_with_text("Fred", 1){ |c| c.should == @fred}
+ end
+
+ it "takes XPath filter as third argument" do
+ @document.each_element_with_text("Fred", 0, "Person"){ |c| c.should == @fred}
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/element_reference_spec.rb b/spec/ruby/library/rexml/element/element_reference_spec.rb
new file mode 100644
index 0000000000..9e5d371ce4
--- /dev/null
+++ b/spec/ruby/library/rexml/element/element_reference_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#[]" do
+
+ before :each do
+ @doc = REXML::Document.new("<root foo='bar'></root>")
+ @child = REXML::Element.new("child")
+ @doc.root.add_element @child
+ end
+
+ it "return attribute value if argument is string or symbol" do
+ @doc.root[:foo].should == 'bar'
+ @doc.root['foo'].should == 'bar'
+ end
+
+ it "return nth element if argument is int" do
+ @doc.root[0].should == @child
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/get_text_spec.rb b/spec/ruby/library/rexml/element/get_text_spec.rb
new file mode 100644
index 0000000000..0fa8d7cb3f
--- /dev/null
+++ b/spec/ruby/library/rexml/element/get_text_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#get_text" do
+ before :each do
+ @doc = REXML::Document.new "<p>some text<b>this is bold!</b> more text</p>"
+ end
+
+ it "returns the first text child node" do
+ @doc.root.get_text.value.should == "some text"
+ @doc.root.get_text.should be_kind_of(REXML::Text)
+ end
+
+ it "returns text from an element matching path" do
+ @doc.root.get_text("b").value.should == "this is bold!"
+ @doc.root.get_text("b").should be_kind_of(REXML::Text)
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/has_attributes_spec.rb b/spec/ruby/library/rexml/element/has_attributes_spec.rb
new file mode 100644
index 0000000000..af3ce8ce1b
--- /dev/null
+++ b/spec/ruby/library/rexml/element/has_attributes_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#has_attributes?" do
+ before :each do
+ @e = REXML::Element.new("test_elem")
+ end
+
+ it "returns true when element has any attributes" do
+ @e.add_attribute("name", "Joe")
+ @e.has_attributes?.should be_true
+ end
+
+ it "returns false if element has no attributes" do
+ @e.has_attributes?.should be_false
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/has_elements_spec.rb b/spec/ruby/library/rexml/element/has_elements_spec.rb
new file mode 100644
index 0000000000..04c7fe01a5
--- /dev/null
+++ b/spec/ruby/library/rexml/element/has_elements_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#has_elements?" do
+ before :each do
+ @e = REXML::Element.new("root")
+ end
+
+ it "returns true if element has child elements" do
+ child = REXML::Element.new("child")
+ @e << child
+ @e.has_elements?.should be_true
+ end
+
+ it "returns false if element doesn't have child elements" do
+ @e.has_elements?.should be_false
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/has_text_spec.rb b/spec/ruby/library/rexml/element/has_text_spec.rb
new file mode 100644
index 0000000000..206c167ae6
--- /dev/null
+++ b/spec/ruby/library/rexml/element/has_text_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#has_text?" do
+
+ it "returns true if element has a Text child" do
+ e = REXML::Element.new("Person")
+ e.text = "My text"
+ e.has_text?.should be_true
+ end
+
+ it "returns false if it has no Text children" do
+ e = REXML::Element.new("Person")
+ e.has_text?.should be_false
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/inspect_spec.rb b/spec/ruby/library/rexml/element/inspect_spec.rb
new file mode 100644
index 0000000000..ec16c136ee
--- /dev/null
+++ b/spec/ruby/library/rexml/element/inspect_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#inspect" do
+
+ before :each do
+ @name = REXML::Element.new "name"
+ end
+
+ it "returns the node as a string" do
+ @name.inspect.should == "<name/>"
+ end
+
+ it "inserts '...' if the node has children" do
+ e = REXML::Element.new "last_name"
+ @name << e
+ @name.inspect.should == "<name> ... </>"
+ # This might make more sense but differs from MRI's default behavior
+ # @name.inspect.should == "<name> ... </name>"
+ end
+
+ it "inserts the attributes in the string" do
+ @name.add_attribute "language"
+ @name.attributes["language"] = "english"
+ @name.inspect.should == "<name language='english'/>"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/instructions_spec.rb b/spec/ruby/library/rexml/element/instructions_spec.rb
new file mode 100644
index 0000000000..11f1396df0
--- /dev/null
+++ b/spec/ruby/library/rexml/element/instructions_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#instructions" do
+ before :each do
+ @elem = REXML::Element.new("root")
+ end
+ it "returns the Instruction children nodes" do
+ inst = REXML::Instruction.new("xml-stylesheet", "href='headlines.css'")
+ @elem << inst
+ @elem.instructions.first.should == inst
+ end
+
+ it "returns an empty array if it has no Instruction children" do
+ @elem.instructions.should be_empty
+ end
+
+ it "freezes the returned array" do
+ @elem.instructions.frozen?.should be_true
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/namespace_spec.rb b/spec/ruby/library/rexml/element/namespace_spec.rb
new file mode 100644
index 0000000000..28966289c5
--- /dev/null
+++ b/spec/ruby/library/rexml/element/namespace_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#namespace" do
+ before :each do
+ @doc = REXML::Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
+ @elem = @doc.elements["//b"]
+ end
+
+ it "returns the default namespace" do
+ @elem.namespace.should == "1"
+ end
+
+ it "accepts a namespace prefix" do
+ @elem.namespace("y").should == "2"
+ @doc.elements["//c"].namespace("z").should == "3"
+ end
+
+ it "returns an empty String if default namespace is not defined" do
+ e = REXML::Document.new("<a/>")
+ e.root.namespace.should be_empty
+ end
+
+ it "returns nil if namespace is not defined" do
+ @elem.namespace("z").should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/namespaces_spec.rb b/spec/ruby/library/rexml/element/namespaces_spec.rb
new file mode 100644
index 0000000000..4544540173
--- /dev/null
+++ b/spec/ruby/library/rexml/element/namespaces_spec.rb
@@ -0,0 +1,35 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#namespaces" do
+ before :each do
+ doc = REXML::Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
+ @elem = doc.elements["//c"]
+ end
+
+ it "returns a hash of the namespaces" do
+ ns = {"y"=>"2", "z"=>"3", "xmlns"=>"1"}
+ @elem.namespaces.keys.sort.should == ns.keys.sort
+ @elem.namespaces.values.sort.should == ns.values.sort
+ end
+
+ it "returns an empty hash if no namespaces exist" do
+ e = REXML::Element.new "element"
+ e.namespaces.kind_of?(Hash).should == true
+ e.namespaces.should be_empty
+ end
+
+ it "uses namespace prefixes as keys" do
+ prefixes = ["y", "z", "xmlns"]
+ @elem.namespaces.keys.sort.should == prefixes.sort
+ end
+
+ it "uses namespace values as the hash values" do
+ values = ["2", "3", "1"]
+ @elem.namespaces.values.sort.should == values.sort
+ end
+
+ end
+end
diff --git a/spec/ruby/library/rexml/element/new_spec.rb b/spec/ruby/library/rexml/element/new_spec.rb
new file mode 100644
index 0000000000..c6ab289476
--- /dev/null
+++ b/spec/ruby/library/rexml/element/new_spec.rb
@@ -0,0 +1,38 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#new" do
+
+ it "creates element from tag name" do
+ REXML::Element.new("foo").name.should == "foo"
+ end
+
+ it "creates element with default attributes" do
+ e = REXML::Element.new
+ e.name.should == REXML::Element::UNDEFINED
+ e.context.should == nil
+ e.parent.should == nil
+ end
+
+ it "creates element from another element" do
+ e = REXML::Element.new "foo"
+ f = REXML::Element.new e
+ e.name.should == f.name
+ e.context.should == f.context
+ e.parent.should == f.parent
+ end
+
+ it "takes parent as second argument" do
+ parent = REXML::Element.new "foo"
+ child = REXML::Element.new "bar", parent
+ child.parent.should == parent
+ end
+
+ it "takes context as third argument" do
+ context = {"some_key" => "some_value"}
+ REXML::Element.new("foo", nil, context).context.should == context
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/next_element_spec.rb b/spec/ruby/library/rexml/element/next_element_spec.rb
new file mode 100644
index 0000000000..46d8f74760
--- /dev/null
+++ b/spec/ruby/library/rexml/element/next_element_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#next_element" do
+ before :each do
+ @a = REXML::Element.new "a"
+ @b = REXML::Element.new "b"
+ @c = REXML::Element.new "c"
+ @a.root << @b
+ @a.root << @c
+ end
+ it "returns next existing element" do
+ @a.elements["b"].next_element.should == @c
+ end
+
+ it "returns nil on last element" do
+ @a.elements["c"].next_element.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/node_type_spec.rb b/spec/ruby/library/rexml/element/node_type_spec.rb
new file mode 100644
index 0000000000..a39c2deca5
--- /dev/null
+++ b/spec/ruby/library/rexml/element/node_type_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#node_type" do
+ it "returns :element" do
+ REXML::Element.new("MyElem").node_type.should == :element
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/prefixes_spec.rb b/spec/ruby/library/rexml/element/prefixes_spec.rb
new file mode 100644
index 0000000000..ea4caab4bc
--- /dev/null
+++ b/spec/ruby/library/rexml/element/prefixes_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#prefixes" do
+ before :each do
+ doc = REXML::Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
+ @elem = doc.elements["//c"]
+ end
+
+ it "returns an array of the prefixes of the namespaces" do
+ @elem.prefixes.should == ["y", "z"]
+ end
+
+ it "does not include the default namespace" do
+ @elem.prefixes.include?("xmlns").should == false
+ end
+
+ it "returns an empty array if no namespace was defined" do
+ doc = REXML::Document.new "<root><something/></root>"
+ root = doc.elements["//root"]
+ root.prefixes.should == []
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/previous_element_spec.rb b/spec/ruby/library/rexml/element/previous_element_spec.rb
new file mode 100644
index 0000000000..a43b1ddd10
--- /dev/null
+++ b/spec/ruby/library/rexml/element/previous_element_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#previous_element" do
+ before :each do
+ @a = REXML::Element.new "a"
+ @b = REXML::Element.new "b"
+ @c = REXML::Element.new "c"
+ @a.root << @b
+ @a.root << @c
+ end
+
+ it "returns previous element" do
+ @a.elements["c"].previous_element.should == @b
+ end
+
+ it "returns nil on first element" do
+ @a.elements["b"].previous_element.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/raw_spec.rb b/spec/ruby/library/rexml/element/raw_spec.rb
new file mode 100644
index 0000000000..200a99d194
--- /dev/null
+++ b/spec/ruby/library/rexml/element/raw_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#raw" do
+ it "returns true if raw mode is set to all" do
+ REXML::Element.new("MyElem", nil, {raw: :all}).raw.should == true
+ end
+
+ it "returns true if raw mode is set to expanded_name" do
+ REXML::Element.new("MyElem", nil, {raw: "MyElem"}).raw.should == true
+ end
+
+ it "returns false if raw mode is not set" do
+ REXML::Element.new("MyElem", nil, {raw: ""}).raw.should == false
+ end
+
+ it "returns false if raw is not :all or expanded_name" do
+ REXML::Element.new("MyElem", nil, {raw: "Something"}).raw.should == false
+ end
+
+ it "returns nil if context is not set" do
+ REXML::Element.new("MyElem").raw.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/root_spec.rb b/spec/ruby/library/rexml/element/root_spec.rb
new file mode 100644
index 0000000000..52aa4571b9
--- /dev/null
+++ b/spec/ruby/library/rexml/element/root_spec.rb
@@ -0,0 +1,31 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#root" do
+ before :each do
+ @doc = REXML::Document.new
+ @root = REXML::Element.new "root"
+ @node = REXML::Element.new "node"
+ @doc << @root << @node
+ end
+
+ it "returns first child on documents" do
+ @doc.root.should == @root
+ end
+
+ it "returns self on root nodes" do
+ @root.root.should == @root
+ end
+
+ it "returns parent's root on child nodes" do
+ @node.root.should == @root
+ end
+
+ it "returns self on standalone nodes" do
+ e = REXML::Element.new "Elem" # Note that it doesn't have a parent node
+ e.root.should == e
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/text_spec.rb b/spec/ruby/library/rexml/element/text_spec.rb
new file mode 100644
index 0000000000..3234bba153
--- /dev/null
+++ b/spec/ruby/library/rexml/element/text_spec.rb
@@ -0,0 +1,49 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#text" do
+ before :each do
+ @e = REXML::Element.new "name"
+ @e.text = "John"
+ end
+
+ it "returns the text node of element" do
+ @e.text.should == "John"
+ end
+
+ it "returns the text node value" do
+ t = REXML::Text.new "Joe"
+ @e.text = t
+ @e.text.should == "Joe"
+ @e.text.should_not == t
+ end
+
+ it "returns nil if no text is attached" do
+ elem = REXML::Element.new "name"
+ elem.text.should == nil
+ end
+ end
+
+ describe "REXML::Element#text=" do
+ before :each do
+ @e = REXML::Element.new "name"
+ @e.text = "John"
+ end
+
+ it "sets the text node" do
+ @e.to_s.should == "<name>John</name>"
+ end
+
+ it "replaces existing text" do
+ @e.text = "Joe"
+ @e.to_s.should == "<name>Joe</name>"
+ end
+
+ it "receives nil as an argument" do
+ @e.text = nil
+ @e.to_s.should == "<name/>"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/texts_spec.rb b/spec/ruby/library/rexml/element/texts_spec.rb
new file mode 100644
index 0000000000..2d374d5e66
--- /dev/null
+++ b/spec/ruby/library/rexml/element/texts_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#texts" do
+
+ it "returns an array of the Text children" do
+ e = REXML::Element.new("root")
+ e.add_text "First"
+ e.add_text "Second"
+ e.texts.should == ["FirstSecond"]
+ end
+
+ it "returns an empty array if it has no Text children" do
+ REXML::Element.new("root").texts.should == []
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/element/whitespace_spec.rb b/spec/ruby/library/rexml/element/whitespace_spec.rb
new file mode 100644
index 0000000000..f455067922
--- /dev/null
+++ b/spec/ruby/library/rexml/element/whitespace_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Element#whitespace" do
+ it "returns true if whitespace is respected in the element" do
+ e = REXML::Element.new("root")
+ e.whitespace.should be_true
+
+ e = REXML::Element.new("root", nil, respect_whitespace: :all)
+ e.whitespace.should be_true
+
+ e = REXML::Element.new("root", nil, respect_whitespace: ["root"])
+ e.whitespace.should be_true
+ end
+
+ it "returns false if whitespace is ignored inside element" do
+ e = REXML::Element.new("root", nil, compress_whitespace: :all)
+ e.whitespace.should be_false
+
+ e = REXML::Element.new("root", nil, compress_whitespace: ["root"])
+ e.whitespace.should be_false
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/node/each_recursive_spec.rb b/spec/ruby/library/rexml/node/each_recursive_spec.rb
new file mode 100644
index 0000000000..da347b1389
--- /dev/null
+++ b/spec/ruby/library/rexml/node/each_recursive_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Node#each_recursive" do
+ before :each do
+ @doc = REXML::Document.new
+ @doc << REXML::XMLDecl.new
+ @root = REXML::Element.new "root"
+ @child1 = REXML::Element.new "child1"
+ @child2 = REXML::Element.new "child2"
+ @root << @child1
+ @root << @child2
+ @doc << @root
+ end
+
+ it "visits all subnodes of self" do
+ nodes = []
+ @doc.each_recursive { |node| nodes << node}
+ nodes.should == [@root, @child1, @child2]
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/node/find_first_recursive_spec.rb b/spec/ruby/library/rexml/node/find_first_recursive_spec.rb
new file mode 100644
index 0000000000..2a4f1097ae
--- /dev/null
+++ b/spec/ruby/library/rexml/node/find_first_recursive_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Node#find_first_recursive" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @node1 = REXML::Element.new("node")
+ @node2 = REXML::Element.new("another node")
+ @subnode = REXML::Element.new("another node")
+ @node1 << @subnode
+ @e << @node1
+ @e << @node2
+ end
+
+ it "finds the first element that matches block" do
+ found = @e.find_first_recursive { |n| n.to_s == "<node><another node/></node>"}
+ found.should == @node1
+ end
+
+ it "visits the nodes in preorder" do
+ found = @e.find_first_recursive { |n| n.to_s == "<another node/>"}
+ found.should == @subnode
+ found.should_not == @node2
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/node/index_in_parent_spec.rb b/spec/ruby/library/rexml/node/index_in_parent_spec.rb
new file mode 100644
index 0000000000..55909f86d6
--- /dev/null
+++ b/spec/ruby/library/rexml/node/index_in_parent_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Node#index_in_parent" do
+ it "returns the index (starting from 1) of self in parent" do
+ e = REXML::Element.new("root")
+ node1 = REXML::Element.new("node")
+ node2 = REXML::Element.new("another node")
+ e << node1
+ e << node2
+
+ node1.index_in_parent.should == 1
+ node2.index_in_parent.should == 2
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/node/next_sibling_node_spec.rb b/spec/ruby/library/rexml/node/next_sibling_node_spec.rb
new file mode 100644
index 0000000000..7aae861d75
--- /dev/null
+++ b/spec/ruby/library/rexml/node/next_sibling_node_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Node#next_sibling_node" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @node1 = REXML::Element.new("node")
+ @node2 = REXML::Element.new("another node")
+ @e << @node1
+ @e << @node2
+ end
+
+ it "returns the next child node in parent" do
+ @node1.next_sibling_node.should == @node2
+ end
+
+ it "returns nil if there are no more child nodes next" do
+ @node2.next_sibling_node.should == nil
+ @e.next_sibling_node.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/node/parent_spec.rb b/spec/ruby/library/rexml/node/parent_spec.rb
new file mode 100644
index 0000000000..43c3a747e0
--- /dev/null
+++ b/spec/ruby/library/rexml/node/parent_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Node#parent?" do
+ it "returns true for Elements" do
+ e = REXML::Element.new("foo")
+ e.should.parent?
+ end
+
+ it "returns true for Documents" do
+ e = REXML::Document.new
+ e.should.parent?
+ end
+
+ # This includes attributes, CData and declarations.
+ it "returns false for Texts" do
+ e = REXML::Text.new("foo")
+ e.should_not.parent?
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/node/previous_sibling_node_spec.rb b/spec/ruby/library/rexml/node/previous_sibling_node_spec.rb
new file mode 100644
index 0000000000..11263968a7
--- /dev/null
+++ b/spec/ruby/library/rexml/node/previous_sibling_node_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Node#previous_sibling_node" do
+ before :each do
+ @e = REXML::Element.new("root")
+ @node1 = REXML::Element.new("node")
+ @node2 = REXML::Element.new("another node")
+ @e << @node1
+ @e << @node2
+ end
+
+ it "returns the previous child node in parent" do
+ @node2.previous_sibling_node.should == @node1
+ end
+
+ it "returns nil if there are no more child nodes before" do
+ @node1.previous_sibling_node.should == nil
+ @e.previous_sibling_node.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/shared/each_element.rb b/spec/ruby/library/rexml/shared/each_element.rb
new file mode 100644
index 0000000000..2e0871161d
--- /dev/null
+++ b/spec/ruby/library/rexml/shared/each_element.rb
@@ -0,0 +1,36 @@
+require 'rexml/document'
+require_relative '../../../spec_helper'
+
+describe :rexml_each_element, shared: true do
+ before :each do
+ @e = REXML::Element.new "root"
+ s1 = REXML::Element.new "node1"
+ s2 = REXML::Element.new "node2"
+ s3 = REXML::Element.new "node3"
+ s4 = REXML::Element.new "sub_node"
+ @e << s1
+ @e << s2
+ @e << s3
+ @e << s4
+ end
+
+ it "iterates through element" do
+ str = ""
+ @e.send(@method) { |elem| str << elem.name << " " }
+ str.should == "node1 node2 node3 sub_node "
+ end
+
+ it "iterates through element filtering with XPath" do
+ str = ""
+ @e.send(@method, "/*"){ |e| str << e.name << " "}
+ str.should == "node1 node2 node3 sub_node "
+ end
+end
+
+describe "REXML::Element#each_element" do
+ it_behaves_like :rexml_each_element, :each_element
+end
+
+describe "REXML::Elements#each" do
+ it_behaves_like :rexml_each_element, :each
+end
diff --git a/spec/ruby/library/rexml/shared/elements_to_a.rb b/spec/ruby/library/rexml/shared/elements_to_a.rb
new file mode 100644
index 0000000000..b7169f0b2e
--- /dev/null
+++ b/spec/ruby/library/rexml/shared/elements_to_a.rb
@@ -0,0 +1,34 @@
+require 'rexml/document'
+require_relative '../../../spec_helper'
+
+describe :rexml_elements_to_a, shared: true do
+ before :each do
+ @e = REXML::Element.new "root"
+ @first = REXML::Element.new("FirstChild")
+ @second = REXML::Element.new("SecondChild")
+ @e << @first
+ @e << @second
+ end
+
+ it "returns elements that match xpath" do
+ @e.elements.send(@method, "FirstChild").first.should == @first
+ end
+
+ # According to the docs REXML::Element#get_elements is an alias for
+ # REXML::Elements.to_a. Implementation wise there's a difference, get_elements
+ # always needs the first param (even if it's nil).
+ # A patch was submitted:
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=19354&group_id=426&atid=1698
+ it "returns all children if xpath is nil" do
+ @e.elements.send(@method).should == [@first, @second]
+ end
+
+end
+
+describe "REXML::REXML::Elements#to_a" do
+ it_behaves_like :rexml_elements_to_a, :to_a
+end
+
+describe "REXML::REXML::Element#get_elements" do
+ it_behaves_like :rexml_elements_to_a, :get_elements
+end
diff --git a/spec/ruby/library/rexml/text/append_spec.rb b/spec/ruby/library/rexml/text/append_spec.rb
new file mode 100644
index 0000000000..5e7a5bae7c
--- /dev/null
+++ b/spec/ruby/library/rexml/text/append_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#<<" do
+ it "appends a string to this text node" do
+ text = REXML::Text.new("foo")
+ text << "bar"
+ text.should == "foobar"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/clone_spec.rb b/spec/ruby/library/rexml/text/clone_spec.rb
new file mode 100644
index 0000000000..7801782ff5
--- /dev/null
+++ b/spec/ruby/library/rexml/text/clone_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#clone" do
+ it "creates a copy of this node" do
+ text = REXML::Text.new("foo")
+ text.clone.should == "foo"
+ text.clone.should == text
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/comparison_spec.rb b/spec/ruby/library/rexml/text/comparison_spec.rb
new file mode 100644
index 0000000000..119dd050a6
--- /dev/null
+++ b/spec/ruby/library/rexml/text/comparison_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#<=>" do
+ before :each do
+ @first = REXML::Text.new("abc")
+ @last = REXML::Text.new("def")
+ end
+
+ it "returns -1 if lvalue is less than rvalue" do
+ val = @first <=> @last
+ val.should == -1
+ end
+
+ it "returns -1 if lvalue is greater than rvalue" do
+ val = @last <=> @first
+ val.should == 1
+ end
+
+ it "returns 0 if both values are equal" do
+ tmp = REXML::Text.new("tmp")
+ val = tmp <=> tmp
+ val.should == 0
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/empty_spec.rb b/spec/ruby/library/rexml/text/empty_spec.rb
new file mode 100644
index 0000000000..4c9c899bcb
--- /dev/null
+++ b/spec/ruby/library/rexml/text/empty_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#empty?" do
+ it "returns true if the text is empty" do
+ REXML::Text.new("").should.empty?
+ end
+
+ it "returns false if the text is not empty" do
+ REXML::Text.new("some_text").should_not.empty?
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/indent_text_spec.rb b/spec/ruby/library/rexml/text/indent_text_spec.rb
new file mode 100644
index 0000000000..73065c37da
--- /dev/null
+++ b/spec/ruby/library/rexml/text/indent_text_spec.rb
@@ -0,0 +1,26 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#indent_text" do
+ before :each do
+ @t = REXML::Text.new("")
+ end
+ it "indents a string with default parameters" do
+ @t.indent_text("foo").should == "\tfoo"
+ end
+
+ it "accepts a custom indentation level as second argument" do
+ @t.indent_text("foo", 2, "\t", true).should == "\t\tfoo"
+ end
+
+ it "accepts a custom separator as third argument" do
+ @t.indent_text("foo", 1, "\n", true).should == "\nfoo"
+ end
+
+ it "accepts a fourth parameter to skip the first line" do
+ @t.indent_text("foo", 1, "\t", false).should == "foo"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/inspect_spec.rb b/spec/ruby/library/rexml/text/inspect_spec.rb
new file mode 100644
index 0000000000..af389890ee
--- /dev/null
+++ b/spec/ruby/library/rexml/text/inspect_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#inspect" do
+ it "inspects the string attribute as a string" do
+ REXML::Text.new("a text").inspect.should == "a text".inspect
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/new_spec.rb b/spec/ruby/library/rexml/text/new_spec.rb
new file mode 100644
index 0000000000..8b33da9294
--- /dev/null
+++ b/spec/ruby/library/rexml/text/new_spec.rb
@@ -0,0 +1,51 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text.new" do
+
+ it "creates a Text child node with no parent" do
+ t = REXML::Text.new("test")
+ t.should be_kind_of(REXML::Child)
+ t.should == "test"
+ t.parent.should == nil
+ end
+
+ it "respects whitespace if second argument is true" do
+ t = REXML::Text.new("testing whitespace", true)
+ t.should == "testing whitespace"
+ t = REXML::Text.new(" ", true)
+ t.should == " "
+ end
+
+ it "receives a parent as third argument" do
+ e = REXML::Element.new("root")
+ t = REXML::Text.new("test", false, e)
+ t.parent.should == e
+ e.to_s.should == "<root>test</root>"
+ end
+
+ it "expects escaped text if raw is true" do
+ t = REXML::Text.new("&lt;&amp;&gt;", false, nil, true)
+ t.should == "&lt;&amp;&gt;"
+
+ ->{ REXML::Text.new("<&>", false, nil, true)}.should raise_error(Exception)
+ end
+
+ it "uses raw value of the parent if raw is nil" do
+ e1 = REXML::Element.new("root", nil, { raw: :all})
+ -> {REXML::Text.new("<&>", false, e1)}.should raise_error(Exception)
+
+ e2 = REXML::Element.new("root", nil, { raw: []})
+ e2.raw.should be_false
+ t1 = REXML::Text.new("<&>", false, e2)
+ t1.should == "&lt;&amp;&gt;"
+ end
+
+ it "escapes the values if raw is false" do
+ t = REXML::Text.new("<&>", false, nil, false)
+ t.should == "&lt;&amp;&gt;"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/node_type_spec.rb b/spec/ruby/library/rexml/text/node_type_spec.rb
new file mode 100644
index 0000000000..f44a1ede3e
--- /dev/null
+++ b/spec/ruby/library/rexml/text/node_type_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#node_type" do
+ it "returns :text" do
+ REXML::Text.new("test").node_type.should == :text
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/normalize_spec.rb b/spec/ruby/library/rexml/text/normalize_spec.rb
new file mode 100644
index 0000000000..cde11ec3c9
--- /dev/null
+++ b/spec/ruby/library/rexml/text/normalize_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text.normalize" do
+ it "escapes a string with <, >, &, ' and \" " do
+ REXML::Text.normalize("< > & \" '").should == "&lt; &gt; &amp; &quot; &apos;"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/read_with_substitution_spec.rb b/spec/ruby/library/rexml/text/read_with_substitution_spec.rb
new file mode 100644
index 0000000000..7ff26f4d53
--- /dev/null
+++ b/spec/ruby/library/rexml/text/read_with_substitution_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text.read_with_substitution" do
+ it "reads a text and escapes entities" do
+ REXML::Text.read_with_substitution("&lt; &gt; &amp; &quot; &apos;").should == "< > & \" '"
+ end
+
+ it "accepts an regex for invalid expressions and raises an error if text matches" do
+ -> {REXML::Text.read_with_substitution("this is illegal", /illegal/)}.should raise_error(Exception)
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/to_s_spec.rb b/spec/ruby/library/rexml/text/to_s_spec.rb
new file mode 100644
index 0000000000..e67632c9a1
--- /dev/null
+++ b/spec/ruby/library/rexml/text/to_s_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#to_s" do
+ it "returns the string of this Text node" do
+ u = REXML::Text.new("sean russell", false, nil, true)
+ u.to_s.should == "sean russell"
+
+ t = REXML::Text.new("some test text")
+ t.to_s.should == "some test text"
+ end
+
+ it "escapes the text" do
+ t = REXML::Text.new("& < >")
+ t.to_s.should == "&amp; &lt; &gt;"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/unnormalize_spec.rb b/spec/ruby/library/rexml/text/unnormalize_spec.rb
new file mode 100644
index 0000000000..7b507194d0
--- /dev/null
+++ b/spec/ruby/library/rexml/text/unnormalize_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text.unnormalize" do
+ it "unescapes a string with the values defined in SETUTITSBUS" do
+ REXML::Text.unnormalize("&lt; &gt; &amp; &quot; &apos;").should == "< > & \" '"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/value_spec.rb b/spec/ruby/library/rexml/text/value_spec.rb
new file mode 100644
index 0000000000..53d40c765f
--- /dev/null
+++ b/spec/ruby/library/rexml/text/value_spec.rb
@@ -0,0 +1,40 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#value" do
+ it "returns the text value of this node" do
+ REXML::Text.new("test").value.should == "test"
+ end
+
+ it "does not escape entities" do
+ REXML::Text.new("& \"").value.should == "& \""
+ end
+
+ it "follows the respect_whitespace attribute" do
+ REXML::Text.new("test bar", false).value.should == "test bar"
+ REXML::Text.new("test bar", true).value.should == "test bar"
+ end
+
+ it "ignores the raw attribute" do
+ REXML::Text.new("sean russell", false, nil, true).value.should == "sean russell"
+ end
+ end
+
+ describe "REXML::Text#value=" do
+ before :each do
+ @t = REXML::Text.new("new")
+ end
+
+ it "sets the text of the node" do
+ @t.value = "another text"
+ @t.to_s.should == "another text"
+ end
+
+ it "escapes entities" do
+ @t.value = "<a>"
+ @t.to_s.should == "&lt;a&gt;"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/wrap_spec.rb b/spec/ruby/library/rexml/text/wrap_spec.rb
new file mode 100644
index 0000000000..331a8439e2
--- /dev/null
+++ b/spec/ruby/library/rexml/text/wrap_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#wrap" do
+ before :each do
+ @t = REXML::Text.new("abc def")
+ end
+
+ it "wraps the text at width" do
+ @t.wrap("abc def", 3, false).should == "abc\ndef"
+ end
+
+ it "returns the string if width is greater than the size of the string" do
+ @t.wrap("abc def", 10, false).should == "abc def"
+ end
+
+ it "takes a newline at the beginning option as the third parameter" do
+ @t.wrap("abc def", 3, true).should == "\nabc\ndef"
+ end
+ end
+end
diff --git a/spec/ruby/library/rexml/text/write_with_substitution_spec.rb b/spec/ruby/library/rexml/text/write_with_substitution_spec.rb
new file mode 100644
index 0000000000..840f141e3d
--- /dev/null
+++ b/spec/ruby/library/rexml/text/write_with_substitution_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Text#write_with_substitution" do
+ before :each do
+ @t = REXML::Text.new("test")
+ @f = tmp("rexml_spec")
+ @file = File.open(@f, "w+")
+ end
+
+ after :each do
+ @file.close
+ rm_r @f
+ end
+
+ it "writes out the input to a String" do
+ s = ""
+ @t.write_with_substitution(s, "some text")
+ s.should == "some text"
+ end
+
+ it "writes out the input to an IO" do
+ @t.write_with_substitution(@file, "some text")
+ @file.rewind
+ @file.gets.should == "some text"
+ end
+
+ it "escapes characters" do
+ @t.write_with_substitution(@file, "& < >")
+ @file.rewind
+ @file.gets.should == "&amp; &lt; &gt;"
+ end
+ end
+end
diff --git a/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb b/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb
index 9b37eaa43c..58913cddab 100644
--- a/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb
+++ b/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb
@@ -3,7 +3,7 @@ require 'rubygems'
describe "Gem.load_path_insert_index" do
guard -> { RbConfig::TOPDIR } do
- it "is set for an installed Ruby" do
+ it "is set for an installed an installed Ruby" do
Gem.load_path_insert_index.should be_kind_of Integer
end
end
diff --git a/spec/ruby/library/set/comparison_spec.rb b/spec/ruby/library/set/comparison_spec.rb
index ddcfbae0af..b851ea3d57 100644
--- a/spec/ruby/library/set/comparison_spec.rb
+++ b/spec/ruby/library/set/comparison_spec.rb
@@ -1,27 +1,29 @@
-require_relative '../../spec_helper'
-require 'set'
-
-describe "Set#<=>" do
- it "returns 0 if the sets are equal" do
- (Set[] <=> Set[]).should == 0
- (Set[:a, :b, :c] <=> Set[:a, :b, :c]).should == 0
- end
-
- it "returns -1 if the set is a proper subset of the other set" do
- (Set[] <=> Set[1]).should == -1
- (Set[1, 2] <=> Set[1, 2, 3]).should == -1
- end
-
- it "returns +1 if the set is a proper superset of other set" do
- (Set[1] <=> Set[]).should == +1
- (Set[1, 2, 3] <=> Set[1, 2]).should == +1
- end
-
- it "returns nil if the set has unique elements" do
- (Set[1, 2, 3] <=> Set[:a, :b, :c]).should be_nil
- end
-
- it "returns nil when the argument is not set-like" do
- (Set[] <=> false).should be_nil
- end
-end
+require_relative '../../spec_helper'
+require 'set'
+
+ruby_version_is "3.0" do
+ describe "Set#<=>" do
+ it "returns 0 if the sets are equal" do
+ (Set[] <=> Set[]).should == 0
+ (Set[:a, :b, :c] <=> Set[:a, :b, :c]).should == 0
+ end
+
+ it "returns -1 if the set is a proper subset of the other set" do
+ (Set[] <=> Set[1]).should == -1
+ (Set[1, 2] <=> Set[1, 2, 3]).should == -1
+ end
+
+ it "returns +1 if the set is a proper superset of other set" do
+ (Set[1] <=> Set[]).should == +1
+ (Set[1, 2, 3] <=> Set[1, 2]).should == +1
+ end
+
+ it "returns nil if the set has unique elements" do
+ (Set[1, 2, 3] <=> Set[:a, :b, :c]).should be_nil
+ end
+
+ it "returns nil when the argument is not set-like" do
+ (Set[] <=> false).should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/set/divide_spec.rb b/spec/ruby/library/set/divide_spec.rb
index 998a1b292c..fdd8cd9622 100644
--- a/spec/ruby/library/set/divide_spec.rb
+++ b/spec/ruby/library/set/divide_spec.rb
@@ -13,11 +13,11 @@ describe "Set#divide" do
ret.sort.should == ["five", "four", "one", "three", "two"]
end
- it "returns an enumerator when not passed a block" do
- ret = Set[1, 2, 3, 4].divide
- ret.should be_kind_of(Enumerator)
- ret.each(&:even?).should == Set[Set[1, 3], Set[2, 4]]
- end
+ # BUG: Does not raise a LocalJumpError, but a NoMethodError
+ #
+ # it "raises a LocalJumpError when not passed a block" do
+ # lambda { Set[1].divide }.should raise_error(LocalJumpError)
+ # end
end
describe "Set#divide when passed a block with an arity of 2" do
@@ -31,29 +31,4 @@ describe "Set#divide when passed a block with an arity of 2" do
Set[1, 2].divide { |x, y| ret << [x, y] }
ret.sort.should == [[1, 1], [1, 2], [2, 1], [2, 2]]
end
-
- it "returns an enumerator when not passed a block" do
- ret = Set[1, 2, 3, 4].divide
- ret.should be_kind_of(Enumerator)
- ret.each { |a, b| (a + b).even? }.should == Set[Set[1, 3], Set[2, 4]]
- end
-end
-
-describe "Set#divide when passed a block with an arity of > 2" do
- it "only uses the first element if the arity > 2" do
- set = Set["one", "two", "three", "four", "five"].divide do |x, y, z|
- y.should be_nil
- z.should be_nil
- x.length
- end
- set.map { |x| x.to_a.sort }.sort.should == [["five", "four"], ["one", "two"], ["three"]]
- end
-
- it "only uses the first element if the arity = -1" do
- set = Set["one", "two", "three", "four", "five"].divide do |*xs|
- xs.size.should == 1
- xs.first.length
- end
- set.map { |x| x.to_a.sort }.sort.should == [["five", "four"], ["one", "two"], ["three"]]
- end
end
diff --git a/spec/ruby/library/set/each_spec.rb b/spec/ruby/library/set/each_spec.rb
index 44e185a4da..9bb5ead03a 100644
--- a/spec/ruby/library/set/each_spec.rb
+++ b/spec/ruby/library/set/each_spec.rb
@@ -18,7 +18,6 @@ describe "Set#each" do
it "returns an Enumerator when not passed a block" do
enum = @set.each
- enum.should be_an_instance_of(Enumerator)
ret = []
enum.each { |x| ret << x }
diff --git a/spec/ruby/library/set/enumerable/to_set_spec.rb b/spec/ruby/library/set/enumerable/to_set_spec.rb
index b2d850515b..3790d8deee 100644
--- a/spec/ruby/library/set/enumerable/to_set_spec.rb
+++ b/spec/ruby/library/set/enumerable/to_set_spec.rb
@@ -7,6 +7,14 @@ describe "Enumerable#to_set" do
{a: 1, b: 2}.to_set.should == Set[[:b, 2], [:a, 1]]
end
+ ruby_version_is ''...'3.0' do
+ it "allows passing an alternate class for Set" do
+ sorted_set = [1, 2, 3].to_set(SortedSet)
+ sorted_set.should == SortedSet[1, 2, 3]
+ sorted_set.instance_of?(SortedSet).should == true
+ end
+ end
+
it "passes down passed blocks" do
[1, 2, 3].to_set { |x| x * x }.should == Set[1, 4, 9]
end
diff --git a/spec/ruby/library/set/flatten_spec.rb b/spec/ruby/library/set/flatten_spec.rb
index 51b58d6439..4ac83ea825 100644
--- a/spec/ruby/library/set/flatten_spec.rb
+++ b/spec/ruby/library/set/flatten_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative 'fixtures/set_like'
require 'set'
-set_version = defined?(Set::VERSION) ? Set::VERSION : '1.0.0'
describe "Set#flatten" do
it "returns a copy of self with each included Set flattened" do
@@ -46,11 +45,9 @@ describe "Set#flatten!" do
-> { set.flatten! }.should raise_error(ArgumentError)
end
- version_is(set_version, ""..."1.1.0") do #ruby_version_is ""..."3.3" do
- context "when Set contains a Set-like object" do
- it "flattens self, including Set-like objects" do
- Set[SetSpecs::SetLike.new([1])].flatten!.should == Set[1]
- end
+ context "when Set contains a Set-like object" do
+ it "flattens self, including Set-like objects" do
+ Set[SetSpecs::SetLike.new([1])].flatten!.should == Set[1]
end
end
end
diff --git a/spec/ruby/library/set/initialize_clone_spec.rb b/spec/ruby/library/set/initialize_clone_spec.rb
index bda42cd6e8..62985987fa 100644
--- a/spec/ruby/library/set/initialize_clone_spec.rb
+++ b/spec/ruby/library/set/initialize_clone_spec.rb
@@ -2,15 +2,17 @@ require_relative '../../spec_helper'
require 'set'
describe "Set#initialize_clone" do
- # See https://bugs.ruby-lang.org/issues/14266
- it "does not freeze the new Set when called from clone(freeze: false)" do
- set1 = Set[1, 2]
- set1.freeze
- set2 = set1.clone(freeze: false)
- set1.frozen?.should == true
- set2.frozen?.should == false
- set2.add 3
- set1.should == Set[1, 2]
- set2.should == Set[1, 2, 3]
+ ruby_version_is "3.0" do
+ # See https://bugs.ruby-lang.org/issues/14266
+ it "does not freeze the new Set when called from clone(freeze: false)" do
+ set1 = Set[1, 2]
+ set1.freeze
+ set2 = set1.clone(freeze: false)
+ set1.frozen?.should == true
+ set2.frozen?.should == false
+ set2.add 3
+ set1.should == Set[1, 2]
+ set2.should == Set[1, 2, 3]
+ end
end
end
diff --git a/spec/ruby/library/set/join_spec.rb b/spec/ruby/library/set/join_spec.rb
index 3f511a84e4..7498a91d98 100644
--- a/spec/ruby/library/set/join_spec.rb
+++ b/spec/ruby/library/set/join_spec.rb
@@ -1,29 +1,31 @@
require_relative '../../spec_helper'
require 'set'
-describe "Set#join" do
- it "returns an empty string if the Set is empty" do
- Set[].join.should == ''
- end
+ruby_version_is "3.0" do
+ describe "Set#join" do
+ it "returns an empty string if the Set is empty" do
+ Set[].join.should == ''
+ end
- it "returns a new string formed by joining elements after conversion" do
- set = Set[:a, :b, :c]
- set.join.should == "abc"
- end
+ it "returns a new string formed by joining elements after conversion" do
+ set = Set[:a, :b, :c]
+ set.join.should == "abc"
+ end
- it "does not separate elements when the passed separator is nil" do
- set = Set[:a, :b, :c]
- set.join(nil).should == "abc"
- end
+ it "does not separate elements when the passed separator is nil" do
+ set = Set[:a, :b, :c]
+ set.join(nil).should == "abc"
+ end
- it "returns a string formed by concatenating each element separated by the separator" do
- set = Set[:a, :b, :c]
- set.join(' | ').should == "a | b | c"
- end
+ it "returns a string formed by concatenating each element separated by the separator" do
+ set = Set[:a, :b, :c]
+ set.join(' | ').should == "a | b | c"
+ end
- it "calls #to_a to convert the Set in to an Array" do
- set = Set[:a, :b, :c]
- set.should_receive(:to_a).and_return([:a, :b, :c])
- set.join.should == "abc"
+ it "calls #to_a to convert the Set in to an Array" do
+ set = Set[:a, :b, :c]
+ set.should_receive(:to_a).and_return([:a, :b, :c])
+ set.join.should == "abc"
+ end
end
end
diff --git a/spec/ruby/library/set/proper_subset_spec.rb b/spec/ruby/library/set/proper_subset_spec.rb
index 6b51dedc9f..1f496a6199 100644
--- a/spec/ruby/library/set/proper_subset_spec.rb
+++ b/spec/ruby/library/set/proper_subset_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative 'fixtures/set_like'
require 'set'
-set_version = defined?(Set::VERSION) ? Set::VERSION : '1.0.0'
describe "Set#proper_subset?" do
before :each do
@@ -34,11 +33,9 @@ describe "Set#proper_subset?" do
-> { Set[].proper_subset?(Object.new) }.should raise_error(ArgumentError)
end
- version_is(set_version, ""..."1.1.0") do #ruby_version_is ""..."3.3" do
- context "when comparing to a Set-like object" do
- it "returns true if passed a Set-like object that self is a proper subset of" do
- Set[1, 2, 3].proper_subset?(SetSpecs::SetLike.new([1, 2, 3, 4])).should be_true
- end
+ context "when comparing to a Set-like object" do
+ it "returns true if passed a Set-like object that self is a proper subset of" do
+ Set[1, 2, 3].proper_subset?(SetSpecs::SetLike.new([1, 2, 3, 4])).should be_true
end
end
end
diff --git a/spec/ruby/library/set/shared/inspect.rb b/spec/ruby/library/set/shared/inspect.rb
index adb6ddb4c9..69fbdd12f6 100644
--- a/spec/ruby/library/set/shared/inspect.rb
+++ b/spec/ruby/library/set/shared/inspect.rb
@@ -1,4 +1,4 @@
-describe :set_inspect, shared: true do
+describe "set_inspect", shared: true do
it "returns a String representation of self" do
Set[].send(@method).should be_kind_of(String)
Set[nil, false, true].send(@method).should be_kind_of(String)
@@ -7,19 +7,9 @@ describe :set_inspect, shared: true do
Set[:a, "b", Set[?c]].send(@method).should be_kind_of(String)
end
- it "does include the elements of the set" do
- Set["1"].send(@method).should == '#<Set: {"1"}>'
- end
-
- it "puts spaces between the elements" do
- Set["1", "2"].send(@method).should include('", "')
- end
-
- it "correctly handles cyclic-references" do
- set1 = Set[]
- set2 = Set[set1]
- set1 << set2
- set1.send(@method).should be_kind_of(String)
- set1.send(@method).should include("#<Set: {...}>")
+ it "correctly handles self-references" do
+ (set = Set[]) << set
+ set.send(@method).should be_kind_of(String)
+ set.send(@method).should include("#<Set: {...}>")
end
end
diff --git a/spec/ruby/library/set/sortedset/add_spec.rb b/spec/ruby/library/set/sortedset/add_spec.rb
new file mode 100644
index 0000000000..4f3bb252e1
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/add_spec.rb
@@ -0,0 +1,42 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+ require_relative 'shared/add'
+
+ describe "SortedSet#add" do
+ it_behaves_like :sorted_set_add, :add
+
+ it "takes only values which responds <=>" do
+ obj = mock('no_comparison_operator')
+ obj.stub!(:respond_to?).with(:<=>).and_return(false)
+ -> { SortedSet["hello"].add(obj) }.should raise_error(ArgumentError)
+ end
+
+ it "raises on incompatible <=> comparison" do
+ # Use #to_a here as elements are sorted only when needed.
+ # Therefore the <=> incompatibility is only noticed on sorting.
+ -> { SortedSet['1', '2'].add(3).to_a }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "SortedSet#add?" do
+ before :each do
+ @set = SortedSet.new
+ end
+
+ it "adds the passed Object to self" do
+ @set.add?("cat")
+ @set.should include("cat")
+ end
+
+ it "returns self when the Object has not yet been added to self" do
+ @set.add?("cat").should equal(@set)
+ end
+
+ it "returns nil when the Object has already been added to self" do
+ @set.add?("cat")
+ @set.add?("cat").should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/append_spec.rb b/spec/ruby/library/set/sortedset/append_spec.rb
new file mode 100644
index 0000000000..d72d70b21f
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/append_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+ require_relative 'shared/add'
+
+ describe "SortedSet#<<" do
+ it_behaves_like :sorted_set_add, :<<
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/case_equality_spec.rb b/spec/ruby/library/set/sortedset/case_equality_spec.rb
new file mode 100644
index 0000000000..d7c296b626
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/case_equality_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/include'
+ require 'set'
+
+ describe "SortedSet#===" do
+ it_behaves_like :sorted_set_include, :===
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/classify_spec.rb b/spec/ruby/library/set/sortedset/classify_spec.rb
new file mode 100644
index 0000000000..4011e58b82
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/classify_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#classify" do
+ before :each do
+ @set = SortedSet["one", "two", "three", "four"]
+ end
+
+ it "yields each Object in self in sorted order" do
+ res = []
+ @set.classify { |x| res << x }
+ res.should == ["one", "two", "three", "four"].sort
+ end
+
+ it "returns an Enumerator when passed no block" do
+ enum = @set.classify
+ enum.should be_an_instance_of(Enumerator)
+
+ classified = enum.each { |x| x.length }
+ classified.should == { 3 => SortedSet["one", "two"], 4 => SortedSet["four"], 5 => SortedSet["three"] }
+ end
+
+ it "classifies the Objects in self based on the block's return value" do
+ classified = @set.classify { |x| x.length }
+ classified.should == { 3 => SortedSet["one", "two"], 4 => SortedSet["four"], 5 => SortedSet["three"] }
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/clear_spec.rb b/spec/ruby/library/set/sortedset/clear_spec.rb
new file mode 100644
index 0000000000..879aa824d8
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/clear_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#clear" do
+ before :each do
+ @set = SortedSet["one", "two", "three", "four"]
+ end
+
+ it "removes all elements from self" do
+ @set.clear
+ @set.should be_empty
+ end
+
+ it "returns self" do
+ @set.clear.should equal(@set)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/collect_spec.rb b/spec/ruby/library/set/sortedset/collect_spec.rb
new file mode 100644
index 0000000000..0674f0d130
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/collect_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+ require_relative 'shared/collect'
+
+ describe "SortedSet#collect!" do
+ it_behaves_like :sorted_set_collect_bang, :collect!
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/constructor_spec.rb b/spec/ruby/library/set/sortedset/constructor_spec.rb
new file mode 100644
index 0000000000..31f30fd892
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/constructor_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet[]" do
+ it "returns a new SortedSet populated with the passed Objects" do
+ set = SortedSet[1, 2, 3]
+
+ set.instance_of?(SortedSet).should be_true
+ set.size.should eql(3)
+
+ set.should include(1)
+ set.should include(2)
+ set.should include(3)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/delete_if_spec.rb b/spec/ruby/library/set/sortedset/delete_if_spec.rb
new file mode 100644
index 0000000000..787639ae12
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/delete_if_spec.rb
@@ -0,0 +1,41 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#delete_if" do
+ before :each do
+ @set = SortedSet["one", "two", "three"]
+ end
+
+ it "yields each Object in self in sorted order" do
+ ret = []
+ @set.delete_if { |x| ret << x }
+ ret.should == ["one", "two", "three"].sort
+ end
+
+ it "deletes every element from self for which the passed block returns true" do
+ @set.delete_if { |x| x.size == 3 }
+ @set.size.should eql(1)
+
+ @set.should_not include("one")
+ @set.should_not include("two")
+ @set.should include("three")
+ end
+
+ it "returns self" do
+ @set.delete_if { |x| x }.should equal(@set)
+ end
+
+ it "returns an Enumerator when passed no block" do
+ enum = @set.delete_if
+ enum.should be_an_instance_of(Enumerator)
+
+ enum.each { |x| x.size == 3 }
+
+ @set.should_not include("one")
+ @set.should_not include("two")
+ @set.should include("three")
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/delete_spec.rb b/spec/ruby/library/set/sortedset/delete_spec.rb
new file mode 100644
index 0000000000..0e2a6accf3
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/delete_spec.rb
@@ -0,0 +1,40 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#delete" do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "deletes the passed Object from self" do
+ @set.delete("a")
+ @set.should_not include("a")
+ end
+
+ it "returns self" do
+ @set.delete("a").should equal(@set)
+ @set.delete("x").should equal(@set)
+ end
+ end
+
+ describe "SortedSet#delete?" do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "deletes the passed Object from self" do
+ @set.delete?("a")
+ @set.should_not include("a")
+ end
+
+ it "returns self when the passed Object is in self" do
+ @set.delete?("a").should equal(@set)
+ end
+
+ it "returns nil when the passed Object is not in self" do
+ @set.delete?("x").should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/difference_spec.rb b/spec/ruby/library/set/sortedset/difference_spec.rb
new file mode 100644
index 0000000000..fb064bdff9
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/difference_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+ require_relative 'shared/difference'
+
+ describe "SortedSet#difference" do
+ it_behaves_like :sorted_set_difference, :difference
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/divide_spec.rb b/spec/ruby/library/set/sortedset/divide_spec.rb
new file mode 100644
index 0000000000..31ab6037e4
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/divide_spec.rb
@@ -0,0 +1,37 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#divide" do
+ it "divides self into a set of subsets based on the blocks return values" do
+ set = SortedSet["one", "two", "three", "four", "five"].divide { |x| x.length }
+ set.map { |x| x.to_a }.to_a.sort.should == [["five", "four"], ["one", "two"], ["three"]]
+ end
+
+ it "yields each Object in self in sorted order" do
+ ret = []
+ SortedSet["one", "two", "three", "four", "five"].divide { |x| ret << x }
+ ret.should == ["one", "two", "three", "four", "five"].sort
+ end
+
+ # BUG: Does not raise a LocalJumpError, but a NoMethodError
+ #
+ # it "raises a LocalJumpError when not passed a block" do
+ # lambda { SortedSet[1].divide }.should raise_error(LocalJumpError)
+ # end
+ end
+
+ describe "SortedSet#divide when passed a block with an arity of 2" do
+ it "divides self into a set of subsets based on the blocks return values" do
+ set = SortedSet[1, 3, 4, 6, 9, 10, 11].divide { |x, y| (x - y).abs == 1 }
+ set.map { |x| x.to_a }.to_a.sort.should == [[1], [3, 4], [6], [9, 10, 11]]
+ end
+
+ it "yields each two Objects to the block" do
+ ret = []
+ SortedSet[1, 2].divide { |x, y| ret << [x, y] }
+ ret.should == [[1, 1], [1, 2], [2, 1], [2, 2]]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/each_spec.rb b/spec/ruby/library/set/sortedset/each_spec.rb
new file mode 100644
index 0000000000..79d8aee223
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/each_spec.rb
@@ -0,0 +1,29 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#each" do
+ before :each do
+ @set = SortedSet[1, 2, 3]
+ end
+
+ it "yields each Object in self in sorted order" do
+ ret = []
+ SortedSet["one", "two", "three"].each { |x| ret << x }
+ ret.should == ["one", "two", "three"].sort
+ end
+
+ it "returns self" do
+ @set.each { |x| x }.should equal(@set)
+ end
+
+ it "returns an Enumerator when not passed a block" do
+ enum = @set.each
+
+ ret = []
+ enum.each { |x| ret << x }
+ ret.sort.should == [1, 2, 3]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/empty_spec.rb b/spec/ruby/library/set/sortedset/empty_spec.rb
new file mode 100644
index 0000000000..2e52c3e81a
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/empty_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#empty?" do
+ it "returns true if self is empty" do
+ SortedSet[].empty?.should be_true
+ SortedSet[1].empty?.should be_false
+ SortedSet[1,2,3].empty?.should be_false
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/eql_spec.rb b/spec/ruby/library/set/sortedset/eql_spec.rb
new file mode 100644
index 0000000000..050464994b
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/eql_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#eql?" do
+ it "returns true when the passed argument is a SortedSet and contains the same elements" do
+ SortedSet[].should eql(SortedSet[])
+ SortedSet[1, 2, 3].should eql(SortedSet[1, 2, 3])
+ SortedSet[1, 2, 3].should eql(SortedSet[3, 2, 1])
+
+ # SortedSet["a", :b, ?c].should eql(SortedSet[?c, :b, "a"])
+
+ SortedSet[1, 2, 3].should_not eql(SortedSet[1.0, 2, 3])
+ SortedSet[1, 2, 3].should_not eql(SortedSet[2, 3])
+ SortedSet[1, 2, 3].should_not eql(SortedSet[])
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/equal_value_spec.rb b/spec/ruby/library/set/sortedset/equal_value_spec.rb
new file mode 100644
index 0000000000..30422f5b95
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/equal_value_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#==" do
+ it "returns true when the passed Object is a SortedSet and self and the Object contain the same elements" do
+ SortedSet[].should == SortedSet[]
+ SortedSet[1, 2, 3].should == SortedSet[1, 2, 3]
+ SortedSet["1", "2", "3"].should == SortedSet["1", "2", "3"]
+
+ SortedSet[1, 2, 3].should_not == SortedSet[1.0, 2, 3]
+ SortedSet[1, 2, 3].should_not == [1, 2, 3]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/exclusion_spec.rb b/spec/ruby/library/set/sortedset/exclusion_spec.rb
new file mode 100644
index 0000000000..1967dfbfa6
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/exclusion_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#^" do
+ before :each do
+ @set = SortedSet[1, 2, 3, 4]
+ end
+
+ it "returns a new SortedSet containing elements that are not in both self and the passed Enumerable" do
+ (@set ^ SortedSet[3, 4, 5]).should == SortedSet[1, 2, 5]
+ (@set ^ [3, 4, 5]).should == SortedSet[1, 2, 5]
+ end
+
+ it "raises an ArgumentError when passed a non-Enumerable" do
+ -> { @set ^ 3 }.should raise_error(ArgumentError)
+ -> { @set ^ Object.new }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/filter_spec.rb b/spec/ruby/library/set/sortedset/filter_spec.rb
new file mode 100644
index 0000000000..3b9dcb63c9
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/filter_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/select'
+ require 'set'
+
+ describe "SortedSet#filter!" do
+ it_behaves_like :sorted_set_select_bang, :filter!
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/flatten_merge_spec.rb b/spec/ruby/library/set/sortedset/flatten_merge_spec.rb
new file mode 100644
index 0000000000..0d67cb331e
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/flatten_merge_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#flatten_merge" do
+ it "is protected" do
+ SortedSet.should have_protected_instance_method("flatten_merge")
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/flatten_spec.rb b/spec/ruby/library/set/sortedset/flatten_spec.rb
new file mode 100644
index 0000000000..e83ad1044a
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/flatten_spec.rb
@@ -0,0 +1,47 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ # Note: Flatten make little sens on sorted sets, because SortedSets are not (by default)
+ # comparable. For a SortedSet to be both valid and nested, we need to define a comparison operator:
+ module SortedSet_FlattenSpecs
+ class ComparableSortedSet < SortedSet
+ def <=>(other)
+ return puts "#{other} vs #{self}" unless other.is_a?(ComparableSortedSet)
+ to_a <=> other.to_a
+ end
+ end
+ end
+
+ describe "SortedSet#flatten" do
+ it "returns a copy of self with each included SortedSet flattened" do
+ klass = SortedSet_FlattenSpecs::ComparableSortedSet
+ set = klass[klass[1,2], klass[3,4], klass[5,6,7], klass[8]]
+ flattened_set = set.flatten
+
+ flattened_set.should_not equal(set)
+ flattened_set.should == klass[1, 2, 3, 4, 5, 6, 7, 8]
+ end
+ end
+
+ describe "SortedSet#flatten!" do
+ it "flattens self" do
+ klass = SortedSet_FlattenSpecs::ComparableSortedSet
+ set = klass[klass[1,2], klass[3,4], klass[5,6,7], klass[8]]
+ set.flatten!
+ set.should == klass[1, 2, 3, 4, 5, 6, 7, 8]
+ end
+
+ it "returns self when self was modified" do
+ klass = SortedSet_FlattenSpecs::ComparableSortedSet
+ set = klass[klass[1,2], klass[3,4]]
+ set.flatten!.should equal(set)
+ end
+
+ it "returns nil when self was not modified" do
+ set = SortedSet[1, 2, 3, 4]
+ set.flatten!.should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/hash_spec.rb b/spec/ruby/library/set/sortedset/hash_spec.rb
new file mode 100644
index 0000000000..40676de7fc
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/hash_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#hash" do
+ it "is static" do
+ SortedSet[].hash.should == SortedSet[].hash
+ SortedSet[1, 2, 3].hash.should == SortedSet[1, 2, 3].hash
+ SortedSet["a", "b", "c"].hash.should == SortedSet["c", "b", "a"].hash
+
+ SortedSet[].hash.should_not == SortedSet[1, 2, 3].hash
+ SortedSet[1, 2, 3].hash.should_not == SortedSet["a", "b", "c"].hash
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/include_spec.rb b/spec/ruby/library/set/sortedset/include_spec.rb
new file mode 100644
index 0000000000..ec2ad987d5
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/include_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/include'
+ require 'set'
+
+ describe "SortedSet#include?" do
+ it_behaves_like :sorted_set_include, :include?
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/initialize_spec.rb b/spec/ruby/library/set/sortedset/initialize_spec.rb
new file mode 100644
index 0000000000..4d1707b72a
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/initialize_spec.rb
@@ -0,0 +1,33 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#initialize" do
+ it "is private" do
+ SortedSet.should have_private_instance_method("initialize")
+ end
+
+ it "adds all elements of the passed Enumerable to self" do
+ s = SortedSet.new([1, 2, 3])
+ s.size.should eql(3)
+ s.should include(1)
+ s.should include(2)
+ s.should include(3)
+ end
+
+ it "preprocesses all elements by a passed block before adding to self" do
+ s = SortedSet.new([1, 2, 3]) { |x| x * x }
+ s.size.should eql(3)
+ s.should include(1)
+ s.should include(4)
+ s.should include(9)
+ end
+
+ it "raises on incompatible <=> comparison" do
+ # Use #to_a here as elements are sorted only when needed.
+ # Therefore the <=> incompatibility is only noticed on sorting.
+ -> { SortedSet.new(['00', nil]).to_a }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/inspect_spec.rb b/spec/ruby/library/set/sortedset/inspect_spec.rb
new file mode 100644
index 0000000000..1c4dd9e6e2
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/inspect_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#inspect" do
+ it "returns a String representation of self" do
+ SortedSet[].inspect.should be_kind_of(String)
+ SortedSet[1, 2, 3].inspect.should be_kind_of(String)
+ SortedSet["1", "2", "3"].inspect.should be_kind_of(String)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/intersection_spec.rb b/spec/ruby/library/set/sortedset/intersection_spec.rb
new file mode 100644
index 0000000000..6daa271b73
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/intersection_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/intersection'
+ require 'set'
+
+ describe "SortedSet#intersection" do
+ it_behaves_like :sorted_set_intersection, :intersection
+ end
+
+ describe "SortedSet#&" do
+ it_behaves_like :sorted_set_intersection, :&
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/keep_if_spec.rb b/spec/ruby/library/set/sortedset/keep_if_spec.rb
new file mode 100644
index 0000000000..3e5f3bbc47
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/keep_if_spec.rb
@@ -0,0 +1,34 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#keep_if" do
+ before :each do
+ @set = SortedSet["one", "two", "three"]
+ end
+
+ it "yields each Object in self in sorted order" do
+ ret = []
+ @set.keep_if { |x| ret << x }
+ ret.should == ["one", "two", "three"].sort
+ end
+
+ it "keeps every element from self for which the passed block returns true" do
+ @set.keep_if { |x| x.size != 3 }
+ @set.to_a.should == ["three"]
+ end
+
+ it "returns self" do
+ @set.keep_if {}.should equal(@set)
+ end
+
+ it "returns an Enumerator when passed no block" do
+ enum = @set.keep_if
+ enum.should be_an_instance_of(Enumerator)
+
+ enum.each { |x| x.size != 3 }
+ @set.to_a.should == ["three"]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/length_spec.rb b/spec/ruby/library/set/sortedset/length_spec.rb
new file mode 100644
index 0000000000..de6791f6bb
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/length_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/length'
+ require 'set'
+
+ describe "SortedSet#length" do
+ it_behaves_like :sorted_set_length, :length
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/map_spec.rb b/spec/ruby/library/set/sortedset/map_spec.rb
new file mode 100644
index 0000000000..4971b9529b
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/map_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+ require_relative 'shared/collect'
+
+ describe "SortedSet#map!" do
+ it_behaves_like :sorted_set_collect_bang, :map!
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/member_spec.rb b/spec/ruby/library/set/sortedset/member_spec.rb
new file mode 100644
index 0000000000..142b09b651
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/member_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/include'
+ require 'set'
+
+ describe "SortedSet#member?" do
+ it_behaves_like :sorted_set_include, :member?
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/merge_spec.rb b/spec/ruby/library/set/sortedset/merge_spec.rb
new file mode 100644
index 0000000000..c4cbc6d2b4
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/merge_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#merge" do
+ it "adds the elements of the passed Enumerable to self" do
+ SortedSet["a", "b"].merge(SortedSet["b", "c", "d"]).should == SortedSet["a", "b", "c", "d"]
+ SortedSet[1, 2].merge([3, 4]).should == SortedSet[1, 2, 3, 4]
+ end
+
+ it "returns self" do
+ set = SortedSet[1, 2]
+ set.merge([3, 4]).should equal(set)
+ end
+
+ it "raises an ArgumentError when passed a non-Enumerable" do
+ -> { SortedSet[1, 2].merge(1) }.should raise_error(ArgumentError)
+ -> { SortedSet[1, 2].merge(Object.new) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/minus_spec.rb b/spec/ruby/library/set/sortedset/minus_spec.rb
new file mode 100644
index 0000000000..d6abc5e204
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/minus_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+ require_relative 'shared/difference'
+
+ describe "SortedSet#-" do
+ it_behaves_like :sorted_set_difference, :-
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/plus_spec.rb b/spec/ruby/library/set/sortedset/plus_spec.rb
new file mode 100644
index 0000000000..13fc873ad1
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/plus_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/union'
+ require 'set'
+
+ describe "SortedSet#+" do
+ it_behaves_like :sorted_set_union, :+
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb b/spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb
new file mode 100644
index 0000000000..e97f509406
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#pretty_print_cycle" do
+ it "passes the 'pretty print' representation of a self-referencing SortedSet to the pretty print writer" do
+ pp = mock("PrettyPrint")
+ pp.should_receive(:text).with("#<SortedSet: {...}>")
+ SortedSet[1, 2, 3].pretty_print_cycle(pp)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/pretty_print_spec.rb b/spec/ruby/library/set/sortedset/pretty_print_spec.rb
new file mode 100644
index 0000000000..a8088bf797
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/pretty_print_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#pretty_print" do
+ it "passes the 'pretty print' representation of self to the pretty print writer" do
+ pp = mock("PrettyPrint")
+ set = SortedSet[1, 2, 3]
+
+ pp.should_receive(:text).with("#<SortedSet: {")
+ pp.should_receive(:text).with("}>")
+
+ pp.should_receive(:nest).with(1).and_yield
+ pp.should_receive(:seplist).with(set)
+
+ set.pretty_print(pp)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/proper_subset_spec.rb b/spec/ruby/library/set/sortedset/proper_subset_spec.rb
new file mode 100644
index 0000000000..34fb89d13d
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/proper_subset_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#proper_subset?" do
+ before :each do
+ @set = SortedSet[1, 2, 3, 4]
+ end
+
+ it "returns true if passed a SortedSet that self is a proper subset of" do
+ SortedSet[].proper_subset?(@set).should be_true
+ SortedSet[].proper_subset?(SortedSet[1, 2, 3]).should be_true
+ SortedSet[].proper_subset?(SortedSet["a", "b", "c"]).should be_true
+
+ SortedSet[1, 2, 3].proper_subset?(@set).should be_true
+ SortedSet[1, 3].proper_subset?(@set).should be_true
+ SortedSet[1, 2].proper_subset?(@set).should be_true
+ SortedSet[1].proper_subset?(@set).should be_true
+
+ SortedSet[5].proper_subset?(@set).should be_false
+ SortedSet[1, 5].proper_subset?(@set).should be_false
+ SortedSet["test"].proper_subset?(@set).should be_false
+
+ @set.proper_subset?(@set).should be_false
+ SortedSet[].proper_subset?(SortedSet[]).should be_false
+ end
+
+ it "raises an ArgumentError when passed a non-SortedSet" do
+ -> { SortedSet[].proper_subset?([]) }.should raise_error(ArgumentError)
+ -> { SortedSet[].proper_subset?(1) }.should raise_error(ArgumentError)
+ -> { SortedSet[].proper_subset?("test") }.should raise_error(ArgumentError)
+ -> { SortedSet[].proper_subset?(Object.new) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/proper_superset_spec.rb b/spec/ruby/library/set/sortedset/proper_superset_spec.rb
new file mode 100644
index 0000000000..8b92444f72
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/proper_superset_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#proper_superset?" do
+ before :each do
+ @set = SortedSet[1, 2, 3, 4]
+ end
+
+ it "returns true if passed a SortedSet that self is a proper superset of" do
+ @set.proper_superset?(SortedSet[]).should be_true
+ SortedSet[1, 2, 3].proper_superset?(SortedSet[]).should be_true
+ SortedSet["a", "b", "c"].proper_superset?(SortedSet[]).should be_true
+
+ @set.proper_superset?(SortedSet[1, 2, 3]).should be_true
+ @set.proper_superset?(SortedSet[1, 3]).should be_true
+ @set.proper_superset?(SortedSet[1, 2]).should be_true
+ @set.proper_superset?(SortedSet[1]).should be_true
+
+ @set.proper_superset?(SortedSet[5]).should be_false
+ @set.proper_superset?(SortedSet[1, 5]).should be_false
+ @set.proper_superset?(SortedSet["test"]).should be_false
+
+ @set.proper_superset?(@set).should be_false
+ SortedSet[].proper_superset?(SortedSet[]).should be_false
+ end
+
+ it "raises an ArgumentError when passed a non-SortedSet" do
+ -> { SortedSet[].proper_superset?([]) }.should raise_error(ArgumentError)
+ -> { SortedSet[].proper_superset?(1) }.should raise_error(ArgumentError)
+ -> { SortedSet[].proper_superset?("test") }.should raise_error(ArgumentError)
+ -> { SortedSet[].proper_superset?(Object.new) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/reject_spec.rb b/spec/ruby/library/set/sortedset/reject_spec.rb
new file mode 100644
index 0000000000..396b864cc5
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/reject_spec.rb
@@ -0,0 +1,45 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#reject!" do
+ before :each do
+ @set = SortedSet["one", "two", "three"]
+ end
+
+ it "yields each Object in self in sorted order" do
+ res = []
+ @set.reject! { |x| res << x }
+ res.should == ["one", "two", "three"].sort
+ end
+
+ it "deletes every element from self for which the passed block returns true" do
+ @set.reject! { |x| x.size == 3 }
+ @set.size.should eql(1)
+
+ @set.should_not include("one")
+ @set.should_not include("two")
+ @set.should include("three")
+ end
+
+ it "returns self when self was modified" do
+ @set.reject! { |x| true }.should equal(@set)
+ end
+
+ it "returns nil when self was not modified" do
+ @set.reject! { |x| false }.should be_nil
+ end
+
+ it "returns an Enumerator when passed no block" do
+ enum = @set.reject!
+ enum.should be_an_instance_of(Enumerator)
+
+ enum.each { |x| x.size == 3 }
+
+ @set.should_not include("one")
+ @set.should_not include("two")
+ @set.should include("three")
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/replace_spec.rb b/spec/ruby/library/set/sortedset/replace_spec.rb
new file mode 100644
index 0000000000..2900221c01
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/replace_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#replace" do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "replaces the contents with other and returns self" do
+ @set.replace(SortedSet[1, 2, 3]).should == @set
+ @set.should == SortedSet[1, 2, 3]
+ end
+
+ it "accepts any enumerable as other" do
+ @set.replace([1, 2, 3]).should == SortedSet[1, 2, 3]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/select_spec.rb b/spec/ruby/library/set/sortedset/select_spec.rb
new file mode 100644
index 0000000000..fc4c15ee4d
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/select_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/select'
+ require 'set'
+
+ describe "SortedSet#select!" do
+ it_behaves_like :sorted_set_select_bang, :select!
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/add.rb b/spec/ruby/library/set/sortedset/shared/add.rb
new file mode 100644
index 0000000000..95ef1b090e
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/add.rb
@@ -0,0 +1,14 @@
+describe :sorted_set_add, shared: true do
+ before :each do
+ @set = SortedSet.new
+ end
+
+ it "adds the passed Object to self" do
+ @set.send(@method, "dog")
+ @set.should include("dog")
+ end
+
+ it "returns self" do
+ @set.send(@method, "dog").should equal(@set)
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/collect.rb b/spec/ruby/library/set/sortedset/shared/collect.rb
new file mode 100644
index 0000000000..e53304d427
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/collect.rb
@@ -0,0 +1,20 @@
+describe :sorted_set_collect_bang, shared: true do
+ before :each do
+ @set = SortedSet[1, 2, 3, 4, 5]
+ end
+
+ it "yields each Object in self in sorted order" do
+ res = []
+ SortedSet["one", "two", "three"].send(@method) { |x| res << x; x }
+ res.should == ["one", "two", "three"].sort
+ end
+
+ it "returns self" do
+ @set.send(@method) { |x| x }.should equal(@set)
+ end
+
+ it "replaces self with the return values of the block" do
+ @set.send(@method) { |x| x * 2 }
+ @set.should == SortedSet[2, 4, 6, 8, 10]
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/difference.rb b/spec/ruby/library/set/sortedset/shared/difference.rb
new file mode 100644
index 0000000000..688e23a7a7
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/difference.rb
@@ -0,0 +1,15 @@
+describe :sorted_set_difference, shared: true do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "returns a new SortedSet containing self's elements excluding the elements in the passed Enumerable" do
+ @set.send(@method, SortedSet["a", "b"]).should == SortedSet["c"]
+ @set.send(@method, ["b", "c"]).should == SortedSet["a"]
+ end
+
+ it "raises an ArgumentError when passed a non-Enumerable" do
+ -> { @set.send(@method, 1) }.should raise_error(ArgumentError)
+ -> { @set.send(@method, Object.new) }.should raise_error(ArgumentError)
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/include.rb b/spec/ruby/library/set/sortedset/shared/include.rb
new file mode 100644
index 0000000000..cd1758819d
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/include.rb
@@ -0,0 +1,7 @@
+describe :sorted_set_include, shared: true do
+ it "returns true when self contains the passed Object" do
+ set = SortedSet["a", "b", "c"]
+ set.send(@method, "a").should be_true
+ set.send(@method, "e").should be_false
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/intersection.rb b/spec/ruby/library/set/sortedset/shared/intersection.rb
new file mode 100644
index 0000000000..045716ad05
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/intersection.rb
@@ -0,0 +1,15 @@
+describe :sorted_set_intersection, shared: true do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "returns a new SortedSet containing only elements shared by self and the passed Enumerable" do
+ @set.send(@method, SortedSet["b", "c", "d", "e"]).should == SortedSet["b", "c"]
+ @set.send(@method, ["b", "c", "d"]).should == SortedSet["b", "c"]
+ end
+
+ it "raises an ArgumentError when passed a non-Enumerable" do
+ -> { @set.send(@method, 1) }.should raise_error(ArgumentError)
+ -> { @set.send(@method, Object.new) }.should raise_error(ArgumentError)
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/length.rb b/spec/ruby/library/set/sortedset/shared/length.rb
new file mode 100644
index 0000000000..d1dfee1cff
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/length.rb
@@ -0,0 +1,6 @@
+describe :sorted_set_length, shared: true do
+ it "returns the number of elements in the set" do
+ set = SortedSet["a", "b", "c"]
+ set.send(@method).should == 3
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/select.rb b/spec/ruby/library/set/sortedset/shared/select.rb
new file mode 100644
index 0000000000..e13311eda5
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/select.rb
@@ -0,0 +1,35 @@
+require_relative '../../../../spec_helper'
+require 'set'
+
+describe :sorted_set_select_bang, shared: true do
+ before :each do
+ @set = SortedSet["one", "two", "three"]
+ end
+
+ it "yields each Object in self in sorted order" do
+ res = []
+ @set.send(@method) { |x| res << x }
+ res.should == ["one", "two", "three"].sort
+ end
+
+ it "keeps every element from self for which the passed block returns true" do
+ @set.send(@method) { |x| x.size != 3 }
+ @set.to_a.should == ["three"]
+ end
+
+ it "returns self when self was modified" do
+ @set.send(@method) { false }.should equal(@set)
+ end
+
+ it "returns nil when self was not modified" do
+ @set.send(@method) { true }.should be_nil
+ end
+
+ it "returns an Enumerator when passed no block" do
+ enum = @set.send(@method)
+ enum.should be_an_instance_of(Enumerator)
+
+ enum.each { |x| x.size != 3 }
+ @set.to_a.should == ["three"]
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/shared/union.rb b/spec/ruby/library/set/sortedset/shared/union.rb
new file mode 100644
index 0000000000..9015bdc8e3
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/shared/union.rb
@@ -0,0 +1,15 @@
+describe :sorted_set_union, shared: true do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "returns a new SortedSet containing all elements of self and the passed Enumerable" do
+ @set.send(@method, SortedSet["b", "d", "e"]).should == SortedSet["a", "b", "c", "d", "e"]
+ @set.send(@method, ["b", "e"]).should == SortedSet["a", "b", "c", "e"]
+ end
+
+ it "raises an ArgumentError when passed a non-Enumerable" do
+ -> { @set.send(@method, 1) }.should raise_error(ArgumentError)
+ -> { @set.send(@method, Object.new) }.should raise_error(ArgumentError)
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/size_spec.rb b/spec/ruby/library/set/sortedset/size_spec.rb
new file mode 100644
index 0000000000..d908b33b53
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/size_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/length'
+ require 'set'
+
+ describe "SortedSet#size" do
+ it_behaves_like :sorted_set_length, :size
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/sortedset_spec.rb b/spec/ruby/library/set/sortedset/sortedset_spec.rb
index 67993dee29..3ead5495fc 100644
--- a/spec/ruby/library/set/sortedset/sortedset_spec.rb
+++ b/spec/ruby/library/set/sortedset/sortedset_spec.rb
@@ -1,12 +1,22 @@
require_relative '../../../spec_helper'
require 'set'
-describe "SortedSet" do
- it "raises error including message that it has been extracted from the set stdlib" do
- -> {
- SortedSet
- }.should raise_error(RuntimeError) { |e|
- e.message.should.include?("The `SortedSet` class has been extracted from the `set` library")
- }
+ruby_version_is "3.0" do
+ describe "SortedSet" do
+ it "raises error including message that it has been extracted from the set stdlib" do
+ -> {
+ SortedSet
+ }.should raise_error(RuntimeError) { |e|
+ e.message.should.include?("The `SortedSet` class has been extracted from the `set` library")
+ }
+ end
+ end
+end
+
+ruby_version_is ""..."3.0" do
+ describe "SortedSet" do
+ it "is part of the set stdlib" do
+ SortedSet.superclass.should == Set
+ end
end
end
diff --git a/spec/ruby/library/set/sortedset/subset_spec.rb b/spec/ruby/library/set/sortedset/subset_spec.rb
new file mode 100644
index 0000000000..272e3f985e
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/subset_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#subset?" do
+ before :each do
+ @set = SortedSet[1, 2, 3, 4]
+ end
+
+ it "returns true if passed a SortedSet that is equal to self or self is a subset of" do
+ @set.subset?(@set).should be_true
+ SortedSet[].subset?(SortedSet[]).should be_true
+
+ SortedSet[].subset?(@set).should be_true
+ SortedSet[].subset?(SortedSet[1, 2, 3]).should be_true
+ SortedSet[].subset?(SortedSet["a", "b", "c"]).should be_true
+
+ SortedSet[1, 2, 3].subset?(@set).should be_true
+ SortedSet[1, 3].subset?(@set).should be_true
+ SortedSet[1, 2].subset?(@set).should be_true
+ SortedSet[1].subset?(@set).should be_true
+
+ SortedSet[5].subset?(@set).should be_false
+ SortedSet[1, 5].subset?(@set).should be_false
+ SortedSet["test"].subset?(@set).should be_false
+ end
+
+ it "raises an ArgumentError when passed a non-SortedSet" do
+ -> { SortedSet[].subset?([]) }.should raise_error(ArgumentError)
+ -> { SortedSet[].subset?(1) }.should raise_error(ArgumentError)
+ -> { SortedSet[].subset?("test") }.should raise_error(ArgumentError)
+ -> { SortedSet[].subset?(Object.new) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/subtract_spec.rb b/spec/ruby/library/set/sortedset/subtract_spec.rb
new file mode 100644
index 0000000000..b2af127f89
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/subtract_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#subtract" do
+ before :each do
+ @set = SortedSet["a", "b", "c"]
+ end
+
+ it "deletes any elements contained in other and returns self" do
+ @set.subtract(SortedSet["b", "c"]).should == @set
+ @set.should == SortedSet["a"]
+ end
+
+ it "accepts any enumerable as other" do
+ @set.subtract(["c"]).should == SortedSet["a", "b"]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/superset_spec.rb b/spec/ruby/library/set/sortedset/superset_spec.rb
new file mode 100644
index 0000000000..a1bbacb966
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/superset_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#superset?" do
+ before :each do
+ @set = SortedSet[1, 2, 3, 4]
+ end
+
+ it "returns true if passed a SortedSet that equals self or self is a proper superset of" do
+ @set.superset?(@set).should be_true
+ SortedSet[].superset?(SortedSet[]).should be_true
+
+ @set.superset?(SortedSet[]).should be_true
+ SortedSet[1, 2, 3].superset?(SortedSet[]).should be_true
+ SortedSet["a", "b", "c"].superset?(SortedSet[]).should be_true
+
+ @set.superset?(SortedSet[1, 2, 3]).should be_true
+ @set.superset?(SortedSet[1, 3]).should be_true
+ @set.superset?(SortedSet[1, 2]).should be_true
+ @set.superset?(SortedSet[1]).should be_true
+
+ @set.superset?(SortedSet[5]).should be_false
+ @set.superset?(SortedSet[1, 5]).should be_false
+ @set.superset?(SortedSet["test"]).should be_false
+ end
+
+ it "raises an ArgumentError when passed a non-SortedSet" do
+ -> { SortedSet[].superset?([]) }.should raise_error(ArgumentError)
+ -> { SortedSet[].superset?(1) }.should raise_error(ArgumentError)
+ -> { SortedSet[].superset?("test") }.should raise_error(ArgumentError)
+ -> { SortedSet[].superset?(Object.new) }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/to_a_spec.rb b/spec/ruby/library/set/sortedset/to_a_spec.rb
new file mode 100644
index 0000000000..bb54cd7cdb
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/to_a_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require 'set'
+
+ describe "SortedSet#to_a" do
+ it "returns an array containing elements" do
+ set = SortedSet.new [1, 2, 3]
+ set.to_a.should == [1, 2, 3]
+ end
+
+ it "returns a sorted array containing elements" do
+ set = SortedSet[2, 3, 1]
+ set.to_a.should == [1, 2, 3]
+
+ set = SortedSet.new [5, 6, 4, 4]
+ set.to_a.should == [4, 5, 6]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/union_spec.rb b/spec/ruby/library/set/sortedset/union_spec.rb
new file mode 100644
index 0000000000..c942f20d3e
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/union_spec.rb
@@ -0,0 +1,14 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is ""..."3.0" do
+ require_relative 'shared/union'
+ require 'set'
+
+ describe "SortedSet#union" do
+ it_behaves_like :sorted_set_union, :union
+ end
+
+ describe "SortedSet#|" do
+ it_behaves_like :sorted_set_union, :|
+ end
+end
diff --git a/spec/ruby/library/set/subset_spec.rb b/spec/ruby/library/set/subset_spec.rb
index 85666d633f..f375efa6df 100644
--- a/spec/ruby/library/set/subset_spec.rb
+++ b/spec/ruby/library/set/subset_spec.rb
@@ -1,7 +1,6 @@
require_relative '../../spec_helper'
require_relative 'fixtures/set_like'
require 'set'
-set_version = defined?(Set::VERSION) ? Set::VERSION : '1.0.0'
describe "Set#subset?" do
before :each do
@@ -34,11 +33,9 @@ describe "Set#subset?" do
-> { Set[].subset?(Object.new) }.should raise_error(ArgumentError)
end
- version_is(set_version, ""..."1.1.0") do #ruby_version_is ""..."3.3" do
- context "when comparing to a Set-like object" do
- it "returns true if passed a Set-like object that self is a subset of" do
- Set[1, 2, 3].subset?(SetSpecs::SetLike.new([1, 2, 3, 4])).should be_true
- end
+ context "when comparing to a Set-like object" do
+ it "returns true if passed a Set-like object that self is a subset of" do
+ Set[1, 2, 3].subset?(SetSpecs::SetLike.new([1, 2, 3, 4])).should be_true
end
end
end
diff --git a/spec/ruby/library/set/to_s_spec.rb b/spec/ruby/library/set/to_s_spec.rb
index 3c26ae9346..7b9f7b6603 100644
--- a/spec/ruby/library/set/to_s_spec.rb
+++ b/spec/ruby/library/set/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../spec_helper"
require_relative 'shared/inspect'
require 'set'
diff --git a/spec/ruby/library/shellwords/shellwords_spec.rb b/spec/ruby/library/shellwords/shellwords_spec.rb
index fe86b6faab..2975fd9974 100644
--- a/spec/ruby/library/shellwords/shellwords_spec.rb
+++ b/spec/ruby/library/shellwords/shellwords_spec.rb
@@ -1,33 +1,34 @@
require_relative '../../spec_helper'
require 'shellwords'
+include Shellwords
describe "Shellwords#shellwords" do
it "honors quoted strings" do
- Shellwords.shellwords('a "b b" a').should == ['a', 'b b', 'a']
+ shellwords('a "b b" a').should == ['a', 'b b', 'a']
end
it "honors escaped double quotes" do
- Shellwords.shellwords('a "\"b\" c" d').should == ['a', '"b" c', 'd']
+ shellwords('a "\"b\" c" d').should == ['a', '"b" c', 'd']
end
it "honors escaped single quotes" do
- Shellwords.shellwords("a \"'b' c\" d").should == ['a', "'b' c", 'd']
+ shellwords("a \"'b' c\" d").should == ['a', "'b' c", 'd']
end
it "honors escaped spaces" do
- Shellwords.shellwords('a b\ c d').should == ['a', 'b c', 'd']
+ shellwords('a b\ c d').should == ['a', 'b c', 'd']
end
it "raises ArgumentError when double quoted strings are misquoted" do
- -> { Shellwords.shellwords('a "b c d e') }.should raise_error(ArgumentError)
+ -> { shellwords('a "b c d e') }.should raise_error(ArgumentError)
end
it "raises ArgumentError when single quoted strings are misquoted" do
- -> { Shellwords.shellwords("a 'b c d e") }.should raise_error(ArgumentError)
+ -> { shellwords("a 'b c d e") }.should raise_error(ArgumentError)
end
# https://bugs.ruby-lang.org/issues/10055
it "matches POSIX sh behavior for backslashes within double quoted strings" do
- Shellwords.shellsplit('printf "%s\n"').should == ['printf', '%s\n']
+ shellsplit('printf "%s\n"').should == ['printf', '%s\n']
end
end
diff --git a/spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb b/spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb
index 4f7cf439a0..c32da5986d 100644
--- a/spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb
+++ b/spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb
@@ -1,4 +1,5 @@
-describe :socket_addrinfo_to_sockaddr, shared: true do
+describe :socket_addrinfo_to_sockaddr, :shared => true do
+
describe "for an ipv4 socket" do
before :each do
@addrinfo = Addrinfo.tcp("127.0.0.1", 80)
@@ -46,4 +47,5 @@ describe :socket_addrinfo_to_sockaddr, shared: true do
addr.send(@method).should == Socket.sockaddr_in(0, '')
end
end
+
end
diff --git a/spec/ruby/library/socket/basicsocket/recv_spec.rb b/spec/ruby/library/socket/basicsocket/recv_spec.rb
index a56114f4ab..b6ccda5d00 100644
--- a/spec/ruby/library/socket/basicsocket/recv_spec.rb
+++ b/spec/ruby/library/socket/basicsocket/recv_spec.rb
@@ -32,25 +32,6 @@ describe "BasicSocket#recv" do
ScratchPad.recorded.should == 'hello'
end
- ruby_version_is "3.3" do
- it "returns nil on a closed stream socket" do
- t = Thread.new do
- client = @server.accept
- packet = client.recv(10)
- client.close
- packet
- end
-
- Thread.pass while t.status and t.status != "sleep"
- t.status.should_not be_nil
-
- socket = TCPSocket.new('127.0.0.1', @port)
- socket.close
-
- t.value.should be_nil
- end
- end
-
platform_is_not :solaris do
it "accepts flags to specify unusual receiving behaviour" do
t = Thread.new do
diff --git a/spec/ruby/library/socket/basicsocket/send_spec.rb b/spec/ruby/library/socket/basicsocket/send_spec.rb
index 041ce03d72..868801df30 100644
--- a/spec/ruby/library/socket/basicsocket/send_spec.rb
+++ b/spec/ruby/library/socket/basicsocket/send_spec.rb
@@ -22,7 +22,7 @@ describe "BasicSocket#send" do
client = @server.accept
loop do
got = client.recv(5)
- break if got.nil? || got.empty?
+ break if got.empty?
data << got
end
client.close
@@ -67,7 +67,7 @@ describe "BasicSocket#send" do
client = @server.accept
loop do
got = client.recv(5)
- break if got.nil? || got.empty?
+ break if got.empty?
data << got
end
client.close
diff --git a/spec/ruby/library/socket/basicsocket/shutdown_spec.rb b/spec/ruby/library/socket/basicsocket/shutdown_spec.rb
index c78b32de38..41d9581bde 100644
--- a/spec/ruby/library/socket/basicsocket/shutdown_spec.rb
+++ b/spec/ruby/library/socket/basicsocket/shutdown_spec.rb
@@ -23,7 +23,7 @@ platform_is_not :windows do # hangs
it 'shuts down a socket for reading' do
@client.shutdown(Socket::SHUT_RD)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for writing' do
@@ -35,7 +35,7 @@ platform_is_not :windows do # hangs
it 'shuts down a socket for reading and writing' do
@client.shutdown(Socket::SHUT_RDWR)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
-> { @client.write('hello') }.should raise_error(Errno::EPIPE)
end
@@ -49,13 +49,13 @@ platform_is_not :windows do # hangs
it 'shuts down a socket for reading using :RD' do
@client.shutdown(:RD)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for reading using :SHUT_RD' do
@client.shutdown(:SHUT_RD)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for writing using :WR' do
@@ -73,7 +73,7 @@ platform_is_not :windows do # hangs
it 'shuts down a socket for reading and writing' do
@client.shutdown(:RDWR)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
-> { @client.write('hello') }.should raise_error(Errno::EPIPE)
end
@@ -87,13 +87,13 @@ platform_is_not :windows do # hangs
it 'shuts down a socket for reading using "RD"' do
@client.shutdown('RD')
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for reading using "SHUT_RD"' do
@client.shutdown('SHUT_RD')
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for writing using "WR"' do
@@ -123,7 +123,7 @@ platform_is_not :windows do # hangs
@client.shutdown(@dummy)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for reading using "SHUT_RD"' do
@@ -131,7 +131,7 @@ platform_is_not :windows do # hangs
@client.shutdown(@dummy)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
end
it 'shuts down a socket for reading and writing' do
@@ -139,7 +139,7 @@ platform_is_not :windows do # hangs
@client.shutdown(@dummy)
- @client.recv(1).to_s.should be_empty
+ @client.recv(1).should be_empty
-> { @client.write('hello') }.should raise_error(Errno::EPIPE)
end
diff --git a/spec/ruby/library/socket/fixtures/classes.rb b/spec/ruby/library/socket/fixtures/classes.rb
index 786629d2ef..4a590502ca 100644
--- a/spec/ruby/library/socket/fixtures/classes.rb
+++ b/spec/ruby/library/socket/fixtures/classes.rb
@@ -37,9 +37,7 @@ module SocketSpecs
# Check for too long unix socket path (max 104 bytes on macOS)
# Note that Linux accepts not null-terminated paths but the man page advises against it.
if path.bytesize > 104
- # rm_r in spec/mspec/lib/mspec/helpers/fs.rb fails against
- # "/tmp/unix_server_spec.socket"
- skip "too long unix socket path: #{path}"
+ path = "/tmp/unix_server_spec.socket"
end
rm_socket(path)
path
@@ -113,7 +111,7 @@ module SocketSpecs
begin
data = socket.recv(1024)
- return if data.nil? || data.empty?
+ return if data.empty?
log "SpecTCPServer received: #{data.inspect}"
return if data == "QUIT"
diff --git a/spec/ruby/library/socket/ipsocket/getaddress_spec.rb b/spec/ruby/library/socket/ipsocket/getaddress_spec.rb
index 96324982e5..746d2ab86b 100644
--- a/spec/ruby/library/socket/ipsocket/getaddress_spec.rb
+++ b/spec/ruby/library/socket/ipsocket/getaddress_spec.rb
@@ -19,7 +19,7 @@ describe "Socket::IPSocket#getaddress" do
# traditionally invalidly named ones.
it "raises an error on unknown hostnames" do
-> {
- IPSocket.getaddress("rubyspecdoesntexist.ruby-lang.org")
+ IPSocket.getaddress("rubyspecdoesntexist.fallingsnow.net")
}.should raise_error(SocketError)
end
end
diff --git a/spec/ruby/library/socket/shared/partially_closable_sockets.rb b/spec/ruby/library/socket/shared/partially_closable_sockets.rb
index b1c2ebabe1..1bdff08bf6 100644
--- a/spec/ruby/library/socket/shared/partially_closable_sockets.rb
+++ b/spec/ruby/library/socket/shared/partially_closable_sockets.rb
@@ -1,4 +1,4 @@
-describe :partially_closable_sockets, shared: true do
+describe "partially closable sockets", shared: true do
it "if the write end is closed then the other side can read past EOF without blocking" do
@s1.write("foo")
@s1.close_write
diff --git a/spec/ruby/library/socket/socket/getnameinfo_spec.rb b/spec/ruby/library/socket/socket/getnameinfo_spec.rb
index 4f13bf484d..b406348aa8 100644
--- a/spec/ruby/library/socket/socket/getnameinfo_spec.rb
+++ b/spec/ruby/library/socket/socket/getnameinfo_spec.rb
@@ -70,7 +70,7 @@ describe 'Socket.getnameinfo' do
it 'raises SocketError or TypeError when using an invalid String' do
-> { Socket.getnameinfo('cats') }.should raise_error(Exception) { |e|
- (e.is_a?(SocketError) || e.is_a?(TypeError)).should == true
+ [SocketError, TypeError].should include(e.class)
}
end
diff --git a/spec/ruby/library/socket/socket/new_spec.rb b/spec/ruby/library/socket/socket/new_spec.rb
new file mode 100644
index 0000000000..b2ec607f6a
--- /dev/null
+++ b/spec/ruby/library/socket/socket/new_spec.rb
@@ -0,0 +1,2 @@
+require_relative '../spec_helper'
+require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/socket/tcpserver/new_spec.rb b/spec/ruby/library/socket/tcpserver/new_spec.rb
index dd1ba676bd..8d9696c9d8 100644
--- a/spec/ruby/library/socket/tcpserver/new_spec.rb
+++ b/spec/ruby/library/socket/tcpserver/new_spec.rb
@@ -97,12 +97,6 @@ describe "TCPServer.new" do
addr[1].should be_kind_of(Integer)
end
- it "does not use the given block and warns to use TCPServer::open" do
- -> {
- @server = TCPServer.new(0) { raise }
- }.should complain(/warning: TCPServer::new\(\) does not take block; use TCPServer::open\(\) instead/)
- end
-
it "raises Errno::EADDRNOTAVAIL when the address is unknown" do
-> { TCPServer.new("1.2.3.4", 0) }.should raise_error(Errno::EADDRNOTAVAIL)
end
diff --git a/spec/ruby/library/socket/tcpsocket/initialize_spec.rb b/spec/ruby/library/socket/tcpsocket/initialize_spec.rb
index 3bec06c697..065c8f4190 100644
--- a/spec/ruby/library/socket/tcpsocket/initialize_spec.rb
+++ b/spec/ruby/library/socket/tcpsocket/initialize_spec.rb
@@ -4,27 +4,6 @@ require_relative 'shared/new'
describe 'TCPSocket#initialize' do
it_behaves_like :tcpsocket_new, :new
-
- describe "with a running server" do
- before :each do
- @server = SocketSpecs::SpecTCPServer.new
- @hostname = @server.hostname
- end
-
- after :each do
- if @socket
- @socket.write "QUIT"
- @socket.close
- end
- @server.shutdown
- end
-
- it "does not use the given block and warns to use TCPSocket::open" do
- -> {
- @socket = TCPSocket.new(@hostname, @server.port, nil) { raise }
- }.should complain(/warning: TCPSocket::new\(\) does not take block; use TCPSocket::open\(\) instead/)
- end
- end
end
describe 'TCPSocket#initialize' do
diff --git a/spec/ruby/library/socket/tcpsocket/open_spec.rb b/spec/ruby/library/socket/tcpsocket/open_spec.rb
index 0c0b579064..31b630a23b 100644
--- a/spec/ruby/library/socket/tcpsocket/open_spec.rb
+++ b/spec/ruby/library/socket/tcpsocket/open_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/new'
describe "TCPSocket.open" do
diff --git a/spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb b/spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb
index d365ecd335..a381627a39 100644
--- a/spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb
+++ b/spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb
@@ -16,6 +16,6 @@ describe "TCPSocket partial closability" do
@s2.close
end
- it_should_behave_like :partially_closable_sockets
+ it_should_behave_like "partially closable sockets"
end
diff --git a/spec/ruby/library/socket/tcpsocket/shared/new.rb b/spec/ruby/library/socket/tcpsocket/shared/new.rb
index 90f8d7e6a2..e7eb2f3c13 100644
--- a/spec/ruby/library/socket/tcpsocket/shared/new.rb
+++ b/spec/ruby/library/socket/tcpsocket/shared/new.rb
@@ -14,14 +14,11 @@ describe :tcpsocket_new, shared: true do
}
end
- ruby_version_is ""..."3.2" do
+ ruby_version_is "3.0"..."3.1" do
it 'raises Errno::ETIMEDOUT with :connect_timeout when no server is listening on the given address' do
-> {
TCPSocket.send(@method, "192.0.2.1", 80, connect_timeout: 0)
}.should raise_error(Errno::ETIMEDOUT)
- rescue Errno::ENETUNREACH
- # In the case all network interfaces down.
- # raise_error cannot deal with multiple expected exceptions
end
end
@@ -30,9 +27,6 @@ describe :tcpsocket_new, shared: true do
-> {
TCPSocket.send(@method, "192.0.2.1", 80, connect_timeout: 0)
}.should raise_error(IO::TimeoutError)
- rescue Errno::ENETUNREACH
- # In the case all network interfaces down.
- # raise_error cannot deal with multiple expected exceptions
end
end
@@ -98,9 +92,11 @@ describe :tcpsocket_new, shared: true do
@socket.addr[2].should =~ /^#{@hostname}/
end
- it "connects to a server when passed connect_timeout argument" do
- @socket = TCPSocket.send(@method, @hostname, @server.port, connect_timeout: 1)
- @socket.should be_an_instance_of(TCPSocket)
+ ruby_version_is "3.0" do
+ it "connects to a server when passed connect_timeout argument" do
+ @socket = TCPSocket.send(@method, @hostname, @server.port, connect_timeout: 1)
+ @socket.should be_an_instance_of(TCPSocket)
+ end
end
end
end
diff --git a/spec/ruby/library/socket/udpsocket/new_spec.rb b/spec/ruby/library/socket/udpsocket/new_spec.rb
index 79bfcb624d..6cc0cadbcb 100644
--- a/spec/ruby/library/socket/udpsocket/new_spec.rb
+++ b/spec/ruby/library/socket/udpsocket/new_spec.rb
@@ -26,12 +26,6 @@ describe 'UDPSocket.new' do
@socket.should be_an_instance_of(UDPSocket)
end
- it "does not use the given block and warns to use UDPSocket::open" do
- -> {
- @socket = UDPSocket.new { raise }
- }.should complain(/warning: UDPSocket::new\(\) does not take block; use UDPSocket::open\(\) instead/)
- end
-
it 'raises Errno::EAFNOSUPPORT or Errno::EPROTONOSUPPORT if unsupported family passed' do
-> { UDPSocket.new(-1) }.should raise_error(SystemCallError) { |e|
[Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT].should include(e.class)
diff --git a/spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb b/spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb
index dba3de7359..30688b46b6 100644
--- a/spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb
+++ b/spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb
@@ -1,8 +1,9 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXServer#accept_nonblock" do
+describe "UNIXServer#accept_nonblock" do
+
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -32,7 +33,9 @@ with_feature :unix_socket do
@server.accept_nonblock(exception: false).should == :wait_readable
end
end
+end
+with_feature :unix_socket do
describe 'UNIXServer#accept_nonblock' do
before do
@path = SocketSpecs.socket_path
diff --git a/spec/ruby/library/socket/unixserver/accept_spec.rb b/spec/ruby/library/socket/unixserver/accept_spec.rb
index 624782d6b9..c05fbe7f22 100644
--- a/spec/ruby/library/socket/unixserver/accept_spec.rb
+++ b/spec/ruby/library/socket/unixserver/accept_spec.rb
@@ -1,7 +1,7 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
+platform_is_not :windows do
describe "UNIXServer#accept" do
before :each do
@path = SocketSpecs.socket_path
diff --git a/spec/ruby/library/socket/unixserver/for_fd_spec.rb b/spec/ruby/library/socket/unixserver/for_fd_spec.rb
index e00c4d9526..4f3816ad37 100644
--- a/spec/ruby/library/socket/unixserver/for_fd_spec.rb
+++ b/spec/ruby/library/socket/unixserver/for_fd_spec.rb
@@ -1,7 +1,7 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
+platform_is_not :windows do
describe "UNIXServer#for_fd" do
before :each do
@unix_path = SocketSpecs.socket_path
diff --git a/spec/ruby/library/socket/unixserver/new_spec.rb b/spec/ruby/library/socket/unixserver/new_spec.rb
index a160e3ce5c..f831f40bc6 100644
--- a/spec/ruby/library/socket/unixserver/new_spec.rb
+++ b/spec/ruby/library/socket/unixserver/new_spec.rb
@@ -1,14 +1,6 @@
require_relative '../spec_helper'
require_relative 'shared/new'
-with_feature :unix_socket do
- describe "UNIXServer.new" do
- it_behaves_like :unixserver_new, :new
-
- it "does not use the given block and warns to use UNIXServer::open" do
- -> {
- @server = UNIXServer.new(@path) { raise }
- }.should complain(/warning: UNIXServer::new\(\) does not take block; use UNIXServer::open\(\) instead/)
- end
- end
+describe "UNIXServer.new" do
+ it_behaves_like :unixserver_new, :new
end
diff --git a/spec/ruby/library/socket/unixserver/open_spec.rb b/spec/ruby/library/socket/unixserver/open_spec.rb
index 16453dd3bd..f2506d9f6f 100644
--- a/spec/ruby/library/socket/unixserver/open_spec.rb
+++ b/spec/ruby/library/socket/unixserver/open_spec.rb
@@ -2,10 +2,10 @@ require_relative '../spec_helper'
require_relative '../fixtures/classes'
require_relative 'shared/new'
-with_feature :unix_socket do
- describe "UNIXServer.open" do
- it_behaves_like :unixserver_new, :open
+describe "UNIXServer.open" do
+ it_behaves_like :unixserver_new, :open
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
end
diff --git a/spec/ruby/library/socket/unixserver/shared/new.rb b/spec/ruby/library/socket/unixserver/shared/new.rb
index b537f2a871..35395826c9 100644
--- a/spec/ruby/library/socket/unixserver/shared/new.rb
+++ b/spec/ruby/library/socket/unixserver/shared/new.rb
@@ -2,19 +2,21 @@ require_relative '../../spec_helper'
require_relative '../../fixtures/classes'
describe :unixserver_new, shared: true do
- before :each do
- @path = SocketSpecs.socket_path
- end
+ platform_is_not :windows do
+ before :each do
+ @path = SocketSpecs.socket_path
+ end
- after :each do
- @server.close if @server
- @server = nil
- SocketSpecs.rm_socket @path
- end
+ after :each do
+ @server.close if @server
+ @server = nil
+ SocketSpecs.rm_socket @path
+ end
- it "creates a new UNIXServer" do
- @server = UNIXServer.send(@method, @path)
- @server.path.should == @path
- @server.addr.should == ["AF_UNIX", @path]
+ it "creates a new UNIXServer" do
+ @server = UNIXServer.send(@method, @path)
+ @server.path.should == @path
+ @server.addr.should == ["AF_UNIX", @path]
+ end
end
end
diff --git a/spec/ruby/library/socket/unixsocket/addr_spec.rb b/spec/ruby/library/socket/unixsocket/addr_spec.rb
index d93e061312..e8431bea16 100644
--- a/spec/ruby/library/socket/unixsocket/addr_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/addr_spec.rb
@@ -1,8 +1,9 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#addr" do
+describe "UNIXSocket#addr" do
+
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
diff --git a/spec/ruby/library/socket/unixsocket/inspect_spec.rb b/spec/ruby/library/socket/unixsocket/inspect_spec.rb
index a542ba6db5..d2e3cabbd3 100644
--- a/spec/ruby/library/socket/unixsocket/inspect_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/inspect_spec.rb
@@ -1,8 +1,8 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#inspect" do
+describe "UNIXSocket#inspect" do
+ platform_is_not :windows do
it "returns sockets fd for unnamed sockets" do
begin
s1, s2 = UNIXSocket.socketpair
diff --git a/spec/ruby/library/socket/unixsocket/local_address_spec.rb b/spec/ruby/library/socket/unixsocket/local_address_spec.rb
index 734253e7f5..cbf315f9f4 100644
--- a/spec/ruby/library/socket/unixsocket/local_address_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/local_address_spec.rb
@@ -46,7 +46,9 @@ with_feature :unix_socket do
end
end
end
+end
+with_feature :unix_socket do
describe 'UNIXSocket#local_address with a UNIX socket pair' do
before :each do
@sock, @sock2 = Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM)
diff --git a/spec/ruby/library/socket/unixsocket/new_spec.rb b/spec/ruby/library/socket/unixsocket/new_spec.rb
index 6d8ea6dcfe..05a6b3eda2 100644
--- a/spec/ruby/library/socket/unixsocket/new_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/new_spec.rb
@@ -1,14 +1,6 @@
require_relative '../spec_helper'
require_relative 'shared/new'
-with_feature :unix_socket do
- describe "UNIXSocket.new" do
- it_behaves_like :unixsocket_new, :new
-
- it "does not use the given block and warns to use UNIXSocket::open" do
- -> {
- @client = UNIXSocket.new(@path) { raise }
- }.should complain(/warning: UNIXSocket::new\(\) does not take block; use UNIXSocket::open\(\) instead/)
- end
- end
+describe "UNIXSocket.new" do
+ it_behaves_like :unixsocket_new, :new
end
diff --git a/spec/ruby/library/socket/unixsocket/open_spec.rb b/spec/ruby/library/socket/unixsocket/open_spec.rb
index 61def30abb..99ad151bb8 100644
--- a/spec/ruby/library/socket/unixsocket/open_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/open_spec.rb
@@ -2,12 +2,12 @@ require_relative '../spec_helper'
require_relative '../fixtures/classes'
require_relative 'shared/new'
-with_feature :unix_socket do
- describe "UNIXSocket.open" do
- it_behaves_like :unixsocket_new, :open
- end
+describe "UNIXSocket.open" do
+ it_behaves_like :unixsocket_new, :open
+end
- describe "UNIXSocket.open" do
+describe "UNIXSocket.open" do
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
diff --git a/spec/ruby/library/socket/unixsocket/pair_spec.rb b/spec/ruby/library/socket/unixsocket/pair_spec.rb
index 9a66c56c10..845ff76ecc 100644
--- a/spec/ruby/library/socket/unixsocket/pair_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/pair_spec.rb
@@ -2,9 +2,10 @@ require_relative '../spec_helper'
require_relative '../fixtures/classes'
require_relative '../shared/partially_closable_sockets'
-with_feature :unix_socket do
- describe "UNIXSocket#pair" do
- it_should_behave_like :partially_closable_sockets
+describe "UNIXSocket#pair" do
+ platform_is_not :windows do
+
+ it_should_behave_like "partially closable sockets"
before :each do
@s1, @s2 = UNIXSocket.pair
diff --git a/spec/ruby/library/socket/unixsocket/partially_closable_spec.rb b/spec/ruby/library/socket/unixsocket/partially_closable_spec.rb
index ef7d0f0b2a..78a64fe6be 100644
--- a/spec/ruby/library/socket/unixsocket/partially_closable_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/partially_closable_spec.rb
@@ -2,8 +2,9 @@ require_relative '../spec_helper'
require_relative '../fixtures/classes'
require_relative '../shared/partially_closable_sockets'
-with_feature :unix_socket do
+platform_is_not :windows do
describe "UNIXSocket partial closability" do
+
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -18,6 +19,7 @@ with_feature :unix_socket do
SocketSpecs.rm_socket @path
end
- it_should_behave_like :partially_closable_sockets
+ it_should_behave_like "partially closable sockets"
+
end
end
diff --git a/spec/ruby/library/socket/unixsocket/path_spec.rb b/spec/ruby/library/socket/unixsocket/path_spec.rb
index a608378e4f..317ffc0975 100644
--- a/spec/ruby/library/socket/unixsocket/path_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/path_spec.rb
@@ -1,8 +1,9 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#path" do
+describe "UNIXSocket#path" do
+
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -23,4 +24,5 @@ with_feature :unix_socket do
@client.path.should == ""
end
end
+
end
diff --git a/spec/ruby/library/socket/unixsocket/peeraddr_spec.rb b/spec/ruby/library/socket/unixsocket/peeraddr_spec.rb
index 72bc96b1fe..0b6b1ccf04 100644
--- a/spec/ruby/library/socket/unixsocket/peeraddr_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/peeraddr_spec.rb
@@ -1,8 +1,9 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#peeraddr" do
+describe "UNIXSocket#peeraddr" do
+
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -25,4 +26,5 @@ with_feature :unix_socket do
}.should raise_error(Errno::ENOTCONN)
end
end
+
end
diff --git a/spec/ruby/library/socket/unixsocket/recv_io_spec.rb b/spec/ruby/library/socket/unixsocket/recv_io_spec.rb
index 1dbc4538e3..533f02a0fa 100644
--- a/spec/ruby/library/socket/unixsocket/recv_io_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/recv_io_spec.rb
@@ -1,8 +1,9 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#recv_io" do
+describe "UNIXSocket#recv_io" do
+
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -40,7 +41,9 @@ with_feature :unix_socket do
@io.should be_an_instance_of(File)
end
end
+end
+with_feature :unix_socket do
describe 'UNIXSocket#recv_io' do
before do
@file = File.open('/dev/null', 'w')
diff --git a/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb b/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb
index fedf74bb2f..c0e1cf670b 100644
--- a/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb
@@ -1,8 +1,8 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#recvfrom" do
+describe "UNIXSocket#recvfrom" do
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -42,7 +42,10 @@ with_feature :unix_socket do
sock.close
end
end
+end
+
+with_feature :unix_socket do
describe 'UNIXSocket#recvfrom' do
describe 'using a socket pair' do
before do
diff --git a/spec/ruby/library/socket/unixsocket/send_io_spec.rb b/spec/ruby/library/socket/unixsocket/send_io_spec.rb
index 80f3550c6d..a2a7d26539 100644
--- a/spec/ruby/library/socket/unixsocket/send_io_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/send_io_spec.rb
@@ -1,8 +1,9 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
-with_feature :unix_socket do
- describe "UNIXSocket#send_io" do
+describe "UNIXSocket#send_io" do
+
+ platform_is_not :windows do
before :each do
@path = SocketSpecs.socket_path
@server = UNIXServer.open(@path)
@@ -31,7 +32,9 @@ with_feature :unix_socket do
@io.read.should == File.read(@send_io_path)
end
end
+end
+with_feature :unix_socket do
describe 'UNIXSocket#send_io' do
before do
@file = File.open('/dev/null', 'w')
diff --git a/spec/ruby/library/socket/unixsocket/shared/new.rb b/spec/ruby/library/socket/unixsocket/shared/new.rb
index f075b03c5e..bfb7ed3886 100644
--- a/spec/ruby/library/socket/unixsocket/shared/new.rb
+++ b/spec/ruby/library/socket/unixsocket/shared/new.rb
@@ -2,21 +2,23 @@ require_relative '../../spec_helper'
require_relative '../../fixtures/classes'
describe :unixsocket_new, shared: true do
- before :each do
- @path = SocketSpecs.socket_path
- @server = UNIXServer.open(@path)
- end
+ platform_is_not :windows do
+ before :each do
+ @path = SocketSpecs.socket_path
+ @server = UNIXServer.open(@path)
+ end
- after :each do
- @client.close if @client
- @server.close
- SocketSpecs.rm_socket @path
- end
+ after :each do
+ @client.close if @client
+ @server.close
+ SocketSpecs.rm_socket @path
+ end
- it "opens a unix socket on the specified file" do
- @client = UNIXSocket.send(@method, @path)
+ it "opens a unix socket on the specified file" do
+ @client = UNIXSocket.send(@method, @path)
- @client.addr[0].should == "AF_UNIX"
- @client.should_not.closed?
+ @client.addr[0].should == "AF_UNIX"
+ @client.should_not.closed?
+ end
end
end
diff --git a/spec/ruby/library/stringio/append_spec.rb b/spec/ruby/library/stringio/append_spec.rb
index 5383e3e795..981229fc10 100644
--- a/spec/ruby/library/stringio/append_spec.rb
+++ b/spec/ruby/library/stringio/append_spec.rb
@@ -29,6 +29,13 @@ describe "StringIO#<< when passed [Object]" do
@io.string.should == "example\000\000\000\000\000\000\000\000just testing"
end
+ ruby_version_is ""..."3.0" do
+ it "does not taint self when the passed argument is tainted" do
+ (@io << "test".taint)
+ @io.tainted?.should be_false
+ end
+ end
+
it "updates self's position" do
@io << "test"
@io.pos.should eql(4)
diff --git a/spec/ruby/library/stringio/bytes_spec.rb b/spec/ruby/library/stringio/bytes_spec.rb
new file mode 100644
index 0000000000..4ef7a490a5
--- /dev/null
+++ b/spec/ruby/library/stringio/bytes_spec.rb
@@ -0,0 +1,29 @@
+require_relative '../../spec_helper'
+require 'stringio'
+require_relative 'shared/each_byte'
+
+ruby_version_is ''...'3.0' do
+ describe "StringIO#bytes" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_byte, :bytes
+ end
+
+ describe "StringIO#bytes when self is not readable" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_byte_not_readable, :bytes
+ end
+end
diff --git a/spec/ruby/library/stringio/chars_spec.rb b/spec/ruby/library/stringio/chars_spec.rb
new file mode 100644
index 0000000000..58cba77634
--- /dev/null
+++ b/spec/ruby/library/stringio/chars_spec.rb
@@ -0,0 +1,29 @@
+require_relative '../../spec_helper'
+require 'stringio'
+require_relative 'shared/each_char'
+
+ruby_version_is ''...'3.0' do
+ describe "StringIO#chars" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_char, :chars
+ end
+
+ describe "StringIO#chars when self is not readable" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_char_not_readable, :chars
+ end
+end
diff --git a/spec/ruby/library/stringio/codepoints_spec.rb b/spec/ruby/library/stringio/codepoints_spec.rb
new file mode 100644
index 0000000000..ceaadefc32
--- /dev/null
+++ b/spec/ruby/library/stringio/codepoints_spec.rb
@@ -0,0 +1,19 @@
+# -*- encoding: utf-8 -*-
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative 'shared/codepoints'
+
+ruby_version_is ''...'3.0' do
+ # See redmine #1667
+ describe "StringIO#codepoints" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_codepoints, :codepoints
+ end
+end
diff --git a/spec/ruby/library/stringio/initialize_spec.rb b/spec/ruby/library/stringio/initialize_spec.rb
index 158c08488b..c597e328d3 100644
--- a/spec/ruby/library/stringio/initialize_spec.rb
+++ b/spec/ruby/library/stringio/initialize_spec.rb
@@ -294,9 +294,14 @@ describe "StringIO#initialize sets" do
io.string.encoding.should == Encoding::EUC_JP
end
- it "the #external_encoding to the encoding of the String when passed a String" do
- s = ''.force_encoding(Encoding::EUC_JP)
- io = StringIO.new(s)
- io.external_encoding.should == Encoding::EUC_JP
+ guard_not -> { # [Bug #16497]
+ stringio_version = StringIO.const_defined?(:VERSION) ? StringIO::VERSION : "0.0.2"
+ version_is(stringio_version, "0.0.3"..."0.1.1")
+ } do
+ it "the #external_encoding to the encoding of the String when passed a String" do
+ s = ''.force_encoding(Encoding::EUC_JP)
+ io = StringIO.new(s)
+ io.external_encoding.should == Encoding::EUC_JP
+ end
end
end
diff --git a/spec/ruby/library/stringio/lines_spec.rb b/spec/ruby/library/stringio/lines_spec.rb
new file mode 100644
index 0000000000..42d11772ae
--- /dev/null
+++ b/spec/ruby/library/stringio/lines_spec.rb
@@ -0,0 +1,53 @@
+require_relative '../../spec_helper'
+require 'stringio'
+require_relative 'shared/each'
+
+ruby_version_is ''...'3.0' do
+ describe "StringIO#lines when passed a separator" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_separator, :lines
+ end
+
+ describe "StringIO#lines when passed no arguments" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_no_arguments, :lines
+ end
+
+ describe "StringIO#lines when self is not readable" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_not_readable, :lines
+ end
+
+ describe "StringIO#lines when passed chomp" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it_behaves_like :stringio_each_chomp, :lines
+ end
+end
diff --git a/spec/ruby/library/stringio/new_spec.rb b/spec/ruby/library/stringio/new_spec.rb
index ec4b32aa11..e36d210caa 100644
--- a/spec/ruby/library/stringio/new_spec.rb
+++ b/spec/ruby/library/stringio/new_spec.rb
@@ -2,9 +2,7 @@ require_relative '../../spec_helper'
require 'stringio'
describe "StringIO.new" do
- it "does not use the given block and warns to use StringIO::open" do
- -> {
- StringIO.new { raise }
- }.should complain(/warning: StringIO::new\(\) does not take block; use StringIO::open\(\) instead/)
+ it "warns when called with a block" do
+ -> { eval("StringIO.new {}") }.should complain(/StringIO::new\(\) does not take block; use StringIO::open\(\) instead/)
end
-end
+end \ No newline at end of file
diff --git a/spec/ruby/library/stringio/reopen_spec.rb b/spec/ruby/library/stringio/reopen_spec.rb
index 9851c5b706..4863a5332b 100644
--- a/spec/ruby/library/stringio/reopen_spec.rb
+++ b/spec/ruby/library/stringio/reopen_spec.rb
@@ -23,6 +23,17 @@ describe "StringIO#reopen when passed [Object, Integer]" do
@io.string.should == "reopened, another time"
end
+ ruby_version_is ""..."3.0" do
+ # NOTE: WEIRD!
+ it "does not taint self when the passed Object was tainted" do
+ @io.reopen("reopened".taint, IO::RDONLY)
+ @io.tainted?.should be_false
+
+ @io.reopen("reopened".taint, IO::WRONLY)
+ @io.tainted?.should be_false
+ end
+ end
+
it "tries to convert the passed Object to a String using #to_str" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return("to_str")
@@ -81,6 +92,17 @@ describe "StringIO#reopen when passed [Object, Object]" do
str.should == ""
end
+ ruby_version_is ""..."3.0" do
+ # NOTE: WEIRD!
+ it "does not taint self when the passed Object was tainted" do
+ @io.reopen("reopened".taint, "r")
+ @io.tainted?.should be_false
+
+ @io.reopen("reopened".taint, "w")
+ @io.tainted?.should be_false
+ end
+ end
+
it "tries to convert the passed Object to a String using #to_str" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return("to_str")
@@ -142,6 +164,14 @@ describe "StringIO#reopen when passed [String]" do
@io.string.should == "reopened"
end
+ ruby_version_is ""..."3.0" do
+ # NOTE: WEIRD!
+ it "does not taint self when the passed Object was tainted" do
+ @io.reopen("reopened".taint)
+ @io.tainted?.should be_false
+ end
+ end
+
it "resets self's position to 0" do
@io.read(5)
@io.reopen("reopened")
diff --git a/spec/ruby/library/stringio/set_encoding_spec.rb b/spec/ruby/library/stringio/set_encoding_spec.rb
index 19ca0875bf..21d45750f3 100644
--- a/spec/ruby/library/stringio/set_encoding_spec.rb
+++ b/spec/ruby/library/stringio/set_encoding_spec.rb
@@ -17,12 +17,4 @@ describe "StringIO#set_encoding" do
io.set_encoding Encoding::UTF_8
io.string.encoding.should == Encoding::US_ASCII
end
-
- it "accepts a String" do
- str = "".encode(Encoding::US_ASCII)
- io = StringIO.new(str)
- io.set_encoding("ASCII-8BIT")
- io.external_encoding.should == Encoding::BINARY
- str.encoding.should == Encoding::BINARY
- end
end
diff --git a/spec/ruby/library/stringio/shared/each.rb b/spec/ruby/library/stringio/shared/each.rb
index acd8d22c14..bf3265ee46 100644
--- a/spec/ruby/library/stringio/shared/each.rb
+++ b/spec/ruby/library/stringio/shared/each.rb
@@ -36,7 +36,7 @@ describe :stringio_each_separator, shared: true do
seen.should == ["2 1 2 1 2"]
end
- version_is StringIO::VERSION, ""..."3.0.4" do #ruby_version_is ""..."3.2" do
+ ruby_version_is ''..."3.2" do
it "yields each paragraph with two separation characters when passed an empty String as separator" do
seen = []
io = StringIO.new("para1\n\npara2\n\n\npara3")
@@ -45,7 +45,7 @@ describe :stringio_each_separator, shared: true do
end
end
- version_is StringIO::VERSION, "3.0.4" do #ruby_version_is "3.2" do
+ ruby_version_is "3.2" do
it "yields each paragraph with all separation characters when passed an empty String as separator" do
seen = []
io = StringIO.new("para1\n\npara2\n\n\npara3")
diff --git a/spec/ruby/library/stringio/shared/sysread.rb b/spec/ruby/library/stringio/shared/sysread.rb
index 937bac705c..3376bd9907 100644
--- a/spec/ruby/library/stringio/shared/sysread.rb
+++ b/spec/ruby/library/stringio/shared/sysread.rb
@@ -1,4 +1,4 @@
-describe :stringio_sysread_length, shared: true do
+describe :stringio_sysread_length, :shared => true do
before :each do
@io = StringIO.new("example")
end
diff --git a/spec/ruby/library/stringio/shared/write.rb b/spec/ruby/library/stringio/shared/write.rb
index aa67bb73c7..d9c21028e0 100644
--- a/spec/ruby/library/stringio/shared/write.rb
+++ b/spec/ruby/library/stringio/shared/write.rb
@@ -60,6 +60,13 @@ describe :stringio_write_string, shared: true do
@io.string.size.should == n.times.map(&:to_s).join.size
end
+ ruby_version_is ""..."3.0" do
+ it "does not taint self when the passed argument is tainted" do
+ @io.send(@method, "test".taint)
+ @io.tainted?.should be_false
+ end
+ end
+
it "handles writing non-ASCII UTF-8 after seek" do
@io.binmode
@io << "\x80"
@@ -81,27 +88,6 @@ describe :stringio_write_string, shared: true do
@io.write "fghi"
@io.string.should == "12fghi"
end
-
- it "transcodes the given string when the external encoding is set and neither is BINARY" do
- utf8_str = "hello"
- io = StringIO.new.set_encoding(Encoding::UTF_16BE)
- io.external_encoding.should == Encoding::UTF_16BE
-
- io.send(@method, utf8_str)
-
- expected = [0, 104, 0, 101, 0, 108, 0, 108, 0, 111] # UTF-16BE bytes for "hello"
- io.string.bytes.should == expected
- end
-
- it "does not transcode the given string when the external encoding is set and the string encoding is BINARY" do
- str = "été".b
- io = StringIO.new.set_encoding(Encoding::UTF_16BE)
- io.external_encoding.should == Encoding::UTF_16BE
-
- io.send(@method, str)
-
- io.string.bytes.should == str.bytes
- end
end
describe :stringio_write_not_writable, shared: true do
diff --git a/spec/ruby/library/time/to_datetime_spec.rb b/spec/ruby/library/time/to_datetime_spec.rb
index 9c44f38e5c..6025950b59 100644
--- a/spec/ruby/library/time/to_datetime_spec.rb
+++ b/spec/ruby/library/time/to_datetime_spec.rb
@@ -1,7 +1,5 @@
require_relative '../../spec_helper'
require 'time'
-require 'date'
-date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
describe "Time#to_datetime" do
it "returns a DateTime representing the same instant" do
@@ -15,7 +13,8 @@ describe "Time#to_datetime" do
datetime.sec.should == 59
end
- version_is date_version, '3.2.3' do #ruby_version_is '3.2' do
+ date_version = defined?(Date::VERSION) ? Date::VERSION : '0.0.0'
+ version_is(date_version, '3.2.3') do
it "returns a DateTime representing the same instant before Gregorian" do
time = Time.utc(1582, 10, 14, 23, 58, 59)
datetime = time.to_datetime
diff --git a/spec/ruby/library/uri/generic/host_spec.rb b/spec/ruby/library/uri/generic/host_spec.rb
index 210124ef66..f2076d2bc1 100644
--- a/spec/ruby/library/uri/generic/host_spec.rb
+++ b/spec/ruby/library/uri/generic/host_spec.rb
@@ -2,12 +2,7 @@ require_relative '../../../spec_helper'
require 'uri'
describe "URI::Generic#host" do
- version_is URI::VERSION, "0.12" do #ruby_version_is "3.2" do
- # https://hackerone.com/reports/156615
- it "returns empty string when host is empty" do
- URI.parse('http:////foo.com').host.should == ''
- end
- end
+ it "needs to be reviewed for spec completeness"
end
describe "URI::Generic#host=" do
diff --git a/spec/ruby/library/uri/generic/to_s_spec.rb b/spec/ruby/library/uri/generic/to_s_spec.rb
index 8cebd374a1..8c90d7645b 100644
--- a/spec/ruby/library/uri/generic/to_s_spec.rb
+++ b/spec/ruby/library/uri/generic/to_s_spec.rb
@@ -2,10 +2,5 @@ require_relative '../../../spec_helper'
require 'uri'
describe "URI::Generic#to_s" do
- version_is URI::VERSION, "0.12" do #ruby_version_is "3.2" do
- # https://hackerone.com/reports/156615
- it "preserves / characters when host is empty" do
- URI('http:///foo.com').to_s.should == 'http:///foo.com'
- end
- end
+ it "needs to be reviewed for spec completeness"
end
diff --git a/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb b/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb
index 52cb978bea..940eebfb91 100644
--- a/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb b/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb
index 994c2e6d36..91f5091d24 100644
--- a/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/codepage_spec.rb b/spec/ruby/library/win32ole/win32ole/codepage_spec.rb
index 07e93646ac..4e0cf5ca55 100644
--- a/spec/ruby/library/win32ole/win32ole/codepage_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/codepage_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/connect_spec.rb b/spec/ruby/library/win32ole/win32ole/connect_spec.rb
index ac0976ddc1..72dceb1572 100644
--- a/spec/ruby/library/win32ole/win32ole/connect_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/connect_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/const_load_spec.rb b/spec/ruby/library/win32ole/win32ole/const_load_spec.rb
index 2099c4aa66..cacc7a2b22 100644
--- a/spec/ruby/library/win32ole/win32ole/const_load_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/const_load_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/constants_spec.rb b/spec/ruby/library/win32ole/win32ole/constants_spec.rb
index 8533741440..978b7ade92 100644
--- a/spec/ruby/library/win32ole/win32ole/constants_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/constants_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb b/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb
index 8aa853df9e..2e18b6ab11 100644
--- a/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/invoke_spec.rb b/spec/ruby/library/win32ole/win32ole/invoke_spec.rb
index d6ff7fade3..08a5156e05 100644
--- a/spec/ruby/library/win32ole/win32ole/invoke_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/invoke_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/locale_spec.rb b/spec/ruby/library/win32ole/win32ole/locale_spec.rb
index 78ede4375a..75a82ddd7f 100644
--- a/spec/ruby/library/win32ole/win32ole/locale_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/locale_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/new_spec.rb b/spec/ruby/library/win32ole/win32ole/new_spec.rb
index 7e91c2d3ea..6b717195f1 100644
--- a/spec/ruby/library/win32ole/win32ole/new_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/new_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb
index 2bbe8c27d4..75748182fe 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb
index c1d1970214..a991624a23 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb
index 9cb3f9e6cf..8a26d79a20 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
require_relative 'shared/ole_method'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb
index e48ff8d905..f82a212f5d 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
require_relative 'shared/ole_method'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb
index fe161ce9f0..5ac9ae9cfa 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb
index afcf16a051..ef8944ee39 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb
index c091c83c95..727291e9f0 100644
--- a/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb b/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb
index bacdee63da..7409823f20 100644
--- a/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
require_relative 'shared/setproperty'
diff --git a/spec/ruby/library/win32ole/win32ole_event/new_spec.rb b/spec/ruby/library/win32ole/win32ole_event/new_spec.rb
index 94fabb1e3b..a1a1612393 100644
--- a/spec/ruby/library/win32ole/win32ole_event/new_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_event/new_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
diff --git a/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb b/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb
index 0957bdd2d4..feb26b0637 100644
--- a/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do
diff --git a/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb b/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb
index ece71df0d4..69068683b7 100644
--- a/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb b/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb
index 78634d2fde..70c8b30cca 100644
--- a/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
guard -> { WIN32OLESpecs::SYSTEM_MONITOR_CONTROL_AVAILABLE } do
diff --git a/spec/ruby/library/win32ole/win32ole_method/event_spec.rb b/spec/ruby/library/win32ole/win32ole_method/event_spec.rb
index 9b642a010c..c41f8fe99d 100644
--- a/spec/ruby/library/win32ole/win32ole_method/event_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/event_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require_relative '../fixtures/classes'
guard -> { WIN32OLESpecs::SYSTEM_MONITOR_CONTROL_AVAILABLE } do
diff --git a/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb b/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb
index d1c5ee3be2..21b3ae8bde 100644
--- a/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb b/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb
index 59dad9244c..b6d0a19a37 100644
--- a/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb b/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb
index b2f24ba151..9f940fd4a0 100644
--- a/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb b/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb
index d7fedf0d36..7fff479daf 100644
--- a/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb b/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb
index d5536fd17b..e8638abd91 100644
--- a/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/name_spec.rb b/spec/ruby/library/win32ole/win32ole_method/name_spec.rb
index 477b820f4d..cd5404fc54 100644
--- a/spec/ruby/library/win32ole/win32ole_method/name_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_method/new_spec.rb b/spec/ruby/library/win32ole/win32ole_method/new_spec.rb
index 4e427421b9..8ebf93b992 100644
--- a/spec/ruby/library/win32ole/win32ole_method/new_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/new_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb b/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb
index b3da9a8303..8e50c39787 100644
--- a/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/params_spec.rb b/spec/ruby/library/win32ole/win32ole_method/params_spec.rb
index 09fb0eb5ac..2f8da3d45b 100644
--- a/spec/ruby/library/win32ole/win32ole_method/params_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/params_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb b/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb
index 582a5951d5..f8ce3e1b3a 100644
--- a/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb b/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb
index dd8add402d..58e26df77b 100644
--- a/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb b/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb
index 3fca3d54ed..dc159dd09e 100644
--- a/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb b/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb
index fe9facb53a..a38fe5c681 100644
--- a/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb b/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb
index 8ea6e61e7d..0c5a94c338 100644
--- a/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb
index 11107a77fc..ecb3c08038 100644
--- a/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb b/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb
index d1a50523fc..918b6ef782 100644
--- a/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/default_spec.rb b/spec/ruby/library/win32ole/win32ole_param/default_spec.rb
index 44bd3d7fd3..af08c84782 100644
--- a/spec/ruby/library/win32ole/win32ole_param/default_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/default_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/input_spec.rb b/spec/ruby/library/win32ole/win32ole_param/input_spec.rb
index e9134b1df8..e2a90daa56 100644
--- a/spec/ruby/library/win32ole/win32ole_param/input_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/input_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/name_spec.rb b/spec/ruby/library/win32ole/win32ole_param/name_spec.rb
index 67a8955ba4..0c20c24720 100644
--- a/spec/ruby/library/win32ole/win32ole_param/name_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb b/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb
index f05455e3f1..e683d1c16e 100644
--- a/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb b/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb
index 1467130e03..b9a3639c3e 100644
--- a/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb b/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb
index b39ee41179..3fb9dc1867 100644
--- a/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb b/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb
index dd613dd29a..f5546e79e5 100644
--- a/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb
index e9153a2eb2..5b4b4c1c80 100644
--- a/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb b/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb
index abdf8d34b9..25907c8e32 100644
--- a/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb b/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb
index eee23abc56..d436835188 100644
--- a/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb b/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb
index 3a0a9ead94..01e6945138 100644
--- a/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb b/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb
index 9ab0004668..3bd2cbe5dd 100644
--- a/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb b/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb
index 7d2731f778..7dae16617d 100644
--- a/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb b/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb
index 3904e78d42..ff412dd100 100644
--- a/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/name_spec.rb b/spec/ruby/library/win32ole/win32ole_type/name_spec.rb
index d76998d7dc..b7a28c553a 100644
--- a/spec/ruby/library/win32ole/win32ole_type/name_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_type/new_spec.rb b/spec/ruby/library/win32ole/win32ole_type/new_spec.rb
index cc691ffa67..3c3aa1c390 100644
--- a/spec/ruby/library/win32ole/win32ole_type/new_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/new_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb b/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb
index a3a1d4ac58..0ce0fc98a4 100644
--- a/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb b/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb
index 3b99b97a61..9265549d20 100644
--- a/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb b/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb
index 24292b1c4f..2bc19aa85e 100644
--- a/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb b/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb
index 340fdb34e8..f0d80ba39e 100644
--- a/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb b/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb
index 793535b48d..19d8bf56e0 100644
--- a/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb b/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb
index 3f89fe702a..71e304d80a 100644
--- a/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb
index 9f086a5a35..b713990ed2 100644
--- a/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb b/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb
index 391d505e01..35f3562721 100644
--- a/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb b/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb
index a487208caa..369e0274f3 100644
--- a/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb b/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb
index 7f61b8af95..fbf3dd0341 100644
--- a/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb b/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb
index 99e34edcdd..403b2b843b 100644
--- a/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb
index dd9bfa594f..8bac1a9891 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb
index 7a9c791494..dab4edabaa 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb
index 03a9aa4c74..d08acc9bde 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb
index d4cab8e924..000ac14d7e 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/name'
platform_is :windows do
diff --git a/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb
index b7849793c5..4f240b561c 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb
index 7a79d32ddc..4cca7f8874 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb
index 9d7b8238c8..56cd1c337a 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb
index 60252e8139..7f7a557b57 100644
--- a/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb
+++ b/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
platform_is :windows do
require 'win32ole'
diff --git a/spec/ruby/library/yaml/dump_spec.rb b/spec/ruby/library/yaml/dump_spec.rb
index ea94b2f856..3107a8f51d 100644
--- a/spec/ruby/library/yaml/dump_spec.rb
+++ b/spec/ruby/library/yaml/dump_spec.rb
@@ -1,21 +1,17 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/common'
-require 'yaml'
-
+# TODO: WTF is this using a global?
describe "YAML.dump" do
- before :each do
- @test_file = tmp("yaml_test_file")
- end
-
after :each do
- rm_r @test_file
+ rm_r $test_file
end
it "converts an object to YAML and write result to io when io provided" do
- File.open(@test_file, 'w' ) do |io|
+ File.open($test_file, 'w' ) do |io|
YAML.dump( ['badger', 'elephant', 'tiger'], io )
end
- YAML.load_file(@test_file).should == ['badger', 'elephant', 'tiger']
+ YAML.load_file($test_file).should == ['badger', 'elephant', 'tiger']
end
it "returns a string containing dumped YAML when no io provided" do
diff --git a/spec/ruby/library/yaml/dump_stream_spec.rb b/spec/ruby/library/yaml/dump_stream_spec.rb
index f0578fa800..9d30fef819 100644
--- a/spec/ruby/library/yaml/dump_stream_spec.rb
+++ b/spec/ruby/library/yaml/dump_stream_spec.rb
@@ -1,6 +1,5 @@
require_relative '../../spec_helper'
-
-require 'yaml'
+require_relative 'fixtures/common'
describe "YAML.dump_stream" do
it "returns a YAML stream containing the objects passed" do
diff --git a/spec/ruby/library/yaml/fixtures/common.rb b/spec/ruby/library/yaml/fixtures/common.rb
new file mode 100644
index 0000000000..f7fb4037e7
--- /dev/null
+++ b/spec/ruby/library/yaml/fixtures/common.rb
@@ -0,0 +1,4 @@
+require 'yaml'
+
+$test_file = tmp("yaml_test_file")
+$test_parse_file = File.dirname(__FILE__) + "/test_yaml.yml"
diff --git a/spec/ruby/library/yaml/load_file_spec.rb b/spec/ruby/library/yaml/load_file_spec.rb
index 4941d0485b..2363c08120 100644
--- a/spec/ruby/library/yaml/load_file_spec.rb
+++ b/spec/ruby/library/yaml/load_file_spec.rb
@@ -1,18 +1,13 @@
require_relative '../../spec_helper'
-
-require 'yaml'
+require_relative 'fixtures/common'
describe "YAML.load_file" do
- before :each do
- @test_file = tmp("yaml_test_file")
- end
-
after :each do
- rm_r @test_file
+ rm_r $test_file
end
it "returns a hash" do
- File.open(@test_file,'w' ){|io| YAML.dump( {"bar"=>2, "car"=>1}, io ) }
- YAML.load_file(@test_file).should == {"bar"=>2, "car"=>1}
+ File.open($test_file,'w' ){|io| YAML.dump( {"bar"=>2, "car"=>1}, io ) }
+ YAML.load_file($test_file).should == {"bar"=>2, "car"=>1}
end
end
diff --git a/spec/ruby/library/yaml/load_stream_spec.rb b/spec/ruby/library/yaml/load_stream_spec.rb
index 31bc862f5e..689653c8cd 100644
--- a/spec/ruby/library/yaml/load_stream_spec.rb
+++ b/spec/ruby/library/yaml/load_stream_spec.rb
@@ -1,9 +1,8 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/common'
require_relative 'fixtures/strings'
require_relative 'shared/each_document'
-require 'yaml'
-
describe "YAML.load_stream" do
it_behaves_like :yaml_each_document, :load_stream
end
diff --git a/spec/ruby/library/yaml/parse_file_spec.rb b/spec/ruby/library/yaml/parse_file_spec.rb
index 7bffcdc62f..8c59a2d7ef 100644
--- a/spec/ruby/library/yaml/parse_file_spec.rb
+++ b/spec/ruby/library/yaml/parse_file_spec.rb
@@ -1,10 +1,8 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/common'
-require 'yaml'
-
-describe "YAML.parse_file" do
+describe "YAML#parse_file" do
it "returns a YAML::Syck::Map object after parsing a YAML file" do
- test_parse_file = fixture __FILE__, "test_yaml.yml"
- YAML.parse_file(test_parse_file).should be_kind_of(Psych::Nodes::Document)
+ YAML.parse_file($test_parse_file).should be_kind_of(Psych::Nodes::Document)
end
end
diff --git a/spec/ruby/library/yaml/parse_spec.rb b/spec/ruby/library/yaml/parse_spec.rb
index 37e2b7fa0a..d5dbfdcee2 100644
--- a/spec/ruby/library/yaml/parse_spec.rb
+++ b/spec/ruby/library/yaml/parse_spec.rb
@@ -1,14 +1,13 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/common'
-require 'yaml'
-
-describe "YAML.parse with an empty string" do
+describe "YAML#parse with an empty string" do
it "returns false" do
YAML.parse('').should be_false
end
end
-describe "YAML.parse" do
+describe "YAML#parse" do
before :each do
@string_yaml = "foo".to_yaml
end
diff --git a/spec/ruby/library/yaml/shared/each_document.rb b/spec/ruby/library/yaml/shared/each_document.rb
index 7d32c6001f..999123dc2a 100644
--- a/spec/ruby/library/yaml/shared/each_document.rb
+++ b/spec/ruby/library/yaml/shared/each_document.rb
@@ -9,8 +9,7 @@ describe :yaml_each_document, shared: true do
end
it "works on files" do
- test_parse_file = fixture __FILE__, "test_yaml.yml"
- File.open(test_parse_file, "r") do |file|
+ File.open($test_parse_file, "r") do |file|
YAML.send(@method, file) do |doc|
doc.should == {"project"=>{"name"=>"RubySpec"}}
end
diff --git a/spec/ruby/library/yaml/shared/load.rb b/spec/ruby/library/yaml/shared/load.rb
index 1ebe08be2c..185a5a60cd 100644
--- a/spec/ruby/library/yaml/shared/load.rb
+++ b/spec/ruby/library/yaml/shared/load.rb
@@ -1,16 +1,14 @@
+require_relative '../fixtures/common'
require_relative '../fixtures/strings'
-require 'yaml'
-
describe :yaml_load_safe, shared: true do
it "returns a document from current io stream when io provided" do
- @test_file = tmp("yaml_test_file")
- File.open(@test_file, 'w') do |io|
+ File.open($test_file, 'w') do |io|
YAML.dump( ['badger', 'elephant', 'tiger'], io )
end
- File.open(@test_file) { |yf| YAML.send(@method, yf ) }.should == ['badger', 'elephant', 'tiger']
+ File.open($test_file) { |yf| YAML.send(@method, yf ) }.should == ['badger', 'elephant', 'tiger']
ensure
- rm_r @test_file
+ rm_r $test_file
end
it "loads strings" do
diff --git a/spec/ruby/library/yaml/to_yaml_spec.rb b/spec/ruby/library/yaml/to_yaml_spec.rb
index 547009c942..8e80b02cb4 100644
--- a/spec/ruby/library/yaml/to_yaml_spec.rb
+++ b/spec/ruby/library/yaml/to_yaml_spec.rb
@@ -1,8 +1,7 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/common'
require_relative 'fixtures/example_class'
-require 'yaml'
-
describe "Object#to_yaml" do
it "returns the YAML representation of an Array object" do
@@ -13,21 +12,13 @@ describe "Object#to_yaml" do
{ "a" => "b"}.to_yaml.should match_yaml("--- \na: b\n")
end
- it "returns the YAML representation of an object" do
- YAMLSpecs::Example.new("baz").to_yaml.should match_yaml("--- !ruby/object:YAMLSpecs::Example\nname: baz\n")
- end
-
it "returns the YAML representation of a Class object" do
- YAMLSpecs::Example.to_yaml.should match_yaml("--- !ruby/class 'YAMLSpecs::Example'\n")
- end
-
- it "returns the YAML representation of a Module object" do
- Enumerable.to_yaml.should match_yaml("--- !ruby/module 'Enumerable'\n")
+ YAMLSpecs::Example.new("baz").to_yaml.should match_yaml("--- !ruby/object:YAMLSpecs::Example\nname: baz\n")
end
it "returns the YAML representation of a Date object" do
require 'date'
- Date.new(1997, 12, 30).to_yaml.should match_yaml("--- 1997-12-30\n")
+ Date.parse('1997/12/30').to_yaml.should match_yaml("--- 1997-12-30\n")
end
it "returns the YAML representation of a FalseClass" do
@@ -67,11 +58,6 @@ describe "Object#to_yaml" do
Person.new("Jane", "female").to_yaml.should match_yaml("--- !ruby/struct:Person\nname: Jane\ngender: female\n")
end
- it "returns the YAML representation of an unnamed Struct object" do
- person = Struct.new(:name, :gender)
- person.new("Jane", "female").to_yaml.should match_yaml("--- !ruby/struct\nname: Jane\ngender: female\n")
- end
-
it "returns the YAML representation of a Symbol object" do
:symbol.to_yaml.should match_yaml("--- :symbol\n")
end
diff --git a/spec/ruby/library/zlib/deflate/new_spec.rb b/spec/ruby/library/zlib/deflate/new_spec.rb
new file mode 100644
index 0000000000..e15f14f95f
--- /dev/null
+++ b/spec/ruby/library/zlib/deflate/new_spec.rb
@@ -0,0 +1 @@
+require_relative '../../../spec_helper'
diff --git a/spec/ruby/library/zlib/gzipreader/each_line_spec.rb b/spec/ruby/library/zlib/gzipreader/each_line_spec.rb
index 6f17365879..efaf27d6bb 100644
--- a/spec/ruby/library/zlib/gzipreader/each_line_spec.rb
+++ b/spec/ruby/library/zlib/gzipreader/each_line_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/each'
describe "Zlib::GzipReader#each_line" do
diff --git a/spec/ruby/library/zlib/gzipreader/each_spec.rb b/spec/ruby/library/zlib/gzipreader/each_spec.rb
index 3b98391a87..59aa63e52c 100644
--- a/spec/ruby/library/zlib/gzipreader/each_spec.rb
+++ b/spec/ruby/library/zlib/gzipreader/each_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require_relative 'shared/each'
describe "Zlib::GzipReader#each" do
diff --git a/spec/ruby/library/zlib/gzipreader/mtime_spec.rb b/spec/ruby/library/zlib/gzipreader/mtime_spec.rb
deleted file mode 100644
index e8e71fa72e..0000000000
--- a/spec/ruby/library/zlib/gzipreader/mtime_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require_relative '../../../spec_helper'
-require 'zlib'
-require 'stringio'
-
-describe "Zlib::GzipReader#mtime" do
- it "returns the timestamp from the Gzip header" do
- io = StringIO.new "\x1f\x8b\x08\x00\x44\x33\x22\x11\x00\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- gz = Zlib::GzipReader.new(io)
- gz.mtime.to_i.should == 0x11223344
- end
-end
diff --git a/spec/ruby/library/zlib/gzipreader/new_spec.rb b/spec/ruby/library/zlib/gzipreader/new_spec.rb
new file mode 100644
index 0000000000..e15f14f95f
--- /dev/null
+++ b/spec/ruby/library/zlib/gzipreader/new_spec.rb
@@ -0,0 +1 @@
+require_relative '../../../spec_helper'
diff --git a/spec/ruby/library/zlib/inflate/finish_spec.rb b/spec/ruby/library/zlib/inflate/finish_spec.rb
index 3e0663e265..f6e592fb6b 100644
--- a/spec/ruby/library/zlib/inflate/finish_spec.rb
+++ b/spec/ruby/library/zlib/inflate/finish_spec.rb
@@ -1,4 +1,3 @@
-require_relative "../../../spec_helper"
require 'zlib'
describe "Zlib::Inflate#finish" do
diff --git a/spec/ruby/library/zlib/inflate/new_spec.rb b/spec/ruby/library/zlib/inflate/new_spec.rb
new file mode 100644
index 0000000000..e15f14f95f
--- /dev/null
+++ b/spec/ruby/library/zlib/inflate/new_spec.rb
@@ -0,0 +1 @@
+require_relative '../../../spec_helper'
diff --git a/spec/ruby/optional/capi/array_spec.rb b/spec/ruby/optional/capi/array_spec.rb
index 9c35017e21..8e90980c6a 100644
--- a/spec/ruby/optional/capi/array_spec.rb
+++ b/spec/ruby/optional/capi/array_spec.rb
@@ -343,40 +343,6 @@ describe "C-API Array function" do
end
end
- describe "rb_iterate" do
- it "calls an callback function as a block passed to an method" do
- s = [1,2,3,4]
- s2 = @s.rb_iterate(s)
-
- s2.should == s
-
- # Make sure they're different objects
- s2.equal?(s).should be_false
- end
-
- it "calls a function with the other function available as a block" do
- h = {a: 1, b: 2}
-
- @s.rb_iterate_each_pair(h).sort.should == [1,2]
- end
-
- it "calls a function which can yield into the original block" do
- s2 = []
-
- o = Object.new
- def o.each
- yield 1
- yield 2
- yield 3
- yield 4
- end
-
- @s.rb_iterate_then_yield(o) { |x| s2 << x }
-
- s2.should == [1,2,3,4]
- end
- end
-
describe "rb_block_call" do
it "calls an callback function as a block passed to an method" do
s = [1,2,3,4]
diff --git a/spec/ruby/optional/capi/class_spec.rb b/spec/ruby/optional/capi/class_spec.rb
index d0a9913570..66af381243 100644
--- a/spec/ruby/optional/capi/class_spec.rb
+++ b/spec/ruby/optional/capi/class_spec.rb
@@ -119,21 +119,23 @@ describe "C-API Class function" do
end
end
- describe "rb_class_new_instance_kw" do
- it "passes arguments and keywords to the #initialize method" do
- obj = @s.rb_class_new_instance_kw([{pos: 1}, {kw: 2}], CApiClassSpecs::KeywordAlloc)
- obj.args.should == [{pos: 1}]
- obj.kwargs.should == {kw: 2}
-
- obj = @s.rb_class_new_instance_kw([{}], CApiClassSpecs::KeywordAlloc)
- obj.args.should == []
- obj.kwargs.should == {}
- end
-
- it "raises TypeError if the last argument is not a Hash" do
- -> {
- @s.rb_class_new_instance_kw([42], CApiClassSpecs::KeywordAlloc)
- }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
+ ruby_version_is "3.0" do
+ describe "rb_class_new_instance_kw" do
+ it "passes arguments and keywords to the #initialize method" do
+ obj = @s.rb_class_new_instance_kw([{pos: 1}, {kw: 2}], CApiClassSpecs::KeywordAlloc)
+ obj.args.should == [{pos: 1}]
+ obj.kwargs.should == {kw: 2}
+
+ obj = @s.rb_class_new_instance_kw([{}], CApiClassSpecs::KeywordAlloc)
+ obj.args.should == []
+ obj.kwargs.should == {}
+ end
+
+ it "raises TypeError if the last argument is not a Hash" do
+ -> {
+ @s.rb_class_new_instance_kw([42], CApiClassSpecs::KeywordAlloc)
+ }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
+ end
end
end
diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb
index 36437cc7b6..aa632b963b 100644
--- a/spec/ruby/optional/capi/encoding_spec.rb
+++ b/spec/ruby/optional/capi/encoding_spec.rb
@@ -657,20 +657,6 @@ describe "C-API Encoding function" do
end
end
- describe "rb_enc_raise" do
- it "forces exception message encoding to the specified one" do
- utf_8_incompatible_string = "\x81".b
-
- -> {
- @s.rb_enc_raise(Encoding::UTF_8, RuntimeError, utf_8_incompatible_string)
- }.should raise_error { |e|
- e.message.encoding.should == Encoding::UTF_8
- e.message.valid_encoding?.should == false
- e.message.bytes.should == utf_8_incompatible_string.bytes
- }
- end
- end
-
describe "rb_uv_to_utf8" do
it 'converts a Unicode codepoint to a UTF-8 C string' do
str = ' ' * 6
@@ -688,22 +674,6 @@ describe "C-API Encoding function" do
end
end
- describe "rb_enc_left_char_head" do
- it 'returns the head position of a character' do
- @s.rb_enc_left_char_head("é", 1).should == 0
- @s.rb_enc_left_char_head("éééé", 7).should == 6
-
- @s.rb_enc_left_char_head("a", 0).should == 0
-
- # unclear if this is intended to work
- @s.rb_enc_left_char_head("a", 1).should == 1
-
- # Works because for single-byte encodings rb_enc_left_char_head() just returns the pointer
- @s.rb_enc_left_char_head("a".force_encoding(Encoding::US_ASCII), 88).should == 88
- @s.rb_enc_left_char_head("a".b, 88).should == 88
- end
- end
-
describe "ONIGENC_MBC_CASE_FOLD" do
it "returns the correct case fold for the given string" do
@s.ONIGENC_MBC_CASE_FOLD("lower").should == ["l", 1]
diff --git a/spec/ruby/optional/capi/exception_spec.rb b/spec/ruby/optional/capi/exception_spec.rb
index 5bb60608b2..b0a8a2860e 100644
--- a/spec/ruby/optional/capi/exception_spec.rb
+++ b/spec/ruby/optional/capi/exception_spec.rb
@@ -100,40 +100,6 @@ describe "C-API Exception function" do
end
end
- describe "rb_syserr_new" do
- it "returns system error with default message when passed message is NULL" do
- exception = @s.rb_syserr_new(Errno::ENOENT::Errno, nil)
- exception.class.should == Errno::ENOENT
- exception.message.should include("No such file or directory")
- exception.should.is_a?(SystemCallError)
- end
-
- it "returns system error with custom message" do
- exception = @s.rb_syserr_new(Errno::ENOENT::Errno, "custom message")
-
- exception.message.should include("custom message")
- exception.class.should == Errno::ENOENT
- exception.should.is_a?(SystemCallError)
- end
- end
-
- describe "rb_syserr_new_str" do
- it "returns system error with default message when passed message is nil" do
- exception = @s.rb_syserr_new_str(Errno::ENOENT::Errno, nil)
-
- exception.message.should include("No such file or directory")
- exception.class.should == Errno::ENOENT
- exception.should.is_a?(SystemCallError)
- end
-
- it "returns system error with custom message" do
- exception = @s.rb_syserr_new_str(Errno::ENOENT::Errno, "custom message")
- exception.message.should include("custom message")
- exception.class.should == Errno::ENOENT
- exception.should.is_a?(SystemCallError)
- end
- end
-
describe "rb_make_exception" do
it "returns a RuntimeError when given a String argument" do
e = @s.rb_make_exception(["Message"])
diff --git a/spec/ruby/optional/capi/ext/array_spec.c b/spec/ruby/optional/capi/ext/array_spec.c
index 2347798bb4..9386239813 100644
--- a/spec/ruby/optional/capi/ext/array_spec.c
+++ b/spec/ruby/optional/capi/ext/array_spec.c
@@ -196,14 +196,6 @@ static VALUE copy_ary(RB_BLOCK_CALL_FUNC_ARGLIST(el, new_ary)) {
return rb_ary_push(new_ary, el);
}
-static VALUE array_spec_rb_iterate(VALUE self, VALUE ary) {
- VALUE new_ary = rb_ary_new();
-
- rb_iterate(rb_each, ary, copy_ary, new_ary);
-
- return new_ary;
-}
-
static VALUE array_spec_rb_block_call(VALUE self, VALUE ary) {
VALUE new_ary = rb_ary_new();
@@ -216,18 +208,6 @@ static VALUE sub_pair(RB_BLOCK_CALL_FUNC_ARGLIST(el, holder)) {
return rb_ary_push(holder, rb_ary_entry(el, 1));
}
-static VALUE each_pair(VALUE obj) {
- return rb_funcall(obj, rb_intern("each_pair"), 0);
-}
-
-static VALUE array_spec_rb_iterate_each_pair(VALUE self, VALUE obj) {
- VALUE new_ary = rb_ary_new();
-
- rb_iterate(each_pair, obj, sub_pair, new_ary);
-
- return new_ary;
-}
-
static VALUE array_spec_rb_block_call_each_pair(VALUE self, VALUE obj) {
VALUE new_ary = rb_ary_new();
@@ -241,11 +221,6 @@ static VALUE iter_yield(RB_BLOCK_CALL_FUNC_ARGLIST(el, ary)) {
return Qnil;
}
-static VALUE array_spec_rb_iterate_then_yield(VALUE self, VALUE obj) {
- rb_iterate(rb_each, obj, iter_yield, obj);
- return Qnil;
-}
-
static VALUE array_spec_rb_block_call_then_yield(VALUE self, VALUE obj) {
rb_block_call(obj, rb_intern("each"), 0, 0, iter_yield, obj);
return Qnil;
@@ -308,9 +283,6 @@ void Init_array_spec(void) {
rb_define_method(cls, "rb_ary_plus", array_spec_rb_ary_plus, 2);
rb_define_method(cls, "rb_ary_unshift", array_spec_rb_ary_unshift, 2);
rb_define_method(cls, "rb_assoc_new", array_spec_rb_assoc_new, 2);
- rb_define_method(cls, "rb_iterate", array_spec_rb_iterate, 1);
- rb_define_method(cls, "rb_iterate_each_pair", array_spec_rb_iterate_each_pair, 1);
- rb_define_method(cls, "rb_iterate_then_yield", array_spec_rb_iterate_then_yield, 1);
rb_define_method(cls, "rb_block_call", array_spec_rb_block_call, 1);
rb_define_method(cls, "rb_block_call_each_pair", array_spec_rb_block_call_each_pair, 1);
rb_define_method(cls, "rb_block_call_then_yield", array_spec_rb_block_call_then_yield, 1);
diff --git a/spec/ruby/optional/capi/ext/class_spec.c b/spec/ruby/optional/capi/ext/class_spec.c
index f376534924..589025f677 100644
--- a/spec/ruby/optional/capi/ext/class_spec.c
+++ b/spec/ruby/optional/capi/ext/class_spec.c
@@ -72,7 +72,7 @@ static VALUE class_spec_rb_class_new_instance_kw(VALUE self, VALUE args, VALUE k
#endif
static VALUE class_spec_rb_class_real(VALUE self, VALUE object) {
- if (rb_type_p(object, T_FIXNUM)) {
+ if(rb_type_p(object, T_FIXNUM)) {
return INT2FIX(rb_class_real(FIX2INT(object)));
} else {
return rb_class_real(CLASS_OF(object));
@@ -116,19 +116,19 @@ VALUE class_spec_define_attr(VALUE self, VALUE klass, VALUE sym, VALUE read, VAL
}
static VALUE class_spec_rb_define_class(VALUE self, VALUE name, VALUE super) {
- if (NIL_P(super)) super = 0;
+ if(NIL_P(super)) super = 0;
return rb_define_class(RSTRING_PTR(name), super);
}
static VALUE class_spec_rb_define_class_under(VALUE self, VALUE outer,
VALUE name, VALUE super) {
- if (NIL_P(super)) super = 0;
+ if(NIL_P(super)) super = 0;
return rb_define_class_under(outer, RSTRING_PTR(name), super);
}
static VALUE class_spec_rb_define_class_id_under(VALUE self, VALUE outer,
VALUE name, VALUE super) {
- if (NIL_P(super)) super = 0;
+ if(NIL_P(super)) super = 0;
return rb_define_class_id_under(outer, SYM2ID(name), super);
}
diff --git a/spec/ruby/optional/capi/ext/debug_spec.c b/spec/ruby/optional/capi/ext/debug_spec.c
index 9131eda78b..344dfc33fa 100644
--- a/spec/ruby/optional/capi/ext/debug_spec.c
+++ b/spec/ruby/optional/capi/ext/debug_spec.c
@@ -45,7 +45,7 @@ static VALUE rb_debug_inspector_frame_iseq_get_callback(const rb_debug_inspector
return rb_debug_inspector_frame_iseq_get(dc, NUM2LONG((VALUE) ptr));
}
-static VALUE debug_spec_callback_data(VALUE self) {
+static VALUE debug_spec_callback_data(VALUE self){
return callback_data;
}
diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c
index 3343848b54..a0136530f2 100644
--- a/spec/ruby/optional/capi/ext/encoding_spec.c
+++ b/spec/ruby/optional/capi/ext/encoding_spec.c
@@ -12,7 +12,7 @@ static VALUE encoding_spec_MBCLEN_CHARFOUND_P(VALUE self, VALUE obj) {
}
static VALUE encoding_spec_ENC_CODERANGE_ASCIIONLY(VALUE self, VALUE obj) {
- if (ENC_CODERANGE_ASCIIONLY(obj)) {
+ if(ENC_CODERANGE_ASCIIONLY(obj)) {
return Qtrue;
} else {
return Qfalse;
@@ -61,13 +61,13 @@ static VALUE encoding_spec_rb_filesystem_encindex(VALUE self) {
static VALUE encoding_spec_rb_default_internal_encoding(VALUE self) {
rb_encoding* enc = rb_default_internal_encoding();
- if (enc == 0) return Qnil;
+ if(enc == 0) return Qnil;
return rb_str_new2(enc->name);
}
static VALUE encoding_spec_rb_default_external_encoding(VALUE self) {
rb_encoding* enc = rb_default_external_encoding();
- if (enc == 0) return Qnil;
+ if(enc == 0) return Qnil;
return rb_str_new2(enc->name);
}
@@ -86,7 +86,7 @@ static VALUE encoding_spec_rb_enc_associate_index(VALUE self, VALUE obj, VALUE i
static VALUE encoding_spec_rb_enc_compatible(VALUE self, VALUE a, VALUE b) {
rb_encoding* enc = rb_enc_compatible(a, b);
- if (!enc) return INT2FIX(0);
+ if(!enc) return INT2FIX(0);
return rb_enc_from_encoding(enc);
}
@@ -271,13 +271,6 @@ static VALUE encoding_spec_rb_enc_str_asciionly_p(VALUE self, VALUE str) {
}
}
-static VALUE encoding_spec_rb_enc_raise(VALUE self, VALUE encoding, VALUE exception_class, VALUE format) {
- rb_encoding *e = rb_to_encoding(encoding);
- const char *f = RSTRING_PTR(format);
-
- rb_enc_raise(e, exception_class, "%s", f);
-}
-
static VALUE encoding_spec_rb_uv_to_utf8(VALUE self, VALUE buf, VALUE num) {
int len = rb_uv_to_utf8(RSTRING_PTR(buf), NUM2INT(num));
RB_ENC_CODERANGE_CLEAR(buf);
@@ -314,12 +307,6 @@ static VALUE encoding_spec_rb_enc_strlen(VALUE self, VALUE str, VALUE length, VA
return LONG2FIX(rb_enc_strlen(p, e, rb_to_encoding(encoding)));
}
-static VALUE encoding_spec_rb_enc_left_char_head(VALUE self, VALUE str, VALUE offset) {
- char *ptr = RSTRING_PTR(str);
- char *result = rb_enc_left_char_head(ptr, ptr + NUM2INT(offset), RSTRING_END(str), rb_enc_get(str));
- return LONG2NUM(result - ptr);
-}
-
void Init_encoding_spec(void) {
VALUE cls;
native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*));
@@ -375,10 +362,8 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_enc_nth", encoding_spec_rb_enc_nth, 2);
rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1);
rb_define_method(cls, "rb_enc_str_asciionly_p", encoding_spec_rb_enc_str_asciionly_p, 1);
- rb_define_method(cls, "rb_enc_raise", encoding_spec_rb_enc_raise, 3);
rb_define_method(cls, "rb_uv_to_utf8", encoding_spec_rb_uv_to_utf8, 2);
rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1);
- rb_define_method(cls, "rb_enc_left_char_head", encoding_spec_rb_enc_left_char_head, 2);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/exception_spec.c b/spec/ruby/optional/capi/ext/exception_spec.c
index 0e8347ab0d..e1114aabb8 100644
--- a/spec/ruby/optional/capi/ext/exception_spec.c
+++ b/spec/ruby/optional/capi/ext/exception_spec.c
@@ -27,7 +27,7 @@ VALUE exception_spec_rb_exc_new3(VALUE self, VALUE str) {
}
VALUE exception_spec_rb_exc_raise(VALUE self, VALUE exc) {
- if (self != Qundef) rb_exc_raise(exc);
+ if (self != Qundef) rb_exc_raise(exc);
return Qnil;
}
@@ -36,21 +36,6 @@ VALUE exception_spec_rb_set_errinfo(VALUE self, VALUE exc) {
return Qnil;
}
-VALUE exception_spec_rb_syserr_new(VALUE self, VALUE num, VALUE msg) {
- int n = NUM2INT(num);
- char *cstr = NULL;
-
- if (msg != Qnil) {
- cstr = StringValuePtr(msg);
- }
-
- return rb_syserr_new(n, cstr);
-}
-
-VALUE exception_spec_rb_syserr_new_str(VALUE self, VALUE num, VALUE msg) {
- int n = NUM2INT(num);
- return rb_syserr_new_str(n, msg);
-}
VALUE exception_spec_rb_make_exception(VALUE self, VALUE ary) {
int argc = RARRAY_LENINT(ary);
@@ -66,8 +51,6 @@ void Init_exception_spec(void) {
rb_define_method(cls, "rb_exc_new3", exception_spec_rb_exc_new3, 1);
rb_define_method(cls, "rb_exc_raise", exception_spec_rb_exc_raise, 1);
rb_define_method(cls, "rb_set_errinfo", exception_spec_rb_set_errinfo, 1);
- rb_define_method(cls, "rb_syserr_new", exception_spec_rb_syserr_new, 2);
- rb_define_method(cls, "rb_syserr_new_str", exception_spec_rb_syserr_new_str, 2);
rb_define_method(cls, "rb_make_exception", exception_spec_rb_make_exception, 1);
}
diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c
index 7dd0b87655..b323c2456d 100644
--- a/spec/ruby/optional/capi/ext/gc_spec.c
+++ b/spec/ruby/optional/capi/ext/gc_spec.c
@@ -51,7 +51,7 @@ static VALUE gc_spec_rb_gc(VALUE self) {
return Qnil;
}
-static VALUE gc_spec_rb_gc_latest_gc_info(VALUE self, VALUE hash_or_key) {
+static VALUE gc_spec_rb_gc_latest_gc_info(VALUE self, VALUE hash_or_key){
return rb_gc_latest_gc_info(hash_or_key);
}
diff --git a/spec/ruby/optional/capi/ext/hash_spec.c b/spec/ruby/optional/capi/ext/hash_spec.c
index 69ef02d5da..7f38708915 100644
--- a/spec/ruby/optional/capi/ext/hash_spec.c
+++ b/spec/ruby/optional/capi/ext/hash_spec.c
@@ -105,12 +105,6 @@ VALUE hash_spec_rb_hash_new(VALUE self) {
return rb_hash_new();
}
-#ifdef RUBY_VERSION_IS_3_2
-VALUE hash_spec_rb_hash_new_capa(VALUE self, VALUE capacity) {
- return rb_hash_new_capa(NUM2LONG(capacity));
-}
-#endif
-
VALUE rb_ident_hash_new(void); /* internal.h, used in ripper */
VALUE hash_spec_rb_ident_hash_new(VALUE self) {
@@ -155,9 +149,6 @@ void Init_hash_spec(void) {
rb_define_method(cls, "rb_hash_lookup2", hash_spec_rb_hash_lookup2, 3);
rb_define_method(cls, "rb_hash_lookup2_default_undef", hash_spec_rb_hash_lookup2_default_undef, 2);
rb_define_method(cls, "rb_hash_new", hash_spec_rb_hash_new, 0);
-#ifdef RUBY_VERSION_IS_3_2
- rb_define_method(cls, "rb_hash_new_capa", hash_spec_rb_hash_new_capa, 1);
-#endif
rb_define_method(cls, "rb_ident_hash_new", hash_spec_rb_ident_hash_new, 0);
rb_define_method(cls, "rb_hash_size", hash_spec_rb_hash_size, 1);
rb_define_method(cls, "rb_hash_set_ifnone", hash_spec_rb_hash_set_ifnone, 2);
diff --git a/spec/ruby/optional/capi/ext/integer_spec.c b/spec/ruby/optional/capi/ext/integer_spec.c
index 792fc0652a..16cd95f111 100644
--- a/spec/ruby/optional/capi/ext/integer_spec.c
+++ b/spec/ruby/optional/capi/ext/integer_spec.c
@@ -6,7 +6,8 @@ extern "C" {
#endif
static VALUE integer_spec_rb_integer_pack(VALUE self, VALUE value,
- VALUE words, VALUE numwords, VALUE wordsize, VALUE nails, VALUE flags) {
+ VALUE words, VALUE numwords, VALUE wordsize, VALUE nails, VALUE flags)
+{
int result = rb_integer_pack(value, (void*)RSTRING_PTR(words), FIX2INT(numwords),
FIX2INT(wordsize), FIX2INT(nails), FIX2INT(flags));
return INT2FIX(result);
@@ -14,7 +15,7 @@ static VALUE integer_spec_rb_integer_pack(VALUE self, VALUE value,
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y); /* internal.h, used in ripper */
-static VALUE integer_spec_rb_int_positive_pow(VALUE self, VALUE a, VALUE b) {
+static VALUE integer_spec_rb_int_positive_pow(VALUE self, VALUE a, VALUE b){
return rb_int_positive_pow(FIX2INT(a), FIX2INT(b));
}
diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c
index ab3aef4c92..f257cef554 100644
--- a/spec/ruby/optional/capi/ext/io_spec.c
+++ b/spec/ruby/optional/capi/ext/io_spec.c
@@ -28,13 +28,9 @@ static int set_non_blocking(int fd) {
}
static int io_spec_get_fd(VALUE io) {
-#ifdef RUBY_VERSION_IS_3_1
- return rb_io_descriptor(io);
-#else
rb_io_t* fp;
GetOpenFile(io, fp);
return fp->fd;
-#endif
}
VALUE io_spec_GetOpenFile_fd(VALUE self, VALUE io) {
@@ -134,7 +130,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
rb_sys_fail("set_non_blocking failed");
#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
- if (RTEST(read_p)) {
+ if(RTEST(read_p)) {
if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) {
return Qnil;
}
@@ -145,7 +141,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
ret = rb_io_wait_readable(fd);
- if (RTEST(read_p)) {
+ if(RTEST(read_p)) {
ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF);
if (r != RB_IO_WAIT_READABLE_BUF) {
perror("read");
@@ -166,60 +162,6 @@ VALUE io_spec_rb_io_wait_writable(VALUE self, VALUE io) {
return ret ? Qtrue : Qfalse;
}
-#ifdef RUBY_VERSION_IS_3_1
-VALUE io_spec_rb_io_maybe_wait_writable(VALUE self, VALUE error, VALUE io, VALUE timeout) {
- int ret = rb_io_maybe_wait_writable(NUM2INT(error), io, timeout);
- return INT2NUM(ret);
-}
-#endif
-
-#ifdef RUBY_VERSION_IS_3_1
-VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p) {
- int fd = io_spec_get_fd(io);
-#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
- char buf[RB_IO_WAIT_READABLE_BUF];
- int ret, saved_errno;
-#endif
-
- if (set_non_blocking(fd) == -1)
- rb_sys_fail("set_non_blocking failed");
-
-#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
- if (RTEST(read_p)) {
- if (read(fd, buf, RB_IO_WAIT_READABLE_BUF) != -1) {
- return Qnil;
- }
- saved_errno = errno;
- rb_ivar_set(self, rb_intern("@write_data"), Qtrue);
- errno = saved_errno;
- }
-
- // main part
- ret = rb_io_maybe_wait_readable(NUM2INT(error), io, timeout);
-
- if (RTEST(read_p)) {
- ssize_t r = read(fd, buf, RB_IO_WAIT_READABLE_BUF);
- if (r != RB_IO_WAIT_READABLE_BUF) {
- perror("read");
- return SSIZET2NUM(r);
- }
- rb_ivar_set(self, rb_intern("@read_data"),
- rb_str_new(buf, RB_IO_WAIT_READABLE_BUF));
- }
-
- return INT2NUM(ret);
-#else
- UNREACHABLE;
-#endif
-}
-#endif
-
-#ifdef RUBY_VERSION_IS_3_1
-VALUE io_spec_rb_io_maybe_wait(VALUE self, VALUE error, VALUE io, VALUE events, VALUE timeout) {
- return rb_io_maybe_wait(NUM2INT(error), io, events, timeout);
-}
-#endif
-
VALUE io_spec_rb_thread_wait_fd(VALUE self, VALUE io) {
rb_thread_wait_fd(io_spec_get_fd(io));
return Qnil;
@@ -307,7 +249,7 @@ VALUE io_spec_rb_io_set_nonblock(VALUE self, VALUE io) {
GetOpenFile(io, fp);
rb_io_set_nonblock(fp);
#ifdef F_GETFL
- flags = fcntl(io_spec_get_fd(io), F_GETFL, 0);
+ flags = fcntl(fp->fd, F_GETFL, 0);
return flags & O_NONBLOCK ? Qtrue : Qfalse;
#else
return Qfalse;
@@ -326,13 +268,9 @@ static VALUE io_spec_errno_set(VALUE self, VALUE val) {
}
VALUE io_spec_mode_sync_flag(VALUE self, VALUE io) {
-#ifdef RUBY_VERSION_IS_3_3
- if (rb_io_mode(io) & FMODE_SYNC) {
-#else
rb_io_t *fp;
GetOpenFile(io, fp);
if (fp->mode & FMODE_SYNC) {
-#endif
return Qtrue;
} else {
return Qfalse;
@@ -356,11 +294,6 @@ void Init_io_spec(void) {
rb_define_method(cls, "rb_io_taint_check", io_spec_rb_io_taint_check, 1);
rb_define_method(cls, "rb_io_wait_readable", io_spec_rb_io_wait_readable, 2);
rb_define_method(cls, "rb_io_wait_writable", io_spec_rb_io_wait_writable, 1);
-#ifdef RUBY_VERSION_IS_3_1
- rb_define_method(cls, "rb_io_maybe_wait_writable", io_spec_rb_io_maybe_wait_writable, 3);
- rb_define_method(cls, "rb_io_maybe_wait_readable", io_spec_rb_io_maybe_wait_readable, 4);
- rb_define_method(cls, "rb_io_maybe_wait", io_spec_rb_io_maybe_wait, 4);
-#endif
rb_define_method(cls, "rb_thread_wait_fd", io_spec_rb_thread_wait_fd, 1);
rb_define_method(cls, "rb_thread_fd_writable", io_spec_rb_thread_fd_writable, 1);
rb_define_method(cls, "rb_thread_fd_select_read", io_spec_rb_thread_fd_select_read, 1);
diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c
index a921eb13e0..e194ba8fde 100644
--- a/spec/ruby/optional/capi/ext/kernel_spec.c
+++ b/spec/ruby/optional/capi/ext/kernel_spec.c
@@ -220,7 +220,7 @@ static VALUE kernel_spec_rb_eval_string_protect(VALUE self, VALUE str, VALUE ary
VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
errno = 1;
- if (msg == Qnil) {
+ if(msg == Qnil) {
rb_sys_fail(0);
} else if (self != Qundef) {
rb_sys_fail(StringValuePtr(msg));
@@ -229,7 +229,7 @@ VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
}
VALUE kernel_spec_rb_syserr_fail(VALUE self, VALUE err, VALUE msg) {
- if (msg == Qnil) {
+ if(msg == Qnil) {
rb_syserr_fail(NUM2INT(err), NULL);
} else if (self != Qundef) {
rb_syserr_fail(NUM2INT(err), StringValuePtr(msg));
@@ -292,9 +292,9 @@ static VALUE kernel_spec_rb_yield_values2(VALUE self, VALUE ary) {
}
static VALUE do_rec(VALUE obj, VALUE arg, int is_rec) {
- if (is_rec) {
+ if(is_rec) {
return obj;
- } else if (arg == Qtrue) {
+ } else if(arg == Qtrue) {
return rb_exec_recursive(do_rec, obj, Qnil);
} else {
return Qnil;
@@ -340,12 +340,8 @@ static VALUE kernel_spec_rb_funcallv_public(VALUE self, VALUE obj, VALUE method)
return rb_funcallv_public(obj, SYM2ID(method), 0, NULL);
}
-static VALUE kernel_spec_rb_funcall_with_block(VALUE self, VALUE obj, VALUE method, VALUE args, VALUE block) {
- return rb_funcall_with_block(obj, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args), block);
-}
-
-static VALUE kernel_spec_rb_funcall_with_block_kw(VALUE self, VALUE obj, VALUE method, VALUE args, VALUE block) {
- return rb_funcall_with_block_kw(obj, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args), block, RB_PASS_KEYWORDS);
+static VALUE kernel_spec_rb_funcall_with_block(VALUE self, VALUE obj, VALUE method, VALUE block) {
+ return rb_funcall_with_block(obj, SYM2ID(method), 0, NULL, block);
}
static VALUE kernel_spec_rb_funcall_many_args(VALUE self, VALUE obj, VALUE method) {
@@ -401,8 +397,7 @@ void Init_kernel_spec(void) {
#endif
rb_define_method(cls, "rb_funcallv_public", kernel_spec_rb_funcallv_public, 2);
rb_define_method(cls, "rb_funcall_many_args", kernel_spec_rb_funcall_many_args, 2);
- rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 4);
- rb_define_method(cls, "rb_funcall_with_block_kw", kernel_spec_rb_funcall_with_block_kw, 4);
+ rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 3);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c
index 7023c29bdb..30ac44cf1f 100644
--- a/spec/ruby/optional/capi/ext/object_spec.c
+++ b/spec/ruby/optional/capi/ext/object_spec.c
@@ -154,12 +154,30 @@ static VALUE object_specs_rb_obj_method(VALUE self, VALUE obj, VALUE method) {
return rb_obj_method(obj, method);
}
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wdeprecated-declarations")
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+# endif
+#endif
+
#ifndef RUBY_VERSION_IS_3_2
static VALUE object_spec_rb_obj_taint(VALUE self, VALUE obj) {
return rb_obj_taint(obj);
}
#endif
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic pop
+#elif defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wdeprecated-declarations")
+# pragma clang diagnostic pop
+# endif
+#endif
+
static VALUE so_require(VALUE self) {
rb_require("fixtures/foo");
return Qnil;
@@ -200,126 +218,126 @@ static VALUE so_check_type(VALUE self, VALUE obj, VALUE other) {
}
static VALUE so_is_type_nil(VALUE self, VALUE obj) {
- if (TYPE(obj) == T_NIL) {
+ if(TYPE(obj) == T_NIL) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_object(VALUE self, VALUE obj) {
- if (TYPE(obj) == T_OBJECT) {
+ if(TYPE(obj) == T_OBJECT) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_array(VALUE self, VALUE obj) {
- if (TYPE(obj) == T_ARRAY) {
+ if(TYPE(obj) == T_ARRAY) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_module(VALUE self, VALUE obj) {
- if (TYPE(obj) == T_MODULE) {
+ if(TYPE(obj) == T_MODULE) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_class(VALUE self, VALUE obj) {
- if (TYPE(obj) == T_CLASS) {
+ if(TYPE(obj) == T_CLASS) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_type_data(VALUE self, VALUE obj) {
- if (TYPE(obj) == T_DATA) {
+ if(TYPE(obj) == T_DATA) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_nil(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_NIL)) {
+ if(rb_type_p(obj, T_NIL)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_object(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_OBJECT)) {
+ if(rb_type_p(obj, T_OBJECT)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_array(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_ARRAY)) {
+ if(rb_type_p(obj, T_ARRAY)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_module(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_MODULE)) {
+ if(rb_type_p(obj, T_MODULE)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_class(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_CLASS)) {
+ if(rb_type_p(obj, T_CLASS)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_data(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_DATA)) {
+ if(rb_type_p(obj, T_DATA)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_rb_type_p_file(VALUE self, VALUE obj) {
- if (rb_type_p(obj, T_FILE)) {
+ if(rb_type_p(obj, T_FILE)) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_object(VALUE self, VALUE obj) {
- if (BUILTIN_TYPE(obj) == T_OBJECT) {
+ if(BUILTIN_TYPE(obj) == T_OBJECT) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_array(VALUE self, VALUE obj) {
- if (BUILTIN_TYPE(obj) == T_ARRAY) {
+ if(BUILTIN_TYPE(obj) == T_ARRAY) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_module(VALUE self, VALUE obj) {
- if (BUILTIN_TYPE(obj) == T_MODULE) {
+ if(BUILTIN_TYPE(obj) == T_MODULE) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_class(VALUE self, VALUE obj) {
- if (BUILTIN_TYPE(obj) == T_CLASS) {
+ if(BUILTIN_TYPE(obj) == T_CLASS) {
return Qtrue;
}
return Qfalse;
}
static VALUE so_is_builtin_type_data(VALUE self, VALUE obj) {
- if (BUILTIN_TYPE(obj) == T_DATA) {
+ if(BUILTIN_TYPE(obj) == T_DATA) {
return Qtrue;
}
return Qfalse;
diff --git a/spec/ruby/optional/capi/ext/proc_spec.c b/spec/ruby/optional/capi/ext/proc_spec.c
index b7cd5d6262..1137f4156b 100644
--- a/spec/ruby/optional/capi/ext/proc_spec.c
+++ b/spec/ruby/optional/capi/ext/proc_spec.c
@@ -76,18 +76,6 @@ VALUE proc_spec_rb_proc_call(VALUE self, VALUE prc, VALUE args) {
return rb_proc_call(prc, args);
}
-VALUE proc_spec_rb_proc_call_kw(VALUE self, VALUE prc, VALUE args) {
- return rb_proc_call_kw(prc, args, RB_PASS_KEYWORDS);
-}
-
-VALUE proc_spec_rb_proc_call_with_block(VALUE self, VALUE prc, VALUE args, VALUE block) {
- return rb_proc_call_with_block(prc, RARRAY_LENINT(args), RARRAY_PTR(args), block);
-}
-
-static VALUE proc_spec_rb_proc_call_with_block_kw(VALUE self, VALUE prc, VALUE args, VALUE block) {
- return rb_proc_call_with_block_kw(prc, RARRAY_LENINT(args), RARRAY_PTR(args), block, RB_PASS_KEYWORDS);
-}
-
VALUE proc_spec_rb_obj_is_proc(VALUE self, VALUE prc) {
return rb_obj_is_proc(prc);
}
@@ -135,9 +123,6 @@ void Init_proc_spec(void) {
rb_define_method(cls, "rb_proc_new_block_given_p", proc_spec_rb_proc_new_block_given_p, 0);
rb_define_method(cls, "rb_proc_arity", proc_spec_rb_proc_arity, 1);
rb_define_method(cls, "rb_proc_call", proc_spec_rb_proc_call, 2);
- rb_define_method(cls, "rb_proc_call_kw", proc_spec_rb_proc_call_kw, 2);
- rb_define_method(cls, "rb_proc_call_with_block", proc_spec_rb_proc_call_with_block, 3);
- rb_define_method(cls, "rb_proc_call_with_block_kw", proc_spec_rb_proc_call_with_block_kw, 3);
rb_define_method(cls, "rb_Proc_new", proc_spec_rb_Proc_new, 1);
rb_define_method(cls, "rb_obj_is_proc", proc_spec_rb_obj_is_proc, 1);
}
diff --git a/spec/ruby/optional/capi/ext/range_spec.c b/spec/ruby/optional/capi/ext/range_spec.c
index b0cf1a8662..7a475ec695 100644
--- a/spec/ruby/optional/capi/ext/range_spec.c
+++ b/spec/ruby/optional/capi/ext/range_spec.c
@@ -7,7 +7,7 @@ extern "C" {
VALUE range_spec_rb_range_new(int argc, VALUE* argv, VALUE self) {
int exclude_end = 0;
- if (argc == 3) {
+ if(argc == 3) {
exclude_end = RTEST(argv[2]);
}
return rb_range_new(argv[0], argv[1], exclude_end);
diff --git a/spec/ruby/optional/capi/ext/rbasic_spec.c b/spec/ruby/optional/capi/ext/rbasic_spec.c
index 26be2fed6d..9178e5f639 100644
--- a/spec/ruby/optional/capi/ext/rbasic_spec.c
+++ b/spec/ruby/optional/capi/ext/rbasic_spec.c
@@ -5,14 +5,6 @@
extern "C" {
#endif
-#ifndef RBASIC_FLAGS
-#define RBASIC_FLAGS(obj) (RBASIC(obj)->flags)
-#endif
-
-#ifndef RBASIC_SET_FLAGS
-#define RBASIC_SET_FLAGS(obj, flags_to_set) (RBASIC(obj)->flags = flags_to_set)
-#endif
-
#ifndef FL_SHAREABLE
static const VALUE VISIBLE_BITS = FL_TAINT | FL_FREEZE;
static const VALUE DATA_VISIBLE_BITS = FL_TAINT | FL_FREEZE | ~(FL_USER0 - 1);
@@ -42,53 +34,47 @@ VALUE rbasic_spec_freeze_flag(VALUE self) {
return VALUE2NUM(RUBY_FL_FREEZE);
}
-static VALUE spec_get_flags(VALUE obj, VALUE visible_bits) {
- VALUE flags = RB_FL_TEST(obj, visible_bits);
+ static VALUE spec_get_flags(const struct RBasic *b, VALUE visible_bits) {
+ VALUE flags = b->flags & visible_bits;
return VALUE2NUM(flags);
}
-static VALUE spec_set_flags(VALUE obj, VALUE flags, VALUE visible_bits) {
+static VALUE spec_set_flags(struct RBasic *b, VALUE flags, VALUE visible_bits) {
flags &= visible_bits;
-
- // Could also be done like:
- // RB_FL_UNSET(obj, visible_bits);
- // RB_FL_SET(obj, flags);
- // But that seems rather indirect
- RBASIC_SET_FLAGS(obj, (RBASIC_FLAGS(obj) & ~visible_bits) | flags);
-
+ b->flags = (b->flags & ~visible_bits) | flags;
return VALUE2NUM(flags);
}
-static VALUE rbasic_spec_get_flags(VALUE self, VALUE obj) {
- return spec_get_flags(obj, VISIBLE_BITS);
+VALUE rbasic_spec_get_flags(VALUE self, VALUE val) {
+ return spec_get_flags(RBASIC(val), VISIBLE_BITS);
}
-static VALUE rbasic_spec_set_flags(VALUE self, VALUE obj, VALUE flags) {
- return spec_set_flags(obj, NUM2VALUE(flags), VISIBLE_BITS);
+VALUE rbasic_spec_set_flags(VALUE self, VALUE val, VALUE flags) {
+ return spec_set_flags(RBASIC(val), NUM2VALUE(flags), VISIBLE_BITS);
}
-static VALUE rbasic_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
- return spec_set_flags(to, RBASIC_FLAGS(from), VISIBLE_BITS);
+VALUE rbasic_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
+ return spec_set_flags(RBASIC(to), RBASIC(from)->flags, VISIBLE_BITS);
}
-static VALUE rbasic_spec_get_klass(VALUE self, VALUE obj) {
- return RBASIC_CLASS(obj);
+VALUE rbasic_spec_get_klass(VALUE self, VALUE val) {
+ return RBASIC(val)->klass;
}
-static VALUE rbasic_rdata_spec_get_flags(VALUE self, VALUE structure) {
- return spec_get_flags(structure, DATA_VISIBLE_BITS);
+VALUE rbasic_rdata_spec_get_flags(VALUE self, VALUE structure) {
+ return spec_get_flags(&RDATA(structure)->basic, DATA_VISIBLE_BITS);
}
-static VALUE rbasic_rdata_spec_set_flags(VALUE self, VALUE structure, VALUE flags) {
- return spec_set_flags(structure, NUM2VALUE(flags), DATA_VISIBLE_BITS);
+VALUE rbasic_rdata_spec_set_flags(VALUE self, VALUE structure, VALUE flags) {
+ return spec_set_flags(&RDATA(structure)->basic, NUM2VALUE(flags), DATA_VISIBLE_BITS);
}
-static VALUE rbasic_rdata_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
- return spec_set_flags(to, RBASIC_FLAGS(from), DATA_VISIBLE_BITS);
+VALUE rbasic_rdata_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
+ return spec_set_flags(&RDATA(to)->basic, RDATA(from)->basic.flags, DATA_VISIBLE_BITS);
}
-static VALUE rbasic_rdata_spec_get_klass(VALUE self, VALUE structure) {
- return RBASIC_CLASS(structure);
+VALUE rbasic_rdata_spec_get_klass(VALUE self, VALUE structure) {
+ return RDATA(structure)->basic.klass;
}
void Init_rbasic_spec(void) {
diff --git a/spec/ruby/optional/capi/ext/rubyspec.h b/spec/ruby/optional/capi/ext/rubyspec.h
index 09135774af..245669d200 100644
--- a/spec/ruby/optional/capi/ext/rubyspec.h
+++ b/spec/ruby/optional/capi/ext/rubyspec.h
@@ -11,29 +11,6 @@
# include <version.h>
#endif
-/* copied from ext/-test-/cxxanyargs/cxxanyargs.cpp */
-#if 0 /* Ignore deprecation warnings */
-
-#elif defined(_MSC_VER)
-#pragma warning(disable : 4996)
-
-#elif defined(__INTEL_COMPILER)
-#pragma warning(disable : 1786)
-
-#elif defined(__clang__)
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-
-#elif defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
-#elif defined(__SUNPRO_CC)
-#pragma error_messages (off,symdeprecated)
-
-#else
-// :FIXME: improve here for your compiler.
-
-#endif
-
#ifndef RUBY_VERSION_MAJOR
#define RUBY_VERSION_MAJOR RUBY_API_VERSION_MAJOR
#define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
@@ -44,21 +21,16 @@
((RUBY_VERSION_MAJOR < (major)) || \
(RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR < (minor)) || \
(RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR == (minor) && RUBY_VERSION_TEENY < (teeny)))
-#define RUBY_VERSION_SINCE(major,minor,teeny) (!RUBY_VERSION_BEFORE(major, minor, teeny))
-
-#if RUBY_VERSION_SINCE(3, 3, 0)
-#define RUBY_VERSION_IS_3_3
-#endif
-#if RUBY_VERSION_SINCE(3, 2, 0)
+#if RUBY_VERSION_MAJOR > 3 || (RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 2)
#define RUBY_VERSION_IS_3_2
#endif
-#if RUBY_VERSION_SINCE(3, 1, 0)
+#if RUBY_VERSION_MAJOR > 3 || (RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 1)
#define RUBY_VERSION_IS_3_1
#endif
-#if RUBY_VERSION_SINCE(3, 0, 0)
+#if RUBY_VERSION_MAJOR > 3 || (RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 0)
#define RUBY_VERSION_IS_3_0
#endif
diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c
index 2bd789fb72..a858936243 100644
--- a/spec/ruby/optional/capi/ext/string_spec.c
+++ b/spec/ruby/optional/capi/ext/string_spec.c
@@ -62,7 +62,7 @@ VALUE string_spec_rb_str_buf_new(VALUE self, VALUE len, VALUE str) {
buf = rb_str_buf_new(NUM2LONG(len));
- if (RTEST(str)) {
+ if(RTEST(str)) {
snprintf(RSTRING_PTR(buf), NUM2LONG(len), "%s", RSTRING_PTR(str));
}
@@ -129,7 +129,7 @@ VALUE string_spec_rb_str_conv_enc(VALUE self, VALUE str, VALUE from, VALUE to) {
from_enc = rb_to_encoding(from);
- if (NIL_P(to)) {
+ if(NIL_P(to)) {
to_enc = 0;
} else {
to_enc = rb_to_encoding(to);
@@ -139,13 +139,14 @@ VALUE string_spec_rb_str_conv_enc(VALUE self, VALUE str, VALUE from, VALUE to) {
}
VALUE string_spec_rb_str_conv_enc_opts(VALUE self, VALUE str, VALUE from, VALUE to,
- VALUE ecflags, VALUE ecopts) {
+ VALUE ecflags, VALUE ecopts)
+{
rb_encoding* from_enc;
rb_encoding* to_enc;
from_enc = rb_to_encoding(from);
- if (NIL_P(to)) {
+ if(NIL_P(to)) {
to_enc = 0;
} else {
to_enc = rb_to_encoding(to);
@@ -199,7 +200,7 @@ VALUE string_spec_rb_str_new_offset(VALUE self, VALUE str, VALUE offset, VALUE l
}
VALUE string_spec_rb_str_new2(VALUE self, VALUE str) {
- if (NIL_P(str)) {
+ if(NIL_P(str)) {
return rb_str_new2("");
} else {
return rb_str_new2(RSTRING_PTR(str));
@@ -215,7 +216,7 @@ VALUE string_spec_rb_str_export_to_enc(VALUE self, VALUE str, VALUE enc) {
}
VALUE string_spec_rb_str_new_cstr(VALUE self, VALUE str) {
- if (NIL_P(str)) {
+ if(NIL_P(str)) {
return rb_str_new_cstr("");
} else {
return rb_str_new_cstr(RSTRING_PTR(str));
@@ -254,6 +255,16 @@ VALUE string_spec_rb_str_new5(VALUE self, VALUE str, VALUE ptr, VALUE len) {
return rb_str_new5(str, RSTRING_PTR(ptr), FIX2INT(len));
}
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wdeprecated-declarations")
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+# endif
+#endif
+
#ifndef RUBY_VERSION_IS_3_2
VALUE string_spec_rb_tainted_str_new(VALUE self, VALUE str, VALUE len) {
return rb_tainted_str_new(RSTRING_PTR(str), FIX2INT(len));
@@ -264,6 +275,14 @@ VALUE string_spec_rb_tainted_str_new2(VALUE self, VALUE str) {
}
#endif
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic pop
+#elif defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wdeprecated-declarations")
+# pragma clang diagnostic pop
+# endif
+#endif
+
VALUE string_spec_rb_str_plus(VALUE self, VALUE str1, VALUE str2) {
return rb_str_plus(str1, str2);
}
@@ -371,7 +390,7 @@ VALUE string_spec_RSTRING_PTR_set(VALUE self, VALUE str, VALUE i, VALUE chr) {
VALUE string_spec_RSTRING_PTR_after_funcall(VALUE self, VALUE str, VALUE cb) {
/* Silence gcc 4.3.2 warning about computed value not used */
- if (RSTRING_PTR(str)) { /* force it out */
+ if(RSTRING_PTR(str)) { /* force it out */
rb_funcall(cb, rb_intern("call"), 1, str);
}
@@ -554,7 +573,7 @@ static VALUE string_spec_rb_utf8_str_new_cstr(VALUE self) {
}
PRINTF_ARGS(static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...), 2, 3);
-static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...) {
+static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...){
va_list ap;
va_start(ap, fmt);
VALUE result = rb_str_vcatf(mesg, fmt, ap);
@@ -578,6 +597,18 @@ static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
return rb_str_unlocktmp(str);
}
+VALUE rb_str_to_interned_str(VALUE str);
+VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc);
+
+static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE enc) {
+ rb_encoding *e = NIL_P(enc) ? 0 : rb_to_encoding(enc);
+ return rb_enc_interned_str_cstr(RSTRING_PTR(str), e);
+}
+
+static VALUE string_spec_rb_str_to_interned_str(VALUE self, VALUE str) {
+ return rb_str_to_interned_str(str);
+}
+
void Init_string_spec(void) {
VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject);
rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
@@ -679,6 +710,8 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_str_catf", string_spec_rb_str_catf, 1);
rb_define_method(cls, "rb_str_locktmp", string_spec_rb_str_locktmp, 1);
rb_define_method(cls, "rb_str_unlocktmp", string_spec_rb_str_unlocktmp, 1);
+ rb_define_method(cls, "rb_enc_interned_str_cstr", string_spec_rb_enc_interned_str_cstr, 2);
+ rb_define_method(cls, "rb_str_to_interned_str", string_spec_rb_str_to_interned_str, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/struct_spec.c b/spec/ruby/optional/capi/ext/struct_spec.c
index 9c45bd5672..0393d6937d 100644
--- a/spec/ruby/optional/capi/ext/struct_spec.c
+++ b/spec/ruby/optional/capi/ext/struct_spec.c
@@ -15,11 +15,13 @@ static VALUE struct_spec_rb_struct_getmember(VALUE self, VALUE st, VALUE key) {
return rb_struct_getmember(st, SYM2ID(key));
}
-static VALUE struct_spec_rb_struct_s_members(VALUE self, VALUE klass) {
+static VALUE struct_spec_rb_struct_s_members(VALUE self, VALUE klass)
+{
return rb_ary_dup(rb_struct_s_members(klass));
}
-static VALUE struct_spec_rb_struct_members(VALUE self, VALUE st) {
+static VALUE struct_spec_rb_struct_members(VALUE self, VALUE st)
+{
return rb_ary_dup(rb_struct_members(st));
}
@@ -54,11 +56,14 @@ static VALUE struct_spec_struct_define_under(VALUE self, VALUE outer,
}
static VALUE struct_spec_rb_struct_new(VALUE self, VALUE klass,
- VALUE a, VALUE b, VALUE c) {
+ VALUE a, VALUE b, VALUE c)
+{
+
return rb_struct_new(klass, a, b, c);
}
-static VALUE struct_spec_rb_struct_size(VALUE self, VALUE st) {
+static VALUE struct_spec_rb_struct_size(VALUE self, VALUE st)
+{
return rb_struct_size(st);
}
diff --git a/spec/ruby/optional/capi/ext/thread_spec.c b/spec/ruby/optional/capi/ext/thread_spec.c
index 7d08d45098..be812d796f 100644
--- a/spec/ruby/optional/capi/ext/thread_spec.c
+++ b/spec/ruby/optional/capi/ext/thread_spec.c
@@ -8,10 +8,7 @@
#include <unistd.h>
#endif
#if defined(_WIN32)
-#include "ruby/win32.h"
-#define read rb_w32_read
-#define write rb_w32_write
-#define pipe rb_w32_pipe
+#define pipe(p) rb_w32_pipe(p)
#endif
#ifndef _WIN32
@@ -26,6 +23,10 @@ static VALUE thread_spec_rb_thread_alone(VALUE self) {
return rb_thread_alone() ? Qtrue : Qfalse;
}
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
/* This is unblocked by unblock_func(). */
static void* blocking_gvl_func(void* data) {
int rfd = *(int *)data;
diff --git a/spec/ruby/optional/capi/ext/tracepoint_spec.c b/spec/ruby/optional/capi/ext/tracepoint_spec.c
index 6666c8f85c..78c459d6cb 100644
--- a/spec/ruby/optional/capi/ext/tracepoint_spec.c
+++ b/spec/ruby/optional/capi/ext/tracepoint_spec.c
@@ -17,7 +17,7 @@ static VALUE tracepoint_spec_rb_tracepoint_new(VALUE self, VALUE data) {
return rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, callback, (void*) data);
}
-static VALUE tracepoint_spec_callback_called(VALUE self) {
+static VALUE tracepoint_spec_callback_called(VALUE self){
return callback_called;
}
diff --git a/spec/ruby/optional/capi/ext/typed_data_spec.c b/spec/ruby/optional/capi/ext/typed_data_spec.c
index 38889ecf5c..eca2b667cc 100644
--- a/spec/ruby/optional/capi/ext/typed_data_spec.c
+++ b/spec/ruby/optional/capi/ext/typed_data_spec.c
@@ -106,12 +106,6 @@ VALUE sws_typed_wrap_struct(VALUE self, VALUE val) {
return TypedData_Wrap_Struct(rb_cObject, &sample_typed_wrapped_struct_data_type, bar);
}
-VALUE sws_untyped_wrap_struct(VALUE self, VALUE val) {
- int* data = (int*) malloc(sizeof(int));
- *data = FIX2INT(val);
- return Data_Wrap_Struct(rb_cObject, NULL, free, data);
-}
-
VALUE sws_typed_get_struct(VALUE self, VALUE obj) {
struct sample_typed_wrapped_struct* bar;
TypedData_Get_Struct(obj, struct sample_typed_wrapped_struct, &sample_typed_wrapped_struct_data_type, bar);
@@ -171,17 +165,12 @@ VALUE sws_typed_rb_check_typeddata_different_type(VALUE self, VALUE obj) {
return rb_check_typeddata(obj, &sample_typed_wrapped_struct_other_data_type) == DATA_PTR(obj) ? Qtrue : Qfalse;
}
-VALUE sws_typed_RTYPEDDATA_P(VALUE self, VALUE obj) {
- return RTYPEDDATA_P(obj) ? Qtrue : Qfalse;
-}
-
void Init_typed_data_spec(void) {
VALUE cls = rb_define_class("CApiAllocTypedSpecs", rb_cObject);
rb_define_alloc_func(cls, sdaf_alloc_typed_func);
rb_define_method(cls, "typed_wrapped_data", sdaf_typed_get_struct, 0);
cls = rb_define_class("CApiWrappedTypedStructSpecs", rb_cObject);
rb_define_method(cls, "typed_wrap_struct", sws_typed_wrap_struct, 1);
- rb_define_method(cls, "untyped_wrap_struct", sws_untyped_wrap_struct, 1);
rb_define_method(cls, "typed_get_struct", sws_typed_get_struct, 1);
rb_define_method(cls, "typed_get_struct_other", sws_typed_get_struct_different_type, 1);
rb_define_method(cls, "typed_get_struct_parent", sws_typed_get_struct_parent_type, 1);
@@ -192,7 +181,6 @@ void Init_typed_data_spec(void) {
rb_define_method(cls, "rb_check_typeddata_same_type", sws_typed_rb_check_typeddata_same_type, 1);
rb_define_method(cls, "rb_check_typeddata_same_type_parent", sws_typed_rb_check_typeddata_same_type_parent, 1);
rb_define_method(cls, "rb_check_typeddata_different_type", sws_typed_rb_check_typeddata_different_type, 1);
- rb_define_method(cls, "RTYPEDDATA_P", sws_typed_RTYPEDDATA_P, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/fixtures/kernel.rb b/spec/ruby/optional/capi/fixtures/kernel.rb
deleted file mode 100644
index f5b95e0fea..0000000000
--- a/spec/ruby/optional/capi/fixtures/kernel.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class CApiKernelSpecs
- class ClassWithPublicMethod
- def public_method(*, **)
- 0
- end
- end
-
- class ClassWithPrivateMethod
- private def private_method(*, **)
- 0
- end
- end
-
- class ClassWithProtectedMethod
- protected def protected_method(*, **)
- 0
- end
- end
-end
diff --git a/spec/ruby/optional/capi/hash_spec.rb b/spec/ruby/optional/capi/hash_spec.rb
index a0e49ffc4c..a60467a66b 100644
--- a/spec/ruby/optional/capi/hash_spec.rb
+++ b/spec/ruby/optional/capi/hash_spec.rb
@@ -50,22 +50,6 @@ describe "C-API Hash function" do
end
end
- ruby_version_is '3.2' do
- describe "rb_hash_new_capa" do
- it "returns a new hash" do
- @s.rb_hash_new_capa(3).should == {}
- end
-
- it "creates a hash with no default proc" do
- @s.rb_hash_new_capa(3) {}.default_proc.should be_nil
- end
-
- it "raises RuntimeError when negative index is provided" do
- -> { @s.rb_hash_new_capa(-1) }.should raise_error(RuntimeError, "st_table too big")
- end
- end
- end
-
describe "rb_ident_hash_new" do
it "returns a new compare by identity hash" do
result = @s.rb_ident_hash_new
diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb
index e5fb86a837..95717351a6 100644
--- a/spec/ruby/optional/capi/io_spec.rb
+++ b/spec/ruby/optional/capi/io_spec.rb
@@ -175,18 +175,13 @@ describe "C-API IO function" do
end
end
- describe "rb_io_descriptor or GetOpenFile" do
+ describe "GetOpenFile" do
it "allows access to the system fileno" do
@o.GetOpenFile_fd($stdin).should == 0
@o.GetOpenFile_fd($stdout).should == 1
@o.GetOpenFile_fd($stderr).should == 2
@o.GetOpenFile_fd(@io).should == @io.fileno
end
-
- it "raises IOError if the IO is closed" do
- @io.close
- -> { @o.GetOpenFile_fd(@io) }.should raise_error(IOError, "closed stream")
- end
end
describe "rb_io_binmode" do
@@ -261,27 +256,6 @@ describe "C-API IO function" do
end
end
- ruby_version_is "3.1" do
- describe "rb_io_maybe_wait_writable" do
- it "returns mask for events if operation was interrupted" do
- @o.rb_io_maybe_wait_writable(Errno::EINTR::Errno, @w_io, nil).should == IO::WRITABLE
- end
-
- it "returns 0 if there is no error condition" do
- @o.rb_io_maybe_wait_writable(0, @w_io, nil).should == 0
- end
-
- it "raises an IOError if the IO is closed" do
- @w_io.close
- -> { @o.rb_io_maybe_wait_writable(0, @w_io, nil) }.should raise_error(IOError, "closed stream")
- end
-
- it "raises an IOError if the IO is not initialized" do
- -> { @o.rb_io_maybe_wait_writable(0, IO.allocate, nil) }.should raise_error(IOError, "uninitialized stream")
- end
- end
- end
-
describe "rb_thread_fd_writable" do
it "waits til an fd is ready for writing" do
@o.rb_thread_fd_writable(@w_io).should be_nil
@@ -331,40 +305,6 @@ describe "C-API IO function" do
thr.join
end
end
-
- ruby_version_is "3.1" do
- describe "rb_io_maybe_wait_readable" do
- it "returns mask for events if operation was interrupted" do
- @o.rb_io_maybe_wait_readable(Errno::EINTR::Errno, @r_io, nil, false).should == IO::READABLE
- end
-
- it "returns 0 if there is no error condition" do
- @o.rb_io_maybe_wait_readable(0, @r_io, nil, false).should == 0
- end
-
- it "blocks until the io is readable and returns events that actually occurred" do
- @o.instance_variable_set :@write_data, false
- thr = Thread.new do
- Thread.pass until @o.instance_variable_get(:@write_data)
- @w_io.write "rb_io_wait_readable"
- end
-
- @o.rb_io_maybe_wait_readable(Errno::EAGAIN::Errno, @r_io, IO::READABLE, true).should == IO::READABLE
- @o.instance_variable_get(:@read_data).should == "rb_io_wait_re"
-
- thr.join
- end
-
- it "raises an IOError if the IO is closed" do
- @r_io.close
- -> { @o.rb_io_maybe_wait_readable(0, @r_io, nil, false) }.should raise_error(IOError, "closed stream")
- end
-
- it "raises an IOError if the IO is not initialized" do
- -> { @o.rb_io_maybe_wait_readable(0, IO.allocate, nil, false) }.should raise_error(IOError, "uninitialized stream")
- end
- end
- end
end
describe "rb_thread_wait_fd" do
@@ -404,42 +344,6 @@ describe "C-API IO function" do
@o.rb_wait_for_single_fd(@r_io, 1, 0, 0).should == 0
end
end
-
- ruby_version_is "3.1" do
- describe "rb_io_maybe_wait" do
- it "waits til an fd is ready for reading" do
- start = false
- thr = Thread.new do
- start = true
- sleep 0.05
- @w_io.write "rb_io_maybe_wait"
- end
-
- Thread.pass until start
-
- @o.rb_io_maybe_wait(Errno::EAGAIN::Errno, @r_io, IO::READABLE, nil).should == IO::READABLE
-
- thr.join
- end
-
- it "returns mask for events if operation was interrupted" do
- @o.rb_io_maybe_wait(Errno::EINTR::Errno, @w_io, IO::WRITABLE, nil).should == IO::WRITABLE
- end
-
- it "returns false if there is no error condition" do
- @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil).should == false
- end
-
- it "raises an IOError if the IO is closed" do
- @w_io.close
- -> { @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, nil) }.should raise_error(IOError, "closed stream")
- end
-
- it "raises an IOError if the IO is not initialized" do
- -> { @o.rb_io_maybe_wait(0, IO.allocate, IO::WRITABLE, nil) }.should raise_error(IOError, "uninitialized stream")
- end
- end
- end
end
describe "rb_fd_fix_cloexec" do
diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb
index 17c49b2155..54d8d8a8d3 100644
--- a/spec/ruby/optional/capi/kernel_spec.rb
+++ b/spec/ruby/optional/capi/kernel_spec.rb
@@ -1,5 +1,4 @@
require_relative 'spec_helper'
-require_relative 'fixtures/kernel'
kernel_path = load_extension("kernel")
@@ -503,11 +502,6 @@ describe "C-API Kernel function" do
it "evaluates a string of ruby code" do
@s.rb_eval_string("1+1").should == 2
end
-
- it "captures local variables when called within a method" do
- a = 2
- @s.rb_eval_string("a+1").should == 3
- end
end
describe "rb_eval_cmd_kw" do
@@ -603,65 +597,47 @@ describe "C-API Kernel function" do
@s.rb_funcallv(self, :empty, []).should == 42
@s.rb_funcallv(self, :sum, [1, 2]).should == 3
end
-
- it "calls a private method" do
- object = CApiKernelSpecs::ClassWithPrivateMethod.new
- @s.rb_funcallv(object, :private_method, []).should == 0
- end
-
- it "calls a protected method" do
- object = CApiKernelSpecs::ClassWithProtectedMethod.new
- @s.rb_funcallv(object, :protected_method, []).should == 0
- end
end
- describe "rb_funcallv_kw" do
- it "passes keyword arguments to the callee" do
- def m(*args, **kwargs)
- [args, kwargs]
- end
-
- @s.rb_funcallv_kw(self, :m, [{}]).should == [[], {}]
- @s.rb_funcallv_kw(self, :m, [{a: 1}]).should == [[], {a: 1}]
- @s.rb_funcallv_kw(self, :m, [{b: 2}, {a: 1}]).should == [[{b: 2}], {a: 1}]
- @s.rb_funcallv_kw(self, :m, [{b: 2}, {}]).should == [[{b: 2}], {}]
- end
+ ruby_version_is "3.0" do
+ describe "rb_funcallv_kw" do
+ it "passes keyword arguments to the callee" do
+ def m(*args, **kwargs)
+ [args, kwargs]
+ end
- it "calls a private method" do
- object = CApiKernelSpecs::ClassWithPrivateMethod.new
- @s.rb_funcallv_kw(object, :private_method, [{}]).should == 0
- end
+ @s.rb_funcallv_kw(self, :m, [{}]).should == [[], {}]
+ @s.rb_funcallv_kw(self, :m, [{a: 1}]).should == [[], {a: 1}]
+ @s.rb_funcallv_kw(self, :m, [{b: 2}, {a: 1}]).should == [[{b: 2}], {a: 1}]
+ @s.rb_funcallv_kw(self, :m, [{b: 2}, {}]).should == [[{b: 2}], {}]
+ end
- it "calls a protected method" do
- object = CApiKernelSpecs::ClassWithProtectedMethod.new
- @s.rb_funcallv_kw(object, :protected_method, [{}]).should == 0
- end
+ it "raises TypeError if the last argument is not a Hash" do
+ def m(*args, **kwargs)
+ [args, kwargs]
+ end
- it "raises TypeError if the last argument is not a Hash" do
- def m(*args, **kwargs)
- [args, kwargs]
+ -> {
+ @s.rb_funcallv_kw(self, :m, [42])
+ }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
end
-
- -> {
- @s.rb_funcallv_kw(self, :m, [42])
- }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
end
- end
- describe "rb_keyword_given_p" do
- it "returns whether keywords were given to the C extension method" do
- h = {a: 1}
- empty = {}
- @s.rb_keyword_given_p(a: 1).should == true
- @s.rb_keyword_given_p("foo" => "bar").should == true
- @s.rb_keyword_given_p(**h).should == true
+ describe "rb_keyword_given_p" do
+ it "returns whether keywords were given to the C extension method" do
+ h = {a: 1}
+ empty = {}
+ @s.rb_keyword_given_p(a: 1).should == true
+ @s.rb_keyword_given_p("foo" => "bar").should == true
+ @s.rb_keyword_given_p(**h).should == true
- @s.rb_keyword_given_p(h).should == false
- @s.rb_keyword_given_p().should == false
- @s.rb_keyword_given_p(**empty).should == false
+ @s.rb_keyword_given_p(h).should == false
+ @s.rb_keyword_given_p().should == false
+ @s.rb_keyword_given_p(**empty).should == false
- @s.rb_funcallv_kw(@s, :rb_keyword_given_p, [{a: 1}]).should == true
- @s.rb_funcallv_kw(@s, :rb_keyword_given_p, [{}]).should == false
+ @s.rb_funcallv_kw(@s, :rb_keyword_given_p, [{a: 1}]).should == true
+ @s.rb_funcallv_kw(@s, :rb_keyword_given_p, [{}]).should == false
+ end
end
end
@@ -700,56 +676,21 @@ describe "C-API Kernel function" do
end
describe 'rb_funcall_with_block' do
- it "calls a method with block" do
+ before :each do
@obj = Object.new
class << @obj
- def method_public(*args); [args, yield] end
+ def method_public; yield end
+ def method_private; yield end
+ private :method_private
end
-
- @s.rb_funcall_with_block(@obj, :method_public, [1, 2], proc { :result }).should == [[1, 2], :result]
end
- it "does not call a private method" do
- object = CApiKernelSpecs::ClassWithPrivateMethod.new
-
- -> {
- @s.rb_funcall_with_block(object, :private_method, [], proc { })
- }.should raise_error(NoMethodError, /private/)
- end
-
- it "does not call a protected method" do
- object = CApiKernelSpecs::ClassWithProtectedMethod.new
-
- -> {
- @s.rb_funcall_with_block(object, :protected_method, [], proc { })
- }.should raise_error(NoMethodError, /protected/)
- end
- end
-
- describe 'rb_funcall_with_block_kw' do
- it "calls a method with keyword arguments and a block" do
- @obj = Object.new
- class << @obj
- def method_public(*args, **kw, &block); [args, kw, block.call] end
- end
-
- @s.rb_funcall_with_block_kw(@obj, :method_public, [1, 2, {a: 2}], proc { :result }).should == [[1, 2], {a: 2}, :result]
+ it "calls a method with block" do
+ @s.rb_funcall_with_block(@obj, :method_public, proc { :result }).should == :result
end
it "does not call a private method" do
- object = CApiKernelSpecs::ClassWithPrivateMethod.new
-
- -> {
- @s.rb_funcall_with_block_kw(object, :private_method, [{}], proc { })
- }.should raise_error(NoMethodError, /private/)
- end
-
- it "does not call a protected method" do
- object = CApiKernelSpecs::ClassWithProtectedMethod.new
-
- -> {
- @s.rb_funcall_with_block_kw(object, :protected_method, [{}], proc { })
- }.should raise_error(NoMethodError, /protected/)
+ -> { @s.rb_funcall_with_block(@obj, :method_private, proc { :result }) }.should raise_error(NoMethodError, /private/)
end
end
end
diff --git a/spec/ruby/optional/capi/object_spec.rb b/spec/ruby/optional/capi/object_spec.rb
index 6ee6d65680..25a43d8908 100644
--- a/spec/ruby/optional/capi/object_spec.rb
+++ b/spec/ruby/optional/capi/object_spec.rb
@@ -219,7 +219,7 @@ describe "CApiObject" do
end
it "requires a ruby file" do
- $:.unshift __dir__
+ $:.unshift File.dirname(__FILE__)
@o.rb_require()
$foo.should == 7
end
@@ -993,19 +993,13 @@ describe "CApiObject" do
end
it "calls the callback function for each cvar and ivar on a class" do
- exp = [:@@cvar, :foo, :@@cvar2, :bar, :@ivar, :baz]
- exp.unshift(:__classpath__, 'CApiObjectSpecs::CVars') if RUBY_VERSION < "3.3"
-
ary = @o.rb_ivar_foreach(CApiObjectSpecs::CVars)
- ary.should == exp
+ ary.should == [:__classpath__, 'CApiObjectSpecs::CVars', :@@cvar, :foo, :@@cvar2, :bar, :@ivar, :baz]
end
it "calls the callback function for each cvar and ivar on a module" do
- exp = [:@@mvar, :foo, :@@mvar2, :bar, :@ivar, :baz]
- exp.unshift(:__classpath__, 'CApiObjectSpecs::MVars') if RUBY_VERSION < "3.3"
-
ary = @o.rb_ivar_foreach(CApiObjectSpecs::MVars)
- ary.should == exp
+ ary.should == [:__classpath__, 'CApiObjectSpecs::MVars', :@@mvar, :foo, :@@mvar2, :bar, :@ivar, :baz]
end
end
diff --git a/spec/ruby/optional/capi/proc_spec.rb b/spec/ruby/optional/capi/proc_spec.rb
index 8b94432f3e..c839665ae9 100644
--- a/spec/ruby/optional/capi/proc_spec.rb
+++ b/spec/ruby/optional/capi/proc_spec.rb
@@ -82,59 +82,6 @@ describe "C-API Proc function" do
end
end
- describe "rb_proc_call_kw" do
- it "passes keyword arguments to the proc" do
- prc = proc { |*args, **kw| [args, kw] }
-
- @p.rb_proc_call_kw(prc, [{}]).should == [[], {}]
- @p.rb_proc_call_kw(prc, [{a: 1}]).should == [[], {a: 1}]
- @p.rb_proc_call_kw(prc, [{b: 2}, {a: 1}]).should == [[{b: 2}], {a: 1}]
- @p.rb_proc_call_kw(prc, [{b: 2}, {}]).should == [[{b: 2}], {}]
- end
-
- it "raises TypeError if the last argument is not a Hash" do
- -> {
- @p.rb_proc_call_kw(proc {}, [42])
- }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
- end
- end
-
- describe "rb_proc_call_with_block" do
- it "calls the Proc and passes arguments and a block" do
- prc = Proc.new { |a, b, &block| block.call(a * b) }
- @p.rb_proc_call_with_block(prc, [6, 7], proc { |n| n * 2 }).should == 6 * 7 * 2
- end
-
- it "calls the Proc and passes arguments when a block is nil" do
- prc = Proc.new { |a, b| a * b }
- @p.rb_proc_call_with_block(prc, [6, 7], nil).should == 6 * 7
- end
- end
-
- describe "rb_proc_call_with_block_kw" do
- it "passes keyword arguments and a block to the proc" do
- prc = proc { |*args, **kw, &block| [args, kw, block.call(42)] }
- block = proc { |n| n }
-
- @p.rb_proc_call_with_block_kw(prc, [{}], block).should == [[], {}, 42]
- @p.rb_proc_call_with_block_kw(prc, [{a: 1}], block).should == [[], {a: 1}, 42]
- @p.rb_proc_call_with_block_kw(prc, [{b: 2}, {a: 1}], block).should == [[{b: 2}], {a: 1}, 42]
- @p.rb_proc_call_with_block_kw(prc, [{b: 2}, {}], block).should == [[{b: 2}], {}, 42]
- end
-
- it "raises TypeError if the last argument is not a Hash" do
- -> {
- @p.rb_proc_call_with_block_kw(proc {}, [42], proc {})
- }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
- end
-
- it "passes keyword arguments to the proc when a block is nil" do
- prc = proc { |*args, **kw| [args, kw] }
-
- @p.rb_proc_call_with_block_kw(prc, [{}], nil).should == [[], {}]
- end
- end
-
describe "rb_obj_is_proc" do
it "returns true for Proc" do
prc = Proc.new {|a,b| a * b }
diff --git a/spec/ruby/optional/capi/rbasic_spec.rb b/spec/ruby/optional/capi/rbasic_spec.rb
index f3367e05ff..577f2060da 100644
--- a/spec/ruby/optional/capi/rbasic_spec.rb
+++ b/spec/ruby/optional/capi/rbasic_spec.rb
@@ -33,8 +33,6 @@ describe "RBasic support for RData" do
initial = @specs.get_flags(obj1)
@specs.get_flags(obj2).should == initial
@specs.set_flags(obj1, 1 << 14 | 1 << 16 | initial)
- @specs.get_flags(obj1).should == 1 << 14 | 1 << 16 | initial
-
@specs.copy_flags(obj2, obj1)
@specs.get_flags(obj2).should == 1 << 14 | 1 << 16 | initial
@specs.set_flags(obj1, initial)
diff --git a/spec/ruby/optional/capi/shared/rbasic.rb b/spec/ruby/optional/capi/shared/rbasic.rb
index 9d80a93e1d..95c3137143 100644
--- a/spec/ruby/optional/capi/shared/rbasic.rb
+++ b/spec/ruby/optional/capi/shared/rbasic.rb
@@ -1,4 +1,5 @@
describe :rbasic, shared: true do
+
before :all do
specs = CApiRBasicSpecs.new
@taint = ruby_version_is(''...'3.1') ? specs.taint_flag : 0
diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb
index 3a47fa9762..c0fbf3d1ba 100644
--- a/spec/ruby/optional/capi/string_spec.rb
+++ b/spec/ruby/optional/capi/string_spec.rb
@@ -1227,4 +1227,67 @@ end
-> { @s.rb_str_unlocktmp("test") }.should raise_error(RuntimeError, 'temporal unlocking already unlocked string')
end
end
+
+ describe "rb_enc_interned_str_cstr" do
+ it "returns a frozen string" do
+ str = "hello"
+ val = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
+
+ val.should.is_a?(String)
+ val.encoding.should == Encoding::US_ASCII
+ val.should.frozen?
+ end
+
+ it "returns the same frozen string" do
+ str = "hello"
+ result1 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
+ result2 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
+ result1.should.equal?(result2)
+ end
+
+ it "returns different frozen strings for different encodings" do
+ str = "hello"
+ result1 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
+ result2 = @s.rb_enc_interned_str_cstr(str, Encoding::UTF_8)
+ result1.should_not.equal?(result2)
+ end
+
+ it "returns the same string as String#-@" do
+ @s.rb_enc_interned_str_cstr("hello", Encoding::UTF_8).should.equal?(-"hello")
+ end
+
+ ruby_bug "#20322", ""..."3.4" do
+ it "uses the default encoding if encoding is null" do
+ str = "hello"
+ val = @s.rb_enc_interned_str_cstr(str, nil)
+ val.encoding.should == Encoding::ASCII_8BIT
+ end
+ end
+ end
+
+ describe "rb_str_to_interned_str" do
+ it "returns a frozen string" do
+ str = "hello"
+ result = @s.rb_str_to_interned_str(str)
+ result.should.is_a?(String)
+ result.should.frozen?
+ end
+
+ it "returns the same frozen string" do
+ str = "hello"
+ result1 = @s.rb_str_to_interned_str(str)
+ result2 = @s.rb_str_to_interned_str(str)
+ result1.should.equal?(result2)
+ end
+
+ it "returns different frozen strings for different encodings" do
+ result1 = @s.rb_str_to_interned_str("hello".force_encoding(Encoding::US_ASCII))
+ result2 = @s.rb_str_to_interned_str("hello".force_encoding(Encoding::UTF_8))
+ result1.should_not.equal?(result2)
+ end
+
+ it "returns the same string as String#-@" do
+ @s.rb_str_to_interned_str("hello").should.equal?(-"hello")
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/thread_spec.rb b/spec/ruby/optional/capi/thread_spec.rb
index af641f0564..5cb46bbb7c 100644
--- a/spec/ruby/optional/capi/thread_spec.rb
+++ b/spec/ruby/optional/capi/thread_spec.rb
@@ -165,23 +165,25 @@ describe "C-API Thread function" do
end
end
- it "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" do
- thr = Thread.new do
- @t.rb_thread_call_without_gvl_with_ubf_io
- end
+ platform_is_not :mingw do
+ it "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" do
+ thr = Thread.new do
+ @t.rb_thread_call_without_gvl_with_ubf_io
+ end
- # Wait until it's blocking...
- Thread.pass until thr.stop?
+ # Wait until it's blocking...
+ Thread.pass until thr.stop?
- # The thread status is set to sleep by rb_thread_call_without_gvl(),
- # but the thread might not be in the blocking read(2) yet, so wait a bit.
- sleep 0.1
+ # The thread status is set to sleep by rb_thread_call_without_gvl(),
+ # but the thread might not be in the blocking read(2) yet, so wait a bit.
+ sleep 0.1
- # Wake it up, causing the unblock function to be run.
- thr.wakeup
+ # Wake it up, causing the unblock function to be run.
+ thr.wakeup
- # Make sure it stopped and we got a proper value
- thr.value.should be_true
+ # Make sure it stopped and we got a proper value
+ thr.value.should be_true
+ end
end
end
end
diff --git a/spec/ruby/optional/capi/time_spec.rb b/spec/ruby/optional/capi/time_spec.rb
index ca5fc5952a..579e81fc19 100644
--- a/spec/ruby/optional/capi/time_spec.rb
+++ b/spec/ruby/optional/capi/time_spec.rb
@@ -283,11 +283,6 @@ describe "CApiTimeSpecs" do
-> { @s.rb_time_timespec_new(1447087832, 476451125, 86400) }.should raise_error(ArgumentError)
-> { @s.rb_time_timespec_new(1447087832, 476451125, -86400) }.should raise_error(ArgumentError)
end
-
- it "doesn't call Time.at directly" do
- Time.should_not_receive(:at)
- @s.rb_time_timespec_new(1447087832, 476451125, 32400).should be_kind_of(Time)
- end
end
describe "rb_timespec_now" do
diff --git a/spec/ruby/optional/capi/typed_data_spec.rb b/spec/ruby/optional/capi/typed_data_spec.rb
index 6d1398a1a0..23b7c157ef 100644
--- a/spec/ruby/optional/capi/typed_data_spec.rb
+++ b/spec/ruby/optional/capi/typed_data_spec.rb
@@ -85,16 +85,4 @@ describe "CApiWrappedTypedStruct" do
-> { @s.rb_check_typeddata_different_type(a) }.should raise_error(TypeError)
end
end
-
- describe "RTYPEDDATA_P" do
- it "returns true for a typed data" do
- a = @s.typed_wrap_struct(1024)
- @s.RTYPEDDATA_P(a).should == true
- end
-
- it "returns false for an untyped data object" do
- a = @s.untyped_wrap_struct(1024)
- @s.RTYPEDDATA_P(a).should == false
- end
- end
end
diff --git a/spec/ruby/optional/capi/util_spec.rb b/spec/ruby/optional/capi/util_spec.rb
index 2c16999cdc..38f6f47b1a 100644
--- a/spec/ruby/optional/capi/util_spec.rb
+++ b/spec/ruby/optional/capi/util_spec.rb
@@ -115,11 +115,22 @@ describe "C-API Util function" do
ScratchPad.recorded.should == [1, nil]
end
- it "rejects the use of nil as a hash" do
- -> {
- @o.rb_scan_args([1, nil], "1:", 2, @acc).should == 1
- }.should raise_error(ArgumentError)
- ScratchPad.recorded.should == []
+ ruby_version_is ''...'3.0' do
+ it "assigns required and Hash arguments with nil Hash" do
+ suppress_warning do
+ @o.rb_scan_args([1, nil], "1:", 2, @acc).should == 1
+ end
+ ScratchPad.recorded.should == [1, nil]
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "rejects the use of nil as a hash" do
+ -> {
+ @o.rb_scan_args([1, nil], "1:", 2, @acc).should == 1
+ }.should raise_error(ArgumentError)
+ ScratchPad.recorded.should == []
+ end
end
it "assigns required and optional arguments with no hash argument given" do
@@ -127,41 +138,61 @@ describe "C-API Util function" do
ScratchPad.recorded.should == [1, 7, 4]
end
- it "assigns optional arguments with no hash argument given" do
- @o.rb_scan_args([1, 7], "02:", 3, @acc).should == 2
- ScratchPad.recorded.should == [1, 7, nil]
- end
-
- it "assigns optional arguments with no hash argument given and rejects the use of optional nil argument as a hash" do
- -> {
- @o.rb_scan_args([1, nil], "02:", 3, @acc).should == 2
- }.should_not complain
-
- ScratchPad.recorded.should == [1, nil, nil]
- end
-
it "assigns required, optional, splat, post-splat, Hash and block arguments" do
h = {a: 1, b: 2}
@o.rb_scan_args([1, 2, 3, 4, 5, h], "k11*1:&", 6, @acc, &@prc).should == 5
ScratchPad.recorded.should == [1, 2, [3, 4], 5, h, @prc]
end
- it "does not reject non-symbol keys in keyword arguments" do
- h = {1 => 2, 3 => 4}
- @o.rb_scan_args([h], "k0:", 1, @acc).should == 0
- ScratchPad.recorded.should == [h]
- end
+ ruby_version_is ''...'3.0' do
+ # r43934
+ it "rejects non-keyword arguments" do
+ h = {1 => 2, 3 => 4}
+ -> {
+ suppress_warning do
+ @o.rb_scan_args([h], "k0:", 1, @acc)
+ end
+ }.should raise_error(ArgumentError)
+ ScratchPad.recorded.should == []
+ end
- it "does not reject non-symbol keys in keyword arguments with required argument" do
- h = {1 => 2, 3 => 4}
- @o.rb_scan_args([1, h], "k1:", 2, @acc).should == 1
- ScratchPad.recorded.should == [1, h]
+ it "rejects required and non-keyword arguments" do
+ h = {1 => 2, 3 => 4}
+ -> {
+ suppress_warning do
+ @o.rb_scan_args([1, h], "k1:", 2, @acc)
+ end
+ }.should raise_error(ArgumentError)
+ ScratchPad.recorded.should == []
+ end
+
+ it "considers the hash as a post argument when there is a splat" do
+ h = {1 => 2, 3 => 4}
+ suppress_warning do
+ @o.rb_scan_args([1, 2, 3, 4, 5, h], "k11*1:&", 6, @acc, &@prc).should == 6
+ end
+ ScratchPad.recorded.should == [1, 2, [3, 4, 5], h, nil, @prc]
+ end
end
- it "considers keyword arguments with non-symbol keys as keywords when using splat and post arguments" do
- h = {1 => 2, 3 => 4}
- @o.rb_scan_args([1, 2, 3, 4, 5, h], "k11*1:&", 6, @acc, &@prc).should == 5
- ScratchPad.recorded.should == [1, 2, [3, 4], 5, h, @prc]
+ ruby_version_is '3.0' do
+ it "does not reject non-symbol keys in keyword arguments" do
+ h = {1 => 2, 3 => 4}
+ @o.rb_scan_args([h], "k0:", 1, @acc).should == 0
+ ScratchPad.recorded.should == [h]
+ end
+
+ it "does not reject non-symbol keys in keyword arguments with required argument" do
+ h = {1 => 2, 3 => 4}
+ @o.rb_scan_args([1, h], "k1:", 2, @acc).should == 1
+ ScratchPad.recorded.should == [1, h]
+ end
+
+ it "considers keyword arguments with non-symbol keys as keywords when using splat and post arguments" do
+ h = {1 => 2, 3 => 4}
+ @o.rb_scan_args([1, 2, 3, 4, 5, h], "k11*1:&", 6, @acc, &@prc).should == 5
+ ScratchPad.recorded.should == [1, 2, [3, 4], 5, h, @prc]
+ end
end
end
diff --git a/spec/ruby/security/cve_2014_8080_spec.rb b/spec/ruby/security/cve_2014_8080_spec.rb
new file mode 100644
index 0000000000..23770f94b1
--- /dev/null
+++ b/spec/ruby/security/cve_2014_8080_spec.rb
@@ -0,0 +1,34 @@
+require_relative '../spec_helper'
+
+ruby_version_is ''...'3.0' do
+ require 'rexml/document'
+
+ describe "REXML::Document.new" do
+
+ it "resists CVE-2014-8080 by raising an exception when entity expansion has grown too large" do
+ xml = <<XML
+ <?xml version="1.0" encoding="UTF-8" ?>
+ <!DOCTYPE x [
+ <!ENTITY % x0 "xxxxxxxxxx">
+ <!ENTITY % x1 "%x0;%x0;%x0;%x0;%x0;%x0;%x0;%x0;%x0;%x0;">
+ <!ENTITY % x2 "%x1;%x1;%x1;%x1;%x1;%x1;%x1;%x1;%x1;%x1;">
+ <!ENTITY % x3 "%x2;%x2;%x2;%x2;%x2;%x2;%x2;%x2;%x2;%x2;">
+ <!ENTITY % x4 "%x3;%x3;%x3;%x3;%x3;%x3;%x3;%x3;%x3;%x3;">
+ <!ENTITY % x5 "%x4;%x4;%x4;%x4;%x4;%x4;%x4;%x4;%x4;%x4;">
+ <!ENTITY % x6 "%x5;%x5;%x5;%x5;%x5;%x5;%x5;%x5;%x5;%x5;">
+ <!ENTITY % x7 "%x6;%x6;%x6;%x6;%x6;%x6;%x6;%x6;%x6;%x6;">
+ <!ENTITY % x8 "%x7;%x7;%x7;%x7;%x7;%x7;%x7;%x7;%x7;%x7;">
+ <!ENTITY % x9 "%x8;%x8;%x8;%x8;%x8;%x8;%x8;%x8;%x8;%x8;">
+ ]>
+ <x>
+ %x9;%x9;%x9;%x9;%x9;%x9;%x9;%x9;%x9;%x9;
+ </x>
+XML
+
+ -> {
+ REXML::Document.new(xml).doctype.entities['x9'].value
+ }.should raise_error(REXML::ParseException, /entity expansion has grown too large/)
+ end
+
+ end
+end
diff --git a/spec/ruby/security/cve_2017_17742_spec.rb b/spec/ruby/security/cve_2017_17742_spec.rb
new file mode 100644
index 0000000000..b0d93e42b8
--- /dev/null
+++ b/spec/ruby/security/cve_2017_17742_spec.rb
@@ -0,0 +1,37 @@
+require_relative '../spec_helper'
+
+# webrick is no longer in stdlib in Ruby 3+
+ruby_version_is ""..."3.0" do
+ require "webrick"
+ require "stringio"
+ require "net/http"
+
+ describe "WEBrick" do
+ describe "resists CVE-2017-17742" do
+ it "for a response splitting headers" do
+ config = WEBrick::Config::HTTP
+ res = WEBrick::HTTPResponse.new config
+ res['X-header'] = "malicious\r\nCookie: hack"
+ io = StringIO.new
+ res.send_response io
+ io.rewind
+ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io))
+ res.code.should == '500'
+ io.string.should_not =~ /hack/
+ end
+
+ it "for a response splitting cookie headers" do
+ user_input = "malicious\r\nCookie: hack"
+ config = WEBrick::Config::HTTP
+ res = WEBrick::HTTPResponse.new config
+ res.cookies << WEBrick::Cookie.new('author', user_input)
+ io = StringIO.new
+ res.send_response io
+ io.rewind
+ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io))
+ res.code.should == '500'
+ io.string.should_not =~ /hack/
+ end
+ end
+ end
+end
diff --git a/spec/ruby/security/cve_2019_8323_spec.rb b/spec/ruby/security/cve_2019_8323_spec.rb
index 49a31a6682..d4606de054 100644
--- a/spec/ruby/security/cve_2019_8323_spec.rb
+++ b/spec/ruby/security/cve_2019_8323_spec.rb
@@ -11,12 +11,7 @@ describe "CVE-2019-8323 is resisted by" do
cutter = Class.new {
include Gem::GemcutterUtilities
}.new
- klass = if defined?(Gem::Net::HTTPSuccess)
- Gem::Net::HTTPSuccess
- else
- Net::HTTPSuccess
- end
- response = klass.new(nil, nil, nil)
+ response = Net::HTTPSuccess.new(nil, nil, nil)
def response.body
"\e]2;nyan\a"
end
@@ -30,12 +25,7 @@ describe "CVE-2019-8323 is resisted by" do
}.new
def cutter.terminate_interaction(n)
end
- klass = if defined?(Gem::Net::HTTPNotFound)
- Gem::Net::HTTPNotFound
- else
- Net::HTTPNotFound
- end
- response = klass.new(nil, nil, nil)
+ response = Net::HTTPNotFound.new(nil, nil, nil)
def response.body
"\e]2;nyan\a"
end
diff --git a/spec/ruby/shared/file/exist.rb b/spec/ruby/shared/file/exist.rb
index 67424146c5..3bd97711b4 100644
--- a/spec/ruby/shared/file/exist.rb
+++ b/spec/ruby/shared/file/exist.rb
@@ -4,6 +4,11 @@ describe :file_exist, shared: true do
@object.send(@method, 'a_fake_file').should == false
end
+ it "returns true if the file exist using the alias exists?" do
+ @object.send(@method, __FILE__).should == true
+ @object.send(@method, 'a_fake_file').should == false
+ end
+
it "raises an ArgumentError if not passed one argument" do
-> { @object.send(@method) }.should raise_error(ArgumentError)
-> { @object.send(@method, __FILE__, __FILE__) }.should raise_error(ArgumentError)
diff --git a/spec/ruby/shared/kernel/at_exit.rb b/spec/ruby/shared/kernel/at_exit.rb
deleted file mode 100644
index 26ad361a5b..0000000000
--- a/spec/ruby/shared/kernel/at_exit.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-describe :kernel_at_exit, shared: true do
- it "runs after all other code" do
- ruby_exe("#{@method} { print 5 }; print 6").should == "65"
- end
-
- it "runs in reverse order of registration" do
- code = "#{@method} { print 4 }; #{@method} { print 5 }; print 6; #{@method} { print 7 }"
- ruby_exe(code).should == "6754"
- end
-
- it "allows calling exit inside a handler" do
- code = "#{@method} { print 3 }; #{@method} { print 4; exit; print 5 }; #{@method} { print 6 }"
- ruby_exe(code).should == "643"
- end
-
- it "gives access to the last raised exception - global variables $! and $@" do
- code = <<-EOC
- #{@method} {
- puts "The exception matches: \#{$! == $exception && $@ == $exception.backtrace} (message=\#{$!.message})"
- }
-
- begin
- raise "foo"
- rescue => $exception
- raise
- end
- EOC
-
- result = ruby_exe(code, args: "2>&1", exit_status: 1)
- result.lines.should.include?("The exception matches: true (message=foo)\n")
- end
-
- it "both exceptions in a handler and in the main script are printed" do
- code = "#{@method} { raise 'at_exit_error' }; raise 'main_script_error'"
- result = ruby_exe(code, args: "2>&1", exit_status: 1)
- result.should.include?('at_exit_error (RuntimeError)')
- result.should.include?('main_script_error (RuntimeError)')
- end
-
- it "decides the exit status if both at_exit and the main script raise SystemExit" do
- ruby_exe("#{@method} { exit 43 }; exit 42", args: "2>&1", exit_status: 43)
- $?.exitstatus.should == 43
- end
-
- it "runs all handlers even if some raise exceptions" do
- code = "#{@method} { STDERR.puts 'last' }; #{@method} { exit 43 }; #{@method} { STDERR.puts 'first' }; exit 42"
- result = ruby_exe(code, args: "2>&1", exit_status: 43)
- result.should == "first\nlast\n"
- $?.exitstatus.should == 43
- end
-
- it "runs handlers even if the main script fails to parse" do
- script = fixture(__FILE__, "#{@method}.rb")
- result = ruby_exe('{', options: "-r#{script}", args: "2>&1", exit_status: 1)
- $?.should_not.success?
- result.should.include?("handler ran\n")
- result.should.include?("syntax error")
- end
-
- it "calls the nested handler right after the outer one if a handler is nested into another handler" do
- ruby_exe(<<~ruby).should == "last\nbefore\nafter\nnested\nfirst\n"
- #{@method} { puts :first }
- #{@method} { puts :before; #{@method} { puts :nested }; puts :after };
- #{@method} { puts :last }
- ruby
- end
-end
diff --git a/spec/ruby/shared/kernel/fixtures/END.rb b/spec/ruby/shared/kernel/fixtures/END.rb
deleted file mode 100644
index cc8ac17c36..0000000000
--- a/spec/ruby/shared/kernel/fixtures/END.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-END {
- STDERR.puts "handler ran"
-}
diff --git a/spec/ruby/shared/kernel/fixtures/at_exit.rb b/spec/ruby/shared/kernel/fixtures/at_exit.rb
deleted file mode 100644
index e7bc8baf52..0000000000
--- a/spec/ruby/shared/kernel/fixtures/at_exit.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-at_exit do
- STDERR.puts "handler ran"
-end
diff --git a/spec/ruby/shared/process/exit.rb b/spec/ruby/shared/process/exit.rb
index 1e073614a3..7d901f1f1e 100644
--- a/spec/ruby/shared/process/exit.rb
+++ b/spec/ruby/shared/process/exit.rb
@@ -104,12 +104,6 @@ describe :process_exit!, shared: true do
$?.exitstatus.should == 21
end
- it "skips ensure clauses" do
- out = ruby_exe("begin; STDERR.puts 'before'; #{@object}.send(:exit!, 21); ensure; STDERR.puts 'ensure'; end", args: '2>&1', exit_status: 21)
- out.should == "before\n"
- $?.exitstatus.should == 21
- end
-
it "overrides the original exception and exit status when called from #at_exit" do
code = <<-RUBY
at_exit do
diff --git a/spec/ruby/shared/queue/deque.rb b/spec/ruby/shared/queue/deque.rb
index 9e6b45009d..616e56ec8a 100644
--- a/spec/ruby/shared/queue/deque.rb
+++ b/spec/ruby/shared/queue/deque.rb
@@ -37,15 +37,6 @@ describe :queue_deq, shared: true do
q.send(@method).should == 1
end
- it "converts false-ish for non_blocking to boolean" do
- q = @object.call
- q << 1
- q << 2
-
- q.send(@method, false).should == 1
- q.send(@method, nil).should == 2
- end
-
it "returns nil for a closed empty queue" do
q = @object.call
q.close
@@ -123,12 +114,6 @@ describe :queue_deq, shared: true do
"can't set a timeout if non_block is enabled",
)
end
-
- it "returns nil for a closed empty queue" do
- q = @object.call
- q.close
- q.send(@method, timeout: 0).should == nil
- end
end
end
@@ -158,13 +143,5 @@ describe :queue_deq, shared: true do
q.close
-> { q.send(@method, true) }.should raise_error(ThreadError)
end
-
- it "converts true-ish non_blocking argument to true" do
- q = @object.call
-
- -> { q.send(@method, true) }.should raise_error(ThreadError)
- -> { q.send(@method, 1) }.should raise_error(ThreadError)
- -> { q.send(@method, "") }.should raise_error(ThreadError)
- end
end
end
diff --git a/spec/ruby/shared/rational/Rational.rb b/spec/ruby/shared/rational/Rational.rb
index 500f7ed271..2dc49c869c 100644
--- a/spec/ruby/shared/rational/Rational.rb
+++ b/spec/ruby/shared/rational/Rational.rb
@@ -85,11 +85,6 @@ describe :kernel_Rational, shared: true do
end
end
- it "raises a ZeroDivisionError if the second argument is 0" do
- -> { Rational(1, 0) }.should raise_error(ZeroDivisionError, "divided by 0")
- -> { Rational(1, 0.0) }.should raise_error(ZeroDivisionError, "divided by 0")
- end
-
it "raises a TypeError if the first argument is nil" do
-> { Rational(nil) }.should raise_error(TypeError)
end
@@ -143,8 +138,4 @@ describe :kernel_Rational, shared: true do
end
end
end
-
- it "freezes its result" do
- Rational(1).frozen?.should == true
- end
end
diff --git a/spec/ruby/shared/rational/marshal_dump.rb b/spec/ruby/shared/rational/marshal_dump.rb
new file mode 100644
index 0000000000..09782b45a5
--- /dev/null
+++ b/spec/ruby/shared/rational/marshal_dump.rb
@@ -0,0 +1,5 @@
+require_relative '../../spec_helper'
+
+describe :rational_marshal_dump, shared: true do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/shared/rational/marshal_load.rb b/spec/ruby/shared/rational/marshal_load.rb
new file mode 100644
index 0000000000..20bdd6fdf4
--- /dev/null
+++ b/spec/ruby/shared/rational/marshal_load.rb
@@ -0,0 +1,5 @@
+require_relative '../../spec_helper'
+
+describe :rational_marshal_load, shared: true do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/shared/rational/quo.rb b/spec/ruby/shared/rational/quo.rb
new file mode 100644
index 0000000000..53b32fed2f
--- /dev/null
+++ b/spec/ruby/shared/rational/quo.rb
@@ -0,0 +1,5 @@
+require_relative '../../spec_helper'
+
+describe :rational_quo, shared: true do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/shared/rational/truncate.rb b/spec/ruby/shared/rational/truncate.rb
index df5198ca02..761dd3113a 100644
--- a/spec/ruby/shared/rational/truncate.rb
+++ b/spec/ruby/shared/rational/truncate.rb
@@ -17,18 +17,6 @@ describe :rational_truncate, shared: true do
end
end
- describe "with an explicit precision = 0" do
- it "returns an integer" do
- @rational.truncate(0).should be_kind_of(Integer)
- end
-
- it "returns the truncated value toward 0" do
- @rational.truncate(0).should == 314
- Rational(1, 2).truncate(0).should == 0
- Rational(-1, 2).truncate(0).should == 0
- end
- end
-
describe "with a precision < 0" do
it "returns an integer" do
@rational.truncate(-2).should be_kind_of(Integer)
@@ -54,18 +42,4 @@ describe :rational_truncate, shared: true do
@rational.truncate(3).should == Rational(62857, 200)
end
end
-
- describe "with an invalid value for precision" do
- it "raises a TypeError" do
- -> { @rational.truncate(nil) }.should raise_error(TypeError, "not an integer")
- -> { @rational.truncate(1.0) }.should raise_error(TypeError, "not an integer")
- -> { @rational.truncate('') }.should raise_error(TypeError, "not an integer")
- end
-
- it "does not call to_int on the argument" do
- object = Object.new
- object.should_not_receive(:to_int)
- -> { @rational.truncate(object) }.should raise_error(TypeError, "not an integer")
- end
- end
end
diff --git a/spec/ruby/shared/sizedqueue/enque.rb b/spec/ruby/shared/sizedqueue/enque.rb
index 6307f3c3ca..059f1025a7 100644
--- a/spec/ruby/shared/sizedqueue/enque.rb
+++ b/spec/ruby/shared/sizedqueue/enque.rb
@@ -37,7 +37,7 @@ describe :sizedqueue_enq, shared: true do
q << 1
t = Thread.new {
- -> { q.send(@method, 2) }.should raise_error(ClosedQueueError, "queue closed")
+ -> { q.send(@method, 2) }.should raise_error(ClosedQueueError)
}
Thread.pass until q.num_waiting == 1
@@ -73,7 +73,7 @@ describe :sizedqueue_enq, shared: true do
t.join
end
- it "returns nil if no space is available and timeout is 0" do
+ it "returns nil if no space is avialable and timeout is 0" do
q = @object.call(1)
q.send(@method, 1, timeout: 0).should == q
q.send(@method, 2, timeout: 0).should == nil
@@ -108,28 +108,6 @@ describe :sizedqueue_enq, shared: true do
"can't set a timeout if non_block is enabled",
)
end
-
- it "raise ClosedQueueError when closed before enqueued" do
- q = @object.call(1)
- q.close
- -> { q.send(@method, 2, timeout: 1) }.should raise_error(ClosedQueueError, "queue closed")
- end
-
- it "interrupts enqueuing threads with ClosedQueueError when the queue is closed" do
- q = @object.call(1)
- q << 1
-
- t = Thread.new {
- -> { q.send(@method, 1, timeout: 10) }.should raise_error(ClosedQueueError, "queue closed")
- }
-
- Thread.pass until q.num_waiting == 1
-
- q.close
-
- t.join
- q.pop.should == 1
- end
end
end
end
diff --git a/spec/ruby/shared/string/start_with.rb b/spec/ruby/shared/string/start_with.rb
index 4b947a3bbf..6932a017b6 100644
--- a/spec/ruby/shared/string/start_with.rb
+++ b/spec/ruby/shared/string/start_with.rb
@@ -70,15 +70,7 @@ describe :start_with, shared: true do
$1.should be_nil
end
- ruby_version_is ""..."3.3" do
- it "does not check that we are not matching part of a character" do
- "\xC3\xA9".send(@method).should.start_with?("\xC3")
- end
- end
-
- ruby_version_is "3.3" do # #19784
- it "checks that we are not matching part of a character" do
- "\xC3\xA9".send(@method).should_not.start_with?("\xC3")
- end
+ it "does not check that we are not matching part of a character" do
+ "\xC3\xA9".send(@method).should.start_with?("\xC3")
end
end
diff --git a/spec/ruby/shared/string/times.rb b/spec/ruby/shared/string/times.rb
index be3b622f73..8ca9507570 100644
--- a/spec/ruby/shared/string/times.rb
+++ b/spec/ruby/shared/string/times.rb
@@ -32,10 +32,20 @@ describe :string_times, shared: true do
@object.call("", max_long).should == ""
end
- it "returns String instances" do
- @object.call(MyString.new("cool"), 0).should be_an_instance_of(String)
- @object.call(MyString.new("cool"), 1).should be_an_instance_of(String)
- @object.call(MyString.new("cool"), 2).should be_an_instance_of(String)
+ ruby_version_is ''...'3.0' do
+ it "returns subclass instances" do
+ @object.call(MyString.new("cool"), 0).should be_an_instance_of(MyString)
+ @object.call(MyString.new("cool"), 1).should be_an_instance_of(MyString)
+ @object.call(MyString.new("cool"), 2).should be_an_instance_of(MyString)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns String instances" do
+ @object.call(MyString.new("cool"), 0).should be_an_instance_of(String)
+ @object.call(MyString.new("cool"), 1).should be_an_instance_of(String)
+ @object.call(MyString.new("cool"), 2).should be_an_instance_of(String)
+ end
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/shared/types/rb_num2dbl_fails.rb b/spec/ruby/shared/types/rb_num2dbl_fails.rb
deleted file mode 100644
index ec7cc11986..0000000000
--- a/spec/ruby/shared/types/rb_num2dbl_fails.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Shared tests for rb_num2dbl related conversion failures.
-#
-# Usage example:
-# it_behaves_like :rb_num2dbl_fails, nil, -> v { o = A.new; o.foo(v) }
-#
-
-describe :rb_num2dbl_fails, shared: true do
- it "fails if string is provided" do
- -> { @object.call("123") }.should raise_error(TypeError, "no implicit conversion to float from string")
- end
-
- it "fails if boolean is provided" do
- -> { @object.call(true) }.should raise_error(TypeError, "no implicit conversion to float from true")
- -> { @object.call(false) }.should raise_error(TypeError, "no implicit conversion to float from false")
- end
-end
diff --git a/spec/ruby/spec_helper.rb b/spec/ruby/spec_helper.rb
index af1c385878..3404521c03 100644
--- a/spec/ruby/spec_helper.rb
+++ b/spec/ruby/spec_helper.rb
@@ -1,5 +1,5 @@
use_realpath = File.respond_to?(:realpath)
-root = __dir__
+root = File.dirname(__FILE__)
dir = "fixtures/code"
CODE_LOADING_DIR = use_realpath ? File.realpath(dir, root) : File.expand_path(dir, root)
diff --git a/spec/syntax_suggest/integration/ruby_command_line_spec.rb b/spec/syntax_suggest/integration/ruby_command_line_spec.rb
index c1ec4be54e..b41a4c86e3 100644
--- a/spec/syntax_suggest/integration/ruby_command_line_spec.rb
+++ b/spec/syntax_suggest/integration/ruby_command_line_spec.rb
@@ -9,7 +9,7 @@ module SyntaxSuggest
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
- script.write <<~EOM
+ script.write <<~'EOM'
puts Kernel.private_methods
EOM
@@ -159,7 +159,7 @@ module SyntaxSuggest
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
- script.write <<~EOM
+ script.write <<~'EOM'
$stderr = STDOUT
eval("def lol")
EOM
@@ -167,7 +167,7 @@ module SyntaxSuggest
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest #{script} 2>&1`
expect($?.success?).to be_falsey
- expect(out).to match(/\(eval.*\):1/)
+ expect(out).to include("(eval):1")
expect(out).to_not include("SyntaxSuggest")
expect(out).to_not include("Could not find filename")
@@ -178,7 +178,7 @@ module SyntaxSuggest
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
- script.write <<~EOM
+ script.write <<~'EOM'
break
EOM
diff --git a/spec/syntax_suggest/integration/syntax_suggest_spec.rb b/spec/syntax_suggest/integration/syntax_suggest_spec.rb
index 9071d37c1b..64dafabcdd 100644
--- a/spec/syntax_suggest/integration/syntax_suggest_spec.rb
+++ b/spec/syntax_suggest/integration/syntax_suggest_spec.rb
@@ -26,7 +26,7 @@ module SyntaxSuggest
debug_display(io.string)
debug_display(benchmark)
- expect(io.string).to include(<<~EOM)
+ expect(io.string).to include(<<~'EOM')
6 class SyntaxTree < Ripper
170 def self.parse(source)
174 end
@@ -54,7 +54,7 @@ module SyntaxSuggest
end
expect(io.string).to_not include("def ruby_install_binstub_path")
- expect(io.string).to include(<<~EOM)
+ expect(io.string).to include(<<~'EOM')
> 1067 def add_yarn_binary
> 1068 return [] if yarn_preinstalled?
> 1069 |
@@ -72,7 +72,7 @@ module SyntaxSuggest
)
debug_display(io.string)
- expect(io.string).to include(<<~EOM)
+ expect(io.string).to include(<<~'EOM')
1 Rails.application.routes.draw do
> 113 namespace :admin do
> 116 match "/foobar(*path)", via: :all, to: redirect { |_params, req|
@@ -91,7 +91,7 @@ module SyntaxSuggest
)
debug_display(io.string)
- expect(io.string).to include(<<~EOM)
+ expect(io.string).to include(<<~'EOM')
1 describe "webmock tests" do
22 it "body" do
27 query = Cutlass::FunctionQuery.new(
@@ -113,7 +113,7 @@ module SyntaxSuggest
)
debug_display(io.string)
- expect(io.string).to include(<<~EOM)
+ expect(io.string).to include(<<~'EOM')
5 module DerailedBenchmarks
6 class RequireTree
> 13 def initialize(name)
@@ -166,7 +166,7 @@ module SyntaxSuggest
end
it "ambiguous end" do
- source = <<~EOM
+ source = <<~'EOM'
def call # 0
print "lol" # 1
end # one # 2
@@ -186,7 +186,7 @@ module SyntaxSuggest
end
it "simple regression" do
- source = <<~EOM
+ source = <<~'EOM'
class Dog
def bark
puts "woof"
@@ -206,7 +206,7 @@ module SyntaxSuggest
end
it "empty else" do
- source = <<~EOM
+ source = <<~'EOM'
class Foo
def foo
if cond?
diff --git a/spec/syntax_suggest/unit/api_spec.rb b/spec/syntax_suggest/unit/api_spec.rb
index e900b9e10b..079a91e46d 100644
--- a/spec/syntax_suggest/unit/api_spec.rb
+++ b/spec/syntax_suggest/unit/api_spec.rb
@@ -8,12 +8,6 @@ end
module SyntaxSuggest
RSpec.describe "Top level SyntaxSuggest api" do
- it "doesn't load prism if env var is set" do
- skip("SYNTAX_SUGGEST_DISABLE_PRISM not set") unless ENV["SYNTAX_SUGGEST_DISABLE_PRISM"]
-
- expect(SyntaxSuggest.use_prism_parser?).to be_falsey
- end
-
it "has a `handle_error` interface" do
fake_error = Object.new
def fake_error.message
diff --git a/spec/syntax_suggest/unit/around_block_scan_spec.rb b/spec/syntax_suggest/unit/around_block_scan_spec.rb
index 6c940a5919..d6756448bd 100644
--- a/spec/syntax_suggest/unit/around_block_scan_spec.rb
+++ b/spec/syntax_suggest/unit/around_block_scan_spec.rb
@@ -5,7 +5,7 @@ require_relative "../spec_helper"
module SyntaxSuggest
RSpec.describe AroundBlockScan do
it "continues scan from last location even if scan is false" do
- source = <<~EOM
+ source = <<~'EOM'
print 'omg'
print 'lol'
print 'haha'
diff --git a/spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb b/spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb
index 09f8d90d33..02d9be4387 100644
--- a/spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb
+++ b/spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb
@@ -5,7 +5,7 @@ require_relative "../../spec_helper"
module SyntaxSuggest
RSpec.describe Capture::BeforeAfterKeywordEnds do
it "before after keyword ends" do
- source = <<~EOM
+ source = <<~'EOM'
def nope
print 'not me'
end
@@ -36,7 +36,7 @@ module SyntaxSuggest
).call
lines.sort!
- expect(lines.join).to include(<<~EOM)
+ expect(lines.join).to include(<<~'EOM')
def lol
end
def yolo
diff --git a/spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb b/spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb
index ed2265539a..61d1642d97 100644
--- a/spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb
+++ b/spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb
@@ -5,7 +5,7 @@ require_relative "../../spec_helper"
module SyntaxSuggest
RSpec.describe Capture::FallingIndentLines do
it "on_falling_indent" do
- source = <<~EOM
+ source = <<~'EOM'
class OH
def lol
print 'lol
@@ -33,7 +33,7 @@ module SyntaxSuggest
end
lines.sort!
- expect(lines.join).to eq(<<~EOM)
+ expect(lines.join).to eq(<<~'EOM')
class OH
def hello
end
diff --git a/spec/syntax_suggest/unit/capture_code_context_spec.rb b/spec/syntax_suggest/unit/capture_code_context_spec.rb
index d9379d0ce7..46f13e8961 100644
--- a/spec/syntax_suggest/unit/capture_code_context_spec.rb
+++ b/spec/syntax_suggest/unit/capture_code_context_spec.rb
@@ -5,7 +5,7 @@ require_relative "../spec_helper"
module SyntaxSuggest
RSpec.describe CaptureCodeContext do
it "capture_before_after_kws two" do
- source = <<~EOM
+ source = <<~'EOM'
class OH
def hello
@@ -23,7 +23,7 @@ module SyntaxSuggest
code_lines: code_lines
)
display.capture_before_after_kws(block)
- expect(display.sorted_lines.join).to eq(<<~EOM.indent(2))
+ expect(display.sorted_lines.join).to eq(<<~'EOM'.indent(2))
def hello
def hai
end
@@ -31,7 +31,7 @@ module SyntaxSuggest
end
it "capture_before_after_kws" do
- source = <<~EOM
+ source = <<~'EOM'
def sit
end
@@ -50,7 +50,7 @@ module SyntaxSuggest
)
lines = display.capture_before_after_kws(block).sort
- expect(lines.join).to eq(<<~EOM)
+ expect(lines.join).to eq(<<~'EOM')
def sit
end
def bark
@@ -60,7 +60,7 @@ module SyntaxSuggest
end
it "handles ambiguous end" do
- source = <<~EOM
+ source = <<~'EOM'
def call # 0
print "lol" # 1
end # one # 2
@@ -79,7 +79,7 @@ module SyntaxSuggest
lines = lines.sort.map(&:original)
- expect(lines.join).to eq(<<~EOM)
+ expect(lines.join).to eq(<<~'EOM')
def call # 0
end # one # 2
end # two # 3
@@ -94,7 +94,7 @@ module SyntaxSuggest
code_lines = CleanDocument.new(source: source).call.lines
code_lines[0..75].each(&:mark_invisible)
- code_lines[77..].each(&:mark_invisible)
+ code_lines[77..-1].each(&:mark_invisible)
expect(code_lines.join.strip).to eq("class Lookups")
block = CodeBlock.new(lines: code_lines[76..149])
@@ -106,7 +106,7 @@ module SyntaxSuggest
lines = display.call
lines = lines.sort.map(&:original)
- expect(lines.join).to include(<<~EOM.indent(2))
+ expect(lines.join).to include(<<~'EOM'.indent(2))
class Lookups
def format_requires
end
@@ -114,7 +114,7 @@ module SyntaxSuggest
end
it "shows ends of captured block" do
- source = <<~EOM
+ source = <<~'EOM'
class Dog
def bark
puts "woof"
@@ -123,7 +123,7 @@ module SyntaxSuggest
code_lines = CleanDocument.new(source: source).call.lines
block = CodeBlock.new(lines: code_lines)
- code_lines[1..].each(&:mark_invisible)
+ code_lines[1..-1].each(&:mark_invisible)
expect(block.to_s.strip).to eq("class Dog")
@@ -132,7 +132,7 @@ module SyntaxSuggest
code_lines: code_lines
)
lines = display.call.sort.map(&:original)
- expect(lines.join).to eq(<<~EOM)
+ expect(lines.join).to eq(<<~'EOM')
class Dog
def bark
end
@@ -140,7 +140,7 @@ module SyntaxSuggest
end
it "captures surrounding context on falling indent" do
- source = <<~EOM
+ source = <<~'EOM'
class Blerg
end
@@ -164,7 +164,7 @@ module SyntaxSuggest
code_lines: code_lines
)
lines = display.call.sort.map(&:original)
- expect(lines.join).to eq(<<~EOM)
+ expect(lines.join).to eq(<<~'EOM')
class OH
def hello
it "foo" do
@@ -174,7 +174,7 @@ module SyntaxSuggest
end
it "captures surrounding context on same indent" do
- source = <<~EOM
+ source = <<~'EOM'
class Blerg
end
class OH
@@ -200,7 +200,7 @@ module SyntaxSuggest
code_lines = CleanDocument.new(source: source).call.lines
block = CodeBlock.new(lines: code_lines[7..10])
- expect(block.to_s).to eq(<<~EOM.indent(2))
+ expect(block.to_s).to eq(<<~'EOM'.indent(2))
def lol
end
@@ -217,7 +217,7 @@ module SyntaxSuggest
lines: lines
).call
- expect(out).to eq(<<~EOM.indent(2))
+ expect(out).to eq(<<~'EOM'.indent(2))
3 class OH
8 def lol
9 end
diff --git a/spec/syntax_suggest/unit/clean_document_spec.rb b/spec/syntax_suggest/unit/clean_document_spec.rb
index c531c199b1..25a62e4454 100644
--- a/spec/syntax_suggest/unit/clean_document_spec.rb
+++ b/spec/syntax_suggest/unit/clean_document_spec.rb
@@ -8,7 +8,7 @@ module SyntaxSuggest
source = fixtures_dir.join("this_project_extra_def.rb.txt").read
code_lines = CleanDocument.new(source: source).call.lines
- expect(code_lines[18 - 1].to_s).to eq(<<-EOL)
+ expect(code_lines[18 - 1].to_s).to eq(<<-'EOL')
@io.puts <<~EOM
SyntaxSuggest: A syntax error was detected
@@ -54,7 +54,7 @@ module SyntaxSuggest
DisplayCodeWithLineNumbers.new(
lines: lines
).call
- ).to eq(<<~EOM.indent(2))
+ ).to eq(<<~'EOM'.indent(2))
1 User
2 .where(name: 'schneems')
3 .first
@@ -65,7 +65,7 @@ module SyntaxSuggest
lines: lines,
highlight_lines: lines[0]
).call
- ).to eq(<<~EOM)
+ ).to eq(<<~'EOM')
> 1 User
> 2 .where(name: 'schneems')
> 3 .first
@@ -85,7 +85,7 @@ module SyntaxSuggest
code_lines = doc.lines
expect(code_lines[0].to_s.count($/)).to eq(5)
- code_lines[1..].each do |line|
+ code_lines[1..-1].each do |line|
expect(line.to_s.strip.length).to eq(0)
end
end
diff --git a/spec/syntax_suggest/unit/code_line_spec.rb b/spec/syntax_suggest/unit/code_line_spec.rb
index 5b62cc2757..d5b568fd19 100644
--- a/spec/syntax_suggest/unit/code_line_spec.rb
+++ b/spec/syntax_suggest/unit/code_line_spec.rb
@@ -5,7 +5,7 @@ require_relative "../spec_helper"
module SyntaxSuggest
RSpec.describe CodeLine do
it "bug in keyword detection" do
- lines = CodeLine.from_source(<<~EOM)
+ lines = CodeLine.from_source(<<~'EOM')
def to_json(*opts)
{
type: :module,
@@ -19,7 +19,7 @@ module SyntaxSuggest
it "supports endless method definitions" do
skip("Unsupported ruby version") unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3")
- line = CodeLine.from_source(<<~EOM).first
+ line = CodeLine.from_source(<<~'EOM').first
def square(x) = x * x
EOM
@@ -28,7 +28,7 @@ module SyntaxSuggest
end
it "retains original line value, after being marked invisible" do
- line = CodeLine.from_source(<<~EOM).first
+ line = CodeLine.from_source(<<~'EOM').first
puts "lol"
EOM
expect(line.line).to match('puts "lol"')
@@ -38,7 +38,7 @@ module SyntaxSuggest
end
it "knows which lines can be joined" do
- code_lines = CodeLine.from_source(<<~EOM)
+ code_lines = CodeLine.from_source(<<~'EOM')
user = User.
where(name: 'schneems').
first
@@ -50,7 +50,7 @@ module SyntaxSuggest
end
it "trailing if" do
- code_lines = CodeLine.from_source(<<~EOM)
+ code_lines = CodeLine.from_source(<<~'EOM')
puts "lol" if foo
if foo
end
@@ -60,7 +60,7 @@ module SyntaxSuggest
end
it "trailing unless" do
- code_lines = CodeLine.from_source(<<~EOM)
+ code_lines = CodeLine.from_source(<<~'EOM')
puts "lol" unless foo
unless foo
end
diff --git a/spec/syntax_suggest/unit/code_search_spec.rb b/spec/syntax_suggest/unit/code_search_spec.rb
index 502de14d7f..f836ba36f3 100644
--- a/spec/syntax_suggest/unit/code_search_spec.rb
+++ b/spec/syntax_suggest/unit/code_search_spec.rb
@@ -12,13 +12,13 @@ module SyntaxSuggest
search = CodeSearch.new(source)
search.call
- expect(search.invalid_blocks.join.strip).to eq(<<~EOM.strip)
+ expect(search.invalid_blocks.join.strip).to eq(<<~'EOM'.strip)
class Lookups
EOM
end
it "squished do regression" do
- source = <<~EOM
+ source = <<~'EOM'
def call
trydo
@@ -47,14 +47,14 @@ module SyntaxSuggest
search = CodeSearch.new(source)
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
trydo
end # one
EOM
end
it "regression test ambiguous end" do
- source = <<~EOM
+ source = <<~'EOM'
def call # 0
print "lol" # 1
end # one # 2
@@ -64,13 +64,13 @@ module SyntaxSuggest
search = CodeSearch.new(source)
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
end # two # 3
EOM
end
it "regression dog test" do
- source = <<~EOM
+ source = <<~'EOM'
class Dog
def bark
puts "woof"
@@ -79,7 +79,7 @@ module SyntaxSuggest
search = CodeSearch.new(source)
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
class Dog
EOM
expect(search.invalid_blocks.first.lines.length).to eq(4)
@@ -99,7 +99,7 @@ module SyntaxSuggest
search = CodeSearch.new(source)
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
Foo.call do |a
end # one
EOM
@@ -118,7 +118,7 @@ module SyntaxSuggest
search = CodeSearch.new(source)
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
Foo.call do {
EOM
end
@@ -152,7 +152,7 @@ module SyntaxSuggest
end
it "handles no spaces between blocks" do
- source = <<~EOM
+ source = <<~'EOM'
context "foo bar" do
it "bars the foo" do
travel_to DateTime.new(2020, 10, 1, 10, 0, 0) do
@@ -172,7 +172,7 @@ module SyntaxSuggest
it "records debugging steps to a directory" do
Dir.mktmpdir do |dir|
dir = Pathname(dir)
- search = CodeSearch.new(<<~EOM, record_dir: dir)
+ search = CodeSearch.new(<<~'EOM', record_dir: dir)
class OH
def hello
def hai
@@ -193,7 +193,7 @@ module SyntaxSuggest
end
it "def with missing end" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
class OH
def hello
@@ -206,7 +206,7 @@ module SyntaxSuggest
expect(search.invalid_blocks.join.strip).to eq("def hello")
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
class OH
def hello
@@ -218,7 +218,7 @@ module SyntaxSuggest
expect(search.invalid_blocks.join.strip).to eq("def hello")
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
class OH
def hello
def hai
@@ -227,7 +227,7 @@ module SyntaxSuggest
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
def hello
EOM
end
@@ -244,13 +244,13 @@ module SyntaxSuggest
highlight_lines: search.invalid_blocks.flat_map(&:lines)
).call
- expect(document).to include(<<~EOM)
+ expect(document).to include(<<~'EOM')
> 36 def filename
EOM
end
it "Format Code blocks real world example" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
require 'rails_helper'
RSpec.describe AclassNameHere, type: :worker do
@@ -291,7 +291,7 @@ module SyntaxSuggest
highlight_lines: search.invalid_blocks.flat_map(&:lines)
).call
- expect(document).to include(<<~EOM)
+ expect(document).to include(<<~'EOM')
1 require 'rails_helper'
2
3 RSpec.describe AclassNameHere, type: :worker do
@@ -308,7 +308,7 @@ module SyntaxSuggest
describe "needs improvement" do
describe "mis-matched-indentation" do
it "extra space before end" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
@@ -318,14 +318,14 @@ module SyntaxSuggest
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end # two
EOM
end
it "stacked ends 2" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
def cat
blerg
end
@@ -339,7 +339,7 @@ module SyntaxSuggest
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call do
end # one
end # two
@@ -348,7 +348,7 @@ module SyntaxSuggest
end
it "stacked ends " do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
@@ -358,14 +358,14 @@ module SyntaxSuggest
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end
EOM
end
it "missing space before end" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
@@ -377,7 +377,7 @@ module SyntaxSuggest
search.call
# expand-1 and expand-2 seem to be broken?
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end
EOM
@@ -386,7 +386,7 @@ module SyntaxSuggest
end
it "returns syntax error in outer block without inner block" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
@@ -396,27 +396,27 @@ module SyntaxSuggest
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end # two
EOM
end
it "doesn't just return an empty `end`" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
Foo.call
end
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end
EOM
end
it "finds multiple syntax errors" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
describe "hi" do
Foo.call
end
@@ -429,7 +429,7 @@ module SyntaxSuggest
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
Foo.call
end
Bar.call
@@ -438,47 +438,47 @@ module SyntaxSuggest
end
it "finds a typo def" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
defzfoo
puts "lol"
end
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM)
+ expect(search.invalid_blocks.join).to eq(<<~'EOM')
defzfoo
end
EOM
end
it "finds a mis-matched def" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
def foo
def blerg
end
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
def blerg
EOM
end
it "finds a naked end" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
def foo
end # one
end # two
EOM
search.call
- expect(search.invalid_blocks.join).to eq(<<~EOM.indent(2))
+ expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
end # one
EOM
end
it "returns when no invalid blocks are found" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
def foo
puts 'lol'
end
@@ -489,14 +489,14 @@ module SyntaxSuggest
end
it "expands frontier by eliminating valid lines" do
- search = CodeSearch.new(<<~EOM)
+ search = CodeSearch.new(<<~'EOM')
def foo
puts 'lol'
end
EOM
search.create_blocks_from_untracked_lines
- expect(search.code_lines.join).to eq(<<~EOM)
+ expect(search.code_lines.join).to eq(<<~'EOM')
def foo
end
EOM
diff --git a/spec/syntax_suggest/unit/core_ext_spec.rb b/spec/syntax_suggest/unit/core_ext_spec.rb
index 499c38a240..802d03ecc0 100644
--- a/spec/syntax_suggest/unit/core_ext_spec.rb
+++ b/spec/syntax_suggest/unit/core_ext_spec.rb
@@ -8,7 +8,7 @@ module SyntaxSuggest
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
file = tmpdir.join("file.rb")
- file.write(<<~EOM.strip)
+ file.write(<<~'EOM'.strip)
print 'no newline
EOM
diff --git a/spec/syntax_suggest/unit/explain_syntax_spec.rb b/spec/syntax_suggest/unit/explain_syntax_spec.rb
index c62a42b925..394981dcf6 100644
--- a/spec/syntax_suggest/unit/explain_syntax_spec.rb
+++ b/spec/syntax_suggest/unit/explain_syntax_spec.rb
@@ -14,7 +14,7 @@ module SyntaxSuggest
).call
expect(explain.missing).to eq([])
- expect(explain.errors.join.strip).to_not be_empty
+ expect(explain.errors.join).to include("unterminated string")
end
it "handles %w[]" do
@@ -191,7 +191,7 @@ module SyntaxSuggest
).call
expect(explain.missing).to eq([])
- expect(explain.errors).to eq(GetParseErrors.errors(source))
+ expect(explain.errors).to eq(RipperErrors.new(source).call.errors)
end
it "handles an unexpected rescue" do
diff --git a/spec/syntax_suggest/unit/lex_all_spec.rb b/spec/syntax_suggest/unit/lex_all_spec.rb
index 9621c9ecec..0c0df7cfaa 100644
--- a/spec/syntax_suggest/unit/lex_all_spec.rb
+++ b/spec/syntax_suggest/unit/lex_all_spec.rb
@@ -17,6 +17,9 @@ module SyntaxSuggest
end # 9
EOM
+ # raw_lex = Ripper.lex(source)
+ # expect(raw_lex.to_s).to_not include("dog")
+
lex = LexAll.new(source: source)
expect(lex.map(&:token).to_s).to include("dog")
expect(lex.first.line).to eq(1)
diff --git a/spec/syntax_suggest/unit/pathname_from_message_spec.rb b/spec/syntax_suggest/unit/pathname_from_message_spec.rb
index de58acebaa..76756efda9 100644
--- a/spec/syntax_suggest/unit/pathname_from_message_spec.rb
+++ b/spec/syntax_suggest/unit/pathname_from_message_spec.rb
@@ -43,15 +43,6 @@ module SyntaxSuggest
expect(file).to be_falsey
end
- it "does not output error message on syntax error inside of an (eval at __FILE__:__LINE__)" do
- message = "(eval at #{__FILE__}:#{__LINE__}):1: invalid multibyte char (UTF-8) (SyntaxError)\n"
- io = StringIO.new
- file = PathnameFromMessage.new(message, io: io).call.name
-
- expect(io.string).to eq("")
- expect(file).to be_falsey
- end
-
it "does not output error message on syntax error inside of streamed code" do
# An example of streamed code is: $ echo "def foo" | ruby
message = "-:1: syntax error, unexpected end-of-input\n"
diff --git a/spec/syntax_suggest/unit/scan_history_spec.rb b/spec/syntax_suggest/unit/scan_history_spec.rb
index d8b0a54ba6..0e75ac66ce 100644
--- a/spec/syntax_suggest/unit/scan_history_spec.rb
+++ b/spec/syntax_suggest/unit/scan_history_spec.rb
@@ -5,7 +5,7 @@ require_relative "../spec_helper"
module SyntaxSuggest
RSpec.describe ScanHistory do
it "retains commits" do
- source = <<~EOM
+ source = <<~'EOM'
class OH # 0
def lol # 1
print 'lol # 2
@@ -42,7 +42,7 @@ module SyntaxSuggest
end
it "is stashable" do
- source = <<~EOM
+ source = <<~'EOM'
class OH # 0
def lol # 1
print 'lol # 2
@@ -79,7 +79,7 @@ module SyntaxSuggest
end
it "doesnt change if you dont't change it" do
- source = <<~EOM
+ source = <<~'EOM'
class OH # 0
def lol # 1
print 'lol # 2
diff --git a/sprintf.c b/sprintf.c
index b2d89617aa..b13530614f 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -247,8 +247,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
}
#define update_coderange(partial) do { \
- if (coderange != ENC_CODERANGE_BROKEN && scanned < blen \
- && rb_enc_to_index(enc) /* != ENCINDEX_ASCII_8BIT */) { \
+ if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) { \
int cr = coderange; \
scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr); \
ENC_CODERANGE_SET(result, \
@@ -812,7 +811,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (FIXNUM_P(num)) {
if ((SIGNED_VALUE)num < 0) {
long n = -FIX2LONG(num);
- num = LONG2FIX(n);
+ num = LONG2NUM(n);
sign = -1;
}
}
diff --git a/st.c b/st.c
index b921b1bf3b..d9a588db8a 100644
--- a/st.c
+++ b/st.c
@@ -103,11 +103,13 @@
#ifdef NOT_RUBY
#include "regint.h"
#include "st.h"
-#elif defined RUBY_EXPORT
+#include <assert.h>
+#else
#include "internal.h"
#include "internal/bits.h"
#include "internal/hash.h"
#include "internal/sanitizers.h"
+#include "ruby_assert.h"
#endif
#include <stdio.h>
@@ -115,7 +117,6 @@
#include <stdlib.h>
#endif
#include <string.h>
-#include <assert.h>
#ifdef __GNUC__
#define PREFETCH(addr, write_p) __builtin_prefetch(addr, write_p)
@@ -313,17 +314,22 @@ static const struct st_features features[] = {
#define RESERVED_HASH_VAL (~(st_hash_t) 0)
#define RESERVED_HASH_SUBSTITUTION_VAL ((st_hash_t) 0)
-/* Return hash value of KEY for table TAB. */
static inline st_hash_t
-do_hash(st_data_t key, st_table *tab)
+normalize_hash_value(st_hash_t hash)
{
- st_hash_t hash = (st_hash_t)(tab->type->hash)(key);
-
/* RESERVED_HASH_VAL is used for a deleted entry. Map it into
another value. Such mapping should be extremely rare. */
return hash == RESERVED_HASH_VAL ? RESERVED_HASH_SUBSTITUTION_VAL : hash;
}
+/* Return hash value of KEY for table TAB. */
+static inline st_hash_t
+do_hash(st_data_t key, st_table *tab)
+{
+ st_hash_t hash = (st_hash_t)(tab->type->hash)(key);
+ return normalize_hash_value(hash);
+}
+
/* Power of 2 defining the minimal number of allocated entries. */
#define MINIMAL_POWER2 2
@@ -342,7 +348,7 @@ get_power2(st_index_t size)
unsigned int n = ST_INDEX_BITS - nlz_intptr(size);
if (n <= MAX_POWER2)
return n < MINIMAL_POWER2 ? MINIMAL_POWER2 : n;
-#ifdef RUBY
+#ifndef NOT_RUBY
/* Ran out of the table entries */
rb_raise(rb_eRuntimeError, "st_table too big");
#endif
@@ -509,9 +515,13 @@ stat_col(void)
}
#endif
+/* Create and return table with TYPE which can hold at least SIZE
+ entries. The real number of entries which the table can hold is
+ the nearest power of two for SIZE. */
st_table *
-st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type, st_index_t size)
+st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
{
+ st_table *tab;
int n;
#ifdef HASH_LOG
@@ -532,7 +542,11 @@ st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type,
if (n < 0)
return NULL;
#endif
-
+ tab = (st_table *) malloc(sizeof (st_table));
+#ifndef RUBY
+ if (tab == NULL)
+ return NULL;
+#endif
tab->type = type;
tab->entry_power = n;
tab->bin_power = features[n].bin_power;
@@ -561,30 +575,6 @@ st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type,
return tab;
}
-/* Create and return table with TYPE which can hold at least SIZE
- entries. The real number of entries which the table can hold is
- the nearest power of two for SIZE. */
-st_table *
-st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
-{
- st_table *tab = malloc(sizeof(st_table));
-#ifndef RUBY
- if (tab == NULL)
- return NULL;
-#endif
-
-#ifdef RUBY
- st_init_existing_table_with_size(tab, type, size);
-#else
- if (st_init_existing_table_with_size(tab, type, size) == NULL) {
- free(tab);
- return NULL;
- }
-#endif
-
- return tab;
-}
-
size_t
st_table_size(const struct st_table *tbl)
{
@@ -657,7 +647,8 @@ st_clear(st_table *tab)
void
st_free_table(st_table *tab)
{
- free(tab->bins);
+ if (tab->bins != NULL)
+ free(tab->bins);
free(tab->entries);
free(tab);
}
@@ -779,11 +770,15 @@ rebuild_table_with(st_table *new_tab, st_table *tab)
new_tab->num_entries++;
ni++;
}
+
+ assert(new_tab->num_entries == tab->num_entries);
+
if (new_tab != tab) {
tab->entry_power = new_tab->entry_power;
tab->bin_power = new_tab->bin_power;
tab->size_ind = new_tab->size_ind;
- free(tab->bins);
+ if (tab->bins != NULL)
+ free(tab->bins);
tab->bins = new_tab->bins;
free(tab->entries);
tab->entries = new_tab->entries;
@@ -795,7 +790,7 @@ rebuild_table_with(st_table *new_tab, st_table *tab)
}
/* Return the next secondary hash index for table TAB using previous
- index IND and PERTURB. Finally modulo of the function becomes a
+ index IND and PERTERB. Finally modulo of the function becomes a
full *cycle linear congruential generator*, in other words it
guarantees traversing all table bins in extreme case.
@@ -807,10 +802,10 @@ rebuild_table_with(st_table *new_tab, st_table *tab)
For our case a is 5, c is 1, and m is a power of two. */
static inline st_index_t
-secondary_hash(st_index_t ind, st_table *tab, st_index_t *perturb)
+secondary_hash(st_index_t ind, st_table *tab, st_index_t *perterb)
{
- *perturb >>= 11;
- ind = (ind << 2) + ind + *perturb + 1;
+ *perterb >>= 11;
+ ind = (ind << 2) + ind + *perterb + 1;
return hash_bin(ind, tab);
}
@@ -853,7 +848,7 @@ find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
#ifdef QUADRATIC_PROBE
st_index_t d;
#else
- st_index_t perturb;
+ st_index_t peterb;
#endif
st_index_t bin;
st_table_entry *entries = tab->entries;
@@ -862,7 +857,7 @@ find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
#ifdef QUADRATIC_PROBE
d = 1;
#else
- perturb = hash_value;
+ peterb = hash_value;
#endif
FOUND_BIN;
for (;;) {
@@ -880,7 +875,7 @@ find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
ind = hash_bin(ind + d, tab);
d++;
#else
- ind = secondary_hash(ind, tab, &perturb);
+ ind = secondary_hash(ind, tab, &peterb);
#endif
COLLISION;
}
@@ -899,7 +894,7 @@ find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
#ifdef QUADRATIC_PROBE
st_index_t d;
#else
- st_index_t perturb;
+ st_index_t peterb;
#endif
st_index_t bin;
st_table_entry *entries = tab->entries;
@@ -908,7 +903,7 @@ find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
#ifdef QUADRATIC_PROBE
d = 1;
#else
- perturb = hash_value;
+ peterb = hash_value;
#endif
FOUND_BIN;
for (;;) {
@@ -926,7 +921,7 @@ find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
ind = hash_bin(ind + d, tab);
d++;
#else
- ind = secondary_hash(ind, tab, &perturb);
+ ind = secondary_hash(ind, tab, &peterb);
#endif
COLLISION;
}
@@ -943,7 +938,7 @@ find_table_bin_ind_direct(st_table *tab, st_hash_t hash_value, st_data_t key)
#ifdef QUADRATIC_PROBE
st_index_t d;
#else
- st_index_t perturb;
+ st_index_t peterb;
#endif
st_index_t bin;
@@ -951,7 +946,7 @@ find_table_bin_ind_direct(st_table *tab, st_hash_t hash_value, st_data_t key)
#ifdef QUADRATIC_PROBE
d = 1;
#else
- perturb = hash_value;
+ peterb = hash_value;
#endif
FOUND_BIN;
for (;;) {
@@ -962,7 +957,7 @@ find_table_bin_ind_direct(st_table *tab, st_hash_t hash_value, st_data_t key)
ind = hash_bin(ind + d, tab);
d++;
#else
- ind = secondary_hash(ind, tab, &perturb);
+ ind = secondary_hash(ind, tab, &peterb);
#endif
COLLISION;
}
@@ -987,7 +982,7 @@ find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
#ifdef QUADRATIC_PROBE
st_index_t d;
#else
- st_index_t perturb;
+ st_index_t peterb;
#endif
st_index_t entry_index;
st_index_t first_deleted_bin_ind;
@@ -997,7 +992,7 @@ find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
#ifdef QUADRATIC_PROBE
d = 1;
#else
- perturb = curr_hash_value;
+ peterb = curr_hash_value;
#endif
FOUND_BIN;
first_deleted_bin_ind = UNDEFINED_BIN_IND;
@@ -1027,7 +1022,7 @@ find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
ind = hash_bin(ind + d, tab);
d++;
#else
- ind = secondary_hash(ind, tab, &perturb);
+ ind = secondary_hash(ind, tab, &peterb);
#endif
COLLISION;
}
@@ -1160,6 +1155,8 @@ st_add_direct_with_hash(st_table *tab,
st_index_t ind;
st_index_t bin_ind;
+ assert(hash != RESERVED_HASH_VAL);
+
rebuild_table_if_necessary(tab);
ind = tab->entries_bound++;
entry = &tab->entries[ind];
@@ -1177,7 +1174,7 @@ void
rb_st_add_direct_with_hash(st_table *tab,
st_data_t key, st_data_t value, st_hash_t hash)
{
- st_add_direct_with_hash(tab, key, value, hash);
+ st_add_direct_with_hash(tab, key, value, normalize_hash_value(hash));
}
/* Insert (KEY, VALUE) into table TAB. The table should not have
@@ -1240,10 +1237,17 @@ st_insert2(st_table *tab, st_data_t key, st_data_t value,
return 1;
}
-/* Create a copy of old_tab into new_tab. */
+/* Create and return a copy of table OLD_TAB. */
st_table *
-st_replace(st_table *new_tab, st_table *old_tab)
+st_copy(st_table *old_tab)
{
+ st_table *new_tab;
+
+ new_tab = (st_table *) malloc(sizeof(st_table));
+#ifndef RUBY
+ if (new_tab == NULL)
+ return NULL;
+#endif
*new_tab = *old_tab;
if (old_tab->bins == NULL)
new_tab->bins = NULL;
@@ -1251,6 +1255,7 @@ st_replace(st_table *new_tab, st_table *old_tab)
new_tab->bins = (st_index_t *) malloc(bins_size(old_tab));
#ifndef RUBY
if (new_tab->bins == NULL) {
+ free(new_tab);
return NULL;
}
#endif
@@ -1259,6 +1264,7 @@ st_replace(st_table *new_tab, st_table *old_tab)
* sizeof(st_table_entry));
#ifndef RUBY
if (new_tab->entries == NULL) {
+ st_free_table(new_tab);
return NULL;
}
#endif
@@ -1266,27 +1272,6 @@ st_replace(st_table *new_tab, st_table *old_tab)
get_allocated_entries(old_tab));
if (old_tab->bins != NULL)
MEMCPY(new_tab->bins, old_tab->bins, char, bins_size(old_tab));
-
- return new_tab;
-}
-
-/* Create and return a copy of table OLD_TAB. */
-st_table *
-st_copy(st_table *old_tab)
-{
- st_table *new_tab;
-
- new_tab = (st_table *) malloc(sizeof(st_table));
-#ifndef RUBY
- if (new_tab == NULL)
- return NULL;
-#endif
-
- if (st_replace(new_tab, old_tab) == NULL) {
- st_free_table(new_tab);
- return NULL;
- }
-
return new_tab;
}
@@ -2085,7 +2070,6 @@ st_numhash(st_data_t n)
return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
}
-#ifdef RUBY
/* Expand TAB to be suitable for holding SIZ entries in total.
Pre-existing entries remain not deleted inside of TAB, but its bins
are cleared to expect future reconstruction. See rehash below. */
@@ -2102,8 +2086,10 @@ st_expand_table(st_table *tab, st_index_t siz)
n = get_allocated_entries(tab);
MEMCPY(tmp->entries, tab->entries, st_table_entry, n);
free(tab->entries);
- free(tab->bins);
- free(tmp->bins);
+ if (tab->bins != NULL)
+ free(tab->bins);
+ if (tmp->bins != NULL)
+ free(tmp->bins);
tab->entry_power = tmp->entry_power;
tab->bin_power = tmp->bin_power;
tab->size_ind = tmp->size_ind;
@@ -2121,10 +2107,10 @@ st_rehash_linear(st_table *tab)
int eq_p, rebuilt_p;
st_index_t i, j;
st_table_entry *p, *q;
-
- free(tab->bins);
- tab->bins = NULL;
-
+ if (tab->bins) {
+ free(tab->bins);
+ tab->bins = NULL;
+ }
for (i = tab->entries_start; i < tab->entries_bound; i++) {
p = &tab->entries[i];
if (DELETED_ENTRY_P(p))
@@ -2165,7 +2151,7 @@ st_rehash_indexed(st_table *tab)
#ifdef QUADRATIC_PROBE
st_index_t d = 1;
#else
- st_index_t perturb = p->hash;
+ st_index_t peterb = p->hash;
#endif
if (DELETED_ENTRY_P(p))
@@ -2198,7 +2184,7 @@ st_rehash_indexed(st_table *tab)
ind = hash_bin(ind + d, tab);
d++;
#else
- ind = secondary_hash(ind, tab, &perturb);
+ ind = secondary_hash(ind, tab, &peterb);
#endif
}
}
@@ -2223,6 +2209,7 @@ st_rehash(st_table *tab)
} while (rebuilt_p);
}
+#ifdef RUBY
static st_data_t
st_stringify(VALUE key)
{
diff --git a/string.c b/string.c
index 3d4650ff05..441e09bc24 100644
--- a/string.c
+++ b/string.c
@@ -23,6 +23,7 @@
#include "debug_counter.h"
#include "encindex.h"
+#include "gc.h"
#include "id.h"
#include "internal.h"
#include "internal/array.h"
@@ -44,6 +45,7 @@
#include "ruby/util.h"
#include "ruby_assert.h"
#include "vm_sync.h"
+#include "ruby/internal/attr/nonstring.h"
#if defined HAVE_CRYPT_R
# if defined HAVE_CRYPT_H
@@ -82,6 +84,7 @@ VALUE rb_cSymbol;
*
* 1: RSTRING_NOEMBED
* 2: STR_SHARED (== ELTS_SHARED)
+ * 2-6: RSTRING_EMBED_LEN (5 bits == 32)
* 5: STR_SHARED_ROOT (RSTRING_NOEMBED==1 && STR_SHARED == 0, there may be
* other strings that rely on this string's buffer)
* 6: STR_BORROWED (when RSTRING_NOEMBED==1 && klass==0, unsafe to recycle
@@ -107,12 +110,45 @@ VALUE rb_cSymbol;
#define STR_SET_NOEMBED(str) do {\
FL_SET((str), STR_NOEMBED);\
- FL_UNSET((str), STR_SHARED | STR_SHARED_ROOT | STR_BORROWED);\
+ if (USE_RVARGC) {\
+ FL_UNSET((str), STR_SHARED | STR_SHARED_ROOT | STR_BORROWED);\
+ }\
+ else {\
+ STR_SET_EMBED_LEN((str), 0);\
+ }\
} while (0)
#define STR_SET_EMBED(str) FL_UNSET((str), (STR_NOEMBED|STR_NOFREE))
+#if USE_RVARGC
+# define STR_SET_EMBED_LEN(str, n) do { \
+ assert(str_embed_capa(str) > (n));\
+ RSTRING(str)->as.embed.len = (n);\
+} while (0)
+#else
+# define STR_SET_EMBED_LEN(str, n) do { \
+ long tmp_n = (n);\
+ RBASIC(str)->flags &= ~RSTRING_EMBED_LEN_MASK;\
+ RBASIC(str)->flags |= (tmp_n) << RSTRING_EMBED_LEN_SHIFT;\
+} while (0)
+#endif
#define STR_SET_LEN(str, n) do { \
- RSTRING(str)->len = (n); \
+ if (STR_EMBED_P(str)) {\
+ STR_SET_EMBED_LEN((str), (n));\
+ }\
+ else {\
+ RSTRING(str)->as.heap.len = (n);\
+ }\
+} while (0)
+
+#define STR_DEC_LEN(str) do {\
+ if (STR_EMBED_P(str)) {\
+ long n = RSTRING_LEN(str);\
+ n--;\
+ STR_SET_EMBED_LEN((str), n);\
+ }\
+ else {\
+ RSTRING(str)->as.heap.len--;\
+ }\
} while (0)
static inline bool
@@ -149,7 +185,7 @@ str_enc_fastpath(VALUE str)
const long tlen = RSTRING_LEN(str);\
memcpy(tmp, RSTRING_PTR(str), tlen);\
RSTRING(str)->as.heap.ptr = tmp;\
- RSTRING(str)->len = tlen;\
+ RSTRING(str)->as.heap.len = tlen;\
STR_SET_NOEMBED(str);\
RSTRING(str)->as.heap.aux.capa = (capacity);\
}\
@@ -193,7 +229,11 @@ str_enc_fastpath(VALUE str)
static inline long
str_embed_capa(VALUE str)
{
+#if USE_RVARGC
return rb_gc_obj_slot_size(str) - offsetof(struct RString, as.embed.ary);
+#else
+ return RSTRING_EMBED_LEN_MAX + 1;
+#endif
}
bool
@@ -212,8 +252,9 @@ size_t
rb_str_size_as_embedded(VALUE str)
{
size_t real_size;
+#if USE_RVARGC
if (STR_EMBED_P(str)) {
- real_size = rb_str_embed_size(RSTRING(str)->len) + TERM_LEN(str);
+ real_size = rb_str_embed_size(RSTRING(str)->as.embed.len) + TERM_LEN(str);
}
/* if the string is not currently embedded, but it can be embedded, how
* much space would it require */
@@ -221,15 +262,22 @@ rb_str_size_as_embedded(VALUE str)
real_size = rb_str_embed_size(RSTRING(str)->as.heap.aux.capa) + TERM_LEN(str);
}
else {
+#endif
real_size = sizeof(struct RString);
+#if USE_RVARGC
}
+#endif
return real_size;
}
static inline bool
STR_EMBEDDABLE_P(long len, long termlen)
{
+#if USE_RVARGC
return rb_gc_size_allocatable_p(rb_str_embed_size(len + termlen));
+#else
+ return len <= RSTRING_EMBED_LEN_MAX + 1 - termlen;
+#endif
}
static VALUE str_replace_shared_without_enc(VALUE str2, VALUE str);
@@ -266,10 +314,10 @@ rb_str_make_embedded(VALUE str)
RUBY_ASSERT(!STR_EMBED_P(str));
char *buf = RSTRING(str)->as.heap.ptr;
- long len = RSTRING(str)->len;
+ long len = RSTRING(str)->as.heap.len;
STR_SET_EMBED(str);
- STR_SET_LEN(str, len);
+ STR_SET_EMBED_LEN(str, len);
if (len > 0) {
memcpy(RSTRING_PTR(str), buf, len);
@@ -280,6 +328,26 @@ rb_str_make_embedded(VALUE str)
}
void
+rb_str_update_shared_ary(VALUE str, VALUE old_root, VALUE new_root)
+{
+ // if the root location hasn't changed, we don't need to update
+ if (new_root == old_root) {
+ return;
+ }
+
+ // if the root string isn't embedded, we don't need to touch the ponter.
+ // it already points to the shame shared buffer
+ if (!STR_EMBED_P(new_root)) {
+ return;
+ }
+
+ size_t offset = (size_t)((uintptr_t)RSTRING(str)->as.heap.ptr - (uintptr_t)RSTRING(old_root)->as.embed.ary);
+
+ RUBY_ASSERT(RSTRING(str)->as.heap.ptr >= RSTRING(old_root)->as.embed.ary);
+ RSTRING(str)->as.heap.ptr = RSTRING(new_root)->as.embed.ary + offset;
+}
+
+void
rb_debug_rstring_null_ptr(const char *func)
{
fprintf(stderr, "%s is returning NULL!! "
@@ -353,13 +421,13 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t data, int exist
else {
if (FL_TEST_RAW(str, STR_FAKESTR)) {
if (arg->copy) {
- VALUE new_str = str_new(rb_cString, RSTRING(str)->as.heap.ptr, RSTRING(str)->len);
+ VALUE new_str = str_new(rb_cString, RSTRING(str)->as.heap.ptr, RSTRING(str)->as.heap.len);
rb_enc_copy(new_str, str);
str = new_str;
}
else {
str = str_new_static(rb_cString, RSTRING(str)->as.heap.ptr,
- RSTRING(str)->len,
+ RSTRING(str)->as.heap.len,
ENCODING_GET(str));
}
OBJ_FREEZE_RAW(str);
@@ -401,14 +469,13 @@ rb_fstring(VALUE str)
OBJ_FREEZE_RAW(str);
return str;
}
-
- if (FL_TEST_RAW(str, STR_SHARED_ROOT | STR_SHARED) == STR_SHARED_ROOT) {
+ if (FL_TEST_RAW(str, STR_NOEMBED|STR_SHARED_ROOT|STR_SHARED) == (STR_NOEMBED|STR_SHARED_ROOT)) {
assert(OBJ_FROZEN(str));
return str;
}
}
- if (!FL_TEST_RAW(str, FL_FREEZE | STR_NOFREE))
+ if (!OBJ_FROZEN(str))
rb_str_resize(str, RSTRING_LEN(str));
fstr = register_fstring(str, FALSE);
@@ -458,7 +525,7 @@ setup_fake_str(struct RString *fake_str, const char *name, long len, int encidx)
ENCODING_SET_INLINED((VALUE)fake_str, encidx);
RBASIC_SET_CLASS_RAW((VALUE)fake_str, rb_cString);
- fake_str->len = len;
+ fake_str->as.heap.len = len;
fake_str->as.heap.ptr = (char *)name;
fake_str->as.heap.aux.capa = len;
return (VALUE)fake_str;
@@ -478,7 +545,7 @@ rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encod
* shared string which refers a static string literal. `ptr` must
* point a constant string.
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_fstring_new(const char *ptr, long len)
{
struct RString fake_str;
@@ -702,20 +769,6 @@ str_enc_copy(VALUE str1, VALUE str2)
rb_enc_set_index(str1, ENCODING_GET(str2));
}
-/* Like str_enc_copy, but does not check frozen status of str1.
- * You should use this only if you're certain that str1 is not frozen. */
-static inline void
-str_enc_copy_direct(VALUE str1, VALUE str2)
-{
- int inlined_encoding = RB_ENCODING_GET_INLINED(str2);
- if (inlined_encoding == ENCODING_INLINE_MAX) {
- rb_enc_set_index(str1, rb_enc_get_index(str2));
- }
- else {
- ENCODING_SET_INLINED(str1, inlined_encoding);
- }
-}
-
static void
rb_enc_cr_str_copy_for_substr(VALUE dest, VALUE src)
{
@@ -801,10 +854,14 @@ static size_t
str_capacity(VALUE str, const int termlen)
{
if (STR_EMBED_P(str)) {
+#if USE_RVARGC
return str_embed_capa(str) - termlen;
+#else
+ return (RSTRING_EMBED_LEN_MAX + 1 - termlen);
+#endif
}
else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
- return RSTRING(str)->len;
+ return RSTRING(str)->as.heap.len;
}
else {
return RSTRING(str)->as.heap.aux.capa;
@@ -831,9 +888,12 @@ str_alloc_embed(VALUE klass, size_t capa)
size_t size = rb_str_embed_size(capa);
assert(size > 0);
assert(rb_gc_size_allocatable_p(size));
+#if !USE_RVARGC
+ assert(size <= sizeof(struct RString));
+#endif
- NEWOBJ_OF(str, struct RString, klass,
- T_STRING | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), size, 0);
+ RVARGC_NEWOBJ_OF(str, struct RString, klass,
+ T_STRING | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), size);
return (VALUE)str;
}
@@ -841,8 +901,8 @@ str_alloc_embed(VALUE klass, size_t capa)
static inline VALUE
str_alloc_heap(VALUE klass)
{
- NEWOBJ_OF(str, struct RString, klass,
- T_STRING | STR_NOEMBED | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), sizeof(struct RString), 0);
+ RVARGC_NEWOBJ_OF(str, struct RString, klass,
+ T_STRING | STR_NOEMBED | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), sizeof(struct RString));
return (VALUE)str;
}
@@ -984,7 +1044,7 @@ str_new_static(VALUE klass, const char *ptr, long len, int encindex)
else {
RUBY_DTRACE_CREATE_HOOK(STRING, len);
str = str_alloc_heap(klass);
- RSTRING(str)->len = len;
+ RSTRING(str)->as.heap.len = len;
RSTRING(str)->as.heap.ptr = (char *)ptr;
RSTRING(str)->as.heap.aux.capa = len;
RBASIC(str)->flags |= STR_NOFREE;
@@ -1268,6 +1328,7 @@ str_replace_shared_without_enc(VALUE str2, VALUE str)
char *ptr2 = RSTRING(str2)->as.embed.ary;
STR_SET_EMBED(str2);
memcpy(ptr2, RSTRING_PTR(str), len);
+ STR_SET_EMBED_LEN(str2, len);
TERM_FILL(ptr2+len, termlen);
}
else {
@@ -1291,12 +1352,10 @@ str_replace_shared_without_enc(VALUE str2, VALUE str)
}
}
FL_SET(str2, STR_NOEMBED);
+ RSTRING(str2)->as.heap.len = len;
RSTRING(str2)->as.heap.ptr = ptr;
STR_SET_SHARED(str2, root);
}
-
- STR_SET_LEN(str2, len);
-
return str2;
}
@@ -1341,42 +1400,6 @@ rb_str_tmp_frozen_acquire(VALUE orig)
return str_new_frozen_buffer(0, orig, FALSE);
}
-VALUE
-rb_str_tmp_frozen_no_embed_acquire(VALUE orig)
-{
- if (OBJ_FROZEN_RAW(orig) && !STR_EMBED_P(orig) && !rb_str_reembeddable_p(orig)) return orig;
- if (STR_SHARED_P(orig) && !STR_EMBED_P(RSTRING(orig)->as.heap.aux.shared)) return rb_str_tmp_frozen_acquire(orig);
-
- VALUE str = str_alloc_heap(0);
- OBJ_FREEZE(str);
- /* Always set the STR_SHARED_ROOT to ensure it does not get re-embedded. */
- FL_SET(str, STR_SHARED_ROOT);
-
- size_t capa = str_capacity(orig, TERM_LEN(orig));
-
- /* If the string is embedded then we want to create a copy that is heap
- * allocated. If the string is shared then the shared root must be
- * embedded, so we want to create a copy. If the string is a shared root
- * then it must be embedded, so we want to create a copy. */
- if (STR_EMBED_P(orig) || FL_TEST_RAW(orig, STR_SHARED | STR_SHARED_ROOT)) {
- RSTRING(str)->as.heap.ptr = rb_xmalloc_mul_add_mul(sizeof(char), capa, sizeof(char), TERM_LEN(orig));
- memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), capa);
- }
- else {
- /* orig must be heap allocated and not shared, so we can safely transfer
- * the pointer to str. */
- RSTRING(str)->as.heap.ptr = RSTRING(orig)->as.heap.ptr;
- RBASIC(str)->flags |= RBASIC(orig)->flags & STR_NOFREE;
- RBASIC(orig)->flags &= ~STR_NOFREE;
- STR_SET_SHARED(orig, str);
- }
-
- RSTRING(str)->len = RSTRING(orig)->len;
- RSTRING(str)->as.heap.aux.capa = capa;
-
- return str;
-}
-
void
rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
{
@@ -1392,7 +1415,7 @@ rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
if (shared == tmp && !FL_TEST_RAW(tmp, STR_BORROWED)) {
assert(RSTRING(orig)->as.heap.ptr == RSTRING(tmp)->as.heap.ptr);
- assert(RSTRING_LEN(orig) == RSTRING_LEN(tmp));
+ assert(RSTRING(orig)->as.heap.len == RSTRING(tmp)->as.heap.len);
/* Unshare orig since the root (tmp) only has this one child. */
FL_UNSET_RAW(orig, STR_SHARED);
@@ -1402,7 +1425,7 @@ rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
/* Make tmp embedded and empty so it is safe for sweeping. */
STR_SET_EMBED(tmp);
- STR_SET_LEN(tmp, 0);
+ STR_SET_EMBED_LEN(tmp, 0);
}
}
}
@@ -1420,7 +1443,7 @@ heap_str_make_shared(VALUE klass, VALUE orig)
assert(!STR_SHARED_P(orig));
VALUE str = str_alloc_heap(klass);
- STR_SET_LEN(str, RSTRING_LEN(orig));
+ RSTRING(str)->as.heap.len = RSTRING_LEN(orig);
RSTRING(str)->as.heap.ptr = RSTRING_PTR(orig);
RSTRING(str)->as.heap.aux.capa = RSTRING(orig)->as.heap.aux.capa;
RBASIC(str)->flags |= RBASIC(orig)->flags & STR_NOFREE;
@@ -1447,10 +1470,13 @@ str_new_frozen_buffer(VALUE klass, VALUE orig, int copy_encoding)
if (FL_TEST_RAW(orig, STR_SHARED)) {
VALUE shared = RSTRING(orig)->as.heap.aux.shared;
long ofs = RSTRING(orig)->as.heap.ptr - RSTRING_PTR(shared);
- long rest = RSTRING_LEN(shared) - ofs - RSTRING_LEN(orig);
+ long rest = RSTRING_LEN(shared) - ofs - RSTRING(orig)->as.heap.len;
assert(ofs >= 0);
assert(rest >= 0);
assert(ofs + rest <= RSTRING_LEN(shared));
+#if !USE_RVARGC
+ assert(!STR_EMBED_P(shared));
+#endif
assert(OBJ_FROZEN(shared));
if ((ofs > 0) || (rest > 0) ||
@@ -1459,7 +1485,7 @@ str_new_frozen_buffer(VALUE klass, VALUE orig, int copy_encoding)
str = str_new_shared(klass, shared);
assert(!STR_EMBED_P(str));
RSTRING(str)->as.heap.ptr += ofs;
- STR_SET_LEN(str, RSTRING_LEN(str) - (ofs + rest));
+ RSTRING(str)->as.heap.len -= ofs + rest;
}
else {
if (RBASIC_CLASS(shared) == 0)
@@ -1471,7 +1497,7 @@ str_new_frozen_buffer(VALUE klass, VALUE orig, int copy_encoding)
str = str_alloc_embed(klass, RSTRING_LEN(orig) + TERM_LEN(orig));
STR_SET_EMBED(str);
memcpy(RSTRING_PTR(str), RSTRING_PTR(orig), RSTRING_LEN(orig));
- STR_SET_LEN(str, RSTRING_LEN(orig));
+ STR_SET_EMBED_LEN(str, RSTRING_LEN(orig));
TERM_FILL(RSTRING_END(str), TERM_LEN(orig));
}
else {
@@ -1499,6 +1525,9 @@ str_new_empty_String(VALUE str)
}
#define STR_BUF_MIN_SIZE 63
+#if !USE_RVARGC
+STATIC_ASSERT(STR_BUF_MIN_SIZE, STR_BUF_MIN_SIZE > RSTRING_EMBED_LEN_MAX);
+#endif
VALUE
rb_str_buf_new(long capa)
@@ -1509,6 +1538,11 @@ rb_str_buf_new(long capa)
VALUE str = str_alloc_heap(rb_cString);
+#if !USE_RVARGC
+ if (capa < STR_BUF_MIN_SIZE) {
+ capa = STR_BUF_MIN_SIZE;
+ }
+#endif
RSTRING(str)->as.heap.aux.capa = capa;
RSTRING(str)->as.heap.ptr = ALLOC_N(char, (size_t)capa + 1);
RSTRING(str)->as.heap.ptr[0] = '\0';
@@ -1600,31 +1634,33 @@ str_shared_replace(VALUE str, VALUE str2)
str_discard(str);
termlen = rb_enc_mbminlen(enc);
- STR_SET_LEN(str, RSTRING_LEN(str2));
-
if (str_embed_capa(str) >= RSTRING_LEN(str2) + termlen) {
STR_SET_EMBED(str);
memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), (size_t)RSTRING_LEN(str2) + termlen);
+ STR_SET_EMBED_LEN(str, RSTRING_LEN(str2));
rb_enc_associate(str, enc);
ENC_CODERANGE_SET(str, cr);
}
else {
+#if USE_RVARGC
if (STR_EMBED_P(str2)) {
assert(!FL_TEST(str2, STR_SHARED));
- long len = RSTRING_LEN(str2);
+ long len = RSTRING(str2)->as.embed.len;
assert(len + termlen <= str_embed_capa(str2));
char *new_ptr = ALLOC_N(char, len + termlen);
memcpy(new_ptr, RSTRING(str2)->as.embed.ary, len + termlen);
RSTRING(str2)->as.heap.ptr = new_ptr;
- STR_SET_LEN(str2, len);
+ RSTRING(str2)->as.heap.len = len;
RSTRING(str2)->as.heap.aux.capa = len;
STR_SET_NOEMBED(str2);
}
+#endif
STR_SET_NOEMBED(str);
FL_UNSET(str, STR_SHARED);
RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2);
+ RSTRING(str)->as.heap.len = RSTRING_LEN(str2);
if (FL_TEST(str2, STR_SHARED)) {
VALUE shared = RSTRING(str2)->as.heap.aux.shared;
@@ -1637,7 +1673,7 @@ str_shared_replace(VALUE str, VALUE str2)
/* abandon str2 */
STR_SET_EMBED(str2);
RSTRING_PTR(str2)[0] = 0;
- STR_SET_LEN(str2, 0);
+ STR_SET_EMBED_LEN(str2, 0);
rb_enc_associate(str, enc);
ENC_CODERANGE_SET(str, cr);
}
@@ -1655,7 +1691,7 @@ rb_obj_as_string(VALUE obj)
return rb_obj_as_string_result(str, obj);
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_obj_as_string_result(VALUE str, VALUE obj)
{
if (!RB_TYPE_P(str, T_STRING))
@@ -1673,7 +1709,7 @@ str_replace(VALUE str, VALUE str2)
VALUE shared = RSTRING(str2)->as.heap.aux.shared;
assert(OBJ_FROZEN(shared));
STR_SET_NOEMBED(str);
- STR_SET_LEN(str, len);
+ RSTRING(str)->as.heap.len = len;
RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2);
STR_SET_SHARED(str, shared);
rb_enc_cr_str_exact_copy(str, str2);
@@ -1691,9 +1727,12 @@ ec_str_alloc_embed(struct rb_execution_context_struct *ec, VALUE klass, size_t c
size_t size = rb_str_embed_size(capa);
assert(size > 0);
assert(rb_gc_size_allocatable_p(size));
+#if !USE_RVARGC
+ assert(size <= sizeof(struct RString));
+#endif
- NEWOBJ_OF(str, struct RString, klass,
- T_STRING | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), size, ec);
+ RB_RVARGC_EC_NEWOBJ_OF(ec, str, struct RString, klass,
+ T_STRING | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), size);
return (VALUE)str;
}
@@ -1701,8 +1740,8 @@ ec_str_alloc_embed(struct rb_execution_context_struct *ec, VALUE klass, size_t c
static inline VALUE
ec_str_alloc_heap(struct rb_execution_context_struct *ec, VALUE klass)
{
- NEWOBJ_OF(str, struct RString, klass,
- T_STRING | STR_NOEMBED | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), sizeof(struct RString), ec);
+ RB_RVARGC_EC_NEWOBJ_OF(ec, str, struct RString, klass,
+ T_STRING | STR_NOEMBED | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0), sizeof(struct RString));
return (VALUE)str;
}
@@ -1711,16 +1750,20 @@ static inline VALUE
str_duplicate_setup(VALUE klass, VALUE str, VALUE dup)
{
const VALUE flag_mask =
+#if !USE_RVARGC
+ RSTRING_NOEMBED | RSTRING_EMBED_LEN_MASK |
+#endif
ENC_CODERANGE_MASK | ENCODING_MASK |
FL_FREEZE
;
VALUE flags = FL_TEST_RAW(str, flag_mask);
int encidx = 0;
if (STR_EMBED_P(str)) {
- long len = RSTRING_LEN(str);
+ long len = RSTRING_EMBED_LEN(str);
assert(STR_EMBED_P(dup));
assert(str_embed_capa(dup) >= len + 1);
+ STR_SET_EMBED_LEN(dup, len);
MEMCPY(RSTRING(dup)->as.embed.ary, RSTRING(str)->as.embed.ary, char, len + 1);
}
else {
@@ -1734,15 +1777,23 @@ str_duplicate_setup(VALUE klass, VALUE str, VALUE dup)
}
assert(!STR_SHARED_P(root));
assert(RB_OBJ_FROZEN_RAW(root));
-
- RSTRING(dup)->as.heap.ptr = RSTRING_PTR(str);
- FL_SET(root, STR_SHARED_ROOT);
- RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, root);
- flags |= RSTRING_NOEMBED | STR_SHARED;
+ if (0) {}
+#if !USE_RVARGC
+ else if (STR_EMBED_P(root)) {
+ MEMCPY(RSTRING(dup)->as.embed.ary, RSTRING(root)->as.embed.ary,
+ char, RSTRING_EMBED_LEN_MAX + 1);
+ FL_UNSET(dup, STR_NOEMBED);
+ }
+#endif
+ else {
+ RSTRING(dup)->as.heap.len = RSTRING_LEN(str);
+ RSTRING(dup)->as.heap.ptr = RSTRING_PTR(str);
+ FL_SET(root, STR_SHARED_ROOT);
+ RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, root);
+ flags |= RSTRING_NOEMBED | STR_SHARED;
+ }
}
- STR_SET_LEN(dup, RSTRING_LEN(str));
-
if ((flags & ENCODING_MASK) == (ENCODING_INLINE_MAX<<ENCODING_SHIFT)) {
encidx = rb_enc_get_index(str);
flags &= ~ENCODING_MASK;
@@ -1756,11 +1807,11 @@ static inline VALUE
ec_str_duplicate(struct rb_execution_context_struct *ec, VALUE klass, VALUE str)
{
VALUE dup;
- if (STR_EMBED_P(str)) {
- dup = ec_str_alloc_embed(ec, klass, RSTRING_LEN(str) + TERM_LEN(str));
+ if (FL_TEST(str, STR_NOEMBED)) {
+ dup = ec_str_alloc_heap(ec, klass);
}
else {
- dup = ec_str_alloc_heap(ec, klass);
+ dup = ec_str_alloc_embed(ec, klass, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
}
return str_duplicate_setup(klass, str, dup);
@@ -1770,11 +1821,11 @@ static inline VALUE
str_duplicate(VALUE klass, VALUE str)
{
VALUE dup;
- if (STR_EMBED_P(str)) {
- dup = str_alloc_embed(klass, RSTRING_LEN(str) + TERM_LEN(str));
+ if (FL_TEST(str, STR_NOEMBED)) {
+ dup = str_alloc_heap(klass);
}
else {
- dup = str_alloc_heap(klass);
+ dup = str_alloc_embed(klass, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
}
return str_duplicate_setup(klass, str, dup);
@@ -1786,18 +1837,6 @@ rb_str_dup(VALUE str)
return str_duplicate(rb_obj_class(str), str);
}
-/* :nodoc: */
-VALUE
-rb_str_dup_m(VALUE str)
-{
- if (LIKELY(BARE_STRING_P(str))) {
- return str_duplicate(rb_obj_class(str), str);
- }
- else {
- return rb_obj_dup(str);
- }
-}
-
VALUE
rb_str_resurrect(VALUE str)
{
@@ -1860,13 +1899,21 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
if (orig == str) n = 0;
}
str_modifiable(str);
- if (STR_EMBED_P(str) || FL_TEST(str, STR_SHARED|STR_NOFREE)) {
- /* make noembed always */
+ if (STR_EMBED_P(str)) { /* make noembed always */
+ char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
+#if USE_RVARGC
+ assert(RSTRING(str)->as.embed.len + 1 <= str_embed_capa(str));
+ memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.len + 1);
+#else
+ memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_EMBED_LEN_MAX + 1);
+#endif
+ RSTRING(str)->as.heap.ptr = new_ptr;
+ }
+ else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
const size_t size = (size_t)capa + termlen;
const char *const old_ptr = RSTRING_PTR(str);
- const size_t osize = RSTRING_LEN(str) + TERM_LEN(str);
- char *new_ptr = ALLOC_N(char, size);
- if (STR_EMBED_P(str)) RUBY_ASSERT(osize <= str_embed_capa(str));
+ const size_t osize = RSTRING(str)->as.heap.len + TERM_LEN(str);
+ char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
memcpy(new_ptr, old_ptr, osize < size ? osize : size);
FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE);
RSTRING(str)->as.heap.ptr = new_ptr;
@@ -1875,7 +1922,7 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
(size_t)capa + termlen, STR_HEAP_SIZE(str));
}
- STR_SET_LEN(str, len);
+ RSTRING(str)->as.heap.len = len;
TERM_FILL(&RSTRING(str)->as.heap.ptr[len], termlen);
if (n == 1) {
memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), len);
@@ -1898,98 +1945,6 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
return str;
}
-/* :nodoc: */
-static VALUE
-rb_str_s_new(int argc, VALUE *argv, VALUE klass)
-{
- if (klass != rb_cString) {
- return rb_class_new_instance_pass_kw(argc, argv, klass);
- }
-
- static ID keyword_ids[2];
- VALUE orig, opt, encoding = Qnil, capacity = Qnil;
- VALUE kwargs[2];
- rb_encoding *enc = NULL;
-
- int n = rb_scan_args(argc, argv, "01:", &orig, &opt);
- if (NIL_P(opt)) {
- return rb_class_new_instance_pass_kw(argc, argv, klass);
- }
-
- keyword_ids[0] = rb_id_encoding();
- CONST_ID(keyword_ids[1], "capacity");
- rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs);
- encoding = kwargs[0];
- capacity = kwargs[1];
-
- int termlen = 1;
-
- if (n == 1) {
- orig = StringValue(orig);
- }
- else {
- orig = Qnil;
- }
-
- if (UNDEF_P(encoding)) {
- if (!NIL_P(orig)) {
- encoding = rb_obj_encoding(orig);
- }
- }
-
- if (!UNDEF_P(encoding)) {
- enc = rb_to_encoding(encoding);
- termlen = rb_enc_mbminlen(enc);
- }
-
- // If capacity is nil, we're basically just duping `orig`.
- if (UNDEF_P(capacity)) {
- if (NIL_P(orig)) {
- VALUE empty_str = str_new(klass, "", 0);
- if (enc) {
- rb_enc_associate(empty_str, enc);
- }
- return empty_str;
- }
- VALUE copy = str_duplicate(klass, orig);
- rb_enc_associate(copy, enc);
- ENC_CODERANGE_CLEAR(copy);
- return copy;
- }
-
- long capa = 0;
- capa = NUM2LONG(capacity);
- if (capa < 0) {
- capa = 0;
- }
-
- if (!NIL_P(orig)) {
- long orig_capa = rb_str_capacity(orig);
- if (orig_capa > capa) {
- capa = orig_capa;
- }
- }
-
- long fake_len = capa - termlen;
- if (fake_len < 0) {
- fake_len = 0;
- }
-
- VALUE str = str_new0(klass, NULL, fake_len, termlen);
- STR_SET_LEN(str, 0);
- TERM_FILL(RSTRING_PTR(str), termlen);
-
- if (enc) {
- rb_enc_associate(str, enc);
- }
-
- if (!NIL_P(orig)) {
- rb_str_buf_append(str, orig);
- }
-
- return str;
-}
-
#ifdef NONASCII_MASK
#define is_utf8_lead_byte(c) (((c)&0xC0) != 0x80)
@@ -2219,7 +2174,7 @@ rb_str_length(VALUE str)
*
*/
-VALUE
+static VALUE
rb_str_bytesize(VALUE str)
{
return LONG2NUM(RSTRING_LEN(str));
@@ -2284,7 +2239,7 @@ rb_str_plus(VALUE str1, VALUE str2)
}
/* A variant of rb_str_plus that does not raise but return Qundef instead. */
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_str_opt_plus(VALUE str1, VALUE str2)
{
assert(RBASIC_CLASS(str1) == rb_cString);
@@ -2393,7 +2348,7 @@ rb_str_times(VALUE str, VALUE times)
* "%05d" % 123 # => "00123"
*
* If +self+ contains multiple substitutions, +object+ must be
- * an Array or Hash containing the values to be substituted:
+ * an \Array or \Hash containing the values to be substituted:
*
* "%-5s: %016x" % [ "ID", self.object_id ] # => "ID : 00002b054ec93168"
* "foo = %{foo}" % {foo: 'bar'} # => "foo = bar"
@@ -2459,7 +2414,7 @@ str_make_independent_expand(VALUE str, long len, long expand, const int termlen)
STR_SET_EMBED(str);
memcpy(RSTRING(str)->as.embed.ary, ptr, len);
TERM_FILL(RSTRING(str)->as.embed.ary + len, termlen);
- STR_SET_LEN(str, len);
+ STR_SET_EMBED_LEN(str, len);
return;
}
@@ -2475,7 +2430,7 @@ str_make_independent_expand(VALUE str, long len, long expand, const int termlen)
FL_UNSET(str, STR_SHARED|STR_NOFREE);
TERM_FILL(ptr + len, termlen);
RSTRING(str)->as.heap.ptr = ptr;
- STR_SET_LEN(str, len);
+ RSTRING(str)->as.heap.len = len;
RSTRING(str)->as.heap.aux.capa = capa;
}
@@ -2527,7 +2482,7 @@ str_discard(VALUE str)
if (!STR_EMBED_P(str) && !FL_TEST(str, STR_SHARED|STR_NOFREE)) {
ruby_sized_xfree(STR_HEAP_PTR(str), STR_HEAP_SIZE(str));
RSTRING(str)->as.heap.ptr = 0;
- STR_SET_LEN(str, 0);
+ RSTRING(str)->as.heap.len = 0;
}
}
@@ -2849,34 +2804,19 @@ str_subseq(VALUE str, long beg, long len)
{
VALUE str2;
- assert(beg >= 0);
- assert(len >= 0);
- assert(beg+len <= RSTRING_LEN(str));
+ const long rstring_embed_capa_max = ((sizeof(struct RString) - offsetof(struct RString, as.embed.ary)) / sizeof(char)) - 1;
- const int termlen = TERM_LEN(str);
- if (!SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) {
+ if (!SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str)) ||
+ len <= rstring_embed_capa_max) {
str2 = rb_str_new(RSTRING_PTR(str) + beg, len);
RB_GC_GUARD(str);
- return str2;
- }
-
- str2 = str_alloc_heap(rb_cString);
- if (str_embed_capa(str2) >= len + termlen) {
- char *ptr2 = RSTRING(str2)->as.embed.ary;
- STR_SET_EMBED(str2);
- memcpy(ptr2, RSTRING_PTR(str) + beg, len);
- TERM_FILL(ptr2+len, termlen);
-
- STR_SET_LEN(str2, len);
- RB_GC_GUARD(str);
}
else {
- str_replace_shared(str2, str);
- assert(!STR_EMBED_P(str2));
+ str2 = str_new_shared(rb_cString, str);
ENC_CODERANGE_CLEAR(str2);
RSTRING(str2)->as.heap.ptr += beg;
- if (RSTRING_LEN(str2) > len) {
- STR_SET_LEN(str2, len);
+ if (RSTRING(str2)->as.heap.len > len) {
+ RSTRING(str2)->as.heap.len = len;
}
}
@@ -2896,11 +2836,12 @@ rb_str_subpos(VALUE str, long beg, long *lenp)
{
long len = *lenp;
long slen = -1L;
- long blen = RSTRING_LEN(str);
+ const long blen = RSTRING_LEN(str);
rb_encoding *enc = STR_ENC_GET(str);
char *p, *s = RSTRING_PTR(str), *e = s + blen;
if (len < 0) return 0;
+ if (beg < 0 && -beg < 0) return 0;
if (!blen) {
len = 0;
}
@@ -2918,7 +2859,8 @@ rb_str_subpos(VALUE str, long beg, long *lenp)
}
if (beg < 0) {
if (len > -beg) len = -beg;
- if (-beg * rb_enc_mbmaxlen(enc) < RSTRING_LEN(str) / 8) {
+ if ((ENC_CODERANGE(str) == ENC_CODERANGE_VALID) &&
+ (-beg * rb_enc_mbmaxlen(enc) < blen / 8)) {
beg = -beg;
while (beg-- > len && (e = rb_enc_prev_char(s, e, e, enc)) != 0);
p = e;
@@ -2936,7 +2878,7 @@ rb_str_subpos(VALUE str, long beg, long *lenp)
if (len == 0) goto end;
}
}
- else if (beg > 0 && beg > RSTRING_LEN(str)) {
+ else if (beg > 0 && beg > blen) {
return 0;
}
if (len == 0) {
@@ -2999,7 +2941,6 @@ str_substr(VALUE str, long beg, long len, int empty)
return str2;
}
-/* :nodoc: */
VALUE
rb_str_freeze(VALUE str)
{
@@ -3031,23 +2972,13 @@ str_uplus(VALUE str)
/*
* call-seq:
* -string -> frozen_string
- * dedup -> frozen_string
*
* Returns a frozen, possibly pre-existing copy of the string.
*
* The returned \String will be deduplicated as long as it does not have
* any instance variables set on it and is not a String subclass.
*
- * Note that <tt>-string</tt> variant is more convenient for defining
- * constants:
- *
- * FILENAME = -'config/database.yml'
- *
- * while +dedup+ is better suitable for using the method in chains
- * of calculations:
- *
- * @url_list.concat(urls.map(&:dedup))
- *
+ * String#dedup is an alias for String#-@.
*/
static VALUE
str_uminus(VALUE str)
@@ -3152,7 +3083,7 @@ rb_str_resize(VALUE str, long len)
if (STR_EMBED_P(str)) {
if (len == slen) return str;
if (str_embed_capa(str) >= len + termlen) {
- STR_SET_LEN(str, len);
+ STR_SET_EMBED_LEN(str, len);
TERM_FILL(RSTRING(str)->as.embed.ary + len, termlen);
return str;
}
@@ -3164,7 +3095,7 @@ rb_str_resize(VALUE str, long len)
if (slen > len) slen = len;
if (slen > 0) MEMCPY(RSTRING(str)->as.embed.ary, ptr, char, slen);
TERM_FILL(RSTRING(str)->as.embed.ary + len, termlen);
- STR_SET_LEN(str, len);
+ STR_SET_EMBED_LEN(str, len);
if (independent) ruby_xfree(ptr);
return str;
}
@@ -3179,7 +3110,7 @@ rb_str_resize(VALUE str, long len)
RSTRING(str)->as.heap.aux.capa = len;
}
else if (len == slen) return str;
- STR_SET_LEN(str, len);
+ RSTRING(str)->as.heap.len = len;
TERM_FILL(RSTRING(str)->as.heap.ptr + len, termlen); /* sentinel */
}
return str;
@@ -3196,17 +3127,28 @@ str_buf_cat4(VALUE str, const char *ptr, long len, bool keep_cr)
}
if (len == 0) return 0;
- long total, olen, off = -1;
+ long capa, total, olen, off = -1;
char *sptr;
const int termlen = TERM_LEN(str);
+#if !USE_RVARGC
+ assert(termlen < RSTRING_EMBED_LEN_MAX + 1); /* < (LONG_MAX/2) */
+#endif
RSTRING_GETMEM(str, sptr, olen);
if (ptr >= sptr && ptr <= sptr + olen) {
off = ptr - sptr;
}
- long capa = str_capacity(str, termlen);
-
+ if (STR_EMBED_P(str)) {
+ capa = str_embed_capa(str) - termlen;
+ sptr = RSTRING(str)->as.embed.ary;
+ olen = RSTRING_EMBED_LEN(str);
+ }
+ else {
+ capa = RSTRING(str)->as.heap.aux.capa;
+ sptr = RSTRING(str)->as.heap.ptr;
+ olen = RSTRING(str)->as.heap.len;
+ }
if (olen > LONG_MAX - len) {
rb_raise(rb_eArgError, "string sizes too big");
}
@@ -3417,19 +3359,28 @@ rb_str_append(VALUE str, VALUE str2)
return rb_str_buf_append(str, str2);
}
-VALUE
+#define MIN_PRE_ALLOC_SIZE 48
+
+MJIT_FUNC_EXPORTED VALUE
rb_str_concat_literals(size_t num, const VALUE *strary)
{
VALUE str;
- size_t i, s = 0;
- unsigned long len = 1;
+ size_t i, s;
+ long len = 1;
if (UNLIKELY(!num)) return rb_str_new(0, 0);
if (UNLIKELY(num == 1)) return rb_str_resurrect(strary[0]);
for (i = 0; i < num; ++i) { len += RSTRING_LEN(strary[i]); }
- str = rb_str_buf_new(len);
- str_enc_copy_direct(str, strary[0]);
+ if (LIKELY(len < MIN_PRE_ALLOC_SIZE)) {
+ str = rb_str_resurrect(strary[0]);
+ s = 1;
+ }
+ else {
+ str = rb_str_buf_new(len);
+ rb_enc_copy(str, strary[0]);
+ s = 0;
+ }
for (i = s; i < num; ++i) {
const VALUE v = strary[i];
@@ -3454,7 +3405,7 @@ rb_str_concat_literals(size_t num, const VALUE *strary)
* s.concat('bar', 'baz') # => "foobarbaz"
* s # => "foobarbaz"
*
- * For each given object +object+ that is an Integer,
+ * For each given object +object+ that is an \Integer,
* the value is considered a codepoint and converted to a character before concatenation:
*
* s = 'foo'
@@ -3493,7 +3444,7 @@ rb_str_concat_multi(int argc, VALUE *argv, VALUE str)
* s << 'bar' # => "foobar"
* s # => "foobar"
*
- * If +object+ is an Integer,
+ * If +object+ is an \Integer,
* the value is considered a codepoint and converted to a character before concatenation:
*
* s = 'foo'
@@ -3622,12 +3573,11 @@ rb_str_prepend_multi(int argc, VALUE *argv, VALUE str)
st_index_t
rb_str_hash(VALUE str)
{
- st_index_t h = rb_memhash((const void *)RSTRING_PTR(str), RSTRING_LEN(str));
- int e = RSTRING_LEN(str) ? ENCODING_GET(str) : 0;
- if (e && !is_ascii_string(str)) {
- h = rb_hash_end(rb_hash_uint32(h, (uint32_t)e));
+ int e = ENCODING_GET(str);
+ if (e && is_ascii_string(str)) {
+ e = 0;
}
- return h;
+ return rb_memhash((const void *)RSTRING_PTR(str), RSTRING_LEN(str)) ^ e;
}
int
@@ -3763,7 +3713,7 @@ rb_str_equal(VALUE str1, VALUE str2)
*
*/
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
if (str1 == str2) return Qtrue;
@@ -3973,9 +3923,7 @@ strseq_core(const char *str_ptr, const char *str_ptr_end, long str_len,
return pos + offset;
}
-/* found index in byte */
#define rb_str_index(str, sub, offset) rb_strseq_index(str, sub, offset, 0)
-#define rb_str_byteindex(str, sub, offset) rb_strseq_index(str, sub, offset, 1)
static long
rb_strseq_index(VALUE str, VALUE sub, long offset, int in_byte)
@@ -4029,28 +3977,36 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str)
{
VALUE sub;
VALUE initpos;
- rb_encoding *enc = STR_ENC_GET(str);
long pos;
if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
- long slen = str_strlen(str, enc); /* str's enc */
pos = NUM2LONG(initpos);
- if (pos < 0 ? (pos += slen) < 0 : pos > slen) {
+ }
+ else {
+ pos = 0;
+ }
+ if (pos < 0) {
+ pos += str_strlen(str, NULL);
+ if (pos < 0) {
if (RB_TYPE_P(sub, T_REGEXP)) {
rb_backref_set(Qnil);
}
return Qnil;
}
}
- else {
- pos = 0;
- }
if (RB_TYPE_P(sub, T_REGEXP)) {
+ if (pos > str_strlen(str, NULL)) {
+ rb_backref_set(Qnil);
+ return Qnil;
+ }
pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
- enc, single_byte_optimizable(str));
+ rb_enc_check(str, sub), single_byte_optimizable(str));
- if (rb_reg_search(sub, str, pos, 0) >= 0) {
+ if (rb_reg_search(sub, str, pos, 0) < 0) {
+ return Qnil;
+ }
+ else {
VALUE match = rb_backref_get();
struct re_registers *regs = RMATCH_REGS(match);
pos = rb_str_sublen(str, BEG(0));
@@ -4060,28 +4016,25 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str)
else {
StringValue(sub);
pos = rb_str_index(str, sub, pos);
- if (pos >= 0) {
- pos = rb_str_sublen(str, pos);
- return LONG2NUM(pos);
- }
+ pos = rb_str_sublen(str, pos);
}
- return Qnil;
+
+ if (pos == -1) return Qnil;
+ return LONG2NUM(pos);
}
-/* Ensure that the given pos is a valid character boundary.
+/* whether given pos is valid character boundary or not
* Note that in this function, "character" means a code point
* (Unicode scalar value), not a grapheme cluster.
*/
-static void
-str_ensure_byte_pos(VALUE str, long pos)
+static bool
+str_check_byte_pos(VALUE str, long pos)
{
const char *s = RSTRING_PTR(str);
const char *e = RSTRING_END(str);
const char *p = s + pos;
- if (!at_char_boundary(s, p, e, rb_enc_get(str))) {
- rb_raise(rb_eIndexError,
- "offset %ld does not land on character boundary", pos);
- }
+ const char *pp = rb_enc_left_char_head(s, p, e, rb_enc_get(str));
+ return p == pp;
}
/*
@@ -4089,7 +4042,7 @@ str_ensure_byte_pos(VALUE str, long pos)
* byteindex(substring, offset = 0) -> integer or nil
* byteindex(regexp, offset = 0) -> integer or nil
*
- * Returns the Integer byte-based index of the first occurrence of the given +substring+,
+ * Returns the \Integer byte-based index of the first occurrence of the given +substring+,
* or +nil+ if none found:
*
* 'foo'.byteindex('f') # => 0
@@ -4097,7 +4050,7 @@ str_ensure_byte_pos(VALUE str, long pos)
* 'foo'.byteindex('oo') # => 1
* 'foo'.byteindex('ooo') # => nil
*
- * Returns the Integer byte-based index of the first match for the given Regexp +regexp+,
+ * Returns the \Integer byte-based index of the first match for the given \Regexp +regexp+,
* or +nil+ if none found:
*
* 'foo'.byteindex(/f/) # => 0
@@ -4105,7 +4058,7 @@ str_ensure_byte_pos(VALUE str, long pos)
* 'foo'.byteindex(/oo/) # => 1
* 'foo'.byteindex(/ooo/) # => nil
*
- * Integer argument +offset+, if given, specifies the byte-based position in the
+ * \Integer argument +offset+, if given, specifies the byte-based position in the
* string to begin the search:
*
* 'foo'.byteindex('o', 1) # => 1
@@ -4135,7 +4088,10 @@ rb_str_byteindex_m(int argc, VALUE *argv, VALUE str)
if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
long slen = RSTRING_LEN(str);
pos = NUM2LONG(initpos);
- if (pos < 0 ? (pos += slen) < 0 : pos > slen) {
+ if (pos < 0) {
+ pos += slen;
+ }
+ if (pos < 0 || pos > slen) {
if (RB_TYPE_P(sub, T_REGEXP)) {
rb_backref_set(Qnil);
}
@@ -4146,10 +4102,16 @@ rb_str_byteindex_m(int argc, VALUE *argv, VALUE str)
pos = 0;
}
- str_ensure_byte_pos(str, pos);
+ if (!str_check_byte_pos(str, pos)) {
+ rb_raise(rb_eIndexError,
+ "offset %ld does not land on character boundary", pos);
+ }
if (RB_TYPE_P(sub, T_REGEXP)) {
- if (rb_reg_search(sub, str, pos, 0) >= 0) {
+ if (rb_reg_search(sub, str, pos, 0) < 0) {
+ return Qnil;
+ }
+ else {
VALUE match = rb_backref_get();
struct re_registers *regs = RMATCH_REGS(match);
pos = BEG(0);
@@ -4158,10 +4120,11 @@ rb_str_byteindex_m(int argc, VALUE *argv, VALUE str)
}
else {
StringValue(sub);
- pos = rb_str_byteindex(str, sub, pos);
- if (pos >= 0) return LONG2NUM(pos);
+ pos = rb_strseq_index(str, sub, pos, 1);
}
- return Qnil;
+
+ if (pos == -1) return Qnil;
+ return LONG2NUM(pos);
}
#ifdef HAVE_MEMRCHR
@@ -4220,7 +4183,6 @@ str_rindex(VALUE str, VALUE sub, const char *s, rb_encoding *enc)
}
#endif
-/* found index in byte */
static long
rb_str_rindex(VALUE str, VALUE sub, long pos)
{
@@ -4250,7 +4212,7 @@ rb_str_rindex(VALUE str, VALUE sub, long pos)
}
s = str_nth(sbeg, RSTRING_END(str), pos, enc, singlebyte);
- return str_rindex(str, sub, s, enc);
+ return rb_str_sublen(str, str_rindex(str, sub, s, enc));
}
/*
@@ -4258,7 +4220,7 @@ rb_str_rindex(VALUE str, VALUE sub, long pos)
* rindex(substring, offset = self.length) -> integer or nil
* rindex(regexp, offset = self.length) -> integer or nil
*
- * Returns the Integer index of the _last_ occurrence of the given +substring+,
+ * Returns the \Integer index of the _last_ occurrence of the given +substring+,
* or +nil+ if none found:
*
* 'foo'.rindex('f') # => 0
@@ -4266,7 +4228,7 @@ rb_str_rindex(VALUE str, VALUE sub, long pos)
* 'foo'.rindex('oo') # => 1
* 'foo'.rindex('ooo') # => nil
*
- * Returns the Integer index of the _last_ match for the given Regexp +regexp+,
+ * Returns the \Integer index of the _last_ match for the given \Regexp +regexp+,
* or +nil+ if none found:
*
* 'foo'.rindex(/f/) # => 0
@@ -4291,7 +4253,7 @@ rb_str_rindex(VALUE str, VALUE sub, long pos)
* 'foo'.index(/o+(?!.*o)/) # => 1
* $~ #=> #<MatchData "oo">
*
- * Integer argument +offset+, if given and non-negative, specifies the maximum starting position in the
+ * \Integer argument +offset+, if given and non-negative, specifies the maximum starting position in the
* string to _end_ the search:
*
* 'foo'.rindex('o', 0) # => nil
@@ -4299,7 +4261,7 @@ rb_str_rindex(VALUE str, VALUE sub, long pos)
* 'foo'.rindex('o', 2) # => 2
* 'foo'.rindex('o', 3) # => 2
*
- * If +offset+ is a negative Integer, the maximum starting position in the
+ * If +offset+ is a negative \Integer, the maximum starting position in the
* string to _end_ the search is the sum of the string's length and +offset+:
*
* 'foo'.rindex('o', -1) # => 2
@@ -4314,17 +4276,20 @@ static VALUE
rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
{
VALUE sub;
- VALUE initpos;
+ VALUE vpos;
rb_encoding *enc = STR_ENC_GET(str);
long pos, len = str_strlen(str, enc); /* str's enc */
- if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
- pos = NUM2LONG(initpos);
- if (pos < 0 && (pos += len) < 0) {
- if (RB_TYPE_P(sub, T_REGEXP)) {
- rb_backref_set(Qnil);
+ if (rb_scan_args(argc, argv, "11", &sub, &vpos) == 2) {
+ pos = NUM2LONG(vpos);
+ if (pos < 0) {
+ pos += len;
+ if (pos < 0) {
+ if (RB_TYPE_P(sub, T_REGEXP)) {
+ rb_backref_set(Qnil);
+ }
+ return Qnil;
}
- return Qnil;
}
if (pos > len) pos = len;
}
@@ -4333,7 +4298,7 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
}
if (RB_TYPE_P(sub, T_REGEXP)) {
- /* enc = rb_enc_check(str, sub); */
+ /* enc = rb_get_check(str, sub); */
pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
enc, single_byte_optimizable(str));
@@ -4347,10 +4312,7 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
else {
StringValue(sub);
pos = rb_str_rindex(str, sub, pos);
- if (pos >= 0) {
- pos = rb_str_sublen(str, pos);
- return LONG2NUM(pos);
- }
+ if (pos >= 0) return LONG2NUM(pos);
}
return Qnil;
}
@@ -4391,7 +4353,7 @@ rb_str_byterindex(VALUE str, VALUE sub, long pos)
* byterindex(substring, offset = self.bytesize) -> integer or nil
* byterindex(regexp, offset = self.bytesize) -> integer or nil
*
- * Returns the Integer byte-based index of the _last_ occurrence of the given +substring+,
+ * Returns the \Integer byte-based index of the _last_ occurrence of the given +substring+,
* or +nil+ if none found:
*
* 'foo'.byterindex('f') # => 0
@@ -4399,7 +4361,7 @@ rb_str_byterindex(VALUE str, VALUE sub, long pos)
* 'foo'.byterindex('oo') # => 1
* 'foo'.byterindex('ooo') # => nil
*
- * Returns the Integer byte-based index of the _last_ match for the given Regexp +regexp+,
+ * Returns the \Integer byte-based index of the _last_ match for the given \Regexp +regexp+,
* or +nil+ if none found:
*
* 'foo'.byterindex(/f/) # => 0
@@ -4424,7 +4386,7 @@ rb_str_byterindex(VALUE str, VALUE sub, long pos)
* 'foo'.byteindex(/o+(?!.*o)/) # => 1
* $~ #=> #<MatchData "oo">
*
- * Integer argument +offset+, if given and non-negative, specifies the maximum starting byte-based position in the
+ * \Integer argument +offset+, if given and non-negative, specifies the maximum starting byte-based position in the
* string to _end_ the search:
*
* 'foo'.byterindex('o', 0) # => nil
@@ -4432,7 +4394,7 @@ rb_str_byterindex(VALUE str, VALUE sub, long pos)
* 'foo'.byterindex('o', 2) # => 2
* 'foo'.byterindex('o', 3) # => 2
*
- * If +offset+ is a negative Integer, the maximum starting position in the
+ * If +offset+ is a negative \Integer, the maximum starting position in the
* string to _end_ the search is the sum of the string's length and +offset+:
*
* 'foo'.byterindex('o', -1) # => 2
@@ -4450,16 +4412,19 @@ static VALUE
rb_str_byterindex_m(int argc, VALUE *argv, VALUE str)
{
VALUE sub;
- VALUE initpos;
+ VALUE vpos;
long pos, len = RSTRING_LEN(str);
- if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
- pos = NUM2LONG(initpos);
- if (pos < 0 && (pos += len) < 0) {
- if (RB_TYPE_P(sub, T_REGEXP)) {
- rb_backref_set(Qnil);
+ if (rb_scan_args(argc, argv, "11", &sub, &vpos) == 2) {
+ pos = NUM2LONG(vpos);
+ if (pos < 0) {
+ pos += len;
+ if (pos < 0) {
+ if (RB_TYPE_P(sub, T_REGEXP)) {
+ rb_backref_set(Qnil);
+ }
+ return Qnil;
}
- return Qnil;
}
if (pos > len) pos = len;
}
@@ -4467,7 +4432,10 @@ rb_str_byterindex_m(int argc, VALUE *argv, VALUE str)
pos = len;
}
- str_ensure_byte_pos(str, pos);
+ if (!str_check_byte_pos(str, pos)) {
+ rb_raise(rb_eIndexError,
+ "offset %ld does not land on character boundary", pos);
+ }
if (RB_TYPE_P(sub, T_REGEXP)) {
if (rb_reg_search(sub, str, pos, 1) >= 0) {
@@ -4490,16 +4458,16 @@ rb_str_byterindex_m(int argc, VALUE *argv, VALUE str)
* string =~ regexp -> integer or nil
* string =~ object -> integer or nil
*
- * Returns the Integer index of the first substring that matches
+ * Returns the \Integer index of the first substring that matches
* the given +regexp+, or +nil+ if no match found:
*
* 'foo' =~ /f/ # => 0
* 'foo' =~ /o/ # => 1
* 'foo' =~ /x/ # => nil
*
- * Note: also updates Regexp@Global+Variables.
+ * Note: also updates Regexp@Special+global+variables.
*
- * If the given +object+ is not a Regexp, returns the value
+ * If the given +object+ is not a \Regexp, returns the value
* returned by <tt>object =~ self</tt>.
*
* Note that <tt>string =~ regexp</tt> is different from <tt>regexp =~ string</tt>
@@ -4537,13 +4505,13 @@ static VALUE get_pat(VALUE);
* match(pattern, offset = 0) -> matchdata or nil
* match(pattern, offset = 0) {|matchdata| ... } -> object
*
- * Returns a MatchData object (or +nil+) based on +self+ and the given +pattern+.
+ * Returns a \MatchData object (or +nil+) based on +self+ and the given +pattern+.
*
- * Note: also updates Regexp@Global+Variables.
+ * Note: also updates Regexp@Special+global+variables.
*
- * - Computes +regexp+ by converting +pattern+ (if not already a Regexp).
+ * - Computes +regexp+ by converting +pattern+ (if not already a \Regexp).
* regexp = Regexp.new(pattern)
- * - Computes +matchdata+, which will be either a MatchData object or +nil+
+ * - Computes +matchdata+, which will be either a \MatchData object or +nil+
* (see Regexp#match):
* matchdata = <tt>regexp.match(self)
*
@@ -4553,7 +4521,7 @@ static VALUE get_pat(VALUE);
* 'foo'.match('o') # => #<MatchData "o">
* 'foo'.match('x') # => nil
*
- * If Integer argument +offset+ is given, the search begins at index +offset+:
+ * If \Integer argument +offset+ is given, the search begins at index +offset+:
*
* 'foo'.match('f', 1) # => nil
* 'foo'.match('o', 1) # => #<MatchData "o">
@@ -4588,19 +4556,19 @@ rb_str_match_m(int argc, VALUE *argv, VALUE str)
*
* Returns +true+ or +false+ based on whether a match is found for +self+ and +pattern+.
*
- * Note: does not update Regexp@Global+Variables.
+ * Note: does not update Regexp@Special+global+variables.
*
- * Computes +regexp+ by converting +pattern+ (if not already a Regexp).
+ * Computes +regexp+ by converting +pattern+ (if not already a \Regexp).
* regexp = Regexp.new(pattern)
*
- * Returns +true+ if <tt>self+.match(regexp)</tt> returns a MatchData object,
+ * Returns +true+ if <tt>self+.match(regexp)</tt> returns a \MatchData object,
* +false+ otherwise:
*
* 'foo'.match?(/o/) # => true
* 'foo'.match?('o') # => true
* 'foo'.match?(/x/) # => false
*
- * If Integer argument +offset+ is given, the search begins at index +offset+:
+ * If \Integer argument +offset+ is given, the search begins at index +offset+:
* 'foo'.match?('f', 1) # => false
* 'foo'.match?('o', 1) # => true
*
@@ -4856,6 +4824,7 @@ static VALUE str_succ(VALUE str);
*
* ''.succ # => ""
*
+ * String#next is an alias for String#succ.
*/
VALUE
@@ -4960,6 +4929,8 @@ str_succ(VALUE str)
* succ! -> self
*
* Equivalent to String#succ, but modifies +self+ in place; returns +self+.
+ *
+ * String#next! is an alias for String#succ!.
*/
static VALUE
@@ -5016,7 +4987,7 @@ str_upto_i(VALUE str, VALUE arg)
* '25'.upto('5') {|s| fail s }
* 'aa'.upto('a') {|s| fail s }
*
- * With no block given, returns a new Enumerator:
+ * With no block given, returns a new \Enumerator:
*
* 'a8'.upto('b6') # => #<Enumerator: "a8":upto("b6")>
*
@@ -5299,6 +5270,7 @@ rb_str_drop_bytes(VALUE str, long len)
char *oldptr = ptr;
int fl = (int)(RBASIC(str)->flags & (STR_NOEMBED|STR_SHARED|STR_NOFREE));
STR_SET_EMBED(str);
+ STR_SET_EMBED_LEN(str, nlen);
ptr = RSTRING(str)->as.embed.ary;
memmove(ptr, oldptr + len, nlen);
if (fl == STR_NOEMBED) xfree(oldptr);
@@ -5310,21 +5282,18 @@ rb_str_drop_bytes(VALUE str, long len)
OBJ_FREEZE(shared);
}
ptr = RSTRING(str)->as.heap.ptr += len;
+ RSTRING(str)->as.heap.len = nlen;
}
- STR_SET_LEN(str, nlen);
-
- if (!SHARABLE_MIDDLE_SUBSTRING) {
- TERM_FILL(ptr + nlen, TERM_LEN(str));
- }
+ ptr[nlen] = 0;
ENC_CODERANGE_CLEAR(str);
return str;
}
static void
-rb_str_update_1(VALUE str, long beg, long len, VALUE val, long vbeg, long vlen)
+rb_str_splice_0(VALUE str, long beg, long len, VALUE val)
{
char *sptr;
- long slen;
+ long slen, vlen = RSTRING_LEN(val);
int cr;
if (beg == 0 && vlen == 0) {
@@ -5354,7 +5323,7 @@ rb_str_update_1(VALUE str, long beg, long len, VALUE val, long vbeg, long vlen)
MEMZERO(sptr + slen, char, -len);
}
if (vlen > 0) {
- memmove(sptr + beg, RSTRING_PTR(val) + vbeg, vlen);
+ memmove(sptr + beg, RSTRING_PTR(val), vlen);
}
slen += vlen - len;
STR_SET_LEN(str, slen);
@@ -5362,12 +5331,6 @@ rb_str_update_1(VALUE str, long beg, long len, VALUE val, long vbeg, long vlen)
ENC_CODERANGE_SET(str, cr);
}
-static inline void
-rb_str_update_0(VALUE str, long beg, long len, VALUE val)
-{
- rb_str_update_1(str, beg, len, val, 0, RSTRING_LEN(val));
-}
-
void
rb_str_update(VALUE str, long beg, long len, VALUE val)
{
@@ -5401,13 +5364,15 @@ rb_str_update(VALUE str, long beg, long len, VALUE val)
/* error check */
beg = p - RSTRING_PTR(str); /* physical position */
len = e - p; /* physical length */
- rb_str_update_0(str, beg, len, val);
+ rb_str_splice_0(str, beg, len, val);
rb_enc_associate(str, enc);
cr = ENC_CODERANGE_AND(ENC_CODERANGE(str), ENC_CODERANGE(val));
if (cr != ENC_CODERANGE_BROKEN)
ENC_CODERANGE_SET(str, cr);
}
+#define rb_str_splice(str, beg, len, val) rb_str_update(str, beg, len, val)
+
static void
rb_str_subpat_set(VALUE str, VALUE re, VALUE backref, VALUE val)
{
@@ -5438,7 +5403,7 @@ rb_str_subpat_set(VALUE str, VALUE re, VALUE backref, VALUE val)
len = end - start;
StringValue(val);
enc = rb_enc_check_str(str, val);
- rb_str_update_0(str, start, len, val);
+ rb_str_splice_0(str, start, len, val);
rb_enc_associate(str, enc);
}
@@ -5458,7 +5423,7 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val)
rb_raise(rb_eIndexError, "string not matched");
}
beg = rb_str_sublen(str, beg);
- rb_str_update(str, beg, str_strlen(indx, NULL), val);
+ rb_str_splice(str, beg, str_strlen(indx, NULL), val);
return val;
default:
@@ -5466,7 +5431,7 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val)
{
long beg, len;
if (rb_range_beg_len(indx, &beg, &len, str_strlen(str, NULL), 2)) {
- rb_str_update(str, beg, len, val);
+ rb_str_splice(str, beg, len, val);
return val;
}
}
@@ -5474,7 +5439,7 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val)
case T_FIXNUM:
idx = NUM2LONG(indx);
- rb_str_update(str, idx, 1, val);
+ rb_str_splice(str, idx, 1, val);
return val;
}
}
@@ -5504,6 +5469,8 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val)
* s['lly'] = 'ncial' # => "ncial"
* s # => "financial"
*
+ * String#slice is an alias for String#[].
+ *
*/
static VALUE
@@ -5514,7 +5481,7 @@ rb_str_aset_m(int argc, VALUE *argv, VALUE str)
rb_str_subpat_set(str, argv[0], argv[1], argv[2]);
}
else {
- rb_str_update(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
+ rb_str_splice(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
}
return argv[2];
}
@@ -5528,11 +5495,11 @@ rb_str_aset_m(int argc, VALUE *argv, VALUE str)
*
* Inserts the given +other_string+ into +self+; returns +self+.
*
- * If the Integer +index+ is positive, inserts +other_string+ at offset +index+:
+ * If the \Integer +index+ is positive, inserts +other_string+ at offset +index+:
*
* 'foo'.insert(1, 'bar') # => "fbaroo"
*
- * If the Integer +index+ is negative, counts backward from the end of +self+
+ * If the \Integer +index+ is negative, counts backward from the end of +self+
* and inserts +other_string+ at offset <tt>index+1</tt>
* (that is, _after_ <tt>self[index]</tt>):
*
@@ -5551,7 +5518,7 @@ rb_str_insert(VALUE str, VALUE idx, VALUE str2)
else if (pos < 0) {
pos++;
}
- rb_str_update(str, pos, 0, str2);
+ rb_str_splice(str, pos, 0, str2);
return str;
}
@@ -5717,7 +5684,7 @@ static long
rb_pat_search(VALUE pat, VALUE str, long pos, int set_backref_str)
{
if (BUILTIN_TYPE(pat) == T_STRING) {
- pos = rb_str_byteindex(str, pat, pos);
+ pos = rb_strseq_index(str, pat, pos, 1);
if (set_backref_str) {
if (pos >= 0) {
str = rb_str_new_frozen_String(str);
@@ -5852,8 +5819,6 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str));
ENC_CODERANGE_SET(str, cr);
- RB_GC_GUARD(match);
-
return str;
}
return Qnil;
@@ -5885,7 +5850,8 @@ rb_str_sub(int argc, VALUE *argv, VALUE str)
static VALUE
str_gsub(int argc, VALUE *argv, VALUE str, int bang)
{
- VALUE pat, val = Qnil, repl, match0 = Qnil, dest, hash = Qnil;
+ VALUE pat, val = Qnil, repl, match, match0 = Qnil, dest, hash = Qnil;
+ struct re_registers *regs;
long beg, beg0, end0;
long offset, blen, slen, len, last;
enum {STR, ITER, MAP} mode = STR;
@@ -5930,8 +5896,8 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);
do {
- VALUE match = rb_backref_get();
- struct re_registers *regs = RMATCH_REGS(match);
+ match = rb_backref_get();
+ regs = RMATCH_REGS(match);
if (RB_TYPE_P(pat, T_STRING)) {
beg0 = beg;
end0 = beg0 + RSTRING_LEN(pat);
@@ -5988,8 +5954,6 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
cp = RSTRING_PTR(str) + offset;
if (offset > RSTRING_LEN(str)) break;
beg = rb_pat_search(pat, str, offset, need_backref);
-
- RB_GC_GUARD(match);
} while (beg >= 0);
if (RSTRING_LEN(str) > offset) {
rb_enc_str_buf_cat(dest, cp, RSTRING_LEN(str) - offset, str_enc);
@@ -6092,7 +6056,7 @@ rb_str_clear(VALUE str)
{
str_discard(str);
STR_SET_EMBED(str);
- STR_SET_LEN(str, 0);
+ STR_SET_EMBED_LEN(str, 0);
RSTRING_PTR(str)[0] = 0;
if (rb_enc_asciicompat(STR_ENC_GET(str)))
ENC_CODERANGE_SET(str, ENC_CODERANGE_7BIT);
@@ -6131,7 +6095,7 @@ rb_str_chr(VALUE str)
*
* Related: String#setbyte.
*/
-VALUE
+static VALUE
rb_str_getbyte(VALUE str, VALUE index)
{
long pos = NUM2LONG(index);
@@ -6230,7 +6194,7 @@ str_byte_substr(VALUE str, long beg, long len, int empty)
VALUE str2 = str_subseq(str, beg, len);
- str_enc_copy_direct(str2, str);
+ str_enc_copy(str2, str);
if (RSTRING_LEN(str2) == 0) {
if (!rb_enc_asciicompat(STR_ENC_GET(str)))
@@ -6332,43 +6296,16 @@ rb_str_byteslice(int argc, VALUE *argv, VALUE str)
return str_byte_aref(str, argv[0]);
}
-static void
-str_check_beg_len(VALUE str, long *beg, long *len)
-{
- long end, slen = RSTRING_LEN(str);
-
- if (*len < 0) rb_raise(rb_eIndexError, "negative length %ld", *len);
- if ((slen < *beg) || ((*beg < 0) && (*beg + slen < 0))) {
- rb_raise(rb_eIndexError, "index %ld out of string", *beg);
- }
- if (*beg < 0) {
- *beg += slen;
- }
- assert(*beg >= 0);
- assert(*beg <= slen);
- if (*len > slen - *beg) {
- *len = slen - *beg;
- }
- end = *beg + *len;
- str_ensure_byte_pos(str, *beg);
- str_ensure_byte_pos(str, end);
-}
-
/*
* call-seq:
* bytesplice(index, length, str) -> string
- * bytesplice(index, length, str, str_index, str_length) -> string
- * bytesplice(range, str) -> string
- * bytesplice(range, str, str_range) -> string
+ * bytesplice(range, str) -> string
*
* Replaces some or all of the content of +self+ with +str+, and returns +self+.
* The portion of the string affected is determined using
* the same criteria as String#byteslice, except that +length+ cannot be omitted.
* If the replacement string is not the same length as the text it is replacing,
* the string will be adjusted accordingly.
- *
- * If +str_index+ and +str_length+, or +str_range+ are given, the content of +self+ is replaced by str.byteslice(str_index, str_length) or str.byteslice(str_range); however the substring of +str+ is not allocated as a new string.
- *
* The form that take an Integer will raise an IndexError if the value is out
* of range; the Range form will raise a RangeError.
* If the beginning or ending offset does not land on character (codepoint)
@@ -6378,56 +6315,50 @@ str_check_beg_len(VALUE str, long *beg, long *len)
static VALUE
rb_str_bytesplice(int argc, VALUE *argv, VALUE str)
{
- long beg, len, vbeg, vlen;
+ long beg, end, len, slen;
VALUE val;
rb_encoding *enc;
int cr;
- rb_check_arity(argc, 2, 5);
- if (!(argc == 2 || argc == 3 || argc == 5)) {
- rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 2, 3, or 5)", argc);
- }
- if (argc == 2 || (argc == 3 && !RB_INTEGER_TYPE_P(argv[0]))) {
+ rb_check_arity(argc, 2, 3);
+ if (argc == 2) {
if (!rb_range_beg_len(argv[0], &beg, &len, RSTRING_LEN(str), 2)) {
rb_raise(rb_eTypeError, "wrong argument type %s (expected Range)",
rb_builtin_class_name(argv[0]));
}
val = argv[1];
- StringValue(val);
- if (argc == 2) {
- /* bytesplice(range, str) */
- vbeg = 0;
- vlen = RSTRING_LEN(val);
- }
- else {
- /* bytesplice(range, str, str_range) */
- if (!rb_range_beg_len(argv[2], &vbeg, &vlen, RSTRING_LEN(val), 2)) {
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Range)",
- rb_builtin_class_name(argv[2]));
- }
- }
}
else {
beg = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
val = argv[2];
- StringValue(val);
- if (argc == 3) {
- /* bytesplice(index, length, str) */
- vbeg = 0;
- vlen = RSTRING_LEN(val);
- }
- else {
- /* bytesplice(index, length, str, str_index, str_length) */
- vbeg = NUM2LONG(argv[3]);
- vlen = NUM2LONG(argv[4]);
- }
}
- str_check_beg_len(str, &beg, &len);
- str_check_beg_len(val, &vbeg, &vlen);
+ if (len < 0) rb_raise(rb_eIndexError, "negative length %ld", len);
+ slen = RSTRING_LEN(str);
+ if ((slen < beg) || ((beg < 0) && (beg + slen < 0))) {
+ rb_raise(rb_eIndexError, "index %ld out of string", beg);
+ }
+ if (beg < 0) {
+ beg += slen;
+ }
+ assert(beg >= 0);
+ assert(beg <= slen);
+ if (len > slen - beg) {
+ len = slen - beg;
+ }
+ end = beg + len;
+ if (!str_check_byte_pos(str, beg)) {
+ rb_raise(rb_eIndexError,
+ "offset %ld does not land on character boundary", beg);
+ }
+ if (!str_check_byte_pos(str, end)) {
+ rb_raise(rb_eIndexError,
+ "offset %ld does not land on character boundary", end);
+ }
+ StringValue(val);
enc = rb_enc_check(str, val);
str_modify_keep_cr(str);
- rb_str_update_1(str, beg, len, val, vbeg, vlen);
+ rb_str_splice_0(str, beg, len, val);
rb_enc_associate(str, enc);
cr = ENC_CODERANGE_AND(ENC_CODERANGE(str), ENC_CODERANGE(val));
if (cr != ENC_CODERANGE_BROKEN)
@@ -6489,7 +6420,7 @@ rb_str_reverse(VALUE str)
}
}
STR_SET_LEN(rev, RSTRING_LEN(str));
- str_enc_copy_direct(rev, str);
+ str_enc_copy(rev, str);
ENC_CODERANGE_SET(rev, cr);
return rev;
@@ -6611,7 +6542,7 @@ rb_str_to_i(int argc, VALUE *argv, VALUE str)
* Returns the result of interpreting leading characters in +self+ as a Float:
*
* '3.14159'.to_f # => 3.14159
- * '1.234e-2'.to_f # => 0.01234
+ '1.234e-2'.to_f # => 0.01234
*
* Characters past a leading valid number (in the given +base+) are ignored:
*
@@ -6636,6 +6567,9 @@ rb_str_to_f(VALUE str)
*
* Returns +self+ if +self+ is a \String,
* or +self+ converted to a \String if +self+ is a subclass of \String.
+ *
+ * String#to_str is an alias for String#to_s.
+ *
*/
static VALUE
@@ -7270,8 +7204,6 @@ str_undump(VALUE str)
}
}
- RB_GC_GUARD(str);
-
return undumped;
invalid_format:
rb_raise(rb_eRuntimeError, "invalid dumped string; not wrapped with '\"' nor '\"...\".force_encoding(\"...\")' form");
@@ -7370,8 +7302,7 @@ mapping_buffer_free(void *p)
static const rb_data_type_t mapping_buffer_type = {
"mapping_buffer",
- {0, mapping_buffer_free,},
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
+ {0, mapping_buffer_free,}
};
static VALUE
@@ -7444,7 +7375,7 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
RB_GC_GUARD(buffer_anchor);
/* TODO: check about string terminator character */
- str_enc_copy_direct(target, source);
+ str_enc_copy(target, source);
/*ENC_CODERANGE_SET(mapped, cr);*/
return target;
@@ -7575,7 +7506,7 @@ rb_str_upcase(int argc, VALUE *argv, VALUE str)
enc = str_true_enc(str);
if (case_option_single_p(flags, enc, str)) {
ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
- str_enc_copy_direct(ret, str);
+ str_enc_copy(ret, str);
upcase_single(ret);
}
else if (flags&ONIGENC_CASE_ASCII_ONLY) {
@@ -7677,7 +7608,7 @@ rb_str_downcase(int argc, VALUE *argv, VALUE str)
enc = str_true_enc(str);
if (case_option_single_p(flags, enc, str)) {
ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
- str_enc_copy_direct(ret, str);
+ str_enc_copy(ret, str);
downcase_single(ret);
}
else if (flags&ONIGENC_CASE_ASCII_ONLY) {
@@ -7886,10 +7817,8 @@ trnext(struct tr *t, rb_encoding *enc)
}
continue; /* not reached */
}
- else if (t->now < c) {
- t->gen = 1;
- t->max = c;
- }
+ t->gen = 1;
+ t->max = c;
}
}
return t->now;
@@ -8070,7 +7999,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
}
TERM_FILL((char *)t, termlen);
RSTRING(str)->as.heap.ptr = (char *)buf;
- STR_SET_LEN(str, t - buf);
+ RSTRING(str)->as.heap.len = t - buf;
STR_SET_NOEMBED(str);
RSTRING(str)->as.heap.aux.capa = max;
}
@@ -8146,7 +8075,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
}
TERM_FILL((char *)t, termlen);
RSTRING(str)->as.heap.ptr = (char *)buf;
- STR_SET_LEN(str, t - buf);
+ RSTRING(str)->as.heap.len = t - buf;
STR_SET_NOEMBED(str);
RSTRING(str)->as.heap.aux.capa = max;
}
@@ -8814,6 +8743,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
#define SPLIT_STR(beg, len) (empty_count = split_string(result, str, beg, len, empty_count))
+ if (result) result = rb_ary_new();
beg = 0;
char *ptr = RSTRING_PTR(str);
char *eptr = RSTRING_END(str);
@@ -8822,7 +8752,6 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
int skip = 1;
unsigned int c;
- if (result) result = rb_ary_new();
end = beg;
if (is_ascii_string(str)) {
while (ptr < eptr) {
@@ -8882,7 +8811,6 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
char *sptr = RSTRING_PTR(spat);
long slen = RSTRING_LEN(spat);
- if (result) result = rb_ary_new();
mustnot_broken(str);
enc = rb_enc_check(str, spat);
while (ptr < eptr &&
@@ -8904,7 +8832,6 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
char *str_start = ptr;
int n;
- if (result) result = rb_ary_new_capa(RSTRING_LEN(str));
mustnot_broken(str);
enc = rb_enc_get(str);
while (ptr < eptr &&
@@ -8916,7 +8843,6 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
beg = ptr - str_start;
}
else {
- if (result) result = rb_ary_new();
long len = RSTRING_LEN(str);
long start = beg;
long idx;
@@ -9703,7 +9629,7 @@ chompped_length(VALUE str, VALUE rs)
if (p[len-1] == newline &&
(rslen <= 1 ||
memcmp(rsptr, pp, rslen) == 0)) {
- if (at_char_boundary(p, pp, e, enc))
+ if (rb_enc_left_char_head(p, pp, e, enc) == pp)
return len - rslen;
RB_GC_GUARD(rs);
}
@@ -9758,7 +9684,7 @@ rb_str_chomp_bang(int argc, VALUE *argv, VALUE str)
{
VALUE rs;
str_modifiable(str);
- if (RSTRING_LEN(str) == 0 && argc < 2) return Qnil;
+ if (RSTRING_LEN(str) == 0) return Qnil;
rs = chomp_rs(argc, argv);
if (NIL_P(rs)) return Qnil;
return rb_str_chomp_string(str, rs);
@@ -10025,11 +9951,11 @@ rb_str_strip(VALUE str)
static VALUE
scan_once(VALUE str, VALUE pat, long *start, int set_backref_str)
{
- VALUE result = Qnil;
+ VALUE result, match;
+ struct re_registers *regs;
+ int i;
long end, pos = rb_pat_search(pat, str, *start, set_backref_str);
if (pos >= 0) {
- VALUE match;
- struct re_registers *regs;
if (BUILTIN_TYPE(pat) == T_STRING) {
regs = NULL;
end = pos + RSTRING_LEN(pat);
@@ -10040,7 +9966,6 @@ scan_once(VALUE str, VALUE pat, long *start, int set_backref_str)
pos = BEG(0);
end = END(0);
}
-
if (pos == end) {
rb_encoding *enc = STR_ENC_GET(str);
/*
@@ -10055,27 +9980,22 @@ scan_once(VALUE str, VALUE pat, long *start, int set_backref_str)
else {
*start = end;
}
-
if (!regs || regs->num_regs == 1) {
result = rb_str_subseq(str, pos, end - pos);
return result;
}
- else {
- result = rb_ary_new2(regs->num_regs);
- for (int i = 1; i < regs->num_regs; i++) {
- VALUE s = Qnil;
- if (BEG(i) >= 0) {
- s = rb_str_subseq(str, BEG(i), END(i)-BEG(i));
- }
-
- rb_ary_push(result, s);
+ result = rb_ary_new2(regs->num_regs);
+ for (i=1; i < regs->num_regs; i++) {
+ VALUE s = Qnil;
+ if (BEG(i) >= 0) {
+ s = rb_str_subseq(str, BEG(i), END(i)-BEG(i));
}
+ rb_ary_push(result, s);
}
- RB_GC_GUARD(match);
+ return result;
}
-
- return result;
+ return Qnil;
}
@@ -10620,6 +10540,7 @@ rb_str_rpartition(VALUE str, VALUE sep)
if (pos < 0) {
goto failed;
}
+ pos = rb_str_offset(str, pos);
}
return rb_ary_new3(3, rb_str_subseq(str, 0, pos),
@@ -10650,20 +10571,10 @@ rb_str_start_with(int argc, VALUE *argv, VALUE str)
return Qtrue;
}
else {
- const char *p, *s, *e;
- long slen, tlen;
- rb_encoding *enc;
-
StringValue(tmp);
- enc = rb_enc_check(str, tmp);
- if ((tlen = RSTRING_LEN(tmp)) == 0) return Qtrue;
- if ((slen = RSTRING_LEN(str)) < tlen) continue;
- p = RSTRING_PTR(str);
- e = p + slen;
- s = p + tlen;
- if (!at_char_right_boundary(p, s, e, enc))
- continue;
- if (memcmp(p, RSTRING_PTR(tmp), tlen) == 0)
+ rb_enc_check(str, tmp);
+ if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue;
+ if (memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
return Qtrue;
}
}
@@ -10682,13 +10593,12 @@ static VALUE
rb_str_end_with(int argc, VALUE *argv, VALUE str)
{
int i;
+ char *p, *s, *e;
+ rb_encoding *enc;
for (i=0; i<argc; i++) {
VALUE tmp = argv[i];
- const char *p, *s, *e;
long slen, tlen;
- rb_encoding *enc;
-
StringValue(tmp);
enc = rb_enc_check(str, tmp);
if ((tlen = RSTRING_LEN(tmp)) == 0) return Qtrue;
@@ -10696,9 +10606,9 @@ rb_str_end_with(int argc, VALUE *argv, VALUE str)
p = RSTRING_PTR(str);
e = p + slen;
s = e - tlen;
- if (!at_char_boundary(p, s, e, enc))
+ if (rb_enc_left_char_head(p, s, e, enc) != s)
continue;
- if (memcmp(s, RSTRING_PTR(tmp), tlen) == 0)
+ if (memcmp(s, RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
return Qtrue;
}
return Qfalse;
@@ -10716,17 +10626,12 @@ rb_str_end_with(int argc, VALUE *argv, VALUE str)
static long
deleted_prefix_length(VALUE str, VALUE prefix)
{
- const char *strptr, *prefixptr;
+ char *strptr, *prefixptr;
long olen, prefixlen;
- rb_encoding *enc = rb_enc_get(str);
StringValue(prefix);
-
- if (!is_broken_string(prefix) ||
- !rb_enc_asciicompat(enc) ||
- !rb_enc_asciicompat(rb_enc_get(prefix))) {
- enc = rb_enc_check(str, prefix);
- }
+ if (is_broken_string(prefix)) return 0;
+ rb_enc_check(str, prefix);
/* return 0 if not start with prefix */
prefixlen = RSTRING_LEN(prefix);
@@ -10736,19 +10641,6 @@ deleted_prefix_length(VALUE str, VALUE prefix)
strptr = RSTRING_PTR(str);
prefixptr = RSTRING_PTR(prefix);
if (memcmp(strptr, prefixptr, prefixlen) != 0) return 0;
- if (is_broken_string(prefix)) {
- if (!is_broken_string(str)) {
- /* prefix in a valid string cannot be broken */
- return 0;
- }
- const char *strend = strptr + olen;
- const char *after_prefix = strptr + prefixlen;
- if (!at_char_right_boundary(strptr, after_prefix, strend, enc)) {
- /* prefix does not end at char-boundary */
- return 0;
- }
- }
- /* prefix part in `str` also should be valid. */
return prefixlen;
}
@@ -10805,7 +10697,7 @@ rb_str_delete_prefix(VALUE str, VALUE prefix)
static long
deleted_suffix_length(VALUE str, VALUE suffix)
{
- const char *strptr, *suffixptr;
+ char *strptr, *suffixptr, *s;
long olen, suffixlen;
rb_encoding *enc;
@@ -10820,10 +10712,9 @@ deleted_suffix_length(VALUE str, VALUE suffix)
if (olen < suffixlen) return 0;
strptr = RSTRING_PTR(str);
suffixptr = RSTRING_PTR(suffix);
- const char *strend = strptr + olen;
- const char *before_suffix = strend - suffixlen;
- if (memcmp(before_suffix, suffixptr, suffixlen) != 0) return 0;
- if (!at_char_boundary(strptr, before_suffix, strend, enc)) return 0;
+ s = strptr + olen - suffixlen;
+ if (memcmp(s, suffixptr, suffixlen) != 0) return 0;
+ if (rb_enc_left_char_head(strptr, s, strptr + olen, enc) != s) return 0;
return suffixlen;
}
@@ -10913,23 +10804,7 @@ static VALUE
rb_str_force_encoding(VALUE str, VALUE enc)
{
str_modifiable(str);
-
- rb_encoding *encoding = rb_to_encoding(enc);
- int idx = rb_enc_to_index(encoding);
-
- // If the encoding is unchanged, we do nothing.
- if (ENCODING_GET(str) == idx) {
- return str;
- }
-
- rb_enc_associate_index(str, idx);
-
- // If the coderange was 7bit and the new encoding is ASCII-compatible
- // we can keep the coderange.
- if (ENC_CODERANGE(str) == ENC_CODERANGE_7BIT && encoding && rb_enc_asciicompat(encoding)) {
- return str;
- }
-
+ rb_enc_associate(str, rb_to_encoding(enc));
ENC_CODERANGE_CLEAR(str);
return str;
}
@@ -10946,11 +10821,11 @@ static VALUE
rb_str_b(VALUE str)
{
VALUE str2;
- if (STR_EMBED_P(str)) {
- str2 = str_alloc_embed(rb_cString, RSTRING_LEN(str) + TERM_LEN(str));
+ if (FL_TEST(str, STR_NOEMBED)) {
+ str2 = str_alloc_heap(rb_cString);
}
else {
- str2 = str_alloc_heap(rb_cString);
+ str2 = str_alloc_embed(rb_cString, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
}
str_replace_shared_without_enc(str2, str);
@@ -11119,7 +10994,7 @@ enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl, int cr)
encidx = rb_enc_to_index(enc);
#define DEFAULT_REPLACE_CHAR(str) do { \
- static const char replace[sizeof(str)-1] = str; \
+ RBIMPL_ATTR_NONSTRING() static const char replace[sizeof(str)-1] = str; \
rep = replace; replen = (int)sizeof(replace); \
} while (0)
@@ -11473,17 +11348,17 @@ rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str)
/**********************************************************************
* Document-class: Symbol
*
- * \Symbol objects represent named identifiers inside the Ruby interpreter.
+ * Symbol objects represent named identifiers inside the Ruby interpreter.
*
* You can create a \Symbol object explicitly with:
*
* - A {symbol literal}[rdoc-ref:syntax/literals.rdoc@Symbol+Literals].
*
- * The same \Symbol object will be
+ * The same Symbol object will be
* created for a given name or string for the duration of a program's
* execution, regardless of the context or meaning of that name. Thus
* if <code>Fred</code> is a constant in one context, a method in
- * another, and a class in a third, the \Symbol <code>:Fred</code>
+ * another, and a class in a third, the Symbol <code>:Fred</code>
* will be the same object in all three contexts.
*
* module One
@@ -11526,8 +11401,8 @@ rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str)
* local_variables
* # => [:seven]
*
- * \Symbol objects are different from String objects in that
- * \Symbol objects represent identifiers, while String objects
+ * Symbol objects are different from String objects in that
+ * Symbol objects represent identifiers, while String objects
* represent text or data.
*
* == What's Here
@@ -11597,6 +11472,9 @@ rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str)
* symbol == object -> true or false
*
* Returns +true+ if +object+ is the same object as +self+, +false+ otherwise.
+ *
+ * Symbol#=== is an alias for Symbol#==.
+ *
*/
#define sym_equal rb_obj_equal
@@ -11657,7 +11535,7 @@ rb_str_quote_unprintable(VALUE str)
return str;
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_id_quote_unprintable(ID id)
{
VALUE str = rb_id2str(id);
@@ -11696,15 +11574,10 @@ sym_inspect(VALUE sym)
}
else {
rb_encoding *enc = STR_ENC_GET(str);
-
- VALUE orig_str = str;
- RSTRING_GETMEM(orig_str, ptr, len);
-
+ RSTRING_GETMEM(str, ptr, len);
str = rb_enc_str_new(0, len + 1, enc);
dest = RSTRING_PTR(str);
memcpy(dest + 1, ptr, len);
-
- RB_GC_GUARD(orig_str);
}
dest[0] = ':';
return str;
@@ -11718,6 +11591,8 @@ sym_inspect(VALUE sym)
*
* :foo.to_s # => "foo"
*
+ * Symbol#id2name is an alias for Symbol#to_s.
+ *
* Related: Symbol#inspect, Symbol#name.
*/
@@ -11727,7 +11602,7 @@ rb_sym_to_s(VALUE sym)
return str_new_shared(rb_cString, rb_sym2str(sym));
}
-VALUE
+MJIT_FUNC_EXPORTED VALUE
rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc)
{
VALUE obj;
@@ -11747,6 +11622,8 @@ rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed
*
* :foo.succ # => :fop
*
+ * Symbol#next is an alias for Symbol#succ.
+ *
* Related: String#succ.
*/
@@ -11888,6 +11765,9 @@ sym_aref(int argc, VALUE *argv, VALUE sym)
* length -> integer
*
* Equivalent to <tt>self.to_s.length</tt>; see String#length.
+ *
+ * Symbol#size is an alias for Symbol#length.
+ *
*/
static VALUE
@@ -11992,7 +11872,7 @@ sym_start_with(int argc, VALUE *argv, VALUE sym)
/*
* call-seq:
- * end_with?(*strings) -> true or false
+ * end_with?(*string_or_regexp) -> true or false
*
*
* Equivalent to <tt>self.to_s.end_with?</tt>; see String#end_with?.
@@ -12114,7 +11994,6 @@ Init_String(void)
st_foreach(rb_vm_fstring_table(), fstring_set_class_i, rb_cString);
rb_include_module(rb_cString, rb_mComparable);
rb_define_alloc_func(rb_cString, empty_str_alloc);
- rb_define_singleton_method(rb_cString, "new", rb_str_s_new, -1);
rb_define_singleton_method(rb_cString, "try_convert", rb_str_s_try_convert, 1);
rb_define_method(rb_cString, "initialize", rb_str_init, -1);
rb_define_method(rb_cString, "initialize_copy", rb_str_replace, 1);
@@ -12159,7 +12038,6 @@ Init_String(void)
rb_define_method(rb_cString, "freeze", rb_str_freeze, 0);
rb_define_method(rb_cString, "+@", str_uplus, 0);
rb_define_method(rb_cString, "-@", str_uminus, 0);
- rb_define_method(rb_cString, "dup", rb_str_dup_m, 0);
rb_define_alias(rb_cString, "dedup", "-@");
rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);
diff --git a/string.rb b/string.rb
index 137cbe7a88..b410e09395 100644
--- a/string.rb
+++ b/string.rb
@@ -76,7 +76,7 @@
# - <tt>\n</tt> (_n_ a non-negative integer) refers to <tt>$n</tt>.
# - <tt>\k<name></tt> refers to the named capture +name+.
#
-# See Regexp for details.
+# See rdoc-ref:regexp.rdoc for details.
#
# Note that within the string +replacement+, a character combination
# such as <tt>$&</tt> is treated as ordinary text, and not as
@@ -90,10 +90,10 @@
# which contains string after match.
# - <tt>\`</tt> corresponds to <tt>$`</tt>,
# which contains string before match.
-# - <tt>\\+</tt> corresponds to <tt>$+</tt>,
+# - <tt>\+</tt> corresponds to <tt>$+</tt>,
# which contains last capture group.
#
-# See Regexp for details.
+# See rdoc-ref:regexp.rdoc for details.
#
# Note that <tt>\\\\</tt> is interpreted as an escape, i.e., a single backslash.
#
@@ -265,7 +265,7 @@
#
# <b><tt>string[regexp, capture = 0]</tt></b>
#
-# When the Regexp argument +regexp+ is given,
+# When the \Regexp argument +regexp+ is given,
# and the +capture+ argument is <tt>0</tt>,
# the slice is the first matching substring found in +self+:
#
@@ -278,7 +278,7 @@
# If argument +capture+ is given and not <tt>0</tt>,
# it should be either an capture group index (integer)
# or a capture group name (string or symbol);
-# the slice is the specified capture (see Regexp@Groups+and+Captures):
+# the slice is the specified capture (see Regexp@Capturing):
#
# s = 'hello there'
# s[/[aeiou](.)\1/, 1] # => "l"
diff --git a/struct.c b/struct.c
index c54dc12a04..8b7fea7f95 100644
--- a/struct.c
+++ b/struct.c
@@ -18,6 +18,7 @@
#include "internal/proc.h"
#include "internal/struct.h"
#include "internal/symbol.h"
+#include "transient_heap.h"
#include "vm_core.h"
#include "builtin.h"
@@ -412,15 +413,18 @@ struct_make_members_list(va_list ar)
{
char *mem;
VALUE ary, list = rb_ident_hash_new();
+ st_table *tbl = RHASH_TBL_RAW(list);
+
RBASIC_CLEAR_CLASS(list);
+ OBJ_WB_UNPROTECT(list);
while ((mem = va_arg(ar, char*)) != 0) {
VALUE sym = rb_sym_intern_ascii_cstr(mem);
- if (RTEST(rb_hash_has_key(list, sym))) {
+ if (st_insert(tbl, sym, Qtrue)) {
rb_raise(rb_eArgError, "duplicate member: %s", mem);
}
- rb_hash_aset(list, sym, Qtrue);
}
ary = rb_hash_keys(list);
+ st_clear(tbl);
RBASIC_CLEAR_CLASS(ary);
OBJ_FREEZE_RAW(ary);
return ary;
@@ -516,8 +520,8 @@ rb_struct_define_under(VALUE outer, const char *name, ...)
/*
* call-seq:
- * Struct.new(*member_names, keyword_init: nil){|Struct_subclass| ... } -> Struct_subclass
- * Struct.new(class_name, *member_names, keyword_init: nil){|Struct_subclass| ... } -> Struct_subclass
+ * Struct.new(*member_names, keyword_init: false){|Struct_subclass| ... } -> Struct_subclass
+ * Struct.new(class_name, *member_names, keyword_init: false){|Struct_subclass| ... } -> Struct_subclass
* Struct_subclass.new(*member_names) -> Struct_subclass_instance
* Struct_subclass.new(**member_names) -> Struct_subclass_instance
*
@@ -566,7 +570,7 @@ rb_struct_define_under(VALUE outer, const char *name, ...)
*
* <b>Member Names</b>
*
- * Symbol arguments +member_names+
+ * \Symbol arguments +member_names+
* determines the members of the new subclass:
*
* Struct.new(:foo, :bar).members # => [:foo, :bar]
@@ -600,6 +604,8 @@ rb_struct_define_under(VALUE outer, const char *name, ...)
* Foo.new(foo: 0, bar: 1, baz: 2)
* # Raises ArgumentError: unknown keywords: baz
*
+ * \Method <tt>::[]</tt> is an alias for method <tt>::new</tt>.
+ *
* - \Method <tt>:inspect</tt> returns a string representation of the subclass:
*
* Foo.inspect
@@ -641,14 +647,18 @@ rb_struct_define_under(VALUE outer, const char *name, ...)
static VALUE
rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
{
- VALUE name = Qnil, rest, keyword_init = Qnil;
+ VALUE name, rest, keyword_init = Qnil;
long i;
VALUE st;
+ st_table *tbl;
VALUE opt;
- argc = rb_scan_args(argc, argv, "0*:", NULL, &opt);
- if (argc >= 1 && !SYMBOL_P(argv[0])) {
- name = argv[0];
+ argc = rb_scan_args(argc, argv, "1*:", NULL, NULL, &opt);
+ name = argv[0];
+ if (SYMBOL_P(name)) {
+ name = Qnil;
+ }
+ else {
--argc;
++argv;
}
@@ -670,17 +680,19 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
rest = rb_ident_hash_new();
RBASIC_CLEAR_CLASS(rest);
+ OBJ_WB_UNPROTECT(rest);
+ tbl = RHASH_TBL_RAW(rest);
for (i=0; i<argc; i++) {
VALUE mem = rb_to_symbol(argv[i]);
if (rb_is_attrset_sym(mem)) {
rb_raise(rb_eArgError, "invalid struct member: %"PRIsVALUE, mem);
}
- if (RTEST(rb_hash_has_key(rest, mem))) {
+ if (st_insert(tbl, mem, Qtrue)) {
rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem);
}
- rb_hash_aset(rest, mem, Qtrue);
}
rest = rb_hash_keys(rest);
+ st_clear(tbl);
RBASIC_CLEAR_CLASS(rest);
OBJ_FREEZE_RAW(rest);
if (NIL_P(name)) {
@@ -802,34 +814,60 @@ rb_struct_initialize(VALUE self, VALUE values)
static VALUE *
struct_heap_alloc(VALUE st, size_t len)
{
- return ALLOC_N(VALUE, len);
+ VALUE *ptr = rb_transient_heap_alloc((VALUE)st, sizeof(VALUE) * len);
+
+ if (ptr) {
+ RSTRUCT_TRANSIENT_SET(st);
+ return ptr;
+ }
+ else {
+ RSTRUCT_TRANSIENT_UNSET(st);
+ return ALLOC_N(VALUE, len);
+ }
+}
+
+#if USE_TRANSIENT_HEAP
+void
+rb_struct_transient_heap_evacuate(VALUE obj, int promote)
+{
+ if (RSTRUCT_TRANSIENT_P(obj)) {
+ const VALUE *old_ptr = rb_struct_const_heap_ptr(obj);
+ VALUE *new_ptr;
+ long len = RSTRUCT_LEN(obj);
+
+ if (promote) {
+ new_ptr = ALLOC_N(VALUE, len);
+ FL_UNSET_RAW(obj, RSTRUCT_TRANSIENT_FLAG);
+ }
+ else {
+ new_ptr = struct_heap_alloc(obj, len);
+ }
+ MEMCPY(new_ptr, old_ptr, VALUE, len);
+ RSTRUCT(obj)->as.heap.ptr = new_ptr;
+ }
}
+#endif
static VALUE
struct_alloc(VALUE klass)
{
- long n = num_members(klass);
- size_t embedded_size = offsetof(struct RStruct, as.ary) + (sizeof(VALUE) * n);
- VALUE flags = T_STRUCT | (RGENGC_WB_PROTECTED_STRUCT ? FL_WB_PROTECTED : 0);
-
- if (n > 0 && rb_gc_size_allocatable_p(embedded_size)) {
- flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
+ long n;
+ NEWOBJ_OF(st, struct RStruct, klass, T_STRUCT | (RGENGC_WB_PROTECTED_STRUCT ? FL_WB_PROTECTED : 0));
- NEWOBJ_OF(st, struct RStruct, klass, flags, embedded_size, 0);
+ n = num_members(klass);
+ if (0 < n && n <= RSTRUCT_EMBED_LEN_MAX) {
+ RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
+ RBASIC(st)->flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
rb_mem_clear((VALUE *)st->as.ary, n);
-
- return (VALUE)st;
}
else {
- NEWOBJ_OF(st, struct RStruct, klass, flags, sizeof(struct RStruct), 0);
-
st->as.heap.ptr = struct_heap_alloc((VALUE)st, n);
rb_mem_clear((VALUE *)st->as.heap.ptr, n);
st->as.heap.len = n;
-
- return (VALUE)st;
}
+
+ return (VALUE)st;
}
VALUE
@@ -1002,6 +1040,8 @@ inspect_struct(VALUE s, VALUE prefix, int recur)
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
* joe.inspect # => "#<struct Customer name=\"Joe Smith\", address=\"123 Maple, Anytown NC\", zip=12345>"
*
+ * Struct#to_s is an alias for Struct#inspect.
+ *
*/
static VALUE
@@ -1020,6 +1060,8 @@ rb_struct_inspect(VALUE s)
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
* joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]
*
+ * Struct#values and Struct#deconstruct are aliases for Struct#to_a.
+ *
* Related: #members.
*/
@@ -1341,6 +1383,8 @@ rb_struct_values_at(int argc, VALUE *argv, VALUE s)
* a # => [12345]
*
* With no block given, returns an Enumerator.
+ *
+ * Struct#filter is an alias for Struct#select.
*/
static VALUE
@@ -1499,6 +1543,7 @@ rb_struct_eql(VALUE s, VALUE s2)
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
* joe.size #=> 3
*
+ * Struct#length is an alias for Struct#size.
*/
VALUE
@@ -1580,7 +1625,7 @@ rb_struct_dig(int argc, VALUE *argv, VALUE self)
* distance.unit #=> "km"
*
* Constructed object also has a reasonable definitions of #==
- * operator, #to_h hash conversion, and #deconstruct / #deconstruct_keys
+ * operator, #to_h hash conversion, and #deconstruct/#deconstruct_keys
* to be used in pattern matching.
*
* ::define method accepts an optional block and evaluates it in
@@ -1670,20 +1715,23 @@ rb_data_s_def(int argc, VALUE *argv, VALUE klass)
VALUE rest;
long i;
VALUE data_class;
+ st_table *tbl;
rest = rb_ident_hash_new();
RBASIC_CLEAR_CLASS(rest);
+ OBJ_WB_UNPROTECT(rest);
+ tbl = RHASH_TBL_RAW(rest);
for (i=0; i<argc; i++) {
VALUE mem = rb_to_symbol(argv[i]);
if (rb_is_attrset_sym(mem)) {
rb_raise(rb_eArgError, "invalid data member: %"PRIsVALUE, mem);
}
- if (RTEST(rb_hash_has_key(rest, mem))) {
+ if (st_insert(tbl, mem, Qtrue)) {
rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem);
}
- rb_hash_aset(rest, mem, Qtrue);
}
rest = rb_hash_keys(rest);
+ st_clear(tbl);
RBASIC_CLEAR_CLASS(rest);
OBJ_FREEZE_RAW(rest);
data_class = anonymous_struct(klass);
@@ -1695,20 +1743,6 @@ rb_data_s_def(int argc, VALUE *argv, VALUE klass)
return data_class;
}
-VALUE
-rb_data_define(VALUE super, ...)
-{
- va_list ar;
- VALUE ary;
- va_start(ar, super);
- ary = struct_make_members_list(ar);
- va_end(ar);
- if (!super) super = rb_cData;
- VALUE klass = setup_data(anonymous_struct(super), ary);
- rb_vm_add_root_module(klass);
- return klass;
-}
-
/*
* call-seq:
* DataClass::members -> array_of_symbols
@@ -1740,7 +1774,7 @@ rb_data_define(VALUE super, ...)
* Measure.new(amount: 1, unit: 'km')
* #=> #<data Measure amount=1, unit="km">
*
- * # Alternative shorter initialization with []
+ * # Alternative shorter intialization with []
* Measure[1, 'km']
* #=> #<data Measure amount=1, unit="km">
* Measure[amount: 1, unit: 'km']
@@ -1800,12 +1834,10 @@ rb_data_initialize_m(int argc, const VALUE *argv, VALUE self)
arg.self = self;
arg.unknown_keywords = Qnil;
rb_hash_foreach(argv[0], struct_hash_set_i, (VALUE)&arg);
- // Freeze early before potentially raising, so that we don't leave an
- // unfrozen copy on the heap, which could get exposed via ObjectSpace.
- OBJ_FREEZE_RAW(self);
if (arg.unknown_keywords != Qnil) {
rb_exc_raise(rb_keyword_error_new("unknown", arg.unknown_keywords));
}
+ OBJ_FREEZE_RAW(self);
return Qnil;
}
@@ -1857,9 +1889,22 @@ rb_data_with(int argc, const VALUE *argv, VALUE self)
return self;
}
- VALUE h = rb_struct_to_h(self);
- rb_hash_update_by(h, kwargs, 0);
- return rb_class_new_instance_kw(1, &h, rb_obj_class(self), TRUE);
+ VALUE copy = rb_obj_alloc(rb_obj_class(self));
+ rb_struct_init_copy(copy, self);
+
+ struct struct_hash_set_arg arg;
+ arg.self = copy;
+ arg.unknown_keywords = Qnil;
+ rb_hash_foreach(kwargs, struct_hash_set_i, (VALUE)&arg);
+ // Freeze early before potentially raising, so that we don't leave an
+ // unfrozen copy on the heap, which could get exposed via ObjectSpace.
+ RB_OBJ_FREEZE_RAW(copy);
+
+ if (arg.unknown_keywords != Qnil) {
+ rb_exc_raise(rb_keyword_error_new("unknown", arg.unknown_keywords));
+ }
+
+ return copy;
}
/*
diff --git a/symbol.c b/symbol.c
index bdbfbae831..429064e43d 100644
--- a/symbol.c
+++ b/symbol.c
@@ -9,6 +9,7 @@
**********************************************************************/
+#include "gc.h"
#include "internal.h"
#include "internal/error.h"
#include "internal/gc.h"
@@ -22,6 +23,7 @@
#include "symbol.h"
#include "vm_sync.h"
#include "builtin.h"
+#include "ruby/internal/attr/nonstring.h"
#if defined(USE_SYMBOL_GC) && !(USE_SYMBOL_GC+0)
# undef USE_SYMBOL_GC
@@ -30,11 +32,7 @@
# undef USE_SYMBOL_GC
# define USE_SYMBOL_GC 1
#endif
-#if defined(SYMBOL_DEBUG) && (SYMBOL_DEBUG+0)
-# undef SYMBOL_DEBUG
-# define SYMBOL_DEBUG 1
-#else
-# undef SYMBOL_DEBUG
+#ifndef SYMBOL_DEBUG
# define SYMBOL_DEBUG 0
#endif
#ifndef CHECK_ID_SERIAL
@@ -155,7 +153,7 @@ rb_id_attrset(ID id)
/* make new symbol and ID */
if (!(str = lookup_id_str(id))) {
- static const char id_types[][8] = {
+ RBIMPL_ATTR_NONSTRING() static const char id_types[][8] = {
"local",
"instance",
"invalid",
@@ -460,7 +458,8 @@ get_id_serial_entry(rb_id_serial_t num, ID id, const enum id_entry_type t)
if (NIL_P(result)) {
result = 0;
}
- else if (CHECK_ID_SERIAL) {
+ else {
+#if CHECK_ID_SERIAL
if (id) {
VALUE sym = result;
if (t != ID_ENTRY_SYM)
@@ -472,6 +471,7 @@ get_id_serial_entry(rb_id_serial_t num, ID id, const enum id_entry_type t)
if (RSYMBOL(sym)->id != id) result = 0;
}
}
+#endif
}
}
}
@@ -506,6 +506,7 @@ rb_id_serial_to_id(rb_id_serial_t num)
}
}
+#if SYMBOL_DEBUG
static int
register_sym_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
{
@@ -516,29 +517,19 @@ register_sym_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, in
*value = arg;
return ST_CONTINUE;
}
+#endif
static void
register_sym(rb_symbols_t *symbols, VALUE str, VALUE sym)
{
ASSERT_vm_locking();
- if (SYMBOL_DEBUG) {
- st_update(symbols->str_sym, (st_data_t)str,
- register_sym_update_callback, (st_data_t)sym);
- }
- else {
- st_add_direct(symbols->str_sym, (st_data_t)str, (st_data_t)sym);
- }
-}
-
-void
-rb_free_static_symid_str(void)
-{
- GLOBAL_SYMBOLS_ENTER(symbols)
- {
- st_free_table(symbols->str_sym);
- }
- GLOBAL_SYMBOLS_LEAVE();
+#if SYMBOL_DEBUG
+ st_update(symbols->str_sym, (st_data_t)str,
+ register_sym_update_callback, (st_data_t)sym);
+#else
+ st_add_direct(symbols->str_sym, (st_data_t)str, (st_data_t)sym);
+#endif
}
static void
diff --git a/symbol.h b/symbol.h
index 3649f125bf..ffbf7ce198 100644
--- a/symbol.h
+++ b/symbol.h
@@ -100,7 +100,7 @@ sym_type(VALUE sym)
#define is_class_sym(sym) (sym_type(sym)==ID_CLASS)
#define is_junk_sym(sym) (sym_type(sym)==ID_JUNK)
-RUBY_FUNC_EXPORTED const uint_least32_t ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
+RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
static inline int
is_global_name_punct(const int c)
@@ -109,9 +109,10 @@ is_global_name_punct(const int c)
return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
}
+int rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset);
+
RUBY_SYMBOL_EXPORT_BEGIN
-int rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset);
size_t rb_sym_immortal_count(void);
RUBY_SYMBOL_EXPORT_END
diff --git a/symbol.rb b/symbol.rb
index f31bf0bee3..0b23ebb267 100644
--- a/symbol.rb
+++ b/symbol.rb
@@ -4,6 +4,8 @@ class Symbol
#
# Returns +self+.
#
+ # Symbol#intern is an alias for Symbol#to_sym.
+ #
# Related: String#to_sym.
def to_sym
self
diff --git a/template/Doxyfile.tmpl b/template/Doxyfile.tmpl
index c801e0e79b..502e171384 100644
--- a/template/Doxyfile.tmpl
+++ b/template/Doxyfile.tmpl
@@ -1,4 +1,4 @@
-# Doxyfile 1.9.7
+# Doxyfile 1.9.3
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -12,16 +12,6 @@
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
-#
-# Note:
-#
-# Use doxygen to compare the used configuration file with the template
-# configuration file:
-# doxygen -x [configFile]
-# Use doxygen to compare the used configuration file with the template
-# configuration file without replacing the environment variables or CMake type
-# replacement variables:
-# doxygen -x_noenv [configFile]
<%
srcdir = miniruby = nil
@@ -87,28 +77,16 @@ PROJECT_LOGO =
OUTPUT_DIRECTORY = doc/capi
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
-# sub-directories (in 2 levels) under the output directory of each output format
-# and will distribute the generated files over these directories. Enabling this
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to
-# control the number of sub-directories.
+# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = YES
-# Controls the number of sub-directories that will be created when
-# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every
-# level increment doubles the number of directories, resulting in 4096
-# directories at level 8 which is the default and also the maximum value. The
-# sub-directories are organized in 2 levels, the first level always has a fixed
-# number of 16 directories.
-# Minimum value: 0, maximum value: 8, default value: 8.
-# This tag requires that the tag CREATE_SUBDIRS is set to YES.
-
-CREATE_SUBDIRS_LEVEL = 8
-
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
@@ -120,14 +98,14 @@ ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian,
-# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English
-# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek,
-# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with
-# English messages), Korean, Korean-en (Korean with English messages), Latvian,
-# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese,
-# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish,
-# Swedish, Turkish, Ukrainian and Vietnamese.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
# The default value is: English.
OUTPUT_LANGUAGE = English
@@ -376,17 +354,6 @@ MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
-# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to
-# generate identifiers for the Markdown headings. Note: Every identifier is
-# unique.
-# Possible values are: DOXYGEN Use a fixed 'autotoc_md' string followed by a
-# sequence number starting at 0. and GITHUB Use the lower case version of title
-# with any whitespace replaced by '-' and punctations characters removed..
-# The default value is: DOXYGEN.
-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
-
-MARKDOWN_ID_STYLE = GITHUB
-
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
@@ -498,7 +465,7 @@ TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
-# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use
+# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
# during processing. When set to 0 doxygen will based this on the number of
# cores available in the system. You can set it explicitly to a value larger
# than 0 to get more control over the balance between CPU load and processing
@@ -511,14 +478,6 @@ LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
-# If the TIMESTAMP tag is set different from NO then each generated page will
-# contain the date or date and time when the page was generated. Setting this to
-# NO can help when comparing the output of multiple runs.
-# Possible values are: YES, NO, DATETIME and DATE.
-# The default value is: NO.
-
-TIMESTAMP = NO
-
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -600,8 +559,7 @@ HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set
# to NO, these classes will be included in the various overviews. This option
-# will also hide undocumented C++ concepts if enabled. This option has no effect
-# if EXTRACT_ALL is enabled.
+# has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_CLASSES = NO
@@ -632,15 +590,14 @@ INTERNAL_DOCS = NO
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
-# are not case sensitive the option should be set to NO to properly deal with
+# are not case sensitive the option should be be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
# Windows (including Cygwin) and MacOS, users should typically set this option
# to NO, whereas on Linux or other Unix flavors it should typically be set to
# YES.
-# Possible values are: SYSTEM, NO and YES.
-# The default value is: SYSTEM.
+# The default value is: system dependent.
CASE_SENSE_NAMES = NO
@@ -892,26 +849,11 @@ WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO
-# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about
-# undocumented enumeration values. If set to NO, doxygen will accept
-# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: NO.
-
-WARN_IF_UNDOC_ENUM_VAL = NO
-
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
# at the end of the doxygen process doxygen will return with a non-zero status.
-# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves
-# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not
-# write the warning messages in between other messages but write them at the end
-# of a run, in case a WARN_LOGFILE is defined the warning messages will be
-# besides being in the defined file also be shown at the end of a run, unless
-# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case
-# the behavior will remain as with the setting FAIL_ON_WARNINGS.
-# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT.
+# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
WARN_AS_ERROR = NO
@@ -922,27 +864,13 @@ WARN_AS_ERROR = NO
# and the warning text. Optionally the format may contain $version, which will
# be replaced by the version of the file (if it could be obtained via
# FILE_VERSION_FILTER)
-# See also: WARN_LINE_FORMAT
# The default value is: $file:$line: $text.
WARN_FORMAT = "$file:$line: $text"
-# In the $text part of the WARN_FORMAT command it is possible that a reference
-# to a more specific place is given. To make it easier to jump to this place
-# (outside of doxygen) the user can define a custom "cut" / "paste" string.
-# Example:
-# WARN_LINE_FORMAT = "'vi $file +$line'"
-# See also: WARN_FORMAT
-# The default value is: at line $line of file $file.
-
-WARN_LINE_FORMAT = "at line $line of file $file"
-
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
-# error (stderr). In case the file specified cannot be opened for writing the
-# warning and error messages are written to standard error. When as file - is
-# specified the warning and error messages are written to standard output
-# (stdout).
+# error (stderr).
WARN_LOGFILE =
@@ -965,21 +893,10 @@ INPUT += .
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see:
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
-# See also: INPUT_FILE_ENCODING
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify
-# character encoding on a per file pattern basis. Doxygen will compare the file
-# name with each pattern and apply the encoding instead of the default
-# INPUT_ENCODING) if there is a match. The character encodings are a list of the
-# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding
-# "INPUT_ENCODING" for further information on supported encodings.
-
-INPUT_FILE_ENCODING =
-
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories.
@@ -1050,7 +967,7 @@ EXCLUDE_PATTERNS += encdb.h
EXCLUDE_PATTERNS += extconf.h
EXCLUDE_PATTERNS += insns.def
EXCLUDE_PATTERNS += lib
-EXCLUDE_PATTERNS += rb_rjit_header.h
+EXCLUDE_PATTERNS += rb_mjit_header.h
EXCLUDE_PATTERNS += spec
EXCLUDE_PATTERNS += test
EXCLUDE_PATTERNS += tmp
@@ -1061,7 +978,10 @@ EXCLUDE_PATTERNS += yarvtest
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# ANamespace::AClass, ANamespace::*Test
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS =
@@ -1106,11 +1026,6 @@ IMAGE_PATH = <%=srcdir%>/doc/images
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
-# Note that doxygen will use the data processed and written to standard output
-# for further processing, therefore nothing else, like debug statements or used
-# commands (so in case of a Windows batch file always use @echo OFF), should be
-# written to standard output.
-#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
@@ -1152,15 +1067,6 @@ FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
-# The Fortran standard specifies that for fixed formatted Fortran code all
-# characters from position 72 are to be considered as comment. A common
-# extension is to allow longer lines before the automatic comment starts. The
-# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can
-# be processed before the automatic comment starts.
-# Minimum value: 7, maximum value: 10000, default value: 72.
-
-FORTRAN_COMMENT_AFTER = 72
-
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
@@ -1258,11 +1164,10 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
-# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes)
-# that should be ignored while generating the index headers. The IGNORE_PREFIX
-# tag works for classes, function and member names. The entity will be placed in
-# the alphabetical list under the first letter of the entity name that remains
-# after removing the prefix.
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
@@ -1341,12 +1246,7 @@ HTML_STYLESHEET =
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# Note: Since the styling of scrollbars can currently not be overruled in
-# Webkit/Chromium, the styling will be left out of the default doxygen.css if
-# one or more extra stylesheets have been specified. So if scrollbar
-# customization is desired it has to be added explicitly. For an example see the
-# documentation.
+# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
@@ -1361,19 +1261,6 @@ HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
-# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
-# should be rendered with a dark or light theme.
-# Possible values are: LIGHT always generate light mode output, DARK always
-# generate dark mode output, AUTO_LIGHT automatically set the mode according to
-# the user preference, use light mode if no preference is set (the default),
-# AUTO_DARK automatically set the mode according to the user preference, use
-# dark mode if no preference is set and TOGGLE allow to user to switch between
-# light and dark mode via a button.
-# The default value is: AUTO_LIGHT.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE = AUTO_LIGHT
-
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a color-wheel, see
@@ -1404,6 +1291,15 @@ HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will
@@ -1553,16 +1449,6 @@ BINARY_TOC = NO
TOC_EXPAND = NO
-# The SITEMAP_URL tag is used to specify the full URL of the place where the
-# generated documentation will be placed on the server by the user during the
-# deployment of the documentation. The generated sitemap is called sitemap.xml
-# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL
-# is specified no sitemap is generated. For information about the sitemap
-# protocol see https://www.sitemaps.org
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SITEMAP_URL =
-
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
@@ -1680,7 +1566,7 @@ GENERATE_TREEVIEW = NO
# area (value NO) or if it should extend to the full height of the window (value
# YES). Setting this to YES gives a layout similar to
# https://docs.readthedocs.io with more room for contents, but less room for the
-# project logo, title, and description. If either GENERATE_TREEVIEW or
+# project logo, title, and description. If either GENERATOR_TREEVIEW or
# DISABLE_INDEX is set to NO, this option has no effect.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1711,13 +1597,6 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
-# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
-# addresses.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-OBFUSCATE_EMAILS = YES
-
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
@@ -1738,6 +1617,17 @@ HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
@@ -2051,16 +1941,9 @@ PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
-# The LATEX_BATCHMODE tag ignals the behavior of LaTeX in case of an error.
-# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch
-# mode nothing is printed on the terminal, errors are scrolled as if <return> is
-# hit at every error; missing files that TeX tries to input or request from
-# keyboard input (\read on a not open input stream) cause the job to abort,
-# NON_STOP In nonstop mode the diagnostic message will appear on the terminal,
-# but there is no possibility of user interaction just like in batch mode,
-# SCROLL In scroll mode, TeX will stop only for missing files to input or if
-# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at
-# each error, asking for user intervention.
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -2081,6 +1964,14 @@ LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
@@ -2246,7 +2137,7 @@ DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
# the structure of the code including all documentation. Note that this feature
# is still experimental and incomplete at the moment.
# The default value is: NO.
@@ -2327,8 +2218,7 @@ SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by the
-# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
-# RECURSIVE has no effect here.
+# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
@@ -2359,10 +2249,10 @@ PREDEFINED += DEPRECATED(_)=_
PREDEFINED += DEPRECATED_BY(__,_)=_
PREDEFINED += ENUM_OVER_INT=1
PREDEFINED += ERRORFUNC(__,_)=_
-PREDEFINED += RJIT_FUNC_EXPORTED=
-PREDEFINED += RJIT_STATIC=extern
-PREDEFINED += RJIT_SYMBOL_EXPORT_BEGIN=
-PREDEFINED += RJIT_SYMBOL_EXPORT_END=
+PREDEFINED += MJIT_FUNC_EXPORTED=
+PREDEFINED += MJIT_STATIC=extern
+PREDEFINED += MJIT_SYMBOL_EXPORT_BEGIN=
+PREDEFINED += MJIT_SYMBOL_EXPORT_END=
PREDEFINED += NOINLINE(_)=_
PREDEFINED += NORETURN(_)=_
PREDEFINED += PACKED_STRUCT_UNALIGNED(_)=_
@@ -2462,9 +2352,16 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
-# Configuration options related to diagram generator tools
+# Configuration options related to the dot tool
#---------------------------------------------------------------------------
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
# If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
@@ -2473,7 +2370,7 @@ HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
-# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: NO.
@@ -2490,51 +2387,37 @@ HAVE_DOT = <%= have_dot %>
DOT_NUM_THREADS = 0
-# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of
-# subgraphs. When you want a differently looking font in the dot files that
-# doxygen generates you can specify fontname, fontcolor and fontsize attributes.
-# For details please see <a href=https://graphviz.org/doc/info/attrs.html>Node,
-# Edge and Graph Attributes specification</a> You need to make sure dot is able
-# to find the font, which can be done by putting it in a standard location or by
-# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
-# directory containing the font. Default graphviz fontsize is 14.
-# The default value is: fontname=Helvetica,fontsize=10.
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
-DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
+DOT_FONTNAME = FreeSans
-# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can
-# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. <a
-# href=https://graphviz.org/doc/info/arrows.html>Complete documentation about
-# arrows shapes.</a>
-# The default value is: labelfontname=Helvetica,labelfontsize=10.
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
-DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
+DOT_FONTSIZE = 10
-# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
-# around nodes set 'shape=plain' or 'shape=plaintext' <a
-# href=https://www.graphviz.org/doc/info/shapes.html>Shapes specification</a>
-# The default value is: shape=box,height=0.2,width=0.4.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
-
-# You can set the path where dot can find font specified with fontname in
-# DOT_COMMON_ATTR and others dot attributes.
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTPATH =
-# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will
-# generate a graph for each documented class showing the direct and indirect
-# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and
-# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case
-# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the
-# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used.
-# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance
-# relations will be shown as texts / links.
-# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN.
+# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
+# graph for each documented class showing the direct and indirect inheritance
+# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
+# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
+# to TEXT the direct and indirect inheritance relations will be shown as texts /
+# links.
+# Possible values are: NO, YES, TEXT and GRAPH.
# The default value is: YES.
CLASS_GRAPH = NO
@@ -2549,8 +2432,7 @@ CLASS_GRAPH = NO
COLLABORATION_GRAPH = NO
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies. See also the chapter Grouping
-# in the manual.
+# groups, showing the direct groups dependencies.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2675,7 +2557,7 @@ DIR_GRAPH_MAX_DEPTH = 1
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
-# https://www.graphviz.org/)).
+# http://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
@@ -2712,12 +2594,11 @@ DOT_PATH =
DOTFILE_DIRS =
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
-DIA_PATH =
+MSCFILE_DIRS =
# The DIAFILE_DIRS tag can be used to specify one or more directories that
# contain dia files that are included in the documentation (see the \diafile
@@ -2726,10 +2607,10 @@ DIA_PATH =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file or to the filename of jar file
-# to be used. If left blank, it is assumed PlantUML is not used or called during
-# a preprocessing step. Doxygen will generate a warning when it encounters a
-# \startuml command in this case and will not generate output for the diagram.
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
PLANTUML_JAR_PATH =
@@ -2767,6 +2648,18 @@ DOT_GRAPH_MAX_NODES = 128
MAX_DOT_GRAPH_DEPTH = 0
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
@@ -2779,8 +2672,6 @@ DOT_MULTI_TARGETS = NO
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
-# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
-# graphical representation for inheritance and collaboration diagrams is used.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2794,19 +2685,3 @@ GENERATE_LEGEND = YES
# The default value is: YES.
DOT_CLEANUP = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will
-# use a built-in version of mscgen tool to produce the charts. Alternatively,
-# the MSCGEN_TOOL tag can also specify the name an external tool. For instance,
-# specifying prog as the value, doxygen will call the tool as prog -T
-# <outfile_format> -o <outputfile> <inputfile>. The external tool should support
-# output file formats "png", "eps", "svg", and "ismap".
-
-MSCGEN_TOOL =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS =
diff --git a/template/GNUmakefile.in b/template/GNUmakefile.in
index ce7d931e0a..4db4467905 100644
--- a/template/GNUmakefile.in
+++ b/template/GNUmakefile.in
@@ -1,9 +1,5 @@
gnumake = yes
-ifneq ($(filter notintermediate,$(.FEATURES)),)
-DOT_WAIT = .WAIT
-endif
-
ifeq ($(filter Makefile,$(MAKEFILE_LIST)),)
include Makefile
@@ -18,6 +14,10 @@ endif
override order_only := |
+ifneq ($(filter notintermediate,$(.FEATURES)),)
+DOT_WAIT = .WAIT
+endif
+
# Needs the dependency when any Unicode tables data files exist.
override UNICODE_TABLES_DEPENDENTS = \
$(if $(or \
@@ -27,6 +27,7 @@ override UNICODE_TABLES_DEPENDENTS = \
$(UNICODE_TABLES_DATA_FILES)))),\
force,none)
+include $(srcdir)/defs/universal.mk
-include uncommon.mk
include $(srcdir)/defs/gmake.mk
diff --git a/template/Makefile.in b/template/Makefile.in
index 8c462f20fb..e189d88c3f 100644
--- a/template/Makefile.in
+++ b/template/Makefile.in
@@ -29,7 +29,7 @@ CPP = @CPP@
LD = @LD@
RUSTC = @RUSTC@
CARGO = @CARGO@
-YACC = $(BASERUBY) $(tooldir)/lrama/exe/lrama
+YACC = bison
PURIFY =
AUTOCONF = autoconf
CONFIGURE = @CONFIGURE@
@@ -65,7 +65,6 @@ rubyarchhdrdir = @rubyarchhdrdir@
ruby_version = @ruby_version@
RUBY_VERSION_NAME = @RUBY_VERSION_NAME@
UNIVERSAL_ARCHNAMES = @UNIVERSAL_ARCHNAMES@
-BUILTIN_BINARY = @X_BUILTIN_BINARY@
TESTUI = console
TESTS =
@@ -97,11 +96,25 @@ XCFLAGS = @XCFLAGS@ $(INCFLAGS) $(_RUBY_DEVEL_enabled:yes=-DRUBY_DEVEL=1)
USE_RUBYGEMS = @USE_RUBYGEMS@
USE_RUBYGEMS_ = $(USE_RUBYGEMS:yes=)
CPPFLAGS = @CPPFLAGS@ $(USE_RUBYGEMS_:no=-DDISABLE_RUBYGEMS=1)
-RJIT_SUPPORT = @RJIT_SUPPORT@
+MJIT_SUPPORT = @MJIT_SUPPORT@
+MJIT_HEADER_FLAGS = @MJIT_HEADER_FLAGS@
+MJIT_HEADER_SUFFIX =
+MJIT_HEADER_ARCH =
+MJIT_HEADER_INSTALL_DIR = @MJIT_HEADER_INSTALL_DIR@
+MJIT_CC = @MJIT_CC@
+MJIT_CFLAGS = @MJIT_CFLAGS@
+MJIT_OPTFLAGS = @MJIT_OPTFLAGS@
+MJIT_DEBUGFLAGS = @MJIT_DEBUGFLAGS@
+MJIT_LDSHARED = @MJIT_LDSHARED@
+MJIT_DLDFLAGS = $(XDLDFLAGS)
+MJIT_HEADER = rb_mjit_header.h
+MJIT_MIN_HEADER_NAME = rb_mjit_min_header-$(RUBY_PROGRAM_VERSION).h
+MJIT_MIN_HEADER = $(MJIT_HEADER_BUILD_DIR)/$(MJIT_MIN_HEADER_NAME)
+MJIT_HEADER_BUILD_DIR = $(EXTOUT)/include/$(arch)
+MJIT_TABS=@MJIT_TABS@
YJIT_SUPPORT=@YJIT_SUPPORT@
YJIT_LIBS=@YJIT_LIBS@
YJIT_OBJ=@YJIT_OBJ@
-YJIT_LIBOBJ = $(YJIT_LIBS:.a=.@OBJEXT@)
CARGO_TARGET_DIR=@abs_top_builddir@/yjit/target
CARGO_BUILD_ARGS=@CARGO_BUILD_ARGS@
LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
@@ -118,7 +131,7 @@ XDLDFLAGS = @DLDFLAGS@
DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(XLDFLAGS) $(ARCH_FLAG)
SOLIBS = @SOLIBS@
ENABLE_DEBUG_ENV = @ENABLE_DEBUG_ENV@
-MAINLIBS = @MAINLIBS@
+MAINLIBS = $(YJIT_LIBS) @MAINLIBS@
ARCHMINIOBJS = @MINIOBJS@
DLNOBJ = @DLNOBJ@
ENCOBJS = @ENCOBJS@
@@ -173,6 +186,7 @@ MAJOR= @MAJOR@
MINOR= @MINOR@
TEENY= @TEENY@
+# here for MJIT_MIN_HEADER_NAME, not in common.mk
RUBY_PROGRAM_VERSION = $(MAJOR).$(MINOR).$(TEENY)
LIBRUBY_A = @LIBRUBY_A@
@@ -283,20 +297,16 @@ all:
# Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT:
-# On GNU make and BSD make, clean up the target when the recipe
-# fails. Prevents half-built targets corrupting future runs.
-.DELETE_ON_ERROR:
-
miniruby$(EXEEXT):
@-if test -f $@; then $(MV) -f $@ $@.old; $(RM) $@.old; fi
$(ECHO) linking $@
- $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(MAINLIBS) $(OUTFLAG)$@
+ $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(MAINLIBS) $(LIBS) $(OUTFLAG)$@
$(Q) $(POSTLINK)
$(PROGRAM):
@$(RM) $@
$(ECHO) linking $@
- $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(EXTLIBS) $(OUTFLAG)$@
+ $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@
$(Q) $(POSTLINK)
$(PROGRAM): @XRUBY_LIBPATHENV_WRAPPER@
@@ -313,11 +323,21 @@ $(LIBRUBY_A):
@-[ -z "$(EXTSTATIC)" ] || $(PRE_LIBRUBY_UPDATE)
$(ECHO) linking static-library $@
$(Q) $(AR) $(ARFLAGS) $@ $(LIBRUBY_A_OBJS) $(INITOBJS)
+ $(Q) if [ 'no' != '$(YJIT_SUPPORT)' ]; then \
+ set -eu$(V0:1=x) && \
+ $(ECHO0) 'merging $(YJIT_LIBS) into $@' && \
+ $(RMALL) libyjit/ && \
+ $(MAKEDIRS) libyjit/ && \
+ trap "$(RMALL) libyjit/" 0 && \
+ (cd libyjit/ && $(AR) -x ../$(YJIT_LIBS)) && \
+ : "$(AR) $(ARFLAGS) $@ libyjit/*.$(OBJEXT)" && \
+ find libyjit/ -name '*.$(OBJEXT)' -exec $(AR) $(ARFLAGS) $@ '{}' '+' ; \
+ fi
@-$(RANLIB) $@ 2> /dev/null || true
verify-static-library: $(LIBRUBY_A)
$(ECHO) verifying static-library $@
- @$(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(OUTFLAG)conftest$(EXEEXT)
+ @$(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)conftest$(EXEEXT)
@$(RMALL) conftest$(EXEEXT) conftest.c conftest.dSYM
$(LIBRUBY_SO):
@@ -368,7 +388,7 @@ install-cross: $(arch)-fake.rb $(RBCONFIG) rbconfig.rb $(arch_hdrdir)/ruby/confi
Makefile: $(srcdir)/template/Makefile.in $(srcdir)/enc/Makefile.in
-$(MKFILES): config.status $(srcdir)/version.h $(ABI_VERSION_HDR)
+$(MKFILES): config.status $(srcdir)/version.h $(REVISION_H) $(ABI_VERSION_HDR)
@[ -f $@ ] && mv $@ $@.old
MAKE=$(MAKE) $(SHELL) ./config.status $@
@cmp $@ $@.old > /dev/null 2>&1 && echo $@ unchanged && exit 0; \
@@ -479,6 +499,18 @@ probes.$(OBJEXT): $(srcdir)/probes.d $(DTRACE_REBUILD:yes=probes.stamp)
$(Q) $(RM) $@
$(Q) $(DTRACE) -G -C $(INCFLAGS) -s $(srcdir)/probes.d -o $@ $(DTRACE_REBUILD_OBJS)
+main: mjit-headers
+yes-mjit-headers: $(MJIT_MIN_HEADER)
+clean-local::
+ $(Q)$(RM) \
+ $(MJIT_HEADER) $(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h \
+ $(MJIT_MIN_HEADER) $(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h \
+ $(MJIT_HEADER_INSTALL_DIR)/rb_mjit_min_header-*.h \
+ $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time mjit_config.h \
+ || $(NULLCMD)
+ $(Q)$(RM) -r mjit_build_dir.*
+ -$(Q) $(RMDIRS) $(MJIT_HEADER_INSTALL_DIR) $(MJIT_HEADER_BUILD_DIR) $(TIMESTAMPDIR) 2> $(NULL) || $(NULLCMD)
+
# DTrace static library hacks described here:
# https://marc.info/?l=opensolaris-dtrace-discuss&m=114761203110734&w=4
ruby-glommed.$(OBJEXT):
@@ -574,12 +606,29 @@ update-benchmark-driver:
--branch $(BENCHMARK_DRIVER_GIT_REF) \
$(BENCHMARK_DRIVER_GIT_URL) benchmark-driver $(GIT_OPTS)
+update-doclie:
+ $(Q) $(tooldir)/git-refresh -C $(srcdir)/coverage $(Q1:0=-q) \
+ --branch $(DOCLIE_GIT_REF) \
+ $(DOCLIE_GIT_URL) doclie $(GIT_OPTS)
+
+update-simplecov-html:
+ $(Q) $(tooldir)/git-refresh -C $(srcdir)/coverage $(Q1:0=-q) \
+ --branch $(SIMPLECOV_HTML_GIT_REF) \
+ $(SIMPLECOV_HTML_GIT_URL) simplecov-html $(GIT_OPTS)
+
+update-simplecov:
+ $(Q) $(tooldir)/git-refresh -C $(srcdir)/coverage $(Q1:0=-q) \
+ --branch $(SIMPLECOV_GIT_REF) \
+ $(SIMPLECOV_GIT_URL) simplecov $(GIT_OPTS)
+
+update-coverage: update-simplecov update-simplecov-html update-doclie
+
update-known-errors:
errno --list | cut -d' ' -f1 | sort -u - $(srcdir)/defs/known_errors.def | \
$(IFCHANGE) $(srcdir)/defs/known_errors.def -
-INSNS = optinsn.inc optunifs.inc insns.inc insns_info.inc \
- vmtc.inc vm.inc
+INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
+ vmtc.inc vm.inc mjit_sp_inc.inc
$(INSNS): $(srcdir)/insns.def vm_opts.h \
$(srcdir)/defs/opt_operand.def $(srcdir)/defs/opt_insn_unif.def \
@@ -618,6 +667,8 @@ $(INSNS): $(srcdir)/insns.def vm_opts.h \
$(tooldir)/ruby_vm/views/_trace_instruction.erb \
$(tooldir)/ruby_vm/views/insns.inc.erb \
$(tooldir)/ruby_vm/views/insns_info.inc.erb \
+ $(tooldir)/ruby_vm/views/mjit_sp_inc.inc.erb \
+ $(tooldir)/ruby_vm/views/opt_sc.inc.erb \
$(tooldir)/ruby_vm/views/optinsn.inc.erb \
$(tooldir)/ruby_vm/views/optunifs.inc.erb \
$(tooldir)/ruby_vm/views/vm.inc.erb \
@@ -634,16 +685,44 @@ un-runnable:
$(ECHO) cannot make runnable, configure with --enable-load-relative.
$(Q) exit 1
-LIBRUBY_FOR_LEAKED_GLOBALS = $(enable_shared:no=)
-yes-test-basic: $(DOT_WAIT) test-leaked-globals
-leaked-globals: test-leaked-globals
-yes-test-leaked-globals-precheck: $(COMMONOBJS) prog $(tooldir)/leaked-globals
-test-leaked-globals: yes-test-leaked-globals
-yes-test-leaked-globals: yes-test-leaked-globals-precheck
- $(ACTIONS_GROUP)
- $(Q) $(XRUBY) $(tooldir)/leaked-globals \
- SOEXT=$(SOEXT) NM="$(NM) -Pgp" SYMBOL_PREFIX=$(SYMBOL_PREFIX) \
- SYMBOLS_IN_EMPTYLIB="@XSYMBOLS_IN_EMPTYLIB@" \
- PLATFORM=$(hdrdir)/ruby/$(PLATFORM_DIR).h $(srcdir)/configure.ac \
- $(COMMONOBJS) $(LIBRUBY_FOR_LEAKED_GLOBALS:yes=$(LIBRUBY_SO))
- $(ACTIONS_ENDGROUP)
+mjit_config.h:
+ $(ECHO) making $@
+ @{ \
+ . $(tooldir)/mjit_archflag.sh; \
+ parse_arch_flags "$(UNIVERSAL_ARCHNAMES)" $(ARCH_FLAG); \
+ test "$(Q)" = @ || set -x; \
+ echo '#ifndef RUBY_MJIT_CONFIG_H'; \
+ echo '#define RUBY_MJIT_CONFIG_H 1'; \
+ echo; \
+ sep=; \
+ echo '#ifdef LOAD_RELATIVE'; \
+ quote MJIT_HEADER_INSTALL_DIR "/$(MJIT_HEADER_INSTALL_DIR)"; \
+ echo '#else'; \
+ quote MJIT_HEADER_INSTALL_DIR "$(rubyarchhdrdir)"; \
+ echo '#endif'; \
+ quote MJIT_MIN_HEADER_NAME "$(MJIT_MIN_HEADER_NAME)"; \
+ sep=,; \
+ quote "MJIT_CC_COMMON " $(MJIT_CC); \
+ quote "MJIT_CFLAGS MJIT_ARCHFLAG" $(MJIT_CFLAGS); \
+ quote "MJIT_OPTFLAGS " $(MJIT_OPTFLAGS); \
+ quote "MJIT_DEBUGFLAGS " $(MJIT_DEBUGFLAGS); \
+ quote "MJIT_LDSHARED " $(MJIT_LDSHARED); \
+ quote "MJIT_DLDFLAGS MJIT_ARCHFLAG" $(MJIT_DLDFLAGS); \
+ quote "MJIT_LIBS " $(LIBRUBYARG_SHARED); \
+ quote 'PRELOADENV "@PRELOADENV@"'; \
+ indent=$${archs:+' '}; \
+ define_arch_flags; \
+ echo; \
+ echo '#endif /* RUBY_MJIT_CONFIG_H */'; \
+ } > $@
+
+yes-test-almost yes-test-all programs: mjit_build_dir.$(SOEXT)
+mjit_build_dir.$(SOEXT): $(MJIT_MIN_HEADER) $(srcdir)/ruby-runner.c ruby-runner.h
+ $(ECHO) making $@
+ $(Q) $(DLDSHARED) $(MJIT_DLDFLAGS) $(ARCH_FLAG) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) \
+ -DMAKE_MJIT_BUILD_DIR=1 -DMJIT_MIN_HEADER='"$(MJIT_MIN_HEADER)"' \
+ $(OUTFLAG)$@ $(srcdir)/ruby-runner.c
+
+# yes-test-basic: leaked-globals
+leaked-globals: $(COMMONOBJS) prog $(tooldir)/leaked-globals PHONY
+ $(Q) $(XRUBY) $(tooldir)/leaked-globals NM=$(NM) SYMBOL_PREFIX=$(SYMBOL_PREFIX) PLATFORM=$(hdrdir)/ruby/$(PLATFORM_DIR).h $(srcdir)/configure.ac $(COMMONOBJS)
diff --git a/template/builtin_binary.inc.tmpl b/template/builtin_binary.inc.tmpl
index 2c2f071705..787ced5f3d 100644
--- a/template/builtin_binary.inc.tmpl
+++ b/template/builtin_binary.inc.tmpl
@@ -10,19 +10,19 @@ static const unsigned char <%= feature %>_bin[] = {
% iseq \
% . to_binary \
% . each_byte \
+% . map(&:ord) \
+% . map{ '0x%02x' % _1 } \
% . each_slice(12) {|a|
- <%= a.map{ '0x%02x,' % _1 }.join(' ') %>
+ <%= a.join(', ') %>,
% }
};
% }
-#define BUILTIN_BIN(feature) \
- { #feature, feature ## _bin, sizeof(feature ## _bin), }
static const struct builtin_binary builtin_binary[] = {
% ary.each{|feature, |
- BUILTIN_BIN(<%= feature %>),
+ { <%= feature.dump %>, <%= feature %>_bin, sizeof(<%= feature %>_bin), },
% }
- { NULL, },/* sentinel */
+ { NULL, },<%# dummy entry %>
};
#define BUILTIN_BINARY_SIZE <%= ary.size %>
diff --git a/template/configure-ext.mk.tmpl b/template/configure-ext.mk.tmpl
index bc192a37ce..8ba6b963e3 100644
--- a/template/configure-ext.mk.tmpl
+++ b/template/configure-ext.mk.tmpl
@@ -23,7 +23,7 @@ exts = {}
end
%>
MINIRUBY = <%=miniruby%>
-SCRIPT_ARGS = <%=script_args.gsub("#", "\\#").gsub(/\A|[\s"']\K--jobserver-auth=[^\s'"]*/, "")%>
+SCRIPT_ARGS = <%=script_args.gsub("#", "\\#")%>
EXTMK_ARGS = $(SCRIPT_ARGS) --gnumake=$(gnumake) --extflags="$(EXTLDFLAGS)" \
--make-flags="MINIRUBY='$(MINIRUBY)'"
diff --git a/template/exts.mk.tmpl b/template/exts.mk.tmpl
index 29c29df37c..5595a08da1 100644
--- a/template/exts.mk.tmpl
+++ b/template/exts.mk.tmpl
@@ -27,7 +27,7 @@ contpat = /(?>(?>[^\\\n]|\\.)*\\\n)*(?>[^\\\n]|\\.)*/
Dir.glob("{ext,.bundle/gems}/*/exts.mk") do |e|
gem = e.start_with?(".bundle/gems/")
s = File.read(e)
- s.scan(/^(extensions|SUBMAKEOPTS|EXT[A-Z]+|MFLAGS|MESSAGE_(?:BEGIN|END)|NOTE_[A-Z]+)[ \t]*=[ \t]*(#{contpat})$/o) do |n, v|
+ s.scan(/^(extensions|SUBMAKEOPTS|EXT[A-Z]+|MFLAGS|NOTE_[A-Z]+)[ \t]*=[ \t]*(#{contpat})$/o) do |n, v|
v.gsub!(/\\\n[ \t]*/, ' ')
next if v.empty?
n = "old_extensions" if n == "extensions" and !confexts.include?(e)
diff --git a/template/fake.rb.in b/template/fake.rb.in
index 5e52d95594..7b74421d62 100644
--- a/template/fake.rb.in
+++ b/template/fake.rb.in
@@ -24,7 +24,7 @@ File.read(File.join(arg['srcdir'], 'version.c')).
scan(/rb_define_global_const\("(RUBY_\w+)",[^;]*?\bMK(?:INT|(STR))\(([^()]*)\)/m) do |n, s, v|
version[n] = arg[v] || src.value(v) || (s ? v : 0)
end
-arg['RUBY_DESCRIPTION_WITH_RJIT'] = src.value('description_with_rjit') || 'description_with_rjit'
+arg['RUBY_DESCRIPTION_WITH_MJIT'] = src.value('description_with_mjit') || 'description_with_mjit'
arg['RUBY_DESCRIPTION_WITH_YJIT'] = src.value('description_with_yjit') || 'description_with_yjit'
%>baseruby="<%=arg['BASERUBY']%>"
_\
@@ -42,8 +42,8 @@ class Object
constants.grep(/^RUBY_/) {|n| remove_const n}
% arg['versions'].each {|n, v|
<%=n%> = <%if n=='RUBY_DESCRIPTION' %>case
- when RubyVM.const_defined?(:RJIT) && RubyVM::RJIT.enabled?
- <%=arg['RUBY_DESCRIPTION_WITH_RJIT'].inspect%>
+ when RubyVM.const_defined?(:MJIT) && RubyVM::MJIT.enabled?
+ <%=arg['RUBY_DESCRIPTION_WITH_MJIT'].inspect%>
when RubyVM.const_defined?(:YJIT) && RubyVM::YJIT.enabled?
<%=arg['RUBY_DESCRIPTION_WITH_YJIT'].inspect%>
else
diff --git a/template/id.c.tmpl b/template/id.c.tmpl
index 5b9e879730..5aa8e47ce7 100644
--- a/template/id.c.tmpl
+++ b/template/id.c.tmpl
@@ -22,7 +22,8 @@ ops = ids[:token_op].uniq {|id, op, token| token && op}
static const struct {
unsigned short token;
- const char name[3], term;
+ RBIMPL_ATTR_NONSTRING() const char name[3];
+ const char term;
} op_tbl[] = {
% ops.each do |_id, op, token|
% next unless token
diff --git a/template/id.h.tmpl b/template/id.h.tmpl
index 4f7053885f..9c588305eb 100644
--- a/template/id.h.tmpl
+++ b/template/id.h.tmpl
@@ -67,33 +67,24 @@ enum ruby_method_ids {
id<%=token%>,
% end
tPRESERVED_ID_END,
-
% prev = 'tPRESERVED_ID_END'
% types.each do |type|
% tokens = ids[type]
- /* <%= type %> tokens {{{ */
tTOKEN_<%=type%>_BEGIN = <%=prev%>-1,
% tokens.each do |token|
t<%=token%>,
% end
% prev = "tTOKEN_#{type}_END"
<%=prev%>,
- /* <%= type %> tokens }}} */
-
% end
tNEXT_ID = <%=prev%>,
-
% types.each do |type|
% tokens = ids[type]
- /* <%= type %> IDs {{{ */
#define DEFINE_<%=type%>ID_FROM_TOKEN(n) id##n = TOKEN2<%=type%>ID(t##n)
% tokens or next
% tokens.each do |token|
DEFINE_<%=type%>ID_FROM_TOKEN(<%=token%>),
% end
-#undef DEFINE_<%=type%>ID_FROM_TOKEN
- /* <%= type %> IDs }}} */
-
% end
tLAST_OP_ID = tPRESERVED_ID_END-1,
idLAST_OP_ID = tLAST_OP_ID >> ID_SCOPE_SHIFT
diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl
index 74f6c08da7..b724ec6506 100644
--- a/template/prelude.c.tmpl
+++ b/template/prelude.c.tmpl
@@ -43,10 +43,7 @@ class Prelude
lineno = 0
result = [@preludes.size, @vpath.strip(filename), lines, sub]
@vpath.foreach(filename) do |line|
- if line.respond_to?(:force_encoding)
- enc = line.encoding
- line.force_encoding("ASCII-8BIT")
- end
+ line.force_encoding("ASCII-8BIT") if line.respond_to?(:force_encoding)
line.rstrip!
lineno += 1
@preludes[filename] ||= result
@@ -74,7 +71,6 @@ class Prelude
orig
end
end
- comment.force_encoding(enc) if enc and comment
lines << [line, comment]
end
result << (start_line || 1)
@@ -90,9 +86,9 @@ Prelude.new(output, ARGV, vpath).instance_eval do
*/
%unless @preludes.empty?
#include "internal.h"
-#include "internal/ruby_parser.h"
#include "internal/warnings.h"
#include "iseq.h"
+#include "ruby/internal/attr/nonstring.h"
#include "ruby/ruby.h"
#include "vm_core.h"
@@ -112,12 +108,12 @@ static const struct {
% size += line.size
% next
% end
- char L<%=beg%><%=%>[<%=size%><%=%>]; /* <%=beg+1%>..<%=n%> */
+ RBIMPL_ATTR_NONSTRING() char L<%=beg%><%=%>[<%=size%><%=%>]; /* <%=beg+1%>..<%=n%> */
% size = line.size
% beg = n
% }
% if size > 0
- char L<%=beg%><%=%>[<%=size%><%=%>]; /* <%=beg+1%>..<%=lines.size+1%> */
+ RBIMPL_ATTR_NONSTRING() char L<%=beg%><%=%>[<%=size%><%=%>]; /* <%=beg+1%>..<%=lines.size+1%> */
% end
} prelude_code<%=i%><%=%> = {
% size = 0
@@ -145,8 +141,8 @@ static rb_ast_t *
prelude_ast(VALUE name, VALUE code, int line)
{
rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line);
- if (!ast || !ast->body.root) {
- if (ast) rb_ast_dispose(ast);
+ if (!ast->body.root) {
+ rb_ast_dispose(ast);
rb_exc_raise(rb_errinfo());
}
return ast;
@@ -184,14 +180,15 @@ static void
prelude_eval(VALUE code, VALUE name, int line)
{
static const rb_compile_option_t optimization = {
- TRUE, /* unsigned int inline_const_cache; */
- TRUE, /* unsigned int peephole_optimization; */
- FALSE,/* unsigned int tailcall_optimization; */
- TRUE, /* unsigned int specialized_instruction; */
- TRUE, /* unsigned int operands_unification; */
- TRUE, /* unsigned int instructions_unification; */
- TRUE, /* unsigned int frozen_string_literal; */
- FALSE, /* unsigned int debug_frozen_string_literal; */
+ TRUE, /* int inline_const_cache; */
+ TRUE, /* int peephole_optimization; */
+ FALSE,/* int tailcall_optimization; */
+ TRUE, /* int specialized_instruction; */
+ TRUE, /* int operands_unification; */
+ TRUE, /* int instructions_unification; */
+ TRUE, /* int stack_caching; */
+ TRUE, /* int frozen_string_literal; */
+ FALSE, /* int debug_frozen_string_literal; */
FALSE, /* unsigned int coverage_enabled; */
0, /* int debug_level; */
};
@@ -212,7 +209,7 @@ Init_<%=init_name%><%=%>(void)
%unless @prelude_count.zero?
% preludes.each do |i, prelude, lines, sub, start_line|
% next if sub
- prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%><%=%>);
+ prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%>);
% end
#if 0
diff --git a/template/ruby.pc.in b/template/ruby.pc.in
index 6901ec2320..c4848805a3 100644
--- a/template/ruby.pc.in
+++ b/template/ruby.pc.in
@@ -52,7 +52,7 @@ DLDFLAGS=@DLDFLAGS@
Name: Ruby
Description: Object Oriented Script Language
-Version: ${RUBY_PROGRAM_VERSION}
+Version: ${ruby_version}
URL: https://www.ruby-lang.org
Cflags: -I${rubyarchhdrdir} -I${rubyhdrdir}
Libs: ${DLDFLAGS} ${LIBRUBYARG_SHARED} ${LIBS}
diff --git a/template/unicode_properties.rdoc.tmpl b/template/unicode_properties.rdoc.tmpl
deleted file mode 100755
index 7bbedc780c..0000000000
--- a/template/unicode_properties.rdoc.tmpl
+++ /dev/null
@@ -1,59 +0,0 @@
-== \Regexps Based on Unicode Properties
-
-The properties shown here are those currently supported in Ruby.
-Older versions may not support all of these.
-<%
-# Generate a documentation file for the unicode properties.
-#
-# Usage:
-#
-# Get PropertyAliases.txt, PropertyValueAliases.txt from unicode.org
-# (http://unicode.org/Public/UNIDATA/) and run
-# ```
-# ruby tool/generic_erb.rb template/unicode_properties.rdoc.tmpl data_dir name2ctype.h
-# ```
-
-data_dir = ARGV.shift&.tap { |d| Dir.exist?(d) } ||
- abort("Usage: #{$0} data_directory [name2ctype.h]")
-
-# Map group names, given as last argument to #make_const in enc-unicode.rb,
-# to sections in the doc. The order in this hash controls the order in the doc.
-map = {
- /\[\[:/ => 'POSIX brackets',
- '-' => 'Special',
- /.+ Category/ => 'Major and General Categories',
- 'Binary Property' => 'Prop List',
- /Derived Property/ => 'Derived Core Properties',
- 'Script' => 'Scripts',
- 'Block' => 'Blocks',
- 'Emoji' => 'Emoji',
- /Grapheme/ => 'Graphemes',
- /Derived Age/ => 'Derived Ages',
-}
-
-# aliases in the form { short => long }, e.g. { 'Hex' => 'Hex_Digit', 'L' => 'Letter' }
-aliases = (
- File.binread(File.join(data_dir, 'PropertyAliases.txt')).scan(/^(\w+)\s*; (\w+)/) +
- File.binread(File.join(data_dir, 'PropertyValueAliases.txt')).scan(/^(?:gc|sc)\s*; (\w+)\s*; (\w+)/)
-).to_h
-
-props_by_section = {}
-ARGF.each_line do |line|
- next unless /'(?<prop>[^']+)': (?<name>.+) \*/ =~ line
- next if prop == 'NEWLINE' # ignore custom internal prop
-
- section = map.find { |k, v| k === name }&.last || warn("no doc section for #{name}")
-
- # normalize prop names - the header file uses a mix of short and long names
- long_prop_name = aliases[prop] || prop
- (props_by_section[section] ||= []) << long_prop_name
-end
-
-map.each_value do |section| -%>
-
-=== <%=section%>
-
-% props_by_section[section].sort.each do |prop|
-- <%= [prop, aliases.key(prop)].compact.uniq.map { |v| "<tt>\\p{#{v}}</tt>" }.join(', ') %>
-% end
-% end
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb
index fd043690ac..50f2d8201f 100644
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb
@@ -4,10 +4,17 @@ 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 "flaky with RJIT" if JITSupport.rjit_enabled?
+ pend "macOS 15 is not working with this test" if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`
+
+ omit if ENV['RUBY_ON_BUG']
+
description = RUBY_DESCRIPTION
- description = description.sub(/\+RJIT /, '') unless JITSupport.rjit_force_enabled?
+ description = description.sub(/\+MJIT /, '') unless JITSupport.mjit_force_enabled?
expected_stderr = [
:*,
/\[BUG\]\sSegmentation\sfault.*\n/,
@@ -19,9 +26,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 = ["-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})
+ 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
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_profile_frames.rb b/test/-ext-/debug/test_profile_frames.rb
index b44b14d851..d6ae953dd2 100644
--- a/test/-ext-/debug/test_profile_frames.rb
+++ b/test/-ext-/debug/test_profile_frames.rb
@@ -14,8 +14,6 @@ class SampleClassForTestProfileFrames
end
class Sample2
- EVAL_LINE = __LINE__ + 3
-
def baz(block)
instance_eval "def zab(block) block.call end"
[self, zab(block)]
@@ -39,20 +37,6 @@ 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{
@@ -128,7 +112,7 @@ class TestProfileFrames < Test::Unit::TestCase
"SampleClassForTestProfileFrames#foo",
"TestProfileFrames#test_profile_frames",
]
- paths = [ nil, file=__FILE__, "(eval at #{__FILE__}:#{SampleClassForTestProfileFrames::Sample2::EVAL_LINE})", file, file, file, file, file, file, nil ]
+ paths = [ nil, file=__FILE__, "(eval)", 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)
@@ -153,56 +137,13 @@ 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)]
- 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)
+ assert_equal(backtrace_locations.size, profile_frames.size)
# The first entries are not going to match, since one is #backtrace_locations and the other #profile_frames
backtrace_locations.shift
diff --git a/test/-ext-/iseq_load/test_iseq_load.rb b/test/-ext-/iseq_load/test_iseq_load.rb
index 864ce1afbb..6e5bc8e811 100644
--- a/test/-ext-/iseq_load/test_iseq_load.rb
+++ b/test/-ext-/iseq_load/test_iseq_load.rb
@@ -123,8 +123,6 @@ 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
deleted file mode 100644
index 471d3acebd..0000000000
--- a/test/-ext-/load/test_resolve_symbol.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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
deleted file mode 100644
index 0d9736b591..0000000000
--- a/test/-ext-/load/test_stringify_symbols.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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-/postponed_job/test_postponed_job.rb b/test/-ext-/postponed_job/test_postponed_job.rb
index 8c2b3e95d1..fee0172d11 100644
--- a/test/-ext-/postponed_job/test_postponed_job.rb
+++ b/test/-ext-/postponed_job/test_postponed_job.rb
@@ -2,70 +2,34 @@
require 'test/unit'
require '-test-/postponed_job'
-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
+module Bug
+ def self.postponed_job_call_direct_wrapper(*args)
+ postponed_job_call_direct(*args)
end
- 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
+ def self.postponed_job_register_wrapper(*args)
+ postponed_job_register(*args)
end
+end
- 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
-
- def test_legacy_register
- assert_separately([], __FILE__, __LINE__, <<-'RUBY')
- require '-test-/postponed_job'
- direct, registered = [], []
-
- Bug.postponed_job_call_direct(direct)
- Bug.postponed_job_register(registered)
+class TestPostponed_job < Test::Unit::TestCase
+ def test_register
+ direct, registered = [], []
- assert_equal([0], direct)
- assert_equal([3], registered)
+ Bug.postponed_job_call_direct_wrapper(direct)
+ Bug.postponed_job_register_wrapper(registered)
- Bug.postponed_job_register_one(ary = [])
- assert_equal [1], ary
- RUBY
- end
+ assert_equal([0], direct)
+ assert_equal([3], registered)
- 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
+ Bug.postponed_job_register_one(ary = [])
+ assert_equal [1], ary
end
if Bug.respond_to?(:postponed_job_register_in_c_thread)
- 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
+ def test_register_in_c_thread
+ assert Bug.postponed_job_register_in_c_thread(ary = [])
+ assert_equal [1], ary
end
end
end
diff --git a/test/-ext-/string/test_capacity.rb b/test/-ext-/string/test_capacity.rb
index 2c6c51fdda..0cb7c00761 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(10_000 - 1, capa(String.new(capacity: 10_000))) # Real capa doesn't account for termlen
+ assert_equal(10000, capa(String.new(capacity: 10000)))
assert_equal("", String.new(capacity: -1000))
assert_equal(capa(String.new(capacity: -10000)), capa(String.new(capacity: -1000)))
@@ -66,7 +66,11 @@ class Test_StringCapacity < Test::Unit::TestCase
end
def embed_header_size
- 3 * RbConfig::SIZEOF['void*']
+ if GC.using_rvargc?
+ 2 * RbConfig::SIZEOF['void*'] + RbConfig::SIZEOF['long']
+ else
+ 2 * RbConfig::SIZEOF['void*']
+ end
end
def max_embed_len
diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb
index 962e0a0a6f..92982a315e 100644
--- a/test/-ext-/string/test_fstring.rb
+++ b/test/-ext-/string/test_fstring.rb
@@ -57,10 +57,6 @@ 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_too_many_dummy_encodings.rb b/test/-ext-/string/test_too_many_dummy_encodings.rb
deleted file mode 100644
index b96b40db7b..0000000000
--- a/test/-ext-/string/test_too_many_dummy_encodings.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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
deleted file mode 100644
index 8dbc9113a5..0000000000
--- a/test/-ext-/struct/test_data.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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-/thread/helper.rb b/test/-ext-/thread/helper.rb
deleted file mode 100644
index 3ea2057d15..0000000000
--- a/test/-ext-/thread/helper.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-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 9a3b67fa10..dd620e7380 100644
--- a/test/-ext-/thread/test_instrumentation_api.rb
+++ b/test/-ext-/thread/test_instrumentation_api.rb
@@ -1,289 +1,91 @@
# 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'
- cleanup_threads
- end
-
- def teardown
- return if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
- Bug::ThreadInstrumentation.unregister_callback
- cleanup_threads
- end
-
- THREADS_COUNT = 3
-
- 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_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
+ Thread.list.each do |thread|
+ if thread != Thread.current
+ thread.kill
+ thread.join rescue nil
end
-
- queue1.pop
- queue2 << true
- thread.join
end
+ assert_equal [Thread.current], Thread.list
- 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
+ Bug::ThreadInstrumentation.reset_counters
+ Bug::ThreadInstrumentation::register_callback
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
+ def teardown
+ return if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
+ Bug::ThreadInstrumentation::unregister_callback
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
+ THREADS_COUNT = 3
- timeline = timeline_for(thread, full_timeline)
- assert_consistent_timeline(timeline)
- assert_equal %i(started ready resumed suspended), timeline
+ 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)
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
+ def test_join_counters # Bug #18900
+ thr = Thread.new { fib(30) }
+ Bug::ThreadInstrumentation.reset_counters
+ thr.join
+ assert_join_counters(Bug::ThreadInstrumentation.local_counters)
end
def test_thread_instrumentation_fork_safe
skip "No fork()" unless Process.respond_to?(:fork)
- thread_statuses = full_timeline = nil
+ thread_statuses = counters = nil
IO.popen("-") do |read_pipe|
if read_pipe
thread_statuses = Marshal.load(read_pipe)
- full_timeline = Marshal.load(read_pipe)
+ counters = Marshal.load(read_pipe)
else
- threads = threaded_cpu_bound_work.each(&:join)
+ Bug::ThreadInstrumentation.reset_counters
+ threads = threaded_cpu_work
Marshal.dump(threads.map(&:status), STDOUT)
- full_timeline = Bug::ThreadInstrumentation.unregister_callback.map { |t, e| [t.to_s, e ] }
- Marshal.dump(full_timeline, STDOUT)
+ Marshal.dump(Bug::ThreadInstrumentation.counters, STDOUT)
end
end
assert_predicate $?, :success?
assert_equal [false] * THREADS_COUNT, thread_statuses
- thread_names = full_timeline.map(&:first).uniq
- thread_names.each do |thread_name|
- assert_consistent_timeline(timeline_for(thread_name, full_timeline))
- end
+ assert_join_counters(counters)
+ assert_global_join_counters(counters)
end
def test_thread_instrumentation_unregister
+ Bug::ThreadInstrumentation::unregister_callback
assert Bug::ThreadInstrumentation::register_and_unregister_callbacks
end
private
- def fib(n = 30)
+ def fib(n = 20)
return n if n <= 1
fib(n-1) + fib(n-2)
end
- 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
+ def threaded_cpu_work(size = 20)
+ THREADS_COUNT.times.map { Thread.new { fib(size) } }.each(&:join)
end
- def threaded_cpu_bound_work(duration = 0.5)
- THREADS_COUNT.times.map do
- Thread.new do
- cpu_bound_work(duration)
- end
+ def assert_join_counters(counters)
+ counters.each_with_index do |c, i|
+ assert_operator c, :>, 0, "Call counters[#{i}]: #{counters.inspect}"
end
end
- 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
+ def assert_global_join_counters(counters)
+ assert_equal THREADS_COUNT, counters.first
end
end
diff --git a/test/.excludes/TestArraySubclass.rb b/test/.excludes/TestArraySubclass.rb
deleted file mode 100644
index 73da272007..0000000000
--- a/test/.excludes/TestArraySubclass.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_shared_marking, "The target code has already been changed")
diff --git a/test/.excludes/TestThread.rb b/test/.excludes/TestThread.rb
deleted file mode 100644
index f26ea420a6..0000000000
--- a/test/.excludes/TestThread.rb
+++ /dev/null
@@ -1,18 +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
-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/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index b28242b747..0228240506 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -294,11 +294,7 @@ class TestBigDecimal < Test::Unit::TestCase
end
def test_s_allocate
- if RUBY_ENGINE == "truffleruby"
- assert_raise_with_message(NoMethodError, /undefined.+allocate.+for BigDecimal/) { BigDecimal.allocate }
- else
- assert_raise_with_message(TypeError, /allocator undefined for BigDecimal/) { BigDecimal.allocate }
- end
+ assert_raise_with_message(TypeError, /allocator undefined for BigDecimal/) { BigDecimal.allocate }
end
def test_s_new
@@ -1415,13 +1411,9 @@ class TestBigDecimal < Test::Unit::TestCase
end
def test_to_s
- assert_equal('0.0', BigDecimal('0').to_s)
- assert_equal('-123 45678 90123.45678 90123 45678 9', BigDecimal('-1234567890123.45678901234567890').to_s('5F'))
- assert_equal('+12345 67890123.45678901 23456789', BigDecimal('1234567890123.45678901234567890').to_s('+8F'))
- assert_equal(' 1234567890123.4567890123456789', BigDecimal('1234567890123.45678901234567890').to_s(' F'))
- assert_equal('100 000 000 000.000 000 000 01', BigDecimal('100000000000.00000000001').to_s('3F'))
- assert_equal('0.0 0 0 0 0 0 0 0 0 0 0 0 1', BigDecimal('0.0000000000001').to_s('1F'))
- assert_equal('+1000000 0000000.0', BigDecimal('10000000000000').to_s('+7F'))
+ 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
@@ -2264,23 +2256,6 @@ class TestBigDecimal < Test::Unit::TestCase
assert_equal(BigDecimal(minus_ullong_max.to_s), BigDecimal(minus_ullong_max), "[GH-200]")
end
- def test_reminder_infinity_gh_187
- # https://github.com/ruby/bigdecimal/issues/187
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- bd = BigDecimal("4.2")
- assert_equal(bd.remainder(BigDecimal("+Infinity")), bd)
- assert_equal(bd.remainder(BigDecimal("-Infinity")), bd)
- end
- end
-
- def test_bsearch_for_bigdecimal
- assert_raise(TypeError) {
- (BigDecimal('0.5')..BigDecimal('2.25')).bsearch
- }
- end
-
def assert_no_memory_leak(code, *rest, **opt)
code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}"
super(["-rbigdecimal"],
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index b0612fc87d..d058cccd86 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -74,10 +74,6 @@ 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-._~"),
@@ -105,11 +101,6 @@ 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)
@@ -186,22 +177,6 @@ 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)
@@ -269,6 +244,14 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"]))
assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<BR><A HREF="url"></A>', "A", "IMG"))
assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<BR><A HREF="url"></A>', ["A", "IMG"]))
+
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<A <A HREF="url"></A>', "A", "IMG"))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<A <A HREF="url"></A>', ["A", "IMG"]))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<A <A HREF="url"></A>', "A", "IMG"))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<A <A HREF="url"></A>', ["A", "IMG"]))
+
+ assert_equal("&lt;A &lt;A ", escapeElement('<A <A ', "A", "IMG"))
+ assert_equal("&lt;A &lt;A ", escapeElement('<A <A ', ["A", "IMG"]))
end
@@ -277,6 +260,16 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescapeElement(escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]))
assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescape_element(escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG"))
assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescape_element(escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]))
+
+ assert_equal('<A <A HREF="url"></A>', unescapeElement(escapeHTML('<A <A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('<A <A HREF="url"></A>', unescapeElement(escapeHTML('<A <A HREF="url"></A>'), ["A", "IMG"]))
+ assert_equal('<A <A HREF="url"></A>', unescape_element(escapeHTML('<A <A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('<A <A HREF="url"></A>', unescape_element(escapeHTML('<A <A HREF="url"></A>'), ["A", "IMG"]))
+
+ assert_equal('<A <A ', unescapeElement(escapeHTML('<A <A '), "A", "IMG"))
+ assert_equal('<A <A ', unescapeElement(escapeHTML('<A <A '), ["A", "IMG"]))
+ assert_equal('<A <A ', unescape_element(escapeHTML('<A <A '), "A", "IMG"))
+ assert_equal('<A <A ', unescape_element(escapeHTML('<A <A '), ["A", "IMG"]))
end
end
@@ -287,7 +280,7 @@ class CGIUtilPureRubyTest < Test::Unit::TestCase
remove_method :escapeHTML
alias _unescapeHTML unescapeHTML
remove_method :unescapeHTML
- end if defined?(CGI::Escape)
+ end
end
def teardown
@@ -296,11 +289,9 @@ class CGIUtilPureRubyTest < Test::Unit::TestCase
remove_method :_escapeHTML
alias unescapeHTML _unescapeHTML
remove_method :_unescapeHTML
- end if defined?(CGI::Escape)
+ end
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/test_coverage.rb b/test/coverage/test_coverage.rb
index 16be47b458..a2efa0d1c0 100644
--- a/test/coverage/test_coverage.rb
+++ b/test/coverage/test_coverage.rb
@@ -165,16 +165,14 @@ class TestCoverage < Test::Unit::TestCase
end
def test_eval_coverage
- assert_in_out_err(%w[-rcoverage], <<-"end;", ["[1, 1, 1, nil, 0, nil]"], [])
+ assert_in_out_err(%w[-rcoverage], <<-"end;", ["[1, nil, 1, 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
+ s = String.new
+ begin
+ s << "foo
+ bar".freeze; end
RUBY
p Coverage.result["test.rb"][:lines]
@@ -183,7 +181,6 @@ class TestCoverage < Test::Unit::TestCase
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)
@@ -848,10 +845,9 @@ class TestCoverage < Test::Unit::TestCase
EOS
end
- 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]
+ 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], [])
Coverage.setup
tmp = Dir.pwd
require tmp + "/test.rb"
@@ -860,34 +856,15 @@ class TestCoverage < Test::Unit::TestCase
bar
Coverage.suspend
baz
- assert_equal cov1, Coverage.peek_result[tmp + "/test.rb"]
+ p Coverage.peek_result[tmp + "/test.rb"]
Coverage.resume
baz
- assert_equal cov2, Coverage.result[tmp + "/test.rb"]
+ p Coverage.result[tmp + "/test.rb"]
end;
- 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,
- }
- }
-
+ 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], [])
Coverage.setup(:all)
tmp = Dir.pwd
require tmp + "/test.rb"
@@ -896,16 +873,15 @@ class TestCoverage < Test::Unit::TestCase
bar
Coverage.suspend
baz
- assert_equal cov1, Coverage.peek_result[tmp + "/test.rb"]
+ p Coverage.peek_result[tmp + "/test.rb"]
Coverage.resume
baz
- assert_equal cov2, Coverage.result[tmp + "/test.rb"]
+ p Coverage.result[tmp + "/test.rb"]
end;
- assert_separately(%w[-rcoverage], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- cov1 = {:oneshot_lines=>[6]}
- cov2 = {:oneshot_lines=>[6, 10]}
+ cov1 = "{:oneshot_lines=>[6]}"
+ cov2 = "{:oneshot_lines=>[6, 10]}"
+ assert_in_out_err(%w[-rcoverage], <<-"end;", [cov1, cov2], [])
Coverage.setup(oneshot_lines: true)
tmp = Dir.pwd
require tmp + "/test.rb"
@@ -914,10 +890,10 @@ class TestCoverage < Test::Unit::TestCase
bar
Coverage.suspend
baz
- assert_equal cov1, Coverage.peek_result[tmp + "/test.rb"]
+ p Coverage.peek_result[tmp + "/test.rb"]
Coverage.resume
baz
- assert_equal cov2, Coverage.result[tmp + "/test.rb"]
+ p Coverage.result[tmp + "/test.rb"]
end;
}
}
diff --git a/test/csv/helper.rb b/test/csv/helper.rb
index ff3aa38b10..1f9cf96979 100644
--- a/test/csv/helper.rb
+++ b/test/csv/helper.rb
@@ -5,7 +5,7 @@ require "csv"
require_relative "../lib/with_different_ofs"
-module CSVHelper
+module Helper
def with_chunk_size(chunk_size)
chunk_size_keep = ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"]
begin
diff --git a/test/csv/interface/test_read.rb b/test/csv/interface/test_read.rb
index 9b35dc2e01..001177036a 100644
--- a/test/csv/interface/test_read.rb
+++ b/test/csv/interface/test_read.rb
@@ -113,11 +113,11 @@ class TestCSVInterfaceRead < Test::Unit::TestCase
file << "\u{1F600},\u{1F601}"
end
CSV.open(@input.path, encoding: "EUC-JP") do |csv|
- error = assert_raise(CSV::InvalidEncodingError) do
+ error = assert_raise(CSV::MalformedCSVError) do
csv.shift
end
- assert_equal([Encoding::EUC_JP, "Invalid byte sequence in EUC-JP in line 1."],
- [error.encoding, error.message])
+ assert_equal("Invalid byte sequence in EUC-JP in line 1.",
+ error.message)
end
end
diff --git a/test/csv/parse/test_general.rb b/test/csv/parse/test_general.rb
index a565ff2ef8..ff32eef6d3 100644
--- a/test/csv/parse/test_general.rb
+++ b/test/csv/parse/test_general.rb
@@ -7,7 +7,7 @@ require_relative "../helper"
#
# Following tests are my interpretation of the
-# {CSV RCF}[https://www.ietf.org/rfc/rfc4180.txt]. I only deviate from that
+# {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>.
#
@@ -75,7 +75,7 @@ class TestCSVParseGeneral < Test::Unit::TestCase
end
end
- # From: [ruby-core:6496]
+ # 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\""]],
@@ -323,22 +323,15 @@ line,5,jkl
end
private
-
- {
- "YJIT"=>1, # for --yjit-call-threshold=1
- "MJIT"=>5, "RJIT"=>5, # for --jit-wait
- }.any? do |jit, timeout|
- if (RubyVM.const_defined?(jit) and
- jit = RubyVM.const_get(jit) and
- jit.respond_to?(:enabled?) and
- jit.enabled?)
- PARSE_ERROR_TIMEOUT = timeout
- end
- end
- PARSE_ERROR_TIMEOUT ||= 0.2
-
- def assert_parse_errors_out(data, timeout: PARSE_ERROR_TIMEOUT, **options)
+ def assert_parse_errors_out(data, **options)
assert_raise(CSV::MalformedCSVError) do
+ timeout = 0.2
+ if defined?(RubyVM::YJIT.enabled?) and RubyVM::YJIT.enabled?
+ timeout = 1 # for --yjit-call-threshold=1
+ end
+ 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")
diff --git a/test/csv/parse/test_inputs_scanner.rb b/test/csv/parse/test_inputs_scanner.rb
index 81327c187f..06e1c845d5 100644
--- a/test/csv/parse/test_inputs_scanner.rb
+++ b/test/csv/parse/test_inputs_scanner.rb
@@ -1,7 +1,7 @@
require_relative "../helper"
class TestCSVParseInputsScanner < Test::Unit::TestCase
- include CSVHelper
+ include Helper
def test_scan_keep_over_chunks_nested_back
input = CSV::Parser::UnoptimizedStringIO.new("abcdefghijklmnl")
diff --git a/test/csv/parse/test_row_separator.rb b/test/csv/parse/test_row_separator.rb
index 5fd8e75152..eaf6adc910 100644
--- a/test/csv/parse/test_row_separator.rb
+++ b/test/csv/parse/test_row_separator.rb
@@ -5,7 +5,7 @@ require_relative "../helper"
class TestCSVParseRowSeparator < Test::Unit::TestCase
extend DifferentOFS
- include CSVHelper
+ include Helper
def test_multiple_characters
with_chunk_size("1") do
diff --git a/test/csv/parse/test_skip_lines.rb b/test/csv/parse/test_skip_lines.rb
index 2fea02eb04..98d67ae51c 100644
--- a/test/csv/parse/test_skip_lines.rb
+++ b/test/csv/parse/test_skip_lines.rb
@@ -4,7 +4,7 @@ require_relative "../helper"
class TestCSVParseSkipLines < Test::Unit::TestCase
extend DifferentOFS
- include CSVHelper
+ include Helper
def test_default
csv = CSV.new("a,b,c\n")
@@ -115,12 +115,4 @@ class TestCSVParseSkipLines < Test::Unit::TestCase
CSV.parse("a,b\r\n,\r\n",
:skip_lines => /^,+$/))
end
-
- def test_crlf_strip_no_last_crlf
- assert_equal([["a"], ["b"]],
- CSV.parse("a\r\nb",
- row_sep: "\r\n",
- skip_lines: /^ *$/,
- strip: true))
- end
end
diff --git a/test/csv/test_encodings.rb b/test/csv/test_encodings.rb
index 55a7a60f2e..f08d551f69 100644
--- a/test/csv/test_encodings.rb
+++ b/test/csv/test_encodings.rb
@@ -5,7 +5,7 @@ require_relative "helper"
class TestCSVEncodings < Test::Unit::TestCase
extend DifferentOFS
- include CSVHelper
+ include Helper
def setup
super
@@ -280,12 +280,12 @@ class TestCSVEncodings < Test::Unit::TestCase
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::InvalidEncodingError) do
+ error = assert_raise(CSV::MalformedCSVError) do
csv.shift
csv.shift
end
- assert_equal([Encoding::UTF_8, "Invalid byte sequence in UTF-8 in line 2."],
- [error.encoding, error.message])
+ assert_equal("Invalid byte sequence in UTF-8 in line 2.",
+ error.message)
end
def test_string_input_transcode
diff --git a/test/csv/write/test_general.rb b/test/csv/write/test_general.rb
index 4788d99e81..677119e1ae 100644
--- a/test/csv/write/test_general.rb
+++ b/test/csv/write/test_general.rb
@@ -4,7 +4,7 @@
require_relative "../helper"
module TestCSVWriteGeneral
- include CSVHelper
+ include Helper
def test_tab
assert_equal("\t#{$INPUT_RECORD_SEPARATOR}",
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 c58b78455f..1fdbd4510f 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_match(/^undefined method `sizee' for /,
- Marshal.load(Marshal.dump(error)).original_message)
+ assert_equal "undefined method `sizee' for #<File:test_name_error_extension.rb (closed)>",
+ Marshal.load(Marshal.dump(error)).original_message
end
end
diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb
index 72220f32ef..71bc92ab70 100644
--- a/test/drb/drbtest.rb
+++ b/test/drb/drbtest.rb
@@ -218,7 +218,7 @@ module DRbCore
omit if RUBY_PLATFORM.include?("armv7l-linux")
omit if RUBY_PLATFORM.include?("sparc-solaris2.10")
omit if RUBY_PLATFORM.include?("freebsd")
- omit if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # expecting a certain delay is difficult for --jit-wait CI
+ 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
diff --git a/test/drb/test_drbssl.rb b/test/drb/test_drbssl.rb
index f2d9a20271..0c7e39ca70 100644
--- a/test/drb/test_drbssl.rb
+++ b/test/drb/test_drbssl.rb
@@ -23,10 +23,6 @@ class DRbSSLService < DRbService
config[:SSLVerifyCallback] = lambda{ |ok,x509_store|
true
}
- if RUBY_PLATFORM.match?(/openbsd/)
- config[:SSLMinVersion] = OpenSSL::SSL::TLS1_2_VERSION
- config[:SSLMaxVersion] = OpenSSL::SSL::TLS1_2_VERSION
- end
begin
data = open("sample.key"){|io| io.read }
config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)
diff --git a/test/drb/ut_array_drbssl.rb b/test/drb/ut_array_drbssl.rb
index 778021a0b5..5938d9ff3d 100644
--- a/test/drb/ut_array_drbssl.rb
+++ b/test/drb/ut_array_drbssl.rb
@@ -24,10 +24,6 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
config = Hash.new
config[:SSLTmpDhCallback] = proc { DRbTests::TEST_KEY_DH1024 }
- if RUBY_PLATFORM.match?(/openbsd/)
- config[:SSLMinVersion] = OpenSSL::SSL::TLS1_2_VERSION
- config[:SSLMaxVersion] = OpenSSL::SSL::TLS1_2_VERSION
- end
config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
config[:SSLVerifyCallback] = lambda{|ok,x509_store|
true
diff --git a/test/error_highlight/test_error_highlight.rb b/test/error_highlight/test_error_highlight.rb
index 006ecb05bf..37026d0578 100644
--- a/test/error_highlight/test_error_highlight.rb
+++ b/test/error_highlight/test_error_highlight.rb
@@ -37,20 +37,9 @@ class ErrorHighlightTest < Test::Unit::TestCase
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_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
nil.foo + 1
^^^^
@@ -62,7 +51,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_noarg_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
.foo + 1
^^^^
@@ -75,7 +64,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_noarg_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
foo + 1
^^^
@@ -88,7 +77,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_noarg_4
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
(nil).foo + 1
^^^^
@@ -100,7 +89,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_arg_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
nil.foo (42)
^^^^
@@ -112,7 +101,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_arg_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
.foo (
^^^^
@@ -127,7 +116,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_arg_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
foo (
^^^
@@ -142,7 +131,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_arg_4
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
nil.foo(42)
^^^^
@@ -154,7 +143,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_arg_5
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
.foo(
^^^^
@@ -169,7 +158,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_CALL_arg_6
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
foo(
^^^
@@ -184,7 +173,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_QCALL_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ ONE_RECV_MESSAGE }
+undefined method `foo' for 1:Integer
1&.foo
^^^^^
@@ -196,7 +185,7 @@ undefined method `foo' for #{ ONE_RECV_MESSAGE }
def test_QCALL_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ ONE_RECV_MESSAGE }
+undefined method `foo' for 1:Integer
1&.foo(42)
^^^^^
@@ -208,7 +197,7 @@ undefined method `foo' for #{ ONE_RECV_MESSAGE }
def test_CALL_aref_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
nil [ ]
^^^
@@ -220,7 +209,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
def test_CALL_aref_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
nil [0]
^^^
@@ -232,7 +221,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
def test_CALL_aref_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
END
nil [
@@ -243,9 +232,8 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
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 #{ recv }
+undefined method `[]' for #{ v.inspect }
v &.[](0)
^^^^
@@ -257,7 +245,7 @@ undefined method `[]' for #{ recv }
def test_CALL_aref_5
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
(nil)[ ]
^^^
@@ -269,7 +257,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
def test_CALL_aset
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for #{ NIL_RECV_MESSAGE }
+undefined method `[]=' for nil:NilClass
nil.[]=
^^^^
@@ -282,7 +270,7 @@ undefined method `[]=' for #{ NIL_RECV_MESSAGE }
def test_CALL_op_asgn
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
v += 42
^
@@ -294,7 +282,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def test_CALL_special_call_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `call' for #{ NIL_RECV_MESSAGE }
+undefined method `call' for nil:NilClass
END
nil.()
@@ -303,7 +291,7 @@ undefined method `call' for #{ NIL_RECV_MESSAGE }
def test_CALL_special_call_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `call' for #{ NIL_RECV_MESSAGE }
+undefined method `call' for nil:NilClass
END
nil.(42)
@@ -312,7 +300,7 @@ undefined method `call' for #{ NIL_RECV_MESSAGE }
def test_CALL_send
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
nil.send(:foo, 42)
^^^^^
@@ -324,7 +312,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_ATTRASGN_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for #{ NIL_RECV_MESSAGE }
+undefined method `[]=' for nil:NilClass
nil [ ] = 42
^^^^^
@@ -336,7 +324,7 @@ undefined method `[]=' for #{ NIL_RECV_MESSAGE }
def test_ATTRASGN_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for #{ NIL_RECV_MESSAGE }
+undefined method `[]=' for nil:NilClass
nil [0] = 42
^^^^^
@@ -348,7 +336,7 @@ undefined method `[]=' for #{ NIL_RECV_MESSAGE }
def test_ATTRASGN_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo=' for #{ NIL_RECV_MESSAGE }
+undefined method `foo=' for nil:NilClass
nil.foo = 42
^^^^^^
@@ -360,7 +348,7 @@ undefined method `foo=' for #{ NIL_RECV_MESSAGE }
def test_ATTRASGN_4
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for #{ NIL_RECV_MESSAGE }
+undefined method `[]=' for nil:NilClass
(nil)[0] = 42
^^^^^
@@ -372,7 +360,7 @@ undefined method `[]=' for #{ NIL_RECV_MESSAGE }
def test_ATTRASGN_5
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo=' for #{ NIL_RECV_MESSAGE }
+undefined method `foo=' for nil:NilClass
(nil).foo = 42
^^^^^^
@@ -384,7 +372,7 @@ undefined method `foo=' for #{ NIL_RECV_MESSAGE }
def test_OPCALL_binary_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
nil + 42
^
@@ -396,7 +384,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def test_OPCALL_binary_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
nil + # comment
^
@@ -409,7 +397,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def test_OPCALL_binary_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
(nil) + 42
^
@@ -421,7 +409,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def test_OPCALL_unary_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `+@' for #{ NIL_RECV_MESSAGE }
+undefined method `+@' for nil:NilClass
+ nil
^
@@ -433,7 +421,7 @@ undefined method `+@' for #{ NIL_RECV_MESSAGE }
def test_OPCALL_unary_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `+@' for #{ NIL_RECV_MESSAGE }
+undefined method `+@' for nil:NilClass
+(nil)
^
@@ -445,7 +433,7 @@ undefined method `+@' for #{ NIL_RECV_MESSAGE }
def test_FCALL_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
nil.instance_eval { foo() }
^^^
@@ -457,7 +445,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_FCALL_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
nil.instance_eval { foo(42) }
^^^
@@ -469,7 +457,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def test_VCALL_2
assert_error_message(NameError, <<~END) do
-undefined local variable or method `foo' for #{ NIL_RECV_MESSAGE }
+undefined local variable or method `foo' for nil:NilClass
nil.instance_eval { foo }
^^^
@@ -483,7 +471,7 @@ undefined local variable or method `foo' for #{ NIL_RECV_MESSAGE }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
v [0] += 42
^^^
@@ -497,7 +485,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
v [0] += # comment
^^^
@@ -512,7 +500,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
END
v [
@@ -526,7 +514,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ NIL_RECV_MESSAGE }
+undefined method `[]' for nil:NilClass
(v)[0] += 42
^^^
@@ -541,7 +529,7 @@ undefined method `[]' for #{ NIL_RECV_MESSAGE }
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
v [0] += 42
^
@@ -556,7 +544,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
v [0 ] += # comment
^
@@ -572,7 +560,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
END
v [
@@ -587,7 +575,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
(v)[0] += 42
^
@@ -662,7 +650,7 @@ undefined method `[]=' for #{ v.inspect }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
v.foo += 42
^^^^
@@ -676,7 +664,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
v.foo += # comment
^^^^
@@ -691,7 +679,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
(v).foo += 42
^^^^
@@ -706,7 +694,7 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
def v.foo; nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
v.foo += 42
^
@@ -721,7 +709,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def v.foo; nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
v.foo += # comment
^
@@ -737,7 +725,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def v.foo; nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
(v).foo += 42
^
@@ -830,54 +818,6 @@ 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
@@ -931,7 +871,7 @@ uninitialized constant ErrorHighlightTest::OP_CDECL_TEST::NotDefined
def test_OP_CDECL_op_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
OP_CDECL_TEST::Nil += 1
^
@@ -943,7 +883,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def test_OP_CDECL_op_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
OP_CDECL_TEST::Nil += # comment
^
@@ -956,7 +896,7 @@ undefined method `+' for #{ NIL_RECV_MESSAGE }
def test_OP_CDECL_op_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for #{ NIL_RECV_MESSAGE }
+undefined method `+' for nil:NilClass
Nil += 1
^
@@ -980,9 +920,8 @@ 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 #{ recv }
+undefined method `+' for ErrorHighlightTest:Class
::ErrorHighlightTest += 1
^
@@ -1043,7 +982,7 @@ local variable `foo' is not defined for #{ b.inspect }
def test_multibyte
assert_error_message(NoMethodError, <<~END) do
-undefined method `ã‚ã„ã†ãˆãŠ' for #{ NIL_RECV_MESSAGE }
+undefined method `ã‚ã„ã†ãˆãŠ' for nil:NilClass
END
nil.ã‚ã„ã†ãˆãŠ
@@ -1215,7 +1154,7 @@ nil can't be coerced into Integer (TypeError)
original_formatter, ErrorHighlight.formatter = ErrorHighlight.formatter, custom_formatter
assert_error_message(NoMethodError, <<~END) do
-undefined method `time' for #{ ONE_RECV_MESSAGE }
+undefined method `time' for 1:Integer
{:first_lineno=>#{ __LINE__ + 3 }, :first_column=>7, :last_lineno=>#{ __LINE__ + 3 }, :last_column=>12, :snippet=>" 1.time {}\\n"}
END
@@ -1233,7 +1172,7 @@ undefined method `time' for #{ ONE_RECV_MESSAGE }
tmp.close
assert_error_message(NoMethodError, <<~END.gsub("_", "\t")) do
-undefined method `time' for #{ ONE_RECV_MESSAGE }
+undefined method `time' for 1:Integer
_ _1.time {}
_ _ ^^^^^
@@ -1250,7 +1189,7 @@ _ _ ^^^^^
tmp.close
assert_error_message(NoMethodError, <<~END) do
-undefined method `time' for #{ ONE_RECV_MESSAGE }
+undefined method `time' for 1:Integer
1.time {}
^^^^^
@@ -1263,7 +1202,7 @@ undefined method `time' for #{ ONE_RECV_MESSAGE }
def test_simulate_funcallv_from_embedded_ruby
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for #{ NIL_RECV_MESSAGE }
+undefined method `foo' for nil:NilClass
END
nil.foo + 1
@@ -1278,9 +1217,8 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE }
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 #{ recv }
+ undefined local variable or method `foo' for "dummy":String
END
"dummy".instance_eval do
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/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..cf7e88427e
--- /dev/null
+++ b/test/excludes/TestThread.rb
@@ -0,0 +1,14 @@
+# 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/.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/fiber/scheduler.rb b/test/fiber/scheduler.rb
index 5090271db1..204a297133 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -1,13 +1,8 @@
# 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().
-# - 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.
+# It is not efficient for a large number of file descriptors as it uses IO.select().
+# Production Fiber schedulers should use epoll/kqueue/etc.
require 'fiber'
require 'socket'
@@ -63,7 +58,7 @@ class Scheduler
# $stderr.puts [__method__, Fiber.current].inspect
while @readable.any? or @writable.any? or @waiting.any? or @blocking.any?
- # May only handle file descriptors up to 1024...
+ # Can 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?
@@ -120,16 +115,10 @@ class Scheduler
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
@@ -164,7 +153,6 @@ 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
@@ -183,7 +171,6 @@ 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
@@ -193,39 +180,23 @@ 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
- readable = true
+ @readable[io] = Fiber.current
end
unless (events & IO::WRITABLE).zero?
- @writable[io] = fiber
- writable = true
- end
-
- if duration
- @waiting[fiber] = current_time + duration
+ @writable[io] = Fiber.current
end
Fiber.yield
ensure
- @waiting.delete(fiber) if duration
- @readable.delete(io) if readable
- @writable.delete(io) if writable
+ @readable.delete(io)
+ @writable.delete(io)
end
- # 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
@@ -233,7 +204,7 @@ class Scheduler
end.value
end
- # This hook is invoked by `Kernel#sleep` and `Thread::Mutex#sleep`.
+ # Used for Kernel#sleep and Thread::Mutex#sleep
def kernel_sleep(duration = nil)
# $stderr.puts [__method__, duration, Fiber.current].inspect
@@ -242,10 +213,8 @@ class Scheduler
return true
end
- # 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.
+ # Used when blocking on synchronization (Thread::Mutex#lock,
+ # Thread::Queue#pop, Thread::SizedQueue#push, ...)
def block(blocker, timeout = nil)
# $stderr.puts [__method__, blocker, timeout].inspect
@@ -269,8 +238,9 @@ class Scheduler
end
end
- # 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.
+ # Used when synchronization wakes up a previously-blocked fiber
+ # (Thread::Mutex#unlock, Thread::Queue#push, ...).
+ # This might be called from another thread.
def unblock(blocker, fiber)
# $stderr.puts [__method__, blocker, fiber].inspect
# $stderr.puts blocker.backtrace.inspect
@@ -284,9 +254,6 @@ 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)
@@ -295,9 +262,6 @@ class Scheduler
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
@@ -305,8 +269,6 @@ 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
@@ -366,72 +328,11 @@ class IOBufferScheduler < Scheduler
return total
end
- 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)}
-
- 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 result
- end
- 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 result
- end
- elsif result < 0
- return result
- end
- end
-
- return total
- end
-
def blocking(&block)
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
@@ -440,9 +341,6 @@ 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)
@@ -453,8 +351,6 @@ class SleepingUnblockScheduler < Scheduler
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.
diff --git a/test/fiber/test_address_resolve.rb b/test/fiber/test_address_resolve.rb
index 09c8db6049..12223bcc06 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(Socket::ResolutionError) {
+ assert_raise(SocketError) {
Addrinfo.getaddrinfo("non-existing-domain.abc", nil)
}
end
diff --git a/test/fiber/test_io.rb b/test/fiber/test_io.rb
index 0e3e086d5a..c1ad56a8cf 100644
--- a/test/fiber/test_io.rb
+++ b/test/fiber/test_io.rb
@@ -219,19 +219,4 @@ class TestFiberIO < Test::Unit::TestCase
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 a08b1ce1a9..3de70200d5 100644
--- a/test/fiber/test_io_buffer.rb
+++ b/test/fiber/test_io_buffer.rb
@@ -155,45 +155,4 @@ class TestFiberIOBuffer < Test::Unit::TestCase
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_scheduler.rb b/test/fiber/test_scheduler.rb
index 34effad816..654154c622 100644
--- a/test/fiber/test_scheduler.rb
+++ b/test/fiber/test_scheduler.rb
@@ -118,7 +118,7 @@ class TestFiberScheduler < Test::Unit::TestCase
end
def test_autoload
- 10.times do
+ 100.times do
Object.autoload(:TestFiberSchedulerAutoload, File.expand_path("autoload.rb", __dir__))
thread = Thread.new do
@@ -139,6 +139,19 @@ class TestFiberScheduler < Test::Unit::TestCase
end
end
+ def test_iseq_compile_under_gc_stress_bug_21180
+ Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ EnvUtil.under_gc_stress do
+ RubyVM::InstructionSequence.compile_file(File::NULL)
+ end
+ end
+ end.join
+ end
+
def test_deadlock
mutex = Thread::Mutex.new
condition = Thread::ConditionVariable.new
@@ -182,4 +195,32 @@ class TestFiberScheduler < Test::Unit::TestCase
thread.join
signaller.join
end
+
+ def test_condition_variable
+ condition_variable = ::Thread::ConditionVariable.new
+ mutex = ::Thread::Mutex.new
+
+ error = nil
+
+ thread = Thread.new do
+ Thread.current.report_on_exception = false
+
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ fiber = Fiber.schedule do
+ begin
+ mutex.synchronize do
+ condition_variable.wait(mutex)
+ end
+ rescue => error
+ end
+ end
+
+ fiber.raise(RuntimeError)
+ end
+
+ thread.join
+ assert_kind_of RuntimeError, error
+ end
end
diff --git a/test/fiber/test_thread.rb b/test/fiber/test_thread.rb
index 5e3cc6d0e1..6fae266955 100644
--- a/test/fiber/test_thread.rb
+++ b/test/fiber/test_thread.rb
@@ -39,7 +39,7 @@ class TestFiberThread < Test::Unit::TestCase
assert_predicate sleeper, :alive?
ensure
- sleeper&.kill&.join
+ sleeper&.kill
end
def test_thread_join_implicit
diff --git a/test/fiddle/test_c_struct_entry.rb b/test/fiddle/test_c_struct_entry.rb
index 45de2efe21..9fd16d7101 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, TYPE_DOUBLE, TYPE_BOOL]
+ types = [TYPE_DOUBLE, TYPE_CHAR]
size = CStructEntity.size types
@@ -20,12 +20,6 @@ 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 abb6bdbd32..825ea9651d 100644
--- a/test/fiddle/test_closure.rb
+++ b/test/fiddle/test_closure.rb
@@ -81,18 +81,6 @@ module Fiddle
end
end
- 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?)
diff --git a/test/fiddle/test_cparser.rb b/test/fiddle/test_cparser.rb
index f1b67476ba..ae319197a4 100644
--- a/test/fiddle/test_cparser.rb
+++ b/test/fiddle/test_cparser.rb
@@ -24,32 +24,14 @@ 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
@@ -68,32 +50,14 @@ 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
@@ -121,10 +85,6 @@ 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_func.rb b/test/fiddle/test_func.rb
index df79539e76..ff52f727d0 100644
--- a/test/fiddle/test_func.rb
+++ b/test/fiddle/test_func.rb
@@ -145,22 +145,5 @@ 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_pointer.rb b/test/fiddle/test_pointer.rb
index f2c1d285ad..d6cba04bbe 100644
--- a/test/fiddle/test_pointer.rb
+++ b/test/fiddle/test_pointer.rb
@@ -10,22 +10,6 @@ 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)
diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
index 481f913d0c..3994da7433 100644
--- a/test/fileutils/test_fileutils.rb
+++ b/test/fileutils/test_fileutils.rb
@@ -1237,14 +1237,6 @@ 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'
diff --git a/test/set/fixtures/fake_sorted_set_gem/sorted_set.rb b/test/fixtures/fake_sorted_set_gem/sorted_set.rb
index f45a766303..f45a766303 100644
--- a/test/set/fixtures/fake_sorted_set_gem/sorted_set.rb
+++ b/test/fixtures/fake_sorted_set_gem/sorted_set.rb
diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb
index fd0e57b8a5..3f4b64bbcd 100644
--- a/test/io/console/test_io_console.rb
+++ b/test/io/console/test_io_console.rb
@@ -241,6 +241,7 @@ 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
@@ -258,15 +259,6 @@ 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
diff --git a/test/io/wait/test_io_wait.rb b/test/io/wait/test_io_wait.rb
index cbc01f9622..7997a4814f 100644
--- a/test/io/wait/test_io_wait.rb
+++ b/test/io/wait/test_io_wait.rb
@@ -36,7 +36,6 @@ 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
diff --git a/test/irb/command/test_custom_command.rb b/test/irb/command/test_custom_command.rb
deleted file mode 100644
index 3a3ad11d5a..0000000000
--- a/test/irb/command/test_custom_command.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-# frozen_string_literal: true
-require "irb"
-
-require_relative "../helper"
-
-module TestIRB
- class CustomCommandIntegrationTest < TestIRB::IntegrationTestCase
- def test_command_registration_can_happen_after_irb_require
- write_ruby <<~RUBY
- require "irb"
- require "irb/command"
-
- class PrintCommand < IRB::Command::Base
- category 'CommandTest'
- description 'print_command'
- def execute(*)
- puts "Hello from PrintCommand"
- end
- end
-
- IRB::Command.register(:print!, PrintCommand)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "print!"
- type "exit"
- end
-
- assert_include(output, "Hello from PrintCommand")
- end
-
- def test_command_registration_accepts_string_too
- write_ruby <<~RUBY
- require "irb/command"
-
- class PrintCommand < IRB::Command::Base
- category 'CommandTest'
- description 'print_command'
- def execute(*)
- puts "Hello from PrintCommand"
- end
- end
-
- IRB::Command.register("print!", PrintCommand)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "print!"
- type "exit"
- end
-
- assert_include(output, "Hello from PrintCommand")
- end
-
- def test_arguments_propagation
- write_ruby <<~RUBY
- require "irb/command"
-
- class PrintArgCommand < IRB::Command::Base
- category 'CommandTest'
- description 'print_command_arg'
- def execute(arg)
- $nth_execution ||= 0
- puts "\#{$nth_execution} arg=\#{arg.inspect}"
- $nth_execution += 1
- end
- end
-
- IRB::Command.register(:print_arg, PrintArgCommand)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "print_arg"
- type "print_arg \n"
- type "print_arg a r g"
- type "print_arg a r g \n"
- type "exit"
- end
-
- assert_include(output, "0 arg=\"\"")
- assert_include(output, "1 arg=\"\"")
- assert_include(output, "2 arg=\"a r g\"")
- assert_include(output, "3 arg=\"a r g\"")
- end
-
- def test_def_extend_command_still_works
- write_ruby <<~RUBY
- require "irb"
-
- class FooBarCommand < IRB::Command::Base
- category 'FooBarCategory'
- description 'foobar_description'
- def execute(*)
- $nth_execution ||= 1
- puts "\#{$nth_execution} FooBar executed"
- $nth_execution += 1
- end
- end
-
- IRB::ExtendCommandBundle.def_extend_command(:foobar, FooBarCommand, nil, [:fbalias, IRB::Command::OVERRIDE_ALL])
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "foobar"
- type "fbalias"
- type "help foobar"
- type "exit"
- end
-
- assert_include(output, "1 FooBar executed")
- assert_include(output, "2 FooBar executed")
- assert_include(output, "foobar_description")
- end
-
- def test_no_meta_command_also_works
- write_ruby <<~RUBY
- require "irb/command"
-
- class NoMetaCommand < IRB::Command::Base
- def execute(*)
- puts "This command does not override meta attributes"
- end
- end
-
- IRB::Command.register(:no_meta, NoMetaCommand)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "no_meta"
- type "help no_meta"
- type "exit"
- end
-
- assert_include(output, "This command does not override meta attributes")
- assert_include(output, "No description provided.")
- assert_not_include(output, "Maybe IRB bug")
- end
- end
-end
diff --git a/test/irb/command/test_force_exit.rb b/test/irb/command/test_force_exit.rb
deleted file mode 100644
index 191a786872..0000000000
--- a/test/irb/command/test_force_exit.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# 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
- end
-end
diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb
deleted file mode 100644
index b34832b022..0000000000
--- a/test/irb/command/test_help.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-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
-
- def test_help_lists_helper_methods
- out = run_ruby_file do
- type "help"
- type "exit"
- end
-
- assert_match(/Helper methods\s+conf\s+Returns the current IRB context/, out)
- end
- end
-end
diff --git a/test/irb/command/test_multi_irb_commands.rb b/test/irb/command/test_multi_irb_commands.rb
deleted file mode 100644
index e313c0c5d2..0000000000
--- a/test/irb/command/test_multi_irb_commands.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require "tempfile"
-require_relative "../helper"
-
-module TestIRB
- class MultiIRBTest < IntegrationTestCase
- def setup
- super
-
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
- end
-
- def test_jobs_command_with_print_deprecated_warning
- out = run_ruby_file do
- type "jobs"
- type "exit"
- end
-
- assert_match(/Multi-irb commands are deprecated and will be removed in IRB 2\.0\.0\. Please use workspace commands instead\./, out)
- assert_match(%r|If you have any use case for multi-irb, please leave a comment at https://github.com/ruby/irb/issues/653|, out)
- assert_match(/#0->irb on main \(#<Thread:0x.+ run>: running\)/, out)
- end
-
- def test_irb_jobs_and_kill_commands
- out = run_ruby_file do
- type "irb"
- type "jobs"
- type "kill 1"
- type "exit"
- end
-
- assert_match(/#0->irb on main \(#<Thread:0x.+ sleep_forever>: stop\)/, out)
- assert_match(/#1->irb#1 on main \(#<Thread:0x.+ run>: running\)/, out)
- end
-
- def test_irb_fg_jobs_and_kill_commands
- out = run_ruby_file do
- type "irb"
- type "fg 0"
- type "jobs"
- type "kill 1"
- type "exit"
- end
-
- assert_match(/#0->irb on main \(#<Thread:0x.+ run>: running\)/, out)
- assert_match(/#1->irb#1 on main \(#<Thread:0x.+ sleep_forever>: stop\)/, out)
- end
- end
-end
diff --git a/test/irb/command/test_show_source.rb b/test/irb/command/test_show_source.rb
deleted file mode 100644
index d014c78fc4..0000000000
--- a/test/irb/command/test_show_source.rb
+++ /dev/null
@@ -1,397 +0,0 @@
-# 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
index acaf6277f3..e4ce7bff08 100644
--- a/test/irb/helper.rb
+++ b/test/irb/helper.rb
@@ -1,29 +1,22 @@
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 = [])
+ super("test")
@line_no = 0
@list = list
end
@@ -64,158 +57,20 @@ module TestIRB
end
def without_rdoc(&block)
- ::Kernel.send(:alias_method, :irb_original_require, :require)
+ ::Kernel.send(:alias_method, :old_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."
+ ::Kernel.send(:old_require, name)
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")
-
- envs_for_spawn = @envs.merge('TERM' => 'dumb', 'TEST_IRB_FORCE_INTERACTIVE' => 'true')
-
- PTY.spawn(envs_for_spawn, *cmd) do |read, write, pid|
- Timeout.timeout(TIMEOUT_SEC) do
- while line = safe_gets(read)
- lines << line
-
- # 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{irbtest- .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
+ begin
+ require_relative "../lib/envutil"
+ rescue LoadError # ruby/ruby defines EnvUtil differently
end
-
- @irbrc.write(content)
- @irbrc.close
- @envs['IRBRC'] = @irbrc.path
+ EnvUtil.suppress_warning { ::Kernel.send(:alias_method, :require, :old_require) }
end
end
end
diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb
new file mode 100644
index 0000000000..719a2bbf8f
--- /dev/null
+++ b/test/irb/test_cmd.rb
@@ -0,0 +1,692 @@
+# frozen_string_literal: false
+require "rubygems"
+require "irb"
+require "irb/extend-command"
+
+require_relative "helper"
+
+module TestIRB
+ class CommandTestCase < TestCase
+ 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.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
+ end
+
+ class ExtendCommandTest < CommandTestCase
+ 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
+ @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
+
+ class InfoCommandTest < ExtendCommandTest
+ 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")
+
+ 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
+ \.irbrc\spath:\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_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
+ \.irbrc\spath:\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
+ 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
+ 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
+ \.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_empty err
+ assert_match expected, out
+ end
+ end
+
+ def test_measure
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> ',
+ PROMPT_N: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false
+ }
+
+ c = Class.new(Object)
+ out, err = execute_lines(
+ "3\n",
+ "measure\n",
+ "3\n",
+ "measure :off\n",
+ "3\n",
+ conf: conf,
+ main: c
+ )
+
+ 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
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> ',
+ PROMPT_N: '> '
+ }
+ },
+ 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_N: '> '
+ }
+ },
+ 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_N: '> '
+ }
+ },
+ 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_with_proc
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> ',
+ PROMPT_N: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false,
+ }
+ c = Class.new(Object)
+ out, err = execute_lines(
+ "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",
+ conf: conf,
+ main: c
+ )
+
+ 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
+ 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
+
+ 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
+
+ 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_grep
+ pend if RUBY_ENGINE == 'truffleruby'
+ 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
+ pend if RUBY_ENGINE == 'truffleruby'
+ out, err = execute_lines("ls\n")
+ assert_empty err
+ assert_match(/whereami/, out)
+ assert_match(/show_source/, out)
+
+ [
+ "ls grep: /whereami/\n",
+ "ls -g whereami\n",
+ "ls -G whereami\n",
+ ].each do |line|
+ out, err = execute_lines(line)
+ assert_empty err
+ assert_match(/whereami/, out)
+ assert_not_match(/show_source/, 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
+
+ def test_show_source
+ out, err = execute_lines(
+ "show_source IRB.conf\n",
+ )
+ assert_empty err
+ assert_match(%r[/irb\.rb], out)
+ end
+
+ def test_show_source_method
+ out, err = execute_lines(
+ "p show_source('IRB.conf')\n",
+ )
+ assert_empty err
+ assert_match(%r[/irb\.rb], out)
+ end
+
+ def test_show_source_string
+ out, err = execute_lines(
+ "show_source 'IRB.conf'\n",
+ )
+ assert_empty err
+ assert_match(%r[/irb\.rb], out)
+ end
+
+ def test_show_source_alias
+ out, err = execute_lines(
+ "$ 'IRB.conf'\n",
+ conf: { COMMAND_ALIASES: { :'$' => :show_source } }
+ )
+ 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 unless defined?(show_source_test_method)
+ EOS
+
+ out, err = execute_lines(
+ "show_source 'TestIRB::ExtendCommandTest#show_source_test_method'\n",
+ )
+
+ assert_empty err
+ assert_include(out, code)
+ end
+
+ 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
+
+ def test_vars_with_aliases
+ @foo = "foo"
+ $bar = "bar"
+ out, err = execute_lines(
+ "@foo\n",
+ "$bar\n",
+ )
+ assert_empty err
+ assert_match(/"foo"/, out)
+ assert_match(/"bar"/, out)
+ ensure
+ remove_instance_variable(:@foo)
+ $bar = nil
+ end
+
+ def test_show_cmds
+ out, err = execute_lines(
+ "show_cmds\n"
+ )
+
+ assert_empty err
+ assert_match(/List all available commands and their description/, out)
+ assert_match(/Start the debugger of debug\.gem/, out)
+ end
+
+ class ShowDocTest < CommandTestCase
+ def test_help_and_show_doc
+ ["help", "show_doc"].each do |cmd|
+ out, _ = execute_lines(
+ "#{cmd} 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(possible_rdoc_output.any? { |output| output.match?(out) }, "Expect the `#{cmd}` command to match one of the possible outputs. Got:\n#{out}")
+ end
+ ensure
+ # this is the only way to reset the redefined method without coupling the test with its implementation
+ EnvUtil.suppress_warning { load "irb/cmd/help.rb" }
+ end
+
+ def test_show_doc_without_rdoc
+ out, _ = 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(/=> IRB::ExtendCommand::Help\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/cmd/help.rb" }
+ end
+ end
+
+ class EditTest < CommandTestCase
+ def setup
+ @original_editor = ENV["EDITOR"]
+ # noop the command so nothing gets executed
+ ENV["EDITOR"] = ": code"
+ end
+
+ def teardown
+ 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_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
+ # const_source_location is supported after Ruby 2.7
+ omit if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') || RUBY_ENGINE == 'truffleruby'
+
+ 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
+ end
+ end
+end
diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb
index 9d78f5233e..1b27afb898 100644
--- a/test/irb/test_color.rb
+++ b/test/irb/test_color.rb
@@ -1,11 +1,12 @@
# frozen_string_literal: false
require 'irb/color'
+require 'rubygems'
require 'stringio'
require_relative "helper"
module TestIRB
- class ColorTest < TestCase
+ class TestColor < TestCase
CLEAR = "\e[0m"
BOLD = "\e[1m"
UNDERLINE = "\e[4m"
@@ -17,20 +18,6 @@ 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"
{
@@ -89,7 +76,6 @@ 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}]",
@@ -99,7 +85,7 @@ module TestIRB
"foo %i[bar]" => "foo #{YELLOW}%i[#{CLEAR}#{YELLOW}bar#{CLEAR}#{YELLOW}]#{CLEAR}",
"foo :@bar, baz, :@@qux, :$quux" => "foo #{YELLOW}:#{CLEAR}#{YELLOW}@bar#{CLEAR}, baz, #{YELLOW}:#{CLEAR}#{YELLOW}@@qux#{CLEAR}, #{YELLOW}:#{CLEAR}#{YELLOW}$quux#{CLEAR}",
"`echo`" => "#{RED}#{BOLD}`#{CLEAR}#{RED}echo#{CLEAR}#{RED}#{BOLD}`#{CLEAR}",
- "\t" => Reline::Unicode.escape_for_print("\t") == ' ' ? ' ' : "\t", # not ^I
+ "\t" => "\t", # not ^I
"foo(*%W(bar))" => "foo(*#{RED}#{BOLD}%W(#{CLEAR}#{RED}bar#{CLEAR}#{RED}#{BOLD})#{CLEAR})",
"$stdout" => "#{GREEN}#{BOLD}$stdout#{CLEAR}",
"__END__" => "#{GREEN}__END__#{CLEAR}",
@@ -108,11 +94,14 @@ module TestIRB
"<<A+1\nA" => "#{RED}<<A#{CLEAR}+#{BLUE}#{BOLD}1#{CLEAR}\n#{RED}A#{CLEAR}",
}
- 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 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
# specific to Ruby 3.0+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
@@ -132,9 +121,18 @@ module TestIRB
})
end
else
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
+ tests.merge!({
+ "[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",
+ })
+ else
+ tests.merge!({
+ "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]]]^S",
+ "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{CYAN}#{BOLD}true#{CLEAR}) end",
+ })
+ end
tests.merge!({
- "[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}",
@@ -171,6 +169,10 @@ module TestIRB
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
+
# `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}",
@@ -199,6 +201,16 @@ module TestIRB
assert_equal_with_term(code, code, complete: false, colorable: false)
assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
+
+ unless complete_option_supported?
+ assert_equal_with_term(result, code, complete: true)
+
+ 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
end
end
@@ -224,6 +236,11 @@ module TestIRB
private
+ # `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 c2c624d868..79ab050550 100644
--- a/test/irb/test_color_printer.rb
+++ b/test/irb/test_color_printer.rb
@@ -1,11 +1,12 @@
# frozen_string_literal: false
require 'irb/color_printer'
+require 'rubygems'
require 'stringio'
require_relative "helper"
module TestIRB
- class ColorPrinterTest < TestCase
+ class TestColorPrinter < TestCase
CLEAR = "\e[0m"
BOLD = "\e[1m"
RED = "\e[31m"
@@ -14,10 +15,6 @@ 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
@@ -28,19 +25,18 @@ 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::ColorPrinterTest::IRBTestColorPrinter#{CLEAR} a#{GREEN}=#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{RED}test#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{GREEN}>#{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",
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|
@@ -51,6 +47,10 @@ 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
deleted file mode 100644
index 8cb8928adb..0000000000
--- a/test/irb/test_command.rb
+++ /dev/null
@@ -1,971 +0,0 @@
-# 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 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"
- )
-
- assert_empty err
- assert_include(out, "Current workspace: #{self}")
- 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",
- "self.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",
- "self.class\n"
- )
- assert_empty err
- assert_include(out, "Current workspace: #<#{self.class.name}::Foo")
- assert_include(out, "=> #{self.class}::Foo")
- end
-
- def test_chws_does_nothing_when_receiving_no_argument
- out, err = execute_lines(
- "chws\n",
- )
- assert_empty err
- assert_include(out, "Current workspace: #{self}")
- 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 5fe7952b3d..1ab7dbbb19 100644
--- a/test/irb/test_completion.rb
+++ b/test/irb/test_completion.rb
@@ -5,90 +5,90 @@ require "irb"
require_relative "helper"
module TestIRB
- 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)
+ class TestCompletion < TestCase
+ def setup
+ # make sure require completion candidates are not cached
+ IRB::InputCompletor.class_variable_set(:@@files_from_load_path, nil)
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')
+ 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"
end
end
- class MethodCompletionTest < CompletionTest
+ class TestMethodCompletion < TestCompletion
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))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("'foo'.up", bind: binding), "'foo'.upcase")
+ assert_equal("String.upcase", IRB::InputCompletor.retrieve_completion_data("'foo'.upcase", bind: binding, doc_namespace: true))
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))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("/foo/.ma", bind: binding), "/foo/.match")
+ assert_equal("Regexp.match", IRB::InputCompletor.retrieve_completion_data("/foo/.match", bind: binding, doc_namespace: true))
end
def test_complete_array
- assert_include(completion_candidates("[].an", binding), "[].any?")
- assert_equal("Array.any?", doc_namespace("[].any?", binding))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("[].an", bind: binding), "[].any?")
+ assert_equal("Array.any?", IRB::InputCompletor.retrieve_completion_data("[].any?", bind: binding, doc_namespace: true))
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))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("{}.an", bind: binding), "{}.any?")
+ assert_equal(["Proc.any?", "Hash.any?"], IRB::InputCompletor.retrieve_completion_data("{}.any?", bind: binding, doc_namespace: true))
# proc
- assert_include(completion_candidates("{}.bin", binding), "{}.binding")
- assert_equal(["Hash.binding", "Proc.binding"], doc_namespace("{}.binding", binding))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("{}.bin", bind: binding), "{}.binding")
+ assert_equal(["Proc.binding", "Hash.binding"], IRB::InputCompletor.retrieve_completion_data("{}.binding", bind: binding, doc_namespace: true))
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(IRB::InputCompletor.retrieve_completion_data("1.positi", bind: binding), "1.positive?")
+ assert_equal("Integer.positive?", IRB::InputCompletor.retrieve_completion_data("1.positive?", bind: binding, doc_namespace: true))
- assert_include(completion_candidates("1r.positi", binding), "1r.positive?")
- assert_equal("Rational.positive?", doc_namespace("1r.positive?", binding))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("1r.positi", bind: binding), "1r.positive?")
+ assert_equal("Rational.positive?", IRB::InputCompletor.retrieve_completion_data("1r.positive?", bind: binding, doc_namespace: true))
- assert_include(completion_candidates("0xFFFF.positi", binding), "0xFFFF.positive?")
- assert_equal("Integer.positive?", doc_namespace("0xFFFF.positive?", binding))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("0xFFFF.positi", bind: binding), "0xFFFF.positive?")
+ assert_equal("Integer.positive?", IRB::InputCompletor.retrieve_completion_data("0xFFFF.positive?", bind: binding, doc_namespace: true))
- assert_empty(completion_candidates("1i.positi", binding))
+ assert_empty(IRB::InputCompletor.retrieve_completion_data("1i.positi", bind: 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))
+ assert_include(IRB::InputCompletor.retrieve_completion_data(":foo.to_p", bind: binding), ":foo.to_proc")
+ assert_equal("Symbol.to_proc", IRB::InputCompletor.retrieve_completion_data(":foo.to_proc", bind: binding, doc_namespace: true))
end
def test_complete_class
- assert_include(completion_candidates("String.ne", binding), "String.new")
- assert_equal("String.new", doc_namespace("String.new", binding))
+ assert_include(IRB::InputCompletor.retrieve_completion_data("String.ne", bind: binding), "String.new")
+ assert_equal("String.new", IRB::InputCompletor.retrieve_completion_data("String.new", bind: binding, doc_namespace: true))
end
end
- class RequireComepletionTest < CompletionTest
+ class TestRequireComepletion < TestCompletion
def test_complete_require
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
+ candidates = IRB::InputCompletor::CompletionProc.("'irb", "require ", "")
%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)
+ candidates = IRB::InputCompletor::CompletionProc.("'irb", "require ", "")
%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
@@ -97,7 +97,7 @@ module TestIRB
test_path = Pathname.new(temp_dir)
$LOAD_PATH << test_path
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
+ candidates = IRB::InputCompletor::CompletionProc.("'foo", "require ", "")
assert_include candidates, "'foo"
ensure
$LOAD_PATH.pop if test_path
@@ -111,7 +111,7 @@ module TestIRB
object.define_singleton_method(:to_s) { temp_dir }
$LOAD_PATH << object
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
+ candidates = IRB::InputCompletor::CompletionProc.("'foo", "require ", "")
assert_include candidates, "'foo"
ensure
$LOAD_PATH.pop if object
@@ -124,28 +124,28 @@ module TestIRB
$LOAD_PATH << object
assert_nothing_raised do
- IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
+ IRB::InputCompletor::CompletionProc.("'foo", "require ", "")
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
+ pend 'Need to use virtual library paths'
+ candidates = IRB::InputCompletor::CompletionProc.("'csv", "require ", "")
+ assert_equal "'csv", candidates.first
end
def test_complete_require_relative
candidates = Dir.chdir(__dir__ + "/../..") do
- IRB::RegexpCompletor.new.completion_candidates("require_relative ", "'lib/irb", "", bind: binding)
+ 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::RegexpCompletor.new.completion_candidates("require_relative ", "'lib/irb", "", bind: binding)
+ IRB::InputCompletor::CompletionProc.("'lib/irb", "require_relative ", "")
end
%w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
assert_include candidates, word
@@ -153,7 +153,7 @@ module TestIRB
end
end
- class VariableCompletionTest < CompletionTest
+ class TestVariableCompletion < TestCompletion
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
@@ -174,13 +174,13 @@ module TestIRB
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(IRB::InputCompletor.retrieve_completion_data("str_examp", bind: binding), "str_example")
+ assert_equal("String", IRB::InputCompletor.retrieve_completion_data("str_example", bind: binding, doc_namespace: true))
+ assert_equal("String.to_s", IRB::InputCompletor.retrieve_completion_data("str_example.to_s", bind: binding, doc_namespace: true))
- 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(IRB::InputCompletor.retrieve_completion_data("@str_examp", bind: binding), "@str_example")
+ assert_equal("String", IRB::InputCompletor.retrieve_completion_data("@str_example", bind: binding, doc_namespace: true))
+ assert_equal("String.to_s", IRB::InputCompletor.retrieve_completion_data("@str_example.to_s", bind: binding, doc_namespace: true))
end
def test_complete_sort_variables
@@ -190,12 +190,12 @@ module TestIRB
xzy_1.clear
xzy2.clear
- candidates = completion_candidates("xz", binding)
+ candidates = IRB::InputCompletor.retrieve_completion_data("xz", bind: binding, doc_namespace: false)
assert_equal(%w[xzy xzy2 xzy_1], candidates)
end
end
- class ConstantCompletionTest < CompletionTest
+ class TestConstantCompletion < TestCompletion
class Foo
B3 = 1
B1 = 1
@@ -203,56 +203,134 @@ module TestIRB
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(["Foo"], IRB::InputCompletor.retrieve_completion_data("Fo", bind: binding))
+ assert_equal(["Foo::B1", "Foo::B2", "Foo::B3"], IRB::InputCompletor.retrieve_completion_data("Foo::B", bind: binding))
+ assert_equal(["Foo::B1.positive?"], IRB::InputCompletor.retrieve_completion_data("Foo::B1.pos", bind: binding))
- assert_equal(["::Forwardable"], completion_candidates("::Fo", binding))
- assert_equal("Forwardable", doc_namespace("::Forwardable", binding))
+ assert_equal(["::Forwardable"], IRB::InputCompletor.retrieve_completion_data("::Fo", bind: binding))
+ assert_equal("Forwardable", IRB::InputCompletor.retrieve_completion_data("::Forwardable", bind: binding, doc_namespace: true))
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))
+ class TestPerfectMatching < TestCompletion
+ def setup
+ # trigger PerfectMatchedProc to set up RDocRIDriver constant
+ IRB::InputCompletor::PerfectMatchedProc.("foo", bind: binding)
+
+ @original_use_stdout = IRB::InputCompletor::RDocRIDriver.use_stdout
+ # force the driver to use stdout so it doesn't start a pager and interrupt tests
+ IRB::InputCompletor::RDocRIDriver.use_stdout = true
+ end
+
+ def teardown
+ IRB::InputCompletor::RDocRIDriver.use_stdout = @original_use_stdout
+ end
+
+ def test_perfectly_matched_namespace_triggers_document_display
+ omit unless has_rdoc_content?
+
+ out, err = capture_output do
+ IRB::InputCompletor::PerfectMatchedProc.("String", bind: binding)
+ 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 = IRB::InputCompletor::PerfectMatchedProc.("{}.nil?", bind: binding)
+ 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 = IRB::InputCompletor::PerfectMatchedProc.("Stri", bind: binding)
+ 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 = IRB::InputCompletor::PerfectMatchedProc.("String", bind: 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(IRB::InputCompletor::PerfectMatchedProc.(":aiueo", bind: binding))
+ end
+
+ assert_empty(err)
+ assert_empty(out)
+ end
+
+ private
+
+ def has_rdoc_content?
+ File.exist?(RDoc::RI::Paths::BASE)
+ end
end
def test_complete_symbol
- symbols = %w"UTF-16LE UTF-7".map do |enc|
+ %w"UTF-16LE UTF-7".each do |enc|
"K".force_encoding(enc).to_sym
rescue
end
- 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))
+ _ = :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))
end
def test_complete_invalid_three_colons
- assert_empty(completion_candidates(":::A", binding))
- assert_empty(completion_candidates(":::", binding))
+ assert_empty(IRB::InputCompletor.retrieve_completion_data(":::A", bind: binding))
+ assert_empty(IRB::InputCompletor.retrieve_completion_data(":::", bind: binding))
end
def test_complete_absolute_constants_with_special_characters
- 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))
+ 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_reserved_words
- candidates = completion_candidates("de", binding)
+ candidates = IRB::InputCompletor.retrieve_completion_data("de", bind: binding)
%w[def defined?].each do |word|
assert_include candidates, word
end
- candidates = completion_candidates("__", binding)
+ candidates = IRB::InputCompletor.retrieve_completion_data("__", bind: binding)
%w[__ENCODING__ __LINE__ __FILE__].each do |word|
assert_include candidates, word
end
@@ -273,39 +351,13 @@ module TestIRB
}
bind = obj.instance_exec { binding }
- 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
-
- 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 teardown
- restore_encodings
- $VERBOSE = @verbose
- end
-
- 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
+ assert_include(IRB::InputCompletor.retrieve_completion_data("public_hog", bind: bind), "public_hoge")
+ assert_include(IRB::InputCompletor.retrieve_completion_data("public_hoge.to_s", bind: bind), "public_hoge.to_s")
+ assert_include(IRB::InputCompletor.retrieve_completion_data("public_hoge", bind: bind, doc_namespace: true), "public_hoge")
- 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')
+ assert_include(IRB::InputCompletor.retrieve_completion_data("private_hog", bind: bind), "private_hoge")
+ assert_include(IRB::InputCompletor.retrieve_completion_data("private_hoge.to_s", bind: bind), "private_hoge.to_s")
+ assert_include(IRB::InputCompletor.retrieve_completion_data("private_hoge", bind: bind, doc_namespace: true), "private_hoge")
end
end
end
diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb
index cd3f2c8f62..4d256a73a2 100644
--- a/test/irb/test_context.rb
+++ b/test/irb/test_context.rb
@@ -1,16 +1,16 @@
# frozen_string_literal: false
require 'tempfile'
require 'irb'
+require 'rubygems' if defined?(Gem)
require_relative "helper"
module TestIRB
- class ContextTest < TestCase
+ class TestContext < 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)
@@ -19,17 +19,53 @@ 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",
@@ -42,32 +78,17 @@ module TestIRB
irb.eval_input
end
assert_empty err
-
- 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)
+ assert_pattern_list([:*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
+ :*, /#<RuntimeError: Foo>\n/,
+ :*, /0$/,
+ :*, /0$/,
+ /\s*/], out)
ensure
$VERBOSE = verbose
end
def test_eval_input_raise2x
+ pend if RUBY_ENGINE == 'truffleruby'
input = TestInputMethod.new([
"raise 'Foo'\n",
"raise 'Bar'\n",
@@ -78,33 +99,11 @@ module TestIRB
irb.eval_input
end
assert_empty err
- 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"
+ assert_pattern_list([
+ :*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
+ :*, /\(irb\):2:in `<main>': Bar \(RuntimeError\)\n/,
+ :*, /#<RuntimeError: Bar>\n/,
+ ], out)
end
def test_output_to_pipe
@@ -130,14 +129,16 @@ module TestIRB
[:marshal, "123", Marshal.dump(123)],
],
failed: [
- [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:/]
+ [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/]
]
}.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
@@ -152,71 +153,61 @@ module TestIRB
end
end
- 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
+ def test_default_config
+ assert_equal(true, @context.use_autocomplete?)
end
- 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
+ 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"
+ )
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
- 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
+ [
+ "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"
+ )
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?)
+ def test_assignment_expression_with_local_variable
+ input = TestInputMethod.new
+ irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
+ code = "a /1;x=1#/"
+ refute(irb.assignment_expression?(code), "#{code}: should not be an assignment expression")
+ irb.context.workspace.binding.eval('a = 1')
+ assert(irb.assignment_expression?(code), "#{code}: should be an assignment expression")
+ refute(irb.assignment_expression?(""), "empty code should not be an assignment expression")
end
def test_echo_on_assignment
@@ -353,7 +344,7 @@ module TestIRB
end
assert_empty err
assert_equal("=> \n#{value}\n", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
+ irb.context.evaluate('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = true
@@ -363,7 +354,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_expression('A.remove_method(:inspect)', 0)
+ irb.context.evaluate('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = true
@@ -373,7 +364,7 @@ module TestIRB
end
assert_empty err
assert_equal("=> \n#{value}\n=> \n#{value}\n", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
+ irb.context.evaluate('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = false
@@ -383,7 +374,7 @@ module TestIRB
end
assert_empty err
assert_equal("", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
+ irb.context.evaluate('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = false
@@ -393,7 +384,7 @@ module TestIRB
end
assert_empty err
assert_equal("", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
+ irb.context.evaluate('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = false
@@ -403,7 +394,7 @@ module TestIRB
end
assert_empty err
assert_equal("", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
+ irb.context.evaluate('A.remove_method(:inspect)', 0)
end
end
@@ -471,6 +462,7 @@ 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
@@ -500,35 +492,28 @@ module TestIRB
irb.eval_input
end
assert_empty err
- 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)
+ if 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)
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,31 +523,22 @@ module TestIRB
irb.eval_input
end
assert_empty err
- 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)
+ if 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)
ensure
$VERBOSE = verbose
end
@@ -588,43 +564,43 @@ module TestIRB
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
@@ -633,43 +609,6 @@ 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_prompt_format
- main = 'main'
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
- assert_equal('%% main %m %main %%m >', irb.send(:format_prompt, '%%%% %m %%m %%%m %%%%m %l', '>', 1, 1))
- assert_equal('42,%i, 42,%3i,042,%03i', irb.send(:format_prompt, '%i,%%i,%3i,%%3i,%03i,%%03i', nil, 42, 1))
- assert_equal('42,%n, 42,%3n,042,%03n', irb.send(:format_prompt, '%n,%%n,%3n,%%3n,%03n,%%03n', nil, 1, 42))
- end
-
def test_lineno
input = TestInputMethod.new([
"\n",
@@ -691,31 +630,6 @@ 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_debug_cmd.rb b/test/irb/test_debug_cmd.rb
new file mode 100644
index 0000000000..4d1bb6d6b9
--- /dev/null
+++ b/test/irb/test_debug_cmd.rb
@@ -0,0 +1,303 @@
+# frozen_string_literal: true
+
+begin
+ require "pty"
+rescue LoadError
+ return
+end
+
+require "tempfile"
+require "tmpdir"
+require "envutil"
+
+require_relative "helper"
+
+module TestIRB
+ LIB = File.expand_path("../../lib", __dir__)
+
+ class DebugCommandTestCase < TestCase
+ IRB_AND_DEBUGGER_OPTIONS = {
+ "RUBY_DEBUG_NO_RELINE" => "true", "NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => ''
+ }
+
+ def setup
+ if ruby_core?
+ omit "This test works only under ruby/irb"
+ end
+
+ if RUBY_ENGINE == 'truffleruby'
+ omit "This test runs with ruby/debug, which doesn't work with truffleruby"
+ end
+ end
+
+ def test_backtrace
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ end
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "backtrace"
+ type "q!"
+ end
+
+ assert_match(/\(rdbg:irb\) 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(/\(rdbg\) next/, output)
+ assert_match(/=> 2\| puts "hello"/, 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(/\(rdbg:irb\) 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(/\(rdbg:irb\) 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(/\(rdbg:irb\) 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(/\(rdbg:irb\) step/, output)
+ assert_match(/=> 5\| foo/, output)
+ assert_match(/=> 2\| puts "Hello"/, 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(/\(rdbg:irb\) continue/, output)
+ assert_match(/=> 3: binding.irb/, 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(/\(rdbg:irb\) 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(/\(rdbg:irb\) 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(/\(rdbg:irb\) catch/, output)
+ assert_match(/Stop by #0 BP - Catch "ZeroDivisionError"/, output)
+ end
+
+ private
+
+ TIMEOUT_SEC = 3
+
+ def run_ruby_file(&block)
+ cmd = [EnvUtil.rubybin, "-I", LIB, @ruby_file.to_path]
+ tmp_dir = Dir.mktmpdir
+ rc_file = File.open(File.join(tmp_dir, ".irbrc"), "w+")
+ rc_file.write("IRB.conf[:USE_SINGLELINE] = true")
+ rc_file.close
+
+ @commands = []
+ lines = []
+
+ yield
+
+ PTY.spawn(IRB_AND_DEBUGGER_OPTIONS.merge("IRBRC" => rc_file.to_path), *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
+ File.unlink(@ruby_file) if @ruby_file
+ 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#L729-L736
+ 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})
+ @ruby_file.write(program)
+ @ruby_file.close
+ end
+ end
+end
diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb
deleted file mode 100644
index 8b1bddea17..0000000000
--- a/test/irb/test_debugger_integration.rb
+++ /dev/null
@@ -1,496 +0,0 @@
-# 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_debug_command_can_only_be_called_from_binding_irb
- write_ruby <<~'ruby'
- require "irb"
- # trick test framework
- puts "binding.irb"
- IRB.start
- ruby
-
- output = run_ruby_file do
- type "debug"
- type "exit"
- end
-
- assert_include(output, "Debugging commands are only available when IRB is started with binding.irb")
- end
-
- def test_next
- write_ruby <<~'ruby'
- binding.irb
- 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 "he" + "llo"
- RUBY
-
- output = run_ruby_file do
- type "debug"
- type "exit"
- end
-
- assert_match(/irb:rdbg\(main\):002>/, output)
- assert_match(/hello/, output)
- end
-
- def test_force_exit
- write_ruby <<~'RUBY'
- binding.irb
- puts "he" + "llo"
- RUBY
-
- output = run_ruby_file do
- type "debug"
- type "exit!"
- end
-
- assert_match(/irb:rdbg\(main\):002>/, output)
- assert_not_match(/hello/, output)
- end
-
- def test_quit
- write_ruby <<~'RUBY'
- binding.irb
- puts "he" + "llo"
- RUBY
-
- output = run_ruby_file do
- type "debug"
- type "quit!"
- end
-
- assert_match(/irb:rdbg\(main\):002>/, output)
- assert_not_match(/hello/, 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
deleted file mode 100644
index 54913ceff5..0000000000
--- a/test/irb/test_eval_history.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# 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
deleted file mode 100644
index adb69b2067..0000000000
--- a/test/irb/test_evaluation.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# 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_helper_method.rb b/test/irb/test_helper_method.rb
deleted file mode 100644
index 291278c16a..0000000000
--- a/test/irb/test_helper_method.rb
+++ /dev/null
@@ -1,134 +0,0 @@
-# frozen_string_literal: true
-require "irb"
-
-require_relative "helper"
-
-module TestIRB
- class HelperMethodTestCase < TestCase
- def setup
- $VERBOSE = nil
- @verbosity = $VERBOSE
- save_encodings
- IRB.instance_variable_get(:@CONF).clear
- end
-
- def teardown
- $VERBOSE = @verbosity
- 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.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.conf[:USE_PAGER] = false
- capture_output do
- irb.eval_input
- end
- end
- end
-
- module TestHelperMethod
- class ConfTest < HelperMethodTestCase
- def test_conf_returns_the_context_object
- out, err = execute_lines("conf.ap_name")
-
- assert_empty err
- assert_include out, "=> \"irb\""
- end
- end
- end
-
- class HelperMethodIntegrationTest < IntegrationTestCase
- def test_arguments_propogation
- write_ruby <<~RUBY
- require "irb/helper_method"
-
- class MyHelper < IRB::HelperMethod::Base
- description "This is a test helper"
-
- def execute(
- required_arg, optional_arg = nil, *splat_arg, required_keyword_arg:,
- optional_keyword_arg: nil, **double_splat_arg, &block_arg
- )
- puts [required_arg, optional_arg, splat_arg, required_keyword_arg, optional_keyword_arg, double_splat_arg, block_arg.call].to_s
- end
- end
-
- IRB::HelperMethod.register(:my_helper, MyHelper)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type <<~INPUT
- my_helper(
- "required", "optional", "splat", required_keyword_arg: "required",
- optional_keyword_arg: "optional", a: 1, b: 2
- ) { "block" }
- INPUT
- type "exit"
- end
-
- assert_include(output, '["required", "optional", ["splat"], "required", "optional", {:a=>1, :b=>2}, "block"]')
- end
-
- def test_helper_method_injection_can_happen_after_irb_require
- write_ruby <<~RUBY
- require "irb"
-
- class MyHelper < IRB::HelperMethod::Base
- description "This is a test helper"
-
- def execute
- puts "Hello from MyHelper"
- end
- end
-
- IRB::HelperMethod.register(:my_helper, MyHelper)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "my_helper"
- type "exit"
- end
-
- assert_include(output, 'Hello from MyHelper')
- end
-
- def test_helper_method_instances_are_memoized
- write_ruby <<~RUBY
- require "irb/helper_method"
-
- class MyHelper < IRB::HelperMethod::Base
- description "This is a test helper"
-
- def execute(val)
- @val ||= val
- end
- end
-
- IRB::HelperMethod.register(:my_helper, MyHelper)
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "my_helper(100)"
- type "my_helper(200)"
- type "exit"
- end
-
- assert_include(output, '=> 100')
- assert_not_include(output, '=> 200')
- end
- end
-end
diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb
index 63be35fdaa..c74a3a2cb9 100644
--- a/test/irb/test_history.rb
+++ b/test/irb/test_history.rb
@@ -1,45 +1,22 @@
# frozen_string_literal: false
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 HistoryTest < TestCase
+ class TestHistory < TestCase
def setup
- @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)
+ IRB.conf[:RC_NAME_GENERATOR] = nil
end
def teardown
- 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 TestInputMethodWithRelineHistory < TestInputMethod
- # When IRB.conf[:USE_MULTILINE] is true, IRB::RelineInputMethod uses Reline::History
- HISTORY = Reline::History.new(Reline.core.config)
-
- include IRB::HistorySavingAbility
+ IRB.conf[:RC_NAME_GENERATOR] = nil
end
- class TestInputMethodWithReadlineHistory < TestInputMethod
- # When IRB.conf[:USE_MULTILINE] is false, IRB::ReadlineInputMethod uses Readline::HISTORY
- HISTORY = Readline::HISTORY
+ class TestInputMethodWithHistory < TestInputMethod
+ HISTORY = Array.new
include IRB::HistorySavingAbility
end
@@ -123,80 +100,10 @@ module TestIRB
INPUT
end
- def test_history_concurrent_use_reline
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = 1
- history_concurrent_use_for_input_method(TestInputMethodWithRelineHistory)
- end
-
- def test_history_concurrent_use_readline
+ def test_history_concurrent_use
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|
+ assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT) do |history_file|
exit
5
exit
@@ -209,7 +116,7 @@ module TestIRB
5
exit
INPUT
- assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2, input_method)
+ assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2)
exit
EXPECTED_HISTORY2
1
@@ -224,31 +131,60 @@ module TestIRB
end
end
- def assert_history(expected_history, initial_irb_history, input, input_method = TestInputMethodWithRelineHistory, locale: IRB::Locale.new)
- IRB.conf[:LC_MESSAGES] = locale
- actual_history = nil
- history_file = IRB.rc_file("_history")
- ENV["HOME"] = @tmpdir
- File.open(history_file, "w") do |f|
- f.write(initial_irb_history)
+ def test_history_concurrent_use_not_present
+ backup_home = ENV["HOME"]
+ backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME")
+ backup_irbrc = ENV.delete("IRBRC")
+ IRB.conf[:LC_MESSAGES] = IRB::Locale.new
+ IRB.conf[:SAVE_HISTORY] = 1
+ Dir.mktmpdir("test_irb_history_") do |tmpdir|
+ ENV["HOME"] = tmpdir
+ io = TestInputMethodWithHistory.new
+ io.class::HISTORY.clear
+ io.load_history
+ io.class::HISTORY.concat(%w"line1 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
+ ensure
+ ENV["HOME"] = backup_home
+ ENV["XDG_CONFIG_HOME"] = backup_xdg_config_home
+ ENV["IRBRC"] = backup_irbrc
+ 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
+ actual_history = nil
+ Dir.mktmpdir("test_irb_history_") do |tmpdir|
+ ENV["HOME"] = tmpdir
+ File.open(IRB.rc_file("_history"), "w") do |f|
+ f.write(initial_irb_history)
+ end
- 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 = TestInputMethodWithHistory.new
io.class::HISTORY.clear
- previous_history.each { |line| io.class::HISTORY << line }
- end
- input.split.each { |line| io.class::HISTORY << line }
- io.save_history
+ 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
- io.load_history
- File.open(history_file, "r") do |f|
- actual_history = f.read
+ io.load_history
+ File.open(IRB.rc_file("_history"), "r") do |f|
+ actual_history = f.read
+ end
end
assert_equal(expected_history, actual_history, <<~MESSAGE)
expected:
@@ -256,6 +192,10 @@ 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
@@ -266,226 +206,4 @@ module TestIRB
end
end
end
-
- 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
+end if not RUBY_PLATFORM.match?(/solaris|mswin|mingw/i)
diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb
index f11d7398c8..d9e338da8d 100644
--- a/test/irb/test_init.rb
+++ b/test/irb/test_init.rb
@@ -5,24 +5,19 @@ require "fileutils"
require_relative "helper"
module TestIRB
- class InitTest < TestCase
+ class TestInit < 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 = File.realpath(Dir.mktmpdir("test_irb_init_#{$$}"))
- end
-
- def reset_rc_name_generators
- IRB.instance_variable_set(:@existing_rc_name_generators, nil)
+ ENV["HOME"] = @tmpdir = Dir.mktmpdir("test_irb_init_#{$$}")
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
@@ -39,80 +34,42 @@ module TestIRB
assert_equal orig, $0
end
- def test_rc_files
+ def test_rc_file
tmpdir = @tmpdir
Dir.chdir(tmpdir) do
- 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'))
+ ENV["XDG_CONFIG_HOME"] = "#{tmpdir}/xdg"
+ 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"))
+ assert_file.not_exist?(tmpdir+"/xdg")
+ 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"))
+ assert_file.not_exist?(tmpdir+"/xdg")
end
end
- def test_duplicated_rc_files
+ def test_rc_file_in_subdir
tmpdir = @tmpdir
Dir.chdir(tmpdir) do
- 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)
+ 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"))
end
- reset_rc_name_generators
- assert_equal([env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc], IRB.irbrc_files)
end
end
- def test_sigint_restore_default
+ def test_recovery_sigint
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'] : []
- # 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", //, //)
+ status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e binding.irb;loop{Process.kill("SIGINT",$$)} -- -f --], "exit\n", //, //)
Process.kill("SIGKILL", status.pid) if !status.exited? && !status.stopped? && !status.signaled?
end
@@ -163,50 +120,6 @@ module TestIRB
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)
@@ -251,12 +164,6 @@ module TestIRB
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)
@@ -267,44 +174,4 @@ 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
index ce317b4b32..fdfb566390 100644
--- a/test/irb/test_input_method.rb
+++ b/test/irb/test_input_method.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: false
require "irb"
-require "rdoc"
+
require_relative "helper"
module TestIRB
- class InputMethodTest < TestCase
+ class TestRelineInputMethod < TestCase
def setup
@conf_backup = IRB.conf.dup
IRB.conf[:LC_MESSAGES] = IRB::Locale.new
@@ -15,22 +15,16 @@ module TestIRB
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)
+ IRB::RelineInputMethod.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
+ assert_equal IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS, Reline.basic_word_break_characters
+ assert_equal IRB::InputCompletor::CompletionProc, Reline.completion_proc
+ assert_equal IRB::InputCompletor::PerfectMatchedProc, Reline.dig_perfect_match_proc
end
def test_initialization_without_use_autocomplete
@@ -40,7 +34,7 @@ module TestIRB
IRB.conf[:USE_AUTOCOMPLETE] = false
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+ IRB::RelineInputMethod.new
refute Reline.autocompletion
assert_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
@@ -55,10 +49,10 @@ module TestIRB
IRB.conf[:USE_AUTOCOMPLETE] = true
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+ IRB::RelineInputMethod.new
assert Reline.autocompletion
- assert_not_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
+ assert_equal IRB::RelineInputMethod::SHOW_DOC_DIALOG, Reline.dialog_proc(:show_doc).dialog_proc
ensure
Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
end
@@ -71,7 +65,7 @@ module TestIRB
IRB.conf[:USE_AUTOCOMPLETE] = true
without_rdoc do
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+ IRB::RelineInputMethod.new
end
assert Reline.autocompletion
@@ -81,93 +75,5 @@ module TestIRB
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
deleted file mode 100644
index 28be744088..0000000000
--- a/test/irb/test_irb.rb
+++ /dev/null
@@ -1,917 +0,0 @@
-# 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 NestedBindingIrbTest < IntegrationTestCase
- def test_current_context_restore
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type '$ctx = IRB.CurrentContext'
- type 'binding.irb'
- type 'p context_changed: IRB.CurrentContext != $ctx'
- type 'exit'
- type 'p context_restored: IRB.CurrentContext == $ctx'
- type 'exit'
- end
-
- assert_include output, '{:context_changed=>true}'
- assert_include output, '{:context_restored=>true}'
- end
- end
-
- class IrbIOConfigurationTest < TestCase
- Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :indent_level)
-
- 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
-
- class BacktraceFilteringTest < TestIRB::IntegrationTestCase
- def test_backtrace_filtering
- write_ruby <<~'RUBY'
- def foo
- raise "error"
- end
-
- def bar
- foo
- end
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "bar"
- type "exit"
- end
-
- assert_match(/irbtest-.*\.rb:2:in (`|'Object#)foo': error \(RuntimeError\)/, output)
- frame_traces = output.split("\n").select { |line| line.strip.match?(/from /) }.map(&:strip)
-
- expected_traces = if RUBY_VERSION >= "3.3.0"
- [
- /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/,
- /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/,
- /from <internal:kernel>:\d+:in (`|'Kernel#)loop'/,
- /from <internal:prelude>:\d+:in (`|'Binding#)irb'/,
- /from .*\/irbtest-.*.rb:9:in [`']<main>'/
- ]
- else
- [
- /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/,
- /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/,
- /from <internal:prelude>:\d+:in (`|'Binding#)irb'/,
- /from .*\/irbtest-.*.rb:9:in [`']<main>'/
- ]
- end
-
- expected_traces.reverse! if RUBY_VERSION < "3.0.0"
-
- expected_traces.each_with_index do |expected_trace, index|
- assert_match(expected_trace, frame_traces[index])
- end
- end
-
- def test_backtrace_filtering_with_backtrace_filter
- write_rc <<~'RUBY'
- class TestBacktraceFilter
- def self.call(backtrace)
- backtrace.reject { |line| line.include?("internal") }
- end
- end
-
- IRB.conf[:BACKTRACE_FILTER] = TestBacktraceFilter
- RUBY
-
- write_ruby <<~'RUBY'
- def foo
- raise "error"
- end
-
- def bar
- foo
- end
-
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "bar"
- type "exit"
- end
-
- assert_match(/irbtest-.*\.rb:2:in (`|'Object#)foo': error \(RuntimeError\)/, output)
- frame_traces = output.split("\n").select { |line| line.strip.match?(/from /) }.map(&:strip)
-
- expected_traces = [
- /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/,
- /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/,
- /from .*\/irbtest-.*.rb:9:in [`']<main>'/
- ]
-
- expected_traces.reverse! if RUBY_VERSION < "3.0.0"
-
- expected_traces.each_with_index do |expected_trace, index|
- assert_match(expected_trace, frame_traces[index])
- end
- end
- end
-end
diff --git a/test/irb/test_locale.rb b/test/irb/test_locale.rb
deleted file mode 100644
index 930a38834c..0000000000
--- a/test/irb/test_locale.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-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
deleted file mode 100644
index 2482d40081..0000000000
--- a/test/irb/test_nesting_parser.rb
+++ /dev/null
@@ -1,341 +0,0 @@
-# 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 fec31f384f..e334cee6dd 100644
--- a/test/irb/test_option.rb
+++ b/test/irb/test_option.rb
@@ -2,7 +2,7 @@
require_relative "helper"
module TestIRB
- class OptionTest < TestCase
+ class TestOption < 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
deleted file mode 100644
index 44a5ae87e1..0000000000
--- a/test/irb/test_raise_exception.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# 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
new file mode 100644
index 0000000000..9565419cdd
--- /dev/null
+++ b/test/irb/test_raise_no_backtrace_exception.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: false
+require "tmpdir"
+
+require_relative "helper"
+
+module TestIRB
+ class TestRaiseNoBacktraceException < TestCase
+ def test_raise_exception
+ 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
+ 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_ruby_lex.rb b/test/irb/test_ruby_lex.rb
index 4e406a8ce0..fa68a4632c 100644
--- a/test/irb/test_ruby_lex.rb
+++ b/test/irb/test_ruby_lex.rb
@@ -1,10 +1,26 @@
-# frozen_string_literal: true
-require "irb"
+$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
+require 'irb'
+require 'rubygems'
+require 'ostruct'
require_relative "helper"
module TestIRB
- class RubyLexTest < TestCase
+ class TestRubyLex < 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 setup
save_encodings
end
@@ -13,77 +29,638 @@ module TestIRB
restore_encodings
end
- 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 })
+ 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
+
+ context = build_context
+ context.auto_indent_mode = true
+ 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: context)
+ ruby_lex.set_auto_indent(context)
+ end
+
+ def assert_nesting_level(lines, expected, local_variables: [])
+ ruby_lex = ruby_lex_for_lines(lines, local_variables: local_variables)
+ 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 assert_code_block_open(lines, expected, local_variables: [])
+ ruby_lex = ruby_lex_for_lines(lines, local_variables: local_variables)
+ error_message = "Wrong result of code_block_open for:\n #{lines.join("\n")}"
+ assert_equal(expected, ruby_lex.instance_variable_get(:@code_block_open), error_message)
+ end
+
+ def ruby_lex_for_lines(lines, local_variables: [])
+ ruby_lex = RubyLex.new()
+
+ context = build_context(local_variables)
+ io = proc{ lines.join("\n") }
+ ruby_lex.set_input(io, io, context: context)
+ ruby_lex.lex(context)
+ ruby_lex
+ 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
- # 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
+
+ def test_endless_range_at_end_of_line
+ 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_heredoc_with_embexpr
+ input_with_prompt = [
+ PromptRow.new('001:0:":* ', %q(<<A+%W[#{<<B)),
+ PromptRow.new('002:0:":* ', %q(#{<<C+%W[)),
+ PromptRow.new('003:0:":* ', %q()),
+ PromptRow.new('004:0:":* ', %q(C)),
+ PromptRow.new('005:0:]:* ', %q()),
+ PromptRow.new('006:0:":* ', %q(]})),
+ PromptRow.new('007:0:":* ', %q(})),
+ PromptRow.new('008:0:":* ', %q(A)),
+ PromptRow.new('009:0:]:* ', %q(B)),
+ PromptRow.new('010:0:]:* ', %q(})),
+ PromptRow.new('011:0: :> ', %q(])),
+ PromptRow.new('012: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_backtick_method
+ input_with_prompt = [
+ PromptRow.new('001:0: :> ', %q(self.`(arg))),
+ PromptRow.new('002:0: :* ', %q()),
+ PromptRow.new('003:0: :> ', %q(def `(); end)),
+ PromptRow.new('004: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),
+ ]
+
+ 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_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
+ 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)
+ 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)
+ 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
+ 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
+ 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
end
def test_local_variables_dependent_code
+ pend if RUBY_ENGINE == 'truffleruby'
lines = ["a /1#/ do", "2"]
- assert_indent_level(lines, 1)
+ assert_nesting_level(lines, 1)
assert_code_block_open(lines, true)
- assert_indent_level(lines, 0, local_variables: ['a'])
+ assert_nesting_level(lines, 0, local_variables: ['a'])
assert_code_block_open(lines, false, local_variables: ['a'])
end
- def test_literal_ends_with_space
- assert_code_block_open(['% a'], true)
- assert_code_block_open(['% a '], false)
+ 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
end
- def test_literal_ends_with_newline
- assert_code_block_open(['%'], true)
- assert_code_block_open(['%', ''], false)
+ 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),
+ ]
+
+ 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_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),
+ ]
+
+ 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 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)
+ 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
+ context = build_context
+ ruby_lex.set_input(io, context: context)
end
- 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
+ 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)),
+ ]
- # recoverable syntax error code is not terminated
- assert_code_block_open(['a+'], true)
+ lines = input_with_prompt.map(&:content)
+ expected_prompt_list = input_with_prompt.map(&:prompt)
+ assert_dynamic_prompt(lines, expected_prompt_list)
+ end
- # unrecoverable syntax error code is terminated
- assert_code_block_open(['.; a+'], false)
+ 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(])),
+ ]
- # 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)
+ lines = input_with_prompt.map(&:content)
+ expected_prompt_list = input_with_prompt.map(&:prompt)
+ assert_dynamic_prompt(lines, expected_prompt_list)
end
def test_broken_percent_literal
- tokens = IRB::RubyLex.ripper_lex_without_warning('%wwww')
+ 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')
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}.")
@@ -92,7 +669,11 @@ module TestIRB
end
def test_broken_percent_literal_in_method
- tokens = IRB::RubyLex.ripper_lex_without_warning(<<~EOC.chomp)
+ 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)
def foo
%wwww
end
@@ -105,8 +686,12 @@ module TestIRB
end
def test_unterminated_code
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
+ pend 'This test needs Ripper::Lexer#scan to take broken tokens'
+ end
+
['do', '<<A'].each do |code|
- tokens = IRB::RubyLex.ripper_lex_without_warning(code)
+ tokens = 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')
@@ -115,128 +700,26 @@ module TestIRB
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
+ tokens = RubyLex.ripper_lex_without_warning(code)
+ string_literal = RubyLex.new.check_string_literal(tokens)
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 build_context(local_variables = nil)
+ IRB.init_config(nil)
+ workspace = IRB::WorkSpace.new(TOPLEVEL_BINDING.dup)
- 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"
+ if local_variables
+ local_variables.each do |n|
+ workspace.binding.local_variable_set(n, nil)
+ end
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]
+ IRB.conf[:VERBOSE] = false
+ IRB::Context.new(nil, workspace)
end
end
end
diff --git a/test/irb/test_tracer.rb b/test/irb/test_tracer.rb
deleted file mode 100644
index 540f8be131..0000000000
--- a/test/irb/test_tracer.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# 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
deleted file mode 100644
index 5ed8988b34..0000000000
--- a/test/irb/test_type_completor.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# 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 199ce95a37..9b10c27b89 100644
--- a/test/irb/test_workspace.rb
+++ b/test/irb/test_workspace.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
require 'tempfile'
+require 'rubygems'
require 'irb'
require 'irb/workspace'
require 'irb/color'
@@ -7,7 +8,7 @@ require 'irb/color'
require_relative "helper"
module TestIRB
- class WorkSpaceTest < TestCase
+ class TestWorkSpace < TestCase
def test_code_around_binding
IRB.conf[:USE_COLORIZE] = false
Tempfile.create('irb') do |f|
@@ -82,6 +83,7 @@ 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__}/../.."
@@ -90,7 +92,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 44e07a3a12..9e09948869 100644
--- a/test/irb/yamatanooroti/test_rendering.rb
+++ b/test/irb/yamatanooroti/test_rendering.rb
@@ -2,516 +2,248 @@ 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::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)
- 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 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_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_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
+ 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
- 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
+ @irbrc_backup = ENV['IRBRC']
+ @irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc')
+ File.unlink(@irbrc_file) if File.exist?(@irbrc_file)
+ 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
+ def teardown
+ FileUtils.rm_rf(@tmpdir)
+ ENV['IRBRC'] = @irbrc_backup
+ ENV.delete('RELINE_TEST_PROMPT') if ENV['RELINE_TEST_PROMPT']
+ end
- # 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/
+ 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
- 001> IRB
- IRBPress Opti
- IRB
+ irb(main):001:0> 'Hello, World!'
+ => "Hello, World!"
+ irb(main):002:0>
+ 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
EOC
- else
+ close
assert_screen(<<~EOC)
start IRB
- 001> IRB
- IRBPress Alt+
- 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
- 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_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
- 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_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
+ 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_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
+ 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:0> :`
+ => :`
+ irb(main):002:0>
+ EOC
+ end
- 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_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_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
+ 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
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_include(screen, "irb:rdbg(main):002> foo\n")
- ensure
- File.unlink(script) if script
- 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:0> #{code}
+ =>
+ [0,
+ ...
+ irb(main):002:0>
+ EOC
+ end
- private
+ private
- def write_irbrc(content)
- File.open(@irbrc_file, 'w') do |f|
- f.write content
+ def write_irbrc(content)
+ File.open(@irbrc_file, 'w') do |f|
+ f.write content
+ end
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 2877bef7d8..614c735567 100644
--- a/test/json/json_addition_test.rb
+++ b/test/json/json_addition_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require_relative 'test_helper'
+require 'test_helper'
require 'json/add/core'
require 'json/add/complex'
require 'json/add/rational'
@@ -183,7 +183,7 @@ 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 if defined?(::BigDecimal)
+ end
def test_ostruct
o = OpenStruct.new
diff --git a/test/json/json_common_interface_test.rb b/test/json/json_common_interface_test.rb
index c16f6ceaaf..9148b78c8b 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_relative 'test_helper'
+require 'test_helper'
require 'stringio'
require 'tempfile'
@@ -99,26 +99,18 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
def test_dump
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
- 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)
+ 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
end
def test_dump_should_modify_defaults
diff --git a/test/json/json_encoding_test.rb b/test/json/json_encoding_test.rb
index be87f3c3d6..cc7b71553a 100644
--- a/test/json/json_encoding_test.rb
+++ b/test/json/json_encoding_test.rb
@@ -1,5 +1,6 @@
-# frozen_string_literal: false
-require_relative 'test_helper'
+# encoding: utf-8
+#frozen_string_literal: false
+require 'test_helper'
class JSONEncodingTest < Test::Unit::TestCase
include JSON
@@ -85,7 +86,9 @@ class JSONEncodingTest < Test::Unit::TestCase
def test_chars
(0..0x7f).each do |i|
json = '["\u%04x"]' % i
- i = i.chr
+ if RUBY_VERSION >= "1.9."
+ i = i.chr
+ end
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 f49f88b596..c5a030ea8a 100644
--- a/test/json/json_ext_parser_test.rb
+++ b/test/json/json_ext_parser_test.rb
@@ -1,10 +1,8 @@
#frozen_string_literal: false
-require_relative 'test_helper'
+require '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
@@ -13,22 +11,5 @@ 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 acc8749965..845abb4867 100644
--- a/test/json/json_fixtures_test.rb
+++ b/test/json/json_fixtures_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require_relative 'test_helper'
+require '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 526bb8c1fe..f31b6b290e 100755..100644
--- a/test/json/json_generator_test.rb
+++ b/test/json/json_generator_test.rb
@@ -1,7 +1,8 @@
#!/usr/bin/env ruby
+# encoding: utf-8
# frozen_string_literal: false
-require_relative 'test_helper'
+require 'test_helper'
class JSONGeneratorTest < Test::Unit::TestCase
include JSON
@@ -61,14 +62,6 @@ 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)
@@ -156,8 +149,7 @@ EOT
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
- :script_safe => false,
- :strict => false,
+ :escape_slash => false,
:indent => " ",
:max_nesting => 100,
:object_nl => "\n",
@@ -174,8 +166,7 @@ EOT
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
- :script_safe => false,
- :strict => false,
+ :escape_slash => false,
:indent => "",
:max_nesting => 100,
:object_nl => "",
@@ -192,8 +183,7 @@ EOT
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
- :script_safe => false,
- :strict => false,
+ :escape_slash => false,
:indent => "",
:max_nesting => 0,
:object_nl => "",
@@ -243,7 +233,7 @@ EOT
def test_gc
if respond_to?(:assert_in_out_err) && !(RUBY_PLATFORM =~ /java/)
- assert_in_out_err(%w[-rjson], <<-EOS, [], [])
+ assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], [])
bignum_too_long_to_embed_as_string = 1234567890123456789012345
expect = bignum_too_long_to_embed_as_string.to_s
GC.stress = true
@@ -346,13 +336,7 @@ EOT
def test_json_generate
assert_raise JSON::GeneratorError do
- generate(["\xea"])
- end
- end
-
- def test_json_generate_unsupported_types
- assert_raise JSON::GeneratorError do
- generate(Object.new, strict: true)
+ assert_equal true, generate(["\xea"])
end
end
@@ -386,18 +370,6 @@ 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 = ['"']
@@ -419,31 +391,6 @@ 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 c4d391208c..82742dcd63 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_relative 'test_helper'
+require 'test_helper'
class JSONGenericObjectTest < Test::Unit::TestCase
include JSON
diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb
index cc9a74a95b..146ff7c047 100644
--- a/test/json/json_parser_test.rb
+++ b/test/json/json_parser_test.rb
@@ -1,13 +1,10 @@
# encoding: utf-8
# frozen_string_literal: false
-require_relative 'test_helper'
+require 'test_helper'
require 'stringio'
require 'tempfile'
require 'ostruct'
-begin
- require 'bigdecimal'
-rescue LoadError
-end
+require 'bigdecimal'
class JSONParserTest < Test::Unit::TestCase
include JSON
@@ -24,9 +21,6 @@ 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) {
@@ -119,7 +113,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 if defined?(::BigDecimal)
+ end
def test_parse_string_mixed_unicode
assert_equal(["éé"], JSON.parse("[\"\\u00e9é\"]"))
diff --git a/test/json/json_string_matching_test.rb b/test/json/json_string_matching_test.rb
index b9cf904aaa..5d55dc31b0 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_relative 'test_helper'
+require 'test_helper'
require 'time'
class JSONStringMatchingTest < Test::Unit::TestCase
diff --git a/test/json/ractor_test.rb b/test/json/ractor_test.rb
index ba9bf7a7f6..71105e55ec 100644
--- a/test/json/ractor_test.rb
+++ b/test/json/ractor_test.rb
@@ -1,11 +1,7 @@
+# encoding: utf-8
# frozen_string_literal: false
-require_relative 'test_helper'
-
-begin
- require_relative './lib/helper'
-rescue LoadError
-end
+require 'test_helper'
class JSONInRactorTest < Test::Unit::TestCase
def test_generate
diff --git a/test/lib/!Nothing_to_test.rb b/test/lib/!Nothing_to_test.rb
deleted file mode 100644
index c1f4c439d3..0000000000
--- a/test/lib/!Nothing_to_test.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-### 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 cf3baaaeb7..812c13b925 100644
--- a/test/lib/jit_support.rb
+++ b/test/lib/jit_support.rb
@@ -1,7 +1,72 @@
require 'rbconfig'
module JITSupport
+ JIT_TIMEOUT = 600 # 10min for each...
+ JIT_SUCCESS_PREFIX = 'JIT success'
+ 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],
+ ]
+ UNSUPPORTED_ARCHITECTURES = [
+ 's390x',
+ 'sparc',
+ ]
+ # 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, call_threshold: 5, save_temps: false, max_cache: 1000, wait: true, timeout: JIT_TIMEOUT)
+ args = [
+ '--disable-gems', "--mjit-verbose=#{verbose}",
+ "--mjit-call-threshold=#{call_threshold}", "--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
+
+ # For MJIT
+ def supported?
+ return @supported if defined?(@supported)
+ @supported = RbConfig::CONFIG["MJIT_SUPPORT"] != 'no' &&
+ UNSUPPORTED_COMPILERS.all? { |regexp| !regexp.match?(RbConfig::CONFIG['MJIT_CC']) } &&
+ !PENDING_RUBYCI_NICKNAMES.include?(ENV['RUBYCI_NICKNAME']) &&
+ !UNSUPPORTED_ARCHITECTURES.include?(RUBY_PLATFORM.split('-', 2).first)
+ end
def yjit_supported?
return @yjit_supported if defined?(@yjit_supported)
@@ -9,25 +74,25 @@ module JITSupport
@yjit_supported = ![nil, 'no'].include?(RbConfig::CONFIG['YJIT_SUPPORT'])
end
- def yjit_enabled?
- defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
- end
-
- def yjit_force_enabled?
- "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?YJIT_FORCE_ENABLE\b/)
+ 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
end
- def rjit_supported?
- return @rjit_supported if defined?(@rjit_supported)
- # nil in mswin
- @rjit_supported = ![nil, 'no'].include?(RbConfig::CONFIG['RJIT_SUPPORT'])
+ def code_block(code)
+ %Q["""\n#{code}\n"""\n\n]
end
- def rjit_enabled?
- defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ # 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")
end
- def rjit_force_enabled?
- "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?RJIT_FORCE_ENABLE\b/)
+ def mjit_force_enabled?
+ "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?MJIT_FORCE_ENABLE\b/)
end
end
diff --git a/test/logger/test_severity.rb b/test/logger/test_severity.rb
index e1069c8262..dad63472a6 100644
--- a/test/logger/test_severity.rb
+++ b/test/logger/test_severity.rb
@@ -3,8 +3,6 @@
require 'logger'
class TestLoggerSeverity < Test::Unit::TestCase
- include Logger::Severity
-
def test_enum
logger_levels = Logger.constants
levels = ["WARN", "UNKNOWN", "INFO", "FATAL", "DEBUG", "ERROR"]
@@ -25,34 +23,4 @@ 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 7df07c16a6..ec42bca100 100644
--- a/test/mkmf/base.rb
+++ b/test/mkmf/base.rb
@@ -147,10 +147,7 @@ class TestMkmf < Test::Unit::TestCase
include Base
- 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)
+ def assert_separately(args, src, *rest, **options)
+ super(args + ["-r#{__FILE__}"], "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 7211c61d53..93ebe3a4ea 100644
--- a/test/mkmf/test_config.rb
+++ b/test/mkmf/test_config.rb
@@ -1,30 +1,15 @@
# frozen_string_literal: false
-require_relative 'base'
+$extmk = true
-class TestMkmfConfig < TestMkmf
+require 'test/unit'
+require 'mkmf'
+
+class TestMkmfConfig < Test::Unit::TestCase
def test_dir_config
bug8074 = '[Bug #8074]'
lib = RbConfig.expand(RbConfig::MAKEFILE_CONFIG["libdir"], "exec_prefix"=>"/test/foo")
- assert_separately([], %w[--with-foo-dir=/test/foo], <<-"end;")
+ assert_separately %w[-rmkmf - -- --with-foo-dir=/test/foo], %{
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
end
diff --git a/test/mkmf/test_configuration.rb b/test/mkmf/test_configuration.rb
deleted file mode 100644
index 0261f78a01..0000000000
--- a/test/mkmf/test_configuration.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# 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_flags.rb b/test/mkmf/test_flags.rb
index 6fde46adec..aedf06b610 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/monitor/test_monitor.rb b/test/monitor/test_monitor.rb
index 4c55afca6c..8ff6d006df 100644
--- a/test/monitor/test_monitor.rb
+++ b/test/monitor/test_monitor.rb
@@ -300,8 +300,6 @@ 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/http/test_http.rb b/test/net/http/test_http.rb
index 53092ee0e8..eb7d3e672c 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -549,7 +549,7 @@ module TestNetHTTP_version_1_1_methods
conn = Net::HTTP.new('localhost', port)
conn.write_timeout = EnvUtil.apply_timeout_scale(0.01)
conn.read_timeout = EnvUtil.apply_timeout_scale(0.01) if windows?
- conn.open_timeout = EnvUtil.apply_timeout_scale(0.1)
+ conn.open_timeout = EnvUtil.apply_timeout_scale(1)
th = Thread.new do
err = !windows? ? Net::WriteTimeout : Net::ReadTimeout
@@ -573,9 +573,9 @@ module TestNetHTTP_version_1_1_methods
port = server.addr[1]
conn = Net::HTTP.new('localhost', port)
- conn.write_timeout = 0.01
- conn.read_timeout = 0.01 if windows?
- conn.open_timeout = 0.1
+ conn.write_timeout = EnvUtil.apply_timeout_scale(0.01)
+ conn.read_timeout = EnvUtil.apply_timeout_scale(0.01) if windows?
+ conn.open_timeout = EnvUtil.apply_timeout_scale(1)
req = Net::HTTP::Post.new('/')
data = "a"*50_000_000
@@ -1249,7 +1249,7 @@ end
class TestNetHTTPLocalBind < Test::Unit::TestCase
CONFIG = {
- 'host' => 'localhost',
+ 'host' => '127.0.0.1',
'proxy_host' => nil,
'proxy_port' => nil,
}
@@ -1286,7 +1286,7 @@ end
class TestNetHTTPForceEncoding < Test::Unit::TestCase
CONFIG = {
- 'host' => 'localhost',
+ 'host' => '127.0.0.1',
'proxy_host' => nil,
'proxy_port' => nil,
}
diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb
index cf297f3755..6ce43b03d5 100644
--- a/test/net/http/test_https.rb
+++ b/test/net/http/test_https.rb
@@ -23,7 +23,7 @@ class TestNetHTTPS < Test::Unit::TestCase
TEST_STORE = OpenSSL::X509::Store.new.tap {|s| s.add_cert(CA_CERT) }
CONFIG = {
- 'host' => HOST,
+ 'host' => HOST_IP,
'proxy_host' => nil,
'proxy_port' => nil,
'ssl_enable' => true,
@@ -167,23 +167,21 @@ 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.')
- omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 3.3.')
http = Net::HTTP.new(HOST, config("port"))
http.use_ssl = true
http.cert_store = TEST_STORE
- http.ssl_timeout = -1
+ http.ssl_timeout = 1
http.start
http.get("/")
http.finish
-
+ sleep 1.25
http.start
http.get("/")
socket = http.instance_variable_get(:@socket).io
- assert_equal false, socket.session_reused?, "NOTE: OpenSSL library version is #{OpenSSL::OPENSSL_LIBRARY_VERSION}"
+ assert_equal false, socket.session_reused?
http.finish
end
diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index 4e09fe1af7..7556fca530 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -141,7 +141,6 @@ 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;
@@ -218,21 +217,6 @@ class TestObjSpace < Test::Unit::TestCase
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
@@ -289,27 +273,19 @@ 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"
-
+ def test_dump_too_complex_shape
+ if defined?(RubyVM::Shape)
RubyVM::Shape::SHAPE_MAX_VARIATIONS.times do
- TooComplex.new.instance_variable_set(:"@a#{_1}", 1)
+ Object.new.instance_variable_set(:"@a#{_1}", 1)
end
- tc = TooComplex.new
- info = ObjectSpace.dump(tc)
- assert_not_match(/"too_complex_shape"/, info)
+ tc = Object.new
tc.instance_variable_set(:@new_ivar, 1)
info = ObjectSpace.dump(tc)
assert_match(/"too_complex_shape":true/, info)
@@ -389,22 +365,6 @@ 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"')
@@ -563,30 +523,9 @@ class TestObjSpace < Test::Unit::TestCase
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::UTF_16BE)
+ unknown = "TEST STRING".dup.force_encoding(Encoding::BINARY)
2.times do # ensure that dumping the string doesn't mutate it
assert_includes ObjectSpace.dump(unknown), '"coderange":"unknown"'
end
@@ -648,26 +587,9 @@ 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(/TEST2/)
+ assert_equal(2, test_string_in_dump_all.size, "number of strings")
- 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)
-
- entry_hash = JSON.parse(strs[0])
+ entry_hash = JSON.parse(test_string_in_dump_all[1])
assert_equal(5, entry_hash["bytesize"], "bytesize is wrong")
assert_equal("TEST2", entry_hash["value"], "value is wrong")
diff --git a/test/open-uri/test_open-uri.rb b/test/open-uri/test_open-uri.rb
index 30e3b5c9c1..fdd1969666 100644
--- a/test/open-uri/test_open-uri.rb
+++ b/test/open-uri/test_open-uri.rb
@@ -172,19 +172,6 @@ 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" } )
@@ -558,25 +545,6 @@ 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
diff --git a/test/openssl/fixtures/pkey/dh1024.pem b/test/openssl/fixtures/pkey/dh1024.pem
new file mode 100644
index 0000000000..f99c757f21
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dh1024.pem
@@ -0,0 +1,5 @@
+-----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
deleted file mode 100644
index 9b182b7201..0000000000
--- a/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem
+++ /dev/null
@@ -1,8 +0,0 @@
------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/test_bn.rb b/test/openssl/test_bn.rb
index ea88ff06ce..77af14091e 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -175,9 +175,7 @@ class OpenSSL::TestBN < OpenSSL::TestCase
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(3, 4.to_bn.mod_sqrt(5))
assert_equal(0, 5.to_bn.mod_sqrt(5))
assert_raise(OpenSSL::BNError) { 3.to_bn.mod_sqrt(5) }
end
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index 8faa570648..1c8610b2a9 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -205,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?(1, 1, 1, 0x03, 0xf) # version >= 1.1.1c
+ OpenSSL::OPENSSL_VERSION_NUMBER >= 0x1010103f # 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 6dbb9c6138..24a215a486 100644
--- a/test/openssl/test_config.rb
+++ b/test/openssl/test_config.rb
@@ -91,19 +91,22 @@ __EOC__
assert_equal('123baz456bar798', c['dollar']['qux'])
assert_equal('123baz456bar798.123baz456bar798', c['dollar']['quxx'])
- assert_raise_with_message(OpenSSL::ConfigError, /error in line 1: variable has no value/) do
+ excn = assert_raise(OpenSSL::ConfigError) do
OpenSSL::Config.parse("foo = $bar")
end
+ assert_equal("error in line 1: variable has no value", excn.message)
- assert_raise_with_message(OpenSSL::ConfigError, /error in line 1: no close brace/) do
+ excn = assert_raise(OpenSSL::ConfigError) do
OpenSSL::Config.parse("foo = $(bar")
end
+ assert_equal("error in line 1: no close brace", excn.message)
- assert_raise_with_message(OpenSSL::ConfigError, /error in line 1: missing equal sign/) do
+ excn = assert_raise(OpenSSL::ConfigError) do
OpenSSL::Config.parse("f o =b ar # no space in key")
end
+ assert_equal("error in line 1: missing equal sign", excn.message)
- assert_raise_with_message(OpenSSL::ConfigError, /error in line 7: missing close square bracket/) do
+ excn = assert_raise(OpenSSL::ConfigError) do
OpenSSL::Config.parse(<<__EOC__)
# comment 1 # comments
@@ -114,6 +117,7 @@ __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 b0b5b9bed1..84c128c12f 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.unpack1("H*")
+ str.unpack("H*").first
end
def test_sha2
diff --git a/test/openssl/test_engine.rb b/test/openssl/test_engine.rb
index b6025f915b..1ede6ed086 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 = OpenSSL::Engine.by_id("openssl")
+ engine = get_engine
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 = OpenSSL::Engine.by_id("openssl")
+ engine = get_engine
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 = OpenSSL::Engine.by_id("openssl")
+ engine = get_engine
digest = engine.digest("SHA1")
assert_not_nil(digest)
data = "test"
@@ -59,21 +59,12 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
end
with_openssl(<<-'end;', ignore_stderr: true)
- engine = OpenSSL::Engine.by_id("openssl")
+ engine = get_engine
algo = "RC4"
data = "a" * 1000
key = OpenSSL::Random.random_bytes(16)
-
- 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
-
+ encrypted = crypt_data(data, key, :encrypt) { engine.cipher(algo) }
+ decrypted = crypt_data(encrypted, key, :decrypt) { OpenSSL::Cipher.new(algo) }
assert_equal(data, decrypted)
end;
end
@@ -82,10 +73,25 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
# this is required because OpenSSL::Engine methods change global state
def with_openssl(code, **opts)
- assert_separately(["-ropenssl"], <<~"end;", **opts)
+ assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;", **opts)
+ require #{__FILE__.dump}
+ include OpenSSL::TestEngine::Utils
#{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 4a3dd43a41..8cd474f9a3 100644
--- a/test/openssl/test_fips.rb
+++ b/test/openssl/test_fips.rb
@@ -4,46 +4,22 @@ 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
- assert_separately(["-ropenssl"], <<~"end;")
- OpenSSL.fips_mode = false
- OpenSSL.fips_mode = false
- end;
+ OpenSSL.fips_mode = false
+ OpenSSL.fips_mode = false
end
- def test_fips_mode_get_with_fips_mode_set
- omit('OpenSSL is not FIPS-capable') unless OpenSSL::OPENSSL_FIPS
+ def test_fips_mode_get
+ return unless OpenSSL::OPENSSL_FIPS
+ assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;")
+ require #{__FILE__.dump}
- assert_separately(["-ropenssl"], <<~"end;")
begin
OpenSSL.fips_mode = true
- assert OpenSSL.fips_mode == true, ".fips_mode should return true when .fips_mode=true"
+ assert OpenSSL.fips_mode == true, ".fips_mode returns true when .fips_mode=true"
OpenSSL.fips_mode = false
- assert OpenSSL.fips_mode == false, ".fips_mode should return false when .fips_mode=false"
+ assert OpenSSL.fips_mode == false, ".fips_mode returns false when .fips_mode=false"
rescue OpenSSL::OpenSSLError
pend "Could not set FIPS mode (OpenSSL::OpenSSLError: \#$!); skipping"
end
diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb
index d76fc9e5cf..383931b98b 100644
--- a/test/openssl/test_ns_spki.rb
+++ b/test/openssl/test_ns_spki.rb
@@ -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.unpack1("m"), spki.to_der)
+ assert_equal(@b64.unpack("m").first, spki.to_der)
assert_equal("MozillaIsMyFriend", spki.challenge)
assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)
- spki = OpenSSL::Netscape::SPKI.new(@b64.unpack1("m"))
+ spki = OpenSSL::Netscape::SPKI.new(@b64.unpack("m").first)
assert_equal(@b64, spki.to_pem)
- assert_equal(@b64.unpack1("m"), spki.to_der)
+ assert_equal(@b64.unpack("m").first, spki.to_der)
assert_equal("MozillaIsMyFriend", spki.challenge)
assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)
end
diff --git a/test/openssl/test_ossl.rb b/test/openssl/test_ossl.rb
index 979669a003..e1d86bd40b 100644
--- a/test/openssl/test_ossl.rb
+++ b/test/openssl/test_ossl.rb
@@ -60,19 +60,6 @@ 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_pkcs12.rb b/test/openssl/test_pkcs12.rb
index e6b91b52af..ec676743bc 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.unpack1("m")
+ str = <<~EOF.unpack("m").first
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.unpack1("m")
+ str = <<~EOF.unpack("m").first
MIIJ7wIBAzCCCbUGCSqGSIb3DQEHAaCCCaYEggmiMIIJnjCCCZoGCSqGSIb3
DQEHAaCCCYsEggmHMIIJgzCCCX8GCyqGSIb3DQEMCgECoIIJbjCCCWowHAYK
KoZIhvcNAQwBAzAOBAjX5nN8jyRKwQICCAAEgglIBIRLHfiY1mNHpl3FdX6+
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb
index aee0546f63..1219f3f1d7 100644
--- a/test/openssl/test_pkey.rb
+++ b/test/openssl/test_pkey.rb
@@ -40,11 +40,6 @@ 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|
@@ -52,6 +47,11 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
raise "exit!" if cb_called.size == 3
}
}
+ if !cb_called && openssl?(3, 0, 0) && !openssl?(3, 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
assert_not_empty cb_called
end
@@ -82,9 +82,6 @@ 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-----
@@ -99,11 +96,9 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
begin
priv = OpenSSL::PKey.read(priv_pem)
pub = OpenSSL::PKey.read(pub_pem)
- rescue OpenSSL::PKey::PKeyError => e
+ rescue OpenSSL::PKey::PKeyError
# OpenSSL < 1.1.1
- pend "Ed25519 is not implemented" unless openssl?(1, 1, 1)
-
- raise e
+ pend "Ed25519 is not implemented"
end
assert_instance_of OpenSSL::PKey::PKey, priv
assert_instance_of OpenSSL::PKey::PKey, pub
@@ -111,19 +106,6 @@ 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
@@ -144,32 +126,6 @@ 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
@@ -194,32 +150,6 @@ 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 d32ffaf6b1..161af1897b 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -18,26 +18,15 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
assert_key(dh)
end if ENV["OSSL_TEST_ALL"]
- def test_new_break_on_non_fips
- omit_on_fips
-
+ def test_new_break
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("dh2048_ffdhe2048")
+ params = Fixtures.pkey("dh1024")
dh1 = OpenSSL::PKey.generate_key(params)
dh2 = OpenSSL::PKey.generate_key(params)
dh1_pub = OpenSSL::PKey.read(dh1.public_to_der)
@@ -55,38 +44,34 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_DHparams
- dh = Fixtures.pkey("dh2048_ffdhe2048")
- dh_params = dh.public_key
+ dh1024 = Fixtures.pkey("dh1024")
+ dh1024params = dh1024.public_key
asn1 = OpenSSL::ASN1::Sequence([
- OpenSSL::ASN1::Integer(dh.p),
- OpenSSL::ASN1::Integer(dh.g)
+ OpenSSL::ASN1::Integer(dh1024.p),
+ OpenSSL::ASN1::Integer(dh1024.g)
])
key = OpenSSL::PKey::DH.new(asn1.to_der)
- assert_same_dh dh_params, key
+ assert_same_dh dh1024params, key
pem = <<~EOF
-----BEGIN DH PARAMETERS-----
- MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
- +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
- 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
- YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
- 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
- ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
+ MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
+ pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
+ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
-----END DH PARAMETERS-----
EOF
-
key = OpenSSL::PKey::DH.new(pem)
- assert_same_dh dh_params, key
+ assert_same_dh dh1024params, key
key = OpenSSL::PKey.read(pem)
- assert_same_dh dh_params, key
+ assert_same_dh dh1024params, key
- assert_equal asn1.to_der, dh.to_der
- assert_equal pem, dh.export
+ assert_equal asn1.to_der, dh1024.to_der
+ assert_equal pem, dh1024.export
end
def test_public_key
- dh = Fixtures.pkey("dh2048_ffdhe2048")
+ dh = Fixtures.pkey("dh1024")
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)
@@ -95,8 +80,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
def test_generate_key
# Deprecated in v3.0.0; incompatible with OpenSSL 3.0
- # Creates a copy with params only
- dh = Fixtures.pkey("dh2048_ffdhe2048").public_key
+ dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only
assert_no_key(dh)
dh.generate_key!
assert_key(dh)
@@ -107,15 +91,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end if !openssl?(3, 0, 0)
def test_params_ok?
- # 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")
+ dh0 = Fixtures.pkey("dh1024")
dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(dh0.p),
@@ -132,7 +108,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
def test_dup
# Parameters only
- dh1 = Fixtures.pkey("dh2048_ffdhe2048")
+ dh1 = Fixtures.pkey("dh1024")
dh2 = dh1.dup
assert_equal dh1.to_der, dh2.to_der
assert_not_equal nil, dh1.p
@@ -149,7 +125,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
# With a key pair
- dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh2048_ffdhe2048"))
+ dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024"))
dh4 = dh3.dup
assert_equal dh3.to_der, dh4.to_der
assert_equal dh1.to_der, dh4.to_der # encodes parameters only
@@ -160,7 +136,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_marshal
- dh = Fixtures.pkey("dh2048_ffdhe2048")
+ dh = Fixtures.pkey("dh1024")
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 3f64a80e32..d1059093c5 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -58,7 +58,7 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
signature = dsa512.sign("SHA256", data)
assert_equal true, dsa512.verify("SHA256", signature, data)
- signature0 = (<<~'end;').unpack1("m")
+ signature0 = (<<~'end;').unpack("m")[0]
MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/
6g==
end;
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index 2cb8e287ab..e5fef940a6 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -5,6 +5,20 @@ 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
@@ -35,17 +49,6 @@ 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")
@@ -107,7 +110,7 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
signature = p256.sign("SHA256", data)
assert_equal true, p256.verify("SHA256", signature, data)
- signature0 = (<<~'end;').unpack1("m")
+ signature0 = (<<~'end;').unpack("m")[0]
MEQCIEOTY/hD7eI8a0qlzxkIt8LLZ8uwiaSfVbjX2dPAvN11AiAQdCYx56Fq
QdBp1B4sxJoA8jvODMMklMyBKVmudboA6A==
end;
@@ -229,8 +232,6 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
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 61c55c60b2..b0ae5784b3 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -83,7 +83,7 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
signature = rsa1024.sign("SHA256", data)
assert_equal true, rsa1024.verify("SHA256", signature, data)
- signature0 = (<<~'end;').unpack1("m")
+ signature0 = (<<~'end;').unpack("m")[0]
oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+
WA6YQo8jPH4hSuyWIM4Gz4qRYiYRkl5TDMUYob94zm8Si1HxEiS9354tzvqS
zS8MLW2BtNPuTubMxTItHGTnOzo9sUg0LAHVFt8kHG2NfKAw/gQ=
diff --git a/test/openssl/test_provider.rb b/test/openssl/test_provider.rb
deleted file mode 100644
index 7361a0e250..0000000000
--- a/test/openssl/test_provider.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# 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
- omit 'not working on freebsd RubyCI' if ENV['RUBYCI_NICKNAME'] =~ /freebsd/
- with_openssl <<-'end;'
- legacy_provider = OpenSSL::Provider.load("legacy")
- assert_equal(2, OpenSSL::Provider.provider_names.size)
- assert_includes(OpenSSL::Provider.provider_names, "legacy")
-
- assert_equal(true, legacy_provider.unload)
- assert_equal(1, OpenSSL::Provider.provider_names.size)
- assert_not_includes(OpenSSL::Provider.provider_names, "legacy")
- 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
- omit 'not working on freebsd RubyCI' if ENV['RUBYCI_NICKNAME'] =~ /freebsd/
- with_openssl(<<-'end;')
- OpenSSL::Provider.load("legacy")
- 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 07dc9a343c..db76f1dc4c 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -481,40 +481,6 @@ 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
@@ -1080,9 +1046,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
start_server(ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params
- # OpenSSL <= 1.1.0: "self signed certificate in certificate chain"
- # OpenSSL >= 3.0.0: "self-signed certificate in certificate chain"
- assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) {
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /certificate/) {
server_connect(port, ctx)
}
}
diff --git a/test/openssl/test_ssl_session.rb b/test/openssl/test_ssl_session.rb
index 89cf672a7b..b243201e18 100644
--- a/test/openssl/test_ssl_session.rb
+++ b/test/openssl/test_ssl_session.rb
@@ -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.unpack1('m'))
+ assert_equal(session.to_der, pem.unpack('m*')[0])
assert_not_nil(session.to_text)
}
end
diff --git a/test/openssl/test_x509ext.rb b/test/openssl/test_x509ext.rb
index 59a41ed736..7ad010d1ed 100644
--- a/test/openssl/test_x509ext.rb
+++ b/test/openssl/test_x509ext.rb
@@ -50,41 +50,24 @@ class OpenSSL::TestX509Extension < OpenSSL::TestCase
cdp = ef.create_extension("crlDistributionPoints", "@crlDistPts")
assert_equal(false, cdp.critical?)
assert_equal("crlDistributionPoints", cdp.oid)
- assert_include(cdp.value, "URI:http://www.example.com/crl")
- assert_include(cdp.value,
- "URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary")
+ assert_match(%{URI:http://www\.example\.com/crl}, cdp.value)
+ assert_match(
+ %r{URI:ldap://ldap\.example\.com/cn=ca\?certificateRevocationList;binary},
+ cdp.value)
cdp = ef.create_extension("crlDistributionPoints", "critical, @crlDistPts")
assert_equal(true, cdp.critical?)
assert_equal("crlDistributionPoints", cdp.oid)
- assert_include(cdp.value, "URI:http://www.example.com/crl")
- assert_include(cdp.value,
- "URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary")
+ assert_match(%{URI:http://www.example.com/crl}, cdp.value)
+ assert_match(
+ %r{URI:ldap://ldap.example.com/cn=ca\?certificateRevocationList;binary},
+ cdp.value)
cp = ef.create_extension("certificatePolicies", "@certPolicies")
assert_equal(false, cp.critical?)
assert_equal("certificatePolicies", cp.oid)
- 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)
+ assert_match(%r{2.23.140.1.2.1}, cp.value)
+ assert_match(%r{http://cps.example.com}, cp.value)
end
def test_dup
diff --git a/test/openssl/test_x509req.rb b/test/openssl/test_x509req.rb
index ff17c41163..b98754b8c8 100644
--- a/test/openssl/test_x509req.rb
+++ b/test/openssl/test_x509req.rb
@@ -39,11 +39,6 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
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('SHA256'))
- assert_equal(1, req.version)
- req = OpenSSL::X509::Request.new(req.to_der)
- assert_equal(1, req.version)
end
def test_subject
@@ -106,7 +101,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
assert_equal(false, req.verify(@rsa2048))
assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
- req.version = 1
+ req.subject = OpenSSL::X509::Name.parse("/C=JP/CN=FooBarFooBar")
assert_equal(false, req.verify(@rsa1024))
rescue OpenSSL::X509::RequestError # RHEL 9 disables SHA1
end
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index f6c84eef67..4ebcb9837b 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -1,13 +1,38 @@
# 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)
@@ -106,12 +131,11 @@ module OpenSSL::TestUtils
end
end
- def openssl?(major = nil, minor = nil, fix = nil, patch = 0, status = 0)
+ def openssl?(major = nil, minor = nil, fix = nil, patch = 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 +
- status * 0x1
+ major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10
end
def libressl?(major = nil, minor = nil, fix = nil)
@@ -124,7 +148,6 @@ 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"
@@ -139,30 +162,6 @@ 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_getopts.rb b/test/optparse/test_getopts.rb
index 4a0ae284e7..7d9160f7af 100644
--- a/test/optparse/test_getopts.rb
+++ b/test/optparse/test_getopts.rb
@@ -11,39 +11,23 @@ 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/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb
index 19bb606145..256db7a0c7 100644
--- a/test/ostruct/test_ostruct.rb
+++ b/test/ostruct/test_ostruct.rb
@@ -412,23 +412,4 @@ 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
deleted file mode 100644
index bd83d72da3..0000000000
--- a/test/prism/attribute_write_test.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# 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
deleted file mode 100644
index 1525caf458..0000000000
--- a/test/prism/bom_test.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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/comments_test.rb b/test/prism/comments_test.rb
deleted file mode 100644
index b99c00268c..0000000000
--- a/test/prism/comments_test.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# 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
deleted file mode 100644
index ed028d03d8..0000000000
--- a/test/prism/compiler_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-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
deleted file mode 100644
index 9842be0c49..0000000000
--- a/test/prism/constant_path_node_test.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# 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
- end
-end
diff --git a/test/prism/desugar_compiler_test.rb b/test/prism/desugar_compiler_test.rb
deleted file mode 100644
index c72e141c6b..0000000000
--- a/test/prism/desugar_compiler_test.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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).
- class EnsureEveryNodeOnceInAST < Visitor
- def initialize
- @all_nodes = {}.compare_by_identity
- end
-
- def visit(node)
- if node
- 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
- end
- super(node)
- end
- end
-
- def assert_desugars(expected, source)
- ast = Prism.parse(source).value.accept(DesugarCompiler.new)
- assert_equal expected, ast_inspect(ast.statements.body.last)
-
- ast.accept(EnsureEveryNodeOnceInAST.new)
- 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
deleted file mode 100644
index 0d8a6d35e9..0000000000
--- a/test/prism/dispatcher_test.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# 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
deleted file mode 100644
index e4678c6f82..0000000000
--- a/test/prism/encoding_test.rb
+++ /dev/null
@@ -1,349 +0,0 @@
-# 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,
- Encoding::Windows_1253 => codepoints_1byte
- }
-
- # 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.each do |name|
- next if name == "locale"
-
- 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))
-
- encodings.each_key do |encoding|
- define_method(:"test_encoding_flags_#{encoding.name}") do
- assert_encoding_flags(encoding, escapes)
- 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
-
- # 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_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
-
- 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
-
- 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?
- 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
- end
-end
diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb
deleted file mode 100644
index 51ac7bc5cf..0000000000
--- a/test/prism/errors_test.rb
+++ /dev/null
@@ -1,2062 +0,0 @@
-# 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",
- "expected a newline or semicolon after the statement"
- ]
- 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", [
- ["expected a constant name after `module`", 20..20]
- ]
- 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", 11..11]
- ]
- end
-
- def test_unterminated_embdoc
- assert_errors expression("1"), "1\n=begin\n", [
- ["could not find a terminator for the embedded document", 2..9]
- ]
- 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', [
- ["expected a closing delimiter for the string literal", 6..6]
- ]
- assert_equal expr.unescaped, "hello"
- assert_equal expr.closing, ""
- end
-
- def test_unterminated_string
- expr = expression("'hello")
- assert_errors expr, "'hello", [
- ["expected a closing delimiter for the string literal", 0..1]
- ]
- assert_equal expr.unescaped, "hello"
- assert_equal expr.closing, ""
- end
-
- def test_unterminated_empty_string
- expr = expression('"')
- assert_errors expr, '"', [
- ["expected a closing delimiter for the string literal", 1..1]
- ]
- assert_equal expr.unescaped, ""
- assert_equal expr.closing, ""
- end
-
- def test_incomplete_instance_var_string
- assert_errors expression('%@#@@#'), '%@#@@#', [
- ["incomplete instance variable", 4..5],
- ["expected a newline or semicolon after the statement", 4..4]
- ]
- 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', [
- ["expected a newline or semicolon after the statement", 6..6],
- ["cannot parse the expression", 6..6],
- ["expected a matching `)`", 6..6]
- ]
- end
-
- def test_missing_terminator_in_parentheses
- assert_error_messages "(0 0)", [
- "expected a newline or semicolon after the statement"
- ]
- end
-
- def test_unterminated_argument_expression
- assert_errors expression('a %'), 'a %', [
- ["invalid `%` token", 2..3],
- ["expected an expression after the operator", 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)", [
- ["expected a newline or semicolon after the statement", 2..2],
- ["cannot parse the expression", 2..2],
- ["expected a matching `)`", 2..2],
- ["expected a newline or semicolon after the statement", 2..2],
- ["cannot parse the expression", 2..2],
- ["expected a newline or semicolon after the statement", 5..5],
- ["cannot parse the expression", 5..5],
- ["expected a newline or semicolon after the statement", 8..8],
- ["cannot parse the expression", 8..8]
- ]
- end
-
- def test_return_1_2_3
- assert_error_messages "return(1, 2, 3)", [
- "expected a newline or semicolon after the statement",
- "cannot parse the expression",
- "expected a matching `)`",
- "expected a newline or semicolon after the statement",
- "cannot parse the expression"
- ]
- end
-
- def test_return_1
- assert_errors expression("return 1,;"), "return 1,;", [
- ["expected an argument", 9..9]
- ]
- end
-
- def test_next_1_2_3
- assert_errors expression("next(1, 2, 3)"), "next(1, 2, 3)", [
- ["expected a newline or semicolon after the statement", 6..6],
- ["cannot parse the expression", 6..6],
- ["expected a matching `)`", 6..6],
- ["expected a newline or semicolon after the statement", 12..12],
- ["cannot parse the expression", 12..12]
- ]
- end
-
- def test_next_1
- assert_errors expression("next 1,;"), "next 1,;", [
- ["expected an argument", 7..7]
- ]
- end
-
- def test_break_1_2_3
- assert_errors expression("break(1, 2, 3)"), "break(1, 2, 3)", [
- ["expected a newline or semicolon after the statement", 7..7],
- ["cannot parse the expression", 7..7],
- ["expected a matching `)`", 7..7],
- ["expected a newline or semicolon after the statement", 13..13],
- ["cannot parse the expression", 13..13]
- ]
- end
-
- def test_break_1
- assert_errors expression("break 1,;"), "break 1,;", [
- ["expected an argument", 8..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",
- "expected a newline or semicolon after the statement"
- ]
- end
-
- def test_top_level_constant_starting_with_downcased_identifier
- assert_error_messages "::foo::A", [
- "expected a constant after the `::` operator",
- "expected a newline or semicolon after the statement"
- ]
- 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`; expected a bare word, symbol, constant, or global variable", 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],
- ["expected a method name", 7..7]
- ]
- 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 `)`", 7..7],
- ["expected a `.` or `::` after the receiver in a method definition", 7..7],
- ["expected a method name", 7..7],
- ["cannot parse the expression", 10..10],
- ["cannot parse the expression", 11..11]
- ]
- end
-
- def test_def_with_empty_expression_receiver
- assert_errors expression("def ().a; end"), "def ().a; end", [
- ["expected a receiver for the method definition", 5..5]
- ]
- end
-
- def test_block_beginning_with_brace_and_ending_with_end
- assert_error_messages "x.each { x end", [
- "expected a newline or semicolon after the statement",
- "cannot parse the expression",
- "cannot parse the expression",
- "expected a block beginning with `{` to end with `}`"
- ]
- end
-
- def test_double_splat_followed_by_splat_argument
- expected = CallNode(
- 0,
- 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(
- 0,
- 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)", [
- "expected a `)` to close the arguments",
- "expected a newline or semicolon after the statement",
- "cannot parse the expression"
- ]
- end
-
- def test_splat_argument_after_keyword_argument
- expected = CallNode(
- 0,
- nil,
- nil,
- :a,
- Location(),
- Location(),
- ArgumentsNode(0, [
- KeywordHashNode(1, [
- AssocNode(
- SymbolNode(0, 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)]),
- [],
- 0,
- Location(),
- nil,
- nil,
- nil,
- nil,
- Location()
- )
-
- assert_errors expected, "def foo;module A;end;end", [
- ["unexpected module definition in a method definition", 8..14]
- ]
- end
-
- def test_module_definition_in_method_body_within_block
- expected = DefNode(
- :foo,
- Location(),
- nil,
- nil,
- StatementsNode(
- [CallNode(
- 0,
- nil,
- nil,
- :bar,
- Location(),
- nil,
- nil,
- nil,
- BlockNode(
- [],
- 0,
- nil,
- StatementsNode([ModuleNode([], Location(), ConstantReadNode(:Foo), nil, Location(), :Foo)]),
- Location(),
- Location()
- )
- )]
- ),
- [],
- 0,
- Location(),
- nil,
- nil,
- nil,
- nil,
- Location()
- )
-
- assert_errors expected, <<~RUBY, [["unexpected module definition in a method definition", 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 a method definition"
- 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
- )]
- ),
- [],
- 0,
- Location(),
- nil,
- nil,
- nil,
- nil,
- Location()
- )
-
- assert_errors expected, "def foo;class A;end;end", [
- ["unexpected class definition in a method definition", 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 a method definition"
- 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(:A),
- RequiredParameterNode(:@a),
- RequiredParameterNode(:$A),
- RequiredParameterNode(:@@a),
- ], [], nil, [], [], nil, nil),
- nil,
- [:A, :@a, :$A, :@@a],
- 4,
- 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
-
- def test_cannot_assign_to_a_reserved_numbered_parameter
- expected = BeginNode(
- Location(),
- StatementsNode([
- LocalVariableWriteNode(:_1, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_2, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_3, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_4, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_5, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_6, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_7, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_8, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_9, 0, Location(), SymbolNode(0, Location(), Location(), nil, "a"), Location()),
- LocalVariableWriteNode(:_10, 0, Location(), SymbolNode(0, 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
-
- def test_do_not_allow_trailing_commas_in_method_parameters
- expected = DefNode(
- :foo,
- Location(),
- nil,
- ParametersNode(
- [RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:c)],
- [],
- nil,
- [],
- [],
- nil,
- nil
- ),
- nil,
- [:a, :b, :c],
- 3,
- 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],
- 2,
- Location(),
- Location(),
- Location(),
- BlockParametersNode(
- ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(: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(:a)],
- [],
- nil,
- BlockParameterNode(:block, Location(), Location())
- ),
- nil,
- [:block, :a],
- 2,
- 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(:a)], [], nil, BlockParameterNode(nil, nil, Location())),
- nil,
- [:&, :a],
- 2,
- 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(:a)],
- [],
- ForwardingParameterNode(),
- nil
- ),
- nil,
- [:"...", :a],
- 2,
- 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(:a)],
- [RequiredKeywordParameterNode(:b, Location())],
- nil,
- nil
- ),
- nil,
- [:b, :a],
- 2,
- 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(:b, Location())],
- KeywordRestParameterNode(:rest, Location(), Location()),
- nil
- ),
- nil,
- [:rest, :b],
- 2,
- 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,
- [:"..."],
- 1,
- 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(:a)],
- [RequiredKeywordParameterNode(:b, Location())],
- KeywordRestParameterNode(:args, Location(), Location()),
- nil
- ),
- nil,
- [:args, :a, :b],
- 3,
- 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(:a)],
- [RequiredKeywordParameterNode(:b, Location())],
- KeywordRestParameterNode(:args, Location(), Location()),
- nil
- ),
- nil,
- [:args, :a, :b],
- 3,
- 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(:a)],
- [RequiredKeywordParameterNode(:b, Location())],
- KeywordRestParameterNode(:args, Location(), Location()),
- nil
- ),
- nil,
- [:args, :a, :b],
- 3,
- 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(:a)],
- [
- OptionalParameterNode(:b, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL)),
- OptionalParameterNode(:d, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL))
- ],
- nil,
- [RequiredParameterNode(:c), RequiredParameterNode(:e)],
- [],
- nil,
- nil
- ),
- nil,
- [:a, :b, :c, :d, :e],
- 5,
- 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(0, 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(0, 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)]),
- [],
- 0,
- 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(
- [],
- 0,
- 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(
- 0,
- nil,
- nil,
- :a,
- Location(),
- nil,
- nil,
- nil,
- BlockNode(
- [],
- 0,
- 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 a class or module body", 15..16]
- ]
- 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 a class or module body", 16..17]
- ]
- 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", [
- ["immutable variable as a write target", 6..8],
- ["immutable variable as a write target", 15..20]
- ]
- end
-
- def test_duplicated_parameter_names
- # For some reason, Ripper reports no error for Ruby 3.0 when you have
- # duplicated parameter names for positional parameters.
- unless RUBY_VERSION < "3.1.0"
- expected = DefNode(
- :foo,
- Location(),
- nil,
- ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], nil, [], [], nil, nil),
- nil,
- [:a, :b],
- 2,
- Location(),
- nil,
- Location(),
- Location(),
- nil,
- Location()
- )
-
- assert_errors expected, "def foo(a,b,a);end", [
- ["repeated parameter name", 12..13]
- ]
- end
-
- expected = DefNode(
- :foo,
- Location(),
- nil,
- ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], RestParameterNode(:a, Location(), Location()), [], [], nil, nil),
- nil,
- [:a, :b],
- 2,
- Location(),
- nil,
- Location(),
- Location(),
- nil,
- Location()
- )
-
- assert_errors expected, "def foo(a,b,*a);end", [
- ["repeated parameter name", 13..14]
- ]
-
- expected = DefNode(
- :foo,
- Location(),
- nil,
- ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], KeywordRestParameterNode(:a, Location(), Location()), nil),
- nil,
- [:a, :b],
- 2,
- Location(),
- nil,
- Location(),
- Location(),
- nil,
- Location()
- )
-
- assert_errors expected, "def foo(a,b,**a);end", [
- ["repeated parameter name", 14..15]
- ]
-
- expected = DefNode(
- :foo,
- Location(),
- nil,
- ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], nil, BlockParameterNode(:a, Location(), Location())),
- nil,
- [:a, :b],
- 2,
- Location(),
- nil,
- Location(),
- Location(),
- nil,
- Location()
- )
-
- assert_errors expected, "def foo(a,b,&a);end", [
- ["repeated parameter name", 13..14]
- ]
-
- expected = DefNode(
- :foo,
- Location(),
- nil,
- ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL))], RestParameterNode(:c, Location(), Location()), [RequiredParameterNode(:b)], [], nil, nil),
- nil,
- [:a, :b, :c],
- 3,
- Location(),
- nil,
- Location(),
- Location(),
- nil,
- Location()
- )
-
- assert_errors expected, "def foo(a = 1,b,*c);end", [["unexpected parameter `*`", 16..17]]
- 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
- assert_errors expression("$"), "$", [
- ["invalid global variable", 0..1]
- ]
- end
-
- def test_invalid_global_variable_write
- assert_errors expression("$',"), "$',", [
- ["immutable variable as a write target", 0..2],
- ["unexpected write target", 0..2]
- ]
- end
-
- def test_invalid_multi_target
- error_messages = ["unexpected write target"]
- immutable = "immutable variable as a 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,", [immutable, *error_messages]
- assert_error_messages "$+,", [immutable, *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
-
- 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
-
- 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, compare_ripper: false
- 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
-
- def test_numbered_parameters_in_block_arguments
- source = "foo { |_1| }"
- assert_errors expression(source), source, [
- ["_1 is reserved for numbered parameters", 7..9],
- ]
- 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, compare_ripper: false
- end
-
- def test_class_name
- source = "class 0.X end"
- assert_errors expression(source), source, [
- ["expected a constant name after `class`", 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],
- ["expected a newline or semicolon after the statement", 7..7],
- ["cannot parse the expression", 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, [
- ["repeated parameter name", 7..8],
- ]
- end
-
- def test_repeated_parameter_name_in_destructured_params
- source = "def f(a, (b, (a))); end"
- # In Ruby 3.0.x, `Ripper.sexp_raw` does not return `nil` for this case.
- compare_ripper = RUBY_ENGINE == "ruby" && (RUBY_VERSION.split('.').map { |x| x.to_i } <=> [3, 1]) >= 1
- assert_errors expression(source), source, [
- ["repeated parameter name", 14..15],
- ], compare_ripper: compare_ripper
- 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, [
- ["expected a closing delimiter for the string literal", 14..14],
- ]
- end
-
- def test_symbol_in_hash
- source = "{x:'y':}"
- assert_errors expression(source), source, [
- ["expected a closing delimiter for the string literal", 7..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],
- ['cannot parse the expression', 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
- message1 = 'expected a newline or semicolon after the statement'
- message2 = 'cannot parse the expression'
- assert_errors expression(source), source, [
- [message1, 6..6],
- [message2, 6..6],
- [message1, 17..17],
- [message2, 17..17],
- ]
- end
-
- def test_rational_number_with_exponential_portion
- source = '1e1r; 1e1ri'
- message = 'expected a newline or semicolon after the statement'
- assert_errors expression(source), source, [
- [message, 3..3],
- [message, 9..9]
- ]
- 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],
- [message, 81..86],
- [message, 97..103],
- [message, 123..129],
- [message, 168..174],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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]
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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]
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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],
- ], compare_ripper: false # Ripper does not check 'void value expression'.
- 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, [
- ['expected a newline or semicolon after the statement', 4..4],
- ['cannot parse the expression', 4..4],
- ]
- end
-
- def test_upcase_end_in_def
- assert_warning_messages "def foo; END { }; end", [
- "END in method; use at_exit"
- ]
- 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
- message1 = 'expected a newline or semicolon after the statement'
- message2 = 'cannot parse the expression'
- assert_errors expression(source), source, [
- [message1, 9..9],
- [message2, 9..9],
- [message1, 23..23],
- [message2, 23..23],
- [message1, 39..39],
- [message2, 39..39],
- [message1, 57..57],
- [message2, 57..57],
- [message1, 71..71],
- [message2, 71..71],
- [message1, 87..87],
- [message2, 87..87],
- [message1, 97..97],
- [message2, 97..97],
- [message1, 109..109],
- [message2, 109..109],
- ]
- 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
- message1 = 'expected a newline or semicolon after the statement'
- message2 = 'cannot parse the expression'
- assert_errors expression(source), source, [
- [message1, 3..3],
- [message2, 3..3],
- [message1, 10..10],
- [message2, 10..10],
- ]
- end
-
- def test_circular_param
- source = <<~RUBY
- def foo(bar = bar) = 42
- def foo(bar: bar) = 42
- proc { |foo = foo| }
- proc { |foo: foo| }
- RUBY
- message = 'parameter default value references itself'
- assert_errors expression(source), source, [
- [message, 14..17],
- [message, 37..40],
- [message, 61..64],
- [message, 81..84],
- ], compare_ripper: false # Ripper does not check 'circular reference'.
- 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|
- assert_nil Ripper.sexp_raw(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|
- assert_nil Ripper.sexp_raw(source)
- assert_false(Prism.parse(source).success?)
- end
- 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
- message1 = 'expected a newline or semicolon after the statement'
- message2 = 'cannot parse the expression'
- assert_errors expression(source), source, [
- [message1, 6..6],
- [message2, 6..6],
- [message1, 18..18],
- [message2, 18..18],
- [message1, 31..31],
- [message2, 31..31],
- [message1, 44..44],
- [message2, 44..44],
- [message1, 56..56],
- [message2, 56..56],
- [message1, 69..69],
- [message2, 69..69],
- ]
- end
-
- private
-
- def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby")
- # Ripper behaves differently on JRuby/TruffleRuby, so only check this on CRuby
- assert_nil Ripper.sexp_raw(source) if compare_ripper
-
- 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, compare_ripper: RUBY_ENGINE == "ruby")
- assert_nil Ripper.sexp_raw(source) if compare_ripper
- result = Prism.parse(source)
- assert_equal(errors, result.errors.map(&:message))
- 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
deleted file mode 100644
index 376dacd7cc..0000000000
--- a/test/prism/fixtures/alias.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index b1e1267b95..0000000000
--- a/test/prism/fixtures/arithmetic.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index cd4e3046f7..0000000000
--- a/test/prism/fixtures/arrays.txt
+++ /dev/null
@@ -1,142 +0,0 @@
-[*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[&bar] = 1
-
-foo.foo[&bar] = 1
-
-def foo(&)
- bar[&] = 1
-end
-
-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
-
-foo[bar, &baz] += 1
-
-foo[bar, &baz] ||= 1
-
-foo[bar, &baz] &&= 1
-
-foo.foo[bar, &baz] += 1
-
-foo.foo[bar, &baz] ||= 1
-
-foo.foo[bar, &baz] &&= 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
deleted file mode 100644
index 6cfb627453..0000000000
--- a/test/prism/fixtures/begin_ensure.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100644
index 0a56fbef9f..0000000000
--- a/test/prism/fixtures/begin_rescue.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-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
deleted file mode 100644
index e33d95c150..0000000000
--- a/test/prism/fixtures/blocks.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-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
deleted file mode 100644
index dd0b9c9f01..0000000000
--- a/test/prism/fixtures/boolean_operators.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-a &&= b
-
-a += b
-
-a ||= b
diff --git a/test/prism/fixtures/booleans.txt b/test/prism/fixtures/booleans.txt
deleted file mode 100644
index d9417254b6..0000000000
--- a/test/prism/fixtures/booleans.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-false
-
-true
diff --git a/test/prism/fixtures/break.txt b/test/prism/fixtures/break.txt
deleted file mode 100644
index 61859d8a8a..0000000000
--- a/test/prism/fixtures/break.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-break
-
-break (1), (2), (3)
-
-break 1
-
-break 1, 2,
-3
-
-break 1, 2, 3
-
-break [1, 2, 3]
-
-break(
- 1
- 2
-)
-
-break()
-
-break(1)
-
-foo { break 42 } == 42
-
-foo { |a| break } == 42
diff --git a/test/prism/fixtures/case.txt b/test/prism/fixtures/case.txt
deleted file mode 100644
index 9db91e8d0f..0000000000
--- a/test/prism/fixtures/case.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-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
diff --git a/test/prism/fixtures/classes.txt b/test/prism/fixtures/classes.txt
deleted file mode 100644
index 056cb00e82..0000000000
--- a/test/prism/fixtures/classes.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-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
deleted file mode 100644
index 182b87948b..0000000000
--- a/test/prism/fixtures/command_method_call.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-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
deleted file mode 100644
index 9bd853e927..0000000000
--- a/test/prism/fixtures/comments.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-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
deleted file mode 100644
index d86f8d3402..0000000000
--- a/test/prism/fixtures/constants.txt
+++ /dev/null
@@ -1,184 +0,0 @@
-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
deleted file mode 100644
index 3e663fae63..0000000000
--- a/test/prism/fixtures/dash_heredocs.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-<<-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
deleted file mode 100644
index 247fa94e3a..0000000000
--- a/test/prism/fixtures/defined.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index c105522fa1..0000000000
--- a/test/prism/fixtures/dos_endings.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-puts "hi"\
- "there"
-
-%I{a\
-b}
-
-<<-E
- 1 \
- 2
- 3
-E
-
-x = %
-
-
-
-a = foo(<<~EOF.chop)
-
- baz
- EOF
diff --git a/test/prism/fixtures/embdoc_no_newline_at_end.txt b/test/prism/fixtures/embdoc_no_newline_at_end.txt
deleted file mode 100644
index 7dc2e32d73..0000000000
--- a/test/prism/fixtures/embdoc_no_newline_at_end.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-=begin
-=end \ No newline at end of file
diff --git a/test/prism/fixtures/endless_methods.txt b/test/prism/fixtures/endless_methods.txt
deleted file mode 100644
index 8c2f2a30cc..0000000000
--- a/test/prism/fixtures/endless_methods.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 6048008584..0000000000
--- a/test/prism/fixtures/endless_range_in_conditional.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-if 1..2 ; end
-if ..1 ; end
-if 1.. ; end
diff --git a/test/prism/fixtures/for.txt b/test/prism/fixtures/for.txt
deleted file mode 100644
index b6eb2cb24f..0000000000
--- a/test/prism/fixtures/for.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644
index 3dc52722a0..0000000000
--- a/test/prism/fixtures/global_variables.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-$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
deleted file mode 100644
index 443b2359c6..0000000000
--- a/test/prism/fixtures/hashes.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-{}
-
-{
-}
-
-{ 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
diff --git a/test/prism/fixtures/heredoc_with_comment.txt b/test/prism/fixtures/heredoc_with_comment.txt
deleted file mode 100644
index 8e7b7275bd..0000000000
--- a/test/prism/fixtures/heredoc_with_comment.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-<<-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
deleted file mode 100644
index 81f314e0b3..0000000000
--- a/test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-<<-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
deleted file mode 100644
index 13771bf3ac..0000000000
--- a/test/prism/fixtures/heredoc_with_trailing_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-<<-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
deleted file mode 100644
index e786f08774..0000000000
--- a/test/prism/fixtures/heredocs_leading_whitespace.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-<<-' 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
deleted file mode 100644
index 0802378278..0000000000
--- a/test/prism/fixtures/heredocs_nested.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-<<~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
deleted file mode 100644
index 8e12546ec7..0000000000
--- a/test/prism/fixtures/heredocs_with_ignored_newlines.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-<<-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
deleted file mode 100644
index aeacbd8126..0000000000
--- a/test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<-EOE
- some
- heredocs
-EOE \ No newline at end of file
diff --git a/test/prism/fixtures/if.txt b/test/prism/fixtures/if.txt
deleted file mode 100644
index c5281a6693..0000000000
--- a/test/prism/fixtures/if.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-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
-
-break if true
-
-next if true
-
-return if true
-
-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 1
- lambda do |_|
- end
-elsif 2
- 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
deleted file mode 100644
index 5a96dcacf7..0000000000
--- a/test/prism/fixtures/indented_file_end.txt
+++ /dev/null
@@ -1,4 +0,0 @@
- 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
deleted file mode 100644
index 37163acf30..0000000000
--- a/test/prism/fixtures/integer_operations.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-!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
deleted file mode 100644
index 9154469441..0000000000
--- a/test/prism/fixtures/keyword_method_names.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-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
deleted file mode 100644
index 90cdfb41c7..0000000000
--- a/test/prism/fixtures/keywords.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-redo
-
-retry
-
-self
-
-__ENCODING__
-
-__FILE__
-
-__LINE__
diff --git a/test/prism/fixtures/lambda.txt b/test/prism/fixtures/lambda.txt
deleted file mode 100644
index 5c21eafb24..0000000000
--- a/test/prism/fixtures/lambda.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-->(
- 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
deleted file mode 100644
index d8c32a148f..0000000000
--- a/test/prism/fixtures/method_calls.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-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
diff --git a/test/prism/fixtures/methods.txt b/test/prism/fixtures/methods.txt
deleted file mode 100644
index 703527f2de..0000000000
--- a/test/prism/fixtures/methods.txt
+++ /dev/null
@@ -1,186 +0,0 @@
-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
-
-def foo(_a, _a, b, c)
-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
deleted file mode 100644
index 76bd9bea43..0000000000
--- a/test/prism/fixtures/modules.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-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/newline_terminated.txt b/test/prism/fixtures/newline_terminated.txt
deleted file mode 100644
index 12f3bda229..0000000000
--- a/test/prism/fixtures/newline_terminated.txt
+++ /dev/null
Binary files differ
diff --git a/test/prism/fixtures/next.txt b/test/prism/fixtures/next.txt
deleted file mode 100644
index 476f17ffe3..0000000000
--- a/test/prism/fixtures/next.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-next
-
-next (1), (2), (3)
-
-next 1
-
-next 1, 2,
-3
-
-next 1, 2, 3
-
-next [1, 2, 3]
-
-next(
- 1
- 2
-)
-
-next
-1
-
-next()
-
-next(1)
diff --git a/test/prism/fixtures/nils.txt b/test/prism/fixtures/nils.txt
deleted file mode 100644
index 8084db2534..0000000000
--- a/test/prism/fixtures/nils.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-nil
-
-()
-
-(
-;
-;
-)
-
-END { 1 }
-
-BEGIN { 1 }
-
diff --git a/test/prism/fixtures/non_alphanumeric_methods.txt b/test/prism/fixtures/non_alphanumeric_methods.txt
deleted file mode 100644
index 1da3fd852b..0000000000
--- a/test/prism/fixtures/non_alphanumeric_methods.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-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
deleted file mode 100644
index 520b34fa37..0000000000
--- a/test/prism/fixtures/not.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-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
deleted file mode 100644
index 47f20dcb42..0000000000
--- a/test/prism/fixtures/numbers.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-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
deleted file mode 100644
index d73c8d025e..0000000000
--- a/test/prism/fixtures/patterns.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-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 }
-
-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 => []
-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 }
-
-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:}]
diff --git a/test/prism/fixtures/procs.txt b/test/prism/fixtures/procs.txt
deleted file mode 100644
index 7ffb11e78a..0000000000
--- a/test/prism/fixtures/procs.txt
+++ /dev/null
@@ -1,27 +0,0 @@
--> (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
deleted file mode 100644
index 3b12672b4f..0000000000
--- a/test/prism/fixtures/range_begin_open_exclusive.txt
+++ /dev/null
@@ -1 +0,0 @@
-...2
diff --git a/test/prism/fixtures/range_begin_open_inclusive.txt b/test/prism/fixtures/range_begin_open_inclusive.txt
deleted file mode 100644
index 052f45900b..0000000000
--- a/test/prism/fixtures/range_begin_open_inclusive.txt
+++ /dev/null
@@ -1 +0,0 @@
-..2
diff --git a/test/prism/fixtures/range_end_open_exclusive.txt b/test/prism/fixtures/range_end_open_exclusive.txt
deleted file mode 100644
index 2ffd68afdb..0000000000
--- a/test/prism/fixtures/range_end_open_exclusive.txt
+++ /dev/null
@@ -1 +0,0 @@
-2...
diff --git a/test/prism/fixtures/range_end_open_inclusive.txt b/test/prism/fixtures/range_end_open_inclusive.txt
deleted file mode 100644
index 48445391f6..0000000000
--- a/test/prism/fixtures/range_end_open_inclusive.txt
+++ /dev/null
@@ -1 +0,0 @@
-2..
diff --git a/test/prism/fixtures/ranges.txt b/test/prism/fixtures/ranges.txt
deleted file mode 100644
index e2e4136ae9..0000000000
--- a/test/prism/fixtures/ranges.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-(...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
deleted file mode 100644
index ef2f6d45a3..0000000000
--- a/test/prism/fixtures/regex.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-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(
-(?:[\w#$%_']|\(\)|\(,\)|\[\]|[0-9])*
- (?:[\w#$%_']+)
-)
-
-/(?#\))/ =~ "hi"
-
-%r#pound#
-
-/aaa #{bbb}/o
-
-/(?<a\
-b>)/ =~ ""; ab
-
-/(?<abc>)(?<abc>)/ =~ ""; abc
-
-/(?<a b>)/ =~ ""
-
-a = 1
-tap { /(?<a>)/ =~ to_s }
diff --git a/test/prism/fixtures/rescue.txt b/test/prism/fixtures/rescue.txt
deleted file mode 100644
index 0d26fd2523..0000000000
--- a/test/prism/fixtures/rescue.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-foo rescue nil
-
-foo rescue
-nil
-
-break rescue nil
-
-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
diff --git a/test/prism/fixtures/return.txt b/test/prism/fixtures/return.txt
deleted file mode 100644
index a8b5b95fab..0000000000
--- a/test/prism/fixtures/return.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-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
deleted file mode 100644
index bed5755901..0000000000
--- a/test/prism/fixtures/seattlerb/BEGIN.txt
+++ /dev/null
@@ -1 +0,0 @@
-BEGIN { 42 }
diff --git a/test/prism/fixtures/seattlerb/README.rdoc b/test/prism/fixtures/seattlerb/README.rdoc
deleted file mode 100644
index 649e4e4c2f..0000000000
--- a/test/prism/fixtures/seattlerb/README.rdoc
+++ /dev/null
@@ -1,113 +0,0 @@
-= 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[3]_parser.yy.
-* Extend lib/ruby[3]_parser.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
deleted file mode 100644
index c55b3e1f70..0000000000
--- a/test/prism/fixtures/seattlerb/TestRubyParserShared.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-%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
deleted file mode 100644
index d6debf2f92..0000000000
--- a/test/prism/fixtures/seattlerb/__ENCODING__.txt
+++ /dev/null
@@ -1 +0,0 @@
-__ENCODING__
diff --git a/test/prism/fixtures/seattlerb/alias_gvar_backref.txt b/test/prism/fixtures/seattlerb/alias_gvar_backref.txt
deleted file mode 100644
index 016bd94fe0..0000000000
--- a/test/prism/fixtures/seattlerb/alias_gvar_backref.txt
+++ /dev/null
@@ -1 +0,0 @@
-alias $MATCH $&
diff --git a/test/prism/fixtures/seattlerb/alias_resword.txt b/test/prism/fixtures/seattlerb/alias_resword.txt
deleted file mode 100644
index 63e782614b..0000000000
--- a/test/prism/fixtures/seattlerb/alias_resword.txt
+++ /dev/null
@@ -1 +0,0 @@
-alias in out
diff --git a/test/prism/fixtures/seattlerb/and_multi.txt b/test/prism/fixtures/seattlerb/and_multi.txt
deleted file mode 100644
index 8902086cac..0000000000
--- a/test/prism/fixtures/seattlerb/and_multi.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 3244eebafc..0000000000
--- a/test/prism/fixtures/seattlerb/aref_args_assocs.txt
+++ /dev/null
@@ -1 +0,0 @@
-[1 => 2]
diff --git a/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt b/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt
deleted file mode 100644
index 0b6ffa7e2c..0000000000
--- a/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2 => 3]
diff --git a/test/prism/fixtures/seattlerb/args_kw_block.txt b/test/prism/fixtures/seattlerb/args_kw_block.txt
deleted file mode 100644
index cb6ab39852..0000000000
--- a/test/prism/fixtures/seattlerb/args_kw_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index be9f2d9cb8..0000000000
--- a/test/prism/fixtures/seattlerb/array_line_breaks.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-[
-'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
deleted file mode 100644
index 868384a407..0000000000
--- a/test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-%w[].b
-
-[].b
diff --git a/test/prism/fixtures/seattlerb/assoc__bare.txt b/test/prism/fixtures/seattlerb/assoc__bare.txt
deleted file mode 100644
index 96c2940f31..0000000000
--- a/test/prism/fixtures/seattlerb/assoc__bare.txt
+++ /dev/null
@@ -1 +0,0 @@
-{ y: }
diff --git a/test/prism/fixtures/seattlerb/assoc_label.txt b/test/prism/fixtures/seattlerb/assoc_label.txt
deleted file mode 100644
index 372dc75031..0000000000
--- a/test/prism/fixtures/seattlerb/assoc_label.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index f63c2f5dcb..0000000000
--- a/test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt
+++ /dev/null
@@ -1 +0,0 @@
-A::b = 1
diff --git a/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt b/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt
deleted file mode 100644
index db9e2db063..0000000000
--- a/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a[[1, 2]] = 3
diff --git a/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt b/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt
deleted file mode 100644
index 0b8e31632d..0000000000
--- a/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt
+++ /dev/null
@@ -1 +0,0 @@
-[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
deleted file mode 100644
index 380a718963..0000000000
--- a/test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.B = 1
diff --git a/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt b/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt
deleted file mode 100644
index b3ba31c72a..0000000000
--- a/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt
+++ /dev/null
@@ -1 +0,0 @@
-x `#{y}`
diff --git a/test/prism/fixtures/seattlerb/bang_eq.txt b/test/prism/fixtures/seattlerb/bang_eq.txt
deleted file mode 100644
index 0283460e46..0000000000
--- a/test/prism/fixtures/seattlerb/bang_eq.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 != 2
diff --git a/test/prism/fixtures/seattlerb/bdot2.txt b/test/prism/fixtures/seattlerb/bdot2.txt
deleted file mode 100644
index 4fb2692299..0000000000
--- a/test/prism/fixtures/seattlerb/bdot2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-..10
-; ..a
-; c
diff --git a/test/prism/fixtures/seattlerb/bdot3.txt b/test/prism/fixtures/seattlerb/bdot3.txt
deleted file mode 100644
index 8079cf9872..0000000000
--- a/test/prism/fixtures/seattlerb/bdot3.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-...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
deleted file mode 100644
index 51dde02ea3..0000000000
--- a/test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index ae6e2c3636..0000000000
--- a/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 456d9a5d6e..0000000000
--- a/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 896e3c030a..0000000000
--- a/test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-begin
-rescue
-ensure
-end
diff --git a/test/prism/fixtures/seattlerb/block_arg__bare.txt b/test/prism/fixtures/seattlerb/block_arg__bare.txt
deleted file mode 100644
index 6454b00345..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg__bare.txt
+++ /dev/null
@@ -1 +0,0 @@
-def x(&); end
diff --git a/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt b/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt
deleted file mode 100644
index a9c255cc66..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 14cb02c68e..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a077ae1f34..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_opt_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 5016a7c6b9..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 966afc5640..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_optional.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b = 1| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_scope.txt b/test/prism/fixtures/seattlerb/block_arg_scope.txt
deleted file mode 100644
index 2362e08559..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_scope.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b; c| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_scope2.txt b/test/prism/fixtures/seattlerb/block_arg_scope2.txt
deleted file mode 100644
index f7222dc7b1..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_scope2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index d7c31aae6b..0000000000
--- a/test/prism/fixtures/seattlerb/block_arg_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b, *c, d| }
diff --git a/test/prism/fixtures/seattlerb/block_args_kwargs.txt b/test/prism/fixtures/seattlerb/block_args_kwargs.txt
deleted file mode 100644
index 467b577a7e..0000000000
--- a/test/prism/fixtures/seattlerb/block_args_kwargs.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 5c9bfa3a62..0000000000
--- a/test/prism/fixtures/seattlerb/block_args_no_kwargs.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |**nil| }
diff --git a/test/prism/fixtures/seattlerb/block_args_opt1.txt b/test/prism/fixtures/seattlerb/block_args_opt1.txt
deleted file mode 100644
index 372689e36a..0000000000
--- a/test/prism/fixtures/seattlerb/block_args_opt1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 10d0746646..0000000000
--- a/test/prism/fixtures/seattlerb/block_args_opt2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 563a9bf915..0000000000
--- a/test/prism/fixtures/seattlerb/block_args_opt2_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index bb5a7c8458..0000000000
--- a/test/prism/fixtures/seattlerb/block_args_opt3.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, b = 42, c = 24, &d| [a, b, c, d] }
diff --git a/test/prism/fixtures/seattlerb/block_break.txt b/test/prism/fixtures/seattlerb/block_break.txt
deleted file mode 100644
index 35eabee187..0000000000
--- a/test/prism/fixtures/seattlerb/block_break.txt
+++ /dev/null
@@ -1 +0,0 @@
-break foo arg do |bar| end
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
deleted file mode 100644
index ff1b3a4c9f..0000000000
--- a/test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 63da9ee7af..0000000000
--- a/test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 24e7d0f1f1..0000000000
--- a/test/prism/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 593b9e1bc0..0000000000
--- a/test/prism/fixtures/seattlerb/block_call_operation_colon.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 20b8e4fcb8..0000000000
--- a/test/prism/fixtures/seattlerb/block_call_operation_dot.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 7f8be95100..0000000000
--- a/test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index db221ad496..0000000000
--- a/test/prism/fixtures/seattlerb/block_command_operation_colon.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 56b71677e8..0000000000
--- a/test/prism/fixtures/seattlerb/block_command_operation_dot.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 96f5d5d2ec..0000000000
--- a/test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |(*, a)| }
diff --git a/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt b/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt
deleted file mode 100644
index f8db3874de..0000000000
--- a/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e64f4e8c3d..0000000000
--- a/test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |(a, *b, c)| }
diff --git a/test/prism/fixtures/seattlerb/block_decomp_splat.txt b/test/prism/fixtures/seattlerb/block_decomp_splat.txt
deleted file mode 100644
index 970f00a626..0000000000
--- a/test/prism/fixtures/seattlerb/block_decomp_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |(*a)| }
diff --git a/test/prism/fixtures/seattlerb/block_kw.txt b/test/prism/fixtures/seattlerb/block_kw.txt
deleted file mode 100644
index bacfd32e80..0000000000
--- a/test/prism/fixtures/seattlerb/block_kw.txt
+++ /dev/null
@@ -1 +0,0 @@
-blah { |k:42| }
diff --git a/test/prism/fixtures/seattlerb/block_kw__required.txt b/test/prism/fixtures/seattlerb/block_kw__required.txt
deleted file mode 100644
index b84ab97037..0000000000
--- a/test/prism/fixtures/seattlerb/block_kw__required.txt
+++ /dev/null
@@ -1 +0,0 @@
-blah do |k:| end
diff --git a/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt b/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt
deleted file mode 100644
index 390b9195e0..0000000000
--- a/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index df3e4afde8..0000000000
--- a/test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt
+++ /dev/null
@@ -1 +0,0 @@
-bl { |kw: :val, kw2: :val2 | kw }
diff --git a/test/prism/fixtures/seattlerb/block_next.txt b/test/prism/fixtures/seattlerb/block_next.txt
deleted file mode 100644
index 760fcbf809..0000000000
--- a/test/prism/fixtures/seattlerb/block_next.txt
+++ /dev/null
@@ -1 +0,0 @@
-next foo arg do |bar| end
diff --git a/test/prism/fixtures/seattlerb/block_opt_arg.txt b/test/prism/fixtures/seattlerb/block_opt_arg.txt
deleted file mode 100644
index 5e312fdf41..0000000000
--- a/test/prism/fixtures/seattlerb/block_opt_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b=1, c| }
diff --git a/test/prism/fixtures/seattlerb/block_opt_splat.txt b/test/prism/fixtures/seattlerb/block_opt_splat.txt
deleted file mode 100644
index 772a3fc412..0000000000
--- a/test/prism/fixtures/seattlerb/block_opt_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 76466f9d54..0000000000
--- a/test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b=1, *c, d, &e| }
diff --git a/test/prism/fixtures/seattlerb/block_optarg.txt b/test/prism/fixtures/seattlerb/block_optarg.txt
deleted file mode 100644
index a471554da1..0000000000
--- a/test/prism/fixtures/seattlerb/block_optarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b = :c| }
diff --git a/test/prism/fixtures/seattlerb/block_paren_splat.txt b/test/prism/fixtures/seattlerb/block_paren_splat.txt
deleted file mode 100644
index 3dd4bba1ed..0000000000
--- a/test/prism/fixtures/seattlerb/block_paren_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |(b, *c)| }
diff --git a/test/prism/fixtures/seattlerb/block_reg_optarg.txt b/test/prism/fixtures/seattlerb/block_reg_optarg.txt
deleted file mode 100644
index c024651f78..0000000000
--- a/test/prism/fixtures/seattlerb/block_reg_optarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b, c = :d| }
diff --git a/test/prism/fixtures/seattlerb/block_return.txt b/test/prism/fixtures/seattlerb/block_return.txt
deleted file mode 100644
index f30ba71d8f..0000000000
--- a/test/prism/fixtures/seattlerb/block_return.txt
+++ /dev/null
@@ -1 +0,0 @@
-return foo arg do |bar| end
diff --git a/test/prism/fixtures/seattlerb/block_scope.txt b/test/prism/fixtures/seattlerb/block_scope.txt
deleted file mode 100644
index 7a83d8ab87..0000000000
--- a/test/prism/fixtures/seattlerb/block_scope.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |;b| }
diff --git a/test/prism/fixtures/seattlerb/block_splat_reg.txt b/test/prism/fixtures/seattlerb/block_splat_reg.txt
deleted file mode 100644
index 58f0619e5d..0000000000
--- a/test/prism/fixtures/seattlerb/block_splat_reg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |*b, c| }
diff --git a/test/prism/fixtures/seattlerb/bug169.txt b/test/prism/fixtures/seattlerb/bug169.txt
deleted file mode 100644
index db2e5ace5e..0000000000
--- a/test/prism/fixtures/seattlerb/bug169.txt
+++ /dev/null
@@ -1 +0,0 @@
-m () {}
diff --git a/test/prism/fixtures/seattlerb/bug179.txt b/test/prism/fixtures/seattlerb/bug179.txt
deleted file mode 100644
index 02ae07a3be..0000000000
--- a/test/prism/fixtures/seattlerb/bug179.txt
+++ /dev/null
@@ -1 +0,0 @@
-p ()..nil
diff --git a/test/prism/fixtures/seattlerb/bug190.txt b/test/prism/fixtures/seattlerb/bug190.txt
deleted file mode 100644
index 861b2d305f..0000000000
--- a/test/prism/fixtures/seattlerb/bug190.txt
+++ /dev/null
@@ -1 +0,0 @@
-%r'\''
diff --git a/test/prism/fixtures/seattlerb/bug191.txt b/test/prism/fixtures/seattlerb/bug191.txt
deleted file mode 100644
index 03f7fd1228..0000000000
--- a/test/prism/fixtures/seattlerb/bug191.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-a ? "": b
-
-a ? '': b
diff --git a/test/prism/fixtures/seattlerb/bug202.txt b/test/prism/fixtures/seattlerb/bug202.txt
deleted file mode 100644
index a3b06ffdfc..0000000000
--- a/test/prism/fixtures/seattlerb/bug202.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-$测试 = 1
-测试 = 1
diff --git a/test/prism/fixtures/seattlerb/bug236.txt b/test/prism/fixtures/seattlerb/bug236.txt
deleted file mode 100644
index cefe1eb058..0000000000
--- a/test/prism/fixtures/seattlerb/bug236.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-x{|a,|}
-
-x{|a|}
diff --git a/test/prism/fixtures/seattlerb/bug290.txt b/test/prism/fixtures/seattlerb/bug290.txt
deleted file mode 100644
index dbcd28cd48..0000000000
--- a/test/prism/fixtures/seattlerb/bug290.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-begin
- foo
-end
diff --git a/test/prism/fixtures/seattlerb/bug_187.txt b/test/prism/fixtures/seattlerb/bug_187.txt
deleted file mode 100644
index 1e1ecd8202..0000000000
--- a/test/prism/fixtures/seattlerb/bug_187.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index f0d09ba5ff..0000000000
--- a/test/prism/fixtures/seattlerb/bug_215.txt
+++ /dev/null
@@ -1 +0,0 @@
-undef %s(foo)
diff --git a/test/prism/fixtures/seattlerb/bug_249.txt b/test/prism/fixtures/seattlerb/bug_249.txt
deleted file mode 100644
index ccccdf5326..0000000000
--- a/test/prism/fixtures/seattlerb/bug_249.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 6243359a9e..0000000000
--- a/test/prism/fixtures/seattlerb/bug_and.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 08466554fd..0000000000
--- a/test/prism/fixtures/seattlerb/bug_args__19.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |(a, b)| d }
diff --git a/test/prism/fixtures/seattlerb/bug_args_masgn.txt b/test/prism/fixtures/seattlerb/bug_args_masgn.txt
deleted file mode 100644
index e0a71e9197..0000000000
--- a/test/prism/fixtures/seattlerb/bug_args_masgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |(a, b), c| }
diff --git a/test/prism/fixtures/seattlerb/bug_args_masgn2.txt b/test/prism/fixtures/seattlerb/bug_args_masgn2.txt
deleted file mode 100644
index 2f12756bfe..0000000000
--- a/test/prism/fixtures/seattlerb/bug_args_masgn2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a2b0178676..0000000000
--- a/test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 4f04368802..0000000000
--- a/test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt
+++ /dev/null
@@ -1,11 +0,0 @@
- 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
deleted file mode 100644
index 2536696a42..0000000000
--- a/test/prism/fixtures/seattlerb/bug_case_when_regexp.txt
+++ /dev/null
@@ -1 +0,0 @@
-case :x; when /x/ then end
diff --git a/test/prism/fixtures/seattlerb/bug_comma.txt b/test/prism/fixtures/seattlerb/bug_comma.txt
deleted file mode 100644
index d86f1ea9dd..0000000000
--- a/test/prism/fixtures/seattlerb/bug_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1b4f90058e..0000000000
--- a/test/prism/fixtures/seattlerb/bug_cond_pct.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index b815f8a666..0000000000
--- a/test/prism/fixtures/seattlerb/bug_hash_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6057b245a5..0000000000
--- a/test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 01fe238056..0000000000
--- a/test/prism/fixtures/seattlerb/bug_hash_interp_array.txt
+++ /dev/null
@@ -1 +0,0 @@
-{ "#{}": [] }
diff --git a/test/prism/fixtures/seattlerb/bug_masgn_right.txt b/test/prism/fixtures/seattlerb/bug_masgn_right.txt
deleted file mode 100644
index 12ea7b8d62..0000000000
--- a/test/prism/fixtures/seattlerb/bug_masgn_right.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (b, c)| }
diff --git a/test/prism/fixtures/seattlerb/bug_not_parens.txt b/test/prism/fixtures/seattlerb/bug_not_parens.txt
deleted file mode 100644
index 8847b7bec6..0000000000
--- a/test/prism/fixtures/seattlerb/bug_not_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-not(a)
diff --git a/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt b/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt
deleted file mode 100644
index 6a0b25cbdc..0000000000
--- a/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt
+++ /dev/null
@@ -1 +0,0 @@
-a ||= b rescue nil
diff --git a/test/prism/fixtures/seattlerb/call_and.txt b/test/prism/fixtures/seattlerb/call_and.txt
deleted file mode 100644
index c17be8f356..0000000000
--- a/test/prism/fixtures/seattlerb/call_and.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 & 2
diff --git a/test/prism/fixtures/seattlerb/call_arg_assoc.txt b/test/prism/fixtures/seattlerb/call_arg_assoc.txt
deleted file mode 100644
index 376c299be5..0000000000
--- a/test/prism/fixtures/seattlerb/call_arg_assoc.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a4be0fb62c..0000000000
--- a/test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 4848fd9e8d..0000000000
--- a/test/prism/fixtures/seattlerb/call_arg_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0af2259577..0000000000
--- a/test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 6ad08f3238..0000000000
--- a/test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-f(1, 2=>3,)
diff --git a/test/prism/fixtures/seattlerb/call_args_command.txt b/test/prism/fixtures/seattlerb/call_args_command.txt
deleted file mode 100644
index dd6df29c7b..0000000000
--- a/test/prism/fixtures/seattlerb/call_args_command.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 5c724fa328..0000000000
--- a/test/prism/fixtures/seattlerb/call_array_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6d4c1b276e..0000000000
--- a/test/prism/fixtures/seattlerb/call_array_block_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index dc5b5807b2..0000000000
--- a/test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index daba00947e..0000000000
--- a/test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt
+++ /dev/null
@@ -1 +0,0 @@
-a([:b, :c => 1])
diff --git a/test/prism/fixtures/seattlerb/call_assoc.txt b/test/prism/fixtures/seattlerb/call_assoc.txt
deleted file mode 100644
index 2adc1eee1c..0000000000
--- a/test/prism/fixtures/seattlerb/call_assoc.txt
+++ /dev/null
@@ -1 +0,0 @@
-f(2=>3)
diff --git a/test/prism/fixtures/seattlerb/call_assoc_new.txt b/test/prism/fixtures/seattlerb/call_assoc_new.txt
deleted file mode 100644
index b8457bfdfc..0000000000
--- a/test/prism/fixtures/seattlerb/call_assoc_new.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index fe0a37dabb..0000000000
--- a/test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 4d86a4541d..0000000000
--- a/test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 4f3ba4b93c..0000000000
--- a/test/prism/fixtures/seattlerb/call_bang_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-! a.b 1
diff --git a/test/prism/fixtures/seattlerb/call_bang_squiggle.txt b/test/prism/fixtures/seattlerb/call_bang_squiggle.txt
deleted file mode 100644
index d7039f910a..0000000000
--- a/test/prism/fixtures/seattlerb/call_bang_squiggle.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e9b43491fe..0000000000
--- a/test/prism/fixtures/seattlerb/call_begin_call_block_call.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 08fea89d11..0000000000
--- a/test/prism/fixtures/seattlerb/call_block_arg_named.txt
+++ /dev/null
@@ -1 +0,0 @@
-x(&blk)
diff --git a/test/prism/fixtures/seattlerb/call_carat.txt b/test/prism/fixtures/seattlerb/call_carat.txt
deleted file mode 100644
index 3e88c09837..0000000000
--- a/test/prism/fixtures/seattlerb/call_carat.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 ^ 2
diff --git a/test/prism/fixtures/seattlerb/call_colon2.txt b/test/prism/fixtures/seattlerb/call_colon2.txt
deleted file mode 100644
index 47aab7e637..0000000000
--- a/test/prism/fixtures/seattlerb/call_colon2.txt
+++ /dev/null
@@ -1 +0,0 @@
-A::b
diff --git a/test/prism/fixtures/seattlerb/call_colon_parens.txt b/test/prism/fixtures/seattlerb/call_colon_parens.txt
deleted file mode 100644
index 51ed4df11b..0000000000
--- a/test/prism/fixtures/seattlerb/call_colon_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-1::()
diff --git a/test/prism/fixtures/seattlerb/call_div.txt b/test/prism/fixtures/seattlerb/call_div.txt
deleted file mode 100644
index 85b4d7b0b0..0000000000
--- a/test/prism/fixtures/seattlerb/call_div.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 / 2
diff --git a/test/prism/fixtures/seattlerb/call_dot_parens.txt b/test/prism/fixtures/seattlerb/call_dot_parens.txt
deleted file mode 100644
index 0270596a07..0000000000
--- a/test/prism/fixtures/seattlerb/call_dot_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-1.()
diff --git a/test/prism/fixtures/seattlerb/call_env.txt b/test/prism/fixtures/seattlerb/call_env.txt
deleted file mode 100644
index dadc0d3861..0000000000
--- a/test/prism/fixtures/seattlerb/call_env.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.happy
diff --git a/test/prism/fixtures/seattlerb/call_eq3.txt b/test/prism/fixtures/seattlerb/call_eq3.txt
deleted file mode 100644
index 6a2fb465cb..0000000000
--- a/test/prism/fixtures/seattlerb/call_eq3.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 === 2
diff --git a/test/prism/fixtures/seattlerb/call_gt.txt b/test/prism/fixtures/seattlerb/call_gt.txt
deleted file mode 100644
index 9d0a1caa90..0000000000
--- a/test/prism/fixtures/seattlerb/call_gt.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 > 2
diff --git a/test/prism/fixtures/seattlerb/call_kwsplat.txt b/test/prism/fixtures/seattlerb/call_kwsplat.txt
deleted file mode 100644
index eda700c3e1..0000000000
--- a/test/prism/fixtures/seattlerb/call_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-a(**1)
diff --git a/test/prism/fixtures/seattlerb/call_leading_dots.txt b/test/prism/fixtures/seattlerb/call_leading_dots.txt
deleted file mode 100644
index 1e7b2e5179..0000000000
--- a/test/prism/fixtures/seattlerb/call_leading_dots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index c5deec5642..0000000000
--- a/test/prism/fixtures/seattlerb/call_leading_dots_comment.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-a
-.b
-#.c
-.d
diff --git a/test/prism/fixtures/seattlerb/call_lt.txt b/test/prism/fixtures/seattlerb/call_lt.txt
deleted file mode 100644
index 17e69c79b5..0000000000
--- a/test/prism/fixtures/seattlerb/call_lt.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 < 2
diff --git a/test/prism/fixtures/seattlerb/call_lte.txt b/test/prism/fixtures/seattlerb/call_lte.txt
deleted file mode 100644
index 7574027634..0000000000
--- a/test/prism/fixtures/seattlerb/call_lte.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 <= 2
diff --git a/test/prism/fixtures/seattlerb/call_not.txt b/test/prism/fixtures/seattlerb/call_not.txt
deleted file mode 100644
index 51e4742f55..0000000000
--- a/test/prism/fixtures/seattlerb/call_not.txt
+++ /dev/null
@@ -1 +0,0 @@
-not 42
diff --git a/test/prism/fixtures/seattlerb/call_pipe.txt b/test/prism/fixtures/seattlerb/call_pipe.txt
deleted file mode 100644
index 1555910665..0000000000
--- a/test/prism/fixtures/seattlerb/call_pipe.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 | 2
diff --git a/test/prism/fixtures/seattlerb/call_rshift.txt b/test/prism/fixtures/seattlerb/call_rshift.txt
deleted file mode 100644
index 9ff1def4e0..0000000000
--- a/test/prism/fixtures/seattlerb/call_rshift.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 >> 2
diff --git a/test/prism/fixtures/seattlerb/call_self_brackets.txt b/test/prism/fixtures/seattlerb/call_self_brackets.txt
deleted file mode 100644
index 6533df2ce0..0000000000
--- a/test/prism/fixtures/seattlerb/call_self_brackets.txt
+++ /dev/null
@@ -1 +0,0 @@
-self[1]
diff --git a/test/prism/fixtures/seattlerb/call_spaceship.txt b/test/prism/fixtures/seattlerb/call_spaceship.txt
deleted file mode 100644
index 905c3a1c46..0000000000
--- a/test/prism/fixtures/seattlerb/call_spaceship.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2d1afdad28..0000000000
--- a/test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0d995a04d1..0000000000
--- a/test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-a -> { 1 } do 2 end
diff --git a/test/prism/fixtures/seattlerb/call_star.txt b/test/prism/fixtures/seattlerb/call_star.txt
deleted file mode 100644
index 096ec022d4..0000000000
--- a/test/prism/fixtures/seattlerb/call_star.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 * 2
diff --git a/test/prism/fixtures/seattlerb/call_star2.txt b/test/prism/fixtures/seattlerb/call_star2.txt
deleted file mode 100644
index bef4719d3c..0000000000
--- a/test/prism/fixtures/seattlerb/call_star2.txt
+++ /dev/null
@@ -1 +0,0 @@
-1 ** 2
diff --git a/test/prism/fixtures/seattlerb/call_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_trailing_comma.txt
deleted file mode 100644
index e9a3ca35be..0000000000
--- a/test/prism/fixtures/seattlerb/call_trailing_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-f(1,)
diff --git a/test/prism/fixtures/seattlerb/call_trailing_dots.txt b/test/prism/fixtures/seattlerb/call_trailing_dots.txt
deleted file mode 100644
index 960cdbb45f..0000000000
--- a/test/prism/fixtures/seattlerb/call_trailing_dots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-a.
-b.
-c
diff --git a/test/prism/fixtures/seattlerb/call_unary_bang.txt b/test/prism/fixtures/seattlerb/call_unary_bang.txt
deleted file mode 100644
index 91f702d4a9..0000000000
--- a/test/prism/fixtures/seattlerb/call_unary_bang.txt
+++ /dev/null
@@ -1 +0,0 @@
-!1
diff --git a/test/prism/fixtures/seattlerb/case_in.txt b/test/prism/fixtures/seattlerb/case_in.txt
deleted file mode 100644
index 0835da0956..0000000000
--- a/test/prism/fixtures/seattlerb/case_in.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-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
deleted file mode 100644
index b9bf25b132..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_31.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 25b6fb9261..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_37.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index bc6a2233f5..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_42.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index ce4b65a5d0..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_42_2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 60f17ed7ce..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_47.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index c1c55e68c7..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_67.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 63ba92e533..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_86.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 4ad16c451a..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_86_2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 8551e48e2c..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_array_pat_const.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index fca423ea61..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index c56f728337..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 5b0dcc18e2..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_const.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 6f096862c5..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_else.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 476fcabe11..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_find.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 5eb4010b7f..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_find_array.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index cb012e8d99..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_hash_pat.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 58fd59ff9c..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index de3a10740c..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 449fd0d4d4..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 6f67cb1d10..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 91d0592412..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index dbe24a5c8a..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 1b6dd06cfe..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_multiple.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 875e37749f..0000000000
--- a/test/prism/fixtures/seattlerb/case_in_or.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 9701eca7e5..0000000000
--- a/test/prism/fixtures/seattlerb/class_comments.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# 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
deleted file mode 100644
index 80293115da..0000000000
--- a/test/prism/fixtures/seattlerb/cond_unary_minus.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6912c2d76b..0000000000
--- a/test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt
+++ /dev/null
@@ -1 +0,0 @@
-::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
deleted file mode 100644
index bbcd25a369..0000000000
--- a/test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt
+++ /dev/null
@@ -1 +0,0 @@
-::X ||= 1
diff --git a/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt b/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt
deleted file mode 100644
index 3964df0ead..0000000000
--- a/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt
+++ /dev/null
@@ -1 +0,0 @@
-::X &= 1
diff --git a/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt b/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt
deleted file mode 100644
index 1bef4b4154..0000000000
--- a/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt
+++ /dev/null
@@ -1 +0,0 @@
-::X &&= 1
diff --git a/test/prism/fixtures/seattlerb/const_op_asgn_or.txt b/test/prism/fixtures/seattlerb/const_op_asgn_or.txt
deleted file mode 100644
index 729e425262..0000000000
--- a/test/prism/fixtures/seattlerb/const_op_asgn_or.txt
+++ /dev/null
@@ -1 +0,0 @@
-X::Y ||= 1
diff --git a/test/prism/fixtures/seattlerb/dasgn_icky2.txt b/test/prism/fixtures/seattlerb/dasgn_icky2.txt
deleted file mode 100644
index 2f50d32304..0000000000
--- a/test/prism/fixtures/seattlerb/dasgn_icky2.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-a do
- v = nil
- begin
- yield
- rescue Exception => v
- break
- end
-end
diff --git a/test/prism/fixtures/seattlerb/defined_eh_parens.txt b/test/prism/fixtures/seattlerb/defined_eh_parens.txt
deleted file mode 100644
index 5ca5d9f4c4..0000000000
--- a/test/prism/fixtures/seattlerb/defined_eh_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-defined?(42)
diff --git a/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt b/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt
deleted file mode 100644
index f629a5de60..0000000000
--- a/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 500e2e1fe0..0000000000
--- a/test/prism/fixtures/seattlerb/defn_arg_forward_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index fc1ee138de..0000000000
--- a/test/prism/fixtures/seattlerb/defn_args_forward_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 04c7ea1a10..0000000000
--- a/test/prism/fixtures/seattlerb/defn_comments.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
deleted file mode 100644
index 172de2ca6c..0000000000
--- a/test/prism/fixtures/seattlerb/defn_endless_command.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 05ed392e38..0000000000
--- a/test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 46ed199875..0000000000
--- a/test/prism/fixtures/seattlerb/defn_forward_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2d34077c93..0000000000
--- a/test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-def f ...
- m(...)
-end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_env.txt b/test/prism/fixtures/seattlerb/defn_kwarg_env.txt
deleted file mode 100644
index b512677195..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_env.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 3962d2645c..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index bd39819482..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index aba71cba07..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 9eac108cca..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 481457bf0e..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 1a2803926f..0000000000
--- a/test/prism/fixtures/seattlerb/defn_kwarg_val.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 857ec8debb..0000000000
--- a/test/prism/fixtures/seattlerb/defn_no_kwargs.txt
+++ /dev/null
@@ -1 +0,0 @@
-def x(**nil); end
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner.txt b/test/prism/fixtures/seattlerb/defn_oneliner.txt
deleted file mode 100644
index 4aef08ce46..0000000000
--- a/test/prism/fixtures/seattlerb/defn_oneliner.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1b1ce27a15..0000000000
--- a/test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index cb4f76d244..0000000000
--- a/test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c582e896c1..0000000000
--- a/test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt
+++ /dev/null
@@ -1 +0,0 @@
-def exec() = system
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt b/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt
deleted file mode 100644
index ffe2228c9d..0000000000
--- a/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 91500bf137..0000000000
--- a/test/prism/fixtures/seattlerb/defn_opt_last_arg.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index c665674bc4..0000000000
--- a/test/prism/fixtures/seattlerb/defn_opt_reg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 876398b478..0000000000
--- a/test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 73415f0db9..0000000000
--- a/test/prism/fixtures/seattlerb/defn_powarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 69f501a38e..0000000000
--- a/test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a2a84bed30..0000000000
--- a/test/prism/fixtures/seattlerb/defn_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(*, a) end
diff --git a/test/prism/fixtures/seattlerb/defn_unary_not.txt b/test/prism/fixtures/seattlerb/defn_unary_not.txt
deleted file mode 100644
index fb83c84a13..0000000000
--- a/test/prism/fixtures/seattlerb/defn_unary_not.txt
+++ /dev/null
@@ -1 +0,0 @@
-def !@; true; end
diff --git a/test/prism/fixtures/seattlerb/defns_reserved.txt b/test/prism/fixtures/seattlerb/defns_reserved.txt
deleted file mode 100644
index 7de9322f0d..0000000000
--- a/test/prism/fixtures/seattlerb/defns_reserved.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 4d493d73dd..0000000000
--- a/test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 52b9b4a6b3..0000000000
--- a/test/prism/fixtures/seattlerb/defs_comments.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
deleted file mode 100644
index 3b605657de..0000000000
--- a/test/prism/fixtures/seattlerb/defs_endless_command.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6ece366db0..0000000000
--- a/test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 59970a371e..0000000000
--- a/test/prism/fixtures/seattlerb/defs_kwarg.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-def self.a b: 1
-end
diff --git a/test/prism/fixtures/seattlerb/defs_oneliner.txt b/test/prism/fixtures/seattlerb/defs_oneliner.txt
deleted file mode 100644
index 1867edcfbf..0000000000
--- a/test/prism/fixtures/seattlerb/defs_oneliner.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1e55f68bf3..0000000000
--- a/test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 7a04012b8f..0000000000
--- a/test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 5c73907cae..0000000000
--- a/test/prism/fixtures/seattlerb/difficult0_.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 8008127dc9..0000000000
--- a/test/prism/fixtures/seattlerb/difficult1_line_numbers.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 1964562416..0000000000
--- a/test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 3259097492..0000000000
--- a/test/prism/fixtures/seattlerb/difficult2_.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-1 ? b('') : 2
-a d: 3
diff --git a/test/prism/fixtures/seattlerb/difficult3_.txt b/test/prism/fixtures/seattlerb/difficult3_.txt
deleted file mode 100644
index 9f95860b82..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3_.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (b, *c)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3_2.txt b/test/prism/fixtures/seattlerb/difficult3_2.txt
deleted file mode 100644
index 8abfe3f634..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |*a, b| }
diff --git a/test/prism/fixtures/seattlerb/difficult3_3.txt b/test/prism/fixtures/seattlerb/difficult3_3.txt
deleted file mode 100644
index 6f43ab7b1d..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3_3.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |*a, b, &c| }
diff --git a/test/prism/fixtures/seattlerb/difficult3_4.txt b/test/prism/fixtures/seattlerb/difficult3_4.txt
deleted file mode 100644
index 7070e1e964..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3_4.txt
+++ /dev/null
@@ -1 +0,0 @@
-a=b ? true: false
diff --git a/test/prism/fixtures/seattlerb/difficult3_5.txt b/test/prism/fixtures/seattlerb/difficult3_5.txt
deleted file mode 100644
index 6d52692481..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3_5.txt
+++ /dev/null
@@ -1 +0,0 @@
-f ->() { g do end }
diff --git a/test/prism/fixtures/seattlerb/difficult3__10.txt b/test/prism/fixtures/seattlerb/difficult3__10.txt
deleted file mode 100644
index 89974f5114..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__10.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (*b, c)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__11.txt b/test/prism/fixtures/seattlerb/difficult3__11.txt
deleted file mode 100644
index 911d037961..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__11.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (*)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__12.txt b/test/prism/fixtures/seattlerb/difficult3__12.txt
deleted file mode 100644
index 2405a80ec1..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__12.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (*, b)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__6.txt b/test/prism/fixtures/seattlerb/difficult3__6.txt
deleted file mode 100644
index 3a45ae86fb..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__6.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (b, *c, d)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__7.txt b/test/prism/fixtures/seattlerb/difficult3__7.txt
deleted file mode 100644
index 55272a1fc4..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__7.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (b, *)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__8.txt b/test/prism/fixtures/seattlerb/difficult3__8.txt
deleted file mode 100644
index 76740db4ff..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__8.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (b, *, c)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__9.txt b/test/prism/fixtures/seattlerb/difficult3__9.txt
deleted file mode 100644
index b65f7fd052..0000000000
--- a/test/prism/fixtures/seattlerb/difficult3__9.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, (*b)| }
diff --git a/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt b/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt
deleted file mode 100644
index 332dc8225c..0000000000
--- a/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-a
-.b
diff --git a/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt b/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt
deleted file mode 100644
index fe73f641fe..0000000000
--- a/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-..3
diff --git a/test/prism/fixtures/seattlerb/difficult6_.txt b/test/prism/fixtures/seattlerb/difficult6_.txt
deleted file mode 100644
index 7396a9a76f..0000000000
--- a/test/prism/fixtures/seattlerb/difficult6_.txt
+++ /dev/null
@@ -1 +0,0 @@
-->(a, b=nil) { p [a, b] }
diff --git a/test/prism/fixtures/seattlerb/difficult6__7.txt b/test/prism/fixtures/seattlerb/difficult6__7.txt
deleted file mode 100644
index 048358bbdc..0000000000
--- a/test/prism/fixtures/seattlerb/difficult6__7.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.b (1) {c}
diff --git a/test/prism/fixtures/seattlerb/difficult6__8.txt b/test/prism/fixtures/seattlerb/difficult6__8.txt
deleted file mode 100644
index ba1cbc235d..0000000000
--- a/test/prism/fixtures/seattlerb/difficult6__8.txt
+++ /dev/null
@@ -1 +0,0 @@
-a::b (1) {c}
diff --git a/test/prism/fixtures/seattlerb/difficult7_.txt b/test/prism/fixtures/seattlerb/difficult7_.txt
deleted file mode 100644
index 112b75c5f2..0000000000
--- a/test/prism/fixtures/seattlerb/difficult7_.txt
+++ /dev/null
@@ -1,5 +0,0 @@
- {
- 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
deleted file mode 100644
index a274e72baf..0000000000
--- a/test/prism/fixtures/seattlerb/do_bug.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 06d2a38d30..0000000000
--- a/test/prism/fixtures/seattlerb/do_lambda.txt
+++ /dev/null
@@ -1 +0,0 @@
-->() do end
diff --git a/test/prism/fixtures/seattlerb/dot2_nil__26.txt b/test/prism/fixtures/seattlerb/dot2_nil__26.txt
deleted file mode 100644
index cc070eb69f..0000000000
--- a/test/prism/fixtures/seattlerb/dot2_nil__26.txt
+++ /dev/null
@@ -1 +0,0 @@
-a..
diff --git a/test/prism/fixtures/seattlerb/dot3_nil__26.txt b/test/prism/fixtures/seattlerb/dot3_nil__26.txt
deleted file mode 100644
index 7f4aef7af7..0000000000
--- a/test/prism/fixtures/seattlerb/dot3_nil__26.txt
+++ /dev/null
@@ -1 +0,0 @@
-a...
diff --git a/test/prism/fixtures/seattlerb/dstr_evstr.txt b/test/prism/fixtures/seattlerb/dstr_evstr.txt
deleted file mode 100644
index 5fe4a858c1..0000000000
--- a/test/prism/fixtures/seattlerb/dstr_evstr.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{'a'}#{b}"
diff --git a/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt b/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt
deleted file mode 100644
index 7a55030fa8..0000000000
--- a/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt
+++ /dev/null
@@ -1 +0,0 @@
-:"#{field}"
diff --git a/test/prism/fixtures/seattlerb/dstr_lex_state.txt b/test/prism/fixtures/seattlerb/dstr_lex_state.txt
deleted file mode 100644
index 6cac1d8e95..0000000000
--- a/test/prism/fixtures/seattlerb/dstr_lex_state.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{p:a}"
diff --git a/test/prism/fixtures/seattlerb/dstr_str.txt b/test/prism/fixtures/seattlerb/dstr_str.txt
deleted file mode 100644
index 226ce2b191..0000000000
--- a/test/prism/fixtures/seattlerb/dstr_str.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{'a'} b"
diff --git a/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt b/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt
deleted file mode 100644
index e5781453c1..0000000000
--- a/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt
+++ /dev/null
@@ -1 +0,0 @@
-:"Variet\303\240"
diff --git a/test/prism/fixtures/seattlerb/dsym_to_sym.txt b/test/prism/fixtures/seattlerb/dsym_to_sym.txt
deleted file mode 100644
index 813c90342c..0000000000
--- a/test/prism/fixtures/seattlerb/dsym_to_sym.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-alias :"<<" :">>"
-
-alias :<< :>>
diff --git a/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt b/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt
deleted file mode 100644
index aae82e1207..0000000000
--- a/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 88ff599e91..0000000000
--- a/test/prism/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-h[k]=begin
- 42
- end
diff --git a/test/prism/fixtures/seattlerb/evstr_evstr.txt b/test/prism/fixtures/seattlerb/evstr_evstr.txt
deleted file mode 100644
index cf0b5ee873..0000000000
--- a/test/prism/fixtures/seattlerb/evstr_evstr.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{a}#{b}"
diff --git a/test/prism/fixtures/seattlerb/evstr_str.txt b/test/prism/fixtures/seattlerb/evstr_str.txt
deleted file mode 100644
index 5746909b19..0000000000
--- a/test/prism/fixtures/seattlerb/evstr_str.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{a} b"
diff --git a/test/prism/fixtures/seattlerb/expr_not_bang.txt b/test/prism/fixtures/seattlerb/expr_not_bang.txt
deleted file mode 100644
index 6ed80c76d3..0000000000
--- a/test/prism/fixtures/seattlerb/expr_not_bang.txt
+++ /dev/null
@@ -1 +0,0 @@
-! a b
diff --git a/test/prism/fixtures/seattlerb/f_kw.txt b/test/prism/fixtures/seattlerb/f_kw.txt
deleted file mode 100644
index 4dd42662b8..0000000000
--- a/test/prism/fixtures/seattlerb/f_kw.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2e1e258ff0..0000000000
--- a/test/prism/fixtures/seattlerb/f_kw__required.txt
+++ /dev/null
@@ -1 +0,0 @@
-def x k:; end
diff --git a/test/prism/fixtures/seattlerb/flip2_env_lvar.txt b/test/prism/fixtures/seattlerb/flip2_env_lvar.txt
deleted file mode 100644
index 619b2c915e..0000000000
--- a/test/prism/fixtures/seattlerb/flip2_env_lvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6a62d4a308..0000000000
--- a/test/prism/fixtures/seattlerb/float_with_if_modifier.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index cfbcb2a11d..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 0cc5b35fd5..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-" 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
deleted file mode 100644
index 2c386cc6a9..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 235a041e90..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index c230b12f65..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_comma_arg.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-[" some text
-",]
-
-[<<-FILE,
- some text
-FILE
-]
diff --git a/test/prism/fixtures/seattlerb/heredoc_lineno.txt b/test/prism/fixtures/seattlerb/heredoc_lineno.txt
deleted file mode 100644
index 73a2e3806b..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_lineno.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 508d6d3c05..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_nested.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-[<<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
deleted file mode 100644
index e630ff62b4..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 61b62157db..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 0d89134c87..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 4602d757fb..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-<<~A
-A
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt
deleted file mode 100644
index 47ff3c9070..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 7076f6ef71..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-<<~A
-a
-A
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt
deleted file mode 100644
index b193f0473b..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 5b75dd2b59..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 3f9198296d..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 12c8fac126..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<END\
-blah
-END
-.strip
diff --git a/test/prism/fixtures/seattlerb/heredoc_unicode.txt b/test/prism/fixtures/seattlerb/heredoc_unicode.txt
deleted file mode 100644
index 216a5cfe24..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_unicode.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<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
deleted file mode 100644
index cb4967d154..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-<<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
deleted file mode 100644
index 75ed936b5d..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-<<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
deleted file mode 100644
index 1c58c05cc5..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<'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
deleted file mode 100644
index 706cb0d5c0..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-<<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
deleted file mode 100644
index 8ed84799b1..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-<<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
deleted file mode 100644
index 250e606f45..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<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
deleted file mode 100644
index 12f97aff5e..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<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
deleted file mode 100644
index f94c2c9e27..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-<<-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
deleted file mode 100644
index 468ba85cf7..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-<<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
deleted file mode 100644
index e973eff110..0000000000
--- a/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-<<EOS
-
-
-\r
-EOS
-
diff --git a/test/prism/fixtures/seattlerb/if_elsif.txt b/test/prism/fixtures/seattlerb/if_elsif.txt
deleted file mode 100644
index bc1c0a2b3d..0000000000
--- a/test/prism/fixtures/seattlerb/if_elsif.txt
+++ /dev/null
@@ -1 +0,0 @@
-if 1; elsif 2; end
diff --git a/test/prism/fixtures/seattlerb/if_symbol.txt b/test/prism/fixtures/seattlerb/if_symbol.txt
deleted file mode 100644
index 8d6e958ede..0000000000
--- a/test/prism/fixtures/seattlerb/if_symbol.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 40db7f868b..0000000000
--- a/test/prism/fixtures/seattlerb/in_expr_no_case.txt
+++ /dev/null
@@ -1 +0,0 @@
-'woot' in String
diff --git a/test/prism/fixtures/seattlerb/index_0.txt b/test/prism/fixtures/seattlerb/index_0.txt
deleted file mode 100644
index 050d4566ba..0000000000
--- a/test/prism/fixtures/seattlerb/index_0.txt
+++ /dev/null
@@ -1 +0,0 @@
-a[] = b
diff --git a/test/prism/fixtures/seattlerb/index_0_opasgn.txt b/test/prism/fixtures/seattlerb/index_0_opasgn.txt
deleted file mode 100644
index 7189f0c3ea..0000000000
--- a/test/prism/fixtures/seattlerb/index_0_opasgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-a[] += b
diff --git a/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt b/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt
deleted file mode 100644
index bf2f621e92..0000000000
--- a/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index f4c7cb9662..0000000000
--- a/test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-%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
deleted file mode 100644
index d52b4789cf..0000000000
--- a/test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-%W(
-a
-b
-)
-1
diff --git a/test/prism/fixtures/seattlerb/iter_args_1.txt b/test/prism/fixtures/seattlerb/iter_args_1.txt
deleted file mode 100644
index c890ef62c3..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 3f558c5392..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_10_1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 4158e79d14..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_10_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index f86175c1a0..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_11_1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e4b017e44a..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_11_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 84dd744243..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_2__19.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |(a, b)| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_3.txt b/test/prism/fixtures/seattlerb/iter_args_3.txt
deleted file mode 100644
index 261968ff13..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_3.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 7db4d43ad3..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_4.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, *b, c| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_5.txt b/test/prism/fixtures/seattlerb/iter_args_5.txt
deleted file mode 100644
index 088fcdfcc5..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_5.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a, &b| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_6.txt b/test/prism/fixtures/seattlerb/iter_args_6.txt
deleted file mode 100644
index e980ec064b..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_6.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e1dbf4b312..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_7_1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e46e78e00e..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_7_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a0ec82ea5b..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_8_1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a1839fe706..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_8_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 13e5b20fe7..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_9_1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 83f6e1e029..0000000000
--- a/test/prism/fixtures/seattlerb/iter_args_9_2.txt
+++ /dev/null
@@ -1 +0,0 @@
-f { |a = 42, b, &c| }
diff --git a/test/prism/fixtures/seattlerb/iter_kwarg.txt b/test/prism/fixtures/seattlerb/iter_kwarg.txt
deleted file mode 100644
index d4296cad76..0000000000
--- a/test/prism/fixtures/seattlerb/iter_kwarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b: 1| }
diff --git a/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt b/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt
deleted file mode 100644
index dd0ea13a6f..0000000000
--- a/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-a { |b: 1, **c| }
diff --git a/test/prism/fixtures/seattlerb/label_vs_string.txt b/test/prism/fixtures/seattlerb/label_vs_string.txt
deleted file mode 100644
index 27ba8b64de..0000000000
--- a/test/prism/fixtures/seattlerb/label_vs_string.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-_buf << ':
-'
diff --git a/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt b/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt
deleted file mode 100644
index bbf663a46a..0000000000
--- a/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 0dad496c28..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 3f63c0b748..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0e86f1587d..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a = b 1 rescue 2
diff --git a/test/prism/fixtures/seattlerb/lasgn_command.txt b/test/prism/fixtures/seattlerb/lasgn_command.txt
deleted file mode 100644
index aca35b880c..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_command.txt
+++ /dev/null
@@ -1 +0,0 @@
-a = b.c 1
diff --git a/test/prism/fixtures/seattlerb/lasgn_env.txt b/test/prism/fixtures/seattlerb/lasgn_env.txt
deleted file mode 100644
index aec10273e5..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_env.txt
+++ /dev/null
@@ -1 +0,0 @@
-a = 42
diff --git a/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt b/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt
deleted file mode 100644
index 2fa8471c01..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt
+++ /dev/null
@@ -1 +0,0 @@
-@a = 42
diff --git a/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt b/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt
deleted file mode 100644
index 5147131852..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-a = b = c 1
diff --git a/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt b/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt
deleted file mode 100644
index bb378ca680..0000000000
--- a/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-a = b, *c, d
diff --git a/test/prism/fixtures/seattlerb/magic_encoding_comment.txt b/test/prism/fixtures/seattlerb/magic_encoding_comment.txt
deleted file mode 100644
index a02711ea05..0000000000
--- a/test/prism/fixtures/seattlerb/magic_encoding_comment.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# 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
deleted file mode 100644
index b796a742ed..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-*, a = b
diff --git a/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt b/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt
deleted file mode 100644
index e0919793d4..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a, b::c = d
diff --git a/test/prism/fixtures/seattlerb/masgn_arg_ident.txt b/test/prism/fixtures/seattlerb/masgn_arg_ident.txt
deleted file mode 100644
index 45f248d854..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_arg_ident.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 05fe7c4d5f..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-a, *b, c = d
diff --git a/test/prism/fixtures/seattlerb/masgn_colon2.txt b/test/prism/fixtures/seattlerb/masgn_colon2.txt
deleted file mode 100644
index 4e4f838d7d..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_colon2.txt
+++ /dev/null
@@ -1 +0,0 @@
-a, b::C = 1, 2
diff --git a/test/prism/fixtures/seattlerb/masgn_colon3.txt b/test/prism/fixtures/seattlerb/masgn_colon3.txt
deleted file mode 100644
index 46098ba8c5..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_colon3.txt
+++ /dev/null
@@ -1 +0,0 @@
-::A, ::B = 1, 2
diff --git a/test/prism/fixtures/seattlerb/masgn_command_call.txt b/test/prism/fixtures/seattlerb/masgn_command_call.txt
deleted file mode 100644
index 6da01e8a31..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-a, = b.c 1
diff --git a/test/prism/fixtures/seattlerb/masgn_double_paren.txt b/test/prism/fixtures/seattlerb/masgn_double_paren.txt
deleted file mode 100644
index ffac0a85a3..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_double_paren.txt
+++ /dev/null
@@ -1 +0,0 @@
-((a,b))=c
diff --git a/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt b/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt
deleted file mode 100644
index 2419ef1671..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-*a = 1, 2, 3
diff --git a/test/prism/fixtures/seattlerb/masgn_paren.txt b/test/prism/fixtures/seattlerb/masgn_paren.txt
deleted file mode 100644
index 3889b9ff48..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_paren.txt
+++ /dev/null
@@ -1 +0,0 @@
-(a, b) = c.d
diff --git a/test/prism/fixtures/seattlerb/masgn_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_splat_arg.txt
deleted file mode 100644
index a7c91425b0..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_splat_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-*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
deleted file mode 100644
index 46196bd703..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-*a, b, c = d
diff --git a/test/prism/fixtures/seattlerb/masgn_star.txt b/test/prism/fixtures/seattlerb/masgn_star.txt
deleted file mode 100644
index c5eea37de2..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_star.txt
+++ /dev/null
@@ -1 +0,0 @@
-* = 1
diff --git a/test/prism/fixtures/seattlerb/masgn_var_star_var.txt b/test/prism/fixtures/seattlerb/masgn_var_star_var.txt
deleted file mode 100644
index 04089c36ac..0000000000
--- a/test/prism/fixtures/seattlerb/masgn_var_star_var.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a7d1035ae3..0000000000
--- a/test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 86f0fbdfc9..0000000000
--- a/test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1a155fba12..0000000000
--- a/test/prism/fixtures/seattlerb/method_call_trailing_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.f(1,)
diff --git a/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt
deleted file mode 100644
index 7389b95563..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-a, b, c, * = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_back_splat.txt b/test/prism/fixtures/seattlerb/mlhs_back_splat.txt
deleted file mode 100644
index ec5d23889a..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_back_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 67e569438c..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-*, x, y, z = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_front_splat.txt b/test/prism/fixtures/seattlerb/mlhs_front_splat.txt
deleted file mode 100644
index dabadc382d..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_front_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-*s, x, y, z = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_keyword.txt b/test/prism/fixtures/seattlerb/mlhs_keyword.txt
deleted file mode 100644
index 899e7f8ed3..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_keyword.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.!=(true, true)
diff --git a/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt
deleted file mode 100644
index a70a7e531b..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2d23fd3966..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_mid_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index b4c79ae32e..0000000000
--- a/test/prism/fixtures/seattlerb/mlhs_rescue.txt
+++ /dev/null
@@ -1 +0,0 @@
-a, b = f rescue 42
diff --git a/test/prism/fixtures/seattlerb/module_comments.txt b/test/prism/fixtures/seattlerb/module_comments.txt
deleted file mode 100644
index cecb717c5b..0000000000
--- a/test/prism/fixtures/seattlerb/module_comments.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-# 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
deleted file mode 100644
index 21530307d2..0000000000
--- a/test/prism/fixtures/seattlerb/multiline_hash_declaration.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 1e14673f4e..0000000000
--- a/test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-%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
deleted file mode 100644
index 79c1418770..0000000000
--- a/test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-%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
deleted file mode 100644
index 92c989cb0d..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 89cfccda66..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2bfced81fe..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a567f60e83..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0784b49167..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c0f16eb3c1..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 69057abf04..0000000000
--- a/test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 8d7d06c688..0000000000
--- a/test/prism/fixtures/seattlerb/parse_def_special_name.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1fd9bb7327..0000000000
--- a/test/prism/fixtures/seattlerb/parse_if_not_canonical.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 1fd9bb7327..0000000000
--- a/test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 21664649db..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_block.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index f55ced714f..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 6f1fee62a0..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-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
deleted file mode 100644
index b00de34dc0..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 73785eb794..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 6f136e6d6f..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 7900afd4b8..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_call_no_args.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 244a8e862b..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_defn_complex.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 373ca7fbec..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 10f004a149..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-def f a
-end
diff --git a/test/prism/fixtures/seattlerb/parse_line_dot2.txt b/test/prism/fixtures/seattlerb/parse_line_dot2.txt
deleted file mode 100644
index 61c7554221..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_dot2.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index b3e1e5aaf9..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_dot2_open.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-0..
-; a..
-; c
diff --git a/test/prism/fixtures/seattlerb/parse_line_dot3.txt b/test/prism/fixtures/seattlerb/parse_line_dot3.txt
deleted file mode 100644
index d1866b41de..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_dot3.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 38e7634b21..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_dot3_open.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 29c1754915..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-"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
deleted file mode 100644
index e4dbd7bcb2..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-"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
deleted file mode 100644
index c1d91a51c4..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-"a"\
-"#{b}"
diff --git a/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt b/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt
deleted file mode 100644
index 25f8c90a06..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-:s1 => 1,
-}
diff --git a/test/prism/fixtures/seattlerb/parse_line_heredoc.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc.txt
deleted file mode 100644
index 201339534c..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_heredoc.txt
+++ /dev/null
@@ -1,5 +0,0 @@
- 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
deleted file mode 100644
index d50844db4b..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<-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
deleted file mode 100644
index 3fbf0f2c26..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-<<-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
deleted file mode 100644
index 5dab9cf4e7..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt
+++ /dev/null
@@ -1,5 +0,0 @@
- 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
deleted file mode 100644
index bf1b33c8a2..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 25e9ea1c67..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index cdefb3c9b7..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_multiline_str.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-"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
deleted file mode 100644
index a179ba8c9c..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-"a\nb"
-1
diff --git a/test/prism/fixtures/seattlerb/parse_line_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_newlines.txt
deleted file mode 100644
index 28b0c286e8..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_newlines.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-true
-
-
diff --git a/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt b/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt
deleted file mode 100644
index f2691c2ce4..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt
+++ /dev/null
@@ -1,4 +0,0 @@
- foo +=
- bar
- baz
-
diff --git a/test/prism/fixtures/seattlerb/parse_line_postexe.txt b/test/prism/fixtures/seattlerb/parse_line_postexe.txt
deleted file mode 100644
index fd8b318d19..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_postexe.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-END {
-foo
-}
diff --git a/test/prism/fixtures/seattlerb/parse_line_preexe.txt b/test/prism/fixtures/seattlerb/parse_line_preexe.txt
deleted file mode 100644
index b3eda77ebc..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_preexe.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-BEGIN {
-foo
-}
diff --git a/test/prism/fixtures/seattlerb/parse_line_rescue.txt b/test/prism/fixtures/seattlerb/parse_line_rescue.txt
deleted file mode 100644
index a583160ce2..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_rescue.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 81021c2644..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_return.txt
+++ /dev/null
@@ -1,6 +0,0 @@
- 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
deleted file mode 100644
index b2b6bb8234..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 590d0abd14..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_to_ary.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index afa826fb50..0000000000
--- a/test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 649c109ea1..0000000000
--- a/test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 741cd4ffd1..0000000000
--- a/test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-1[2,]
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_019.txt b/test/prism/fixtures/seattlerb/parse_pattern_019.txt
deleted file mode 100644
index 1e8a75902d..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_019.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index a6a0ac6c1c..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_044.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index b7cf769f50..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_051.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index bd7537098e..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_058.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index eb1b3cd8ab..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_058_2.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index f43dff8959..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_069.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index bb947605b3..0000000000
--- a/test/prism/fixtures/seattlerb/parse_pattern_076.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 4de38968dc..0000000000
--- a/test/prism/fixtures/seattlerb/parse_until_not_canonical.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 4de38968dc..0000000000
--- a/test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 5aa464167f..0000000000
--- a/test/prism/fixtures/seattlerb/parse_while_not_canonical.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 5aa464167f..0000000000
--- a/test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-while not var.nil?
- 'foo'
-end
diff --git a/test/prism/fixtures/seattlerb/pctW_lineno.txt b/test/prism/fixtures/seattlerb/pctW_lineno.txt
deleted file mode 100644
index b222ff0174..0000000000
--- a/test/prism/fixtures/seattlerb/pctW_lineno.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-%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
deleted file mode 100644
index 4420560d2b..0000000000
--- a/test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-%q{ \
-}
diff --git a/test/prism/fixtures/seattlerb/pct_nl.txt b/test/prism/fixtures/seattlerb/pct_nl.txt
deleted file mode 100644
index 2cee1cdd44..0000000000
--- a/test/prism/fixtures/seattlerb/pct_nl.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 4e084661bf..0000000000
--- a/test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-%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
deleted file mode 100644
index e692cc434f..0000000000
--- a/test/prism/fixtures/seattlerb/pipe_semicolon.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.b do | ; c | end
diff --git a/test/prism/fixtures/seattlerb/pipe_space.txt b/test/prism/fixtures/seattlerb/pipe_space.txt
deleted file mode 100644
index 7f0df799b9..0000000000
--- a/test/prism/fixtures/seattlerb/pipe_space.txt
+++ /dev/null
@@ -1 +0,0 @@
-a.b do | | end
diff --git a/test/prism/fixtures/seattlerb/qWords_space.txt b/test/prism/fixtures/seattlerb/qWords_space.txt
deleted file mode 100644
index a8299ba3f8..0000000000
--- a/test/prism/fixtures/seattlerb/qWords_space.txt
+++ /dev/null
@@ -1 +0,0 @@
-%W( )
diff --git a/test/prism/fixtures/seattlerb/qsymbols.txt b/test/prism/fixtures/seattlerb/qsymbols.txt
deleted file mode 100644
index cb9ff09ae0..0000000000
--- a/test/prism/fixtures/seattlerb/qsymbols.txt
+++ /dev/null
@@ -1 +0,0 @@
-%I(a b c)
diff --git a/test/prism/fixtures/seattlerb/qsymbols_empty.txt b/test/prism/fixtures/seattlerb/qsymbols_empty.txt
deleted file mode 100644
index 10a3279907..0000000000
--- a/test/prism/fixtures/seattlerb/qsymbols_empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-%I()
diff --git a/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt b/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt
deleted file mode 100644
index 819f16ad06..0000000000
--- a/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt
+++ /dev/null
@@ -1 +0,0 @@
-%I( )
diff --git a/test/prism/fixtures/seattlerb/qsymbols_interp.txt b/test/prism/fixtures/seattlerb/qsymbols_interp.txt
deleted file mode 100644
index 2f34883867..0000000000
--- a/test/prism/fixtures/seattlerb/qsymbols_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-%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
deleted file mode 100644
index 4f1295ef18..0000000000
--- a/test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-puts 'a': {}
diff --git a/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt b/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt
deleted file mode 100644
index c6a946723d..0000000000
--- a/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt
+++ /dev/null
@@ -1 +0,0 @@
-{ 'a': :b }
diff --git a/test/prism/fixtures/seattlerb/qw_escape.txt b/test/prism/fixtures/seattlerb/qw_escape.txt
deleted file mode 100644
index a94a0e5dcb..0000000000
--- a/test/prism/fixtures/seattlerb/qw_escape.txt
+++ /dev/null
@@ -1 +0,0 @@
-%q(\')
diff --git a/test/prism/fixtures/seattlerb/qw_escape_term.txt b/test/prism/fixtures/seattlerb/qw_escape_term.txt
deleted file mode 100644
index 9734fc3421..0000000000
--- a/test/prism/fixtures/seattlerb/qw_escape_term.txt
+++ /dev/null
@@ -1 +0,0 @@
-%q|blah blah \| blah blah|
diff --git a/test/prism/fixtures/seattlerb/qwords_empty.txt b/test/prism/fixtures/seattlerb/qwords_empty.txt
deleted file mode 100644
index 69cc6679d6..0000000000
--- a/test/prism/fixtures/seattlerb/qwords_empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-%w()
diff --git a/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt b/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt
deleted file mode 100644
index 427b94cc4d..0000000000
--- a/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt
+++ /dev/null
@@ -1 +0,0 @@
-?\u{00a0}
diff --git a/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt b/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt
deleted file mode 100644
index 71aa7a4347..0000000000
--- a/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt
+++ /dev/null
@@ -1 +0,0 @@
-?\u00a0
diff --git a/test/prism/fixtures/seattlerb/regexp.txt b/test/prism/fixtures/seattlerb/regexp.txt
deleted file mode 100644
index bc06458c5c..0000000000
--- a/test/prism/fixtures/seattlerb/regexp.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-/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
deleted file mode 100644
index 1fd9207c66..0000000000
--- a/test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt
+++ /dev/null
@@ -1 +0,0 @@
-/\cC\d/
diff --git a/test/prism/fixtures/seattlerb/regexp_esc_u.txt b/test/prism/fixtures/seattlerb/regexp_esc_u.txt
deleted file mode 100644
index b91704fb0a..0000000000
--- a/test/prism/fixtures/seattlerb/regexp_esc_u.txt
+++ /dev/null
@@ -1 +0,0 @@
-/[\u0021-\u0027]/
diff --git a/test/prism/fixtures/seattlerb/regexp_escape_extended.txt b/test/prism/fixtures/seattlerb/regexp_escape_extended.txt
deleted file mode 100644
index 73dcbab69c..0000000000
--- a/test/prism/fixtures/seattlerb/regexp_escape_extended.txt
+++ /dev/null
@@ -1 +0,0 @@
-/\“/
diff --git a/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt b/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt
deleted file mode 100644
index 5a02bd92ca..0000000000
--- a/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-/\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
deleted file mode 100644
index 453bcbb33b..0000000000
--- a/test/prism/fixtures/seattlerb/required_kwarg_no_value.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 7049be66c5..0000000000
--- a/test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 5f16ec2f15..0000000000
--- a/test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index d04215eb48..0000000000
--- a/test/prism/fixtures/seattlerb/rescue_do_end_raised.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 4b377511f0..0000000000
--- a/test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c6e834aa1e..0000000000
--- a/test/prism/fixtures/seattlerb/rescue_in_block.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-blah do
-rescue
- stuff
-end
diff --git a/test/prism/fixtures/seattlerb/rescue_parens.txt b/test/prism/fixtures/seattlerb/rescue_parens.txt
deleted file mode 100644
index f0eb4db417..0000000000
--- a/test/prism/fixtures/seattlerb/rescue_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-a (b rescue c)
diff --git a/test/prism/fixtures/seattlerb/return_call_assocs.txt b/test/prism/fixtures/seattlerb/return_call_assocs.txt
deleted file mode 100644
index 34ea778f17..0000000000
--- a/test/prism/fixtures/seattlerb/return_call_assocs.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index ca581031e2..0000000000
--- a/test/prism/fixtures/seattlerb/rhs_asgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-42 => n
diff --git a/test/prism/fixtures/seattlerb/ruby21_numbers.txt b/test/prism/fixtures/seattlerb/ruby21_numbers.txt
deleted file mode 100644
index 34ceb63a0c..0000000000
--- a/test/prism/fixtures/seattlerb/ruby21_numbers.txt
+++ /dev/null
@@ -1 +0,0 @@
-[1i, 2r, 3ri]
diff --git a/test/prism/fixtures/seattlerb/safe_attrasgn.txt b/test/prism/fixtures/seattlerb/safe_attrasgn.txt
deleted file mode 100644
index 1279e02cfc..0000000000
--- a/test/prism/fixtures/seattlerb/safe_attrasgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b = 1
diff --git a/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt b/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt
deleted file mode 100644
index 3a17ac6bcf..0000000000
--- a/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.B = 1
diff --git a/test/prism/fixtures/seattlerb/safe_call.txt b/test/prism/fixtures/seattlerb/safe_call.txt
deleted file mode 100644
index 8ecd27e0fe..0000000000
--- a/test/prism/fixtures/seattlerb/safe_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b
diff --git a/test/prism/fixtures/seattlerb/safe_call_after_newline.txt b/test/prism/fixtures/seattlerb/safe_call_after_newline.txt
deleted file mode 100644
index 58e3fba554..0000000000
--- a/test/prism/fixtures/seattlerb/safe_call_after_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-a
-&.b
diff --git a/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt b/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt
deleted file mode 100644
index 5def076640..0000000000
--- a/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.()
diff --git a/test/prism/fixtures/seattlerb/safe_call_newline.txt b/test/prism/fixtures/seattlerb/safe_call_newline.txt
deleted file mode 100644
index 8778b46585..0000000000
--- a/test/prism/fixtures/seattlerb/safe_call_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-a&.b
-
diff --git a/test/prism/fixtures/seattlerb/safe_call_operator.txt b/test/prism/fixtures/seattlerb/safe_call_operator.txt
deleted file mode 100644
index f3fe2b0392..0000000000
--- a/test/prism/fixtures/seattlerb/safe_call_operator.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.> 1
diff --git a/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt b/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt
deleted file mode 100644
index d3b07b77b2..0000000000
--- a/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-c = a&.b
-
diff --git a/test/prism/fixtures/seattlerb/safe_calls.txt b/test/prism/fixtures/seattlerb/safe_calls.txt
deleted file mode 100644
index eafeace500..0000000000
--- a/test/prism/fixtures/seattlerb/safe_calls.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b&.c(1)
diff --git a/test/prism/fixtures/seattlerb/safe_op_asgn.txt b/test/prism/fixtures/seattlerb/safe_op_asgn.txt
deleted file mode 100644
index 8915a1cccf..0000000000
--- a/test/prism/fixtures/seattlerb/safe_op_asgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b += x 1
diff --git a/test/prism/fixtures/seattlerb/safe_op_asgn2.txt b/test/prism/fixtures/seattlerb/safe_op_asgn2.txt
deleted file mode 100644
index 0960b2548b..0000000000
--- a/test/prism/fixtures/seattlerb/safe_op_asgn2.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 421989c76f..0000000000
--- a/test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index f16bed4ccf..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt
+++ /dev/null
@@ -1 +0,0 @@
-->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
deleted file mode 100644
index 87a7c5dad3..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt
+++ /dev/null
@@ -1 +0,0 @@
-->(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
deleted file mode 100644
index 5e9e3f5527..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_block_iter_call.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 7235394751..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 74d9e0a328..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_block_kw.txt
+++ /dev/null
@@ -1 +0,0 @@
--> (k:42) { }
diff --git a/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt b/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt
deleted file mode 100644
index bd16ffa73c..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt
+++ /dev/null
@@ -1 +0,0 @@
--> (k:) { }
diff --git a/test/prism/fixtures/seattlerb/stabby_proc_scope.txt b/test/prism/fixtures/seattlerb/stabby_proc_scope.txt
deleted file mode 100644
index 1f7f9ff52b..0000000000
--- a/test/prism/fixtures/seattlerb/stabby_proc_scope.txt
+++ /dev/null
@@ -1 +0,0 @@
-->(a; b) {}
diff --git a/test/prism/fixtures/seattlerb/str_backslashes.txt b/test/prism/fixtures/seattlerb/str_backslashes.txt
deleted file mode 100644
index 5fd6da361b..0000000000
--- a/test/prism/fixtures/seattlerb/str_backslashes.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2b022a55f6..0000000000
--- a/test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e439225344..0000000000
--- a/test/prism/fixtures/seattlerb/str_double_escaped_newline.txt
+++ /dev/null
@@ -1 +0,0 @@
-a "\n";b
diff --git a/test/prism/fixtures/seattlerb/str_double_newline.txt b/test/prism/fixtures/seattlerb/str_double_newline.txt
deleted file mode 100644
index 2d439506ca..0000000000
--- a/test/prism/fixtures/seattlerb/str_double_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-a "
-";b
diff --git a/test/prism/fixtures/seattlerb/str_evstr.txt b/test/prism/fixtures/seattlerb/str_evstr.txt
deleted file mode 100644
index 86c6d1526d..0000000000
--- a/test/prism/fixtures/seattlerb/str_evstr.txt
+++ /dev/null
@@ -1 +0,0 @@
-"a #{b}"
diff --git a/test/prism/fixtures/seattlerb/str_evstr_escape.txt b/test/prism/fixtures/seattlerb/str_evstr_escape.txt
deleted file mode 100644
index 517dfd4778..0000000000
--- a/test/prism/fixtures/seattlerb/str_evstr_escape.txt
+++ /dev/null
@@ -1 +0,0 @@
-"a #{b}\302\275"
diff --git a/test/prism/fixtures/seattlerb/str_heredoc_interp.txt b/test/prism/fixtures/seattlerb/str_heredoc_interp.txt
deleted file mode 100644
index aa2613008c..0000000000
--- a/test/prism/fixtures/seattlerb/str_heredoc_interp.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-<<""
-#{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
deleted file mode 100644
index fe6637678f..0000000000
--- a/test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{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
deleted file mode 100644
index f4eb3971bb..0000000000
--- a/test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-"\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
deleted file mode 100644
index 9c8f702000..0000000000
--- a/test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-"\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
deleted file mode 100644
index 1f3d0613e5..0000000000
--- a/test/prism/fixtures/seattlerb/str_pct_Q_nested.txt
+++ /dev/null
@@ -1 +0,0 @@
-%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
deleted file mode 100644
index cb12415215..0000000000
--- a/test/prism/fixtures/seattlerb/str_pct_nested_nested.txt
+++ /dev/null
@@ -1 +0,0 @@
-%{ { #{ "#{1}" } } }
diff --git a/test/prism/fixtures/seattlerb/str_pct_q.txt b/test/prism/fixtures/seattlerb/str_pct_q.txt
deleted file mode 100644
index 65d71197c9..0000000000
--- a/test/prism/fixtures/seattlerb/str_pct_q.txt
+++ /dev/null
@@ -1 +0,0 @@
-%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
deleted file mode 100644
index 2ff0aec111..0000000000
--- a/test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 5abb8d6334..0000000000
--- a/test/prism/fixtures/seattlerb/str_single_escaped_newline.txt
+++ /dev/null
@@ -1 +0,0 @@
-a '\n';b
diff --git a/test/prism/fixtures/seattlerb/str_single_newline.txt b/test/prism/fixtures/seattlerb/str_single_newline.txt
deleted file mode 100644
index 1033cc7e96..0000000000
--- a/test/prism/fixtures/seattlerb/str_single_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-a '
-';b
diff --git a/test/prism/fixtures/seattlerb/str_str.txt b/test/prism/fixtures/seattlerb/str_str.txt
deleted file mode 100644
index 388d777dc2..0000000000
--- a/test/prism/fixtures/seattlerb/str_str.txt
+++ /dev/null
@@ -1 +0,0 @@
-"a #{'b'}"
diff --git a/test/prism/fixtures/seattlerb/str_str_str.txt b/test/prism/fixtures/seattlerb/str_str_str.txt
deleted file mode 100644
index d64e01dc5d..0000000000
--- a/test/prism/fixtures/seattlerb/str_str_str.txt
+++ /dev/null
@@ -1 +0,0 @@
-"a #{'b'} c"
diff --git a/test/prism/fixtures/seattlerb/super_arg.txt b/test/prism/fixtures/seattlerb/super_arg.txt
deleted file mode 100644
index 1b19ecd51c..0000000000
--- a/test/prism/fixtures/seattlerb/super_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-super 42
diff --git a/test/prism/fixtures/seattlerb/symbol_empty.txt b/test/prism/fixtures/seattlerb/symbol_empty.txt
deleted file mode 100644
index cbb260bb4e..0000000000
--- a/test/prism/fixtures/seattlerb/symbol_empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-:''
diff --git a/test/prism/fixtures/seattlerb/symbol_list.txt b/test/prism/fixtures/seattlerb/symbol_list.txt
deleted file mode 100644
index d357195184..0000000000
--- a/test/prism/fixtures/seattlerb/symbol_list.txt
+++ /dev/null
@@ -1 +0,0 @@
-%I[#{a} #{b}]
diff --git a/test/prism/fixtures/seattlerb/symbols.txt b/test/prism/fixtures/seattlerb/symbols.txt
deleted file mode 100644
index 3ec930ce66..0000000000
--- a/test/prism/fixtures/seattlerb/symbols.txt
+++ /dev/null
@@ -1 +0,0 @@
-%i(a b c)
diff --git a/test/prism/fixtures/seattlerb/symbols_empty.txt b/test/prism/fixtures/seattlerb/symbols_empty.txt
deleted file mode 100644
index 840948efb2..0000000000
--- a/test/prism/fixtures/seattlerb/symbols_empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-%i()
diff --git a/test/prism/fixtures/seattlerb/symbols_empty_space.txt b/test/prism/fixtures/seattlerb/symbols_empty_space.txt
deleted file mode 100644
index 16c2e68a2b..0000000000
--- a/test/prism/fixtures/seattlerb/symbols_empty_space.txt
+++ /dev/null
@@ -1 +0,0 @@
-%i( )
diff --git a/test/prism/fixtures/seattlerb/symbols_interp.txt b/test/prism/fixtures/seattlerb/symbols_interp.txt
deleted file mode 100644
index 63116eb632..0000000000
--- a/test/prism/fixtures/seattlerb/symbols_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-%i(a b#{1+1} c)
diff --git a/test/prism/fixtures/seattlerb/thingy.txt b/test/prism/fixtures/seattlerb/thingy.txt
deleted file mode 100644
index 5aa598c4be..0000000000
--- a/test/prism/fixtures/seattlerb/thingy.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-f.(42)
-
-f::(42)
diff --git a/test/prism/fixtures/seattlerb/uminus_float.txt b/test/prism/fixtures/seattlerb/uminus_float.txt
deleted file mode 100644
index 1344bfd9db..0000000000
--- a/test/prism/fixtures/seattlerb/uminus_float.txt
+++ /dev/null
@@ -1 +0,0 @@
--0.0
diff --git a/test/prism/fixtures/seattlerb/unary_minus.txt b/test/prism/fixtures/seattlerb/unary_minus.txt
deleted file mode 100644
index 66af866f85..0000000000
--- a/test/prism/fixtures/seattlerb/unary_minus.txt
+++ /dev/null
@@ -1 +0,0 @@
--a
diff --git a/test/prism/fixtures/seattlerb/unary_plus.txt b/test/prism/fixtures/seattlerb/unary_plus.txt
deleted file mode 100644
index daea40b71e..0000000000
--- a/test/prism/fixtures/seattlerb/unary_plus.txt
+++ /dev/null
@@ -1 +0,0 @@
-+a
diff --git a/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt b/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt
deleted file mode 100644
index 752331df47..0000000000
--- a/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt
+++ /dev/null
@@ -1 +0,0 @@
-+:a
diff --git a/test/prism/fixtures/seattlerb/unary_tilde.txt b/test/prism/fixtures/seattlerb/unary_tilde.txt
deleted file mode 100644
index f0a507b437..0000000000
--- a/test/prism/fixtures/seattlerb/unary_tilde.txt
+++ /dev/null
@@ -1 +0,0 @@
-~a
diff --git a/test/prism/fixtures/seattlerb/utf8_bom.txt b/test/prism/fixtures/seattlerb/utf8_bom.txt
deleted file mode 100644
index c8e9e1cbae..0000000000
--- a/test/prism/fixtures/seattlerb/utf8_bom.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/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
deleted file mode 100644
index 6b79f5dad0..0000000000
--- a/test/prism/fixtures/seattlerb/when_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-case a; when *b then; end
diff --git a/test/prism/fixtures/seattlerb/words_interp.txt b/test/prism/fixtures/seattlerb/words_interp.txt
deleted file mode 100644
index f71486495b..0000000000
--- a/test/prism/fixtures/seattlerb/words_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-%W(#{1}b)
diff --git a/test/prism/fixtures/seattlerb/yield_arg.txt b/test/prism/fixtures/seattlerb/yield_arg.txt
deleted file mode 100644
index 7e752f62e2..0000000000
--- a/test/prism/fixtures/seattlerb/yield_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-yield 42
diff --git a/test/prism/fixtures/seattlerb/yield_call_assocs.txt b/test/prism/fixtures/seattlerb/yield_call_assocs.txt
deleted file mode 100644
index 95963dfcf9..0000000000
--- a/test/prism/fixtures/seattlerb/yield_call_assocs.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-yield 1, :z => 1
-
-yield 1, :z => 1, :w => 2
-
-yield y :z=>1
-
-yield y z:1
-
-yield y(z:1)
-
-yield y(z=>1)
diff --git a/test/prism/fixtures/seattlerb/yield_empty_parens.txt b/test/prism/fixtures/seattlerb/yield_empty_parens.txt
deleted file mode 100644
index cff86b243a..0000000000
--- a/test/prism/fixtures/seattlerb/yield_empty_parens.txt
+++ /dev/null
@@ -1 +0,0 @@
-yield()
diff --git a/test/prism/fixtures/single_quote_heredocs.txt b/test/prism/fixtures/single_quote_heredocs.txt
deleted file mode 100644
index 0122b2726c..0000000000
--- a/test/prism/fixtures/single_quote_heredocs.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-<<-'EOS'
- cd L:\Work\MG3710IQPro\Develop
-EOS
diff --git a/test/prism/fixtures/spanning_heredoc.txt b/test/prism/fixtures/spanning_heredoc.txt
deleted file mode 100644
index d09cb11b1f..0000000000
--- a/test/prism/fixtures/spanning_heredoc.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-# 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/strings.txt b/test/prism/fixtures/strings.txt
deleted file mode 100644
index 2ce8b738a3..0000000000
--- a/test/prism/fixtures/strings.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-%%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
deleted file mode 100644
index cd7aaf992e..0000000000
--- a/test/prism/fixtures/super.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-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
deleted file mode 100644
index 7563eb874f..0000000000
--- a/test/prism/fixtures/symbols.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-:'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
deleted file mode 100644
index 79d2d7d837..0000000000
--- a/test/prism/fixtures/ternary_operator.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-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
deleted file mode 100644
index cca47ef00b..0000000000
--- a/test/prism/fixtures/tilde_heredocs.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-<<~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
deleted file mode 100644
index 129c349433..0000000000
--- a/test/prism/fixtures/undef.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-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
deleted file mode 100644
index e2da5a696c..0000000000
--- a/test/prism/fixtures/unescaping.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-["\c#{1}"]
-
-/\c#{1}/
-
-"\c#{1}"
-
-<<~HERE
- \c#{1}
-HERE
diff --git a/test/prism/fixtures/unless.txt b/test/prism/fixtures/unless.txt
deleted file mode 100644
index 410d460e69..0000000000
--- a/test/prism/fixtures/unless.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-unless true; 1; end
-
-unless true
-1 else 2 end
-
-1 unless true
-
-break unless true
-
-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
deleted file mode 100644
index 44863d7afb..0000000000
--- a/test/prism/fixtures/unparser/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-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
deleted file mode 100644
index fb06a295e8..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/alias.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 84a74e8928..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/assignment.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-$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
deleted file mode 100644
index b2baf1dc12..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/block.txt
+++ /dev/null
@@ -1,96 +0,0 @@
-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
deleted file mode 100644
index c455fd7c39..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/case.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-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
deleted file mode 100644
index f0198625e9..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/class.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-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/control.txt b/test/prism/fixtures/unparser/corpus/literal/control.txt
deleted file mode 100644
index 648782bc96..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/control.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-next
-return
-break
-retry
-redo
-return 1
-return 1, 2
-return true ? 1 : 2
-break true ? 1 : 2
-next true ? 1 : 2
-return true, if true
- 1
-else
- 2
-end
diff --git a/test/prism/fixtures/unparser/corpus/literal/def.txt b/test/prism/fixtures/unparser/corpus/literal/def.txt
deleted file mode 100644
index 61339bd4a6..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/def.txt
+++ /dev/null
@@ -1,134 +0,0 @@
-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
deleted file mode 100644
index 65e7c370fd..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/defined.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index b70aa9efc5..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/defs.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-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
deleted file mode 100644
index 8a912d28ed..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/dstr.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-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
deleted file mode 100644
index e69de29bb2..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/empty.txt
+++ /dev/null
diff --git a/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt b/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt
deleted file mode 100644
index 6a452c185a..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt
+++ /dev/null
@@ -1 +0,0 @@
-()
diff --git a/test/prism/fixtures/unparser/corpus/literal/flipflop.txt b/test/prism/fixtures/unparser/corpus/literal/flipflop.txt
deleted file mode 100644
index 8badd39d57..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/flipflop.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-if ((i == 4)..(i == 4))
- foo
-end
-if ((i == 4)...(i == 4))
- foo
-end
diff --git a/test/prism/fixtures/unparser/corpus/literal/for.txt b/test/prism/fixtures/unparser/corpus/literal/for.txt
deleted file mode 100644
index 4c19a352d9..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/for.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index 08f14f47b3..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/hookexe.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 0c13801f9e..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/if.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-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
deleted file mode 100644
index 6cc1e74ca6..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/kwbegin.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-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
deleted file mode 100644
index 4eb722dad1..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/lambda.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 2fc7cd1d79..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/literal.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-{ "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
deleted file mode 100644
index cec03f3bfd..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/module.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-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
deleted file mode 100644
index 5858d773d0..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/opasgn.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-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
deleted file mode 100644
index 7cfaa4dc67..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/pattern.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-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
deleted file mode 100644
index 4f6dd71b38..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/pragma.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-__ENCODING__
-__FILE__
-__LINE__
-__dir__
diff --git a/test/prism/fixtures/unparser/corpus/literal/range.txt b/test/prism/fixtures/unparser/corpus/literal/range.txt
deleted file mode 100644
index eb1f3874c0..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/range.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-(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
deleted file mode 100644
index a787816808..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/rescue.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 1e9c2a94be..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/send.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-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
deleted file mode 100644
index c332f9e48e..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/since/27.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--> {
- _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
deleted file mode 100644
index b73328a4b0..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/since/30.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 504eb94d5b..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/since/31.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index fa279f11cf..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/since/32.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-def foo(argument, **)
- bar(argument, **)
-end
-
-def foo(argument, *)
- bar(argument, *)
-end
diff --git a/test/prism/fixtures/unparser/corpus/literal/singletons.txt b/test/prism/fixtures/unparser/corpus/literal/singletons.txt
deleted file mode 100644
index 496e6a41ce..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/singletons.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-false
-nil
-self
-true
diff --git a/test/prism/fixtures/unparser/corpus/literal/super.txt b/test/prism/fixtures/unparser/corpus/literal/super.txt
deleted file mode 100644
index 0e73e6f052..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/super.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100644
index 77685cb71d..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/unary.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-!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
deleted file mode 100644
index a65d8d0cc4..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/undef.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index 1de938f376..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/variables.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 19a60ef5ff..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/while.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-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/literal/yield.txt b/test/prism/fixtures/unparser/corpus/literal/yield.txt
deleted file mode 100644
index c0b5820842..0000000000
--- a/test/prism/fixtures/unparser/corpus/literal/yield.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-yield
-yield(a)
-yield(a, b)
diff --git a/test/prism/fixtures/unparser/corpus/semantic/and.txt b/test/prism/fixtures/unparser/corpus/semantic/and.txt
deleted file mode 100644
index 43d1712445..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/and.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 5891690025..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/block.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-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
deleted file mode 100644
index 7574619392..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/def.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 919e736077..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/dstr.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-<<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
deleted file mode 100644
index d275a96a5c..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-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
deleted file mode 100644
index c424db5a53..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/literal.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-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/send.txt b/test/prism/fixtures/unparser/corpus/semantic/send.txt
deleted file mode 100644
index a65b27d2f2..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/send.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 47debc3114..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/undef.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-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
deleted file mode 100644
index a55dcc52fc..0000000000
--- a/test/prism/fixtures/unparser/corpus/semantic/while.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-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
deleted file mode 100644
index 7dcb5d495d..0000000000
--- a/test/prism/fixtures/until.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-until true; 1; end
-
-1 until true
-
-break until true
-
-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
deleted file mode 100644
index 1545c30c80..0000000000
--- a/test/prism/fixtures/variables.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@@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
deleted file mode 100644
index eecfbfdddd..0000000000
--- a/test/prism/fixtures/while.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-while true; 1; end
-
-1 while true
-
-break while true
-
-next while true
-
-return while true
-
-foo :a, :b while bar?
-
-while def self.foo a = tap do end; end; break; end
-
-while class Foo a = tap do end; end; break; end
-
-while class << self; tap do end; end; break; end
-
-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
deleted file mode 100644
index 971310e3d6..0000000000
--- a/test/prism/fixtures/whitequark/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-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
deleted file mode 100644
index d6debf2f92..0000000000
--- a/test/prism/fixtures/whitequark/__ENCODING__.txt
+++ /dev/null
@@ -1 +0,0 @@
-__ENCODING__
diff --git a/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt b/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt
deleted file mode 100644
index d6debf2f92..0000000000
--- a/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt
+++ /dev/null
@@ -1 +0,0 @@
-__ENCODING__
diff --git a/test/prism/fixtures/whitequark/alias.txt b/test/prism/fixtures/whitequark/alias.txt
deleted file mode 100644
index e33b120022..0000000000
--- a/test/prism/fixtures/whitequark/alias.txt
+++ /dev/null
@@ -1 +0,0 @@
-alias :foo bar
diff --git a/test/prism/fixtures/whitequark/alias_gvar.txt b/test/prism/fixtures/whitequark/alias_gvar.txt
deleted file mode 100644
index b975d97f8e..0000000000
--- a/test/prism/fixtures/whitequark/alias_gvar.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 9b2e3afad5..0000000000
--- a/test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt
+++ /dev/null
@@ -1 +0,0 @@
-a ? b & '': nil
diff --git a/test/prism/fixtures/whitequark/and.txt b/test/prism/fixtures/whitequark/and.txt
deleted file mode 100644
index 43fa6a65cd..0000000000
--- a/test/prism/fixtures/whitequark/and.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-foo && bar
-
-foo and bar
diff --git a/test/prism/fixtures/whitequark/and_asgn.txt b/test/prism/fixtures/whitequark/and_asgn.txt
deleted file mode 100644
index a979265914..0000000000
--- a/test/prism/fixtures/whitequark/and_asgn.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index e346041604..0000000000
--- a/test/prism/fixtures/whitequark/and_or_masgn.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index e3eaaad6ce..0000000000
--- a/test/prism/fixtures/whitequark/anonymous_blockarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def foo(&); bar(&); end
diff --git a/test/prism/fixtures/whitequark/arg.txt b/test/prism/fixtures/whitequark/arg.txt
deleted file mode 100644
index b1984ad5c4..0000000000
--- a/test/prism/fixtures/whitequark/arg.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 0f5cc33961..0000000000
--- a/test/prism/fixtures/whitequark/arg_duplicate_ignored.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 82db416cb4..0000000000
--- a/test/prism/fixtures/whitequark/arg_label.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 6c67ab72e3..0000000000
--- a/test/prism/fixtures/whitequark/arg_scope.txt
+++ /dev/null
@@ -1 +0,0 @@
-lambda{|;a|a}
diff --git a/test/prism/fixtures/whitequark/args.txt b/test/prism/fixtures/whitequark/args.txt
deleted file mode 100644
index 773be477d3..0000000000
--- a/test/prism/fixtures/whitequark/args.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-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
deleted file mode 100644
index 445f899442..0000000000
--- a/test/prism/fixtures/whitequark/args_args_assocs.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index b566a59037..0000000000
--- a/test/prism/fixtures/whitequark/args_args_assocs_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[bar, :baz => 1,]
diff --git a/test/prism/fixtures/whitequark/args_args_comma.txt b/test/prism/fixtures/whitequark/args_args_comma.txt
deleted file mode 100644
index 80770716dd..0000000000
--- a/test/prism/fixtures/whitequark/args_args_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[bar,]
diff --git a/test/prism/fixtures/whitequark/args_args_star.txt b/test/prism/fixtures/whitequark/args_args_star.txt
deleted file mode 100644
index d4dc9cc579..0000000000
--- a/test/prism/fixtures/whitequark/args_args_star.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-fun(foo, *bar)
-
-fun(foo, *bar, &baz)
diff --git a/test/prism/fixtures/whitequark/args_assocs.txt b/test/prism/fixtures/whitequark/args_assocs.txt
deleted file mode 100644
index b33e131181..0000000000
--- a/test/prism/fixtures/whitequark/args_assocs.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-fun(:foo => 1)
-
-fun(:foo => 1, &baz)
-
-self.[]= foo, :a => 1
-
-self[:bar => 1]
-
-super(:foo => 42)
-
-yield(:foo => 42)
diff --git a/test/prism/fixtures/whitequark/args_assocs_comma.txt b/test/prism/fixtures/whitequark/args_assocs_comma.txt
deleted file mode 100644
index 15e5cd65dc..0000000000
--- a/test/prism/fixtures/whitequark/args_assocs_comma.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[:baz => 1,]
diff --git a/test/prism/fixtures/whitequark/args_assocs_legacy.txt b/test/prism/fixtures/whitequark/args_assocs_legacy.txt
deleted file mode 100644
index b33e131181..0000000000
--- a/test/prism/fixtures/whitequark/args_assocs_legacy.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-fun(:foo => 1)
-
-fun(:foo => 1, &baz)
-
-self.[]= foo, :a => 1
-
-self[:bar => 1]
-
-super(:foo => 42)
-
-yield(:foo => 42)
diff --git a/test/prism/fixtures/whitequark/args_block_pass.txt b/test/prism/fixtures/whitequark/args_block_pass.txt
deleted file mode 100644
index 35d7d23885..0000000000
--- a/test/prism/fixtures/whitequark/args_block_pass.txt
+++ /dev/null
@@ -1 +0,0 @@
-fun(&bar)
diff --git a/test/prism/fixtures/whitequark/args_cmd.txt b/test/prism/fixtures/whitequark/args_cmd.txt
deleted file mode 100644
index dd0c8891d0..0000000000
--- a/test/prism/fixtures/whitequark/args_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-fun(f bar)
diff --git a/test/prism/fixtures/whitequark/args_star.txt b/test/prism/fixtures/whitequark/args_star.txt
deleted file mode 100644
index ce1e6f8465..0000000000
--- a/test/prism/fixtures/whitequark/args_star.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-fun(*bar)
-
-fun(*bar, &baz)
diff --git a/test/prism/fixtures/whitequark/array_assocs.txt b/test/prism/fixtures/whitequark/array_assocs.txt
deleted file mode 100644
index fcecfcdefc..0000000000
--- a/test/prism/fixtures/whitequark/array_assocs.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[ 1 => 2 ]
-
-[ 1, 2 => 3 ]
diff --git a/test/prism/fixtures/whitequark/array_plain.txt b/test/prism/fixtures/whitequark/array_plain.txt
deleted file mode 100644
index 44e2ace7e5..0000000000
--- a/test/prism/fixtures/whitequark/array_plain.txt
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2]
diff --git a/test/prism/fixtures/whitequark/array_splat.txt b/test/prism/fixtures/whitequark/array_splat.txt
deleted file mode 100644
index 144c1eb124..0000000000
--- a/test/prism/fixtures/whitequark/array_splat.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-[*foo]
-
-[1, *foo, 2]
-
-[1, *foo]
diff --git a/test/prism/fixtures/whitequark/array_symbols.txt b/test/prism/fixtures/whitequark/array_symbols.txt
deleted file mode 100644
index a9f9df0404..0000000000
--- a/test/prism/fixtures/whitequark/array_symbols.txt
+++ /dev/null
@@ -1 +0,0 @@
-%i[foo bar]
diff --git a/test/prism/fixtures/whitequark/array_symbols_empty.txt b/test/prism/fixtures/whitequark/array_symbols_empty.txt
deleted file mode 100644
index da3a89ee9b..0000000000
--- a/test/prism/fixtures/whitequark/array_symbols_empty.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-%I()
-
-%i[]
diff --git a/test/prism/fixtures/whitequark/array_symbols_interp.txt b/test/prism/fixtures/whitequark/array_symbols_interp.txt
deleted file mode 100644
index d4950d0c05..0000000000
--- a/test/prism/fixtures/whitequark/array_symbols_interp.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-%I[foo #{bar}]
-
-%I[foo#{bar}]
diff --git a/test/prism/fixtures/whitequark/array_words.txt b/test/prism/fixtures/whitequark/array_words.txt
deleted file mode 100644
index a07380cadc..0000000000
--- a/test/prism/fixtures/whitequark/array_words.txt
+++ /dev/null
@@ -1 +0,0 @@
-%w[foo bar]
diff --git a/test/prism/fixtures/whitequark/array_words_empty.txt b/test/prism/fixtures/whitequark/array_words_empty.txt
deleted file mode 100644
index 7568263f4a..0000000000
--- a/test/prism/fixtures/whitequark/array_words_empty.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-%W()
-
-%w[]
diff --git a/test/prism/fixtures/whitequark/array_words_interp.txt b/test/prism/fixtures/whitequark/array_words_interp.txt
deleted file mode 100644
index 1460f7dc03..0000000000
--- a/test/prism/fixtures/whitequark/array_words_interp.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-%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
deleted file mode 100644
index 81f8cc1c8d..0000000000
--- a/test/prism/fixtures/whitequark/asgn_cmd.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index f0b0055e55..0000000000
--- a/test/prism/fixtures/whitequark/asgn_mrhs.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 03166e10ee..0000000000
--- a/test/prism/fixtures/whitequark/back_ref.txt
+++ /dev/null
@@ -1 +0,0 @@
-$+
diff --git a/test/prism/fixtures/whitequark/bang.txt b/test/prism/fixtures/whitequark/bang.txt
deleted file mode 100644
index 6cf9410cf5..0000000000
--- a/test/prism/fixtures/whitequark/bang.txt
+++ /dev/null
@@ -1 +0,0 @@
-!foo
diff --git a/test/prism/fixtures/whitequark/bang_cmd.txt b/test/prism/fixtures/whitequark/bang_cmd.txt
deleted file mode 100644
index 0a5252c001..0000000000
--- a/test/prism/fixtures/whitequark/bang_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-!m foo
diff --git a/test/prism/fixtures/whitequark/begin_cmdarg.txt b/test/prism/fixtures/whitequark/begin_cmdarg.txt
deleted file mode 100644
index a5873668e9..0000000000
--- a/test/prism/fixtures/whitequark/begin_cmdarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index ae6c75564a..0000000000
--- a/test/prism/fixtures/whitequark/beginless_erange_after_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-foo
-...100
diff --git a/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt b/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt
deleted file mode 100644
index bfc8d5e5e8..0000000000
--- a/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-foo
-..100
diff --git a/test/prism/fixtures/whitequark/beginless_range.txt b/test/prism/fixtures/whitequark/beginless_range.txt
deleted file mode 100644
index ef52703b8a..0000000000
--- a/test/prism/fixtures/whitequark/beginless_range.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-...100
-
-..100
diff --git a/test/prism/fixtures/whitequark/blockarg.txt b/test/prism/fixtures/whitequark/blockarg.txt
deleted file mode 100644
index 63552e97be..0000000000
--- a/test/prism/fixtures/whitequark/blockarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(&block); end
diff --git a/test/prism/fixtures/whitequark/blockargs.txt b/test/prism/fixtures/whitequark/blockargs.txt
deleted file mode 100644
index cdd2c4f331..0000000000
--- a/test/prism/fixtures/whitequark/blockargs.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-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/break.txt b/test/prism/fixtures/whitequark/break.txt
deleted file mode 100644
index da51ec7c31..0000000000
--- a/test/prism/fixtures/whitequark/break.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-break
-
-break foo
-
-break()
-
-break(foo)
diff --git a/test/prism/fixtures/whitequark/break_block.txt b/test/prism/fixtures/whitequark/break_block.txt
deleted file mode 100644
index 4b58c58d5e..0000000000
--- a/test/prism/fixtures/whitequark/break_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-break fun foo do end
diff --git a/test/prism/fixtures/whitequark/bug_435.txt b/test/prism/fixtures/whitequark/bug_435.txt
deleted file mode 100644
index 3e4e0d5abd..0000000000
--- a/test/prism/fixtures/whitequark/bug_435.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#{-> foo {}}"
diff --git a/test/prism/fixtures/whitequark/bug_447.txt b/test/prism/fixtures/whitequark/bug_447.txt
deleted file mode 100644
index 7da59bbc2f..0000000000
--- a/test/prism/fixtures/whitequark/bug_447.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 8b41dd6027..0000000000
--- a/test/prism/fixtures/whitequark/bug_452.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index ad02ad38ae..0000000000
--- a/test/prism/fixtures/whitequark/bug_466.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0d2ea883a1..0000000000
--- a/test/prism/fixtures/whitequark/bug_473.txt
+++ /dev/null
@@ -1 +0,0 @@
-m "#{[]}"
diff --git a/test/prism/fixtures/whitequark/bug_480.txt b/test/prism/fixtures/whitequark/bug_480.txt
deleted file mode 100644
index 0558b2c957..0000000000
--- a/test/prism/fixtures/whitequark/bug_480.txt
+++ /dev/null
@@ -1 +0,0 @@
-m "#{}#{()}"
diff --git a/test/prism/fixtures/whitequark/bug_481.txt b/test/prism/fixtures/whitequark/bug_481.txt
deleted file mode 100644
index 6328e9dbbd..0000000000
--- a/test/prism/fixtures/whitequark/bug_481.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 85399bd19a..0000000000
--- a/test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-# 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
deleted file mode 100644
index 7e9e54c518..0000000000
--- a/test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt
+++ /dev/null
@@ -1 +0,0 @@
-desc "foo" do end
diff --git a/test/prism/fixtures/whitequark/bug_cmdarg.txt b/test/prism/fixtures/whitequark/bug_cmdarg.txt
deleted file mode 100644
index 0281cd6668..0000000000
--- a/test/prism/fixtures/whitequark/bug_cmdarg.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 615dc88217..0000000000
--- a/test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 21340fd6e8..0000000000
--- a/test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 7dece50408..0000000000
--- a/test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6c4dd205d2..0000000000
--- a/test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 06fef0a99f..0000000000
--- a/test/prism/fixtures/whitequark/bug_heredoc_do.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index be0b1a8542..0000000000
--- a/test/prism/fixtures/whitequark/bug_interp_single.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-"#{1}"
-
-%W"#{1}"
diff --git a/test/prism/fixtures/whitequark/bug_lambda_leakage.txt b/test/prism/fixtures/whitequark/bug_lambda_leakage.txt
deleted file mode 100644
index 372b36929a..0000000000
--- a/test/prism/fixtures/whitequark/bug_lambda_leakage.txt
+++ /dev/null
@@ -1 +0,0 @@
-->(scope) {}; scope
diff --git a/test/prism/fixtures/whitequark/bug_regex_verification.txt b/test/prism/fixtures/whitequark/bug_regex_verification.txt
deleted file mode 100644
index f8483c8b10..0000000000
--- a/test/prism/fixtures/whitequark/bug_regex_verification.txt
+++ /dev/null
@@ -1 +0,0 @@
-/#)/x
diff --git a/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt b/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt
deleted file mode 100644
index e8c81edc57..0000000000
--- a/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 628c36ef13..0000000000
--- a/test/prism/fixtures/whitequark/bug_while_not_parens_do.txt
+++ /dev/null
@@ -1 +0,0 @@
-while not (true) do end
diff --git a/test/prism/fixtures/whitequark/case_cond.txt b/test/prism/fixtures/whitequark/case_cond.txt
deleted file mode 100644
index a236b27ebd..0000000000
--- a/test/prism/fixtures/whitequark/case_cond.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 06eefa4a1b..0000000000
--- a/test/prism/fixtures/whitequark/case_cond_else.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 472672c781..0000000000
--- a/test/prism/fixtures/whitequark/case_expr.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 3c55826134..0000000000
--- a/test/prism/fixtures/whitequark/case_expr_else.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 964d0f4c9b..0000000000
--- a/test/prism/fixtures/whitequark/casgn_scoped.txt
+++ /dev/null
@@ -1 +0,0 @@
-Bar::Foo = 10
diff --git a/test/prism/fixtures/whitequark/casgn_toplevel.txt b/test/prism/fixtures/whitequark/casgn_toplevel.txt
deleted file mode 100644
index 047a3b6745..0000000000
--- a/test/prism/fixtures/whitequark/casgn_toplevel.txt
+++ /dev/null
@@ -1 +0,0 @@
-::Foo = 10
diff --git a/test/prism/fixtures/whitequark/casgn_unscoped.txt b/test/prism/fixtures/whitequark/casgn_unscoped.txt
deleted file mode 100644
index 5632cf64ee..0000000000
--- a/test/prism/fixtures/whitequark/casgn_unscoped.txt
+++ /dev/null
@@ -1 +0,0 @@
-Foo = 10
diff --git a/test/prism/fixtures/whitequark/character.txt b/test/prism/fixtures/whitequark/character.txt
deleted file mode 100644
index b22ffbb71a..0000000000
--- a/test/prism/fixtures/whitequark/character.txt
+++ /dev/null
@@ -1 +0,0 @@
-?a
diff --git a/test/prism/fixtures/whitequark/class.txt b/test/prism/fixtures/whitequark/class.txt
deleted file mode 100644
index a30a248e96..0000000000
--- a/test/prism/fixtures/whitequark/class.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-class Foo end
-
-class Foo; end
diff --git a/test/prism/fixtures/whitequark/class_definition_in_while_cond.txt b/test/prism/fixtures/whitequark/class_definition_in_while_cond.txt
deleted file mode 100644
index 10427314b5..0000000000
--- a/test/prism/fixtures/whitequark/class_definition_in_while_cond.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-while class << self; a = tap do end; end; break; end
-
-while class << self; tap do end; end; break; end
-
-while class Foo a = tap do end; end; break; end
-
-while class Foo; tap do end; end; break; end
diff --git a/test/prism/fixtures/whitequark/class_super.txt b/test/prism/fixtures/whitequark/class_super.txt
deleted file mode 100644
index 8829d82d36..0000000000
--- a/test/prism/fixtures/whitequark/class_super.txt
+++ /dev/null
@@ -1 +0,0 @@
-class Foo < Bar; end
diff --git a/test/prism/fixtures/whitequark/class_super_label.txt b/test/prism/fixtures/whitequark/class_super_label.txt
deleted file mode 100644
index 5d47897ab6..0000000000
--- a/test/prism/fixtures/whitequark/class_super_label.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 208f2d87fe..0000000000
--- a/test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-a #
- #
-&.foo
-
-
-a #
- #
-.foo
-
-
-a #
-#
-&.foo
-
-
-a #
-#
-.foo
-
diff --git a/test/prism/fixtures/whitequark/complex.txt b/test/prism/fixtures/whitequark/complex.txt
deleted file mode 100644
index 1dbf2c13f4..0000000000
--- a/test/prism/fixtures/whitequark/complex.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-42.1i
-
-42.1ri
-
-42i
-
-42ri
diff --git a/test/prism/fixtures/whitequark/cond_begin.txt b/test/prism/fixtures/whitequark/cond_begin.txt
deleted file mode 100644
index 49d709b79c..0000000000
--- a/test/prism/fixtures/whitequark/cond_begin.txt
+++ /dev/null
@@ -1 +0,0 @@
-if (bar); foo; end
diff --git a/test/prism/fixtures/whitequark/cond_begin_masgn.txt b/test/prism/fixtures/whitequark/cond_begin_masgn.txt
deleted file mode 100644
index f9b65026b4..0000000000
--- a/test/prism/fixtures/whitequark/cond_begin_masgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-if (bar; a, b = foo); end
diff --git a/test/prism/fixtures/whitequark/cond_eflipflop.txt b/test/prism/fixtures/whitequark/cond_eflipflop.txt
deleted file mode 100644
index 1236c2dbb5..0000000000
--- a/test/prism/fixtures/whitequark/cond_eflipflop.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-!(foo...bar)
-
-if foo...bar; end
diff --git a/test/prism/fixtures/whitequark/cond_iflipflop.txt b/test/prism/fixtures/whitequark/cond_iflipflop.txt
deleted file mode 100644
index 84bee71a74..0000000000
--- a/test/prism/fixtures/whitequark/cond_iflipflop.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-!(foo..bar)
-
-if foo..bar; end
diff --git a/test/prism/fixtures/whitequark/cond_match_current_line.txt b/test/prism/fixtures/whitequark/cond_match_current_line.txt
deleted file mode 100644
index 21878c7bd8..0000000000
--- a/test/prism/fixtures/whitequark/cond_match_current_line.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-!/wat/
-
-if /wat/; end
diff --git a/test/prism/fixtures/whitequark/const_op_asgn.txt b/test/prism/fixtures/whitequark/const_op_asgn.txt
deleted file mode 100644
index e72e7adee8..0000000000
--- a/test/prism/fixtures/whitequark/const_op_asgn.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-::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
deleted file mode 100644
index 4b03d85fc0..0000000000
--- a/test/prism/fixtures/whitequark/const_scoped.txt
+++ /dev/null
@@ -1 +0,0 @@
-Bar::Foo
diff --git a/test/prism/fixtures/whitequark/const_toplevel.txt b/test/prism/fixtures/whitequark/const_toplevel.txt
deleted file mode 100644
index f783ae752b..0000000000
--- a/test/prism/fixtures/whitequark/const_toplevel.txt
+++ /dev/null
@@ -1 +0,0 @@
-::Foo
diff --git a/test/prism/fixtures/whitequark/const_unscoped.txt b/test/prism/fixtures/whitequark/const_unscoped.txt
deleted file mode 100644
index bc56c4d894..0000000000
--- a/test/prism/fixtures/whitequark/const_unscoped.txt
+++ /dev/null
@@ -1 +0,0 @@
-Foo
diff --git a/test/prism/fixtures/whitequark/cpath.txt b/test/prism/fixtures/whitequark/cpath.txt
deleted file mode 100644
index a4041692d1..0000000000
--- a/test/prism/fixtures/whitequark/cpath.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-module ::Foo; end
-
-module Bar::Foo; end
diff --git a/test/prism/fixtures/whitequark/cvar.txt b/test/prism/fixtures/whitequark/cvar.txt
deleted file mode 100644
index 4997896e4a..0000000000
--- a/test/prism/fixtures/whitequark/cvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-@@foo
diff --git a/test/prism/fixtures/whitequark/cvasgn.txt b/test/prism/fixtures/whitequark/cvasgn.txt
deleted file mode 100644
index 8f7e19c4fe..0000000000
--- a/test/prism/fixtures/whitequark/cvasgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-@@var = 10
diff --git a/test/prism/fixtures/whitequark/dedenting_heredoc.txt b/test/prism/fixtures/whitequark/dedenting_heredoc.txt
deleted file mode 100644
index 84937d84ab..0000000000
--- a/test/prism/fixtures/whitequark/dedenting_heredoc.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-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
deleted file mode 100644
index 0427715d61..0000000000
--- a/test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<~'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
deleted file mode 100644
index fd7bc02419..0000000000
--- a/test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<~'FOO'
- baz\
- qux
-FOO
diff --git a/test/prism/fixtures/whitequark/def.txt b/test/prism/fixtures/whitequark/def.txt
deleted file mode 100644
index d96a4238b3..0000000000
--- a/test/prism/fixtures/whitequark/def.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 5cf93e22e3..0000000000
--- a/test/prism/fixtures/whitequark/defined.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-defined? @foo
-
-defined? foo
-
-defined?(foo)
diff --git a/test/prism/fixtures/whitequark/defs.txt b/test/prism/fixtures/whitequark/defs.txt
deleted file mode 100644
index e0b7aa86eb..0000000000
--- a/test/prism/fixtures/whitequark/defs.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 8b13789179..0000000000
--- a/test/prism/fixtures/whitequark/empty_stmt.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/test/prism/fixtures/whitequark/endless_comparison_method.txt b/test/prism/fixtures/whitequark/endless_comparison_method.txt
deleted file mode 100644
index e10c3a6ced..0000000000
--- a/test/prism/fixtures/whitequark/endless_comparison_method.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 7002526229..0000000000
--- a/test/prism/fixtures/whitequark/endless_method.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index d9dad2d747..0000000000
--- a/test/prism/fixtures/whitequark/endless_method_command_syntax.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-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
deleted file mode 100644
index 5955e40b5b..0000000000
--- a/test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 93dc63a45d..0000000000
--- a/test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 90ea8f7c6d..0000000000
--- a/test/prism/fixtures/whitequark/endless_method_without_args.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 6c4b47c63c..0000000000
--- a/test/prism/fixtures/whitequark/ensure.txt
+++ /dev/null
@@ -1 +0,0 @@
-begin; meth; ensure; bar; end
diff --git a/test/prism/fixtures/whitequark/ensure_empty.txt b/test/prism/fixtures/whitequark/ensure_empty.txt
deleted file mode 100644
index 39a175c371..0000000000
--- a/test/prism/fixtures/whitequark/ensure_empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-begin ensure end
diff --git a/test/prism/fixtures/whitequark/false.txt b/test/prism/fixtures/whitequark/false.txt
deleted file mode 100644
index c508d5366f..0000000000
--- a/test/prism/fixtures/whitequark/false.txt
+++ /dev/null
@@ -1 +0,0 @@
-false
diff --git a/test/prism/fixtures/whitequark/float.txt b/test/prism/fixtures/whitequark/float.txt
deleted file mode 100644
index 8c7592a192..0000000000
--- a/test/prism/fixtures/whitequark/float.txt
+++ /dev/null
@@ -1,3 +0,0 @@
--1.33
-
-1.33
diff --git a/test/prism/fixtures/whitequark/for.txt b/test/prism/fixtures/whitequark/for.txt
deleted file mode 100644
index a27ae578da..0000000000
--- a/test/prism/fixtures/whitequark/for.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 53cd5229a4..0000000000
--- a/test/prism/fixtures/whitequark/for_mlhs.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c7590a8d53..0000000000
--- a/test/prism/fixtures/whitequark/forward_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index fd4c06bcb5..0000000000
--- a/test/prism/fixtures/whitequark/forward_arg_with_open_args.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-(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
deleted file mode 100644
index 0d9162457f..0000000000
--- a/test/prism/fixtures/whitequark/forward_args_legacy.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 7dbf472232..0000000000
--- a/test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index f734bfd9ec..0000000000
--- a/test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def foo(argument, *); bar(argument, *); end
diff --git a/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt b/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt
deleted file mode 100644
index 16cd8b2913..0000000000
--- a/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 52759b838f..0000000000
--- a/test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 65ac2cc1ed..0000000000
--- a/test/prism/fixtures/whitequark/forwarded_restarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def foo(*); bar(*); end
diff --git a/test/prism/fixtures/whitequark/gvar.txt b/test/prism/fixtures/whitequark/gvar.txt
deleted file mode 100644
index bbf13489ad..0000000000
--- a/test/prism/fixtures/whitequark/gvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-$foo
diff --git a/test/prism/fixtures/whitequark/gvasgn.txt b/test/prism/fixtures/whitequark/gvasgn.txt
deleted file mode 100644
index 2bcc22cdd1..0000000000
--- a/test/prism/fixtures/whitequark/gvasgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-$var = 10
diff --git a/test/prism/fixtures/whitequark/hash_empty.txt b/test/prism/fixtures/whitequark/hash_empty.txt
deleted file mode 100644
index ffcd4415b0..0000000000
--- a/test/prism/fixtures/whitequark/hash_empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-{ }
diff --git a/test/prism/fixtures/whitequark/hash_hashrocket.txt b/test/prism/fixtures/whitequark/hash_hashrocket.txt
deleted file mode 100644
index 2cbb3bd96d..0000000000
--- a/test/prism/fixtures/whitequark/hash_hashrocket.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-{ 1 => 2 }
-
-{ 1 => 2, :foo => "bar" }
diff --git a/test/prism/fixtures/whitequark/hash_kwsplat.txt b/test/prism/fixtures/whitequark/hash_kwsplat.txt
deleted file mode 100644
index 921aa97c7c..0000000000
--- a/test/prism/fixtures/whitequark/hash_kwsplat.txt
+++ /dev/null
@@ -1 +0,0 @@
-{ foo: 2, **bar }
diff --git a/test/prism/fixtures/whitequark/hash_label.txt b/test/prism/fixtures/whitequark/hash_label.txt
deleted file mode 100644
index 3aacae4b69..0000000000
--- a/test/prism/fixtures/whitequark/hash_label.txt
+++ /dev/null
@@ -1 +0,0 @@
-{ foo: 2 }
diff --git a/test/prism/fixtures/whitequark/hash_label_end.txt b/test/prism/fixtures/whitequark/hash_label_end.txt
deleted file mode 100644
index ac9f7c4b41..0000000000
--- a/test/prism/fixtures/whitequark/hash_label_end.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 9d8ccb5877..0000000000
--- a/test/prism/fixtures/whitequark/hash_pair_value_omission.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-{BAR:}
-
-{a:, b:}
-
-{puts:}
diff --git a/test/prism/fixtures/whitequark/heredoc.txt b/test/prism/fixtures/whitequark/heredoc.txt
deleted file mode 100644
index 1bfc963f94..0000000000
--- a/test/prism/fixtures/whitequark/heredoc.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-<<'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
deleted file mode 100644
index 3de3525286..0000000000
--- a/test/prism/fixtures/whitequark/if.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 62bab8138c..0000000000
--- a/test/prism/fixtures/whitequark/if_else.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 4d71e82214..0000000000
--- a/test/prism/fixtures/whitequark/if_elsif.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0c2c8bb04f..0000000000
--- a/test/prism/fixtures/whitequark/if_masgn__24.txt
+++ /dev/null
@@ -1 +0,0 @@
-if (a, b = foo); end
diff --git a/test/prism/fixtures/whitequark/if_mod.txt b/test/prism/fixtures/whitequark/if_mod.txt
deleted file mode 100644
index da177b5606..0000000000
--- a/test/prism/fixtures/whitequark/if_mod.txt
+++ /dev/null
@@ -1 +0,0 @@
-bar if foo
diff --git a/test/prism/fixtures/whitequark/if_nl_then.txt b/test/prism/fixtures/whitequark/if_nl_then.txt
deleted file mode 100644
index b68107bad2..0000000000
--- a/test/prism/fixtures/whitequark/if_nl_then.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-if foo
-then bar end
diff --git a/test/prism/fixtures/whitequark/if_while_after_class__since_32.txt b/test/prism/fixtures/whitequark/if_while_after_class__since_32.txt
deleted file mode 100644
index 1552494d28..0000000000
--- a/test/prism/fixtures/whitequark/if_while_after_class__since_32.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-class if true; Object end::Kernel; end
-
-class while true; break Object end::Kernel; end
-
-module if true; Object end::Kernel; end
-
-module while true; break Object end::Kernel; end
diff --git a/test/prism/fixtures/whitequark/int.txt b/test/prism/fixtures/whitequark/int.txt
deleted file mode 100644
index 6d419918c6..0000000000
--- a/test/prism/fixtures/whitequark/int.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-+42
-
--42
-
-42
diff --git a/test/prism/fixtures/whitequark/int___LINE__.txt b/test/prism/fixtures/whitequark/int___LINE__.txt
deleted file mode 100644
index 05dcf7afe0..0000000000
--- a/test/prism/fixtures/whitequark/int___LINE__.txt
+++ /dev/null
@@ -1 +0,0 @@
-__LINE__
diff --git a/test/prism/fixtures/whitequark/interp_digit_var.txt b/test/prism/fixtures/whitequark/interp_digit_var.txt
deleted file mode 100644
index 1ae5a2e3e0..0000000000
--- a/test/prism/fixtures/whitequark/interp_digit_var.txt
+++ /dev/null
@@ -1,87 +0,0 @@
- "#@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
deleted file mode 100644
index 9149fc67f9..0000000000
--- a/test/prism/fixtures/whitequark/ivar.txt
+++ /dev/null
@@ -1 +0,0 @@
-@foo
diff --git a/test/prism/fixtures/whitequark/ivasgn.txt b/test/prism/fixtures/whitequark/ivasgn.txt
deleted file mode 100644
index ac291799db..0000000000
--- a/test/prism/fixtures/whitequark/ivasgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-@var = 10
diff --git a/test/prism/fixtures/whitequark/keyword_argument_omission.txt b/test/prism/fixtures/whitequark/keyword_argument_omission.txt
deleted file mode 100644
index 47883dc9a5..0000000000
--- a/test/prism/fixtures/whitequark/keyword_argument_omission.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo(a:, b:)
diff --git a/test/prism/fixtures/whitequark/kwarg.txt b/test/prism/fixtures/whitequark/kwarg.txt
deleted file mode 100644
index ca02a1fd2a..0000000000
--- a/test/prism/fixtures/whitequark/kwarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(foo:); end
diff --git a/test/prism/fixtures/whitequark/kwbegin_compstmt.txt b/test/prism/fixtures/whitequark/kwbegin_compstmt.txt
deleted file mode 100644
index 33ceff2489..0000000000
--- a/test/prism/fixtures/whitequark/kwbegin_compstmt.txt
+++ /dev/null
@@ -1 +0,0 @@
-begin foo!; bar! end
diff --git a/test/prism/fixtures/whitequark/kwnilarg.txt b/test/prism/fixtures/whitequark/kwnilarg.txt
deleted file mode 100644
index 8fc482d5af..0000000000
--- a/test/prism/fixtures/whitequark/kwnilarg.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-->(**nil) {}
-
-def f(**nil); end
-
-m { |**nil| }
diff --git a/test/prism/fixtures/whitequark/kwoptarg.txt b/test/prism/fixtures/whitequark/kwoptarg.txt
deleted file mode 100644
index dc3ce728d6..0000000000
--- a/test/prism/fixtures/whitequark/kwoptarg.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 99dcc7239b..0000000000
--- a/test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(a: nil, **); b(**) end
diff --git a/test/prism/fixtures/whitequark/kwrestarg_named.txt b/test/prism/fixtures/whitequark/kwrestarg_named.txt
deleted file mode 100644
index e17a661001..0000000000
--- a/test/prism/fixtures/whitequark/kwrestarg_named.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(**foo); end
diff --git a/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt b/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt
deleted file mode 100644
index 1b26b1d2ac..0000000000
--- a/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 277c200c9f..0000000000
--- a/test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index dc3a98b1c8..0000000000
--- a/test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-foo (-1.3).abs
-
-meth (-1.3).abs
diff --git a/test/prism/fixtures/whitequark/lvar.txt b/test/prism/fixtures/whitequark/lvar.txt
deleted file mode 100644
index 257cc5642c..0000000000
--- a/test/prism/fixtures/whitequark/lvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo
diff --git a/test/prism/fixtures/whitequark/lvar_injecting_match.txt b/test/prism/fixtures/whitequark/lvar_injecting_match.txt
deleted file mode 100644
index ba814a1088..0000000000
--- a/test/prism/fixtures/whitequark/lvar_injecting_match.txt
+++ /dev/null
@@ -1 +0,0 @@
-/(?<match>bar)/ =~ 'bar'; match
diff --git a/test/prism/fixtures/whitequark/lvasgn.txt b/test/prism/fixtures/whitequark/lvasgn.txt
deleted file mode 100644
index 330b8eff27..0000000000
--- a/test/prism/fixtures/whitequark/lvasgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-var = 10; var
diff --git a/test/prism/fixtures/whitequark/masgn.txt b/test/prism/fixtures/whitequark/masgn.txt
deleted file mode 100644
index 032124287c..0000000000
--- a/test/prism/fixtures/whitequark/masgn.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-(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
deleted file mode 100644
index 91a703ef44..0000000000
--- a/test/prism/fixtures/whitequark/masgn_attr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 18e096f1ee..0000000000
--- a/test/prism/fixtures/whitequark/masgn_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo, bar = m foo
diff --git a/test/prism/fixtures/whitequark/masgn_const.txt b/test/prism/fixtures/whitequark/masgn_const.txt
deleted file mode 100644
index 3b6fba588a..0000000000
--- a/test/prism/fixtures/whitequark/masgn_const.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-::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
deleted file mode 100644
index a1ccf4e385..0000000000
--- a/test/prism/fixtures/whitequark/masgn_nested.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-((b, )) = foo
-
-a, (b, c) = foo
diff --git a/test/prism/fixtures/whitequark/masgn_splat.txt b/test/prism/fixtures/whitequark/masgn_splat.txt
deleted file mode 100644
index a15dab10f2..0000000000
--- a/test/prism/fixtures/whitequark/masgn_splat.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-* = 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/method_definition_in_while_cond.txt b/test/prism/fixtures/whitequark/method_definition_in_while_cond.txt
deleted file mode 100644
index 6ec38906a1..0000000000
--- a/test/prism/fixtures/whitequark/method_definition_in_while_cond.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-while def foo a = tap do end; end; break; end
-
-while def foo; tap do end; end; break; end
-
-while def self.foo a = tap do end; end; break; end
-
-while def self.foo; tap do end; end; break; end
diff --git a/test/prism/fixtures/whitequark/module.txt b/test/prism/fixtures/whitequark/module.txt
deleted file mode 100644
index f999df3791..0000000000
--- a/test/prism/fixtures/whitequark/module.txt
+++ /dev/null
@@ -1 +0,0 @@
-module Foo; end
diff --git a/test/prism/fixtures/whitequark/multiple_pattern_matches.txt b/test/prism/fixtures/whitequark/multiple_pattern_matches.txt
deleted file mode 100644
index 54a4bb4774..0000000000
--- a/test/prism/fixtures/whitequark/multiple_pattern_matches.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-{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
deleted file mode 100644
index 1681844331..0000000000
--- a/test/prism/fixtures/whitequark/newline_in_hash_argument.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-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/next.txt b/test/prism/fixtures/whitequark/next.txt
deleted file mode 100644
index 7556ac2b74..0000000000
--- a/test/prism/fixtures/whitequark/next.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-next
-
-next foo
-
-next()
-
-next(foo)
diff --git a/test/prism/fixtures/whitequark/next_block.txt b/test/prism/fixtures/whitequark/next_block.txt
deleted file mode 100644
index d3b51dfa21..0000000000
--- a/test/prism/fixtures/whitequark/next_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-next fun foo do end
diff --git a/test/prism/fixtures/whitequark/nil.txt b/test/prism/fixtures/whitequark/nil.txt
deleted file mode 100644
index 607602cfc6..0000000000
--- a/test/prism/fixtures/whitequark/nil.txt
+++ /dev/null
@@ -1 +0,0 @@
-nil
diff --git a/test/prism/fixtures/whitequark/nil_expression.txt b/test/prism/fixtures/whitequark/nil_expression.txt
deleted file mode 100644
index aabf53f005..0000000000
--- a/test/prism/fixtures/whitequark/nil_expression.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-()
-
-begin end
diff --git a/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt b/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt
deleted file mode 100644
index f1eb7d3c2c..0000000000
--- a/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt
+++ /dev/null
@@ -1 +0,0 @@
-/#{1}(?<match>bar)/ =~ 'bar'
diff --git a/test/prism/fixtures/whitequark/not.txt b/test/prism/fixtures/whitequark/not.txt
deleted file mode 100644
index d87f68f48c..0000000000
--- a/test/prism/fixtures/whitequark/not.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-not foo
-
-not()
-
-not(foo)
diff --git a/test/prism/fixtures/whitequark/not_cmd.txt b/test/prism/fixtures/whitequark/not_cmd.txt
deleted file mode 100644
index 685ec209ee..0000000000
--- a/test/prism/fixtures/whitequark/not_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-not m foo
diff --git a/test/prism/fixtures/whitequark/not_masgn__24.txt b/test/prism/fixtures/whitequark/not_masgn__24.txt
deleted file mode 100644
index cb93b9103d..0000000000
--- a/test/prism/fixtures/whitequark/not_masgn__24.txt
+++ /dev/null
@@ -1 +0,0 @@
-!(a, b = foo)
diff --git a/test/prism/fixtures/whitequark/nth_ref.txt b/test/prism/fixtures/whitequark/nth_ref.txt
deleted file mode 100644
index 16ef65b105..0000000000
--- a/test/prism/fixtures/whitequark/nth_ref.txt
+++ /dev/null
@@ -1 +0,0 @@
-$10
diff --git a/test/prism/fixtures/whitequark/numbered_args_after_27.txt b/test/prism/fixtures/whitequark/numbered_args_after_27.txt
deleted file mode 100644
index 96fe7a32e2..0000000000
--- a/test/prism/fixtures/whitequark/numbered_args_after_27.txt
+++ /dev/null
@@ -1,7 +0,0 @@
--> 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
deleted file mode 100644
index 37cbce182d..0000000000
--- a/test/prism/fixtures/whitequark/numparam_outside_block.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-_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/op_asgn.txt b/test/prism/fixtures/whitequark/op_asgn.txt
deleted file mode 100644
index a5a28b1010..0000000000
--- a/test/prism/fixtures/whitequark/op_asgn.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 017aa9bef7..0000000000
--- a/test/prism/fixtures/whitequark/op_asgn_cmd.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 92cfb225fc..0000000000
--- a/test/prism/fixtures/whitequark/op_asgn_index.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 161b244bd4..0000000000
--- a/test/prism/fixtures/whitequark/op_asgn_index_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[0, 1] += m foo
diff --git a/test/prism/fixtures/whitequark/optarg.txt b/test/prism/fixtures/whitequark/optarg.txt
deleted file mode 100644
index 9d60609961..0000000000
--- a/test/prism/fixtures/whitequark/optarg.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index c2042ebb41..0000000000
--- a/test/prism/fixtures/whitequark/or.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-foo or bar
-
-foo || bar
diff --git a/test/prism/fixtures/whitequark/or_asgn.txt b/test/prism/fixtures/whitequark/or_asgn.txt
deleted file mode 100644
index 6e4ecc9f93..0000000000
--- a/test/prism/fixtures/whitequark/or_asgn.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 2f2f2b84d2..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_272.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index cf544b1ff6..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_490.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index bf616b85c8..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_507.txt
+++ /dev/null
@@ -1 +0,0 @@
-m = -> *args do end
diff --git a/test/prism/fixtures/whitequark/parser_bug_518.txt b/test/prism/fixtures/whitequark/parser_bug_518.txt
deleted file mode 100644
index 22f4afe3c8..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_518.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-class A < B
-end
diff --git a/test/prism/fixtures/whitequark/parser_bug_525.txt b/test/prism/fixtures/whitequark/parser_bug_525.txt
deleted file mode 100644
index 59d0e735b4..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_525.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 7eb91c2f46..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_604.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index fb62ded04c..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_640.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-<<~FOO
- baz\
- qux
-FOO
diff --git a/test/prism/fixtures/whitequark/parser_bug_645.txt b/test/prism/fixtures/whitequark/parser_bug_645.txt
deleted file mode 100644
index cb1e5a0dcf..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_645.txt
+++ /dev/null
@@ -1 +0,0 @@
--> (arg={}) {}
diff --git a/test/prism/fixtures/whitequark/parser_bug_830.txt b/test/prism/fixtures/whitequark/parser_bug_830.txt
deleted file mode 100644
index e5865e960d..0000000000
--- a/test/prism/fixtures/whitequark/parser_bug_830.txt
+++ /dev/null
@@ -1 +0,0 @@
-/\(/
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
deleted file mode 100644
index bddae8e153..0000000000
--- a/test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-<<~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
deleted file mode 100644
index 564cebdd74..0000000000
--- a/test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-"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
deleted file mode 100644
index fe0edaed55..0000000000
--- a/test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt
+++ /dev/null
@@ -1,4 +0,0 @@
- 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
deleted file mode 100644
index 6bf059af41..0000000000
--- a/test/prism/fixtures/whitequark/pattern_matching_blank_else.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 29f14c91ab..0000000000
--- a/test/prism/fixtures/whitequark/pattern_matching_else.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 12279afa24..0000000000
--- a/test/prism/fixtures/whitequark/pattern_matching_single_line.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 1e429335d0..0000000000
--- a/test/prism/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-[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
deleted file mode 100644
index baee33af66..0000000000
--- a/test/prism/fixtures/whitequark/postexe.txt
+++ /dev/null
@@ -1 +0,0 @@
-END { 1 }
diff --git a/test/prism/fixtures/whitequark/preexe.txt b/test/prism/fixtures/whitequark/preexe.txt
deleted file mode 100644
index 9e802f3f4e..0000000000
--- a/test/prism/fixtures/whitequark/preexe.txt
+++ /dev/null
@@ -1 +0,0 @@
-BEGIN { 1 }
diff --git a/test/prism/fixtures/whitequark/procarg0.txt b/test/prism/fixtures/whitequark/procarg0.txt
deleted file mode 100644
index 74cae2c2eb..0000000000
--- a/test/prism/fixtures/whitequark/procarg0.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-m { |(foo, bar)| }
-
-m { |foo| }
diff --git a/test/prism/fixtures/whitequark/range_exclusive.txt b/test/prism/fixtures/whitequark/range_exclusive.txt
deleted file mode 100644
index 9e07faed27..0000000000
--- a/test/prism/fixtures/whitequark/range_exclusive.txt
+++ /dev/null
@@ -1 +0,0 @@
-1...2
diff --git a/test/prism/fixtures/whitequark/range_inclusive.txt b/test/prism/fixtures/whitequark/range_inclusive.txt
deleted file mode 100644
index 8c12abf7de..0000000000
--- a/test/prism/fixtures/whitequark/range_inclusive.txt
+++ /dev/null
@@ -1 +0,0 @@
-1..2
diff --git a/test/prism/fixtures/whitequark/rational.txt b/test/prism/fixtures/whitequark/rational.txt
deleted file mode 100644
index e11cacc742..0000000000
--- a/test/prism/fixtures/whitequark/rational.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-42.1r
-
-42r
diff --git a/test/prism/fixtures/whitequark/redo.txt b/test/prism/fixtures/whitequark/redo.txt
deleted file mode 100644
index f49789cbab..0000000000
--- a/test/prism/fixtures/whitequark/redo.txt
+++ /dev/null
@@ -1 +0,0 @@
-redo
diff --git a/test/prism/fixtures/whitequark/regex_interp.txt b/test/prism/fixtures/whitequark/regex_interp.txt
deleted file mode 100644
index f9ad7fcbc8..0000000000
--- a/test/prism/fixtures/whitequark/regex_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-/foo#{bar}baz/
diff --git a/test/prism/fixtures/whitequark/regex_plain.txt b/test/prism/fixtures/whitequark/regex_plain.txt
deleted file mode 100644
index b86faecf98..0000000000
--- a/test/prism/fixtures/whitequark/regex_plain.txt
+++ /dev/null
@@ -1 +0,0 @@
-/source/im
diff --git a/test/prism/fixtures/whitequark/resbody_list.txt b/test/prism/fixtures/whitequark/resbody_list.txt
deleted file mode 100644
index e40d45fc45..0000000000
--- a/test/prism/fixtures/whitequark/resbody_list.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 92b8bb2c02..0000000000
--- a/test/prism/fixtures/whitequark/resbody_list_mrhs.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0a2fb90b6d..0000000000
--- a/test/prism/fixtures/whitequark/resbody_list_var.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2104ac58e7..0000000000
--- a/test/prism/fixtures/whitequark/resbody_var.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 2d3be9dc56..0000000000
--- a/test/prism/fixtures/whitequark/rescue.txt
+++ /dev/null
@@ -1 +0,0 @@
-begin; meth; rescue; foo; end
diff --git a/test/prism/fixtures/whitequark/rescue_else.txt b/test/prism/fixtures/whitequark/rescue_else.txt
deleted file mode 100644
index a22f8d100e..0000000000
--- a/test/prism/fixtures/whitequark/rescue_else.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 167eee194a..0000000000
--- a/test/prism/fixtures/whitequark/rescue_else_ensure.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 8237257c41..0000000000
--- a/test/prism/fixtures/whitequark/rescue_ensure.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index ccd8ed72c5..0000000000
--- a/test/prism/fixtures/whitequark/rescue_in_lambda_block.txt
+++ /dev/null
@@ -1 +0,0 @@
--> do rescue; end
diff --git a/test/prism/fixtures/whitequark/rescue_mod.txt b/test/prism/fixtures/whitequark/rescue_mod.txt
deleted file mode 100644
index 06375d3e9b..0000000000
--- a/test/prism/fixtures/whitequark/rescue_mod.txt
+++ /dev/null
@@ -1 +0,0 @@
-meth rescue bar
diff --git a/test/prism/fixtures/whitequark/rescue_mod_asgn.txt b/test/prism/fixtures/whitequark/rescue_mod_asgn.txt
deleted file mode 100644
index abf7cd9a3d..0000000000
--- a/test/prism/fixtures/whitequark/rescue_mod_asgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo = meth rescue bar
diff --git a/test/prism/fixtures/whitequark/rescue_mod_masgn.txt b/test/prism/fixtures/whitequark/rescue_mod_masgn.txt
deleted file mode 100644
index 0716eb1f67..0000000000
--- a/test/prism/fixtures/whitequark/rescue_mod_masgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 178efa3a20..0000000000
--- a/test/prism/fixtures/whitequark/rescue_mod_op_assign.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 8416569e2c..0000000000
--- a/test/prism/fixtures/whitequark/rescue_without_begin_end.txt
+++ /dev/null
@@ -1 +0,0 @@
-meth do; foo; rescue; bar; end
diff --git a/test/prism/fixtures/whitequark/restarg_named.txt b/test/prism/fixtures/whitequark/restarg_named.txt
deleted file mode 100644
index 355cd8f493..0000000000
--- a/test/prism/fixtures/whitequark/restarg_named.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(*foo); end
diff --git a/test/prism/fixtures/whitequark/restarg_unnamed.txt b/test/prism/fixtures/whitequark/restarg_unnamed.txt
deleted file mode 100644
index c9932dd30c..0000000000
--- a/test/prism/fixtures/whitequark/restarg_unnamed.txt
+++ /dev/null
@@ -1 +0,0 @@
-def f(*); end
diff --git a/test/prism/fixtures/whitequark/retry.txt b/test/prism/fixtures/whitequark/retry.txt
deleted file mode 100644
index 77428f7b73..0000000000
--- a/test/prism/fixtures/whitequark/retry.txt
+++ /dev/null
@@ -1 +0,0 @@
-retry
diff --git a/test/prism/fixtures/whitequark/return.txt b/test/prism/fixtures/whitequark/return.txt
deleted file mode 100644
index e3d966bda0..0000000000
--- a/test/prism/fixtures/whitequark/return.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-return
-
-return foo
-
-return()
-
-return(foo)
diff --git a/test/prism/fixtures/whitequark/return_block.txt b/test/prism/fixtures/whitequark/return_block.txt
deleted file mode 100644
index 00723a7517..0000000000
--- a/test/prism/fixtures/whitequark/return_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 4d0fb213d8..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_10279.txt
+++ /dev/null
@@ -1 +0,0 @@
-{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
deleted file mode 100644
index 51354a1f70..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_10653.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 1f28cb06f6..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11107.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1631548e3a..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11380.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a25aa9e267..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11873.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index 1856235ce5..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11873_a.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-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
deleted file mode 100644
index 1b86662008..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11873_b.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index d49b8614ed..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11989.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index d0fe7b2739..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_11990.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index b2e3784422..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_12073.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 060d5d95a1..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_12402.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-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
deleted file mode 100644
index cd89689446..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_12669.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 7742e791b8..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_12686.txt
+++ /dev/null
@@ -1 +0,0 @@
-f (g rescue nil)
diff --git a/test/prism/fixtures/whitequark/ruby_bug_13547.txt b/test/prism/fixtures/whitequark/ruby_bug_13547.txt
deleted file mode 100644
index 29eafc3a4c..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_13547.txt
+++ /dev/null
@@ -1 +0,0 @@
-meth[] {}
diff --git a/test/prism/fixtures/whitequark/ruby_bug_14690.txt b/test/prism/fixtures/whitequark/ruby_bug_14690.txt
deleted file mode 100644
index b73b1d8aad..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_14690.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6324db5110..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_15789.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 60dfa09d51..0000000000
--- a/test/prism/fixtures/whitequark/ruby_bug_9669.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-def a b:
-return
-end
-
-o = {
-a:
-1
-}
diff --git a/test/prism/fixtures/whitequark/sclass.txt b/test/prism/fixtures/whitequark/sclass.txt
deleted file mode 100644
index e6aadaef21..0000000000
--- a/test/prism/fixtures/whitequark/sclass.txt
+++ /dev/null
@@ -1 +0,0 @@
-class << foo; nil; end
diff --git a/test/prism/fixtures/whitequark/self.txt b/test/prism/fixtures/whitequark/self.txt
deleted file mode 100644
index 31f9efa4a1..0000000000
--- a/test/prism/fixtures/whitequark/self.txt
+++ /dev/null
@@ -1 +0,0 @@
-self
diff --git a/test/prism/fixtures/whitequark/send_attr_asgn.txt b/test/prism/fixtures/whitequark/send_attr_asgn.txt
deleted file mode 100644
index b477966b2a..0000000000
--- a/test/prism/fixtures/whitequark/send_attr_asgn.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 1279e02cfc..0000000000
--- a/test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b = 1
diff --git a/test/prism/fixtures/whitequark/send_binary_op.txt b/test/prism/fixtures/whitequark/send_binary_op.txt
deleted file mode 100644
index 3e3e9300b3..0000000000
--- a/test/prism/fixtures/whitequark/send_binary_op.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-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
deleted file mode 100644
index c6fe1aab0e..0000000000
--- a/test/prism/fixtures/whitequark/send_block_chain_cmd.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index dcc8361762..0000000000
--- a/test/prism/fixtures/whitequark/send_block_conditional.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo&.bar {}
diff --git a/test/prism/fixtures/whitequark/send_call.txt b/test/prism/fixtures/whitequark/send_call.txt
deleted file mode 100644
index 99701270bb..0000000000
--- a/test/prism/fixtures/whitequark/send_call.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-foo.(1)
-
-foo::(1)
diff --git a/test/prism/fixtures/whitequark/send_conditional.txt b/test/prism/fixtures/whitequark/send_conditional.txt
deleted file mode 100644
index 8ecd27e0fe..0000000000
--- a/test/prism/fixtures/whitequark/send_conditional.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b
diff --git a/test/prism/fixtures/whitequark/send_index.txt b/test/prism/fixtures/whitequark/send_index.txt
deleted file mode 100644
index f9c4dafc4e..0000000000
--- a/test/prism/fixtures/whitequark/send_index.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[1, 2]
diff --git a/test/prism/fixtures/whitequark/send_index_asgn.txt b/test/prism/fixtures/whitequark/send_index_asgn.txt
deleted file mode 100644
index e232fa3b96..0000000000
--- a/test/prism/fixtures/whitequark/send_index_asgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e232fa3b96..0000000000
--- a/test/prism/fixtures/whitequark/send_index_asgn_legacy.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[1, 2] = 3
diff --git a/test/prism/fixtures/whitequark/send_index_cmd.txt b/test/prism/fixtures/whitequark/send_index_cmd.txt
deleted file mode 100644
index 32090e7536..0000000000
--- a/test/prism/fixtures/whitequark/send_index_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[m bar]
diff --git a/test/prism/fixtures/whitequark/send_index_legacy.txt b/test/prism/fixtures/whitequark/send_index_legacy.txt
deleted file mode 100644
index f9c4dafc4e..0000000000
--- a/test/prism/fixtures/whitequark/send_index_legacy.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo[1, 2]
diff --git a/test/prism/fixtures/whitequark/send_lambda.txt b/test/prism/fixtures/whitequark/send_lambda.txt
deleted file mode 100644
index eadd6c9c03..0000000000
--- a/test/prism/fixtures/whitequark/send_lambda.txt
+++ /dev/null
@@ -1,5 +0,0 @@
--> * { }
-
--> do end
-
-->{ }
diff --git a/test/prism/fixtures/whitequark/send_lambda_args.txt b/test/prism/fixtures/whitequark/send_lambda_args.txt
deleted file mode 100644
index 68392f2f34..0000000000
--- a/test/prism/fixtures/whitequark/send_lambda_args.txt
+++ /dev/null
@@ -1,3 +0,0 @@
--> (a) { }
-
-->(a) { }
diff --git a/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt b/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt
deleted file mode 100644
index c0ae077f95..0000000000
--- a/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt
+++ /dev/null
@@ -1,3 +0,0 @@
--> 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
deleted file mode 100644
index 230f35ab89..0000000000
--- a/test/prism/fixtures/whitequark/send_lambda_args_shadow.txt
+++ /dev/null
@@ -1 +0,0 @@
-->(a; foo, bar) { }
diff --git a/test/prism/fixtures/whitequark/send_lambda_legacy.txt b/test/prism/fixtures/whitequark/send_lambda_legacy.txt
deleted file mode 100644
index a509407c43..0000000000
--- a/test/prism/fixtures/whitequark/send_lambda_legacy.txt
+++ /dev/null
@@ -1 +0,0 @@
-->{ }
diff --git a/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt b/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt
deleted file mode 100644
index 906088dcd1..0000000000
--- a/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt
+++ /dev/null
@@ -1 +0,0 @@
-a&.b &&= 1
diff --git a/test/prism/fixtures/whitequark/send_plain.txt b/test/prism/fixtures/whitequark/send_plain.txt
deleted file mode 100644
index ebaf1d18c7..0000000000
--- a/test/prism/fixtures/whitequark/send_plain.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index e3fd63f272..0000000000
--- a/test/prism/fixtures/whitequark/send_plain_cmd.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index f084b9bca7..0000000000
--- a/test/prism/fixtures/whitequark/send_self.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-fun
-
-fun!
-
-fun(1)
diff --git a/test/prism/fixtures/whitequark/send_self_block.txt b/test/prism/fixtures/whitequark/send_self_block.txt
deleted file mode 100644
index 1cd6703c82..0000000000
--- a/test/prism/fixtures/whitequark/send_self_block.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 73814d199f..0000000000
--- a/test/prism/fixtures/whitequark/send_unary_op.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-+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
deleted file mode 100644
index 4962a058ea..0000000000
--- a/test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-<<-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
deleted file mode 100644
index 47957cba54..0000000000
--- a/test/prism/fixtures/whitequark/space_args_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-fun (1)
diff --git a/test/prism/fixtures/whitequark/space_args_arg_block.txt b/test/prism/fixtures/whitequark/space_args_arg_block.txt
deleted file mode 100644
index 5560a82818..0000000000
--- a/test/prism/fixtures/whitequark/space_args_arg_block.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 3b0ae831fe..0000000000
--- a/test/prism/fixtures/whitequark/space_args_arg_call.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a6cdac6ed1..0000000000
--- a/test/prism/fixtures/whitequark/space_args_arg_newline.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-fun (1
-)
diff --git a/test/prism/fixtures/whitequark/space_args_block.txt b/test/prism/fixtures/whitequark/space_args_block.txt
deleted file mode 100644
index 555a097605..0000000000
--- a/test/prism/fixtures/whitequark/space_args_block.txt
+++ /dev/null
@@ -1 +0,0 @@
-fun () {}
diff --git a/test/prism/fixtures/whitequark/space_args_cmd.txt b/test/prism/fixtures/whitequark/space_args_cmd.txt
deleted file mode 100644
index a749695cb7..0000000000
--- a/test/prism/fixtures/whitequark/space_args_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-fun (f bar)
diff --git a/test/prism/fixtures/whitequark/string___FILE__.txt b/test/prism/fixtures/whitequark/string___FILE__.txt
deleted file mode 100644
index 4815727d05..0000000000
--- a/test/prism/fixtures/whitequark/string___FILE__.txt
+++ /dev/null
@@ -1 +0,0 @@
-__FILE__
diff --git a/test/prism/fixtures/whitequark/string_concat.txt b/test/prism/fixtures/whitequark/string_concat.txt
deleted file mode 100644
index 30cc4f8116..0000000000
--- a/test/prism/fixtures/whitequark/string_concat.txt
+++ /dev/null
@@ -1 +0,0 @@
-"foo#@a" "bar"
diff --git a/test/prism/fixtures/whitequark/string_dvar.txt b/test/prism/fixtures/whitequark/string_dvar.txt
deleted file mode 100644
index bbe5b617b2..0000000000
--- a/test/prism/fixtures/whitequark/string_dvar.txt
+++ /dev/null
@@ -1 +0,0 @@
-"#@a #@@a #$a"
diff --git a/test/prism/fixtures/whitequark/string_interp.txt b/test/prism/fixtures/whitequark/string_interp.txt
deleted file mode 100644
index 5fdd803341..0000000000
--- a/test/prism/fixtures/whitequark/string_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-"foo#{bar}baz"
diff --git a/test/prism/fixtures/whitequark/string_plain.txt b/test/prism/fixtures/whitequark/string_plain.txt
deleted file mode 100644
index 4aca78decb..0000000000
--- a/test/prism/fixtures/whitequark/string_plain.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-%q(foobar)
-
-'foobar'
diff --git a/test/prism/fixtures/whitequark/super.txt b/test/prism/fixtures/whitequark/super.txt
deleted file mode 100644
index 9e68a9e988..0000000000
--- a/test/prism/fixtures/whitequark/super.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-super foo
-
-super()
-
-super(foo)
diff --git a/test/prism/fixtures/whitequark/super_block.txt b/test/prism/fixtures/whitequark/super_block.txt
deleted file mode 100644
index 05a7d7fdd8..0000000000
--- a/test/prism/fixtures/whitequark/super_block.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index d5011b270d..0000000000
--- a/test/prism/fixtures/whitequark/symbol_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-:"foo#{bar}baz"
diff --git a/test/prism/fixtures/whitequark/symbol_plain.txt b/test/prism/fixtures/whitequark/symbol_plain.txt
deleted file mode 100644
index fd1fd0017c..0000000000
--- a/test/prism/fixtures/whitequark/symbol_plain.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-:'foo'
-
-:foo
diff --git a/test/prism/fixtures/whitequark/ternary.txt b/test/prism/fixtures/whitequark/ternary.txt
deleted file mode 100644
index 3a149d4e1c..0000000000
--- a/test/prism/fixtures/whitequark/ternary.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo ? 1 : 2
diff --git a/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt b/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt
deleted file mode 100644
index 19aa523c07..0000000000
--- a/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 043870ade2..0000000000
--- a/test/prism/fixtures/whitequark/trailing_forward_arg.txt
+++ /dev/null
@@ -1 +0,0 @@
-def foo(a, b, ...); bar(a, 42, ...); end
diff --git a/test/prism/fixtures/whitequark/true.txt b/test/prism/fixtures/whitequark/true.txt
deleted file mode 100644
index 27ba77ddaf..0000000000
--- a/test/prism/fixtures/whitequark/true.txt
+++ /dev/null
@@ -1 +0,0 @@
-true
diff --git a/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt b/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt
deleted file mode 100644
index f0343e3c8b..0000000000
--- a/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-+2.0 ** 10
-
--2 ** 10
-
--2.0 ** 10
diff --git a/test/prism/fixtures/whitequark/undef.txt b/test/prism/fixtures/whitequark/undef.txt
deleted file mode 100644
index 3e88ec7084..0000000000
--- a/test/prism/fixtures/whitequark/undef.txt
+++ /dev/null
@@ -1 +0,0 @@
-undef foo, :bar, :"foo#{1}"
diff --git a/test/prism/fixtures/whitequark/unless.txt b/test/prism/fixtures/whitequark/unless.txt
deleted file mode 100644
index d04043ed90..0000000000
--- a/test/prism/fixtures/whitequark/unless.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 8243d42031..0000000000
--- a/test/prism/fixtures/whitequark/unless_else.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 2d0376a310..0000000000
--- a/test/prism/fixtures/whitequark/unless_mod.txt
+++ /dev/null
@@ -1 +0,0 @@
-bar unless foo
diff --git a/test/prism/fixtures/whitequark/until.txt b/test/prism/fixtures/whitequark/until.txt
deleted file mode 100644
index 06082233cb..0000000000
--- a/test/prism/fixtures/whitequark/until.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 46a85d2ba9..0000000000
--- a/test/prism/fixtures/whitequark/until_mod.txt
+++ /dev/null
@@ -1 +0,0 @@
-meth until foo
diff --git a/test/prism/fixtures/whitequark/until_post.txt b/test/prism/fixtures/whitequark/until_post.txt
deleted file mode 100644
index 988e43b665..0000000000
--- a/test/prism/fixtures/whitequark/until_post.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 25502968f9..0000000000
--- a/test/prism/fixtures/whitequark/var_and_asgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-a &&= 1
diff --git a/test/prism/fixtures/whitequark/var_op_asgn.txt b/test/prism/fixtures/whitequark/var_op_asgn.txt
deleted file mode 100644
index 402d818a7e..0000000000
--- a/test/prism/fixtures/whitequark/var_op_asgn.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@@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
deleted file mode 100644
index 33f4bc0e73..0000000000
--- a/test/prism/fixtures/whitequark/var_op_asgn_cmd.txt
+++ /dev/null
@@ -1 +0,0 @@
-foo += m foo
diff --git a/test/prism/fixtures/whitequark/var_or_asgn.txt b/test/prism/fixtures/whitequark/var_or_asgn.txt
deleted file mode 100644
index aa30b3d5ca..0000000000
--- a/test/prism/fixtures/whitequark/var_or_asgn.txt
+++ /dev/null
@@ -1 +0,0 @@
-a ||= 1
diff --git a/test/prism/fixtures/whitequark/when_multi.txt b/test/prism/fixtures/whitequark/when_multi.txt
deleted file mode 100644
index b4fbd33125..0000000000
--- a/test/prism/fixtures/whitequark/when_multi.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 695e5da34e..0000000000
--- a/test/prism/fixtures/whitequark/when_splat.txt
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 63293452b3..0000000000
--- a/test/prism/fixtures/whitequark/when_then.txt
+++ /dev/null
@@ -1 +0,0 @@
-case foo; when 'bar' then bar; end
diff --git a/test/prism/fixtures/whitequark/while.txt b/test/prism/fixtures/whitequark/while.txt
deleted file mode 100644
index 28b204f247..0000000000
--- a/test/prism/fixtures/whitequark/while.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index ce3cf01d14..0000000000
--- a/test/prism/fixtures/whitequark/while_mod.txt
+++ /dev/null
@@ -1 +0,0 @@
-meth while foo
diff --git a/test/prism/fixtures/whitequark/while_post.txt b/test/prism/fixtures/whitequark/while_post.txt
deleted file mode 100644
index ac6e05008b..0000000000
--- a/test/prism/fixtures/whitequark/while_post.txt
+++ /dev/null
@@ -1 +0,0 @@
-begin meth end while foo
diff --git a/test/prism/fixtures/whitequark/xstring_interp.txt b/test/prism/fixtures/whitequark/xstring_interp.txt
deleted file mode 100644
index dfede8123f..0000000000
--- a/test/prism/fixtures/whitequark/xstring_interp.txt
+++ /dev/null
@@ -1 +0,0 @@
-`foo#{bar}baz`
diff --git a/test/prism/fixtures/whitequark/xstring_plain.txt b/test/prism/fixtures/whitequark/xstring_plain.txt
deleted file mode 100644
index fce255049d..0000000000
--- a/test/prism/fixtures/whitequark/xstring_plain.txt
+++ /dev/null
@@ -1 +0,0 @@
-`foobar`
diff --git a/test/prism/fixtures/whitequark/yield.txt b/test/prism/fixtures/whitequark/yield.txt
deleted file mode 100644
index 0ecf639589..0000000000
--- a/test/prism/fixtures/whitequark/yield.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-yield
-
-yield foo
-
-yield()
-
-yield(foo)
diff --git a/test/prism/fixtures/whitequark/zsuper.txt b/test/prism/fixtures/whitequark/zsuper.txt
deleted file mode 100644
index 16f5c2d3aa..0000000000
--- a/test/prism/fixtures/whitequark/zsuper.txt
+++ /dev/null
@@ -1 +0,0 @@
-super
diff --git a/test/prism/fixtures/xstring.txt b/test/prism/fixtures/xstring.txt
deleted file mode 100644
index 01bcc09fc5..0000000000
--- a/test/prism/fixtures/xstring.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-%x[foo]
-
-`foo #{bar} baz`
-
-`f\oo`
-
-`foo`
diff --git a/test/prism/fixtures/yield.txt b/test/prism/fixtures/yield.txt
deleted file mode 100644
index d75ab57a18..0000000000
--- a/test/prism/fixtures/yield.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-yield
-
-yield()
-
-yield(1)
-
-yield(1, 2, 3)
diff --git a/test/prism/fuzzer_test.rb b/test/prism/fuzzer_test.rb
deleted file mode 100644
index ac112f897a..0000000000
--- a/test/prism/fuzzer_test.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# frozen_string_literal: true
-
-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
deleted file mode 100644
index 9fbc4d936a..0000000000
--- a/test/prism/heredoc_dedent_test.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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/library_symbols_test.rb b/test/prism/library_symbols_test.rb
deleted file mode 100644
index 4a4d35b2c7..0000000000
--- a/test/prism/library_symbols_test.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-return if RUBY_PLATFORM !~ /linux/
-
-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
deleted file mode 100644
index df391ca048..0000000000
--- a/test/prism/locals_test.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-# 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.2"
-
-# 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
- invalid = []
- todos = []
-
- # Invalid break
- invalid << "break.txt"
- invalid << "if.txt"
- invalid << "rescue.txt"
- invalid << "seattlerb/block_break.txt"
- invalid << "unless.txt"
- invalid << "whitequark/break.txt"
- invalid << "whitequark/break_block.txt"
-
- # Invalid next
- invalid << "next.txt"
- invalid << "seattlerb/block_next.txt"
- invalid << "unparser/corpus/literal/control.txt"
- invalid << "whitequark/next.txt"
- invalid << "whitequark/next_block.txt"
-
- # Invalid redo
- invalid << "keywords.txt"
- invalid << "whitequark/redo.txt"
-
- # Invalid retry
- invalid << "whitequark/retry.txt"
-
- # Invalid yield
- invalid << "seattlerb/dasgn_icky2.txt"
- invalid << "seattlerb/yield_arg.txt"
- invalid << "seattlerb/yield_call_assocs.txt"
- invalid << "seattlerb/yield_empty_parens.txt"
- invalid << "unparser/corpus/literal/yield.txt"
- invalid << "whitequark/args_assocs.txt"
- invalid << "whitequark/args_assocs_legacy.txt"
- invalid << "whitequark/yield.txt"
- invalid << "yield.txt"
-
- # Dead code eliminated
- invalid << "whitequark/ruby_bug_10653.txt"
-
- # case :a
- # in Symbol(*lhs, x, *rhs)
- # end
- todos << "seattlerb/case_in.txt"
-
- # <<~HERE
- # #{<<~THERE}
- # THERE
- # HERE
- todos << "seattlerb/heredoc_nested.txt"
-
- # Ruby < 3.3.0 fails to parse:
- #
- # <<-' HERE'
- # foo
- # HERE
- invalid << "heredocs_leading_whitespace.txt" if RUBY_VERSION < "3.3.0"
-
- base = File.join(__dir__, "fixtures")
- skips = invalid | todos
-
- Dir["**/*.txt", base: base].each do |relative|
- next if skips.include?(relative)
-
- 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
deleted file mode 100644
index 809c1bd8ae..0000000000
--- a/test/prism/location_test.rb
+++ /dev/null
@@ -1,915 +0,0 @@
-# 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, "{ 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", 10..25, &:body)
- assert_location(BeginNode, "module Foo\nrescue then end", 11..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, "break")
- assert_location(BreakNode, "break foo")
- assert_location(BreakNode, "break foo, bar")
- assert_location(BreakNode, "break(foo)")
- 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')")
- 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}/")
- 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_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)
- 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, "next")
- assert_location(NextNode, "next foo")
- assert_location(NextNode, "next foo, bar")
- assert_location(NextNode, "next(foo)")
- 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, "foo in ^bar", 7...11, &:pattern)
- 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, "redo")
- end
-
- def test_RegularExpressionNode
- assert_location(RegularExpressionNode, "/foo/")
- 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, "retry")
- 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_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, "yield")
- assert_location(YieldNode, "yield foo")
- assert_location(YieldNode, "yield foo, bar")
- assert_location(YieldNode, "yield(foo)")
- 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)
- result = Prism.parse(source)
- assert_equal [], result.comments
- assert_equal [], result.errors
-
- 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
deleted file mode 100644
index 812109f2bb..0000000000
--- a/test/prism/magic_comment_test.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-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=big5, tabsize=3, shiftwidth=3"
- ]
-
- examples.each do |example|
- define_method(:"test_magic_comment_#{example}") do
- assert_magic_comment(example)
- end
- end
-
- private
-
- def assert_magic_comment(example)
- expected = Ripper.new(example).tap(&:parse).encoding
- actual = Prism.parse(example).source.source.encoding
- assert_equal expected, actual
- end
- end
-end
diff --git a/test/prism/memsize_test.rb b/test/prism/memsize_test.rb
deleted file mode 100644
index d7e1448dbc..0000000000
--- a/test/prism/memsize_test.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-return if Prism::BACKEND == :FFI
-
-module Prism
- class MemsizeTest < TestCase
- def test_memsize
- result = Debug.memsize("2 + 3")
-
- assert_equal 5, result[:length]
- assert_kind_of Integer, result[:memsize]
- assert_equal 6, result[:node_count]
- end
- end
-end
diff --git a/test/prism/newline_test.rb b/test/prism/newline_test.rb
deleted file mode 100644
index d998502869..0000000000
--- a/test/prism/newline_test.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# 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 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
deleted file mode 100644
index 788ce7b907..0000000000
--- a/test/prism/parameters_signature_test.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-return if RUBY_VERSION < "3.2" || RUBY_ENGINE == "truffleruby"
-
-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
- 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
deleted file mode 100644
index 30086e3155..0000000000
--- a/test/prism/parse_comments_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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_test.rb b/test/prism/parse_test.rb
deleted file mode 100644
index e2de55463c..0000000000
--- a/test/prism/parse_test.rb
+++ /dev/null
@@ -1,283 +0,0 @@
-# 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
- 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
- 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
-
- def test_parse_lex_file
- node, tokens = Prism.parse_lex_file(__FILE__).value
-
- assert_kind_of ProgramNode, node
- refute_empty tokens
- 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[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_parse = ripper_should_match = ripper_enabled
-
- # 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 relative == "seattlerb/pct_w_heredoc_interp_nested.txt" && RUBY_VERSION < "3.3.0"
-
- # 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 if relative == "seattlerb/heredoc_nested.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.
- #
- # Additionally, Ripper cannot parse the %w[] fixture in this file, so set ripper_should_parse to false.
- ripper_should_parse = false if relative == "spanning_heredoc.txt"
-
- # Ruby < 3.3.0 cannot parse heredocs where there are leading whitespace charactes in the heredoc start.
- # Example: <<~' EOF' or <<-' EOF'
- # https://bugs.ruby-lang.org/issues/19539
- ripper_should_parse = false if relative == "heredocs_leading_whitespace.txt" && RUBY_VERSION < "3.3.0"
-
- 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)
-
- if ripper_should_parse
- src = source
-
- case relative
- when /break|next|redo|if|unless|rescue|control|keywords|retry/
- # Uncaught syntax errors: Invalid break, Invalid next
- src = "->do\nrescue\n#{src}\nend"
- ripper_should_match = false
- end
- case src
- when /^ *yield/
- # Uncaught syntax errors: Invalid yield
- src = "def __invalid_yield__\n#{src}\nend"
- ripper_should_match = false
- end
-
- # Make sure that it can be correctly parsed by Ripper. If it can't, then we have a fixture
- # that is invalid Ruby.
- refute_nil(Ripper.sexp_raw(src), "Ripper failed to parse")
- end
-
- # 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
-
- # 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)
-
- # 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_parse && 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"
-
- # 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
-
- assert_equal_nodes(result.value, Prism.load(snippet, Prism.dump(snippet, filepath: relative)).value)
- 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/pattern_test.rb b/test/prism/pattern_test.rb
deleted file mode 100644
index e0aa079cb9..0000000000
--- a/test/prism/pattern_test.rb
+++ /dev/null
@@ -1,132 +0,0 @@
-# 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
deleted file mode 100644
index 0a5fc2b4fc..0000000000
--- a/test/prism/regexp_test.rb
+++ /dev/null
@@ -1,263 +0,0 @@
-# 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_compat_test.rb b/test/prism/ripper_compat_test.rb
deleted file mode 100644
index e30f3824e2..0000000000
--- a/test/prism/ripper_compat_test.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-module Prism
- class RipperCompatTest < TestCase
- def test_binary
- assert_equivalent("1 + 2")
- assert_equivalent("3 - 4 * 5")
- assert_equivalent("6 / 7; 8 % 9")
- end
-
- private
-
- def assert_equivalent(source)
- assert_equal Ripper.sexp_raw(source), RipperCompat.sexp_raw(source)
- end
- end
-end
diff --git a/test/prism/ruby_api_test.rb b/test/prism/ruby_api_test.rb
deleted file mode 100644
index 3bf89f3339..0000000000
--- a/test/prism/ruby_api_test.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-module Prism
- class RubyAPITest < TestCase
- 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
-
- 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 2, Prism.parse("foo", scopes: [[:foo], []]).value.statements.body[0].depth
- 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
- 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_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/snapshots/alias.txt b/test/prism/snapshots/alias.txt
deleted file mode 100644
index b473ab7a9b..0000000000
--- a/test/prism/snapshots/alias.txt
+++ /dev/null
@@ -1,193 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── closing_loc: (7,14)-(7,15) = "}"
- │ │ └── closing_loc: (7,15)-(7,16) = "\""
- │ ├── old_name:
- │ │ @ SymbolNode (location: (7,17)-(7,23))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (11,6)-(11,9) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ ├── old_name:
- │ │ @ SymbolNode (location: (11,10)-(11,13))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (15,6)-(15,9) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ ├── old_name:
- │ │ @ SymbolNode (location: (15,10)-(15,12))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (17,6)-(17,9) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ ├── old_name:
- │ │ @ SymbolNode (location: (17,10)-(17,13))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: (19,6)-(19,7) = ":"
- │ │ ├── value_loc: (19,7)-(19,9) = "=="
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "=="
- │ ├── old_name:
- │ │ @ SymbolNode (location: (19,10)-(19,15))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (21,6)-(21,7) = "A"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "A"
- │ ├── old_name:
- │ │ @ SymbolNode (location: (21,8)-(21,9))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 8eebc70dca..0000000000
--- a/test/prism/snapshots/arithmetic.txt
+++ /dev/null
@@ -1,252 +0,0 @@
-@ ProgramNode (location: (1,0)-(13,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(13,8))
- └── body: (length: 7)
- ├── @ CallNode (location: (1,0)-(1,8))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index d31cd7afc8..0000000000
--- a/test/prism/snapshots/arrays.txt
+++ /dev/null
@@ -1,2268 +0,0 @@
-@ ProgramNode (location: (1,0)-(142,32))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(142,32))
- └── body: (length: 59)
- ├── @ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── @ IntegerNode (location: (3,19)-(3,20))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (3,22)-(3,23))
- │ │ │ └── flags: decimal
- │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (5,1)-(5,12))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (5,1)-(5,3))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: (5,5)-(5,6) = ":"
- │ │ │ │ │ ├── value_loc: (5,6)-(5,7) = "b"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "b"
- │ │ │ │ └── @ SymbolNode (location: (5,9)-(5,11))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (9,1)-(9,2) = ":"
- │ │ │ ├── value_loc: (9,2)-(9,3) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ ├── @ SymbolNode (location: (9,5)-(9,7))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (9,5)-(9,6) = ":"
- │ │ │ ├── value_loc: (9,6)-(9,7) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ ├── @ SymbolNode (location: (10,0)-(10,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── @ SymbolNode (location: (14,0)-(14,2))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (18,1)-(18,2) = ":"
- │ │ │ ├── value_loc: (18,2)-(18,3) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ ├── @ SymbolNode (location: (18,5)-(18,7))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (18,5)-(18,6) = ":"
- │ │ │ ├── value_loc: (18,6)-(18,7) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ ├── @ SymbolNode (location: (19,0)-(19,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── @ SymbolNode (location: (23,0)-(23,2))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── receiver:
- │ │ │ │ @ CallNode (location: (41,0)-(41,3))
- │ │ │ │ ├── flags: variable_call
- │ │ │ │ ├── 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
- │ │ │ ├── closing_loc: (41,5)-(41,6) = "]"
- │ │ │ └── block: ∅
- │ │ └── @ IndexTargetNode (location: (41,8)-(41,14))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (41,8)-(41,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (41,20)-(41,21))
- │ │ └── flags: decimal
- │ ├── opening_loc: ∅
- │ └── closing_loc: ∅
- ├── @ CallNode (location: (43,0)-(43,19))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (43,0)-(43,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ └── @ 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
- │ │ │ ├── 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
- │ │ └── @ 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (62,3)-(62,6) = "one"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "one"
- │ │ ├── @ SymbolNode (location: (62,7)-(62,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (62,7)-(62,10) = "two"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "two"
- │ │ └── @ SymbolNode (location: (62,11)-(62,16))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (69,3)-(69,6) = "one"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "one"
- │ │ ├── @ SymbolNode (location: (69,7)-(69,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (69,7)-(69,10) = "two"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "two"
- │ │ └── @ SymbolNode (location: (69,11)-(69,16))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (76,3)-(76,6) = "one"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "one"
- │ │ ├── @ SymbolNode (location: (76,7)-(76,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (76,7)-(76,10) = "two"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "two"
- │ │ └── @ SymbolNode (location: (76,11)-(76,16))
- │ │ ├── flags: ∅
- │ │ ├── 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) = "]"
- ├── @ CallNode (location: (84,0)-(84,13))
- │ ├── flags: attribute_write
- │ ├── receiver:
- │ │ @ CallNode (location: (84,0)-(84,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (84,0)-(84,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :[]=
- │ ├── message_loc: (84,3)-(84,9) = "[&bar]"
- │ ├── opening_loc: (84,3)-(84,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (84,12)-(84,13))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ IntegerNode (location: (84,12)-(84,13))
- │ │ └── flags: decimal
- │ ├── closing_loc: (84,8)-(84,9) = "]"
- │ └── block:
- │ @ BlockArgumentNode (location: (84,4)-(84,8))
- │ ├── expression:
- │ │ @ CallNode (location: (84,5)-(84,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (84,5)-(84,8) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── operator_loc: (84,4)-(84,5) = "&"
- ├── @ CallNode (location: (86,0)-(86,17))
- │ ├── flags: attribute_write
- │ ├── receiver:
- │ │ @ CallNode (location: (86,0)-(86,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (86,0)-(86,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (86,0)-(86,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (86,3)-(86,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (86,4)-(86,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :[]=
- │ ├── message_loc: (86,7)-(86,13) = "[&bar]"
- │ ├── opening_loc: (86,7)-(86,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (86,16)-(86,17))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ IntegerNode (location: (86,16)-(86,17))
- │ │ └── flags: decimal
- │ ├── closing_loc: (86,12)-(86,13) = "]"
- │ └── block:
- │ @ BlockArgumentNode (location: (86,8)-(86,12))
- │ ├── expression:
- │ │ @ CallNode (location: (86,9)-(86,12))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (86,9)-(86,12) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── operator_loc: (86,8)-(86,9) = "&"
- ├── @ DefNode (location: (88,0)-(90,3))
- │ ├── name: :foo
- │ ├── name_loc: (88,4)-(88,7) = "foo"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (88,8)-(88,9))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (88,8)-(88,9))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (88,8)-(88,9) = "&"
- │ ├── body:
- │ │ @ StatementsNode (location: (89,2)-(89,12))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (89,2)-(89,12))
- │ │ ├── flags: attribute_write
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (89,2)-(89,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :bar
- │ │ │ ├── message_loc: (89,2)-(89,5) = "bar"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :[]=
- │ │ ├── message_loc: (89,5)-(89,8) = "[&]"
- │ │ ├── opening_loc: (89,5)-(89,6) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (89,11)-(89,12))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 1)
- │ │ │ └── @ IntegerNode (location: (89,11)-(89,12))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: (89,7)-(89,8) = "]"
- │ │ └── block:
- │ │ @ BlockArgumentNode (location: (89,6)-(89,7))
- │ │ ├── expression: ∅
- │ │ └── operator_loc: (89,6)-(89,7) = "&"
- │ ├── locals: [:&]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (88,0)-(88,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (88,7)-(88,8) = "("
- │ ├── rparen_loc: (88,9)-(88,10) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (90,0)-(90,3) = "end"
- ├── @ IndexOperatorWriteNode (location: (92,0)-(92,10))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (92,0)-(92,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (92,0)-(92,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (92,3)-(92,4) = "["
- │ ├── arguments: ∅
- │ ├── closing_loc: (92,4)-(92,5) = "]"
- │ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (92,6)-(92,8) = "+="
- │ └── value:
- │ @ IntegerNode (location: (92,9)-(92,10))
- │ └── flags: decimal
- ├── @ IndexOrWriteNode (location: (94,0)-(94,11))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (94,0)-(94,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (94,0)-(94,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (94,3)-(94,4) = "["
- │ ├── arguments: ∅
- │ ├── closing_loc: (94,4)-(94,5) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (94,6)-(94,9) = "||="
- │ └── value:
- │ @ IntegerNode (location: (94,10)-(94,11))
- │ └── flags: decimal
- ├── @ IndexAndWriteNode (location: (96,0)-(96,11))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (96,0)-(96,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ ├── closing_loc: (96,4)-(96,5) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (96,6)-(96,9) = "&&="
- │ └── value:
- │ @ IntegerNode (location: (96,10)-(96,11))
- │ └── flags: decimal
- ├── @ IndexOperatorWriteNode (location: (98,0)-(98,14))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (98,0)-(98,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (98,0)-(98,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (98,0)-(98,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (98,3)-(98,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (98,4)-(98,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (98,7)-(98,8) = "["
- │ ├── arguments: ∅
- │ ├── closing_loc: (98,8)-(98,9) = "]"
- │ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (98,10)-(98,12) = "+="
- │ └── value:
- │ @ IntegerNode (location: (98,13)-(98,14))
- │ └── flags: decimal
- ├── @ IndexOrWriteNode (location: (100,0)-(100,15))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (100,0)-(100,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (100,0)-(100,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (100,0)-(100,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (100,3)-(100,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (100,4)-(100,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (100,7)-(100,8) = "["
- │ ├── arguments: ∅
- │ ├── closing_loc: (100,8)-(100,9) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (100,10)-(100,13) = "||="
- │ └── value:
- │ @ IntegerNode (location: (100,14)-(100,15))
- │ └── flags: decimal
- ├── @ IndexAndWriteNode (location: (102,0)-(102,15))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (102,0)-(102,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (102,0)-(102,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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: ∅
- │ ├── closing_loc: (102,8)-(102,9) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (102,10)-(102,13) = "&&="
- │ └── value:
- │ @ IntegerNode (location: (102,14)-(102,15))
- │ └── flags: decimal
- ├── @ IndexOperatorWriteNode (location: (104,0)-(104,13))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (104,0)-(104,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (104,0)-(104,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (104,3)-(104,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (104,4)-(104,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (104,4)-(104,7))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (104,4)-(104,7) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (104,7)-(104,8) = "]"
- │ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (104,9)-(104,11) = "+="
- │ └── value:
- │ @ IntegerNode (location: (104,12)-(104,13))
- │ └── flags: decimal
- ├── @ IndexOrWriteNode (location: (106,0)-(106,14))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (106,0)-(106,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (106,0)-(106,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (106,3)-(106,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (106,4)-(106,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (106,4)-(106,7))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (106,4)-(106,7) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (106,7)-(106,8) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (106,9)-(106,12) = "||="
- │ └── value:
- │ @ IntegerNode (location: (106,13)-(106,14))
- │ └── flags: decimal
- ├── @ IndexAndWriteNode (location: (108,0)-(108,14))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (108,0)-(108,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (108,0)-(108,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (108,3)-(108,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (108,4)-(108,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (108,4)-(108,7))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (108,4)-(108,7) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (108,7)-(108,8) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (108,9)-(108,12) = "&&="
- │ └── value:
- │ @ IntegerNode (location: (108,13)-(108,14))
- │ └── flags: decimal
- ├── @ IndexOperatorWriteNode (location: (110,0)-(110,17))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (110,0)-(110,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (110,0)-(110,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (110,0)-(110,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (110,3)-(110,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (110,4)-(110,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (110,7)-(110,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (110,8)-(110,11))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (110,8)-(110,11))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (110,8)-(110,11) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (110,11)-(110,12) = "]"
- │ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (110,13)-(110,15) = "+="
- │ └── value:
- │ @ IntegerNode (location: (110,16)-(110,17))
- │ └── flags: decimal
- ├── @ IndexOrWriteNode (location: (112,0)-(112,18))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (112,0)-(112,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (112,0)-(112,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (112,0)-(112,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (112,3)-(112,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (112,4)-(112,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (112,7)-(112,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (112,8)-(112,11))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (112,8)-(112,11))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (112,8)-(112,11) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (112,11)-(112,12) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (112,13)-(112,16) = "||="
- │ └── value:
- │ @ IntegerNode (location: (112,17)-(112,18))
- │ └── flags: decimal
- ├── @ IndexAndWriteNode (location: (114,0)-(114,18))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (114,0)-(114,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (114,0)-(114,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (114,0)-(114,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (114,3)-(114,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (114,4)-(114,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (114,7)-(114,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (114,8)-(114,11))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (114,8)-(114,11))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (114,8)-(114,11) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (114,11)-(114,12) = "]"
- │ ├── block: ∅
- │ ├── operator_loc: (114,13)-(114,16) = "&&="
- │ └── value:
- │ @ IntegerNode (location: (114,17)-(114,18))
- │ └── flags: decimal
- ├── @ IndexOperatorWriteNode (location: (116,0)-(116,19))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (116,0)-(116,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (116,0)-(116,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (116,3)-(116,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (116,4)-(116,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (116,4)-(116,7))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (116,4)-(116,7) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (116,13)-(116,14) = "]"
- │ ├── block:
- │ │ @ BlockArgumentNode (location: (116,9)-(116,13))
- │ │ ├── expression:
- │ │ │ @ CallNode (location: (116,10)-(116,13))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (116,10)-(116,13) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── operator_loc: (116,9)-(116,10) = "&"
- │ ├── operator: :+
- │ ├── operator_loc: (116,15)-(116,17) = "+="
- │ └── value:
- │ @ IntegerNode (location: (116,18)-(116,19))
- │ └── flags: decimal
- ├── @ IndexOrWriteNode (location: (118,0)-(118,20))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (118,0)-(118,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (118,0)-(118,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (118,3)-(118,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (118,4)-(118,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (118,4)-(118,7))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (118,4)-(118,7) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (118,13)-(118,14) = "]"
- │ ├── block:
- │ │ @ BlockArgumentNode (location: (118,9)-(118,13))
- │ │ ├── expression:
- │ │ │ @ CallNode (location: (118,10)-(118,13))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (118,10)-(118,13) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── operator_loc: (118,9)-(118,10) = "&"
- │ ├── operator_loc: (118,15)-(118,18) = "||="
- │ └── value:
- │ @ IntegerNode (location: (118,19)-(118,20))
- │ └── flags: decimal
- ├── @ IndexAndWriteNode (location: (120,0)-(120,20))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (120,0)-(120,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (120,0)-(120,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (120,3)-(120,4) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (120,4)-(120,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (120,4)-(120,7))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (120,4)-(120,7) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (120,13)-(120,14) = "]"
- │ ├── block:
- │ │ @ BlockArgumentNode (location: (120,9)-(120,13))
- │ │ ├── expression:
- │ │ │ @ CallNode (location: (120,10)-(120,13))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (120,10)-(120,13) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── operator_loc: (120,9)-(120,10) = "&"
- │ ├── operator_loc: (120,15)-(120,18) = "&&="
- │ └── value:
- │ @ IntegerNode (location: (120,19)-(120,20))
- │ └── flags: decimal
- ├── @ IndexOperatorWriteNode (location: (122,0)-(122,23))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (122,0)-(122,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (122,0)-(122,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (122,0)-(122,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (122,3)-(122,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (122,4)-(122,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (122,7)-(122,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (122,8)-(122,11))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (122,8)-(122,11))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (122,8)-(122,11) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (122,17)-(122,18) = "]"
- │ ├── block:
- │ │ @ BlockArgumentNode (location: (122,13)-(122,17))
- │ │ ├── expression:
- │ │ │ @ CallNode (location: (122,14)-(122,17))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (122,14)-(122,17) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── operator_loc: (122,13)-(122,14) = "&"
- │ ├── operator: :+
- │ ├── operator_loc: (122,19)-(122,21) = "+="
- │ └── value:
- │ @ IntegerNode (location: (122,22)-(122,23))
- │ └── flags: decimal
- ├── @ IndexOrWriteNode (location: (124,0)-(124,24))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (124,0)-(124,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (124,0)-(124,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (124,0)-(124,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (124,3)-(124,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (124,4)-(124,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (124,7)-(124,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (124,8)-(124,11))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (124,8)-(124,11))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (124,8)-(124,11) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (124,17)-(124,18) = "]"
- │ ├── block:
- │ │ @ BlockArgumentNode (location: (124,13)-(124,17))
- │ │ ├── expression:
- │ │ │ @ CallNode (location: (124,14)-(124,17))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (124,14)-(124,17) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── operator_loc: (124,13)-(124,14) = "&"
- │ ├── operator_loc: (124,19)-(124,22) = "||="
- │ └── value:
- │ @ IntegerNode (location: (124,23)-(124,24))
- │ └── flags: decimal
- ├── @ IndexAndWriteNode (location: (126,0)-(126,24))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (126,0)-(126,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (126,0)-(126,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (126,0)-(126,3) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: (126,3)-(126,4) = "."
- │ │ ├── name: :foo
- │ │ ├── message_loc: (126,4)-(126,7) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── call_operator_loc: ∅
- │ ├── opening_loc: (126,7)-(126,8) = "["
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (126,8)-(126,11))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (126,8)-(126,11))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (126,8)-(126,11) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (126,17)-(126,18) = "]"
- │ ├── block:
- │ │ @ BlockArgumentNode (location: (126,13)-(126,17))
- │ │ ├── expression:
- │ │ │ @ CallNode (location: (126,14)-(126,17))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (126,14)-(126,17) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── operator_loc: (126,13)-(126,14) = "&"
- │ ├── operator_loc: (126,19)-(126,22) = "&&="
- │ └── value:
- │ @ IntegerNode (location: (126,23)-(126,24))
- │ └── flags: decimal
- ├── @ DefNode (location: (128,0)-(128,19))
- │ ├── name: :f
- │ ├── name_loc: (128,4)-(128,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (128,6)-(128,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (128,6)-(128,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (128,6)-(128,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (128,10)-(128,14))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (128,10)-(128,14))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (128,10)-(128,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (128,10)-(128,11) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :[]
- │ │ ├── message_loc: (128,11)-(128,14) = "[*]"
- │ │ ├── opening_loc: (128,11)-(128,12) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (128,12)-(128,13))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 1)
- │ │ │ └── @ SplatNode (location: (128,12)-(128,13))
- │ │ │ ├── operator_loc: (128,12)-(128,13) = "*"
- │ │ │ └── expression: ∅
- │ │ ├── closing_loc: (128,13)-(128,14) = "]"
- │ │ └── block: ∅
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (128,0)-(128,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (128,5)-(128,6) = "("
- │ ├── rparen_loc: (128,7)-(128,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (128,16)-(128,19) = "end"
- ├── @ DefNode (location: (130,0)-(130,22))
- │ ├── name: :f
- │ ├── name_loc: (130,4)-(130,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (130,6)-(130,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (130,6)-(130,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (130,6)-(130,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (130,10)-(130,17))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (130,10)-(130,17))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (130,10)-(130,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (130,10)-(130,11) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :[]
- │ │ ├── message_loc: (130,11)-(130,17) = "[1, *]"
- │ │ ├── opening_loc: (130,11)-(130,12) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (130,12)-(130,16))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 2)
- │ │ │ ├── @ IntegerNode (location: (130,12)-(130,13))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ SplatNode (location: (130,15)-(130,16))
- │ │ │ ├── operator_loc: (130,15)-(130,16) = "*"
- │ │ │ └── expression: ∅
- │ │ ├── closing_loc: (130,16)-(130,17) = "]"
- │ │ └── block: ∅
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (130,0)-(130,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (130,5)-(130,6) = "("
- │ ├── rparen_loc: (130,7)-(130,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (130,19)-(130,22) = "end"
- ├── @ DefNode (location: (132,0)-(132,23))
- │ ├── name: :f
- │ ├── name_loc: (132,4)-(132,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (132,6)-(132,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (132,6)-(132,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (132,6)-(132,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (132,10)-(132,18))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (132,10)-(132,18))
- │ │ ├── flags: attribute_write
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (132,10)-(132,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (132,10)-(132,11) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :[]=
- │ │ ├── message_loc: (132,11)-(132,14) = "[*]"
- │ │ ├── opening_loc: (132,11)-(132,12) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (132,12)-(132,18))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 2)
- │ │ │ ├── @ SplatNode (location: (132,12)-(132,13))
- │ │ │ │ ├── operator_loc: (132,12)-(132,13) = "*"
- │ │ │ │ └── expression: ∅
- │ │ │ └── @ IntegerNode (location: (132,17)-(132,18))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: (132,13)-(132,14) = "]"
- │ │ └── block: ∅
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (132,0)-(132,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (132,5)-(132,6) = "("
- │ ├── rparen_loc: (132,7)-(132,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (132,20)-(132,23) = "end"
- ├── @ DefNode (location: (134,0)-(134,26))
- │ ├── name: :f
- │ ├── name_loc: (134,4)-(134,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (134,6)-(134,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (134,6)-(134,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (134,6)-(134,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (134,10)-(134,21))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (134,10)-(134,21))
- │ │ ├── flags: attribute_write
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (134,10)-(134,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (134,10)-(134,11) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :[]=
- │ │ ├── message_loc: (134,11)-(134,17) = "[1, *]"
- │ │ ├── opening_loc: (134,11)-(134,12) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (134,12)-(134,21))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 3)
- │ │ │ ├── @ IntegerNode (location: (134,12)-(134,13))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── @ SplatNode (location: (134,15)-(134,16))
- │ │ │ │ ├── operator_loc: (134,15)-(134,16) = "*"
- │ │ │ │ └── expression: ∅
- │ │ │ └── @ IntegerNode (location: (134,20)-(134,21))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: (134,16)-(134,17) = "]"
- │ │ └── block: ∅
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (134,0)-(134,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (134,5)-(134,6) = "("
- │ ├── rparen_loc: (134,7)-(134,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (134,23)-(134,26) = "end"
- ├── @ DefNode (location: (136,0)-(136,24))
- │ ├── name: :f
- │ ├── name_loc: (136,4)-(136,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (136,6)-(136,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (136,6)-(136,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (136,6)-(136,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (136,10)-(136,19))
- │ │ └── body: (length: 1)
- │ │ └── @ IndexOperatorWriteNode (location: (136,10)-(136,19))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (136,10)-(136,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (136,10)-(136,11) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── opening_loc: (136,11)-(136,12) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (136,12)-(136,13))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 1)
- │ │ │ └── @ SplatNode (location: (136,12)-(136,13))
- │ │ │ ├── operator_loc: (136,12)-(136,13) = "*"
- │ │ │ └── expression: ∅
- │ │ ├── closing_loc: (136,13)-(136,14) = "]"
- │ │ ├── block: ∅
- │ │ ├── operator: :+
- │ │ ├── operator_loc: (136,15)-(136,17) = "+="
- │ │ └── value:
- │ │ @ IntegerNode (location: (136,18)-(136,19))
- │ │ └── flags: decimal
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (136,0)-(136,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (136,5)-(136,6) = "("
- │ ├── rparen_loc: (136,7)-(136,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (136,21)-(136,24) = "end"
- ├── @ DefNode (location: (138,0)-(138,28))
- │ ├── name: :f
- │ ├── name_loc: (138,4)-(138,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (138,6)-(138,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (138,6)-(138,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (138,6)-(138,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (138,10)-(138,23))
- │ │ └── body: (length: 1)
- │ │ └── @ IndexAndWriteNode (location: (138,10)-(138,23))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (138,10)-(138,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (138,10)-(138,11) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── opening_loc: (138,11)-(138,12) = "["
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (138,12)-(138,16))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 2)
- │ │ │ ├── @ IntegerNode (location: (138,12)-(138,13))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ SplatNode (location: (138,15)-(138,16))
- │ │ │ ├── operator_loc: (138,15)-(138,16) = "*"
- │ │ │ └── expression: ∅
- │ │ ├── closing_loc: (138,16)-(138,17) = "]"
- │ │ ├── block: ∅
- │ │ ├── operator_loc: (138,18)-(138,21) = "&&="
- │ │ └── value:
- │ │ @ IntegerNode (location: (138,22)-(138,23))
- │ │ └── flags: decimal
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (138,0)-(138,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (138,5)-(138,6) = "("
- │ ├── rparen_loc: (138,7)-(138,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (138,25)-(138,28) = "end"
- ├── @ DefNode (location: (140,0)-(140,29))
- │ ├── name: :f
- │ ├── name_loc: (140,4)-(140,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (140,6)-(140,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (140,6)-(140,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (140,6)-(140,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (140,10)-(140,29))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── rescue_clause:
- │ │ │ @ RescueNode (location: (140,10)-(140,24))
- │ │ │ ├── keyword_loc: (140,10)-(140,16) = "rescue"
- │ │ │ ├── exceptions: (length: 0)
- │ │ │ ├── operator_loc: (140,17)-(140,19) = "=>"
- │ │ │ ├── reference:
- │ │ │ │ @ IndexTargetNode (location: (140,20)-(140,24))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver:
- │ │ │ │ │ @ CallNode (location: (140,20)-(140,21))
- │ │ │ │ │ ├── flags: variable_call
- │ │ │ │ │ ├── receiver: ∅
- │ │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ │ ├── name: :a
- │ │ │ │ │ ├── message_loc: (140,20)-(140,21) = "a"
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── arguments: ∅
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── block: ∅
- │ │ │ │ ├── opening_loc: (140,21)-(140,22) = "["
- │ │ │ │ ├── arguments:
- │ │ │ │ │ @ ArgumentsNode (location: (140,22)-(140,23))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ └── arguments: (length: 1)
- │ │ │ │ │ └── @ SplatNode (location: (140,22)-(140,23))
- │ │ │ │ │ ├── operator_loc: (140,22)-(140,23) = "*"
- │ │ │ │ │ └── expression: ∅
- │ │ │ │ ├── closing_loc: (140,23)-(140,24) = "]"
- │ │ │ │ └── block: ∅
- │ │ │ ├── statements: ∅
- │ │ │ └── consequent: ∅
- │ │ ├── else_clause: ∅
- │ │ ├── ensure_clause: ∅
- │ │ └── end_keyword_loc: (140,26)-(140,29) = "end"
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (140,0)-(140,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (140,5)-(140,6) = "("
- │ ├── rparen_loc: (140,7)-(140,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (140,26)-(140,29) = "end"
- └── @ DefNode (location: (142,0)-(142,32))
- ├── name: :f
- ├── name_loc: (142,4)-(142,5) = "f"
- ├── receiver: ∅
- ├── parameters:
- │ @ ParametersNode (location: (142,6)-(142,7))
- │ ├── requireds: (length: 0)
- │ ├── optionals: (length: 0)
- │ ├── rest:
- │ │ @ RestParameterNode (location: (142,6)-(142,7))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (142,6)-(142,7) = "*"
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body:
- │ @ BeginNode (location: (142,10)-(142,32))
- │ ├── begin_keyword_loc: ∅
- │ ├── statements: ∅
- │ ├── rescue_clause:
- │ │ @ RescueNode (location: (142,10)-(142,27))
- │ │ ├── keyword_loc: (142,10)-(142,16) = "rescue"
- │ │ ├── exceptions: (length: 0)
- │ │ ├── operator_loc: (142,17)-(142,19) = "=>"
- │ │ ├── reference:
- │ │ │ @ IndexTargetNode (location: (142,20)-(142,27))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver:
- │ │ │ │ @ CallNode (location: (142,20)-(142,21))
- │ │ │ │ ├── flags: variable_call
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── message_loc: (142,20)-(142,21) = "a"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ ├── opening_loc: (142,21)-(142,22) = "["
- │ │ │ ├── arguments:
- │ │ │ │ @ ArgumentsNode (location: (142,22)-(142,26))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ └── arguments: (length: 2)
- │ │ │ │ ├── @ IntegerNode (location: (142,22)-(142,23))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── @ SplatNode (location: (142,25)-(142,26))
- │ │ │ │ ├── operator_loc: (142,25)-(142,26) = "*"
- │ │ │ │ └── expression: ∅
- │ │ │ ├── closing_loc: (142,26)-(142,27) = "]"
- │ │ │ └── block: ∅
- │ │ ├── statements: ∅
- │ │ └── consequent: ∅
- │ ├── else_clause: ∅
- │ ├── ensure_clause: ∅
- │ └── end_keyword_loc: (142,29)-(142,32) = "end"
- ├── locals: [:*]
- ├── locals_body_index: 1
- ├── def_keyword_loc: (142,0)-(142,3) = "def"
- ├── operator_loc: ∅
- ├── lparen_loc: (142,5)-(142,6) = "("
- ├── rparen_loc: (142,7)-(142,8) = ")"
- ├── equal_loc: ∅
- └── end_keyword_loc: (142,29)-(142,32) = "end"
diff --git a/test/prism/snapshots/begin_ensure.txt b/test/prism/snapshots/begin_ensure.txt
deleted file mode 100644
index 82eb5c6fa3..0000000000
--- a/test/prism/snapshots/begin_ensure.txt
+++ /dev/null
@@ -1,253 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ │ │ │ ├── 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
deleted file mode 100644
index f9cbe096a2..0000000000
--- a/test/prism/snapshots/begin_rescue.txt
+++ /dev/null
@@ -1,699 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index c490e8be19..0000000000
--- a/test/prism/snapshots/blocks.txt
+++ /dev/null
@@ -1,777 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (1,11)-(1,14))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (1,11)-(1,14))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (4,0)-(4,3))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (4,0)-(4,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ ├── closing_loc: (7,10)-(7,11) = ")"
- │ └── block:
- │ @ BlockNode (location: (7,12)-(7,35))
- │ ├── locals: [:x, :memo]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (7,14)-(7,23))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (7,15)-(7,22))
- │ │ │ ├── requireds: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (7,15)-(7,16))
- │ │ │ │ │ └── name: :x
- │ │ │ │ └── @ RequiredParameterNode (location: (7,18)-(7,22))
- │ │ │ │ └── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (9,4)-(9,6) = "do"
- │ └── closing_loc: (9,7)-(9,10) = "end"
- ├── @ CallNode (location: (11,0)-(11,21))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (13,8)-(13,10) = "do"
- │ └── closing_loc: (13,11)-(13,14) = "end"
- ├── @ CallNode (location: (15,0)-(15,18))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (15,12)-(15,14) = "do"
- │ └── closing_loc: (15,15)-(15,18) = "end"
- ├── @ CallNode (location: (17,0)-(18,3))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (21,0)-(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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (25,2)-(28,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (25,2)-(28,5))
- │ │ ├── flags: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (26,4)-(27,7))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (26,4)-(27,7))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (31,11)-(31,14))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (31,11)-(31,14))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (33,6)-(33,20))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (33,7)-(33,19))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (33,7)-(33,8))
- │ │ │ │ └── name: :x
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (33,10)-(33,15))
- │ │ │ │ ├── name: :y
- │ │ │ │ ├── name_loc: (33,10)-(33,11) = "y"
- │ │ │ │ ├── operator_loc: (33,12)-(33,13) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (33,14)-(33,15))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 1)
- │ │ │ │ └── @ RequiredKeywordParameterNode (location: (33,17)-(33,19))
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (35,6)-(35,9))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (35,7)-(35,8))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (35,7)-(35,8))
- │ │ │ │ └── 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
- │ └── operator_loc: (37,5)-(37,6) = "="
- ├── @ CallNode (location: (38,0)-(39,3))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (38,8)-(38,11))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (38,9)-(38,10))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (38,9)-(38,10))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (41,7)-(41,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (41,8)-(41,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (41,8)-(41,9))
- │ │ │ │ └── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (43,2)-(43,4) = "do"
- │ └── closing_loc: (44,0)-(44,3) = "end"
- ├── @ CallNode (location: (46,0)-(46,4))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (46,2)-(46,3) = "{"
- │ └── closing_loc: (46,3)-(46,4) = "}"
- ├── @ CallNode (location: (48,0)-(52,1))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ ├── 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]
- │ │ ├── locals_body_index: 2
- │ │ ├── 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))
- │ │ │ │ │ │ ├── name: :a
- │ │ │ │ │ │ ├── name_loc: (49,2)-(49,4) = "a:"
- │ │ │ │ │ │ └── value:
- │ │ │ │ │ │ @ IntegerNode (location: (49,5)-(49,6))
- │ │ │ │ │ │ └── flags: decimal
- │ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (50,2)-(50,6))
- │ │ │ │ │ ├── name: :b
- │ │ │ │ │ ├── name_loc: (50,2)-(50,4) = "b:"
- │ │ │ │ │ └── value:
- │ │ │ │ │ @ IntegerNode (location: (50,5)-(50,6))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ ├── 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (54,7)-(54,13))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (54,8)-(54,12))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (54,8)-(54,11))
- │ │ │ └── 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
deleted file mode 100644
index 82d85a9cbb..0000000000
--- a/test/prism/snapshots/boolean_operators.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 4731966243..0000000000
--- a/test/prism/snapshots/booleans.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index d605851d63..0000000000
--- a/test/prism/snapshots/break.txt
+++ /dev/null
@@ -1,221 +0,0 @@
-@ ProgramNode (location: (1,0)-(25,23))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(25,23))
- └── body: (length: 11)
- ├── @ BreakNode (location: (1,0)-(1,5))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,0)-(1,5) = "break"
- ├── @ BreakNode (location: (3,0)-(3,19))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (3,6)-(3,19))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 3)
- │ │ ├── @ ParenthesesNode (location: (3,6)-(3,9))
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (3,7)-(3,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (3,7)-(3,8))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── opening_loc: (3,6)-(3,7) = "("
- │ │ │ └── closing_loc: (3,8)-(3,9) = ")"
- │ │ ├── @ ParenthesesNode (location: (3,11)-(3,14))
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (3,12)-(3,13))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (3,12)-(3,13))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── 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
- │ │ ├── opening_loc: (3,16)-(3,17) = "("
- │ │ └── closing_loc: (3,18)-(3,19) = ")"
- │ └── keyword_loc: (3,0)-(3,5) = "break"
- ├── @ BreakNode (location: (5,0)-(5,7))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (5,6)-(5,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ IntegerNode (location: (5,6)-(5,7))
- │ │ └── flags: decimal
- │ └── keyword_loc: (5,0)-(5,5) = "break"
- ├── @ BreakNode (location: (7,0)-(8,1))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (7,6)-(8,1))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 3)
- │ │ ├── @ IntegerNode (location: (7,6)-(7,7))
- │ │ │ └── flags: decimal
- │ │ ├── @ IntegerNode (location: (7,9)-(7,10))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (8,0)-(8,1))
- │ │ └── flags: decimal
- │ └── keyword_loc: (7,0)-(7,5) = "break"
- ├── @ BreakNode (location: (10,0)-(10,13))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (10,6)-(10,13))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 3)
- │ │ ├── @ IntegerNode (location: (10,6)-(10,7))
- │ │ │ └── flags: decimal
- │ │ ├── @ IntegerNode (location: (10,9)-(10,10))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (10,12)-(10,13))
- │ │ └── flags: decimal
- │ └── keyword_loc: (10,0)-(10,5) = "break"
- ├── @ BreakNode (location: (12,0)-(12,15))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (12,6)-(12,15))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ArrayNode (location: (12,6)-(12,15))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 3)
- │ │ │ ├── @ IntegerNode (location: (12,7)-(12,8))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── @ IntegerNode (location: (12,10)-(12,11))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (12,13)-(12,14))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (12,6)-(12,7) = "["
- │ │ └── closing_loc: (12,14)-(12,15) = "]"
- │ └── keyword_loc: (12,0)-(12,5) = "break"
- ├── @ BreakNode (location: (14,0)-(17,1))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (14,5)-(17,1))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (14,5)-(17,1))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (15,2)-(16,3))
- │ │ │ └── body: (length: 2)
- │ │ │ ├── @ IntegerNode (location: (15,2)-(15,3))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (16,2)-(16,3))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (14,5)-(14,6) = "("
- │ │ └── closing_loc: (17,0)-(17,1) = ")"
- │ └── keyword_loc: (14,0)-(14,5) = "break"
- ├── @ BreakNode (location: (19,0)-(19,7))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (19,5)-(19,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (19,5)-(19,7))
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (19,5)-(19,6) = "("
- │ │ └── closing_loc: (19,6)-(19,7) = ")"
- │ └── keyword_loc: (19,0)-(19,5) = "break"
- ├── @ BreakNode (location: (21,0)-(21,8))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (21,5)-(21,8))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (21,5)-(21,8))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (21,6)-(21,7))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (21,6)-(21,7))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (21,5)-(21,6) = "("
- │ │ └── closing_loc: (21,7)-(21,8) = ")"
- │ └── keyword_loc: (21,0)-(21,5) = "break"
- ├── @ CallNode (location: (23,0)-(23,22))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (23,0)-(23,16))
- │ │ ├── flags: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ │ └── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- └── @ CallNode (location: (25,0)-(25,23))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (25,0)-(25,17))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (25,6)-(25,9))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (25,7)-(25,8))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (25,7)-(25,8))
- │ │ │ │ └── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/case.txt b/test/prism/snapshots/case.txt
deleted file mode 100644
index e8aef78b7a..0000000000
--- a/test/prism/snapshots/case.txt
+++ /dev/null
@@ -1,358 +0,0 @@
-@ ProgramNode (location: (1,0)-(44,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(44,22))
- └── body: (length: 13)
- ├── @ CaseNode (location: (1,0)-(3,3))
- │ ├── predicate:
- │ │ @ SymbolNode (location: (1,5)-(1,8))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (2,5)-(2,6) = ":"
- │ │ │ ├── value_loc: (2,6)-(2,8) = "hi"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "hi"
- │ │ └── 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))
- │ │ │ └── statements:
- │ │ │ @ StatementsNode (location: (5,22)-(5,30))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (5,22)-(5,30))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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))
- │ │ └── statements:
- │ │ @ StatementsNode (location: (5,44)-(5,53))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (5,44)-(5,53))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :foo
- │ │ │ ├── message_loc: (7,12)-(7,15) = "foo"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (10,5)-(10,6) = ":"
- │ │ │ ├── value_loc: (10,6)-(10,8) = "hi"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "hi"
- │ │ └── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ └── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── message_loc: (18,12)-(18,15) = "bar"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (22,5)-(22,6) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── 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
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (28,8)-(28,9) = ":"
- │ │ │ ├── value_loc: (28,9)-(28,10) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ └── 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
- │ │ └── 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
- │ │ ├── pattern:
- │ │ │ @ IntegerNode (location: (34,10)-(34,11))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ └── 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
- │ │ ├── pattern:
- │ │ │ @ IntegerNode (location: (38,10)-(38,11))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ └── 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
- │ │ ├── pattern:
- │ │ │ @ IntegerNode (location: (40,10)-(40,11))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── 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
- │ ├── pattern:
- │ │ @ IntegerNode (location: (44,10)-(44,11))
- │ │ └── flags: decimal
- │ └── 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
- │ ├── 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"
diff --git a/test/prism/snapshots/classes.txt b/test/prism/snapshots/classes.txt
deleted file mode 100644
index 7bb029234d..0000000000
--- a/test/prism/snapshots/classes.txt
+++ /dev/null
@@ -1,358 +0,0 @@
-@ 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
- │ │ └── 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,9)-(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,9)-(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
- │ │ └── 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
- │ │ │ ├── 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,24)-(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,24)-(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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index e5cb5202bf..0000000000
--- a/test/prism/snapshots/command_method_call.txt
+++ /dev/null
@@ -1,718 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (3,0)-(3,9))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (5,0)-(5,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (5,0)-(5,5))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (7,0)-(7,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (7,0)-(7,5))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── statements:
- │ @ StatementsNode (location: (9,0)-(9,5))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (9,0)-(9,5))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── statements:
- │ @ StatementsNode (location: (11,0)-(11,5))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (11,0)-(11,5))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ RescueModifierNode (location: (13,0)-(13,18))
- │ ├── expression:
- │ │ @ CallNode (location: (13,0)-(13,5))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── keyword_loc: (13,6)-(13,12) = "rescue"
- │ └── rescue_expression:
- │ @ CallNode (location: (13,13)-(13,18))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (15,0)-(15,10))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (15,0)-(15,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: (15,9)-(15,10) = "]"
- │ └── block: ∅
- ├── @ AndNode (location: (17,0)-(17,15))
- │ ├── left:
- │ │ @ CallNode (location: (17,0)-(17,5))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── right:
- │ │ @ CallNode (location: (17,10)-(17,15))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── operator_loc: (17,6)-(17,9) = "and"
- ├── @ OrNode (location: (19,0)-(19,14))
- │ ├── left:
- │ │ @ CallNode (location: (19,0)-(19,5))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── right:
- │ │ @ CallNode (location: (19,9)-(19,14))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ └── 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
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 5d0b626d90..0000000000
--- a/test/prism/snapshots/comments.txt
+++ /dev/null
@@ -1,145 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 2210e26cc4..0000000000
--- a/test/prism/snapshots/constants.txt
+++ /dev/null
@@ -1,1237 +0,0 @@
-@ 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
- │ │ ├── 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
- ├── @ ConstantWriteNode (location: (9,0)-(9,5))
- │ ├── name: :A
- │ ├── name_loc: (9,0)-(9,1) = "A"
- │ ├── value:
- │ │ @ IntegerNode (location: (9,4)-(9,5))
- │ │ └── flags: decimal
- │ └── operator_loc: (9,2)-(9,3) = "="
- ├── @ ConstantReadNode (location: (11,0)-(11,3))
- │ └── name: :ABC
- ├── @ CallNode (location: (13,0)-(13,5))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (15,0)-(15,8))
- │ ├── flags: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- ├── @ 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
- ├── @ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 60973c73db..0000000000
--- a/test/prism/snapshots/dash_heredocs.txt
+++ /dev/null
@@ -1,254 +0,0 @@
-@ 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
- │ │ │ │ ├── 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))
- │ ├── opening_loc: (25,0)-(25,8) = "<<-\"EOF\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (26,0)-(27,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (30,0)-(30,6) = "<<-EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (31,0)-(32,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ │ ├── opening_loc: (49,7)-(49,11) = "<<-B"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (52,0)-(53,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ └── closing_loc: (54,2)-(54,3) = "}"
- │ │ │ └── @ StringNode (location: (54,3)-(55,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ ├── opening_loc: (57,7)-(57,11) = "<<-B"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (60,0)-(61,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (62,3)-(62,4) = "}"
- │ │ └── @ StringNode (location: (62,4)-(63,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 521cb1cdd7..0000000000
--- a/test/prism/snapshots/defined.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 446ad3b3d9..0000000000
--- a/test/prism/snapshots/dos_endings.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-@ 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: ∅
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (1,5)-(1,9))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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\r\n 3\r\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: ∅
- │ ├── 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))
- │ │ │ ├── opening_loc: (17,8)-(17,14) = "<<~EOF"
- │ │ │ ├── parts: (length: 2)
- │ │ │ │ ├── @ StringNode (location: (18,0)-(19,0))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── content_loc: (18,0)-(19,0) = "\r\n"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "\n"
- │ │ │ │ └── @ StringNode (location: (19,0)-(20,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (19,0)-(20,0) = " baz\r\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "baz\r\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/embdoc_no_newline_at_end.txt b/test/prism/snapshots/embdoc_no_newline_at_end.txt
deleted file mode 100644
index 3a21ce5559..0000000000
--- a/test/prism/snapshots/embdoc_no_newline_at_end.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,0))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,0))
- └── body: (length: 0)
diff --git a/test/prism/snapshots/endless_methods.txt b/test/prism/snapshots/endless_methods.txt
deleted file mode 100644
index 0ff973c119..0000000000
--- a/test/prism/snapshots/endless_methods.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-@ 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index eb5b321c94..0000000000
--- a/test/prism/snapshots/endless_range_in_conditional.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (1,6)-(1,7))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ └── 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
- │ ├── 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
deleted file mode 100644
index b2aeb8fccf..0000000000
--- a/test/prism/snapshots/for.txt
+++ /dev/null
@@ -1,176 +0,0 @@
-@ 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (5,12)-(5,14))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (7,14)-(7,16))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (11,16)-(11,18))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (15,12)-(15,14))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ ├── right:
- │ │ @ IntegerNode (location: (19,12)-(19,14))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 725de21126..0000000000
--- a/test/prism/snapshots/global_variables.txt
+++ /dev/null
@@ -1,191 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ ├── opening_loc: (51,0)-(51,1) = ":"
- │ ├── value_loc: (51,1)-(51,3) = "$_"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$_"
- ├── @ SymbolNode (location: (53,0)-(53,4))
- │ ├── flags: ∅
- │ ├── opening_loc: (53,0)-(53,1) = ":"
- │ ├── value_loc: (53,1)-(53,4) = "$-w"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$-w"
- ├── @ SymbolNode (location: (55,0)-(55,11))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ ├── opening_loc: (57,0)-(57,1) = ":"
- │ ├── value_loc: (57,1)-(57,7) = "$stdin"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$stdin"
- ├── @ SymbolNode (location: (59,0)-(59,8))
- │ ├── flags: ∅
- │ ├── opening_loc: (59,0)-(59,1) = ":"
- │ ├── value_loc: (59,1)-(59,8) = "$stdout"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$stdout"
- ├── @ SymbolNode (location: (61,0)-(61,8))
- │ ├── flags: ∅
- │ ├── opening_loc: (61,0)-(61,1) = ":"
- │ ├── value_loc: (61,1)-(61,8) = "$stderr"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$stderr"
- ├── @ SymbolNode (location: (63,0)-(63,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (63,0)-(63,1) = ":"
- │ ├── value_loc: (63,1)-(63,3) = "$!"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$!"
- ├── @ SymbolNode (location: (65,0)-(65,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (65,0)-(65,1) = ":"
- │ ├── value_loc: (65,1)-(65,3) = "$?"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$?"
- ├── @ SymbolNode (location: (67,0)-(67,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (67,0)-(67,1) = ":"
- │ ├── value_loc: (67,1)-(67,3) = "$~"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$~"
- ├── @ SymbolNode (location: (69,0)-(69,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (69,0)-(69,1) = ":"
- │ ├── value_loc: (69,1)-(69,3) = "$&"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$&"
- ├── @ SymbolNode (location: (71,0)-(71,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (71,0)-(71,1) = ":"
- │ ├── value_loc: (71,1)-(71,3) = "$`"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$`"
- ├── @ SymbolNode (location: (73,0)-(73,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (73,0)-(73,1) = ":"
- │ ├── value_loc: (73,1)-(73,3) = "$'"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$'"
- ├── @ SymbolNode (location: (75,0)-(75,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (75,0)-(75,1) = ":"
- │ ├── value_loc: (75,1)-(75,3) = "$+"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$+"
- ├── @ SymbolNode (location: (77,0)-(77,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (77,0)-(77,1) = ":"
- │ ├── value_loc: (77,1)-(77,3) = "$:"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$:"
- ├── @ SymbolNode (location: (79,0)-(79,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (79,0)-(79,1) = ":"
- │ ├── value_loc: (79,1)-(79,3) = "$;"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$;"
- ├── @ SymbolNode (location: (81,0)-(81,7))
- │ ├── flags: ∅
- │ ├── opening_loc: (81,0)-(81,1) = ":"
- │ ├── value_loc: (81,1)-(81,7) = "$DEBUG"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$DEBUG"
- ├── @ SymbolNode (location: (83,0)-(83,10))
- │ ├── flags: ∅
- │ ├── opening_loc: (83,0)-(83,1) = ":"
- │ ├── value_loc: (83,1)-(83,10) = "$FILENAME"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$FILENAME"
- ├── @ SymbolNode (location: (85,0)-(85,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (85,0)-(85,1) = ":"
- │ ├── value_loc: (85,1)-(85,3) = "$0"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$0"
- ├── @ SymbolNode (location: (87,0)-(87,4))
- │ ├── flags: ∅
- │ ├── opening_loc: (87,0)-(87,1) = ":"
- │ ├── value_loc: (87,1)-(87,4) = "$-0"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$-0"
- ├── @ SymbolNode (location: (89,0)-(89,17))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ ├── opening_loc: (91,0)-(91,1) = ":"
- │ ├── value_loc: (91,1)-(91,9) = "$VERBOSE"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$VERBOSE"
- └── @ SymbolNode (location: (93,0)-(93,4))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 9f930694fe..0000000000
--- a/test/prism/snapshots/hashes.txt
+++ /dev/null
@@ -1,366 +0,0 @@
-@ ProgramNode (location: (1,0)-(26,3))
-├── locals: [:a]
-└── statements:
- @ StatementsNode (location: (1,0)-(26,3))
- └── body: (length: 9)
- ├── @ 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ └── operator_loc: (22,2)-(22,3) = "="
- └── @ CallNode (location: (23,0)-(26,3))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 0
- ├── 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
- │ │ └── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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"
diff --git a/test/prism/snapshots/heredoc_with_comment.txt b/test/prism/snapshots/heredoc_with_comment.txt
deleted file mode 100644
index 117fdc117a..0000000000
--- a/test/prism/snapshots/heredoc_with_comment.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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\r\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
deleted file mode 100644
index 5d17559ed4..0000000000
--- a/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index b064931aa8..0000000000
--- a/test/prism/snapshots/heredoc_with_trailing_newline.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 06116821ca..0000000000
--- a/test/prism/snapshots/heredocs_leading_whitespace.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ ProgramNode (location: (1,0)-(16,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(16,10))
- └── body: (length: 4)
- ├── @ 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"
- ├── @ InterpolatedStringNode (location: (11,0)-(11,10))
- │ ├── opening_loc: (11,0)-(11,10) = "<<~' FOO'"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (12,0)-(13,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (12,0)-(13,0) = "a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (13,0)-(14,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (13,0)-(14,0) = "b\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "b\n"
- │ └── closing_loc: (14,0)-(15,0) = " FOO\n"
- └── @ InterpolatedStringNode (location: (16,0)-(16,10))
- ├── opening_loc: (16,0)-(16,10) = "<<~' FOO'"
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (17,0)-(18,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (17,0)-(18,0) = "a\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "a\n"
- │ └── @ StringNode (location: (18,0)-(19,0))
- │ ├── flags: ∅
- │ ├── opening_loc: ∅
- │ ├── content_loc: (18,0)-(19,0) = "b\n"
- │ ├── closing_loc: ∅
- │ └── unescaped: "b\n"
- └── closing_loc: (19,0)-(20,0) = " FOO\n"
diff --git a/test/prism/snapshots/heredocs_nested.txt b/test/prism/snapshots/heredocs_nested.txt
deleted file mode 100644
index e49e7df97a..0000000000
--- a/test/prism/snapshots/heredocs_nested.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-@ ProgramNode (location: (1,0)-(12,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(12,4))
- └── body: (length: 2)
- ├── @ InterpolatedStringNode (location: (1,0)-(1,7))
- │ ├── opening_loc: (1,0)-(1,7) = "<<~RUBY"
- │ ├── parts: (length: 4)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (7,1)-(8,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (8,0)-(9,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- ├── 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))
- │ │ │ ├── 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))
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ │ │ │ └── closing_loc: (17,3)-(17,4) = "}"
- │ │ │ │ │ │ │ └── @ StringNode (location: (17,4)-(18,0))
- │ │ │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 00111b1ca5..0000000000
--- a/test/prism/snapshots/heredocs_with_ignored_newlines.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-@ 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))
- ├── opening_loc: (4,0)-(4,8) = "<<~THERE"
- ├── parts: (length: 8)
- │ ├── @ StringNode (location: (5,0)-(6,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (5,0)-(6,0) = " way over\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "way over\n"
- │ ├── @ StringNode (location: (6,0)-(7,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (6,0)-(7,0) = " <<HERE\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "<<HERE\n"
- │ ├── @ StringNode (location: (7,0)-(8,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (7,0)-(8,0) = " not here\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: " not here\n"
- │ ├── @ StringNode (location: (8,0)-(9,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (8,0)-(9,0) = " HERE\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "HERE\n"
- │ ├── @ StringNode (location: (9,0)-(10,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (9,0)-(10,0) = "\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "\n"
- │ ├── @ StringNode (location: (10,0)-(12,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (10,0)-(12,0) = " <<~BUT\\\n but\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "<<~BUT but\n"
- │ ├── @ StringNode (location: (12,0)-(13,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (12,0)-(13,0) = " BUT\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "BUT\n"
- │ └── @ StringNode (location: (13,0)-(14,0))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index df422f0c1c..0000000000
--- a/test/prism/snapshots/heredocs_with_ignored_newlines_and_non_empty.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 6733e57bed..0000000000
--- a/test/prism/snapshots/if.txt
+++ /dev/null
@@ -1,454 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ │ └── 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
- │ ├── consequent: ∅
- │ └── end_keyword_loc: ∅
- ├── @ IfNode (location: (10,0)-(10,13))
- │ ├── if_keyword_loc: (10,6)-(10,8) = "if"
- │ ├── predicate:
- │ │ @ TrueNode (location: (10,9)-(10,13))
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (10,0)-(10,5))
- │ │ └── body: (length: 1)
- │ │ └── @ BreakNode (location: (10,0)-(10,5))
- │ │ ├── arguments: ∅
- │ │ └── keyword_loc: (10,0)-(10,5) = "break"
- │ ├── consequent: ∅
- │ └── end_keyword_loc: ∅
- ├── @ IfNode (location: (12,0)-(12,12))
- │ ├── if_keyword_loc: (12,5)-(12,7) = "if"
- │ ├── predicate:
- │ │ @ TrueNode (location: (12,8)-(12,12))
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (12,0)-(12,4))
- │ │ └── body: (length: 1)
- │ │ └── @ NextNode (location: (12,0)-(12,4))
- │ │ ├── arguments: ∅
- │ │ └── keyword_loc: (12,0)-(12,4) = "next"
- │ ├── consequent: ∅
- │ └── end_keyword_loc: ∅
- ├── @ 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: ∅
- ├── @ IfNode (location: (16,0)-(16,30))
- │ ├── if_keyword_loc: (16,0)-(16,2) = "if"
- │ ├── predicate:
- │ │ @ CallNode (location: (16,3)-(16,12))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :exit_loop
- │ │ ├── message_loc: (16,3)-(16,12) = "exit_loop"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── then_keyword_loc: (16,13)-(16,17) = "then"
- │ ├── statements:
- │ │ @ StatementsNode (location: (16,18)-(16,26))
- │ │ └── body: (length: 1)
- │ │ └── @ BreakNode (location: (16,18)-(16,26))
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (16,24)-(16,26))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 1)
- │ │ │ └── @ IntegerNode (location: (16,24)-(16,26))
- │ │ │ └── flags: decimal
- │ │ └── keyword_loc: (16,18)-(16,23) = "break"
- │ ├── consequent: ∅
- │ └── end_keyword_loc: (16,27)-(16,30) = "end"
- ├── @ IfNode (location: (18,0)-(20,3))
- │ ├── if_keyword_loc: (18,0)-(18,2) = "if"
- │ ├── predicate:
- │ │ @ CallNode (location: (18,3)-(18,6))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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: static_keys
- │ │ │ └── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (25,4)-(25,6))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (25,4)-(25,6))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ └── 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
- │ │ │ │ ├── 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:
- │ @ IntegerNode (location: (33,3)-(33,4))
- │ └── flags: decimal
- ├── then_keyword_loc: ∅
- ├── statements:
- │ @ StatementsNode (location: (34,2)-(35,5))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (34,2)-(35,5))
- │ ├── flags: ∅
- │ ├── 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: [:_]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (34,12)-(34,15))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (34,13)-(34,14))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (34,13)-(34,14))
- │ │ │ │ └── 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:
- │ │ @ IntegerNode (location: (36,6)-(36,7))
- │ │ └── flags: decimal
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (37,2)-(38,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (37,2)-(38,5))
- │ │ ├── flags: ∅
- │ │ ├── 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: [:_]
- │ │ ├── locals_body_index: 1
- │ │ ├── parameters:
- │ │ │ @ BlockParametersNode (location: (37,12)-(37,15))
- │ │ │ ├── parameters:
- │ │ │ │ @ ParametersNode (location: (37,13)-(37,14))
- │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ └── @ RequiredParameterNode (location: (37,13)-(37,14))
- │ │ │ │ │ └── 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: ∅
- │ │ │ ├── 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: [:_]
- │ │ │ ├── locals_body_index: 1
- │ │ │ ├── parameters:
- │ │ │ │ @ BlockParametersNode (location: (40,12)-(40,15))
- │ │ │ │ ├── parameters:
- │ │ │ │ │ @ ParametersNode (location: (40,13)-(40,14))
- │ │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ │ └── @ RequiredParameterNode (location: (40,13)-(40,14))
- │ │ │ │ │ │ └── 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
deleted file mode 100644
index 91e8aed58a..0000000000
--- a/test/prism/snapshots/indented_file_end.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index c8b76cacfa..0000000000
--- a/test/prism/snapshots/integer_operations.txt
+++ /dev/null
@@ -1,569 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (7,0)-(7,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (7,0)-(7,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (9,0)-(9,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (9,0)-(9,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (11,0)-(11,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (11,0)-(11,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (13,0)-(13,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (13,0)-(13,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (15,0)-(15,4))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (15,0)-(15,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (17,0)-(17,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (17,0)-(17,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (19,0)-(19,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (19,0)-(19,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (21,0)-(21,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (21,0)-(21,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (25,0)-(25,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (25,0)-(25,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (27,0)-(27,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (27,0)-(27,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (29,0)-(29,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (29,0)-(29,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (31,0)-(31,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (31,0)-(31,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (33,0)-(33,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (33,0)-(33,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (35,0)-(35,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (35,0)-(35,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (37,0)-(37,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (37,0)-(37,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (39,0)-(39,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (39,0)-(39,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (41,0)-(41,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (41,0)-(41,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (43,0)-(43,6))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (43,0)-(43,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (45,0)-(45,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (45,0)-(45,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (47,0)-(47,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (47,0)-(47,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ AndNode (location: (49,0)-(49,6))
- │ ├── left:
- │ │ @ IntegerNode (location: (49,0)-(49,1))
- │ │ └── flags: decimal
- │ ├── right:
- │ │ @ IntegerNode (location: (49,5)-(49,6))
- │ │ └── flags: decimal
- │ └── operator_loc: (49,2)-(49,4) = "&&"
- ├── @ AndNode (location: (51,0)-(51,7))
- │ ├── left:
- │ │ @ IntegerNode (location: (51,0)-(51,1))
- │ │ └── flags: decimal
- │ ├── right:
- │ │ @ IntegerNode (location: (51,6)-(51,7))
- │ │ └── flags: decimal
- │ └── operator_loc: (51,2)-(51,5) = "and"
- ├── @ CallNode (location: (53,0)-(53,10))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (53,0)-(53,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ OrNode (location: (57,0)-(57,6))
- │ ├── left:
- │ │ @ IntegerNode (location: (57,0)-(57,1))
- │ │ └── flags: decimal
- │ ├── right:
- │ │ @ IntegerNode (location: (57,5)-(57,6))
- │ │ └── flags: decimal
- │ └── operator_loc: (57,2)-(57,4) = "or"
- ├── @ OrNode (location: (59,0)-(59,6))
- │ ├── left:
- │ │ @ IntegerNode (location: (59,0)-(59,1))
- │ │ └── flags: decimal
- │ ├── right:
- │ │ @ IntegerNode (location: (59,5)-(59,6))
- │ │ └── flags: decimal
- │ └── operator_loc: (59,2)-(59,4) = "||"
- ├── @ CallNode (location: (61,0)-(61,9))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (61,0)-(61,1))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 0361ac729a..0000000000
--- a/test/prism/snapshots/keyword_method_names.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body: ∅
- │ │ │ ├── opening_loc: (8,6)-(8,8) = "do"
- │ │ │ └── closing_loc: (9,2)-(9,5) = "end"
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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))
- │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ └── filepath: "keyword_method_names.txt"
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 6df11487d7..0000000000
--- a/test/prism/snapshots/keywords.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ ProgramNode (location: (1,0)-(11,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(11,8))
- └── body: (length: 6)
- ├── @ RedoNode (location: (1,0)-(1,4))
- ├── @ RetryNode (location: (3,0)-(3,5))
- ├── @ SelfNode (location: (5,0)-(5,4))
- ├── @ SourceEncodingNode (location: (7,0)-(7,12))
- ├── @ SourceFileNode (location: (9,0)-(9,8))
- │ └── filepath: "keywords.txt"
- └── @ SourceLineNode (location: (11,0)-(11,8))
diff --git a/test/prism/snapshots/lambda.txt b/test/prism/snapshots/lambda.txt
deleted file mode 100644
index 52edf26b52..0000000000
--- a/test/prism/snapshots/lambda.txt
+++ /dev/null
@@ -1,200 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── name: :x
- │ │ │ │ ├── name_loc: (5,3)-(5,5) = "x:"
- │ │ │ │ └── value:
- │ │ │ │ @ InterpolatedStringNode (location: (5,6)-(5,13))
- │ │ │ │ ├── opening_loc: (5,6)-(5,7) = "\""
- │ │ │ │ ├── parts: (length: 2)
- │ │ │ │ │ ├── @ StringNode (location: (5,7)-(5,8))
- │ │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :foo
- │ │ │ ├── name_loc: (11,3)-(11,7) = "foo:"
- │ │ │ └── value:
- │ │ │ @ CallNode (location: (11,8)-(11,11))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
deleted file mode 100644
index 65f0d1df16..0000000000
--- a/test/prism/snapshots/method_calls.txt
+++ /dev/null
@@ -1,2345 +0,0 @@
-@ ProgramNode (location: (1,0)-(149,18))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(149,18))
- └── body: (length: 63)
- ├── @ CallNode (location: (1,0)-(1,14))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (1,0)-(1,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── @ IntegerNode (location: (15,6)-(15,7))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (15,9)-(15,10))
- │ │ └── flags: decimal
- │ ├── closing_loc: (15,10)-(15,11) = ")"
- │ └── block: ∅
- ├── @ CallNode (location: (17,0)-(17,4))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (17,0)-(17,1))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (23,0)-(23,2))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ └── @ IntegerNode (location: (41,22)-(41,23))
- │ │ └── flags: decimal
- │ ├── opening_loc: ∅
- │ └── closing_loc: ∅
- ├── @ CallNode (location: (43,0)-(43,4))
- │ ├── flags: safe_navigation
- │ ├── receiver:
- │ │ @ CallNode (location: (43,0)-(43,1))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── opening_loc: (51,4)-(51,5) = ":"
- │ │ │ │ ├── value_loc: (51,5)-(51,6) = "a"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "a"
- │ │ │ └── @ SymbolNode (location: (51,8)-(51,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (53,4)-(53,5) = ":"
- │ │ │ ├── value_loc: (53,5)-(53,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (55,2)-(55,4))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (60,4)-(60,5) = ":"
- │ │ │ ├── value_loc: (60,5)-(60,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ KeywordHashNode (location: (60,8)-(60,32))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 2)
- │ │ ├── @ AssocNode (location: (60,8)-(60,22))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (60,8)-(60,10))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ │ │ ├── opening_loc: (60,15)-(60,16) = ":"
- │ │ │ │ │ │ ├── value_loc: (60,16)-(60,17) = "x"
- │ │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ │ └── unescaped: "x"
- │ │ │ │ │ └── @ SymbolNode (location: (60,19)-(60,21))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ └── @ 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (64,4)-(64,5) = ":"
- │ │ │ ├── value_loc: (64,5)-(64,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ KeywordHashNode (location: (64,8)-(64,15))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (64,8)-(64,15))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (64,8)-(64,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (64,19)-(64,25))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (64,20)-(64,24))
- │ │ │ ├── requireds: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (64,20)-(64,21))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (64,23)-(64,24))
- │ │ │ │ └── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (66,3)-(66,17))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (66,3)-(66,9))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (74,3)-(74,20))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (74,3)-(74,9))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (76,4)-(76,5) = ":"
- │ │ │ ├── value_loc: (76,5)-(76,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (77,0)-(77,2))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (81,0)-(81,1) = ":"
- │ │ │ ├── value_loc: (81,1)-(81,2) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ KeywordHashNode (location: (82,0)-(82,5))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (82,0)-(82,5))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (82,0)-(82,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 2)
- │ │ ├── @ AssocNode (location: (87,4)-(87,11))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (87,4)-(87,6))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ └── @ KeywordHashNode (location: (89,13)-(89,21))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (89,13)-(89,21))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (89,13)-(89,19))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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
- │ ├── closing_loc: (91,17)-(91,18) = ")"
- │ └── block: ∅
- ├── @ CallNode (location: (93,0)-(93,10))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (93,0)-(93,1))
- │ │ ├── flags: variable_call
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (101,14)-(101,15) = "{"
- │ └── closing_loc: (101,16)-(101,17) = "}"
- ├── @ CallNode (location: (103,0)-(103,12))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (103,4)-(103,11))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (103,4)-(103,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ ├── closing_loc: (103,11)-(103,12) = ")"
- │ └── block: ∅
- ├── @ CallNode (location: (105,0)-(105,28))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (105,4)-(105,28))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (105,4)-(105,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (107,4)-(107,24))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (107,4)-(107,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── 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
- │ │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (109,30)-(109,32) = "do"
- │ └── closing_loc: (109,33)-(109,36) = "end"
- ├── @ CallNode (location: (111,0)-(111,28))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (117,19)-(117,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (117,19)-(117,20))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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]
- │ │ │ ├── locals_body_index: 1
- │ │ │ ├── parameters:
- │ │ │ │ @ BlockParametersNode (location: (121,11)-(121,14))
- │ │ │ │ ├── parameters:
- │ │ │ │ │ @ ParametersNode (location: (121,12)-(121,13))
- │ │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ │ └── @ RequiredParameterNode (location: (121,12)-(121,13))
- │ │ │ │ │ │ └── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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]
- │ │ │ ├── locals_body_index: 1
- │ │ │ ├── parameters:
- │ │ │ │ @ BlockParametersNode (location: (128,11)-(128,14))
- │ │ │ │ ├── parameters:
- │ │ │ │ │ @ ParametersNode (location: (128,12)-(128,13))
- │ │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ │ └── @ RequiredParameterNode (location: (128,12)-(128,13))
- │ │ │ │ │ │ └── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ ├── 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]
- │ │ ├── locals_body_index: 1
- │ │ ├── parameters:
- │ │ │ @ BlockParametersNode (location: (139,9)-(139,12))
- │ │ │ ├── parameters:
- │ │ │ │ @ ParametersNode (location: (139,10)-(139,11))
- │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ └── @ RequiredParameterNode (location: (139,10)-(139,11))
- │ │ │ │ │ └── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (143,9)-(143,10) = "{"
- │ │ └── closing_loc: (143,10)-(143,11) = "}"
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ InterpolatedStringNode (location: (145,0)-(145,17))
- │ ├── 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: ∅
- │ │ │ ├── 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))
- │ ├── 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
- │ │ │ │ ├── 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))
- │ │ ├── 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: ∅
- │ ├── 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: [:*]
- ├── locals_body_index: 1
- ├── 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"
diff --git a/test/prism/snapshots/methods.txt b/test/prism/snapshots/methods.txt
deleted file mode 100644
index 62c117b82e..0000000000
--- a/test/prism/snapshots/methods.txt
+++ /dev/null
@@ -1,2072 +0,0 @@
-@ ProgramNode (location: (1,0)-(186,37))
-├── locals: [:a, :c, :foo]
-└── statements:
- @ StatementsNode (location: (1,0)-(186,37))
- └── body: (length: 70)
- ├── @ 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))
- │ │ │ │ │ └── name: :bar
- │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,17))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ │ └── name: :bar
- │ │ │ │ └── @ RequiredParameterNode (location: (4,14)-(4,17))
- │ │ │ │ └── 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))
- │ │ │ ├── name: :optional
- │ │ │ ├── name_loc: (4,20)-(4,28) = "optional"
- │ │ │ ├── operator_loc: (4,29)-(4,30) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (4,31)-(4,32))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ MultiTargetNode (location: (4,34)-(4,44))
- │ │ │ ├── lefts: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (4,35)-(4,38))
- │ │ │ │ │ └── name: :bin
- │ │ │ │ └── @ RequiredParameterNode (location: (4,40)-(4,43))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 5
- │ ├── 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,7)-(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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :a
- │ │ ├── message_loc: (25,4)-(25,5) = "a"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ ├── name: :b
- │ │ │ └── name_loc: (31,6)-(31,8) = "b:"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :b
- │ │ │ └── name_loc: (35,6)-(35,8) = "b:"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (38,8)-(38,9) = "b"
- │ │ │ └── operator_loc: (38,6)-(38,8) = "**"
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (41,6)-(41,8) = "**"
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:**]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ └── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ └── name: :b
- │ │ │ ├── @ RequiredParameterNode (location: (47,9)-(47,10))
- │ │ │ │ └── name: :c
- │ │ │ └── @ RequiredParameterNode (location: (47,12)-(47,13))
- │ │ │ └── name: :d
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b, :c, :d]
- │ ├── locals_body_index: 3
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ ├── name: :b
- │ │ │ │ └── name_loc: (53,6)-(53,8) = "b:"
- │ │ │ └── @ OptionalKeywordParameterNode (location: (53,10)-(53,14))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (53,10)-(53,12) = "c:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (53,13)-(53,14))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b, :c]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :b
- │ │ │ │ └── name_loc: (56,6)-(56,8) = "b:"
- │ │ │ └── @ OptionalKeywordParameterNode (location: (56,10)-(56,14))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (56,10)-(56,12) = "c:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (56,13)-(56,14))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b, :c]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (59,6)-(59,8) = "b:"
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (60,2)-(60,3))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ RequiredKeywordParameterNode (location: (60,5)-(60,7))
- │ │ │ ├── name: :c
- │ │ │ └── name_loc: (60,5)-(60,7) = "c:"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b, :c]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (65,6)-(65,7) = "b"
- │ │ │ │ ├── operator_loc: (65,8)-(65,9) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (65,10)-(65,11))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ OptionalParameterNode (location: (65,13)-(65,18))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (65,13)-(65,14) = "c"
- │ │ │ ├── operator_loc: (65,15)-(65,16) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (65,17)-(65,18))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b, :c]
- │ ├── locals_body_index: 2
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (71,9)-(71,14))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (71,9)-(71,10) = "c"
- │ │ │ ├── operator_loc: (71,11)-(71,12) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (71,13)-(71,14))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b, :c]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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,7)-(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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (82,6)-(82,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ │ └── operator_loc: (86,2)-(86,3) = "="
- │ ├── locals: [:b]
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── opening_loc: (100,0)-(100,1) = ":"
- │ │ ├── value_loc: (100,1)-(100,4) = "bye"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "bye"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── 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
- │ ├── locals: [:bar]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ ├── 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: ∅
- │ │ ├── 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: [:*]
- │ ├── locals_body_index: 1
- │ ├── 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: ∅
- │ │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── @ IntegerNode (location: (114,17)-(114,18))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ ForwardingArgumentsNode (location: (114,20)-(114,23))
- │ │ ├── closing_loc: (114,23)-(114,24) = ")"
- │ │ └── block: ∅
- │ ├── locals: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (119,7)-(119,8) = "b"
- │ │ └── operator_loc: (119,6)-(119,7) = "&"
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (122,6)-(122,7) = "&"
- │ ├── body: ∅
- │ ├── locals: [:&]
- │ ├── locals_body_index: 1
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ └── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ ├── opening_loc: (136,12)-(136,13) = "\""
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (136,13)-(136,16))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ ├── right:
- │ │ │ │ │ @ IntegerNode (location: (142,16)-(142,18))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── operator_loc: (142,13)-(142,16) = "..."
- │ │ │ ├── opening_loc: (142,11)-(142,12) = "("
- │ │ │ └── closing_loc: (142,18)-(142,19) = ")"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:a]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ └── operator_loc: (145,12)-(145,15) = "..."
- │ │ │ ├── opening_loc: (145,11)-(145,12) = "("
- │ │ │ └── closing_loc: (145,17)-(145,18) = ")"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:a]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ ├── right:
- │ │ │ │ │ @ IntegerNode (location: (151,17)-(151,19))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body: ∅
- │ │ │ ├── opening_loc: (161,12)-(161,13) = "{"
- │ │ │ └── closing_loc: (161,13)-(161,14) = "}"
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:a]
- │ ├── locals_body_index: 1
- │ ├── 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"
- ├── @ DefNode (location: (164,0)-(165,3))
- │ ├── name: :foo
- │ ├── name_loc: (164,4)-(164,7) = "foo"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (164,8)-(164,20))
- │ │ ├── requireds: (length: 4)
- │ │ │ ├── @ RequiredParameterNode (location: (164,8)-(164,10))
- │ │ │ │ └── name: :_a
- │ │ │ ├── @ RequiredParameterNode (location: (164,12)-(164,14))
- │ │ │ │ └── name: :_a
- │ │ │ ├── @ RequiredParameterNode (location: (164,16)-(164,17))
- │ │ │ │ └── name: :b
- │ │ │ └── @ RequiredParameterNode (location: (164,19)-(164,20))
- │ │ │ └── name: :c
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:_a, :b, :c]
- │ ├── locals_body_index: 3
- │ ├── def_keyword_loc: (164,0)-(164,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (164,7)-(164,8) = "("
- │ ├── rparen_loc: (164,20)-(164,21) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (165,0)-(165,3) = "end"
- ├── @ LocalVariableWriteNode (location: (167,0)-(167,7))
- │ ├── name: :foo
- │ ├── depth: 0
- │ ├── name_loc: (167,0)-(167,3) = "foo"
- │ ├── value:
- │ │ @ IntegerNode (location: (167,6)-(167,7))
- │ │ └── flags: decimal
- │ └── operator_loc: (167,4)-(167,5) = "="
- ├── @ DefNode (location: (168,0)-(168,16))
- │ ├── name: :bar
- │ ├── name_loc: (168,8)-(168,11) = "bar"
- │ ├── receiver:
- │ │ @ LocalVariableReadNode (location: (168,4)-(168,7))
- │ │ ├── name: :foo
- │ │ └── depth: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── def_keyword_loc: (168,0)-(168,3) = "def"
- │ ├── operator_loc: (168,7)-(168,8) = "."
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (168,13)-(168,16) = "end"
- ├── @ DefNode (location: (170,0)-(170,18))
- │ ├── name: :f
- │ ├── name_loc: (170,4)-(170,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (170,6)-(170,7))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (170,6)-(170,7))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (170,6)-(170,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (170,10)-(170,13))
- │ │ └── body: (length: 1)
- │ │ └── @ ArrayNode (location: (170,10)-(170,13))
- │ │ ├── flags: contains_splat
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ SplatNode (location: (170,11)-(170,12))
- │ │ │ ├── operator_loc: (170,11)-(170,12) = "*"
- │ │ │ └── expression: ∅
- │ │ ├── opening_loc: (170,10)-(170,11) = "["
- │ │ └── closing_loc: (170,12)-(170,13) = "]"
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (170,0)-(170,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (170,5)-(170,6) = "("
- │ ├── rparen_loc: (170,7)-(170,8) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (170,15)-(170,18) = "end"
- ├── @ DefNode (location: (172,0)-(172,15))
- │ ├── name: :f
- │ ├── name_loc: (172,4)-(172,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (172,6)-(172,10))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 1)
- │ │ │ └── @ OptionalKeywordParameterNode (location: (172,6)-(172,10))
- │ │ │ ├── name: :x
- │ │ │ ├── name_loc: (172,6)-(172,8) = "x:"
- │ │ │ └── value:
- │ │ │ @ CallNode (location: (172,8)-(172,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver:
- │ │ │ │ @ CallNode (location: (172,9)-(172,10))
- │ │ │ │ ├── flags: variable_call
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── message_loc: (172,9)-(172,10) = "a"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :-@
- │ │ │ ├── message_loc: (172,8)-(172,9) = "-"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:x]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (172,0)-(172,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (172,12)-(172,15) = "end"
- ├── @ DefNode (location: (174,0)-(174,15))
- │ ├── name: :f
- │ ├── name_loc: (174,4)-(174,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (174,6)-(174,10))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 1)
- │ │ │ └── @ OptionalKeywordParameterNode (location: (174,6)-(174,10))
- │ │ │ ├── name: :x
- │ │ │ ├── name_loc: (174,6)-(174,8) = "x:"
- │ │ │ └── value:
- │ │ │ @ CallNode (location: (174,8)-(174,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver:
- │ │ │ │ @ CallNode (location: (174,9)-(174,10))
- │ │ │ │ ├── flags: variable_call
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── message_loc: (174,9)-(174,10) = "a"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :+@
- │ │ │ ├── message_loc: (174,8)-(174,9) = "+"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:x]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (174,0)-(174,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (174,12)-(174,15) = "end"
- ├── @ DefNode (location: (176,0)-(176,15))
- │ ├── name: :f
- │ ├── name_loc: (176,4)-(176,5) = "f"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (176,6)-(176,10))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 1)
- │ │ │ └── @ OptionalKeywordParameterNode (location: (176,6)-(176,10))
- │ │ │ ├── name: :x
- │ │ │ ├── name_loc: (176,6)-(176,8) = "x:"
- │ │ │ └── value:
- │ │ │ @ CallNode (location: (176,8)-(176,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver:
- │ │ │ │ @ CallNode (location: (176,9)-(176,10))
- │ │ │ │ ├── flags: variable_call
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── message_loc: (176,9)-(176,10) = "a"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :!
- │ │ │ ├── message_loc: (176,8)-(176,9) = "!"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:x]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (176,0)-(176,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (176,12)-(176,15) = "end"
- ├── @ DefNode (location: (178,0)-(178,20))
- │ ├── name: :foo
- │ ├── name_loc: (178,4)-(178,7) = "foo"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (178,8)-(178,15))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 1)
- │ │ │ └── @ OptionalKeywordParameterNode (location: (178,8)-(178,15))
- │ │ │ ├── name: :x
- │ │ │ ├── name_loc: (178,8)-(178,10) = "x:"
- │ │ │ └── value:
- │ │ │ @ StringNode (location: (178,10)-(178,15))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (178,10)-(178,12) = "%("
- │ │ │ ├── content_loc: (178,12)-(178,14) = "xx"
- │ │ │ ├── closing_loc: (178,14)-(178,15) = ")"
- │ │ │ └── unescaped: "xx"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:x]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (178,0)-(178,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (178,17)-(178,20) = "end"
- ├── @ DefNode (location: (180,0)-(182,3))
- │ ├── name: :foo
- │ ├── name_loc: (180,4)-(180,7) = "foo"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (180,8)-(180,11))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest:
- │ │ │ @ ForwardingParameterNode (location: (180,8)-(180,11))
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (181,2)-(181,7))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (181,2)-(181,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (181,2)-(181,5) = "bar"
- │ │ ├── opening_loc: (181,5)-(181,6) = "("
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: (181,7)-(181,8) = ")"
- │ │ └── block:
- │ │ @ BlockArgumentNode (location: (181,6)-(181,7))
- │ │ ├── expression: ∅
- │ │ └── operator_loc: (181,6)-(181,7) = "&"
- │ ├── locals: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (180,0)-(180,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (180,7)-(180,8) = "("
- │ ├── rparen_loc: (180,11)-(180,12) = ")"
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (182,0)-(182,3) = "end"
- ├── @ DefNode (location: (184,0)-(184,42))
- │ ├── name: :foo
- │ ├── name_loc: (184,4)-(184,7) = "foo"
- │ ├── receiver: ∅
- │ ├── parameters:
- │ │ @ ParametersNode (location: (184,8)-(184,37))
- │ │ ├── requireds: (length: 0)
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (184,8)-(184,37))
- │ │ │ ├── name: :bar
- │ │ │ ├── name_loc: (184,8)-(184,11) = "bar"
- │ │ │ ├── operator_loc: (184,12)-(184,13) = "="
- │ │ │ └── value:
- │ │ │ @ ParenthesesNode (location: (184,14)-(184,37))
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (184,15)-(184,36))
- │ │ │ │ └── body: (length: 2)
- │ │ │ │ ├── @ DefNode (location: (184,15)-(184,33))
- │ │ │ │ │ ├── name: :baz
- │ │ │ │ │ ├── name_loc: (184,19)-(184,22) = "baz"
- │ │ │ │ │ ├── receiver: ∅
- │ │ │ │ │ ├── parameters:
- │ │ │ │ │ │ @ ParametersNode (location: (184,23)-(184,26))
- │ │ │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (184,23)-(184,26))
- │ │ │ │ │ │ │ └── name: :bar
- │ │ │ │ │ │ ├── optionals: (length: 0)
- │ │ │ │ │ │ ├── rest: ∅
- │ │ │ │ │ │ ├── posts: (length: 0)
- │ │ │ │ │ │ ├── keywords: (length: 0)
- │ │ │ │ │ │ ├── keyword_rest: ∅
- │ │ │ │ │ │ └── block: ∅
- │ │ │ │ │ ├── body:
- │ │ │ │ │ │ @ StatementsNode (location: (184,30)-(184,33))
- │ │ │ │ │ │ └── body: (length: 1)
- │ │ │ │ │ │ └── @ LocalVariableReadNode (location: (184,30)-(184,33))
- │ │ │ │ │ │ ├── name: :bar
- │ │ │ │ │ │ └── depth: 0
- │ │ │ │ │ ├── locals: [:bar]
- │ │ │ │ │ ├── locals_body_index: 1
- │ │ │ │ │ ├── def_keyword_loc: (184,15)-(184,18) = "def"
- │ │ │ │ │ ├── operator_loc: ∅
- │ │ │ │ │ ├── lparen_loc: (184,22)-(184,23) = "("
- │ │ │ │ │ ├── rparen_loc: (184,26)-(184,27) = ")"
- │ │ │ │ │ ├── equal_loc: (184,28)-(184,29) = "="
- │ │ │ │ │ └── end_keyword_loc: ∅
- │ │ │ │ └── @ IntegerNode (location: (184,35)-(184,36))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── opening_loc: (184,14)-(184,15) = "("
- │ │ │ └── closing_loc: (184,36)-(184,37) = ")"
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (184,41)-(184,42))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (184,41)-(184,42))
- │ │ └── flags: decimal
- │ ├── locals: [:bar]
- │ ├── locals_body_index: 1
- │ ├── def_keyword_loc: (184,0)-(184,3) = "def"
- │ ├── operator_loc: ∅
- │ ├── lparen_loc: (184,7)-(184,8) = "("
- │ ├── rparen_loc: (184,37)-(184,38) = ")"
- │ ├── equal_loc: (184,39)-(184,40) = "="
- │ └── end_keyword_loc: ∅
- └── @ DefNode (location: (186,0)-(186,37))
- ├── name: :foo
- ├── name_loc: (186,21)-(186,24) = "foo"
- ├── receiver:
- │ @ ParenthesesNode (location: (186,4)-(186,20))
- │ ├── body:
- │ │ @ ClassNode (location: (186,5)-(186,19))
- │ │ ├── locals: []
- │ │ ├── class_keyword_loc: (186,5)-(186,10) = "class"
- │ │ ├── constant_path:
- │ │ │ @ ConstantReadNode (location: (186,11)-(186,14))
- │ │ │ └── name: :Foo
- │ │ ├── inheritance_operator_loc: ∅
- │ │ ├── superclass: ∅
- │ │ ├── body: ∅
- │ │ ├── end_keyword_loc: (186,16)-(186,19) = "end"
- │ │ └── name: :Foo
- │ ├── opening_loc: (186,4)-(186,5) = "("
- │ └── closing_loc: (186,19)-(186,20) = ")"
- ├── parameters:
- │ @ ParametersNode (location: (186,25)-(186,32))
- │ ├── requireds: (length: 0)
- │ ├── optionals: (length: 1)
- │ │ └── @ OptionalParameterNode (location: (186,25)-(186,32))
- │ │ ├── name: :bar
- │ │ ├── name_loc: (186,25)-(186,28) = "bar"
- │ │ ├── operator_loc: (186,29)-(186,30) = "="
- │ │ └── value:
- │ │ @ IntegerNode (location: (186,31)-(186,32))
- │ │ └── flags: decimal
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body:
- │ @ StatementsNode (location: (186,36)-(186,37))
- │ └── body: (length: 1)
- │ └── @ IntegerNode (location: (186,36)-(186,37))
- │ └── flags: decimal
- ├── locals: [:bar]
- ├── locals_body_index: 1
- ├── def_keyword_loc: (186,0)-(186,3) = "def"
- ├── operator_loc: (186,20)-(186,21) = "."
- ├── lparen_loc: (186,24)-(186,25) = "("
- ├── rparen_loc: (186,32)-(186,33) = ")"
- ├── equal_loc: (186,34)-(186,35) = "="
- └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/modules.txt b/test/prism/snapshots/modules.txt
deleted file mode 100644
index cab1bef992..0000000000
--- a/test/prism/snapshots/modules.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-@ 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
- │ │ └── operator_loc: (1,11)-(1,12) = "="
- │ ├── end_keyword_loc: (1,15)-(1,18) = "end"
- │ └── name: :A
- ├── @ InterpolatedStringNode (location: (3,0)-(3,18))
- │ ├── opening_loc: (3,0)-(3,3) = "%Q{"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (3,3)-(3,7))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: (9,1)-(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
- │ │ │ └── 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
- │ │ ├── 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/newline_terminated.txt b/test/prism/snapshots/newline_terminated.txt
deleted file mode 100644
index 496e86fbe4..0000000000
--- a/test/prism/snapshots/newline_terminated.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index aa11809246..0000000000
--- a/test/prism/snapshots/next.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-@ ProgramNode (location: (1,0)-(24,7))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(24,7))
- └── body: (length: 11)
- ├── @ NextNode (location: (1,0)-(1,4))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,0)-(1,4) = "next"
- ├── @ NextNode (location: (3,0)-(3,18))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (3,5)-(3,18))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 3)
- │ │ ├── @ ParenthesesNode (location: (3,5)-(3,8))
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (3,6)-(3,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (3,6)-(3,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── opening_loc: (3,5)-(3,6) = "("
- │ │ │ └── closing_loc: (3,7)-(3,8) = ")"
- │ │ ├── @ ParenthesesNode (location: (3,10)-(3,13))
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (3,11)-(3,12))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (3,11)-(3,12))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── opening_loc: (3,10)-(3,11) = "("
- │ │ │ └── closing_loc: (3,12)-(3,13) = ")"
- │ │ └── @ ParenthesesNode (location: (3,15)-(3,18))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (3,16)-(3,17))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (3,16)-(3,17))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (3,15)-(3,16) = "("
- │ │ └── closing_loc: (3,17)-(3,18) = ")"
- │ └── keyword_loc: (3,0)-(3,4) = "next"
- ├── @ NextNode (location: (5,0)-(5,6))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (5,5)-(5,6))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ IntegerNode (location: (5,5)-(5,6))
- │ │ └── flags: decimal
- │ └── keyword_loc: (5,0)-(5,4) = "next"
- ├── @ NextNode (location: (7,0)-(8,1))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (7,5)-(8,1))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 3)
- │ │ ├── @ IntegerNode (location: (7,5)-(7,6))
- │ │ │ └── flags: decimal
- │ │ ├── @ IntegerNode (location: (7,8)-(7,9))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (8,0)-(8,1))
- │ │ └── flags: decimal
- │ └── keyword_loc: (7,0)-(7,4) = "next"
- ├── @ NextNode (location: (10,0)-(10,12))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (10,5)-(10,12))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 3)
- │ │ ├── @ IntegerNode (location: (10,5)-(10,6))
- │ │ │ └── flags: decimal
- │ │ ├── @ IntegerNode (location: (10,8)-(10,9))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (10,11)-(10,12))
- │ │ └── flags: decimal
- │ └── keyword_loc: (10,0)-(10,4) = "next"
- ├── @ NextNode (location: (12,0)-(12,14))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (12,5)-(12,14))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ArrayNode (location: (12,5)-(12,14))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 3)
- │ │ │ ├── @ IntegerNode (location: (12,6)-(12,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── @ IntegerNode (location: (12,9)-(12,10))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (12,12)-(12,13))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (12,5)-(12,6) = "["
- │ │ └── closing_loc: (12,13)-(12,14) = "]"
- │ └── keyword_loc: (12,0)-(12,4) = "next"
- ├── @ NextNode (location: (14,0)-(17,1))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (14,4)-(17,1))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (14,4)-(17,1))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (15,2)-(16,3))
- │ │ │ └── body: (length: 2)
- │ │ │ ├── @ IntegerNode (location: (15,2)-(15,3))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (16,2)-(16,3))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (14,4)-(14,5) = "("
- │ │ └── closing_loc: (17,0)-(17,1) = ")"
- │ └── keyword_loc: (14,0)-(14,4) = "next"
- ├── @ NextNode (location: (19,0)-(19,4))
- │ ├── arguments: ∅
- │ └── keyword_loc: (19,0)-(19,4) = "next"
- ├── @ IntegerNode (location: (20,0)-(20,1))
- │ └── flags: decimal
- ├── @ NextNode (location: (22,0)-(22,6))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (22,4)-(22,6))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (22,4)-(22,6))
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (22,4)-(22,5) = "("
- │ │ └── closing_loc: (22,5)-(22,6) = ")"
- │ └── keyword_loc: (22,0)-(22,4) = "next"
- └── @ NextNode (location: (24,0)-(24,7))
- ├── arguments:
- │ @ ArgumentsNode (location: (24,4)-(24,7))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ ParenthesesNode (location: (24,4)-(24,7))
- │ ├── body:
- │ │ @ StatementsNode (location: (24,5)-(24,6))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (24,5)-(24,6))
- │ │ └── flags: decimal
- │ ├── opening_loc: (24,4)-(24,5) = "("
- │ └── closing_loc: (24,6)-(24,7) = ")"
- └── keyword_loc: (24,0)-(24,4) = "next"
diff --git a/test/prism/snapshots/nils.txt b/test/prism/snapshots/nils.txt
deleted file mode 100644
index cbadbcf911..0000000000
--- a/test/prism/snapshots/nils.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index f7b210fdda..0000000000
--- a/test/prism/snapshots/non_alphanumeric_methods.txt
+++ /dev/null
@@ -1,536 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (27,8)-(27,9) = "b"
- │ │ │ └── operator_loc: (27,6)-(27,8) = "**"
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :a
- │ │ ├── message_loc: (48,4)-(48,5) = "a"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 572e7b13ca..0000000000
--- a/test/prism/snapshots/not.txt
+++ /dev/null
@@ -1,351 +0,0 @@
-@ 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index c27f2a6354..0000000000
--- a/test/prism/snapshots/numbers.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-@ 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
- ├── @ IntegerNode (location: (3,0)-(3,1))
- │ └── flags: decimal
- ├── @ FloatNode (location: (5,0)-(5,3))
- ├── @ IntegerNode (location: (7,0)-(7,1))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (9,0)-(9,3))
- │ └── flags: binary
- ├── @ IntegerNode (location: (11,0)-(11,3))
- │ └── flags: binary
- ├── @ IntegerNode (location: (13,0)-(13,4))
- │ └── flags: binary
- ├── @ IntegerNode (location: (15,0)-(15,3))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (17,0)-(17,3))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (19,0)-(19,3))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (21,0)-(21,2))
- │ └── flags: octal
- ├── @ IntegerNode (location: (23,0)-(23,2))
- │ └── flags: octal
- ├── @ IntegerNode (location: (25,0)-(25,2))
- │ └── flags: octal
- ├── @ IntegerNode (location: (27,0)-(27,3))
- │ └── flags: octal
- ├── @ IntegerNode (location: (29,0)-(29,3))
- │ └── flags: octal
- ├── @ IntegerNode (location: (31,0)-(31,3))
- │ └── flags: octal
- ├── @ IntegerNode (location: (33,0)-(33,3))
- │ └── flags: hexadecimal
- ├── @ IntegerNode (location: (35,0)-(35,3))
- │ └── flags: hexadecimal
- ├── @ IntegerNode (location: (37,0)-(37,3))
- │ └── flags: hexadecimal
- ├── @ ImaginaryNode (location: (39,0)-(39,2))
- │ └── numeric:
- │ @ IntegerNode (location: (39,0)-(39,1))
- │ └── flags: decimal
- ├── @ RationalNode (location: (41,0)-(41,2))
- │ └── numeric:
- │ @ IntegerNode (location: (41,0)-(41,1))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (43,0)-(43,2))
- │ └── flags: decimal
- ├── @ ImaginaryNode (location: (45,0)-(45,3))
- │ └── numeric:
- │ @ RationalNode (location: (45,0)-(45,2))
- │ └── numeric:
- │ @ IntegerNode (location: (45,0)-(45,1))
- │ └── flags: decimal
- ├── @ RationalNode (location: (47,0)-(47,4))
- │ └── numeric:
- │ @ FloatNode (location: (47,0)-(47,3))
- ├── @ ImaginaryNode (location: (49,0)-(49,5))
- │ └── numeric:
- │ @ RationalNode (location: (49,0)-(49,4))
- │ └── numeric:
- │ @ FloatNode (location: (49,0)-(49,3))
- ├── @ ImaginaryNode (location: (51,0)-(51,4))
- │ └── numeric:
- │ @ RationalNode (location: (51,0)-(51,3))
- │ └── numeric:
- │ @ IntegerNode (location: (51,0)-(51,2))
- │ └── flags: decimal
- ├── @ RationalNode (location: (53,0)-(53,5))
- │ └── numeric:
- │ @ FloatNode (location: (53,0)-(53,4))
- ├── @ ImaginaryNode (location: (55,0)-(55,6))
- │ └── numeric:
- │ @ RationalNode (location: (55,0)-(55,5))
- │ └── numeric:
- │ @ FloatNode (location: (55,0)-(55,4))
- ├── @ RationalNode (location: (57,0)-(57,4))
- │ └── numeric:
- │ @ IntegerNode (location: (57,0)-(57,3))
- │ └── flags: octal
- ├── @ ImaginaryNode (location: (59,0)-(59,4))
- │ └── numeric:
- │ @ IntegerNode (location: (59,0)-(59,3))
- │ └── flags: octal
- ├── @ ImaginaryNode (location: (61,0)-(61,5))
- │ └── numeric:
- │ @ RationalNode (location: (61,0)-(61,4))
- │ └── numeric:
- │ @ IntegerNode (location: (61,0)-(61,3))
- │ └── flags: octal
- ├── @ RationalNode (location: (63,0)-(63,4))
- │ └── numeric:
- │ @ IntegerNode (location: (63,0)-(63,3))
- │ └── flags: decimal
- ├── @ ImaginaryNode (location: (65,0)-(65,4))
- │ └── numeric:
- │ @ IntegerNode (location: (65,0)-(65,3))
- │ └── flags: decimal
- └── @ ImaginaryNode (location: (67,0)-(67,5))
- └── numeric:
- @ RationalNode (location: (67,0)-(67,4))
- └── numeric:
- @ IntegerNode (location: (67,0)-(67,3))
- └── flags: binary
diff --git a/test/prism/snapshots/patterns.txt b/test/prism/snapshots/patterns.txt
deleted file mode 100644
index aacdbb250e..0000000000
--- a/test/prism/snapshots/patterns.txt
+++ /dev/null
@@ -1,4761 +0,0 @@
-@ ProgramNode (location: (1,0)-(202,19))
-├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x]
-└── statements:
- @ StatementsNode (location: (1,0)-(202,19))
- └── body: (length: 175)
- ├── @ MatchRequiredNode (location: (1,0)-(1,10))
- │ ├── value:
- │ │ @ CallNode (location: (1,0)-(1,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ └── operator_loc: (2,4)-(2,6) = "=>"
- ├── @ MatchRequiredNode (location: (3,0)-(3,10))
- │ ├── value:
- │ │ @ CallNode (location: (3,0)-(3,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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))
- │ └── operator_loc: (3,4)-(3,6) = "=>"
- ├── @ MatchRequiredNode (location: (4,0)-(4,9))
- │ ├── value:
- │ │ @ CallNode (location: (4,0)-(4,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ └── operator_loc: (4,4)-(4,6) = "=>"
- ├── @ MatchRequiredNode (location: (5,0)-(5,9))
- │ ├── value:
- │ │ @ CallNode (location: (5,0)-(5,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ └── operator_loc: (5,4)-(5,6) = "=>"
- ├── @ MatchRequiredNode (location: (6,0)-(6,11))
- │ ├── value:
- │ │ @ CallNode (location: (6,0)-(6,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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))
- │ │ └── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (28,12)-(28,13))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── 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))
- │ │ ├── right:
- │ │ │ @ FloatNode (location: (29,14)-(29,17))
- │ │ └── 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
- │ │ ├── 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
- │ │ ├── right:
- │ │ │ @ ImaginaryNode (location: (30,13)-(30,15))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (30,13)-(30,14))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── 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
- │ │ ├── right:
- │ │ │ @ RationalNode (location: (31,13)-(31,15))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (31,13)-(31,14))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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))
- │ │ │ └── filepath: "patterns.txt"
- │ │ ├── right:
- │ │ │ @ SourceFileNode (location: (49,19)-(49,27))
- │ │ │ └── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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) = "=>"
- ├── @ MatchRequiredNode (location: (54,0)-(54,11))
- │ ├── value:
- │ │ @ CallNode (location: (54,0)-(54,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (54,0)-(54,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ PinnedVariableNode (location: (54,7)-(54,11))
- │ │ ├── variable:
- │ │ │ @ LocalVariableReadNode (location: (54,8)-(54,11))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ └── operator_loc: (54,7)-(54,8) = "^"
- │ └── operator_loc: (54,4)-(54,6) = "=>"
- ├── @ MatchRequiredNode (location: (55,0)-(55,12))
- │ ├── value:
- │ │ @ CallNode (location: (55,0)-(55,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── @ IntegerNode (location: (70,14)-(70,15))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (70,17)-(70,18))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── @ IntegerNode (location: (78,14)-(78,15))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (78,17)-(78,18))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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,9))
- │ ├── value:
- │ │ @ CallNode (location: (91,0)-(91,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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,9))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── opening_loc: (91,7)-(91,8) = "["
- │ │ └── closing_loc: (91,8)-(91,9) = "]"
- │ └── operator_loc: (91,4)-(91,6) = "=>"
- ├── @ MatchRequiredNode (location: (92,0)-(92,17))
- │ ├── value:
- │ │ @ CallNode (location: (92,0)-(92,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (92,0)-(92,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayPatternNode (location: (92,7)-(92,17))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ ArrayPatternNode (location: (92,8)-(92,16))
- │ │ │ ├── constant: ∅
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ ArrayPatternNode (location: (92,9)-(92,15))
- │ │ │ │ ├── constant: ∅
- │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ └── @ ArrayPatternNode (location: (92,10)-(92,14))
- │ │ │ │ │ ├── constant: ∅
- │ │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ │ └── @ ArrayPatternNode (location: (92,11)-(92,13))
- │ │ │ │ │ │ ├── constant: ∅
- │ │ │ │ │ │ ├── requireds: (length: 0)
- │ │ │ │ │ │ ├── rest: ∅
- │ │ │ │ │ │ ├── posts: (length: 0)
- │ │ │ │ │ │ ├── opening_loc: (92,11)-(92,12) = "["
- │ │ │ │ │ │ └── closing_loc: (92,12)-(92,13) = "]"
- │ │ │ │ │ ├── rest: ∅
- │ │ │ │ │ ├── posts: (length: 0)
- │ │ │ │ │ ├── opening_loc: (92,10)-(92,11) = "["
- │ │ │ │ │ └── closing_loc: (92,13)-(92,14) = "]"
- │ │ │ │ ├── rest: ∅
- │ │ │ │ ├── posts: (length: 0)
- │ │ │ │ ├── opening_loc: (92,9)-(92,10) = "["
- │ │ │ │ └── closing_loc: (92,14)-(92,15) = "]"
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── opening_loc: (92,8)-(92,9) = "["
- │ │ │ └── closing_loc: (92,15)-(92,16) = "]"
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── opening_loc: (92,7)-(92,8) = "["
- │ │ └── closing_loc: (92,16)-(92,17) = "]"
- │ └── operator_loc: (92,4)-(92,6) = "=>"
- ├── @ MatchRequiredNode (location: (94,0)-(94,13))
- │ ├── value:
- │ │ @ CallNode (location: (94,0)-(94,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (94,0)-(94,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayPatternNode (location: (94,7)-(94,13))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 0)
- │ │ ├── rest:
- │ │ │ @ SplatNode (location: (94,8)-(94,12))
- │ │ │ ├── operator_loc: (94,8)-(94,9) = "*"
- │ │ │ └── expression:
- │ │ │ @ LocalVariableTargetNode (location: (94,9)-(94,12))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── posts: (length: 0)
- │ │ ├── opening_loc: (94,7)-(94,8) = "["
- │ │ └── closing_loc: (94,12)-(94,13) = "]"
- │ └── operator_loc: (94,4)-(94,6) = "=>"
- ├── @ MatchRequiredNode (location: (95,0)-(95,23))
- │ ├── value:
- │ │ @ CallNode (location: (95,0)-(95,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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,23))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 0)
- │ │ ├── rest:
- │ │ │ @ SplatNode (location: (95,8)-(95,12))
- │ │ │ ├── operator_loc: (95,8)-(95,9) = "*"
- │ │ │ └── expression:
- │ │ │ @ LocalVariableTargetNode (location: (95,9)-(95,12))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── posts: (length: 2)
- │ │ │ ├── @ LocalVariableTargetNode (location: (95,14)-(95,17))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ └── @ LocalVariableTargetNode (location: (95,19)-(95,22))
- │ │ │ ├── name: :qux
- │ │ │ └── depth: 0
- │ │ ├── opening_loc: (95,7)-(95,8) = "["
- │ │ └── closing_loc: (95,22)-(95,23) = "]"
- │ └── operator_loc: (95,4)-(95,6) = "=>"
- ├── @ MatchRequiredNode (location: (96,0)-(96,23))
- │ ├── value:
- │ │ @ CallNode (location: (96,0)-(96,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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,23))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ LocalVariableTargetNode (location: (96,8)-(96,11))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── rest:
- │ │ │ @ SplatNode (location: (96,13)-(96,17))
- │ │ │ ├── operator_loc: (96,13)-(96,14) = "*"
- │ │ │ └── expression:
- │ │ │ @ LocalVariableTargetNode (location: (96,14)-(96,17))
- │ │ │ ├── name: :baz
- │ │ │ └── depth: 0
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ LocalVariableTargetNode (location: (96,19)-(96,22))
- │ │ │ ├── name: :qux
- │ │ │ └── depth: 0
- │ │ ├── opening_loc: (96,7)-(96,8) = "["
- │ │ └── closing_loc: (96,22)-(96,23) = "]"
- │ └── operator_loc: (96,4)-(96,6) = "=>"
- ├── @ MatchRequiredNode (location: (97,0)-(97,23))
- │ ├── value:
- │ │ @ CallNode (location: (97,0)-(97,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (97,0)-(97,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayPatternNode (location: (97,7)-(97,23))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ LocalVariableTargetNode (location: (97,8)-(97,11))
- │ │ │ │ ├── name: :bar
- │ │ │ │ └── depth: 0
- │ │ │ └── @ LocalVariableTargetNode (location: (97,13)-(97,16))
- │ │ │ ├── name: :baz
- │ │ │ └── depth: 0
- │ │ ├── rest:
- │ │ │ @ SplatNode (location: (97,18)-(97,22))
- │ │ │ ├── operator_loc: (97,18)-(97,19) = "*"
- │ │ │ └── expression:
- │ │ │ @ LocalVariableTargetNode (location: (97,19)-(97,22))
- │ │ │ ├── name: :qux
- │ │ │ └── depth: 0
- │ │ ├── posts: (length: 0)
- │ │ ├── opening_loc: (97,7)-(97,8) = "["
- │ │ └── closing_loc: (97,22)-(97,23) = "]"
- │ └── operator_loc: (97,4)-(97,6) = "=>"
- ├── @ MatchRequiredNode (location: (98,0)-(98,24))
- │ ├── value:
- │ │ @ CallNode (location: (98,0)-(98,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (98,0)-(98,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ FindPatternNode (location: (98,7)-(98,24))
- │ │ ├── constant: ∅
- │ │ ├── left:
- │ │ │ @ SplatNode (location: (98,8)-(98,12))
- │ │ │ ├── operator_loc: (98,8)-(98,9) = "*"
- │ │ │ └── expression:
- │ │ │ @ LocalVariableTargetNode (location: (98,9)-(98,12))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ LocalVariableTargetNode (location: (98,14)-(98,17))
- │ │ │ ├── name: :baz
- │ │ │ └── depth: 0
- │ │ ├── right:
- │ │ │ @ SplatNode (location: (98,19)-(98,23))
- │ │ │ ├── operator_loc: (98,19)-(98,20) = "*"
- │ │ │ └── expression:
- │ │ │ @ LocalVariableTargetNode (location: (98,20)-(98,23))
- │ │ │ ├── name: :qux
- │ │ │ └── depth: 0
- │ │ ├── opening_loc: (98,7)-(98,8) = "["
- │ │ └── closing_loc: (98,23)-(98,24) = "]"
- │ └── operator_loc: (98,4)-(98,6) = "=>"
- ├── @ MatchPredicateNode (location: (100,0)-(100,10))
- │ ├── value:
- │ │ @ CallNode (location: (100,0)-(100,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (100,0)-(100,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ LocalVariableTargetNode (location: (100,7)-(100,10))
- │ │ ├── name: :bar
- │ │ └── depth: 0
- │ └── operator_loc: (100,4)-(100,6) = "in"
- ├── @ MatchPredicateNode (location: (101,0)-(101,8))
- │ ├── value:
- │ │ @ CallNode (location: (101,0)-(101,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (101,0)-(101,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ IntegerNode (location: (101,7)-(101,8))
- │ │ └── flags: decimal
- │ └── operator_loc: (101,4)-(101,6) = "in"
- ├── @ MatchPredicateNode (location: (102,0)-(102,10))
- │ ├── value:
- │ │ @ CallNode (location: (102,0)-(102,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (102,0)-(102,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ FloatNode (location: (102,7)-(102,10))
- │ └── operator_loc: (102,4)-(102,6) = "in"
- ├── @ MatchPredicateNode (location: (103,0)-(103,9))
- │ ├── value:
- │ │ @ CallNode (location: (103,0)-(103,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (103,0)-(103,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ImaginaryNode (location: (103,7)-(103,9))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (103,7)-(103,8))
- │ │ └── flags: decimal
- │ └── operator_loc: (103,4)-(103,6) = "in"
- ├── @ MatchPredicateNode (location: (104,0)-(104,9))
- │ ├── value:
- │ │ @ CallNode (location: (104,0)-(104,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (104,0)-(104,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ RationalNode (location: (104,7)-(104,9))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (104,7)-(104,8))
- │ │ └── flags: decimal
- │ └── operator_loc: (104,4)-(104,6) = "in"
- ├── @ MatchPredicateNode (location: (105,0)-(105,11))
- │ ├── value:
- │ │ @ CallNode (location: (105,0)-(105,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (105,0)-(105,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SymbolNode (location: (105,7)-(105,11))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (105,7)-(105,8) = ":"
- │ │ ├── value_loc: (105,8)-(105,11) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (105,4)-(105,6) = "in"
- ├── @ MatchPredicateNode (location: (106,0)-(106,14))
- │ ├── value:
- │ │ @ CallNode (location: (106,0)-(106,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (106,0)-(106,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SymbolNode (location: (106,7)-(106,14))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (106,7)-(106,10) = "%s["
- │ │ ├── value_loc: (106,10)-(106,13) = "foo"
- │ │ ├── closing_loc: (106,13)-(106,14) = "]"
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (106,4)-(106,6) = "in"
- ├── @ MatchPredicateNode (location: (107,0)-(107,13))
- │ ├── value:
- │ │ @ CallNode (location: (107,0)-(107,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (107,0)-(107,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SymbolNode (location: (107,7)-(107,13))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (107,7)-(107,9) = ":\""
- │ │ ├── value_loc: (107,9)-(107,12) = "foo"
- │ │ ├── closing_loc: (107,12)-(107,13) = "\""
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (107,4)-(107,6) = "in"
- ├── @ MatchPredicateNode (location: (108,0)-(108,12))
- │ ├── value:
- │ │ @ CallNode (location: (108,0)-(108,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (108,0)-(108,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ RegularExpressionNode (location: (108,7)-(108,12))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (108,7)-(108,8) = "/"
- │ │ ├── content_loc: (108,8)-(108,11) = "foo"
- │ │ ├── closing_loc: (108,11)-(108,12) = "/"
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (108,4)-(108,6) = "in"
- ├── @ MatchPredicateNode (location: (109,0)-(109,12))
- │ ├── value:
- │ │ @ CallNode (location: (109,0)-(109,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (109,0)-(109,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ XStringNode (location: (109,7)-(109,12))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (109,7)-(109,8) = "`"
- │ │ ├── content_loc: (109,8)-(109,11) = "foo"
- │ │ ├── closing_loc: (109,11)-(109,12) = "`"
- │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (110,0)-(110,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ XStringNode (location: (110,7)-(110,14))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (110,7)-(110,10) = "%x["
- │ │ ├── content_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,14))
- │ ├── value:
- │ │ @ CallNode (location: (111,0)-(111,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (111,0)-(111,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayNode (location: (111,7)-(111,14))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ SymbolNode (location: (111,10)-(111,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (111,10)-(111,13) = "foo"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "foo"
- │ │ ├── opening_loc: (111,7)-(111,10) = "%i["
- │ │ └── closing_loc: (111,13)-(111,14) = "]"
- │ └── operator_loc: (111,4)-(111,6) = "in"
- ├── @ MatchPredicateNode (location: (112,0)-(112,14))
- │ ├── value:
- │ │ @ CallNode (location: (112,0)-(112,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (112,0)-(112,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayNode (location: (112,7)-(112,14))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ SymbolNode (location: (112,10)-(112,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (112,10)-(112,13) = "foo"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "foo"
- │ │ ├── opening_loc: (112,7)-(112,10) = "%I["
- │ │ └── closing_loc: (112,13)-(112,14) = "]"
- │ └── operator_loc: (112,4)-(112,6) = "in"
- ├── @ MatchPredicateNode (location: (113,0)-(113,14))
- │ ├── value:
- │ │ @ CallNode (location: (113,0)-(113,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (113,0)-(113,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayNode (location: (113,7)-(113,14))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ StringNode (location: (113,10)-(113,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (113,10)-(113,13) = "foo"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "foo"
- │ │ ├── opening_loc: (113,7)-(113,10) = "%w["
- │ │ └── closing_loc: (113,13)-(113,14) = "]"
- │ └── operator_loc: (113,4)-(113,6) = "in"
- ├── @ MatchPredicateNode (location: (114,0)-(114,14))
- │ ├── value:
- │ │ @ CallNode (location: (114,0)-(114,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (114,0)-(114,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayNode (location: (114,7)-(114,14))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ StringNode (location: (114,10)-(114,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (114,10)-(114,13) = "foo"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "foo"
- │ │ ├── opening_loc: (114,7)-(114,10) = "%W["
- │ │ └── closing_loc: (114,13)-(114,14) = "]"
- │ └── operator_loc: (114,4)-(114,6) = "in"
- ├── @ MatchPredicateNode (location: (115,0)-(115,14))
- │ ├── value:
- │ │ @ CallNode (location: (115,0)-(115,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (115,0)-(115,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ StringNode (location: (115,7)-(115,14))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (115,7)-(115,10) = "%q["
- │ │ ├── content_loc: (115,10)-(115,13) = "foo"
- │ │ ├── closing_loc: (115,13)-(115,14) = "]"
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (115,4)-(115,6) = "in"
- ├── @ MatchPredicateNode (location: (116,0)-(116,14))
- │ ├── value:
- │ │ @ CallNode (location: (116,0)-(116,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (116,0)-(116,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ StringNode (location: (116,7)-(116,14))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (116,7)-(116,10) = "%Q["
- │ │ ├── content_loc: (116,10)-(116,13) = "foo"
- │ │ ├── closing_loc: (116,13)-(116,14) = "]"
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (116,4)-(116,6) = "in"
- ├── @ MatchPredicateNode (location: (117,0)-(117,12))
- │ ├── value:
- │ │ @ CallNode (location: (117,0)-(117,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (117,0)-(117,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ StringNode (location: (117,7)-(117,12))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (117,7)-(117,8) = "\""
- │ │ ├── content_loc: (117,8)-(117,11) = "foo"
- │ │ ├── closing_loc: (117,11)-(117,12) = "\""
- │ │ └── unescaped: "foo"
- │ └── operator_loc: (117,4)-(117,6) = "in"
- ├── @ MatchPredicateNode (location: (118,0)-(118,10))
- │ ├── value:
- │ │ @ CallNode (location: (118,0)-(118,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (118,0)-(118,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ NilNode (location: (118,7)-(118,10))
- │ └── operator_loc: (118,4)-(118,6) = "in"
- ├── @ MatchPredicateNode (location: (119,0)-(119,11))
- │ ├── value:
- │ │ @ CallNode (location: (119,0)-(119,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (119,0)-(119,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SelfNode (location: (119,7)-(119,11))
- │ └── operator_loc: (119,4)-(119,6) = "in"
- ├── @ MatchPredicateNode (location: (120,0)-(120,11))
- │ ├── value:
- │ │ @ CallNode (location: (120,0)-(120,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (120,0)-(120,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ TrueNode (location: (120,7)-(120,11))
- │ └── operator_loc: (120,4)-(120,6) = "in"
- ├── @ MatchPredicateNode (location: (121,0)-(121,12))
- │ ├── value:
- │ │ @ CallNode (location: (121,0)-(121,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (121,0)-(121,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ FalseNode (location: (121,7)-(121,12))
- │ └── operator_loc: (121,4)-(121,6) = "in"
- ├── @ MatchPredicateNode (location: (122,0)-(122,15))
- │ ├── value:
- │ │ @ CallNode (location: (122,0)-(122,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (122,0)-(122,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SourceFileNode (location: (122,7)-(122,15))
- │ │ └── filepath: "patterns.txt"
- │ └── operator_loc: (122,4)-(122,6) = "in"
- ├── @ MatchPredicateNode (location: (123,0)-(123,15))
- │ ├── value:
- │ │ @ CallNode (location: (123,0)-(123,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (123,0)-(123,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SourceLineNode (location: (123,7)-(123,15))
- │ └── operator_loc: (123,4)-(123,6) = "in"
- ├── @ MatchPredicateNode (location: (124,0)-(124,19))
- │ ├── value:
- │ │ @ CallNode (location: (124,0)-(124,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (124,0)-(124,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ SourceEncodingNode (location: (124,7)-(124,19))
- │ └── operator_loc: (124,4)-(124,6) = "in"
- ├── @ MatchPredicateNode (location: (125,0)-(125,17))
- │ ├── value:
- │ │ @ CallNode (location: (125,0)-(125,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (125,0)-(125,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ LambdaNode (location: (125,7)-(125,17))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── operator_loc: (125,7)-(125,9) = "->"
- │ │ ├── opening_loc: (125,10)-(125,11) = "{"
- │ │ ├── closing_loc: (125,16)-(125,17) = "}"
- │ │ ├── parameters: ∅
- │ │ └── body:
- │ │ @ StatementsNode (location: (125,12)-(125,15))
- │ │ └── body: (length: 1)
- │ │ └── @ LocalVariableReadNode (location: (125,12)-(125,15))
- │ │ ├── name: :bar
- │ │ └── depth: 1
- │ └── operator_loc: (125,4)-(125,6) = "in"
- ├── @ CaseMatchNode (location: (127,0)-(127,25))
- │ ├── predicate:
- │ │ @ CallNode (location: (127,5)-(127,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (127,5)-(127,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (127,10)-(127,21))
- │ │ ├── pattern:
- │ │ │ @ LocalVariableTargetNode (location: (127,13)-(127,16))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (127,10)-(127,12) = "in"
- │ │ └── then_loc: (127,17)-(127,21) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (127,0)-(127,4) = "case"
- │ └── end_keyword_loc: (127,22)-(127,25) = "end"
- ├── @ CaseMatchNode (location: (128,0)-(128,23))
- │ ├── predicate:
- │ │ @ CallNode (location: (128,5)-(128,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (128,5)-(128,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (128,10)-(128,19))
- │ │ ├── pattern:
- │ │ │ @ IntegerNode (location: (128,13)-(128,14))
- │ │ │ └── flags: decimal
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (128,10)-(128,12) = "in"
- │ │ └── then_loc: (128,15)-(128,19) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (128,0)-(128,4) = "case"
- │ └── end_keyword_loc: (128,20)-(128,23) = "end"
- ├── @ CaseMatchNode (location: (129,0)-(129,25))
- │ ├── predicate:
- │ │ @ CallNode (location: (129,5)-(129,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (129,5)-(129,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (129,10)-(129,21))
- │ │ ├── pattern:
- │ │ │ @ FloatNode (location: (129,13)-(129,16))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (129,10)-(129,12) = "in"
- │ │ └── then_loc: (129,17)-(129,21) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (129,0)-(129,4) = "case"
- │ └── end_keyword_loc: (129,22)-(129,25) = "end"
- ├── @ CaseMatchNode (location: (130,0)-(130,24))
- │ ├── predicate:
- │ │ @ CallNode (location: (130,5)-(130,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (130,5)-(130,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (130,10)-(130,20))
- │ │ ├── pattern:
- │ │ │ @ ImaginaryNode (location: (130,13)-(130,15))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (130,13)-(130,14))
- │ │ │ └── flags: decimal
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (130,10)-(130,12) = "in"
- │ │ └── then_loc: (130,16)-(130,20) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (130,0)-(130,4) = "case"
- │ └── end_keyword_loc: (130,21)-(130,24) = "end"
- ├── @ CaseMatchNode (location: (131,0)-(131,24))
- │ ├── predicate:
- │ │ @ CallNode (location: (131,5)-(131,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (131,5)-(131,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (131,10)-(131,20))
- │ │ ├── pattern:
- │ │ │ @ RationalNode (location: (131,13)-(131,15))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (131,13)-(131,14))
- │ │ │ └── flags: decimal
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (131,10)-(131,12) = "in"
- │ │ └── then_loc: (131,16)-(131,20) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (131,0)-(131,4) = "case"
- │ └── end_keyword_loc: (131,21)-(131,24) = "end"
- ├── @ CaseMatchNode (location: (132,0)-(132,26))
- │ ├── predicate:
- │ │ @ CallNode (location: (132,5)-(132,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (132,5)-(132,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (132,10)-(132,22))
- │ │ ├── pattern:
- │ │ │ @ SymbolNode (location: (132,13)-(132,17))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (132,13)-(132,14) = ":"
- │ │ │ ├── value_loc: (132,14)-(132,17) = "foo"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (132,10)-(132,12) = "in"
- │ │ └── then_loc: (132,18)-(132,22) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (132,0)-(132,4) = "case"
- │ └── end_keyword_loc: (132,23)-(132,26) = "end"
- ├── @ CaseMatchNode (location: (133,0)-(133,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (133,5)-(133,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (133,5)-(133,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (133,10)-(133,25))
- │ │ ├── pattern:
- │ │ │ @ SymbolNode (location: (133,13)-(133,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (133,13)-(133,16) = "%s["
- │ │ │ ├── value_loc: (133,16)-(133,19) = "foo"
- │ │ │ ├── closing_loc: (133,19)-(133,20) = "]"
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (133,10)-(133,12) = "in"
- │ │ └── then_loc: (133,21)-(133,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (133,0)-(133,4) = "case"
- │ └── end_keyword_loc: (133,26)-(133,29) = "end"
- ├── @ CaseMatchNode (location: (134,0)-(134,28))
- │ ├── predicate:
- │ │ @ CallNode (location: (134,5)-(134,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (134,5)-(134,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (134,10)-(134,24))
- │ │ ├── pattern:
- │ │ │ @ SymbolNode (location: (134,13)-(134,19))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (134,13)-(134,15) = ":\""
- │ │ │ ├── value_loc: (134,15)-(134,18) = "foo"
- │ │ │ ├── closing_loc: (134,18)-(134,19) = "\""
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (134,10)-(134,12) = "in"
- │ │ └── then_loc: (134,20)-(134,24) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (134,0)-(134,4) = "case"
- │ └── end_keyword_loc: (134,25)-(134,28) = "end"
- ├── @ CaseMatchNode (location: (135,0)-(135,27))
- │ ├── predicate:
- │ │ @ CallNode (location: (135,5)-(135,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,23))
- │ │ ├── pattern:
- │ │ │ @ RegularExpressionNode (location: (135,13)-(135,18))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (135,13)-(135,14) = "/"
- │ │ │ ├── content_loc: (135,14)-(135,17) = "foo"
- │ │ │ ├── closing_loc: (135,17)-(135,18) = "/"
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (135,10)-(135,12) = "in"
- │ │ └── then_loc: (135,19)-(135,23) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (135,0)-(135,4) = "case"
- │ └── end_keyword_loc: (135,24)-(135,27) = "end"
- ├── @ CaseMatchNode (location: (136,0)-(136,27))
- │ ├── predicate:
- │ │ @ CallNode (location: (136,5)-(136,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,23))
- │ │ ├── pattern:
- │ │ │ @ XStringNode (location: (136,13)-(136,18))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (136,13)-(136,14) = "`"
- │ │ │ ├── content_loc: (136,14)-(136,17) = "foo"
- │ │ │ ├── closing_loc: (136,17)-(136,18) = "`"
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (136,10)-(136,12) = "in"
- │ │ └── then_loc: (136,19)-(136,23) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (136,0)-(136,4) = "case"
- │ └── end_keyword_loc: (136,24)-(136,27) = "end"
- ├── @ CaseMatchNode (location: (137,0)-(137,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (137,5)-(137,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,25))
- │ │ ├── pattern:
- │ │ │ @ XStringNode (location: (137,13)-(137,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (137,13)-(137,16) = "%x["
- │ │ │ ├── content_loc: (137,16)-(137,19) = "foo"
- │ │ │ ├── closing_loc: (137,19)-(137,20) = "]"
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (137,10)-(137,12) = "in"
- │ │ └── then_loc: (137,21)-(137,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (137,0)-(137,4) = "case"
- │ └── end_keyword_loc: (137,26)-(137,29) = "end"
- ├── @ CaseMatchNode (location: (138,0)-(138,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (138,5)-(138,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,25))
- │ │ ├── pattern:
- │ │ │ @ ArrayNode (location: (138,13)-(138,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── elements: (length: 1)
- │ │ │ │ └── @ SymbolNode (location: (138,16)-(138,19))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (138,16)-(138,19) = "foo"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── opening_loc: (138,13)-(138,16) = "%i["
- │ │ │ └── closing_loc: (138,19)-(138,20) = "]"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (138,10)-(138,12) = "in"
- │ │ └── then_loc: (138,21)-(138,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (138,0)-(138,4) = "case"
- │ └── end_keyword_loc: (138,26)-(138,29) = "end"
- ├── @ CaseMatchNode (location: (139,0)-(139,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (139,5)-(139,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,25))
- │ │ ├── pattern:
- │ │ │ @ ArrayNode (location: (139,13)-(139,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── elements: (length: 1)
- │ │ │ │ └── @ SymbolNode (location: (139,16)-(139,19))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (139,16)-(139,19) = "foo"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── opening_loc: (139,13)-(139,16) = "%I["
- │ │ │ └── closing_loc: (139,19)-(139,20) = "]"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (139,10)-(139,12) = "in"
- │ │ └── then_loc: (139,21)-(139,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (139,0)-(139,4) = "case"
- │ └── end_keyword_loc: (139,26)-(139,29) = "end"
- ├── @ CaseMatchNode (location: (140,0)-(140,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (140,5)-(140,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,25))
- │ │ ├── pattern:
- │ │ │ @ ArrayNode (location: (140,13)-(140,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── elements: (length: 1)
- │ │ │ │ └── @ StringNode (location: (140,16)-(140,19))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (140,16)-(140,19) = "foo"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── opening_loc: (140,13)-(140,16) = "%w["
- │ │ │ └── closing_loc: (140,19)-(140,20) = "]"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (140,10)-(140,12) = "in"
- │ │ └── then_loc: (140,21)-(140,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (140,0)-(140,4) = "case"
- │ └── end_keyword_loc: (140,26)-(140,29) = "end"
- ├── @ CaseMatchNode (location: (141,0)-(141,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (141,5)-(141,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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:
- │ │ │ @ ArrayNode (location: (141,13)-(141,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── elements: (length: 1)
- │ │ │ │ └── @ StringNode (location: (141,16)-(141,19))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (141,16)-(141,19) = "foo"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── opening_loc: (141,13)-(141,16) = "%W["
- │ │ │ └── closing_loc: (141,19)-(141,20) = "]"
- │ │ ├── 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,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (142,5)-(142,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,25))
- │ │ ├── pattern:
- │ │ │ @ StringNode (location: (142,13)-(142,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (142,13)-(142,16) = "%q["
- │ │ │ ├── content_loc: (142,16)-(142,19) = "foo"
- │ │ │ ├── closing_loc: (142,19)-(142,20) = "]"
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (142,10)-(142,12) = "in"
- │ │ └── then_loc: (142,21)-(142,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (142,0)-(142,4) = "case"
- │ └── end_keyword_loc: (142,26)-(142,29) = "end"
- ├── @ CaseMatchNode (location: (143,0)-(143,29))
- │ ├── predicate:
- │ │ @ CallNode (location: (143,5)-(143,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,25))
- │ │ ├── pattern:
- │ │ │ @ StringNode (location: (143,13)-(143,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (143,13)-(143,16) = "%Q["
- │ │ │ ├── content_loc: (143,16)-(143,19) = "foo"
- │ │ │ ├── closing_loc: (143,19)-(143,20) = "]"
- │ │ │ └── unescaped: "foo"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (143,10)-(143,12) = "in"
- │ │ └── then_loc: (143,21)-(143,25) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (143,0)-(143,4) = "case"
- │ └── end_keyword_loc: (143,26)-(143,29) = "end"
- ├── @ CaseMatchNode (location: (144,0)-(144,27))
- │ ├── predicate:
- │ │ @ CallNode (location: (144,5)-(144,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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:
- │ │ │ @ StringNode (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,25))
- │ ├── predicate:
- │ │ @ CallNode (location: (145,5)-(145,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,21))
- │ │ ├── pattern:
- │ │ │ @ NilNode (location: (145,13)-(145,16))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (145,10)-(145,12) = "in"
- │ │ └── then_loc: (145,17)-(145,21) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (145,0)-(145,4) = "case"
- │ └── end_keyword_loc: (145,22)-(145,25) = "end"
- ├── @ CaseMatchNode (location: (146,0)-(146,26))
- │ ├── predicate:
- │ │ @ CallNode (location: (146,5)-(146,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,22))
- │ │ ├── pattern:
- │ │ │ @ SelfNode (location: (146,13)-(146,17))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (146,10)-(146,12) = "in"
- │ │ └── then_loc: (146,18)-(146,22) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (146,0)-(146,4) = "case"
- │ └── end_keyword_loc: (146,23)-(146,26) = "end"
- ├── @ CaseMatchNode (location: (147,0)-(147,26))
- │ ├── predicate:
- │ │ @ CallNode (location: (147,5)-(147,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,22))
- │ │ ├── pattern:
- │ │ │ @ TrueNode (location: (147,13)-(147,17))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (147,10)-(147,12) = "in"
- │ │ └── then_loc: (147,18)-(147,22) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (147,0)-(147,4) = "case"
- │ └── end_keyword_loc: (147,23)-(147,26) = "end"
- ├── @ CaseMatchNode (location: (148,0)-(148,27))
- │ ├── predicate:
- │ │ @ CallNode (location: (148,5)-(148,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,23))
- │ │ ├── pattern:
- │ │ │ @ FalseNode (location: (148,13)-(148,18))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (148,10)-(148,12) = "in"
- │ │ └── then_loc: (148,19)-(148,23) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (148,0)-(148,4) = "case"
- │ └── end_keyword_loc: (148,24)-(148,27) = "end"
- ├── @ CaseMatchNode (location: (149,0)-(149,30))
- │ ├── predicate:
- │ │ @ CallNode (location: (149,5)-(149,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,26))
- │ │ ├── pattern:
- │ │ │ @ SourceFileNode (location: (149,13)-(149,21))
- │ │ │ └── filepath: "patterns.txt"
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (149,10)-(149,12) = "in"
- │ │ └── then_loc: (149,22)-(149,26) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (149,0)-(149,4) = "case"
- │ └── end_keyword_loc: (149,27)-(149,30) = "end"
- ├── @ CaseMatchNode (location: (150,0)-(150,30))
- │ ├── predicate:
- │ │ @ CallNode (location: (150,5)-(150,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,26))
- │ │ ├── pattern:
- │ │ │ @ SourceLineNode (location: (150,13)-(150,21))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (150,10)-(150,12) = "in"
- │ │ └── then_loc: (150,22)-(150,26) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (150,0)-(150,4) = "case"
- │ └── end_keyword_loc: (150,27)-(150,30) = "end"
- ├── @ CaseMatchNode (location: (151,0)-(151,34))
- │ ├── predicate:
- │ │ @ CallNode (location: (151,5)-(151,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,30))
- │ │ ├── pattern:
- │ │ │ @ SourceEncodingNode (location: (151,13)-(151,25))
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (151,10)-(151,12) = "in"
- │ │ └── then_loc: (151,26)-(151,30) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (151,0)-(151,4) = "case"
- │ └── end_keyword_loc: (151,31)-(151,34) = "end"
- ├── @ CaseMatchNode (location: (152,0)-(152,32))
- │ ├── predicate:
- │ │ @ CallNode (location: (152,5)-(152,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,28))
- │ │ ├── pattern:
- │ │ │ @ LambdaNode (location: (152,13)-(152,23))
- │ │ │ ├── locals: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── operator_loc: (152,13)-(152,15) = "->"
- │ │ │ ├── opening_loc: (152,16)-(152,17) = "{"
- │ │ │ ├── closing_loc: (152,22)-(152,23) = "}"
- │ │ │ ├── parameters: ∅
- │ │ │ └── body:
- │ │ │ @ StatementsNode (location: (152,18)-(152,21))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ LocalVariableReadNode (location: (152,18)-(152,21))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 1
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (152,10)-(152,12) = "in"
- │ │ └── then_loc: (152,24)-(152,28) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (152,0)-(152,4) = "case"
- │ └── end_keyword_loc: (152,29)-(152,32) = "end"
- ├── @ CaseMatchNode (location: (154,0)-(154,32))
- │ ├── predicate:
- │ │ @ CallNode (location: (154,5)-(154,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,28))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (154,13)-(154,23))
- │ │ │ ├── if_keyword_loc: (154,17)-(154,19) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (154,20)-(154,23))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (154,13)-(154,16))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ LocalVariableTargetNode (location: (154,13)-(154,16))
- │ │ │ │ ├── name: :bar
- │ │ │ │ └── depth: 0
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (154,10)-(154,12) = "in"
- │ │ └── then_loc: (154,24)-(154,28) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (154,0)-(154,4) = "case"
- │ └── end_keyword_loc: (154,29)-(154,32) = "end"
- ├── @ CaseMatchNode (location: (155,0)-(155,30))
- │ ├── predicate:
- │ │ @ CallNode (location: (155,5)-(155,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,26))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (155,13)-(155,21))
- │ │ │ ├── if_keyword_loc: (155,15)-(155,17) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (155,18)-(155,21))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (155,13)-(155,14))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (155,13)-(155,14))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (155,10)-(155,12) = "in"
- │ │ └── then_loc: (155,22)-(155,26) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (155,0)-(155,4) = "case"
- │ └── end_keyword_loc: (155,27)-(155,30) = "end"
- ├── @ CaseMatchNode (location: (156,0)-(156,32))
- │ ├── predicate:
- │ │ @ CallNode (location: (156,5)-(156,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,28))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (156,13)-(156,23))
- │ │ │ ├── if_keyword_loc: (156,17)-(156,19) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (156,20)-(156,23))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (156,13)-(156,16))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ FloatNode (location: (156,13)-(156,16))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (156,10)-(156,12) = "in"
- │ │ └── then_loc: (156,24)-(156,28) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (156,0)-(156,4) = "case"
- │ └── end_keyword_loc: (156,29)-(156,32) = "end"
- ├── @ CaseMatchNode (location: (157,0)-(157,31))
- │ ├── predicate:
- │ │ @ CallNode (location: (157,5)-(157,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,27))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (157,13)-(157,22))
- │ │ │ ├── if_keyword_loc: (157,16)-(157,18) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (157,19)-(157,22))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (157,13)-(157,15))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ ImaginaryNode (location: (157,13)-(157,15))
- │ │ │ │ └── numeric:
- │ │ │ │ @ IntegerNode (location: (157,13)-(157,14))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (157,10)-(157,12) = "in"
- │ │ └── then_loc: (157,23)-(157,27) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (157,0)-(157,4) = "case"
- │ └── end_keyword_loc: (157,28)-(157,31) = "end"
- ├── @ CaseMatchNode (location: (158,0)-(158,31))
- │ ├── predicate:
- │ │ @ CallNode (location: (158,5)-(158,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,27))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (158,13)-(158,22))
- │ │ │ ├── if_keyword_loc: (158,16)-(158,18) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (158,19)-(158,22))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (158,13)-(158,15))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ RationalNode (location: (158,13)-(158,15))
- │ │ │ │ └── numeric:
- │ │ │ │ @ IntegerNode (location: (158,13)-(158,14))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (158,10)-(158,12) = "in"
- │ │ └── then_loc: (158,23)-(158,27) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (158,0)-(158,4) = "case"
- │ └── end_keyword_loc: (158,28)-(158,31) = "end"
- ├── @ CaseMatchNode (location: (159,0)-(159,33))
- │ ├── predicate:
- │ │ @ CallNode (location: (159,5)-(159,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,29))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (159,13)-(159,24))
- │ │ │ ├── if_keyword_loc: (159,18)-(159,20) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (159,21)-(159,24))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (159,13)-(159,17))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SymbolNode (location: (159,13)-(159,17))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (159,13)-(159,14) = ":"
- │ │ │ │ ├── value_loc: (159,14)-(159,17) = "foo"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (159,10)-(159,12) = "in"
- │ │ └── then_loc: (159,25)-(159,29) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (159,0)-(159,4) = "case"
- │ └── end_keyword_loc: (159,30)-(159,33) = "end"
- ├── @ CaseMatchNode (location: (160,0)-(160,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (160,5)-(160,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (160,13)-(160,27))
- │ │ │ ├── if_keyword_loc: (160,21)-(160,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (160,24)-(160,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (160,13)-(160,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SymbolNode (location: (160,13)-(160,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (160,13)-(160,16) = "%s["
- │ │ │ │ ├── value_loc: (160,16)-(160,19) = "foo"
- │ │ │ │ ├── closing_loc: (160,19)-(160,20) = "]"
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (160,10)-(160,12) = "in"
- │ │ └── then_loc: (160,28)-(160,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (160,0)-(160,4) = "case"
- │ └── end_keyword_loc: (160,33)-(160,36) = "end"
- ├── @ CaseMatchNode (location: (161,0)-(161,35))
- │ ├── predicate:
- │ │ @ CallNode (location: (161,5)-(161,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (161,5)-(161,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── conditions: (length: 1)
- │ │ └── @ InNode (location: (161,10)-(161,31))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (161,13)-(161,26))
- │ │ │ ├── if_keyword_loc: (161,20)-(161,22) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (161,23)-(161,26))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (161,13)-(161,19))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SymbolNode (location: (161,13)-(161,19))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (161,13)-(161,15) = ":\""
- │ │ │ │ ├── value_loc: (161,15)-(161,18) = "foo"
- │ │ │ │ ├── closing_loc: (161,18)-(161,19) = "\""
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (161,10)-(161,12) = "in"
- │ │ └── then_loc: (161,27)-(161,31) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (161,0)-(161,4) = "case"
- │ └── end_keyword_loc: (161,32)-(161,35) = "end"
- ├── @ CaseMatchNode (location: (162,0)-(162,34))
- │ ├── predicate:
- │ │ @ CallNode (location: (162,5)-(162,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,30))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (162,13)-(162,25))
- │ │ │ ├── if_keyword_loc: (162,19)-(162,21) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (162,22)-(162,25))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (162,13)-(162,18))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ RegularExpressionNode (location: (162,13)-(162,18))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (162,13)-(162,14) = "/"
- │ │ │ │ ├── content_loc: (162,14)-(162,17) = "foo"
- │ │ │ │ ├── closing_loc: (162,17)-(162,18) = "/"
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (162,10)-(162,12) = "in"
- │ │ └── then_loc: (162,26)-(162,30) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (162,0)-(162,4) = "case"
- │ └── end_keyword_loc: (162,31)-(162,34) = "end"
- ├── @ CaseMatchNode (location: (163,0)-(163,34))
- │ ├── predicate:
- │ │ @ CallNode (location: (163,5)-(163,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,30))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (163,13)-(163,25))
- │ │ │ ├── if_keyword_loc: (163,19)-(163,21) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (163,22)-(163,25))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (163,13)-(163,18))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ XStringNode (location: (163,13)-(163,18))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (163,13)-(163,14) = "`"
- │ │ │ │ ├── content_loc: (163,14)-(163,17) = "foo"
- │ │ │ │ ├── closing_loc: (163,17)-(163,18) = "`"
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (163,10)-(163,12) = "in"
- │ │ └── then_loc: (163,26)-(163,30) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (163,0)-(163,4) = "case"
- │ └── end_keyword_loc: (163,31)-(163,34) = "end"
- ├── @ CaseMatchNode (location: (164,0)-(164,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (164,5)-(164,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (164,13)-(164,27))
- │ │ │ ├── if_keyword_loc: (164,21)-(164,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (164,24)-(164,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (164,13)-(164,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ XStringNode (location: (164,13)-(164,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (164,13)-(164,16) = "%x["
- │ │ │ │ ├── content_loc: (164,16)-(164,19) = "foo"
- │ │ │ │ ├── closing_loc: (164,19)-(164,20) = "]"
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (164,10)-(164,12) = "in"
- │ │ └── then_loc: (164,28)-(164,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (164,0)-(164,4) = "case"
- │ └── end_keyword_loc: (164,33)-(164,36) = "end"
- ├── @ CaseMatchNode (location: (165,0)-(165,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (165,5)-(165,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (165,13)-(165,27))
- │ │ │ ├── if_keyword_loc: (165,21)-(165,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (165,24)-(165,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (165,13)-(165,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ ArrayNode (location: (165,13)-(165,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── elements: (length: 1)
- │ │ │ │ │ └── @ SymbolNode (location: (165,16)-(165,19))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── value_loc: (165,16)-(165,19) = "foo"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "foo"
- │ │ │ │ ├── opening_loc: (165,13)-(165,16) = "%i["
- │ │ │ │ └── closing_loc: (165,19)-(165,20) = "]"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (165,10)-(165,12) = "in"
- │ │ └── then_loc: (165,28)-(165,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (165,0)-(165,4) = "case"
- │ └── end_keyword_loc: (165,33)-(165,36) = "end"
- ├── @ CaseMatchNode (location: (166,0)-(166,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (166,5)-(166,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (166,13)-(166,27))
- │ │ │ ├── if_keyword_loc: (166,21)-(166,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (166,24)-(166,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (166,13)-(166,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ ArrayNode (location: (166,13)-(166,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── elements: (length: 1)
- │ │ │ │ │ └── @ SymbolNode (location: (166,16)-(166,19))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── value_loc: (166,16)-(166,19) = "foo"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "foo"
- │ │ │ │ ├── opening_loc: (166,13)-(166,16) = "%I["
- │ │ │ │ └── closing_loc: (166,19)-(166,20) = "]"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (166,10)-(166,12) = "in"
- │ │ └── then_loc: (166,28)-(166,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (166,0)-(166,4) = "case"
- │ └── end_keyword_loc: (166,33)-(166,36) = "end"
- ├── @ CaseMatchNode (location: (167,0)-(167,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (167,5)-(167,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (167,13)-(167,27))
- │ │ │ ├── if_keyword_loc: (167,21)-(167,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (167,24)-(167,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (167,13)-(167,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ ArrayNode (location: (167,13)-(167,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── elements: (length: 1)
- │ │ │ │ │ └── @ StringNode (location: (167,16)-(167,19))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── content_loc: (167,16)-(167,19) = "foo"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "foo"
- │ │ │ │ ├── opening_loc: (167,13)-(167,16) = "%w["
- │ │ │ │ └── closing_loc: (167,19)-(167,20) = "]"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (167,10)-(167,12) = "in"
- │ │ └── then_loc: (167,28)-(167,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (167,0)-(167,4) = "case"
- │ └── end_keyword_loc: (167,33)-(167,36) = "end"
- ├── @ CaseMatchNode (location: (168,0)-(168,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (168,5)-(168,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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)
- │ │ │ │ └── @ ArrayNode (location: (168,13)-(168,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── elements: (length: 1)
- │ │ │ │ │ └── @ StringNode (location: (168,16)-(168,19))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── content_loc: (168,16)-(168,19) = "foo"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "foo"
- │ │ │ │ ├── opening_loc: (168,13)-(168,16) = "%W["
- │ │ │ │ └── closing_loc: (168,19)-(168,20) = "]"
- │ │ │ ├── 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,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (169,5)-(169,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (169,13)-(169,27))
- │ │ │ ├── if_keyword_loc: (169,21)-(169,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (169,24)-(169,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (169,13)-(169,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ StringNode (location: (169,13)-(169,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (169,13)-(169,16) = "%q["
- │ │ │ │ ├── content_loc: (169,16)-(169,19) = "foo"
- │ │ │ │ ├── closing_loc: (169,19)-(169,20) = "]"
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (169,10)-(169,12) = "in"
- │ │ └── then_loc: (169,28)-(169,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (169,0)-(169,4) = "case"
- │ └── end_keyword_loc: (169,33)-(169,36) = "end"
- ├── @ CaseMatchNode (location: (170,0)-(170,36))
- │ ├── predicate:
- │ │ @ CallNode (location: (170,5)-(170,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,32))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (170,13)-(170,27))
- │ │ │ ├── if_keyword_loc: (170,21)-(170,23) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (170,24)-(170,27))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (170,13)-(170,20))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ StringNode (location: (170,13)-(170,20))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (170,13)-(170,16) = "%Q["
- │ │ │ │ ├── content_loc: (170,16)-(170,19) = "foo"
- │ │ │ │ ├── closing_loc: (170,19)-(170,20) = "]"
- │ │ │ │ └── unescaped: "foo"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (170,10)-(170,12) = "in"
- │ │ └── then_loc: (170,28)-(170,32) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (170,0)-(170,4) = "case"
- │ └── end_keyword_loc: (170,33)-(170,36) = "end"
- ├── @ CaseMatchNode (location: (171,0)-(171,34))
- │ ├── predicate:
- │ │ @ CallNode (location: (171,5)-(171,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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)
- │ │ │ │ └── @ StringNode (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,32))
- │ ├── predicate:
- │ │ @ CallNode (location: (172,5)-(172,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,28))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (172,13)-(172,23))
- │ │ │ ├── if_keyword_loc: (172,17)-(172,19) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (172,20)-(172,23))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (172,13)-(172,16))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ NilNode (location: (172,13)-(172,16))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (172,10)-(172,12) = "in"
- │ │ └── then_loc: (172,24)-(172,28) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (172,0)-(172,4) = "case"
- │ └── end_keyword_loc: (172,29)-(172,32) = "end"
- ├── @ CaseMatchNode (location: (173,0)-(173,33))
- │ ├── predicate:
- │ │ @ CallNode (location: (173,5)-(173,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,29))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (173,13)-(173,24))
- │ │ │ ├── if_keyword_loc: (173,18)-(173,20) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (173,21)-(173,24))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (173,13)-(173,17))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SelfNode (location: (173,13)-(173,17))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (173,10)-(173,12) = "in"
- │ │ └── then_loc: (173,25)-(173,29) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (173,0)-(173,4) = "case"
- │ └── end_keyword_loc: (173,30)-(173,33) = "end"
- ├── @ CaseMatchNode (location: (174,0)-(174,33))
- │ ├── predicate:
- │ │ @ CallNode (location: (174,5)-(174,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,29))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (174,13)-(174,24))
- │ │ │ ├── if_keyword_loc: (174,18)-(174,20) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (174,21)-(174,24))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (174,13)-(174,17))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ TrueNode (location: (174,13)-(174,17))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (174,10)-(174,12) = "in"
- │ │ └── then_loc: (174,25)-(174,29) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (174,0)-(174,4) = "case"
- │ └── end_keyword_loc: (174,30)-(174,33) = "end"
- ├── @ CaseMatchNode (location: (175,0)-(175,34))
- │ ├── predicate:
- │ │ @ CallNode (location: (175,5)-(175,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,30))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (175,13)-(175,25))
- │ │ │ ├── if_keyword_loc: (175,19)-(175,21) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (175,22)-(175,25))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (175,13)-(175,18))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ FalseNode (location: (175,13)-(175,18))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (175,10)-(175,12) = "in"
- │ │ └── then_loc: (175,26)-(175,30) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (175,0)-(175,4) = "case"
- │ └── end_keyword_loc: (175,31)-(175,34) = "end"
- ├── @ CaseMatchNode (location: (176,0)-(176,37))
- │ ├── predicate:
- │ │ @ CallNode (location: (176,5)-(176,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,33))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (176,13)-(176,28))
- │ │ │ ├── if_keyword_loc: (176,22)-(176,24) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (176,25)-(176,28))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (176,13)-(176,21))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SourceFileNode (location: (176,13)-(176,21))
- │ │ │ │ └── filepath: "patterns.txt"
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (176,10)-(176,12) = "in"
- │ │ └── then_loc: (176,29)-(176,33) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (176,0)-(176,4) = "case"
- │ └── end_keyword_loc: (176,34)-(176,37) = "end"
- ├── @ CaseMatchNode (location: (177,0)-(177,37))
- │ ├── predicate:
- │ │ @ CallNode (location: (177,5)-(177,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,33))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (177,13)-(177,28))
- │ │ │ ├── if_keyword_loc: (177,22)-(177,24) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (177,25)-(177,28))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (177,13)-(177,21))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SourceLineNode (location: (177,13)-(177,21))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (177,10)-(177,12) = "in"
- │ │ └── then_loc: (177,29)-(177,33) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (177,0)-(177,4) = "case"
- │ └── end_keyword_loc: (177,34)-(177,37) = "end"
- ├── @ CaseMatchNode (location: (178,0)-(178,41))
- │ ├── predicate:
- │ │ @ CallNode (location: (178,5)-(178,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,37))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (178,13)-(178,32))
- │ │ │ ├── if_keyword_loc: (178,26)-(178,28) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (178,29)-(178,32))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (178,13)-(178,25))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ SourceEncodingNode (location: (178,13)-(178,25))
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (178,10)-(178,12) = "in"
- │ │ └── then_loc: (178,33)-(178,37) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (178,0)-(178,4) = "case"
- │ └── end_keyword_loc: (178,38)-(178,41) = "end"
- ├── @ CaseMatchNode (location: (179,0)-(179,39))
- │ ├── predicate:
- │ │ @ CallNode (location: (179,5)-(179,8))
- │ │ ├── flags: variable_call
- │ │ ├── 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,35))
- │ │ ├── pattern:
- │ │ │ @ IfNode (location: (179,13)-(179,30))
- │ │ │ ├── if_keyword_loc: (179,24)-(179,26) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ LocalVariableReadNode (location: (179,27)-(179,30))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 0
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (179,13)-(179,23))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ LambdaNode (location: (179,13)-(179,23))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── operator_loc: (179,13)-(179,15) = "->"
- │ │ │ │ ├── opening_loc: (179,16)-(179,17) = "{"
- │ │ │ │ ├── closing_loc: (179,22)-(179,23) = "}"
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ └── body:
- │ │ │ │ @ StatementsNode (location: (179,18)-(179,21))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ LocalVariableReadNode (location: (179,18)-(179,21))
- │ │ │ │ ├── name: :bar
- │ │ │ │ └── depth: 1
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: ∅
- │ │ ├── statements: ∅
- │ │ ├── in_loc: (179,10)-(179,12) = "in"
- │ │ └── then_loc: (179,31)-(179,35) = "then"
- │ ├── consequent: ∅
- │ ├── case_keyword_loc: (179,0)-(179,4) = "case"
- │ └── end_keyword_loc: (179,36)-(179,39) = "end"
- ├── @ IfNode (location: (181,0)-(182,3))
- │ ├── if_keyword_loc: (181,0)-(181,2) = "if"
- │ ├── predicate:
- │ │ @ MatchPredicateNode (location: (181,3)-(181,10))
- │ │ ├── value:
- │ │ │ @ CallNode (location: (181,3)-(181,4))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :a
- │ │ │ ├── message_loc: (181,3)-(181,4) = "a"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── pattern:
- │ │ │ @ ArrayPatternNode (location: (181,8)-(181,10))
- │ │ │ ├── constant: ∅
- │ │ │ ├── requireds: (length: 0)
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── opening_loc: (181,8)-(181,9) = "["
- │ │ │ └── closing_loc: (181,9)-(181,10) = "]"
- │ │ └── operator_loc: (181,5)-(181,7) = "in"
- │ ├── then_keyword_loc: ∅
- │ ├── statements: ∅
- │ ├── consequent: ∅
- │ └── end_keyword_loc: (182,0)-(182,3) = "end"
- ├── @ MatchRequiredNode (location: (184,0)-(186,1))
- │ ├── value:
- │ │ @ CallNode (location: (184,0)-(184,1))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :a
- │ │ ├── message_loc: (184,0)-(184,1) = "a"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ ArrayPatternNode (location: (184,5)-(186,1))
- │ │ ├── constant: ∅
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ LocalVariableTargetNode (location: (185,2)-(185,3))
- │ │ │ ├── name: :b
- │ │ │ └── depth: 0
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── opening_loc: (184,5)-(184,6) = "["
- │ │ └── closing_loc: (186,0)-(186,1) = "]"
- │ └── operator_loc: (184,2)-(184,4) = "=>"
- ├── @ MatchPredicateNode (location: (188,0)-(192,1))
- │ ├── value:
- │ │ @ CallNode (location: (188,0)-(188,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (188,0)-(188,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ HashPatternNode (location: (188,7)-(192,1))
- │ │ ├── constant:
- │ │ │ @ ConstantReadNode (location: (188,7)-(188,8))
- │ │ │ └── name: :A
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (189,2)-(191,3))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (189,2)-(189,6))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (189,2)-(189,5) = "bar"
- │ │ │ │ ├── closing_loc: (189,5)-(189,6) = ":"
- │ │ │ │ └── unescaped: "bar"
- │ │ │ ├── value:
- │ │ │ │ @ HashPatternNode (location: (189,7)-(191,3))
- │ │ │ │ ├── constant:
- │ │ │ │ │ @ ConstantReadNode (location: (189,7)-(189,8))
- │ │ │ │ │ └── name: :B
- │ │ │ │ ├── elements: (length: 1)
- │ │ │ │ │ └── @ AssocNode (location: (190,4)-(190,12))
- │ │ │ │ │ ├── key:
- │ │ │ │ │ │ @ SymbolNode (location: (190,4)-(190,10))
- │ │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ │ ├── value_loc: (190,4)-(190,9) = "value"
- │ │ │ │ │ │ ├── closing_loc: (190,9)-(190,10) = ":"
- │ │ │ │ │ │ └── unescaped: "value"
- │ │ │ │ │ ├── value:
- │ │ │ │ │ │ @ LocalVariableTargetNode (location: (190,11)-(190,12))
- │ │ │ │ │ │ ├── name: :a
- │ │ │ │ │ │ └── depth: 0
- │ │ │ │ │ └── operator_loc: ∅
- │ │ │ │ ├── rest: ∅
- │ │ │ │ ├── opening_loc: (189,8)-(189,9) = "["
- │ │ │ │ └── closing_loc: (191,2)-(191,3) = "]"
- │ │ │ └── operator_loc: ∅
- │ │ ├── rest: ∅
- │ │ ├── opening_loc: (188,8)-(188,9) = "["
- │ │ └── closing_loc: (192,0)-(192,1) = "]"
- │ └── operator_loc: (188,4)-(188,6) = "in"
- ├── @ MatchPredicateNode (location: (194,0)-(194,17))
- │ ├── value:
- │ │ @ CallNode (location: (194,0)-(194,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (194,0)-(194,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ CapturePatternNode (location: (194,7)-(194,17))
- │ │ ├── value:
- │ │ │ @ LocalVariableTargetNode (location: (194,7)-(194,10))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── target:
- │ │ │ @ LocalVariableTargetNode (location: (194,14)-(194,17))
- │ │ │ ├── name: :baz
- │ │ │ └── depth: 0
- │ │ └── operator_loc: (194,11)-(194,13) = "=>"
- │ └── operator_loc: (194,4)-(194,6) = "in"
- ├── @ MatchRequiredNode (location: (195,0)-(195,17))
- │ ├── value:
- │ │ @ CallNode (location: (195,0)-(195,3))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (195,0)-(195,3) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── pattern:
- │ │ @ CapturePatternNode (location: (195,7)-(195,17))
- │ │ ├── value:
- │ │ │ @ LocalVariableTargetNode (location: (195,7)-(195,10))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ ├── target:
- │ │ │ @ LocalVariableTargetNode (location: (195,14)-(195,17))
- │ │ │ ├── name: :baz
- │ │ │ └── depth: 0
- │ │ └── operator_loc: (195,11)-(195,13) = "=>"
- │ └── operator_loc: (195,4)-(195,6) = "=>"
- ├── @ MultiWriteNode (location: (197,0)-(197,20))
- │ ├── lefts: (length: 3)
- │ │ ├── @ LocalVariableTargetNode (location: (197,0)-(197,3))
- │ │ │ ├── name: :foo
- │ │ │ └── depth: 0
- │ │ ├── @ LocalVariableTargetNode (location: (197,5)-(197,8))
- │ │ │ ├── name: :bar
- │ │ │ └── depth: 0
- │ │ └── @ LocalVariableTargetNode (location: (197,10)-(197,13))
- │ │ ├── name: :baz
- │ │ └── depth: 0
- │ ├── rest: ∅
- │ ├── rights: (length: 0)
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── operator_loc: (197,14)-(197,15) = "="
- │ └── value:
- │ @ ArrayNode (location: (197,16)-(197,20))
- │ ├── flags: ∅
- │ ├── elements: (length: 2)
- │ │ ├── @ IntegerNode (location: (197,16)-(197,17))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (197,19)-(197,20))
- │ │ └── flags: decimal
- │ ├── opening_loc: ∅
- │ └── closing_loc: ∅
- ├── @ CallNode (location: (198,0)-(200,3))
- │ ├── flags: ∅
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :foo
- │ ├── message_loc: (198,0)-(198,3) = "foo"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (198,4)-(200,3))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (199,2)-(199,29))
- │ │ └── body: (length: 1)
- │ │ └── @ MatchRequiredNode (location: (199,2)-(199,29))
- │ │ ├── value:
- │ │ │ @ ArrayNode (location: (199,2)-(199,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── elements: (length: 2)
- │ │ │ │ ├── @ IntegerNode (location: (199,3)-(199,4))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── @ IntegerNode (location: (199,6)-(199,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── opening_loc: (199,2)-(199,3) = "["
- │ │ │ └── closing_loc: (199,7)-(199,8) = "]"
- │ │ ├── pattern:
- │ │ │ @ CapturePatternNode (location: (199,12)-(199,29))
- │ │ │ ├── value:
- │ │ │ │ @ ArrayPatternNode (location: (199,12)-(199,22))
- │ │ │ │ ├── constant: ∅
- │ │ │ │ ├── requireds: (length: 2)
- │ │ │ │ │ ├── @ LocalVariableTargetNode (location: (199,13)-(199,16))
- │ │ │ │ │ │ ├── name: :foo
- │ │ │ │ │ │ └── depth: 1
- │ │ │ │ │ └── @ LocalVariableTargetNode (location: (199,18)-(199,21))
- │ │ │ │ │ ├── name: :bar
- │ │ │ │ │ └── depth: 1
- │ │ │ │ ├── rest: ∅
- │ │ │ │ ├── posts: (length: 0)
- │ │ │ │ ├── opening_loc: (199,12)-(199,13) = "["
- │ │ │ │ └── closing_loc: (199,21)-(199,22) = "]"
- │ │ │ ├── target:
- │ │ │ │ @ LocalVariableTargetNode (location: (199,26)-(199,29))
- │ │ │ │ ├── name: :baz
- │ │ │ │ └── depth: 1
- │ │ │ └── operator_loc: (199,23)-(199,25) = "=>"
- │ │ └── operator_loc: (199,9)-(199,11) = "=>"
- │ ├── opening_loc: (198,4)-(198,6) = "do"
- │ └── closing_loc: (200,0)-(200,3) = "end"
- └── @ MatchRequiredNode (location: (202,0)-(202,19))
- ├── value:
- │ @ LocalVariableReadNode (location: (202,0)-(202,3))
- │ ├── name: :foo
- │ └── depth: 0
- ├── pattern:
- │ @ ArrayPatternNode (location: (202,7)-(202,19))
- │ ├── constant:
- │ │ @ ConstantReadNode (location: (202,7)-(202,13))
- │ │ └── name: :Object
- │ ├── requireds: (length: 1)
- │ │ └── @ HashPatternNode (location: (202,14)-(202,18))
- │ │ ├── constant: ∅
- │ │ ├── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (202,15)-(202,17))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (202,15)-(202,17))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (202,15)-(202,16) = "x"
- │ │ │ │ ├── closing_loc: (202,16)-(202,17) = ":"
- │ │ │ │ └── unescaped: "x"
- │ │ │ ├── value: ∅
- │ │ │ └── operator_loc: ∅
- │ │ ├── rest: ∅
- │ │ ├── opening_loc: (202,14)-(202,15) = "{"
- │ │ └── closing_loc: (202,17)-(202,18) = "}"
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── opening_loc: (202,13)-(202,14) = "["
- │ └── closing_loc: (202,18)-(202,19) = "]"
- └── operator_loc: (202,4)-(202,6) = "=>"
diff --git a/test/prism/snapshots/procs.txt b/test/prism/snapshots/procs.txt
deleted file mode 100644
index 3080af8312..0000000000
--- a/test/prism/snapshots/procs.txt
+++ /dev/null
@@ -1,383 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── locals: (length: 3)
- │ │ │ ├── @ BlockLocalVariableNode (location: (1,7)-(1,8))
- │ │ │ │ └── name: :b
- │ │ │ ├── @ BlockLocalVariableNode (location: (1,10)-(1,11))
- │ │ │ │ └── name: :c
- │ │ │ └── @ BlockLocalVariableNode (location: (1,13)-(1,14))
- │ │ │ └── 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: []
- │ ├── locals_body_index: 0
- │ ├── operator_loc: (3,0)-(3,2) = "->"
- │ ├── opening_loc: (3,3)-(3,5) = "do"
- │ ├── closing_loc: (5,0)-(5,3) = "end"
- │ ├── parameters: ∅
- │ └── body:
- │ @ BeginNode (location: (4,0)-(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: []
- │ ├── locals_body_index: 0
- │ ├── operator_loc: (7,0)-(7,2) = "->"
- │ ├── opening_loc: (7,3)-(7,5) = "do"
- │ ├── closing_loc: (11,0)-(11,3) = "end"
- │ ├── parameters: ∅
- │ └── body:
- │ @ BeginNode (location: (8,0)-(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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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]
- │ ├── locals_body_index: 5
- │ ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (17,6)-(17,11))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (17,6)-(17,7) = "b"
- │ │ │ │ ├── operator_loc: (17,8)-(17,9) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (17,10)-(17,11))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 2)
- │ │ │ │ ├── @ RequiredKeywordParameterNode (location: (17,13)-(17,15))
- │ │ │ │ │ ├── name: :c
- │ │ │ │ │ └── name_loc: (17,13)-(17,15) = "c:"
- │ │ │ │ └── @ RequiredKeywordParameterNode (location: (17,17)-(17,19))
- │ │ │ │ ├── name: :d
- │ │ │ │ └── name_loc: (17,17)-(17,19) = "d:"
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (17,21)-(17,23))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 7
- │ ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (19,7)-(19,12))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (19,7)-(19,8) = "b"
- │ │ │ │ ├── operator_loc: (19,9)-(19,10) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (19,11)-(19,12))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (19,14)-(19,16))
- │ │ │ │ ├── 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))
- │ │ │ │ │ ├── name: :d
- │ │ │ │ │ └── name_loc: (19,18)-(19,20) = "d:"
- │ │ │ │ └── @ RequiredKeywordParameterNode (location: (19,22)-(19,24))
- │ │ │ │ ├── name: :e
- │ │ │ │ └── name_loc: (19,22)-(19,24) = "e:"
- │ │ │ ├── keyword_rest:
- │ │ │ │ @ KeywordRestParameterNode (location: (19,26)-(19,29))
- │ │ │ │ ├── name: :f
- │ │ │ │ ├── name_loc: (19,28)-(19,29) = "f"
- │ │ │ │ └── operator_loc: (19,26)-(19,28) = "**"
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (19,31)-(19,33))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 7
- │ ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (21,7)-(21,12))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (21,7)-(21,8) = "b"
- │ │ │ │ ├── operator_loc: (21,9)-(21,10) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (21,11)-(21,12))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (21,14)-(21,16))
- │ │ │ │ ├── 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))
- │ │ │ │ │ ├── name: :d
- │ │ │ │ │ └── name_loc: (21,18)-(21,20) = "d:"
- │ │ │ │ └── @ RequiredKeywordParameterNode (location: (21,22)-(21,24))
- │ │ │ │ ├── name: :e
- │ │ │ │ └── name_loc: (21,22)-(21,24) = "e:"
- │ │ │ ├── keyword_rest:
- │ │ │ │ @ KeywordRestParameterNode (location: (21,26)-(21,29))
- │ │ │ │ ├── name: :f
- │ │ │ │ ├── name_loc: (21,28)-(21,29) = "f"
- │ │ │ │ └── operator_loc: (21,26)-(21,28) = "**"
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (21,31)-(21,33))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (27,8)-(27,9))
- │ │ │ │ └── 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))
- │ │ │ ├── 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
deleted file mode 100644
index 0ac4d10bf7..0000000000
--- a/test/prism/snapshots/range_begin_open_exclusive.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── 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
deleted file mode 100644
index 1cba894221..0000000000
--- a/test/prism/snapshots/range_begin_open_inclusive.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── 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
deleted file mode 100644
index 76b8eb197e..0000000000
--- a/test/prism/snapshots/range_end_open_exclusive.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 576ea40fa5..0000000000
--- a/test/prism/snapshots/range_end_open_inclusive.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- ├── right: ∅
- └── operator_loc: (1,1)-(1,3) = ".."
diff --git a/test/prism/snapshots/ranges.txt b/test/prism/snapshots/ranges.txt
deleted file mode 100644
index c9dbf26022..0000000000
--- a/test/prism/snapshots/ranges.txt
+++ /dev/null
@@ -1,492 +0,0 @@
-@ 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
- │ │ └── 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
- │ │ └── 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
- │ ├── right:
- │ │ @ IntegerNode (location: (5,4)-(5,5))
- │ │ └── flags: decimal
- │ └── operator_loc: (5,1)-(5,4) = "..."
- ├── @ CallNode (location: (7,0)-(7,9))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (7,0)-(7,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ ├── right:
- │ │ @ IntegerNode (location: (13,3)-(13,4))
- │ │ └── flags: decimal
- │ └── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ ├── right:
- │ │ @ RangeNode (location: (19,5)-(19,8))
- │ │ ├── flags: ∅
- │ │ ├── left: ∅
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (19,7)-(19,8))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ │ ├── right: ∅
- │ │ └── operator_loc: (21,1)-(21,3) = ".."
- │ ├── right:
- │ │ @ IntegerNode (location: (21,7)-(21,8))
- │ │ └── flags: decimal
- │ └── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ RangeNode (location: (47,0)-(47,7))
- │ ├── flags: ∅
- │ ├── left:
- │ │ @ IntegerNode (location: (47,0)-(47,1))
- │ │ └── flags: decimal
- │ ├── right:
- │ │ @ CallNode (location: (47,4)-(47,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ IntegerNode (location: (47,6)-(47,7))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- ├── right:
- │ @ CallNode (location: (49,4)-(49,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (49,6)-(49,7))
- │ │ └── flags: decimal
- │ ├── 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
deleted file mode 100644
index 318c1a832a..0000000000
--- a/test/prism/snapshots/regex.txt
+++ /dev/null
@@ -1,371 +0,0 @@
-@ ProgramNode (location: (1,0)-(40,24))
-├── locals: [:foo, :ab, :abc, :a]
-└── statements:
- @ StatementsNode (location: (1,0)-(40,24))
- └── body: (length: 21)
- ├── @ CallNode (location: (1,0)-(1,9))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ ├── 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
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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: ∅
- │ ├── opening_loc: (21,0)-(21,3) = "%r("
- │ ├── content_loc: (21,3)-(24,0) = "\n(?:[\\w\#$%_']|\\(\\)|\\(,\\)|\\[\\]|[0-9])*\n (?:[\\w\#$%_']+)\n"
- │ ├── closing_loc: (24,0)-(24,1) = ")"
- │ └── unescaped: "\n(?:[\\w\#$%_']|\\(\\)|\\(,\\)|\\[\\]|[0-9])*\n (?:[\\w\#$%_']+)\n"
- ├── @ CallNode (location: (26,0)-(26,16))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ RegularExpressionNode (location: (26,0)-(26,8))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ └── operator_loc: (39,2)-(39,3) = "="
- └── @ CallNode (location: (40,0)-(40,24))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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) = "}"
diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt
deleted file mode 100644
index 3f9dc426a2..0000000000
--- a/test/prism/snapshots/rescue.txt
+++ /dev/null
@@ -1,390 +0,0 @@
-@ ProgramNode (location: (1,0)-(31,3))
-├── locals: [:a]
-└── statements:
- @ StatementsNode (location: (1,0)-(31,3))
- └── body: (length: 12)
- ├── @ RescueModifierNode (location: (1,0)-(1,14))
- │ ├── expression:
- │ │ @ CallNode (location: (1,0)-(1,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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))
- ├── @ RescueModifierNode (location: (6,0)-(6,16))
- │ ├── expression:
- │ │ @ BreakNode (location: (6,0)-(6,5))
- │ │ ├── arguments: ∅
- │ │ └── keyword_loc: (6,0)-(6,5) = "break"
- │ ├── keyword_loc: (6,6)-(6,12) = "rescue"
- │ └── rescue_expression:
- │ @ NilNode (location: (6,13)-(6,16))
- ├── @ RescueModifierNode (location: (8,0)-(8,15))
- │ ├── expression:
- │ │ @ NextNode (location: (8,0)-(8,4))
- │ │ ├── arguments: ∅
- │ │ └── keyword_loc: (8,0)-(8,4) = "next"
- │ ├── keyword_loc: (8,5)-(8,11) = "rescue"
- │ └── rescue_expression:
- │ @ NilNode (location: (8,12)-(8,15))
- ├── @ 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
- │ │ ├── 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
- │ └── operator_loc: (12,15)-(12,17) = "||"
- ├── @ RescueModifierNode (location: (14,0)-(14,22))
- │ ├── expression:
- │ │ @ CallNode (location: (14,0)-(14,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── 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
- │ │ └── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (18,7)-(18,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (18,8)-(18,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (18,8)-(18,9))
- │ │ │ │ └── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── keyword_loc: (26,34)-(26,40) = "rescue"
- │ │ └── rescue_expression:
- │ │ @ NilNode (location: (26,41)-(26,44))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: (29,2)-(31,3))
- │ ├── begin_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (29,2)-(29,6))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (29,2)-(29,6))
- │ │ ├── flags: ∅
- │ │ ├── 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: static_keys
- │ │ │ └── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (29,4)-(29,6))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (29,4)-(29,6))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── def_keyword_loc: (28,0)-(28,3) = "def"
- ├── operator_loc: ∅
- ├── lparen_loc: ∅
- ├── rparen_loc: ∅
- ├── equal_loc: ∅
- └── end_keyword_loc: (31,0)-(31,3) = "end"
diff --git a/test/prism/snapshots/return.txt b/test/prism/snapshots/return.txt
deleted file mode 100644
index 647ae1af9d..0000000000
--- a/test/prism/snapshots/return.txt
+++ /dev/null
@@ -1,138 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- ├── @ 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
- ├── @ 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
- │ ├── @ IntegerNode (location: (9,10)-(9,11))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (10,0)-(10,1))
- │ └── flags: decimal
- ├── @ 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
- │ ├── @ IntegerNode (location: (12,10)-(12,11))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (12,13)-(12,14))
- │ └── flags: decimal
- ├── @ 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
- │ │ ├── @ IntegerNode (location: (14,11)-(14,12))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (14,14)-(14,15))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (18,2)-(18,3))
- │ │ └── flags: decimal
- │ ├── 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
- ├── 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
deleted file mode 100644
index 3595e2a05c..0000000000
--- a/test/prism/snapshots/seattlerb/BEGIN.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 20da816e25..0000000000
--- a/test/prism/snapshots/seattlerb/TestRubyParserShared.txt
+++ /dev/null
@@ -1,357 +0,0 @@
-@ 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (7,0)-(7,5) = "line2"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "line2"
- │ │ └── @ SymbolNode (location: (8,0)-(8,5))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (27,0)-(27,5) = "line2"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "line2"
- │ │ └── @ SymbolNode (location: (28,0)-(28,5))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (47,0)-(47,1) = ":"
- │ │ │ ├── value_loc: (47,1)-(47,6) = "line2"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "line2"
- │ │ └── @ SymbolNode (location: (48,0)-(48,6))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (53,8)-(53,9))
- │ │ │ │ └── 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]
- │ │ ├── locals_body_index: 2
- │ │ ├── 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
- │ │ │ └── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (68,8)-(68,9))
- │ │ │ │ └── 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]
- │ │ ├── locals_body_index: 2
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: (76,4)-(76,5) = ":"
- │ │ │ │ │ ├── value_loc: (76,5)-(76,10) = "line3"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "line3"
- │ │ │ │ └── @ SymbolNode (location: (77,4)-(77,10))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- ├── 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: ∅
- │ │ ├── opening_loc: (90,0)-(90,1) = ":"
- │ │ ├── value_loc: (90,1)-(90,6) = "line2"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "line2"
- │ └── @ SymbolNode (location: (91,0)-(91,6))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 1b223bd8fe..0000000000
--- a/test/prism/snapshots/seattlerb/__ENCODING__.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index a2586423d7..0000000000
--- a/test/prism/snapshots/seattlerb/alias_gvar_backref.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
deleted file mode 100644
index bf475a5c71..0000000000
--- a/test/prism/snapshots/seattlerb/alias_resword.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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: ∅
- │ ├── opening_loc: ∅
- │ ├── value_loc: (1,6)-(1,8) = "in"
- │ ├── closing_loc: ∅
- │ └── unescaped: "in"
- ├── old_name:
- │ @ SymbolNode (location: (1,9)-(1,12))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index b60b131fd2..0000000000
--- a/test/prism/snapshots/seattlerb/and_multi.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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
deleted file mode 100644
index 398a014248..0000000000
--- a/test/prism/snapshots/seattlerb/aref_args_assocs.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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:
- │ │ @ IntegerNode (location: (1,6)-(1,7))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 7a63842f36..0000000000
--- a/test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-@ 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
- │ └── @ 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:
- │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 538a2691d6..0000000000
--- a/test/prism/snapshots/seattlerb/args_kw_block.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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))
- │ │ ├── name: :a
- │ │ ├── name_loc: (1,6)-(1,8) = "a:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block:
- │ @ BlockParameterNode (location: (1,12)-(1,14))
- │ ├── name: :b
- │ ├── name_loc: (1,13)-(1,14) = "b"
- │ └── operator_loc: (1,12)-(1,13) = "&"
- ├── body: ∅
- ├── locals: [:a, :b]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index a08ee03052..0000000000
--- a/test/prism/snapshots/seattlerb/array_line_breaks.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt b/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt
deleted file mode 100644
index d46a181fc7..0000000000
--- a/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
deleted file mode 100644
index 8707c29593..0000000000
--- a/test/prism/snapshots/seattlerb/assoc__bare.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 1d65eef3f9..0000000000
--- a/test/prism/snapshots/seattlerb/assoc_label.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,2)-(1,5))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,2)-(1,4))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index c869af4607..0000000000
--- a/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt b/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt
deleted file mode 100644
index d9e5572292..0000000000
--- a/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── 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
- │ │ │ └── @ IntegerNode (location: (1,6)-(1,7))
- │ │ │ └── flags: decimal
- │ │ ├── opening_loc: (1,2)-(1,3) = "["
- │ │ └── closing_loc: (1,7)-(1,8) = "]"
- │ └── @ IntegerNode (location: (1,12)-(1,13))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 9a41409dbb..0000000000
--- a/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-@ 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
- │ │ ├── @ IntegerNode (location: (1,4)-(1,5))
- │ │ │ └── flags: decimal
- │ │ ├── @ IntegerNode (location: (1,7)-(1,8))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (1,10)-(1,11))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index 74faad3303..0000000000
--- a/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt b/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt
deleted file mode 100644
index abb7e680d7..0000000000
--- a/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index 553362030e..0000000000
--- a/test/prism/snapshots/seattlerb/bang_eq.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bdot2.txt b/test/prism/snapshots/seattlerb/bdot2.txt
deleted file mode 100644
index ad710a4212..0000000000
--- a/test/prism/snapshots/seattlerb/bdot2.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- │ └── operator_loc: (1,0)-(1,2) = ".."
- ├── @ RangeNode (location: (2,2)-(2,5))
- │ ├── flags: ∅
- │ ├── left: ∅
- │ ├── right:
- │ │ @ CallNode (location: (2,4)-(2,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index c9a1097099..0000000000
--- a/test/prism/snapshots/seattlerb/bdot3.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- │ └── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index e1698d0bae..0000000000
--- a/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-@ 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
deleted file mode 100644
index 686fa100f1..0000000000
--- a/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- ├── 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
- │ └── 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
- │ └── 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
- │ └── 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
deleted file mode 100644
index 02e1f097ac..0000000000
--- a/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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
deleted file mode 100644
index b36fe5c1fe..0000000000
--- a/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-@ 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
deleted file mode 100644
index 81d5727812..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg__bare.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ ├── name: ∅
- │ ├── name_loc: ∅
- │ └── operator_loc: (1,6)-(1,7) = "&"
- ├── body: ∅
- ├── locals: [:&]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index d503dc7443..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── 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
deleted file mode 100644
index fd0b46ed83..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,21))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,21))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,21))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,19))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,18))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,11))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
- │ │ │ ├── operator_loc: (1,9)-(1,10) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,10)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ └── name: :d
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,16)-(1,18))
- │ │ ├── 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
deleted file mode 100644
index 736fec6ec1..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,18))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,17))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,13))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,13))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,15)-(1,17))
- │ │ │ ├── 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
deleted file mode 100644
index 2b57a0c090..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,25))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,25))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,25))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 5
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,23))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,22))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,11))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
- │ │ │ ├── operator_loc: (1,9)-(1,10) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,10)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
- │ │ │ ├── name: :d
- │ │ │ ├── name_loc: (1,14)-(1,15) = "d"
- │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
- │ │ │ └── name: :e
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,20)-(1,22))
- │ │ ├── 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
deleted file mode 100644
index 5e28906256..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_optional.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index 51de82e90a..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_scope.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,10))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,6))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── locals: (length: 1)
- │ │ └── @ BlockLocalVariableNode (location: (1,8)-(1,9))
- │ │ └── 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
deleted file mode 100644
index 3b4b198d1f..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_scope2.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,3)-(1,12))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,4)-(1,5))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── locals: (length: 2)
- │ │ ├── @ BlockLocalVariableNode (location: (1,7)-(1,8))
- │ │ │ └── name: :c
- │ │ └── @ BlockLocalVariableNode (location: (1,10)-(1,11))
- │ │ └── 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
deleted file mode 100644
index c8aae59285..0000000000
--- a/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,14))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,13))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,8)-(1,10))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,9)-(1,10) = "c"
- │ │ │ └── operator_loc: (1,8)-(1,9) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
- │ │ │ └── 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
deleted file mode 100644
index e4d311085d..0000000000
--- a/test/prism/snapshots/seattlerb/block_args_kwargs.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,23))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,23))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,23))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── 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
deleted file mode 100644
index 70e4084395..0000000000
--- a/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 4a5dc9b59b..0000000000
--- a/test/prism/snapshots/seattlerb/block_args_opt1.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,24))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,24))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,24))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,15))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,14))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index af334a87f7..0000000000
--- a/test/prism/snapshots/seattlerb/block_args_opt2.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (1,6)-(1,7) = "b"
- │ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ OptionalParameterNode (location: (1,11)-(1,14))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,11)-(1,12) = "c"
- │ │ │ ├── operator_loc: (1,12)-(1,13) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,13)-(1,14))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index ee99843c6f..0000000000
--- a/test/prism/snapshots/seattlerb/block_args_opt2_2.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,35))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,35))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,35))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,23))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,22))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 2)
- │ │ │ ├── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ OptionalParameterNode (location: (1,16)-(1,22))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,16)-(1,17) = "c"
- │ │ │ ├── operator_loc: (1,18)-(1,19) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,20)-(1,22))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index 016fdc6358..0000000000
--- a/test/prism/snapshots/seattlerb/block_args_opt3.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,42))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,42))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,42))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,27))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,26))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 2)
- │ │ │ ├── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ │ ├── name: :b
- │ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ OptionalParameterNode (location: (1,16)-(1,22))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,16)-(1,17) = "c"
- │ │ │ ├── operator_loc: (1,18)-(1,19) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,20)-(1,22))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,24)-(1,26))
- │ │ ├── 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_break.txt b/test/prism/snapshots/seattlerb/block_break.txt
deleted file mode 100644
index 502d60ed40..0000000000
--- a/test/prism/snapshots/seattlerb/block_break.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,26))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,26))
- └── body: (length: 1)
- └── @ BreakNode (location: (1,0)-(1,26))
- ├── arguments:
- │ @ ArgumentsNode (location: (1,6)-(1,26))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ CallNode (location: (1,6)-(1,26))
- │ ├── flags: ∅
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :foo
- │ ├── message_loc: (1,6)-(1,9) = "foo"
- │ ├── opening_loc: ∅
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (1,10)-(1,13))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (1,10)-(1,13))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :arg
- │ │ ├── message_loc: (1,10)-(1,13) = "arg"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (1,14)-(1,26))
- │ ├── locals: [:bar]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (1,17)-(1,22))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (1,18)-(1,21))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,18)-(1,21))
- │ │ │ │ └── name: :bar
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── locals: (length: 0)
- │ │ ├── opening_loc: (1,17)-(1,18) = "|"
- │ │ └── closing_loc: (1,21)-(1,22) = "|"
- │ ├── body: ∅
- │ ├── opening_loc: (1,14)-(1,16) = "do"
- │ └── closing_loc: (1,23)-(1,26) = "end"
- └── keyword_loc: (1,0)-(1,5) = "break"
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
deleted file mode 100644
index 363ee275fa..0000000000
--- a/test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,11))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,11))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(3,4))
- │ ├── flags: ∅
- │ ├── 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))
- │ │ │ │ └── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :d
- │ │ │ ├── message_loc: (2,1)-(2,2) = "d"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── locals: [:c]
- │ │ ├── locals_body_index: 1
- │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index e49d2b8d01..0000000000
--- a/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-@ 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
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (1,11)-(1,12))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (1,11)-(1,12))
- │ │ ├── flags: variable_call
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,22)-(1,25))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,23)-(1,24))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,23)-(1,24))
- │ │ │ └── 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
- │ ├── 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
deleted file mode 100644
index 0656b2e53e..0000000000
--- a/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt
+++ /dev/null
@@ -1,114 +0,0 @@
-@ 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
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (1,11)-(1,12))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (1,11)-(1,12))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,24)-(1,27))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,25)-(1,26))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,25)-(1,26))
- │ │ │ └── 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
- │ ├── 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
deleted file mode 100644
index ebe805b932..0000000000
--- a/test/prism/snapshots/seattlerb/block_call_operation_colon.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 1824f897f6..0000000000
--- a/test/prism/snapshots/seattlerb/block_call_operation_dot.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 69e5ddf6fc..0000000000
--- a/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-@ ProgramNode (location: (1,0)-(2,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(2,10))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,5))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index d4d3f88220..0000000000
--- a/test/prism/snapshots/seattlerb/block_command_operation_colon.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 2fc6674e4c..0000000000
--- a/test/prism/snapshots/seattlerb/block_command_operation_dot.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index d3de3562a6..0000000000
--- a/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index dcb4415a70..0000000000
--- a/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index 52a7a6b7f8..0000000000
--- a/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── rest:
- │ │ │ │ @ SplatNode (location: (1,9)-(1,11))
- │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
- │ │ │ │ └── expression:
- │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11))
- │ │ │ │ └── name: :b
- │ │ │ ├── rights: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ │ └── 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
deleted file mode 100644
index 4be5573522..0000000000
--- a/test/prism/snapshots/seattlerb/block_decomp_splat.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index fa7cce4870..0000000000
--- a/test/prism/snapshots/seattlerb/block_kw.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :k
- │ │ │ ├── name_loc: (1,8)-(1,10) = "k:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,10)-(1,12))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index 6636ce987a..0000000000
--- a/test/prism/snapshots/seattlerb/block_kw__required.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── 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
deleted file mode 100644
index 6eee362895..0000000000
--- a/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :kw
- │ │ │ ├── name_loc: (1,6)-(1,9) = "kw:"
- │ │ │ └── value:
- │ │ │ @ SymbolNode (location: (1,10)-(1,14))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 3d6ed902f1..0000000000
--- a/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ │ ├── name: :kw
- │ │ │ │ ├── name_loc: (1,6)-(1,9) = "kw:"
- │ │ │ │ └── value:
- │ │ │ │ @ SymbolNode (location: (1,10)-(1,14))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
- │ │ │ │ ├── value_loc: (1,11)-(1,14) = "val"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "val"
- │ │ │ └── @ OptionalKeywordParameterNode (location: (1,16)-(1,26))
- │ │ │ ├── name: :kw2
- │ │ │ ├── name_loc: (1,16)-(1,20) = "kw2:"
- │ │ │ └── value:
- │ │ │ @ SymbolNode (location: (1,21)-(1,26))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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_next.txt b/test/prism/snapshots/seattlerb/block_next.txt
deleted file mode 100644
index a72f57490e..0000000000
--- a/test/prism/snapshots/seattlerb/block_next.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,25))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,25))
- └── body: (length: 1)
- └── @ NextNode (location: (1,0)-(1,25))
- ├── arguments:
- │ @ ArgumentsNode (location: (1,5)-(1,25))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ CallNode (location: (1,5)-(1,25))
- │ ├── flags: ∅
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :foo
- │ ├── message_loc: (1,5)-(1,8) = "foo"
- │ ├── opening_loc: ∅
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (1,9)-(1,12))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (1,9)-(1,12))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :arg
- │ │ ├── message_loc: (1,9)-(1,12) = "arg"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (1,13)-(1,25))
- │ ├── locals: [:bar]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (1,16)-(1,21))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (1,17)-(1,20))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,20))
- │ │ │ │ └── name: :bar
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── locals: (length: 0)
- │ │ ├── opening_loc: (1,16)-(1,17) = "|"
- │ │ └── closing_loc: (1,20)-(1,21) = "|"
- │ ├── body: ∅
- │ ├── opening_loc: (1,13)-(1,15) = "do"
- │ └── closing_loc: (1,22)-(1,25) = "end"
- └── keyword_loc: (1,0)-(1,4) = "next"
diff --git a/test/prism/snapshots/seattlerb/block_opt_arg.txt b/test/prism/snapshots/seattlerb/block_opt_arg.txt
deleted file mode 100644
index c0e90ed132..0000000000
--- a/test/prism/snapshots/seattlerb/block_opt_arg.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
- │ │ │ ├── operator_loc: (1,6)-(1,7) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,7)-(1,8))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11))
- │ │ │ └── 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
deleted file mode 100644
index dfdd8926cd..0000000000
--- a/test/prism/snapshots/seattlerb/block_opt_splat.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,12)-(1,14))
- │ │ │ ├── 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
deleted file mode 100644
index 444baeb8d0..0000000000
--- a/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,22))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,22))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
- │ │ │ ├── operator_loc: (1,6)-(1,7) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,7)-(1,8))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,10)-(1,12))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,11)-(1,12) = "c"
- │ │ │ └── operator_loc: (1,10)-(1,11) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
- │ │ │ └── name: :d
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,17)-(1,19))
- │ │ ├── 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
deleted file mode 100644
index 052299e44b..0000000000
--- a/test/prism/snapshots/seattlerb/block_optarg.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ SymbolNode (location: (1,9)-(1,11))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
deleted file mode 100644
index a34e0bca37..0000000000
--- a/test/prism/snapshots/seattlerb/block_paren_splat.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ │ └── name: :b
- │ │ │ ├── rest:
- │ │ │ │ @ SplatNode (location: (1,9)-(1,11))
- │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
- │ │ │ │ └── expression:
- │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11))
- │ │ │ │ └── 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
deleted file mode 100644
index cad3954495..0000000000
--- a/test/prism/snapshots/seattlerb/block_reg_optarg.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,15))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,14))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ SymbolNode (location: (1,12)-(1,14))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 3764cac9c8..0000000000
--- a/test/prism/snapshots/seattlerb/block_return.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,18)-(1,23))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,19)-(1,22))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,19)-(1,22))
- │ │ │ └── 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
deleted file mode 100644
index cccf6b79a2..0000000000
--- a/test/prism/snapshots/seattlerb/block_scope.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,8))
- │ ├── parameters: ∅
- │ ├── locals: (length: 1)
- │ │ └── @ BlockLocalVariableNode (location: (1,6)-(1,7))
- │ │ └── 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
deleted file mode 100644
index 0cf4b62f7d..0000000000
--- a/test/prism/snapshots/seattlerb/block_splat_reg.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,6)-(1,7) = "b"
- │ │ │ └── operator_loc: (1,5)-(1,6) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ └── 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
deleted file mode 100644
index 22d8e4c48f..0000000000
--- a/test/prism/snapshots/seattlerb/bug169.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 11620b2dea..0000000000
--- a/test/prism/snapshots/seattlerb/bug179.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index f7eaefa5c6..0000000000
--- a/test/prism/snapshots/seattlerb/bug190.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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,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
deleted file mode 100644
index b9cbac0d1c..0000000000
--- a/test/prism/snapshots/seattlerb/bug191.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 3faff193dc..0000000000
--- a/test/prism/snapshots/seattlerb/bug202.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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
- │ └── 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
- └── operator_loc: (2,7)-(2,8) = "="
diff --git a/test/prism/snapshots/seattlerb/bug236.txt b/test/prism/snapshots/seattlerb/bug236.txt
deleted file mode 100644
index 65339efa8b..0000000000
--- a/test/prism/snapshots/seattlerb/bug236.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,6))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,6))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,7))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (1,2)-(1,6))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (1,3)-(1,5))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4))
- │ │ │ │ └── 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (3,2)-(3,5))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (3,3)-(3,4))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (3,3)-(3,4))
- │ │ │ └── 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
deleted file mode 100644
index e0633eb815..0000000000
--- a/test/prism/snapshots/seattlerb/bug290.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 5630cbf9c9..0000000000
--- a/test/prism/snapshots/seattlerb/bug_187.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(3,3))
- ├── flags: ∅
- ├── 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
- │ │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (2,4)-(2,6) = "do"
- │ │ └── closing_loc: (2,7)-(2,10) = "end"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 443b9b7358..0000000000
--- a/test/prism/snapshots/seattlerb/bug_215.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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: ∅
- │ ├── 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
deleted file mode 100644
index 4c684f32dc..0000000000
--- a/test/prism/snapshots/seattlerb/bug_249.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,28))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,28))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(4,28))
- ├── flags: ∅
- ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (4,11)-(4,28))
- │ ├── key:
- │ │ @ SymbolNode (location: (4,11)-(4,14))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 3daf505e5f..0000000000
--- a/test/prism/snapshots/seattlerb/bug_and.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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
deleted file mode 100644
index e2617df20f..0000000000
--- a/test/prism/snapshots/seattlerb/bug_args__19.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── 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
- │ ├── 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
deleted file mode 100644
index 3ee3dd05ec..0000000000
--- a/test/prism/snapshots/seattlerb/bug_args_masgn.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ │ │ │ └── name: :a
- │ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ │ └── name: :b
- │ │ │ │ ├── rest: ∅
- │ │ │ │ ├── rights: (length: 0)
- │ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
- │ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
- │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ └── 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
deleted file mode 100644
index 3de9e976d1..0000000000
--- a/test/prism/snapshots/seattlerb/bug_args_masgn2.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,22))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,22))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── 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))
- │ │ │ │ │ │ │ │ └── name: :a
- │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11))
- │ │ │ │ │ │ │ └── name: :b
- │ │ │ │ │ │ ├── rest: ∅
- │ │ │ │ │ │ ├── rights: (length: 0)
- │ │ │ │ │ │ ├── lparen_loc: (1,6)-(1,7) = "("
- │ │ │ │ │ │ └── rparen_loc: (1,11)-(1,12) = ")"
- │ │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
- │ │ │ │ │ └── name: :c
- │ │ │ │ ├── rest: ∅
- │ │ │ │ ├── rights: (length: 0)
- │ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
- │ │ │ │ └── rparen_loc: (1,15)-(1,16) = ")"
- │ │ │ └── @ RequiredParameterNode (location: (1,18)-(1,19))
- │ │ │ └── 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
deleted file mode 100644
index 4278d58a00..0000000000
--- a/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,19))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,19))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ │ │ │ │ └── name: :k
- │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11))
- │ │ │ │ │ │ └── name: :v
- │ │ │ │ │ ├── rest: ∅
- │ │ │ │ │ ├── rights: (length: 0)
- │ │ │ │ │ ├── lparen_loc: (1,6)-(1,7) = "("
- │ │ │ │ │ └── rparen_loc: (1,11)-(1,12) = ")"
- │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
- │ │ │ │ └── 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
deleted file mode 100644
index 5056fe6d70..0000000000
--- a/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ │ │ ├── opening_loc: (2,10)-(2,11) = "("
- │ │ │ │ └── closing_loc: (2,13)-(2,14) = ")"
- │ │ │ └── @ IntegerNode (location: (2,16)-(2,17))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ │ ├── opening_loc: (7,10)-(7,11) = "("
- │ │ │ │ └── closing_loc: (7,12)-(7,13) = ")"
- │ │ │ └── @ IntegerNode (location: (7,15)-(7,16))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- ├── 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
- │ │ ├── opening_loc: (11,2)-(11,3) = "("
- │ │ └── closing_loc: (11,5)-(11,6) = ")"
- │ └── @ IntegerNode (location: (11,8)-(11,9))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 6479334c8e..0000000000
--- a/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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: ∅
- │ ├── 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,17))
- │ ├── keyword_loc: (1,9)-(1,13) = "when"
- │ ├── conditions: (length: 1)
- │ │ └── @ RegularExpressionNode (location: (1,14)-(1,17))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (1,14)-(1,15) = "/"
- │ │ ├── content_loc: (1,15)-(1,16) = "x"
- │ │ ├── closing_loc: (1,16)-(1,17) = "/"
- │ │ └── unescaped: "x"
- │ └── 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
deleted file mode 100644
index 42815e0dfe..0000000000
--- a/test/prism/snapshots/seattlerb/bug_comma.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index b5a397f4f5..0000000000
--- a/test/prism/snapshots/seattlerb/bug_cond_pct.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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: ∅
- │ │ ├── opening_loc: (1,11)-(1,14) = "%r%"
- │ │ ├── content_loc: (1,14)-(1,22) = "blahblah"
- │ │ ├── closing_loc: (1,22)-(1,23) = "%"
- │ │ └── unescaped: "blahblah"
- │ └── 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
deleted file mode 100644
index cea1fc8db0..0000000000
--- a/test/prism/snapshots/seattlerb/bug_hash_args.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,19))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,19))
- ├── flags: ∅
- ├── 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: ∅
- │ │ ├── opening_loc: (1,4)-(1,5) = ":"
- │ │ ├── value_loc: (1,5)-(1,8) = "bar"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "bar"
- │ └── @ KeywordHashNode (location: (1,10)-(1,18))
- │ ├── flags: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,10)-(1,18))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,10)-(1,14))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index e4c2a10f2e..0000000000
--- a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ │ ├── opening_loc: (1,4)-(1,5) = ":"
- │ │ ├── value_loc: (1,5)-(1,8) = "bar"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "bar"
- │ └── @ KeywordHashNode (location: (1,10)-(1,18))
- │ ├── flags: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,10)-(1,18))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,10)-(1,14))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 433fb02411..0000000000
--- a/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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
deleted file mode 100644
index 194b01f281..0000000000
--- a/test/prism/snapshots/seattlerb/bug_masgn_right.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,15))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,14))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,14))
- │ │ │ ├── lefts: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ │ └── name: :b
- │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
- │ │ │ │ └── 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
deleted file mode 100644
index c5157a0ed9..0000000000
--- a/test/prism/snapshots/seattlerb/bug_not_parens.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index b31d4a19b6..0000000000
--- a/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index 8c6bf2f2e3..0000000000
--- a/test/prism/snapshots/seattlerb/call_and.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc.txt b/test/prism/snapshots/seattlerb/call_arg_assoc.txt
deleted file mode 100644
index b52ba53930..0000000000
--- a/test/prism/snapshots/seattlerb/call_arg_assoc.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- ├── 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
- │ └── @ 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:
- │ │ @ IntegerNode (location: (1,8)-(1,9))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 9a052beffa..0000000000
--- a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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: ∅
- ├── 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
- │ └── @ KeywordHashNode (location: (1,5)-(1,15))
- │ ├── flags: ∅
- │ └── elements: (length: 2)
- │ ├── @ AssocNode (location: (1,5)-(1,10))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,5)-(1,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ └── @ AssocSplatNode (location: (1,12)-(1,15))
- │ ├── value:
- │ │ @ IntegerNode (location: (1,14)-(1,15))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index dab497db45..0000000000
--- a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 958231a21a..0000000000
--- a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,8))
- └── body: (length: 3)
- ├── @ CallNode (location: (1,0)-(1,11))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (3,0)-(3,8))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (3,2)-(3,8))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (3,2)-(3,6))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- └── @ CallNode (location: (5,0)-(5,8))
- ├── flags: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (5,2)-(5,8))
- │ ├── key:
- │ │ @ SymbolNode (location: (5,2)-(5,6))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index ae1e2be40d..0000000000
--- a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- ├── 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
- │ └── @ 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:
- │ │ @ IntegerNode (location: (1,8)-(1,9))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index c371dda3f4..0000000000
--- a/test/prism/snapshots/seattlerb/call_args_command.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 1bca15afca..0000000000
--- a/test/prism/snapshots/seattlerb/call_array_arg.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- ├── 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: ∅
- │ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
- │ │ │ ├── value_loc: (1,7)-(1,8) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ └── @ SymbolNode (location: (1,10)-(1,12))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index c75ddc8272..0000000000
--- a/test/prism/snapshots/seattlerb/call_array_block_call.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,19))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,19))
- ├── flags: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
deleted file mode 100644
index 04900f9b39..0000000000
--- a/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ ProgramNode (location: (1,0)-(2,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(2,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(2,3))
- ├── flags: ∅
- ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index f8cde2f6a9..0000000000
--- a/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ │ │ ├── opening_loc: (1,3)-(1,4) = ":"
- │ │ │ ├── value_loc: (1,4)-(1,5) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ └── @ KeywordHashNode (location: (1,7)-(1,14))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,7)-(1,14))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,7)-(1,9))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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
deleted file mode 100644
index ac3a0e1ebf..0000000000
--- a/test/prism/snapshots/seattlerb/call_assoc.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- ├── 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:
- │ │ @ IntegerNode (location: (1,5)-(1,6))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 6d12125260..0000000000
--- a/test/prism/snapshots/seattlerb/call_assoc_new.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,2)-(1,5))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,2)-(1,4))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 1c079f9d1d..0000000000
--- a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,4))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(5,4))
- ├── flags: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,2)-(5,3))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,2)-(1,4))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ └── 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
deleted file mode 100644
index 18e937c55c..0000000000
--- a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- ├── 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:
- │ │ @ IntegerNode (location: (1,5)-(1,6))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 1631f7dd6e..0000000000
--- a/test/prism/snapshots/seattlerb/call_bang_command_call.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index ba7dcfa262..0000000000
--- a/test/prism/snapshots/seattlerb/call_bang_squiggle.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── 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
deleted file mode 100644
index 037ab33222..0000000000
--- a/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(3,3))
- ├── flags: ∅
- ├── 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
- │ │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
deleted file mode 100644
index 24e9dd6cc9..0000000000
--- a/test/prism/snapshots/seattlerb/call_block_arg_named.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index 7c0fdbc7bc..0000000000
--- a/test/prism/snapshots/seattlerb/call_carat.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_colon2.txt b/test/prism/snapshots/seattlerb/call_colon2.txt
deleted file mode 100644
index 98bfc63126..0000000000
--- a/test/prism/snapshots/seattlerb/call_colon2.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 5522d7b39d..0000000000
--- a/test/prism/snapshots/seattlerb/call_colon_parens.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index bc4e4c94cf..0000000000
--- a/test/prism/snapshots/seattlerb/call_div.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_dot_parens.txt b/test/prism/snapshots/seattlerb/call_dot_parens.txt
deleted file mode 100644
index 8c0989c7bc..0000000000
--- a/test/prism/snapshots/seattlerb/call_dot_parens.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 7b502cf511..0000000000
--- a/test/prism/snapshots/seattlerb/call_env.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 4a31d62679..0000000000
--- a/test/prism/snapshots/seattlerb/call_eq3.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_gt.txt b/test/prism/snapshots/seattlerb/call_gt.txt
deleted file mode 100644
index 5d766435da..0000000000
--- a/test/prism/snapshots/seattlerb/call_gt.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_kwsplat.txt b/test/prism/snapshots/seattlerb/call_kwsplat.txt
deleted file mode 100644
index 04eab025f8..0000000000
--- a/test/prism/snapshots/seattlerb/call_kwsplat.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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: ∅
- ├── 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
- │ └── 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
deleted file mode 100644
index 943dd871d3..0000000000
--- a/test/prism/snapshots/seattlerb/call_leading_dots.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index bebe26f994..0000000000
--- a/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index 11308d4664..0000000000
--- a/test/prism/snapshots/seattlerb/call_lt.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_lte.txt b/test/prism/snapshots/seattlerb/call_lte.txt
deleted file mode 100644
index 3bf6cfd433..0000000000
--- a/test/prism/snapshots/seattlerb/call_lte.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_not.txt b/test/prism/snapshots/seattlerb/call_not.txt
deleted file mode 100644
index a370633ed3..0000000000
--- a/test/prism/snapshots/seattlerb/call_not.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 2300d68c77..0000000000
--- a/test/prism/snapshots/seattlerb/call_pipe.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_rshift.txt b/test/prism/snapshots/seattlerb/call_rshift.txt
deleted file mode 100644
index 53fcc9cbbe..0000000000
--- a/test/prism/snapshots/seattlerb/call_rshift.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_self_brackets.txt b/test/prism/snapshots/seattlerb/call_self_brackets.txt
deleted file mode 100644
index f5652a807e..0000000000
--- a/test/prism/snapshots/seattlerb/call_self_brackets.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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:
- │ @ 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
- ├── 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
deleted file mode 100644
index 450a45b749..0000000000
--- a/test/prism/snapshots/seattlerb/call_spaceship.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── 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
deleted file mode 100644
index 4f3ba3bac8..0000000000
--- a/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,22))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,22))
- ├── flags: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (1,14)-(1,22))
- ├── locals: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,17)-(1,18))
- │ └── body: (length: 1)
- │ └── @ IntegerNode (location: (1,17)-(1,18))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 34c65e80f1..0000000000
--- a/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,19))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,19))
- ├── flags: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (1,11)-(1,19))
- ├── locals: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,14)-(1,15))
- │ └── body: (length: 1)
- │ └── @ IntegerNode (location: (1,14)-(1,15))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index ba3099a0c6..0000000000
--- a/test/prism/snapshots/seattlerb/call_star.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_star2.txt b/test/prism/snapshots/seattlerb/call_star2.txt
deleted file mode 100644
index d6f112fc2c..0000000000
--- a/test/prism/snapshots/seattlerb/call_star2.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_trailing_comma.txt
deleted file mode 100644
index 0e0dd27e38..0000000000
--- a/test/prism/snapshots/seattlerb/call_trailing_comma.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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: ∅
- ├── 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
- ├── 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
deleted file mode 100644
index f0f374f3d4..0000000000
--- a/test/prism/snapshots/seattlerb/call_trailing_dots.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index 03b295254a..0000000000
--- a/test/prism/snapshots/seattlerb/call_unary_bang.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 53bc2bc367..0000000000
--- a/test/prism/snapshots/seattlerb/case_in.txt
+++ /dev/null
@@ -1,940 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: (2,4)-(2,5) = "\""
- │ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "b"
- │ │ │ │ │ ├── closing_loc: (2,6)-(2,8) = "\":"
- │ │ │ │ │ └── unescaped: "b"
- │ │ │ │ ├── value: ∅
- │ │ │ │ └── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── value_loc: (6,6)-(6,7) = "a"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "a"
- │ │ │ │ └── @ SymbolNode (location: (6,8)-(6,9))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── value_loc: (14,6)-(14,7) = "a"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "a"
- │ │ │ │ └── @ SymbolNode (location: (14,8)-(14,9))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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,9))
- │ │ ├── pattern:
- │ │ │ @ RangeNode (location: (22,4)-(22,9))
- │ │ │ ├── flags: exclude_end
- │ │ │ ├── left: ∅
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (22,7)-(22,9))
- │ │ │ │ └── flags: decimal
- │ │ │ └── operator_loc: (22,4)-(22,7) = "..."
- │ │ ├── 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: ∅
- │ │ ├── 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,8))
- │ │ ├── pattern:
- │ │ │ @ RangeNode (location: (26,4)-(26,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── left: ∅
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (26,6)-(26,8))
- │ │ │ │ └── flags: decimal
- │ │ │ └── operator_loc: (26,4)-(26,6) = ".."
- │ │ ├── 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: ∅
- │ │ ├── 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,8))
- │ │ ├── pattern:
- │ │ │ @ RangeNode (location: (30,4)-(30,8))
- │ │ │ ├── flags: exclude_end
- │ │ │ ├── left:
- │ │ │ │ @ IntegerNode (location: (30,4)-(30,5))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── right: ∅
- │ │ │ └── operator_loc: (30,5)-(30,8) = "..."
- │ │ ├── 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: ∅
- │ │ ├── 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,9))
- │ │ ├── pattern:
- │ │ │ @ RangeNode (location: (34,4)-(34,9))
- │ │ │ ├── flags: exclude_end
- │ │ │ ├── left:
- │ │ │ │ @ IntegerNode (location: (34,4)-(34,5))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (34,8)-(34,9))
- │ │ │ │ └── flags: decimal
- │ │ │ └── operator_loc: (34,5)-(34,8) = "..."
- │ │ ├── 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: ∅
- │ │ ├── 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,6))
- │ │ ├── pattern:
- │ │ │ @ IntegerNode (location: (38,4)-(38,6))
- │ │ │ └── flags: decimal
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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]
- │ │ │ │ │ ├── locals_body_index: 1
- │ │ │ │ │ ├── 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))
- │ │ │ │ │ │ │ │ └── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: (106,5)-(106,6) = "\""
- │ │ │ │ │ ├── value_loc: (106,6)-(106,7) = "b"
- │ │ │ │ │ ├── closing_loc: (106,7)-(106,9) = "\":"
- │ │ │ │ │ └── unescaped: "b"
- │ │ │ │ ├── value: ∅
- │ │ │ │ └── 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: ∅
- │ ├── 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
deleted file mode 100644
index b33d5943fc..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_31.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 117b27503a..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_37.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 41f3094cd1..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_42.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index e144f1d13a..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_42_2.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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: ∅
- │ ├── 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
deleted file mode 100644
index b104d00224..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_47.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── opening_loc: (2,7)-(2,8) = ":"
- │ │ │ │ ├── value_loc: (2,8)-(2,9) = "b"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "b"
- │ │ │ └── @ SymbolNode (location: (2,11)-(2,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 4b6c2a2b17..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_67.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index cd11904371..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_86.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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: ∅
- │ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
- │ │ │ ├── value_loc: (1,7)-(1,8) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (1,10)-(1,12))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index f750ffa90c..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_86_2.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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: ∅
- │ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
- │ │ │ ├── value_loc: (1,7)-(1,8) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (1,10)-(1,12))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 9490477ab0..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 5d18d5fca7..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index e09f87f98e..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index c31a44d952..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_const.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 8e4cefe48d..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_else.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 37a264e273..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_find.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 757256d3fd..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_find_array.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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
deleted file mode 100644
index 50d7867c72..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_hash_pat.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 17136fd0bc..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (2,30)-(2,31) = "f"
- │ │ │ │ ├── closing_loc: (2,31)-(2,32) = ":"
- │ │ │ │ └── unescaped: "f"
- │ │ │ ├── value: ∅
- │ │ │ └── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 8c25711bfd..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index f062b23cbc..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index bfdfa90505..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 78f7840544..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 4292c1effa..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 60d48f0be4..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_multiple.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 26c26974da..0000000000
--- a/test/prism/snapshots/seattlerb/case_in_or.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 47e2043df6..0000000000
--- a/test/prism/snapshots/seattlerb/class_comments.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 0d112d7203..0000000000
--- a/test/prism/snapshots/seattlerb/cond_unary_minus.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 332c7ff302..0000000000
--- a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
deleted file mode 100644
index e7130cc1b3..0000000000
--- a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
deleted file mode 100644
index c4c5534f92..0000000000
--- a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-@ 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
- └── operator: :&
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
deleted file mode 100644
index ef9ee358b9..0000000000
--- a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
deleted file mode 100644
index 7afc8882e9..0000000000
--- a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/dasgn_icky2.txt b/test/prism/snapshots/seattlerb/dasgn_icky2.txt
deleted file mode 100644
index 83497a3c72..0000000000
--- a/test/prism/snapshots/seattlerb/dasgn_icky2.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-@ ProgramNode (location: (1,0)-(8,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(8,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(8,3))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index b03666c7e4..0000000000
--- a/test/prism/snapshots/seattlerb/defined_eh_parens.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 6adedb2395..0000000000
--- a/test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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))
- │ │ └── name: :interp
- │ ├── optionals: (length: 0)
- │ ├── rest:
- │ │ @ RestParameterNode (location: (1,17)-(1,18))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (1,17)-(1,18) = "*"
- │ ├── posts: (length: 1)
- │ │ └── @ RequiredParameterNode (location: (1,20)-(1,24))
- │ │ └── name: :args
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:interp, :*, :args]
- ├── locals_body_index: 3
- ├── 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
deleted file mode 100644
index 85f50a79ce..0000000000
--- a/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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))
- │ │ └── 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: ∅
- │ ├── 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, :"..."]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index e78a807e1c..0000000000
--- a/test/prism/snapshots/seattlerb/defn_args_forward_args.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-@ 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))
- │ │ │ └── name: :x
- │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ └── name: :y
- │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
- │ │ └── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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, :"..."]
- ├── locals_body_index: 4
- ├── 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
deleted file mode 100644
index bc4ba5462b..0000000000
--- a/test/prism/snapshots/seattlerb/defn_comments.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index f578856927..0000000000
--- a/test/prism/snapshots/seattlerb/defn_endless_command.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 3a1736771e..0000000000
--- a/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── keyword_loc: (1,34)-(1,40) = "rescue"
- │ └── rescue_expression:
- │ @ IntegerNode (location: (1,41)-(1,43))
- │ └── flags: decimal
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 2b0af43df0..0000000000
--- a/test/prism/snapshots/seattlerb/defn_forward_args.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- │ ├── 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: [:"..."]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index ad3c108dc2..0000000000
--- a/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- │ ├── 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: [:"..."]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index e562b6729b..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 18ead9e624..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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))
- │ │ └── name: :a
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 2)
- │ │ ├── @ OptionalKeywordParameterNode (location: (1,9)-(1,13))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,9)-(1,11) = "b:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,13))
- │ │ │ └── flags: decimal
- │ │ └── @ OptionalKeywordParameterNode (location: (1,15)-(1,19))
- │ │ ├── name: :c
- │ │ ├── name_loc: (1,15)-(1,17) = "c:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,18)-(1,19))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a, :b, :c]
- ├── locals_body_index: 3
- ├── 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
deleted file mode 100644
index a711c39305..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,6)-(1,8) = "b:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ └── flags: decimal
- │ ├── keyword_rest:
- │ │ @ KeywordRestParameterNode (location: (1,12)-(1,15))
- │ │ ├── name: :c
- │ │ ├── name_loc: (1,14)-(1,15) = "c"
- │ │ └── operator_loc: (1,12)-(1,14) = "**"
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:b, :c]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index f16cf144ad..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,6)-(1,8) = "b:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ └── flags: decimal
- │ ├── keyword_rest:
- │ │ @ KeywordRestParameterNode (location: (1,12)-(1,14))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (1,12)-(1,14) = "**"
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:b, :**]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index ad8d189fd1..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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))
- │ │ ├── name: :kw
- │ │ ├── name_loc: (1,8)-(1,11) = "kw:"
- │ │ └── value:
- │ │ @ SymbolNode (location: (1,12)-(1,16))
- │ │ ├── flags: ∅
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 9899f4360d..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ │ ├── name: :a
- │ │ ├── name_loc: (1,6)-(1,8) = "a:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,9)-(1,10))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index beca85c996..0000000000
--- a/test/prism/snapshots/seattlerb/defn_kwarg_val.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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))
- │ │ └── name: :a
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 1)
- │ │ └── @ OptionalKeywordParameterNode (location: (1,9)-(1,12))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,9)-(1,11) = "b:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,11)-(1,12))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a, :b]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 868fe3d202..0000000000
--- a/test/prism/snapshots/seattlerb/defn_no_kwargs.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 02e070dddd..0000000000
--- a/test/prism/snapshots/seattlerb/defn_oneliner.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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))
- │ │ └── 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: ∅
- │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 7252adaa93..0000000000
--- a/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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))
- │ │ │ └── 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
- │ ├── locals: [:o]
- │ ├── locals_body_index: 1
- │ ├── 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
deleted file mode 100644
index da1c11496e..0000000000
--- a/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :system
- │ ├── message_loc: (1,11)-(1,17) = "system"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 965d8b9bb3..0000000000
--- a/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :system
- │ ├── message_loc: (1,13)-(1,19) = "system"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index ad58ae383c..0000000000
--- a/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt
+++ /dev/null
@@ -1,158 +0,0 @@
-@ 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))
- │ │ │ └── name: :cmd
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (2,2)-(5,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (2,2)-(2,13))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (2,2)-(2,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ └── 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: ∅
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index fae68d5342..0000000000
--- a/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index aeff12d658..0000000000
--- a/test/prism/snapshots/seattlerb/defn_opt_reg.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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))
- │ │ ├── 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))
- │ │ └── name: :b
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a, :b]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 7ec94cf670..0000000000
--- a/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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))
- │ │ ├── name: :a
- │ │ ├── name_loc: (1,7)-(1,8) = "a"
- │ │ ├── operator_loc: (1,9)-(1,10) = "="
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,11)-(1,12))
- │ │ └── flags: decimal
- │ ├── rest:
- │ │ @ RestParameterNode (location: (1,14)-(1,16))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,15)-(1,16) = "b"
- │ │ └── operator_loc: (1,14)-(1,15) = "*"
- │ ├── posts: (length: 1)
- │ │ └── @ RequiredParameterNode (location: (1,18)-(1,19))
- │ │ └── name: :c
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a, :b, :c]
- ├── locals_body_index: 3
- ├── 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
deleted file mode 100644
index 1b0fbe656c..0000000000
--- a/test/prism/snapshots/seattlerb/defn_powarg.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ │ ├── name: :opts
- │ │ ├── name_loc: (1,8)-(1,12) = "opts"
- │ │ └── operator_loc: (1,6)-(1,8) = "**"
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:opts]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 6ef9635fb6..0000000000
--- a/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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))
- │ │ └── name: :a
- │ ├── optionals: (length: 1)
- │ │ └── @ OptionalParameterNode (location: (1,9)-(1,15))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,9)-(1,10) = "b"
- │ │ ├── operator_loc: (1,11)-(1,12) = "="
- │ │ └── value:
- │ │ @ SymbolNode (location: (1,13)-(1,15))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ │ └── name: :d
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a, :b, :d]
- ├── locals_body_index: 3
- ├── 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
deleted file mode 100644
index 453673f753..0000000000
--- a/test/prism/snapshots/seattlerb/defn_splat_arg.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (1,6)-(1,7) = "*"
- │ ├── posts: (length: 1)
- │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ └── name: :a
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:*, :a]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 9f3fc27171..0000000000
--- a/test/prism/snapshots/seattlerb/defn_unary_not.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 97ed2d542e..0000000000
--- a/test/prism/snapshots/seattlerb/defns_reserved.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 0e07d3e05c..0000000000
--- a/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,30))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,30))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,30))
- ├── flags: ∅
- ├── 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
- │ │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (1,18)-(1,20) = "do"
- │ │ └── closing_loc: (1,22)-(1,25) = "end"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index a25b50614d..0000000000
--- a/test/prism/snapshots/seattlerb/defs_comments.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index b9d926662a..0000000000
--- a/test/prism/snapshots/seattlerb/defs_endless_command.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 0ac0ca2479..0000000000
--- a/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── keyword_loc: (1,36)-(1,42) = "rescue"
- │ └── rescue_expression:
- │ @ IntegerNode (location: (1,43)-(1,45))
- │ └── flags: decimal
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 9c42a36282..0000000000
--- a/test/prism/snapshots/seattlerb/defs_kwarg.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,11)-(1,13) = "b:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,14)-(1,15))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:b]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index e7f981c895..0000000000
--- a/test/prism/snapshots/seattlerb/defs_oneliner.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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))
- │ │ └── 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: ∅
- │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index ffbb6befd8..0000000000
--- a/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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))
- │ │ │ └── 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
- │ ├── locals: [:o]
- │ ├── locals_body_index: 1
- │ ├── 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
deleted file mode 100644
index e5acf45e76..0000000000
--- a/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt
+++ /dev/null
@@ -1,161 +0,0 @@
-@ 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))
- │ │ │ └── name: :cmd
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (2,2)-(5,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (2,2)-(2,13))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (2,2)-(2,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ └── 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: ∅
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index d5b6a87c1e..0000000000
--- a/test/prism/snapshots/seattlerb/difficult0_.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,8))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(4,8))
- ├── flags: ∅
- ├── 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))
- │ │ │ ├── opening_loc: (1,9)-(1,10) = "'"
- │ │ │ ├── parts: (length: 2)
- │ │ │ │ ├── @ StringNode (location: (1,10)-(2,0))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── content_loc: (1,10)-(2,0) = "b\n"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "b\n"
- │ │ │ │ └── @ StringNode (location: (4,0)-(4,3))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
deleted file mode 100644
index 646a365ef0..0000000000
--- a/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt
+++ /dev/null
@@ -1,253 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (3,2)-(3,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (3,2)-(3,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (4,2)-(4,10))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (4,2)-(4,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (4,9)-(4,10))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (5,2)-(5,7))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (5,2)-(5,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (6,2)-(6,10))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (6,2)-(6,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (6,9)-(6,10))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (7,2)-(7,6))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: (7,5)-(7,6) = ")"
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (8,2)-(8,8))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (8,2)-(8,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ ├── closing_loc: (8,7)-(8,8) = ")"
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (9,2)-(9,11))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (9,2)-(9,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (9,9)-(9,10))
- │ │ │ └── flags: decimal
- │ │ ├── closing_loc: (9,10)-(9,11) = ")"
- │ │ └── block: ∅
- │ ├── @ CallNode (location: (10,2)-(10,8))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ CallNode (location: (10,2)-(10,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ ├── closing_loc: (10,7)-(10,8) = ")"
- │ │ └── block: ∅
- │ └── @ CallNode (location: (11,2)-(11,11))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (11,2)-(11,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (11,9)-(11,10))
- │ │ └── flags: decimal
- │ ├── 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
deleted file mode 100644
index 4d23cd5efe..0000000000
--- a/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ │ └── operator_loc: (3,4)-(3,5) = "="
- │ │ ├── @ CallNode (location: (4,2)-(4,5))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (5,4)-(5,5) = "="
- │ ├── consequent: ∅
- │ └── end_keyword_loc: (6,0)-(6,3) = "end"
- └── @ CallNode (location: (7,0)-(7,1))
- ├── flags: variable_call
- ├── 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
deleted file mode 100644
index a81b0ce458..0000000000
--- a/test/prism/snapshots/seattlerb/difficult2_.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-@ 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
- │ ├── then_keyword_loc: (1,2)-(1,3) = "?"
- │ ├── statements:
- │ │ @ StatementsNode (location: (1,4)-(1,9))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (1,4)-(1,9))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ └── end_keyword_loc: ∅
- │ └── end_keyword_loc: ∅
- └── @ CallNode (location: (2,0)-(2,6))
- ├── flags: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (2,2)-(2,6))
- │ ├── key:
- │ │ @ SymbolNode (location: (2,2)-(2,4))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── operator_loc: ∅
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult3_.txt b/test/prism/snapshots/seattlerb/difficult3_.txt
deleted file mode 100644
index 6a6306c01b..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3_.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,16))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,15))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,15))
- │ │ │ ├── lefts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── name: :b
- │ │ │ ├── rest:
- │ │ │ │ @ SplatNode (location: (1,12)-(1,14))
- │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*"
- │ │ │ │ └── expression:
- │ │ │ │ @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ │ └── 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
deleted file mode 100644
index 753217ca40..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3_2.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,6)-(1,7) = "a"
- │ │ │ └── operator_loc: (1,5)-(1,6) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ └── 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
deleted file mode 100644
index eb2e1baf07..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3_3.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,6)-(1,7) = "a"
- │ │ │ └── operator_loc: (1,5)-(1,6) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ └── name: :b
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,12)-(1,14))
- │ │ ├── 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
deleted file mode 100644
index a8be0694c9..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3_4.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index c9fa99bf61..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3_5.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,19))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,19))
- ├── flags: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 8b972ebd6f..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__10.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,16))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,15))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── 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))
- │ │ │ │ └── name: :b
- │ │ │ ├── rights: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ │ └── 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
deleted file mode 100644
index 11652bba93..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__11.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,12))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,11))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── 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
deleted file mode 100644
index 388fdc8335..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__12.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,15))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,14))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index 960aec5da9..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__6.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,21))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,21))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,21))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,19))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,18))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,18))
- │ │ │ ├── lefts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── name: :b
- │ │ │ ├── rest:
- │ │ │ │ @ SplatNode (location: (1,12)-(1,14))
- │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*"
- │ │ │ │ └── expression:
- │ │ │ │ @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ │ └── name: :c
- │ │ │ ├── rights: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,16)-(1,17))
- │ │ │ │ └── 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
deleted file mode 100644
index 8fdc3f4a90..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__7.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,15))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,14))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,14))
- │ │ │ ├── lefts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── 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
deleted file mode 100644
index 4d18fd9453..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__8.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,18))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,17))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,17))
- │ │ │ ├── lefts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index 97de361cb7..0000000000
--- a/test/prism/snapshots/seattlerb/difficult3__9.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,13))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,12))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index f340c624d9..0000000000
--- a/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index c5868e193c..0000000000
--- a/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- └── @ RangeNode (location: (2,0)-(2,3))
- ├── flags: ∅
- ├── left: ∅
- ├── right:
- │ @ IntegerNode (location: (2,2)-(2,3))
- │ └── flags: decimal
- └── operator_loc: (2,0)-(2,2) = ".."
diff --git a/test/prism/snapshots/seattlerb/difficult6_.txt b/test/prism/snapshots/seattlerb/difficult6_.txt
deleted file mode 100644
index a99969f51a..0000000000
--- a/test/prism/snapshots/seattlerb/difficult6_.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,11))
- │ │ │ ├── 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: ∅
- ├── 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
deleted file mode 100644
index ce48b01a4c..0000000000
--- a/test/prism/snapshots/seattlerb/difficult6__7.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── opening_loc: (1,4)-(1,5) = "("
- │ └── closing_loc: (1,6)-(1,7) = ")"
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (1,8)-(1,11))
- ├── locals: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,9)-(1,10))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,9)-(1,10))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index 22b3c3cec3..0000000000
--- a/test/prism/snapshots/seattlerb/difficult6__8.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── opening_loc: (1,5)-(1,6) = "("
- │ └── closing_loc: (1,7)-(1,8) = ")"
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (1,9)-(1,12))
- ├── locals: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,10)-(1,11))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,10)-(1,11))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index 28c3753aed..0000000000
--- a/test/prism/snapshots/seattlerb/difficult7_.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index be64a43e0d..0000000000
--- a/test/prism/snapshots/seattlerb/do_bug.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,3))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,3))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- └── @ CallNode (location: (2,0)-(4,3))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (2,0)-(2,1))
- │ ├── flags: variable_call
- │ ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (2,7)-(2,10))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (2,8)-(2,9))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (2,8)-(2,9))
- │ │ │ └── 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
deleted file mode 100644
index 9de71cea2d..0000000000
--- a/test/prism/snapshots/seattlerb/do_lambda.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,11))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,11))
- └── body: (length: 1)
- └── @ LambdaNode (location: (1,0)-(1,11))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 0d73215bc2..0000000000
--- a/test/prism/snapshots/seattlerb/dot2_nil__26.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 94c873dbb8..0000000000
--- a/test/prism/snapshots/seattlerb/dot3_nil__26.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 4c48657914..0000000000
--- a/test/prism/snapshots/seattlerb/dstr_evstr.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,12))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,12))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,12))
- ├── 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
- │ │ ├── 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
deleted file mode 100644
index 65be266f20..0000000000
--- a/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index cc2c07a027..0000000000
--- a/test/prism/snapshots/seattlerb/dstr_lex_state.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,8))
- ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 42bd37a1ac..0000000000
--- a/test/prism/snapshots/seattlerb/dstr_str.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,10))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,10))
- ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index e3da9c4a9a..0000000000
--- a/test/prism/snapshots/seattlerb/dsym_esc_to_sym.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,17))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,17))
- └── body: (length: 1)
- └── @ SymbolNode (location: (1,0)-(1,17))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 92ca039207..0000000000
--- a/test/prism/snapshots/seattlerb/dsym_to_sym.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── opening_loc: (3,6)-(3,7) = ":"
- │ ├── value_loc: (3,7)-(3,9) = "<<"
- │ ├── closing_loc: ∅
- │ └── unescaped: "<<"
- ├── old_name:
- │ @ SymbolNode (location: (3,10)-(3,13))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 1fd43f6166..0000000000
--- a/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-@ 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
- └── @ IntegerNode (location: (6,0)-(6,1))
- └── flags: decimal
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
deleted file mode 100644
index 545f29a532..0000000000
--- a/test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 25be925826..0000000000
--- a/test/prism/snapshots/seattlerb/evstr_evstr.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,10))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,10))
- ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 535881f353..0000000000
--- a/test/prism/snapshots/seattlerb/evstr_str.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,8))
- ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index dab908c1ee..0000000000
--- a/test/prism/snapshots/seattlerb/expr_not_bang.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 3f4d6d6981..0000000000
--- a/test/prism/snapshots/seattlerb/f_kw.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ │ ├── name: :k
- │ │ ├── name_loc: (1,6)-(1,8) = "k:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,8)-(1,10))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:k]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 61fe5edbae..0000000000
--- a/test/prism/snapshots/seattlerb/f_kw__required.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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))
- │ │ ├── name: :k
- │ │ └── name_loc: (1,6)-(1,8) = "k:"
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:k]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index fe3592fd0b..0000000000
--- a/test/prism/snapshots/seattlerb/flip2_env_lvar.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 5cf12848c4..0000000000
--- a/test/prism/snapshots/seattlerb/float_with_if_modifier.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-@ 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))
- ├── 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
deleted file mode 100644
index 6ba437e36a..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc__backslash_dos_format.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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\r\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
deleted file mode 100644
index fc4c1784fe..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_backslash_nl.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 2b1d776404..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 7a01f8d6d1..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_bad_oct_escape.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 888ebc809a..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_comma_arg.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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
deleted file mode 100644
index eb632218a4..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_lineno.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- └── operator_loc: (7,2)-(7,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_nested.txt b/test/prism/snapshots/seattlerb/heredoc_nested.txt
deleted file mode 100644
index fde81dd586..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_nested.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (2,6)-(3,0) = "\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "\n"
- │ │ │ └── @ StringNode (location: (5,0)-(6,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- ├── 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
deleted file mode 100644
index 48f830befa..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ ├── opening_loc: (1,4)-(1,12) = "<<~\"EOF\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "x\n"
- │ │ ├── @ StringNode (location: (3,0)-(4,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (3,0)-(4,0) = " y\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "y\n"
- │ │ └── @ StringNode (location: (4,0)-(5,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index e12caf2895..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-@ 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: ∅
- │ ├── 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))
- │ │ │ ├── opening_loc: (1,8)-(1,14) = "<<~EOF"
- │ │ │ ├── parts: (length: 3)
- │ │ │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
deleted file mode 100644
index 533f8ac460..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ ├── opening_loc: (1,4)-(1,10) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "x\n"
- │ │ ├── @ StringNode (location: (3,0)-(4,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (3,0)-(4,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (4,0)-(5,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index c998f19984..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_empty.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 8602ed3731..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_interp.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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))
- │ ├── opening_loc: (1,4)-(1,10) = "<<~EOF"
- │ ├── parts: (length: 5)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (2,0)-(3,0) = " w\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: " w\n"
- │ │ ├── @ StringNode (location: (3,0)-(3,3))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (3,7)-(3,8) = "}"
- │ │ ├── @ StringNode (location: (3,8)-(4,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (3,8)-(4,0) = " y\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: " y\n"
- │ │ └── @ StringNode (location: (4,0)-(5,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 7c17bc4820..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_no_indent.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 8a0581917d..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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))
- │ ├── opening_loc: (1,4)-(1,12) = "<<~\"EOF\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (2,0)-(3,0) = " blah blah\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "blah blah\n"
- │ │ └── @ StringNode (location: (3,0)-(4,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index af85f11e68..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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))
- │ ├── opening_loc: (1,4)-(1,12) = "<<~\"EOF\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (2,0)-(3,0) = " blah blah\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "blah blah\n"
- │ │ └── @ StringNode (location: (3,0)-(4,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 3cba13a968..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ ├── opening_loc: (1,4)-(1,10) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "x\n"
- │ │ ├── @ StringNode (location: (3,0)-(4,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (3,0)-(4,0) = " \n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (4,0)-(5,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index bc05047b40..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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
deleted file mode 100644
index 2c72854324..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_unicode.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 43bb8d5ea8..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 21802c5707..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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\r\nbaz\r\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
deleted file mode 100644
index dca03e71b0..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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\r\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
deleted file mode 100644
index 93fa1a1687..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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\r\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
deleted file mode 100644
index 98b6e3fe11..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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\r\nbaz\r\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
deleted file mode 100644
index 0067e49809..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,5))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,5))
- ├── opening_loc: (1,0)-(1,5) = "<<EOS"
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (2,0)-(2,5))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index dc8f8ae6d6..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,5))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,5))
- ├── opening_loc: (1,0)-(1,5) = "<<EOS"
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (2,0)-(2,5))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── opening_loc: ∅
- │ ├── content_loc: (2,10)-(3,0) = "\r\n"
- │ ├── closing_loc: ∅
- │ └── unescaped: "\r\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
deleted file mode 100644
index 6e1648f659..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 6771f4afd7..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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: "\r\n\r\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
deleted file mode 100644
index b0f5d369dc..0000000000
--- a/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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\r\n\r\r\r\n\r\r\n"
diff --git a/test/prism/snapshots/seattlerb/if_elsif.txt b/test/prism/snapshots/seattlerb/if_elsif.txt
deleted file mode 100644
index 8ce1864e76..0000000000
--- a/test/prism/snapshots/seattlerb/if_elsif.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-@ 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
- ├── 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
- │ ├── 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
deleted file mode 100644
index 65558b2e9b..0000000000
--- a/test/prism/snapshots/seattlerb/if_symbol.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 0a026c08db..0000000000
--- a/test/prism/snapshots/seattlerb/in_expr_no_case.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 38a7d5d5c9..0000000000
--- a/test/prism/snapshots/seattlerb/index_0.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index d43bdceb71..0000000000
--- a/test/prism/snapshots/seattlerb/index_0_opasgn.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 7e0c8a2365..0000000000
--- a/test/prism/snapshots/seattlerb/integer_with_if_modifier.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index f196555770..0000000000
--- a/test/prism/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (2,0)-(2,1) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (3,0)-(3,1))
- │ │ ├── flags: ∅
- │ │ ├── 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
diff --git a/test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt b/test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt
deleted file mode 100644
index bc28bf8574..0000000000
--- a/test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/iter_args_1.txt b/test/prism/snapshots/seattlerb/iter_args_1.txt
deleted file mode 100644
index 0a296a66cd..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_1.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,9))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,8))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ └── @ RequiredParameterNode (location: (1,7)-(1,8))
- │ │ │ └── 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
deleted file mode 100644
index 8bccaacefd..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_10_1.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,21))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,21))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,21))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,19))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,18))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
- │ │ │ ├── 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
deleted file mode 100644
index 08eacad4aa..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_10_2.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,25))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,25))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,25))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,23))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,22))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
- │ │ │ ├── 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))
- │ │ ├── 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
deleted file mode 100644
index e4c0a21997..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_11_1.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,24))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,24))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,24))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,22))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,21))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,17)-(1,18) = "c"
- │ │ │ └── operator_loc: (1,16)-(1,17) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,20)-(1,21))
- │ │ │ └── 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
deleted file mode 100644
index 369075ca3c..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_11_2.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 5
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,26))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,25))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,14))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,17)-(1,18) = "c"
- │ │ │ └── operator_loc: (1,16)-(1,17) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,20)-(1,21))
- │ │ │ └── name: :d
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,23)-(1,25))
- │ │ ├── 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
deleted file mode 100644
index 9934cc4349..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_2__19.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── 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
deleted file mode 100644
index abd2eec189..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_3.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,18))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,17))
- │ │ ├── requireds: (length: 3)
- │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ │ └── name: :a
- │ │ │ ├── @ MultiTargetNode (location: (1,8)-(1,14))
- │ │ │ │ ├── lefts: (length: 2)
- │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ │ │ └── name: :b
- │ │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
- │ │ │ │ │ └── name: :c
- │ │ │ │ ├── rest: ∅
- │ │ │ │ ├── rights: (length: 0)
- │ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
- │ │ │ │ └── rparen_loc: (1,13)-(1,14) = ")"
- │ │ │ └── @ RequiredParameterNode (location: (1,16)-(1,17))
- │ │ │ └── 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
deleted file mode 100644
index 8a64bdb1f8..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_4.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,14))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,13))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,8)-(1,10))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,9)-(1,10) = "b"
- │ │ │ └── operator_loc: (1,8)-(1,9) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
- │ │ │ └── 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
deleted file mode 100644
index 0aaf2c47b2..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_5.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,11))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,10))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,8)-(1,10))
- │ │ ├── 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
deleted file mode 100644
index cc8a4f72eb..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_6.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── parameters:
- │ @ BlockParametersNode (location: (1,4)-(1,16))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,5)-(1,15))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,12))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
- │ │ │ ├── operator_loc: (1,9)-(1,10) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,10)-(1,12))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
- │ │ │ └── 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
deleted file mode 100644
index 5deb0d55be..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_7_1.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
- │ │ │ ├── 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
deleted file mode 100644
index fc49660153..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_7_2.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,22))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,22))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
- │ │ │ ├── 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))
- │ │ ├── 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
deleted file mode 100644
index aec251bffb..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_8_1.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,21))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,21))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,21))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,14)-(1,15) = "b"
- │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
- │ │ │ └── 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
deleted file mode 100644
index f1f925dd86..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_8_2.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,25))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,25))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,25))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 4
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,14)-(1,15) = "b"
- │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
- │ │ │ └── name: :c
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,20)-(1,22))
- │ │ ├── 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
deleted file mode 100644
index 1fc22f1043..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_9_1.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ └── 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
deleted file mode 100644
index 6a18271ba2..0000000000
--- a/test/prism/snapshots/seattlerb/iter_args_9_2.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,21))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,21))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,21))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ ├── name: :a
- │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,9)-(1,11))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
- │ │ │ └── name: :b
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,16)-(1,18))
- │ │ ├── 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
deleted file mode 100644
index d1f71bfd08..0000000000
--- a/test/prism/snapshots/seattlerb/iter_kwarg.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,7) = "b:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,8)-(1,9))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index 6b85b3858e..0000000000
--- a/test/prism/snapshots/seattlerb/iter_kwarg_kwsplat.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (1,5)-(1,7) = "b:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,8)-(1,9))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest:
- │ │ │ @ KeywordRestParameterNode (location: (1,11)-(1,14))
- │ │ │ ├── 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
deleted file mode 100644
index a0832d8a47..0000000000
--- a/test/prism/snapshots/seattlerb/label_vs_string.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index e451aca510..0000000000
--- a/test/prism/snapshots/seattlerb/lambda_do_vs_brace.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,9))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,9))
- └── body: (length: 4)
- ├── @ CallNode (location: (1,0)-(1,11))
- │ ├── flags: ∅
- │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index b1c234bff2..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_arg_rescue_arg.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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
- │ ├── keyword_loc: (1,6)-(1,12) = "rescue"
- │ └── rescue_expression:
- │ @ IntegerNode (location: (1,13)-(1,14))
- │ └── flags: decimal
- └── 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
deleted file mode 100644
index fe18d5ad49..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: (1,7)-(1,8) = ")"
- │ │ └── block: ∅
- │ ├── keyword_loc: (1,9)-(1,15) = "rescue"
- │ └── rescue_expression:
- │ @ IntegerNode (location: (1,16)-(1,17))
- │ └── flags: decimal
- └── 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
deleted file mode 100644
index 637451a550..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── keyword_loc: (1,8)-(1,14) = "rescue"
- │ └── rescue_expression:
- │ @ IntegerNode (location: (1,15)-(1,16))
- │ └── flags: decimal
- └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_command.txt b/test/prism/snapshots/seattlerb/lasgn_command.txt
deleted file mode 100644
index 4b38e56028..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_command.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 33539a6918..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_env.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
- └── 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
deleted file mode 100644
index e37a331d51..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_ivar_env.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── 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
deleted file mode 100644
index 8d6662ae0d..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_lasgn_command_call.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 076c4ec89d..0000000000
--- a/test/prism/snapshots/seattlerb/lasgn_middle_splat.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index ce6e432133..0000000000
--- a/test/prism/snapshots/seattlerb/magic_encoding_comment.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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ì]
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index f1f07d2908..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_anon_splat_arg.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index cf893a9bc5..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_arg_colon_arg.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 8cd088f034..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_arg_ident.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 3d756144c5..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_arg_splat_arg.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 5a5b5e67db..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_colon2.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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
- │ │ ├── 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
- │ └── @ IntegerNode (location: (1,13)-(1,14))
- │ └── flags: decimal
- ├── opening_loc: ∅
- └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_colon3.txt b/test/prism/snapshots/seattlerb/masgn_colon3.txt
deleted file mode 100644
index f2880a4426..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_colon3.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ └── @ IntegerNode (location: (1,14)-(1,15))
- │ └── flags: decimal
- ├── opening_loc: ∅
- └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_command_call.txt b/test/prism/snapshots/seattlerb/masgn_command_call.txt
deleted file mode 100644
index 974910101b..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_command_call.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_double_paren.txt b/test/prism/snapshots/seattlerb/masgn_double_paren.txt
deleted file mode 100644
index 900e8e0f14..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_double_paren.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 7615d7d02b..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_lhs_splat.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── @ IntegerNode (location: (1,8)-(1,9))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (1,11)-(1,12))
- │ └── flags: decimal
- ├── opening_loc: ∅
- └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_paren.txt b/test/prism/snapshots/seattlerb/masgn_paren.txt
deleted file mode 100644
index 610f6ba2e4..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_paren.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 0d2d782bf1..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_splat_arg.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index be9e1324f8..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_splat_arg_arg.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 22783c909d..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_star.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/masgn_var_star_var.txt b/test/prism/snapshots/seattlerb/masgn_var_star_var.txt
deleted file mode 100644
index 0833b44d6b..0000000000
--- a/test/prism/snapshots/seattlerb/masgn_var_star_var.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index d15cf6fcbc..0000000000
--- a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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
deleted file mode 100644
index e9eeb336e5..0000000000
--- a/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── 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:
- │ │ @ IntegerNode (location: (1,7)-(1,8))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index aea6bc7de1..0000000000
--- a/test/prism/snapshots/seattlerb/method_call_trailing_comma.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 0bf5baefd5..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_back_anonsplat.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 2051bb832b..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_back_splat.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index fbe7480d50..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_front_anonsplat.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 6585289d54..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_front_splat.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index d7033a5203..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_keyword.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index a2aad9a335..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_mid_anonsplat.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 10a0a23917..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_mid_splat.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 9885ab4c78..0000000000
--- a/test/prism/snapshots/seattlerb/mlhs_rescue.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ ├── 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
diff --git a/test/prism/snapshots/seattlerb/module_comments.txt b/test/prism/snapshots/seattlerb/module_comments.txt
deleted file mode 100644
index 8e8b2fd9cc..0000000000
--- a/test/prism/snapshots/seattlerb/module_comments.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index efa6fa242d..0000000000
--- a/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-@ ProgramNode (location: (1,0)-(8,12))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(8,12))
- └── body: (length: 3)
- ├── @ CallNode (location: (1,0)-(3,2))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,2)-(3,1))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,2)-(1,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (5,2)-(6,1))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (5,2)-(5,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (8,2)-(8,11))
- │ ├── key:
- │ │ @ SymbolNode (location: (8,2)-(8,8))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 08dce249af..0000000000
--- a/test/prism/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (2,0)-(2,1) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (3,0)-(3,1))
- │ │ ├── flags: ∅
- │ │ ├── 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
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
deleted file mode 100644
index 705ab476d6..0000000000
--- a/test/prism/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/op_asgn_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_command_call.txt
deleted file mode 100644
index ae82ec31cd..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_command_call.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index f25e6328be..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- ├── 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
- ├── 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
deleted file mode 100644
index 03b8811fc1..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_index_command_call.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ ├── 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: ∅
- ├── 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
- │ └── @ IntegerNode (location: (1,15)-(1,16))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index f17ca505da..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 0416e0fa71..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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
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
deleted file mode 100644
index 0fbbe197c7..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index afd48a88f8..0000000000
--- a/test/prism/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── 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: ∅
- ├── 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
- ├── 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
deleted file mode 100644
index 1373229932..0000000000
--- a/test/prism/snapshots/seattlerb/parse_def_special_name.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 10f788a271..0000000000
--- a/test/prism/snapshots/seattlerb/parse_if_not_canonical.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-@ 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
- │ │ │ ├── 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
deleted file mode 100644
index 10f788a271..0000000000
--- a/test/prism/snapshots/seattlerb/parse_if_not_noncanonical.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-@ 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
- │ │ │ ├── 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
deleted file mode 100644
index ba579a280a..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_block.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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
- │ └── operator_loc: (1,2)-(1,3) = "="
- └── @ CallNode (location: (2,0)-(2,3))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 5b4c006eff..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_block_inline_comment.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index ddabbe84e4..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 7a55397bac..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 991e3a1685..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index 15af12fe83..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index 8a07a8912c..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_call_no_args.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(3,3))
- ├── flags: ∅
- ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,5)-(1,11))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,6)-(1,10))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7))
- │ │ │ │ └── name: :x
- │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ └── 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
deleted file mode 100644
index 0ec63b3123..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-@ 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))
- │ │ └── 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: ∅
- │ │ ├── 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
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index e9d68521e4..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_defn_no_parens.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 8a0a1c752a..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_defn_no_parens_args.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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))
- │ │ └── name: :a
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 960369cfa5..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_dot2.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ ├── right:
- │ │ @ IntegerNode (location: (2,0)-(2,1))
- │ │ └── flags: decimal
- │ └── operator_loc: (1,1)-(1,3) = ".."
- ├── @ RangeNode (location: (3,0)-(4,1))
- │ ├── flags: ∅
- │ ├── left:
- │ │ @ CallNode (location: (3,0)-(3,1))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 986f57136e..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_dot2_open.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- │ ├── right: ∅
- │ └── operator_loc: (1,1)-(1,3) = ".."
- ├── @ RangeNode (location: (2,2)-(2,5))
- │ ├── flags: ∅
- │ ├── left:
- │ │ @ CallNode (location: (2,2)-(2,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 791618812d..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_dot3.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ ├── right:
- │ │ @ IntegerNode (location: (2,0)-(2,1))
- │ │ └── flags: decimal
- │ └── 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
- │ │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 49ce1b0bae..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_dot3_open.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index e135d31a25..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,4))
- └── body: (length: 2)
- ├── @ InterpolatedStringNode (location: (1,0)-(2,2))
- │ ├── opening_loc: (1,0)-(1,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (1,1)-(1,4))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 4415cbcc1b..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_dstr_soft_newline.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,4))
- └── body: (length: 2)
- ├── @ InterpolatedStringNode (location: (1,0)-(3,2))
- │ ├── opening_loc: (1,0)-(1,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (1,1)-(2,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 9a6cbfdb65..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_evstr_after_break.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ ProgramNode (location: (1,0)-(2,6))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(2,6))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(2,6))
- ├── opening_loc: ∅
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (1,0)-(1,3))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index 17aa26bda7..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_hash_lit.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 2b52a3b6fb..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_heredoc.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index 0a96830a65..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_heredoc_evstr.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,4))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,4))
- ├── opening_loc: (1,0)-(1,4) = "<<-A"
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index ad0f0dfd99..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
deleted file mode 100644
index c762376f14..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index a22d252918..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_iter_call_no_parens.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(3,3))
- ├── flags: ∅
- ├── 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
- │ ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,7)-(1,13))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,8)-(1,12))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,8)-(1,9))
- │ │ │ │ └── name: :x
- │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
- │ │ │ └── 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
deleted file mode 100644
index e9a7b0140d..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_iter_call_parens.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(3,3))
- ├── flags: ∅
- ├── 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
- │ ├── 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]
- ├── locals_body_index: 2
- ├── parameters:
- │ @ BlockParametersNode (location: (1,8)-(1,14))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,9)-(1,13))
- │ │ ├── requireds: (length: 2)
- │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ │ └── name: :x
- │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
- │ │ │ └── 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
deleted file mode 100644
index fa8c491047..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_multiline_str.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
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
deleted file mode 100644
index c72b516baa..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/parse_line_newlines.txt b/test/prism/snapshots/seattlerb/parse_line_newlines.txt
deleted file mode 100644
index 3e1ceef586..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_newlines.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 63d52a477d..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 3a5e0f084e..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_postexe.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 71ca121314..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_preexe.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index a13ef4357d..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_rescue.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index fc83061d01..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_return.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── consequent: ∅
- │ └── end_keyword_loc: (4,8)-(4,11) = "end"
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index ee1fa91116..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_str_with_newline_escape.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index c0a7a6f631..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_to_ary.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 355a0da11c..0000000000
--- a/test/prism/snapshots/seattlerb/parse_line_trailing_newlines.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 310507d26a..0000000000
--- a/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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
- ├── 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:
- │ │ @ IntegerNode (location: (1,5)-(1,6))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index c1d086d5f3..0000000000
--- a/test/prism/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- ├── 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
- ├── 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
deleted file mode 100644
index 2ba406f186..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_019.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- ├── 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
- │ │ ├── right:
- │ │ │ @ IntegerNode (location: (2,7)-(2,8))
- │ │ │ └── flags: decimal
- │ │ └── 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
deleted file mode 100644
index 1eeb954839..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_044.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 6ae0944d10..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_051.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ │ ├── @ IntegerNode (location: (1,9)-(1,10))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (1,12)-(1,13))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ │ └── @ IntegerNode (location: (2,7)-(2,8))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index d372ece2d4..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_058.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (2,4)-(2,5) = "a"
- │ │ │ │ ├── closing_loc: (2,5)-(2,6) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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
deleted file mode 100644
index b75b198907..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_058_2.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (2,4)-(2,5) = "a"
- │ │ │ │ ├── closing_loc: (2,5)-(2,6) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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
deleted file mode 100644
index b5cd94cd77..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_069.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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
- │ ├── 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
deleted file mode 100644
index 8f4ef571c7..0000000000
--- a/test/prism/snapshots/seattlerb/parse_pattern_076.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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
deleted file mode 100644
index 71002ef207..0000000000
--- a/test/prism/snapshots/seattlerb/parse_until_not_canonical.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ │ ├── 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
deleted file mode 100644
index 71002ef207..0000000000
--- a/test/prism/snapshots/seattlerb/parse_until_not_noncanonical.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ │ ├── 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
deleted file mode 100644
index 973d32fe39..0000000000
--- a/test/prism/snapshots/seattlerb/parse_while_not_canonical.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ │ ├── 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
deleted file mode 100644
index 973d32fe39..0000000000
--- a/test/prism/snapshots/seattlerb/parse_while_not_noncanonical.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ │ ├── 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
deleted file mode 100644
index 58efa9c59a..0000000000
--- a/test/prism/snapshots/seattlerb/pctW_lineno.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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
deleted file mode 100644
index 31cc0941ee..0000000000
--- a/test/prism/snapshots/seattlerb/pct_Q_backslash_nl.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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: " \\\n"
diff --git a/test/prism/snapshots/seattlerb/pct_nl.txt b/test/prism/snapshots/seattlerb/pct_nl.txt
deleted file mode 100644
index 1009fcb51d..0000000000
--- a/test/prism/snapshots/seattlerb/pct_nl.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 946f08bc3c..0000000000
--- a/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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))
- │ │ ├── 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
deleted file mode 100644
index 3b611021c8..0000000000
--- a/test/prism/snapshots/seattlerb/pipe_semicolon.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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
- │ ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,7)-(1,14))
- │ ├── parameters: ∅
- │ ├── locals: (length: 1)
- │ │ └── @ BlockLocalVariableNode (location: (1,11)-(1,12))
- │ │ └── 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
deleted file mode 100644
index c791d2b117..0000000000
--- a/test/prism/snapshots/seattlerb/pipe_space.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 95ae6d4075..0000000000
--- a/test/prism/snapshots/seattlerb/qWords_space.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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
deleted file mode 100644
index ff04f9a650..0000000000
--- a/test/prism/snapshots/seattlerb/qsymbols.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,3)-(1,4) = "a"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "a"
- │ ├── @ SymbolNode (location: (1,5)-(1,6))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,5)-(1,6) = "b"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "b"
- │ └── @ SymbolNode (location: (1,7)-(1,8))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 54aa3f77d7..0000000000
--- a/test/prism/snapshots/seattlerb/qsymbols_empty.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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
deleted file mode 100644
index 624b922ce6..0000000000
--- a/test/prism/snapshots/seattlerb/qsymbols_empty_space.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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
deleted file mode 100644
index 16b9f7c845..0000000000
--- a/test/prism/snapshots/seattlerb/qsymbols_interp.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ └── closing_loc: (1,11)-(1,12) = "}"
- │ │ └── closing_loc: ∅
- │ └── @ SymbolNode (location: (1,13)-(1,14))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 59bd8f0220..0000000000
--- a/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,5)-(1,12))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,5)-(1,9))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 1e28bb61cb..0000000000
--- a/test/prism/snapshots/seattlerb/quoted_symbol_keys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index d92c1da7a6..0000000000
--- a/test/prism/snapshots/seattlerb/qw_escape.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index e935b7eb68..0000000000
--- a/test/prism/snapshots/seattlerb/qw_escape_term.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index f9915c97c9..0000000000
--- a/test/prism/snapshots/seattlerb/qwords_empty.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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
deleted file mode 100644
index 3ea5604b69..0000000000
--- a/test/prism/snapshots/seattlerb/read_escape_unicode_curlies.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 1eba1396fd..0000000000
--- a/test/prism/snapshots/seattlerb/read_escape_unicode_h4.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index abe17918e5..0000000000
--- a/test/prism/snapshots/seattlerb/regexp.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ ProgramNode (location: (1,0)-(9,13))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(9,13))
- └── body: (length: 5)
- ├── @ RegularExpressionNode (location: (1,0)-(1,5))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index b6bf242612..0000000000
--- a/test/prism/snapshots/seattlerb/regexp_esc_C_slash.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,7))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,7))
- └── body: (length: 1)
- └── @ RegularExpressionNode (location: (1,0)-(1,7))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 7b1ebdc636..0000000000
--- a/test/prism/snapshots/seattlerb/regexp_esc_u.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,17))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,17))
- └── body: (length: 1)
- └── @ RegularExpressionNode (location: (1,0)-(1,17))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 6568d2bd92..0000000000
--- a/test/prism/snapshots/seattlerb/regexp_escape_extended.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 8dd265af5f..0000000000
--- a/test/prism/snapshots/seattlerb/regexp_unicode_curlies.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,8))
- └── body: (length: 2)
- ├── @ RegularExpressionNode (location: (1,0)-(1,15))
- │ ├── flags: ∅
- │ ├── 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: ∅
- ├── 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
deleted file mode 100644
index fe2ce0bc7e..0000000000
--- a/test/prism/snapshots/seattlerb/required_kwarg_no_value.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ │ │ ├── name: :a
- │ │ │ └── name_loc: (1,6)-(1,8) = "a:"
- │ │ └── @ RequiredKeywordParameterNode (location: (1,10)-(1,12))
- │ │ ├── name: :b
- │ │ └── name_loc: (1,10)-(1,12) = "b:"
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:a, :b]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 9640b4d060..0000000000
--- a/test/prism/snapshots/seattlerb/rescue_do_end_ensure_result.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-@ 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (2,2)-(5,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (2,2)-(2,8))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ SymbolNode (location: (2,2)-(2,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
deleted file mode 100644
index d5e1180a26..0000000000
--- a/test/prism/snapshots/seattlerb/rescue_do_end_no_raise.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-@ ProgramNode (location: (1,0)-(9,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(9,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(9,3))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ BeginNode (location: (2,2)-(9,3))
- │ ├── begin_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (2,2)-(2,8))
- │ │ └── body: (length: 1)
- │ │ └── @ SymbolNode (location: (2,2)-(2,8))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index d400d7c4f9..0000000000
--- a/test/prism/snapshots/seattlerb/rescue_do_end_raised.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(5,3))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ BeginNode (location: (2,2)-(5,3))
- │ ├── begin_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (2,2)-(2,7))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (2,2)-(2,7))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 1b66ad6e3b..0000000000
--- a/test/prism/snapshots/seattlerb/rescue_do_end_rescued.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-@ ProgramNode (location: (1,0)-(9,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(9,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(9,3))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ BeginNode (location: (2,2)-(9,3))
- │ ├── begin_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (2,2)-(2,7))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (2,2)-(2,7))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index 10019765e3..0000000000
--- a/test/prism/snapshots/seattlerb/rescue_in_block.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(4,3))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ BeginNode (location: (2,0)-(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
- │ │ │ ├── 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
deleted file mode 100644
index 0471b8b36a..0000000000
--- a/test/prism/snapshots/seattlerb/rescue_parens.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 8baf6c4c7e..0000000000
--- a/test/prism/snapshots/seattlerb/return_call_assocs.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-@ 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
- │ └── @ KeywordHashNode (location: (1,10)-(1,17))
- │ ├── flags: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,10)-(1,17))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,10)-(1,12))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
- │ └── @ KeywordHashNode (location: (3,10)-(3,26))
- │ ├── flags: static_keys
- │ └── elements: (length: 2)
- │ ├── @ AssocNode (location: (3,10)-(3,17))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (3,10)-(3,12))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (3,13)-(3,15) = "=>"
- │ └── @ AssocNode (location: (3,19)-(3,26))
- │ ├── key:
- │ │ @ SymbolNode (location: (3,19)-(3,21))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (5,9)-(5,14))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (5,9)-(5,11))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (7,9)-(7,12))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (7,9)-(7,11))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (9,9)-(9,12))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (9,9)-(9,11))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- ├── 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
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 61ed05f4e1..0000000000
--- a/test/prism/snapshots/seattlerb/rhs_asgn.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index e1ad6b924c..0000000000
--- a/test/prism/snapshots/seattlerb/ruby21_numbers.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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
- │ ├── @ RationalNode (location: (1,5)-(1,7))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (1,5)-(1,6))
- │ │ └── flags: decimal
- │ └── @ ImaginaryNode (location: (1,9)-(1,12))
- │ └── numeric:
- │ @ RationalNode (location: (1,9)-(1,11))
- │ └── numeric:
- │ @ IntegerNode (location: (1,9)-(1,10))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 530ae74362..0000000000
--- a/test/prism/snapshots/seattlerb/safe_attrasgn.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt b/test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt
deleted file mode 100644
index c34b981d9d..0000000000
--- a/test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call.txt b/test/prism/snapshots/seattlerb/safe_call.txt
deleted file mode 100644
index a6ba52bede..0000000000
--- a/test/prism/snapshots/seattlerb/safe_call.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index e9adf068c7..0000000000
--- a/test/prism/snapshots/seattlerb/safe_call_after_newline.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index e46db2b102..0000000000
--- a/test/prism/snapshots/seattlerb/safe_call_dot_parens.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index a6ba52bede..0000000000
--- a/test/prism/snapshots/seattlerb/safe_call_newline.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index f6027afefb..0000000000
--- a/test/prism/snapshots/seattlerb/safe_call_operator.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 9acf398819..0000000000
--- a/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index 76931bd4fe..0000000000
--- a/test/prism/snapshots/seattlerb/safe_calls.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 01b783642f..0000000000
--- a/test/prism/snapshots/seattlerb/safe_op_asgn.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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
- │ ├── 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: ∅
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn2.txt b/test/prism/snapshots/seattlerb/safe_op_asgn2.txt
deleted file mode 100644
index 9d350e53a1..0000000000
--- a/test/prism/snapshots/seattlerb/safe_op_asgn2.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 840b67ab1a..0000000000
--- a/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ ProgramNode (location: (1,0)-(6,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(6,5))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(4,8))
- │ ├── flags: ∅
- │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index a2c67e609c..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ └── 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
deleted file mode 100644
index 1cd4580bc5..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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]
- ├── locals_body_index: 5
- ├── 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))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,9))
- │ │ │ ├── name: :c
- │ │ │ ├── name_loc: (1,6)-(1,7) = "c"
- │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,8)-(1,9))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (1,11)-(1,13))
- │ │ │ ├── name: :d
- │ │ │ ├── name_loc: (1,12)-(1,13) = "d"
- │ │ │ └── operator_loc: (1,11)-(1,12) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,15)-(1,16))
- │ │ │ └── name: :e
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (1,18)-(1,20))
- │ │ ├── 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
deleted file mode 100644
index 0115ceb46a..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_block_iter_call.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(4,3))
- ├── flags: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 2c680db712..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ ProgramNode (location: (1,0)-(4,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(4,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(4,3))
- ├── flags: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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
- │ ├── closing_loc: (2,3)-(2,4) = ")"
- │ └── block:
- │ @ BlockNode (location: (2,5)-(3,3))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index b9a2151a76..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_block_kw.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── name: :k
- │ │ │ ├── name_loc: (1,4)-(1,6) = "k:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,6)-(1,8))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index 5d0ac1e5c0..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_block_kw__required.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── 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
deleted file mode 100644
index 23ab524fad..0000000000
--- a/test/prism/snapshots/seattlerb/stabby_proc_scope.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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]
- ├── locals_body_index: 2
- ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── locals: (length: 1)
- │ │ └── @ BlockLocalVariableNode (location: (1,6)-(1,7))
- │ │ └── 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
deleted file mode 100644
index ce5160fd3b..0000000000
--- a/test/prism/snapshots/seattlerb/str_backslashes.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,204))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,204))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,204))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 2edea58cc1..0000000000
--- a/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,9))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,9))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,7))
- │ ├── flags: ∅
- │ ├── 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
- ├── 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
deleted file mode 100644
index 53d356ddaa..0000000000
--- a/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,6))
- │ ├── flags: ∅
- │ ├── 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
- ├── 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
deleted file mode 100644
index b5fd8fb582..0000000000
--- a/test/prism/snapshots/seattlerb/str_double_newline.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(2,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(2,3))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(2,1))
- │ ├── flags: ∅
- │ ├── 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
- ├── 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
deleted file mode 100644
index 48798a3ddb..0000000000
--- a/test/prism/snapshots/seattlerb/str_evstr.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,8))
- ├── opening_loc: (1,0)-(1,1) = "\""
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (1,1)-(1,3))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index f173c0269b..0000000000
--- a/test/prism/snapshots/seattlerb/str_evstr_escape.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,16))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,16))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,16))
- ├── opening_loc: (1,0)-(1,1) = "\""
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (1,1)-(1,3))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index eab9b874d6..0000000000
--- a/test/prism/snapshots/seattlerb/str_heredoc_interp.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,4))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,4))
- ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 5fadc71333..0000000000
--- a/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,23))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,23))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,23))
- ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
deleted file mode 100644
index b841407cd8..0000000000
--- a/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ ProgramNode (location: (1,0)-(2,66))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(2,66))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(2,66))
- ├── opening_loc: ∅
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (1,0)-(1,62))
- │ │ ├── flags: forced_utf8_encoding
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 89f20da7b5..0000000000
--- a/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt b/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt
deleted file mode 100644
index edf51fff7b..0000000000
--- a/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,26))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,26))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,26))
- ├── opening_loc: (1,0)-(1,3) = "%Q["
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (1,3)-(1,11))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 85ad89bc60..0000000000
--- a/test/prism/snapshots/seattlerb/str_pct_nested_nested.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,20))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,20))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,20))
- ├── opening_loc: (1,0)-(1,2) = "%{"
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (1,2)-(1,5))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ └── 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: ∅
- │ ├── 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
deleted file mode 100644
index c4dd5bacae..0000000000
--- a/test/prism/snapshots/seattlerb/str_pct_q.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index c519951ed0..0000000000
--- a/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,9))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,9))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,7))
- │ ├── flags: ∅
- │ ├── 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
- ├── 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
deleted file mode 100644
index 80c4712a74..0000000000
--- a/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,6))
- │ ├── flags: ∅
- │ ├── 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
- ├── 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
deleted file mode 100644
index d9b8d69f99..0000000000
--- a/test/prism/snapshots/seattlerb/str_single_newline.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(2,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(2,3))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(2,1))
- │ ├── flags: ∅
- │ ├── 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
- ├── 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
deleted file mode 100644
index f183980f5e..0000000000
--- a/test/prism/snapshots/seattlerb/str_str.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,10))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,10))
- ├── opening_loc: (1,0)-(1,1) = "\""
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (1,1)-(1,3))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 68873d8182..0000000000
--- a/test/prism/snapshots/seattlerb/str_str_str.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,12))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,12))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,12))
- ├── opening_loc: (1,0)-(1,1) = "\""
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (1,1)-(1,3))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index a7f13a4adf..0000000000
--- a/test/prism/snapshots/seattlerb/super_arg.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-@ 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
- ├── rparen_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/symbol_empty.txt b/test/prism/snapshots/seattlerb/symbol_empty.txt
deleted file mode 100644
index 0208aa39c5..0000000000
--- a/test/prism/snapshots/seattlerb/symbol_empty.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,3))
- └── body: (length: 1)
- └── @ SymbolNode (location: (1,0)-(1,3))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 212edfcbc7..0000000000
--- a/test/prism/snapshots/seattlerb/symbol_list.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index bd07b09de3..0000000000
--- a/test/prism/snapshots/seattlerb/symbols.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,3)-(1,4) = "a"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "a"
- │ ├── @ SymbolNode (location: (1,5)-(1,6))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,5)-(1,6) = "b"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "b"
- │ └── @ SymbolNode (location: (1,7)-(1,8))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index dc743e2be5..0000000000
--- a/test/prism/snapshots/seattlerb/symbols_empty.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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
deleted file mode 100644
index ea7ada9446..0000000000
--- a/test/prism/snapshots/seattlerb/symbols_empty_space.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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
deleted file mode 100644
index d141c9a5a2..0000000000
--- a/test/prism/snapshots/seattlerb/symbols_interp.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,3)-(1,4) = "a"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "a"
- │ ├── @ SymbolNode (location: (1,5)-(1,12))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,5)-(1,12) = "b\#{1+1}"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "b\#{1+1}"
- │ └── @ SymbolNode (location: (1,13)-(1,14))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 63ec8c7e36..0000000000
--- a/test/prism/snapshots/seattlerb/thingy.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── closing_loc: (1,5)-(1,6) = ")"
- │ └── block: ∅
- └── @ CallNode (location: (3,0)-(3,7))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (3,0)-(3,1))
- │ ├── flags: variable_call
- │ ├── 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
- ├── 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
deleted file mode 100644
index b509e2f7f3..0000000000
--- a/test/prism/snapshots/seattlerb/uminus_float.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,4))
- └── body: (length: 1)
- └── @ FloatNode (location: (1,0)-(1,4))
diff --git a/test/prism/snapshots/seattlerb/unary_minus.txt b/test/prism/snapshots/seattlerb/unary_minus.txt
deleted file mode 100644
index 53fe7a65f2..0000000000
--- a/test/prism/snapshots/seattlerb/unary_minus.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 34ea027ce3..0000000000
--- a/test/prism/snapshots/seattlerb/unary_plus.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 1638de8b8d..0000000000
--- a/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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: ∅
- │ ├── 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
deleted file mode 100644
index 7268b99cd3..0000000000
--- a/test/prism/snapshots/seattlerb/unary_tilde.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index ad48aa068f..0000000000
--- a/test/prism/snapshots/seattlerb/utf8_bom.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-@ ProgramNode (location: (2,0)-(2,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (2,0)-(2,3))
- └── body: (length: 1)
- └── @ CallNode (location: (2,0)-(2,3))
- ├── flags: ∅
- ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/when_splat.txt b/test/prism/snapshots/seattlerb/when_splat.txt
deleted file mode 100644
index bd5928ca8b..0000000000
--- a/test/prism/snapshots/seattlerb/when_splat.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- │ ├── 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,15))
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :b
- │ │ ├── message_loc: (1,14)-(1,15) = "b"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── 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
deleted file mode 100644
index 864f826dcb..0000000000
--- a/test/prism/snapshots/seattlerb/words_interp.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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))
- │ ├── 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
- │ │ │ └── closing_loc: (1,6)-(1,7) = "}"
- │ │ └── @ StringNode (location: (1,7)-(1,8))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index d297e5acdb..0000000000
--- a/test/prism/snapshots/seattlerb/yield_arg.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-@ 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
- └── rparen_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/yield_call_assocs.txt b/test/prism/snapshots/seattlerb/yield_call_assocs.txt
deleted file mode 100644
index 82d1765f21..0000000000
--- a/test/prism/snapshots/seattlerb/yield_call_assocs.txt
+++ /dev/null
@@ -1,215 +0,0 @@
-@ 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
- │ │ └── @ KeywordHashNode (location: (1,9)-(1,16))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,9)-(1,16))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,9)-(1,11))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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
- │ │ └── @ KeywordHashNode (location: (3,9)-(3,25))
- │ │ ├── flags: static_keys
- │ │ └── elements: (length: 2)
- │ │ ├── @ AssocNode (location: (3,9)-(3,16))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (3,9)-(3,11))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ └── operator_loc: (3,12)-(3,14) = "=>"
- │ │ └── @ AssocNode (location: (3,18)-(3,25))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (3,18)-(3,20))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ ├── 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: static_keys
- │ │ │ └── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (5,8)-(5,13))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (5,8)-(5,10))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ ├── 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: static_keys
- │ │ │ └── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (7,8)-(7,11))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (7,8)-(7,10))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ ├── 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: static_keys
- │ │ │ └── elements: (length: 1)
- │ │ │ └── @ AssocNode (location: (9,8)-(9,11))
- │ │ │ ├── key:
- │ │ │ │ @ SymbolNode (location: (9,8)-(9,10))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ └── 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
deleted file mode 100644
index 5ecd89823f..0000000000
--- a/test/prism/snapshots/seattlerb/yield_empty_parens.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-@ 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_quote_heredocs.txt b/test/prism/snapshots/single_quote_heredocs.txt
deleted file mode 100644
index 429c9daf11..0000000000
--- a/test/prism/snapshots/single_quote_heredocs.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 5602d567eb..0000000000
--- a/test/prism/snapshots/spanning_heredoc.txt
+++ /dev/null
@@ -1,409 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ │ ├── content_loc: (4,14)-(4,16) = "b\\"
- │ │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ │ └── unescaped: "b"
- │ │ │ │ │ └── @ StringNode (location: (7,0)-(7,1))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (10,9)-(10,10) = "\""
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (10,10)-(10,12))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (10,10)-(10,12) = "d\\"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "d"
- │ │ │ └── @ StringNode (location: (13,0)-(13,1))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (16,9)-(16,12) = "%q["
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (16,12)-(16,14))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (16,12)-(16,14) = "f\\"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "f\\\n"
- │ │ │ └── @ StringNode (location: (19,0)-(19,1))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (22,9)-(22,12) = "%Q["
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (22,12)-(22,14))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (22,12)-(22,14) = "h\\"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "h"
- │ │ │ └── @ StringNode (location: (25,0)-(25,1))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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))
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── parts: (length: 2)
- │ │ │ │ ├── @ StringNode (location: (35,12)-(35,14))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── content_loc: (35,12)-(35,14) = "l\\"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "l\n"
- │ │ │ │ └── @ StringNode (location: (38,0)-(38,1))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (41,12)-(41,14) = "n\\"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "n\n"
- │ │ │ └── @ SymbolNode (location: (44,0)-(44,1))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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)
- │ │ │ │ ├── @ SymbolNode (location: (48,12)-(48,14))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── value_loc: (48,12)-(48,14) = "p\\"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: "p\n"
- │ │ │ │ └── @ StringNode (location: (48,12)-(48,14))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ ├── content_loc: (53,6)-(53,7) = "\\"
- │ │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ │ └── unescaped: ""
- │ │ │ │ └── @ StringNode (location: (55,0)-(55,6))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (57,7)-(58,0) = "a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (59,0)-(59,1))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (61,7)-(62,0) = "a\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "a\n"
- │ └── @ StringNode (location: (63,0)-(63,1))
- │ ├── flags: ∅
- │ ├── 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/strings.txt b/test/prism/snapshots/strings.txt
deleted file mode 100644
index eec1d27f33..0000000000
--- a/test/prism/snapshots/strings.txt
+++ /dev/null
@@ -1,527 +0,0 @@
-@ 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))
- │ ├── 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))
- │ ├── opening_loc: (35,0)-(35,2) = "%{"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (35,2)-(35,6))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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))
- │ ├── opening_loc: (55,0)-(55,1) = "\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (55,1)-(55,5))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── parts: (length: 3)
- │ │ │ │ ├── @ StringNode (location: (67,5)-(67,6))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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))
- │ ├── 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))
- │ ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (99,0)-(99,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (99,0)-(99,1) = "?"
- │ │ │ ├── content_loc: (99,1)-(99,2) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ StringNode (location: (99,3)-(99,6))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 72ed5625bd..0000000000
--- a/test/prism/snapshots/super.txt
+++ /dev/null
@@ -1,124 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── @ IntegerNode (location: (7,9)-(7,10))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (7,12)-(7,13))
- │ │ └── flags: decimal
- │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── @ IntegerNode (location: (15,9)-(15,10))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (15,12)-(15,13))
- │ │ └── flags: decimal
- │ ├── rparen_loc: (15,13)-(15,14) = ")"
- │ └── block:
- │ @ BlockNode (location: (15,15)-(15,17))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── @ IntegerNode (location: (17,9)-(17,10))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (17,12)-(17,13))
- │ └── flags: decimal
- ├── rparen_loc: (17,20)-(17,21) = ")"
- └── block:
- @ BlockArgumentNode (location: (17,15)-(17,20))
- ├── expression:
- │ @ SymbolNode (location: (17,16)-(17,20))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index e830ddb7cc..0000000000
--- a/test/prism/snapshots/symbols.txt
+++ /dev/null
@@ -1,456 +0,0 @@
-@ ProgramNode (location: (1,0)-(93,13))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(93,13))
- └── body: (length: 47)
- ├── @ SymbolNode (location: (1,0)-(1,6))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ ├── opening_loc: (9,0)-(9,1) = ":"
- │ ├── value_loc: (9,1)-(9,3) = "-@"
- │ ├── closing_loc: ∅
- │ └── unescaped: "-@"
- ├── @ SymbolNode (location: (11,0)-(11,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (11,0)-(11,1) = ":"
- │ ├── value_loc: (11,1)-(11,2) = "-"
- │ ├── closing_loc: ∅
- │ └── unescaped: "-"
- ├── @ SymbolNode (location: (13,0)-(13,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (13,0)-(13,1) = ":"
- │ ├── value_loc: (13,1)-(13,2) = "%"
- │ ├── closing_loc: ∅
- │ └── unescaped: "%"
- ├── @ SymbolNode (location: (15,0)-(15,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (15,0)-(15,1) = ":"
- │ ├── value_loc: (15,1)-(15,2) = "|"
- │ ├── closing_loc: ∅
- │ └── unescaped: "|"
- ├── @ SymbolNode (location: (17,0)-(17,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (17,0)-(17,1) = ":"
- │ ├── value_loc: (17,1)-(17,3) = "+@"
- │ ├── closing_loc: ∅
- │ └── unescaped: "+@"
- ├── @ SymbolNode (location: (19,0)-(19,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (19,0)-(19,1) = ":"
- │ ├── value_loc: (19,1)-(19,2) = "+"
- │ ├── closing_loc: ∅
- │ └── unescaped: "+"
- ├── @ SymbolNode (location: (21,0)-(21,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (21,0)-(21,1) = ":"
- │ ├── value_loc: (21,1)-(21,2) = "/"
- │ ├── closing_loc: ∅
- │ └── unescaped: "/"
- ├── @ SymbolNode (location: (23,0)-(23,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (23,0)-(23,1) = ":"
- │ ├── value_loc: (23,1)-(23,3) = "**"
- │ ├── closing_loc: ∅
- │ └── unescaped: "**"
- ├── @ SymbolNode (location: (25,0)-(25,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (25,0)-(25,1) = ":"
- │ ├── value_loc: (25,1)-(25,2) = "*"
- │ ├── closing_loc: ∅
- │ └── unescaped: "*"
- ├── @ SymbolNode (location: (27,0)-(27,3))
- │ ├── flags: ∅
- │ ├── 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
- │ │ ├── @ FloatNode (location: (29,4)-(29,7))
- │ │ ├── @ RationalNode (location: (29,9)-(29,11))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (29,9)-(29,10))
- │ │ │ └── flags: decimal
- │ │ └── @ ImaginaryNode (location: (29,13)-(29,15))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (29,13)-(29,14))
- │ │ └── flags: decimal
- │ ├── opening_loc: (29,0)-(29,1) = "["
- │ └── closing_loc: (29,15)-(29,16) = "]"
- ├── @ SymbolNode (location: (31,0)-(31,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (31,0)-(31,1) = ":"
- │ ├── value_loc: (31,1)-(31,2) = "~"
- │ ├── closing_loc: ∅
- │ └── unescaped: "~"
- ├── @ SymbolNode (location: (33,0)-(33,2))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (35,3)-(35,4) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ ├── @ SymbolNode (location: (35,5)-(35,6))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (35,5)-(35,6) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ └── @ SymbolNode (location: (35,7)-(35,8))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (37,3)-(37,4) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ ├── @ SymbolNode (location: (37,5)-(37,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (37,5)-(37,10) = "b\#{1}"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b\#{1}"
- │ │ ├── @ SymbolNode (location: (37,11)-(37,16))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (37,11)-(37,16) = "\#{2}c"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\#{2}c"
- │ │ └── @ SymbolNode (location: (37,17)-(37,23))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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
- │ │ │ │ └── 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
- │ │ │ │ │ └── closing_loc: (39,14)-(39,15) = "}"
- │ │ │ │ └── @ StringNode (location: (39,15)-(39,16))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ └── closing_loc: (39,21)-(39,22) = "}"
- │ │ │ └── @ StringNode (location: (39,22)-(39,23))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── opening_loc: (47,0)-(47,1) = ":"
- │ ├── value_loc: (47,1)-(47,3) = "$a"
- │ ├── closing_loc: ∅
- │ └── unescaped: "$a"
- ├── @ SymbolNode (location: (49,0)-(49,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (49,0)-(49,1) = ":"
- │ ├── value_loc: (49,1)-(49,3) = "@a"
- │ ├── closing_loc: ∅
- │ └── unescaped: "@a"
- ├── @ SymbolNode (location: (51,0)-(51,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (51,0)-(51,1) = ":"
- │ ├── value_loc: (51,1)-(51,3) = "do"
- │ ├── closing_loc: ∅
- │ └── unescaped: "do"
- ├── @ SymbolNode (location: (53,0)-(53,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (53,0)-(53,1) = ":"
- │ ├── value_loc: (53,1)-(53,2) = "&"
- │ ├── closing_loc: ∅
- │ └── unescaped: "&"
- ├── @ SymbolNode (location: (55,0)-(55,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (55,0)-(55,1) = ":"
- │ ├── value_loc: (55,1)-(55,2) = "`"
- │ ├── closing_loc: ∅
- │ └── unescaped: "`"
- ├── @ SymbolNode (location: (57,0)-(57,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (57,0)-(57,1) = ":"
- │ ├── value_loc: (57,1)-(57,3) = "!@"
- │ ├── closing_loc: ∅
- │ └── unescaped: "!@"
- ├── @ SymbolNode (location: (59,0)-(59,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (59,0)-(59,1) = ":"
- │ ├── value_loc: (59,1)-(59,3) = "!~"
- │ ├── closing_loc: ∅
- │ └── unescaped: "!~"
- ├── @ SymbolNode (location: (61,0)-(61,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (61,0)-(61,1) = ":"
- │ ├── value_loc: (61,1)-(61,2) = "!"
- │ ├── closing_loc: ∅
- │ └── unescaped: "!"
- ├── @ SymbolNode (location: (63,0)-(63,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (63,0)-(63,1) = ":"
- │ ├── value_loc: (63,1)-(63,3) = "[]"
- │ ├── closing_loc: ∅
- │ └── unescaped: "[]"
- ├── @ SymbolNode (location: (65,0)-(65,4))
- │ ├── flags: ∅
- │ ├── opening_loc: (65,0)-(65,1) = ":"
- │ ├── value_loc: (65,1)-(65,4) = "[]="
- │ ├── closing_loc: ∅
- │ └── unescaped: "[]="
- ├── @ SymbolNode (location: (67,0)-(67,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (67,0)-(67,1) = ":"
- │ ├── value_loc: (67,1)-(67,2) = "^"
- │ ├── closing_loc: ∅
- │ └── unescaped: "^"
- ├── @ SymbolNode (location: (69,0)-(69,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (69,0)-(69,1) = ":"
- │ ├── value_loc: (69,1)-(69,3) = "=="
- │ ├── closing_loc: ∅
- │ └── unescaped: "=="
- ├── @ SymbolNode (location: (71,0)-(71,4))
- │ ├── flags: ∅
- │ ├── opening_loc: (71,0)-(71,1) = ":"
- │ ├── value_loc: (71,1)-(71,4) = "==="
- │ ├── closing_loc: ∅
- │ └── unescaped: "==="
- ├── @ SymbolNode (location: (73,0)-(73,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (73,0)-(73,1) = ":"
- │ ├── value_loc: (73,1)-(73,3) = "=~"
- │ ├── closing_loc: ∅
- │ └── unescaped: "=~"
- ├── @ SymbolNode (location: (75,0)-(75,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (75,0)-(75,1) = ":"
- │ ├── value_loc: (75,1)-(75,3) = ">="
- │ ├── closing_loc: ∅
- │ └── unescaped: ">="
- ├── @ SymbolNode (location: (77,0)-(77,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (77,0)-(77,1) = ":"
- │ ├── value_loc: (77,1)-(77,3) = ">>"
- │ ├── closing_loc: ∅
- │ └── unescaped: ">>"
- ├── @ SymbolNode (location: (79,0)-(79,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (79,0)-(79,1) = ":"
- │ ├── value_loc: (79,1)-(79,2) = ">"
- │ ├── closing_loc: ∅
- │ └── unescaped: ">"
- ├── @ SymbolNode (location: (81,0)-(81,4))
- │ ├── flags: ∅
- │ ├── opening_loc: (81,0)-(81,1) = ":"
- │ ├── value_loc: (81,1)-(81,4) = "<=>"
- │ ├── closing_loc: ∅
- │ └── unescaped: "<=>"
- ├── @ SymbolNode (location: (83,0)-(83,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (83,0)-(83,1) = ":"
- │ ├── value_loc: (83,1)-(83,3) = "<="
- │ ├── closing_loc: ∅
- │ └── unescaped: "<="
- ├── @ SymbolNode (location: (85,0)-(85,3))
- │ ├── flags: ∅
- │ ├── opening_loc: (85,0)-(85,1) = ":"
- │ ├── value_loc: (85,1)-(85,3) = "<<"
- │ ├── closing_loc: ∅
- │ └── unescaped: "<<"
- ├── @ SymbolNode (location: (87,0)-(87,2))
- │ ├── flags: ∅
- │ ├── opening_loc: (87,0)-(87,1) = ":"
- │ ├── value_loc: (87,1)-(87,2) = "<"
- │ ├── closing_loc: ∅
- │ └── unescaped: "<"
- ├── @ SymbolNode (location: (89,0)-(89,9))
- │ ├── flags: ∅
- │ ├── opening_loc: (89,0)-(89,1) = ":"
- │ ├── value_loc: (89,1)-(89,9) = "__LINE__"
- │ ├── closing_loc: ∅
- │ └── unescaped: "__LINE__"
- ├── @ SymbolNode (location: (91,0)-(91,9))
- │ ├── flags: ∅
- │ ├── opening_loc: (91,0)-(91,1) = ":"
- │ ├── value_loc: (91,1)-(91,9) = "__FILE__"
- │ ├── closing_loc: ∅
- │ └── unescaped: "__FILE__"
- └── @ SymbolNode (location: (93,0)-(93,13))
- ├── flags: ∅
- ├── 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
deleted file mode 100644
index 541bd8c792..0000000000
--- a/test/prism/snapshots/ternary_operator.txt
+++ /dev/null
@@ -1,293 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ └── 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
- │ └── end_keyword_loc: ∅
- └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/tilde_heredocs.txt b/test/prism/snapshots/tilde_heredocs.txt
deleted file mode 100644
index fb09e075e1..0000000000
--- a/test/prism/snapshots/tilde_heredocs.txt
+++ /dev/null
@@ -1,381 +0,0 @@
-@ ProgramNode (location: (1,0)-(94,6))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(94,6))
- └── body: (length: 19)
- ├── @ InterpolatedStringNode (location: (1,0)-(1,6))
- │ ├── opening_loc: (1,0)-(1,6) = "<<~EOF"
- │ ├── parts: (length: 4)
- │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (3,3)-(3,4) = "}"
- │ │ ├── @ StringNode (location: (3,4)-(4,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (3,4)-(4,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (4,0)-(5,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (11,0)-(11,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (12,0)-(13,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (12,0)-(13,0) = "\ta\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\ta\n"
- │ │ ├── @ StringNode (location: (13,0)-(14,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (13,0)-(14,0) = " b\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b\n"
- │ │ └── @ StringNode (location: (14,0)-(15,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── 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
- │ │ │ └── closing_loc: (18,5)-(18,6) = "}"
- │ │ └── @ StringNode (location: (18,6)-(19,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (21,0)-(21,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (22,0)-(22,4))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (22,7)-(22,8) = "}"
- │ │ └── @ StringNode (location: (22,8)-(23,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (25,0)-(25,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (26,0)-(27,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (27,4)-(27,5) = "}"
- │ │ └── @ StringNode (location: (27,5)-(28,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (30,0)-(30,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (31,0)-(32,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (32,5)-(32,6) = "}"
- │ │ └── @ StringNode (location: (32,6)-(33,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (35,0)-(35,6) = "<<~EOF"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (36,0)-(37,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (36,0)-(37,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (37,0)-(38,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (40,0)-(40,6) = "<<~EOF"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (41,0)-(42,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (41,0)-(42,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (42,0)-(43,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (45,0)-(45,6) = "<<~EOF"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (46,0)-(47,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (46,0)-(47,0) = "\t\t\ta\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\ta\n"
- │ │ └── @ StringNode (location: (47,0)-(48,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (54,0)-(54,6) = "<<~EOF"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (55,0)-(56,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (55,0)-(56,0) = "\ta\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (56,0)-(57,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (59,0)-(59,6) = "<<~EOF"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (60,0)-(61,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (60,0)-(61,0) = "\t a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: " a\n"
- │ │ └── @ StringNode (location: (61,0)-(62,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (64,0)-(64,6) = "<<~EOF"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (65,0)-(66,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (65,0)-(66,0) = " \ta\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (66,0)-(67,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (69,0)-(69,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (70,0)-(71,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (70,0)-(71,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ ├── @ StringNode (location: (71,0)-(72,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (71,0)-(72,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (72,0)-(73,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (75,0)-(75,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (76,0)-(77,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (76,0)-(77,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ ├── @ StringNode (location: (77,0)-(78,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (77,0)-(78,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (78,0)-(79,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (81,0)-(81,6) = "<<~EOF"
- │ ├── parts: (length: 5)
- │ │ ├── @ StringNode (location: (82,0)-(83,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (82,0)-(83,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ ├── @ StringNode (location: (83,0)-(84,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (83,0)-(84,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ ├── @ StringNode (location: (84,0)-(85,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (84,0)-(85,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ ├── @ StringNode (location: (85,0)-(86,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (85,0)-(86,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (86,0)-(87,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (89,0)-(89,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (90,0)-(91,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (91,5)-(91,6) = "}"
- │ │ └── @ StringNode (location: (91,6)-(92,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- ├── 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
- │ │ └── closing_loc: (95,5)-(95,6) = "}"
- │ ├── @ StringNode (location: (95,6)-(96,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (95,6)-(96,0) = "\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "\n"
- │ └── @ StringNode (location: (96,0)-(97,0))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 2bb369d7d8..0000000000
--- a/test/prism/snapshots/undef.txt
+++ /dev/null
@@ -1,116 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (3,6)-(3,7) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (3,9)-(3,10))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (11,6)-(11,7) = ":"
- │ │ │ ├── value_loc: (11,7)-(11,8) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ ├── @ SymbolNode (location: (11,10)-(11,12))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: (11,10)-(11,11) = ":"
- │ │ │ ├── value_loc: (11,11)-(11,12) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ └── @ SymbolNode (location: (11,14)-(11,16))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ ├── 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
deleted file mode 100644
index 00c5f59cd1..0000000000
--- a/test/prism/snapshots/unescaping.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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: ∅
- │ ├── 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
deleted file mode 100644
index 3bc3e99897..0000000000
--- a/test/prism/snapshots/unless.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ │ └── 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
- │ ├── consequent: ∅
- │ └── end_keyword_loc: ∅
- ├── @ UnlessNode (location: (8,0)-(8,17))
- │ ├── keyword_loc: (8,6)-(8,12) = "unless"
- │ ├── predicate:
- │ │ @ TrueNode (location: (8,13)-(8,17))
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (8,0)-(8,5))
- │ │ └── body: (length: 1)
- │ │ └── @ BreakNode (location: (8,0)-(8,5))
- │ │ ├── arguments: ∅
- │ │ └── keyword_loc: (8,0)-(8,5) = "break"
- │ ├── consequent: ∅
- │ └── end_keyword_loc: ∅
- ├── @ UnlessNode (location: (10,0)-(10,16))
- │ ├── keyword_loc: (10,5)-(10,11) = "unless"
- │ ├── predicate:
- │ │ @ TrueNode (location: (10,12)-(10,16))
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (10,0)-(10,4))
- │ │ └── body: (length: 1)
- │ │ └── @ NextNode (location: (10,0)-(10,4))
- │ │ ├── arguments: ∅
- │ │ └── keyword_loc: (10,0)-(10,4) = "next"
- │ ├── consequent: ∅
- │ └── end_keyword_loc: ∅
- ├── @ 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (14,4)-(14,5) = ":"
- │ │ │ ├── value_loc: (14,5)-(14,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (14,8)-(14,10))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 68ee27f7f9..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/alias.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 18edafe415..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/assignment.txt
+++ /dev/null
@@ -1,1035 +0,0 @@
-@ 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
- │ └── 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
- │ │ └── @ IntegerNode (location: (2,15)-(2,16))
- │ │ └── flags: decimal
- │ ├── 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
- ├── @ 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
- │ │ └── @ IntegerNode (location: (5,13)-(5,14))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (6,17)-(6,18))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (7,15)-(7,16))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ ArrayNode (location: (8,18)-(8,24))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 2)
- │ │ │ ├── @ IntegerNode (location: (8,19)-(8,20))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (8,22)-(8,23))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (9,13)-(9,14))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (10,16)-(10,17))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (11,13)-(11,14))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (14,21)-(14,22))
- │ │ └── flags: decimal
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (15,22)-(15,23))
- │ │ └── flags: decimal
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── closing_loc: (16,4)-(16,5) = "]"
- │ │ │ └── block: ∅
- │ │ └── @ IndexTargetNode (location: (16,7)-(16,11))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (16,19)-(16,20))
- │ │ └── flags: decimal
- │ ├── 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
- ├── @ 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
- │ └── 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
- │ └── 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
- │ └── 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
- ├── @ 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
- │ │ ├── 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
- │ └── 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: ∅
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (27,11)-(27,12))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (30,7)-(30,8))
- │ │ │ │ └── flags: decimal
- │ │ │ └── operator_loc: (30,5)-(30,7) = ".."
- │ │ └── @ CallNode (location: (30,12)-(30,17))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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))
- │ │ ├── opening_loc: (39,4)-(39,14) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (40,0)-(40,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ │ ├── opening_loc: (42,4)-(42,14) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (43,0)-(43,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ │ ├── opening_loc: (45,6)-(45,16) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (46,0)-(46,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ │ ├── opening_loc: (48,2)-(48,12) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (49,0)-(49,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ ├── 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))
- ├── opening_loc: (51,7)-(51,17) = "<<-HEREDOC"
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (52,0)-(52,2))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 63fcfd23dd..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/block.txt
+++ /dev/null
@@ -1,1408 +0,0 @@
-@ ProgramNode (location: (1,0)-(96,1))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(96,1))
- └── body: (length: 30)
- ├── @ CallNode (location: (1,0)-(2,1))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,4)-(1,5) = "{"
- │ └── closing_loc: (2,0)-(2,1) = "}"
- ├── @ CallNode (location: (3,0)-(4,1))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (3,6)-(3,9))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (3,7)-(3,8))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (3,7)-(3,8))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (5,6)-(5,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (5,7)-(5,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (5,7)-(5,8))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (7,6)-(7,13))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (7,7)-(7,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (7,7)-(7,8))
- │ │ │ │ └── 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))
- │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (9,6)-(9,12))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (9,7)-(9,11))
- │ │ │ ├── requireds: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (9,7)-(9,8))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (9,10)-(9,11))
- │ │ │ │ └── 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: ∅
- │ ├── 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
- │ ├── closing_loc: (11,5)-(11,6) = ")"
- │ └── block:
- │ @ BlockNode (location: (11,7)-(13,1))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (14,6)-(14,13))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (14,7)-(14,12))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (14,7)-(14,8))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (14,10)-(14,12))
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (17,6)-(17,12))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (17,7)-(17,11))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (17,7)-(17,8))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (17,10)-(17,11))
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (21,2)-(21,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (21,2)-(21,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ │ │ │ │ └── name: :a
- │ │ │ │ │ │ └── @ RequiredParameterNode (location: (23,15)-(23,16))
- │ │ │ │ │ │ └── name: :b
- │ │ │ │ │ ├── rest: ∅
- │ │ │ │ │ ├── rights: (length: 0)
- │ │ │ │ │ ├── lparen_loc: (23,11)-(23,12) = "("
- │ │ │ │ │ └── rparen_loc: (23,16)-(23,17) = ")"
- │ │ │ │ └── @ RequiredParameterNode (location: (23,19)-(23,20))
- │ │ │ │ └── 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
- │ │ ├── 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
- │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── 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))
- │ │ │ └── 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
- │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (28,10)-(28,16))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (28,11)-(28,12))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (28,11)-(28,12))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── locals: (length: 1)
- │ │ │ └── @ BlockLocalVariableNode (location: (28,14)-(28,15))
- │ │ │ └── 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
- │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (30,10)-(30,18))
- │ │ ├── parameters: ∅
- │ │ ├── locals: (length: 2)
- │ │ │ ├── @ BlockLocalVariableNode (location: (30,13)-(30,14))
- │ │ │ │ └── name: :a
- │ │ │ └── @ BlockLocalVariableNode (location: (30,16)-(30,17))
- │ │ │ └── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ │ │ └── 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
- │ │ ├── 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
- │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ │ │ └── name: :a
- │ │ │ │ │ └── @ RequiredParameterNode (location: (44,15)-(44,16))
- │ │ │ │ │ └── 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
- │ │ ├── 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
- │ │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (50,0)-(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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (53,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
- │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (58,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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (63,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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (68,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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (73,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
- │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (77,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
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (83,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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (88,0)-(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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (91,0)-(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: ∅
- ├── 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]
- ├── locals_body_index: 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
deleted file mode 100644
index be09557956..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/case.txt
+++ /dev/null
@@ -1,434 +0,0 @@
-@ 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── message_loc: (2,5)-(2,8) = "bar"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ └── statements:
- │ │ │ @ StatementsNode (location: (3,2)-(3,5))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (3,2)-(3,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (4,5)-(4,8) = "baz"
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── message_loc: (8,5)-(8,8) = "bar"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ └── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (9,5)-(9,8) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── statements:
- │ │ @ StatementsNode (location: (10,2)-(10,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (10,2)-(10,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── message_loc: (13,5)-(13,8) = "bar"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ └── statements:
- │ │ │ @ StatementsNode (location: (14,2)-(14,5))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (14,2)-(14,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (15,5)-(15,8) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── statements:
- │ │ @ StatementsNode (location: (16,2)-(16,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (16,2)-(16,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (19,10)-(19,13) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── statements:
- │ │ @ StatementsNode (location: (20,2)-(20,8))
- │ │ └── body: (length: 1)
- │ │ └── @ SymbolNode (location: (20,2)-(20,8))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :bar
- │ │ │ ├── message_loc: (23,6)-(23,9) = "bar"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── statements:
- │ │ @ StatementsNode (location: (24,2)-(24,8))
- │ │ └── body: (length: 1)
- │ │ └── @ SymbolNode (location: (24,2)-(24,8))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :bar
- │ │ │ ├── message_loc: (27,5)-(27,8) = "bar"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── statements:
- │ │ @ StatementsNode (location: (28,2)-(28,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (28,2)-(28,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :baz
- │ │ │ │ ├── message_loc: (33,12)-(33,15) = "baz"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── 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
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── 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
deleted file mode 100644
index b26934afbb..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/class.txt
+++ /dev/null
@@ -1,234 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (30,4)-(30,5) = ":"
- │ │ │ ├── value_loc: (30,5)-(30,8) = "bar"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "bar"
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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/control.txt b/test/prism/snapshots/unparser/corpus/literal/control.txt
deleted file mode 100644
index 3f667bd431..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/control.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-@ ProgramNode (location: (1,0)-(15,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(15,3))
- └── body: (length: 11)
- ├── @ NextNode (location: (1,0)-(1,4))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,0)-(1,4) = "next"
- ├── @ ReturnNode (location: (2,0)-(2,6))
- │ ├── keyword_loc: (2,0)-(2,6) = "return"
- │ └── arguments: ∅
- ├── @ BreakNode (location: (3,0)-(3,5))
- │ ├── arguments: ∅
- │ └── keyword_loc: (3,0)-(3,5) = "break"
- ├── @ RetryNode (location: (4,0)-(4,5))
- ├── @ RedoNode (location: (5,0)-(5,4))
- ├── @ ReturnNode (location: (6,0)-(6,8))
- │ ├── keyword_loc: (6,0)-(6,6) = "return"
- │ └── arguments:
- │ @ ArgumentsNode (location: (6,7)-(6,8))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ IntegerNode (location: (6,7)-(6,8))
- │ └── flags: decimal
- ├── @ ReturnNode (location: (7,0)-(7,11))
- │ ├── keyword_loc: (7,0)-(7,6) = "return"
- │ └── arguments:
- │ @ ArgumentsNode (location: (7,7)-(7,11))
- │ ├── flags: ∅
- │ └── arguments: (length: 2)
- │ ├── @ IntegerNode (location: (7,7)-(7,8))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (7,10)-(7,11))
- │ └── flags: decimal
- ├── @ ReturnNode (location: (8,0)-(8,19))
- │ ├── keyword_loc: (8,0)-(8,6) = "return"
- │ └── arguments:
- │ @ ArgumentsNode (location: (8,7)-(8,19))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ IfNode (location: (8,7)-(8,19))
- │ ├── if_keyword_loc: ∅
- │ ├── predicate:
- │ │ @ TrueNode (location: (8,7)-(8,11))
- │ ├── then_keyword_loc: (8,12)-(8,13) = "?"
- │ ├── statements:
- │ │ @ StatementsNode (location: (8,14)-(8,15))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (8,14)-(8,15))
- │ │ └── flags: decimal
- │ ├── consequent:
- │ │ @ ElseNode (location: (8,16)-(8,19))
- │ │ ├── else_keyword_loc: (8,16)-(8,17) = ":"
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (8,18)-(8,19))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (8,18)-(8,19))
- │ │ │ └── flags: decimal
- │ │ └── end_keyword_loc: ∅
- │ └── end_keyword_loc: ∅
- ├── @ BreakNode (location: (9,0)-(9,18))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (9,6)-(9,18))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ IfNode (location: (9,6)-(9,18))
- │ │ ├── if_keyword_loc: ∅
- │ │ ├── predicate:
- │ │ │ @ TrueNode (location: (9,6)-(9,10))
- │ │ ├── then_keyword_loc: (9,11)-(9,12) = "?"
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (9,13)-(9,14))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (9,13)-(9,14))
- │ │ │ └── flags: decimal
- │ │ ├── consequent:
- │ │ │ @ ElseNode (location: (9,15)-(9,18))
- │ │ │ ├── else_keyword_loc: (9,15)-(9,16) = ":"
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (9,17)-(9,18))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (9,17)-(9,18))
- │ │ │ │ └── flags: decimal
- │ │ │ └── end_keyword_loc: ∅
- │ │ └── end_keyword_loc: ∅
- │ └── keyword_loc: (9,0)-(9,5) = "break"
- ├── @ NextNode (location: (10,0)-(10,17))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (10,5)-(10,17))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ IfNode (location: (10,5)-(10,17))
- │ │ ├── if_keyword_loc: ∅
- │ │ ├── predicate:
- │ │ │ @ TrueNode (location: (10,5)-(10,9))
- │ │ ├── then_keyword_loc: (10,10)-(10,11) = "?"
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (10,12)-(10,13))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (10,12)-(10,13))
- │ │ │ └── flags: decimal
- │ │ ├── consequent:
- │ │ │ @ ElseNode (location: (10,14)-(10,17))
- │ │ │ ├── else_keyword_loc: (10,14)-(10,15) = ":"
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (10,16)-(10,17))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (10,16)-(10,17))
- │ │ │ │ └── flags: decimal
- │ │ │ └── end_keyword_loc: ∅
- │ │ └── end_keyword_loc: ∅
- │ └── keyword_loc: (10,0)-(10,4) = "next"
- └── @ ReturnNode (location: (11,0)-(15,3))
- ├── keyword_loc: (11,0)-(11,6) = "return"
- └── arguments:
- @ ArgumentsNode (location: (11,7)-(15,3))
- ├── flags: ∅
- └── arguments: (length: 2)
- ├── @ TrueNode (location: (11,7)-(11,11))
- └── @ IfNode (location: (11,13)-(15,3))
- ├── if_keyword_loc: (11,13)-(11,15) = "if"
- ├── predicate:
- │ @ TrueNode (location: (11,16)-(11,20))
- ├── then_keyword_loc: ∅
- ├── statements:
- │ @ StatementsNode (location: (12,2)-(12,3))
- │ └── body: (length: 1)
- │ └── @ IntegerNode (location: (12,2)-(12,3))
- │ └── flags: decimal
- ├── consequent:
- │ @ ElseNode (location: (13,0)-(15,3))
- │ ├── else_keyword_loc: (13,0)-(13,4) = "else"
- │ ├── statements:
- │ │ @ StatementsNode (location: (14,2)-(14,3))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (14,2)-(14,3))
- │ │ └── flags: decimal
- │ └── end_keyword_loc: (15,0)-(15,3) = "end"
- └── end_keyword_loc: (15,0)-(15,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/def.txt b/test/prism/snapshots/unparser/corpus/literal/def.txt
deleted file mode 100644
index 0648be1293..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/def.txt
+++ /dev/null
@@ -1,1201 +0,0 @@
-@ 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: (2,2)-(9,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (2,2)-(2,3))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (2,2)-(2,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: (12,2)-(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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ ├── name: :bar
- │ │ │ │ └── name_loc: (21,8)-(21,12) = "bar:"
- │ │ │ └── @ RequiredKeywordParameterNode (location: (21,14)-(21,18))
- │ │ │ ├── name: :baz
- │ │ │ └── name_loc: (21,14)-(21,18) = "baz:"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:bar, :baz]
- │ ├── locals_body_index: 2
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (28,2)-(28,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: (32,2)-(37,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (32,2)-(32,5))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (32,2)-(32,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: (40,2)-(43,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (40,2)-(40,5))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (40,2)-(40,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: (46,2)-(49,3))
- │ │ ├── begin_keyword_loc: ∅
- │ │ ├── statements:
- │ │ │ @ StatementsNode (location: (46,2)-(46,5))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (46,2)-(46,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── name: :bar
- │ │ │ └── @ RequiredParameterNode (location: (55,13)-(55,16))
- │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── name: :bar
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (70,13)-(70,23))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── name: :bar
- │ │ │ ├── name_loc: (74,8)-(74,12) = "bar:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (74,13)-(74,14))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:bar]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :bar
- │ │ │ ├── name_loc: (77,8)-(77,12) = "bar:"
- │ │ │ └── value:
- │ │ │ @ CallNode (location: (77,13)-(77,16))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :bar
- │ │ │ ├── name_loc: (80,8)-(80,12) = "bar:"
- │ │ │ └── value:
- │ │ │ @ CallNode (location: (80,13)-(80,18))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (84,2)-(84,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:*]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── name: :bar
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (91,13)-(91,17))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── 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))
- │ │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (96,2)-(96,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:baz, :bor]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── 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))
- │ │ │ ├── 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))
- │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (100,2)-(100,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:baz, :bor, :block]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ └── name: :bar
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (103,13)-(103,23))
- │ │ │ ├── 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))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (108,2)-(108,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:block]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── name: :bar
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (111,13)-(111,19))
- │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :baz
- │ │ ├── message_loc: (117,2)-(117,5) = "baz"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── name: :bar
- │ │ │ │ └── name_loc: (123,8)-(123,12) = "bar:"
- │ │ │ └── @ OptionalKeywordParameterNode (location: (123,14)-(123,26))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ ├── opening_loc: (127,2)-(127,12) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (128,0)-(128,4))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (128,7)-(129,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── closing_loc: (129,0)-(130,0) = " HEREDOC\n"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index f2a19370e5..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/defined.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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
- │ │ │ └── @ IntegerNode (location: (3,23)-(3,24))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index 8b8dcf2f28..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/defs.txt
+++ /dev/null
@@ -1,369 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (5,2)-(5,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :baz
- │ │ ├── message_loc: (10,2)-(10,5) = "baz"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (14,2)-(14,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ │ ├── 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]
- │ │ │ ├── locals_body_index: 1
- │ │ │ ├── parameters:
- │ │ │ │ @ BlockParametersNode (location: (17,11)-(17,16))
- │ │ │ │ ├── parameters:
- │ │ │ │ │ @ ParametersNode (location: (17,12)-(17,15))
- │ │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ │ └── @ RequiredParameterNode (location: (17,12)-(17,15))
- │ │ │ │ │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (19,2)-(19,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :bar
- │ │ ├── message_loc: (23,2)-(23,5) = "bar"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :baz
- │ │ ├── message_loc: (27,2)-(27,5) = "baz"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :baz
- │ │ ├── message_loc: (31,2)-(31,5) = "baz"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :baz
- │ │ ├── message_loc: (35,2)-(35,5) = "baz"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :baz
- │ ├── message_loc: (39,2)-(39,5) = "baz"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index f4fbe11140..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/dstr.txt
+++ /dev/null
@@ -1,340 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ │ │ ├── opening_loc: (5,2)-(5,12) = "<<-HEREDOC"
- │ │ │ ├── parts: (length: 3)
- │ │ │ │ ├── @ StringNode (location: (6,0)-(7,0))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ ├── 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))
- │ ├── opening_loc: (12,0)-(12,10) = "<<-HEREDOC"
- │ ├── parts: (length: 7)
- │ │ ├── @ StringNode (location: (13,0)-(14,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ ├── opening_loc: (22,0)-(22,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (22,1)-(22,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ ├── opening_loc: (23,0)-(23,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (23,1)-(23,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ ├── opening_loc: (24,0)-(24,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (24,1)-(24,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ ├── opening_loc: (25,0)-(25,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (25,1)-(25,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ │ ├── opening_loc: (27,9)-(27,19) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (28,0)-(28,4))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ └── closing_loc: (28,8)-(28,9) = "}"
- │ │ │ └── @ StringNode (location: (28,9)-(29,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (31,4)-(31,14) = "<<-HEREDOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (32,0)-(32,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- ├── 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))
- │ ├── opening_loc: (34,4)-(34,14) = "<<-HEREDOC"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (35,0)-(35,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (34,18)-(34,21))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (34,19)-(34,20))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (34,19)-(34,20))
- │ │ │ └── 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
deleted file mode 100644
index 3a21ce5559..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/empty.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-@ 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
deleted file mode 100644
index 838b4bf6f0..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-@ 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
deleted file mode 100644
index 45b2ed0c94..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/flipflop.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-@ ProgramNode (location: (1,0)-(6,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(6,3))
- └── body: (length: 2)
- ├── @ 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
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ ├── 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"
diff --git a/test/prism/snapshots/unparser/corpus/literal/for.txt b/test/prism/snapshots/unparser/corpus/literal/for.txt
deleted file mode 100644
index 626a97fe55..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/for.txt
+++ /dev/null
@@ -1,171 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 0ff57fb213..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/hookexe.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 7b6300b85a..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/if.txt
+++ /dev/null
@@ -1,280 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (5,2)-(5,3))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (5,2)-(5,3))
- │ │ └── flags: decimal
- │ ├── 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
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (8,2)-(8,3))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (8,2)-(8,3))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── 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
- │ ├── 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
- │ ├── then_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (16,2)-(16,3))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (16,2)-(16,3))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (31,9)-(31,15))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (31,10)-(31,14))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (31,10)-(31,14))
- │ │ │ │ └── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index ed148fff8b..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt
+++ /dev/null
@@ -1,491 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index a8b58e5574..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/lambda.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-@ ProgramNode (location: (1,0)-(13,1))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(13,1))
- └── body: (length: 6)
- ├── @ CallNode (location: (1,0)-(2,1))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,7)-(1,8) = "{"
- │ └── closing_loc: (2,0)-(2,1) = "}"
- ├── @ CallNode (location: (3,0)-(5,1))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (3,9)-(3,15))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (3,10)-(3,14))
- │ │ │ ├── requireds: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (3,10)-(3,11))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (3,13)-(3,14))
- │ │ │ │ └── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (10,6)-(10,7))
- │ │ │ │ └── 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ └── @ RequiredParameterNode (location: (12,6)-(12,7))
- │ │ │ └── name: :b
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── locals: (length: 1)
- │ │ └── @ BlockLocalVariableNode (location: (12,9)-(12,10))
- │ │ └── 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
deleted file mode 100644
index 21ae9f670b..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/literal.txt
+++ /dev/null
@@ -1,1144 +0,0 @@
-@ 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: ∅
- │ │ │ │ ├── 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))
- │ │ │ │ ├── opening_loc: (1,11)-(1,21) = "<<-HEREDOC"
- │ │ │ │ ├── parts: (length: 3)
- │ │ │ │ │ ├── @ StringNode (location: (2,0)-(2,2))
- │ │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ │ │ ├── opening_loc: (6,2)-(6,12) = "<<-HEREDOC"
- │ │ │ ├── parts: (length: 3)
- │ │ │ │ ├── @ StringNode (location: (7,0)-(7,2))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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))
- │ │ │ │ ├── opening_loc: (10,11)-(10,21) = "<<-HEREDOC"
- │ │ │ │ ├── parts: (length: 3)
- │ │ │ │ │ ├── @ StringNode (location: (11,0)-(11,2))
- │ │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ ├── 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))
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- ├── @ CallNode (location: (16,0)-(16,3))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ IntegerNode (location: (16,1)-(16,3))
- │ │ └── flags: decimal
- │ ├── call_operator_loc: ∅
- │ ├── name: :+@
- │ ├── message_loc: (16,0)-(16,1) = "+"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ IntegerNode (location: (17,0)-(17,1))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (18,0)-(18,1))
- │ └── flags: decimal
- ├── @ RationalNode (location: (19,0)-(19,2))
- │ └── numeric:
- │ @ IntegerNode (location: (19,0)-(19,1))
- │ └── flags: decimal
- ├── @ RationalNode (location: (20,0)-(20,4))
- │ └── numeric:
- │ @ FloatNode (location: (20,0)-(20,3))
- ├── @ RationalNode (location: (21,0)-(21,4))
- │ └── numeric:
- │ @ FloatNode (location: (21,0)-(21,3))
- ├── @ ImaginaryNode (location: (22,0)-(22,2))
- │ └── numeric:
- │ @ IntegerNode (location: (22,0)-(22,1))
- │ └── flags: decimal
- ├── @ ImaginaryNode (location: (23,0)-(23,3))
- │ └── numeric:
- │ @ IntegerNode (location: (23,0)-(23,2))
- │ └── flags: decimal
- ├── @ ImaginaryNode (location: (24,0)-(24,4))
- │ └── numeric:
- │ @ FloatNode (location: (24,0)-(24,3))
- ├── @ ImaginaryNode (location: (25,0)-(25,5))
- │ └── numeric:
- │ @ FloatNode (location: (25,0)-(25,4))
- ├── @ ImaginaryNode (location: (26,0)-(26,32))
- │ └── numeric:
- │ @ IntegerNode (location: (26,0)-(26,31))
- │ └── flags: decimal
- ├── @ ImaginaryNode (location: (27,0)-(27,3))
- │ └── numeric:
- │ @ RationalNode (location: (27,0)-(27,2))
- │ └── numeric:
- │ @ IntegerNode (location: (27,0)-(27,1))
- │ └── flags: decimal
- ├── @ InterpolatedStringNode (location: (28,0)-(28,11))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (28,0)-(28,5))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (29,0)-(29,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (29,1)-(29,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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))
- │ ├── opening_loc: (30,0)-(30,1) = "\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (30,1)-(30,4))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ └── closing_loc: (30,7)-(30,8) = "}"
- │ │ └── @ StringNode (location: (30,8)-(30,11))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (31,0)-(31,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (31,1)-(31,5))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (32,4)-(32,8) = "\\\#{}"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "\#{}"
- │ └── closing_loc: (32,8)-(32,9) = "\""
- ├── @ InterpolatedStringNode (location: (33,0)-(33,9))
- │ ├── opening_loc: (33,0)-(33,1) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (33,1)-(33,5))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── opening_loc: (43,0)-(43,1) = ":"
- │ ├── value_loc: (43,1)-(43,4) = "foo"
- │ ├── closing_loc: ∅
- │ └── unescaped: "foo"
- ├── @ SymbolNode (location: (44,0)-(44,6))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ ├── opening_loc: (45,0)-(45,1) = ":"
- │ ├── value_loc: (45,1)-(45,4) = "foo"
- │ ├── closing_loc: ∅
- │ └── unescaped: "foo"
- ├── @ SymbolNode (location: (46,0)-(46,6))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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
- │ ├── 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
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ │ │ ├── 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))
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── opening_loc: (60,0)-(60,1) = "("
- │ │ └── closing_loc: (60,10)-(60,11) = ")"
- │ ├── right:
- │ │ @ IntegerNode (location: (60,13)-(60,14))
- │ │ └── flags: decimal
- │ └── operator_loc: (60,11)-(60,13) = ".."
- ├── @ RangeNode (location: (61,0)-(61,14))
- │ ├── flags: ∅
- │ ├── left:
- │ │ @ IntegerNode (location: (61,0)-(61,1))
- │ │ └── flags: decimal
- │ ├── 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))
- │ │ │ ├── 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))
- │ │ │ ├── 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))
- │ │ │ ├── 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))
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ ├── opening_loc: (62,0)-(62,1) = "("
- │ │ └── closing_loc: (62,10)-(62,11) = ")"
- │ ├── right:
- │ │ @ IntegerNode (location: (62,13)-(62,16))
- │ │ └── flags: decimal
- │ └── operator_loc: (62,11)-(62,13) = ".."
- ├── @ FloatNode (location: (63,0)-(63,4))
- ├── @ FloatNode (location: (64,0)-(64,3))
- ├── @ ArrayNode (location: (65,0)-(65,6))
- │ ├── flags: ∅
- │ ├── elements: (length: 2)
- │ │ ├── @ IntegerNode (location: (65,1)-(65,2))
- │ │ │ └── flags: decimal
- │ │ └── @ IntegerNode (location: (65,4)-(65,5))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ ├── @ 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
- │ │ ├── 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
- │ ├── 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
- │ │ └── @ 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
- │ ├── 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:
- │ │ │ @ IntegerNode (location: (74,7)-(74,8))
- │ │ │ └── flags: decimal
- │ │ └── 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:
- │ │ │ │ @ IntegerNode (location: (75,7)-(75,8))
- │ │ │ │ └── flags: decimal
- │ │ │ └── operator_loc: (75,4)-(75,6) = "=>"
- │ │ └── @ AssocNode (location: (75,10)-(75,16))
- │ │ ├── key:
- │ │ │ @ IntegerNode (location: (75,10)-(75,11))
- │ │ │ └── flags: decimal
- │ │ ├── value:
- │ │ │ @ IntegerNode (location: (75,15)-(75,16))
- │ │ │ └── flags: decimal
- │ │ └── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── keyword_loc: (76,8)-(76,14) = "rescue"
- │ │ │ │ │ └── rescue_expression:
- │ │ │ │ │ @ CallNode (location: (76,15)-(76,18))
- │ │ │ │ │ ├── flags: variable_call
- │ │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── operator_loc: ∅
- │ │ └── @ AssocNode (location: (77,8)-(77,12))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (77,8)-(77,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ ├── opening_loc: (80,2)-(80,3) = ":"
- │ │ │ ├── value_loc: (80,3)-(80,5) = "-@"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "-@"
- │ │ ├── value:
- │ │ │ @ IntegerNode (location: (80,9)-(80,10))
- │ │ │ └── flags: decimal
- │ │ └── operator_loc: (80,6)-(80,8) = "=>"
- │ └── closing_loc: (80,11)-(80,12) = "}"
- ├── @ InterpolatedStringNode (location: (81,0)-(82,7))
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (84,2)-(85,7))
- │ │ └── body: (length: 1)
- │ │ └── @ InterpolatedStringNode (location: (84,2)-(85,7))
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 71621f5a29..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/module.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: (14,4)-(14,5) = ":"
- │ │ ├── value_loc: (14,5)-(14,8) = "bar"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "bar"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index cf7de993c1..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
+++ /dev/null
@@ -1,489 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- ├── @ 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
- ├── @ 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
- ├── @ 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
- ├── @ 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
- ├── @ 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
- │ ├── 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
- ├── @ 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
- │ │ ├── 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
- ├── @ 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
- │ │ ├── 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
- ├── @ 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
- │ │ ├── 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
- ├── @ 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
- │ │ ├── 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
- ├── @ 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
- │ │ ├── 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
- ├── @ 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- └── @ CallOperatorWriteNode (location: (24,0)-(24,10))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (24,0)-(24,3))
- │ ├── flags: variable_call
- │ ├── 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
diff --git a/test/prism/snapshots/unparser/corpus/literal/pattern.txt b/test/prism/snapshots/unparser/corpus/literal/pattern.txt
deleted file mode 100644
index 8aa64face6..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/pattern.txt
+++ /dev/null
@@ -1,424 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ │ │ └── @ IntegerNode (location: (2,8)-(2,9))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ │ └── @ IntegerNode (location: (4,7)-(4,8))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ │ ├── value_loc: (6,5)-(6,6) = "x"
- │ │ │ │ │ │ ├── closing_loc: (6,6)-(6,7) = ":"
- │ │ │ │ │ │ └── unescaped: "x"
- │ │ │ │ │ ├── value: ∅
- │ │ │ │ │ └── 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: ∅
- │ │ │ │ │ │ │ ├── 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
- │ │ │ │ │ │ └── operator_loc: ∅
- │ │ │ │ │ └── @ AssocNode (location: (14,10)-(14,15))
- │ │ │ │ │ ├── key:
- │ │ │ │ │ │ @ SymbolNode (location: (14,10)-(14,13))
- │ │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ └── 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: ∅
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ └── 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
- │ │ │ │ ├── right:
- │ │ │ │ │ @ IntegerNode (location: (22,7)-(22,8))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ └── @ IntegerNode (location: (35,8)-(35,9))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 49a790c20f..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/pragma.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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))
- │ └── filepath: "unparser/corpus/literal/pragma.txt"
- ├── @ SourceLineNode (location: (3,0)-(3,8))
- └── @ CallNode (location: (4,0)-(4,7))
- ├── flags: variable_call
- ├── 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
deleted file mode 100644
index 5bf208d962..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/range.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── right:
- │ │ @ IntegerNode (location: (2,3)-(2,4))
- │ │ └── flags: decimal
- │ └── 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
- │ │ ├── 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
- ├── right:
- │ @ IntegerNode (location: (4,4)-(4,5))
- │ └── flags: decimal
- └── 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
deleted file mode 100644
index 80fd34f321..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/rescue.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index a96937e87e..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/send.txt
+++ /dev/null
@@ -1,2183 +0,0 @@
-@ 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
- │ │ │ │ ├── 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
- │ │ │ └── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── message_loc: (18,5)-(18,8) = "bar"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ └── 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
- │ │ │ ├── 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
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── message_loc: (21,5)-(21,8) = "bar"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block: ∅
- │ │ │ └── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ ├── right:
- │ │ │ │ @ IntegerNode (location: (38,4)-(38,5))
- │ │ │ │ └── flags: decimal
- │ │ │ └── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ ├── right:
- │ │ @ CallNode (location: (42,3)-(42,8))
- │ │ ├── flags: ∅
- │ │ ├── receiver:
- │ │ │ @ IntegerNode (location: (42,3)-(42,4))
- │ │ │ └── flags: decimal
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ └── @ IntegerNode (location: (54,7)-(54,8))
- │ │ └── flags: decimal
- │ ├── closing_loc: (54,8)-(54,9) = ")"
- │ └── block: ∅
- ├── @ CallNode (location: (55,0)-(55,8))
- │ ├── flags: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (63,8)-(63,16))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (63,8)-(63,12))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (70,4)-(70,8))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (70,4)-(70,6))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (71,6)-(71,10))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (71,6)-(71,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (74,7)-(74,8))
- │ │ └── flags: decimal
- │ ├── closing_loc: (74,8)-(74,9) = "]"
- │ └── block: ∅
- ├── @ CallNode (location: (75,0)-(75,5))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (75,0)-(75,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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: ∅
- │ ├── 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
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 2099e84209..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/since/27.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 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
- │ └── 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
deleted file mode 100644
index f595ebb780..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/since/30.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index d5bc8d0903..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/since/31.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ │ ├── 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: [:&]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ └── name: :a
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block:
- │ @ BlockParameterNode (location: (5,11)-(5,12))
- │ ├── 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: ∅
- │ ├── 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, :&]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 85d8e595b4..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/since/32.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-@ 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,20))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,8)-(1,16))
- │ │ │ └── name: :argument
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest:
- │ │ │ @ KeywordRestParameterNode (location: (1,18)-(1,20))
- │ │ │ ├── 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: ∅
- │ │ ├── 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, :**]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ └── name: :argument
- │ ├── optionals: (length: 0)
- │ ├── rest:
- │ │ @ RestParameterNode (location: (5,18)-(5,19))
- │ │ ├── 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: ∅
- │ ├── 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, :*]
- ├── locals_body_index: 2
- ├── 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"
diff --git a/test/prism/snapshots/unparser/corpus/literal/singletons.txt b/test/prism/snapshots/unparser/corpus/literal/singletons.txt
deleted file mode 100644
index 45c06f7b07..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/singletons.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-@ 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
deleted file mode 100644
index c4f3c0efca..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/super.txt
+++ /dev/null
@@ -1,282 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (8,2)-(8,5))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (8,2)-(8,5))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (11,2)-(11,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (11,2)-(11,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (14,2)-(14,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (14,2)-(14,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (17,2)-(17,5))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (17,2)-(17,5))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (20,2)-(20,5))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (20,2)-(20,5))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index 97eec0c01e..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/unary.txt
+++ /dev/null
@@ -1,245 +0,0 @@
-@ 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
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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
- │ │ │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ │ ├── 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
deleted file mode 100644
index 4133ea0a34..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/undef.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: (2,6)-(2,7) = ":"
- │ │ ├── value_loc: (2,7)-(2,10) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ └── @ SymbolNode (location: (2,12)-(2,16))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index a667bc7e8b..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/variables.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 5c1bae8281..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/while.txt
+++ /dev/null
@@ -1,705 +0,0 @@
-@ 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: ∅
- │ │ ├── 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]
- │ │ ├── locals_body_index: 1
- │ │ ├── parameters:
- │ │ │ @ BlockParametersNode (location: (2,8)-(2,13))
- │ │ │ ├── parameters:
- │ │ │ │ @ ParametersNode (location: (2,9)-(2,12))
- │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ └── @ RequiredParameterNode (location: (2,9)-(2,12))
- │ │ │ │ │ └── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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]
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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]
- │ │ ├── locals_body_index: 1
- │ │ ├── parameters:
- │ │ │ @ BlockParametersNode (location: (28,9)-(28,14))
- │ │ │ ├── parameters:
- │ │ │ │ @ ParametersNode (location: (28,10)-(28,13))
- │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ └── @ RequiredParameterNode (location: (28,10)-(28,13))
- │ │ │ │ │ └── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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]
- │ │ ├── locals_body_index: 1
- │ │ ├── parameters:
- │ │ │ @ BlockParametersNode (location: (36,9)-(36,14))
- │ │ │ ├── parameters:
- │ │ │ │ @ ParametersNode (location: (36,10)-(36,13))
- │ │ │ │ ├── requireds: (length: 1)
- │ │ │ │ │ └── @ RequiredParameterNode (location: (36,10)-(36,13))
- │ │ │ │ │ └── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- ├── @ 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: ∅
- │ ├── 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
- └── @ 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- ├── 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
deleted file mode 100644
index a1c0f25855..0000000000
--- a/test/prism/snapshots/unparser/corpus/literal/yield.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index c0682a5ecb..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/and.txt
+++ /dev/null
@@ -1,235 +0,0 @@
-@ 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index 9f490a4ce7..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/block.txt
+++ /dev/null
@@ -1,195 +0,0 @@
-@ ProgramNode (location: (1,0)-(26,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(26,3))
- └── body: (length: 6)
- ├── @ CallNode (location: (1,0)-(2,3))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,4)-(1,6) = "do"
- │ └── closing_loc: (2,0)-(2,3) = "end"
- ├── @ CallNode (location: (4,0)-(6,3))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ BeginNode (location: (5,0)-(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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (13,7)-(13,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (13,8)-(13,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (13,8)-(13,9))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (16,15)-(16,18))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (16,16)-(16,17))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (16,16)-(16,17))
- │ │ │ │ └── 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (25,2)-(25,3))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (25,2)-(25,3))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index 1219d65b4d..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/def.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-@ 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 5ab954b6d4..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/dstr.txt
+++ /dev/null
@@ -1,570 +0,0 @@
-@ 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))
- │ ├── opening_loc: (21,0)-(21,5) = "<<DOC"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (22,0)-(23,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (26,0)-(26,6) = "<<~DOC"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (27,0)-(28,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (31,0)-(31,6) = "<<~DOC"
- │ ├── parts: (length: 4)
- │ │ ├── @ StringNode (location: (32,0)-(33,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (33,5)-(34,0) = "\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (34,0)-(35,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (37,0)-(37,6) = "<<~DOC"
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (38,0)-(39,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (38,0)-(39,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (39,0)-(40,0))
- │ │ ├── flags: ∅
- │ │ ├── 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))
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (63,0)-(63,5) = "<<DOC"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (64,0)-(64,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (68,0)-(68,5) = "<<DOC"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (69,0)-(69,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── 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: ∅
- │ │ ├── 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))
- │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ │ ├── opening_loc: (84,2)-(84,8) = "<<~DOC"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (85,0)-(85,5))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ │ ├── 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: ∅
- │ │ │ ├── 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))
- │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (105,0)-(105,2) = "%("
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (105,2)-(105,5))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (107,0)-(107,3) = "%Q("
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (107,3)-(107,7))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (109,0)-(109,1) = "\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (109,1)-(110,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (113,0)-(113,1) = "\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (113,1)-(113,4))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (116,0)-(116,1) = "\""
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (116,1)-(117,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (119,0)-(119,3))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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))
- │ │ ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (122,0)-(122,2))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ InterpolatedStringNode (location: (124,0)-(124,8))
- │ │ │ ├── opening_loc: (124,0)-(124,1) = "\""
- │ │ │ ├── parts: (length: 2)
- │ │ │ │ ├── @ StringNode (location: (124,1)-(124,2))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ InterpolatedStringNode (location: (125,0)-(125,6))
- │ │ │ ├── opening_loc: (125,0)-(125,1) = "\""
- │ │ │ ├── parts: (length: 2)
- │ │ │ │ ├── @ StringNode (location: (125,1)-(125,2))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ InterpolatedStringNode (location: (126,0)-(126,6))
- │ │ │ ├── opening_loc: (126,0)-(126,1) = "\""
- │ │ │ ├── parts: (length: 2)
- │ │ │ │ ├── @ StringNode (location: (126,1)-(126,2))
- │ │ │ │ │ ├── flags: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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))
- ├── opening_loc: ∅
- ├── parts: (length: 2)
- │ ├── @ InterpolatedStringNode (location: (127,0)-(127,7))
- │ │ ├── opening_loc: (127,0)-(127,1) = "\""
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (127,1)-(127,2))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index e87557841f..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/kwbegin.txt
+++ /dev/null
@@ -1,259 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index c4bb54a9ec..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/literal.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-@ 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))
- ├── @ RationalNode (location: (2,0)-(2,3))
- │ └── numeric:
- │ @ IntegerNode (location: (2,0)-(2,2))
- │ └── flags: decimal
- ├── @ IntegerNode (location: (3,0)-(3,3))
- │ └── flags: hexadecimal
- ├── @ IntegerNode (location: (4,0)-(4,5))
- │ └── flags: decimal
- ├── @ FloatNode (location: (5,0)-(5,4))
- ├── @ FloatNode (location: (6,0)-(6,14))
- ├── @ FloatNode (location: (7,0)-(7,15))
- ├── @ 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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))
- ├── @ FloatNode (location: (13,0)-(13,17))
- └── @ CallNode (location: (14,0)-(14,10))
- ├── flags: ∅
- ├── 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: ∅
- │ ├── 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
- │ │ ├── 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/send.txt b/test/prism/snapshots/unparser/corpus/semantic/send.txt
deleted file mode 100644
index 8cb28a8e57..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/send.txt
+++ /dev/null
@@ -1,162 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ ├── 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
- │ ├── 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 1578260a64..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/undef.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (2,6)-(2,9) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ └── @ SymbolNode (location: (2,11)-(2,14))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 23466c147e..0000000000
--- a/test/prism/snapshots/unparser/corpus/semantic/while.txt
+++ /dev/null
@@ -1,281 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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
- │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (17,2)-(17,3))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (17,2)-(17,3))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index ed08d06df2..0000000000
--- a/test/prism/snapshots/until.txt
+++ /dev/null
@@ -1,141 +0,0 @@
-@ 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
- ├── @ 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
- ├── @ UntilNode (location: (5,0)-(5,16))
- │ ├── flags: ∅
- │ ├── keyword_loc: (5,6)-(5,11) = "until"
- │ ├── closing_loc: ∅
- │ ├── predicate:
- │ │ @ TrueNode (location: (5,12)-(5,16))
- │ └── statements:
- │ @ StatementsNode (location: (5,0)-(5,5))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (5,0)-(5,5))
- │ ├── arguments: ∅
- │ └── keyword_loc: (5,0)-(5,5) = "break"
- ├── @ UntilNode (location: (7,0)-(7,15))
- │ ├── flags: ∅
- │ ├── keyword_loc: (7,5)-(7,10) = "until"
- │ ├── closing_loc: ∅
- │ ├── predicate:
- │ │ @ TrueNode (location: (7,11)-(7,15))
- │ └── statements:
- │ @ StatementsNode (location: (7,0)-(7,4))
- │ └── body: (length: 1)
- │ └── @ NextNode (location: (7,0)-(7,4))
- │ ├── arguments: ∅
- │ └── keyword_loc: (7,0)-(7,4) = "next"
- ├── @ 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (11,4)-(11,5) = ":"
- │ │ │ ├── value_loc: (11,5)-(11,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (11,8)-(11,10))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index f8134aeab6..0000000000
--- a/test/prism/snapshots/variables.txt
+++ /dev/null
@@ -1,379 +0,0 @@
-@ 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
- │ └── 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
- ├── @ 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
- │ │ │ └── @ IntegerNode (location: (7,11)-(7,12))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ └── 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
- │ └── operator_loc: (15,5)-(15,6) = "="
- ├── @ CallNode (location: (17,0)-(17,1))
- │ ├── flags: variable_call
- │ ├── 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
- │ └── 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
- ├── @ 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
- │ │ │ └── @ IntegerNode (location: (23,10)-(23,11))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- ├── @ 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
- │ │ │ └── @ IntegerNode (location: (27,10)-(27,11))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ └── 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
- │ │ │ └── @ IntegerNode (location: (29,18)-(29,19))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (31,9)-(31,10))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ └── @ IntegerNode (location: (33,12)-(33,13))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (35,10)-(35,11))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (37,15)-(37,16))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ ArrayNode (location: (39,21)-(39,27))
- │ │ ├── flags: ∅
- │ │ ├── elements: (length: 2)
- │ │ │ ├── @ IntegerNode (location: (39,22)-(39,23))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ IntegerNode (location: (39,25)-(39,26))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (43,9)-(43,10))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index d86d8b8033..0000000000
--- a/test/prism/snapshots/while.txt
+++ /dev/null
@@ -1,365 +0,0 @@
-@ 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
- ├── @ 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
- ├── @ WhileNode (location: (5,0)-(5,16))
- │ ├── flags: ∅
- │ ├── keyword_loc: (5,6)-(5,11) = "while"
- │ ├── closing_loc: ∅
- │ ├── predicate:
- │ │ @ TrueNode (location: (5,12)-(5,16))
- │ └── statements:
- │ @ StatementsNode (location: (5,0)-(5,5))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (5,0)-(5,5))
- │ ├── arguments: ∅
- │ └── keyword_loc: (5,0)-(5,5) = "break"
- ├── @ WhileNode (location: (7,0)-(7,15))
- │ ├── flags: ∅
- │ ├── keyword_loc: (7,5)-(7,10) = "while"
- │ ├── closing_loc: ∅
- │ ├── predicate:
- │ │ @ TrueNode (location: (7,11)-(7,15))
- │ └── statements:
- │ @ StatementsNode (location: (7,0)-(7,4))
- │ └── body: (length: 1)
- │ └── @ NextNode (location: (7,0)-(7,4))
- │ ├── arguments: ∅
- │ └── keyword_loc: (7,0)-(7,4) = "next"
- ├── @ 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── opening_loc: (11,4)-(11,5) = ":"
- │ │ │ ├── value_loc: (11,5)-(11,6) = "a"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a"
- │ │ └── @ SymbolNode (location: (11,8)-(11,10))
- │ │ ├── flags: ∅
- │ │ ├── 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,50))
- │ ├── flags: ∅
- │ ├── keyword_loc: (13,0)-(13,5) = "while"
- │ ├── closing_loc: (13,47)-(13,50) = "end"
- │ ├── predicate:
- │ │ @ DefNode (location: (13,6)-(13,38))
- │ │ ├── name: :foo
- │ │ ├── name_loc: (13,15)-(13,18) = "foo"
- │ │ ├── receiver:
- │ │ │ @ SelfNode (location: (13,10)-(13,14))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (13,19)-(13,33))
- │ │ │ ├── requireds: (length: 0)
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (13,19)-(13,33))
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── name_loc: (13,19)-(13,20) = "a"
- │ │ │ │ ├── operator_loc: (13,21)-(13,22) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ CallNode (location: (13,23)-(13,33))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (13,23)-(13,26) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (13,27)-(13,33))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (13,27)-(13,29) = "do"
- │ │ │ │ └── closing_loc: (13,30)-(13,33) = "end"
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── body: ∅
- │ │ ├── locals: [:a]
- │ │ ├── locals_body_index: 1
- │ │ ├── def_keyword_loc: (13,6)-(13,9) = "def"
- │ │ ├── operator_loc: (13,14)-(13,15) = "."
- │ │ ├── lparen_loc: ∅
- │ │ ├── rparen_loc: ∅
- │ │ ├── equal_loc: ∅
- │ │ └── end_keyword_loc: (13,35)-(13,38) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (13,40)-(13,45))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (13,40)-(13,45))
- │ ├── arguments: ∅
- │ └── keyword_loc: (13,40)-(13,45) = "break"
- ├── @ WhileNode (location: (15,0)-(15,47))
- │ ├── flags: ∅
- │ ├── keyword_loc: (15,0)-(15,5) = "while"
- │ ├── closing_loc: (15,44)-(15,47) = "end"
- │ ├── predicate:
- │ │ @ ClassNode (location: (15,6)-(15,35))
- │ │ ├── locals: [:a]
- │ │ ├── class_keyword_loc: (15,6)-(15,11) = "class"
- │ │ ├── constant_path:
- │ │ │ @ ConstantReadNode (location: (15,12)-(15,15))
- │ │ │ └── name: :Foo
- │ │ ├── inheritance_operator_loc: ∅
- │ │ ├── superclass: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (15,16)-(15,30))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ LocalVariableWriteNode (location: (15,16)-(15,30))
- │ │ │ ├── name: :a
- │ │ │ ├── depth: 0
- │ │ │ ├── name_loc: (15,16)-(15,17) = "a"
- │ │ │ ├── value:
- │ │ │ │ @ CallNode (location: (15,20)-(15,30))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (15,20)-(15,23) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (15,24)-(15,30))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (15,24)-(15,26) = "do"
- │ │ │ │ └── closing_loc: (15,27)-(15,30) = "end"
- │ │ │ └── operator_loc: (15,18)-(15,19) = "="
- │ │ ├── end_keyword_loc: (15,32)-(15,35) = "end"
- │ │ └── name: :Foo
- │ └── statements:
- │ @ StatementsNode (location: (15,37)-(15,42))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (15,37)-(15,42))
- │ ├── arguments: ∅
- │ └── keyword_loc: (15,37)-(15,42) = "break"
- ├── @ WhileNode (location: (17,0)-(17,48))
- │ ├── flags: ∅
- │ ├── keyword_loc: (17,0)-(17,5) = "while"
- │ ├── closing_loc: (17,45)-(17,48) = "end"
- │ ├── predicate:
- │ │ @ SingletonClassNode (location: (17,6)-(17,36))
- │ │ ├── locals: []
- │ │ ├── class_keyword_loc: (17,6)-(17,11) = "class"
- │ │ ├── operator_loc: (17,12)-(17,14) = "<<"
- │ │ ├── expression:
- │ │ │ @ SelfNode (location: (17,15)-(17,19))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (17,21)-(17,31))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (17,21)-(17,31))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :tap
- │ │ │ ├── message_loc: (17,21)-(17,24) = "tap"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block:
- │ │ │ @ BlockNode (location: (17,25)-(17,31))
- │ │ │ ├── locals: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body: ∅
- │ │ │ ├── opening_loc: (17,25)-(17,27) = "do"
- │ │ │ └── closing_loc: (17,28)-(17,31) = "end"
- │ │ └── end_keyword_loc: (17,33)-(17,36) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (17,38)-(17,43))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (17,38)-(17,43))
- │ ├── arguments: ∅
- │ └── keyword_loc: (17,38)-(17,43) = "break"
- ├── @ WhileNode (location: (19,0)-(19,52))
- │ ├── flags: ∅
- │ ├── keyword_loc: (19,0)-(19,5) = "while"
- │ ├── closing_loc: (19,49)-(19,52) = "end"
- │ ├── predicate:
- │ │ @ SingletonClassNode (location: (19,6)-(19,40))
- │ │ ├── locals: [:a]
- │ │ ├── class_keyword_loc: (19,6)-(19,11) = "class"
- │ │ ├── operator_loc: (19,12)-(19,14) = "<<"
- │ │ ├── expression:
- │ │ │ @ SelfNode (location: (19,15)-(19,19))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (19,21)-(19,35))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ LocalVariableWriteNode (location: (19,21)-(19,35))
- │ │ │ ├── name: :a
- │ │ │ ├── depth: 0
- │ │ │ ├── name_loc: (19,21)-(19,22) = "a"
- │ │ │ ├── value:
- │ │ │ │ @ CallNode (location: (19,25)-(19,35))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (19,25)-(19,28) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (19,29)-(19,35))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (19,29)-(19,31) = "do"
- │ │ │ │ └── closing_loc: (19,32)-(19,35) = "end"
- │ │ │ └── operator_loc: (19,23)-(19,24) = "="
- │ │ └── end_keyword_loc: (19,37)-(19,40) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (19,42)-(19,47))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (19,42)-(19,47))
- │ ├── arguments: ∅
- │ └── keyword_loc: (19,42)-(19,47) = "break"
- ├── @ 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body: ∅
- │ │ │ ├── opening_loc: (21,20)-(21,22) = "do"
- │ │ │ └── closing_loc: (21,23)-(21,26) = "end"
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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
- ├── 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
deleted file mode 100644
index 1b223bd8fe..0000000000
--- a/test/prism/snapshots/whitequark/__ENCODING__.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 1b223bd8fe..0000000000
--- a/test/prism/snapshots/whitequark/__ENCODING___legacy_.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 6c529a3589..0000000000
--- a/test/prism/snapshots/whitequark/alias.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index d13f816555..0000000000
--- a/test/prism/snapshots/whitequark/alias_gvar.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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
deleted file mode 100644
index 535266c325..0000000000
--- a/test/prism/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 35b1c43dd0..0000000000
--- a/test/prism/snapshots/whitequark/and.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 789ba792f2..0000000000
--- a/test/prism/snapshots/whitequark/and_asgn.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- └── @ IndexAndWriteNode (location: (3,0)-(3,15))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (3,0)-(3,3))
- │ ├── flags: variable_call
- │ ├── 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
- │ └── @ IntegerNode (location: (3,7)-(3,8))
- │ └── flags: decimal
- ├── closing_loc: (3,8)-(3,9) = "]"
- ├── block: ∅
- ├── operator_loc: (3,10)-(3,13) = "&&="
- └── value:
- @ IntegerNode (location: (3,14)-(3,15))
- └── flags: decimal
diff --git a/test/prism/snapshots/whitequark/and_or_masgn.txt b/test/prism/snapshots/whitequark/and_or_masgn.txt
deleted file mode 100644
index d1a349619b..0000000000
--- a/test/prism/snapshots/whitequark/and_or_masgn.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index dea08d7e73..0000000000
--- a/test/prism/snapshots/whitequark/anonymous_blockarg.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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))
- │ ├── 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: ∅
- │ ├── 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: [:&]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 8e3cd2ec69..0000000000
--- a/test/prism/snapshots/whitequark/arg.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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))
- │ │ │ └── name: :foo
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:foo]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── name: :foo
- │ │ └── @ RequiredParameterNode (location: (3,11)-(3,14))
- │ │ └── name: :bar
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:foo, :bar]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 11a3bcc986..0000000000
--- a/test/prism/snapshots/whitequark/arg_duplicate_ignored.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ 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))
- │ │ │ │ └── name: :_
- │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
- │ │ │ └── name: :_
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:_]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── name: :_a
- │ │ └── @ RequiredParameterNode (location: (3,12)-(3,14))
- │ │ └── name: :_a
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:_a]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 4e45db5d6c..0000000000
--- a/test/prism/snapshots/whitequark/arg_label.txt
+++ /dev/null
@@ -1,118 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (2,2)-(2,3) = ":"
- │ │ │ ├── value_loc: (2,3)-(2,4) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── opening_loc: (4,11)-(4,12) = ":"
- │ │ │ ├── value_loc: (4,12)-(4,13) = "b"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "b"
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index a27d7dc016..0000000000
--- a/test/prism/snapshots/whitequark/arg_scope.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,7)-(1,11))
- │ ├── parameters: ∅
- │ ├── locals: (length: 1)
- │ │ └── @ BlockLocalVariableNode (location: (1,9)-(1,10))
- │ │ └── 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
deleted file mode 100644
index 3346517743..0000000000
--- a/test/prism/snapshots/whitequark/args.txt
+++ /dev/null
@@ -1,1024 +0,0 @@
-@ 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (1,7)-(1,8) = "b"
- │ │ └── operator_loc: (1,6)-(1,7) = "&"
- │ ├── body: ∅
- │ ├── locals: [:b]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── name: :r
- │ │ │ ├── rights: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (11,12)-(11,13))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── rest:
- │ │ │ │ @ SplatNode (location: (17,11)-(17,13))
- │ │ │ │ ├── operator_loc: (17,11)-(17,12) = "*"
- │ │ │ │ └── expression:
- │ │ │ │ @ RequiredParameterNode (location: (17,12)-(17,13))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ └── name: :a
- │ │ │ ├── rest:
- │ │ │ │ @ SplatNode (location: (19,11)-(19,13))
- │ │ │ │ ├── operator_loc: (19,11)-(19,12) = "*"
- │ │ │ │ └── expression:
- │ │ │ │ @ RequiredParameterNode (location: (19,12)-(19,13))
- │ │ │ │ └── name: :r
- │ │ │ ├── rights: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (19,15)-(19,16))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (21,11)-(21,13))
- │ │ │ │ └── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── name: :foo
- │ │ │ ├── name_loc: (23,7)-(23,11) = "foo:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (23,12)-(23,13))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (23,15)-(23,17))
- │ │ ├── name: :b
- │ │ ├── name_loc: (23,16)-(23,17) = "b"
- │ │ └── operator_loc: (23,15)-(23,16) = "&"
- │ ├── body: ∅
- │ ├── locals: [:foo, :b]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :foo
- │ │ │ │ ├── name_loc: (25,7)-(25,11) = "foo:"
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (25,12)-(25,13))
- │ │ │ │ └── flags: decimal
- │ │ │ └── @ OptionalKeywordParameterNode (location: (25,15)-(25,21))
- │ │ │ ├── name: :bar
- │ │ │ ├── name_loc: (25,15)-(25,19) = "bar:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (25,20)-(25,21))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest:
- │ │ │ @ KeywordRestParameterNode (location: (25,23)-(25,28))
- │ │ │ ├── name: :baz
- │ │ │ ├── name_loc: (25,25)-(25,28) = "baz"
- │ │ │ └── operator_loc: (25,23)-(25,25) = "**"
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (25,30)-(25,32))
- │ │ ├── name: :b
- │ │ ├── name_loc: (25,31)-(25,32) = "b"
- │ │ └── operator_loc: (25,30)-(25,31) = "&"
- │ ├── body: ∅
- │ ├── locals: [:foo, :bar, :baz, :b]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ ├── name: :baz
- │ │ │ ├── name_loc: (27,8)-(27,11) = "baz"
- │ │ │ └── operator_loc: (27,6)-(27,8) = "**"
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (27,13)-(27,15))
- │ │ ├── name: :b
- │ │ ├── name_loc: (27,14)-(27,15) = "b"
- │ │ └── operator_loc: (27,13)-(27,14) = "&"
- │ ├── body: ∅
- │ ├── locals: [:baz, :b]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (29,6)-(29,7) = "*"
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest:
- │ │ │ @ KeywordRestParameterNode (location: (29,9)-(29,11))
- │ │ │ ├── name: ∅
- │ │ │ ├── name_loc: ∅
- │ │ │ └── operator_loc: (29,9)-(29,11) = "**"
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:*, :**]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (31,11)-(31,12) = "b"
- │ │ └── operator_loc: (31,10)-(31,11) = "&"
- │ ├── body: ∅
- │ ├── locals: [:r, :b]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── name: :r
- │ │ │ ├── name_loc: (33,7)-(33,8) = "r"
- │ │ │ └── operator_loc: (33,6)-(33,7) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (33,10)-(33,11))
- │ │ │ └── name: :p
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (33,13)-(33,15))
- │ │ ├── name: :b
- │ │ ├── name_loc: (33,14)-(33,15) = "b"
- │ │ └── operator_loc: (33,13)-(33,14) = "&"
- │ ├── body: ∅
- │ ├── locals: [:r, :p, :b]
- │ ├── locals_body_index: 3
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (37,9)-(37,11))
- │ │ ├── name: :b
- │ │ ├── name_loc: (37,10)-(37,11) = "b"
- │ │ └── operator_loc: (37,9)-(37,10) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :b]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (39,9)-(39,11))
- │ │ │ ├── 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (39,14)-(39,15) = "b"
- │ │ └── operator_loc: (39,13)-(39,14) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :r, :b]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (41,9)-(41,11))
- │ │ │ ├── name: :r
- │ │ │ ├── name_loc: (41,10)-(41,11) = "r"
- │ │ │ └── operator_loc: (41,9)-(41,10) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (41,13)-(41,14))
- │ │ │ └── name: :p
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (41,16)-(41,18))
- │ │ ├── name: :b
- │ │ ├── name_loc: (41,17)-(41,18) = "b"
- │ │ └── operator_loc: (41,16)-(41,17) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :r, :p, :b]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (43,9)-(43,12))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (43,9)-(43,10) = "o"
- │ │ │ ├── operator_loc: (43,10)-(43,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (43,11)-(43,12))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (43,14)-(43,16))
- │ │ ├── name: :b
- │ │ ├── name_loc: (43,15)-(43,16) = "b"
- │ │ └── operator_loc: (43,14)-(43,15) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :o, :b]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (45,9)-(45,12))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (45,9)-(45,10) = "o"
- │ │ │ ├── operator_loc: (45,10)-(45,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (45,11)-(45,12))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (45,14)-(45,16))
- │ │ │ ├── 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (45,19)-(45,20) = "b"
- │ │ └── operator_loc: (45,18)-(45,19) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :o, :r, :b]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (47,9)-(47,12))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (47,9)-(47,10) = "o"
- │ │ │ ├── operator_loc: (47,10)-(47,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (47,11)-(47,12))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (47,14)-(47,16))
- │ │ │ ├── name: :r
- │ │ │ ├── name_loc: (47,15)-(47,16) = "r"
- │ │ │ └── operator_loc: (47,14)-(47,15) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (47,18)-(47,19))
- │ │ │ └── name: :p
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (47,21)-(47,23))
- │ │ ├── name: :b
- │ │ ├── name_loc: (47,22)-(47,23) = "b"
- │ │ └── operator_loc: (47,21)-(47,22) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :o, :r, :p, :b]
- │ ├── locals_body_index: 5
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (49,9)-(49,12))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (49,9)-(49,10) = "o"
- │ │ │ ├── operator_loc: (49,10)-(49,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (49,11)-(49,12))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (49,14)-(49,15))
- │ │ │ └── name: :p
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (49,17)-(49,19))
- │ │ ├── name: :b
- │ │ ├── name_loc: (49,18)-(49,19) = "b"
- │ │ └── operator_loc: (49,17)-(49,18) = "&"
- │ ├── body: ∅
- │ ├── locals: [:a, :o, :p, :b]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ ├── name: :foo
- │ │ │ └── name_loc: (51,6)-(51,10) = "foo:"
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:foo]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :foo
- │ │ │ ├── name_loc: (54,6)-(54,10) = "foo:"
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (54,11)-(54,13))
- │ │ │ └── flags: decimal
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:foo]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (57,6)-(57,7) = "o"
- │ │ │ ├── operator_loc: (57,7)-(57,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (57,8)-(57,9))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (57,11)-(57,13))
- │ │ ├── name: :b
- │ │ ├── name_loc: (57,12)-(57,13) = "b"
- │ │ └── operator_loc: (57,11)-(57,12) = "&"
- │ ├── body: ∅
- │ ├── locals: [:o, :b]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (59,6)-(59,7) = "o"
- │ │ │ ├── operator_loc: (59,7)-(59,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (59,8)-(59,9))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (59,11)-(59,13))
- │ │ │ ├── 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))
- │ │ ├── name: :b
- │ │ ├── name_loc: (59,16)-(59,17) = "b"
- │ │ └── operator_loc: (59,15)-(59,16) = "&"
- │ ├── body: ∅
- │ ├── locals: [:o, :r, :b]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ ├── name: :o
- │ │ │ ├── name_loc: (61,6)-(61,7) = "o"
- │ │ │ ├── operator_loc: (61,7)-(61,8) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (61,8)-(61,9))
- │ │ │ └── flags: decimal
- │ │ ├── rest:
- │ │ │ @ RestParameterNode (location: (61,11)-(61,13))
- │ │ │ ├── name: :r
- │ │ │ ├── name_loc: (61,12)-(61,13) = "r"
- │ │ │ └── operator_loc: (61,11)-(61,12) = "*"
- │ │ ├── posts: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (61,15)-(61,16))
- │ │ │ └── name: :p
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block:
- │ │ @ BlockParameterNode (location: (61,18)-(61,20))
- │ │ ├── name: :b
- │ │ ├── name_loc: (61,19)-(61,20) = "b"
- │ │ └── operator_loc: (61,18)-(61,19) = "&"
- │ ├── body: ∅
- │ ├── locals: [:o, :r, :p, :b]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ ├── name: :o
- │ │ ├── name_loc: (63,6)-(63,7) = "o"
- │ │ ├── operator_loc: (63,7)-(63,8) = "="
- │ │ └── value:
- │ │ @ IntegerNode (location: (63,8)-(63,9))
- │ │ └── flags: decimal
- │ ├── rest: ∅
- │ ├── posts: (length: 1)
- │ │ └── @ RequiredParameterNode (location: (63,11)-(63,12))
- │ │ └── name: :p
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block:
- │ @ BlockParameterNode (location: (63,14)-(63,16))
- │ ├── name: :b
- │ ├── name_loc: (63,15)-(63,16) = "b"
- │ └── operator_loc: (63,14)-(63,15) = "&"
- ├── body: ∅
- ├── locals: [:o, :p, :b]
- ├── locals_body_index: 3
- ├── 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
deleted file mode 100644
index d5c0d7d136..0000000000
--- a/test/prism/snapshots/whitequark/args_args_assocs.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,24))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,24))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,19))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,9)-(1,18))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,9)-(1,13))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (1,14)-(1,16) = "=>"
- │ ├── closing_loc: (1,18)-(1,19) = ")"
- │ └── block: ∅
- └── @ CallNode (location: (3,0)-(3,24))
- ├── flags: ∅
- ├── 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
- │ │ ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (3,9)-(3,18))
- │ ├── key:
- │ │ @ SymbolNode (location: (3,9)-(3,13))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
- │ ├── 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
deleted file mode 100644
index 2aa1644610..0000000000
--- a/test/prism/snapshots/whitequark/args_args_assocs_comma.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,9)-(1,18))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,9)-(1,13))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 70f6c07d6f..0000000000
--- a/test/prism/snapshots/whitequark/args_args_comma.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index b38eacfb14..0000000000
--- a/test/prism/snapshots/whitequark/args_args_star.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,19))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,14))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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: ∅
- ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index bf51dda187..0000000000
--- a/test/prism/snapshots/whitequark/args_assocs.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-@ ProgramNode (location: (1,0)-(11,17))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(11,17))
- └── body: (length: 6)
- ├── @ CallNode (location: (1,0)-(1,14))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,4)-(1,13))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,4)-(1,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (1,9)-(1,11) = "=>"
- │ ├── closing_loc: (1,13)-(1,14) = ")"
- │ └── block: ∅
- ├── @ CallNode (location: (3,0)-(3,19))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (3,4)-(3,13))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (3,4)-(3,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (5,14)-(5,21))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (5,14)-(5,16))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (5,17)-(5,19) = "=>"
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (7,0)-(7,15))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (7,5)-(7,14))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (7,5)-(7,9))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (9,6)-(9,16))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (9,6)-(9,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (11,6)-(11,16))
- │ ├── key:
- │ │ @ SymbolNode (location: (11,6)-(11,10))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index b98aa39cb7..0000000000
--- a/test/prism/snapshots/whitequark/args_assocs_comma.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- │ ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,4)-(1,13))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,4)-(1,8))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index bf51dda187..0000000000
--- a/test/prism/snapshots/whitequark/args_assocs_legacy.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-@ ProgramNode (location: (1,0)-(11,17))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(11,17))
- └── body: (length: 6)
- ├── @ CallNode (location: (1,0)-(1,14))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,4)-(1,13))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,4)-(1,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (1,9)-(1,11) = "=>"
- │ ├── closing_loc: (1,13)-(1,14) = ")"
- │ └── block: ∅
- ├── @ CallNode (location: (3,0)-(3,19))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (3,4)-(3,13))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (3,4)-(3,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (5,14)-(5,21))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (5,14)-(5,16))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: (5,17)-(5,19) = "=>"
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (7,0)-(7,15))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (7,5)-(7,14))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (7,5)-(7,9))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (9,6)-(9,16))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (9,6)-(9,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (11,6)-(11,16))
- │ ├── key:
- │ │ @ SymbolNode (location: (11,6)-(11,10))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 84089ed92c..0000000000
--- a/test/prism/snapshots/whitequark/args_block_pass.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index f626fc686e..0000000000
--- a/test/prism/snapshots/whitequark/args_cmd.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 6cbc248ba2..0000000000
--- a/test/prism/snapshots/whitequark/args_star.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,14))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,9))
- │ ├── flags: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index c66356b89a..0000000000
--- a/test/prism/snapshots/whitequark/array_assocs.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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:
- │ │ │ @ IntegerNode (location: (1,7)-(1,8))
- │ │ │ └── flags: decimal
- │ │ └── 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
- │ └── @ 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:
- │ │ @ IntegerNode (location: (3,10)-(3,11))
- │ │ └── flags: decimal
- │ └── 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
deleted file mode 100644
index 17dd4a2137..0000000000
--- a/test/prism/snapshots/whitequark/array_plain.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- │ └── @ IntegerNode (location: (1,4)-(1,5))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 3e6c8a6efe..0000000000
--- a/test/prism/snapshots/whitequark/array_splat.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── @ SplatNode (location: (3,4)-(3,8))
- │ │ │ ├── operator_loc: (3,4)-(3,5) = "*"
- │ │ │ └── expression:
- │ │ │ @ CallNode (location: (3,5)-(3,8))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── 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
- │ ├── 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
- │ └── @ SplatNode (location: (5,4)-(5,8))
- │ ├── operator_loc: (5,4)-(5,5) = "*"
- │ └── expression:
- │ @ CallNode (location: (5,5)-(5,8))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index 9eeaa3e69a..0000000000
--- a/test/prism/snapshots/whitequark/array_symbols.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,3)-(1,6) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ └── @ SymbolNode (location: (1,7)-(1,10))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index 1068ba6d0e..0000000000
--- a/test/prism/snapshots/whitequark/array_symbols_empty.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-@ 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
deleted file mode 100644
index d10eb2c528..0000000000
--- a/test/prism/snapshots/whitequark/array_symbols_interp.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index 84121de355..0000000000
--- a/test/prism/snapshots/whitequark/array_words.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
deleted file mode 100644
index e4dba94cdf..0000000000
--- a/test/prism/snapshots/whitequark/array_words_empty.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-@ 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
deleted file mode 100644
index 3e9e0eaaaa..0000000000
--- a/test/prism/snapshots/whitequark/array_words_interp.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-@ 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))
- │ │ ├── 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
- │ │ │ │ ├── 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))
- │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index ee13da76c0..0000000000
--- a/test/prism/snapshots/whitequark/asgn_cmd.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 11caa62274..0000000000
--- a/test/prism/snapshots/whitequark/asgn_mrhs.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-@ 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
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index ea6b76faf7..0000000000
--- a/test/prism/snapshots/whitequark/back_ref.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index 843d0edea4..0000000000
--- a/test/prism/snapshots/whitequark/bang.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index 83f70c6c2b..0000000000
--- a/test/prism/snapshots/whitequark/bang_cmd.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 26045f1caa..0000000000
--- a/test/prism/snapshots/whitequark/begin_cmdarg.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (1,19)-(1,20))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (1,19)-(1,20))
- │ │ │ └── flags: decimal
- │ │ ├── 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
deleted file mode 100644
index e67233cc03..0000000000
--- a/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- │ ├── 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
- └── 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
deleted file mode 100644
index 64643f2189..0000000000
--- a/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-@ 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
- │ ├── 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
- └── operator_loc: (2,0)-(2,2) = ".."
diff --git a/test/prism/snapshots/whitequark/beginless_range.txt b/test/prism/snapshots/whitequark/beginless_range.txt
deleted file mode 100644
index ffbde4de34..0000000000
--- a/test/prism/snapshots/whitequark/beginless_range.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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
- │ └── operator_loc: (1,0)-(1,3) = "..."
- └── @ RangeNode (location: (3,0)-(3,5))
- ├── flags: ∅
- ├── left: ∅
- ├── right:
- │ @ IntegerNode (location: (3,2)-(3,5))
- │ └── flags: decimal
- └── operator_loc: (3,0)-(3,2) = ".."
diff --git a/test/prism/snapshots/whitequark/blockarg.txt b/test/prism/snapshots/whitequark/blockarg.txt
deleted file mode 100644
index ce3bb106b5..0000000000
--- a/test/prism/snapshots/whitequark/blockarg.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ ├── name: :block
- │ ├── name_loc: (1,7)-(1,12) = "block"
- │ └── operator_loc: (1,6)-(1,7) = "&"
- ├── body: ∅
- ├── locals: [:block]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 3abacbea60..0000000000
--- a/test/prism/snapshots/whitequark/blockargs.txt
+++ /dev/null
@@ -1,1288 +0,0 @@
-@ ProgramNode (location: (1,0)-(71,7))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(71,7))
- └── body: (length: 35)
- ├── @ CallNode (location: (1,0)-(1,5))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,1)-(1,2) = "{"
- │ └── closing_loc: (1,4)-(1,5) = "}"
- ├── @ CallNode (location: (3,0)-(3,8))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :baz
- │ │ │ │ ├── name_loc: (7,6)-(7,9) = "baz"
- │ │ │ │ └── operator_loc: (7,4)-(7,6) = "**"
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (7,11)-(7,13))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── name: ∅
- │ │ │ │ ├── name_loc: ∅
- │ │ │ │ └── operator_loc: (9,4)-(9,5) = "*"
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (9,7)-(9,9))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ │ ├── name: :r
- │ │ │ │ ├── name_loc: (11,5)-(11,6) = "r"
- │ │ │ │ └── operator_loc: (11,4)-(11,5) = "*"
- │ │ │ ├── posts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (11,8)-(11,9))
- │ │ │ │ └── name: :p
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (11,11)-(11,13))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── 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))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (19,3)-(21,1))
- │ │ ├── parameters: ∅
- │ │ ├── locals: (length: 1)
- │ │ │ └── @ BlockLocalVariableNode (location: (20,0)-(20,1))
- │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (23,3)-(23,7))
- │ │ ├── parameters: ∅
- │ │ ├── locals: (length: 1)
- │ │ │ └── @ BlockLocalVariableNode (location: (23,5)-(23,6))
- │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (25,3)-(25,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (25,4)-(25,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (25,4)-(25,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (25,7)-(25,9))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (27,3)-(27,13))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (27,4)-(27,12))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (27,4)-(27,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (27,7)-(27,8))
- │ │ │ │ ├── name: ∅
- │ │ │ │ ├── name_loc: ∅
- │ │ │ │ └── operator_loc: (27,7)-(27,8) = "*"
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (27,10)-(27,12))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 4
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (29,3)-(29,17))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (29,4)-(29,16))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (29,4)-(29,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (29,7)-(29,9))
- │ │ │ │ ├── name: :r
- │ │ │ │ ├── name_loc: (29,8)-(29,9) = "r"
- │ │ │ │ └── operator_loc: (29,7)-(29,8) = "*"
- │ │ │ ├── posts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (29,11)-(29,12))
- │ │ │ │ └── name: :p
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (29,14)-(29,16))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (31,3)-(31,14))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (31,4)-(31,13))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (31,4)-(31,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (31,7)-(31,9))
- │ │ │ │ ├── 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))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (33,3)-(33,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (33,4)-(33,9))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (33,4)-(33,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (33,7)-(33,9))
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (35,3)-(35,9))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (35,4)-(35,8))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (35,4)-(35,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 0)
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (35,7)-(35,8))
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (37,3)-(37,10))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (37,4)-(37,9))
- │ │ │ ├── requireds: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (37,4)-(37,5))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (37,7)-(37,8))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (39,3)-(39,9))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (39,4)-(39,8))
- │ │ │ ├── requireds: (length: 2)
- │ │ │ │ ├── @ RequiredParameterNode (location: (39,4)-(39,5))
- │ │ │ │ │ └── name: :a
- │ │ │ │ └── @ RequiredParameterNode (location: (39,7)-(39,8))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (41,3)-(41,15))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (41,4)-(41,14))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (41,4)-(41,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (41,7)-(41,10))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (41,7)-(41,8) = "o"
- │ │ │ │ ├── operator_loc: (41,8)-(41,9) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (41,9)-(41,10))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (41,12)-(41,14))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 5
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (43,3)-(43,22))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (43,4)-(43,21))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (43,4)-(43,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (43,7)-(43,10))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (43,7)-(43,8) = "o"
- │ │ │ │ ├── operator_loc: (43,8)-(43,9) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (43,9)-(43,10))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (43,12)-(43,14))
- │ │ │ │ ├── name: :r
- │ │ │ │ ├── name_loc: (43,13)-(43,14) = "r"
- │ │ │ │ └── operator_loc: (43,12)-(43,13) = "*"
- │ │ │ ├── posts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (43,16)-(43,17))
- │ │ │ │ └── name: :p
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (43,19)-(43,21))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 5
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (45,3)-(45,25))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (45,4)-(45,24))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (45,4)-(45,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 2)
- │ │ │ │ ├── @ OptionalParameterNode (location: (45,7)-(45,10))
- │ │ │ │ │ ├── name: :o
- │ │ │ │ │ ├── name_loc: (45,7)-(45,8) = "o"
- │ │ │ │ │ ├── operator_loc: (45,8)-(45,9) = "="
- │ │ │ │ │ └── value:
- │ │ │ │ │ @ IntegerNode (location: (45,9)-(45,10))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── @ OptionalParameterNode (location: (45,12)-(45,16))
- │ │ │ │ ├── name: :o1
- │ │ │ │ ├── name_loc: (45,12)-(45,14) = "o1"
- │ │ │ │ ├── operator_loc: (45,14)-(45,15) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (45,15)-(45,16))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (45,18)-(45,20))
- │ │ │ │ ├── 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))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 4
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (47,3)-(47,18))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (47,4)-(47,17))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (47,4)-(47,5))
- │ │ │ │ └── name: :a
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (47,7)-(47,10))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (47,7)-(47,8) = "o"
- │ │ │ │ ├── operator_loc: (47,8)-(47,9) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (47,9)-(47,10))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (47,12)-(47,13))
- │ │ │ │ └── name: :p
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (47,15)-(47,17))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (49,3)-(49,7))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (49,4)-(49,6))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (49,4)-(49,5))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (51,3)-(51,6))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (51,4)-(51,5))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (51,4)-(51,5))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (53,3)-(53,6))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (53,4)-(53,5))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (53,4)-(53,5))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (55,3)-(55,6))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (55,4)-(55,5))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (55,4)-(55,5))
- │ │ │ │ └── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :foo
- │ │ │ │ ├── name_loc: (57,4)-(57,8) = "foo:"
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (57,9)-(57,10))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (57,12)-(57,14))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ │ │ ├── name: :foo
- │ │ │ │ │ ├── name_loc: (59,4)-(59,8) = "foo:"
- │ │ │ │ │ └── value:
- │ │ │ │ │ @ IntegerNode (location: (59,9)-(59,10))
- │ │ │ │ │ └── flags: decimal
- │ │ │ │ └── @ OptionalKeywordParameterNode (location: (59,12)-(59,18))
- │ │ │ │ ├── name: :bar
- │ │ │ │ ├── name_loc: (59,12)-(59,16) = "bar:"
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (59,17)-(59,18))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── keyword_rest:
- │ │ │ │ @ KeywordRestParameterNode (location: (59,20)-(59,25))
- │ │ │ │ ├── name: :baz
- │ │ │ │ ├── name_loc: (59,22)-(59,25) = "baz"
- │ │ │ │ └── operator_loc: (59,20)-(59,22) = "**"
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (59,27)-(59,29))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (63,4)-(63,5) = "o"
- │ │ │ │ ├── operator_loc: (63,5)-(63,6) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (63,6)-(63,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (63,9)-(63,11))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (65,4)-(65,5) = "o"
- │ │ │ │ ├── operator_loc: (65,5)-(65,6) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (65,6)-(65,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (65,9)-(65,11))
- │ │ │ │ ├── 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))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 4
- │ ├── 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))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (67,4)-(67,5) = "o"
- │ │ │ │ ├── operator_loc: (67,5)-(67,6) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (67,6)-(67,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest:
- │ │ │ │ @ RestParameterNode (location: (67,9)-(67,11))
- │ │ │ │ ├── name: :r
- │ │ │ │ ├── name_loc: (67,10)-(67,11) = "r"
- │ │ │ │ └── operator_loc: (67,9)-(67,10) = "*"
- │ │ │ ├── posts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (67,13)-(67,14))
- │ │ │ │ └── name: :p
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (67,16)-(67,18))
- │ │ │ ├── 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ │ ├── name: :o
- │ │ │ │ ├── name_loc: (69,4)-(69,5) = "o"
- │ │ │ │ ├── operator_loc: (69,5)-(69,6) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (69,6)-(69,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (69,9)-(69,10))
- │ │ │ │ └── name: :p
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block:
- │ │ │ @ BlockParameterNode (location: (69,12)-(69,14))
- │ │ │ ├── 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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/break.txt b/test/prism/snapshots/whitequark/break.txt
deleted file mode 100644
index 4f40ca759e..0000000000
--- a/test/prism/snapshots/whitequark/break.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,10))
- └── body: (length: 4)
- ├── @ BreakNode (location: (1,0)-(1,5))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,0)-(1,5) = "break"
- ├── @ BreakNode (location: (3,0)-(3,9))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (3,6)-(3,9))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (3,6)-(3,9))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (3,6)-(3,9) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── keyword_loc: (3,0)-(3,5) = "break"
- ├── @ BreakNode (location: (5,0)-(5,7))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (5,5)-(5,7))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (5,5)-(5,7))
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (5,5)-(5,6) = "("
- │ │ └── closing_loc: (5,6)-(5,7) = ")"
- │ └── keyword_loc: (5,0)-(5,5) = "break"
- └── @ BreakNode (location: (7,0)-(7,10))
- ├── arguments:
- │ @ ArgumentsNode (location: (7,5)-(7,10))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ ParenthesesNode (location: (7,5)-(7,10))
- │ ├── body:
- │ │ @ StatementsNode (location: (7,6)-(7,9))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (7,6)-(7,9))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (7,6)-(7,9) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── opening_loc: (7,5)-(7,6) = "("
- │ └── closing_loc: (7,9)-(7,10) = ")"
- └── keyword_loc: (7,0)-(7,5) = "break"
diff --git a/test/prism/snapshots/whitequark/break_block.txt b/test/prism/snapshots/whitequark/break_block.txt
deleted file mode 100644
index 12a9263911..0000000000
--- a/test/prism/snapshots/whitequark/break_block.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,20))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,20))
- └── body: (length: 1)
- └── @ BreakNode (location: (1,0)-(1,20))
- ├── arguments:
- │ @ ArgumentsNode (location: (1,6)-(1,20))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ CallNode (location: (1,6)-(1,20))
- │ ├── flags: ∅
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :fun
- │ ├── message_loc: (1,6)-(1,9) = "fun"
- │ ├── opening_loc: ∅
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (1,10)-(1,13))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (1,10)-(1,13))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (1,10)-(1,13) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (1,14)-(1,20))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,14)-(1,16) = "do"
- │ └── closing_loc: (1,17)-(1,20) = "end"
- └── keyword_loc: (1,0)-(1,5) = "break"
diff --git a/test/prism/snapshots/whitequark/bug_435.txt b/test/prism/snapshots/whitequark/bug_435.txt
deleted file mode 100644
index afce74425e..0000000000
--- a/test/prism/snapshots/whitequark/bug_435.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,14))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,14))
- ├── 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]
- │ │ ├── locals_body_index: 1
- │ │ ├── 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))
- │ │ │ │ │ └── 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
deleted file mode 100644
index 427579b8b8..0000000000
--- a/test/prism/snapshots/whitequark/bug_447.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,14))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,11))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,5)-(1,7) = "do"
- │ └── closing_loc: (1,8)-(1,11) = "end"
- └── @ CallNode (location: (3,0)-(3,14))
- ├── flags: ∅
- ├── 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
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (3,8)-(3,14))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 8bed829c80..0000000000
--- a/test/prism/snapshots/whitequark/bug_452.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,37))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,37))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,21))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 32361b6e75..0000000000
--- a/test/prism/snapshots/whitequark/bug_466.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,27))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,27))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,27))
- ├── flags: ∅
- ├── 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))
- │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index c4767f4ec1..0000000000
--- a/test/prism/snapshots/whitequark/bug_473.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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: ∅
- ├── 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))
- │ ├── 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
deleted file mode 100644
index 73903adb78..0000000000
--- a/test/prism/snapshots/whitequark/bug_480.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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: ∅
- ├── 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))
- │ ├── 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
deleted file mode 100644
index ccacf71b1e..0000000000
--- a/test/prism/snapshots/whitequark/bug_481.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,28))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,28))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,14))
- │ ├── flags: ∅
- │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 7aa8694f66..0000000000
--- a/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 91e849c830..0000000000
--- a/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 6779d11735..0000000000
--- a/test/prism/snapshots/whitequark/bug_cmdarg.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,26))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,26))
- └── body: (length: 3)
- ├── @ CallNode (location: (1,0)-(1,15))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,7)-(1,15))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,7)-(1,10))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (5,2)-(5,26))
- │ ├── key:
- │ │ @ SymbolNode (location: (5,2)-(5,4))
- │ │ ├── flags: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
deleted file mode 100644
index 27d57492ab..0000000000
--- a/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 3b5bc5b475..0000000000
--- a/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (1,23)-(1,25) = "do"
- │ │ └── closing_loc: (1,26)-(1,29) = "end"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index 3283361ac1..0000000000
--- a/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
deleted file mode 100644
index 4415a16551..0000000000
--- a/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt
+++ /dev/null
@@ -1,394 +0,0 @@
-@ ProgramNode (location: (1,0)-(9,52))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(9,52))
- └── body: (length: 5)
- ├── @ CallNode (location: (1,0)-(1,42))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ │ ├── 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: []
- │ │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: ∅
- ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (9,14)-(9,16) = "do"
- │ │ │ │ └── closing_loc: (9,17)-(9,20) = "end"
- │ │ │ ├── value:
- │ │ │ │ @ CallNode (location: (9,24)-(9,35))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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
deleted file mode 100644
index 7d1254f4fe..0000000000
--- a/test/prism/snapshots/whitequark/bug_heredoc_do.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,3))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,3))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(3,3))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 699dd6297e..0000000000
--- a/test/prism/snapshots/whitequark/bug_interp_single.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,8))
- └── body: (length: 2)
- ├── @ InterpolatedStringNode (location: (1,0)-(1,6))
- │ ├── 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
- │ │ └── 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))
- │ ├── 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
- │ │ └── 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
deleted file mode 100644
index f538e3f613..0000000000
--- a/test/prism/snapshots/whitequark/bug_lambda_leakage.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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
- ├── 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
deleted file mode 100644
index 5ca85e34c7..0000000000
--- a/test/prism/snapshots/whitequark/bug_regex_verification.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 52734cc1e9..0000000000
--- a/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
deleted file mode 100644
index aa8aa11ccc..0000000000
--- a/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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
deleted file mode 100644
index c578d386da..0000000000
--- a/test/prism/snapshots/whitequark/case_cond.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (1,11)-(1,14) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── 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
deleted file mode 100644
index f6411ad5a9..0000000000
--- a/test/prism/snapshots/whitequark/case_cond_else.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (1,11)-(1,14) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── 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
deleted file mode 100644
index d52625f74e..0000000000
--- a/test/prism/snapshots/whitequark/case_expr.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ │ ├── opening_loc: (1,15)-(1,16) = "'"
- │ │ ├── content_loc: (1,16)-(1,19) = "bar"
- │ │ ├── closing_loc: (1,19)-(1,20) = "'"
- │ │ └── unescaped: "bar"
- │ └── statements:
- │ @ StatementsNode (location: (1,22)-(1,25))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,22)-(1,25))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index ddb80acfcb..0000000000
--- a/test/prism/snapshots/whitequark/case_expr_else.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ │ ├── opening_loc: (1,15)-(1,16) = "'"
- │ │ ├── content_loc: (1,16)-(1,19) = "bar"
- │ │ ├── closing_loc: (1,19)-(1,20) = "'"
- │ │ └── unescaped: "bar"
- │ └── statements:
- │ @ StatementsNode (location: (1,22)-(1,25))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,22)-(1,25))
- │ ├── flags: variable_call
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index bb3a8b072a..0000000000
--- a/test/prism/snapshots/whitequark/casgn_scoped.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/whitequark/casgn_toplevel.txt b/test/prism/snapshots/whitequark/casgn_toplevel.txt
deleted file mode 100644
index bc48b1e841..0000000000
--- a/test/prism/snapshots/whitequark/casgn_toplevel.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
diff --git a/test/prism/snapshots/whitequark/casgn_unscoped.txt b/test/prism/snapshots/whitequark/casgn_unscoped.txt
deleted file mode 100644
index 90434d39db..0000000000
--- a/test/prism/snapshots/whitequark/casgn_unscoped.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── operator_loc: (1,4)-(1,5) = "="
diff --git a/test/prism/snapshots/whitequark/character.txt b/test/prism/snapshots/whitequark/character.txt
deleted file mode 100644
index b70f05b544..0000000000
--- a/test/prism/snapshots/whitequark/character.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index e38bec6c47..0000000000
--- a/test/prism/snapshots/whitequark/class.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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_definition_in_while_cond.txt b/test/prism/snapshots/whitequark/class_definition_in_while_cond.txt
deleted file mode 100644
index 44b7d83765..0000000000
--- a/test/prism/snapshots/whitequark/class_definition_in_while_cond.txt
+++ /dev/null
@@ -1,175 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,44))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,44))
- └── body: (length: 4)
- ├── @ WhileNode (location: (1,0)-(1,52))
- │ ├── flags: ∅
- │ ├── keyword_loc: (1,0)-(1,5) = "while"
- │ ├── closing_loc: (1,49)-(1,52) = "end"
- │ ├── predicate:
- │ │ @ SingletonClassNode (location: (1,6)-(1,40))
- │ │ ├── locals: [:a]
- │ │ ├── class_keyword_loc: (1,6)-(1,11) = "class"
- │ │ ├── operator_loc: (1,12)-(1,14) = "<<"
- │ │ ├── expression:
- │ │ │ @ SelfNode (location: (1,15)-(1,19))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (1,21)-(1,35))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ LocalVariableWriteNode (location: (1,21)-(1,35))
- │ │ │ ├── name: :a
- │ │ │ ├── depth: 0
- │ │ │ ├── name_loc: (1,21)-(1,22) = "a"
- │ │ │ ├── value:
- │ │ │ │ @ CallNode (location: (1,25)-(1,35))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (1,25)-(1,28) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (1,29)-(1,35))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (1,29)-(1,31) = "do"
- │ │ │ │ └── closing_loc: (1,32)-(1,35) = "end"
- │ │ │ └── operator_loc: (1,23)-(1,24) = "="
- │ │ └── end_keyword_loc: (1,37)-(1,40) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (1,42)-(1,47))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (1,42)-(1,47))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,42)-(1,47) = "break"
- ├── @ WhileNode (location: (3,0)-(3,48))
- │ ├── flags: ∅
- │ ├── keyword_loc: (3,0)-(3,5) = "while"
- │ ├── closing_loc: (3,45)-(3,48) = "end"
- │ ├── predicate:
- │ │ @ SingletonClassNode (location: (3,6)-(3,36))
- │ │ ├── locals: []
- │ │ ├── class_keyword_loc: (3,6)-(3,11) = "class"
- │ │ ├── operator_loc: (3,12)-(3,14) = "<<"
- │ │ ├── expression:
- │ │ │ @ SelfNode (location: (3,15)-(3,19))
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (3,21)-(3,31))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (3,21)-(3,31))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :tap
- │ │ │ ├── message_loc: (3,21)-(3,24) = "tap"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block:
- │ │ │ @ BlockNode (location: (3,25)-(3,31))
- │ │ │ ├── locals: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body: ∅
- │ │ │ ├── opening_loc: (3,25)-(3,27) = "do"
- │ │ │ └── closing_loc: (3,28)-(3,31) = "end"
- │ │ └── end_keyword_loc: (3,33)-(3,36) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (3,38)-(3,43))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (3,38)-(3,43))
- │ ├── arguments: ∅
- │ └── keyword_loc: (3,38)-(3,43) = "break"
- ├── @ WhileNode (location: (5,0)-(5,47))
- │ ├── flags: ∅
- │ ├── keyword_loc: (5,0)-(5,5) = "while"
- │ ├── closing_loc: (5,44)-(5,47) = "end"
- │ ├── predicate:
- │ │ @ ClassNode (location: (5,6)-(5,35))
- │ │ ├── locals: [:a]
- │ │ ├── class_keyword_loc: (5,6)-(5,11) = "class"
- │ │ ├── constant_path:
- │ │ │ @ ConstantReadNode (location: (5,12)-(5,15))
- │ │ │ └── name: :Foo
- │ │ ├── inheritance_operator_loc: ∅
- │ │ ├── superclass: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (5,16)-(5,30))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ LocalVariableWriteNode (location: (5,16)-(5,30))
- │ │ │ ├── name: :a
- │ │ │ ├── depth: 0
- │ │ │ ├── name_loc: (5,16)-(5,17) = "a"
- │ │ │ ├── value:
- │ │ │ │ @ CallNode (location: (5,20)-(5,30))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (5,20)-(5,23) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (5,24)-(5,30))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (5,24)-(5,26) = "do"
- │ │ │ │ └── closing_loc: (5,27)-(5,30) = "end"
- │ │ │ └── operator_loc: (5,18)-(5,19) = "="
- │ │ ├── end_keyword_loc: (5,32)-(5,35) = "end"
- │ │ └── name: :Foo
- │ └── statements:
- │ @ StatementsNode (location: (5,37)-(5,42))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (5,37)-(5,42))
- │ ├── arguments: ∅
- │ └── keyword_loc: (5,37)-(5,42) = "break"
- └── @ WhileNode (location: (7,0)-(7,44))
- ├── flags: ∅
- ├── keyword_loc: (7,0)-(7,5) = "while"
- ├── closing_loc: (7,41)-(7,44) = "end"
- ├── predicate:
- │ @ ClassNode (location: (7,6)-(7,32))
- │ ├── locals: []
- │ ├── class_keyword_loc: (7,6)-(7,11) = "class"
- │ ├── constant_path:
- │ │ @ ConstantReadNode (location: (7,12)-(7,15))
- │ │ └── name: :Foo
- │ ├── inheritance_operator_loc: ∅
- │ ├── superclass: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (7,17)-(7,27))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (7,17)-(7,27))
- │ │ ├── flags: ∅
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :tap
- │ │ ├── message_loc: (7,17)-(7,20) = "tap"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (7,21)-(7,27))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (7,21)-(7,23) = "do"
- │ │ └── closing_loc: (7,24)-(7,27) = "end"
- │ ├── end_keyword_loc: (7,29)-(7,32) = "end"
- │ └── name: :Foo
- └── statements:
- @ StatementsNode (location: (7,34)-(7,39))
- └── body: (length: 1)
- └── @ BreakNode (location: (7,34)-(7,39))
- ├── arguments: ∅
- └── keyword_loc: (7,34)-(7,39) = "break"
diff --git a/test/prism/snapshots/whitequark/class_super.txt b/test/prism/snapshots/whitequark/class_super.txt
deleted file mode 100644
index ea8bbd70d9..0000000000
--- a/test/prism/snapshots/whitequark/class_super.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-@ 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
deleted file mode 100644
index 519583475b..0000000000
--- a/test/prism/snapshots/whitequark/class_super_label.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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: ∅
- │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 4868d0913e..0000000000
--- a/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index f81564d700..0000000000
--- a/test/prism/snapshots/whitequark/complex.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-@ 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))
- ├── @ ImaginaryNode (location: (3,0)-(3,6))
- │ └── numeric:
- │ @ RationalNode (location: (3,0)-(3,5))
- │ └── numeric:
- │ @ FloatNode (location: (3,0)-(3,4))
- ├── @ ImaginaryNode (location: (5,0)-(5,3))
- │ └── numeric:
- │ @ IntegerNode (location: (5,0)-(5,2))
- │ └── flags: decimal
- └── @ ImaginaryNode (location: (7,0)-(7,4))
- └── numeric:
- @ RationalNode (location: (7,0)-(7,3))
- └── numeric:
- @ IntegerNode (location: (7,0)-(7,2))
- └── flags: decimal
diff --git a/test/prism/snapshots/whitequark/cond_begin.txt b/test/prism/snapshots/whitequark/cond_begin.txt
deleted file mode 100644
index d70314408f..0000000000
--- a/test/prism/snapshots/whitequark/cond_begin.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 93892315ac..0000000000
--- a/test/prism/snapshots/whitequark/cond_begin_masgn.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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
- │ │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index ab617f583f..0000000000
--- a/test/prism/snapshots/whitequark/cond_eflipflop.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-@ 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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_iflipflop.txt b/test/prism/snapshots/whitequark/cond_iflipflop.txt
deleted file mode 100644
index 061bfd4315..0000000000
--- a/test/prism/snapshots/whitequark/cond_iflipflop.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-@ 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
- │ │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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_match_current_line.txt b/test/prism/snapshots/whitequark/cond_match_current_line.txt
deleted file mode 100644
index fb5ff33ed5..0000000000
--- a/test/prism/snapshots/whitequark/cond_match_current_line.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index b2292fcc85..0000000000
--- a/test/prism/snapshots/whitequark/const_op_asgn.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-@ 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
- │ └── 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
- │ └── 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
- │ └── 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 1e2bccef96..0000000000
--- a/test/prism/snapshots/whitequark/const_scoped.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
deleted file mode 100644
index b54b069d06..0000000000
--- a/test/prism/snapshots/whitequark/const_toplevel.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index 5e272e1775..0000000000
--- a/test/prism/snapshots/whitequark/const_unscoped.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index b892525646..0000000000
--- a/test/prism/snapshots/whitequark/cpath.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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
deleted file mode 100644
index 7847ce4495..0000000000
--- a/test/prism/snapshots/whitequark/cvar.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index e6a1c7e973..0000000000
--- a/test/prism/snapshots/whitequark/cvasgn.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── operator_loc: (1,6)-(1,7) = "="
diff --git a/test/prism/snapshots/whitequark/dedenting_heredoc.txt b/test/prism/snapshots/whitequark/dedenting_heredoc.txt
deleted file mode 100644
index a459cd851f..0000000000
--- a/test/prism/snapshots/whitequark/dedenting_heredoc.txt
+++ /dev/null
@@ -1,485 +0,0 @@
-@ ProgramNode (location: (1,0)-(72,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(72,8))
- └── body: (length: 16)
- ├── @ CallNode (location: (1,0)-(1,8))
- │ ├── flags: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\""
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (6,2)-(6,8) = "<<~\"E\""
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (7,0)-(8,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (11,2)-(11,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (12,0)-(13,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (12,0)-(13,0) = "\tx\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "x\n"
- │ │ │ └── @ StringNode (location: (13,0)-(14,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (16,2)-(16,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (17,0)-(18,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (17,0)-(18,0) = "\tx\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "\tx\n"
- │ │ │ └── @ StringNode (location: (18,0)-(19,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (21,2)-(21,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (22,0)-(23,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (22,0)-(23,0) = " \tx\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "x\n"
- │ │ │ └── @ StringNode (location: (23,0)-(24,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (26,2)-(26,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (27,0)-(28,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (27,0)-(28,0) = " \tx\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "\tx\n"
- │ │ │ └── @ StringNode (location: (28,0)-(29,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (31,2)-(31,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (32,0)-(33,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (32,0)-(33,0) = " x\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: " x\n"
- │ │ │ └── @ StringNode (location: (33,0)-(34,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (36,2)-(36,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (37,0)-(38,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (37,0)-(38,0) = " x\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: " x\n"
- │ │ │ └── @ StringNode (location: (38,0)-(39,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (44,2)-(44,6) = "<<~E"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (45,0)-(46,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (45,0)-(46,0) = " x\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: " x\n"
- │ │ │ ├── @ StringNode (location: (46,0)-(47,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (46,0)-(47,0) = "\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "\n"
- │ │ │ └── @ StringNode (location: (47,0)-(48,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (50,2)-(50,6) = "<<~E"
- │ │ ├── parts: (length: 3)
- │ │ │ ├── @ StringNode (location: (51,0)-(52,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (51,0)-(52,0) = " x\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "x\n"
- │ │ │ ├── @ StringNode (location: (52,0)-(53,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (52,0)-(53,0) = " \n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: " \n"
- │ │ │ └── @ StringNode (location: (53,0)-(54,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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))
- │ │ ├── opening_loc: (56,2)-(56,6) = "<<~E"
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (57,0)-(58,0))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── content_loc: (57,0)-(58,0) = " x\n"
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── unescaped: "x\n"
- │ │ │ └── @ StringNode (location: (58,0)-(59,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- ├── 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
- │ │ │ │ ├── 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
deleted file mode 100644
index cc5be3d967..0000000000
--- a/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,8))
- ├── opening_loc: (1,0)-(1,8) = "<<~'FOO'"
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (2,0)-(3,0) = " baz\\\\\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "baz\\\\\n"
- │ └── @ StringNode (location: (3,0)-(4,0))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index d9f7fe2ec7..0000000000
--- a/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,8))
- ├── opening_loc: (1,0)-(1,8) = "<<~'FOO'"
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (2,0)-(3,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (2,0)-(3,0) = " baz\\\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "baz\\\n"
- │ └── @ StringNode (location: (3,0)-(4,0))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index ac91bcf067..0000000000
--- a/test/prism/snapshots/whitequark/def.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 6a1d8cd499..0000000000
--- a/test/prism/snapshots/whitequark/defined.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 4bb97ea025..0000000000
--- a/test/prism/snapshots/whitequark/defs.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-@ 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
- │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 3a21ce5559..0000000000
--- a/test/prism/snapshots/whitequark/empty_stmt.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-@ 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
deleted file mode 100644
index 7104b23494..0000000000
--- a/test/prism/snapshots/whitequark/endless_comparison_method.txt
+++ /dev/null
@@ -1,221 +0,0 @@
-@ 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))
- │ │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :do_something
- │ │ ├── message_loc: (1,16)-(1,28) = "do_something"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:other]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :do_something
- │ │ ├── message_loc: (3,16)-(3,28) = "do_something"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:other]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :do_something
- │ │ ├── message_loc: (5,16)-(5,28) = "do_something"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:other]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :do_something
- │ │ ├── message_loc: (7,16)-(7,28) = "do_something"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:other]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :do_something
- │ │ ├── message_loc: (9,17)-(9,29) = "do_something"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:other]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ └── 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
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :do_something
- │ ├── message_loc: (11,16)-(11,28) = "do_something"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: [:other]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 20550049ce..0000000000
--- a/test/prism/snapshots/whitequark/endless_method.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-@ 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: [:x]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ │ ├── 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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))
- │ │ └── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── locals: [:x]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index c544e19265..0000000000
--- a/test/prism/snapshots/whitequark/endless_method_command_syntax.txt
+++ /dev/null
@@ -1,396 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ │ ├── 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))
- │ │ ├── opening_loc: (13,45)-(13,46) = "\""
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (13,46)-(13,55))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ └── 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: ∅
- │ │ ├── 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))
- │ ├── opening_loc: (15,50)-(15,51) = "\""
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (15,51)-(15,57))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index f4b3ec941e..0000000000
--- a/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- │ ├── 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: [:"..."]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index ba50d04c7b..0000000000
--- a/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ 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
- │ │ ├── keyword_loc: (1,12)-(1,18) = "rescue"
- │ │ └── rescue_expression:
- │ │ @ IntegerNode (location: (1,19)-(1,20))
- │ │ └── flags: decimal
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── keyword_loc: (3,17)-(3,23) = "rescue"
- │ └── rescue_expression:
- │ @ IntegerNode (location: (3,24)-(3,25))
- │ └── flags: decimal
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 1f02c3f940..0000000000
--- a/test/prism/snapshots/whitequark/endless_method_without_args.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-@ 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── keyword_loc: (3,13)-(3,19) = "rescue"
- │ │ └── rescue_expression:
- │ │ @ NilNode (location: (3,20)-(3,23))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── keyword_loc: (7,18)-(7,24) = "rescue"
- │ └── rescue_expression:
- │ @ NilNode (location: (7,25)-(7,28))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 9c93109927..0000000000
--- a/test/prism/snapshots/whitequark/ensure.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 0bab5d80c3..0000000000
--- a/test/prism/snapshots/whitequark/ensure_empty.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-@ 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
deleted file mode 100644
index 00562f703a..0000000000
--- a/test/prism/snapshots/whitequark/false.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 14457fcff2..0000000000
--- a/test/prism/snapshots/whitequark/float.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,4))
- └── body: (length: 2)
- ├── @ FloatNode (location: (1,0)-(1,5))
- └── @ FloatNode (location: (3,0)-(3,4))
diff --git a/test/prism/snapshots/whitequark/for.txt b/test/prism/snapshots/whitequark/for.txt
deleted file mode 100644
index 0f52869838..0000000000
--- a/test/prism/snapshots/whitequark/for.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-@ 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index a4b8e3d349..0000000000
--- a/test/prism/snapshots/whitequark/for_mlhs.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 3d7c90eed2..0000000000
--- a/test/prism/snapshots/whitequark/forward_arg.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-@ 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: ∅
- │ ├── 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: [:"..."]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 1a85c80765..0000000000
--- a/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt
+++ /dev/null
@@ -1,404 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: [:"..."]
- │ │ ├── locals_body_index: 1
- │ │ ├── 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: ∅
- │ │ │ ├── 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: [:"..."]
- │ │ ├── locals_body_index: 1
- │ │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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: ∅
- │ │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ ├── 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, :"..."]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ └── 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: ∅
- │ │ ├── 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, :"..."]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 1)
- │ │ │ └── @ OptionalParameterNode (location: (18,11)-(18,16))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (18,11)-(18,12) = "b"
- │ │ │ ├── operator_loc: (18,13)-(18,14) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (18,15)-(18,16))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest:
- │ │ │ @ ForwardingParameterNode (location: (18,18)-(18,21))
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:a, :b, :"..."]
- │ ├── locals_body_index: 3
- │ ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (21,8)-(21,9) = "b"
- │ │ │ ├── operator_loc: (21,10)-(21,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (21,12)-(21,13))
- │ │ │ └── flags: decimal
- │ │ ├── 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: ∅
- │ │ ├── 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, :"..."]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ ├── name: :b
- │ │ │ ├── name_loc: (25,8)-(25,9) = "b"
- │ │ │ ├── operator_loc: (25,10)-(25,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (25,12)-(25,13))
- │ │ │ └── flags: decimal
- │ │ ├── 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: ∅
- │ │ ├── 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, :"..."]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ └── 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: ∅
- │ ├── 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, :"..."]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 8ece72dd9f..0000000000
--- a/test/prism/snapshots/whitequark/forward_args_legacy.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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: [:"..."]
- │ ├── locals_body_index: 1
- │ ├── 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: [:"..."]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index ee2ae74c6d..0000000000
--- a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ 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))
- │ │ └── name: :argument
- │ ├── optionals: (length: 0)
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest:
- │ │ @ KeywordRestParameterNode (location: (1,18)-(1,20))
- │ │ ├── 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: ∅
- │ ├── 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, :**]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index c590fa3526..0000000000
--- a/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ 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))
- │ │ └── name: :argument
- │ ├── optionals: (length: 0)
- │ ├── rest:
- │ │ @ RestParameterNode (location: (1,18)-(1,19))
- │ │ ├── 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: ∅
- │ ├── 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, :*]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index cb09606e53..0000000000
--- a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ ├── 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: [:**]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 10c0cdc45a..0000000000
--- a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: [:**]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index bd0352377e..0000000000
--- a/test/prism/snapshots/whitequark/forwarded_restarg.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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))
- │ │ ├── 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: ∅
- │ ├── 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: [:*]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index f4401c4389..0000000000
--- a/test/prism/snapshots/whitequark/gvar.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index 541a3a0fc4..0000000000
--- a/test/prism/snapshots/whitequark/gvasgn.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── operator_loc: (1,5)-(1,6) = "="
diff --git a/test/prism/snapshots/whitequark/hash_empty.txt b/test/prism/snapshots/whitequark/hash_empty.txt
deleted file mode 100644
index 38a2c15a9a..0000000000
--- a/test/prism/snapshots/whitequark/hash_empty.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-@ 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
deleted file mode 100644
index 59117a7445..0000000000
--- a/test/prism/snapshots/whitequark/hash_hashrocket.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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:
- │ │ │ @ IntegerNode (location: (1,7)-(1,8))
- │ │ │ └── flags: decimal
- │ │ └── 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:
- │ │ │ @ IntegerNode (location: (3,7)-(3,8))
- │ │ │ └── flags: decimal
- │ │ └── operator_loc: (3,4)-(3,6) = "=>"
- │ └── @ AssocNode (location: (3,10)-(3,23))
- │ ├── key:
- │ │ @ SymbolNode (location: (3,10)-(3,14))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 66bb06e936..0000000000
--- a/test/prism/snapshots/whitequark/hash_kwsplat.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ └── @ AssocSplatNode (location: (1,10)-(1,15))
- │ ├── value:
- │ │ @ CallNode (location: (1,12)-(1,15))
- │ │ ├── flags: variable_call
- │ │ ├── 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
deleted file mode 100644
index 4e385b7df4..0000000000
--- a/test/prism/snapshots/whitequark/hash_label.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 6aa1aac055..0000000000
--- a/test/prism/snapshots/whitequark/hash_label_end.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,22))
- └── body: (length: 3)
- ├── @ CallNode (location: (1,0)-(1,12))
- │ ├── flags: ∅
- │ ├── 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
- │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ └── @ AssocNode (location: (5,12)-(5,21))
- │ ├── key:
- │ │ @ SymbolNode (location: (5,12)-(5,18))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index cfa0feadd4..0000000000
--- a/test/prism/snapshots/whitequark/hash_pair_value_omission.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 86543097ee..0000000000
--- a/test/prism/snapshots/whitequark/heredoc.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-@ 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
deleted file mode 100644
index 233e51de23..0000000000
--- a/test/prism/snapshots/whitequark/if.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 3e83f32c87..0000000000
--- a/test/prism/snapshots/whitequark/if_else.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 50f79966d2..0000000000
--- a/test/prism/snapshots/whitequark/if_elsif.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ │ └── 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
deleted file mode 100644
index 4c01b8fee6..0000000000
--- a/test/prism/snapshots/whitequark/if_masgn__24.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index 58ad3c29fd..0000000000
--- a/test/prism/snapshots/whitequark/if_mod.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index befe49ca45..0000000000
--- a/test/prism/snapshots/whitequark/if_nl_then.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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/if_while_after_class__since_32.txt b/test/prism/snapshots/whitequark/if_while_after_class__since_32.txt
deleted file mode 100644
index 0a2982ed35..0000000000
--- a/test/prism/snapshots/whitequark/if_while_after_class__since_32.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,48))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,48))
- └── body: (length: 4)
- ├── @ ClassNode (location: (1,0)-(1,38))
- │ ├── locals: []
- │ ├── class_keyword_loc: (1,0)-(1,5) = "class"
- │ ├── constant_path:
- │ │ @ ConstantPathNode (location: (1,6)-(1,33))
- │ │ ├── parent:
- │ │ │ @ IfNode (location: (1,6)-(1,25))
- │ │ │ ├── if_keyword_loc: (1,6)-(1,8) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ TrueNode (location: (1,9)-(1,13))
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (1,15)-(1,21))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ ConstantReadNode (location: (1,15)-(1,21))
- │ │ │ │ └── name: :Object
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: (1,22)-(1,25) = "end"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (1,27)-(1,33))
- │ │ │ └── name: :Kernel
- │ │ └── delimiter_loc: (1,25)-(1,27) = "::"
- │ ├── inheritance_operator_loc: ∅
- │ ├── superclass: ∅
- │ ├── body: ∅
- │ ├── end_keyword_loc: (1,35)-(1,38) = "end"
- │ └── name: :Kernel
- ├── @ ClassNode (location: (3,0)-(3,47))
- │ ├── locals: []
- │ ├── class_keyword_loc: (3,0)-(3,5) = "class"
- │ ├── constant_path:
- │ │ @ ConstantPathNode (location: (3,6)-(3,42))
- │ │ ├── parent:
- │ │ │ @ WhileNode (location: (3,6)-(3,34))
- │ │ │ ├── flags: ∅
- │ │ │ ├── keyword_loc: (3,6)-(3,11) = "while"
- │ │ │ ├── closing_loc: (3,31)-(3,34) = "end"
- │ │ │ ├── predicate:
- │ │ │ │ @ TrueNode (location: (3,12)-(3,16))
- │ │ │ └── statements:
- │ │ │ @ StatementsNode (location: (3,18)-(3,30))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ BreakNode (location: (3,18)-(3,30))
- │ │ │ ├── arguments:
- │ │ │ │ @ ArgumentsNode (location: (3,24)-(3,30))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ └── arguments: (length: 1)
- │ │ │ │ └── @ ConstantReadNode (location: (3,24)-(3,30))
- │ │ │ │ └── name: :Object
- │ │ │ └── keyword_loc: (3,18)-(3,23) = "break"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (3,36)-(3,42))
- │ │ │ └── name: :Kernel
- │ │ └── delimiter_loc: (3,34)-(3,36) = "::"
- │ ├── inheritance_operator_loc: ∅
- │ ├── superclass: ∅
- │ ├── body: ∅
- │ ├── end_keyword_loc: (3,44)-(3,47) = "end"
- │ └── name: :Kernel
- ├── @ ModuleNode (location: (5,0)-(5,39))
- │ ├── locals: []
- │ ├── module_keyword_loc: (5,0)-(5,6) = "module"
- │ ├── constant_path:
- │ │ @ ConstantPathNode (location: (5,7)-(5,34))
- │ │ ├── parent:
- │ │ │ @ IfNode (location: (5,7)-(5,26))
- │ │ │ ├── if_keyword_loc: (5,7)-(5,9) = "if"
- │ │ │ ├── predicate:
- │ │ │ │ @ TrueNode (location: (5,10)-(5,14))
- │ │ │ ├── then_keyword_loc: ∅
- │ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (5,16)-(5,22))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ ConstantReadNode (location: (5,16)-(5,22))
- │ │ │ │ └── name: :Object
- │ │ │ ├── consequent: ∅
- │ │ │ └── end_keyword_loc: (5,23)-(5,26) = "end"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (5,28)-(5,34))
- │ │ │ └── name: :Kernel
- │ │ └── delimiter_loc: (5,26)-(5,28) = "::"
- │ ├── body: ∅
- │ ├── end_keyword_loc: (5,36)-(5,39) = "end"
- │ └── name: :Kernel
- └── @ ModuleNode (location: (7,0)-(7,48))
- ├── locals: []
- ├── module_keyword_loc: (7,0)-(7,6) = "module"
- ├── constant_path:
- │ @ ConstantPathNode (location: (7,7)-(7,43))
- │ ├── parent:
- │ │ @ WhileNode (location: (7,7)-(7,35))
- │ │ ├── flags: ∅
- │ │ ├── keyword_loc: (7,7)-(7,12) = "while"
- │ │ ├── closing_loc: (7,32)-(7,35) = "end"
- │ │ ├── predicate:
- │ │ │ @ TrueNode (location: (7,13)-(7,17))
- │ │ └── statements:
- │ │ @ StatementsNode (location: (7,19)-(7,31))
- │ │ └── body: (length: 1)
- │ │ └── @ BreakNode (location: (7,19)-(7,31))
- │ │ ├── arguments:
- │ │ │ @ ArgumentsNode (location: (7,25)-(7,31))
- │ │ │ ├── flags: ∅
- │ │ │ └── arguments: (length: 1)
- │ │ │ └── @ ConstantReadNode (location: (7,25)-(7,31))
- │ │ │ └── name: :Object
- │ │ └── keyword_loc: (7,19)-(7,24) = "break"
- │ ├── child:
- │ │ @ ConstantReadNode (location: (7,37)-(7,43))
- │ │ └── name: :Kernel
- │ └── delimiter_loc: (7,35)-(7,37) = "::"
- ├── body: ∅
- ├── end_keyword_loc: (7,45)-(7,48) = "end"
- └── name: :Kernel
diff --git a/test/prism/snapshots/whitequark/int.txt b/test/prism/snapshots/whitequark/int.txt
deleted file mode 100644
index 8690dee172..0000000000
--- a/test/prism/snapshots/whitequark/int.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
- ├── @ IntegerNode (location: (3,0)-(3,3))
- │ └── flags: decimal
- └── @ IntegerNode (location: (5,0)-(5,2))
- └── flags: decimal
diff --git a/test/prism/snapshots/whitequark/int___LINE__.txt b/test/prism/snapshots/whitequark/int___LINE__.txt
deleted file mode 100644
index bf2ea47102..0000000000
--- a/test/prism/snapshots/whitequark/int___LINE__.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index e867b6bdde..0000000000
--- a/test/prism/snapshots/whitequark/interp_digit_var.txt
+++ /dev/null
@@ -1,273 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 9c70e6e959..0000000000
--- a/test/prism/snapshots/whitequark/ivar.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index 3be3907f62..0000000000
--- a/test/prism/snapshots/whitequark/ivasgn.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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
- └── 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
deleted file mode 100644
index 3ff3f9a176..0000000000
--- a/test/prism/snapshots/whitequark/keyword_argument_omission.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-@ 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: ∅
- ├── 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: static_keys
- │ └── elements: (length: 2)
- │ ├── @ AssocNode (location: (1,4)-(1,6))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,4)-(1,6))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index ad1c1752bf..0000000000
--- a/test/prism/snapshots/whitequark/kwarg.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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))
- │ │ ├── name: :foo
- │ │ └── name_loc: (1,6)-(1,10) = "foo:"
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:foo]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 92eaa5bb0e..0000000000
--- a/test/prism/snapshots/whitequark/kwbegin_compstmt.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 041b0a3773..0000000000
--- a/test/prism/snapshots/whitequark/kwnilarg.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,13))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,13))
- └── body: (length: 3)
- ├── @ LambdaNode (location: (1,0)-(1,12))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index e1fe137c2f..0000000000
--- a/test/prism/snapshots/whitequark/kwoptarg.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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))
- │ │ ├── name: :foo
- │ │ ├── name_loc: (1,6)-(1,10) = "foo:"
- │ │ └── value:
- │ │ @ IntegerNode (location: (1,11)-(1,12))
- │ │ └── flags: decimal
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:foo]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 290d66b0fc..0000000000
--- a/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ 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))
- │ │ ├── name: :a
- │ │ ├── name_loc: (1,6)-(1,8) = "a:"
- │ │ └── value:
- │ │ @ NilNode (location: (1,9)-(1,12))
- │ ├── keyword_rest:
- │ │ @ KeywordRestParameterNode (location: (1,14)-(1,16))
- │ │ ├── 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: ∅
- │ ├── 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, :**]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 73c73087da..0000000000
--- a/test/prism/snapshots/whitequark/kwrestarg_named.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ │ ├── name: :foo
- │ │ ├── name_loc: (1,8)-(1,11) = "foo"
- │ │ └── operator_loc: (1,6)-(1,8) = "**"
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:foo]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index be042c7609..0000000000
--- a/test/prism/snapshots/whitequark/kwrestarg_unnamed.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (1,6)-(1,8) = "**"
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:**]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index b1664264ac..0000000000
--- a/test/prism/snapshots/whitequark/lbrace_arg_after_command_args.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,22))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,22))
- ├── flags: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,11)-(1,20))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,11)-(1,20))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index ac9432787d..0000000000
--- a/test/prism/snapshots/whitequark/lparenarg_after_lvar__since_25.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,15))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,15))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,14))
- │ ├── flags: ∅
- │ ├── 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))
- │ │ │ ├── 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: ∅
- ├── 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))
- │ │ ├── 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
deleted file mode 100644
index 878a4a91f5..0000000000
--- a/test/prism/snapshots/whitequark/lvar.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index a1d70e9ccf..0000000000
--- a/test/prism/snapshots/whitequark/lvar_injecting_match.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index dfa7183840..0000000000
--- a/test/prism/snapshots/whitequark/lvasgn.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-@ 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
- │ └── 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
deleted file mode 100644
index d87d21a605..0000000000
--- a/test/prism/snapshots/whitequark/masgn.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-@ 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
- │ │ └── @ IntegerNode (location: (1,16)-(1,17))
- │ │ └── flags: decimal
- │ ├── 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
- │ │ └── @ IntegerNode (location: (3,14)-(3,15))
- │ │ └── flags: decimal
- │ ├── 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
- │ └── @ IntegerNode (location: (5,19)-(5,20))
- │ └── flags: decimal
- ├── opening_loc: ∅
- └── closing_loc: ∅
diff --git a/test/prism/snapshots/whitequark/masgn_attr.txt b/test/prism/snapshots/whitequark/masgn_attr.txt
deleted file mode 100644
index d87d7a6cb1..0000000000
--- a/test/prism/snapshots/whitequark/masgn_attr.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (3,16)-(3,17))
- │ │ │ └── flags: decimal
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index b9d66d5d89..0000000000
--- a/test/prism/snapshots/whitequark/masgn_cmd.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index 56169deb17..0000000000
--- a/test/prism/snapshots/whitequark/masgn_const.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ 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
deleted file mode 100644
index 6bbfc61ef6..0000000000
--- a/test/prism/snapshots/whitequark/masgn_nested.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index be3cbfb47d..0000000000
--- a/test/prism/snapshots/whitequark/masgn_splat.txt
+++ /dev/null
@@ -1,284 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ ├── 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/method_definition_in_while_cond.txt b/test/prism/snapshots/whitequark/method_definition_in_while_cond.txt
deleted file mode 100644
index 7ad047983d..0000000000
--- a/test/prism/snapshots/whitequark/method_definition_in_while_cond.txt
+++ /dev/null
@@ -1,205 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,47))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,47))
- └── body: (length: 4)
- ├── @ WhileNode (location: (1,0)-(1,45))
- │ ├── flags: ∅
- │ ├── keyword_loc: (1,0)-(1,5) = "while"
- │ ├── closing_loc: (1,42)-(1,45) = "end"
- │ ├── predicate:
- │ │ @ DefNode (location: (1,6)-(1,33))
- │ │ ├── name: :foo
- │ │ ├── name_loc: (1,10)-(1,13) = "foo"
- │ │ ├── receiver: ∅
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (1,14)-(1,28))
- │ │ │ ├── requireds: (length: 0)
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (1,14)-(1,28))
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── name_loc: (1,14)-(1,15) = "a"
- │ │ │ │ ├── operator_loc: (1,16)-(1,17) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ CallNode (location: (1,18)-(1,28))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (1,18)-(1,21) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (1,22)-(1,28))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (1,22)-(1,24) = "do"
- │ │ │ │ └── closing_loc: (1,25)-(1,28) = "end"
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── body: ∅
- │ │ ├── locals: [:a]
- │ │ ├── locals_body_index: 1
- │ │ ├── def_keyword_loc: (1,6)-(1,9) = "def"
- │ │ ├── operator_loc: ∅
- │ │ ├── lparen_loc: ∅
- │ │ ├── rparen_loc: ∅
- │ │ ├── equal_loc: ∅
- │ │ └── end_keyword_loc: (1,30)-(1,33) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (1,35)-(1,40))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (1,35)-(1,40))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,35)-(1,40) = "break"
- ├── @ WhileNode (location: (3,0)-(3,42))
- │ ├── flags: ∅
- │ ├── keyword_loc: (3,0)-(3,5) = "while"
- │ ├── closing_loc: (3,39)-(3,42) = "end"
- │ ├── predicate:
- │ │ @ DefNode (location: (3,6)-(3,30))
- │ │ ├── name: :foo
- │ │ ├── name_loc: (3,10)-(3,13) = "foo"
- │ │ ├── receiver: ∅
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (3,15)-(3,25))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (3,15)-(3,25))
- │ │ │ ├── flags: ∅
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :tap
- │ │ │ ├── message_loc: (3,15)-(3,18) = "tap"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block:
- │ │ │ @ BlockNode (location: (3,19)-(3,25))
- │ │ │ ├── locals: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body: ∅
- │ │ │ ├── opening_loc: (3,19)-(3,21) = "do"
- │ │ │ └── closing_loc: (3,22)-(3,25) = "end"
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── def_keyword_loc: (3,6)-(3,9) = "def"
- │ │ ├── operator_loc: ∅
- │ │ ├── lparen_loc: ∅
- │ │ ├── rparen_loc: ∅
- │ │ ├── equal_loc: ∅
- │ │ └── end_keyword_loc: (3,27)-(3,30) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (3,32)-(3,37))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (3,32)-(3,37))
- │ ├── arguments: ∅
- │ └── keyword_loc: (3,32)-(3,37) = "break"
- ├── @ WhileNode (location: (5,0)-(5,50))
- │ ├── flags: ∅
- │ ├── keyword_loc: (5,0)-(5,5) = "while"
- │ ├── closing_loc: (5,47)-(5,50) = "end"
- │ ├── predicate:
- │ │ @ DefNode (location: (5,6)-(5,38))
- │ │ ├── name: :foo
- │ │ ├── name_loc: (5,15)-(5,18) = "foo"
- │ │ ├── receiver:
- │ │ │ @ SelfNode (location: (5,10)-(5,14))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (5,19)-(5,33))
- │ │ │ ├── requireds: (length: 0)
- │ │ │ ├── optionals: (length: 1)
- │ │ │ │ └── @ OptionalParameterNode (location: (5,19)-(5,33))
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── name_loc: (5,19)-(5,20) = "a"
- │ │ │ │ ├── operator_loc: (5,21)-(5,22) = "="
- │ │ │ │ └── value:
- │ │ │ │ @ CallNode (location: (5,23)-(5,33))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── receiver: ∅
- │ │ │ │ ├── call_operator_loc: ∅
- │ │ │ │ ├── name: :tap
- │ │ │ │ ├── message_loc: (5,23)-(5,26) = "tap"
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── arguments: ∅
- │ │ │ │ ├── closing_loc: ∅
- │ │ │ │ └── block:
- │ │ │ │ @ BlockNode (location: (5,27)-(5,33))
- │ │ │ │ ├── locals: []
- │ │ │ │ ├── locals_body_index: 0
- │ │ │ │ ├── parameters: ∅
- │ │ │ │ ├── body: ∅
- │ │ │ │ ├── opening_loc: (5,27)-(5,29) = "do"
- │ │ │ │ └── closing_loc: (5,30)-(5,33) = "end"
- │ │ │ ├── rest: ∅
- │ │ │ ├── posts: (length: 0)
- │ │ │ ├── keywords: (length: 0)
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── body: ∅
- │ │ ├── locals: [:a]
- │ │ ├── locals_body_index: 1
- │ │ ├── def_keyword_loc: (5,6)-(5,9) = "def"
- │ │ ├── operator_loc: (5,14)-(5,15) = "."
- │ │ ├── lparen_loc: ∅
- │ │ ├── rparen_loc: ∅
- │ │ ├── equal_loc: ∅
- │ │ └── end_keyword_loc: (5,35)-(5,38) = "end"
- │ └── statements:
- │ @ StatementsNode (location: (5,40)-(5,45))
- │ └── body: (length: 1)
- │ └── @ BreakNode (location: (5,40)-(5,45))
- │ ├── arguments: ∅
- │ └── keyword_loc: (5,40)-(5,45) = "break"
- └── @ WhileNode (location: (7,0)-(7,47))
- ├── flags: ∅
- ├── keyword_loc: (7,0)-(7,5) = "while"
- ├── closing_loc: (7,44)-(7,47) = "end"
- ├── predicate:
- │ @ DefNode (location: (7,6)-(7,35))
- │ ├── name: :foo
- │ ├── name_loc: (7,15)-(7,18) = "foo"
- │ ├── receiver:
- │ │ @ SelfNode (location: (7,10)-(7,14))
- │ ├── parameters: ∅
- │ ├── body:
- │ │ @ StatementsNode (location: (7,20)-(7,30))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (7,20)-(7,30))
- │ │ ├── flags: ∅
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :tap
- │ │ ├── message_loc: (7,20)-(7,23) = "tap"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (7,24)-(7,30))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (7,24)-(7,26) = "do"
- │ │ └── closing_loc: (7,27)-(7,30) = "end"
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── def_keyword_loc: (7,6)-(7,9) = "def"
- │ ├── operator_loc: (7,14)-(7,15) = "."
- │ ├── lparen_loc: ∅
- │ ├── rparen_loc: ∅
- │ ├── equal_loc: ∅
- │ └── end_keyword_loc: (7,32)-(7,35) = "end"
- └── statements:
- @ StatementsNode (location: (7,37)-(7,42))
- └── body: (length: 1)
- └── @ BreakNode (location: (7,37)-(7,42))
- ├── arguments: ∅
- └── keyword_loc: (7,37)-(7,42) = "break"
diff --git a/test/prism/snapshots/whitequark/module.txt b/test/prism/snapshots/whitequark/module.txt
deleted file mode 100644
index 87348c4ec9..0000000000
--- a/test/prism/snapshots/whitequark/module.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
deleted file mode 100644
index 856ecc8c67..0000000000
--- a/test/prism/snapshots/whitequark/multiple_pattern_matches.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-@ 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (1,10)-(1,11) = "a"
- │ │ │ │ ├── closing_loc: (1,11)-(1,12) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (2,10)-(2,11) = "a"
- │ │ │ │ ├── closing_loc: (2,11)-(2,12) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (4,10)-(4,11) = "a"
- │ │ │ │ ├── closing_loc: (4,11)-(4,12) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── value_loc: (5,10)-(5,11) = "a"
- │ │ │ ├── closing_loc: (5,11)-(5,12) = ":"
- │ │ │ └── unescaped: "a"
- │ │ ├── value: ∅
- │ │ └── 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
deleted file mode 100644
index 0e036fbd85..0000000000
--- a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-@ 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
- │ │ ├── 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: ∅
- │ │ │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ │ │ ├── value_loc: (2,3)-(2,4) = "a"
- │ │ │ │ │ │ ├── closing_loc: (2,4)-(2,5) = ":"
- │ │ │ │ │ │ └── unescaped: "a"
- │ │ │ │ │ ├── value: ∅
- │ │ │ │ │ └── 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
- │ │ │ │ └── @ 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: ∅
- │ │ │ │ │ ├── opening_loc: (5,3)-(5,4) = "\""
- │ │ │ │ │ ├── value_loc: (5,4)-(5,5) = "b"
- │ │ │ │ │ ├── closing_loc: (5,5)-(5,7) = "\":"
- │ │ │ │ │ └── unescaped: "b"
- │ │ │ │ ├── value: ∅
- │ │ │ │ └── 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
- │ │ │ └── @ 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
- │ │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (10,8)-(11,1))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (10,8)-(10,14))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── operator_loc: ∅
- │ ├── closing_loc: ∅
- │ └── block: ∅
- └── @ CallNode (location: (13,0)-(14,1))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (13,0)-(13,3))
- │ ├── flags: variable_call
- │ ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (13,8)-(14,1))
- │ ├── key:
- │ │ @ SymbolNode (location: (13,8)-(13,12))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── operator_loc: ∅
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/whitequark/next.txt b/test/prism/snapshots/whitequark/next.txt
deleted file mode 100644
index 74a071ba78..0000000000
--- a/test/prism/snapshots/whitequark/next.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,9))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,9))
- └── body: (length: 4)
- ├── @ NextNode (location: (1,0)-(1,4))
- │ ├── arguments: ∅
- │ └── keyword_loc: (1,0)-(1,4) = "next"
- ├── @ NextNode (location: (3,0)-(3,8))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (3,5)-(3,8))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (3,5)-(3,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (3,5)-(3,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── keyword_loc: (3,0)-(3,4) = "next"
- ├── @ NextNode (location: (5,0)-(5,6))
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (5,4)-(5,6))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ ParenthesesNode (location: (5,4)-(5,6))
- │ │ ├── body: ∅
- │ │ ├── opening_loc: (5,4)-(5,5) = "("
- │ │ └── closing_loc: (5,5)-(5,6) = ")"
- │ └── keyword_loc: (5,0)-(5,4) = "next"
- └── @ NextNode (location: (7,0)-(7,9))
- ├── arguments:
- │ @ ArgumentsNode (location: (7,4)-(7,9))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ ParenthesesNode (location: (7,4)-(7,9))
- │ ├── body:
- │ │ @ StatementsNode (location: (7,5)-(7,8))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (7,5)-(7,8))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (7,5)-(7,8) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── opening_loc: (7,4)-(7,5) = "("
- │ └── closing_loc: (7,8)-(7,9) = ")"
- └── keyword_loc: (7,0)-(7,4) = "next"
diff --git a/test/prism/snapshots/whitequark/next_block.txt b/test/prism/snapshots/whitequark/next_block.txt
deleted file mode 100644
index 99a4d87747..0000000000
--- a/test/prism/snapshots/whitequark/next_block.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,19))
- └── body: (length: 1)
- └── @ NextNode (location: (1,0)-(1,19))
- ├── arguments:
- │ @ ArgumentsNode (location: (1,5)-(1,19))
- │ ├── flags: ∅
- │ └── arguments: (length: 1)
- │ └── @ CallNode (location: (1,5)-(1,19))
- │ ├── flags: ∅
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── name: :fun
- │ ├── message_loc: (1,5)-(1,8) = "fun"
- │ ├── opening_loc: ∅
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (1,9)-(1,12))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ CallNode (location: (1,9)-(1,12))
- │ │ ├── flags: variable_call
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (1,9)-(1,12) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (1,13)-(1,19))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,13)-(1,15) = "do"
- │ └── closing_loc: (1,16)-(1,19) = "end"
- └── keyword_loc: (1,0)-(1,4) = "next"
diff --git a/test/prism/snapshots/whitequark/nil.txt b/test/prism/snapshots/whitequark/nil.txt
deleted file mode 100644
index 15774c02fd..0000000000
--- a/test/prism/snapshots/whitequark/nil.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 7421115611..0000000000
--- a/test/prism/snapshots/whitequark/nil_expression.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-@ 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
deleted file mode 100644
index 7b577e5bd9..0000000000
--- a/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- │ │ │ └── closing_loc: (1,4)-(1,5) = "}"
- │ │ └── @ StringNode (location: (1,5)-(1,18))
- │ │ ├── flags: ∅
- │ │ ├── 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
deleted file mode 100644
index 95984ddc06..0000000000
--- a/test/prism/snapshots/whitequark/not.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index d2e82ae62c..0000000000
--- a/test/prism/snapshots/whitequark/not_cmd.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index f25433976f..0000000000
--- a/test/prism/snapshots/whitequark/not_masgn__24.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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
- │ │ ├── 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
deleted file mode 100644
index 1d386d518b..0000000000
--- a/test/prism/snapshots/whitequark/nth_ref.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index ed70923edf..0000000000
--- a/test/prism/snapshots/whitequark/numbered_args_after_27.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 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]
- │ ├── locals_body_index: 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: ∅
- │ ├── 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]
- │ ├── locals_body_index: 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: ∅
- ├── 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]
- ├── locals_body_index: 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
deleted file mode 100644
index bfd1bb8e0c..0000000000
--- a/test/prism/snapshots/whitequark/numparam_outside_block.txt
+++ /dev/null
@@ -1,115 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :_1
- │ │ ├── message_loc: (7,12)-(7,14) = "_1"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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/op_asgn.txt b/test/prism/snapshots/whitequark/op_asgn.txt
deleted file mode 100644
index 76f2e27dd9..0000000000
--- a/test/prism/snapshots/whitequark/op_asgn.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-@ 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
- │ │ ├── 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
- ├── @ CallOperatorWriteNode (location: (3,0)-(3,10))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (3,0)-(3,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- └── @ CallOperatorWriteNode (location: (5,0)-(5,11))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (5,0)-(5,3))
- │ ├── flags: variable_call
- │ ├── 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
diff --git a/test/prism/snapshots/whitequark/op_asgn_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
deleted file mode 100644
index cb390aa010..0000000000
--- a/test/prism/snapshots/whitequark/op_asgn_cmd.txt
+++ /dev/null
@@ -1,178 +0,0 @@
-@ 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index abeb1626ff..0000000000
--- a/test/prism/snapshots/whitequark/op_asgn_index.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ ├── 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
- │ └── @ IntegerNode (location: (1,7)-(1,8))
- │ └── flags: decimal
- ├── closing_loc: (1,8)-(1,9) = "]"
- ├── block: ∅
- ├── operator: :+
- ├── operator_loc: (1,10)-(1,12) = "+="
- └── value:
- @ IntegerNode (location: (1,13)-(1,14))
- └── flags: decimal
diff --git a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
deleted file mode 100644
index ffbbff9e5f..0000000000
--- a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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
- │ ├── 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
- │ └── @ IntegerNode (location: (1,7)-(1,8))
- │ └── flags: decimal
- ├── closing_loc: (1,8)-(1,9) = "]"
- ├── block: ∅
- ├── operator: :+
- ├── operator_loc: (1,10)-(1,12) = "+="
- └── value:
- @ CallNode (location: (1,13)-(1,18))
- ├── flags: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index 5a192fc360..0000000000
--- a/test/prism/snapshots/whitequark/optarg.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-@ 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))
- │ │ │ ├── name: :foo
- │ │ │ ├── name_loc: (1,6)-(1,9) = "foo"
- │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (1,12)-(1,13))
- │ │ │ └── flags: decimal
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── body: ∅
- │ ├── locals: [:foo]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ ├── name: :foo
- │ │ │ ├── name_loc: (3,6)-(3,9) = "foo"
- │ │ │ ├── operator_loc: (3,9)-(3,10) = "="
- │ │ │ └── value:
- │ │ │ @ IntegerNode (location: (3,10)-(3,11))
- │ │ │ └── flags: decimal
- │ │ └── @ OptionalParameterNode (location: (3,13)-(3,18))
- │ │ ├── name: :bar
- │ │ ├── name_loc: (3,13)-(3,16) = "bar"
- │ │ ├── operator_loc: (3,16)-(3,17) = "="
- │ │ └── value:
- │ │ @ IntegerNode (location: (3,17)-(3,18))
- │ │ └── flags: decimal
- │ ├── rest: ∅
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:foo, :bar]
- ├── locals_body_index: 2
- ├── 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
deleted file mode 100644
index 9e57edb194..0000000000
--- a/test/prism/snapshots/whitequark/or.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index e795a5a28a..0000000000
--- a/test/prism/snapshots/whitequark/or_asgn.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- └── @ IndexOrWriteNode (location: (3,0)-(3,15))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (3,0)-(3,3))
- │ ├── flags: variable_call
- │ ├── 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
- │ └── @ IntegerNode (location: (3,7)-(3,8))
- │ └── flags: decimal
- ├── closing_loc: (3,8)-(3,9) = "]"
- ├── block: ∅
- ├── operator_loc: (3,10)-(3,13) = "||="
- └── value:
- @ IntegerNode (location: (3,14)-(3,15))
- └── flags: decimal
diff --git a/test/prism/snapshots/whitequark/parser_bug_272.txt b/test/prism/snapshots/whitequark/parser_bug_272.txt
deleted file mode 100644
index 70d6b71930..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_272.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (1,8)-(1,11))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (1,9)-(1,10))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
- │ │ │ └── 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
deleted file mode 100644
index f33f18623c..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_490.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index b8f9c0f83f..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_507.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── 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
deleted file mode 100644
index b63fbb8284..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_518.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-@ 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
deleted file mode 100644
index 087cc76e1b..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_525.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,32))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,32))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,32))
- ├── flags: ∅
- ├── 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: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,3)-(1,11))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,3)-(1,5))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,16)-(1,27))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,16)-(1,27))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index ee00389c90..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_604.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ ├── 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
- │ │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 0320011e2e..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_640.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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) = "<<~FOO"
- ├── content_loc: (2,0)-(4,0) = " baz\\\n qux\n"
- ├── closing_loc: (4,0)-(5,0) = "FOO\n"
- └── unescaped: "baz qux\n"
diff --git a/test/prism/snapshots/whitequark/parser_bug_645.txt b/test/prism/snapshots/whitequark/parser_bug_645.txt
deleted file mode 100644
index 16b1e171d2..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_645.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── 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
deleted file mode 100644
index e920108731..0000000000
--- a/test/prism/snapshots/whitequark/parser_bug_830.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,4))
- └── body: (length: 1)
- └── @ RegularExpressionNode (location: (1,0)-(1,4))
- ├── flags: ∅
- ├── 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_drops_truncated_parts_of_squiggly_heredoc.txt b/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
deleted file mode 100644
index d974435534..0000000000
--- a/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,7))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,7))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,7))
- ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index aac6b051b3..0000000000
--- a/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index b3a6af3ec8..0000000000
--- a/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-@ 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))
- │ │ │ └── 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
- │ │ │ ├── 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))
- │ │ │ │ └── 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
deleted file mode 100644
index 308abd2f02..0000000000
--- a/test/prism/snapshots/whitequark/pattern_matching_blank_else.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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
- ├── conditions: (length: 1)
- │ └── @ InNode (location: (1,8)-(1,15))
- │ ├── pattern:
- │ │ @ IntegerNode (location: (1,11)-(1,12))
- │ │ └── flags: decimal
- │ ├── statements:
- │ │ @ StatementsNode (location: (1,14)-(1,15))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (1,14)-(1,15))
- │ │ └── flags: decimal
- │ ├── 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
deleted file mode 100644
index 944cc7b429..0000000000
--- a/test/prism/snapshots/whitequark/pattern_matching_else.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- ├── conditions: (length: 1)
- │ └── @ InNode (location: (1,8)-(1,15))
- │ ├── pattern:
- │ │ @ IntegerNode (location: (1,11)-(1,12))
- │ │ └── flags: decimal
- │ ├── statements:
- │ │ @ StatementsNode (location: (1,14)-(1,15))
- │ │ └── body: (length: 1)
- │ │ └── @ IntegerNode (location: (1,14)-(1,15))
- │ │ └── flags: decimal
- │ ├── 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
- │ └── 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
deleted file mode 100644
index 4cda50acb1..0000000000
--- a/test/prism/snapshots/whitequark/pattern_matching_single_line.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index dad320593a..0000000000
--- a/test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
+++ /dev/null
@@ -1,233 +0,0 @@
-@ 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
- │ │ │ └── @ IntegerNode (location: (1,4)-(1,5))
- │ │ │ └── flags: decimal
- │ │ ├── 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
- │ │ │ └── @ IntegerNode (location: (3,4)-(3,5))
- │ │ │ └── flags: decimal
- │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (5,10)-(5,11) = "a"
- │ │ │ │ ├── closing_loc: (5,11)-(5,12) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ └── 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: ∅
- │ │ │ │ ├── opening_loc: ∅
- │ │ │ │ ├── value_loc: (7,10)-(7,11) = "a"
- │ │ │ │ ├── closing_loc: (7,11)-(7,12) = ":"
- │ │ │ │ └── unescaped: "a"
- │ │ │ ├── value: ∅
- │ │ │ └── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
deleted file mode 100644
index 1c833ffaa4..0000000000
--- a/test/prism/snapshots/whitequark/postexe.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 955ba6d444..0000000000
--- a/test/prism/snapshots/whitequark/preexe.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index 5a06fa7f33..0000000000
--- a/test/prism/snapshots/whitequark/procarg0.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,11))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,11))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,18))
- │ ├── flags: ∅
- │ ├── 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]
- │ ├── locals_body_index: 2
- │ ├── 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))
- │ │ │ │ │ │ └── name: :foo
- │ │ │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,14))
- │ │ │ │ │ └── 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: ∅
- ├── 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]
- ├── locals_body_index: 1
- ├── parameters:
- │ @ BlockParametersNode (location: (3,4)-(3,9))
- │ ├── parameters:
- │ │ @ ParametersNode (location: (3,5)-(3,8))
- │ │ ├── requireds: (length: 1)
- │ │ │ └── @ RequiredParameterNode (location: (3,5)-(3,8))
- │ │ │ └── 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
deleted file mode 100644
index 4964755075..0000000000
--- a/test/prism/snapshots/whitequark/range_exclusive.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── right:
- │ @ IntegerNode (location: (1,4)-(1,5))
- │ └── flags: decimal
- └── operator_loc: (1,1)-(1,4) = "..."
diff --git a/test/prism/snapshots/whitequark/range_inclusive.txt b/test/prism/snapshots/whitequark/range_inclusive.txt
deleted file mode 100644
index 04de2d8dec..0000000000
--- a/test/prism/snapshots/whitequark/range_inclusive.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-@ 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
- ├── right:
- │ @ IntegerNode (location: (1,3)-(1,4))
- │ └── flags: decimal
- └── operator_loc: (1,1)-(1,3) = ".."
diff --git a/test/prism/snapshots/whitequark/rational.txt b/test/prism/snapshots/whitequark/rational.txt
deleted file mode 100644
index 260a5d2efc..0000000000
--- a/test/prism/snapshots/whitequark/rational.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-@ 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))
- └── @ RationalNode (location: (3,0)-(3,3))
- └── numeric:
- @ IntegerNode (location: (3,0)-(3,2))
- └── flags: decimal
diff --git a/test/prism/snapshots/whitequark/redo.txt b/test/prism/snapshots/whitequark/redo.txt
deleted file mode 100644
index 48d3da9d52..0000000000
--- a/test/prism/snapshots/whitequark/redo.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,4))
- └── body: (length: 1)
- └── @ RedoNode (location: (1,0)-(1,4))
diff --git a/test/prism/snapshots/whitequark/regex_interp.txt b/test/prism/snapshots/whitequark/regex_interp.txt
deleted file mode 100644
index ef83e9a2e8..0000000000
--- a/test/prism/snapshots/whitequark/regex_interp.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 34fe61c687..0000000000
--- a/test/prism/snapshots/whitequark/regex_plain.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
- ├── 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
deleted file mode 100644
index d5a71cc3f3..0000000000
--- a/test/prism/snapshots/whitequark/resbody_list.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 58b88972f5..0000000000
--- a/test/prism/snapshots/whitequark/resbody_list_mrhs.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 9e2d5ec3f6..0000000000
--- a/test/prism/snapshots/whitequark/resbody_list_var.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index b4c2bc310e..0000000000
--- a/test/prism/snapshots/whitequark/resbody_var.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index ac57561bf5..0000000000
--- a/test/prism/snapshots/whitequark/rescue.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 5a87d408bc..0000000000
--- a/test/prism/snapshots/whitequark/rescue_else.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 9f1f9f51a4..0000000000
--- a/test/prism/snapshots/whitequark/rescue_else_ensure.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 567b283128..0000000000
--- a/test/prism/snapshots/whitequark/rescue_ensure.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-@ 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 1b46b0f258..0000000000
--- a/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,17))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,17))
- └── body: (length: 1)
- └── @ LambdaNode (location: (1,0)-(1,17))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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,6)-(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
deleted file mode 100644
index 413c522102..0000000000
--- a/test/prism/snapshots/whitequark/rescue_mod.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 35d7f01084..0000000000
--- a/test/prism/snapshots/whitequark/rescue_mod_asgn.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 6c3d0e92f0..0000000000
--- a/test/prism/snapshots/whitequark/rescue_mod_masgn.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ ├── 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
- │ └── @ IntegerNode (location: (1,27)-(1,28))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 773b8645a6..0000000000
--- a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 3f086abe57..0000000000
--- a/test/prism/snapshots/whitequark/rescue_without_begin_end.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,30))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,30))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,30))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ BeginNode (location: (1,9)-(1,30))
- │ ├── begin_keyword_loc: ∅
- │ ├── statements:
- │ │ @ StatementsNode (location: (1,9)-(1,12))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (1,9)-(1,12))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index b61f1fb929..0000000000
--- a/test/prism/snapshots/whitequark/restarg_named.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 0879ffa3ee..0000000000
--- a/test/prism/snapshots/whitequark/restarg_unnamed.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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))
- │ │ ├── name: ∅
- │ │ ├── name_loc: ∅
- │ │ └── operator_loc: (1,6)-(1,7) = "*"
- │ ├── posts: (length: 0)
- │ ├── keywords: (length: 0)
- │ ├── keyword_rest: ∅
- │ └── block: ∅
- ├── body: ∅
- ├── locals: [:*]
- ├── locals_body_index: 1
- ├── 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/retry.txt b/test/prism/snapshots/whitequark/retry.txt
deleted file mode 100644
index 671c369514..0000000000
--- a/test/prism/snapshots/whitequark/retry.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,5))
- └── body: (length: 1)
- └── @ RetryNode (location: (1,0)-(1,5))
diff --git a/test/prism/snapshots/whitequark/return.txt b/test/prism/snapshots/whitequark/return.txt
deleted file mode 100644
index 72e4ab9849..0000000000
--- a/test/prism/snapshots/whitequark/return.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 5e55998a2f..0000000000
--- a/test/prism/snapshots/whitequark/return_block.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index cd681d8d3c..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_10279.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 5c26bd6120..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_10653.txt
+++ /dev/null
@@ -1,175 +0,0 @@
-@ 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── 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
- │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── parameters:
- │ │ @ BlockParametersNode (location: (5,16)-(5,19))
- │ │ ├── parameters:
- │ │ │ @ ParametersNode (location: (5,17)-(5,18))
- │ │ │ ├── requireds: (length: 1)
- │ │ │ │ └── @ RequiredParameterNode (location: (5,17)-(5,18))
- │ │ │ │ └── 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: ∅
- │ │ ├── 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
- │ └── 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
deleted file mode 100644
index 329f382d3b..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11107.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,24))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,24))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,24))
- ├── flags: ∅
- ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index cd2939f8bb..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11380.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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: ∅
- ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: ∅
- │ │ ├── opening_loc: (1,7)-(1,8) = ":"
- │ │ ├── value_loc: (1,8)-(1,13) = "hello"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "hello"
- │ └── @ KeywordHashNode (location: (1,17)-(1,21))
- │ ├── flags: static_keys
- │ └── elements: (length: 1)
- │ └── @ AssocNode (location: (1,17)-(1,21))
- │ ├── key:
- │ │ @ SymbolNode (location: (1,17)-(1,19))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ └── operator_loc: ∅
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (1,22)-(1,28))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index de43e28eb2..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11873.txt
+++ /dev/null
@@ -1,785 +0,0 @@
-@ ProgramNode (location: (1,0)-(23,22))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(23,22))
- └── body: (length: 12)
- ├── @ CallNode (location: (1,0)-(1,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,14)-(1,16) = "do"
- │ └── closing_loc: (1,17)-(1,20) = "end"
- ├── @ CallNode (location: (3,0)-(3,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (3,14)-(3,16) = "do"
- │ └── closing_loc: (3,17)-(3,20) = "end"
- ├── @ CallNode (location: (5,0)-(5,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (5,15)-(5,17) = "do"
- │ └── closing_loc: (5,18)-(5,21) = "end"
- ├── @ CallNode (location: (7,0)-(7,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (7,15)-(7,17) = "do"
- │ └── closing_loc: (7,18)-(7,21) = "end"
- ├── @ CallNode (location: (9,0)-(9,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (9,15)-(9,17) = "do"
- │ └── closing_loc: (9,18)-(9,21) = "end"
- ├── @ CallNode (location: (11,0)-(11,22))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (11,16)-(11,18) = "do"
- │ └── closing_loc: (11,19)-(11,22) = "end"
- ├── @ CallNode (location: (13,0)-(13,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (13,4)-(13,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (13,4)-(13,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (13,14)-(13,16) = "do"
- │ └── closing_loc: (13,17)-(13,20) = "end"
- ├── @ CallNode (location: (15,0)-(15,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (15,4)-(15,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (15,4)-(15,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (15,14)-(15,16) = "do"
- │ └── closing_loc: (15,17)-(15,20) = "end"
- ├── @ CallNode (location: (17,0)-(17,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (17,4)-(17,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (17,4)-(17,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (17,15)-(17,17) = "do"
- │ └── closing_loc: (17,18)-(17,21) = "end"
- ├── @ CallNode (location: (19,0)-(19,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (19,4)-(19,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (19,4)-(19,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (19,15)-(19,17) = "do"
- │ └── closing_loc: (19,18)-(19,21) = "end"
- ├── @ CallNode (location: (21,0)-(21,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (21,4)-(21,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (21,4)-(21,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (21,15)-(21,17) = "do"
- │ └── closing_loc: (21,18)-(21,21) = "end"
- └── @ CallNode (location: (23,0)-(23,22))
- ├── flags: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (23,4)-(23,8))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (23,4)-(23,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index d4219b3b77..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt
+++ /dev/null
@@ -1,1245 +0,0 @@
-@ ProgramNode (location: (1,0)-(39,20))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(39,20))
- └── body: (length: 20)
- ├── @ CallNode (location: (1,0)-(1,18))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (1,12)-(1,18))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,12)-(1,14) = "do"
- │ └── closing_loc: (1,15)-(1,18) = "end"
- ├── @ CallNode (location: (3,0)-(3,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (3,14)-(3,20))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (3,14)-(3,16) = "do"
- │ └── closing_loc: (3,17)-(3,20) = "end"
- ├── @ CallNode (location: (5,0)-(5,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (5,15)-(5,21))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (5,15)-(5,17) = "do"
- │ └── closing_loc: (5,18)-(5,21) = "end"
- ├── @ CallNode (location: (7,0)-(7,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (7,15)-(7,21))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (7,15)-(7,17) = "do"
- │ └── closing_loc: (7,18)-(7,21) = "end"
- ├── @ CallNode (location: (9,0)-(9,19))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (9,13)-(9,15) = "do"
- │ └── closing_loc: (9,16)-(9,19) = "end"
- ├── @ CallNode (location: (11,0)-(11,19))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (11,13)-(11,19))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (11,13)-(11,15) = "do"
- │ └── closing_loc: (11,16)-(11,19) = "end"
- ├── @ CallNode (location: (13,0)-(13,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (13,15)-(13,21))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (13,15)-(13,17) = "do"
- │ └── closing_loc: (13,18)-(13,21) = "end"
- ├── @ CallNode (location: (15,0)-(15,22))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (15,16)-(15,22))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (15,16)-(15,18) = "do"
- │ └── closing_loc: (15,19)-(15,22) = "end"
- ├── @ CallNode (location: (17,0)-(17,22))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (17,16)-(17,22))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (17,16)-(17,18) = "do"
- │ └── closing_loc: (17,19)-(17,22) = "end"
- ├── @ CallNode (location: (19,0)-(19,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (19,14)-(19,16) = "do"
- │ └── closing_loc: (19,17)-(19,20) = "end"
- ├── @ CallNode (location: (21,0)-(21,18))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (21,4)-(21,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (21,4)-(21,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (21,12)-(21,18))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (21,12)-(21,14) = "do"
- │ └── closing_loc: (21,15)-(21,18) = "end"
- ├── @ CallNode (location: (23,0)-(23,20))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (23,4)-(23,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (23,4)-(23,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (23,14)-(23,20))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (23,14)-(23,16) = "do"
- │ └── closing_loc: (23,17)-(23,20) = "end"
- ├── @ CallNode (location: (25,0)-(25,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (25,4)-(25,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (25,4)-(25,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (25,15)-(25,21))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (25,15)-(25,17) = "do"
- │ └── closing_loc: (25,18)-(25,21) = "end"
- ├── @ CallNode (location: (27,0)-(27,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (27,4)-(27,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (27,4)-(27,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (27,15)-(27,21))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (27,15)-(27,17) = "do"
- │ └── closing_loc: (27,18)-(27,21) = "end"
- ├── @ CallNode (location: (29,0)-(29,19))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (29,4)-(29,7))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (29,4)-(29,7))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (29,13)-(29,15) = "do"
- │ └── closing_loc: (29,16)-(29,19) = "end"
- ├── @ CallNode (location: (31,0)-(31,19))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (31,4)-(31,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (31,4)-(31,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (31,13)-(31,19))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (31,13)-(31,15) = "do"
- │ └── closing_loc: (31,16)-(31,19) = "end"
- ├── @ CallNode (location: (33,0)-(33,21))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (33,4)-(33,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (33,4)-(33,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (33,15)-(33,21))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (33,15)-(33,17) = "do"
- │ └── closing_loc: (33,18)-(33,21) = "end"
- ├── @ CallNode (location: (35,0)-(35,22))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (35,4)-(35,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (35,4)-(35,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (35,16)-(35,22))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (35,16)-(35,18) = "do"
- │ └── closing_loc: (35,19)-(35,22) = "end"
- ├── @ CallNode (location: (37,0)-(37,22))
- │ ├── flags: ∅
- │ ├── 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: ∅
- │ │ │ ├── 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: []
- │ │ │ ├── locals_body_index: 0
- │ │ │ ├── parameters: ∅
- │ │ │ ├── body:
- │ │ │ │ @ StatementsNode (location: (37,4)-(37,8))
- │ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ CallNode (location: (37,4)-(37,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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))
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (37,16)-(37,22))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (37,16)-(37,18) = "do"
- │ └── closing_loc: (37,19)-(37,22) = "end"
- └── @ CallNode (location: (39,0)-(39,20))
- ├── flags: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (39,4)-(39,8))
- │ │ │ └── body: (length: 1)
- │ │ │ └── @ CallNode (location: (39,4)-(39,8))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 62d3b0387d..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,25))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,25))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,25))
- ├── flags: ∅
- ├── 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: ∅
- │ │ ├── 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: []
- │ │ ├── locals_body_index: 0
- │ │ ├── parameters: ∅
- │ │ ├── body:
- │ │ │ @ StatementsNode (location: (1,4)-(1,12))
- │ │ │ └── body: (length: 2)
- │ │ │ ├── @ CallNode (location: (1,4)-(1,8))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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
- │ │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index b853f81f46..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11989.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-@ 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: ∅
- ├── 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
deleted file mode 100644
index e726cff9bf..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_11990.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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: ∅
- ├── 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))
- │ ├── opening_loc: ∅
- │ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (1,2)-(1,6))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 521df7a013..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_12073.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-@ 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
- │ └── operator_loc: (1,2)-(1,3) = "="
- ├── @ CallNode (location: (1,7)-(1,13))
- │ ├── flags: ∅
- │ ├── 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: static_keys
- │ │ └── elements: (length: 1)
- │ │ └── @ AssocNode (location: (1,9)-(1,13))
- │ │ ├── key:
- │ │ │ @ SymbolNode (location: (1,9)-(1,11))
- │ │ │ ├── flags: ∅
- │ │ │ ├── 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
- │ │ └── 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))
- │ │ └── 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: ∅
- │ ├── 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]
- ├── locals_body_index: 1
- ├── 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
deleted file mode 100644
index 76a8facca6..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_12402.txt
+++ /dev/null
@@ -1,565 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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
- ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index 95e438f7d5..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_12669.txt
+++ /dev/null
@@ -1,133 +0,0 @@
-@ 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ │ │ ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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
deleted file mode 100644
index d236b88348..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_12686.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index 3d1fdaf853..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_13547.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index f7fa7b0496..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_14690.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,23))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,23))
- └── body: (length: 1)
- └── @ CallNode (location: (1,0)-(1,23))
- ├── flags: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── parameters: ∅
- ├── body:
- │ @ StatementsNode (location: (1,9)-(1,21))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,9)-(1,21))
- │ ├── flags: ∅
- │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
deleted file mode 100644
index de09d37a4d..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_15789.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,19))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,19))
- └── body: (length: 2)
- ├── @ CallNode (location: (1,0)-(1,20))
- │ ├── flags: ∅
- │ ├── 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]
- │ │ ├── locals_body_index: 1
- │ │ ├── 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))
- │ │ │ │ │ ├── name: :a
- │ │ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
- │ │ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
- │ │ │ │ │ └── value:
- │ │ │ │ │ @ LambdaNode (location: (1,9)-(1,15))
- │ │ │ │ │ ├── locals: [:_1]
- │ │ │ │ │ ├── locals_body_index: 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: ∅
- ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── name_loc: (3,5)-(3,7) = "a:"
- │ │ │ │ └── value:
- │ │ │ │ @ LambdaNode (location: (3,8)-(3,14))
- │ │ │ │ ├── locals: [:_1]
- │ │ │ │ ├── locals_body_index: 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
deleted file mode 100644
index 8f6d188acd..0000000000
--- a/test/prism/snapshots/whitequark/ruby_bug_9669.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-@ 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))
- │ │ │ ├── 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]
- │ ├── locals_body_index: 1
- │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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
deleted file mode 100644
index 1947a4638d..0000000000
--- a/test/prism/snapshots/whitequark/sclass.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index c69f8fa8c5..0000000000
--- a/test/prism/snapshots/whitequark/self.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 938fcf7541..0000000000
--- a/test/prism/snapshots/whitequark/send_attr_asgn.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (3,0)-(3,9))
- │ ├── flags: attribute_write
- │ ├── receiver:
- │ │ @ CallNode (location: (3,0)-(3,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── 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
- │ │ │ ├── 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
- └── @ CallNode (location: (7,0)-(7,10))
- ├── flags: attribute_write
- ├── receiver:
- │ @ CallNode (location: (7,0)-(7,3))
- │ ├── flags: variable_call
- │ ├── 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
- ├── 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
deleted file mode 100644
index 530ae74362..0000000000
--- a/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ 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
- │ ├── 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
- ├── closing_loc: ∅
- └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_binary_op.txt b/test/prism/snapshots/whitequark/send_binary_op.txt
deleted file mode 100644
index c18eb69f2c..0000000000
--- a/test/prism/snapshots/whitequark/send_binary_op.txt
+++ /dev/null
@@ -1,530 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (3,0)-(3,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (3,0)-(3,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (5,0)-(5,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (5,0)-(5,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (7,0)-(7,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (7,0)-(7,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (9,0)-(9,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (9,0)-(9,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (11,0)-(11,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (11,0)-(11,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (13,0)-(13,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (13,0)-(13,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (15,0)-(15,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (15,0)-(15,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (17,0)-(17,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (17,0)-(17,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (19,0)-(19,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (19,0)-(19,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (21,0)-(21,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (21,0)-(21,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (23,0)-(23,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (23,0)-(23,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (25,0)-(25,9))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (25,0)-(25,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (27,0)-(27,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (27,0)-(27,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (29,0)-(29,9))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (29,0)-(29,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (31,0)-(31,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (31,0)-(31,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (33,0)-(33,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (33,0)-(33,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (35,0)-(35,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (35,0)-(35,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (37,0)-(37,8))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (37,0)-(37,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- ├── @ CallNode (location: (39,0)-(39,7))
- │ ├── flags: ∅
- │ ├── receiver:
- │ │ @ CallNode (location: (39,0)-(39,3))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block: ∅
- └── @ CallNode (location: (41,0)-(41,7))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (41,0)-(41,3))
- │ ├── flags: variable_call
- │ ├── 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
- ├── 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
deleted file mode 100644
index 83e8186450..0000000000
--- a/test/prism/snapshots/whitequark/send_block_chain_cmd.txt
+++ /dev/null
@@ -1,328 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (1,7)-(1,13))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (3,7)-(3,13))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (5,7)-(5,13))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (7,7)-(7,13))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (9,7)-(9,13))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: ∅
- │ │ ├── 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
- │ │ ├── closing_loc: ∅
- │ │ └── block:
- │ │ @ BlockNode (location: (11,7)-(11,13))
- │ │ ├── locals: []
- │ │ ├── locals_body_index: 0
- │ │ ├── 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
- │ │ ├── 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: ∅
- │ ├── 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
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (13,7)-(13,13))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 9b6b288434..0000000000
--- a/test/prism/snapshots/whitequark/send_block_conditional.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 0135a5d854..0000000000
--- a/test/prism/snapshots/whitequark/send_call.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── closing_loc: (1,6)-(1,7) = ")"
- │ └── block: ∅
- └── @ CallNode (location: (3,0)-(3,8))
- ├── flags: ∅
- ├── receiver:
- │ @ CallNode (location: (3,0)-(3,3))
- │ ├── flags: variable_call
- │ ├── 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
- ├── 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
deleted file mode 100644
index a6ba52bede..0000000000
--- a/test/prism/snapshots/whitequark/send_conditional.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-@ 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
- │ ├── 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
deleted file mode 100644
index df9ed12a3a..0000000000
--- a/test/prism/snapshots/whitequark/send_index.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- │ ├── 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
- │ └── @ IntegerNode (location: (1,7)-(1,8))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 34adbb1dde..0000000000
--- a/test/prism/snapshots/whitequark/send_index_asgn.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── @ IntegerNode (location: (1,7)-(1,8))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (1,12)-(1,13))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 34adbb1dde..0000000000
--- a/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── @ IntegerNode (location: (1,7)-(1,8))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (1,12)-(1,13))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index e1a6caa7ad..0000000000
--- a/test/prism/snapshots/whitequark/send_index_cmd.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index df9ed12a3a..0000000000
--- a/test/prism/snapshots/whitequark/send_index_legacy.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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
- │ ├── 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
- │ └── @ IntegerNode (location: (1,7)-(1,8))
- │ └── flags: decimal
- ├── 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
deleted file mode 100644
index 5b0aa38d3d..0000000000
--- a/test/prism/snapshots/whitequark/send_lambda.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-@ ProgramNode (location: (1,0)-(5,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(5,5))
- └── body: (length: 3)
- ├── @ LambdaNode (location: (1,0)-(1,8))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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))
- │ │ │ │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index e5ca1e2ee7..0000000000
--- a/test/prism/snapshots/whitequark/send_lambda_args.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ └── 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]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ └── 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
deleted file mode 100644
index b97b8647ab..0000000000
--- a/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-@ 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]
- │ ├── locals_body_index: 1
- │ ├── 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))
- │ │ │ │ ├── name: :a
- │ │ │ │ ├── name_loc: (1,3)-(1,5) = "a:"
- │ │ │ │ └── value:
- │ │ │ │ @ IntegerNode (location: (1,6)-(1,7))
- │ │ │ │ └── flags: decimal
- │ │ │ ├── keyword_rest: ∅
- │ │ │ └── block: ∅
- │ │ ├── locals: (length: 0)
- │ │ ├── opening_loc: ∅
- │ │ └── closing_loc: ∅
- │ └── body: ∅
- └── @ LambdaNode (location: (3,0)-(3,9))
- ├── locals: [:a]
- ├── locals_body_index: 1
- ├── 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))
- │ │ │ ├── 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
deleted file mode 100644
index 388988b573..0000000000
--- a/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-@ 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]
- ├── locals_body_index: 3
- ├── 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))
- │ │ │ └── name: :a
- │ │ ├── optionals: (length: 0)
- │ │ ├── rest: ∅
- │ │ ├── posts: (length: 0)
- │ │ ├── keywords: (length: 0)
- │ │ ├── keyword_rest: ∅
- │ │ └── block: ∅
- │ ├── locals: (length: 2)
- │ │ ├── @ BlockLocalVariableNode (location: (1,6)-(1,9))
- │ │ │ └── name: :foo
- │ │ └── @ BlockLocalVariableNode (location: (1,11)-(1,14))
- │ │ └── 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
deleted file mode 100644
index bf05f2267a..0000000000
--- a/test/prism/snapshots/whitequark/send_lambda_legacy.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,5))
- └── body: (length: 1)
- └── @ LambdaNode (location: (1,0)-(1,5))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index a8d1e7ea83..0000000000
--- a/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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
- │ ├── 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
diff --git a/test/prism/snapshots/whitequark/send_plain.txt b/test/prism/snapshots/whitequark/send_plain.txt
deleted file mode 100644
index 355f460f53..0000000000
--- a/test/prism/snapshots/whitequark/send_plain.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index e1ab3b8f2f..0000000000
--- a/test/prism/snapshots/whitequark/send_plain_cmd.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index cc87037252..0000000000
--- a/test/prism/snapshots/whitequark/send_self.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ ├── 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: ∅
- ├── 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
- ├── 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
deleted file mode 100644
index d66949ac36..0000000000
--- a/test/prism/snapshots/whitequark/send_self_block.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,10))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,10))
- └── body: (length: 4)
- ├── @ CallNode (location: (1,0)-(1,10))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (1,4)-(1,6) = "do"
- │ └── closing_loc: (1,7)-(1,10) = "end"
- ├── @ CallNode (location: (3,0)-(3,7))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (3,4)-(3,5) = "{"
- │ └── closing_loc: (3,6)-(3,7) = "}"
- ├── @ CallNode (location: (5,0)-(5,9))
- │ ├── flags: ∅
- │ ├── 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: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (5,6)-(5,7) = "{"
- │ └── closing_loc: (5,8)-(5,9) = "}"
- └── @ CallNode (location: (7,0)-(7,10))
- ├── flags: ∅
- ├── 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
- ├── closing_loc: (7,5)-(7,6) = ")"
- └── block:
- @ BlockNode (location: (7,7)-(7,10))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 163146793d..0000000000
--- a/test/prism/snapshots/whitequark/send_unary_op.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 58a134dd62..0000000000
--- a/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-@ 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))
- ├── opening_loc: (8,0)-(8,4) = "<<~E"
- ├── parts: (length: 2)
- │ ├── @ StringNode (location: (9,0)-(11,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (9,0)-(11,0) = " 1 \\\n 2\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "1 2\n"
- │ └── @ StringNode (location: (11,0)-(12,0))
- │ ├── flags: ∅
- │ ├── 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
deleted file mode 100644
index a116b67b1b..0000000000
--- a/test/prism/snapshots/whitequark/space_args_arg.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index cb5dd7281c..0000000000
--- a/test/prism/snapshots/whitequark/space_args_arg_block.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── opening_loc: (1,8)-(1,9) = "("
- │ │ └── closing_loc: (1,10)-(1,11) = ")"
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (1,12)-(1,14))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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
- │ │ ├── opening_loc: (3,9)-(3,10) = "("
- │ │ └── closing_loc: (3,11)-(3,12) = ")"
- │ ├── closing_loc: ∅
- │ └── block:
- │ @ BlockNode (location: (3,13)-(3,15))
- │ ├── locals: []
- │ ├── locals_body_index: 0
- │ ├── parameters: ∅
- │ ├── body: ∅
- │ ├── opening_loc: (3,13)-(3,14) = "{"
- │ └── closing_loc: (3,14)-(3,15) = "}"
- └── @ CallNode (location: (5,0)-(5,10))
- ├── flags: ∅
- ├── 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
- │ ├── opening_loc: (5,4)-(5,5) = "("
- │ └── closing_loc: (5,6)-(5,7) = ")"
- ├── closing_loc: ∅
- └── block:
- @ BlockNode (location: (5,8)-(5,10))
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index f1339b89fa..0000000000
--- a/test/prism/snapshots/whitequark/space_args_arg_call.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ 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: ∅
- ├── 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
- │ │ ├── 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
deleted file mode 100644
index 68bf503bc7..0000000000
--- a/test/prism/snapshots/whitequark/space_args_arg_newline.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@ 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: ∅
- ├── 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
- │ ├── 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
deleted file mode 100644
index da513176a3..0000000000
--- a/test/prism/snapshots/whitequark/space_args_block.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-@ 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: ∅
- ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 7cc14caaf3..0000000000
--- a/test/prism/snapshots/whitequark/space_args_cmd.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-@ 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: ∅
- ├── 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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
deleted file mode 100644
index c6ce21be5f..0000000000
--- a/test/prism/snapshots/whitequark/string___FILE__.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,8))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,8))
- └── body: (length: 1)
- └── @ SourceFileNode (location: (1,0)-(1,8))
- └── filepath: "whitequark/string___FILE__.txt"
diff --git a/test/prism/snapshots/whitequark/string_concat.txt b/test/prism/snapshots/whitequark/string_concat.txt
deleted file mode 100644
index 38ea0c745d..0000000000
--- a/test/prism/snapshots/whitequark/string_concat.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,14))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,14))
- ├── opening_loc: ∅
- ├── parts: (length: 2)
- │ ├── @ InterpolatedStringNode (location: (1,0)-(1,8))
- │ │ ├── opening_loc: (1,0)-(1,1) = "\""
- │ │ ├── parts: (length: 2)
- │ │ │ ├── @ StringNode (location: (1,1)-(1,4))
- │ │ │ │ ├── flags: ∅
- │ │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 123b36e01d..0000000000
--- a/test/prism/snapshots/whitequark/string_dvar.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,14))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,14))
- ├── 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: ∅
- │ │ ├── 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: ∅
- │ │ ├── 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
deleted file mode 100644
index 90a4ee5a70..0000000000
--- a/test/prism/snapshots/whitequark/string_interp.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ ProgramNode (location: (1,0)-(1,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(1,14))
- └── body: (length: 1)
- └── @ InterpolatedStringNode (location: (1,0)-(1,14))
- ├── opening_loc: (1,0)-(1,1) = "\""
- ├── parts: (length: 3)
- │ ├── @ StringNode (location: (1,1)-(1,4))
- │ │ ├── flags: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 7534ac1844..0000000000
--- a/test/prism/snapshots/whitequark/string_plain.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ 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
deleted file mode 100644
index 4cd4a940dc..0000000000
--- a/test/prism/snapshots/whitequark/super.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 0ad1f04bd2..0000000000
--- a/test/prism/snapshots/whitequark/super_block.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-@ 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: []
- │ ├── locals_body_index: 0
- │ ├── 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
- │ │ ├── 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
- │ ├── 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: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index dac34b63bc..0000000000
--- a/test/prism/snapshots/whitequark/symbol_interp.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 54c7ce1b5c..0000000000
--- a/test/prism/snapshots/whitequark/symbol_plain.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-@ ProgramNode (location: (1,0)-(3,4))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(3,4))
- └── body: (length: 2)
- ├── @ SymbolNode (location: (1,0)-(1,6))
- │ ├── flags: ∅
- │ ├── 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: ∅
- ├── 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
deleted file mode 100644
index 913f1227ff..0000000000
--- a/test/prism/snapshots/whitequark/ternary.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
- │ └── 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
deleted file mode 100644
index faf7a0c36b..0000000000
--- a/test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ └── 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
- │ │ ├── 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
deleted file mode 100644
index 0c27ddd67e..0000000000
--- a/test/prism/snapshots/whitequark/trailing_forward_arg.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-@ 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))
- │ │ │ └── name: :a
- │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
- │ │ └── 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: ∅
- │ ├── 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
- │ │ └── @ ForwardingArgumentsNode (location: (1,31)-(1,34))
- │ ├── closing_loc: (1,34)-(1,35) = ")"
- │ └── block: ∅
- ├── locals: [:a, :b, :"..."]
- ├── locals_body_index: 3
- ├── 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
deleted file mode 100644
index 3e1ceef586..0000000000
--- a/test/prism/snapshots/whitequark/true.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-@ 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
deleted file mode 100644
index 4bc54ba22c..0000000000
--- a/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-@ 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))
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
- │ │ ├── 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))
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 6d0bffb289..0000000000
--- a/test/prism/snapshots/whitequark/undef.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-@ 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── value_loc: (1,6)-(1,9) = "foo"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "foo"
- │ ├── @ SymbolNode (location: (1,11)-(1,15))
- │ │ ├── flags: ∅
- │ │ ├── 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: ∅
- │ │ │ ├── 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
- │ │ └── 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
deleted file mode 100644
index d9261db337..0000000000
--- a/test/prism/snapshots/whitequark/unless.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 78f942fcca..0000000000
--- a/test/prism/snapshots/whitequark/unless_else.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-@ 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
- │ │ ├── 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
- │ │ ├── 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
- │ │ │ ├── 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
- │ ├── 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
- │ ├── 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
- │ │ ├── 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
deleted file mode 100644
index bccbeb0b5a..0000000000
--- a/test/prism/snapshots/whitequark/unless_mod.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index 78b8c7dbc8..0000000000
--- a/test/prism/snapshots/whitequark/until.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 07f1817b08..0000000000
--- a/test/prism/snapshots/whitequark/until_mod.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 2aff618af3..0000000000
--- a/test/prism/snapshots/whitequark/until_post.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index fc746a9350..0000000000
--- a/test/prism/snapshots/whitequark/var_and_asgn.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
- ├── name: :a
- └── depth: 0
diff --git a/test/prism/snapshots/whitequark/var_op_asgn.txt b/test/prism/snapshots/whitequark/var_op_asgn.txt
deleted file mode 100644
index c4d20d2ec0..0000000000
--- a/test/prism/snapshots/whitequark/var_op_asgn.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-@ 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
- │ └── 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
- │ └── 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
- │ ├── 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
- │ └── operator: :|
- ├── locals: []
- ├── locals_body_index: 0
- ├── 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
deleted file mode 100644
index 4e574f8db2..0000000000
--- a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-@ 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: ∅
- │ ├── 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
deleted file mode 100644
index d5064bc55b..0000000000
--- a/test/prism/snapshots/whitequark/var_or_asgn.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-@ 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
- ├── name: :a
- └── depth: 0
diff --git a/test/prism/snapshots/whitequark/when_multi.txt b/test/prism/snapshots/whitequark/when_multi.txt
deleted file mode 100644
index 6ae94a3fef..0000000000
--- a/test/prism/snapshots/whitequark/when_multi.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ │ │ ├── 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: ∅
- │ │ ├── opening_loc: (1,22)-(1,23) = "'"
- │ │ ├── content_loc: (1,23)-(1,26) = "baz"
- │ │ ├── closing_loc: (1,26)-(1,27) = "'"
- │ │ └── unescaped: "baz"
- │ └── statements:
- │ @ StatementsNode (location: (1,29)-(1,32))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,29)-(1,32))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index 016f264744..0000000000
--- a/test/prism/snapshots/whitequark/when_splat.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-@ 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
- │ ├── 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
- │ │ │ └── @ SplatNode (location: (1,18)-(1,22))
- │ │ │ ├── operator_loc: (1,18)-(1,19) = "*"
- │ │ │ └── expression:
- │ │ │ @ CallNode (location: (1,19)-(1,22))
- │ │ │ ├── flags: variable_call
- │ │ │ ├── receiver: ∅
- │ │ │ ├── call_operator_loc: ∅
- │ │ │ ├── name: :baz
- │ │ │ ├── message_loc: (1,19)-(1,22) = "baz"
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── arguments: ∅
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── block: ∅
- │ │ └── statements:
- │ │ @ StatementsNode (location: (1,24)-(1,27))
- │ │ └── body: (length: 1)
- │ │ └── @ CallNode (location: (1,24)-(1,27))
- │ │ ├── flags: variable_call
- │ │ ├── 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
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── name: :foo
- │ │ ├── message_loc: (1,35)-(1,38) = "foo"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ └── block: ∅
- │ └── 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
deleted file mode 100644
index 06b7e0ae87..0000000000
--- a/test/prism/snapshots/whitequark/when_then.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-@ 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
- │ ├── 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: ∅
- │ │ ├── opening_loc: (1,15)-(1,16) = "'"
- │ │ ├── content_loc: (1,16)-(1,19) = "bar"
- │ │ ├── closing_loc: (1,19)-(1,20) = "'"
- │ │ └── unescaped: "bar"
- │ └── statements:
- │ @ StatementsNode (location: (1,26)-(1,29))
- │ └── body: (length: 1)
- │ └── @ CallNode (location: (1,26)-(1,29))
- │ ├── flags: variable_call
- │ ├── 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
deleted file mode 100644
index e437a19297..0000000000
--- a/test/prism/snapshots/whitequark/while.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index b659a8f9c0..0000000000
--- a/test/prism/snapshots/whitequark/while_mod.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-@ 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
- │ ├── 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
- ├── 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
deleted file mode 100644
index 10f46e67e1..0000000000
--- a/test/prism/snapshots/whitequark/while_post.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-@ 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
- │ ├── 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
- │ ├── 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
deleted file mode 100644
index ad81c2bc42..0000000000
--- a/test/prism/snapshots/whitequark/xstring_interp.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-@ 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: ∅
- │ │ ├── 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
- │ │ │ ├── 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: ∅
- │ ├── 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
deleted file mode 100644
index 97084286d9..0000000000
--- a/test/prism/snapshots/whitequark/xstring_plain.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-@ 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
deleted file mode 100644
index dccc6b9df9..0000000000
--- a/test/prism/snapshots/whitequark/yield.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-@ 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
- │ │ ├── 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
- │ ├── 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
deleted file mode 100644
index 9c28128d06..0000000000
--- a/test/prism/snapshots/whitequark/zsuper.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-@ 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
deleted file mode 100644
index 9c73210a6b..0000000000
--- a/test/prism/snapshots/xstring.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,5))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,5))
- └── body: (length: 4)
- ├── @ 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: ∅
- │ │ │ ├── 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
- │ │ │ │ ├── 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: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (3,11)-(3,15) = " baz"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: " baz"
- │ └── closing_loc: (3,15)-(3,16) = "`"
- ├── @ XStringNode (location: (5,0)-(5,6))
- │ ├── flags: ∅
- │ ├── opening_loc: (5,0)-(5,1) = "`"
- │ ├── content_loc: (5,1)-(5,5) = "f\\oo"
- │ ├── closing_loc: (5,5)-(5,6) = "`"
- │ └── unescaped: "foo"
- └── @ XStringNode (location: (7,0)-(7,5))
- ├── flags: ∅
- ├── opening_loc: (7,0)-(7,1) = "`"
- ├── content_loc: (7,1)-(7,4) = "foo"
- ├── closing_loc: (7,4)-(7,5) = "`"
- └── unescaped: "foo"
diff --git a/test/prism/snapshots/yield.txt b/test/prism/snapshots/yield.txt
deleted file mode 100644
index 9c1fd59d34..0000000000
--- a/test/prism/snapshots/yield.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-@ ProgramNode (location: (1,0)-(7,14))
-├── locals: []
-└── statements:
- @ StatementsNode (location: (1,0)-(7,14))
- └── 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,7))
- │ ├── keyword_loc: (3,0)-(3,5) = "yield"
- │ ├── lparen_loc: (3,5)-(3,6) = "("
- │ ├── arguments: ∅
- │ └── rparen_loc: (3,6)-(3,7) = ")"
- ├── @ YieldNode (location: (5,0)-(5,8))
- │ ├── keyword_loc: (5,0)-(5,5) = "yield"
- │ ├── 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
- │ └── rparen_loc: (5,7)-(5,8) = ")"
- └── @ YieldNode (location: (7,0)-(7,14))
- ├── keyword_loc: (7,0)-(7,5) = "yield"
- ├── 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
- │ ├── @ IntegerNode (location: (7,9)-(7,10))
- │ │ └── flags: decimal
- │ └── @ IntegerNode (location: (7,12)-(7,13))
- │ └── flags: decimal
- └── rparen_loc: (7,13)-(7,14) = ")"
diff --git a/test/prism/test_helper.rb b/test/prism/test_helper.rb
deleted file mode 100644
index a16de14cbe..0000000000
--- a/test/prism/test_helper.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# 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
-
- 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
- deconstructed_expected = expected.deconstruct_keys(nil)
- deconstructed_actual = actual.deconstruct_keys(nil)
- assert_equal deconstructed_expected.keys, deconstructed_actual.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.
- assert_equal deconstructed_expected.except(:filepath), deconstructed_actual.except(:filepath)
- assert_equal File.basename(deconstructed_expected[:filepath]), File.basename(deconstructed_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
deleted file mode 100644
index 2a352c5234..0000000000
--- a/test/prism/unescape_test.rb
+++ /dev/null
@@ -1,235 +0,0 @@
-# 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
deleted file mode 100644
index 29ee6b224c..0000000000
--- a/test/prism/version_test.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# 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/psych/test_encoding.rb b/test/psych/test_encoding.rb
index 1867d59ea6..7d33814805 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 <<~RUBY, __FILE__, __LINE__ + 1
+ class_eval %{
def #{m} *args
@strings += args.flatten.find_all { |a|
String === a
}
end
- RUBY
+ }
end
end
diff --git a/test/psych/test_numeric.rb b/test/psych/test_numeric.rb
index 4c012e4562..9c75c016cd 100644
--- a/test/psych/test_numeric.rb
+++ b/test/psych/test_numeric.rb
@@ -1,9 +1,6 @@
# frozen_string_literal: true
require_relative 'helper'
-begin
- require 'bigdecimal'
-rescue LoadError
-end
+require 'bigdecimal'
module Psych
###
@@ -32,13 +29,13 @@ module Psych
def test_big_decimal_tag
decimal = BigDecimal("12.34")
assert_match "!ruby/object:BigDecimal", Psych.dump(decimal)
- end if defined?(BigDecimal)
+ end
def test_big_decimal_round_trip
decimal = BigDecimal("12.34")
$DEBUG = false
assert_cycle decimal
- end if defined?(BigDecimal)
+ end
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 86bb9034b9..269d72242e 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_same data.first, data.last
+ assert_equal data.first.object_id, data.last.object_id
end
def test_float_references
@@ -49,7 +49,7 @@ module Psych
- *name
eoyml
assert_equal data.first, data.last
- assert_same data.first, data.last
+ assert_equal data.first.object_id, data.last.object_id
end
def test_binary_references
@@ -60,7 +60,7 @@ module Psych
- *name
eoyml
assert_equal data.first, data.last
- assert_same data.first, data.last
+ assert_equal data.first.object_id, data.last.object_id
end
def test_regexp_references
@@ -70,7 +70,7 @@ module Psych
- *name
eoyml
assert_equal data.first, data.last
- assert_same data.first, data.last
+ assert_equal data.first.object_id, data.last.object_id
end
end
end
diff --git a/test/psych/test_parser.rb b/test/psych/test_parser.rb
index c1e0abb89d..e087e319a5 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 <<~RUBY, __FILE__, __LINE__ + 1
+ class_eval %{
def #{m} *args
super
@marks << @parser.mark if @parser
@calls << [:#{m}, args]
end
- RUBY
+ }
end
end
@@ -384,25 +384,6 @@ 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 c977e799e3..1abd69ceca 100644
--- a/test/psych/test_psych.rb
+++ b/test/psych/test_psych.rb
@@ -419,15 +419,12 @@ 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)
+ Psych.safe_dump(:foo, permitted_classes: [Symbol])
end
assert_equal "Tried to dump unspecified class: Symbol(:foo)", error.message
- assert_match(/\A--- :foo\n(?:\.\.\.\n)?\z/, Psych.safe_dump(:foo, permitted_symbols: [:foo]))
+ assert_match(/\A--- :foo\n(?:\.\.\.\n)?\z/, Psych.safe_dump(:foo, permitted_classes: [Symbol], permitted_symbols: [:foo]))
end
def test_safe_dump_aliases
diff --git a/test/psych/test_yaml.rb b/test/psych/test_yaml.rb
index cedec46cc7..32dd43b98e 100644
--- a/test/psych/test_yaml.rb
+++ b/test/psych/test_yaml.rb
@@ -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 8bcf5491ca..70adbb9ca0 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_include(@io.string, "key: value")
+ assert_match(/key: value/, @io.string)
assert_equal @io.string, s.yaml
- assert_not_include(s.yaml, "...")
+ assert(/\.\.\./ !~ s.yaml)
end
def test_scalar
@@ -76,7 +76,7 @@ module Psych
@visitor.accept s
- assert_include(@io.string, "hello")
+ assert_match(/hello/, @io.string)
assert_equal @io.string, s.yaml
end
@@ -90,8 +90,8 @@ module Psych
@visitor.accept s
- assert_include(@io.string, "str")
- assert_include(@io.string, "hello")
+ assert_match(/str/, @io.string)
+ assert_match(/hello/, @io.string)
assert_equal @io.string, s.yaml
end
@@ -107,7 +107,7 @@ module Psych
@visitor.accept s
- assert_include(@io.string, "- hello")
+ assert_match(/- hello/, @io.string)
assert_equal @io.string, s.yaml
end
@@ -122,7 +122,7 @@ module Psych
@visitor.accept s
- assert_include(@io.string, "key: value")
+ assert_match(/key: value/, @io.string)
assert_equal @io.string, s.yaml
end
@@ -137,7 +137,7 @@ module Psych
@visitor.accept s
- assert_include(@io.string, "&A key: \*A")
+ assert_match(/&A key: \*A/, @io.string)
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 89c3676651..3d4608b903 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_same list[0], list[1]
+ assert_equal list[0].object_id, list[1].object_id
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 01e685134a..4c48670f2f 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_include io.string, "hello world"
+ assert_match "hello world", io.string
end
def test_binary_formatting
@@ -167,9 +167,9 @@ module Psych
end
def test_string
- assert_include(Psych.dump({'a' => '017'}), "'017'")
- assert_include(Psych.dump({'a' => '019'}), "'019'")
- assert_include(Psych.dump({'a' => '01818'}), "'01818'")
+ assert_match(/'017'/, Psych.dump({'a' => '017'}))
+ assert_match(/'019'/, Psych.dump({'a' => '019'}))
+ assert_match(/'01818'/, Psych.dump({'a' => '01818'}))
end
# http://yaml.org/type/null.html
diff --git a/test/racc/assets/cadenza.y b/test/racc/assets/cadenza.y
new file mode 100644
index 0000000000..1940ead225
--- /dev/null
+++ b/test/racc/assets/cadenza.y
@@ -0,0 +1,170 @@
+# 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
new file mode 100644
index 0000000000..d180c09e14
--- /dev/null
+++ b/test/racc/assets/cast.y
@@ -0,0 +1,926 @@
+# 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
new file mode 100644
index 0000000000..7e0ee20f1e
--- /dev/null
+++ b/test/racc/assets/chk.y
@@ -0,0 +1,126 @@
+#
+# 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
new file mode 100644
index 0000000000..de9de71d28
--- /dev/null
+++ b/test/racc/assets/conf.y
@@ -0,0 +1,16 @@
+
+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
new file mode 100644
index 0000000000..3d6af25d85
--- /dev/null
+++ b/test/racc/assets/csspool.y
@@ -0,0 +1,729 @@
+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
new file mode 100644
index 0000000000..17a034ee54
--- /dev/null
+++ b/test/racc/assets/digraph.y
@@ -0,0 +1,29 @@
+# ? 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
new file mode 100644
index 0000000000..0fda2685aa
--- /dev/null
+++ b/test/racc/assets/echk.y
@@ -0,0 +1,118 @@
+#
+# 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
new file mode 100644
index 0000000000..4f5f6bb4fd
--- /dev/null
+++ b/test/racc/assets/edtf.y
@@ -0,0 +1,583 @@
+# -*- 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
new file mode 100644
index 0000000000..ae280957cc
--- /dev/null
+++ b/test/racc/assets/err.y
@@ -0,0 +1,60 @@
+
+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
new file mode 100644
index 0000000000..1fd21ac7d0
--- /dev/null
+++ b/test/racc/assets/error_recovery.y
@@ -0,0 +1,35 @@
+# 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
new file mode 100644
index 0000000000..24c27443e2
--- /dev/null
+++ b/test/racc/assets/expect.y
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..ab0692e543
--- /dev/null
+++ b/test/racc/assets/firstline.y
@@ -0,0 +1,4 @@
+class T
+rule
+ a: A B C
+end
diff --git a/test/racc/assets/huia.y b/test/racc/assets/huia.y
new file mode 100644
index 0000000000..de9d45150c
--- /dev/null
+++ b/test/racc/assets/huia.y
@@ -0,0 +1,318 @@
+# 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
new file mode 100644
index 0000000000..1d359df83e
--- /dev/null
+++ b/test/racc/assets/ichk.y
@@ -0,0 +1,102 @@
+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
new file mode 100644
index 0000000000..18dbe4b1a7
--- /dev/null
+++ b/test/racc/assets/ifelse.y
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..39e42afd74
--- /dev/null
+++ b/test/racc/assets/intp.y
@@ -0,0 +1,546 @@
+#
+# 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
new file mode 100644
index 0000000000..c2640f3339
--- /dev/null
+++ b/test/racc/assets/journey.y
@@ -0,0 +1,47 @@
+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
new file mode 100644
index 0000000000..8045a072a4
--- /dev/null
+++ b/test/racc/assets/liquor.y
@@ -0,0 +1,313 @@
+# 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
new file mode 100644
index 0000000000..ea92d47a69
--- /dev/null
+++ b/test/racc/assets/machete.y
@@ -0,0 +1,423 @@
+# 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
new file mode 100644
index 0000000000..5ede008308
--- /dev/null
+++ b/test/racc/assets/macruby.y
@@ -0,0 +1,2197 @@
+# 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
new file mode 100644
index 0000000000..eb7d4d529d
--- /dev/null
+++ b/test/racc/assets/mailp.y
@@ -0,0 +1,437 @@
+#
+# 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
new file mode 100644
index 0000000000..94cc411ea7
--- /dev/null
+++ b/test/racc/assets/mediacloth.y
@@ -0,0 +1,599 @@
+# 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
new file mode 100644
index 0000000000..2e83c79b6f
--- /dev/null
+++ b/test/racc/assets/mof.y
@@ -0,0 +1,649 @@
+# 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
new file mode 100644
index 0000000000..0378345fef
--- /dev/null
+++ b/test/racc/assets/namae.y
@@ -0,0 +1,302 @@
+# -*- 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
new file mode 100644
index 0000000000..c7b8e46551
--- /dev/null
+++ b/test/racc/assets/nasl.y
@@ -0,0 +1,626 @@
+################################################################################
+# 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
new file mode 100644
index 0000000000..5b670c966a
--- /dev/null
+++ b/test/racc/assets/newsyn.y
@@ -0,0 +1,25 @@
+
+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
new file mode 100644
index 0000000000..5aa0670be0
--- /dev/null
+++ b/test/racc/assets/noend.y
@@ -0,0 +1,4 @@
+class MyParser
+rule
+input: A B C
+end
diff --git a/test/racc/assets/nokogiri-css.y b/test/racc/assets/nokogiri-css.y
new file mode 100644
index 0000000000..24dfbf3b1b
--- /dev/null
+++ b/test/racc/assets/nokogiri-css.y
@@ -0,0 +1,255 @@
+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
new file mode 100644
index 0000000000..b9a35a2626
--- /dev/null
+++ b/test/racc/assets/nonass.y
@@ -0,0 +1,41 @@
+#
+# 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
new file mode 100644
index 0000000000..96ae352c82
--- /dev/null
+++ b/test/racc/assets/normal.y
@@ -0,0 +1,27 @@
+
+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
new file mode 100644
index 0000000000..e50a4b3472
--- /dev/null
+++ b/test/racc/assets/norule.y
@@ -0,0 +1,4 @@
+
+class A
+rule
+end
diff --git a/test/racc/assets/nullbug1.y b/test/racc/assets/nullbug1.y
new file mode 100644
index 0000000000..4b267ba0ea
--- /dev/null
+++ b/test/racc/assets/nullbug1.y
@@ -0,0 +1,25 @@
+#
+# 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
new file mode 100644
index 0000000000..0c1d43bf3e
--- /dev/null
+++ b/test/racc/assets/nullbug2.y
@@ -0,0 +1,15 @@
+#
+# 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
new file mode 100644
index 0000000000..ae6a5a6bdd
--- /dev/null
+++ b/test/racc/assets/opal.y
@@ -0,0 +1,1807 @@
+# 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
new file mode 100644
index 0000000000..a011953a51
--- /dev/null
+++ b/test/racc/assets/opt.y
@@ -0,0 +1,123 @@
+#
+# 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
new file mode 100644
index 0000000000..68d63583ca
--- /dev/null
+++ b/test/racc/assets/percent.y
@@ -0,0 +1,35 @@
+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
new file mode 100644
index 0000000000..99f78f2081
--- /dev/null
+++ b/test/racc/assets/php_serialization.y
@@ -0,0 +1,98 @@
+# 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
new file mode 100644
index 0000000000..b6e849dda9
--- /dev/null
+++ b/test/racc/assets/recv.y
@@ -0,0 +1,97 @@
+# 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
new file mode 100644
index 0000000000..1d99b0fdb8
--- /dev/null
+++ b/test/racc/assets/riml.y
@@ -0,0 +1,665 @@
+# 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
new file mode 100644
index 0000000000..baf9249a77
--- /dev/null
+++ b/test/racc/assets/rrconf.y
@@ -0,0 +1,14 @@
+# 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
new file mode 100644
index 0000000000..eceb253298
--- /dev/null
+++ b/test/racc/assets/ruby18.y
@@ -0,0 +1,1943 @@
+# 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
new file mode 100644
index 0000000000..b405c952e7
--- /dev/null
+++ b/test/racc/assets/ruby19.y
@@ -0,0 +1,2174 @@
+# 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
new file mode 100644
index 0000000000..6e07734778
--- /dev/null
+++ b/test/racc/assets/ruby20.y
@@ -0,0 +1,2350 @@
+# 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
new file mode 100644
index 0000000000..2ac94afb0c
--- /dev/null
+++ b/test/racc/assets/ruby21.y
@@ -0,0 +1,2359 @@
+# 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
new file mode 100644
index 0000000000..751c0e866b
--- /dev/null
+++ b/test/racc/assets/ruby22.y
@@ -0,0 +1,2381 @@
+# 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
new file mode 100644
index 0000000000..709254ed66
--- /dev/null
+++ b/test/racc/assets/scan.y
@@ -0,0 +1,72 @@
+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
new file mode 100644
index 0000000000..727f74a29d
--- /dev/null
+++ b/test/racc/assets/syntax.y
@@ -0,0 +1,50 @@
+#
+# 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
new file mode 100644
index 0000000000..388ed1302d
--- /dev/null
+++ b/test/racc/assets/tp_plus.y
@@ -0,0 +1,622 @@
+# 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
new file mode 100644
index 0000000000..d3bc748d3a
--- /dev/null
+++ b/test/racc/assets/twowaysql.y
@@ -0,0 +1,278 @@
+# 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
new file mode 100644
index 0000000000..518acc7f31
--- /dev/null
+++ b/test/racc/assets/unterm.y
@@ -0,0 +1,5 @@
+# unterminated action
+
+class A
+rule
+ a: A {
diff --git a/test/racc/assets/useless.y b/test/racc/assets/useless.y
new file mode 100644
index 0000000000..3f172e341c
--- /dev/null
+++ b/test/racc/assets/useless.y
@@ -0,0 +1,12 @@
+
+
+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
new file mode 100644
index 0000000000..9faae89a79
--- /dev/null
+++ b/test/racc/assets/yyerr.y
@@ -0,0 +1,46 @@
+#
+# 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
new file mode 100644
index 0000000000..c6ba136201
--- /dev/null
+++ b/test/racc/bench.y
@@ -0,0 +1,36 @@
+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
new file mode 100644
index 0000000000..ebc30b8288
--- /dev/null
+++ b/test/racc/case.rb
@@ -0,0 +1,111 @@
+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' 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
new file mode 100644
index 0000000000..88b1e1e93b
--- /dev/null
+++ b/test/racc/infini.y
@@ -0,0 +1,8 @@
+
+class I
+
+rule
+
+list: list X
+
+end
diff --git a/test/racc/regress/README.txt b/test/racc/regress/README.txt
new file mode 100644
index 0000000000..dcab73260d
--- /dev/null
+++ b/test/racc/regress/README.txt
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..dafce3c9f3
--- /dev/null
+++ b/test/racc/regress/cadenza
@@ -0,0 +1,796 @@
+#
+# 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
new file mode 100644
index 0000000000..60e92a0abd
--- /dev/null
+++ b/test/racc/regress/cast
@@ -0,0 +1,3945 @@
+#
+# 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
new file mode 100644
index 0000000000..a3d14a9b34
--- /dev/null
+++ b/test/racc/regress/csspool
@@ -0,0 +1,2314 @@
+#
+# 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
new file mode 100644
index 0000000000..5947931260
--- /dev/null
+++ b/test/racc/regress/edtf
@@ -0,0 +1,1794 @@
+#
+# 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
new file mode 100644
index 0000000000..cac22873df
--- /dev/null
+++ b/test/racc/regress/huia
@@ -0,0 +1,1681 @@
+#
+# 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
new file mode 100644
index 0000000000..3daf81dac0
--- /dev/null
+++ b/test/racc/regress/journey
@@ -0,0 +1,222 @@
+#
+# 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
new file mode 100644
index 0000000000..9fa2ca4da0
--- /dev/null
+++ b/test/racc/regress/liquor
@@ -0,0 +1,885 @@
+#
+# 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
new file mode 100644
index 0000000000..6297fe2ac9
--- /dev/null
+++ b/test/racc/regress/machete
@@ -0,0 +1,833 @@
+#
+# 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
new file mode 100644
index 0000000000..cca7d3c7e4
--- /dev/null
+++ b/test/racc/regress/mediacloth
@@ -0,0 +1,1463 @@
+#
+# 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
new file mode 100644
index 0000000000..d702292e51
--- /dev/null
+++ b/test/racc/regress/mof
@@ -0,0 +1,1368 @@
+#
+# 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
new file mode 100644
index 0000000000..5a795e4579
--- /dev/null
+++ b/test/racc/regress/namae
@@ -0,0 +1,634 @@
+#
+# 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
new file mode 100644
index 0000000000..52a329d20a
--- /dev/null
+++ b/test/racc/regress/nasl
@@ -0,0 +1,2548 @@
+#
+# 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
new file mode 100644
index 0000000000..bc2faf8702
--- /dev/null
+++ b/test/racc/regress/nokogiri-css
@@ -0,0 +1,836 @@
+#
+# 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
new file mode 100644
index 0000000000..53420a8f0e
--- /dev/null
+++ b/test/racc/regress/opal
@@ -0,0 +1,10107 @@
+#
+# 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
new file mode 100644
index 0000000000..e412db1cc8
--- /dev/null
+++ b/test/racc/regress/php_serialization
@@ -0,0 +1,336 @@
+#
+# 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
new file mode 100644
index 0000000000..5882a431cf
--- /dev/null
+++ b/test/racc/regress/riml
@@ -0,0 +1,4037 @@
+#
+# 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
new file mode 100644
index 0000000000..9e9c55d564
--- /dev/null
+++ b/test/racc/regress/ruby18
@@ -0,0 +1,9945 @@
+#
+# 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
new file mode 100644
index 0000000000..4731071275
--- /dev/null
+++ b/test/racc/regress/ruby22
@@ -0,0 +1,11180 @@
+#
+# 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
new file mode 100644
index 0000000000..34b6284db7
--- /dev/null
+++ b/test/racc/regress/tp_plus
@@ -0,0 +1,1933 @@
+#
+# 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
new file mode 100644
index 0000000000..219f1a8b04
--- /dev/null
+++ b/test/racc/regress/twowaysql
@@ -0,0 +1,556 @@
+#
+# 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
new file mode 100644
index 0000000000..f6c843853e
--- /dev/null
+++ b/test/racc/scandata/brace
@@ -0,0 +1,7 @@
+{ {
+ } { } {
+ { { { } } }
+ { { { {} } } }
+ {} {} {}
+ }
+}
diff --git a/test/racc/scandata/gvar b/test/racc/scandata/gvar
new file mode 100644
index 0000000000..50528ce97b
--- /dev/null
+++ b/test/racc/scandata/gvar
@@ -0,0 +1 @@
+{ $' $" $& $-a $/ $\ $( $1 $2 $3 $? $-i }
diff --git a/test/racc/scandata/normal b/test/racc/scandata/normal
new file mode 100644
index 0000000000..e705131536
--- /dev/null
+++ b/test/racc/scandata/normal
@@ -0,0 +1,4 @@
+{
+ # comment
+ result = "string".match(/regexp/)[0]
+}
diff --git a/test/racc/scandata/percent b/test/racc/scandata/percent
new file mode 100644
index 0000000000..fded9a385c
--- /dev/null
+++ b/test/racc/scandata/percent
@@ -0,0 +1,18 @@
+{
+ 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
new file mode 100644
index 0000000000..190135b3bd
--- /dev/null
+++ b/test/racc/scandata/slash
@@ -0,0 +1,10 @@
+{
+ # 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
new file mode 100644
index 0000000000..4d2460e8ed
--- /dev/null
+++ b/test/racc/src.intp
@@ -0,0 +1,34 @@
+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
new file mode 100644
index 0000000000..86296899b8
--- /dev/null
+++ b/test/racc/start.y
@@ -0,0 +1,20 @@
+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
new file mode 100644
index 0000000000..883737c45f
--- /dev/null
+++ b/test/racc/test_chk_y.rb
@@ -0,0 +1,52 @@
+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
new file mode 100644
index 0000000000..8f6e090cb2
--- /dev/null
+++ b/test/racc/test_grammar_file_parser.rb
@@ -0,0 +1,15 @@
+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
new file mode 100644
index 0000000000..5bfebf150b
--- /dev/null
+++ b/test/racc/test_racc_command.rb
@@ -0,0 +1,339 @@
+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
new file mode 100644
index 0000000000..fcd7e53c99
--- /dev/null
+++ b/test/racc/test_scan_y.rb
@@ -0,0 +1,52 @@
+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
new file mode 100644
index 0000000000..d7877511ec
--- /dev/null
+++ b/test/racc/testscanner.rb
@@ -0,0 +1,51 @@
+#
+# 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/text_formatter_test_case.rb b/test/rdoc/support/text_formatter_test_case.rb
index e359028a29..22a762b5f0 100644
--- a/test/rdoc/support/text_formatter_test_case.rb
+++ b/test/rdoc/support/text_formatter_test_case.rb
@@ -112,3 +112,4 @@ 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 b11c15420c..6915b466f0 100644
--- a/test/rdoc/test_rdoc_any_method.rb
+++ b/test/rdoc/test_rdoc_any_method.rb
@@ -69,20 +69,6 @@ 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
@@ -529,30 +515,6 @@ 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 28e8cf76b4..d3c16bceca 100644
--- a/test/rdoc/test_rdoc_comment.rb
+++ b/test/rdoc/test_rdoc_comment.rb
@@ -206,15 +206,6 @@ 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_section.rb b/test/rdoc/test_rdoc_context_section.rb
index 6834cccafb..24c68c49dd 100644
--- a/test/rdoc/test_rdoc_context_section.rb
+++ b/test/rdoc/test_rdoc_context_section.rb
@@ -144,3 +144,4 @@ 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 96319bb4f7..7e9edae469 100644
--- a/test/rdoc/test_rdoc_generator_darkfish.rb
+++ b/test/rdoc/test_rdoc_generator_darkfish.rb
@@ -107,15 +107,14 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
encoding = Regexp.escape Encoding::UTF_8.name
- assert_match %r%<meta charset="#{encoding}">%, File.binread('index.html')
- assert_match %r%<meta charset="#{encoding}">%, File.binread('Object.html')
+ assert_match %r%<meta charset="#{encoding}">%, File.read('index.html')
+ assert_match %r%<meta charset="#{encoding}">%, File.read('Object.html')
- refute_match(/Ignored/, File.binread('index.html'))
- summary = File.binread('index.html')[%r[<summary.*Klass\.html.*</summary>.*</details>]m]
+ refute_match(/Ignored/, File.read('index.html'))
+ summary = File.read('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]
+ omit 'The following line crashes with "invalid byte sequence in US-ASCII" on ci.rvm.jp and some RubyCIs'
+ klassnav = File.read('Klass.html')[%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
@@ -124,14 +123,6 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
%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
@@ -140,15 +131,15 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@g.generate
assert_file 'outer_rdoc.html'
assert_file 'outer/inner_rdoc.html'
- index = File.binread('index.html')
+ index = File.read('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.binread('outer_rdoc.html'))
+ assert_match(re, File.read('outer_rdoc.html'))
re = %r[<details open><summary><a href="\.\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
- assert_match(re, File.binread('outer/inner_rdoc.html'))
+ assert_match(re, File.read('outer/inner_rdoc.html'))
end
def test_generate_dry_run
@@ -285,7 +276,7 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@g.generate
Dir.glob("*.html", base: @tmpdir) do |html|
- File.binread(File.join(@tmpdir, html)).scan(/.*should be escaped.*/) do |line|
+ File.read(File.join(@tmpdir, html)).scan(/.*should be escaped.*/) do |line|
assert_not_include line, "<em>", html
end
end
@@ -303,7 +294,7 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@g.generate
assert_file base
- assert_include File.binread('index.html'), %Q[href="./#{base}"]
+ assert_include File.read('index.html'), %Q[href="./#{base}"]
end
def test_title
@@ -311,7 +302,7 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@options.title = title
@g.generate
- assert_main_title(File.binread('index.html'), title)
+ assert_main_title(File.read('index.html'), title)
end
def test_title_escape
@@ -319,7 +310,7 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@options.title = title
@g.generate
- assert_main_title(File.binread('index.html'), title)
+ assert_main_title(File.read('index.html'), title)
end
##
diff --git a/test/rdoc/test_rdoc_generator_markup.rb b/test/rdoc/test_rdoc_generator_markup.rb
index 7c021e432e..5491b7c61e 100644
--- a/test/rdoc/test_rdoc_generator_markup.rb
+++ b/test/rdoc/test_rdoc_generator_markup.rb
@@ -57,3 +57,4 @@ class TestRDocGeneratorMarkup < RDoc::TestCase
end
end
+
diff --git a/test/rdoc/test_rdoc_markup.rb b/test/rdoc/test_rdoc_markup.rb
index 4d79f8bc3f..b9bdafab2a 100644
--- a/test/rdoc/test_rdoc_markup.rb
+++ b/test/rdoc/test_rdoc_markup.rb
@@ -93,3 +93,4 @@ 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 dcae48525d..e8ff602f96 100644
--- a/test/rdoc/test_rdoc_markup_attribute_manager.rb
+++ b/test/rdoc/test_rdoc_markup_attribute_manager.rb
@@ -393,3 +393,4 @@ 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 1ab408d801..0dfd72bdb6 100644
--- a/test/rdoc/test_rdoc_markup_attributes.rb
+++ b/test/rdoc/test_rdoc_markup_attributes.rb
@@ -37,3 +37,4 @@ 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 e4f3b9daf1..3db834b85d 100644
--- a/test/rdoc/test_rdoc_markup_document.rb
+++ b/test/rdoc/test_rdoc_markup_document.rb
@@ -205,3 +205,4 @@ 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 af19d832ca..8702db379d 100644
--- a/test/rdoc/test_rdoc_markup_formatter.rb
+++ b/test/rdoc/test_rdoc_markup_formatter.rb
@@ -104,12 +104,6 @@ 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 ac67c68d10..adebfdc311 100644
--- a/test/rdoc/test_rdoc_markup_hard_break.rb
+++ b/test/rdoc/test_rdoc_markup_hard_break.rb
@@ -29,3 +29,4 @@ 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 de92af91a0..05a8e005ba 100644
--- a/test/rdoc/test_rdoc_markup_heading.rb
+++ b/test/rdoc/test_rdoc_markup_heading.rb
@@ -27,3 +27,4 @@ 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 b3e9b845c3..9126526b73 100644
--- a/test/rdoc/test_rdoc_markup_include.rb
+++ b/test/rdoc/test_rdoc_markup_include.rb
@@ -17,3 +17,4 @@ 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 d2a9cbe5ca..7b5758998f 100644
--- a/test/rdoc/test_rdoc_markup_indented_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_indented_paragraph.rb
@@ -51,3 +51,4 @@ 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 1b26846eb3..ca89a74fc3 100644
--- a/test/rdoc/test_rdoc_markup_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_paragraph.rb
@@ -30,3 +30,4 @@ 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 52887e6f6c..c7795b24e1 100644
--- a/test/rdoc/test_rdoc_markup_raw.rb
+++ b/test/rdoc/test_rdoc_markup_raw.rb
@@ -20,3 +20,4 @@ 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 81372c64d2..1d1fc7db46 100644
--- a/test/rdoc/test_rdoc_markup_to_ansi.rb
+++ b/test/rdoc/test_rdoc_markup_to_ansi.rb
@@ -367,3 +367,4 @@ bar:
end
end
+
diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb
index e3affa533c..d11c2a4ed7 100644
--- a/test/rdoc/test_rdoc_markup_to_html.rb
+++ b/test/rdoc/test_rdoc_markup_to_html.rb
@@ -391,43 +391,11 @@ 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.start_accepting
- @to.accept_paragraph para("+hello+\n", "world\n")
- assert_equal "\n<p><code>hello</code> 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.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> <code>world</code></p>\n", @to.res.join
+ assert_equal "\n<p>hello world </p>\n", @to.res.join
end
def test_accept_heading_output_decoration
@@ -634,9 +602,9 @@ end
end
def test_accept_verbatim_redefinable_operators
- functions = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~].flat_map { |redefinable_op|
+ functions = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~].map { |redefinable_op|
["def #{redefinable_op}\n", "end\n"]
- }
+ }.flatten
verb = @RM::Verbatim.new(*functions)
@@ -989,3 +957,4 @@ EXPECTED
assert_include result, CGI.escapeHTML(unexpected)
end
end
+
diff --git a/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb b/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
index 8bd2d67247..cbaf75a04e 100644
--- a/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
@@ -30,3 +30,4 @@ 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 2bf2e0ecdf..70ea7f0f1b 100644
--- a/test/rdoc/test_rdoc_markup_to_label.rb
+++ b/test/rdoc/test_rdoc_markup_to_label.rb
@@ -110,3 +110,4 @@ 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 ff47364faa..c8c5fd4d52 100644
--- a/test/rdoc/test_rdoc_markup_to_markdown.rb
+++ b/test/rdoc/test_rdoc_markup_to_markdown.rb
@@ -387,3 +387,4 @@ 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 bb30ee5226..1d833b156a 100644
--- a/test/rdoc/test_rdoc_markup_to_rdoc.rb
+++ b/test/rdoc/test_rdoc_markup_to_rdoc.rb
@@ -375,3 +375,4 @@ 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 7512495aec..11ab6f197b 100644
--- a/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
+++ b/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
@@ -124,3 +124,4 @@ 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 c709d7a4d5..8508f823df 100644
--- a/test/rdoc/test_rdoc_markup_to_tt_only.rb
+++ b/test/rdoc/test_rdoc_markup_to_tt_only.rb
@@ -244,3 +244,4 @@ 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 2f8a57266a..1a650c44ef 100644
--- a/test/rdoc/test_rdoc_markup_verbatim.rb
+++ b/test/rdoc/test_rdoc_markup_verbatim.rb
@@ -27,3 +27,4 @@ class TestRDocMarkupVerbatim < RDoc::TestCase
end
end
+
diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
index 443d595ca6..c71ee25cef 100644
--- a/test/rdoc/test_rdoc_options.rb
+++ b/test/rdoc/test_rdoc_options.rb
@@ -209,13 +209,6 @@ 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]
@@ -228,19 +221,6 @@ 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]
diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb
index 10bd7f5524..b65561b2bb 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,9 +475,6 @@ 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("\\"));
@@ -541,9 +538,6 @@ 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
@@ -1379,36 +1373,6 @@ 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:
@@ -2104,3 +2068,4 @@ 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 587a156d3a..6584840572 100644
--- a/test/rdoc/test_rdoc_parser_changelog.rb
+++ b/test/rdoc/test_rdoc_parser_changelog.rb
@@ -482,3 +482,4 @@ 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 cca9c1ddfd..06c6700d96 100644
--- a/test/rdoc/test_rdoc_parser_markdown.rb
+++ b/test/rdoc/test_rdoc_parser_markdown.rb
@@ -59,3 +59,4 @@ 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 48663e6d7d..bac9c65592 100644
--- a/test/rdoc/test_rdoc_parser_rd.rb
+++ b/test/rdoc/test_rdoc_parser_rd.rb
@@ -53,3 +53,4 @@ 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 1f75ba7c6e..76fb28808c 100644
--- a/test/rdoc/test_rdoc_parser_ruby.rb
+++ b/test/rdoc/test_rdoc_parser_ruby.rb
@@ -3205,14 +3205,6 @@ 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
@@ -3358,13 +3350,6 @@ 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 4255cb97d8..2f1ad00de4 100644
--- a/test/rdoc/test_rdoc_parser_simple.rb
+++ b/test/rdoc/test_rdoc_parser_simple.rb
@@ -113,3 +113,4 @@ contents of a string.
end
end
+
diff --git a/test/rdoc/test_rdoc_rd.rb b/test/rdoc/test_rdoc_rd.rb
index 38de575bb0..83ee423455 100644
--- a/test/rdoc/test_rdoc_rd.rb
+++ b/test/rdoc/test_rdoc_rd.rb
@@ -28,3 +28,4 @@ class TestRDocRd < RDoc::TestCase
end
end
+
diff --git a/test/rdoc/test_rdoc_rd_inline.rb b/test/rdoc/test_rdoc_rd_inline.rb
index 6bfb229933..13ab86d3d9 100644
--- a/test/rdoc/test_rdoc_rd_inline.rb
+++ b/test/rdoc/test_rdoc_rd_inline.rb
@@ -61,3 +61,4 @@ class TestRDocRdInline < RDoc::TestCase
end
end
+
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
index 5168932430..853d7dad22 100644
--- a/test/rdoc/test_rdoc_rdoc.rb
+++ b/test/rdoc/test_rdoc_rdoc.rb
@@ -165,7 +165,12 @@ class TestRDocRDoc < RDoc::TestCase
b = Dir.glob(b).first
c = Dir.glob(c).first
- File.write('.document', "a.rb\n""b.rb\n")
+ 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
expected_files << a
expected_files << b
@@ -191,7 +196,12 @@ class TestRDocRDoc < RDoc::TestCase
b = Dir.glob(b).first
c = Dir.glob(c).first
- File.write('.document', "a.rb\n""b.rb\n")
+ 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
expected_files << a
@rdoc.options.exclude = Regexp.new(['b.rb'].join('|'))
diff --git a/test/rdoc/test_rdoc_ri_paths.rb b/test/rdoc/test_rdoc_ri_paths.rb
index 6dccd6dbdd..c01a4711ee 100644
--- a/test/rdoc/test_rdoc_ri_paths.rb
+++ b/test/rdoc/test_rdoc_ri_paths.rb
@@ -155,3 +155,4 @@ 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 e81a1498ba..ee242d7bc9 100644
--- a/test/rdoc/test_rdoc_single_class.rb
+++ b/test/rdoc/test_rdoc_single_class.rb
@@ -18,3 +18,4 @@ class TestRDocSingleClass < RDoc::TestCase
end
end
+
diff --git a/test/rdoc/test_rdoc_stats.rb b/test/rdoc/test_rdoc_stats.rb
index ce272d36cf..b9918e4fd3 100644
--- a/test/rdoc/test_rdoc_stats.rb
+++ b/test/rdoc/test_rdoc_stats.rb
@@ -720,3 +720,4 @@ m(a, b) { |c, d| ... }
end
end
+
diff --git a/test/rdoc/test_rdoc_store.rb b/test/rdoc/test_rdoc_store.rb
index 50e8667d81..8350d257b3 100644
--- a/test/rdoc/test_rdoc_store.rb
+++ b/test/rdoc/test_rdoc_store.rb
@@ -373,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.flat_map do |mod|
+ methods = s.all_classes_and_modules.map do |mod|
mod.method_list
- end.sort
+ end.flatten.sort
_meth_bang_alias = RDoc::AnyMethod.new nil, 'method_bang'
_meth_bang_alias.parent = @klass
@@ -388,9 +388,9 @@ class TestRDocStore < XrefTestCase
assert_equal @klass, methods.last.parent
- attributes = s.all_classes_and_modules.flat_map do |mod|
+ attributes = s.all_classes_and_modules.map do |mod|
mod.attributes
- end.sort
+ end.flatten.sort
assert_equal [@attr], attributes
diff --git a/test/rdoc/test_rdoc_task.rb b/test/rdoc/test_rdoc_task.rb
index 67d223087b..23add7d5fe 100644
--- a/test/rdoc/test_rdoc_task.rb
+++ b/test/rdoc/test_rdoc_task.rb
@@ -50,7 +50,6 @@ 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
@@ -59,7 +58,6 @@ 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
@@ -112,16 +110,11 @@ 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
@@ -138,7 +131,6 @@ 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
@@ -148,7 +140,6 @@ 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 4a0ddb9fec..cdfa615dae 100644
--- a/test/rdoc/test_rdoc_token_stream.rb
+++ b/test/rdoc/test_rdoc_token_stream.rb
@@ -39,13 +39,6 @@ class TestRDocTokenStream < RDoc::TestCase
assert_equal '', RDoc::TokenStream.to_html([])
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
@@ -60,14 +53,6 @@ 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 c9315b7806..de76a90602 100644
--- a/test/rdoc/xref_data.rb
+++ b/test/rdoc/xref_data.rb
@@ -149,3 +149,4 @@ class Child < Parent
end
XREF_DATA
+
diff --git a/test/rdoc/xref_test_case.rb b/test/rdoc/xref_test_case.rb
index 0f7395e516..22b00d04bc 100644
--- a/test/rdoc/xref_test_case.rb
+++ b/test/rdoc/xref_test_case.rb
@@ -91,3 +91,4 @@ class XrefTestCase < RDoc::TestCase
end
end
+
diff --git a/test/readline/helper.rb b/test/readline/helper.rb
new file mode 100644
index 0000000000..2d28d18a7e
--- /dev/null
+++ b/test/readline/helper.rb
@@ -0,0 +1,29 @@
+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
new file mode 100644
index 0000000000..ab70e43711
--- /dev/null
+++ b/test/readline/test_readline.rb
@@ -0,0 +1,955 @@
+# frozen_string_literal: false
+require_relative "helper"
+require "test/unit"
+require "tempfile"
+require "timeout"
+require "open3"
+
+module BasetestReadline
+ RUBY = EnvUtil.rubybin
+
+ 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
+
+ # Skip arm32-linux (Travis CI). See aefc988 in main ruby repo.
+ omit "Skip arm32-linux" if /armv[0-9+][a-z]-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
new file mode 100644
index 0000000000..39ad4fe85a
--- /dev/null
+++ b/test/readline/test_readline_history.rb
@@ -0,0 +1,292 @@
+# 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 26fe834482..e8b8e3a6e1 100644
--- a/test/reline/helper.rb
+++ b/test/reline/helper.rb
@@ -5,77 +5,33 @@ 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(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
+ 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
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
- # 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 start_pasting
+ Reline::GeneralIO.start_pasting
+end
- # 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
+def finish_pasting
+ Reline::GeneralIO.finish_pasting
end
class Reline::TestCase < Test::Unit::TestCase
@@ -128,14 +84,9 @@ class Reline::TestCase < Test::Unit::TestCase
end
end
- def assert_line_around_cursor(before, after)
- before = convert_str(before)
- after = convert_str(after)
- line = @line_editor.current_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])
+ def assert_line(expected)
+ expected = convert_str(expected)
+ assert_equal(expected, @line_editor.line)
end
def assert_byte_pointer_size(expected)
@@ -150,18 +101,25 @@ 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)
- 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])
+ 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
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
deleted file mode 100644
index e1c56b9ee1..0000000000
--- a/test/reline/test_ansi_with_terminfo.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-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
deleted file mode 100644
index 3d153514f3..0000000000
--- a/test/reline/test_ansi_without_terminfo.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-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 6068292847..c08d7ba498 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.core.io_gate.reset(encoding: Encoding::US_ASCII)
+ Reline::IOGate.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.core.io_gate.reset(encoding: Encoding::UTF_8)
+ Reline::IOGate.reset(encoding: Encoding::UTF_8)
@config = Reline::Config.new
assert_equal nil, @config.convert_meta
@@ -160,23 +160,6 @@ 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
@@ -216,38 +199,6 @@ class Reline::Config::Test < Reline::TestCase
end
end
- def test_nested_if_else
- @config.read_lines(<<~LINES.lines)
- $if Ruby
- "\x1": "O"
- $if NotRuby
- "\x2": "X"
- $else
- "\x3": "O"
- $if Ruby
- "\x4": "O"
- $else
- "\x5": "X"
- $endif
- "\x6": "O"
- $endif
- "\x7": "O"
- $else
- "\x8": "X"
- $if NotRuby
- "\x9": "X"
- $else
- "\xA": "X"
- $endif
- "\xB": "X"
- $endif
- "\xC": "O"
- LINES
- keys = [0x1, 0x3, 0x4, 0x6, 0x7, 0xC]
- key_bindings = keys.to_h { |k| [[k.ord], ['O'.ord]] }
- assert_equal(key_bindings, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- end
-
def test_unclosed_if
e = assert_raise(Reline::Config::InvalidInputrc) do
@config.read_lines(<<~LINES.lines, "INPUTRC")
@@ -275,78 +226,6 @@ class Reline::Config::Test < Reline::TestCase
assert_equal "INPUTRC:1: unmatched endif", e.message
end
- def test_if_with_mode
- @config.read_lines(<<~LINES.lines)
- $if mode=emacs
- "\C-e": history-search-backward # comment
- $else
- "\C-f": history-search-forward
- $endif
- LINES
-
- assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
- end
-
- def test_else
- @config.read_lines(<<~LINES.lines)
- $if mode=vi
- "\C-e": history-search-backward # comment
- $else
- "\C-f": history-search-forward
- $endif
- LINES
-
- assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
- end
-
- def test_if_with_invalid_mode
- @config.read_lines(<<~LINES.lines)
- $if mode=vim
- "\C-e": history-search-backward
- $else
- "\C-f": history-search-forward # comment
- $endif
- LINES
-
- assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
- end
-
- def test_mode_label_differs_from_keymap_label
- @config.read_lines(<<~LINES.lines)
- # Sets mode_label and keymap_label to vi
- set editing-mode vi
- # Change keymap_label to emacs. mode_label is still vi.
- set keymap emacs
- # condition=true because current mode_label is vi
- $if mode=vi
- # sets keybinding to current keymap_label=emacs
- "\C-e": history-search-backward
- $endif
- LINES
- assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
- end
-
- def test_if_without_else_condition
- @config.read_lines(<<~LINES.lines)
- set editing-mode vi
- $if mode=vi
- "\C-e": history-search-backward
- $endif
- LINES
-
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
- end
-
def test_default_key_bindings
@config.add_default_key_binding('abcd'.bytes, 'EFGH'.bytes)
@config.read_lines(<<~'LINES'.lines)
@@ -417,18 +296,6 @@ class Reline::Config::Test < Reline::TestCase
assert_equal expected, @config.key_bindings
end
- def test_key_bindings_with_reset
- # @config.reset is called after each readline.
- # inputrc file is read once, so key binding shouldn't be cleared by @config.reset
- @config.add_default_key_binding('default'.bytes, 'DEFAULT'.bytes)
- @config.read_lines(<<~'LINES'.lines)
- "additional": "ADDITIONAL"
- LINES
- @config.reset
- expected = { 'default'.bytes => 'DEFAULT'.bytes, 'additional'.bytes => 'ADDITIONAL'.bytes }
- assert_equal expected, @config.key_bindings
- end
-
def test_history_size
@config.read_lines(<<~LINES.lines)
set history-size 5000
diff --git a/test/reline/test_face.rb b/test/reline/test_face.rb
deleted file mode 100644
index 8fa2be8fa4..0000000000
--- a/test/reline/test_face.rb
+++ /dev/null
@@ -1,257 +0,0 @@
-# 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 ddf8fb1472..53360409bc 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.core.encoding
+ if encoding = Reline::IOGate.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 013ca2f7b3..40b26e5058 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.core.encoding
+ @encoding = Reline::IOGate.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
@line_editor.reset(@prompt, encoding: @encoding)
end
@@ -19,699 +19,1234 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
def test_ed_insert_one
input_keys('a')
- assert_line_around_cursor('a', '')
+ assert_line('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
end
def test_ed_insert_two
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_insert_mbchar_one
input_keys('ã‹')
- assert_line_around_cursor('ã‹', '')
+ assert_line('ã‹')
+ assert_byte_pointer_size('ã‹')
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_insert_mbchar_two
input_keys('ã‹ã')
- assert_line_around_cursor('ã‹ã', '')
+ assert_line('ã‹ã')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(4)
end
def test_ed_insert_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099")
- assert_line_around_cursor("ã‹\u3099", '')
+ assert_line("ã‹\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_insert_for_plural_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099", '')
+ assert_line("ã‹\u3099ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
end
def test_move_next_and_prev
input_keys('abd')
- assert_line_around_cursor('abd', '')
+ assert_byte_pointer_size('abd')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('ab', 'd')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('a', 'bd')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
input_keys("\C-f", false)
- assert_line_around_cursor('ab', 'd')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys('c')
- assert_line_around_cursor('abc', 'd')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(4)
+ assert_line('abcd')
end
def test_move_next_and_prev_for_mbchar
input_keys('ã‹ãã‘')
- assert_line_around_cursor('ã‹ãã‘', '')
+ assert_byte_pointer_size('ã‹ãã‘')
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('ã‹ã', 'ã‘')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('ã‹', 'ãã‘')
+ assert_byte_pointer_size('ã‹')
+ assert_cursor(2)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor('ã‹ã', 'ã‘')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys('ã')
- assert_line_around_cursor('ã‹ãã', 'ã‘')
+ assert_byte_pointer_size('ã‹ãã')
+ assert_cursor(6)
+ assert_cursor_max(8)
+ assert_line('ã‹ããã‘')
end
def test_move_next_and_prev_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099ã‘\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099ã‘\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099ã‘\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor("ã‹\u3099ã\u3099", "ã‘\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã‘\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor("ã‹\u3099ã\u3099", "ã‘\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099ã\u3099", "ã‘\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099ã\u3099")
+ assert_cursor(6)
+ assert_cursor_max(8)
+ assert_line("ã‹\u3099ã\u3099ã\u3099ã‘\u3099")
end
def test_move_to_beg_end
input_keys('bcd')
- assert_line_around_cursor('bcd', '')
+ assert_byte_pointer_size('bcd')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-a", false)
- assert_line_around_cursor('', 'bcd')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys('a')
- assert_line_around_cursor('a', 'bcd')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(4)
input_keys("\C-e", false)
- assert_line_around_cursor('abcd', '')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys('e')
- assert_line_around_cursor('abcde', '')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('abcde')
end
def test_ed_newline_with_cr
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
refute(@line_editor.finished?)
input_keys("\C-m", false)
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
assert(@line_editor.finished?)
end
def test_ed_newline_with_lf
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
refute(@line_editor.finished?)
input_keys("\C-j", false)
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
assert(@line_editor.finished?)
end
def test_em_delete_prev_char
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\C-h", false)
- assert_line_around_cursor('a', '')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ assert_line('a')
end
def test_em_delete_prev_char_for_mbchar
input_keys('ã‹ã')
- assert_line_around_cursor('ã‹ã', '')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-h", false)
- assert_line_around_cursor('ã‹', '')
+ assert_byte_pointer_size('ã‹')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('ã‹')
end
def test_em_delete_prev_char_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-h", false)
- assert_line_around_cursor("ã‹\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line("ã‹\u3099")
end
def test_ed_quoted_insert
input_keys("ab\C-v\C-acd")
- assert_line_around_cursor("ab\C-acd", '')
+ assert_line("ab\C-acd")
+ assert_byte_pointer_size("ab\C-acd")
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-q\C-b")
- assert_line_around_cursor("ab\C-acd\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)
end
def test_ed_kill_line
input_keys("\C-k", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-k", false)
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('abc')
input_keys("\C-b\C-k", false)
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('ab')
end
def test_em_kill_line
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
input_keys("\C-b", false)
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
input_keys("\C-a", false)
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_move_to_beg
input_keys('abd')
- assert_line_around_cursor('abd', '')
+ assert_byte_pointer_size('abd')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('ab', 'd')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys('c')
- assert_line_around_cursor('abc', 'd')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(4)
input_keys("\C-a", false)
- assert_line_around_cursor('', 'abcd')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
input_keys('012')
- assert_line_around_cursor('012', 'abcd')
+ assert_byte_pointer_size('012')
+ assert_cursor(3)
+ assert_cursor_max(7)
+ assert_line('012abcd')
input_keys("\C-a", false)
- assert_line_around_cursor('', '012abcd')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
input_keys('ABC')
- assert_line_around_cursor('ABC', '012abcd')
+ assert_byte_pointer_size('ABC')
+ assert_cursor(3)
+ assert_cursor_max(10)
+ assert_line('ABC012abcd')
input_keys("\C-f" * 10 + "\C-a", false)
- assert_line_around_cursor('', 'ABC012abcd')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(10)
input_keys('a')
- assert_line_around_cursor('a', 'ABC012abcd')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(11)
+ assert_line('aABC012abcd')
end
def test_ed_move_to_beg_with_blank
input_keys(' abc')
- assert_line_around_cursor(' abc', '')
+ assert_byte_pointer_size(' abc')
+ assert_cursor(5)
+ assert_cursor_max(5)
input_keys("\C-a", false)
- assert_line_around_cursor('', ' abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
end
def test_ed_move_to_end
input_keys('abd')
- assert_line_around_cursor('abd', '')
+ assert_byte_pointer_size('abd')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('ab', 'd')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys('c')
- assert_line_around_cursor('abc', 'd')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(4)
input_keys("\C-e", false)
- assert_line_around_cursor('abcd', '')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys('012')
- assert_line_around_cursor('abcd012', '')
+ assert_byte_pointer_size('abcd012')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('abcd012')
input_keys("\C-e", false)
- assert_line_around_cursor('abcd012', '')
+ assert_byte_pointer_size('abcd012')
+ assert_cursor(7)
+ assert_cursor_max(7)
input_keys('ABC')
- assert_line_around_cursor('abcd012ABC', '')
+ assert_byte_pointer_size('abcd012ABC')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('abcd012ABC')
input_keys("\C-b" * 10 + "\C-e", false)
- assert_line_around_cursor('abcd012ABC', '')
+ assert_byte_pointer_size('abcd012ABC')
+ assert_cursor(10)
+ assert_cursor_max(10)
input_keys('a')
- assert_line_around_cursor('abcd012ABCa', '')
+ assert_byte_pointer_size('abcd012ABCa')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('abcd012ABCa')
end
def test_em_delete
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\C-a", false)
- assert_line_around_cursor('', 'ab')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
input_keys("\C-d", false)
- assert_line_around_cursor('', 'b')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('b')
end
def test_em_delete_for_mbchar
input_keys('ã‹ã')
- assert_line_around_cursor('ã‹ã', '')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-a", false)
- assert_line_around_cursor('', 'ã‹ã')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
input_keys("\C-d", false)
- assert_line_around_cursor('', 'ã')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line('ã')
end
def test_em_delete_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-a", false)
- assert_line_around_cursor('', "ã‹\u3099ã\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
input_keys("\C-d", false)
- 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?)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line("ã\u3099")
end
def test_ed_clear_screen
- @line_editor.instance_variable_get(:@rendered_screen).lines = [[]]
+ refute(@line_editor.instance_variable_get(:@cleared))
input_keys("\C-l", false)
- assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines)
+ assert(@line_editor.instance_variable_get(:@cleared))
end
def test_ed_clear_screen_with_inputed
input_keys('abc')
input_keys("\C-b", false)
- @line_editor.instance_variable_get(:@rendered_screen).lines = [[]]
- assert_line_around_cursor('ab', 'c')
+ refute(@line_editor.instance_variable_get(:@cleared))
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys("\C-l", false)
- 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?)
+ assert(@line_editor.instance_variable_get(:@cleared))
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ assert_line('abc')
end
- def test_key_delete_preserves_cursor
+ def test_ed_delete_next_char
input_keys('abc')
- input_keys("\C-b", false)
- assert_line_around_cursor('ab', 'c')
+ assert_cursor(3)
+ assert_cursor_max(3)
@line_editor.input_key(Reline::Key.new(:key_delete, :key_delete, false))
- assert_line_around_cursor('ab', '')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('abc')
end
def test_em_next_word
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
input_keys('abc def{bbb}ccc')
input_keys("\C-a\M-F", false)
- assert_line_around_cursor('abc', ' def{bbb}ccc')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
input_keys("\M-F", false)
- assert_line_around_cursor('abc def', '{bbb}ccc')
+ assert_byte_pointer_size('abc def')
+ assert_cursor(7)
input_keys("\M-F", false)
- assert_line_around_cursor('abc def{bbb', '}ccc')
+ assert_byte_pointer_size('abc def{bbb')
+ assert_cursor(11)
input_keys("\M-F", false)
- assert_line_around_cursor('abc def{bbb}ccc', '')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
input_keys("\M-F", false)
- assert_line_around_cursor('abc def{bbb}ccc', '')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
end
def test_em_next_word_for_mbchar
- assert_line_around_cursor('', '')
+ assert_cursor(0)
input_keys('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
input_keys("\C-a\M-F", false)
- assert_line_around_cursor('ã‚ã„ã†', ' ã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('ã‚ã„ã†')
+ assert_cursor(6)
input_keys("\M-F", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã', '{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã')
+ assert_cursor(13)
input_keys("\M-F", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™', '}ãŸã¡ã¤')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™')
+ assert_cursor(20)
input_keys("\M-F", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_cursor(27)
input_keys("\M-F", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_cursor(27)
end
def test_em_next_word_for_mbchar_by_plural_code_points
- assert_line_around_cursor("", "")
+ assert_cursor(0)
input_keys("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
input_keys("\C-a\M-F", false)
- assert_line_around_cursor("ã‚ã„ã†", " ã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size("ã‚ã„ã†")
+ assert_cursor(6)
input_keys("\M-F", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099", "{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099")
+ assert_cursor(13)
input_keys("\M-F", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™", "}ãŸã¡ã¤")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™")
+ assert_cursor(20)
input_keys("\M-F", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤", "")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_cursor(27)
input_keys("\M-F", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤", "")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_cursor(27)
end
def test_em_prev_word
input_keys('abc def{bbb}ccc')
- assert_line_around_cursor('abc def{bbb}ccc', '')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
input_keys("\M-B", false)
- assert_line_around_cursor('abc def{bbb}', 'ccc')
+ assert_byte_pointer_size('abc def{bbb}')
+ assert_cursor(12)
input_keys("\M-B", false)
- assert_line_around_cursor('abc def{', 'bbb}ccc')
+ assert_byte_pointer_size('abc def{')
+ assert_cursor(8)
input_keys("\M-B", false)
- assert_line_around_cursor('abc ', 'def{bbb}ccc')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
input_keys("\M-B", false)
- assert_line_around_cursor('', 'abc def{bbb}ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
input_keys("\M-B", false)
- assert_line_around_cursor('', 'abc def{bbb}ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
end
def test_em_prev_word_for_mbchar
input_keys('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_cursor(27)
input_keys("\M-B", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}', 'ãŸã¡ã¤')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}')
+ assert_cursor(21)
input_keys("\M-B", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{', 'ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{')
+ assert_cursor(14)
input_keys("\M-B", false)
- assert_line_around_cursor('ã‚ã„ㆠ', 'ã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
input_keys("\M-B", false)
- assert_line_around_cursor('', 'ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
input_keys("\M-B", false)
- assert_line_around_cursor('', 'ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
end
def test_em_prev_word_for_mbchar_by_plural_code_points
input_keys("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤", "")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_cursor(27)
input_keys("\M-B", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}", "ãŸã¡ã¤")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}")
+ assert_cursor(21)
input_keys("\M-B", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{", "ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{")
+ assert_cursor(14)
input_keys("\M-B", false)
- assert_line_around_cursor("ã‚ã„ㆠ", "ã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
input_keys("\M-B", false)
- assert_line_around_cursor("", "ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
input_keys("\M-B", false)
- assert_line_around_cursor("", "ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
end
def test_em_delete_next_word
input_keys('abc def{bbb}ccc')
input_keys("\C-a", false)
- assert_line_around_cursor('', 'abc def{bbb}ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(15)
input_keys("\M-d", false)
- assert_line_around_cursor('', ' def{bbb}ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(12)
+ assert_line(' def{bbb}ccc')
input_keys("\M-d", false)
- assert_line_around_cursor('', '{bbb}ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(8)
+ assert_line('{bbb}ccc')
input_keys("\M-d", false)
- assert_line_around_cursor('', '}ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
+ assert_line('}ccc')
input_keys("\M-d", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_em_delete_next_word_for_mbchar
input_keys('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
input_keys("\C-a", false)
- assert_line_around_cursor('', 'ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(27)
input_keys("\M-d", false)
- assert_line_around_cursor('', ' ã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(21)
+ assert_line(' ã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
input_keys("\M-d", false)
- assert_line_around_cursor('', '{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(14)
+ assert_line('{ã•ã—ã™}ãŸã¡ã¤')
input_keys("\M-d", false)
- assert_line_around_cursor('', '}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
+ assert_line('}ãŸã¡ã¤')
input_keys("\M-d", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_em_delete_next_word_for_mbchar_by_plural_code_points
input_keys("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
input_keys("\C-a", false)
- assert_line_around_cursor('', "ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(27)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(27)
input_keys("\M-d", false)
- assert_line_around_cursor('', " ã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(21)
+ assert_line(" ã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
input_keys("\M-d", false)
- assert_line_around_cursor('', '{ã•ã—ã™}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(14)
+ assert_line('{ã•ã—ã™}ãŸã¡ã¤')
input_keys("\M-d", false)
- assert_line_around_cursor('', '}ãŸã¡ã¤')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
+ assert_line('}ãŸã¡ã¤')
input_keys("\M-d", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_delete_prev_word
input_keys('abc def{bbb}ccc')
- assert_line_around_cursor('abc def{bbb}ccc', '')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
input_keys("\M-\C-H", false)
- assert_line_around_cursor('abc def{bbb}', '')
+ assert_byte_pointer_size('abc def{bbb}')
+ assert_cursor(12)
+ assert_cursor_max(12)
+ assert_line('abc def{bbb}')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('abc def{', '')
+ assert_byte_pointer_size('abc def{')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('abc def{')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('abc ', '')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('abc ')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_delete_prev_word_for_mbchar
input_keys('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_cursor(27)
+ assert_cursor_max(27)
input_keys("\M-\C-H", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}')
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line('ã‚ã„ㆠã‹ãã{ã•ã—ã™}')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{')
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line('ã‚ã„ㆠã‹ãã{')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('ã‚ã„ㆠ', '')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('ã‚ã„ㆠ')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
input_keys("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤", '')
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_cursor(27)
+ assert_cursor_max(27)
input_keys("\M-\C-H", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}", '')
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}")
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}")
input_keys("\M-\C-H", false)
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{", '')
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{")
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{")
input_keys("\M-\C-H", false)
- assert_line_around_cursor('ã‚ã„ㆠ', '')
+ assert_byte_pointer_size("ã‚ã„ㆠ")
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('ã‚ã„ㆠ')
input_keys("\M-\C-H", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_transpose_chars
input_keys('abc')
input_keys("\C-a", false)
- assert_line_around_cursor('', 'abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys("\C-t", false)
- assert_line_around_cursor('', 'abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ assert_line('abc')
input_keys("\C-f\C-t", false)
- assert_line_around_cursor('ba', 'c')
+ assert_byte_pointer_size('ba')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ assert_line('bac')
input_keys("\C-t", false)
- assert_line_around_cursor('bca', '')
+ assert_byte_pointer_size('bca')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('bca')
input_keys("\C-t", false)
- assert_line_around_cursor('bac', '')
+ assert_byte_pointer_size('bac')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('bac')
end
def test_ed_transpose_chars_for_mbchar
input_keys('ã‚ã‹ã•')
input_keys("\C-a", false)
- assert_line_around_cursor('', 'ã‚ã‹ã•')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("\C-t", false)
- assert_line_around_cursor('', 'ã‚ã‹ã•')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ assert_line('ã‚ã‹ã•')
input_keys("\C-f\C-t", false)
- assert_line_around_cursor('ã‹ã‚', 'ã•')
+ assert_byte_pointer_size('ã‹ã‚')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line('ã‹ã‚ã•')
input_keys("\C-t", false)
- assert_line_around_cursor('ã‹ã•ã‚', '')
+ assert_byte_pointer_size('ã‹ã•ã‚')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('ã‹ã•ã‚')
input_keys("\C-t", false)
- assert_line_around_cursor('ã‹ã‚ã•', '')
+ assert_byte_pointer_size('ã‹ã‚ã•')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('ã‹ã‚ã•')
end
def test_ed_transpose_chars_for_mbchar_by_plural_code_points
input_keys("ã‚ã‹\u3099ã•")
input_keys("\C-a", false)
- assert_line_around_cursor('', "ã‚ã‹\u3099ã•")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("\C-t", false)
- assert_line_around_cursor('', "ã‚ã‹\u3099ã•")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ assert_line("ã‚ã‹\u3099ã•")
input_keys("\C-f\C-t", false)
- assert_line_around_cursor("ã‹\u3099ã‚", 'ã•')
+ assert_byte_pointer_size("ã‹\u3099ã‚")
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line("ã‹\u3099ã‚ã•")
input_keys("\C-t", false)
- assert_line_around_cursor("ã‹\u3099ã•ã‚", '')
+ assert_byte_pointer_size("ã‹\u3099ã•ã‚")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line("ã‹\u3099ã•ã‚")
input_keys("\C-t", false)
- assert_line_around_cursor("ã‹\u3099ã‚ã•", '')
+ assert_byte_pointer_size("ã‹\u3099ã‚ã•")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line("ã‹\u3099ã‚ã•")
end
def test_ed_transpose_words
input_keys('abc def')
- assert_line_around_cursor('abc def', '')
+ assert_line('abc def')
+ assert_byte_pointer_size('abc def')
+ assert_cursor(7)
+ assert_cursor_max(7)
input_keys("\M-t", false)
- assert_line_around_cursor('def abc', '')
+ assert_line('def abc')
+ assert_byte_pointer_size('def abc')
+ assert_cursor(7)
+ assert_cursor_max(7)
input_keys("\C-a\C-k", false)
input_keys(' abc def ')
input_keys("\C-b" * 4, false)
- assert_line_around_cursor(' abc de', 'f ')
+ assert_line(' abc def ')
+ assert_byte_pointer_size(' abc de')
+ assert_cursor(8)
+ assert_cursor_max(12)
input_keys("\M-t", false)
- assert_line_around_cursor(' def abc', ' ')
+ assert_line(' def abc ')
+ assert_byte_pointer_size(' def abc')
+ assert_cursor(9)
+ assert_cursor_max(12)
input_keys("\C-a\C-k", false)
input_keys(' abc def ')
input_keys("\C-b" * 6, false)
- assert_line_around_cursor(' abc ', 'def ')
+ assert_line(' abc def ')
+ assert_byte_pointer_size(' abc ')
+ assert_cursor(6)
+ assert_cursor_max(12)
input_keys("\M-t", false)
- assert_line_around_cursor(' def abc', ' ')
+ assert_line(' def abc ')
+ assert_byte_pointer_size(' def abc')
+ assert_cursor(9)
+ assert_cursor_max(12)
input_keys("\M-t", false)
- assert_line_around_cursor(' abc def', '')
+ assert_line(' abc def')
+ assert_byte_pointer_size(' abc def')
+ assert_cursor(12)
+ assert_cursor_max(12)
end
def test_ed_transpose_words_for_mbchar
input_keys('ã‚ã„ㆠã‹ãã')
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã', '')
+ assert_line('ã‚ã„ㆠã‹ãã')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã')
+ assert_cursor(13)
+ assert_cursor_max(13)
input_keys("\M-t", false)
- assert_line_around_cursor('ã‹ãã ã‚ã„ã†', '')
+ assert_line('ã‹ãã ã‚ã„ã†')
+ assert_byte_pointer_size('ã‹ãã ã‚ã„ã†')
+ assert_cursor(13)
+ assert_cursor_max(13)
input_keys("\C-a\C-k", false)
input_keys(' ã‚ã„ㆠã‹ãã ')
input_keys("\C-b" * 4, false)
- assert_line_around_cursor(' ã‚ã„ㆠã‹ã', 'ã ')
+ assert_line(' ã‚ã„ㆠã‹ãã ')
+ assert_byte_pointer_size(' ã‚ã„ㆠã‹ã')
+ assert_cursor(13)
+ assert_cursor_max(18)
input_keys("\M-t", false)
- assert_line_around_cursor(' ã‹ãã ã‚ã„ã†', ' ')
+ assert_line(' ã‹ãã ã‚ã„ㆠ')
+ assert_byte_pointer_size(' ã‹ãã ã‚ã„ã†')
+ assert_cursor(15)
+ assert_cursor_max(18)
input_keys("\C-a\C-k", false)
input_keys(' ã‚ã„ㆠã‹ãã ')
input_keys("\C-b" * 6, false)
- assert_line_around_cursor(' ã‚ã„ㆠ', 'ã‹ãã ')
+ assert_line(' ã‚ã„ㆠã‹ãã ')
+ assert_byte_pointer_size(' ã‚ã„ㆠ')
+ assert_cursor(9)
+ assert_cursor_max(18)
input_keys("\M-t", false)
- assert_line_around_cursor(' ã‹ãã ã‚ã„ã†', ' ')
+ assert_line(' ã‹ãã ã‚ã„ㆠ')
+ assert_byte_pointer_size(' ã‹ãã ã‚ã„ã†')
+ assert_cursor(15)
+ assert_cursor_max(18)
input_keys("\M-t", false)
- assert_line_around_cursor(' ã‚ã„ㆠã‹ãã', '')
+ assert_line(' ã‚ã„ㆠã‹ãã')
+ assert_byte_pointer_size(' ã‚ã„ㆠã‹ãã')
+ assert_cursor(18)
+ assert_cursor_max(18)
end
def test_ed_transpose_words_with_one_word
input_keys('abc ')
- assert_line_around_cursor('abc ', '')
+ assert_line('abc ')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(5)
+ assert_cursor_max(5)
input_keys("\M-t", false)
- assert_line_around_cursor('abc ', '')
+ assert_line('abc ')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(5)
+ assert_cursor_max(5)
input_keys("\C-b", false)
- assert_line_around_cursor('abc ', ' ')
+ assert_line('abc ')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ assert_cursor_max(5)
input_keys("\M-t", false)
- assert_line_around_cursor('abc ', ' ')
+ assert_line('abc ')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ assert_cursor_max(5)
input_keys("\C-b" * 2, false)
- assert_line_around_cursor('ab', 'c ')
+ assert_line('abc ')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(5)
input_keys("\M-t", false)
- assert_line_around_cursor('ab', 'c ')
+ assert_line('abc ')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(5)
input_keys("\M-t", false)
- assert_line_around_cursor('ab', 'c ')
+ assert_line('abc ')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(5)
end
def test_ed_transpose_words_with_one_word_for_mbchar
input_keys('ã‚ã„ㆠ')
- assert_line_around_cursor('ã‚ã„ㆠ', '')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(8)
+ assert_cursor_max(8)
input_keys("\M-t", false)
- assert_line_around_cursor('ã‚ã„ㆠ', '')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(8)
+ assert_cursor_max(8)
input_keys("\C-b", false)
- assert_line_around_cursor('ã‚ã„ㆠ', ' ')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
+ assert_cursor_max(8)
input_keys("\M-t", false)
- assert_line_around_cursor('ã‚ã„ㆠ', ' ')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
+ assert_cursor_max(8)
input_keys("\C-b" * 2, false)
- assert_line_around_cursor('ã‚ã„', 'ㆠ')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„')
+ assert_cursor(4)
+ assert_cursor_max(8)
input_keys("\M-t", false)
- assert_line_around_cursor('ã‚ã„', 'ㆠ')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„')
+ assert_cursor(4)
+ assert_cursor_max(8)
input_keys("\M-t", false)
- assert_line_around_cursor('ã‚ã„', 'ㆠ')
+ assert_line('ã‚ã„ㆠ')
+ assert_byte_pointer_size('ã‚ã„')
+ assert_cursor(4)
+ assert_cursor_max(8)
end
def test_ed_digit
input_keys('0123')
- assert_line_around_cursor('0123', '')
+ assert_byte_pointer_size('0123')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('0123')
end
def test_ed_next_and_prev_char
input_keys('abc')
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('ab', 'c')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('a', 'bc')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('', 'abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys("\C-b", false)
- assert_line_around_cursor('', 'abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys("\C-f", false)
- assert_line_around_cursor('a', 'bc')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
input_keys("\C-f", false)
- assert_line_around_cursor('ab', 'c')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
input_keys("\C-f", false)
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-f", false)
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
end
def test_ed_next_and_prev_char_for_mbchar
input_keys('ã‚ã„ã†')
- assert_line_around_cursor('ã‚ã„ã†', '')
+ assert_byte_pointer_size('ã‚ã„ã†')
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('ã‚ã„', 'ã†')
+ assert_byte_pointer_size('ã‚ã„')
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('ã‚', 'ã„ã†')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('', 'ã‚ã„ã†')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('', 'ã‚ã„ã†')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor('ã‚', 'ã„ã†')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor('ã‚ã„', 'ã†')
+ assert_byte_pointer_size('ã‚ã„')
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor('ã‚ã„ã†', '')
+ assert_byte_pointer_size('ã‚ã„ã†')
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor('ã‚ã„ã†', '')
+ assert_byte_pointer_size('ã‚ã„ã†')
+ assert_cursor(6)
+ assert_cursor_max(6)
end
def test_ed_next_and_prev_char_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099ã\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099ã\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor("ã‹\u3099ã\u3099", "ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('', "ã‹\u3099ã\u3099ã\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("\C-b", false)
- assert_line_around_cursor('', "ã‹\u3099ã\u3099ã\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor("ã‹\u3099ã\u3099", "ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor("ã‹\u3099ã\u3099ã\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099ã\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
input_keys("\C-f", false)
- assert_line_around_cursor("ã‹\u3099ã\u3099ã\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099ã\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
end
def test_em_capitol_case
input_keys('abc def{bbb}ccc')
input_keys("\C-a\M-c", false)
- assert_line_around_cursor('Abc', ' def{bbb}ccc')
+ assert_byte_pointer_size('Abc')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('Abc def{bbb}ccc')
input_keys("\M-c", false)
- assert_line_around_cursor('Abc Def', '{bbb}ccc')
+ assert_byte_pointer_size('Abc Def')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('Abc Def{bbb}ccc')
input_keys("\M-c", false)
- assert_line_around_cursor('Abc Def{Bbb', '}ccc')
+ assert_byte_pointer_size('Abc Def{Bbb')
+ assert_cursor(11)
+ assert_cursor_max(15)
+ assert_line('Abc Def{Bbb}ccc')
input_keys("\M-c", false)
- assert_line_around_cursor('Abc Def{Bbb}Ccc', '')
+ assert_byte_pointer_size('Abc Def{Bbb}Ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ assert_line('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_line_around_cursor('{}#* Aaa', '!!!cCc ')
+ assert_byte_pointer_size('{}#* Aaa')
+ assert_cursor(11)
+ assert_cursor_max(20)
+ assert_line('{}#* Aaa!!!cCc ')
input_keys("\M-c", false)
- assert_line_around_cursor('{}#* Aaa!!!Ccc', ' ')
+ assert_byte_pointer_size('{}#* Aaa!!!Ccc')
+ assert_cursor(17)
+ assert_cursor_max(20)
+ assert_line('{}#* Aaa!!!Ccc ')
input_keys("\M-c", false)
- assert_line_around_cursor('{}#* Aaa!!!Ccc ', '')
+ assert_byte_pointer_size('{}#* Aaa!!!Ccc ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('{}#* Aaa!!!Ccc ')
end
def test_em_lower_case
input_keys('AbC def{bBb}CCC')
input_keys("\C-a\M-l", false)
- assert_line_around_cursor('abc', ' def{bBb}CCC')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('abc def{bBb}CCC')
input_keys("\M-l", false)
- assert_line_around_cursor('abc def', '{bBb}CCC')
+ assert_byte_pointer_size('abc def')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('abc def{bBb}CCC')
input_keys("\M-l", false)
- assert_line_around_cursor('abc def{bbb', '}CCC')
+ assert_byte_pointer_size('abc def{bbb')
+ assert_cursor(11)
+ assert_cursor_max(15)
+ assert_line('abc def{bbb}CCC')
input_keys("\M-l", false)
- assert_line_around_cursor('abc def{bbb}ccc', '')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ assert_line('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_line_around_cursor('{}#* aaa', '!!!cCc ')
+ assert_byte_pointer_size('{}#* aaa')
+ assert_cursor(11)
+ assert_cursor_max(20)
+ assert_line('{}#* aaa!!!cCc ')
input_keys("\M-l", false)
- assert_line_around_cursor('{}#* aaa!!!ccc', ' ')
+ assert_byte_pointer_size('{}#* aaa!!!ccc')
+ assert_cursor(17)
+ assert_cursor_max(20)
+ assert_line('{}#* aaa!!!ccc ')
input_keys("\M-l", false)
- assert_line_around_cursor('{}#* aaa!!!ccc ', '')
+ assert_byte_pointer_size('{}#* aaa!!!ccc ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('{}#* aaa!!!ccc ')
end
def test_em_upper_case
input_keys('AbC def{bBb}CCC')
input_keys("\C-a\M-u", false)
- assert_line_around_cursor('ABC', ' def{bBb}CCC')
+ assert_byte_pointer_size('ABC')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('ABC def{bBb}CCC')
input_keys("\M-u", false)
- assert_line_around_cursor('ABC DEF', '{bBb}CCC')
+ assert_byte_pointer_size('ABC DEF')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('ABC DEF{bBb}CCC')
input_keys("\M-u", false)
- assert_line_around_cursor('ABC DEF{BBB', '}CCC')
+ assert_byte_pointer_size('ABC DEF{BBB')
+ assert_cursor(11)
+ assert_cursor_max(15)
+ assert_line('ABC DEF{BBB}CCC')
input_keys("\M-u", false)
- assert_line_around_cursor('ABC DEF{BBB}CCC', '')
+ assert_byte_pointer_size('ABC DEF{BBB}CCC')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ assert_line('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_line_around_cursor('{}#* AAA', '!!!cCc ')
+ assert_byte_pointer_size('{}#* AAA')
+ assert_cursor(11)
+ assert_cursor_max(20)
+ assert_line('{}#* AAA!!!cCc ')
input_keys("\M-u", false)
- assert_line_around_cursor('{}#* AAA!!!CCC', ' ')
+ assert_byte_pointer_size('{}#* AAA!!!CCC')
+ assert_cursor(17)
+ assert_cursor_max(20)
+ assert_line('{}#* AAA!!!CCC ')
input_keys("\M-u", false)
- assert_line_around_cursor('{}#* AAA!!!CCC ', '')
+ assert_byte_pointer_size('{}#* AAA!!!CCC ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('{}#* AAA!!!CCC ')
end
def test_em_delete_or_list
@@ -726,16 +1261,28 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('fooo')
- assert_line_around_cursor('fooo', '')
+ assert_byte_pointer_size('fooo')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('fooo')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-b", false)
- assert_line_around_cursor('foo', 'o')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(4)
+ assert_line('fooo')
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_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('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_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -750,13 +1297,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('foo_')
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
assert_equal(%w{foo_foo foo_bar}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -772,63 +1328,36 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('fo')
- assert_line_around_cursor('fo', '')
+ assert_byte_pointer_size('fo')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('fo')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('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_line_around_cursor('foo_a', '')
+ assert_byte_pointer_size('foo_a')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('foo_a')
input_keys("\C-h", false)
input_keys('b')
input_keys("\C-i", false)
- assert_line_around_cursor('foo_ba', '')
- input_keys("\C-h")
- input_key_by_symbol(:complete)
- assert_line_around_cursor('foo_ba', '')
- input_keys("\C-h", false)
- input_key_by_symbol(:menu_complete)
- assert_line_around_cursor('foo_bar', '')
- input_key_by_symbol(:menu_complete)
- assert_line_around_cursor('foo_baz', '')
- input_keys("\C-h", false)
- input_key_by_symbol(:menu_complete_backward)
- assert_line_around_cursor('foo_baz', '')
- input_key_by_symbol(:menu_complete_backward)
- assert_line_around_cursor('foo_bar', '')
- end
-
- def test_autocompletion
- @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', '')
- input_key_by_symbol(:completion_journey_up)
- assert_line_around_cursor('Readline', '')
- input_key_by_symbol(:complete)
- assert_line_around_cursor('Regexp', '')
- input_key_by_symbol(:menu_complete_backward)
- assert_line_around_cursor('Readline', '')
- input_key_by_symbol(:menu_complete)
- assert_line_around_cursor('Regexp', '')
- ensure
- @config.autocompletion = false
+ assert_byte_pointer_size('foo_ba')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('foo_ba')
end
def test_completion_with_indent
@@ -843,13 +1372,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys(' fo')
- assert_line_around_cursor(' fo', '')
+ assert_byte_pointer_size(' fo')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line(' fo')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor(' foo_', '')
+ assert_byte_pointer_size(' foo_')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line(' foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor(' foo_', '')
+ assert_byte_pointer_size(' foo_')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line(' foo_')
assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -865,13 +1403,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys(' "".fo')
- assert_line_around_cursor(' "".fo', '')
+ assert_byte_pointer_size(' "".fo')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line(' "".fo')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor(' "".foo_', '')
+ assert_byte_pointer_size(' "".foo_')
+ assert_cursor(9)
+ assert_cursor_max(9)
+ assert_line(' "".foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor(' "".foo_', '')
+ assert_byte_pointer_size(' "".foo_')
+ assert_cursor(9)
+ assert_cursor_max(9)
+ assert_line(' "".foo_')
assert_equal(%w{"".foo_foo "".foo_bar "".foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -889,33 +1436,54 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
matched = m
}
input_keys('fo')
- assert_line_around_cursor('fo', '')
+ assert_byte_pointer_size('fo')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('fo')
assert_equal(Reline::LineEditor::CompletionState::NORMAL, @line_editor.instance_variable_get(:@completion_state))
assert_equal(nil, matched)
input_keys("\C-i", false)
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('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_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('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_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('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_line_around_cursor('foo_bar', '')
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('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_line_around_cursor('foo_bar', '')
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('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_line_around_cursor('foo_bar', '')
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal('foo_bar', matched)
end
@@ -932,25 +1500,43 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('fo')
- assert_line_around_cursor('fo', '')
+ assert_byte_pointer_size('fo')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('fo')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('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_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('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_line_around_cursor('foo_a', '')
+ assert_byte_pointer_size('foo_a')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('foo_a')
input_keys("\C-h", false)
input_keys('b')
input_keys("\C-i", false)
- assert_line_around_cursor('foo_ba', '')
+ assert_byte_pointer_size('foo_ba')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('foo_ba')
end
def test_completion_in_middle_of_line
@@ -965,11 +1551,17 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('abcde fo ABCDE')
- assert_line_around_cursor('abcde fo ABCDE', '')
+ assert_line('abcde fo ABCDE')
input_keys("\C-b" * 6 + "\C-i", false)
- assert_line_around_cursor('abcde foo_', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_')
+ assert_cursor(10)
+ assert_cursor_max(16)
+ assert_line('abcde foo_ ABCDE')
input_keys("\C-b" * 2 + "\C-i", false)
- assert_line_around_cursor('abcde foo_', 'o_ ABCDE')
+ assert_byte_pointer_size('abcde foo_')
+ assert_cursor(10)
+ assert_cursor_max(18)
+ assert_line('abcde foo_o_ ABCDE')
end
def test_completion_with_nil_value
@@ -985,65 +1577,125 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
@config.completion_ignore_case = true
input_keys('fo')
- assert_line_around_cursor('fo', '')
+ assert_byte_pointer_size('fo')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('fo')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_line_around_cursor('foo_', '')
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('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_line_around_cursor('foo_a', '')
+ assert_byte_pointer_size('foo_a')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('foo_a')
input_keys("\C-h", false)
input_keys('b')
input_keys("\C-i", false)
- assert_line_around_cursor('foo_ba', '')
+ assert_byte_pointer_size('foo_ba')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('foo_ba')
end
def test_em_kill_region
input_keys('abc def{bbb}ccc ddd ')
- assert_line_around_cursor('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 ')
input_keys("\C-w", false)
- assert_line_around_cursor('abc def{bbb}ccc ', '')
+ assert_byte_pointer_size('abc def{bbb}ccc ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('abc def{bbb}ccc ')
input_keys("\C-w", false)
- assert_line_around_cursor('abc ', '')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('abc ')
input_keys("\C-w", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys("\C-w", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_em_kill_region_mbchar
input_keys('ã‚ ã„ ã†{ã†}ㆠ')
- assert_line_around_cursor('ã‚ ã„ ã†{ã†}ㆠ', '')
+ assert_byte_pointer_size('ã‚ ã„ ã†{ã†}ㆠ')
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line('ã‚ ã„ ã†{ã†}ㆠ')
input_keys("\C-w", false)
- assert_line_around_cursor('ã‚ ã„ ', '')
+ assert_byte_pointer_size('ã‚ ã„ ')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('ã‚ ã„ ')
input_keys("\C-w", false)
- assert_line_around_cursor('ã‚ ', '')
+ assert_byte_pointer_size('ã‚ ')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('ã‚ ')
input_keys("\C-w", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_vi_search_prev
Reline::HISTORY.concat(%w{abc 123 AAA})
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-ra\C-j")
- assert_line_around_cursor('', 'abc')
+ assert_line('abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
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_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-p")
- assert_line_around_cursor('AAA', '')
+ assert_line('AAA')
+ assert_byte_pointer_size('AAA')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-p")
- assert_line_around_cursor('123', '')
+ assert_line('123')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-p")
- assert_line_around_cursor('123', '')
+ assert_line('123')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(3)
ensure
@config.history_size = history_size
end
@@ -1054,13 +1706,25 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r123")
- assert_line_around_cursor('1234', '')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys("\C-ha")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-h3")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_search_history_to_front
@@ -1069,13 +1733,25 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-s123")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys("\C-ha")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-h3")
- assert_line_around_cursor('1234', '')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_search_history_front_and_back
@@ -1084,15 +1760,30 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-s12")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys("\C-s")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_search_history_back_and_front
@@ -1101,15 +1792,30 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r12")
- assert_line_around_cursor('1234', '')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys("\C-r")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-s")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-s")
- assert_line_around_cursor('1234', '')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_search_history_to_back_in_the_middle_of_histories
@@ -1118,11 +1824,20 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-p\C-p")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('12aa')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-r123")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('1235')
+ assert_cursor(4)
+ assert_cursor_max(4)
end
def test_search_history_twice
@@ -1131,11 +1846,20 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r123")
- assert_line_around_cursor('1234', '')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys("\C-r")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_search_history_by_last_determined
@@ -1144,17 +1868,35 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r123")
- assert_line_around_cursor('1234', '')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys("\C-j")
- assert_line_around_cursor('', '1234')
+ assert_line('1234')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
input_keys("\C-k") # delete
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r")
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r")
- assert_line_around_cursor('1235', '')
+ assert_line('1235')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_search_history_with_isearch_terminator
@@ -1166,40 +1908,76 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys("\C-r12a")
- assert_line_around_cursor('12aa', '')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0) # doesn't determine yet
input_keys('Y')
- assert_line_around_cursor('', '12aa')
+ assert_line('12aa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
input_keys('x')
- assert_line_around_cursor('x', '12aa')
+ assert_line('x12aa')
+ assert_byte_pointer_size('x')
+ assert_cursor(1)
+ assert_cursor_max(5)
end
def test_em_set_mark_and_em_exchange_mark
input_keys('aaa bbb ccc ddd')
- assert_line_around_cursor('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')
input_keys("\C-a\M-F\M-F", false)
- assert_line_around_cursor('aaa bbb', ' ccc ddd')
+ assert_byte_pointer_size('aaa bbb')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
input_keys("\x00", false) # C-Space
- assert_line_around_cursor('aaa bbb', ' ccc ddd')
+ assert_byte_pointer_size('aaa bbb')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ccc ddd')
assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer))
input_keys("\C-a", false)
- assert_line_around_cursor('', 'aaa bbb ccc ddd')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ccc ddd')
assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer))
input_key_by_symbol(:em_exchange_mark)
- assert_line_around_cursor('aaa bbb', ' ccc ddd')
+ assert_byte_pointer_size('aaa bbb')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('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_line_around_cursor('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')
input_keys("\C-a\M-f", false)
- assert_line_around_cursor('aaa', ' bbb ccc ddd')
+ assert_byte_pointer_size('aaa')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
input_key_by_symbol(:em_exchange_mark)
- assert_line_around_cursor('aaa', ' bbb ccc ddd')
+ assert_byte_pointer_size('aaa')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
end
@@ -1210,7 +1988,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, @line_editor.finished?)
+ result = @line_editor.__send__(:modify_lines, @line_editor.whole_lines)
$/ = nil
assert_equal(['abcdef'], result)
ensure
@@ -1228,11 +2006,20 @@ 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_line_around_cursor('123', '45')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('123', '56')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12356')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('123', '56')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12356')
end
def test_ed_search_prev_history_with_empty
@@ -1243,13 +2030,25 @@ 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_line_around_cursor('', '12345')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12aaa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12aaa')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12356')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12356')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12356')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12356')
end
def test_ed_search_prev_history_without_match
@@ -1261,7 +2060,10 @@ 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_line_around_cursor('ABC', '')
+ assert_byte_pointer_size('ABC')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('ABC')
end
def test_ed_search_next_history
@@ -1273,15 +2075,30 @@ 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_line_around_cursor('123', '45')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('123', '56')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12356')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('123', '56')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12356')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('123', '45')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12345')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('123', '45')
+ assert_byte_pointer_size('123')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ assert_line('12345')
end
def test_ed_search_next_history_with_empty
@@ -1292,75 +2109,133 @@ 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_line_around_cursor('', '12345')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12aaa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12aaa')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12356')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12356')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('', '12aaa')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12aaa')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('', '12345')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ assert_line('12345')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- 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')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
# Unicode emoji test
def test_ed_insert_for_include_zwj_emoji
- omit "This test is for UTF-8 but the locale is #{Reline.core.encoding}" if Reline.core.encoding != Encoding::UTF_8
+ omit "This test is for UTF-8 but the locale is #{Reline::IOGate.encoding}" if Reline::IOGate.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_around_cursor('👨', '')
+ assert_line("\u{1F468}")
+ assert_byte_pointer_size("\u{1F468}")
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\u200D") # U+200D is ZERO WIDTH JOINER
- assert_line_around_cursor('👨â€', '')
+ assert_line("\u{1F468 200D}")
+ assert_byte_pointer_size("\u{1F468 200D}")
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\u{1F469}") # U+1F469 is woman "👩"
- assert_line_around_cursor('👨â€ðŸ‘©', '')
+ assert_line("\u{1F468 200D 1F469}")
+ assert_byte_pointer_size("\u{1F468 200D 1F469}")
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\u200D") # U+200D is ZERO WIDTH JOINER
- assert_line_around_cursor('👨â€ðŸ‘©â€', '')
+ assert_line("\u{1F468 200D 1F469 200D}")
+ assert_byte_pointer_size("\u{1F468 200D 1F469 200D}")
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\u{1F467}") # U+1F467 is girl "👧"
- assert_line_around_cursor('👨â€ðŸ‘©â€ðŸ‘§', '')
+ 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)
input_keys("\u200D") # U+200D is ZERO WIDTH JOINER
- assert_line_around_cursor('👨â€ðŸ‘©â€ðŸ‘§â€', '')
+ 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)
input_keys("\u{1F466}") # U+1F466 is boy "👦"
- assert_line_around_cursor('👨â€ðŸ‘©â€ðŸ‘§â€ðŸ‘¦', '')
+ 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)
# 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_around_cursor('👨â€ðŸ‘©â€ðŸ‘§â€ðŸ‘¦ðŸ‘¨â€ðŸ‘©â€ðŸ‘§â€ðŸ‘¦', '')
+ 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)
end
def test_ed_insert_for_include_valiation_selector
- omit "This test is for UTF-8 but the locale is #{Reline.core.encoding}" if Reline.core.encoding != Encoding::UTF_8
+ omit "This test is for UTF-8 but the locale is #{Reline::IOGate.encoding}" if Reline::IOGate.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_around_cursor('0', '')
+ assert_line("\u0030")
+ assert_byte_pointer_size("\u0030")
+ assert_cursor(1)
+ assert_cursor_max(1)
input_keys("\uFE00") # U+FE00 is VARIATION SELECTOR-1
- assert_line_around_cursor('0︀', '')
+ assert_line("\u{0030 FE00}")
+ assert_byte_pointer_size("\u{0030 FE00}")
+ assert_cursor(1)
+ assert_cursor_max(1)
end
def test_em_yank_pop
input_keys("def hoge\C-w\C-b\C-f\C-w", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys("\C-y", false)
- assert_line_around_cursor('def ', '')
+ assert_byte_pointer_size('def ')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('def ')
input_keys("\M-\C-y", false)
- assert_line_around_cursor('hoge', '')
+ assert_byte_pointer_size('hoge')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('hoge')
end
def test_em_kill_region_with_kill_ring
input_keys("def hoge\C-b\C-b\C-b\C-b", false)
- assert_line_around_cursor('def ', 'hoge')
+ assert_byte_pointer_size('def ')
+ assert_cursor(4)
+ assert_cursor_max(8)
+ assert_line('def hoge')
input_keys("\C-k\C-w", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys("\C-y", false)
- assert_line_around_cursor('def hoge', '')
+ assert_byte_pointer_size('def hoge')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('def hoge')
end
def test_ed_search_prev_next_history_in_multibyte
@@ -1376,133 +2251,104 @@ 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_line_around_cursor(' 123', '45')
+ assert_byte_pointer_size(' 123')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line(' 12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
assert_line_index(2)
assert_whole_lines(['def hoge', ' 67890', ' 12345', 'end'])
- assert_line_around_cursor(' 123', '45')
+ assert_byte_pointer_size(' 123')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line(' 12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
assert_line_index(2)
assert_whole_lines(['def hoge', ' 67890', ' 12345', 'end'])
- assert_line_around_cursor(' 123', '45')
+ assert_byte_pointer_size(' 123')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line(' 12345')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
assert_line_index(1)
assert_whole_lines(['def foo', ' 12345', 'end'])
- assert_line_around_cursor(' 123', '45')
+ assert_byte_pointer_size(' 123')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line(' 12345')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
assert_line_index(1)
assert_whole_lines(['def foo', ' 12345', 'end'])
- assert_line_around_cursor(' 123', '45')
+ assert_byte_pointer_size(' 123')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line(' 12345')
end
def test_ignore_NUL_by_ed_quoted_insert
input_keys(%Q{"\C-v\C-@"}, false)
- assert_line_around_cursor('""', '')
+ assert_byte_pointer_size('""')
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_argument_digit_by_meta_num
input_keys('abcdef')
- assert_line_around_cursor('abcdef', '')
+ assert_byte_pointer_size('abcdef')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('abcdef')
input_keys("\M-2", false)
input_keys("\C-h", false)
- assert_line_around_cursor('abcd', '')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('abcd')
end
def test_halfwidth_kana_width_dakuten
input_raw_keys('ガギゲゴ')
- assert_line_around_cursor('ガギゲゴ', '')
+ assert_byte_pointer_size('ガギゲゴ')
+ assert_cursor(8)
+ assert_cursor_max(8)
input_keys("\C-b\C-b", false)
- assert_line_around_cursor('ガギ', 'ゲゴ')
+ assert_byte_pointer_size('ガギ')
+ assert_cursor(4)
+ assert_cursor_max(8)
input_raw_keys('グ', false)
- assert_line_around_cursor('ガギグ', 'ゲゴ')
+ assert_byte_pointer_size('ガギグ')
+ assert_cursor(6)
+ assert_cursor_max(10)
+ assert_line('ガギグゲゴ')
end
def test_input_unknown_char
input_keys('͸') # U+0378 (unassigned)
- assert_line_around_cursor('͸', '')
+ assert_line('͸')
+ assert_byte_pointer_size('͸')
+ assert_cursor(1)
+ assert_cursor_max(1)
end
def test_unix_line_discard
input_keys("\C-u", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-b\C-u", false)
- assert_line_around_cursor('', 'c')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
input_keys("\C-f\C-u", false)
- 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
-
- def test_undo
- input_keys("\C-_", false)
- assert_line_around_cursor('', '')
- input_keys("aã‚b\C-h\C-h\C-h", false)
- assert_line_around_cursor('', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('a', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('aã‚', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('aã‚b', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('aã‚', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('a', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('', '')
- end
-
- def test_undo_with_cursor_position
- input_keys("abc\C-b\C-h", false)
- assert_line_around_cursor('a', 'c')
- input_keys("\C-_", false)
- assert_line_around_cursor('ab', 'c')
- input_keys("ã‚ã„ã†\C-b\C-h", false)
- assert_line_around_cursor('abã‚', 'ã†c')
- input_keys("\C-_", false)
- assert_line_around_cursor('abã‚ã„', 'ã†c')
- end
-
- def test_undo_with_multiline
- @line_editor.multiline_on
- @line_editor.confirm_multiline_termination_proc = proc {}
- input_keys("1\n2\n3", false)
- assert_whole_lines(["1", "2", "3"])
- assert_line_index(2)
- assert_line_around_cursor('3', '')
- input_keys("\C-p\C-h\C-h", false)
- assert_whole_lines(["1", "3"])
- assert_line_index(0)
- assert_line_around_cursor('1', '')
- input_keys("\C-_", false)
- assert_whole_lines(["1", "", "3"])
- assert_line_index(1)
- assert_line_around_cursor('', '')
- input_keys("\C-_", false)
- assert_whole_lines(["1", "2", "3"])
- assert_line_index(1)
- assert_line_around_cursor('2', '')
- input_keys("\C-_", false)
- assert_whole_lines(["1", "2", ""])
- assert_line_index(2)
- assert_line_around_cursor('', '')
- input_keys("\C-_", false)
- assert_whole_lines(["1", "2"])
- assert_line_index(1)
- assert_line_around_cursor('2', '')
- end
-
- def test_undo_with_many_times
- str = "a" + "b" * 100
- input_keys(str, false)
- 100.times { input_keys("\C-_", false) }
- assert_line_around_cursor('a', '')
- input_keys("\C-_", false)
- assert_line_around_cursor('a', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
end
diff --git a/test/reline/test_key_actor_vi.rb b/test/reline/test_key_actor_vi.rb
index 4deae2dd83..6e1d9dbbda 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.core.encoding
+ @encoding = Reline::IOGate.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
@line_editor.reset(@prompt, encoding: @encoding)
end
@@ -25,513 +25,950 @@ 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_around_cursor('ab', 'c')
+ assert_line('abc')
end
def test_vi_insert
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys('i')
- assert_line_around_cursor('i', '')
+ assert_line('i')
+ assert_cursor(1)
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("\C-[")
- assert_line_around_cursor('', 'i')
+ assert_line('i')
+ assert_cursor(0)
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('i')
- assert_line_around_cursor('', 'i')
+ assert_line('i')
+ assert_cursor(0)
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_around_cursor('a', '')
+ assert_line('a')
+ assert_cursor(1)
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("\C-[")
- assert_line_around_cursor('', 'a')
+ assert_line('a')
+ assert_cursor(0)
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('a')
- assert_line_around_cursor('a', '')
+ assert_line('a')
+ assert_cursor(1)
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_vi_insert_at_bol
input_keys('I')
- assert_line_around_cursor('I', '')
+ assert_line('I')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("12345\C-[hh")
- assert_line_around_cursor('I12', '345')
+ assert_line('I12345')
+ assert_byte_pointer_size('I12')
+ assert_cursor(3)
+ assert_cursor_max(6)
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('I')
- assert_line_around_cursor('', 'I12345')
+ assert_line('I12345')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_vi_add_at_eol
input_keys('A')
- assert_line_around_cursor('A', '')
+ assert_line('A')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("12345\C-[hh")
- assert_line_around_cursor('A12', '345')
+ assert_line('A12345')
+ assert_byte_pointer_size('A12')
+ assert_cursor(3)
+ assert_cursor_max(6)
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('A')
- assert_line_around_cursor('A12345', '')
+ assert_line('A12345')
+ assert_byte_pointer_size('A12345')
+ assert_cursor(6)
+ assert_cursor_max(6)
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_ed_insert_one
input_keys('a')
- assert_line_around_cursor('a', '')
+ assert_line('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
end
def test_ed_insert_two
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_insert_mbchar_one
input_keys('ã‹')
- assert_line_around_cursor('ã‹', '')
+ assert_line('ã‹')
+ assert_byte_pointer_size('ã‹')
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_insert_mbchar_two
input_keys('ã‹ã')
- assert_line_around_cursor('ã‹ã', '')
+ assert_line('ã‹ã')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(4)
end
def test_ed_insert_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099")
- assert_line_around_cursor("ã‹\u3099", '')
+ assert_line("ã‹\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
end
def test_ed_insert_for_plural_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099", '')
+ assert_line("ã‹\u3099ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
end
def test_ed_next_char
input_keys("abcdef\C-[0")
- assert_line_around_cursor('', 'abcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys('l')
- assert_line_around_cursor('a', 'bcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(6)
input_keys('2l')
- assert_line_around_cursor('abc', 'def')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
end
def test_ed_prev_char
input_keys("abcdef\C-[")
- assert_line_around_cursor('abcde', 'f')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(6)
input_keys('h')
- assert_line_around_cursor('abcd', 'ef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
input_keys('2h')
- assert_line_around_cursor('ab', 'cdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(6)
end
def test_history
Reline::HISTORY.concat(%w{abc 123 AAA})
input_keys("\C-[")
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys('k')
- assert_line_around_cursor('', 'AAA')
+ assert_line('AAA')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys('2k')
- assert_line_around_cursor('', 'abc')
+ assert_line('abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys('j')
- assert_line_around_cursor('', '123')
+ assert_line('123')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
input_keys('2j')
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_vi_paste_prev
input_keys("abcde\C-[3h")
- assert_line_around_cursor('a', 'bcde')
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
input_keys('P')
- assert_line_around_cursor('a', 'bcde')
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
input_keys('d$')
- assert_line_around_cursor('', 'a')
+ assert_line('a')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
input_keys('P')
- assert_line_around_cursor('bcd', 'ea')
+ assert_line('bcdea')
+ assert_byte_pointer_size('bcd')
+ assert_cursor(3)
+ assert_cursor_max(5)
input_keys('2P')
- assert_line_around_cursor('bcdbcdbcd', 'eeea')
+ assert_line('bcdbcdbcdeeea')
+ assert_byte_pointer_size('bcdbcdbcd')
+ assert_cursor(9)
+ assert_cursor_max(13)
end
def test_vi_paste_next
input_keys("abcde\C-[3h")
- assert_line_around_cursor('a', 'bcde')
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
input_keys('p')
- assert_line_around_cursor('a', 'bcde')
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
input_keys('d$')
- assert_line_around_cursor('', 'a')
+ assert_line('a')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
input_keys('p')
- assert_line_around_cursor('abcd', 'e')
+ assert_line('abcde')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(5)
input_keys('2p')
- assert_line_around_cursor('abcdebcdebcd', 'e')
+ assert_line('abcdebcdebcde')
+ assert_byte_pointer_size('abcdebcdebcd')
+ assert_cursor(12)
+ assert_cursor_max(13)
end
def test_vi_paste_prev_for_mbchar
input_keys("ã‚ã„ã†ãˆãŠ\C-[3h")
- assert_line_around_cursor('ã‚', 'ã„ã†ãˆãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('P')
- assert_line_around_cursor('ã‚', 'ã„ã†ãˆãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('d$')
- assert_line_around_cursor('', 'ã‚')
+ assert_line('ã‚')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
input_keys('P')
- assert_line_around_cursor('ã„ã†ãˆ', 'ãŠã‚')
+ assert_line('ã„ã†ãˆãŠã‚')
+ assert_byte_pointer_size('ã„ã†ãˆ')
+ assert_cursor(6)
+ assert_cursor_max(10)
input_keys('2P')
- assert_line_around_cursor('ã„ã†ãˆã„ã†ãˆã„ã†ãˆ', 'ãŠãŠãŠã‚')
+ assert_line('ã„ã†ãˆã„ã†ãˆã„ã†ãˆãŠãŠãŠã‚')
+ assert_byte_pointer_size('ã„ã†ãˆã„ã†ãˆã„ã†ãˆ')
+ assert_cursor(18)
+ assert_cursor_max(26)
end
def test_vi_paste_next_for_mbchar
input_keys("ã‚ã„ã†ãˆãŠ\C-[3h")
- assert_line_around_cursor('ã‚', 'ã„ã†ãˆãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('p')
- assert_line_around_cursor('ã‚', 'ã„ã†ãˆãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('d$')
- assert_line_around_cursor('', 'ã‚')
+ assert_line('ã‚')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
input_keys('p')
- assert_line_around_cursor('ã‚ã„ã†ãˆ', 'ãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚ã„ã†ãˆ')
+ assert_cursor(8)
+ assert_cursor_max(10)
input_keys('2p')
- assert_line_around_cursor('ã‚ã„ã†ãˆãŠã„ã†ãˆãŠã„ã†ãˆ', 'ãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠã„ã†ãˆãŠã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚ã„ã†ãˆãŠã„ã†ãˆãŠã„ã†ãˆ')
+ assert_cursor(24)
+ assert_cursor_max(26)
end
def test_vi_paste_prev_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099\C-[3h")
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_line("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('P')
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_line("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('d$')
- assert_line_around_cursor('', "ã‹\u3099")
+ assert_line("ã‹\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
input_keys('P')
- assert_line_around_cursor("ã\u3099ã\u3099ã‘\u3099", "ã“\u3099ã‹\u3099")
+ assert_line("ã\u3099ã\u3099ã‘\u3099ã“\u3099ã‹\u3099")
+ assert_byte_pointer_size("ã\u3099ã\u3099ã‘\u3099")
+ assert_cursor(6)
+ assert_cursor_max(10)
input_keys('2P')
- assert_line_around_cursor("ã\u3099ã\u3099ã‘\u3099ã\u3099ã\u3099ã‘\u3099ã\u3099ã\u3099ã‘\u3099", "ã“\u3099ã“\u3099ã“\u3099ã‹\u3099")
+ 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)
end
def test_vi_paste_next_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099\C-[3h")
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_line("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('p')
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_line("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('d$')
- assert_line_around_cursor('', "ã‹\u3099")
+ assert_line("ã‹\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
input_keys('p')
- assert_line_around_cursor("ã‹\u3099ã\u3099ã\u3099ã‘\u3099", "ã“\u3099")
+ assert_line("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099")
+ assert_byte_pointer_size("ã‹\u3099ã\u3099ã\u3099ã‘\u3099")
+ assert_cursor(8)
+ assert_cursor_max(10)
input_keys('2p')
- assert_line_around_cursor("ã‹\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099ã\u3099ã\u3099ã‘\u3099ã“\u3099ã\u3099ã\u3099ã‘\u3099", "ã“\u3099")
+ 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)
end
def test_vi_prev_next_word
input_keys("aaa b{b}b ccc\C-[0")
- assert_line_around_cursor('', 'aaa b{b}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa ', 'b{b}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa b', '{b}b ccc')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(5)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa b{', 'b}b ccc')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(6)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa b{b', '}b ccc')
+ assert_byte_pointer_size('aaa b{b')
+ assert_cursor(7)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa b{b}', 'b ccc')
+ assert_byte_pointer_size('aaa b{b}')
+ assert_cursor(8)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa b{b}b ', 'ccc')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
input_keys('w')
- assert_line_around_cursor('aaa b{b}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('aaa b{b}b ', 'ccc')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('aaa b{b}', 'b ccc')
+ assert_byte_pointer_size('aaa b{b}')
+ assert_cursor(8)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('aaa b{b', '}b ccc')
+ assert_byte_pointer_size('aaa b{b')
+ assert_cursor(7)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('aaa b{', 'b}b ccc')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(6)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('aaa b', '{b}b ccc')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(5)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('aaa ', 'b{b}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
input_keys('b')
- assert_line_around_cursor('', 'aaa b{b}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
input_keys('3w')
- assert_line_around_cursor('aaa b{', 'b}b ccc')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(6)
+ assert_cursor_max(13)
input_keys('3w')
- assert_line_around_cursor('aaa b{b}b ', 'ccc')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
input_keys('3w')
- assert_line_around_cursor('aaa b{b}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
input_keys('3b')
- assert_line_around_cursor('aaa b{b', '}b ccc')
+ assert_byte_pointer_size('aaa b{b')
+ assert_cursor(7)
+ assert_cursor_max(13)
input_keys('3b')
- assert_line_around_cursor('aaa ', 'b{b}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
input_keys('3b')
- assert_line_around_cursor('', 'aaa b{b}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
end
def test_vi_end_word
input_keys("aaa b{b}}}b ccc\C-[0")
- assert_line_around_cursor('', 'aaa b{b}}}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aa', 'a b{b}}}b ccc')
+ assert_byte_pointer_size('aa')
+ assert_cursor(2)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa ', 'b{b}}}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(6)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa b', '{b}}}b ccc')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(7)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa b{', 'b}}}b ccc')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(8)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa b{b}}', '}b ccc')
+ assert_byte_pointer_size('aaa b{b}}')
+ assert_cursor(11)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa b{b}}}', 'b ccc')
+ assert_byte_pointer_size('aaa b{b}}}')
+ assert_cursor(12)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa b{b}}}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
input_keys('e')
- assert_line_around_cursor('aaa b{b}}}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
input_keys('03e')
- assert_line_around_cursor('aaa b', '{b}}}b ccc')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(7)
+ assert_cursor_max(19)
input_keys('3e')
- assert_line_around_cursor('aaa b{b}}}', 'b ccc')
+ assert_byte_pointer_size('aaa b{b}}}')
+ assert_cursor(12)
+ assert_cursor_max(19)
input_keys('3e')
- assert_line_around_cursor('aaa b{b}}}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
end
def test_vi_prev_next_big_word
input_keys("aaa b{b}b ccc\C-[0")
- assert_line_around_cursor('', 'aaa b{b}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
input_keys('W')
- assert_line_around_cursor('aaa ', 'b{b}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
input_keys('W')
- assert_line_around_cursor('aaa b{b}b ', 'ccc')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
input_keys('W')
- assert_line_around_cursor('aaa b{b}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
input_keys('B')
- assert_line_around_cursor('aaa b{b}b ', 'ccc')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
input_keys('B')
- assert_line_around_cursor('aaa ', 'b{b}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
input_keys('B')
- assert_line_around_cursor('', 'aaa b{b}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
input_keys('2W')
- assert_line_around_cursor('aaa b{b}b ', 'ccc')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
input_keys('2W')
- assert_line_around_cursor('aaa b{b}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
input_keys('2B')
- assert_line_around_cursor('aaa ', 'b{b}b ccc')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
input_keys('2B')
- assert_line_around_cursor('', 'aaa b{b}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
end
def test_vi_end_big_word
input_keys("aaa b{b}}}b ccc\C-[0")
- assert_line_around_cursor('', 'aaa b{b}}}b ccc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(19)
input_keys('E')
- assert_line_around_cursor('aa', 'a b{b}}}b ccc')
+ assert_byte_pointer_size('aa')
+ assert_cursor(2)
+ assert_cursor_max(19)
input_keys('E')
- assert_line_around_cursor('aaa b{b}}}', 'b ccc')
+ assert_byte_pointer_size('aaa b{b}}}')
+ assert_cursor(12)
+ assert_cursor_max(19)
input_keys('E')
- assert_line_around_cursor('aaa b{b}}}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
input_keys('E')
- assert_line_around_cursor('aaa b{b}}}b cc', 'c')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
end
def test_ed_quoted_insert
input_keys("ab\C-v\C-acd")
- assert_line_around_cursor("ab\C-acd", '')
+ assert_line("ab\C-acd")
+ assert_byte_pointer_size("ab\C-acd")
+ assert_cursor(6)
+ assert_cursor_max(6)
end
def test_ed_quoted_insert_with_vi_arg
input_keys("ab\C-[3\C-v\C-aacd")
- assert_line_around_cursor("a\C-a\C-a\C-abcd", '')
+ 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)
end
def test_vi_replace_char
input_keys("abcdef\C-[03l")
- assert_line_around_cursor('abc', 'def')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
input_keys('rz')
- assert_line_around_cursor('abc', 'zef')
+ assert_line('abczef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
input_keys('2rx')
- assert_line_around_cursor('abcxx', 'f')
+ assert_line('abcxxf')
+ assert_byte_pointer_size('abcxx')
+ assert_cursor(5)
+ assert_cursor_max(6)
end
def test_vi_replace_char_with_mbchar
input_keys("ã‚ã„ã†ãˆãŠ\C-[0l")
- assert_line_around_cursor('ã‚', 'ã„ã†ãˆãŠ')
+ assert_line('ã‚ã„ã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(10)
input_keys('rx')
- assert_line_around_cursor('ã‚', 'xã†ãˆãŠ')
+ assert_line('ã‚xã†ãˆãŠ')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(9)
input_keys('l2ry')
- assert_line_around_cursor('ã‚xyy', 'ãŠ')
+ assert_line('ã‚xyyãŠ')
+ assert_byte_pointer_size('ã‚xyy')
+ assert_cursor(5)
+ assert_cursor_max(7)
end
def test_vi_next_char
input_keys("abcdef\C-[0")
- assert_line_around_cursor('', 'abcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys('fz')
- assert_line_around_cursor('', 'abcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys('fe')
- assert_line_around_cursor('abcd', 'ef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
end
def test_vi_to_next_char
input_keys("abcdef\C-[0")
- assert_line_around_cursor('', 'abcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys('tz')
- assert_line_around_cursor('', 'abcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys('te')
- assert_line_around_cursor('abc', 'def')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
end
def test_vi_prev_char
input_keys("abcdef\C-[")
- assert_line_around_cursor('abcde', 'f')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(6)
input_keys('Fz')
- assert_line_around_cursor('abcde', 'f')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(6)
input_keys('Fa')
- assert_line_around_cursor('', 'abcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
end
def test_vi_to_prev_char
input_keys("abcdef\C-[")
- assert_line_around_cursor('abcde', 'f')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(6)
input_keys('Tz')
- assert_line_around_cursor('abcde', 'f')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(6)
input_keys('Ta')
- assert_line_around_cursor('a', 'bcdef')
+ assert_line('abcdef')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(6)
end
def test_vi_delete_next_char
input_keys("abc\C-[h")
- assert_line_around_cursor('a', 'bc')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ assert_line('abc')
input_keys('x')
- assert_line_around_cursor('a', 'c')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(2)
+ assert_line('ac')
input_keys('x')
- assert_line_around_cursor('', 'a')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('a')
input_keys('x')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('x')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_vi_delete_next_char_for_mbchar
input_keys("ã‚ã„ã†\C-[h")
- assert_line_around_cursor('ã‚', 'ã„ã†')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(6)
+ assert_line('ã‚ã„ã†')
input_keys('x')
- assert_line_around_cursor('ã‚', 'ã†')
+ assert_byte_pointer_size('ã‚')
+ assert_cursor(2)
+ assert_cursor_max(4)
+ assert_line('ã‚ã†')
input_keys('x')
- assert_line_around_cursor('', 'ã‚')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line('ã‚')
input_keys('x')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('x')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_vi_delete_next_char_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099ã\u3099\C-[h")
- assert_line_around_cursor("ã‹\u3099", "ã\u3099ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
+ assert_line("ã‹\u3099ã\u3099ã\u3099")
input_keys('x')
- assert_line_around_cursor("ã‹\u3099", "ã\u3099")
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(4)
+ assert_line("ã‹\u3099ã\u3099")
input_keys('x')
- assert_line_around_cursor('', "ã‹\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line("ã‹\u3099")
input_keys('x')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('x')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_vi_delete_prev_char
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
input_keys("\C-h")
- assert_line_around_cursor('a', '')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ assert_line('a')
end
def test_vi_delete_prev_char_for_mbchar
input_keys('ã‹ã')
- assert_line_around_cursor('ã‹ã', '')
+ assert_byte_pointer_size('ã‹ã')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-h")
- assert_line_around_cursor('ã‹', '')
+ assert_byte_pointer_size('ã‹')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('ã‹')
end
def test_vi_delete_prev_char_for_mbchar_by_plural_code_points
input_keys("ã‹\u3099ã\u3099")
- assert_line_around_cursor("ã‹\u3099ã\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099ã\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-h")
- assert_line_around_cursor("ã‹\u3099", '')
+ assert_byte_pointer_size("ã‹\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line("ã‹\u3099")
end
def test_ed_delete_prev_char
input_keys("abcdefg\C-[h")
- assert_line_around_cursor('abcde', 'fg')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line('abcdefg')
input_keys('X')
- assert_line_around_cursor('abcd', 'fg')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line('abcdfg')
input_keys('3X')
- assert_line_around_cursor('a', 'fg')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ assert_line('afg')
input_keys('p')
- assert_line_around_cursor('afbc', 'dg')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line('afbcdg')
end
def test_ed_delete_prev_word
input_keys('abc def{bbb}ccc')
- assert_line_around_cursor('abc def{bbb}ccc', '')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
input_keys("\C-w")
- assert_line_around_cursor('abc def{bbb}', '')
+ assert_byte_pointer_size('abc def{bbb}')
+ assert_cursor(12)
+ assert_cursor_max(12)
+ assert_line('abc def{bbb}')
input_keys("\C-w")
- assert_line_around_cursor('abc def{', '')
+ assert_byte_pointer_size('abc def{')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('abc def{')
input_keys("\C-w")
- assert_line_around_cursor('abc ', '')
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('abc ')
input_keys("\C-w")
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_delete_prev_word_for_mbchar
input_keys('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}ãŸã¡ã¤')
+ assert_cursor(27)
+ assert_cursor_max(27)
input_keys("\C-w")
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{ã•ã—ã™}', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{ã•ã—ã™}')
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line('ã‚ã„ㆠã‹ãã{ã•ã—ã™}')
input_keys("\C-w")
- assert_line_around_cursor('ã‚ã„ㆠã‹ãã{', '')
+ assert_byte_pointer_size('ã‚ã„ㆠã‹ãã{')
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line('ã‚ã„ㆠã‹ãã{')
input_keys("\C-w")
- assert_line_around_cursor('ã‚ã„ㆠ', '')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('ã‚ã„ㆠ')
input_keys("\C-w")
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
input_keys("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤", '')
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}ãŸã¡ã¤")
+ assert_cursor(27)
+ assert_cursor_max(27)
input_keys("\C-w")
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}", '')
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}")
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{ã•ã—ã™}")
input_keys("\C-w")
- assert_line_around_cursor("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{", '')
+ assert_byte_pointer_size("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{")
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line("ã‚ã„ㆠã‹\u3099ã\u3099ã\u3099{")
input_keys("\C-w")
- assert_line_around_cursor('ã‚ã„ㆠ', '')
+ assert_byte_pointer_size('ã‚ã„ㆠ')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('ã‚ã„ㆠ')
input_keys("\C-w")
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_newline_with_cr
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
refute(@line_editor.finished?)
input_keys("\C-m")
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
assert(@line_editor.finished?)
end
def test_ed_newline_with_lf
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
refute(@line_editor.finished?)
input_keys("\C-j")
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
assert(@line_editor.finished?)
end
def test_vi_list_or_eof
input_keys("\C-d") # quit from inputing
- assert_nil(@line_editor.line)
+ assert_line(nil)
assert(@line_editor.finished?)
end
def test_vi_list_or_eof_with_non_empty_line
input_keys('ab')
- assert_line_around_cursor('ab', '')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
refute(@line_editor.finished?)
input_keys("\C-d")
- assert_line_around_cursor('ab', '')
+ assert_line('ab')
assert(@line_editor.finished?)
end
@@ -545,19 +982,40 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
input_keys("\C-n")
- assert_line_around_cursor('foo_bar', '')
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
input_keys("\C-n")
- assert_line_around_cursor('foo_bar_baz', '')
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
input_keys("\C-n")
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
input_keys("\C-n")
- assert_line_around_cursor('foo_bar', '')
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
input_keys("_\C-n")
- assert_line_around_cursor('foo_bar_baz', '')
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
input_keys("\C-n")
- assert_line_around_cursor('foo_bar_', '')
+ assert_byte_pointer_size('foo_bar_')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('foo_bar_')
end
def test_completion_journey_reverse
@@ -570,19 +1028,40 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
input_keys("\C-p")
- assert_line_around_cursor('foo_bar_baz', '')
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
input_keys("\C-p")
- assert_line_around_cursor('foo_bar', '')
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
input_keys("\C-p")
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
input_keys("\C-p")
- assert_line_around_cursor('foo_bar_baz', '')
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
input_keys("\C-h\C-p")
- assert_line_around_cursor('foo_bar_baz', '')
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
input_keys("\C-p")
- assert_line_around_cursor('foo_bar_ba', '')
+ assert_byte_pointer_size('foo_bar_ba')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('foo_bar_ba')
end
def test_completion_journey_in_middle_of_line
@@ -595,21 +1074,42 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('abcde fo ABCDE')
- assert_line_around_cursor('abcde fo ABCDE', '')
+ assert_line('abcde fo ABCDE')
input_keys("\C-[" + 'h' * 5 + "i\C-n")
- assert_line_around_cursor('abcde foo_bar', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_bar')
+ assert_cursor(13)
+ assert_cursor_max(19)
+ assert_line('abcde foo_bar ABCDE')
input_keys("\C-n")
- assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_bar_baz')
+ assert_cursor(17)
+ assert_cursor_max(23)
+ assert_line('abcde foo_bar_baz ABCDE')
input_keys("\C-n")
- assert_line_around_cursor('abcde fo', ' ABCDE')
+ assert_byte_pointer_size('abcde fo')
+ assert_cursor(8)
+ assert_cursor_max(14)
+ assert_line('abcde fo ABCDE')
input_keys("\C-n")
- assert_line_around_cursor('abcde foo_bar', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_bar')
+ assert_cursor(13)
+ assert_cursor_max(19)
+ assert_line('abcde foo_bar ABCDE')
input_keys("_\C-n")
- assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_bar_baz')
+ assert_cursor(17)
+ assert_cursor_max(23)
+ assert_line('abcde foo_bar_baz ABCDE')
input_keys("\C-n")
- assert_line_around_cursor('abcde foo_bar_', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_bar_')
+ assert_cursor(14)
+ assert_cursor_max(20)
+ assert_line('abcde foo_bar_ ABCDE')
input_keys("\C-n")
- assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE')
+ assert_byte_pointer_size('abcde foo_bar_baz')
+ assert_cursor(17)
+ assert_cursor_max(23)
+ assert_line('abcde foo_bar_baz ABCDE')
end
def test_completion
@@ -622,55 +1122,15 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
input_keys("\C-i")
- 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
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
end
def test_completion_with_disable_completion
@@ -684,224 +1144,315 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
input_keys("\C-i")
- assert_line_around_cursor('foo', '')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
end
def test_vi_first_print
input_keys("abcde\C-[^")
- assert_line_around_cursor('', 'abcde')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
input_keys("0\C-ki")
input_keys(" abcde\C-[^")
- assert_line_around_cursor(' ', 'abcde')
+ assert_byte_pointer_size(' ')
+ assert_cursor(1)
+ assert_cursor_max(6)
input_keys("0\C-ki")
input_keys(" abcde ABCDE \C-[^")
- assert_line_around_cursor(' ', 'abcde ABCDE ')
+ assert_byte_pointer_size(' ')
+ assert_cursor(3)
+ assert_cursor_max(17)
end
def test_ed_move_to_beg
input_keys("abcde\C-[0")
- assert_line_around_cursor('', 'abcde')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
input_keys("0\C-ki")
input_keys(" abcde\C-[0")
- assert_line_around_cursor('', ' abcde')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
input_keys("0\C-ki")
input_keys(" abcde ABCDE \C-[0")
- 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一二', '三')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(17)
end
def test_vi_delete_meta
input_keys("aaa bbb ccc ddd eee\C-[02w")
- assert_line_around_cursor('aaa bbb ', 'ccc ddd eee')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(19)
+ assert_line('aaa bbb ccc ddd eee')
input_keys('dw')
- assert_line_around_cursor('aaa bbb ', 'ddd eee')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ddd eee')
input_keys('db')
- assert_line_around_cursor('aaa ', 'ddd eee')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(11)
+ assert_line('aaa ddd eee')
end
def test_vi_delete_meta_with_vi_next_word_at_eol
input_keys("foo bar\C-[0w")
- assert_line_around_cursor('foo ', 'bar')
+ assert_byte_pointer_size('foo ')
+ assert_cursor(4)
+ assert_cursor_max(7)
+ assert_line('foo bar')
input_keys('w')
- assert_line_around_cursor('foo ba', 'r')
+ assert_byte_pointer_size('foo ba')
+ assert_cursor(6)
+ assert_cursor_max(7)
+ assert_line('foo bar')
input_keys('0dw')
- assert_line_around_cursor('', 'bar')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ assert_line('bar')
input_keys('dw')
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
end
def test_vi_delete_meta_with_vi_next_char
input_keys("aaa bbb ccc ___ ddd\C-[02w")
- assert_line_around_cursor('aaa bbb ', 'ccc ___ ddd')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(19)
+ assert_line('aaa bbb ccc ___ ddd')
input_keys('df_')
- assert_line_around_cursor('aaa bbb ', '__ ddd')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(14)
+ assert_line('aaa bbb __ ddd')
end
def test_vi_delete_meta_with_arg
- input_keys("aaa bbb ccc ddd\C-[03w")
- assert_line_around_cursor('aaa bbb ccc ', 'ddd')
+ 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('2dl')
- 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('', '')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(9)
+ assert_line('aaa bbb c')
end
def test_vi_change_meta
input_keys("aaa bbb ccc ddd eee\C-[02w")
- assert_line_around_cursor('aaa bbb ', 'ccc ddd eee')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(19)
+ assert_line('aaa bbb ccc ddd eee')
input_keys('cwaiueo')
- assert_line_around_cursor('aaa bbb aiueo', ' ddd eee')
+ assert_byte_pointer_size('aaa bbb aiueo')
+ assert_cursor(13)
+ assert_cursor_max(21)
+ assert_line('aaa bbb aiueo ddd eee')
input_keys("\C-[")
- assert_line_around_cursor('aaa bbb aiue', 'o ddd eee')
+ assert_byte_pointer_size('aaa bbb aiue')
+ assert_cursor(12)
+ assert_cursor_max(21)
+ assert_line('aaa bbb aiueo ddd eee')
input_keys('cb')
- assert_line_around_cursor('aaa bbb ', 'o ddd eee')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(17)
+ assert_line('aaa bbb o ddd eee')
end
def test_vi_change_meta_with_vi_next_word
input_keys("foo bar baz\C-[0w")
- assert_line_around_cursor('foo ', 'bar baz')
+ assert_byte_pointer_size('foo ')
+ assert_cursor(5)
+ assert_cursor_max(13)
+ assert_line('foo bar baz')
input_keys('cwhoge')
- assert_line_around_cursor('foo hoge', ' baz')
+ assert_byte_pointer_size('foo hoge')
+ assert_cursor(9)
+ assert_cursor_max(14)
+ assert_line('foo hoge baz')
input_keys("\C-[")
- 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')
+ assert_byte_pointer_size('foo hog')
+ assert_cursor(8)
+ assert_cursor_max(14)
+ assert_line('foo hoge baz')
end
def test_unimplemented_vi_command_should_be_no_op
input_keys("abc\C-[h")
- assert_line_around_cursor('a', 'bc')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ assert_line('abc')
input_keys('@')
- assert_line_around_cursor('a', 'bc')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ assert_line('abc')
end
def test_vi_yank
- input_keys("foo bar\C-[2h")
- assert_line_around_cursor('foo ', 'bar')
+ input_keys("foo bar\C-[0")
+ assert_line('foo bar')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
input_keys('y3l')
- assert_line_around_cursor('foo ', 'bar')
+ assert_line('foo bar')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
input_keys('P')
- 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')
+ assert_line('foofoo bar')
+ assert_byte_pointer_size('fo')
+ assert_cursor(2)
+ assert_cursor_max(10)
end
def test_vi_end_word_with_operator
input_keys("foo bar\C-[0")
- assert_line_around_cursor('', 'foo bar')
+ assert_line('foo bar')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
input_keys('de')
- assert_line_around_cursor('', ' bar')
+ assert_line(' bar')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
input_keys('de')
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys('de')
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_vi_end_big_word_with_operator
input_keys("aaa b{b}}}b\C-[0")
- assert_line_around_cursor('', 'aaa b{b}}}b')
+ assert_line('aaa b{b}}}b')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
input_keys('dE')
- assert_line_around_cursor('', ' b{b}}}b')
+ assert_line(' b{b}}}b')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(10)
input_keys('dE')
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
input_keys('dE')
- assert_line_around_cursor('', '')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
end
def test_vi_next_char_with_operator
input_keys("foo bar\C-[0")
- assert_line_around_cursor('', 'foo bar')
+ assert_line('foo bar')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
input_keys('df ')
- assert_line_around_cursor('', 'bar')
+ 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)
end
def test_ed_delete_next_char_at_eol
input_keys('"ã‚"')
- assert_line_around_cursor('"ã‚"', '')
+ assert_line('"ã‚"')
+ assert_byte_pointer_size('"ã‚"')
+ assert_cursor(4)
+ assert_cursor_max(4)
input_keys("\C-[")
- assert_line_around_cursor('"ã‚', '"')
+ assert_line('"ã‚"')
+ assert_byte_pointer_size('"ã‚')
+ assert_cursor(3)
+ assert_cursor_max(4)
input_keys('xa"')
- assert_line_around_cursor('"ã‚"', '')
+ assert_line('"ã‚"')
+ assert_byte_pointer_size('"ã‚"')
+ assert_cursor(4)
+ assert_cursor_max(4)
end
def test_vi_kill_line_prev
input_keys("\C-u", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
- assert_line_around_cursor('abc', '')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
input_keys("\C-u", false)
- assert_line_around_cursor('', '')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
input_keys('abc')
input_keys("\C-[\C-u", false)
- assert_line_around_cursor('', 'c')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
input_keys("\C-u", false)
- 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)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
end
def test_vi_motion_operators
@@ -911,9 +1462,4 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
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 cd205c7d9e..d377a1e972 100644
--- a/test/reline/test_key_stroke.rb
+++ b/test/reline/test_key_stroke.rb
@@ -36,27 +36,6 @@ 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
{
@@ -66,11 +45,6 @@ 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
deleted file mode 100644
index 7a38ecd596..0000000000
--- a/test/reline/test_line_editor.rb
+++ /dev/null
@@ -1,185 +0,0 @@
-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_multibyte
- base = [0, 12, '一二三一二三']
- left = [0, 3, 'LLL']
- right = [9, 3, 'RRR']
- front = [3, 6, 'FFFFFF']
- # 一 FFFFFF 三
- # 一二三一二三
- assert_output '[COL_2]二三一二' do
- @line_editor.render_line_differential([base, front], [base, nil])
- end
-
- # LLLFFFFFF 三
- # LLL 三一二三
- assert_output '[COL_3] 三一二' do
- @line_editor.render_line_differential([base, left, front], [base, left, nil])
- end
-
- # 一 FFFFFFRRR
- # 一二三一 RRR
- assert_output '[COL_2]二三一 ' do
- @line_editor.render_line_differential([base, right, front], [base, right, nil])
- end
-
- # LLLFFFFFFRRR
- # LLL 三一 RRR
- assert_output '[COL_3] 三一 ' do
- @line_editor.render_line_differential([base, left, right, front], [base, left, right, nil])
- end
- end
-
- def test_complicated
- state_a = [nil, [19, 7, 'bbbbbbb'], [15, 8, 'cccccccc'], [10, 5, 'ddddd'], [18, 4, 'eeee'], [1, 3, 'fff'], [17, 2, 'gg'], [7, 1, 'h']]
- state_b = [[5, 9, 'aaaaaaaaa'], nil, [15, 8, 'cccccccc'], nil, [18, 4, 'EEEE'], [25, 4, 'ffff'], [17, 2, 'gg'], [2, 2, 'hh']]
- # 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 04aa6474b4..76a677c834 100644
--- a/test/reline/test_macro.rb
+++ b/test/reline/test_macro.rb
@@ -4,8 +4,9 @@ class Reline::MacroTest < Reline::TestCase
def setup
Reline.send(:test_mode)
@config = Reline::Config.new
- @encoding = Reline.core.encoding
+ @encoding = Reline::IOGate.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 a20a5c9f44..e58accb3a7 100644
--- a/test/reline/test_reline.rb
+++ b/test/reline/test_reline.rb
@@ -8,7 +8,6 @@ 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
@@ -285,7 +284,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.core.io_gate}"
+ omit "Setting to input is not effective on #{Reline::IOGate}"
end
Reline.output = output
@@ -303,12 +302,12 @@ class Reline::Test < Reline::TestCase
def test_vi_editing_mode
Reline.vi_editing_mode
- assert_equal(Reline::KeyActor::ViInsert, Reline.core.config.editing_mode.class)
+ assert_equal(Reline::KeyActor::ViInsert, Reline.send(:core).config.editing_mode.class)
end
def test_emacs_editing_mode
Reline.emacs_editing_mode
- assert_equal(Reline::KeyActor::Emacs, Reline.core.config.editing_mode.class)
+ assert_equal(Reline::KeyActor::Emacs, Reline.send(:core).config.editing_mode.class)
end
def test_add_dialog_proc
@@ -322,9 +321,6 @@ 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)
@@ -374,32 +370,14 @@ class Reline::Test < Reline::TestCase
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)
+ out = IO.popen([{"TERM"=>"dumb"}, "ruby", "-I#{lib}", "-rreline", "-e", "p Reline::IOGate"], &:read)
assert_equal("Reline::GeneralIO", out.chomp)
end
- def test_require_reline_should_not_trigger_winsize
- pend if win?
- lib = File.expand_path("../../lib", __dir__)
- code = <<~RUBY
- require "io/console"
- def STDIN.tty?; true; end
- def STDOUT.tty?; true; end
- def STDIN.winsize; raise; end
- require("reline") && p(Reline.core.io_gate)
- RUBY
- out = IO.popen([{}, Reline.test_rubybin, "-I#{lib}", "-e", code], &:read)
- assert_equal("Reline::ANSI", out.chomp)
- end
-
- def win?
- /mswin|mingw/.match?(RUBY_PLATFORM)
- end
-
def get_reline_encoding
- if encoding = Reline.core.encoding
+ if encoding = Reline::IOGate.encoding
encoding
- elsif win?
+ elsif RUBY_PLATFORM =~ /mswin|mingw/
Encoding::UTF_8
else
Encoding::default_external
diff --git a/test/reline/test_reline_key.rb b/test/reline/test_reline_key.rb
index 7f9a11394a..fb700a6f2e 100644
--- a/test/reline/test_reline_key.rb
+++ b/test/reline/test_reline_key.rb
@@ -3,7 +3,6 @@ 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 c9b9e38643..5db97545da 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.core.encoding
+ @encoding = Reline::IOGate.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
@line_editor.reset(@prompt, encoding: @encoding)
end
@@ -30,7 +30,10 @@ 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)
@@ -39,7 +42,10 @@ 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)
@@ -48,7 +54,10 @@ 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)
@@ -57,7 +66,10 @@ 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 4e59c54838..dda9b32495 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? && Reline::Terminfo.term_supported?
+end if Reline::Terminfo.enabled?
diff --git a/test/reline/test_unicode.rb b/test/reline/test_unicode.rb
index deba4d4681..1233e034e8 100644
--- a/test/reline/test_unicode.rb
+++ b/test/reline/test_unicode.rb
@@ -18,75 +18,8 @@ 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_split_by_width_csi_reset_sgr_optimization
- assert_equal [["\e[1ma\e[mb\e[2mc", nil, "\e[2md\e[0me\e[3mf", nil, "\e[3mg"], 3], Reline::Unicode.split_by_width("\e[1ma\e[mb\e[2mcd\e[0me\e[3mfg", 3)
- assert_equal [["\e[1ma\1\e[mzero\e[0m\2\e[2mb", nil, "\e[1m\e[2mc"], 2], Reline::Unicode.split_by_width("\e[1ma\1\e[mzero\e[0m\2\e[2mbc", 2)
- 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 "\1zero\2cdef", Reline::Unicode.take_range("ab\1zero\2cdef", 2, 4)
- assert_equal "b\1zero\2cde", Reline::Unicode.take_range("ab\1zero\2cdef", 1, 4)
- assert_equal "\e[31mcd\e[42mef", Reline::Unicode.take_range("\e[31mabcd\e[42mefg", 2, 4)
- assert_equal "\e]0;1\acd", Reline::Unicode.take_range("ab\e]0;1\acd", 2, 3)
assert_equal 'ã„ã†', Reline::Unicode.take_range('ã‚ã„ã†ãˆãŠ', 2, 4)
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
-
- def test_take_mbchar_range
- assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4)
- assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, padding: true)
- assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_begin: true)
- assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_end: true)
- assert_equal ['ã„ã†', 2, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 2, 4)
- assert_equal ['ã„ã†', 2, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 2, 4, padding: true)
- assert_equal ['ã„ã†', 2, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 2, 4, cover_begin: true)
- assert_equal ['ã„ã†', 2, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 2, 4, cover_end: true)
- assert_equal ['ã†', 4, 2], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 4)
- assert_equal [' ㆠ', 3, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 4, padding: true)
- assert_equal ['ã„ã†', 2, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 4, cover_begin: true)
- assert_equal ['ã†ãˆ', 4, 4], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 4, cover_end: true)
- assert_equal ['ã„ㆠ', 2, 5], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 4, cover_begin: true, padding: true)
- assert_equal [' ã†ãˆ', 3, 5], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 4, cover_end: true, padding: true)
- assert_equal [' ã†ãˆãŠ ', 3, 10], Reline::Unicode.take_mbchar_range('ã‚ã„ã†ãˆãŠ', 3, 10, padding: true)
- assert_equal [" \e[41mã†ãˆãŠ\e[0m ", 3, 10], Reline::Unicode.take_mbchar_range("ã‚ã„\e[41mã†ãˆãŠ", 3, 10, padding: true)
- assert_equal ["\e[41m \e[42mã„\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mã‚\e[42mã„\e[43mã†", 1, 4, padding: true)
- assert_equal ["\e[31mc\1ABC\2d\e[0mef", 2, 4], Reline::Unicode.take_mbchar_range("\e[31mabc\1ABC\2d\e[0mefghi", 2, 4)
- assert_equal ["\e[41m \e[42mã„\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mã‚\e[42mã„\e[43mã†", 1, 4, padding: true)
- end
end
diff --git a/test/reline/test_within_pipe.rb b/test/reline/test_within_pipe.rb
index 4f05255301..43a66f45f4 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.core.encoding
+ @encoding = Reline::IOGate.encoding
@input_reader, @writer = IO.pipe(@encoding)
Reline.input = @input_reader
@reader, @output_writer = IO.pipe(@encoding)
@output = Reline.output = @output_writer
- @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
+ @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
end
def teardown
@@ -23,6 +23,7 @@ class Reline::WithinPipeTest < Reline::TestCase
@reader.close
@output_writer.close
@config.reset
+ @config.reset_default_key_bindings
Reline.test_reset
end
diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl
index 8b82be60f4..d27d216652 100755
--- a/test/reline/yamatanooroti/multiline_repl
+++ b/test/reline/yamatanooroti/multiline_repl
@@ -9,10 +9,14 @@ 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|
- "\e[1m[%04d]>\e[m " % i
+ '[%04d]> ' % i
}
}
}
@@ -35,46 +39,8 @@ 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') {
- 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
+ AutoIndent.new
}
opt.on('--dialog VAL') { |v|
Reline.add_dialog_proc(:simple_dialog, lambda {
@@ -132,7 +98,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, face: :completion_dialog)
+ Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents, height: height, scrollbar: scrollbar)
})
if v.include?('alt-scrollbar')
ENV['RELINE_ALT_SCROLLBAR'] = '1'
@@ -143,21 +109,12 @@ opt.on('--complete') {
%w{String ScriptError SyntaxError Signal}.select{ |c| c.start_with?(target) }
}
}
-opt.on('--complete-menu-with-perfect-match') {
- Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil|
- %w{abs abs2}.select{ |c| c.start_with?(target) }
- }
-}
opt.on('--autocomplete') {
Reline.autocompletion = true
Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil|
%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|
@@ -188,7 +145,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) }
}
}
@@ -222,9 +179,10 @@ rescue
end
begin
- prompt = ENV['RELINE_TEST_PROMPT'] || "\e[1mprompt>\e[m "
+ prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> '
puts 'Multiline REPL.'
- while code = Reline.readmultiline(prompt, true) { |code| TerminationChecker.terminated?(code) }
+ checker = TerminationChecker.new
+ while code = Reline.readmultiline(prompt, true) { |code| checker.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 b97c798c59..256f1bb2a2 100644
--- a/test/reline/yamatanooroti/termination_checker.rb
+++ b/test/reline/yamatanooroti/termination_checker.rb
@@ -1,26 +1,30 @@
require 'ripper'
+require 'irb/ruby-lex'
-module TerminationChecker
- def self.terminated?(code)
- Ripper.sexp(code) ? true : false
+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
end
end
-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
+class AutoIndent < RubyLex
+ def initialize
+ context = Struct.new("MockIRBContext", :auto_indent_mode, :workspace, :local_variables).new(true, nil, [])
+ set_input(self, context: context)
+ set_auto_indent(context)
end
- def self.nesting_level(lines)
- code = lines.join("\n")
- code.scan(/if|def|\(|\[|\{/).size - code.scan(/end|\)|\]|\}/).size
+ def auto_indent(&block)
+ Reline.auto_indent_proc = block
end
end
diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb
index 37a1c1a193..c383112131 100644
--- a/test/reline/yamatanooroti/test_rendering.rb
+++ b/test/reline/yamatanooroti/test_rendering.rb
@@ -3,34 +3,7 @@ require 'reline'
begin
require 'yamatanooroti'
- 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
-
+ class Reline::TestRendering < Yamatanooroti::TestCase
def setup
@pwd = Dir.pwd
suffix = '%010d' % Random.rand(0..65535)
@@ -197,12 +170,9 @@ 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)
- (ins)prompt> :a
- => :a
+ Multiline REPL.
(ins)prompt> :a
=> :a
(cmd)prompt> :a
@@ -267,21 +237,6 @@ 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.')
@@ -309,21 +264,6 @@ begin
EOC
end
- def test_readline_with_multiline_input
- start_terminal(5, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt}, startup_message: 'Multiline REPL.')
- write("def foo\n bar\nend\n")
- write("Reline.readline('prompt> ')\n")
- write("\C-p\C-p")
- close
- assert_screen(<<~EOC)
- => :foo
- [0000]> Reline.readline('prompt> ')
- prompt> def foo
- bar
- end
- EOC
- end
-
def test_multiline_and_autowrap
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def aaaaaaaaaa\n 33333333\n end\C-a\C-pputs\C-e\e\C-m888888888888888")
@@ -341,23 +281,6 @@ 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")
@@ -482,9 +405,6 @@ 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
@@ -496,9 +416,6 @@ 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
@@ -519,34 +436,39 @@ begin
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.')
+ 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.')
write("def hoge\n 3\nend")
close
assert_screen(<<~EOC)
Multiline REPL.
[0000]> def hoge
[0001]> 3
- [0001]> end
+ [0002]> end
EOC
end
- 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")
+ 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]> %[ S
- [0001]>
+ [0000]> def hoge
+ [0001]> 3
+ [0001]> end
EOC
end
- def test_bracketed_paste
- omit if Reline.core.io_gate.win?
+ def test_enable_bracketed_paste
+ omit if Reline::IOGate.win?
+ write_inputrc <<~LINES
+ set enable-bracketed-paste on
+ LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
- write("\e[200~def hoge\r\t3\rend\e[201~")
+ write("\e[200~,")
+ write("def hoge\n 3\nend")
+ write("\e[200~.")
close
assert_screen(<<~EOC)
Multiline REPL.
@@ -556,19 +478,6 @@ begin
EOC
end
- def test_bracketed_paste_with_undo
- omit if Reline.core.io_gate.win?
- start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
- write("abc")
- write("\e[200~def hoge\r\t3\rend\e[201~")
- write("\C-_")
- close
- assert_screen(<<~EOC)
- Multiline REPL.
- prompt> abc
- EOC
- end
-
def test_backspace_until_returns_to_initial
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("ABC")
@@ -723,31 +632,6 @@ 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")
@@ -765,66 +649,6 @@ 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")
@@ -854,20 +678,6 @@ 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")
@@ -953,30 +763,18 @@ begin
EOC
end
- def test_eof_with_newline
- omit if Reline.core.io_gate.win?
+ def test_with_newline
+ omit if Reline::IOGate.win?
cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'}
start_terminal(40, 50, ['bash', '-c', cmd])
sleep 1
- close rescue nil
+ close
assert_screen(<<~'EOC')
> abc def
"abc def "
EOC
end
- def test_eof_without_newline
- omit if Reline.core.io_gate.win?
- cmd = %Q{ruby -e 'print(%{hello})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'}
- start_terminal(40, 50, ['bash', '-c', cmd])
- sleep 1
- close rescue nil
- assert_screen(<<~'EOC')
- > hello
- "hello"
- EOC
- end
-
def test_em_set_mark_and_em_exchange_mark
start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("aaa bbb ccc ddd\M-b\M-b\M-\x20\M-b\C-x\C-xX\C-x\C-xY")
@@ -987,18 +785,6 @@ 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
@@ -1026,127 +812,44 @@ begin
EOC
end
- def test_completion_menu_is_displayed_horizontally
- start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.')
- write("S\t\t")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> S
- ScriptError String
- Signal SyntaxError
- EOC
- end
-
- def test_show_all_if_ambiguous_on
- write_inputrc <<~LINES
- set show-all-if-ambiguous on
- LINES
- start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.')
- write("S\t")
+ 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> S
- ScriptError String
- Signal SyntaxError
+ 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
- def test_show_all_if_ambiguous_on_and_menu_with_perfect_match
- write_inputrc <<~LINES
- set show-all-if-ambiguous on
- LINES
- start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete-menu-with-perfect-match}, startup_message: 'Multiline REPL.')
- write("a\t")
+ 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> abs
- abs abs2
+ 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
- def test_simple_dialog
- 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
- 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
start_terminal(15, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
write('def hoge' + "\C-m" * 10 + "end\C-p ")
@@ -1193,53 +896,11 @@ begin
assert_screen(<<~'EOC')
Multiline REPL.
prompt> St
- r
- String
- Struct
- EOC
- end
-
- def test_autocomplete_target_at_end_of_line
- start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
- write(' ')
- write('Str')
- write("\C-i")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> Str
- ing String
+ r String
Struct
EOC
end
- def test_autocomplete_completed_input_is_wrapped
- start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
- write(' ')
- write('Str')
- write("\C-i")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> Stri
- ng String
- Struct
- EOC
- end
-
- 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')
@@ -1342,32 +1003,6 @@ 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")
@@ -1396,23 +1031,6 @@ 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')
@@ -1463,32 +1081,6 @@ 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]
@@ -1498,15 +1090,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
@@ -1550,7 +1142,7 @@ begin
Multiline R
EPL.
prompt> Sym
- String â–ˆ
+ String
Struct â–ˆ
Symbol â–ˆ
StopIteratâ–ˆ
@@ -1609,21 +1201,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\n\n\n\n\n")
- write("def hoge\n\nend\C-p\C-e")
+ 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(" S")
close
assert_screen(<<~'EOC')
+ prompt> def hoge
prompt>
prompt>
prompt>
- prompt>
- prompt>
- prompt> def hoge
prompt> S
- prompt> enString â–ˆ
- Struct â–€
- Symbol
+ prompt> String
+ prompt> Struct
+ prompt> enSymbol
+ ScriptError
+ Signal
EOC
end
@@ -1663,49 +1255,32 @@ 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\n\n")
- write("\C-p\C-p\C-e; S")
+ write("class A\n 3\nend\n")
+ write("\C-p\C-p\C-p\C-e\C-hS")
write("\C-n")
- write(";")
+ write("1")
close
assert_screen(<<~'EOC')
prompt> 3
prompt> end
=> 3
- prompt>
- prompt>
- prompt> class A
- prompt> 3; S
- prompt> end;
+ prompt> class S
+ prompt> 31
+ 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 3\n end\nend")
+ write("class A\n def a\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
@@ -1723,7 +1298,6 @@ begin
write(" 3")
close
assert_screen(<<~'EOC')
- prompt> 3
prompt> end
prompt> end
=> :a
@@ -1759,59 +1333,6 @@ 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 20c3408cd6..93a7042fa9 100644
--- a/test/resolv/test_dns.rb
+++ b/test/resolv/test_dns.rb
@@ -44,16 +44,6 @@ 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
@@ -167,168 +157,6 @@ 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('127.0.0.1', 0) {|u|
- _, server_port, _, server_address = u.addr
- with_tcp('127.0.0.1', server_port) {|t|
- 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
@@ -546,8 +374,7 @@ 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: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"],
+ ["2001:db8::1:1:1:1:1", "2001:db8:0:1: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"],
]
@@ -589,6 +416,13 @@ class TestResolvDNS < Test::Unit::TestCase
assert_operator(2**14, :<, m.to_s.length)
end
+ def test_too_long_address
+ too_long_address_message = [0, 0, 1, 0, 0, 0].pack("n*") + "\x01x" * 129 + [0, 0, 0].pack("cnn")
+ assert_raise_with_message(Resolv::DNS::DecodeError, /name label data exceed 255 octets/) do
+ Resolv::DNS::Message.decode too_long_address_message
+ end
+ end
+
def assert_no_fd_leak
socket = assert_throw(self) do |tag|
Resolv::DNS.stub(:bind_random_port, ->(s, *) {throw(tag, s)}) do
@@ -630,30 +464,4 @@ 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 b688155dc2..b75cf67f31 100644
--- a/test/resolv/test_resource.rb
+++ b/test/resolv/test_resource.rb
@@ -23,12 +23,4 @@ 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
diff --git a/test/resolv/test_svcb_https.rb b/test/resolv/test_svcb_https.rb
deleted file mode 100644
index 5dc3163d9e..0000000000
--- a/test/resolv/test_svcb_https.rb
+++ /dev/null
@@ -1,231 +0,0 @@
-# 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
index 00404e39df..74d8d363b4 100644
--- a/test/rinda/test_rinda.rb
+++ b/test/rinda/test_rinda.rb
@@ -402,7 +402,7 @@ module TupleSpaceTestModule
end
def test_cancel_02
- omit 'this test is unstable with --jit-wait' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ 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
@@ -686,7 +686,7 @@ class TestRingServer < Test::Unit::TestCase
end
def test_do_reply_local
- omit 'timeout-based test becomes unstable with --jit-wait' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ omit 'timeout-based test becomes unstable with --jit-wait' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
with_timeout(30) {_test_do_reply_local}
end
diff --git a/test/ripper/assert_parse_files.rb b/test/ripper/assert_parse_files.rb
index 0d583a99e3..85d20cf69e 100644
--- a/test/ripper/assert_parse_files.rb
+++ b/test/ripper/assert_parse_files.rb
@@ -5,39 +5,26 @@ module TestRipper; end
class TestRipper::Generic < Test::Unit::TestCase
SRCDIR = File.expand_path("../../..", __FILE__)
- 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}],
+ def assert_parse_files(dir, pattern = "**/*.rb")
+ assert_separately(%W[--disable-gem -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.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 = Dir.chdir(dir) {Dir[pattern]}
+ 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)
- EnvUtil.under_gc_stress(gc_stress) do
- parser.instance_eval "parse", "<#{script}>"
- end
+ parser.instance_eval "parse", "<#{script}>"
}
end
end;
diff --git a/test/ripper/dummyparser.rb b/test/ripper/dummyparser.rb
index ef5ea49b1f..fa834bd0f7 100644
--- a/test/ripper/dummyparser.rb
+++ b/test/ripper/dummyparser.rb
@@ -4,9 +4,8 @@
#
require 'ripper'
-module TestRipper; end
-class TestRipper::Node
+class Node
def initialize(name, *nodes)
@name = name
@children = nodes
@@ -15,7 +14,7 @@ class TestRipper::Node
attr_reader :name, :children
def to_s
- "#{@name}(#{TestRipper::Node.trim_nil(@children).map {|n| n.to_s }.join(',')})"
+ "#{@name}(#{Node.trim_nil(@children).map {|n| n.to_s }.join(',')})"
end
def self.trim_nil(list)
@@ -37,7 +36,7 @@ class TestRipper::Node
end
end
-class TestRipper::NodeList
+class NodeList
def initialize(list = [])
@list = list
end
@@ -63,7 +62,7 @@ class TestRipper::NodeList
end
end
-class TestRipper::DummyParser < Ripper
+class DummyParser < Ripper
def hook(*names)
class << self; self; end.class_eval do
names.each do |name|
@@ -82,7 +81,7 @@ class TestRipper::DummyParser < Ripper
end
def on_stmts_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_stmts_add(stmts, st)
@@ -91,23 +90,23 @@ class TestRipper::DummyParser < Ripper
end
def on_void_stmt
- TestRipper::Node.new('void')
+ Node.new('void')
end
def on_var_ref(name)
- TestRipper::Node.new('ref', name)
+ Node.new('ref', name)
end
def on_var_alias(a, b)
- TestRipper::Node.new('valias', a, b)
+ Node.new('valias', a, b)
end
def on_assign_error(mesg = nil, a)
- TestRipper::Node.new('assign_error', a)
+ Node.new('assign_error', a)
end
def on_alias_error(mesg = nil, a)
- TestRipper::Node.new('aliaserr', a)
+ Node.new('aliaserr', a)
end
def on_arg_paren(args)
@@ -115,7 +114,7 @@ class TestRipper::DummyParser < Ripper
end
def on_args_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_args_add(list, arg)
@@ -157,7 +156,7 @@ class TestRipper::DummyParser < Ripper
end
def on_brace_block(params, code)
- TestRipper::Node.new('block', params, code)
+ Node.new('block', params, code)
end
def on_block_var(params, shadow)
@@ -177,7 +176,7 @@ class TestRipper::DummyParser < Ripper
end
def on_params(required, optional, rest, more, keyword, keyword_rest, block)
- args = TestRipper::NodeList.new
+ args = NodeList.new
required.each do |req|
args.push(req)
@@ -198,15 +197,15 @@ class TestRipper::DummyParser < Ripper
end
def on_assoc_new(a, b)
- TestRipper::Node.new('assoc', a, b)
+ Node.new('assoc', a, b)
end
def on_bare_assoc_hash(assoc_list)
- TestRipper::Node.new('assocs', *assoc_list)
+ Node.new('assocs', *assoc_list)
end
def on_assoclist_from_args(a)
- TestRipper::Node.new('assocs', *a)
+ Node.new('assocs', *a)
end
def on_word_new
@@ -218,7 +217,7 @@ class TestRipper::DummyParser < Ripper
end
def on_words_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_words_add(words, word)
@@ -226,7 +225,7 @@ class TestRipper::DummyParser < Ripper
end
def on_qwords_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_qwords_add(words, word)
@@ -234,27 +233,27 @@ class TestRipper::DummyParser < Ripper
end
def on_symbols_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_symbols_add(symbols, symbol)
- symbols.push TestRipper::Node::Sym.new(symbol)
+ symbols.push Node::Sym.new(symbol)
end
def on_qsymbols_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_qsymbols_add(symbols, symbol)
- symbols.push TestRipper::Node::Sym.new(symbol)
+ symbols.push Node::Sym.new(symbol)
end
def on_mlhs_new
- TestRipper::NodeList.new
+ NodeList.new
end
def on_mlhs_paren(list)
- TestRipper::Node.new(:mlhs, list)
+ Node.new(:mlhs, list)
end
def on_mlhs_add(list, node)
@@ -278,12 +277,12 @@ class TestRipper::DummyParser < Ripper
end
def on_rescue(exc, *rest)
- TestRipper::Node.new('rescue', (exc && TestRipper::NodeList.new(exc)), *rest)
+ Node.new('rescue', (exc && 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|
- TestRipper::Node.new(event, *args)
+ Node.new(event, *args)
end
end
end
diff --git a/test/ripper/test_lexer.rb b/test/ripper/test_lexer.rb
index 65d4ce3b5b..bbb0b31ae3 100644
--- a/test/ripper/test_lexer.rb
+++ b/test/ripper/test_lexer.rb
@@ -265,74 +265,6 @@ world"
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_lexer(expected, code)
-
- 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_lexer(expected, code)
- end
-
def test_invalid_escape_ctrl_mbchar
code = %["\\C-\u{3042}"]
expected = [
diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb
index 8a7782820b..c4d9a627a6 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 = TestRipper::DummyParser.new(str)
+ dp = DummyParser.new(str)
dp.hook(*nm, &bl) if nm
dp.parse.to_s
end
@@ -152,7 +152,6 @@ 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
@@ -513,7 +512,7 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
end
end
- parser = TestRipper::DummyParser.new("a::b").extend(hook)
+ parser = DummyParser.new("a::b").extend(hook)
assert_equal '[call(vcall((ident: "a")),(method: (op: "::")),(ident: "b"))]', parser.parse.to_s
end
diff --git a/test/ripper/test_ripper.rb b/test/ripper/test_ripper.rb
index 9adfd97dfd..83b43d67fe 100644
--- a/test/ripper/test_ripper.rb
+++ b/test/ripper/test_ripper.rb
@@ -14,13 +14,6 @@ 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
diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb
index 792f19ef1a..31792d36a7 100644
--- a/test/ripper/test_scanner_events.rb
+++ b/test/ripper/test_scanner_events.rb
@@ -53,6 +53,8 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
Ripper.tokenize("1 .foo\n")
assert_equal ["1", "\n", " ", ".", "foo", "\n"],
Ripper.tokenize("1\n .foo\n")
+ assert_equal ["def", " ", "f", ";", " ", "(", "x", ")", "::", "A", " ", "="],
+ Ripper.tokenize("def f; (x)::A =")
end
def test_lex
@@ -113,11 +115,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],
@@ -717,7 +719,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
@@ -997,21 +999,13 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
assert_equal [:on_parse_error, "Invalid escape character syntax", "\\C-\u{3042}"], err
end
- def test_invalid_hex_escape_string
+ def test_invalid_hex_escape
err = nil
- assert_equal ['\\x', 'U'], scan('tstring_content', '"\\xU"') {|*e| err = e}
+ assert_equal ['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 ['\\x', 'U'], scan('tstring_content', '/\\xU/') {|*e| err = e}
+ assert_equal ['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 a1cf5e4f0a..9faeaba782 100644
--- a/test/ripper/test_sexp.rb
+++ b/test/ripper/test_sexp.rb
@@ -175,7 +175,7 @@ eot
[:aryptn,
nil,
[[:var_field, [:@ident, "a", [1, 11]]]],
- nil,
+ [:var_field, nil],
nil],
[[:void_stmt]],
nil]],
@@ -407,14 +407,6 @@ 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]],
@@ -494,22 +486,6 @@ 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 de18ac865c..bc57d57ee4 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)
- File.foreach(expand_filename(filename), encoding: Encoding::ASCII_8BIT) do |line|
+ IO.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_emoji_breaks.rb b/test/ruby/enc/test_emoji_breaks.rb
index bb5114680e..3e2999d61e 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 = []
- File.foreach(file.fullname, encoding: Encoding::UTF_8) do |line|
+ IO.foreach(file.fullname, encoding: Encoding::UTF_8) do |line|
line.chomp!
if $.==1
if line=="# #{file.basename}-#{file.version}.txt"
diff --git a/test/ruby/enc/test_grapheme_breaks.rb b/test/ruby/enc/test_grapheme_breaks.rb
index 7e6d722d40..f4e3c93b47 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 = []
- File.foreach(GRAPHEME_BREAK_TEST_FILE, encoding: Encoding::UTF_8) do |line|
+ IO.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 b5d5c6e337..eaabbc58a2 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
- File.readlines("#{UNICODE_DATA_PATH}/CaseFolding.txt", encoding: Encoding::ASCII_8BIT)
+ IO.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
deleted file mode 100644
index fbf780d6c3..0000000000
--- a/test/ruby/rjit/test_assembler.rb
+++ /dev/null
@@ -1,368 +0,0 @@
-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_argf.rb b/test/ruby/test_argf.rb
index 12f7d6485a..903cd62b02 100644
--- a/test/ruby/test_argf.rb
+++ b/test/ruby/test_argf.rb
@@ -267,6 +267,7 @@ class TestArgf < Test::Unit::TestCase
end
def test_inplace_nonascii
+ omit "not working on MinGW" if /mingw/ =~ RUBY_PLATFORM
ext = Encoding.default_external or
omit "no default external encoding"
t = nil
diff --git a/test/ruby/test_arity.rb b/test/ruby/test_arity.rb
index bd26d5f0f5..d26338e0aa 100644
--- a/test/ruby/test_arity.rb
+++ b/test/ruby/test_arity.rb
@@ -65,5 +65,6 @@ 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 9f89a54358..6c0db0832b 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -529,19 +529,14 @@ 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, a4 ]
+ a = @cls[ a1, a2, a3 ]
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))
@@ -1334,17 +1329,13 @@ 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, a4 ]
+ a = @cls[ a1, a2, a3 ]
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))
@@ -1702,15 +1693,6 @@ 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))
@@ -3556,15 +3538,6 @@ 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)
diff --git a/test/ruby/test_assignment.rb b/test/ruby/test_assignment.rb
index 3a8dafb7f0..3d0e773c82 100644
--- a/test/ruby/test_assignment.rb
+++ b/test/ruby/test_assignment.rb
@@ -248,6 +248,16 @@ class TestAssignment < Test::Unit::TestCase
a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c])
end
+ def test_massign_optimized_literal_bug_21012
+ a = []
+ def a.[]=(*args)
+ push args
+ end
+ a["a", "b"], = 1
+ a["a", 10], = 2
+ assert_equal [["a", "b", 1], ["a", 10, 2]], a
+ end
+
def test_assign_rescue
a = raise rescue 2; assert_equal(2, a)
a, b = raise rescue [3,4]; assert_equal([3, 4], [a, b])
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index 234c7af219..e43dac28b3 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -214,128 +214,6 @@ 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
@@ -746,41 +624,6 @@ dummy
assert_equal("def test_keep_script_lines_for_of\n", node_method.source.lines.first)
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
@@ -1205,23 +1048,10 @@ dummy
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 assert_error_tolerant(src, expected, keep_tokens: false)
+ def assert_error_tolerant(src, expected)
begin
verbose_bak, $VERBOSE = $VERBOSE, false
- node = RubyVM::AbstractSyntaxTree.parse(src, error_tolerant: true, keep_tokens: keep_tokens)
+ node = RubyVM::AbstractSyntaxTree.parse(src, error_tolerant: true)
ensure
$VERBOSE = verbose_bak
end
@@ -1229,6 +1059,5 @@ dummy
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 1eb3551e57..e475520321 100644
--- a/test/ruby/test_autoload.rb
+++ b/test/ruby/test_autoload.rb
@@ -274,11 +274,6 @@ 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 d35dead95b..bb0562c0bb 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].map.map { [1].map.map { foo } }
- assert_equal("[\"#{__FILE__}:#{@line}:in `map'\"]", @res)
+ 1.times.map { 1.times.map { foo } }
+ assert_equal("[\"#{__FILE__}:#{@line}:in `times'\"]", @res)
end
def test_caller_location_path_cfunc_iseq_no_pc
def self.foo
@res = caller_locations(2, 1)[0].path
end
- [1].map.map { [1].map.map { foo } }
+ 1.times.map { 1.times.map { foo } }
assert_equal(__FILE__, @res)
end
diff --git a/test/ruby/test_beginendblock.rb b/test/ruby/test_beginendblock.rb
index 301a746f4a..eb8394864f 100644
--- a/test/ruby/test_beginendblock.rb
+++ b/test/ruby/test_beginendblock.rb
@@ -14,11 +14,6 @@ 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")
@@ -45,9 +40,9 @@ class TestBeginEndBlock < Test::Unit::TestCase
end
def test_endblockwarn_in_eval
- assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", [], ['test.rb:1: warning: END in method; use at_exit'])
+ assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", [], ['(eval):2: warning: END in method; use at_exit'])
begin;
- eval <<-EOE, nil, "test.rb", 0
+ eval <<-EOE
def end2
END {}
end
diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb
index 1b705b02a8..065a944853 100644
--- a/test/ruby/test_bignum.rb
+++ b/test/ruby/test_bignum.rb
@@ -821,11 +821,5 @@ class TestBignum < Test::Unit::TestCase
assert_nil(T1024P.infinite?)
assert_nil((-T1024P).infinite?)
end
-
- def test_gmp_version
- if RbConfig::CONFIG.fetch('configure_args').include?("'--with-gmp'")
- assert_kind_of(String, Integer::GMP_VERSION)
- end
- end if ENV['GITHUB_WORKFLOW'] == 'Compilations'
end
end
diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb
index 09146efa41..88e2ddcb7b 100644
--- a/test/ruby/test_call.rb
+++ b/test/ruby/test_call.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: false
require 'test/unit'
-require '-test-/iter'
class TestCall < Test::Unit::TestCase
def aaa(a, b=100, *rest)
@@ -100,207 +99,6 @@ 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{}
-
- # +=, without block, non-popped
- assert_equal([[], {}, nil, [4], {}, nil], h.v{h[**kw] += 1})
- assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, **kw] += 1})
- assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, *a, **kw] += 1})
- assert_equal([[], {kw: 5}, nil, [4], {kw: 5}, nil], h.v{h[kw: 5] += 1})
- assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1})
- assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1})
- assert_equal([[0], {kw: 5, a: 2}, nil, [0, 4], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] += 1})
- assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 4], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] += 1})
-
- # +=, with block, non-popped
- assert_equal([[], {}, b, [4], {}, b], h.v{h[**kw, &b] += 1})
- assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, **kw, &b] += 1})
- assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, *a, **kw, &b] += 1})
- assert_equal([[], {kw: 5}, b, [4], {kw: 5}, b], h.v{h[kw: 5, &b] += 1})
- assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1})
- assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1})
- assert_equal([[0], {kw: 5, a: 2}, b, [0, 4], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] += 1})
- assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 4], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1})
-
- # +=, without block, popped
- assert_equal([[], {}, nil, [4], {}, nil], h.v{h[**kw] += 1; nil})
- assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, **kw] += 1; nil})
- assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, *a, **kw] += 1; nil})
- assert_equal([[], {kw: 5}, nil, [4], {kw: 5}, nil], h.v{h[kw: 5] += 1; nil})
- assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1; nil})
- assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1; nil})
- assert_equal([[0], {kw: 5, a: 2}, nil, [0, 4], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] += 1; nil})
- assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 4], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] += 1; nil})
-
- # +=, with block, popped
- assert_equal([[], {}, b, [4], {}, b], h.v{h[**kw, &b] += 1; nil})
- assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, **kw, &b] += 1; nil})
- assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, *a, **kw, &b] += 1; nil})
- assert_equal([[], {kw: 5}, b, [4], {kw: 5}, b], h.v{h[kw: 5, &b] += 1; nil})
- assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1; nil})
- assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1; nil})
- assert_equal([[0], {kw: 5, a: 2}, b, [0, 4], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] += 1; nil})
- assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 4], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1; nil})
-
- # &&=, without block, non-popped
- assert_equal([[], {}, nil, [1], {}, nil], h.v{h[**kw] &&= 1})
- assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, **kw] &&= 1})
- assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, *a, **kw] &&= 1})
- assert_equal([[], {kw: 5}, nil, [1], {kw: 5}, nil], h.v{h[kw: 5] &&= 1})
- assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1})
- assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1})
- assert_equal([[0], {kw: 5, a: 2}, nil, [0, 1], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] &&= 1})
- assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 1], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1})
-
- # &&=, with block, non-popped
- assert_equal([[], {}, b, [1], {}, b], h.v{h[**kw, &b] &&= 1})
- assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, **kw, &b] &&= 1})
- assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, *a, **kw, &b] &&= 1})
- assert_equal([[], {kw: 5}, b, [1], {kw: 5}, b], h.v{h[kw: 5, &b] &&= 1})
- assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1})
- assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1})
- assert_equal([[0], {kw: 5, a: 2}, b, [0, 1], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] &&= 1})
- assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 1], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1})
-
- # &&=, without block, popped
- assert_equal([[], {}, nil, [1], {}, nil], h.v{h[**kw] &&= 1; nil})
- assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, **kw] &&= 1; nil})
- assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, *a, **kw] &&= 1; nil})
- assert_equal([[], {kw: 5}, nil, [1], {kw: 5}, nil], h.v{h[kw: 5] &&= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1; nil})
- assert_equal([[0], {kw: 5, a: 2}, nil, [0, 1], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] &&= 1; nil})
- assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 1], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1; nil})
-
- # &&=, with block, popped
- assert_equal([[], {}, b, [1], {}, b], h.v{h[**kw, &b] &&= 1; nil})
- assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, **kw, &b] &&= 1; nil})
- assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, *a, **kw, &b] &&= 1; nil})
- assert_equal([[], {kw: 5}, b, [1], {kw: 5}, b], h.v{h[kw: 5, &b] &&= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1; nil})
- assert_equal([[0], {kw: 5, a: 2}, b, [0, 1], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] &&= 1; nil})
- assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 1], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1; nil})
-
- # ||=, without block, non-popped
- assert_equal([[], {}, nil], h.v{h[**kw] ||= 1})
- assert_equal([[0], {}, nil], h.v{h[0, **kw] ||= 1})
- assert_equal([[0], {}, nil], h.v{h[0, *a, **kw] ||= 1})
- assert_equal([[], {kw: 5}, nil], h.v{h[kw: 5] ||= 1})
- assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1})
- assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1})
- assert_equal([[0], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] ||= 1})
- assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1})
-
- # ||=, with block, non-popped
- assert_equal([[], {}, b], h.v{h[**kw, &b] ||= 1})
- assert_equal([[0], {}, b], h.v{h[0, **kw, &b] ||= 1})
- assert_equal([[0], {}, b], h.v{h[0, *a, **kw, &b] ||= 1})
- assert_equal([[], {kw: 5}, b], h.v{h[kw: 5, &b] ||= 1})
- assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1})
- assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1})
- assert_equal([[0], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] ||= 1})
- assert_equal([[0], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1})
-
- # ||=, without block, popped
- assert_equal([[], {}, nil], h.v{h[**kw] ||= 1; nil})
- assert_equal([[0], {}, nil], h.v{h[0, **kw] ||= 1; nil})
- assert_equal([[0], {}, nil], h.v{h[0, *a, **kw] ||= 1; nil})
- assert_equal([[], {kw: 5}, nil], h.v{h[kw: 5] ||= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1; nil})
- assert_equal([[0], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] ||= 1; nil})
- assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1; nil})
-
- # ||=, with block, popped
- assert_equal([[], {}, b], h.v{h[**kw, &b] ||= 1; nil})
- assert_equal([[0], {}, b], h.v{h[0, **kw, &b] ||= 1; nil})
- assert_equal([[0], {}, b], h.v{h[0, *a, **kw, &b] ||= 1; nil})
- assert_equal([[], {kw: 5}, b], h.v{h[kw: 5, &b] ||= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1; nil})
- assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1; nil})
- assert_equal([[0], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] ||= 1; nil})
- assert_equal([[0], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1; nil})
-
- 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
-
- o[kw: 1] += 1
- assert_equal([], ary)
-
- o[**o] += 1
- assert_equal([:to_hash], ary)
-
- ary.clear
- o[**o, &o] += 1
- # to_proc called twice because no VM instruction for coercing to proc
- assert_equal([:to_hash, :to_proc, :to_proc], ary)
-
- ary.clear
- o[*o, **o, &o] += 1
- assert_equal([:to_a, :to_hash, :to_proc, :to_proc], ary)
- 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
-
- a = []
- kw = {}
-
- assert_equal([[2], {b: 5}, [2, 4], {b: 5}], h.v{h[*a, 2, b: 5, **kw] += 1})
- end
-
def test_call_splat_order
bug12860 = '[ruby-core:77701] [Bug# 12860]'
ary = [1, 2]
@@ -317,1014 +115,4 @@ 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 a8a019cee2..300ab950ac 100644
--- a/test/ruby/test_class.rb
+++ b/test/ruby/test_class.rb
@@ -362,17 +362,6 @@ 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)
diff --git a/test/ruby/test_comparable.rb b/test/ruby/test_comparable.rb
index b689469d9e..b849217b7d 100644
--- a/test/ruby/test_comparable.rb
+++ b/test/ruby/test_comparable.rb
@@ -85,13 +85,7 @@ class TestComparable < Test::Unit::TestCase
assert_equal(1, @o.clamp(1, 1))
assert_equal(@o, @o.clamp(0, 0))
- 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') {
+ assert_raise_with_message(ArgumentError, 'min argument must be smaller than max argument') {
@o.clamp(2, 1)
}
end
@@ -121,7 +115,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 less than or equal to max argument') {
+ assert_raise_with_message(ArgumentError, 'min argument must be smaller than max argument') {
@o.clamp(2..1)
}
end
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb
deleted file mode 100644
index 5482a1529d..0000000000
--- a/test/ruby/test_compile_prism.rb
+++ /dev/null
@@ -1,2110 +0,0 @@
-# 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
- ruby_eval = RubyVM::InstructionSequence.compile("__LINE__").eval
- prism_eval = RubyVM::InstructionSequence.compile_prism("__LINE__").eval
-
- assert_equal ruby_eval, prism_eval
- 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))")
- 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_IndexAndWriteNode
- assert_prism_eval("[0][0] &&= 1")
- assert_prism_eval("[nil][0] &&= 1")
-
- # Testing `[]` with a block passed in
- assert_prism_eval(<<-CODE)
- class CustomHash < Hash
- def []=(key, value, &block)
- block ? super(block.call(key), value) : super(key, value)
- end
- end
-
- hash = CustomHash.new
-
- # Call the custom method with a block that modifies
- # the key before assignment
- hash["KEY"] = "test"
- hash["key", &(Proc.new { _1.upcase })] &&= "value"
- hash
- CODE
- end
-
- def test_IndexOrWriteNode
- assert_prism_eval("[0][0] ||= 1")
- assert_prism_eval("[nil][0] ||= 1")
-
- # Testing `[]` with a block passed in
- assert_prism_eval(<<-CODE)
- class CustomHash < Hash
- def []=(key, value, &block)
- super(block.call(key), value)
- end
- end
-
- hash = CustomHash.new
-
- # Call the custom method with a block that modifies
- # the key before assignment
- hash["key", &(Proc.new { _1.upcase })] ||= "value"
- hash
- CODE
- end
-
- def test_IndexOperatorWriteNode
- assert_prism_eval("[0][0] += 1")
-
- # Testing `[]` with a block passed in
- assert_prism_eval(<<-CODE)
- class CustomHash < Hash
- def [](key, &block)
- block ? super(block.call(key)) : super(key)
- end
-
- def []=(key, value, &block)
- block ? super(block.call(key), value) : super(key, value)
- end
- end
-
- hash = CustomHash.new
-
- # Call the custom method with a block that modifies
- # the key before assignment
- hash["KEY"] = "test"
- hash["key", &(Proc.new { _1.upcase })] &&= "value"
- hash
- CODE
- 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("_, {}[:foo] = 1")
- assert_prism_eval("_, {}[:foo], _ = 1")
- assert_prism_eval("_, {}[:foo], _ = 1")
- assert_prism_eval("_,{}[:foo], _, {}[:bar] = 1")
-
- 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
- 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"')
- 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('`echo #{1}`')
- assert_prism_eval('`printf #{"100"}`')
- 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?')
-
- frozen_source = <<-CODE
- # frozen_string_literal: true
- "a".frozen?
- CODE
- ruby_eval = RubyVM::InstructionSequence.compile(frozen_source).eval
- prism_eval = RubyVM::InstructionSequence.compile_prism(frozen_source).eval
-
- assert_equal ruby_eval, prism_eval
- end
-
- def test_SymbolNode
- assert_prism_eval(":pit")
- 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]")
- 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}")
- 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")
- 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
- 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')
- 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")
- end
-
- def test_WhileNode
- assert_prism_eval("a = 0; while a != 1; a = a + 1; end")
- 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_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
- 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
- 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
- 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
- end
-
- def test_RescueModiferNode
- 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
- 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 }")
- 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_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_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
- # BEGIN {} must be defined at the top level, so we need to manually
- # call the evals here instead of calling `assert_prism_eval`
- ruby_eval = RubyVM::InstructionSequence.compile("BEGIN { a = 1 }; 2").eval
- prism_eval = RubyVM::InstructionSequence.compile_prism("BEGIN { a = 1 }; 2").eval
- assert_equal ruby_eval, prism_eval
-
- ruby_eval = RubyVM::InstructionSequence.compile("b = 2; BEGIN { a = 1 }; a + b").eval
- prism_eval = RubyVM::InstructionSequence.compile_prism("b = 2; BEGIN { a = 1 }; a + b").eval
- assert_equal ruby_eval, prism_eval
- 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)")
- 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(<<-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
-
- 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
- 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
- # http://ci.rvm.jp/results/trunk-iseq_binary@ruby-sp2-docker/4779277
- #
- # expected:
- # == disasm: #<ISeq:prism_test_forwarding_arguments_node1@<compiled>:2 (2,8)-(4,11)>
- # local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: 1])
- # [ 1] "..."@0
- # 0000 putself ( 3)
- # 0001 getlocal_WC_0 ?@-2
- # 0003 splatarray false
- # 0005 getblockparamproxy ?@-1, 0
- # 0008 send <calldata!mid:prism_test_forwarding_arguments_node, argc:1, ARGS_SPLAT|ARGS_BLOCKARG|FCALL>, nil
- # 0011 leave ( 2)
- # actual:
- # == disasm: #<ISeq:prism_test_forwarding_arguments_node1@<compiled>:2 (2,8)-(4,11)>
- # local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: 1])
- # [ 1] "..."@0
- # 0000 putself ( 3)
- # 0001 getlocal_WC_0 ?@-2
- # 0003 splatarray false
- # 0005 getblockparamproxy "!"@-1, 0
- # 0008 send <calldata!mid:prism_test_forwarding_arguments_node, argc:1, ARGS_SPLAT|ARGS_BLOCKARG|FCALL>, nil
- # 0011 leave ( 2)
-
- omit "fails on trunk-iseq_binary"
-
- 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
- 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){}")
- 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}")
- 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 { |**| }")
- 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")
- 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_ScopeNode
- assert_separately(%w[], "#{<<-'begin;'}\n#{<<-'end;'}")
- begin;
- 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")
- end;
- end
-
- ############################################################################
- # Errors #
- ############################################################################
-
- def test_MissingNode
- # TODO
- end
-
- ############################################################################
- # Encoding #
- ############################################################################
-
- def test_encoding
- assert_prism_eval('"però"')
- assert_prism_eval(":però")
- end
-
- private
-
- def compare_eval(source)
- 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
- else
- assert_equal ruby_eval, prism_eval
- end
- 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
- end
-end
diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb
index 8817a62873..b262b2c1c1 100644
--- a/test/ruby/test_complex.rb
+++ b/test/ruby/test_complex.rb
@@ -526,71 +526,6 @@ 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?)
diff --git a/test/ruby/test_data.rb b/test/ruby/test_data.rb
index bb38f8ec91..3cafb365ed 100644
--- a/test/ruby/test_data.rb
+++ b/test/ruby/test_data.rb
@@ -97,7 +97,6 @@ class TestData < Test::Unit::TestCase
# 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)
@@ -117,31 +116,14 @@ class TestData < Test::Unit::TestCase
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)
@@ -235,22 +217,6 @@ class TestData < Test::Unit::TestCase
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
diff --git a/test/ruby/test_default_gems.rb b/test/ruby/test_default_gems.rb
index d8e8226253..467e5ecf83 100644
--- a/test/ruby/test_default_gems.rb
+++ b/test/ruby/test_default_gems.rb
@@ -2,26 +2,15 @@
require 'rubygems'
class TestDefaultGems < Test::Unit::TestCase
- def self.load(file)
- code = File.read(file, mode: "r:UTF-8:-", &:read)
-
- # - `git ls-files` is useless under ruby's repository
- # - `2>/dev/null` works only on Unix-like platforms
- code.gsub!(/`git.*?`/, '""')
-
- 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__)
- 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}")
+ Dir.glob("#{srcdir}/{lib,ext}/**/*.gemspec").map do |src|
+ assert_nothing_raised do
+ raise("invalid spec in #{src}") unless Gem::Specification.load(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 b9bf939394..3324a09afe 100644
--- a/test/ruby/test_defined.rb
+++ b/test/ruby/test_defined.rb
@@ -303,20 +303,6 @@ 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 026338f567..63ef99f159 100644
--- a/test/ruby/test_dir.rb
+++ b/test/ruby/test_dir.rb
@@ -96,7 +96,7 @@ class TestDir < Test::Unit::TestCase
d.close
end
- def test_class_chdir
+ def test_chdir
pwd = Dir.pwd
setup_envs
@@ -134,51 +134,6 @@ class TestDir < Test::Unit::TestCase
end
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|
- assert_empty(a)
-
- assert_warning(/conflicting chdir during another chdir block/) { dir.chdir }
- assert_warning(/conflicting chdir during another chdir block/) { 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 chdir during another chdir block/) { dir.chdir }
- assert_equal(pwd, Dir.pwd)
-
- assert_warning(/conflicting chdir during another chdir block/) { root_dir.chdir }
- assert_equal(@root, Dir.pwd)
-
- assert_warning(/conflicting chdir during another chdir block/) { dir.chdir }
-
- root_dir.chdir do
- assert_equal(@root, Dir.pwd)
- end
- assert_equal(pwd, Dir.pwd)
-
- 42
- 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
pwd = Dir.pwd
q = Thread::Queue.new
@@ -584,40 +539,6 @@ class TestDir < Test::Unit::TestCase
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
@@ -679,21 +600,6 @@ 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_econv.rb b/test/ruby/test_econv.rb
index 1d0641e918..1aad0de347 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[-d - #{enc.name}], <<-EOS, ignore_stderr: true)
+ assert_separately(%W[--disable=gems -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 f2c609a4cd..cde2951413 100644
--- a/test/ruby/test_encoding.rb
+++ b/test/ruby/test_encoding.rb
@@ -55,6 +55,40 @@ class TestEncoding < Test::Unit::TestCase
assert_raise(TypeError, bug5150) {Encoding.find(1)}
end
+ def test_replicate
+ assert_separately([], "#{<<~'END;'}")
+ Warning[:deprecated] = false
+ 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;
+ 100.times {|i|
+ EnvUtil.suppress_warning { 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) { EnvUtil.suppress_warning { 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?)
@@ -106,7 +140,7 @@ class TestEncoding < Test::Unit::TestCase
end
def test_errinfo_after_autoload
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ assert_separately(%w[--disable=gems], "#{<<~"begin;"}\n#{<<~'end;'}")
bug9038 = '[ruby-core:57949] [Bug #9038]'
begin;
e = assert_raise_with_message(SyntaxError, /unknown regexp option - Q/, bug9038) {
@@ -126,4 +160,18 @@ class TestEncoding < Test::Unit::TestCase
end
end;
end
+
+ def test_exceed_encoding_table_size
+ assert_separately(%w[--disable=gems], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ begin
+ enc = Encoding::UTF_8
+ 1_000.times{|i| EnvUtil.suppress_warning{ enc.replicate("R_#{i}") } } # now 256 entries
+ rescue EncodingError => e
+ assert_match(/too many encoding/, e.message)
+ else
+ assert false
+ end
+ end;
+ end
end
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index f7c8f012d8..cc217b05cc 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -1334,16 +1334,4 @@ 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 825c191d87..9224506e44 100644
--- a/test/ruby/test_enumerator.rb
+++ b/test/ruby/test_enumerator.rb
@@ -127,17 +127,6 @@ 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)
@@ -863,21 +852,6 @@ 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])
@@ -1035,13 +1009,18 @@ class TestEnumerator < Test::Unit::TestCase
}
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 }
+ def test_sum_of_numeric
+ num = Class.new(Numeric) do
+ attr_reader :to_f
+ def initialize(val)
+ @to_f = Float(val)
+ end
+ end
+
+ ary = [5, 10, 20].map {|i| num.new(i)}
+
+ assert_equal(35.0, ary.sum)
+ enum = ary.each
+ assert_equal(35.0, enum.sum)
end
end
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index cdadeac148..949913b590 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -2,7 +2,9 @@
require 'test/unit'
class TestEnv < Test::Unit::TestCase
- IGNORE_CASE = /bccwin|mswin|mingw/ =~ RUBY_PLATFORM
+ windows = /bccwin|mswin|mingw/ =~ RUBY_PLATFORM
+ IGNORE_CASE = windows
+ ENCODING = windows ? Encoding::UTF_8 : Encoding.find("locale")
PATH_ENV = "PATH"
INVALID_ENVVARS = [
"foo\0bar",
@@ -353,6 +355,13 @@ class TestEnv < Test::Unit::TestCase
end
end
+ def test_inspect_encoding
+ ENV.clear
+ key = "VAR\u{e5 e1 e2 e4 e3 101 3042}"
+ ENV[key] = "foo"
+ assert_equal(%{{#{(key.encode(ENCODING) rescue key.b).inspect}=>"foo"}}, ENV.inspect)
+ end
+
def test_to_a
ENV.clear
ENV["foo"] = "bar"
@@ -403,8 +412,7 @@ class TestEnv < Test::Unit::TestCase
assert_equal("foo", v)
end
assert_invalid_env {|var| ENV.assoc(var)}
- encoding = /mswin|mingw/ =~ RUBY_PLATFORM ? Encoding::UTF_8 : Encoding.find("locale")
- assert_equal(encoding, v.encoding)
+ assert_equal(ENCODING, v.encoding)
end
def test_has_value2
@@ -517,7 +525,7 @@ class TestEnv < Test::Unit::TestCase
assert_equal(huge_value, ENV["foo"])
end
- if /mswin|mingw/ =~ RUBY_PLATFORM
+ if windows
def windows_version
@windows_version ||= %x[ver][/Version (\d+)/, 1].to_i
end
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index 082d1dc03c..d55977c986 100644
--- a/test/ruby/test_eval.rb
+++ b/test/ruby/test_eval.rb
@@ -488,9 +488,6 @@ 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
@@ -547,8 +544,8 @@ class TestEval < Test::Unit::TestCase
end
def test_eval_location_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(['(eval)', 1], eval("[__FILE__, __LINE__]", nil))
+ assert_equal(['(eval)', 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 07b39d1217..c2eada0bfb 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -685,7 +685,7 @@ end.join
def test_machine_stackoverflow
bug9109 = '[ruby-dev:47804] [Bug #9109]'
- assert_separately([], <<-SRC)
+ assert_separately(%w[--disable-gem], <<-SRC)
assert_raise(SystemStackError, #{bug9109.dump}) {
h = {a: ->{h[:a].call}}
h[:a].call
@@ -696,7 +696,7 @@ end.join
def test_machine_stackoverflow_by_define_method
bug9454 = '[ruby-core:60113] [Bug #9454]'
- assert_separately([], <<-SRC)
+ assert_separately(%w[--disable-gem], <<-SRC)
assert_raise(SystemStackError, #{bug9454.dump}) {
define_method(:foo) {self.foo}
self.foo
@@ -1266,7 +1266,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
begin;
class Bug < RuntimeError
def backtrace
- File.readlines(IO::NULL)
+ IO.readlines(IO::NULL)
end
end
bug = Bug.new '[ruby-core:85939] [Bug #14577]'
@@ -1310,7 +1310,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 at .*\):1:/, bug)
+ assert_in_out_err(['-e', 'eval("raise")'], "", [], /^\(eval\):1:/, bug)
end
def test_full_message
@@ -1470,19 +1470,6 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
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;'}")
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index cb6e846bc6..5825aaf6cc 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::RJIT) && RubyVM::RJIT.enabled?
+ omit 'This is unstable on GitHub Actions --jit-wait. TODO: debug it' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
max = 1000
assert_equal(max, max.times{
Fiber.new{}
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb
index fbb18f07f9..d0472a0081 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -1517,12 +1517,9 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_equal(File.zero?(f), test(?z, f), f)
stat = File.stat(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_equal(stat.atime, File.atime(f), f)
+ assert_equal(stat.ctime, File.ctime(f), f)
+ assert_equal(stat.mtime, File.mtime(f), f)
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 b91b904d1e..cee69b6018 100644
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -227,12 +227,6 @@ 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
@@ -492,17 +486,6 @@ 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))
@@ -530,6 +513,10 @@ class TestFloat < Test::Unit::TestCase
assert_raise(TypeError) {1.0.floor(nil)}
def (prec = Object.new).to_int; 2; end
assert_equal(0.99, 0.998.floor(prec))
+
+ assert_equal(-10000000000, -1.0.floor(-10), "[Bug #20654]")
+ assert_equal(-100000000000000000000, -1.0.floor(-20), "[Bug #20654]")
+ assert_equal(-100000000000000000000000000000000000000000000000000, -1.0.floor(-50), "[Bug #20654]")
end
def test_ceil_with_precision
@@ -557,6 +544,10 @@ class TestFloat < Test::Unit::TestCase
assert_raise(TypeError) {1.0.ceil(nil)}
def (prec = Object.new).to_int; 2; end
assert_equal(0.99, 0.981.ceil(prec))
+
+ assert_equal(10000000000, 1.0.ceil(-10), "[Bug #20654]")
+ assert_equal(100000000000000000000, 1.0.ceil(-20), "[Bug #20654]")
+ assert_equal(100000000000000000000000000000000000000000000000000, 1.0.ceil(-50), "[Bug #20654]")
end
def test_truncate_with_precision
@@ -842,6 +833,12 @@ class TestFloat < Test::Unit::TestCase
o = Object.new
def o.to_f; inf = Float::INFINITY; inf/inf; end
assert_predicate(Float(o), :nan?)
+
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-16be"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-16le"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-32be"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("utf-32le"))}
+ assert_raise(Encoding::CompatibilityError) {Float("0".encode("iso-2022-jp"))}
end
def test_invalid_str
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index 39b001c3d0..bb136656ce 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -128,8 +128,6 @@ 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]
@@ -151,13 +149,8 @@ class TestGc < Test::Unit::TestCase
GC.stat(stat)
GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT].times do |i|
- begin
- reenable_gc = !GC.disable
- GC.stat_heap(i, stat_heap)
- GC.stat(stat)
- ensure
- GC.enable if reenable_gc
- end
+ GC.stat_heap(i, stat_heap)
+ GC.stat(stat)
assert_equal GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] * (2**i), stat_heap[:slot_size]
assert_operator stat_heap[:heap_allocatable_pages], :<=, stat[:heap_allocatable_pages]
@@ -168,10 +161,6 @@ 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)
@@ -183,7 +172,6 @@ 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 = {}
@@ -195,11 +183,6 @@ 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
@@ -211,10 +194,8 @@ class TestGc < Test::Unit::TestCase
stat = GC.stat
stat_heap = GC.stat_heap
- 2.times do
- GC.stat(stat)
- GC.stat_heap(nil, stat_heap)
- end
+ GC.stat(stat)
+ GC.stat_heap(nil, stat_heap)
stat_heap_sum = Hash.new(0)
stat_heap.values.each do |hash|
@@ -227,36 +208,17 @@ 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([], __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
+ 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
GC.latest_gc_info(h = {}) # allocate hash and rehearsal
GC.start
@@ -293,74 +255,19 @@ class TestGc < Test::Unit::TestCase
assert_nil GC.latest_gc_info(:need_major_by)
# allocate objects until need_major_by is set or major GC happens
+ major_count = GC.stat(:major_gc_count)
objects = []
- while GC.latest_gc_info(:need_major_by).nil?
+ while GC.stat(:major_gc_count) == major_count && 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)
+ assert_not_nil 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
+ assert_not_nil GC.latest_gc_info(:major_by)
end
def test_stress_compile_send
- assert_in_out_err([], <<-EOS, [], [], "")
+ assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "")
GC.stress = true
begin
eval("A::B.c(1, 1, d: 234)")
@@ -370,7 +277,7 @@ class TestGc < Test::Unit::TestCase
end
def test_singleton_method
- assert_in_out_err([], <<-EOS, [], [], "[ruby-dev:42832]")
+ assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "[ruby-dev:42832]")
GC.stress = true
10.times do
obj = Object.new
@@ -382,7 +289,7 @@ class TestGc < Test::Unit::TestCase
end
def test_singleton_method_added
- assert_in_out_err([], <<-EOS, [], [], "[ruby-dev:44436]")
+ assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "[ruby-dev:44436]")
class BasicObject
undef singleton_method_added
def singleton_method_added(mid)
@@ -400,21 +307,22 @@ class TestGc < Test::Unit::TestCase
env = {
"RUBY_GC_HEAP_INIT_SLOTS" => "100"
}
- 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/)
+ assert_in_out_err([env, "-W0", "-e", "exit"], "", [], [], "[Bug #19284]")
- 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 = {
+ "RUBY_GC_MALLOC_LIMIT" => "60000000",
+ "RUBY_GC_HEAP_INIT_SLOTS" => "100000"
+ }
+ assert_normal_exit("exit", "[ruby-core:39777]", :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 = {
+ "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 = {
"RUBY_GC_HEAP_GROWTH_FACTOR" => "2.0",
@@ -424,13 +332,16 @@ 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]")
- 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_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?
env = {
"RUBY_GC_MALLOC_LIMIT" => "60000000",
@@ -453,127 +364,6 @@ 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
@@ -587,27 +377,19 @@ class TestGc < Test::Unit::TestCase
def test_profiler_clear
omit "for now"
- 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)
-
- 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
-
- def test_profiler_raw_data
+ assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'eom', timeout: 30
GC::Profiler.enable
+
GC.start
- assert GC::Profiler.raw_data
- ensure
- GC::Profiler.disable
+ 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)
+ eom
end
def test_profiler_total_time
@@ -621,34 +403,34 @@ class TestGc < Test::Unit::TestCase
end
def test_finalizing_main_thread
- assert_in_out_err([], <<-EOS, ["\"finalize\""], [], "[ruby-dev:46647]")
+ assert_in_out_err(%w[--disable-gems], <<-EOS, ["\"finalize\""], [], "[ruby-dev:46647]")
ObjectSpace.define_finalizer(Thread.main) { p 'finalize' }
EOS
end
def test_expand_heap
- 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})"
+ 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})"
- a = []
- (base_length * 500).times{ a << 'a'; nil }
- GC.start
- assert_operator base_length, :<, GC.stat[:heap_eden_pages] + 1
- RUBY
+ a = []
+ (base_length * 500).times{ a << 'a'; nil }
+ GC.start
+ assert_operator base_length, :<, GC.stat[:heap_eden_pages] + 1
+ eom
end
def test_thrashing_for_young_objects
# This test prevents bugs like [Bug #18929]
- assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'RUBY'
# Grow the heap
@ary = 100_000.times.map { Object.new }
@@ -738,11 +520,11 @@ class TestGc < Test::Unit::TestCase
end
def test_finalizer_passed_object_id
- assert_in_out_err([], <<~RUBY, ["true"], [])
+ assert_in_out_err(%w[--disable-gems], <<-EOS, ["true"], [])
o = Object.new
obj_id = o.object_id
ObjectSpace.define_finalizer(o, ->(id){ p id == obj_id })
- RUBY
+ EOS
end
def test_verify_internal_consistency
@@ -851,30 +633,4 @@ 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 f8ebba84b8..3ccd2deb07 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -313,7 +313,7 @@ class TestGCCompact < Test::Unit::TestCase
assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
- ARY_COUNT = 50000
+ ARY_COUNT = 500
GC.verify_compaction_references(expand_heap: true, toward: :empty)
@@ -325,7 +325,7 @@ class TestGCCompact < Test::Unit::TestCase
}.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats.dig(:moved_down, :T_ARRAY) || 0, :>=, ARY_COUNT - 10)
+ assert_operator(stats.dig(:moved_down, :T_ARRAY) || 0, :>=, ARY_COUNT)
refute_empty($arys.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
@@ -335,7 +335,7 @@ class TestGCCompact < Test::Unit::TestCase
assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
- ARY_COUNT = 50000
+ ARY_COUNT = 500
GC.verify_compaction_references(expand_heap: true, toward: :empty)
@@ -349,7 +349,7 @@ class TestGCCompact < Test::Unit::TestCase
}.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats.dig(:moved_up, :T_ARRAY) || 0, :>=, ARY_COUNT - 10)
+ assert_operator(stats.dig(:moved_up, :T_ARRAY) || 0, :>=, ARY_COUNT)
refute_empty($arys.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
@@ -367,7 +367,7 @@ class TestGCCompact < Test::Unit::TestCase
end
end
- OBJ_COUNT = 50000
+ OBJ_COUNT = 500
GC.verify_compaction_references(expand_heap: true, toward: :empty)
@@ -381,28 +381,27 @@ class TestGCCompact < Test::Unit::TestCase
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats.dig(:moved_up, :T_OBJECT) || 0, :>=, OBJ_COUNT - 10)
- refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
+ assert_operator(stats.dig(:moved_up, :T_OBJECT) || 0, :>=, OBJ_COUNT)
end;
end
def test_moving_strings_up_size_pools
omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
- assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30, signal: :SEGV)
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
- STR_COUNT = 50000
+ STR_COUNT = 500
GC.verify_compaction_references(expand_heap: true, toward: :empty)
Fiber.new {
- str = "a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 4
+ str = "a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]
$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 - 10)
+ assert_operator(stats[:moved_up][:T_STRING], :>=, STR_COUNT)
refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
@@ -410,46 +409,23 @@ class TestGCCompact < Test::Unit::TestCase
def test_moving_strings_down_size_pools
omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
- assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30, signal: :SEGV)
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
- STR_COUNT = 50000
+ STR_COUNT = 500
GC.verify_compaction_references(expand_heap: true, toward: :empty)
Fiber.new {
- $ary = STR_COUNT.times.map { ("a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 4).squeeze! }
+ $ary = STR_COUNT.times.map { ("a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]).squeeze! }
}.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats[:moved_down][:T_STRING], :>=, STR_COUNT - 10)
+ assert_operator(stats[:moved_down][:T_STRING], :>=, STR_COUNT)
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;"}")
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index a063518190..58fbfea1de 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -4,6 +4,7 @@ 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
@@ -84,9 +85,20 @@ 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
@@ -101,6 +113,35 @@ 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'])
@@ -178,16 +219,6 @@ 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"))
@@ -263,6 +294,78 @@ 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 ]
@@ -369,10 +472,6 @@ 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
@@ -743,6 +842,14 @@ 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
@@ -858,6 +965,13 @@ 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)
@@ -904,6 +1018,12 @@ 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] }
@@ -1185,6 +1305,15 @@ 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
@@ -1436,6 +1565,17 @@ class TestHash < Test::Unit::TestCase
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)
+ end
+
def test_threaded_iter_level
bug9105 = '[ruby-dev:47807] [Bug #9105]'
h = @cls[1=>2]
@@ -1467,16 +1607,6 @@ 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]
@@ -1607,6 +1737,124 @@ 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_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
+ 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))
@@ -1626,12 +1874,12 @@ class TestHash < Test::Unit::TestCase
def o.respond_to?(*args)
super
end
- assert_raise(TypeError, bug12030) {@cls[foo: o].dig(:foo, :foo)}
+ assert_raise(TypeError, bug12030) {{foo: o}.dig(:foo, :foo)}
end
def test_cmp
- h1 = @cls[a:1, b:2]
- h2 = @cls[a:1, b:2, c:3]
+ h1 = {a:1, b:2}
+ h2 = {a:1, b:2, c:3}
assert_operator(h1, :<=, h1)
assert_operator(h1, :<=, h2)
@@ -1655,8 +1903,8 @@ class TestHash < Test::Unit::TestCase
end
def test_cmp_samekeys
- h1 = @cls[a:1]
- h2 = @cls[a:2]
+ h1 = {a:1}
+ h2 = {a:2}
assert_operator(h1, :<=, h1)
assert_not_operator(h1, :<=, h2)
@@ -1680,15 +1928,15 @@ class TestHash < Test::Unit::TestCase
end
def test_to_proc
- h = @cls[
+ h = {
1 => 10,
2 => 20,
3 => 30,
- ]
+ }
assert_equal([10, 20, 30], [1, 2, 3].map(&h))
- assert_predicate(h.to_proc, :lambda?)
+ assert_equal(true, h.to_proc.lambda?)
end
def test_transform_keys
@@ -1818,6 +2066,22 @@ 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)}
@@ -1847,27 +2111,6 @@ 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
@@ -1877,341 +2120,6 @@ 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([], "#{<<~"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_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
@@ -2237,11 +2145,23 @@ class TestHashOnly < Test::Unit::TestCase
assert_raise(TypeError) { Hash.ruby2_keywords_hash(1) }
end
- def ar2st_object
- class << (obj = Object.new)
- attr_reader :h
+ def test_ar2st
+ # insert
+ obj = Object.new
+ obj.instance_variable_set(:@h, h = {})
+ def obj.hash
+ 10.times{|i| @h[i] = i}
+ 0
end
- obj.instance_variable_set(:@h, {})
+ def obj.inspect
+ 'test'
+ 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 = {})
def obj.hash
10.times{|i| @h[i] = i}
0
@@ -2252,21 +2172,6 @@ class TestHashOnly < 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
@@ -2275,12 +2180,20 @@ class TestHashOnly < 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
@@ -2296,6 +2209,27 @@ class TestHashOnly < 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;'}")
@@ -2322,15 +2256,6 @@ class TestHashOnly < Test::Unit::TestCase
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;
@@ -2339,17 +2264,29 @@ class TestHashOnly < Test::Unit::TestCase
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
+
+ def test_ar_to_st_reserved_value
+ klass = Class.new do
+ attr_reader :hash
+ def initialize(val) = @hash = val
+ end
+
+ values = 0.downto(-16).to_a
+ hash = {}
+ values.each do |val|
+ hash[klass.new(val)] = val
+ end
+ assert_equal values, hash.values, "[ruby-core:121239] [Bug #21170]"
+ end
end
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index 3349a1c493..2115883810 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -138,6 +138,20 @@ 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) }
@@ -238,32 +252,6 @@ class TestInteger < Test::Unit::TestCase
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?)
@@ -321,34 +309,23 @@ class TestInteger < Test::Unit::TestCase
begin;
called = false
Integer.class_eval do
- alias old_succ succ
- undef succ
- define_method(:succ){|x| called = true; x+1}
+ alias old_plus +
+ undef +
+ define_method(:+){|x| called = true; 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 succ
- alias succ old_succ
+ undef +
+ alias + old_plus
undef <
alias < old_lt
end
-
- # Asssert that Fixnum and Bignum behave consistently
bug18377 = "[ruby-core:106361]"
- assert_equal(fix_called, big_called, bug18377)
+ assert_equal(false, called, bug18377)
end;
end
@@ -465,6 +442,10 @@ class TestInteger < Test::Unit::TestCase
assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1111, 1111_1111_1111_1111_1111_1111_1111_1111.floor(1))
assert_int_equal(10**400, (10**400).floor(1))
+
+ assert_int_equal(-10000000000, -1.floor(-10), "[Bug #20654]")
+ assert_int_equal(-100000000000000000000, -1.floor(-20), "[Bug #20654]")
+ assert_int_equal(-100000000000000000000000000000000000000000000000000, -1.floor(-50), "[Bug #20654]")
end
def test_ceil
@@ -493,6 +474,10 @@ class TestInteger < Test::Unit::TestCase
assert_int_equal(1111_1111_1111_1111_1111_1111_1111_1111, 1111_1111_1111_1111_1111_1111_1111_1111.ceil(1))
assert_int_equal(10**400, (10**400).ceil(1))
+
+ assert_int_equal(10000000000, 1.ceil(-10), "[Bug #20654]")
+ assert_int_equal(100000000000000000000, 1.ceil(-20), "[Bug #20654]")
+ assert_int_equal(100000000000000000000000000000000000000000000000000, 1.ceil(-50), "[Bug #20654]")
end
def test_truncate
@@ -704,14 +689,6 @@ 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
@@ -756,9 +733,5 @@ 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 150f45cfd7..1ad13dd31b 100644
--- a/test/ruby/test_integer_comb.rb
+++ b/test/ruby/test_integer_comb.rb
@@ -408,32 +408,19 @@ 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 + VS.map {|b| [coerce.new(b), b]}).each {|b, i = b|
- if i == 0
+ VS.each {|b|
+ if b == 0
assert_raise(ZeroDivisionError) { a.divmod(b) }
else
- r = assert_nothing_raised(ArgumentError, "#{a}.remainder(#{b})") {a.remainder(b)}
+ r = a.remainder(b)
assert_kind_of(Integer, r)
if a < 0
- assert_operator(-i.abs, :<, r, "#{a}.remainder(#{b})")
+ assert_operator(-b.abs, :<, r, "#{a}.remainder(#{b})")
assert_operator(0, :>=, r, "#{a}.remainder(#{b})")
elsif 0 < a
assert_operator(0, :<=, r, "#{a}.remainder(#{b})")
- assert_operator(i.abs, :>, r, "#{a}.remainder(#{b})")
+ assert_operator(b.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 476d9f882f..2e6347e7f4 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 "RJIT has busy wait on GC. This sometimes fails with --jit." if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ omit "MJIT has busy wait on GC. This sometimes fails with --jit." if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
omit "multiple threads already active" if Thread.list.size > 1
msg = 'r58534 [ruby-core:80969] [Backport #13533]'
@@ -1116,6 +1116,34 @@ class TestIO < Test::Unit::TestCase
}
end
+ def test_copy_stream_dup_buffer
+ bug21131 = '[ruby-core:120961] [Bug #21131]'
+ mkcdtmpdir do
+ dst_class = Class.new do
+ def initialize(&block)
+ @block = block
+ end
+
+ def write(data)
+ @block.call(data.dup)
+ data.bytesize
+ end
+ end
+
+ rng = Random.new(42)
+ body = Tempfile.new("ruby-bug", binmode: true)
+ body.write(rng.bytes(16_385))
+ body.rewind
+
+ payload = []
+ IO.copy_stream(body, dst_class.new{|data| payload << data})
+ body.rewind
+ assert_equal(body.read, payload.join, bug21131)
+ ensure
+ body&.close
+ end
+ end
+
def test_copy_stream_write_in_binmode
bug8767 = '[ruby-core:56518] [Bug #8767]'
mkcdtmpdir {
@@ -1679,7 +1707,7 @@ class TestIO < Test::Unit::TestCase
end if have_nonblock?
def test_read_nonblock_no_exceptions
- 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.
+ 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.
with_pipe {|r, w|
assert_equal :wait_readable, r.read_nonblock(4096, exception: false)
w.puts "HI!"
@@ -1898,107 +1926,33 @@ 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
+ def test_readline_limit_nonascii
+ mkcdtmpdir do
+ i = 0
- File.open(__FILE__) do |f|
- assert_raise(TypeError) do
- f.readline 1, 2
- end
- end
- end
+ File.open("text#{i+=1}", "w+:utf-8") do |f|
+ f.write("Test\nok\u{bf}ok\n")
+ f.rewind
- def test_readline_raises
- File.open(__FILE__) do |f|
- assert_equal File.read(__FILE__), f.readline(nil)
- assert_raise(EOFError) do
- f.readline
+ assert_equal("Test\nok\u{bf}", f.readline("\u{bf}"))
+ assert_equal("ok\n", f.readline("\u{bf}"))
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
+ File.open("text#{i+=1}", "w+b:utf-32le") do |f|
+ f.write("0123456789")
+ f.rewind
- # 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
+ assert_equal(4, f.readline(4).bytesize)
+ assert_equal(4, f.readline(3).bytesize)
+ 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
+ File.open("text#{i+=1}", "w+:utf-8:utf-32le") do |f|
+ f.write("0123456789")
+ f.rewind
- def test_readline_chomp_true
- File.open(__FILE__) do |f|
- line = f.readline(chomp: true)
- assert_equal File.readlines(__FILE__).first.chomp, line
+ assert_equal(4, f.readline(4).bytesize)
+ assert_equal(4, f.readline(3).bytesize)
+ end
end
end
@@ -2451,9 +2405,9 @@ class TestIO < Test::Unit::TestCase
end
def test_autoclose_true_closed_by_finalizer
- # 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?
+ # 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?
feature2250 = '[ruby-core:26222]'
pre = 'ft2250'
@@ -2516,19 +2470,15 @@ class TestIO < Test::Unit::TestCase
end
def test_open_pipe
- 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
+ open("|" + EnvUtil.rubybin, "r+") do |f|
+ f.puts "puts 'foo'"
+ f.close_write
+ assert_equal("foo\n", f.read)
end
end
def test_read_command
- 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_equal("foo\n", IO.read("|echo foo"))
assert_raise(Errno::ENOENT, Errno::EINVAL) do
File.read("|#{EnvUtil.rubybin} -e puts")
end
@@ -2542,9 +2492,7 @@ class TestIO < Test::Unit::TestCase
Class.new(IO).binread("|#{EnvUtil.rubybin} -e puts")
end
assert_raise(Errno::ESPIPE) do
- assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630
- IO.read("|echo foo", 1, 1)
- end
+ IO.read("|echo foo", 1, 1)
end
end
@@ -2729,16 +2677,11 @@ class TestIO < Test::Unit::TestCase
def test_foreach
a = []
-
- 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
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
assert_equal(["foo\n", "bar\n", "baz\n"], a)
a = []
- 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
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :zot'", :open_args => ["r"]) {|x| a << x }
assert_equal(["zot\n"], a)
make_tempfile {|t|
@@ -2981,9 +2924,6 @@ 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
@@ -3929,7 +3869,7 @@ __END__
end
def test_race_gets_and_close
- opt = { signal: :ABRT, timeout: 10 }
+ opt = { signal: :ABRT, timeout: 200 }
assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}", **opt)
bug13076 = '[ruby-core:78845] [Bug #13076]'
begin;
@@ -4091,7 +4031,7 @@ __END__
assert_raise(EOFError) { f.pread(1, f.size) }
end
}
- end
+ end if IO.method_defined?(:pread)
def test_pwrite
make_tempfile { |t|
@@ -4100,7 +4040,7 @@ __END__
assert_equal("ooo", f.pread(3, 4))
end
}
- end
+ end if IO.method_defined?(:pread) and IO.method_defined?(:pwrite)
def test_select_exceptfds
if Etc.uname[:sysname] == 'SunOS'
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 7a58ec0c5a..1c76403b2d 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 TypeError do
+ assert_raise NoMethodError do
IO::Buffer.map("foobar")
end
end
@@ -102,6 +102,11 @@ 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:
@@ -111,16 +116,6 @@ 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
@@ -129,20 +124,6 @@ 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
@@ -199,14 +180,6 @@ 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)
@@ -236,6 +209,43 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
+ def test_slice_readonly
+ hello = %w"Hello World".join(" ").freeze
+ buffer = IO::Buffer.for(hello)
+ slice = buffer.slice
+ assert_predicate slice, :readonly?
+ assert_raise IO::Buffer::AccessError do
+ # This breaks the literal in string pool and many other tests in this file.
+ slice.set_string("Adios", 0, 5)
+ end
+ assert_equal "Hello World", hello
+ end
+
+ def test_transfer
+ hello = %w"Hello World".join(" ")
+ buffer = IO::Buffer.for(hello)
+ transferred = buffer.transfer
+ assert_equal "Hello World", transferred.get_string
+ assert_predicate buffer, :null?
+ assert_raise IO::Buffer::AccessError do
+ transferred.set_string("Goodbye")
+ end
+ assert_equal "Hello World", hello
+ end
+
+ def test_transfer_in_block
+ hello = %w"Hello World".join(" ")
+ buffer = IO::Buffer.for(hello, &:transfer)
+ assert_equal "Hello World", buffer.get_string
+ buffer.set_string("Ciao!")
+ assert_equal "Ciao! World", hello
+ hello.freeze
+ assert_raise IO::Buffer::AccessError do
+ buffer.set_string("Hola")
+ end
+ assert_equal "Ciao! World", hello
+ end
+
def test_locked
buffer = IO::Buffer.new(128, IO::Buffer::INTERNAL|IO::Buffer::LOCKED)
@@ -278,14 +288,6 @@ class TestIOBuffer < Test::Unit::TestCase
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.
RANGES = {
:U8 => [0, 2**8-1],
@@ -332,13 +334,6 @@ class TestIOBuffer < Test::Unit::TestCase
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)
@@ -363,12 +358,6 @@ class TestIOBuffer < Test::Unit::TestCase
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)
@@ -376,12 +365,6 @@ class TestIOBuffer < Test::Unit::TestCase
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!")
@@ -413,9 +396,11 @@ class TestIOBuffer < Test::Unit::TestCase
input.close
end
- def hello_world_tempfile
+ def hello_world_tempfile(repeats = 1)
io = Tempfile.new
- io.write("Hello World")
+ repeats.times do
+ io.write("Hello World")
+ end
io.seek(0)
yield io
@@ -447,6 +432,15 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
+ def test_read_with_length_and_offset
+ hello_world_tempfile(100) do |io|
+ buffer = IO::Buffer.new(1024)
+ # Only read 24 bytes from the file, as we are starting at offset 1000 in the buffer.
+ assert_equal 24, buffer.read(io, 0, 1000)
+ assert_equal "Hello World", buffer.get_string(1000, 11)
+ end
+ end
+
def test_write
io = Tempfile.new
@@ -460,6 +454,19 @@ class TestIOBuffer < Test::Unit::TestCase
io.close!
end
+ def test_write_with_length_and_offset
+ io = Tempfile.new
+
+ buffer = IO::Buffer.new(5)
+ buffer.set_string("Hello")
+ buffer.write(io, 4, 1)
+
+ io.seek(0)
+ assert_equal "ello", io.read(4)
+ ensure
+ io.close!
+ end
+
def test_pread
io = Tempfile.new
io.write("Hello World")
@@ -552,24 +559,4 @@ class TestIOBuffer < Test::Unit::TestCase
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 b01d627d92..9c14087eba 100644
--- a/test/ruby/test_io_m17n.rb
+++ b/test/ruby/test_io_m17n.rb
@@ -1158,78 +1158,6 @@ 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|
@@ -1396,27 +1324,23 @@ EOT
end
def test_open_pipe_r_enc
- 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
+ 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
def test_open_pipe_r_enc2
- 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
+ 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
def test_s_foreach_enc
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index b0896511d8..f5147831e4 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -167,6 +167,14 @@ class TestISeq < Test::Unit::TestCase
end
end
+ def test_ractor_shareable_value_frozen_core
+ iseq = RubyVM::InstructionSequence.compile(<<~'RUBY')
+ # shareable_constant_value: literal
+ REGEX = /#{}/ # [Bug #20569]
+ RUBY
+ assert_includes iseq.to_binary, "REGEX".b
+ end
+
def test_disasm_encoding
src = "\u{3042} = 1; \u{3042}; \u{3043}"
asm = compile(src).disasm
@@ -497,8 +505,7 @@ class TestISeq < Test::Unit::TestCase
[7, :line],
[9, :return]]],
[["ensure in foo@2", [[7, :line]]]],
- [["rescue in foo@4", [[5, :line],
- [5, :rescue]]]]]],
+ [["rescue in foo@4", [[5, :line]]]]]],
[["<class:D>@17", [[17, :class],
[18, :end]]]]], collect_iseq.call(sample_iseq)
end
@@ -638,8 +645,6 @@ class TestISeq < Test::Unit::TestCase
}
lines
- ensure
- Object.send(:remove_const, :A) rescue nil
end
def test_to_binary_line_tracepoint
@@ -761,17 +766,12 @@ class TestISeq < Test::Unit::TestCase
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)
+ def test_unreachable_pattern_matching
+ assert_in_out_err([], "true or 1 in 1")
+ assert_in_out_err([], "true or (case 1; in 1; 1; in 2; 2; end)")
end
- def test_unreachable_pattern_matching
+ def test_unreachable_pattern_matching_in_if_condition
assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", %w[1])
begin;
if true or {a: 0} in {a:}
@@ -782,31 +782,24 @@ class TestISeq < Test::Unit::TestCase
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_unreachable_next_in_block
+ bug20344 = '[ruby-core:117210] [Bug #20344]'
+ assert_nothing_raised(SyntaxError, bug20344) do
+ compile(<<~RUBY)
+ proc do
+ next
- def test_compile_prism_with_file
- Tempfile.create(%w"test_iseq .rb") do |f|
- f.puts "name = 'Prism'; puts 'hello"
- f.close
+ case nil
+ when "a"
+ next
+ when "b"
+ when "c"
+ proc {}
+ end
- assert_nothing_raised(SyntaxError) {
- RubyVM::InstructionSequence.compile_prism(f.path)
- }
+ next
+ end
+ RUBY
end
end
end
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 9aca787dff..94b5323ab0 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -237,16 +237,16 @@ 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.yo(**kw) kw end
m = method(:yo)
assert_equal(false, yo(**{}).frozen?)
@@ -447,30 +447,6 @@ class TestKeywordArguments < Test::Unit::TestCase
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
diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb
index 7738034240..9949fab8c7 100644
--- a/test/ruby/test_lambda.rb
+++ b/test/ruby/test_lambda.rb
@@ -177,6 +177,32 @@ 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 22127e903a..32bf097318 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -282,11 +282,6 @@ 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)
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index 907360b3a6..28293ffffc 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1090,23 +1090,7 @@ 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")
-
- 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
-
+ assert_raise(Encoding::CompatibilityError){s.rindex(a("\xb1\xa3"))}
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 13645e3aa8..6cd0b9acc3 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
require 'test/unit'
+require 'tempfile'
require_relative 'marshaltestlib'
class TestMarshal < Test::Unit::TestCase
@@ -313,10 +314,11 @@ class TestMarshal < Test::Unit::TestCase
assert_equal(c, Marshal.load(Marshal.dump(c)), bug2109)
assert_nothing_raised(ArgumentError, '[ruby-dev:40386]') do
- 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)
+ 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
end
assert_equal(//, re)
end
diff --git a/test/ruby/test_math.rb b/test/ruby/test_math.rb
index 6e67099c6b..73f44c6ae3 100644
--- a/test/ruby/test_math.rb
+++ b/test/ruby/test_math.rb
@@ -5,7 +5,6 @@ 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)
@@ -166,9 +165,6 @@ 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
@@ -183,7 +179,6 @@ 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
@@ -198,7 +193,6 @@ 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
@@ -283,7 +277,8 @@ 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_infinity(x, mesg)
+ assert_predicate(x, :negative?, mesg)
assert_nan(Math.gamma(Float::NAN))
end
@@ -304,6 +299,7 @@ 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 423ebd391a..aa564cde25 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -209,6 +209,27 @@ class TestMethod < Test::Unit::TestCase
assert_kind_of(String, o.method(:foo).hash.to_s)
end
+ def test_hash_does_not_change_after_compaction
+ omit "compaction is not supported on this platform" unless GC.respond_to?(:compact)
+
+ # iseq backed method
+ assert_separately([], <<~RUBY)
+ def a; end
+
+ # Need this method here because otherwise the iseq may be on the C stack
+ # which would get pinned and not move during compaction
+ def get_hash
+ method(:a).hash
+ end
+
+ hash = get_hash
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_equal(hash, get_hash)
+ RUBY
+ end
+
def test_owner
c = Class.new do
def foo; end
@@ -450,18 +471,6 @@ 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__
@@ -783,14 +792,6 @@ 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))
@@ -1443,25 +1444,25 @@ class TestMethod < Test::Unit::TestCase
end
def test_argument_error_location
- 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
+ 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
END_OF_BODY
assert_separately [], body
@@ -1470,7 +1471,7 @@ class TestMethod < Test::Unit::TestCase
end
def test_zsuper_private_override_instance_method
- assert_separately([], <<-'end;', timeout: 30)
+ assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
# Bug #16942 [ruby-core:98691]
module M
def x
@@ -1491,7 +1492,7 @@ class TestMethod < Test::Unit::TestCase
end
def test_override_optimized_method_on_class_using_prepend
- assert_separately([], <<-'end;', timeout: 30)
+ assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
# Bug #17725 [ruby-core:102884]
$VERBOSE = nil
String.prepend(Module.new)
@@ -1615,12 +1616,4 @@ 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
end
diff --git a/test/ruby/test_mjit.rb b/test/ruby/test_mjit.rb
new file mode 100644
index 0000000000..a97747eb88
--- /dev/null
+++ b/test/ruby/test_mjit.rb
@@ -0,0 +1,1327 @@
+# 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/,
+ /\AJIT batch \([^)]+ms\): .+\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,
+
+ # 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_twice('nil rescue true', result_inspect: 'nil', insns: %i[nop])
+ end
+
+ def test_compile_insn_local
+ assert_compile_twice("#{<<~"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: '33', success_count: 2, insns: %i[getblockparam setblockparam])
+ begin;
+ def foo(&b)
+ a = b
+ b = 2
+ a.call + 2
+ end
+
+ print foo { 1 }
+ 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_twice('$1', result_inspect: 'nil', insns: %i[getspecial])
+ end
+
+ def test_compile_insn_setspecial
+ assert_compile_twice("#{<<~"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_twice("#{<<~"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: 2, call_threshold: 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: '11', success_count: 1, insns: %i[getclassvariable setclassvariable])
+ begin;
+ class Foo
+ def self.foo
+ @@foo = 1
+ @@foo
+ end
+ end
+
+ print Foo.foo
+ print Foo.foo
+ end;
+ end
+
+ def test_compile_insn_constant
+ EnvUtil.suppress_warning do
+ assert_compile_twice("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[opt_getconstant_path setconstant])
+ begin;
+ FOO = 1
+ FOO
+ end;
+ end
+ end
+
+ def test_compile_insn_global
+ assert_compile_twice("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getglobal setglobal])
+ begin;
+ $foo = 1
+ $foo
+ end;
+ end
+
+ def test_compile_insn_putnil
+ assert_compile_twice('nil', result_inspect: 'nil', insns: %i[putnil])
+ end
+
+ def test_compile_insn_putself
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hellohello', success_count: 1, insns: %i[putself])
+ begin;
+ 2.times { print "hello" }
+ end;
+ end
+
+ def test_compile_insn_putobject
+ assert_compile_twice('0', result_inspect: '0', insns: %i[putobject_INT2FIX_0_])
+ assert_compile_twice('1', result_inspect: '1', insns: %i[putobject_INT2FIX_1_])
+ assert_compile_twice('2', result_inspect: '2', insns: %i[putobject])
+ end
+
+ def test_compile_insn_definemethod_definesmethod
+ verbose_bak, $VERBOSE = $VERBOSE, nil
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'helloworldhelloworld', success_count: 3, insns: %i[definemethod definesmethod])
+ begin;
+ print 2.times.map {
+ def method_definition
+ 'hello'
+ end
+
+ def self.smethod_definition
+ 'world'
+ end
+
+ method_definition + smethod_definition
+ }.join
+ end;
+ ensure
+ $VERBOSE = verbose_bak
+ end
+
+ def test_compile_insn_putspecialobject
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'aa', success_count: 2, insns: %i[putspecialobject])
+ begin;
+ print 2.times.map {
+ def a
+ 'a'
+ end
+
+ alias :b :a
+
+ b
+ }.join
+ end;
+ end
+
+ def test_compile_insn_putstring_concatstrings_objtostring
+ assert_compile_twice('"a#{}b" + "c"', result_inspect: '"abc"', insns: %i[putstring concatstrings objtostring])
+ end
+
+ def test_compile_insn_toregexp
+ assert_compile_twice('/#{true}/ =~ "true"', result_inspect: '0', insns: %i[toregexp])
+ end
+
+ def test_compile_insn_newarray
+ assert_compile_twice("#{<<~"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_twice('[**{ x: 1 }]', result_inspect: '[{:x=>1}]', insns: %i[newarraykwsplat])
+ end
+
+ def test_compile_insn_intern_duparray
+ assert_compile_twice('[:"#{0}"] + [1,2,3]', result_inspect: '[:"0", 1, 2, 3]', insns: %i[intern duparray])
+ end
+
+ def test_compile_insn_expandarray
+ assert_compile_twice('y = [ true, false, nil ]; x, = y; x', result_inspect: 'true', insns: %i[expandarray])
+ end
+
+ def test_compile_insn_concatarray
+ assert_compile_twice('["t", "r", *x = "u", "e"].join', result_inspect: '"true"', insns: %i[concatarray])
+ end
+
+ def test_compile_insn_splatarray
+ assert_compile_twice('[*(1..2)]', result_inspect: '[1, 2]', insns: %i[splatarray])
+ end
+
+ def test_compile_insn_newhash
+ assert_compile_twice('a = 1; { a: a }', result_inspect: '{:a=>1}', insns: %i[newhash])
+ end
+
+ def test_compile_insn_duphash
+ assert_compile_twice('{ a: 1 }', result_inspect: '{:a=>1}', insns: %i[duphash])
+ end
+
+ def test_compile_insn_newrange
+ assert_compile_twice('a = 1; 0..a', result_inspect: '0..1', insns: %i[newrange])
+ end
+
+ def test_compile_insn_pop
+ assert_compile_twice("#{<<~"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_twice("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '3', insns: %i[dup])
+ begin;
+ a = 1
+ a&.+(2)
+ end;
+ end
+
+ def test_compile_insn_dupn
+ assert_compile_twice("#{<<~"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_twice('{}["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_twice('[nil][0] = 1', result_inspect: '1', insns: %i[setn])
+ end
+
+ def test_compile_insn_adjuststack
+ assert_compile_twice("#{<<~"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_twice('defined?(a)', result_inspect: 'nil', insns: %i[defined])
+ end
+
+ def test_compile_insn_checkkeyword
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'truetrue', success_count: 1, insns: %i[checkkeyword])
+ begin;
+ def test(x: rand)
+ x
+ end
+ print test(x: true)
+ 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: '11', success_count: 4, insns: %i[send])
+ begin;
+ print proc { yield_self { 1 } }.call
+ print proc { yield_self { 1 } }.call
+ end;
+ end
+
+ def test_compile_insn_opt_str_freeze
+ assert_compile_twice("#{<<~"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_twice("#{<<~"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_twice("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"bar"', insns: %i[opt_str_uminus])
+ begin;
+ -'bar'
+ end;
+ end
+
+ def test_compile_insn_opt_newarray_max
+ assert_compile_twice("#{<<~"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_twice("#{<<~"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_twice('print', result_inspect: 'nil', insns: %i[opt_send_without_block])
+ end
+
+ def test_compile_insn_invokesuper
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '33', 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
+ print klass.new.test
+ end;
+ end
+
+ def test_compile_insn_invokeblock_leave
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '22', success_count: 2, insns: %i[invokeblock leave])
+ begin;
+ def foo
+ yield
+ end
+ print foo { 2 }
+ print foo { 2 }
+ end;
+ end
+
+ def test_compile_insn_throw
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '44', 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
+ print test
+ end;
+ end
+
+ def test_compile_insn_jump_branchif
+ assert_compile_twice("#{<<~"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_twice("#{<<~"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_twice("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '3', insns: %i[branchnil])
+ begin;
+ a = 2
+ a&.+(1)
+ end;
+ end
+
+ def test_compile_insn_objtostring
+ assert_compile_twice("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"42"', insns: %i[objtostring])
+ begin;
+ a = '2'
+ "4#{a}"
+ end;
+ end
+
+ def test_compile_insn_getconstant_path
+ assert_compile_twice('Struct', result_inspect: 'Struct', insns: %i[opt_getconstant_path])
+ end
+
+ def test_compile_insn_once
+ assert_compile_twice('/#{true}/o =~ "true" && $~.to_a', result_inspect: '["true"]', insns: %i[once])
+ end
+
+ def test_compile_insn_checkmatch_opt_case_dispatch
+ assert_compile_twice("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"world"', insns: %i[opt_case_dispatch])
+ begin;
+ case 'hello'
+ when 'hello'
+ 'world'
+ end
+ end;
+ end
+
+ def test_compile_multiple_values_case
+ assert_compile_twice("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"world"', insns: %i[opt_case_dispatch])
+ begin;
+ case 'hello'
+ when 'hello', 'world'
+ 'world'
+ end
+ end;
+ end
+
+ def test_compile_insn_opt_calc
+ assert_compile_twice('4 + 2 - ((2 * 3 / 2) % 2)', result_inspect: '5', insns: %i[opt_plus opt_minus opt_mult opt_div opt_mod])
+ assert_compile_twice('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_twice('4 + 2', result_inspect: '6')
+ end
+
+ def test_compile_insn_opt_cmp
+ assert_compile_twice('(1 == 1) && (1 != 2)', result_inspect: 'true', insns: %i[opt_eq opt_neq])
+ end
+
+ def test_compile_insn_opt_rel
+ assert_compile_twice('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_twice('[1] << 2', result_inspect: '[1, 2]', insns: %i[opt_ltlt])
+ end
+
+ def test_compile_insn_opt_and
+ assert_compile_twice('1 & 3', result_inspect: '1', insns: %i[opt_and])
+ end
+
+ def test_compile_insn_opt_or
+ assert_compile_twice('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: '221', success_count: 1, call_threshold: 2, 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({ 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: 3, call_threshold: 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_twice("{ '1' => 2 }['1']", result_inspect: '2', insns: %i[opt_aref_with])
+ end
+
+ def test_compile_insn_opt_aset
+ assert_compile_twice("#{<<~"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_twice("#{<<~"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_twice('[].empty?', result_inspect: 'true', insns: %i[opt_empty_p])
+ end
+
+ def test_compile_insn_opt_succ
+ assert_compile_twice('1.succ', result_inspect: '2', insns: %i[opt_succ])
+ end
+
+ def test_compile_insn_opt_not
+ assert_compile_twice('!!true', result_inspect: 'true', insns: %i[opt_not])
+ end
+
+ def test_compile_insn_opt_regexpmatch2
+ assert_compile_twice("/true/ =~ 'true'", result_inspect: '0', insns: %i[opt_regexpmatch2])
+ assert_compile_twice("'true' =~ /true/", result_inspect: '0', insns: %i[opt_regexpmatch2])
+ end
+
+ def test_compile_insn_invokebuiltin
+ iseq = eval(EnvUtil.invoke_ruby(['-e', <<~'EOS'], '', true).first)
+ p RubyVM::InstructionSequence.of([].method(:sample)).to_a
+ EOS
+ insns = collect_insns(iseq)
+ mark_tested_insn(:invokebuiltin, used_insns: insns)
+ assert_eval_with_jit('print [].sample(1); print [].sample(1)', stdout: '[][]', success_count: 1)
+ 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");print "\x00".unpack("c")', stdout: '[0][0]', success_count: 1)
+ end
+
+ def test_compile_insn_checkmatch
+ assert_compile_twice("#{<<~"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: 'hellohello', success_count: 1)
+ begin;
+ def test(arg = 'hello')
+ print arg
+ end
+ test
+ test
+ end;
+ end
+
+ def test_mjit_output
+ out, err = eval_with_jit('4.times { puts "MJIT" }', verbose: 1, call_threshold: 2)
+ assert_equal("MJIT\n" * 4, out)
+ assert_match(/^#{JIT_SUCCESS_PREFIX}: block in <main>@-e:1$/, err)
+ assert_match(/^Successful MJIT finish$/, err)
+ end
+
+ def test_nothing_to_unload_with_jit_wait
+ omit 'unload_units is removed for now'
+ 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
+ omit 'unload_units is removed for now'
+ 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
+ omit 'unload_units is removed for now'
+ 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, call_threshold: 2, 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
+ arr
+ p arr
+ end;
+ end
+
+ def test_local_stack_on_exception
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '33', success_count: 2)
+ begin;
+ def b
+ raise
+ rescue
+ 2
+ end
+
+ def a
+ # Calling #b should be vm_exec, not direct jit_exec.
+ # Otherwise `1` on local variable would be purged.
+ 1 + b
+ end
+
+ print a
+ print a
+ end;
+ end
+
+ def test_local_stack_with_sp_motion_by_blockargs
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '11', 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
+ print a
+ end;
+ end
+
+ def test_catching_deep_exception
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '11', 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'])
+ print wrapper(['1'], ['2'])
+ end;
+ end
+
+ def test_inlined_builtin_methods
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 1, call_threshold: 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: 1, recompile_count: 1, call_threshold: 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: 4, recompile_count: 2, call_threshold: 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: 4, call_threshold: 2)
+ 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: 1, call_threshold: 2)
+ 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, call_threshold: 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: 3, call_threshold: 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: 3, call_threshold: 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, call_threshold: 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.0", success_count: 1, call_threshold: 2)
+ begin;
+ def test(foo)
+ ".#{foo unless foo == 1}" if true
+ end
+ print test(0)
+ 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;"}", call_threshold: 2)
+ 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\ntrue\n", success_count: 2, call_threshold: 2)
+ begin;
+ class Integer
+ remove_method :zero?
+ def zero?
+ self == 0
+ end
+ end
+
+ 4.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\n70.0\n", success_count: 2, call_threshold: 2)
+ begin;
+ def multiply(a, b)
+ a *= b
+ end
+
+ 4.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, call_threshold: 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, call_threshold: 2)
+ begin;
+ RubyVM::MJIT.pause
+ proc {}.call
+ end;
+ end
+
+ def test_not_cancel_by_tracepoint_class
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 3, call_threshold: 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, call_threshold: 2)
+ begin;
+ TracePoint.new(:line) {}.enable
+ 2.times {}
+ end;
+ end
+
+ def test_cancel_by_bop_redefinition
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 0, call_threshold: 2)
+ begin;
+ class Integer
+ def <(x)
+ true
+ end
+ end
+ 2.times {}
+ end;
+ end
+
+ def test_caller_locations_without_catch_table
+ out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", call_threshold: 2)
+ 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_jit_failure
+ _, err = Dir.mktmpdir("jit_test_jit_failure") do |dir|
+ eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~"end;"}", call_threshold: 2, verbose: 1)
+ begin;
+ 2.times do
+ class A
+ end
+ end
+ end;
+ end
+ assert_match(/^MJIT warning: .+ unsupported instruction: defineclass/, err)
+ end
+
+ private
+
+ # The shortest way to test one proc
+ def assert_compile_twice(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("test = proc {#{script}}; p test.call; p test.call", stdout: "#{result_inspect}\n#{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, call_threshold: 2, max_cache: 1000, insns: [], uplevel: 1, ignorable_patterns: [])
+ out, err = eval_with_jit(script, verbose: 1, call_threshold: call_threshold, 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, call_threshold: call_threshold, 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
new file mode 100644
index 0000000000..0b50acc68d
--- /dev/null
+++ b/test/ruby/test_mjit_debug.rb
@@ -0,0 +1,17 @@
+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 4722fa22e0..24785affa0 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -784,6 +784,18 @@ class TestModule < Test::Unit::TestCase
assert_equal([:m1, :m0, :m, :sc, :m1, :m0, :c], sc.new.m)
end
+ def test_include_into_module_after_prepend_bug_20871
+ bar = Module.new{def bar; 'bar'; end}
+ foo = Module.new{def foo; 'foo'; end}
+ m = Module.new
+ c = Class.new{include m}
+ m.prepend bar
+ Class.new{include m}
+ m.include foo
+ assert_include c.ancestors, foo
+ assert_equal "foo", c.new.foo
+ end
+
def test_protected_include_into_included_module
m1 = Module.new do
def other_foo(other)
@@ -1736,8 +1748,6 @@ 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
@@ -2878,7 +2888,6 @@ class TestModule < Test::Unit::TestCase
def test_invalid_attr
%W[
- foo=
foo?
@foo
@@foo
@@ -3183,7 +3192,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?
+ omit "Investigating trunk-mjit failure on ci.rvm.jp" if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
m = Module.new
m.module_eval "A = 1", __FILE__, line = __LINE__
e = assert_raise_with_message(TypeError, /is not a module/) {
@@ -3348,7 +3357,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 /) {
+ assert_raise_with_message(NoMethodError, "private method `#{method}' called for main:Object") {
recv = self
recv.#{method}
}
diff --git a/test/ruby/test_nomethod_error.rb b/test/ruby/test_nomethod_error.rb
index 0306535943..321b7ccab2 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 an instance of String"
+ msg = "undefined method `#{id}' for \"#{str}\":String"
assert_raise_with_message(NoMethodError, Regexp.compile(Regexp.quote(msg)), bug3237) do
str.__send__(id)
end
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index 0bb9e633a1..26256b80db 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -355,41 +355,6 @@ 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
@@ -457,18 +422,6 @@ 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
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index 70b6bde6ed..88de3fa8b9 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -451,17 +451,6 @@ class TestRubyOptimization < Test::Unit::TestCase
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;'}"
@@ -535,7 +524,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::RJIT) && RubyVM::RJIT.enabled?
+ omit 'currently JIT-ed code always creates a new stack frame' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
bug16161 = '[ruby-core:94881]'
tailcall("#{<<-"begin;"}\n#{<<~"end;"}")
diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb
index 1ce46e8916..0ee36857ba 100644
--- a/test/ruby/test_pack.rb
+++ b/test/ruby/test_pack.rb
@@ -1,13 +1,8 @@
# 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";
# Need the expression in here to force ary[5] to be numeric. This avoids
@@ -98,11 +93,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))
- case J_SIZE
- when 4
+ psize = [nil].pack('p').bytesize
+ if psize == 4
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("j"+mod))
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("J"+mod))
- when 8
+ elsif psize == 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
@@ -114,11 +109,10 @@ 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))
- case J_SIZE
- when 4
+ if psize == 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))
- when 8
+ elsif psize == 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
@@ -147,11 +141,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))
- case J_SIZE
- when 4
+ psize = [nil].pack('p').bytesize
+ if psize == 4
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("j"+mod))
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("J"+mod))
- when 8
+ elsif psize == 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
@@ -163,11 +157,10 @@ 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))
- case J_SIZE
- when 4
+ if psize == 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))
- when 8
+ elsif psize == 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
@@ -203,8 +196,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
@@ -449,6 +442,7 @@ 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*")
@@ -471,8 +465,10 @@ class TestPack < Test::Unit::TestCase
end if RbConfig::CONFIG['HAVE_LONG_LONG']
def test_pack_unpack_jJ
- case J_SIZE
- when 4
+ # 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
s1 = [67305985, -50462977].pack("j*")
s2 = [67305985, 4244504319].pack("J*")
assert_equal(s1, s2)
@@ -486,7 +482,7 @@ class TestPack < Test::Unit::TestCase
assert_equal(4, [1].pack("j").bytesize)
assert_equal(4, [1].pack("J").bytesize)
- when 8
+ elsif psize == 8
s1 = [578437695752307201, -506097522914230529].pack("j*")
s2 = [578437695752307201, 17940646550795321087].pack("J*")
assert_equal(s1, s2)
@@ -781,32 +777,32 @@ EXPECTED
end
def test_pack_garbage
- assert_raise(ArgumentError, %r%unknown pack directive '\*' in '\*U'$%) do
+ assert_warn(%r%unknown pack directive '\*' in '\*U'$%) do
assert_equal "\000", [0].pack("*U")
end
end
def test_unpack_garbage
- assert_raise(ArgumentError, %r%unknown unpack directive '\*' in '\*U'$%) do
+ assert_warn(%r%unknown unpack directive '\*' in '\*U'$%) do
assert_equal [0], "\000".unpack("*U")
end
end
def test_invalid_warning
- assert_raise(ArgumentError, /unknown pack directive ',' in ','/) {
+ assert_warning(/unknown pack directive ',' in ','/) {
[].pack(",")
}
- assert_raise(ArgumentError, /\A[ -~]+\Z/) {
+ assert_warning(/\A[ -~]+\Z/) {
[].pack("\x7f")
}
- assert_raise(ArgumentError, /\A(.* in '\u{3042}'\n)+\z/) {
+ assert_warning(/\A(.* in '\u{3042}'\n)+\z/) {
[].pack("\u{3042}")
}
- assert_raise(ArgumentError, /\A.* in '.*U'\Z/) {
+ assert_warning(/\A.* in '.*U'\Z/) {
assert_equal "\000", [0].pack("\0U")
}
- assert_raise(ArgumentError, /\A.* in '.*U'\Z/) {
+ assert_warning(/\A.* in '.*U'\Z/) {
"\000".unpack("\0U")
}
end
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index c2f02ff809..ca9c305639 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -14,7 +14,6 @@ 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
@@ -453,44 +452,10 @@ class TestParse < Test::Unit::TestCase
end
def test_define_singleton_error
- 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
+ assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /singleton method for literals/) do
+ begin;
+ def ("foo").foo; end
+ end;
end
end
@@ -681,7 +646,6 @@ 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
@@ -722,16 +686,6 @@ 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
@@ -889,6 +843,7 @@ x = __ENCODING__
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")}
@@ -896,10 +851,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(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(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("defined?(1); nil")}
assert_equal 1, x
@@ -907,14 +862,12 @@ x = __ENCODING__
end
def test_assign_in_conditional
- # multiple assignment
assert_warning(/`= literal' in conditional/) do
eval <<-END, nil, __FILE__, __LINE__+1
(x, y = 1, 2) ? 1 : 2
END
end
- # instance variable assignment
assert_warning(/`= literal' in conditional/) do
eval <<-END, nil, __FILE__, __LINE__+1
if @x = true
@@ -924,71 +877,6 @@ 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
@@ -1072,30 +960,6 @@ 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|
@@ -1242,40 +1106,31 @@ x = __ENCODING__
end;
end
- def test_heredoc_interpolation
- var = 1
-
- v1 = <<~HEREDOC
- something
- #{"/#{var}"}
- HEREDOC
+ def test_heredoc_interpolation
+ var = 1
- v2 = <<~HEREDOC
- something
- #{_other = "/#{var}"}
- HEREDOC
-
- v3 = <<~HEREDOC
- something
- #{("/#{var}")}
- HEREDOC
+ v1 = <<~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
+ v2 = <<~HEREDOC
+ something
+ #{_other = "/#{var}"}
+ HEREDOC
- def test_heredoc_unterminated_interpolation
- code = <<~'HEREDOC'
- <<A+1
- #{
- HEREDOC
+ v3 = <<~HEREDOC
+ something
+ #{("/#{var}")}
+ HEREDOC
- assert_syntax_error(code, /can't find string "A"/)
- 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_unexpected_token_error
assert_syntax_error('"x"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', /unexpected/)
@@ -1285,8 +1140,6 @@ 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
@@ -1574,29 +1427,9 @@ 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 8e2806581c..0337e5d945 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.formatter=nil)
+ if defined?(DidYouMean)
@original_formatter = DidYouMean.formatter
DidYouMean.formatter = NullFormatter.new
end
end
def teardown
- if defined?(DidYouMean.formatter=nil)
+ if defined?(DidYouMean)
DidYouMean.formatter = @original_formatter
end
end
@@ -109,12 +109,16 @@ 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
@@ -796,10 +800,6 @@ END
true
end
end
-
- assert_syntax_error(%q{
- 0 => [a, *a]
- }, /duplicated variable name/)
end
def test_find_pattern
@@ -868,10 +868,6 @@ END
false
end
end
-
- assert_syntax_error(%q{
- 0 => [*a, a, b, *b]
- }, /duplicated variable name/)
end
def test_hash_pattern
@@ -1161,7 +1157,7 @@ END
end
end
- bug18890 = assert_warning(/(?:.*:[47]: warning: possibly useless use of a literal in void context\n){2}/) do
+ bug18890 = assert_warning(/(?:.*:[47]: warning: unused literal ignored\n){2}/) do
eval("#{<<~';;;'}")
proc do |i|
case i
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index 8d6ebf5dcb..35455ecd5e 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -168,6 +168,24 @@ class TestProc < Test::Unit::TestCase
assert_operator(procs.map(&:hash).uniq.size, :>=, 500)
end
+ def test_hash_does_not_change_after_compaction
+ # [Bug #20853]
+ [
+ "proc {}", # iseq backed proc
+ "{}.to_proc", # ifunc backed proc
+ ":hello.to_proc", # symbol backed proc
+ ].each do |proc|
+ assert_separately([], <<~RUBY)
+ p1 = #{proc}
+ hash = p1.hash
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_equal(hash, p1.hash, "proc is `#{proc}`")
+ RUBY
+ end
+ end
+
def test_block_par
assert_equal(10, Proc.new{|&b| b.call(10)}.call {|x| x})
assert_equal(12, Proc.new{|a,&b| b.call(a)}.call(12) {|x| x})
@@ -289,6 +307,7 @@ 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?)
@@ -298,21 +317,47 @@ class TestProc < Test::Unit::TestCase
assert_equal(true, Proc.new(&l).lambda?)
end
- def helper_test_warn_lambda_with_passed_block &b
+ def self.helper_test_warn_lamda_with_passed_block &b
lambda(&b)
end
- def test_lambda_warning_pass_proc
- assert_raise(ArgumentError) do
- b = proc{}
- 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 test_lambda_warning_pass_block
- assert_raise(ArgumentError) do
- helper_test_warn_lambda_with_passed_block{}
- 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{}
+ 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)
end
def test_curry_ski_fib
@@ -388,15 +433,6 @@ 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
diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index d9804aaa57..f48c4982c2 100644
--- a/test/ruby/test_process.rb
+++ b/test/ruby/test_process.rb
@@ -272,7 +272,7 @@ class TestProcess < Test::Unit::TestCase
end;
end
- MANDATORY_ENVS = %w[RUBYLIB RJIT_SEARCH_BUILD_DIR]
+ MANDATORY_ENVS = %w[RUBYLIB MJIT_SEARCH_BUILD_DIR]
case RbConfig::CONFIG['target_os']
when /linux/
MANDATORY_ENVS << 'LD_PRELOAD'
@@ -665,7 +665,6 @@ 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,21 +682,15 @@ 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")
@@ -710,25 +703,14 @@ 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
@@ -923,15 +905,29 @@ class TestProcess < Test::Unit::TestCase
}
end
- def test_popen_fork
- IO.popen("-") {|io|
- if !io
- puts "fooo"
- else
- assert_equal("fooo\n", io.read)
+ if Process.respond_to?(:fork)
+ def test_popen_fork
+ IO.popen("-") do |io|
+ if !io
+ puts "fooo"
+ else
+ assert_equal("fooo\n", io.read)
+ end
end
- }
- rescue NotImplementedError
+ end
+
+ def test_popen_fork_ensure
+ IO.popen("-") do |io|
+ if !io
+ STDERR.reopen(STDOUT)
+ raise "fooo"
+ else
+ assert_empty io.read
+ end
+ end
+ rescue RuntimeError
+ abort "[Bug #20995] should not reach here"
+ end
end
def test_fd_inheritance
@@ -1442,11 +1438,6 @@ 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")
@@ -1455,15 +1446,8 @@ class TestProcess < Test::Unit::TestCase
assert_equal(s, s)
assert_equal(s, s.to_i)
- 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(s.to_i & 0x55555555, s & 0x55555555)
+ assert_equal(s.to_i >> 1, s >> 1)
assert_equal(false, s.stopped?)
assert_equal(nil, s.stopsig)
@@ -1576,8 +1560,6 @@ 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
@@ -1726,6 +1708,11 @@ 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
@@ -1744,7 +1731,7 @@ class TestProcess < Test::Unit::TestCase
Process.wait pid
assert_send [sig_r, :wait_readable, 5], 'self-pipe not readable'
end
- if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # checking -DRJIT_FORCE_ENABLE. It may trigger extra SIGCHLD.
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # checking -DMJIT_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]"
@@ -1815,20 +1802,14 @@ class TestProcess < Test::Unit::TestCase
exs << Errno::EINVAL if windows?
exs << Errno::E2BIG if defined?(Errno::E2BIG)
opts = {[STDOUT, STDERR]=>File::NULL}
- if defined?(Process::RLIMIT_NPROC)
- opts[:rlimit_nproc] = /openbsd/i =~ RUBY_PLATFORM ? 64 : 128
- end
+ opts[:rlimit_nproc] = 128 if defined?(Process::RLIMIT_NPROC)
EnvUtil.suppress_warning do
assert_raise(*exs, mesg) do
begin
loop do
Process.spawn(cmds.join(sep), opts)
min = [cmds.size, min].max
- begin
- cmds *= 100
- rescue ArgumentError
- raise NoMemoryError
- end
+ cmds *= 100
end
rescue NoMemoryError
size = cmds.size
@@ -1870,6 +1851,8 @@ class TestProcess < Test::Unit::TestCase
end
def test_daemon_noclose
+ pend "macOS 15 is not working with this test" if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`
+
data = IO.popen("-", "r+") do |f|
break f.read if f
Process.daemon(false, true)
@@ -2188,9 +2171,7 @@ EOS
t3 = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
assert_operator(t1, :<=, t2)
assert_operator(t2, :<=, t3)
- assert_raise_with_message(Errno::EINVAL, /:foo/) do
- Process.clock_gettime(:foo)
- end
+ assert_raise(Errno::EINVAL) { Process.clock_gettime(:foo) }
end
def test_clock_gettime_unit
@@ -2295,9 +2276,7 @@ EOS
rescue Errno::EINVAL
else
assert_kind_of(Integer, r)
- assert_raise_with_message(Errno::EINVAL, /:foo/) do
- Process.clock_getres(:foo)
- end
+ assert_raise(Errno::EINVAL) { Process.clock_getres(:foo) }
end
def test_clock_getres_constants
@@ -2384,7 +2363,7 @@ EOS
end
def test_deadlock_by_signal_at_forking
- assert_separately(%W(- #{RUBY}), <<-INPUT, timeout: 100)
+ assert_separately(%W(--disable=gems - #{RUBY}), <<-INPUT, timeout: 100)
ruby = ARGV.shift
GC.start # reduce garbage
GC.disable # avoid triggering CoW after forks
@@ -2623,26 +2602,6 @@ 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]'
@@ -2716,73 +2675,84 @@ EOS
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
+ def _test_concurrent_group_and_pid_wait(nohang)
+ # 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?
+ assert_nil Process.waitpid(-1, Process::WNOHANG)
+ short_wpipe.close # Make short_pid exit
+
+ # The short pid has exited, so waitpid(-1) should pick that up.
+ exited_pid =
+ unless nohang
+ Process.waitpid(-1)
+ else
+ EnvUtil.timeout(5) do
+ loop do
+ pid = Process.waitpid(-1, Process::WNOHANG)
- assert_not_include(ObjectSpace.dump(obj), '"old":true')
- Process.warmup
- assert_include(ObjectSpace.dump(obj), '"old":true')
- end;
- end
+ break pid if pid
- 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
+ sleep 0.1
+ end
+ 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
+ assert_equal short_pid, exited_pid
- def test_warmup_frees_pages
- assert_separately([{"RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO" => "1.0"}, "-W0"], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- GC.start
+ # Terminate t1 for the next phase of the test.
+ t1.kill
+ t1.join
- TIMES = 10_000
- ary = Array.new(TIMES)
- TIMES.times do |i|
- ary[i] = Object.new
+ t2 = Thread.new do
+ Process.waitpid -1
+ rescue Errno::ECHILD
+ nil
end
- ary.clear
- ary = nil
-
- # Disable GC so we can make sure GC only runs in Process.warmup
- GC.disable
+ Thread.pass until t2.stop?
+ t3 = Thread.new do
+ Process.waitpid long_pid
+ rescue Errno::ECHILD
+ nil
+ end
+ Thread.pass until t3.stop?
- total_pages_before = GC.stat_heap.map { |_, v| v[:heap_eden_pages] + v[:heap_allocatable_pages] }
+ # 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)
- Process.warmup
+ def test_concurrent_group_and_pid_wait
+ _test_concurrent_group_and_pid_wait(false)
+ end if defined?(fork)
- # 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_nohang
+ _test_concurrent_group_and_pid_wait(true)
+ end if defined?(fork)
def test_handle_interrupt_with_fork
Thread.handle_interrupt(RuntimeError => :never) do
diff --git a/test/ruby/test_random_formatter.rb b/test/ruby/test_random_formatter.rb
index f927522d96..a5072099e1 100644
--- a/test/ruby/test_random_formatter.rb
+++ b/test/ruby/test_random_formatter.rb
@@ -75,47 +75,6 @@ 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)
@@ -124,20 +83,6 @@ 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 2aa69dc6a4..e64a93d9c2 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -2,6 +2,7 @@
require 'test/unit'
require 'delegate'
require 'timeout'
+require 'bigdecimal'
require 'date'
require 'rbconfig/sizeof'
@@ -496,151 +497,6 @@ class TestRange < Test::Unit::TestCase
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)
@@ -726,8 +582,6 @@ class TestRange < Test::Unit::TestCase
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
@@ -735,7 +589,7 @@ class TestRange < Test::Unit::TestCase
assert_not_operator('A'..'Z', :===, 'ana')
assert_operator('A'.., :===, 'ANA')
assert_operator(..'Z', :===, 'ANA')
- assert_operator(nil..nil, :===, 'ANA')
+ assert_raise(TypeError) {(nil..nil) === 'ANA'}
end
def test_eqq_time
@@ -987,10 +841,6 @@ class TestRange < Test::Unit::TestCase
assert_equal 41, (1...42).size
assert_equal 6, (1...6.3).size
assert_equal 5, (1.1...6).size
- assert_equal 3, (1..3r).size
- assert_equal 2, (1...3r).size
- assert_equal 3, (1..3.1r).size
- assert_equal 3, (1...3.1r).size
assert_equal 42, (1..42).each.size
assert_nil ("a"..."z").size
assert_nil ("a"...).size
@@ -1002,7 +852,6 @@ class TestRange < Test::Unit::TestCase
assert_equal Float::INFINITY, (...1).size
assert_equal Float::INFINITY, (...1.0).size
assert_nil ("a"...).size
- assert_nil (..."z").size
end
def test_bsearch_typechecks_return_values
@@ -1026,6 +875,9 @@ 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
@@ -1199,10 +1051,7 @@ 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 {} }
@@ -1227,81 +1076,6 @@ 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_refinement.rb b/test/ruby/test_refinement.rb
index d081bc9127..56f33ae00a 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -1606,35 +1606,18 @@ 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
@@ -1815,7 +1798,7 @@ class TestRefinement < Test::Unit::TestCase
assert_equal([int_refinement, str_refinement], m.refinements)
end
- def test_target
+ def test_refined_class
refinements = Module.new {
refine Integer do
end
@@ -1823,14 +1806,8 @@ class TestRefinement < Test::Unit::TestCase
refine String do
end
}.refinements
- 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
+ assert_equal(Integer, refinements[0].refined_class)
+ assert_equal(String, refinements[1].refined_class)
end
def test_warn_setconst_in_refinmenet
@@ -2649,46 +2626,6 @@ 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
-
private
def eval_using(mod, s)
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index c8caca2891..b385760b42 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -40,6 +40,19 @@ 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(/3\.3/) {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(/3\.3/) {Regexp.new(s, nil, "u")}
+ end
+ end
+
def test_ruby_dev_31309
assert_equal('Ruby', 'Ruby'.sub(/[^a-z]/i, '-'))
end
@@ -72,19 +85,6 @@ 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}/
@@ -324,9 +324,6 @@ 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)
@@ -470,13 +467,6 @@ 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])
@@ -713,18 +703,6 @@ class TestRegexp < Test::Unit::TestCase
}
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)})
@@ -749,18 +727,31 @@ class TestRegexp < Test::Unit::TestCase
assert_equal(1.0, Regexp.compile("", timeout: 1.0).timeout)
end
+ assert_deprecated_warning(/3\.3/) do
+ assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", nil, "n").encoding)
+ end
+ assert_deprecated_warning(/3\.3/) do
+ assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", nil, "n", timeout: 1).encoding)
+ end
+ assert_deprecated_warning(/3\.3/) do
+ assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
+ end
+ assert_deprecated_warning(/3\.3/) do
+ assert_equal(//n, Regexp.new("", nil, "n"))
+ end
+ assert_deprecated_warning(/3\.3/) do
+ assert_equal(arg_encoding_none, Regexp.new("", nil, "n").options)
+ end
+ assert_deprecated_warning(/3\.3/) do
+ assert_equal(arg_encoding_none, Regexp.new("", nil, "N").options)
+ end
+
assert_raise(RegexpError) { Regexp.new(")(") }
assert_raise(RegexpError) { Regexp.new('[\\40000000000') }
assert_raise(RegexpError) { Regexp.new('[\\600000000000.') }
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)
@@ -892,14 +883,6 @@ 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,
@@ -1406,109 +1389,30 @@ class TestRegexp < Test::Unit::TestCase
end
def test_unicode_age
- 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
+ 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}")
end
MatchData_A = eval("class MatchData_\u{3042} < MatchData; self; end")
@@ -1810,23 +1714,6 @@ class TestRegexp < Test::Unit::TestCase
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 test_bug_20453
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
@@ -1864,12 +1751,10 @@ class TestRegexp < Test::Unit::TestCase
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
@@ -1895,97 +1780,27 @@ class TestRegexp < Test::Unit::TestCase
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
+ def test_cache_optimization_exponential
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")
+ assert_nil(/^(a*)*$/ =~ "a" * 1000000 + "x")
end;
end
- def test_match_cache_positive_look_behind
+ def test_cache_optimization_square
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")
+ assert_nil(/^a*b?a*$/ =~ "a" * 1000000 + "x")
end;
end
- def test_cache_opcodes_initialize
+ def test_cache_index_initialize
str = 'test1-test2-test3-test4-test_5'
re = '^([0-9a-zA-Z\-/]*){1,256}$'
100.times do
@@ -1998,7 +1813,7 @@ class TestRegexp < Test::Unit::TestCase
assert_equal("10:0:0".match(pattern)[0], "10:0:0")
end
- def test_bug_19467 # [Bug #19467]
+ def test_bug_19467
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
begin;
@@ -2013,57 +1828,6 @@ class TestRegexp < Test::Unit::TestCase
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']
@@ -2071,17 +1835,7 @@ class TestRegexp < Test::Unit::TestCase
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 871912e491..1b93a42e42 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -209,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([], <<-INPUT, %w(:ok), [])
+ assert_in_out_err(['--disable-gems'], <<-INPUT, %w(:ok), [])
require "#{req}"
require "#{req}"
INPUT
@@ -227,7 +227,6 @@ 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
@@ -717,7 +716,7 @@ class TestRequire < Test::Unit::TestCase
Dir.mktmpdir {|tmp|
Dir.chdir(tmp) {
open("foo.rb", "w") {}
- assert_in_out_err([{"RUBYOPT"=>nil}], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
+ assert_in_out_err([{"RUBYOPT"=>nil}, '--disable-gems'], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
begin;
$:.replace([IO::NULL])
a = Object.new
@@ -745,7 +744,7 @@ class TestRequire < Test::Unit::TestCase
Dir.mktmpdir {|tmp|
Dir.chdir(tmp) {
open("foo.rb", "w") {}
- assert_in_out_err([{"RUBYOPT"=>nil}], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
+ assert_in_out_err([{"RUBYOPT"=>nil}, '--disable-gems'], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
begin;
$:.replace([IO::NULL])
a = Object.new
@@ -775,7 +774,7 @@ class TestRequire < Test::Unit::TestCase
open("foo.rb", "w") {}
Dir.mkdir("a")
open(File.join("a", "bar.rb"), "w") {}
- assert_in_out_err([], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7383)
+ assert_in_out_err(['--disable-gems'], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7383)
begin;
$:.replace([IO::NULL])
$:.#{add} "#{tmp}"
@@ -999,7 +998,7 @@ class TestRequire < Test::Unit::TestCase
def test_require_with_public_method_missing
# [Bug #19793]
- assert_separately(["-W0", "-rtempfile"], __FILE__, __LINE__, <<~RUBY)
+ assert_separately(["-W0", "--disable-gems", "-rtempfile"], __FILE__, __LINE__, <<~RUBY)
GC.stress = true
class Object
diff --git a/test/ruby/test_require_lib.rb b/test/ruby/test_require_lib.rb
index a88279727e..95fa3f29e1 100644
--- a/test/ruby/test_require_lib.rb
+++ b/test/ruby/test_require_lib.rb
@@ -1,26 +1,25 @@
-# frozen_string_literal: true
+# frozen_string_literal: false
require 'test/unit'
class TestRequireLib < Test::Unit::TestCase
- libdir = __dir__ + '/../../lib'
+ TEST_RATIO = ENV["TEST_REQUIRE_THREAD_RATIO"]&.tap {|s|break s.to_f} || 0.05 # testing all files needs too long time...
- # .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|
+ 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)
define_method "test_thread_size:#{lib}" do
- assert_separately(['-W0'], "#{<<~"begin;"}\n#{<<~"end;"}")
+ assert_separately(['--disable-gems', '-W0'], "#{<<~"begin;"}\n#{<<~"end;"}")
begin;
n = Thread.list.size
- require #{lib.dump}
+ begin
+ require #{lib.dump}
+ rescue Exception
+ omit $!
+ end
assert_equal n, Thread.list.size
end;
end
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 38ca119a8f..b8e22b7c7d 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -7,12 +7,12 @@ require 'tempfile'
require_relative '../lib/jit_support'
class TestRubyOptions < Test::Unit::TestCase
- def self.rjit_enabled? = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ def self.mjit_enabled? = defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
def self.yjit_enabled? = defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
NO_JIT_DESCRIPTION =
- if rjit_enabled?
- RUBY_DESCRIPTION.sub(/\+RJIT /, '')
+ if mjit_enabled?
+ RUBY_DESCRIPTION.sub(/\+MJIT /, '')
elsif yjit_enabled?
RUBY_DESCRIPTION.sub(/\+YJIT( (dev|dev_nodebug|stats))? /, '')
else
@@ -74,7 +74,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=-2), "", [], /wrong limit for backtrace length/)
+ assert_in_out_err(%w(--backtrace-limit=-1), "", [], /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,22 +84,11 @@ 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.delete('RUBYOPT')
+ save_rubyopt = ENV['RUBYOPT']
+ ENV['RUBYOPT'] = nil
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), [])
@@ -110,36 +99,31 @@ class TestRubyOptions < Test::Unit::TestCase
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 -e) + ['p Warning[:performance]'], "", %w(false), [])
- assert_in_out_err(%w(-W:performance -e) + ['p Warning[:performance]'], "", %w(true), [])
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), [])
- assert_in_out_err(%w(-w -e) + ['p Warning[:performance]'], "", %w(false), [])
- assert_in_out_err(%w(-W -e) + ['p Warning[:performance]'], "", %w(false), [])
- code = 'puts "#{$VERBOSE}:#{Warning[:deprecated]}:#{Warning[:experimental]}:#{Warning[:performance]}"'
+ code = 'puts "#{$VERBOSE}:#{Warning[:deprecated]}:#{Warning[:experimental]}"'
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:false:true:false), [])
- assert_in_out_err(["-r#{t.path}", '-w', '-e', code], "", %w(true:true:true:false true:true:true:false), [])
- assert_in_out_err(["-r#{t.path}", '-W:deprecated', '-e', code], "", %w(false:true:true:false false:true:true:false), [])
- assert_in_out_err(["-r#{t.path}", '-W:no-experimental', '-e', code], "", %w(false:false:false:false false:false:false:false), [])
- assert_in_out_err(["-r#{t.path}", '-W:performance', '-e', code], "", %w(false:false:true:true false:false:true:true), [])
+ 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), [])
end
ensure
ENV['RUBYOPT'] = save_rubyopt
end
def test_debug
- assert_in_out_err(["-de", "p $DEBUG"], "", %w(true), [])
+ assert_in_out_err(["--disable-gems", "-de", "p $DEBUG"], "", %w(true), [])
- assert_in_out_err(["--debug", "-e", "p $DEBUG"],
+ assert_in_out_err(["--disable-gems", "--debug", "-e", "p $DEBUG"],
"", %w(true), [])
- assert_in_out_err(["--debug-", "-e", "p $DEBUG"], "", %w(), /invalid option --debug-/)
+ assert_in_out_err(["--disable-gems", "--debug-", "-e", "p $DEBUG"], "", %w(), /invalid option --debug-/)
end
q = Regexp.method(:quote)
@@ -153,21 +137,21 @@ class TestRubyOptions < Test::Unit::TestCase
end
private_constant :VERSION_PATTERN
- VERSION_PATTERN_WITH_RJIT =
+ VERSION_PATTERN_WITH_JIT =
case RUBY_ENGINE
when 'ruby'
- /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+RJIT (\+MN )?\[#{q[RUBY_PLATFORM]}\]$/
+ /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+MJIT \[#{q[RUBY_PLATFORM]}\]$/
else
VERSION_PATTERN
end
- private_constant :VERSION_PATTERN_WITH_RJIT
+ private_constant :VERSION_PATTERN_WITH_JIT
def test_verbose
assert_in_out_err([{'RUBY_YJIT_ENABLE' => nil}, "-vve", ""]) do |r, e|
assert_match(VERSION_PATTERN, r[0])
- if self.class.rjit_enabled? && !JITSupport.rjit_force_enabled?
+ if self.class.mjit_enabled? && !JITSupport.mjit_force_enabled?
assert_equal(NO_JIT_DESCRIPTION, r[0])
- elsif self.class.yjit_enabled? && !JITSupport.yjit_force_enabled?
+ elsif self.class.yjit_enabled? && !yjit_force_enabled? # checking -DYJIT_FORCE_ENABLE
assert_equal(NO_JIT_DESCRIPTION, r[0])
else
assert_equal(RUBY_DESCRIPTION, r[0])
@@ -188,15 +172,10 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_enable
- if JITSupport.yjit_supported?
+ if JITSupport.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'/)
@@ -210,14 +189,14 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(%w(--disable foobarbazqux -e) + [""], "", [],
/unknown argument for --disable: `foobarbazqux'/)
assert_in_out_err(%w(--disable), "", [], /missing argument for --disable/)
- assert_in_out_err(%w(-e) + ['p defined? Gem'], "", ["nil"], [])
+ assert_in_out_err(%w(--disable-gems -e) + ['p defined? Gem'], "", ["nil"], [])
assert_in_out_err(%w(--disable-did_you_mean -e) + ['p defined? DidYouMean'], "", ["nil"], [])
- assert_in_out_err(%w(-e) + ['p defined? DidYouMean'], "", ["nil"], [])
+ assert_in_out_err(%w(--disable-gems -e) + ['p defined? DidYouMean'], "", ["nil"], [])
end
def test_kanji
assert_in_out_err(%w(-KU), "p '\u3042'") do |r, e|
- assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ assert_equal("\"\u3042\"", r.join('').force_encoding(Encoding::UTF_8))
end
line = '-eputs"\xc2\xa1".encoding'
env = {'RUBYOPT' => nil}
@@ -233,29 +212,31 @@ 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.rjit_enabled? || self.class.yjit_enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
+ elsif self.class.mjit_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
- def test_rjit_disabled_version
- return unless JITSupport.rjit_supported?
- return if JITSupport.yjit_force_enabled?
+ return if RbConfig::CONFIG["MJIT_SUPPORT"] == 'no'
+ return if yjit_force_enabled?
- env = { 'RUBY_YJIT_ENABLE' => nil } # unset in children
[
- %w(--version --rjit --disable=rjit),
- %w(--version --enable=rjit --disable=rjit),
- %w(--version --enable-rjit --disable-rjit),
+ %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?),
].each do |args|
assert_in_out_err([env] + args) do |r, e|
assert_match(VERSION_PATTERN, r[0])
@@ -263,43 +244,31 @@ class TestRubyOptions < Test::Unit::TestCase
assert_equal([], e)
end
end
- end
-
- 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])
+ 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)
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=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/, warning)
- end
-
def test_eval
assert_in_out_err(%w(-e), "", [], /no code specified for -e \(RuntimeError\)/)
end
@@ -337,15 +306,27 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_chdir
+ omit "not working on MinGW" if /mingw/ =~ RUBY_PLATFORM
assert_in_out_err(%w(-C), "", [], /Can't chdir/)
assert_in_out_err(%w(-C test_ruby_test_rubyoptions_foobarbazqux), "", [], /Can't chdir/)
d = Dir.tmpdir
assert_in_out_err(["-C", d, "-e", "puts Dir.pwd"]) do |r, e|
- assert_file.identical?(r.join, d)
+ assert_file.identical?(r.join(''), d)
assert_equal([], e)
end
+
+ Dir.mktmpdir(d) do |base|
+ # "test" in Japanese and N'Ko
+ test = base + "/\u{30c6 30b9 30c8}_\u{7e1 7ca 7dd 7cc 7df 7cd 7eb}"
+ Dir.mkdir(test)
+ assert_in_out_err(["-C", base, "-C", File.basename(test), "-e", "puts Dir.pwd"]) do |r, e|
+ assert_file.identical?(r.join(''), test)
+ assert_equal([], e)
+ end
+ Dir.rmdir(test)
+ end
end
def test_yydebug
@@ -381,25 +362,7 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_syntax_check
- 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"], [])
+ assert_in_out_err(%w(-c -e a=1+1 -e !a), "", ["Syntax OK"], [])
end
def test_invalid_option
@@ -447,11 +410,12 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(%w(), "p Warning[:experimental]", ["false"])
ENV['RUBYOPT'] = '-W:qux'
assert_in_out_err(%w(), "", [], /unknown warning category: `qux'/)
-
- ENV['RUBYOPT'] = 'w'
- assert_in_out_err(%w(), "p $VERBOSE", ["true"])
ensure
- ENV['RUBYOPT'] = rubyopt_orig
+ if rubyopt_orig
+ ENV['RUBYOPT'] = rubyopt_orig
+ else
+ ENV.delete('RUBYOPT')
+ end
end
def test_search
@@ -789,7 +753,7 @@ class TestRubyOptions < Test::Unit::TestCase
-e:(?:1:)?\s\[BUG\]\sSegmentation\sfault.*\n
)x,
%r(
- #{ Regexp.quote((TestRubyOptions.rjit_enabled? && !JITSupport.rjit_force_enabled?) ? NO_JIT_DESCRIPTION : RUBY_DESCRIPTION) }\n\n
+ #{ Regexp.quote((TestRubyOptions.mjit_enabled? && !JITSupport.mjit_force_enabled?) ? NO_JIT_DESCRIPTION : RUBY_DESCRIPTION) }\n\n
)x,
%r(
(?:--\s(?:.+\n)*\n)?
@@ -806,9 +770,6 @@ class TestRubyOptions < Test::Unit::TestCase
)?
)x,
%r(
- (?:--\sThreading(?:.+\n)*\n)?
- )x,
- %r(
(?:--\sMachine(?:.+\n)*\n)?
)x,
%r(
@@ -824,32 +785,32 @@ class TestRubyOptions < Test::Unit::TestCase
)?
)x,
]
-
- KILL_SELF = "Process.kill :SEGV, $$"
end
- def assert_segv(args, message=nil, list: SEGVTest::ExpectedStderrList, **opt)
+ def assert_segv(args, message=nil)
+ pend "macOS 15 is not working with this assertion" if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`
+
+ omit if ENV['RUBY_ON_BUG']
+
# 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})
- args.unshift(env)
test_stdin = ""
+ opt = SEGVTest::ExecOptions.dup
+ list = SEGVTest::ExpectedStderrList
- assert_in_out_err(args, test_stdin, //, list, encoding: "ASCII-8BIT",
- **SEGVTest::ExecOptions, **opt)
+ assert_in_out_err(args, test_stdin, //, list, encoding: "ASCII-8BIT", **opt)
end
def test_segv_test
- assert_segv(["--disable-gems", "-e", SEGVTest::KILL_SELF])
+ assert_segv(["--disable-gems", "-e", "Process.kill :SEGV, $$"])
end
def test_segv_loaded_features
bug7402 = '[ruby-core:49573]'
- status = assert_segv(['-e', "END {#{SEGVTest::KILL_SELF}}",
+ status = assert_segv(['-e', 'END {Process.kill :SEGV, $$}',
'-e', 'class Bogus; def to_str; exit true; end; end',
'-e', '$".clear',
'-e', '$".unshift Bogus.new',
@@ -863,70 +824,10 @@ 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]; #{SEGVTest::KILL_SELF}", t.path], bug7597)
+ assert_segv(["--disable-gems", "-e", "$0=ARGV[0]; Process.kill :SEGV, $$", t.path], bug7597)
}
end
- def assert_crash_report(path, cmd = nil)
- 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)
- 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
- assert_crash_report("%e.%f.%p.log") do |status, report|
- assert_equal("#{File.basename(EnvUtil.rubybin)}.-e.#{status.pid}.log", report)
- end
- end
-
- def test_crash_report_script
- assert_crash_report("%e.%f.%p.log", "bug.rb") do |status, report|
- assert_equal("#{File.basename(EnvUtil.rubybin)}.bug.rb.#{status.pid}.log", report)
- end
- end
-
- def test_crash_report_executable_path
- omit if EnvUtil.rubybin.size > 245
- assert_crash_report("%E.%p.log") do |status, report|
- assert_equal("#{EnvUtil.rubybin.tr('/', '!')}.#{status.pid}.log", report)
- end
- end
-
- def test_crash_report_script_path
- assert_crash_report("%F.%p.log", "test/bug.rb") do |status, report|
- assert_equal("test!bug.rb.#{status.pid}.log", report)
- end
- 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
- env = {"RUBY_CRASH_REPORT"=>"| #{echo} %e:%f:%p", "RUBY_ON_BUG"=>nil}
- assert_in_out_err([env], SEGVTest::KILL_SELF,
- encoding: "ASCII-8BIT",
- **SEGVTest::ExecOptions) do |stdout, stderr, status|
- assert_empty(stderr)
- assert_equal(["#{File.basename(EnvUtil.rubybin)}:-:#{status.pid}"], stdout)
- end
- end
-
def test_DATA
Tempfile.create(["test_ruby_test_rubyoption", ".rb"]) {|t|
t.puts "puts DATA.read.inspect"
@@ -1073,6 +974,7 @@ class TestRubyOptions < Test::Unit::TestCase
# Since the codepage is shared all processes per conhost.exe, do
# not chcp, or parallel test may break.
def test_locale_codepage
+ omit "not working on MinGW" if /mingw/ =~ RUBY_PLATFORM
locale = Encoding.find("locale")
list = %W"\u{c7} \u{452} \u{3066 3059 3068}"
list.each do |s|
@@ -1241,9 +1143,16 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err([IO::NULL], success: true)
end
- 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/)
+ def test_mjit_debug
+ if JITSupport.supported?
+ 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/)
end
end
diff --git a/test/ruby/test_rubyvm_mjit.rb b/test/ruby/test_rubyvm_mjit.rb
new file mode 100644
index 0000000000..73f43af7f9
--- /dev/null
+++ b/test/ruby/test_rubyvm_mjit.rb
@@ -0,0 +1,105 @@
+# 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, call_threshold: 2, wait: false)
+ i = 0
+ while i < 5
+ eval("def mjit#{i}; end; mjit#{i}; 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, call_threshold: 2, wait: false)
+ def a() end; a; a
+ def b() end; b; 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}```",
+ )
+ end
+
+ def test_pause_after_waitall
+ out, err = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 2, wait: false)
+ def test() = nil
+ test
+ 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, call_threshold: 2, 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, call_threshold: 2, 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, call_threshold: 2, 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 a90c885247..0e77d22b03 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -93,6 +93,22 @@ class TestSetTraceFunc < Test::Unit::TestCase
assert_equal([[:req]], parameters)
end
+ def test_c_call_aliased_method
+ # [Bug #20915]
+ klass = Class.new do
+ alias_method :new_method, :method
+ end
+
+ instance = klass.new
+ parameters = nil
+
+ TracePoint.new(:c_call) do |tp|
+ parameters = tp.parameters
+ end.enable { instance.new_method(:to_s) }
+
+ assert_equal([[:req]], parameters)
+ end
+
def test_call
events = []
name = "#{self.class}\##{__method__}"
@@ -358,18 +374,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] if file == name
+ events[:set] << [event, lineno, mid, klass, :set]
}
prc = prc # suppress warning
prc2 = Proc.new { |event, file, lineno, mid, binding, klass|
- events[:add] << [event, lineno, mid, klass, :add] if file == name
+ events[:add] << [event, lineno, mid, klass, :add]
}
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)
@@ -504,7 +520,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
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'
3: }
- 4: [1].each{|;_local_var| _local_var = :inner
+ 4: 1.times{|;_local_var| _local_var = :inner
5: tap{}
6: }
7: class XYZZY
@@ -531,10 +547,10 @@ class TestSetTraceFunc < Test::Unit::TestCase
answer_events = [
#
[:line, 4, 'xyzzy', self.class, method, self, :outer, :nothing],
- [:c_call, 4, 'xyzzy', Array, :each, [1], nil, :nothing],
+ [:c_call, 4, 'xyzzy', Integer, :times, 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", Array, :each, [1], nil, [1]],
+ [:c_return, 4, "xyzzy", Integer, :times, 1, nil, 1],
[:line, 7, 'xyzzy', self.class, method, self, :outer, :nothing],
[:c_call, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, nil, :nothing],
[:c_return, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, nil, nil],
@@ -652,7 +668,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].map{|;_local_var| _local_var = :inner
+ 4: 1.times{|;_local_var| _local_var = :inner
5: tap{}
6: }
7: class XYZZY
@@ -968,55 +984,6 @@ 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
@@ -1056,7 +1023,7 @@ CODE
/return/ =~ tp.event ? tp.return_value : nil
]
}.enable{
- [1].map{
+ 1.times{
3
}
method_for_test_tracepoint_block{
@@ -1066,10 +1033,10 @@ CODE
# pp events
# expected_events =
[[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
- [:c_call, :map, Array, Array, nil],
+ [:c_call, :times, Integer, Integer, nil],
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 3],
- [:c_return, :map, Array, Array, [3]],
+ [:c_return, :times, Integer, Integer, 1],
[: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],
@@ -1372,7 +1339,7 @@ CODE
next if !target_thread?
events << tp.event
}.enable{
- [1].map{
+ 1.times{
3
}
method_for_test_tracepoint_block{
@@ -1394,7 +1361,7 @@ CODE
next if !target_thread?
events << tp.event
}.enable{
- [1].map{
+ 1.times{
3
}
method_for_test_tracepoint_block{
@@ -1753,7 +1720,7 @@ CODE
Bug10724.new
}
- assert_equal([:call, :call, :return, :return], evs)
+ assert_equal([:call, :return], evs)
end
require 'fiber'
@@ -1985,11 +1952,7 @@ CODE
def tp_return_value mid
ary = []
- 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{
+ TracePoint.new(:return, :b_return){|tp| next if !target_thread?; ary << [tp.event, tp.method_id, tp.return_value]}.enable{
send mid
}
ary.pop # last b_return event is not required.
@@ -2198,7 +2161,7 @@ CODE
q = Thread::Queue.new
t = Thread.new{
Thread.current.add_trace_func proc{|ev, file, line, *args|
- events << [ev, line] if file == __FILE__
+ events << [ev, line]
} # do not stop trace. They will be stopped at Thread termination.
q.push 1
_x = 1
@@ -2234,9 +2197,9 @@ CODE
}
# it is dirty hack. usually we shouldn't use such technique
Thread.pass until t.status == 'sleep'
- # When RJIT thread exists, t.status becomes 'sleep' even if it does not reach m2t_q.pop.
+ # When MJIT 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::RJIT) && RubyVM::RJIT.enabled?
+ sleep 1 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
t.add_trace_func proc{|ev, file, line, *args|
if file == __FILE__
@@ -2472,18 +2435,6 @@ 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|
@@ -2804,77 +2755,6 @@ CODE
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
diff --git a/test/ruby/test_shapes.rb b/test/ruby/test_shapes.rb
index ee99fbad6d..7db4d0998d 100644
--- a/test/ruby/test_shapes.rb
+++ b/test/ruby/test_shapes.rb
@@ -1,12 +1,8 @@
# 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 }
@@ -32,14 +28,6 @@ class TestShapes < Test::Unit::TestCase
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
@@ -121,464 +109,6 @@ class TestShapes < Test::Unit::TestCase
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;
@@ -622,42 +152,6 @@ class TestShapes < Test::Unit::TestCase
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
@@ -738,84 +232,6 @@ class TestShapes < Test::Unit::TestCase
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(GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT])
- 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
@@ -824,8 +240,6 @@ class TestShapes < Test::Unit::TestCase
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
@@ -835,7 +249,6 @@ class TestShapes < Test::Unit::TestCase
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
@@ -886,10 +299,7 @@ class TestShapes < Test::Unit::TestCase
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_shape_equal(RubyVM::Shape.root_shape, shape.parent)
+ assert_shape_equal(RubyVM::Shape.root_shape, RubyVM::Shape.of(TestObject.new).parent)
end
def test_str_has_root_shape
@@ -900,6 +310,10 @@ class TestShapes < Test::Unit::TestCase
assert_shape_equal(RubyVM::Shape.root_shape, RubyVM::Shape.of([]))
end
+ def test_hash_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
@@ -908,12 +322,7 @@ class TestShapes < Test::Unit::TestCase
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)
@@ -925,7 +334,7 @@ class TestShapes < Test::Unit::TestCase
shape = shape.parent
assert_equal(RubyVM::Shape.root_shape.id, shape.id)
- assert_equal(1, obj.instance_variable_get(:@a))
+ assert_equal(obj.instance_variable_get(:@a), 1)
end
def test_different_objects_make_same_transition
@@ -989,15 +398,6 @@ class TestShapes < Test::Unit::TestCase
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)
diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb
index 7877a35129..c5043eea59 100644
--- a/test/ruby/test_signal.rb
+++ b/test/ruby/test_signal.rb
@@ -323,6 +323,49 @@ 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 c453ecd350..3f821f7a5d 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -227,6 +227,10 @@ class TestSprintf < Test::Unit::TestCase
bug11766 = '[ruby-core:71806] [Bug #11766]'
assert_equal("x"*10+" 1.0", sprintf("x"*10+"%8.1f", 1r), bug11766)
+
+ require 'rbconfig/sizeof'
+ fmin, fmax = RbConfig::LIMITS.values_at("FIXNUM_MIN", "FIXNUM_MAX")
+ assert_match(/\A-\d+\.\d+\z/, sprintf("%f", Rational(fmin, fmax)))
end
def test_rational_precision
@@ -543,4 +547,12 @@ class TestSprintf < Test::Unit::TestCase
sprintf("%*s", RbConfig::LIMITS["INT_MIN"], "")
end
end
+
+ def test_binary_format_coderange
+ 1.upto(500) do |i|
+ str = sprintf("%*s".b, i, "\xe2".b)
+ refute_predicate str, :ascii_only?
+ assert_equal i, str.bytesize
+ end
+ end
end
diff --git a/test/ruby/test_stack.rb b/test/ruby/test_stack.rb
index 8a78848322..763aeb6bc2 100644
--- a/test/ruby/test_stack.rb
+++ b/test/ruby/test_stack.rb
@@ -18,6 +18,7 @@ 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 149c128ed4..f4ef6ccb6b 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -80,13 +80,6 @@ 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
@@ -107,7 +100,7 @@ class TestString < Test::Unit::TestCase
return unless @cls == String
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
-code = proc {('x'*100_000).__send__(:initialize, '')}
+code = proc {('x'*100000).__send__(:initialize, '')}
1_000.times(&code)
PREP
100_000.times(&code)
@@ -119,7 +112,7 @@ CODE
return unless @cls == String
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
-code = proc {0.to_s.__send__(:initialize, capacity: 100_000)}
+code = proc {0.to_s.__send__(:initialize, capacity: 10000)}
1_000.times(&code)
PREP
100_000.times(&code)
@@ -169,6 +162,15 @@ CODE
assert_raise(ArgumentError) { "foo"[] }
end
+ def test_AREF_underflow
+ require "rbconfig/sizeof"
+ assert_equal(nil, S("\u{3042 3044 3046}")[RbConfig::LIMITS["LONG_MIN"], 1])
+ end
+
+ def test_AREF_invalid_encoding
+ assert_equal(S("\x80"), S("A"*39+"\x80")[-1, 1])
+ end
+
def test_ASET # '[]='
s = S("FooBar")
s[0] = S('A')
@@ -597,8 +599,6 @@ 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
@@ -673,27 +673,6 @@ 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")))
@@ -908,18 +887,6 @@ 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")
@@ -1284,11 +1251,6 @@ 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
@@ -1332,15 +1294,6 @@ 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/, {}))
@@ -1368,9 +1321,6 @@ 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
@@ -1391,54 +1341,54 @@ CODE
end
def test_index
- assert_index(0, S("hello"), ?h)
- assert_index(1, S("hello"), S("ell"))
- assert_index(2, S("hello"), /ll./)
+ assert_equal(0, S("hello").index(?h))
+ assert_equal(1, S("hello").index(S("ell")))
+ assert_equal(2, S("hello").index(/ll./))
- assert_index(3, S("hello"), ?l, 3)
- assert_index(3, S("hello"), S("l"), 3)
- assert_index(3, S("hello"), /l./, 3)
+ 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(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, 3))
+ assert_nil(S("hello").index(S("z"), 3))
+ assert_nil(S("hello").index(/z./, 3))
- assert_index(nil, S("hello"), ?z)
- assert_index(nil, S("hello"), S("z"))
- assert_index(nil, S("hello"), /z./)
+ assert_nil(S("hello").index(?z))
+ assert_nil(S("hello").index(S("z")))
+ assert_nil(S("hello").index(/z./))
- 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"), //)
+ 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(//))
s = S("long") * 1000 << "x"
- assert_index(nil, s, S("y"))
- assert_index(4 * 1000, s, S("x"))
+ assert_nil(s.index(S("y")))
+ assert_equal(4 * 1000, s.index(S("x")))
s << "yx"
- assert_index(4 * 1000, s, S("x"))
- assert_index(4 * 1000, s, S("xyx"))
+ assert_equal(4 * 1000, s.index(S("x")))
+ assert_equal(4 * 1000, s.index(S("xyx")))
o = Object.new
def o.to_str; "bar"; end
- assert_index(3, S("foobarbarbaz"), o)
+ assert_equal(3, S("foobarbarbaz").index(o))
assert_raise(TypeError) { S("foo").index(Object.new) }
- assert_index(nil, S("foo"), //, -100)
- assert_index(nil, S("foo"), //, 4)
+ assert_nil(S("foo").index(//, -100))
+ assert_nil($~)
- assert_index(2, S("abcdbce"), /b\Kc/)
+ assert_equal(2, S("abcdbce").index(/b\Kc/))
- assert_index(0, S("ã“ã‚“ã«ã¡ã¯"), ?ã“)
- assert_index(1, S("ã“ã‚“ã«ã¡ã¯"), S("ã‚“ã«ã¡"))
- assert_index(2, S("ã“ã‚“ã«ã¡ã¯"), /ã«ã¡./)
+ assert_equal(0, S("ã“ã‚“ã«ã¡ã¯").index(?ã“))
+ assert_equal(1, S("ã“ã‚“ã«ã¡ã¯").index(S("ã‚“ã«ã¡")))
+ assert_equal(2, S("ã“ã‚“ã«ã¡ã¯").index(/ã«ã¡./))
- assert_index(0, S("ã«ã‚“ã«ã¡ã¯"), ?ã«, 0)
- assert_index(2, S("ã«ã‚“ã«ã¡ã¯"), ?ã«, 1)
- assert_index(2, S("ã«ã‚“ã«ã¡ã¯"), ?ã«, 2)
- assert_index(nil, S("ã«ã‚“ã«ã¡ã¯"), ?ã«, 3)
+ assert_equal(0, S("ã«ã‚“ã«ã¡ã¯").index(?ã«, 0))
+ assert_equal(2, S("ã«ã‚“ã«ã¡ã¯").index(?ã«, 1))
+ assert_equal(2, S("ã«ã‚“ã«ã¡ã¯").index(?ã«, 2))
+ assert_nil(S("ã«ã‚“ã«ã¡ã¯").index(?ã«, 3))
end
def test_insert
@@ -1585,57 +1535,57 @@ CODE
end
def test_rindex
- 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").rindex(?l))
+ assert_equal(6, S("ell, hello").rindex(S("ell")))
+ assert_equal(7, S("ell, hello").rindex(/ll./))
- 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_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(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, 3))
+ assert_nil(S("hello").rindex(S("z"), 3))
+ assert_nil(S("hello").rindex(/z./, 3))
- assert_rindex(nil, S("hello"), ?z)
- assert_rindex(nil, S("hello"), S("z"))
- assert_rindex(nil, S("hello"), /z./)
+ assert_nil(S("hello").rindex(?z))
+ assert_nil(S("hello").rindex(S("z")))
+ assert_nil(S("hello").rindex(/z./))
- 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)
+ 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))
o = Object.new
def o.to_str; "bar"; end
- assert_rindex(6, S("foobarbarbaz"), o)
+ assert_equal(6, S("foobarbarbaz").rindex(o))
assert_raise(TypeError) { S("foo").rindex(Object.new) }
- assert_rindex(nil, S("foo"), //, -100)
+ assert_nil(S("foo").rindex(//, -100))
+ assert_nil($~)
- m = assert_rindex(3, S("foo"), //)
- assert_equal([3, 3], m.offset(0))
- assert_rindex(3, S("foo"), //, 4)
+ assert_equal(3, S("foo").rindex(//))
+ assert_equal([3, 3], $~.offset(0))
- assert_rindex(5, S("abcdbce"), /b\Kc/)
+ assert_equal(5, S("abcdbce").rindex(/b\Kc/))
- assert_rindex(2, S("ã“ã‚“ã«ã¡ã¯"), ?ã«)
- assert_rindex(6, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), S("ã«ã¡ã¯"))
- assert_rindex(6, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), /ã«ã¡./)
+ assert_equal(2, S("ã“ã‚“ã«ã¡ã¯").rindex(?ã«))
+ assert_equal(6, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").rindex(S("ã«ã¡ã¯")))
+ assert_equal(6, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").rindex(/ã«ã¡./))
- 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(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(0, S("ã“ã‚“ã«ã¡ã¯"), S("ã“ã‚“ã«ã¡ã¯"))
- assert_rindex(nil, S("ã“ã‚“ã«ã¡"), S("ã“ã‚“ã«ã¡ã¯"))
- assert_rindex(nil, S("ã“"), S("ã“ã‚“ã«ã¡ã¯"))
- assert_rindex(nil, S(""), S("ã“ã‚“ã«ã¡ã¯"))
+ assert_equal(0, S("ã“ã‚“ã«ã¡ã¯").rindex(S("ã“ã‚“ã«ã¡ã¯")))
+ assert_nil(S("ã“ã‚“ã«ã¡").rindex(S("ã“ã‚“ã«ã¡ã¯")))
+ assert_nil(S("ã“").rindex(S("ã“ã‚“ã«ã¡ã¯")))
+ assert_nil(S("").rindex(S("ã“ã‚“ã«ã¡ã¯")))
end
def test_rjust
@@ -1674,11 +1624,6 @@ 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
@@ -1995,15 +1940,10 @@ 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/))
@@ -2106,16 +2046,6 @@ 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
@@ -2373,8 +2303,6 @@ 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!
@@ -2399,8 +2327,6 @@ 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
@@ -2408,8 +2334,6 @@ 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!
@@ -2422,8 +2346,6 @@ 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
@@ -2963,13 +2885,11 @@ CODE
end
- def test_delete_prefix_type_error
+ def test_delete_prefix
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)
@@ -2989,9 +2909,8 @@ CODE
s = S("hello")
assert_equal("hello", s.delete_prefix("\u{3053 3093}"))
assert_equal("hello", s)
- end
- def test_delete_prefix_broken_encoding
+ # skip if argument is a broken string
s = S("\xe3\x81\x82")
assert_equal("\xe3\x81\x82", s.delete_prefix("\xe3"))
assert_equal("\xe3\x81\x82", s)
@@ -3000,31 +2919,23 @@ CODE
assert_equal("\x95\x5c".force_encoding("Shift_JIS"), s.delete_prefix("\x95"))
assert_equal("\x95\x5c".force_encoding("Shift_JIS"), s)
- 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
+ # 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
- def test_delete_prefix_argument_conversion
+ # argument should be converted to String
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_type_error
+ def test_delete_prefix_bang
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)
@@ -3044,32 +2955,23 @@ CODE
s = S("hello")
assert_equal(nil, s.delete_prefix!("\u{3053 3093}"))
assert_equal("hello", s)
- end
- def test_delete_prefix_bang_broken_encoding
+ # skip if argument is a broken string
s = S("\xe3\x81\x82")
assert_equal(nil, s.delete_prefix!("\xe3"))
assert_equal("\xe3\x81\x82", s)
- s = S("\xFF\xFE")
- assert_equal("\xFE", s.delete_prefix!("\xFF"))
- assert_equal("\xFE", s)
- end
-
- def test_delete_prefix_bang_clear_coderange
+ # 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
- def test_delete_prefix_bang_argument_conversion
+ # argument should be converted to String
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")}
@@ -3082,13 +2984,11 @@ CODE
assert_raise_with_message(FrozenError, /frozen/) {s.delete_prefix!(o)}
end
- def test_delete_suffix_type_error
+ def test_delete_suffix
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)
@@ -3108,28 +3008,23 @@ CODE
s = S("hello")
assert_equal("hello", s.delete_suffix("\u{3061 306f}"))
assert_equal("hello", s)
- end
- def test_delete_suffix_broken_encoding
+ # skip if argument is a broken string
s = S("\xe3\x81\x82")
assert_equal("\xe3\x81\x82", s.delete_suffix("\x82"))
assert_equal("\xe3\x81\x82", s)
- end
- def test_delete_suffix_clear_coderange
+ # 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
- def test_delete_suffix_argument_conversion
+ # argument should be converted to String
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"
@@ -3140,13 +3035,11 @@ CODE
assert_equal("foo\r", s.delete_suffix("\n"))
end
- def test_delete_suffix_bang_type_error
+ def test_delete_suffix_bang
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')}
@@ -3157,9 +3050,7 @@ 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)
@@ -3179,9 +3070,8 @@ CODE
s = S("hello")
assert_equal(nil, s.delete_suffix!("\u{3061 306f}"))
assert_equal("hello", s)
- end
- def test_delete_suffix_bang_broken_encoding
+ # skip if argument is a broken string
s = S("\xe3\x81\x82")
assert_equal(nil, s.delete_suffix!("\x82"))
assert_equal("\xe3\x81\x82", s)
@@ -3189,22 +3079,18 @@ 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
- def test_delete_suffix_bang_clear_coderange
+ # 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
- def test_delete_suffix_bang_argument_conversion
+ # argument should be converted to String
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"
@@ -3462,56 +3348,56 @@ CODE
end
def test_byteindex
- assert_byteindex(0, S("hello"), ?h)
- assert_byteindex(1, S("hello"), S("ell"))
- assert_byteindex(2, S("hello"), /ll./)
+ assert_equal(0, S("hello").byteindex(?h))
+ assert_equal(1, S("hello").byteindex(S("ell")))
+ assert_equal(2, S("hello").byteindex(/ll./))
- assert_byteindex(3, S("hello"), ?l, 3)
- assert_byteindex(3, S("hello"), S("l"), 3)
- assert_byteindex(3, S("hello"), /l./, 3)
+ 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(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, 3))
+ assert_nil(S("hello").byteindex(S("z"), 3))
+ assert_nil(S("hello").byteindex(/z./, 3))
- assert_byteindex(nil, S("hello"), ?z)
- assert_byteindex(nil, S("hello"), S("z"))
- assert_byteindex(nil, S("hello"), /z./)
+ assert_nil(S("hello").byteindex(?z))
+ assert_nil(S("hello").byteindex(S("z")))
+ assert_nil(S("hello").byteindex(/z./))
- 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"), //)
+ 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(//))
s = S("long") * 1000 << "x"
- assert_byteindex(nil, s, S("y"))
- assert_byteindex(4 * 1000, s, S("x"))
+ assert_nil(s.byteindex(S("y")))
+ assert_equal(4 * 1000, s.byteindex(S("x")))
s << "yx"
- assert_byteindex(4 * 1000, s, S("x"))
- assert_byteindex(4 * 1000, s, S("xyx"))
+ assert_equal(4 * 1000, s.byteindex(S("x")))
+ assert_equal(4 * 1000, s.byteindex(S("xyx")))
o = Object.new
def o.to_str; "bar"; end
- assert_byteindex(3, S("foobarbarbaz"), o)
+ assert_equal(3, S("foobarbarbaz").byteindex(o))
assert_raise(TypeError) { S("foo").byteindex(Object.new) }
- assert_byteindex(nil, S("foo"), //, -100)
- assert_byteindex(nil, S("foo"), //, -4)
+ assert_nil(S("foo").byteindex(//, -100))
+ assert_nil($~)
- assert_byteindex(2, S("abcdbce"), /b\Kc/)
+ assert_equal(2, S("abcdbce").byteindex(/b\Kc/))
- assert_byteindex(0, S("ã“ã‚“ã«ã¡ã¯"), ?ã“)
- assert_byteindex(3, S("ã“ã‚“ã«ã¡ã¯"), S("ã‚“ã«ã¡"))
- assert_byteindex(6, S("ã“ã‚“ã«ã¡ã¯"), /ã«ã¡./)
+ assert_equal(0, S("ã“ã‚“ã«ã¡ã¯").byteindex(?ã“))
+ assert_equal(3, S("ã“ã‚“ã«ã¡ã¯").byteindex(S("ã‚“ã«ã¡")))
+ assert_equal(6, S("ã“ã‚“ã«ã¡ã¯").byteindex(/ã«ã¡./))
- assert_byteindex(0, S("ã«ã‚“ã«ã¡ã¯"), ?ã«, 0)
+ assert_equal(0, S("ã«ã‚“ã«ã¡ã¯").byteindex(?ã«, 0))
assert_raise(IndexError) { S("ã«ã‚“ã«ã¡ã¯").byteindex(?ã«, 1) }
assert_raise(IndexError) { S("ã«ã‚“ã«ã¡ã¯").byteindex(?ã«, 5) }
- assert_byteindex(6, S("ã«ã‚“ã«ã¡ã¯"), ?ã«, 6)
- assert_byteindex(6, S("ã«ã‚“ã«ã¡ã¯"), S("ã«"), 6)
- assert_byteindex(6, S("ã«ã‚“ã«ã¡ã¯"), /ã«./, 6)
+ assert_equal(6, S("ã«ã‚“ã«ã¡ã¯").byteindex(?ã«, 6))
+ assert_equal(6, S("ã«ã‚“ã«ã¡ã¯").byteindex(S("ã«"), 6))
+ assert_equal(6, S("ã«ã‚“ã«ã¡ã¯").byteindex(/ã«./, 6))
assert_raise(IndexError) { S("ã«ã‚“ã«ã¡ã¯").byteindex(?ã«, 7) }
s = S("foobarbarbaz")
@@ -3519,134 +3405,90 @@ CODE
end
def test_byterindex
- 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").byterindex(?l))
+ assert_equal(6, S("ell, hello").byterindex(S("ell")))
+ assert_equal(7, S("ell, hello").byterindex(/ll./))
- 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_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(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, 3))
+ assert_nil(S("hello").byterindex(S("z"), 3))
+ assert_nil(S("hello").byterindex(/z./, 3))
- assert_byterindex(nil, S("hello"), ?z)
- assert_byterindex(nil, S("hello"), S("z"))
- assert_byterindex(nil, S("hello"), /z./)
+ assert_nil(S("hello").byterindex(?z))
+ assert_nil(S("hello").byterindex(S("z")))
+ assert_nil(S("hello").byterindex(/z./))
- 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)
+ 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))
o = Object.new
def o.to_str; "bar"; end
- assert_byterindex(6, S("foobarbarbaz"), o)
+ assert_equal(6, S("foobarbarbaz").byterindex(o))
assert_raise(TypeError) { S("foo").byterindex(Object.new) }
- assert_byterindex(nil, S("foo"), //, -100)
+ assert_nil(S("foo").byterindex(//, -100))
+ assert_nil($~)
- m = assert_byterindex(3, S("foo"), //)
- assert_equal([3, 3], m.offset(0))
- assert_byterindex(3, S("foo"), //, 4)
+ assert_equal(3, S("foo").byterindex(//))
+ assert_equal([3, 3], $~.offset(0))
- assert_byterindex(5, S("abcdbce"), /b\Kc/)
+ assert_equal(5, S("abcdbce").byterindex(/b\Kc/))
- assert_byterindex(6, S("ã“ã‚“ã«ã¡ã¯"), ?ã«)
- assert_byterindex(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), S("ã«ã¡ã¯"))
- assert_byterindex(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), /ã«ã¡./)
+ assert_equal(6, S("ã“ã‚“ã«ã¡ã¯").byterindex(?ã«))
+ assert_equal(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯")))
+ assert_equal(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(/ã«ã¡./))
assert_raise(IndexError) { S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), 19) }
assert_raise(IndexError) { S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), -2) }
- assert_byterindex(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), S("ã«ã¡ã¯"), 18)
- assert_byterindex(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), S("ã«ã¡ã¯"), -3)
+ assert_equal(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), 18))
+ assert_equal(18, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), -3))
assert_raise(IndexError) { S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), 17) }
assert_raise(IndexError) { S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), -4) }
assert_raise(IndexError) { S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), 1) }
- assert_byterindex(0, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯"), S("ã«ã¡ã¯"), 0)
+ assert_equal(0, S("ã«ã¡ã¯ã€ã“ã‚“ã«ã¡ã¯").byterindex(S("ã«ã¡ã¯"), 0))
- assert_byterindex(0, S("ã“ã‚“ã«ã¡ã¯"), S("ã“ã‚“ã«ã¡ã¯"))
- assert_byterindex(nil, S("ã“ã‚“ã«ã¡"), S("ã“ã‚“ã«ã¡ã¯"))
- assert_byterindex(nil, S("ã“"), S("ã“ã‚“ã«ã¡ã¯"))
- assert_byterindex(nil, S(""), S("ã“ã‚“ã«ã¡ã¯"))
+ assert_equal(0, S("ã“ã‚“ã«ã¡ã¯").byterindex(S("ã“ã‚“ã«ã¡ã¯")))
+ assert_nil(S("ã“ã‚“ã«ã¡").byterindex(S("ã“ã‚“ã«ã¡ã¯")))
+ assert_nil(S("ã“").byterindex(S("ã“ã‚“ã«ã¡ã¯")))
+ assert_nil(S("").byterindex(S("ã“ã‚“ã«ã¡ã¯")))
end
def test_bytesplice
- 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_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_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
private
@@ -3659,42 +3501,6 @@ CODE
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
deleted file mode 100644
index 3b4694f36f..0000000000
--- a/test/ruby/test_string_memory.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# 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 3d727adf04..8a5706b18c 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -41,14 +41,6 @@ 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|
diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb
index ce78e66c52..08be568660 100644
--- a/test/ruby/test_super.rb
+++ b/test/ruby/test_super.rb
@@ -558,18 +558,6 @@ 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
@@ -617,6 +605,35 @@ class TestSuper < Test::Unit::TestCase
}
end
+ def test_super_with_included_prepended_module_method_caching_bug_20716
+ a = Module.new do
+ def test(*args)
+ super
+ end
+ end
+
+ b = Module.new do
+ def test(a)
+ a
+ end
+ end
+
+ c = Class.new
+
+ b.prepend(a)
+ c.include(b)
+
+ assert_equal(1, c.new.test(1))
+
+ b.class_eval do
+ def test
+ :test
+ end
+ end
+
+ assert_equal(:test, c.new.test)
+ end
+
class TestFor_super_with_modified_rest_parameter_base
def foo *args
args
diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb
index 67a8303c54..1d2a18d734 100644
--- a/test/ruby/test_symbol.rb
+++ b/test/ruby/test_symbol.rb
@@ -118,13 +118,6 @@ 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
- 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 cc332a9412..7553cd74a6 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -13,7 +13,8 @@ class TestSyntax < Test::Unit::TestCase
def assert_syntax_files(test)
srcdir = File.expand_path("../../..", __FILE__)
srcdir = File.join(srcdir, test)
- assert_separately(%W[- #{srcdir}], __FILE__, __LINE__, <<-'eom', timeout: Float::INFINITY)
+ assert_separately(%W[--disable-gem - #{srcdir}],
+ __FILE__, __LINE__, <<-'eom', timeout: Float::INFINITY)
dir = ARGV.shift
for script in Dir["#{dir}/**/*.rb"].sort
assert_valid_syntax(IO::read(script), script)
@@ -76,111 +77,97 @@ 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
- 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))
+ 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
@@ -364,12 +351,6 @@ 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
@@ -671,8 +652,6 @@ 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
@@ -1026,7 +1005,7 @@ eom
["p ", ""], # no-pop
["", "p Foo::Bar"], # pop
].each do |p1, p2|
- src = <<~EOM
+ src = <<-EOM.gsub(/^\s*\n/, '')
class Foo
#{"Bar = " + preset if preset}
end
@@ -1058,7 +1037,7 @@ eom
["p ", ""], # no-pop
["", "p ::Bar"], # pop
].each do |p1, p2|
- src = <<~EOM
+ src = <<-EOM.gsub(/^\s*\n/, '')
#{"Bar = " + preset if preset}
class Foo
#{p1}::Bar #{op}= 42
@@ -1209,6 +1188,20 @@ eom
assert_syntax_error("a&.x,=0", /multiple assignment destination/)
end
+ def test_safe_call_in_for_variable
+ assert_valid_syntax("for x&.bar in []; end")
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ foo = nil
+ for foo&.bar in [1]; end
+ assert_nil(foo)
+
+ foo = Struct.new(:bar).new
+ for foo&.bar in [1]; end
+ assert_equal(1, foo.bar)
+ end;
+ end
+
def test_no_warning_logop_literal
assert_warning("") do
eval("true||raise;nil")
@@ -1354,10 +1347,6 @@ 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_do_after_local_variable
obj = Object.new
def obj.m; yield; end
@@ -1440,54 +1429,6 @@ 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
@@ -1500,16 +1441,6 @@ eom
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)
@@ -1729,29 +1660,6 @@ 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
@@ -1800,20 +1708,6 @@ eom
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_no_warning(/`it`/) {eval('if false; it; end')}
- assert_no_warning(/`it`/) {eval('def foo; it; end')}
- assert_warn(/`it`/) {eval('0.times { it }')}
- assert_no_warning(/`it`/) {eval('0.times { || it }')}
- assert_no_warning(/`it`/) {eval('0.times { |_n| it }')}
- assert_warn(/`it`/) {eval('0.times { it; it = 1; it }')}
- assert_no_warning(/`it`/) {eval('0.times { it = 1; it }')}
- assert_no_warning(/`it`/) {eval('it = 1; 0.times { it }')}
- ensure
- self.class.remove_method(:foo)
end
def test_value_expr_in_condition
@@ -1824,11 +1718,6 @@ 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")
diff --git a/test/ruby/test_system.rb b/test/ruby/test_system.rb
index 3fcdaa6aad..31c9cd7654 100644
--- a/test/ruby/test_system.rb
+++ b/test/ruby/test_system.rb
@@ -146,19 +146,6 @@ 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 da14c429e6..85fbde2de8 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -3,7 +3,6 @@
require 'test/unit'
require "rbconfig/sizeof"
require "timeout"
-require "fiddle"
class TestThread < Test::Unit::TestCase
class Thread < ::Thread
@@ -324,7 +323,7 @@ class TestThread < Test::Unit::TestCase
s += 1
end
Thread.pass until t.stop?
- sleep 1 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
+ sleep 1 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
assert_equal(1, s)
t.wakeup
Thread.pass while t.alive?
@@ -396,7 +395,7 @@ class TestThread < Test::Unit::TestCase
end
INPUT
- assert_in_out_err(%w(-d), <<-INPUT, %w(false 2), %r".+")
+ assert_in_out_err(%w(--disable-gems -d), <<-INPUT, %w(false 2), %r".+")
p Thread.abort_on_exception
begin
t = Thread.new { raise }
@@ -1435,8 +1434,7 @@ q.pop
Thread.pass until th1.stop?
# After a thread starts (and execute `sleep`), it returns native_thread_id
- native_tid = th1.native_thread_id
- assert_instance_of Integer, native_tid if native_tid # it can be nil
+ assert_instance_of Integer, th1.native_thread_id
th1.wakeup
Thread.pass while th1.alive?
@@ -1445,40 +1443,11 @@ 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 RJIT
- opts[:reprieve] = 3 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ # prevent SIGABRT from slow shutdown with MJIT
+ opts[:reprieve] = 3 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
assert_normal_exit(<<-_end, '[Bug #8996]', **opts)
Thread.report_on_exception = false
diff --git a/test/ruby/test_thread_cv.rb b/test/ruby/test_thread_cv.rb
index eb88b9606c..88733419da 100644
--- a/test/ruby/test_thread_cv.rb
+++ b/test/ruby/test_thread_cv.rb
@@ -6,6 +6,12 @@ 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 545bf98888..723450ad23 100644
--- a/test/ruby/test_thread_queue.rb
+++ b/test/ruby/test_thread_queue.rb
@@ -8,23 +8,14 @@ class TestThreadQueue < Test::Unit::TestCase
SizedQueue = Thread::SizedQueue
def test_queue_initialized
- assert_raise_with_message(TypeError, /\bQueue.* not initialized/) {
+ assert_raise(TypeError) {
Queue.allocate.push(nil)
}
end
def test_sized_queue_initialized
- 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
+ SizedQueue.allocate.push(nil)
}
end
@@ -217,14 +208,14 @@ class TestThreadQueue < Test::Unit::TestCase
bug5343 = '[ruby-core:39634]'
Dir.mktmpdir {|d|
- timeout = 60
+ timeout = EnvUtil.apply_timeout_scale(60)
total_count = 250
begin
- assert_normal_exit(<<-"_eom", bug5343, timeout: timeout, chdir: d)
- r, w = IO.pipe
+ assert_normal_exit(<<-"_eom", bug5343, **{:timeout => timeout, :chdir=>d})
#{total_count}.times do |i|
- File.open("test_thr_kill_count", "w") {|f| f.puts i }
+ 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
@@ -594,14 +585,9 @@ 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
- mutex.lock
- mutex.unlock
+ sleep(rand / 100)
count_items.times{|i| q << [i,"#{i} for #{Thread.current.inspect}"]}
end
end
@@ -619,11 +605,9 @@ 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.to_s =~ /\A(?:run|sleep)\z/}
-
- assert (consumers + producers).all?{|thr| thr.status.to_s =~ /\A(?:run|sleep)\z/}, 'no threads running'
+ Thread.pass until Time.now - t > 10 || (consumers + producers).all?{|thr| thr.status =~ /\A(?:run|sleep)\z/}
- mutex.unlock
+ assert (consumers + producers).all?{|thr| thr.status =~ /\A(?:run|sleep)\z/}, 'no threads running'
# 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 2a541bbe8c..0faad878fc 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -77,7 +77,6 @@ class TestTime < Test::Unit::TestCase
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)
@@ -439,7 +438,7 @@ class TestTime < Test::Unit::TestCase
end
def test_marshal_zone_gc
- assert_separately([], <<-'end;', timeout: 30)
+ assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
ENV["TZ"] = "JST-9"
s = Marshal.dump(Time.now)
t = Marshal.load(s)
@@ -1408,10 +1407,7 @@ 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[: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
-
+ omit "GC is in debug" if GC::INTERNAL_CONSTANTS[:DEBUG]
require 'objspace'
t = Time.at(0)
sizeof_timew =
@@ -1422,7 +1418,7 @@ class TestTime < Test::Unit::TestCase
end
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
+ assert_equal expect, ObjectSpace.memsize_of(t)
rescue LoadError => e
omit "failed to load objspace: #{e.message}"
end
diff --git a/test/ruby/test_transcode.rb b/test/ruby/test_transcode.rb
index 4b63263aae..24ee9b9533 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_undefined_in("\x80", 'ASCII-8BIT')
- assert_invalid_in("\x80", 'US-ASCII')
- assert_undefined_in("\xA5", 'iso-8859-3')
+ 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_raise(FrozenError) { 'hello'.freeze.encode!('iso-8859-1') }
assert_raise(FrozenError) { '\u3053\u3093\u306b\u3061\u306f'.freeze.encode!('iso-8859-1') } # ã“ã‚“ã«ã¡ã¯
end
@@ -52,6 +52,16 @@ 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,
@@ -178,16 +188,16 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_874
check_both_ways("\u20AC", "\x80", 'windows-874') # €
- assert_undefined_in("\x81", 'windows-874')
- assert_undefined_in("\x84", 'windows-874')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x84".encode("utf-8", 'windows-874') }
check_both_ways("\u2026", "\x85", 'windows-874') # …
- assert_undefined_in("\x86", 'windows-874')
- assert_undefined_in("\x8F", 'windows-874')
- assert_undefined_in("\x90", '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') }
check_both_ways("\u2018", "\x91", 'windows-874') # ‘
check_both_ways("\u2014", "\x97", 'windows-874') # —
- assert_undefined_in("\x98", 'windows-874')
- assert_undefined_in("\x9F", 'windows-874')
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", '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') # à¸
@@ -196,31 +206,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_undefined_in("\xDB", 'windows-874')
- assert_undefined_in("\xDE", 'windows-874')
+ assert_raise(Encoding::UndefinedConversionError) { "\xDB".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xDE".encode("utf-8", '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_undefined_in("\xFC", 'windows-874')
- assert_undefined_in("\xFF", 'windows-874')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-874') }
end
def test_windows_1250
check_both_ways("\u20AC", "\x80", 'windows-1250') # €
- assert_undefined_in("\x81", 'windows-1250')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1250') }
check_both_ways("\u201A", "\x82", 'windows-1250') # ‚
- assert_undefined_in("\x83", 'windows-1250')
+ assert_raise(Encoding::UndefinedConversionError) { "\x83".encode("utf-8", 'windows-1250') }
check_both_ways("\u201E", "\x84", 'windows-1250') # „
check_both_ways("\u2021", "\x87", 'windows-1250') # ‡
- assert_undefined_in("\x88", 'windows-1250')
+ assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1250') }
check_both_ways("\u2030", "\x89", 'windows-1250') # ‰
check_both_ways("\u0179", "\x8F", 'windows-1250') # Ź
- assert_undefined_in("\x90", 'windows-1250')
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1250') }
check_both_ways("\u2018", "\x91", 'windows-1250') # ‘
check_both_ways("\u2014", "\x97", 'windows-1250') # —
- assert_undefined_in("\x98", 'windows-1250')
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", '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') # Å»
@@ -241,7 +251,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_undefined_in("\x98", 'windows-1251')
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", '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') # Ї
@@ -259,16 +269,16 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1252
check_both_ways("\u20AC", "\x80", 'windows-1252') # €
- assert_undefined_in("\x81", 'windows-1252')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1252') }
check_both_ways("\u201A", "\x82", 'windows-1252') # ‚
check_both_ways("\u0152", "\x8C", 'windows-1252') # >Å’
- assert_undefined_in("\x8D", 'windows-1252')
+ assert_raise(Encoding::UndefinedConversionError) { "\x8D".encode("utf-8", 'windows-1252') }
check_both_ways("\u017D", "\x8E", 'windows-1252') # Ž
- assert_undefined_in("\x8F", 'windows-1252')
- assert_undefined_in("\x90", 'windows-1252')
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1252') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1252') }
check_both_ways("\u2018", "\x91", 'windows-1252') #‘
check_both_ways("\u0153", "\x9C", 'windows-1252') # Å“
- assert_undefined_in("\x9D", 'windows-1252')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9D".encode("utf-8", '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') # ¯
@@ -286,24 +296,24 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1253
check_both_ways("\u20AC", "\x80", 'windows-1253') # €
- assert_undefined_in("\x81", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1253') }
check_both_ways("\u201A", "\x82", 'windows-1253') # ‚
check_both_ways("\u2021", "\x87", 'windows-1253') # ‡
- assert_undefined_in("\x88", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1253') }
check_both_ways("\u2030", "\x89", 'windows-1253') # ‰
- assert_undefined_in("\x8A", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1253') }
check_both_ways("\u2039", "\x8B", 'windows-1253') # ‹
- assert_undefined_in("\x8C", 'windows-1253')
- assert_undefined_in("\x8F", 'windows-1253')
- assert_undefined_in("\x90", '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') }
check_both_ways("\u2018", "\x91", 'windows-1253') # ‘
check_both_ways("\u2014", "\x97", 'windows-1253') # —
- assert_undefined_in("\x98", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1253') }
check_both_ways("\u2122", "\x99", 'windows-1253') # â„¢
- assert_undefined_in("\x9A", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1253') }
check_both_ways("\u203A", "\x9B", 'windows-1253') # ›
- assert_undefined_in("\x9C", 'windows-1253')
- assert_undefined_in("\x9F", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1253') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", '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') # °
@@ -312,28 +322,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_undefined_in("\xD2", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\xD2".encode("utf-8", '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_undefined_in("\xFF", 'windows-1253')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-1253') }
end
def test_windows_1254
check_both_ways("\u20AC", "\x80", 'windows-1254') # €
- assert_undefined_in("\x81", 'windows-1254')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1254') }
check_both_ways("\u201A", "\x82", 'windows-1254') # ‚
check_both_ways("\u0152", "\x8C", 'windows-1254') # Å’
- assert_undefined_in("\x8D", 'windows-1254')
- assert_undefined_in("\x8F", 'windows-1254')
- assert_undefined_in("\x90", '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') }
check_both_ways("\u2018", "\x91", 'windows-1254') # ‘
check_both_ways("\u0153", "\x9C", 'windows-1254') # Å“
- assert_undefined_in("\x9D", 'windows-1254')
- assert_undefined_in("\x9E", 'windows-1254')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9D".encode("utf-8", 'windows-1254') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9E".encode("utf-8", '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') # ¯
@@ -351,20 +361,20 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1255
check_both_ways("\u20AC", "\x80", 'windows-1255') # €
- assert_undefined_in("\x81", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1255') }
check_both_ways("\u201A", "\x82", 'windows-1255') # ‚
check_both_ways("\u2030", "\x89", 'windows-1255') # ‰
- assert_undefined_in("\x8A", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1255') }
check_both_ways("\u2039", "\x8B", 'windows-1255') # ‹
- assert_undefined_in("\x8C", 'windows-1255')
- assert_undefined_in("\x8F", 'windows-1255')
- assert_undefined_in("\x90", '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') }
check_both_ways("\u2018", "\x91", 'windows-1255') # ‘
check_both_ways("\u2122", "\x99", 'windows-1255') # â„¢
- assert_undefined_in("\x9A", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1255') }
check_both_ways("\u203A", "\x9B", 'windows-1255') # ›
- assert_undefined_in("\x9C", 'windows-1255')
- assert_undefined_in("\x9F", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", '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') # ×
@@ -381,17 +391,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_undefined_in("\xD9", 'windows-1255')
- assert_undefined_in("\xDF", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\xD9".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xDF".encode("utf-8", '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_undefined_in("\xFB", 'windows-1255')
- assert_undefined_in("\xFC", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFB".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", '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_undefined_in("\xFF", 'windows-1255')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-1255') }
end
def test_windows_1256
@@ -419,35 +429,35 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1257
check_both_ways("\u20AC", "\x80", 'windows-1257') # €
- assert_undefined_in("\x81", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1257') }
check_both_ways("\u201A", "\x82", 'windows-1257') # ‚
- assert_undefined_in("\x83", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x83".encode("utf-8", 'windows-1257') }
check_both_ways("\u201E", "\x84", 'windows-1257') # „
check_both_ways("\u2021", "\x87", 'windows-1257') # ‡
- assert_undefined_in("\x88", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1257') }
check_both_ways("\u2030", "\x89", 'windows-1257') # ‰
- assert_undefined_in("\x8A", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1257') }
check_both_ways("\u2039", "\x8B", 'windows-1257') # ‹
- assert_undefined_in("\x8C", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1257') }
check_both_ways("\u00A8", "\x8D", 'windows-1257') # ¨
check_both_ways("\u02C7", "\x8E", 'windows-1257') # ˇ
check_both_ways("\u00B8", "\x8F", 'windows-1257') # ¸
- assert_undefined_in("\x90", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1257') }
check_both_ways("\u2018", "\x91", 'windows-1257') # ‘
check_both_ways("\u2014", "\x97", 'windows-1257') # —
- assert_undefined_in("\x98", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1257') }
check_both_ways("\u2122", "\x99", 'windows-1257') # â„¢
- assert_undefined_in("\x9A", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1257') }
check_both_ways("\u203A", "\x9B", 'windows-1257') # ›
- assert_undefined_in("\x9C", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1257') }
check_both_ways("\u00AF", "\x9D", 'windows-1257') # ¯
check_both_ways("\u02DB", "\x9E", 'windows-1257') # Ë›
- assert_undefined_in("\x9F", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1257') }
check_both_ways("\u00A0", "\xA0", 'windows-1257') # non-breaking space
- assert_undefined_in("\xA1", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA1".encode("utf-8", 'windows-1257') }
check_both_ways("\u00A2", "\xA2", 'windows-1257') # ¢
check_both_ways("\u00A4", "\xA4", 'windows-1257') # ¤
- assert_undefined_in("\xA5", 'windows-1257')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5".encode("utf-8", 'windows-1257') }
check_both_ways("\u00A6", "\xA6", 'windows-1257') # ¦
check_both_ways("\u00C6", "\xAF", 'windows-1257') # Æ
check_both_ways("\u00B0", "\xB0", 'windows-1257') # °
@@ -482,9 +492,9 @@ class TestTranscode < Test::Unit::TestCase
end
def test_IBM720
- assert_undefined_in("\x80", 'IBM720')
- assert_undefined_in("\x8F", 'IBM720')
- assert_undefined_in("\x90", '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') }
check_both_ways("\u0627", "\x9F", 'IBM720') # ا
check_both_ways("\u0628", "\xA0", 'IBM720') # ب
check_both_ways("\u00BB", "\xAF", 'IBM720') # »
@@ -570,17 +580,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_undefined_in("\xD5", 'IBM857')
+ assert_raise(Encoding::UndefinedConversionError) { "\xD5".encode("utf-8", '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_undefined_in("\xE7", 'IBM857')
+ assert_raise(Encoding::UndefinedConversionError) { "\xE7".encode("utf-8", '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_undefined_in("\xF2", 'IBM857')
+ assert_raise(Encoding::UndefinedConversionError) { "\xF2".encode("utf-8", 'IBM857') }
check_both_ways("\u00BE", "\xF3", 'IBM857') # ¾
check_both_ways("\u00A0", "\xFF", 'IBM857') # non-breaking space
end
@@ -700,16 +710,16 @@ class TestTranscode < Test::Unit::TestCase
end
def test_IBM869
- assert_undefined_in("\x80", 'IBM869')
- assert_undefined_in("\x85", 'IBM869')
+ assert_raise(Encoding::UndefinedConversionError) { "\x80".encode("utf-8", 'IBM869') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x85".encode("utf-8", 'IBM869') }
check_both_ways("\u0386", "\x86", 'IBM869') # Ά
- assert_undefined_in("\x87", 'IBM869')
+ assert_raise(Encoding::UndefinedConversionError) { "\x87".encode("utf-8", '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_undefined_in("\x93", 'IBM869')
- assert_undefined_in("\x94", 'IBM869')
+ assert_raise(Encoding::UndefinedConversionError) { "\x93".encode("utf-8", 'IBM869') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x94".encode("utf-8", 'IBM869') }
check_both_ways("\u038E", "\x95", 'IBM869') # ÎŽ
check_both_ways("\u03AF", "\x9F", 'IBM869') # ί
check_both_ways("\u03CA", "\xA0", 'IBM869') # ÏŠ
@@ -798,7 +808,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_undefined_in("\xFF", 'macGreek')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'macGreek') }
end
def test_macIceland
@@ -877,7 +887,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_undefined_in("\xF5", 'macTurkish')
+ assert_raise(Encoding::UndefinedConversionError) { "\xF5".encode("utf-8", 'macTurkish') }
check_both_ways("\u02C6", "\xF6", 'macTurkish') # ˆ
check_both_ways("\u02C7", "\xFF", 'macTurkish') # ˇ
end
@@ -948,11 +958,11 @@ class TestTranscode < Test::Unit::TestCase
end
def test_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')
+ 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') }
check_both_ways("\u0E01", "\xA1", 'TIS-620') # à¸
check_both_ways("\u0E0F", "\xAF", 'TIS-620') # à¸
check_both_ways("\u0E10", "\xB0", 'TIS-620') # à¸
@@ -961,15 +971,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_undefined_in("\xDB", 'TIS-620')
- assert_undefined_in("\xDE", 'TIS-620')
+ assert_raise(Encoding::UndefinedConversionError) { "\xDB".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xDE".encode("utf-8", '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_undefined_in("\xFC", 'TIS-620')
- assert_undefined_in("\xFF", 'TIS-620')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'TIS-620') }
end
def test_CP850
@@ -1172,15 +1182,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_invalid_in(%w/feffdfb7/.pack("H*"), "UTF-16")
- assert_invalid_in(%w/fffeb7df/.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")}
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_invalid_in(%w/0000feff00110000/.pack("H*"), "UTF-32")
+ assert_raise(Encoding::InvalidByteSequenceError){%w/0000feff00110000/.pack("H*").encode("UTF-8","UTF-32")}
end
def check_utf_32_both_ways(utf8, raw)
@@ -1362,24 +1372,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_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')
+ 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') }
#check_both_ways("\u9ADC", "\xFC\x40", 'shift_jis') # 髜 (IBM extended)
- 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')
+ 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') }
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') # 神林義åš
@@ -1399,34 +1409,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_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')
+ 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') }
check_both_ways("\u25EF", "\xA2\xFE", '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')
+ 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') }
check_both_ways("\u6A97", "\xDD\xA1", 'euc-jp') # 檗
check_both_ways("\u6BEF", "\xDD\xDF", 'euc-jp') # 毯
check_both_ways("\u9EBE", "\xDD\xE0", 'euc-jp') # 麾
@@ -1439,7 +1449,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_undefined_in("\xF4\xA7", 'euc-jp')
+ assert_raise(Encoding::UndefinedConversionError) { "\xF4\xA7".encode("utf-8", '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') # æ¾æœ¬è¡Œå¼˜
@@ -1471,7 +1481,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') # ï½”
- assert_undefined_in("\xA5\xF7", 'euc-jis-2004')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5\xF7".encode("utf-8", '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') # Ï‚
@@ -1556,33 +1566,33 @@ class TestTranscode < Test::Unit::TestCase
end
def test_eucjp_sjis_undef
- 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")
+ 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") }
end
def test_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_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_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"),
@@ -1645,11 +1655,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_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")
+ 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") }
# FULLWIDTH REVERSE SOLIDUS
check_both_ways("\uFF3C", "\x81\x5F", "Shift_JIS")
@@ -1670,21 +1680,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_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")
+ 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") }
end
def test_gb2312
check_both_ways("\u3000", "\xA1\xA1", 'GB2312') # full-width space
check_both_ways("\u3013", "\xA1\xFE", 'GB2312') # 〓
- assert_undefined_in("\xA2\xB0", 'GB2312')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GB2312') }
check_both_ways("\u2488", "\xA2\xB1", 'GB2312') # â’ˆ
- assert_undefined_in("\xA2\xE4", 'GB2312')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GB2312') }
check_both_ways("\u3220", "\xA2\xE5", 'GB2312') # ㈠
- assert_undefined_in("\xA2\xF0", 'GB2312')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GB2312') }
check_both_ways("\u2160", "\xA2\xF1", 'GB2312') # â… 
check_both_ways("\uFF01", "\xA3\xA1", 'GB2312') # ï¼
check_both_ways("\uFFE3", "\xA3\xFE", 'GB2312') # ï¿£
@@ -1695,9 +1705,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_undefined_in("\xA8\xC4", 'GB2312')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GB2312') }
check_both_ways("\u3105", "\xA8\xC5", 'GB2312') # ã„…
- assert_undefined_in("\xA9\xA3", 'GB2312')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GB2312') }
check_both_ways("\u2500", "\xA9\xA4", 'GB2312') # ─
check_both_ways("\u554A", "\xB0\xA1", 'GB2312') # 啊
check_both_ways("\u5265", "\xB0\xFE", 'GB2312') # 剥
@@ -1711,7 +1721,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_undefined_in("\xD7\xFA", 'GB2312')
+ assert_raise(Encoding::UndefinedConversionError) { "\xD7\xFA".encode("utf-8", 'GB2312') }
check_both_ways("\u647A", "\xDF\xA1", 'GB2312') # 摺
check_both_ways("\u553C", "\xDF\xFE", 'GB2312') # 唼
check_both_ways("\u5537", "\xE0\xA1", 'GB2312') # å”·
@@ -1749,48 +1759,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_undefined_in("\xA2\xA0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xA0".encode("utf-8", 'GBK') }
check_both_ways("\u2170", "\xA2\xA1", 'GBK') # â…°
- assert_undefined_in("\xA2\xB0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GBK') }
check_both_ways("\u2488", "\xA2\xB1", 'GBK') # â’ˆ
- assert_undefined_in("\xA2\xE4", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GBK') }
check_both_ways("\u3220", "\xA2\xE5", 'GBK') # ㈠
- assert_undefined_in("\xA2\xF0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GBK') }
check_both_ways("\u2160", "\xA2\xF1", 'GBK') # â… 
- assert_undefined_in("\xA3\xA0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xA0".encode("utf-8", 'GBK') }
check_both_ways("\uFF01", "\xA3\xA1", 'GBK') # ï¼
check_both_ways("\uFFE3", "\xA3\xFE", 'GBK') # ï¿£
- assert_undefined_in("\xA4\xA0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA4\xA0".encode("utf-8", 'GBK') }
check_both_ways("\u3041", "\xA4\xA1", 'GBK') # ã
- assert_undefined_in("\xA5\xA0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5\xA0".encode("utf-8", 'GBK') }
check_both_ways("\u30A1", "\xA5\xA1", 'GBK') # ã‚¡
check_both_ways("\u0391", "\xA6\xA1", 'GBK') # Α
check_both_ways("\u03B1", "\xA6\xC1", 'GBK') # α
- assert_undefined_in("\xA6\xED", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA6\xED".encode("utf-8", '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_undefined_in("\xA8\x96", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\x96".encode("utf-8", 'GBK') }
check_both_ways("\u0101", "\xA8\xA1", 'GBK') # Ä
- assert_undefined_in("\xA8\xBC", 'GBK')
- assert_undefined_in("\xA8\xBF", 'GBK')
- assert_undefined_in("\xA8\xC4", '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') }
check_both_ways("\u3105", "\xA8\xC5", 'GBK') # ã„…
check_both_ways("\u3021", "\xA9\x40", 'GBK') # 〡
- assert_undefined_in("\xA9\x58", 'GBK')
- assert_undefined_in("\xA9\x5B", 'GBK')
- assert_undefined_in("\xA9\x5D", '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') }
check_both_ways("\u3007", "\xA9\x96", 'GBK') # 〇
- assert_undefined_in("\xA9\xA3", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GBK') }
check_both_ways("\u2500", "\xA9\xA4", 'GBK') # ─
- assert_undefined_in("\xA9\xF0", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\xF0".encode("utf-8", '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_undefined_in("\xAF\xA1", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xAF\xA1".encode("utf-8", 'GBK') }
check_both_ways("\u7645", "\xB0\x40", 'GBK') # ç™…
check_both_ways("\u769B", "\xB0\x7E", 'GBK') # çš›
check_both_ways("\u769C", "\xB0\x80", 'GBK') # 皜
@@ -1831,10 +1841,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_undefined_in("\xFD\xA1", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFD\xA1".encode("utf-8", 'GBK') }
check_both_ways("\uFA0C", "\xFE\x40", 'GBK') # 兀
check_both_ways("\uFA29", "\xFE\x4F", 'GBK') # 﨩
- assert_undefined_in("\xFE\x50", 'GBK')
+ assert_raise(Encoding::UndefinedConversionError) { "\xFE\x50".encode("utf-8", '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
@@ -1870,48 +1880,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_undefined_in("\xA2\xA0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xA0".encode("utf-8", 'GB18030') }
check_both_ways("\u2170", "\xA2\xA1", 'GB18030') # â…°
- #assert_undefined_in("\xA2\xB0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GB18030') }
check_both_ways("\u2488", "\xA2\xB1", 'GB18030') #
- #assert_undefined_in("\xA2\xE4", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GB18030') }
check_both_ways("\u3220", "\xA2\xE5", 'GB18030') # ㈠
- #assert_undefined_in("\xA2\xF0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GB18030') }
check_both_ways("\u2160", "\xA2\xF1", 'GB18030') # â… 
- #assert_undefined_in("\xA3\xA0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA3\xA0".encode("utf-8", 'GB18030') }
check_both_ways("\uFF01", "\xA3\xA1", 'GB18030') # E
check_both_ways("\uFFE3", "\xA3\xFE", 'GB18030') # E
- #assert_undefined_in("\xA4\xA0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA4\xA0".encode("utf-8", 'GB18030') }
check_both_ways("\u3041", "\xA4\xA1", 'GB18030') #
- #assert_undefined_in("\xA5\xA0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA5\xA0".encode("utf-8", 'GB18030') }
check_both_ways("\u30A1", "\xA5\xA1", 'GB18030') # ã‚¡
check_both_ways("\u0391", "\xA6\xA1", 'GB18030') #
check_both_ways("\u03B1", "\xA6\xC1", 'GB18030') # α
- #assert_undefined_in("\xA6\xED", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA6\xED".encode("utf-8", '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_undefined_in("\xA8\x96", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA8\x96".encode("utf-8", 'GB18030') }
check_both_ways("\u0101", "\xA8\xA1", 'GB18030') #
- #assert_undefined_in("\xA8\xBC", 'GB18030')
- #assert_undefined_in("\xA8\xBF", 'GB18030')
- #assert_undefined_in("\xA8\xC4", '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') }
check_both_ways("\u3105", "\xA8\xC5", 'GB18030') #
check_both_ways("\u3021", "\xA9\x40", 'GB18030') # 〡
- #assert_undefined_in("\xA9\x58", 'GB18030')
- #assert_undefined_in("\xA9\x5B", 'GB18030')
- #assert_undefined_in("\xA9\x5D", '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') }
check_both_ways("\u3007", "\xA9\x96", 'GB18030') #
- #assert_undefined_in("\xA9\xA3", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GB18030') }
check_both_ways("\u2500", "\xA9\xA4", 'GB18030') # ─
- #assert_undefined_in("\xA9\xF0", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\xF0".encode("utf-8", '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_undefined_in("\xAF\xA1", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xAF\xA1".encode("utf-8", 'GB18030') }
check_both_ways("\u7645", "\xB0\x40", 'GB18030') #
check_both_ways("\u769B", "\xB0\x7E", 'GB18030') #
check_both_ways("\u769C", "\xB0\x80", 'GB18030') #
@@ -1952,10 +1962,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_undefined_in("\xFD\xA1", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xFD\xA1".encode("utf-8", 'GB18030') }
check_both_ways("\uFA0C", "\xFE\x40", 'GB18030') # E
check_both_ways("\uFA29", "\xFE\x4F", 'GB18030') # E
- #assert_undefined_in("\xFE\x50", 'GB18030')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xFE\x50".encode("utf-8", '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') # 神林義
@@ -2010,7 +2020,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_undefined_in("\xA3\xC0", 'Big5')
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'Big5') }
check_both_ways("\u6D6C", "\xAF\x40", 'Big5') # 浬
check_both_ways("\u7837", "\xAF\x7E", 'Big5') # ç ·
check_both_ways("\u7825", "\xAF\xA1", 'Big5') # ç ¥
@@ -2029,9 +2039,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_undefined_in("\xC6\xA1", 'Big5')
- #assert_undefined_in("\xC7\x40", 'Big5')
- #assert_undefined_in("\xC8\x40", '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') }
check_both_ways("\u4E42", "\xC9\x40", 'Big5') # 乂
check_both_ways("\u6C15", "\xC9\x7E", 'Big5') # æ°•
check_both_ways("\u6C36", "\xC9\xA1", 'Big5') # æ°¶
@@ -2064,7 +2074,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_undefined_in("\xF9\xD6", 'Big5')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xF9\xD6".encode("utf-8", 'Big5') }
check_both_ways("\u795E\u6797\u7FA9\u535A", "\xAF\xAB\xAA\x4C\xB8\x71\xB3\xD5", 'Big5') # 神林義åš
end
@@ -2077,7 +2087,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_undefined_in("\xA3\xC0", 'Big5-HKSCS')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", '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') # ç ¥
@@ -2096,9 +2106,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_undefined_in("\xC6\xA1", 'Big5-HKSCS')
- #assert_undefined_in("\xC7\x40", 'Big5-HKSCS')
- #assert_undefined_in("\xC8\x40", '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') }
check_both_ways("\u4E42", "\xC9\x40", 'Big5-HKSCS') # 乂
check_both_ways("\u6C15", "\xC9\x7E", 'Big5-HKSCS') # æ°•
check_both_ways("\u6C36", "\xC9\xA1", 'Big5-HKSCS') # æ°¶
@@ -2132,7 +2142,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_undefined_in("\xF9\xD6", 'Big5-HKSCS')
+ #assert_raise(Encoding::UndefinedConversionError) { "\xF9\xD6".encode("utf-8", 'Big5-HKSCS') }
check_both_ways("\u795E\u6797\u7FA9\u535A", "\xAF\xAB\xAA\x4C\xB8\x71\xB3\xD5", 'Big5-HKSCS') # 神林義åš
end
@@ -2298,34 +2308,4 @@ class TestTranscode < Test::Unit::TestCase
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 86f2e4bb84..5e8abb0734 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -174,21 +174,6 @@ 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, $$)
@@ -266,84 +251,6 @@ 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
@@ -413,18 +320,6 @@ 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..7efb0e0cd8 100644
--- a/test/ruby/test_vm_dump.rb
+++ b/test/ruby/test_vm_dump.rb
@@ -3,6 +3,8 @@ require 'test/unit'
class TestVMDump < Test::Unit::TestCase
def assert_darwin_vm_dump_works(args)
+ pend "macOS 15 is not working with this assertion" if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`
+
omit if RUBY_PLATFORM !~ /darwin/
assert_in_out_err(args, "", [], /^\[IMPORTANT\]/)
end
diff --git a/test/ruby/test_weakkeymap.rb b/test/ruby/test_weakkeymap.rb
deleted file mode 100644
index 1718ccf06b..0000000000
--- a/test/ruby/test_weakkeymap.rb
+++ /dev/null
@@ -1,145 +0,0 @@
-# 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
- 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 97d7197dbb..7fc956dfae 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -82,22 +82,6 @@ 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
@@ -193,17 +177,16 @@ class TestWeakMap < Test::Unit::TestCase
end;
end
- def test_compaction
+ def test_compaction_bug_19529
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;')
+ assert_separately(%w(--disable-gems), <<-'end;')
wm = ObjectSpace::WeakMap.new
obj = Object.new
100.times do
@@ -212,34 +195,6 @@ class TestWeakMap < Test::Unit::TestCase
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
diff --git a/test/ruby/test_whileuntil.rb b/test/ruby/test_whileuntil.rb
index ff6d29ac4a..121c44817d 100644
--- a/test/ruby/test_whileuntil.rb
+++ b/test/ruby/test_whileuntil.rb
@@ -73,24 +73,6 @@ 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 206193d86d..b90235cd7d 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -10,10 +10,8 @@ require_relative '../lib/jit_support'
return unless JITSupport.yjit_supported?
-require 'stringio'
-
# Tests for YJIT with assertions on compilation and side exits
-# insipired by the RJIT tests in test/ruby/test_rjit.rb
+# insipired by the MJIT tests in test/ruby/test_mjit.rb
class TestYJIT < Test::Unit::TestCase
running_with_yjit = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
@@ -53,97 +51,8 @@ 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')
- refute_predicate RubyVM::YJIT, :enabled?
- refute_includes RUBY_DESCRIPTION, "+YJIT"
-
- RubyVM::YJIT.enable
-
- assert_predicate RubyVM::YJIT, :enabled?
- assert_includes RUBY_DESCRIPTION, "+YJIT"
- RUBY
- end
-
- def test_yjit_disable
- assert_separately(["--yjit", "--yjit-disable"], <<~'RUBY')
- refute_predicate RubyVM::YJIT, :enabled?
- refute_includes RUBY_DESCRIPTION, "+YJIT"
-
- RubyVM::YJIT.enable
-
- assert_predicate RubyVM::YJIT, :enabled?
- assert_includes RUBY_DESCRIPTION, "+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 = invoke_ruby(%w(-v --yjit-stats), '', true, true)
+ _stdout, stderr, _status = EnvUtil.invoke_ruby(%w(-v --yjit-stats), '', true, true)
refute_includes(stderr, "NoMethodError")
end
@@ -544,32 +453,6 @@ 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)
@@ -641,7 +524,8 @@ class TestYJIT < Test::Unit::TestCase
end
def test_getblockparamproxy
- assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: {})
+ # Currently two side exits as OPTIMIZED_METHOD_TYPE_CALL is unimplemented
+ assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: { opt_send_without_block: 2 })
def foo &blk
p blk.call
p blk.call
@@ -652,24 +536,6 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
- 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
@@ -718,7 +584,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")
+ assert_compiles(<<~'RUBY', result: "2#a:1,b:2/A", exits: {opt_send_without_block: 1})
def internal_method(**kw)
"#{kw.size}##{kw.keys.map { |k| "#{k}:#{kw[k]}" }.join(",")}"
end
@@ -758,7 +624,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")
+ assert_compiles(<<~'RUBY', result: "2#a:1,b:2/B", exits: {opt_send_without_block: 1})
def internal_method(**kw)
"#{kw.size}##{kw.keys.map { |k| "#{k}:#{kw[k]}" }.join(",")}"
end
@@ -772,7 +638,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")
+ assert_compiles(<<~'RUBY', result: "b:n/b:y/b:y/b:n", exits: { :setlocal_WC_0 => 0..1 })
def internal_method(&b)
"b:#{block_given? ? "y" : "n"}"
end
@@ -888,25 +754,6 @@ 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
@@ -1105,55 +952,8 @@ class TestYJIT < Test::Unit::TestCase
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
-
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: :ok, mem_size: 1)
fiber = Fiber.new {
# Loop to call the same basic block again after Fiber.yield
while true
@@ -1264,7 +1064,7 @@ class TestYJIT < Test::Unit::TestCase
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)
+ assert_compiles(<<~'RUBY', result: [[n, -n], [n, -n]])
def foo(_, a, b, c)
[a & b, ~c]
end
@@ -1277,42 +1077,8 @@ class TestYJIT < Test::Unit::TestCase
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 })
+ assert_compiles(<<~RUBY, frozen_string_literal: true, result: :ok)
def str_uplus
_ = 1
_ = 2
@@ -1355,9 +1121,29 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_nested_send
+ #[Bug #19464]
+ assert_compiles(<<~RUBY, result: [:ok, :ok])
+ 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_return_to_invalidated_block
# [Bug #19463]
- assert_compiles(<<~RUBY, result: [1, 1, :ugokanai], exits: { definesmethod: 1, getlocal_WC_0: 1 })
+ assert_compiles(<<~RUBY, result: [1, 1, :ugokanai])
klass = Class.new do
def self.lookup(hash, key) = hash[key]
@@ -1396,79 +1182,6 @@ class TestYJIT < Test::Unit::TestCase
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)
@@ -1488,44 +1201,6 @@ class TestYJIT < Test::Unit::TestCase
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")
- 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
-
private
def code_gc_helpers
@@ -1537,9 +1212,9 @@ class TestYJIT < Test::Unit::TestCase
end
def add_pages(num_jits)
- pages = RubyVM::YJIT.runtime_stats[:live_page_count]
+ pages = RubyVM::YJIT.runtime_stats[:compiled_page_count]
num_jits.times { return false unless eval('compiles { nil.to_i }') }
- pages.nil? || pages < RubyVM::YJIT.runtime_stats[:live_page_count]
+ pages.nil? || pages < RubyVM::YJIT.runtime_stats[:compiled_page_count]
end
RUBY
end
@@ -1549,7 +1224,7 @@ class TestYJIT < Test::Unit::TestCase
end
ANY = Object.new
- def assert_compiles(test_script, insns: [], call_threshold: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil, mem_size: nil, code_gc: false)
+ def assert_compiles(test_script, insns: [], call_threshold: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil, mem_size: nil)
reset_stats = <<~RUBY
RubyVM::YJIT.runtime_stats
RubyVM::YJIT.reset_stats!
@@ -1583,7 +1258,7 @@ class TestYJIT < Test::Unit::TestCase
#{write_results}
RUBY
- status, out, err, stats = eval_with_jit(script, call_threshold:, mem_size:, code_gc:)
+ status, out, err, stats = eval_with_jit(script, call_threshold:, mem_size:)
assert status.success?, "exited with status #{status.to_i}, stderr:\n#{err}"
@@ -1609,16 +1284,9 @@ class TestYJIT < Test::Unit::TestCase
# barriers, cache misses.)
if exits != :any &&
exits != recorded_exits &&
- (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
+ !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}"
end
end
@@ -1644,38 +1312,22 @@ 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, mem_size: nil, code_gc: false)
+ def eval_with_jit(script, call_threshold: 1, timeout: 1000, mem_size: nil)
args = [
"--disable-gems",
"--yjit-call-threshold=#{call_threshold}",
- "--yjit-stats=quiet"
+ "--yjit-stats"
]
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
- # 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 })
+ out, err, status = EnvUtil.invoke_ruby(args,
+ '', true, true, timeout: timeout, ios: {3 => stats_w}
+ )
stats_w.close
- stats_reader.join(timeout)
+ stats = stats_r.read
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 816ab457ce..5421f9c804 100644
--- a/test/ruby/test_yjit_exit_locations.rb
+++ b/test/ruby/test_yjit_exit_locations.rb
@@ -11,15 +11,29 @@ require_relative '../lib/jit_support'
return unless JITSupport.yjit_supported?
# Tests for YJIT with assertions on tracing exits
-# insipired by the RJIT tests in test/ruby/test_yjit.rb
+# insipired by the MJIT 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_expandarray_splat
- assert_exit_locations('*arr = []')
+ 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('![]')
end
private
diff --git a/test/rubygems/bundler_test_gem.rb b/test/rubygems/bundler_test_gem.rb
index ca2980e04b..9ce2f82173 100644
--- a/test/rubygems/bundler_test_gem.rb
+++ b/test/rubygems/bundler_test_gem.rb
@@ -3,7 +3,7 @@
require_relative "helper"
class TestBundlerGem < Gem::TestCase
- PROJECT_DIR = File.expand_path("../..", __dir__)
+ PROJECT_DIR = File.expand_path("../..", __dir__).tap(&Gem::UNTAINT)
def test_self_use_gemdeps
with_local_bundler_at(Gem.dir) do
@@ -38,7 +38,7 @@ class TestBundlerGem < 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
@@ -46,11 +46,11 @@ class TestBundlerGem < Gem::TestCase
end
Gem.refresh
- write_file(File.join(Dir.pwd, "Gemfile")) do |fp|
+ 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"))
+ Gem.use_gemdeps(File.join Dir.pwd, "Gemfile")
expected = [
File.expand_path("test/rubygems/sff/discover.rb", PROJECT_DIR),
@@ -131,22 +131,22 @@ class TestBundlerGem < Gem::TestCase
install_specs a, b, c
- install_gem a, install_dir: path
- install_gem b, install_dir: path
- install_gem c, install_dir: path
+ 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}"
+ 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
+ out0 = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
IO.popen("foo", &:read).split(/\n/)
end
@@ -154,7 +154,7 @@ class TestBundlerGem < Gem::TestCase
f.puts "gem 'b'"
f.puts "gem 'c'"
end
- out = with_path_and_rubyopt(new_path, new_rubyopt) do
+ out = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
IO.popen("foo", &:read).split(/\n/)
end
@@ -183,33 +183,33 @@ class TestBundlerGem < Gem::TestCase
install_specs a, b, c
- install_gem a, install_dir: path
- install_gem b, install_dir: path
- install_gem c, install_dir: path
+ 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}"
+ 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/)
+ 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/)
+ out = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
+ IO.popen("foo", :chdir => "sub1", &:read).split(/\n/)
end
Dir.rmdir "sub1"
@@ -221,7 +221,7 @@ class TestBundlerGem < Gem::TestCase
def test_use_gemdeps
with_local_bundler_at(Gem.dir) do
- gem_deps_file = "gem.deps.rb"
+ gem_deps_file = "gem.deps.rb".tap(&Gem::UNTAINT)
spec = util_spec "a", 1
install_specs spec
@@ -384,10 +384,8 @@ You may need to `bundle install` to install missing gems
end
def with_path_and_rubyopt(path_value, rubyopt_value)
- path = ENV["PATH"]
- ENV["PATH"] = path_value
- rubyopt = ENV["RUBYOPT"]
- ENV["RUBYOPT"] = rubyopt_value
+ path, ENV["PATH"] = ENV["PATH"], path_value
+ rubyopt, ENV["RUBYOPT"] = ENV["RUBYOPT"], rubyopt_value
yield
ensure
@@ -396,8 +394,7 @@ You may need to `bundle install` to install missing gems
end
def with_rubygems_gemdeps(value)
- rubygems_gemdeps = ENV["RUBYGEMS_GEMDEPS"]
- ENV["RUBYGEMS_GEMDEPS"] = value
+ rubygems_gemdeps, ENV["RUBYGEMS_GEMDEPS"] = ENV["RUBYGEMS_GEMDEPS"], value
yield
ensure
diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb
index 7014843bba..688d121599 100644
--- a/test/rubygems/helper.rb
+++ b/test/rubygems/helper.rb
@@ -11,18 +11,21 @@ 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 "rubygems/vendor/uri/lib/uri"
+require "uri"
require "zlib"
require "benchmark" # stdlib
-require_relative "mock_gem_ui"
+require "rubygems/mock_gem_ui"
module Gem
+
##
# Allows setting the gem path searcher.
@@ -70,6 +73,8 @@ 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:
@@ -105,32 +110,39 @@ class Gem::TestCase < Test::Unit::TestCase
refute File.directory?(path), msg
end
- # Originally copied from minitest/assertions.rb
+ # 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
def capture_subprocess_io
- require "tempfile"
+ _synchronize do
+ begin
+ require "tempfile"
- captured_stdout = Tempfile.new("out")
- captured_stderr = Tempfile.new("err")
+ captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
- orig_stdout = $stdout.dup
- orig_stderr = $stderr.dup
- $stdout.reopen captured_stdout
- $stderr.reopen captured_stderr
+ orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
+ $stdout.reopen captured_stdout
+ $stderr.reopen captured_stderr
- yield
+ yield
- $stdout.rewind
- $stderr.rewind
+ $stdout.rewind
+ $stderr.rewind
- [captured_stdout.read, captured_stderr.read]
- ensure
- $stdout.reopen orig_stdout
- $stderr.reopen orig_stderr
+ return 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!
+ orig_stdout.close
+ orig_stderr.close
+ captured_stdout.close!
+ captured_stderr.close!
+ end
+ end
end
##
@@ -151,14 +163,6 @@ 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
#
@@ -253,10 +257,18 @@ class Gem::TestCase < Test::Unit::TestCase
def assert_contains_make_command(target, output, msg = nil)
if output.include?("\n")
msg = build_message(msg,
- 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))
+ "Expected output containing make command \"%s\", but was \n\nBEGIN_OF_OUTPUT\n%sEND_OF_OUTPUT" % [
+ ("%s %s" % [make_command, target]).rstrip,
+ output,
+ ]
+ )
else
msg = build_message(msg,
- format('Expected make command "%s", but was "%s"', format("%s %s", make_command, target).rstrip, output))
+ 'Expected make command "%s", but was "%s"' % [
+ ("%s %s" % [make_command, target]).rstrip,
+ output,
+ ]
+ )
end
assert scan_make_command_lines(output).any? {|line|
@@ -283,14 +295,12 @@ class Gem::TestCase < Test::Unit::TestCase
def setup
@orig_hooks = {}
@orig_env = ENV.to_hash
+ @tmp = File.expand_path("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)
+ FileUtils.mkdir_p @tmp
@tempdir = Dir.mktmpdir("test_rubygems_", @tmp)
+ @tempdir.tap(&Gem::UNTAINT)
ENV["GEM_VENDOR"] = nil
ENV["GEMRC"] = nil
@@ -311,7 +321,7 @@ class Gem::TestCase < Test::Unit::TestCase
# capture output
Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
- @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")
@@ -327,19 +337,16 @@ class Gem::TestCase < Test::Unit::TestCase
ruby
end
- @git = ENV["GIT"] || "git#{RbConfig::CONFIG["EXEEXT"]}"
+ @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 = begin
- File.realpath(s)
- rescue StandardError
- File.expand_path(s)
- end
+ expand_path = File.realpath(s) rescue File.expand_path(s)
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
@@ -352,16 +359,11 @@ 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
@@ -371,7 +373,7 @@ class Gem::TestCase < Test::Unit::TestCase
ENV["GEM_PRIVATE_KEY_PASSPHRASE"] = PRIVATE_KEY_PASSPHRASE
- Gem.instance_variable_set(:@default_specifications_dir, File.join(@gemhome, "specifications", "default"))
+ Gem.instance_variable_set(:@default_specifications_dir, nil)
if Gem.java_platform?
@orig_default_gem_home = RbConfig::CONFIG["default_gem_home"]
RbConfig::CONFIG["default_gem_home"] = @gemhome
@@ -403,7 +405,7 @@ class Gem::TestCase < Test::Unit::TestCase
Gem::RemoteFetcher.fetcher = Gem::FakeFetcher.new
@gem_repo = "http://gems.example.com/"
- @uri = Gem::URI.parse @gem_repo
+ @uri = URI.parse @gem_repo
Gem.sources.replace [@gem_repo]
Gem.searcher = nil
@@ -411,7 +413,7 @@ class Gem::TestCase < Test::Unit::TestCase
@orig_arch = RbConfig::CONFIG["arch"]
- if Gem.win_platform?
+ if win_platform?
util_set_arch "i386-mswin32"
else
util_set_arch "i686-darwin8.10.1"
@@ -422,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
##
@@ -430,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
@@ -449,11 +451,13 @@ class Gem::TestCase < Test::Unit::TestCase
Dir.chdir @current_dir
- ENV.replace(@orig_env)
+ FileUtils.rm_rf @tempdir
+
+ 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
@@ -469,24 +473,20 @@ 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
-
- FileUtils.rm_rf @tempdir
-
- refute_directory_exists @tempdir, "#{@tempdir} used by test #{method_name} is still in use"
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 0o600, @temp_cred
+ File.chmod 0600, @temp_cred
end
def credential_teardown
@@ -534,16 +534,6 @@ class Gem::TestCase < Test::Unit::TestCase
ENV["BUNDLE_GEMFILE"] = File.join(@tempdir, "Gemfile")
end
- def with_env(overrides, &block)
- orig_env = ENV.to_h
- ENV.replace(overrides)
- begin
- block.call
- ensure
- ENV.replace(orig_env)
- end
- end
-
##
# A git_gem is used with a gem dependencies file. The gem created here
# has no files, just a gem specification for the given +name+ and +version+.
@@ -582,7 +572,7 @@ class Gem::TestCase < Test::Unit::TestCase
head = Gem::Util.popen(@git, "rev-parse", "HEAD").strip
end
- [name, git_spec.version, directory, head]
+ return name, git_spec.version, directory, head
end
##
@@ -595,7 +585,7 @@ class Gem::TestCase < Test::Unit::TestCase
end
def in_path?(executable) # :nodoc:
- return true if %r{\A([A-Z]:|/)}.match?(executable) && File.exist?(executable)
+ return true if %r{\A([A-Z]:|/)} =~ executable && File.exist?(executable)
ENV["PATH"].split(File::PATH_SEPARATOR).any? do |directory|
File.exist? File.join directory, executable
@@ -617,17 +607,17 @@ class Gem::TestCase < Test::Unit::TestCase
end
end
- gem = File.join(@tempdir, File.basename(gem))
+ gem = File.join(@tempdir, File.basename(gem)).tap(&Gem::UNTAINT)
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
##
@@ -639,7 +629,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
##
@@ -656,7 +646,7 @@ class Gem::TestCase < Test::Unit::TestCase
# Reads a Marshal file at +path+
def read_cache(path)
- File.open path.dup, "rb" do |io|
+ File.open path.dup.tap(&Gem::UNTAINT), "rb" do |io|
Marshal.load io.read
end
end
@@ -698,8 +688,11 @@ class Gem::TestCase < Test::Unit::TestCase
# Load a YAML file, the psych 3 way
def load_yaml_file(file)
- require "rubygems/config_file"
- Gem::ConfigFile.load_with_rubygems_config_hash(File.read(file))
+ if Psych.respond_to?(:unsafe_load_file)
+ Psych.unsafe_load_file(file)
+ else
+ Psych.load_file(file)
+ end
end
def all_spec_names
@@ -740,7 +733,7 @@ class Gem::TestCase < Test::Unit::TestCase
Gem::Specification.reset
- spec
+ return spec
end
##
@@ -791,7 +784,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
@@ -802,7 +795,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
@@ -875,7 +868,7 @@ class Gem::TestCase < Test::Unit::TestCase
FileUtils.rm spec.spec_file
end
- spec
+ return spec
end
##
@@ -942,7 +935,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 - 86_400
+ s.date = Gem::Specification::TODAY - 86400
s.homepage = "http://a.example.com"
s.email = %w[example@example.com example2@example.com]
s.authors = %w[Example Example2]
@@ -985,15 +978,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
@@ -1053,18 +1046,20 @@ 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(&:name_tuple)
+ specs = all.map {|spec| spec.name_tuple }
s_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic specs
- latest_specs = latest.map(&:name_tuple)
+ latest_specs = latest.map do |spec|
+ spec.name_tuple
+ end
l_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic latest_specs
- prerelease_specs = prerelease.map(&:name_tuple)
+ prerelease_specs = prerelease.map {|spec| spec.name_tuple }
p_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic prerelease_specs
@fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip
@@ -1100,12 +1095,12 @@ Also, a list:
Gem.send :remove_instance_variable, :@ruby_version
end
- @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
+ @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)
util_clear_RUBY_VERSION
@@ -1114,27 +1109,58 @@ 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
+ Object.const_set :RUBY_ENGINE_VERSION, engine_version if 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
- 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
+ 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)
end
def util_clear_RUBY_VERSION
Object.send :remove_const, :RUBY_VERSION
- Object.send :remove_const, :RUBY_PATCHLEVEL
- Object.send :remove_const, :RUBY_REVISION
- Object.send :remove_const, :RUBY_DESCRIPTION
+ 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_ENGINE
- Object.send :remove_const, :RUBY_ENGINE_VERSION
+ 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?
end
##
@@ -1146,10 +1172,18 @@ Also, a list:
end
##
- # see ::vc_windows?
+ # Returns whether or not we're on a version of Ruby built with VC++ (or
+ # Borland) versus Cygwin, Mingw, etc.
def vc_windows?
- self.class.vc_windows?
+ RUBY_PLATFORM.match("mswin")
+ end
+
+ ##
+ # Is this test being run on a version of Ruby built with mingw?
+
+ def self.mingw_windows?
+ RUBY_PLATFORM.match("mingw")
end
##
@@ -1172,6 +1206,15 @@ Also, a list:
# built on MS Windows with VC++ or Borland it will return 'nmake'. On all
# other platforms, including Cygwin, it will return 'make'.
+ def self.make_command
+ ENV["make"] || ENV["MAKE"] || (vc_windows? ? "nmake" : "make")
+ 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'.
+
def make_command
ENV["make"] || ENV["MAKE"] || (vc_windows? ? "nmake" : "make")
end
@@ -1192,6 +1235,22 @@ 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)
@@ -1217,7 +1276,7 @@ Also, a list:
ruby = ENV["RUBY"]
return ruby if ruby
ruby = "ruby"
- rubyexe = "#{ruby}#{RbConfig::CONFIG["EXEEXT"]}"
+ rubyexe = "#{ruby}#{RbConfig::CONFIG['EXEEXT']}"
3.times do
if File.exist?(ruby) && File.executable?(ruby) && !File.directory?(ruby)
@@ -1268,29 +1327,32 @@ Also, a list:
end
def silence_warnings
- old_verbose = $VERBOSE
- $VERBOSE = false
+ old_verbose, $VERBOSE = $VERBOSE, false
yield
ensure
$VERBOSE = old_verbose
end
- # :nodoc:
- ##
- # Return the join path, with escaping backticks, dollars, and
- # double-quotes. Unlike `shellescape`, equal-sign is not escaped.
+ class << self
+ # :nodoc:
+ ##
+ # Return the join path, with escaping backticks, dollars, and
+ # double-quotes. Unlike `shellescape`, equal-sign is not escaped.
- def self.escape_path(*path)
- path = File.join(*path)
- if %r{\A[-+:/=@,.\w]+\z}.match?(path)
- path
- else
- "\"#{path.gsub(/[`$"]/, '\\&')}\""
+ private
+
+ def escape_path(*path)
+ path = File.join(*path)
+ if %r{\A[-+:/=@,.\w]+\z} =~ path
+ path
+ else
+ "\"#{path.gsub(/[`$"]/, '\\&')}\""
+ end
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.
@@ -1373,12 +1435,12 @@ Also, a list:
#
# Yields the +specification+ to the block, if given
- def vendor_gem(name = "a", version = 1, &block)
+ def vendor_gem(name = "a", version = 1)
directory = File.join "vendor", name
FileUtils.mkdir_p directory
- save_gemspec name, version, directory, &block
+ save_gemspec name, version, directory
end
##
@@ -1396,7 +1458,7 @@ Also, a list:
io.write vendor_spec.to_ruby
end
- [name, vendor_spec.version, directory]
+ return name, vendor_spec.version, directory
end
##
@@ -1476,11 +1538,7 @@ Also, a list:
# <tt>test/rubygems/</tt>.
def self.cert_path(cert_name)
- if begin
- Time.at(2**32)
- rescue StandardError
- 32
- end == 32
+ if 32 == (Time.at(2**32) rescue 32)
cert_file = "#{__dir__}/#{cert_name}_cert_32.pem"
return cert_file if File.exist? cert_file
@@ -1529,6 +1587,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
diff --git a/test/rubygems/installer_test_case.rb b/test/rubygems/installer_test_case.rb
index abddcbe848..705de6804e 100644
--- a/test/rubygems/installer_test_case.rb
+++ b/test/rubygems/installer_test_case.rb
@@ -111,7 +111,7 @@ class Gem::InstallerTestCase < Gem::TestCase
def setup_base_installer(force = true)
@gem = setup_base_gem
- util_installer @spec, @gemhome, force
+ util_installer @spec, @gemhome, false, force
end
##
@@ -163,7 +163,7 @@ class Gem::InstallerTestCase < Gem::TestCase
@user_gem = @user_spec.cache_file
- Gem::Installer.at @user_gem, user_install: true
+ util_installer @user_spec, Gem.user_dir, :user
end
##
@@ -215,16 +215,18 @@ 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+.
+ # Creates an installer for +spec+ that will install into +gem_home+. If
+ # +user+ is true a user-install will be performed.
- def util_installer(spec, gem_home, force=true)
+ def util_installer(spec, gem_home, user=false, force=true)
Gem::Installer.at(spec.cache_file,
- install_dir: gem_home,
- force: force)
+ :install_dir => gem_home,
+ :user_install => user,
+ :force => force)
end
@@symlink_supported = nil
diff --git a/test/rubygems/mock_gem_ui.rb b/test/rubygems/mock_gem_ui.rb
deleted file mode 100644
index 1ece78fde7..0000000000
--- a/test/rubygems/mock_gem_ui.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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/package/tar_test_case.rb b/test/rubygems/package/tar_test_case.rb
index e3d812bf3f..710f589169 100644
--- a/test/rubygems/package/tar_test_case.rb
+++ b/test/rubygems/package/tar_test_case.rb
@@ -124,7 +124,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
end
def to_oct(n, pad_size)
- format("%0#{pad_size}o", n)
+ "%0#{pad_size}o" % n
end
def util_entry(tar)
@@ -163,11 +163,11 @@ class Gem::Package::TarTestCase < Gem::TestCase
data_tgz = util_tar_gz(&block)
util_tar do |tar|
if spec
- tar.add_file "metadata.gz", 0o444 do |io|
+ tar.add_file "metadata.gz", 0444 do |io|
io.write util_gzip(spec.to_yaml)
end
end
- tar.add_file "data.tar.gz", 0o644 do |io|
+ tar.add_file "data.tar.gz", 0644 do |io|
io.write data_tgz.string
end
end
diff --git a/test/rubygems/plugin/exception/rubygems_plugin.rb b/test/rubygems/plugin/exception/rubygems_plugin.rb
new file mode 100644
index 0000000000..40bd7cb3d0
--- /dev/null
+++ b/test/rubygems/plugin/exception/rubygems_plugin.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+TestGem::TEST_PLUGIN_EXCEPTION = :loaded
+raise Exception.new("boom")
diff --git a/test/rubygems/plugin/scripterror/rubygems_plugin.rb b/test/rubygems/plugin/scripterror/rubygems_plugin.rb
deleted file mode 100644
index 0acd55be12..0000000000
--- a/test/rubygems/plugin/scripterror/rubygems_plugin.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# frozen_string_literal: true
-
-TestGem::TEST_PLUGIN_EXCEPTION = :loaded
-raise ScriptError.new("boom")
diff --git a/test/rubygems/specifications/rubyforge-0.0.1.gemspec b/test/rubygems/specifications/rubyforge-0.0.1.gemspec
index 0421b675a0..49619bf569 100644
--- a/test/rubygems/specifications/rubyforge-0.0.1.gemspec
+++ b/test/rubygems/specifications/rubyforge-0.0.1.gemspec
@@ -1,15 +1,14 @@
# 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.required_ruby_version = ">= 1.9.3"
+ 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"
end
diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb
index a737185681..47c1d34df5 100644
--- a/test/rubygems/test_bundled_ca.rb
+++ b/test/rubygems/test_bundled_ca.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative "helper"
-require "rubygems/vendored_net_http"
+require "net/http"
require "rubygems/openssl"
unless Gem::HAVE_OPENSSL
@@ -28,12 +28,12 @@ class TestGemBundledCA < Gem::TestCase
def assert_https(host)
assert true
- http = Gem::Net::HTTP.new(host, 443)
+ http = 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, Gem::Net::OpenTimeout
+ rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError
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 657624d526..26f681328f 100644
--- a/test/rubygems/test_config.rb
+++ b/test/rubygems/test_config.rb
@@ -16,13 +16,13 @@ class TestGemConfig < Gem::TestCase
path = Gem::TestCase.class_variable_get(:@@good_rake)
ruby, rake = path.shellsplit
assert_equal(Gem.ruby, ruby)
- assert_match(%r{/good_rake.rb\z}, rake)
+ assert_match(/\/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(%r{/bad_rake.rb\z}, rake)
+ assert_match(/\/bad_rake.rb\z/, rake)
end
end
diff --git a/test/rubygems/test_deprecate.rb b/test/rubygems/test_deprecate.rb
index d15de646a4..be622c4e33 100644
--- a/test/rubygems/test_deprecate.rb
+++ b/test/rubygems/test_deprecate.rb
@@ -29,7 +29,7 @@ class TestGemDeprecate < 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
@@ -46,7 +46,6 @@ class TestGemDeprecate < Gem::TestCase
def foo
@message = "foo"
end
-
def bar
@message = "bar"
end
@@ -55,7 +54,6 @@ class TestGemDeprecate < Gem::TestCase
def foo_arg(msg)
@message = "foo" + msg
end
-
def bar_arg(msg)
@message = "bar" + msg
end
@@ -64,7 +62,6 @@ class TestGemDeprecate < Gem::TestCase
def foo_kwarg(message:)
@message = "foo" + message
end
-
def bar_kwarg(message:)
@message = "bar" + message
end
@@ -77,7 +74,6 @@ class TestGemDeprecate < Gem::TestCase
def foo
@message = "foo"
end
-
def bar
@message = "bar"
end
@@ -86,7 +82,6 @@ class TestGemDeprecate < Gem::TestCase
def foo_arg(msg)
@message = "foo" + msg
end
-
def bar_arg(msg)
@message = "bar" + msg
end
@@ -95,7 +90,6 @@ class TestGemDeprecate < Gem::TestCase
def foo_kwarg(message:)
@message = "foo" + message
end
-
def bar_kwarg(message:)
@message = "bar" + message
end
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 40a473f8d6..967bc4b8b5 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -11,7 +11,7 @@ require "rbconfig"
class TestGem < Gem::TestCase
PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant
- PROJECT_DIR = File.expand_path("../..", __dir__)
+ PROJECT_DIR = File.expand_path("../..", __dir__).tap(&Gem::UNTAINT)
def setup
super
@@ -96,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(&:full_name)
+ assert_equal %w[a-1], installed.map {|spec| spec.full_name }
assert_path_exist File.join(gemhome2, "gems", "a-1")
end
@@ -115,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(&:full_name)
+ assert_equal %w[a-1], installed.map {|spec| spec.full_name }
end
def test_self_install_permissions
@@ -132,8 +132,8 @@ class TestGem < Gem::TestCase
end
def test_self_install_permissions_umask_077
- umask = File.umask(0o077)
- assert_self_install_permissions(data_mode: 0o600)
+ umask = File.umask(077)
+ assert_self_install_permissions
ensure
File.umask(umask)
end
@@ -151,21 +151,21 @@ class TestGem < Gem::TestCase
Gem::Installer.exec_format = nil
end
- def assert_self_install_permissions(format_executable: false, data_mode: 0o640)
- mask = Gem.win_platform? ? 0o700 : 0o777
+ def assert_self_install_permissions(format_executable: false)
+ mask = win_platform? ? 0700 : 0777
options = {
- dir_mode: 0o500,
- prog_mode: Gem.win_platform? ? 0o410 : 0o510,
- data_mode: data_mode,
- wrappers: true,
- format_executable: format_executable,
+ :dir_mode => 0500,
+ :prog_mode => win_platform? ? 0410 : 0510,
+ :data_mode => 0640,
+ :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 0o755, "bin/foo"
+ File.chmod 0755, "bin/foo"
File.write "data/foo.txt", "blah\n"
@@ -192,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 Gem.win_platform?
+ expected["bin/#{prog_name}.bat"] = mask.to_s(8) if win_platform?
result = {}
Dir.chdir @gemhome do
expected.each_key do |n|
@@ -201,7 +201,7 @@ class TestGem < Gem::TestCase
end
assert_equal(expected, result)
ensure
- File.chmod(0o755, *Dir.glob(@gemhome + "/gems/**/"))
+ File.chmod(0755, *Dir.glob(@gemhome + "/gems/**/").map {|path| path.tap(&Gem::UNTAINT) })
end
def test_require_missing
@@ -367,7 +367,7 @@ class TestGem < Gem::TestCase
install_specs bundler_latest, bundler_previous
File.open("Gemfile.lock", "w") do |f|
- f.write <<~L
+ f.write <<-L.gsub(/ {8}/, "")
GEM
remote: https://rubygems.org/
specs:
@@ -401,7 +401,7 @@ class TestGem < Gem::TestCase
install_specs bundler_latest, bundler_previous
File.open("Gemfile.lock", "w") do |f|
- f.write <<~L
+ f.write <<-L.gsub(/ {8}/, "")
GEM
remote: https://rubygems.org/
specs:
@@ -425,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
+ f.write <<-L.gsub(/ {8}/, "")
GEM
remote: https://rubygems.org/
specs:
@@ -516,10 +516,7 @@ class TestGem < Gem::TestCase
Gem.clear_paths
- with_env("GEM_HOME" => "foo", "GEM_PATH" => "bar") do
- assert_equal("foo", Gem.dir)
- assert_equal("bar", Gem.path.first)
- end
+ assert_nil Gem::Specification.send(:class_variable_get, :@@all)
end
def test_self_configuration
@@ -642,13 +639,13 @@ class TestGem < Gem::TestCase
FileUtils.rm_r @gemhome
Gem.use_paths @gemhome
- Gem.ensure_gem_subdirectories @gemhome, 0o750
+ Gem.ensure_gem_subdirectories @gemhome, 0750
assert_directory_exists File.join(@gemhome, "cache")
- 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?
+ 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?
def test_self_ensure_gem_directories_safe_permissions
FileUtils.rm_r @gemhome
@@ -658,21 +655,17 @@ class TestGem < Gem::TestCase
File.umask 0
Gem.ensure_gem_subdirectories @gemhome
- assert_equal 0, File::Stat.new(@gemhome).mode & 0o002
- assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 0o002
+ assert_equal 0, File::Stat.new(@gemhome).mode & 002
+ assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 002
ensure
File.umask old_umask
- end unless Gem.win_platform?
+ end unless win_platform?
def test_self_ensure_gem_directories_missing_parents
gemdir = File.join @tempdir, "a/b/c/gemdir"
- begin
- FileUtils.rm_rf File.join(@tempdir, "a")
- rescue StandardError
- nil
- end
+ FileUtils.rm_rf File.join(@tempdir, "a") rescue nil
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
@@ -680,45 +673,37 @@ class TestGem < Gem::TestCase
assert_directory_exists util_cache_dir
end
- unless Gem.win_platform? || Process.uid.zero? # only for FS that support write protection
+ unless 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"
- begin
- FileUtils.rm_r gemdir
- rescue StandardError
- nil
- end
+ FileUtils.rm_r gemdir rescue nil
refute File.exist?(gemdir), "manually remove #{gemdir}, tests are broken"
FileUtils.mkdir_p gemdir
- FileUtils.chmod 0o400, gemdir
+ FileUtils.chmod 0400, gemdir
Gem.use_paths gemdir
Gem.ensure_gem_subdirectories gemdir
refute File.exist?(util_cache_dir)
ensure
- FileUtils.chmod 0o600, gemdir
+ FileUtils.chmod 0600, gemdir
end
def test_self_ensure_gem_directories_write_protected_parents
parent = File.join(@tempdir, "egd")
gemdir = "#{parent}/a/b/c"
- begin
- FileUtils.rm_r parent
- rescue StandardError
- nil
- end
+ FileUtils.rm_r parent rescue nil
refute File.exist?(parent), "manually remove #{parent}, tests are broken"
FileUtils.mkdir_p parent
- FileUtils.chmod 0o400, parent
+ FileUtils.chmod 0400, parent
Gem.use_paths(gemdir)
Gem.ensure_gem_subdirectories gemdir
refute File.exist? File.join(gemdir, "gems")
ensure
- FileUtils.chmod 0o600, parent
+ FileUtils.chmod 0600, parent
end
def test_self_ensure_gem_directories_non_existent_paths
@@ -750,7 +735,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
@@ -782,7 +767,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
@@ -980,11 +965,11 @@ class TestGem < Gem::TestCase
pend "chmod not supported" if Gem.win_platform?
begin
- File.chmod 0o444, "test"
+ File.chmod 0444, "test"
assert_equal ["\xCF", "\x80"], Gem.read_binary("test").chars.to_a
ensure
- File.chmod 0o644, "test"
+ File.chmod 0644, "test"
end
end
@@ -1045,8 +1030,7 @@ 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
@@ -1069,7 +1053,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_non_mri_implementations
- 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]"
+ 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]"
assert_equal Gem::Version.new("2.5.0"), Gem.ruby_version
ensure
@@ -1077,7 +1061,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_svn_prerelease
- util_set_RUBY_VERSION "2.6.0", -1, 63_539, "ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]"
+ util_set_RUBY_VERSION "2.6.0", -1, 63539, "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
@@ -1093,7 +1077,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, 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"
+ 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"
assert_equal Gem::Version.new("2.6.0.preview2"), Gem.ruby_version
ensure
@@ -1101,7 +1085,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_svn_trunk
- util_set_RUBY_VERSION "1.9.2", -1, 23_493, "ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]"
+ util_set_RUBY_VERSION "1.9.2", -1, 23493, "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
@@ -1257,8 +1241,8 @@ class TestGem < Gem::TestCase
Gem.try_activate "a_file"
end
- assert_include(e.message, "Could not find 'b' ")
- assert_include(e.message, "at: #{a.spec_file}")
+ assert_match %r{Could not find 'b' }, e.message
+ assert_match %r{at: #{a.spec_file}}, e.message
end
def test_self_try_activate_missing_prerelease
@@ -1278,12 +1262,13 @@ class TestGem < Gem::TestCase
Gem.try_activate "a_file"
end
- assert_match(/Could not find 'b' \(= 1.0rc1\)/, e.message)
+ assert_match %r{Could not find 'b' \(= 1.0rc1\)}, e.message
end
def test_self_try_activate_missing_extensions
spec = util_spec "ext", "1" do |s|
s.extensions = %w[ext/extconf.rb]
+ s.mark_version
s.installed_by_version = v("2.2")
end
@@ -1296,7 +1281,7 @@ class TestGem < Gem::TestCase
refute Gem.try_activate "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
@@ -1328,7 +1313,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
@@ -1380,7 +1365,7 @@ class TestGem < Gem::TestCase
r.gem "b", "= 1"
end
- activated = Gem::Specification.map(&:full_name)
+ activated = Gem::Specification.map {|x| x.full_name }
assert_equal %w[a-1 b-1 c-2], activated.sort
end
@@ -1405,7 +1390,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
@@ -1518,31 +1503,19 @@ class TestGem < Gem::TestCase
def test_load_env_plugins
with_plugin("load") { Gem.load_env_plugins }
- begin
- assert_equal :loaded, TEST_PLUGIN_LOAD
- rescue StandardError
- nil
- end
+ assert_equal :loaded, TEST_PLUGIN_LOAD rescue nil
util_remove_interrupt_command
# Should attempt to cause a StandardError
with_plugin("standarderror") { Gem.load_env_plugins }
- begin
- assert_equal :loaded, TEST_PLUGIN_STANDARDERROR
- rescue StandardError
- nil
- end
+ assert_equal :loaded, TEST_PLUGIN_STANDARDERROR rescue nil
util_remove_interrupt_command
# Should attempt to cause an Exception
- with_plugin("scripterror") { Gem.load_env_plugins }
- begin
- assert_equal :loaded, TEST_PLUGIN_EXCEPTION
- rescue StandardError
- nil
- end
+ with_plugin("exception") { Gem.load_env_plugins }
+ assert_equal :loaded, TEST_PLUGIN_EXCEPTION rescue nil
end
def test_gem_path_ordering
@@ -1554,20 +1527,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
@@ -1577,25 +1550,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)
@@ -1610,11 +1583,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"),
@@ -1665,14 +1638,14 @@ class TestGem < Gem::TestCase
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
@@ -1722,14 +1695,14 @@ class TestGem < Gem::TestCase
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
@@ -1775,7 +1748,7 @@ class TestGem < Gem::TestCase
#
# FIXME what does this solve precisely? -ebh
#
- @additional.each do |_dir|
+ @additional.each do |dir|
Gem.ensure_gem_subdirectories @gemhome
end
end
diff --git a/test/rubygems/test_gem_available_set.rb b/test/rubygems/test_gem_available_set.rb
index 7c24d25bcb..595a896cb0 100644
--- a/test/rubygems/test_gem_available_set.rb
+++ b/test/rubygems/test_gem_available_set.rb
@@ -37,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(&:full_name)
+ assert_equal %w[a-1], set.find_all(dep).map {|spec| spec.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(&:full_name).sort
+ set.find_all(dep).map {|spec| spec.full_name }.sort
end
def test_match_platform
@@ -123,7 +123,7 @@ class TestGemAvailableSet < Gem::TestCase
set.add a2a, @source
set.add a2, @source
- g = set.sorted.map(&:spec)
+ g = set.sorted.map {|t| t.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 6d88810493..1de4809aec 100644
--- a/test/rubygems/test_gem_bundler_version_finder.rb
+++ b/test/rubygems/test_gem_bundler_version_finder.rb
@@ -79,7 +79,7 @@ class TestGemBundlerVersionFinder < Gem::TestCase
end
def test_deleted_directory
- pend "Cannot perform this test on windows" if Gem.win_platform?
+ pend "Cannot perform this test on windows" if 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
deleted file mode 100644
index a28ee49f4b..0000000000
--- a/test/rubygems/test_gem_ci_detector.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "helper"
-require "rubygems"
-
-class TestCiDetector < Gem::TestCase
- def test_ci?
- with_env("FOO" => "bar") { assert_equal(false, Gem::CIDetector.ci?) }
- with_env("CI" => "true") { assert_equal(true, Gem::CIDetector.ci?) }
- 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
-end
diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb
index 3695f9488f..5768703daf 100644
--- a/test/rubygems/test_gem_command.rb
+++ b/test/rubygems/test_gem_command.rb
@@ -16,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
]
@@ -56,9 +56,7 @@ class TestGemCommand < Gem::TestCase
end
def test_self_extra_args
- verbose = $VERBOSE
- $VERBOSE = nil
- separator = $;
+ verbose, $VERBOSE, separator = $VERBOSE, nil, $;
extra_args = Gem::Command.extra_args
Gem::Command.extra_args = %w[--all]
@@ -71,6 +69,7 @@ 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
@@ -92,7 +91,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"
@@ -102,7 +101,7 @@ class TestGemCommand < Gem::TestCase
@cmd.invoke
end
- assert_match(/Usage: gem doit/, @ui.output)
+ assert_match %r{Usage: gem doit}, @ui.output
end
def test_invoke
@@ -153,7 +152,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
@@ -176,7 +175,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
@@ -188,7 +187,7 @@ class TestGemCommand < Gem::TestCase
@cmd.invoke "-h"
end
- assert_match(/Usage: gem doit/, @ui.output)
+ assert_match %r{Usage: gem doit}, @ui.output
end
def test_add_option
@@ -204,13 +203,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"])
@@ -234,11 +233,11 @@ class TestGemCommand < Gem::TestCase
WARNING: The \"--test\" option has been deprecated and will be removed in Rubygems 3.1.
EXPECTED
- test_command = Class.new(Gem::Command) do
+ testCommand = 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
@@ -250,7 +249,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg
end
end
- cmd = test_command.new
+ cmd = testCommand.new
use_ui @ui do
cmd.invoke("--test")
@@ -263,11 +262,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
- test_command = Class.new(Gem::Command) do
+ testCommand = 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
@@ -279,7 +278,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur
end
end
- cmd = test_command.new
+ cmd = testCommand.new
use_ui @ui do
cmd.invoke("--test")
@@ -292,11 +291,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
- test_command = Class.new(Gem::Command) do
+ testCommand = 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
@@ -308,7 +307,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg
end
end
- cmd = test_command.new
+ cmd = testCommand.new
use_ui @ui do
cmd.invoke("--test")
@@ -321,11 +320,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
- test_command = Class.new(Gem::Command) do
+ testCommand = 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
@@ -337,7 +336,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur
end
end
- cmd = test_command.new
+ cmd = testCommand.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 f04ec0cafa..3495af9f5a 100644
--- a/test/rubygems/test_gem_command_manager.rb
+++ b/test/rubygems/test_gem_command_manager.rb
@@ -4,7 +4,7 @@ require_relative "helper"
require "rubygems/command_manager"
class TestGemCommandManager < Gem::TestCase
- PROJECT_DIR = File.expand_path("../..", __dir__)
+ PROJECT_DIR = File.expand_path("../..", __dir__).tap(&Gem::UNTAINT)
def setup
super
@@ -150,7 +150,7 @@ class TestGemCommandManager < Gem::TestCase
end
end
- assert_match(/install isn't a directory\./i, @ui.error)
+ assert_match(/install isn't a directory./i, @ui.error)
end
def test_process_args_with_c_flag_path_not_found
@@ -164,7 +164,7 @@ class TestGemCommandManager < Gem::TestCase
end
end
- assert_match(/#{Regexp.quote(custom_start_point)} isn't a directory\./i, @ui.error)
+ assert_match(/#{custom_start_point} isn't a directory./i, @ui.error)
end
def test_process_args_bad_arg
@@ -177,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|
@@ -187,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]
@@ -197,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 .
@@ -211,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
@@ -303,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]
@@ -312,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]
@@ -327,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"
@@ -368,7 +368,7 @@ 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
@@ -393,7 +393,7 @@ 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 9\.9\.9/, @ui.error)
+ 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 d44126d204..9b2a245064 100644
--- a/test/rubygems/test_gem_commands_build_command.rb
+++ b/test/rubygems/test_gem_commands_build_command.rb
@@ -26,9 +26,8 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
@gem = util_spec "some_gem" do |s|
- s.license = "AGPL-3.0-only"
+ s.license = "AGPL-3.0"
s.files = ["README.md"]
- s.required_ruby_version = "2.3.0"
end
@cmd = Gem::Commands::BuildCommand.new
@@ -179,7 +178,6 @@ 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)
@@ -200,9 +198,8 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
error = @ui.error.split "\n"
- 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: 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: See https://guides.rubygems.org/specification-reference/ for help", error.shift
assert_equal [], error
@@ -596,7 +593,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
def test_build_signed_gem
- pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform?
+ pend "openssl is missing" unless Gem::HAVE_OPENSSL && !java_platform?
trust_dir = Gem::Security.trust_dir
@@ -623,7 +620,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
def test_build_signed_gem_with_cert_expiration_length_days
- pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform?
+ pend "openssl is missing" unless Gem::HAVE_OPENSSL && !java_platform?
gem_path = File.join Gem.user_home, ".gem"
Dir.mkdir gem_path
@@ -667,7 +664,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
def test_build_auto_resign_cert
- pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform?
+ pend "openssl is missing" unless Gem::HAVE_OPENSSL && !java_platform?
gem_path = File.join Gem.user_home, ".gem"
Dir.mkdir gem_path
@@ -703,7 +700,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 c173467935..e05cbd5d99 100644
--- a/test/rubygems/test_gem_commands_cert_command.rb
+++ b/test/rubygems/test_gem_commands_cert_command.rb
@@ -47,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
@@ -129,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!",
@@ -161,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!",
@@ -221,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!",
@@ -284,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
@@ -306,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
@@ -327,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
@@ -476,7 +476,7 @@ Removed '/CN=alternate/DC=example'
def test_execute_sign
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0o600
+ Gem::Security.write ALTERNATE_CERT, path, 0600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -498,14 +498,14 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0o100600 & (~File.umask)
+ mask = 0100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(path).mode unless win_platform?
end
def test_execute_sign_encrypted_key
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0o600
+ Gem::Security.write ALTERNATE_CERT, path, 0600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -527,9 +527,9 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0o100600 & (~File.umask)
+ mask = 0100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(path).mode unless win_platform?
end
def test_execute_sign_default
@@ -542,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, 0o600
+ Gem::Security.write ALTERNATE_CERT, path, 0600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -559,22 +559,22 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0o100600 & (~File.umask)
+ mask = 0100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(path).mode unless 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, 0o600, PRIVATE_KEY_PASSPHRASE
+ Gem::Security.write ENCRYPTED_PRIVATE_KEY, private_key_path, 0600, 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, 0o600
+ Gem::Security.write ALTERNATE_CERT, path, 0600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -591,9 +591,9 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0o100600 & (~File.umask)
+ mask = 0100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(path).mode unless win_platform?
end
def test_execute_sign_no_cert
@@ -603,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, 0o600
+ Gem::Security.write ALTERNATE_CERT, path, 0600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -631,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, 0o600
+ Gem::Security.write ALTERNATE_CERT, path, 0600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -657,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, 0o600
+ Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600
assert_equal "/CN=nobody/DC=example", EXPIRED_PUBLIC_CERT.issuer.to_s
@@ -677,9 +677,8 @@ 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 expired certificate will be located at: #{Regexp.quote(expected_path)}\.[0-9]+/,
+ /INFO: Your certificate #{tmp_expired_cert_file} has been re-signed\nINFO: Your expired certificate will be located at: #{expected_path}\.[0-9]+/,
@ui.output
)
assert_equal "", @ui.error
@@ -690,7 +689,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, 0o600
+ Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600
assert_equal "/CN=nobody/DC=example", EXPIRED_PUBLIC_CERT.issuer.to_s
@@ -733,12 +732,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(&:to_pem)
+ @cmd.options[:add].map {|cert| cert.to_pem }
assert_equal %w[nobody example], @cmd.options[:remove]
assert_equal %w[nobody@example other@example],
- @cmd.options[:build].map(&:to_s)
+ @cmd.options[:build].map {|name| name.to_s }
assert_equal ["", "example"], @cmd.options[:list]
end
@@ -779,7 +778,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
@@ -790,7 +789,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
@@ -808,7 +807,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_cleanup_command.rb b/test/rubygems/test_gem_commands_cleanup_command.rb
index bcb8871b57..bcbcf8b54d 100644
--- a/test/rubygems/test_gem_commands_cleanup_command.rb
+++ b/test/rubygems/test_gem_commands_cleanup_command.rb
@@ -166,10 +166,10 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
end
def test_execute_all_user_no_sudo
- FileUtils.chmod 0o555, @gemhome
+ FileUtils.chmod 0555, @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]
@@ -183,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 0o755, @gemhome
- end unless Gem.win_platform? || Process.uid.zero?
+ FileUtils.chmod 0755, @gemhome
+ end unless win_platform? || Process.uid.zero?
def test_execute_dry_run
@cmd.options[:args] = %w[a]
@@ -231,7 +231,7 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/^Skipped default gems: b-2/, @ui.output)
+ assert_match %r{^Skipped default gems: b-2}, @ui.output
assert_empty @ui.error
end
@@ -243,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
@@ -270,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 d8e6ba3dec..8d7f301a5b 100644
--- a/test/rubygems/test_gem_commands_contents_command.rb
+++ b/test/rubygems/test_gem_commands_contents_command.rb
@@ -28,7 +28,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
assert_match %r{lib/foo\.rb}, @ui.output
- assert_match(/Rakefile/, @ui.output)
+ assert_match %r{Rakefile}, @ui.output
assert_equal "", @ui.error
end
@@ -44,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(/Rakefile/, @ui.output)
+ assert_match %r{Rakefile}, @ui.output
assert_equal "", @ui.error
end
@@ -57,8 +57,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
end
- assert_match(/Unable to find gem 'foo' in default gem paths/, @ui.output)
- assert_match(/Directories searched:/, @ui.output)
+ assert_match %r{Unable to find gem 'foo' in default gem paths}, @ui.output
+ assert_match %r{Directories searched:}, @ui.output
assert_equal "", @ui.error
end
@@ -72,7 +72,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
assert_match %r{lib/foo\.rb}, @ui.output
- assert_match(/Rakefile/, @ui.output)
+ assert_match %r{Rakefile}, @ui.output
assert_equal "", @ui.error
end
@@ -87,7 +87,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
assert_match %r{lib/foo\.rb}, @ui.output
- refute_match(/Rakefile/, @ui.output)
+ refute_match %r{Rakefile}, @ui.output
assert_equal "", @ui.error
end
@@ -148,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(/Rakefile/, @ui.output)
+ assert_match %r{Rakefile}, @ui.output
assert_equal "", @ui.error
end
diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb
index 48252d84d4..5839970ede 100644
--- a/test/rubygems/test_gem_commands_environment_command.rb
+++ b/test/rubygems/test_gem_commands_environment_command.rb
@@ -12,8 +12,7 @@ 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"
@@ -23,33 +22,34 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase
@cmd.execute
end
- 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{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 %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
@@ -126,6 +126,7 @@ 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
index e52fe247a2..9d0f7eb94a 100644
--- a/test/rubygems/test_gem_commands_exec_command.rb
+++ b/test/rubygems/test_gem_commands_exec_command.rb
@@ -71,10 +71,10 @@ class TestGemCommandsExecCommand < Gem::TestCase
assert_equal options, {
args: ["install", "--no-color", "--help", "--verbose"],
executable: "pod",
- explicit_prerelease: false,
+ :explicit_prerelease => false,
gem_name: "cocoapods",
prerelease: false,
- version: Gem::Requirement.new(["> 1", "< 1.3"]),
+ :version => Gem::Requirement.new(["> 1", "< 1.3"]),
build_args: nil,
}
end
@@ -87,7 +87,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
args: [],
executable: "rails",
gem_name: "rails",
- version: Gem::Requirement.new([">= 0"]),
+ :version => Gem::Requirement.new([">= 0"]),
build_args: nil,
}
end
@@ -100,7 +100,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
args: [],
executable: "rails",
gem_name: "rails",
- version: Gem::Requirement.new(["= 7.1"]),
+ :version => Gem::Requirement.new(["= 7.1"]),
build_args: nil,
}
end
@@ -129,7 +129,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
f << "Gem.ui.say #{s.original_name.dump}"
end
end
@@ -149,7 +149,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
f << "Gem.ui.say #{s.original_name.dump}"
end
end
@@ -159,7 +159,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
f << "Gem.ui.say #{s.original_name.dump}"
end
end
@@ -184,7 +184,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -225,7 +225,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -236,13 +236,13 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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|
+ write_file File.join(*%W[gems #{s.original_name} extconf.rb]) do |f|
f.write <<-RUBY
gem('with_platform', '~> 2.0')
require 'with_platform'
@@ -290,7 +290,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
f << "Gem.ui.say #{s.original_name.dump}"
end
end
@@ -310,7 +310,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
f << "raise #{s.original_name.dump}"
end
end
@@ -333,11 +333,11 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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|
+ 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
@@ -357,11 +357,11 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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|
+ 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
@@ -388,7 +388,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -415,7 +415,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -445,7 +445,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -504,15 +504,15 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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.executables = %w[foo ]
s.files = %w[bin/foo lib/a.rb]
- write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ 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
@@ -532,15 +532,15 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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.executables = %w[foo ]
s.files = %w[bin/foo lib/a.rb]
- write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ 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
@@ -558,7 +558,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -585,7 +585,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -603,7 +603,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -612,7 +612,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -632,7 +632,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -648,7 +648,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -657,7 +657,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -684,7 +684,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -693,7 +693,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -713,7 +713,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
f << "Gem.ui.say #{s.original_name.dump}"
end
end
@@ -731,13 +731,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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
+ invoke "gem", "uninstall", "--verbose", "-x", "a" rescue nil
refute_includes @ui.output, "running gem exec with"
assert_includes @ui.output, "Successfully uninstalled a-2\n"
@@ -759,7 +753,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -769,7 +763,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
assert_raise Gem::MockGemUi::TermError do
invoke "a"
end
- assert_equal "ERROR: Could not find a valid gem 'a' (>= 0) in any repository\n" \
+ 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
@@ -807,7 +801,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
@@ -816,7 +810,7 @@ class TestGemCommandsExecCommand < Gem::TestCase
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|
+ 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
diff --git a/test/rubygems/test_gem_commands_generate_index_command.rb b/test/rubygems/test_gem_commands_generate_index_command.rb
new file mode 100644
index 0000000000..d16d82bdb3
--- /dev/null
+++ b/test/rubygems/test_gem_commands_generate_index_command.rb
@@ -0,0 +1,81 @@
+# 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 359da0a6d0..090db73284 100644
--- a/test/rubygems/test_gem_commands_help_command.rb
+++ b/test/rubygems/test_gem_commands_help_command.rb
@@ -56,7 +56,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase
if Gem::HAVE_OPENSSL
assert_empty err
- refute_match(/No command found for /, out)
+ refute_match %r{No command found for }, out
end
end
end
@@ -64,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 83e4c8a896..54a87853ef 100644
--- a/test/rubygems/test_gem_commands_info_command.rb
+++ b/test/rubygems/test_gem_commands_info_command.rb
@@ -33,12 +33,12 @@ class TestGemCommandsInfoCommand < Gem::TestCase
@cmd.execute
end
- 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 %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_match "", @ui.error
end
diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb
index 5b09512ac4..d03b884462 100644
--- a/test/rubygems/test_gem_commands_install_command.rb
+++ b/test/rubygems/test_gem_commands_install_command.rb
@@ -44,7 +44,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_explicit_version_includes_prerelease
@@ -66,7 +66,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
end
- assert_equal %w[a-2.a], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2.a], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_local
@@ -92,7 +92,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
end
@@ -183,35 +183,40 @@ 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(&:full_name).sort
+ assert_equal %w[a-2 b-2.a c-3], @cmd.installed_specs.map {|spec| spec.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 Gem.win_platform?
+ pend "skipped on MS Windows (chmod has no effect)" if win_platform?
pend "skipped in root privilege" if Process.uid.zero?
- spec_fetcher do |fetcher|
- fetcher.download "a", 2
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem "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
- FileUtils.chmod 0o755, @userhome
- FileUtils.chmod 0o555, @gemhome
+ orig_dir = Dir.pwd
+ begin
+ FileUtils.chmod 0755, @userhome
+ FileUtils.chmod 0555, @gemhome
- assert_raise Gem::MockGemUi::SystemExitException, @ui.error do
- @cmd.execute
+ Dir.chdir @tempdir
+ assert_raise Gem::FilePermissionError do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ FileUtils.chmod 0755, @gemhome
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
@@ -228,7 +233,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
@@ -247,7 +252,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
@@ -431,6 +436,21 @@ 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
@@ -446,7 +466,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_prerelease_wins_over_previous_ver
@@ -464,7 +484,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2.a], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2.a], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_with_version_specified_by_colon
@@ -481,7 +501,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_prerelease_skipped_when_non_pre_available
@@ -499,7 +519,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_required_ruby_version
@@ -529,7 +549,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_required_ruby_version_upper_bound
@@ -550,7 +570,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2.0], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2.0], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_required_ruby_version_specific_not_met
@@ -588,7 +608,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1.0], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-1.0], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_required_ruby_version_specific_prerelease_not_met
@@ -755,7 +775,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
end
@@ -775,7 +795,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
end
@@ -795,7 +815,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
a1_gemspec = File.join(@gemhome, "specifications", "a-1.gemspec")
@@ -849,7 +869,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
@@ -883,7 +903,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2 b-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2 b-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "2 gems installed", @ui.output
end
@@ -925,7 +945,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1 b-1], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-1 b-1], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_execute_conservative
@@ -951,7 +971,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[b-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[b-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_equal "", @ui.error
assert_match "1 gem installed", @ui.output
@@ -973,7 +993,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem "a", ">= 0"
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|s| s.full_name }
assert done_installing, "documentation was not generated"
end
@@ -987,7 +1007,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem "a", ">= 0"
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_install_gem_ignore_dependencies_remote_platform_local
@@ -1004,7 +1024,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem "a", ">= 0"
- assert_equal %W[a-3-#{local}], @cmd.installed_specs.map(&:full_name)
+ assert_equal %W[a-3-#{local}], @cmd.installed_specs.map {|spec| spec.full_name }
end
def test_install_gem_ignore_dependencies_specific_file
@@ -1018,7 +1038,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(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|s| s.full_name }
end
def test_parses_requirement_from_gemname
@@ -1047,7 +1067,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
assert_equal 2, e.exit_code
- assert_match(/Could not find a valid gem 'a' \(= 10.0\)/, @ui.error)
+ assert_match %r{Could not find a valid gem 'a' \(= 10.0\)}, @ui.error
end
def test_show_errors_on_failure
@@ -1088,7 +1108,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
@@ -1113,7 +1133,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "1 gem installed", @ui.output
@@ -1140,7 +1160,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "Using a (2)", @ui.output
assert File.exist?("#{@gemdeps}.lock")
@@ -1164,7 +1184,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "Using a (2)", @ui.output
assert !File.exist?("#{@gemdeps}.lock")
@@ -1189,7 +1209,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "Using a (1)", @ui.output
end
@@ -1211,7 +1231,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
+ assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
assert_match "Installing a (2)", @ui.output
end
@@ -1234,7 +1254,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map(&:full_name)
+ names = @cmd.installed_specs.map {|spec| spec.full_name }
assert_equal %w[q-1.0 r-2.0], names
@@ -1261,7 +1281,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map(&:full_name)
+ names = @cmd.installed_specs.map {|spec| spec.full_name }
assert_equal %w[r-2.0], names
@@ -1288,7 +1308,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map(&:full_name)
+ names = @cmd.installed_specs.map {|spec| spec.full_name }
assert_equal %w[q-1.0 r-2.0], names
@@ -1320,7 +1340,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map(&:full_name)
+ names = @cmd.installed_specs.map {|spec| spec.full_name }
assert_equal %w[q-1.0 r-2.0], names
@@ -1337,7 +1357,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"
@@ -1355,7 +1375,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map(&:full_name)
+ names = @cmd.installed_specs.map {|spec| spec.full_name }
assert_equal %w[r-2.0], names
@@ -1534,7 +1554,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
def test_suggest_update_if_enabled
- TestUpdateSuggestion.with_eligible_environment(cmd: @cmd) do
+ TestUpdateSuggestion.with_eglible_environment(cmd: @cmd) do
spec_fetcher do |fetcher|
fetcher.gem "a", 2
end
diff --git a/test/rubygems/test_gem_commands_mirror.rb b/test/rubygems/test_gem_commands_mirror.rb
index 2256a3ab33..95f3bbcc9f 100644
--- a/test/rubygems/test_gem_commands_mirror.rb
+++ b/test/rubygems/test_gem_commands_mirror.rb
@@ -15,6 +15,6 @@ class TestGemCommandsMirrorCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/Install the rubygems-mirror/i, @ui.error)
+ assert_match %r{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 d9e518048c..b60e29ace9 100644
--- a/test/rubygems/test_gem_commands_open_command.rb
+++ b/test/rubygems/test_gem_commands_open_command.rb
@@ -22,23 +22,20 @@ class TestGemCommandsOpenCommand < Gem::TestCase
def test_execute
@cmd.options[:args] = %w[foo]
- @cmd.options[:editor] = (ruby_with_rubygems_in_load_path + ["-e", "puts(ARGV,Dir.pwd)", "--"]).join(" ")
+ @cmd.options[:editor] = "#{ruby_with_rubygems_in_load_path} -eexit --"
gem "foo", "1.0.0"
spec = gem "foo", "1.0.1"
assert_nothing_raised Gem::MockGemUi::TermError do
- stdout, stderr = capture_subprocess_io do
+ Dir.stub(:chdir, spec.full_gem_path) 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
@@ -53,7 +50,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
end
end
- assert_match(/Unable to find gem 'foo'/, @ui.output)
+ assert_match %r{Unable to find gem 'foo'}, @ui.output
assert_equal "", @ui.error
end
@@ -66,7 +63,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
end
end
- assert_match(/Unable to find gem 'foo'/, @ui.output)
+ assert_match %r{Unable to find gem 'foo'}, @ui.output
assert_equal "", @ui.error
end
@@ -95,7 +92,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
end
end
- assert_match(/'foo' is a default gem and can't be opened\./, @ui.output)
+ assert_match %r{'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_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb
index eddd8afaf5..9b1e077e65 100644
--- a/test/rubygems/test_gem_commands_owner_command.rb
+++ b/test/rubygems/test_gem_commands_owner_command.rb
@@ -44,14 +44,14 @@ EOF
@cmd.show_owners("freewill")
end
- assert_equal Gem::Net::HTTP::Get, @stub_fetcher.last_request.class
+ assert_equal Net::HTTP::Get, @stub_fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"]
- 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)
+ 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
end
def test_show_owners_dont_load_objects
@@ -88,8 +88,8 @@ EOF
@cmd.show_owners("freewill")
end
- assert_match(/Owners for gem: freewill/, @stub_ui.output)
- assert_match(/- user1@example.com/, @stub_ui.output)
+ assert_match %r{Owners for gem: freewill}, @stub_ui.output
+ assert_match %r{- user1@example.com}, @stub_ui.output
end
def test_show_owners_setting_up_host
@@ -103,8 +103,8 @@ EOF
@cmd.show_owners("freewill")
end
- assert_match(/Owners for gem: freewill/, @stub_ui.output)
- assert_match(/- user1@example.com/, @stub_ui.output)
+ assert_match %r{Owners for gem: freewill}, @stub_ui.output
+ assert_match %r{- user1@example.com}, @stub_ui.output
end
def test_show_owners_denied
@@ -165,7 +165,7 @@ EOF
@cmd.add_owners("freewill", ["user-new1@example.com"])
end
- assert_equal Gem::Net::HTTP::Post, @stub_fetcher.last_request.class
+ assert_equal 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
@@ -218,8 +218,8 @@ EOF
end
assert_match add_owner_response, @stub_ui.output
- assert_match(/Owners for gem: freewill/, @stub_ui.output)
- assert_match(/- user1@example.com/, @stub_ui.output)
+ assert_match %r{Owners for gem: freewill}, @stub_ui.output
+ assert_match %r{- user1@example.com}, @stub_ui.output
end
def test_add_owners_key
@@ -244,7 +244,7 @@ EOF
@cmd.remove_owners("freewill", ["user-remove1@example.com"])
end
- assert_equal Gem::Net::HTTP::Delete, @stub_fetcher.last_request.class
+ assert_equal 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
@@ -471,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 "Username/email:", @stub_ui.output
+ assert_match "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
@@ -495,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 "Username/email:", @stub_ui.output
+ assert_match "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 a17d7837c9..a6170c1702 100644
--- a/test/rubygems/test_gem_commands_pristine_command.rb
+++ b/test/rubygems/test_gem_commands_pristine_command.rb
@@ -54,7 +54,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
end
def test_execute_user_install
- FileUtils.chmod 0o555, @gemhome
+ FileUtils.chmod 0555, @gemhome
a = util_spec "a" do |s|
s.executables = %w[foo]
@@ -99,7 +99,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
assert_equal "Restored #{a.full_name}", out.shift
assert_empty out, out.inspect
ensure
- FileUtils.chmod(0o755, @gemhome)
+ FileUtils.chmod(0755, @gemhome)
end
def test_execute_all
@@ -158,11 +158,11 @@ class TestGemCommandsPristineCommand < Gem::TestCase
assert_path_exist gem_exec
- ruby_exec = format Gem.default_exec_format, "ruby"
+ ruby_exec = sprintf Gem.default_exec_format, "ruby"
- bin_env = Gem.win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " "
+ bin_env = win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " "
- assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(gem_exec))
+ assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(gem_exec)
end
def test_execute_extensions_explicit
@@ -296,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]
@@ -392,9 +392,6 @@ 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
@@ -507,7 +504,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
end
end
- assert_match(/at least one gem name/, e.message)
+ assert_match %r{at least one gem name}, e.message
end
def test_execute_only_executables
@@ -599,7 +596,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
FileUtils.rm gem_exec
FileUtils.rm gem_bindir
- @cmd.handle_options ["--all", "--only-executables", "--bindir", gem_bindir.to_s]
+ @cmd.handle_options ["--all", "--only-executables", "--bindir", "#{gem_bindir}"]
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 a7a18ff4ab..cb615f47b8 100644
--- a/test/rubygems/test_gem_commands_push_command.rb
+++ b/test/rubygems/test_gem_commands_push_command.rb
@@ -3,7 +3,6 @@
require_relative "helper"
require_relative "multifactor_auth_utilities"
require "rubygems/commands/push_command"
-require "rubygems/config_file"
class TestGemCommandsPushCommand < Gem::TestCase
def setup
@@ -58,9 +57,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.send_gem(@path)
end
- assert_match(/Pushing gem to #{@host}.../, @ui.output)
+ assert_match %r{Pushing gem to #{@host}...}, @ui.output
- assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal 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"]
@@ -77,7 +76,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.execute
- assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal 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"]
@@ -96,7 +95,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.execute
- assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal 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"]
@@ -108,7 +107,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
end
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@spec.metadata["allowed_push_host"]}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "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"]
@@ -116,7 +115,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.execute
- assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal 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"]
@@ -159,7 +158,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -193,7 +192,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -230,11 +229,11 @@ 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 Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -275,7 +274,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -305,7 +304,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -317,9 +316,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
# do not set @host
use_ui(@ui) { @cmd.send_gem(@path) }
- assert_match(/Pushing gem to #{host}.../, @ui.output)
+ assert_match %r{Pushing gem to #{host}...}, @ui.output
- assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal 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"]
@@ -547,7 +546,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 "Username/email:", @ui.output
+ assert_match "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
@@ -588,7 +587,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 "Username/email:", @ui.output
+ assert_match "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 8e590df124..c76f1c0f63 100644
--- a/test/rubygems/test_gem_commands_query_command.rb
+++ b/test/rubygems/test_gem_commands_query_command.rb
@@ -23,7 +23,9 @@ class TestGemCommandsQueryCommandWithInstalledGems < Gem::TestCase
include TestGemCommandsQueryCommandSetup
def test_execute
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-r]
@@ -44,7 +46,9 @@ pl (1 i386-linux)
end
def test_execute_all
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-r --all]
@@ -65,7 +69,9 @@ pl (1 i386-linux)
end
def test_execute_all_prerelease
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-r --all --prerelease]
@@ -305,7 +311,9 @@ pl (1)
end
def test_execute_local
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.options[:domain] = :local
@@ -326,7 +334,9 @@ pl (1 i386-linux)
end
def test_execute_local_notty
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[]
@@ -346,7 +356,9 @@ pl (1 i386-linux)
end
def test_execute_local_quiet
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.options[:domain] = :local
Gem.configuration.verbose = false
@@ -365,7 +377,9 @@ pl (1 i386-linux)
end
def test_execute_no_versions
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-r --no-versions]
@@ -386,7 +400,9 @@ pl
end
def test_execute_notty
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-r]
@@ -424,7 +440,9 @@ a (3.a)
end
def test_execute_prerelease_local
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-l --prerelease]
@@ -444,7 +462,9 @@ pl (1 i386-linux)
end
def test_execute_no_prerelease_local
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[-l --no-prerelease]
@@ -464,7 +484,9 @@ pl (1 i386-linux)
end
def test_execute_remote
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.options[:domain] = :remote
@@ -485,7 +507,9 @@ pl (1 i386-linux)
end
def test_execute_remote_notty
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[]
@@ -505,7 +529,9 @@ pl (1 i386-linux)
end
def test_execute_remote_quiet
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.options[:domain] = :remote
Gem.configuration.verbose = false
@@ -544,7 +570,9 @@ pl (1 i386-linux)
# Test for multiple args handling!
def test_execute_multiple_args
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
@cmd.handle_options %w[a pl]
@@ -552,8 +580,8 @@ pl (1 i386-linux)
@cmd.execute
end
- assert_match(/^a /, @stub_ui.output)
- assert_match(/^pl /, @stub_ui.output)
+ assert_match %r{^a }, @stub_ui.output
+ assert_match %r{^pl }, @stub_ui.output
assert_equal "", @stub_ui.error
end
@@ -565,8 +593,8 @@ pl (1 i386-linux)
@cmd.send :show_gems, /a/i
end
- assert_match(/^a /, @stub_ui.output)
- refute_match(/^pl /, @stub_ui.output)
+ assert_match %r{^a }, @stub_ui.output
+ refute_match %r{^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
deleted file mode 100644
index 5e8c797e2d..0000000000
--- a/test/rubygems/test_gem_commands_rebuild_command.rb
+++ /dev/null
@@ -1,145 +0,0 @@
-# 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_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb
index cabb7cf49d..256d27928b 100644
--- a/test/rubygems/test_gem_commands_server_command.rb
+++ b/test/rubygems/test_gem_commands_server_command.rb
@@ -15,6 +15,6 @@ class TestGemCommandsServerCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/Install the rubygems-server/i, @ui.error)
+ assert_match %r{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 77d75e6b88..8eeeb11a9c 100644
--- a/test/rubygems/test_gem_commands_setup_command.rb
+++ b/test/rubygems/test_gem_commands_setup_command.rb
@@ -36,10 +36,12 @@ class TestGemCommandsSetupCommand < Gem::TestCase
create_dummy_files(filelist)
- gemspec = util_spec "bundler", BUNDLER_VERS do |s|
- s.bindir = "exe"
- s.executables = ["bundle", "bundler"]
- end
+ gemspec = Gem::Specification.new
+ gemspec.author = "Us"
+ gemspec.name = "bundler"
+ gemspec.version = BUNDLER_VERS
+ gemspec.bindir = "exe"
+ gemspec.executables = ["bundle", "bundler"]
File.open "bundler/bundler.gemspec", "w" do |io|
io.puts gemspec.to_ruby
@@ -67,7 +69,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
@cmd.execute
- assert_match(/\A#!/, File.read(gem_bin_path))
+ assert_match %r{\A#!}, File.read(gem_bin_path)
end
def test_execute_no_regenerate_binstubs
@@ -90,7 +92,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
@cmd.execute
- assert_match(/\Arequire/, File.read(gem_plugin_path))
+ assert_match %r{\Arequire}, File.read(gem_plugin_path)
end
def test_execute_no_regenerate_plugins
@@ -113,7 +115,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
@cmd.execute
- assert_match(/\Arequire/, File.read(gem_plugin_path))
+ assert_match %r{\Arequire}, File.read(gem_plugin_path)
end
def test_execute_informs_about_installed_executables
@@ -138,13 +140,13 @@ class TestGemCommandsSetupCommand < Gem::TestCase
@cmd.options[:env_shebang] = true
@cmd.execute
- ruby_exec = format Gem.default_exec_format, "ruby"
+ ruby_exec = sprintf Gem.default_exec_format, "ruby"
- 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))
+ 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)
end
def test_destdir_flag_does_not_try_to_write_to_the_default_gem_home
@@ -160,23 +162,6 @@ class TestGemCommandsSetupCommand < Gem::TestCase
end
end
- def test_destdir_flag_regenerates_binstubs
- # install to destdir
- destdir = File.join(@tempdir, "foo")
- gem_bin_path = gem_install "destdir-only-gem", install_dir: destdir
-
- # change binstub manually
- write_file gem_bin_path do |io|
- io.puts "I changed it!"
- end
-
- @cmd.options[:destdir] = destdir
- @cmd.options[:prefix] = "/"
- @cmd.execute
-
- assert_match(/\A#!/, File.read(gem_bin_path))
- end
-
def test_files_in
assert_equal %w[rubygems.rb rubygems/requirement.rb rubygems/ssl_certs/rubygems.org/foo.pem],
@cmd.files_in("lib").sort
@@ -431,7 +416,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
end
end
- def gem_install(name, **options)
+ def gem_install(name)
gem = util_spec name do |s|
s.executables = [name]
s.files = %W[bin/#{name}]
@@ -439,8 +424,8 @@ class TestGemCommandsSetupCommand < Gem::TestCase
write_file File.join @tempdir, "bin", name do |f|
f.puts "#!/usr/bin/ruby"
end
- install_gem gem, **options
- File.join options[:install_dir] || @gemhome, "bin", name
+ install_gem gem
+ File.join @gemhome, "bin", name
end
def gem_install_with_plugin(name)
diff --git a/test/rubygems/test_gem_commands_signin_command.rb b/test/rubygems/test_gem_commands_signin_command.rb
index 29e5edceb7..b7520f5929 100644
--- a/test/rubygems/test_gem_commands_signin_command.rb
+++ b/test/rubygems/test_gem_commands_signin_command.rb
@@ -24,14 +24,14 @@ class TestGemCommandsSigninCommand < Gem::TestCase
def test_execute_when_not_already_signed_in
sign_in_ui = util_capture { @cmd.execute }
- assert_match(/Signed in./, sign_in_ui.output)
+ assert_match %r{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(/Signed in./, sign_in_ui.output)
+ assert_match %r{Signed in.}, sign_in_ui.output
end
def test_execute_when_already_signed_in_with_same_host
@@ -64,8 +64,8 @@ class TestGemCommandsSigninCommand < Gem::TestCase
host = "http://some-gemcutter-compatible-host.org"
sign_in_ui = util_capture(nil, host) { @cmd.execute }
- assert_match(/Enter your #{host} credentials./, sign_in_ui.output)
- assert_match(/Signed in./, sign_in_ui.output)
+ assert_match %r{Enter your #{host} credentials.}, sign_in_ui.output
+ assert_match %r{Signed in.}, sign_in_ui.output
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
credentials = load_yaml_file Gem.configuration.credentials_path
@@ -85,7 +85,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
headers: { "location" => redirected_uri }
)
Gem::RemoteFetcher.fetcher = fetcher
- ui = Gem::MockGemUi.new("you@example.com\nsecret\n\n\n")
+ ui = Gem::MockGemUi.new("you@example.com\nsecret\n\n\n\n\n\n\n\n\n")
assert_raise Gem::MockGemUi::TermError do
use_ui ui do
@@ -106,98 +106,51 @@ class TestGemCommandsSigninCommand < Gem::TestCase
assert_equal api_key, credentials[:rubygems_api_key]
end
- def test_execute_with_key_name_default_scope
+ def test_execute_with_key_name_and_scope
email = "you@example.com"
password = "secret"
- api_key = "1234abcd"
+ api_key = "1234"
fetcher = Gem::RemoteFetcher.fetcher
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\n"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\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 "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 = "1234abcd"
- fetcher = Gem::RemoteFetcher.fetcher
-
- 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_and_exclusive_scope
+ def test_execute_with_key_name_scope_and_mfa_level_of_ui_only
email = "you@example.com"
password = "secret"
- 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"
+ api_key = "1234"
fetcher = Gem::RemoteFetcher.fetcher
mfa_level = "ui_only"
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\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
@@ -205,28 +158,26 @@ class TestGemCommandsSigninCommand < Gem::TestCase
assert_equal api_key, credentials[:rubygems_api_key]
end
- def test_execute_with_key_name_custom_scope_and_mfa_level_of_gem_signin
+ def test_execute_with_key_name_scope_and_mfa_level_of_gem_signin
email = "you@example.com"
password = "secret"
- api_key = "1234abcd"
+ api_key = "1234"
fetcher = Gem::RemoteFetcher.fetcher
mfa_level = "ui_and_gem_signin"
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\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
@@ -237,7 +188,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
def test_execute_with_warnings
email = "you@example.com"
password = "secret"
- api_key = "1234abcd"
+ api_key = "1234"
fetcher = Gem::RemoteFetcher.fetcher
mfa_level = "disabled"
warning = "/[WARNING/] For protection of your account and gems"
@@ -253,14 +204,14 @@ class TestGemCommandsSigninCommand < Gem::TestCase
email = "you@example.com"
password = "secret"
- api_key = "1234abcd"
+ api_key = "1234"
fetcher = Gem::RemoteFetcher.fetcher
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\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"
+ 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
@@ -270,13 +221,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
@@ -291,13 +242,13 @@ class TestGemCommandsSigninCommand < Gem::TestCase
# 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")
+ sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\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 999a14080f..992b127a94 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(/You have successfully signed out/, @sign_out_ui.output)
+ assert_match %r{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(/You are not currently signed in/, @sign_out_ui.error)
+ assert_match %r{You are not currently signed in}, @sign_out_ui.error
end
end
diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb
index 454d6ea1c6..1261ebdcd7 100644
--- a/test/rubygems/test_gem_commands_specification_command.rb
+++ b/test/rubygems/test_gem_commands_specification_command.rb
@@ -21,8 +21,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/Gem::Specification/, @ui.output)
- assert_match(/name: foo/, @ui.output)
+ assert_match %r{Gem::Specification}, @ui.output
+ assert_match %r{name: foo}, @ui.output
assert_equal "", @ui.error
end
@@ -37,10 +37,10 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- 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_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_equal "", @ui.error
end
@@ -99,8 +99,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/Gem::Specification/, @ui.output)
- assert_match(/name: foo/, @ui.output)
+ assert_match %r{Gem::Specification}, @ui.output
+ assert_match %r{name: foo}, @ui.output
assert_equal "", @ui.error
end
@@ -131,8 +131,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/Gem::Specification/, @ui.output)
- assert_match(/name: foo/, @ui.output)
+ assert_match %r{Gem::Specification}, @ui.output
+ assert_match %r{name: foo}, @ui.output
assert_equal "", @ui.error
end
@@ -165,7 +165,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output
- assert_match(/name: foo/, @ui.output)
+ assert_match %r{name: foo}, @ui.output
end
def test_execute_remote_with_version
@@ -229,7 +229,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output
- assert_match(/name: foo/, @ui.output)
+ assert_match %r{name: foo}, @ui.output
spec = load_yaml @ui.output
@@ -251,7 +251,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output
- assert_match(/name: foo/, @ui.output)
+ assert_match %r{name: foo}, @ui.output
spec = load_yaml @ui.output
@@ -270,8 +270,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match(/Gem::Specification.new/, @ui.output)
- assert_match(/s.name = "foo"/, @ui.output)
+ assert_match %r{Gem::Specification.new}, @ui.output
+ assert_match %r{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 ea7493b418..8b260853e6 100644
--- a/test/rubygems/test_gem_commands_stale_command.rb
+++ b/test/rubygems/test_gem_commands_stale_command.rb
@@ -25,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 - 86_400)
+ FileUtils.touch(filename, :mtime => Time.now - 86400)
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 4daa61cb0c..b7fc56a51a 100644
--- a/test/rubygems/test_gem_commands_uninstall_command.rb
+++ b/test/rubygems/test_gem_commands_uninstall_command.rb
@@ -21,7 +21,7 @@ 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
assert_gems_presence "a-1", "a-4", "b-2", "default-1", dirs: [@gemhome, gemhome2]
@@ -114,7 +114,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
def test_execute_removes_executable
initial_install
- if Gem.win_platform?
+ if win_platform?
assert File.exist?(@executable)
else
assert File.symlink?(@executable)
@@ -158,7 +158,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
@cmd.execute
assert_equal false, File.exist?(formatted_executable)
- rescue StandardError
+ rescue
Gem::Installer.exec_format = nil
end
@@ -229,26 +229,6 @@ 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"
@@ -381,7 +361,7 @@ 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
assert_gems_presence "a-4", dirs: [@gemhome, gemhome2]
@@ -400,7 +380,7 @@ 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
assert_gems_presence "a-4", dirs: [@gemhome, gemhome2]
@@ -516,7 +496,7 @@ WARNING: Use your OS package manager to uninstall vendor gems
end
assert_empty @ui.output
- assert_match(/Error: unable to successfully uninstall '#{@spec.name}'/, @ui.error)
+ assert_match %r{Error: unable to successfully uninstall '#{@spec.name}'}, @ui.error
end
private
diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb
index 61cf8a611a..18e1bd86bd 100644
--- a/test/rubygems/test_gem_commands_unpack_command.rb
+++ b/test/rubygems/test_gem_commands_unpack_command.rb
@@ -16,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"
)
@@ -152,11 +152,11 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
end
def test_execute_sudo
- pend "Cannot perform this test on windows (chmod)" if Gem.win_platform?
+ pend "Cannot perform this test on windows (chmod)" if win_platform?
util_make_gems
- FileUtils.chmod 0o555, @gemhome
+ FileUtils.chmod 0555, @gemhome
@cmd.options[:args] = %w[b]
@@ -168,7 +168,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, "b-2")), "b should be unpacked"
ensure
- FileUtils.chmod 0o755, @gemhome
+ FileUtils.chmod 0755, @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 2683840f2e..02dd57f660 100644
--- a/test/rubygems/test_gem_commands_update_command.rb
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -79,6 +79,7 @@ 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,6 +123,7 @@ 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"
@@ -130,34 +132,6 @@ 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|
@@ -177,6 +151,7 @@ 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
@@ -210,6 +185,7 @@ 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
@@ -229,7 +205,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]
@@ -266,6 +242,7 @@ 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
@@ -376,6 +353,7 @@ 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
@@ -692,10 +670,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
@@ -711,10 +689,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 cbd5b5ef14..30f97811c8 100644
--- a/test/rubygems/test_gem_commands_which_command.rb
+++ b/test/rubygems/test_gem_commands_which_command.rb
@@ -33,8 +33,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "", @ui.output
- assert_match(/Can.t find Ruby library file or shared library directory\n/,
- @ui.error)
+ assert_match %r{Can.t find Ruby library file or shared library directory\n},
+ @ui.error
end
def test_execute_one_missing
@@ -51,8 +51,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
- assert_match(/Can.t find Ruby library file or shared library missinglib\n/,
- @ui.error)
+ assert_match %r{Can.t find Ruby library file or shared library missinglib\n},
+ @ui.error
end
def test_execute_missing
@@ -65,8 +65,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "", @ui.output
- assert_match(/Can.t find Ruby library file or shared library missinglib\n/,
- @ui.error)
+ assert_match %r{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 eb78e3a542..1fd4706381 100644
--- a/test/rubygems/test_gem_commands_yank_command.rb
+++ b/test/rubygems/test_gem_commands_yank_command.rb
@@ -57,7 +57,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
end
assert_match %r{Yanking gem from http://example}, @ui.output
- assert_match(/Successfully yanked/, @ui.output)
+ assert_match %r{Successfully yanked}, @ui.output
platform = Gem.platforms[1]
body = @fetcher.last_request.body.split("&").sort
@@ -88,7 +88,7 @@ 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(/Successfully yanked/, @otp_ui.output)
+ assert_match %r{Successfully yanked}, @otp_ui.output
assert_equal "111111", @fetcher.last_request["OTP"]
end
@@ -259,7 +259,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
end
assert_match %r{Yanking gem from https://other.example}, @ui.output
- assert_match(/Successfully yanked/, @ui.output)
+ assert_match %r{Successfully yanked}, @ui.output
body = @fetcher.last_request.body.split("&").sort
assert_equal %w[gem_name=a version=1.0], body
@@ -291,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 "Username/email:", @ui.output
+ assert_match "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 c56fa1a3cc..959f5b2433 100644
--- a/test/rubygems/test_gem_config_file.rb
+++ b/test/rubygems/test_gem_config_file.rb
@@ -185,22 +185,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", 0o600 do |fp|
+ File.open temp_cred, "w", 0600 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 Gem.win_platform?
+ pend "chmod not supported" if win_platform?
@cfg.rubygems_api_key = "x"
- File.chmod 0o644, @cfg.credentials_path
+ File.chmod 0644, @cfg.credentials_path
use_ui @ui do
assert_raise Gem::MockGemUi::TermError do
@@ -323,28 +323,23 @@ 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", 0o600 do |fp|
- fp.puts ":rubygems_api_key: rubygems_b9ce70c306b3a2e248679fbbbd66722d408d3c8c4f00566c"
- fp.puts ":other: rubygems_9636a120106ea8b81fbc792188251738665711d2ece160c5"
- fp.puts "http://localhost:3000: rubygems_be293ad9dd71550a012b17d848893b41960b811ce9312b47"
+ File.open temp_cred, "w", 0600 do |fp|
+ fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
+ fp.puts ":other: a5fdbb6ba150cbb83aad2bb2fede64c"
end
util_config_file
- assert_equal(
- { :rubygems => "rubygems_b9ce70c306b3a2e248679fbbbd66722d408d3c8c4f00566c",
- :other => "rubygems_9636a120106ea8b81fbc792188251738665711d2ece160c5",
- "http://localhost:3000" => "rubygems_be293ad9dd71550a012b17d848893b41960b811ce9312b47" },
- @cfg.api_keys
- )
+ assert_equal({ :rubygems => "701229f217cdf23b1344c7b4b54ca97",
+ :other => "a5fdbb6ba150cbb83aad2bb2fede64c" }, @cfg.api_keys)
end
def test_load_api_keys_bad_permission
- pend "chmod not supported" if Gem.win_platform?
+ pend "chmod not supported" if win_platform?
@cfg.rubygems_api_key = "x"
- File.chmod 0o644, @cfg.credentials_path
+ File.chmod 0644, @cfg.credentials_path
assert_raise Gem::MockGemUi::TermError do
@cfg.load_api_keys
@@ -369,38 +364,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 Gem.win_platform?
+ unless win_platform?
stat = File.stat @cfg.credentials_path
- assert_equal 0o600, stat.mode & 0o600
+ assert_equal 0600, stat.mode & 0600
end
end
def test_rubygems_api_key_equals_bad_permission
- pend "chmod not supported" if Gem.win_platform?
+ pend "chmod not supported" if win_platform?
@cfg.rubygems_api_key = "x"
- File.chmod 0o644, @cfg.credentials_path
+ File.chmod 0644, @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 0o644, stat.mode & 0o644
+ assert_equal 0644, stat.mode & 0644
end
def test_write
@@ -476,8 +471,7 @@ if you believe they were disclosed to a third party.
end
begin
- verbose = $VERBOSE
- $VERBOSE = nil
+ verbose, $VERBOSE = $VERBOSE, nil
util_config_file
ensure
@@ -485,16 +479,6 @@ 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"
@@ -530,42 +514,4 @@ 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
end
diff --git a/test/rubygems/test_gem_console_ui.rb b/test/rubygems/test_gem_console_ui.rb
deleted file mode 100644
index b8a619625f..0000000000
--- a/test/rubygems/test_gem_console_ui.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# 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 2a989a5551..2a7a55f0d8 100644
--- a/test/rubygems/test_gem_dependency.rb
+++ b/test/rubygems/test_gem_dependency.rb
@@ -106,13 +106,8 @@ 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
@@ -394,16 +389,6 @@ 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 8999723ba1..819fc5b60b 100644
--- a/test/rubygems/test_gem_dependency_installer.rb
+++ b/test/rubygems/test_gem_dependency_installer.rb
@@ -75,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)
@@ -97,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)
@@ -132,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)
@@ -153,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(&:full_name),
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name },
"sanity check"
Dir.chdir @tempdir do
@@ -165,7 +165,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "e"
end
- assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name)
+ assert_equal %w[a-1 e-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_cache_dir
@@ -178,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(&:full_name)
+ assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
assert File.exist? File.join(@gemhome, "cache", @a1.file_name)
assert File.exist? File.join(@gemhome, "cache", @b1.file_name)
@@ -198,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
@@ -207,7 +207,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "a", req("= 2")
end
- assert_equal %w[a-2], inst.installed_gems.map(&:full_name),
+ assert_equal %w[a-2], inst.installed_gems.map {|s| s.full_name },
"sanity check"
FileUtils.rm File.join(@tempdir, a2.file_name)
@@ -218,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(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
# This asserts that if a gem's dependency is satisfied by an
@@ -237,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
@@ -255,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(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_dependency
@@ -274,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(&:full_name)
+ assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
assert done_installing_ran, "post installs hook was not run"
end
@@ -294,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(&:full_name)
+ assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_dependency_development_deep
@@ -314,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(&:full_name)
+ assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_dependency_development_shallow
@@ -334,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(&:full_name)
+ assert_equal %w[c-1 d-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_dependency_existing
@@ -354,7 +354,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_dependency_existing_extension
@@ -391,7 +391,7 @@ class TestGemDependencyInstaller < Gem::TestCase
Dir.chdir pwd
end
- assert_equal %w[f-1], inst.installed_gems.map(&:full_name)
+ assert_equal %w[f-1], inst.installed_gems.map {|s| s.full_name }
assert_path_exist e1.extension_dir
end
@@ -411,7 +411,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "f"
end
- assert_equal %w[f-2], inst.installed_gems.map(&:full_name)
+ assert_equal %w[f-2], inst.installed_gems.map {|s| s.full_name }
end
def test_install_local
@@ -421,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(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_local_prerelease
@@ -435,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(&:full_name)
+ assert_equal %w[a-1.a], inst.installed_gems.map {|s| s.full_name }
end
def test_install_local_dependency
@@ -451,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(&:full_name)
+ assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_local_dependency_installed
@@ -469,11 +469,11 @@ 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(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_local_dependency_no_network_for_target_gem
@@ -488,8 +488,8 @@ class TestGemDependencyInstaller < Gem::TestCase
@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")
+ compact_index_response = Net::HTTPResponse.new "1.1", 200, "OK"
+ compact_index_response.uri = URI("http://gems.example.com")
@fetcher.data["http://gems.example.com/"] = compact_index_response
# but private local gem not present there
@@ -516,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(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_minimal_deps
@@ -542,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(&:full_name),
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.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(&:full_name)
+ assert_equal %w[a-1 e-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_no_minimal_deps
@@ -576,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(&:full_name),
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.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(&:full_name)
+ assert_equal %w[a-1 b-2 e-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_no_document
@@ -596,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
@@ -615,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(/\A#!#{env} #{RbConfig::CONFIG["ruby_install_name"]}\n/,
- File.read(File.join(@gemhome, "bin", "a_bin")))
+ assert_match %r{\A#!#{env} #{RbConfig::CONFIG['ruby_install_name']}\n},
+ File.read(File.join(@gemhome, "bin", "a_bin"))
end
def test_install_force
@@ -634,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(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_build_args
@@ -649,7 +649,8 @@ 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
@@ -663,11 +664,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(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_install_dir
@@ -684,11 +685,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(&:full_name)
+ assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
assert File.exist?(File.join(gemhome2, "specifications", @a1.spec_name))
assert File.exist?(File.join(gemhome2, "cache", @a1.file_name))
@@ -708,11 +709,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(&:full_name)
+ assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
a1, b1 = inst.installed_gems
assert_equal a1.spec_file, a1.loaded_from
@@ -732,11 +733,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(&:full_name)
+ assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_domain_local
@@ -747,7 +748,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
@@ -755,7 +756,7 @@ class TestGemDependencyInstaller < Gem::TestCase
assert_equal expected, e.message
end
- assert_equal [], inst.installed_gems.map(&:full_name)
+ assert_equal [], inst.installed_gems.map {|s| s.full_name }
end
def test_install_domain_remote
@@ -768,10 +769,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(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_dual_repository
@@ -784,11 +785,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(&:full_name),
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name },
"sanity check"
ENV["GEM_HOME"] = @gemhome
@@ -800,7 +801,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_reinstall
@@ -811,7 +812,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
@@ -835,7 +836,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "a"
end
- assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_remote_dep
@@ -855,7 +856,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install dep
end
- assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_remote_platform_newer
@@ -885,10 +886,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(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_platform_is_ignored_when_a_file_is_specified
@@ -896,10 +897,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(&:full_name)
+ assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map {|s| s.full_name }
end
require "rubygems/openssl"
@@ -908,14 +909,14 @@ class TestGemDependencyInstaller < Gem::TestCase
def test_install_security_policy
util_setup_gems
- data = File.open(@a1_gem, "rb", &:read)
+ data = File.open(@a1_gem, "rb") {|f| f.read }
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = data
- data = File.open(@b1_gem, "rb", &:read)
+ data = File.open(@b1_gem, "rb") {|f| f.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"
@@ -924,21 +925,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(&:full_name)
+ assert_equal %w[], inst.installed_gems.map {|s| s.full_name }
end
end
# Wrappers don't work on mswin
- unless Gem.win_platform?
+ unless 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(/This file was generated by RubyGems./,
+ refute_match(%r{This file was generated by RubyGems.},
File.read(File.join(@gemhome, "bin", "a_bin")))
end
end
@@ -946,32 +947,32 @@ class TestGemDependencyInstaller < Gem::TestCase
def test_install_version
util_setup_d
- data = File.open(@d2_gem, "rb", &:read)
+ data = File.open(@d2_gem, "rb") {|f| f.read }
@fetcher.data["http://gems.example.com/gems/d-2.gem"] = data
- data = File.open(@d1_gem, "rb", &:read)
+ data = File.open(@d1_gem, "rb") {|f| f.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(&:full_name)
+ assert_equal %w[d-1], inst.installed_gems.map {|s| s.full_name }
end
def test_install_version_default
util_setup_d
- data = File.open(@d2_gem, "rb", &:read)
+ data = File.open(@d2_gem, "rb") {|f| f.read }
@fetcher.data["http://gems.example.com/gems/d-2.gem"] = data
- data = File.open(@d1_gem, "rb", &:read)
+ data = File.open(@d1_gem, "rb") {|f| f.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(&:full_name)
+ assert_equal %w[d-2], inst.installed_gems.map {|s| s.full_name }
end
def test_install_legacy_spec_with_nil_required_ruby_version
@@ -1144,7 +1145,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = Gem::DependencyInstaller.new
request_set = inst.resolve_dependencies "b", req(">= 0")
- requests = request_set.sorted_requests.map(&:full_name)
+ requests = request_set.sorted_requests.map {|req| req.full_name }
assert_equal %w[a-1 b-1], requests
end
@@ -1155,10 +1156,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(&:full_name)
+ requests = request_set.sorted_requests.map {|req| req.full_name }
assert request_set.ignore_dependencies
@@ -1175,7 +1176,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(&:full_name)
+ requests = request_set.sorted_requests.map {|req| req.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 590e042315..21c71a4ac1 100644
--- a/test/rubygems/test_gem_dependency_list.rb
+++ b/test/rubygems/test_gem_dependency_list.rb
@@ -53,7 +53,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[d-1 c-1 b-1 a-1], order.map(&:full_name)
+ assert_equal %w[d-1 c-1 b-1 a-1], order.map {|s| s.full_name }
end
def test_dependency_order_circle
@@ -62,7 +62,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[b-1 c-1 a-1], order.map(&:full_name)
+ assert_equal %w[b-1 c-1 a-1], order.map {|s| s.full_name }
end
def test_dependency_order_development
@@ -80,7 +80,7 @@ class TestGemDependencyList < Gem::TestCase
order = deplist.dependency_order
- assert_equal %w[g-1 a-1 f-1 e-1], order.map(&:full_name),
+ assert_equal %w[g-1 a-1 f-1 e-1], order.map {|s| s.full_name },
"development on"
deplist2 = Gem::DependencyList.new
@@ -88,7 +88,7 @@ class TestGemDependencyList < Gem::TestCase
order = deplist2.dependency_order
- assert_equal %w[a-1 g-1 f-1 e-1], order.map(&:full_name),
+ assert_equal %w[a-1 g-1 f-1 e-1], order.map {|s| s.full_name },
"development off"
end
@@ -100,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(&:full_name),
+ assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map {|s| s.full_name },
"deps of trimmed specs not included"
end
@@ -109,7 +109,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[c-2 a-1], order.map(&:full_name)
+ assert_equal %w[c-2 a-1], order.map {|s| s.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 98a6b6b8fd..bf99969226 100644
--- a/test/rubygems/test_gem_dependency_resolution_error.rb
+++ b/test/rubygems/test_gem_dependency_resolution_error.rb
@@ -6,20 +6,22 @@ class TestGemDependencyResolutionError < Gem::TestCase
def setup
super
+ @DR = Gem::Resolver
+
@spec = util_spec "a", 2
- @a1_req = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil
- @a2_req = Gem::Resolver::DependencyRequest.new dep("a", "= 2"), nil
+ @a1_req = @DR::DependencyRequest.new dep("a", "= 1"), nil
+ @a2_req = @DR::DependencyRequest.new dep("a", "= 2"), nil
- @activated = Gem::Resolver::ActivationRequest.new @spec, @a2_req
+ @activated = @DR::ActivationRequest.new @spec, @a2_req
- @conflict = Gem::Resolver::Conflict.new @a1_req, @activated
+ @conflict = @DR::Conflict.new @a1_req, @activated
@error = Gem::DependencyResolutionError.new @conflict
end
def test_message
- assert_match(/^conflicting dependencies a \(= 1\) and a \(= 2\)$/,
- @error.message)
+ assert_match %r{^conflicting dependencies a \(= 1\) and a \(= 2\)$},
+ @error.message
end
end
diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb
index baf6140468..2ea05abf38 100644
--- a/test/rubygems/test_gem_ext_builder.rb
+++ b/test/rubygems/test_gem_ext_builder.rb
@@ -6,7 +6,7 @@ require "rubygems/installer"
class TestGemExtBuilder < Gem::TestCase
def setup
- @orig_destdir = ENV["DESTDIR"]
+ @orig_DESTDIR = ENV["DESTDIR"]
@orig_make = ENV["make"]
super
@@ -23,7 +23,7 @@ class TestGemExtBuilder < Gem::TestCase
def teardown
super
- ENV["DESTDIR"] = @orig_destdir
+ ENV["DESTDIR"] = @orig_DESTDIR
ENV["make"] = @orig_make
end
@@ -48,14 +48,14 @@ install:
results = results.join("\n").b
- assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} clean$/, results)
- assert_match(/DESTDIR\\=#{ENV["DESTDIR"]}$/, results)
- assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} install$/, results)
+ assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} clean$}, results
+ assert_match %r{DESTDIR\\=#{ENV['DESTDIR']}$}, results
+ assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} install$}, results
- unless results.include?("nmake")
- assert_match(/^clean: destination$/, results)
- assert_match(/^all: destination$/, results)
- assert_match(/^install: destination$/, results)
+ if /nmake/ !~ results
+ assert_match %r{^clean: destination$}, results
+ assert_match %r{^all: destination$}, results
+ assert_match %r{^install: destination$}, results
end
end
@@ -77,14 +77,12 @@ install:
results = results.join("\n").b
- assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} clean$/, results)
- assert_match(/DESTDIR\\=#{ENV["DESTDIR"]}$/, results)
- assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} install$/, results)
+ assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} clean$}, results
+ assert_match %r{DESTDIR\\=#{ENV['DESTDIR']}$}, results
+ assert_match %r{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|
@@ -101,48 +99,45 @@ install:
end
Gem::Ext::Builder.make @dest_path, results, @ext
results = results.join("\n").b
- assert_match(/clean: OK/, results)
- assert_match(/all: OK/, results)
- assert_match(/install: OK/, results)
+ assert_match %r{clean: OK}, results
+ assert_match %r{all: OK}, results
+ assert_match %r{install: OK}, results
end
def test_build_extensions
pend "terminates on mswin" if vc_windows? && ruby_repo?
+ @spec.extensions << "ext/extconf.rb"
- extension_in_lib do
- @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'
-
- 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
def test_build_extensions_with_gemhome_with_space
@@ -158,41 +153,54 @@ install:
end
def test_build_extensions_install_ext_only
+ class << Gem
+ alias orig_install_extension_in_lib install_extension_in_lib
+
+ remove_method :install_extension_in_lib
+
+ def Gem.install_extension_in_lib
+ false
+ end
+ end
pend "terminates on mswin" if vc_windows? && ruby_repo?
- extension_in_lib(false) do
- @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
+ 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
- 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"
+ alias install_extension_in_lib orig_install_extension_in_lib
end
end
@@ -243,7 +251,7 @@ install:
cmd_make_out = File.read(gem_make_out)
assert_match %r{#{Regexp.escape Gem.ruby} .* extconf\.rb}, cmd_make_out
- assert_match(/: No such file/, cmd_make_out)
+ assert_match %r{: 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 5faf3e2480..bde99e2743 100644
--- a/test/rubygems/test_gem_ext_cargo_builder.rb
+++ b/test/rubygems/test_gem_ext_cargo_builder.rb
@@ -36,12 +36,12 @@ class TestGemExtCargoBuilder < Gem::TestCase
end
output = output.join "\n"
- bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG["DLEXT"]}")
+ bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}")
assert_match(/Finished/, output)
assert_match(/release/, output)
assert_ffi_handle bundle, "Init_rust_ruby_example"
- rescue StandardError => e
+ rescue Exception => e
pp output if output
raise(e)
@@ -62,12 +62,12 @@ class TestGemExtCargoBuilder < Gem::TestCase
end
output = output.join "\n"
- bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG["DLEXT"]}")
+ bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}")
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
+ rescue Exception => e
pp output if output
raise(e)
@@ -140,7 +140,7 @@ class TestGemExtCargoBuilder < Gem::TestCase
private
def skip_unsupported_platforms!
- pend "jruby not supported" if Gem.java_platform?
+ pend "jruby not supported" if java_platform?
pend "truffleruby not supported (yet)" if RUBY_ENGINE == "truffleruby"
system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out])
pend "cargo not present" unless $?.success?
@@ -152,16 +152,12 @@ class TestGemExtCargoBuilder < Gem::TestCase
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)
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
index abd1e0ae33..e597d1981e 100644
--- 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
@@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.69.1"
+version = "0.60.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2"
+checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6"
dependencies = [
"bitflags",
"cexpr",
@@ -28,14 +28,13 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
- "syn",
]
[[package]]
name = "bitflags"
-version = "2.3.3"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cexpr"
@@ -134,44 +133,40 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "proc-macro2"
-version = "1.0.66"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.32"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rb-sys"
-version = "0.9.97"
+version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5"
+checksum = "b3277448b8eee18de8bedb18883ae02dcd60d47922ddfc6ab408def77da0a9b4"
dependencies = [
"rb-sys-build",
]
[[package]]
name = "rb-sys-build"
-version = "0.9.97"
+version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a"
+checksum = "c9baae802c93180af02cccb21819589d109070f8e28e14e7070a9ffdeca9b464"
dependencies = [
"bindgen",
- "lazy_static",
- "proc-macro2",
- "quote",
"regex",
"shell-words",
- "syn",
]
[[package]]
@@ -205,20 +200,9 @@ 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"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
+checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "unicode-ident"
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
index ad3e7f9b76..53f0879012 100644
--- 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
@@ -7,4 +7,4 @@ edition = "2021"
crate-type = ["cdylib"]
[dependencies]
-rb-sys = "0.9.97"
+rb-sys = "0.9.54"
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 1d174f569e..4e2719fcba 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
@@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.69.1"
+version = "0.60.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2"
+checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6"
dependencies = [
"bitflags",
"cexpr",
@@ -28,14 +28,13 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
- "syn",
]
[[package]]
name = "bitflags"
-version = "2.3.3"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cexpr"
@@ -127,40 +126,39 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "proc-macro2"
-version = "1.0.66"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.32"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
+checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rb-sys"
-version = "0.9.97"
+version = "0.9.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5"
+checksum = "e8fe617bad8e88fd7e5d6f432e35f09e5f94144dfb8e8ee4adde82fb920dc59b"
dependencies = [
"rb-sys-build",
]
[[package]]
name = "rb-sys-build"
-version = "0.9.97"
+version = "0.9.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a"
+checksum = "007e63597f91c711cbb299e60fecbdb6f5ad4a066d6a20c81943893f1584c895"
dependencies = [
"bindgen",
"lazy_static",
- "proc-macro2",
"quote",
"regex",
"shell-words",
@@ -205,15 +203,15 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "shlex"
-version = "1.3.0"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "syn"
-version = "2.0.28"
+version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
+checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
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 60cf49ce03..91627ada0f 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 = "0.9.97"
+rb-sys = "0.9.65"
diff --git a/test/rubygems/test_gem_ext_cargo_builder_unit.rb b/test/rubygems/test_gem_ext_cargo_builder_unit.rb
index 89495b84ff..0ca8306842 100644
--- a/test/rubygems/test_gem_ext_cargo_builder_unit.rb
+++ b/test/rubygems/test_gem_ext_cargo_builder_unit.rb
@@ -55,6 +55,6 @@ class TestGemExtCargoBuilderUnit < Gem::TestCase
end
def skip_unsupported_platforms!
- pend "jruby not supported" if Gem.java_platform?
+ pend "jruby not supported" if 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 5f886af05f..03b5da4e63 100644
--- a/test/rubygems/test_gem_ext_cmake_builder.rb
+++ b/test/rubygems/test_gem_ext_cmake_builder.rb
@@ -29,7 +29,7 @@ class TestGemExtCmakeBuilder < Gem::TestCase
def test_self_build
File.open File.join(@ext, "CMakeLists.txt"), "w" do |cmakelists|
cmakelists.write <<-EO_CMAKE
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 3.5)
project(self_build NONE)
install (FILES test.txt DESTINATION bin)
EO_CMAKE
@@ -43,11 +43,11 @@ install (FILES test.txt DESTINATION bin)
output = output.join "\n"
- assert_match(/^cmake \. -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}/, output)
- assert_match(/#{Regexp.escape @ext}/, output)
+ assert_match %r{^cmake \. -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}}, output
+ assert_match %r{#{Regexp.escape @ext}}, output
assert_contains_make_command "", output
assert_contains_make_command "install", output
- assert_match(/test\.txt/, output)
+ assert_match %r{test\.txt}, output
end
def test_self_build_fail
@@ -59,12 +59,12 @@ install (FILES test.txt DESTINATION bin)
output = output.join "\n"
- shell_error_msg = /(CMake Error: .*)/
+ shell_error_msg = %r{(CMake Error: .*)}
assert_match "cmake failed", error.message
- assert_match(/^cmake . -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}/, output)
- assert_match(/#{shell_error_msg}/, output)
+ assert_match %r{^cmake . -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}}, output
+ assert_match %r{#{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 6a2f9883f0..737aea6a34 100644
--- a/test/rubygems/test_gem_ext_configure_builder.rb
+++ b/test/rubygems/test_gem_ext_configure_builder.rb
@@ -57,7 +57,7 @@ class TestGemExtConfigureBuilder < Gem::TestCase
assert_match(/^current directory:/, output.shift)
assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift
- assert_match(/#{shell_error_msg}/, output.shift)
+ assert_match %r{#{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 218c6f3d5e..e6b980a96b 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 Gem.java_platform?
+ if 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(/^#{Regexp.quote(Gem.ruby)}.* extconf.rb/, output[1])
+ assert_match(/^#{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 Gem.java_platform?
+ if 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_large_make = ENV.delete "MAKE"
+ env_MAKE = ENV.delete "MAKE"
ENV["MAKE"] = "anothermake"
- if Gem.java_platform?
+ if 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_large_make
+ ENV["MAKE"] = env_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(/^#{Regexp.quote(Gem.ruby)}.* extconf.rb/, output[1])
+ assert_match(/^#{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,6 +218,7 @@ 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 bd72c1aa08..e6ca842a2e 100644
--- a/test/rubygems/test_gem_ext_rake_builder.rb
+++ b/test/rubygems/test_gem_ext_rake_builder.rb
@@ -23,9 +23,9 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
- 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)
+ 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
end
end
@@ -42,9 +42,9 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
- 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)
+ 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
end
end
@@ -72,7 +72,7 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
assert_match "OpenSSL", output
- assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output)
+ assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output
end
def test_class_build_no_mkrf_passes_args
@@ -83,8 +83,8 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
- refute_match(/^rake failed:/, output)
- assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path} test1 test2/, output)
+ 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
end
end
@@ -92,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(/^rake failed/, error.message)
+ assert_match %r{^rake failed}, error.message
end
end
diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb
index a3236e6276..cb767bbdae 100644
--- a/test/rubygems/test_gem_gemcutter_utilities.rb
+++ b/test/rubygems/test_gem_gemcutter_utilities.rb
@@ -5,7 +5,6 @@ require_relative "multifactor_auth_utilities"
require "rubygems"
require "rubygems/command"
require "rubygems/gemcutter_utilities"
-require "rubygems/config_file"
class TestGemGemcutterUtilities < Gem::TestCase
def setup
@@ -42,7 +41,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
ENV["RUBYGEMS_HOST"] = "http://rubygems.engineyard.com"
@@ -53,10 +52,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 Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -65,10 +64,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 Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
@@ -98,9 +97,9 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_sign_in
util_sign_in
- assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output)
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match(/Signed in./, @sign_in_ui.output)
+ assert_match %r{Signed in.}, @sign_in_ui.output
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
@@ -113,7 +112,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
assert_match "Enter your http://example.com credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match(/Signed in./, @sign_in_ui.output)
+ assert_match %r{Signed in.}, @sign_in_ui.output
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal @fetcher.api_key, credentials["http://example.com"]
@@ -126,7 +125,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
assert_match "Enter your RubyGems.org credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match(/Signed in./, @sign_in_ui.output)
+ assert_match %r{Signed in.}, @sign_in_ui.output
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
@@ -139,7 +138,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
assert_match "Enter your http://example.com credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match(/Signed in./, @sign_in_ui.output)
+ assert_match %r{Signed in.}, @sign_in_ui.output
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal @fetcher.api_key, credentials["http://example.com"]
@@ -164,15 +163,13 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys
other_api_key = "f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf"
- config = Hash[:other_api_key, other_api_key]
-
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(config)
+ f.write Hash[:other_api_key, other_api_key].to_yaml
end
util_sign_in
- assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output)
- assert_match(/Signed in./, @sign_in_ui.output)
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert_match %r{Signed in.}, @sign_in_ui.output
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
@@ -185,8 +182,8 @@ class TestGemGemcutterUtilities < Gem::TestCase
util_sign_in
end
- assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output)
- assert_match(/Access Denied./, @sign_in_ui.output)
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert_match %r{Access Denied.}, @sign_in_ui.output
end
def test_signin_with_env_otp_code
@@ -306,7 +303,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
ENV["RUBYGEMS_HOST"] = @fetcher.host
Gem::RemoteFetcher.fetcher = @fetcher
- @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n" + extra_input)
+ @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input)
use_ui @sign_in_ui do
if args.length > 0
@@ -318,9 +315,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 Gem::ConfigFile.dump_with_rubygems_yaml(keys)
+ f.write keys.to_yaml
end
Gem.configuration.load_api_keys
diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb
new file mode 100644
index 0000000000..a0746574bd
--- /dev/null
+++ b/test/rubygems/test_gem_indexer.rb
@@ -0,0 +1,381 @@
+# 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 teardown
+ FileUtils.rm_rf(@indexer.directory)
+ ensure
+ super
+ end
+
+ def with_indexer(dir, **opts)
+ indexer = Gem::Indexer.new(dir, **opts)
+ build_directory = indexer.directory
+ yield indexer
+ ensure
+ FileUtils.rm_rf(build_directory) if build_directory
+ end
+
+ def test_initialize
+ assert_equal @indexerdir, @indexer.dest_directory
+ Dir.mktmpdir("gem_generate_index") do |tmpdir|
+ assert_match %r{#{tmpdir.match(/.*-/)}}, @indexer.directory
+ end
+
+ with_indexer(@indexerdir) do |indexer|
+ assert_predicate indexer, :build_modern
+ end
+
+ with_indexer(@indexerdir, :build_modern => true) do |indexer|
+ assert_predicate indexer, :build_modern
+ end
+ 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
+
+ with_indexer @indexerdir do |indexer|
+ 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
+ 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 8fd5d9c543..1526eadcb6 100644
--- a/test/rubygems/test_gem_install_update_options.rb
+++ b/test/rubygems/test_gem_install_update_options.rb
@@ -130,9 +130,6 @@ 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
@@ -140,20 +137,26 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
util_build_gem @spec
@gem = @spec.cache_file
- @cmd.handle_options %w[--no-user-install]
+ 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]
- refute @cmd.options[:user_install]
+ refute @cmd.options[:user_install]
- FileUtils.chmod 0o755, @userhome
- FileUtils.chmod 0o000, @gemhome
+ FileUtils.chmod 0755, @userhome
+ FileUtils.chmod 0000, @gemhome
- Gem.use_paths @gemhome, @userhome
+ Gem.use_paths @gemhome, @userhome
- assert_raise(Gem::FilePermissionError) do
- Gem::Installer.at(@gem, @cmd.options).install
+ assert_raise(Gem::FilePermissionError) do
+ Gem::Installer.at(@gem, @cmd.options).install
+ end
end
ensure
- FileUtils.chmod 0o755, @gemhome
+ FileUtils.chmod 0755, @gemhome
end
def test_vendor
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index edcc2216bd..4d3f94d3e7 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -84,7 +84,7 @@ end
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end
def test_check_executable_overwrite_default_bin_dir
@@ -100,8 +100,8 @@ end
end
conflicted = File.join @gemhome, "bin", "executable"
- assert_match(/\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z/,
- e.message)
+ assert_match %r{\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z},
+ e.message
end
end
end
@@ -142,7 +142,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
ensure
Gem::Installer.exec_format = nil
end
@@ -177,7 +177,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end
def test_check_executable_overwrite_other_non_gem
@@ -192,7 +192,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end unless Gem.win_platform?
def test_check_that_user_bin_dir_is_in_path
@@ -204,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
@@ -213,9 +213,9 @@ gem 'other', version
assert_empty @ui.error
- return unless Gem.win_platform?
+ return unless 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
@@ -223,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 Gem.win_platform?
+ pend "Tilde is PATH is not supported under MS Windows" if 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"
@@ -241,7 +241,7 @@ gem 'other', version
assert_empty @ui.error
ensure
- ENV["PATH"] = orig_path unless Gem.win_platform?
+ ENV["PATH"] = orig_PATH unless win_platform?
end
def test_check_that_user_bin_dir_is_in_path_not_in_path
@@ -287,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
@@ -299,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
@@ -335,25 +335,22 @@ 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 Gem.win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless win_platform?
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end
def test_generate_bin_bindir_with_user_install_warning
- bin_dir = if Gem.win_platform?
- File.expand_path(ENV["WINDIR"]).upcase
- else
- "/usr/bin"
- end
+ bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase :
+ "/usr/bin"
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
@@ -365,6 +362,7 @@ gem 'other', version
end
assert_equal "", @ui.error
+
ensure
ENV["PATH"] = old_path
end
@@ -380,10 +378,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 Gem.win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless win_platform?
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end
def test_generate_bin_script_format
@@ -439,10 +437,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 Gem.win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless win_platform?
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end
def test_generate_bin_script_no_execs
@@ -464,19 +462,19 @@ gem 'other', version
Dir.mkdir util_inst_bindir
- if Gem.win_platform?
+ if 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 0o000, util_inst_bindir
+ FileUtils.chmod 0000, util_inst_bindir
assert_raise Gem::FilePermissionError do
installer.generate_bin
end
end
ensure
- FileUtils.chmod 0o755, util_inst_bindir unless $DEBUG || Gem.win_platform?
+ FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG || win_platform?)
end
def test_generate_bin_script_no_shebang
@@ -496,12 +494,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 Gem.win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless win_platform?
wrapper = File.read installed_exec
- 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
+ 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
end
def test_generate_bin_script_wrappers
@@ -523,12 +521,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 Gem.win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless win_platform?
- assert_match(/generated by RubyGems/, File.read(installed_exec))
+ assert_match %r{generated by RubyGems}, File.read(installed_exec)
- refute_match(/generated by RubyGems/, File.read(real_exec),
- "real executable overwritten")
+ refute_match %r{generated by RubyGems}, File.read(real_exec),
+ "real executable overwritten"
end
def test_generate_bin_symlink
@@ -568,19 +566,19 @@ gem 'other', version
Dir.mkdir util_inst_bindir
- if Gem.win_platform?
+ if 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 0o000, util_inst_bindir
+ FileUtils.chmod 0000, util_inst_bindir
assert_raise Gem::FilePermissionError do
installer.generate_bin
end
end
ensure
- FileUtils.chmod 0o755, util_inst_bindir unless $DEBUG || Gem.win_platform?
+ FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG || win_platform?)
end
def test_generate_bin_symlink_update_newer
@@ -738,9 +736,9 @@ gem 'other', version
installer.generate_bin
default_shebang = Gem.ruby
- shebang_line = File.open("#{@gemhome}/bin/executable", &:gets)
+ shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
assert_match(/\A#!/, shebang_line)
- assert_include(shebang_line, default_shebang)
+ assert_match(/#{default_shebang}/, shebang_line)
end
end
@@ -749,8 +747,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
@@ -818,10 +816,10 @@ gem 'other', version
util_build_gem spec
- File.chmod(0o555, Gem.plugindir)
+ File.chmod(0555, Gem.plugindir)
system_path = File.join(Gem.plugindir, "a_plugin.rb")
user_path = File.join(Gem.plugindir(Gem.user_dir), "a_plugin.rb")
- installer = Gem::Installer.at spec.cache_file, user_install: true, force: true
+ installer = util_installer spec, Gem.dir, :user
assert_equal spec, installer.install
@@ -840,13 +838,13 @@ gem 'other', version
util_build_gem spec
- File.chmod(0o555, Gem.plugindir)
+ File.chmod(0555, 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
@@ -953,7 +951,7 @@ end
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
@@ -977,7 +975,7 @@ end
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
@@ -988,26 +986,13 @@ end
@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
@@ -1047,8 +1032,8 @@ end
exe = File.join gemdir, "bin", "executable"
assert_path_exist exe
- exe_mode = File.stat(exe).mode & 0o111
- assert_equal 0o111, exe_mode, format("0%o", exe_mode) unless Gem.win_platform?
+ exe_mode = File.stat(exe).mode & 0111
+ assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
assert_path_exist File.join gemdir, "lib", "code.rb"
@@ -1089,7 +1074,7 @@ end
@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
@@ -1250,7 +1235,7 @@ end
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
@@ -1268,7 +1253,7 @@ end
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
@@ -1280,29 +1265,9 @@ end
build_root = File.join(@tempdir, "build_root")
@gem = setup_base_gem
- 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
+ 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
@@ -1419,7 +1384,7 @@ end
installer.install
end
- assert_match(/I am a shiny gem!/, @ui.output)
+ assert_match %r{I am a shiny gem!}, @ui.output
end
def test_install_with_skipped_message
@@ -1429,11 +1394,11 @@ end
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(/I am a shiny gem!/, @ui.output)
+ refute_match %r{I am a shiny gem!}, @ui.output
end
def test_install_extension_dir
@@ -1453,7 +1418,7 @@ end
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
@@ -1492,7 +1457,7 @@ end
# 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
@@ -1518,7 +1483,7 @@ end
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
@@ -1652,7 +1617,7 @@ end
installer.install
end
assert_path_exist so
- rescue StandardError
+ rescue
puts "-" * 78
puts File.read File.join(@gemhome, "gems", "a-2", "Makefile")
puts "-" * 78
@@ -1770,7 +1735,7 @@ end
# 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
@@ -1784,7 +1749,6 @@ end
def spec.full_name # so the spec is buildable
"malicious-1"
end
-
def spec.validate(packaging, strict); end
util_build_gem spec
@@ -1805,7 +1769,6 @@ end
def spec.full_name # so the spec is buildable
"malicious-1"
end
-
def spec.validate(*args); end
util_build_gem spec
@@ -1827,7 +1790,6 @@ end
def spec.full_name # so the spec is buildable
"malicious-1"
end
-
def spec.validate(*args); end
spec.require_paths = ["malicious\n``"]
@@ -1851,7 +1813,6 @@ end
def spec.full_name # so the spec is buildable
"malicious-1"
end
-
def spec.validate(*args); end
spec.extensions = ["malicious\n``"]
@@ -1873,7 +1834,6 @@ end
def spec.full_name # so the spec is buildable
"malicious-1"
end
-
def spec.validate(*args); end
spec.specification_version = "malicious\n``"
@@ -1895,7 +1855,6 @@ end
def spec.full_name # so the spec is buildable
"malicious-1"
end
-
def spec.validate(*args); end
spec.add_dependency "b\nfoo", "> 5"
@@ -1918,9 +1877,9 @@ end
installer = Gem::Installer.at(
gem_with_ill_formated_platform,
- install_dir: @gemhome,
- user_install: false,
- force: true
+ :install_dir => @gemhome,
+ :user_install => false,
+ :force => true
)
use_ui @ui do
@@ -1960,7 +1919,7 @@ end
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
@@ -1975,48 +1934,6 @@ end
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
@@ -2104,7 +2021,7 @@ end
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
@@ -2241,7 +2158,7 @@ end
end
def get_bin_env
- if Gem.win_platform?
+ if win_platform?
""
else
%w[/usr/bin/env /bin/env].find {|f| File.executable?(f) }
@@ -2323,7 +2240,7 @@ end
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
@@ -2415,7 +2332,7 @@ end
ensure
File.class_eval do
remove_method :write
- alias_method :write, :original_write
+ alias_method :write, :original_write # rubocop:disable Lint/DuplicateMethods
remove_method :original_write
end
end
@@ -2428,7 +2345,7 @@ end
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
@@ -2465,10 +2382,10 @@ end
wrapper = File.read installed_exec
if symlink_supported?
- refute_match(/generated by RubyGems/, wrapper)
+ refute_match %r{generated by RubyGems}, wrapper
else # when symlink not supported, it warns and fallbacks back to installing wrapper
- assert_match(/Unable to use symlinks, installing wrapper/, @ui.error)
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{Unable to use symlinks, installing wrapper}, @ui.error
+ assert_match %r{generated by RubyGems}, wrapper
end
end
@@ -2489,7 +2406,7 @@ end
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match(/generated by RubyGems/, wrapper)
+ assert_match %r{generated by RubyGems}, wrapper
end
def test_default_gem_with_exe_as_bindir
@@ -2581,15 +2498,15 @@ end
end
def mask
- 0o100755
+ 0100755
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 cea9cde82b..b84e70e8b8 100644
--- a/test/rubygems/test_gem_local_remote_options.rb
+++ b/test/rubygems/test_gem_local_remote_options.rb
@@ -34,7 +34,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase
def test_clear_sources_option
@cmd.add_local_remote_options
- s = Gem::URI.parse "http://only-gems.example.com/"
+ s = URI.parse "http://only-gems.example.com/"
@cmd.handle_options %W[--clear-sources --source #{s}]
assert_equal [s.to_s], Gem.sources
@@ -76,10 +76,10 @@ class TestGemLocalRemoteOptions < Gem::TestCase
def test_source_option
@cmd.add_source_option
- 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
+ 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
original_sources = Gem.sources.dup
@@ -97,7 +97,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase
original_sources = Gem.sources.dup
- source = Gem::URI.parse "http://more-gems.example.com/"
+ source = 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 bdb8181ce8..75c0784d14 100644
--- a/test/rubygems/test_gem_name_tuple.rb
+++ b/test/rubygems/test_gem_name_tuple.rb
@@ -19,31 +19,14 @@ class TestGemNameTuple < Gem::TestCase
end
def test_platform_normalization
- 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
+ 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
end
def test_spec_name
diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb
index 2065864107..9d6215838d 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 Gem.win_platform?
+ if win_platform?
pend "symlink - must be admin with no UAC on Windows"
else
raise e
@@ -205,8 +205,7 @@ 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|
@@ -287,8 +286,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
@@ -330,8 +329,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
@@ -393,8 +392,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
@@ -430,8 +429,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
@@ -442,11 +441,11 @@ class TestGemPackage < Gem::Package::TarTestCase
data_tgz = util_tar_gz {}
gem = util_tar do |tar|
- tar.add_file "data.tar.gz", 0o644 do |io|
+ tar.add_file "data.tar.gz", 0644 do |io|
io.write data_tgz.string
end
- tar.add_file "metadata.gz", 0o644 do |io|
+ tar.add_file "metadata.gz", 0644 do |io|
Zlib::GzipWriter.wrap io do |gzio|
gzio.write @spec.to_yaml
end
@@ -479,21 +478,21 @@ class TestGemPackage < Gem::Package::TarTestCase
extracted = File.join @destination, "lib/code.rb"
assert_path_exist extracted
- mask = 0o100666 & (~File.umask)
+ mask = 0100666 & (~File.umask)
assert_equal mask.to_s(8), File.stat(extracted).mode.to_s(8) unless
- Gem.win_platform?
+ win_platform?
end
def test_extract_files_empty
data_tgz = util_tar_gz {}
gem = util_tar do |tar|
- tar.add_file "data.tar.gz", 0o644 do |io|
+ tar.add_file "data.tar.gz", 0644 do |io|
io.write data_tgz.string
end
- tar.add_file "metadata.gz", 0o644 do |io|
+ tar.add_file "metadata.gz", 0644 do |io|
Zlib::GzipWriter.wrap io do |gzio|
gzio.write @spec.to_yaml
end
@@ -512,7 +511,7 @@ class TestGemPackage < Gem::Package::TarTestCase
end
def test_extract_file_permissions
- pend "chmod not supported" if Gem.win_platform?
+ pend "chmod not supported" if win_platform?
gem_with_long_permissions = File.expand_path("packages/Bluebie-legs-0.6.2.gem", __dir__)
@@ -523,14 +522,14 @@ class TestGemPackage < Gem::Package::TarTestCase
filepath = File.join @destination, "README.rdoc"
assert_path_exist filepath
- assert_equal 0o104444, File.stat(filepath).mode
+ assert_equal 0104444, 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", 0o644 do |io|
+ tar.add_file "/absolute.rb", 0644 do |io|
io.write "hi"
end
end
@@ -539,7 +538,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
@@ -548,18 +547,18 @@ class TestGemPackage < Gem::Package::TarTestCase
package.verify
tgz_io = util_tar_gz do |tar|
- tar.add_file "relative.rb", 0o644 do |io|
+ tar.add_file "relative.rb", 0644 do |io|
io.write "hi"
end
- tar.mkdir "lib", 0o755
- tar.add_symlink "lib/foo.rb", "../relative.rb", 0o644
+ tar.mkdir "lib", 0755
+ tar.add_symlink "lib/foo.rb", "../relative.rb", 0644
end
begin
package.extract_tar_gz tgz_io, @destination
rescue Errno::EACCES => e
- if Gem.win_platform?
+ if win_platform?
pend "symlink - must be admin with no UAC on Windows"
else
raise e
@@ -574,39 +573,13 @@ 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", 0o755
- tar.add_symlink "lib/foo.rb", "../broken.rb", 0o644
+ tar.mkdir "lib", 0755
+ tar.add_symlink "lib/foo.rb", "../broken.rb", 0644
end
ui = Gem::MockGemUi.new
@@ -625,9 +598,9 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.mkdir "lib", 0o755
- tar.add_symlink "lib/link", "../..", 0o644
- tar.add_file "lib/link/outside.txt", 0o644 do |io|
+ tar.mkdir "lib", 0755
+ tar.add_symlink "lib/link", "../..", 0644
+ tar.add_file "lib/link/outside.txt", 0644 do |io|
io.write "hi"
end
end
@@ -638,7 +611,7 @@ class TestGemPackage < Gem::Package::TarTestCase
destination_subdir = File.join @destination, "subdir"
FileUtils.mkdir_p destination_subdir
- expected_exceptions = Gem.win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
+ expected_exceptions = win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
e = assert_raise(*expected_exceptions) do
package.extract_tar_gz tgz_io, destination_subdir
@@ -646,7 +619,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")
@@ -669,11 +642,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, 16_877
- tar.add_symlink "link/dir", ".", 16_877
+ tar.add_symlink "link", destination_user_dir, 16877
+ tar.add_symlink "link/dir", ".", 16877
end
- expected_exceptions = Gem.win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
+ expected_exceptions = win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
e = assert_raise(*expected_exceptions) do
package.extract_tar_gz tgz_io, destination_subdir
@@ -681,7 +654,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
@@ -693,11 +666,11 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.mkdir "lib", 0o755
- tar.add_file "lib/foo.rb", 0o644 do |io|
+ tar.mkdir "lib", 0755
+ tar.add_file "lib/foo.rb", 0644 do |io|
io.write "hi"
end
- tar.mkdir "lib/foo", 0o755
+ tar.mkdir "lib/foo", 0755
end
package.extract_tar_gz tgz_io, @destination
@@ -713,7 +686,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file "./dot_slash.rb", 0o644 do |io|
+ tar.add_file "./dot_slash.rb", 0644 do |io|
io.write "hi"
end
end
@@ -728,7 +701,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file ".dot_file.rb", 0o644 do |io|
+ tar.add_file ".dot_file.rb", 0644 do |io|
io.write "hi"
end
end
@@ -744,7 +717,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file "foo/file.rb", 0o644 do |io|
+ tar.add_file "foo/file.rb", 0644 do |io|
io.write "hi"
end
end
@@ -760,10 +733,12 @@ 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
@@ -773,7 +748,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
@@ -797,10 +772,12 @@ 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
@@ -812,7 +789,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
@@ -827,15 +804,13 @@ 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"
@@ -856,7 +831,7 @@ class TestGemPackage < Gem::Package::TarTestCase
def test_verify_checksum_bad
data_tgz = util_tar_gz do |tar|
- tar.add_file "lib/code.rb", 0o444 do |io|
+ tar.add_file "lib/code.rb", 0444 do |io|
io.write "# lib/code.rb"
end
end
@@ -866,11 +841,11 @@ class TestGemPackage < Gem::Package::TarTestCase
gem = util_tar do |tar|
metadata_gz = Gem::Util.gzip @spec.to_yaml
- tar.add_file "metadata.gz", 0o444 do |io|
+ tar.add_file "metadata.gz", 0444 do |io|
io.write metadata_gz
end
- tar.add_file "data.tar.gz", 0o444 do |io|
+ tar.add_file "data.tar.gz", 0444 do |io|
io.write data_tgz
end
@@ -880,7 +855,7 @@ class TestGemPackage < Gem::Package::TarTestCase
"metadata.gz" => "bogus",
},
}
- tar.add_file "checksums.yaml.gz", 0o444 do |io|
+ tar.add_file "checksums.yaml.gz", 0444 do |io|
Zlib::GzipWriter.wrap io do |gz_io|
gz_io.write Psych.dump bogus_checksums
end
@@ -903,7 +878,7 @@ class TestGemPackage < Gem::Package::TarTestCase
def test_verify_checksum_missing
data_tgz = util_tar_gz do |tar|
- tar.add_file "lib/code.rb", 0o444 do |io|
+ tar.add_file "lib/code.rb", 0444 do |io|
io.write "# lib/code.rb"
end
end
@@ -913,7 +888,7 @@ class TestGemPackage < Gem::Package::TarTestCase
gem = util_tar do |tar|
metadata_gz = Gem::Util.gzip @spec.to_yaml
- tar.add_file "metadata.gz", 0o444 do |io|
+ tar.add_file "metadata.gz", 0444 do |io|
io.write metadata_gz
end
@@ -926,13 +901,13 @@ class TestGemPackage < Gem::Package::TarTestCase
},
}
- tar.add_file "checksums.yaml.gz", 0o444 do |io|
+ tar.add_file "checksums.yaml.gz", 0444 do |io|
Zlib::GzipWriter.wrap io do |gz_io|
gz_io.write Psych.dump checksums
end
end
- tar.add_file "data.tar.gz", 0o444 do |io|
+ tar.add_file "data.tar.gz", 0444 do |io|
io.write data_tgz
end
end
@@ -951,7 +926,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", 0o644, data.length, Time.now)
+ tar_file_header("metadata.gz", "\000x", 0644, data.length, Time.now)
io.write data
io.rewind
@@ -968,95 +943,6 @@ 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"
@@ -1076,8 +962,8 @@ class TestGemPackage < Gem::Package::TarTestCase
package.verify
end
- assert_match(/^No such file or directory/, e.message)
- assert_match(/nonexistent.gem$/, e.message)
+ assert_match %r{^No such file or directory}, e.message
+ assert_match %r{nonexistent.gem$}, e.message
end
def test_verify_duplicate_file
@@ -1092,8 +978,8 @@ class TestGemPackage < Gem::Package::TarTestCase
build.add_metadata gem
build.add_contents gem
- gem.add_file_simple "a.sig", 0o444, 0
- gem.add_file_simple "a.sig", 0o444, 0
+ gem.add_file_simple "a.sig", 0444, 0
+ gem.add_file_simple "a.sig", 0444, 0
end
end
@@ -1164,23 +1050,12 @@ 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", 0o444, fake_signer.new do |io|
+ gem.add_file_signed "data2.tar.gz", 0444, fake_signer.new do |io|
io.write bogus_data
end
@@ -1222,9 +1097,7 @@ 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
@@ -1251,15 +1124,11 @@ 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)
@@ -1272,15 +1141,11 @@ 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)
diff --git a/test/rubygems/test_gem_package_old.rb b/test/rubygems/test_gem_package_old.rb
index 7582dbedd4..25e5cebb99 100644
--- a/test/rubygems/test_gem_package_old.rb
+++ b/test/rubygems/test_gem_package_old.rb
@@ -39,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 = 0o100644 & (~File.umask)
+ mask = 0100644 & (~File.umask)
- assert_equal mask, File.stat(extracted).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(extracted).mode unless win_platform?
end
def test_extract_files_security_policy
@@ -83,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 a3f95bb770..6439464c11 100644
--- a/test/rubygems/test_gem_package_tar_header.rb
+++ b/test/rubygems/test_gem_package_tar_header.rb
@@ -8,19 +8,19 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
super
header = {
- 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",
+ :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",
}
@tar_header = Gem::Package::TarHeader.new header
@@ -40,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 10_000, @tar_header.gid, "gid"
+ assert_equal 10000, @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 0o644, @tar_header.mode, "mode"
- assert_equal 12_345, @tar_header.mtime, "mtime"
+ assert_equal 0644, @tar_header.mode, "mode"
+ assert_equal 12345, @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"
@@ -59,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
@@ -92,38 +92,13 @@ 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
- def test_empty
- @tar_header = Gem::Package::TarHeader.from(StringIO.new(Gem::Package::TarHeader::EMPTY_HEADER))
-
- assert_empty @tar_header
- assert_equal Gem::Package::TarHeader.new(
- checksum: 0,
- devmajor: 0,
- devminor: 0,
- empty: true,
- gid: 0,
- gname: "",
- linkname: "",
- magic: "",
- mode: 0,
- mtime: 0,
- name: "",
- prefix: "",
- size: 0,
- typeflag: "0",
- uid: 0,
- uname: "",
- version: 0,
- ), @tar_header
- end
-
def test_equals2
assert_equal @tar_header, @tar_header
assert_equal @tar_header, @tar_header.dup
@@ -185,7 +160,6 @@ 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
@@ -221,13 +195,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 1_991_400_094, tar_header.uid
- assert_equal 1_991_400_094, tar_header.gid
+ assert_equal 1991400094, tar_header.uid
+ assert_equal 1991400094, tar_header.gid
assert_equal "GeoIP2-City_20190528/", tar_header.name
- assert_equal 0o755, tar_header.mode
+ assert_equal 0755, tar_header.mode
assert_equal 0, tar_header.size
- assert_equal 1_559_064_640, tar_header.mtime
+ assert_equal 1559064640, 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 b2f7cc2d5c..313950f4ea 100644
--- a/test/rubygems/test_gem_package_tar_reader.rb
+++ b/test/rubygems/test_gem_package_tar_reader.rb
@@ -25,26 +25,11 @@ 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", "", 0o10644, content.size, Time.now) +
+ tar_file_header("lib/foo", "", 010644, content.size, Time.now) +
content + "\0" * (512 - content.size)
str << "\0" * 1024
@@ -93,7 +78,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
@@ -105,7 +90,7 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase
def test_read_in_gem_data
gem_tar = util_gem_data_tar do |tar|
- tar.add_file "lib/code.rb", 0o444 do |io|
+ tar.add_file "lib/code.rb", 0444 do |io|
io.write "# lib/code.rb"
end
end
@@ -127,10 +112,10 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase
def test_seek_in_gem_data
gem_tar = util_gem_data_tar do |tar|
- tar.add_file "lib/code.rb", 0o444 do |io|
+ tar.add_file "lib/code.rb", 0444 do |io|
io.write "# lib/code.rb"
end
- tar.add_file "lib/foo.rb", 0o444 do |io|
+ tar.add_file "lib/foo.rb", 0444 do |io|
io.write "# lib/foo.rb"
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 67ab7922b5..051d3ebbd5 100644
--- a/test/rubygems/test_gem_package_tar_reader_entry.rb
+++ b/test/rubygems/test_gem_package_tar_reader_entry.rb
@@ -24,11 +24,11 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
def test_open
io = TempIO.new @tar
header = Gem::Package::TarHeader.from io
- retval = Gem::Package::TarReader::Entry.open header, io, &:getc
+ retval = Gem::Package::TarReader::Entry.open header, io do |entry|
+ entry.getc
+ end
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
@@ -40,8 +40,6 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
end
assert entry.closed?
assert_raise(IOError) { entry.getc }
- ensure
- io&.close!
end
def test_open_returns_entry
@@ -49,11 +47,9 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
header = Gem::Package::TarHeader.from io
entry = Gem::Package::TarReader::Entry.open header, io
refute entry.closed?
- assert_equal "a", entry.getc
+ assert_equal ?a, entry.getc
assert_nil entry.close
assert entry.closed?
- ensure
- io&.close!
end
def test_bytes_read
@@ -117,7 +113,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
@@ -181,15 +177,10 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal @contents[100..-1], @entry.read
end
- def test_readpartial
+ def test_read_partial
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)
@@ -198,42 +189,11 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
def test_readpartial_past_eof
@entry.readpartial(@contents.size)
- assert @entry.eof?
assert_raise(EOFError) do
@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
@@ -273,16 +233,12 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
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
@@ -339,20 +295,4 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
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 751ceaca81..d85de4418a 100644
--- a/test/rubygems/test_gem_package_tar_writer.rb
+++ b/test/rubygems/test_gem_package_tar_writer.rb
@@ -28,12 +28,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_add_file
- Time.stub :now, Time.at(1_458_518_157) do
- @tar_writer.add_file "x", 0o644 do |f|
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_file "x", 0644 do |f|
f.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -42,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(1_458_518_157) do
- @tar_writer.mkdir "foo", 0o644
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.mkdir "foo", 0644
- assert_headers_equal tar_dir_header("foo", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
+ assert_headers_equal tar_dir_header("foo", "", 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
@io.string[0, 512]
end
end
def test_add_symlink
- Time.stub :now, Time.at(1_458_518_157) do
- @tar_writer.add_symlink "x", "y", 0o644
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_symlink "x", "y", 0644
- assert_headers_equal(tar_symlink_header("x", "", 0o644, Time.now, "y"),
+ assert_headers_equal(tar_symlink_header("x", "", 0644, Time.now, "y"),
@io.string[0, 512])
end
assert_equal 512, @io.pos
@@ -62,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(1_458_518_157) do
- @tar_writer.add_symlink "x", "y", 0o644
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_symlink "x", "y", 0644
- assert_headers_equal(tar_symlink_header("x", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, "y"),
+ assert_headers_equal(tar_symlink_header("x", "", 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, "y"),
@io.string[0, 512])
end
end
def test_add_file_digest
- digest_algorithms = OpenSSL::Digest::SHA1.new, OpenSSL::Digest::SHA512.new
+ digest_algorithms = Digest::SHA1.new, Digest::SHA512.new
- Time.stub :now, Time.at(1_458_518_157) do
- digests = @tar_writer.add_file_digest "x", 0o644, digest_algorithms do |io|
+ Time.stub :now, Time.at(1458518157) do
+ digests = @tar_writer.add_file_digest "x", 0644, digest_algorithms do |io|
io.write "a" * 10
end
@@ -86,7 +86,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
"e1cf14b0",
digests["SHA512"].hexdigest
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -94,10 +94,10 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_add_file_digest_multiple
- digest_algorithms = [OpenSSL::Digest::SHA1.new, OpenSSL::Digest::SHA512.new]
+ digest_algorithms = [Digest::SHA1.new, Digest::SHA512.new]
- Time.stub :now, Time.at(1_458_518_157) do
- digests = @tar_writer.add_file_digest "x", 0o644, digest_algorithms do |io|
+ Time.stub :now, Time.at(1458518157) do
+ digests = @tar_writer.add_file_digest "x", 0644, digest_algorithms do |io|
io.write "a" * 10
end
@@ -109,7 +109,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
"e1cf14b0",
digests["SHA512"].hexdigest
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -121,12 +121,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT]
- Time.stub :now, Time.at(1_458_518_157) do
- @tar_writer.add_file_signed "x", 0o644, signer do |io|
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_file_signed "x", 0644, signer do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
@io.string[0, 512])
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -136,7 +136,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
signature = signer.sign digest.digest
- assert_headers_equal(tar_file_header("x.sig", "", 0o444, signature.length,
+ assert_headers_equal(tar_file_header("x.sig", "", 0444, signature.length,
Time.now),
@io.string[1024, 512])
assert_equal "#{signature}#{"\0" * (512 - signature.length)}",
@@ -149,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(1_458_518_157) do
- @tar_writer.add_file_signed "x", 0o644, signer do |io|
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_file_signed "x", 0644, signer do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -163,12 +163,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_add_file_simple
- Time.stub :now, Time.at(1_458_518_157) do
- @tar_writer.add_file_simple "x", 0o644, 10 do |io|
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_file_simple "x", 0644, 10 do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
@io.string[0, 512])
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -178,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(1_458_518_157) do
- @tar_writer.add_file_simple "x", 0o644, 10 do |io|
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.add_file_simple "x", 0644, 10 do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
+ assert_headers_equal(tar_file_header("x", "", 0644, 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(1_458_518_157) do
+ Time.stub :now, Time.at(1458518157) do
@tar_writer.add_file_simple "x", 0, 100
assert_headers_equal tar_file_header("x", "", 0, 100, Time.now),
@@ -247,10 +247,10 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_mkdir
- Time.stub :now, Time.at(1_458_518_157) do
- @tar_writer.mkdir "foo", 0o644
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.mkdir "foo", 0644
- assert_headers_equal tar_dir_header("foo", "", 0o644, Time.now),
+ assert_headers_equal tar_dir_header("foo", "", 0644, Time.now),
@io.string[0, 512]
assert_equal 512, @io.pos
@@ -259,20 +259,20 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
def test_mkdir_source_date_epoch
ENV["SOURCE_DATE_EPOCH"] = "123456789"
- Time.stub :now, Time.at(1_458_518_157) do
- @tar_writer.mkdir "foo", 0o644
+ Time.stub :now, Time.at(1458518157) do
+ @tar_writer.mkdir "foo", 0644
- assert_headers_equal tar_dir_header("foo", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
+ assert_headers_equal tar_dir_header("foo", "", 0644, 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)
@@ -283,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 6f322ad61e..f0aaa3f082 100644
--- a/test/rubygems/test_gem_package_task.rb
+++ b/test/rubygems/test_gem_package_task.rb
@@ -9,6 +9,10 @@ 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_platform.rb b/test/rubygems/test_gem_platform.rb
index 00e48498c6..3325d7e779 100644
--- a/test/rubygems/test_gem_platform.rb
+++ b/test/rubygems/test_gem_platform.rb
@@ -28,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
@@ -41,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
@@ -71,7 +71,7 @@ class TestGemPlatform < Gem::TestCase
Gem.platforms = platforms
class << Gem::Platform
remove_method :match_gem?
- alias_method :match_gem?, :original_match_gem?
+ alias_method :match_gem?, :original_match_gem? # rubocop:disable Lint/DuplicateMethods
remove_method :original_match_gem?
end
end
@@ -145,9 +145,6 @@ class TestGemPlatform < Gem::TestCase
"x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"],
"x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"],
"x86_64-openbsd" => ["x86_64", "openbsd", nil],
- "wasm32-wasi" => ["wasm32", "wasi", nil],
- "wasm32-wasip1" => ["wasm32", "wasi", nil],
- "wasm32-wasip2" => ["wasm32", "wasi", nil],
}
test_cases.each do |arch, expected|
@@ -178,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]
@@ -187,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
@@ -215,7 +212,7 @@ class TestGemPlatform < Gem::TestCase
end
def test_to_s
- if Gem.win_platform?
+ if win_platform?
assert_equal "x86-mswin32-60", Gem::Platform.local.to_s
else
assert_equal "x86-darwin-8", Gem::Platform.local.to_s
@@ -235,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) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert(my === my)
refute(other === my)
refute(my === other)
end
@@ -486,10 +483,8 @@ class TestGemPlatform < Gem::TestCase
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
+ 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
def assert_local_match(name)
diff --git a/test/rubygems/test_gem_rdoc.rb b/test/rubygems/test_gem_rdoc.rb
index f9b1df6cd5..69baae0039 100644
--- a/test/rubygems/test_gem_rdoc.rb
+++ b/test/rubygems/test_gem_rdoc.rb
@@ -100,7 +100,7 @@ class TestGemRDoc < Gem::TestCase
assert_equal @a.base_dir, e.directory
ensure
- FileUtils.chmod(0o755, @a.base_dir) if File.directory?(@a.base_dir)
+ FileUtils.chmod(0755, @a.base_dir) if File.directory?(@a.base_dir)
end
def test_ri_installed?
@@ -130,7 +130,7 @@ class TestGemRDoc < Gem::TestCase
assert_equal @a.doc_dir, e.directory
ensure
if File.exist? @a.doc_dir
- FileUtils.chmod 0o755, @a.doc_dir
+ FileUtils.chmod 0755, @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 e71b2f5ff6..a501a9f740 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -162,7 +162,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_cache_update_path
- uri = Gem::URI "http://example/file"
+ uri = URI "http://example/file"
path = File.join @tempdir, "file"
fetcher = util_fuck_with_fetcher "hello"
@@ -176,7 +176,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_cache_update_path_with_utf8_internal_encoding
with_internal_encoding("UTF-8") do
- uri = Gem::URI "http://example/file"
+ uri = URI "http://example/file"
path = File.join @tempdir, "file"
data = String.new("\xC8").force_encoding(Encoding::BINARY)
@@ -190,7 +190,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_cache_update_path_no_update
- uri = Gem::URI "http://example/file"
+ uri = URI "http://example/file"
path = File.join @tempdir, "file"
fetcher = util_fuck_with_fetcher "hello"
@@ -206,7 +206,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher = Gem::RemoteFetcher.fetcher
fetcher.instance_variable_set :@test_data, data
- if blow
+ unless blow
+ def fetcher.fetch_path(arg, *rest)
+ @test_arg = arg
+ @test_data
+ end
+ else
def fetcher.fetch_path(arg, *rest)
# OMG I'm such an ass
class << self; remove_method :fetch_path; end
@@ -217,11 +222,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
raise Gem::RemoteFetcher::FetchError.new("haha!", "")
end
- else
- def fetcher.fetch_path(arg, *rest)
- @test_arg = arg
- @test_data
- end
end
fetcher
@@ -311,7 +311,6 @@ 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
@@ -324,7 +323,6 @@ 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
@@ -339,7 +337,9 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_download_install_dir
- a1_data = File.open @a1_gem, "rb", &:read
+ a1_data = File.open @a1_gem, "rb" do |fp|
+ fp.read
+ end
fetcher = util_fuck_with_fetcher a1_data
@@ -356,19 +356,14 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
assert File.exist?(a1_cache_gem)
end
- unless Gem.win_platform? || Process.uid.zero? # File.chmod doesn't work
+ unless 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 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")
+ 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")
Dir.chdir @tempdir do
inst = Gem::RemoteFetcher.fetcher
@@ -377,23 +372,21 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
assert_equal(File.join(@tempdir, @a1.file_name),
inst.download(@a1, local_path))
ensure
- if local_path
- FileUtils.chmod 0o755, File.join(Gem.user_dir, "cache")
- FileUtils.chmod 0o755, @a1.cache_dir
- end
+ FileUtils.chmod 0755, File.join(Gem.user_dir, "cache")
+ FileUtils.chmod 0755, @a1.cache_dir
end
def test_download_read_only
- FileUtils.chmod 0o555, @a1.cache_dir
- FileUtils.chmod 0o555, @gemhome
+ FileUtils.chmod 0555, @a1.cache_dir
+ FileUtils.chmod 0555, @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 0o755, @gemhome
- FileUtils.chmod 0o755, @a1.cache_dir
+ FileUtils.chmod 0755, @gemhome
+ FileUtils.chmod 0755, @a1.cache_dir
end
end
@@ -423,7 +416,6 @@ 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
@@ -544,8 +536,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher.fetch_path url
end
- assert_match(/ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z/,
- e.message)
+ assert_match %r{ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z},
+ e.message
assert_equal url, e.uri
end
@@ -554,7 +546,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@fetcher = fetcher
def fetcher.fetch_http(uri, mtime = nil, head = nil)
- raise Gem::Timeout::Error, "timed out"
+ raise Timeout::Error, "timed out"
end
url = "http://example.com/uri"
@@ -563,8 +555,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher.fetch_path url
end
- assert_match(/Gem::Timeout::Error: timed out \(#{Regexp.escape url}\)\z/,
- e.message)
+ assert_match %r{Timeout::Error: timed out \(#{Regexp.escape url}\)\z},
+ e.message
assert_equal url, e.uri
end
@@ -582,8 +574,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher.fetch_path url
end
- assert_match(/SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z/,
- e.message)
+ assert_match %r{SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z},
+ e.message
assert_equal url, e.uri
end
@@ -613,7 +605,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
nil
end
- assert_nil fetcher.fetch_path(Gem::URI.parse(@gem_repo), Time.at(0))
+ assert_nil fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
end
def test_implicit_no_proxy
@@ -658,20 +650,19 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def fetcher.request(uri, request_class, last_modified = nil)
url = "http://gems.example.com/redirect"
- if defined? @requested
- res = Gem::Net::HTTPOK.new nil, 200, nil
- def res.body
- "real_path"
- end
- else
+ unless defined? @requested
@requested = true
- res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil
+ res = 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 Gem::URI.parse(url)
+ data = fetcher.fetch_http URI.parse(url)
assert_equal "real_path", data
end
@@ -683,13 +674,13 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def fetcher.request(uri, request_class, last_modified = nil)
url = "http://gems.example.com/redirect"
- res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil
+ res = Net::HTTPMovedPermanently.new nil, 301, nil
res.add_field "Location", url
res
end
e = assert_raise Gem::RemoteFetcher::FetchError do
- fetcher.fetch_http Gem::URI.parse(url)
+ fetcher.fetch_http URI.parse(url)
end
assert_equal "too many redirects (#{url})", e.message
@@ -701,12 +692,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
url = "http://gems.example.com/redirect"
def fetcher.request(uri, request_class, last_modified = nil)
- res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil
+ res = Net::HTTPMovedPermanently.new nil, 301, nil
res
end
e = assert_raise Gem::RemoteFetcher::FetchError do
- fetcher.fetch_http Gem::URI.parse(url)
+ fetcher.fetch_http URI.parse(url)
end
assert_equal "redirecting but no redirect location was given (#{url})", e.message
@@ -714,7 +705,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_http_with_additional_headers
ENV["http_proxy"] = @proxy_uri
- ENV["no_proxy"] = Gem::URI.parse(@server_uri).host
+ ENV["no_proxy"] = URI::parse(@server_uri).host
fetcher = Gem::RemoteFetcher.new nil, nil, { "X-Captain" => "murphy" }
@fetcher = fetcher
assert_equal "murphy", fetcher.fetch_path(@server_uri)
@@ -728,10 +719,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def fetcher.request(uri, request_class, last_modified = nil)
$fetched_uri = uri
- res = Gem::Net::HTTPOK.new nil, 200, nil
- def res.body
- "success"
- end
+ res = Net::HTTPOK.new nil, 200, nil
+ def res.body() "success" end
res
end
@@ -747,7 +736,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
s3_uri_signer
end
- data = fetcher.fetch_s3 Gem::URI.parse(url)
+ data = fetcher.fetch_s3 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
@@ -757,10 +746,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b"
end
ensure
@@ -769,10 +758,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2"
end
ensure
@@ -781,10 +770,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken"
end
ensure
@@ -796,10 +785,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b"
end
ensure
@@ -812,10 +801,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2"
end
ensure
@@ -828,10 +817,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken"
end
ensure
@@ -841,18 +830,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) 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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b", nil, "us-east-1",
'{"AccessKeyId": "testuser", "SecretAccessKey": "testpass"}'
end
@@ -862,11 +851,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2",
'{"AccessKeyId": "testuser", "SecretAccessKey": "testpass"}'
end
@@ -876,11 +865,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(1_561_353_581) do
+ Time.stub :now, Time.at(1561353581) do
assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken", "us-east-1",
'{"AccessKeyId": "testuser", "SecretAccessKey": "testpass", "Token": "testtoken"}'
end
@@ -893,7 +882,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@fetcher = fetcher
e = assert_raise Gem::RemoteFetcher::FetchError do
- fetcher.fetch_s3 Gem::URI.parse(url)
+ fetcher.fetch_s3 URI.parse(url)
end
assert_match expected_message, e.message
@@ -906,7 +895,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"
@@ -916,7 +905,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"
@@ -925,7 +914,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"
@@ -936,7 +925,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_observe_no_proxy_env_single_host
use_ui @stub_ui do
ENV["http_proxy"] = @proxy_uri
- ENV["no_proxy"] = Gem::URI.parse(@server_uri).host
+ ENV["no_proxy"] = URI::parse(@server_uri).host
fetcher = Gem::RemoteFetcher.new nil
@fetcher = fetcher
assert_data_from_server fetcher.fetch_path(@server_uri)
@@ -946,7 +935,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, #{Gem::URI.parse(@server_uri).host}"
+ ENV["no_proxy"] = "fakeurl.com, #{URI::parse(@server_uri).host}"
fetcher = Gem::RemoteFetcher.new nil
@fetcher = fetcher
assert_data_from_server fetcher.fetch_path(@server_uri)
@@ -958,8 +947,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@fetcher = fetcher
assert_throws :block_called do
- fetcher.request Gem::URI("http://example"), Gem::Net::HTTP::Get do |req|
- assert_kind_of Gem::Net::HTTPGenericRequest, req
+ fetcher.request URI("http://example"), Net::HTTP::Get do |req|
+ assert_kind_of Net::HTTPGenericRequest, req
throw :block_called
end
end
@@ -983,33 +972,31 @@ 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
@@ -1094,7 +1081,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
class NilLog < WEBrick::Log
- def log(level, data) # Do nothing
+ def log(level, data) #Do nothing
end
end
@@ -1129,7 +1116,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@ssl_server_thread.kill.join
@ssl_server_thread = nil
end
- WEBrick::Utils::TimeoutHandler.terminate
+ utils = WEBrick::Utils # TimeoutHandler is since 1.9
+ utils::TimeoutHandler.terminate if defined?(utils::TimeoutHandler.terminate)
end
def normal_server_port
@@ -1145,17 +1133,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|
@@ -1163,12 +1151,14 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
server.ssl_context.tmp_dh_callback = proc { TEST_KEY_DH2048 }
t = Thread.new do
- server.start
- rescue StandardError => ex
- puts "ERROR during server thread: #{ex.message}"
- raise
- ensure
- server.shutdown
+ begin
+ server.start
+ rescue Exception => ex
+ puts "ERROR during server thread: #{ex.message}"
+ raise
+ ensure
+ server.shutdown
+ end
end
while server.status != :Running
sleep 0.1
@@ -1185,12 +1175,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"]
@@ -1204,7 +1194,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"
@@ -1215,11 +1205,13 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
end
th = Thread.new do
- s.start
- rescue StandardError => ex
- abort "ERROR during server thread: #{ex.message}"
- ensure
- s.shutdown
+ begin
+ s.start
+ rescue Exception => ex
+ abort "ERROR during server thread: #{ex.message}"
+ ensure
+ s.shutdown
+ end
end
th[:server] = s
th
diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb
index 5e9b264dac..956960a47a 100644
--- a/test/rubygems/test_gem_request.rb
+++ b/test/rubygems/test_gem_request.rb
@@ -34,7 +34,7 @@ class TestGemRequest < Gem::TestCase
super
@proxy_uri = "http://localhost:1234"
- @uri = Gem::URI("http://example")
+ @uri = URI("http://example")
@request = make_request @uri, nil, nil, nil
end
@@ -56,7 +56,7 @@ class TestGemRequest < Gem::TestCase
def test_initialize_proxy_URI
proxy_uri = "http://proxy.example.com"
- request = make_request @uri, nil, nil, Gem::URI(proxy_uri)
+ request = make_request @uri, nil, nil, URI(proxy_uri)
assert_equal proxy_uri, request.proxy_uri.to_s
end
@@ -77,18 +77,18 @@ class TestGemRequest < Gem::TestCase
def test_initialize_proxy_ENV_https
ENV["https_proxy"] = @proxy_uri
- request = make_request Gem::URI("https://example"), nil, nil, nil
+ request = make_request URI("https://example"), nil, nil, nil
proxy = request.proxy_uri
- assert_equal Gem::URI(@proxy_uri), proxy
+ assert_equal URI(@proxy_uri), proxy
end
def test_proxy_ENV
ENV["http_proxy"] = "http://proxy"
ENV["https_proxy"] = ""
- request = make_request Gem::URI("https://example"), nil, nil, nil
+ request = make_request URI("https://example"), nil, nil, nil
proxy = request.proxy_uri
@@ -96,13 +96,13 @@ class TestGemRequest < Gem::TestCase
end
def test_configure_connection_for_https
- connection = Gem::Net::HTTP.new "localhost", 443
+ connection = 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 Gem::URI("https://example"), nil, nil, nil
+ end.create_with_proxy URI("https://example"), nil, nil, nil
Gem::Request.configure_connection_for_https connection, request.cert_files
@@ -112,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 = Gem::Net::HTTP.new "localhost", 443
+ connection = 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 Gem::URI("https://example"), nil, nil, nil
+ end.create_with_proxy URI("https://example"), nil, nil, nil
Gem::Request.configure_connection_for_https connection, request.cert_files
@@ -138,17 +138,17 @@ class TestGemRequest < Gem::TestCase
request = make_request @uri, nil, nil, nil
proxy = request.proxy_uri
- assert_equal Gem::URI(@proxy_uri), proxy
+ assert_equal URI(@proxy_uri), proxy
end
def test_get_proxy_from_env_https
ENV["https_proxy"] = @proxy_uri
- uri = Gem::URI("https://example")
+ uri = URI("https://example")
request = make_request uri, nil, nil, nil
proxy = request.proxy_uri
- assert_equal Gem::URI(@proxy_uri), proxy
+ assert_equal URI(@proxy_uri), proxy
end
def test_get_proxy_from_env_domain
@@ -191,9 +191,9 @@ class TestGemRequest < Gem::TestCase
end
def test_fetch
- 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)
+ 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)
@request.fetch
end
@@ -204,58 +204,58 @@ class TestGemRequest < Gem::TestCase
def test_fetch_basic_auth
Gem.configuration.verbose = :really
- 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|
+ 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|
use_ui @ui do
- @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil)
+ @request = make_request(uri, 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(Gem::URI.parse("https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}"))
+ uri = Gem::Uri.new(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, Gem::Net::HTTP::Get, nil, nil)
+ @request = make_request(uri, 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(Gem::URI.parse("https://%7BDEScede%7Dpass:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}"))
+ uri = Gem::Uri.new(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, Gem::Net::HTTP::Get, nil, nil)
+ @request = make_request(uri, 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(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)
+ 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)
@request.fetch
end
@@ -264,10 +264,10 @@ class TestGemRequest < Gem::TestCase
end
def test_fetch_unmodified
- uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}"))
+ uri = Gem::Uri.new(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, Gem::Net::HTTP::Get, t, nil)
+ conn, response = util_stub_net_http(:body => "", :code => 304) do |c|
+ @request = make_request(uri, Net::HTTP::Get, t, nil)
[c, @request.fetch]
end
@@ -286,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(/\(#{Regexp.escape RUBY_RELEASE_DATE} /, ua)
+ assert_match %r{\(#{Regexp.escape RUBY_RELEASE_DATE} }, ua
end
def test_user_agent_engine
@@ -297,7 +297,7 @@ class TestGemRequest < Gem::TestCase
ua = make_request(@uri, nil, nil, nil).user_agent
- assert_match(/\) vroom/, ua)
+ assert_match %r{\) vroom}, ua
ensure
util_restore_version
end
@@ -310,7 +310,7 @@ class TestGemRequest < Gem::TestCase
ua = make_request(@uri, nil, nil, nil).user_agent
- assert_match(/\)/, ua)
+ assert_match %r{\)}, ua
ensure
util_restore_version
end
@@ -333,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
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
Object.send :const_set, :RUBY_REVISION, 6
ua = make_request(@uri, nil, nil, nil).user_agent
@@ -344,6 +344,20 @@ 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?
@@ -484,19 +498,21 @@ 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
+ Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if
+ defined?(@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
- Object.send :const_set, :RUBY_REVISION, @orig_ruby_revision
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+ Object.send :const_set, :RUBY_REVISION, @orig_RUBY_REVISION if
+ defined?(@orig_RUBY_REVISION)
end
def util_save_version
- @orig_ruby_engine = RUBY_ENGINE
- @orig_ruby_patchlevel = RUBY_PATCHLEVEL
- @orig_ruby_revision = RUBY_REVISION
+ @orig_RUBY_ENGINE = RUBY_ENGINE
+ @orig_RUBY_PATCHLEVEL = RUBY_PATCHLEVEL
+ @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION
end
def util_stub_net_http(hash)
@@ -511,10 +527,7 @@ 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 966447bff6..729f6333b7 100644
--- a/test/rubygems/test_gem_request_connection_pools.rb
+++ b/test/rubygems/test_gem_request_connection_pools.rb
@@ -2,7 +2,7 @@
require_relative "helper"
require "rubygems/request"
-require "rubygems/vendored_timeout"
+require "timeout"
class TestGemRequestConnectionPool < Gem::TestCase
class FakeHttp
@@ -18,7 +18,7 @@ class TestGemRequestConnectionPool < Gem::TestCase
@old_client = Gem::Request::ConnectionPools.client
Gem::Request::ConnectionPools.client = FakeHttp
- @proxy = Gem::URI "http://proxy.example"
+ @proxy = URI "http://proxy.example"
end
def teardown
@@ -49,7 +49,7 @@ class TestGemRequestConnectionPool < Gem::TestCase
end
def test_checkout_same_connection
- uri = Gem::URI.parse("http://example/some_endpoint")
+ uri = URI.parse("http://example/some_endpoint")
pools = Gem::Request::ConnectionPools.new nil, []
pool = pools.pool_for uri
@@ -99,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, Gem::URI("http://example"), nil
+ net_http_args = pools.send :net_http_args, URI("http://example"), nil
assert_equal ["example", 80], net_http_args
end
@@ -107,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, Gem::URI("http://[::1]"), nil
+ net_http_args = pools.send :net_http_args, URI("http://[::1]"), nil
assert_equal ["::1", 80], net_http_args
end
@@ -115,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, Gem::URI("http://example"), @proxy
+ net_http_args = pools.send :net_http_args, 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, Gem::URI("http://example"), @proxy
+ net_http_args = pools.send :net_http_args, 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 = Gem::URI.parse("http://example/some_endpoint")
+ uri = URI.parse("http://example/some_endpoint")
pools = Gem::Request::ConnectionPools.new nil, []
pool = pools.pool_for uri
pool.checkout
Thread.new do
- assert_raise(Gem::Timeout::Error) do
- Gem::Timeout.timeout(1) do
+ assert_raise(Timeout::Error) do
+ 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 9aa244892c..7ee5c9cdeb 100644
--- a/test/rubygems/test_gem_request_set.rb
+++ b/test/rubygems/test_gem_request_set.rb
@@ -8,6 +8,8 @@ class TestGemRequestSet < Gem::TestCase
super
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
+
+ @DR = Gem::Resolver
end
def test_gem
@@ -44,7 +46,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
@@ -55,7 +57,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
@@ -87,7 +89,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
@@ -109,11 +111,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
@@ -133,7 +135,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
@@ -171,7 +173,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
@@ -225,7 +227,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
@@ -250,7 +252,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
@@ -323,7 +325,7 @@ ruby "0"
res = rs.resolve StaticSet.new([a, b])
assert_equal 2, res.size
- names = res.map(&:full_name).sort
+ names = res.map {|s| s.full_name }.sort
assert_equal ["a-2", "b-2"], names
@@ -342,7 +344,7 @@ ruby "0"
res = rs.resolve StaticSet.new([a, b, c])
assert_equal 3, res.size
- names = res.map(&:full_name).sort
+ names = res.map {|s| s.full_name }.sort
assert_equal %w[a-1.b b-1.b c-1.1.b], names
end
@@ -409,12 +411,12 @@ ruby "0"
res = rs.resolve
assert_equal 1, res.size
- names = res.map(&:full_name).sort
+ names = res.map {|s| s.full_name }.sort
assert_equal %w[a-1], names
- assert_equal [Gem::Resolver::BestSet, Gem::Resolver::GitSet, Gem::Resolver::VendorSet, Gem::Resolver::SourceSet],
- rs.sets.map(&:class)
+ assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet, @DR::SourceSet],
+ rs.sets.map {|set| set.class }
end
def test_resolve_ignore_dependencies
@@ -428,7 +430,7 @@ ruby "0"
res = rs.resolve StaticSet.new([a, b])
assert_equal 1, res.size
- names = res.map(&:full_name).sort
+ names = res.map {|s| s.full_name }.sort
assert_equal %w[a-2], names
end
@@ -473,12 +475,12 @@ ruby "0"
res = rs.resolve
assert_equal 2, res.size
- names = res.map(&:full_name).sort
+ names = res.map {|s| s.full_name }.sort
assert_equal ["a-1", "b-2"], names
- assert_equal [Gem::Resolver::BestSet, Gem::Resolver::GitSet, Gem::Resolver::VendorSet, Gem::Resolver::SourceSet],
- rs.sets.map(&:class)
+ assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet, @DR::SourceSet],
+ rs.sets.map {|set| set.class }
end
def test_sorted_requests
@@ -491,7 +493,7 @@ ruby "0"
rs.resolve StaticSet.new([a, b, c])
- names = rs.sorted_requests.map(&:full_name)
+ names = rs.sorted_requests.map {|s| s.full_name }
assert_equal %w[c-2 b-2 a-2], names
end
@@ -520,14 +522,14 @@ ruby "0"
installers << installer
end
- assert_equal %w[b-1 a-1], reqs.map(&:full_name)
+ assert_equal %w[b-1 a-1], reqs.map {|req| req.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(&:full_name)
+ assert_equal %w[b-1 a-1], installed.map {|s| s.full_name }
assert done_installing_ran
end
@@ -550,7 +552,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(&:full_name)
+ assert_equal %w[b-1 a-1], installed.map {|s| s.full_name }
end
def test_install_into_development_shallow
@@ -574,15 +576,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(&:full_name).sort
+ assert_equal %w[a-1 b-1], installed.map {|s| s.full_name }.sort
end
def test_sorted_requests_development_shallow
@@ -607,7 +609,7 @@ ruby "0"
rs.resolve StaticSet.new [a_spec, b_spec, c_spec]
- assert_equal %w[b-1 a-1], rs.sorted_requests.map(&:full_name)
+ assert_equal %w[b-1 a-1], rs.sorted_requests.map {|req| req.full_name }
end
def test_tsort_each_child_development
@@ -636,7 +638,7 @@ ruby "0"
deps = rs.enum_for(:tsort_each_child, a_req).to_a
- assert_equal %w[b], deps.map(&:name)
+ assert_equal %w[b], deps.map {|dep| dep.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 af32005a16..0d4adc24ef 100644
--- a/test/rubygems/test_gem_request_set_gem_dependency_api.rb
+++ b/test/rubygems/test_gem_request_set_gem_dependency_api.rb
@@ -7,12 +7,14 @@ 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 = Gem::RequestSet::GemDependencyAPI.new @set, "gem.deps.rb"
+ @gda = @GDA.new @set, "gem.deps.rb"
@gda.instance_variable_set :@git_set, @git_set
@gda.instance_variable_set :@vendor_set, @vendor_set
end
@@ -47,7 +49,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
@@ -90,7 +92,7 @@ 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
@@ -102,7 +104,7 @@ 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
@@ -115,7 +117,7 @@ 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
@@ -129,7 +131,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
@@ -140,7 +142,7 @@ 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
@@ -150,7 +152,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
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
@@ -161,7 +163,7 @@ 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
@@ -170,7 +172,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
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
@@ -178,7 +180,7 @@ 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
@@ -191,7 +193,7 @@ 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
@@ -204,7 +206,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
@@ -212,7 +214,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
@@ -222,7 +224,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
@@ -230,7 +232,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
@@ -244,11 +246,10 @@ 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,37 +258,36 @@ 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 = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :ruby
+ gda = @GDA.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 = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :ruby
+ gda = @GDA.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 = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :ruby
+ gda = @GDA.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 = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :ruby
+ gda = @GDA.new set, "gem.deps.rb"
+ gda.gem "a", :platforms => :ruby
assert_empty set.dependencies
end
@@ -296,8 +296,8 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
with_engine_version "ruby", "2.0.0" do
set = Gem::RequestSet.new
- gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :ruby
+ gda = @GDA.new set, "gem.deps.rb"
+ gda.gem "a", :platforms => :ruby
assert_empty set.dependencies
end
@@ -307,32 +307,31 @@ 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 = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :ruby
+ gda = @GDA.new set, "gem.deps.rb"
+ gda.gem "a", :platforms => :ruby
refute_empty set.dependencies
set = Gem::RequestSet.new
- gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :maglev
+ gda = @GDA.new set, "gem.deps.rb"
+ gda.gem "a", :platforms => :maglev
refute_empty set.dependencies
end
@@ -343,38 +342,37 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_platforms_truffleruby
with_engine_version "truffleruby", "1.0.0" do
set = Gem::RequestSet.new
- gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :truffleruby
+ gda = @GDA.new set, "gem.deps.rb"
+ gda.gem "a", :platforms => :truffleruby
refute_empty set.dependencies
set = Gem::RequestSet.new
- gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
- gda.gem "a", platforms: :maglev
+ gda = @GDA.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
@@ -384,7 +382,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
@@ -392,15 +390,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
@@ -409,7 +407,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
@@ -419,7 +417,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
@@ -447,7 +445,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
@@ -455,19 +453,19 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_source_mismatch
name, _, directory = vendor_gem
- gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
+ gda = @GDA.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 = Gem::RequestSet::GemDependencyAPI.new @set, nil
+ gda = @GDA.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
@@ -480,7 +478,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_deps_file
assert_equal "gem.deps.rb", @gda.gem_deps_file
- gda = Gem::RequestSet::GemDependencyAPI.new @set, "foo/Gemfile"
+ gda = @GDA.new @set, "foo/Gemfile"
assert_equal "Gemfile", gda.gem_deps_file
end
@@ -489,10 +487,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(&:to_s)
+ assert_equal [:a, :b, :c, :d], groups.sort_by {|group| group.to_s }
end
def test_gemspec
@@ -537,7 +535,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
@@ -569,7 +567,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
@@ -599,7 +597,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
@@ -621,7 +619,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
"git://example/#{repo_name}.git"
end
- @gda.gem "a", example: "repo"
+ @gda.gem "a", :example => "repo"
assert_equal ["git://example/repo.git", nil], @git_set.repositories["a"]
end
@@ -645,7 +643,7 @@ end
GEM_DEPS
io.flush
- gda = Gem::RequestSet::GemDependencyAPI.new @set, io.path
+ gda = @GDA.new @set, io.path
assert_equal gda, gda.load
@@ -656,7 +654,7 @@ end
end
def test_pin_gem_source
- gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
+ gda = @GDA.new @set, nil
gda.send :pin_gem_source, "a"
gda.send :pin_gem_source, "a"
@@ -677,7 +675,7 @@ end
end
def test_platform_mswin
- if Gem.win_platform?
+ if win_platform?
util_set_arch "x86-mswin32-60" do
@gda.platform :mswin do
@gda.gem "a"
@@ -698,10 +696,9 @@ 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 = Gem::RequestSet::GemDependencyAPI.new @set, nil
+ gda = @GDA.new @set, nil
with_engine_version "ruby", "1.8.7" do
gda.platform :mri_19, :mri_20 do
@@ -711,7 +708,7 @@ end
assert_empty @set.dependencies
- gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
+ gda = @GDA.new @set, nil
with_engine_version "ruby", "2.0.0" do
gda.platform :mri_19, :mri_20 do
@@ -725,8 +722,7 @@ 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"
@@ -738,7 +734,7 @@ end
end
def test_platforms
- unless Gem.win_platform?
+ unless win_platform?
util_set_arch "i686-darwin8.10.1" do
@gda.platforms :ruby do
@gda.gem "a"
@@ -762,19 +758,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",
@@ -785,7 +781,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",
@@ -795,7 +791,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_parser.rb b/test/rubygems/test_gem_request_set_lockfile_parser.rb
index 253a59b243..0a6a7177a9 100644
--- a/test/rubygems/test_gem_request_set_lockfile_parser.rb
+++ b/test/rubygems/test_gem_request_set_lockfile_parser.rb
@@ -94,7 +94,7 @@ DEPENDENCIES
assert lockfile_set, "could not find a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
+ assert_equal %w[a-2], lockfile_set.specs.map {|tuple| tuple.full_name }
end
def test_parse_dependencies
@@ -124,7 +124,7 @@ DEPENDENCIES
assert lockfile_set, "could not find a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
+ assert_equal %w[a-2], lockfile_set.specs.map {|tuple| tuple.full_name }
end
def test_parse_DEPENDENCIES_git
@@ -218,7 +218,7 @@ DEPENDENCIES
assert lockfile_set, "found a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
+ assert_equal %w[a-2], lockfile_set.specs.map {|s| s.full_name }
end
def test_parse_GEM_remote_multiple
@@ -246,7 +246,7 @@ DEPENDENCIES
assert lockfile_set, "found a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
+ assert_equal %w[a-2], lockfile_set.specs.map {|s| s.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 } }
@@ -284,7 +284,7 @@ DEPENDENCIES
assert git_set, "could not find a GitSet"
- assert_equal %w[a-2], git_set.specs.values.map(&:full_name)
+ assert_equal %w[a-2], git_set.specs.values.map {|s| s.full_name }
assert_equal [dep("b", ">= 3"), dep("c")],
git_set.specs.values.first.dependencies
@@ -438,7 +438,7 @@ DEPENDENCIES
assert vendor_set, "could not find a VendorSet"
- assert_equal %w[a-1], vendor_set.specs.values.map(&:full_name)
+ assert_equal %w[a-1], vendor_set.specs.values.map {|s| s.full_name }
spec = vendor_set.load_spec "a", nil, nil, nil
@@ -497,14 +497,14 @@ DEPENDENCIES
assert lockfile_set, "could not find a LockSet"
- assert_equal %w[a-2 b-3], lockfile_set.specs.map(&:full_name)
+ assert_equal %w[a-2 b-3], lockfile_set.specs.map {|tuple| tuple.full_name }
expected = [
Gem::Platform::RUBY,
Gem::Platform.new("x86_64-linux"),
]
- assert_equal expected, lockfile_set.specs.map(&:platform)
+ assert_equal expected, lockfile_set.specs.map {|tuple| tuple.platform }
spec = lockfile_set.specs.first
diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb
index de0d11ec00..e482630392 100644
--- a/test/rubygems/test_gem_requirement.rb
+++ b/test/rubygems/test_gem_requirement.rb
@@ -12,14 +12,6 @@ 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
@@ -92,7 +84,7 @@ class TestGemRequirement < Gem::TestCase
Gem::Requirement.parse(Gem::Version.new("2"))
end
- unless Gem.java_platform? && ENV["JRUBY_OPTS"].to_s.include?("--debug")
+ if !(Gem.java_platform? && ENV["JRUBY_OPTS"].to_s.include?("--debug"))
def test_parse_deduplication
assert_same "~>", Gem::Requirement.parse("~> 1").first
end
@@ -295,7 +287,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
@@ -445,19 +437,19 @@ class TestGemRequirement < Gem::TestCase
end
def test_marshal_load_attack
- wa = Gem::Net::WriteAdapter.allocate
+ wa = 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 = Gem::Net::WriteAdapter.allocate
+ wa = 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 = Gem::Net::BufferedIO.allocate
+ io = 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 b7dadda708..3dbbce87bc 100644
--- a/test/rubygems/test_gem_resolver.rb
+++ b/test/rubygems/test_gem_resolver.rb
@@ -3,12 +3,18 @@
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 Gem::URI @gem_repo
+ source = Gem::Source.new URI @gem_repo
specs = specs.map do |spec|
Gem::Resolver::SpecSpecification.new nil, spec, source
@@ -20,10 +26,10 @@ class TestGemResolver < Gem::TestCase
def assert_resolves_to(expected, resolver)
actual = resolver.resolve
- exp = expected.sort_by(&:full_name)
- act = actual.map {|a| a.spec.spec }.sort_by(&:full_name)
+ exp = expected.sort_by {|s| s.full_name }
+ act = actual.map {|a| a.spec.spec }.sort_by {|s| s.full_name }
- msg = "Set of gems was not the same: #{exp.map(&:full_name).inspect} != #{act.map(&:full_name).inspect}"
+ msg = "Set of gems was not the same: #{exp.map {|x| x.full_name }.inspect} != #{act.map {|x| x.full_name }.inspect}"
assert_equal exp, act, msg
rescue Gem::DependencyResolutionError => e
@@ -31,18 +37,18 @@ class TestGemResolver < Gem::TestCase
end
def test_self_compose_sets_best_set
- best_set = Gem::Resolver::BestSet.new
+ best_set = @DR::BestSet.new
- composed = Gem::Resolver.compose_sets best_set
+ composed = @DR.compose_sets best_set
assert_equal best_set, composed
end
def test_self_compose_sets_multiple
- index_set = Gem::Resolver::IndexSet.new
- vendor_set = Gem::Resolver::VendorSet.new
+ index_set = @DR::IndexSet.new
+ vendor_set = @DR::VendorSet.new
- composed = Gem::Resolver.compose_sets index_set, vendor_set
+ composed = @DR.compose_sets index_set, vendor_set
assert_kind_of Gem::Resolver::ComposedSet, composed
@@ -50,14 +56,14 @@ class TestGemResolver < Gem::TestCase
end
def test_self_compose_sets_nest
- index_set = Gem::Resolver::IndexSet.new
- vendor_set = Gem::Resolver::VendorSet.new
+ index_set = @DR::IndexSet.new
+ vendor_set = @DR::VendorSet.new
- inner = Gem::Resolver.compose_sets index_set, vendor_set
+ inner = @DR.compose_sets index_set, vendor_set
- current_set = Gem::Resolver::CurrentSet.new
+ current_set = @DR::CurrentSet.new
- composed = Gem::Resolver.compose_sets inner, current_set
+ composed = @DR.compose_sets inner, current_set
assert_kind_of Gem::Resolver::ComposedSet, composed
@@ -65,23 +71,23 @@ class TestGemResolver < Gem::TestCase
end
def test_self_compose_sets_nil
- index_set = Gem::Resolver::IndexSet.new
+ index_set = @DR::IndexSet.new
- composed = Gem::Resolver.compose_sets index_set, nil
+ composed = @DR.compose_sets index_set, nil
assert_same index_set, composed
e = assert_raise ArgumentError do
- Gem::Resolver.compose_sets nil
+ @DR.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 = Gem::Resolver::IndexSet.new
+ index_set = @DR::IndexSet.new
- composed = Gem::Resolver.compose_sets index_set
+ composed = @DR.compose_sets index_set
assert_same index_set, composed
end
@@ -99,7 +105,7 @@ class TestGemResolver < Gem::TestCase
res.requests a1, act, reqs
- assert_equal ["b (= 2)"], reqs.map(&:to_s)
+ assert_equal ["b (= 2)"], reqs.map {|req| req.to_s }
end
def test_requests_development
@@ -121,7 +127,7 @@ class TestGemResolver < Gem::TestCase
res.requests spec, act, reqs
- assert_equal ["b (= 2)"], reqs.map(&:to_s)
+ assert_equal ["b (= 2)"], reqs.map {|req| req.to_s }
assert spec.instance_variable_defined? :@called
end
@@ -202,8 +208,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
@@ -773,29 +779,29 @@ class TestGemResolver < Gem::TestCase
end
def test_sorts_by_source_then_version
- 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"
+ sourceA = Gem::Source.new "http://example.com/a"
+ sourceB = Gem::Source.new "http://example.com/b"
+ sourceC = 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, 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),
+ 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),
]
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 53875b72cb..a346033c13 100644
--- a/test/rubygems/test_gem_resolver_activation_request.rb
+++ b/test/rubygems/test_gem_resolver_activation_request.rb
@@ -6,22 +6,24 @@ class TestGemResolverActivationRequest < Gem::TestCase
def setup
super
- @dep = Gem::Resolver::DependencyRequest.new dep("a", ">= 0"), nil
+ @DR = Gem::Resolver
+
+ @dep = @DR::DependencyRequest.new dep("a", ">= 0"), nil
source = Gem::Source::Local.new
platform = Gem::Platform::RUBY
- @a3 = Gem::Resolver::IndexSpecification.new nil, "a", v(3), source, platform
+ @a3 = @DR::IndexSpecification.new nil, "a", v(3), source, platform
- @req = Gem::Resolver::ActivationRequest.new @a3, @dep
+ @req = @DR::ActivationRequest.new @a3, @dep
end
def test_development_eh
refute @req.development?
- dep_req = Gem::Resolver::DependencyRequest.new dep("a", ">= 0", :development), nil
+ dep_req = @DR::DependencyRequest.new dep("a", ">= 0", :development), nil
- act_req = Gem::Resolver::ActivationRequest.new @a3, dep_req
+ act_req = @DR::ActivationRequest.new @a3, dep_req
assert act_req.development?
end
@@ -34,7 +36,7 @@ class TestGemResolverActivationRequest < Gem::TestCase
def test_installed_eh
v_spec = Gem::Resolver::VendorSpecification.new nil, @a3
- @req = Gem::Resolver::ActivationRequest.new v_spec, @dep
+ @req = @DR::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 5781cf37d2..64918a2ad2 100644
--- a/test/rubygems/test_gem_resolver_api_set.rb
+++ b/test/rubygems/test_gem_resolver_api_set.rb
@@ -6,50 +6,51 @@ class TestGemResolverAPISet < Gem::TestCase
def setup
super
- @dep_uri = Gem::URI "#{@gem_repo}info/"
+ @DR = Gem::Resolver
+ @dep_uri = URI "#{@gem_repo}info/"
end
def test_initialize
- set = Gem::Resolver::APISet.new
+ set = @DR::APISet.new
- 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
+ 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
end
def test_initialize_deeper_uri
- set = Gem::Resolver::APISet.new "https://rubygemsserver.com/mygems/info"
+ set = @DR::APISet.new "https://rubygemsserver.com/mygems/info"
- 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
+ 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
end
def test_initialize_uri
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- assert_equal Gem::URI("#{@gem_repo}info/"), set.dep_uri
- assert_equal Gem::URI(@gem_repo.to_s), set.uri
+ assert_equal URI("#{@gem_repo}info/"), set.dep_uri
+ assert_equal URI("#{@gem_repo}"), 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 = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
expected = [
- Gem::Resolver::APISpecification.new(set, data.first),
+ @DR::APISpecification.new(set, data.first),
]
assert_equal expected, set.find_all(a_dep)
@@ -59,26 +60,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 = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
set.prerelease = true
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
expected = [
- Gem::Resolver::APISpecification.new(set, data.first),
- Gem::Resolver::APISpecification.new(set, data.last),
+ @DR::APISpecification.new(set, data.first),
+ @DR::APISpecification.new(set, data.last),
]
assert_equal expected, set.find_all(a_dep)
@@ -88,22 +89,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 = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
set.prefetch [a_dep]
expected = [
- Gem::Resolver::APISpecification.new(set, data.first),
+ @DR::APISpecification.new(set, data.first),
]
assert_equal expected, set.find_all(a_dep)
@@ -112,10 +113,10 @@ class TestGemResolverAPISet < Gem::TestCase
end
def test_find_all_local
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
set.remote = false
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
assert_empty set.find_all(a_dep)
end
@@ -125,9 +126,9 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---"
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
assert_empty set.find_all(a_dep)
@@ -142,14 +143,14 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
@fetcher.data["#{@dep_uri}b"] = "---"
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
- b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
+ b_dep = @DR::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep, b_dep]
- assert_equal %w[a-1], set.find_all(a_dep).map(&:full_name)
+ assert_equal %w[a-1], set.find_all(a_dep).map {|s| s.full_name }
assert_empty set.find_all(b_dep)
end
@@ -158,10 +159,10 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
- b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
+ b_dep = @DR::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep]
@@ -177,10 +178,10 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
@fetcher.data["#{@dep_uri}b"] = "---"
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
- b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
+ b_dep = @DR::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep, b_dep]
@@ -196,11 +197,11 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
@fetcher.data["#{@dep_uri}b"] = "---"
- set = Gem::Resolver::APISet.new @dep_uri
+ set = @DR::APISet.new @dep_uri
set.remote = false
- a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
- b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
+ a_dep = @DR::DependencyRequest.new dep("a"), nil
+ b_dep = @DR::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 2119d73478..6ec0aa48fa 100644
--- a/test/rubygems/test_gem_resolver_api_specification.rb
+++ b/test/rubygems/test_gem_resolver_api_specification.rb
@@ -6,10 +6,10 @@ 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"],
],
@@ -45,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"],
],
@@ -72,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
@@ -83,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
@@ -94,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
@@ -108,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
@@ -124,13 +124,13 @@ class TestGemResolverAPISpecification < Gem::TestCase
fetcher.spec "a", 1
end
- dep_uri = Gem::URI(@gem_repo) + "info"
+ dep_uri = 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
@@ -148,13 +148,13 @@ class TestGemResolverAPISpecification < Gem::TestCase
end
end
- dep_uri = Gem::URI(@gem_repo) + "info"
+ dep_uri = 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 8a750cdf8f..0609f7ab30 100644
--- a/test/rubygems/test_gem_resolver_best_set.rb
+++ b/test/rubygems/test_gem_resolver_best_set.rb
@@ -3,8 +3,14 @@
require_relative "helper"
class TestGemResolverBestSet < Gem::TestCase
+ def setup
+ super
+
+ @DR = Gem::Resolver
+ end
+
def test_initialize
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
assert_empty set.sets
end
@@ -16,15 +22,15 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
dependency = dep "a", "~> 1"
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1], found.map(&:full_name)
+ assert_equal %w[a-1], found.map {|s| s.full_name }
end
def test_find_all_fallback
@@ -32,19 +38,19 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "a", 1
end
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
- api_uri = Gem::URI(@gem_repo)
+ api_uri = URI(@gem_repo)
set.sets << Gem::Resolver::APISet.new(api_uri)
dependency = dep "a", "~> 1"
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1], found.map(&:full_name)
+ assert_equal %w[a-1], found.map {|s| s.full_name }
end
def test_find_all_local
@@ -54,12 +60,12 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
set.remote = false
dependency = dep "a", "~> 1"
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
found = set.find_all req
@@ -71,7 +77,7 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "a", 1
end
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
set.prefetch []
@@ -83,7 +89,7 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "a", 1
end
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
set.remote = false
set.prefetch []
@@ -92,9 +98,9 @@ class TestGemResolverBestSet < Gem::TestCase
end
def test_replace_failed_api_set
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
- api_uri = Gem::URI(@gem_repo) + "./info/"
+ api_uri = URI(@gem_repo) + "./info/"
api_set = Gem::Resolver::APISet.new api_uri
set.sets << api_set
@@ -113,7 +119,7 @@ class TestGemResolverBestSet < Gem::TestCase
end
def test_replace_failed_api_set_no_api_set
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo
@@ -129,9 +135,9 @@ class TestGemResolverBestSet < Gem::TestCase
end
def test_replace_failed_api_set_uri_with_credentials
- set = Gem::Resolver::BestSet.new
+ set = @DR::BestSet.new
- api_uri = Gem::URI(@gem_repo) + "./info/"
+ api_uri = 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_conflict.rb b/test/rubygems/test_gem_resolver_conflict.rb
index 5696ff266d..46831c2983 100644
--- a/test/rubygems/test_gem_resolver_conflict.rb
+++ b/test/rubygems/test_gem_resolver_conflict.rb
@@ -36,14 +36,16 @@ class TestGemResolverConflict < Gem::TestCase
end
def test_explanation_user_request
+ @DR = Gem::Resolver
+
spec = util_spec "a", 2
- a1_req = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil
- a2_req = Gem::Resolver::DependencyRequest.new dep("a", "= 2"), nil
+ a1_req = @DR::DependencyRequest.new dep("a", "= 1"), nil
+ a2_req = @DR::DependencyRequest.new dep("a", "= 2"), nil
- activated = Gem::Resolver::ActivationRequest.new spec, a2_req
+ activated = @DR::ActivationRequest.new spec, a2_req
- conflict = Gem::Resolver::Conflict.new a1_req, activated
+ conflict = @DR::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 3e14771da8..d8836da0aa 100644
--- a/test/rubygems/test_gem_resolver_dependency_request.rb
+++ b/test/rubygems/test_gem_resolver_dependency_request.rb
@@ -3,16 +3,22 @@
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 = Gem::Resolver::DependencyRequest.new a_dep, nil
+ a_dep_req = @DR.new a_dep, nil
refute a_dep_req.development?
b_dep = dep "b", ">= 1", :development
- b_dep_req = Gem::Resolver::DependencyRequest.new b_dep, nil
+ b_dep_req = @DR.new b_dep, nil
assert b_dep_req.development?
end
@@ -21,7 +27,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", 1
dependency = dep "a", ">= 1"
- dr = Gem::Resolver::DependencyRequest.new dependency, nil
+ dr = @DR.new dependency, nil
assert dr.match? spec
end
@@ -30,12 +36,12 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", "1.a"
a_dep = dep "a", ">= 1"
- a_dr = Gem::Resolver::DependencyRequest.new a_dep, nil
+ a_dr = @DR.new a_dep, nil
refute a_dr.match? spec
a_pre_dep = dep "a", ">= 1.a"
- a_pre_dr = Gem::Resolver::DependencyRequest.new a_pre_dep, nil
+ a_pre_dr = @DR.new a_pre_dep, nil
assert a_pre_dr.match? spec
end
@@ -44,7 +50,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", "2.a"
a_dep = dep "a", ">= 1"
- a_dr = Gem::Resolver::DependencyRequest.new a_dep, nil
+ a_dr = @DR.new a_dep, nil
assert a_dr.match? spec, true
end
@@ -53,7 +59,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", 1
dependency = dep "a", ">= 1"
- dr = Gem::Resolver::DependencyRequest.new dependency, nil
+ dr = @DR.new dependency, nil
assert dr.matches_spec? spec
end
@@ -62,7 +68,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", "1.a"
dependency = dep "a", ">= 0"
- dr = Gem::Resolver::DependencyRequest.new dependency, nil
+ dr = @DR.new dependency, nil
assert dr.matches_spec? spec
end
@@ -70,7 +76,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
def test_requirement
dependency = dep "a", ">= 1"
- dr = Gem::Resolver::DependencyRequest.new dependency, nil
+ dr = @DR.new dependency, nil
assert_equal dependency, dr.dependency
end
diff --git a/test/rubygems/test_gem_resolver_git_specification.rb b/test/rubygems/test_gem_resolver_git_specification.rb
index 621333d3bf..d13dbb0086 100644
--- a/test/rubygems/test_gem_resolver_git_specification.rb
+++ b/test/rubygems/test_gem_resolver_git_specification.rb
@@ -29,8 +29,7 @@ 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
diff --git a/test/rubygems/test_gem_resolver_index_set.rb b/test/rubygems/test_gem_resolver_index_set.rb
index 8ff1acbf1e..68d8841cc8 100644
--- a/test/rubygems/test_gem_resolver_index_set.rb
+++ b/test/rubygems/test_gem_resolver_index_set.rb
@@ -3,8 +3,14 @@
require_relative "helper"
class TestGemResolverIndexSet < Gem::TestCase
+ def setup
+ super
+
+ @DR = Gem::Resolver
+ end
+
def test_initialize
- set = Gem::Resolver::IndexSet.new
+ set = @DR::IndexSet.new
fetcher = set.instance_variable_get :@f
@@ -12,7 +18,7 @@ class TestGemResolverIndexSet < Gem::TestCase
end
def test_initialize_source
- set = Gem::Resolver::IndexSet.new "http://alternate.example"
+ set = @DR::IndexSet.new "http://alternate.example"
fetcher = set.instance_variable_get :@f
@@ -28,15 +34,15 @@ class TestGemResolverIndexSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = Gem::Resolver::IndexSet.new
+ set = @DR::IndexSet.new
dependency = dep "a", "~> 1"
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1], found.map(&:full_name)
+ assert_equal %w[a-1], found.map {|s| s.full_name }
end
def test_find_all_local
@@ -46,12 +52,12 @@ class TestGemResolverIndexSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = Gem::Resolver::IndexSet.new
+ set = @DR::IndexSet.new
set.remote = false
dependency = dep "a", "~> 1"
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
assert_empty set.find_all req
end
@@ -61,11 +67,11 @@ class TestGemResolverIndexSet < Gem::TestCase
fetcher.spec "a", "1.a"
end
- set = Gem::Resolver::IndexSet.new
+ set = @DR::IndexSet.new
dependency = dep "a"
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
found = set.find_all req
@@ -73,10 +79,10 @@ class TestGemResolverIndexSet < Gem::TestCase
dependency.prerelease = true
- req = Gem::Resolver::DependencyRequest.new dependency, nil
+ req = @DR::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1.a], found.map(&:full_name)
+ assert_equal %w[a-1.a], found.map {|s| s.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 ed9475f0cf..e795f99e68 100644
--- a/test/rubygems/test_gem_resolver_index_specification.rb
+++ b/test/rubygems/test_gem_resolver_index_specification.rb
@@ -10,8 +10,7 @@ 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
@@ -26,8 +25,7 @@ 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
@@ -41,8 +39,7 @@ 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_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb
index 202fe9d653..0e7518d03d 100644
--- a/test/rubygems/test_gem_resolver_installer_set.rb
+++ b/test/rubygems/test_gem_resolver_installer_set.rb
@@ -15,7 +15,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-2], set.always_install.map(&:full_name)
+ assert_equal %w[a-2], set.always_install.map {|s| s.full_name }
e = assert_raise Gem::UnsatisfiableDependencyError do
set.add_always_install dep("b")
@@ -49,7 +49,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1], set.always_install.map(&:full_name)
+ assert_equal %w[a-1], set.always_install.map {|s| s.full_name }
end
def test_add_always_install_platform_if_gem_platforms_modified_by_platform_flag
@@ -68,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(&:full_name)
+ assert_equal %w[a-1-x86-freebsd-9], set.always_install.map {|s| s.full_name }
end
def test_add_always_install_index_spec_platform
@@ -81,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(&:platform)
+ assert_equal [Gem::Platform.local], set.always_install.map {|s| s.platform }
end
def test_add_always_install_prerelease
@@ -94,7 +94,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1], set.always_install.map(&:full_name)
+ assert_equal %w[a-1], set.always_install.map {|s| s.full_name }
end
def test_add_always_install_prerelease_github_problem
@@ -112,7 +112,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1], set.always_install.map(&:full_name)
+ assert_equal %w[a-1], set.always_install.map {|s| s.full_name }
end
def test_add_always_install_prerelease_only
@@ -143,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(&:full_name)
+ assert_equal %w[a-1], set.find_all(req).map {|spec| spec.full_name }
end
def test_consider_local_eh
@@ -199,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(&:full_name)
+ assert_equal %w[a-2], set.find_all(req).map {|spec| spec.full_name }
end
def test_find_all_prerelease
@@ -212,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(&:full_name)
+ assert_equal %w[a-1], set.find_all(req).map {|spec| spec.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(&:full_name).sort
+ set.find_all(req).map {|spec| spec.full_name }.sort
end
def test_find_all_prerelease_dependencies_with_add_local
@@ -229,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(&:full_name)
+ assert_equal %w[activesupport-7.1.0.alpha], set.find_all(req).map {|spec| spec.full_name }
end
def test_load_spec
diff --git a/test/rubygems/test_gem_resolver_lock_set.rb b/test/rubygems/test_gem_resolver_lock_set.rb
index ebb64ef583..29db065979 100644
--- a/test/rubygems/test_gem_resolver_lock_set.rb
+++ b/test/rubygems/test_gem_resolver_lock_set.rb
@@ -16,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(&:full_name)
+ assert_equal %w[a-2], @set.specs.map {|t| t.full_name }
assert_kind_of Gem::Resolver::LockSpecification, spec
@@ -34,11 +34,11 @@ class TestGemResolverLockSet < Gem::TestCase
found = @set.find_all dep "a"
- assert_equal %w[a-2], found.map(&:full_name)
+ assert_equal %w[a-2], found.map {|s| s.full_name }
found = @set.find_all dep "a", ">= 0.a"
- assert_equal %w[a-1.a a-2], found.map(&:full_name)
+ assert_equal %w[a-1.a a-2], found.map {|s| s.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 402f5d1509..7b5a03459c 100644
--- a/test/rubygems/test_gem_resolver_lock_specification.rb
+++ b/test/rubygems/test_gem_resolver_lock_specification.rb
@@ -8,12 +8,14 @@ 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 = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
assert_equal "a", spec.name
assert_equal v(2), spec.version
@@ -23,7 +25,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
end
def test_add_dependency
- l_spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ l_spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
b_dep = dep("b", ">= 0")
@@ -37,7 +39,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
fetcher.download "a", 2
end
- spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
called = false
@@ -49,7 +51,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
end
def test_install_installed
- spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
FileUtils.touch File.join(@gemhome, "specifications", spec.spec.spec_name)
@@ -65,7 +67,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
def test_spec
version = v(2)
- l_spec = Gem::Resolver::LockSpecification.new @set, "a", version, [@source], Gem::Platform::RUBY
+ l_spec = @LS.new @set, "a", version, [@source], Gem::Platform::RUBY
b_dep = dep "b", ">= 0"
c_dep = dep "c", "~> 1"
@@ -89,7 +91,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
version = v(2)
- l_spec = Gem::Resolver::LockSpecification.new @set, "a", version, [@source], Gem::Platform::RUBY
+ l_spec = @LS.new @set, "a", version, [@source], Gem::Platform::RUBY
assert_same real_spec, l_spec.spec
end
diff --git a/test/rubygems/test_gem_resolver_specification.rb b/test/rubygems/test_gem_resolver_specification.rb
index e2bbce0c0c..db7093e423 100644
--- a/test/rubygems/test_gem_resolver_specification.rb
+++ b/test/rubygems/test_gem_resolver_specification.rb
@@ -25,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_specification.rb b/test/rubygems/test_gem_resolver_vendor_specification.rb
index 3525a6c14c..2e52e4619c 100644
--- a/test/rubygems/test_gem_resolver_vendor_specification.rb
+++ b/test/rubygems/test_gem_resolver_vendor_specification.rb
@@ -28,8 +28,7 @@ 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
deleted file mode 100644
index ebb000a9ef..0000000000
--- a/test/rubygems/test_gem_safe_marshal.rb
+++ /dev/null
@@ -1,404 +0,0 @@
-# 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
deleted file mode 100644
index 02df9f97da..0000000000
--- a/test/rubygems/test_gem_safe_yaml.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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 82449a8626..b5c97e846c 100644
--- a/test/rubygems/test_gem_security.rb
+++ b/test/rubygems/test_gem_security.rb
@@ -19,11 +19,17 @@ 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 = Gem::Security.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5
+ cert = @SEC.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5
assert_kind_of OpenSSL::X509::Certificate, cert
@@ -56,7 +62,7 @@ class TestGemSecurity < Gem::TestCase
def test_class_create_cert_self_signed
subject = PUBLIC_CERT.subject
- cert = Gem::Security.create_cert_self_signed subject, PRIVATE_KEY, 60
+ cert = @SEC.create_cert_self_signed subject, PRIVATE_KEY, 60
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
assert_equal "sha256WithRSAEncryption", cert.signature_algorithm
@@ -67,7 +73,7 @@ class TestGemSecurity < Gem::TestCase
name = PUBLIC_CERT.subject
key = PRIVATE_KEY
- cert = Gem::Security.create_cert_email email, key, 60
+ cert = @SEC.create_cert_email email, key, 60
assert_kind_of OpenSSL::X509::Certificate, cert
@@ -99,20 +105,20 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_create_key
- key = Gem::Security.create_key "rsa"
+ key = @SEC.create_key "rsa"
assert_kind_of OpenSSL::PKey::RSA, key
end
def test_class_create_key_downcases
- key = Gem::Security.create_key "DSA"
+ key = @SEC.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
- Gem::Security.create_key "NOT_RSA"
+ @SEC.create_key "NOT_RSA"
end
assert_equal "NOT_RSA algorithm not found. RSA, DSA, and EC algorithms are supported.",
@@ -122,27 +128,27 @@ class TestGemSecurity < Gem::TestCase
def test_class_get_public_key_rsa
pkey_pem = PRIVATE_KEY.public_key.to_pem
- assert_equal pkey_pem, Gem::Security.get_public_key(PRIVATE_KEY).to_pem
+ assert_equal pkey_pem, @SEC.get_public_key(PRIVATE_KEY).to_pem
end
def test_class_get_public_key_ec
- pkey = Gem::Security.get_public_key(EC_KEY)
+ pkey = @SEC.get_public_key(EC_KEY)
assert_respond_to pkey, :to_pem
end
def test_class_email_to_name
assert_equal "/CN=nobody/DC=example",
- Gem::Security.email_to_name("nobody@example").to_s
+ @SEC.email_to_name("nobody@example").to_s
assert_equal "/CN=nobody/DC=example/DC=com",
- Gem::Security.email_to_name("nobody@example.com").to_s
+ @SEC.email_to_name("nobody@example.com").to_s
assert_equal "/CN=no.body/DC=example",
- Gem::Security.email_to_name("no.body@example").to_s
+ @SEC.email_to_name("no.body@example").to_s
assert_equal "/CN=no_body/DC=example",
- Gem::Security.email_to_name("no+body@example").to_s
+ @SEC.email_to_name("no+body@example").to_s
end
def test_class_re_sign
@@ -166,7 +172,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
@@ -177,16 +183,16 @@ class TestGemSecurity < Gem::TestCase
end
assert_equal "incorrect signing key for re-signing " +
- ALTERNATE_CERT.subject.to_s,
+ "#{ALTERNATE_CERT.subject}",
e.message
end
def test_class_reset
- trust_dir = Gem::Security.trust_dir
+ trust_dir = @SEC.trust_dir
- Gem::Security.reset
+ @SEC.reset
- refute_equal trust_dir, Gem::Security.trust_dir
+ refute_equal trust_dir, @SEC.trust_dir
end
def test_class_sign
@@ -200,7 +206,7 @@ class TestGemSecurity < Gem::TestCase
cert.subject = signee
cert.public_key = key.public_key
- signed = Gem::Security.sign cert, key, PUBLIC_CERT, 60
+ signed = @SEC.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
@@ -235,9 +241,9 @@ class TestGemSecurity < Gem::TestCase
issuer = PUBLIC_CERT.subject
signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example"
- cert = Gem::Security.create_cert_email "signee@example", PRIVATE_KEY
+ cert = @SEC.create_cert_email "signee@example", PRIVATE_KEY
- signed = Gem::Security.sign cert, PRIVATE_KEY, PUBLIC_CERT, 60
+ signed = @SEC.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
@@ -274,7 +280,7 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_trust_dir
- trust_dir = Gem::Security.trust_dir
+ trust_dir = @SEC.trust_dir
expected = File.join Gem.user_home, ".gem/trust"
@@ -282,11 +288,11 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_write
- key = Gem::Security.create_key "rsa"
+ key = @SEC.create_key "rsa"
path = File.join @tempdir, "test-private_key.pem"
- Gem::Security.write key, path
+ @SEC.write key, path
assert_path_exist path
@@ -296,13 +302,13 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_write_encrypted
- key = Gem::Security.create_key "rsa"
+ key = @SEC.create_key "rsa"
path = File.join @tempdir, "test-private_encrypted_key.pem"
passphrase = "It should be long."
- Gem::Security.write key, path, 0o600, passphrase
+ @SEC.write key, path, 0600, passphrase
assert_path_exist path
@@ -312,7 +318,7 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_write_encrypted_cipher
- key = Gem::Security.create_key "rsa"
+ key = @SEC.create_key "rsa"
path = File.join @tempdir, "test-private_encrypted__with_non_default_cipher_key.pem"
@@ -320,7 +326,7 @@ class TestGemSecurity < Gem::TestCase
cipher = OpenSSL::Cipher.new "AES-192-CBC"
- Gem::Security.write key, path, 0o600, passphrase, cipher
+ @SEC.write key, path, 0600, 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 2f4fb1ce28..9217f5a818 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,9 +452,7 @@ 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"]
@@ -477,9 +475,7 @@ 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"
@@ -508,9 +504,7 @@ 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"
@@ -536,6 +530,6 @@ class TestGemSecurityPolicy < Gem::TestCase
digests = { Gem::Security::DIGEST_NAME => { 0 => data } }
signatures = { 0 => sign(data, key) }
- [digests, signatures]
+ return 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 f4799cbd46..a7ec5502d9 100644
--- a/test/rubygems/test_gem_security_signer.rb
+++ b/test/rubygems/test_gem_security_signer.rb
@@ -37,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(&:to_pem),
- signer.cert_chain.map(&:to_pem)
+ assert_equal [PUBLIC_CERT, CHILD_CERT].map {|c| c.to_pem },
+ signer.cert_chain.map {|c| c.to_pem }
end
def test_initialize_cert_chain_invalid
@@ -50,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(&:to_pem),
- signer.cert_chain.map(&:to_pem)
+ assert_equal [PUBLIC_CERT].map {|c| c.to_pem },
+ signer.cert_chain.map {|c| c.to_pem }
end
def test_initialize_default
@@ -66,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(&:to_pem)
+ assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map {|c| c.to_pem }
end
def test_initialize_key_path
@@ -100,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(&:to_pem)
+ signer.cert_chain.map {|c| c.to_pem }
end
def test_load_cert_chain_broken
@@ -112,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(&:to_pem)
+ signer.cert_chain.map {|c| c.to_pem }
end
def test_sign
@@ -144,7 +144,7 @@ B8khkB8hDKC6moCzebmUxCBmTmXD0Wjzon+bf4MOriVE3a0ySGRvpr1mKR2+
def test_sign_expired_auto_update
pend if Gem.java_platform?
- FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), mode: 0o700
+ FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), :mode => 0700
private_key_path = File.join(Gem.user_home, ".gem", "gem-private_key.pem")
Gem::Security.write PRIVATE_KEY, private_key_path
@@ -171,7 +171,7 @@ B8khkB8hDKC6moCzebmUxCBmTmXD0Wjzon+bf4MOriVE3a0ySGRvpr1mKR2+
end
def test_sign_expired_auto_update_exists
- FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), mode: 0o700
+ FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), :mode => 0700
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 cfde8e9d48..b13cf42eeb 100644
--- a/test/rubygems/test_gem_security_trust_dir.rb
+++ b/test/rubygems/test_gem_security_trust_dir.rb
@@ -56,9 +56,9 @@ class TestGemSecurityTrustDir < Gem::TestCase
assert_path_exist trusted
- mask = 0o100600 & (~File.umask)
+ mask = 0100600 & (~File.umask)
- assert_equal mask, File.stat(trusted).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(trusted).mode unless win_platform?
assert_equal PUBLIC_CERT.to_pem, File.read(trusted)
end
@@ -70,10 +70,10 @@ class TestGemSecurityTrustDir < Gem::TestCase
assert_path_exist @dest_dir
- mask = 0o040700 & (~File.umask)
- mask |= 0o200000 if RUBY_PLATFORM.include?("aix")
+ mask = 040700 & (~File.umask)
+ mask |= 0200000 if RUBY_PLATFORM.include?("aix")
- assert_equal mask, File.stat(@dest_dir).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(@dest_dir).mode unless win_platform?
end
def test_verify_file
@@ -87,13 +87,13 @@ class TestGemSecurityTrustDir < Gem::TestCase
end
def test_verify_wrong_permissions
- FileUtils.mkdir_p @dest_dir, mode: 0o777
+ FileUtils.mkdir_p @dest_dir, :mode => 0777
@trust_dir.verify
- mask = 0o40700 & (~File.umask)
- mask |= 0o200000 if RUBY_PLATFORM.include?("aix")
+ mask = 040700 & (~File.umask)
+ mask |= 0200000 if RUBY_PLATFORM.include?("aix")
- assert_equal mask, File.stat(@dest_dir).mode unless Gem.win_platform?
+ assert_equal mask, File.stat(@dest_dir).mode unless 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 001a73eb51..1c46f018fa 100644
--- a/test/rubygems/test_gem_silent_ui.rb
+++ b/test/rubygems/test_gem_silent_ui.rb
@@ -2,6 +2,7 @@
require_relative "helper"
require "rubygems/user_interaction"
+require "timeout"
class TestGemSilentUI < Gem::TestCase
def setup
@@ -115,7 +116,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 4d445f3437..26223d2bbf 100644
--- a/test/rubygems/test_gem_source.rb
+++ b/test/rubygems/test_gem_source.rb
@@ -2,6 +2,7 @@
require_relative "helper"
require "rubygems/source"
+require "rubygems/indexer"
class TestGemSource < Gem::TestCase
def tuple(*args)
@@ -22,7 +23,7 @@ class TestGemSource < Gem::TestCase
end
def test_initialize_invalid_uri
- assert_raise Gem::URI::InvalidURIError do
+ assert_raise URI::InvalidURIError do
Gem::Source.new "git@example:a.git"
end
end
@@ -36,15 +37,15 @@ class TestGemSource < Gem::TestCase
end
def test_cache_dir_escapes_windows_paths
- uri = Gem::URI.parse("file:///C:/WINDOWS/Temp/gem_repo")
+ uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo")
root = Gem.spec_cache_dir
cache_dir = @source.cache_dir(uri).gsub(root, "")
- assert !cache_dir.include?(":"), "#{cache_dir} should not contain a :"
+ assert cache_dir !~ /:/, "#{cache_dir} should not contain a :"
end
def test_dependency_resolver_set_bundler_api
- response = Gem::Net::HTTPResponse.new "1.1", 200, "OK"
- response.uri = Gem::URI("http://example")
+ response = Net::HTTPResponse.new "1.1", 200, "OK"
+ response.uri = URI("http://example")
@fetcher.data[@gem_repo] = response
@@ -54,8 +55,7 @@ class TestGemSource < Gem::TestCase
end
def test_dependency_resolver_set_file_uri
- File.write(File.join(@tempdir, "prerelease_specs.4.8.gz"), Gem::Util.gzip("\x04\x08[\x05".b))
- File.write(File.join(@tempdir, "specs.4.8.gz"), Gem::Util.gzip("\x04\x08[\x05".b))
+ Gem::Indexer.new(@tempdir).generate_index
source = Gem::Source.new "file://#{@tempdir}/"
@@ -78,7 +78,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 Gem::URI.parse(spec_uri)
+ cache_dir = @source.cache_dir URI.parse(spec_uri)
cache_file = File.join cache_dir, a1.spec_name
@@ -91,7 +91,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 Gem::URI.parse(spec_uri)
+ cache_dir = @source.cache_dir URI.parse(spec_uri)
FileUtils.mkdir_p cache_dir
cache_file = File.join cache_dir, a1.spec_name
@@ -105,7 +105,9 @@ class TestGemSource < Gem::TestCase
end
def test_fetch_spec_platform
- specs = spec_fetcher(&:legacy_platform)
+ specs = spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
spec = @source.fetch_spec tuple("pl", Gem::Version.new(1), "i386-linux")
@@ -121,7 +123,7 @@ class TestGemSource < Gem::TestCase
end
def test_load_specs
- released = @source.load_specs(:released).map(&:full_name)
+ released = @source.load_specs(:released).map {|spec| spec.full_name }
assert_equal %W[a-2 a-1 b-2], released
cache_dir = File.join Gem.spec_cache_dir, "gems.example.com%80"
@@ -163,7 +165,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"
@@ -195,7 +197,7 @@ class TestGemSource < Gem::TestCase
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- assert_equal(0, remote.<=>(remote), "remote <=> remote") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, remote.<=>(remote), "remote <=> remote")
assert_equal(-1, remote.<=>(specific), "remote <=> specific")
assert_equal(1, specific.<=>(remote), "specific <=> remote")
@@ -213,12 +215,12 @@ class TestGemSource < Gem::TestCase
end
def test_spaceship_order_is_preserved_when_uri_differs
- source_a = Gem::Source.new "http://example.com/a"
- source_b = Gem::Source.new "http://example.com/b"
+ sourceA = Gem::Source.new "http://example.com/a"
+ sourceB = Gem::Source.new "http://example.com/b"
- 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")
+ assert_equal(0, sourceA.<=>(sourceA), "sourceA <=> sourceA")
+ assert_equal(1, sourceA.<=>(sourceB), "sourceA <=> sourceB")
+ assert_equal(1, sourceB.<=>(sourceA), "sourceB <=> sourceA")
end
def test_update_cache_eh
diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb
index 20e750a0d4..f23d8feba6 100644
--- a/test/rubygems/test_gem_source_git.rb
+++ b/test/rubygems/test_gem_source_git.rb
@@ -9,7 +9,7 @@ class TestGemSourceGit < Gem::TestCase
@name, @version, @repository, @head = git_gem
- @hash = OpenSSL::Digest::SHA1.hexdigest @repository
+ @hash = Digest::SHA1.hexdigest @repository
@source = Gem::Source::Git.new @name, @repository, nil, false
end
@@ -216,7 +216,7 @@ class TestGemSourceGit < Gem::TestCase
installed = Gem::Source::Installed.new
vendor = Gem::Source::Vendor.new "vendor/foo"
- assert_equal(0, git.<=>(git), "git <=> git") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, git.<=>(git), "git <=> git")
assert_equal(1, git.<=>(remote), "git <=> remote")
assert_equal(-1, remote.<=>(git), "remote <=> git")
@@ -252,7 +252,7 @@ class TestGemSourceGit < Gem::TestCase
specs = source.specs
end
- assert_equal %w[a-1 b-1], specs.map(&:full_name)
+ assert_equal %w[a-1 b-1], specs.map {|spec| spec.full_name }
a_spec = specs.shift
@@ -289,7 +289,7 @@ class TestGemSourceGit < Gem::TestCase
end
def test_uri
- assert_equal Gem::URI(@repository), @source.uri
+ assert_equal URI(@repository), @source.uri
end
def test_uri_hash
diff --git a/test/rubygems/test_gem_source_installed.rb b/test/rubygems/test_gem_source_installed.rb
index 0d6171b0e5..4c4c49ad90 100644
--- a/test/rubygems/test_gem_source_installed.rb
+++ b/test/rubygems/test_gem_source_installed.rb
@@ -15,7 +15,7 @@ class TestGemSourceInstalled < Gem::TestCase
git = Gem::Source::Git.new "a", "a", nil
vendor = Gem::Source::Vendor.new "a"
- assert_equal(0, installed.<=>(installed), "installed <=> installed") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, installed.<=>(installed), "installed <=> installed")
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 64353f8f90..fc084830ba 100644
--- a/test/rubygems/test_gem_source_list.rb
+++ b/test/rubygems/test_gem_source_list.rb
@@ -37,7 +37,7 @@ class TestGemSourceList < Gem::TestCase
assert_kind_of Gem::Source, source
- assert_kind_of Gem::URI, source.uri
+ assert_kind_of URI, source.uri
assert_equal source.uri.to_s, @uri
assert_equal [source], sl.sources
@@ -99,7 +99,7 @@ class TestGemSourceList < Gem::TestCase
def test_include_eh
assert @sl.include?(@uri), "string comparison not working"
- assert @sl.include?(Gem::URI.parse(@uri)), "uri comparison not working"
+ assert @sl.include?(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 c15e0e07c0..82db0f5b47 100644
--- a/test/rubygems/test_gem_source_local.rb
+++ b/test/rubygems/test_gem_source_local.rb
@@ -73,7 +73,7 @@ class TestGemSourceLocal < Gem::TestCase
@sl.load_specs :released
- inner = [@a, @ap, @b].map(&:name_tuple).inspect
+ inner = [@a, @ap, @b].map {|t| t.name_tuple }.inspect
assert_equal "#<Gem::Source::Local specs: #{inner}>", @sl.inspect
end
@@ -93,7 +93,7 @@ class TestGemSourceLocal < Gem::TestCase
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- assert_equal(0, local.<=>(local), "local <=> local") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, local.<=>(local), "local <=> local")
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 91ffee68f2..87716d3960 100644
--- a/test/rubygems/test_gem_source_lock.rb
+++ b/test/rubygems/test_gem_source_lock.rb
@@ -40,11 +40,9 @@ 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")
@@ -110,6 +108,6 @@ class TestGemSourceLock < Gem::TestCase
remote = Gem::Source.new @gem_repo
lock = Gem::Source::Lock.new remote
- assert_equal Gem::URI(@gem_repo), lock.uri
+ assert_equal 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 3bc1901ee1..8815017b8a 100644
--- a/test/rubygems/test_gem_source_specific_file.rb
+++ b/test/rubygems/test_gem_source_specific_file.rb
@@ -46,7 +46,7 @@ class TestGemSourceSpecificFile < Gem::TestCase
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- assert_equal(0, specific.<=>(specific), "specific <=> specific") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, specific.<=>(specific), "specific <=> specific")
assert_equal(-1, remote.<=>(specific), "remote <=> specific")
assert_equal(1, specific.<=>(remote), "specific <=> remote")
@@ -70,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") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, a1_source.<=>(a1_source), "a1_source <=> a1_source")
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 a451a81a25..98a3d5b02b 100644
--- a/test/rubygems/test_gem_source_subpath_problem.rb
+++ b/test/rubygems/test_gem_source_subpath_problem.rb
@@ -21,8 +21,8 @@ class TestGemSourceSubpathProblem < Gem::TestCase
end
def test_dependency_resolver_set
- response = Gem::Net::HTTPResponse.new "1.1", 200, "OK"
- response.uri = Gem::URI("http://example")
+ response = Net::HTTPResponse.new "1.1", 200, "OK"
+ response.uri = URI("http://example")
@fetcher.data["#{@gem_repo}/"] = response
@@ -44,7 +44,7 @@ class TestGemSourceSubpathProblem < Gem::TestCase
Gem::NameTuple.new(@b2.name, @b2.version, "ruby"),
]))
- released = @source.load_specs(:latest).map(&:full_name)
+ released = @source.load_specs(:latest).map {|spec| spec.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 2543871439..d55bbe9526 100644
--- a/test/rubygems/test_gem_source_vendor.rb
+++ b/test/rubygems/test_gem_source_vendor.rb
@@ -16,7 +16,7 @@ class TestGemSourceVendor < Gem::TestCase
git = Gem::Source::Git.new "a", "a", nil
installed = Gem::Source::Installed.new
- assert_equal(0, vendor.<=>(vendor), "vendor <=> vendor") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, vendor.<=>(vendor), "vendor <=> vendor")
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 cb4a4f7204..cdbf6e6a0a 100644
--- a/test/rubygems/test_gem_spec_fetcher.rb
+++ b/test/rubygems/test_gem_spec_fetcher.rb
@@ -11,7 +11,7 @@ class TestGemSpecFetcher < Gem::TestCase
def setup
super
- @uri = Gem::URI.parse @gem_repo
+ @uri = URI.parse @gem_repo
@source = Gem::Source.new(@uri)
@sf = Gem::SpecFetcher.new
@@ -41,12 +41,12 @@ class TestGemSpecFetcher < Gem::TestCase
def test_initialize_unwritable_home_dir
pend "chmod not supported" if Gem.win_platform?
- FileUtils.chmod 0o000, Gem.user_home
+ FileUtils.chmod 0000, Gem.user_home
begin
assert Gem::SpecFetcher.new
ensure
- FileUtils.chmod 0o755, Gem.user_home
+ FileUtils.chmod 0755, Gem.user_home
end
end
@@ -109,7 +109,9 @@ class TestGemSpecFetcher < Gem::TestCase
def test_spec_for_dependency_platform
util_set_arch "i386-linux"
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
dep = Gem::Dependency.new "pl", 1
specs_and_sources, _ = @sf.spec_for_dependency dep
@@ -125,7 +127,9 @@ class TestGemSpecFetcher < Gem::TestCase
def test_spec_for_dependency_mismatched_platform
util_set_arch "hrpa-989"
- spec_fetcher(&:legacy_platform)
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
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 d0a1e4bc5f..2f9d520d92 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -56,6 +56,7 @@ end
s.add_dependency "jabber4r", "> 0.0.0"
s.add_dependency "pqa", ["> 0.4", "<= 0.6"]
+ s.mark_version
s.files = %w[lib/code.rb]
end
end
@@ -68,6 +69,7 @@ end
s.license = "MIT"
s.platform = platform
+ s.mark_version
s.files = %w[lib/code.rb]
s.installed_by_version = v("2.2")
end
@@ -88,12 +90,12 @@ 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"
s.license = "MIT"
+ s.mark_version
s.files = %w[lib/code.rb]
end
@@ -690,7 +692,7 @@ end
version
]
- actual_value = Gem::Specification.attribute_names.map(&:to_s).sort
+ actual_value = Gem::Specification.attribute_names.map {|a| a.to_s }.sort
assert_equal expected_value, actual_value
end
@@ -795,6 +797,26 @@ 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{'
@@ -941,13 +963,13 @@ dependencies: []
install_specs @a1
assert_includes Gem::Specification.all_names, "a-1"
- assert_includes Gem::Specification.stubs.map(&:full_name), "a-1"
+ assert_includes Gem::Specification.stubs.map {|s| s.full_name }, "a-1"
uninstall_gem @a1
Gem::Specification.reset
refute_includes Gem::Specification.all_names, "a-1"
- refute_includes Gem::Specification.stubs.map(&:full_name), "a-1"
+ refute_includes Gem::Specification.stubs.map {|s| s.full_name }, "a-1"
end
def test_self_remove_spec_removed
@@ -962,34 +984,31 @@ dependencies: []
Gem::Specification.reset
refute_includes Gem::Specification.all_names, "a-1"
- refute_includes Gem::Specification.stubs.map(&:full_name), "a-1"
+ refute_includes Gem::Specification.stubs.map {|s| s.full_name }, "a-1"
end
def test_self_stubs_for_lazy_loading
Gem.loaded_specs.clear
-
- specification_record = Gem::Specification.specification_record
-
- specification_record.instance_variable_set(:@stubs, nil)
+ Gem::Specification.class_variable_set(:@@stubs, nil)
dir_standard_specs = File.join Gem.dir, "specifications"
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(&:full_name)
- assert_equal 1, specification_record.instance_variable_get(:@stubs_by_name).length
- assert_equal ["b-1"], Gem::Specification.stubs_for("b").map(&:full_name)
- assert_equal 2, specification_record.instance_variable_get(:@stubs_by_name).length
+ assert_equal ["a-1"], Gem::Specification.stubs_for("a").map {|s| s.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 2, Gem::Specification.class_variable_get(:@@stubs_by_name).length
assert_equal(
- Gem::Specification.stubs_for("a").map(&:object_id),
- Gem::Specification.stubs_for("a").map(&:object_id)
+ Gem::Specification.stubs_for("a").map {|s| s.object_id },
+ Gem::Specification.stubs_for("a").map {|s| s.object_id }
)
Gem.loaded_specs.delete "a"
Gem.loaded_specs.delete "b"
- specification_record.instance_variable_set(:@stubs, nil)
+ Gem::Specification.class_variable_set(:@@stubs, nil)
end
def test_self_stubs_for_no_lazy_loading_after_all_specs_setup
@@ -997,7 +1016,7 @@ dependencies: []
save_gemspec("b-1", "1", File.join(Gem.dir, "specifications")) {|s| s.name = "b" }
- assert_equal [], Gem::Specification.stubs_for("b").map(&:full_name)
+ assert_equal [], Gem::Specification.stubs_for("b").map {|s| s.full_name }
end
def test_self_stubs_for_mult_platforms
@@ -1016,7 +1035,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|
@@ -1073,25 +1092,6 @@ dependencies: []
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
spec = Gem::Specification.new do |s|
s.name = "blah"
@@ -1195,13 +1195,10 @@ dependencies: []
assert_same spec.bindir, dup_spec.bindir
assert_equal ">= 0", spec.required_ruby_version.to_s
- assert_equal spec.required_ruby_version, dup_spec.required_ruby_version
- refute_same spec.required_ruby_version, dup_spec.required_ruby_version
+ assert_same spec.required_ruby_version, dup_spec.required_ruby_version
assert_equal ">= 0", spec.required_rubygems_version.to_s
- assert_equal spec.required_rubygems_version,
- dup_spec.required_rubygems_version
- refute_same spec.required_rubygems_version,
+ assert_same spec.required_rubygems_version,
dup_spec.required_rubygems_version
end
@@ -1211,7 +1208,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
@@ -1264,7 +1261,7 @@ dependencies: []
awesome.add_dependency :gem_name
end
- assert_equal %w[true gem_name], gem.dependencies.map(&:name)
+ assert_equal %w[true gem_name], gem.dependencies.map {|dep| dep.name }
end
def test_add_dependency_from_existing_dependency
@@ -1334,7 +1331,9 @@ dependencies: []
assert_empty @ext.build_args
- File.open @ext.build_info_file, "w", &:puts
+ File.open @ext.build_info_file, "w" do |io|
+ io.puts
+ end
assert_empty @ext.build_args
@@ -1454,15 +1453,15 @@ dependencies: []
end
FileUtils.mkdir_p File.join @ext.base_dir, "extensions"
- FileUtils.chmod 0o555, @ext.base_dir
- FileUtils.chmod 0o555, File.join(@ext.base_dir, "extensions")
+ FileUtils.chmod 0555, @ext.base_dir
+ FileUtils.chmod 0555, File.join(@ext.base_dir, "extensions")
@ext.build_extensions
assert_path_not_exist @ext.extension_dir
ensure
- 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
+ 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
end
end
@@ -1487,14 +1486,14 @@ dependencies: []
end
FileUtils.rm_r File.join @gemhome, "extensions"
- FileUtils.chmod 0o555, @gemhome
+ FileUtils.chmod 0555, @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 0o755, @gemhome
+ FileUtils.chmod 0755, @gemhome
end
def test_build_extensions_none
@@ -1549,7 +1548,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
@@ -1565,17 +1564,6 @@ 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
@@ -1613,12 +1601,12 @@ dependencies: []
def test_date_tolerates_hour_sec_zulu
@a1.date = "2012-01-12 11:22:33.4444444 Z"
- assert_equal Time.utc(2012,1,12,0,0,0), @a1.date
+ assert_equal Time.utc(2012,01,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,1,12,0,0,0), @a1.date
+ assert_equal Time.utc(2012,01,12,0,0,0), @a1.date
end
def test_date_use_env_source_date_epoch
@@ -1705,8 +1693,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
@@ -1722,11 +1710,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_method :orig_default_ext_dir_for, :default_ext_dir_for
+ alias orig_default_ext_dir_for default_ext_dir_for
remove_method :default_ext_dir_for
@@ -1748,7 +1736,7 @@ dependencies: []
class << Gem
remove_method :default_ext_dir_for
- alias_method :default_ext_dir_for, :orig_default_ext_dir_for
+ alias default_ext_dir_for orig_default_ext_dir_for
end
end
@@ -1860,7 +1848,7 @@ dependencies: []
end
def test_full_gem_path_double_slash
- gemhome = @gemhome.to_s.sub(%r{\w/}, '\&/')
+ gemhome = @gemhome.to_s.sub(/\w\//, '\&/')
@a1.loaded_from = File.join gemhome, "specifications", @a1.spec_name
expected = File.join @gemhome, "gems", @a1.full_name
@@ -1878,7 +1866,7 @@ dependencies: []
@a1.instance_variable_set :@new_platform, "mswin32"
assert_equal "a-1-mswin32", @a1.full_name, "legacy"
- return if Gem.win_platform?
+ return if win_platform?
@a1 = Gem::Specification.new "a", 1
@a1.platform = "current"
@@ -1992,8 +1980,8 @@ dependencies: []
test_cases = {
"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|
@@ -2020,6 +2008,12 @@ 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
@@ -2201,7 +2195,7 @@ dependencies: []
expected = %w[rake jabber4r pqa]
- assert_equal expected, @c1.runtime_dependencies.map(&:name)
+ assert_equal expected, @c1.runtime_dependencies.map {|d| d.name }
end
def test_spaceship_name
@@ -2209,7 +2203,7 @@ dependencies: []
s2 = util_spec "b", "1"
assert_equal(-1, (s1 <=> s2))
- assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, (s1 <=> s1))
assert_equal(1, (s2 <=> s1))
end
@@ -2220,7 +2214,7 @@ dependencies: []
end
assert_equal(-1, (s1 <=> s2))
- assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, (s1 <=> s1))
assert_equal(1, (s2 <=> s1))
end
@@ -2229,7 +2223,7 @@ dependencies: []
s2 = util_spec "a", "2"
assert_equal(-1, (s1 <=> s2))
- assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(0, (s1 <=> s1))
assert_equal(1, (s2 <=> s1))
end
@@ -2278,7 +2272,7 @@ dependencies: []
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "2".freeze
+ s.version = "2"
s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze, "other".freeze]
@@ -2293,7 +2287,7 @@ Gem::Specification.new do |s|
s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
- s.add_runtime_dependency(%q<b>.freeze, [\"= 1\".freeze])
+ s.add_runtime_dependency(%q<b>.freeze, [\"= 1\"])
end
SPEC
@@ -2318,7 +2312,7 @@ end
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "2".freeze
+ s.version = "2"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
@@ -2351,7 +2345,7 @@ end
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "2".freeze
+ s.version = "2"
s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
@@ -2363,11 +2357,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}".freeze if s.respond_to? :installed_by_version
+ s.installed_by_version = "#{Gem::VERSION}" if s.respond_to? :installed_by_version
s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
- s.add_runtime_dependency(%q<b>.freeze, ["= 1".freeze])
+ s.add_runtime_dependency(%q<b>.freeze, [\"= 1\"])
end
SPEC
@@ -2387,19 +2381,19 @@ end
ruby_code = @c1.to_ruby
local = Gem::Platform.local
- expected_platform = "[#{local.cpu.inspect}.freeze, #{local.os.inspect}.freeze, #{local.version.inspect}.freeze]"
+ expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]"
stub_require_paths =
@c1.instance_variable_get(:@require_paths).join "\u0000"
extensions = @c1.extensions.join "\u0000"
expected = <<-SPEC
# -*- encoding: utf-8 -*-
-# stub: a 1 #{Gem.win_platform? ? "x86-mswin32-60" : "x86-darwin-8"} #{stub_require_paths}
+# stub: a 1 #{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".freeze
+ s.version = "1"
s.platform = Gem::Platform.new(#{expected_platform})
s.required_rubygems_version = Gem::Requirement.new(\">= 0\".freeze) if s.respond_to? :required_rubygems_version=
@@ -2420,9 +2414,9 @@ Gem::Specification.new do |s|
s.specification_version = 4
- 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])
+ 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\"])
end
SPEC
@@ -2438,7 +2432,7 @@ end
s.add_dependency "b", ["~> 1.0", ">= 1.0.0"]
end
- assert_includes spec.to_ruby, '"~> 1.0".freeze, ">= 1.0.0".freeze'
+ assert_includes spec.to_ruby, '"~> 1.0", ">= 1.0.0"'
end
def test_to_ruby_legacy
@@ -2453,13 +2447,13 @@ end
def test_to_ruby_nested_hash
metadata = {}
- metadata[:metadata] = {}
+ metadata[metadata] = metadata
@a2.metadata = metadata
ruby = @a2.to_ruby
- assert_match(/^ s\.metadata = \{ "/, ruby)
+ assert_match %r%^ s\.metadata = \{ "%, ruby
end
def test_to_ruby_platform
@@ -2476,7 +2470,7 @@ end
def test_to_yaml
yaml_str = @a1.to_yaml
- refute_match(/!!null/, yaml_str)
+ refute_match %r{!!null}, yaml_str
same_spec = Gem::Specification.from_yaml(yaml_str)
@@ -2497,7 +2491,7 @@ end
def test_to_yaml_platform_empty_string
@a1.instance_variable_set :@original_platform, ""
- assert_match(/^platform: ruby$/, @a1.to_yaml)
+ assert_match %r{^platform: ruby$}, @a1.to_yaml
end
def test_to_yaml_platform_legacy
@@ -2515,7 +2509,7 @@ end
def test_to_yaml_platform_nil
@a1.instance_variable_set :@original_platform, nil
- assert_match(/^platform: ruby$/, @a1.to_yaml)
+ assert_match %r{^platform: ruby$}, @a1.to_yaml
end
def test_validate
@@ -2526,21 +2520,10 @@ 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
@@ -2624,18 +2607,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
@@ -2659,9 +2642,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
@@ -2688,53 +2671,6 @@ 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
@@ -2778,7 +2714,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
@a1.validate
end
- assert_match(/add rake as a runtime dependency/, @ui.error)
+ assert_match(/add rake as a dependency/, @ui.error)
end
end
@@ -2794,7 +2730,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
@a1.validate
end
- refute_match(/add rake as a runtime dependency/, @ui.error)
+ refute_match(/add rake as a dependency/, @ui.error)
end
end
@@ -2958,7 +2894,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end
def test_validate_empty_require_paths
- if Gem.win_platform?
+ if win_platform?
pend "test_validate_empty_require_paths skipped on MS Windows (symlink)"
else
util_setup_validate
@@ -2974,7 +2910,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 Gem.win_platform?
+ pend "test_validate_files skipped on MS Windows (symlink)" if win_platform?
util_setup_validate
@a1.files += ["lib", "lib2"]
@@ -3003,7 +2939,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
@@ -3030,7 +2966,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") },
@@ -3065,7 +3001,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
@@ -3138,23 +3074,11 @@ Please report a bug if this causes problems.
end
assert_match <<-WARNING, @ui.error
-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: licenses is empty, but is recommended. Use a license identifier from
+http://spdx.org/licenses or 'Nonstandard' for a nonstandard 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
@@ -3167,7 +3091,7 @@ or set it to nil if you don't want to specify a license.
end
def test_removed_methods
- assert_equal Gem::Specification::REMOVED_METHODS, [:rubyforge_project=, :mark_version]
+ assert_equal Gem::Specification::REMOVED_METHODS, [:rubyforge_project=]
end
def test_validate_removed_rubyforge_project
@@ -3190,9 +3114,8 @@ or set it to nil if you don't want to specify a license.
end
assert_match <<-WARNING, @ui.error
-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: license value 'BSD' is invalid. Use a license identifier from
+http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
WARNING
end
@@ -3207,7 +3130,7 @@ or set it to nil if you don't want to specify a license.
assert_empty @ui.error
end
- def test_validate_deprecated_license_values_plus
+ def test_validate_license_values_plus
util_setup_validate
use_ui @ui do
@@ -3215,11 +3138,7 @@ or set it to nil if you don't want to specify a license.
@a1.validate
end
- 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
+ assert_empty @ui.error
end
def test_validate_license_values_or_later
@@ -3237,7 +3156,7 @@ or set it to nil if you don't want to specify a license.
util_setup_validate
use_ui @ui do
- @a1.licenses = ["GPL-2.0-or-later WITH Autoconf-exception-2.0"]
+ @a1.licenses = ["GPL-2.0+ WITH Autoconf-exception-2.0"]
@a1.validate
end
@@ -3253,14 +3172,12 @@ or set it to nil if you don't want to specify a license.
end
assert_match <<-WARNING, @ui.error
-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: license value 'GPL-2.0+ FOO' is invalid. Use a license identifier from
+http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
WARNING
assert_match <<-WARNING, @ui.error
-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: license value 'GPL-2.0 FOO' is invalid. Use a license identifier from
+http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
WARNING
end
@@ -3268,29 +3185,13 @@ or set it to nil if you don't want to specify a license.
util_setup_validate
use_ui @ui do
- @a1.licenses = ["GPL-2.0-only WITH Autocofn-exception-2.0"]
+ @a1.licenses = ["GPL-2.0+ WITH Autocofn-exception-2.0"]
@a1.validate
end
assert_match <<-WARNING, @ui.error
-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: 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
end
@@ -3303,9 +3204,8 @@ or set it to nil if you don't want to specify a license.
end
assert_match <<-WARNING, @ui.error
-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.
+WARNING: license value 'ruby' is invalid. Use a license identifier from
+http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
Did you mean 'Ruby'?
WARNING
end
@@ -3403,7 +3303,7 @@ Did you mean 'Ruby'?
spec.validate
end
- assert_match(/^#{name}/, e.message)
+ assert_match %r{^#{name}}, e.message
end
end
end
@@ -3414,8 +3314,8 @@ Did you mean 'Ruby'?
util_setup_validate
Dir.chdir @tempdir do
- File.chmod 0o640, File.join("lib", "code.rb")
- File.chmod 0o640, File.join("bin", "exec")
+ File.chmod 0640, File.join("lib", "code.rb")
+ File.chmod 0640, File.join("bin", "exec")
use_ui @ui do
@a1.validate
@@ -3460,17 +3360,12 @@ Did you mean 'Ruby'?
util_setup_validate
@a1.rubygems_version = "3"
-
- use_ui @ui do
+ e = assert_raise Gem::InvalidSpecificationException do
@a1.validate
end
- expected = <<~EXPECTED
- #{w}: expected RubyGems version #{Gem::VERSION}, was 3
- #{w}: See https://guides.rubygems.org/specification-reference/ for help
- EXPECTED
-
- assert_equal expected, @ui.error
+ assert_equal "expected RubyGems version #{Gem::VERSION}, was 3",
+ e.message
end
def test_validate_specification_version
@@ -3568,7 +3463,7 @@ Did you mean 'Ruby'?
capture_output do
Gem::Specification.load(specfile.path)
end
- rescue StandardError => e
+ rescue => e
name_rexp = Regexp.new(Regexp.escape(specfile.path))
assert e.backtrace.grep(name_rexp).any?
end
@@ -3711,39 +3606,6 @@ 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]
@@ -3756,7 +3618,7 @@ Did you mean 'Ruby'?
Gem::Specification.new do |s|
s.name = "m".freeze
- s.version = "1".freeze
+ s.version = "1"
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=
@@ -3855,13 +3717,6 @@ 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"
@@ -3954,7 +3809,7 @@ end
FileUtils.touch File.join("lib", "code.rb")
FileUtils.touch File.join("test", "suite.rb")
- File.open "bin/exec", "w", 0o755 do |fp|
+ File.open "bin/exec", "w", 0755 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 b1fcb3bc26..18ac886f20 100644
--- a/test/rubygems/test_gem_stream_ui.rb
+++ b/test/rubygems/test_gem_stream_ui.rb
@@ -2,19 +2,19 @@
require_relative "helper"
require "rubygems/user_interaction"
-require "rubygems/vendored_timeout"
+require "timeout"
class TestGemStreamUI < Gem::TestCase
# 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
+ SHORT_TIMEOUT = (RUBY_ENGINE == "ruby" && !rjit_enabled) ? 0.1 : 1.0
module IsTty
attr_accessor :tty
def tty?
@tty = true unless defined? @tty
- @tty
+ return @tty
end
alias_method :isatty, :tty?
@@ -40,7 +40,7 @@ class TestGemStreamUI < Gem::TestCase
end
def test_ask
- Gem::Timeout.timeout(5) do
+ Timeout.timeout(5) do
expected_answer = "Arthur, King of the Britons"
@in.string = "#{expected_answer}\n"
actual_answer = @sui.ask("What is your name?")
@@ -51,14 +51,14 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_no_tty
@in.tty = false
- Gem::Timeout.timeout(SHORT_TIMEOUT) do
+ Timeout.timeout(SHORT_TIMEOUT) do
answer = @sui.ask("what is your favorite color?")
assert_nil answer
end
end
def test_ask_for_password
- Gem::Timeout.timeout(5) do
+ 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?")
@@ -69,7 +69,7 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_for_password_no_tty
@in.tty = false
- Gem::Timeout.timeout(SHORT_TIMEOUT) do
+ Timeout.timeout(SHORT_TIMEOUT) do
answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?")
assert_nil answer
end
@@ -78,7 +78,7 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_yes_no_no_tty_with_default
@in.tty = false
- Gem::Timeout.timeout(SHORT_TIMEOUT) do
+ Timeout.timeout(SHORT_TIMEOUT) do
answer = @sui.ask_yes_no("do coconuts migrate?", false)
assert_equal false, answer
@@ -90,7 +90,7 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_yes_no_no_tty_without_default
@in.tty = false
- Gem::Timeout.timeout(SHORT_TIMEOUT) do
+ Timeout.timeout(SHORT_TIMEOUT) do
assert_raise(Gem::OperationNotSupportedError) do
@sui.ask_yes_no("do coconuts migrate?")
end
diff --git a/test/rubygems/test_gem_stub_specification.rb b/test/rubygems/test_gem_stub_specification.rb
index fe30a78c0b..c33a87205a 100644
--- a/test/rubygems/test_gem_stub_specification.rb
+++ b/test/rubygems/test_gem_stub_specification.rb
@@ -72,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_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb
index aa5ab0ed67..0b1787d590 100644
--- a/test/rubygems/test_gem_uninstaller.rb
+++ b/test/rubygems/test_gem_uninstaller.rb
@@ -25,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
@@ -59,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"
@@ -74,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"
@@ -89,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
@@ -104,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
@@ -121,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
@@ -137,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
@@ -161,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
@@ -178,7 +178,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
@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"
@@ -188,81 +188,22 @@ class TestGemUninstaller < Gem::InstallerTestCase
refute File.exist?(plugin_path), "plugin not removed"
end
- def test_uninstall_with_install_dir_removes_plugins
+ def test_remove_plugins_with_install_dir
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
io.write "# do nothing"
end
@spec.files += %w[lib/rubygems_plugin.rb]
- package = Gem::Package.build(@spec)
-
- Gem::Installer.at(package, 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"
- install_dir = "#{@gemhome}2"
-
- Gem::Installer.at(package, force: true, install_dir: install_dir).install
-
- install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb"
- assert File.exist?(install_dir_plugin_path), "plugin not written"
-
- Gem::Specification.dirs = [install_dir]
- Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall
+ Dir.mkdir "#{@gemhome}2"
+ Gem::Uninstaller.new(nil, :install_dir => "#{@gemhome}2").remove_plugins @spec
assert File.exist?(plugin_path), "plugin unintentionally removed"
- refute File.exist?(install_dir_plugin_path), "plugin not removed"
- end
-
- def test_uninstall_with_install_dir_regenerates_plugins
- write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "# do nothing"
- end
-
- @spec.files += %w[lib/rubygems_plugin.rb]
-
- install_dir = "#{@gemhome}2"
-
- package = Gem::Package.build(@spec)
-
- spec_v9 = @spec.dup
- spec_v9.version = "9"
- package_v9 = Gem::Package.build(spec_v9)
-
- Gem::Installer.at(package, force: true, install_dir: install_dir).install
- Gem::Installer.at(package_v9, force: true, install_dir: install_dir).install
-
- install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb"
- assert File.exist?(install_dir_plugin_path), "plugin not written"
-
- Gem::Specification.dirs = [install_dir]
- Gem::Uninstaller.new(@spec.name, version: "9", executables: true, install_dir: install_dir).uninstall
- assert File.exist?(install_dir_plugin_path), "plugin unintentionally removed"
-
- Gem::Specification.dirs = [install_dir]
- Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall
- refute File.exist?(install_dir_plugin_path), "plugin not removed"
- end
-
- def test_remove_plugins_user_installed
- write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "# do nothing"
- end
-
- @spec.files += %w[lib/rubygems_plugin.rb]
-
- Gem::Installer.at(Gem::Package.build(@spec), force: true, user_install: true).install
-
- plugin_path = File.join Gem.user_dir, "plugins/a_plugin.rb"
- assert File.exist?(plugin_path), "plugin not written"
-
- Gem::Specification.dirs = [Gem.dir, Gem.user_dir]
-
- Gem::Uninstaller.new(@spec.name, executables: true, force: true, user_install: true).uninstall
-
- refute File.exist?(plugin_path), "plugin not removed"
end
def test_regenerate_plugins_for
@@ -272,7 +213,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
@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"
@@ -306,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 Gem.win_platform?
+ sleep(0.1) if win_platform?
assert File.exist?(gem_dir), "gem_dir should exist"
end
Gem.post_uninstall do
- sleep(0.1) if Gem.win_platform?
+ sleep(0.1) if win_platform?
refute File.exist?(gem_dir), "gem_dir should not exist"
end
@@ -333,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
@@ -353,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
@@ -381,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
@@ -429,11 +370,11 @@ create_makefile '#{@spec.name}'
end
def test_uninstall_user_install
- Gem::Specification.dirs = [Gem.user_dir]
+ @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
@@ -453,37 +394,11 @@ create_makefile '#{@spec.name}'
assert_same uninstaller, @post_uninstall_hook_arg
end
- def test_uninstall_user_install_with_symlinked_home
- pend "Symlinks not supported or not enabled" unless symlink_supported?
-
- Gem::Specification.dirs = [Gem.user_dir]
-
- symlinked_home = File.join(@tempdir, "new-home")
- FileUtils.ln_s(Gem.user_home, symlinked_home)
-
- ENV["HOME"] = symlinked_home
- Gem.instance_variable_set(:@user_home, nil)
- Gem.instance_variable_set(:@data_home, nil)
-
- uninstaller = Gem::Uninstaller.new(@user_spec.name,
- executables: true,
- user_install: true,
- force: true)
-
- gem_dir = File.join @user_spec.gem_dir
-
- assert_path_exist gem_dir
-
- uninstaller.uninstall
-
- assert_path_not_exist gem_dir
- end
-
def test_uninstall_wrong_repo
Dir.mkdir "#{@gemhome}2"
Gem.use_paths "#{@gemhome}2", [@gemhome]
- uninstaller = Gem::Uninstaller.new @spec.name, executables: true
+ uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
e = assert_raise Gem::InstallError do
uninstaller.uninstall
@@ -552,12 +467,12 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match(/You have requested to uninstall the gem:/, lines.shift)
+ assert_match %r{You have requested to uninstall the gem:}, lines.shift
lines.shift
lines.shift
- assert_match(/r-1 depends on q \(= 1\)/, lines.shift)
- assert_match(/Successfully uninstalled q-1/, lines.last)
+ assert_match %r{r-1 depends on q \(= 1\)}, lines.shift
+ assert_match %r{Successfully uninstalled q-1}, lines.last
end
def test_uninstall_only_lists_unsatisfied_deps
@@ -572,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
@@ -582,12 +497,12 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match(/You have requested to uninstall the gem:/, lines.shift)
+ assert_match %r{You have requested to uninstall the gem:}, lines.shift
lines.shift
lines.shift
- assert_match(/x-1 depends on q \(= 1.0\)/, lines.shift)
- assert_match(/Successfully uninstalled q-1.0/, lines.last)
+ assert_match %r{x-1 depends on q \(= 1.0\)}, lines.shift
+ assert_match %r{Successfully uninstalled q-1.0}, lines.last
end
def test_uninstall_doesnt_prompt_when_other_gem_satisfies_requirement
@@ -598,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
@@ -617,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
@@ -636,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
@@ -653,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
@@ -663,12 +578,12 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match(/You have requested to uninstall the gem:/, lines.shift)
+ assert_match %r{You have requested to uninstall the gem:}, lines.shift
lines.shift
lines.shift
- assert_match(/r-1 depends on q \(= 1, development\)/, lines.shift)
- assert_match(/Successfully uninstalled q-1/, lines.last)
+ assert_match %r{r-1 depends on q \(= 1, development\)}, lines.shift
+ assert_match %r{Successfully uninstalled q-1}, lines.last
end
def test_uninstall_prompt_only_lists_the_dependents_that_prevented_uninstallation
@@ -682,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
@@ -692,16 +607,16 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match(/You have requested to uninstall the gem:/, lines.shift)
+ assert_match %r{You have requested to uninstall the gem:}, lines.shift
lines.shift
lines.shift
- assert_match(/s-1 depends on q \(= 1\)/, lines.shift)
- assert_match(/Successfully uninstalled q-1/, lines.last)
+ assert_match %r{s-1 depends on q \(= 1\)}, lines.shift
+ assert_match %r{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
@@ -726,34 +641,34 @@ create_makefile '#{@spec.name}'
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_update_suggestion.rb b/test/rubygems/test_gem_update_suggestion.rb
index 8cb8ee57ff..1d13bfdc84 100644
--- a/test/rubygems/test_gem_update_suggestion.rb
+++ b/test/rubygems/test_gem_update_suggestion.rb
@@ -15,13 +15,13 @@ class TestUpdateSuggestion < Gem::TestCase
@week = 7 * 24 * @minute
end
- def with_eligible_environment(**params)
- self.class.with_eligible_environment(**params) do
+ def with_eglible_environment(**params)
+ self.class.with_eglible_environment(**params) do
yield
end
end
- def self.with_eligible_environment(
+ def self.with_eglible_environment(
tty: true,
rubygems_version: Gem::Version.new("1.2.3"),
latest_rubygems_version: Gem::Version.new("2.0.0"),
@@ -29,18 +29,15 @@ class TestUpdateSuggestion < Gem::TestCase
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
+ 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
+ cmd.stub :ci?, ci do
yield
end
end
@@ -65,145 +62,148 @@ class TestUpdateSuggestion < Gem::TestCase
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
+ def test_eglible_for_update
+ with_eglible_environment(cmd: @cmd) do
+ Time.stub :now, 123456789 do
+ assert @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, 123456789
# test last check is written to config file
- assert_include File.read(Gem.configuration.state_file_name), "123456789"
+ assert File.read(Gem.configuration.state_file_name).match("123456789")
end
end
end
- def test_eligible_for_update_is_not_annoying_when_new_version_is_released
+ def test_eglible_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
+ # checking for first time, it is not eglible since new version
# is not released yet and stored
- with_eligible_environment(cmd: @cmd, rubygems_version: current_version, latest_rubygems_version: latest_version) do
+ with_eglible_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
+ refute @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, @start_time
end
end
- # checking next week, it is not eligible since new version
+ # checking next week, it is not eglible since new version
# is not released yet and timestamp is stored
- with_eligible_environment(
+ with_eglible_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
+ refute @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, @start_time + @week
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
+ # checking later same next week, it is not eglible even new version
# is released and timestamp is not stored
- with_eligible_environment(
+ with_eglible_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
+ refute @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, @start_time + @week
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
+ def test_eglible_for_update_is_not_annoying_when_not_upgraded
+ with_eglible_environment(cmd: @cmd) do
+ # checking for first time, it is eglible and stored
Time.stub :now, @start_time do
- assert_predicate @cmd, :eligible_for_update?
- assert_equal @start_time, Gem.configuration.last_update_check
+ assert @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, @start_time
end
- # checking minute later is not eligible and not stored
+ # checking minute later is not eglible 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
+ refute @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, @start_time
end
- # checking week later is eligible again and stored
+ # checking week later is eglible 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
+ assert @cmd.eglible_for_update?
+ assert_equal Gem.configuration.last_update_check, @start_time + @week
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
+ def test_eglible_for_update_prevent_config
+ with_eglible_environment(cmd: @cmd) do
+ begin
+ original_config, Gem.configuration[:prevent_update_suggestion] = Gem.configuration[:prevent_update_suggestion], true
+ refute @cmd.eglible_for_update?
+ ensure
+ Gem.configuration[:prevent_update_suggestion] = original_config
+ end
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
+ def test_eglible_for_update_prevent_env
+ with_eglible_environment(cmd: @cmd) do
+ begin
+ original_env, ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"], "yes"
+ refute @cmd.eglible_for_update?
+ ensure
+ ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = original_env
+ end
end
end
- def test_eligible_for_update_non_tty
- with_eligible_environment(tty: false, cmd: @cmd) do
- refute_predicate @cmd, :eligible_for_update?
+ def test_eglible_for_update_non_tty
+ with_eglible_environment(tty: false, cmd: @cmd) do
+ refute @cmd.eglible_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?
+ def test_eglible_for_update_for_prerelease
+ with_eglible_environment(rubygems_version: Gem::Version.new("1.0.0-rc1"), cmd: @cmd) do
+ refute @cmd.eglible_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
+ def test_eglible_for_update_disabled_update
+ with_eglible_environment(cmd: @cmd) do
+ begin
+ original_disable, Gem.disable_system_update_message = Gem.disable_system_update_message, "disabled"
+ refute @cmd.eglible_for_update?
+ ensure
+ Gem.disable_system_update_message = original_disable
+ end
end
end
- def test_eligible_for_update_on_ci
- with_eligible_environment(ci: true, cmd: @cmd) do
- refute_predicate @cmd, :eligible_for_update?
+ def test_eglible_for_update_on_ci
+ with_eglible_environment(ci: true, cmd: @cmd) do
+ refute @cmd.eglible_for_update?
end
end
- def test_eligible_for_update_unwrittable_config
- with_eligible_environment(cmd: @cmd) do
+ def test_eglible_for_update_unwrittable_config
+ with_eglible_environment(cmd: @cmd) do
Gem.configuration.stub :state_file_writable?, false do
- refute_predicate @cmd, :eligible_for_update?
+ refute @cmd.eglible_for_update?
end
end
end
- def test_eligible_for_update_notification_delay
- with_eligible_environment(cmd: @cmd) do
+ def test_eglible_for_update_notification_delay
+ with_eglible_environment(cmd: @cmd) do
Gem.configuration.last_update_check = Time.now.to_i
- refute_predicate @cmd, :eligible_for_update?
+ refute @cmd.eglible_for_update?
end
end
end
diff --git a/test/rubygems/test_gem_util.rb b/test/rubygems/test_gem_util.rb
index 608210a903..27bed2d135 100644
--- a/test/rubygems/test_gem_util.rb
+++ b/test/rubygems/test_gem_util.rb
@@ -36,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 Gem.win_platform? || Gem.java_platform?
+ pend "skipped on MS Windows (chmod has no effect)" if win_platform? || 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(0o666, "d/e")
+ FileUtils.chmod(0666, "d/e")
pend "skipped in root privilege" if Process.uid.zero?
@@ -53,7 +53,15 @@ class TestGemUtil < Gem::TestCase
assert_equal File.realpath("../..", @tempdir), paths[3]
ensure
# restore default permissions, allow the directory to be removed
- FileUtils.chmod(0o775, "d/e") unless Gem.win_platform? || Gem.java_platform?
+ 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 }
end
def test_glob_files_in_dir
diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb
index cf771bc5a1..9e8da47c0d 100644
--- a/test/rubygems/test_gem_version.rb
+++ b/test/rubygems/test_gem_version.rb
@@ -269,8 +269,7 @@ class TestGemVersion < Gem::TestCase
# Assert that two versions are eql?. Checks both directions.
def assert_version_eql(first, second)
- first = v(first)
- second = v(second)
+ first, second = v(first), v(second)
assert first.eql?(second), "#{first} is eql? #{second}"
assert second.eql?(first), "#{second} is eql? #{first}"
end
@@ -291,8 +290,7 @@ class TestGemVersion < Gem::TestCase
# directions.
def refute_version_eql(first, second)
- first = v(first)
- second = v(second)
+ first, second = v(first), 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 8b6e14fc42..b837b794db 100644
--- a/test/rubygems/test_gem_version_option.rb
+++ b/test/rubygems/test_gem_version_option.rb
@@ -82,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
@@ -97,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
@@ -112,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
@@ -128,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
@@ -143,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
@@ -154,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 d862b26fe9..2e50127173 100644
--- a/test/rubygems/test_kernel.rb
+++ b/test/rubygems/test_kernel.rb
@@ -43,29 +43,19 @@ class TestGemKernel < Gem::TestCase
def test_gem_redundant
assert gem("a", "= 1"), "Should load"
refute gem("a", "= 1"), "Should not load"
- assert_equal 1, $:.count {|p| p.include?("a-1/lib") }
+ assert_equal 1, $:.select {|p| p.include?("a-1/lib") }.size
end
def test_gem_overlapping
assert gem("a", "= 1"), "Should load"
refute gem("a", ">= 1"), "Should not load"
- assert_equal 1, $:.count {|p| p.include?("a-1/lib") }
+ assert_equal 1, $:.select {|p| p.include?("a-1/lib") }.size
end
- def test_gem_prerelease_is_the_only_available
+ def test_gem_prerelease
quick_gem "d", "1.1.a"
-
- 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") }
+ refute gem("d", ">= 1"), "release requirement must not load prerelease"
+ assert gem("d", ">= 1.a"), "prerelease requirement may load prerelease"
end
def test_gem_env_req
diff --git a/test/rubygems/test_remote_fetch_error.rb b/test/rubygems/test_remote_fetch_error.rb
index 5d9028ede7..7efb98cecb 100644
--- a/test/rubygems/test_remote_fetch_error.rb
+++ b/test/rubygems/test_remote_fetch_error.rb
@@ -5,7 +5,7 @@ require_relative "helper"
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(/secret/, error.to_s)
+ refute_match %r{secret}, error.to_s
end
def test_invalid_url
diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb
index 30a4a477f9..067d2b3f7b 100644
--- a/test/rubygems/test_require.rb
+++ b/test/rubygems/test_require.rb
@@ -92,10 +92,12 @@ class TestGemRequire < Gem::TestCase
def create_sync_thread
Thread.new do
- yield
- ensure
- FILE_ENTERED_LATCH.release
- FILE_EXIT_LATCH.await
+ begin
+ yield
+ ensure
+ FILE_ENTERED_LATCH.release
+ FILE_EXIT_LATCH.await
+ end
end
end
@@ -225,7 +227,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 Gem.java_platform?
+ spaceship_specific_file test before this one" if java_platform?
pend "not installed yet" unless RbConfig::TOPDIR
@@ -382,8 +384,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.to_s))
- FileUtils.rm_rf(File.join(@gemhome, "specifications", "default", "#{b1.full_name}.gemspec"))
+ FileUtils.rm_rf(File.join @gemhome, "#{b1.full_name}")
+ FileUtils.rm_rf(File.join @gemhome, "specifications", "default", "#{b1.full_name}.gemspec")
# Require gems that have not been removed.
assert_require "a/b"
@@ -424,7 +426,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
@@ -471,11 +473,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
@@ -489,17 +491,6 @@ 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")
@@ -540,65 +531,6 @@ 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
@@ -610,10 +542,8 @@ class TestGemRequire < Gem::TestCase
def test_try_activate_error_unlocks_require_monitor
silence_warnings do
class << ::Gem
- alias_method :old_try_activate, :try_activate
- def try_activate(*)
- raise "raised from try_activate"
- end
+ alias old_try_activate try_activate
+ def try_activate(*); raise "raised from try_activate"; end
end
end
@@ -624,7 +554,7 @@ class TestGemRequire < Gem::TestCase
ensure
silence_warnings do
class << ::Gem
- alias_method :try_activate, :old_try_activate
+ alias try_activate old_try_activate
end
end
Kernel::RUBYGEMS_ACTIVATION_MONITOR.exit
diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb
index ec195b65cd..341025c56e 100644
--- a/test/rubygems/test_rubygems.rb
+++ b/test/rubygems/test_rubygems.rb
@@ -4,7 +4,7 @@ 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
@@ -15,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_match(/undefined local variable or method [`']intentionally_not_implemented_method'/, output)
+ assert_includes output, "undefined local variable or method `intentionally_not_implemented_method'"
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 " \
@@ -42,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
@@ -71,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
index 08edabceb2..5e91064b49 100644
--- a/test/rubygems/test_webauthn_listener.rb
+++ b/test/rubygems/test_webauthn_listener.rb
@@ -19,7 +19,7 @@ class WebauthnListenerTest < Gem::TestCase
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")
+ Gem::MockBrowser.get URI("http://localhost:#{@port}?code=xyz")
thread.join
assert_equal "xyz", thread[:otp]
@@ -27,7 +27,7 @@ class WebauthnListenerTest < Gem::TestCase
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")
+ Gem::MockBrowser.post URI("http://localhost:#{@port}?code=xyz")
thread.join
assert_equal "Security device verification failed: Invalid HTTP method POST received.", thread[:error].message
@@ -35,15 +35,15 @@ class WebauthnListenerTest < Gem::TestCase
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
+ assert Gem::MockBrowser.options(URI("http://localhost:#{@port}?code=xyz")).is_a? Net::HTTPNoContent
+ assert Gem::MockBrowser.get(URI("http://localhost:#{@port}?code=xyz")).is_a? 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")
+ response = Gem::MockBrowser.options URI("http://localhost:#{@port}?code=xyz")
- assert response.is_a? Gem::Net::HTTPNoContent
+ assert response.is_a? 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"]
@@ -52,9 +52,9 @@ class WebauthnListenerTest < Gem::TestCase
def test_wait_for_otp_code_get_request
wait_for_otp_code
- response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?code=xyz")
+ response = Gem::MockBrowser.get URI("http://localhost:#{@port}?code=xyz")
- assert response.is_a? Gem::Net::HTTPOK
+ assert response.is_a? 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"]
@@ -69,10 +69,10 @@ class WebauthnListenerTest < Gem::TestCase
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")
+ response = Gem::MockBrowser.post URI("http://localhost:#{@port}?code=xyz")
assert response
- assert response.is_a? Gem::Net::HTTPMethodNotAllowed
+ assert response.is_a? Net::HTTPMethodNotAllowed
assert_equal "GET, OPTIONS", response["allow"]
assert_equal "close", response["Connection"]
@@ -82,9 +82,9 @@ class WebauthnListenerTest < Gem::TestCase
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")
+ response = Gem::MockBrowser.post URI("http://localhost:#{@port}/path?code=xyz")
- assert response.is_a? Gem::Net::HTTPNotFound
+ assert response.is_a? Net::HTTPNotFound
assert_equal "close", response["Connection"]
@thread.join
@@ -93,9 +93,9 @@ class WebauthnListenerTest < Gem::TestCase
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}")
+ response = Gem::MockBrowser.get URI("http://localhost:#{@port}")
- assert response.is_a? Gem::Net::HTTPBadRequest
+ assert response.is_a? Net::HTTPBadRequest
assert_equal "text/plain; charset=utf-8", response["Content-Type"]
assert_equal "22", response["Content-Length"]
assert_equal "close", response["Connection"]
@@ -107,9 +107,9 @@ class WebauthnListenerTest < Gem::TestCase
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")
+ response = Gem::MockBrowser.get URI("http://localhost:#{@port}?param=xyz")
- assert response.is_a? Gem::Net::HTTPBadRequest
+ assert response.is_a? Net::HTTPBadRequest
assert_equal "text/plain; charset=utf-8", response["Content-Type"]
assert_equal "22", response["Content-Length"]
assert_equal "close", response["Connection"]
diff --git a/test/rubygems/test_webauthn_poller.rb b/test/rubygems/test_webauthn_poller.rb
index fd24081758..23c24faa11 100644
--- a/test/rubygems/test_webauthn_poller.rb
+++ b/test/rubygems/test_webauthn_poller.rb
@@ -13,7 +13,7 @@ class WebauthnPollerTest < Gem::TestCase
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
@credentials = {
- identifier: "email@example.com",
+ email: "email@example.com",
password: "password",
}
end
@@ -45,8 +45,8 @@ class WebauthnPollerTest < Gem::TestCase
end
def test_poll_thread_timeout_error
- raise_error = ->(*_args) { raise Gem::Timeout::Error, "execution expired" }
- Gem::Timeout.stub(:timeout, raise_error) do
+ raise_error = ->(*_args) { raise Timeout::Error, "execution expired" }
+ 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"
@@ -72,8 +72,8 @@ class WebauthnPollerTest < Gem::TestCase
msg: "OK"
)
- assert_raise Gem::Timeout::Error do
- Gem::Timeout.timeout(0.1) do
+ assert_raise Timeout::Error do
+ Timeout.timeout(0.1) do
Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
end
end
@@ -121,14 +121,4 @@ class WebauthnPollerTest < Gem::TestCase
assert_equal error.message,
"Security device verification failed: The token in the link you used has either expired or been used already."
end
-
- def test_poll_for_otp_missing_credentials
- @credentials = { password: "password" }
-
- error = assert_raise Gem::WebauthnVerificationError do
- Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
- end
-
- assert_equal error.message, "Security device verification failed: Provided missing credentials"
- end
end
diff --git a/test/rubygems/utilities.rb b/test/rubygems/utilities.rb
index 357379f88d..1eee708e5b 100644
--- a/test/rubygems/utilities.rb
+++ b/test/rubygems/utilities.rb
@@ -40,22 +40,22 @@ class Gem::FakeFetcher
end
def find_data(path)
- return Gem.read_binary path.path if Gem::URI === path && path.scheme == "file"
+ return Gem.read_binary path.path if URI === path && "file" == path.scheme
- if Gem::URI === path && "Gem::URI::#{path.scheme.upcase}" != path.class.name
+ if URI === path && "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 Gem::URI" unless path.start_with?("https://", "http://")
+ raise ArgumentError, "need full 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].is_a?(Array)
+ if @data[path].kind_of?(Array)
@data[path].shift
else
@data[path]
@@ -65,7 +65,7 @@ class Gem::FakeFetcher
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)
+ raise TypeError, "#{response.class} is not a type of Net::HTTPResponse" unless response.kind_of?(Net::HTTPResponse)
response
end
@@ -120,7 +120,7 @@ class Gem::FakeFetcher
path = path.to_s
@paths << path
- raise ArgumentError, "need full URI" unless %r{^http://}.match?(path)
+ raise ArgumentError, "need full URI" unless path =~ %r{^http://}
unless @data.key? path
raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
@@ -141,7 +141,7 @@ class Gem::FakeFetcher
path = File.join path, name
- if /^http/.match?(source_uri)
+ if source_uri =~ /^http/
File.open(path, "wb") do |f|
f.write fetch_path(File.join(source_uri, "gems", name))
end
@@ -164,7 +164,7 @@ class Gem::FakeFetcher
end
##
-# The HTTPResponseFactory allows easy creation of Gem::Net::HTTPResponse instances in RubyGems tests:
+# The HTTPResponseFactory allows easy creation of Net::HTTPResponse instances in RubyGems tests:
#
# Example:
#
@@ -178,7 +178,7 @@ end
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 = 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 }
@@ -194,30 +194,30 @@ end
# Example:
#
# # Sends a get request to http://localhost:5678
-# Gem::MockBrowser.get Gem::URI("http://localhost:5678")
+# Gem::MockBrowser.get 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|
+ options = Net::HTTP::Options.new(uri)
+ 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|
+ get = Net::HTTP::Get.new(uri)
+ 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|
+ post = Net::HTTP::Post.new(uri, headers)
+ Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(post)
end
end
@@ -366,14 +366,13 @@ class Gem::TestCase::SpecFetcherSetup
Gem::Specification.reset
begin
- gem_repo = @test.gem_repo
- @test.gem_repo = @repository
- @test.uri = Gem::URI @repository
+ gem_repo, @test.gem_repo = @test.gem_repo, @repository
+ @test.uri = URI @repository
@test.util_setup_spec_fetcher(*@downloaded)
ensure
@test.gem_repo = gem_repo
- @test.uri = Gem::URI gem_repo
+ @test.uri = URI gem_repo
end
@gems.each do |spec, gem|
diff --git a/test/runner.rb b/test/runner.rb
index c34517cbf2..2f3267f6c3 100644
--- a/test/runner.rb
+++ b/test/runner.rb
@@ -1,5 +1,16 @@
# frozen_string_literal: true
-# NOTE: Do not add any settings here for test-all. Instead, please add it to ../tool/test/init.rb.
+# Should be done in rubygems test files?
+ENV["GEM_SKIP"] = "".freeze
+ENV.delete("RUBY_CODESIGN")
+
+Warning[:experimental] = false
+
+gem_path = [
+ File.realdirpath(".bundle"),
+ File.realdirpath("../.bundle", __dir__),
+]
+ENV["GEM_PATH"] = gem_path.join(File::PATH_SEPARATOR)
+ENV["GEM_HOME"] = gem_path.first
require_relative '../tool/test/runner'
diff --git a/test/set/test_set.rb b/test/set/test_set.rb
deleted file mode 100644
index 49dc58ef7b..0000000000
--- a/test/set/test_set.rb
+++ /dev/null
@@ -1,892 +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)
-
- 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/socket/test_addrinfo.rb b/test/socket/test_addrinfo.rb
index c61764d76d..832a1f8d05 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(Socket::ResolutionError, /getaddrinfo/) do
+ e = assert_raise_with_message(SocketError, /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(Socket::ResolutionError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
+ assert_raise(SocketError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
end
def random_port
diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb
index 598a05d123..e3ce2b920e 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(Socket::ResolutionError) { Socket.getaddrinfo("www.kame.net", 80, "AF_UNIX") }
+ assert_raise(SocketError) { 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(Socket::ResolutionError, '[ruby-core:29427]'){ Socket.getaddrinfo(nil, nil, 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_nothing_raised('[ruby-core:29427]'){ TCPServer.open('localhost', 0) {} }
end
def test_getnameinfo
- assert_raise(Socket::ResolutionError) { Socket.getnameinfo(["AF_UNIX", 80, "0.0.0.0"]) }
+ assert_raise(SocketError) { 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,10 +340,6 @@ 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
@@ -447,12 +443,13 @@ class TestSocket < Test::Unit::TestCase
omit "UDP server is no response: #{$!}"
ensure
if th
- unless skipped
+ if skipped
+ Thread.kill th unless th.join(10)
+ else
Addrinfo.udp("127.0.0.1", port).connect {|s| s.sendmsg "exit" }
- end
- unless th.join(10)
- th.kill.join(10)
- unless skipped
+ unless th.join(10)
+ Thread.kill th
+ th.join(10)
raise "thread killed"
end
end
@@ -489,14 +486,13 @@ class TestSocket < Test::Unit::TestCase
end while IO.select([r], nil, nil, 0.1).nil?
n
end
- timeout = (defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? ? 120 : 30) # for --jit-wait
+ timeout = (defined?(RubyVM::MJIT) && RubyVM::MJIT.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")
@@ -505,10 +501,6 @@ 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
@@ -770,12 +762,4 @@ 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
-
end if defined?(Socket)
diff --git a/test/socket/test_tcp.rb b/test/socket/test_tcp.rb
index 7f9dc53cae..83ebea1b7a 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(IO::TimeoutError, Errno::ENETUNREACH) do
+ assert_raise(IO::TimeoutError) 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 3e7d85befc..e206339db0 100644
--- a/test/socket/test_unix.rb
+++ b/test/socket/test_unix.rb
@@ -152,7 +152,7 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
lock = Thread::Mutex.new
nr = 0
x = 2
- y = 400
+ y = 1000
begin
s1.send_io(nil)
rescue NotImplementedError
@@ -420,10 +420,9 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
s1.recv_nonblock(10)
fail
rescue => e
- assert_kind_of(IO::EWOULDBLOCKWaitReadable, e)
- assert_kind_of(IO::WaitReadable, e)
+ assert(IO::EAGAINWaitReadable === e)
+ assert(IO::WaitReadable === e)
end
-
s2.send("", 0)
s2.send("haha", 0)
s2.send("", 0)
@@ -447,67 +446,6 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
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")
diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb
index 216b06d3ad..fd9974caeb 100644
--- a/test/stringio/test_stringio.rb
+++ b/test/stringio/test_stringio.rb
@@ -14,10 +14,6 @@ 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')
@@ -88,14 +84,6 @@ 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))
@@ -741,32 +729,6 @@ 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)
diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb
index 29626b159f..2fce4c3e74 100644
--- a/test/strscan/test_stringscanner.rb
+++ b/test/strscan/test_stringscanner.rb
@@ -737,8 +737,8 @@ module StringScannerTests
def test_captures
s = create_string_scanner("Timestamp: Fri Dec 12 1975 14:39")
s.scan("Timestamp: ")
- s.scan(/(\w+) (\w+) (\d+) (1980)?/)
- assert_equal(["Fri", "Dec", "12", nil], s.captures)
+ s.scan(/(\w+) (\w+) (\d+) /)
+ assert_equal(["Fri", "Dec", "12"], s.captures)
s.scan(/(\w+) (\w+) (\d+) /)
assert_nil(s.captures)
end
diff --git a/test/test_extlibs.rb b/test/test_extlibs.rb
index 38070f227a..1d7f616424 100644
--- a/test/test_extlibs.rb
+++ b/test/test_extlibs.rb
@@ -65,7 +65,9 @@ class TestExtLibs < Test::Unit::TestCase
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"
diff --git a/test/test_ipaddr.rb b/test/test_ipaddr.rb
index 90a7fc352a..c07ee2a8ee 100644
--- a/test/test_ipaddr.rb
+++ b/test/test_ipaddr.rb
@@ -426,26 +426,6 @@ 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?
diff --git a/test/test_mutex_m.rb b/test/test_mutex_m.rb
index f938e71729..e5cfbc8b5f 100644
--- a/test/test_mutex_m.rb
+++ b/test/test_mutex_m.rb
@@ -55,25 +55,4 @@ class TestMutexM < Test::Unit::TestCase
def test_initialize_no_args
assert NoArgInitializeChild.new
end
-
- def test_alias_extended_object
- object = Object.new
- object.extend(Mutex_m)
-
- assert object.respond_to?(:locked?)
- assert object.respond_to?(:lock)
- assert object.respond_to?(:unlock)
- assert object.respond_to?(:try_lock)
- assert object.respond_to?(:synchronize)
- end
-
- def test_alias_included_class
- object = NoArgInitializeChild.new
-
- assert object.respond_to?(:locked?)
- assert object.respond_to?(:lock)
- assert object.respond_to?(:unlock)
- assert object.respond_to?(:try_lock)
- assert object.respond_to?(:synchronize)
- end
end
diff --git a/test/test_open3.rb b/test/test_open3.rb
index 19277c8a66..a06697a37b 100644
--- a/test/test_open3.rb
+++ b/test/test_open3.rb
@@ -3,6 +3,10 @@
require 'test/unit'
require 'open3'
+if RUBY_ENGINE == 'ruby'
+ require_relative 'lib/jit_support'
+end
+
class TestOpen3 < Test::Unit::TestCase
RUBY = EnvUtil.rubybin
@@ -126,7 +130,11 @@ class TestOpen3 < Test::Unit::TestCase
i.close
STDERR.reopen(old)
assert_equal("zo", o.read)
- assert_equal("ze", r.read)
+ if defined?(JITSupport)
+ assert_equal("ze", JITSupport.remove_mjit_logs(r.read))
+ else
+ assert_equal("ze", r.read)
+ end
}
}
}
diff --git a/test/test_pp.rb b/test/test_pp.rb
index bb2299a3fa..4fcb8df4b0 100644
--- a/test/test_pp.rb
+++ b/test/test_pp.rb
@@ -5,6 +5,15 @@ 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
@@ -164,12 +173,11 @@ class PPCycleTest < Test::Unit::TestCase
end
def test_withinspect
- omit if RUBY_ENGINE == "jruby"
a = []
a << HasInspect.new(a)
assert_equal("[<inspect:[...]>]\n", PP.pp(a, ''.dup))
assert_equal("#{a.inspect}\n", PP.pp(a, ''.dup))
- end
+ end unless RUBY_VERSION < "2.7" # temporary mask to test on JRuby 9.3 (2.6 equivalent)
def test_share_nil
begin
@@ -189,7 +197,6 @@ 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
diff --git a/test/test_set.rb b/test/test_set.rb
new file mode 100644
index 0000000000..164dc460a7
--- /dev/null
+++ b/test/test_set.rb
@@ -0,0 +1,879 @@
+# 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 e474a0ccc5..b3c48bb5f5 100644
--- a/test/test_singleton.rb
+++ b/test/test_singleton.rb
@@ -94,23 +94,6 @@ 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
@@ -118,8 +101,4 @@ 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/set/test_sorted_set.rb b/test/test_sorted_set.rb
index f7ad7af299..f7ad7af299 100644
--- a/test/set/test_sorted_set.rb
+++ b/test/test_sorted_set.rb
diff --git a/test/test_tempfile.rb b/test/test_tempfile.rb
index eddbac5d75..6b087f9207 100644
--- a/test/test_tempfile.rb
+++ b/test/test_tempfile.rb
@@ -63,22 +63,6 @@ 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
@@ -225,7 +209,8 @@ puts Tempfile.new('foo').path
def test_tempfile_finalizer_does_not_run_if_unlinked
bug8768 = '[ruby-core:56521] [Bug #8768]'
- assert_in_out_err(%w(-rtempfile), <<-'EOS') do |(filename), (error)|
+ args = %w(--disable-gems -rtempfile)
+ assert_in_out_err(args, <<-'EOS') do |(filename), (error)|
tmp = Tempfile.new('foo')
puts tmp.path
tmp.close
@@ -378,14 +363,6 @@ 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_timeout.rb b/test/test_timeout.rb
index e900b10cd7..2d3dd16245 100644
--- a/test/test_timeout.rb
+++ b/test/test_timeout.rb
@@ -4,33 +4,12 @@ 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
@@ -62,87 +41,25 @@ 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_standarderror
+ def test_skip_rescue
+ bug8730 = '[Bug #8730]'
e = nil
- assert_raise_with_message(Timeout::Error, /execution expired/) do
+ assert_raise_with_message(Timeout::Error, /execution expired/, bug8730) do
Timeout.timeout 0.01 do
begin
sleep 3
- rescue => e
+ rescue Exception => e
flunk "should not see any exception but saw #{e.inspect}"
end
end
end
- 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
+ assert_nil(e, bug8730)
end
def test_rescue_exit
@@ -210,11 +127,11 @@ class TestTimeout < Test::Unit::TestCase
bug11344 = '[ruby-dev:49179] [Bug #11344]'
ok = false
assert_raise(Timeout::Error) {
- Thread.handle_interrupt(Timeout::ExitException => :never) {
+ Thread.handle_interrupt(Timeout::Error => :never) {
Timeout.timeout(0.01) {
sleep 0.2
ok = true
- Thread.handle_interrupt(Timeout::ExitException => :on_blocking) {
+ Thread.handle_interrupt(Timeout::Error => :on_blocking) {
sleep 0.2
}
}
@@ -255,17 +172,4 @@ class TestTimeout < Test::Unit::TestCase
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 054ca15d7a..eada416f6f 100644
--- a/test/test_tmpdir.rb
+++ b/test/test_tmpdir.rb
@@ -115,20 +115,4 @@ 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 878d79e628..763f493899 100644
--- a/test/test_trick.rb
+++ b/test/test_trick.rb
@@ -1,7 +1,6 @@
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.
@@ -213,61 +212,3 @@ class TestTRICK2022 < Test::Unit::TestCase
assert_in_out_err(["-W0", "-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 8789ed92d2..034d71d808 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 = File.readlines(expand_filename('NormalizationTest'), encoding: 'utf-8')
+ lines = IO.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 1df19e6968..245b3d8cc3 100644
--- a/test/uri/test_common.rb
+++ b/test/uri/test_common.rb
@@ -3,7 +3,10 @@ require 'test/unit'
require 'envutil'
require 'uri'
-class URI::TestCommon < Test::Unit::TestCase
+module URI
+
+
+class TestCommon < Test::Unit::TestCase
def setup
end
@@ -113,7 +116,7 @@ class URI::TestCommon < Test::Unit::TestCase
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_linear_performance((1..10).map {|i| i * 100}, pre: pre) do |uri|
assert_raise(URI::InvalidURIError) do
URI.parse(uri)
end
@@ -289,3 +292,6 @@ class URI::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 f45bb0667c..0eec984db8 100644
--- a/test/uri/test_ftp.rb
+++ b/test/uri/test_ftp.rb
@@ -2,7 +2,10 @@
require 'test/unit'
require 'uri/ftp'
-class URI::TestFTP < Test::Unit::TestCase
+module URI
+
+
+class TestFTP < Test::Unit::TestCase
def setup
end
@@ -26,7 +29,7 @@ class URI::TestFTP < Test::Unit::TestCase
end
def test_parse_invalid
- assert_raise(URI::InvalidURIError) {URI.parse('ftp:example')}
+ assert_raise(InvalidURIError){URI.parse('ftp:example')}
end
def test_paths
@@ -59,3 +62,6 @@ class URI::TestFTP < Test::Unit::TestCase
end
end
end
+
+
+end
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index e6619373c6..4b5e12c0ef 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -164,6 +164,17 @@ class URI::TestGeneric < Test::Unit::TestCase
# must be empty string to identify as path-abempty, not path-absolute
assert_equal('', url.host)
assert_equal('http:////example.com', url.to_s)
+
+ # sec-2957667
+ url = URI.parse('http://user:pass@example.com').merge('//example.net')
+ assert_equal('http://example.net', url.to_s)
+ assert_nil(url.userinfo)
+ url = URI.join('http://user:pass@example.com', '//example.net')
+ assert_equal('http://example.net', url.to_s)
+ assert_nil(url.userinfo)
+ url = URI.parse('http://user:pass@example.com') + '//example.net'
+ assert_equal('http://example.net', url.to_s)
+ assert_nil(url.userinfo)
end
def test_parse_scheme_with_symbols
@@ -256,6 +267,13 @@ class URI::TestGeneric < Test::Unit::TestCase
assert_equal(u0, u1)
end
+ def test_merge_authority
+ u = URI.parse('http://user:pass@example.com:8080')
+ u0 = URI.parse('http://new.example.org/path')
+ u1 = u.merge('//new.example.org/path')
+ assert_equal(u0, u1)
+ end
+
def test_route
url = URI.parse('http://hoge/a.html').route_to('http://hoge/b.html')
assert_equal('b.html', url.to_s)
@@ -977,10 +995,6 @@ 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 e937b1a26b..748e90a322 100644
--- a/test/uri/test_http.rb
+++ b/test/uri/test_http.rb
@@ -3,7 +3,10 @@ require 'test/unit'
require 'uri/http'
require 'uri/https'
-class URI::TestHTTP < Test::Unit::TestCase
+module URI
+
+
+class TestHTTP < Test::Unit::TestCase
def setup
end
@@ -79,3 +82,6 @@ class URI::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 9c4506a357..2625b24103 100644
--- a/test/uri/test_ldap.rb
+++ b/test/uri/test_ldap.rb
@@ -2,7 +2,10 @@
require 'test/unit'
require 'uri/ldap'
-class URI::TestLDAP < Test::Unit::TestCase
+module URI
+
+
+class TestLDAP < Test::Unit::TestCase
def setup
end
@@ -97,3 +100,6 @@ class URI::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 75c02fe65b..cee0acb4b5 100644
--- a/test/uri/test_parser.rb
+++ b/test/uri/test_parser.rb
@@ -78,14 +78,6 @@ class URI::TestParser < Test::Unit::TestCase
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
diff --git a/test/uri/test_ws.rb b/test/uri/test_ws.rb
index f3918f617c..17acb0d9f2 100644
--- a/test/uri/test_ws.rb
+++ b/test/uri/test_ws.rb
@@ -3,7 +3,10 @@ require 'test/unit'
require 'uri/http'
require 'uri/ws'
-class URI::TestWS < Test::Unit::TestCase
+module URI
+
+
+class TestWS < Test::Unit::TestCase
def setup
end
@@ -63,3 +66,6 @@ class URI::TestWS < Test::Unit::TestCase
end
end
end
+
+
+end
diff --git a/test/uri/test_wss.rb b/test/uri/test_wss.rb
index 13a2583059..2e8b9bc4b7 100644
--- a/test/uri/test_wss.rb
+++ b/test/uri/test_wss.rb
@@ -3,7 +3,10 @@ require 'test/unit'
require 'uri/https'
require 'uri/wss'
-class URI::TestWSS < Test::Unit::TestCase
+module URI
+
+
+class TestWSS < Test::Unit::TestCase
def setup
end
@@ -63,3 +66,6 @@ class URI::TestWSS < Test::Unit::TestCase
end
end
end
+
+
+end
diff --git a/test/win32ole/test_win32ole.rb b/test/win32ole/test_win32ole.rb
index 594830b8fa..e5f9d35e24 100644
--- a/test/win32ole/test_win32ole.rb
+++ b/test/win32ole/test_win32ole.rb
@@ -335,8 +335,6 @@ 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
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 502ccceec5..f57b7f2730 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -506,7 +506,6 @@ if defined? Zlib
end
def test_multithread_deflate
- pend 'hangs' if RUBY_ENGINE == 'truffleruby'
zd = Zlib::Deflate.new
s = "x" * 10000
@@ -523,7 +522,6 @@ if defined? Zlib
end
def test_multithread_inflate
- pend 'hangs' if RUBY_ENGINE == 'truffleruby'
zi = Zlib::Inflate.new
s = Zlib.deflate("x" * 10000)
@@ -794,7 +792,7 @@ if defined? Zlib
}
end
- if defined?(File::TMPFILE) and RUBY_ENGINE != 'truffleruby'
+ if defined? File::TMPFILE
def test_path_tmpfile
sio = StringIO.new("".dup, 'w')
gz = Zlib::GzipWriter.new(sio)
@@ -806,16 +804,10 @@ if defined? Zlib
io.rewind
gz0 = Zlib::GzipWriter.new(io)
- gz1 = Zlib::GzipReader.new(io)
-
- 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
+ assert_nil gz0.path
+ gz1 = Zlib::GzipReader.new(io)
+ assert_nil gz1.path
gz0.close
gz1.close
end
@@ -1205,38 +1197,6 @@ 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
@@ -1491,13 +1451,6 @@ 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")
diff --git a/thread.c b/thread.c
index abd91e1e2e..7c5183da56 100644
--- a/thread.c
+++ b/thread.c
@@ -73,12 +73,12 @@
#define TH_SCHED(th) (&(th)->ractor->threads.sched)
#include "eval_intern.h"
+#include "gc.h"
#include "hrtime.h"
#include "internal.h"
#include "internal/class.h"
#include "internal/cont.h"
#include "internal/error.h"
-#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/io.h"
#include "internal/object.h"
@@ -89,7 +89,7 @@
#include "internal/time.h"
#include "internal/warnings.h"
#include "iseq.h"
-#include "rjit.h"
+#include "mjit.h"
#include "ruby/debug.h"
#include "ruby/io.h"
#include "ruby/thread.h"
@@ -100,7 +100,7 @@
#include "vm_debug.h"
#include "vm_sync.h"
-#if USE_RJIT && defined(HAVE_SYS_WAIT_H)
+#if USE_MJIT && defined(HAVE_SYS_WAIT_H)
#include <sys/wait.h>
#endif
@@ -116,6 +116,11 @@ static VALUE sym_immediate;
static VALUE sym_on_blocking;
static VALUE sym_never;
+enum SLEEP_FLAGS {
+ SLEEP_DEADLOCKABLE = 0x1,
+ SLEEP_SPURIOUS_CHECK = 0x2
+};
+
#define THREAD_LOCAL_STORAGE_INITIALISED FL_USER13
#define THREAD_LOCAL_STORAGE_INITIALISED_P(th) RB_FL_TEST_RAW((th), THREAD_LOCAL_STORAGE_INITIALISED)
@@ -129,16 +134,8 @@ rb_thread_local_storage(VALUE thread)
return rb_ivar_get(thread, idLocals);
}
-enum SLEEP_FLAGS {
- SLEEP_DEADLOCKABLE = 0x01,
- SLEEP_SPURIOUS_CHECK = 0x02,
- SLEEP_ALLOW_SPURIOUS = 0x04,
- SLEEP_NO_CHECKINTS = 0x08,
-};
-
-static void sleep_forever(rb_thread_t *th, unsigned int fl);
static int sleep_hrtime(rb_thread_t *, rb_hrtime_t, unsigned int fl);
-
+static void sleep_forever(rb_thread_t *th, unsigned int fl);
static void rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker, VALUE timeout, rb_hrtime_t end);
static int rb_threadptr_dead(rb_thread_t *th);
static void rb_check_deadlock(rb_ractor_t *r);
@@ -146,16 +143,18 @@ static int rb_threadptr_pending_interrupt_empty_p(const rb_thread_t *th);
static const char *thread_status_name(rb_thread_t *th, int detail);
static int hrtime_update_expire(rb_hrtime_t *, const rb_hrtime_t);
NORETURN(static void async_bug_fd(const char *mesg, int errno_arg, int fd));
-MAYBE_UNUSED(static int consume_communication_pipe(int fd));
+static int consume_communication_pipe(int fd);
+static int check_signals_nogvl(rb_thread_t *, int sigwait_fd);
+void rb_sigwait_fd_migrate(rb_vm_t *); /* process.c */
+#define eKillSignal INT2FIX(0)
+#define eTerminateSignal INT2FIX(1)
static volatile int system_working = 1;
-static rb_internal_thread_specific_key_t specific_key_count;
struct waiting_fd {
struct ccan_list_node wfd_node; /* <=> vm.waiting_fds */
rb_thread_t *th;
int fd;
- struct rb_io_close_wait_list *busy;
};
/********************************************************************************/
@@ -175,11 +174,11 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio
#define THREAD_BLOCKING_BEGIN(th) do { \
struct rb_thread_sched * const sched = TH_SCHED(th); \
- RB_VM_SAVE_MACHINE_CONTEXT(th); \
- thread_sched_to_waiting((sched), (th));
+ RB_GC_SAVE_MACHINE_CONTEXT(th); \
+ thread_sched_to_waiting(sched);
#define THREAD_BLOCKING_END(th) \
- thread_sched_to_running((sched), (th)); \
+ thread_sched_to_running(sched, th); \
rb_ractor_thread_switch(th->ractor, th); \
} while(0)
@@ -199,8 +198,8 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio
!only_if_constant(fail_if_interrupted, TRUE)) { \
/* Important that this is inlined into the macro, and not part of \
* blocking_region_begin - see bug #20493 */ \
- RB_VM_SAVE_MACHINE_CONTEXT(th); \
- thread_sched_to_waiting(TH_SCHED(th), th); \
+ RB_GC_SAVE_MACHINE_CONTEXT(th); \
+ thread_sched_to_waiting(TH_SCHED(th)); \
exec; \
blocking_region_end(th, &__region); \
}; \
@@ -263,8 +262,13 @@ timeout_prepare(rb_hrtime_t **to, rb_hrtime_t *rel, rb_hrtime_t *end,
}
MAYBE_UNUSED(NOINLINE(static int thread_start_func_2(rb_thread_t *th, VALUE *stack_start)));
-MAYBE_UNUSED(static bool th_has_dedicated_nt(const rb_thread_t *th));
-MAYBE_UNUSED(static int waitfd_to_waiting_flag(int wfd_event));
+void ruby_sigchld_handler(rb_vm_t *); /* signal.c */
+
+static void
+ubf_sigwait(void *ignore)
+{
+ rb_thread_wakeup_timer_thread(0);
+}
#include THREAD_IMPL_SRC
@@ -344,23 +348,19 @@ unblock_function_clear(rb_thread_t *th)
static void
rb_threadptr_interrupt_common(rb_thread_t *th, int trap)
{
- RUBY_DEBUG_LOG("th:%u trap:%d", rb_th_serial(th), trap);
-
rb_native_mutex_lock(&th->interrupt_lock);
- {
- if (trap) {
- RUBY_VM_SET_TRAP_INTERRUPT(th->ec);
- }
- else {
- RUBY_VM_SET_INTERRUPT(th->ec);
- }
- if (th->unblock.func != NULL) {
- (th->unblock.func)(th->unblock.arg);
- }
- else {
- /* none */
- }
+ if (trap) {
+ RUBY_VM_SET_TRAP_INTERRUPT(th->ec);
+ }
+ else {
+ RUBY_VM_SET_INTERRUPT(th->ec);
+ }
+ if (th->unblock.func != NULL) {
+ (th->unblock.func)(th->unblock.arg);
+ }
+ else {
+ /* none */
}
rb_native_mutex_unlock(&th->interrupt_lock);
}
@@ -368,7 +368,6 @@ rb_threadptr_interrupt_common(rb_thread_t *th, int trap)
void
rb_threadptr_interrupt(rb_thread_t *th)
{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
rb_threadptr_interrupt_common(th, 0);
}
@@ -387,7 +386,7 @@ terminate_all(rb_ractor_t *r, const rb_thread_t *main_thread)
if (th != main_thread) {
RUBY_DEBUG_LOG("terminate start th:%u status:%s", rb_th_serial(th), thread_status_name(th, TRUE));
- rb_threadptr_pending_interrupt_enque(th, RUBY_FATAL_THREAD_TERMINATED);
+ rb_threadptr_pending_interrupt_enque(th, eTerminateSignal);
rb_threadptr_interrupt(th);
RUBY_DEBUG_LOG("terminate done th:%u status:%s", rb_th_serial(th), thread_status_name(th, TRUE));
@@ -419,7 +418,6 @@ rb_threadptr_join_list_wakeup(rb_thread_t *thread)
case THREAD_STOPPED:
case THREAD_STOPPED_FOREVER:
target_thread->status = THREAD_RUNNABLE;
- break;
default:
break;
}
@@ -434,7 +432,7 @@ rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th)
rb_mutex_t *mutex = th->keeping_mutexes;
th->keeping_mutexes = mutex->next_mutex;
- // rb_warn("mutex #<%p> was not unlocked by thread #<%p>", (void *)mutex, (void*)th);
+ /* rb_warn("mutex #<%p> remains to be locked by terminated thread", (void *)mutexes); */
const char *error_message = rb_mutex_unlock_th(mutex, th, mutex->fiber);
if (error_message) rb_bug("invalid keeping_mutexes: %s", error_message);
@@ -515,13 +513,16 @@ thread_cleanup_func(void *th_ptr, int atfork)
* Unfortunately, we can't release native threading resource at fork
* because libc may have unstable locking state therefore touching
* a threading resource may cause a deadlock.
+ *
+ * FIXME: Skipping native_mutex_destroy(pthread_mutex_destroy) is safe
+ * with NPTL, but native_thread_destroy calls pthread_cond_destroy
+ * which calls free(3), so there is a small memory leak atfork, here.
*/
- if (atfork) {
- th->nt = NULL;
+ if (atfork)
return;
- }
rb_native_mutex_destroy(&th->interrupt_lock);
+ native_thread_destroy(th);
}
static VALUE rb_threadptr_raise(rb_thread_t *, int, VALUE *);
@@ -586,7 +587,7 @@ thread_do_start_proc(rb_thread_t *th)
if (args_len < 8) {
/* free proc.args if the length is enough small */
args_ptr = ALLOCA_N(VALUE, args_len);
- MEMCPY((VALUE *)args_ptr, RARRAY_CONST_PTR(args), VALUE, args_len);
+ MEMCPY((VALUE *)args_ptr, RARRAY_CONST_PTR_TRANSIENT(args), VALUE, args_len);
th->invoke_arg.proc.args = Qnil;
}
else {
@@ -632,18 +633,26 @@ thread_do_start(rb_thread_t *th)
}
void rb_ec_clear_current_thread_trace_func(const rb_execution_context_t *ec);
+#define thread_sched_to_dead thread_sched_to_waiting
static int
thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
{
STACK_GROW_DIR_DETECTION;
-
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
- VM_ASSERT(th != th->vm->ractor.main_thread);
-
enum ruby_tag_type state;
VALUE errinfo = Qnil;
+ size_t size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
rb_thread_t *ractor_main_th = th->ractor->threads.main;
+ VALUE * vm_stack = NULL;
+
+ VM_ASSERT(th != th->vm->ractor.main_thread);
+ RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
+
+ // setup native thread
+ thread_sched_to_running(TH_SCHED(th), th);
+ ruby_thread_set_native(th);
+
+ RUBY_DEBUG_LOG("got lock. th:%u", rb_th_serial(th));
// setup ractor
if (rb_ractor_status_p(th->ractor, ractor_blocking)) {
@@ -658,6 +667,17 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
RB_VM_UNLOCK();
}
+ // This assertion is not passed on win32 env. Check it later.
+ // VM_ASSERT((size * sizeof(VALUE)) <= th->ec->machine.stack_maxsize);
+
+ // setup VM and machine stack
+ vm_stack = alloca(size * sizeof(VALUE));
+ VM_ASSERT(vm_stack);
+
+ rb_ec_initialize_vm_stack(th->ec, vm_stack, size);
+ th->ec->machine.stack_start = STACK_DIR_UPPER(vm_stack + size, vm_stack);
+ th->ec->machine.stack_maxsize -= size * sizeof(VALUE);
+
// Ensure that we are not joinable.
VM_ASSERT(UNDEF_P(th->value));
@@ -773,12 +793,12 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
// after rb_ractor_living_threads_remove()
// GC will happen anytime and this ractor can be collected (and destroy GVL).
// So gvl_release() should be before it.
- thread_sched_to_dead(TH_SCHED(th), th);
+ thread_sched_to_dead(TH_SCHED(th));
rb_ractor_living_threads_remove(th->ractor, th);
}
else {
rb_ractor_living_threads_remove(th->ractor, th);
- thread_sched_to_dead(TH_SCHED(th), th);
+ thread_sched_to_dead(TH_SCHED(th));
}
return 0;
@@ -798,8 +818,6 @@ struct thread_create_params {
VALUE (*fn)(void *);
};
-static void thread_specific_storage_alloc(rb_thread_t *th);
-
static VALUE
thread_create_core(VALUE thval, struct thread_create_params *params)
{
@@ -807,8 +825,6 @@ thread_create_core(VALUE thval, struct thread_create_params *params)
rb_thread_t *th = rb_thread_ptr(thval), *current_th = rb_ec_thread_ptr(ec);
int err;
- thread_specific_storage_alloc(th);
-
if (OBJ_FROZEN(current_th->thgroup)) {
rb_raise(rb_eThreadError,
"can't start a new thread (frozen ThreadGroup)");
@@ -986,11 +1002,11 @@ rb_thread_create(VALUE (*fn)(void *), void *arg)
}
VALUE
-rb_thread_create_ractor(rb_ractor_t *r, VALUE args, VALUE proc)
+rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc)
{
struct thread_create_params params = {
.type = thread_invoke_type_ractor_proc,
- .g = r,
+ .g = g,
.args = args,
.proc = proc,
};
@@ -1055,7 +1071,11 @@ thread_join_sleep(VALUE arg)
else return Qfalse;
}
else if (!limit) {
- sleep_forever(th, SLEEP_DEADLOCKABLE | SLEEP_ALLOW_SPURIOUS | SLEEP_NO_CHECKINTS);
+ th->status = THREAD_STOPPED_FOREVER;
+ rb_ractor_sleeper_threads_inc(th->ractor);
+ rb_check_deadlock(th->ractor);
+ native_sleep(th, 0);
+ rb_ractor_sleeper_threads_dec(th->ractor);
}
else {
if (hrtime_update_expire(limit, end)) {
@@ -1258,6 +1278,32 @@ rb_hrtime_now(void)
return rb_timespec2hrtime(&ts);
}
+static void
+sleep_forever(rb_thread_t *th, unsigned int fl)
+{
+ enum rb_thread_status prev_status = th->status;
+ enum rb_thread_status status;
+ int woke;
+
+ status = fl & SLEEP_DEADLOCKABLE ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
+ th->status = status;
+ RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+ while (th->status == status) {
+ if (fl & SLEEP_DEADLOCKABLE) {
+ rb_ractor_sleeper_threads_inc(th->ractor);
+ rb_check_deadlock(th->ractor);
+ }
+ native_sleep(th, 0);
+ if (fl & SLEEP_DEADLOCKABLE) {
+ rb_ractor_sleeper_threads_dec(th->ractor);
+ }
+ woke = vm_check_ints_blocking(th->ec);
+ if (woke && !(fl & SLEEP_SPURIOUS_CHECK))
+ break;
+ }
+ th->status = prev_status;
+}
+
/*
* at least gcc 7.2 and 7.3 complains about "rb_hrtime_t end"
* being uninitialized, maybe other versions, too.
@@ -1332,56 +1378,32 @@ sleep_hrtime_until(rb_thread_t *th, rb_hrtime_t end, unsigned int fl)
return woke;
}
-static void
-sleep_forever(rb_thread_t *th, unsigned int fl)
-{
- enum rb_thread_status prev_status = th->status;
- enum rb_thread_status status;
- int woke;
-
- status = fl & SLEEP_DEADLOCKABLE ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
- th->status = status;
-
- if (!(fl & SLEEP_NO_CHECKINTS)) RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
-
- while (th->status == status) {
- if (fl & SLEEP_DEADLOCKABLE) {
- rb_ractor_sleeper_threads_inc(th->ractor);
- rb_check_deadlock(th->ractor);
- }
- {
- native_sleep(th, 0);
- }
- if (fl & SLEEP_DEADLOCKABLE) {
- rb_ractor_sleeper_threads_dec(th->ractor);
- }
- if (fl & SLEEP_ALLOW_SPURIOUS) {
- break;
- }
-
- woke = vm_check_ints_blocking(th->ec);
-
- if (woke && !(fl & SLEEP_SPURIOUS_CHECK)) {
- break;
- }
- }
- th->status = prev_status;
-}
-
void
rb_thread_sleep_forever(void)
{
- RUBY_DEBUG_LOG("forever");
+ RUBY_DEBUG_LOG("");
sleep_forever(GET_THREAD(), SLEEP_SPURIOUS_CHECK);
}
void
rb_thread_sleep_deadly(void)
{
- RUBY_DEBUG_LOG("deadly");
+ RUBY_DEBUG_LOG("");
sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE|SLEEP_SPURIOUS_CHECK);
}
+void
+rb_thread_sleep_interruptible(void)
+{
+ rb_thread_t *th = GET_THREAD();
+ enum rb_thread_status prev_status = th->status;
+
+ th->status = THREAD_STOPPED;
+ native_sleep(th, 0);
+ RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+ th->status = prev_status;
+}
+
static void
rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker, VALUE timeout, rb_hrtime_t end)
{
@@ -1390,7 +1412,7 @@ rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker, VALUE timeout, rb_hr
rb_fiber_scheduler_block(scheduler, blocker, timeout);
}
else {
- RUBY_DEBUG_LOG("...");
+ RUBY_DEBUG_LOG("");
if (end) {
sleep_hrtime_until(GET_THREAD(), end, SLEEP_SPURIOUS_CHECK);
}
@@ -1454,7 +1476,7 @@ rb_thread_schedule_limits(uint32_t limits_us)
if (th->running_time_us >= limits_us) {
RUBY_DEBUG_LOG("switch %s", "start");
- RB_VM_SAVE_MACHINE_CONTEXT(th);
+ RB_GC_SAVE_MACHINE_CONTEXT(th);
thread_sched_yield(TH_SCHED(th), th);
rb_ractor_thread_switch(th->ractor, th);
@@ -1487,7 +1509,7 @@ blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer *region,
th->status = THREAD_STOPPED;
rb_ractor_blocking_threads_inc(th->ractor, __FILE__, __LINE__);
- RUBY_DEBUG_LOG("thread_id:%p", (void *)th->nt->thread_id);
+ RUBY_DEBUG_LOG("");
return TRUE;
}
else {
@@ -1512,12 +1534,8 @@ blocking_region_end(rb_thread_t *th, struct rb_blocking_region_buffer *region)
th->status = region->prev_status;
}
- RUBY_DEBUG_LOG("end");
-
-#ifndef _WIN32
- // GET_THREAD() clears WSAGetLastError()
+ RUBY_DEBUG_LOG("");
VM_ASSERT(th == GET_THREAD());
-#endif
}
void *
@@ -1541,11 +1559,14 @@ rb_nogvl(void *(*func)(void *), void *data1,
if (flags & RB_NOGVL_UBF_ASYNC_SAFE) {
vm->ubf_async_safe = 1;
}
+ else {
+ ubf_th = rb_thread_start_unblock_thread();
+ }
}
BLOCKING_REGION(th, {
val = func(data1);
- saved_errno = rb_errno();
+ saved_errno = errno;
}, ubf, data2, flags & RB_NOGVL_INTR_FAIL);
if (is_main_thread) vm->ubf_async_safe = 0;
@@ -1558,7 +1579,7 @@ rb_nogvl(void *(*func)(void *), void *data1,
thread_value(rb_thread_kill(ubf_th));
}
- rb_errno_set(saved_errno);
+ errno = saved_errno;
return val;
}
@@ -1662,107 +1683,30 @@ rb_thread_call_without_gvl(void *(*func)(void *data), void *data1,
return rb_nogvl(func, data1, ubf, data2, 0);
}
-static int
-waitfd_to_waiting_flag(int wfd_event)
-{
- return wfd_event << 1;
-}
-
-static void
-thread_io_setup_wfd(rb_thread_t *th, int fd, struct waiting_fd *wfd)
-{
- wfd->fd = fd;
- wfd->th = th;
- wfd->busy = NULL;
-
- RB_VM_LOCK_ENTER();
- {
- ccan_list_add(&th->vm->waiting_fds, &wfd->wfd_node);
- }
- RB_VM_LOCK_LEAVE();
-}
-
-static void
-thread_io_wake_pending_closer(struct waiting_fd *wfd)
-{
- bool has_waiter = wfd->busy && RB_TEST(wfd->busy->wakeup_mutex);
- if (has_waiter) {
- rb_mutex_lock(wfd->busy->wakeup_mutex);
- }
-
- /* Needs to be protected with RB_VM_LOCK because we don't know if
- wfd is on the global list of pending FD ops or if it's on a
- struct rb_io_close_wait_list close-waiter. */
- RB_VM_LOCK_ENTER();
- ccan_list_del(&wfd->wfd_node);
- RB_VM_LOCK_LEAVE();
-
- if (has_waiter) {
- rb_thread_wakeup(wfd->busy->closing_thread);
- rb_mutex_unlock(wfd->busy->wakeup_mutex);
- }
-}
-
-static int
-thread_io_wait_events(rb_thread_t *th, rb_execution_context_t *ec, int fd, int events, struct timeval *timeout, struct waiting_fd *wfd)
-{
-#if defined(USE_MN_THREADS) && USE_MN_THREADS
- if (!th_has_dedicated_nt(th) &&
- (events || timeout) &&
- th->blocking // no fiber scheduler
- ) {
- int r;
- rb_hrtime_t rel, *prel;
-
- if (timeout) {
- rel = rb_timeval2hrtime(timeout);
- prel = &rel;
- }
- else {
- prel = NULL;
- }
-
- VM_ASSERT(prel || (events & (RB_WAITFD_IN | RB_WAITFD_OUT)));
-
- thread_io_setup_wfd(th, fd, wfd);
- {
- // wait readable/writable
- r = thread_sched_wait_events(TH_SCHED(th), th, fd, waitfd_to_waiting_flag(events), prel);
- }
- thread_io_wake_pending_closer(wfd);
-
- RUBY_VM_CHECK_INTS_BLOCKING(ec);
-
- return r;
- }
-#endif // defined(USE_MN_THREADS) && USE_MN_THREADS
-
- return 0;
-}
-
VALUE
-rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events)
+rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
{
- rb_execution_context_t * volatile ec = GET_EC();
- rb_thread_t *th = rb_ec_thread_ptr(ec);
-
- RUBY_DEBUG_LOG("th:%u fd:%d ev:%d", rb_th_serial(th), fd, events);
-
- struct waiting_fd waiting_fd;
-
- thread_io_wait_events(th, ec, fd, events, NULL, &waiting_fd);
-
volatile VALUE val = Qundef; /* shouldn't be used */
+ rb_execution_context_t * volatile ec = GET_EC();
volatile int saved_errno = 0;
enum ruby_tag_type state;
+ struct waiting_fd waiting_fd = {
+ .fd = fd,
+ .th = rb_ec_thread_ptr(ec)
+ };
+
// `errno` is only valid when there is an actual error - but we can't
// extract that from the return value of `func` alone, so we clear any
// prior `errno` value here so that we can later check if it was set by
// `func` or not (as opposed to some previously set value).
errno = 0;
- thread_io_setup_wfd(th, fd, &waiting_fd);
+ RB_VM_LOCK_ENTER();
+ {
+ ccan_list_add(&rb_ec_vm_ptr(ec)->waiting_fds, &waiting_fd.wfd_node);
+ }
+ RB_VM_LOCK_LEAVE();
EC_PUSH_TAG(ec);
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
@@ -1775,9 +1719,13 @@ rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, in
/*
* must be deleted before jump
- * this will delete either from waiting_fds or on-stack struct rb_io_close_wait_list
+ * this will delete either from waiting_fds or on-stack CCAN_LIST_HEAD(busy)
*/
- thread_io_wake_pending_closer(&waiting_fd);
+ RB_VM_LOCK_ENTER();
+ {
+ ccan_list_del(&waiting_fd.wfd_node);
+ }
+ RB_VM_LOCK_LEAVE();
if (state) {
EC_JUMP_TAG(ec, state);
@@ -1795,12 +1743,6 @@ rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, in
return val;
}
-VALUE
-rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
-{
- return rb_thread_io_blocking_call(func, data1, fd, 0);
-}
-
/*
* rb_thread_call_with_gvl - re-enter the Ruby world after GVL release.
*
@@ -1860,8 +1802,8 @@ rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
/* leave from Ruby world: You can not access Ruby values, etc. */
int released = blocking_region_begin(th, brb, prev_unblock.func, prev_unblock.arg, FALSE);
RUBY_ASSERT_ALWAYS(released);
- RB_VM_SAVE_MACHINE_CONTEXT(th);
- thread_sched_to_waiting(TH_SCHED(th), th);
+ RB_GC_SAVE_MACHINE_CONTEXT(th);
+ thread_sched_to_waiting(TH_SCHED(th));
return r;
}
@@ -1949,23 +1891,6 @@ enum handle_interrupt_timing {
};
static enum handle_interrupt_timing
-rb_threadptr_pending_interrupt_from_symbol(rb_thread_t *th, VALUE sym)
-{
- if (sym == sym_immediate) {
- return INTERRUPT_IMMEDIATE;
- }
- else if (sym == sym_on_blocking) {
- return INTERRUPT_ON_BLOCKING;
- }
- else if (sym == sym_never) {
- return INTERRUPT_NEVER;
- }
- else {
- rb_raise(rb_eThreadError, "unknown mask signature");
- }
-}
-
-static enum handle_interrupt_timing
rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err)
{
VALUE mask;
@@ -1977,16 +1902,6 @@ rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err)
for (i=0; i<mask_stack_len; i++) {
mask = mask_stack[mask_stack_len-(i+1)];
- if (SYMBOL_P(mask)) {
- /* do not match RUBY_FATAL_THREAD_KILLED etc */
- if (err != rb_cInteger) {
- return rb_threadptr_pending_interrupt_from_symbol(th, mask);
- }
- else {
- continue;
- }
- }
-
for (mod = err; mod; mod = RCLASS_SUPER(mod)) {
VALUE klass = mod;
VALUE sym;
@@ -1999,7 +1914,18 @@ rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err)
}
if ((sym = rb_hash_aref(mask, klass)) != Qnil) {
- return rb_threadptr_pending_interrupt_from_symbol(th, sym);
+ if (sym == sym_immediate) {
+ return INTERRUPT_IMMEDIATE;
+ }
+ else if (sym == sym_on_blocking) {
+ return INTERRUPT_ON_BLOCKING;
+ }
+ else if (sym == sym_never) {
+ return INTERRUPT_NEVER;
+ }
+ else {
+ rb_raise(rb_eThreadError, "unknown mask signature");
+ }
}
}
/* try to next mask */
@@ -2091,24 +2017,10 @@ handle_interrupt_arg_check_i(VALUE key, VALUE val, VALUE args)
rb_raise(rb_eArgError, "unknown mask signature");
}
- if (key == rb_eException && (UNDEF_P(*maskp) || NIL_P(*maskp))) {
- *maskp = val;
- return ST_CONTINUE;
- }
-
- if (RTEST(*maskp)) {
- if (!RB_TYPE_P(*maskp, T_HASH)) {
- VALUE prev = *maskp;
- *maskp = rb_ident_hash_new();
- if (SYMBOL_P(prev)) {
- rb_hash_aset(*maskp, rb_eException, prev);
- }
- }
- rb_hash_aset(*maskp, key, val);
- }
- else {
- *maskp = Qfalse;
+ if (!*maskp) {
+ *maskp = rb_ident_hash_new();
}
+ rb_hash_aset(*maskp, key, val);
return ST_CONTINUE;
}
@@ -2224,7 +2136,7 @@ handle_interrupt_arg_check_i(VALUE key, VALUE val, VALUE args)
static VALUE
rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
{
- VALUE mask = Qundef;
+ VALUE mask;
rb_execution_context_t * volatile ec = GET_EC();
rb_thread_t * volatile th = rb_ec_thread_ptr(ec);
volatile VALUE r = Qnil;
@@ -2234,25 +2146,13 @@ rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
rb_raise(rb_eArgError, "block is needed.");
}
+ mask = 0;
mask_arg = rb_to_hash_type(mask_arg);
-
- if (OBJ_FROZEN(mask_arg) && rb_hash_compare_by_id_p(mask_arg)) {
- mask = Qnil;
- }
-
rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, (VALUE)&mask);
-
- if (UNDEF_P(mask)) {
+ if (!mask) {
return rb_yield(Qnil);
}
-
- if (!RTEST(mask)) {
- mask = mask_arg;
- }
- else if (RB_TYPE_P(mask, T_HASH)) {
- OBJ_FREEZE_RAW(mask);
- }
-
+ OBJ_FREEZE_RAW(mask);
rb_ary_push(th->pending_interrupt_mask_stack, mask);
if (!rb_threadptr_pending_interrupt_empty_p(th)) {
th->pending_interrupt_queue_checked = 0;
@@ -2402,7 +2302,13 @@ threadptr_get_interrupts(rb_thread_t *th)
return interrupt & (rb_atomic_t)~ec->interrupt_mask;
}
-int
+#if USE_MJIT
+// process.c
+extern bool mjit_waitpid_finished;
+extern int mjit_waitpid_status;
+#endif
+
+MJIT_FUNC_EXPORTED int
rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
{
rb_atomic_t interrupt;
@@ -2436,27 +2342,41 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
/* signal handling */
if (trap_interrupt && (th == th->vm->ractor.main_thread)) {
enum rb_thread_status prev_status = th->status;
+ int sigwait_fd = rb_sigwait_fd_get(th);
+ if (sigwait_fd >= 0) {
+ (void)consume_communication_pipe(sigwait_fd);
+ ruby_sigchld_handler(th->vm);
+ rb_sigwait_fd_put(th, sigwait_fd);
+ rb_sigwait_fd_migrate(th->vm);
+ }
th->status = THREAD_RUNNABLE;
- {
- while ((sig = rb_get_next_signal()) != 0) {
- ret |= rb_signal_exec(th, sig);
- }
+ while ((sig = rb_get_next_signal()) != 0) {
+ ret |= rb_signal_exec(th, sig);
}
th->status = prev_status;
}
+#if USE_MJIT
+ // Handle waitpid_signal for MJIT issued by ruby_sigchld_handler. This needs to be done
+ // outside ruby_sigchld_handler to avoid recursively relying on the SIGCHLD handler.
+ if (mjit_waitpid_finished && th == th->vm->ractor.main_thread) {
+ mjit_waitpid_finished = false;
+ mjit_notify_waitpid(WIFEXITED(mjit_waitpid_status) ? WEXITSTATUS(mjit_waitpid_status) : -1);
+ }
+#endif
+
/* exception from another thread */
if (pending_interrupt && threadptr_pending_interrupt_active_p(th)) {
VALUE err = rb_threadptr_pending_interrupt_deque(th, blocking_timing ? INTERRUPT_ON_BLOCKING : INTERRUPT_NONE);
- RUBY_DEBUG_LOG("err:%"PRIdVALUE, err);
+ RUBY_DEBUG_LOG("err:%"PRIdVALUE"\n", err);
ret = TRUE;
if (UNDEF_P(err)) {
/* no error */
}
- else if (err == RUBY_FATAL_THREAD_KILLED /* Thread#kill received */ ||
- err == RUBY_FATAL_THREAD_TERMINATED /* Terminate thread */ ||
+ else if (err == eKillSignal /* Thread#kill received */ ||
+ err == eTerminateSignal /* Terminate thread */ ||
err == INT2FIX(TAG_FATAL) /* Thread.exit etc. */ ) {
terminate_interrupt = 1;
}
@@ -2486,7 +2406,7 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
limits_us >>= -th->priority;
if (th->status == THREAD_RUNNABLE)
- th->running_time_us += 10 * 1000; // 10ms = 10_000us // TODO: use macro
+ th->running_time_us += TIME_QUANTUM_USEC;
VM_ASSERT(th->ec->cfp);
EXEC_EVENT_HOOK(th->ec, RUBY_INTERNAL_EVENT_SWITCH, th->ec->cfp->self,
@@ -2581,13 +2501,10 @@ rb_ec_reset_raised(rb_execution_context_t *ec)
}
int
-rb_notify_fd_close(int fd, struct rb_io_close_wait_list *busy)
+rb_notify_fd_close(int fd, struct ccan_list_head *busy)
{
rb_vm_t *vm = GET_THREAD()->vm;
struct waiting_fd *wfd = 0, *next;
- ccan_list_head_init(&busy->pending_fd_users);
- int has_any;
- VALUE wakeup_mutex;
RB_VM_LOCK_ENTER();
{
@@ -2597,57 +2514,27 @@ rb_notify_fd_close(int fd, struct rb_io_close_wait_list *busy)
VALUE err;
ccan_list_del(&wfd->wfd_node);
- ccan_list_add(&busy->pending_fd_users, &wfd->wfd_node);
+ ccan_list_add(busy, &wfd->wfd_node);
- wfd->busy = busy;
err = th->vm->special_exceptions[ruby_error_stream_closed];
rb_threadptr_pending_interrupt_enque(th, err);
rb_threadptr_interrupt(th);
}
}
}
-
- has_any = !ccan_list_empty(&busy->pending_fd_users);
- busy->closing_thread = rb_thread_current();
- wakeup_mutex = Qnil;
- if (has_any) {
- wakeup_mutex = rb_mutex_new();
- RBASIC_CLEAR_CLASS(wakeup_mutex); /* hide from ObjectSpace */
- }
- busy->wakeup_mutex = wakeup_mutex;
-
RB_VM_LOCK_LEAVE();
- /* If the caller didn't pass *busy as a pointer to something on the stack,
- we need to guard this mutex object on _our_ C stack for the duration
- of this function. */
- RB_GC_GUARD(wakeup_mutex);
- return has_any;
-}
-
-void
-rb_notify_fd_close_wait(struct rb_io_close_wait_list *busy)
-{
- if (!RB_TEST(busy->wakeup_mutex)) {
- /* There was nobody else using this file when we closed it, so we
- never bothered to allocate a mutex*/
- return;
- }
-
- rb_mutex_lock(busy->wakeup_mutex);
- while (!ccan_list_empty(&busy->pending_fd_users)) {
- rb_mutex_sleep(busy->wakeup_mutex, Qnil);
- }
- rb_mutex_unlock(busy->wakeup_mutex);
+ return !ccan_list_empty(busy);
}
void
rb_thread_fd_close(int fd)
{
- struct rb_io_close_wait_list busy;
+ struct ccan_list_head busy;
+ ccan_list_head_init(&busy);
if (rb_notify_fd_close(fd, &busy)) {
- rb_notify_fd_close_wait(&busy);
+ do rb_thread_schedule(); while (!ccan_list_empty(&busy));
}
}
@@ -2720,7 +2607,7 @@ rb_thread_kill(VALUE thread)
}
else {
threadptr_check_pending_interrupt_queue(target_th);
- rb_threadptr_pending_interrupt_enque(target_th, RUBY_FATAL_THREAD_KILLED);
+ rb_threadptr_pending_interrupt_enque(target_th, eKillSignal);
rb_threadptr_interrupt(target_th);
}
@@ -2889,7 +2776,7 @@ VALUE
rb_thread_list(void)
{
// TODO
- return rb_ractor_thread_list();
+ return rb_ractor_thread_list(GET_RACTOR());
}
/*
@@ -3416,7 +3303,7 @@ rb_thread_setname(VALUE thread, VALUE name)
name = rb_str_new_frozen(name);
}
target_th->name = name;
- if (threadptr_initialized(target_th) && target_th->has_dedicated_nt) {
+ if (threadptr_initialized(target_th)) {
native_set_another_thread_name(target_th->nt->thread_id, name);
}
return name;
@@ -4007,7 +3894,7 @@ rb_fd_init_copy(rb_fdset_t *dst, rb_fdset_t *src)
void
rb_fd_term(rb_fdset_t *fds)
{
- xfree(fds->fdset);
+ if (fds->fdset) xfree(fds->fdset);
fds->maxfd = 0;
fds->fdset = 0;
}
@@ -4174,7 +4061,7 @@ rb_fd_set(int fd, rb_fdset_t *set)
#endif
static int
-wait_retryable(volatile int *result, int errnum, rb_hrtime_t *rel, rb_hrtime_t end)
+wait_retryable(int *result, int errnum, rb_hrtime_t *rel, rb_hrtime_t end)
{
if (*result < 0) {
switch (errnum) {
@@ -4202,6 +4089,7 @@ wait_retryable(volatile int *result, int errnum, rb_hrtime_t *rel, rb_hrtime_t e
struct select_set {
int max;
+ int sigwait_fd;
rb_thread_t *th;
rb_fdset_t *rset;
rb_fdset_t *wset;
@@ -4217,6 +4105,11 @@ select_set_free(VALUE p)
{
struct select_set *set = (struct select_set *)p;
+ if (set->sigwait_fd >= 0) {
+ rb_sigwait_fd_put(set->th, set->sigwait_fd);
+ rb_sigwait_fd_migrate(set->th->vm);
+ }
+
rb_fd_term(&set->orig_rset);
rb_fd_term(&set->orig_wset);
rb_fd_term(&set->orig_eset);
@@ -4224,16 +4117,33 @@ select_set_free(VALUE p)
return Qfalse;
}
+static const rb_hrtime_t *
+sigwait_timeout(rb_thread_t *th, int sigwait_fd, const rb_hrtime_t *orig,
+ int *drained_p)
+{
+ static const rb_hrtime_t quantum = TIME_QUANTUM_USEC * 1000;
+
+ if (sigwait_fd >= 0 && (!ubf_threads_empty() || BUSY_WAIT_SIGNALS)) {
+ *drained_p = check_signals_nogvl(th, sigwait_fd);
+ if (!orig || *orig > quantum)
+ return &quantum;
+ }
+
+ return orig;
+}
+
+#define sigwait_signals_fd(result, cond, sigwait_fd) \
+ (result > 0 && (cond) ? (result--, (sigwait_fd)) : -1)
+
static VALUE
do_select(VALUE p)
{
struct select_set *set = (struct select_set *)p;
- volatile int result = 0;
+ int result = 0;
int lerrno;
rb_hrtime_t *to, rel, end = 0;
timeout_prepare(&to, &rel, &end, set->timeout);
- volatile rb_hrtime_t endtime = end;
#define restore_fdset(dst, src) \
((dst) ? rb_fd_dup(dst, src) : (void)0)
#define do_select_update() \
@@ -4243,21 +4153,31 @@ do_select(VALUE p)
TRUE)
do {
+ int drained;
lerrno = 0;
BLOCKING_REGION(set->th, {
+ const rb_hrtime_t *sto;
struct timeval tv;
+ sto = sigwait_timeout(set->th, set->sigwait_fd, to, &drained);
if (!RUBY_VM_INTERRUPTED(set->th->ec)) {
- result = native_fd_select(set->max,
- set->rset, set->wset, set->eset,
- rb_hrtime2timeval(&tv, to), set->th);
+ result = native_fd_select(set->max, set->rset, set->wset,
+ set->eset,
+ rb_hrtime2timeval(&tv, sto), set->th);
if (result < 0) lerrno = errno;
}
- }, ubf_select, set->th, TRUE);
+ }, set->sigwait_fd >= 0 ? ubf_sigwait : ubf_select, set->th, TRUE);
+
+ if (set->sigwait_fd >= 0) {
+ int fd = sigwait_signals_fd(result,
+ rb_fd_isset(set->sigwait_fd, set->rset),
+ set->sigwait_fd);
+ (void)check_signals_nogvl(set->th, fd);
+ }
RUBY_VM_CHECK_INTS_BLOCKING(set->th->ec); /* may raise */
- } while (wait_retryable(&result, lerrno, to, endtime) && do_select_update());
+ } while (wait_retryable(&result, lerrno, to, end) && do_select_update());
if (result < 0) {
errno = lerrno;
@@ -4266,6 +4186,18 @@ do_select(VALUE p)
return (VALUE)result;
}
+static rb_fdset_t *
+init_set_fd(int fd, rb_fdset_t *fds)
+{
+ if (fd < 0) {
+ return 0;
+ }
+ rb_fd_init(fds);
+ rb_fd_set(fd, fds);
+
+ return fds;
+}
+
int
rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * except,
struct timeval *timeout)
@@ -4289,6 +4221,16 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
return 0;
}
+ set.sigwait_fd = rb_sigwait_fd_get(set.th);
+ if (set.sigwait_fd >= 0) {
+ if (set.rset)
+ rb_fd_set(set.sigwait_fd, set.rset);
+ else
+ set.rset = init_set_fd(set.sigwait_fd, &set.orig_rset);
+ if (set.sigwait_fd >= set.max) {
+ set.max = set.sigwait_fd + 1;
+ }
+ }
#define fd_init_copy(f) do { \
if (set.f) { \
rb_fd_resize(set.max - 1, set.f); \
@@ -4325,50 +4267,74 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
int
rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
{
- struct pollfd fds[1];
- volatile int result = 0;
+ struct pollfd fds[2];
+ int result = 0;
+ int drained;
nfds_t nfds;
+ rb_unblock_function_t *ubf;
struct waiting_fd wfd;
int state;
volatile int lerrno;
- rb_execution_context_t *ec = GET_EC();
- rb_thread_t *th = rb_ec_thread_ptr(ec);
+ wfd.th = GET_THREAD();
+ wfd.fd = fd;
- if (thread_io_wait_events(th, ec, fd, events, timeout, &wfd)) {
- return 0; // timeout
+ RB_VM_LOCK_ENTER();
+ {
+ ccan_list_add(&wfd.th->vm->waiting_fds, &wfd.wfd_node);
}
-
- thread_io_setup_wfd(th, fd, &wfd);
+ RB_VM_LOCK_LEAVE();
EC_PUSH_TAG(wfd.th->ec);
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
rb_hrtime_t *to, rel, end = 0;
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
timeout_prepare(&to, &rel, &end, timeout);
- volatile rb_hrtime_t endtime = end;
fds[0].fd = fd;
fds[0].events = (short)events;
fds[0].revents = 0;
do {
- nfds = 1;
+ fds[1].fd = rb_sigwait_fd_get(wfd.th);
+
+ if (fds[1].fd >= 0) {
+ fds[1].events = POLLIN;
+ fds[1].revents = 0;
+ nfds = 2;
+ ubf = ubf_sigwait;
+ }
+ else {
+ nfds = 1;
+ ubf = ubf_select;
+ }
lerrno = 0;
BLOCKING_REGION(wfd.th, {
+ const rb_hrtime_t *sto;
struct timespec ts;
+ sto = sigwait_timeout(wfd.th, fds[1].fd, to, &drained);
if (!RUBY_VM_INTERRUPTED(wfd.th->ec)) {
- result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0);
+ result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, sto), 0);
if (result < 0) lerrno = errno;
}
- }, ubf_select, wfd.th, TRUE);
+ }, ubf, wfd.th, TRUE);
+ if (fds[1].fd >= 0) {
+ int fd1 = sigwait_signals_fd(result, fds[1].revents, fds[1].fd);
+ (void)check_signals_nogvl(wfd.th, fd1);
+ rb_sigwait_fd_put(wfd.th, fds[1].fd);
+ rb_sigwait_fd_migrate(wfd.th->vm);
+ }
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
- } while (wait_retryable(&result, lerrno, to, endtime));
+ } while (wait_retryable(&result, lerrno, to, end));
}
EC_POP_TAG();
- thread_io_wake_pending_closer(&wfd);
+ RB_VM_LOCK_ENTER();
+ {
+ ccan_list_del(&wfd.wfd_node);
+ }
+ RB_VM_LOCK_LEAVE();
if (state) {
EC_JUMP_TAG(wfd.th->ec, state);
@@ -4442,7 +4408,11 @@ select_single_cleanup(VALUE ptr)
{
struct select_args *args = (struct select_args *)ptr;
- thread_io_wake_pending_closer(&args->wfd);
+ RB_VM_LOCK_ENTER();
+ {
+ ccan_list_del(&args->wfd.wfd_node);
+ }
+ RB_VM_LOCK_LEAVE();
if (args->read) rb_fd_term(args->read);
if (args->write) rb_fd_term(args->write);
if (args->except) rb_fd_term(args->except);
@@ -4450,18 +4420,6 @@ select_single_cleanup(VALUE ptr)
return (VALUE)-1;
}
-static rb_fdset_t *
-init_set_fd(int fd, rb_fdset_t *fds)
-{
- if (fd < 0) {
- return 0;
- }
- rb_fd_init(fds);
- rb_fd_set(fd, fds);
-
- return fds;
-}
-
int
rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
{
@@ -4469,12 +4427,6 @@ rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
struct select_args args;
int r;
VALUE ptr = (VALUE)&args;
- rb_execution_context_t *ec = GET_EC();
- rb_thread_t *th = rb_ec_thread_ptr(ec);
-
- if (thread_io_wait_events(th, ec, fd, events, timeout, &args.wfd)) {
- return 0; // timeout
- }
args.as.fd = fd;
args.read = (events & RB_WAITFD_IN) ? init_set_fd(fd, &rfds) : NULL;
@@ -4482,8 +4434,7 @@ rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
args.except = (events & RB_WAITFD_PRI) ? init_set_fd(fd, &efds) : NULL;
args.tv = timeout;
args.wfd.fd = fd;
- args.wfd.th = th;
- args.wfd.busy = NULL;
+ args.wfd.th = GET_THREAD();
RB_VM_LOCK_ENTER();
{
@@ -4550,13 +4501,16 @@ consume_communication_pipe(int fd)
ssize_t result;
int ret = FALSE; /* for rb_sigwait_sleep */
+ /*
+ * disarm UBF_TIMER before we read, because it can become
+ * re-armed at any time via sighandler and the pipe will refill
+ * We can disarm it because this thread is now processing signals
+ * and we do not want unnecessary SIGVTALRM
+ */
+ ubf_timer_disarm();
+
while (1) {
result = read(fd, buff, sizeof(buff));
-#if USE_EVENTFD
- RUBY_DEBUG_LOG("resultf:%d buff:%lu", (int)result, (unsigned long)buff[0]);
-#else
- RUBY_DEBUG_LOG("result:%d", (int)result);
-#endif
if (result > 0) {
ret = TRUE;
if (USE_EVENTFD || result < (ssize_t)sizeof(buff)) {
@@ -4583,6 +4537,26 @@ consume_communication_pipe(int fd)
}
}
+static int
+check_signals_nogvl(rb_thread_t *th, int sigwait_fd)
+{
+ rb_vm_t *vm = GET_VM(); /* th may be 0 */
+ int ret = sigwait_fd >= 0 ? consume_communication_pipe(sigwait_fd) : FALSE;
+ ubf_wakeup_all_threads();
+ ruby_sigchld_handler(vm);
+ if (rb_signal_buff_size()) {
+ if (th == vm->ractor.main_thread) {
+ /* no need to lock + wakeup if already in main thread */
+ RUBY_VM_SET_TRAP_INTERRUPT(th->ec);
+ }
+ else {
+ threadptr_trap_interrupt(vm->ractor.main_thread);
+ }
+ ret = TRUE; /* for SIGCHLD_LOSSY && rb_sigwait_sleep */
+ }
+ return ret;
+}
+
void
rb_thread_stop_timer_thread(void)
{
@@ -4668,9 +4642,9 @@ rb_thread_atfork_internal(rb_thread_t *th, void (*atfork)(rb_thread_t *, const r
rb_vm_living_threads_init(vm);
rb_ractor_atfork(vm, th);
- rb_vm_postponed_job_atfork();
- /* may be held by RJIT threads in parent */
+ /* may be held by MJIT threads in parent */
+ rb_native_mutex_initialize(&vm->waitpid_lock);
rb_native_mutex_initialize(&vm->workqueue_lock);
/* may be held by any thread in parent */
@@ -4680,10 +4654,6 @@ rb_thread_atfork_internal(rb_thread_t *th, void (*atfork)(rb_thread_t *, const r
rb_ractor_sleeper_threads_clear(th->ractor);
rb_clear_coverages();
- // restart timer thread (timer threads access to `vm->waitpid_lock` and so on.
- rb_thread_reset_timer_thread();
- rb_thread_start_timer_thread();
-
VM_ASSERT(vm->ractor.blocking_cnt == 0);
VM_ASSERT(vm->ractor.cnt == 1);
}
@@ -4710,6 +4680,9 @@ rb_thread_atfork(void)
/* We don't want reproduce CVE-2003-0900. */
rb_reset_random_seed();
+
+ /* For child, starting MJIT worker thread in this place which is safer than immediately after `after_fork_ruby`. */
+ mjit_child_after_fork();
}
static void
@@ -4740,16 +4713,19 @@ rb_thread_atfork_before_exec(void)
struct thgroup {
int enclosed;
+ VALUE group;
};
+static size_t
+thgroup_memsize(const void *ptr)
+{
+ return sizeof(struct thgroup);
+}
+
static const rb_data_type_t thgroup_data_type = {
"thgroup",
- {
- 0,
- RUBY_TYPED_DEFAULT_FREE,
- NULL, // No external memory to report
- },
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
+ {0, RUBY_TYPED_DEFAULT_FREE, thgroup_memsize,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
/*
@@ -4779,6 +4755,7 @@ thgroup_s_alloc(VALUE klass)
group = TypedData_Make_Struct(klass, struct thgroup, &thgroup_data_type, data);
data->enclosed = 0;
+ data->group = group;
return group;
}
@@ -5340,6 +5317,7 @@ Init_Thread_Mutex(void)
{
rb_thread_t *th = GET_THREAD();
+ rb_native_mutex_initialize(&th->vm->waitpid_lock);
rb_native_mutex_initialize(&th->vm->workqueue_lock);
rb_native_mutex_initialize(&th->interrupt_lock);
}
@@ -5448,12 +5426,8 @@ Init_Thread(void)
/* main thread setting */
{
/* acquire global vm lock */
-#ifdef HAVE_PTHREAD_NP_H
- VM_ASSERT(TH_SCHED(th)->running == th);
-#endif
- // thread_sched_to_running() should not be called because
- // it assumes blocked by thread_sched_to_waiting().
- // thread_sched_to_running(sched, th);
+ struct rb_thread_sched *sched = TH_SCHED(th);
+ thread_sched_to_running(sched, th);
th->pending_interrupt_queue = rb_ary_hidden_new(0);
th->pending_interrupt_queue_checked = 0;
@@ -5464,9 +5438,6 @@ Init_Thread(void)
rb_thread_create_timer_thread();
Init_thread_sync();
-
- // TODO: Suppress unused function warning for now
- // if (0) rb_thread_sched_destroy(NULL);
}
int
@@ -5496,7 +5467,7 @@ debug_deadlock_check(rb_ractor_t *r, VALUE msg)
ccan_list_for_each(&r->threads.set, th, lt_node) {
rb_str_catf(msg, "* %+"PRIsVALUE"\n rb_thread_t:%p "
"native:%p int:%u",
- th->self, (void *)th, th->nt ? thread_id_str(th) : "N/A", th->ec->interrupt_flag);
+ th->self, (void *)th, thread_id_str(th), th->ec->interrupt_flag);
if (th->locking_mutex) {
rb_mutex_t *mutex = mutex_ptr(th->locking_mutex);
@@ -5522,18 +5493,14 @@ rb_check_deadlock(rb_ractor_t *r)
{
if (GET_THREAD()->vm->thread_ignore_deadlock) return;
-#ifdef RUBY_THREAD_PTHREAD_H
- if (r->threads.sched.readyq_cnt > 0) return;
-#endif
-
+ int found = 0;
+ rb_thread_t *th = NULL;
int sleeper_num = rb_ractor_sleeper_thread_num(r);
int ltnum = rb_ractor_living_thread_num(r);
if (ltnum > sleeper_num) return;
if (ltnum < sleeper_num) rb_bug("sleeper must not be more than vm_living_thread_num(vm)");
-
- int found = 0;
- rb_thread_t *th = NULL;
+ if (patrol_thread && patrol_thread != GET_THREAD()) return;
ccan_list_for_each(&r->threads.set, th, lt_node) {
if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th->ec)) {
@@ -5832,66 +5799,3 @@ rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data)
RUBY_VM_CHECK_INTS(cur_th->ec);
return ret;
}
-
-static void
-thread_specific_storage_alloc(rb_thread_t *th)
-{
- VM_ASSERT(th->specific_storage == NULL);
-
- if (UNLIKELY(specific_key_count > 0)) {
- th->specific_storage = ZALLOC_N(void *, RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX);
- }
-}
-
-rb_internal_thread_specific_key_t
-rb_internal_thread_specific_key_create(void)
-{
- rb_vm_t *vm = GET_VM();
-
- if (specific_key_count == 0 && vm->ractor.cnt > 1) {
- rb_raise(rb_eThreadError, "The first rb_internal_thread_specific_key_create() is called with multiple ractors");
- }
- else if (specific_key_count > RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX) {
- rb_raise(rb_eThreadError, "rb_internal_thread_specific_key_create() is called more than %d times", RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX);
- }
- else {
- rb_internal_thread_specific_key_t key = specific_key_count++;
-
- if (key == 0) {
- // allocate
- rb_ractor_t *cr = GET_RACTOR();
- rb_thread_t *th;
-
- ccan_list_for_each(&cr->threads.set, th, lt_node) {
- thread_specific_storage_alloc(th);
- }
- }
- return key;
- }
-}
-
-// async and native thread safe.
-void *
-rb_internal_thread_specific_get(VALUE thread_val, rb_internal_thread_specific_key_t key)
-{
- rb_thread_t *th = DATA_PTR(thread_val);
-
- VM_ASSERT(rb_thread_ptr(thread_val) == th);
- VM_ASSERT(key < RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX);
- VM_ASSERT(th->specific_storage);
-
- return th->specific_storage[key];
-}
-
-// async and native thread safe.
-void
-rb_internal_thread_specific_set(VALUE thread_val, rb_internal_thread_specific_key_t key, void *data)
-{
- rb_thread_t *th = DATA_PTR(thread_val);
-
- VM_ASSERT(rb_thread_ptr(thread_val) == th);
- VM_ASSERT(key < RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX);
- VM_ASSERT(th->specific_storage);
-
- th->specific_storage[key] = data;
-}
diff --git a/thread_none.c b/thread_none.c
index d3b533110e..a82ced684e 100644
--- a/thread_none.c
+++ b/thread_none.c
@@ -30,19 +30,17 @@ thread_sched_to_running(struct rb_thread_sched *sched, rb_thread_t *th)
}
static void
-thread_sched_to_waiting(struct rb_thread_sched *sched, rb_thread_t *th)
+thread_sched_to_waiting(struct rb_thread_sched *sched)
{
}
-#define thread_sched_to_dead thread_sched_to_waiting
-
static void
thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
{
}
void
-rb_thread_sched_init(struct rb_thread_sched *sched, bool atfork)
+rb_thread_sched_init(struct rb_thread_sched *sched)
{
}
@@ -136,8 +134,8 @@ Init_native_thread(rb_thread_t *main_th)
ruby_thread_set_native(main_th);
}
-void
-ruby_mn_threads_params(void)
+static void
+native_thread_destroy(rb_thread_t *th)
{
}
@@ -278,51 +276,9 @@ native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *e
return rb_fd_select(n, readfds, writefds, exceptfds, timeout);
}
-static bool
-th_has_dedicated_nt(const rb_thread_t *th)
-{
- return true;
-}
-
-void
-rb_add_running_thread(rb_thread_t *th){
- // do nothing
-}
-
-void
-rb_del_running_thread(rb_thread_t *th)
-{
- // do nothing
-}
-
-void
-rb_threadptr_sched_free(rb_thread_t *th)
+static VALUE
+rb_thread_start_unblock_thread(void)
{
- // do nothing
+ return Qfalse;
}
-
-void
-rb_ractor_sched_barrier_start(rb_vm_t *vm, rb_ractor_t *cr)
-{
- // do nothing
-}
-
-void
-rb_ractor_sched_barrier_join(rb_vm_t *vm, rb_ractor_t *cr)
-{
- // do nothing
-}
-
-void
-rb_threadptr_remove(rb_thread_t *th)
-{
- // do nothing
-}
-
-void
-rb_thread_sched_mark_zombies(rb_vm_t *vm)
-{
- // do nothing
-}
-
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
diff --git a/thread_none.h b/thread_none.h
index ac47e52bda..89f64667f0 100644
--- a/thread_none.h
+++ b/thread_none.h
@@ -16,6 +16,5 @@ struct rb_thread_sched_item {};
struct rb_thread_sched {};
RUBY_EXTERN struct rb_execution_context_struct *ruby_current_ec;
-NOINLINE(struct rb_execution_context_struct *rb_current_ec_noinline(void)); // for assertions
#endif /* RUBY_THREAD_NONE_H */
diff --git a/thread_pthread.c b/thread_pthread.c
index 82a255d030..aa5435aa99 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -11,8 +11,8 @@
#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
-#include "internal/gc.h"
-#include "rjit.h"
+#include "gc.h"
+#include "mjit.h"
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
@@ -51,264 +51,236 @@
# define USE_EVENTFD (0)
#endif
-#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
- defined(CLOCK_REALTIME) && defined(CLOCK_MONOTONIC) && \
- defined(HAVE_CLOCK_GETTIME)
-static pthread_condattr_t condattr_mono;
-static pthread_condattr_t *condattr_monotonic = &condattr_mono;
-#else
-static const void *const condattr_monotonic = NULL;
+#if defined(SIGVTALRM) && !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__)
+# define USE_UBF_LIST 1
#endif
-#include COROUTINE_H
-
-#ifndef HAVE_SYS_EVENT_H
-#define HAVE_SYS_EVENT_H 0
+/*
+ * UBF_TIMER and ubf_list both use SIGVTALRM.
+ *
+ * UBF_TIMER has NOTHING to do with thread timeslices (TIMER_INTERRUPT_MASK)
+ *
+ * UBF_TIMER is to close TOCTTOU signal race on programs where we
+ * cannot rely on GVL contention (vm->gvl.timer) to perform wakeups
+ * while a thread is doing blocking I/O on sockets or pipes. With
+ * rb_thread_call_without_gvl and similar functions:
+ *
+ * (1) Check interrupts.
+ * (2) release GVL.
+ * (2a) signal received
+ * (3) call func with data1 (blocks for a long time without ubf_timer)
+ * (4) acquire GVL.
+ * Other Ruby threads can not run in parallel any more.
+ * (5) Check interrupts.
+ *
+ * We need UBF_TIMER to break out of (3) if (2a) happens.
+ *
+ * ubf_list wakeups may be triggered on gvl_yield.
+ *
+ * If we have vm->gvl.timer (on GVL contention), we don't need UBF_TIMER
+ * as it can perform the same tasks while doing timeslices.
+ */
+#define UBF_TIMER_NONE 0
+#define UBF_TIMER_POSIX 1
+#define UBF_TIMER_PTHREAD 2
+
+#ifndef UBF_TIMER
+# if defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_CREATE) && \
+ defined(CLOCK_MONOTONIC) && defined(USE_UBF_LIST)
+ /* preferred */
+# define UBF_TIMER UBF_TIMER_POSIX
+# elif defined(USE_UBF_LIST)
+ /* safe, but inefficient */
+# define UBF_TIMER UBF_TIMER_PTHREAD
+# else
+ /* we'll be racy without SIGVTALRM for ubf_list */
+# define UBF_TIMER UBF_TIMER_NONE
+# endif
#endif
-#ifndef HAVE_SYS_EPOLL_H
-#define HAVE_SYS_EPOLL_H 0
-#else
-// force setting for debug
-// #undef HAVE_SYS_EPOLL_H
-// #define HAVE_SYS_EPOLL_H 0
-#endif
+struct rb_internal_thread_event_hook {
+ rb_internal_thread_event_callback callback;
+ rb_event_flag_t event;
+ void *user_data;
-#ifndef USE_MN_THREADS
- #if defined(__EMSCRIPTEN__) || defined(COROUTINE_PTHREAD_CONTEXT)
- // on __EMSCRIPTEN__ provides epoll* declarations, but no implementations.
- // on COROUTINE_PTHREAD_CONTEXT, it doesn't worth to use it.
- #define USE_MN_THREADS 0
- #elif HAVE_SYS_EPOLL_H
- #include <sys/epoll.h>
- #define USE_MN_THREADS 1
- #elif HAVE_SYS_EVENT_H
- #include <sys/event.h>
- #define USE_MN_THREADS 1
- #else
- #define USE_MN_THREADS 0
- #endif
-#endif
+ struct rb_internal_thread_event_hook *next;
+};
-// native thread wrappers
+static rb_internal_thread_event_hook_t *rb_internal_thread_event_hooks = NULL;
+static pthread_rwlock_t rb_internal_thread_event_hooks_rw_lock = PTHREAD_RWLOCK_INITIALIZER;
-#define NATIVE_MUTEX_LOCK_DEBUG 0
+#define RB_INTERNAL_THREAD_HOOK(event) if (rb_internal_thread_event_hooks) { rb_thread_execute_hooks(event); }
-static void
-mutex_debug(const char *msg, void *lock)
+rb_internal_thread_event_hook_t *
+rb_internal_thread_add_event_hook(rb_internal_thread_event_callback callback, rb_event_flag_t internal_event, void *user_data)
{
- if (NATIVE_MUTEX_LOCK_DEBUG) {
- int r;
- static pthread_mutex_t dbglock = PTHREAD_MUTEX_INITIALIZER;
-
- if ((r = pthread_mutex_lock(&dbglock)) != 0) {exit(EXIT_FAILURE);}
- fprintf(stdout, "%s: %p\n", msg, lock);
- if ((r = pthread_mutex_unlock(&dbglock)) != 0) {exit(EXIT_FAILURE);}
- }
-}
+ rb_internal_thread_event_hook_t *hook = ALLOC_N(rb_internal_thread_event_hook_t, 1);
+ hook->callback = callback;
+ hook->user_data = user_data;
+ hook->event = internal_event;
-void
-rb_native_mutex_lock(pthread_mutex_t *lock)
-{
int r;
- mutex_debug("lock", lock);
- if ((r = pthread_mutex_lock(lock)) != 0) {
- rb_bug_errno("pthread_mutex_lock", r);
+ if ((r = pthread_rwlock_wrlock(&rb_internal_thread_event_hooks_rw_lock))) {
+ rb_bug_errno("pthread_rwlock_wrlock", r);
}
-}
-void
-rb_native_mutex_unlock(pthread_mutex_t *lock)
-{
- int r;
- mutex_debug("unlock", lock);
- if ((r = pthread_mutex_unlock(lock)) != 0) {
- rb_bug_errno("pthread_mutex_unlock", r);
+ hook->next = rb_internal_thread_event_hooks;
+ ATOMIC_PTR_EXCHANGE(rb_internal_thread_event_hooks, hook);
+
+ if ((r = pthread_rwlock_unlock(&rb_internal_thread_event_hooks_rw_lock))) {
+ rb_bug_errno("pthread_rwlock_unlock", r);
}
+ return hook;
}
-int
-rb_native_mutex_trylock(pthread_mutex_t *lock)
+bool
+rb_internal_thread_remove_event_hook(rb_internal_thread_event_hook_t * hook)
{
int r;
- mutex_debug("trylock", lock);
- if ((r = pthread_mutex_trylock(lock)) != 0) {
- if (r == EBUSY) {
- return EBUSY;
- }
- else {
- rb_bug_errno("pthread_mutex_trylock", r);
- }
+ if ((r = pthread_rwlock_wrlock(&rb_internal_thread_event_hooks_rw_lock))) {
+ rb_bug_errno("pthread_rwlock_wrlock", r);
}
- return 0;
-}
-void
-rb_native_mutex_initialize(pthread_mutex_t *lock)
-{
- int r = pthread_mutex_init(lock, 0);
- mutex_debug("init", lock);
- if (r != 0) {
- rb_bug_errno("pthread_mutex_init", r);
- }
-}
+ bool success = FALSE;
-void
-rb_native_mutex_destroy(pthread_mutex_t *lock)
-{
- int r = pthread_mutex_destroy(lock);
- mutex_debug("destroy", lock);
- if (r != 0) {
- rb_bug_errno("pthread_mutex_destroy", r);
+ if (rb_internal_thread_event_hooks == hook) {
+ ATOMIC_PTR_EXCHANGE(rb_internal_thread_event_hooks, hook->next);
+ success = TRUE;
}
-}
+ else {
+ rb_internal_thread_event_hook_t *h = rb_internal_thread_event_hooks;
-void
-rb_native_cond_initialize(rb_nativethread_cond_t *cond)
-{
- int r = pthread_cond_init(cond, condattr_monotonic);
- if (r != 0) {
- rb_bug_errno("pthread_cond_init", r);
+ do {
+ if (h->next == hook) {
+ h->next = hook->next;
+ success = TRUE;
+ break;
+ }
+ } while ((h = h->next));
}
-}
-void
-rb_native_cond_destroy(rb_nativethread_cond_t *cond)
-{
- int r = pthread_cond_destroy(cond);
- if (r != 0) {
- rb_bug_errno("pthread_cond_destroy", r);
+ if ((r = pthread_rwlock_unlock(&rb_internal_thread_event_hooks_rw_lock))) {
+ rb_bug_errno("pthread_rwlock_unlock", r);
}
-}
-
-/*
- * In OS X 10.7 (Lion), pthread_cond_signal and pthread_cond_broadcast return
- * EAGAIN after retrying 8192 times. You can see them in the following page:
- *
- * http://www.opensource.apple.com/source/Libc/Libc-763.11/pthreads/pthread_cond.c
- *
- * The following rb_native_cond_signal and rb_native_cond_broadcast functions
- * need to retrying until pthread functions don't return EAGAIN.
- */
-void
-rb_native_cond_signal(rb_nativethread_cond_t *cond)
-{
- int r;
- do {
- r = pthread_cond_signal(cond);
- } while (r == EAGAIN);
- if (r != 0) {
- rb_bug_errno("pthread_cond_signal", r);
+ if (success) {
+ ruby_xfree(hook);
}
+ return success;
}
-void
-rb_native_cond_broadcast(rb_nativethread_cond_t *cond)
+static void
+rb_thread_execute_hooks(rb_event_flag_t event)
{
int r;
- do {
- r = pthread_cond_broadcast(cond);
- } while (r == EAGAIN);
- if (r != 0) {
- rb_bug_errno("rb_native_cond_broadcast", r);
+ if ((r = pthread_rwlock_rdlock(&rb_internal_thread_event_hooks_rw_lock))) {
+ rb_bug_errno("pthread_rwlock_rdlock", r);
}
-}
-void
-rb_native_cond_wait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex)
-{
- int r = pthread_cond_wait(cond, mutex);
- if (r != 0) {
- rb_bug_errno("pthread_cond_wait", r);
+ if (rb_internal_thread_event_hooks) {
+ rb_internal_thread_event_hook_t *h = rb_internal_thread_event_hooks;
+ do {
+ if (h->event & event) {
+ (*h->callback)(event, NULL, h->user_data);
+ }
+ } while((h = h->next));
+ }
+ if ((r = pthread_rwlock_unlock(&rb_internal_thread_event_hooks_rw_lock))) {
+ rb_bug_errno("pthread_rwlock_unlock", r);
}
}
-static int
-native_cond_timedwait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex, const rb_hrtime_t *abs)
-{
- int r;
- struct timespec ts;
+enum rtimer_state {
+ /* alive, after timer_create: */
+ RTIMER_DISARM,
+ RTIMER_ARMING,
+ RTIMER_ARMED,
- /*
- * An old Linux may return EINTR. Even though POSIX says
- * "These functions shall not return an error code of [EINTR]".
- * http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html
- * Let's hide it from arch generic code.
- */
- do {
- rb_hrtime2timespec(&ts, abs);
- r = pthread_cond_timedwait(cond, mutex, &ts);
- } while (r == EINTR);
+ RTIMER_DEAD
+};
- if (r != 0 && r != ETIMEDOUT) {
- rb_bug_errno("pthread_cond_timedwait", r);
- }
+#if UBF_TIMER == UBF_TIMER_POSIX
+static const struct itimerspec zero;
+static struct {
+ rb_atomic_t state_; /* rtimer_state */
+ rb_pid_t owner;
+ timer_t timerid;
+} timer_posix = {
+ /* .state = */ RTIMER_DEAD,
+};
- return r;
-}
+#define TIMER_STATE_DEBUG 0
-static rb_hrtime_t
-native_cond_timeout(rb_nativethread_cond_t *cond, const rb_hrtime_t rel)
+static const char *
+rtimer_state_name(enum rtimer_state state)
{
- if (condattr_monotonic) {
- return rb_hrtime_add(rb_hrtime_now(), rel);
- }
- else {
- struct timespec ts;
-
- rb_timespec_now(&ts);
- return rb_hrtime_add(rb_timespec2hrtime(&ts), rel);
+ switch (state) {
+ case RTIMER_DISARM: return "disarm";
+ case RTIMER_ARMING: return "arming";
+ case RTIMER_ARMED: return "armed";
+ case RTIMER_DEAD: return "dead";
+ default: rb_bug("unreachable");
}
}
-void
-rb_native_cond_timedwait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex, unsigned long msec)
+static enum rtimer_state
+timer_state_exchange(enum rtimer_state state)
{
- rb_hrtime_t hrmsec = native_cond_timeout(cond, RB_HRTIME_PER_MSEC * msec);
- native_cond_timedwait(cond, mutex, &hrmsec);
+ enum rtimer_state prev = ATOMIC_EXCHANGE(timer_posix.state_, state);
+ if (TIMER_STATE_DEBUG) fprintf(stderr, "state (exc): %s->%s\n", rtimer_state_name(prev), rtimer_state_name(state));
+ return prev;
}
-// thread scheduling
-
-static rb_internal_thread_event_hook_t *rb_internal_thread_event_hooks = NULL;
-static void rb_thread_execute_hooks(rb_event_flag_t event, rb_thread_t *th);
-
-#if 0
-static const char *
-event_name(rb_event_flag_t event)
+static enum rtimer_state
+timer_state_cas(enum rtimer_state expected_prev, enum rtimer_state state)
{
- switch (event) {
- case RUBY_INTERNAL_THREAD_EVENT_STARTED:
- return "STARTED";
- case RUBY_INTERNAL_THREAD_EVENT_READY:
- return "READY";
- case RUBY_INTERNAL_THREAD_EVENT_RESUMED:
- return "RESUMED";
- case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED:
- return "SUSPENDED";
- case RUBY_INTERNAL_THREAD_EVENT_EXITED:
- return "EXITED";
- }
- return "no-event";
-}
+ enum rtimer_state prev = ATOMIC_CAS(timer_posix.state_, expected_prev, state);
-#define RB_INTERNAL_THREAD_HOOK(event, th) \
- if (UNLIKELY(rb_internal_thread_event_hooks)) { \
- fprintf(stderr, "[thread=%"PRIxVALUE"] %s in %s (%s:%d)\n", th->self, event_name(event), __func__, __FILE__, __LINE__); \
- rb_thread_execute_hooks(event, th); \
+ if (TIMER_STATE_DEBUG) {
+ if (prev == expected_prev) {
+ fprintf(stderr, "state (cas): %s->%s\n", rtimer_state_name(prev), rtimer_state_name(state));
+ }
+ else {
+ fprintf(stderr, "state (cas): %s (expected:%s)\n", rtimer_state_name(prev), rtimer_state_name(expected_prev));
+ }
}
-#else
-#define RB_INTERNAL_THREAD_HOOK(event, th) if (UNLIKELY(rb_internal_thread_event_hooks)) { rb_thread_execute_hooks(event, th); }
-#endif
-static rb_serial_t current_fork_gen = 1; /* We can't use GET_VM()->fork_gen */
+ return prev;
+}
-#if defined(SIGVTALRM) && !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__)
-# define USE_UBF_LIST 1
+#elif UBF_TIMER == UBF_TIMER_PTHREAD
+static void *timer_pthread_fn(void *);
+static struct {
+ int low[2];
+ rb_atomic_t armed; /* boolean */
+ rb_pid_t owner;
+ pthread_t thid;
+} timer_pthread = {
+ { -1, -1 },
+};
#endif
+static const rb_hrtime_t *sigwait_timeout(rb_thread_t *, int sigwait_fd,
+ const rb_hrtime_t *,
+ int *drained_p);
+static void ubf_timer_disarm(void);
static void threadptr_trap_interrupt(rb_thread_t *);
+static void ubf_wakeup_all_threads(void);
+static int ubf_threads_empty(void);
+
+#define TIMER_THREAD_CREATED_P() (signal_self_pipe.owner_process == getpid())
+
+/* for testing, and in case we come across a platform w/o pipes: */
+#define BUSY_WAIT_SIGNALS (0)
+
+/*
+ * sigwait_th is the thread which owns sigwait_fd and sleeps on it
+ * (using ppoll). MJIT worker can be sigwait_th==0, so we initialize
+ * it to THREAD_INVALID at startup and fork time. It is the ONLY thread
+ * allowed to read from sigwait_fd, otherwise starvation can occur.
+ */
+#define THREAD_INVALID ((const rb_thread_t *)-1)
+static const rb_thread_t *sigwait_th;
#ifdef HAVE_SCHED_YIELD
#define native_thread_yield() (void)sched_yield()
@@ -316,6 +288,15 @@ static void threadptr_trap_interrupt(rb_thread_t *);
#define native_thread_yield() ((void)0)
#endif
+#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
+ defined(CLOCK_REALTIME) && defined(CLOCK_MONOTONIC) && \
+ defined(HAVE_CLOCK_GETTIME)
+static pthread_condattr_t condattr_mono;
+static pthread_condattr_t *condattr_monotonic = &condattr_mono;
+#else
+static const void *const condattr_monotonic = NULL;
+#endif
+
/* 100ms. 10ms is too small for user level thread scheduling
* on recent Linux (tested on 2.6.35)
*/
@@ -323,1240 +304,414 @@ static void threadptr_trap_interrupt(rb_thread_t *);
#define TIME_QUANTUM_USEC (TIME_QUANTUM_MSEC * 1000)
#define TIME_QUANTUM_NSEC (TIME_QUANTUM_USEC * 1000)
-static void native_thread_dedicated_inc(rb_vm_t *vm, rb_ractor_t *cr, struct rb_native_thread *nt);
-static void native_thread_dedicated_dec(rb_vm_t *vm, rb_ractor_t *cr, struct rb_native_thread *nt);
-static void native_thread_assign(struct rb_native_thread *nt, rb_thread_t *th);
-
-static void ractor_sched_enq(rb_vm_t *vm, rb_ractor_t *r);
-static void timer_thread_wakeup(void);
-static void timer_thread_wakeup_locked(rb_vm_t *vm);
-static void timer_thread_wakeup_force(void);
-static void thread_sched_switch(rb_thread_t *cth, rb_thread_t *next_th);
-
-#define thread_sched_dump(s) thread_sched_dump_(__FILE__, __LINE__, s)
-
-static bool
-th_has_dedicated_nt(const rb_thread_t *th)
-{
- // TODO: th->has_dedicated_nt
- return th->nt->dedicated > 0;
-}
-
-RBIMPL_ATTR_MAYBE_UNUSED()
-static void
-thread_sched_dump_(const char *file, int line, struct rb_thread_sched *sched)
-{
- fprintf(stderr, "@%s:%d running:%d\n", file, line, sched->running ? (int)sched->running->serial : -1);
- rb_thread_t *th;
- int i = 0;
- ccan_list_for_each(&sched->readyq, th, sched.node.readyq) {
- i++; if (i>10) rb_bug("too many");
- fprintf(stderr, " ready:%d (%sNT:%d)\n", th->serial,
- th->nt ? (th->nt->dedicated ? "D" : "S") : "x",
- th->nt ? (int)th->nt->serial : -1);
- }
-}
-
-#define ractor_sched_dump(s) ractor_sched_dump_(__FILE__, __LINE__, s)
-
-RBIMPL_ATTR_MAYBE_UNUSED()
-static void
-ractor_sched_dump_(const char *file, int line, rb_vm_t *vm)
-{
- rb_ractor_t *r;
-
- fprintf(stderr, "ractor_sched_dump %s:%d\n", file, line);
+static rb_hrtime_t native_cond_timeout(rb_nativethread_cond_t *, rb_hrtime_t);
+static int native_cond_timedwait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex, const rb_hrtime_t *abs);
- int i = 0;
- ccan_list_for_each(&vm->ractor.sched.grq, r, threads.sched.grq_node) {
- i++;
- if (i>10) rb_bug("!!");
- fprintf(stderr, " %d ready:%d\n", i, rb_ractor_id(r));
- }
-}
-
-#define thread_sched_lock(a, b) thread_sched_lock_(a, b, __FILE__, __LINE__)
-#define thread_sched_unlock(a, b) thread_sched_unlock_(a, b, __FILE__, __LINE__)
-
-static void
-thread_sched_lock_(struct rb_thread_sched *sched, rb_thread_t *th, const char *file, int line)
-{
- rb_native_mutex_lock(&sched->lock_);
-
-#if VM_CHECK_MODE
- RUBY_DEBUG_LOG2(file, line, "th:%u prev_owner:%u", rb_th_serial(th), rb_th_serial(sched->lock_owner));
- VM_ASSERT(sched->lock_owner == NULL);
- sched->lock_owner = th;
-#else
- RUBY_DEBUG_LOG2(file, line, "th:%u", rb_th_serial(th));
-#endif
-}
-
-static void
-thread_sched_unlock_(struct rb_thread_sched *sched, rb_thread_t *th, const char *file, int line)
-{
- RUBY_DEBUG_LOG2(file, line, "th:%u", rb_th_serial(th));
-
-#if VM_CHECK_MODE
- VM_ASSERT(sched->lock_owner == th);
- sched->lock_owner = NULL;
-#endif
-
- rb_native_mutex_unlock(&sched->lock_);
-}
-
-static void
-thread_sched_set_lock_owner(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
-
-#if VM_CHECK_MODE > 0
- sched->lock_owner = th;
-#endif
-}
-
-static void
-ASSERT_thread_sched_locked(struct rb_thread_sched *sched, rb_thread_t *th)
+/*
+ * Designate the next sched.timer thread, favor the last thread in
+ * the readyq since it will be in readyq longest
+ */
+static int
+designate_timer_thread(struct rb_thread_sched *sched)
{
- VM_ASSERT(rb_native_mutex_trylock(&sched->lock_) == EBUSY);
-
-#if VM_CHECK_MODE
- if (th) {
- VM_ASSERT(sched->lock_owner == th);
- }
- else {
- VM_ASSERT(sched->lock_owner != NULL);
- }
-#endif
-}
+ rb_thread_t *last;
-#define ractor_sched_lock(a, b) ractor_sched_lock_(a, b, __FILE__, __LINE__)
-#define ractor_sched_unlock(a, b) ractor_sched_unlock_(a, b, __FILE__, __LINE__)
+ last = ccan_list_tail(&sched->readyq, rb_thread_t, sched.node.readyq);
-RBIMPL_ATTR_MAYBE_UNUSED()
-static unsigned int
-rb_ractor_serial(const rb_ractor_t *r) {
- if (r) {
- return rb_ractor_id(r);
+ if (last) {
+ rb_native_cond_signal(&last->nt->cond.readyq);
+ return TRUE;
}
else {
- return 0;
+ return FALSE;
}
}
+/*
+ * We become designated timer thread to kick vm->gvl.owner
+ * periodically. Continue on old timeout if it expired.
+ */
static void
-ractor_sched_set_locked(rb_vm_t *vm, rb_ractor_t *cr)
-{
-#if VM_CHECK_MODE > 0
- VM_ASSERT(vm->ractor.sched.lock_owner == NULL);
- VM_ASSERT(vm->ractor.sched.locked == false);
-
- vm->ractor.sched.lock_owner = cr;
- vm->ractor.sched.locked = true;
-#endif
-}
-
-static void
-ractor_sched_set_unlocked(rb_vm_t *vm, rb_ractor_t *cr)
-{
-#if VM_CHECK_MODE > 0
- VM_ASSERT(vm->ractor.sched.locked);
- VM_ASSERT(vm->ractor.sched.lock_owner == cr);
-
- vm->ractor.sched.locked = false;
- vm->ractor.sched.lock_owner = NULL;
-#endif
-}
-
-static void
-ractor_sched_lock_(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line)
-{
- rb_native_mutex_lock(&vm->ractor.sched.lock);
-
-#if VM_CHECK_MODE
- RUBY_DEBUG_LOG2(file, line, "cr:%u prev_owner:%u", rb_ractor_serial(cr), rb_ractor_serial(vm->ractor.sched.lock_owner));
-#else
- RUBY_DEBUG_LOG2(file, line, "cr:%u", rb_ractor_serial(cr));
-#endif
-
- ractor_sched_set_locked(vm, cr);
-}
-
-static void
-ractor_sched_unlock_(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line)
-{
- RUBY_DEBUG_LOG2(file, line, "cr:%u", rb_ractor_serial(cr));
-
- ractor_sched_set_unlocked(vm, cr);
- rb_native_mutex_unlock(&vm->ractor.sched.lock);
-}
-
-static void
-ASSERT_ractor_sched_locked(rb_vm_t *vm, rb_ractor_t *cr)
-{
- VM_ASSERT(rb_native_mutex_trylock(&vm->ractor.sched.lock) == EBUSY);
- VM_ASSERT(vm->ractor.sched.locked);
- VM_ASSERT(cr == NULL || vm->ractor.sched.lock_owner == cr);
-}
-
-RBIMPL_ATTR_MAYBE_UNUSED()
-static bool
-ractor_sched_running_threads_contain_p(rb_vm_t *vm, rb_thread_t *th)
+do_gvl_timer(struct rb_thread_sched *sched, rb_thread_t *th)
{
- rb_thread_t *rth;
- ccan_list_for_each(&vm->ractor.sched.running_threads, rth, sched.node.running_threads) {
- if (rth == th) return true;
- }
- return false;
-}
+ rb_vm_t *vm = GET_VM();
+ static rb_hrtime_t abs;
-RBIMPL_ATTR_MAYBE_UNUSED()
-static unsigned int
-ractor_sched_running_threads_size(rb_vm_t *vm)
-{
- rb_thread_t *th;
- unsigned int i = 0;
- ccan_list_for_each(&vm->ractor.sched.running_threads, th, sched.node.running_threads) {
- i++;
- }
- return i;
-}
+ sched->timer = th;
-RBIMPL_ATTR_MAYBE_UNUSED()
-static unsigned int
-ractor_sched_timeslice_threads_size(rb_vm_t *vm)
-{
- rb_thread_t *th;
- unsigned int i = 0;
- ccan_list_for_each(&vm->ractor.sched.timeslice_threads, th, sched.node.timeslice_threads) {
- i++;
- }
- return i;
-}
+ /* take over wakeups from UBF_TIMER */
+ ubf_timer_disarm();
-RBIMPL_ATTR_MAYBE_UNUSED()
-static bool
-ractor_sched_timeslice_threads_contain_p(rb_vm_t *vm, rb_thread_t *th)
-{
- rb_thread_t *rth;
- ccan_list_for_each(&vm->ractor.sched.timeslice_threads, rth, sched.node.timeslice_threads) {
- if (rth == th) return true;
+ if (sched->timer_err == ETIMEDOUT) {
+ abs = native_cond_timeout(&th->nt->cond.readyq, TIME_QUANTUM_NSEC);
}
- return false;
-}
+ sched->timer_err = native_cond_timedwait(&th->nt->cond.readyq, &sched->lock, &abs);
-static void ractor_sched_barrier_join_signal_locked(rb_vm_t *vm);
-static void ractor_sched_barrier_join_wait_locked(rb_vm_t *vm, rb_thread_t *th);
+ ubf_wakeup_all_threads();
+ ruby_sigchld_handler(vm);
-// setup timeslice signals by the timer thread.
-static void
-thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *cr, rb_vm_t *vm,
- rb_thread_t *add_th, rb_thread_t *del_th, rb_thread_t *add_timeslice_th)
-{
-#if USE_RUBY_DEBUG_LOG
- unsigned int prev_running_cnt = vm->ractor.sched.running_cnt;
-#endif
-
- rb_thread_t *del_timeslice_th;
-
- if (del_th && sched->is_running_timeslice) {
- del_timeslice_th = del_th;
- sched->is_running_timeslice = false;
- }
- else {
- del_timeslice_th = NULL;
- }
-
- RUBY_DEBUG_LOG("+:%u -:%u +ts:%u -ts:%u",
- rb_th_serial(add_th), rb_th_serial(del_th),
- rb_th_serial(add_timeslice_th), rb_th_serial(del_timeslice_th));
-
- ractor_sched_lock(vm, cr);
- {
- // update running_threads
- if (del_th) {
- VM_ASSERT(ractor_sched_running_threads_contain_p(vm, del_th));
- VM_ASSERT(del_timeslice_th != NULL ||
- !ractor_sched_timeslice_threads_contain_p(vm, del_th));
-
- ccan_list_del_init(&del_th->sched.node.running_threads);
- vm->ractor.sched.running_cnt--;
-
- if (UNLIKELY(vm->ractor.sched.barrier_waiting)) {
- ractor_sched_barrier_join_signal_locked(vm);
- }
- sched->is_running = false;
- }
-
- if (add_th) {
- if (UNLIKELY(vm->ractor.sched.barrier_waiting)) {
- RUBY_DEBUG_LOG("barrier-wait");
-
- ractor_sched_barrier_join_signal_locked(vm);
- ractor_sched_barrier_join_wait_locked(vm, add_th);
- }
-
- VM_ASSERT(!ractor_sched_running_threads_contain_p(vm, add_th));
- VM_ASSERT(!ractor_sched_timeslice_threads_contain_p(vm, add_th));
-
- ccan_list_add(&vm->ractor.sched.running_threads, &add_th->sched.node.running_threads);
- vm->ractor.sched.running_cnt++;
- sched->is_running = true;
- }
-
- if (add_timeslice_th) {
- // update timeslice threads
- int was_empty = ccan_list_empty(&vm->ractor.sched.timeslice_threads);
- VM_ASSERT(!ractor_sched_timeslice_threads_contain_p(vm, add_timeslice_th));
- ccan_list_add(&vm->ractor.sched.timeslice_threads, &add_timeslice_th->sched.node.timeslice_threads);
- sched->is_running_timeslice = true;
- if (was_empty) {
- timer_thread_wakeup_locked(vm);
- }
- }
-
- if (del_timeslice_th) {
- VM_ASSERT(ractor_sched_timeslice_threads_contain_p(vm, del_timeslice_th));
- ccan_list_del_init(&del_timeslice_th->sched.node.timeslice_threads);
+ if (UNLIKELY(rb_signal_buff_size())) {
+ if (th == vm->ractor.main_thread) {
+ RUBY_VM_SET_TRAP_INTERRUPT(th->ec);
}
-
- VM_ASSERT(ractor_sched_running_threads_size(vm) == vm->ractor.sched.running_cnt);
- VM_ASSERT(ractor_sched_timeslice_threads_size(vm) <= vm->ractor.sched.running_cnt);
- }
- ractor_sched_unlock(vm, cr);
-
- if (add_th && !del_th && UNLIKELY(vm->ractor.sync.lock_owner != NULL)) {
- // it can be after barrier synchronization by another ractor
- rb_thread_t *lock_owner = NULL;
-#if VM_CHECK_MODE
- lock_owner = sched->lock_owner;
-#endif
- thread_sched_unlock(sched, lock_owner);
- {
- RB_VM_LOCK_ENTER();
- RB_VM_LOCK_LEAVE();
+ else {
+ threadptr_trap_interrupt(vm->ractor.main_thread);
}
- thread_sched_lock(sched, lock_owner);
- }
-
- //RUBY_DEBUG_LOG("+:%u -:%u +ts:%u -ts:%u run:%u->%u",
- // rb_th_serial(add_th), rb_th_serial(del_th),
- // rb_th_serial(add_timeslice_th), rb_th_serial(del_timeslice_th),
- RUBY_DEBUG_LOG("run:%u->%u", prev_running_cnt, vm->ractor.sched.running_cnt);
-}
-
-static void
-thread_sched_add_running_thread(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- ASSERT_thread_sched_locked(sched, th);
- VM_ASSERT(sched->running == th);
-
- rb_vm_t *vm = th->vm;
- thread_sched_setup_running_threads(sched, th->ractor, vm, th, NULL, ccan_list_empty(&sched->readyq) ? NULL : th);
-}
-
-static void
-thread_sched_del_running_thread(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- ASSERT_thread_sched_locked(sched, th);
-
- rb_vm_t *vm = th->vm;
- thread_sched_setup_running_threads(sched, th->ractor, vm, NULL, th, NULL);
-}
-
-void
-rb_add_running_thread(rb_thread_t *th)
-{
- struct rb_thread_sched *sched = TH_SCHED(th);
-
- thread_sched_lock(sched, th);
- {
- thread_sched_add_running_thread(sched, th);
}
- thread_sched_unlock(sched, th);
-}
-
-void
-rb_del_running_thread(rb_thread_t *th)
-{
- struct rb_thread_sched *sched = TH_SCHED(th);
- thread_sched_lock(sched, th);
- {
- thread_sched_del_running_thread(sched, th);
+ /*
+ * Timeslice. Warning: the process may fork while this
+ * thread is contending for GVL:
+ */
+ const rb_thread_t *running;
+ if ((running = sched->running) != 0) {
+ // strictly speaking, accessing "running" is not thread-safe
+ RUBY_VM_SET_TIMER_INTERRUPT(running->ec);
}
- thread_sched_unlock(sched, th);
+ sched->timer = 0;
}
-// setup current or next running thread
-// sched->running should be set only on this function.
-//
-// if th is NULL, there is no running threads.
static void
-thread_sched_set_running(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- RUBY_DEBUG_LOG("th:%u->th:%u", rb_th_serial(sched->running), rb_th_serial(th));
- VM_ASSERT(sched->running != th);
-
- sched->running = th;
-}
-
-RBIMPL_ATTR_MAYBE_UNUSED()
-static bool
-thread_sched_readyq_contain_p(struct rb_thread_sched *sched, rb_thread_t *th)
+thread_sched_to_ready_common(struct rb_thread_sched *sched, rb_thread_t *th)
{
- rb_thread_t *rth;
- ccan_list_for_each(&sched->readyq, rth, sched.node.readyq) {
- if (rth == th) return true;
- }
- return false;
-}
-
-// deque thread from the ready queue.
-// if the ready queue is empty, return NULL.
-//
-// return deque'ed running thread (or NULL).
-static rb_thread_t *
-thread_sched_deq(struct rb_thread_sched *sched)
-{
- ASSERT_thread_sched_locked(sched, NULL);
- rb_thread_t *next_th;
-
- VM_ASSERT(sched->running != NULL);
-
- if (ccan_list_empty(&sched->readyq)) {
- next_th = NULL;
- }
- else {
- next_th = ccan_list_pop(&sched->readyq, rb_thread_t, sched.node.readyq);
-
- VM_ASSERT(sched->readyq_cnt > 0);
- sched->readyq_cnt--;
- ccan_list_node_init(&next_th->sched.node.readyq);
- }
-
- RUBY_DEBUG_LOG("next_th:%u readyq_cnt:%d", rb_th_serial(next_th), sched->readyq_cnt);
-
- return next_th;
+ ccan_list_add_tail(&sched->readyq, &th->sched.node.readyq);
}
-// enqueue ready thread to the ready queue.
static void
-thread_sched_enq(struct rb_thread_sched *sched, rb_thread_t *ready_th)
+thread_sched_to_running_common(struct rb_thread_sched *sched, rb_thread_t *th)
{
- ASSERT_thread_sched_locked(sched, NULL);
- RUBY_DEBUG_LOG("ready_th:%u readyq_cnt:%d", rb_th_serial(ready_th), sched->readyq_cnt);
-
- VM_ASSERT(sched->running != NULL);
- VM_ASSERT(!thread_sched_readyq_contain_p(sched, ready_th));
-
- if (sched->is_running) {
- if (ccan_list_empty(&sched->readyq)) {
- // add sched->running to timeslice
- thread_sched_setup_running_threads(sched, ready_th->ractor, ready_th->vm, NULL, NULL, sched->running);
- }
- }
- else {
- VM_ASSERT(!ractor_sched_timeslice_threads_contain_p(ready_th->vm, sched->running));
- }
-
- ccan_list_add_tail(&sched->readyq, &ready_th->sched.node.readyq);
- sched->readyq_cnt++;
-}
+ RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_READY);
+ if (sched->running) {
+ VM_ASSERT(th->unblock.func == 0 &&
+ "we must not be in ubf_list and GVL readyq at the same time");
-// DNT: kick condvar
-// SNT: TODO
-static void
-thread_sched_wakeup_running_thread(struct rb_thread_sched *sched, rb_thread_t *next_th, bool will_switch)
-{
- ASSERT_thread_sched_locked(sched, NULL);
- VM_ASSERT(sched->running == next_th);
+ // waiting -> ready
+ thread_sched_to_ready_common(sched, th);
- if (next_th) {
- if (next_th->nt) {
- if (th_has_dedicated_nt(next_th)) {
- RUBY_DEBUG_LOG("pinning th:%u", next_th->serial);
- rb_native_cond_signal(&next_th->nt->cond.readyq);
- }
- else {
- // TODO
- RUBY_DEBUG_LOG("th:%u is already running.", next_th->serial);
- }
- }
- else {
- if (will_switch) {
- RUBY_DEBUG_LOG("th:%u (do nothing)", rb_th_serial(next_th));
+ // wait for running chance
+ do {
+ if (!sched->timer) {
+ do_gvl_timer(sched, th);
}
else {
- RUBY_DEBUG_LOG("th:%u (enq)", rb_th_serial(next_th));
- ractor_sched_enq(next_th->vm, next_th->ractor);
+ rb_native_cond_wait(&th->nt->cond.readyq, &sched->lock);
}
- }
- }
- else {
- RUBY_DEBUG_LOG("no waiting threads%s", "");
- }
-}
-
-// waiting -> ready (locked)
-static void
-thread_sched_to_ready_common(struct rb_thread_sched *sched, rb_thread_t *th, bool wakeup, bool will_switch)
-{
- RUBY_DEBUG_LOG("th:%u running:%u redyq_cnt:%d", rb_th_serial(th), rb_th_serial(sched->running), sched->readyq_cnt);
+ } while (sched->running);
- VM_ASSERT(sched->running != th);
- VM_ASSERT(!thread_sched_readyq_contain_p(sched, th));
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_READY, th);
+ ccan_list_del_init(&th->sched.node.readyq);
- if (sched->running == NULL) {
- thread_sched_set_running(sched, th);
- if (wakeup) thread_sched_wakeup_running_thread(sched, th, will_switch);
- }
- else {
- thread_sched_enq(sched, th);
+ if (sched->need_yield) {
+ sched->need_yield = 0;
+ rb_native_cond_signal(&sched->switch_cond);
+ }
}
-}
-
-// waiting -> ready
-//
-// `th` had became "waiting" state by `thread_sched_to_waiting`
-// and `thread_sched_to_ready` enqueue `th` to the thread ready queue.
-RBIMPL_ATTR_MAYBE_UNUSED()
-static void
-thread_sched_to_ready(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
-
- thread_sched_lock(sched, th);
- {
- thread_sched_to_ready_common(sched, th, true, false);
+ else { /* reset timer if uncontended */
+ sched->timer_err = ETIMEDOUT;
}
- thread_sched_unlock(sched, th);
-}
-
-// wait until sched->running is `th`.
-static void
-thread_sched_wait_running_turn(struct rb_thread_sched *sched, rb_thread_t *th, bool can_direct_transfer)
-{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
-
- ASSERT_thread_sched_locked(sched, th);
- VM_ASSERT(th == GET_THREAD());
-
- if (th != sched->running) {
- // already deleted from running threads
- // VM_ASSERT(!ractor_sched_running_threads_contain_p(th->vm, th)); // need locking
- // wait for execution right
- rb_thread_t *next_th;
- while((next_th = sched->running) != th) {
- if (th_has_dedicated_nt(th)) {
- RUBY_DEBUG_LOG("(nt) sleep th:%u running:%u", rb_th_serial(th), rb_th_serial(sched->running));
+ // ready -> running
+ sched->running = th;
- thread_sched_set_lock_owner(sched, NULL);
- {
- RUBY_DEBUG_LOG("nt:%d cond:%p", th->nt->serial, &th->nt->cond.readyq);
- rb_native_cond_wait(&th->nt->cond.readyq, &sched->lock_);
- }
- thread_sched_set_lock_owner(sched, th);
+ RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_RESUMED);
- RUBY_DEBUG_LOG("(nt) wakeup %s", sched->running == th ? "success" : "failed");
- if (th == sched->running) {
- rb_ractor_thread_switch(th->ractor, th);
- }
- }
- else {
- // search another ready thread
- if (can_direct_transfer &&
- (next_th = sched->running) != NULL &&
- !next_th->nt // next_th is running or has dedicated nt
- ) {
-
- RUBY_DEBUG_LOG("th:%u->%u (direct)", rb_th_serial(th), rb_th_serial(next_th));
-
- thread_sched_set_lock_owner(sched, NULL);
- {
- rb_ractor_set_current_ec(th->ractor, NULL);
- thread_sched_switch(th, next_th);
- }
- thread_sched_set_lock_owner(sched, th);
- }
- else {
- // search another ready ractor
- struct rb_native_thread *nt = th->nt;
- native_thread_assign(NULL, th);
-
- RUBY_DEBUG_LOG("th:%u->%u (ractor scheduling)", rb_th_serial(th), rb_th_serial(next_th));
-
- thread_sched_set_lock_owner(sched, NULL);
- {
- rb_ractor_set_current_ec(th->ractor, NULL);
- coroutine_transfer(th->sched.context, nt->nt_context);
- }
- thread_sched_set_lock_owner(sched, th);
- }
-
- VM_ASSERT(GET_EC() == th->ec);
- }
+ if (!sched->timer) {
+ if (!designate_timer_thread(sched) && !ubf_threads_empty()) {
+ rb_thread_wakeup_timer_thread(-1);
}
-
- VM_ASSERT(th->nt != NULL);
- VM_ASSERT(GET_EC() == th->ec);
- VM_ASSERT(th->sched.waiting_reason.flags == thread_sched_waiting_none);
-
- // add th to running threads
- thread_sched_add_running_thread(sched, th);
- }
-
- // VM_ASSERT(ractor_sched_running_threads_contain_p(th->vm, th)); need locking
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_RESUMED, th);
-}
-
-// waiting -> ready -> running (locked)
-static void
-thread_sched_to_running_common(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- RUBY_DEBUG_LOG("th:%u dedicated:%d", rb_th_serial(th), th_has_dedicated_nt(th));
-
- VM_ASSERT(sched->running != th);
- VM_ASSERT(th_has_dedicated_nt(th));
- VM_ASSERT(GET_THREAD() == th);
-
- native_thread_dedicated_dec(th->vm, th->ractor, th->nt);
-
- // waiting -> ready
- thread_sched_to_ready_common(sched, th, false, false);
-
- if (sched->running == th) {
- thread_sched_add_running_thread(sched, th);
}
-
- // TODO: check SNT number
- thread_sched_wait_running_turn(sched, th, false);
}
-// waiting -> ready -> running
-//
-// `th` had been waiting by `thread_sched_to_waiting()`
-// and run a dedicated task (like waitpid and so on).
-// After the dedicated task, this function is called
-// to join a normal thread-scheduling.
static void
thread_sched_to_running(struct rb_thread_sched *sched, rb_thread_t *th)
{
- thread_sched_lock(sched, th);
- {
- thread_sched_to_running_common(sched, th);
- }
- thread_sched_unlock(sched, th);
+ rb_native_mutex_lock(&sched->lock);
+ thread_sched_to_running_common(sched, th);
+ rb_native_mutex_unlock(&sched->lock);
}
-// resume a next thread in the thread ready queue.
-//
-// deque next running thread from the ready thread queue and
-// resume this thread if available.
-//
-// If the next therad has a dedicated native thraed, simply signal to resume.
-// Otherwise, make the ractor ready and other nt will run the ractor and the thread.
-static void
-thread_sched_wakeup_next_thread(struct rb_thread_sched *sched, rb_thread_t *th, bool will_switch)
+static rb_thread_t *
+thread_sched_to_waiting_common(struct rb_thread_sched *sched)
{
- ASSERT_thread_sched_locked(sched, th);
+ rb_thread_t *next;
+ sched->running = NULL;
+ next = ccan_list_top(&sched->readyq, rb_thread_t, sched.node.readyq);
+ if (next) rb_native_cond_signal(&next->nt->cond.readyq);
- VM_ASSERT(sched->running == th);
- VM_ASSERT(sched->running->nt != NULL);
-
- rb_thread_t *next_th = thread_sched_deq(sched);
-
- RUBY_DEBUG_LOG("next_th:%u", rb_th_serial(next_th));
- VM_ASSERT(th != next_th);
-
- thread_sched_set_running(sched, next_th);
- VM_ASSERT(next_th == sched->running);
- thread_sched_wakeup_running_thread(sched, next_th, will_switch);
-
- if (th != next_th) {
- thread_sched_del_running_thread(sched, th);
- }
+ return next;
}
-// running -> waiting
-//
-// to_dead: false
-// th will run dedicated task.
-// run another ready thread.
-// to_dead: true
-// th will be dead.
-// run another ready thread.
static void
-thread_sched_to_waiting_common0(struct rb_thread_sched *sched, rb_thread_t *th, bool to_dead)
+thread_sched_to_waiting(struct rb_thread_sched *sched)
{
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED, th);
-
- if (!to_dead) native_thread_dedicated_inc(th->vm, th->ractor, th->nt);
-
- RUBY_DEBUG_LOG("%sth:%u", to_dead ? "to_dead " : "", rb_th_serial(th));
-
- bool can_switch = to_dead ? !th_has_dedicated_nt(th) : false;
- thread_sched_wakeup_next_thread(sched, th, can_switch);
+ RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED);
+ rb_native_mutex_lock(&sched->lock);
+ thread_sched_to_waiting_common(sched);
+ rb_native_mutex_unlock(&sched->lock);
}
-// running -> dead (locked)
static void
-thread_sched_to_dead_common(struct rb_thread_sched *sched, rb_thread_t *th)
+thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
{
- RUBY_DEBUG_LOG("dedicated:%d", th->nt->dedicated);
- thread_sched_to_waiting_common0(sched, th, true);
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_EXITED, th);
-}
+ rb_thread_t *next;
-// running -> dead
-static void
-thread_sched_to_dead(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- thread_sched_lock(sched, th);
- {
- thread_sched_to_dead_common(sched, th);
+ /*
+ * Perhaps other threads are stuck in blocking region w/o GVL, too,
+ * (perhaps looping in io_close_fptr) so we kick them:
+ */
+ ubf_wakeup_all_threads();
+ rb_native_mutex_lock(&sched->lock);
+ next = thread_sched_to_waiting_common(sched);
+
+ /* An another thread is processing GVL yield. */
+ if (UNLIKELY(sched->wait_yield)) {
+ while (sched->wait_yield)
+ rb_native_cond_wait(&sched->switch_wait_cond, &sched->lock);
+ }
+ else if (next) {
+ /* Wait until another thread task takes GVL. */
+ sched->need_yield = 1;
+ sched->wait_yield = 1;
+ while (sched->need_yield)
+ rb_native_cond_wait(&sched->switch_cond, &sched->lock);
+ sched->wait_yield = 0;
+ rb_native_cond_broadcast(&sched->switch_wait_cond);
}
- thread_sched_unlock(sched, th);
-}
-
-// running -> waiting (locked)
-//
-// This thread will run dedicated task (th->nt->dedicated++).
-static void
-thread_sched_to_waiting_common(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- RUBY_DEBUG_LOG("dedicated:%d", th->nt->dedicated);
- thread_sched_to_waiting_common0(sched, th, false);
-}
-
-// running -> waiting
-//
-// This thread will run a dedicated task.
-static void
-thread_sched_to_waiting(struct rb_thread_sched *sched, rb_thread_t *th)
-{
- thread_sched_lock(sched, th);
- {
- thread_sched_to_waiting_common(sched, th);
+ else {
+ rb_native_mutex_unlock(&sched->lock);
+ native_thread_yield();
+ rb_native_mutex_lock(&sched->lock);
+ rb_native_cond_broadcast(&sched->switch_wait_cond);
}
- thread_sched_unlock(sched, th);
+ thread_sched_to_running_common(sched, th);
+ rb_native_mutex_unlock(&sched->lock);
}
-// mini utility func
-static void
-setup_ubf(rb_thread_t *th, rb_unblock_function_t *func, void *arg)
+void
+rb_thread_sched_init(struct rb_thread_sched *sched)
{
- rb_native_mutex_lock(&th->interrupt_lock);
- {
- th->unblock.func = func;
- th->unblock.arg = arg;
- }
- rb_native_mutex_unlock(&th->interrupt_lock);
+ rb_native_mutex_initialize(&sched->lock);
+ rb_native_cond_initialize(&sched->switch_cond);
+ rb_native_cond_initialize(&sched->switch_wait_cond);
+ ccan_list_head_init(&sched->readyq);
+ sched->running = NULL;
+ sched->timer = 0;
+ sched->timer_err = ETIMEDOUT;
+ sched->need_yield = 0;
+ sched->wait_yield = 0;
}
-static void
-ubf_waiting(void *ptr)
-{
- rb_thread_t *th = (rb_thread_t *)ptr;
- struct rb_thread_sched *sched = TH_SCHED(th);
-
- // only once. it is safe because th->interrupt_lock is already acquired.
- th->unblock.func = NULL;
- th->unblock.arg = NULL;
-
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
+#if 0
+// TODO
- thread_sched_lock(sched, th);
- {
- if (sched->running == th) {
- // not sleeping yet.
- }
- else {
- thread_sched_to_ready_common(sched, th, true, false);
- }
- }
- thread_sched_unlock(sched, th);
-}
+static void clear_thread_cache_altstack(void);
-// running -> waiting
-//
-// This thread will sleep until other thread wakeup the thread.
static void
-thread_sched_to_waiting_until_wakeup(struct rb_thread_sched *sched, rb_thread_t *th)
+rb_thread_sched_destroy(struct rb_thread_sched *sched)
{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
-
- RB_VM_SAVE_MACHINE_CONTEXT(th);
- setup_ubf(th, ubf_waiting, (void *)th);
-
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED, th);
-
- thread_sched_lock(sched, th);
- {
- if (!RUBY_VM_INTERRUPTED(th->ec)) {
- bool can_direct_transfer = !th_has_dedicated_nt(th);
- thread_sched_wakeup_next_thread(sched, th, can_direct_transfer);
- thread_sched_wait_running_turn(sched, th, can_direct_transfer);
- }
- else {
- RUBY_DEBUG_LOG("th:%u interrupted", rb_th_serial(th));
- }
+ /*
+ * only called once at VM shutdown (not atfork), another thread
+ * may still grab vm->gvl.lock when calling gvl_release at
+ * the end of thread_start_func_2
+ */
+ if (0) {
+ rb_native_cond_destroy(&sched->switch_wait_cond);
+ rb_native_cond_destroy(&sched->switch_cond);
+ rb_native_mutex_destroy(&sched->lock);
}
- thread_sched_unlock(sched, th);
-
- setup_ubf(th, NULL, NULL);
+ clear_thread_cache_altstack();
}
+#endif
-// run another thread in the ready queue.
-// continue to run if there are no ready threads.
+#if defined(HAVE_WORKING_FORK)
+static void thread_cache_reset(void);
static void
-thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
+thread_sched_atfork(struct rb_thread_sched *sched)
{
- RUBY_DEBUG_LOG("th:%d sched->readyq_cnt:%d", (int)th->serial, sched->readyq_cnt);
-
- thread_sched_lock(sched, th);
- {
- if (!ccan_list_empty(&sched->readyq)) {
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED, th);
- thread_sched_wakeup_next_thread(sched, th, !th_has_dedicated_nt(th));
- bool can_direct_transfer = !th_has_dedicated_nt(th);
- thread_sched_to_ready_common(sched, th, false, can_direct_transfer);
- thread_sched_wait_running_turn(sched, th, can_direct_transfer);
- }
- else {
- VM_ASSERT(sched->readyq_cnt == 0);
- }
- }
- thread_sched_unlock(sched, th);
+ thread_cache_reset();
+ rb_thread_sched_init(sched);
+ thread_sched_to_running(sched, GET_THREAD());
}
-
-void
-rb_thread_sched_init(struct rb_thread_sched *sched, bool atfork)
-{
- rb_native_mutex_initialize(&sched->lock_);
-
-#if VM_CHECK_MODE
- sched->lock_owner = NULL;
#endif
- ccan_list_head_init(&sched->readyq);
- sched->readyq_cnt = 0;
-
-#if USE_MN_THREADS
- if (!atfork) sched->enable_mn_threads = true; // MN is enabled on Ractors
-#endif
-}
+#define NATIVE_MUTEX_LOCK_DEBUG 0
static void
-thread_sched_switch0(struct coroutine_context *current_cont, rb_thread_t *next_th, struct rb_native_thread *nt)
+mutex_debug(const char *msg, void *lock)
{
- VM_ASSERT(!nt->dedicated);
- VM_ASSERT(next_th->nt == NULL);
-
- RUBY_DEBUG_LOG("next_th:%u", rb_th_serial(next_th));
-
- ruby_thread_set_native(next_th);
- native_thread_assign(nt, next_th);
- coroutine_transfer(current_cont, next_th->sched.context);
-}
+ if (NATIVE_MUTEX_LOCK_DEBUG) {
+ int r;
+ static pthread_mutex_t dbglock = PTHREAD_MUTEX_INITIALIZER;
-static void
-thread_sched_switch(rb_thread_t *cth, rb_thread_t *next_th)
-{
- struct rb_native_thread *nt = cth->nt;
- native_thread_assign(NULL, cth);
- RUBY_DEBUG_LOG("th:%u->%u on nt:%d", rb_th_serial(cth), rb_th_serial(next_th), nt->serial);
- thread_sched_switch0(cth->sched.context, next_th, nt);
+ if ((r = pthread_mutex_lock(&dbglock)) != 0) {exit(EXIT_FAILURE);}
+ fprintf(stdout, "%s: %p\n", msg, lock);
+ if ((r = pthread_mutex_unlock(&dbglock)) != 0) {exit(EXIT_FAILURE);}
+ }
}
-#if VM_CHECK_MODE > 0
-RBIMPL_ATTR_MAYBE_UNUSED()
-static unsigned int
-grq_size(rb_vm_t *vm, rb_ractor_t *cr)
+void
+rb_native_mutex_lock(pthread_mutex_t *lock)
{
- ASSERT_ractor_sched_locked(vm, cr);
-
- rb_ractor_t *r, *prev_r = NULL;
- unsigned int i = 0;
-
- ccan_list_for_each(&vm->ractor.sched.grq, r, threads.sched.grq_node) {
- i++;
-
- VM_ASSERT(r != prev_r);
- prev_r = r;
+ int r;
+ mutex_debug("lock", lock);
+ if ((r = pthread_mutex_lock(lock)) != 0) {
+ rb_bug_errno("pthread_mutex_lock", r);
}
- return i;
}
-#endif
-static void
-ractor_sched_enq(rb_vm_t *vm, rb_ractor_t *r)
+void
+rb_native_mutex_unlock(pthread_mutex_t *lock)
{
- struct rb_thread_sched *sched = &r->threads.sched;
- rb_ractor_t *cr = NULL; // timer thread can call this function
-
- VM_ASSERT(sched->running != NULL);
- VM_ASSERT(sched->running->nt == NULL);
-
- ractor_sched_lock(vm, cr);
- {
-#if VM_CHECK_MODE > 0
- // check if grq contains r
- rb_ractor_t *tr;
- ccan_list_for_each(&vm->ractor.sched.grq, tr, threads.sched.grq_node) {
- VM_ASSERT(r != tr);
- }
-#endif
-
- ccan_list_add_tail(&vm->ractor.sched.grq, &sched->grq_node);
- vm->ractor.sched.grq_cnt++;
- VM_ASSERT(grq_size(vm, cr) == vm->ractor.sched.grq_cnt);
-
- RUBY_DEBUG_LOG("r:%u th:%u grq_cnt:%u", rb_ractor_id(r), rb_th_serial(sched->running), vm->ractor.sched.grq_cnt);
-
- rb_native_cond_signal(&vm->ractor.sched.cond);
-
- // ractor_sched_dump(vm);
+ int r;
+ mutex_debug("unlock", lock);
+ if ((r = pthread_mutex_unlock(lock)) != 0) {
+ rb_bug_errno("pthread_mutex_unlock", r);
}
- ractor_sched_unlock(vm, cr);
}
-
-#ifndef SNT_KEEP_SECONDS
-#define SNT_KEEP_SECONDS 0
-#endif
-
-#ifndef MINIMUM_SNT
-// make at least MINIMUM_SNT snts for debug.
-#define MINIMUM_SNT 0
-#endif
-
-static rb_ractor_t *
-ractor_sched_deq(rb_vm_t *vm, rb_ractor_t *cr)
+int
+rb_native_mutex_trylock(pthread_mutex_t *lock)
{
- rb_ractor_t *r;
-
- ractor_sched_lock(vm, cr);
- {
- RUBY_DEBUG_LOG("empty? %d", ccan_list_empty(&vm->ractor.sched.grq));
- // ractor_sched_dump(vm);
-
- VM_ASSERT(rb_current_execution_context(false) == NULL);
- VM_ASSERT(grq_size(vm, cr) == vm->ractor.sched.grq_cnt);
-
- while ((r = ccan_list_pop(&vm->ractor.sched.grq, rb_ractor_t, threads.sched.grq_node)) == NULL) {
- RUBY_DEBUG_LOG("wait grq_cnt:%d", (int)vm->ractor.sched.grq_cnt);
-
-#if SNT_KEEP_SECONDS > 0
- rb_hrtime_t abs = rb_hrtime_add(rb_hrtime_now(), RB_HRTIME_PER_SEC * SNT_KEEP_SECONDS);
- if (native_cond_timedwait(&vm->ractor.sched.cond, &vm->ractor.sched.lock, &abs) == ETIMEDOUT) {
- RUBY_DEBUG_LOG("timeout, grq_cnt:%d", (int)vm->ractor.sched.grq_cnt);
- VM_ASSERT(r == NULL);
- vm->ractor.sched.snt_cnt--;
- vm->ractor.sched.running_cnt--;
- break;
- }
- else {
- RUBY_DEBUG_LOG("wakeup grq_cnt:%d", (int)vm->ractor.sched.grq_cnt);
- }
-#else
- ractor_sched_set_unlocked(vm, cr);
- rb_native_cond_wait(&vm->ractor.sched.cond, &vm->ractor.sched.lock);
- ractor_sched_set_locked(vm, cr);
-
- RUBY_DEBUG_LOG("wakeup grq_cnt:%d", (int)vm->ractor.sched.grq_cnt);
-#endif
- }
-
- VM_ASSERT(rb_current_execution_context(false) == NULL);
-
- if (r) {
- VM_ASSERT(vm->ractor.sched.grq_cnt > 0);
- vm->ractor.sched.grq_cnt--;
- RUBY_DEBUG_LOG("r:%d grq_cnt:%u", (int)rb_ractor_id(r), vm->ractor.sched.grq_cnt);
+ int r;
+ mutex_debug("trylock", lock);
+ if ((r = pthread_mutex_trylock(lock)) != 0) {
+ if (r == EBUSY) {
+ return EBUSY;
}
else {
- VM_ASSERT(SNT_KEEP_SECONDS > 0);
- // timeout
+ rb_bug_errno("pthread_mutex_trylock", r);
}
}
- ractor_sched_unlock(vm, cr);
-
- return r;
+ return 0;
}
-void rb_ractor_lock_self(rb_ractor_t *r);
-void rb_ractor_unlock_self(rb_ractor_t *r);
-
void
-rb_ractor_sched_sleep(rb_execution_context_t *ec, rb_ractor_t *cr, rb_unblock_function_t *ubf)
+rb_native_mutex_initialize(pthread_mutex_t *lock)
{
- // ractor lock of cr is acquired
- // r is sleeping statuss
- rb_thread_t *th = rb_ec_thread_ptr(ec);
- struct rb_thread_sched *sched = TH_SCHED(th);
- cr->sync.wait.waiting_thread = th; // TODO: multi-thread
-
- setup_ubf(th, ubf, (void *)cr);
-
- thread_sched_lock(sched, th);
- {
- rb_ractor_unlock_self(cr);
- {
- if (RUBY_VM_INTERRUPTED(th->ec)) {
- RUBY_DEBUG_LOG("interrupted");
- }
- else if (cr->sync.wait.wakeup_status != wakeup_none) {
- RUBY_DEBUG_LOG("awaken:%d", (int)cr->sync.wait.wakeup_status);
- }
- else {
- // sleep
- RB_VM_SAVE_MACHINE_CONTEXT(th);
- th->status = THREAD_STOPPED_FOREVER;
-
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED, th);
-
- bool can_direct_transfer = !th_has_dedicated_nt(th);
- thread_sched_wakeup_next_thread(sched, th, can_direct_transfer);
- thread_sched_wait_running_turn(sched, th, can_direct_transfer);
- th->status = THREAD_RUNNABLE;
- // wakeup
- }
- }
+ int r = pthread_mutex_init(lock, 0);
+ mutex_debug("init", lock);
+ if (r != 0) {
+ rb_bug_errno("pthread_mutex_init", r);
}
- thread_sched_unlock(sched, th);
-
- setup_ubf(th, NULL, NULL);
-
- rb_ractor_lock_self(cr);
- cr->sync.wait.waiting_thread = NULL;
}
void
-rb_ractor_sched_wakeup(rb_ractor_t *r)
+rb_native_mutex_destroy(pthread_mutex_t *lock)
{
- rb_thread_t *r_th = r->sync.wait.waiting_thread;
- // ractor lock of r is acquired
- struct rb_thread_sched *sched = TH_SCHED(r_th);
-
- VM_ASSERT(r->sync.wait.wakeup_status != 0);
-
- thread_sched_lock(sched, r_th);
- {
- if (r_th->status == THREAD_STOPPED_FOREVER) {
- thread_sched_to_ready_common(sched, r_th, true, false);
- }
+ int r = pthread_mutex_destroy(lock);
+ mutex_debug("destroy", lock);
+ if (r != 0) {
+ rb_bug_errno("pthread_mutex_destroy", r);
}
- thread_sched_unlock(sched, r_th);
}
-static bool
-ractor_sched_barrier_completed_p(rb_vm_t *vm)
+void
+rb_native_cond_initialize(rb_nativethread_cond_t *cond)
{
- RUBY_DEBUG_LOG("run:%u wait:%u", vm->ractor.sched.running_cnt, vm->ractor.sched.barrier_waiting_cnt);
- VM_ASSERT(vm->ractor.sched.running_cnt - 1 >= vm->ractor.sched.barrier_waiting_cnt);
- return (vm->ractor.sched.running_cnt - vm->ractor.sched.barrier_waiting_cnt) == 1;
+ int r = pthread_cond_init(cond, condattr_monotonic);
+ if (r != 0) {
+ rb_bug_errno("pthread_cond_init", r);
+ }
}
void
-rb_ractor_sched_barrier_start(rb_vm_t *vm, rb_ractor_t *cr)
+rb_native_cond_destroy(rb_nativethread_cond_t *cond)
{
- VM_ASSERT(cr == GET_RACTOR());
- VM_ASSERT(vm->ractor.sync.lock_owner == cr); // VM is locked
- VM_ASSERT(!vm->ractor.sched.barrier_waiting);
- VM_ASSERT(vm->ractor.sched.barrier_waiting_cnt == 0);
-
- RUBY_DEBUG_LOG("start serial:%u", vm->ractor.sched.barrier_serial);
-
- unsigned int lock_rec;
-
- ractor_sched_lock(vm, cr);
- {
- vm->ractor.sched.barrier_waiting = true;
-
- // release VM lock
- lock_rec = vm->ractor.sync.lock_rec;
- vm->ractor.sync.lock_rec = 0;
- vm->ractor.sync.lock_owner = NULL;
- rb_native_mutex_unlock(&vm->ractor.sync.lock);
- {
- // interrupts all running threads
- rb_thread_t *ith;
- ccan_list_for_each(&vm->ractor.sched.running_threads, ith, sched.node.running_threads) {
- if (ith->ractor != cr) {
- RUBY_DEBUG_LOG("barrier int:%u", rb_th_serial(ith));
- RUBY_VM_SET_VM_BARRIER_INTERRUPT(ith->ec);
- }
- }
-
- // wait for other ractors
- while (!ractor_sched_barrier_completed_p(vm)) {
- ractor_sched_set_unlocked(vm, cr);
- rb_native_cond_wait(&vm->ractor.sched.barrier_complete_cond, &vm->ractor.sched.lock);
- ractor_sched_set_locked(vm, cr);
- }
- }
- }
- ractor_sched_unlock(vm, cr);
-
- // acquire VM lock
- rb_native_mutex_lock(&vm->ractor.sync.lock);
- vm->ractor.sync.lock_rec = lock_rec;
- vm->ractor.sync.lock_owner = cr;
-
- RUBY_DEBUG_LOG("completed seirial:%u", vm->ractor.sched.barrier_serial);
-
- ractor_sched_lock(vm, cr);
- {
- vm->ractor.sched.barrier_waiting = false;
- vm->ractor.sched.barrier_serial++;
- vm->ractor.sched.barrier_waiting_cnt = 0;
- rb_native_cond_broadcast(&vm->ractor.sched.barrier_release_cond);
+ int r = pthread_cond_destroy(cond);
+ if (r != 0) {
+ rb_bug_errno("pthread_cond_destroy", r);
}
- ractor_sched_unlock(vm, cr);
}
-static void
-ractor_sched_barrier_join_signal_locked(rb_vm_t *vm)
+/*
+ * In OS X 10.7 (Lion), pthread_cond_signal and pthread_cond_broadcast return
+ * EAGAIN after retrying 8192 times. You can see them in the following page:
+ *
+ * http://www.opensource.apple.com/source/Libc/Libc-763.11/pthreads/pthread_cond.c
+ *
+ * The following rb_native_cond_signal and rb_native_cond_broadcast functions
+ * need to retrying until pthread functions don't return EAGAIN.
+ */
+
+void
+rb_native_cond_signal(rb_nativethread_cond_t *cond)
{
- if (ractor_sched_barrier_completed_p(vm)) {
- rb_native_cond_signal(&vm->ractor.sched.barrier_complete_cond);
+ int r;
+ do {
+ r = pthread_cond_signal(cond);
+ } while (r == EAGAIN);
+ if (r != 0) {
+ rb_bug_errno("pthread_cond_signal", r);
}
}
-static void
-ractor_sched_barrier_join_wait_locked(rb_vm_t *vm, rb_thread_t *th)
+void
+rb_native_cond_broadcast(rb_nativethread_cond_t *cond)
{
- VM_ASSERT(vm->ractor.sched.barrier_waiting);
-
- unsigned int barrier_serial = vm->ractor.sched.barrier_serial;
-
- while (vm->ractor.sched.barrier_serial == barrier_serial) {
- RUBY_DEBUG_LOG("sleep serial:%u", barrier_serial);
- RB_VM_SAVE_MACHINE_CONTEXT(th);
-
- rb_ractor_t *cr = th->ractor;
- ractor_sched_set_unlocked(vm, cr);
- rb_native_cond_wait(&vm->ractor.sched.barrier_release_cond, &vm->ractor.sched.lock);
- ractor_sched_set_locked(vm, cr);
-
- RUBY_DEBUG_LOG("wakeup serial:%u", barrier_serial);
+ int r;
+ do {
+ r = pthread_cond_broadcast(cond);
+ } while (r == EAGAIN);
+ if (r != 0) {
+ rb_bug_errno("rb_native_cond_broadcast", r);
}
}
void
-rb_ractor_sched_barrier_join(rb_vm_t *vm, rb_ractor_t *cr)
+rb_native_cond_wait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex)
{
- VM_ASSERT(cr->threads.sched.running != NULL); // running ractor
- VM_ASSERT(cr == GET_RACTOR());
- VM_ASSERT(vm->ractor.sync.lock_owner == NULL); // VM is locked, but owner == NULL
- VM_ASSERT(vm->ractor.sched.barrier_waiting); // VM needs barrier sync
-
-#if USE_RUBY_DEBUG_LOG || VM_CHECK_MODE > 0
- unsigned int barrier_serial = vm->ractor.sched.barrier_serial;
-#endif
-
- RUBY_DEBUG_LOG("join");
-
- rb_native_mutex_unlock(&vm->ractor.sync.lock);
- {
- VM_ASSERT(vm->ractor.sched.barrier_waiting); // VM needs barrier sync
- VM_ASSERT(vm->ractor.sched.barrier_serial == barrier_serial);
-
- ractor_sched_lock(vm, cr);
- {
- // running_cnt
- vm->ractor.sched.barrier_waiting_cnt++;
- RUBY_DEBUG_LOG("waiting_cnt:%u serial:%u", vm->ractor.sched.barrier_waiting_cnt, barrier_serial);
-
- ractor_sched_barrier_join_signal_locked(vm);
- ractor_sched_barrier_join_wait_locked(vm, cr->threads.sched.running);
- }
- ractor_sched_unlock(vm, cr);
+ int r = pthread_cond_wait(cond, mutex);
+ if (r != 0) {
+ rb_bug_errno("pthread_cond_wait", r);
}
-
- rb_native_mutex_lock(&vm->ractor.sync.lock);
- // VM locked here
}
-#if 0
-// TODO
-
-static void clear_thread_cache_altstack(void);
-
-static void
-rb_thread_sched_destroy(struct rb_thread_sched *sched)
+static int
+native_cond_timedwait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex, const rb_hrtime_t *abs)
{
+ int r;
+ struct timespec ts;
+
/*
- * only called once at VM shutdown (not atfork), another thread
- * may still grab vm->gvl.lock when calling gvl_release at
- * the end of thread_start_func_2
+ * An old Linux may return EINTR. Even though POSIX says
+ * "These functions shall not return an error code of [EINTR]".
+ * http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html
+ * Let's hide it from arch generic code.
*/
- if (0) {
- rb_native_mutex_destroy(&sched->lock);
+ do {
+ rb_hrtime2timespec(&ts, abs);
+ r = pthread_cond_timedwait(cond, mutex, &ts);
+ } while (r == EINTR);
+
+ if (r != 0 && r != ETIMEDOUT) {
+ rb_bug_errno("pthread_cond_timedwait", r);
}
- clear_thread_cache_altstack();
+
+ return r;
}
-#endif
-#ifdef RB_THREAD_T_HAS_NATIVE_ID
-static int
-get_native_thread_id(void)
+void
+rb_native_cond_timedwait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex, unsigned long msec)
{
-#ifdef __linux__
- return (int)syscall(SYS_gettid);
-#elif defined(__FreeBSD__)
- return pthread_getthreadid_np();
-#endif
+ rb_hrtime_t hrmsec = native_cond_timeout(cond, RB_HRTIME_PER_MSEC * msec);
+ native_cond_timedwait(cond, mutex, &hrmsec);
}
-#endif
-#if defined(HAVE_WORKING_FORK)
-static void
-thread_sched_atfork(struct rb_thread_sched *sched)
+static rb_hrtime_t
+native_cond_timeout(rb_nativethread_cond_t *cond, const rb_hrtime_t rel)
{
- current_fork_gen++;
- rb_thread_sched_init(sched, true);
- rb_thread_t *th = GET_THREAD();
- rb_vm_t *vm = GET_VM();
-
- if (th_has_dedicated_nt(th)) {
- vm->ractor.sched.snt_cnt = 0;
- }
- else {
- vm->ractor.sched.snt_cnt = 1;
- }
- vm->ractor.sched.running_cnt = 0;
-
- // rb_native_cond_destroy(&vm->ractor.sched.cond);
- rb_native_cond_initialize(&vm->ractor.sched.cond);
- rb_native_cond_initialize(&vm->ractor.sched.barrier_complete_cond);
- rb_native_cond_initialize(&vm->ractor.sched.barrier_release_cond);
-
- ccan_list_head_init(&vm->ractor.sched.grq);
- ccan_list_head_init(&vm->ractor.sched.timeslice_threads);
- ccan_list_head_init(&vm->ractor.sched.running_threads);
-
- VM_ASSERT(sched->is_running);
- sched->is_running_timeslice = false;
-
- if (sched->running != th) {
- thread_sched_to_running(sched, th);
+ if (condattr_monotonic) {
+ return rb_hrtime_add(rb_hrtime_now(), rel);
}
else {
- thread_sched_setup_running_threads(sched, th->ractor, vm, th, NULL, NULL);
- }
+ struct timespec ts;
-#ifdef RB_THREAD_T_HAS_NATIVE_ID
- if (th->nt) {
- th->nt->tid = get_native_thread_id();
+ rb_timespec_now(&ts);
+ return rb_hrtime_add(rb_timespec2hrtime(&ts), rel);
}
-#endif
}
-#endif
+#define native_cleanup_push pthread_cleanup_push
+#define native_cleanup_pop pthread_cleanup_pop
#ifdef RB_THREAD_LOCAL_SPECIFIER
static RB_THREAD_LOCAL_SPECIFIER rb_thread_t *ruby_native_thread;
@@ -1568,8 +723,6 @@ static void
null_func(int i)
{
/* null */
- // This function can be called from signal handler
- // RUBY_DEBUG_LOG("i:%d", i);
}
rb_thread_t *
@@ -1604,8 +757,28 @@ ruby_thread_set_native(rb_thread_t *th)
#endif
}
-static void native_thread_setup(struct rb_native_thread *nt);
-static void native_thread_setup_on_thread(struct rb_native_thread *nt);
+#ifdef RB_THREAD_T_HAS_NATIVE_ID
+static int
+get_native_thread_id(void)
+{
+#ifdef __linux__
+ return (int)syscall(SYS_gettid);
+#elif defined(__FreeBSD__)
+ return pthread_getthreadid_np();
+#endif
+}
+#endif
+
+static void
+native_thread_init(struct rb_native_thread *nt)
+{
+#ifdef RB_THREAD_T_HAS_NATIVE_ID
+ nt->tid = get_native_thread_id();
+#endif
+ rb_native_cond_initialize(&nt->cond.readyq);
+ if (&nt->cond.readyq != &nt->cond.intr)
+ rb_native_cond_initialize(&nt->cond.intr);
+}
void
Init_native_thread(rb_thread_t *main_th)
@@ -1628,145 +801,40 @@ Init_native_thread(rb_thread_t *main_th)
rb_bug("pthread_key_create failed (ruby_current_ec_key)");
}
#endif
- ruby_posix_signal(SIGVTALRM, null_func);
-
- // setup vm
- rb_vm_t *vm = main_th->vm;
- rb_native_mutex_initialize(&vm->ractor.sched.lock);
- rb_native_cond_initialize(&vm->ractor.sched.cond);
- rb_native_cond_initialize(&vm->ractor.sched.barrier_complete_cond);
- rb_native_cond_initialize(&vm->ractor.sched.barrier_release_cond);
-
- ccan_list_head_init(&vm->ractor.sched.grq);
- ccan_list_head_init(&vm->ractor.sched.timeslice_threads);
- ccan_list_head_init(&vm->ractor.sched.running_threads);
+ posix_signal(SIGVTALRM, null_func);
// setup main thread
main_th->nt->thread_id = pthread_self();
- main_th->nt->serial = 1;
-#ifdef RUBY_NT_SERIAL
- ruby_nt_serial = 1;
-#endif
ruby_thread_set_native(main_th);
- native_thread_setup(main_th->nt);
- native_thread_setup_on_thread(main_th->nt);
-
- TH_SCHED(main_th)->running = main_th;
- main_th->has_dedicated_nt = 1;
-
- thread_sched_setup_running_threads(TH_SCHED(main_th), main_th->ractor, vm, main_th, NULL, NULL);
-
- // setup main NT
- main_th->nt->dedicated = 1;
- main_th->nt->vm = vm;
-
- // setup mn
- vm->ractor.sched.dnt_cnt = 1;
+ native_thread_init(main_th->nt);
}
-extern int ruby_mn_threads_enabled;
-
-void
-ruby_mn_threads_params(void)
-{
- rb_vm_t *vm = GET_VM();
- rb_ractor_t *main_ractor = GET_RACTOR();
-
- const char *mn_threads_cstr = getenv("RUBY_MN_THREADS");
- bool enable_mn_threads = false;
-
- if (USE_MN_THREADS && mn_threads_cstr && (enable_mn_threads = atoi(mn_threads_cstr) > 0)) {
- // enabled
- ruby_mn_threads_enabled = 1;
- }
- main_ractor->threads.sched.enable_mn_threads = enable_mn_threads;
-
- const char *max_cpu_cstr = getenv("RUBY_MAX_CPU");
- const int default_max_cpu = 8; // TODO: CPU num?
- int max_cpu = default_max_cpu;
-
- if (USE_MN_THREADS && max_cpu_cstr && (max_cpu = atoi(max_cpu_cstr)) > 0) {
- max_cpu = default_max_cpu;
- }
-
- vm->ractor.sched.max_cpu = max_cpu;
-}
+#ifndef USE_THREAD_CACHE
+#define USE_THREAD_CACHE 1
+#endif
static void
-native_thread_dedicated_inc(rb_vm_t *vm, rb_ractor_t *cr, struct rb_native_thread *nt)
+native_thread_destroy(rb_thread_t *th)
{
- RUBY_DEBUG_LOG("nt:%d %d->%d", nt->serial, nt->dedicated, nt->dedicated + 1);
+ struct rb_native_thread *nt = th->nt;
- if (nt->dedicated == 0) {
- ractor_sched_lock(vm, cr);
- {
- vm->ractor.sched.snt_cnt--;
- vm->ractor.sched.dnt_cnt++;
- }
- ractor_sched_unlock(vm, cr);
- }
+ rb_native_cond_destroy(&nt->cond.readyq);
- nt->dedicated++;
-}
-
-static void
-native_thread_dedicated_dec(rb_vm_t *vm, rb_ractor_t *cr, struct rb_native_thread *nt)
-{
- RUBY_DEBUG_LOG("nt:%d %d->%d", nt->serial, nt->dedicated, nt->dedicated - 1);
- VM_ASSERT(nt->dedicated > 0);
- nt->dedicated--;
+ if (&nt->cond.readyq != &nt->cond.intr)
+ rb_native_cond_destroy(&nt->cond.intr);
- if (nt->dedicated == 0) {
- ractor_sched_lock(vm, cr);
- {
- nt->vm->ractor.sched.snt_cnt++;
- nt->vm->ractor.sched.dnt_cnt--;
- }
- ractor_sched_unlock(vm, cr);
- }
+ /*
+ * prevent false positive from ruby_thread_has_gvl_p if that
+ * gets called from an interposing function wrapper
+ */
+ if (USE_THREAD_CACHE)
+ ruby_thread_set_native(0);
}
-static void
-native_thread_assign(struct rb_native_thread *nt, rb_thread_t *th)
-{
-#if USE_RUBY_DEBUG_LOG
- if (nt) {
- if (th->nt) {
- RUBY_DEBUG_LOG("th:%d nt:%d->%d", (int)th->serial, (int)th->nt->serial, (int)nt->serial);
- }
- else {
- RUBY_DEBUG_LOG("th:%d nt:NULL->%d", (int)th->serial, (int)nt->serial);
- }
- }
- else {
- if (th->nt) {
- RUBY_DEBUG_LOG("th:%d nt:%d->NULL", (int)th->serial, (int)th->nt->serial);
- }
- else {
- RUBY_DEBUG_LOG("th:%d nt:NULL->NULL", (int)th->serial);
- }
- }
+#if USE_THREAD_CACHE
+static rb_thread_t *register_cached_thread_and_wait(void *);
#endif
- th->nt = nt;
-}
-
-static void
-native_thread_destroy(struct rb_native_thread *nt)
-{
- if (nt) {
- rb_native_cond_destroy(&nt->cond.readyq);
-
- if (&nt->cond.readyq != &nt->cond.intr) {
- rb_native_cond_destroy(&nt->cond.intr);
- }
-
- RB_ALTSTACK_FREE(nt->altstack);
- ruby_xfree(nt->nt_context);
- ruby_xfree(nt);
- }
-}
-
#if defined HAVE_PTHREAD_GETATTR_NP || defined HAVE_PTHREAD_ATTR_GET_NP
#define STACKADDR_AVAILABLE 1
#elif defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP
@@ -2056,15 +1124,13 @@ native_thread_init_stack(rb_thread_t *th)
}
else {
#ifdef STACKADDR_AVAILABLE
- if (th_has_dedicated_nt(th)) {
- void *start;
- size_t size;
-
- if (get_stack(&start, &size) == 0) {
- uintptr_t diff = (uintptr_t)start - (uintptr_t)&curr;
- th->ec->machine.stack_start = (VALUE *)&curr;
- th->ec->machine.stack_maxsize = size - diff;
- }
+ void *start;
+ size_t size;
+
+ if (get_stack(&start, &size) == 0) {
+ uintptr_t diff = (uintptr_t)start - (uintptr_t)&curr;
+ th->ec->machine.stack_start = (VALUE *)&curr;
+ th->ec->machine.stack_maxsize = size - diff;
}
#else
rb_raise(rb_eNotImpError, "ruby engine can initialize only in the main thread");
@@ -2074,280 +1140,198 @@ native_thread_init_stack(rb_thread_t *th)
return 0;
}
-struct nt_param {
- rb_vm_t *vm;
- struct rb_native_thread *nt;
-};
+#ifndef __CYGWIN__
+#define USE_NATIVE_THREAD_INIT 1
+#endif
static void *
-nt_start(void *ptr);
-
-static int
-native_thread_create0(struct rb_native_thread *nt)
+thread_start_func_1(void *th_ptr)
{
- int err = 0;
- pthread_attr_t attr;
-
- const size_t stack_size = nt->vm->default_params.thread_machine_stack_size;
- const size_t space = space_size(stack_size);
-
- nt->machine_stack_maxsize = stack_size - space;
-
-#ifdef USE_SIGALTSTACK
- nt->altstack = rb_allocate_sigaltstack();
+ rb_thread_t *th = th_ptr;
+ RB_ALTSTACK_INIT(void *altstack, th->nt->altstack);
+#if USE_THREAD_CACHE
+ thread_start:
+#endif
+ {
+#if !defined USE_NATIVE_THREAD_INIT
+ VALUE stack_start;
#endif
- CHECK_ERR(pthread_attr_init(&attr));
-
-# ifdef PTHREAD_STACK_MIN
- RUBY_DEBUG_LOG("stack size: %lu", (unsigned long)stack_size);
- CHECK_ERR(pthread_attr_setstacksize(&attr, stack_size));
-# endif
-
-# ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
- CHECK_ERR(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
-# endif
- CHECK_ERR(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
-
- err = pthread_create(&nt->thread_id, &attr, nt_start, nt);
-
- RUBY_DEBUG_LOG("nt:%d err:%d", (int)nt->serial, err);
-
- CHECK_ERR(pthread_attr_destroy(&attr));
-
- return err;
-}
-
-static void
-native_thread_setup(struct rb_native_thread *nt)
-{
- // init cond
- rb_native_cond_initialize(&nt->cond.readyq);
-
- if (&nt->cond.readyq != &nt->cond.intr) {
- rb_native_cond_initialize(&nt->cond.intr);
- }
-}
-
-static void
-native_thread_setup_on_thread(struct rb_native_thread *nt)
-{
- // init tid
-#ifdef RB_THREAD_T_HAS_NATIVE_ID
- nt->tid = get_native_thread_id();
+#if defined USE_NATIVE_THREAD_INIT
+ native_thread_init_stack(th);
#endif
- // init signal handler
- RB_ALTSTACK_INIT(nt->altstack, nt->altstack);
-}
+ native_thread_init(th->nt);
-static struct rb_native_thread *
-native_thread_alloc(void)
-{
- struct rb_native_thread *nt = ZALLOC(struct rb_native_thread);
- native_thread_setup(nt);
+ RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_STARTED);
-#if USE_MN_THREADS
- nt->nt_context = ruby_xmalloc(sizeof(struct coroutine_context));
+ /* run */
+#if defined USE_NATIVE_THREAD_INIT
+ thread_start_func_2(th, th->ec->machine.stack_start);
+#else
+ thread_start_func_2(th, &stack_start);
#endif
-#if USE_RUBY_DEBUG_LOG
- static rb_atomic_t nt_serial = 2;
- nt->serial = RUBY_ATOMIC_FETCH_ADD(nt_serial, 1);
+ RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_EXITED);
+ }
+#if USE_THREAD_CACHE
+ /* cache thread */
+ if ((th = register_cached_thread_and_wait(RB_ALTSTACK(altstack))) != 0) {
+ goto thread_start;
+ }
+#else
+ RB_ALTSTACK_FREE(altstack);
#endif
- return nt;
+ return 0;
}
-static int
-native_thread_create_dedicated(rb_thread_t *th)
-{
- th->nt = native_thread_alloc();
- th->nt->vm = th->vm;
- th->nt->running_thread = th;
- th->nt->dedicated = 1;
-
- // vm stack
- size_t vm_stack_word_size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
- void *vm_stack = ruby_xmalloc(vm_stack_word_size * sizeof(VALUE));
- th->sched.malloc_stack = true;
- rb_ec_initialize_vm_stack(th->ec, vm_stack, vm_stack_word_size);
- th->sched.context_stack = vm_stack;
-
- // setup
- thread_sched_to_ready(TH_SCHED(th), th);
+struct cached_thread_entry {
+ rb_nativethread_cond_t cond;
+ rb_nativethread_id_t thread_id;
+ rb_thread_t *th;
+ void *altstack;
+ struct ccan_list_node node;
+};
- return native_thread_create0(th->nt);
-}
+#if USE_THREAD_CACHE
+static rb_nativethread_lock_t thread_cache_lock = RB_NATIVETHREAD_LOCK_INIT;
+static CCAN_LIST_HEAD(cached_thread_head);
+# if defined(HAVE_WORKING_FORK)
static void
-call_thread_start_func_2(rb_thread_t *th)
+thread_cache_reset(void)
{
- native_thread_init_stack(th);
- thread_start_func_2(th, th->ec->machine.stack_start);
+ rb_native_mutex_initialize(&thread_cache_lock);
+ ccan_list_head_init(&cached_thread_head);
}
+# endif
-static void *
-nt_start(void *ptr)
-{
- struct rb_native_thread *nt = (struct rb_native_thread *)ptr;
- rb_vm_t *vm = nt->vm;
-
- native_thread_setup_on_thread(nt);
-
- // init tid
-#ifdef RB_THREAD_T_HAS_NATIVE_ID
- nt->tid = get_native_thread_id();
-#endif
-
-#if USE_RUBY_DEBUG_LOG && defined(RUBY_NT_SERIAL)
- ruby_nt_serial = nt->serial;
+/*
+ * number of seconds to cache for, I think 1-5s is sufficient to obviate
+ * the need for thread pool in many network programs (taking into account
+ * worst case network latency across the globe) without wasting memory
+ */
+#ifndef THREAD_CACHE_TIME
+# define THREAD_CACHE_TIME ((rb_hrtime_t)3 * RB_HRTIME_PER_SEC)
#endif
- RUBY_DEBUG_LOG("nt:%u", nt->serial);
-
- if (!nt->dedicated) {
- coroutine_initialize_main(nt->nt_context);
- }
+static rb_thread_t *
+register_cached_thread_and_wait(void *altstack)
+{
+ rb_hrtime_t end = THREAD_CACHE_TIME;
+ struct cached_thread_entry entry;
- while (1) {
- if (nt->dedicated) {
- // wait running turn
- rb_thread_t *th = nt->running_thread;
- struct rb_thread_sched *sched = TH_SCHED(th);
+ rb_native_cond_initialize(&entry.cond);
+ entry.altstack = altstack;
+ entry.th = NULL;
+ entry.thread_id = pthread_self();
+ end = native_cond_timeout(&entry.cond, end);
- RUBY_DEBUG_LOG("on dedicated th:%u", rb_th_serial(th));
- ruby_thread_set_native(th);
+ rb_native_mutex_lock(&thread_cache_lock);
+ {
+ ccan_list_add(&cached_thread_head, &entry.node);
- thread_sched_lock(sched, th);
- {
- if (sched->running == th) {
- thread_sched_add_running_thread(sched, th);
- }
- thread_sched_wait_running_turn(sched, th, false);
- }
- thread_sched_unlock(sched, th);
+ native_cond_timedwait(&entry.cond, &thread_cache_lock, &end);
- // start threads
- call_thread_start_func_2(th);
- break; // TODO: allow to change to the SNT
- }
- else {
- RUBY_DEBUG_LOG("check next");
- rb_ractor_t *r = ractor_sched_deq(vm, NULL);
-
- if (r) {
- struct rb_thread_sched *sched = &r->threads.sched;
-
- thread_sched_lock(sched, NULL);
- {
- rb_thread_t *next_th = sched->running;
-
- if (next_th && next_th->nt == NULL) {
- RUBY_DEBUG_LOG("nt:%d next_th:%d", (int)nt->serial, (int)next_th->serial);
- thread_sched_switch0(nt->nt_context, next_th, nt);
- }
- else {
- RUBY_DEBUG_LOG("no schedulable threads -- next_th:%p", next_th);
- }
- }
- thread_sched_unlock(sched, NULL);
- }
- else {
- // timeout -> deleted.
- break;
- }
+ if (entry.th == NULL) { /* unused */
+ ccan_list_del(&entry.node);
}
}
+ rb_native_mutex_unlock(&thread_cache_lock);
- return NULL;
-}
-
-static int native_thread_create_shared(rb_thread_t *th);
+ rb_native_cond_destroy(&entry.cond);
+ if (!entry.th) {
+ RB_ALTSTACK_FREE(entry.altstack);
+ }
-#if USE_MN_THREADS
-static void nt_free_stack(void *mstack);
+ return entry.th;
+}
+#else
+# if defined(HAVE_WORKING_FORK)
+static void thread_cache_reset(void) { }
+# endif
#endif
-void
-rb_threadptr_remove(rb_thread_t *th)
+static int
+use_cached_thread(rb_thread_t *th)
{
-#if USE_MN_THREADS
- if (th->sched.malloc_stack) {
- // dedicated
- return;
- }
- else {
- rb_vm_t *vm = th->vm;
- th->sched.finished = false;
+#if USE_THREAD_CACHE
+ struct cached_thread_entry *entry;
- RB_VM_LOCK_ENTER();
- {
- ccan_list_add(&vm->ractor.sched.zombie_threads, &th->sched.node.zombie_threads);
- }
- RB_VM_LOCK_LEAVE();
+ rb_native_mutex_lock(&thread_cache_lock);
+ entry = ccan_list_pop(&cached_thread_head, struct cached_thread_entry, node);
+ if (entry) {
+ entry->th = th;
+ /* th->nt->thread_id must be set before signal for Thread#name= */
+ th->nt->thread_id = entry->thread_id;
+ rb_native_cond_signal(&entry->cond);
}
+ rb_native_mutex_unlock(&thread_cache_lock);
+ return !!entry;
#endif
+ return 0;
}
-void
-rb_threadptr_sched_free(rb_thread_t *th)
+#if 0
+// TODO
+static void
+clear_thread_cache_altstack(void)
{
-#if USE_MN_THREADS
- if (th->sched.malloc_stack) {
- // has dedicated
- ruby_xfree(th->sched.context_stack);
- native_thread_destroy(th->nt);
- }
- else {
- nt_free_stack(th->sched.context_stack);
- // TODO: how to free nt and nt->altstack?
- }
+#if USE_THREAD_CACHE
+ struct cached_thread_entry *entry;
- if (th->sched.context) {
- ruby_xfree(th->sched.context);
- VM_ASSERT((th->sched.context = NULL) == NULL);
+ rb_native_mutex_lock(&thread_cache_lock);
+ ccan_list_for_each(&cached_thread_head, entry, node) {
+ void MAYBE_UNUSED(*altstack) = entry->altstack;
+ entry->altstack = 0;
+ RB_ALTSTACK_FREE(altstack);
}
-#else
- ruby_xfree(th->sched.context_stack);
- native_thread_destroy(th->nt);
+ rb_native_mutex_unlock(&thread_cache_lock);
#endif
-
- th->nt = NULL;
-}
-
-void
-rb_thread_sched_mark_zombies(rb_vm_t *vm)
-{
- if (!ccan_list_empty(&vm->ractor.sched.zombie_threads)) {
- rb_thread_t *zombie_th, *next_zombie_th;
- ccan_list_for_each_safe(&vm->ractor.sched.zombie_threads, zombie_th, next_zombie_th, sched.node.zombie_threads) {
- if (zombie_th->sched.finished) {
- ccan_list_del_init(&zombie_th->sched.node.zombie_threads);
- }
- else {
- rb_gc_mark(zombie_th->self);
- }
- }
- }
}
+#endif
static int
native_thread_create(rb_thread_t *th)
{
- VM_ASSERT(th->nt == 0);
- RUBY_DEBUG_LOG("th:%d has_dnt:%d", th->serial, th->has_dedicated_nt);
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_STARTED, th);
+ int err = 0;
- if (!th->ractor->threads.sched.enable_mn_threads) {
- th->has_dedicated_nt = 1;
- }
+ VM_ASSERT(th->nt == 0);
+ th->nt = ZALLOC(struct rb_native_thread);
- if (th->has_dedicated_nt) {
- return native_thread_create_dedicated(th);
+ if (use_cached_thread(th)) {
+ RUBY_DEBUG_LOG("use cached nt. th:%u", rb_th_serial(th));
}
else {
- return native_thread_create_shared(th);
+ pthread_attr_t attr;
+ const size_t stack_size = th->vm->default_params.thread_machine_stack_size + th->vm->default_params.thread_vm_stack_size;
+ const size_t space = space_size(stack_size);
+
+#ifdef USE_SIGALTSTACK
+ th->nt->altstack = rb_allocate_sigaltstack();
+#endif
+ th->ec->machine.stack_maxsize = stack_size - space;
+
+ CHECK_ERR(pthread_attr_init(&attr));
+
+# ifdef PTHREAD_STACK_MIN
+ RUBY_DEBUG_LOG("stack size: %lu", (unsigned long)stack_size);
+ CHECK_ERR(pthread_attr_setstacksize(&attr, stack_size));
+# endif
+
+# ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
+ CHECK_ERR(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
+# endif
+ CHECK_ERR(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
+
+ err = pthread_create(&th->nt->thread_id, &attr, thread_start_func_1, th);
+
+ RUBY_DEBUG_LOG("th:%u err:%d", rb_th_serial(th), err);
+
+ /* should be done in the created thread */
+ CHECK_ERR(pthread_attr_destroy(&attr));
}
+ return err;
}
#if USE_NATIVE_THREAD_PRIORITY
@@ -2390,7 +1374,7 @@ static void
ubf_pthread_cond_signal(void *ptr)
{
rb_thread_t *th = (rb_thread_t *)ptr;
- RUBY_DEBUG_LOG("th:%u on nt:%d", rb_th_serial(th), (int)th->nt->serial);
+ RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
rb_native_cond_signal(&th->nt->cond.intr);
}
@@ -2455,54 +1439,33 @@ ubf_list_atfork(void)
rb_native_mutex_initialize(&ubf_list_lock);
}
-RBIMPL_ATTR_MAYBE_UNUSED()
-static bool
-ubf_list_contain_p(rb_thread_t *th)
-{
- rb_thread_t *list_th;
- ccan_list_for_each(&ubf_list_head, list_th, sched.node.ubf) {
- if (list_th == th) return true;
- }
- return false;
-}
-
/* The thread 'th' is registered to be trying unblock. */
static void
register_ubf_list(rb_thread_t *th)
{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
struct ccan_list_node *node = &th->sched.node.ubf;
- VM_ASSERT(th->unblock.func != NULL);
-
- rb_native_mutex_lock(&ubf_list_lock);
- {
- // check not connected yet
- if (ccan_list_empty((struct ccan_list_head*)node)) {
- VM_ASSERT(!ubf_list_contain_p(th));
- ccan_list_add(&ubf_list_head, node);
- }
+ if (ccan_list_empty((struct ccan_list_head*)node)) {
+ rb_native_mutex_lock(&ubf_list_lock);
+ ccan_list_add(&ubf_list_head, node);
+ rb_native_mutex_unlock(&ubf_list_lock);
}
- rb_native_mutex_unlock(&ubf_list_lock);
-
- timer_thread_wakeup();
}
/* The thread 'th' is unblocked. It no longer need to be registered. */
static void
unregister_ubf_list(rb_thread_t *th)
{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
struct ccan_list_node *node = &th->sched.node.ubf;
/* we can't allow re-entry into ubf_list_head */
- VM_ASSERT(th->unblock.func == NULL);
+ VM_ASSERT(th->unblock.func == 0);
if (!ccan_list_empty((struct ccan_list_head*)node)) {
rb_native_mutex_lock(&ubf_list_lock);
- {
- VM_ASSERT(ubf_list_contain_p(th));
- ccan_list_del_init(node);
+ ccan_list_del_init(node);
+ if (ccan_list_empty(&ubf_list_head) && !rb_signal_buff_size()) {
+ ubf_timer_disarm();
}
rb_native_mutex_unlock(&ubf_list_lock);
}
@@ -2515,8 +1478,7 @@ unregister_ubf_list(rb_thread_t *th)
static void
ubf_wakeup_thread(rb_thread_t *th)
{
- RUBY_DEBUG_LOG("th:%u thread_id:%p", rb_th_serial(th), (void *)th->nt->thread_id);
-
+ RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
pthread_kill(th->nt->thread_id, SIGVTALRM);
}
@@ -2524,27 +1486,53 @@ static void
ubf_select(void *ptr)
{
rb_thread_t *th = (rb_thread_t *)ptr;
- RUBY_DEBUG_LOG("wakeup th:%u", rb_th_serial(th));
- ubf_wakeup_thread(th);
+ struct rb_thread_sched *sched = TH_SCHED(th);
+ const rb_thread_t *cur = ruby_thread_from_native(); /* may be 0 */
+
register_ubf_list(th);
+
+ /*
+ * ubf_wakeup_thread() doesn't guarantee to wake up a target thread.
+ * Therefore, we repeatedly call ubf_wakeup_thread() until a target thread
+ * exit from ubf function. We must have a timer to perform this operation.
+ * We use double-checked locking here because this function may be called
+ * while vm->gvl.lock is held in do_gvl_timer.
+ * There is also no need to start a timer if we're the designated
+ * sigwait_th thread, otherwise we can deadlock with a thread
+ * in unblock_function_clear.
+ */
+ if (cur != sched->timer && cur != sigwait_th) {
+ /*
+ * Double-checked locking above was to prevent nested locking
+ * by the SAME thread. We use trylock here to prevent deadlocks
+ * between DIFFERENT threads
+ */
+ if (rb_native_mutex_trylock(&sched->lock) == 0) {
+ if (!sched->timer) {
+ rb_thread_wakeup_timer_thread(-1);
+ }
+ rb_native_mutex_unlock(&sched->lock);
+ }
+ }
+
+ ubf_wakeup_thread(th);
}
-static bool
+static int
ubf_threads_empty(void)
{
- return ccan_list_empty(&ubf_list_head) != 0;
+ return ccan_list_empty(&ubf_list_head);
}
static void
ubf_wakeup_all_threads(void)
{
if (!ubf_threads_empty()) {
- rb_thread_t *th;
rb_native_mutex_lock(&ubf_list_lock);
- {
- ccan_list_for_each(&ubf_list_head, th, sched.node.ubf) {
- ubf_wakeup_thread(th);
- }
+ rb_thread_t *th;
+
+ ccan_list_for_each(&ubf_list_head, th, sched.node.ubf) {
+ ubf_wakeup_thread(th);
}
rb_native_mutex_unlock(&ubf_list_lock);
}
@@ -2555,35 +1543,154 @@ ubf_wakeup_all_threads(void)
#define unregister_ubf_list(th) (void)(th)
#define ubf_select 0
static void ubf_wakeup_all_threads(void) { return; }
-static bool ubf_threads_empty(void) { return true; }
+static int ubf_threads_empty(void) { return 1; }
#define ubf_list_atfork() do {} while (0)
#endif /* USE_UBF_LIST */
#define TT_DEBUG 0
#define WRITE_CONST(fd, str) (void)(write((fd),(str),sizeof(str)-1)<0)
+static struct {
+ /* pipes are closed in forked children when owner_process does not match */
+ int normal[2]; /* [0] == sigwait_fd */
+ int ub_main[2]; /* unblock main thread from native_ppoll_sleep */
+
+ /* volatile for signal handler use: */
+ volatile rb_pid_t owner_process;
+} signal_self_pipe = {
+ {-1, -1},
+ {-1, -1},
+};
+
+/* only use signal-safe system calls here */
+static void
+rb_thread_wakeup_timer_thread_fd(int fd)
+{
+#if USE_EVENTFD
+ const uint64_t buff = 1;
+#else
+ const char buff = '!';
+#endif
+ ssize_t result;
+
+ /* already opened */
+ if (fd >= 0) {
+ retry:
+ if ((result = write(fd, &buff, sizeof(buff))) <= 0) {
+ int e = errno;
+ switch (e) {
+ case EINTR: goto retry;
+ case EAGAIN:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ break;
+ default:
+ async_bug_fd("rb_thread_wakeup_timer_thread: write", e, fd);
+ }
+ }
+ if (TT_DEBUG) WRITE_CONST(2, "rb_thread_wakeup_timer_thread: write\n");
+ }
+ else {
+ /* ignore wakeup */
+ }
+}
+
+/*
+ * This ensures we get a SIGVTALRM in TIME_QUANTUM_MSEC if our
+ * process could not react to the original signal in time.
+ */
+static void
+ubf_timer_arm(rb_pid_t current) /* async signal safe */
+{
+#if UBF_TIMER == UBF_TIMER_POSIX
+ if ((!current || timer_posix.owner == current) &&
+ timer_state_cas(RTIMER_DISARM, RTIMER_ARMING) == RTIMER_DISARM) {
+ struct itimerspec it;
+
+ it.it_interval.tv_sec = it.it_value.tv_sec = 0;
+ it.it_interval.tv_nsec = it.it_value.tv_nsec = TIME_QUANTUM_NSEC;
+
+ if (timer_settime(timer_posix.timerid, 0, &it, 0))
+ rb_async_bug_errno("timer_settime (arm)", errno);
+
+ switch (timer_state_cas(RTIMER_ARMING, RTIMER_ARMED)) {
+ case RTIMER_DISARM:
+ /* somebody requested a disarm while we were arming */
+ /* may race harmlessly with ubf_timer_destroy */
+ (void)timer_settime(timer_posix.timerid, 0, &zero, 0);
+
+ case RTIMER_ARMING: return; /* success */
+ case RTIMER_ARMED:
+ /*
+ * it is possible to have another thread disarm, and
+ * a third thread arm finish re-arming before we get
+ * here, so we wasted a syscall with timer_settime but
+ * probably unavoidable in a signal handler.
+ */
+ return;
+ case RTIMER_DEAD:
+ /* may race harmlessly with ubf_timer_destroy */
+ (void)timer_settime(timer_posix.timerid, 0, &zero, 0);
+ return;
+ default:
+ rb_async_bug_errno("UBF_TIMER_POSIX unknown state", ERANGE);
+ }
+ }
+#elif UBF_TIMER == UBF_TIMER_PTHREAD
+ if (!current || current == timer_pthread.owner) {
+ if (ATOMIC_EXCHANGE(timer_pthread.armed, 1) == 0)
+ rb_thread_wakeup_timer_thread_fd(timer_pthread.low[1]);
+ }
+#endif
+}
+
void
rb_thread_wakeup_timer_thread(int sig)
{
- // This function can be called from signal handlers so that
- // pthread_mutex_lock() should not be used.
+ rb_pid_t current;
+
+ /* non-sighandler path */
+ if (sig <= 0) {
+ rb_thread_wakeup_timer_thread_fd(signal_self_pipe.normal[1]);
+ if (sig < 0) {
+ ubf_timer_arm(0);
+ }
+ return;
+ }
- // wakeup timer thread
- timer_thread_wakeup_force();
+ /* must be safe inside sighandler, so no mutex */
+ current = getpid();
+ if (signal_self_pipe.owner_process == current) {
+ rb_thread_wakeup_timer_thread_fd(signal_self_pipe.normal[1]);
- // interrupt main thread if main thread is available
- if (system_working) {
- rb_vm_t *vm = GET_VM();
- rb_thread_t *main_th = vm->ractor.main_thread;
+ /*
+ * system_working check is required because vm and main_thread are
+ * freed during shutdown
+ */
+ if (system_working > 0) {
+ volatile rb_execution_context_t *ec;
+ rb_vm_t *vm = GET_VM();
+ rb_thread_t *mth;
- if (main_th) {
- volatile rb_execution_context_t *main_th_ec = ACCESS_ONCE(rb_execution_context_t *, main_th->ec);
+ /*
+ * FIXME: root VM and main_thread should be static and not
+ * on heap for maximum safety (and startup/shutdown speed)
+ */
+ if (!vm) return;
+ mth = vm->ractor.main_thread;
+ if (!mth || system_working <= 0) return;
+
+ /* this relies on GC for grace period before cont_free */
+ ec = ACCESS_ONCE(rb_execution_context_t *, mth->ec);
- if (main_th_ec) {
- RUBY_VM_SET_TRAP_INTERRUPT(main_th_ec);
+ if (ec) {
+ RUBY_VM_SET_TRAP_INTERRUPT(ec);
+ ubf_timer_arm(current);
- if (vm->ubf_async_safe && main_th->unblock.func) {
- (main_th->unblock.func)(main_th->unblock.arg);
+ /* some ubfs can interrupt single-threaded process directly */
+ if (vm->ubf_async_safe && mth->unblock.func) {
+ (mth->unblock.func)(mth->unblock.arg);
}
}
}
@@ -2607,12 +1714,12 @@ static void
close_invalidate_pair(int fds[2], const char *msg)
{
if (USE_EVENTFD && fds[0] == fds[1]) {
- fds[1] = -1; // disable write port first
close_invalidate(&fds[0], msg);
+ fds[1] = -1;
}
else {
- close_invalidate(&fds[1], msg);
close_invalidate(&fds[0], msg);
+ close_invalidate(&fds[1], msg);
}
}
@@ -2632,15 +1739,15 @@ set_nonblock(int fd)
}
/* communication pipe with timer thread and signal handler */
-static void
+static int
setup_communication_pipe_internal(int pipes[2])
{
int err;
- if (pipes[0] > 0 || pipes[1] > 0) {
- VM_ASSERT(pipes[0] > 0);
- VM_ASSERT(pipes[1] > 0);
- return;
+ if (pipes[0] >= 0 || pipes[1] >= 0) {
+ VM_ASSERT(pipes[0] >= 0);
+ VM_ASSERT(pipes[1] >= 0);
+ return 0;
}
/*
@@ -2649,21 +1756,23 @@ setup_communication_pipe_internal(int pipes[2])
*/
#if USE_EVENTFD && defined(EFD_NONBLOCK) && defined(EFD_CLOEXEC)
pipes[0] = pipes[1] = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
-
if (pipes[0] >= 0) {
rb_update_max_fd(pipes[0]);
- return;
+ return 0;
}
#endif
err = rb_cloexec_pipe(pipes);
if (err != 0) {
- rb_bug("can not create communication pipe");
+ rb_warn("pipe creation failed for timer: %s, scheduling broken",
+ strerror(errno));
+ return -1;
}
rb_update_max_fd(pipes[0]);
rb_update_max_fd(pipes[1]);
set_nonblock(pipes[0]);
set_nonblock(pipes[1]);
+ return 0;
}
#if !defined(SET_CURRENT_THREAD_NAME) && defined(__linux__) && defined(PR_SET_NAME)
@@ -2746,18 +1855,12 @@ native_set_another_thread_name(rb_nativethread_id_t thread_id, VALUE name)
static VALUE
native_thread_native_thread_id(rb_thread_t *target_th)
{
- if (!target_th->nt) return Qnil;
-
#ifdef RB_THREAD_T_HAS_NATIVE_ID
int tid = target_th->nt->tid;
if (tid == 0) return Qnil;
return INT2FIX(tid);
#elif defined(__APPLE__)
uint64_t tid;
-/* The first condition is needed because MAC_OS_X_VERSION_10_6
- is not defined on 10.5, and while __POWERPC__ takes care of ppc/ppc64,
- i386 will be broken without this. Note, 10.5 is supported with GCC upstream,
- so it has C++17 and everything needed to build modern Ruby. */
# if (!defined(MAC_OS_X_VERSION_10_6) || \
(MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) || \
defined(__POWERPC__) /* never defined for PowerPC platforms */)
@@ -2788,322 +1891,174 @@ native_thread_native_thread_id(rb_thread_t *target_th)
# define USE_NATIVE_THREAD_NATIVE_THREAD_ID 0
#endif
-static struct {
- rb_serial_t created_fork_gen;
- pthread_t pthread_id;
-
- int comm_fds[2]; // r, w
-
-#if (HAVE_SYS_EPOLL_H || HAVE_SYS_EVENT_H) && USE_MN_THREADS
- int event_fd; // kernel event queue fd (epoll/kqueue)
-#endif
-#if HAVE_SYS_EPOLL_H && USE_MN_THREADS
-#define EPOLL_EVENTS_MAX 0x10
- struct epoll_event finished_events[EPOLL_EVENTS_MAX];
-#elif HAVE_SYS_EVENT_H && USE_MN_THREADS
-#define KQUEUE_EVENTS_MAX 0x10
- struct kevent finished_events[KQUEUE_EVENTS_MAX];
-#endif
-
- // waiting threads list
- struct ccan_list_head waiting; // waiting threads in ractors
- pthread_mutex_t waiting_lock;
-} timer_th = {
- .created_fork_gen = 0,
-};
-
-#define TIMER_THREAD_CREATED_P() (timer_th.created_fork_gen == current_fork_gen)
-
-static void timer_thread_check_timeslice(rb_vm_t *vm);
-static int timer_thread_set_timeout(rb_vm_t *vm);
-static void timer_thread_wakeup_thread(rb_thread_t *th);
-
-#include "thread_pthread_mn.c"
-
-static int
-timer_thread_set_timeout(rb_vm_t *vm)
+static void
+ubf_timer_invalidate(void)
{
-#if 0
- return 10; // ms
-#else
- int timeout = -1;
-
- ractor_sched_lock(vm, NULL);
- {
- if ( !ccan_list_empty(&vm->ractor.sched.timeslice_threads) // (1-1) Provide time slice for active NTs
- || !ubf_threads_empty() // (1-3) Periodic UBF
- || vm->ractor.sched.grq_cnt > 0 // (1-4) Lazy GRQ deq start
- ) {
-
- RUBY_DEBUG_LOG("timeslice:%d ubf:%d grq:%d",
- !ccan_list_empty(&vm->ractor.sched.timeslice_threads),
- !ubf_threads_empty(),
- (vm->ractor.sched.grq_cnt > 0));
-
- timeout = 10; // ms
- vm->ractor.sched.timeslice_wait_inf = false;
- }
- else {
- vm->ractor.sched.timeslice_wait_inf = true;
- }
- }
- ractor_sched_unlock(vm, NULL);
-
- if (vm->ractor.sched.timeslice_wait_inf) {
- rb_native_mutex_lock(&timer_th.waiting_lock);
- {
- rb_thread_t *th = ccan_list_top(&timer_th.waiting, rb_thread_t, sched.waiting_reason.node);
- if (th && (th->sched.waiting_reason.flags & thread_sched_waiting_timeout)) {
- rb_hrtime_t now = rb_hrtime_now();
- rb_hrtime_t hrrel = rb_hrtime_sub(th->sched.waiting_reason.data.timeout, now);
-
- RUBY_DEBUG_LOG("th:%u now:%lu rel:%lu", rb_th_serial(th), (unsigned long)now, (unsigned long)hrrel);
-
- // TODO: overflow?
- timeout = (int)((hrrel + RB_HRTIME_PER_MSEC - 1) / RB_HRTIME_PER_MSEC); // ms
- }
- }
- rb_native_mutex_unlock(&timer_th.waiting_lock);
- }
-
- RUBY_DEBUG_LOG("timeout:%d inf:%d", timeout, (int)vm->ractor.sched.timeslice_wait_inf);
-
- // fprintf(stderr, "timeout:%d\n", timeout);
- return timeout;
+#if UBF_TIMER == UBF_TIMER_PTHREAD
+ CLOSE_INVALIDATE_PAIR(timer_pthread.low);
#endif
}
static void
-timer_thread_check_signal(rb_vm_t *vm)
+ubf_timer_pthread_create(rb_pid_t current)
{
- // ruby_sigchld_handler(vm); TODO
+#if UBF_TIMER == UBF_TIMER_PTHREAD
+ int err;
+ if (timer_pthread.owner == current)
+ return;
- int signum = rb_signal_buff_size();
- if (UNLIKELY(signum > 0) && vm->ractor.main_thread) {
- RUBY_DEBUG_LOG("signum:%d", signum);
- threadptr_trap_interrupt(vm->ractor.main_thread);
- }
-}
+ if (setup_communication_pipe_internal(timer_pthread.low) < 0)
+ return;
-static bool
-timer_thread_check_exceed(rb_hrtime_t abs, rb_hrtime_t now)
-{
- if (abs < now) {
- return true;
- }
- else if (abs - now < RB_HRTIME_PER_MSEC) {
- return true; // too short time
- }
- else {
- return false;
- }
+ err = pthread_create(&timer_pthread.thid, 0, timer_pthread_fn, GET_VM());
+ if (!err)
+ timer_pthread.owner = current;
+ else
+ rb_warn("pthread_create failed for timer: %s, signals racy",
+ strerror(err));
+#endif
}
-static rb_thread_t *
-timer_thread_deq_wakeup(rb_vm_t *vm, rb_hrtime_t now)
+static void
+ubf_timer_create(rb_pid_t current)
{
- rb_thread_t *th = ccan_list_top(&timer_th.waiting, rb_thread_t, sched.waiting_reason.node);
+#if UBF_TIMER == UBF_TIMER_POSIX
+# if defined(__sun)
+# define UBF_TIMER_CLOCK CLOCK_REALTIME
+# else /* Tested Linux and FreeBSD: */
+# define UBF_TIMER_CLOCK CLOCK_MONOTONIC
+# endif
- if (th != NULL &&
- (th->sched.waiting_reason.flags & thread_sched_waiting_timeout) &&
- timer_thread_check_exceed(th->sched.waiting_reason.data.timeout, now)) {
+ struct sigevent sev;
- RUBY_DEBUG_LOG("wakeup th:%u", rb_th_serial(th));
+ sev.sigev_notify = SIGEV_SIGNAL;
+ sev.sigev_signo = SIGVTALRM;
+ sev.sigev_value.sival_ptr = &timer_posix;
- // delete from waiting list
- ccan_list_del_init(&th->sched.waiting_reason.node);
+ if (!timer_create(UBF_TIMER_CLOCK, &sev, &timer_posix.timerid)) {
+ rb_atomic_t prev = timer_state_exchange(RTIMER_DISARM);
- // setup result
- th->sched.waiting_reason.flags = thread_sched_waiting_none;
- th->sched.waiting_reason.data.result = 0;
-
- return th;
+ if (prev != RTIMER_DEAD) {
+ rb_bug("timer_posix was not dead: %u\n", (unsigned)prev);
+ }
+ timer_posix.owner = current;
}
-
- return NULL;
+ else {
+ rb_warn("timer_create failed: %s, signals racy", strerror(errno));
+ }
+#endif
+ if (UBF_TIMER == UBF_TIMER_PTHREAD)
+ ubf_timer_pthread_create(current);
}
static void
-timer_thread_wakeup_thread(rb_thread_t *th)
+rb_thread_create_timer_thread(void)
{
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
- struct rb_thread_sched *sched = TH_SCHED(th);
+ /* we only create the pipe, and lazy-spawn */
+ rb_pid_t current = getpid();
+ rb_pid_t owner = signal_self_pipe.owner_process;
- thread_sched_lock(sched, th);
- {
- if (sched->running != th) {
- thread_sched_to_ready_common(sched, th, true, false);
- }
- else {
- // will be release the execution right
- }
+ if (owner && owner != current) {
+ CLOSE_INVALIDATE_PAIR(signal_self_pipe.normal);
+ CLOSE_INVALIDATE_PAIR(signal_self_pipe.ub_main);
+ ubf_timer_invalidate();
}
- thread_sched_unlock(sched, th);
-}
-static void
-timer_thread_check_timeout(rb_vm_t *vm)
-{
- rb_hrtime_t now = rb_hrtime_now();
- rb_thread_t *th;
+ if (setup_communication_pipe_internal(signal_self_pipe.normal) < 0) return;
+ if (setup_communication_pipe_internal(signal_self_pipe.ub_main) < 0) return;
- rb_native_mutex_lock(&timer_th.waiting_lock);
- {
- while ((th = timer_thread_deq_wakeup(vm, now)) != NULL) {
- timer_thread_wakeup_thread(th);
- }
+ ubf_timer_create(current);
+ if (owner != current) {
+ /* validate pipe on this process */
+ sigwait_th = THREAD_INVALID;
+ signal_self_pipe.owner_process = current;
}
- rb_native_mutex_unlock(&timer_th.waiting_lock);
}
static void
-timer_thread_check_timeslice(rb_vm_t *vm)
+ubf_timer_disarm(void)
{
- // TODO: check time
- rb_thread_t *th;
- ccan_list_for_each(&vm->ractor.sched.timeslice_threads, th, sched.node.timeslice_threads) {
- RUBY_DEBUG_LOG("timeslice th:%u", rb_th_serial(th));
- RUBY_VM_SET_TIMER_INTERRUPT(th->ec);
- }
-}
+#if UBF_TIMER == UBF_TIMER_POSIX
+ rb_atomic_t prev;
-void
-rb_assert_sig(void)
-{
- sigset_t oldmask;
- pthread_sigmask(0, NULL, &oldmask);
- if (sigismember(&oldmask, SIGVTALRM)) {
- rb_bug("!!!");
- }
- else {
- RUBY_DEBUG_LOG("ok");
- }
-}
-
-static void *
-timer_thread_func(void *ptr)
-{
- rb_vm_t *vm = (rb_vm_t *)ptr;
-#if defined(RUBY_NT_SERIAL)
- ruby_nt_serial = (rb_atomic_t)-1;
-#endif
+ if (timer_posix.owner && timer_posix.owner != getpid()) return;
+ prev = timer_state_cas(RTIMER_ARMED, RTIMER_DISARM);
+ switch (prev) {
+ case RTIMER_DISARM: return; /* likely */
+ case RTIMER_ARMING: return; /* ubf_timer_arm will disarm itself */
+ case RTIMER_ARMED:
+ if (timer_settime(timer_posix.timerid, 0, &zero, 0)) {
+ int err = errno;
- RUBY_DEBUG_LOG("started%s", "");
+ if (err == EINVAL) {
+ prev = timer_state_cas(RTIMER_DISARM, RTIMER_DISARM);
- while (system_working) {
- timer_thread_check_signal(vm);
- timer_thread_check_timeout(vm);
- ubf_wakeup_all_threads();
+ /* main thread may have killed the timer */
+ if (prev == RTIMER_DEAD) return;
- RUBY_DEBUG_LOG("system_working:%d", system_working);
- timer_thread_polling(vm);
+ rb_bug_errno("timer_settime (disarm)", err);
+ }
+ }
+ return;
+ case RTIMER_DEAD: return; /* stay dead */
+ default:
+ rb_bug("UBF_TIMER_POSIX bad state: %u\n", (unsigned)prev);
}
- RUBY_DEBUG_LOG("terminated");
- return NULL;
+#elif UBF_TIMER == UBF_TIMER_PTHREAD
+ ATOMIC_SET(timer_pthread.armed, 0);
+#endif
}
-/* only use signal-safe system calls here */
static void
-signal_communication_pipe(int fd)
+ubf_timer_destroy(void)
{
-#if USE_EVENTFD
- const uint64_t buff = 1;
-#else
- const char buff = '!';
-#endif
- ssize_t result;
+#if UBF_TIMER == UBF_TIMER_POSIX
+ if (timer_posix.owner == getpid()) {
+ rb_atomic_t expect = RTIMER_DISARM;
+ size_t i, max = 10000000;
- /* already opened */
- if (fd >= 0) {
- retry:
- if ((result = write(fd, &buff, sizeof(buff))) <= 0) {
- int e = errno;
- switch (e) {
- case EINTR: goto retry;
- case EAGAIN:
-#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
- case EWOULDBLOCK:
-#endif
+ /* prevent signal handler from arming: */
+ for (i = 0; i < max; i++) {
+ switch (timer_state_cas(expect, RTIMER_DEAD)) {
+ case RTIMER_DISARM:
+ if (expect == RTIMER_DISARM) goto done;
+ expect = RTIMER_DISARM;
break;
- default:
- async_bug_fd("rb_thread_wakeup_timer_thread: write", e, fd);
+ case RTIMER_ARMING:
+ native_thread_yield(); /* let another thread finish arming */
+ expect = RTIMER_ARMED;
+ break;
+ case RTIMER_ARMED:
+ if (expect == RTIMER_ARMED) {
+ if (timer_settime(timer_posix.timerid, 0, &zero, 0))
+ rb_bug_errno("timer_settime (destroy)", errno);
+ goto done;
+ }
+ expect = RTIMER_ARMED;
+ break;
+ case RTIMER_DEAD:
+ rb_bug("RTIMER_DEAD unexpected");
}
}
- if (TT_DEBUG) WRITE_CONST(2, "rb_thread_wakeup_timer_thread: write\n");
- }
- else {
- // ignore wakeup
- }
-}
-
-static void
-timer_thread_wakeup_force(void)
-{
- // should not use RUBY_DEBUG_LOG() because it can be called within signal handlers.
- signal_communication_pipe(timer_th.comm_fds[1]);
-}
+ rb_bug("timed out waiting for timer to arm");
+done:
+ if (timer_delete(timer_posix.timerid) < 0)
+ rb_sys_fail("timer_delete");
-static void
-timer_thread_wakeup_locked(rb_vm_t *vm)
-{
- // should be locked before.
- ASSERT_ractor_sched_locked(vm, NULL);
-
- if (timer_th.created_fork_gen == current_fork_gen) {
- if (vm->ractor.sched.timeslice_wait_inf) {
- RUBY_DEBUG_LOG("wakeup with fd:%d", timer_th.comm_fds[1]);
- timer_thread_wakeup_force();
- }
- else {
- RUBY_DEBUG_LOG("will be wakeup...");
- }
+ VM_ASSERT(timer_state_exchange(RTIMER_DEAD) == RTIMER_DEAD);
}
-}
-
-static void
-timer_thread_wakeup(void)
-{
- rb_vm_t *vm = GET_VM();
+#elif UBF_TIMER == UBF_TIMER_PTHREAD
+ int err;
- ractor_sched_lock(vm, NULL);
- {
- timer_thread_wakeup_locked(vm);
+ timer_pthread.owner = 0;
+ ubf_timer_disarm();
+ rb_thread_wakeup_timer_thread_fd(timer_pthread.low[1]);
+ err = pthread_join(timer_pthread.thid, 0);
+ if (err) {
+ rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err);
}
- ractor_sched_unlock(vm, NULL);
-}
-
-static void
-rb_thread_create_timer_thread(void)
-{
- rb_serial_t created_fork_gen = timer_th.created_fork_gen;
-
- RUBY_DEBUG_LOG("fork_gen create:%d current:%d", (int)created_fork_gen, (int)current_fork_gen);
-
- timer_th.created_fork_gen = current_fork_gen;
-
- if (created_fork_gen != current_fork_gen) {
- if (created_fork_gen != 0) {
- RUBY_DEBUG_LOG("forked child process");
-
- CLOSE_INVALIDATE_PAIR(timer_th.comm_fds);
-#if HAVE_SYS_EPOLL_H && USE_MN_THREADS
- close_invalidate(&timer_th.event_fd, "close event_fd");
#endif
- rb_native_mutex_destroy(&timer_th.waiting_lock);
- }
-
- ccan_list_head_init(&timer_th.waiting);
- rb_native_mutex_initialize(&timer_th.waiting_lock);
-
- // open communication channel
- setup_communication_pipe_internal(timer_th.comm_fds);
-
- // open event fd
- timer_thread_setup_mn();
- }
-
- pthread_create(&timer_th.pthread_id, NULL, timer_thread_func, GET_VM());
}
static int
@@ -3111,13 +2066,8 @@ native_stop_timer_thread(void)
{
int stopped;
stopped = --system_working <= 0;
-
- if (stopped) {
- RUBY_DEBUG_LOG("wakeup send %d", timer_th.comm_fds[1]);
- timer_thread_wakeup_force();
- RUBY_DEBUG_LOG("wakeup sent");
- pthread_join(timer_th.pthread_id, NULL);
- }
+ if (stopped)
+ ubf_timer_destroy();
if (TT_DEBUG) fprintf(stderr, "stop timer thread\n");
return stopped;
@@ -3126,7 +2076,7 @@ native_stop_timer_thread(void)
static void
native_reset_timer_thread(void)
{
- //
+ if (TT_DEBUG) fprintf(stderr, "reset timer thread\n");
}
#ifdef HAVE_SIGALTSTACK
@@ -3177,26 +2127,22 @@ int
rb_reserved_fd_p(int fd)
{
/* no false-positive if out-of-FD at startup */
- if (fd < 0) return 0;
+ if (fd < 0)
+ return 0;
- if (fd == timer_th.comm_fds[0] ||
- fd == timer_th.comm_fds[1]
-#if (HAVE_SYS_EPOLL_H || HAVE_SYS_EVENT_H) && USE_MN_THREADS
- || fd == timer_th.event_fd
+#if UBF_TIMER == UBF_TIMER_PTHREAD
+ if (fd == timer_pthread.low[0] || fd == timer_pthread.low[1])
+ goto check_pid;
#endif
- ) {
- goto check_fork_gen;
- }
+ if (fd == signal_self_pipe.normal[0] || fd == signal_self_pipe.normal[1])
+ goto check_pid;
+ if (fd == signal_self_pipe.ub_main[0] || fd == signal_self_pipe.ub_main[1])
+ goto check_pid;
return 0;
-
- check_fork_gen:
- if (timer_th.created_fork_gen == current_fork_gen) {
- /* async-signal-safe */
+check_pid:
+ if (signal_self_pipe.owner_process == getpid()) /* async-signal-safe */
return 1;
- }
- else {
- return 0;
- }
+ return 0;
}
rb_nativethread_id_t
@@ -3205,7 +2151,35 @@ rb_nativethread_self(void)
return pthread_self();
}
-#if defined(USE_POLL) && !defined(HAVE_PPOLL)
+int
+rb_sigwait_fd_get(const rb_thread_t *th)
+{
+ if (signal_self_pipe.normal[0] >= 0) {
+ VM_ASSERT(signal_self_pipe.owner_process == getpid());
+ /*
+ * no need to keep firing the timer if any thread is sleeping
+ * on the signal self-pipe
+ */
+ ubf_timer_disarm();
+
+ if (ATOMIC_PTR_CAS(sigwait_th, THREAD_INVALID, th) == THREAD_INVALID) {
+ return signal_self_pipe.normal[0];
+ }
+ }
+ return -1; /* avoid thundering herd and work stealing/starvation */
+}
+
+void
+rb_sigwait_fd_put(const rb_thread_t *th, int fd)
+{
+ const rb_thread_t *old;
+
+ VM_ASSERT(signal_self_pipe.normal[0] == fd);
+ old = ATOMIC_PTR_EXCHANGE(sigwait_th, THREAD_INVALID);
+ if (old != th) assert(old == th);
+}
+
+#ifndef HAVE_PPOLL
/* TODO: don't ignore sigmask */
static int
ruby_ppoll(struct pollfd *fds, nfds_t nfds,
@@ -3236,6 +2210,61 @@ ruby_ppoll(struct pollfd *fds, nfds_t nfds,
# define ppoll(fds,nfds,ts,sigmask) ruby_ppoll((fds),(nfds),(ts),(sigmask))
#endif
+void
+rb_sigwait_sleep(rb_thread_t *th, int sigwait_fd, const rb_hrtime_t *rel)
+{
+ struct pollfd pfd;
+ struct timespec ts;
+
+ pfd.fd = sigwait_fd;
+ pfd.events = POLLIN;
+
+ if (!BUSY_WAIT_SIGNALS && ubf_threads_empty()) {
+ (void)ppoll(&pfd, 1, rb_hrtime2timespec(&ts, rel), 0);
+ check_signals_nogvl(th, sigwait_fd);
+ }
+ else {
+ rb_hrtime_t to = RB_HRTIME_MAX, end = 0;
+ int n = 0;
+
+ if (rel) {
+ to = *rel;
+ end = rb_hrtime_add(rb_hrtime_now(), to);
+ }
+ /*
+ * tricky: this needs to return on spurious wakeup (no auto-retry).
+ * But we also need to distinguish between periodic quantum
+ * wakeups, so we care about the result of consume_communication_pipe
+ *
+ * We want to avoid spurious wakeup for Mutex#sleep compatibility
+ * [ruby-core:88102]
+ */
+ for (;;) {
+ const rb_hrtime_t *sto = sigwait_timeout(th, sigwait_fd, &to, &n);
+
+ if (n) return;
+ n = ppoll(&pfd, 1, rb_hrtime2timespec(&ts, sto), 0);
+ if (check_signals_nogvl(th, sigwait_fd))
+ return;
+ if (n || (th && RUBY_VM_INTERRUPTED(th->ec)))
+ return;
+ if (rel && hrtime_update_expire(&to, end))
+ return;
+ }
+ }
+}
+
+/*
+ * we need to guarantee wakeups from native_ppoll_sleep because
+ * ubf_select may not be going through ubf_list if other threads
+ * are all sleeping.
+ */
+static void
+ubf_ppoll_sleep(void *ignore)
+{
+ rb_thread_wakeup_timer_thread_fd(signal_self_pipe.ub_main[1]);
+}
+
/*
* Single CPU setups benefit from explicit sched_yield() before ppoll(),
* since threads may be too starved to enter the GVL waitqueue for
@@ -3247,130 +2276,153 @@ ruby_ppoll(struct pollfd *fds, nfds_t nfds,
* [ruby-core:90417] [Bug #15398]
*/
#define THREAD_BLOCKING_YIELD(th) do { \
- const rb_thread_t *next_th; \
+ const rb_thread_t *next; \
struct rb_thread_sched *sched = TH_SCHED(th); \
- RB_VM_SAVE_MACHINE_CONTEXT(th); \
- thread_sched_to_waiting(sched, (th)); \
- next_th = sched->running; \
- rb_native_mutex_unlock(&sched->lock_); \
- native_thread_yield(); /* TODO: needed? */ \
- if (!next_th && rb_ractor_living_thread_num(th->ractor) > 1) { \
+ RB_GC_SAVE_MACHINE_CONTEXT(th); \
+ rb_native_mutex_lock(&sched->lock); \
+ next = thread_sched_to_waiting_common(sched); \
+ rb_native_mutex_unlock(&sched->lock); \
+ if (!next && rb_ractor_living_thread_num(th->ractor) > 1) { \
native_thread_yield(); \
}
+/*
+ * This function does not exclusively acquire sigwait_fd, so it
+ * cannot safely read from it. However, it can be woken up in
+ * 4 ways:
+ *
+ * 1) ubf_ppoll_sleep (from another thread)
+ * 2) rb_thread_wakeup_timer_thread (from signal handler)
+ * 3) any unmasked signal hitting the process
+ * 4) periodic ubf timer wakeups (after 3)
+ */
static void
-native_sleep(rb_thread_t *th, rb_hrtime_t *rel)
+native_ppoll_sleep(rb_thread_t *th, rb_hrtime_t *rel)
{
- struct rb_thread_sched *sched = TH_SCHED(th);
+ rb_native_mutex_lock(&th->interrupt_lock);
+ th->unblock.func = ubf_ppoll_sleep;
+ rb_native_mutex_unlock(&th->interrupt_lock);
- RUBY_DEBUG_LOG("rel:%d", rel ? (int)*rel : 0);
- if (rel) {
- if (th_has_dedicated_nt(th)) {
- native_cond_sleep(th, rel);
- }
- else {
- thread_sched_wait_events(sched, th, -1, thread_sched_waiting_timeout, rel);
+ THREAD_BLOCKING_YIELD(th);
+ {
+ if (!RUBY_VM_INTERRUPTED(th->ec)) {
+ struct pollfd pfd[2];
+ struct timespec ts;
+
+ pfd[0].fd = signal_self_pipe.normal[0]; /* sigwait_fd */
+ pfd[1].fd = signal_self_pipe.ub_main[0];
+ pfd[0].events = pfd[1].events = POLLIN;
+ if (ppoll(pfd, 2, rb_hrtime2timespec(&ts, rel), 0) > 0) {
+ if (pfd[1].revents & POLLIN) {
+ (void)consume_communication_pipe(pfd[1].fd);
+ }
+ }
+ /*
+ * do not read the sigwait_fd, here, let uplevel callers
+ * or other threads that, otherwise we may steal and starve
+ * other threads
+ */
}
+ unblock_function_clear(th);
}
- else {
- thread_sched_to_waiting_until_wakeup(sched, th);
- }
-
- RUBY_DEBUG_LOG("wakeup");
+ THREAD_BLOCKING_END(th);
}
-// thread internal event hooks (only for pthread)
-
-struct rb_internal_thread_event_hook {
- rb_internal_thread_event_callback callback;
- rb_event_flag_t event;
- void *user_data;
+static void
+native_sleep(rb_thread_t *th, rb_hrtime_t *rel)
+{
+ int sigwait_fd = rb_sigwait_fd_get(th);
+ rb_ractor_blocking_threads_inc(th->ractor, __FILE__, __LINE__);
- struct rb_internal_thread_event_hook *next;
-};
+ RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED);
-static pthread_rwlock_t rb_internal_thread_event_hooks_rw_lock = PTHREAD_RWLOCK_INITIALIZER;
+ if (sigwait_fd >= 0) {
+ rb_native_mutex_lock(&th->interrupt_lock);
+ th->unblock.func = ubf_sigwait;
+ rb_native_mutex_unlock(&th->interrupt_lock);
-rb_internal_thread_event_hook_t *
-rb_internal_thread_add_event_hook(rb_internal_thread_event_callback callback, rb_event_flag_t internal_event, void *user_data)
-{
- rb_internal_thread_event_hook_t *hook = ALLOC_N(rb_internal_thread_event_hook_t, 1);
- hook->callback = callback;
- hook->user_data = user_data;
- hook->event = internal_event;
+ THREAD_BLOCKING_YIELD(th);
+ {
+ if (!RUBY_VM_INTERRUPTED(th->ec)) {
+ rb_sigwait_sleep(th, sigwait_fd, rel);
+ }
+ else {
+ check_signals_nogvl(th, sigwait_fd);
+ }
+ unblock_function_clear(th);
+ }
+ THREAD_BLOCKING_END(th);
- int r;
- if ((r = pthread_rwlock_wrlock(&rb_internal_thread_event_hooks_rw_lock))) {
- rb_bug_errno("pthread_rwlock_wrlock", r);
+ rb_sigwait_fd_put(th, sigwait_fd);
+ rb_sigwait_fd_migrate(th->vm);
}
-
- hook->next = rb_internal_thread_event_hooks;
- ATOMIC_PTR_EXCHANGE(rb_internal_thread_event_hooks, hook);
-
- if ((r = pthread_rwlock_unlock(&rb_internal_thread_event_hooks_rw_lock))) {
- rb_bug_errno("pthread_rwlock_unlock", r);
+ else if (th == th->vm->ractor.main_thread) { /* always able to handle signals */
+ native_ppoll_sleep(th, rel);
}
- return hook;
+ else {
+ native_cond_sleep(th, rel);
+ }
+
+ rb_ractor_blocking_threads_dec(th->ractor, __FILE__, __LINE__);
}
-bool
-rb_internal_thread_remove_event_hook(rb_internal_thread_event_hook_t * hook)
+#if UBF_TIMER == UBF_TIMER_PTHREAD
+static void *
+timer_pthread_fn(void *p)
{
- int r;
- if ((r = pthread_rwlock_wrlock(&rb_internal_thread_event_hooks_rw_lock))) {
- rb_bug_errno("pthread_rwlock_wrlock", r);
- }
+ rb_vm_t *vm = p;
+ pthread_t main_thread_id = vm->ractor.main_thread->nt->thread_id;
+ struct pollfd pfd;
+ int timeout = -1;
+ int ccp;
- bool success = FALSE;
+ pfd.fd = timer_pthread.low[0];
+ pfd.events = POLLIN;
- if (rb_internal_thread_event_hooks == hook) {
- ATOMIC_PTR_EXCHANGE(rb_internal_thread_event_hooks, hook->next);
- success = TRUE;
- }
- else {
- rb_internal_thread_event_hook_t *h = rb_internal_thread_event_hooks;
+ while (system_working > 0) {
+ (void)poll(&pfd, 1, timeout);
+ ccp = consume_communication_pipe(pfd.fd);
- do {
- if (h->next == hook) {
- h->next = hook->next;
- success = TRUE;
- break;
- }
- } while ((h = h->next));
- }
+ if (system_working > 0) {
+ if (ATOMIC_CAS(timer_pthread.armed, 1, 1)) {
+ pthread_kill(main_thread_id, SIGVTALRM);
- if ((r = pthread_rwlock_unlock(&rb_internal_thread_event_hooks_rw_lock))) {
- rb_bug_errno("pthread_rwlock_unlock", r);
+ if (rb_signal_buff_size() || !ubf_threads_empty()) {
+ timeout = TIME_QUANTUM_MSEC;
+ }
+ else {
+ ATOMIC_SET(timer_pthread.armed, 0);
+ timeout = -1;
+ }
+ }
+ else if (ccp) {
+ pthread_kill(main_thread_id, SIGVTALRM);
+ ATOMIC_SET(timer_pthread.armed, 0);
+ timeout = -1;
+ }
+ }
}
- if (success) {
- ruby_xfree(hook);
- }
- return success;
+ return 0;
}
+#endif /* UBF_TIMER_PTHREAD */
-static void
-rb_thread_execute_hooks(rb_event_flag_t event, rb_thread_t *th)
+static VALUE
+ubf_caller(void *ignore)
{
- int r;
- if ((r = pthread_rwlock_rdlock(&rb_internal_thread_event_hooks_rw_lock))) {
- rb_bug_errno("pthread_rwlock_rdlock", r);
- }
+ rb_thread_sleep_forever();
- if (rb_internal_thread_event_hooks) {
- rb_internal_thread_event_hook_t *h = rb_internal_thread_event_hooks;
- do {
- if (h->event & event) {
- rb_internal_thread_event_data_t event_data = {
- .thread = th->self,
- };
- (*h->callback)(event, &event_data, h->user_data);
- }
- } while((h = h->next));
- }
- if ((r = pthread_rwlock_unlock(&rb_internal_thread_event_hooks_rw_lock))) {
- rb_bug_errno("pthread_rwlock_unlock", r);
- }
+ return Qfalse;
}
+/*
+ * Called if and only if one thread is running, and
+ * the unblock function is NOT async-signal-safe
+ * This assumes USE_THREAD_CACHE is true for performance reasons
+ */
+static VALUE
+rb_thread_start_unblock_thread(void)
+{
+ return rb_thread_create(ubf_caller, 0);
+}
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
diff --git a/thread_pthread.h b/thread_pthread.h
index 20c4b9f9a8..0f8e4d6096 100644
--- a/thread_pthread.h
+++ b/thread_pthread.h
@@ -19,59 +19,14 @@
// per-Thead scheduler helper data
struct rb_thread_sched_item {
- struct {
+ union {
struct ccan_list_node ubf;
-
- // connected to ractor->threads.sched.reqdyq
- // locked by ractor->threads.sched.lock
- struct ccan_list_node readyq;
-
- // connected to vm->ractor.sched.timeslice_threads
- // locked by vm->ractor.sched.lock
- struct ccan_list_node timeslice_threads;
-
- // connected to vm->ractor.sched.running_threads
- // locked by vm->ractor.sched.lock
- struct ccan_list_node running_threads;
-
- // connected to vm->ractor.sched.zombie_threads
- struct ccan_list_node zombie_threads;
+ struct ccan_list_node readyq; // protected by sched->lock
} node;
-
- // this data should be protected by timer_th.waiting_lock
- struct {
- enum thread_sched_waiting_flag {
- thread_sched_waiting_none = 0x00,
- thread_sched_waiting_timeout = 0x01,
- thread_sched_waiting_io_read = 0x02,
- thread_sched_waiting_io_write = 0x08,
- thread_sched_waiting_io_force = 0x40, // ignore readable
- } flags;
-
- struct {
- // should be compat with hrtime.h
-#ifdef MY_RUBY_BUILD_MAY_TIME_TRAVEL
- int128_t timeout;
-#else
- uint64_t timeout;
-#endif
- int fd; // -1 for timeout only
- int result;
- } data;
-
- // connected to timer_th.waiting
- struct ccan_list_node node;
- } waiting_reason;
-
- bool finished;
- bool malloc_stack;
- void *context_stack;
- struct coroutine_context *context;
};
struct rb_native_thread {
- rb_atomic_t serial;
- struct rb_vm_struct *vm;
+ int id;
rb_nativethread_id_t thread_id;
@@ -99,11 +54,6 @@ struct rb_native_thread {
#ifdef USE_SIGALTSTACK
void *altstack;
#endif
-
- struct coroutine_context *nt_context;
- int dedicated;
-
- size_t machine_stack_maxsize;
};
#undef except
@@ -113,35 +63,51 @@ struct rb_native_thread {
// per-Ractor
struct rb_thread_sched {
- rb_nativethread_lock_t lock_;
-#if VM_CHECK_MODE
- struct rb_thread_struct *lock_owner;
-#endif
- struct rb_thread_struct *running; // running thread or NULL
- bool is_running;
- bool is_running_timeslice;
- bool enable_mn_threads;
+ /* fast path */
+ const struct rb_thread_struct *running; // running thread or NULL
+ rb_nativethread_lock_t lock;
+
+ /*
+ * slow path, protected by ractor->thread_sched->lock
+ * - @readyq - FIFO queue of threads waiting for running
+ * - @timer - it handles timeslices for @current. It is any one thread
+ * in @waitq, there is no @timer if @waitq is empty, but always
+ * a @timer if @waitq has entries
+ * - @timer_err tracks timeslice limit, the timeslice only resets
+ * when pthread_cond_timedwait returns ETIMEDOUT, so frequent
+ * switching between contended/uncontended GVL won't reset the
+ * timer.
+ */
struct ccan_list_head readyq;
- int readyq_cnt;
- // ractor scheduling
- struct ccan_list_node grq_node;
+ const struct rb_thread_struct *timer;
+ int timer_err;
+
+ /* yield */
+ rb_nativethread_cond_t switch_cond;
+ rb_nativethread_cond_t switch_wait_cond;
+ int need_yield;
+ int wait_yield;
};
+#ifndef RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED
+# if __STDC_VERSION__ >= 201112
+# define RB_THREAD_LOCAL_SPECIFIER _Thread_local
+# elif defined(__GNUC__)
+ /* note that ICC (linux) and Clang are covered by __GNUC__ */
+# define RB_THREAD_LOCAL_SPECIFIER __thread
+# endif
+#endif
+
+RUBY_SYMBOL_EXPORT_BEGIN
#ifdef RB_THREAD_LOCAL_SPECIFIER
- NOINLINE(void rb_current_ec_set(struct rb_execution_context_struct *));
- NOINLINE(struct rb_execution_context_struct *rb_current_ec_noinline(void));
-
- # ifdef __APPLE__
- // on Darwin, TLS can not be accessed across .so
- NOINLINE(struct rb_execution_context_struct *rb_current_ec(void));
- # else
- RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
-
- // for RUBY_DEBUG_LOG()
- RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER rb_atomic_t ruby_nt_serial;
- #define RUBY_NT_SERIAL 1
- # endif
+# ifdef __APPLE__
+// on Darwin, TLS can not be accessed across .so
+struct rb_execution_context_struct *rb_current_ec(void);
+void rb_current_ec_set(struct rb_execution_context_struct *);
+# else
+RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
+# endif
#else
typedef pthread_key_t native_tls_key_t;
@@ -162,5 +128,6 @@ native_tls_set(native_tls_key_t key, void *ptr)
RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
#endif
+RUBY_SYMBOL_EXPORT_END
#endif /* RUBY_THREAD_PTHREAD_H */
diff --git a/thread_pthread_mn.c b/thread_pthread_mn.c
deleted file mode 100644
index c8c7d9f173..0000000000
--- a/thread_pthread_mn.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-// included by "thread_pthread.c"
-
-#if USE_MN_THREADS
-
-static void timer_thread_unregister_waiting(rb_thread_t *th, int fd, enum thread_sched_waiting_flag flags);
-
-static bool
-timer_thread_cancel_waiting(rb_thread_t *th)
-{
- bool canceled = false;
-
- if (th->sched.waiting_reason.flags) {
- rb_native_mutex_lock(&timer_th.waiting_lock);
- {
- if (th->sched.waiting_reason.flags) {
- canceled = true;
- ccan_list_del_init(&th->sched.waiting_reason.node);
- if (th->sched.waiting_reason.flags & (thread_sched_waiting_io_read | thread_sched_waiting_io_write)) {
- timer_thread_unregister_waiting(th, th->sched.waiting_reason.data.fd, th->sched.waiting_reason.flags);
- }
- th->sched.waiting_reason.flags = thread_sched_waiting_none;
- }
- }
- rb_native_mutex_unlock(&timer_th.waiting_lock);
- }
-
- return canceled;
-}
-
-static void
-ubf_event_waiting(void *ptr)
-{
- rb_thread_t *th = (rb_thread_t *)ptr;
- struct rb_thread_sched *sched = TH_SCHED(th);
-
- RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
-
- VM_ASSERT(th->nt == NULL || !th_has_dedicated_nt(th));
-
- // only once. it is safe because th->interrupt_lock is already acquired.
- th->unblock.func = NULL;
- th->unblock.arg = NULL;
-
- bool canceled = timer_thread_cancel_waiting(th);
-
- thread_sched_lock(sched, th);
- {
- if (sched->running == th) {
- RUBY_DEBUG_LOG("not waiting yet");
- }
- else if (canceled) {
- thread_sched_to_ready_common(sched, th, true, false);
- }
- else {
- RUBY_DEBUG_LOG("already not waiting");
- }
- }
- thread_sched_unlock(sched, th);
-}
-
-static bool timer_thread_register_waiting(rb_thread_t *th, int fd, enum thread_sched_waiting_flag flags, rb_hrtime_t *rel);
-
-// return true if timed out
-static bool
-thread_sched_wait_events(struct rb_thread_sched *sched, rb_thread_t *th, int fd, enum thread_sched_waiting_flag events, rb_hrtime_t *rel)
-{
- VM_ASSERT(!th_has_dedicated_nt(th)); // on SNT
-
- volatile bool timedout = false, need_cancel = false;
-
- if (timer_thread_register_waiting(th, fd, events, rel)) {
- RUBY_DEBUG_LOG("wait fd:%d", fd);
-
- RB_VM_SAVE_MACHINE_CONTEXT(th);
- setup_ubf(th, ubf_event_waiting, (void *)th);
-
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_SUSPENDED, th);
-
- thread_sched_lock(sched, th);
- {
- if (th->sched.waiting_reason.flags == thread_sched_waiting_none) {
- // already awaken
- }
- else if (RUBY_VM_INTERRUPTED(th->ec)) {
- need_cancel = true;
- }
- else {
- RUBY_DEBUG_LOG("sleep");
-
- th->status = THREAD_STOPPED_FOREVER;
- thread_sched_wakeup_next_thread(sched, th, true);
- thread_sched_wait_running_turn(sched, th, true);
-
- RUBY_DEBUG_LOG("wakeup");
- }
-
- timedout = th->sched.waiting_reason.data.result == 0;
- }
- thread_sched_unlock(sched, th);
-
- if (need_cancel) {
- timer_thread_cancel_waiting(th);
- }
-
- setup_ubf(th, NULL, NULL); // TODO: maybe it is already NULL?
-
- th->status = THREAD_RUNNABLE;
- }
- else {
- RUBY_DEBUG_LOG("can not wait fd:%d", fd);
- return false;
- }
-
- VM_ASSERT(sched->running == th);
-
- return timedout;
-}
-
-/// stack management
-
-static int
-get_sysconf_page_size(void)
-{
- static long page_size = 0;
-
- if (UNLIKELY(page_size == 0)) {
- page_size = sysconf(_SC_PAGESIZE);
- VM_ASSERT(page_size < INT_MAX);
- }
- return (int)page_size;
-}
-
-#define MSTACK_CHUNK_SIZE (512 * 1024 * 1024) // 512MB
-#define MSTACK_PAGE_SIZE get_sysconf_page_size()
-#define MSTACK_CHUNK_PAGE_NUM (MSTACK_CHUNK_SIZE / MSTACK_PAGE_SIZE - 1) // 1 is start redzone
-
-// 512MB chunk
-// 131,072 pages (> 65,536)
-// 0th page is Redzone. Start from 1st page.
-
-/*
- * <--> machine stack + vm stack
- * ----------------------------------
- * |HD...|RZ| ... |RZ| ... ... |RZ|
- * <------------- 512MB ------------->
- */
-
-static struct nt_stack_chunk_header {
- struct nt_stack_chunk_header *prev_chunk;
- struct nt_stack_chunk_header *prev_free_chunk;
-
- uint16_t start_page;
- uint16_t stack_count;
- uint16_t uninitialized_stack_count;
-
- uint16_t free_stack_pos;
- uint16_t free_stack[];
-} *nt_stack_chunks = NULL,
- *nt_free_stack_chunks = NULL;
-
-struct nt_machine_stack_footer {
- struct nt_stack_chunk_header *ch;
- size_t index;
-};
-
-static rb_nativethread_lock_t nt_machine_stack_lock = RB_NATIVETHREAD_LOCK_INIT;
-
-#include <sys/mman.h>
-
-// vm_stack_size + machine_stack_size + 1 * (guard page size)
-static inline size_t
-nt_thread_stack_size(void)
-{
- static size_t msz;
- if (LIKELY(msz > 0)) return msz;
-
- rb_vm_t *vm = GET_VM();
- int sz = (int)(vm->default_params.thread_vm_stack_size + vm->default_params.thread_machine_stack_size + MSTACK_PAGE_SIZE);
- int page_num = roomof(sz, MSTACK_PAGE_SIZE);
- msz = (size_t)page_num * MSTACK_PAGE_SIZE;
- return msz;
-}
-
-static struct nt_stack_chunk_header *
-nt_alloc_thread_stack_chunk(void)
-{
- int mmap_flags = MAP_ANONYMOUS | MAP_PRIVATE;
-#if defined(MAP_STACK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
- mmap_flags |= MAP_STACK;
-#endif
-
- const char *m = (void *)mmap(NULL, MSTACK_CHUNK_SIZE, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
- if (m == MAP_FAILED) {
- return NULL;
- }
-
- size_t msz = nt_thread_stack_size();
- int header_page_cnt = 1;
- int stack_count = ((MSTACK_CHUNK_PAGE_NUM - header_page_cnt) * MSTACK_PAGE_SIZE) / msz;
- int ch_size = sizeof(struct nt_stack_chunk_header) + sizeof(uint16_t) * stack_count;
-
- if (ch_size > MSTACK_PAGE_SIZE * header_page_cnt) {
- header_page_cnt = (ch_size + MSTACK_PAGE_SIZE - 1) / MSTACK_PAGE_SIZE;
- stack_count = ((MSTACK_CHUNK_PAGE_NUM - header_page_cnt) * MSTACK_PAGE_SIZE) / msz;
- }
-
- VM_ASSERT(stack_count <= UINT16_MAX);
-
- struct nt_stack_chunk_header *ch = (struct nt_stack_chunk_header *)m;
-
- ch->start_page = header_page_cnt;
- ch->prev_chunk = nt_stack_chunks;
- ch->prev_free_chunk = nt_free_stack_chunks;
- ch->uninitialized_stack_count = ch->stack_count = (uint16_t)stack_count;
- ch->free_stack_pos = 0;
-
- RUBY_DEBUG_LOG("ch:%p start_page:%d stack_cnt:%d stack_size:%d", ch, (int)ch->start_page, (int)ch->stack_count, (int)msz);
-
- return ch;
-}
-
-static void *
-nt_stack_chunk_get_stack_start(struct nt_stack_chunk_header *ch, size_t idx)
-{
- const char *m = (char *)ch;
- return (void *)(m + ch->start_page * MSTACK_PAGE_SIZE + idx * nt_thread_stack_size());
-}
-
-static struct nt_machine_stack_footer *
-nt_stack_chunk_get_msf(const rb_vm_t *vm, const char *mstack)
-{
- // TODO: stack direction
- const size_t msz = vm->default_params.thread_machine_stack_size;
- return (struct nt_machine_stack_footer *)&mstack[msz - sizeof(struct nt_machine_stack_footer)];
-}
-
-static void *
-nt_stack_chunk_get_stack(const rb_vm_t *vm, struct nt_stack_chunk_header *ch, size_t idx, void **vm_stack, void **machine_stack)
-{
- // TODO: only support stack going down
- // [VM ... <GUARD> machine stack ...]
-
- const char *vstack, *mstack;
- const char *guard_page;
- vstack = nt_stack_chunk_get_stack_start(ch, idx);
- guard_page = vstack + vm->default_params.thread_vm_stack_size;
- mstack = guard_page + MSTACK_PAGE_SIZE;
-
- struct nt_machine_stack_footer *msf = nt_stack_chunk_get_msf(vm, mstack);
- msf->ch = ch;
- msf->index = idx;
-
-#if 0
- RUBY_DEBUG_LOG("msf:%p vstack:%p-%p guard_page:%p-%p mstack:%p-%p", msf,
- vstack, (void *)(guard_page-1),
- guard_page, (void *)(mstack-1),
- mstack, (void *)(msf));
-#endif
-
- *vm_stack = (void *)vstack;
- *machine_stack = (void *)mstack;
-
- return (void *)guard_page;
-}
-
-RBIMPL_ATTR_MAYBE_UNUSED()
-static void
-nt_stack_chunk_dump(void)
-{
- struct nt_stack_chunk_header *ch;
- int i;
-
- fprintf(stderr, "** nt_stack_chunks\n");
- ch = nt_stack_chunks;
- for (i=0; ch; i++, ch = ch->prev_chunk) {
- fprintf(stderr, "%d %p free_pos:%d\n", i, (void *)ch, (int)ch->free_stack_pos);
- }
-
- fprintf(stderr, "** nt_free_stack_chunks\n");
- ch = nt_free_stack_chunks;
- for (i=0; ch; i++, ch = ch->prev_free_chunk) {
- fprintf(stderr, "%d %p free_pos:%d\n", i, (void *)ch, (int)ch->free_stack_pos);
- }
-}
-
-static int
-nt_guard_page(const char *p, size_t len)
-{
- if (mprotect((void *)p, len, PROT_NONE) != -1) {
- return 0;
- }
- else {
- return errno;
- }
-}
-
-static int
-nt_alloc_stack(rb_vm_t *vm, void **vm_stack, void **machine_stack)
-{
- int err = 0;
-
- rb_native_mutex_lock(&nt_machine_stack_lock);
- {
- retry:
- if (nt_free_stack_chunks) {
- struct nt_stack_chunk_header *ch = nt_free_stack_chunks;
- if (ch->free_stack_pos > 0) {
- RUBY_DEBUG_LOG("free_stack_pos:%d", ch->free_stack_pos);
- nt_stack_chunk_get_stack(vm, ch, ch->free_stack[--ch->free_stack_pos], vm_stack, machine_stack);
- }
- else if (ch->uninitialized_stack_count > 0) {
- RUBY_DEBUG_LOG("uninitialized_stack_count:%d", ch->uninitialized_stack_count);
-
- size_t idx = ch->stack_count - ch->uninitialized_stack_count--;
- void *guard_page = nt_stack_chunk_get_stack(vm, ch, idx, vm_stack, machine_stack);
- err = nt_guard_page(guard_page, MSTACK_PAGE_SIZE);
- }
- else {
- nt_free_stack_chunks = ch->prev_free_chunk;
- ch->prev_free_chunk = NULL;
- goto retry;
- }
- }
- else {
- struct nt_stack_chunk_header *p = nt_alloc_thread_stack_chunk();
- if (p == NULL) {
- err = errno;
- }
- else {
- nt_free_stack_chunks = nt_stack_chunks = p;
- goto retry;
- }
- }
- }
- rb_native_mutex_unlock(&nt_machine_stack_lock);
-
- return err;
-}
-
-static void
-nt_free_stack(void *mstack)
-{
- if (!mstack) return;
-
- rb_native_mutex_lock(&nt_machine_stack_lock);
- {
- struct nt_machine_stack_footer *msf = nt_stack_chunk_get_msf(GET_VM(), mstack);
- struct nt_stack_chunk_header *ch = msf->ch;
- int idx = (int)msf->index;
- void *stack = nt_stack_chunk_get_stack_start(ch, idx);
-
- RUBY_DEBUG_LOG("stack:%p mstack:%p ch:%p index:%d", stack, mstack, ch, idx);
-
- if (ch->prev_free_chunk == NULL) {
- ch->prev_free_chunk = nt_free_stack_chunks;
- nt_free_stack_chunks = ch;
- }
- ch->free_stack[ch->free_stack_pos++] = idx;
-
- // clear the stack pages
-#if defined(MADV_FREE)
- int r = madvise(stack, nt_thread_stack_size(), MADV_FREE);
-#elif defined(MADV_DONTNEED)
- int r = madvise(stack, nt_thread_stack_size(), MADV_DONTNEED);
-#else
- int r = 0;
-#endif
-
- if (r != 0) rb_bug("madvise errno:%d", errno);
- }
- rb_native_mutex_unlock(&nt_machine_stack_lock);
-}
-
-static int
-native_thread_check_and_create_shared(rb_vm_t *vm)
-{
- bool need_to_make = false;
-
- rb_native_mutex_lock(&vm->ractor.sched.lock);
- {
- unsigned int snt_cnt = vm->ractor.sched.snt_cnt;
- if (!vm->ractor.main_ractor->threads.sched.enable_mn_threads) snt_cnt++; // do not need snt for main ractor
-
- if (((int)snt_cnt < MINIMUM_SNT) ||
- (snt_cnt < vm->ractor.cnt &&
- snt_cnt < vm->ractor.sched.max_cpu)) {
-
- RUBY_DEBUG_LOG("added snt:%u dnt:%u ractor_cnt:%u grq_cnt:%u",
- vm->ractor.sched.snt_cnt,
- vm->ractor.sched.dnt_cnt,
- vm->ractor.cnt,
- vm->ractor.sched.grq_cnt);
-
- vm->ractor.sched.snt_cnt++;
- need_to_make = true;
- }
- else {
- RUBY_DEBUG_LOG("snt:%d ractor_cnt:%d", (int)vm->ractor.sched.snt_cnt, (int)vm->ractor.cnt);
- }
- }
- rb_native_mutex_unlock(&vm->ractor.sched.lock);
-
- if (need_to_make) {
- struct rb_native_thread *nt = native_thread_alloc();
- nt->vm = vm;
- return native_thread_create0(nt);
- }
- else {
- return 0;
- }
-}
-
-static COROUTINE
-co_start(struct coroutine_context *from, struct coroutine_context *self)
-{
- rb_thread_t *th = (rb_thread_t *)self->argument;
- struct rb_thread_sched *sched = TH_SCHED(th);
- VM_ASSERT(th->nt != NULL);
- VM_ASSERT(th == sched->running);
- VM_ASSERT(sched->lock_owner == NULL);
-
- // RUBY_DEBUG_LOG("th:%u", rb_th_serial(th));
-
- thread_sched_set_lock_owner(sched, th);
- thread_sched_add_running_thread(TH_SCHED(th), th);
- thread_sched_unlock(sched, th);
- {
- RB_INTERNAL_THREAD_HOOK(RUBY_INTERNAL_THREAD_EVENT_RESUMED, th);
- call_thread_start_func_2(th);
- }
- thread_sched_lock(sched, NULL);
-
- RUBY_DEBUG_LOG("terminated th:%d", (int)th->serial);
-
- // Thread is terminated
-
- VM_ASSERT(!th_has_dedicated_nt(th));
-
- rb_vm_t *vm = th->vm;
- bool has_ready_ractor = vm->ractor.sched.grq_cnt > 0; // at least this ractor is not queued
-
- rb_thread_t *next_th = sched->running;
- struct rb_native_thread *nt = th->nt;
- native_thread_assign(NULL, th);
- rb_ractor_set_current_ec(th->ractor, NULL);
-
- if (!has_ready_ractor && next_th && !next_th->nt) {
- // switch to the next thread
- thread_sched_set_lock_owner(sched, NULL);
- thread_sched_switch0(th->sched.context, next_th, nt);
- th->sched.finished = true;
- }
- else {
- // switch to the next Ractor
- th->sched.finished = true;
- coroutine_transfer(self, nt->nt_context);
- }
- rb_bug("unreachable");
-}
-
-static int
-native_thread_create_shared(rb_thread_t *th)
-{
- // setup coroutine
- rb_vm_t *vm = th->vm;
- void *vm_stack = NULL, *machine_stack = NULL;
- int err = nt_alloc_stack(vm, &vm_stack, &machine_stack);
- if (err) return err;
-
- VM_ASSERT(vm_stack < machine_stack);
-
- // setup vm stack
- size_t vm_stack_words = th->vm->default_params.thread_vm_stack_size/sizeof(VALUE);
- rb_ec_initialize_vm_stack(th->ec, vm_stack, vm_stack_words);
-
- // setup machine stack
- size_t machine_stack_size = vm->default_params.thread_machine_stack_size - sizeof(struct nt_machine_stack_footer);
- th->ec->machine.stack_start = (void *)((uintptr_t)machine_stack + machine_stack_size);
- th->ec->machine.stack_maxsize = machine_stack_size; // TODO
- th->sched.context_stack = machine_stack;
-
- th->sched.context = ruby_xmalloc(sizeof(struct coroutine_context));
- coroutine_initialize(th->sched.context, co_start, machine_stack, machine_stack_size);
- th->sched.context->argument = th;
-
- RUBY_DEBUG_LOG("th:%u vm_stack:%p machine_stack:%p", rb_th_serial(th), vm_stack, machine_stack);
- thread_sched_to_ready(TH_SCHED(th), th);
-
- // setup nt
- return native_thread_check_and_create_shared(th->vm);
-}
-
-#else // USE_MN_THREADS
-
-static int
-native_thread_create_shared(rb_thread_t *th)
-{
- rb_bug("unreachable");
-}
-
-static bool
-thread_sched_wait_events(struct rb_thread_sched *sched, rb_thread_t *th, int fd, enum thread_sched_waiting_flag events, rb_hrtime_t *rel)
-{
- rb_bug("unreachable");
-}
-
-#endif // USE_MN_THREADS
-
-/// EPOLL/KQUEUE specific code
-#if (HAVE_SYS_EPOLL_H || HAVE_SYS_EVENT_H) && USE_MN_THREADS
-
-static bool
-fd_readable_nonblock(int fd)
-{
- struct pollfd pfd = {
- .fd = fd,
- .events = POLLIN,
- };
- return poll(&pfd, 1, 0) != 0;
-}
-
-static bool
-fd_writable_nonblock(int fd)
-{
- struct pollfd pfd = {
- .fd = fd,
- .events = POLLOUT,
- };
- return poll(&pfd, 1, 0) != 0;
-}
-
-static void
-verify_waiting_list(void)
-{
-#if VM_CHECK_MODE > 0
- rb_thread_t *wth, *prev_wth = NULL;
- ccan_list_for_each(&timer_th.waiting, wth, sched.waiting_reason.node) {
- // fprintf(stderr, "verify_waiting_list th:%u abs:%lu\n", rb_th_serial(wth), (unsigned long)wth->sched.waiting_reason.data.timeout);
- if (prev_wth) {
- rb_hrtime_t timeout = wth->sched.waiting_reason.data.timeout;
- rb_hrtime_t prev_timeout = prev_wth->sched.waiting_reason.data.timeout;
- VM_ASSERT(timeout == 0 || prev_timeout <= timeout);
- }
- prev_wth = wth;
- }
-#endif
-}
-
-#if HAVE_SYS_EVENT_H // kqueue helpers
-
-static enum thread_sched_waiting_flag
-kqueue_translate_filter_to_flags(int16_t filter)
-{
- switch (filter) {
- case EVFILT_READ:
- return thread_sched_waiting_io_read;
- case EVFILT_WRITE:
- return thread_sched_waiting_io_write;
- case EVFILT_TIMER:
- return thread_sched_waiting_timeout;
- default:
- rb_bug("kevent filter:%d not supported", filter);
- }
-}
-
-static int
-kqueue_wait(rb_vm_t *vm)
-{
- struct timespec calculated_timeout;
- struct timespec *timeout = NULL;
- int timeout_ms = timer_thread_set_timeout(vm);
-
- if (timeout_ms >= 0) {
- calculated_timeout.tv_sec = timeout_ms / 1000;
- calculated_timeout.tv_nsec = (timeout_ms % 1000) * 1000000;
- timeout = &calculated_timeout;
- }
-
- return kevent(timer_th.event_fd, NULL, 0, timer_th.finished_events, KQUEUE_EVENTS_MAX, timeout);
-}
-
-static void
-kqueue_create(void)
-{
- if ((timer_th.event_fd = kqueue()) == -1) rb_bug("kqueue creation failed (errno:%d)", errno);
- int flags = fcntl(timer_th.event_fd, F_GETFD);
- if (flags == -1) {
- rb_bug("kqueue GETFD failed (errno:%d)", errno);
- }
-
- flags |= FD_CLOEXEC;
- if (fcntl(timer_th.event_fd, F_SETFD, flags) == -1) {
- rb_bug("kqueue SETFD failed (errno:%d)", errno);
- }
-}
-
-static void
-kqueue_unregister_waiting(int fd, enum thread_sched_waiting_flag flags)
-{
- if (flags) {
- struct kevent ke[2];
- int num_events = 0;
-
- if (flags & thread_sched_waiting_io_read) {
- EV_SET(&ke[num_events], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
- num_events++;
- }
- if (flags & thread_sched_waiting_io_write) {
- EV_SET(&ke[num_events], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
- num_events++;
- }
- if (kevent(timer_th.event_fd, ke, num_events, NULL, 0, NULL) == -1) {
- perror("kevent");
- rb_bug("unregister/kevent fails. errno:%d", errno);
- }
- }
-}
-
-static bool
-kqueue_already_registered(int fd)
-{
- rb_thread_t *wth, *found_wth = NULL;
- ccan_list_for_each(&timer_th.waiting, wth, sched.waiting_reason.node) {
- // Similar to EEXIST in epoll_ctl, but more strict because it checks fd rather than flags
- // for simplicity
- if (wth->sched.waiting_reason.flags && wth->sched.waiting_reason.data.fd == fd) {
- found_wth = wth;
- break;
- }
- }
- return found_wth != NULL;
-}
-
-#endif // HAVE_SYS_EVENT_H
-
-// return false if the fd is not waitable or not need to wait.
-static bool
-timer_thread_register_waiting(rb_thread_t *th, int fd, enum thread_sched_waiting_flag flags, rb_hrtime_t *rel)
-{
- RUBY_DEBUG_LOG("th:%u fd:%d flag:%d rel:%lu", rb_th_serial(th), fd, flags, rel ? (unsigned long)*rel : 0);
-
- VM_ASSERT(th == NULL || TH_SCHED(th)->running == th);
- VM_ASSERT(flags != 0);
-
- rb_hrtime_t abs = 0; // 0 means no timeout
-
- if (rel) {
- if (*rel > 0) {
- flags |= thread_sched_waiting_timeout;
- }
- else {
- return false;
- }
- }
-
- if (rel && *rel > 0) {
- flags |= thread_sched_waiting_timeout;
- }
-
-#if HAVE_SYS_EVENT_H
- struct kevent ke[2];
- int num_events = 0;
-#else
- uint32_t epoll_events = 0;
-#endif
- if (flags & thread_sched_waiting_timeout) {
- VM_ASSERT(rel != NULL);
- abs = rb_hrtime_add(rb_hrtime_now(), *rel);
- }
-
- if (flags & thread_sched_waiting_io_read) {
- if (!(flags & thread_sched_waiting_io_force) && fd_readable_nonblock(fd)) {
- RUBY_DEBUG_LOG("fd_readable_nonblock");
- return false;
- }
- else {
- VM_ASSERT(fd >= 0);
-#if HAVE_SYS_EVENT_H
- EV_SET(&ke[num_events], fd, EVFILT_READ, EV_ADD, 0, 0, (void *)th);
- num_events++;
-#else
- epoll_events |= EPOLLIN;
-#endif
- }
- }
-
- if (flags & thread_sched_waiting_io_write) {
- if (!(flags & thread_sched_waiting_io_force) && fd_writable_nonblock(fd)) {
- RUBY_DEBUG_LOG("fd_writable_nonblock");
- return false;
- }
- else {
- VM_ASSERT(fd >= 0);
-#if HAVE_SYS_EVENT_H
- EV_SET(&ke[num_events], fd, EVFILT_WRITE, EV_ADD, 0, 0, (void *)th);
- num_events++;
-#else
- epoll_events |= EPOLLOUT;
-#endif
- }
- }
-
- rb_native_mutex_lock(&timer_th.waiting_lock);
- {
-#if HAVE_SYS_EVENT_H
- if (num_events > 0) {
- if (kqueue_already_registered(fd)) {
- rb_native_mutex_unlock(&timer_th.waiting_lock);
- return false;
- }
-
- if (kevent(timer_th.event_fd, ke, num_events, NULL, 0, NULL) == -1) {
- RUBY_DEBUG_LOG("failed (%d)", errno);
-
- switch (errno) {
- case EBADF:
- // the fd is closed?
- case EINTR:
- // signal received? is there a sensible way to handle this?
- default:
- perror("kevent");
- rb_bug("register/kevent failed(fd:%d, errno:%d)", fd, errno);
- }
- }
- RUBY_DEBUG_LOG("kevent(add, fd:%d) success", fd);
- }
-#else
- if (epoll_events) {
- struct epoll_event event = {
- .events = epoll_events,
- .data = {
- .ptr = (void *)th,
- },
- };
- if (epoll_ctl(timer_th.event_fd, EPOLL_CTL_ADD, fd, &event) == -1) {
- RUBY_DEBUG_LOG("failed (%d)", errno);
-
- switch (errno) {
- case EBADF:
- // the fd is closed?
- case EPERM:
- // the fd doesn't support epoll
- case EEXIST:
- // the fd is already registerred by another thread
- rb_native_mutex_unlock(&timer_th.waiting_lock);
- return false;
- default:
- perror("epoll_ctl");
- rb_bug("register/epoll_ctl failed(fd:%d, errno:%d)", fd, errno);
- }
- }
- RUBY_DEBUG_LOG("epoll_ctl(add, fd:%d, events:%d) success", fd, epoll_events);
- }
-#endif
-
- if (th) {
- VM_ASSERT(th->sched.waiting_reason.flags == thread_sched_waiting_none);
-
- // setup waiting information
- {
- th->sched.waiting_reason.flags = flags;
- th->sched.waiting_reason.data.timeout = abs;
- th->sched.waiting_reason.data.fd = fd;
- th->sched.waiting_reason.data.result = 0;
- }
-
- if (abs == 0) { // no timeout
- VM_ASSERT(!(flags & thread_sched_waiting_timeout));
- ccan_list_add_tail(&timer_th.waiting, &th->sched.waiting_reason.node);
- }
- else {
- RUBY_DEBUG_LOG("abs:%lu", abs);
- VM_ASSERT(flags & thread_sched_waiting_timeout);
-
- // insert th to sorted list (TODO: O(n))
- rb_thread_t *wth, *prev_wth = NULL;
-
- ccan_list_for_each(&timer_th.waiting, wth, sched.waiting_reason.node) {
- if ((wth->sched.waiting_reason.flags & thread_sched_waiting_timeout) &&
- wth->sched.waiting_reason.data.timeout < abs) {
- prev_wth = wth;
- }
- else {
- break;
- }
- }
-
- if (prev_wth) {
- ccan_list_add_after(&timer_th.waiting, &prev_wth->sched.waiting_reason.node, &th->sched.waiting_reason.node);
- }
- else {
- ccan_list_add(&timer_th.waiting, &th->sched.waiting_reason.node);
- }
-
- verify_waiting_list();
-
- // update timeout seconds
- timer_thread_wakeup();
- }
- }
- else {
- VM_ASSERT(abs == 0);
- }
- }
- rb_native_mutex_unlock(&timer_th.waiting_lock);
-
- return true;
-}
-
-static void
-timer_thread_unregister_waiting(rb_thread_t *th, int fd, enum thread_sched_waiting_flag flags)
-{
- RUBY_DEBUG_LOG("th:%u fd:%d", rb_th_serial(th), fd);
-#if HAVE_SYS_EVENT_H
- kqueue_unregister_waiting(fd, flags);
-#else
- // Linux 2.6.9 or later is needed to pass NULL as data.
- if (epoll_ctl(timer_th.event_fd, EPOLL_CTL_DEL, fd, NULL) == -1) {
- switch (errno) {
- case EBADF:
- // just ignore. maybe fd is closed.
- break;
- default:
- perror("epoll_ctl");
- rb_bug("unregister/epoll_ctl fails. errno:%d", errno);
- }
- }
-#endif
-}
-
-static void
-timer_thread_setup_mn(void)
-{
-#if HAVE_SYS_EVENT_H
- kqueue_create();
- RUBY_DEBUG_LOG("kqueue_fd:%d", timer_th.event_fd);
-#else
- if ((timer_th.event_fd = epoll_create1(EPOLL_CLOEXEC)) == -1) rb_bug("epoll_create (errno:%d)", errno);
- RUBY_DEBUG_LOG("epoll_fd:%d", timer_th.event_fd);
-#endif
- RUBY_DEBUG_LOG("comm_fds:%d/%d", timer_th.comm_fds[0], timer_th.comm_fds[1]);
-
- timer_thread_register_waiting(NULL, timer_th.comm_fds[0], thread_sched_waiting_io_read | thread_sched_waiting_io_force, NULL);
-}
-
-static int
-event_wait(rb_vm_t *vm)
-{
-#if HAVE_SYS_EVENT_H
- int r = kqueue_wait(vm);
-#else
- int r = epoll_wait(timer_th.event_fd, timer_th.finished_events, EPOLL_EVENTS_MAX, timer_thread_set_timeout(vm));
-#endif
- return r;
-}
-
-/*
- * The purpose of the timer thread:
- *
- * (1) Periodic checking
- * (1-1) Provide time slice for active NTs
- * (1-2) Check NT shortage
- * (1-3) Periodic UBF (global)
- * (1-4) Lazy GRQ deq start
- * (2) Receive notification
- * (2-1) async I/O termination
- * (2-2) timeout
- * (2-2-1) sleep(n)
- * (2-2-2) timeout(n), I/O, ...
- */
-static void
-timer_thread_polling(rb_vm_t *vm)
-{
- int r = event_wait(vm);
-
- RUBY_DEBUG_LOG("r:%d errno:%d", r, errno);
-
- switch (r) {
- case 0: // timeout
- RUBY_DEBUG_LOG("timeout%s", "");
-
- ractor_sched_lock(vm, NULL);
- {
- // (1-1) timeslice
- timer_thread_check_timeslice(vm);
-
- // (1-4) lazy grq deq
- if (vm->ractor.sched.grq_cnt > 0) {
- RUBY_DEBUG_LOG("GRQ cnt: %u", vm->ractor.sched.grq_cnt);
- rb_native_cond_signal(&vm->ractor.sched.cond);
- }
- }
- ractor_sched_unlock(vm, NULL);
-
- // (1-2)
- native_thread_check_and_create_shared(vm);
-
- break;
-
- case -1:
- switch (errno) {
- case EINTR:
- // simply retry
- break;
- default:
- perror("event_wait");
- rb_bug("event_wait errno:%d", errno);
- }
- break;
-
- default:
- RUBY_DEBUG_LOG("%d event(s)", r);
-
-#if HAVE_SYS_EVENT_H
- for (int i=0; i<r; i++) {
- rb_thread_t *th = (rb_thread_t *)timer_th.finished_events[i].udata;
- int fd = (int)timer_th.finished_events[i].ident;
- int16_t filter = timer_th.finished_events[i].filter;
-
- if (th == NULL) {
- // wakeup timerthread
- RUBY_DEBUG_LOG("comm from fd:%d", timer_th.comm_fds[1]);
- consume_communication_pipe(timer_th.comm_fds[0]);
- } else {
- // wakeup specific thread by IO
- RUBY_DEBUG_LOG("io event. wakeup_th:%u event:%s%s",
- rb_th_serial(th),
- (filter == EVFILT_READ) ? "read/" : "",
- (filter == EVFILT_WRITE) ? "write/" : "");
-
- rb_native_mutex_lock(&timer_th.waiting_lock);
- {
- if (th->sched.waiting_reason.flags) {
- // delete from chain
- ccan_list_del_init(&th->sched.waiting_reason.node);
- timer_thread_unregister_waiting(th, fd, kqueue_translate_filter_to_flags(filter));
-
- th->sched.waiting_reason.flags = thread_sched_waiting_none;
- th->sched.waiting_reason.data.fd = -1;
- th->sched.waiting_reason.data.result = filter;
-
- timer_thread_wakeup_thread(th);
- } else {
- // already released
- }
- }
- rb_native_mutex_unlock(&timer_th.waiting_lock);
- }
- }
-#else
- for (int i=0; i<r; i++) {
- rb_thread_t *th = (rb_thread_t *)timer_th.finished_events[i].data.ptr;
-
- if (th == NULL) {
- // wakeup timerthread
- RUBY_DEBUG_LOG("comm from fd:%d", timer_th.comm_fds[1]);
- consume_communication_pipe(timer_th.comm_fds[0]);
- }
- else {
- // wakeup specific thread by IO
- uint32_t events = timer_th.finished_events[i].events;
-
- RUBY_DEBUG_LOG("io event. wakeup_th:%u event:%s%s%s%s%s%s",
- rb_th_serial(th),
- (events & EPOLLIN) ? "in/" : "",
- (events & EPOLLOUT) ? "out/" : "",
- (events & EPOLLRDHUP) ? "RDHUP/" : "",
- (events & EPOLLPRI) ? "pri/" : "",
- (events & EPOLLERR) ? "err/" : "",
- (events & EPOLLHUP) ? "hup/" : "");
-
- rb_native_mutex_lock(&timer_th.waiting_lock);
- {
- if (th->sched.waiting_reason.flags) {
- // delete from chain
- ccan_list_del_init(&th->sched.waiting_reason.node);
- timer_thread_unregister_waiting(th, th->sched.waiting_reason.data.fd, th->sched.waiting_reason.flags);
-
- th->sched.waiting_reason.flags = thread_sched_waiting_none;
- th->sched.waiting_reason.data.fd = -1;
- th->sched.waiting_reason.data.result = (int)events;
-
- timer_thread_wakeup_thread(th);
- }
- else {
- // already released
- }
- }
- rb_native_mutex_unlock(&timer_th.waiting_lock);
- }
- }
-#endif
- }
-}
-
-#else // HAVE_SYS_EPOLL_H || HAVE_SYS_EVENT_H
-
-static void
-timer_thread_setup_mn(void)
-{
- // do nothing
-}
-
-static void
-timer_thread_polling(rb_vm_t *vm)
-{
- int timeout = timer_thread_set_timeout(vm);
-
- struct pollfd pfd = {
- .fd = timer_th.comm_fds[0],
- .events = POLLIN,
- };
-
- int r = poll(&pfd, 1, timeout);
-
- switch (r) {
- case 0: // timeout
- rb_native_mutex_lock(&vm->ractor.sched.lock);
- {
- // (1-1) timeslice
- timer_thread_check_timeslice(vm);
- }
- rb_native_mutex_unlock(&vm->ractor.sched.lock);
- break;
-
- case -1: // error
- switch (errno) {
- case EINTR:
- // simply retry
- break;
- default:
- perror("poll");
- rb_bug("poll errno:%d", errno);
- break;
- }
-
- case 1:
- consume_communication_pipe(timer_th.comm_fds[0]);
- break;
-
- default:
- rb_bug("unreachbale");
- }
-}
-
-#endif // HAVE_SYS_EPOLL_H || HAVE_SYS_EVENT_H
diff --git a/thread_sync.c b/thread_sync.c
index c0a0ca7103..4a78708348 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -41,8 +41,6 @@ struct queue_sleep_arg {
static void
sync_wakeup(struct ccan_list_head *head, long max)
{
- RUBY_DEBUG_LOG("max:%ld", max);
-
struct sync_waiter *cur = 0, *next;
ccan_list_for_each_safe(head, cur, next, node) {
@@ -53,7 +51,6 @@ sync_wakeup(struct ccan_list_head *head, long max)
rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
}
else {
- RUBY_DEBUG_LOG("target_th:%u", rb_th_serial(cur->th));
rb_threadptr_interrupt(cur->th);
cur->th->status = THREAD_RUNNABLE;
}
@@ -254,8 +251,6 @@ rb_mutex_trylock(VALUE self)
rb_mutex_t *mutex = mutex_ptr(self);
if (mutex->fiber == 0) {
- RUBY_DEBUG_LOG("%p ok", mutex);
-
rb_fiber_t *fiber = GET_EC()->fiber_ptr;
rb_thread_t *th = GET_THREAD();
mutex->fiber = fiber;
@@ -263,12 +258,17 @@ rb_mutex_trylock(VALUE self)
mutex_locked(th, self);
return Qtrue;
}
- else {
- RUBY_DEBUG_LOG("%p ng", mutex);
- return Qfalse;
- }
+
+ return Qfalse;
}
+/*
+ * At maximum, only one thread can use cond_timedwait and watch deadlock
+ * periodically. Multiple polling thread (i.e. concurrent deadlock check)
+ * introduces new race conditions. [Bug #6278] [ruby-core:44275]
+ */
+static const rb_thread_t *patrol_thread = NULL;
+
static VALUE
mutex_owned_p(rb_fiber_t *fiber, rb_mutex_t *mutex)
{
@@ -290,8 +290,6 @@ delete_from_waitq(VALUE value)
return Qnil;
}
-static inline rb_atomic_t threadptr_get_interrupts(rb_thread_t *th);
-
static VALUE
do_mutex_lock(VALUE self, int interruptible_p)
{
@@ -299,7 +297,6 @@ do_mutex_lock(VALUE self, int interruptible_p)
rb_thread_t *th = ec->thread_ptr;
rb_fiber_t *fiber = ec->fiber_ptr;
rb_mutex_t *mutex = mutex_ptr(self);
- rb_atomic_t saved_ints = 0;
/* When running trap handler */
if (!FL_TEST_RAW(self, MUTEX_ALLOW_TRAP) &&
@@ -313,8 +310,6 @@ do_mutex_lock(VALUE self, int interruptible_p)
}
while (mutex->fiber != fiber) {
- VM_ASSERT(mutex->fiber != NULL);
-
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
struct sync_waiter sync_waiter = {
@@ -336,47 +331,51 @@ do_mutex_lock(VALUE self, int interruptible_p)
rb_raise(rb_eThreadError, "deadlock; lock already owned by another fiber belonging to the same thread");
}
+ enum rb_thread_status prev_status = th->status;
+ rb_hrtime_t *timeout = 0;
+ rb_hrtime_t rel = rb_msec2hrtime(100);
+
+ th->status = THREAD_STOPPED_FOREVER;
+ th->locking_mutex = self;
+ rb_ractor_sleeper_threads_inc(th->ractor);
+ /*
+ * Carefully! while some contended threads are in native_sleep(),
+ * ractor->sleeper is unstable value. we have to avoid both deadlock
+ * and busy loop.
+ */
+ if ((rb_ractor_living_thread_num(th->ractor) == rb_ractor_sleeper_thread_num(th->ractor)) &&
+ !patrol_thread) {
+ timeout = &rel;
+ patrol_thread = th;
+ }
+
struct sync_waiter sync_waiter = {
.self = self,
.th = th,
- .fiber = nonblocking_fiber(fiber),
+ .fiber = nonblocking_fiber(fiber)
};
- RUBY_DEBUG_LOG("%p wait", mutex);
-
- // similar code with `sleep_forever`, but
- // sleep_forever(SLEEP_DEADLOCKABLE) raises an exception.
- // Ensure clause is needed like but `rb_ensure` a bit slow.
- //
- // begin
- // sleep_forever(th, SLEEP_DEADLOCKABLE);
- // ensure
- // ccan_list_del(&sync_waiter.node);
- // end
- enum rb_thread_status prev_status = th->status;
- th->status = THREAD_STOPPED_FOREVER;
- rb_ractor_sleeper_threads_inc(th->ractor);
- rb_check_deadlock(th->ractor);
+ ccan_list_add_tail(&mutex->waitq, &sync_waiter.node);
- th->locking_mutex = self;
+ native_sleep(th, timeout); /* release GVL */
- ccan_list_add_tail(&mutex->waitq, &sync_waiter.node);
- {
- native_sleep(th, NULL);
- }
ccan_list_del(&sync_waiter.node);
- // unlocked by another thread while sleeping
if (!mutex->fiber) {
mutex->fiber = fiber;
}
- rb_ractor_sleeper_threads_dec(th->ractor);
- th->status = prev_status;
- th->locking_mutex = Qfalse;
- th->locking_mutex = Qfalse;
+ if (patrol_thread == th)
+ patrol_thread = NULL;
- RUBY_DEBUG_LOG("%p wakeup", mutex);
+ th->locking_mutex = Qfalse;
+ if (mutex->fiber && timeout && !RUBY_VM_INTERRUPTED(th->ec)) {
+ rb_check_deadlock(th->ractor);
+ }
+ if (th->status == THREAD_STOPPED_FOREVER) {
+ th->status = prev_status;
+ }
+ rb_ractor_sleeper_threads_dec(th->ractor);
}
if (interruptible_p) {
@@ -388,27 +387,11 @@ do_mutex_lock(VALUE self, int interruptible_p)
mutex->fiber = fiber;
}
}
- else {
- // clear interrupt information
- if (RUBY_VM_INTERRUPTED(th->ec)) {
- // reset interrupts
- if (saved_ints == 0) {
- saved_ints = threadptr_get_interrupts(th);
- }
- else {
- // ignore additional interrupts
- threadptr_get_interrupts(th);
- }
- }
- }
}
- if (saved_ints) th->ec->interrupt_flag = saved_ints;
if (mutex->fiber == fiber) mutex_locked(th, self);
}
- RUBY_DEBUG_LOG("%p locked", mutex);
-
// assertion
if (mutex_owned_p(fiber, mutex) == Qfalse) rb_bug("do_mutex_lock: mutex is not owned.");
@@ -452,46 +435,46 @@ rb_mutex_owned_p(VALUE self)
static const char *
rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t *th, rb_fiber_t *fiber)
{
- RUBY_DEBUG_LOG("%p", mutex);
+ const char *err = NULL;
if (mutex->fiber == 0) {
- return "Attempt to unlock a mutex which is not locked";
+ err = "Attempt to unlock a mutex which is not locked";
}
else if (mutex->fiber != fiber) {
- return "Attempt to unlock a mutex which is locked by another thread/fiber";
+ err = "Attempt to unlock a mutex which is locked by another thread/fiber";
}
+ else {
+ struct sync_waiter *cur = 0, *next;
- struct sync_waiter *cur = 0, *next;
-
- mutex->fiber = 0;
- thread_mutex_remove(th, mutex);
-
- ccan_list_for_each_safe(&mutex->waitq, cur, next, node) {
- ccan_list_del_init(&cur->node);
+ mutex->fiber = 0;
+ ccan_list_for_each_safe(&mutex->waitq, cur, next, node) {
+ ccan_list_del_init(&cur->node);
- if (cur->th->scheduler != Qnil && cur->fiber) {
- rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
- return NULL;
- }
- else {
- switch (cur->th->status) {
- case THREAD_RUNNABLE: /* from someone else calling Thread#run */
- case THREAD_STOPPED_FOREVER: /* likely (rb_mutex_lock) */
- RUBY_DEBUG_LOG("wakeup th:%u", rb_th_serial(cur->th));
- rb_threadptr_interrupt(cur->th);
- return NULL;
- case THREAD_STOPPED: /* probably impossible */
- rb_bug("unexpected THREAD_STOPPED");
- case THREAD_KILLED:
- /* not sure about this, possible in exit GC? */
- rb_bug("unexpected THREAD_KILLED");
- continue;
+ if (cur->th->scheduler != Qnil && cur->fiber) {
+ rb_fiber_scheduler_unblock(cur->th->scheduler, cur->self, rb_fiberptr_self(cur->fiber));
+ goto found;
+ }
+ else {
+ switch (cur->th->status) {
+ case THREAD_RUNNABLE: /* from someone else calling Thread#run */
+ case THREAD_STOPPED_FOREVER: /* likely (rb_mutex_lock) */
+ rb_threadptr_interrupt(cur->th);
+ goto found;
+ case THREAD_STOPPED: /* probably impossible */
+ rb_bug("unexpected THREAD_STOPPED");
+ case THREAD_KILLED:
+ /* not sure about this, possible in exit GC? */
+ rb_bug("unexpected THREAD_KILLED");
+ continue;
+ }
}
}
+
+ found:
+ thread_mutex_remove(th, mutex);
}
- // We did not find any threads to wake up, so we can just return with no error:
- return NULL;
+ return err;
}
/*
@@ -548,49 +531,55 @@ rb_mutex_abandon_all(rb_mutex_t *mutexes)
}
#endif
-static VALUE
-rb_mutex_sleep_forever(VALUE self)
-{
- rb_thread_sleep_deadly_allow_spurious_wakeup(self, Qnil, 0);
- return Qnil;
-}
+struct rb_mutex_sleep_arguments {
+ VALUE self;
+ VALUE timeout;
+};
static VALUE
-rb_mutex_wait_for(VALUE time)
+mutex_sleep_begin(VALUE _arguments)
{
- rb_hrtime_t *rel = (rb_hrtime_t *)time;
- /* permit spurious check */
- return RBOOL(sleep_hrtime(GET_THREAD(), *rel, 0));
-}
-
-VALUE
-rb_mutex_sleep(VALUE self, VALUE timeout)
-{
- struct timeval t;
+ struct rb_mutex_sleep_arguments *arguments = (struct rb_mutex_sleep_arguments *)_arguments;
+ VALUE timeout = arguments->timeout;
VALUE woken = Qtrue;
- if (!NIL_P(timeout)) {
- t = rb_time_interval(timeout);
- }
-
- rb_mutex_unlock(self);
- time_t beg = time(0);
-
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
rb_fiber_scheduler_kernel_sleep(scheduler, timeout);
- mutex_lock_uninterruptible(self);
}
else {
if (NIL_P(timeout)) {
- rb_ensure(rb_mutex_sleep_forever, self, mutex_lock_uninterruptible, self);
+ rb_thread_sleep_deadly_allow_spurious_wakeup(arguments->self, Qnil, 0);
}
else {
- rb_hrtime_t rel = rb_timeval2hrtime(&t);
- woken = rb_ensure(rb_mutex_wait_for, (VALUE)&rel, mutex_lock_uninterruptible, self);
+ struct timeval timeout_value = rb_time_interval(timeout);
+ rb_hrtime_t relative_timeout = rb_timeval2hrtime(&timeout_value);
+ /* permit spurious check */
+ woken = RBOOL(sleep_hrtime(GET_THREAD(), relative_timeout, 0));
}
}
+ return woken;
+}
+
+VALUE
+rb_mutex_sleep(VALUE self, VALUE timeout)
+{
+ if (!NIL_P(timeout)) {
+ // Validate the argument:
+ rb_time_interval(timeout);
+ }
+
+ rb_mutex_unlock(self);
+ time_t beg = time(0);
+
+ struct rb_mutex_sleep_arguments arguments = {
+ .self = self,
+ .timeout = timeout,
+ };
+
+ VALUE woken = rb_ensure(mutex_sleep_begin, (VALUE)&arguments, mutex_lock_uninterruptible, self);
+
RUBY_VM_CHECK_INTS_BLOCKING(GET_EC());
if (!woken) return Qnil;
time_t end = time(0) - beg;
@@ -668,25 +657,21 @@ rb_mutex_allow_trap(VALUE self, int val)
/* Queue */
#define queue_waitq(q) UNALIGNED_MEMBER_PTR(q, waitq)
-#define queue_list(q) UNALIGNED_MEMBER_PTR(q, que)
-RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN()
-struct rb_queue {
+PACKED_STRUCT_UNALIGNED(struct rb_queue {
struct ccan_list_head waitq;
rb_serial_t fork_gen;
const VALUE que;
int num_waiting;
-} RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END();
+});
#define szqueue_waitq(sq) UNALIGNED_MEMBER_PTR(sq, q.waitq)
-#define szqueue_list(sq) UNALIGNED_MEMBER_PTR(sq, q.que)
#define szqueue_pushq(sq) UNALIGNED_MEMBER_PTR(sq, pushq)
-RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN()
-struct rb_szqueue {
+PACKED_STRUCT_UNALIGNED(struct rb_szqueue {
struct rb_queue q;
int num_waiting_push;
struct ccan_list_head pushq;
long max;
-} RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END();
+});
static void
queue_mark(void *ptr)
@@ -866,8 +851,8 @@ queue_closed_result(VALUE self, struct rb_queue *q)
* information must be exchanged safely between multiple threads. The
* Thread::Queue class implements all the required locking semantics.
*
- * The class implements FIFO (first in, first out) type of queue.
- * In a FIFO queue, the first tasks added are the first retrieved.
+ * The class implements FIFO type of queue. In a FIFO queue, the first
+ * tasks added are the first retrieved.
*
* Example:
*
@@ -875,17 +860,17 @@ queue_closed_result(VALUE self, struct rb_queue *q)
*
* producer = Thread.new do
* 5.times do |i|
- * sleep rand(i) # simulate expense
- * queue << i
- * puts "#{i} produced"
+ * sleep rand(i) # simulate expense
+ * queue << i
+ * puts "#{i} produced"
* end
* end
*
* consumer = Thread.new do
* 5.times do |i|
- * value = queue.pop
- * sleep rand(i/2) # simulate expense
- * puts "consumed #{value}"
+ * value = queue.pop
+ * sleep rand(i/2) # simulate expense
+ * puts "consumed #{value}"
* end
* end
*
@@ -926,7 +911,7 @@ rb_queue_initialize(int argc, VALUE *argv, VALUE self)
if ((argc = rb_scan_args(argc, argv, "01", &initial)) == 1) {
initial = rb_to_array(initial);
}
- RB_OBJ_WRITE(self, queue_list(q), ary_buf_new());
+ RB_OBJ_WRITE(self, &q->que, ary_buf_new());
ccan_list_head_init(queue_waitq(q));
if (argc == 1) {
rb_ary_concat(q->que, initial);
@@ -1158,22 +1143,6 @@ rb_queue_length(VALUE self)
return LONG2NUM(queue_length(self, queue_ptr(self)));
}
-NORETURN(static VALUE rb_queue_freeze(VALUE self));
-/*
- * call-seq:
- * freeze
- *
- * The queue can't be frozen, so this method raises an exception:
- * Thread::Queue.new.freeze # Raises TypeError (cannot freeze #<Thread::Queue:0x...>)
- *
- */
-static VALUE
-rb_queue_freeze(VALUE self)
-{
- rb_raise(rb_eTypeError, "cannot freeze " "%+"PRIsVALUE, self);
- UNREACHABLE_RETURN(self);
-}
-
/*
* Document-method: Thread::Queue#num_waiting
*
@@ -1215,7 +1184,7 @@ rb_szqueue_initialize(VALUE self, VALUE vmax)
rb_raise(rb_eArgError, "queue size must be positive");
}
- RB_OBJ_WRITE(self, szqueue_list(sq), ary_buf_new());
+ RB_OBJ_WRITE(self, &sq->q.que, ary_buf_new());
ccan_list_head_init(szqueue_waitq(sq));
ccan_list_head_init(szqueue_pushq(sq));
sq->max = max;
@@ -1635,7 +1604,6 @@ Init_thread_sync(void)
rb_define_method(rb_cQueue, "clear", rb_queue_clear, 0);
rb_define_method(rb_cQueue, "length", rb_queue_length, 0);
rb_define_method(rb_cQueue, "num_waiting", rb_queue_num_waiting, 0);
- rb_define_method(rb_cQueue, "freeze", rb_queue_freeze, 0);
rb_define_alias(rb_cQueue, "enq", "push");
rb_define_alias(rb_cQueue, "<<", "push");
@@ -1652,7 +1620,6 @@ Init_thread_sync(void)
rb_define_method(rb_cSizedQueue, "clear", rb_szqueue_clear, 0);
rb_define_method(rb_cSizedQueue, "length", rb_szqueue_length, 0);
rb_define_method(rb_cSizedQueue, "num_waiting", rb_szqueue_num_waiting, 0);
- rb_define_method(rb_cSizedQueue, "freeze", rb_queue_freeze, 0);
rb_define_alias(rb_cSizedQueue, "size", "length");
/* CVar */
diff --git a/thread_win32.c b/thread_win32.c
index 4fd488db60..e9deff23cc 100644
--- a/thread_win32.c
+++ b/thread_win32.c
@@ -131,10 +131,8 @@ thread_sched_to_running(struct rb_thread_sched *sched, rb_thread_t *th)
if (GVL_DEBUG) fprintf(stderr, "gvl acquire (%p): acquire\n", th);
}
-#define thread_sched_to_dead thread_sched_to_waiting
-
static void
-thread_sched_to_waiting(struct rb_thread_sched *sched, rb_thread_t *th)
+thread_sched_to_waiting(struct rb_thread_sched *sched)
{
ReleaseMutex(sched->lock);
}
@@ -142,20 +140,19 @@ thread_sched_to_waiting(struct rb_thread_sched *sched, rb_thread_t *th)
static void
thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
{
- thread_sched_to_waiting(sched, th);
+ thread_sched_to_waiting(sched);
native_thread_yield();
thread_sched_to_running(sched, th);
}
void
-rb_thread_sched_init(struct rb_thread_sched *sched, bool atfork)
+rb_thread_sched_init(struct rb_thread_sched *sched)
{
if (GVL_DEBUG) fprintf(stderr, "sched init\n");
sched->lock = w32_mutex_create();
}
#if 0
-// per-ractor
void
rb_thread_sched_destroy(struct rb_thread_sched *sched)
{
@@ -205,11 +202,6 @@ Init_native_thread(rb_thread_t *main_th)
main_th->nt->interrupt_event);
}
-void
-ruby_mn_threads_params(void)
-{
-}
-
static int
w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th)
{
@@ -625,13 +617,11 @@ native_thread_init_stack(rb_thread_t *th)
(void *)InterlockedExchange((long *)(t), (long)(v))
#endif
static void
-native_thread_destroy(struct rb_native_thread *nt)
+native_thread_destroy(rb_thread_t *th)
{
- if (nt) {
- HANDLE intr = InterlockedExchangePointer(&nt->interrupt_event, 0);
- RUBY_DEBUG_LOG("close handle intr:%p, thid:%p\n", intr, nt->thread_id);
- w32_close_handle(intr);
- }
+ HANDLE intr = InterlockedExchangePointer(&th->nt->interrupt_event, 0);
+ RUBY_DEBUG_LOG("close handle intr:%p, thid:%p\n", intr, th->nt->thread_id);
+ w32_close_handle(intr);
}
static unsigned long __stdcall
@@ -647,32 +637,20 @@ thread_start_func_1(void *th_ptr)
RUBY_DEBUG_LOG("thread created th:%u, thid: %p, event: %p",
rb_th_serial(th), th->nt->thread_id, th->nt->interrupt_event);
- thread_sched_to_running(TH_SCHED(th), th);
- ruby_thread_set_native(th);
-
- // kick threads
thread_start_func_2(th, th->ec->machine.stack_start);
w32_close_handle(thread_id);
RUBY_DEBUG_LOG("thread deleted th:%u", rb_th_serial(th));
-
return 0;
}
static int
native_thread_create(rb_thread_t *th)
{
- // setup nt
- const size_t stack_size = th->vm->default_params.thread_machine_stack_size;
+ const size_t stack_size = th->vm->default_params.thread_machine_stack_size + th->vm->default_params.thread_vm_stack_size;
th->nt = ZALLOC(struct rb_native_thread);
th->nt->thread_id = w32_create_thread(stack_size, thread_start_func_1, th);
- // setup vm stack
- size_t vm_stack_word_size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
- void *vm_stack = ruby_xmalloc(vm_stack_word_size * sizeof(VALUE));
- th->sched.vm_stack = vm_stack;
- rb_ec_initialize_vm_stack(th->ec, vm_stack, vm_stack_word_size);
-
if ((th->nt->thread_id) == 0) {
return thread_errno;
}
@@ -773,6 +751,7 @@ timer_thread_func(void *dummy)
while (WaitForSingleObject(timer_thread.lock,
TIME_QUANTUM_USEC/1000) == WAIT_TIMEOUT) {
vm->clock++;
+ ruby_sigchld_handler(vm); /* probably no-op */
rb_threadptr_check_signal(vm->ractor.main_thread);
}
RUBY_DEBUG_LOG("end");
@@ -785,6 +764,12 @@ rb_thread_wakeup_timer_thread(int sig)
/* do nothing */
}
+static VALUE
+rb_thread_start_unblock_thread(void)
+{
+ return Qfalse; /* no-op */
+}
+
static void
rb_thread_create_timer_thread(void)
{
@@ -857,155 +842,44 @@ rb_reserved_fd_p(int fd)
return 0;
}
-rb_nativethread_id_t
-rb_nativethread_self(void)
-{
- return GetCurrentThread();
-}
-
-static void
-native_set_thread_name(rb_thread_t *th)
-{
-}
-
-static VALUE
-native_thread_native_thread_id(rb_thread_t *th)
-{
- DWORD tid = GetThreadId(th->nt->thread_id);
- if (tid == 0) rb_sys_fail("GetThreadId");
- return ULONG2NUM(tid);
-}
-#define USE_NATIVE_THREAD_NATIVE_THREAD_ID 1
-
-void
-rb_add_running_thread(rb_thread_t *th){
- // do nothing
-}
-
-void
-rb_del_running_thread(rb_thread_t *th)
-{
- // do nothing
-}
-
-static bool
-th_has_dedicated_nt(const rb_thread_t *th)
-{
- return true;
-}
-
-void
-rb_threadptr_sched_free(rb_thread_t *th)
+int
+rb_sigwait_fd_get(rb_thread_t *th)
{
- native_thread_destroy(th->nt);
- ruby_xfree(th->nt);
- ruby_xfree(th->sched.vm_stack);
+ return -1; /* TODO */
}
+NORETURN(void rb_sigwait_fd_put(rb_thread_t *, int));
void
-rb_threadptr_remove(rb_thread_t *th)
+rb_sigwait_fd_put(rb_thread_t *th, int fd)
{
- // do nothing
+ rb_bug("not implemented, should not be called");
}
+NORETURN(void rb_sigwait_sleep(const rb_thread_t *, int, const rb_hrtime_t *));
void
-rb_thread_sched_mark_zombies(rb_vm_t *vm)
+rb_sigwait_sleep(const rb_thread_t *th, int fd, const rb_hrtime_t *rel)
{
- // do nothing
+ rb_bug("not implemented, should not be called");
}
-static bool
-vm_barrier_finish_p(rb_vm_t *vm)
+rb_nativethread_id_t
+rb_nativethread_self(void)
{
- RUBY_DEBUG_LOG("cnt:%u living:%u blocking:%u",
- vm->ractor.blocking_cnt == vm->ractor.cnt,
- vm->ractor.sync.barrier_cnt,
- vm->ractor.cnt,
- vm->ractor.blocking_cnt);
-
- VM_ASSERT(vm->ractor.blocking_cnt <= vm->ractor.cnt);
- return vm->ractor.blocking_cnt == vm->ractor.cnt;
+ return GetCurrentThread();
}
-void
-rb_ractor_sched_barrier_start(rb_vm_t *vm, rb_ractor_t *cr)
+static void
+native_set_thread_name(rb_thread_t *th)
{
- vm->ractor.sync.barrier_waiting = true;
-
- RUBY_DEBUG_LOG("barrier start. cnt:%u living:%u blocking:%u",
- vm->ractor.sync.barrier_cnt,
- vm->ractor.cnt,
- vm->ractor.blocking_cnt);
-
- rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
-
- // send signal
- rb_ractor_t *r = 0;
- ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
- if (r != cr) {
- rb_ractor_vm_barrier_interrupt_running_thread(r);
- }
- }
-
- // wait
- while (!vm_barrier_finish_p(vm)) {
- rb_vm_cond_wait(vm, &vm->ractor.sync.barrier_cond);
- }
-
- RUBY_DEBUG_LOG("cnt:%u barrier success", vm->ractor.sync.barrier_cnt);
-
- rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
-
- vm->ractor.sync.barrier_waiting = false;
- vm->ractor.sync.barrier_cnt++;
-
- ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
- rb_native_cond_signal(&r->barrier_wait_cond);
- }
}
-void
-rb_ractor_sched_barrier_join(rb_vm_t *vm, rb_ractor_t *cr)
+static VALUE
+native_thread_native_thread_id(rb_thread_t *th)
{
- vm->ractor.sync.lock_owner = cr;
- unsigned int barrier_cnt = vm->ractor.sync.barrier_cnt;
- rb_thread_t *th = GET_THREAD();
- bool running;
-
- RB_VM_SAVE_MACHINE_CONTEXT(th);
-
- if (rb_ractor_status_p(cr, ractor_running)) {
- rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
- running = true;
- }
- else {
- running = false;
- }
- VM_ASSERT(rb_ractor_status_p(cr, ractor_blocking));
-
- if (vm_barrier_finish_p(vm)) {
- RUBY_DEBUG_LOG("wakeup barrier owner");
- rb_native_cond_signal(&vm->ractor.sync.barrier_cond);
- }
- else {
- RUBY_DEBUG_LOG("wait for barrier finish");
- }
-
- // wait for restart
- while (barrier_cnt == vm->ractor.sync.barrier_cnt) {
- vm->ractor.sync.lock_owner = NULL;
- rb_native_cond_wait(&cr->barrier_wait_cond, &vm->ractor.sync.lock);
- VM_ASSERT(vm->ractor.sync.lock_owner == NULL);
- vm->ractor.sync.lock_owner = cr;
- }
-
- RUBY_DEBUG_LOG("barrier is released. Acquire vm_lock");
-
- if (running) {
- rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
- }
-
- vm->ractor.sync.lock_owner = NULL;
+ DWORD tid = GetThreadId(th->nt->thread_id);
+ if (tid == 0) rb_sys_fail("GetThreadId");
+ return ULONG2NUM(tid);
}
+#define USE_NATIVE_THREAD_NATIVE_THREAD_ID 1
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
diff --git a/thread_win32.h b/thread_win32.h
index 23cd71fcfe..f00f3b2056 100644
--- a/thread_win32.h
+++ b/thread_win32.h
@@ -21,13 +21,18 @@
WINBASEAPI BOOL WINAPI
TryEnterCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
+struct rb_thread_cond_struct {
+ struct cond_event_entry *next;
+ struct cond_event_entry *prev;
+};
+
struct rb_native_thread {
HANDLE thread_id;
HANDLE interrupt_event;
};
struct rb_thread_sched_item {
- void *vm_stack;
+ char dmy;
};
struct rb_thread_sched {
diff --git a/time.c b/time.c
index 25098e7e76..e8815b5e3d 100644
--- a/time.c
+++ b/time.c
@@ -44,6 +44,10 @@
#include "ruby/encoding.h"
#include "timev.h"
+#if defined(_WIN32)
+# include "timezoneapi.h" /* DYNAMIC_TIME_ZONE_INFORMATION */
+#endif
+
#include "builtin.h"
static ID id_submicro, id_nano_num, id_nano_den, id_offset, id_zone;
@@ -62,6 +66,10 @@ static VALUE sym_hour, sym_min, sym_sec, sym_subsec, sym_dst, sym_zone;
#define id_name idName
#define UTC_ZONE Qundef
+#ifndef TM_IS_TIME
+#define TM_IS_TIME 1
+#endif
+
#define NDIV(x,y) (-(-((x)+1)/(y))-1)
#define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
@@ -697,10 +705,51 @@ static VALUE tm_from_time(VALUE klass, VALUE time);
bool ruby_tz_uptodate_p;
+#ifdef _WIN32
+enum {tzkey_max = numberof(((DYNAMIC_TIME_ZONE_INFORMATION *)NULL)->TimeZoneKeyName)};
+static struct {
+ char use_tzkey;
+ char name[tzkey_max * 4 + 1];
+} w32_tz;
+
+static char *
+get_tzname(int dst)
+{
+ if (w32_tz.use_tzkey) {
+ if (w32_tz.name[0]) {
+ return w32_tz.name;
+ }
+ else {
+ /*
+ * Use GetDynamicTimeZoneInformation::TimeZoneKeyName, Windows
+ * time zone ID, which is not localized because it is the key
+ * for "Dynamic DST" keys under the "Time Zones" registry.
+ * Available since Windows Vista and Windows Server 2008.
+ */
+ DYNAMIC_TIME_ZONE_INFORMATION tzi;
+ WCHAR *const wtzkey = tzi.TimeZoneKeyName;
+ DWORD tzret = GetDynamicTimeZoneInformation(&tzi);
+ if (tzret != TIME_ZONE_ID_INVALID && *wtzkey) {
+ int wlen = (int)wcsnlen(wtzkey, tzkey_max);
+ int clen = WideCharToMultiByte(CP_UTF8, 0, wtzkey, wlen,
+ w32_tz.name, sizeof(w32_tz.name) - 1,
+ NULL, NULL);
+ w32_tz.name[clen] = '\0';
+ return w32_tz.name;
+ }
+ }
+ }
+ return _tzname[_daylight && dst];
+}
+#endif
+
void
-ruby_reset_timezone(void)
+ruby_reset_timezone(const char *val)
{
ruby_tz_uptodate_p = false;
+#ifdef _WIN32
+ w32_tz.use_tzkey = !val || !*val;
+#endif
ruby_reset_leap_second_info();
}
@@ -946,7 +995,13 @@ zone_str(const char *zone)
str = rb_usascii_str_new(zone, len);
}
else {
+#ifdef _WIN32
+ str = rb_utf8_str_new(zone, len);
+ /* until we move to UTF-8 on Windows completely */
+ str = rb_str_export_locale(str);
+#else
str = rb_enc_str_new(zone, len, rb_locale_encoding());
+#endif
}
return rb_fstring(str);
}
@@ -1318,6 +1373,9 @@ gmtimew(wideval_t timew, struct vtm *result)
result->wday = tm.tm_wday;
result->yday = tm.tm_yday+1;
result->isdst = tm.tm_isdst;
+#if 0
+ result->zone = rb_fstring_lit("UTC");
+#endif
return result;
}
@@ -1645,11 +1703,9 @@ localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, VAL
if (zone) {
#if defined(HAVE_TM_ZONE)
*zone = zone_str(tm.tm_zone);
+#elif defined(_WIN32)
+ *zone = zone_str(get_tzname(tm.tm_isdst));
#elif defined(HAVE_TZNAME) && defined(HAVE_DAYLIGHT)
-# if defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 140
-# define tzname _tzname
-# define daylight _daylight
-# endif
/* this needs tzset or localtime, instead of localtime_r */
*zone = zone_str(tzname[daylight && tm.tm_isdst]);
#else
@@ -1772,10 +1828,9 @@ struct time_object {
#define TZMODE_SET_LOCALTIME(tobj) ((tobj)->vtm.tzmode = TIME_TZMODE_LOCALTIME)
#define TZMODE_FIXOFF_P(tobj) ((tobj)->vtm.tzmode == TIME_TZMODE_FIXOFF)
-#define TZMODE_SET_FIXOFF(time, tobj, off) do { \
- (tobj)->vtm.tzmode = TIME_TZMODE_FIXOFF; \
- RB_OBJ_WRITE_UNALIGNED(time, &(tobj)->vtm.utc_offset, off); \
-} while (0)
+#define TZMODE_SET_FIXOFF(tobj, off) \
+ ((tobj)->vtm.tzmode = TIME_TZMODE_FIXOFF, \
+ (tobj)->vtm.utc_offset = (off))
#define TZMODE_COPY(tobj1, tobj2) \
((tobj1)->vtm.tzmode = (tobj2)->vtm.tzmode, \
@@ -1798,26 +1853,6 @@ static VALUE time_get_tm(VALUE, struct time_object *);
} \
} while (0)
-static void
-time_set_timew(VALUE time, struct time_object *tobj, wideval_t timew)
-{
- tobj->timew = timew;
- if (!FIXWV_P(timew)) {
- RB_OBJ_WRITTEN(time, Qnil, w2v(timew));
- }
-}
-
-static void
-time_set_vtm(VALUE time, struct time_object *tobj, struct vtm vtm)
-{
- tobj->vtm = vtm;
-
- RB_OBJ_WRITTEN(time, Qnil, tobj->vtm.year);
- RB_OBJ_WRITTEN(time, Qnil, tobj->vtm.subsecx);
- RB_OBJ_WRITTEN(time, Qnil, tobj->vtm.utc_offset);
- RB_OBJ_WRITTEN(time, Qnil, tobj->vtm.zone);
-}
-
static inline void
force_make_tm(VALUE time, struct time_object *tobj)
{
@@ -1841,15 +1876,17 @@ time_mark(void *ptr)
rb_gc_mark(tobj->vtm.zone);
}
+static size_t
+time_memsize(const void *tobj)
+{
+ return sizeof(struct time_object);
+}
+
static const rb_data_type_t time_data_type = {
"time",
- {
- time_mark,
- RUBY_TYPED_DEFAULT_FREE,
- NULL, // No external memory to report,
- },
+ {time_mark, RUBY_TYPED_DEFAULT_FREE, time_memsize,},
0, 0,
- (RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE),
+ (RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE),
};
static VALUE
@@ -1861,7 +1898,7 @@ time_s_alloc(VALUE klass)
obj = TypedData_Make_Struct(klass, struct time_object, &time_data_type, tobj);
tobj->vtm.tzmode = TIME_TZMODE_UNINITIALIZED;
tobj->vtm.tm_got = 0;
- time_set_timew(obj, tobj, WINT2FIXWV(0));
+ tobj->timew = WINT2FIXWV(0);
tobj->vtm.zone = Qnil;
return obj;
@@ -1968,8 +2005,9 @@ time_init_now(rb_execution_context_t *ec, VALUE time, VALUE zone)
GetNewTimeval(time, tobj);
TZMODE_SET_LOCALTIME(tobj);
tobj->vtm.tm_got=0;
+ tobj->timew = WINT2FIXWV(0);
rb_timespec_now(&ts);
- time_set_timew(time, tobj, timenano2timew(ts.tv_sec, ts.tv_nsec));
+ tobj->timew = timenano2timew(ts.tv_sec, ts.tv_nsec);
if (!NIL_P(zone)) {
time_zonelocal(time, zone);
@@ -1995,7 +2033,7 @@ time_set_utc_offset(VALUE time, VALUE off)
tobj->vtm.tm_got = 0;
tobj->vtm.zone = Qnil;
- TZMODE_SET_FIXOFF(time, tobj, off);
+ TZMODE_SET_FIXOFF(tobj, off);
return time;
}
@@ -2248,12 +2286,10 @@ extract_time(VALUE time)
} while (0)
if (rb_typeddata_is_kind_of(time, &time_data_type)) {
- struct time_object *tobj = RTYPEDDATA_GET_DATA(time);
+ struct time_object *tobj = DATA_PTR(time);
time_gmtime(time); /* ensure tm got */
t = rb_time_unmagnify(tobj->timew);
-
- RB_GC_GUARD(time);
}
else if (RB_TYPE_P(time, T_STRUCT)) {
#define AREF(x) rb_struct_aref(time, ID2SYM(id_##x))
@@ -2271,11 +2307,10 @@ extract_time(VALUE time)
}
static wideval_t
-extract_vtm(VALUE time, VALUE orig_time, struct time_object *orig_tobj, VALUE subsecx)
+extract_vtm(VALUE time, struct vtm *vtm, VALUE subsecx)
{
wideval_t t;
const ID id_to_i = idTo_i;
- struct vtm *vtm = &orig_tobj->vtm;
#define EXTRACT_VTM() do { \
VALUE subsecx; \
@@ -2291,15 +2326,13 @@ extract_vtm(VALUE time, VALUE orig_time, struct time_object *orig_tobj, VALUE su
} while (0)
if (rb_typeddata_is_kind_of(time, &time_data_type)) {
- struct time_object *tobj = RTYPEDDATA_GET_DATA(time);
+ struct time_object *tobj = DATA_PTR(time);
time_get_tm(time, tobj);
- time_set_vtm(orig_time, orig_tobj, tobj->vtm);
+ *vtm = tobj->vtm;
t = rb_time_unmagnify(tobj->timew);
if (TZMODE_FIXOFF_P(tobj) && vtm->utc_offset != INT2FIX(0))
t = wadd(t, v2w(vtm->utc_offset));
-
- RB_GC_GUARD(time);
}
else if (RB_TYPE_P(time, T_STRUCT)) {
#define AREF(x) rb_struct_aref(time, ID2SYM(id_##x))
@@ -2308,9 +2341,7 @@ extract_vtm(VALUE time, VALUE orig_time, struct time_object *orig_tobj, VALUE su
}
else if (rb_integer_type_p(time)) {
t = v2w(time);
- struct vtm temp_vtm = *vtm;
- GMTIMEW(rb_time_magnify(t), &temp_vtm);
- time_set_vtm(orig_time, orig_tobj, temp_vtm);
+ GMTIMEW(rb_time_magnify(t), vtm);
}
else {
#define AREF(x) rb_funcallv(time, id_##x, 0, 0)
@@ -2318,9 +2349,7 @@ extract_vtm(VALUE time, VALUE orig_time, struct time_object *orig_tobj, VALUE su
#undef AREF
}
#undef EXTRACT_VTM
-
- RB_OBJ_WRITE_UNALIGNED(orig_time, &vtm->subsecx, subsecx);
-
+ vtm->subsecx = subsecx;
validate_vtm(vtm);
return t;
}
@@ -2339,7 +2368,7 @@ static int
zone_timelocal(VALUE zone, VALUE time)
{
VALUE utc, tm;
- struct time_object *tobj = RTYPEDDATA_GET_DATA(time);
+ struct time_object *tobj = DATA_PTR(time);
wideval_t t, s;
wdivmod(tobj->timew, WINT2FIXWV(TIME_SCALE), &t, &s);
@@ -2353,12 +2382,8 @@ zone_timelocal(VALUE zone, VALUE time)
if (tobj->vtm.subsecx != INT2FIX(0)) {
s = wadd(s, v2w(tobj->vtm.subsecx));
}
- time_set_timew(time, tobj, s);
-
+ tobj->timew = s;
zone_set_dst(zone, tobj, tm);
-
- RB_GC_GUARD(time);
-
return 1;
}
@@ -2366,7 +2391,7 @@ static int
zone_localtime(VALUE zone, VALUE time)
{
VALUE local, tm, subsecx;
- struct time_object *tobj = RTYPEDDATA_GET_DATA(time);
+ struct time_object *tobj = DATA_PTR(time);
wideval_t t, s;
split_second(tobj->timew, &t, &subsecx);
@@ -2375,13 +2400,10 @@ zone_localtime(VALUE zone, VALUE time)
local = rb_check_funcall(zone, id_utc_to_local, 1, &tm);
if (UNDEF_P(local)) return 0;
- s = extract_vtm(local, time, tobj, subsecx);
+ s = extract_vtm(local, &tobj->vtm, subsecx);
tobj->vtm.tm_got = 1;
zone_set_offset(zone, tobj, s, t);
zone_set_dst(zone, tobj, tm);
-
- RB_GC_GUARD(time);
-
return 1;
}
@@ -2470,9 +2492,9 @@ time_init_vtm(VALUE time, struct vtm vtm, VALUE zone)
GetNewTimeval(time, tobj);
if (!NIL_P(zone)) {
- time_set_timew(time, tobj, timegmw(&vtm));
+ tobj->timew = timegmw(&vtm);
vtm_day_wraparound(&vtm);
- time_set_vtm(time, tobj, vtm);
+ tobj->vtm = vtm;
tobj->vtm.tm_got = 1;
TZMODE_SET_LOCALTIME(tobj);
if (zone_timelocal(zone, time)) {
@@ -2485,10 +2507,10 @@ time_init_vtm(VALUE time, struct vtm vtm, VALUE zone)
}
if (utc == UTC_ZONE) {
- time_set_timew(time, tobj, timegmw(&vtm));
+ tobj->timew = timegmw(&vtm);
vtm.isdst = 0; /* No DST in UTC */
vtm_day_wraparound(&vtm);
- time_set_vtm(time, tobj, vtm);
+ tobj->vtm = vtm;
tobj->vtm.tm_got = 1;
TZMODE_SET_UTC(tobj);
return time;
@@ -2496,18 +2518,17 @@ time_init_vtm(VALUE time, struct vtm vtm, VALUE zone)
TZMODE_SET_LOCALTIME(tobj);
tobj->vtm.tm_got=0;
+ tobj->timew = WINT2FIXWV(0);
if (!NIL_P(vtm.utc_offset)) {
VALUE off = vtm.utc_offset;
vtm_add_offset(&vtm, off, -1);
vtm.utc_offset = Qnil;
- time_set_timew(time, tobj, timegmw(&vtm));
-
+ tobj->timew = timegmw(&vtm);
return time_set_utc_offset(time, off);
}
else {
- time_set_timew(time, tobj, timelocalw(&vtm));
-
+ tobj->timew = timelocalw(&vtm);
return time_localtime(time);
}
}
@@ -2710,9 +2731,9 @@ time_new_timew(VALUE klass, wideval_t timew)
VALUE time = time_s_alloc(klass);
struct time_object *tobj;
- tobj = RTYPEDDATA_GET_DATA(time); /* skip type check */
+ tobj = DATA_PTR(time); /* skip type check */
TZMODE_SET_LOCALTIME(tobj);
- time_set_timew(time, tobj, timew);
+ tobj->timew = timew;
return time;
}
@@ -2739,7 +2760,7 @@ rb_time_timespec_new(const struct timespec *ts, int offset)
if (-86400 < offset && offset < 86400) { /* fixoff */
GetTimeval(time, tobj);
- TZMODE_SET_FIXOFF(time, tobj, INT2FIX(offset));
+ TZMODE_SET_FIXOFF(tobj, INT2FIX(offset));
}
else if (offset == INT_MAX) { /* localtime */
}
@@ -3584,7 +3605,7 @@ tmcmp(struct tm *a, struct tm *b)
* Time.utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) -> new_time
* Time.utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy) -> new_time
*
- * Returns a new +Time+ object based the on given arguments,
+ * Returns a new \Time object based the on given arguments,
* in the UTC timezone.
*
* With one to seven arguments given,
@@ -3645,7 +3666,7 @@ tmcmp(struct tm *a, struct tm *b)
* Time.utc(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0, 0.0)
* # => 0000-01-01 00:00:00 UTC
*
- * - String integers:
+ * - \String integers:
*
* a = %w[0 1 1 0 0 0 0 0]
* # => ["0", "1", "1", "0", "0", "0", "0", "0"]
@@ -3662,7 +3683,7 @@ tmcmp(struct tm *a, struct tm *b)
* # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
* Time.utc(*a) # => 0005-04-03 02:01:00 UTC
*
- * This form is useful for creating a +Time+ object from a 10-element
+ * This form is useful for creating a \Time object from a 10-element
* array returned by Time.to_a:
*
* t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006
@@ -3676,6 +3697,8 @@ tmcmp(struct tm *a, struct tm *b)
* Raises an exception if the number of arguments is eight, nine,
* or greater than ten.
*
+ * Time.gm is an alias for Time.utc.
+ *
* Related: Time.local.
*
*/
@@ -3693,7 +3716,7 @@ time_s_mkutc(int argc, VALUE *argv, VALUE klass)
* Time.local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) -> new_time
* Time.local(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy) -> new_time
*
- * Like Time.utc, except that the returned +Time+ object
+ * Like Time.utc, except that the returned \Time object
* has the local timezone, not the UTC timezone:
*
* # With seven arguments.
@@ -3727,6 +3750,8 @@ time_s_mktime(int argc, VALUE *argv, VALUE klass)
* Time.utc(1950, 1, 1, 0, 0, 0).to_i # => -631152000
* Time.utc(1990, 1, 1, 0, 0, 0).to_i # => 631152000
*
+ * Time#tv_sec is an alias for Time#to_i.
+ *
* Related: Time#to_f Time#to_r.
*/
@@ -3806,6 +3831,8 @@ time_to_r(VALUE time)
* t.usec # => 548469
*
* Related: Time#subsec (returns exact subseconds).
+ *
+ * Time#tv_usec is an alias for Time#usec.
*/
static VALUE
@@ -3833,6 +3860,8 @@ time_usec(VALUE time)
* t.nsec # => 321963700
*
* Related: Time#subsec (returns exact subseconds).
+ *
+ * Time#tv_nsec is an alias for Time#usec.
*/
static VALUE
@@ -3922,7 +3951,7 @@ time_cmp(VALUE time1, VALUE time2)
* eql?(other_time)
*
* Returns +true+ if +self+ and +other_time+ are
- * both +Time+ objects with the exact same time value.
+ * both \Time objects with the exact same time value.
*/
static VALUE
@@ -3951,6 +3980,8 @@ time_eql(VALUE time1, VALUE time2)
* # => 2000-01-01 20:15:01 UTC
* utc.utc? # => true
*
+ * Time#gmt? is an alias for Time#utc?.
+ *
* Related: Time.utc.
*/
@@ -4026,7 +4057,7 @@ time_localtime(VALUE time)
if (!localtimew(tobj->timew, &vtm))
rb_raise(rb_eArgError, "localtime error");
- time_set_vtm(time, tobj, vtm);
+ tobj->vtm = vtm;
tobj->vtm.tm_got = 1;
TZMODE_SET_LOCALTIME(tobj);
@@ -4062,20 +4093,20 @@ time_zonelocal(VALUE time, VALUE off)
* With no argument given:
*
* - Returns +self+ if +self+ is a local time.
- * - Otherwise returns a new +Time+ in the user's local timezone:
+ * - Otherwise returns a new \Time in the user's local timezone:
*
* t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
* t.localtime # => 2000-01-01 14:15:01 -0600
*
* With argument +zone+ given,
- * returns the new +Time+ object created by converting
+ * returns the new \Time object created by converting
* +self+ to the given time zone:
*
* t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
* t.localtime("-09:00") # => 2000-01-01 11:15:01 -0900
*
* For forms of argument +zone+, see
- * {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
+ * {Timezone Specifiers}[rdoc-ref:timezones.rdoc].
*
*/
@@ -4102,7 +4133,9 @@ time_localtime_m(int argc, VALUE *argv, VALUE time)
* t.utc # => 2000-01-01 06:00:00 UTC
* t.utc? # => true
*
- * Related: Time#getutc (returns a new converted +Time+ object).
+ * Time#gmtime is an alias for Time#utc.
+ *
+ * Related: Time#getutc (returns a new converted \Time object).
*/
static VALUE
@@ -4122,7 +4155,7 @@ time_gmtime(VALUE time)
vtm.zone = str_utc;
GMTIMEW(tobj->timew, &vtm);
- time_set_vtm(time, tobj, vtm);
+ tobj->vtm = vtm;
tobj->vtm.tm_got = 1;
TZMODE_SET_UTC(tobj);
@@ -4153,13 +4186,12 @@ time_fixoff(VALUE time)
GMTIMEW(tobj->timew, &vtm);
zone = tobj->vtm.zone;
- vtm_add_offset(&vtm, off, +1);
-
- time_set_vtm(time, tobj, vtm);
- RB_OBJ_WRITE_UNALIGNED(time, &tobj->vtm.zone, zone);
+ tobj->vtm = vtm;
+ tobj->vtm.zone = zone;
+ vtm_add_offset(&tobj->vtm, off, +1);
tobj->vtm.tm_got = 1;
- TZMODE_SET_FIXOFF(time, tobj, off);
+ TZMODE_SET_FIXOFF(tobj, off);
return time;
}
@@ -4167,7 +4199,7 @@ time_fixoff(VALUE time)
* call-seq:
* getlocal(zone = nil) -> new_time
*
- * Returns a new +Time+ object representing the value of +self+
+ * Returns a new \Time object representing the value of +self+
* converted to a given timezone;
* if +zone+ is +nil+, the local timezone is used:
*
@@ -4176,7 +4208,7 @@ time_fixoff(VALUE time)
* t.getlocal('+12:00') # => 2000-01-01 12:00:00 +1200
*
* For forms of argument +zone+, see
- * {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
+ * {Timezone Specifiers}[rdoc-ref:timezones.rdoc].
*
*/
@@ -4216,7 +4248,7 @@ time_getlocaltime(int argc, VALUE *argv, VALUE time)
* call-seq:
* getutc -> new_time
*
- * Returns a new +Time+ object representing the value of +self+
+ * Returns a new \Time object representing the value of +self+
* converted to the UTC timezone:
*
* local = Time.local(2000) # => 2000-01-01 00:00:00 -0600
@@ -4225,6 +4257,7 @@ time_getlocaltime(int argc, VALUE *argv, VALUE time)
* utc.utc? # => true
* utc == local # => true
*
+ * Time#getgm is an alias for Time#getutc.
*/
static VALUE
@@ -4258,6 +4291,8 @@ static VALUE strftime_cstr(const char *fmt, size_t len, VALUE time, rb_encoding
* t.strftime('%a %b %e %T %Y') # => "Sun Dec 31 23:59:59 2000"
* t.strftime('%c') # => "Sun Dec 31 23:59:59 2000"
*
+ * Time#asctime is an alias for Time#ctime.
+ *
* Related: Time#to_s, Time#inspect:
*
* t.inspect # => "2000-12-31 23:59:59.5 +000001"
@@ -4381,7 +4416,7 @@ time_add(const struct time_object *tobj, VALUE torig, VALUE offset, int sign)
* call-seq:
* self + numeric -> new_time
*
- * Returns a new +Time+ object whose value is the sum of the numeric value
+ * Returns a new \Time object whose value is the sum of the numeric value
* of +self+ and the given +numeric+:
*
* t = Time.new(2000) # => 2000-01-01 00:00:00 -0600
@@ -4409,7 +4444,7 @@ time_plus(VALUE time1, VALUE time2)
* self - other_time -> float
*
* When +numeric+ is given,
- * returns a new +Time+ object whose value is the difference
+ * returns a new \Time object whose value is the difference
* of the numeric value of +self+ and +numeric+:
*
* t = Time.new(2000) # => 2000-01-01 00:00:00 -0600
@@ -4418,7 +4453,7 @@ time_plus(VALUE time1, VALUE time2)
*
* When +other_time+ is given,
* returns a Float whose value is the difference
- * of the numeric values of +self+ and +other_time+ in seconds:
+ * of the numeric values of +self+ and +other_time+:
*
* t - t # => 0.0
*
@@ -4459,7 +4494,7 @@ ndigits_denominator(VALUE ndigits)
* call-seq:
* round(ndigits = 0) -> new_time
*
- * Returns a new +Time+ object whose numeric value is that of +self+,
+ * Returns a new \Time object whose numeric value is that of +self+,
* with its seconds value rounded to precision +ndigits+:
*
* t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r)
@@ -4508,7 +4543,7 @@ time_round(int argc, VALUE *argv, VALUE time)
* call-seq:
* floor(ndigits = 0) -> new_time
*
- * Returns a new +Time+ object whose numerical value
+ * Returns a new \Time object whose numerical value
* is less than or equal to +self+ with its seconds
* truncated to precision +ndigits+:
*
@@ -4553,7 +4588,7 @@ time_floor(int argc, VALUE *argv, VALUE time)
* call-seq:
* ceil(ndigits = 0) -> new_time
*
- * Returns a new +Time+ object whose numerical value
+ * Returns a new \Time object whose numerical value
* is greater than or equal to +self+ with its seconds
* truncated to precision +ndigits+:
*
@@ -4683,6 +4718,8 @@ time_hour(VALUE time)
* # => 2000-01-02 03:04:05 +000006
* t.mday # => 2
*
+ * Time#day is an alias for Time#mday.
+ *
* Related: Time#year, Time#hour, Time#min.
*/
@@ -4707,6 +4744,8 @@ time_mday(VALUE time)
* # => 2000-01-02 03:04:05 +000006
* t.mon # => 1
*
+ * Time#month is an alias for Time#mday.
+ *
* Related: Time#year, Time#hour, Time#min.
*/
@@ -4931,6 +4970,7 @@ time_yday(VALUE time)
* t.zone # => "Central Daylight Time"
* t.dst? # => true
*
+ * Time#isdst is an alias for Time#dst?.
*/
static VALUE
@@ -4986,6 +5026,7 @@ time_zone(VALUE time)
* Time.utc(2000, 1, 1).utc_offset # => 0
* Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.
*
+ * Time#gmt_offset and Time#gmtoff are aliases for Time#utc_offset.
*/
VALUE
@@ -5015,7 +5056,7 @@ rb_time_utc_offset(VALUE time)
* # [sec, min, hour, day, mon, year, wday, yday, dst?, zone]
*
* The returned array is suitable for use as an argument to Time.utc or Time.local
- * to create a new +Time+ object.
+ * to create a new \Time object.
*
*/
@@ -5513,7 +5554,7 @@ end_submicro: ;
GetNewTimeval(time, tobj);
TZMODE_SET_LOCALTIME(tobj);
tobj->vtm.tm_got = 0;
- time_set_timew(time, tobj, timew);
+ tobj->timew = timew;
if (gmt) {
TZMODE_SET_UTC(tobj);
@@ -5564,22 +5605,46 @@ tm_from_time(VALUE klass, VALUE time)
{
struct time_object *tobj;
struct vtm vtm, *v;
+#if TM_IS_TIME
VALUE tm;
struct time_object *ttm;
GetTimeval(time, tobj);
tm = time_s_alloc(klass);
- ttm = RTYPEDDATA_GET_DATA(tm);
+ ttm = DATA_PTR(tm);
v = &vtm;
GMTIMEW(ttm->timew = tobj->timew, v);
ttm->timew = wsub(ttm->timew, v->subsecx);
v->subsecx = INT2FIX(0);
v->zone = Qnil;
- time_set_vtm(tm, ttm, *v);
+ ttm->vtm = *v;
ttm->vtm.tm_got = 1;
TZMODE_SET_UTC(ttm);
return tm;
+#else
+ VALUE args[8];
+ int i = 0;
+
+ GetTimeval(time, tobj);
+ if (tobj->tm_got && TZMODE_UTC_P(tobj))
+ v = &tobj->vtm;
+ else
+ GMTIMEW(tobj->timew, v = &vtm);
+ args[i++] = v->year;
+ args[i++] = INT2FIX(v->mon);
+ args[i++] = INT2FIX(v->mday);
+ args[i++] = INT2FIX(v->hour);
+ args[i++] = INT2FIX(v->min);
+ args[i++] = INT2FIX(v->sec);
+ switch (v->isdst) {
+ case 0: args[i++] = Qfalse; break;
+ case 1: args[i++] = Qtrue; break;
+ default: args[i++] = Qnil; break;
+ }
+ args[i++] = w2v(rb_time_unmagnify(tobj->timew));
+ return rb_class_new_instance(i, args, klass);
+#endif
}
/*
@@ -5591,7 +5656,7 @@ tm_from_time(VALUE klass, VALUE time)
*/
static VALUE
-tm_initialize(int argc, VALUE *argv, VALUE time)
+tm_initialize(int argc, VALUE *argv, VALUE tm)
{
struct vtm vtm;
wideval_t t;
@@ -5599,12 +5664,24 @@ tm_initialize(int argc, VALUE *argv, VALUE time)
if (rb_check_arity(argc, 1, 7) > 6) argc = 6;
time_arg(argc, argv, &vtm);
t = timegmw(&vtm);
- struct time_object *tobj = RTYPEDDATA_GET_DATA(time);
- TZMODE_SET_UTC(tobj);
- time_set_timew(time, tobj, t);
- time_set_vtm(time, tobj, vtm);
-
- return time;
+ {
+#if TM_IS_TIME
+ struct time_object *tobj = DATA_PTR(tm);
+ TZMODE_SET_UTC(tobj);
+ tobj->timew = t;
+ tobj->vtm = vtm;
+#else
+ int i = 0;
+ RSTRUCT_SET(tm, i++, INT2FIX(vtm.sec));
+ RSTRUCT_SET(tm, i++, INT2FIX(vtm.min));
+ RSTRUCT_SET(tm, i++, INT2FIX(vtm.hour));
+ RSTRUCT_SET(tm, i++, INT2FIX(vtm.mday));
+ RSTRUCT_SET(tm, i++, INT2FIX(vtm.mon));
+ RSTRUCT_SET(tm, i++, vtm.year);
+ RSTRUCT_SET(tm, i++, w2v(rb_time_unmagnify(t)));
+#endif
+ }
+ return tm;
}
/* call-seq:
@@ -5617,14 +5694,52 @@ tm_initialize(int argc, VALUE *argv, VALUE time)
static VALUE
tm_to_time(VALUE tm)
{
+#if TM_IS_TIME
struct time_object *torig = get_timeval(tm);
VALUE dup = time_s_alloc(rb_cTime);
- struct time_object *tobj = RTYPEDDATA_GET_DATA(dup);
+ struct time_object *tobj = DATA_PTR(dup);
*tobj = *torig;
return dup;
+#else
+ VALUE t[6];
+ const VALUE *p = RSTRUCT_CONST_PTR(tm);
+ int i;
+
+ for (i = 0; i < numberof(t); ++i) {
+ t[i] = p[numberof(t) - 1 - i];
+ }
+ return time_s_mkutc(numberof(t), t, rb_cTime);
+#endif
+}
+
+#if !TM_IS_TIME
+static VALUE
+tm_zero(VALUE tm)
+{
+ return INT2FIX(0);
+}
+
+#define tm_subsec tm_zero
+#define tm_utc_offset tm_zero
+
+static VALUE
+tm_isdst(VALUE tm)
+{
+ return Qfalse;
}
static VALUE
+tm_to_s(VALUE tm)
+{
+ const VALUE *p = RSTRUCT_CONST_PTR(tm);
+
+ return rb_sprintf("%.4"PRIsVALUE"-%.2"PRIsVALUE"-%.2"PRIsVALUE" "
+ "%.2"PRIsVALUE":%.2"PRIsVALUE":%.2"PRIsVALUE" "
+ "UTC",
+ p[5], p[4], p[3], p[2], p[1], p[0]);
+}
+#else
+static VALUE
tm_plus(VALUE tm, VALUE offset)
{
return time_add0(rb_obj_class(tm), get_timeval(tm), tm, offset, +1);
@@ -5635,12 +5750,14 @@ tm_minus(VALUE tm, VALUE offset)
{
return time_add0(rb_obj_class(tm), get_timeval(tm), tm, offset, -1);
}
+#endif
static VALUE
Init_tm(VALUE outer, const char *name)
{
/* :stopdoc:*/
VALUE tm;
+#if TM_IS_TIME
tm = rb_define_class_under(outer, name, rb_cObject);
rb_define_alloc_func(tm, time_s_alloc);
rb_define_method(tm, "sec", time_sec, 0);
@@ -5673,6 +5790,18 @@ Init_tm(VALUE outer, const char *name)
rb_define_method(tm, "to_r", time_to_r, 0);
rb_define_method(tm, "+", tm_plus, 1);
rb_define_method(tm, "-", tm_minus, 1);
+#else
+ tm = rb_struct_define_under(outer, "tm",
+ "sec", "min", "hour",
+ "mday", "mon", "year",
+ "to_i", NULL);
+ rb_define_method(tm, "subsec", tm_subsec, 0);
+ rb_define_method(tm, "utc_offset", tm_utc_offset, 0);
+ rb_define_method(tm, "to_s", tm_to_s, 0);
+ rb_define_method(tm, "inspect", tm_to_s, 0);
+ rb_define_method(tm, "isdst", tm_isdst, 0);
+ rb_define_method(tm, "dst?", tm_isdst, 0);
+#endif
rb_define_method(tm, "initialize", tm_initialize, -1);
rb_define_method(tm, "utc", tm_to_time, 0);
rb_alias(tm, rb_intern_const("to_time"), rb_intern_const("utc"));
@@ -5727,6 +5856,10 @@ rb_time_zone_abbreviation(VALUE zone, VALUE time)
void
Init_Time(void)
{
+#ifdef _WIN32
+ ruby_reset_timezone(getenv("TZ"));
+#endif
+
id_submicro = rb_intern_const("submicro");
id_nano_num = rb_intern_const("nano_num");
id_nano_den = rb_intern_const("nano_den");
@@ -5844,10 +5977,15 @@ Init_Time(void)
/* methods for marshaling */
rb_define_private_method(rb_cTime, "_dump", time_dump, -1);
rb_define_private_method(scTime, "_load", time_load, 1);
+#if 0
+ /* Time will support marshal_dump and marshal_load in the future (1.9 maybe) */
+ rb_define_private_method(rb_cTime, "marshal_dump", time_mdump, 0);
+ rb_define_private_method(rb_cTime, "marshal_load", time_mload, 1);
+#endif
if (debug_find_time_numguess) {
rb_define_hooked_variable("$find_time_numguess", (VALUE *)&find_time_numguess,
- find_time_numguess_getter, 0);
+ find_time_numguess_getter, NULL);
}
rb_cTimeTM = Init_tm(rb_cTime, "tm");
diff --git a/timev.rb b/timev.rb
index 22f46b9729..76d3ab7058 100644
--- a/timev.rb
+++ b/timev.rb
@@ -1,4 +1,4 @@
-# A +Time+ object represents a date and time:
+# A \Time object represents a date and time:
#
# Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600
#
@@ -41,7 +41,7 @@
#
# == \Time Resolution
#
-# A +Time+ object derived from the system clock
+# A \Time object derived from the system clock
# (for example, by method Time.now)
# has the resolution supported by the system.
#
@@ -49,7 +49,7 @@
#
# All of these examples were done using the EST timezone which is GMT-5.
#
-# === Creating a New +Time+ Instance
+# === Creating a New \Time Instance
#
# You can create a new instance of Time with Time.new. This will use the
# current system time. Time.now is an alias for this. You can also
@@ -66,7 +66,7 @@
#
# Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
#
-# Or {a timezone object}[rdoc-ref:Time@Timezone+Objects]:
+# Or a timezone object:
#
# zone = timezone("Europe/Athens") # Eastern European Time, UTC+2
# Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
@@ -81,7 +81,7 @@
#
# Time.at(628232400) #=> 1989-11-28 00:00:00 -0500
#
-# === Working with an Instance of +Time+
+# === Working with an Instance of \Time
#
# Once you have an instance of Time there is a multitude of things you can
# do with it. Below are some examples. For all of the following examples, we
@@ -123,19 +123,19 @@
#
# == What's Here
#
-# First, what's elsewhere. \Class +Time+:
+# First, what's elsewhere. \Class \Time:
#
# - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
#
-# Here, class +Time+ provides methods that are useful for:
+# Here, class \Time provides methods that are useful for:
#
-# - {Creating +Time+ objects}[rdoc-ref:Time@Methods+for+Creating].
-# - {Fetching +Time+ values}[rdoc-ref:Time@Methods+for+Fetching].
-# - {Querying a +Time+ object}[rdoc-ref:Time@Methods+for+Querying].
-# - {Comparing +Time+ objects}[rdoc-ref:Time@Methods+for+Comparing].
-# - {Converting a +Time+ object}[rdoc-ref:Time@Methods+for+Converting].
-# - {Rounding a +Time+}[rdoc-ref:Time@Methods+for+Rounding].
+# - {Creating \Time objects}[rdoc-ref:Time@Methods+for+Creating].
+# - {Fetching \Time values}[rdoc-ref:Time@Methods+for+Fetching].
+# - {Querying a \Time object}[rdoc-ref:Time@Methods+for+Querying].
+# - {Comparing \Time objects}[rdoc-ref:Time@Methods+for+Comparing].
+# - {Converting a \Time object}[rdoc-ref:Time@Methods+for+Converting].
+# - {Rounding a \Time}[rdoc-ref:Time@Methods+for+Rounding].
#
# === Methods for Creating
#
@@ -210,27 +210,25 @@
# - #floor: Returns a new time with subseconds lowered to a floor.
#
# For the forms of argument +zone+, see
-# {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
-#
-# :include: doc/_timezones.rdoc
+# {Timezone Specifiers}[rdoc-ref:timezones.rdoc].
class Time
- # Creates a new +Time+ object from the current system time.
+ # Creates a new \Time object from the current system time.
# This is the same as Time.new without arguments.
#
# Time.now # => 2009-06-24 12:39:54 +0900
# Time.now(in: '+04:00') # => 2009-06-24 07:39:54 +0400
#
# For forms of argument +zone+, see
- # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
+ # {Timezone Specifiers}[rdoc-ref:timezones.rdoc].
def self.now(in: nil)
Primitive.time_s_now(Primitive.arg!(:in))
end
- # Returns a new +Time+ object based on the given arguments.
+ # Returns a new \Time object based on the given arguments.
#
# Required argument +time+ may be either of:
#
- # - A +Time+ object, whose value is the basis for the returned time;
+ # - A \Time object, whose value is the basis for the returned time;
# also influenced by optional keyword argument +in:+ (see below).
# - A numeric number of
# {Epoch seconds}[rdoc-ref:Time@Epoch+Seconds]
@@ -272,14 +270,14 @@ class Time
# Time.at(secs, -1000000000, :nanosecond) # => 2000-12-31 23:59:58 -0600
#
#
- # Optional keyword argument <tt>in: zone</tt> specifies the timezone
+ # Optional keyword argument <tt>+in: zone</tt> specifies the timezone
# for the returned time:
#
# Time.at(secs, in: '+12:00') # => 2001-01-01 17:59:59 +1200
# Time.at(secs, in: '-12:00') # => 2000-12-31 17:59:59 -1200
#
# For the forms of argument +zone+, see
- # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
+ # {Timezone Specifiers}[rdoc-ref:timezones.rdoc].
#
def self.at(time, subsec = false, unit = :microsecond, in: nil)
if Primitive.mandatory_only?
@@ -289,10 +287,7 @@ class Time
end
end
- # call-seq:
- # Time.new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9)
- #
- # Returns a new +Time+ object based on the given arguments,
+ # Returns a new \Time object based on the given arguments,
# by default in the local timezone.
#
# With no positional arguments, returns the value of Time.now:
@@ -300,7 +295,7 @@ class Time
# Time.new # => 2021-04-24 17:27:46.0512465 -0500
#
# With one string argument that represents a time, returns a new
- # +Time+ object based on the given argument, in the local timezone.
+ # \Time object based on the given argument, in the local timezone.
#
# Time.new('2000-12-31 23:59:59.5') # => 2000-12-31 23:59:59.5 -0600
# Time.new('2000-12-31 23:59:59.5 +0900') # => 2000-12-31 23:59:59.5 +0900
@@ -308,7 +303,7 @@ class Time
# Time.new('2000-12-31 23:59:59.5') # => 2000-12-31 23:59:59.5 -0600
# Time.new('2000-12-31 23:59:59.56789', precision: 3) # => 2000-12-31 23:59:59.567 -0600
#
- # With one to six arguments, returns a new +Time+ object
+ # With one to six arguments, returns a new \Time object
# based on the given arguments, in the local timezone.
#
# Time.new(2000, 1, 2, 3, 4, 5) # => 2000-01-02 03:04:05 -0600
@@ -364,16 +359,16 @@ class Time
# Time.new(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0)
# # => 0000-01-01 00:00:00 -0600
#
- # - String integers:
+ # - \String integers:
#
# a = %w[0 1 1 0 0 0]
# # => ["0", "1", "1", "0", "0", "0"]
# Time.new(*a) # => 0000-01-01 00:00:00 -0600
#
# When positional argument +zone+ or keyword argument +in:+ is given,
- # the new +Time+ object is in the specified timezone.
+ # the new \Time object is in the specified timezone.
# For the forms of argument +zone+, see
- # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers]:
+ # {Timezone Specifiers}[rdoc-ref:timezones.rdoc]:
#
# Time.new(2000, 1, 1, 0, 0, 0, '+12:00')
# # => 2000-01-01 00:00:00 +1200
@@ -382,14 +377,8 @@ class Time
# Time.new(in: '-12:00')
# # => 2022-08-23 08:49:26.1941467 -1200
#
- # Since +in:+ keyword argument just provides the default, so if the
- # first argument in single string form contains time zone information,
- # this keyword argument will be silently ignored.
- #
- # Time.new('2000-01-01 00:00:00 +0100', in: '-0500').utc_offset # => 3600
- #
# - +precision+: maximum effective digits in sub-second part, default is 9.
- # More digits will be truncated, as other operations of +Time+.
+ # More digits will be truncated, as other operations of \Time.
# Ignored unless the first argument is a string.
#
def initialize(year = (now = true), mon = (str = year; nil), mday = nil, hour = nil, min = nil, sec = nil, zone = nil,
diff --git a/tool/bundler/dev_gems.rb b/tool/bundler/dev_gems.rb
index 1422cfc7a5..ef63263414 100644
--- a/tool/bundler/dev_gems.rb
+++ b/tool/bundler/dev_gems.rb
@@ -3,18 +3,17 @@
source "https://rubygems.org"
gem "test-unit", "~> 3.0"
-gem "rake", "~> 13.1"
+gem "rake", "~> 13.0"
gem "rb_sys"
gem "webrick", "~> 1.6"
-gem "turbo_tests", "~> 2.2.3"
-gem "parallel_tests", "< 3.9.0"
+gem "parallel_tests", "~> 2.29"
gem "parallel", "~> 1.19"
gem "rspec-core", "~> 3.12"
gem "rspec-expectations", "~> 3.12"
gem "rspec-mocks", "~> 3.12"
-gem "uri", "~> 0.13.0"
+gem "uri", "~> 0.12.0"
group :doc do
- gem "nronn", "~> 0.11.1", platform: :ruby
+ gem "ronn", "~> 0.7.3", :platform => :ruby
end
diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock
new file mode 100644
index 0000000000..d7b1d5cd64
--- /dev/null
+++ b/tool/bundler/dev_gems.rb.lock
@@ -0,0 +1,57 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ diff-lcs (1.5.0)
+ hpricot (0.8.6)
+ hpricot (0.8.6-java)
+ mustache (1.1.1)
+ parallel (1.23.0)
+ parallel_tests (2.32.0)
+ parallel
+ power_assert (2.0.3)
+ rake (13.0.6)
+ rb_sys (0.9.78)
+ rdiscount (2.2.7)
+ ronn (0.7.3)
+ hpricot (>= 0.8.2)
+ mustache (>= 0.7.0)
+ rdiscount (>= 1.5.8)
+ rspec-core (3.12.2)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.3)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.5)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-support (3.12.0)
+ test-unit (3.5.9)
+ power_assert
+ uri (0.12.1)
+ webrick (1.8.1)
+
+PLATFORMS
+ java
+ ruby
+ universal-java-11
+ universal-java-18
+ x64-mingw-ucrt
+ x64-mingw32
+ x86_64-darwin-20
+ x86_64-linux
+
+DEPENDENCIES
+ parallel (~> 1.19)
+ parallel_tests (~> 2.29)
+ rake (~> 13.0)
+ rb_sys
+ ronn (~> 0.7.3)
+ rspec-core (~> 3.12)
+ rspec-expectations (~> 3.12)
+ rspec-mocks (~> 3.12)
+ test-unit (~> 3.0)
+ uri (~> 0.12.0)
+ webrick (~> 1.6)
+
+BUNDLED WITH
+ 2.4.19
diff --git a/tool/bundler/rubocop_gems.rb b/tool/bundler/rubocop_gems.rb
index 4d0b21060a..9cb740cd15 100644
--- a/tool/bundler/rubocop_gems.rb
+++ b/tool/bundler/rubocop_gems.rb
@@ -2,7 +2,7 @@
source "https://rubygems.org"
-gem "rubocop", ">= 1.52.1", "< 2"
+gem "rubocop", "~> 1.7"
gem "minitest"
gem "rake"
diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock
new file mode 100644
index 0000000000..1b72f41521
--- /dev/null
+++ b/tool/bundler/rubocop_gems.rb.lock
@@ -0,0 +1,73 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ ast (2.4.2)
+ diff-lcs (1.5.0)
+ json (2.6.3)
+ json (2.6.3-java)
+ minitest (5.16.3)
+ parallel (1.22.1)
+ parser (3.1.3.0)
+ ast (~> 2.4.1)
+ power_assert (2.0.2)
+ rainbow (3.1.1)
+ rake (13.0.6)
+ rake-compiler (1.2.0)
+ rake
+ rb_sys (0.9.63)
+ regexp_parser (2.6.1)
+ rexml (3.2.5)
+ rspec (3.12.0)
+ rspec-core (~> 3.12.0)
+ rspec-expectations (~> 3.12.0)
+ rspec-mocks (~> 3.12.0)
+ rspec-core (3.12.2)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.3)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.5)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-support (3.12.0)
+ rubocop (1.40.0)
+ json (~> 2.3)
+ parallel (~> 1.10)
+ parser (>= 3.1.2.1)
+ rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 1.8, < 3.0)
+ rexml (>= 3.2.5, < 4.0)
+ rubocop-ast (>= 1.23.0, < 2.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (>= 1.4.0, < 3.0)
+ rubocop-ast (1.24.0)
+ parser (>= 3.1.1.0)
+ ruby-progressbar (1.11.0)
+ test-unit (3.5.5)
+ power_assert
+ unicode-display_width (2.3.0)
+
+PLATFORMS
+ aarch64-linux
+ arm64-darwin-20
+ arm64-darwin-21
+ arm64-darwin-22
+ universal-java-11
+ universal-java-18
+ x64-mingw-ucrt
+ x86_64-darwin-19
+ x86_64-darwin-20
+ x86_64-darwin-21
+ x86_64-linux
+
+DEPENDENCIES
+ minitest
+ rake
+ rake-compiler
+ rb_sys
+ rspec
+ rubocop (~> 1.7)
+ test-unit
+
+BUNDLED WITH
+ 2.4.19
diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock
new file mode 100644
index 0000000000..55bff432c0
--- /dev/null
+++ b/tool/bundler/standard_gems.rb.lock
@@ -0,0 +1,81 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ ast (2.4.2)
+ diff-lcs (1.5.0)
+ json (2.6.3)
+ json (2.6.3-java)
+ language_server-protocol (3.17.0.2)
+ minitest (5.16.3)
+ parallel (1.22.1)
+ parser (3.1.3.0)
+ ast (~> 2.4.1)
+ power_assert (2.0.2)
+ rainbow (3.1.1)
+ rake (13.0.6)
+ rake-compiler (1.2.0)
+ rake
+ rb_sys (0.9.63)
+ regexp_parser (2.6.1)
+ rexml (3.2.5)
+ rspec (3.12.0)
+ rspec-core (~> 3.12.0)
+ rspec-expectations (~> 3.12.0)
+ rspec-mocks (~> 3.12.0)
+ rspec-core (3.12.2)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.3)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.5)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-support (3.12.0)
+ rubocop (1.39.0)
+ json (~> 2.3)
+ parallel (~> 1.10)
+ parser (>= 3.1.2.1)
+ rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 1.8, < 3.0)
+ rexml (>= 3.2.5, < 4.0)
+ rubocop-ast (>= 1.23.0, < 2.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (>= 1.4.0, < 3.0)
+ rubocop-ast (1.24.0)
+ parser (>= 3.1.1.0)
+ rubocop-performance (1.15.1)
+ rubocop (>= 1.7.0, < 2.0)
+ rubocop-ast (>= 0.4.0)
+ ruby-progressbar (1.11.0)
+ standard (1.19.1)
+ language_server-protocol (~> 3.17.0.2)
+ rubocop (= 1.39.0)
+ rubocop-performance (= 1.15.1)
+ test-unit (3.5.5)
+ power_assert
+ unicode-display_width (2.3.0)
+
+PLATFORMS
+ aarch64-linux
+ arm64-darwin-20
+ arm64-darwin-21
+ arm64-darwin-22
+ universal-java-11
+ universal-java-18
+ x64-mingw-ucrt
+ x86_64-darwin-19
+ x86_64-darwin-20
+ x86_64-darwin-21
+ x86_64-linux
+
+DEPENDENCIES
+ minitest
+ rake
+ rake-compiler
+ rb_sys
+ rspec
+ standard (~> 1.0)
+ test-unit
+
+BUNDLED WITH
+ 2.4.19
diff --git a/tool/bundler/test_gems.rb b/tool/bundler/test_gems.rb
index 32cb6b34ee..9ba5763a3b 100644
--- a/tool/bundler/test_gems.rb
+++ b/tool/bundler/test_gems.rb
@@ -2,13 +2,11 @@
source "https://rubygems.org"
-gem "rack", "~> 2.0"
-gem "base64"
+gem "rack", "2.0.8"
gem "webrick", "1.7.0"
gem "rack-test", "~> 1.1"
-gem "compact_index", "~> 0.15.0"
-gem "sinatra", "~> 3.0"
-gem "rake", "~> 13.1"
+gem "compact_index", "~> 0.13.0"
+gem "sinatra", "~> 2.0"
+gem "rake", "13.0.1"
gem "builder", "~> 3.2"
gem "rb_sys"
-gem "rubygems-generate_index", "~> 1.1"
diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock
new file mode 100644
index 0000000000..61af54be9d
--- /dev/null
+++ b/tool/bundler/test_gems.rb.lock
@@ -0,0 +1,45 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ builder (3.2.4)
+ compact_index (0.13.0)
+ mustermann (1.1.2)
+ ruby2_keywords (~> 0.0.1)
+ rack (2.0.8)
+ rack-protection (2.0.8.1)
+ rack
+ rack-test (1.1.0)
+ rack (>= 1.0, < 3)
+ rake (13.0.1)
+ rb_sys (0.9.63)
+ ruby2_keywords (0.0.5)
+ sinatra (2.0.8.1)
+ mustermann (~> 1.0)
+ rack (~> 2.0)
+ rack-protection (= 2.0.8.1)
+ tilt (~> 2.0)
+ tilt (2.0.11)
+ webrick (1.7.0)
+
+PLATFORMS
+ java
+ ruby
+ universal-java-11
+ universal-java-18
+ x64-mingw-ucrt
+ x64-mingw32
+ x86_64-darwin-20
+ x86_64-linux
+
+DEPENDENCIES
+ builder (~> 3.2)
+ compact_index (~> 0.13.0)
+ rack (= 2.0.8)
+ rack-test (~> 1.1)
+ rake (= 13.0.1)
+ rb_sys
+ sinatra (~> 2.0)
+ webrick (= 1.7.0)
+
+BUNDLED WITH
+ 2.4.19
diff --git a/tool/bundler/vendor_gems.rb b/tool/bundler/vendor_gems.rb
deleted file mode 100644
index 2500e6c800..0000000000
--- a/tool/bundler/vendor_gems.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-source "https://rubygems.org"
-
-gem "fileutils", "1.7.2"
-gem "molinillo", github: "cocoapods/molinillo"
-gem "net-http", "0.4.0"
-gem "net-http-persistent", "4.0.2"
-gem "net-protocol", "0.2.2"
-gem "optparse", "0.4.0"
-gem "pub_grub", github: "jhawthorn/pub_grub"
-gem "resolv", "0.3.0"
-gem "timeout", "0.4.1"
-gem "thor", "1.3.0"
-gem "tsort", "0.2.0"
diff --git a/tool/bundler/vendor_gems.rb.lock b/tool/bundler/vendor_gems.rb.lock
deleted file mode 100644
index ad3602c984..0000000000
--- a/tool/bundler/vendor_gems.rb.lock
+++ /dev/null
@@ -1,71 +0,0 @@
-GIT
- remote: https://github.com/cocoapods/molinillo.git
- revision: 6bc3d6045edadf800ba1b634fef15d3574369e60
- specs:
- molinillo (0.8.0)
-
-GIT
- remote: https://github.com/jhawthorn/pub_grub.git
- revision: 4250c533895080c356407d1f49619cb90fa2562d
- specs:
- pub_grub (0.5.0)
-
-GEM
- remote: https://rubygems.org/
- specs:
- connection_pool (2.4.1)
- fileutils (1.7.2)
- net-http (0.4.0)
- uri
- net-http-persistent (4.0.2)
- connection_pool (~> 2.2)
- net-protocol (0.2.2)
- timeout
- optparse (0.4.0)
- resolv (0.3.0)
- thor (1.3.0)
- timeout (0.4.1)
- tsort (0.2.0)
- uri (0.13.0)
-
-PLATFORMS
- java
- ruby
- universal-java-11
- universal-java-18
- universal-java-19
- x64-mingw-ucrt
- x64-mingw32
- x86_64-darwin-20
- x86_64-linux
-
-DEPENDENCIES
- fileutils (= 1.7.2)
- molinillo!
- net-http (= 0.4.0)
- net-http-persistent (= 4.0.2)
- net-protocol (= 0.2.2)
- optparse (= 0.4.0)
- pub_grub!
- resolv (= 0.3.0)
- thor (= 1.3.0)
- timeout (= 0.4.1)
- tsort (= 0.2.0)
-
-CHECKSUMS
- connection_pool (2.4.1) sha256=0f40cf997091f1f04ff66da67eabd61a9fe0d4928b9a3645228532512fab62f4
- fileutils (1.7.2) sha256=36a0fb324218263e52b486ad7408e9a295378fe8edc9fd343709e523c0980631
- molinillo (0.8.0)
- net-http (0.4.0) sha256=d87a6163ce3c64008bc8764e210d5f4ec9b87ca558a9052eb390b2c2c277f157
- net-http-persistent (4.0.2) sha256=03f827a33857b1d56b4e796957ad19bf5b58367d853fd0a224eb70fba8d02a44
- net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
- optparse (0.4.0) sha256=f584afc034f610ea7b28a9b1a68b0917d34e0da73c40c2b29cd7151c5eb0bade
- pub_grub (0.5.0)
- resolv (0.3.0) sha256=14b917f1bb4f363c81601295b68097bf1ff8b3c4179972c2d174ffb7e997a406
- thor (1.3.0) sha256=1adc7f9e5b3655a68c71393fee8bd0ad088d14ee8e83a0b73726f23cbb3ca7c3
- timeout (0.4.1) sha256=6f1f4edd4bca28cffa59501733a94215407c6960bd2107331f0280d4abdebb9a
- tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
- uri (0.13.0) sha256=26553c2a9399762e1e8bebd4444b4361c4b21298cf1c864b22eeabc9c4998f24
-
-BUNDLED WITH
- 2.5.0.dev
diff --git a/tool/ci_functions.sh b/tool/ci_functions.sh
new file mode 100644
index 0000000000..7066bbe4ec
--- /dev/null
+++ b/tool/ci_functions.sh
@@ -0,0 +1,29 @@
+# -*- BASH -*-
+# Manage functions used on a CI.
+# Run `. tool/ci_functions.sh` to use it.
+
+# Create options with patterns `-n !/name1/ -n !/name2/ ..` to exclude the test
+# method names by the method names `name1 name2 ..`.
+# See `ruby tool/test/runner.rb --help` `-n` option.
+function ci_to_excluded_test_opts {
+ local tests_str="${1}"
+ # Use the backward matching `!/name$/`, as the perfect matching doesn't work.
+ # https://bugs.ruby-lang.org/issues/16936
+ ruby <<EOF
+ opts = "${tests_str}".split.map { |test| "-n \!/#{test}\$$/" }
+ puts opts.join(' ')
+EOF
+ return 0
+}
+
+# Create options with patterns `-n name1 -n name2 ..` to include the test
+# method names by the method names `name1 name2 ..`.
+# See `ruby tool/test/runner.rb --help` `-n` option.
+function ci_to_included_test_opts {
+ local tests_str="${1}"
+ ruby <<EOF
+ opts = "${tests_str}".split.map { |test| "-n #{test}" }
+ puts opts.join(' ')
+EOF
+ return 0
+}
diff --git a/tool/darwin-ar b/tool/darwin-ar
deleted file mode 100755
index 8b25425cfe..0000000000
--- a/tool/darwin-ar
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-export LANG=C LC_ALL=C # Suppress localication
-exec 2> >(exec grep -v \
- -e ' no symbols$' \
- >&2)
-exec "$@"
diff --git a/tool/darwin-cc b/tool/darwin-cc
index 42637022a4..6eee96e435 100755
--- a/tool/darwin-cc
+++ b/tool/darwin-cc
@@ -2,8 +2,5 @@
exec 2> >(exec grep -v \
-e '^ld: warning: The [a-z0-9_][a-z0-9_]* architecture is deprecated for macOS' \
-e '^ld: warning: text-based stub file /System/Library/Frameworks/' \
- -e '^ld: warning: ignoring duplicate libraries:' \
- -e "warning: '\.debug_macinfo' is not currently supported:" \
- -e "note: while processing" \
>&2)
exec "$@"
diff --git a/tool/downloader.rb b/tool/downloader.rb
index 2398fd7b04..0bcd8f31c3 100644
--- a/tool/downloader.rb
+++ b/tool/downloader.rb
@@ -270,7 +270,6 @@ class Downloader
end
dest = (cache_save && cache && !cache.exist? ? cache : file)
dest.parent.mkpath
- dest.unlink if dest.symlink? && !dest.exist?
dest.open("wb", 0600) do |f|
f.write(data)
f.chmod(mode_for(data))
diff --git a/tool/enc-case-folding.rb b/tool/enc-case-folding.rb
index 82fec7b625..76c6b5c48b 100755
--- a/tool/enc-case-folding.rb
+++ b/tool/enc-case-folding.rb
@@ -61,7 +61,7 @@ class CaseFolding
@version = nil
turkic = []
- File.foreach(filename, mode: "rb") do |line|
+ IO.foreach(filename, mode: "rb") do |line|
@version ||= line[/-([0-9.]+).txt/, 1]
next unless res = pattern.match(line)
ch_from = res[1].to_i(16)
@@ -230,7 +230,7 @@ class CaseMapping
@specials = []
@specials_length = 0
@version = nil
- File.foreach(File.join(mapping_directory, 'UnicodeData.txt'), mode: "rb") do |line|
+ IO.foreach(File.join(mapping_directory, 'UnicodeData.txt'), mode: "rb") do |line|
next if line =~ /^</
code, _, _, _, _, _, _, _, _, _, _, _, upper, lower, title = line.chomp.split ';'
unless upper and lower and title and (upper+lower+title)==''
@@ -239,7 +239,7 @@ class CaseMapping
end
@filename = File.join(mapping_directory, 'SpecialCasing.txt')
- File.foreach(@filename, mode: "rb") do |line|
+ IO.foreach(@filename, mode: "rb") do |line|
@version ||= line[/-([0-9.]+).txt/, 1]
line.chomp!
line, comment = line.split(/ *#/)
diff --git a/tool/enc-unicode.rb b/tool/enc-unicode.rb
index 9d49f427bb..6f2576cc37 100755
--- a/tool/enc-unicode.rb
+++ b/tool/enc-unicode.rb
@@ -5,30 +5,14 @@
#
# To use this, get UnicodeData.txt, Scripts.txt, PropList.txt,
# PropertyAliases.txt, PropertyValueAliases.txt, DerivedCoreProperties.txt,
-# DerivedAge.txt, Blocks.txt, emoji/emoji-data.txt,
-# auxiliary/GraphemeBreakProperty.txt from unicode.org
+# DerivedAge.txt and Blocks.txt from unicode.org.
# (http://unicode.org/Public/UNIDATA/) And run following command.
-# tool/enc-unicode.rb data_dir emoji_data_dir > enc/unicode/name2ctype.kwd
+# ruby1.9 tool/enc-unicode.rb data_dir > enc/unicode/name2ctype.kwd
# You can get source file for gperf. After this, simply make ruby.
-# Or directly run:
-# tool/enc-unicode.rb --header data_dir emoji_data_dir > enc/unicode/<VERSION>/name2ctype.h
-
-while arg = ARGV.shift
- case arg
- when "--"
- break
- when "--header"
- header = true
- when "--diff"
- diff = ARGV.shift or abort "#{$0}: --diff=DIFF-COMMAND"
- when /\A--diff=(.+)/m
- diff = $1
- when /\A-/
- abort "#{$0}: unknown option #{arg}"
- else
- ARGV.unshift(arg)
- break
- end
+
+if ARGV[0] == "--header"
+ header = true
+ ARGV.shift
end
unless ARGV.size == 2
abort "Usage: #{$0} data_directory emoji_data_directory"
@@ -75,7 +59,7 @@ def parse_unicode_data(file)
data = {'Any' => (0x0000..0x10ffff).to_a, 'Assigned' => [],
'ASCII' => (0..0x007F).to_a, 'NEWLINE' => [0x0a], 'Cn' => []}
beg_cp = nil
- File.foreach(file) do |line|
+ IO.foreach(file) do |line|
fields = line.split(';')
cp = fields[0].to_i(16)
@@ -166,7 +150,7 @@ def parse_scripts(data, categories)
categories[current] = file[:title]
(names[file[:title]] ||= []) << current
cps = []
- elsif /^(\h+)(?:\.\.(\h+))?\s*;\s*(\w+)/ =~ line
+ elsif /^([0-9a-fA-F]+)(?:\.\.([0-9a-fA-F]+))?\s*;\s*(\w+)/ =~ line
current = $3
$2 ? cps.concat(($1.to_i(16)..$2.to_i(16)).to_a) : cps.push($1.to_i(16))
end
@@ -221,7 +205,7 @@ def parse_age(data)
ages << current
last_constname = constname
cps = []
- elsif /^(\h+)(?:\.\.(\h+))?\s*;\s*(\d+\.\d+)/ =~ line
+ elsif /^([0-9a-fA-F]+)(?:\.\.([0-9a-fA-F]+))?\s*;\s*(\d+\.\d+)/ =~ line
current = $3
$2 ? cps.concat(($1.to_i(16)..$2.to_i(16)).to_a) : cps.push($1.to_i(16))
end
@@ -240,7 +224,7 @@ def parse_GraphemeBreakProperty(data)
make_const(constname, cps, "Grapheme_Cluster_Break=#{current}")
ages << current
cps = []
- elsif /^(\h+)(?:\.\.(\h+))?\s*;\s*(\w+)/ =~ line
+ elsif /^([0-9a-fA-F]+)(?:\.\.([0-9a-fA-F]+))?\s*;\s*(\w+)/ =~ line
current = $3
$2 ? cps.concat(($1.to_i(16)..$2.to_i(16)).to_a) : cps.push($1.to_i(16))
end
@@ -252,7 +236,7 @@ def parse_block(data)
cps = []
blocks = []
data_foreach('Blocks.txt') do |line|
- if /^(\h+)\.\.(\h+);\s*(.*)/ =~ line
+ if /^([0-9a-fA-F]+)\.\.([0-9a-fA-F]+);\s*(.*)/ =~ line
cps = ($1.to_i(16)..$2.to_i(16)).to_a
constname = constantize_blockname($3)
data[constname] = cps
@@ -269,12 +253,23 @@ def parse_block(data)
blocks << constname
end
+# shim for Ruby 1.8
+unless {}.respond_to?(:key)
+ class Hash
+ alias key index
+ end
+end
+
$const_cache = {}
# make_const(property, pairs, name): Prints a 'static const' structure for a
# given property, group of paired codepoints, and a human-friendly name for
# the group
def make_const(prop, data, name)
- puts "\n/* '#{prop}': #{name} */" # comment used to generate documentation
+ if name.empty?
+ puts "\n/* '#{prop}' */"
+ else
+ puts "\n/* '#{prop}': #{name} */"
+ end
if origprop = $const_cache.key(data)
puts "#define CR_#{prop} CR_#{origprop}"
else
@@ -426,6 +421,8 @@ define_posix_props(data)
POSIX_NAMES.each do |name|
if name == 'XPosixPunct'
make_const(name, data[name], "[[:Punct:]]")
+ elsif name == 'Punct'
+ make_const(name, data[name], "")
else
make_const(name, data[name], "[[:#{name}:]]")
end
@@ -547,47 +544,6 @@ output.restore
if header
require 'tempfile'
- def diff_args(diff)
- ok = IO.popen([diff, "-DDIFF_TEST", IO::NULL, "-"], "r+") do |f|
- f.puts "Test for diffutils 3.8"
- f.close_write
- /^#if/ =~ f.read
- end
- if ok
- proc {|macro, *inputs|
- [diff, "-D#{macro}", *inputs]
- }
- else
- IO.popen([diff, "--old-group-format=%<", "--new-group-format=%>", IO::NULL, IO::NULL], err: %i[child out], &:read)
- unless $?.success?
- abort "#{$0}: #{diff} -D does not work"
- end
- warn "Avoiding diffutils 3.8 bug#61193"
- proc {|macro, *inputs|
- [diff] + [
- "--old-group-format=" \
- "#ifndef @\n" \
- "%<" \
- "#endif /* ! @ */\n",
-
- "--new-group-format=" \
- "#ifdef @\n" \
- "%>" \
- "#endif /* @ */\n",
-
- "--changed-group-format=" \
- "#ifndef @\n" \
- "%<" \
- "#else /* @ */\n" \
- "%>" \
- "#endif /* @ */\n"
- ].map {|opt| opt.gsub(/@/) {macro}} + inputs
- }
- end
- end
-
- ifdef = diff_args(diff || "diff")
-
NAME2CTYPE = %w[gperf -7 -c -j1 -i1 -t -C -P -T -H uniname2ctype_hash -Q uniname2ctype_pool -N uniname2ctype_p]
fds = []
@@ -597,8 +553,9 @@ if header
IO.popen([*NAME2CTYPE, out: tmp], "w") {|f| output.show(f, *syms)}
end while syms.pop
fds.each(&:close)
- IO.popen(ifdef["USE_UNICODE_AGE_PROPERTIES", fds[1].path, fds[0].path], "r") {|age|
- IO.popen(ifdef["USE_UNICODE_PROPERTIES", fds[2].path, "-"], "r", in: age) {|f|
+ ff = nil
+ IO.popen(%W[diff -DUSE_UNICODE_AGE_PROPERTIES #{fds[1].path} #{fds[0].path}], "r") {|age|
+ IO.popen(%W[diff -DUSE_UNICODE_PROPERTIES #{fds[2].path} -], "r", in: age) {|f|
ansi = false
f.each {|line|
if /ANSI-C code produced by gperf/ =~ line
@@ -607,7 +564,7 @@ if header
line.sub!(/\/\*ANSI\*\//, '1') if ansi
line.gsub!(/\(int\)\((?:long|size_t)\)&\(\(struct uniname2ctype_pool_t \*\)0\)->uniname2ctype_pool_(str\d+),\s+/,
'uniname2ctype_offset(\1), ')
- if line.start_with?("uniname2ctype_hash\s") ... line.start_with?("}")
+ if ff = (!ff ? /^(uniname2ctype_hash) /=~line : /^\}/!~line) # no line can match both, exclusive flip-flop
line.sub!(/^( *(?:register\s+)?(.*\S)\s+hval\s*=\s*)(?=len;)/, '\1(\2)')
end
puts line
diff --git a/tool/extlibs.rb b/tool/extlibs.rb
index 887cac61eb..b482258a2c 100755
--- a/tool/extlibs.rb
+++ b/tool/extlibs.rb
@@ -185,7 +185,7 @@ class ExtLibs
extracted = false
dest = File.dirname(list)
url = chksums = nil
- File.foreach(list) do |line|
+ IO.foreach(list) do |line|
line.sub!(/\s*#.*/, '')
if /^(\w+)\s*=\s*(.*)/ =~ line
vars[$1] = vars.expand($2)
diff --git a/tool/fetch-bundled_gems.rb b/tool/fetch-bundled_gems.rb
index f790c92ba9..8d04892b70 100755
--- a/tool/fetch-bundled_gems.rb
+++ b/tool/fetch-bundled_gems.rb
@@ -10,7 +10,6 @@ BEGIN {
n, v, u, r = $F
-next unless n
next if n =~ /^#/
if File.directory?(n)
@@ -20,22 +19,13 @@ else
puts "retrieving #{n} ..."
system(*%W"git clone #{u} #{n}") or abort
end
-
if r
puts "fetching #{r} ..."
system("git", "fetch", "origin", r, chdir: n) or abort
end
-
c = r || "v#{v}"
checkout = %w"git -c advice.detachedHead=false checkout"
puts "checking out #{c} (v=#{v}, r=#{r}) ..."
unless system(*checkout, c, "--", chdir: n)
abort if r or !system(*checkout, v, "--", chdir: n)
end
-
-if r
- unless File.exist? "#{n}/#{n}.gemspec"
- require_relative "lib/bundled_gem"
- BundledGem.dummy_gemspec("#{n}/#{n}.gemspec")
- end
-end
diff --git a/tool/format-release b/tool/format-release
index 737148e0ce..7b0f8e78e7 100755
--- a/tool/format-release
+++ b/tool/format-release
@@ -235,11 +235,11 @@ eom
diff.each_with_index do |line, index|
case index
when 0
- line.sub!(/\A--- (.*)\t(\d+-\d+-\d+ [0-9:.]+(?: [\-+]\d+)?)\Z/) do
+ line.sub!(/\A--- (.*)\t(\d+-\d+-\d+ [0-9:.]+ [\-+]\d+)\Z/) do
"--- a/#{filename}\t#{$2}"
end
when 1
- line.sub!(/\A\+\+\+ (.*)\t(\d+-\d+-\d+ [0-9:.]+(?: [\-+]\d+)?)\Z/) do
+ line.sub!(/\A\+\+\+ (.*)\t(\d+-\d+-\d+ [0-9:.]+ [\-+]\d+)\Z/) do
"+++ b/#{filename}\t#{$2}"
end
end
diff --git a/tool/gen-github-release.rb b/tool/gen-github-release.rb
deleted file mode 100755
index 4d8c2910f4..0000000000
--- a/tool/gen-github-release.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env ruby
-
-if ARGV.size < 2
- puts "Usage: #{$0} <from version tag> <to version tag> [--no-dry-run]"
- puts " : if --no-dry-run is specified, it will create a release on GitHub"
- exit 1
-end
-
-require "bundler/inline"
-
-gemfile do
- source "https://rubygems.org"
- gem "octokit"
- gem "faraday-retry"
- gem "nokogiri"
-end
-
-require "open-uri"
-
-Octokit.configure do |c|
- c.access_token = ENV['GITHUB_TOKEN']
- c.auto_paginate = true
- c.per_page = 100
-end
-
-client = Octokit::Client.new
-
-note = "## What's Changed\n\n"
-
-diff = client.compare("ruby/ruby", ARGV[0], ARGV[1])
-diff[:commits].each do |c|
- if c[:commit][:message] =~ /\[Backport #(\d*)\]/
- url = "https://bugs.ruby-lang.org/issues/#{$1}"
- title = Nokogiri::HTML(URI.open(url)).title
- title.gsub!(/ - Ruby master - Ruby Issue Tracking System/, "")
- elsif c[:commit][:message] =~ /\(#(\d*)\)/
- url = "https://github.com/ruby/ruby/pull/#{$1}"
- title = Nokogiri::HTML(URI.open(url)).title
- title.gsub!(/ · ruby\/ruby · GitHub/, "")
- else
- next
- end
- note << "* [#{title}](#{url})\n"
-rescue OpenURI::HTTPError
- puts "Error: #{url}"
-end
-
-note << "\n"
-note << "Note: This list is automatically generated by tool/gen-github-release.rb. Because of this, some commits may be missing.\n\n"
-note << "## Full Changelog\n\n"
-note << "https://github.com/ruby/ruby/compare/#{ARGV[0]}...#{ARGV[1]}\n\n"
-
-if ARGV[2] == "--no-dry-run"
- name = ARGV[1].gsub(/v/, "").gsub(/_/, ".")
- client.create_release("ruby/ruby", ARGV[1], name: name, body: note)
- puts "Created a release: https://github.com/ruby/ruby/releases/tag/#{ARGV[1]}"
-else
- puts note
-end
diff --git a/tool/leaked-globals b/tool/leaked-globals
index 87089ebd81..d95f3794e8 100755
--- a/tool/leaked-globals
+++ b/tool/leaked-globals
@@ -3,27 +3,21 @@ require_relative 'lib/colorize'
until ARGV.empty?
case ARGV[0]
- when /\A SYMBOL_PREFIX=(.*)/x
+ when /\ASYMBOL_PREFIX=(.*)/
SYMBOL_PREFIX = $1
- when /\A NM=(.*)/x # may be multiple words
+ when /\ANM=(.*)/ # may be multiple words
NM = $1
- when /\A PLATFORM=(.+)?/x
+ when /\APLATFORM=(.+)?/
platform = $1
- when /\A SOEXT=(.+)?/x
- soext = $1
- when /\A SYMBOLS_IN_EMPTYLIB=(.*)/x
- SYMBOLS_IN_EMPTYLIB = $1.split(" ")
else
break
end
ARGV.shift
end
-SYMBOLS_IN_EMPTYLIB ||= nil
config = ARGV.shift
count = 0
col = Colorize.new
-
config_code = File.read(config)
REPLACE = config_code.scan(/\bAC_(?:REPLACE|CHECK)_FUNCS?\((\w+)/).flatten
# REPLACE << 'memcmp' if /\bAC_FUNC_MEMCMP\b/ =~ config_code
@@ -35,9 +29,8 @@ if platform and !platform.empty?
else
REPLACE.concat(
h .gsub(%r[/\*.*?\*/]m, " ") # delete block comments
- .gsub(%r[//.*], " ") # delete oneline comments
+ .gsub(%r[//.*], ' ') # delete oneline comments
.gsub(/^\s*#.*(?:\\\n.*)*/, "") # delete preprocessor directives
- .gsub(/(?:\A|;)\K\s*typedef\s.*?;/m, "")
.scan(/\b((?!rb_|DEPRECATED|_)\w+)\s*\(.*\);/)
.flatten)
end
@@ -45,41 +38,18 @@ end
missing = File.dirname(config) + "/missing/"
ARGV.reject! do |n|
unless (src = Dir.glob(missing + File.basename(n, ".*") + ".[cS]")).empty?
- puts "Ignore #{col.skip(n)} because of #{src.map {|s| File.basename(s)}.join(', ')} under missing"
+ puts "Ignore #{n} because of #{src.map {|s| File.basename(s)}.join(', ')} under missing"
true
end
end
-
-# darwin's ld64 seems to require exception handling personality functions to be
-# extern, so we allow the Rust one.
-REPLACE.push("rust_eh_personality") if RUBY_PLATFORM.include?("darwin")
-
print "Checking leaked global symbols..."
STDOUT.flush
-soext = /\.#{soext}(?:$|\.)/ if soext
-so = soext =~ ARGV.first if ARGV.size == 1
-IO.foreach("|#{NM} #{ARGV.join(' ')}") do |line|
- line.chomp!
- next so = nil if line.empty?
- if so.nil? and line.chomp!(":")
- so = soext =~ line || false
- next
- end
+IO.foreach("|#{NM} -Pgp #{ARGV.join(' ')}") do |line|
n, t, = line.split
next unless /[A-TV-Z]/ =~ t
next unless n.sub!(/^#{SYMBOL_PREFIX}/o, "")
next if n.include?(".")
- next if !so and n.start_with?("___asan_")
- case n
- when /\A(?:Init_|InitVM_|pm_|[Oo]nig|dln_|coroutine_)/
- next
- when /\Aruby_static_id_/
- next unless so
- when /\A(?:RUBY_|ruby_|rb_)/
- next unless so and /_(threadptr|ec)_/ =~ n
- when *SYMBOLS_IN_EMPTYLIB
- next
- end
+ next if /\A(?:Init_|InitVM_|RUBY_|ruby_|rb_|[Oo]nig|dln_|mjit_|coroutine_)/ =~ n
next if REPLACE.include?(n)
puts col.fail("leaked") if count.zero?
count += 1
diff --git a/tool/lib/bundled_gem.rb b/tool/lib/bundled_gem.rb
index 8730f0fb3a..6633d3e0c4 100644
--- a/tool/lib/bundled_gem.rb
+++ b/tool/lib/bundled_gem.rb
@@ -12,6 +12,7 @@ module BundledGem
"singleton", # prime
"ipaddr", # rinda
"forwardable", # prime, rinda
+ "ruby2_keywords", # drb
"strscan" # rexml
]
@@ -21,26 +22,6 @@ module BundledGem
pkg = Gem::Package.new(file)
prepare_test(pkg.spec, *rest) {|dir| pkg.extract_files(dir)}
puts "Unpacked #{file}"
- rescue Gem::Package::FormatError, Errno::ENOENT
- puts "Try with hash version of bundled gems instead of #{file}. We don't use this gem with release version of Ruby."
- if file =~ /^gems\/(\w+)-/
- file = Dir.glob("gems/#{$1}-*.gem").first
- end
- retry
- end
-
- def build(gemspec, version, outdir = ".", validation: true)
- outdir = File.expand_path(outdir)
- gemdir, gemfile = File.split(gemspec)
- Dir.chdir(gemdir) do
- spec = Gem::Specification.load(gemfile)
- abort "Failed to load #{gemspec}" unless spec
- output = File.join(outdir, spec.file_name)
- FileUtils.rm_rf(output)
- package = Gem::Package.new(output)
- package.spec = spec
- package.build(validation == false)
- end
end
def copy(path, *rest)
@@ -84,36 +65,4 @@ module BundledGem
end
FileUtils.rm_rf(Dir.glob("#{gem_dir}/.git*"))
end
-
- def dummy_gemspec(gemspec)
- return if File.exist?(gemspec)
- gemdir, gemfile = File.split(gemspec)
- Dir.chdir(gemdir) do
- spec = Gem::Specification.new do |s|
- s.name = gemfile.chomp(".gemspec")
- s.version = File.read("lib/#{s.name}.rb")[/VERSION = "(.+?)"/, 1]
- s.authors = ["DUMMY"]
- s.email = ["dummy@ruby-lang.org"]
- s.files = Dir.glob("{lib,ext}/**/*").select {|f| File.file?(f)}
- s.licenses = ["Ruby"]
- s.description = "DO NOT USE; dummy gemspec only for test"
- s.summary = "(dummy gemspec)"
- end
- File.write(gemfile, spec.to_ruby)
- end
- end
-
- def checkout(gemdir, repo, rev, git: $git)
- return unless rev or !git or git.empty?
- unless File.exist?("#{gemdir}/.git")
- puts "Cloning #{repo}"
- command = "#{git} clone #{repo} #{gemdir}"
- system(command) or raise "failed: #{command}"
- end
- puts "Update #{File.basename(gemdir)} to #{rev}"
- command = "#{git} fetch origin #{rev}"
- system(command, chdir: gemdir) or raise "failed: #{command}"
- command = "#{git} checkout --detach #{rev}"
- system(command, chdir: gemdir) or raise "failed: #{command}"
- end
end
diff --git a/tool/lib/colorize.rb b/tool/lib/colorize.rb
index 1131221586..467cd21246 100644
--- a/tool/lib/colorize.rb
+++ b/tool/lib/colorize.rb
@@ -7,7 +7,7 @@ class Colorize
def initialize(color = nil, opts = ((_, color = color, nil)[0] if Hash === color))
@colors = @reset = nil
@color = opts && opts[:color] || color
- if color or (color == nil && coloring?)
+ if color or (color == nil && STDOUT.tty? && (ENV["NO_COLOR"] || "").empty?)
if (%w[smso so].any? {|attr| /\A\e\[.*m\z/ =~ IO.popen("tput #{attr}", "r", :err => IO::NULL, &:read)} rescue nil)
@beg = "\e["
colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:\n]*)/)] : {}
@@ -27,47 +27,21 @@ class Colorize
end
DEFAULTS = {
- # color names
+ "pass"=>"32", "fail"=>"31;1", "skip"=>"33;1",
"black"=>"30", "red"=>"31", "green"=>"32", "yellow"=>"33",
"blue"=>"34", "magenta"=>"35", "cyan"=>"36", "white"=>"37",
"bold"=>"1", "underline"=>"4", "reverse"=>"7",
- "bright_black"=>"90", "bright_red"=>"91", "bright_green"=>"92", "bright_yellow"=>"93",
- "bright_blue"=>"94", "bright_magenta"=>"95", "bright_cyan"=>"96", "bright_white"=>"97",
-
- # abstract decorations
- "pass"=>"green", "fail"=>"red;bold", "skip"=>"yellow;bold", "note"=>"bright_yellow",
}
- def coloring?
- STDOUT.tty? && (!(nc = ENV['NO_COLOR']) || nc.empty?)
- end
-
# colorize.decorate(str, name = color_name)
def decorate(str, name = @color)
- if coloring? and color = resolve_color(name)
+ if @colors and color = (@colors[name] || DEFAULTS[name])
"#{@beg}#{color}m#{str}#{@reset}"
else
str
end
end
- def resolve_color(color = @color, seen = {}, colors = nil)
- return unless @colors
- color.to_s.gsub(/\b[a-z][\w ]+/) do |n|
- n.gsub!(/\W+/, "_")
- n.downcase!
- c = seen[n] and next c
- if colors
- c = colors[n]
- elsif (c = (tbl = @colors)[n] || (tbl = DEFAULTS)[n])
- colors = tbl
- else
- next n
- end
- seen[n] = resolve_color(c, seen, colors)
- end
- end
-
DEFAULTS.each_key do |name|
define_method(name) {|str|
decorate(str, name)
diff --git a/tool/lib/core_assertions.rb b/tool/lib/core_assertions.rb
index 358e7d9551..dea37b093e 100644
--- a/tool/lib/core_assertions.rb
+++ b/tool/lib/core_assertions.rb
@@ -1,43 +1,6 @@
# frozen_string_literal: true
module Test
-
- class << self
- ##
- # Filter object for backtraces.
-
- attr_accessor :backtrace_filter
- end
-
- class BacktraceFilter # :nodoc:
- def filter bt
- return ["No backtrace"] unless bt
-
- new_bt = []
- pattern = %r[/(?:lib\/test/|core_assertions\.rb:)]
-
- unless $DEBUG then
- bt.each do |line|
- break if pattern.match?(line)
- new_bt << line
- end
-
- new_bt = bt.reject { |line| pattern.match?(line) } if new_bt.empty?
- new_bt = bt.dup if new_bt.empty?
- else
- new_bt = bt.dup
- end
-
- new_bt
- end
- end
-
- self.backtrace_filter = BacktraceFilter.new
-
- def self.filter_backtrace bt # :nodoc:
- backtrace_filter.filter bt
- end
-
module Unit
module Assertions
def assert_raises(*exp, &b)
@@ -817,7 +780,9 @@ eom
end
times.compact!
tmin, tmax = times.minmax
- tbase = 10 ** Math.log10(tmax * ([(tmax / tmin), 2].max ** 2)).ceil
+
+ # safe_factor * tmax * rehearsal_time_variance_factor(equals to 1 when variance is small)
+ tbase = 10 * tmax * [(tmax / tmin) ** 2 / 4, 1].max
info = "(tmin: #{tmin}, tmax: #{tmax}, tbase: #{tbase})"
seq.each do |i|
diff --git a/tool/lib/envutil.rb b/tool/lib/envutil.rb
index 4ffa83b66f..728ca7059b 100644
--- a/tool/lib/envutil.rb
+++ b/tool/lib/envutil.rb
@@ -15,22 +15,23 @@ end
module EnvUtil
def rubybin
if ruby = ENV["RUBY"]
- ruby
- elsif defined?(RbConfig.ruby)
+ return ruby
+ end
+ ruby = "ruby"
+ exeext = RbConfig::CONFIG["EXEEXT"]
+ rubyexe = (ruby + exeext if exeext and !exeext.empty?)
+ 3.times do
+ 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
+ ruby = File.join("..", ruby)
+ end
+ if defined?(RbConfig.ruby)
RbConfig.ruby
else
- ruby = "ruby"
- exeext = RbConfig::CONFIG["EXEEXT"]
- rubyexe = (ruby + exeext if exeext and !exeext.empty?)
- 3.times do
- 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
- ruby = File.join("..", ruby)
- end
"ruby"
end
end
@@ -154,7 +155,7 @@ module EnvUtil
# remain env
%w(ASAN_OPTIONS RUBY_ON_BUG).each{|name|
- child_env[name] = ENV[name] if !child_env.key?(name) and ENV.key?(name)
+ child_env[name] = ENV[name] if ENV[name]
}
args = [args] if args.kind_of?(String)
@@ -245,24 +246,6 @@ module EnvUtil
end
module_function :under_gc_stress
- def under_gc_compact_stress(val = :empty, &block)
- raise "compaction doesn't work well on s390x. Omit the test in the caller." if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
- auto_compact = GC.auto_compact
- GC.auto_compact = val
- under_gc_stress(&block)
- ensure
- GC.auto_compact = auto_compact
- end
- module_function :under_gc_compact_stress
-
- def without_gc
- prev_disabled = GC.disable
- yield
- ensure
- GC.enable unless prev_disabled
- end
- module_function :without_gc
-
def with_default_external(enc)
suppress_warning { Encoding.default_external = enc }
yield
diff --git a/tool/lib/iseq_loader_checker.rb b/tool/lib/iseq_loader_checker.rb
index 73784f8450..3f07b3a999 100644
--- a/tool/lib/iseq_loader_checker.rb
+++ b/tool/lib/iseq_loader_checker.rb
@@ -76,15 +76,6 @@ class RubyVM::InstructionSequence
# return value
i2_bin if CHECK_TO_BINARY
end if CHECK_TO_A || CHECK_TO_BINARY
-
- if opt == "prism"
- # If RUBY_ISEQ_DUMP_DEBUG is "prism", we'll set up
- # InstructionSequence.load_iseq to intercept loading filepaths to compile
- # using prism.
- def self.load_iseq(filepath)
- RubyVM::InstructionSequence.compile_file_prism(filepath)
- end
- end
end
#require_relative 'x'; exit(1)
diff --git a/tool/lib/memory_status.rb b/tool/lib/memory_status.rb
index 60632523a8..5e9e80a68a 100644
--- a/tool/lib/memory_status.rb
+++ b/tool/lib/memory_status.rb
@@ -12,7 +12,7 @@ module Memory
PROC_FILE = procfile
VM_PAT = pat
def self.read_status
- File.foreach(PROC_FILE, encoding: Encoding::ASCII_8BIT) do |l|
+ IO.foreach(PROC_FILE, encoding: Encoding::ASCII_8BIT) do |l|
yield($1.downcase.intern, $2.to_i * 1024) if VM_PAT =~ l
end
end
diff --git a/tool/lib/output.rb b/tool/lib/output.rb
index 5c645daca6..51e3d32010 100644
--- a/tool/lib/output.rb
+++ b/tool/lib/output.rb
@@ -6,27 +6,19 @@ class Output
def initialize
@path = @timestamp = @ifchange = @color = nil
- @overwrite = @create_only = false
@vpath = VPath.new
end
- COLOR_WHEN = {
- 'always' => true, 'auto' => nil, 'never' => false,
- nil => true, false => false,
- }
-
def def_options(opt)
opt.separator(" Output common options:")
opt.on('-o', '--output=PATH') {|v| @path = v}
opt.on('-t', '--timestamp[=PATH]') {|v| @timestamp = v || true}
opt.on('-c', '--[no-]if-change') {|v| @ifchange = v}
- opt.on('--[no-]color=[WHEN]', COLOR_WHEN.keys) {|v| @color = COLOR_WHEN[v]}
- opt.on('--[no-]create-only') {|v| @create_only = v}
- opt.on('--[no-]overwrite') {|v| @overwrite = v}
+ opt.on('--color') {@color = true}
@vpath.def_options(opt)
end
- def write(data, overwrite: @overwrite, create_only: @create_only)
+ def write(data, overwrite: false, create_only: false)
unless @path
$stdout.print data
return true
diff --git a/tool/lib/test/unit.rb b/tool/lib/test/unit.rb
index 1c2d5fd924..0fa7b4c5cd 100644
--- a/tool/lib/test/unit.rb
+++ b/tool/lib/test/unit.rb
@@ -24,6 +24,42 @@ require 'optparse'
# See Test::Unit
module Test
+ class << self
+ ##
+ # Filter object for backtraces.
+
+ attr_accessor :backtrace_filter
+ end
+
+ class BacktraceFilter # :nodoc:
+ def filter bt
+ return ["No backtrace"] unless bt
+
+ new_bt = []
+ pattern = %r[/(?:lib\/test/|core_assertions\.rb:)]
+
+ unless $DEBUG then
+ bt.each do |line|
+ break if pattern.match?(line)
+ new_bt << line
+ end
+
+ new_bt = bt.reject { |line| pattern.match?(line) } if new_bt.empty?
+ new_bt = bt.dup if new_bt.empty?
+ else
+ new_bt = bt.dup
+ end
+
+ new_bt
+ end
+ end
+
+ self.backtrace_filter = BacktraceFilter.new
+
+ def self.filter_backtrace bt # :nodoc:
+ backtrace_filter.filter bt
+ end
+
##
# Test::Unit is an implementation of the xUnit testing framework for Ruby.
module Unit
@@ -53,7 +89,17 @@ module Test
end
end
+ module MJITFirst
+ def group(list)
+ # MJIT first
+ mjit, others = list.partition {|e| /test_mjit/ =~ e}
+ mjit + others
+ end
+ end
+
class Alpha < NoSort
+ include MJITFirst
+
def sort_by_name(list)
list.sort_by(&:name)
end
@@ -66,6 +112,8 @@ module Test
# shuffle test suites based on CRC32 of their names
Shuffle = Struct.new(:seed, :salt) do
+ include MJITFirst
+
def initialize(seed)
self.class::CRC_TBL ||= (0..255).map {|i|
(0..7).inject(i) {|c,| (c & 1 == 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1) }
@@ -83,10 +131,6 @@ module Test
list.sort_by {|e| randomize_key(e)}
end
- def group(list)
- list
- end
-
private
def crc32(str, crc32 = 0xffffffff)
@@ -259,7 +303,7 @@ module Test
r.close_on_exec = true
w.close_on_exec = true
@jobserver = [r, w]
- options[:parallel] ||= 256 # number of tokens to acquire first
+ options[:parallel] ||= 1
end
end
@worker_timeout = EnvUtil.apply_timeout_scale(options[:worker_timeout] || 180)
@@ -302,8 +346,7 @@ module Test
options[:retry] = false
end
- opts.on '--ruby VAL', "Path to ruby which is used at -j option",
- "Also used as EnvUtil.rubybin by some assertion methods" do |a|
+ opts.on '--ruby VAL', "Path to ruby which is used at -j option" do |a|
options[:ruby] = a.split(/ /).reject(&:empty?)
end
@@ -653,18 +696,10 @@ module Test
@ios = [] # Array of worker IOs
@job_tokens = String.new(encoding: Encoding::ASCII_8BIT) if @jobserver
begin
- while true
- newjobs = [@tasks.size, @options[:parallel]].min - @workers.size
- if newjobs > 0
- if @jobserver
- t = @jobserver[0].read_nonblock(newjobs, exception: false)
- @job_tokens << t if String === t
- newjobs = @job_tokens.size + 1 - @workers.size
- end
- newjobs.times {launch_worker}
- end
+ [@tasks.size, @options[:parallel]].min.times {launch_worker}
- timeout = [(@workers.filter_map {|w| w.response_at}.min&.-(Time.now) || 0), 0].max + @worker_timeout
+ while true
+ timeout = [(@workers.filter_map {|w| w.response_at}.min&.-(Time.now) || 0) + @worker_timeout, 1].max
if !(_io = IO.select(@ios, nil, nil, timeout))
timeout = Time.now - @worker_timeout
@@ -678,9 +713,15 @@ module Test
}
break
end
- if @tasks.empty?
- break if @workers.empty?
- next # wait for all workers to finish
+ break if @tasks.empty? and @workers.empty?
+ if @jobserver and @job_tokens and !@tasks.empty? and
+ ((newjobs = [@tasks.size, @options[:parallel]].min) > @workers.size or
+ !@workers.any? {|x| x.status == :ready})
+ t = @jobserver[0].read_nonblock(newjobs, exception: false)
+ if String === t
+ @job_tokens << t
+ t.size.times {launch_worker}
+ end
end
end
rescue Interrupt => ex
@@ -772,7 +813,6 @@ module Test
warn ""
@warnings.uniq! {|w| w[1].message}
@warnings.each do |w|
- @errors += 1
warn "#{w[0]}: #{w[1].message} (#{w[1].class})"
end
warn ""
@@ -940,7 +980,7 @@ module Test
end
def _prepare_run(suites, type)
- options[:job_status] ||= @tty ? :replace : :normal unless @verbose
+ options[:job_status] ||= :replace if @tty && !@verbose
case options[:color]
when :always
color = true
@@ -956,14 +996,11 @@ module Test
@output = Output.new(self) unless @options[:testing]
filter = options[:filter]
type = "#{type}_methods"
- total = suites.sum {|suite|
- methods = suite.send(type)
- if filter
- methods.count {|method| filter === "#{suite}##{method}"}
- else
- methods.size
- end
- }
+ total = if filter
+ suites.inject(0) {|n, suite| n + suite.send(type).grep(filter).size}
+ else
+ suites.inject(0) {|n, suite| n + suite.send(type).size}
+ end
@test_count = 0
@total_tests = total.to_s(10)
end
@@ -1057,7 +1094,7 @@ module Test
runner.add_status(" = #$1")
when /\A\.+\z/
runner.succeed
- when /\A\.*[EFST][EFST.]*\z/
+ when /\A\.*[EFS][EFS.]*\z/
runner.failed(s)
else
$stdout.print(s)
@@ -1245,13 +1282,8 @@ module Test
puts "#{f}: #{$!}"
end
}
- @load_failed = errors.size.nonzero?
result
end
-
- def run(*)
- super or @load_failed
- end
end
module RepeatOption # :nodoc: all
@@ -1542,7 +1574,7 @@ module Test
_start_method(inst)
inst._assertions = 0
- print "#{suite}##{method.inspect.sub(/\A:/, '')} = " if @verbose
+ print "#{suite}##{method} = " if @verbose
start_time = Time.now if @verbose
result =
@@ -1557,7 +1589,7 @@ module Test
puts if @verbose
$stdout.flush
- unless defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # compiler process is wrongly considered as leak
+ unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # compiler process is wrongly considered as leak
leakchecker.check("#{inst.class}\##{inst.__name__}")
end
@@ -1648,7 +1680,7 @@ module Test
break unless report.empty?
end
- return (failures + errors).nonzero? # or return nil...
+ return failures + errors if self.test_count > 0 # or return nil...
rescue Interrupt
abort 'Interrupted'
end
diff --git a/tool/lib/test/unit/parallel.rb b/tool/lib/test/unit/parallel.rb
index f2244ec20a..b3a8957f26 100644
--- a/tool/lib/test/unit/parallel.rb
+++ b/tool/lib/test/unit/parallel.rb
@@ -1,6 +1,12 @@
# frozen_string_literal: true
+$LOAD_PATH.unshift "#{__dir__}/../.."
+require_relative '../../test/unit'
-require_relative "../../../test/init"
+require_relative '../../profile_test_all' if ENV.key?('RUBY_TEST_ALL_PROFILE')
+require_relative '../../tracepointchecker'
+require_relative '../../zombie_hunter'
+require_relative '../../iseq_loader_checker'
+require_relative '../../gc_checker'
module Test
module Unit
@@ -202,9 +208,5 @@ if $0 == __FILE__
end
end
require 'rubygems'
- begin
- require 'rake'
- rescue LoadError
- end
Test::Unit::Worker.new.run(ARGV)
end
diff --git a/tool/lib/test/unit/testcase.rb b/tool/lib/test/unit/testcase.rb
index 51ffff37eb..44d9ba7fdb 100644
--- a/tool/lib/test/unit/testcase.rb
+++ b/tool/lib/test/unit/testcase.rb
@@ -137,9 +137,6 @@ module Test
attr_reader :__name__ # :nodoc:
- # Method name of this test.
- alias method_name __name__
-
PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException,
Interrupt, SystemExit] # :nodoc:
@@ -147,7 +144,8 @@ module Test
# Runs the tests reporting the status to +runner+
def run runner
- @__runner_options__ = runner.options
+ @options = runner.options
+
trap "INFO" do
runner.report.each_with_index do |msg, i|
warn "\n%3d) %s" % [i + 1, msg]
@@ -163,7 +161,7 @@ module Test
result = ""
begin
- @__passed__ = nil
+ @passed = nil
self.before_setup
self.setup
self.after_setup
@@ -171,11 +169,11 @@ module Test
result = "." unless io?
time = Time.now - start_time
runner.record self.class, self.__name__, self._assertions, time, nil
- @__passed__ = true
+ @passed = true
rescue *PASSTHROUGH_EXCEPTIONS
raise
rescue Exception => e
- @__passed__ = Test::Unit::PendedError === e
+ @passed = Test::Unit::PendedError === e
time = Time.now - start_time
runner.record self.class, self.__name__, self._assertions, time, e
result = runner.puke self.class, self.__name__, e
@@ -186,7 +184,7 @@ module Test
rescue *PASSTHROUGH_EXCEPTIONS
raise
rescue Exception => e
- @__passed__ = false
+ @passed = false
runner.record self.class, self.__name__, self._assertions, time, e
result = runner.puke self.class, self.__name__, e
end
@@ -208,12 +206,12 @@ module Test
def initialize name # :nodoc:
@__name__ = name
@__io__ = nil
- @__passed__ = nil
- @@__current__ = self # FIX: make thread local
+ @passed = nil
+ @@current = self # FIX: make thread local
end
def self.current # :nodoc:
- @@__current__ # FIX: make thread local
+ @@current # FIX: make thread local
end
##
@@ -265,7 +263,7 @@ module Test
# Returns true if the test passed.
def passed?
- @__passed__
+ @passed
end
##
diff --git a/tool/lib/vcs.rb b/tool/lib/vcs.rb
index ace60f8f8e..857b7928a4 100644
--- a/tool/lib/vcs.rb
+++ b/tool/lib/vcs.rb
@@ -154,7 +154,8 @@ class VCS
alias dryrun? dryrun
alias debug? debug
- NullDevice = IO::NULL
+ NullDevice = defined?(IO::NULL) ? IO::NULL :
+ %w[/dev/null NUL NIL: NL:].find {|dev| File.exist?(dev)}
# returns
# * the last revision of the current branch
@@ -194,7 +195,6 @@ class VCS
rescue ArgumentError
modified = Time.utc(*$~[1..6]) + $7.to_i * 3600 + $8.to_i * 60
end
- modified = modified.getlocal(@zone)
end
return last, changed, modified, *rest
end
@@ -698,41 +698,15 @@ class VCS
fix = $1
s = s.lines
fix.each_line do |x|
- next unless x.sub!(/^(\s+)(?:(\d+)|\$(?:-\d+)?)/, '')
- b = ($2&.to_i || (s.size - 1 + $3.to_i))
- sp = $1
- if x.sub!(/^,(?:(\d+)|\$(?:-\d+)?)/, '')
- range = b..($1&.to_i || (s.size - 1 + $2.to_i))
- else
- range = b..b
- end
case x
- when %r[^s([#{LOG_FIX_REGEXP_SEPARATORS}])(.+)\1(.*)\1([gr]+)?]o
- wrong = $2
- correct = $3
- if opt = $4 and opt.include?("r") # regexp
- wrong = Regexp.new(wrong)
- correct.gsub!(/(?<!\\)(?:\\\\)*\K(?:\\n)+/) {"\n" * ($&.size / 2)}
- sub = opt.include?("g") ? :gsub! : :sub!
- else
- sub = false
- end
- range.each do |n|
- if sub
- ss = s[n].sub(/^#{sp}/, "") # un-indent for /^/
- if ss.__send__(sub, wrong, correct)
- s[n, 1] = ss.lines.map {|l| "#{sp}#{l}"}
- next
- end
- else
- begin
- s[n][wrong] = correct
- rescue IndexError
- else
- next
- end
- end
- message = ["format_changelog failed to replace #{wrong.dump} with #{correct.dump} at #{n}\n"]
+ when %r[^ +(\d+)s([#{LOG_FIX_REGEXP_SEPARATORS}])(.+)\2(.*)\2]o
+ n = $1.to_i
+ wrong = $3
+ correct = $4
+ begin
+ s[n][wrong] = correct
+ rescue IndexError
+ message = ["format_changelog failed to replace #{wrong.dump} with #{correct.dump} at #$1\n"]
from = [1, n-2].max
to = [s.size-1, n+2].min
s.each_with_index do |e, i|
@@ -742,13 +716,12 @@ class VCS
end
raise message.join('')
end
- when %r[^i([#{LOG_FIX_REGEXP_SEPARATORS}])(.*)\1]o
- insert = "#{sp}#{$2}\n"
- range.reverse_each do |n|
- s[n, 0] = insert
- end
- when %r[^d]
- s[range] = []
+ when %r[^( +)(\d+)i([#{LOG_FIX_REGEXP_SEPARATORS}])(.*)\3]o
+ s[$2.to_i, 0] = "#{$1}#{$4}\n"
+ when %r[^ +(\d+)(?:,(\d+))?d]
+ n = $1.to_i
+ e = $2
+ s[n..(e ? e.to_i : n)] = []
end
end
s = s.join('')
diff --git a/tool/ln_sr.rb b/tool/ln_sr.rb
index e1b5b6f76b..2aa8391e17 100755
--- a/tool/ln_sr.rb
+++ b/tool/ln_sr.rb
@@ -96,7 +96,7 @@ unless respond_to?(:ln_sr)
while c = comp.shift
if c == ".." and clean.last != ".." and !(fu_have_symlink? && File.symlink?(path))
clean.pop
- path.sub!(%r((?<=\A|/)[^/]+/\z), "")
+ path.chomp!(%r((?<=\A|/)[^/]+/\z), "")
else
clean << c
path << c << "/"
diff --git a/tool/lrama/LEGAL.md b/tool/lrama/LEGAL.md
deleted file mode 100644
index a3ef848514..0000000000
--- a/tool/lrama/LEGAL.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# LEGAL NOTICE INFORMATION
-
-All the files in this distribution are covered under the MIT License except some files
-mentioned below.
-
-## GNU General Public License version 3
-
-These files are licensed under the GNU General Public License version 3 or later. See these files for more information.
-
-* template/bison/_yacc.h
-* template/bison/yacc.c
-* template/bison/yacc.h
diff --git a/tool/lrama/MIT b/tool/lrama/MIT
deleted file mode 100644
index b23d5210d5..0000000000
--- a/tool/lrama/MIT
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2023 Yuichiro Kaneko
-
-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/tool/lrama/NEWS.md b/tool/lrama/NEWS.md
deleted file mode 100644
index de4c3bbf12..0000000000
--- a/tool/lrama/NEWS.md
+++ /dev/null
@@ -1,167 +0,0 @@
-# NEWS for Lrama
-
-## Lrama 0.5.11 (2023-12-02)
-
-### Type specification of parameterizing rules
-
-Allow to specify type of rules by specifying tag, `<i>` in below example.
-Tag is post-modification style.
-
-```
-%union {
- int i;
-}
-
-%%
-
-program : option(number) <i>
- | number_alias? <i>
- ;
-```
-
-https://github.com/ruby/lrama/pull/272
-
-
-## Lrama 0.5.10 (2023-11-18)
-
-### Parameterizing rules (option, nonempty_list, list)
-
-Support function call style parameterizing rules for `option`, `nonempty_list` and `list`.
-
-https://github.com/ruby/lrama/pull/197
-
-### Parameterizing rules (separated_list)
-
-Support `separated_list` and `separated_nonempty_list` parameterizing rules.
-
-```
-program: separated_list(',', number)
-
-// Expanded to
-
-program: separated_list_number
-separated_list_number: ε
-separated_list_number: separated_nonempty_list_number
-separated_nonempty_list_number: number
-separated_nonempty_list_number: separated_nonempty_list_number ',' number
-```
-
-```
-program: separated_nonempty_list(',', number)
-
-// Expanded to
-
-program: separated_nonempty_list_number
-separated_nonempty_list_number: number
-separated_nonempty_list_number: separated_nonempty_list_number ',' number
-```
-
-https://github.com/ruby/lrama/pull/204
-
-## Lrama 0.5.9 (2023-11-05)
-
-### Parameterizing rules (suffix)
-
-Parameterizing rules are template of rules.
-It's very common pattern to write "list" grammar rule like:
-
-```
-opt_args: /* none */
- | args
- ;
-
-args: arg
- | args arg
-```
-
-Lrama supports these suffixes:
-
-* `?`: option
-* `+`: nonempty list
-* `*`: list
-
-Idea of Parameterizing rules comes from Menhir LR(1) parser generator (https://gallium.inria.fr/~fpottier/menhir/manual.html#sec32).
-
-https://github.com/ruby/lrama/pull/181
-
-## Lrama 0.5.7 (2023-10-23)
-
-### Racc parser
-
-Replace Lrama's parser from hand written parser to LR parser generated by Racc.
-Lrama uses `--embedded` option to generate LR parser because Racc is changed from default gem to bundled gem by Ruby 3.3 (https://github.com/ruby/lrama/pull/132).
-
-https://github.com/ruby/lrama/pull/62
-
-## Lrama 0.5.4 (2023-08-17)
-
-### Runtime configuration for error recovery
-
-Meke error recovery function configurable on runtime by two new macros.
-
-* `YYMAXREPAIR`: Expected to return max length of repair operations. `%parse-param` is passed to this function.
-* `YYERROR_RECOVERY_ENABLED`: Expected to return bool value to determine error recovery is enabled or not. `%parse-param` is passed to this function.
-
-https://github.com/ruby/lrama/pull/74
-
-## Lrama 0.5.3 (2023-08-05)
-
-### Error Recovery
-
-Support token insert base Error Recovery.
-`-e` option is needed to generate parser with error recovery functions.
-
-https://github.com/ruby/lrama/pull/44
-
-## Lrama 0.5.2 (2023-06-14)
-
-### Named References
-
-Instead of positional references like `$1` or `$$`,
-named references allow to access to symbol by name.
-
-```
-primary: k_class cpath superclass bodystmt k_end
- {
- $primary = new_class($cpath, $bodystmt, $superclass);
- }
-```
-
-Alias name can be declared.
-
-```
-expr[result]: expr[ex-left] '+' expr[ex.right]
- {
- $result = $[ex-left] + $[ex.right];
- }
-```
-
-Bison supports this feature from 2.5.
-
-### Add parse params to some macros and functions
-
-`%parse-param` are added to these macros and functions to remove ytab.sed hack from Ruby.
-
-* `YY_LOCATION_PRINT`
-* `YY_SYMBOL_PRINT`
-* `yy_stack_print`
-* `YY_STACK_PRINT`
-* `YY_REDUCE_PRINT`
-* `yysyntax_error`
-
-https://github.com/ruby/lrama/pull/40
-
-See also: https://github.com/ruby/ruby/pull/7807
-
-## Lrama 0.5.0 (2023-05-17)
-
-### stdin mode
-
-When `-` is given as grammar file name, reads the grammar source from STDIN, and takes the next argument as the input file name. This mode helps pre-process a grammar source.
-
-https://github.com/ruby/lrama/pull/8
-
-## Lrama 0.4.0 (2023-05-13)
-
-This is the first version migrated to Ruby.
-This version generates "parse.c" compatible with Bison 3.8.2.
diff --git a/tool/lrama/exe/lrama b/tool/lrama/exe/lrama
deleted file mode 100755
index ba5fb06c82..0000000000
--- a/tool/lrama/exe/lrama
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env ruby
-
-$LOAD_PATH << File.join(__dir__, "../lib")
-require "lrama"
-
-Lrama::Command.new.run(ARGV.dup)
diff --git a/tool/lrama/lib/lrama.rb b/tool/lrama/lib/lrama.rb
deleted file mode 100644
index 9e517b0d71..0000000000
--- a/tool/lrama/lib/lrama.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require "lrama/bitmap"
-require "lrama/command"
-require "lrama/context"
-require "lrama/counterexamples"
-require "lrama/digraph"
-require "lrama/grammar"
-require "lrama/lexer"
-require "lrama/option_parser"
-require "lrama/options"
-require "lrama/output"
-require "lrama/parser"
-require "lrama/report"
-require "lrama/state"
-require "lrama/states"
-require "lrama/states_reporter"
-require "lrama/version"
-require "lrama/warning"
diff --git a/tool/lrama/lib/lrama/bitmap.rb b/tool/lrama/lib/lrama/bitmap.rb
deleted file mode 100644
index 8349a23c34..0000000000
--- a/tool/lrama/lib/lrama/bitmap.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Lrama
- module Bitmap
- def self.from_array(ary)
- bit = 0
-
- ary.each do |int|
- bit |= (1 << int)
- end
-
- bit
- end
-
- def self.to_array(int)
- a = []
- i = 0
-
- while int > 0 do
- if int & 1 == 1
- a << i
- end
-
- i += 1
- int >>= 1
- end
-
- a
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/command.rb b/tool/lrama/lib/lrama/command.rb
deleted file mode 100644
index b6b1fd2766..0000000000
--- a/tool/lrama/lib/lrama/command.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module Lrama
- class Command
- def run(argv)
- options = OptionParser.new.parse(argv)
-
- Report::Duration.enable if options.trace_opts[:time]
-
- warning = Lrama::Warning.new
- text = options.y.read
- options.y.close if options.y != STDIN
- grammar = Lrama::Parser.new(text, options.grammar_file, options.debug).parse
- states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
- states.compute
- context = Lrama::Context.new(states)
-
- if options.report_file
- reporter = Lrama::StatesReporter.new(states)
- File.open(options.report_file, "w+") do |f|
- reporter.report(f, **options.report_opts)
- end
- end
-
- if options.trace_opts && options.trace_opts[:rules]
- puts "Grammar rules:"
- puts grammar.rules
- end
-
- File.open(options.outfile, "w+") do |f|
- Lrama::Output.new(
- out: f,
- output_file_path: options.outfile,
- template_name: options.skeleton,
- grammar_file_path: options.grammar_file,
- header_file_path: options.header_file,
- context: context,
- grammar: grammar,
- error_recovery: options.error_recovery,
- ).render
- end
-
- if warning.has_error?
- exit 1
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/context.rb b/tool/lrama/lib/lrama/context.rb
deleted file mode 100644
index 895290a2bb..0000000000
--- a/tool/lrama/lib/lrama/context.rb
+++ /dev/null
@@ -1,517 +0,0 @@
-require "lrama/report/duration"
-
-module Lrama
- # This is passed to a template
- class Context
- include Report::Duration
-
- ErrorActionNumber = -Float::INFINITY
- BaseMin = -Float::INFINITY
-
- # TODO: It might be better to pass `states` to Output directly?
- attr_reader :states
-
- def initialize(states)
- @states = states
- @yydefact = nil
- @yydefgoto = nil
- # Array of array
- @_actions = []
-
- compute_tables
- end
-
- # enum yytokentype
- def yytokentype
- @states.terms.reject do |term|
- 0 < term.token_id && term.token_id < 128
- end.map do |term|
- [term.id.s_value, term.token_id, term.display_name]
- end.unshift(["YYEMPTY", -2, nil])
- end
-
- # enum yysymbol_kind_t
- def yysymbol_kind_t
- @states.symbols.map do |sym|
- [sym.enum_name, sym.number, sym.comment]
- end.unshift(["YYSYMBOL_YYEMPTY", -2, nil])
- end
-
- # State number of final (accepted) state
- def yyfinal
- @states.states.find do |state|
- state.items.find do |item|
- item.rule.lhs.id.s_value == "$accept" && item.end_of_rule?
- end
- end.id
- end
-
- def yylast
- @yylast
- end
-
- # Number of terms
- def yyntokens
- @states.terms.count
- end
-
- # Number of nterms
- def yynnts
- @states.nterms.count
- end
-
- # Number of rules
- def yynrules
- @states.rules.count
- end
-
- # Number of states
- def yynstates
- @states.states.count
- end
-
- # Last token number
- def yymaxutok
- @states.terms.map(&:token_id).max
- end
-
- # YYTRANSLATE
- #
- # yytranslate is a mapping from token id to symbol number
- def yytranslate
- # 2 is YYSYMBOL_YYUNDEF
- a = Array.new(yymaxutok, 2)
-
- @states.terms.each do |term|
- a[term.token_id] = term.number
- end
-
- return a
- end
-
- def yytranslate_inverted
- a = Array.new(@states.symbols.count, @states.undef_symbol.token_id)
-
- @states.terms.each do |term|
- a[term.number] = term.token_id
- end
-
- return a
- end
-
- # Mapping from rule number to line number of the rule is defined.
- # Dummy rule is appended as the first element whose value is 0
- # because 0 means error in yydefact.
- def yyrline
- a = [0]
-
- @states.rules.each do |rule|
- a << rule.lineno
- end
-
- return a
- end
-
- # Mapping from symbol number to its name
- def yytname
- @states.symbols.sort_by(&:number).map do |sym|
- sym.display_name
- end
- end
-
- def yypact_ninf
- @yypact_ninf
- end
-
- def yytable_ninf
- @yytable_ninf
- end
-
- def yypact
- @base[0...yynstates]
- end
-
- def yydefact
- @yydefact
- end
-
- def yypgoto
- @base[yynstates..-1]
- end
-
- def yydefgoto
- @yydefgoto
- end
-
- def yytable
- @table
- end
-
- def yycheck
- @check
- end
-
- def yystos
- @states.states.map do |state|
- state.accessing_symbol.number
- end
- end
-
- # Mapping from rule number to symbol number of LHS.
- # Dummy rule is appended as the first element whose value is 0
- # because 0 means error in yydefact.
- def yyr1
- a = [0]
-
- @states.rules.each do |rule|
- a << rule.lhs.number
- end
-
- return a
- end
-
- # Mapping from rule number to length of RHS.
- # Dummy rule is appended as the first element whose value is 0
- # because 0 means error in yydefact.
- def yyr2
- a = [0]
-
- @states.rules.each do |rule|
- a << rule.rhs.count
- end
-
- return a
- end
-
- private
-
- # Compute these
- #
- # See also: "src/tables.c" of Bison.
- #
- # * yydefact
- # * yydefgoto
- # * yypact and yypgoto
- # * yytable
- # * yycheck
- # * yypact_ninf
- # * yytable_ninf
- def compute_tables
- report_duration(:compute_yydefact) { compute_yydefact }
- report_duration(:compute_yydefgoto) { compute_yydefgoto }
- report_duration(:sort_actions) { sort_actions }
- # debug_sorted_actions
- report_duration(:compute_packed_table) { compute_packed_table }
- end
-
- def vectors_count
- @states.states.count + @states.nterms.count
- end
-
- # In compressed table, rule 0 is appended as an error case
- # and reduce is represented as minus number.
- def rule_id_to_action_number(rule_id)
- (rule_id + 1) * -1
- end
-
- # Symbol number is assigned to term first then nterm.
- # This method calculates sequence_number for nterm.
- def nterm_number_to_sequence_number(nterm_number)
- nterm_number - @states.terms.count
- end
-
- # Vector is states + nterms
- def nterm_number_to_vector_number(nterm_number)
- @states.states.count + (nterm_number - @states.terms.count)
- end
-
- def compute_yydefact
- # Default action (shift/reduce/error) for each state.
- # Index is state id, value is `rule id + 1` of a default reduction.
- @yydefact = Array.new(@states.states.count, 0)
-
- @states.states.each do |state|
- # Action number means
- #
- # * number = 0, default action
- # * number = -Float::INFINITY, error by %nonassoc
- # * number > 0, shift then move to state "number"
- # * number < 0, reduce by "-number" rule. Rule "number" is already added by 1.
- actions = Array.new(@states.terms.count, 0)
-
- if state.reduces.map(&:selected_look_ahead).any? {|la| !la.empty? }
- # Iterate reduces with reverse order so that first rule is used.
- state.reduces.reverse.each do |reduce|
- reduce.look_ahead.each do |term|
- actions[term.number] = rule_id_to_action_number(reduce.rule.id)
- end
- end
- end
-
- # Shift is selected when S/R conflict exists.
- state.selected_term_transitions.each do |shift, next_state|
- actions[shift.next_sym.number] = next_state.id
- end
-
- state.resolved_conflicts.select do |conflict|
- conflict.which == :error
- end.each do |conflict|
- actions[conflict.symbol.number] = ErrorActionNumber
- end
-
- # If default_reduction_rule, replace default_reduction_rule in
- # actions with zero.
- if state.default_reduction_rule
- actions.map! do |e|
- if e == rule_id_to_action_number(state.default_reduction_rule.id)
- 0
- else
- e
- end
- end
- end
-
- # If no default_reduction_rule, default behavior is an
- # error then replace ErrorActionNumber with zero.
- if !state.default_reduction_rule
- actions.map! do |e|
- if e == ErrorActionNumber
- 0
- else
- e
- end
- end
- end
-
- s = actions.each_with_index.map do |n, i|
- [i, n]
- end.select do |i, n|
- # Remove default_reduction_rule entries
- n != 0
- end
-
- if s.count != 0
- # Entry of @_actions is an array of
- #
- # * State id
- # * Array of tuple, [from, to] where from is term number and to is action.
- # * The number of "Array of tuple" used by sort_actions
- # * "width" used by sort_actions
- @_actions << [state.id, s, s.count, s.last[0] - s.first[0] + 1]
- end
-
- @yydefact[state.id] = state.default_reduction_rule ? state.default_reduction_rule.id + 1 : 0
- end
- end
-
- def compute_yydefgoto
- # Default GOTO (nterm transition) for each nterm.
- # Index is sequence number of nterm, value is state id
- # of a default nterm transition destination.
- @yydefgoto = Array.new(@states.nterms.count, 0)
- # Mapping from nterm to next_states
- nterm_to_next_states = {}
-
- @states.states.each do |state|
- state.nterm_transitions.each do |shift, next_state|
- key = shift.next_sym
- nterm_to_next_states[key] ||= []
- nterm_to_next_states[key] << [state, next_state] # [from_state, to_state]
- end
- end
-
- @states.nterms.each do |nterm|
- if !(states = nterm_to_next_states[nterm])
- default_goto = 0
- not_default_gotos = []
- else
- default_state = states.map(&:last).group_by {|s| s }.max_by {|_, v| v.count }.first
- default_goto = default_state.id
- not_default_gotos = []
- states.each do |from_state, to_state|
- next if to_state.id == default_goto
- not_default_gotos << [from_state.id, to_state.id]
- end
- end
-
- k = nterm_number_to_sequence_number(nterm.number)
- @yydefgoto[k] = default_goto
-
- if not_default_gotos.count != 0
- v = nterm_number_to_vector_number(nterm.number)
-
- # Entry of @_actions is an array of
- #
- # * Nterm number as vector number
- # * Array of tuple, [from, to] where from is state number and to is state number.
- # * The number of "Array of tuple" used by sort_actions
- # * "width" used by sort_actions
- @_actions << [v, not_default_gotos, not_default_gotos.count, not_default_gotos.last[0] - not_default_gotos.first[0] + 1]
- end
- end
- end
-
- def sort_actions
- # This is not same with #sort_actions
- #
- # @sorted_actions = @_actions.sort_by do |_, _, count, width|
- # [-width, -count]
- # end
-
- @sorted_actions = []
-
- @_actions.each do |action|
- if @sorted_actions.empty?
- @sorted_actions << action
- next
- end
-
- j = @sorted_actions.count - 1
- _state_id, _froms_and_tos, count, width = action
-
- while (j >= 0) do
- case
- when @sorted_actions[j][3] < width
- j -= 1
- when @sorted_actions[j][3] == width && @sorted_actions[j][2] < count
- j -= 1
- else
- break
- end
- end
-
- @sorted_actions.insert(j + 1, action)
- end
- end
-
- def debug_sorted_actions
- ary = Array.new
- @sorted_actions.each do |state_id, froms_and_tos, count, width|
- ary[state_id] = [state_id, froms_and_tos, count, width]
- end
-
- print sprintf("table_print:\n\n")
-
- print sprintf("order [\n")
- vectors_count.times do |i|
- print sprintf("%d, ", @sorted_actions[i] ? @sorted_actions[i][0] : 0)
- print "\n" if i % 10 == 9
- end
- print sprintf("]\n\n")
-
- print sprintf("width [\n")
- vectors_count.times do |i|
- print sprintf("%d, ", ary[i] ? ary[i][3] : 0)
- print "\n" if i % 10 == 9
- end
- print sprintf("]\n\n")
-
- print sprintf("tally [\n")
- vectors_count.times do |i|
- print sprintf("%d, ", ary[i] ? ary[i][2] : 0)
- print "\n" if i % 10 == 9
- end
- print sprintf("]\n\n")
- end
-
- def compute_packed_table
- # yypact and yypgoto
- @base = Array.new(vectors_count, BaseMin)
- # yytable
- @table = []
- # yycheck
- @check = []
- # Key is froms_and_tos, value is index position
- pushed = {}
- userd_res = {}
- lowzero = 0
- high = 0
-
- @sorted_actions.each do |state_id, froms_and_tos, _, _|
- if (res = pushed[froms_and_tos])
- @base[state_id] = res
- next
- end
-
- res = lowzero - froms_and_tos.first[0]
-
- while true do
- ok = true
-
- froms_and_tos.each do |from, to|
- loc = res + from
-
- if @table[loc]
- # If the cell of table is set, can not use the cell.
- ok = false
- break
- end
- end
-
- if ok && userd_res[res]
- ok = false
- end
-
- if ok
- break
- else
- res += 1
- end
- end
-
- loc = 0
-
- froms_and_tos.each do |from, to|
- loc = res + from
-
- @table[loc] = to
- @check[loc] = from
- end
-
- while (@table[lowzero]) do
- lowzero += 1
- end
-
- high = loc if high < loc
-
- @base[state_id] = res
- pushed[froms_and_tos] = res
- userd_res[res] = true
- end
-
- @yylast = high
-
- # replace_ninf
- @yypact_ninf = (@base.select {|i| i != BaseMin } + [0]).min - 1
- @base.map! do |i|
- case i
- when BaseMin
- @yypact_ninf
- else
- i
- end
- end
-
- @yytable_ninf = (@table.compact.select {|i| i != ErrorActionNumber } + [0]).min - 1
- @table.map! do |i|
- case i
- when nil
- 0
- when ErrorActionNumber
- @yytable_ninf
- else
- i
- end
- end
-
- @check.map! do |i|
- case i
- when nil
- -1
- else
- i
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples.rb b/tool/lrama/lib/lrama/counterexamples.rb
deleted file mode 100644
index 046265da59..0000000000
--- a/tool/lrama/lib/lrama/counterexamples.rb
+++ /dev/null
@@ -1,286 +0,0 @@
-require "set"
-
-require "lrama/counterexamples/derivation"
-require "lrama/counterexamples/example"
-require "lrama/counterexamples/path"
-require "lrama/counterexamples/production_path"
-require "lrama/counterexamples/start_path"
-require "lrama/counterexamples/state_item"
-require "lrama/counterexamples/transition_path"
-require "lrama/counterexamples/triple"
-
-module Lrama
- # See: https://www.cs.cornell.edu/andru/papers/cupex/cupex.pdf
- # 4. Constructing Nonunifying Counterexamples
- class Counterexamples
- attr_reader :transitions, :productions
-
- def initialize(states)
- @states = states
- setup_transitions
- setup_productions
- end
-
- def to_s
- "#<Counterexamples>"
- end
- alias :inspect :to_s
-
- def compute(conflict_state)
- conflict_state.conflicts.flat_map do |conflict|
- case conflict.type
- when :shift_reduce
- shift_reduce_example(conflict_state, conflict)
- when :reduce_reduce
- reduce_reduce_examples(conflict_state, conflict)
- end
- end.compact
- end
-
- private
-
- def setup_transitions
- # Hash [StateItem, Symbol] => StateItem
- @transitions = {}
- # Hash [StateItem, Symbol] => Set(StateItem)
- @reverse_transitions = {}
-
- @states.states.each do |src_state|
- trans = {}
-
- src_state.transitions.each do |shift, next_state|
- trans[shift.next_sym] = next_state
- end
-
- src_state.items.each do |src_item|
- next if src_item.end_of_rule?
- sym = src_item.next_sym
- dest_state = trans[sym]
-
- dest_state.kernels.each do |dest_item|
- next unless (src_item.rule == dest_item.rule) && (src_item.position + 1 == dest_item.position)
- src_state_item = StateItem.new(src_state, src_item)
- dest_state_item = StateItem.new(dest_state, dest_item)
-
- @transitions[[src_state_item, sym]] = dest_state_item
-
- key = [dest_state_item, sym]
- @reverse_transitions[key] ||= Set.new
- @reverse_transitions[key] << src_state_item
- end
- end
- end
- end
-
- def setup_productions
- # Hash [StateItem] => Set(Item)
- @productions = {}
- # Hash [State, Symbol] => Set(Item). Symbol is nterm
- @reverse_productions = {}
-
- @states.states.each do |state|
- # LHS => Set(Item)
- h = {}
-
- state.closure.each do |item|
- sym = item.lhs
-
- h[sym] ||= Set.new
- h[sym] << item
- end
-
- state.items.each do |item|
- next if item.end_of_rule?
- next if item.next_sym.term?
-
- sym = item.next_sym
- state_item = StateItem.new(state, item)
- key = [state, sym]
-
- @productions[state_item] = h[sym]
-
- @reverse_productions[key] ||= Set.new
- @reverse_productions[key] << item
- end
- end
- end
-
- def shift_reduce_example(conflict_state, conflict)
- conflict_symbol = conflict.symbols.first
- shift_conflict_item = conflict_state.items.find { |item| item.next_sym == conflict_symbol }
- path2 = shortest_path(conflict_state, conflict.reduce.item, conflict_symbol)
- path1 = find_shift_conflict_shortest_path(path2, conflict_state, shift_conflict_item)
-
- Example.new(path1, path2, conflict, conflict_symbol, self)
- end
-
- def reduce_reduce_examples(conflict_state, conflict)
- conflict_symbol = conflict.symbols.first
- path1 = shortest_path(conflict_state, conflict.reduce1.item, conflict_symbol)
- path2 = shortest_path(conflict_state, conflict.reduce2.item, conflict_symbol)
-
- Example.new(path1, path2, conflict, conflict_symbol, self)
- end
-
- def find_shift_conflict_shortest_path(reduce_path, conflict_state, conflict_item)
- state_items = find_shift_conflict_shortest_state_items(reduce_path, conflict_state, conflict_item)
- build_paths_from_state_items(state_items)
- end
-
- def find_shift_conflict_shortest_state_items(reduce_path, conflict_state, conflict_item)
- target_state_item = StateItem.new(conflict_state, conflict_item)
- result = [target_state_item]
- reversed_reduce_path = reduce_path.to_a.reverse
- # Index for state_item
- i = 0
-
- while (path = reversed_reduce_path[i])
- # Index for prev_state_item
- j = i + 1
- _j = j
-
- while (prev_path = reversed_reduce_path[j])
- if prev_path.production?
- j += 1
- else
- break
- end
- end
-
- state_item = path.to
- prev_state_item = prev_path&.to
-
- if target_state_item == state_item || target_state_item.item.start_item?
- result.concat(reversed_reduce_path[_j..-1].map(&:to))
- break
- end
-
- if target_state_item.item.beginning_of_rule?
- queue = []
- queue << [target_state_item]
-
- # Find reverse production
- while (sis = queue.shift)
- si = sis.last
-
- # Reach to start state
- if si.item.start_item?
- sis.shift
- result.concat(sis)
- target_state_item = si
- break
- end
-
- if !si.item.beginning_of_rule?
- key = [si, si.item.previous_sym]
- @reverse_transitions[key].each do |prev_target_state_item|
- next if prev_target_state_item.state != prev_state_item.state
- sis.shift
- result.concat(sis)
- result << prev_target_state_item
- target_state_item = prev_target_state_item
- i = j
- queue.clear
- break
- end
- else
- key = [si.state, si.item.lhs]
- @reverse_productions[key].each do |item|
- state_item = StateItem.new(si.state, item)
- queue << (sis + [state_item])
- end
- end
- end
- else
- # Find reverse transition
- key = [target_state_item, target_state_item.item.previous_sym]
- @reverse_transitions[key].each do |prev_target_state_item|
- next if prev_target_state_item.state != prev_state_item.state
- result << prev_target_state_item
- target_state_item = prev_target_state_item
- i = j
- break
- end
- end
- end
-
- result.reverse
- end
-
- def build_paths_from_state_items(state_items)
- state_items.zip([nil] + state_items).map do |si, prev_si|
- case
- when prev_si.nil?
- StartPath.new(si)
- when si.item.beginning_of_rule?
- ProductionPath.new(prev_si, si)
- else
- TransitionPath.new(prev_si, si)
- end
- end
- end
-
- def shortest_path(conflict_state, conflict_reduce_item, conflict_term)
- # queue: is an array of [Triple, [Path]]
- queue = []
- visited = {}
- start_state = @states.states.first
- raise "BUG: Start state should be just one kernel." if start_state.kernels.count != 1
-
- start = Triple.new(start_state, start_state.kernels.first, Set.new([@states.eof_symbol]))
-
- queue << [start, [StartPath.new(start.state_item)]]
-
- while true
- triple, paths = queue.shift
-
- next if visited[triple]
- visited[triple] = true
-
- # Found
- if triple.state == conflict_state && triple.item == conflict_reduce_item && triple.l.include?(conflict_term)
- return paths
- end
-
- # transition
- triple.state.transitions.each do |shift, next_state|
- next unless triple.item.next_sym && triple.item.next_sym == shift.next_sym
- next_state.kernels.each do |kernel|
- next if kernel.rule != triple.item.rule
- t = Triple.new(next_state, kernel, triple.l)
- queue << [t, paths + [TransitionPath.new(triple.state_item, t.state_item)]]
- end
- end
-
- # production step
- triple.state.closure.each do |item|
- next unless triple.item.next_sym && triple.item.next_sym == item.lhs
- l = follow_l(triple.item, triple.l)
- t = Triple.new(triple.state, item, l)
- queue << [t, paths + [ProductionPath.new(triple.state_item, t.state_item)]]
- end
-
- break if queue.empty?
- end
-
- return nil
- end
-
- def follow_l(item, current_l)
- # 1. follow_L (A -> X1 ... Xn-1 • Xn) = L
- # 2. follow_L (A -> X1 ... Xk • Xk+1 Xk+2 ... Xn) = {Xk+2} if Xk+2 is a terminal
- # 3. follow_L (A -> X1 ... Xk • Xk+1 Xk+2 ... Xn) = FIRST(Xk+2) if Xk+2 is a nonnullable nonterminal
- # 4. follow_L (A -> X1 ... Xk • Xk+1 Xk+2 ... Xn) = FIRST(Xk+2) + follow_L (A -> X1 ... Xk+1 • Xk+2 ... Xn) if Xk+2 is a nullable nonterminal
- case
- when item.number_of_rest_symbols == 1
- current_l
- when item.next_next_sym.term?
- Set.new([item.next_next_sym])
- when !item.next_next_sym.nullable
- item.next_next_sym.first_set
- else
- item.next_next_sym.first_set + follow_l(item.new_by_next_position, current_l)
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/derivation.rb b/tool/lrama/lib/lrama/counterexamples/derivation.rb
deleted file mode 100644
index 691e935356..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/derivation.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-module Lrama
- class Counterexamples
- class Derivation
- attr_reader :item, :left, :right
- attr_writer :right
-
- def initialize(item, left, right = nil)
- @item = item
- @left = left
- @right = right
- end
-
- def to_s
- "#<Derivation(#{item.display_name})>"
- end
- alias :inspect :to_s
-
- def render_strings_for_report
- result = []
- _render_for_report(self, 0, result, 0)
- result.map(&:rstrip)
- end
-
- def render_for_report
- render_strings_for_report.join("\n")
- end
-
- private
-
- def _render_for_report(derivation, offset, strings, index)
- item = derivation.item
- if strings[index]
- strings[index] << " " * (offset - strings[index].length)
- else
- strings[index] = " " * offset
- end
- str = strings[index]
- str << "#{item.rule_id}: #{item.symbols_before_dot.map(&:display_name).join(" ")} "
-
- if derivation.left
- len = str.length
- str << "#{item.next_sym.display_name}"
- length = _render_for_report(derivation.left, len, strings, index + 1)
- # I want String#ljust!
- str << " " * (length - str.length)
- else
- str << " • #{item.symbols_after_dot.map(&:display_name).join(" ")} "
- return str.length
- end
-
- if derivation.right&.left
- length = _render_for_report(derivation.right.left, str.length, strings, index + 1)
- str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} "
- str << " " * (length - str.length) if length > str.length
- elsif item.next_next_sym
- str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} "
- end
-
- return str.length
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/example.rb b/tool/lrama/lib/lrama/counterexamples/example.rb
deleted file mode 100644
index 8f02d71fa4..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/example.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-module Lrama
- class Counterexamples
- class Example
- attr_reader :path1, :path2, :conflict, :conflict_symbol
-
- # path1 is shift conflict when S/R conflict
- # path2 is always reduce conflict
- def initialize(path1, path2, conflict, conflict_symbol, counterexamples)
- @path1 = path1
- @path2 = path2
- @conflict = conflict
- @conflict_symbol = conflict_symbol
- @counterexamples = counterexamples
- end
-
- def type
- @conflict.type
- end
-
- def path1_item
- @path1.last.to.item
- end
-
- def path2_item
- @path2.last.to.item
- end
-
- def derivations1
- @derivations1 ||= _derivations(path1)
- end
-
- def derivations2
- @derivations2 ||= _derivations(path2)
- end
-
- private
-
- def _derivations(paths)
- derivation = nil
- current = :production
- lookahead_sym = paths.last.to.item.end_of_rule? ? @conflict_symbol : nil
-
- paths.reverse.each do |path|
- item = path.to.item
-
- case current
- when :production
- case path
- when StartPath
- derivation = Derivation.new(item, derivation)
- current = :start
- when TransitionPath
- derivation = Derivation.new(item, derivation)
- current = :transition
- when ProductionPath
- derivation = Derivation.new(item, derivation)
- current = :production
- end
-
- if lookahead_sym && item.next_next_sym && item.next_next_sym.first_set.include?(lookahead_sym)
- state_item = @counterexamples.transitions[[path.to, item.next_sym]]
- derivation2 = find_derivation_for_symbol(state_item, lookahead_sym)
- derivation.right = derivation2
- lookahead_sym = nil
- end
-
- when :transition
- case path
- when StartPath
- derivation = Derivation.new(item, derivation)
- current = :start
- when TransitionPath
- # ignore
- current = :transition
- when ProductionPath
- # ignore
- current = :production
- end
- else
- raise "BUG: Unknown #{current}"
- end
-
- break if current == :start
- end
-
- derivation
- end
-
- def find_derivation_for_symbol(state_item, sym)
- queue = []
- queue << [state_item]
-
- while (sis = queue.shift)
- si = sis.last
- next_sym = si.item.next_sym
-
- if next_sym == sym
- derivation = nil
-
- sis.reverse.each do |si|
- derivation = Derivation.new(si.item, derivation)
- end
-
- return derivation
- end
-
- if next_sym.nterm? && next_sym.first_set.include?(sym)
- @counterexamples.productions[si].each do |next_item|
- next if next_item.empty_rule?
- next_si = StateItem.new(si.state, next_item)
- next if sis.include?(next_si)
- queue << (sis + [next_si])
- end
-
- if next_sym.nullable
- next_si = @counterexamples.transitions[[si, next_sym]]
- queue << (sis + [next_si])
- end
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/path.rb b/tool/lrama/lib/lrama/counterexamples/path.rb
deleted file mode 100644
index edba67a3b6..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/path.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module Lrama
- class Counterexamples
- class Path
- def initialize(from_state_item, to_state_item)
- @from_state_item = from_state_item
- @to_state_item = to_state_item
- end
-
- def from
- @from_state_item
- end
-
- def to
- @to_state_item
- end
-
- def to_s
- "#<Path(#{type})>"
- end
- alias :inspect :to_s
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/production_path.rb b/tool/lrama/lib/lrama/counterexamples/production_path.rb
deleted file mode 100644
index d7db688518..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/production_path.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module Lrama
- class Counterexamples
- class ProductionPath < Path
- def type
- :production
- end
-
- def transition?
- false
- end
-
- def production?
- true
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/start_path.rb b/tool/lrama/lib/lrama/counterexamples/start_path.rb
deleted file mode 100644
index 4a6821cd0f..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/start_path.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Lrama
- class Counterexamples
- class StartPath < Path
- def initialize(to_state_item)
- super nil, to_state_item
- end
-
- def type
- :start
- end
-
- def transition?
- false
- end
-
- def production?
- false
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/state_item.rb b/tool/lrama/lib/lrama/counterexamples/state_item.rb
deleted file mode 100644
index 930ff4a5f8..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/state_item.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Lrama
- class Counterexamples
- class StateItem < Struct.new(:state, :item)
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/transition_path.rb b/tool/lrama/lib/lrama/counterexamples/transition_path.rb
deleted file mode 100644
index 96e611612a..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/transition_path.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module Lrama
- class Counterexamples
- class TransitionPath < Path
- def type
- :transition
- end
-
- def transition?
- true
- end
-
- def production?
- false
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/counterexamples/triple.rb b/tool/lrama/lib/lrama/counterexamples/triple.rb
deleted file mode 100644
index e802beccf4..0000000000
--- a/tool/lrama/lib/lrama/counterexamples/triple.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Lrama
- class Counterexamples
- # s: state
- # itm: item within s
- # l: precise lookahead set
- class Triple < Struct.new(:s, :itm, :l)
- alias :state :s
- alias :item :itm
- alias :precise_lookahead_set :l
-
- def state_item
- StateItem.new(state, item)
- end
-
- def inspect
- "#{state.inspect}. #{item.display_name}. #{l.map(&:id).map(&:s_value)}"
- end
- alias :to_s :inspect
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/digraph.rb b/tool/lrama/lib/lrama/digraph.rb
deleted file mode 100644
index bbaa86019f..0000000000
--- a/tool/lrama/lib/lrama/digraph.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-module Lrama
- # Algorithm Digraph of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625)
- class Digraph
- def initialize(sets, relation, base_function)
- # X in the paper
- @sets = sets
- # R in the paper
- @relation = relation
- # F' in the paper
- @base_function = base_function
- # S in the paper
- @stack = []
- # N in the paper
- @h = Hash.new(0)
- # F in the paper
- @result = {}
- end
-
- def compute
- @sets.each do |x|
- next if @h[x] != 0
- traverse(x)
- end
-
- return @result
- end
-
- private
-
- def traverse(x)
- @stack.push(x)
- d = @stack.count
- @h[x] = d
- @result[x] = @base_function[x] # F x = F' x
-
- @relation[x]&.each do |y|
- traverse(y) if @h[y] == 0
- @h[x] = [@h[x], @h[y]].min
- @result[x] |= @result[y] # F x = F x + F y
- end
-
- if @h[x] == d
- while (z = @stack.pop) do
- @h[z] = Float::INFINITY
- break if z == x
- @result[z] = @result[x] # F (Top of S) = F x
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar.rb b/tool/lrama/lib/lrama/grammar.rb
deleted file mode 100644
index c6bdc8a644..0000000000
--- a/tool/lrama/lib/lrama/grammar.rb
+++ /dev/null
@@ -1,612 +0,0 @@
-require "lrama/grammar/auxiliary"
-require "lrama/grammar/code"
-require "lrama/grammar/counter"
-require "lrama/grammar/error_token"
-require "lrama/grammar/percent_code"
-require "lrama/grammar/precedence"
-require "lrama/grammar/printer"
-require "lrama/grammar/reference"
-require "lrama/grammar/rule"
-require "lrama/grammar/rule_builder"
-require "lrama/grammar/symbol"
-require "lrama/grammar/type"
-require "lrama/grammar/union"
-require "lrama/lexer"
-
-module Lrama
- # Grammar is the result of parsing an input grammar file
- class Grammar
- attr_reader :percent_codes, :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux
- attr_accessor :union, :expect,
- :printers, :error_tokens,
- :lex_param, :parse_param, :initial_action,
- :symbols, :types,
- :rules, :rule_builders,
- :sym_to_rules
-
- def initialize(rule_counter)
- @rule_counter = rule_counter
-
- # Code defined by "%code"
- @percent_codes = []
- @printers = []
- @error_tokens = []
- @symbols = []
- @types = []
- @rule_builders = []
- @rules = []
- @sym_to_rules = {}
- @empty_symbol = nil
- @eof_symbol = nil
- @error_symbol = nil
- @undef_symbol = nil
- @accept_symbol = nil
- @aux = Auxiliary.new
-
- append_special_symbols
- end
-
- def add_percent_code(id:, code:)
- @percent_codes << PercentCode.new(id, code)
- end
-
- def add_printer(ident_or_tags:, token_code:, lineno:)
- @printers << Printer.new(ident_or_tags: ident_or_tags, token_code: token_code, lineno: lineno)
- end
-
- def add_error_token(ident_or_tags:, token_code:, lineno:)
- @error_tokens << ErrorToken.new(ident_or_tags: ident_or_tags, token_code: token_code, lineno: lineno)
- end
-
- def add_term(id:, alias_name: nil, tag: nil, token_id: nil, replace: false)
- if token_id && (sym = @symbols.find {|s| s.token_id == token_id })
- if replace
- sym.id = id
- sym.alias_name = alias_name
- sym.tag = tag
- end
-
- return sym
- end
-
- if sym = @symbols.find {|s| s.id == id }
- return sym
- end
-
- sym = Symbol.new(
- id: id, alias_name: alias_name, number: nil, tag: tag,
- term: true, token_id: token_id, nullable: false
- )
- @symbols << sym
- @terms = nil
-
- return sym
- end
-
- def add_nterm(id:, alias_name: nil, tag: nil)
- return if @symbols.find {|s| s.id == id }
-
- sym = Symbol.new(
- id: id, alias_name: alias_name, number: nil, tag: tag,
- term: false, token_id: nil, nullable: nil,
- )
- @symbols << sym
- @nterms = nil
-
- return sym
- end
-
- def add_type(id:, tag:)
- @types << Type.new(id: id, tag: tag)
- end
-
- def add_nonassoc(sym, precedence)
- set_precedence(sym, Precedence.new(type: :nonassoc, precedence: precedence))
- end
-
- def add_left(sym, precedence)
- set_precedence(sym, Precedence.new(type: :left, precedence: precedence))
- end
-
- def add_right(sym, precedence)
- set_precedence(sym, Precedence.new(type: :right, precedence: precedence))
- end
-
- def add_precedence(sym, precedence)
- set_precedence(sym, Precedence.new(type: :precedence, precedence: precedence))
- end
-
- def set_precedence(sym, precedence)
- raise "" if sym.nterm?
- sym.precedence = precedence
- end
-
- def set_union(code, lineno)
- @union = Union.new(code: code, lineno: lineno)
- end
-
- def add_rule_builder(builder)
- @rule_builders << builder
- end
-
- def prologue_first_lineno=(prologue_first_lineno)
- @aux.prologue_first_lineno = prologue_first_lineno
- end
-
- def prologue=(prologue)
- @aux.prologue = prologue
- end
-
- def epilogue_first_lineno=(epilogue_first_lineno)
- @aux.epilogue_first_lineno = epilogue_first_lineno
- end
-
- def epilogue=(epilogue)
- @aux.epilogue = epilogue
- end
-
- def prepare
- normalize_rules
- collect_symbols
- set_lhs_and_rhs
- fill_symbol_number
- fill_default_precedence
- fill_sym_to_rules
- fill_nterm_type
- fill_symbol_printer
- fill_symbol_error_token
- @symbols.sort_by!(&:number)
- compute_nullable
- compute_first_set
- end
-
- # TODO: More validation methods
- #
- # * Validaiton for no_declared_type_reference
- def validate!
- validate_symbol_number_uniqueness!
- validate_symbol_alias_name_uniqueness!
- validate_rule_lhs_is_nterm!
- end
-
- def find_symbol_by_s_value(s_value)
- @symbols.find do |sym|
- sym.id.s_value == s_value
- end
- end
-
- def find_symbol_by_s_value!(s_value)
- find_symbol_by_s_value(s_value) || (raise "Symbol not found: #{s_value}")
- end
-
- def find_symbol_by_id(id)
- @symbols.find do |sym|
- sym.id == id || sym.alias_name == id.s_value
- end
- end
-
- def find_symbol_by_id!(id)
- find_symbol_by_id(id) || (raise "Symbol not found: #{id}")
- end
-
- def find_symbol_by_number!(number)
- sym = @symbols[number]
-
- raise "Symbol not found: #{number}" unless sym
- raise "[BUG] Symbol number mismatch. #{number}, #{sym}" if sym.number != number
-
- sym
- end
-
- def find_rules_by_symbol!(sym)
- find_rules_by_symbol(sym) || (raise "Rules for #{sym} not found")
- end
-
- def find_rules_by_symbol(sym)
- @sym_to_rules[sym.number]
- end
-
- def terms_count
- terms.count
- end
-
- def terms
- @terms ||= @symbols.select(&:term?)
- end
-
- def nterms_count
- nterms.count
- end
-
- def nterms
- @nterms ||= @symbols.select(&:nterm?)
- end
-
- private
-
- def compute_nullable
- @rules.each do |rule|
- case
- when rule.rhs.empty?
- rule.nullable = true
- when rule.rhs.any?(&:term)
- rule.nullable = false
- else
- # noop
- end
- end
-
- while true do
- rs = @rules.select {|e| e.nullable.nil? }
- nts = nterms.select {|e| e.nullable.nil? }
- rule_count_1 = rs.count
- nterm_count_1 = nts.count
-
- rs.each do |rule|
- if rule.rhs.all?(&:nullable)
- rule.nullable = true
- end
- end
-
- nts.each do |nterm|
- find_rules_by_symbol!(nterm).each do |rule|
- if rule.nullable
- nterm.nullable = true
- end
- end
- end
-
- rule_count_2 = @rules.count {|e| e.nullable.nil? }
- nterm_count_2 = nterms.count {|e| e.nullable.nil? }
-
- if (rule_count_1 == rule_count_2) && (nterm_count_1 == nterm_count_2)
- break
- end
- end
-
- rules.select {|r| r.nullable.nil? }.each do |rule|
- rule.nullable = false
- end
-
- nterms.select {|r| r.nullable.nil? }.each do |nterm|
- nterm.nullable = false
- end
- end
-
- def compute_first_set
- terms.each do |term|
- term.first_set = Set.new([term]).freeze
- term.first_set_bitmap = Lrama::Bitmap.from_array([term.number])
- end
-
- nterms.each do |nterm|
- nterm.first_set = Set.new([]).freeze
- nterm.first_set_bitmap = Lrama::Bitmap.from_array([])
- end
-
- while true do
- changed = false
-
- @rules.each do |rule|
- rule.rhs.each do |r|
- if rule.lhs.first_set_bitmap | r.first_set_bitmap != rule.lhs.first_set_bitmap
- changed = true
- rule.lhs.first_set_bitmap = rule.lhs.first_set_bitmap | r.first_set_bitmap
- end
-
- break unless r.nullable
- end
- end
-
- break unless changed
- end
-
- nterms.each do |nterm|
- nterm.first_set = Lrama::Bitmap.to_array(nterm.first_set_bitmap).map do |number|
- find_symbol_by_number!(number)
- end.to_set
- end
- end
-
- def setup_rules
- @rule_builders.each do |builder|
- builder.setup_rules
- end
- end
-
- def find_nterm_by_id!(id)
- nterms.find do |nterm|
- nterm.id == id
- end || (raise "Nterm not found: #{id}")
- end
-
- def append_special_symbols
- # YYEMPTY (token_id: -2, number: -2) is added when a template is evaluated
- # term = add_term(id: Token.new(Token::Ident, "YYEMPTY"), token_id: -2)
- # term.number = -2
- # @empty_symbol = term
-
- # YYEOF
- term = add_term(id: Lrama::Lexer::Token::Ident.new(s_value: "YYEOF"), alias_name: "\"end of file\"", token_id: 0)
- term.number = 0
- term.eof_symbol = true
- @eof_symbol = term
-
- # YYerror
- term = add_term(id: Lrama::Lexer::Token::Ident.new(s_value: "YYerror"), alias_name: "error")
- term.number = 1
- term.error_symbol = true
- @error_symbol = term
-
- # YYUNDEF
- term = add_term(id: Lrama::Lexer::Token::Ident.new(s_value: "YYUNDEF"), alias_name: "\"invalid token\"")
- term.number = 2
- term.undef_symbol = true
- @undef_symbol = term
-
- # $accept
- term = add_nterm(id: Lrama::Lexer::Token::Ident.new(s_value: "$accept"))
- term.accept_symbol = true
- @accept_symbol = term
- end
-
- # 1. Add $accept rule to the top of rules
- # 2. Extract action in the middle of RHS into new Empty rule
- # 3. Append id and extract action then create Rule
- #
- # Bison 3.8.2 uses different orders for symbol number and rule number
- # when a rule has actions in the middle of a rule.
- #
- # For example,
- #
- # `program: $@1 top_compstmt`
- #
- # Rules are ordered like below,
- #
- # 1 $@1: ε
- # 2 program: $@1 top_compstmt
- #
- # Symbols are ordered like below,
- #
- # 164 program
- # 165 $@1
- #
- def normalize_rules
- # 1. Add $accept rule to the top of rules
- accept = @accept_symbol
- eof = @eof_symbol
- lineno = @rule_builders.first ? @rule_builders.first.line : 0
- @rules << Rule.new(id: @rule_counter.increment, _lhs: accept.id, _rhs: [@rule_builders.first.lhs, eof.id], token_code: nil, lineno: lineno)
-
- setup_rules
-
- @rule_builders.each do |builder|
- # Extract actions in the middle of RHS into new rules.
- builder.midrule_action_rules.each do |rule|
- @rules << rule
- end
-
- builder.rules.each do |rule|
- add_nterm(id: rule._lhs)
- @rules << rule
- end
-
- builder.parameterizing_rules.each do |rule|
- add_nterm(id: rule._lhs, tag: rule.lhs_tag)
- @rules << rule
- end
-
- builder.midrule_action_rules.each do |rule|
- add_nterm(id: rule._lhs)
- end
- end
- end
-
- # Collect symbols from rules
- def collect_symbols
- @rules.flat_map(&:_rhs).each do |s|
- case s
- when Lrama::Lexer::Token::Char
- add_term(id: s)
- when Lrama::Lexer::Token
- # skip
- else
- raise "Unknown class: #{s}"
- end
- end
- end
-
- # Fill #number and #token_id
- def fill_symbol_number
- # Character literal in grammar file has
- # token id corresponding to ASCII code by default,
- # so start token_id from 256.
- token_id = 256
-
- # YYEMPTY = -2
- # YYEOF = 0
- # YYerror = 1
- # YYUNDEF = 2
- number = 3
-
- nterm_token_id = 0
- used_numbers = {}
-
- @symbols.map(&:number).each do |n|
- used_numbers[n] = true
- end
-
- (@symbols.select(&:term?) + @symbols.select(&:nterm?)).each do |sym|
- while used_numbers[number] do
- number += 1
- end
-
- if sym.number.nil?
- sym.number = number
- number += 1
- end
-
- # If id is Token::Char, it uses ASCII code
- if sym.term? && sym.token_id.nil?
- if sym.id.is_a?(Lrama::Lexer::Token::Char)
- # Ignore ' on the both sides
- case sym.id.s_value[1..-2]
- when "\\b"
- sym.token_id = 8
- when "\\f"
- sym.token_id = 12
- when "\\n"
- sym.token_id = 10
- when "\\r"
- sym.token_id = 13
- when "\\t"
- sym.token_id = 9
- when "\\v"
- sym.token_id = 11
- when "\""
- sym.token_id = 34
- when "'"
- sym.token_id = 39
- when "\\\\"
- sym.token_id = 92
- when /\A\\(\d+)\z/
- sym.token_id = Integer($1, 8)
- when /\A(.)\z/
- sym.token_id = $1.bytes.first
- else
- raise "Unknown Char s_value #{sym}"
- end
- else
- sym.token_id = token_id
- token_id += 1
- end
- end
-
- if sym.nterm? && sym.token_id.nil?
- sym.token_id = nterm_token_id
- nterm_token_id += 1
- end
- end
- end
-
- def set_lhs_and_rhs
- @rules.each do |rule|
- rule.lhs = token_to_symbol(rule._lhs) if rule._lhs
-
- rule.rhs = rule._rhs.map do |t|
- token_to_symbol(t)
- end
- end
- end
-
- def token_to_symbol(token)
- case token
- when Lrama::Lexer::Token
- find_symbol_by_id!(token)
- else
- raise "Unknown class: #{token}"
- end
- end
-
- # Rule inherits precedence from the last term in RHS.
- #
- # https://www.gnu.org/software/bison/manual/html_node/How-Precedence.html
- def fill_default_precedence
- @rules.each do |rule|
- # Explicitly specified precedence has the highest priority
- next if rule.precedence_sym
-
- precedence_sym = nil
- rule.rhs.each do |sym|
- precedence_sym = sym if sym.term?
- end
-
- rule.precedence_sym = precedence_sym
- end
- end
-
- def fill_sym_to_rules
- @rules.each do |rule|
- key = rule.lhs.number
- @sym_to_rules[key] ||= []
- @sym_to_rules[key] << rule
- end
- end
-
- # Fill nterm's tag defined by %type decl
- def fill_nterm_type
- @types.each do |type|
- nterm = find_nterm_by_id!(type.id)
- nterm.tag = type.tag
- end
- end
-
- def fill_symbol_printer
- @symbols.each do |sym|
- @printers.each do |printer|
- printer.ident_or_tags.each do |ident_or_tag|
- case ident_or_tag
- when Lrama::Lexer::Token::Ident
- sym.printer = printer if sym.id == ident_or_tag
- when Lrama::Lexer::Token::Tag
- sym.printer = printer if sym.tag == ident_or_tag
- else
- raise "Unknown token type. #{printer}"
- end
- end
- end
- end
- end
-
- def fill_symbol_error_token
- @symbols.each do |sym|
- @error_tokens.each do |error_token|
- error_token.ident_or_tags.each do |ident_or_tag|
- case ident_or_tag
- when Lrama::Lexer::Token::Ident
- sym.error_token = error_token if sym.id == ident_or_tag
- when Lrama::Lexer::Token::Tag
- sym.error_token = error_token if sym.tag == ident_or_tag
- else
- raise "Unknown token type. #{error_token}"
- end
- end
- end
- end
- end
-
- def validate_symbol_number_uniqueness!
- invalid = @symbols.group_by(&:number).select do |number, syms|
- syms.count > 1
- end
-
- return if invalid.empty?
-
- raise "Symbol number is duplicated. #{invalid}"
- end
-
- def validate_symbol_alias_name_uniqueness!
- invalid = @symbols.select(&:alias_name).group_by(&:alias_name).select do |alias_name, syms|
- syms.count > 1
- end
-
- return if invalid.empty?
-
- raise "Symbol alias name is duplicated. #{invalid}"
- end
-
- def validate_rule_lhs_is_nterm!
- errors = []
-
- rules.each do |rule|
- next if rule.lhs.nterm?
-
- errors << "[BUG] LHS of #{rule} (line: #{rule.lineno}) is term. It should be nterm."
- end
-
- return if errors.empty?
-
- raise errors.join("\n")
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/auxiliary.rb b/tool/lrama/lib/lrama/grammar/auxiliary.rb
deleted file mode 100644
index 933574b0f6..0000000000
--- a/tool/lrama/lib/lrama/grammar/auxiliary.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Lrama
- class Grammar
- # Grammar file information not used by States but by Output
- class Auxiliary < Struct.new(:prologue_first_lineno, :prologue, :epilogue_first_lineno, :epilogue, keyword_init: true)
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/code.rb b/tool/lrama/lib/lrama/grammar/code.rb
deleted file mode 100644
index f5c9d0f701..0000000000
--- a/tool/lrama/lib/lrama/grammar/code.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require "forwardable"
-
-module Lrama
- class Grammar
- class Code < Struct.new(:type, :token_code, keyword_init: true)
- extend Forwardable
-
- def_delegators "token_code", :s_value, :line, :column, :references
-
- # $$, $n, @$, @n are translated to C code
- def translated_code
- t_code = s_value.dup
-
- references.reverse.each do |ref|
- first_column = ref.first_column
- last_column = ref.last_column
-
- str = reference_to_c(ref)
-
- t_code[first_column..last_column] = str
- end
-
- return t_code
- end
-
- private
-
- def reference_to_c(ref)
- raise NotImplementedError.new("#reference_to_c is not implemented")
- end
- end
- end
-end
-
-require "lrama/grammar/code/initial_action_code"
-require "lrama/grammar/code/no_reference_code"
-require "lrama/grammar/code/printer_code"
-require "lrama/grammar/code/rule_action"
diff --git a/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb b/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb
deleted file mode 100644
index 2b064f271e..0000000000
--- a/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Lrama
- class Grammar
- class Code
- class InitialActionCode < Code
- private
-
- # * ($$) yylval
- # * (@$) yylloc
- # * ($1) error
- # * (@1) error
- def reference_to_c(ref)
- case
- when ref.type == :dollar && ref.name == "$" # $$
- "yylval"
- when ref.type == :at && ref.name == "$" # @$
- "yylloc"
- when ref.type == :dollar # $n
- raise "$#{ref.value} can not be used in initial_action."
- when ref.type == :at # @n
- raise "@#{ref.value} can not be used in initial_action."
- else
- raise "Unexpected. #{self}, #{ref}"
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb b/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb
deleted file mode 100644
index ac6cdb8fba..0000000000
--- a/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module Lrama
- class Grammar
- class Code
- class NoReferenceCode < Code
- private
-
- # * ($$) error
- # * (@$) error
- # * ($1) error
- # * (@1) error
- def reference_to_c(ref)
- case
- when ref.type == :dollar # $$, $n
- raise "$#{ref.value} can not be used in #{type}."
- when ref.type == :at # @$, @n
- raise "@#{ref.value} can not be used in #{type}."
- else
- raise "Unexpected. #{self}, #{ref}"
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/code/printer_code.rb b/tool/lrama/lib/lrama/grammar/code/printer_code.rb
deleted file mode 100644
index a19646adda..0000000000
--- a/tool/lrama/lib/lrama/grammar/code/printer_code.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module Lrama
- class Grammar
- class Code
- class PrinterCode < Code
- def initialize(type: nil, token_code: nil, tag: nil)
- super(type: type, token_code: token_code)
- @tag = tag
- end
-
- private
-
- # * ($$) *yyvaluep
- # * (@$) *yylocationp
- # * ($1) error
- # * (@1) error
- def reference_to_c(ref)
- case
- when ref.type == :dollar && ref.name == "$" # $$
- member = @tag.member
- "((*yyvaluep).#{member})"
- when ref.type == :at && ref.name == "$" # @$
- "(*yylocationp)"
- when ref.type == :dollar # $n
- raise "$#{ref.value} can not be used in #{type}."
- when ref.type == :at # @n
- raise "@#{ref.value} can not be used in #{type}."
- else
- raise "Unexpected. #{self}, #{ref}"
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/code/rule_action.rb b/tool/lrama/lib/lrama/grammar/code/rule_action.rb
deleted file mode 100644
index 984c350b25..0000000000
--- a/tool/lrama/lib/lrama/grammar/code/rule_action.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-module Lrama
- class Grammar
- class Code
- class RuleAction < Code
- def initialize(type: nil, token_code: nil, rule: nil)
- super(type: type, token_code: token_code)
- @rule = rule
- end
-
- private
-
- # * ($$) yyval
- # * (@$) yyloc
- # * ($1) yyvsp[i]
- # * (@1) yylsp[i]
- #
- #
- # Consider a rule like
- #
- # class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
- #
- # For the semantic action of original rule:
- #
- # "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
- # "Position in grammar" $1 $2 $3 $4 $5 $6
- # "Index for yyvsp" -4 -3 -2 -1 0
- #
- #
- # For the first midrule action:
- #
- # "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
- # "Position in grammar" $1
- # "Index for yyvsp" 0
- def reference_to_c(ref)
- case
- when ref.type == :dollar && ref.name == "$" # $$
- tag = ref.ex_tag || lhs.tag
- raise_tag_not_found_error(ref) unless tag
- "(yyval.#{tag.member})"
- when ref.type == :at && ref.name == "$" # @$
- "(yyloc)"
- when ref.type == :dollar # $n
- i = -position_in_rhs + ref.index
- tag = ref.ex_tag || rhs[ref.index - 1].tag
- raise_tag_not_found_error(ref) unless tag
- "(yyvsp[#{i}].#{tag.member})"
- when ref.type == :at # @n
- i = -position_in_rhs + ref.index
- "(yylsp[#{i}])"
- else
- raise "Unexpected. #{self}, #{ref}"
- end
- end
-
- def position_in_rhs
- # If rule is not derived rule, User Code is only action at
- # the end of rule RHS. In such case, the action is located on
- # `@rule.rhs.count`.
- @rule.position_in_original_rule_rhs || @rule.rhs.count
- end
-
- # If this is midrule action, RHS is a RHS of the original rule.
- def rhs
- (@rule.original_rule || @rule).rhs
- end
-
- # Unlike `rhs`, LHS is always a LHS of the rule.
- def lhs
- @rule.lhs
- end
-
- def raise_tag_not_found_error(ref)
- raise "Tag is not specified for '$#{ref.value}' in '#{@rule.to_s}'"
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/counter.rb b/tool/lrama/lib/lrama/grammar/counter.rb
deleted file mode 100644
index c13f4ec3e3..0000000000
--- a/tool/lrama/lib/lrama/grammar/counter.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Lrama
- class Grammar
- class Counter
- def initialize(number)
- @number = number
- end
-
- def increment
- n = @number
- @number += 1
- n
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/error_token.rb b/tool/lrama/lib/lrama/grammar/error_token.rb
deleted file mode 100644
index 8efde7df33..0000000000
--- a/tool/lrama/lib/lrama/grammar/error_token.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Lrama
- class Grammar
- class ErrorToken < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
- def translated_code(tag)
- Code::PrinterCode.new(type: :error_token, token_code: token_code, tag: tag).translated_code
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb
deleted file mode 100644
index 20950b9b36..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-require 'lrama/grammar/parameterizing_rules/builder/base'
-require 'lrama/grammar/parameterizing_rules/builder/list'
-require 'lrama/grammar/parameterizing_rules/builder/nonempty_list'
-require 'lrama/grammar/parameterizing_rules/builder/option'
-require 'lrama/grammar/parameterizing_rules/builder/separated_nonempty_list'
-require 'lrama/grammar/parameterizing_rules/builder/separated_list'
-
-module Lrama
- class Grammar
- class ParameterizingRules
- # Builder for parameterizing rules
- class Builder
- RULES = {
- option: Lrama::Grammar::ParameterizingRules::Builder::Option,
- "?": Lrama::Grammar::ParameterizingRules::Builder::Option,
- nonempty_list: Lrama::Grammar::ParameterizingRules::Builder::NonemptyList,
- "+": Lrama::Grammar::ParameterizingRules::Builder::NonemptyList,
- list: Lrama::Grammar::ParameterizingRules::Builder::List,
- "*": Lrama::Grammar::ParameterizingRules::Builder::List,
- separated_nonempty_list: Lrama::Grammar::ParameterizingRules::Builder::SeparatedNonemptyList,
- separated_list: Lrama::Grammar::ParameterizingRules::Builder::SeparatedList,
- }
-
- def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
- @token = token
- @key = token.s_value.to_sym
- @rule_counter = rule_counter
- @lhs_tag = lhs_tag
- @user_code = user_code
- @precedence_sym = precedence_sym
- @line = line
- @builder = nil
- end
-
- def build
- create_builder
- @builder.build
- end
-
- def build_token
- create_builder
- @builder.build_token
- end
-
- private
-
- def create_builder
- unless @builder
- validate_key!
- @builder = RULES[@key].new(@token, @rule_counter, @lhs_tag, @user_code, @precedence_sym, @line)
- end
- end
-
- def validate_key!
- raise "Parameterizing rule does not exist. `#{@key}`" unless RULES.key?(@key)
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb
deleted file mode 100644
index 5787714f0c..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/base.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-module Lrama
- class Grammar
- class ParameterizingRules
- class Builder
- # Base class for parameterizing rules builder
- class Base
- attr_reader :build_token
-
- def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
- @args = token.args
- @token = @args.first
- @rule_counter = rule_counter
- @lhs_tag = lhs_tag
- @user_code = user_code
- @precedence_sym = precedence_sym
- @line = line
- @expected_argument_num = 1
- @build_token = nil
- end
-
- def build
- raise NotImplementedError
- end
-
- private
-
- def validate_argument_number!
- unless @args.count == @expected_argument_num
- raise "Invalid number of arguments. expect: #{@expected_argument_num} actual: #{@args.count}"
- end
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb
deleted file mode 100644
index 248e1e7ad4..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/list.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Lrama
- class Grammar
- class ParameterizingRules
- class Builder
- # Builder for list of general parameterizing rules
- class List < Base
-
- # program: list(number)
- #
- # =>
- #
- # program: list_number
- # list_number: ε
- # list_number: list_number number
- def build
- validate_argument_number!
-
- rules = []
- @build_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{@token.s_value}")
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb
deleted file mode 100644
index bcec1d823a..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Lrama
- class Grammar
- class ParameterizingRules
- class Builder
- # Builder for nonempty list of general parameterizing rules
- class NonemptyList < Base
-
- # program: nonempty_list(number)
- #
- # =>
- #
- # program: nonempty_list_number
- # nonempty_list_number: number
- # nonempty_list_number: nonempty_list_number number
- def build
- validate_argument_number!
-
- rules = []
- @build_token = Lrama::Lexer::Token::Ident.new(s_value: "nonempty_list_#{@token.s_value}")
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb
deleted file mode 100644
index 8be045ec30..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/option.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Lrama
- class Grammar
- class ParameterizingRules
- class Builder
- # Builder for option of general parameterizing rules
- class Option < Base
-
- # program: option(number)
- #
- # =>
- #
- # program: option_number
- # option_number: ε
- # option_number: number
- def build
- validate_argument_number!
-
- rules = []
- @build_token = Lrama::Lexer::Token::Ident.new(s_value: "option_#{@token.s_value}")
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb
deleted file mode 100644
index f9677cadbc..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module Lrama
- class Grammar
- class ParameterizingRules
- class Builder
- # Builder for separated list of general parameterizing rules
- class SeparatedList < Base
- def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
- super
- @separator = @args[0]
- @token = @args[1]
- @expected_argument_num = 2
- end
-
- # program: separated_list(',', number)
- #
- # =>
- #
- # program: separated_list_number
- # separated_list_number: ε
- # separated_list_number: separated_nonempty_list_number
- # separated_nonempty_list_number: number
- # separated_nonempty_list_number: separated_nonempty_list_number ',' number
- def build
- validate_argument_number!
-
- rules = []
- @build_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_list_#{@token.s_value}")
- separated_nonempty_list_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_nonempty_list_#{@token.s_value}")
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [separated_nonempty_list_token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: separated_nonempty_list_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: separated_nonempty_list_token, _rhs: [separated_nonempty_list_token, @separator, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb
deleted file mode 100644
index ba6ecf24cc..0000000000
--- a/tool/lrama/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module Lrama
- class Grammar
- class ParameterizingRules
- class Builder
- # Builder for separated nonempty list of general parameterizing rules
- class SeparatedNonemptyList < Base
- def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
- super
- @separator = @args[0]
- @token = @args[1]
- @expected_argument_num = 2
- end
-
- # program: separated_nonempty_list(',', number)
- #
- # =>
- #
- # program: separated_nonempty_list_number
- # separated_nonempty_list_number: number
- # separated_nonempty_list_number: separated_nonempty_list_number ',' number
- def build
- validate_argument_number!
-
- rules = []
- @build_token = Lrama::Lexer::Token::Ident.new(s_value: "separated_nonempty_list_#{@token.s_value}")
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @separator, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
- rules
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/percent_code.rb b/tool/lrama/lib/lrama/grammar/percent_code.rb
deleted file mode 100644
index 5faa3a582b..0000000000
--- a/tool/lrama/lib/lrama/grammar/percent_code.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Lrama
- class Grammar
- class PercentCode
- attr_reader :id, :code
-
- def initialize(id, code)
- @id = id
- @code = code
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/precedence.rb b/tool/lrama/lib/lrama/grammar/precedence.rb
deleted file mode 100644
index fed739b3c0..0000000000
--- a/tool/lrama/lib/lrama/grammar/precedence.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module Lrama
- class Grammar
- class Precedence < Struct.new(:type, :precedence, keyword_init: true)
- include Comparable
-
- def <=>(other)
- self.precedence <=> other.precedence
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/printer.rb b/tool/lrama/lib/lrama/grammar/printer.rb
deleted file mode 100644
index 8984a96e1a..0000000000
--- a/tool/lrama/lib/lrama/grammar/printer.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Lrama
- class Grammar
- class Printer < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
- def translated_code(tag)
- Code::PrinterCode.new(type: :printer, token_code: token_code, tag: tag).translated_code
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/reference.rb b/tool/lrama/lib/lrama/grammar/reference.rb
deleted file mode 100644
index 24c981298e..0000000000
--- a/tool/lrama/lib/lrama/grammar/reference.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Lrama
- class Grammar
- # type: :dollar or :at
- # name: String (e.g. $$, $foo, $expr.right)
- # index: Integer (e.g. $1)
- # ex_tag: "$<tag>1" (Optional)
- class Reference < Struct.new(:type, :name, :index, :ex_tag, :first_column, :last_column, keyword_init: true)
- def value
- name || index
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/rule.rb b/tool/lrama/lib/lrama/grammar/rule.rb
deleted file mode 100644
index 2876472030..0000000000
--- a/tool/lrama/lib/lrama/grammar/rule.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-module Lrama
- class Grammar
- # _rhs holds original RHS element. Use rhs to refer to Symbol.
- class Rule < Struct.new(:id, :_lhs, :lhs, :lhs_tag, :_rhs, :rhs, :token_code, :position_in_original_rule_rhs, :nullable, :precedence_sym, :lineno, keyword_init: true)
- attr_accessor :original_rule
-
- def ==(other)
- self.class == other.class &&
- self.lhs == other.lhs &&
- self.lhs_tag == other.lhs_tag &&
- self.rhs == other.rhs &&
- self.token_code == other.token_code &&
- self.position_in_original_rule_rhs == other.position_in_original_rule_rhs &&
- self.nullable == other.nullable &&
- self.precedence_sym == other.precedence_sym &&
- self.lineno == other.lineno
- end
-
- # TODO: Change this to display_name
- def to_s
- l = lhs.id.s_value
- r = rhs.empty? ? "ε" : rhs.map {|r| r.id.s_value }.join(", ")
-
- "#{l} -> #{r}"
- end
-
- # Used by #user_actions
- def as_comment
- l = lhs.id.s_value
- r = rhs.empty? ? "%empty" : rhs.map(&:display_name).join(" ")
-
- "#{l}: #{r}"
- end
-
- # opt_nl: ε <-- empty_rule
- # | '\n' <-- not empty_rule
- def empty_rule?
- rhs.empty?
- end
-
- def precedence
- precedence_sym&.precedence
- end
-
- def initial_rule?
- id == 0
- end
-
- def translated_code
- return nil unless token_code
-
- Code::RuleAction.new(type: :rule_action, token_code: token_code, rule: self).translated_code
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/rule_builder.rb b/tool/lrama/lib/lrama/grammar/rule_builder.rb
deleted file mode 100644
index 94a744dca0..0000000000
--- a/tool/lrama/lib/lrama/grammar/rule_builder.rb
+++ /dev/null
@@ -1,177 +0,0 @@
-require 'lrama/grammar/parameterizing_rules/builder'
-
-module Lrama
- class Grammar
- class RuleBuilder
- attr_accessor :lhs, :lhs_tag, :line
- attr_reader :rhs, :user_code, :precedence_sym
-
- def initialize(rule_counter, midrule_action_counter, position_in_original_rule_rhs = nil, skip_preprocess_references: false)
- @rule_counter = rule_counter
- @midrule_action_counter = midrule_action_counter
- @position_in_original_rule_rhs = position_in_original_rule_rhs
- @skip_preprocess_references = skip_preprocess_references
-
- @lhs = nil
- @rhs = []
- @lhs_tag = nil
- @user_code = nil
- @precedence_sym = nil
- @line = nil
- @rule_builders_for_derived_rules = []
- end
-
- def add_rhs(rhs)
- if !@line
- @line = rhs.line
- end
-
- flush_user_code
-
- @rhs << rhs
- end
-
- def user_code=(user_code)
- if !@line
- @line = user_code.line
- end
-
- flush_user_code
-
- @user_code = user_code
- end
-
- def precedence_sym=(precedence_sym)
- flush_user_code
-
- @precedence_sym = precedence_sym
- end
-
- def complete_input
- freeze_rhs
- end
-
- def setup_rules
- preprocess_references unless @skip_preprocess_references
- process_rhs
- build_rules
- end
-
- def parameterizing_rules
- @parameterizing_rules
- end
-
- def midrule_action_rules
- @midrule_action_rules
- end
-
- def rules
- @rules
- end
-
- private
-
- def freeze_rhs
- @rhs.freeze
- end
-
- def preprocess_references
- numberize_references
- end
-
- def build_rules
- tokens = @replaced_rhs
-
- rule = Rule.new(
- id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, token_code: user_code,
- position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line
- )
- @rules = [rule]
- @midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder|
- rule_builder.rules
- end.flatten
- @midrule_action_rules.each do |r|
- r.original_rule = rule
- end
- end
-
- # rhs is a mixture of variety type of tokens like `Ident`, `Parameterizing`, `UserCode` and so on.
- # `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`.
- def process_rhs
- return if @replaced_rhs
-
- @replaced_rhs = []
- @parameterizing_rules = []
-
- rhs.each_with_index do |token, i|
- case token
- when Lrama::Lexer::Token::Char
- @replaced_rhs << token
- when Lrama::Lexer::Token::Ident
- @replaced_rhs << token
- when Lrama::Lexer::Token::Parameterizing
- parameterizing = ParameterizingRules::Builder.new(token, @rule_counter, @lhs_tag, user_code, precedence_sym, line)
- parameterizing.build.each do |r|
- @parameterizing_rules << r
- end
- @replaced_rhs << parameterizing.build_token
- when Lrama::Lexer::Token::UserCode
- prefix = token.referred ? "@" : "$@"
- new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s)
- @replaced_rhs << new_token
-
- rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, skip_preprocess_references: true)
- rule_builder.lhs = new_token
- rule_builder.user_code = token
- rule_builder.complete_input
- rule_builder.setup_rules
-
- @rule_builders_for_derived_rules << rule_builder
- else
- raise "Unexpected token. #{token}"
- end
- end
- end
-
- def numberize_references
- # Bison n'th component is 1-origin
- (rhs + [user_code]).compact.each.with_index(1) do |token, i|
- next unless token.is_a?(Lrama::Lexer::Token::UserCode)
-
- token.references.each do |ref|
- ref_name = ref.name
- if ref_name && ref_name != '$'
- if lhs.referred_by?(ref_name)
- ref.name = '$'
- else
- candidates = rhs.each_with_index.select {|token, i| token.referred_by?(ref_name) }
-
- raise "Referring symbol `#{ref_name}` is duplicated. #{token}" if candidates.size >= 2
- raise "Referring symbol `#{ref_name}` is not found. #{token}" unless referring_symbol = candidates.first
-
- ref.index = referring_symbol[1] + 1
- end
- end
-
- # TODO: Need to check index of @ too?
- next if ref.type == :at
-
- if ref.index
- # TODO: Prohibit $0 even so Bison allows it?
- # See: https://www.gnu.org/software/bison/manual/html_node/Actions.html
- raise "Can not refer following component. #{ref.index} >= #{i}. #{token}" if ref.index >= i
- rhs[ref.index - 1].referred = true
- end
- end
- end
- end
-
- def flush_user_code
- if c = @user_code
- @rhs << c
- @user_code = nil
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/symbol.rb b/tool/lrama/lib/lrama/grammar/symbol.rb
deleted file mode 100644
index df866db716..0000000000
--- a/tool/lrama/lib/lrama/grammar/symbol.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-# Symbol is both of nterm and term
-# `number` is both for nterm and term
-# `token_id` is tokentype for term, internal sequence number for nterm
-#
-# TODO: Add validation for ASCII code range for Token::Char
-
-module Lrama
- class Grammar
- class Symbol
- attr_accessor :id, :alias_name, :tag, :number, :token_id, :nullable, :precedence, :printer, :error_token, :first_set, :first_set_bitmap
- attr_reader :term
- attr_writer :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol
-
- def initialize(id:, alias_name: nil, number: nil, tag: nil, term:, token_id: nil, nullable: nil, precedence: nil, printer: nil)
- @id = id
- @alias_name = alias_name
- @number = number
- @tag = tag
- @term = term
- @token_id = token_id
- @nullable = nullable
- @precedence = precedence
- @printer = printer
- end
-
- def term?
- term
- end
-
- def nterm?
- !term
- end
-
- def eof_symbol?
- !!@eof_symbol
- end
-
- def error_symbol?
- !!@error_symbol
- end
-
- def undef_symbol?
- !!@undef_symbol
- end
-
- def accept_symbol?
- !!@accept_symbol
- end
-
- def display_name
- alias_name || id.s_value
- end
-
- # name for yysymbol_kind_t
- #
- # See: b4_symbol_kind_base
- # @type var name: String
- def enum_name
- case
- when accept_symbol?
- name = "YYACCEPT"
- when eof_symbol?
- name = "YYEOF"
- when term? && id.is_a?(Lrama::Lexer::Token::Char)
- name = number.to_s + display_name
- when term? && id.is_a?(Lrama::Lexer::Token::Ident)
- name = id.s_value
- when nterm? && (id.s_value.include?("$") || id.s_value.include?("@"))
- name = number.to_s + id.s_value
- when nterm?
- name = id.s_value
- else
- raise "Unexpected #{self}"
- end
-
- "YYSYMBOL_" + name.gsub(/\W+/, "_")
- end
-
- # comment for yysymbol_kind_t
- def comment
- case
- when accept_symbol?
- # YYSYMBOL_YYACCEPT
- id.s_value
- when eof_symbol?
- # YYEOF
- alias_name
- when (term? && 0 < token_id && token_id < 128)
- # YYSYMBOL_3_backslash_, YYSYMBOL_14_
- alias_name || id.s_value
- when id.s_value.include?("$") || id.s_value.include?("@")
- # YYSYMBOL_21_1
- id.s_value
- else
- # YYSYMBOL_keyword_class, YYSYMBOL_strings_1
- alias_name || id.s_value
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/type.rb b/tool/lrama/lib/lrama/grammar/type.rb
deleted file mode 100644
index 6861d9f846..0000000000
--- a/tool/lrama/lib/lrama/grammar/type.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Lrama
- class Grammar
- class Type < Struct.new(:id, :tag, keyword_init: true)
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/grammar/union.rb b/tool/lrama/lib/lrama/grammar/union.rb
deleted file mode 100644
index 854bffb5c1..0000000000
--- a/tool/lrama/lib/lrama/grammar/union.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module Lrama
- class Grammar
- class Union < Struct.new(:code, :lineno, keyword_init: true)
- def braces_less_code
- # Braces is already removed by lexer
- code.s_value
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer.rb b/tool/lrama/lib/lrama/lexer.rb
deleted file mode 100644
index 8aab19be5c..0000000000
--- a/tool/lrama/lib/lrama/lexer.rb
+++ /dev/null
@@ -1,174 +0,0 @@
-require "strscan"
-require "lrama/lexer/location"
-require "lrama/lexer/token"
-
-module Lrama
- class Lexer
- attr_reader :head_line, :head_column
- attr_accessor :status
- attr_accessor :end_symbol
-
- SYMBOLS = ['%{', '%}', '%%', '{', '}', '\[', '\]', '\(', '\)', '\,', ':', '\|', ';']
- PERCENT_TOKENS = %w(
- %union
- %token
- %type
- %left
- %right
- %nonassoc
- %expect
- %define
- %require
- %printer
- %lex-param
- %parse-param
- %initial-action
- %precedence
- %prec
- %error-token
- %empty
- %code
- )
-
- def initialize(text)
- @scanner = StringScanner.new(text)
- @head_column = @head = @scanner.pos
- @head_line = @line = 1
- @status = :initial
- @end_symbol = nil
- end
-
- def next_token
- case @status
- when :initial
- lex_token
- when :c_declaration
- lex_c_code
- end
- end
-
- def line
- @line
- end
-
- def column
- @scanner.pos - @head
- end
-
- def location
- Location.new(
- first_line: @head_line, first_column: @head_column,
- last_line: @line, last_column: column
- )
- end
-
- def lex_token
- while !@scanner.eos? do
- case
- when @scanner.scan(/\n/)
- newline
- when @scanner.scan(/\s+/)
- # noop
- when @scanner.scan(/\/\*/)
- lex_comment
- when @scanner.scan(/\/\/.*(?<newline>\n)?/)
- newline if @scanner[:newline]
- else
- break
- end
- end
-
- @head_line = line
- @head_column = column
-
- case
- when @scanner.eos?
- return
- when @scanner.scan(/#{SYMBOLS.join('|')}/)
- return [@scanner.matched, @scanner.matched]
- when @scanner.scan(/#{PERCENT_TOKENS.join('|')}/)
- return [@scanner.matched, @scanner.matched]
- when @scanner.scan(/[\?\+\*]/)
- return [@scanner.matched, @scanner.matched]
- when @scanner.scan(/<\w+>/)
- return [:TAG, Lrama::Lexer::Token::Tag.new(s_value: @scanner.matched, location: location)]
- when @scanner.scan(/'.'/)
- return [:CHARACTER, Lrama::Lexer::Token::Char.new(s_value: @scanner.matched, location: location)]
- when @scanner.scan(/'\\\\'|'\\b'|'\\t'|'\\f'|'\\r'|'\\n'|'\\v'|'\\13'/)
- return [:CHARACTER, Lrama::Lexer::Token::Char.new(s_value: @scanner.matched, location: location)]
- when @scanner.scan(/".*?"/)
- return [:STRING, %Q(#{@scanner.matched})]
- when @scanner.scan(/\d+/)
- return [:INTEGER, Integer(@scanner.matched)]
- when @scanner.scan(/([a-zA-Z_.][-a-zA-Z0-9_.]*)/)
- token = Lrama::Lexer::Token::Ident.new(s_value: @scanner.matched, location: location)
- type =
- if @scanner.check(/\s*(\[\s*[a-zA-Z_.][-a-zA-Z0-9_.]*\s*\])?\s*:/)
- :IDENT_COLON
- else
- :IDENTIFIER
- end
- return [type, token]
- else
- raise ParseError, "Unexpected token: #{@scanner.peek(10).chomp}."
- end
- end
-
- def lex_c_code
- nested = 0
- code = ''
- while !@scanner.eos? do
- case
- when @scanner.scan(/{/)
- code += @scanner.matched
- nested += 1
- when @scanner.scan(/}/)
- if nested == 0 && @end_symbol == '}'
- @scanner.unscan
- return [:C_DECLARATION, Lrama::Lexer::Token::UserCode.new(s_value: code, location: location)]
- else
- code += @scanner.matched
- nested -= 1
- end
- when @scanner.check(/#{@end_symbol}/)
- return [:C_DECLARATION, Lrama::Lexer::Token::UserCode.new(s_value: code, location: location)]
- when @scanner.scan(/\n/)
- code += @scanner.matched
- newline
- when @scanner.scan(/".*?"/)
- code += %Q(#{@scanner.matched})
- @line += @scanner.matched.count("\n")
- when @scanner.scan(/'.*?'/)
- code += %Q(#{@scanner.matched})
- else
- if @scanner.scan(/[^\"'\{\}\n#{@end_symbol}]+/)
- code += @scanner.matched
- else
- code += @scanner.getch
- end
- end
- end
- raise ParseError, "Unexpected code: #{code}."
- end
-
- private
-
- def lex_comment
- while !@scanner.eos? do
- case
- when @scanner.scan(/\n/)
- newline
- when @scanner.scan(/\*\//)
- return
- else
- @scanner.getch
- end
- end
- end
-
- def newline
- @line += 1
- @head = @scanner.pos + 1
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/location.rb b/tool/lrama/lib/lrama/lexer/location.rb
deleted file mode 100644
index d247c7d4cf..0000000000
--- a/tool/lrama/lib/lrama/lexer/location.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-module Lrama
- class Lexer
- class Location
- attr_reader :first_line, :first_column, :last_line, :last_column
-
- def initialize(first_line:, first_column:, last_line:, last_column:)
- @first_line = first_line
- @first_column = first_column
- @last_line = last_line
- @last_column = last_column
- end
-
- def ==(other)
- self.class == other.class &&
- self.first_line == other.first_line &&
- self.first_column == other.first_column &&
- self.last_line == other.last_line &&
- self.last_column == other.last_column
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/token.rb b/tool/lrama/lib/lrama/lexer/token.rb
deleted file mode 100644
index b82f86bb05..0000000000
--- a/tool/lrama/lib/lrama/lexer/token.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'lrama/lexer/token/char'
-require 'lrama/lexer/token/ident'
-require 'lrama/lexer/token/parameterizing'
-require 'lrama/lexer/token/tag'
-require 'lrama/lexer/token/user_code'
-
-module Lrama
- class Lexer
- class Token
- attr_reader :s_value, :location
- attr_accessor :alias_name, :referred
-
- def initialize(s_value:, alias_name: nil, location: nil)
- s_value.freeze
- @s_value = s_value
- @alias_name = alias_name
- @location = location
- end
-
- def to_s
- "#{super} location: #{location}"
- end
-
- def referred_by?(string)
- [self.s_value, self.alias_name].compact.include?(string)
- end
-
- def ==(other)
- self.class == other.class && self.s_value == other.s_value
- end
-
- def first_line
- location.first_line
- end
- alias :line :first_line
-
- def first_column
- location.first_column
- end
- alias :column :first_column
-
- def last_line
- location.last_line
- end
-
- def last_column
- location.last_column
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/token/char.rb b/tool/lrama/lib/lrama/lexer/token/char.rb
deleted file mode 100644
index ec3560ca09..0000000000
--- a/tool/lrama/lib/lrama/lexer/token/char.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Lrama
- class Lexer
- class Token
- class Char < Token
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/token/ident.rb b/tool/lrama/lib/lrama/lexer/token/ident.rb
deleted file mode 100644
index e576eaeccd..0000000000
--- a/tool/lrama/lib/lrama/lexer/token/ident.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Lrama
- class Lexer
- class Token
- class Ident < Token
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/token/parameterizing.rb b/tool/lrama/lib/lrama/lexer/token/parameterizing.rb
deleted file mode 100644
index f2eed3cf4a..0000000000
--- a/tool/lrama/lib/lrama/lexer/token/parameterizing.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module Lrama
- class Lexer
- class Token
- class Parameterizing < Token
- attr_accessor :args
-
- def initialize(s_value:, alias_name: nil, location: nil, args: [])
- super s_value: s_value, alias_name: alias_name, location: location
- @args = args
- end
-
- def option?
- %w(option ?).include?(self.s_value)
- end
-
- def nonempty_list?
- %w(nonempty_list +).include?(self.s_value)
- end
-
- def list?
- %w(list *).include?(self.s_value)
- end
-
- def separated_nonempty_list?
- %w(separated_nonempty_list).include?(self.s_value)
- end
-
- def separated_list?
- %w(separated_list).include?(self.s_value)
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/token/tag.rb b/tool/lrama/lib/lrama/lexer/token/tag.rb
deleted file mode 100644
index e54d773915..0000000000
--- a/tool/lrama/lib/lrama/lexer/token/tag.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Lrama
- class Lexer
- class Token
- class Tag < Token
- # Omit "<>"
- def member
- s_value[1..-2] or raise "Unexpected Tag format (#{s_value})"
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/lexer/token/user_code.rb b/tool/lrama/lib/lrama/lexer/token/user_code.rb
deleted file mode 100644
index abe6fba2b3..0000000000
--- a/tool/lrama/lib/lrama/lexer/token/user_code.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require "strscan"
-
-module Lrama
- class Lexer
- class Token
- class UserCode < Token
- def references
- @references ||= _references
- end
-
- private
-
- def _references
- scanner = StringScanner.new(s_value)
- references = []
-
- while !scanner.eos? do
- case
- when reference = scan_reference(scanner)
- references << reference
- when scanner.scan(/\/\*/)
- scanner.scan_until(/\*\//)
- else
- scanner.getch
- end
- end
-
- references
- end
-
- def scan_reference(scanner)
- start = scanner.pos
- case
- # $ references
- # It need to wrap an identifier with brackets to use ".-" for identifiers
- when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
- tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
- return Lrama::Grammar::Reference.new(type: :dollar, name: "$", ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
- when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
- tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
- return Lrama::Grammar::Reference.new(type: :dollar, index: Integer(scanner[2]), ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
- when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
- tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
- return Lrama::Grammar::Reference.new(type: :dollar, name: scanner[2], ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
- when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
- tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
- return Lrama::Grammar::Reference.new(type: :dollar, name: scanner[2], ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
-
- # @ references
- # It need to wrap an identifier with brackets to use ".-" for identifiers
- when scanner.scan(/@\$/) # @$
- return Lrama::Grammar::Reference.new(type: :at, name: "$", first_column: start, last_column: scanner.pos - 1)
- when scanner.scan(/@(\d+)/) # @1
- return Lrama::Grammar::Reference.new(type: :at, index: Integer(scanner[1]), first_column: start, last_column: scanner.pos - 1)
- when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
- return Lrama::Grammar::Reference.new(type: :at, name: scanner[1], first_column: start, last_column: scanner.pos - 1)
- when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
- return Lrama::Grammar::Reference.new(type: :at, name: scanner[1], first_column: start, last_column: scanner.pos - 1)
- end
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/option_parser.rb b/tool/lrama/lib/lrama/option_parser.rb
deleted file mode 100644
index 560b269b06..0000000000
--- a/tool/lrama/lib/lrama/option_parser.rb
+++ /dev/null
@@ -1,128 +0,0 @@
-require 'optparse'
-
-module Lrama
- # Handle option parsing for the command line interface.
- class OptionParser
- def initialize
- @options = Options.new
- @trace = []
- @report = []
- end
-
- def parse(argv)
- parse_by_option_parser(argv)
-
- @options.trace_opts = validate_trace(@trace)
- @options.report_opts = validate_report(@report)
- @options.grammar_file = argv.shift
-
- if !@options.grammar_file
- abort "File should be specified\n"
- end
-
- if @options.grammar_file == '-'
- @options.grammar_file = argv.shift or abort "File name for STDIN should be specified\n"
- else
- @options.y = File.open(@options.grammar_file, 'r')
- end
-
- if !@report.empty? && @options.report_file.nil? && @options.grammar_file
- @options.report_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".output"
- end
-
- if !@options.header_file && @options.header
- case
- when @options.outfile
- @options.header_file = File.dirname(@options.outfile) + "/" + File.basename(@options.outfile, ".*") + ".h"
- when @options.grammar_file
- @options.header_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".h"
- end
- end
-
- @options
- end
-
- private
-
- def parse_by_option_parser(argv)
- ::OptionParser.new do |o|
- o.banner = <<~BANNER
- Lrama is LALR (1) parser generator written by Ruby.
-
- Usage: lrama [options] FILE
- BANNER
- o.separator ''
- o.separator 'STDIN mode:'
- o.separator 'lrama [options] - FILE read grammar from STDIN'
- o.separator ''
- o.separator 'Tuning the Parser:'
- o.on('-S', '--skeleton=FILE', 'specify the skeleton to use') {|v| @options.skeleton = v }
- o.on('-t', 'reserved, do nothing') { }
- o.on('--debug', 'display debugging outputs of internal parser') {|v| @options.debug = true }
- o.separator ''
- o.separator 'Output:'
- o.on('-H', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v }
- o.on('-d', 'also produce a header file') { @options.header = true }
- o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v }
- o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v }
- o.on('-o', '--output=FILE', 'leave output to FILE') {|v| @options.outfile = v }
- o.on('--trace=THINGS', Array, 'also output trace logs at runtime') {|v| @trace = v }
- o.on('-v', 'reserved, do nothing') { }
- o.separator ''
- o.separator 'Error Recovery:'
- o.on('-e', 'enable error recovery') {|v| @options.error_recovery = true }
- o.separator ''
- o.separator 'Other options:'
- o.on('-V', '--version', "output version information and exit") {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
- o.on('-h', '--help', "display this help and exit") {|v| puts o; exit 0 }
- o.separator ''
- o.parse!(argv)
- end
- end
-
- def validate_report(report)
- bison_list = %w[states itemsets lookaheads solved counterexamples cex all none]
- others = %w[verbose]
- list = bison_list + others
- not_supported = %w[cex none]
- h = { grammar: true }
-
- report.each do |r|
- if list.include?(r) && !not_supported.include?(r)
- h[r.to_sym] = true
- else
- raise "Invalid report option \"#{r}\"."
- end
- end
-
- if h[:all]
- (bison_list - not_supported).each do |r|
- h[r.to_sym] = true
- end
-
- h.delete(:all)
- end
-
- return h
- end
-
- def validate_trace(trace)
- list = %w[
- none locations scan parse automaton bitsets
- closure grammar rules resource sets muscles tools
- m4-early m4 skeleton time ielr cex all
- ]
- h = {}
-
- trace.each do |t|
- if list.include?(t)
- h[t.to_sym] = true
- else
- raise "Invalid trace option \"#{t}\"."
- end
- end
-
- return h
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/options.rb b/tool/lrama/lib/lrama/options.rb
deleted file mode 100644
index e63679bcf2..0000000000
--- a/tool/lrama/lib/lrama/options.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module Lrama
- # Command line options.
- class Options
- attr_accessor :skeleton, :header, :header_file,
- :report_file, :outfile,
- :error_recovery, :grammar_file,
- :trace_opts, :report_opts, :y,
- :debug
-
- def initialize
- @skeleton = "bison/yacc.c"
- @header = false
- @header_file = nil
- @report_file = nil
- @outfile = "y.tab.c"
- @error_recovery = false
- @grammar_file = nil
- @trace_opts = nil
- @report_opts = nil
- @y = STDIN
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/output.rb b/tool/lrama/lib/lrama/output.rb
deleted file mode 100644
index f672085097..0000000000
--- a/tool/lrama/lib/lrama/output.rb
+++ /dev/null
@@ -1,417 +0,0 @@
-require "erb"
-require "forwardable"
-require "lrama/report/duration"
-
-module Lrama
- class Output
- extend Forwardable
- include Report::Duration
-
- attr_reader :grammar_file_path, :context, :grammar, :error_recovery, :include_header
-
- def_delegators "@context", :yyfinal, :yylast, :yyntokens, :yynnts, :yynrules, :yynstates,
- :yymaxutok, :yypact_ninf, :yytable_ninf
-
- def_delegators "@grammar", :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol
-
- def initialize(
- out:, output_file_path:, template_name:, grammar_file_path:,
- header_out: nil, header_file_path: nil,
- context:, grammar:, error_recovery: false
- )
- @out = out
- @output_file_path = output_file_path
- @template_name = template_name
- @grammar_file_path = grammar_file_path
- @header_out = header_out
- @header_file_path = header_file_path
- @context = context
- @grammar = grammar
- @error_recovery = error_recovery
- @include_header = header_file_path ? header_file_path.sub("./", "") : nil
- end
-
- if ERB.instance_method(:initialize).parameters.last.first == :key
- def self.erb(input)
- ERB.new(input, trim_mode: '-')
- end
- else
- def self.erb(input)
- ERB.new(input, nil, '-')
- end
- end
-
- def render_partial(file)
- render_template(partial_file(file))
- end
-
- def render
- report_duration(:render) do
- tmp = eval_template(template_file, @output_file_path)
- @out << tmp
-
- if @header_file_path
- tmp = eval_template(header_template_file, @header_file_path)
-
- if @header_out
- @header_out << tmp
- else
- File.write(@header_file_path, tmp)
- end
- end
- end
- end
-
- # A part of b4_token_enums
- def token_enums
- str = ""
-
- @context.yytokentype.each do |s_value, token_id, display_name|
- s = sprintf("%s = %d%s", s_value, token_id, token_id == yymaxutok ? "" : ",")
-
- if display_name
- str << sprintf(" %-30s /* %s */\n", s, display_name)
- else
- str << sprintf(" %s\n", s)
- end
- end
-
- str
- end
-
- # b4_symbol_enum
- def symbol_enum
- str = ""
-
- last_sym_number = @context.yysymbol_kind_t.last[1]
- @context.yysymbol_kind_t.each do |s_value, sym_number, display_name|
- s = sprintf("%s = %d%s", s_value, sym_number, (sym_number == last_sym_number) ? "" : ",")
-
- if display_name
- str << sprintf(" %-40s /* %s */\n", s, display_name)
- else
- str << sprintf(" %s\n", s)
- end
- end
-
- str
- end
-
- def yytranslate
- int_array_to_string(@context.yytranslate)
- end
-
- def yytranslate_inverted
- int_array_to_string(@context.yytranslate_inverted)
- end
-
- def yyrline
- int_array_to_string(@context.yyrline)
- end
-
- def yytname
- string_array_to_string(@context.yytname) + " YY_NULLPTR"
- end
-
- # b4_int_type_for
- def int_type_for(ary)
- min = ary.min
- max = ary.max
-
- case
- when (-127 <= min && min <= 127) && (-127 <= max && max <= 127)
- "yytype_int8"
- when (0 <= min && min <= 255) && (0 <= max && max <= 255)
- "yytype_uint8"
- when (-32767 <= min && min <= 32767) && (-32767 <= max && max <= 32767)
- "yytype_int16"
- when (0 <= min && min <= 65535) && (0 <= max && max <= 65535)
- "yytype_uint16"
- else
- "int"
- end
- end
-
- def symbol_actions_for_printer
- str = ""
-
- @grammar.symbols.each do |sym|
- next unless sym.printer
-
- str << <<-STR
- case #{sym.enum_name}: /* #{sym.comment} */
-#line #{sym.printer.lineno} "#{@grammar_file_path}"
- {#{sym.printer.translated_code(sym.tag)}}
-#line [@oline@] [@ofile@]
- break;
-
- STR
- end
-
- str
- end
-
- # b4_user_initial_action
- def user_initial_action(comment = "")
- return "" unless @grammar.initial_action
-
- <<-STR
- #{comment}
-#line #{@grammar.initial_action.line} "#{@grammar_file_path}"
- {#{@grammar.initial_action.translated_code}}
- STR
- end
-
- def symbol_actions_for_error_token
- str = ""
-
- @grammar.symbols.each do |sym|
- next unless sym.error_token
-
- str << <<-STR
- case #{sym.enum_name}: /* #{sym.comment} */
-#line #{sym.error_token.lineno} "#{@grammar_file_path}"
- {#{sym.error_token.translated_code(sym.tag)}}
-#line [@oline@] [@ofile@]
- break;
-
- STR
- end
-
- str
- end
-
- # b4_user_actions
- def user_actions
- str = ""
-
- @context.states.rules.each do |rule|
- next unless rule.token_code
-
- code = rule.token_code
- spaces = " " * (code.column - 1)
-
- str << <<-STR
- case #{rule.id + 1}: /* #{rule.as_comment} */
-#line #{code.line} "#{@grammar_file_path}"
-#{spaces}{#{rule.translated_code}}
-#line [@oline@] [@ofile@]
- break;
-
- STR
- end
-
- str << <<-STR
-
-#line [@oline@] [@ofile@]
- STR
-
- str
- end
-
- def omit_blanks(param)
- param.strip
- end
-
- # b4_parse_param
- def parse_param
- if @grammar.parse_param
- omit_blanks(@grammar.parse_param)
- else
- ""
- end
- end
-
- def lex_param
- if @grammar.lex_param
- omit_blanks(@grammar.lex_param)
- else
- ""
- end
- end
-
- # b4_user_formals
- def user_formals
- if @grammar.parse_param
- ", #{parse_param}"
- else
- ""
- end
- end
-
- # b4_user_args
- def user_args
- if @grammar.parse_param
- ", #{parse_param_name}"
- else
- ""
- end
- end
-
- def extract_param_name(param)
- param[/\b([a-zA-Z0-9_]+)(?=\s*\z)/]
- end
-
- def parse_param_name
- if @grammar.parse_param
- extract_param_name(parse_param)
- else
- ""
- end
- end
-
- def lex_param_name
- if @grammar.lex_param
- extract_param_name(lex_param)
- else
- ""
- end
- end
-
- # b4_parse_param_use
- def parse_param_use(val, loc)
- str = <<-STR
- YY_USE (#{val});
- YY_USE (#{loc});
- STR
-
- if @grammar.parse_param
- str << " YY_USE (#{parse_param_name});"
- end
-
- str
- end
-
- # b4_yylex_formals
- def yylex_formals
- ary = ["&yylval", "&yylloc"]
-
- if @grammar.lex_param
- ary << lex_param_name
- end
-
- "(#{ary.join(', ')})"
- end
-
- # b4_table_value_equals
- def table_value_equals(table, value, literal, symbol)
- if literal < table.min || table.max < literal
- "0"
- else
- "((#{value}) == #{symbol})"
- end
- end
-
- # b4_yyerror_args
- def yyerror_args
- ary = ["&yylloc"]
-
- if @grammar.parse_param
- ary << parse_param_name
- end
-
- "#{ary.join(', ')}"
- end
-
- def template_basename
- File.basename(template_file)
- end
-
- def aux
- @grammar.aux
- end
-
- def int_array_to_string(ary)
- last = ary.count - 1
-
- s = ary.each_with_index.each_slice(10).map do |slice|
- str = " "
-
- slice.each do |e, i|
- str << sprintf("%6d%s", e, (i == last) ? "" : ",")
- end
-
- str
- end
-
- s.join("\n")
- end
-
- def spec_mapped_header_file
- @header_file_path
- end
-
- def b4_cpp_guard__b4_spec_mapped_header_file
- if @header_file_path
- "YY_YY_" + @header_file_path.gsub(/[^a-zA-Z_0-9]+/, "_").upcase + "_INCLUDED"
- else
- ""
- end
- end
-
- # b4_percent_code_get
- def percent_code(name)
- @grammar.percent_codes.select do |percent_code|
- percent_code.id.s_value == name
- end.map do |percent_code|
- percent_code.code.s_value
- end.join
- end
-
- private
-
- def eval_template(file, path)
- tmp = render_template(file)
- replace_special_variables(tmp, path)
- end
-
- def render_template(file)
- erb = self.class.erb(File.read(file))
- erb.filename = file
- erb.result_with_hash(context: @context, output: self)
- end
-
- def template_file
- File.join(template_dir, @template_name)
- end
-
- def header_template_file
- File.join(template_dir, "bison/yacc.h")
- end
-
- def partial_file(file)
- File.join(template_dir, file)
- end
-
- def template_dir
- File.expand_path("../../../template", __FILE__)
- end
-
- def string_array_to_string(ary)
- str = ""
- tmp = " "
-
- ary.each do |s|
- s = s.gsub('\\', '\\\\\\\\')
- s = s.gsub('"', '\\"')
-
- if (tmp + s + " \"\",").length > 75
- str << tmp << "\n"
- tmp = " \"#{s}\","
- else
- tmp << " \"#{s}\","
- end
- end
-
- str << tmp
- end
-
- def replace_special_variables(str, ofile)
- str.each_line.with_index(1).map do |line, i|
- line.gsub!("[@oline@]", (i + 1).to_s)
- line.gsub!("[@ofile@]", "\"#{ofile}\"")
- line
- end.join
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/parser.rb b/tool/lrama/lib/lrama/parser.rb
deleted file mode 100644
index bde7179ad0..0000000000
--- a/tool/lrama/lib/lrama/parser.rb
+++ /dev/null
@@ -1,1934 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.7.3
-# from Racc grammar file "parser.y".
-#
-
-###### racc/parser.rb begin
-unless $".find {|p| p.end_with?('/racc/parser.rb')}
-$".push "#{__dir__}/racc/parser.rb"
-self.class.module_eval(<<'...end racc/parser.rb/module_eval...', 'racc/parser.rb', 1)
-#--
-# Copyright (c) 1999-2006 Minero Aoki
-#
-# This program is free software.
-# You can distribute/modify this program under the same terms of ruby.
-#
-# As a special exception, when this code is copied by Racc
-# into a Racc output file, you may use that output file
-# without restriction.
-#++
-
-unless $".find {|p| p.end_with?('/racc/info.rb')}
-$".push "#{__dir__}/racc/info.rb"
-
-module Racc
- VERSION = '1.7.3'
- Version = VERSION
- Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
-end
-
-end
-
-
-unless defined?(NotImplementedError)
- NotImplementedError = NotImplementError # :nodoc:
-end
-
-module Racc
- class ParseError < StandardError; end
-end
-unless defined?(::ParseError)
- ParseError = Racc::ParseError # :nodoc:
-end
-
-# Racc is a LALR(1) parser generator.
-# It is written in Ruby itself, and generates Ruby programs.
-#
-# == Command-line Reference
-#
-# racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
-# [-e<var>rubypath</var>] [--executable=<var>rubypath</var>]
-# [-v] [--verbose]
-# [-O<var>filename</var>] [--log-file=<var>filename</var>]
-# [-g] [--debug]
-# [-E] [--embedded]
-# [-l] [--no-line-convert]
-# [-c] [--line-convert-all]
-# [-a] [--no-omit-actions]
-# [-C] [--check-only]
-# [-S] [--output-status]
-# [--version] [--copyright] [--help] <var>grammarfile</var>
-#
-# [+grammarfile+]
-# Racc grammar file. Any extension is permitted.
-# [-o+outfile+, --output-file=+outfile+]
-# A filename for output. default is <+filename+>.tab.rb
-# [-O+filename+, --log-file=+filename+]
-# Place logging output in file +filename+.
-# Default log file name is <+filename+>.output.
-# [-e+rubypath+, --executable=+rubypath+]
-# output executable file(mode 755). where +path+ is the Ruby interpreter.
-# [-v, --verbose]
-# verbose mode. create +filename+.output file, like yacc's y.output file.
-# [-g, --debug]
-# add debug code to parser class. To display debugging information,
-# use this '-g' option and set @yydebug true in parser class.
-# [-E, --embedded]
-# Output parser which doesn't need runtime files (racc/parser.rb).
-# [-F, --frozen]
-# Output parser which declares frozen_string_literals: true
-# [-C, --check-only]
-# Check syntax of racc grammar file and quit.
-# [-S, --output-status]
-# Print messages time to time while compiling.
-# [-l, --no-line-convert]
-# turns off line number converting.
-# [-c, --line-convert-all]
-# Convert line number of actions, inner, header and footer.
-# [-a, --no-omit-actions]
-# Call all actions, even if an action is empty.
-# [--version]
-# print Racc version and quit.
-# [--copyright]
-# Print copyright and quit.
-# [--help]
-# Print usage and quit.
-#
-# == Generating Parser Using Racc
-#
-# To compile Racc grammar file, simply type:
-#
-# $ racc parse.y
-#
-# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
-#
-# == Writing A Racc Grammar File
-#
-# If you want your own parser, you have to write a grammar file.
-# A grammar file contains the name of your parser class, grammar for the parser,
-# user code, and anything else.
-# When writing a grammar file, yacc's knowledge is helpful.
-# If you have not used yacc before, Racc is not too difficult.
-#
-# Here's an example Racc grammar file.
-#
-# class Calcparser
-# rule
-# target: exp { print val[0] }
-#
-# exp: exp '+' exp
-# | exp '*' exp
-# | '(' exp ')'
-# | NUMBER
-# end
-#
-# Racc grammar files resemble yacc files.
-# But (of course), this is Ruby code.
-# yacc's $$ is the 'result', $0, $1... is
-# an array called 'val', and $-1, $-2... is an array called '_values'.
-#
-# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
-# more information on grammar files.
-#
-# == Parser
-#
-# Then you must prepare the parse entry method. There are two types of
-# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
-#
-# Racc::Parser#do_parse is simple.
-#
-# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
-# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
-# EOF is [false, false].
-# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
-# If you want to change this, see the grammar reference.
-#
-# Racc::Parser#yyparse is little complicated, but useful.
-# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
-#
-# For example, <code>yyparse(obj, :scan)</code> causes
-# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
-#
-# == Debugging
-#
-# When debugging, "-v" or/and the "-g" option is helpful.
-#
-# "-v" creates verbose log file (.output).
-# "-g" creates a "Verbose Parser".
-# Verbose Parser prints the internal status when parsing.
-# But it's _not_ automatic.
-# You must use -g option and set +@yydebug+ to +true+ in order to get output.
-# -g option only creates the verbose parser.
-#
-# === Racc reported syntax error.
-#
-# Isn't there too many "end"?
-# grammar of racc file is changed in v0.10.
-#
-# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
-#
-# === Racc reported "XXXX conflicts".
-#
-# Try "racc -v xxxx.y".
-# It causes producing racc's internal log file, xxxx.output.
-#
-# === Generated parsers does not work correctly
-#
-# Try "racc -g xxxx.y".
-# This command let racc generate "debugging parser".
-# Then set @yydebug=true in your parser.
-# It produces a working log of your parser.
-#
-# == Re-distributing Racc runtime
-#
-# A parser, which is created by Racc, requires the Racc runtime module;
-# racc/parser.rb.
-#
-# Ruby 1.8.x comes with Racc runtime module,
-# you need NOT distribute Racc runtime files.
-#
-# If you want to include the Racc runtime module with your parser.
-# This can be done by using '-E' option:
-#
-# $ racc -E -omyparser.rb myparser.y
-#
-# This command creates myparser.rb which `includes' Racc runtime.
-# Only you must do is to distribute your parser file (myparser.rb).
-#
-# Note: parser.rb is ruby license, but your parser is not.
-# Your own parser is completely yours.
-module Racc
-
- unless defined?(Racc_No_Extensions)
- Racc_No_Extensions = false # :nodoc:
- end
-
- class Parser
-
- Racc_Runtime_Version = ::Racc::VERSION
- Racc_Runtime_Core_Version_R = ::Racc::VERSION
-
- begin
- if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
- require 'jruby'
- require 'racc/cparse-jruby.jar'
- com.headius.racc.Cparse.new.load(JRuby.runtime, false)
- else
- require 'racc/cparse'
- end
-
- unless new.respond_to?(:_racc_do_parse_c, true)
- raise LoadError, 'old cparse.so'
- end
- if Racc_No_Extensions
- raise LoadError, 'selecting ruby version of racc runtime core'
- end
-
- Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc:
- Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc:
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc:
- Racc_Runtime_Type = 'c' # :nodoc:
- rescue LoadError
- Racc_Main_Parsing_Routine = :_racc_do_parse_rb
- Racc_YY_Parse_Method = :_racc_yyparse_rb
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
- Racc_Runtime_Type = 'ruby'
- end
-
- def Parser.racc_runtime_type # :nodoc:
- Racc_Runtime_Type
- end
-
- def _racc_setup
- @yydebug = false unless self.class::Racc_debug_parser
- @yydebug = false unless defined?(@yydebug)
- if @yydebug
- @racc_debug_out = $stderr unless defined?(@racc_debug_out)
- @racc_debug_out ||= $stderr
- end
- arg = self.class::Racc_arg
- arg[13] = true if arg.size < 14
- arg
- end
-
- def _racc_init_sysvars
- @racc_state = [0]
- @racc_tstack = []
- @racc_vstack = []
-
- @racc_t = nil
- @racc_val = nil
-
- @racc_read_next = true
-
- @racc_user_yyerror = false
- @racc_error_status = 0
- end
-
- # The entry point of the parser. This method is used with #next_token.
- # If Racc wants to get token (and its value), calls next_token.
- #
- # Example:
- # def parse
- # @q = [[1,1],
- # [2,2],
- # [3,3],
- # [false, '$']]
- # do_parse
- # end
- #
- # def next_token
- # @q.shift
- # end
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
- def do_parse
- #{Racc_Main_Parsing_Routine}(_racc_setup(), false)
- end
- RUBY
-
- # The method to fetch next token.
- # If you use #do_parse method, you must implement #next_token.
- #
- # The format of return value is [TOKEN_SYMBOL, VALUE].
- # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
- # for 'IDENT'. ";" (String) for ';'.
- #
- # The final symbol (End of file) must be false.
- def next_token
- raise NotImplementedError, "#{self.class}\#next_token is not defined"
- end
-
- def _racc_do_parse_rb(arg, in_debug)
- action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, * = arg
-
- _racc_init_sysvars
- tok = act = i = nil
-
- catch(:racc_end_parse) {
- while true
- if i = action_pointer[@racc_state[-1]]
- if @racc_read_next
- if @racc_t != 0 # not EOF
- tok, @racc_val = next_token()
- unless tok # EOF
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- racc_read_token(@racc_t, tok, @racc_val) if @yydebug
- @racc_read_next = false
- end
- end
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- else
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- }
- end
-
- # Another entry point for the parser.
- # If you use this method, you must implement RECEIVER#METHOD_ID method.
- #
- # RECEIVER#METHOD_ID is a method to get next token.
- # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
- def yyparse(recv, mid)
- #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false)
- end
- RUBY
-
- def _racc_yyparse_rb(recv, mid, arg, c_debug)
- action_table, action_check, action_default, action_pointer,
- _, _, _, _,
- _, _, token_table, * = arg
-
- _racc_init_sysvars
-
- catch(:racc_end_parse) {
- until i = action_pointer[@racc_state[-1]]
- while act = _racc_evalact(action_default[@racc_state[-1]], arg)
- ;
- end
- end
- recv.__send__(mid) do |tok, val|
- unless tok
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- @racc_val = val
- @racc_read_next = false
-
- i += @racc_t
- unless i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
-
- while !(i = action_pointer[@racc_state[-1]]) ||
- ! @racc_read_next ||
- @racc_t == 0 # $
- unless i and i += @racc_t and
- i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- ;
- end
- end
- end
- }
- end
-
- ###
- ### common
- ###
-
- def _racc_evalact(act, arg)
- action_table, action_check, _, action_pointer,
- _, _, _, _,
- _, _, _, shift_n,
- reduce_n, * = arg
- nerr = 0 # tmp
-
- if act > 0 and act < shift_n
- #
- # shift
- #
- if @racc_error_status > 0
- @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
- end
- @racc_vstack.push @racc_val
- @racc_state.push act
- @racc_read_next = true
- if @yydebug
- @racc_tstack.push @racc_t
- racc_shift @racc_t, @racc_tstack, @racc_vstack
- end
-
- elsif act < 0 and act > -reduce_n
- #
- # reduce
- #
- code = catch(:racc_jump) {
- @racc_state.push _racc_do_reduce(arg, act)
- false
- }
- if code
- case code
- when 1 # yyerror
- @racc_user_yyerror = true # user_yyerror
- return -reduce_n
- when 2 # yyaccept
- return shift_n
- else
- raise '[Racc Bug] unknown jump code'
- end
- end
-
- elsif act == shift_n
- #
- # accept
- #
- racc_accept if @yydebug
- throw :racc_end_parse, @racc_vstack[0]
-
- elsif act == -reduce_n
- #
- # error
- #
- case @racc_error_status
- when 0
- unless arg[21] # user_yyerror
- nerr += 1
- on_error @racc_t, @racc_val, @racc_vstack
- end
- when 3
- if @racc_t == 0 # is $
- # We're at EOF, and another error occurred immediately after
- # attempting auto-recovery
- throw :racc_end_parse, nil
- end
- @racc_read_next = true
- end
- @racc_user_yyerror = false
- @racc_error_status = 3
- while true
- if i = action_pointer[@racc_state[-1]]
- i += 1 # error token
- if i >= 0 and
- (act = action_table[i]) and
- action_check[i] == @racc_state[-1]
- break
- end
- end
- throw :racc_end_parse, nil if @racc_state.size <= 1
- @racc_state.pop
- @racc_vstack.pop
- if @yydebug
- @racc_tstack.pop
- racc_e_pop @racc_state, @racc_tstack, @racc_vstack
- end
- end
- return act
-
- else
- raise "[Racc Bug] unknown action #{act.inspect}"
- end
-
- racc_next_state(@racc_state[-1], @racc_state) if @yydebug
-
- nil
- end
-
- def _racc_do_reduce(arg, act)
- _, _, _, _,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, _, _,
- _, use_result, * = arg
-
- state = @racc_state
- vstack = @racc_vstack
- tstack = @racc_tstack
-
- i = act * -3
- len = reduce_table[i]
- reduce_to = reduce_table[i+1]
- method_id = reduce_table[i+2]
- void_array = []
-
- tmp_t = tstack[-len, len] if @yydebug
- tmp_v = vstack[-len, len]
- tstack[-len, len] = void_array if @yydebug
- vstack[-len, len] = void_array
- state[-len, len] = void_array
-
- # tstack must be updated AFTER method call
- if use_result
- vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
- else
- vstack.push __send__(method_id, tmp_v, vstack)
- end
- tstack.push reduce_to
-
- racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
-
- k1 = reduce_to - nt_base
- if i = goto_pointer[k1]
- i += state[-1]
- if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
- return curstate
- end
- end
- goto_default[k1]
- end
-
- # This method is called when a parse error is found.
- #
- # ERROR_TOKEN_ID is an internal ID of token which caused error.
- # You can get string representation of this ID by calling
- # #token_to_str.
- #
- # ERROR_VALUE is a value of error token.
- #
- # value_stack is a stack of symbol values.
- # DO NOT MODIFY this object.
- #
- # This method raises ParseError by default.
- #
- # If this method returns, parsers enter "error recovering mode".
- def on_error(t, val, vstack)
- raise ParseError, sprintf("parse error on value %s (%s)",
- val.inspect, token_to_str(t) || '?')
- end
-
- # Enter error recovering mode.
- # This method does not call #on_error.
- def yyerror
- throw :racc_jump, 1
- end
-
- # Exit parser.
- # Return value is +Symbol_Value_Stack[0]+.
- def yyaccept
- throw :racc_jump, 2
- end
-
- # Leave error recovering mode.
- def yyerrok
- @racc_error_status = 0
- end
-
- # For debugging output
- def racc_read_token(t, tok, val)
- @racc_debug_out.print 'read '
- @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
- @racc_debug_out.puts val.inspect
- @racc_debug_out.puts
- end
-
- def racc_shift(tok, tstack, vstack)
- @racc_debug_out.puts "shift #{racc_token2str tok}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_reduce(toks, sim, tstack, vstack)
- out = @racc_debug_out
- out.print 'reduce '
- if toks.empty?
- out.print ' <none>'
- else
- toks.each {|t| out.print ' ', racc_token2str(t) }
- end
- out.puts " --> #{racc_token2str(sim)}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_accept
- @racc_debug_out.puts 'accept'
- @racc_debug_out.puts
- end
-
- def racc_e_pop(state, tstack, vstack)
- @racc_debug_out.puts 'error recovering mode: pop token'
- racc_print_states state
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_next_state(curstate, state)
- @racc_debug_out.puts "goto #{curstate}"
- racc_print_states state
- @racc_debug_out.puts
- end
-
- def racc_print_stacks(t, v)
- out = @racc_debug_out
- out.print ' ['
- t.each_index do |i|
- out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
- end
- out.puts ' ]'
- end
-
- def racc_print_states(s)
- out = @racc_debug_out
- out.print ' ['
- s.each {|st| out.print ' ', st }
- out.puts ' ]'
- end
-
- def racc_token2str(tok)
- self.class::Racc_token_to_s_table[tok] or
- raise "[Racc Bug] can't convert token #{tok} to string"
- end
-
- # Convert internal ID of token symbol to the string.
- def token_to_str(t)
- self.class::Racc_token_to_s_table[t]
- end
-
- end
-
-end
-
-...end racc/parser.rb/module_eval...
-end
-###### racc/parser.rb end
-module Lrama
- class Parser < Racc::Parser
-
-module_eval(<<'...end parser.y/module_eval...', 'parser.y', 420)
-
-include Lrama::Report::Duration
-
-def initialize(text, path, debug = false)
- @text = text
- @path = path
- @yydebug = debug
- @rule_counter = Lrama::Grammar::Counter.new(0)
- @midrule_action_counter = Lrama::Grammar::Counter.new(1)
-end
-
-def parse
- report_duration(:parse) do
- @lexer = Lrama::Lexer.new(@text)
- @grammar = Lrama::Grammar.new(@rule_counter)
- @precedence_number = 0
- reset_precs
- do_parse
- @grammar.prepare
- @grammar.validate!
- @grammar
- end
-end
-
-def next_token
- @lexer.next_token
-end
-
-def on_error(error_token_id, error_value, value_stack)
- if error_value.is_a?(Lrama::Lexer::Token)
- line = error_value.first_line
- first_column = error_value.first_column
- last_column = error_value.last_column
- value = "'#{error_value.s_value}'"
- else
- line = @lexer.line
- first_column = @lexer.head_column
- last_column = @lexer.column
- value = error_value.inspect
- end
-
- raise ParseError, <<~ERROR
- #{@path}:#{line}:#{first_column}: parse error on value #{value} (#{token_to_str(error_token_id) || '?'})
- #{@text.split("\n")[line - 1]}
- #{carrets(first_column, last_column)}
- ERROR
-end
-
-def on_action_error(error_message, error_value)
- if error_value.is_a?(Lrama::Lexer::Token)
- line = error_value.first_line
- first_column = error_value.first_column
- last_column = error_value.last_column
- else
- line = @lexer.line
- first_column = @lexer.head_column
- last_column = @lexer.column
- end
-
- raise ParseError, <<~ERROR
- #{@path}:#{line}: #{error_message}
- #{@text.split("\n")[line - 1]}
- #{carrets(first_column, last_column)}
- ERROR
-end
-
-private
-
-def reset_precs
- @prec_seen = false
- @code_after_prec = false
-end
-
-def begin_c_declaration(end_symbol)
- @lexer.status = :c_declaration
- @lexer.end_symbol = end_symbol
-end
-
-def end_c_declaration
- @lexer.status = :initial
- @lexer.end_symbol = nil
-end
-
-def carrets(first_column, last_column)
- ' ' * (first_column + 1) + '^' * (last_column - first_column)
-end
-...end parser.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 82, 42, 83, 137, 42, 65, 137, 38, 65, 136,
- 42, 6, 41, 7, 42, 56, 41, 139, 65, 61,
- 139, 135, 42, 42, 41, 41, 20, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 140, 38, 3, 140,
- 84, 42, 77, 41, 8, 42, 68, 41, 172, 42,
- 68, 41, 32, 173, 68, 39, 20, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 9, 42, 45, 41,
- 12, 13, 14, 15, 16, 17, 45, 45, 18, 19,
- 20, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 42, 48, 41, 151, 49, 68, 152, 153, 154, 42,
- 42, 41, 41, 65, 163, 42, 42, 41, 41, 65,
- 163, 42, 42, 41, 41, 65, 163, 42, 42, 41,
- 41, 65, 163, 42, 42, 41, 41, 65, 163, 42,
- 42, 41, 41, 65, 163, 42, 42, 41, 41, 65,
- 65, 42, 42, 41, 41, 65, 65, 42, 42, 41,
- 41, 65, 65, 42, 42, 41, 41, 65, 65, 42,
- 42, 41, 41, 50, 51, 52, 53, 74, 78, 80,
- 85, 85, 85, 87, 93, 97, 98, 101, 101, 101,
- 101, 106, 107, 109, 111, 112, 113, 114, 115, 118,
- 121, 122, 125, 126, 127, 129, 142, 144, 145, 146,
- 147, 148, 125, 80, 158, 159, 167, 170, 167, 177,
- 80 ]
-
-racc_action_check = [
- 40, 124, 40, 124, 149, 124, 149, 9, 149, 123,
- 25, 2, 25, 2, 26, 25, 26, 124, 26, 26,
- 149, 123, 13, 55, 13, 55, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 124, 33, 1, 149,
- 40, 27, 33, 27, 3, 28, 27, 28, 168, 29,
- 28, 29, 7, 168, 29, 12, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 4, 56, 14, 56,
- 4, 4, 4, 4, 4, 4, 15, 16, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 30, 17, 30, 137, 18, 30, 137, 137, 137, 146,
- 67, 146, 67, 146, 146, 147, 68, 147, 68, 147,
- 147, 148, 93, 148, 93, 148, 148, 160, 95, 160,
- 95, 160, 160, 164, 101, 164, 101, 164, 164, 165,
- 103, 165, 103, 165, 165, 60, 61, 60, 61, 60,
- 61, 98, 100, 98, 100, 98, 100, 119, 140, 119,
- 140, 119, 140, 151, 173, 151, 173, 151, 173, 116,
- 120, 116, 120, 20, 22, 23, 24, 31, 36, 37,
- 44, 46, 47, 48, 54, 58, 59, 66, 71, 72,
- 73, 79, 80, 86, 88, 89, 90, 91, 92, 96,
- 104, 105, 106, 107, 108, 110, 128, 130, 131, 132,
- 133, 134, 135, 138, 141, 143, 150, 156, 172, 174,
- 177 ]
-
-racc_action_pointer = [
- nil, 38, 1, 44, 57, nil, nil, 45, nil, 3,
- nil, nil, 49, 19, 49, 57, 58, 86, 75, nil,
- 144, nil, 145, 146, 147, 7, 11, 38, 42, 46,
- 87, 165, nil, 33, nil, nil, 146, 126, nil, nil,
- -5, nil, nil, nil, 151, nil, 152, 153, 154, nil,
- nil, nil, nil, nil, 166, 20, 64, nil, 169, 168,
- 132, 133, nil, nil, nil, nil, 169, 97, 103, nil,
- nil, 170, 171, 172, nil, nil, nil, nil, nil, 148,
- 177, nil, nil, nil, nil, nil, 181, nil, 182, 183,
- 184, 185, 186, 109, nil, 115, 182, nil, 138, nil,
- 139, 121, nil, 127, 179, 189, 157, 149, 192, nil,
- 193, nil, nil, nil, nil, nil, 156, nil, nil, 144,
- 157, nil, nil, -13, -2, nil, nil, nil, 176, nil,
- 177, 178, 179, 180, 181, 167, nil, 57, 160, nil,
- 145, 184, nil, 185, nil, nil, 96, 102, 108, 1,
- 198, 150, nil, nil, nil, nil, 205, nil, nil, nil,
- 114, nil, nil, nil, 120, 126, nil, nil, 11, nil,
- nil, nil, 200, 151, 189, nil, nil, 167, nil ]
-
-racc_action_default = [
- -2, -113, -8, -113, -113, -3, -4, -113, 179, -113,
- -9, -10, -113, -113, -113, -113, -113, -113, -113, -22,
- -113, -26, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -7, -98, -73, -75, -113, -95, -97, -11,
- -102, -71, -72, -101, -13, -62, -14, -15, -113, -19,
- -23, -27, -30, -33, -36, -42, -113, -45, -48, -37,
- -52, -113, -55, -57, -58, -110, -38, -65, -113, -68,
- -70, -39, -40, -41, -5, -1, -74, -99, -76, -113,
- -113, -12, -103, -104, -105, -59, -113, -16, -113, -113,
- -113, -113, -113, -113, -46, -43, -50, -49, -113, -56,
- -53, -113, -69, -66, -113, -113, -81, -113, -113, -63,
- -113, -20, -24, -28, -31, -34, -44, -47, -51, -54,
- -67, -6, -100, -77, -78, -82, -96, -60, -113, -17,
- -113, -113, -113, -113, -113, -81, -80, -71, -95, -86,
- -113, -113, -64, -113, -21, -25, -113, -113, -113, -79,
- -111, -113, -90, -91, -92, -83, -113, -89, -61, -18,
- -29, -106, -108, -109, -32, -35, -84, -112, -113, -93,
- -87, -107, -111, -113, -113, -85, -94, -95, -88 ]
-
-racc_goto_table = [
- 62, 79, 43, 60, 103, 55, 94, 102, 34, 166,
- 124, 44, 46, 47, 58, 1, 70, 70, 70, 70,
- 171, 160, 164, 165, 171, 171, 66, 71, 72, 73,
- 2, 175, 76, 4, 99, 62, 95, 120, 100, 149,
- 33, 75, 5, 102, 58, 58, 94, 31, 104, 10,
- 11, 40, 81, 110, 143, 88, 70, 70, 130, 89,
- 102, 131, 90, 132, 91, 133, 92, 94, 134, 54,
- 59, 96, 62, 116, 99, 119, 117, 108, 141, 86,
- 128, 123, 58, 150, 58, 168, 156, 174, 105, nil,
- 70, nil, 70, 99, nil, nil, nil, nil, 138, nil,
- nil, nil, 155, nil, nil, 58, nil, nil, nil, 70,
- nil, nil, nil, nil, 157, nil, nil, nil, nil, nil,
- nil, nil, nil, 138, nil, 169, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 178, nil, nil, nil, nil, nil, 176 ]
-
-racc_goto_check = [
- 37, 48, 33, 36, 43, 31, 32, 44, 45, 52,
- 50, 13, 13, 13, 33, 1, 33, 33, 33, 33,
- 57, 19, 19, 19, 57, 57, 30, 30, 30, 30,
- 2, 52, 45, 3, 37, 37, 31, 43, 36, 50,
- 4, 5, 6, 44, 33, 33, 32, 7, 8, 9,
- 10, 11, 12, 14, 15, 16, 33, 33, 17, 20,
- 44, 21, 22, 23, 24, 25, 26, 32, 27, 28,
- 29, 34, 37, 31, 37, 36, 35, 39, 40, 41,
- 42, 49, 33, 51, 33, 53, 54, 55, 56, nil,
- 33, nil, 33, 37, nil, nil, nil, nil, 37, nil,
- nil, nil, 48, nil, nil, 33, nil, nil, nil, 33,
- nil, nil, nil, nil, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, 37, nil, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 48, nil, nil, nil, nil, nil, 37 ]
-
-racc_goto_pointer = [
- nil, 15, 30, 31, 31, 8, 40, 41, -26, 45,
- 46, 38, 12, -3, -34, -75, 6, -53, nil, -125,
- 9, -51, 11, -50, 12, -49, 13, -47, 44, 44,
- -1, -20, -49, -11, 13, -20, -23, -26, nil, -8,
- -49, 34, -29, -64, -60, -1, nil, nil, -36, -25,
- -96, -54, -141, -66, -53, -83, 11, -140 ]
-
-racc_goto_default = [
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, nil, nil, nil, nil, nil, 21, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 57, 63, nil, nil, nil, 162, 64, nil,
- nil, nil, nil, 67, 69, nil, 35, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 161 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 5, 47, :_reduce_none,
- 0, 48, :_reduce_none,
- 2, 48, :_reduce_none,
- 0, 53, :_reduce_4,
- 0, 54, :_reduce_5,
- 5, 52, :_reduce_6,
- 2, 52, :_reduce_none,
- 0, 49, :_reduce_8,
- 2, 49, :_reduce_none,
- 1, 55, :_reduce_none,
- 2, 55, :_reduce_11,
- 3, 55, :_reduce_none,
- 2, 55, :_reduce_none,
- 2, 55, :_reduce_14,
- 2, 55, :_reduce_15,
- 0, 60, :_reduce_16,
- 0, 61, :_reduce_17,
- 7, 55, :_reduce_18,
- 0, 62, :_reduce_19,
- 0, 63, :_reduce_20,
- 6, 55, :_reduce_21,
- 1, 55, :_reduce_none,
- 0, 66, :_reduce_23,
- 0, 67, :_reduce_24,
- 6, 56, :_reduce_25,
- 1, 56, :_reduce_none,
- 0, 68, :_reduce_27,
- 0, 69, :_reduce_28,
- 7, 56, :_reduce_none,
- 0, 70, :_reduce_30,
- 0, 71, :_reduce_31,
- 7, 56, :_reduce_32,
- 0, 72, :_reduce_33,
- 0, 73, :_reduce_34,
- 7, 56, :_reduce_35,
- 2, 64, :_reduce_none,
- 2, 64, :_reduce_37,
- 2, 64, :_reduce_38,
- 2, 64, :_reduce_39,
- 2, 64, :_reduce_40,
- 2, 64, :_reduce_41,
- 1, 74, :_reduce_42,
- 2, 74, :_reduce_43,
- 3, 74, :_reduce_44,
- 1, 77, :_reduce_45,
- 2, 77, :_reduce_46,
- 3, 78, :_reduce_47,
- 0, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 0, 81, :_reduce_none,
- 1, 81, :_reduce_none,
- 1, 75, :_reduce_52,
- 2, 75, :_reduce_53,
- 3, 75, :_reduce_54,
- 1, 82, :_reduce_55,
- 2, 82, :_reduce_56,
- 1, 83, :_reduce_none,
- 1, 83, :_reduce_none,
- 0, 85, :_reduce_59,
- 0, 86, :_reduce_60,
- 6, 59, :_reduce_61,
- 0, 87, :_reduce_62,
- 0, 88, :_reduce_63,
- 5, 59, :_reduce_64,
- 1, 76, :_reduce_65,
- 2, 76, :_reduce_66,
- 3, 76, :_reduce_67,
- 1, 89, :_reduce_68,
- 2, 89, :_reduce_69,
- 1, 90, :_reduce_none,
- 1, 79, :_reduce_71,
- 1, 79, :_reduce_72,
- 1, 50, :_reduce_none,
- 2, 50, :_reduce_none,
- 1, 91, :_reduce_none,
- 2, 91, :_reduce_none,
- 4, 92, :_reduce_77,
- 1, 95, :_reduce_78,
- 3, 95, :_reduce_79,
- 2, 95, :_reduce_none,
- 0, 96, :_reduce_81,
- 1, 96, :_reduce_82,
- 3, 96, :_reduce_83,
- 4, 96, :_reduce_84,
- 6, 96, :_reduce_85,
- 0, 100, :_reduce_86,
- 0, 101, :_reduce_87,
- 7, 96, :_reduce_88,
- 3, 96, :_reduce_89,
- 1, 97, :_reduce_none,
- 1, 97, :_reduce_none,
- 1, 97, :_reduce_none,
- 1, 99, :_reduce_93,
- 3, 99, :_reduce_94,
- 0, 94, :_reduce_none,
- 3, 94, :_reduce_96,
- 1, 93, :_reduce_none,
- 0, 51, :_reduce_none,
- 0, 102, :_reduce_99,
- 3, 51, :_reduce_100,
- 1, 57, :_reduce_none,
- 0, 58, :_reduce_none,
- 1, 58, :_reduce_none,
- 1, 58, :_reduce_none,
- 1, 58, :_reduce_none,
- 1, 65, :_reduce_106,
- 2, 65, :_reduce_107,
- 1, 103, :_reduce_none,
- 1, 103, :_reduce_none,
- 1, 84, :_reduce_110,
- 0, 98, :_reduce_none,
- 1, 98, :_reduce_none ]
-
-racc_reduce_n = 113
-
-racc_shift_n = 179
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :C_DECLARATION => 2,
- :CHARACTER => 3,
- :IDENT_COLON => 4,
- :IDENTIFIER => 5,
- :INTEGER => 6,
- :STRING => 7,
- :TAG => 8,
- "%%" => 9,
- "%{" => 10,
- "%}" => 11,
- "%require" => 12,
- "%expect" => 13,
- "%define" => 14,
- "%param" => 15,
- "%lex-param" => 16,
- "%parse-param" => 17,
- "%code" => 18,
- "{" => 19,
- "}" => 20,
- "%initial-action" => 21,
- ";" => 22,
- "%union" => 23,
- "%destructor" => 24,
- "%printer" => 25,
- "%error-token" => 26,
- "%token" => 27,
- "%type" => 28,
- "%left" => 29,
- "%right" => 30,
- "%precedence" => 31,
- "%nonassoc" => 32,
- ":" => 33,
- "|" => 34,
- "%empty" => 35,
- "(" => 36,
- ")" => 37,
- "%prec" => 38,
- "?" => 39,
- "+" => 40,
- "*" => 41,
- "," => 42,
- "[" => 43,
- "]" => 44,
- "{...}" => 45 }
-
-racc_nt_base = 46
-
-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 ]
-Ractor.make_shareable(Racc_arg) if defined?(Ractor)
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "C_DECLARATION",
- "CHARACTER",
- "IDENT_COLON",
- "IDENTIFIER",
- "INTEGER",
- "STRING",
- "TAG",
- "\"%%\"",
- "\"%{\"",
- "\"%}\"",
- "\"%require\"",
- "\"%expect\"",
- "\"%define\"",
- "\"%param\"",
- "\"%lex-param\"",
- "\"%parse-param\"",
- "\"%code\"",
- "\"{\"",
- "\"}\"",
- "\"%initial-action\"",
- "\";\"",
- "\"%union\"",
- "\"%destructor\"",
- "\"%printer\"",
- "\"%error-token\"",
- "\"%token\"",
- "\"%type\"",
- "\"%left\"",
- "\"%right\"",
- "\"%precedence\"",
- "\"%nonassoc\"",
- "\":\"",
- "\"|\"",
- "\"%empty\"",
- "\"(\"",
- "\")\"",
- "\"%prec\"",
- "\"?\"",
- "\"+\"",
- "\"*\"",
- "\",\"",
- "\"[\"",
- "\"]\"",
- "\"{...}\"",
- "$start",
- "input",
- "prologue_declarations",
- "bison_declarations",
- "grammar",
- "epilogue_opt",
- "prologue_declaration",
- "@1",
- "@2",
- "bison_declaration",
- "grammar_declaration",
- "variable",
- "value",
- "params",
- "@3",
- "@4",
- "@5",
- "@6",
- "symbol_declaration",
- "generic_symlist",
- "@7",
- "@8",
- "@9",
- "@10",
- "@11",
- "@12",
- "@13",
- "@14",
- "token_declarations",
- "symbol_declarations",
- "token_declarations_for_precedence",
- "token_declaration_list",
- "token_declaration",
- "id",
- "int_opt",
- "alias",
- "symbol_declaration_list",
- "symbol",
- "string_as_id",
- "@15",
- "@16",
- "@17",
- "@18",
- "token_declaration_list_for_precedence",
- "token_declaration_for_precedence",
- "rules_or_grammar_declaration",
- "rules",
- "id_colon",
- "named_ref_opt",
- "rhs_list",
- "rhs",
- "parameterizing_suffix",
- "tag_opt",
- "parameterizing_args",
- "@19",
- "@20",
- "@21",
- "generic_symlist_item" ]
-Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
-
-Racc_debug_parser = true
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-# reduce 2 omitted
-
-# reduce 3 omitted
-
-module_eval(<<'.,.,', 'parser.y', 14)
- def _reduce_4(val, _values, result)
- begin_c_declaration("%}")
- @grammar.prologue_first_lineno = @lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 19)
- def _reduce_5(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 23)
- def _reduce_6(val, _values, result)
- @grammar.prologue = val[2].s_value
-
- result
- end
-.,.,
-
-# reduce 7 omitted
-
-module_eval(<<'.,.,', 'parser.y', 27)
- def _reduce_8(val, _values, result)
- result = ""
- result
- end
-.,.,
-
-# reduce 9 omitted
-
-# reduce 10 omitted
-
-module_eval(<<'.,.,', 'parser.y', 31)
- def _reduce_11(val, _values, result)
- @grammar.expect = val[1]
- result
- end
-.,.,
-
-# reduce 12 omitted
-
-# reduce 13 omitted
-
-module_eval(<<'.,.,', 'parser.y', 36)
- def _reduce_14(val, _values, result)
- val[1].each {|token|
- @grammar.lex_param = Grammar::Code::NoReferenceCode.new(type: :lex_param, token_code: token).token_code.s_value
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 42)
- def _reduce_15(val, _values, result)
- val[1].each {|token|
- @grammar.parse_param = Grammar::Code::NoReferenceCode.new(type: :parse_param, token_code: token).token_code.s_value
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 48)
- def _reduce_16(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 52)
- def _reduce_17(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 56)
- def _reduce_18(val, _values, result)
- @grammar.add_percent_code(id: val[1], code: val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 60)
- def _reduce_19(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 64)
- def _reduce_20(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 68)
- def _reduce_21(val, _values, result)
- @grammar.initial_action = Grammar::Code::InitialActionCode.new(type: :initial_action, token_code: val[3])
-
- result
- end
-.,.,
-
-# reduce 22 omitted
-
-module_eval(<<'.,.,', 'parser.y', 74)
- def _reduce_23(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 78)
- def _reduce_24(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 82)
- def _reduce_25(val, _values, result)
- @grammar.set_union(
- Grammar::Code::NoReferenceCode.new(type: :union, token_code: val[3]),
- val[3].line
- )
-
- result
- end
-.,.,
-
-# reduce 26 omitted
-
-module_eval(<<'.,.,', 'parser.y', 90)
- def _reduce_27(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 94)
- def _reduce_28(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-# reduce 29 omitted
-
-module_eval(<<'.,.,', 'parser.y', 99)
- def _reduce_30(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 103)
- def _reduce_31(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 107)
- def _reduce_32(val, _values, result)
- @grammar.add_printer(
- ident_or_tags: val[6],
- token_code: val[3],
- lineno: val[3].line
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 115)
- def _reduce_33(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 119)
- def _reduce_34(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 123)
- def _reduce_35(val, _values, result)
- @grammar.add_error_token(
- ident_or_tags: val[6],
- token_code: val[3],
- lineno: val[3].line
- )
-
- result
- end
-.,.,
-
-# reduce 36 omitted
-
-module_eval(<<'.,.,', 'parser.y', 133)
- def _reduce_37(val, _values, result)
- val[1].each {|hash|
- hash[:tokens].each {|id|
- @grammar.add_type(id: id, tag: hash[:tag])
- }
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 141)
- def _reduce_38(val, _values, result)
- val[1].each {|hash|
- hash[:tokens].each {|id|
- sym = @grammar.add_term(id: id)
- @grammar.add_left(sym, @precedence_number)
- }
- }
- @precedence_number += 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 151)
- def _reduce_39(val, _values, result)
- val[1].each {|hash|
- hash[:tokens].each {|id|
- sym = @grammar.add_term(id: id)
- @grammar.add_right(sym, @precedence_number)
- }
- }
- @precedence_number += 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 161)
- def _reduce_40(val, _values, result)
- val[1].each {|hash|
- hash[:tokens].each {|id|
- sym = @grammar.add_term(id: id)
- @grammar.add_precedence(sym, @precedence_number)
- }
- }
- @precedence_number += 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 171)
- def _reduce_41(val, _values, result)
- val[1].each {|hash|
- hash[:tokens].each {|id|
- sym = @grammar.add_term(id: id)
- @grammar.add_nonassoc(sym, @precedence_number)
- }
- }
- @precedence_number += 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 182)
- def _reduce_42(val, _values, result)
- val[0].each {|token_declaration|
- @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: nil, replace: true)
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 188)
- def _reduce_43(val, _values, result)
- val[1].each {|token_declaration|
- @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: val[0], replace: true)
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 194)
- def _reduce_44(val, _values, result)
- val[2].each {|token_declaration|
- @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: val[1], replace: true)
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 199)
- def _reduce_45(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 200)
- def _reduce_46(val, _values, result)
- result = val[0].append(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 202)
- def _reduce_47(val, _values, result)
- result = val
- result
- end
-.,.,
-
-# reduce 48 omitted
-
-# reduce 49 omitted
-
-# reduce 50 omitted
-
-# reduce 51 omitted
-
-module_eval(<<'.,.,', 'parser.y', 212)
- def _reduce_52(val, _values, result)
- result = [{tag: nil, tokens: val[0]}]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 216)
- def _reduce_53(val, _values, result)
- result = [{tag: val[0], tokens: val[1]}]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 220)
- def _reduce_54(val, _values, result)
- result = val[0].append({tag: val[1], tokens: val[2]})
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 223)
- def _reduce_55(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 224)
- def _reduce_56(val, _values, result)
- result = val[0].append(val[1])
- result
- end
-.,.,
-
-# reduce 57 omitted
-
-# reduce 58 omitted
-
-module_eval(<<'.,.,', 'parser.y', 231)
- def _reduce_59(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 235)
- def _reduce_60(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 239)
- def _reduce_61(val, _values, result)
- result = val[0].append(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 243)
- def _reduce_62(val, _values, result)
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 247)
- def _reduce_63(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 251)
- def _reduce_64(val, _values, result)
- result = [val[2]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 256)
- def _reduce_65(val, _values, result)
- result = [{tag: nil, tokens: val[0]}]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 260)
- def _reduce_66(val, _values, result)
- result = [{tag: val[0], tokens: val[1]}]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 264)
- def _reduce_67(val, _values, result)
- result = val[0].append({tag: val[1], tokens: val[2]})
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 267)
- def _reduce_68(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 268)
- def _reduce_69(val, _values, result)
- result = val[0].append(val[1])
- result
- end
-.,.,
-
-# reduce 70 omitted
-
-module_eval(<<'.,.,', 'parser.y', 272)
- def _reduce_71(val, _values, result)
- on_action_error("ident after %prec", val[0]) if @prec_seen
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 273)
- def _reduce_72(val, _values, result)
- on_action_error("char after %prec", val[0]) if @prec_seen
- result
- end
-.,.,
-
-# reduce 73 omitted
-
-# reduce 74 omitted
-
-# reduce 75 omitted
-
-# reduce 76 omitted
-
-module_eval(<<'.,.,', 'parser.y', 283)
- def _reduce_77(val, _values, result)
- lhs = val[0]
- lhs.alias_name = val[1]
- val[3].each do |builder|
- builder.lhs = lhs
- builder.complete_input
- @grammar.add_rule_builder(builder)
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 294)
- def _reduce_78(val, _values, result)
- builder = val[0]
- if !builder.line
- builder.line = @lexer.line - 1
- end
- result = [builder]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 302)
- def _reduce_79(val, _values, result)
- builder = val[2]
- if !builder.line
- builder.line = @lexer.line - 1
- end
- result = val[0].append(builder)
-
- result
- end
-.,.,
-
-# reduce 80 omitted
-
-module_eval(<<'.,.,', 'parser.y', 312)
- def _reduce_81(val, _values, result)
- reset_precs
- result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 317)
- def _reduce_82(val, _values, result)
- reset_precs
- result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 322)
- def _reduce_83(val, _values, result)
- token = val[1]
- token.alias_name = val[2]
- builder = val[0]
- builder.add_rhs(token)
- result = builder
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 330)
- def _reduce_84(val, _values, result)
- token = Lrama::Lexer::Token::Parameterizing.new(s_value: val[2], location: @lexer.location, args: [val[1]])
- builder = val[0]
- builder.add_rhs(token)
- builder.lhs_tag = val[3]
- builder.line = val[1].first_line
- result = builder
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 339)
- def _reduce_85(val, _values, result)
- token = Lrama::Lexer::Token::Parameterizing.new(s_value: val[1].s_value, location: @lexer.location, args: val[3])
- builder = val[0]
- builder.add_rhs(token)
- builder.lhs_tag = val[5]
- builder.line = val[1].first_line
- result = builder
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 348)
- def _reduce_86(val, _values, result)
- if @prec_seen
- on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec
- @code_after_prec = true
- end
- begin_c_declaration("}")
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 356)
- def _reduce_87(val, _values, result)
- end_c_declaration
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 360)
- def _reduce_88(val, _values, result)
- user_code = val[3]
- user_code.alias_name = val[6]
- builder = val[0]
- builder.user_code = user_code
- result = builder
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 368)
- def _reduce_89(val, _values, result)
- sym = @grammar.find_symbol_by_id!(val[2])
- @prec_seen = true
- builder = val[0]
- builder.precedence_sym = sym
- result = builder
-
- result
- end
-.,.,
-
-# reduce 90 omitted
-
-# reduce 91 omitted
-
-# reduce 92 omitted
-
-module_eval(<<'.,.,', 'parser.y', 379)
- def _reduce_93(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 380)
- def _reduce_94(val, _values, result)
- result = val[0].append(val[2])
- result
- end
-.,.,
-
-# reduce 95 omitted
-
-module_eval(<<'.,.,', 'parser.y', 383)
- def _reduce_96(val, _values, result)
- result = val[1].s_value
- result
- end
-.,.,
-
-# reduce 97 omitted
-
-# reduce 98 omitted
-
-module_eval(<<'.,.,', 'parser.y', 390)
- def _reduce_99(val, _values, result)
- begin_c_declaration('\Z')
- @grammar.epilogue_first_lineno = @lexer.line + 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 395)
- def _reduce_100(val, _values, result)
- end_c_declaration
- @grammar.epilogue = val[2].s_value
-
- result
- end
-.,.,
-
-# reduce 101 omitted
-
-# reduce 102 omitted
-
-# reduce 103 omitted
-
-# reduce 104 omitted
-
-# reduce 105 omitted
-
-module_eval(<<'.,.,', 'parser.y', 406)
- def _reduce_106(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'parser.y', 407)
- def _reduce_107(val, _values, result)
- result = val[0].append(val[1])
- result
- end
-.,.,
-
-# reduce 108 omitted
-
-# reduce 109 omitted
-
-module_eval(<<'.,.,', 'parser.y', 412)
- def _reduce_110(val, _values, result)
- result = Lrama::Lexer::Token::Ident.new(s_value: val[0])
- result
- end
-.,.,
-
-# reduce 111 omitted
-
-# reduce 112 omitted
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Lrama
diff --git a/tool/lrama/lib/lrama/report.rb b/tool/lrama/lib/lrama/report.rb
deleted file mode 100644
index 650ac09d52..0000000000
--- a/tool/lrama/lib/lrama/report.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require 'lrama/report/duration'
-require 'lrama/report/profile'
diff --git a/tool/lrama/lib/lrama/report/duration.rb b/tool/lrama/lib/lrama/report/duration.rb
deleted file mode 100644
index 7afe284f1a..0000000000
--- a/tool/lrama/lib/lrama/report/duration.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-module Lrama
- class Report
- module Duration
- def self.enable
- @_report_duration_enabled = true
- end
-
- def self.enabled?
- !!@_report_duration_enabled
- end
-
- def report_duration(method_name)
- time1 = Time.now.to_f
- result = yield
- time2 = Time.now.to_f
-
- if Duration.enabled?
- puts sprintf("%s %10.5f s", method_name, time2 - time1)
- end
-
- return result
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/report/profile.rb b/tool/lrama/lib/lrama/report/profile.rb
deleted file mode 100644
index 36156800a4..0000000000
--- a/tool/lrama/lib/lrama/report/profile.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module Lrama
- class Report
- module Profile
- # See "Profiling Lrama" in README.md for how to use.
- def self.report_profile
- require "stackprof"
-
- StackProf.run(mode: :cpu, raw: true, out: 'tmp/stackprof-cpu-myapp.dump') do
- yield
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/state.rb b/tool/lrama/lib/lrama/state.rb
deleted file mode 100644
index 1b40640215..0000000000
--- a/tool/lrama/lib/lrama/state.rb
+++ /dev/null
@@ -1,166 +0,0 @@
-require "lrama/state/reduce"
-require "lrama/state/reduce_reduce_conflict"
-require "lrama/state/resolved_conflict"
-require "lrama/state/shift"
-require "lrama/state/shift_reduce_conflict"
-
-module Lrama
- class State
- attr_reader :id, :accessing_symbol, :kernels, :conflicts, :resolved_conflicts,
- :default_reduction_rule, :closure, :items
- attr_accessor :shifts, :reduces
-
- def initialize(id, accessing_symbol, kernels)
- @id = id
- @accessing_symbol = accessing_symbol
- @kernels = kernels.freeze
- @items = @kernels
- # Manage relationships between items to state
- # to resolve next state
- @items_to_state = {}
- @conflicts = []
- @resolved_conflicts = []
- @default_reduction_rule = nil
- end
-
- def closure=(closure)
- @closure = closure
- @items = @kernels + @closure
- end
-
- def non_default_reduces
- reduces.select do |reduce|
- reduce.rule != @default_reduction_rule
- end
- end
-
- def compute_shifts_reduces
- _shifts = {}
- reduces = []
- items.each do |item|
- # TODO: Consider what should be pushed
- if item.end_of_rule?
- reduces << Reduce.new(item)
- else
- key = item.next_sym
- _shifts[key] ||= []
- _shifts[key] << item.new_by_next_position
- end
- end
-
- # It seems Bison 3.8.2 iterates transitions order by symbol number
- shifts = _shifts.sort_by do |next_sym, new_items|
- next_sym.number
- end.map do |next_sym, new_items|
- Shift.new(next_sym, new_items.flatten)
- end
- self.shifts = shifts.freeze
- self.reduces = reduces.freeze
- end
-
- def set_items_to_state(items, next_state)
- @items_to_state[items] = next_state
- end
-
- def set_look_ahead(rule, look_ahead)
- reduce = reduces.find do |r|
- r.rule == rule
- end
-
- reduce.look_ahead = look_ahead
- end
-
- # Returns array of [Shift, next_state]
- def nterm_transitions
- return @nterm_transitions if @nterm_transitions
-
- @nterm_transitions = []
-
- shifts.each do |shift|
- next if shift.next_sym.term?
-
- @nterm_transitions << [shift, @items_to_state[shift.next_items]]
- end
-
- @nterm_transitions
- end
-
- # Returns array of [Shift, next_state]
- def term_transitions
- return @term_transitions if @term_transitions
-
- @term_transitions = []
-
- shifts.each do |shift|
- next if shift.next_sym.nterm?
-
- @term_transitions << [shift, @items_to_state[shift.next_items]]
- end
-
- @term_transitions
- end
-
- def transitions
- term_transitions + nterm_transitions
- end
-
- def selected_term_transitions
- term_transitions.select do |shift, next_state|
- !shift.not_selected
- end
- end
-
- # Move to next state by sym
- def transition(sym)
- result = nil
-
- if sym.term?
- term_transitions.each do |shift, next_state|
- term = shift.next_sym
- result = next_state if term == sym
- end
- else
- nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
- result = next_state if nterm == sym
- end
- end
-
- raise "Can not transit by #{sym} #{self}" if result.nil?
-
- result
- end
-
- def find_reduce_by_item!(item)
- reduces.find do |r|
- r.item == item
- end || (raise "reduce is not found. #{item}")
- end
-
- def default_reduction_rule=(default_reduction_rule)
- @default_reduction_rule = default_reduction_rule
-
- reduces.each do |r|
- if r.rule == default_reduction_rule
- r.default_reduction = true
- end
- end
- end
-
- def has_conflicts?
- !@conflicts.empty?
- end
-
- def sr_conflicts
- @conflicts.select do |conflict|
- conflict.type == :shift_reduce
- end
- end
-
- def rr_conflicts
- @conflicts.select do |conflict|
- conflict.type == :reduce_reduce
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/state/reduce.rb b/tool/lrama/lib/lrama/state/reduce.rb
deleted file mode 100644
index 8ba51f45f2..0000000000
--- a/tool/lrama/lib/lrama/state/reduce.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-module Lrama
- class State
- class Reduce
- # https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html
- attr_reader :item, :look_ahead, :not_selected_symbols
- attr_accessor :default_reduction
-
- def initialize(item)
- @item = item
- @look_ahead = nil
- @not_selected_symbols = []
- end
-
- def rule
- @item.rule
- end
-
- def look_ahead=(look_ahead)
- @look_ahead = look_ahead.freeze
- end
-
- def add_not_selected_symbol(sym)
- @not_selected_symbols << sym
- end
-
- def selected_look_ahead
- if @look_ahead
- @look_ahead - @not_selected_symbols
- else
- []
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb b/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb
deleted file mode 100644
index 0a0e4dc20a..0000000000
--- a/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Lrama
- class State
- class ReduceReduceConflict < Struct.new(:symbols, :reduce1, :reduce2, keyword_init: true)
- def type
- :reduce_reduce
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/state/resolved_conflict.rb b/tool/lrama/lib/lrama/state/resolved_conflict.rb
deleted file mode 100644
index 02ea892147..0000000000
--- a/tool/lrama/lib/lrama/state/resolved_conflict.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Lrama
- class State
- # * symbol: A symbol under discussion
- # * reduce: A reduce under discussion
- # * which: For which a conflict is resolved. :shift, :reduce or :error (for nonassociative)
- class ResolvedConflict < Struct.new(:symbol, :reduce, :which, :same_prec, keyword_init: true)
- def report_message
- s = symbol.display_name
- r = reduce.rule.precedence_sym.display_name
- case
- when which == :shift && same_prec
- msg = "resolved as #{which} (%right #{s})"
- when which == :shift
- msg = "resolved as #{which} (#{r} < #{s})"
- when which == :reduce && same_prec
- msg = "resolved as #{which} (%left #{s})"
- when which == :reduce
- msg = "resolved as #{which} (#{s} < #{r})"
- when which == :error
- msg = "resolved as an #{which} (%nonassoc #{s})"
- else
- raise "Unknown direction. #{self}"
- end
-
- "Conflict between rule #{reduce.rule.id} and token #{s} #{msg}."
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/state/shift.rb b/tool/lrama/lib/lrama/state/shift.rb
deleted file mode 100644
index 2021eb61f6..0000000000
--- a/tool/lrama/lib/lrama/state/shift.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Lrama
- class State
- class Shift
- attr_reader :next_sym, :next_items
- attr_accessor :not_selected
-
- def initialize(next_sym, next_items)
- @next_sym = next_sym
- @next_items = next_items
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb b/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb
deleted file mode 100644
index f80bd5f352..0000000000
--- a/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Lrama
- class State
- class ShiftReduceConflict < Struct.new(:symbols, :shift, :reduce, keyword_init: true)
- def type
- :shift_reduce
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/states.rb b/tool/lrama/lib/lrama/states.rb
deleted file mode 100644
index 290e996b82..0000000000
--- a/tool/lrama/lib/lrama/states.rb
+++ /dev/null
@@ -1,556 +0,0 @@
-require "forwardable"
-require "lrama/report/duration"
-require "lrama/states/item"
-
-module Lrama
- # States is passed to a template file
- #
- # "Efficient Computation of LALR(1) Look-Ahead Sets"
- # https://dl.acm.org/doi/pdf/10.1145/69622.357187
- class States
- extend Forwardable
- include Lrama::Report::Duration
-
- def_delegators "@grammar", :symbols, :terms, :nterms, :rules,
- :accept_symbol, :eof_symbol, :undef_symbol, :find_symbol_by_s_value!
-
- attr_reader :states, :reads_relation, :includes_relation, :lookback_relation
-
- def initialize(grammar, warning, trace_state: false)
- @grammar = grammar
- @warning = warning
- @trace_state = trace_state
-
- @states = []
-
- # `DR(p, A) = {t ∈ T | p -(A)-> r -(t)-> }`
- # where p is state, A is nterm, t is term.
- #
- # `@direct_read_sets` is a hash whose
- # key is [state.id, nterm.token_id],
- # value is bitmap of term.
- @direct_read_sets = {}
-
- # Reads relation on nonterminal transitions (pair of state and nterm)
- # `(p, A) reads (r, C) iff p -(A)-> r -(C)-> and C =>* ε`
- # where p, r are state, A, C are nterm.
- #
- # `@reads_relation` is a hash whose
- # key is [state.id, nterm.token_id],
- # value is array of [state.id, nterm.token_id].
- @reads_relation = {}
-
- # `@read_sets` is a hash whose
- # key is [state.id, nterm.token_id],
- # value is bitmap of term.
- @read_sets = {}
-
- # `(p, A) includes (p', B) iff B -> βAγ, γ =>* ε, p' -(β)-> p`
- # where p, p' are state, A, B are nterm, β, γ is sequence of symbol.
- #
- # `@includes_relation` is a hash whose
- # key is [state.id, nterm.token_id],
- # value is array of [state.id, nterm.token_id].
- @includes_relation = {}
-
- # `(q, A -> ω) lookback (p, A) iff p -(ω)-> q`
- # where p, q are state, A -> ω is rule, A is nterm, ω is sequence of symbol.
- #
- # `@lookback_relation` is a hash whose
- # key is [state.id, rule.id],
- # value is array of [state.id, nterm.token_id].
- @lookback_relation = {}
-
- # `@follow_sets` is a hash whose
- # key is [state.id, rule.id],
- # value is bitmap of term.
- @follow_sets = {}
-
- # `LA(q, A -> ω) = ∪{Follow(p, A) | (q, A -> ω) lookback (p, A)`
- #
- # `@la` is a hash whose
- # key is [state.id, rule.id],
- # value is bitmap of term.
- @la = {}
- end
-
- def compute
- # Look Ahead Sets
- report_duration(:compute_lr0_states) { compute_lr0_states }
- report_duration(:compute_direct_read_sets) { compute_direct_read_sets }
- report_duration(:compute_reads_relation) { compute_reads_relation }
- report_duration(:compute_read_sets) { compute_read_sets }
- report_duration(:compute_includes_relation) { compute_includes_relation }
- report_duration(:compute_lookback_relation) { compute_lookback_relation }
- report_duration(:compute_follow_sets) { compute_follow_sets }
- report_duration(:compute_look_ahead_sets) { compute_look_ahead_sets }
-
- # Conflicts
- report_duration(:compute_conflicts) { compute_conflicts }
-
- report_duration(:compute_default_reduction) { compute_default_reduction }
-
- check_conflicts
- end
-
- def reporter
- StatesReporter.new(self)
- end
-
- def states_count
- @states.count
- end
-
- def direct_read_sets
- @direct_read_sets.transform_values do |v|
- bitmap_to_terms(v)
- end
- end
-
- def read_sets
- @read_sets.transform_values do |v|
- bitmap_to_terms(v)
- end
- end
-
- def follow_sets
- @follow_sets.transform_values do |v|
- bitmap_to_terms(v)
- end
- end
-
- def la
- @la.transform_values do |v|
- bitmap_to_terms(v)
- end
- end
-
- private
-
- def sr_conflicts
- @states.flat_map(&:sr_conflicts)
- end
-
- def rr_conflicts
- @states.flat_map(&:rr_conflicts)
- end
-
- def trace_state
- if @trace_state
- yield STDERR
- end
- end
-
- def create_state(accessing_symbol, kernels, states_created)
- # A item can appear in some states,
- # so need to use `kernels` (not `kernels.first`) as a key.
- #
- # For example...
- #
- # %%
- # program: '+' strings_1
- # | '-' strings_2
- # ;
- #
- # strings_1: string_1
- # ;
- #
- # strings_2: string_1
- # | string_2
- # ;
- #
- # string_1: string
- # ;
- #
- # string_2: string '+'
- # ;
- #
- # string: tSTRING
- # ;
- # %%
- #
- # For these grammar, there are 2 states
- #
- # State A
- # string_1: string •
- #
- # State B
- # string_1: string •
- # string_2: string • '+'
- #
- return [states_created[kernels], false] if states_created[kernels]
-
- state = State.new(@states.count, accessing_symbol, kernels)
- @states << state
- states_created[kernels] = state
-
- return [state, true]
- end
-
- def setup_state(state)
- # closure
- closure = []
- visited = {}
- queued = {}
- items = state.kernels.dup
-
- items.each do |item|
- queued[item] = true
- end
-
- while (item = items.shift) do
- visited[item] = true
-
- if (sym = item.next_sym) && sym.nterm?
- @grammar.find_rules_by_symbol!(sym).each do |rule|
- i = Item.new(rule: rule, position: 0)
- next if queued[i]
- closure << i
- items << i
- queued[i] = true
- end
- end
- end
-
- state.closure = closure.sort_by {|i| i.rule.id }
-
- # Trace
- trace_state do |out|
- out << "Closure: input\n"
- state.kernels.each do |item|
- out << " #{item.display_rest}\n"
- end
- out << "\n\n"
- out << "Closure: output\n"
- state.items.each do |item|
- out << " #{item.display_rest}\n"
- end
- out << "\n\n"
- end
-
- # shift & reduce
- state.compute_shifts_reduces
- end
-
- def enqueue_state(states, state)
- # Trace
- previous = state.kernels.first.previous_sym
- trace_state do |out|
- out << sprintf("state_list_append (state = %d, symbol = %d (%s))",
- @states.count, previous.number, previous.display_name)
- end
-
- states << state
- end
-
- def compute_lr0_states
- # State queue
- states = []
- states_created = {}
-
- state, _ = create_state(symbols.first, [Item.new(rule: @grammar.rules.first, position: 0)], states_created)
- enqueue_state(states, state)
-
- while (state = states.shift) do
- # Trace
- #
- # Bison 3.8.2 renders "(reached by "end-of-input")" for State 0 but
- # I think it is not correct...
- previous = state.kernels.first.previous_sym
- trace_state do |out|
- out << "Processing state #{state.id} (reached by #{previous.display_name})\n"
- end
-
- setup_state(state)
-
- state.shifts.each do |shift|
- new_state, created = create_state(shift.next_sym, shift.next_items, states_created)
- state.set_items_to_state(shift.next_items, new_state)
- enqueue_state(states, new_state) if created
- end
- end
- end
-
- def nterm_transitions
- a = []
-
- @states.each do |state|
- state.nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
- a << [state, nterm, next_state]
- end
- end
-
- a
- end
-
- def compute_direct_read_sets
- @states.each do |state|
- state.nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
-
- ary = next_state.term_transitions.map do |shift, _|
- shift.next_sym.number
- end
-
- key = [state.id, nterm.token_id]
- @direct_read_sets[key] = Bitmap.from_array(ary)
- end
- end
- end
-
- def compute_reads_relation
- @states.each do |state|
- state.nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
- next_state.nterm_transitions.each do |shift2, _next_state2|
- nterm2 = shift2.next_sym
- if nterm2.nullable
- key = [state.id, nterm.token_id]
- @reads_relation[key] ||= []
- @reads_relation[key] << [next_state.id, nterm2.token_id]
- end
- end
- end
- end
- end
-
- def compute_read_sets
- sets = nterm_transitions.map do |state, nterm, next_state|
- [state.id, nterm.token_id]
- end
-
- @read_sets = Digraph.new(sets, @reads_relation, @direct_read_sets).compute
- end
-
- # Execute transition of state by symbols
- # then return final state.
- def transition(state, symbols)
- symbols.each do |sym|
- state = state.transition(sym)
- end
-
- state
- end
-
- def compute_includes_relation
- @states.each do |state|
- state.nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
- @grammar.find_rules_by_symbol!(nterm).each do |rule|
- i = rule.rhs.count - 1
-
- while (i > -1) do
- sym = rule.rhs[i]
-
- break if sym.term?
- state2 = transition(state, rule.rhs[0...i])
- # p' = state, B = nterm, p = state2, A = sym
- key = [state2.id, sym.token_id]
- # TODO: need to omit if state == state2 ?
- @includes_relation[key] ||= []
- @includes_relation[key] << [state.id, nterm.token_id]
- break if !sym.nullable
- i -= 1
- end
- end
- end
- end
- end
-
- def compute_lookback_relation
- @states.each do |state|
- state.nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
- @grammar.find_rules_by_symbol!(nterm).each do |rule|
- state2 = transition(state, rule.rhs)
- # p = state, A = nterm, q = state2, A -> ω = rule
- key = [state2.id, rule.id]
- @lookback_relation[key] ||= []
- @lookback_relation[key] << [state.id, nterm.token_id]
- end
- end
- end
- end
-
- def compute_follow_sets
- sets = nterm_transitions.map do |state, nterm, next_state|
- [state.id, nterm.token_id]
- end
-
- @follow_sets = Digraph.new(sets, @includes_relation, @read_sets).compute
- end
-
- def compute_look_ahead_sets
- @states.each do |state|
- rules.each do |rule|
- ary = @lookback_relation[[state.id, rule.id]]
- next if !ary
-
- ary.each do |state2_id, nterm_token_id|
- # q = state, A -> ω = rule, p = state2, A = nterm
- follows = @follow_sets[[state2_id, nterm_token_id]]
-
- next if follows == 0
-
- key = [state.id, rule.id]
- @la[key] ||= 0
- look_ahead = @la[key] | follows
- @la[key] |= look_ahead
-
- # No risk of conflict when
- # * the state only has single reduce
- # * the state only has nterm_transitions (GOTO)
- next if state.reduces.count == 1 && state.term_transitions.count == 0
-
- state.set_look_ahead(rule, bitmap_to_terms(look_ahead))
- end
- end
- end
- end
-
- def bitmap_to_terms(bit)
- ary = Bitmap.to_array(bit)
- ary.map do |i|
- @grammar.find_symbol_by_number!(i)
- end
- end
-
- def compute_conflicts
- compute_shift_reduce_conflicts
- compute_reduce_reduce_conflicts
- end
-
- def compute_shift_reduce_conflicts
- states.each do |state|
- state.shifts.each do |shift|
- state.reduces.each do |reduce|
- sym = shift.next_sym
-
- next unless reduce.look_ahead
- next if !reduce.look_ahead.include?(sym)
-
- # Shift/Reduce conflict
- shift_prec = sym.precedence
- reduce_prec = reduce.item.rule.precedence
-
- # Can resolve only when both have prec
- unless shift_prec && reduce_prec
- state.conflicts << State::ShiftReduceConflict.new(symbols: [sym], shift: shift, reduce: reduce)
- next
- end
-
- case
- when shift_prec < reduce_prec
- # Reduce is selected
- state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :reduce)
- shift.not_selected = true
- next
- when shift_prec > reduce_prec
- # Shift is selected
- state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :shift)
- reduce.add_not_selected_symbol(sym)
- next
- end
-
- # shift_prec == reduce_prec, then check associativity
- case sym.precedence.type
- when :precedence
- # %precedence only specifies precedence and not specify associativity
- # then a conflict is unresolved if precedence is same.
- state.conflicts << State::ShiftReduceConflict.new(symbols: [sym], shift: shift, reduce: reduce)
- next
- when :right
- # Shift is selected
- state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :shift, same_prec: true)
- reduce.add_not_selected_symbol(sym)
- next
- when :left
- # Reduce is selected
- state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :reduce, same_prec: true)
- shift.not_selected = true
- next
- when :nonassoc
- # Can not resolve
- #
- # nonassoc creates "run-time" error, precedence creates "compile-time" error.
- # Then omit both the shift and reduce.
- #
- # https://www.gnu.org/software/bison/manual/html_node/Using-Precedence.html
- state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :error)
- shift.not_selected = true
- reduce.add_not_selected_symbol(sym)
- else
- raise "Unknown precedence type. #{sym}"
- end
- end
- end
- end
- end
-
- def compute_reduce_reduce_conflicts
- states.each do |state|
- count = state.reduces.count
-
- for i in 0...count do
- reduce1 = state.reduces[i]
- next if reduce1.look_ahead.nil?
-
- for j in (i+1)...count do
- reduce2 = state.reduces[j]
- next if reduce2.look_ahead.nil?
-
- intersection = reduce1.look_ahead & reduce2.look_ahead
-
- if !intersection.empty?
- state.conflicts << State::ReduceReduceConflict.new(symbols: intersection, reduce1: reduce1, reduce2: reduce2)
- end
- end
- end
- end
- end
-
- def compute_default_reduction
- states.each do |state|
- next if state.reduces.empty?
- # Do not set, if conflict exist
- next if !state.conflicts.empty?
- # Do not set, if shift with `error` exists.
- next if state.shifts.map(&:next_sym).include?(@grammar.error_symbol)
-
- state.default_reduction_rule = state.reduces.map do |r|
- [r.rule, r.rule.id, (r.look_ahead || []).count]
- end.min_by do |rule, rule_id, count|
- [-count, rule_id]
- end.first
- end
- end
-
- def check_conflicts
- sr_count = sr_conflicts.count
- rr_count = rr_conflicts.count
-
- if @grammar.expect
-
- expected_sr_conflicts = @grammar.expect
- expected_rr_conflicts = 0
-
- if expected_sr_conflicts != sr_count
- @warning.error("shift/reduce conflicts: #{sr_count} found, #{expected_sr_conflicts} expected")
- end
-
- if expected_rr_conflicts != rr_count
- @warning.error("reduce/reduce conflicts: #{rr_count} found, #{expected_rr_conflicts} expected")
- end
- else
- if sr_count != 0
- @warning.warn("shift/reduce conflicts: #{sr_count} found")
- end
-
- if rr_count != 0
- @warning.warn("reduce/reduce conflicts: #{rr_count} found")
- end
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/states/item.rb b/tool/lrama/lib/lrama/states/item.rb
deleted file mode 100644
index 823ccc72e1..0000000000
--- a/tool/lrama/lib/lrama/states/item.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-# TODO: Validate position is not over rule rhs
-
-module Lrama
- class States
- class Item < Struct.new(:rule, :position, keyword_init: true)
- # Optimization for States#setup_state
- def hash
- [rule.id, position].hash
- end
-
- def rule_id
- rule.id
- end
-
- def empty_rule?
- rule.empty_rule?
- end
-
- def number_of_rest_symbols
- rule.rhs.count - position
- end
-
- def lhs
- rule.lhs
- end
-
- def next_sym
- rule.rhs[position]
- end
-
- def next_next_sym
- rule.rhs[position + 1]
- end
-
- def previous_sym
- rule.rhs[position - 1]
- end
-
- def end_of_rule?
- rule.rhs.count == position
- end
-
- def beginning_of_rule?
- position == 0
- end
-
- def start_item?
- rule.id == 0 && position == 0
- end
-
- def new_by_next_position
- Item.new(rule: rule, position: position + 1)
- end
-
- def symbols_before_dot
- rule.rhs[0...position]
- end
-
- def symbols_after_dot
- rule.rhs[position..-1]
- end
-
- def to_s
- "#{lhs.id.s_value}: #{display_name}"
- end
-
- def display_name
- r = rule.rhs.map(&:display_name).insert(position, "•").join(" ")
- "#{r} (rule #{rule.id})"
- end
-
- # Right after position
- def display_rest
- r = rule.rhs[position..-1].map(&:display_name).join(" ")
- ". #{r} (rule #{rule.id})"
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/states_reporter.rb b/tool/lrama/lib/lrama/states_reporter.rb
deleted file mode 100644
index 8be0f71e40..0000000000
--- a/tool/lrama/lib/lrama/states_reporter.rb
+++ /dev/null
@@ -1,323 +0,0 @@
-module Lrama
- class StatesReporter
- include Lrama::Report::Duration
-
- def initialize(states)
- @states = states
- end
-
- def report(io, **options)
- report_duration(:report) do
- _report(io, **options)
- end
- end
-
- private
-
- def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false)
- # TODO: Unused terms
- # TODO: Unused rules
-
- report_conflicts(io)
- report_grammar(io) if grammar
- report_states(io, itemsets, lookaheads, solved, counterexamples, verbose)
- end
-
- def report_conflicts(io)
- has_conflict = false
-
- @states.states.each do |state|
- messages = []
- cs = state.conflicts.group_by(&:type)
- if cs[:shift_reduce]
- messages << "#{cs[:shift_reduce].count} shift/reduce"
- end
-
- if cs[:reduce_reduce]
- messages << "#{cs[:reduce_reduce].count} reduce/reduce"
- end
-
- if !messages.empty?
- has_conflict = true
- io << "State #{state.id} conflicts: #{messages.join(', ')}\n"
- end
- end
-
- if has_conflict
- io << "\n\n"
- end
- end
-
- def report_grammar(io)
- io << "Grammar\n"
- last_lhs = nil
-
- @states.rules.each do |rule|
- if rule.rhs.empty?
- r = "ε"
- else
- r = rule.rhs.map(&:display_name).join(" ")
- end
-
- if rule.lhs == last_lhs
- io << sprintf("%5d %s| %s\n", rule.id, " " * rule.lhs.display_name.length, r)
- else
- io << "\n"
- io << sprintf("%5d %s: %s\n", rule.id, rule.lhs.display_name, r)
- end
-
- last_lhs = rule.lhs
- end
- io << "\n\n"
- end
-
- def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose)
- if counterexamples
- cex = Counterexamples.new(@states)
- end
-
- @states.states.each do |state|
- # Report State
- io << "State #{state.id}\n\n"
-
- # Report item
- last_lhs = nil
- list = itemsets ? state.items : state.kernels
- list.sort_by {|i| [i.rule_id, i.position] }.each do |item|
- rule = item.rule
- position = item.position
- if rule.rhs.empty?
- r = "ε •"
- else
- r = rule.rhs.map(&:display_name).insert(position, "•").join(" ")
- end
- if rule.lhs == last_lhs
- l = " " * rule.lhs.id.s_value.length + "|"
- else
- l = rule.lhs.id.s_value + ":"
- end
- la = ""
- if lookaheads && item.end_of_rule?
- reduce = state.find_reduce_by_item!(item)
- look_ahead = reduce.selected_look_ahead
- if !look_ahead.empty?
- la = " [#{look_ahead.map(&:display_name).join(", ")}]"
- end
- end
- last_lhs = rule.lhs
-
- io << sprintf("%5i %s %s%s\n", rule.id, l, r, la)
- end
- io << "\n"
-
- # Report shifts
- tmp = state.term_transitions.select do |shift, _|
- !shift.not_selected
- end.map do |shift, next_state|
- [shift.next_sym, next_state.id]
- end
- max_len = tmp.map(&:first).map(&:display_name).map(&:length).max
- tmp.each do |term, state_id|
- io << " #{term.display_name.ljust(max_len)} shift, and go to state #{state_id}\n"
- end
- io << "\n" if !tmp.empty?
-
- # Report error caused by %nonassoc
- nl = false
- tmp = state.resolved_conflicts.select do |resolved|
- resolved.which == :error
- end.map do |error|
- error.symbol.display_name
- end
- max_len = tmp.map(&:length).max
- tmp.each do |name|
- nl = true
- io << " #{name.ljust(max_len)} error (nonassociative)\n"
- end
- io << "\n" if !tmp.empty?
-
- # Report reduces
- nl = false
- max_len = state.non_default_reduces.flat_map(&:look_ahead).compact.map(&:display_name).map(&:length).max || 0
- max_len = [max_len, "$default".length].max if state.default_reduction_rule
- ary = []
-
- state.non_default_reduces.each do |reduce|
- reduce.look_ahead.each do |term|
- ary << [term, reduce]
- end
- end
-
- ary.sort_by do |term, reduce|
- term.number
- end.each do |term, reduce|
- rule = reduce.item.rule
- io << " #{term.display_name.ljust(max_len)} reduce using rule #{rule.id} (#{rule.lhs.display_name})\n"
- nl = true
- end
-
- if r = state.default_reduction_rule
- nl = true
- s = "$default".ljust(max_len)
-
- if r.initial_rule?
- io << " #{s} accept\n"
- else
- io << " #{s} reduce using rule #{r.id} (#{r.lhs.display_name})\n"
- end
- end
- io << "\n" if nl
-
- # Report nonterminal transitions
- tmp = []
- max_len = 0
- state.nterm_transitions.each do |shift, next_state|
- nterm = shift.next_sym
- tmp << [nterm, next_state.id]
- max_len = [max_len, nterm.id.s_value.length].max
- end
- tmp.uniq!
- tmp.sort_by! do |nterm, state_id|
- nterm.number
- end
- tmp.each do |nterm, state_id|
- io << " #{nterm.id.s_value.ljust(max_len)} go to state #{state_id}\n"
- end
- io << "\n" if !tmp.empty?
-
- if solved
- # Report conflict resolutions
- state.resolved_conflicts.each do |resolved|
- io << " #{resolved.report_message}\n"
- end
- io << "\n" if !state.resolved_conflicts.empty?
- end
-
- if counterexamples && state.has_conflicts?
- # Report counterexamples
- examples = cex.compute(state)
- examples.each do |example|
- label0 = example.type == :shift_reduce ? "shift/reduce" : "reduce/reduce"
- label1 = example.type == :shift_reduce ? "Shift derivation" : "First Reduce derivation"
- label2 = example.type == :shift_reduce ? "Reduce derivation" : "Second Reduce derivation"
-
- io << " #{label0} conflict on token #{example.conflict_symbol.id.s_value}:\n"
- io << " #{example.path1_item}\n"
- io << " #{example.path2_item}\n"
- io << " #{label1}\n"
- example.derivations1.render_strings_for_report.each do |str|
- io << " #{str}\n"
- end
- io << " #{label2}\n"
- example.derivations2.render_strings_for_report.each do |str|
- io << " #{str}\n"
- end
- end
- end
-
- if verbose
- # Report direct_read_sets
- io << " [Direct Read sets]\n"
- direct_read_sets = @states.direct_read_sets
- @states.nterms.each do |nterm|
- terms = direct_read_sets[[state.id, nterm.token_id]]
- next if !terms
- next if terms.empty?
-
- str = terms.map {|sym| sym.id.s_value }.join(", ")
- io << " read #{nterm.id.s_value} shift #{str}\n"
- end
- io << "\n"
-
- # Report reads_relation
- io << " [Reads Relation]\n"
- @states.nterms.each do |nterm|
- a = @states.reads_relation[[state.id, nterm.token_id]]
- next if !a
-
- a.each do |state_id2, nterm_id2|
- n = @states.nterms.find {|n| n.token_id == nterm_id2 }
- io << " (State #{state_id2}, #{n.id.s_value})\n"
- end
- end
- io << "\n"
-
- # Report read_sets
- io << " [Read sets]\n"
- read_sets = @states.read_sets
- @states.nterms.each do |nterm|
- terms = read_sets[[state.id, nterm.token_id]]
- next if !terms
- next if terms.empty?
-
- terms.each do |sym|
- io << " #{sym.id.s_value}\n"
- end
- end
- io << "\n"
-
- # Report includes_relation
- io << " [Includes Relation]\n"
- @states.nterms.each do |nterm|
- a = @states.includes_relation[[state.id, nterm.token_id]]
- next if !a
-
- a.each do |state_id2, nterm_id2|
- n = @states.nterms.find {|n| n.token_id == nterm_id2 }
- io << " (State #{state.id}, #{nterm.id.s_value}) -> (State #{state_id2}, #{n.id.s_value})\n"
- end
- end
- io << "\n"
-
- # Report lookback_relation
- io << " [Lookback Relation]\n"
- @states.rules.each do |rule|
- a = @states.lookback_relation[[state.id, rule.id]]
- next if !a
-
- a.each do |state_id2, nterm_id2|
- n = @states.nterms.find {|n| n.token_id == nterm_id2 }
- io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n"
- end
- end
- io << "\n"
-
- # Report follow_sets
- io << " [Follow sets]\n"
- follow_sets = @states.follow_sets
- @states.nterms.each do |nterm|
- terms = follow_sets[[state.id, nterm.token_id]]
-
- next if !terms
-
- terms.each do |sym|
- io << " #{nterm.id.s_value} -> #{sym.id.s_value}\n"
- end
- end
- io << "\n"
-
- # Report LA
- io << " [Look-Ahead Sets]\n"
- tmp = []
- max_len = 0
- @states.rules.each do |rule|
- syms = @states.la[[state.id, rule.id]]
- next if !syms
-
- tmp << [rule, syms]
- max_len = ([max_len] + syms.map {|s| s.id.s_value.length }).max
- end
- tmp.each do |rule, syms|
- syms.each do |sym|
- io << " #{sym.id.s_value.ljust(max_len)} reduce using rule #{rule.id} (#{rule.lhs.id.s_value})\n"
- end
- end
- io << "\n" if !tmp.empty?
- end
-
- # End of Report State
- io << "\n"
- end
- end
- end
-end
diff --git a/tool/lrama/lib/lrama/version.rb b/tool/lrama/lib/lrama/version.rb
deleted file mode 100644
index 3e68736482..0000000000
--- a/tool/lrama/lib/lrama/version.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-module Lrama
- VERSION = "0.5.12".freeze
-end
diff --git a/tool/lrama/lib/lrama/warning.rb b/tool/lrama/lib/lrama/warning.rb
deleted file mode 100644
index 3c99791ebf..0000000000
--- a/tool/lrama/lib/lrama/warning.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-module Lrama
- class Warning
- attr_reader :errors, :warns
-
- def initialize(out = STDERR)
- @out = out
- @errors = []
- @warns = []
- end
-
- def error(message)
- @out << message << "\n"
- @errors << message
- end
-
- def warn(message)
- @out << message << "\n"
- @warns << message
- end
-
- def has_error?
- !@errors.empty?
- end
- end
-end
diff --git a/tool/lrama/template/bison/_yacc.h b/tool/lrama/template/bison/_yacc.h
deleted file mode 100644
index 34ed6d81f5..0000000000
--- a/tool/lrama/template/bison/_yacc.h
+++ /dev/null
@@ -1,71 +0,0 @@
-<%# b4_shared_declarations -%>
- <%-# b4_cpp_guard_open([b4_spec_mapped_header_file]) -%>
- <%- if output.spec_mapped_header_file -%>
-#ifndef <%= output.b4_cpp_guard__b4_spec_mapped_header_file %>
-# define <%= output.b4_cpp_guard__b4_spec_mapped_header_file %>
- <%- end -%>
- <%-# b4_declare_yydebug & b4_YYDEBUG_define -%>
-/* Debug traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG && !defined(yydebug)
-extern int yydebug;
-#endif
-<%= output.percent_code("requires") %>
-
- <%-# b4_token_enums_defines -%>
-/* Token kinds. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- enum yytokentype
- {
-<%= output.token_enums -%>
- };
- typedef enum yytokentype yytoken_kind_t;
-#endif
-
- <%-# b4_declare_yylstype -%>
- <%-# b4_value_type_define -%>
-/* Value type. */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-union YYSTYPE
-{
-#line <%= output.grammar.union.lineno %> "<%= output.grammar_file_path %>"
-<%= output.grammar.union.braces_less_code %>
-#line [@oline@] [@ofile@]
-
-};
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
- <%-# b4_location_type_define -%>
-/* Location type. */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-};
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-
- <%-# b4_declare_yyerror_and_yylex. Not supported -%>
- <%-# b4_declare_yyparse -%>
-int yyparse (<%= output.parse_param %>);
-
-
-<%= output.percent_code("provides") %>
- <%-# b4_cpp_guard_close([b4_spec_mapped_header_file]) -%>
- <%- if output.spec_mapped_header_file -%>
-#endif /* !<%= output.b4_cpp_guard__b4_spec_mapped_header_file %> */
- <%- end -%>
diff --git a/tool/lrama/template/bison/yacc.c b/tool/lrama/template/bison/yacc.c
deleted file mode 100644
index f72d346178..0000000000
--- a/tool/lrama/template/bison/yacc.c
+++ /dev/null
@@ -1,2052 +0,0 @@
-<%# b4_generated_by -%>
-/* A Bison parser, made by Lrama <%= Lrama::VERSION %>. */
-
-<%# b4_copyright -%>
-/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
- Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-<%# b4_disclaimer -%>
-/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
- especially those whose name start with YY_ or yy_. They are
- private implementation details that can be changed or removed. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-<%# b4_identification -%>
-/* Identify Bison output, and Bison version. */
-#define YYBISON 30802
-
-/* Bison version string. */
-#define YYBISON_VERSION "3.8.2"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "<%= output.template_basename %>"
-
-/* Pure parsers. */
-#define YYPURE 1
-
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
-
-<%# b4_user_pre_prologue -%>
-<%- if output.aux.prologue -%>
-/* First part of user prologue. */
-#line <%= output.aux.prologue_first_lineno %> "<%= output.grammar_file_path %>"
-<%= output.aux.prologue %>
-#line [@oline@] [@ofile@]
-<%- end -%>
-
-<%# b4_cast_define -%>
-# ifndef YY_CAST
-# ifdef __cplusplus
-# define YY_CAST(Type, Val) static_cast<Type> (Val)
-# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
-# else
-# define YY_CAST(Type, Val) ((Type) (Val))
-# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
-# endif
-# endif
-<%# b4_null_define -%>
-# ifndef YY_NULLPTR
-# if defined __cplusplus
-# if 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
-# else
-# define YY_NULLPTR 0
-# endif
-# else
-# define YY_NULLPTR ((void*)0)
-# endif
-# endif
-
-<%# b4_header_include_if -%>
-<%- if output.include_header -%>
-#include "<%= output.include_header %>"
-<%- else -%>
-/* Use api.header.include to #include this header
- instead of duplicating it here. */
-<%= output.render_partial("bison/_yacc.h") %>
-<%- end -%>
-<%# b4_declare_symbol_enum -%>
-/* Symbol kind. */
-enum yysymbol_kind_t
-{
-<%= output.symbol_enum -%>
-};
-typedef enum yysymbol_kind_t yysymbol_kind_t;
-
-
-
-
-<%# b4_user_post_prologue -%>
-<%# b4_c99_int_type_define -%>
-#ifdef short
-# undef short
-#endif
-
-/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
- <limits.h> and (if available) <stdint.h> are included
- so that the code can choose integer types of a good width. */
-
-#ifndef __PTRDIFF_MAX__
-# include <limits.h> /* INFRINGES ON USER NAME SPACE */
-# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
-# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_STDINT_H
-# endif
-#endif
-
-/* Narrow types that promote to a signed type and that can represent a
- signed or unsigned integer of at least N bits. In tables they can
- save space and decrease cache pressure. Promoting to a signed type
- helps avoid bugs in integer arithmetic. */
-
-#ifdef __INT_LEAST8_MAX__
-typedef __INT_LEAST8_TYPE__ yytype_int8;
-#elif defined YY_STDINT_H
-typedef int_least8_t yytype_int8;
-#else
-typedef signed char yytype_int8;
-#endif
-
-#ifdef __INT_LEAST16_MAX__
-typedef __INT_LEAST16_TYPE__ yytype_int16;
-#elif defined YY_STDINT_H
-typedef int_least16_t yytype_int16;
-#else
-typedef short yytype_int16;
-#endif
-
-/* Work around bug in HP-UX 11.23, which defines these macros
- incorrectly for preprocessor constants. This workaround can likely
- be removed in 2023, as HPE has promised support for HP-UX 11.23
- (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
- <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
-#ifdef __hpux
-# undef UINT_LEAST8_MAX
-# undef UINT_LEAST16_MAX
-# define UINT_LEAST8_MAX 255
-# define UINT_LEAST16_MAX 65535
-#endif
-
-#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
-typedef __UINT_LEAST8_TYPE__ yytype_uint8;
-#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
- && UINT_LEAST8_MAX <= INT_MAX)
-typedef uint_least8_t yytype_uint8;
-#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
-typedef unsigned char yytype_uint8;
-#else
-typedef short yytype_uint8;
-#endif
-
-#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
-typedef __UINT_LEAST16_TYPE__ yytype_uint16;
-#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
- && UINT_LEAST16_MAX <= INT_MAX)
-typedef uint_least16_t yytype_uint16;
-#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
-typedef unsigned short yytype_uint16;
-#else
-typedef int yytype_uint16;
-#endif
-
-<%# b4_sizes_types_define -%>
-#ifndef YYPTRDIFF_T
-# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
-# define YYPTRDIFF_T __PTRDIFF_TYPE__
-# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
-# elif defined PTRDIFF_MAX
-# ifndef ptrdiff_t
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# endif
-# define YYPTRDIFF_T ptrdiff_t
-# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
-# else
-# define YYPTRDIFF_T long
-# define YYPTRDIFF_MAXIMUM LONG_MAX
-# endif
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM \
- YY_CAST (YYPTRDIFF_T, \
- (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
- ? YYPTRDIFF_MAXIMUM \
- : YY_CAST (YYSIZE_T, -1)))
-
-#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
-
-
-/* Stored state numbers (used for stacks). */
-typedef <%= output.int_type_for([output.yynstates - 1]) %> yy_state_t;
-
-/* State numbers in computations. */
-typedef int yy_state_fast_t;
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(Msgid) Msgid
-# endif
-#endif
-
-
-<%# b4_attribute_define -%>
-#ifndef YY_ATTRIBUTE_PURE
-# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
-# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
-# else
-# define YY_ATTRIBUTE_PURE
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE_UNUSED
-# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
-# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-# else
-# define YY_ATTRIBUTE_UNUSED
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YY_USE(E) ((void) (E))
-#else
-# define YY_USE(E) /* empty */
-#endif
-
-/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
-# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
- _Pragma ("GCC diagnostic push") \
- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
-# else
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
- _Pragma ("GCC diagnostic push") \
- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# endif
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
- _Pragma ("GCC diagnostic pop")
-#else
-# define YY_INITIAL_VALUE(Value) Value
-#endif
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
-
-#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
-# define YY_IGNORE_USELESS_CAST_BEGIN \
- _Pragma ("GCC diagnostic push") \
- _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
-# define YY_IGNORE_USELESS_CAST_END \
- _Pragma ("GCC diagnostic pop")
-#endif
-#ifndef YY_IGNORE_USELESS_CAST_BEGIN
-# define YY_IGNORE_USELESS_CAST_BEGIN
-# define YY_IGNORE_USELESS_CAST_END
-#endif
-
-
-#define YY_ASSERT(E) ((void) (0 && (E)))
-
-#if 1
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
- /* Use EXIT_SUCCESS as a witness for stdlib.h. */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's 'empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# if (defined __cplusplus && ! defined EXIT_SUCCESS \
- && ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
-# endif
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# endif
-#endif /* 1 */
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yy_state_t yyss_alloc;
- YYSTYPE yyvs_alloc;
- YYLTYPE yyls_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \
- + YYSIZEOF (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYPTRDIFF_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / YYSIZEOF (*yyptr); \
- } \
- while (0)
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(Dst, Src, Count) \
- __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
-# else
-# define YYCOPY(Dst, Src, Count) \
- do \
- { \
- YYPTRDIFF_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (Dst)[yyi] = (Src)[yyi]; \
- } \
- while (0)
-# endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL <%= output.yyfinal %>
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST <%= output.yylast %>
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS <%= output.yyntokens %>
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS <%= output.yynnts %>
-/* YYNRULES -- Number of rules. */
-#define YYNRULES <%= output.yynrules %>
-/* YYNSTATES -- Number of states. */
-#define YYNSTATES <%= output.yynstates %>
-
-/* YYMAXUTOK -- Last valid token kind. */
-#define YYMAXUTOK <%= output.yymaxutok %>
-
-
-/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, with out-of-bounds checking. */
-#define YYTRANSLATE(YYX) \
- (0 <= (YYX) && (YYX) <= YYMAXUTOK \
- ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
- : YYSYMBOL_YYUNDEF)
-
-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex. */
-static const <%= output.int_type_for(output.context.yytranslate) %> yytranslate[] =
-{
-<%= output.yytranslate %>
-};
-
-<%- if output.error_recovery -%>
-/* YYTRANSLATE_INVERTED[SYMBOL-NUM] -- Token number corresponding to SYMBOL-NUM */
-static const <%= output.int_type_for(output.context.yytranslate_inverted) %> yytranslate_inverted[] =
-{
-<%= output.yytranslate_inverted %>
-};
-<%- end -%>
-#if YYDEBUG
-/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const <%= output.int_type_for(output.context.yyrline) %> yyrline[] =
-{
-<%= output.yyrline %>
-};
-#endif
-
-/** Accessing symbol of state STATE. */
-#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
-
-#if 1
-/* The user-facing name of the symbol whose (internal) number is
- YYSYMBOL. No bounds checking. */
-static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
-
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
-<%= output.yytname %>
-};
-
-static const char *
-yysymbol_name (yysymbol_kind_t yysymbol)
-{
- return yytname[yysymbol];
-}
-#endif
-
-#define YYPACT_NINF (<%= output.yypact_ninf %>)
-
-#define yypact_value_is_default(Yyn) \
- <%= output.table_value_equals(output.context.yypact, "Yyn", output.yypact_ninf, "YYPACT_NINF") %>
-
-#define YYTABLE_NINF (<%= output.yytable_ninf %>)
-
-#define yytable_value_is_error(Yyn) \
- <%= output.table_value_equals(output.context.yytable, "Yyn", output.yytable_ninf, "YYTABLE_NINF") %>
-
-<%# b4_parser_tables_define -%>
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-static const <%= output.int_type_for(output.context.yypact) %> yypact[] =
-{
-<%= output.int_array_to_string(output.context.yypact) %>
-};
-
-/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE does not specify something else to do. Zero
- means the default is an error. */
-static const <%= output.int_type_for(output.context.yydefact) %> yydefact[] =
-{
-<%= output.int_array_to_string(output.context.yydefact) %>
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const <%= output.int_type_for(output.context.yypgoto) %> yypgoto[] =
-{
-<%= output.int_array_to_string(output.context.yypgoto) %>
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const <%= output.int_type_for(output.context.yydefgoto) %> yydefgoto[] =
-{
-<%= output.int_array_to_string(output.context.yydefgoto) %>
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule whose
- number is the opposite. If YYTABLE_NINF, syntax error. */
-static const <%= output.int_type_for(output.context.yytable) %> yytable[] =
-{
-<%= output.int_array_to_string(output.context.yytable) %>
-};
-
-static const <%= output.int_type_for(output.context.yycheck) %> yycheck[] =
-{
-<%= output.int_array_to_string(output.context.yycheck) %>
-};
-
-/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
- state STATE-NUM. */
-static const <%= output.int_type_for(output.context.yystos) %> yystos[] =
-{
-<%= output.int_array_to_string(output.context.yystos) %>
-};
-
-/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
-static const <%= output.int_type_for(output.context.yyr1) %> yyr1[] =
-{
-<%= output.int_array_to_string(output.context.yyr1) %>
-};
-
-/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
-static const <%= output.int_type_for(output.context.yyr2) %> yyr2[] =
-{
-<%= output.int_array_to_string(output.context.yyr2) %>
-};
-
-
-enum { YYENOMEM = -2 };
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-#define YYNOMEM goto yyexhaustedlab
-
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
- do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (<%= output.yyerror_args %>, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
- while (0)
-
-/* Backward compatibility with an undocumented macro.
- Use YYerror or YYUNDEF. */
-#define YYERRCODE YYUNDEF
-
-<%# b4_yylloc_default_define -%>
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (N) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (0)
-#endif
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (0)
-
-
-<%# b4_yylocation_print_define -%>
-/* YYLOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
-
-# ifndef YYLOCATION_PRINT
-
-# if defined YY_LOCATION_PRINT
-
- /* Temporary convenience wrapper in case some people defined the
- undocumented and private YY_LOCATION_PRINT macros. */
-# define YYLOCATION_PRINT(File, Loc<%= output.user_args %>) YY_LOCATION_PRINT(File, *(Loc)<%= output.user_args %>)
-
-# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-
-/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
-
-YY_ATTRIBUTE_UNUSED
-static int
-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
-{
- int res = 0;
- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
- if (0 <= yylocp->first_line)
- {
- res += YYFPRINTF (yyo, "%d", yylocp->first_line);
- if (0 <= yylocp->first_column)
- res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
- }
- if (0 <= yylocp->last_line)
- {
- if (yylocp->first_line < yylocp->last_line)
- {
- res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
- if (0 <= end_col)
- res += YYFPRINTF (yyo, ".%d", end_col);
- }
- else if (0 <= end_col && yylocp->first_column < end_col)
- res += YYFPRINTF (yyo, "-%d", end_col);
- }
- return res;
-}
-
-# define YYLOCATION_PRINT yy_location_print_
-
- /* Temporary convenience wrapper in case some people defined the
- undocumented and private YY_LOCATION_PRINT macros. */
-# define YY_LOCATION_PRINT(File, Loc<%= output.user_args %>) YYLOCATION_PRINT(File, &(Loc)<%= output.user_args %>)
-
-# else
-
-# define YYLOCATION_PRINT(File, Loc<%= output.user_args %>) ((void) 0)
- /* Temporary convenience wrapper in case some people defined the
- undocumented and private YY_LOCATION_PRINT macros. */
-# define YY_LOCATION_PRINT YYLOCATION_PRINT
-
-# endif
-# endif /* !defined YYLOCATION_PRINT */
-
-
-# define YY_SYMBOL_PRINT(Title, Kind, Value, Location<%= output.user_args %>) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Kind, Value, Location<%= output.user_args %>); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
-
-
-<%# b4_yy_symbol_print_define -%>
-/*-----------------------------------.
-| Print this symbol's value on YYO. |
-`-----------------------------------*/
-
-static void
-yy_symbol_value_print (FILE *yyo,
- yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp<%= output.user_formals %>)
-{
- FILE *yyoutput = yyo;
-<%= output.parse_param_use("yyoutput", "yylocationp") %>
- if (!yyvaluep)
- return;
- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-<%# b4_symbol_actions(printer) -%>
-switch (yykind)
- {
-<%= output.symbol_actions_for_printer -%>
- default:
- break;
- }
- YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-/*---------------------------.
-| Print this symbol on YYO. |
-`---------------------------*/
-
-static void
-yy_symbol_print (FILE *yyo,
- yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp<%= output.user_formals %>)
-{
- YYFPRINTF (yyo, "%s %s (",
- yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
-
- YYLOCATION_PRINT (yyo, yylocationp<%= output.user_args %>);
- YYFPRINTF (yyo, ": ");
- yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp<%= output.user_args %>);
- YYFPRINTF (yyo, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-static void
-yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop<%= output.user_formals %>)
-{
- YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top<%= output.user_args %>) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)<%= output.user_args %>); \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-static void
-yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp,
- int yyrule<%= output.user_formals %>)
-{
- int yylno = yyrline[yyrule];
- int yynrhs = yyr2[yyrule];
- int yyi;
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr,
- YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
- &yyvsp[(yyi + 1) - (yynrhs)],
- &(yylsp[(yyi + 1) - (yynrhs)])<%= output.user_args %>);
- YYFPRINTF (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule<%= output.user_args %>) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyssp, yyvsp, yylsp, Rule<%= output.user_args %>); \
-} while (0)
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-#ifndef yydebug
-int yydebug;
-#endif
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args) ((void) 0)
-# define YY_SYMBOL_PRINT(Title, Kind, Value, Location<%= output.user_args %>)
-# define YY_STACK_PRINT(Bottom, Top<%= output.user_args %>)
-# define YY_REDUCE_PRINT(Rule<%= output.user_args %>)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-/* Context of a parse error. */
-typedef struct
-{
- yy_state_t *yyssp;
- yysymbol_kind_t yytoken;
- YYLTYPE *yylloc;
-} yypcontext_t;
-
-/* Put in YYARG at most YYARGN of the expected tokens given the
- current YYCTX, and return the number of tokens stored in YYARG. If
- YYARG is null, return the number of expected tokens (guaranteed to
- be less than YYNTOKENS). Return YYENOMEM on memory exhaustion.
- Return 0 if there are more than YYARGN expected tokens, yet fill
- YYARG up to YYARGN. */
-static int
-yypcontext_expected_tokens (const yypcontext_t *yyctx,
- yysymbol_kind_t yyarg[], int yyargn)
-{
- /* Actual size of YYARG. */
- int yycount = 0;
- int yyn = yypact[+*yyctx->yyssp];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (!yyarg)
- ++yycount;
- else if (yycount == yyargn)
- return 0;
- else
- yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
- }
- }
- if (yyarg && yycount == 0 && 0 < yyargn)
- yyarg[0] = YYSYMBOL_YYEMPTY;
- return yycount;
-}
-
-
-
-
-#ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
-# else
-/* Return the length of YYSTR. */
-static YYPTRDIFF_T
-yystrlen (const char *yystr)
-{
- YYPTRDIFF_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-#endif
-
-#ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-#endif
-
-#ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYPTRDIFF_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- YYPTRDIFF_T yyn = 0;
- char const *yyp = yystr;
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- else
- goto append;
-
- append:
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (yyres)
- return yystpcpy (yyres, yystr) - yyres;
- else
- return yystrlen (yystr);
-}
-#endif
-
-
-static int
-yy_syntax_error_arguments (const yypcontext_t *yyctx,
- yysymbol_kind_t yyarg[], int yyargn)
-{
- /* Actual size of YYARG. */
- int yycount = 0;
- /* There are many possibilities here to consider:
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yyctx->yytoken != YYSYMBOL_YYEMPTY)
- {
- int yyn;
- if (yyarg)
- yyarg[yycount] = yyctx->yytoken;
- ++yycount;
- yyn = yypcontext_expected_tokens (yyctx,
- yyarg ? yyarg + 1 : yyarg, yyargn - 1);
- if (yyn == YYENOMEM)
- return YYENOMEM;
- else
- yycount += yyn;
- }
- return yycount;
-}
-
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
- const yypcontext_t *yyctx<%= output.user_formals %>)
-{
- enum { YYARGS_MAX = 5 };
- /* Internationalized format string. */
- const char *yyformat = YY_NULLPTR;
- /* Arguments of yyformat: reported tokens (one for the "unexpected",
- one per "expected"). */
- yysymbol_kind_t yyarg[YYARGS_MAX];
- /* Cumulated lengths of YYARG. */
- YYPTRDIFF_T yysize = 0;
-
- /* Actual size of YYARG. */
- int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX);
- if (yycount == YYENOMEM)
- return YYENOMEM;
-
- switch (yycount)
- {
-#define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- default: /* Avoid compiler warnings. */
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-#undef YYCASE_
- }
-
- /* Compute error message size. Don't count the "%s"s, but reserve
- room for the terminator. */
- yysize = yystrlen (yyformat) - 2 * yycount + 1;
- {
- int yyi;
- for (yyi = 0; yyi < yycount; ++yyi)
- {
- YYPTRDIFF_T yysize1
- = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]);
- if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
- yysize = yysize1;
- else
- return YYENOMEM;
- }
- }
-
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return -1;
- }
-
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]);
- yyformat += 2;
- }
- else
- {
- ++yyp;
- ++yyformat;
- }
- }
- return 0;
-}
-
-<%# b4_yydestruct_define %>
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-static void
-yydestruct (const char *yymsg,
- yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp<%= output.user_formals %>)
-{
-<%= output.parse_param_use("yyvaluep", "yylocationp") %>
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp<%= output.user_args %>);
-
- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
- YY_USE (yykind);
- YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-
-<%- if output.error_recovery -%>
-#ifndef YYMAXREPAIR
-# define YYMAXREPAIR(<%= output.parse_param_name %>) (3)
-#endif
-
-#ifndef YYERROR_RECOVERY_ENABLED
-# define YYERROR_RECOVERY_ENABLED(<%= output.parse_param_name %>) (1)
-#endif
-
-enum yy_repair_type {
- insert,
- delete,
- shift,
-};
-
-struct yy_repair {
- enum yy_repair_type type;
- yysymbol_kind_t term;
-};
-typedef struct yy_repair yy_repair;
-
-struct yy_repairs {
- /* For debug */
- int id;
- /* For breadth-first traversing */
- struct yy_repairs *next;
- YYPTRDIFF_T stack_length;
- /* Bottom of states */
- yy_state_t *states;
- /* Top of states */
- yy_state_t *state;
- /* repair length */
- int repair_length;
- /* */
- struct yy_repairs *prev_repair;
- struct yy_repair repair;
-};
-typedef struct yy_repairs yy_repairs;
-
-struct yy_term {
- yysymbol_kind_t kind;
- YYSTYPE value;
- YYLTYPE location;
-};
-typedef struct yy_term yy_term;
-
-struct yy_repair_terms {
- int id;
- int length;
- yy_term terms[];
-};
-typedef struct yy_repair_terms yy_repair_terms;
-
-static void
-yy_error_token_initialize (yysymbol_kind_t yykind, YYSTYPE * const yyvaluep, YYLTYPE * const yylocationp<%= output.user_formals %>)
-{
- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-switch (yykind)
- {
-<%= output.symbol_actions_for_error_token -%>
- default:
- break;
- }
- YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-static yy_repair_terms *
-yy_create_repair_terms(yy_repairs *reps<%= output.user_formals %>)
-{
- yy_repairs *r = reps;
- yy_repair_terms *rep_terms;
- int count = 0;
-
- while (r->prev_repair)
- {
- count++;
- r = r->prev_repair;
- }
-
- rep_terms = (yy_repair_terms *) YYMALLOC (sizeof (yy_repair_terms) + sizeof (yy_term) * count);
- rep_terms->id = reps->id;
- rep_terms->length = count;
-
- r = reps;
- while (r->prev_repair)
- {
- rep_terms->terms[count-1].kind = r->repair.term;
- count--;
- r = r->prev_repair;
- }
-
- return rep_terms;
-}
-
-static void
-yy_print_repairs(yy_repairs *reps<%= output.user_formals %>)
-{
- yy_repairs *r = reps;
-
- YYDPRINTF ((stderr,
- "id: %d, repair_length: %d, repair_state: %d, prev_repair_id: %d\n",
- reps->id, reps->repair_length, *reps->state, reps->prev_repair->id));
-
- while (r->prev_repair)
- {
- YYDPRINTF ((stderr, "%s ", yysymbol_name (r->repair.term)));
- r = r->prev_repair;
- }
-
- YYDPRINTF ((stderr, "\n"));
-}
-
-static void
-yy_print_repair_terms(yy_repair_terms *rep_terms<%= output.user_formals %>)
-{
- for (int i = 0; i < rep_terms->length; i++)
- YYDPRINTF ((stderr, "%s ", yysymbol_name (rep_terms->terms[i].kind)));
-
- YYDPRINTF ((stderr, "\n"));
-}
-
-static void
-yy_free_repairs(yy_repairs *reps<%= output.user_formals %>)
-{
- while (reps)
- {
- yy_repairs *r = reps;
- reps = reps->next;
- YYFREE (r->states);
- YYFREE (r);
- }
-}
-
-static int
-yy_process_repairs(yy_repairs *reps, yysymbol_kind_t token)
-{
- int yyn;
- int yystate = *reps->state;
- int yylen = 0;
- yysymbol_kind_t yytoken = token;
-
- goto yyrecover_backup;
-
-yyrecover_newstate:
- // TODO: check reps->stack_length
- reps->state += 1;
- *reps->state = (yy_state_t) yystate;
-
-
-yyrecover_backup:
- yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
- goto yyrecover_default;
-
- /* "Reading a token" */
- if (yytoken == YYSYMBOL_YYEMPTY)
- return 1;
-
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yyrecover_default;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yytable_value_is_error (yyn))
- goto yyrecover_errlab;
- yyn = -yyn;
- goto yyrecover_reduce;
- }
-
- /* shift */
- yystate = yyn;
- yytoken = YYSYMBOL_YYEMPTY;
- goto yyrecover_newstate;
-
-
-yyrecover_default:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyrecover_errlab;
- goto yyrecover_reduce;
-
-
-yyrecover_reduce:
- yylen = yyr2[yyn];
- /* YYPOPSTACK */
- reps->state -= yylen;
- yylen = 0;
-
- {
- const int yylhs = yyr1[yyn] - YYNTOKENS;
- const int yyi = yypgoto[yylhs] + *reps->state;
- yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *reps->state
- ? yytable[yyi]
- : yydefgoto[yylhs]);
- }
-
- goto yyrecover_newstate;
-
-yyrecover_errlab:
- return 0;
-}
-
-static yy_repair_terms *
-yyrecover(yy_state_t *yyss, yy_state_t *yyssp, int yychar<%= output.user_formals %>)
-{
- yysymbol_kind_t yytoken = YYTRANSLATE (yychar);
- yy_repair_terms *rep_terms = YY_NULLPTR;
- int count = 0;
-
- yy_repairs *head = (yy_repairs *) YYMALLOC (sizeof (yy_repairs));
- yy_repairs *current = head;
- yy_repairs *tail = head;
- YYPTRDIFF_T stack_length = yyssp - yyss + 1;
-
- head->id = count;
- head->next = 0;
- head->stack_length = stack_length;
- head->states = (yy_state_t *) YYMALLOC (sizeof (yy_state_t) * (stack_length));
- head->state = head->states + (yyssp - yyss);
- YYCOPY (head->states, yyss, stack_length);
- head->repair_length = 0;
- head->prev_repair = 0;
-
- stack_length = (stack_length * 2 > 100) ? (stack_length * 2) : 100;
- count++;
-
- while (current)
- {
- int yystate = *current->state;
- int yyn = yypact[yystate];
- /* See also: yypcontext_expected_tokens */
- if (!yypact_value_is_default (yyn))
- {
- int yyxbegin = yyn < 0 ? -yyn : 0;
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- {
- if (yyx != YYSYMBOL_YYerror)
- {
- if (current->repair_length + 1 > YYMAXREPAIR(<%= output.parse_param_name %>))
- continue;
-
- yy_repairs *new = (yy_repairs *) YYMALLOC (sizeof (yy_repairs));
- new->id = count;
- new->next = 0;
- new->stack_length = stack_length;
- new->states = (yy_state_t *) YYMALLOC (sizeof (yy_state_t) * (stack_length));
- new->state = new->states + (current->state - current->states);
- YYCOPY (new->states, current->states, current->state - current->states + 1);
- new->repair_length = current->repair_length + 1;
- new->prev_repair = current;
- new->repair.type = insert;
- new->repair.term = (yysymbol_kind_t) yyx;
-
- /* Process PDA assuming next token is yyx */
- if (! yy_process_repairs (new, yyx))
- {
- YYFREE (new);
- continue;
- }
-
- tail->next = new;
- tail = new;
- count++;
-
- if (yyx == yytoken)
- {
- rep_terms = yy_create_repair_terms (current<%= output.user_args %>);
- YYDPRINTF ((stderr, "repair_terms found. id: %d, length: %d\n", rep_terms->id, rep_terms->length));
- yy_print_repairs (current<%= output.user_args %>);
- yy_print_repair_terms (rep_terms<%= output.user_args %>);
-
- goto done;
- }
-
- YYDPRINTF ((stderr,
- "New repairs is enqueued. count: %d, yystate: %d, yyx: %d\n",
- count, yystate, yyx));
- yy_print_repairs (new<%= output.user_args %>);
- }
- }
- }
-
- current = current->next;
- }
-
-done:
-
- yy_free_repairs(head<%= output.user_args %>);
-
- if (!rep_terms)
- {
- YYDPRINTF ((stderr, "repair_terms not found\n"));
- }
-
- return rep_terms;
-}
-<%- end -%>
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-int
-yyparse (<%= output.parse_param %>)
-{
-<%# b4_declare_scanner_communication_variables -%>
-/* Lookahead token kind. */
-int yychar;
-
-
-/* The semantic value of the lookahead symbol. */
-/* Default value used for initialization, for pacifying older GCCs
- or non-GCC compilers. */
-YY_INITIAL_VALUE (static const YYSTYPE yyval_default;)
-YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
-
-/* Location data for the lookahead symbol. */
-static const YYLTYPE yyloc_default
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
- = { 1, 1, 1, 1 }
-# endif
-;
-YYLTYPE yylloc = yyloc_default;
-
-<%# b4_declare_parser_state_variables -%>
- /* Number of syntax errors so far. */
- int yynerrs = 0;
- YY_USE (yynerrs); /* Silence compiler warning. */
-
- yy_state_fast_t yystate = 0;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus = 0;
-
- /* Refer to the stacks through separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* Their size. */
- YYPTRDIFF_T yystacksize = YYINITDEPTH;
-
- /* The state stack: array, bottom, top. */
- yy_state_t yyssa[YYINITDEPTH];
- yy_state_t *yyss = yyssa;
- yy_state_t *yyssp = yyss;
-
- /* The semantic value stack: array, bottom, top. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- YYSTYPE *yyvsp = yyvs;
-
- /* The location stack: array, bottom, top. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp = yyls;
-
- int yyn;
- /* The return value of yyparse. */
- int yyresult;
- /* Lookahead symbol kind. */
- yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
- YYLTYPE yyloc;
-
- /* The locations where the error started and ended. */
- YYLTYPE yyerror_range[3];
-<%- if output.error_recovery -%>
- yy_repair_terms *rep_terms = 0;
- yy_term term_backup;
- int rep_terms_index;
- int yychar_backup;
-<%- end -%>
-
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yychar = YYEMPTY; /* Cause a token to be read. */
-
-
-<%# b4_user_initial_action -%>
-<%= output.user_initial_action("/* User initialization code. */") %>
-#line [@oline@] [@ofile@]
-
- yylsp[0] = yylloc;
- goto yysetstate;
-
-
-/*------------------------------------------------------------.
-| yynewstate -- push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
-yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
-
-/*--------------------------------------------------------------------.
-| yysetstate -- set current state (the top of the stack) to yystate. |
-`--------------------------------------------------------------------*/
-yysetstate:
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
- YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
- YY_IGNORE_USELESS_CAST_BEGIN
- *yyssp = YY_CAST (yy_state_t, yystate);
- YY_IGNORE_USELESS_CAST_END
- YY_STACK_PRINT (yyss, yyssp<%= output.user_args %>);
-
- if (yyss + yystacksize - 1 <= yyssp)
-#if !defined yyoverflow && !defined YYSTACK_RELOCATE
- YYNOMEM;
-#else
- {
- /* Get the current used size of the three stacks, in elements. */
- YYPTRDIFF_T yysize = yyssp - yyss + 1;
-
-# if defined yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- yy_state_t *yyss1 = yyss;
- YYSTYPE *yyvs1 = yyvs;
- YYLTYPE *yyls1 = yyls;
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * YYSIZEOF (*yyssp),
- &yyvs1, yysize * YYSIZEOF (*yyvsp),
- &yyls1, yysize * YYSIZEOF (*yylsp),
- &yystacksize);
- yyss = yyss1;
- yyvs = yyvs1;
- yyls = yyls1;
- }
-# else /* defined YYSTACK_RELOCATE */
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- YYNOMEM;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yy_state_t *yyss1 = yyss;
- union yyalloc *yyptr =
- YY_CAST (union yyalloc *,
- YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
- if (! yyptr)
- YYNOMEM;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
- YYSTACK_RELOCATE (yyls_alloc, yyls);
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
- yylsp = yyls + yysize - 1;
-
- YY_IGNORE_USELESS_CAST_BEGIN
- YYDPRINTF ((stderr, "Stack size increased to %ld\n",
- YY_CAST (long, yystacksize)));
- YY_IGNORE_USELESS_CAST_END
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
-
-
- if (yystate == YYFINAL)
- YYACCEPT;
-
- goto yybackup;
-
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
- /* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to lookahead token. */
- yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
-<%- if output.error_recovery -%>
- if (YYERROR_RECOVERY_ENABLED(<%= output.parse_param_name %>))
- {
- if (yychar == YYEMPTY && rep_terms)
- {
-
- if (rep_terms_index < rep_terms->length)
- {
- YYDPRINTF ((stderr, "An error recovery token is used\n"));
- yy_term term = rep_terms->terms[rep_terms_index];
- yytoken = term.kind;
- yylval = term.value;
- yylloc = term.location;
- yychar = yytranslate_inverted[yytoken];
- YY_SYMBOL_PRINT ("Next error recovery token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
- rep_terms_index++;
- }
- else
- {
- YYDPRINTF ((stderr, "Error recovery is completed\n"));
- yytoken = term_backup.kind;
- yylval = term_backup.value;
- yylloc = term_backup.location;
- yychar = yychar_backup;
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
-
- YYFREE (rep_terms);
- rep_terms = 0;
- yychar_backup = 0;
- }
- }
- }
-<%- end -%>
- /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token\n"));
- yychar = yylex <%= output.yylex_formals %>;
- }
-
- if (yychar <= <%= output.eof_symbol.id.s_value %>)
- {
- yychar = <%= output.eof_symbol.id.s_value %>;
- yytoken = <%= output.eof_symbol.enum_name %>;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else if (yychar == <%= output.error_symbol.id.s_value %>)
- {
- /* The scanner already issued an error message, process directly
- to error recovery. But do not keep the error token as
- lookahead, it is too special and may lead us to an endless
- loop in error recovery. */
- yychar = <%= output.undef_symbol.id.s_value %>;
- yytoken = <%= output.error_symbol.enum_name %>;
- yyerror_range[1] = yylloc;
- goto yyerrlab1;
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc<%= output.user_args %>);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yytable_value_is_error (yyn))
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the lookahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc<%= output.user_args %>);
- yystate = yyn;
- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
- *++yyvsp = yylval;
- YY_IGNORE_MAYBE_UNINITIALIZED_END
- *++yylsp = yylloc;
-
- /* Discard the shifted token. */
- yychar = YYEMPTY;
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- '$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
- /* Default location. */
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
- yyerror_range[1] = yyloc;
- YY_REDUCE_PRINT (yyn<%= output.user_args %>);
- switch (yyn)
- {
-<%= output.user_actions -%>
-
- default: break;
- }
- /* User semantic actions sometimes alter yychar, and that requires
- that yytoken be updated with the new translation. We take the
- approach of translating immediately before every use of yytoken.
- One alternative is translating here after every semantic action,
- but that translation would be missed if the semantic action invokes
- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
- incorrect destructor might then be invoked immediately. In the
- case of YYERROR or YYBACKUP, subsequent parser actions might lead
- to an incorrect destructor call or verbose syntax error message
- before the lookahead is translated. */
- YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc<%= output.user_args %>);
-
- YYPOPSTACK (yylen);
- yylen = 0;
-
- *++yyvsp = yyval;
- *++yylsp = yyloc;
-
- /* Now 'shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
- {
- const int yylhs = yyr1[yyn] - YYNTOKENS;
- const int yyi = yypgoto[yylhs] + *yyssp;
- yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
- ? yytable[yyi]
- : yydefgoto[yylhs]);
- }
-
- goto yynewstate;
-
-
-/*--------------------------------------.
-| yyerrlab -- here on detecting error. |
-`--------------------------------------*/
-yyerrlab:
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
- {
- yypcontext_t yyctx
- = {yyssp, yytoken, &yylloc};
- char const *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx<%= output.user_args %>);
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == -1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = YY_CAST (char *,
- YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc)));
- if (yymsg)
- {
- yysyntax_error_status
- = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx<%= output.user_args %>);
- yymsgp = yymsg;
- }
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = YYENOMEM;
- }
- }
- yyerror (<%= output.yyerror_args %>, yymsgp);
- if (yysyntax_error_status == YYENOMEM)
- YYNOMEM;
- }
- }
-
- yyerror_range[1] = yylloc;
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse lookahead token after an
- error, discard it. */
-
- if (yychar <= <%= output.eof_symbol.id.s_value %>)
- {
- /* Return failure if at end of input. */
- if (yychar == <%= output.eof_symbol.id.s_value %>)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval, &yylloc<%= output.user_args %>);
- yychar = YYEMPTY;
- }
- }
-
- /* Else will try to reuse lookahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
- /* Pacify compilers when the user code never invokes YYERROR and the
- label yyerrorlab therefore never appears in user code. */
- if (0)
- YYERROR;
- ++yynerrs;
-
- /* Do not reclaim the symbols of the rule whose action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp<%= output.user_args %>);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
-<%- if output.error_recovery -%>
- if (YYERROR_RECOVERY_ENABLED(<%= output.parse_param_name %>))
- {
- rep_terms = yyrecover (yyss, yyssp, yychar<%= output.user_args %>);
- if (rep_terms)
- {
- for (int i = 0; i < rep_terms->length; i++)
- {
- yy_term *term = &rep_terms->terms[i];
- yy_error_token_initialize (term->kind, &term->value, &term->location<%= output.user_args %>);
- }
-
- yychar_backup = yychar;
- /* Can be packed into (the tail of) rep_terms? */
- term_backup.kind = yytoken;
- term_backup.value = yylval;
- term_backup.location = yylloc;
- rep_terms_index = 0;
- yychar = YYEMPTY;
-
- goto yybackup;
- }
- }
-<%- end -%>
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- /* Pop stack until we find a state that shifts the error token. */
- for (;;)
- {
- yyn = yypact[yystate];
- if (!yypact_value_is_default (yyn))
- {
- yyn += YYSYMBOL_YYerror;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
- yyerror_range[1] = *yylsp;
- yydestruct ("Error: popping",
- YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp<%= output.user_args %>);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp<%= output.user_args %>);
- }
-
- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
- *++yyvsp = yylval;
- YY_IGNORE_MAYBE_UNINITIALIZED_END
-
- yyerror_range[2] = yylloc;
- ++yylsp;
- YYLLOC_DEFAULT (*yylsp, yyerror_range, 2);
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp<%= output.user_args %>);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturnlab;
-
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturnlab;
-
-
-/*-----------------------------------------------------------.
-| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
-`-----------------------------------------------------------*/
-yyexhaustedlab:
- yyerror (<%= output.yyerror_args %>, YY_("memory exhausted"));
- yyresult = 2;
- goto yyreturnlab;
-
-
-/*----------------------------------------------------------.
-| yyreturnlab -- parsing is finished, clean up and return. |
-`----------------------------------------------------------*/
-yyreturnlab:
- if (yychar != YYEMPTY)
- {
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = YYTRANSLATE (yychar);
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval, &yylloc<%= output.user_args %>);
- }
- /* Do not reclaim the symbols of the rule whose action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp<%= output.user_args %>);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp<%= output.user_args %>);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- return yyresult;
-}
-
-<%# b4_percent_code_get([[epilogue]]) -%>
-<%- if output.aux.epilogue -%>
-#line <%= output.aux.epilogue_first_lineno - 1 %> "<%= output.grammar_file_path %>"
-<%= output.aux.epilogue -%>
-<%- end -%>
-
diff --git a/tool/lrama/template/bison/yacc.h b/tool/lrama/template/bison/yacc.h
deleted file mode 100644
index 848dbf5961..0000000000
--- a/tool/lrama/template/bison/yacc.h
+++ /dev/null
@@ -1,40 +0,0 @@
-<%# b4_generated_by -%>
-/* A Bison parser, made by Lrama <%= Lrama::VERSION %>. */
-
-<%# b4_copyright -%>
-/* Bison interface for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
- Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-<%# b4_disclaimer -%>
-/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
- especially those whose name start with YY_ or yy_. They are
- private implementation details that can be changed or removed. */
-<%= output.render_partial("bison/_yacc.h") %>
diff --git a/tool/m4/ruby_check_header.m4 b/tool/m4/ruby_check_header.m4
deleted file mode 100644
index 6fec9d16c5..0000000000
--- a/tool/m4/ruby_check_header.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-dnl -*- Autoconf -*-
-AC_DEFUN([RUBY_CHECK_HEADER],
- [# RUBY_CHECK_HEADER($@)
- save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS m4_if([$5], [], [$INCFLAGS], [$5])"
- AC_CHECK_HEADERS([$1], [$2], [$3], [$4])
- CPPFLAGS="$save_CPPFLAGS"
- unset save_CPPFLAGS])
diff --git a/tool/m4/ruby_default_arch.m4 b/tool/m4/ruby_default_arch.m4
index a0f7c6fe2f..35eb8112f6 100644
--- a/tool/m4/ruby_default_arch.m4
+++ b/tool/m4/ruby_default_arch.m4
@@ -1,19 +1,12 @@
dnl -*- Autoconf -*-
AC_DEFUN([RUBY_DEFAULT_ARCH], [
-# Set ARCH_FLAG for different width but family CPU
AC_MSG_CHECKING([arch option])
-AS_CASE([$1:"$host_cpu"],
- [arm64:arm*], [ARCH_FLAG=-m64],
- [arm*:arm*], [ARCH_FLAG=-m32],
- [x86_64:[i[3-6]86]], [ARCH_FLAG=-m64],
- [x64:x86_64], [],
- [[i[3-6]86]:x86_64], [ARCH_FLAG=-m32],
- [ppc64:ppc*], [ARCH_FLAG=-m64],
- [ppc*:ppc64], [ARCH_FLAG=-m32],
- AS_CASE([$build_os],
- [darwin*], [ARCH_FLAG="-arch "$1],
- [ARCH_FLAG=-march=$1]
- )
-)
+AS_CASE([$1],
+ [arm64], [],
+ [*64], [ARCH_FLAG=-m64],
+ [[i[3-6]86]], [ARCH_FLAG=-m32],
+ [ppc], [ARCH_FLAG=-m32],
+ [AC_MSG_ERROR(unknown target architecture: $target_archs)]
+ )
AC_MSG_RESULT([$ARCH_FLAG])
])dnl
diff --git a/tool/m4/ruby_stack_grow_direction.m4 b/tool/m4/ruby_stack_grow_direction.m4
index 8c6fdd5722..a4d205cc3c 100644
--- a/tool/m4/ruby_stack_grow_direction.m4
+++ b/tool/m4/ruby_stack_grow_direction.m4
@@ -3,7 +3,7 @@ AC_DEFUN([RUBY_STACK_GROW_DIRECTION], [
AS_VAR_PUSHDEF([stack_grow_dir], [rb_cv_stack_grow_dir_$1])
AC_CACHE_CHECK(stack growing direction on $1, stack_grow_dir, [
AS_CASE(["$1"],
-[m68*|x86*|x64|i?86|ppc*|sparc*|alpha*|arm*|aarch*], [ $2=-1],
+[m68*|x86*|x64|i?86|ppc*|sparc*|alpha*], [ $2=-1],
[hppa*], [ $2=+1],
[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
diff --git a/tool/m4/ruby_universal_arch.m4 b/tool/m4/ruby_universal_arch.m4
index 4cbea74c4e..c8914c88d9 100644
--- a/tool/m4/ruby_universal_arch.m4
+++ b/tool/m4/ruby_universal_arch.m4
@@ -17,7 +17,7 @@ AS_IF([test ${target_archs+set}], [
cpu=$archs
cpu=`echo $cpu | sed 's/-.*-.*//'`
universal_binary="${universal_binary+$universal_binary,}$cpu"
- universal_archnames="${universal_archnames:+$universal_archnames }${archs}=${cpu}"
+ universal_archnames="${universal_archnames} ${archs}=${cpu}"
ARCH_FLAG="${ARCH_FLAG+$ARCH_FLAG }-arch $archs"
])
done
@@ -73,7 +73,7 @@ EOF
sed -n 's/^"processor-name=\(.*\)"/\1/p'`
target="$target_cpu${target}"
AC_MSG_RESULT([$target_cpu])
- ])
+ ])
])
target_archs="$target_cpu"
])
diff --git a/tool/make-snapshot b/tool/make-snapshot
index 7446f18578..c94bfe5e59 100755
--- a/tool/make-snapshot
+++ b/tool/make-snapshot
@@ -38,6 +38,8 @@ options:
-packages=PKG[,...] make PKG packages (#{PACKAGES.keys.join(", ")})
-digests=ALG[,...] show ALG digests (#{DIGESTS.join(", ")})
-unicode_version=VER Unicode version to generate encodings
+ -svn[=URL] make snapshot from SVN repository
+ (#{SVNURL})
-help, --help show this message
version:
master, trunk, stable, branches/*, tags/*, X.Y, X.Y.Z, X.Y.Z-pL
@@ -56,7 +58,7 @@ PACKAGES = {
DEFAULT_PACKAGES = PACKAGES.keys - ["tar"]
if !$no7z and system("7z", out: IO::NULL)
PACKAGES["gzip"] = %w".tar.gz 7z a dummy -tgzip -mx -so"
- PACKAGES["zip"] = %w".zip 7z a -tzip -l -mx -mtc=off" << {out: IO::NULL}
+ PACKAGES["zip"] = %w".zip 7z a -tzip -mx -mtc=off" << {out: IO::NULL}
elsif gzip = ENV.delete("GZIP")
PACKAGES["gzip"].concat(gzip.shellsplit)
end
@@ -67,12 +69,13 @@ if mflags = ENV["GNUMAKEFLAGS"] and /\A-(\S*)j\d*/ =~ mflags
ENV["GNUMAKEFLAGS"] = (mflags unless mflags.empty?)
end
ENV["LC_ALL"] = ENV["LANG"] = "C"
+SVNURL = URI.parse("https://svn.ruby-lang.org/repos/ruby/")
# https git clone is disabled at git.ruby-lang.org/ruby.git.
GITURL = URI.parse("https://github.com/ruby/ruby.git")
RUBY_VERSION_PATTERN = /^\#define\s+RUBY_VERSION\s+"([\d.]+)"/
ENV["VPATH"] ||= "include/ruby"
-YACC = ENV["YACC"] ||= "#{$tooldir}/lrama/exe/lrama"
+YACC = ENV["YACC"] ||= "bison"
ENV["BASERUBY"] ||= "ruby"
ENV["RUBY"] ||= "ruby"
ENV["MV"] ||= "mv"
@@ -364,7 +367,7 @@ def package(vcs, rev, destdir, tmp = nil)
end
elsif prerelease
versionhdr ||= IO.read("#{v}/version.h")
- versionhdr.sub!(/^\#\s*define\s+RUBY_PATCHLEVEL_STR\s+"\K.+?(?=")/, tag) or raise "no match of RUBY_PATCHLEVEL_STR to replace"
+ versionhdr.sub!(/^\#define\s+RUBY_PATCHLEVEL_STR\s+"\K.+?(?=")/, tag)
IO.write("#{v}/version.h", versionhdr)
else
tag ||= vcs.revision_name(revision)
@@ -384,21 +387,8 @@ def package(vcs, rev, destdir, tmp = nil)
puts $colorize.fail("patching failed")
return
end
-
- class << (clean = [])
- def add(n) push(n)
- n
- end
- def create(file, content = "", &block)
- add(file)
- if block
- File.open(file, "wb", &block)
- else
- File.binwrite(file, content)
- end
- end
- end
-
+ def (clean = []).add(n) push(n); n end
+ def clean.create(file, content = "") File.binwrite(add(file), content) end
Dir.chdir(v) do
unless File.exist?("ChangeLog")
vcs.export_changelog(url, nil, revision, "ChangeLog")
@@ -419,7 +409,7 @@ def package(vcs, rev, destdir, tmp = nil)
puts
end
- clean.create("cross.rb") do |f|
+ File.open(clean.add("cross.rb"), "w") do |f|
f.puts "Object.__send__(:remove_const, :CROSS_COMPILING) if defined?(CROSS_COMPILING)"
f.puts "CROSS_COMPILING=true"
f.puts "Object.__send__(:remove_const, :RUBY_PLATFORM)"
@@ -518,7 +508,8 @@ touch-unicode-files:
end
vcs.after_export(".") if exported
clean.concat(Dir.glob("ext/**/autom4te.cache"))
- clean.add(".downloaded-cache")
+ FileUtils.rm_rf(clean) unless $keep_temp
+ FileUtils.rm_rf(".downloaded-cache")
if File.exist?("gems/bundled_gems")
gems = Dir.glob("gems/*.gem")
gems -= File.readlines("gems/bundled_gems").map {|line|
@@ -526,11 +517,10 @@ touch-unicode-files:
name, version, _ = line.split(' ')
"gems/#{name}-#{version}.gem"
}
- clean.concat(gems)
+ FileUtils.rm_f(gems)
else
- clean.add("gems")
+ FileUtils.rm_rf("gems")
end
- FileUtils.rm_rf(clean)
if modified
touch_all(modified, "**/*/", 0) do |name, stat|
stat.mtime > modified
@@ -599,18 +589,20 @@ ensure
Dir.chdir(pwd)
end
-if [$srcdir, ($git||=nil)].compact.size > 1
- abort "#{File.basename $0}: -srcdir and -git are exclusive"
+if [$srcdir, ($svn||=nil), ($git||=nil)].compact.size > 1
+ abort "#{File.basename $0}: -srcdir, -svn, and -git are exclusive"
end
if $srcdir
vcs = VCS.detect($srcdir)
+elsif $svn
+ vcs = VCS::SVN.new($svn == true ? SVNURL : URI.parse($svn))
elsif $git
abort "#{File.basename $0}: use -srcdir with cloned local repository"
else
begin
vcs = VCS.detect(File.expand_path("../..", __FILE__))
rescue VCS::NotFoundError
- abort "#{File.expand_path("../..", __FILE__)}: cannot find git repository"
+ vcs = VCS::SVN.new(SVNURL)
end
end
diff --git a/tool/merger.rb b/tool/merger.rb
index e45a3ac586..8b12334b73 100755
--- a/tool/merger.rb
+++ b/tool/merger.rb
@@ -115,6 +115,9 @@ class << Merger = Object.new
end
tagname = "v#{v.join('_')}#{("_#{pl}" if v[0] < "2" || (v[0] == "2" && v[1] < "1") || /^(?:preview|rc)/ =~ pl)}"
+ unless execute('git', 'diff', '--exit-code')
+ abort 'uncommitted changes'
+ end
unless execute('git', 'tag', tagname)
abort 'specfied tag already exists. check tag name and remove it if you want to force re-tagging'
end
diff --git a/tool/missing-baseruby.bat b/tool/missing-baseruby.bat
deleted file mode 100755
index d6d66a4d86..0000000000
--- a/tool/missing-baseruby.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-: "
-@echo off
-: "
-echo executable host ruby is required. use --with-baseruby option.
-exit 1
diff --git a/tool/mjit/bindgen.rb b/tool/mjit/bindgen.rb
new file mode 100755
index 0000000000..a966a46944
--- /dev/null
+++ b/tool/mjit/bindgen.rb
@@ -0,0 +1,435 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+ENV['GEM_HOME'] = File.expand_path('./.bundle', __dir__)
+require 'rubygems/source'
+require 'bundler/inline'
+gemfile(true) do
+ source 'https://rubygems.org'
+ gem 'ffi-clang', '0.7.0', require: false
+end
+
+# Help ffi-clang find libclang
+# Hint: apt install libclang1
+ENV['LIBCLANG'] ||= Dir.glob("/usr/lib/llvm-*/lib/libclang.so.1").grep_v(/-cpp/).sort.last
+require 'ffi/clang'
+
+require 'etc'
+require 'fiddle/import'
+require 'set'
+
+unless build_dir = ARGV.first
+ abort "Usage: #{$0} BUILD_DIR"
+end
+
+class Node < Struct.new(
+ :kind,
+ :spelling,
+ :type,
+ :typedef_type,
+ :bitwidth,
+ :sizeof_type,
+ :offsetof,
+ :enum_value,
+ :children,
+ keyword_init: true,
+)
+end
+
+# Parse a C header with ffi-clang and return Node objects.
+# To ease the maintenance, ffi-clang should be used only inside this class.
+class HeaderParser
+ def initialize(header, cflags:)
+ @translation_unit = FFI::Clang::Index.new.parse_translation_unit(header, cflags, [], {})
+ end
+
+ def parse
+ parse_children(@translation_unit.cursor)
+ end
+
+ private
+
+ def parse_children(cursor)
+ children = []
+ cursor.visit_children do |cursor, _parent|
+ children << parse_cursor(cursor)
+ next :continue
+ end
+ children
+ end
+
+ def parse_cursor(cursor)
+ unless cursor.kind.start_with?('cursor_')
+ raise "unexpected cursor kind: #{cursor.kind}"
+ end
+ kind = cursor.kind.to_s.delete_prefix('cursor_').to_sym
+ children = parse_children(cursor)
+
+ offsetof = {}
+ if kind == :struct
+ children.select { |c| c.kind == :field_decl }.each do |child|
+ offsetof[child.spelling] = cursor.type.offsetof(child.spelling)
+ end
+ end
+
+ sizeof_type = nil
+ if %i[struct union].include?(kind)
+ sizeof_type = cursor.type.sizeof
+ end
+
+ enum_value = nil
+ if kind == :enum_constant_decl
+ enum_value = cursor.enum_value
+ end
+
+ Node.new(
+ kind: kind,
+ spelling: cursor.spelling,
+ type: cursor.type.spelling,
+ typedef_type: cursor.typedef_type.spelling,
+ bitwidth: cursor.bitwidth,
+ sizeof_type: sizeof_type,
+ offsetof: offsetof,
+ enum_value: enum_value,
+ children: children,
+ )
+ end
+end
+
+# Convert Node objects to a Ruby binding source.
+class BindingGenerator
+ BINDGEN_BEG = '### MJIT bindgen begin ###'
+ BINDGEN_END = '### MJIT bindgen end ###'
+ DEFAULTS = { '_Bool' => 'CType::Bool.new' }
+ DEFAULTS.default_proc = proc { |_h, k| "CType::Stub.new(:#{k})" }
+
+ attr_reader :src
+
+ # @param src_path [String]
+ # @param uses [Array<String>]
+ # @param values [Hash{ Symbol => Array<String> }]
+ # @param types [Array<String>]
+ # @param dynamic_types [Array<String>] #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
+ # @param skip_fields [Hash{ Symbol => Array<String> }] Struct fields that are skipped from bindgen
+ # @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
+ def initialize(src_path:, uses:, values:, types:, dynamic_types:, skip_fields:, ruby_fields:)
+ @preamble, @postamble = split_ambles(src_path)
+ @src = String.new
+ @uses = uses.sort
+ @values = values.transform_values(&:sort)
+ @types = types.sort
+ @dynamic_types = dynamic_types.sort
+ @skip_fields = skip_fields.transform_keys(&:to_s)
+ @ruby_fields = ruby_fields.transform_keys(&:to_s)
+ @references = Set.new
+ end
+
+ def generate(nodes)
+ println @preamble
+
+ # Define USE_* macros
+ @uses.each do |use|
+ println " def C.#{use}"
+ println " Primitive.cexpr! %q{ RBOOL(#{use} != 0) }"
+ println " end"
+ println
+ end
+
+ # Define macros/enums
+ @values.each do |type, values|
+ values.each do |value|
+ println " def C.#{value}"
+ println " Primitive.cexpr! %q{ #{type}2NUM(#{value}) }"
+ println " end"
+ println
+ end
+ end
+
+ # TODO: Support nested declarations
+ nodes_index = nodes.group_by(&:spelling).transform_values(&:last)
+
+ # Define types
+ @types.each do |type|
+ unless definition = generate_node(nodes_index[type])
+ raise "Failed to generate type: #{type}"
+ end
+ println " def C.#{type}"
+ println "@#{type} ||= #{definition}".gsub(/^/, " ").chomp
+ println " end"
+ println
+ end
+
+ # Define dynamic types
+ @dynamic_types.each do |type|
+ unless generate_node(nodes_index[type])&.start_with?('CType::Immediate')
+ raise "Non-immediate type is given to dynamic_types: #{type}"
+ end
+ println " def C.#{type}"
+ println " @#{type} ||= CType::Immediate.find(Primitive.cexpr!(\"SIZEOF(#{type})\"), Primitive.cexpr!(\"SIGNED_TYPE_P(#{type})\"))"
+ println " end"
+ println
+ end
+
+ # Leave a stub for types that are referenced but not targeted
+ (@references - @types - @dynamic_types).each do |type|
+ println " def C.#{type}"
+ println " #{DEFAULTS[type]}"
+ println " end"
+ println
+ end
+
+ print @postamble
+ end
+
+ private
+
+ # Return code before BINDGEN_BEG and code after BINDGEN_END
+ def split_ambles(src_path)
+ lines = File.read(src_path).lines
+
+ preamble_end = lines.index { |l| l.include?(BINDGEN_BEG) }
+ raise "`#{BINDGEN_BEG}` was not found in '#{src_path}'" if preamble_end.nil?
+
+ postamble_beg = lines.index { |l| l.include?(BINDGEN_END) }
+ raise "`#{BINDGEN_END}` was not found in '#{src_path}'" if postamble_beg.nil?
+ raise "`#{BINDGEN_BEG}` was found after `#{BINDGEN_END}`" if preamble_end >= postamble_beg
+
+ return lines[0..preamble_end].join, lines[postamble_beg..-1].join
+ end
+
+ # Generate code from a node. Used for constructing a complex nested node.
+ # @param node [Node]
+ def generate_node(node, sizeof_type: nil)
+ case node&.kind
+ when :struct, :union
+ # node.spelling is often empty for union, but we'd like to give it a name when it has one.
+ buf = +"CType::#{node.kind.to_s.sub(/\A[a-z]/, &:upcase)}.new(\n"
+ buf << " \"#{node.spelling}\", Primitive.cexpr!(\"SIZEOF(#{sizeof_type || node.type})\"),\n"
+ bit_fields_end = node.children.index { |c| c.bitwidth == -1 } || node.children.size # first non-bit field index
+ node.children.each_with_index do |child, i|
+ skip_type = sizeof_type&.gsub(/\(\(struct ([^\)]+) \*\)NULL\)->/, '\1.') || node.spelling
+ next if @skip_fields.fetch(skip_type, []).include?(child.spelling)
+ field_builder = proc do |field, type|
+ if node.kind == :struct
+ to_ruby = @ruby_fields.fetch(node.spelling, []).include?(field)
+ if child.bitwidth > 0
+ if bit_fields_end <= i # give up offsetof calculation for non-leading bit fields
+ raise "non-leading bit fields are not supported. consider including '#{field}' in skip_fields."
+ end
+ offsetof = node.offsetof.fetch(field)
+ else
+ off_type = sizeof_type || "(*((#{node.type} *)NULL))"
+ offsetof = "Primitive.cexpr!(\"OFFSETOF(#{off_type}, #{field})\")"
+ end
+ " #{field}: [#{type}, #{offsetof}#{', true' if to_ruby}],\n"
+ else
+ " #{field}: #{type},\n"
+ end
+ end
+
+ case child
+ # BitField is struct-specific. So it must be handled here.
+ in Node[kind: :field_decl, spelling:, bitwidth:, children: [_grandchild, *]] if bitwidth > 0
+ buf << field_builder.call(spelling, "CType::BitField.new(#{bitwidth}, #{node.offsetof.fetch(spelling) % 8})")
+ # "(unnamed ...)" struct and union are handled here, which are also struct-specific.
+ in Node[kind: :field_decl, spelling:, type:, children: [grandchild]] if type.match?(/\((unnamed|anonymous) [^)]+\)\z/)
+ if sizeof_type
+ child_type = "#{sizeof_type}.#{child.spelling}"
+ else
+ child_type = "((#{node.type} *)NULL)->#{child.spelling}"
+ end
+ buf << field_builder.call(spelling, generate_node(grandchild, sizeof_type: child_type).gsub(/^/, ' ').sub(/\A +/, ''))
+ # In most cases, we'd like to let generate_type handle the type unless it's "(unnamed ...)".
+ in Node[kind: :field_decl, spelling:, type:] if !type.empty?
+ buf << field_builder.call(spelling, generate_type(type))
+ else # forward declarations are ignored
+ end
+ end
+ buf << ")"
+ when :typedef_decl
+ case node.children
+ in [child]
+ generate_node(child)
+ in [child, Node[kind: :integer_literal]]
+ generate_node(child)
+ in _ unless node.typedef_type.empty?
+ generate_type(node.typedef_type)
+ end
+ when :enum_decl
+ generate_type('int')
+ when :type_ref
+ generate_type(node.spelling)
+ end
+ end
+
+ # Generate code from a type name. Used for resolving the name of a simple leaf node.
+ # @param type [String]
+ def generate_type(type)
+ if type.match?(/\[\d+\]\z/)
+ return "CType::Pointer.new { #{generate_type(type.sub!(/\[\d+\]\z/, ''))} }"
+ end
+ type = type.delete_suffix('const')
+ if type.end_with?('*')
+ return "CType::Pointer.new { #{generate_type(type.delete_suffix('*').rstrip)} }"
+ end
+
+ type = type.gsub(/((const|volatile) )+/, '').rstrip
+ if type.start_with?(/(struct|union|enum) /)
+ target = type.split(' ', 2).last
+ push_target(target)
+ "self.#{target}"
+ else
+ begin
+ ctype = Fiddle::Importer.parse_ctype(type)
+ rescue Fiddle::DLError
+ push_target(type)
+ "self.#{type}"
+ else
+ # Convert any function pointers to void* to workaround FILE* vs int*
+ if ctype == Fiddle::TYPE_VOIDP
+ "CType::Immediate.parse(\"void *\")"
+ else
+ "CType::Immediate.parse(#{type.dump})"
+ end
+ end
+ end
+ end
+
+ def print(str)
+ @src << str
+ end
+
+ def println(str = "")
+ @src << str << "\n"
+ end
+
+ def chomp
+ @src.delete_suffix!("\n")
+ end
+
+ def rstrip!
+ @src.rstrip!
+ end
+
+ def push_target(target)
+ unless target.match?(/\A\w+\z/)
+ raise "invalid target: #{target}"
+ end
+ @references << target
+ end
+end
+
+src_dir = File.expand_path('../..', __dir__)
+src_path = File.join(src_dir, 'mjit_c.rb')
+build_dir = File.expand_path(build_dir)
+cflags = [
+ src_dir,
+ build_dir,
+ File.join(src_dir, 'include'),
+ File.join(build_dir, ".ext/include/#{RUBY_PLATFORM}"),
+].map { |dir| "-I#{dir}" }
+
+# Clear .cache/clangd created by the language server, which could break this bindgen
+clangd_cache = File.join(src_dir, '.cache/clangd')
+if Dir.exist?(clangd_cache)
+ system('rm', '-rf', clangd_cache, exception: true)
+end
+
+# Parse mjit_c.h and generate mjit_c.rb
+nodes = HeaderParser.new(File.join(src_dir, 'mjit_c.h'), cflags: cflags).parse
+generator = BindingGenerator.new(
+ src_path: src_path,
+ uses: %w[
+ USE_LAZY_LOAD
+ ],
+ values: {
+ INT: %w[
+ NOT_COMPILED_STACK_SIZE
+ VM_CALL_KW_SPLAT
+ VM_CALL_KW_SPLAT_bit
+ VM_CALL_TAILCALL
+ VM_CALL_TAILCALL_bit
+ VM_METHOD_TYPE_CFUNC
+ VM_METHOD_TYPE_ISEQ
+ ],
+ UINT: %w[
+ RUBY_EVENT_CLASS
+ SHAPE_CAPACITY_CHANGE
+ SHAPE_FLAG_SHIFT
+ SHAPE_FROZEN
+ SHAPE_ID_NUM_BITS
+ SHAPE_INITIAL_CAPACITY
+ SHAPE_IVAR
+ SHAPE_ROOT
+ ],
+ ULONG: %w[
+ INVALID_SHAPE_ID
+ SHAPE_MASK
+ ],
+ PTR: %w[
+ rb_cFalseClass
+ rb_cFloat
+ rb_cInteger
+ rb_cNilClass
+ rb_cSymbol
+ rb_cTrueClass
+ ],
+ },
+ types: %w[
+ CALL_DATA
+ IC
+ IVC
+ RB_BUILTIN
+ attr_index_t
+ compile_branch
+ compile_status
+ inlined_call_context
+ iseq_inline_constant_cache
+ iseq_inline_constant_cache_entry
+ iseq_inline_iv_cache_entry
+ iseq_inline_storage_entry
+ mjit_options
+ rb_builtin_function
+ rb_call_data
+ rb_callable_method_entry_struct
+ rb_callcache
+ rb_callinfo
+ rb_control_frame_t
+ rb_cref_t
+ rb_execution_context_struct
+ rb_execution_context_t
+ rb_iseq_constant_body
+ rb_iseq_location_t
+ rb_iseq_struct
+ rb_iseq_t
+ rb_method_definition_struct
+ rb_method_iseq_t
+ rb_method_type_t
+ rb_mjit_compile_info
+ rb_mjit_unit
+ rb_serial_t
+ rb_shape
+ rb_shape_t
+ ],
+ dynamic_types: %w[
+ VALUE
+ shape_id_t
+ ],
+ skip_fields: {
+ 'rb_execution_context_struct.machine': %w[regs], # differs between macOS and Linux
+ rb_execution_context_struct: %w[method_missing_reason], # non-leading bit fields not supported
+ rb_iseq_constant_body: %w[yjit_payload], # conditionally defined
+ },
+ ruby_fields: {
+ rb_iseq_location_struct: %w[
+ base_label
+ first_lineno
+ label
+ pathobj
+ ]
+ },
+)
+generator.generate(nodes)
+
+# Write mjit_c.rb
+File.write(src_path, generator.src)
diff --git a/tool/mjit_archflag.sh b/tool/mjit_archflag.sh
new file mode 100644
index 0000000000..082fb4bcd0
--- /dev/null
+++ b/tool/mjit_archflag.sh
@@ -0,0 +1,40 @@
+# -*- sh -*-
+
+quote() {
+ printf "#${indent}define $1"
+ shift
+ ${1+printf} ${1+' "%s"'$sep} ${1+"$@"}
+ echo
+}
+
+archs=""
+arch_flag=""
+
+parse_arch_flags() {
+ for arch in $1; do
+ archs="${archs:+$archs }${arch%=*}"
+ done
+
+ while shift && [ "$#" -gt 0 ]; do
+ case "$1" in
+ -arch)
+ shift
+ archs="${archs:+$archs }$1"
+ ;;
+ *)
+ arch_flag="${arch_flag:+${arch_flag} }$1"
+ ;;
+ esac
+ done
+}
+
+define_arch_flags() {
+ ${archs:+echo} ${archs:+'#if 0'}
+ for arch in $archs; do
+ echo "#elif defined __${arch}__"
+ quote "MJIT_ARCHFLAG " -arch "${arch}"
+ done
+ ${archs:+echo} ${archs:+'#else'}
+ quote "MJIT_ARCHFLAG /* ${arch_flag:-no flag} */" ${arch_flag}
+ ${archs:+echo} ${archs:+'#endif'}
+}
diff --git a/tool/mjit_tabs.rb b/tool/mjit_tabs.rb
new file mode 100644
index 0000000000..edcbf6cfcb
--- /dev/null
+++ b/tool/mjit_tabs.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+# This is a script to run a command in ARGV, expanding tabs in some files
+# included by vm.c to normalize indentation of MJIT header. You can enable
+# this feature by passing `--without-mjit-tabs` in configure.
+#
+# Note that preprocessor of GCC converts a hard tab to one spaces, where
+# we expect it to be shown as 8 spaces. To obviate this script, we need
+# to convert all tabs to spaces in these files.
+
+require 'fileutils'
+
+EXPAND_TARGETS = %w[
+ vm*.*
+ include/ruby/ruby.h
+]
+
+# These files have no hard tab indentations. Skip normalizing these files from the glob result.
+SKIPPED_FILES = %w[
+ vm_callinfo.h
+ vm_debug.h
+ vm_exec.h
+ vm_opts.h
+ vm_sync.h
+ vm_sync.c
+]
+
+srcdir = File.expand_path('..', __dir__)
+targets = EXPAND_TARGETS.flat_map { |t| Dir.glob(File.join(srcdir, t)) } - SKIPPED_FILES.map { |f| File.join(srcdir, f) }
+sources = {}
+mtimes = {}
+
+mjit_tabs, *command = ARGV
+
+targets.each do |target|
+ next if mjit_tabs != 'false'
+ unless File.writable?(target)
+ puts "tool/mjit_tabs.rb: Skipping #{target.dump} as it's not writable."
+ next
+ end
+ source = File.read(target)
+ begin
+ expanded = source.gsub(/^\t+/) { |tab| ' ' * 8 * tab.length }
+ rescue ArgumentError # invalid byte sequence in UTF-8 (Travis, RubyCI)
+ puts "tool/mjit_tabs.rb: Skipping #{target.dump} as the encoding is #{source.encoding}."
+ next
+ end
+
+ sources[target] = source
+ mtimes[target] = File.mtime(target)
+
+ if sources[target] == expanded
+ puts "#{target.dump} has no hard tab indentation. This should be ignored in tool/mjit_tabs.rb."
+ end
+ File.write(target, expanded)
+ FileUtils.touch(target, mtime: mtimes[target])
+end
+
+result = system(*command)
+
+targets.each do |target|
+ if sources.key?(target)
+ File.write(target, sources[target])
+ FileUtils.touch(target, mtime: mtimes.fetch(target))
+ end
+end
+
+exit result
diff --git a/tool/mk_builtin_loader.rb b/tool/mk_builtin_loader.rb
index 95600e6a3b..94af846a7e 100644
--- a/tool/mk_builtin_loader.rb
+++ b/tool/mk_builtin_loader.rb
@@ -6,7 +6,6 @@ require_relative 'ruby_vm/helpers/c_escape'
SUBLIBS = {}
REQUIRED = {}
-BUILTIN_ATTRS = %w[leaf no_gc]
def string_literal(lit, str = [])
while lit
@@ -26,17 +25,6 @@ def string_literal(lit, str = [])
end
end
-# e.g. [:symbol_literal, [:symbol, [:@ident, "inline", [19, 21]]]]
-def symbol_literal(lit)
- symbol_literal, symbol_lit = lit
- raise "#{lit.inspect} was not :symbol_literal" if symbol_literal != :symbol_literal
- symbol, ident_lit = symbol_lit
- raise "#{symbol_lit.inspect} was not :symbol" if symbol != :symbol
- ident, symbol_name, = ident_lit
- raise "#{ident.inspect} was not :@ident" if ident != :@ident
- symbol_name
-end
-
def inline_text argc, arg1
raise "argc (#{argc}) of inline! should be 1" unless argc == 1
arg1 = string_literal(arg1)
@@ -44,16 +32,6 @@ def inline_text argc, arg1
arg1.join("").rstrip
end
-def inline_attrs(args)
- raise "args was empty" if args.empty?
- args.each do |arg|
- attr = symbol_literal(arg)
- unless BUILTIN_ATTRS.include?(attr)
- raise "attr (#{attr}) was not in: #{BUILTIN_ATTRS.join(', ')}"
- end
- end
-end
-
def make_cfunc_name inlines, name, lineno
case name
when /\[\]/
@@ -160,8 +138,10 @@ def collect_builtin base, tree, name, bs, inlines, locals = nil
if /(.+)[\!\?]\z/ =~ func_name
case $1
when 'attr'
- # Compile-time validation only. compile.c will parse them.
- inline_attrs(args)
+ text = inline_text(argc, args.first)
+ if text != 'inline'
+ raise "Only 'inline' is allowed to be annotated (but got: '#{text}')"
+ end
break
when 'cstmt'
text = inline_text argc, args.first
@@ -263,17 +243,10 @@ end
def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_name)
f = StringIO.new
-
- # Avoid generating fetches of lvars we don't need. This is imperfect as it
- # will match text inside strings or other false positives.
- local_candidates = text.scan(/[a-zA-Z_][a-zA-Z0-9_]*/)
-
f.puts '{'
lineno += 1
- # locals is nil outside methods
- locals&.reverse_each&.with_index{|param, i|
+ locals.reverse_each.with_index{|param, i|
next unless Symbol === param
- next unless local_candidates.include?(param.to_s)
f.puts "MAYBE_UNUSED(const VALUE) #{param} = rb_vm_lvar(ec, #{-3 - i});"
lineno += 1
}
@@ -345,6 +318,44 @@ def mk_builtin_header file
end
}
+ bs.each_pair{|func, (argc, cfunc_name)|
+ decl = ', VALUE' * argc
+ argv = argc \
+ . times \
+ . map {|i|", argv[#{i}]"} \
+ . join('')
+ f.puts %'static void'
+ f.puts %'mjit_compile_invokebuiltin_for_#{func}(VALUE buf, long index, unsigned stack_size, bool inlinable_p)'
+ f.puts %'{'
+ f.puts %' rb_str_catf(buf, " VALUE self = GET_SELF();\\n");'
+ f.puts %' rb_str_catf(buf, " typedef VALUE (*func)(rb_execution_context_t *, VALUE#{decl});\\n");'
+ if inlines.has_key? cfunc_name
+ body_lineno, text, locals, func_name = inlines[cfunc_name]
+ lineno, str = generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_name)
+ f.puts %' if (inlinable_p) {'
+ str.gsub(/^(?!#)/, ' ').each_line {|i|
+ j = RubyVM::CEscape.rstring2cstr(i).dup
+ j.sub!(/^ return\b/ , ' val =')
+ f.printf(%' rb_str_catf(buf, "%%s", %s);\n', j)
+ }
+ f.puts(%' return;')
+ f.puts(%' }')
+ end
+ if argc > 0
+ f.puts %' if (index == -1) {'
+ f.puts %' rb_str_catf(buf, " const VALUE *argv = &stack[%d];\\n", stack_size - #{argc});'
+ f.puts %' }'
+ f.puts %' else {'
+ f.puts %' rb_str_catf(buf, " const unsigned int lnum = ISEQ_BODY(GET_ISEQ())->local_table_size;\\n");'
+ f.puts %' rb_str_catf(buf, " const VALUE *argv = GET_EP() - lnum - VM_ENV_DATA_SIZE + 1 + %ld;\\n", index);'
+ f.puts %' }'
+ end
+ f.puts %' rb_str_catf(buf, " func f = (func)%"PRIuVALUE"; /* == #{cfunc_name} */\\n", (VALUE)#{cfunc_name});'
+ f.puts %' rb_str_catf(buf, " val = f(ec, self#{argv});\\n");'
+ f.puts %'}'
+ f.puts
+ }
+
if SUBLIBS[base]
f.puts "// sub libraries"
SUBLIBS[base].each do |sub|
@@ -360,9 +371,9 @@ def mk_builtin_header file
f.puts " // table definition"
f.puts " static const struct rb_builtin_function #{table}[] = {"
bs.each.with_index{|(func, (argc, cfunc_name)), i|
- f.puts " RB_BUILTIN_FUNCTION(#{i}, #{func}, #{cfunc_name}, #{argc}),"
+ f.puts " RB_BUILTIN_FUNCTION(#{i}, #{func}, #{cfunc_name}, #{argc}, mjit_compile_invokebuiltin_for_#{func}),"
}
- f.puts " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0),"
+ f.puts " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0, 0),"
f.puts " };"
f.puts
diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb
index 55e781a28e..e6d61c5d51 100755
--- a/tool/mkconfig.rb
+++ b/tool/mkconfig.rb
@@ -63,8 +63,8 @@ File.foreach "config.status" do |line|
when /^(?:X|(?:MINI|RUN|(?:HAVE_)?BASE|BOOTSTRAP|BTEST)RUBY(?:_COMMAND)?$)/; next
when /^INSTALLDOC|TARGET$/; next
when /^DTRACE/; next
- when /^RJIT_(CC|SUPPORT)$/; # pass
- when /^RJIT_/; next
+ when /^MJIT_(CC|SUPPORT)$/; # pass
+ when /^MJIT_/; next
when /^(?:MAJOR|MINOR|TEENY)$/; vars[name] = val; next
when /^LIBRUBY_D?LD/; next
when /^RUBY_INSTALL_NAME$/; next vars[name] = (install_name = val).dup if $install_name
@@ -122,11 +122,11 @@ File.foreach "config.status" do |line|
universal, val = val, 'universal' if universal
when /^arch$/
if universal
- platform = val.sub(/universal/, '$(arch)')
+ platform = val.sub(/universal/, %q[#{arch && universal[/(?:\A|\s)#{Regexp.quote(arch)}=(\S+)/, 1] || RUBY_PLATFORM[/\A[^-]*/]}])
end
when /^target_cpu$/
if universal
- val = 'cpu'
+ val = 'arch'
end
when /^target$/
val = '"$(target_cpu)-$(target_vendor)-$(target_os)"'
@@ -193,19 +193,17 @@ print " # Ruby installed directory.\n"
print " TOPDIR = File.dirname(__FILE__).chomp!(#{relative_archdir.dump})\n"
print " # DESTDIR on make install.\n"
print " DESTDIR = ", (drive ? "TOPDIR && TOPDIR[/\\A[a-z]:/i] || " : ""), "'' unless defined? DESTDIR\n"
-print <<"UNIVERSAL", <<'ARCH' if universal
- universal = #{universal}
-UNIVERSAL
+print <<'ARCH' if universal
arch_flag = ENV['ARCHFLAGS'] || ((e = ENV['RC_ARCHS']) && e.split.uniq.map {|a| "-arch #{a}"}.join(' '))
arch = arch_flag && arch_flag[/\A\s*-arch\s+(\S+)\s*\z/, 1]
- cpu = arch && universal[/(?:\A|\s)#{Regexp.quote(arch)}=(\S+)/, 1] || RUBY_PLATFORM[/\A[^-]*/]
ARCH
+print " universal = #{universal}\n" if universal
print " # The hash configurations stored.\n"
print " CONFIG = {}\n"
print " CONFIG[\"DESTDIR\"] = DESTDIR\n"
versions = {}
-File.foreach(File.join(srcdir, "version.h")) do |l|
+IO.foreach(File.join(srcdir, "version.h")) do |l|
m = /^\s*#\s*define\s+RUBY_(PATCHLEVEL)\s+(-?\d+)/.match(l)
if m
versions[m[1]] = m[2]
@@ -226,7 +224,7 @@ File.foreach(File.join(srcdir, "version.h")) do |l|
end
end
if versions.size != 4
- File.foreach(File.join(srcdir, "include/ruby/version.h")) do |l|
+ IO.foreach(File.join(srcdir, "include/ruby/version.h")) do |l|
m = /^\s*#\s*define\s+RUBY_API_VERSION_(\w+)\s+(-?\d+)/.match(l)
if m
versions[m[1]] ||= m[2]
diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb
index 97fe1eab45..c409085ba7 100755
--- a/tool/rbinstall.rb
+++ b/tool/rbinstall.rb
@@ -436,8 +436,8 @@ end
install?(:ext, :arch, :hdr, :'arch-hdr', :'hdr-arch') do
prepare "extension headers", archhdrdir
install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "*.h", :mode => $data_mode)
- install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_rjit_header-*.obj", :mode => $data_mode)
- install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_rjit_header-*.pch", :mode => $data_mode)
+ install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_mjit_header-*.obj", :mode => $data_mode)
+ install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "rb_mjit_header-*.pch", :mode => $data_mode)
end
install?(:ext, :comm, :'ext-comm') do
prepare "extension scripts", rubylibdir
@@ -745,108 +745,47 @@ module RbInstall
end
def collect
- requirable_features.sort
- end
-
- private
-
- def features_from_makefile(makefile_path)
- makefile = File.read(makefile_path)
-
- name = makefile[/^TARGET[ \t]*=[ \t]*((?:.*\\\n)*.*)/, 1]
- return [] if name.nil? || name.empty?
-
- feature = makefile[/^DLLIB[ \t]*=[ \t]*((?:.*\\\n)*.*)/, 1]
- feature = feature.sub("$(TARGET)", name)
-
- target_prefix = makefile[/^target_prefix[ \t]*=[ \t]*((?:.*\\\n)*.*)/, 1]
- feature = File.join(target_prefix.delete_prefix("/"), feature) unless target_prefix.empty?
-
- Array(feature)
+ ruby_libraries.sort
end
class Ext < self
- def requirable_features
+ def skip_install?(files)
# install ext only when it's configured
- return [] unless File.exist?(makefile_path)
-
- ruby_features + ext_features
- end
-
- private
-
- def ruby_features
- Dir.glob("**/*.rb", base: "#{makefile_dir}/lib")
- end
-
- def ext_features
- features_from_makefile(makefile_path)
+ !File.exist?("#{$ext_build_dir}/#{relative_base}/Makefile")
end
- def makefile_path
- if File.exist?("#{makefile_dir}/Makefile")
- "#{makefile_dir}/Makefile"
- else
- # for out-of-place build
- "#{$ext_build_dir}/#{relative_base}/Makefile"
- end
- end
-
- def makefile_dir
- "#{root}/#{relative_base}"
- end
-
- def root
- File.expand_path($ext_build_dir, srcdir)
+ def ruby_libraries
+ Dir.glob("lib/**/*.rb", base: "#{srcdir}/ext/#{relative_base}")
end
end
class Lib < self
- def requirable_features
- ruby_features + ext_features
+ def skip_install?(files)
+ files.empty?
end
- private
-
- def ruby_features
+ def ruby_libraries
gemname = File.basename(gemspec, ".gemspec")
base = relative_base || gemname
# for lib/net/net-smtp.gemspec
if m = /.*(?=-(.*)\z)/.match(gemname)
base = File.join(base, *m.to_a.select {|n| !base.include?(n)})
end
- files = Dir.glob("#{base}{.rb,/**/*.rb}", base: root)
+ files = Dir.glob("lib/#{base}{.rb,/**/*.rb}", base: srcdir)
if !relative_base and files.empty? # no files at the toplevel
# pseudo gem like ruby2_keywords
- files << "#{gemname}.rb"
+ files << "lib/#{gemname}.rb"
end
case gemname
when "net-http"
- files << "net/https.rb"
+ files << "lib/net/https.rb"
when "optparse"
- files << "optionparser.rb"
+ files << "lib/optionparser.rb"
end
files
end
-
- def ext_features
- loaded_gemspec = load_gemspec("#{root}/#{gemspec}")
- extension = loaded_gemspec.extensions.first
- return [] unless extension
-
- extconf = File.expand_path(extension, srcdir)
- ext_build_dir = File.dirname(extconf)
- makefile_path = "#{ext_build_dir}/Makefile"
- return [] unless File.exist?(makefile_path)
-
- features_from_makefile(makefile_path)
- end
-
- def root
- "#{srcdir}/lib"
- end
end
end
end
@@ -1028,7 +967,7 @@ def install_default_gem(dir, srcdir, bindir)
spec = load_gemspec("#{base}/#{src}")
file_collector = RbInstall::Specs::FileCollector.for(srcdir, dir, src)
files = file_collector.collect
- if files.empty?
+ if file_collector.skip_install?(files)
next
end
spec.files = files
@@ -1087,16 +1026,22 @@ install?(:ext, :comm, :gem, :'bundled-gems') do
File.foreach("#{srcdir}/gems/bundled_gems") do |name|
next if /^\s*(?:#|$)/ =~ name
next unless /^(\S+)\s+(\S+).*/ =~ name
+ gem = $1
gem_name = "#$1-#$2"
- # Try to find the gemspec file for C ext gems
- # ex .bundle/gems/debug-1.7.1/debug-1.7.1.gemspec
- # This gemspec keep the original dependencies
- path = "#{srcdir}/.bundle/gems/#{gem_name}/#{gem_name}.gemspec"
+ # Try to find the original gemspec file
+ path = "#{srcdir}/.bundle/gems/#{gem_name}/#{gem}.gemspec"
unless File.exist?(path)
- path = "#{srcdir}/.bundle/specifications/#{gem_name}.gemspec"
+ # Try to find the gemspec file for C ext gems
+ # ex .bundle/gems/debug-1.7.1/debug-1.7.1.gemspec
+ # This gemspec keep the original dependencies
+ path = "#{srcdir}/.bundle/gems/#{gem_name}/#{gem_name}.gemspec"
unless File.exist?(path)
- skipped[gem_name] = "gemspec not found"
- next
+ # Try to find the gemspec file for gems that hasn't own gemspec
+ path = "#{srcdir}/.bundle/specifications/#{gem_name}.gemspec"
+ unless File.exist?(path)
+ skipped[gem_name] = "gemspec not found"
+ next
+ end
end
end
spec = load_gemspec(path, "#{srcdir}/.bundle/gems/#{gem_name}")
diff --git a/tool/rbs_skip_tests b/tool/rbs_skip_tests
index 1c0397bf22..d1dc8a509d 100644
--- a/tool/rbs_skip_tests
+++ b/tool/rbs_skip_tests
@@ -1,29 +1,7 @@
-# Running tests of RBS gem may fail because of various reasons.
-# You can skip tests of RBS gem using this file, instead of pushing a new commit to `ruby/rbs` repository.
-#
-# The most frequently seen reason is the incompatibilities introduced to the unreleased version, including
-#
-# * Strict argument type check is introduced
-# * A required method parameter is added
-# * A method/class is removed
-#
-# Feel free to skip the tests with this file for that case.
-#
-# Syntax:
-#
-# $(test-case-name) ` ` $(optional comment) # Skipping single test case
-# $(test-class-name) ` ` $(optional comment) # Skipping a test class
-#
-
-test_replicate(EncodingTest) the method was removed in 3.3
-
test_collection_install(RBS::CliTest) running tests without Bundler
test_collection_install_frozen(RBS::CliTest) running tests without Bundler
-test_collection_install_gemspec(RBS::CliTest) running tests without Bundler
test_collection_update(RBS::CliTest) running tests without Bundler
-test_TOPDIR(RbConfigSingletonTest) `TOPDIR` is `nil` during CI while RBS type is declared as `String`
-
test_aref(FiberSingletonTest) the method should not accept String keys
NetSingletonTest depending on external resources
@@ -31,5 +9,3 @@ NetInstanceTest depending on external resources
TestHTTPRequest depending on external resources
TestSingletonNetHTTPResponse depending on external resources
TestInstanceNetHTTPResponse depending on external resources
-
-test_bytesplice(StringInstanceTest) Assertion Failed: ../src/internal/class.h:156:RCLASS_SET_M_TBL:!RB_OBJ_PROMOTED(klass)
diff --git a/tool/redmine-backporter.rb b/tool/redmine-backporter.rb
index 3f5c6feca9..7f08eb8d1a 100755
--- a/tool/redmine-backporter.rb
+++ b/tool/redmine-backporter.rb
@@ -66,25 +66,25 @@ class String
def color(fore=nil, back=nil, opts={}, bold: false, underscore: false)
seq = ""
if bold || opts[:bold]
- seq << "\e[1m"
+ seq = seq + "\e[1m"
end
if underscore || opts[:underscore]
- seq << "\e[2m"
+ seq = seq + "\e[2m"
end
if fore
c = COLORS[fore]
raise "unknown foreground color #{fore}" unless c
- seq << "\e[#{c}m"
+ seq = seq + "\e[#{c}m"
end
if back
c = COLORS[back]
raise "unknown background color #{back}" unless c
- seq << "\e[#{c + 10}m"
+ seq = seq + "\e[#{c + 10}m"
end
if seq.empty?
self
else
- seq << self << "\e[0m"
+ seq = seq + self + "\e[0m"
end
end
end
@@ -351,27 +351,22 @@ eom
next
end
- if rev.nil? && log = find_git_log("##@issue]")
- /^commit (?<rev>\h{40})$/ =~ log
- end
- if log && rev
- str = log[/merge revision\(s\) ([^:]+)(?=:)/]
- if str
- str.sub!(/\Amerge/, 'merged')
- str.gsub!(/\h{40}/, 'commit:\0')
- str = "ruby_#{TARGET_VERSION.tr('.','_')} commit:#{rev} #{str}."
+ if rev && has_commit(rev, "ruby_#{TARGET_VERSION.tr('.','_')}")
+ notes = "ruby_#{TARGET_VERSION.tr('.','_')} commit:#{rev}."
+ elsif rev.nil? && (log = find_git_log("##@issue]")) && !(revs = log.scan(/^commit (\h{40})$/).flatten).empty?
+ commits = revs.map { |rev| "commit:#{rev}" }.join(", ")
+ if merged_revs = log[/merge revision\(s\) ([^:]+)(?=:)/]
+ merged_revs.sub!(/\Amerge/, 'merged')
+ merged_revs.gsub!(/\h{8,40}/, 'commit:\0')
+ str = "ruby_#{TARGET_VERSION.tr('.','_')} #{commits} #{merged_revs}."
else
- str = "ruby_#{TARGET_VERSION.tr('.','_')} commit:#{rev}."
+ str = "ruby_#{TARGET_VERSION.tr('.','_')} #{commits}."
end
if notes
str << "\n"
str << notes
end
notes = str
- elsif rev && has_commit(rev, "ruby_#{TARGET_VERSION.tr('.','_')}")
- # Backport commit's log doesn't have the issue number.
- # Instead of that manually it's provided.
- notes = "ruby_#{TARGET_VERSION.tr('.','_')} commit:#{rev}."
else
puts "no commit is found whose log include ##@issue"
next
diff --git a/tool/rjit/bindgen.rb b/tool/rjit/bindgen.rb
deleted file mode 100755
index bf33d92bd2..0000000000
--- a/tool/rjit/bindgen.rb
+++ /dev/null
@@ -1,663 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-ENV['GEM_HOME'] = File.expand_path('./.bundle', __dir__)
-require 'rubygems/source'
-require 'bundler/inline'
-gemfile(true) do
- source 'https://rubygems.org'
- gem 'ffi-clang', '0.7.0', require: false
-end
-
-# Help ffi-clang find libclang
-# Hint: apt install libclang1
-ENV['LIBCLANG'] ||= Dir.glob("/usr/lib/llvm-*/lib/libclang.so.1").grep_v(/-cpp/).sort.last
-require 'ffi/clang'
-
-require 'etc'
-require 'fiddle/import'
-require 'set'
-
-unless build_dir = ARGV.first
- abort "Usage: #{$0} BUILD_DIR"
-end
-
-class Node < Struct.new(
- :kind,
- :spelling,
- :type,
- :typedef_type,
- :bitwidth,
- :sizeof_type,
- :offsetof,
- :enum_value,
- :children,
- keyword_init: true,
-)
-end
-
-# Parse a C header with ffi-clang and return Node objects.
-# To ease the maintenance, ffi-clang should be used only inside this class.
-class HeaderParser
- def initialize(header, cflags:)
- @translation_unit = FFI::Clang::Index.new.parse_translation_unit(header, cflags, [], {})
- end
-
- def parse
- parse_children(@translation_unit.cursor)
- end
-
- private
-
- def parse_children(cursor)
- children = []
- cursor.visit_children do |cursor, _parent|
- children << parse_cursor(cursor)
- next :continue
- end
- children
- end
-
- def parse_cursor(cursor)
- unless cursor.kind.start_with?('cursor_')
- raise "unexpected cursor kind: #{cursor.kind}"
- end
- kind = cursor.kind.to_s.delete_prefix('cursor_').to_sym
- children = parse_children(cursor)
-
- offsetof = {}
- if kind == :struct
- children.select { |c| c.kind == :field_decl }.each do |child|
- offsetof[child.spelling] = cursor.type.offsetof(child.spelling)
- end
- end
-
- sizeof_type = nil
- if %i[struct union].include?(kind)
- sizeof_type = cursor.type.sizeof
- end
-
- enum_value = nil
- if kind == :enum_constant_decl
- enum_value = cursor.enum_value
- end
-
- Node.new(
- kind: kind,
- spelling: cursor.spelling,
- type: cursor.type.spelling,
- typedef_type: cursor.typedef_type.spelling,
- bitwidth: cursor.bitwidth,
- sizeof_type: sizeof_type,
- offsetof: offsetof,
- enum_value: enum_value,
- children: children,
- )
- end
-end
-
-# Convert Node objects to a Ruby binding source.
-class BindingGenerator
- BINDGEN_BEG = '### RJIT bindgen begin ###'
- BINDGEN_END = '### RJIT bindgen end ###'
- DEFAULTS = { '_Bool' => 'CType::Bool.new' }
- DEFAULTS.default_proc = proc { |_h, k| "CType::Stub.new(:#{k})" }
-
- attr_reader :src
-
- # @param src_path [String]
- # @param consts [Hash{ Symbol => Array<String> }]
- # @param values [Hash{ Symbol => Array<String> }]
- # @param funcs [Array<String>]
- # @param types [Array<String>]
- # @param dynamic_types [Array<String>] #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
- # @param skip_fields [Hash{ Symbol => Array<String> }] Struct fields that are skipped from bindgen
- # @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
- def initialize(src_path:, consts:, values:, funcs:, types:, dynamic_types:, skip_fields:, ruby_fields:)
- @preamble, @postamble = split_ambles(src_path)
- @src = String.new
- @consts = consts.transform_values(&:sort)
- @values = values.transform_values(&:sort)
- @funcs = funcs.sort
- @types = types.sort
- @dynamic_types = dynamic_types.sort
- @skip_fields = skip_fields.transform_keys(&:to_s)
- @ruby_fields = ruby_fields.transform_keys(&:to_s)
- @references = Set.new
- end
-
- def generate(nodes)
- println @preamble
-
- # Define macros/enums
- @consts.each do |type, values|
- values.each do |value|
- raise "#{value} isn't a valid constant name" unless ('A'..'Z').include?(value[0])
- println " C::#{value} = Primitive.cexpr! %q{ #{type}2NUM(#{value}) }"
- end
- end
- println
-
- # Define variables
- @values.each do |type, values|
- values.each do |value|
- println " def C.#{value}"
- println " Primitive.cexpr! %q{ #{type}2NUM(#{value}) }"
- println " end"
- println
- end
- end
-
- # Define function pointers
- @funcs.each do |func|
- println " def C.#{func}"
- println " Primitive.cexpr! %q{ SIZET2NUM((size_t)#{func}) }"
- println " end"
- println
- end
-
- # Build a hash table for type lookup by name
- nodes_index = flatten_nodes(nodes).group_by(&:spelling).transform_values do |values|
- # Try to search a declaration with definitions
- node_with_children = values.find { |v| !v.children.empty? }
- next node_with_children if node_with_children
-
- # Otherwise, assume the last one is the main declaration
- values.last
- end
-
- # Define types
- @types.each do |type|
- unless definition = generate_node(nodes_index[type])
- raise "Failed to find or generate type: #{type}"
- end
- println " def C.#{type}"
- println "@#{type} ||= #{definition}".gsub(/^/, " ").chomp
- println " end"
- println
- end
-
- # Define dynamic types
- @dynamic_types.each do |type|
- unless generate_node(nodes_index[type])&.start_with?('CType::Immediate')
- raise "Non-immediate type is given to dynamic_types: #{type}"
- end
- println " def C.#{type}"
- println " @#{type} ||= CType::Immediate.find(Primitive.cexpr!(\"SIZEOF(#{type})\"), Primitive.cexpr!(\"SIGNED_TYPE_P(#{type})\"))"
- println " end"
- println
- end
-
- # Leave a stub for types that are referenced but not targeted
- (@references - @types - @dynamic_types).each do |type|
- println " def C.#{type}"
- println " #{DEFAULTS[type]}"
- println " end"
- println
- end
-
- print @postamble
- end
-
- private
-
- # Make an array that includes all top-level and nested nodes
- def flatten_nodes(nodes)
- result = []
- nodes.each do |node|
- unless node.children.empty?
- result.concat(flatten_nodes(node.children))
- end
- end
- result.concat(nodes) # prioritize top-level nodes
- result
- end
-
- # Return code before BINDGEN_BEG and code after BINDGEN_END
- def split_ambles(src_path)
- lines = File.read(src_path).lines
-
- preamble_end = lines.index { |l| l.include?(BINDGEN_BEG) }
- raise "`#{BINDGEN_BEG}` was not found in '#{src_path}'" if preamble_end.nil?
-
- postamble_beg = lines.index { |l| l.include?(BINDGEN_END) }
- raise "`#{BINDGEN_END}` was not found in '#{src_path}'" if postamble_beg.nil?
- raise "`#{BINDGEN_BEG}` was found after `#{BINDGEN_END}`" if preamble_end >= postamble_beg
-
- return lines[0..preamble_end].join, lines[postamble_beg..-1].join
- end
-
- # Generate code from a node. Used for constructing a complex nested node.
- # @param node [Node]
- def generate_node(node, sizeof_type: nil)
- case node&.kind
- when :struct, :union
- # node.spelling is often empty for union, but we'd like to give it a name when it has one.
- buf = +"CType::#{node.kind.to_s.sub(/\A[a-z]/, &:upcase)}.new(\n"
- buf << " \"#{node.spelling}\", Primitive.cexpr!(\"SIZEOF(#{sizeof_type || node.type})\"),\n"
- bit_fields_end = node.children.index { |c| c.bitwidth == -1 } || node.children.size # first non-bit field index
- node.children.each_with_index do |child, i|
- skip_type = sizeof_type&.gsub(/\(\(struct ([^\)]+) \*\)NULL\)->/, '\1.') || node.spelling
- next if @skip_fields.fetch(skip_type, []).include?(child.spelling)
- field_builder = proc do |field, type|
- if node.kind == :struct
- to_ruby = @ruby_fields.fetch(node.spelling, []).include?(field)
- if child.bitwidth > 0
- if bit_fields_end <= i # give up offsetof calculation for non-leading bit fields
- raise "non-leading bit fields are not supported. consider including '#{field}' in skip_fields."
- end
- offsetof = node.offsetof.fetch(field)
- else
- off_type = sizeof_type || "(*((#{node.type} *)NULL))"
- offsetof = "Primitive.cexpr!(\"OFFSETOF(#{off_type}, #{field})\")"
- end
- " #{field}: [#{type}, #{offsetof}#{', true' if to_ruby}],\n"
- else
- " #{field}: #{type},\n"
- end
- end
-
- case child
- # BitField is struct-specific. So it must be handled here.
- in Node[kind: :field_decl, spelling:, bitwidth:, children: [_grandchild, *]] if bitwidth > 0
- buf << field_builder.call(spelling, "CType::BitField.new(#{bitwidth}, #{node.offsetof.fetch(spelling) % 8})")
- # "(unnamed ...)" struct and union are handled here, which are also struct-specific.
- in Node[kind: :field_decl, spelling:, type:, children: [grandchild]] if type.match?(/\((unnamed|anonymous) [^)]+\)\z/)
- if sizeof_type
- child_type = "#{sizeof_type}.#{child.spelling}"
- else
- child_type = "((#{node.type} *)NULL)->#{child.spelling}"
- end
- buf << field_builder.call(spelling, generate_node(grandchild, sizeof_type: child_type).gsub(/^/, ' ').sub(/\A +/, ''))
- # In most cases, we'd like to let generate_type handle the type unless it's "(unnamed ...)".
- in Node[kind: :field_decl, spelling:, type:] if !type.empty?
- buf << field_builder.call(spelling, generate_type(type))
- else # forward declarations are ignored
- end
- end
- buf << ")"
- when :typedef_decl
- case node.children
- in [child]
- generate_node(child)
- in [child, Node[kind: :integer_literal]]
- generate_node(child)
- in _ unless node.typedef_type.empty?
- generate_type(node.typedef_type)
- end
- when :enum_decl
- generate_type('int')
- when :type_ref
- generate_type(node.spelling)
- end
- end
-
- # Generate code from a type name. Used for resolving the name of a simple leaf node.
- # @param type [String]
- def generate_type(type)
- if type.match?(/\[\d+\]\z/)
- return "CType::Array.new { #{generate_type(type.sub!(/\[\d+\]\z/, ''))} }"
- end
- type = type.delete_suffix('const')
- if type.end_with?('*')
- if type == 'const void *'
- # `CType::Pointer.new { CType::Immediate.parse("void") }` is never useful,
- # so specially handle that case here.
- return 'CType::Immediate.parse("void *")'
- end
- return "CType::Pointer.new { #{generate_type(type.delete_suffix('*').rstrip)} }"
- end
-
- type = type.gsub(/((const|volatile) )+/, '').rstrip
- if type.start_with?(/(struct|union|enum) /)
- target = type.split(' ', 2).last
- push_target(target)
- "self.#{target}"
- else
- begin
- ctype = Fiddle::Importer.parse_ctype(type)
- rescue Fiddle::DLError
- push_target(type)
- "self.#{type}"
- else
- # Convert any function pointers to void* to workaround FILE* vs int*
- if ctype == Fiddle::TYPE_VOIDP
- "CType::Immediate.parse(\"void *\")"
- else
- "CType::Immediate.parse(#{type.dump})"
- end
- end
- end
- end
-
- def print(str)
- @src << str
- end
-
- def println(str = "")
- @src << str << "\n"
- end
-
- def chomp
- @src.delete_suffix!("\n")
- end
-
- def rstrip!
- @src.rstrip!
- end
-
- def push_target(target)
- unless target.match?(/\A\w+\z/)
- raise "invalid target: #{target}"
- end
- @references << target
- end
-end
-
-src_dir = File.expand_path('../..', __dir__)
-src_path = File.join(src_dir, 'rjit_c.rb')
-build_dir = File.expand_path(build_dir)
-cflags = [
- src_dir,
- build_dir,
- File.join(src_dir, 'include'),
- File.join(build_dir, ".ext/include/#{RUBY_PLATFORM}"),
-].map { |dir| "-I#{dir}" }
-
-# Clear .cache/clangd created by the language server, which could break this bindgen
-clangd_cache = File.join(src_dir, '.cache/clangd')
-if Dir.exist?(clangd_cache)
- system('rm', '-rf', clangd_cache, exception: true)
-end
-
-# Parse rjit_c.h and generate rjit_c.rb
-nodes = HeaderParser.new(File.join(src_dir, 'rjit_c.h'), cflags: cflags).parse
-generator = BindingGenerator.new(
- src_path: src_path,
- consts: {
- LONG: %w[
- UNLIMITED_ARGUMENTS
- VM_ENV_DATA_INDEX_ME_CREF
- VM_ENV_DATA_INDEX_SPECVAL
- ],
- SIZET: %w[
- ARRAY_REDEFINED_OP_FLAG
- BOP_AND
- BOP_AREF
- BOP_EQ
- BOP_EQQ
- BOP_FREEZE
- BOP_GE
- BOP_GT
- BOP_LE
- BOP_LT
- BOP_MINUS
- BOP_MOD
- BOP_OR
- BOP_PLUS
- BUILTIN_ATTR_LEAF
- BUILTIN_ATTR_NO_GC
- HASH_REDEFINED_OP_FLAG
- INTEGER_REDEFINED_OP_FLAG
- INVALID_SHAPE_ID
- METHOD_VISI_PRIVATE
- METHOD_VISI_PROTECTED
- METHOD_VISI_PUBLIC
- METHOD_VISI_UNDEF
- OBJ_TOO_COMPLEX_SHAPE_ID
- OPTIMIZED_METHOD_TYPE_BLOCK_CALL
- OPTIMIZED_METHOD_TYPE_CALL
- OPTIMIZED_METHOD_TYPE_SEND
- OPTIMIZED_METHOD_TYPE_STRUCT_AREF
- OPTIMIZED_METHOD_TYPE_STRUCT_ASET
- RARRAY_EMBED_FLAG
- RARRAY_EMBED_LEN_MASK
- RARRAY_EMBED_LEN_SHIFT
- RMODULE_IS_REFINEMENT
- ROBJECT_EMBED
- RSTRUCT_EMBED_LEN_MASK
- RUBY_EVENT_CLASS
- RUBY_EVENT_C_CALL
- RUBY_EVENT_C_RETURN
- RUBY_FIXNUM_FLAG
- RUBY_FLONUM_FLAG
- RUBY_FLONUM_MASK
- RUBY_FL_SINGLETON
- RUBY_IMMEDIATE_MASK
- RUBY_SPECIAL_SHIFT
- RUBY_SYMBOL_FLAG
- RUBY_T_ARRAY
- RUBY_T_CLASS
- RUBY_T_ICLASS
- RUBY_T_HASH
- RUBY_T_MASK
- RUBY_T_MODULE
- RUBY_T_STRING
- RUBY_T_SYMBOL
- RUBY_T_OBJECT
- SHAPE_FLAG_SHIFT
- SHAPE_FROZEN
- SHAPE_ID_NUM_BITS
- SHAPE_IVAR
- SHAPE_MASK
- SHAPE_ROOT
- STRING_REDEFINED_OP_FLAG
- T_OBJECT
- VM_BLOCK_HANDLER_NONE
- VM_CALL_ARGS_BLOCKARG
- VM_CALL_ARGS_SPLAT
- VM_CALL_FCALL
- VM_CALL_KWARG
- VM_CALL_KW_SPLAT
- VM_CALL_KW_SPLAT_MUT
- VM_CALL_KW_SPLAT_bit
- VM_CALL_OPT_SEND
- VM_CALL_TAILCALL
- VM_CALL_TAILCALL_bit
- VM_CALL_ZSUPER
- VM_ENV_DATA_INDEX_FLAGS
- VM_ENV_DATA_SIZE
- VM_ENV_FLAG_LOCAL
- VM_ENV_FLAG_WB_REQUIRED
- VM_FRAME_FLAG_BMETHOD
- VM_FRAME_FLAG_CFRAME
- VM_FRAME_FLAG_CFRAME_KW
- VM_FRAME_FLAG_LAMBDA
- VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM
- VM_FRAME_MAGIC_BLOCK
- VM_FRAME_MAGIC_CFUNC
- VM_FRAME_MAGIC_METHOD
- VM_METHOD_TYPE_ALIAS
- VM_METHOD_TYPE_ATTRSET
- VM_METHOD_TYPE_BMETHOD
- VM_METHOD_TYPE_CFUNC
- VM_METHOD_TYPE_ISEQ
- VM_METHOD_TYPE_IVAR
- VM_METHOD_TYPE_MISSING
- VM_METHOD_TYPE_NOTIMPLEMENTED
- VM_METHOD_TYPE_OPTIMIZED
- VM_METHOD_TYPE_REFINED
- VM_METHOD_TYPE_UNDEF
- VM_METHOD_TYPE_ZSUPER
- VM_SPECIAL_OBJECT_VMCORE
- RUBY_ENCODING_MASK
- RUBY_FL_FREEZE
- RHASH_PASS_AS_KEYWORDS
- ],
- },
- values: {
- SIZET: %w[
- block_type_iseq
- imemo_iseq
- imemo_callinfo
- rb_block_param_proxy
- rb_cArray
- rb_cFalseClass
- rb_cFloat
- rb_cInteger
- rb_cNilClass
- rb_cString
- rb_cSymbol
- rb_cTrueClass
- rb_rjit_global_events
- rb_mRubyVMFrozenCore
- rb_vm_insns_count
- idRespond_to_missing
- ],
- },
- funcs: %w[
- rb_ary_entry_internal
- rb_ary_push
- rb_ary_resurrect
- rb_ary_store
- rb_ec_ary_new_from_values
- rb_ec_str_resurrect
- rb_ensure_iv_list_size
- rb_fix_aref
- rb_fix_div_fix
- rb_fix_mod_fix
- rb_fix_mul_fix
- rb_gc_writebarrier
- rb_get_symbol_id
- rb_hash_aref
- rb_hash_aset
- rb_hash_bulk_insert
- rb_hash_new
- rb_hash_new_with_size
- rb_hash_resurrect
- rb_ivar_get
- rb_obj_as_string_result
- rb_obj_is_kind_of
- rb_str_concat_literals
- rb_str_eql_internal
- rb_str_getbyte
- rb_vm_bh_to_procval
- rb_vm_concat_array
- rb_vm_defined
- rb_vm_get_ev_const
- rb_vm_getclassvariable
- rb_vm_ic_hit_p
- rb_vm_opt_newarray_min
- rb_vm_opt_newarray_max
- rb_vm_opt_newarray_hash
- rb_vm_setinstancevariable
- rb_vm_splat_array
- rjit_full_cfunc_return
- rjit_optimized_call
- rjit_str_neq_internal
- rjit_record_exit_stack
- rb_ivar_defined
- rb_vm_throw
- rb_backref_get
- rb_reg_last_match
- rb_reg_match_pre
- rb_reg_match_post
- rb_reg_match_last
- rb_reg_nth_match
- rb_gvar_get
- rb_range_new
- rb_ary_tmp_new_from_values
- rb_reg_new_ary
- rb_ary_clear
- rb_str_intern
- rb_vm_setclassvariable
- rb_str_bytesize
- rjit_str_simple_append
- rb_str_buf_append
- rb_str_dup
- rb_vm_yield_with_cfunc
- rb_vm_set_ivar_id
- rb_ary_dup
- rjit_rb_ary_subseq_length
- rb_ary_unshift_m
- rjit_build_kwhash
- rb_rjit_entry_stub_hit
- rb_rjit_branch_stub_hit
- rb_sym_to_proc
- ],
- types: %w[
- CALL_DATA
- IC
- ID
- IVC
- RArray
- RB_BUILTIN
- RBasic
- RObject
- RStruct
- RString
- attr_index_t
- iseq_inline_constant_cache
- iseq_inline_constant_cache_entry
- iseq_inline_iv_cache_entry
- iseq_inline_storage_entry
- method_optimized_type
- rb_block
- rb_block_type
- rb_builtin_function
- rb_call_data
- rb_callable_method_entry_struct
- rb_callable_method_entry_t
- rb_callcache
- rb_callinfo
- rb_captured_block
- rb_control_frame_t
- rb_cref_t
- rb_execution_context_struct
- rb_execution_context_t
- rb_iseq_constant_body
- rb_iseq_location_t
- rb_iseq_struct
- rb_iseq_t
- rb_method_attr_t
- rb_method_bmethod_t
- rb_method_cfunc_t
- rb_method_definition_struct
- rb_method_entry_t
- rb_method_iseq_t
- rb_method_optimized_t
- rb_method_type_t
- rb_proc_t
- rb_rjit_runtime_counters
- rb_serial_t
- rb_shape
- rb_shape_t
- rb_thread_struct
- rb_jit_func_t
- rb_iseq_param_keyword
- rb_rjit_options
- rb_callinfo_kwarg
- ],
- # #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
- dynamic_types: %w[
- VALUE
- shape_id_t
- ],
- skip_fields: {
- 'rb_execution_context_struct.machine': %w[regs], # differs between macOS and Linux
- rb_execution_context_struct: %w[method_missing_reason], # non-leading bit fields not supported
- rb_iseq_constant_body: %w[jit_exception jit_exception_calls yjit_payload yjit_calls_at_interv], # conditionally defined
- rb_thread_struct: %w[status has_dedicated_nt to_kill abort_on_exception report_on_exception pending_interrupt_queue_checked],
- :'' => %w[is_from_method is_lambda is_isolated], # rb_proc_t
- },
- ruby_fields: {
- rb_iseq_constant_body: %w[
- rjit_blocks
- ],
- rb_iseq_location_struct: %w[
- base_label
- label
- pathobj
- ],
- rb_callable_method_entry_t: %w[
- defined_class
- ],
- rb_callable_method_entry_struct: %w[
- defined_class
- ],
- },
-)
-generator.generate(nodes)
-
-# Write rjit_c.rb
-File.write(src_path, generator.src)
diff --git a/tool/ruby_vm/helpers/c_escape.rb b/tool/ruby_vm/helpers/c_escape.rb
index 2a99e408da..34fafd1e34 100644
--- a/tool/ruby_vm/helpers/c_escape.rb
+++ b/tool/ruby_vm/helpers/c_escape.rb
@@ -17,10 +17,7 @@ module RubyVM::CEscape
# generate comment, with escaps.
def commentify str
- unless str = str.dump[/\A"\K.*(?="\z)/]
- raise Encoding::CompatibilityError, "must be ASCII-compatible (#{str.encoding})"
- end
- return "/* #{str.gsub('*/', '*\\/').gsub('/*', '/\\*')} */"
+ return "/* #{str.b.gsub('*/', '*\\/').gsub('/*', '/\\*')} */"
end
# Mimic gensym of CL.
diff --git a/tool/ruby_vm/models/attribute.rb b/tool/ruby_vm/models/attribute.rb
index ac4122f3ac..de35e7234a 100644
--- a/tool/ruby_vm/models/attribute.rb
+++ b/tool/ruby_vm/models/attribute.rb
@@ -21,7 +21,7 @@ class RubyVM::Attribute
@key = opts[:name]
@expr = RubyVM::CExpr.new location: opts[:location], expr: opts[:expr]
@type = opts[:type]
- @ope_decls = @insn.operands.map do |operand|
+ @ope_decls = @insn.opes.map do |operand|
decl = operand[:decl]
if @key == 'comptime_sp_inc' && operand[:type] == 'CALL_DATA'
decl = decl.gsub('CALL_DATA', 'CALL_INFO').gsub('cd', 'ci')
diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb
index a810d89f3c..6b5f1f6cf8 100755
--- a/tool/ruby_vm/models/bare_instructions.rb
+++ b/tool/ruby_vm/models/bare_instructions.rb
@@ -16,7 +16,7 @@ require_relative 'typemap'
require_relative 'attribute'
class RubyVM::BareInstructions
- attr_reader :template, :name, :operands, :pops, :rets, :decls, :expr
+ attr_reader :template, :name, :opes, :pops, :rets, :decls, :expr
def initialize opts = {}
@template = opts[:template]
@@ -24,7 +24,7 @@ class RubyVM::BareInstructions
@loc = opts[:location]
@sig = opts[:signature]
@expr = RubyVM::CExpr.new opts[:expr]
- @operands = typesplit @sig[:ope]
+ @opes = typesplit @sig[:ope]
@pops = typesplit @sig[:pop].reject {|i| i == '...' }
@rets = typesplit @sig[:ret].reject {|i| i == '...' }
@attrs = opts[:attributes].map {|i|
@@ -51,7 +51,7 @@ class RubyVM::BareInstructions
def call_attribute name
return sprintf 'attr_%s_%s(%s)', name, @name, \
- @operands.map {|i| i[:name] }.compact.join(', ')
+ @opes.map {|i| i[:name] }.compact.join(', ')
end
def has_attribute? k
@@ -65,7 +65,7 @@ class RubyVM::BareInstructions
end
def width
- return 1 + operands.size
+ return 1 + opes.size
end
def declarations
@@ -98,7 +98,7 @@ class RubyVM::BareInstructions
end
def operands_info
- operands.map {|o|
+ opes.map {|o|
c, _ = RubyVM::Typemap.fetch o[:type]
next c
}.join
@@ -137,7 +137,7 @@ class RubyVM::BareInstructions
end
def has_ope? var
- return @operands.any? {|i| i[:name] == var[:name] }
+ return @opes.any? {|i| i[:name] == var[:name] }
end
def has_pop? var
@@ -180,7 +180,7 @@ class RubyVM::BareInstructions
# Beware: order matters here because some attribute depends another.
generate_attribute 'const char*', 'name', "insn_name(#{bin})"
generate_attribute 'enum ruby_vminsn_type', 'bin', bin
- generate_attribute 'rb_num_t', 'open', operands.size
+ generate_attribute 'rb_num_t', 'open', opes.size
generate_attribute 'rb_num_t', 'popn', pops.size
generate_attribute 'rb_num_t', 'retn', rets.size
generate_attribute 'rb_num_t', 'width', width
@@ -191,7 +191,7 @@ class RubyVM::BareInstructions
def default_definition_of_handles_sp
# Insn with ISEQ should yield it; can handle sp.
- return operands.any? {|o| o[:type] == 'ISEQ' }
+ return opes.any? {|o| o[:type] == 'ISEQ' }
end
def default_definition_of_leaf
diff --git a/tool/ruby_vm/models/c_expr.rb b/tool/ruby_vm/models/c_expr.rb
index 4b5aec58dd..073112f545 100644
--- a/tool/ruby_vm/models/c_expr.rb
+++ b/tool/ruby_vm/models/c_expr.rb
@@ -36,10 +36,6 @@ class RubyVM::CExpr
end
def inspect
- if @__LINE__
- sprintf "#<%s:%d %s>", @__FILE__, @__LINE__, @expr
- else
- sprintf "#<%s %s>", @__FILE__, @expr
- end
+ sprintf "#<%s:%d %s>", @__FILE__, @__LINE__, @expr
end
end
diff --git a/tool/ruby_vm/models/operands_unifications.rb b/tool/ruby_vm/models/operands_unifications.rb
index 10e5742897..ee4e3a695d 100644
--- a/tool/ruby_vm/models/operands_unifications.rb
+++ b/tool/ruby_vm/models/operands_unifications.rb
@@ -38,8 +38,8 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
end
def operand_shift_of var
- before = @original.operands.find_index var
- after = @operands.find_index var
+ before = @original.opes.find_index var
+ after = @opes.find_index var
raise "no #{var} for #{@name}" unless before and after
return before - after
end
@@ -50,7 +50,7 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
case val when '*' then
next nil
else
- type = @original.operands[i][:type]
+ type = @original.opes[i][:type]
expr = RubyVM::Typemap.typecast_to_VALUE type, val
next "#{ptr}[#{i}] == #{expr}"
end
@@ -85,7 +85,7 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
def compose location, spec, template
name = namegen spec
*, argv = *spec
- opes = @original.operands
+ opes = @original.opes
if opes.size != argv.size
raise sprintf("operand size mismatch for %s (%s's: %d, given: %d)",
name, template[:name], opes.size, argv.size)
diff --git a/tool/ruby_vm/views/_comptime_insn_stack_increase.erb b/tool/ruby_vm/views/_comptime_insn_stack_increase.erb
index cb895815ce..b633ab4d32 100644
--- a/tool/ruby_vm/views/_comptime_insn_stack_increase.erb
+++ b/tool/ruby_vm/views/_comptime_insn_stack_increase.erb
@@ -42,7 +42,7 @@ comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *o
% end
case <%= i.bin %>:
return <%= attr_function %>(<%=
- i.operands.map.with_index do |v, j|
+ i.opes.map.with_index do |v, j|
if v[:type] == 'CALL_DATA' && i.has_attribute?('comptime_sp_inc')
v = v.dup
v[:type] = 'CALL_INFO'
diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb
index 6ec33461c4..f34afddb1f 100644
--- a/tool/ruby_vm/views/_insn_entry.erb
+++ b/tool/ruby_vm/views/_insn_entry.erb
@@ -20,11 +20,11 @@ INSN_ENTRY(<%= insn.name %>)
<%= render_c_expr konst -%>
% end
%
-% insn.operands.each_with_index do |ope, i|
+% insn.opes.each_with_index do |ope, i|
<%= ope[:decl] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>);
% end
# define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %>
- const bool MAYBE_UNUSED(leaf) = INSN_ATTR(leaf);
+ const bool leaf = INSN_ATTR(leaf);
% insn.pops.reverse_each.with_index.reverse_each do |pop, i|
<%= pop[:decl] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>;
% end
@@ -35,13 +35,13 @@ INSN_ENTRY(<%= insn.name %>)
% end
/* ### Instruction preambles. ### */
- ADD_PC(INSN_ATTR(width));
+ if (! leaf) ADD_PC(INSN_ATTR(width));
% if insn.handles_sp?
POPN(INSN_ATTR(popn));
% end
<%= insn.handle_canary "SETUP_CANARY(leaf)" -%>
COLLECT_USAGE_INSN(INSN_ATTR(bin));
-% insn.operands.each_with_index do |ope, i|
+% insn.opes.each_with_index do |ope, i|
COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>);
% end
% unless body.empty?
@@ -68,6 +68,7 @@ INSN_ENTRY(<%= insn.name %>)
VM_ASSERT(!RB_TYPE_P(TOPN(<%= i %>), T_MOVED));
% end
% end
+ if (leaf) ADD_PC(INSN_ATTR(width));
# undef INSN_ATTR
/* ### Leave the instruction. ### */
diff --git a/tool/ruby_vm/views/_leaf_helpers.erb b/tool/ruby_vm/views/_leaf_helpers.erb
index f740107a0a..1735db2196 100644
--- a/tool/ruby_vm/views/_leaf_helpers.erb
+++ b/tool/ruby_vm/views/_leaf_helpers.erb
@@ -10,7 +10,7 @@
#include "iseq.h"
-// This is used to tell RJIT that this insn would be leaf if CHECK_INTS didn't exist.
+// This is used to tell MJIT that this insn would be leaf if CHECK_INTS didn't exist.
// It should be used only when RUBY_VM_CHECK_INTS is directly written in insns.def.
static bool leafness_of_check_ints = false;
diff --git a/tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb b/tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb
new file mode 100644
index 0000000000..4b20e896a2
--- /dev/null
+++ b/tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb
@@ -0,0 +1,40 @@
+module RubyVM::MJIT # :nodoc: all
+ Instruction = Struct.new(
+ :name,
+ :bin,
+ :len,
+ :expr,
+ :declarations,
+ :preamble,
+ :opes,
+ :pops,
+ :rets,
+ :always_leaf?,
+ :leaf_without_check_ints?,
+ :handles_sp?,
+ )
+
+ INSNS = {
+% RubyVM::Instructions.each_with_index do |insn, i|
+% next if insn.name.start_with?('trace_')
+ <%= i %> => Instruction.new(
+ name: :<%= insn.name %>,
+ bin: <%= i %>, # BIN(<%= insn.name %>)
+ len: <%= insn.width %>, # insn_len
+ expr: <<-EXPR,
+<%= insn.expr.expr.dump.sub(/\A"/, '').sub(/"\z/, '').gsub(/\\n/, "\n").gsub(/\\t/, ' ' * 8) %>
+ EXPR
+ declarations: <%= insn.declarations.inspect %>,
+ preamble: <%= insn.preamble.map(&:expr).inspect %>,
+ opes: <%= insn.opes.inspect %>,
+ pops: <%= insn.pops.inspect %>,
+ rets: <%= insn.rets.inspect %>,
+ always_leaf?: <%= insn.always_leaf? %>,
+ leaf_without_check_ints?: <%= insn.leaf_without_check_ints? %>,
+ handles_sp?: <%= insn.handles_sp? %>,
+ ),
+% end
+ }
+
+ private_constant(*constants)
+end
diff --git a/tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb b/tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb
deleted file mode 100644
index 4f08524a77..0000000000
--- a/tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb
+++ /dev/null
@@ -1,14 +0,0 @@
-module RubyVM::RJIT # :nodoc: all
- Instruction = Data.define(:name, :bin, :len, :operands)
-
- INSNS = {
-% RubyVM::Instructions.each_with_index do |insn, i|
- <%= i %> => Instruction.new(
- name: :<%= insn.name %>,
- bin: <%= i %>, # BIN(<%= insn.name %>)
- len: <%= insn.width %>, # insn_len
- operands: <%= (insn.operands unless insn.name.start_with?('trace_')).inspect %>,
- ),
-% end
- }
-end
diff --git a/tool/ruby_vm/views/mjit_sp_inc.inc.erb b/tool/ruby_vm/views/mjit_sp_inc.inc.erb
new file mode 100644
index 0000000000..7b925420dd
--- /dev/null
+++ b/tool/ruby_vm/views/mjit_sp_inc.inc.erb
@@ -0,0 +1,17 @@
+static rb_snum_t
+mjit_call_attribute_sp_inc(const int insn, const VALUE *operands)
+{
+ switch (insn) {
+% (RubyVM::BareInstructions.to_a + RubyVM::OperandsUnifications.to_a).each do |insn|
+ case BIN(<%= insn.name %>): {
+% # compiler: Prepare operands which may be used by `insn.call_attribute`
+% insn.opes.each_with_index do |ope, i|
+ MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>];
+% end
+ return <%= insn.call_attribute('sp_inc') %>;
+ }
+% end
+ default:
+ rb_bug("unexpected insn in mjit_call_attribute_sp_inc");
+ }
+}
diff --git a/tool/ruby_vm/views/opt_sc.inc.erb b/tool/ruby_vm/views/opt_sc.inc.erb
new file mode 100644
index 0000000000..e58c81989f
--- /dev/null
+++ b/tool/ruby_vm/views/opt_sc.inc.erb
@@ -0,0 +1,40 @@
+/* -*- C -*- */
+
+%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved.
+%#
+%# This file is a part of the programming language Ruby. Permission is hereby
+%# granted, to either redistribute and/or modify this file, provided that the
+%# conditions mentioned in the file COPYING are met. Consult the file for
+%# details.
+% raise ':FIXME:TBW' if RubyVM::VmOptsH['STACK_CACHING']
+<%= render 'copyright' %>
+<%= render 'notice', locals: {
+ this_file: 'is for threaded code',
+ edit: __FILE__,
+} -%>
+
+#define SC_STATE_SIZE 6
+
+#define SCS_XX 1
+#define SCS_AX 2
+#define SCS_BX 3
+#define SCS_AB 4
+#define SCS_BA 5
+
+#define SC_ERROR 0xffffffff
+
+static const VALUE sc_insn_info[][SC_STATE_SIZE] = {
+#define NO_SC { SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR }
+% RubyVM::Instructions.each_slice 8 do |a|
+ <%= a.map{|i| 'NO_SC' }.join(', ') %>,
+% end
+#undef NO_SC
+};
+
+static const VALUE sc_insn_next[] = {
+% RubyVM::Instructions.each_slice 8 do |a|
+ <%= a.map{|i| 'SCS_XX' }.join(', ') %>,
+% end
+};
+
+ASSERT_VM_INSTRUCTION_SIZE(sc_insn_next);
diff --git a/tool/ruby_vm/views/optinsn.inc.erb b/tool/ruby_vm/views/optinsn.inc.erb
index de7bb210ea..0190f9e07a 100644
--- a/tool/ruby_vm/views/optinsn.inc.erb
+++ b/tool/ruby_vm/views/optinsn.inc.erb
@@ -29,14 +29,14 @@ insn_operands_unification(INSN *iobj)
/* <%= insn.pretty_name %> */
if ( <%= insn.condition('op') %> ) {
-% insn.operands.each_with_index do |o, x|
+% insn.opes.each_with_index do |o, x|
% n = insn.operand_shift_of(o)
% if n != 0 then
op[<%= x %>] = op[<%= x + n %>];
% end
% end
iobj->insn_id = <%= insn.bin %>;
- iobj->operand_size = <%= insn.operands.size %>;
+ iobj->operand_size = <%= insn.opes.size %>;
break;
}
% end
diff --git a/tool/rubyspec_temp.rb b/tool/rubyspec_temp.rb
deleted file mode 100644
index 339bfce211..0000000000
--- a/tool/rubyspec_temp.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require "tmpdir"
-require "fileutils"
-
-if (tmpdir = Dir.mktmpdir("rubyspec_temp.")).size > 80
- # On macOS, the default TMPDIR is very long, inspite of UNIX socket
- # path length is limited.
- Dir.rmdir(tmpdir)
- tmpdir = Dir.mktmpdir("rubyspec_temp.", "/tmp")
-end
-# warn "tmpdir(#{tmpdir.size}) = #{tmpdir}"
-END {FileUtils.rm_rf(tmpdir)}
-
-ENV["TMPDIR"] = ENV["SPEC_TEMP_DIR"] = tmpdir
diff --git a/tool/runruby.rb b/tool/runruby.rb
index ec63d1008a..1efe38fd13 100755
--- a/tool/runruby.rb
+++ b/tool/runruby.rb
@@ -11,8 +11,6 @@ when ENV['RUNRUBY_USE_GDB'] == 'true'
debugger = :gdb
when ENV['RUNRUBY_USE_LLDB'] == 'true'
debugger = :lldb
-when ENV['RUNRUBY_USE_RR'] == 'true'
- debugger = :rr
when ENV['RUNRUBY_YJIT_STATS']
use_yjit_stat = true
end
@@ -136,15 +134,12 @@ if File.file?(libruby_so)
env[e] = [abs_archdir, ENV[e]].compact.join(File::PATH_SEPARATOR)
end
end
-# Work around a bug in FreeBSD 13.2 which can cause fork(2) to hang
-# See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271490
-env['LD_BIND_NOW'] = 'yes' if /freebsd/ =~ RUBY_PLATFORM
ENV.update env
if debugger
case debugger
- when :gdb
+ when :gdb, nil
debugger = %W'gdb -x #{srcdir}/.gdbinit'
if File.exist?(gdb = 'run.gdb') or
File.exist?(gdb = File.join(abs_archdir, 'run.gdb'))
@@ -158,8 +153,6 @@ if debugger
debugger.push('-s', lldb)
end
debugger << '--'
- when :rr
- debugger = ['rr', 'record']
end
if idx = precommand.index(:debugger)
diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb
index f4774bad6b..50c35761f3 100755
--- a/tool/sync_default_gems.rb
+++ b/tool/sync_default_gems.rb
@@ -11,83 +11,84 @@ module SyncDefaultGems
module_function
REPOSITORIES = {
+ rubygems: 'rubygems/rubygems',
+ rdoc: 'ruby/rdoc',
+ reline: 'ruby/reline',
+ json: 'flori/json',
+ psych: 'ruby/psych',
+ fileutils: 'ruby/fileutils',
+ fiddle: 'ruby/fiddle',
+ stringio: 'ruby/stringio',
"io-console": 'ruby/io-console',
"io-nonblock": 'ruby/io-nonblock',
"io-wait": 'ruby/io-wait',
- "net-http": "ruby/net-http",
- "net-protocol": "ruby/net-protocol",
- "open-uri": "ruby/open-uri",
- "resolv-replace": "ruby/resolv-replace",
- English: "ruby/English",
- abbrev: "ruby/abbrev",
- base64: "ruby/base64",
- benchmark: "ruby/benchmark",
- bigdecimal: "ruby/bigdecimal",
- cgi: "ruby/cgi",
csv: 'ruby/csv',
- date: 'ruby/date',
- delegate: "ruby/delegate",
- did_you_mean: "ruby/did_you_mean",
- digest: "ruby/digest",
- drb: "ruby/drb",
- erb: "ruby/erb",
- error_highlight: "ruby/error_highlight",
etc: 'ruby/etc',
+ date: 'ruby/date',
+ zlib: 'ruby/zlib',
fcntl: 'ruby/fcntl',
- fiddle: 'ruby/fiddle',
- fileutils: 'ruby/fileutils',
- find: "ruby/find",
- forwardable: "ruby/forwardable",
- getoptlong: "ruby/getoptlong",
+ strscan: 'ruby/strscan',
ipaddr: 'ruby/ipaddr',
- irb: 'ruby/irb',
- json: 'flori/json',
logger: 'ruby/logger',
+ ostruct: 'ruby/ostruct',
+ irb: 'ruby/irb',
+ forwardable: "ruby/forwardable",
mutex_m: "ruby/mutex_m",
- nkf: "ruby/nkf",
- observer: "ruby/observer",
+ racc: "ruby/racc",
+ singleton: "ruby/singleton",
open3: "ruby/open3",
- openssl: "ruby/openssl",
- optparse: "ruby/optparse",
- ostruct: 'ruby/ostruct',
- pathname: "ruby/pathname",
- pp: "ruby/pp",
- prettyprint: "ruby/prettyprint",
- prism: ["ruby/prism", "main"],
+ getoptlong: "ruby/getoptlong",
pstore: "ruby/pstore",
- psych: 'ruby/psych',
- rdoc: 'ruby/rdoc',
+ delegate: "ruby/delegate",
+ benchmark: "ruby/benchmark",
+ cgi: "ruby/cgi",
readline: "ruby/readline",
- reline: 'ruby/reline',
- resolv: "ruby/resolv",
- rinda: "ruby/rinda",
- rubygems: 'rubygems/rubygems',
- securerandom: "ruby/securerandom",
+ "readline-ext": "ruby/readline-ext",
+ observer: "ruby/observer",
+ timeout: "ruby/timeout",
+ yaml: "ruby/yaml",
+ uri: "ruby/uri",
+ openssl: "ruby/openssl",
+ did_you_mean: "ruby/did_you_mean",
+ weakref: "ruby/weakref",
+ tempfile: "ruby/tempfile",
+ tmpdir: "ruby/tmpdir",
+ English: "ruby/English",
+ "net-protocol": "ruby/net-protocol",
+ "net-http": "ruby/net-http",
+ bigdecimal: "ruby/bigdecimal",
+ optparse: "ruby/optparse",
set: "ruby/set",
+ find: "ruby/find",
+ rinda: "ruby/rinda",
+ erb: "ruby/erb",
+ nkf: "ruby/nkf",
+ tsort: "ruby/tsort",
+ abbrev: "ruby/abbrev",
shellwords: "ruby/shellwords",
- singleton: "ruby/singleton",
- stringio: 'ruby/stringio',
- strscan: 'ruby/strscan',
- syntax_suggest: ["ruby/syntax_suggest", "main"],
+ base64: "ruby/base64",
syslog: "ruby/syslog",
- tempfile: "ruby/tempfile",
+ "open-uri": "ruby/open-uri",
+ securerandom: "ruby/securerandom",
+ resolv: "ruby/resolv",
+ "resolv-replace": "ruby/resolv-replace",
time: "ruby/time",
- timeout: "ruby/timeout",
- tmpdir: "ruby/tmpdir",
- tsort: "ruby/tsort",
+ pp: "ruby/pp",
+ prettyprint: "ruby/prettyprint",
+ drb: "ruby/drb",
+ pathname: "ruby/pathname",
+ digest: "ruby/digest",
+ error_highlight: "ruby/error_highlight",
+ syntax_suggest: ["ruby/syntax_suggest", "main"],
un: "ruby/un",
- uri: "ruby/uri",